From a68cc20fd27a3cbebbc7c7cf563fcfb558f1feca Mon Sep 17 00:00:00 2001 From: Paul Bauer Date: Thu, 17 Oct 2019 14:23:56 +0200 Subject: [PATCH] Apply clang-format to source tree Also change default of reformat-all.sh to use clang-format. Had to also made changes for clang-tidy to pass. Clang format is set as the default for the pre-commit hook, with uncrustify disabled. Small changes to .clang-format that should prevent unpopular formatting of constructor elements and function arguments. Also set BreakBeforeBinaryOperators = NonAssignment, so that some code formatting stays closer to previous uncrustify style. Change-Id: Ic2fbfa21bfc27392ec4c9ebe701291ee59f96e1d --- .clang-format | 8 +- .gitattributes | 4 +- admin/git-pre-commit | 2 +- admin/reformat_all.sh | 6 +- admin/uncrustify.sh | 2 +- .../src/gmxapi/export_context.cpp | 21 +- .../src/gmxapi/export_exceptions.cpp | 83 +- python_packaging/src/gmxapi/export_system.cpp | 23 +- .../src/gmxapi/export_tprfile.cpp | 88 +- python_packaging/src/gmxapi/module.cpp | 8 +- python_packaging/src/gmxapi/module.h | 14 +- python_packaging/src/gmxapi/pycontext.cpp | 57 +- python_packaging/src/gmxapi/pycontext.h | 40 +- python_packaging/src/gmxapi/pysystem.h | 2 +- src/api/cpp/context.cpp | 65 +- src/api/cpp/context_impl.h | 162 +- src/api/cpp/createsession.h | 12 +- src/api/cpp/exceptions.cpp | 8 +- src/api/cpp/include/gmxapi/compat/mdparams.h | 24 +- src/api/cpp/include/gmxapi/compat/tpr.h | 65 +- src/api/cpp/include/gmxapi/context.h | 122 +- src/api/cpp/include/gmxapi/exceptions.h | 94 +- src/api/cpp/include/gmxapi/gmxapi.h | 202 +- src/api/cpp/include/gmxapi/gmxapicompat.h | 46 +- src/api/cpp/include/gmxapi/gromacsfwd.h | 4 +- src/api/cpp/include/gmxapi/md.h | 65 +- src/api/cpp/include/gmxapi/md/mdmodule.h | 58 +- src/api/cpp/include/gmxapi/md/mdsignals.h | 81 +- src/api/cpp/include/gmxapi/session.h | 189 +- .../cpp/include/gmxapi/session/resources.h | 6 +- src/api/cpp/include/gmxapi/status.h | 155 +- src/api/cpp/include/gmxapi/system.h | 184 +- src/api/cpp/md.cpp | 45 +- src/api/cpp/md_impl.h | 24 +- src/api/cpp/mdsignals.cpp | 102 +- src/api/cpp/mdsignals.h | 148 +- src/api/cpp/session.cpp | 150 +- src/api/cpp/session_impl.h | 326 +- src/api/cpp/sessionresources.h | 145 +- src/api/cpp/status.cpp | 71 +- src/api/cpp/system.cpp | 22 +- src/api/cpp/system_impl.h | 64 +- src/api/cpp/tests/restraint.cpp | 113 +- src/api/cpp/tests/runner.cpp | 13 +- src/api/cpp/tests/stopsignaler.cpp | 211 +- src/api/cpp/tests/testingconfiguration.h | 115 +- src/api/cpp/tests/version.cpp | 24 +- src/api/cpp/tpr.cpp | 736 ++- src/api/cpp/version.cpp | 6 +- src/api/cpp/workflow.cpp | 22 +- src/api/cpp/workflow.h | 227 +- src/api/cpp/workflow/tests/workflow.cpp | 8 +- src/api/cpp/workflow_impl.h | 58 +- src/gmxpre.h | 12 +- src/gromacs/analysisdata/abstractdata.cpp | 99 +- src/gromacs/analysisdata/abstractdata.h | 638 +-- src/gromacs/analysisdata/analysisdata.cpp | 139 +- src/gromacs/analysisdata/analysisdata.h | 485 +- src/gromacs/analysisdata/arraydata.cpp | 72 +- src/gromacs/analysisdata/arraydata.h | 308 +- src/gromacs/analysisdata/dataframe.cpp | 103 +- src/gromacs/analysisdata/dataframe.h | 876 ++-- src/gromacs/analysisdata/datamodule.cpp | 9 +- src/gromacs/analysisdata/datamodule.h | 334 +- .../analysisdata/datamodulemanager.cpp | 292 +- src/gromacs/analysisdata/datamodulemanager.h | 410 +- src/gromacs/analysisdata/dataproxy.cpp | 50 +- src/gromacs/analysisdata/dataproxy.h | 64 +- src/gromacs/analysisdata/datastorage.cpp | 762 ++- src/gromacs/analysisdata/datastorage.h | 627 ++- src/gromacs/analysisdata/framelocaldata.h | 308 +- src/gromacs/analysisdata/modules/average.cpp | 110 +- src/gromacs/analysisdata/modules/average.h | 158 +- .../analysisdata/modules/displacement.cpp | 152 +- .../analysisdata/modules/displacement.h | 56 +- .../analysisdata/modules/frameaverager.cpp | 14 +- .../analysisdata/modules/frameaverager.h | 188 +- .../analysisdata/modules/histogram.cpp | 497 +- src/gromacs/analysisdata/modules/histogram.h | 647 +-- src/gromacs/analysisdata/modules/lifetime.cpp | 134 +- src/gromacs/analysisdata/modules/lifetime.h | 50 +- src/gromacs/analysisdata/modules/plot.cpp | 250 +- src/gromacs/analysisdata/modules/plot.h | 379 +- src/gromacs/analysisdata/paralleloptions.h | 34 +- .../analysisdata/tests/analysisdata.cpp | 320 +- src/gromacs/analysisdata/tests/arraydata.cpp | 52 +- src/gromacs/analysisdata/tests/average.cpp | 186 +- src/gromacs/analysisdata/tests/datatest.cpp | 133 +- src/gromacs/analysisdata/tests/datatest.h | 610 ++- src/gromacs/analysisdata/tests/histogram.cpp | 350 +- src/gromacs/analysisdata/tests/lifetime.cpp | 109 +- .../analysisdata/tests/mock_datamodule.cpp | 594 +-- .../analysisdata/tests/mock_datamodule.h | 53 +- src/gromacs/applied_forces/densityfitting.cpp | 675 +-- src/gromacs/applied_forces/densityfitting.h | 4 +- .../densityfittingamplitudelookup.cpp | 98 +- .../densityfittingamplitudelookup.h | 49 +- .../densityfittingforceprovider.cpp | 188 +- .../densityfittingforceprovider.h | 48 +- .../applied_forces/densityfittingoptions.cpp | 162 +- .../applied_forces/densityfittingoptions.h | 109 +- .../densityfittingoutputprovider.cpp | 13 +- .../densityfittingoutputprovider.h | 15 +- .../densityfittingparameters.cpp | 9 +- .../applied_forces/densityfittingparameters.h | 26 +- src/gromacs/applied_forces/electricfield.cpp | 237 +- .../applied_forces/tests/densityfitting.cpp | 91 +- .../tests/densityfittingamplitudelookup.cpp | 27 +- .../tests/densityfittingoptions.cpp | 143 +- .../applied_forces/tests/electricfield.cpp | 96 +- src/gromacs/awh/awh.cpp | 164 +- src/gromacs/awh/awh.h | 279 +- src/gromacs/awh/bias.cpp | 167 +- src/gromacs/awh/bias.h | 451 +- src/gromacs/awh/biasparams.cpp | 122 +- src/gromacs/awh/biasparams.h | 321 +- src/gromacs/awh/biassharing.cpp | 32 +- src/gromacs/awh/biassharing.h | 12 +- src/gromacs/awh/biasstate.cpp | 588 +-- src/gromacs/awh/biasstate.h | 860 ++-- src/gromacs/awh/biaswriter.cpp | 124 +- src/gromacs/awh/biaswriter.h | 206 +- src/gromacs/awh/coordstate.cpp | 65 +- src/gromacs/awh/coordstate.h | 132 +- src/gromacs/awh/correlationgrid.cpp | 11 +- src/gromacs/awh/correlationgrid.h | 178 +- src/gromacs/awh/correlationhistory.cpp | 91 +- src/gromacs/awh/correlationhistory.h | 11 +- src/gromacs/awh/correlationtensor.cpp | 84 +- src/gromacs/awh/correlationtensor.h | 424 +- src/gromacs/awh/dimparams.h | 24 +- src/gromacs/awh/grid.cpp | 201 +- src/gromacs/awh/grid.h | 381 +- src/gromacs/awh/histogramsize.cpp | 61 +- src/gromacs/awh/histogramsize.h | 225 +- src/gromacs/awh/pointstate.cpp | 9 +- src/gromacs/awh/pointstate.h | 777 ++- src/gromacs/awh/read_params.cpp | 357 +- src/gromacs/awh/read_params.h | 16 +- src/gromacs/awh/tests/bias.cpp | 257 +- src/gromacs/awh/tests/biasstate.cpp | 98 +- src/gromacs/awh/tests/grid.cpp | 65 +- .../commandline/cmdlinehelpcontext.cpp | 110 +- src/gromacs/commandline/cmdlinehelpcontext.h | 139 +- src/gromacs/commandline/cmdlinehelpmodule.cpp | 736 ++- src/gromacs/commandline/cmdlinehelpmodule.h | 127 +- src/gromacs/commandline/cmdlinehelpwriter.cpp | 380 +- src/gromacs/commandline/cmdlinehelpwriter.h | 107 +- src/gromacs/commandline/cmdlineinit.cpp | 35 +- src/gromacs/commandline/cmdlineinit.h | 17 +- src/gromacs/commandline/cmdlinemodule.cpp | 27 +- src/gromacs/commandline/cmdlinemodule.h | 114 +- .../commandline/cmdlinemodulemanager.cpp | 476 +- .../commandline/cmdlinemodulemanager.h | 555 +- .../commandline/cmdlinemodulemanager_impl.h | 241 +- .../commandline/cmdlineoptionsmodule.cpp | 178 +- .../commandline/cmdlineoptionsmodule.h | 318 +- src/gromacs/commandline/cmdlineparser.cpp | 95 +- src/gromacs/commandline/cmdlineparser.h | 138 +- .../commandline/cmdlineprogramcontext.cpp | 168 +- .../commandline/cmdlineprogramcontext.h | 229 +- src/gromacs/commandline/filenm.cpp | 65 +- src/gromacs/commandline/filenm.h | 61 +- src/gromacs/commandline/pargs.cpp | 376 +- src/gromacs/commandline/pargs.h | 88 +- src/gromacs/commandline/shellcompletions.cpp | 158 +- src/gromacs/commandline/shellcompletions.h | 31 +- .../commandline/tests/cmdlinehelpmodule.cpp | 44 +- .../commandline/tests/cmdlinehelpwriter.cpp | 201 +- .../tests/cmdlinemodulemanager.cpp | 44 +- .../tests/cmdlinemodulemanagertest.cpp | 90 +- .../tests/cmdlinemodulemanagertest.h | 134 +- .../commandline/tests/cmdlineparser.cpp | 87 +- .../tests/cmdlineprogramcontext.cpp | 83 +- src/gromacs/commandline/tests/filenm.cpp | 28 +- src/gromacs/commandline/tests/pargs.cpp | 437 +- src/gromacs/commandline/viewit.cpp | 33 +- src/gromacs/commandline/viewit.h | 6 +- src/gromacs/compat/pointers.h | 194 +- src/gromacs/compat/tests/pointers.cpp | 58 +- src/gromacs/compat/utility.h | 10 +- src/gromacs/coordinateio/coordinatefile.cpp | 169 +- src/gromacs/coordinateio/coordinatefile.h | 219 +- src/gromacs/coordinateio/enums.h | 38 +- src/gromacs/coordinateio/ioutputadapter.h | 69 +- .../coordinateio/outputadaptercontainer.cpp | 9 +- .../coordinateio/outputadaptercontainer.h | 66 +- .../outputadapters/outputselector.cpp | 9 +- .../outputadapters/outputselector.h | 104 +- .../coordinateio/outputadapters/setatoms.cpp | 30 +- .../coordinateio/outputadapters/setatoms.h | 153 +- .../coordinateio/outputadapters/setbox.h | 61 +- .../coordinateio/outputadapters/setforces.cpp | 17 +- .../coordinateio/outputadapters/setforces.h | 82 +- .../outputadapters/setprecision.cpp | 11 +- .../outputadapters/setprecision.h | 62 +- .../outputadapters/setstarttime.cpp | 10 +- .../outputadapters/setstarttime.h | 92 +- .../outputadapters/settimestep.cpp | 6 +- .../coordinateio/outputadapters/settimestep.h | 79 +- .../outputadapters/setvelocities.cpp | 17 +- .../outputadapters/setvelocities.h | 74 +- src/gromacs/coordinateio/requirements.cpp | 62 +- src/gromacs/coordinateio/requirements.h | 94 +- src/gromacs/coordinateio/tests/builder.cpp | 85 +- .../coordinateio/tests/coordinate_test.h | 156 +- .../tests/outputadaptercontainer.cpp | 25 +- .../coordinateio/tests/outputadapters.cpp | 30 +- .../coordinateio/tests/outputadapters.h | 319 +- .../coordinateio/tests/requirements.cpp | 24 +- src/gromacs/coordinateio/tests/requirements.h | 78 +- src/gromacs/coordinateio/tests/setatoms.cpp | 77 +- .../coordinateio/tests/setbothtime.cpp | 81 +- .../coordinateio/tests/setstarttime.cpp | 49 +- .../coordinateio/tests/settimestep.cpp | 45 +- src/gromacs/coordinateio/tests/testmodule.h | 24 +- src/gromacs/correlationfunctions/autocorr.cpp | 266 +- src/gromacs/correlationfunctions/autocorr.h | 59 +- .../correlationfunctions/crosscorr.cpp | 42 +- src/gromacs/correlationfunctions/crosscorr.h | 4 +- src/gromacs/correlationfunctions/expfit.cpp | 346 +- src/gromacs/correlationfunctions/expfit.h | 54 +- .../correlationfunctions/gmx_lmcurve.cpp | 86 +- .../correlationfunctions/gmx_lmcurve.h | 9 +- .../correlationfunctions/integrate.cpp | 38 +- src/gromacs/correlationfunctions/integrate.h | 7 +- .../manyautocorrelation.cpp | 40 +- .../manyautocorrelation.h | 4 +- .../correlationfunctions/polynomials.cpp | 31 +- .../correlationfunctions/tests/autocorr.cpp | 191 +- .../tests/correlationdataset.cpp | 16 +- .../tests/correlationdataset.h | 93 +- .../correlationfunctions/tests/expfit.cpp | 181 +- .../tests/manyautocorrelation.cpp | 14 +- src/gromacs/domdec/atomdistribution.cpp | 18 +- src/gromacs/domdec/atomdistribution.h | 20 +- src/gromacs/domdec/box.cpp | 137 +- src/gromacs/domdec/box.h | 24 +- src/gromacs/domdec/builder.h | 41 +- src/gromacs/domdec/cellsizes.cpp | 400 +- src/gromacs/domdec/cellsizes.h | 30 +- src/gromacs/domdec/collect.cpp | 95 +- src/gromacs/domdec/collect.h | 14 +- src/gromacs/domdec/distribute.cpp | 263 +- src/gromacs/domdec/distribute.h | 14 +- src/gromacs/domdec/dlb.cpp | 23 +- src/gromacs/domdec/dlb.h | 24 +- src/gromacs/domdec/dlbtiming.cpp | 58 +- src/gromacs/domdec/dlbtiming.h | 236 +- src/gromacs/domdec/domdec.cpp | 1404 +++-- src/gromacs/domdec/domdec.h | 158 +- src/gromacs/domdec/domdec_constraints.cpp | 264 +- src/gromacs/domdec/domdec_constraints.h | 19 +- src/gromacs/domdec/domdec_internal.h | 438 +- src/gromacs/domdec/domdec_network.cpp | 171 +- src/gromacs/domdec/domdec_network.h | 153 +- src/gromacs/domdec/domdec_setup.cpp | 371 +- src/gromacs/domdec/domdec_setup.h | 58 +- src/gromacs/domdec/domdec_specatomcomm.cpp | 190 +- src/gromacs/domdec/domdec_specatomcomm.h | 52 +- src/gromacs/domdec/domdec_struct.h | 111 +- src/gromacs/domdec/domdec_topology.cpp | 1063 ++-- src/gromacs/domdec/domdec_vsite.cpp | 40 +- src/gromacs/domdec/domdec_vsite.h | 9 +- src/gromacs/domdec/dump.cpp | 56 +- src/gromacs/domdec/dump.h | 17 +- src/gromacs/domdec/ga2la.cpp | 16 +- src/gromacs/domdec/ga2la.h | 186 +- src/gromacs/domdec/gpuhaloexchange.h | 105 +- src/gromacs/domdec/gpuhaloexchange_impl.cpp | 27 +- src/gromacs/domdec/gpuhaloexchange_impl.cu | 231 +- src/gromacs/domdec/gpuhaloexchange_impl.cuh | 233 +- src/gromacs/domdec/hashedmap.h | 446 +- src/gromacs/domdec/localatomset.cpp | 6 +- src/gromacs/domdec/localatomset.h | 98 +- src/gromacs/domdec/localatomsetdata.cpp | 10 +- src/gromacs/domdec/localatomsetdata.h | 114 +- src/gromacs/domdec/localatomsetmanager.cpp | 20 +- src/gromacs/domdec/localatomsetmanager.h | 66 +- src/gromacs/domdec/mdsetup.cpp | 34 +- src/gromacs/domdec/mdsetup.h | 26 +- src/gromacs/domdec/options.h | 24 +- src/gromacs/domdec/partition.cpp | 1164 ++--- src/gromacs/domdec/partition.h | 56 +- src/gromacs/domdec/redistribute.cpp | 434 +- src/gromacs/domdec/redistribute.h | 14 +- src/gromacs/domdec/tests/hashedmap.cpp | 63 +- .../domdec/tests/localatomsetmanager.cpp | 15 +- src/gromacs/domdec/utility.cpp | 18 +- src/gromacs/domdec/utility.h | 36 +- .../energyanalysis/tests/legacyenergy.cpp | 156 +- src/gromacs/essentialdynamics/edsam.cpp | 1034 ++-- src/gromacs/essentialdynamics/edsam.h | 63 +- src/gromacs/ewald/calculate_spline_moduli.cpp | 76 +- src/gromacs/ewald/calculate_spline_moduli.h | 6 +- src/gromacs/ewald/ewald.cpp | 124 +- src/gromacs/ewald/ewald.h | 44 +- src/gromacs/ewald/ewald_utils.cpp | 20 +- src/gromacs/ewald/ewald_utils.h | 75 +- src/gromacs/ewald/long_range_correction.cpp | 129 +- src/gromacs/ewald/long_range_correction.h | 31 +- src/gromacs/ewald/pme.cpp | 543 +- src/gromacs/ewald/pme.cuh | 2 +- src/gromacs/ewald/pme.h | 283 +- src/gromacs/ewald/pme_calculate_splines.cuh | 147 +- .../ewald/pme_coordinate_receiver_gpu.h | 45 +- .../pme_coordinate_receiver_gpu_impl.cpp | 22 +- .../ewald/pme_coordinate_receiver_gpu_impl.cu | 38 +- .../ewald/pme_coordinate_receiver_gpu_impl.h | 50 +- src/gromacs/ewald/pme_force_sender_gpu.h | 47 +- .../ewald/pme_force_sender_gpu_impl.cpp | 22 +- .../ewald/pme_force_sender_gpu_impl.cu | 36 +- src/gromacs/ewald/pme_force_sender_gpu_impl.h | 54 +- src/gromacs/ewald/pme_gather.clh | 207 +- src/gromacs/ewald/pme_gather.cpp | 302 +- src/gromacs/ewald/pme_gather.cu | 278 +- src/gromacs/ewald/pme_gather.h | 15 +- src/gromacs/ewald/pme_gpu.cpp | 136 +- src/gromacs/ewald/pme_gpu_3dfft.cu | 46 +- src/gromacs/ewald/pme_gpu_3dfft.h | 64 +- src/gromacs/ewald/pme_gpu_3dfft_ocl.cpp | 100 +- src/gromacs/ewald/pme_gpu_constants.h | 19 +- src/gromacs/ewald/pme_gpu_internal.cpp | 736 +-- src/gromacs/ewald/pme_gpu_internal.h | 215 +- src/gromacs/ewald/pme_gpu_program.cpp | 4 +- src/gromacs/ewald/pme_gpu_program.h | 14 +- src/gromacs/ewald/pme_gpu_program_impl.cpp | 5 +- src/gromacs/ewald/pme_gpu_program_impl.cu | 161 +- src/gromacs/ewald/pme_gpu_program_impl.h | 22 +- .../ewald/pme_gpu_program_impl_ocl.cpp | 127 +- src/gromacs/ewald/pme_gpu_timings.cpp | 29 +- src/gromacs/ewald/pme_gpu_timings.h | 10 +- src/gromacs/ewald/pme_gpu_types.h | 48 +- src/gromacs/ewald/pme_gpu_types_host.h | 58 +- src/gromacs/ewald/pme_gpu_types_host_impl.h | 20 +- src/gromacs/ewald/pme_gpu_utils.h | 8 +- src/gromacs/ewald/pme_grid.cpp | 376 +- src/gromacs/ewald/pme_grid.h | 91 +- src/gromacs/ewald/pme_internal.h | 395 +- src/gromacs/ewald/pme_load_balancing.cpp | 495 +- src/gromacs/ewald/pme_load_balancing.h | 44 +- src/gromacs/ewald/pme_only.cpp | 335 +- src/gromacs/ewald/pme_pp.cpp | 226 +- src/gromacs/ewald/pme_pp_comm_gpu.h | 78 +- src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp | 38 +- src/gromacs/ewald/pme_pp_comm_gpu_impl.cu | 69 +- src/gromacs/ewald/pme_pp_comm_gpu_impl.h | 143 +- src/gromacs/ewald/pme_pp_communication.h | 78 +- src/gromacs/ewald/pme_program.cl | 2 +- src/gromacs/ewald/pme_redistribute.cpp | 156 +- src/gromacs/ewald/pme_redistribute.h | 13 +- src/gromacs/ewald/pme_simd.h | 8 +- src/gromacs/ewald/pme_simd4.h | 160 +- src/gromacs/ewald/pme_solve.clh | 100 +- src/gromacs/ewald/pme_solve.cpp | 434 +- src/gromacs/ewald/pme_solve.cu | 149 +- src/gromacs/ewald/pme_solve.h | 23 +- src/gromacs/ewald/pme_spline_work.cpp | 24 +- src/gromacs/ewald/pme_spline_work.h | 8 +- src/gromacs/ewald/pme_spread.clh | 260 +- src/gromacs/ewald/pme_spread.cpp | 567 +-- src/gromacs/ewald/pme_spread.cu | 169 +- src/gromacs/ewald/pme_spread.h | 13 +- src/gromacs/ewald/tests/pmebsplinetest.cpp | 140 +- src/gromacs/ewald/tests/pmegathertest.cpp | 525 +- src/gromacs/ewald/tests/pmesolvetest.cpp | 451 +- .../ewald/tests/pmesplinespreadtest.cpp | 439 +- src/gromacs/ewald/tests/pmetestcommon.cpp | 400 +- src/gromacs/ewald/tests/pmetestcommon.h | 104 +- .../ewald/tests/testhardwarecontexts.cpp | 40 +- .../ewald/tests/testhardwarecontexts.h | 74 +- src/gromacs/fft/calcgrid.cpp | 34 +- src/gromacs/fft/calcgrid.h | 6 +- src/gromacs/fft/fft.cpp | 115 +- src/gromacs/fft/fft.h | 79 +- src/gromacs/fft/fft5d.cpp | 844 +-- src/gromacs/fft/fft5d.h | 89 +- src/gromacs/fft/fft_fftpack.cpp | 173 +- src/gromacs/fft/fft_fftw3.cpp | 355 +- src/gromacs/fft/fft_mkl.cpp | 188 +- src/gromacs/fft/parallel_3dfft.cpp | 99 +- src/gromacs/fft/parallel_3dfft.h | 58 +- src/gromacs/fft/tests/fft.cpp | 245 +- src/gromacs/fileio/checkpoint.cpp | 1516 +++--- src/gromacs/fileio/checkpoint.h | 115 +- src/gromacs/fileio/confio.cpp | 227 +- src/gromacs/fileio/confio.h | 74 +- src/gromacs/fileio/enxio.cpp | 393 +- src/gromacs/fileio/enxio.h | 77 +- src/gromacs/fileio/espio.cpp | 123 +- src/gromacs/fileio/espio.h | 25 +- src/gromacs/fileio/filetypes.cpp | 157 +- src/gromacs/fileio/filetypes.h | 62 +- src/gromacs/fileio/g96io.cpp | 137 +- src/gromacs/fileio/g96io.h | 7 +- src/gromacs/fileio/gmx_internal_xdr.cpp | 288 +- src/gromacs/fileio/gmx_internal_xdr.h | 123 +- src/gromacs/fileio/gmxfio.cpp | 132 +- src/gromacs/fileio/gmxfio.h | 46 +- src/gromacs/fileio/gmxfio_impl.h | 32 +- src/gromacs/fileio/gmxfio_xdr.cpp | 330 +- src/gromacs/fileio/gmxfio_xdr.h | 263 +- src/gromacs/fileio/groio.cpp | 185 +- src/gromacs/fileio/groio.h | 36 +- src/gromacs/fileio/libxdrf.cpp | 397 +- src/gromacs/fileio/matio.cpp | 547 +- src/gromacs/fileio/matio.h | 133 +- src/gromacs/fileio/md5.cpp | 223 +- src/gromacs/fileio/md5.h | 21 +- src/gromacs/fileio/mrcdensitymap.cpp | 123 +- src/gromacs/fileio/mrcdensitymap.h | 110 +- src/gromacs/fileio/mrcdensitymapheader.cpp | 56 +- src/gromacs/fileio/mrcdensitymapheader.h | 55 +- src/gromacs/fileio/mrcserializer.cpp | 58 +- src/gromacs/fileio/mrcserializer.h | 7 +- src/gromacs/fileio/mtxio.cpp | 39 +- src/gromacs/fileio/mtxio.h | 16 +- src/gromacs/fileio/oenv.cpp | 124 +- src/gromacs/fileio/oenv.h | 59 +- src/gromacs/fileio/pdbio.cpp | 431 +- src/gromacs/fileio/pdbio.h | 106 +- src/gromacs/fileio/readinp.cpp | 184 +- src/gromacs/fileio/readinp.h | 93 +- src/gromacs/fileio/tests/confio.cpp | 218 +- src/gromacs/fileio/tests/filemd5.cpp | 52 +- src/gromacs/fileio/tests/mrcdensitymap.cpp | 24 +- .../fileio/tests/mrcdensitymapheader.cpp | 55 +- src/gromacs/fileio/tests/mrcserializer.cpp | 10 +- src/gromacs/fileio/tests/readinp.cpp | 29 +- src/gromacs/fileio/tests/tngio.cpp | 8 +- src/gromacs/fileio/timecontrol.cpp | 11 +- src/gromacs/fileio/timecontrol.h | 10 +- src/gromacs/fileio/tngio.cpp | 755 ++- src/gromacs/fileio/tngio.h | 85 +- src/gromacs/fileio/tpxio.cpp | 753 ++- src/gromacs/fileio/tpxio.h | 70 +- src/gromacs/fileio/trrio.cpp | 127 +- src/gromacs/fileio/trrio.h | 93 +- src/gromacs/fileio/trxio.cpp | 365 +- src/gromacs/fileio/trxio.h | 100 +- src/gromacs/fileio/vmdio.cpp | 99 +- src/gromacs/fileio/vmdio.h | 12 +- src/gromacs/fileio/warninp.cpp | 74 +- src/gromacs/fileio/warninp.h | 54 +- src/gromacs/fileio/writeps.cpp | 122 +- src/gromacs/fileio/writeps.h | 100 +- src/gromacs/fileio/xdr_datatype.h | 4 +- src/gromacs/fileio/xdrd.cpp | 29 +- src/gromacs/fileio/xdrf.h | 28 +- src/gromacs/fileio/xtcio.cpp | 72 +- src/gromacs/fileio/xtcio.h | 25 +- src/gromacs/fileio/xvgr.cpp | 325 +- src/gromacs/fileio/xvgr.h | 165 +- src/gromacs/gmxana/anadih.cpp | 352 +- src/gromacs/gmxana/binsearch.cpp | 55 +- src/gromacs/gmxana/binsearch.h | 14 +- src/gromacs/gmxana/cmat.cpp | 75 +- src/gromacs/gmxana/cmat.h | 46 +- src/gromacs/gmxana/dens_filter.cpp | 29 +- src/gromacs/gmxana/dens_filter.h | 10 +- src/gromacs/gmxana/dlist.cpp | 175 +- src/gromacs/gmxana/eigio.cpp | 77 +- src/gromacs/gmxana/eigio.h | 45 +- src/gromacs/gmxana/fitahx.cpp | 35 +- src/gromacs/gmxana/fitahx.h | 5 +- src/gromacs/gmxana/gmx_ana.h | 200 +- src/gromacs/gmxana/gmx_anaeig.cpp | 651 +-- src/gromacs/gmxana/gmx_analyze.cpp | 723 +-- src/gromacs/gmxana/gmx_angle.cpp | 221 +- src/gromacs/gmxana/gmx_awh.cpp | 438 +- src/gromacs/gmxana/gmx_bar.cpp | 1392 +++-- src/gromacs/gmxana/gmx_bundle.cpp | 183 +- src/gromacs/gmxana/gmx_chi.cpp | 789 +-- src/gromacs/gmxana/gmx_cluster.cpp | 754 +-- src/gromacs/gmxana/gmx_clustsize.cpp | 253 +- src/gromacs/gmxana/gmx_confrms.cpp | 274 +- src/gromacs/gmxana/gmx_covar.cpp | 227 +- src/gromacs/gmxana/gmx_current.cpp | 534 +- src/gromacs/gmxana/gmx_density.cpp | 344 +- src/gromacs/gmxana/gmx_densmap.cpp | 224 +- src/gromacs/gmxana/gmx_densorder.cpp | 416 +- src/gromacs/gmxana/gmx_dielectric.cpp | 211 +- src/gromacs/gmxana/gmx_dipoles.cpp | 835 ++- src/gromacs/gmxana/gmx_disre.cpp | 468 +- src/gromacs/gmxana/gmx_do_dssp.cpp | 262 +- src/gromacs/gmxana/gmx_dos.cpp | 371 +- src/gromacs/gmxana/gmx_dyecoupl.cpp | 143 +- src/gromacs/gmxana/gmx_enemat.cpp | 247 +- src/gromacs/gmxana/gmx_energy.cpp | 1121 ++-- src/gromacs/gmxana/gmx_filter.cpp | 103 +- src/gromacs/gmxana/gmx_gyrate.cpp | 174 +- src/gromacs/gmxana/gmx_h2order.cpp | 219 +- src/gromacs/gmxana/gmx_hbond.cpp | 1498 +++--- src/gromacs/gmxana/gmx_helix.cpp | 156 +- src/gromacs/gmxana/gmx_helixorient.cpp | 270 +- src/gromacs/gmxana/gmx_hydorder.cpp | 302 +- src/gromacs/gmxana/gmx_lie.cpp | 83 +- src/gromacs/gmxana/gmx_make_edi.cpp | 647 ++- src/gromacs/gmxana/gmx_mdmat.cpp | 139 +- src/gromacs/gmxana/gmx_mindist.cpp | 352 +- src/gromacs/gmxana/gmx_msd.cpp | 549 +- src/gromacs/gmxana/gmx_nmeig.cpp | 396 +- src/gromacs/gmxana/gmx_nmens.cpp | 106 +- src/gromacs/gmxana/gmx_nmr.cpp | 423 +- src/gromacs/gmxana/gmx_nmtraj.cpp | 108 +- src/gromacs/gmxana/gmx_order.cpp | 524 +- src/gromacs/gmxana/gmx_polystat.cpp | 179 +- src/gromacs/gmxana/gmx_potential.cpp | 236 +- src/gromacs/gmxana/gmx_principal.cpp | 88 +- src/gromacs/gmxana/gmx_rama.cpp | 39 +- src/gromacs/gmxana/gmx_rms.cpp | 410 +- src/gromacs/gmxana/gmx_rmsdist.cpp | 428 +- src/gromacs/gmxana/gmx_rmsf.cpp | 282 +- src/gromacs/gmxana/gmx_rotacf.cpp | 103 +- src/gromacs/gmxana/gmx_rotmat.cpp | 129 +- src/gromacs/gmxana/gmx_saltbr.cpp | 119 +- src/gromacs/gmxana/gmx_sans.cpp | 176 +- src/gromacs/gmxana/gmx_saxs.cpp | 53 +- src/gromacs/gmxana/gmx_sham.cpp | 564 ++- src/gromacs/gmxana/gmx_sigeps.cpp | 129 +- src/gromacs/gmxana/gmx_sorient.cpp | 221 +- src/gromacs/gmxana/gmx_spatial.cpp | 212 +- src/gromacs/gmxana/gmx_spol.cpp | 150 +- src/gromacs/gmxana/gmx_tcaf.cpp | 256 +- src/gromacs/gmxana/gmx_traj.cpp | 417 +- src/gromacs/gmxana/gmx_trjorder.cpp | 147 +- src/gromacs/gmxana/gmx_vanhove.cpp | 163 +- src/gromacs/gmxana/gmx_velacc.cpp | 167 +- src/gromacs/gmxana/gmx_wham.cpp | 1441 +++--- src/gromacs/gmxana/gmx_wheel.cpp | 133 +- src/gromacs/gmxana/gmx_xpm2ps.cpp | 793 +-- src/gromacs/gmxana/gstat.h | 207 +- src/gromacs/gmxana/hxprops.cpp | 282 +- src/gromacs/gmxana/hxprops.h | 111 +- src/gromacs/gmxana/interf.h | 7 +- src/gromacs/gmxana/nrama.cpp | 73 +- src/gromacs/gmxana/nrama.h | 40 +- src/gromacs/gmxana/nsfactor.cpp | 133 +- src/gromacs/gmxana/nsfactor.h | 71 +- src/gromacs/gmxana/powerspect.cpp | 48 +- src/gromacs/gmxana/powerspect.h | 12 +- src/gromacs/gmxana/pp2shift.cpp | 101 +- src/gromacs/gmxana/princ.cpp | 113 +- src/gromacs/gmxana/princ.h | 16 +- src/gromacs/gmxana/sfactor.cpp | 428 +- src/gromacs/gmxana/sfactor.h | 59 +- src/gromacs/gmxana/tests/entropy.cpp | 81 +- src/gromacs/gmxana/tests/gmx_make_ndx.cpp | 32 +- src/gromacs/gmxana/tests/gmx_mindist.cpp | 104 +- src/gromacs/gmxana/tests/gmx_msd.cpp | 145 +- src/gromacs/gmxana/tests/gmx_traj.cpp | 40 +- src/gromacs/gmxana/thermochemistry.cpp | 116 +- src/gromacs/gmxana/thermochemistry.h | 24 +- src/gromacs/gmxlib/conformation_utilities.cpp | 29 +- src/gromacs/gmxlib/conformation_utilities.h | 5 +- src/gromacs/gmxlib/network.cpp | 140 +- src/gromacs/gmxlib/network.h | 45 +- .../gmxlib/nonbonded/nb_free_energy.cpp | 640 ++- src/gromacs/gmxlib/nonbonded/nb_free_energy.h | 15 +- src/gromacs/gmxlib/nonbonded/nb_kernel.h | 34 +- src/gromacs/gmxlib/nonbonded/nonbonded.h | 10 +- src/gromacs/gmxlib/nrnb.cpp | 411 +- src/gromacs/gmxlib/nrnb.h | 149 +- src/gromacs/gmxpreprocess/add_par.cpp | 49 +- src/gromacs/gmxpreprocess/add_par.h | 22 +- src/gromacs/gmxpreprocess/calch.cpp | 153 +- src/gromacs/gmxpreprocess/calch.h | 4 +- src/gromacs/gmxpreprocess/convparm.cpp | 214 +- src/gromacs/gmxpreprocess/convparm.h | 11 +- src/gromacs/gmxpreprocess/editconf.cpp | 459 +- src/gromacs/gmxpreprocess/editconf.h | 2 +- src/gromacs/gmxpreprocess/fflibutil.cpp | 63 +- src/gromacs/gmxpreprocess/fflibutil.h | 16 +- src/gromacs/gmxpreprocess/gen_ad.cpp | 277 +- src/gromacs/gmxpreprocess/gen_ad.h | 12 +- .../gmxpreprocess/gen_maxwell_velocities.cpp | 66 +- .../gmxpreprocess/gen_maxwell_velocities.h | 7 +- src/gromacs/gmxpreprocess/gen_vsite.cpp | 1340 ++--- src/gromacs/gmxpreprocess/gen_vsite.h | 19 +- src/gromacs/gmxpreprocess/genconf.cpp | 130 +- src/gromacs/gmxpreprocess/genconf.h | 4 +- src/gromacs/gmxpreprocess/genhydro.cpp | 233 +- src/gromacs/gmxpreprocess/genhydro.h | 8 +- src/gromacs/gmxpreprocess/genion.cpp | 250 +- src/gromacs/gmxpreprocess/genion.h | 2 +- src/gromacs/gmxpreprocess/genrestr.cpp | 130 +- src/gromacs/gmxpreprocess/genrestr.h | 2 +- src/gromacs/gmxpreprocess/gmxcpp.cpp | 189 +- src/gromacs/gmxpreprocess/gmxcpp.h | 35 +- src/gromacs/gmxpreprocess/gpp_atomtype.cpp | 139 +- src/gromacs/gmxpreprocess/gpp_atomtype.h | 312 +- .../gmxpreprocess/gpp_bond_atomtype.cpp | 26 +- src/gromacs/gmxpreprocess/gpp_bond_atomtype.h | 85 +- src/gromacs/gmxpreprocess/gpp_nextnb.cpp | 105 +- src/gromacs/gmxpreprocess/gpp_nextnb.h | 24 +- src/gromacs/gmxpreprocess/grompp.cpp | 1079 ++-- src/gromacs/gmxpreprocess/grompp.h | 4 +- src/gromacs/gmxpreprocess/grompp_impl.h | 166 +- src/gromacs/gmxpreprocess/h_db.cpp | 56 +- src/gromacs/gmxpreprocess/h_db.h | 8 +- src/gromacs/gmxpreprocess/hackblock.cpp | 46 +- src/gromacs/gmxpreprocess/hackblock.h | 106 +- src/gromacs/gmxpreprocess/hizzie.cpp | 79 +- src/gromacs/gmxpreprocess/hizzie.h | 2 +- .../gmxpreprocess/insert_molecules.cpp | 395 +- src/gromacs/gmxpreprocess/insert_molecules.h | 8 +- .../gmxpreprocess/makeexclusiondistances.cpp | 9 +- .../gmxpreprocess/makeexclusiondistances.h | 4 +- src/gromacs/gmxpreprocess/nm2type.cpp | 114 +- src/gromacs/gmxpreprocess/nm2type.h | 23 +- src/gromacs/gmxpreprocess/pdb2gmx.cpp | 1390 ++--- src/gromacs/gmxpreprocess/pdb2gmx.h | 10 +- src/gromacs/gmxpreprocess/pdb2top.cpp | 707 ++- src/gromacs/gmxpreprocess/pdb2top.h | 115 +- src/gromacs/gmxpreprocess/pgutil.cpp | 47 +- src/gromacs/gmxpreprocess/pgutil.h | 9 +- src/gromacs/gmxpreprocess/readir.cpp | 1903 ++++--- src/gromacs/gmxpreprocess/readir.h | 116 +- src/gromacs/gmxpreprocess/readpull.cpp | 281 +- src/gromacs/gmxpreprocess/readrot.cpp | 100 +- src/gromacs/gmxpreprocess/resall.cpp | 193 +- src/gromacs/gmxpreprocess/resall.h | 21 +- src/gromacs/gmxpreprocess/solvate.cpp | 370 +- src/gromacs/gmxpreprocess/solvate.h | 4 +- src/gromacs/gmxpreprocess/specbond.cpp | 124 +- src/gromacs/gmxpreprocess/specbond.h | 5 +- src/gromacs/gmxpreprocess/ter_db.cpp | 164 +- src/gromacs/gmxpreprocess/ter_db.h | 12 +- src/gromacs/gmxpreprocess/tests/editconf.cpp | 77 +- src/gromacs/gmxpreprocess/tests/genconf.cpp | 53 +- src/gromacs/gmxpreprocess/tests/genion.cpp | 75 +- .../gmxpreprocess/tests/gpp_atomtype.cpp | 43 +- .../gmxpreprocess/tests/gpp_bond_atomtype.cpp | 30 +- .../gmxpreprocess/tests/insert_molecules.cpp | 53 +- src/gromacs/gmxpreprocess/tests/pdb2gmx.cpp | 248 +- src/gromacs/gmxpreprocess/tests/readir.cpp | 154 +- src/gromacs/gmxpreprocess/tests/solvate.cpp | 47 +- src/gromacs/gmxpreprocess/tomorse.cpp | 55 +- src/gromacs/gmxpreprocess/tomorse.h | 2 +- src/gromacs/gmxpreprocess/topdirs.cpp | 292 +- src/gromacs/gmxpreprocess/topdirs.h | 18 +- src/gromacs/gmxpreprocess/topio.cpp | 573 ++- src/gromacs/gmxpreprocess/topio.h | 40 +- src/gromacs/gmxpreprocess/toppush.cpp | 1146 ++--- src/gromacs/gmxpreprocess/toppush.h | 132 +- src/gromacs/gmxpreprocess/topshake.cpp | 94 +- src/gromacs/gmxpreprocess/topshake.h | 2 +- src/gromacs/gmxpreprocess/toputil.cpp | 200 +- src/gromacs/gmxpreprocess/toputil.h | 15 +- src/gromacs/gmxpreprocess/vsite_parm.cpp | 811 +-- src/gromacs/gmxpreprocess/vsite_parm.h | 6 +- src/gromacs/gmxpreprocess/x2top.cpp | 318 +- src/gromacs/gmxpreprocess/x2top.h | 4 +- src/gromacs/gmxpreprocess/xlate.cpp | 95 +- src/gromacs/gmxpreprocess/xlate.h | 13 +- src/gromacs/gpu_utils/clfftinitializer.cpp | 14 +- src/gromacs/gpu_utils/clfftinitializer.h | 26 +- src/gromacs/gpu_utils/cuda_arch_utils.cuh | 38 +- src/gromacs/gpu_utils/cuda_kernel_utils.cuh | 17 +- src/gromacs/gpu_utils/cudautils.cu | 54 +- src/gromacs/gpu_utils/cudautils.cuh | 156 +- src/gromacs/gpu_utils/device_utils.clh | 31 +- src/gromacs/gpu_utils/devicebuffer.cuh | 74 +- src/gromacs/gpu_utils/devicebuffer.h | 14 +- src/gromacs/gpu_utils/devicebuffer_datatype.h | 35 +- src/gromacs/gpu_utils/devicebuffer_ocl.h | 76 +- src/gromacs/gpu_utils/gmxopencl.h | 10 +- src/gromacs/gpu_utils/gpu_macros.h | 107 +- src/gromacs/gpu_utils/gpu_testutils.cpp | 2 +- src/gromacs/gpu_utils/gpu_utils.cpp | 29 +- src/gromacs/gpu_utils/gpu_utils.cu | 150 +- src/gromacs/gpu_utils/gpu_utils.h | 34 +- src/gromacs/gpu_utils/gpu_utils_ocl.cpp | 151 +- src/gromacs/gpu_utils/gpu_vec.cuh | 148 +- .../gpu_utils/gpueventsynchronizer.cuh | 78 +- .../gpu_utils/gpueventsynchronizer_ocl.h | 126 +- src/gromacs/gpu_utils/gpuregiontimer.cuh | 93 +- src/gromacs/gpu_utils/gpuregiontimer.h | 178 +- src/gromacs/gpu_utils/gpuregiontimer_ocl.h | 113 +- src/gromacs/gpu_utils/gputraits.cuh | 12 +- src/gromacs/gpu_utils/gputraits.h | 10 +- src/gromacs/gpu_utils/gputraits_ocl.h | 10 +- src/gromacs/gpu_utils/hostallocator.cpp | 17 +- src/gromacs/gpu_utils/hostallocator.h | 137 +- src/gromacs/gpu_utils/ocl_caching.cpp | 48 +- src/gromacs/gpu_utils/ocl_caching.h | 13 +- src/gromacs/gpu_utils/ocl_compiler.cpp | 208 +- src/gromacs/gpu_utils/ocl_compiler.h | 35 +- src/gromacs/gpu_utils/oclraii.h | 59 +- src/gromacs/gpu_utils/oclutils.cpp | 67 +- src/gromacs/gpu_utils/oclutils.h | 130 +- src/gromacs/gpu_utils/pinning.cu | 45 +- src/gromacs/gpu_utils/pinning.h | 4 +- src/gromacs/gpu_utils/pmalloc_cuda.cu | 8 +- src/gromacs/gpu_utils/pmalloc_cuda.h | 8 +- .../gpu_utils/tests/devicetransfers.cpp | 6 +- .../gpu_utils/tests/devicetransfers.cu | 17 +- src/gromacs/gpu_utils/tests/devicetransfers.h | 6 +- .../gpu_utils/tests/devicetransfers_ocl.cpp | 25 +- src/gromacs/gpu_utils/tests/gputest.cpp | 4 +- src/gromacs/gpu_utils/tests/gputest.h | 20 +- src/gromacs/gpu_utils/tests/hostallocator.cpp | 103 +- .../gpu_utils/tests/pinnedmemorychecker.cpp | 6 +- src/gromacs/gpu_utils/vectype_ops.clh | 4 +- src/gromacs/gpu_utils/vectype_ops.cuh | 53 +- src/gromacs/hardware/architecture.h | 25 +- src/gromacs/hardware/cpuinfo.cpp | 563 +- src/gromacs/hardware/cpuinfo.h | 376 +- src/gromacs/hardware/detecthardware.cpp | 144 +- src/gromacs/hardware/detecthardware.h | 6 +- src/gromacs/hardware/gpu_hw_info.cpp | 8 +- src/gromacs/hardware/gpu_hw_info.h | 17 +- src/gromacs/hardware/hardwaretopology.cpp | 294 +- src/gromacs/hardware/hardwaretopology.h | 358 +- src/gromacs/hardware/hw_info.h | 56 +- .../hardware/identifyavx512fmaunits.cpp | 262 +- src/gromacs/hardware/identifyavx512fmaunits.h | 5 +- src/gromacs/hardware/printhardware.cpp | 128 +- src/gromacs/hardware/printhardware.h | 6 +- src/gromacs/hardware/tests/cpuinfo.cpp | 23 +- .../hardware/tests/hardwaretopology.cpp | 82 +- src/gromacs/imd/imd.cpp | 796 ++- src/gromacs/imd/imd.h | 202 +- src/gromacs/imd/imdsocket.cpp | 105 +- src/gromacs/imd/imdsocket.h | 20 +- src/gromacs/linearalgebra/eigensolver.cpp | 217 +- src/gromacs/linearalgebra/eigensolver.h | 18 +- src/gromacs/linearalgebra/gmx_arpack.cpp | 1944 +++---- src/gromacs/linearalgebra/gmx_arpack.h | 169 +- src/gromacs/linearalgebra/gmx_blas.h | 368 +- src/gromacs/linearalgebra/gmx_lapack.h | 2500 ++++++--- src/gromacs/linearalgebra/matrix.cpp | 51 +- src/gromacs/linearalgebra/matrix.h | 13 +- src/gromacs/linearalgebra/nrjac.cpp | 73 +- src/gromacs/linearalgebra/nrjac.h | 6 +- src/gromacs/linearalgebra/sparsematrix.cpp | 83 +- src/gromacs/linearalgebra/sparsematrix.h | 56 +- src/gromacs/listed_forces/bonded.cpp | 3290 ++++++------ src/gromacs/listed_forces/bonded.h | 111 +- src/gromacs/listed_forces/disre.cpp | 275 +- src/gromacs/listed_forces/disre.h | 46 +- src/gromacs/listed_forces/gpubonded.h | 86 +- src/gromacs/listed_forces/gpubonded_impl.cpp | 62 +- src/gromacs/listed_forces/gpubonded_impl.cu | 154 +- src/gromacs/listed_forces/gpubonded_impl.h | 168 +- src/gromacs/listed_forces/gpubondedkernels.cu | 610 +-- src/gromacs/listed_forces/listed_forces.cpp | 370 +- src/gromacs/listed_forces/listed_forces.h | 121 +- src/gromacs/listed_forces/listed_internal.cpp | 2 +- src/gromacs/listed_forces/listed_internal.h | 103 +- .../listed_forces/manage_threading.cpp | 120 +- src/gromacs/listed_forces/manage_threading.h | 10 +- src/gromacs/listed_forces/orires.cpp | 325 +- src/gromacs/listed_forces/orires.h | 52 +- src/gromacs/listed_forces/pairs.cpp | 599 +-- src/gromacs/listed_forces/pairs.h | 26 +- .../listed_forces/position_restraints.cpp | 253 +- .../listed_forces/position_restraints.h | 48 +- src/gromacs/listed_forces/restcbt.cpp | 148 +- src/gromacs/listed_forces/restcbt.h | 61 +- src/gromacs/listed_forces/tests/bonded.cpp | 970 ++-- src/gromacs/listed_forces/utilities.h | 8 +- src/gromacs/math/3dtransforms.cpp | 31 +- src/gromacs/math/3dtransforms.h | 6 +- src/gromacs/math/arrayrefwithpadding.h | 220 +- src/gromacs/math/coordinatetransformation.cpp | 74 +- src/gromacs/math/coordinatetransformation.h | 102 +- src/gromacs/math/densityfit.cpp | 242 +- src/gromacs/math/densityfit.h | 66 +- src/gromacs/math/densityfittingforce.cpp | 110 +- src/gromacs/math/densityfittingforce.h | 66 +- src/gromacs/math/do_fit.cpp | 79 +- src/gromacs/math/do_fit.h | 23 +- src/gromacs/math/exponentialmovingaverage.cpp | 20 +- src/gromacs/math/exponentialmovingaverage.h | 68 +- src/gromacs/math/functions.cpp | 77 +- src/gromacs/math/functions.h | 118 +- src/gromacs/math/gausstransform.cpp | 260 +- src/gromacs/math/gausstransform.h | 222 +- src/gromacs/math/gmxcomplex.h | 37 +- src/gromacs/math/invertmatrix.cpp | 45 +- src/gromacs/math/matrix.h | 20 +- src/gromacs/math/multidimarray.h | 375 +- src/gromacs/math/paddedvector.h | 426 +- .../math/tests/arrayrefwithpadding.cpp | 144 +- .../math/tests/coordinatetransformation.cpp | 43 +- src/gromacs/math/tests/densityfit.cpp | 59 +- .../math/tests/densityfittingforce.cpp | 43 +- src/gromacs/math/tests/dofit.cpp | 23 +- .../math/tests/exponentialmovingaverage.cpp | 9 +- src/gromacs/math/tests/functions.cpp | 146 +- src/gromacs/math/tests/gausstransform.cpp | 138 +- src/gromacs/math/tests/invertmatrix.cpp | 32 +- src/gromacs/math/tests/matrix.cpp | 49 +- src/gromacs/math/tests/multidimarray.cpp | 104 +- src/gromacs/math/tests/paddedvector.cpp | 40 +- src/gromacs/math/tests/testarrayrefs.h | 35 +- src/gromacs/math/tests/vectypes.cpp | 28 +- src/gromacs/math/units.cpp | 86 +- src/gromacs/math/units.h | 120 +- src/gromacs/math/utilities.cpp | 27 +- src/gromacs/math/utilities.h | 38 +- src/gromacs/math/vec.h | 268 +- src/gromacs/math/veccompare.cpp | 47 +- src/gromacs/math/veccompare.h | 9 +- src/gromacs/math/vecdump.cpp | 55 +- src/gromacs/math/vecdump.h | 22 +- src/gromacs/math/vectypes.h | 377 +- src/gromacs/mdlib/boxdeformation.cpp | 43 +- src/gromacs/mdlib/boxdeformation.h | 46 +- src/gromacs/mdlib/broadcaststructs.cpp | 43 +- src/gromacs/mdlib/broadcaststructs.h | 42 +- src/gromacs/mdlib/calc_verletbuf.cpp | 585 +-- src/gromacs/mdlib/calc_verletbuf.h | 37 +- src/gromacs/mdlib/calcmu.cpp | 29 +- src/gromacs/mdlib/calcmu.h | 15 +- src/gromacs/mdlib/calcvir.cpp | 145 +- src/gromacs/mdlib/calcvir.h | 8 +- src/gromacs/mdlib/checkpointhandler.cpp | 36 +- src/gromacs/mdlib/checkpointhandler.h | 111 +- src/gromacs/mdlib/compute_io.cpp | 40 +- src/gromacs/mdlib/compute_io.h | 3 +- src/gromacs/mdlib/constr.cpp | 721 ++- src/gromacs/mdlib/constr.h | 312 +- src/gromacs/mdlib/constraintrange.cpp | 90 +- src/gromacs/mdlib/constraintrange.h | 6 +- src/gromacs/mdlib/coupling.cpp | 697 +-- src/gromacs/mdlib/dispersioncorrection.cpp | 324 +- src/gromacs/mdlib/dispersioncorrection.h | 266 +- src/gromacs/mdlib/ebin.cpp | 102 +- src/gromacs/mdlib/ebin.h | 49 +- src/gromacs/mdlib/enerdata_utils.cpp | 98 +- src/gromacs/mdlib/enerdata_utils.h | 8 +- src/gromacs/mdlib/energyoutput.cpp | 557 +- src/gromacs/mdlib/energyoutput.h | 568 +-- src/gromacs/mdlib/expanded.cpp | 443 +- src/gromacs/mdlib/expanded.h | 31 +- src/gromacs/mdlib/force.cpp | 184 +- src/gromacs/mdlib/force.h | 101 +- src/gromacs/mdlib/force_flags.h | 20 +- src/gromacs/mdlib/forcerec.cpp | 599 ++- src/gromacs/mdlib/forcerec.h | 57 +- src/gromacs/mdlib/forcerec_threading.h | 13 +- src/gromacs/mdlib/gmx_omp_nthreads.cpp | 161 +- src/gromacs/mdlib/gmx_omp_nthreads.h | 28 +- src/gromacs/mdlib/groupcoord.cpp | 124 +- src/gromacs/mdlib/groupcoord.h | 33 +- src/gromacs/mdlib/leapfrog_cuda.cu | 186 +- src/gromacs/mdlib/leapfrog_cuda.cuh | 207 +- src/gromacs/mdlib/lincs.cpp | 1215 +++-- src/gromacs/mdlib/lincs.h | 59 +- src/gromacs/mdlib/lincs_cuda.cu | 392 +- src/gromacs/mdlib/lincs_cuda.cuh | 216 +- src/gromacs/mdlib/makeconstraints.h | 44 +- src/gromacs/mdlib/md_support.cpp | 203 +- src/gromacs/mdlib/md_support.h | 90 +- src/gromacs/mdlib/mdatoms.cpp | 161 +- src/gromacs/mdlib/mdatoms.h | 70 +- src/gromacs/mdlib/mdebin_bar.cpp | 186 +- src/gromacs/mdlib/mdebin_bar.h | 165 +- src/gromacs/mdlib/mdoutf.cpp | 197 +- src/gromacs/mdlib/mdoutf.h | 59 +- src/gromacs/mdlib/membed.cpp | 610 ++- src/gromacs/mdlib/membed.h | 16 +- src/gromacs/mdlib/nsgrid.cpp | 304 +- src/gromacs/mdlib/nsgrid.h | 115 +- src/gromacs/mdlib/perf_est.cpp | 212 +- src/gromacs/mdlib/perf_est.h | 6 +- src/gromacs/mdlib/qm_gamess.cpp | 170 +- src/gromacs/mdlib/qm_gamess.h | 7 +- src/gromacs/mdlib/qm_gaussian.cpp | 415 +- src/gromacs/mdlib/qm_gaussian.h | 8 +- src/gromacs/mdlib/qm_mopac.cpp | 115 +- src/gromacs/mdlib/qm_mopac.h | 11 +- src/gromacs/mdlib/qm_orca.cpp | 127 +- src/gromacs/mdlib/qm_orca.h | 11 +- src/gromacs/mdlib/qmmm.cpp | 315 +- src/gromacs/mdlib/qmmm.h | 120 +- src/gromacs/mdlib/rbin.cpp | 58 +- src/gromacs/mdlib/rbin.h | 27 +- src/gromacs/mdlib/resethandler.cpp | 72 +- src/gromacs/mdlib/resethandler.h | 166 +- src/gromacs/mdlib/rf_util.cpp | 20 +- src/gromacs/mdlib/rf_util.h | 4 +- src/gromacs/mdlib/settle.cpp | 423 +- src/gromacs/mdlib/settle.h | 52 +- src/gromacs/mdlib/settle_cuda.cu | 314 +- src/gromacs/mdlib/settle_cuda.cuh | 246 +- src/gromacs/mdlib/shake.cpp | 570 ++- src/gromacs/mdlib/shake.h | 66 +- src/gromacs/mdlib/sighandler.cpp | 43 +- src/gromacs/mdlib/sighandler.h | 6 +- src/gromacs/mdlib/sim_util.cpp | 843 ++- src/gromacs/mdlib/simulationsignal.cpp | 35 +- src/gromacs/mdlib/simulationsignal.h | 123 +- src/gromacs/mdlib/splitter.cpp | 99 +- src/gromacs/mdlib/splitter.h | 6 +- src/gromacs/mdlib/stat.cpp | 117 +- src/gromacs/mdlib/stat.h | 30 +- src/gromacs/mdlib/stophandler.cpp | 100 +- src/gromacs/mdlib/stophandler.h | 279 +- src/gromacs/mdlib/tests/calc_verletbuf.cpp | 30 +- src/gromacs/mdlib/tests/constr.cpp | 751 ++- src/gromacs/mdlib/tests/constrtestdata.cpp | 62 +- src/gromacs/mdlib/tests/constrtestdata.h | 248 +- src/gromacs/mdlib/tests/constrtestrunners.cpp | 68 +- src/gromacs/mdlib/tests/constrtestrunners.cu | 31 +- src/gromacs/mdlib/tests/constrtestrunners.h | 10 +- src/gromacs/mdlib/tests/ebin.cpp | 71 +- src/gromacs/mdlib/tests/energyoutput.cpp | 974 ++-- src/gromacs/mdlib/tests/leapfrog.cpp | 232 +- src/gromacs/mdlib/tests/leapfrogtestdata.cpp | 24 +- src/gromacs/mdlib/tests/leapfrogtestdata.h | 109 +- .../mdlib/tests/leapfrogtestrunners.cpp | 34 +- .../mdlib/tests/leapfrogtestrunners.cu | 41 +- src/gromacs/mdlib/tests/leapfrogtestrunners.h | 10 +- src/gromacs/mdlib/tests/settle.cpp | 403 +- src/gromacs/mdlib/tests/settletestdata.cpp | 50 +- src/gromacs/mdlib/tests/settletestdata.h | 76 +- src/gromacs/mdlib/tests/settletestrunners.cpp | 28 +- src/gromacs/mdlib/tests/settletestrunners.cu | 31 +- src/gromacs/mdlib/tests/settletestrunners.h | 16 +- src/gromacs/mdlib/tests/shake.cpp | 269 +- src/gromacs/mdlib/tests/simulationsignal.cpp | 22 +- src/gromacs/mdlib/tests/updategroups.cpp | 74 +- src/gromacs/mdlib/tests/updategroupscog.cpp | 92 +- src/gromacs/mdlib/tests/watersystem.h | 76 +- src/gromacs/mdlib/tgroup.cpp | 52 +- src/gromacs/mdlib/tgroup.h | 22 +- src/gromacs/mdlib/trajectory_writing.cpp | 68 +- src/gromacs/mdlib/trajectory_writing.h | 46 +- src/gromacs/mdlib/update.cpp | 1037 ++-- src/gromacs/mdlib/update.h | 314 +- src/gromacs/mdlib/update_constrain_cuda.h | 152 +- .../mdlib/update_constrain_cuda_impl.cpp | 55 +- .../mdlib/update_constrain_cuda_impl.cu | 91 +- .../mdlib/update_constrain_cuda_impl.h | 246 +- src/gromacs/mdlib/updategroups.cpp | 238 +- src/gromacs/mdlib/updategroups.h | 12 +- src/gromacs/mdlib/updategroupscog.cpp | 56 +- src/gromacs/mdlib/updategroupscog.h | 208 +- src/gromacs/mdlib/vcm.cpp | 166 +- src/gromacs/mdlib/vcm.h | 52 +- src/gromacs/mdlib/vsite.cpp | 1094 ++-- src/gromacs/mdlib/vsite.h | 93 +- src/gromacs/mdlib/wall.cpp | 209 +- src/gromacs/mdlib/wall.h | 27 +- src/gromacs/mdrun/isimulator.h | 310 +- src/gromacs/mdrun/legacymdrunoptions.cpp | 19 +- src/gromacs/mdrun/legacymdrunoptions.h | 475 +- src/gromacs/mdrun/legacysimulator.cpp | 27 +- src/gromacs/mdrun/legacysimulator.h | 52 +- src/gromacs/mdrun/md.cpp | 733 ++- src/gromacs/mdrun/mdmodules.cpp | 136 +- src/gromacs/mdrun/mdmodules.h | 171 +- src/gromacs/mdrun/mimic.cpp | 235 +- src/gromacs/mdrun/minimize.cpp | 1297 +++-- src/gromacs/mdrun/minimize.h | 2 +- src/gromacs/mdrun/replicaexchange.cpp | 371 +- src/gromacs/mdrun/replicaexchange.h | 33 +- src/gromacs/mdrun/rerun.cpp | 283 +- src/gromacs/mdrun/runner.cpp | 1012 ++-- src/gromacs/mdrun/runner.h | 882 ++-- src/gromacs/mdrun/shellfc.cpp | 576 +-- src/gromacs/mdrun/shellfc.h | 84 +- src/gromacs/mdrun/simulationcontext.cpp | 4 +- src/gromacs/mdrun/simulationcontext.h | 82 +- src/gromacs/mdrun/simulatorbuilder.h | 40 +- src/gromacs/mdrun/tpi.cpp | 323 +- src/gromacs/mdrunutility/handlerestart.cpp | 315 +- src/gromacs/mdrunutility/handlerestart.h | 13 +- src/gromacs/mdrunutility/logging.cpp | 25 +- src/gromacs/mdrunutility/logging.h | 11 +- src/gromacs/mdrunutility/multisim.cpp | 120 +- src/gromacs/mdrunutility/multisim.h | 48 +- src/gromacs/mdrunutility/printtime.cpp | 27 +- src/gromacs/mdrunutility/printtime.h | 14 +- .../mdrunutility/tests/threadaffinity.cpp | 11 +- .../mdrunutility/tests/threadaffinity_mpi.cpp | 57 +- .../mdrunutility/tests/threadaffinitytest.cpp | 16 +- .../mdrunutility/tests/threadaffinitytest.h | 219 +- src/gromacs/mdrunutility/threadaffinity.cpp | 296 +- src/gromacs/mdrunutility/threadaffinity.h | 41 +- src/gromacs/mdspan/accessor_policy.h | 63 +- src/gromacs/mdspan/extensions.h | 48 +- src/gromacs/mdspan/extents.h | 304 +- src/gromacs/mdspan/layouts.h | 227 +- src/gromacs/mdspan/mdspan.h | 447 +- src/gromacs/mdspan/tests/accessor_policy.cpp | 22 +- src/gromacs/mdspan/tests/extensions.cpp | 113 +- src/gromacs/mdspan/tests/extents.cpp | 129 +- src/gromacs/mdspan/tests/layouts.cpp | 55 +- src/gromacs/mdspan/tests/mdspan.cpp | 105 +- src/gromacs/mdtypes/awh_correlation_history.h | 30 +- src/gromacs/mdtypes/awh_history.h | 74 +- src/gromacs/mdtypes/awh_params.h | 85 +- src/gromacs/mdtypes/commrec.h | 51 +- src/gromacs/mdtypes/df_history.cpp | 20 +- src/gromacs/mdtypes/df_history.h | 8 +- src/gromacs/mdtypes/edsamhistory.h | 21 +- src/gromacs/mdtypes/enerdata.h | 33 +- src/gromacs/mdtypes/energyhistory.h | 62 +- src/gromacs/mdtypes/fcdata.h | 74 +- src/gromacs/mdtypes/forceoutput.h | 246 +- src/gromacs/mdtypes/forcerec.h | 132 +- src/gromacs/mdtypes/group.h | 75 +- src/gromacs/mdtypes/iforceprovider.cpp | 21 +- src/gromacs/mdtypes/iforceprovider.h | 138 +- src/gromacs/mdtypes/imdmodule.h | 16 +- src/gromacs/mdtypes/imdoutputprovider.h | 37 +- src/gromacs/mdtypes/imdpoptionprovider.h | 50 +- src/gromacs/mdtypes/inputrec.cpp | 413 +- src/gromacs/mdtypes/inputrec.h | 504 +- src/gromacs/mdtypes/interaction_const.h | 10 +- src/gromacs/mdtypes/locality.h | 10 +- src/gromacs/mdtypes/md_enums.cpp | 240 +- src/gromacs/mdtypes/md_enums.h | 606 ++- src/gromacs/mdtypes/mdatom.h | 89 +- src/gromacs/mdtypes/mdrunoptions.h | 34 +- src/gromacs/mdtypes/nblist.h | 142 +- src/gromacs/mdtypes/pull_params.h | 75 +- src/gromacs/mdtypes/pullhistory.h | 59 +- src/gromacs/mdtypes/simulation_workload.h | 156 +- src/gromacs/mdtypes/state.cpp | 143 +- src/gromacs/mdtypes/state.h | 245 +- .../mdtypes/state_propagator_data_gpu.h | 552 +- .../state_propagator_data_gpu_impl.cpp | 174 +- .../mdtypes/state_propagator_data_gpu_impl.h | 750 ++- .../state_propagator_data_gpu_impl_gpu.cpp | 291 +- src/gromacs/mdtypes/swaphistory.h | 47 +- src/gromacs/mimic/communicator.cpp | 63 +- src/gromacs/mimic/communicator.h | 102 +- src/gromacs/mimic/utilities.cpp | 11 +- src/gromacs/mimic/utilities.h | 4 +- .../modularsimulator/checkpointhelper.cpp | 50 +- .../modularsimulator/checkpointhelper.h | 173 +- .../compositesimulatorelement.cpp | 19 +- .../compositesimulatorelement.h | 66 +- .../computeglobalselement.cpp | 223 +- .../modularsimulator/computeglobalselement.h | 294 +- .../modularsimulator/constraintelement.cpp | 115 +- .../modularsimulator/constraintelement.h | 135 +- src/gromacs/modularsimulator/domdechelper.cpp | 80 +- src/gromacs/modularsimulator/domdechelper.h | 154 +- .../modularsimulator/energyelement.cpp | 131 +- src/gromacs/modularsimulator/energyelement.h | 508 +- src/gromacs/modularsimulator/forceelement.cpp | 115 +- src/gromacs/modularsimulator/forceelement.h | 217 +- .../freeenergyperturbationelement.cpp | 34 +- .../freeenergyperturbationelement.h | 95 +- .../modularsimulator/modularsimulator.cpp | 684 +-- .../modularsimulator/modularsimulator.h | 416 +- .../modularsimulatorinterfaces.h | 249 +- .../parrinellorahmanbarostat.cpp | 61 +- .../parrinellorahmanbarostat.h | 165 +- .../modularsimulator/pmeloadbalancehelper.cpp | 54 +- .../modularsimulator/pmeloadbalancehelper.h | 107 +- src/gromacs/modularsimulator/propagator.cpp | 325 +- src/gromacs/modularsimulator/propagator.h | 139 +- .../modularsimulator/shellfcelement.cpp | 129 +- src/gromacs/modularsimulator/shellfcelement.h | 247 +- src/gromacs/modularsimulator/signallers.cpp | 92 +- src/gromacs/modularsimulator/signallers.h | 546 +- .../modularsimulator/statepropagatordata.cpp | 98 +- .../modularsimulator/statepropagatordata.h | 305 +- .../modularsimulator/topologyholder.cpp | 28 +- src/gromacs/modularsimulator/topologyholder.h | 51 +- .../modularsimulator/trajectoryelement.cpp | 95 +- .../modularsimulator/trajectoryelement.h | 332 +- .../modularsimulator/vrescalethermostat.cpp | 60 +- .../modularsimulator/vrescalethermostat.h | 150 +- src/gromacs/nbnxm/atomdata.cpp | 694 ++- src/gromacs/nbnxm/atomdata.h | 249 +- src/gromacs/nbnxm/benchmark/bench_coords.h | 4510 ++++++----------- src/gromacs/nbnxm/benchmark/bench_setup.cpp | 195 +- src/gromacs/nbnxm/benchmark/bench_setup.h | 31 +- src/gromacs/nbnxm/benchmark/bench_system.cpp | 55 +- src/gromacs/nbnxm/benchmark/bench_system.h | 18 +- src/gromacs/nbnxm/boundingboxes.h | 38 +- src/gromacs/nbnxm/clusterdistancekerneltype.h | 11 +- src/gromacs/nbnxm/constants.h | 8 +- .../nbnxm/cuda/nbnxm_buffer_ops_kernels.cuh | 95 +- src/gromacs/nbnxm/cuda/nbnxm_cuda.cu | 484 +- .../nbnxm/cuda/nbnxm_cuda_data_mgmt.cu | 367 +- src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel.cuh | 597 +-- .../nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cu | 6 +- .../cuda/nbnxm_cuda_kernel_pruneonly.cuh | 108 +- .../nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh | 449 +- src/gromacs/nbnxm/cuda/nbnxm_cuda_kernels.cuh | 84 +- src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h | 181 +- src/gromacs/nbnxm/gpu_common.h | 144 +- src/gromacs/nbnxm/gpu_common_utils.h | 10 +- src/gromacs/nbnxm/gpu_data_mgmt.h | 56 +- src/gromacs/nbnxm/gpu_jit_support.h | 3 +- src/gromacs/nbnxm/gpu_types.h | 12 +- src/gromacs/nbnxm/gpu_types_common.h | 43 +- src/gromacs/nbnxm/grid.cpp | 724 ++- src/gromacs/nbnxm/grid.h | 575 +-- src/gromacs/nbnxm/gridset.cpp | 87 +- src/gromacs/nbnxm/gridset.h | 260 +- src/gromacs/nbnxm/kernel_common.cpp | 43 +- src/gromacs/nbnxm/kernel_common.h | 60 +- src/gromacs/nbnxm/kerneldispatch.cpp | 288 +- .../kernels_reference/kernel_gpu_ref.cpp | 261 +- .../nbnxm/kernels_reference/kernel_gpu_ref.h | 21 +- .../nbnxm/kernels_reference/kernel_ref.h | 222 +- .../kernels_reference/kernel_ref_inner.h | 300 +- .../kernels_reference/kernel_ref_outer.h | 291 +- .../kernels_reference/kernel_ref_prune.cpp | 48 +- .../kernels_reference/kernel_ref_prune.h | 9 +- .../kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp | 40 +- ...rnel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp | 40 +- ...kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp | 40 +- ...kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp | 40 +- ...ernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp | 40 +- ...el_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJ_F.cpp | 40 +- .../kernel_ElecEw_VdwLJ_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJ_VgrpF.cpp | 40 +- ...ernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp | 40 +- ...rnel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp | 40 +- ...l_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp | 40 +- ...nel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp | 40 +- ...nel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp | 40 +- ...el_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp | 40 +- ...ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp | 40 +- ...kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJ_F.cpp | 40 +- .../kernel_ElecRF_VdwLJ_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJ_VgrpF.cpp | 40 +- .../nbnxm/kernels_simd_2xmm/kernel_common.h | 59 +- .../nbnxm/kernels_simd_2xmm/kernel_inner.h | 1141 ++--- .../nbnxm/kernels_simd_2xmm/kernel_outer.h | 583 +-- .../nbnxm/kernels_simd_2xmm/kernel_prune.cpp | 111 +- .../nbnxm/kernels_simd_2xmm/kernel_prune.h | 9 +- src/gromacs/nbnxm/kernels_simd_2xmm/kernels.h | 370 +- .../kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp | 40 +- ...rnel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp | 40 +- ...kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp | 40 +- ...kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp | 40 +- ...ernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp | 40 +- ...el_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_F.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_VF.cpp | 40 +- .../kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecEw_VdwLJ_F.cpp | 40 +- .../kernel_ElecEw_VdwLJ_VF.cpp | 40 +- .../kernel_ElecEw_VdwLJ_VgrpF.cpp | 40 +- ...ernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp | 40 +- ...rnel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp | 40 +- ...l_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp | 40 +- ...nel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp | 40 +- ...nel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp | 40 +- ...el_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp | 40 +- ...ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp | 40 +- ...kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_F.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp | 40 +- .../kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp | 40 +- ...kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_F.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_VF.cpp | 40 +- .../kernel_ElecQSTab_VdwLJ_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_F.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_F.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJCombLB_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_F.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_F.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJFSw_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_F.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJPSw_VgrpF.cpp | 40 +- .../kernel_ElecRF_VdwLJ_F.cpp | 40 +- .../kernel_ElecRF_VdwLJ_VF.cpp | 40 +- .../kernel_ElecRF_VdwLJ_VgrpF.cpp | 40 +- .../nbnxm/kernels_simd_4xm/kernel_common.h | 90 +- .../nbnxm/kernels_simd_4xm/kernel_inner.h | 1755 +++---- .../nbnxm/kernels_simd_4xm/kernel_outer.h | 659 +-- .../nbnxm/kernels_simd_4xm/kernel_prune.cpp | 139 +- .../nbnxm/kernels_simd_4xm/kernel_prune.h | 9 +- src/gromacs/nbnxm/kernels_simd_4xm/kernels.h | 370 +- src/gromacs/nbnxm/nbnxm.cpp | 114 +- src/gromacs/nbnxm/nbnxm.h | 456 +- src/gromacs/nbnxm/nbnxm_geometry.cpp | 21 +- src/gromacs/nbnxm/nbnxm_geometry.h | 44 +- src/gromacs/nbnxm/nbnxm_gpu.h | 129 +- src/gromacs/nbnxm/nbnxm_setup.cpp | 240 +- src/gromacs/nbnxm/nbnxm_simd.h | 18 +- src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp | 402 +- src/gromacs/nbnxm/opencl/nbnxm_ocl_consts.h | 4 +- .../nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp | 445 +- src/gromacs/nbnxm/opencl/nbnxm_ocl_internal.h | 8 +- .../nbnxm/opencl/nbnxm_ocl_jit_support.cpp | 48 +- src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel.clh | 448 +- .../opencl/nbnxm_ocl_kernel_pruneonly.clh | 107 +- .../nbnxm/opencl/nbnxm_ocl_kernel_utils.clh | 697 ++- src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.cl | 13 +- .../nbnxm/opencl/nbnxm_ocl_kernels.clh | 84 +- .../opencl/nbnxm_ocl_kernels_fastgen.clh | 4 +- .../nbnxm_ocl_kernels_fastgen_add_twincut.clh | 8 +- src/gromacs/nbnxm/opencl/nbnxm_ocl_types.h | 202 +- src/gromacs/nbnxm/pairlist.cpp | 2137 ++++---- src/gromacs/nbnxm/pairlist.h | 102 +- src/gromacs/nbnxm/pairlist_simd_2xmm.h | 161 +- src/gromacs/nbnxm/pairlist_simd_4xm.h | 232 +- src/gromacs/nbnxm/pairlist_tuning.cpp | 268 +- src/gromacs/nbnxm/pairlist_tuning.h | 26 +- src/gromacs/nbnxm/pairlistparams.cpp | 15 +- src/gromacs/nbnxm/pairlistparams.h | 31 +- src/gromacs/nbnxm/pairlistset.h | 135 +- src/gromacs/nbnxm/pairlistsets.h | 165 +- src/gromacs/nbnxm/pairlistwork.h | 48 +- src/gromacs/nbnxm/pairsearch.cpp | 30 +- src/gromacs/nbnxm/pairsearch.h | 218 +- src/gromacs/nbnxm/prunekerneldispatch.cpp | 26 +- src/gromacs/onlinehelp/helpformat.cpp | 292 +- src/gromacs/onlinehelp/helpformat.h | 243 +- src/gromacs/onlinehelp/helpmanager.cpp | 90 +- src/gromacs/onlinehelp/helpmanager.h | 71 +- src/gromacs/onlinehelp/helptopic.cpp | 76 +- src/gromacs/onlinehelp/helptopic.h | 212 +- src/gromacs/onlinehelp/helpwritercontext.cpp | 580 +-- src/gromacs/onlinehelp/helpwritercontext.h | 389 +- src/gromacs/onlinehelp/ihelptopic.h | 72 +- src/gromacs/onlinehelp/rstparser.cpp | 34 +- src/gromacs/onlinehelp/rstparser.h | 136 +- src/gromacs/onlinehelp/tests/helpformat.cpp | 8 +- src/gromacs/onlinehelp/tests/helpmanager.cpp | 51 +- .../onlinehelp/tests/helpwritercontext.cpp | 220 +- .../onlinehelp/tests/mock_helptopic.cpp | 33 +- src/gromacs/onlinehelp/tests/mock_helptopic.h | 56 +- src/gromacs/options/abstractoption.cpp | 48 +- src/gromacs/options/abstractoption.h | 811 +-- src/gromacs/options/abstractoptionstorage.h | 457 +- src/gromacs/options/abstractsection.cpp | 12 +- src/gromacs/options/abstractsection.h | 152 +- src/gromacs/options/basicoptions.cpp | 213 +- src/gromacs/options/basicoptions.h | 820 +-- src/gromacs/options/basicoptionstorage.h | 282 +- src/gromacs/options/behaviorcollection.cpp | 21 +- src/gromacs/options/behaviorcollection.h | 44 +- src/gromacs/options/filenameoption.cpp | 177 +- src/gromacs/options/filenameoption.h | 397 +- src/gromacs/options/filenameoptionmanager.cpp | 115 +- src/gromacs/options/filenameoptionmanager.h | 174 +- src/gromacs/options/filenameoptionstorage.h | 95 +- src/gromacs/options/ioptionsbehavior.h | 54 +- src/gromacs/options/ioptionscontainer.h | 125 +- .../options/ioptionscontainerwithsections.h | 73 +- src/gromacs/options/isectionstorage.h | 38 +- src/gromacs/options/ivaluestore.h | 31 +- src/gromacs/options/optionfiletype.h | 3 +- src/gromacs/options/optionflags.h | 24 +- src/gromacs/options/optionmanagercontainer.h | 81 +- src/gromacs/options/options.cpp | 87 +- src/gromacs/options/options.h | 129 +- src/gromacs/options/options_impl.h | 238 +- src/gromacs/options/optionsassigner.cpp | 132 +- src/gromacs/options/optionsassigner.h | 232 +- src/gromacs/options/optionsection.cpp | 10 +- src/gromacs/options/optionsection.h | 38 +- src/gromacs/options/optionstoragetemplate.h | 621 ++- src/gromacs/options/optionsvisitor.cpp | 42 +- src/gromacs/options/optionsvisitor.h | 158 +- src/gromacs/options/repeatingsection.h | 174 +- .../options/tests/abstractoptionstorage.cpp | 192 +- src/gromacs/options/tests/filenameoption.cpp | 81 +- .../options/tests/filenameoptionmanager.cpp | 122 +- src/gromacs/options/tests/option.cpp | 6 +- src/gromacs/options/tests/optionsassigner.cpp | 182 +- .../options/tests/repeatingsection.cpp | 50 +- src/gromacs/options/tests/timeunitmanager.cpp | 26 +- src/gromacs/options/tests/treesupport.cpp | 227 +- src/gromacs/options/timeunitmanager.cpp | 103 +- src/gromacs/options/timeunitmanager.h | 174 +- src/gromacs/options/treesupport.cpp | 370 +- src/gromacs/options/treesupport.h | 15 +- src/gromacs/options/valueconverter.h | 98 +- src/gromacs/options/valuestore.h | 179 +- src/gromacs/pbcutil/boxutilities.cpp | 34 +- src/gromacs/pbcutil/boxutilities.h | 5 +- src/gromacs/pbcutil/ishift.h | 24 +- src/gromacs/pbcutil/mshift.cpp | 350 +- src/gromacs/pbcutil/mshift.h | 60 +- src/gromacs/pbcutil/pbc.cpp | 339 +- src/gromacs/pbcutil/pbc.h | 77 +- src/gromacs/pbcutil/pbc_aiuc.h | 37 +- src/gromacs/pbcutil/pbc_aiuc_cuda.cuh | 54 +- src/gromacs/pbcutil/pbc_simd.cpp | 29 +- src/gromacs/pbcutil/pbc_simd.h | 40 +- src/gromacs/pbcutil/pbcenums.cpp | 24 +- src/gromacs/pbcutil/pbcenums.h | 4 +- src/gromacs/pbcutil/pbcmethods.cpp | 139 +- src/gromacs/pbcutil/pbcmethods.h | 28 +- src/gromacs/pbcutil/rmpbc.cpp | 49 +- src/gromacs/pbcutil/rmpbc.h | 13 +- src/gromacs/pbcutil/tests/pbc.cpp | 4 +- src/gromacs/pulling/output.cpp | 189 +- src/gromacs/pulling/output.h | 8 +- src/gromacs/pulling/pull.cpp | 961 ++-- src/gromacs/pulling/pull.h | 113 +- src/gromacs/pulling/pull_internal.h | 170 +- src/gromacs/pulling/pull_rotation.cpp | 1744 +++---- src/gromacs/pulling/pull_rotation.h | 56 +- src/gromacs/pulling/pullutil.cpp | 487 +- src/gromacs/pulling/tests/pull.cpp | 168 +- src/gromacs/random/exponentialdistribution.h | 211 +- src/gromacs/random/gammadistribution.h | 313 +- src/gromacs/random/normaldistribution.h | 285 +- src/gromacs/random/seed.cpp | 15 +- src/gromacs/random/seed.h | 27 +- .../random/tabulatednormaldistribution.cpp | 10 +- .../random/tabulatednormaldistribution.h | 452 +- .../random/tests/exponentialdistribution.cpp | 48 +- .../random/tests/gammadistribution.cpp | 44 +- .../random/tests/normaldistribution.cpp | 34 +- src/gromacs/random/tests/seed.cpp | 6 +- .../tests/tabulatednormaldistribution.cpp | 70 +- src/gromacs/random/tests/threefry.cpp | 74 +- .../random/tests/uniformintdistribution.cpp | 44 +- .../random/tests/uniformrealdistribution.cpp | 42 +- src/gromacs/random/threefry.h | 970 ++-- src/gromacs/random/uniformintdistribution.h | 330 +- src/gromacs/random/uniformrealdistribution.h | 236 +- src/gromacs/restraint/manager.cpp | 68 +- src/gromacs/restraint/manager.h | 121 +- src/gromacs/restraint/restraintmdmodule.cpp | 79 +- src/gromacs/restraint/restraintmdmodule.h | 108 +- .../restraint/restraintmdmodule_impl.h | 385 +- src/gromacs/restraint/restraintpotential.h | 201 +- src/gromacs/restraint/tests/manager.cpp | 35 +- src/gromacs/selection/centerofmass.cpp | 127 +- src/gromacs/selection/centerofmass.h | 82 +- src/gromacs/selection/compiler.cpp | 472 +- src/gromacs/selection/compiler.h | 12 +- src/gromacs/selection/evaluate.cpp | 464 +- src/gromacs/selection/evaluate.h | 127 +- src/gromacs/selection/indexutil.cpp | 350 +- src/gromacs/selection/indexutil.h | 221 +- src/gromacs/selection/keywords.h | 33 +- src/gromacs/selection/mempool.cpp | 66 +- src/gromacs/selection/mempool.h | 24 +- src/gromacs/selection/nbsearch.cpp | 880 ++-- src/gromacs/selection/nbsearch.h | 822 +-- src/gromacs/selection/params.cpp | 405 +- src/gromacs/selection/parser_internal.h | 89 +- src/gromacs/selection/parsetree.cpp | 392 +- src/gromacs/selection/parsetree.h | 738 ++- src/gromacs/selection/poscalc.cpp | 424 +- src/gromacs/selection/poscalc.h | 366 +- src/gromacs/selection/position.cpp | 73 +- src/gromacs/selection/position.h | 51 +- src/gromacs/selection/scanner.h | 75 +- src/gromacs/selection/scanner_internal.cpp | 219 +- src/gromacs/selection/scanner_internal.h | 67 +- src/gromacs/selection/selection.cpp | 116 +- src/gromacs/selection/selection.h | 1157 ++--- src/gromacs/selection/selectioncollection.cpp | 308 +- src/gromacs/selection/selectioncollection.h | 603 ++- .../selection/selectioncollection_impl.h | 169 +- src/gromacs/selection/selectionenums.h | 39 +- src/gromacs/selection/selectionfileoption.h | 31 +- .../selection/selectionfileoptionstorage.h | 49 +- src/gromacs/selection/selectionoption.cpp | 80 +- src/gromacs/selection/selectionoption.h | 337 +- .../selection/selectionoptionbehavior.cpp | 202 +- .../selection/selectionoptionbehavior.h | 111 +- .../selection/selectionoptionmanager.cpp | 291 +- .../selection/selectionoptionmanager.h | 272 +- .../selection/selectionoptionstorage.h | 131 +- src/gromacs/selection/selelem.cpp | 212 +- src/gromacs/selection/selelem.h | 533 +- src/gromacs/selection/selhelp.cpp | 261 +- src/gromacs/selection/selmethod.cpp | 216 +- src/gromacs/selection/selmethod.h | 104 +- src/gromacs/selection/selparam.h | 25 +- src/gromacs/selection/selvalue.cpp | 29 +- src/gromacs/selection/selvalue.h | 56 +- src/gromacs/selection/sm_compare.cpp | 236 +- src/gromacs/selection/sm_distance.cpp | 126 +- src/gromacs/selection/sm_insolidangle.cpp | 302 +- src/gromacs/selection/sm_keywords.cpp | 502 +- src/gromacs/selection/sm_merge.cpp | 138 +- src/gromacs/selection/sm_permute.cpp | 92 +- src/gromacs/selection/sm_position.cpp | 153 +- src/gromacs/selection/sm_same.cpp | 184 +- src/gromacs/selection/sm_simple.cpp | 621 +-- src/gromacs/selection/symrec.cpp | 267 +- src/gromacs/selection/symrec.h | 329 +- src/gromacs/selection/tests/indexutil.cpp | 308 +- src/gromacs/selection/tests/nbsearch.cpp | 929 ++-- src/gromacs/selection/tests/poscalc.cpp | 242 +- .../selection/tests/selectioncollection.cpp | 799 +-- .../selection/tests/selectionoption.cpp | 139 +- src/gromacs/selection/tests/toputils.cpp | 103 +- src/gromacs/selection/tests/toputils.h | 110 +- .../impl_arm_neon/impl_arm_neon_definitions.h | 81 +- .../impl_arm_neon/impl_arm_neon_general.h | 7 +- .../impl_arm_neon/impl_arm_neon_simd4_float.h | 309 +- .../impl_arm_neon/impl_arm_neon_simd_float.h | 586 +-- .../impl_arm_neon/impl_arm_neon_util_float.h | 229 +- .../impl_arm_neon_asimd_definitions.h | 80 +- .../impl_arm_neon_asimd_simd4_float.h | 57 +- .../impl_arm_neon_asimd_simd_double.h | 551 +- .../impl_arm_neon_asimd_simd_float.h | 66 +- .../impl_arm_neon_asimd_util_double.h | 130 +- .../impl_ibm_vmx/impl_ibm_vmx_definitions.h | 84 +- .../simd/impl_ibm_vmx/impl_ibm_vmx_general.h | 7 +- .../impl_ibm_vmx/impl_ibm_vmx_simd4_float.h | 278 +- .../impl_ibm_vmx/impl_ibm_vmx_simd_float.h | 561 +- .../impl_ibm_vmx/impl_ibm_vmx_util_float.h | 205 +- .../impl_ibm_vsx/impl_ibm_vsx_definitions.h | 97 +- .../simd/impl_ibm_vsx/impl_ibm_vsx_general.h | 9 +- .../impl_ibm_vsx/impl_ibm_vsx_simd4_float.h | 271 +- .../impl_ibm_vsx/impl_ibm_vsx_simd_double.h | 691 +-- .../impl_ibm_vsx/impl_ibm_vsx_simd_float.h | 566 +-- .../impl_ibm_vsx/impl_ibm_vsx_util_double.h | 160 +- .../impl_ibm_vsx/impl_ibm_vsx_util_float.h | 303 +- src/gromacs/simd/impl_none/impl_none.h | 34 +- .../impl_reference_definitions.h | 96 +- .../impl_reference/impl_reference_general.h | 7 +- .../impl_reference_simd4_double.h | 279 +- .../impl_reference_simd4_float.h | 279 +- .../impl_reference_simd_double.h | 523 +- .../impl_reference_simd_float.h | 486 +- .../impl_reference_util_double.h | 305 +- .../impl_reference_util_float.h | 297 +- .../impl_sparc64_hpc_ace_common.h | 44 +- .../impl_sparc64_hpc_ace_simd_double.h | 248 +- .../impl_sparc64_hpc_ace_simd_float.h | 124 +- .../impl_x86_avx2_128_definitions.h | 80 +- .../impl_x86_avx2_128_simd_double.h | 37 +- .../impl_x86_avx2_128_simd_float.h | 43 +- .../impl_x86_avx2_128_util_double.h | 22 +- .../impl_x86_avx2_128_util_float.h | 24 +- .../impl_x86_avx2_256_definitions.h | 82 +- .../impl_x86_avx2_256_simd4_double.h | 32 +- .../impl_x86_avx2_256_simd4_float.h | 32 +- .../impl_x86_avx2_256_simd_double.h | 79 +- .../impl_x86_avx2_256_simd_float.h | 203 +- .../impl_x86_avx2_256_util_double.h | 21 +- .../impl_x86_avx2_256_util_float.h | 21 +- .../impl_x86_avx_128_fma_definitions.h | 86 +- .../impl_x86_avx_128_fma_simd4_double.h | 274 +- .../impl_x86_avx_128_fma_simd4_float.h | 37 +- .../impl_x86_avx_128_fma_simd_double.h | 37 +- .../impl_x86_avx_128_fma_simd_float.h | 43 +- .../impl_x86_avx_128_fma_util_double.h | 22 +- .../impl_x86_avx_128_fma_util_float.h | 24 +- .../impl_x86_avx_256_definitions.h | 82 +- .../impl_x86_avx_256_general.h | 9 +- .../impl_x86_avx_256_simd4_double.h | 275 +- .../impl_x86_avx_256_simd4_float.h | 267 +- .../impl_x86_avx_256_simd_double.h | 567 +-- .../impl_x86_avx_256_simd_float.h | 404 +- .../impl_x86_avx_256_util_double.h | 216 +- .../impl_x86_avx_256_util_float.h | 664 ++- .../simd/impl_x86_avx_512/impl_x86_avx_512.h | 3 +- .../impl_x86_avx_512_definitions.h | 84 +- .../impl_x86_avx_512_general.h | 15 +- .../impl_x86_avx_512_simd4_double.h | 275 +- .../impl_x86_avx_512_simd4_float.h | 269 +- .../impl_x86_avx_512_simd_double.h | 567 +-- .../impl_x86_avx_512_simd_float.h | 546 +- .../impl_x86_avx_512_util_double.h | 268 +- .../impl_x86_avx_512_util_float.h | 345 +- .../impl_x86_avx_512_knl_definitions.h | 84 +- .../impl_x86_avx_512_knl_simd4_double.h | 14 +- .../impl_x86_avx_512_knl_simd4_float.h | 14 +- .../impl_x86_avx_512_knl_simd_double.h | 32 +- .../impl_x86_avx_512_knl_simd_float.h | 56 +- .../impl_x86_mic/impl_x86_mic_definitions.h | 80 +- .../simd/impl_x86_mic/impl_x86_mic_general.h | 9 +- .../impl_x86_mic/impl_x86_mic_simd4_double.h | 304 +- .../impl_x86_mic/impl_x86_mic_simd4_float.h | 322 +- .../impl_x86_mic/impl_x86_mic_simd_double.h | 540 +- .../impl_x86_mic/impl_x86_mic_simd_float.h | 570 +-- .../impl_x86_mic/impl_x86_mic_util_double.h | 274 +- .../impl_x86_mic/impl_x86_mic_util_float.h | 257 +- .../impl_x86_sse2/impl_x86_sse2_definitions.h | 80 +- .../impl_x86_sse2/impl_x86_sse2_general.h | 9 +- .../impl_x86_sse2/impl_x86_sse2_simd4_float.h | 271 +- .../impl_x86_sse2/impl_x86_sse2_simd_double.h | 579 +-- .../impl_x86_sse2/impl_x86_sse2_simd_float.h | 569 +-- .../impl_x86_sse2/impl_x86_sse2_util_double.h | 217 +- .../impl_x86_sse2/impl_x86_sse2_util_float.h | 352 +- .../impl_x86_sse4_1_definitions.h | 80 +- .../impl_x86_sse4_1_simd4_float.h | 30 +- .../impl_x86_sse4_1_simd_double.h | 80 +- .../impl_x86_sse4_1_simd_float.h | 65 +- src/gromacs/simd/scalar/scalar.h | 203 +- src/gromacs/simd/scalar/scalar_math.h | 577 +-- src/gromacs/simd/scalar/scalar_util.h | 298 +- src/gromacs/simd/simd.h | 341 +- src/gromacs/simd/simd_math.h | 4364 ++++++++-------- src/gromacs/simd/simd_memory.h | 320 +- src/gromacs/simd/support.cpp | 138 +- src/gromacs/simd/support.h | 50 +- src/gromacs/simd/tests/base.cpp | 45 +- src/gromacs/simd/tests/base.h | 230 +- .../simd/tests/bootstrap_loadstore.cpp | 89 +- src/gromacs/simd/tests/data.h | 6 +- src/gromacs/simd/tests/scalar.cpp | 25 +- src/gromacs/simd/tests/scalar_math.cpp | 65 +- src/gromacs/simd/tests/scalar_util.cpp | 40 +- src/gromacs/simd/tests/simd.cpp | 181 +- src/gromacs/simd/tests/simd.h | 208 +- src/gromacs/simd/tests/simd4.cpp | 104 +- src/gromacs/simd/tests/simd4.h | 123 +- .../simd/tests/simd4_floatingpoint.cpp | 101 +- src/gromacs/simd/tests/simd4_math.cpp | 26 +- .../simd/tests/simd4_vector_operations.cpp | 17 +- src/gromacs/simd/tests/simd_floatingpoint.cpp | 185 +- .../simd/tests/simd_floatingpoint_util.cpp | 414 +- src/gromacs/simd/tests/simd_integer.cpp | 113 +- src/gromacs/simd/tests/simd_math.cpp | 812 ++- src/gromacs/simd/tests/simd_memory.cpp | 177 +- .../simd/tests/simd_vector_operations.cpp | 59 +- src/gromacs/simd/vector_operations.h | 68 +- src/gromacs/statistics/statistics.cpp | 274 +- src/gromacs/statistics/statistics.h | 89 +- src/gromacs/swap/swapcoords.cpp | 798 ++- src/gromacs/swap/swapcoords.h | 46 +- src/gromacs/tables/cubicsplinetable.cpp | 291 +- src/gromacs/tables/cubicsplinetable.h | 1005 ++-- src/gromacs/tables/forcetable.cpp | 650 ++- src/gromacs/tables/forcetable.h | 39 +- src/gromacs/tables/quadraticsplinetable.cpp | 225 +- src/gromacs/tables/quadraticsplinetable.h | 1119 ++-- src/gromacs/tables/splineutil.cpp | 206 +- src/gromacs/tables/splineutil.h | 75 +- src/gromacs/tables/tableinput.h | 22 +- src/gromacs/tables/tests/splinetable.cpp | 448 +- src/gromacs/taskassignment/decidegpuusage.cpp | 245 +- src/gromacs/taskassignment/decidegpuusage.h | 42 +- .../decidesimulationworkload.cpp | 26 +- .../taskassignment/decidesimulationworkload.h | 18 +- .../taskassignment/findallgputasks.cpp | 106 +- src/gromacs/taskassignment/findallgputasks.h | 31 +- src/gromacs/taskassignment/reportgpuusage.cpp | 65 +- src/gromacs/taskassignment/reportgpuusage.h | 26 +- .../taskassignment/resourcedivision.cpp | 371 +- src/gromacs/taskassignment/resourcedivision.h | 46 +- src/gromacs/taskassignment/taskassignment.cpp | 195 +- src/gromacs/taskassignment/taskassignment.h | 245 +- .../taskassignment/tests/usergpuids.cpp | 54 +- src/gromacs/taskassignment/usergpuids.cpp | 66 +- src/gromacs/taskassignment/usergpuids.h | 25 +- src/gromacs/timing/cyclecounter.cpp | 24 +- src/gromacs/timing/cyclecounter.h | 212 +- src/gromacs/timing/gpu_timing.h | 24 +- src/gromacs/timing/wallcycle.cpp | 436 +- src/gromacs/timing/wallcycle.h | 82 +- src/gromacs/timing/wallcyclereporting.h | 24 +- src/gromacs/timing/walltime_accounting.cpp | 87 +- src/gromacs/timing/walltime_accounting.h | 47 +- src/gromacs/tools/check.cpp | 365 +- src/gromacs/tools/check.h | 4 +- src/gromacs/tools/convert_tpr.cpp | 190 +- src/gromacs/tools/convert_tpr.h | 4 +- src/gromacs/tools/dump.cpp | 408 +- src/gromacs/tools/dump.h | 10 +- src/gromacs/tools/eneconv.cpp | 276 +- src/gromacs/tools/eneconv.h | 2 +- src/gromacs/tools/make_ndx.cpp | 511 +- src/gromacs/tools/make_ndx.h | 2 +- src/gromacs/tools/mk_angndx.cpp | 122 +- src/gromacs/tools/mk_angndx.h | 2 +- src/gromacs/tools/pme_error.cpp | 600 +-- src/gromacs/tools/pme_error.h | 2 +- src/gromacs/tools/report_methods.cpp | 140 +- src/gromacs/tools/report_methods.h | 21 +- src/gromacs/tools/tests/dump.cpp | 54 +- src/gromacs/tools/tests/report_methods.cpp | 69 +- src/gromacs/tools/tests/trjconv.cpp | 98 +- src/gromacs/tools/trjcat.cpp | 287 +- src/gromacs/tools/trjcat.h | 2 +- src/gromacs/tools/trjconv.cpp | 487 +- src/gromacs/tools/trjconv.h | 2 +- src/gromacs/tools/tune_pme.cpp | 1212 ++--- src/gromacs/tools/tune_pme.h | 2 +- src/gromacs/topology/atomprop.cpp | 171 +- src/gromacs/topology/atomprop.h | 118 +- src/gromacs/topology/atoms.cpp | 131 +- src/gromacs/topology/atoms.h | 158 +- src/gromacs/topology/atomsbuilder.cpp | 67 +- src/gromacs/topology/atomsbuilder.h | 70 +- src/gromacs/topology/block.cpp | 86 +- src/gromacs/topology/block.h | 171 +- src/gromacs/topology/exclusionblocks.cpp | 28 +- src/gromacs/topology/exclusionblocks.h | 8 +- src/gromacs/topology/forcefieldparameters.cpp | 27 +- src/gromacs/topology/forcefieldparameters.h | 3 +- src/gromacs/topology/idef.cpp | 253 +- src/gromacs/topology/idef.h | 192 +- src/gromacs/topology/ifunc.cpp | 222 +- src/gromacs/topology/ifunc.h | 24 +- src/gromacs/topology/index.cpp | 326 +- src/gromacs/topology/index.h | 33 +- src/gromacs/topology/invblock.cpp | 28 +- src/gromacs/topology/invblock.h | 6 +- src/gromacs/topology/mtop_lookup.h | 111 +- src/gromacs/topology/mtop_util.cpp | 458 +- src/gromacs/topology/mtop_util.h | 218 +- src/gromacs/topology/residuetypes.cpp | 60 +- src/gromacs/topology/residuetypes.h | 128 +- src/gromacs/topology/symtab.cpp | 81 +- src/gromacs/topology/symtab.h | 32 +- .../topology/tests/exclusionblocks.cpp | 77 +- src/gromacs/topology/tests/mtop.cpp | 16 +- src/gromacs/topology/tests/symtab.cpp | 88 +- src/gromacs/topology/topology.cpp | 215 +- src/gromacs/topology/topology.h | 124 +- src/gromacs/topology/topsort.cpp | 98 +- src/gromacs/topology/topsort.h | 6 +- src/gromacs/trajectory/energyframe.cpp | 22 +- src/gromacs/trajectory/energyframe.h | 86 +- src/gromacs/trajectory/trajectoryframe.cpp | 21 +- src/gromacs/trajectory/trajectoryframe.h | 128 +- .../trajectoryanalysis/analysismodule.cpp | 202 +- .../trajectoryanalysis/analysismodule.h | 684 ++- .../trajectoryanalysis/analysissettings.cpp | 52 +- .../trajectoryanalysis/analysissettings.h | 286 +- .../analysissettings_impl.h | 46 +- .../trajectoryanalysis/cmdlinerunner.cpp | 91 +- .../trajectoryanalysis/cmdlinerunner.h | 170 +- src/gromacs/trajectoryanalysis/modules.cpp | 12 +- src/gromacs/trajectoryanalysis/modules.h | 4 +- .../trajectoryanalysis/modules/angle.cpp | 556 +- .../trajectoryanalysis/modules/angle.h | 10 +- .../modules/convert_trj.cpp | 92 +- .../trajectoryanalysis/modules/convert_trj.h | 8 +- .../trajectoryanalysis/modules/distance.cpp | 222 +- .../trajectoryanalysis/modules/distance.h | 10 +- .../modules/extract_cluster.cpp | 140 +- .../modules/extract_cluster.h | 8 +- .../trajectoryanalysis/modules/freevolume.cpp | 160 +- .../trajectoryanalysis/modules/freevolume.h | 10 +- .../trajectoryanalysis/modules/pairdist.cpp | 393 +- .../trajectoryanalysis/modules/pairdist.h | 10 +- .../trajectoryanalysis/modules/rdf.cpp | 429 +- src/gromacs/trajectoryanalysis/modules/rdf.h | 10 +- .../trajectoryanalysis/modules/sasa.cpp | 636 +-- src/gromacs/trajectoryanalysis/modules/sasa.h | 10 +- .../trajectoryanalysis/modules/select.cpp | 379 +- .../trajectoryanalysis/modules/select.h | 10 +- .../modules/surfacearea.cpp | 615 +-- .../trajectoryanalysis/modules/surfacearea.h | 206 +- .../trajectoryanalysis/modules/trajectory.cpp | 166 +- .../trajectoryanalysis/modules/trajectory.h | 10 +- .../trajectoryanalysis/modules/unionfind.h | 303 +- .../trajectoryanalysis/runnercommon.cpp | 278 +- src/gromacs/trajectoryanalysis/runnercommon.h | 116 +- .../trajectoryanalysis/tests/angle.cpp | 145 +- .../trajectoryanalysis/tests/clustsize.cpp | 64 +- .../tests/cmdlinerunner.cpp | 80 +- .../trajectoryanalysis/tests/convert_trj.cpp | 24 +- .../trajectoryanalysis/tests/distance.cpp | 30 +- .../tests/extract_cluster.cpp | 61 +- .../trajectoryanalysis/tests/freevolume.cpp | 14 +- .../trajectoryanalysis/tests/moduletest.cpp | 103 +- .../trajectoryanalysis/tests/moduletest.h | 195 +- .../trajectoryanalysis/tests/pairdist.cpp | 75 +- src/gromacs/trajectoryanalysis/tests/rdf.cpp | 61 +- src/gromacs/trajectoryanalysis/tests/sasa.cpp | 33 +- .../trajectoryanalysis/tests/select.cpp | 53 +- .../trajectoryanalysis/tests/surfacearea.cpp | 298 +- .../tests/test_selection.cpp | 95 +- .../tests/topologyinformation.cpp | 22 +- .../trajectoryanalysis/tests/trajectory.cpp | 28 +- .../trajectoryanalysis/tests/unionfind.cpp | 4 +- .../topologyinformation.cpp | 47 +- .../trajectoryanalysis/topologyinformation.h | 197 +- src/gromacs/utility.h | 3 +- src/gromacs/utility/alignedallocator.cpp | 47 +- src/gromacs/utility/alignedallocator.h | 124 +- src/gromacs/utility/allocator.h | 132 +- src/gromacs/utility/any.cpp | 2 +- src/gromacs/utility/any.h | 311 +- src/gromacs/utility/arrayref.h | 307 +- src/gromacs/utility/arraysize.h | 6 +- src/gromacs/utility/basedefinitions.h | 66 +- src/gromacs/utility/basenetwork.cpp | 14 +- src/gromacs/utility/basenetwork.h | 4 +- src/gromacs/utility/baseversion.cpp | 24 +- src/gromacs/utility/baseversion.h | 14 +- src/gromacs/utility/binaryinformation.cpp | 189 +- src/gromacs/utility/binaryinformation.h | 118 +- src/gromacs/utility/bitmask.h | 42 +- src/gromacs/utility/classhelpers.h | 121 +- src/gromacs/utility/compare.cpp | 40 +- src/gromacs/utility/compare.h | 20 +- src/gromacs/utility/coolstuff.cpp | 1182 +++-- src/gromacs/utility/coolstuff.h | 4 +- src/gromacs/utility/cstringutil.cpp | 147 +- src/gromacs/utility/cstringutil.h | 48 +- .../utility/cuda_version_information.cu | 8 +- .../utility/cuda_version_information.h | 4 +- src/gromacs/utility/current_function.h | 23 +- src/gromacs/utility/datafilefinder.cpp | 79 +- src/gromacs/utility/datafilefinder.h | 253 +- .../utility/defaultinitializationallocator.h | 43 +- src/gromacs/utility/dir_separator.h | 6 +- src/gromacs/utility/directoryenumerator.cpp | 248 +- src/gromacs/utility/directoryenumerator.h | 115 +- src/gromacs/utility/enumerationhelpers.h | 197 +- src/gromacs/utility/errorcodes.cpp | 9 +- src/gromacs/utility/errorcodes.h | 2 +- src/gromacs/utility/errorformat.cpp | 26 +- src/gromacs/utility/errorformat.h | 11 +- src/gromacs/utility/exceptions.cpp | 340 +- src/gromacs/utility/exceptions.h | 517 +- src/gromacs/utility/fatalerror.cpp | 99 +- src/gromacs/utility/fatalerror.h | 53 +- src/gromacs/utility/fileptr.h | 6 +- src/gromacs/utility/fileredirector.cpp | 42 +- src/gromacs/utility/fileredirector.h | 72 +- src/gromacs/utility/filestream.cpp | 142 +- src/gromacs/utility/filestream.h | 188 +- src/gromacs/utility/fixedcapacityvector.h | 248 +- src/gromacs/utility/flags.h | 108 +- src/gromacs/utility/futil.cpp | 238 +- src/gromacs/utility/futil.h | 52 +- src/gromacs/utility/gmxassert.cpp | 7 +- src/gromacs/utility/gmxassert.h | 38 +- src/gromacs/utility/gmxmpi.h | 46 +- src/gromacs/utility/gmxomp.cpp | 48 +- src/gromacs/utility/gmxomp.h | 6 +- src/gromacs/utility/ikeyvaluetreeerror.cpp | 25 +- src/gromacs/utility/ikeyvaluetreeerror.h | 12 +- src/gromacs/utility/init.cpp | 22 +- src/gromacs/utility/init.h | 4 +- src/gromacs/utility/inmemoryserializer.cpp | 189 +- src/gromacs/utility/inmemoryserializer.h | 90 +- src/gromacs/utility/int64_to_int.cpp | 4 +- src/gromacs/utility/int64_to_int.h | 4 +- src/gromacs/utility/iserializer.h | 175 +- src/gromacs/utility/keyvaluetree.cpp | 261 +- src/gromacs/utility/keyvaluetree.h | 314 +- src/gromacs/utility/keyvaluetreebuilder.h | 543 +- src/gromacs/utility/keyvaluetreemdpwriter.cpp | 12 +- src/gromacs/utility/keyvaluetreemdpwriter.h | 3 +- .../utility/keyvaluetreeserializer.cpp | 154 +- src/gromacs/utility/keyvaluetreeserializer.h | 6 +- src/gromacs/utility/keyvaluetreetransform.cpp | 530 +- src/gromacs/utility/keyvaluetreetransform.h | 458 +- src/gromacs/utility/logger.cpp | 31 +- src/gromacs/utility/logger.h | 199 +- src/gromacs/utility/loggerbuilder.cpp | 95 +- src/gromacs/utility/loggerbuilder.h | 96 +- src/gromacs/utility/mdmodulenotification.h | 143 +- .../utility/messagestringcollector.cpp | 31 +- src/gromacs/utility/messagestringcollector.h | 160 +- src/gromacs/utility/mpiinplacebuffers.cpp | 2 +- src/gromacs/utility/mpiinplacebuffers.h | 18 +- src/gromacs/utility/niceheader.cpp | 14 +- src/gromacs/utility/niceheader.h | 6 +- src/gromacs/utility/nodelete.h | 6 +- src/gromacs/utility/path.cpp | 192 +- src/gromacs/utility/path.h | 202 +- .../utility/physicalnodecommunicator.cpp | 7 +- .../utility/physicalnodecommunicator.h | 39 +- src/gromacs/utility/pleasecite.cpp | 507 +- src/gromacs/utility/pleasecite.h | 6 +- src/gromacs/utility/programcontext.cpp | 32 +- src/gromacs/utility/programcontext.h | 121 +- src/gromacs/utility/range.h | 107 +- src/gromacs/utility/real.h | 93 +- src/gromacs/utility/smalloc.cpp | 84 +- src/gromacs/utility/smalloc.h | 75 +- src/gromacs/utility/snprintf.h | 4 +- src/gromacs/utility/strconvert.cpp | 57 +- src/gromacs/utility/strconvert.h | 88 +- src/gromacs/utility/strdb.cpp | 35 +- src/gromacs/utility/strdb.h | 8 +- src/gromacs/utility/stringcompare.h | 46 +- src/gromacs/utility/stringstream.cpp | 27 +- src/gromacs/utility/stringstream.h | 84 +- src/gromacs/utility/stringutil.cpp | 124 +- src/gromacs/utility/stringutil.h | 586 +-- src/gromacs/utility/sysinfo.cpp | 33 +- src/gromacs/utility/sysinfo.h | 9 +- .../utility/tests/alignedallocator.cpp | 19 +- .../utility/tests/alignedallocator_impl.h | 25 +- src/gromacs/utility/tests/arrayref.cpp | 117 +- src/gromacs/utility/tests/bitmask.h | 10 +- .../tests/defaultinitializationallocator.cpp | 11 +- .../utility/tests/enumerationhelpers.cpp | 10 +- .../utility/tests/fixedcapacityvector.cpp | 10 +- .../utility/tests/keyvaluetreeserializer.cpp | 145 +- .../utility/tests/keyvaluetreetransform.cpp | 175 +- src/gromacs/utility/tests/logger.cpp | 44 +- src/gromacs/utility/tests/mutex.cpp | 42 +- src/gromacs/utility/tests/path.cpp | 31 +- src/gromacs/utility/tests/stringutil.cpp | 51 +- src/gromacs/utility/tests/textreader.cpp | 249 +- src/gromacs/utility/tests/textwriter.cpp | 21 +- src/gromacs/utility/tests/typetraits.cpp | 8 +- src/gromacs/utility/textreader.cpp | 70 +- src/gromacs/utility/textreader.h | 222 +- src/gromacs/utility/textstream.h | 78 +- src/gromacs/utility/textwriter.cpp | 142 +- src/gromacs/utility/textwriter.h | 245 +- src/gromacs/utility/txtdump.cpp | 47 +- src/gromacs/utility/txtdump.h | 38 +- src/gromacs/utility/typetraits.h | 14 +- src/gromacs/utility/unique_cptr.h | 26 +- src/programs/gmx.cpp | 9 +- src/programs/legacymodules.cpp | 302 +- src/programs/legacymodules.h | 4 +- src/programs/mdrun/mdrun.cpp | 30 +- src/programs/mdrun/mdrun_main.h | 4 +- src/programs/mdrun/nonbonded_bench.cpp | 123 +- src/programs/mdrun/nonbonded_bench.h | 14 +- .../mdrun/tests/compressed_x_output.cpp | 38 +- .../mdrun/tests/densityfittingmodule.cpp | 116 +- src/programs/mdrun/tests/energycomparison.cpp | 73 +- src/programs/mdrun/tests/energycomparison.h | 61 +- src/programs/mdrun/tests/energyreader.cpp | 66 +- src/programs/mdrun/tests/energyreader.h | 102 +- .../mdrun/tests/exactcontinuation.cpp | 355 +- src/programs/mdrun/tests/grompp.cpp | 43 +- src/programs/mdrun/tests/helpwriting.cpp | 13 +- .../mdrun/tests/initialconstraints.cpp | 53 +- src/programs/mdrun/tests/interactiveMD.cpp | 22 +- .../mdrun/tests/mdmodulenotification.cpp | 96 +- src/programs/mdrun/tests/mdruncomparison.h | 107 +- src/programs/mdrun/tests/mimic.cpp | 66 +- src/programs/mdrun/tests/minimize.cpp | 83 +- src/programs/mdrun/tests/moduletest.cpp | 61 +- src/programs/mdrun/tests/moduletest.h | 155 +- src/programs/mdrun/tests/multisim.cpp | 16 +- src/programs/mdrun/tests/multisimtest.cpp | 77 +- src/programs/mdrun/tests/multisimtest.h | 71 +- src/programs/mdrun/tests/nonbonded_bench.cpp | 12 +- src/programs/mdrun/tests/normalmodes.cpp | 35 +- src/programs/mdrun/tests/periodicactions.cpp | 240 +- src/programs/mdrun/tests/pmetest.cpp | 140 +- src/programs/mdrun/tests/replicaexchange.cpp | 16 +- src/programs/mdrun/tests/rerun.cpp | 138 +- src/programs/mdrun/tests/simple_mdrun.cpp | 77 +- src/programs/mdrun/tests/simulator.cpp | 155 +- .../mdrun/tests/simulatorcomparison.cpp | 57 +- .../mdrun/tests/simulatorcomparison.h | 14 +- src/programs/mdrun/tests/swapcoords.cpp | 16 +- .../tests/tabulated_bonded_interactions.cpp | 74 +- src/programs/mdrun/tests/termination.cpp | 108 +- .../mdrun/tests/terminationhelper.cpp | 20 +- src/programs/mdrun/tests/terminationhelper.h | 45 +- src/programs/mdrun/tests/tpitest.cpp | 38 +- .../mdrun/tests/trajectory_writing.cpp | 106 +- .../mdrun/tests/trajectorycomparison.cpp | 89 +- .../mdrun/tests/trajectorycomparison.h | 36 +- src/programs/mdrun/tests/trajectoryreader.cpp | 60 +- src/programs/mdrun/tests/trajectoryreader.h | 111 +- src/programs/mdrun_main.cpp | 12 +- src/programs/view/3dview.cpp | 44 +- src/programs/view/3dview.h | 17 +- src/programs/view/Xstuff.h | 221 +- src/programs/view/buttons.cpp | 167 +- src/programs/view/buttons.h | 53 +- src/programs/view/dialogs.cpp | 252 +- src/programs/view/dialogs.h | 136 +- src/programs/view/fgrid.cpp | 165 +- src/programs/view/fgrid.h | 55 +- src/programs/view/filter.cpp | 56 +- src/programs/view/logo.cpp | 139 +- src/programs/view/logo.h | 19 +- src/programs/view/manager.cpp | 238 +- src/programs/view/manager.h | 199 +- src/programs/view/molps.cpp | 105 +- src/programs/view/molps.h | 4 +- src/programs/view/nleg.cpp | 72 +- src/programs/view/nleg.h | 20 +- src/programs/view/nmol.cpp | 237 +- src/programs/view/nmol.h | 36 +- src/programs/view/popup.cpp | 103 +- src/programs/view/popup.h | 47 +- src/programs/view/pulldown.cpp | 65 +- src/programs/view/pulldown.h | 36 +- src/programs/view/view.cpp | 281 +- src/programs/view/view.h | 7 +- src/programs/view/x11.cpp | 151 +- src/programs/view/x11.h | 70 +- src/programs/view/xdlg.cpp | 277 +- src/programs/view/xdlg.h | 110 +- src/programs/view/xdlghi.cpp | 244 +- src/programs/view/xdlghi.h | 41 +- src/programs/view/xdlgitem.cpp | 322 +- src/programs/view/xdlgitem.h | 167 +- src/programs/view/xmb.cpp | 97 +- src/programs/view/xmb.h | 41 +- src/programs/view/xutil.cpp | 160 +- src/programs/view/xutil.h | 71 +- src/testutils/cmdlinetest.cpp | 274 +- src/testutils/cmdlinetest.h | 664 ++- src/testutils/conftest.cpp | 30 +- src/testutils/conftest.h | 32 +- src/testutils/filematchers.cpp | 36 +- src/testutils/filematchers.h | 63 +- src/testutils/interactivetest.cpp | 133 +- src/testutils/interactivetest.h | 82 +- src/testutils/loggertest.cpp | 54 +- src/testutils/loggertest.h | 41 +- src/testutils/mpi_printer.cpp | 130 +- src/testutils/mpitest.cpp | 38 +- src/testutils/mpitest.h | 23 +- src/testutils/refdata.cpp | 806 ++- src/testutils/refdata.h | 765 ++- src/testutils/refdata_checkers.h | 248 +- src/testutils/refdata_impl.h | 232 +- src/testutils/refdata_xml.cpp | 76 +- src/testutils/refdata_xml.h | 6 +- src/testutils/setenv.h | 22 +- src/testutils/simulationdatabase.cpp | 292 +- src/testutils/simulationdatabase.h | 28 +- src/testutils/stdiohelper.cpp | 9 +- src/testutils/stdiohelper.h | 31 +- src/testutils/stringtest.cpp | 39 +- src/testutils/stringtest.h | 94 +- src/testutils/testasserts.cpp | 106 +- src/testutils/testasserts.h | 475 +- src/testutils/testexceptions.h | 39 +- src/testutils/testfilemanager.cpp | 141 +- src/testutils/testfilemanager.h | 298 +- src/testutils/testfileredirector.cpp | 41 +- src/testutils/testfileredirector.h | 87 +- src/testutils/testinit.cpp | 112 +- src/testutils/testinit.h | 10 +- src/testutils/testmatchers.cpp | 151 +- src/testutils/testmatchers.h | 18 +- src/testutils/testoptions.cpp | 56 +- src/testutils/testoptions.h | 51 +- src/testutils/tests/interactivetest.cpp | 127 +- src/testutils/tests/mpitest.cpp | 9 +- src/testutils/tests/refdata_tests.cpp | 61 +- src/testutils/tests/testasserts_tests.cpp | 19 +- src/testutils/tests/xvgtest_tests.cpp | 57 +- src/testutils/textblockmatchers.cpp | 100 +- src/testutils/textblockmatchers.h | 71 +- src/testutils/tprfilegenerator.cpp | 2 +- src/testutils/tprfilegenerator.h | 29 +- src/testutils/unittest_main.cpp | 24 +- src/testutils/xvgtest.cpp | 42 +- src/testutils/xvgtest.h | 56 +- 2066 files changed, 162468 insertions(+), 174763 deletions(-) mode change 100755 => 100644 src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cpp mode change 100755 => 100644 src/gromacs/ewald/pme_force_sender_gpu_impl.cpp mode change 100755 => 100644 src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp diff --git a/.clang-format b/.clang-format index 5851c0a558..600e45a532 100644 --- a/.clang-format +++ b/.clang-format @@ -7,7 +7,7 @@ AlignConsecutiveDeclarations: true AlignEscapedNewlinesLeft: true AlignOperands: true AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: true AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: Inline @@ -31,7 +31,7 @@ BraceWrapping: BeforeCatch: true BeforeElse: true IndentBraces: false -BreakBeforeBinaryOperators: All +BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Allman BreakBeforeTernaryOperators: true BreakConstructorInitializers: AfterColon @@ -40,7 +40,7 @@ BreakInheritanceList: AfterColon BreakStringLiterals: true ColumnLimit: 100 CommentPragmas: '^ IWYU pragma:|NOLINT' -ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 8 Cpp11BracedListStyle: false @@ -75,7 +75,7 @@ PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1 +PenaltyExcessCharacter: 2 PenaltyReturnTypeOnItsOwnLine: 100 PointerAlignment: Left ReflowComments: true diff --git a/.gitattributes b/.gitattributes index 5cbed0f40f..3d701ccad2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -40,8 +40,8 @@ scripts/GMXRC.* !filter scripts/make_gromos_rtp.py !filter share/template/template.cpp filter=copyright share/template/README.cmakein !filter -src/gromacs/linearalgebra/gmx_blas/* !filter -src/gromacs/linearalgebra/gmx_lapack/* !filter +src/gromacs/linearalgebra/gmx_blas/* -filter -gmx-doxygen +src/gromacs/linearalgebra/gmx_lapack/* -filter -gmx-doxygen src/gromacs/selection/parser.cpp -filter -gmx-doxygen src/gromacs/selection/parser.h -filter -gmx-doxygen src/gromacs/selection/scanner.cpp -filter -gmx-doxygen diff --git a/admin/git-pre-commit b/admin/git-pre-commit index d066d6d5af..c52d559148 100755 --- a/admin/git-pre-commit +++ b/admin/git-pre-commit @@ -66,7 +66,7 @@ fi # Redirect output to stderr. exec 1>&2 -uncrustify_mode=`git config hooks.uncrustifymode` +uncrustify_mode=off clangformat_mode=`git config hooks.clangformatmode` copyright_mode=`git config hooks.copyrightmode` if [ -z "$uncrustify_mode" ] diff --git a/admin/reformat_all.sh b/admin/reformat_all.sh index 889c683a1e..5748c91cc5 100755 --- a/admin/reformat_all.sh +++ b/admin/reformat_all.sh @@ -101,7 +101,7 @@ case "$action" in ;; clang-format) if [ -z "$CLANG_FORMAT" ] ; then - CLANG_FORMAT=clang-format + CLANG_FORMAT=clang-format-7 fi if ! which "$CLANG_FORMAT" 1>/dev/null ; then echo "clang-format not found. Specify one with CLANG_FORMAT" @@ -126,7 +126,7 @@ esac if [[ "$filter" == "default" ]] ; then if [[ "$action" == "clang-format" ]] ; then - filter=complete_formatting + filter=clangformat else filter=$action fi @@ -146,7 +146,7 @@ case "$filter" in filter_re="(complete_formatting|clangformat)" ;; complete_formatting) - filter_re="(complete_formatting|clangformat|includesort|copyright)" + filter_re="(complete_formatting|clangformat)" ;; *) echo "Unknown filter mode: $filter" diff --git a/admin/uncrustify.sh b/admin/uncrustify.sh index af5ac18d9f..5e98a11e90 100755 --- a/admin/uncrustify.sh +++ b/admin/uncrustify.sh @@ -138,7 +138,7 @@ cut -f2 <$tmpdir/difflist | \ paste $tmpdir/difflist - | \ grep -E '(complete_formatting|uncrustify|copyright|includesort)$' >$tmpdir/filtered cut -f2 <$tmpdir/filtered >$tmpdir/filelist_all -grep -E '(complete_formatting|uncrustify)$' <$tmpdir/filtered | \ +grep -E '(uncrustify)$' <$tmpdir/filtered | \ cut -f2 >$tmpdir/filelist_uncrustify git diff-files --name-only | grep -Ff $tmpdir/filelist_all >$tmpdir/localmods diff --git a/python_packaging/src/gmxapi/export_context.cpp b/python_packaging/src/gmxapi/export_context.cpp index 3bea021d40..b991398ea7 100644 --- a/python_packaging/src/gmxapi/export_context.cpp +++ b/python_packaging/src/gmxapi/export_context.cpp @@ -70,8 +70,7 @@ namespace py = pybind11; * For reference and default values, see * http://manual.gromacs.org/current/onlinehelp/gmx-mdrun.html#options */ -static void setMDArgs(std::vector* mdargs, - const py::dict ¶ms) +static void setMDArgs(std::vector* mdargs, const py::dict& params) { mdargs->clear(); if (params.contains("grid")) @@ -88,7 +87,7 @@ static void setMDArgs(std::vector* mdargs, ++iterator; } mdargs->emplace_back("-dd"); - for (auto && val : vals) + for (auto&& val : vals) { mdargs->emplace_back(val); } @@ -144,7 +143,7 @@ static void setMDArgs(std::vector* mdargs, mdargs->emplace_back("-noappend"); } } - catch (const py::cast_error &e) + catch (const py::cast_error& e) { // Couldn't cast to bool for some reason. // Convert to gmxapi exception (not implemented) @@ -154,24 +153,22 @@ static void setMDArgs(std::vector* mdargs, } } -void export_context(py::module &m) +void export_context(py::module& m) { // Add argument type before it is used for more sensible automatic bindings behavior. - py::class_ < MDArgs, std::unique_ptr < MDArgs>> mdargs(m, "MDArgs"); + py::class_> mdargs(m, "MDArgs"); mdargs.def(py::init(), "Create an empty MDArgs object."); - mdargs.def("set", - [](MDArgs* self, const py::dict ¶ms){ setMDArgs(self, params); }, + mdargs.def("set", [](MDArgs* self, const py::dict& params) { setMDArgs(self, params); }, "Assign parameters in MDArgs from Python dict."); // Export execution context class - py::class_ < PyContext, std::shared_ptr < PyContext>> context(m, "Context"); + py::class_> context(m, "Context"); context.def(py::init(), "Create a default execution context."); context.def("setMDArgs", &PyContext::setMDArgs, "Set MD runtime parameters."); - context.def("add_mdmodule", &PyContext::addMDModule, - "Add an MD plugin for the simulation."); + context.def("add_mdmodule", &PyContext::addMDModule, "Add an MD plugin for the simulation."); } -} // end namespace gmxpy::detail +} // namespace detail } // end namespace gmxpy diff --git a/python_packaging/src/gmxapi/export_exceptions.cpp b/python_packaging/src/gmxapi/export_exceptions.cpp index 7596f4d09a..fd864f5ada 100644 --- a/python_packaging/src/gmxapi/export_exceptions.cpp +++ b/python_packaging/src/gmxapi/export_exceptions.cpp @@ -68,7 +68,7 @@ namespace detail namespace py = pybind11; -void export_exceptions(pybind11::module &m) +void export_exceptions(pybind11::module& m) { // These two lines could cause exceptions, but they are already handled, // causing an ImportError for the _gmxapi submodule raised from the @@ -84,43 +84,43 @@ void export_exceptions(pybind11::module &m) // Developer note: as of pybind11 2.2.4, the py::exception template argument // is unused internally, but required. - struct UnknownExceptionPlaceHolder {}; - static py::exception unknownException( - m, - "UnknownException", - baseException.ptr()); - unknownException.doc() = "GROMACS library produced an exception that is " - "not mapped in gmxapi or which should have been " - "caught at a lower level. I.e. a bug. (Please report.)"; + struct UnknownExceptionPlaceHolder + { + }; + static py::exception unknownException(m, "UnknownException", + baseException.ptr()); + unknownException.doc() = + "GROMACS library produced an exception that is " + "not mapped in gmxapi or which should have been " + "caught at a lower level. I.e. a bug. (Please report.)"; // Catch unexpected/unbound exceptions from libgromacs or libgmxapi. - py::register_exception_translator( - [](std::exception_ptr p) { - try - { - if (p) - { - std::rethrow_exception(p); - } - } - catch (const gmxapi::Exception &e) - { - // Nothing should be throwing the base exception and all gmxapi - // exceptions should be mapped in this module. Differences - // between GROMACS version and Python package version could leave - // some exceptions unmapped, but we should add an alert in case - // an exception gets overlooked. - std::string message = "Generic gmxapi exception caught: "; - message += e.what(); - baseException(message.c_str()); - } - catch (const std::exception &e) - { - std::string message = "Please report GROMACS bug. Unhandled C++ exception: "; - message += e.what(); - unknownException(message.c_str()); - } - }); + py::register_exception_translator([](std::exception_ptr p) { + try + { + if (p) + { + std::rethrow_exception(p); + } + } + catch (const gmxapi::Exception& e) + { + // Nothing should be throwing the base exception and all gmxapi + // exceptions should be mapped in this module. Differences + // between GROMACS version and Python package version could leave + // some exceptions unmapped, but we should add an alert in case + // an exception gets overlooked. + std::string message = "Generic gmxapi exception caught: "; + message += e.what(); + baseException(message.c_str()); + } + catch (const std::exception& e) + { + std::string message = "Please report GROMACS bug. Unhandled C++ exception: "; + message += e.what(); + unknownException(message.c_str()); + } + }); // Map gmxapi exceptions from gmxapi/exceptions.h to Python package exceptions. // Note: C++ exception translation occurs in revers order of registration, @@ -129,22 +129,25 @@ void export_exceptions(pybind11::module &m) // by linking to online docs or if we had a way to reuse doxygen docs. { - auto exception = py::register_exception(m, "ProtocolError", baseException.ptr()); + auto exception = + py::register_exception(m, "ProtocolError", baseException.ptr()); exception.doc() = "Behavioral protocol violated."; } { - auto exception = py::register_exception(m, "NotImplementedError", baseException.ptr()); + auto exception = py::register_exception( + m, "NotImplementedError", baseException.ptr()); exception.doc() = "Expected feature is not implemented."; } { - auto exception = py::register_exception(m, "UsageError", baseException.ptr()); + auto exception = + py::register_exception(m, "UsageError", baseException.ptr()); exception.doc() = "Unacceptable API usage."; } } -} // end namespace gmxpy::detail +} // namespace detail } // end namespace gmxpy diff --git a/python_packaging/src/gmxapi/export_system.cpp b/python_packaging/src/gmxapi/export_system.cpp index ea91629fbc..91463edcff 100644 --- a/python_packaging/src/gmxapi/export_system.cpp +++ b/python_packaging/src/gmxapi/export_system.cpp @@ -48,9 +48,9 @@ #include "pycontext.h" #include "pysystem.h" -// Note that PyCapsule symbols from Python.h should be imported by way of the pybind headers, so let's not -// muddy the waters by explicitly including Python.h here unless we want to get more particular about the -// CMake configuration. +// Note that PyCapsule symbols from Python.h should be imported by way of the pybind headers, so +// let's not muddy the waters by explicitly including Python.h here unless we want to get more +// particular about the CMake configuration. namespace gmxpy { @@ -61,7 +61,7 @@ namespace detail namespace py = pybind11; -void export_system(py::module &m) +void export_system(py::module& m) { using ::gmxapi::System; @@ -73,24 +73,25 @@ void export_system(py::module &m) // self-documents intent. Future implementations could refactor Session as a // dynamically accessed facet of the Context, which the API client would be // required to maintain and to pass to the API. - py::class_ < ::gmxapi::Session, std::shared_ptr < ::gmxapi::Session>> session(m, "MDSession"); + py::class_<::gmxapi::Session, std::shared_ptr<::gmxapi::Session>> session(m, "MDSession"); session.def("run", &::gmxapi::Session::run, "Run the simulation workflow"); - session.def("close", &::gmxapi::Session::close, "Shut down the execution environment and close the session."); + session.def("close", &::gmxapi::Session::close, + "Shut down the execution environment and close the session."); // Export system container class - py::class_ > system(m, "MDSystem"); + py::class_> system(m, "MDSystem"); system.def("launch", - [](System* system, std::shared_ptr context) - { + [](System* system, std::shared_ptr context) { auto newSession = system->launch(context->get()); return newSession; }, "Launch the configured workflow in the provided context."); // Module-level function - m.def("from_tpr", &gmxpy::from_tpr, "Return a system container initialized from the given input record."); + m.def("from_tpr", &gmxpy::from_tpr, + "Return a system container initialized from the given input record."); } -} // end namespace gmxpy::detail +} // namespace detail } // end namespace gmxpy diff --git a/python_packaging/src/gmxapi/export_tprfile.cpp b/python_packaging/src/gmxapi/export_tprfile.cpp index b5d86404be..58e48728fe 100644 --- a/python_packaging/src/gmxapi/export_tprfile.cpp +++ b/python_packaging/src/gmxapi/export_tprfile.cpp @@ -61,22 +61,21 @@ namespace gmxpy { -void detail::export_tprfile(pybind11::module &module) +void detail::export_tprfile(pybind11::module& module) { namespace py = pybind11; using gmxapicompat::GmxMdParams; - using gmxapicompat::TprReadHandle; using gmxapicompat::readTprFile; + using gmxapicompat::TprReadHandle; py::class_ mdparams(module, "SimulationParameters"); // We don't want Python users to create invalid params objects, so don't // export a constructor until we can default initialize a valid one. // mdparams.def(py::init()); mdparams.def("extract", - [](const GmxMdParams &self) - { + [](const GmxMdParams& self) { py::dict dictionary; - for (const auto &key: gmxapicompat::keys(self)) + for (const auto& key : gmxapicompat::keys(self)) { try { @@ -89,7 +88,7 @@ void detail::export_tprfile(pybind11::module &module) // We can use templates and/or tag dispatch in a more complete // future implementation. - const auto ¶mType = gmxapicompat::mdParamToType(key); + const auto& paramType = gmxapicompat::mdParamToType(key); if (paramType == GmxapiType::FLOAT64) { dictionary[key.c_str()] = extractParam(self, key, double()); @@ -99,7 +98,7 @@ void detail::export_tprfile(pybind11::module &module) dictionary[key.c_str()] = extractParam(self, key, int64_t()); } } - catch (const gmxapicompat::ValueError &e) + catch (const gmxapicompat::ValueError& e) { throw gmxapi::ProtocolError(std::string("Unknown parameter: ") + key); } @@ -110,77 +109,60 @@ void detail::export_tprfile(pybind11::module &module) // Overload a setter for each known type and None mdparams.def("set", - [](GmxMdParams* self, const std::string &key, int64_t value) - { + [](GmxMdParams* self, const std::string& key, int64_t value) { gmxapicompat::setParam(self, key, value); }, - py::arg("key").none(false), - py::arg("value").none(false), + py::arg("key").none(false), py::arg("value").none(false), "Use a dictionary to update simulation parameters."); mdparams.def("set", - [](GmxMdParams* self, const std::string &key, double value) - { + [](GmxMdParams* self, const std::string& key, double value) { gmxapicompat::setParam(self, key, value); }, - py::arg("key").none(false), - py::arg("value").none(false), + py::arg("key").none(false), py::arg("value").none(false), "Use a dictionary to update simulation parameters."); mdparams.def("set", - [](GmxMdParams* self, const std::string &key, py::none) - { + [](GmxMdParams* self, const std::string& key, py::none) { // unsetParam(self, key); }, - py::arg("key").none(false), - py::arg("value"), + py::arg("key").none(false), py::arg("value"), "Use a dictionary to update simulation parameters."); py::class_ tprfile(module, "TprFile"); - tprfile.def("params", - [](const TprReadHandle &self) - { - auto params = gmxapicompat::getMdParams(self); - return params; - }); - - module.def("read_tprfile", - &readTprFile, - py::arg("filename"), + tprfile.def("params", [](const TprReadHandle& self) { + auto params = gmxapicompat::getMdParams(self); + return params; + }); + + module.def("read_tprfile", &readTprFile, py::arg("filename"), "Get a handle to a TPR file resource for a given file name."); module.def("write_tprfile", - [](std::string filename, const GmxMdParams ¶meterObject) - { + [](std::string filename, const GmxMdParams& parameterObject) { auto tprReadHandle = gmxapicompat::getSourceFileHandle(parameterObject); - auto params = gmxapicompat::getMdParams(tprReadHandle); - auto structure = gmxapicompat::getStructureSource(tprReadHandle); - auto state = gmxapicompat::getSimulationState(tprReadHandle); - auto topology = gmxapicompat::getTopologySource(tprReadHandle); + auto params = gmxapicompat::getMdParams(tprReadHandle); + auto structure = gmxapicompat::getStructureSource(tprReadHandle); + auto state = gmxapicompat::getSimulationState(tprReadHandle); + auto topology = gmxapicompat::getTopologySource(tprReadHandle); gmxapicompat::writeTprFile(filename, *params, *structure, *state, *topology); }, - py::arg("filename").none(false), - py::arg("parameters"), + py::arg("filename").none(false), py::arg("parameters"), "Write a new TPR file with the provided data."); module.def("copy_tprfile", - [](const gmxapicompat::TprReadHandle &input, std::string outFile) - { + [](const gmxapicompat::TprReadHandle& input, std::string outFile) { return gmxapicompat::copy_tprfile(input, outFile); }, - py::arg("source"), - py::arg("destination"), - "Copy a TPR file from `source` to `destination`." - ); - - module.def("rewrite_tprfile", - [](std::string input, std::string output, double end_time) - { - return gmxapicompat::rewrite_tprfile(input, output, end_time); - }, - py::arg("source"), - py::arg("destination"), - py::arg("end_time"), - "Copy a TPR file from `source` to `destination`, replacing `nsteps` with `end_time`."); + py::arg("source"), py::arg("destination"), + "Copy a TPR file from `source` to `destination`."); + + module.def( + "rewrite_tprfile", + [](std::string input, std::string output, double end_time) { + return gmxapicompat::rewrite_tprfile(input, output, end_time); + }, + py::arg("source"), py::arg("destination"), py::arg("end_time"), + "Copy a TPR file from `source` to `destination`, replacing `nsteps` with `end_time`."); } } // end namespace gmxpy diff --git a/python_packaging/src/gmxapi/module.cpp b/python_packaging/src/gmxapi/module.cpp index 9dfe0f2e88..0496dc2b8a 100644 --- a/python_packaging/src/gmxapi/module.cpp +++ b/python_packaging/src/gmxapi/module.cpp @@ -75,7 +75,8 @@ code and developer documentation for more details. */ // Instantiate the Python module -PYBIND11_MODULE(_gmxapi, m){ +PYBIND11_MODULE(_gmxapi, m) +{ using namespace gmxpy::detail; m.doc() = docstring; @@ -87,11 +88,10 @@ PYBIND11_MODULE(_gmxapi, m){ export_exceptions(m); // Export core bindings - m.def("has_feature", - &gmxapi::Version::hasFeature, + m.def("has_feature", &gmxapi::Version::hasFeature, "Check the gmxapi library for a named feature."); - py::class_< ::gmxapi::Status > gmx_status(m, "Status", "Holds status for API operations."); + py::class_<::gmxapi::Status> gmx_status(m, "Status", "Holds status for API operations."); // Get bindings exported by the various components. export_context(m); diff --git a/python_packaging/src/gmxapi/module.h b/python_packaging/src/gmxapi/module.h index f25204eeef..349936ee49 100644 --- a/python_packaging/src/gmxapi/module.h +++ b/python_packaging/src/gmxapi/module.h @@ -87,19 +87,19 @@ namespace gmxpy namespace detail { -void export_context(pybind11::module &m); -void export_exceptions(pybind11::module &m); -void export_system(pybind11::module &m); -void export_tprfile(pybind11::module &module); +void export_context(pybind11::module& m); +void export_exceptions(pybind11::module& m); +void export_system(pybind11::module& m); +void export_tprfile(pybind11::module& module); // Forward declaration for the module initialization. // TODO: is there a better way to avoid the warning generated by the pybind macro? // e.g. no previous prototype for function 'PyInit__gmxapi' [-Wmissing-prototypes] extern "C" __attribute__((visibility("default"))) PyObject* PyInit__gmxapi(); -void pybind11_init__gmxapi(pybind11::module &m); +void pybind11_init__gmxapi(pybind11::module& m); -} // end namespace gmxpy::detail +} // namespace detail -} // end namespace gmxpy +} // end namespace gmxpy #endif // GMXPY_MODULE_H diff --git a/python_packaging/src/gmxapi/pycontext.cpp b/python_packaging/src/gmxapi/pycontext.cpp index 669991bbad..4e53b96362 100644 --- a/python_packaging/src/gmxapi/pycontext.cpp +++ b/python_packaging/src/gmxapi/pycontext.cpp @@ -49,13 +49,13 @@ namespace py = pybind11; namespace gmxpy { -void PyContext::setMDArgs(const MDArgs &mdArgs) +void PyContext::setMDArgs(const MDArgs& mdArgs) { assert(context_); context_->setMDArgs(mdArgs); } -std::shared_ptr PyContext::launch(const gmxapi::Workflow &work) +std::shared_ptr PyContext::launch(const gmxapi::Workflow& work) { assert(context_); return context_->launch(work); @@ -74,10 +74,8 @@ std::shared_ptr PyContext::get() const } PyContext::PyContext() : - context_ {std::make_shared()}, -workNodes_ { - std::make_shared() -} + context_{ std::make_shared() }, + workNodes_{ std::make_shared() } { assert(context_); assert(workNodes_); @@ -89,31 +87,30 @@ void PyContext::addMDModule(pybind11::object force_object) // to our C++ object. if (py::hasattr(force_object, "bind")) { - auto spec = getSpec(); - auto holder = new gmxapi::MDHolder(spec); + auto spec = getSpec(); + auto holder = new gmxapi::MDHolder(spec); holder->name_ = "pygmx holder"; - auto deleter = [](PyObject *o) { - if (PyCapsule_IsValid(o, gmxapi::MDHolder_Name)) - { - auto holder_ptr = (gmxapi::MDHolder *) PyCapsule_GetPointer(o, gmxapi::MDHolder_Name); - delete holder_ptr; - // \todo double-check whether there is something we should do to invalidate a PyCapsule. - } - }; - auto capsule = py::capsule(holder, - gmxapi::MDHolder_Name, - deleter); - py::object bind = force_object.attr("bind"); - // py::capsule does not have bindings and does not implicitly convert to py::object - py::object obj = capsule; - bind(obj); - } - else - { - // Note: Exception behavior is likely to change. - // Ref: https://github.com/kassonlab/gmxapi/issues/125 - throw py::value_error("Argument must provide a `bind` method."); - } + auto deleter = [](PyObject* o) { + if (PyCapsule_IsValid(o, gmxapi::MDHolder_Name)) + { + auto holder_ptr = (gmxapi::MDHolder*)PyCapsule_GetPointer(o, gmxapi::MDHolder_Name); + delete holder_ptr; + // \todo double-check whether there is something we should do to invalidate a PyCapsule. + } + }; + }; + auto capsule = py::capsule(holder, gmxapi::MDHolder_Name, deleter); + py::object bind = force_object.attr("bind"); + // py::capsule does not have bindings and does not implicitly convert to py::object + py::object obj = capsule; + bind(obj); +} +else +{ + // Note: Exception behavior is likely to change. + // Ref: https://github.com/kassonlab/gmxapi/issues/125 + throw py::value_error("Argument must provide a `bind` method."); } +} // namespace gmxpy } // end namespace gmxpy diff --git a/python_packaging/src/gmxapi/pycontext.h b/python_packaging/src/gmxapi/pycontext.h index 54c7dc0b9b..7e5d44ed0d 100644 --- a/python_packaging/src/gmxapi/pycontext.h +++ b/python_packaging/src/gmxapi/pycontext.h @@ -61,30 +61,30 @@ using gmxapi::MDArgs; */ class PyContext { - public: - PyContext(); - void setMDArgs(const MDArgs &mdArgs); - std::shared_ptr launch(const gmxapi::Workflow &work); - std::shared_ptr get() const; +public: + PyContext(); + void setMDArgs(const MDArgs& mdArgs); + std::shared_ptr launch(const gmxapi::Workflow& work); + std::shared_ptr get() const; - void addMDModule(pybind11::object forceProvider); + void addMDModule(pybind11::object forceProvider); - /*! - * \brief Borrow shared ownership of the System's container of associated modules. - * - * Used with gmxapi::MDHolder to add MD Modules to the simulation to be run. - * - * \return handle to be passed to gmxapi::MDHolder - * - */ - std::shared_ptr getSpec() const; + /*! + * \brief Borrow shared ownership of the System's container of associated modules. + * + * Used with gmxapi::MDHolder to add MD Modules to the simulation to be run. + * + * \return handle to be passed to gmxapi::MDHolder + * + */ + std::shared_ptr getSpec() const; - private: - std::shared_ptr context_; - std::shared_ptr workNodes_; +private: + std::shared_ptr context_; + std::shared_ptr workNodes_; }; -} // end namespace gmxpy +} // end namespace gmxpy -#endif //GMXPY_PYCONTEXT_H +#endif // GMXPY_PYCONTEXT_H diff --git a/python_packaging/src/gmxapi/pysystem.h b/python_packaging/src/gmxapi/pysystem.h index 2ae84ec18e..0cafe1ee84 100644 --- a/python_packaging/src/gmxapi/pysystem.h +++ b/python_packaging/src/gmxapi/pysystem.h @@ -53,6 +53,6 @@ namespace gmxpy std::shared_ptr from_tpr(std::string filename); -} // end namespace gmxpy +} // end namespace gmxpy #endif // header guard diff --git a/src/api/cpp/context.cpp b/src/api/cpp/context.cpp index fd3b4e5e62..ad3de9be6b 100644 --- a/src/api/cpp/context.cpp +++ b/src/api/cpp/context.cpp @@ -78,7 +78,8 @@ namespace gmxapi ContextImpl::ContextImpl() { - GMX_ASSERT(session_.expired(), "This implementation assumes an expired weak_ptr at initialization."); + GMX_ASSERT(session_.expired(), + "This implementation assumes an expired weak_ptr at initialization."); } std::shared_ptr ContextImpl::create() @@ -87,11 +88,11 @@ std::shared_ptr ContextImpl::create() return impl; } -std::shared_ptr ContextImpl::launch(const Workflow &work) +std::shared_ptr ContextImpl::launch(const Workflow& work) { using namespace gmx; - // Much of this implementation is not easily testable: we need tools to inspect simulation results and to modify - // simulation inputs. + // Much of this implementation is not easily testable: we need tools to inspect simulation + // results and to modify simulation inputs. std::shared_ptr launchedSession = nullptr; @@ -102,7 +103,7 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) // Check workflow spec, build graph for current context, launch and return new session. // \todo This is specific to the session implementation... auto mdNode = work.getNode("MD"); - std::string filename {}; + std::string filename{}; if (mdNode != nullptr) { filename = mdNode->params(); @@ -130,37 +131,37 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) * A future gmxapi version should avoid changing directories once the * process starts and instead manage files (paths) in an absolute and * immutable way, with abstraction provided through the Context chain-of-responsibility. - * TODO: API abstractions for initializing simulations that may be new or partially complete. - * Reference gmxapi milestone 13 at https://redmine.gromacs.org/issues/2585 + * TODO: API abstractions for initializing simulations that may be new or partially + * complete. Reference gmxapi milestone 13 at https://redmine.gromacs.org/issues/2585 */ // Create a mock argv. Note that argv[0] is expected to hold the program name. const int offset = 1; const auto argc = static_cast(mdArgs_.size() + offset); - auto argv = std::vector(argc, nullptr); + auto argv = std::vector(argc, nullptr); // argv[0] is ignored, but should be a valid string (e.g. null terminated array of char) argv[0] = new char[1]; *argv[0] = '\0'; for (size_t argvIndex = offset; argvIndex < argc; ++argvIndex) { - const auto &mdArg = mdArgs_[argvIndex - offset]; - argv[argvIndex] = new char[mdArg.length() + 1]; + const auto& mdArg = mdArgs_[argvIndex - offset]; + argv[argvIndex] = new char[mdArg.length() + 1]; strcpy(argv[argvIndex], mdArg.c_str()); } - auto mdModules = std::make_unique(); + auto mdModules = std::make_unique(); - const char *desc[] = {"gmxapi placeholder text"}; + const char* desc[] = { "gmxapi placeholder text" }; if (options_.updateFromCommandLine(argc, argv.data(), desc) == 0) { return nullptr; } ArrayRef multiSimDirectoryNames = - opt2fnsIfOptionSet("-multidir", ssize(options_.filenames), options_.filenames.data()); + opt2fnsIfOptionSet("-multidir", ssize(options_.filenames), options_.filenames.data()); // Set up the communicator, where possible (see docs for // SimulationContext). - MPI_Comm communicator = GMX_LIB_MPI ? MPI_COMM_WORLD : MPI_COMM_NULL; + MPI_Comm communicator = GMX_LIB_MPI ? MPI_COMM_WORLD : MPI_COMM_NULL; // The SimulationContext is necessary with gmxapi so that // resources owned by the client code can have suitable // lifetime. The gmx wrapper binary uses the same infrastructure, @@ -169,16 +170,13 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) SimulationContext simulationContext(communicator, multiSimDirectoryNames); - StartingBehavior startingBehavior = StartingBehavior::NewSimulation; - LogFilePtr logFileGuard = nullptr; - gmx_multisim_t *ms = simulationContext.multiSimulation_.get(); - std::tie(startingBehavior, - logFileGuard) = handleRestart(findIsSimulationMasterRank(ms, communicator), - communicator, - ms, - options_.mdrunOptions.appendingBehavior, - ssize(options_.filenames), - options_.filenames.data()); + StartingBehavior startingBehavior = StartingBehavior::NewSimulation; + LogFilePtr logFileGuard = nullptr; + gmx_multisim_t* ms = simulationContext.multiSimulation_.get(); + std::tie(startingBehavior, logFileGuard) = + handleRestart(findIsSimulationMasterRank(ms, communicator), communicator, ms, + options_.mdrunOptions.appendingBehavior, ssize(options_.filenames), + options_.filenames.data()); auto builder = MdrunnerBuilder(std::move(mdModules), compat::not_null(&simulationContext)); @@ -203,13 +201,11 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) builder.addLogFile(logFileGuard.get()); // Note, creation is not mature enough to be exposed in the external API yet. - launchedSession = createSession(shared_from_this(), - std::move(builder), - std::move(simulationContext), - std::move(logFileGuard)); + launchedSession = createSession(shared_from_this(), std::move(builder), + std::move(simulationContext), std::move(logFileGuard)); // Clean up argv once builder is no longer in use - for (auto && string : argv) + for (auto&& string : argv) { if (string != nullptr) { @@ -217,7 +213,6 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) string = nullptr; } } - } else { @@ -233,24 +228,22 @@ std::shared_ptr ContextImpl::launch(const Workflow &work) } // As of gmxapi 0.0.3 there is only one Context type -Context::Context() : - Context {ContextImpl::create()} +Context::Context() : Context{ ContextImpl::create() } { GMX_ASSERT(impl_, "Context requires a non-null implementation member."); } -std::shared_ptr Context::launch(const Workflow &work) +std::shared_ptr Context::launch(const Workflow& work) { return impl_->launch(work); } -Context::Context(std::shared_ptr impl) : - impl_ {std::move(impl)} +Context::Context(std::shared_ptr impl) : impl_{ std::move(impl) } { GMX_ASSERT(impl_, "Context requires a non-null implementation member."); } -void Context::setMDArgs(const MDArgs &mdArgs) +void Context::setMDArgs(const MDArgs& mdArgs) { impl_->mdArgs_ = mdArgs; } diff --git a/src/api/cpp/context_impl.h b/src/api/cpp/context_impl.h index f90e323c34..faaf0e5851 100644 --- a/src/api/cpp/context_impl.h +++ b/src/api/cpp/context_impl.h @@ -64,93 +64,93 @@ namespace gmxapi */ class ContextImpl final : public std::enable_shared_from_this { - public: - /*! - * \brief Default constructor. - * - * Don't use this. Use create() to get a shared pointer right away. - * Otherwise, shared_from_this() is potentially dangerous. - * - * \todo Make default constructor private or otherwise reduce brittleness of construction. - */ - ContextImpl(); +public: + /*! + * \brief Default constructor. + * + * Don't use this. Use create() to get a shared pointer right away. + * Otherwise, shared_from_this() is potentially dangerous. + * + * \todo Make default constructor private or otherwise reduce brittleness of construction. + */ + ContextImpl(); - /*! - * \brief Factory function - * - * Since this class provides `shared_from_this`, we need to make sure - * that it never exists without a shared_ptr owning it. - * - * If we can confirm `shared_from_this` is no longer necessary, implementation may change. - * - * \return ownership of a new object - */ - static std::shared_ptr create(); + /*! + * \brief Factory function + * + * Since this class provides `shared_from_this`, we need to make sure + * that it never exists without a shared_ptr owning it. + * + * If we can confirm `shared_from_this` is no longer necessary, implementation may change. + * + * \return ownership of a new object + */ + static std::shared_ptr create(); - /*! - * \brief Copy disallowed because Session state would become ambiguous. - * - * The API implementation needs to unambiguously determine - * which Sessions and Contexts are associated with each other. - * \{ - */ - ContextImpl(const ContextImpl&) = delete; - ContextImpl &operator=(const ContextImpl &) = delete; - //! \} + /*! + * \brief Copy disallowed because Session state would become ambiguous. + * + * The API implementation needs to unambiguously determine + * which Sessions and Contexts are associated with each other. + * \{ + */ + ContextImpl(const ContextImpl&) = delete; + ContextImpl& operator=(const ContextImpl&) = delete; + //! \} - /*! - * \brief Objects are not trivial to move. - * - * \todo Implement move semantics. - * \{ - */ - ContextImpl(ContextImpl &&) = delete; - ContextImpl &operator=(ContextImpl &&) = delete; - //! \} + /*! + * \brief Objects are not trivial to move. + * + * \todo Implement move semantics. + * \{ + */ + ContextImpl(ContextImpl&&) = delete; + ContextImpl& operator=(ContextImpl&&) = delete; + //! \} - /*! - * \brief Translate the workflow to the execution context and launch. - * - * \param work workflow graph - * \return ownership of a new session - * - * \todo This probably makes more sense as a free function, but we need to determine access policies. - * - * Session is returned with shared_ptr ownership so that Context - * can hold a weak_ptr and because Session Resources handles - * are still evolving. - * \todo Hide lifetime management and ownership from handle object. - * We can achieve the necessary aspects of this shared_ptr at a lower level of implementation. - */ - std::shared_ptr launch(const Workflow &work); + /*! + * \brief Translate the workflow to the execution context and launch. + * + * \param work workflow graph + * \return ownership of a new session + * + * \todo This probably makes more sense as a free function, but we need to determine access policies. + * + * Session is returned with shared_ptr ownership so that Context + * can hold a weak_ptr and because Session Resources handles + * are still evolving. + * \todo Hide lifetime management and ownership from handle object. + * We can achieve the necessary aspects of this shared_ptr at a lower level of implementation. + */ + std::shared_ptr launch(const Workflow& work); - /*! - * \brief Retain the ability to find a launched session while it exists. - * - * The client owns the Session launched by a Context, but it is helpful - * for the Context to know if it has an active Session associated with it. - */ - std::weak_ptr session_; + /*! + * \brief Retain the ability to find a launched session while it exists. + * + * The client owns the Session launched by a Context, but it is helpful + * for the Context to know if it has an active Session associated with it. + */ + std::weak_ptr session_; - /*! - * \brief mdrun command line arguments. - * - * Store arguments provided by the client and pass them when launching - * a simulation runner. This allows client code to access the same - * options as are available to mdrun on the command line while the API - * evolves. - */ - MDArgs mdArgs_; + /*! + * \brief mdrun command line arguments. + * + * Store arguments provided by the client and pass them when launching + * a simulation runner. This allows client code to access the same + * options as are available to mdrun on the command line while the API + * evolves. + */ + MDArgs mdArgs_; - /*! - * \brief Legacy option-handling and set up for mdrun. - * - * This object should not exist, but is necessary now to introduce - * the API in a way that means CLI and API work similarly and do not - * duplicate definitions e.g. of command-line options. - */ - gmx::LegacyMdrunOptions options_; + /*! + * \brief Legacy option-handling and set up for mdrun. + * + * This object should not exist, but is necessary now to introduce + * the API in a way that means CLI and API work similarly and do not + * duplicate definitions e.g. of command-line options. + */ + gmx::LegacyMdrunOptions options_; }; -} // end namespace gmxapi -#endif //GMXAPI_CONTEXT_IMPL_H +} // end namespace gmxapi +#endif // GMXAPI_CONTEXT_IMPL_H diff --git a/src/api/cpp/createsession.h b/src/api/cpp/createsession.h index 487d065268..dd28e05c24 100644 --- a/src/api/cpp/createsession.h +++ b/src/api/cpp/createsession.h @@ -68,12 +68,12 @@ namespace gmxapi * * \return Ownership of new Session implementation instance. */ -std::shared_ptr createSession(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr logFilehandle); +std::shared_ptr createSession(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr logFilehandle); -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_LIBRARY_SESSION_H +#endif // GMXAPI_LIBRARY_SESSION_H diff --git a/src/api/cpp/exceptions.cpp b/src/api/cpp/exceptions.cpp index 572df6a63d..04365db5c8 100644 --- a/src/api/cpp/exceptions.cpp +++ b/src/api/cpp/exceptions.cpp @@ -45,13 +45,13 @@ Exception::Exception() = default; Exception::~Exception() = default; -Exception::Exception(const Exception &) = default; +Exception::Exception(const Exception&) = default; -Exception &Exception::operator=(const Exception &) = default; +Exception& Exception::operator=(const Exception&) = default; -Exception::Exception(Exception &&) noexcept = default; +Exception::Exception(Exception&&) noexcept = default; -Exception &Exception::operator=(Exception &&) noexcept = default; +Exception& Exception::operator=(Exception&&) noexcept = default; const char* Exception::what() const noexcept { diff --git a/src/api/cpp/include/gmxapi/compat/mdparams.h b/src/api/cpp/include/gmxapi/compat/mdparams.h index cbf07f2a6f..0f40d4ce82 100644 --- a/src/api/cpp/include/gmxapi/compat/mdparams.h +++ b/src/api/cpp/include/gmxapi/compat/mdparams.h @@ -59,17 +59,17 @@ class GmxMdParamsImpl; class GmxMdParams { - public: - GmxMdParams(); - ~GmxMdParams(); - GmxMdParams(const GmxMdParams &) = delete; - GmxMdParams &operator=(const GmxMdParams &) = delete; - GmxMdParams(GmxMdParams &&) noexcept; - GmxMdParams &operator=(GmxMdParams &&) noexcept; +public: + GmxMdParams(); + ~GmxMdParams(); + GmxMdParams(const GmxMdParams&) = delete; + GmxMdParams& operator=(const GmxMdParams&) = delete; + GmxMdParams(GmxMdParams&& /*unused*/) noexcept; + GmxMdParams& operator=(GmxMdParams&& /*unused*/) noexcept; - explicit GmxMdParams(std::unique_ptr &&impl); + explicit GmxMdParams(std::unique_ptr&& impl); - std::unique_ptr params_; + std::unique_ptr params_; }; /*! @@ -81,8 +81,8 @@ class GmxMdParams * \note The returned data is a copy. Modifying the return value has no affect on * the original object inspected. */ -std::vector keys(const GmxMdParams ¶ms); +std::vector keys(const GmxMdParams& params); -} // end namespace gmxapicompat +} // end namespace gmxapicompat -#endif //GMXAPICOMPAT_MDPARAMS_H +#endif // GMXAPICOMPAT_MDPARAMS_H diff --git a/src/api/cpp/include/gmxapi/compat/tpr.h b/src/api/cpp/include/gmxapi/compat/tpr.h index 0479307ab8..e3f79985ad 100644 --- a/src/api/cpp/include/gmxapi/compat/tpr.h +++ b/src/api/cpp/include/gmxapi/compat/tpr.h @@ -74,27 +74,28 @@ class TprContents; class TprReadHandle { - public: - explicit TprReadHandle(std::shared_ptr tprFile); - explicit TprReadHandle(TprContents &&tprFile); - TprReadHandle(const TprReadHandle &) = default; - TprReadHandle &operator=(const TprReadHandle &) = default; - TprReadHandle(TprReadHandle &&) noexcept = default; - TprReadHandle &operator=(TprReadHandle &&) noexcept = default; - ~TprReadHandle(); - - /*! - * \brief Allow API functions to access data resources. - * - * Used internally. The entire TPR contents are never extracted to the - * client, but API implementation details need to be - * able to access some or all entire contents in later operations. - * - * \return Reference-counted handle to data container. - */ - std::shared_ptr get() const; - private: - std::shared_ptr tprContents_; +public: + explicit TprReadHandle(std::shared_ptr tprFile); + explicit TprReadHandle(TprContents&& tprFile); + TprReadHandle(const TprReadHandle&) = default; + TprReadHandle& operator=(const TprReadHandle&) = default; + TprReadHandle(TprReadHandle&&) noexcept = default; + TprReadHandle& operator=(TprReadHandle&&) noexcept = default; + ~TprReadHandle(); + + /*! + * \brief Allow API functions to access data resources. + * + * Used internally. The entire TPR contents are never extracted to the + * client, but API implementation details need to be + * able to access some or all entire contents in later operations. + * + * \return Reference-counted handle to data container. + */ + std::shared_ptr get() const; + +private: + std::shared_ptr tprContents_; }; /*! @@ -104,24 +105,24 @@ class TprReadHandle * * \todo This is a very temporary shim! Find a better way to construct simulation input. */ -TprReadHandle getSourceFileHandle(const GmxMdParams ¶ms); +TprReadHandle getSourceFileHandle(const GmxMdParams& params); class StructureSource { - public: - std::shared_ptr tprFile_; +public: + std::shared_ptr tprFile_; }; class TopologySource { - public: - std::shared_ptr tprFile_; +public: + std::shared_ptr tprFile_; }; class SimulationState { - public: - std::shared_ptr tprFile_; +public: + std::shared_ptr tprFile_; }; /*! @@ -131,7 +132,7 @@ class SimulationState * \param outFile output TPR file name * \return true if successful. else false. */ -bool copy_tprfile(const gmxapicompat::TprReadHandle &input, const std::string &outFile); +bool copy_tprfile(const gmxapicompat::TprReadHandle& input, const std::string& outFile); /*! * \brief Copy and possibly update TPR file by name. @@ -141,8 +142,8 @@ bool copy_tprfile(const gmxapicompat::TprReadHandle &input, const std::string &o * \param endTime Replace `nsteps` in infile with `endTime/dt` * \return true if successful, else false */ -bool rewrite_tprfile(const std::string &inFile, const std::string &outFile, double endTime); +bool rewrite_tprfile(const std::string& inFile, const std::string& outFile, double endTime); -} // end namespace gmxapicompat +} // end namespace gmxapicompat -#endif //GMXAPICOMPAT_TPR_H +#endif // GMXAPICOMPAT_TPR_H diff --git a/src/api/cpp/include/gmxapi/context.h b/src/api/cpp/include/gmxapi/context.h index 88c8bb4644..855599ce2d 100644 --- a/src/api/cpp/include/gmxapi/context.h +++ b/src/api/cpp/include/gmxapi/context.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -101,73 +101,73 @@ class ContextImpl; */ class Context { - public: - /*! - * \brief Get a handle to a new default context object. - */ - Context(); - ~Context(); +public: + /*! + * \brief Get a handle to a new default context object. + */ + Context(); + ~Context(); - /*! - * \brief Nearly trivial copy - * - * \{ - */ - Context(const Context &) = default; - Context &operator=(const Context &) = default; - //! \} + /*! + * \brief Nearly trivial copy + * + * \{ + */ + Context(const Context&) = default; + Context& operator=(const Context&) = default; + //! \} - /*! - * \brief Allow move - * - * \{ - */ - Context(Context &&) = default; - Context &operator=(Context &&) = default; - //! \} + /*! + * \brief Allow move + * + * \{ + */ + Context(Context&&) = default; + Context& operator=(Context&&) = default; + //! \} - /*! - * \brief Construct by wrapping an implementation object. - * - * \param impl Ownership of Context definition and resources. - */ - explicit Context(std::shared_ptr impl); + /*! + * \brief Construct by wrapping an implementation object. + * + * \param impl Ownership of Context definition and resources. + */ + explicit Context(std::shared_ptr impl); - /*! - * \brief Set the simulation runtime arguments for this instance. - * - * \param mdArgs User-provided runtime parameters (such as for `gmx mdrun`) - * - * This is awkwardly named and due for some evolution, since most of the mdrun CLI options pertain - * to the execution environment rather than the simulation parameters. For the first implementation, - * we just map user arguments to the equivalent command-line substrings. - */ - void setMDArgs(const MDArgs &mdArgs); + /*! + * \brief Set the simulation runtime arguments for this instance. + * + * \param mdArgs User-provided runtime parameters (such as for `gmx mdrun`) + * + * This is awkwardly named and due for some evolution, since most of the mdrun CLI options + * pertain to the execution environment rather than the simulation parameters. For the first + * implementation, we just map user arguments to the equivalent command-line substrings. + */ + void setMDArgs(const MDArgs& mdArgs); - /*! - * \brief Launch a workflow in the current context, if possible. - * - * \param work Configured workflow to instantiate. - * \return Ownership of a new session or nullptr if not possible. - */ - std::shared_ptr launch(const Workflow &work); + /*! + * \brief Launch a workflow in the current context, if possible. + * + * \param work Configured workflow to instantiate. + * \return Ownership of a new session or nullptr if not possible. + */ + std::shared_ptr launch(const Workflow& work); - private: - /*! - * \brief Private implementation - * - * Early implementation has not yet developed distinct handle classes - * for different levels of access to the Context. In this implementation, - * new Context handles to the same resources can be created (in library code) - * by constructing from a smart pointer to an implementation object. - * - * \todo Consider client requirements and ownership contracts. - * Whether/how API client might be required to create and hold a Context - * and/or Session object for the length of a process. - */ - std::shared_ptr impl_; +private: + /*! + * \brief Private implementation + * + * Early implementation has not yet developed distinct handle classes + * for different levels of access to the Context. In this implementation, + * new Context handles to the same resources can be created (in library code) + * by constructing from a smart pointer to an implementation object. + * + * \todo Consider client requirements and ownership contracts. + * Whether/how API client might be required to create and hold a Context + * and/or Session object for the length of a process. + */ + std::shared_ptr impl_; }; -} // end namespace gmxapi +} // end namespace gmxapi #endif // header guard diff --git a/src/api/cpp/include/gmxapi/exceptions.h b/src/api/cpp/include/gmxapi/exceptions.h index 34272a825c..705b3aeb17 100644 --- a/src/api/cpp/include/gmxapi/exceptions.h +++ b/src/api/cpp/include/gmxapi/exceptions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,18 +63,18 @@ namespace gmxapi */ class Exception : public std::exception { - public: - //! \cond - Exception(); - ~Exception() override; - Exception(const Exception &); - Exception &operator=(const Exception &); +public: + //! \cond + Exception(); + ~Exception() override; + Exception(const Exception& /*unused*/); + Exception& operator=(const Exception& /*unused*/); - Exception(Exception &&) noexcept; - Exception &operator=(Exception &&) noexcept; + Exception(Exception&& /*unused*/) noexcept; + Exception& operator=(Exception&& /*unused*/) noexcept; - const char* what() const noexcept override; - //! \endcond + const char* what() const noexcept override; + //! \endcond }; /*! @@ -102,42 +102,34 @@ class Exception : public std::exception template class BasicException : public Exception { - private: - //! Store the usual exception message as a std::string instead of C string. - std::string what_; - public: - //! Initialize with empty message. - BasicException() : BasicException{std::string()} - {} +private: + //! Store the usual exception message as a std::string instead of C string. + std::string what_; - /*! - * \brief Copy a string to use for the exception message. - * - * \param message - * \{ - */ - explicit BasicException(std::string message) noexcept : - what_ {std::move(message)} - {} +public: + //! Initialize with empty message. + BasicException() : BasicException{ std::string() } {} - explicit BasicException(const char* message) - { - what_ = message; - } - //! \} + /*! + * \brief Copy a string to use for the exception message. + * + * \param message + * \{ + */ + explicit BasicException(std::string message) noexcept : what_{ std::move(message) } {} - /*! - * \brief Get message. - * - * \return pointer to C string. - * - * It is the responsibility of the caller to keep the Exception object alive while the char - * pointer is in use. - */ - const char* what() const noexcept override - { - return what_.c_str(); - } + explicit BasicException(const char* message) { what_ = message; } + //! \} + + /*! + * \brief Get message. + * + * \return pointer to C string. + * + * It is the responsibility of the caller to keep the Exception object alive while the char + * pointer is in use. + */ + const char* what() const noexcept override { return what_.c_str(); } }; /*! \brief Behavioral protocol violated. @@ -153,8 +145,8 @@ class BasicException : public Exception */ class ProtocolError : public BasicException { - public: - using BasicException::BasicException; +public: + using BasicException::BasicException; }; /*! @@ -168,8 +160,8 @@ class ProtocolError : public BasicException */ class NotImplementedError : public BasicException { - public: - using BasicException::BasicException; +public: + using BasicException::BasicException; }; /*! @@ -181,10 +173,10 @@ class NotImplementedError : public BasicException */ class UsageError : public BasicException { - public: - using BasicException::BasicException; +public: + using BasicException::BasicException; }; -} // end namespace gmxapi +} // end namespace gmxapi #endif // header guard diff --git a/src/api/cpp/include/gmxapi/gmxapi.h b/src/api/cpp/include/gmxapi/gmxapi.h index e38ecd73b1..4e4bc2752d 100644 --- a/src/api/cpp/include/gmxapi/gmxapi.h +++ b/src/api/cpp/include/gmxapi/gmxapi.h @@ -392,111 +392,111 @@ static constexpr const char MDHolder_Name[] = "__GMXAPI_MDHolder_v1__"; */ class MDHolder { - public: - /*! - * \brief Declare the schema for extra checks before casting. - * - * MDHolder exists for cases where API objects can only be passed by - * casting pointers. api_name is suitable as a descriptor of the schema - * of the object pointed to. See, for instance, usage of the PyCapsule_IsValid - * Python C API function. - */ - static const char* api_name; +public: + /*! + * \brief Declare the schema for extra checks before casting. + * + * MDHolder exists for cases where API objects can only be passed by + * casting pointers. api_name is suitable as a descriptor of the schema + * of the object pointed to. See, for instance, usage of the PyCapsule_IsValid + * Python C API function. + */ + static const char* api_name; - MDHolder(); + MDHolder(); - /*! - * \brief For convenience and logging, give the object an identifying string. - * - * \param name - */ - explicit MDHolder(std::string name); + /*! + * \brief For convenience and logging, give the object an identifying string. + * + * \param name + */ + explicit MDHolder(std::string name); - /*! - * \brief Wrap a Molecular Dynamics work specification. - * - * The container allows portable specification of MD work to be performed. - * It is used when setting up and then launching the simulation. - * - * \param spec references a container with interfaces for client and library APIs - * - * Example: - * - * # With `system` as a gmxapi::System object - * auto spec = system->getSpec(); - * auto holder = std::make_unique(spec); - * - * A PyCapsule object with the name given by gmxapi::MDHolder_Name is assumed to - * contain a pointer to an MDHolder and to have an appropriate deleter attached. - * - * Example: - * - * auto deleter = [](PyObject *o) { - * if (PyCapsule_IsValid(o, gmxapi::MDHolder_Name)) - * { - * auto holder_ptr = (gmxapi::MDHolder *) PyCapsule_GetPointer(o, gmxapi::MDHolder_Name); - * delete holder_ptr; - * }; - * }; - * # With pybind11 PyCapsule bindings: - * auto capsule = py::capsule(holder, - * gmxapi::MDHolder_Name, - * deleter); - * - * The gmxapi Python package gives modules a chance to associate themselves with a - * gmxapi::System object by passing such a PyCapsule to its `bind` method, if implemented. - * - * Such a bind method could be implemented as follows. Assume object.ptr() returns a - * `PyObject*` - * - * Example: - * - * PyObject* capsule = object.ptr(); - * if (PyCapsule_IsValid(capsule, gmxapi::MDHolder::api_name)) - * { - * auto holder = static_cast(PyCapsule_GetPointer(capsule, - * gmxapi::MDHolder::api_name)); - * auto workSpec = holder->getSpec(); - * workSpec->addModule(module); - * } - * else - * { - * throw gmxapi::ProtocolError("bind method requires a python capsule as input"); - * } - */ - explicit MDHolder(std::shared_ptr spec); + /*! + * \brief Wrap a Molecular Dynamics work specification. + * + * The container allows portable specification of MD work to be performed. + * It is used when setting up and then launching the simulation. + * + * \param spec references a container with interfaces for client and library APIs + * + * Example: + * + * # With `system` as a gmxapi::System object + * auto spec = system->getSpec(); + * auto holder = std::make_unique(spec); + * + * A PyCapsule object with the name given by gmxapi::MDHolder_Name is assumed to + * contain a pointer to an MDHolder and to have an appropriate deleter attached. + * + * Example: + * + * auto deleter = [](PyObject *o) { + * if (PyCapsule_IsValid(o, gmxapi::MDHolder_Name)) + * { + * auto holder_ptr = (gmxapi::MDHolder *) PyCapsule_GetPointer(o, + * gmxapi::MDHolder_Name); delete holder_ptr; + * }; + * }; + * # With pybind11 PyCapsule bindings: + * auto capsule = py::capsule(holder, + * gmxapi::MDHolder_Name, + * deleter); + * + * The gmxapi Python package gives modules a chance to associate themselves with a + * gmxapi::System object by passing such a PyCapsule to its `bind` method, if implemented. + * + * Such a bind method could be implemented as follows. Assume object.ptr() returns a + * `PyObject*` + * + * Example: + * + * PyObject* capsule = object.ptr(); + * if (PyCapsule_IsValid(capsule, gmxapi::MDHolder::api_name)) + * { + * auto holder = static_cast(PyCapsule_GetPointer(capsule, + * gmxapi::MDHolder::api_name)); + * auto workSpec = holder->getSpec(); + * workSpec->addModule(module); + * } + * else + * { + * throw gmxapi::ProtocolError("bind method requires a python capsule as input"); + * } + */ + explicit MDHolder(std::shared_ptr spec); - /*! - * \brief Get client-provided name. - * - * \return Name as string. - */ - std::string name() const; + /*! + * \brief Get client-provided name. + * + * \return Name as string. + */ + std::string name() const; - /*! \brief Instance name. - */ - std::string name_ {}; + /*! \brief Instance name. + */ + std::string name_{}; - /// \{ - /*! - * \brief Get the wrapped work specification - * \return shared ownership of the api object. - */ - std::shared_ptr getSpec(); - /*! - * \brief Get the wrapped work specification - * \return smart pointer to const object - */ - std::shared_ptr getSpec() const; - /// \} - private: - /*! \cond internal - * \brief private implementation class - */ - class Impl; - /// \brief opaque pointer to implementation - std::shared_ptr impl_ {nullptr}; - /*! \endcond */ + /// \{ + /*! + * \brief Get the wrapped work specification + * \return shared ownership of the api object. + */ + std::shared_ptr getSpec(); + /*! + * \brief Get the wrapped work specification + * \return smart pointer to const object + */ + std::shared_ptr getSpec() const; + /// \} +private: + /*! \cond internal + * \brief private implementation class + */ + class Impl; + /// \brief opaque pointer to implementation + std::shared_ptr impl_{ nullptr }; + /*! \endcond */ }; /*! @@ -521,6 +521,6 @@ enum class GmxapiType STRING, //! string with metadata NDARRAY, //! multi-dimensional array with metadata }; -} // end namespace gmxapi +} // end namespace gmxapi -#endif // header guard +#endif // header guard diff --git a/src/api/cpp/include/gmxapi/gmxapicompat.h b/src/api/cpp/include/gmxapi/gmxapicompat.h index f9dad254d0..67b33ed866 100644 --- a/src/api/cpp/include/gmxapi/gmxapicompat.h +++ b/src/api/cpp/include/gmxapi/gmxapicompat.h @@ -97,10 +97,10 @@ class TypeError : public gmxapi::BasicException */ std::map simulationParameterTypeMap(); -std::map boolParams(); -std::map int32Params(); -std::map float32Params(); -std::map float64Params(); +std::map boolParams(); +std::map int32Params(); +std::map float32Params(); +std::map float64Params(); std::map int64Params(); /*! @@ -111,7 +111,7 @@ std::map int64Params(); * * \throws gmxapi_compat::ValueError for parameters with no mapping. */ -gmxapi::GmxapiType mdParamToType(const std::string &name); +gmxapi::GmxapiType mdParamToType(const std::string& name); /*! * \brief Facade for objects that can provide atomic data for a configuration. @@ -166,7 +166,7 @@ class TprReadHandle; * \param filename Path of file to read. * \return handle that may share ownership of TPR file resource. */ -std::unique_ptr readTprFile(const std::string &filename); +std::unique_ptr readTprFile(const std::string& filename); /*! * \brief Write a new TPR file to the filesystem with the provided contents. @@ -179,11 +179,11 @@ std::unique_ptr readTprFile(const std::string &filename); * * \throws ValueError for invalid or irreconcilable input. */ -void writeTprFile(const std::string &filename, - const GmxMdParams ¶ms, - const StructureSource &structure, - const SimulationState &state, - const TopologySource &topology); +void writeTprFile(const std::string& filename, + const GmxMdParams& params, + const StructureSource& structure, + const SimulationState& state, + const TopologySource& topology); /*! * \brief Get a topology source from the TPR contents collection. @@ -193,7 +193,7 @@ void writeTprFile(const std::string &filename, * \todo replace with a helper template on T::topologySource() member function existence. */ -std::unique_ptr getTopologySource(const TprReadHandle &handle); +std::unique_ptr getTopologySource(const TprReadHandle& handle); /*! * \brief Get a source of simulation state from the TPR contents collection. @@ -202,21 +202,21 @@ std::unique_ptr getTopologySource(const TprReadHandle &handle); * * \todo template on T::simulationState() member function existence. */ -std::unique_ptr getSimulationState(const TprReadHandle &handle); +std::unique_ptr getSimulationState(const TprReadHandle& handle); /*! * \brief Get a source of atomic structure from the TPR contents collection. * \param handle * \return */ -std::unique_ptr getStructureSource(const TprReadHandle &handle); +std::unique_ptr getStructureSource(const TprReadHandle& handle); /*! * \brief Get an initialized parameters structure. * \param handle * \return */ -std::unique_ptr getMdParams(const TprReadHandle &handle); +std::unique_ptr getMdParams(const TprReadHandle& handle); /*! * \brief A set of overloaded functions to fetch parameters of the indicated type, if possible. @@ -228,15 +228,15 @@ std::unique_ptr getMdParams(const TprReadHandle &handle); * Could be used for dispatch and/or some sort of templating in the future, but * invoked directly for now. */ -int extractParam(const GmxMdParams ¶ms, const std::string &name, int); -int64_t extractParam(const GmxMdParams¶ms, const std::string& name, int64_t); -float extractParam(const GmxMdParams ¶ms, const std::string &name, float); -double extractParam(const GmxMdParams ¶ms, const std::string &name, double); +int extractParam(const GmxMdParams& params, const std::string& name, int /*unused*/); +int64_t extractParam(const GmxMdParams& params, const std::string& name, int64_t /*unused*/); +float extractParam(const GmxMdParams& params, const std::string& name, float /*unused*/); +double extractParam(const GmxMdParams& params, const std::string& name, double /*unused*/); -void setParam(GmxMdParams* params, const std::string &name, double value); -void setParam(GmxMdParams* params, const std::string &name, int64_t value); +void setParam(GmxMdParams* params, const std::string& name, double value); +void setParam(GmxMdParams* params, const std::string& name, int64_t value); // TODO: unsetParam -} // end namespace gmxapicompat +} // end namespace gmxapicompat -#endif //GMXAPICOMPAT_H +#endif // GMXAPICOMPAT_H diff --git a/src/api/cpp/include/gmxapi/gromacsfwd.h b/src/api/cpp/include/gmxapi/gromacsfwd.h index e46f183f91..e40afa2995 100644 --- a/src/api/cpp/include/gmxapi/gromacsfwd.h +++ b/src/api/cpp/include/gmxapi/gromacsfwd.h @@ -68,6 +68,6 @@ namespace gmx // Forward declaration for libgromacs header gromacs/restraint/restraintpotential.h class IRestraintPotential; -} // end namespace gmx +} // end namespace gmx -#endif //GMXAPI_GROMACSFWD_H +#endif // GMXAPI_GROMACSFWD_H diff --git a/src/api/cpp/include/gmxapi/md.h b/src/api/cpp/include/gmxapi/md.h index 54888b72ba..a48411aa4e 100644 --- a/src/api/cpp/include/gmxapi/md.h +++ b/src/api/cpp/include/gmxapi/md.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,8 +37,8 @@ /*! \file * \brief Declare base classes and API for MD simulation engines. * - * This header allows interaction with gmxapi for basic MD simulation functionality in client code without - * additional dependencies. + * This header allows interaction with gmxapi for basic MD simulation functionality in client code + * without additional dependencies. * * Helper functions, standard concrete classes, and implementation interfaces are in gmxapi/md/ * \ingroup gmxapi_md @@ -54,9 +54,9 @@ /*! \defgroup gmxapi_md Molecular Dynamics * \brief API access to Molecular Mechanics and Molecular Dynamics calculation in GROMACS * - * At a minimum, the client code must specify the input source for a MD simulation. Helper functions allow setting up - * inputs from a standard GROMACS run input `.tpr` file. A System object serves as a container for a molecular system - * and associated computational work. + * At a minimum, the client code must specify the input source for a MD simulation. Helper functions + * allow setting up inputs from a standard GROMACS run input `.tpr` file. A System object serves as + * a container for a molecular system and associated computational work. * * \ingroup gmxapi */ @@ -154,33 +154,34 @@ class MDModule; */ class MDWorkSpec { - public: - MDWorkSpec(); - ~MDWorkSpec(); - - /*! - * \brief Grant shared ownership of a modular MD computation object - * - * \param module instance that can produce a IRestraintPotential at runtime. - */ - void addModule(std::shared_ptr module); - - /*! - * \brief Get a handle to the stored list of modules - * - * Future versions of MDWorkSpec will not directly hold and grant access to module instances. - * \return reference that is only valid for the life of this object. - */ - std::vector < std::shared_ptr < gmxapi::MDModule>>&getModules(); - private: - //! \cond internal - //! \brief Private implementation class - class Impl; - //! \brief Opaque pointer to implementation object. - std::unique_ptr impl_; - //! \endcond +public: + MDWorkSpec(); + ~MDWorkSpec(); + + /*! + * \brief Grant shared ownership of a modular MD computation object + * + * \param module instance that can produce a IRestraintPotential at runtime. + */ + void addModule(std::shared_ptr module); + + /*! + * \brief Get a handle to the stored list of modules + * + * Future versions of MDWorkSpec will not directly hold and grant access to module instances. + * \return reference that is only valid for the life of this object. + */ + std::vector>& getModules(); + +private: + //! \cond internal + //! \brief Private implementation class + class Impl; + //! \brief Opaque pointer to implementation object. + std::unique_ptr impl_; + //! \endcond }; -} // end namespace gmxapi +} // end namespace gmxapi #endif // header guard diff --git a/src/api/cpp/include/gmxapi/md/mdmodule.h b/src/api/cpp/include/gmxapi/md/mdmodule.h index f203f94057..e03726f9a8 100644 --- a/src/api/cpp/include/gmxapi/md/mdmodule.h +++ b/src/api/cpp/include/gmxapi/md/mdmodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,37 +69,37 @@ namespace gmxapi */ class MDModule { - public: - virtual ~MDModule(); +public: + virtual ~MDModule(); - /*! - * \brief Get a user-friendly identifier for an instance. - * - * \return see documentation for specific MDModule implementations. - */ - virtual const char* name() const; + /*! + * \brief Get a user-friendly identifier for an instance. + * + * \return see documentation for specific MDModule implementations. + */ + virtual const char* name() const; - /*! - * \brief Allows module to provide a restraint implementation. - * - * To implement a restraint, override this function. - * \return shared ownership of a restraint implementation or nullptr if not implemented. - * - * With future maturation, this interface will presumably be revised to something - * more abstract, though I'm not sure what form that would take. We will probably - * still need to have a general set of possible module types defined with the API, - * in which case it does make sense to have clearly typed dispatching, and - * `bool hasRestraint = module->getRestraint() != nullptr;` might be the simplest thing. - * - * Implementing a restraint is explained in the GROMACS developer documentation, - * which is currently built separately from the GMXAPI documentation. - * Also, refer to the sample plugin in a repository hosted in the same - * place this git repository is found. - */ - virtual std::shared_ptr<::gmx::IRestraintPotential> getRestraint(); + /*! + * \brief Allows module to provide a restraint implementation. + * + * To implement a restraint, override this function. + * \return shared ownership of a restraint implementation or nullptr if not implemented. + * + * With future maturation, this interface will presumably be revised to something + * more abstract, though I'm not sure what form that would take. We will probably + * still need to have a general set of possible module types defined with the API, + * in which case it does make sense to have clearly typed dispatching, and + * `bool hasRestraint = module->getRestraint() != nullptr;` might be the simplest thing. + * + * Implementing a restraint is explained in the GROMACS developer documentation, + * which is currently built separately from the GMXAPI documentation. + * Also, refer to the sample plugin in a repository hosted in the same + * place this git repository is found. + */ + virtual std::shared_ptr<::gmx::IRestraintPotential> getRestraint(); }; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_MDMODULE_H +#endif // GMXAPI_MDMODULE_H diff --git a/src/api/cpp/include/gmxapi/md/mdsignals.h b/src/api/cpp/include/gmxapi/md/mdsignals.h index 28abd58d7e..b6b9243bc8 100644 --- a/src/api/cpp/include/gmxapi/md/mdsignals.h +++ b/src/api/cpp/include/gmxapi/md/mdsignals.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,10 +68,10 @@ enum class signals STOP }; -} // end namespace md +} // end namespace md -class SessionResources; // reference gmxapi/session/resources.h +class SessionResources; // reference gmxapi/session/resources.h /*! * \brief Proxy for signalling function objects. @@ -84,40 +84,40 @@ class SessionResources; // reference gmxapi/session/resources.h */ class Signal { - public: - //! \internal - class SignalImpl; - - /*! - * \brief Construct by taking ownership of an implementation object. - * - * \param signal - */ - explicit Signal(std::unique_ptr signal); - - /*! - * \brief Object is trivially moveable. - * - * \{ - */ - Signal(Signal &&) noexcept; - Signal &operator=(Signal &&) noexcept; - //! \} - - //! \cond - ~Signal(); - //! \endcond - - /*! - * \brief Signal interface is a function object that issues a signal when called. - * - * \todo replace with more concise named type based on std::function. - */ - void operator()(); - - private: - //! Wrapped signaller. - std::unique_ptr impl_; +public: + //! \internal + class SignalImpl; + + /*! + * \brief Construct by taking ownership of an implementation object. + * + * \param signal + */ + explicit Signal(std::unique_ptr signal); + + /*! + * \brief Object is trivially moveable. + * + * \{ + */ + Signal(Signal&& /*unused*/) noexcept; + Signal& operator=(Signal&& /*unused*/) noexcept; + //! \} + + //! \cond + ~Signal(); + //! \endcond + + /*! + * \brief Signal interface is a function object that issues a signal when called. + * + * \todo replace with more concise named type based on std::function. + */ + void operator()(); + +private: + //! Wrapped signaller. + std::unique_ptr impl_; }; /*! @@ -135,9 +135,8 @@ class Signal * * \ingroup gmxapi_md */ -Signal getMdrunnerSignal(SessionResources *resources, - md::signals signal); +Signal getMdrunnerSignal(SessionResources* resources, md::signals signal); -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_MDSIGNALS_H +#endif // GMXAPI_MDSIGNALS_H diff --git a/src/api/cpp/include/gmxapi/session.h b/src/api/cpp/include/gmxapi/session.h index 368a4c1854..a3c60f2939 100644 --- a/src/api/cpp/include/gmxapi/session.h +++ b/src/api/cpp/include/gmxapi/session.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,7 +56,7 @@ namespace gmxapi { // forward declarations -class Context; // defined in gmxapi/context.h +class Context; // defined in gmxapi/context.h class MDModule; class Status; // defined in gmxapi/status.h class Workflow; // implementation detail @@ -65,8 +65,8 @@ class Workflow; // implementation detail * \brief Private implementation class for a session. * * Actual implementation class may depend on the execution context, but this should be irrelevant to - * a client. The implementation details are not exposed in the high-level API, but may be in the extension - * API. See developer documentation for details. + * a client. The implementation details are not exposed in the high-level API, but may be in the + * extension API. See developer documentation for details. * * \ingroup gmxapi */ @@ -76,8 +76,8 @@ class SessionImpl; * \brief Workflow execution session. * * When a workflow is launched in an execution context, the result is a Session object - * that serves as a handle to interact with the running workflow. The handle allows dynamic changes to - * the workflow, or control or data crossing the API boundary. + * that serves as a handle to interact with the running workflow. The handle allows dynamic changes + * to the workflow, or control or data crossing the API boundary. * * Separating run() from construction allows the client to examine the running execution * environment or to retrieve the communicator before beginning long-running computation. @@ -93,90 +93,90 @@ class SessionImpl; */ class Session { - public: - /// A session must be created by launching a workflow in an execution context. - Session() = delete; - - /*! \brief A session cannot be copied, only moved. - * - * For shared ownership of a session, use a shared pointer. - * \{ - */ - Session(const Session &) = delete; - Session &operator=(const Session &) = delete; - //! \} - - /*! - * \brief Pass ownership of a Session. - * - * \{ - */ - Session(Session &&) noexcept = default; - Session &operator=(Session &&) noexcept = default; - //! \} - - /*! - * \brief Construct by taking ownership of an implementation object. - * - * \param impl Concrete object to take ownership of. - */ - explicit Session(std::unique_ptr impl) noexcept; - - /*! - * \brief Destroy Session. - * - * If the session is still active (has not been closed) then it will be closed - * with exceptions suppressed. If possible, problems encountered will be - * noted in the Status object, which the client may have retained shared - * ownership of. - */ - ~Session(); - - /*! - * \brief Close a running session. - * - * close() should be called before destroying the Session object so that the - * client can catch any exceptions thrown during shut down that may be - * unavoidable in the parallel computing environment. - * - * \return status of close() operation. - */ - Status close(); - - /*! - * \brief Run the current workflow to completion. - * - * The client should examine the Status object for errors and resulting workflow state. - * \return the Session's Status after the run. - */ - Status run() noexcept; - - /*! - * \brief Check if session is running. - * - * A Session will be "open" from the point of launch until "close" is - * called. If this is not true, either an error has occurred or there is - * a bug in the implementation. - * - * \return `true` if the session is running, else `false` - */ - bool isOpen() const noexcept; - - /*! \cond internal - * \brief Get a non-owning handle to the implementation object. - * - * Get a raw pointer to the implementation object. The pointer is valid only during the lifetime of the Session, - * so retain a shared pointer to this Session object or only hold the pointer for the duration of a code block - * guaranteed to exist entirely within the lifetime of a Session object. - * - * \return opaque pointer used by gmxapi implementation and extension code. - */ - SessionImpl* getRaw() const noexcept; - //! \endcond - - private: - //! \brief opaque pointer to implementation - std::unique_ptr impl_; +public: + /// A session must be created by launching a workflow in an execution context. + Session() = delete; + + /*! \brief A session cannot be copied, only moved. + * + * For shared ownership of a session, use a shared pointer. + * \{ + */ + Session(const Session&) = delete; + Session& operator=(const Session&) = delete; + //! \} + + /*! + * \brief Pass ownership of a Session. + * + * \{ + */ + Session(Session&&) noexcept = default; + Session& operator=(Session&&) noexcept = default; + //! \} + + /*! + * \brief Construct by taking ownership of an implementation object. + * + * \param impl Concrete object to take ownership of. + */ + explicit Session(std::unique_ptr impl) noexcept; + + /*! + * \brief Destroy Session. + * + * If the session is still active (has not been closed) then it will be closed + * with exceptions suppressed. If possible, problems encountered will be + * noted in the Status object, which the client may have retained shared + * ownership of. + */ + ~Session(); + + /*! + * \brief Close a running session. + * + * close() should be called before destroying the Session object so that the + * client can catch any exceptions thrown during shut down that may be + * unavoidable in the parallel computing environment. + * + * \return status of close() operation. + */ + Status close(); + + /*! + * \brief Run the current workflow to completion. + * + * The client should examine the Status object for errors and resulting workflow state. + * \return the Session's Status after the run. + */ + Status run() noexcept; + + /*! + * \brief Check if session is running. + * + * A Session will be "open" from the point of launch until "close" is + * called. If this is not true, either an error has occurred or there is + * a bug in the implementation. + * + * \return `true` if the session is running, else `false` + */ + bool isOpen() const noexcept; + + /*! \cond internal + * \brief Get a non-owning handle to the implementation object. + * + * Get a raw pointer to the implementation object. The pointer is valid only during the lifetime of the Session, + * so retain a shared pointer to this Session object or only hold the pointer for the duration of a code block + * guaranteed to exist entirely within the lifetime of a Session object. + * + * \return opaque pointer used by gmxapi implementation and extension code. + */ + SessionImpl* getRaw() const noexcept; + //! \endcond + +private: + //! \brief opaque pointer to implementation + std::unique_ptr impl_; }; /*! @@ -190,8 +190,7 @@ class Session * \todo Update for new scheme in which all restraints are managed by a single Restraint module. * \todo Figure out what this object should return to provide more utility and rigorous error checking. */ -Status addSessionRestraint(Session * session, - std::shared_ptr restraint); +Status addSessionRestraint(Session* session, std::shared_ptr restraint); /*! * \brief Launch a workflow in the provided execution context. @@ -207,9 +206,9 @@ Status addSessionRestraint(Session * session, * for details. * \ingroup gmxapi */ -std::shared_ptr launchSession(Context* context, const Workflow &work) noexcept; +std::shared_ptr launchSession(Context* context, const Workflow& work) noexcept; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GROMACS_SESSION_H +#endif // GROMACS_SESSION_H diff --git a/src/api/cpp/include/gmxapi/session/resources.h b/src/api/cpp/include/gmxapi/session/resources.h index 8f2651fb5f..af90c87c3a 100644 --- a/src/api/cpp/include/gmxapi/session/resources.h +++ b/src/api/cpp/include/gmxapi/session/resources.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,6 +55,6 @@ namespace gmxapi */ class SessionResources; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_SESSION_RESOURCES_H +#endif // GMXAPI_SESSION_RESOURCES_H diff --git a/src/api/cpp/include/gmxapi/status.h b/src/api/cpp/include/gmxapi/status.h index c6df7c8ff0..ffc12a3f80 100644 --- a/src/api/cpp/include/gmxapi/status.h +++ b/src/api/cpp/include/gmxapi/status.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,85 +63,86 @@ namespace gmxapi */ class Status final { - public: - /*! - * \brief Status is "unsuccessful" until set otherwise. - * - * \internal - * Default constructor can be used for convenience when preparing the - * return value for an operation that should be assumed unsuccessful - * until proven otherwise. - */ - Status(); - /*! - * \brief Can be copy-initialized - * - * \param status - */ - Status(const Status &status); - /*! - * \brief Can be moved. - */ - Status(Status &&) noexcept; - /*! - * \brief Can be copy-assigned. - * - * \param status - * \return reference to lhs. - */ - Status &operator=(const Status &status); - /*! - * \brief Transfer ownership by move assignment. - * - * \param status - * \return reference to lhs - */ - Status &operator=(Status &&status) noexcept; - /*! - * \brief Set success status from boolean. - * - * \param success true to indicate successful operation. - * \return reference to lhs - */ - Status &operator=(bool success); +public: + /*! + * \brief Status is "unsuccessful" until set otherwise. + * + * \internal + * Default constructor can be used for convenience when preparing the + * return value for an operation that should be assumed unsuccessful + * until proven otherwise. + */ + Status(); + /*! + * \brief Can be copy-initialized + * + * \param status + */ + Status(const Status& status); + /*! + * \brief Can be moved. + */ + Status(Status&& /*unused*/) noexcept; + /*! + * \brief Can be copy-assigned. + * + * \param status + * \return reference to lhs. + */ + Status& operator=(const Status& status); + /*! + * \brief Transfer ownership by move assignment. + * + * \param status + * \return reference to lhs + */ + Status& operator=(Status&& status) noexcept; + /*! + * \brief Set success status from boolean. + * + * \param success true to indicate successful operation. + * \return reference to lhs + */ + Status& operator=(bool success); - /*! - * \brief Initialize with success set true or false. - * - * \param success - */ - explicit Status(bool success); + /*! + * \brief Initialize with success set true or false. + * + * \param success + */ + explicit Status(bool success); - /*! - * \brief Clean up resources. - * - * Note non-virtual destructor. This class is not heritable. - */ - ~Status(); + /*! + * \brief Clean up resources. + * + * Note non-virtual destructor. This class is not heritable. + */ + ~Status(); - /*! - * \brief Check success status. - * - * Forces evaluation of any pending computation. The operation that - * returned the Status object is guaranteed to complete, successfully - * or unsuccessfully, before this function returns. - * - * \return true if the operation described was successful. - * - * \internal - * Unsuccessful operations should have more useful information associated - * than just a boolean. Future versions should behave more like a - * `gmx::future>`, but this functionality is not yet - * available. - */ - bool success() const; - private: - //! \cond - class Impl; - std::unique_ptr impl_; - //! \endcond + /*! + * \brief Check success status. + * + * Forces evaluation of any pending computation. The operation that + * returned the Status object is guaranteed to complete, successfully + * or unsuccessfully, before this function returns. + * + * \return true if the operation described was successful. + * + * \internal + * Unsuccessful operations should have more useful information associated + * than just a boolean. Future versions should behave more like a + * `gmx::future>`, but this functionality is not yet + * available. + */ + bool success() const; + +private: + //! \cond + class Impl; + std::unique_ptr impl_; + //! \endcond }; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_STATUS_H +#endif // GMXAPI_STATUS_H diff --git a/src/api/cpp/include/gmxapi/system.h b/src/api/cpp/include/gmxapi/system.h index c2ae2890ef..eac1f6ca96 100644 --- a/src/api/cpp/include/gmxapi/system.h +++ b/src/api/cpp/include/gmxapi/system.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -80,101 +80,101 @@ class Session; // full specification in gmxapi/session.h */ class System final { - public: - /*! \brief Private implementation class. - * - * System::Impl does not have a public interface and is only exposed in opaque pointers. - */ - class Impl; +public: + /*! \brief Private implementation class. + * + * System::Impl does not have a public interface and is only exposed in opaque pointers. + */ + class Impl; - /*! \brief No copy. - * - * The semantics of copying a System are ambiguous, so disallow implicit - * copy. - * \{ - * \internal - * Some sort of prototype or clone idiom could be useful, but - * needs to explicitly identify any expensive operations. - */ - System(const System &) = delete; - System &operator=(const System &) = delete; - /*! \} */ + /*! \brief No copy. + * + * The semantics of copying a System are ambiguous, so disallow implicit + * copy. + * \{ + * \internal + * Some sort of prototype or clone idiom could be useful, but + * needs to explicitly identify any expensive operations. + */ + System(const System&) = delete; + System& operator=(const System&) = delete; + /*! \} */ - /*! \brief Allow move. - * - * \{ - */ - System(System && /*unused*/) noexcept; - System &operator=(System && /*unused*/) noexcept; - /*! \} */ + /*! \brief Allow move. + * + * \{ + */ + System(System&& /*unused*/) noexcept; + System& operator=(System&& /*unused*/) noexcept; + /*! \} */ - /*! - * \brief Create by taking ownership of an implementation object. - * - * \param implementation - */ - explicit System(std::unique_ptr implementation); + /*! + * \brief Create by taking ownership of an implementation object. + * + * \param implementation + */ + explicit System(std::unique_ptr implementation); - /*! \cond internal - * Destructor defined later to allow unique_ptr members of partially-defined types. - */ - ~System(); - /*! \endcond */ + /*! \cond internal + * Destructor defined later to allow unique_ptr members of partially-defined types. + */ + ~System(); + /*! \endcond */ - /*! - * \brief Configure the computing environment for the specified workflow. - * - * \return Ownership of a ready-to-run workflow or nullptr if there were errors. - * - * If errors occur, they will be stored in the context object. If run without - * an argument, launch() uses the current context of the System object. If a - * context argument is given, the system and its configured workflow are - * translated to the provided context and launched. - * - * \param context (optional) execution context in which to launch. - * - * \note The Session object does not "own" the Context, but must be able - * to extend the lifetime of the Context in which it is running. - * - * \todo Policy: does System then track the (potentially remote) context or should - * it be considered to have "forked", and the new session object retrieved from - * the session handle if needed? - * - * \cond internal - * # Protocol - * - * The current implementation of System::launch() performs the following actions. - * - * When launch() is called, a new gmxapi::Session is created by passing a - * gmxapi::Workflow to context->launch(). - * The Workflow basically just contains the TPR filename. - * 1. A new Mdrunner is created from the information in the gmxapi::Workflow - * 2. A new Session is created using the ContextImpl and the runner - * - * Then, for each module available through getSpec()->getModules(), - * the session and module are passed to gmxapi::setSessionRestraint(). - * 1. A gmx::IRestraintPotential is retrieved from the module. - * 2. A unique, named SessionResources is created for the module and attached to the SessionImpl. - * 1. The module is added as a signaller to the session SignalManager - * with getSignalManager()->addSignaller(module->name()) - * 2. The SessionResources is passed to IRestraintPotential::bindSession(). - * Currently, the only thing the restraint could do at this point is to - * save a copy of the pointer and later pass it to gmxapi::getMdrunnerSignal(). - * 3. The restraint is passed to gmx::Mdrunner::addPullPotential(), - * which adds the restraint to the global gmx::restraint::Manager, - * which then needs to be `clear()`ed after the runner completes. - * - * Shared ownership of the Session is returned to the caller of launch(). - * - * \endcond - */ - std::shared_ptr launch(const std::shared_ptr &context); + /*! + * \brief Configure the computing environment for the specified workflow. + * + * \return Ownership of a ready-to-run workflow or nullptr if there were errors. + * + * If errors occur, they will be stored in the context object. If run without + * an argument, launch() uses the current context of the System object. If a + * context argument is given, the system and its configured workflow are + * translated to the provided context and launched. + * + * \param context (optional) execution context in which to launch. + * + * \note The Session object does not "own" the Context, but must be able + * to extend the lifetime of the Context in which it is running. + * + * \todo Policy: does System then track the (potentially remote) context or should + * it be considered to have "forked", and the new session object retrieved from + * the session handle if needed? + * + * \cond internal + * # Protocol + * + * The current implementation of System::launch() performs the following actions. + * + * When launch() is called, a new gmxapi::Session is created by passing a + * gmxapi::Workflow to context->launch(). + * The Workflow basically just contains the TPR filename. + * 1. A new Mdrunner is created from the information in the gmxapi::Workflow + * 2. A new Session is created using the ContextImpl and the runner + * + * Then, for each module available through getSpec()->getModules(), + * the session and module are passed to gmxapi::setSessionRestraint(). + * 1. A gmx::IRestraintPotential is retrieved from the module. + * 2. A unique, named SessionResources is created for the module and attached to the SessionImpl. + * 1. The module is added as a signaller to the session SignalManager + * with getSignalManager()->addSignaller(module->name()) + * 2. The SessionResources is passed to IRestraintPotential::bindSession(). + * Currently, the only thing the restraint could do at this point is to + * save a copy of the pointer and later pass it to gmxapi::getMdrunnerSignal(). + * 3. The restraint is passed to gmx::Mdrunner::addPullPotential(), + * which adds the restraint to the global gmx::restraint::Manager, + * which then needs to be `clear()`ed after the runner completes. + * + * Shared ownership of the Session is returned to the caller of launch(). + * + * \endcond + */ + std::shared_ptr launch(const std::shared_ptr& context); - private: - /*! - * \brief Opaque pointer to implementation. - */ - std::unique_ptr impl_; +private: + /*! + * \brief Opaque pointer to implementation. + */ + std::unique_ptr impl_; }; @@ -189,8 +189,8 @@ class System final * \returns gmxapi::System object with the specified workflow. * \ingroup gmxapi */ -System fromTprFile(const std::string &filename); +System fromTprFile(const std::string& filename); -} // end namespace gmxapi +} // end namespace gmxapi #endif // include guard diff --git a/src/api/cpp/md.cpp b/src/api/cpp/md.cpp index 6ac41b7be2..7eb8d5d5d3 100644 --- a/src/api/cpp/md.cpp +++ b/src/api/cpp/md.cpp @@ -47,29 +47,28 @@ namespace gmxapi { -const char* MDHolder::api_name = MDHolder_Name; +const char* MDHolder::api_name = MDHolder_Name; //! \cond internal class MDWorkSpec::Impl { - public: - /*! - * \brief container of objects glued together by the client. - * - * Note that the client can't be trusted to keep alive or destroy these, - * and we do not yet have sufficient abstraction layers to allow the - * client to interact asynchronously with code supporting MD simulation - * through truly separate handles to the underlying objects, so ownership - * is amongst the collaborators of the gmxapi::MDModule. - * \todo Pass factory function objects instead of shared handles. - * \todo Consolidate MDWorkSpec and gmxapi::Workflow under new Context umbrella. - */ - std::vector< std::shared_ptr > modules; +public: + /*! + * \brief container of objects glued together by the client. + * + * Note that the client can't be trusted to keep alive or destroy these, + * and we do not yet have sufficient abstraction layers to allow the + * client to interact asynchronously with code supporting MD simulation + * through truly separate handles to the underlying objects, so ownership + * is amongst the collaborators of the gmxapi::MDModule. + * \todo Pass factory function objects instead of shared handles. + * \todo Consolidate MDWorkSpec and gmxapi::Workflow under new Context umbrella. + */ + std::vector> modules; }; //! \endcond -MDWorkSpec::MDWorkSpec() : - impl_ {std::make_unique()} +MDWorkSpec::MDWorkSpec() : impl_{ std::make_unique() } { GMX_ASSERT(impl_, "Expected non-null implementation object."); } @@ -80,7 +79,7 @@ void MDWorkSpec::addModule(std::shared_ptr module) impl_->modules.emplace_back(std::move(module)); } -std::vector < std::shared_ptr < gmxapi::MDModule>> &MDWorkSpec::getModules() +std::vector>& MDWorkSpec::getModules() { GMX_ASSERT(impl_, "Expected non-null implementation object."); return impl_->modules; @@ -102,29 +101,25 @@ std::shared_ptr MDHolder::getSpec() const return impl_->spec_; } -MDHolder::MDHolder() : - MDHolder {std::make_shared()} +MDHolder::MDHolder() : MDHolder{ std::make_shared() } { GMX_ASSERT(impl_, "Expected non-null implementation object."); GMX_ASSERT(impl_->spec_, "Expected non-null work specification."); } MDHolder::MDHolder(std::shared_ptr spec) : - name_(), impl_(std::make_shared(std::move(spec))) { GMX_ASSERT(impl_, "Expected non-null implementation object."); GMX_ASSERT(impl_->spec_, "Expected non-null work specification."); } -MDHolder::Impl::Impl(std::shared_ptr &&spec) : - spec_ {spec} +MDHolder::Impl::Impl(std::shared_ptr&& spec) : spec_{ spec } { GMX_ASSERT(spec_, "Expected non-null work specification."); } -MDHolder::MDHolder(std::string name) : - MDHolder {} +MDHolder::MDHolder(std::string name) : MDHolder{} { name_ = std::move(name); GMX_ASSERT(impl_, "Expected non-null implementation object."); @@ -137,4 +132,4 @@ std::string MDHolder::name() const } -} //end namespace gmxapi +} // end namespace gmxapi diff --git a/src/api/cpp/md_impl.h b/src/api/cpp/md_impl.h index 8eeda00d9e..26a91a00fd 100644 --- a/src/api/cpp/md_impl.h +++ b/src/api/cpp/md_impl.h @@ -57,20 +57,20 @@ class MDWorkSpec; */ class MDHolder::Impl { - public: - /*! - * \brief Construct by capturing a messaging object. - * - * \param spec operations specified for a workflow and the means to instantiate them. - */ - explicit Impl(std::shared_ptr &&spec); +public: + /*! + * \brief Construct by capturing a messaging object. + * + * \param spec operations specified for a workflow and the means to instantiate them. + */ + explicit Impl(std::shared_ptr&& spec); - /*! - * \brief Shared ownership of the gmxapi object used for higher level message passing. - */ - std::shared_ptr spec_ {nullptr}; + /*! + * \brief Shared ownership of the gmxapi object used for higher level message passing. + */ + std::shared_ptr spec_{ nullptr }; }; -} // namespace gmxapi +} // namespace gmxapi #endif // header guard diff --git a/src/api/cpp/mdsignals.cpp b/src/api/cpp/mdsignals.cpp index 17718780c2..3be314b2b7 100644 --- a/src/api/cpp/mdsignals.cpp +++ b/src/api/cpp/mdsignals.cpp @@ -59,13 +59,10 @@ namespace gmxapi { //! \cond -Signal::Signal(Signal &&) noexcept = default; -Signal &Signal::operator=(Signal &&) noexcept = default; +Signal::Signal(Signal&&) noexcept = default; +Signal& Signal::operator=(Signal&&) noexcept = default; -Signal::Signal(std::unique_ptr impl) : - impl_ {std::move(impl)} -{ -} +Signal::Signal(std::unique_ptr impl) : impl_{ std::move(impl) } {} Signal::~Signal() = default; @@ -75,7 +72,7 @@ void Signal::operator()() } //! \endcond -void SignalManager::addSignaller(std::string name) +void SignalManager::addSignaller(const std::string& name) { called_[name].store(false); } @@ -104,54 +101,51 @@ void SignalManager::addSignaller(std::string name) */ class SignalManager::LogicalAND : public Signal::SignalImpl { - public: - /*! - * \brief Create short-lived signal issuer implementation. - * - * \param manager - * \param name - * - * Caller is responsible for ensuring that the object pointed to by - * manager remains valid for the life time of a LogicalAND instance. - */ - LogicalAND(SignalManager* manager, std::string name) : - name_(std::move(name)), - manager_(manager) - {} - - //! \cond - ~LogicalAND() override = default; - //! \endcond - - /*! - * \brief Sets the stop condition when the last issuer issues. - * - * Once all participating signal issuers have called for a stop signal, - * the stop condition state is updated to stopAtNextNSStep. - */ - void call() override +public: + /*! + * \brief Create short-lived signal issuer implementation. + * + * \param manager + * \param name + * + * Caller is responsible for ensuring that the object pointed to by + * manager remains valid for the life time of a LogicalAND instance. + */ + LogicalAND(SignalManager* manager, std::string name) : name_(std::move(name)), manager_(manager) + { + } + + //! \cond + ~LogicalAND() override = default; + //! \endcond + + /*! + * \brief Sets the stop condition when the last issuer issues. + * + * Once all participating signal issuers have called for a stop signal, + * the stop condition state is updated to stopAtNextNSStep. + */ + void call() override + { + auto& callCounter = manager_->called_.at(name_); + callCounter.store(true); + using pairType = typename decltype(manager_->called_)::value_type; + if (std::all_of(manager_->called_.cbegin(), manager_->called_.cend(), + [](const pairType& p) { return p.second.load(); })) { - auto &callCounter = manager_->called_.at(name_); - callCounter.store(true); - using pairType = typename decltype(manager_->called_) ::value_type; - if (std::all_of(manager_->called_.cbegin(), - manager_->called_.cend(), - [](const pairType &p){ return p.second.load(); })) - { - *manager_->state_ = gmx::StopSignal::stopAtNextNSStep; - } + *manager_->state_ = gmx::StopSignal::stopAtNextNSStep; } + } - private: - //! Named signal issuer for the current operation. - const std::string name_; +private: + //! Named signal issuer for the current operation. + const std::string name_; - //! The manager that generated this function object. - SignalManager * manager_; + //! The manager that generated this function object. + SignalManager* manager_; }; -Signal SignalManager::getSignal(std::string name, - md::signals signal) +Signal SignalManager::getSignal(const std::string& name, md::signals signal) { if (called_.find(name) == called_.end()) { @@ -164,13 +158,12 @@ Signal SignalManager::getSignal(std::string name, throw gmxapi::NotImplementedError("This signaller only handles stop signals."); } - auto signalImpl = std::make_unique(this, name); - auto functor = Signal(std::move(signalImpl)); + auto signalImpl = std::make_unique(this, name); + auto functor = Signal(std::move(signalImpl)); return functor; } -Signal getMdrunnerSignal(SessionResources *resources, - md::signals signal) +Signal getMdrunnerSignal(SessionResources* resources, md::signals signal) { // while there is only one choice... if (signal != md::signals::STOP) @@ -180,7 +173,8 @@ Signal getMdrunnerSignal(SessionResources *resources, if (resources == nullptr) { - throw gmxapi::UsageError("Caller must provide a valid SessionResources to getMdrunnerSignal."); + throw gmxapi::UsageError( + "Caller must provide a valid SessionResources to getMdrunnerSignal."); } auto signaller = resources->getMdrunnerSignal(signal); diff --git a/src/api/cpp/mdsignals.h b/src/api/cpp/mdsignals.h index f5717a3f10..a2fee9c456 100644 --- a/src/api/cpp/mdsignals.h +++ b/src/api/cpp/mdsignals.h @@ -68,12 +68,12 @@ namespace gmxapi */ class Signal::SignalImpl { - public: - //! Required functor behavior. - virtual void call() = 0; +public: + //! Required functor behavior. + virtual void call() = 0; - //! May be subclassed. - virtual ~SignalImpl() = default; + //! May be subclassed. + virtual ~SignalImpl() = default; }; /*! @@ -82,16 +82,14 @@ class Signal::SignalImpl * Manages signals for a single gmx::Mdrunner. Currently only supports a stop signal that * is required to be issued by all registered possible issuers before the signal is sent to * the associated runner. This is not what we want in the long run. - * \todo This class should handle signal inputs to operations that take signals as input (like Mdrunner) - * and - * \todo should allow multiple subscribers. - * For additional signal processing, such as boolean operations, - * additional operations should be inserted in a chain. + * \todo This class should handle signal inputs to operations that take signals as input (like + * Mdrunner) and \todo should allow multiple subscribers. For additional signal processing, such as + * boolean operations, additional operations should be inserted in a chain. * * SignalManager objects are created during Session launch and are owned exclusively by session * implementation objects. If Session::isOpen() is true, the SignalManager should still be valid, - * but the intended use case is that SignalManager handles should be retrieved immediately before use - * by implementation code within the library with SessionImpl::getSignalManager(). + * but the intended use case is that SignalManager handles should be retrieved immediately before + * use by implementation code within the library with SessionImpl::getSignalManager(). * * A SignalManager should be created for each signal consumer (each gmx::Mdrunner) in a Session. * This occurs in the SessionImpl::create() function. @@ -100,71 +98,69 @@ class Signal::SignalImpl */ class SignalManager { - public: - /*! - * \brief Set up a manager to mediate access to an upcoming MD stop handler. - * - * \param mdStopHandlerBuilder access to a builder that can be used during construction. - */ - explicit SignalManager(gmx::StopHandlerBuilder* mdStopHandlerBuilder); - - //! \cond - ~SignalManager(); - //! \endcond - - /*! - * \brief Add a name to the list of operations that will be using this signal. - */ - void addSignaller(std::string name); - - /*! - * \brief Allow a registered signaller to retrieve a functor. - * - * \param name Registered signal issuer. - * \param signal type of signal the client would like to issue. - * \return Generic Signal object. - * - * \throws gmxapi::ProtocolError if named signaller was not previously registered. - */ - Signal getSignal(std::string name, - md::signals signal); - - /*! - * \brief Signal operation that issues only when all sources have issued. - * - * Implemented as a member class that can access SignalManager's private members. - * \todo Decouple logical operations from SignalManager class definition. - */ - class LogicalAND; - - private: - //! Non-owning handle to the associated runner. - gmx::Mdrunner* runner_; - - - /*! - * \brief State of the stop condition to be returned by the registered MD signaller. - * - * Ownership is shared by the function objects in the StopConditionHandler - * (owned by the simulator), which read the value, and the - * SessionImpl SignalManager, which mediates write access. - * - * The signal state is either gmx::StopSignal::noSignal or gmx::StopSignal::stopAtNextNSStep, - * so atomicity is not important, and we share the state across - * threads in a tMPI simulation. - */ - std::shared_ptr state_; - - /*! - * \brief Track whether the signal has been issued by each registrant. - * - * \todo This is an implementation detail of LogicalAND that should not be here. - */ - std::map called_; +public: + /*! + * \brief Set up a manager to mediate access to an upcoming MD stop handler. + * + * \param mdStopHandlerBuilder access to a builder that can be used during construction. + */ + explicit SignalManager(gmx::StopHandlerBuilder* mdStopHandlerBuilder); + + //! \cond + ~SignalManager(); + //! \endcond + + /*! + * \brief Add a name to the list of operations that will be using this signal. + */ + void addSignaller(const std::string& name); + + /*! + * \brief Allow a registered signaller to retrieve a functor. + * + * \param name Registered signal issuer. + * \param signal type of signal the client would like to issue. + * \return Generic Signal object. + * + * \throws gmxapi::ProtocolError if named signaller was not previously registered. + */ + Signal getSignal(const std::string& name, md::signals signal); + + /*! + * \brief Signal operation that issues only when all sources have issued. + * + * Implemented as a member class that can access SignalManager's private members. + * \todo Decouple logical operations from SignalManager class definition. + */ + class LogicalAND; + +private: + //! Non-owning handle to the associated runner. + gmx::Mdrunner* runner_; + + + /*! + * \brief State of the stop condition to be returned by the registered MD signaller. + * + * Ownership is shared by the function objects in the StopConditionHandler + * (owned by the simulator), which read the value, and the + * SessionImpl SignalManager, which mediates write access. + * + * The signal state is either gmx::StopSignal::noSignal or gmx::StopSignal::stopAtNextNSStep, + * so atomicity is not important, and we share the state across + * threads in a tMPI simulation. + */ + std::shared_ptr state_; + + /*! + * \brief Track whether the signal has been issued by each registrant. + * + * \todo This is an implementation detail of LogicalAND that should not be here. + */ + std::map called_; }; +} // end namespace gmxapi -} //end namespace gmxapi - -#endif //GMXAPI_MDSIGNALS_IMPL_H +#endif // GMXAPI_MDSIGNALS_IMPL_H diff --git a/src/api/cpp/session.cpp b/src/api/cpp/session.cpp index a2cae740cb..567c064cdb 100644 --- a/src/api/cpp/session.cpp +++ b/src/api/cpp/session.cpp @@ -79,38 +79,39 @@ namespace gmxapi */ class MpiContextManager { - public: - MpiContextManager() - { - gmx::init(nullptr, nullptr); - GMX_RELEASE_ASSERT(!GMX_LIB_MPI || gmx_mpi_initialized(), "MPI should be initialized before reaching this point."); - }; +public: + MpiContextManager() + { + gmx::init(nullptr, nullptr); + GMX_RELEASE_ASSERT(!GMX_LIB_MPI || gmx_mpi_initialized(), + "MPI should be initialized before reaching this point."); + }; - ~MpiContextManager() - { - // This is always safe to call. It is a no-op if - // thread-MPI, and if the constructor completed then the - // MPI library is initialized with reference counting. - gmx::finalize(); - } + ~MpiContextManager() + { + // This is always safe to call. It is a no-op if + // thread-MPI, and if the constructor completed then the + // MPI library is initialized with reference counting. + gmx::finalize(); + } - /*! - * \brief Exclusive ownership of a scoped context means copying is impossible. - * - * \{ - */ - MpiContextManager(const MpiContextManager &) = delete; - MpiContextManager &operator=(const MpiContextManager &) = delete; - //! \} - - /*! - * \brief Move semantics are trivial. - * - * \{ - */ - MpiContextManager(MpiContextManager &&) noexcept = default; - MpiContextManager &operator=(MpiContextManager &&) noexcept = default; - //! \} + /*! + * \brief Exclusive ownership of a scoped context means copying is impossible. + * + * \{ + */ + MpiContextManager(const MpiContextManager&) = delete; + MpiContextManager& operator=(const MpiContextManager&) = delete; + //! \} + + /*! + * \brief Move semantics are trivial. + * + * \{ + */ + MpiContextManager(MpiContextManager&&) noexcept = default; + MpiContextManager& operator=(MpiContextManager&&) noexcept = default; + //! \} }; SignalManager::SignalManager(gmx::StopHandlerBuilder* stopHandlerBuilder) : @@ -128,9 +129,7 @@ SignalManager::SignalManager(gmx::StopHandlerBuilder* stopHandlerBuilder) : * step and not require any synchronization. */ auto currentState = state_; - auto stopSignalIssuer = [currentState](){ - return *currentState; - }; + auto stopSignalIssuer = [currentState]() { return *currentState; }; stopHandlerBuilder->registerStopCondition(stopSignalIssuer); } @@ -173,23 +172,21 @@ Status SessionImpl::run() noexcept return successful; } -std::unique_ptr SessionImpl::create(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr logFilehandle) +std::unique_ptr SessionImpl::create(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr logFilehandle) { // We should be able to get a communicator (or subcommunicator) through the // Context. - return std::make_unique(std::move(context), - std::move(runnerBuilder), - std::move(simulationContext), - std::move(logFilehandle)); + return std::make_unique(std::move(context), std::move(runnerBuilder), + std::move(simulationContext), std::move(logFilehandle)); } -SessionImpl::SessionImpl(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr fplog) : +SessionImpl::SessionImpl(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr fplog) : context_(std::move(context)), mpiContextManager_(std::make_unique()), simulationContext_(std::move(simulationContext)), @@ -201,7 +198,7 @@ SessionImpl::SessionImpl(std::shared_ptr context, // \todo Session objects can have logic specialized for the runtime environment. auto stopHandlerBuilder = std::make_unique(); - signalManager_ = std::make_unique(stopHandlerBuilder.get()); + signalManager_ = std::make_unique(stopHandlerBuilder.get()); GMX_ASSERT(signalManager_, "SessionImpl invariant includes a valid SignalManager."); runnerBuilder.addStopHandlerBuilder(std::move(stopHandlerBuilder)); @@ -213,15 +210,13 @@ SessionImpl::SessionImpl(std::shared_ptr context, gmx_reset_stop_condition(); } -std::shared_ptr createSession(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr logFilehandle) +std::shared_ptr createSession(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr logFilehandle) { - auto newSession = SessionImpl::create(std::move(context), - std::move(runnerBuilder), - std::move(simulationContext), - std::move(logFilehandle)); + auto newSession = SessionImpl::create(std::move(context), std::move(runnerBuilder), + std::move(simulationContext), std::move(logFilehandle)); auto launchedSession = std::make_shared(std::move(newSession)); return launchedSession; } @@ -229,13 +224,11 @@ std::shared_ptr createSession(std::shared_ptr context, Status SessionImpl::addRestraint(std::shared_ptr module) { GMX_ASSERT(runner_, "SessionImpl invariant implies valid Mdrunner handle."); - Status status { - false - }; + Status status{ false }; if (module != nullptr) { - const auto &name = module->name(); + const auto& name = module->name(); if (restraints_.find(name) == restraints_.end()) { auto restraint = module->getRestraint(); @@ -259,7 +252,7 @@ Status SessionImpl::addRestraint(std::shared_ptr module) } -SignalManager *SessionImpl::getSignalManager() +SignalManager* SessionImpl::getSignalManager() { SignalManager* ptr = nullptr; if (isOpen()) @@ -269,9 +262,9 @@ SignalManager *SessionImpl::getSignalManager() return ptr; } -gmx::Mdrunner *SessionImpl::getRunner() +gmx::Mdrunner* SessionImpl::getRunner() { - gmx::Mdrunner * runner = nullptr; + gmx::Mdrunner* runner = nullptr; if (runner_) { runner = runner_.get(); @@ -279,14 +272,14 @@ gmx::Mdrunner *SessionImpl::getRunner() return runner; } -gmxapi::SessionResources *SessionImpl::getResources(const std::string &name) const noexcept +gmxapi::SessionResources* SessionImpl::getResources(const std::string& name) const noexcept { - gmxapi::SessionResources * resources = nullptr; + gmxapi::SessionResources* resources = nullptr; try { resources = resources_.at(name).get(); } - catch (const std::out_of_range &e) + catch (const std::out_of_range& e) { // named operation does not have any resources registered. } @@ -294,13 +287,13 @@ gmxapi::SessionResources *SessionImpl::getResources(const std::string &name) con return resources; } -gmxapi::SessionResources *SessionImpl::createResources(std::shared_ptr module) noexcept +gmxapi::SessionResources* SessionImpl::createResources(std::shared_ptr module) noexcept { // check if resources already exist for this module // If not, create resources and return handle. // Return nullptr for any failure. - gmxapi::SessionResources * resources = nullptr; - const auto &name = module->name(); + gmxapi::SessionResources* resources = nullptr; + const auto& name = module->name(); if (resources_.find(name) == resources_.end()) { auto resourcesInstance = std::make_unique(this, name); @@ -317,8 +310,7 @@ gmxapi::SessionResources *SessionImpl::createResources(std::shared_ptrbindSession(resources); } } - } - ; + }; return resources; } @@ -362,7 +354,7 @@ Session::~Session() { impl_->close(); } - catch (const std::exception &) + catch (const std::exception&) { // \todo find some exception-safe things to do with this via the Context interface. } @@ -376,8 +368,7 @@ bool Session::isOpen() const noexcept return result; } -Status addSessionRestraint(Session * session, - std::shared_ptr restraint) +Status addSessionRestraint(Session* session, std::shared_ptr restraint) { auto status = gmxapi::Status(false); @@ -387,7 +378,8 @@ Status addSessionRestraint(Session * session, // so the public API does not need to offer raw pointers. auto sessionImpl = session->getRaw(); - GMX_RELEASE_ASSERT(sessionImpl, "Session invariant implies valid implementation object handle."); + GMX_RELEASE_ASSERT(sessionImpl, + "Session invariant implies valid implementation object handle."); // GMX_ASSERT alone is not strong enough to convince linters not to warn of possible nullptr. if (sessionImpl) { @@ -398,13 +390,13 @@ Status addSessionRestraint(Session * session, } //! \cond internal -SessionImpl *Session::getRaw() const noexcept +SessionImpl* Session::getRaw() const noexcept { return impl_.get(); } //! \endcond -std::shared_ptr launchSession(Context* context, const Workflow &work) noexcept +std::shared_ptr launchSession(Context* context, const Workflow& work) noexcept { auto session = context->launch(work); return session; @@ -412,8 +404,7 @@ std::shared_ptr launchSession(Context* context, const Workflow &work) n SessionImpl::~SessionImpl() = default; -SessionResources::SessionResources(gmxapi::SessionImpl *session, - std::string name) : +SessionResources::SessionResources(gmxapi::SessionImpl* session, std::string name) : sessionImpl_(session), name_(std::move(name)) { @@ -421,7 +412,7 @@ SessionResources::SessionResources(gmxapi::SessionImpl *session, SessionResources::~SessionResources() = default; -const std::string SessionResources::name() const +std::string SessionResources::name() const { return name_; } @@ -438,7 +429,8 @@ Signal SessionResources::getMdrunnerSignal(md::signals signal) auto signalManager = sessionImpl_->getSignalManager(); if (signalManager == nullptr) { - throw gmxapi::ProtocolError("Client requested access to a signaller that is not available."); + throw gmxapi::ProtocolError( + "Client requested access to a signaller that is not available."); } auto functor = signalManager->getSignal(name_, signal); diff --git a/src/api/cpp/session_impl.h b/src/api/cpp/session_impl.h index 764d153fcf..a223519a42 100644 --- a/src/api/cpp/session_impl.h +++ b/src/api/cpp/session_impl.h @@ -71,187 +71,187 @@ class SignalManager; // defined in mdsignals_impl.h */ class SessionImpl { - public: - //! Use create() factory to get an object. - SessionImpl() = delete; - ~SessionImpl(); +public: + //! Use create() factory to get an object. + SessionImpl() = delete; + ~SessionImpl(); - /*! - * \brief Check if the session is (still) running. - * - * When a session is launched, it should be returned in an "open" state by the launcher function. - * \return True if running, false if already closed. - */ - bool isOpen() const noexcept; + /*! + * \brief Check if the session is (still) running. + * + * When a session is launched, it should be returned in an "open" state by the launcher + * function. \return True if running, false if already closed. + */ + bool isOpen() const noexcept; - /*! - * \brief Explicitly close the session. - * - * Sessions should be explicitly `close()`ed to allow for exceptions to be caught by the client - * and because closing a session involves a more significant state change in the program than - * implied by a typical destructor. If close() can be shown to be exception safe, this protocol may be removed. - * - * \return On closing a session, a status object is transferred to the caller. - */ - Status close(); + /*! + * \brief Explicitly close the session. + * + * Sessions should be explicitly `close()`ed to allow for exceptions to be caught by the client + * and because closing a session involves a more significant state change in the program than + * implied by a typical destructor. If close() can be shown to be exception safe, this protocol may be removed. + * + * \return On closing a session, a status object is transferred to the caller. + */ + Status close(); - /*! - * \brief Run the configured workflow to completion or error. - * - * \return copy of the resulting status. - * - * \internal - * By the time we get to the run() we shouldn't have any unanticipated exceptions. - * If there are, they can be incorporated into richer future Status implementations - * or some other more appropriate output type. - */ - Status run() noexcept; + /*! + * \brief Run the configured workflow to completion or error. + * + * \return copy of the resulting status. + * + * \internal + * By the time we get to the run() we shouldn't have any unanticipated exceptions. + * If there are, they can be incorporated into richer future Status implementations + * or some other more appropriate output type. + */ + Status run() noexcept; - /*! - * \brief Create a new implementation object and transfer ownership. - * - * \param context Shared ownership of a Context implementation instance. - * \param runnerBuilder MD simulation builder to take ownership of. - * \param simulationContext Take ownership of the simulation resources. - * \param logFilehandle Take ownership of filehandle for MD logging - * - * \todo Log file management will be updated soon. - * - * \return Ownership of new Session implementation instance. - */ - static std::unique_ptr create(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr logFilehandle); + /*! + * \brief Create a new implementation object and transfer ownership. + * + * \param context Shared ownership of a Context implementation instance. + * \param runnerBuilder MD simulation builder to take ownership of. + * \param simulationContext Take ownership of the simulation resources. + * \param logFilehandle Take ownership of filehandle for MD logging + * + * \todo Log file management will be updated soon. + * + * \return Ownership of new Session implementation instance. + */ + static std::unique_ptr create(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr logFilehandle); - /*! - * \brief Add a restraint to the simulation. - * - * \param module - * \return - */ - Status addRestraint(std::shared_ptr module); + /*! + * \brief Add a restraint to the simulation. + * + * \param module + * \return + */ + Status addRestraint(std::shared_ptr module); - /*! - * \brief Get a handle to the resources for the named session operation. - * - * \param name unique name of element in workflow - * \return temporary access to the resources. - * - * If called on a non-const Session, creates the resource if it does not yet exist. - * If called on a const Session, - * returns nullptr if the resource does not exist. - */ - gmxapi::SessionResources* getResources(const std::string &name) const noexcept; + /*! + * \brief Get a handle to the resources for the named session operation. + * + * \param name unique name of element in workflow + * \return temporary access to the resources. + * + * If called on a non-const Session, creates the resource if it does not yet exist. + * If called on a const Session, + * returns nullptr if the resource does not exist. + */ + gmxapi::SessionResources* getResources(const std::string& name) const noexcept; - /*! - * \brief Create SessionResources for a module and bind the module. - * - * Adds a new managed resources object to the Session for the uniquely named module. - * Allows the module to bind to the SignalManager and to the resources object. - * - * \param module - * \return non-owning pointer to created resources or nullptr for error. - * - * If the named module is already registered, calling createResources again is considered an - * error and nullptr is returned. - */ - gmxapi::SessionResources* createResources(std::shared_ptr module) noexcept; + /*! + * \brief Create SessionResources for a module and bind the module. + * + * Adds a new managed resources object to the Session for the uniquely named module. + * Allows the module to bind to the SignalManager and to the resources object. + * + * \param module + * \return non-owning pointer to created resources or nullptr for error. + * + * If the named module is already registered, calling createResources again is considered an + * error and nullptr is returned. + */ + gmxapi::SessionResources* createResources(std::shared_ptr module) noexcept; - /*! \internal - * \brief API implementation function to retrieve the current runner. - * - * \return non-owning pointer to the current runner or nullptr if none. - */ - gmx::Mdrunner* getRunner(); + /*! \internal + * \brief API implementation function to retrieve the current runner. + * + * \return non-owning pointer to the current runner or nullptr if none. + */ + gmx::Mdrunner* getRunner(); - /*! - * \brief Get a non-owning handle to the SignalManager for the active MD runner. - * - * Calling code is responsible for ensuring that the SessionImpl is kept alive and "open" - * while the returned SignalManager handle is in use. - * - * \return non-owning pointer if runner and signal manager are active, else nullptr. - */ - SignalManager* getSignalManager(); + /*! + * \brief Get a non-owning handle to the SignalManager for the active MD runner. + * + * Calling code is responsible for ensuring that the SessionImpl is kept alive and "open" + * while the returned SignalManager handle is in use. + * + * \return non-owning pointer if runner and signal manager are active, else nullptr. + */ + SignalManager* getSignalManager(); - /*! - * \brief Constructor for use by create() - * - * \param context specific context to keep alive during session. - * \param runnerBuilder ownership of the MdrunnerBuilder object. - * \param simulationContext take ownership of a SimulationContext - * \param logFilehandle Take ownership of filehandle for MD logging - * - */ - SessionImpl(std::shared_ptr context, - gmx::MdrunnerBuilder &&runnerBuilder, - gmx::SimulationContext &&simulationContext, - gmx::LogFilePtr logFilehandle); + /*! + * \brief Constructor for use by create() + * + * \param context specific context to keep alive during session. + * \param runnerBuilder ownership of the MdrunnerBuilder object. + * \param simulationContext take ownership of a SimulationContext + * \param logFilehandle Take ownership of filehandle for MD logging + * + */ + SessionImpl(std::shared_ptr context, + gmx::MdrunnerBuilder&& runnerBuilder, + gmx::SimulationContext&& simulationContext, + gmx::LogFilePtr logFilehandle); - private: - /*! - * \brief Manage session resources for named workflow elements. - */ - std::map< std::string, std::unique_ptr > resources_; +private: + /*! + * \brief Manage session resources for named workflow elements. + */ + std::map> resources_; - /*! - * \brief Extend the life of the owning context. - * - * The session will get handles for logging, UI status messages, - * and other facilities through this interface. - */ - std::shared_ptr context_; + /*! + * \brief Extend the life of the owning context. + * + * The session will get handles for logging, UI status messages, + * and other facilities through this interface. + */ + std::shared_ptr context_; - /*! - * \brief RAII management of gmx::init() and gmx::finalize() - * - * Uses smart pointer to avoid exposing type definition. - * \todo Not fully implemented. - */ - std::unique_ptr mpiContextManager_; + /*! + * \brief RAII management of gmx::init() and gmx::finalize() + * + * Uses smart pointer to avoid exposing type definition. + * \todo Not fully implemented. + */ + std::unique_ptr mpiContextManager_; - /*! - * \brief Simulation runner object. - * - * If a simulation Session is active, points to a valid Mdrunner object. - * Null if simulation is inactive. - */ - std::unique_ptr runner_; + /*! + * \brief Simulation runner object. + * + * If a simulation Session is active, points to a valid Mdrunner object. + * Null if simulation is inactive. + */ + std::unique_ptr runner_; - /*! - * \brief An active session owns the resources it is using. - */ - gmx::SimulationContext simulationContext_; + /*! + * \brief An active session owns the resources it is using. + */ + gmx::SimulationContext simulationContext_; - /*! \brief Handle to file used for logging. - * - * \todo Move to RAII filehandle management; open and close in one place. - */ - gmx::LogFilePtr logFilePtr_; + /*! \brief Handle to file used for logging. + * + * \todo Move to RAII filehandle management; open and close in one place. + */ + gmx::LogFilePtr logFilePtr_; - /*! - * \brief Own and manager the signalling pathways for the current session. - * - * Registers a stop signal issuer with the stopConditionBuilder that is - * passed to the Mdrunner at launch. Session members issuing stop signals - * are proxied through this resource. - */ - std::unique_ptr signalManager_; + /*! + * \brief Own and manager the signalling pathways for the current session. + * + * Registers a stop signal issuer with the stopConditionBuilder that is + * passed to the Mdrunner at launch. Session members issuing stop signals + * are proxied through this resource. + */ + std::unique_ptr signalManager_; - /*! - * \brief Restraints active in this session. - * - * Client owns these restraint objects, but session has the ability to - * lock the resource to take temporary ownership in case the client - * releases its handle. - * \todo clarify and update object lifetime management - * A restraint module manager and / or a mapping of factory functions with - * which the runner can get objects at run time can encapsulate object management. - */ - std::map > restraints_; + /*! + * \brief Restraints active in this session. + * + * Client owns these restraint objects, but session has the ability to + * lock the resource to take temporary ownership in case the client + * releases its handle. + * \todo clarify and update object lifetime management + * A restraint module manager and / or a mapping of factory functions with + * which the runner can get objects at run time can encapsulate object management. + */ + std::map> restraints_; }; -} //end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_SESSION_IMPL_H +#endif // GMXAPI_SESSION_IMPL_H diff --git a/src/api/cpp/sessionresources.h b/src/api/cpp/sessionresources.h index 709ea4b551..bf3082e6a0 100644 --- a/src/api/cpp/sessionresources.h +++ b/src/api/cpp/sessionresources.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,77 +70,78 @@ namespace gmxapi */ class SessionResources final { - public: - /*! - * \brief Construct a resources object for the named operation. - * - * \param session implementation object backing these resources. - * \param name Unique name of workflow operation. - */ - SessionResources(SessionImpl* session, std::string name); - - /*! - * \brief no default constructor. - * - * \see SessionResources(SessionImpl* session, std::string name) - */ - SessionResources() = delete; - - ///@{ - /*! - * \brief Not moveable or copyable. - * - * Objects of this type should only exist in their Session container. - * If necessary, ownership can be transferred by owning through a unique_ptr handle. - */ - SessionResources(const SessionResources&) = delete; - SessionResources &operator=(const SessionResources &) = delete; - SessionResources(SessionResources &&) = delete; - SessionResources &operator=(SessionResources &&) = delete; - ///@} - - ~SessionResources(); - - /*! - * \brief Get the name of the gmxapi operation for which these resources exist. - * - * \return workflow element name - */ - const std::string name() const; - - /*! - * \brief Get a Signal instance implementing the requested MD signal. - * - * The caller is responsible for ensuring that the session is still active. - * Unfortunately, there isn't really a way to do that right now. This needs improvemnt - * in a near future version. - * - * Also, this is an external interface that should avoid throwing exceptions for ABI compatibility. - * - * \param signal currently must be gmxapi::md::signals::STOP - * \return callable object. - * - * Example: - * - * auto signal = sessionResources->getMdrunnerSignal(md::signals::STOP); - * signal(); - * - * \throws gmxapi::NotImplementedError if an implementation is not available for the requested signal. - * \throws gmxapi::ProtocolError if the Session or Signaller is not available. - */ - Signal getMdrunnerSignal(md::signals signal); - private: - /*! - * \brief pointer to the session owning these resources - */ - SessionImpl* sessionImpl_ = nullptr; - - /*! - * \brief name of the associated gmxapi operation - */ - std::string name_; +public: + /*! + * \brief Construct a resources object for the named operation. + * + * \param session implementation object backing these resources. + * \param name Unique name of workflow operation. + */ + SessionResources(SessionImpl* session, std::string name); + + /*! + * \brief no default constructor. + * + * \see SessionResources(SessionImpl* session, std::string name) + */ + SessionResources() = delete; + + ///@{ + /*! + * \brief Not moveable or copyable. + * + * Objects of this type should only exist in their Session container. + * If necessary, ownership can be transferred by owning through a unique_ptr handle. + */ + SessionResources(const SessionResources&) = delete; + SessionResources& operator=(const SessionResources&) = delete; + SessionResources(SessionResources&&) = delete; + SessionResources& operator=(SessionResources&&) = delete; + ///@} + + ~SessionResources(); + + /*! + * \brief Get the name of the gmxapi operation for which these resources exist. + * + * \return workflow element name + */ + std::string name() const; + + /*! + * \brief Get a Signal instance implementing the requested MD signal. + * + * The caller is responsible for ensuring that the session is still active. + * Unfortunately, there isn't really a way to do that right now. This needs improvemnt + * in a near future version. + * + * Also, this is an external interface that should avoid throwing exceptions for ABI compatibility. + * + * \param signal currently must be gmxapi::md::signals::STOP + * \return callable object. + * + * Example: + * + * auto signal = sessionResources->getMdrunnerSignal(md::signals::STOP); + * signal(); + * + * \throws gmxapi::NotImplementedError if an implementation is not available for the requested signal. + * \throws gmxapi::ProtocolError if the Session or Signaller is not available. + */ + Signal getMdrunnerSignal(md::signals signal); + +private: + /*! + * \brief pointer to the session owning these resources + */ + SessionImpl* sessionImpl_ = nullptr; + + /*! + * \brief name of the associated gmxapi operation + */ + std::string name_; }; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_SESSION_RESOURCES_IMPL_H +#endif // GMXAPI_SESSION_RESOURCES_IMPL_H diff --git a/src/api/cpp/status.cpp b/src/api/cpp/status.cpp index 017fda99c7..cd7858669f 100644 --- a/src/api/cpp/status.cpp +++ b/src/api/cpp/status.cpp @@ -49,66 +49,57 @@ namespace gmxapi */ class Status::Impl { - public: - /*! - * \brief Default construct as unsuccessful status. - */ - Impl() : success_ {false} - {}; - - /*! - * \brief Construct with success for true input. - * - * \param success let Boolean true == success. - */ - explicit Impl(const bool &success) : - success_ {success} - {}; - - ~Impl() = default; - - /*! - * \brief Query success status - * - * \return true if successful - */ - bool success() const - { - return success_; - }; - private: - bool success_; +public: + /*! + * \brief Default construct as unsuccessful status. + */ + Impl() : success_{ false } {}; + + /*! + * \brief Construct with success for true input. + * + * \param success let Boolean true == success. + */ + explicit Impl(const bool& success) : success_{ success } {}; + + ~Impl() = default; + + /*! + * \brief Query success status + * + * \return true if successful + */ + bool success() const { return success_; }; + +private: + bool success_; }; /// \endcond -Status::Status() : - impl_ {std::make_unique()} -{} +Status::Status() : impl_{ std::make_unique() } {} -Status::Status(const Status &status) +Status::Status(const Status& status) { impl_ = std::make_unique(status.success()); } -Status &Status::operator=(const Status &status) +Status& Status::operator=(const Status& status) { this->impl_ = std::make_unique(status.success()); return *this; } -Status &Status::operator=(Status &&) noexcept = default; +Status& Status::operator=(Status&&) noexcept = default; -Status &Status::operator=(bool success) +Status& Status::operator=(bool success) { this->impl_ = std::make_unique(success); return *this; } -Status::Status(Status &&) noexcept = default; +Status::Status(Status&&) noexcept = default; -Status::Status(bool success) : - impl_ {std::make_unique(success)} -{} +Status::Status(bool success) : impl_{ std::make_unique(success) } {} bool Status::success() const { diff --git a/src/api/cpp/system.cpp b/src/api/cpp/system.cpp index 666a14f4c4..604f5c069f 100644 --- a/src/api/cpp/system.cpp +++ b/src/api/cpp/system.cpp @@ -56,9 +56,9 @@ namespace gmxapi //! \cond System::Impl::~Impl() = default; -System::Impl::Impl(System::Impl &&) noexcept = default; +System::Impl::Impl(System::Impl&&) noexcept = default; -System::Impl &System::Impl::operator=(System::Impl &&source) noexcept +System::Impl& System::Impl::operator=(System::Impl&& source) noexcept { if (this != &source) { @@ -68,14 +68,13 @@ System::Impl &System::Impl::operator=(System::Impl &&source) noexcept } //! \endcond -std::shared_ptr System::launch(const std::shared_ptr &context) +std::shared_ptr System::launch(const std::shared_ptr& context) { return impl_->launch(context); } //! \cond -System::System(std::unique_ptr implementation) : - impl_ {std::move(implementation)} +System::System(std::unique_ptr implementation) : impl_{ std::move(implementation) } { GMX_ASSERT(impl_, "Constructor requires valid implementation object."); } @@ -83,11 +82,11 @@ System::System(std::unique_ptr implementation) : System::~System() = default; //! \endcond -System::System(System &&) noexcept = default; +System::System(System&&) noexcept = default; -System &System::operator=(System &&) noexcept = default; +System& System::operator=(System&&) noexcept = default; -System fromTprFile(const std::string &filename) +System fromTprFile(const std::string& filename) { // TODO Confirm the file is readable and parseable and note unique // identifying information for when the work spec is used in a different @@ -125,7 +124,7 @@ System::Impl::Impl(std::unique_ptr workflow) noexcept : GMX_ASSERT(spec_, "Class invariant implies non-null work specification member."); } -std::shared_ptr System::Impl::launch(const std::shared_ptr &context) +std::shared_ptr System::Impl::launch(const std::shared_ptr& context) { std::shared_ptr session = nullptr; if (context != nullptr) @@ -134,12 +133,11 @@ std::shared_ptr System::Impl::launch(const std::shared_ptr &co session = context->launch(*workflow_); GMX_ASSERT(session, "Context::launch() expected to produce non-null session."); - for (auto && module : spec_->getModules()) + for (auto&& module : spec_->getModules()) { // TODO: This should be the job of the launching code that produces the Session. // Configure the restraints in a restraint manager made available to the session launcher. - addSessionRestraint(session.get(), - module); + addSessionRestraint(session.get(), module); } } else diff --git a/src/api/cpp/system_impl.h b/src/api/cpp/system_impl.h index 109de3f638..91e2c4c19d 100644 --- a/src/api/cpp/system_impl.h +++ b/src/api/cpp/system_impl.h @@ -59,44 +59,44 @@ class Workflow; */ class System::Impl final { - public: - /*! \cond */ - ~Impl(); +public: + /*! \cond */ + ~Impl(); - Impl(Impl && /*unused*/) noexcept; - Impl &operator=(Impl &&source) noexcept; - /*! \endcond */ + Impl(Impl&& /*unused*/) noexcept; + Impl& operator=(Impl&& source) noexcept; + /*! \endcond */ - /*! - * \brief Initialize from a work description. - * - * \param workflow Simulation work to perform. - */ - explicit Impl(std::unique_ptr workflow) noexcept; + /*! + * \brief Initialize from a work description. + * + * \param workflow Simulation work to perform. + */ + explicit Impl(std::unique_ptr workflow) noexcept; - /*! - * \brief Launch the configured simulation. - * - * \param context Runtime execution context in which to run simulation. - * \return Ownership of a new simulation session. - * - * The session is returned as a shared pointer so that the Context can - * maintain a weak reference to it via std::weak_ptr. - */ - std::shared_ptr launch(const std::shared_ptr &context); + /*! + * \brief Launch the configured simulation. + * + * \param context Runtime execution context in which to run simulation. + * \return Ownership of a new simulation session. + * + * The session is returned as a shared pointer so that the Context can + * maintain a weak reference to it via std::weak_ptr. + */ + std::shared_ptr launch(const std::shared_ptr& context); - private: - //! Description of simulation work. - std::shared_ptr workflow_; +private: + //! Description of simulation work. + std::shared_ptr workflow_; - /*! - * \brief Specified simulation work. - * - * \todo merge Workflow and MDWorkSpec - */ - std::shared_ptr spec_; + /*! + * \brief Specified simulation work. + * + * \todo merge Workflow and MDWorkSpec + */ + std::shared_ptr spec_; }; -} // end namespace gmxapi +} // end namespace gmxapi #endif // header guard diff --git a/src/api/cpp/tests/restraint.cpp b/src/api/cpp/tests/restraint.cpp index 33d4d05805..a992527aef 100644 --- a/src/api/cpp/tests/restraint.cpp +++ b/src/api/cpp/tests/restraint.cpp @@ -61,39 +61,29 @@ namespace */ class NullRestraint : public gmx::IRestraintPotential { - public: - /*! \cond Implement IRestraintPotential */ - gmx::PotentialPointData evaluate(gmx::Vector /* r1 */, - gmx::Vector /* r2 */, - double /* t */ ) override - { - hasBeenCalled_ = true; - return {{0., 0., 0.}, 0.}; - } - - std::vector sites() const override - { - return {{0, 1}}; - } - - void bindSession(gmxapi::SessionResources * /* resources */) override - { - } - //! \endcond - - /*! - * \brief Check whether the restraint has been called as an IForceProvider. - * - * \return false until restraint is used in MD loop, then true. - */ - bool hasBeenCalled() const - { - return hasBeenCalled_; - } - - private: - //! State: false until after the first call to evaluate() - bool hasBeenCalled_ = false; +public: + /*! \cond Implement IRestraintPotential */ + gmx::PotentialPointData evaluate(gmx::Vector /* r1 */, gmx::Vector /* r2 */, double /* t */) override + { + hasBeenCalled_ = true; + return { { 0., 0., 0. }, 0. }; + } + + std::vector sites() const override { return { { 0, 1 } }; } + + void bindSession(gmxapi::SessionResources* /* resources */) override {} + //! \endcond + + /*! + * \brief Check whether the restraint has been called as an IForceProvider. + * + * \return false until restraint is used in MD loop, then true. + */ + bool hasBeenCalled() const { return hasBeenCalled_; } + +private: + //! State: false until after the first call to evaluate() + bool hasBeenCalled_ = false; }; /*! @@ -101,38 +91,27 @@ class NullRestraint : public gmx::IRestraintPotential */ class SimpleApiModule : public gmxapi::MDModule { - public: - /*! \cond - * Implement gmxapi::MDModule interface. - */ - SimpleApiModule() : - restraint_(std::make_shared()) - {} - - const char *name() const override - { - return "SimpleApiModule"; - } - - std::shared_ptr getRestraint() override - { - return restraint_; - } - //! \endcond - - /*! - * \brief Check whether the restraint has been called as an IForceProvider. - * - * \return false until restraint is used in MD loop, then true. - */ - bool hasBeenCalled() const - { - return restraint_->hasBeenCalled(); - } - - private: - //! restraint to provide to client or MD simulator, as well as to use to implement hasBeenCalled. - std::shared_ptr restraint_; +public: + /*! \cond + * Implement gmxapi::MDModule interface. + */ + SimpleApiModule() : restraint_(std::make_shared()) {} + + const char* name() const override { return "SimpleApiModule"; } + + std::shared_ptr getRestraint() override { return restraint_; } + //! \endcond + + /*! + * \brief Check whether the restraint has been called as an IForceProvider. + * + * \return false until restraint is used in MD loop, then true. + */ + bool hasBeenCalled() const { return restraint_->hasBeenCalled(); } + +private: + //! restraint to provide to client or MD simulator, as well as to use to implement hasBeenCalled. + std::shared_ptr restraint_; }; /*! @@ -149,9 +128,9 @@ TEST_F(GmxApiTest, ApiRunnerRestrainedMD) context->setMDArgs(args); - auto restraint = std::make_shared(); + auto restraint = std::make_shared(); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session != nullptr); EXPECT_EQ(restraint->hasBeenCalled(), false); diff --git a/src/api/cpp/tests/runner.cpp b/src/api/cpp/tests/runner.cpp index e5acb5c623..b03903b65c 100644 --- a/src/api/cpp/tests/runner.cpp +++ b/src/api/cpp/tests/runner.cpp @@ -67,7 +67,7 @@ TEST_F(GmxApiTest, RunnerBasicMD) // usual command line options settings for the tests context->setMDArgs(args); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session != nullptr); gmxapi::Status status; ASSERT_NO_THROW(status = session->run()); @@ -82,8 +82,8 @@ TEST_F(GmxApiTest, RunnerBasicMD) */ TEST_F(GmxApiTest, RunnerReinitialize) { - auto context = std::make_shared(); - gmxapi::MDArgs args = makeMdArgs(); + auto context = std::make_shared(); + gmxapi::MDArgs args = makeMdArgs(); makeTprFile(20); @@ -102,7 +102,7 @@ TEST_F(GmxApiTest, RunnerReinitialize) EXPECT_NE(gmx_get_stop_condition(), gmx_stop_cond_none); session->close(); - } // allow system and session to be destroyed. + } // allow system and session to be destroyed. { context->setMDArgs(args); @@ -126,7 +126,6 @@ TEST_F(GmxApiTest, RunnerReinitialize) session->close(); } - } /*! @@ -148,7 +147,7 @@ TEST_F(GmxApiTest, RunnerContinuedMD) gmxapi::MDArgs args = makeMdArgs(); context->setMDArgs(args); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session != nullptr); gmxapi::Status status; ASSERT_NO_THROW(status = session->run()); @@ -165,7 +164,7 @@ TEST_F(GmxApiTest, RunnerContinuedMD) args.emplace_back("20"); context->setMDArgs(args); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session != nullptr); gmxapi::Status status; ASSERT_NO_THROW(status = session->run()); diff --git a/src/api/cpp/tests/stopsignaler.cpp b/src/api/cpp/tests/stopsignaler.cpp index 873d2c7f5d..60928caa4e 100644 --- a/src/api/cpp/tests/stopsignaler.cpp +++ b/src/api/cpp/tests/stopsignaler.cpp @@ -65,85 +65,72 @@ namespace */ class StopSignalIssuer : public gmx::IRestraintPotential { - public: - /*! - * \brief Construct a restraint that does nothing. - */ - StopSignalIssuer() : - StopSignalIssuer(false) - {} - - /*! - * \brief Choose whether or not to issue stop signal when called. - * - * \param sendStopSignal If true, issue stop signal at every opportunity. - */ - explicit StopSignalIssuer(bool sendStopSignal) : - sendStopSignal_ {sendStopSignal} - {} - - /*! \cond Implement IRestraintPotential */ - gmx::PotentialPointData evaluate(gmx:: Vector /* r_site */, - gmx:: Vector /* r_ref */, - double t) override +public: + /*! + * \brief Construct a restraint that does nothing. + */ + StopSignalIssuer() : StopSignalIssuer(false) {} + + /*! + * \brief Choose whether or not to issue stop signal when called. + * + * \param sendStopSignal If true, issue stop signal at every opportunity. + */ + explicit StopSignalIssuer(bool sendStopSignal) : sendStopSignal_{ sendStopSignal } {} + + /*! \cond Implement IRestraintPotential */ + gmx::PotentialPointData evaluate(gmx::Vector /* r_site */, gmx::Vector /* r_ref */, double t) override + { + // Note that evaluate gets called once for each site, + // which is twice per time step for a pair restraint. + // The following initialization logic is not atomic, but it is sufficient. + if (!isInitialized_) { - // Note that evaluate gets called once for each site, - // which is twice per time step for a pair restraint. - // The following initialization logic is not atomic, but it is sufficient. - if (!isInitialized_) - { - // Force is also calculated for initial step. - simulationStartTime_ = t; - isInitialized_ = true; - } - lastSimulationTime_ = t; - - if (sendStopSignal_) - { - auto signalSender = gmxapi::getMdrunnerSignal(resources_, - gmxapi::md::signals::STOP); - signalSender(); - } - - return {{0., 0., 0.}, 0.}; + // Force is also calculated for initial step. + simulationStartTime_ = t; + isInitialized_ = true; } + lastSimulationTime_ = t; - std::vector sites() const override + if (sendStopSignal_) { - return {{0, 1}}; + auto signalSender = gmxapi::getMdrunnerSignal(resources_, gmxapi::md::signals::STOP); + signalSender(); } - void bindSession(gmxapi::SessionResources* resources) override - { - resources_ = resources; - } - //! \endcond - - /*! - * \brief Note simulation start time when called on the zeroeth step. - */ - double simulationStartTime_ = 0.; - - /*! - * \brief Record the simulation time at the last step active. - */ - double lastSimulationTime_ = 0.; - - private: - /*! - * \brief Whether to consider current simulation time to be the start time. - */ - bool isInitialized_ = false; - - /*! - * \brief Handle through which to get signalling resources. - */ - gmxapi::SessionResources* resources_ = nullptr; - - /*! - * \brief Whether to issue stop signal when called. - */ - bool sendStopSignal_ = false; + return { { 0., 0., 0. }, 0. }; + } + + std::vector sites() const override { return { { 0, 1 } }; } + + void bindSession(gmxapi::SessionResources* resources) override { resources_ = resources; } + //! \endcond + + /*! + * \brief Note simulation start time when called on the zeroeth step. + */ + double simulationStartTime_ = 0.; + + /*! + * \brief Record the simulation time at the last step active. + */ + double lastSimulationTime_ = 0.; + +private: + /*! + * \brief Whether to consider current simulation time to be the start time. + */ + bool isInitialized_ = false; + + /*! + * \brief Handle through which to get signalling resources. + */ + gmxapi::SessionResources* resources_ = nullptr; + + /*! + * \brief Whether to issue stop signal when called. + */ + bool sendStopSignal_ = false; }; /*! @@ -151,46 +138,38 @@ class StopSignalIssuer : public gmx::IRestraintPotential */ class SimpleSignalingClient : public gmxapi::MDModule { - public: - /*! \cond - * Implement gmxapi::MDModule interface. - */ - SimpleSignalingClient() : - restraint_(std::make_shared()) - {} - - explicit SimpleSignalingClient(bool sendStopSignal) : - restraint_(std::make_shared(sendStopSignal)) - {} - - const char *name() const override - { - return "SimpleSignalingClient"; - } +public: + /*! \cond + * Implement gmxapi::MDModule interface. + */ + SimpleSignalingClient() : restraint_(std::make_shared()) {} + + explicit SimpleSignalingClient(bool sendStopSignal) : + restraint_(std::make_shared(sendStopSignal)) + { + } - std::shared_ptr getRestraint() override - { - return restraint_; - } - //! \endcond - - /*! - * \brief Number of steps in which this restraint was active. - * - * \return Number of MD time steps. - */ - int numberOfTimesCalled() const - { - const auto timeElapsed = - restraint_->lastSimulationTime_ - restraint_->simulationStartTime_; + const char* name() const override { return "SimpleSignalingClient"; } - const auto numSteps = timeElapsed / getTestStepSize(); - return gmx::roundToInt(numSteps); - } + std::shared_ptr getRestraint() override { return restraint_; } + //! \endcond + + /*! + * \brief Number of steps in which this restraint was active. + * + * \return Number of MD time steps. + */ + int numberOfTimesCalled() const + { + const auto timeElapsed = restraint_->lastSimulationTime_ - restraint_->simulationStartTime_; + + const auto numSteps = timeElapsed / getTestStepSize(); + return gmx::roundToInt(numSteps); + } - private: - //! restraint to provide to client or MD simulator. - std::shared_ptr restraint_; +private: + //! restraint to provide to client or MD simulator. + std::shared_ptr restraint_; }; /*! @@ -204,15 +183,15 @@ TEST_F(GmxApiTest, ApiRunnerStopSignalClient) // Check assumptions about basic simulation behavior. { - gmxapi::MDArgs args = makeMdArgs(); + gmxapi::MDArgs args = makeMdArgs(); args.emplace_back("-nstlist"); args.emplace_back("1"); context->setMDArgs(args); - auto restraint = std::make_shared(); + auto restraint = std::make_shared(); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session); gmxapi::addSessionRestraint(session.get(), restraint); @@ -229,7 +208,7 @@ TEST_F(GmxApiTest, ApiRunnerStopSignalClient) // Make sure that stop signal shortens simulation. { - gmxapi::MDArgs args = makeMdArgs(); + gmxapi::MDArgs args = makeMdArgs(); args.emplace_back("-nstlist"); args.emplace_back("1"); // TODO should use api functionality to extend simulation instead @@ -239,9 +218,9 @@ TEST_F(GmxApiTest, ApiRunnerStopSignalClient) context->setMDArgs(args); const bool issueImmediateStopSignal = true; - auto restraint = std::make_shared(issueImmediateStopSignal); + auto restraint = std::make_shared(issueImmediateStopSignal); - auto session = system.launch(context); + auto session = system.launch(context); EXPECT_TRUE(session); gmxapi::addSessionRestraint(session.get(), restraint); diff --git a/src/api/cpp/tests/testingconfiguration.h b/src/api/cpp/tests/testingconfiguration.h index 70b05dfa19..f3bef5f6e0 100644 --- a/src/api/cpp/tests/testingconfiguration.h +++ b/src/api/cpp/tests/testingconfiguration.h @@ -69,66 +69,67 @@ namespace testing * * \returns Step size for tests. */ -inline real getTestStepSize() { return 0.001953125; } +inline real getTestStepSize() +{ + return 0.001953125; +} //! Provide command-line infrastructure for gmxapi tests. class GmxApiTest : public gmx::test::MdrunTestFixture { - public: - GmxApiTest() - { - } - - /* \brief - * Prepare a tpr to run the test with. - * - * Sets up the TPR to run a test of the GMXAPI with a set number of \p steps - * defined in the test. - * - * \param[in] steps Number of steps for test to run. - */ - void makeTprFile(int steps) - { - runner_.useTopGroAndNdxFromDatabase("spc_and_methane"); - runner_.useStringAsMdpFile(gmx::formatString("integrator = md\n" - "cutoff-scheme = Verlet\n" - "nsteps = %d\n" - "dt = %11.9f\n" - "nstxout = 2\n" - "nstvout = 2\n" - "nstfout = 4\n" - "nstxout-compressed = 5\n" - "tcoupl = v-rescale\n" - "tc-grps = System\n" - "tau-t = 1\n" - "ref-t = 298\n" - "compressed-x-grps = Sol\n", - steps, - getTestStepSize())); - - EXPECT_EQ(0, runner_.callGromppOnThisRank()); - } - - //! Make the md arguments to work with - std::vector makeMdArgs() const - { - std::vector mdArgs; - - mdArgs.emplace_back("-o"); - mdArgs.emplace_back(runner_.fullPrecisionTrajectoryFileName_); - mdArgs.emplace_back("-x"); - mdArgs.emplace_back(runner_.reducedPrecisionTrajectoryFileName_); - mdArgs.emplace_back("-c"); - mdArgs.emplace_back(runner_.groOutputFileName_); - mdArgs.emplace_back("-g"); - mdArgs.emplace_back(runner_.logFileName_); - mdArgs.emplace_back("-e"); - mdArgs.emplace_back(runner_.edrFileName_); - mdArgs.emplace_back("-cpo"); - mdArgs.emplace_back(runner_.cptFileName_); - - return mdArgs; - } +public: + GmxApiTest() {} + + /* \brief + * Prepare a tpr to run the test with. + * + * Sets up the TPR to run a test of the GMXAPI with a set number of \p steps + * defined in the test. + * + * \param[in] steps Number of steps for test to run. + */ + void makeTprFile(int steps) + { + runner_.useTopGroAndNdxFromDatabase("spc_and_methane"); + runner_.useStringAsMdpFile( + gmx::formatString("integrator = md\n" + "cutoff-scheme = Verlet\n" + "nsteps = %d\n" + "dt = %11.9f\n" + "nstxout = 2\n" + "nstvout = 2\n" + "nstfout = 4\n" + "nstxout-compressed = 5\n" + "tcoupl = v-rescale\n" + "tc-grps = System\n" + "tau-t = 1\n" + "ref-t = 298\n" + "compressed-x-grps = Sol\n", + steps, getTestStepSize())); + + EXPECT_EQ(0, runner_.callGromppOnThisRank()); + } + + //! Make the md arguments to work with + std::vector makeMdArgs() const + { + std::vector mdArgs; + + mdArgs.emplace_back("-o"); + mdArgs.emplace_back(runner_.fullPrecisionTrajectoryFileName_); + mdArgs.emplace_back("-x"); + mdArgs.emplace_back(runner_.reducedPrecisionTrajectoryFileName_); + mdArgs.emplace_back("-c"); + mdArgs.emplace_back(runner_.groOutputFileName_); + mdArgs.emplace_back("-g"); + mdArgs.emplace_back(runner_.logFileName_); + mdArgs.emplace_back("-e"); + mdArgs.emplace_back(runner_.edrFileName_); + mdArgs.emplace_back("-cpo"); + mdArgs.emplace_back(runner_.cptFileName_); + + return mdArgs; + } }; } // namespace testing @@ -136,4 +137,4 @@ class GmxApiTest : public gmx::test::MdrunTestFixture } // end namespace gmxapi -#endif //GROMACS_TESTINGCONFIGURATION_H +#endif // GROMACS_TESTINGCONFIGURATION_H diff --git a/src/api/cpp/tests/version.cpp b/src/api/cpp/tests/version.cpp index 34e733d84a..9ac87cb47d 100644 --- a/src/api/cpp/tests/version.cpp +++ b/src/api/cpp/tests/version.cpp @@ -64,24 +64,12 @@ const int current_patch = gmxapi::c_patchVersion; */ TEST_F(GmxApiTest, SaneVersionComparisons) { - EXPECT_TRUE(Version::isAtLeast(0, - 0, - 0)); - EXPECT_FALSE(Version::isAtLeast(SHRT_MAX, - SHRT_MAX, - SHRT_MAX)); - EXPECT_TRUE(Version::isAtLeast(current_major, - current_minor, - current_patch)); - EXPECT_FALSE(Version::isAtLeast(current_major + 1, - current_minor, - current_patch)); - EXPECT_FALSE(Version::isAtLeast(current_major, - current_minor + 1, - current_patch)); - EXPECT_FALSE(Version::isAtLeast(current_major, - current_minor, - current_patch + 1)); + EXPECT_TRUE(Version::isAtLeast(0, 0, 0)); + EXPECT_FALSE(Version::isAtLeast(SHRT_MAX, SHRT_MAX, SHRT_MAX)); + EXPECT_TRUE(Version::isAtLeast(current_major, current_minor, current_patch)); + EXPECT_FALSE(Version::isAtLeast(current_major + 1, current_minor, current_patch)); + EXPECT_FALSE(Version::isAtLeast(current_major, current_minor + 1, current_patch)); + EXPECT_FALSE(Version::isAtLeast(current_major, current_minor, current_patch + 1)); } /*! diff --git a/src/api/cpp/tpr.cpp b/src/api/cpp/tpr.cpp index 4be050b96c..1ddcd43cb8 100644 --- a/src/api/cpp/tpr.cpp +++ b/src/api/cpp/tpr.cpp @@ -69,59 +69,59 @@ namespace gmxapicompat class TprContents { - public: - explicit TprContents(const std::string &infile) : - irInstance_ {std::make_unique()}, - mtop_ {std::make_unique()}, - state_ {std::make_unique()} - { - read_tpx_state(infile.c_str(), irInstance_.get(), state_.get(), mtop_.get()); - } - ~TprContents() = default; - TprContents(TprContents &&source) noexcept = default; - TprContents &operator=(TprContents &&) noexcept = default; - - /*! - * \brief Get a reference to the input record in the TPR file. - * - * Note that this implementation allows different objects to share ownership - * of the TprFile and does not provide access restrictions to prevent multiple - * code blocks writing to the input record. This should be resolved with a - * combination of managed access controlled handles and through better - * management of the data structures in the TPR file. I.e. the t_inputrec is - * not copyable, moveable, nor default constructable (at least, to produce a - * valid record), and it does not necessarily make sense to map the library - * data structure to the file data structure (except that we don't have another - * way of constructing a complete and valid input record). - * - * \todo We can't play fast and loose with the irInstance for long... - * - * \return - */ - t_inputrec &inputRecord() const - { - assert(irInstance_); - return *irInstance_; - } +public: + explicit TprContents(const std::string& infile) : + irInstance_{ std::make_unique() }, + mtop_{ std::make_unique() }, + state_{ std::make_unique() } + { + read_tpx_state(infile.c_str(), irInstance_.get(), state_.get(), mtop_.get()); + } + ~TprContents() = default; + TprContents(TprContents&& source) noexcept = default; + TprContents& operator=(TprContents&&) noexcept = default; + + /*! + * \brief Get a reference to the input record in the TPR file. + * + * Note that this implementation allows different objects to share ownership + * of the TprFile and does not provide access restrictions to prevent multiple + * code blocks writing to the input record. This should be resolved with a + * combination of managed access controlled handles and through better + * management of the data structures in the TPR file. I.e. the t_inputrec is + * not copyable, moveable, nor default constructable (at least, to produce a + * valid record), and it does not necessarily make sense to map the library + * data structure to the file data structure (except that we don't have another + * way of constructing a complete and valid input record). + * + * \todo We can't play fast and loose with the irInstance for long... + * + * \return + */ + t_inputrec& inputRecord() const + { + assert(irInstance_); + return *irInstance_; + } - gmx_mtop_t &molecularTopology() const - { - assert(mtop_); - return *mtop_; - } + gmx_mtop_t& molecularTopology() const + { + assert(mtop_); + return *mtop_; + } - t_state &state() const - { - assert(state_); - return *state_; - } - private: - // These types are not moveable in GROMACS 2019, so we use unique_ptr as a - // moveable wrapper to let TprContents be moveable. - std::unique_ptr irInstance_; - std::unique_ptr mtop_; - std::unique_ptr state_; + t_state& state() const + { + assert(state_); + return *state_; + } +private: + // These types are not moveable in GROMACS 2019, so we use unique_ptr as a + // moveable wrapper to let TprContents be moveable. + std::unique_ptr irInstance_; + std::unique_ptr mtop_; + std::unique_ptr state_; }; // Note: This mapping is incomplete. Hopefully we can replace it before more mapping is necessary. @@ -129,100 +129,38 @@ class TprContents std::map simulationParameterTypeMap() { return { - { - "integrator", GmxapiType::STRING - }, - { - "tinit", GmxapiType::FLOAT64 - }, - { - "dt", GmxapiType::FLOAT64 - }, - { - "nsteps", GmxapiType::INT64 - }, - { - "init-step", GmxapiType::INT64 - }, - { - "simulation-part", GmxapiType::INT64 - }, - { - "comm-mode", GmxapiType::STRING - }, - { - "nstcomm", GmxapiType::INT64 - }, - { - "comm-grps", GmxapiType::NDARRAY - }, // Note: we do not have processing for this yet. - { - "bd-fric", GmxapiType::FLOAT64 - }, - { - "ld-seed", GmxapiType::INT64 - }, - { - "emtol", GmxapiType::FLOAT64 - }, - { - "emstep", GmxapiType::FLOAT64 - }, - { - "niter", GmxapiType::INT64 - }, - { - "fcstep", GmxapiType::FLOAT64 - }, - { - "nstcgsteep", GmxapiType::INT64 - }, - { - "nbfgscorr", GmxapiType::INT64 - }, - { - "rtpi", GmxapiType::FLOAT64 - }, - { - "nstxout", GmxapiType::INT64 - }, - { - "nstvout", GmxapiType::INT64 - }, - { - "nstfout", GmxapiType::INT64 - }, - { - "nstlog", GmxapiType::INT64 - }, - { - "nstcalcenergy", GmxapiType::INT64 - }, - { - "nstenergy", GmxapiType::INT64 - }, - { - "nstxout-compressed", GmxapiType::INT64 - }, - { - "compressed-x-precision", GmxapiType::FLOAT64 - }, - { - "cutoff-scheme", GmxapiType::STRING - }, - { - "nstlist", GmxapiType::INT64 - }, - { - "ns-type", GmxapiType::STRING - }, - { - "pbc", GmxapiType::STRING - }, - { - "periodic-molecules", GmxapiType::BOOL - }, -// TBD + { "integrator", GmxapiType::STRING }, + { "tinit", GmxapiType::FLOAT64 }, + { "dt", GmxapiType::FLOAT64 }, + { "nsteps", GmxapiType::INT64 }, + { "init-step", GmxapiType::INT64 }, + { "simulation-part", GmxapiType::INT64 }, + { "comm-mode", GmxapiType::STRING }, + { "nstcomm", GmxapiType::INT64 }, + { "comm-grps", GmxapiType::NDARRAY }, // Note: we do not have processing for this yet. + { "bd-fric", GmxapiType::FLOAT64 }, + { "ld-seed", GmxapiType::INT64 }, + { "emtol", GmxapiType::FLOAT64 }, + { "emstep", GmxapiType::FLOAT64 }, + { "niter", GmxapiType::INT64 }, + { "fcstep", GmxapiType::FLOAT64 }, + { "nstcgsteep", GmxapiType::INT64 }, + { "nbfgscorr", GmxapiType::INT64 }, + { "rtpi", GmxapiType::FLOAT64 }, + { "nstxout", GmxapiType::INT64 }, + { "nstvout", GmxapiType::INT64 }, + { "nstfout", GmxapiType::INT64 }, + { "nstlog", GmxapiType::INT64 }, + { "nstcalcenergy", GmxapiType::INT64 }, + { "nstenergy", GmxapiType::INT64 }, + { "nstxout-compressed", GmxapiType::INT64 }, + { "compressed-x-precision", GmxapiType::FLOAT64 }, + { "cutoff-scheme", GmxapiType::STRING }, + { "nstlist", GmxapiType::INT64 }, + { "ns-type", GmxapiType::STRING }, + { "pbc", GmxapiType::STRING }, + { "periodic-molecules", GmxapiType::BOOL }, + // TBD }; } @@ -241,56 +179,28 @@ std::map simulationParameterTypeMap() std::map boolParams() { return { - { - "periodic-molecules", &t_inputrec::bPeriodicMols - }, -// ... + { "periodic-molecules", &t_inputrec::bPeriodicMols }, + // ... }; } std::map int32Params() { return { - { - "simulation-part", &t_inputrec::simulation_part - }, - { - "nstcomm", &t_inputrec::nstcomm - }, - { - "niter", &t_inputrec::niter - }, - { - "nstcgsteep", &t_inputrec::nstcgsteep - }, - { - "nbfgscorr", &t_inputrec::nbfgscorr - }, - { - "nstxout", &t_inputrec::nstxout - }, - { - "nstvout", &t_inputrec::nstvout - }, - { - "nstfout", &t_inputrec::nstfout - }, - { - "nstlog", &t_inputrec::nstlog - }, - { - "nstcalcenergy", &t_inputrec::nstcalcenergy - }, - { - "nstenergy", &t_inputrec::nstenergy - }, - { - "nstxout-compressed", &t_inputrec::nstxout_compressed - }, - { - "nstlist", &t_inputrec::nstlist - }, -// ... + { "simulation-part", &t_inputrec::simulation_part }, + { "nstcomm", &t_inputrec::nstcomm }, + { "niter", &t_inputrec::niter }, + { "nstcgsteep", &t_inputrec::nstcgsteep }, + { "nbfgscorr", &t_inputrec::nbfgscorr }, + { "nstxout", &t_inputrec::nstxout }, + { "nstvout", &t_inputrec::nstvout }, + { "nstfout", &t_inputrec::nstfout }, + { "nstlog", &t_inputrec::nstlog }, + { "nstcalcenergy", &t_inputrec::nstcalcenergy }, + { "nstenergy", &t_inputrec::nstenergy }, + { "nstxout-compressed", &t_inputrec::nstxout_compressed }, + { "nstlist", &t_inputrec::nstlist }, + // ... }; } @@ -312,30 +222,18 @@ template<> std::map compatibleRealParams() { return { - { - "bd-fric", &t_inputrec::bd_fric - }, - { - "emtol", &t_inputrec::em_tol - }, - { - "emstep", &t_inputrec::em_stepsize - }, - { - "fcstep", &t_inputrec::fc_stepsize - }, - { - "rtpi", &t_inputrec::rtpi - }, - { - "compressed-x-precision", &t_inputrec::x_compression_precision - }, -// ... + { "bd-fric", &t_inputrec::bd_fric }, + { "emtol", &t_inputrec::em_tol }, + { "emstep", &t_inputrec::em_stepsize }, + { "fcstep", &t_inputrec::fc_stepsize }, + { "rtpi", &t_inputrec::rtpi }, + { "compressed-x-precision", &t_inputrec::x_compression_precision }, + // ... }; } -} +} // namespace std::map float32Params() { @@ -345,13 +243,8 @@ std::map float32Params() std::map float64Params() { static const std::map explicitDoubles = { - { - "dt", &t_inputrec::delta_t - }, - { - "tinit", &t_inputrec::init_t - }, -// ... + { "dt", &t_inputrec::delta_t }, { "tinit", &t_inputrec::init_t }, + // ... }; @@ -359,7 +252,7 @@ std::map float64Params() auto fullMap = compatibleRealParams(); // Get the explicitly `double` parameters. - for (const auto &item : explicitDoubles) + for (const auto& item : explicitDoubles) { fullMap.emplace(item); } @@ -370,16 +263,10 @@ std::map float64Params() std::map int64Params() { return { - { - "nsteps", &t_inputrec::nsteps - }, - { - "init-step", &t_inputrec::init_step - }, - { - "ld-seed", &t_inputrec::ld_seed - }, -// ... + { "nsteps", &t_inputrec::nsteps }, + { "init-step", &t_inputrec::init_step }, + { "ld-seed", &t_inputrec::ld_seed }, + // ... }; } @@ -392,7 +279,7 @@ std::map int64Params() * * \throws gmxapi_compat::ValueError for parameters with no mapping. */ -GmxapiType mdParamToType(const std::string &name) +GmxapiType mdParamToType(const std::string& name) { const auto staticMap = simulationParameterTypeMap(); auto entry = staticMap.find(name); @@ -422,148 +309,145 @@ GmxapiType mdParamToType(const std::string &name) */ class GmxMdParamsImpl final { - public: - /*! - * \brief Create an initialized but empty parameters structure. - * - * Parameter keys are set at construction, but all values are empty. This - * allows the caller to check for valid parameter names or their types, - * while allowing the consuming code to know which parameters were explicitly - * set by the caller. - * - * To load values from a TPR file, see getMdParams(). - */ - GmxMdParamsImpl(); - - explicit GmxMdParamsImpl(std::shared_ptr tprContents); - - /*! - * \brief Get the current list of keys. - * - * \return - */ - std::vector keys() const +public: + /*! + * \brief Create an initialized but empty parameters structure. + * + * Parameter keys are set at construction, but all values are empty. This + * allows the caller to check for valid parameter names or their types, + * while allowing the consuming code to know which parameters were explicitly + * set by the caller. + * + * To load values from a TPR file, see getMdParams(). + */ + GmxMdParamsImpl(); + + explicit GmxMdParamsImpl(std::shared_ptr tprContents); + + /*! + * \brief Get the current list of keys. + * + * \return + */ + std::vector keys() const + { + std::vector keyList; + for (auto&& entry : int64Params_) { - std::vector keyList; - for (auto && entry : int64Params_) - { - keyList.emplace_back(entry.first); - } - for (auto && entry : intParams_) - { - keyList.emplace_back(entry.first); - } - for (auto && entry : floatParams_) - { - keyList.emplace_back(entry.first); - } - for (auto && entry : float64Params_) - { - keyList.emplace_back(entry.first); - } - return keyList; - }; - - template T extract(const std::string & /* key */) const + keyList.emplace_back(entry.first); + } + for (auto&& entry : intParams_) { - auto value = T(); - // should be an APIError - throw TypeError("unhandled type"); + keyList.emplace_back(entry.first); } - - void set(const std::string &key, const int64_t &value) + for (auto&& entry : floatParams_) { - if (int64Params_.find(key) != int64Params_.end()) - { - int64Params_[key] = std::make_pair(value, true); + keyList.emplace_back(entry.first); + } + for (auto&& entry : float64Params_) + { + keyList.emplace_back(entry.first); + } + return keyList; + }; - if (source_) - { - auto memberPointer = int64Params().at(key); - source_->inputRecord().*memberPointer = value; - } - } - else if (intParams_.find(key) != intParams_.end()) - { - // TODO: check whether value is too large? - intParams_[key] = std::make_pair(static_cast(value), true); + template + T extract(const std::string& /* key */) const + { + auto value = T(); + // should be an APIError + throw TypeError("unhandled type"); + } - if (source_) - { - auto memberPointer = int32Params().at(key); - source_->inputRecord().*memberPointer = value; - } + void set(const std::string& key, const int64_t& value) + { + if (int64Params_.find(key) != int64Params_.end()) + { + int64Params_[key] = std::make_pair(value, true); - } - else + if (source_) { - throw KeyError("Named parameter is incompatible with integer type value."); + auto memberPointer = int64Params().at(key); + source_->inputRecord().*memberPointer = value; } - }; - - void set(const std::string &key, const double &value) + } + else if (intParams_.find(key) != intParams_.end()) { - if (float64Params_.find(key) != float64Params_.end()) - { - float64Params_[key] = std::make_pair(value, true); - - if (source_) - { - auto memberPointer = float64Params().at(key); - source_->inputRecord().*memberPointer = value; - } + // TODO: check whether value is too large? + intParams_[key] = std::make_pair(static_cast(value), true); - } - else if (floatParams_.find(key) != floatParams_.end()) + if (source_) { - // TODO: check whether value is too large? - floatParams_[key] = std::make_pair(static_cast(value), true); + auto memberPointer = int32Params().at(key); + source_->inputRecord().*memberPointer = value; + } + } + else + { + throw KeyError("Named parameter is incompatible with integer type value."); + } + }; - if (source_) - { - auto memberPointer = float32Params().at(key); - source_->inputRecord().*memberPointer = static_cast(value); - } + void set(const std::string& key, const double& value) + { + if (float64Params_.find(key) != float64Params_.end()) + { + float64Params_[key] = std::make_pair(value, true); - } - else + if (source_) { - throw KeyError("Named parameter is incompatible with floating point type value."); + auto memberPointer = float64Params().at(key); + source_->inputRecord().*memberPointer = value; } - }; + } + else if (floatParams_.find(key) != floatParams_.end()) + { + // TODO: check whether value is too large? + floatParams_[key] = std::make_pair(static_cast(value), true); - TprReadHandle getSource() const + if (source_) + { + auto memberPointer = float32Params().at(key); + source_->inputRecord().*memberPointer = static_cast(value); + } + } + else { - // Note: might return a null handle. Need to decide what that means and how to address it. - return TprReadHandle(source_); + throw KeyError("Named parameter is incompatible with floating point type value."); } + }; + + TprReadHandle getSource() const + { + // Note: might return a null handle. Need to decide what that means and how to address it. + return TprReadHandle(source_); + } - private: - - // Hold the settable parameters and whether or not they have been set. - // TODO: update to gmxapi named types? - // TODO: update to gmx::compat::optional now that this file is in the GROMACS source. - std::map < std::string, std::pair < int64_t, bool>> int64Params_; - std::map < std::string, std::pair < int, bool>> intParams_; - std::map < std::string, std::pair < float, bool>> floatParams_; - std::map < std::string, std::pair < double, bool>> float64Params_; - - /*! \brief Shared ownership of a pack of TPR data. - * - * This is a non-normative way to retain access to gmxapi resources. - * \todo Subscribe to a Context-managed resource. - */ - std::shared_ptr source_; +private: + // Hold the settable parameters and whether or not they have been set. + // TODO: update to gmxapi named types? + // TODO: update to gmx::compat::optional now that this file is in the GROMACS source. + std::map> int64Params_; + std::map> intParams_; + std::map> floatParams_; + std::map> float64Params_; + + /*! \brief Shared ownership of a pack of TPR data. + * + * This is a non-normative way to retain access to gmxapi resources. + * \todo Subscribe to a Context-managed resource. + */ + std::shared_ptr source_; }; -void setParam(gmxapicompat::GmxMdParams *params, const std::string &name, double value) +void setParam(gmxapicompat::GmxMdParams* params, const std::string& name, double value) { assert(params != nullptr); assert(params->params_ != nullptr); params->params_->set(name, value); } -void setParam(gmxapicompat::GmxMdParams *params, const std::string &name, int64_t value) +void setParam(gmxapicompat::GmxMdParams* params, const std::string& name, int64_t value) { assert(params != nullptr); assert(params->params_ != nullptr); @@ -571,15 +455,15 @@ void setParam(gmxapicompat::GmxMdParams *params, const std::string &name, int64_ } template -static void updateParamsContainer(ParamsContainerT* params, const TprContents &source, const Mapping &map) +static void updateParamsContainer(ParamsContainerT* params, const TprContents& source, const Mapping& map) { - for (const auto &definition : map) + for (const auto& definition : map) { - const auto &key = definition.first; + const auto& key = definition.first; auto memberPointer = definition.second; - auto &irInstance = source.inputRecord(); + auto& irInstance = source.inputRecord(); auto fileValue = irInstance.*memberPointer; - (*params)[key] = std::make_pair(fileValue, true); + (*params)[key] = std::make_pair(fileValue, true); } } @@ -589,7 +473,7 @@ static void updateParamsContainer(ParamsContainerT* params, const TprContents &s * \param tprContents */ GmxMdParamsImpl::GmxMdParamsImpl(std::shared_ptr tprContents) : - source_ {std::move(tprContents)} + source_{ std::move(tprContents) } { if (source_) { @@ -600,15 +484,13 @@ GmxMdParamsImpl::GmxMdParamsImpl(std::shared_ptr tprC } } -GmxMdParamsImpl::GmxMdParamsImpl() : - GmxMdParamsImpl(nullptr) -{} +GmxMdParamsImpl::GmxMdParamsImpl() : GmxMdParamsImpl(nullptr) {} template<> -int GmxMdParamsImpl::extract(const std::string &key) const +int GmxMdParamsImpl::extract(const std::string& key) const { - const auto ¶ms = intParams_; - const auto &entry = params.find(key); + const auto& params = intParams_; + const auto& entry = params.find(key); if (entry == params.cend()) { throw KeyError("Parameter of the requested name and type not defined."); @@ -625,10 +507,10 @@ int GmxMdParamsImpl::extract(const std::string &key) const } template<> -int64_t GmxMdParamsImpl::extract(const std::string &key) const +int64_t GmxMdParamsImpl::extract(const std::string& key) const { - const auto ¶ms = int64Params_; - const auto &entry = params.find(key); + const auto& params = int64Params_; + const auto& entry = params.find(key); if (entry == params.cend()) { throw KeyError("Parameter of the requested name and type not defined."); @@ -644,10 +526,10 @@ int64_t GmxMdParamsImpl::extract(const std::string &key) const } } template<> -float GmxMdParamsImpl::extract(const std::string &key) const +float GmxMdParamsImpl::extract(const std::string& key) const { - const auto ¶ms = floatParams_; - const auto &entry = params.find(key); + const auto& params = floatParams_; + const auto& entry = params.find(key); if (entry == params.cend()) { throw KeyError("Parameter of the requested name and type not defined."); @@ -663,10 +545,10 @@ float GmxMdParamsImpl::extract(const std::string &key) const } } template<> -double GmxMdParamsImpl::extract(const std::string &key) const +double GmxMdParamsImpl::extract(const std::string& key) const { - const auto ¶ms = float64Params_; - const auto &entry = params.find(key); + const auto& params = float64Params_; + const auto& entry = params.find(key); if (entry == params.cend()) { throw KeyError("Parameter of the requested name and type not defined."); @@ -683,29 +565,29 @@ double GmxMdParamsImpl::extract(const std::string &key) const } -int extractParam(const GmxMdParams ¶ms, const std::string &name, int) +int extractParam(const GmxMdParams& params, const std::string& name, int /*unused*/) { assert(params.params_); return params.params_->extract(name); } -int64_t extractParam(const GmxMdParams ¶ms, const std::string &name, int64_t) +int64_t extractParam(const GmxMdParams& params, const std::string& name, int64_t /*unused*/) { assert(params.params_); - int64_t value {}; + int64_t value{}; // Allow fetching both known integer types. try { value = params.params_->extract(name); } - catch (const KeyError &error) + catch (const KeyError& error) { // If not found as a regular int, check for int64. try { - value = params.params_->extract(name); + value = params.params_->extract(name); } - catch (const KeyError &error64) + catch (const KeyError& error64) { throw KeyError("Parameter of the requested name not set."); } @@ -714,29 +596,29 @@ int64_t extractParam(const GmxMdParams ¶ms, const std::string &name, int64_t return value; } -float extractParam(const GmxMdParams ¶ms, const std::string &name, float) +float extractParam(const GmxMdParams& params, const std::string& name, float /*unused*/) { assert(params.params_); return params.params_->extract(name); } -double extractParam(const GmxMdParams ¶ms, const std::string &name, double) +double extractParam(const GmxMdParams& params, const std::string& name, double /*unused*/) { assert(params.params_); - double value {}; + double value{}; // Allow fetching both single and double precision. try { value = params.params_->extract(name); } - catch (const KeyError &errorDouble) + catch (const KeyError& errorDouble) { // If not found as a double precision value, check for single-precision. try { value = params.params_->extract(name); } - catch (const KeyError &errorFloat) + catch (const KeyError& errorFloat) { throw KeyError("Parameter of the requested name not set."); } @@ -745,20 +627,20 @@ double extractParam(const GmxMdParams ¶ms, const std::string &name, double) return value; } -std::vector keys(const GmxMdParams ¶ms) +std::vector keys(const GmxMdParams& params) { return params.params_->keys(); } -std::unique_ptr readTprFile(const std::string &filename) +std::unique_ptr readTprFile(const std::string& filename) { auto tprfile = gmxapicompat::TprContents(filename); auto handle = std::make_unique(std::move(tprfile)); return handle; } -std::unique_ptr getMdParams(const TprReadHandle &handle) +std::unique_ptr getMdParams(const TprReadHandle& handle) { auto tprfile = handle.get(); // TODO: convert to exception / decide whether null handles are allowed. @@ -768,67 +650,67 @@ std::unique_ptr getMdParams(const TprReadHandle &handle) return params; } -std::unique_ptr getTopologySource(const TprReadHandle &handle) +std::unique_ptr getTopologySource(const TprReadHandle& handle) { - auto source = std::make_unique(); + auto source = std::make_unique(); source->tprFile_ = handle.get(); return source; } -std::unique_ptr getSimulationState(const TprReadHandle &handle) +std::unique_ptr getSimulationState(const TprReadHandle& handle) { - auto source = std::make_unique(); + auto source = std::make_unique(); source->tprFile_ = handle.get(); return source; } -std::unique_ptr getStructureSource(const TprReadHandle &handle) +std::unique_ptr getStructureSource(const TprReadHandle& handle) { - auto source = std::make_unique(); + auto source = std::make_unique(); source->tprFile_ = handle.get(); return source; } TprReadHandle::TprReadHandle(std::shared_ptr tprFile) : - tprContents_ {std::move(tprFile)} + tprContents_{ std::move(tprFile) } { } -TprReadHandle getSourceFileHandle(const GmxMdParams ¶ms) +TprReadHandle getSourceFileHandle(const GmxMdParams& params) { return params.params_->getSource(); } -void writeTprFile(const std::string &filename, - const GmxMdParams ¶ms, - const StructureSource &structure, - const SimulationState &state, - const TopologySource &topology) +void writeTprFile(const std::string& filename, + const GmxMdParams& params, + const StructureSource& structure, + const SimulationState& state, + const TopologySource& topology) { assert(params.params_); // The only way we can check for consistent input right now is to make sure // it all comes from the same file. - if (structure.tprFile_.get() != state.tprFile_.get() || - state.tprFile_.get() != topology.tprFile_.get() || - topology.tprFile_.get() != params.params_->getSource().get().get() || - params.params_->getSource().get().get() != structure.tprFile_.get() - ) + if (structure.tprFile_.get() != state.tprFile_.get() + || state.tprFile_.get() != topology.tprFile_.get() + || topology.tprFile_.get() != params.params_->getSource().get().get() + || params.params_->getSource().get().get() != structure.tprFile_.get()) { - throw ValueError("writeTprFile does not yet know how to reconcile data from different TPR file sources."); + throw ValueError( + "writeTprFile does not yet know how to reconcile data from different TPR file " + "sources."); } - const auto tprFileHandle = params.params_->getSource(); - const auto tprFile = tprFileHandle.get(); + const auto tprFileHandle = params.params_->getSource(); + const auto tprFile = tprFileHandle.get(); assert(tprFile); - const auto &inputRecord = tprFile->inputRecord(); - const auto &writeState = tprFile->state(); - const auto &writeTopology = tprFile->molecularTopology(); + const auto& inputRecord = tprFile->inputRecord(); + const auto& writeState = tprFile->state(); + const auto& writeTopology = tprFile->molecularTopology(); write_tpx_state(filename.c_str(), &inputRecord, &writeState, &writeTopology); - } -TprReadHandle::TprReadHandle(TprContents &&tprFile) : - TprReadHandle {std::make_shared(std::move(tprFile))} +TprReadHandle::TprReadHandle(TprContents&& tprFile) : + TprReadHandle{ std::make_shared(std::move(tprFile)) } { } @@ -842,15 +724,13 @@ TprReadHandle::~TprReadHandle() = default; GmxMdParams::~GmxMdParams() = default; -GmxMdParams::GmxMdParams() : - params_ {std::make_unique()} -{} +GmxMdParams::GmxMdParams() : params_{ std::make_unique() } {} -GmxMdParams::GmxMdParams(GmxMdParams &&) noexcept = default; +GmxMdParams::GmxMdParams(GmxMdParams&&) noexcept = default; -GmxMdParams &GmxMdParams::operator=(GmxMdParams &&) noexcept = default; +GmxMdParams& GmxMdParams::operator=(GmxMdParams&&) noexcept = default; -GmxMdParams::GmxMdParams(std::unique_ptr &&impl) +GmxMdParams::GmxMdParams(std::unique_ptr&& impl) { // We use swap instead of move construction so that we don't have // to worry about the restrictions on Deleters. @@ -859,45 +739,39 @@ GmxMdParams::GmxMdParams(std::unique_ptr &&impl) }; // maybe this should return a handle to the new file? -bool copy_tprfile(const gmxapicompat::TprReadHandle &input, const std::string &outFile) +bool copy_tprfile(const gmxapicompat::TprReadHandle& input, const std::string& outFile) { if (!input.get()) { return false; } - gmxapicompat::writeTprFile(outFile, - *gmxapicompat::getMdParams(input), - *gmxapicompat::getStructureSource(input), - *gmxapicompat::getSimulationState(input), - *gmxapicompat::getTopologySource(input)); + gmxapicompat::writeTprFile( + outFile, *gmxapicompat::getMdParams(input), *gmxapicompat::getStructureSource(input), + *gmxapicompat::getSimulationState(input), *gmxapicompat::getTopologySource(input)); return true; } -bool rewrite_tprfile(const std::string &inFile, const std::string &outFile, double endTime) +bool rewrite_tprfile(const std::string& inFile, const std::string& outFile, double endTime) { - auto success = false; + auto success = false; - const char * top_fn = inFile.c_str(); + const char* top_fn = inFile.c_str(); - t_inputrec irInstance; - gmx_mtop_t mtop; - t_state state; + t_inputrec irInstance; + gmx_mtop_t mtop; + t_state state; read_tpx_state(top_fn, &irInstance, &state, &mtop); /* set program name, command line, and default values for output options */ - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx::TimeUnit timeUnit = gmx::TimeUnit_Default; - bool bView { - false - }; // argument that says we don't want to view graphs. - int xvgFormat { - 0 - }; + bool bView{ false }; // argument that says we don't want to view graphs. + int xvgFormat{ 0 }; output_env_init(&oenv, gmx::getProgramContext(), - static_cast(timeUnit + 1), bView, // NOLINT(misc-misplaced-widening-cast) - static_cast(xvgFormat + 1), 0); + static_cast(timeUnit + 1), // NOLINT(misc-misplaced-widening-cast) + bView, static_cast(xvgFormat + 1), 0); - double run_t = irInstance.init_step*irInstance.delta_t + irInstance.init_t; + double run_t = irInstance.init_step * irInstance.delta_t + irInstance.init_t; irInstance.nsteps = lround((endTime - run_t) / irInstance.delta_t); diff --git a/src/api/cpp/version.cpp b/src/api/cpp/version.cpp index 6617d36daf..6a06b3c173 100644 --- a/src/api/cpp/version.cpp +++ b/src/api/cpp/version.cpp @@ -60,7 +60,7 @@ std::string Version::release() return c_release; } -bool Version::hasFeature(const std::string &featurename) +bool Version::hasFeature(const std::string& featurename) { // For features introduced without an incompatible API change or where // semantic versioning is otherwise insufficient, we can consult a map, TBD. @@ -68,9 +68,7 @@ bool Version::hasFeature(const std::string &featurename) return false; } -bool Version::isAtLeast(version_t major, - version_t minor, - version_t patch) +bool Version::isAtLeast(version_t major, version_t minor, version_t patch) { if (Version::majorVersion() < major) { diff --git a/src/api/cpp/workflow.cpp b/src/api/cpp/workflow.cpp index 5996d509dd..d37e6b6f7b 100644 --- a/src/api/cpp/workflow.cpp +++ b/src/api/cpp/workflow.cpp @@ -51,12 +51,11 @@ std::unique_ptr MDNodeSpecification::clone() { GMX_ASSERT(!tprfilename_.empty(), "Need a non-empty filename string."); std::unique_ptr node = nullptr; - node = std::make_unique(tprfilename_); + node = std::make_unique(tprfilename_); return node; } -MDNodeSpecification::MDNodeSpecification(const std::string &filename) : - tprfilename_ {std::move(filename)} +MDNodeSpecification::MDNodeSpecification(const std::string& filename) : tprfilename_{ filename } { GMX_ASSERT(!tprfilename_.empty(), "Need a non-empty filename string."); } @@ -75,21 +74,22 @@ NodeKey Workflow::addNode(std::unique_ptr spec) return {}; } -std::unique_ptr Workflow::create(const std::string &filename) +std::unique_ptr Workflow::create(const std::string& filename) { const std::string name = "MD"; auto spec = std::make_unique(filename); Workflow::Impl graph; graph.emplace(std::make_pair(name, std::move(spec))); - auto workflow = std::make_unique(std::move(graph)); + auto workflow = std::make_unique(std::move(graph)); return workflow; } -std::unique_ptr Workflow::getNode(const NodeKey &key) const noexcept +std::unique_ptr Workflow::getNode(const NodeKey& key) const noexcept { - const Impl &graph = graph_; - GMX_ASSERT((graph.count(key) == 0) || (graph.count(key) == 1), "Key should occur zero or one times."); - auto const iter = graph.find(key); + const Impl& graph = graph_; + GMX_ASSERT((graph.count(key) == 0) || (graph.count(key) == 1), + "Key should occur zero or one times."); + auto const iter = graph.find(key); std::unique_ptr node = nullptr; if (iter == graph.end()) { @@ -103,9 +103,7 @@ std::unique_ptr Workflow::getNode(const NodeKey &key) const n return node; } -Workflow::Workflow(Workflow::Impl &&impl) : - graph_ {std::forward(impl)} -{} +Workflow::Workflow(Workflow::Impl&& impl) : graph_{ std::forward(impl) } {} Workflow::Impl::const_iterator Workflow::cbegin() const { diff --git a/src/api/cpp/workflow.h b/src/api/cpp/workflow.h index e1ae8c8dc0..ccba142620 100644 --- a/src/api/cpp/workflow.h +++ b/src/api/cpp/workflow.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -99,94 +99,94 @@ class NodeSpecification; /*! * \brief Recipe for a computational workflow. * - * Provides a lightweight and portable container defining the nodes and edges in a workflow with enough information for - * the workflow to be instantiated and run. + * Provides a lightweight and portable container defining the nodes and edges in a workflow with + * enough information for the workflow to be instantiated and run. * * \ingroup gmxapi */ class Workflow final { - public: - //! In initial version, Implementation class is just a type alias. - using Impl = typename std::map< NodeKey, std::unique_ptr >; +public: + //! In initial version, Implementation class is just a type alias. + using Impl = typename std::map>; - /*! \brief Use create() to get Workflow objects. - * - * An empty workflow is not meaningful except to a builder, which does not - * yet exist. Even a builder, though, will probably create the implementation - * object directly and the Workflow object from that. - */ - Workflow() = delete; + /*! \brief Use create() to get Workflow objects. + * + * An empty workflow is not meaningful except to a builder, which does not + * yet exist. Even a builder, though, will probably create the implementation + * object directly and the Workflow object from that. + */ + Workflow() = delete; - /*! - * \brief Construct by transfering ownership of an implementation object. - * - * \param impl Implementation object to wrap. - * - * Usage: - * - * gmxapi::Workflow::Impl newGraph; - * // ... - * // configure graph... - * // ... - * // Create workflow container - * gmxapi::Workflow work {std::move(newGraph)}; - * gmxapi::launchSession(&context, work); - * - */ - explicit Workflow(Impl &&impl); + /*! + * \brief Construct by transfering ownership of an implementation object. + * + * \param impl Implementation object to wrap. + * + * Usage: + * + * gmxapi::Workflow::Impl newGraph; + * // ... + * // configure graph... + * // ... + * // Create workflow container + * gmxapi::Workflow work {std::move(newGraph)}; + * gmxapi::launchSession(&context, work); + * + */ + explicit Workflow(Impl&& impl); - /*! - * \brief Add a node to the workflow graph. - * - * The work specification must already have its inputs assigned to existing - * nodes. This operation should only be permitted if it does not render a - * valid workflow invalid. - * - * \param spec Operational node to add to the Workflow. - * - * \return Key for the new node in the Workflow container. - * - * \todo Not yet implemented. - */ - NodeKey addNode(std::unique_ptr spec); + /*! + * \brief Add a node to the workflow graph. + * + * The work specification must already have its inputs assigned to existing + * nodes. This operation should only be permitted if it does not render a + * valid workflow invalid. + * + * \param spec Operational node to add to the Workflow. + * + * \return Key for the new node in the Workflow container. + * + * \todo Not yet implemented. + */ + NodeKey addNode(std::unique_ptr spec); - /*! - * \brief Get the node specification for a provided key. - * - * \param key Unique identifier for a node in the graph. - * \return copy of the node specification. - */ - std::unique_ptr getNode(const gmxapi::NodeKey &key) const noexcept; + /*! + * \brief Get the node specification for a provided key. + * + * \param key Unique identifier for a node in the graph. + * \return copy of the node specification. + */ + std::unique_ptr getNode(const gmxapi::NodeKey& key) const noexcept; - /*! - * \brief Get an iterator to the node key--value pairs. - * - * \return iterator across nodes in container. - * - * The order in which the nodes are returned is unspecified. Only forward iterator is provided. - * \{ - */ - Impl::const_iterator cbegin() const; - Impl::const_iterator cend() const; - // Allow range based for loop to work before C++17 - Impl::const_iterator begin() const; - Impl::const_iterator end() const; - /*! \} */ + /*! + * \brief Get an iterator to the node key--value pairs. + * + * \return iterator across nodes in container. + * + * The order in which the nodes are returned is unspecified. Only forward iterator is provided. + * \{ + */ + Impl::const_iterator cbegin() const; + Impl::const_iterator cend() const; + // Allow range based for loop to work before C++17 + Impl::const_iterator begin() const; + Impl::const_iterator end() const; + /*! \} */ - /*! - * \brief Create a new workflow. - * - * \param filename TPR filename accessible both to the client and library. - * \return Ownership of a new Workflow instance. - */ - static std::unique_ptr create(const std::string &filename); - private: - /*! - * \brief Storage structure. - */ - Impl graph_; + /*! + * \brief Create a new workflow. + * + * \param filename TPR filename accessible both to the client and library. + * \return Ownership of a new Workflow instance. + */ + static std::unique_ptr create(const std::string& filename); +private: + /*! + * \brief Storage structure. + */ + Impl graph_; }; /*! @@ -212,47 +212,46 @@ class Workflow final */ class NodeSpecification { - public: - //! Base class is heritable. - virtual ~NodeSpecification(); +public: + //! Base class is heritable. + virtual ~NodeSpecification(); - //! Nodes can use arbitrary param type, but string is default. - using paramsType = std::string; + //! Nodes can use arbitrary param type, but string is default. + using paramsType = std::string; - /*! - * \brief Get an equivalent node for a new graph. - * - * \return ownership of a new node specification - * - * Allows a derived class to define its own copy behavior when accessed - * through a base class pointer. - * - * \internal - * Future versions may use this function to translate a node spec from one - * context to another, in which case the context would likely be passed - * as an argument. E.g. clone(&context) or cloneTo(&workspec). It may - * be confusing for developers to manage the distinction between replicating - * a node in a graph versus using helper methods to copy the node-specific - * parameters to a node in a new graph, so it is probably better to - * reserve copy/move construction/assignment for internal code and use - * well-named well-documented free functions for such higher level operations. - * Furthermore, it is not universally intuitive what is meant by copying - * a node without specifying what happens to edges and connected nodes. - */ - virtual std::unique_ptr clone() = 0; + /*! + * \brief Get an equivalent node for a new graph. + * + * \return ownership of a new node specification + * + * Allows a derived class to define its own copy behavior when accessed + * through a base class pointer. + * + * \internal + * Future versions may use this function to translate a node spec from one + * context to another, in which case the context would likely be passed + * as an argument. E.g. clone(&context) or cloneTo(&workspec). It may + * be confusing for developers to manage the distinction between replicating + * a node in a graph versus using helper methods to copy the node-specific + * parameters to a node in a new graph, so it is probably better to + * reserve copy/move construction/assignment for internal code and use + * well-named well-documented free functions for such higher level operations. + * Furthermore, it is not universally intuitive what is meant by copying + * a node without specifying what happens to edges and connected nodes. + */ + virtual std::unique_ptr clone() = 0; - /*! - * \brief Fetch current params value. - * - * \return copy of internal params value. - */ - virtual paramsType params() const noexcept = 0; - - //! Parameters for the operation represented by this node. - paramsType params_ {}; + /*! + * \brief Fetch current params value. + * + * \return copy of internal params value. + */ + virtual paramsType params() const noexcept = 0; + //! Parameters for the operation represented by this node. + paramsType params_{}; }; -} //end namespace gmxapi +} // end namespace gmxapi -#endif //GMXAPI_WORKFLOW_H +#endif // GMXAPI_WORKFLOW_H diff --git a/src/api/cpp/workflow/tests/workflow.cpp b/src/api/cpp/workflow/tests/workflow.cpp index 75a92a8713..15aa305226 100644 --- a/src/api/cpp/workflow/tests/workflow.cpp +++ b/src/api/cpp/workflow/tests/workflow.cpp @@ -63,9 +63,7 @@ TEST_F(GmxApiTest, BuildApiWorkflowImpl) EXPECT_NE(node, nullptr); // Create key - std::string key { - "MD" - }; + std::string key{ "MD" }; key.append(runner_.tprFileName_); // Create graph (workflow implementation object) @@ -75,9 +73,7 @@ TEST_F(GmxApiTest, BuildApiWorkflowImpl) EXPECT_EQ(impl.size(), 1); // Create workflow container - gmxapi::Workflow work { - std::move(impl) - }; + gmxapi::Workflow work{ std::move(impl) }; } //! Create from create() method(s) diff --git a/src/api/cpp/workflow_impl.h b/src/api/cpp/workflow_impl.h index 20efb36b33..4a20aaf3d8 100644 --- a/src/api/cpp/workflow_impl.h +++ b/src/api/cpp/workflow_impl.h @@ -55,8 +55,8 @@ namespace gmxapi class WorkflowKeyError : public BasicException { - public: - using BasicException::BasicException; +public: + using BasicException::BasicException; }; /*! @@ -64,38 +64,38 @@ class WorkflowKeyError : public BasicException */ class MDNodeSpecification : public NodeSpecification { - public: - //! Uses parameter type of base class. - using NodeSpecification::paramsType; +public: + //! Uses parameter type of base class. + using NodeSpecification::paramsType; - /*! - * \brief Simulation node from file input - * - * \param filename TPR input filename. - */ - explicit MDNodeSpecification(const std::string &filename); + /*! + * \brief Simulation node from file input + * + * \param filename TPR input filename. + */ + explicit MDNodeSpecification(const std::string& filename); - /* - * \brief Implement NodeSpecification::clone() - * - * \returns a node to launch a simulation from the same input as this - * - * Returns nullptr if clone is not possible. - */ - std::unique_ptr clone() override; + /* + * \brief Implement NodeSpecification::clone() + * + * \returns a node to launch a simulation from the same input as this + * + * Returns nullptr if clone is not possible. + */ + std::unique_ptr clone() override; - /*! \brief Implement NodeSpecification::params() - * - * \return Copy of internal params value. - */ - paramsType params() const noexcept override; + /*! \brief Implement NodeSpecification::params() + * + * \return Copy of internal params value. + */ + paramsType params() const noexcept override; - private: - //! The TPR input filename, set during construction - paramsType tprfilename_; +private: + //! The TPR input filename, set during construction + paramsType tprfilename_; }; -} // end namespace gmxapi +} // end namespace gmxapi -#endif //GROMACS_WORKFLOW_IMPL_H +#endif // GROMACS_WORKFLOW_IMPL_H diff --git a/src/gmxpre.h b/src/gmxpre.h index ad248a8169..10353266f1 100644 --- a/src/gmxpre.h +++ b/src/gmxpre.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,7 +55,7 @@ */ //! \cond #ifdef HAVE_CONFIG_H -#include "gmxpre-config.h" +# include "gmxpre-config.h" #endif /* We use a few GNU functions for thread affinity and other low-level stuff. @@ -68,7 +68,7 @@ * sorting of the includes more difficult. */ #ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 +# define _GNU_SOURCE 1 #endif /* Some C++(?) compilers require these to be defined to get the integer limits @@ -86,8 +86,8 @@ #define __STDC_FORMAT_MACROS #if GMX_FAHCORE -#define FULLINDIRECT 1 -#define USE_FAH_XDR 1 -#include "swindirect.h" +# define FULLINDIRECT 1 +# define USE_FAH_XDR 1 +# include "swindirect.h" #endif //! \endcond diff --git a/src/gromacs/analysisdata/abstractdata.cpp b/src/gromacs/analysisdata/abstractdata.cpp index 39af90139b..6822878a98 100644 --- a/src/gromacs/analysisdata/abstractdata.cpp +++ b/src/gromacs/analysisdata/abstractdata.cpp @@ -68,19 +68,18 @@ namespace gmx */ class AbstractAnalysisData::Impl { - public: - Impl(); - - //! Column counts for each data set in the data. - std::vector columnCounts_; - //! Whether the data is multipoint. - bool bMultipoint_; - //! Manager for the added modules. - AnalysisDataModuleManager modules_; +public: + Impl(); + + //! Column counts for each data set in the data. + std::vector columnCounts_; + //! Whether the data is multipoint. + bool bMultipoint_; + //! Manager for the added modules. + AnalysisDataModuleManager modules_; }; -AbstractAnalysisData::Impl::Impl() - : bMultipoint_(false) +AbstractAnalysisData::Impl::Impl() : bMultipoint_(false) { columnCounts_.push_back(0); } @@ -90,47 +89,35 @@ AbstractAnalysisData::Impl::Impl() * AbstractAnalysisData */ /*! \cond libapi */ -AbstractAnalysisData::AbstractAnalysisData() - : impl_(new Impl()) -{ -} +AbstractAnalysisData::AbstractAnalysisData() : impl_(new Impl()) {} //! \endcond -AbstractAnalysisData::~AbstractAnalysisData() -{ -} +AbstractAnalysisData::~AbstractAnalysisData() {} -bool -AbstractAnalysisData::isMultipoint() const +bool AbstractAnalysisData::isMultipoint() const { return impl_->bMultipoint_; } -int -AbstractAnalysisData::dataSetCount() const +int AbstractAnalysisData::dataSetCount() const { return impl_->columnCounts_.size(); } -int -AbstractAnalysisData::columnCount(int dataSet) const +int AbstractAnalysisData::columnCount(int dataSet) const { - GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), - "Out of range data set index"); + GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Out of range data set index"); return impl_->columnCounts_[dataSet]; } -int -AbstractAnalysisData::columnCount() const +int AbstractAnalysisData::columnCount() const { - GMX_ASSERT(dataSetCount() == 1, - "Convenience method not available for multiple data sets"); + GMX_ASSERT(dataSetCount() == 1, "Convenience method not available for multiple data sets"); return columnCount(0); } -AnalysisDataFrameRef -AbstractAnalysisData::tryGetDataFrame(int index) const +AnalysisDataFrameRef AbstractAnalysisData::tryGetDataFrame(int index) const { if (index < 0 || index >= frameCount()) { @@ -140,8 +127,7 @@ AbstractAnalysisData::tryGetDataFrame(int index) const } -AnalysisDataFrameRef -AbstractAnalysisData::getDataFrame(int index) const +AnalysisDataFrameRef AbstractAnalysisData::getDataFrame(int index) const { AnalysisDataFrameRef frame = tryGetDataFrame(index); if (!frame.isValid()) @@ -152,8 +138,7 @@ AbstractAnalysisData::getDataFrame(int index) const } -bool -AbstractAnalysisData::requestStorage(int nframes) +bool AbstractAnalysisData::requestStorage(int nframes) { GMX_RELEASE_ASSERT(nframes >= -1, "Invalid number of frames requested"); if (nframes == 0) @@ -164,47 +149,38 @@ AbstractAnalysisData::requestStorage(int nframes) } -void -AbstractAnalysisData::addModule(const AnalysisDataModulePointer &module) +void AbstractAnalysisData::addModule(const AnalysisDataModulePointer& module) { impl_->modules_.addModule(this, module); } -void -AbstractAnalysisData::addColumnModule(int col, int span, - const AnalysisDataModulePointer &module) +void AbstractAnalysisData::addColumnModule(int col, int span, const AnalysisDataModulePointer& module) { - GMX_RELEASE_ASSERT(col >= 0 && span >= 1, - "Invalid columns specified for a column module"); - std::shared_ptr proxy( - new AnalysisDataProxy(col, span, this)); + GMX_RELEASE_ASSERT(col >= 0 && span >= 1, "Invalid columns specified for a column module"); + std::shared_ptr proxy(new AnalysisDataProxy(col, span, this)); proxy->addModule(module); addModule(proxy); } -void -AbstractAnalysisData::applyModule(IAnalysisDataModule *module) +void AbstractAnalysisData::applyModule(IAnalysisDataModule* module) { impl_->modules_.applyModule(this, module); } /*! \cond libapi */ -void -AbstractAnalysisData::setDataSetCount(int dataSetCount) +void AbstractAnalysisData::setDataSetCount(int dataSetCount) { GMX_RELEASE_ASSERT(dataSetCount > 0, "Invalid data column count"); - impl_->modules_.dataPropertyAboutToChange( - AnalysisDataModuleManager::eMultipleDataSets, dataSetCount > 1); + impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipleDataSets, + dataSetCount > 1); impl_->columnCounts_.resize(dataSetCount); } -void -AbstractAnalysisData::setColumnCount(int dataSet, int columnCount) +void AbstractAnalysisData::setColumnCount(int dataSet, int columnCount) { - GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), - "Out of range data set index"); + GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Out of range data set index"); GMX_RELEASE_ASSERT(columnCount > 0, "Invalid data column count"); bool bMultipleColumns = columnCount > 1; @@ -215,25 +191,22 @@ AbstractAnalysisData::setColumnCount(int dataSet, int columnCount) bMultipleColumns = true; } } - impl_->modules_.dataPropertyAboutToChange( - AnalysisDataModuleManager::eMultipleColumns, bMultipleColumns); + impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipleColumns, bMultipleColumns); impl_->columnCounts_[dataSet] = columnCount; } -void -AbstractAnalysisData::setMultipoint(bool bMultipoint) +void AbstractAnalysisData::setMultipoint(bool bMultipoint) { - impl_->modules_.dataPropertyAboutToChange( - AnalysisDataModuleManager::eMultipoint, bMultipoint); + impl_->modules_.dataPropertyAboutToChange(AnalysisDataModuleManager::eMultipoint, bMultipoint); impl_->bMultipoint_ = bMultipoint; } -AnalysisDataModuleManager &AbstractAnalysisData::moduleManager() +AnalysisDataModuleManager& AbstractAnalysisData::moduleManager() { return impl_->modules_; } -const AnalysisDataModuleManager &AbstractAnalysisData::moduleManager() const +const AnalysisDataModuleManager& AbstractAnalysisData::moduleManager() const { return impl_->modules_; } diff --git a/src/gromacs/analysisdata/abstractdata.h b/src/gromacs/analysisdata/abstractdata.h index d57ade6401..3b3767e7a1 100644 --- a/src/gromacs/analysisdata/abstractdata.h +++ b/src/gromacs/analysisdata/abstractdata.h @@ -110,333 +110,333 @@ typedef std::shared_ptr AnalysisDataModulePointer; */ class AbstractAnalysisData { - public: - virtual ~AbstractAnalysisData(); +public: + virtual ~AbstractAnalysisData(); - /*! \brief - * Whether the data can have multiple points in the same column - * in the same frame. - * - * \returns \c true if multiple points in the same column are - * allowed within a single frame. - * - * This kind of data can appear in many histogramming applications - * (e.g., RDFs), where each trajectory frame has several data points - * (possibly a different number for each frame). The current interface - * doesn't support storing such data, but this should rarely be - * necessary. - * - * The returned value does not change after modules have been notified - * of data start. - * \if libapi - * Derived classes can change the type by calling setMultipoint() - * subject to the above restriction. - * If this is not done, the function always returns false. - * \endif - * - * Does not throw. - */ - bool isMultipoint() const; - /*! \brief - * Returns the number of data sets in the data object. - * - * \returns The number of data sets in the data. - * - * If the number is not yet known, returns 0. - * The returned value does not change after modules have been notified - * of data start, but may change multiple times before that, depending - * on the actual data class. - * \if libapi - * Derived classes should set the number of columns with - * setDataSetCount(), within the above limitations. - * \endif - * - * Does not throw. - */ - int dataSetCount() const; - /*! \brief - * Returns the number of columns in a data set. - * - * \param[in] dataSet Zero-based index of the data set to query. - * \returns The number of columns in the data. - * - * If the number of columns is not yet known, returns 0. - * The returned value does not change after modules have been notified - * of data start, but may change multiple times before that, depending - * on the actual data class. - * \if libapi - * Derived classes should set the number of columns with - * setColumnCount(), within the above limitations. - * \endif - * - * Does not throw. - */ - int columnCount(int dataSet) const; - /*! \brief - * Returns the number of columns in the data. - * - * \returns The number of columns in the data. - * - * This is a convenience method for data objects with a single data set. - * Can only be called if dataSetCount() == 1. - * - * Does not throw. - * - * \see columnCount(int) - */ - int columnCount() const; - /*! \brief - * Returns the total number of frames in the data. - * - * \returns The total number of frames in the data. - * - * This function returns the number of frames that the object has - * produced. If requestStorage() has been successfully called, - * tryGetDataframe() or getDataFrame() can be used to access some or - * all of these frames. - * - * Does not throw. - * - * \if libapi - * Derived classes should implement this to return the number of - * frames. The frame count should not be incremented before - * tryGetDataFrameInternal() can return the new frame. - * The frame count must be incremented before - * AnalysisDataModuleManager::notifyFrameFinish() is called. - * \endif - */ - virtual int frameCount() const = 0; - /*! \brief - * Access stored data. - * - * \param[in] index Zero-based frame index to access. - * \returns Frame reference to frame \p index, or an invalid - * reference if no such frame is available. - * - * Does not throw. Failure to access a frame with the given index is - * indicated through the return value. Negative \p index is allowed, - * and will always result in an invalid reference being returned. - * - * \see requestStorage() - * \see getDataFrame() - */ - AnalysisDataFrameRef tryGetDataFrame(int index) const; - /*! \brief - * Access stored data. - * - * \param[in] index Zero-based frame index to access. - * \returns Frame reference to frame \p index. - * \throws APIError if the requested frame is not accessible. - * - * If the data is not certainly available, use tryGetDataFrame(). - * - * \see requestStorage() - * \see tryGetDataFrame() - */ - AnalysisDataFrameRef getDataFrame(int index) const; - /*! \brief - * Request storage of frames. - * - * \param[in] nframes Request storing at least \c nframes previous - * frames (-1 = request storing all). Must be >= -1. - * \returns true if the request could be satisfied. - * - * If called multiple times, the largest request is honored. - * - * Does not throw. Failure to honor the request is indicated through - * the return value. - * - * \see getDataFrame() - * \see tryGetDataFrame() - */ - bool requestStorage(int nframes); + /*! \brief + * Whether the data can have multiple points in the same column + * in the same frame. + * + * \returns \c true if multiple points in the same column are + * allowed within a single frame. + * + * This kind of data can appear in many histogramming applications + * (e.g., RDFs), where each trajectory frame has several data points + * (possibly a different number for each frame). The current interface + * doesn't support storing such data, but this should rarely be + * necessary. + * + * The returned value does not change after modules have been notified + * of data start. + * \if libapi + * Derived classes can change the type by calling setMultipoint() + * subject to the above restriction. + * If this is not done, the function always returns false. + * \endif + * + * Does not throw. + */ + bool isMultipoint() const; + /*! \brief + * Returns the number of data sets in the data object. + * + * \returns The number of data sets in the data. + * + * If the number is not yet known, returns 0. + * The returned value does not change after modules have been notified + * of data start, but may change multiple times before that, depending + * on the actual data class. + * \if libapi + * Derived classes should set the number of columns with + * setDataSetCount(), within the above limitations. + * \endif + * + * Does not throw. + */ + int dataSetCount() const; + /*! \brief + * Returns the number of columns in a data set. + * + * \param[in] dataSet Zero-based index of the data set to query. + * \returns The number of columns in the data. + * + * If the number of columns is not yet known, returns 0. + * The returned value does not change after modules have been notified + * of data start, but may change multiple times before that, depending + * on the actual data class. + * \if libapi + * Derived classes should set the number of columns with + * setColumnCount(), within the above limitations. + * \endif + * + * Does not throw. + */ + int columnCount(int dataSet) const; + /*! \brief + * Returns the number of columns in the data. + * + * \returns The number of columns in the data. + * + * This is a convenience method for data objects with a single data set. + * Can only be called if dataSetCount() == 1. + * + * Does not throw. + * + * \see columnCount(int) + */ + int columnCount() const; + /*! \brief + * Returns the total number of frames in the data. + * + * \returns The total number of frames in the data. + * + * This function returns the number of frames that the object has + * produced. If requestStorage() has been successfully called, + * tryGetDataframe() or getDataFrame() can be used to access some or + * all of these frames. + * + * Does not throw. + * + * \if libapi + * Derived classes should implement this to return the number of + * frames. The frame count should not be incremented before + * tryGetDataFrameInternal() can return the new frame. + * The frame count must be incremented before + * AnalysisDataModuleManager::notifyFrameFinish() is called. + * \endif + */ + virtual int frameCount() const = 0; + /*! \brief + * Access stored data. + * + * \param[in] index Zero-based frame index to access. + * \returns Frame reference to frame \p index, or an invalid + * reference if no such frame is available. + * + * Does not throw. Failure to access a frame with the given index is + * indicated through the return value. Negative \p index is allowed, + * and will always result in an invalid reference being returned. + * + * \see requestStorage() + * \see getDataFrame() + */ + AnalysisDataFrameRef tryGetDataFrame(int index) const; + /*! \brief + * Access stored data. + * + * \param[in] index Zero-based frame index to access. + * \returns Frame reference to frame \p index. + * \throws APIError if the requested frame is not accessible. + * + * If the data is not certainly available, use tryGetDataFrame(). + * + * \see requestStorage() + * \see tryGetDataFrame() + */ + AnalysisDataFrameRef getDataFrame(int index) const; + /*! \brief + * Request storage of frames. + * + * \param[in] nframes Request storing at least \c nframes previous + * frames (-1 = request storing all). Must be >= -1. + * \returns true if the request could be satisfied. + * + * If called multiple times, the largest request is honored. + * + * Does not throw. Failure to honor the request is indicated through + * the return value. + * + * \see getDataFrame() + * \see tryGetDataFrame() + */ + bool requestStorage(int nframes); - /*! \brief - * Adds a module to process the data. - * - * \param module Module to add. - * \throws std::bad_alloc if out of memory. - * \throws APIError if - * - \p module is not compatible with the data object - * - data has already been added to the data object and everything - * is not available through getDataFrame(). - * \throws unspecified Any exception thrown by \p module in its - * notification methods (if data has been added). - * - * If data has already been added to the data, the new module - * immediately processes all existing data. APIError is thrown - * if all data is not available through getDataFrame(). - * - * The caller can keep a copy of the module pointer if it requires - * later access to the module. - * - * If the method throws, the state of the data object is not changed. - * The state of the data module is indeterminate. - */ - void addModule(const AnalysisDataModulePointer &module); - /*! \brief - * Adds a module that processes only a subset of the columns. - * - * \param[in] col First column. - * \param[in] span Number of columns. - * \param module Module to add. - * - * Throws in the same situations as addModule(). - * - * Currently, all data sets are filtered using the same column mask. - * - * \todo - * This method doesn't currently work in all cases with multipoint - * data or with multiple data sets. In particular, if the added module - * requests storage and uses getDataFrame(), it will behave - * unpredictably (most likely asserts). - * - * \todo - * Generalize this method to multiple data sets (e.g., for adding - * modules that only process a single data set). - * - * \see addModule() - */ - void addColumnModule(int col, int span, const AnalysisDataModulePointer &module); - /*! \brief - * Applies a module to process data that is ready. - * - * \param module Module to apply. - * \throws APIError in same situations as addModule(). - * \throws unspecified Any exception thrown by \p module in its - * notification methods. - * - * This function works as addModule(), except that it does not keep a - * reference to \p module within the data object after it returns. - * Also, it can only be called after the data is ready, and only if - * getDataFrame() gives access to all of the data. - * It is provided for additional flexibility in postprocessing - * in-memory data. - * - * \todo - * Currently, this method may not work correctly if \p module requests - * storage (addModule() has the same problem if called after data is - * started). - */ - void applyModule(IAnalysisDataModule *module); + /*! \brief + * Adds a module to process the data. + * + * \param module Module to add. + * \throws std::bad_alloc if out of memory. + * \throws APIError if + * - \p module is not compatible with the data object + * - data has already been added to the data object and everything + * is not available through getDataFrame(). + * \throws unspecified Any exception thrown by \p module in its + * notification methods (if data has been added). + * + * If data has already been added to the data, the new module + * immediately processes all existing data. APIError is thrown + * if all data is not available through getDataFrame(). + * + * The caller can keep a copy of the module pointer if it requires + * later access to the module. + * + * If the method throws, the state of the data object is not changed. + * The state of the data module is indeterminate. + */ + void addModule(const AnalysisDataModulePointer& module); + /*! \brief + * Adds a module that processes only a subset of the columns. + * + * \param[in] col First column. + * \param[in] span Number of columns. + * \param module Module to add. + * + * Throws in the same situations as addModule(). + * + * Currently, all data sets are filtered using the same column mask. + * + * \todo + * This method doesn't currently work in all cases with multipoint + * data or with multiple data sets. In particular, if the added module + * requests storage and uses getDataFrame(), it will behave + * unpredictably (most likely asserts). + * + * \todo + * Generalize this method to multiple data sets (e.g., for adding + * modules that only process a single data set). + * + * \see addModule() + */ + void addColumnModule(int col, int span, const AnalysisDataModulePointer& module); + /*! \brief + * Applies a module to process data that is ready. + * + * \param module Module to apply. + * \throws APIError in same situations as addModule(). + * \throws unspecified Any exception thrown by \p module in its + * notification methods. + * + * This function works as addModule(), except that it does not keep a + * reference to \p module within the data object after it returns. + * Also, it can only be called after the data is ready, and only if + * getDataFrame() gives access to all of the data. + * It is provided for additional flexibility in postprocessing + * in-memory data. + * + * \todo + * Currently, this method may not work correctly if \p module requests + * storage (addModule() has the same problem if called after data is + * started). + */ + void applyModule(IAnalysisDataModule* module); - protected: - /*! \cond libapi */ - /*! \brief - * Initializes a new analysis data object. - * - * \throws std::bad_alloc if out of memory. - */ - AbstractAnalysisData(); +protected: + /*! \cond libapi */ + /*! \brief + * Initializes a new analysis data object. + * + * \throws std::bad_alloc if out of memory. + */ + AbstractAnalysisData(); - /*! \brief - * Sets the number of data sets. - * - * \param[in] dataSetCount Number of data sets (must be > 0). - * \throws std::bad_alloc if out of memory. - * \throws APIError if modules have been added that are not - * compatible with the new data set count. - * - * It not called, the data object has a single data set. Can be called - * only before AnalysisDataModuleManager::notifyDataStart(). - * Multiple calls are allowed before that point; the last call takes - * effect. - * - * Strong exception safety. - * - * \see dataSetCount() - */ - void setDataSetCount(int dataSetCount); - /*! \brief - * Sets the number of columns for a data set. - * - * \param[in] dataSet Zero-based index of the data set. - * \param[in] columnCount Number of columns in \p dataSet (must be > 0). - * \throws APIError if modules have been added that are not - * compatible with the new column count. - * - * Must be called at least once for each data set before - * AnalysisDataModuleManager::notifyDataStart(). Can be called only - * before AnalysisDataModuleManager::notifyDataStart(). - * Multiple calls are allowed before that point; the last call takes - * effect. - * - * Strong exception safety. - * - * \see columnCount() - */ - void setColumnCount(int dataSet, int columnCount); - /*! \brief - * Sets whether the data has multiple points per column in a frame. - * - * \param[in] bMultipoint Whether multiple points per column are - * possible. - * \throws APIError if modules have been added that are not - * compatible with the new setting. - * - * If not called, only a single point per column is allowed. Can be - * called only before AnalysisDataModuleManager::notifyDataStart(). - * Multiple calls are allowed before that point; the last call takes - * effect. - * - * Strong exception safety. - * - * \see isMultipoint() - */ - void setMultipoint(bool bMultipoint); + /*! \brief + * Sets the number of data sets. + * + * \param[in] dataSetCount Number of data sets (must be > 0). + * \throws std::bad_alloc if out of memory. + * \throws APIError if modules have been added that are not + * compatible with the new data set count. + * + * It not called, the data object has a single data set. Can be called + * only before AnalysisDataModuleManager::notifyDataStart(). + * Multiple calls are allowed before that point; the last call takes + * effect. + * + * Strong exception safety. + * + * \see dataSetCount() + */ + void setDataSetCount(int dataSetCount); + /*! \brief + * Sets the number of columns for a data set. + * + * \param[in] dataSet Zero-based index of the data set. + * \param[in] columnCount Number of columns in \p dataSet (must be > 0). + * \throws APIError if modules have been added that are not + * compatible with the new column count. + * + * Must be called at least once for each data set before + * AnalysisDataModuleManager::notifyDataStart(). Can be called only + * before AnalysisDataModuleManager::notifyDataStart(). + * Multiple calls are allowed before that point; the last call takes + * effect. + * + * Strong exception safety. + * + * \see columnCount() + */ + void setColumnCount(int dataSet, int columnCount); + /*! \brief + * Sets whether the data has multiple points per column in a frame. + * + * \param[in] bMultipoint Whether multiple points per column are + * possible. + * \throws APIError if modules have been added that are not + * compatible with the new setting. + * + * If not called, only a single point per column is allowed. Can be + * called only before AnalysisDataModuleManager::notifyDataStart(). + * Multiple calls are allowed before that point; the last call takes + * effect. + * + * Strong exception safety. + * + * \see isMultipoint() + */ + void setMultipoint(bool bMultipoint); - /*! \brief - * Implements access to data frames. - * - * \param[in] index Zero-based frame index to access. - * \returns Frame reference to frame \p index, or an invalid - * reference if no such frame is available. - * - * Must not throw. Failure to access a frame with the given index is - * indicated through the return value. - * - * Code in derived classes can assume that \p index is non-negative and - * less than frameCount(). - * - * Derived classes can choose to return an invalid reference if - * requestStorageInternal() has not been called at all, or if the frame - * is too old (compared to the value given to requestStorageInternal()). - * - * This method is called internally by tryGetDataFrame() and - * getDataFrame(). - * - * \see AnalysisDataStorage - */ - virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const = 0; - /*! \brief - * Implements storage requests. - * - * \param[in] nframes Request storing at least \c nframes previous - * frames (-1 = request storing all). Will be either -1 or >0. - * \returns true if the request could be satisfied. - * - * Must not throw. Failure to access a frame with the given index is - * indicated through the return value. - * - * Derived classes should be prepared for any number of calls to this - * method before notifyDataStart() is called (and during that call). - * - * This method is called internally by requestStorage(). - * - * \see AnalysisDataStorage - */ - virtual bool requestStorageInternal(int nframes) = 0; + /*! \brief + * Implements access to data frames. + * + * \param[in] index Zero-based frame index to access. + * \returns Frame reference to frame \p index, or an invalid + * reference if no such frame is available. + * + * Must not throw. Failure to access a frame with the given index is + * indicated through the return value. + * + * Code in derived classes can assume that \p index is non-negative and + * less than frameCount(). + * + * Derived classes can choose to return an invalid reference if + * requestStorageInternal() has not been called at all, or if the frame + * is too old (compared to the value given to requestStorageInternal()). + * + * This method is called internally by tryGetDataFrame() and + * getDataFrame(). + * + * \see AnalysisDataStorage + */ + virtual AnalysisDataFrameRef tryGetDataFrameInternal(int index) const = 0; + /*! \brief + * Implements storage requests. + * + * \param[in] nframes Request storing at least \c nframes previous + * frames (-1 = request storing all). Will be either -1 or >0. + * \returns true if the request could be satisfied. + * + * Must not throw. Failure to access a frame with the given index is + * indicated through the return value. + * + * Derived classes should be prepared for any number of calls to this + * method before notifyDataStart() is called (and during that call). + * + * This method is called internally by requestStorage(). + * + * \see AnalysisDataStorage + */ + virtual bool requestStorageInternal(int nframes) = 0; - //! Returns the module manager to use for calling notification methods. - AnalysisDataModuleManager &moduleManager(); - //! Returns the module manager to use for calling notification methods. - const AnalysisDataModuleManager &moduleManager() const; - //! \endcond + //! Returns the module manager to use for calling notification methods. + AnalysisDataModuleManager& moduleManager(); + //! Returns the module manager to use for calling notification methods. + const AnalysisDataModuleManager& moduleManager() const; + //! \endcond - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/analysisdata.cpp b/src/gromacs/analysisdata/analysisdata.cpp index 9ad7136a43..5fe4e5fa7b 100644 --- a/src/gromacs/analysisdata/analysisdata.cpp +++ b/src/gromacs/analysisdata/analysisdata.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,20 +69,17 @@ namespace internal */ class AnalysisDataHandleImpl { - public: - //! Creates a handle associated with the given data object. - explicit AnalysisDataHandleImpl(AnalysisData *data) - : data_(*data), currentFrame_(nullptr) - { - } - - //! The data object that this handle belongs to. - AnalysisData &data_; - //! Current storage frame object, or NULL if no current frame. - AnalysisDataStorageFrame *currentFrame_; +public: + //! Creates a handle associated with the given data object. + explicit AnalysisDataHandleImpl(AnalysisData* data) : data_(*data), currentFrame_(nullptr) {} + + //! The data object that this handle belongs to. + AnalysisData& data_; + //! Current storage frame object, or NULL if no current frame. + AnalysisDataStorageFrame* currentFrame_; }; -} // namespace internal +} // namespace internal /******************************************************************** * AnalysisData::Impl @@ -94,41 +92,34 @@ class AnalysisDataHandleImpl */ class AnalysisData::Impl { - public: - //! Smart pointer type to manage a data handle implementation. - typedef std::unique_ptr - HandlePointer; - //! Shorthand for a list of data handles. - typedef std::vector HandleList; - - //! Storage implementation. - AnalysisDataStorage storage_; - /*! \brief - * List of handles for this data object. - * - * Note that AnalysisDataHandle objects also contain (raw) pointers - * to these objects. - */ - HandleList handles_; +public: + //! Smart pointer type to manage a data handle implementation. + typedef std::unique_ptr HandlePointer; + //! Shorthand for a list of data handles. + typedef std::vector HandleList; + + //! Storage implementation. + AnalysisDataStorage storage_; + /*! \brief + * List of handles for this data object. + * + * Note that AnalysisDataHandle objects also contain (raw) pointers + * to these objects. + */ + HandleList handles_; }; /******************************************************************** * AnalysisData */ -AnalysisData::AnalysisData() - : impl_(new Impl) -{ -} +AnalysisData::AnalysisData() : impl_(new Impl) {} -AnalysisData::~AnalysisData() -{ -} +AnalysisData::~AnalysisData() {} -void -AnalysisData::setDataSetCount(int dataSetCount) +void AnalysisData::setDataSetCount(int dataSetCount) { GMX_RELEASE_ASSERT(impl_->handles_.empty(), "Cannot change data dimensionality after creating handles"); @@ -136,8 +127,7 @@ AnalysisData::setDataSetCount(int dataSetCount) } -void -AnalysisData::setColumnCount(int dataSet, int columnCount) +void AnalysisData::setColumnCount(int dataSet, int columnCount) { GMX_RELEASE_ASSERT(impl_->handles_.empty(), "Cannot change data dimensionality after creating handles"); @@ -145,24 +135,20 @@ AnalysisData::setColumnCount(int dataSet, int columnCount) } -void -AnalysisData::setMultipoint(bool bMultipoint) +void AnalysisData::setMultipoint(bool bMultipoint) { - GMX_RELEASE_ASSERT(impl_->handles_.empty(), - "Cannot change data type after creating handles"); + GMX_RELEASE_ASSERT(impl_->handles_.empty(), "Cannot change data type after creating handles"); AbstractAnalysisData::setMultipoint(bMultipoint); } -int -AnalysisData::frameCount() const +int AnalysisData::frameCount() const { return impl_->storage_.frameCount(); } -AnalysisDataHandle -AnalysisData::startData(const AnalysisDataParallelOptions &opt) +AnalysisDataHandle AnalysisData::startData(const AnalysisDataParallelOptions& opt) { GMX_RELEASE_ASSERT(impl_->handles_.size() < static_cast(opt.parallelizationFactor()), "Too many calls to startData() compared to provided options"); @@ -177,15 +163,13 @@ AnalysisData::startData(const AnalysisDataParallelOptions &opt) } -void -AnalysisData::finishFrameSerial(int frameIndex) +void AnalysisData::finishFrameSerial(int frameIndex) { impl_->storage_.finishFrameSerial(frameIndex); } -void -AnalysisData::finishData(AnalysisDataHandle handle) +void AnalysisData::finishData(AnalysisDataHandle handle) { Impl::HandleList::iterator i; @@ -196,8 +180,7 @@ AnalysisData::finishData(AnalysisDataHandle handle) break; } } - GMX_RELEASE_ASSERT(i != impl_->handles_.end(), - "finishData() called for an unknown handle"); + GMX_RELEASE_ASSERT(i != impl_->handles_.end(), "finishData() called for an unknown handle"); impl_->handles_.erase(i); @@ -208,15 +191,13 @@ AnalysisData::finishData(AnalysisDataHandle handle) } -AnalysisDataFrameRef -AnalysisData::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AnalysisData::tryGetDataFrameInternal(int index) const { return impl_->storage_.tryGetDataFrame(index); } -bool -AnalysisData::requestStorageInternal(int nframes) +bool AnalysisData::requestStorageInternal(int nframes) { return impl_->storage_.requestStorage(nframes); } @@ -226,31 +207,22 @@ AnalysisData::requestStorageInternal(int nframes) * AnalysisDataHandle */ -AnalysisDataHandle::AnalysisDataHandle() - : impl_(nullptr) -{ -} +AnalysisDataHandle::AnalysisDataHandle() : impl_(nullptr) {} -AnalysisDataHandle::AnalysisDataHandle(internal::AnalysisDataHandleImpl *impl) - : impl_(impl) -{ -} +AnalysisDataHandle::AnalysisDataHandle(internal::AnalysisDataHandleImpl* impl) : impl_(impl) {} -void -AnalysisDataHandle::startFrame(int index, real x, real dx) +void AnalysisDataHandle::startFrame(int index, real x, real dx) { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ == nullptr, "startFrame() called twice without calling finishFrame()"); - impl_->currentFrame_ = - &impl_->data_.impl_->storage_.startFrame(index, x, dx); + impl_->currentFrame_ = &impl_->data_.impl_->storage_.startFrame(index, x, dx); } -void -AnalysisDataHandle::selectDataSet(int index) +void AnalysisDataHandle::selectDataSet(int index) { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ != nullptr, @@ -259,8 +231,7 @@ AnalysisDataHandle::selectDataSet(int index) } -void -AnalysisDataHandle::setPoint(int column, real value, bool bPresent) +void AnalysisDataHandle::setPoint(int column, real value, bool bPresent) { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ != nullptr, @@ -269,8 +240,7 @@ AnalysisDataHandle::setPoint(int column, real value, bool bPresent) } -void -AnalysisDataHandle::setPoint(int column, real value, real error, bool bPresent) +void AnalysisDataHandle::setPoint(int column, real value, real error, bool bPresent) { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ != nullptr, @@ -279,9 +249,7 @@ AnalysisDataHandle::setPoint(int column, real value, real error, bool bPresent) } -void -AnalysisDataHandle::setPoints(int firstColumn, int count, const real *values, - bool bPresent) +void AnalysisDataHandle::setPoints(int firstColumn, int count, const real* values, bool bPresent) { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ != nullptr, @@ -293,8 +261,7 @@ AnalysisDataHandle::setPoints(int firstColumn, int count, const real *values, } -void -AnalysisDataHandle::finishPointSet() +void AnalysisDataHandle::finishPointSet() { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->data_.isMultipoint(), @@ -305,20 +272,18 @@ AnalysisDataHandle::finishPointSet() } -void -AnalysisDataHandle::finishFrame() +void AnalysisDataHandle::finishFrame() { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); GMX_RELEASE_ASSERT(impl_->currentFrame_ != nullptr, "finishFrame() called without calling startFrame()"); - AnalysisDataStorageFrame *frame = impl_->currentFrame_; - impl_->currentFrame_ = nullptr; + AnalysisDataStorageFrame* frame = impl_->currentFrame_; + impl_->currentFrame_ = nullptr; frame->finishFrame(); } -void -AnalysisDataHandle::finishData() +void AnalysisDataHandle::finishData() { GMX_RELEASE_ASSERT(impl_ != nullptr, "Invalid data handle used"); // Deletes the implementation pointer. diff --git a/src/gromacs/analysisdata/analysisdata.h b/src/gromacs/analysisdata/analysisdata.h index f68b6ca2b5..0c74baf712 100644 --- a/src/gromacs/analysisdata/analysisdata.h +++ b/src/gromacs/analysisdata/analysisdata.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -89,125 +90,125 @@ class AnalysisDataParallelOptions; */ class AnalysisData : public AbstractAnalysisData { - public: - /*! \brief - * Creates an empty analysis data object. - * - * \throws std::bad_alloc if out of memory. - */ - AnalysisData(); - ~AnalysisData() override; +public: + /*! \brief + * Creates an empty analysis data object. + * + * \throws std::bad_alloc if out of memory. + */ + AnalysisData(); + ~AnalysisData() override; - /*! \brief - * Sets the number of data sets. - * - * \param[in] dataSetCount Number of data sets (must be > 0). - * \throws std::bad_alloc if out of memory. - * \throws APIError if modules have been added that are not - * compatible with the new data set count. - * - * Must not be called after startData() has been called. - * If not called, a single data set is assumed. - * If called multiple times, the last call takes effect. - */ - void setDataSetCount(int dataSetCount); - /*! \brief - * Sets the number of columns in a data set. - * - * \param[in] dataSet Zero-based data set index. - * \param[in] columnCount Number of columns in the data (must be > 0). - * \throws APIError if modules have been added that are not - * compatible with the new column count. - * - * Must be called before startData() for each data set. - * Must not be called after startData() has been called. - * If called multiple times for a data set, the last call takes effect. - */ - void setColumnCount(int dataSet, int columnCount); - /*! \brief - * Sets whether the data contains multiple points per column per frame. - * - * \param[in] bMultipoint Whether the data will allow multiple points - * per column within a single frame. - * \throws APIError if modules have been added that are not - * compatible with the new setting. - * - * If this method is not called, the data is not multipoint. - * - * Must not be called after startData() has been called. - * - * \see isMultipoint() - */ - void setMultipoint(bool bMultipoint); + /*! \brief + * Sets the number of data sets. + * + * \param[in] dataSetCount Number of data sets (must be > 0). + * \throws std::bad_alloc if out of memory. + * \throws APIError if modules have been added that are not + * compatible with the new data set count. + * + * Must not be called after startData() has been called. + * If not called, a single data set is assumed. + * If called multiple times, the last call takes effect. + */ + void setDataSetCount(int dataSetCount); + /*! \brief + * Sets the number of columns in a data set. + * + * \param[in] dataSet Zero-based data set index. + * \param[in] columnCount Number of columns in the data (must be > 0). + * \throws APIError if modules have been added that are not + * compatible with the new column count. + * + * Must be called before startData() for each data set. + * Must not be called after startData() has been called. + * If called multiple times for a data set, the last call takes effect. + */ + void setColumnCount(int dataSet, int columnCount); + /*! \brief + * Sets whether the data contains multiple points per column per frame. + * + * \param[in] bMultipoint Whether the data will allow multiple points + * per column within a single frame. + * \throws APIError if modules have been added that are not + * compatible with the new setting. + * + * If this method is not called, the data is not multipoint. + * + * Must not be called after startData() has been called. + * + * \see isMultipoint() + */ + void setMultipoint(bool bMultipoint); - int frameCount() const override; + int frameCount() const override; - /*! \brief - * Creates a handle for adding data. - * - * \param[in] opt Options for setting how this handle will be - * used. - * \returns The created handle. - * \throws std::bad_alloc if out of memory. - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::dataStarted(). - * - * The caller should retain the returned handle (or a copy of it), and - * pass it to finishData() after successfully adding all data. - * The caller should discard the returned handle if an error occurs; - * memory allocated for the handle will be freed when the AnalysisData - * object is destroyed. - * - * The \p opt options should be the same for all calls to this method, - * and the number of calls should match the parallelization factor - * defined in \p opt. - */ - AnalysisDataHandle startData(const AnalysisDataParallelOptions &opt); - /*! \brief - * Performs in-order sequential processing for the next frame. - * - * \param[in] frameIndex Index of the frame that has been finished. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::frameFinishedSerial(). - * - * This method should be called sequentially for each frame, after data - * for that frame has been produced. It is not necessary to call this - * method if there is no parallelism, i.e., if only a single data - * handle is created and the parallelization options provided at that - * time do not indicate parallelism. - */ - void finishFrameSerial(int frameIndex); - /*! \brief - * Destroys a handle after all data has been added. - * - * \param[in] handle Handle to destroy. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::dataFinished(). - * - * \p handle must have been obtained from startData() of this object. - * The order of the calls with respect to the corresponding startData() - * calls is not important. - * - * The \p handle (and any copies) are invalid after the call. - */ - void finishData(AnalysisDataHandle handle); + /*! \brief + * Creates a handle for adding data. + * + * \param[in] opt Options for setting how this handle will be + * used. + * \returns The created handle. + * \throws std::bad_alloc if out of memory. + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::dataStarted(). + * + * The caller should retain the returned handle (or a copy of it), and + * pass it to finishData() after successfully adding all data. + * The caller should discard the returned handle if an error occurs; + * memory allocated for the handle will be freed when the AnalysisData + * object is destroyed. + * + * The \p opt options should be the same for all calls to this method, + * and the number of calls should match the parallelization factor + * defined in \p opt. + */ + AnalysisDataHandle startData(const AnalysisDataParallelOptions& opt); + /*! \brief + * Performs in-order sequential processing for the next frame. + * + * \param[in] frameIndex Index of the frame that has been finished. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::frameFinishedSerial(). + * + * This method should be called sequentially for each frame, after data + * for that frame has been produced. It is not necessary to call this + * method if there is no parallelism, i.e., if only a single data + * handle is created and the parallelization options provided at that + * time do not indicate parallelism. + */ + void finishFrameSerial(int frameIndex); + /*! \brief + * Destroys a handle after all data has been added. + * + * \param[in] handle Handle to destroy. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::dataFinished(). + * + * \p handle must have been obtained from startData() of this object. + * The order of the calls with respect to the corresponding startData() + * calls is not important. + * + * The \p handle (and any copies) are invalid after the call. + */ + void finishData(AnalysisDataHandle handle); - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - class Impl; + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - friend class AnalysisDataHandle; + friend class AnalysisDataHandle; }; namespace internal { class AnalysisDataHandleImpl; -} // namespace internal +} // namespace internal /*! \brief * Handle for inserting data into AnalysisData. @@ -245,145 +246,145 @@ class AnalysisDataHandleImpl; */ class AnalysisDataHandle { - public: - /*! \brief - * Constructs an invalid data handle. - * - * This constructor is provided for convenience in cases where it is - * easiest to declare an AnalysisDataHandle without immediately - * assigning a value to it. Any attempt to call methods without first - * assigning a value from AnalysisData::startData() to the handle - * causes an assert. - * - * Does not throw. - */ - AnalysisDataHandle(); +public: + /*! \brief + * Constructs an invalid data handle. + * + * This constructor is provided for convenience in cases where it is + * easiest to declare an AnalysisDataHandle without immediately + * assigning a value to it. Any attempt to call methods without first + * assigning a value from AnalysisData::startData() to the handle + * causes an assert. + * + * Does not throw. + */ + AnalysisDataHandle(); - //! Returns whether this data handle is valid. - bool isValid() const { return impl_ != nullptr; } + //! Returns whether this data handle is valid. + bool isValid() const { return impl_ != nullptr; } - /*! \brief - * Start data for a new frame. - * - * \param[in] index Zero-based index for the frame to start. - * \param[in] x x value for the frame. - * \param[in] dx Error in x for the frame if applicable. - * - * \throws unspecified Any exception thrown by attached data - * modules in IAnalysisDataModule::frameStarted(). - * - * Each \p index value 0, 1, ..., N (where N is the total number of - * frames) should be started exactly once by exactly one handle of an - * AnalysisData object. The frames may be started out of order, but - * currently the implementation places some limitations on how far - * the index can be in the future (as counted from the first frame that - * is not finished). - */ - void startFrame(int index, real x, real dx = 0.0); - /*! \brief - * Selects a data set for subsequent setPoint()/setPoints() calls. - * - * \param[in] index Zero-based data set index. - * - * After startFrame(), the first data set is always selected. - * The set value is remembered until the end of the current frame, also - * across finishPointSet() calls. - * - * Does not throw. - */ - void selectDataSet(int index); - /*! \brief - * Set a value for a single column for the current frame. - * - * \param[in] column Zero-based column index. - * \param[in] value Value to set for the column. - * \param[in] bPresent Present flag to set for the column. - * - * If called multiple times for a column (within one point set for - * multipoint data), old values are overwritten. - * - * Does not throw. - */ - void setPoint(int column, real value, bool bPresent = true); - /*! \brief - * Set a value and its error estimate for a single column for the - * current frame. - * - * \param[in] column Zero-based column index. - * \param[in] value Value to set for the column. - * \param[in] error Error estimate to set for the column. - * \param[in] bPresent Present flag to set for the column. - * - * If called multiple times for a column (within one point set for - * multipoint data), old values are overwritten. - * - * Does not throw. - */ - void setPoint(int column, real value, real error, bool bPresent = true); - /*! \brief - * Set values for consecutive columns for the current frame. - * - * \param[in] firstColumn Zero-based column index. - * \param[in] count Number of columns to set. - * \param[in] values Value array of \p column items. - * \param[in] bPresent Present flag to set for the column. - * - * Equivalent to calling setPoint(firstColumn + i, values[i], bPresent) for - * i from 0 to count. - * - * Does not throw. - */ - void setPoints(int firstColumn, int count, const real *values, bool bPresent = true); - /*! \brief - * Finish data for the current point set. - * - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data - * modules in IAnalysisDataModule::pointsAdded(). - * - * Must be called after each point set for multipoint data, including - * the last (i.e., no values must be set between the last call to this - * method and AnalysisDataStorage::finishFrame()). - * Must not be called for non-multipoint data. - */ - void finishPointSet(); - /*! \brief - * Finish data for the current frame. - * - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data - * modules in frame notification methods. - */ - void finishFrame(); - //! Calls AnalysisData::finishData() for this handle. - void finishData(); + /*! \brief + * Start data for a new frame. + * + * \param[in] index Zero-based index for the frame to start. + * \param[in] x x value for the frame. + * \param[in] dx Error in x for the frame if applicable. + * + * \throws unspecified Any exception thrown by attached data + * modules in IAnalysisDataModule::frameStarted(). + * + * Each \p index value 0, 1, ..., N (where N is the total number of + * frames) should be started exactly once by exactly one handle of an + * AnalysisData object. The frames may be started out of order, but + * currently the implementation places some limitations on how far + * the index can be in the future (as counted from the first frame that + * is not finished). + */ + void startFrame(int index, real x, real dx = 0.0); + /*! \brief + * Selects a data set for subsequent setPoint()/setPoints() calls. + * + * \param[in] index Zero-based data set index. + * + * After startFrame(), the first data set is always selected. + * The set value is remembered until the end of the current frame, also + * across finishPointSet() calls. + * + * Does not throw. + */ + void selectDataSet(int index); + /*! \brief + * Set a value for a single column for the current frame. + * + * \param[in] column Zero-based column index. + * \param[in] value Value to set for the column. + * \param[in] bPresent Present flag to set for the column. + * + * If called multiple times for a column (within one point set for + * multipoint data), old values are overwritten. + * + * Does not throw. + */ + void setPoint(int column, real value, bool bPresent = true); + /*! \brief + * Set a value and its error estimate for a single column for the + * current frame. + * + * \param[in] column Zero-based column index. + * \param[in] value Value to set for the column. + * \param[in] error Error estimate to set for the column. + * \param[in] bPresent Present flag to set for the column. + * + * If called multiple times for a column (within one point set for + * multipoint data), old values are overwritten. + * + * Does not throw. + */ + void setPoint(int column, real value, real error, bool bPresent = true); + /*! \brief + * Set values for consecutive columns for the current frame. + * + * \param[in] firstColumn Zero-based column index. + * \param[in] count Number of columns to set. + * \param[in] values Value array of \p column items. + * \param[in] bPresent Present flag to set for the column. + * + * Equivalent to calling setPoint(firstColumn + i, values[i], bPresent) for + * i from 0 to count. + * + * Does not throw. + */ + void setPoints(int firstColumn, int count, const real* values, bool bPresent = true); + /*! \brief + * Finish data for the current point set. + * + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data + * modules in IAnalysisDataModule::pointsAdded(). + * + * Must be called after each point set for multipoint data, including + * the last (i.e., no values must be set between the last call to this + * method and AnalysisDataStorage::finishFrame()). + * Must not be called for non-multipoint data. + */ + void finishPointSet(); + /*! \brief + * Finish data for the current frame. + * + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data + * modules in frame notification methods. + */ + void finishFrame(); + //! Calls AnalysisData::finishData() for this handle. + void finishData(); - private: - /*! \brief - * Creates a new data handle associated with \p data. - * - * \param impl Data to associate the handle with. - * - * The constructor is private because data handles should only be - * constructed through AnalysisData::startData(). - * - * Does not throw. - */ - explicit AnalysisDataHandle(internal::AnalysisDataHandleImpl *impl); +private: + /*! \brief + * Creates a new data handle associated with \p data. + * + * \param impl Data to associate the handle with. + * + * The constructor is private because data handles should only be + * constructed through AnalysisData::startData(). + * + * Does not throw. + */ + explicit AnalysisDataHandle(internal::AnalysisDataHandleImpl* impl); - /*! \brief - * Pointer to the internal implementation class. - * - * The memory for this object is managed by the AnalysisData object, - * and AnalysisDataHandle simply provides a public interface for - * accessing the implementation. - */ - internal::AnalysisDataHandleImpl *impl_; + /*! \brief + * Pointer to the internal implementation class. + * + * The memory for this object is managed by the AnalysisData object, + * and AnalysisDataHandle simply provides a public interface for + * accessing the implementation. + */ + internal::AnalysisDataHandleImpl* impl_; - /*! \brief - * Needed to access the non-public implementation. - */ - friend class AnalysisData; + /*! \brief + * Needed to access the non-public implementation. + */ + friend class AnalysisData; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/arraydata.cpp b/src/gromacs/analysisdata/arraydata.cpp index 8be6b94614..691a63a2a7 100644 --- a/src/gromacs/analysisdata/arraydata.cpp +++ b/src/gromacs/analysisdata/arraydata.cpp @@ -53,58 +53,50 @@ namespace gmx { -AbstractAnalysisArrayData::AbstractAnalysisArrayData() - : rowCount_(0), pointSetInfo_(0, 0, 0, 0), xstep_(1.0), - bUniformX_(true), bReady_(false) +AbstractAnalysisArrayData::AbstractAnalysisArrayData() : + rowCount_(0), + pointSetInfo_(0, 0, 0, 0), + xstep_(1.0), + bUniformX_(true), + bReady_(false) { xvalue_.push_back(0); } -AbstractAnalysisArrayData::~AbstractAnalysisArrayData() -{ -} +AbstractAnalysisArrayData::~AbstractAnalysisArrayData() {} -AnalysisDataFrameRef -AbstractAnalysisArrayData::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AbstractAnalysisArrayData::tryGetDataFrameInternal(int index) const { if (!isAllocated()) { return AnalysisDataFrameRef(); } - return AnalysisDataFrameRef( - AnalysisDataFrameHeader(index, xvalue(index), 0.0), - makeConstArrayRef(value_). - subArray(index * columnCount(), columnCount()), - constArrayRefFromArray(&pointSetInfo_, 1)); + return AnalysisDataFrameRef(AnalysisDataFrameHeader(index, xvalue(index), 0.0), + makeConstArrayRef(value_).subArray(index * columnCount(), columnCount()), + constArrayRefFromArray(&pointSetInfo_, 1)); } -bool -AbstractAnalysisArrayData::requestStorageInternal(int /*nframes*/) +bool AbstractAnalysisArrayData::requestStorageInternal(int /*nframes*/) { return true; } -void -AbstractAnalysisArrayData::setColumnCount(int ncols) +void AbstractAnalysisArrayData::setColumnCount(int ncols) { - GMX_RELEASE_ASSERT(!isAllocated(), - "Cannot change column count after data has been allocated"); + GMX_RELEASE_ASSERT(!isAllocated(), "Cannot change column count after data has been allocated"); AbstractAnalysisData::setColumnCount(0, ncols); pointSetInfo_ = AnalysisDataPointSetInfo(0, ncols, 0, 0); } -void -AbstractAnalysisArrayData::setRowCount(int rowCount) +void AbstractAnalysisArrayData::setRowCount(int rowCount) { GMX_RELEASE_ASSERT(rowCount > 0, "Invalid number of rows"); - GMX_RELEASE_ASSERT(!isAllocated(), - "Cannot change row count after data has been allocated"); - GMX_RELEASE_ASSERT(bUniformX_ || xvalue_.empty() - || rowCount == ssize(xvalue_), + GMX_RELEASE_ASSERT(!isAllocated(), "Cannot change row count after data has been allocated"); + GMX_RELEASE_ASSERT(bUniformX_ || xvalue_.empty() || rowCount == ssize(xvalue_), "X axis set with setXAxisValue() does not match the row count"); xvalue_.resize(rowCount); if (bUniformX_ && rowCount > rowCount_) @@ -118,8 +110,7 @@ AbstractAnalysisArrayData::setRowCount(int rowCount) } -void -AbstractAnalysisArrayData::allocateValues() +void AbstractAnalysisArrayData::allocateValues() { GMX_RELEASE_ASSERT(!isAllocated(), "Can only allocate values once"); GMX_RELEASE_ASSERT(rowCount() > 0 && columnCount() > 0, @@ -133,8 +124,7 @@ AbstractAnalysisArrayData::allocateValues() } -void -AbstractAnalysisArrayData::setXAxis(real start, real step) +void AbstractAnalysisArrayData::setXAxis(real start, real step) { GMX_RELEASE_ASSERT(!bReady_, "X axis cannot be set after data is finished"); xvalue_[0] = start; @@ -147,8 +137,7 @@ AbstractAnalysisArrayData::setXAxis(real start, real step) } -void -AbstractAnalysisArrayData::setXAxisValue(int row, real value) +void AbstractAnalysisArrayData::setXAxisValue(int row, real value) { GMX_RELEASE_ASSERT(!bReady_, "X axis cannot be set after data is finished"); if (rowCount_ > 0) @@ -165,8 +154,7 @@ AbstractAnalysisArrayData::setXAxisValue(int row, real value) } -void -AbstractAnalysisArrayData::valuesReady() +void AbstractAnalysisArrayData::valuesReady() { GMX_RELEASE_ASSERT(isAllocated(), "There must be some data"); if (bReady_) @@ -175,30 +163,26 @@ AbstractAnalysisArrayData::valuesReady() } bReady_ = true; - AnalysisDataModuleManager &modules = moduleManager(); + AnalysisDataModuleManager& modules = moduleManager(); modules.notifyDataStart(this); for (int i = 0; i < rowCount(); ++i) { AnalysisDataFrameHeader header(i, xvalue(i), 0); modules.notifyFrameStart(header); - modules.notifyPointsAdd( - AnalysisDataPointSetRef( - header, pointSetInfo_, - makeConstArrayRef(value_). - subArray(i*columnCount(), columnCount()))); + modules.notifyPointsAdd(AnalysisDataPointSetRef( + header, pointSetInfo_, + makeConstArrayRef(value_).subArray(i * columnCount(), columnCount()))); modules.notifyFrameFinish(header); } modules.notifyDataFinish(); } -void -AbstractAnalysisArrayData::copyContents(const AbstractAnalysisArrayData *src, - AbstractAnalysisArrayData *dest) +void AbstractAnalysisArrayData::copyContents(const AbstractAnalysisArrayData* src, + AbstractAnalysisArrayData* dest) { GMX_RELEASE_ASSERT(src->isAllocated(), "Source data must not be empty"); - GMX_RELEASE_ASSERT(!dest->isAllocated(), - "Destination data must not be allocated"); + GMX_RELEASE_ASSERT(!dest->isAllocated(), "Destination data must not be allocated"); dest->setColumnCount(src->columnCount()); dest->setRowCount(src->rowCount()); dest->allocateValues(); diff --git a/src/gromacs/analysisdata/arraydata.h b/src/gromacs/analysisdata/arraydata.h index 77a7c93ef9..7b1e72d165 100644 --- a/src/gromacs/analysisdata/arraydata.h +++ b/src/gromacs/analysisdata/arraydata.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,152 +72,148 @@ namespace gmx */ class AbstractAnalysisArrayData : public AbstractAnalysisData { - public: - ~AbstractAnalysisArrayData() override; +public: + ~AbstractAnalysisArrayData() override; - int frameCount() const override - { - return bReady_ ? rowCount_ : 0; - } + int frameCount() const override { return bReady_ ? rowCount_ : 0; } - /*! \brief - * Returns the number of rows in the data array. - * - * This function is identical to frameCount(), except that frameCount() - * returns 0 before valuesReady() has been called. - */ - int rowCount() const { return rowCount_; } - //! Returns true if values have been allocated. - bool isAllocated() const { return !value_.empty(); } - //! Returns the x value of the first frame. - real xstart() const { return xvalue_[0]; } - //! Returns the step between frame x values. - real xstep() const - { - GMX_ASSERT(bUniformX_, "Accessing x step for non-uniform data"); - return xstep_; - } - //! Returns the x value of a row. - real xvalue(int row) const - { - GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); - return xvalue_[row]; - } - //! Returns a given array element. - const AnalysisDataValue &value(int row, int col) const - { - GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); - GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range"); - GMX_ASSERT(isAllocated(), "Data array not allocated"); - return value_[row * columnCount() + col]; - } + /*! \brief + * Returns the number of rows in the data array. + * + * This function is identical to frameCount(), except that frameCount() + * returns 0 before valuesReady() has been called. + */ + int rowCount() const { return rowCount_; } + //! Returns true if values have been allocated. + bool isAllocated() const { return !value_.empty(); } + //! Returns the x value of the first frame. + real xstart() const { return xvalue_[0]; } + //! Returns the step between frame x values. + real xstep() const + { + GMX_ASSERT(bUniformX_, "Accessing x step for non-uniform data"); + return xstep_; + } + //! Returns the x value of a row. + real xvalue(int row) const + { + GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); + return xvalue_[row]; + } + //! Returns a given array element. + const AnalysisDataValue& value(int row, int col) const + { + GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); + GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range"); + GMX_ASSERT(isAllocated(), "Data array not allocated"); + return value_[row * columnCount() + col]; + } - protected: - /*! \brief - * Initializes an empty array data object. - * - * \throws std::bad_alloc if out of memory. - */ - AbstractAnalysisArrayData(); +protected: + /*! \brief + * Initializes an empty array data object. + * + * \throws std::bad_alloc if out of memory. + */ + AbstractAnalysisArrayData(); - /*! \brief - * Sets the number of columns in the data array. - * - * \param[in] ncols Number of columns in the data. - * - * Cannot be called after allocateValues(). - * - * See AbstractAnalysisData::setColumnCount() for exception behavior. - */ - void setColumnCount(int ncols); - /*! \brief - * Sets the number of rows in the data array. - * - * \param[in] rowCount Number of rows in the data. - * - * Cannot be called after allocateValues(). - * - * Does not throw. - */ - void setRowCount(int rowCount); - /*! \brief - * Allocates memory for the values. - * - * \throws std::bad_alloc if memory allocation fails. - * - * setColumnCount() and setRowCount() must have been called. - * - * Strong exception safety guarantee. - */ - void allocateValues(); - /*! \brief - * Sets the values reported as x values for frames. - * - * \param[in] start x value for the first frame. - * \param[in] step Step between x values of successive frames. - * - * Must not be called after valuesReady(). - * Any values set with setXAxisValue() are overwritten. - * - * Does not throw. - */ - void setXAxis(real start, real step); - /*! \brief - * Sets a single value reported as x value for frames. - * - * \param[in] row Row/frame for which to set the value. - * \param[in] value x value for the frame specified by \p row. - * - * Must not be called after valuesReady(). - * - * Does not throw. - */ - void setXAxisValue(int row, real value); - //! Returns a reference to a given array element. - AnalysisDataValue &value(int row, int col) - { - GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); - GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range"); - GMX_ASSERT(isAllocated(), "Data array not allocated"); - return value_[row * columnCount() + col]; - } - /*! \brief - * Notifies modules of the data. - * - * \throws unspecified Any exception thrown by attached data modules - * in data notification methods. - * - * This function should be called once the values in the array - * have been initialized. The values should not be changed after this - * function has been called. - */ - void valuesReady(); + /*! \brief + * Sets the number of columns in the data array. + * + * \param[in] ncols Number of columns in the data. + * + * Cannot be called after allocateValues(). + * + * See AbstractAnalysisData::setColumnCount() for exception behavior. + */ + void setColumnCount(int ncols); + /*! \brief + * Sets the number of rows in the data array. + * + * \param[in] rowCount Number of rows in the data. + * + * Cannot be called after allocateValues(). + * + * Does not throw. + */ + void setRowCount(int rowCount); + /*! \brief + * Allocates memory for the values. + * + * \throws std::bad_alloc if memory allocation fails. + * + * setColumnCount() and setRowCount() must have been called. + * + * Strong exception safety guarantee. + */ + void allocateValues(); + /*! \brief + * Sets the values reported as x values for frames. + * + * \param[in] start x value for the first frame. + * \param[in] step Step between x values of successive frames. + * + * Must not be called after valuesReady(). + * Any values set with setXAxisValue() are overwritten. + * + * Does not throw. + */ + void setXAxis(real start, real step); + /*! \brief + * Sets a single value reported as x value for frames. + * + * \param[in] row Row/frame for which to set the value. + * \param[in] value x value for the frame specified by \p row. + * + * Must not be called after valuesReady(). + * + * Does not throw. + */ + void setXAxisValue(int row, real value); + //! Returns a reference to a given array element. + AnalysisDataValue& value(int row, int col) + { + GMX_ASSERT(row >= 0 && row < rowCount(), "Row index out of range"); + GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range"); + GMX_ASSERT(isAllocated(), "Data array not allocated"); + return value_[row * columnCount() + col]; + } + /*! \brief + * Notifies modules of the data. + * + * \throws unspecified Any exception thrown by attached data modules + * in data notification methods. + * + * This function should be called once the values in the array + * have been initialized. The values should not be changed after this + * function has been called. + */ + void valuesReady(); - /*! \brief - * Copies the contents into a new object. - * - * \param[in] src Object to copy data from. - * \param[in,out] dest Empty array data object to copy data to. - * \throws std::bad_alloc if memory allocation for \p dest fails. - * - * \p dest should not have previous contents. - */ - static void copyContents(const AbstractAnalysisArrayData *src, - AbstractAnalysisArrayData *dest); + /*! \brief + * Copies the contents into a new object. + * + * \param[in] src Object to copy data from. + * \param[in,out] dest Empty array data object to copy data to. + * \throws std::bad_alloc if memory allocation for \p dest fails. + * + * \p dest should not have previous contents. + */ + static void copyContents(const AbstractAnalysisArrayData* src, AbstractAnalysisArrayData* dest); - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - int rowCount_; - AnalysisDataPointSetInfo pointSetInfo_; - std::vector value_; - std::vector xvalue_; - real xstep_; - bool bUniformX_; - bool bReady_; + int rowCount_; + AnalysisDataPointSetInfo pointSetInfo_; + std::vector value_; + std::vector xvalue_; + real xstep_; + bool bUniformX_; + bool bReady_; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; /*! \brief @@ -239,25 +235,25 @@ class AbstractAnalysisArrayData : public AbstractAnalysisData */ class AnalysisArrayData : public AbstractAnalysisArrayData { - public: - /*! \brief - * Initializes an empty array data object. - * - * \throws std::bad_alloc if out of memory. - */ - AnalysisArrayData() {} +public: + /*! \brief + * Initializes an empty array data object. + * + * \throws std::bad_alloc if out of memory. + */ + AnalysisArrayData() {} - // TODO: These statements cause Doxygen to generate confusing - // documentation. - using AbstractAnalysisArrayData::setColumnCount; - using AbstractAnalysisArrayData::setRowCount; - using AbstractAnalysisArrayData::allocateValues; - using AbstractAnalysisArrayData::setXAxis; - using AbstractAnalysisArrayData::setXAxisValue; - using AbstractAnalysisArrayData::value; - using AbstractAnalysisArrayData::valuesReady; + // TODO: These statements cause Doxygen to generate confusing + // documentation. + using AbstractAnalysisArrayData::allocateValues; + using AbstractAnalysisArrayData::setColumnCount; + using AbstractAnalysisArrayData::setRowCount; + using AbstractAnalysisArrayData::setXAxis; + using AbstractAnalysisArrayData::setXAxisValue; + using AbstractAnalysisArrayData::value; + using AbstractAnalysisArrayData::valuesReady; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; } // namespace gmx diff --git a/src/gromacs/analysisdata/dataframe.cpp b/src/gromacs/analysisdata/dataframe.cpp index 9375b2cb50..7c1de57ea8 100644 --- a/src/gromacs/analysisdata/dataframe.cpp +++ b/src/gromacs/analysisdata/dataframe.cpp @@ -52,14 +52,13 @@ namespace gmx * AnalysisDataFrameHeader */ -AnalysisDataFrameHeader::AnalysisDataFrameHeader() - : index_(-1), x_(0.0), dx_(0.0) -{ -} +AnalysisDataFrameHeader::AnalysisDataFrameHeader() : index_(-1), x_(0.0), dx_(0.0) {} -AnalysisDataFrameHeader::AnalysisDataFrameHeader(int index, real x, real dx) - : index_(index), x_(x), dx_(dx) +AnalysisDataFrameHeader::AnalysisDataFrameHeader(int index, real x, real dx) : + index_(index), + x_(x), + dx_(dx) { GMX_ASSERT(index >= 0, "Invalid frame index"); } @@ -69,47 +68,45 @@ AnalysisDataFrameHeader::AnalysisDataFrameHeader(int index, real x, real dx) * AnalysisDataPointSetRef */ -AnalysisDataPointSetRef::AnalysisDataPointSetRef( - const AnalysisDataFrameHeader &header, - const AnalysisDataPointSetInfo &pointSetInfo, - const AnalysisDataValuesRef &values) - : header_(header), - dataSetIndex_(pointSetInfo.dataSetIndex()), - firstColumn_(pointSetInfo.firstColumn()), - values_(constArrayRefFromArray(&*values.begin() + pointSetInfo.valueOffset(), - pointSetInfo.valueCount())) +AnalysisDataPointSetRef::AnalysisDataPointSetRef(const AnalysisDataFrameHeader& header, + const AnalysisDataPointSetInfo& pointSetInfo, + const AnalysisDataValuesRef& values) : + header_(header), + dataSetIndex_(pointSetInfo.dataSetIndex()), + firstColumn_(pointSetInfo.firstColumn()), + values_(constArrayRefFromArray(&*values.begin() + pointSetInfo.valueOffset(), pointSetInfo.valueCount())) { - GMX_ASSERT(header_.isValid(), - "Invalid point set reference should not be constructed"); + GMX_ASSERT(header_.isValid(), "Invalid point set reference should not be constructed"); } -AnalysisDataPointSetRef::AnalysisDataPointSetRef( - const AnalysisDataFrameHeader &header, - const std::vector &values) - : header_(header), dataSetIndex_(0), firstColumn_(0), - values_(values) +AnalysisDataPointSetRef::AnalysisDataPointSetRef(const AnalysisDataFrameHeader& header, + const std::vector& values) : + header_(header), + dataSetIndex_(0), + firstColumn_(0), + values_(values) { - GMX_ASSERT(header_.isValid(), - "Invalid point set reference should not be constructed"); + GMX_ASSERT(header_.isValid(), "Invalid point set reference should not be constructed"); } -AnalysisDataPointSetRef::AnalysisDataPointSetRef( - const AnalysisDataPointSetRef &points, int firstColumn, int columnCount) - : header_(points.header()), dataSetIndex_(points.dataSetIndex()), - firstColumn_(0) +AnalysisDataPointSetRef::AnalysisDataPointSetRef(const AnalysisDataPointSetRef& points, + int firstColumn, + int columnCount) : + header_(points.header()), + dataSetIndex_(points.dataSetIndex()), + firstColumn_(0) { GMX_ASSERT(firstColumn >= 0, "Invalid first column"); GMX_ASSERT(columnCount >= 0, "Invalid column count"); - if (points.lastColumn() < firstColumn - || points.firstColumn() >= firstColumn + columnCount + if (points.lastColumn() < firstColumn || points.firstColumn() >= firstColumn + columnCount || columnCount == 0) { return; } - AnalysisDataValuesRef::const_iterator begin = points.values().begin(); - int pointsOffset = firstColumn - points.firstColumn(); + AnalysisDataValuesRef::const_iterator begin = points.values().begin(); + int pointsOffset = firstColumn - points.firstColumn(); if (pointsOffset > 0) { // Offset pointer if the first column is not the first in points. @@ -149,47 +146,43 @@ bool AnalysisDataPointSetRef::allPresent() const * AnalysisDataFrameRef */ -AnalysisDataFrameRef::AnalysisDataFrameRef() -{ -} +AnalysisDataFrameRef::AnalysisDataFrameRef() {} -AnalysisDataFrameRef::AnalysisDataFrameRef( - const AnalysisDataFrameHeader &header, - const AnalysisDataValuesRef &values, - const AnalysisDataPointSetInfosRef &pointSets) - : header_(header), values_(values), pointSets_(pointSets) +AnalysisDataFrameRef::AnalysisDataFrameRef(const AnalysisDataFrameHeader& header, + const AnalysisDataValuesRef& values, + const AnalysisDataPointSetInfosRef& pointSets) : + header_(header), + values_(values), + pointSets_(pointSets) { GMX_ASSERT(!pointSets_.empty(), "There must always be a point set"); } -AnalysisDataFrameRef::AnalysisDataFrameRef( - const AnalysisDataFrameHeader &header, - const std::vector &values, - const std::vector &pointSets) - : header_(header), values_(values), - pointSets_(pointSets) +AnalysisDataFrameRef::AnalysisDataFrameRef(const AnalysisDataFrameHeader& header, + const std::vector& values, + const std::vector& pointSets) : + header_(header), + values_(values), + pointSets_(pointSets) { GMX_ASSERT(!pointSets_.empty(), "There must always be a point set"); } -AnalysisDataFrameRef::AnalysisDataFrameRef( - const AnalysisDataFrameRef &frame, int firstColumn, int columnCount) - : header_(frame.header()), - values_(constArrayRefFromArray(&frame.values_[firstColumn], columnCount)), - pointSets_(frame.pointSets_) +AnalysisDataFrameRef::AnalysisDataFrameRef(const AnalysisDataFrameRef& frame, int firstColumn, int columnCount) : + header_(frame.header()), + values_(constArrayRefFromArray(&frame.values_[firstColumn], columnCount)), + pointSets_(frame.pointSets_) { // FIXME: This doesn't produce a valid internal state, although it does // work in some cases. The point sets cannot be correctly managed here, but // need to be handles by the data proxy class. GMX_ASSERT(firstColumn >= 0, "Invalid first column"); GMX_ASSERT(columnCount >= 0, "Invalid column count"); - GMX_ASSERT(pointSets_.size() == 1U, - "Subsets of frames only supported with simple data"); - GMX_ASSERT(firstColumn + columnCount <= ssize(values_), - "Invalid last column"); + GMX_ASSERT(pointSets_.size() == 1U, "Subsets of frames only supported with simple data"); + GMX_ASSERT(firstColumn + columnCount <= ssize(values_), "Invalid last column"); } diff --git a/src/gromacs/analysisdata/dataframe.h b/src/gromacs/analysisdata/dataframe.h index 033855d4d8..5a5164d291 100644 --- a/src/gromacs/analysisdata/dataframe.h +++ b/src/gromacs/analysisdata/dataframe.h @@ -70,106 +70,102 @@ namespace gmx */ class AnalysisDataValue { - public: - /*! \brief - * Constructs an unset value. - */ - AnalysisDataValue() : value_(0.0), error_(0.0) {} - /*! \brief - * Constructs a value object with the given value. - * - * The constructed object is marked as set and present. - */ - explicit AnalysisDataValue(real value) - : value_(value), error_(0.0) - { - flags_.set(efSet); - flags_.set(efPresent); - } +public: + /*! \brief + * Constructs an unset value. + */ + AnalysisDataValue() : value_(0.0), error_(0.0) {} + /*! \brief + * Constructs a value object with the given value. + * + * The constructed object is marked as set and present. + */ + explicit AnalysisDataValue(real value) : value_(value), error_(0.0) + { + flags_.set(efSet); + flags_.set(efPresent); + } - /*! \brief - * Direct access to the value. - * - * Assigning a value to this does not mark the value as set; setValue() - * must be used for this. - */ - real &value() { return value_; } - /*! \brief - * Direct access to the error estimate. - * - * Assigning a value to this does not mark the error estimate as set; - * setValue() must be used for this. - */ - real &error() { return error_; } - //! Returns the value for this value. - real value() const { return value_; } - //! Returns the error estimate for this value, or zero if not set. - real error() const { return error_; } - /*! \brief - * Returns whether this value has been set. - * - * If this method returns false, the return value of value() and - * error() are undefined. - */ - bool isSet() const { return flags_.test(efSet); } - /*! \brief - * Returns whether the error estimate for this value has been set. - * - * If this method returns false, but isSet() returns true, error() - * returns zero. - */ - bool hasError() const { return flags_.test(efErrorSet); } - /*! \brief - * Returns whether this value has been marked as present. - * - * If this method returns false, it is up to the source data to define - * whether isSet() may return true. - */ - bool isPresent() const { return flags_.test(efPresent); } + /*! \brief + * Direct access to the value. + * + * Assigning a value to this does not mark the value as set; setValue() + * must be used for this. + */ + real& value() { return value_; } + /*! \brief + * Direct access to the error estimate. + * + * Assigning a value to this does not mark the error estimate as set; + * setValue() must be used for this. + */ + real& error() { return error_; } + //! Returns the value for this value. + real value() const { return value_; } + //! Returns the error estimate for this value, or zero if not set. + real error() const { return error_; } + /*! \brief + * Returns whether this value has been set. + * + * If this method returns false, the return value of value() and + * error() are undefined. + */ + bool isSet() const { return flags_.test(efSet); } + /*! \brief + * Returns whether the error estimate for this value has been set. + * + * If this method returns false, but isSet() returns true, error() + * returns zero. + */ + bool hasError() const { return flags_.test(efErrorSet); } + /*! \brief + * Returns whether this value has been marked as present. + * + * If this method returns false, it is up to the source data to define + * whether isSet() may return true. + */ + bool isPresent() const { return flags_.test(efPresent); } - //! Clears and unsets this value. - void clear() - { - *this = AnalysisDataValue(); - } - //! Sets this value. - void setValue(real value, bool bPresent = true) - { - value_ = value; - flags_.set(efSet); - flags_.set(efPresent, bPresent); - } - //! Sets this value and its error estimate. - void setValue(real value, real error, bool bPresent = true) - { - value_ = value; - error_ = error; - flags_.set(efSet); - flags_.set(efErrorSet); - flags_.set(efPresent, bPresent); - } - //! Set only error estimate for this value. - void setError(real error) - { - error_ = error; - flags_.set(efErrorSet); - } + //! Clears and unsets this value. + void clear() { *this = AnalysisDataValue(); } + //! Sets this value. + void setValue(real value, bool bPresent = true) + { + value_ = value; + flags_.set(efSet); + flags_.set(efPresent, bPresent); + } + //! Sets this value and its error estimate. + void setValue(real value, real error, bool bPresent = true) + { + value_ = value; + error_ = error; + flags_.set(efSet); + flags_.set(efErrorSet); + flags_.set(efPresent, bPresent); + } + //! Set only error estimate for this value. + void setError(real error) + { + error_ = error; + flags_.set(efErrorSet); + } - private: - //! Possible flags for \a flags_. - enum Flag - { - efSet = 1<<0, //!< Value has been set. - efErrorSet = 1<<1, //!< Error estimate has been set. - efPresent = 1<<2 //!< Value is set as present. - }; +private: + //! Possible flags for \a flags_. + enum Flag + { + efSet = 1 << 0, //!< Value has been set. + efErrorSet = 1 << 1, //!< Error estimate has been set. + efPresent = 1 << 2 //!< Value is set as present. + }; - //! Value for this value. - real value_; - //! Error estimate for this value, zero if not set. - real error_; - //! Status flags for thise value. - FlagsTemplate flags_; + //! Value for this value. + real value_; + //! Error estimate for this value, zero if not set. + real error_; + //! Status flags for thise value. + FlagsTemplate flags_; }; //! Shorthand for reference to an array of data values. @@ -195,71 +191,68 @@ typedef ArrayRef AnalysisDataValuesRef; */ class AnalysisDataFrameHeader { - public: - /*! \brief - * Constructs an invalid frame header. - * - * Return values of other methods than isValid() are unspecified for - * the constructed object. - */ - AnalysisDataFrameHeader(); - /*! \brief - * Constructs a frame header from given values. - * - * \param[in] index Index of the frame. Must be >= 0. - * \param[in] x x coordinate for the frame. - * \param[in] dx Error estimate for x. - */ - AnalysisDataFrameHeader(int index, real x, real dx); +public: + /*! \brief + * Constructs an invalid frame header. + * + * Return values of other methods than isValid() are unspecified for + * the constructed object. + */ + AnalysisDataFrameHeader(); + /*! \brief + * Constructs a frame header from given values. + * + * \param[in] index Index of the frame. Must be >= 0. + * \param[in] x x coordinate for the frame. + * \param[in] dx Error estimate for x. + */ + AnalysisDataFrameHeader(int index, real x, real dx); - /*! \brief - * Returns whether the frame header corresponds to a valid frame. - * - * If returns false, return values of other methods are not specified. - */ - bool isValid() const - { - return index_ >= 0; - } - /*! \brief - * Returns zero-based index of the frame. - * - * The return value is >= 0 for valid frames. - * Should not be called for invalid frames. - */ - int index() const - { - GMX_ASSERT(isValid(), "Tried to access invalid frame header"); - return index_; - } - /*! \brief - * Returns the x coordinate for the frame. - * - * Should not be called for invalid frames. - */ - real x() const - { - GMX_ASSERT(isValid(), "Tried to access invalid frame header"); - return x_; - } - /*! \brief - * Returns error in the x coordinate for the frame (if applicable). - * - * All data do not provide error estimates. - * Typically returns zero in those cases. - * - * Should not be called for invalid frames. - */ - real dx() const - { - GMX_ASSERT(isValid(), "Tried to access invalid frame header"); - return dx_; - } + /*! \brief + * Returns whether the frame header corresponds to a valid frame. + * + * If returns false, return values of other methods are not specified. + */ + bool isValid() const { return index_ >= 0; } + /*! \brief + * Returns zero-based index of the frame. + * + * The return value is >= 0 for valid frames. + * Should not be called for invalid frames. + */ + int index() const + { + GMX_ASSERT(isValid(), "Tried to access invalid frame header"); + return index_; + } + /*! \brief + * Returns the x coordinate for the frame. + * + * Should not be called for invalid frames. + */ + real x() const + { + GMX_ASSERT(isValid(), "Tried to access invalid frame header"); + return x_; + } + /*! \brief + * Returns error in the x coordinate for the frame (if applicable). + * + * All data do not provide error estimates. + * Typically returns zero in those cases. + * + * Should not be called for invalid frames. + */ + real dx() const + { + GMX_ASSERT(isValid(), "Tried to access invalid frame header"); + return dx_; + } - private: - int index_; - real x_; - real dx_; +private: + int index_; + real x_; + real dx_; }; @@ -293,33 +286,34 @@ class AnalysisDataFrameHeader */ class AnalysisDataPointSetInfo { - public: - //! Construct point set data object with the given values. - AnalysisDataPointSetInfo(int valueOffset, int valueCount, - int dataSetIndex, int firstColumn) - : valueOffset_(valueOffset), valueCount_(valueCount), - dataSetIndex_(dataSetIndex), firstColumn_(firstColumn) - { - GMX_ASSERT(valueOffset >= 0, "Negative value offsets are invalid"); - GMX_ASSERT(valueCount >= 0, "Negative value counts are invalid"); - GMX_ASSERT(dataSetIndex >= 0, "Negative data set indices are invalid"); - GMX_ASSERT(firstColumn >= 0, "Negative column indices are invalid"); - } +public: + //! Construct point set data object with the given values. + AnalysisDataPointSetInfo(int valueOffset, int valueCount, int dataSetIndex, int firstColumn) : + valueOffset_(valueOffset), + valueCount_(valueCount), + dataSetIndex_(dataSetIndex), + firstColumn_(firstColumn) + { + GMX_ASSERT(valueOffset >= 0, "Negative value offsets are invalid"); + GMX_ASSERT(valueCount >= 0, "Negative value counts are invalid"); + GMX_ASSERT(dataSetIndex >= 0, "Negative data set indices are invalid"); + GMX_ASSERT(firstColumn >= 0, "Negative column indices are invalid"); + } - //! Returns the offset of the first value in the referenced value array. - int valueOffset() const { return valueOffset_; } - //! Returns the number of values in this point set. - int valueCount() const { return valueCount_; } - //! Returns the data set index for this point set. - int dataSetIndex() const { return dataSetIndex_; } - //! Returns the index of the first column in this point set. - int firstColumn() const { return firstColumn_; } + //! Returns the offset of the first value in the referenced value array. + int valueOffset() const { return valueOffset_; } + //! Returns the number of values in this point set. + int valueCount() const { return valueCount_; } + //! Returns the data set index for this point set. + int dataSetIndex() const { return dataSetIndex_; } + //! Returns the index of the first column in this point set. + int firstColumn() const { return firstColumn_; } - private: - int valueOffset_; - int valueCount_; - int dataSetIndex_; - int firstColumn_; +private: + int valueOffset_; + int valueCount_; + int dataSetIndex_; + int firstColumn_; }; //! Shorthand for reference to an array of point set data objects. @@ -350,154 +344,126 @@ typedef ArrayRef AnalysisDataPointSetInfosRef; */ class AnalysisDataPointSetRef { - public: - /*! \brief - * Constructs a point set reference from given values. - * - * \param[in] header Header for the frame. - * \param[in] pointSetInfo Information about the point set. - * \param[in] values Values for each column. - * - * The first element of the point set should be found from \p values - * using the offset in \p pointSetInfo. - */ - AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header, - const AnalysisDataPointSetInfo &pointSetInfo, - const AnalysisDataValuesRef &values); - /*! \brief - * Constructs a point set reference from given values. - * - * \param[in] header Header for the frame. - * \param[in] values Values for each column. - * - * The first element in \p values should correspond to the first - * column. - */ - AnalysisDataPointSetRef(const AnalysisDataFrameHeader &header, - const std::vector &values); - /*! \brief - * Constructs a point set reference to a subset of columns. - * - * \param[in] points Point set to use as source. - * \param[in] firstColumn First column index to include. - * \param[in] columnCount Number of columns to include. - * - * Creates a point set that contains \p columnCount columns starting - * from \p firstColumn from \p points, or a subset if all requested - * columns are not present in \p points. If the requested column range - * and the range in \p points do not intersect, the result has - * columnCount() == 0. - * - * \p firstColumn is relative to the whole data set, i.e., not relative - * to points.firstColumn(). - * - * Mainly intended for internal use. - */ - AnalysisDataPointSetRef(const AnalysisDataPointSetRef &points, - int firstColumn, int columnCount); +public: + /*! \brief + * Constructs a point set reference from given values. + * + * \param[in] header Header for the frame. + * \param[in] pointSetInfo Information about the point set. + * \param[in] values Values for each column. + * + * The first element of the point set should be found from \p values + * using the offset in \p pointSetInfo. + */ + AnalysisDataPointSetRef(const AnalysisDataFrameHeader& header, + const AnalysisDataPointSetInfo& pointSetInfo, + const AnalysisDataValuesRef& values); + /*! \brief + * Constructs a point set reference from given values. + * + * \param[in] header Header for the frame. + * \param[in] values Values for each column. + * + * The first element in \p values should correspond to the first + * column. + */ + AnalysisDataPointSetRef(const AnalysisDataFrameHeader& header, + const std::vector& values); + /*! \brief + * Constructs a point set reference to a subset of columns. + * + * \param[in] points Point set to use as source. + * \param[in] firstColumn First column index to include. + * \param[in] columnCount Number of columns to include. + * + * Creates a point set that contains \p columnCount columns starting + * from \p firstColumn from \p points, or a subset if all requested + * columns are not present in \p points. If the requested column range + * and the range in \p points do not intersect, the result has + * columnCount() == 0. + * + * \p firstColumn is relative to the whole data set, i.e., not relative + * to points.firstColumn(). + * + * Mainly intended for internal use. + */ + AnalysisDataPointSetRef(const AnalysisDataPointSetRef& points, int firstColumn, int columnCount); - /*! \brief - * Returns the frame header for the frame of this point set. - */ - const AnalysisDataFrameHeader &header() const - { - return header_; - } - //! \copydoc AnalysisDataFrameHeader::index() - int frameIndex() const - { - return header_.index(); - } - //! \copydoc AnalysisDataFrameHeader::x() - real x() const - { - return header_.x(); - } - //! \copydoc AnalysisDataFrameHeader::dx() - real dx() const - { - return header_.dx(); - } - //! Returns zero-based index of the dataset that this set is part of. - int dataSetIndex() const - { - return dataSetIndex_; - } - //! Returns zero-based index of the first column included in this set. - int firstColumn() const - { - return firstColumn_; - } - //! Returns the number of columns included in this set. - int columnCount() const - { - return ssize(values()); - } - //! Returns zero-based index of the last column included in this set (inclusive). - int lastColumn() const - { - return firstColumn_ + columnCount() - 1; - } - /*! \brief - * Returns reference container for all values. - * - * First value in the returned container corresponds to firstColumn(). - */ - const AnalysisDataValuesRef &values() const - { - return values_; - } - /*! \brief - * Returns data value for a column in this set. - * - * \param[in] i Zero-based column index relative to firstColumn(). - * Should be >= 0 and < columnCount(). - */ - real y(int i) const - { - GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); - return values()[i].value(); - } - /*! \brief - * Returns error estimate for a column in this set if applicable. - * - * \param[in] i Zero-based column index relative to firstColumn(). - * Should be >= 0 and < columnCount(). - * - * Currently, this method returns zero if the source data does not - * specify errors. - */ - real dy(int i) const - { - GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); - return values()[i].error(); - } - /*! \brief - * Returns whether a column is present in this set. - * - * \param[in] i Zero-based column index relative to firstColumn(). - * Should be >= 0 and < columnCount(). - * - * If present(i) returns false, it is depends on the source data - * whether y(i) and/or dy(i) are defined. - */ - bool present(int i) const - { - GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); - return values()[i].isPresent(); - } - /*! \brief - * Returns true if all points in this point set are present. - * - * That is, if present() would return true for all points. - */ - bool allPresent() const; + /*! \brief + * Returns the frame header for the frame of this point set. + */ + const AnalysisDataFrameHeader& header() const { return header_; } + //! \copydoc AnalysisDataFrameHeader::index() + int frameIndex() const { return header_.index(); } + //! \copydoc AnalysisDataFrameHeader::x() + real x() const { return header_.x(); } + //! \copydoc AnalysisDataFrameHeader::dx() + real dx() const { return header_.dx(); } + //! Returns zero-based index of the dataset that this set is part of. + int dataSetIndex() const { return dataSetIndex_; } + //! Returns zero-based index of the first column included in this set. + int firstColumn() const { return firstColumn_; } + //! Returns the number of columns included in this set. + int columnCount() const { return ssize(values()); } + //! Returns zero-based index of the last column included in this set (inclusive). + int lastColumn() const { return firstColumn_ + columnCount() - 1; } + /*! \brief + * Returns reference container for all values. + * + * First value in the returned container corresponds to firstColumn(). + */ + const AnalysisDataValuesRef& values() const { return values_; } + /*! \brief + * Returns data value for a column in this set. + * + * \param[in] i Zero-based column index relative to firstColumn(). + * Should be >= 0 and < columnCount(). + */ + real y(int i) const + { + GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); + return values()[i].value(); + } + /*! \brief + * Returns error estimate for a column in this set if applicable. + * + * \param[in] i Zero-based column index relative to firstColumn(). + * Should be >= 0 and < columnCount(). + * + * Currently, this method returns zero if the source data does not + * specify errors. + */ + real dy(int i) const + { + GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); + return values()[i].error(); + } + /*! \brief + * Returns whether a column is present in this set. + * + * \param[in] i Zero-based column index relative to firstColumn(). + * Should be >= 0 and < columnCount(). + * + * If present(i) returns false, it is depends on the source data + * whether y(i) and/or dy(i) are defined. + */ + bool present(int i) const + { + GMX_ASSERT(i >= 0 && i < columnCount(), "Out of range data access"); + return values()[i].isPresent(); + } + /*! \brief + * Returns true if all points in this point set are present. + * + * That is, if present() would return true for all points. + */ + bool allPresent() const; - private: - AnalysisDataFrameHeader header_; - int dataSetIndex_; - int firstColumn_; - AnalysisDataValuesRef values_; +private: + AnalysisDataFrameHeader header_; + int dataSetIndex_; + int firstColumn_; + AnalysisDataValuesRef values_; }; @@ -520,149 +486,119 @@ class AnalysisDataPointSetRef */ class AnalysisDataFrameRef { - public: - /*! \brief - * Constructs an invalid frame reference. - * - * Return values of other methods than isValid() are unspecified for - * the constructed object. - */ - AnalysisDataFrameRef(); - /*! \brief - * Constructs a frame reference from given values. - * - * \param[in] header Header for the frame. - * \param[in] values Values for each column. - * \param[in] pointSets Point set data. - */ - AnalysisDataFrameRef(const AnalysisDataFrameHeader &header, - const AnalysisDataValuesRef &values, - const AnalysisDataPointSetInfosRef &pointSets); - /*! \brief - * Constructs a frame reference from given values. - * - * \param[in] header Header for the frame. - * \param[in] values Values for each column. - * \param[in] pointSets Point set data. - */ - AnalysisDataFrameRef(const AnalysisDataFrameHeader &header, - const std::vector &values, - const std::vector &pointSets); - /*! \brief - * Constructs a frame reference to a subset of columns. - * - * \param[in] frame Frame to use as source. - * \param[in] firstColumn First column index to include. - * \param[in] columnCount Number of columns to include. - * - * Creates a frame reference that contains \p columnCount columns - * starting from \p firstColumn from \p frame, or a subset if all - * requested columns are not present in \p frame. - * - * Mainly intended for internal use. - */ - AnalysisDataFrameRef(const AnalysisDataFrameRef &frame, - int firstColumn, int columnCount); +public: + /*! \brief + * Constructs an invalid frame reference. + * + * Return values of other methods than isValid() are unspecified for + * the constructed object. + */ + AnalysisDataFrameRef(); + /*! \brief + * Constructs a frame reference from given values. + * + * \param[in] header Header for the frame. + * \param[in] values Values for each column. + * \param[in] pointSets Point set data. + */ + AnalysisDataFrameRef(const AnalysisDataFrameHeader& header, + const AnalysisDataValuesRef& values, + const AnalysisDataPointSetInfosRef& pointSets); + /*! \brief + * Constructs a frame reference from given values. + * + * \param[in] header Header for the frame. + * \param[in] values Values for each column. + * \param[in] pointSets Point set data. + */ + AnalysisDataFrameRef(const AnalysisDataFrameHeader& header, + const std::vector& values, + const std::vector& pointSets); + /*! \brief + * Constructs a frame reference to a subset of columns. + * + * \param[in] frame Frame to use as source. + * \param[in] firstColumn First column index to include. + * \param[in] columnCount Number of columns to include. + * + * Creates a frame reference that contains \p columnCount columns + * starting from \p firstColumn from \p frame, or a subset if all + * requested columns are not present in \p frame. + * + * Mainly intended for internal use. + */ + AnalysisDataFrameRef(const AnalysisDataFrameRef& frame, int firstColumn, int columnCount); - /*! \brief - * Returns whether the object refers to a valid frame. - * - * If returns false, return values of other methods are not specified. - */ - bool isValid() const - { - return header().isValid(); - } - //! Returns the header for this frame. - const AnalysisDataFrameHeader &header() const - { - return header_; - } - //! \copydoc AnalysisDataFrameHeader::index() - int frameIndex() const - { - return header().index(); - } - //! \copydoc AnalysisDataFrameHeader::x() - real x() const - { - return header().x(); - } - //! \copydoc AnalysisDataFrameHeader::dx() - real dx() const - { - return header().dx(); - } - /*! \brief - * Returns the number of point sets for this frame. - * - * Returns zero for an invalid frame. - */ - int pointSetCount() const - { - return ssize(pointSets_); - } - /*! \brief - * Returns point set reference for a given point set. - * - * Should not be called for invalid frames. - */ - AnalysisDataPointSetRef pointSet(int index) const - { - GMX_ASSERT(isValid(), "Invalid data frame accessed"); - GMX_ASSERT(index >= 0 && index < pointSetCount(), - "Out of range data access"); - return AnalysisDataPointSetRef(header_, pointSets_[index], values_); - } - /*! \brief - * Convenience method for accessing a column value in simple data. - * - * \copydetails AnalysisDataPointSetRef::y() - */ - real y(int i) const - { - return singleColumnValue(i).value(); - } - /*! \brief - * Convenience method for accessing error for a column value in simple - * data. - * - * \copydetails AnalysisDataPointSetRef::dy() - */ - real dy(int i) const - { - return singleColumnValue(i).error(); - } - /*! \brief - * Convenience method for accessing present status for a column in - * simple data. - * - * \copydetails AnalysisDataPointSetRef::present() - */ - bool present(int i) const - { - return singleColumnValue(i).isPresent(); - } - /*! \brief - * Returns true if all points in this frame are present. - */ - bool allPresent() const; + /*! \brief + * Returns whether the object refers to a valid frame. + * + * If returns false, return values of other methods are not specified. + */ + bool isValid() const { return header().isValid(); } + //! Returns the header for this frame. + const AnalysisDataFrameHeader& header() const { return header_; } + //! \copydoc AnalysisDataFrameHeader::index() + int frameIndex() const { return header().index(); } + //! \copydoc AnalysisDataFrameHeader::x() + real x() const { return header().x(); } + //! \copydoc AnalysisDataFrameHeader::dx() + real dx() const { return header().dx(); } + /*! \brief + * Returns the number of point sets for this frame. + * + * Returns zero for an invalid frame. + */ + int pointSetCount() const { return ssize(pointSets_); } + /*! \brief + * Returns point set reference for a given point set. + * + * Should not be called for invalid frames. + */ + AnalysisDataPointSetRef pointSet(int index) const + { + GMX_ASSERT(isValid(), "Invalid data frame accessed"); + GMX_ASSERT(index >= 0 && index < pointSetCount(), "Out of range data access"); + return AnalysisDataPointSetRef(header_, pointSets_[index], values_); + } + /*! \brief + * Convenience method for accessing a column value in simple data. + * + * \copydetails AnalysisDataPointSetRef::y() + */ + real y(int i) const { return singleColumnValue(i).value(); } + /*! \brief + * Convenience method for accessing error for a column value in simple + * data. + * + * \copydetails AnalysisDataPointSetRef::dy() + */ + real dy(int i) const { return singleColumnValue(i).error(); } + /*! \brief + * Convenience method for accessing present status for a column in + * simple data. + * + * \copydetails AnalysisDataPointSetRef::present() + */ + bool present(int i) const { return singleColumnValue(i).isPresent(); } + /*! \brief + * Returns true if all points in this frame are present. + */ + bool allPresent() const; - private: - //! Helper method for accessing single columns in simple data. - const AnalysisDataValue &singleColumnValue(int i) const - { - GMX_ASSERT(isValid(), "Invalid data frame accessed"); - GMX_ASSERT(pointSets_.size() == 1U && pointSets_[0].firstColumn() == 0, - "Convenience method not available for multiple point sets"); - GMX_ASSERT(i >= 0 && i < ssize(values_), - "Out of range data access"); - return values_[i]; - } +private: + //! Helper method for accessing single columns in simple data. + const AnalysisDataValue& singleColumnValue(int i) const + { + GMX_ASSERT(isValid(), "Invalid data frame accessed"); + GMX_ASSERT(pointSets_.size() == 1U && pointSets_[0].firstColumn() == 0, + "Convenience method not available for multiple point sets"); + GMX_ASSERT(i >= 0 && i < ssize(values_), "Out of range data access"); + return values_[i]; + } - AnalysisDataFrameHeader header_; - AnalysisDataValuesRef values_; - AnalysisDataPointSetInfosRef pointSets_; + AnalysisDataFrameHeader header_; + AnalysisDataValuesRef values_; + AnalysisDataPointSetInfosRef pointSets_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/datamodule.cpp b/src/gromacs/analysisdata/datamodule.cpp index dde3922dbd..3fef355531 100644 --- a/src/gromacs/analysisdata/datamodule.cpp +++ b/src/gromacs/analysisdata/datamodule.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,15 +48,14 @@ namespace gmx { -bool AnalysisDataModuleSerial::parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions & /*options*/) +bool AnalysisDataModuleSerial::parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& /*options*/) { dataStarted(data); return false; } -void AnalysisDataModuleParallel::dataStarted(AbstractAnalysisData *data) +void AnalysisDataModuleParallel::dataStarted(AbstractAnalysisData* data) { AnalysisDataParallelOptions options; (void)parallelDataStarted(data, options); diff --git a/src/gromacs/analysisdata/datamodule.h b/src/gromacs/analysisdata/datamodule.h index 68da7f0a05..6183cbc177 100644 --- a/src/gromacs/analysisdata/datamodule.h +++ b/src/gromacs/analysisdata/datamodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -80,151 +80,150 @@ class AnalysisDataPointSetRef; */ class IAnalysisDataModule { - public: - /*! \brief - * Possible flags for flags(). - */ - enum Flag - { - //! The module can process multipoint data. - efAllowMultipoint = 1<<0, - //! The module does not make sense for non-multipoint data. - efOnlyMultipoint = 1<<1, - //! The module can process data with more than one column. - efAllowMulticolumn = 1<<2, - //! The module can process data with missing points. - efAllowMissing = 1<<3, - //! The module can process data with multiple data sets. - efAllowMultipleDataSets = 1<<4 - }; +public: + /*! \brief + * Possible flags for flags(). + */ + enum Flag + { + //! The module can process multipoint data. + efAllowMultipoint = 1 << 0, + //! The module does not make sense for non-multipoint data. + efOnlyMultipoint = 1 << 1, + //! The module can process data with more than one column. + efAllowMulticolumn = 1 << 2, + //! The module can process data with missing points. + efAllowMissing = 1 << 3, + //! The module can process data with multiple data sets. + efAllowMultipleDataSets = 1 << 4 + }; - virtual ~IAnalysisDataModule() {} + virtual ~IAnalysisDataModule() {} - /*! \brief - * Returns properties supported by the module. - * - * The return value of this method should not change after the module - * has been added to a data (this responsibility can, and in most cases - * must, be delegated to the user of the module). - * - * The purpose of this method is to remove the need for common checks - * for data compatibility in the classes that implement the interface. - * Instead, AbstractAnalysisData performs these checks based on the - * flags provided. - * - * Does not throw. - */ - virtual int flags() const = 0; + /*! \brief + * Returns properties supported by the module. + * + * The return value of this method should not change after the module + * has been added to a data (this responsibility can, and in most cases + * must, be delegated to the user of the module). + * + * The purpose of this method is to remove the need for common checks + * for data compatibility in the classes that implement the interface. + * Instead, AbstractAnalysisData performs these checks based on the + * flags provided. + * + * Does not throw. + */ + virtual int flags() const = 0; - /*! \brief - * Called (once) when the data has been set up properly. - * - * \param[in] data Data object to which the module is added. - * \throws APIError if the provided data is not compatible. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - * - * When the data is ready, either this method or parallelDataStarted() - * is called, depending on the nature of the input data. If this - * method is called, the input data will always present the frames in - * sequential order. - * - * The data to which the module is attached is passed as an argument - * to provide access to properties of the data for initialization - * and/or validation. The module can also call - * AbstractAnalysisData::requestStorage() if needed. - * - * This is the only place where the module gets access to the data; - * if properties of the data are required later, the module should - * store them internally. It is guaranteed that the data properties - * (column count, whether it's multipoint) do not change once this - * method has been called. - * - * Notice that \p data will be a proxy object if the module is added as - * a column module, not the data object for which - * AbstractAnalysisData::addColumnModule() was called. - */ - virtual void dataStarted(AbstractAnalysisData *data) = 0; - /*! \brief - * Called (once) for parallel data when the data has been set up. - * - * \param[in] data Data object to which the module is added. - * \param[in] options Parallelization properties of the input data. - * \returns true if the module can process the input in - * non-sequential order. - * \throws APIError if the provided data is not compatible. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - * - * This method is called instead of dataStarted() if the input data has - * the capability to present data in non-sequential order. - * If the method returns true, then the module accepts this and frame - * notification methods may be called in that non-sequential order. - * If the method returns false, then the frame notification methods are - * called in sequential order, as if dataStarted() had been called. - * - * See dataStarted() for general information on initializing the data. - * That applies to this method as well, with the exception that calling - * AbstractAnalysisData::requestStorage() is currently not very well - * supported (or rather, accessing the requested storage doesn't work). - */ - virtual bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) = 0; - /*! \brief - * Called at the start of each data frame. - * - * \param[in] frame Header information for the frame that is starting. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - */ - virtual void frameStarted(const AnalysisDataFrameHeader &frame) = 0; - /*! \brief - * Called one or more times during each data frame. - * - * \param[in] points Set of points added (also provides access to - * frame-level data). - * \throws APIError if the provided data is not compatible. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - * - * Can be called once or multiple times for a frame. For all data - * objects currently implemented in the library (and all objects that - * will use AnalysisDataStorage for internal implementation), it is - * called exactly once for each frame if the data is not multipoint, - * but currently this restriction is not enforced. - */ - virtual void pointsAdded(const AnalysisDataPointSetRef &points) = 0; - /*! \brief - * Called when a data frame is finished. - * - * \param[in] header Header information for the frame that is ending. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - */ - virtual void frameFinished(const AnalysisDataFrameHeader &header) = 0; - /*! \brief - * Called in sequential order for each frame after they are finished. - * - * \param[in] frameIndex Index of the next finished frame. - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - * - * This method is called after frameFinished(), but with an additional - * constraint that it is always called in serial and with an increasing - * \p frameIndex. Parallel data modules need this to serialize their - * data for downsteam serial modules; AnalysisDataModuleSerial provides - * an empty implementation, as there frameFinished() can be used for - * the same purpose. - */ - virtual void frameFinishedSerial(int frameIndex) = 0; - /*! \brief - * Called (once) when no more data is available. - * - * \throws unspecified Can throw any exception required by the - * implementing class to report errors. - */ - virtual void dataFinished() = 0; + /*! \brief + * Called (once) when the data has been set up properly. + * + * \param[in] data Data object to which the module is added. + * \throws APIError if the provided data is not compatible. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + * + * When the data is ready, either this method or parallelDataStarted() + * is called, depending on the nature of the input data. If this + * method is called, the input data will always present the frames in + * sequential order. + * + * The data to which the module is attached is passed as an argument + * to provide access to properties of the data for initialization + * and/or validation. The module can also call + * AbstractAnalysisData::requestStorage() if needed. + * + * This is the only place where the module gets access to the data; + * if properties of the data are required later, the module should + * store them internally. It is guaranteed that the data properties + * (column count, whether it's multipoint) do not change once this + * method has been called. + * + * Notice that \p data will be a proxy object if the module is added as + * a column module, not the data object for which + * AbstractAnalysisData::addColumnModule() was called. + */ + virtual void dataStarted(AbstractAnalysisData* data) = 0; + /*! \brief + * Called (once) for parallel data when the data has been set up. + * + * \param[in] data Data object to which the module is added. + * \param[in] options Parallelization properties of the input data. + * \returns true if the module can process the input in + * non-sequential order. + * \throws APIError if the provided data is not compatible. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + * + * This method is called instead of dataStarted() if the input data has + * the capability to present data in non-sequential order. + * If the method returns true, then the module accepts this and frame + * notification methods may be called in that non-sequential order. + * If the method returns false, then the frame notification methods are + * called in sequential order, as if dataStarted() had been called. + * + * See dataStarted() for general information on initializing the data. + * That applies to this method as well, with the exception that calling + * AbstractAnalysisData::requestStorage() is currently not very well + * supported (or rather, accessing the requested storage doesn't work). + */ + virtual bool parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) = 0; + /*! \brief + * Called at the start of each data frame. + * + * \param[in] frame Header information for the frame that is starting. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + */ + virtual void frameStarted(const AnalysisDataFrameHeader& frame) = 0; + /*! \brief + * Called one or more times during each data frame. + * + * \param[in] points Set of points added (also provides access to + * frame-level data). + * \throws APIError if the provided data is not compatible. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + * + * Can be called once or multiple times for a frame. For all data + * objects currently implemented in the library (and all objects that + * will use AnalysisDataStorage for internal implementation), it is + * called exactly once for each frame if the data is not multipoint, + * but currently this restriction is not enforced. + */ + virtual void pointsAdded(const AnalysisDataPointSetRef& points) = 0; + /*! \brief + * Called when a data frame is finished. + * + * \param[in] header Header information for the frame that is ending. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + */ + virtual void frameFinished(const AnalysisDataFrameHeader& header) = 0; + /*! \brief + * Called in sequential order for each frame after they are finished. + * + * \param[in] frameIndex Index of the next finished frame. + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + * + * This method is called after frameFinished(), but with an additional + * constraint that it is always called in serial and with an increasing + * \p frameIndex. Parallel data modules need this to serialize their + * data for downsteam serial modules; AnalysisDataModuleSerial provides + * an empty implementation, as there frameFinished() can be used for + * the same purpose. + */ + virtual void frameFinishedSerial(int frameIndex) = 0; + /*! \brief + * Called (once) when no more data is available. + * + * \throws unspecified Can throw any exception required by the + * implementing class to report errors. + */ + virtual void dataFinished() = 0; }; /*! \brief @@ -239,22 +238,20 @@ class IAnalysisDataModule */ class AnalysisDataModuleSerial : public IAnalysisDataModule { - public: - ~AnalysisDataModuleSerial() override {} +public: + ~AnalysisDataModuleSerial() override {} - int flags() const override = 0; + int flags() const override = 0; - void dataStarted(AbstractAnalysisData *data) override = 0; - void frameStarted(const AnalysisDataFrameHeader &frame) override = 0; - void pointsAdded(const AnalysisDataPointSetRef &points) override = 0; - void frameFinished(const AnalysisDataFrameHeader &header) override = 0; - void dataFinished() override = 0; + void dataStarted(AbstractAnalysisData* data) override = 0; + void frameStarted(const AnalysisDataFrameHeader& frame) override = 0; + void pointsAdded(const AnalysisDataPointSetRef& points) override = 0; + void frameFinished(const AnalysisDataFrameHeader& header) override = 0; + void dataFinished() override = 0; - private: - bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) override; - void frameFinishedSerial(int /*frameIndex*/) override {} +private: + bool parallelDataStarted(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options) override; + void frameFinishedSerial(int /*frameIndex*/) override {} }; /*! \brief @@ -269,22 +266,21 @@ class AnalysisDataModuleSerial : public IAnalysisDataModule */ class AnalysisDataModuleParallel : public IAnalysisDataModule { - public: - ~AnalysisDataModuleParallel() override {} +public: + ~AnalysisDataModuleParallel() override {} - int flags() const override = 0; + int flags() const override = 0; - bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) override = 0; - void frameStarted(const AnalysisDataFrameHeader &frame) override = 0; - void pointsAdded(const AnalysisDataPointSetRef &points) override = 0; - void frameFinished(const AnalysisDataFrameHeader &header) override = 0; - void frameFinishedSerial(int index) override = 0; - void dataFinished() override = 0; + bool parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) override = 0; + void frameStarted(const AnalysisDataFrameHeader& frame) override = 0; + void pointsAdded(const AnalysisDataPointSetRef& points) override = 0; + void frameFinished(const AnalysisDataFrameHeader& header) override = 0; + void frameFinishedSerial(int index) override = 0; + void dataFinished() override = 0; - private: - void dataStarted(AbstractAnalysisData *data) override; +private: + void dataStarted(AbstractAnalysisData* data) override; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/datamodulemanager.cpp b/src/gromacs/analysisdata/datamodulemanager.cpp index 58a4aee2ce..a68bb85459 100644 --- a/src/gromacs/analysisdata/datamodulemanager.cpp +++ b/src/gromacs/analysisdata/datamodulemanager.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,113 +68,114 @@ namespace gmx */ class AnalysisDataModuleManager::Impl { - public: - //! Stores information about an attached module. - struct ModuleInfo +public: + //! Stores information about an attached module. + struct ModuleInfo + { + //! Initializes the module information. + explicit ModuleInfo(AnalysisDataModulePointer module) : + module(std::move(module)), + bParallel(false) { - //! Initializes the module information. - explicit ModuleInfo(AnalysisDataModulePointer module) - : module(std::move(module)), bParallel(false) - { - } + } - //! Pointer to the actual module. - AnalysisDataModulePointer module; - //! Whether the module supports parallel processing. - bool bParallel; - }; + //! Pointer to the actual module. + AnalysisDataModulePointer module; + //! Whether the module supports parallel processing. + bool bParallel; + }; - //! Shorthand for list of modules added to the data. - typedef std::vector ModuleList; + //! Shorthand for list of modules added to the data. + typedef std::vector ModuleList; - //! Describes the current state of the notification methods. - enum State - { - eNotStarted, //!< Initial state (nothing called). - eInData, //!< notifyDataStart() called, no frame in progress. - eInFrame, //!< notifyFrameStart() called, but notifyFrameFinish() not. - eFinished //!< notifyDataFinish() called. - }; - - Impl(); - - /*! \brief - * Checks whether a module is compatible with a given data property. - * - * \param[in] module Module to check. - * \param[in] property Property to check. - * \param[in] bSet Value of the property to check against. - * \throws APIError if \p module is not compatible with the data. - */ - void checkModuleProperty(const IAnalysisDataModule &module, - DataProperty property, bool bSet) const; - /*! \brief - * Checks whether a module is compatible with the data properties. - * - * \param[in] module Module to check. - * \throws APIError if \p module is not compatible with the data. - * - * Does not currently check the actual data (e.g., missing values), but - * only the dimensionality and other preset properties of the data. - */ - void checkModuleProperties(const IAnalysisDataModule &module) const; - - /*! \brief - * Present data already added to the data object to a module. - * - * \param[in] data Data object to read data from. - * \param[in] module Module to present the data to. - * \throws APIError if \p module is not compatible with the data. - * \throws APIError if all data is not available through - * getDataFrame(). - * \throws unspecified Any exception thrown by \p module in its data - * notification methods. - * - * Uses getDataFrame() in \p data to access all data in the object, and - * calls the notification functions in \p module as if the module had - * been registered to the data object when the data was added. - */ - void presentData(AbstractAnalysisData *data, - IAnalysisDataModule *module); - - //! List of modules added to the data. - ModuleList modules_; - //! Properties of the owning data for module checking. - bool bDataProperty_[eDataPropertyNR]; - //! true if all modules support missing data. - bool bAllowMissing_; - //! true if there are modules that do not support parallel processing. - bool bSerialModules_; - //! true if there are modules that support parallel processing. - bool bParallelModules_; - - /*! \brief - * Current state of the notification methods. - * - * This is used together with \a currIndex_ for sanity checks on the - * input data; invalid call sequences trigger asserts. - * The state of these variables does not otherwise affect the behavior - * of this class; this is the reason they can be changed in const - * methods. - */ - //! Whether notifyDataStart() has been called. - mutable State state_; - //! Index of currently active frame or the next frame if not in frame. - mutable int currIndex_; + //! Describes the current state of the notification methods. + enum State + { + eNotStarted, //!< Initial state (nothing called). + eInData, //!< notifyDataStart() called, no frame in progress. + eInFrame, //!< notifyFrameStart() called, but notifyFrameFinish() not. + eFinished //!< notifyDataFinish() called. + }; + + Impl(); + + /*! \brief + * Checks whether a module is compatible with a given data property. + * + * \param[in] module Module to check. + * \param[in] property Property to check. + * \param[in] bSet Value of the property to check against. + * \throws APIError if \p module is not compatible with the data. + */ + void checkModuleProperty(const IAnalysisDataModule& module, DataProperty property, bool bSet) const; + /*! \brief + * Checks whether a module is compatible with the data properties. + * + * \param[in] module Module to check. + * \throws APIError if \p module is not compatible with the data. + * + * Does not currently check the actual data (e.g., missing values), but + * only the dimensionality and other preset properties of the data. + */ + void checkModuleProperties(const IAnalysisDataModule& module) const; + + /*! \brief + * Present data already added to the data object to a module. + * + * \param[in] data Data object to read data from. + * \param[in] module Module to present the data to. + * \throws APIError if \p module is not compatible with the data. + * \throws APIError if all data is not available through + * getDataFrame(). + * \throws unspecified Any exception thrown by \p module in its data + * notification methods. + * + * Uses getDataFrame() in \p data to access all data in the object, and + * calls the notification functions in \p module as if the module had + * been registered to the data object when the data was added. + */ + void presentData(AbstractAnalysisData* data, IAnalysisDataModule* module); + + //! List of modules added to the data. + ModuleList modules_; + //! Properties of the owning data for module checking. + bool bDataProperty_[eDataPropertyNR]; + //! true if all modules support missing data. + bool bAllowMissing_; + //! true if there are modules that do not support parallel processing. + bool bSerialModules_; + //! true if there are modules that support parallel processing. + bool bParallelModules_; + + /*! \brief + * Current state of the notification methods. + * + * This is used together with \a currIndex_ for sanity checks on the + * input data; invalid call sequences trigger asserts. + * The state of these variables does not otherwise affect the behavior + * of this class; this is the reason they can be changed in const + * methods. + */ + //! Whether notifyDataStart() has been called. + mutable State state_; + //! Index of currently active frame or the next frame if not in frame. + mutable int currIndex_; }; -AnalysisDataModuleManager::Impl::Impl() - : bDataProperty_(), // This must be in sync with how AbstractAnalysisData - // is actually initialized. - bAllowMissing_(true), bSerialModules_(false), bParallelModules_(false), - state_(eNotStarted), currIndex_(0) +AnalysisDataModuleManager::Impl::Impl() : + bDataProperty_(), // This must be in sync with how AbstractAnalysisData + // is actually initialized. + bAllowMissing_(true), + bSerialModules_(false), + bParallelModules_(false), + state_(eNotStarted), + currIndex_(0) { } -void -AnalysisDataModuleManager::Impl::checkModuleProperty( - const IAnalysisDataModule &module, - DataProperty property, bool bSet) const +void AnalysisDataModuleManager::Impl::checkModuleProperty(const IAnalysisDataModule& module, + DataProperty property, + bool bSet) const { bool bOk = true; const int flags = module.flags(); @@ -198,8 +200,7 @@ AnalysisDataModuleManager::Impl::checkModuleProperty( bOk = false; } break; - default: - GMX_RELEASE_ASSERT(false, "Invalid data property enumeration"); + default: GMX_RELEASE_ASSERT(false, "Invalid data property enumeration"); } if (!bOk) { @@ -207,9 +208,7 @@ AnalysisDataModuleManager::Impl::checkModuleProperty( } } -void -AnalysisDataModuleManager::Impl::checkModuleProperties( - const IAnalysisDataModule &module) const +void AnalysisDataModuleManager::Impl::checkModuleProperties(const IAnalysisDataModule& module) const { for (int i = 0; i < eDataPropertyNR; ++i) { @@ -217,19 +216,16 @@ AnalysisDataModuleManager::Impl::checkModuleProperties( } } -void -AnalysisDataModuleManager::Impl::presentData(AbstractAnalysisData *data, - IAnalysisDataModule *module) +void AnalysisDataModuleManager::Impl::presentData(AbstractAnalysisData* data, IAnalysisDataModule* module) { if (state_ == eNotStarted) { return; } - GMX_RELEASE_ASSERT(state_ != eInFrame, - "Cannot apply a modules in mid-frame"); + GMX_RELEASE_ASSERT(state_ != eInFrame, "Cannot apply a modules in mid-frame"); module->dataStarted(data); - const bool bCheckMissing = bAllowMissing_ - && ((module->flags() & IAnalysisDataModule::efAllowMissing) == 0); + const bool bCheckMissing = + bAllowMissing_ && ((module->flags() & IAnalysisDataModule::efAllowMissing) == 0); for (int i = 0; i < data->frameCount(); ++i) { AnalysisDataFrameRef frame = data->getDataFrame(i); @@ -258,17 +254,11 @@ AnalysisDataModuleManager::Impl::presentData(AbstractAnalysisData *data, * AnalysisDataModuleManager */ -AnalysisDataModuleManager::AnalysisDataModuleManager() - : impl_(new Impl()) -{ -} +AnalysisDataModuleManager::AnalysisDataModuleManager() : impl_(new Impl()) {} -AnalysisDataModuleManager::~AnalysisDataModuleManager() -{ -} +AnalysisDataModuleManager::~AnalysisDataModuleManager() {} -void -AnalysisDataModuleManager::dataPropertyAboutToChange(DataProperty property, bool bSet) +void AnalysisDataModuleManager::dataPropertyAboutToChange(DataProperty property, bool bSet) { GMX_RELEASE_ASSERT(impl_->state_ == Impl::eNotStarted, "Cannot change data properties after data has been started"); @@ -283,16 +273,13 @@ AnalysisDataModuleManager::dataPropertyAboutToChange(DataProperty property, bool } } -void -AnalysisDataModuleManager::addModule(AbstractAnalysisData *data, - const AnalysisDataModulePointer &module) +void AnalysisDataModuleManager::addModule(AbstractAnalysisData* data, const AnalysisDataModulePointer& module) { impl_->checkModuleProperties(*module); // TODO: Ensure that the system does not end up in an inconsistent state by // adding a module in mid-data during parallel processing (probably best to // prevent alltogether). - GMX_RELEASE_ASSERT(impl_->state_ != Impl::eInFrame, - "Cannot add a data module in mid-frame"); + GMX_RELEASE_ASSERT(impl_->state_ != Impl::eInFrame, "Cannot add a data module in mid-frame"); impl_->presentData(data, module.get()); if (!(module->flags() & IAnalysisDataModule::efAllowMissing)) @@ -302,9 +289,7 @@ AnalysisDataModuleManager::addModule(AbstractAnalysisData *data, impl_->modules_.emplace_back(module); } -void -AnalysisDataModuleManager::applyModule(AbstractAnalysisData *data, - IAnalysisDataModule *module) +void AnalysisDataModuleManager::applyModule(AbstractAnalysisData* data, IAnalysisDataModule* module) { impl_->checkModuleProperties(*module); GMX_RELEASE_ASSERT(impl_->state_ == Impl::eFinished, @@ -313,8 +298,7 @@ AnalysisDataModuleManager::applyModule(AbstractAnalysisData *data, } -bool -AnalysisDataModuleManager::hasSerialModules() const +bool AnalysisDataModuleManager::hasSerialModules() const { GMX_ASSERT(impl_->state_ != Impl::eNotStarted, "Module state not accessible before data is started"); @@ -322,15 +306,13 @@ AnalysisDataModuleManager::hasSerialModules() const } -void -AnalysisDataModuleManager::notifyDataStart(AbstractAnalysisData *data) +void AnalysisDataModuleManager::notifyDataStart(AbstractAnalysisData* data) { GMX_RELEASE_ASSERT(impl_->state_ == Impl::eNotStarted, "notifyDataStart() called more than once"); for (int d = 0; d < data->dataSetCount(); ++d) { - GMX_RELEASE_ASSERT(data->columnCount(d) > 0, - "Data column count is not set"); + GMX_RELEASE_ASSERT(data->columnCount(d) > 0, "Data column count is not set"); } impl_->state_ = Impl::eInData; impl_->bSerialModules_ = !impl_->modules_.empty(); @@ -348,17 +330,14 @@ AnalysisDataModuleManager::notifyDataStart(AbstractAnalysisData *data) } -void -AnalysisDataModuleManager::notifyParallelDataStart( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) +void AnalysisDataModuleManager::notifyParallelDataStart(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) { GMX_RELEASE_ASSERT(impl_->state_ == Impl::eNotStarted, "notifyDataStart() called more than once"); for (int d = 0; d < data->dataSetCount(); ++d) { - GMX_RELEASE_ASSERT(data->columnCount(d) > 0, - "Data column count is not set"); + GMX_RELEASE_ASSERT(data->columnCount(d) > 0, "Data column count is not set"); } impl_->state_ = Impl::eInData; impl_->bSerialModules_ = false; @@ -384,12 +363,11 @@ AnalysisDataModuleManager::notifyParallelDataStart( } -void -AnalysisDataModuleManager::notifyFrameStart(const AnalysisDataFrameHeader &header) const +void AnalysisDataModuleManager::notifyFrameStart(const AnalysisDataFrameHeader& header) const { GMX_ASSERT(impl_->state_ == Impl::eInData, "Invalid call sequence"); GMX_ASSERT(header.index() == impl_->currIndex_, "Out of order frames"); - impl_->state_ = Impl::eInFrame; + impl_->state_ = Impl::eInFrame; if (impl_->bSerialModules_) { @@ -404,9 +382,7 @@ AnalysisDataModuleManager::notifyFrameStart(const AnalysisDataFrameHeader &heade } } -void -AnalysisDataModuleManager::notifyParallelFrameStart( - const AnalysisDataFrameHeader &header) const +void AnalysisDataModuleManager::notifyParallelFrameStart(const AnalysisDataFrameHeader& header) const { if (impl_->bParallelModules_) { @@ -422,13 +398,12 @@ AnalysisDataModuleManager::notifyParallelFrameStart( } -void -AnalysisDataModuleManager::notifyPointsAdd(const AnalysisDataPointSetRef &points) const +void AnalysisDataModuleManager::notifyPointsAdd(const AnalysisDataPointSetRef& points) const { GMX_ASSERT(impl_->state_ == Impl::eInFrame, "notifyFrameStart() not called"); // TODO: Add checks for column spans (requires passing the information // about the column counts from somewhere). - //GMX_ASSERT(points.lastColumn() < columnCount(points.dataSetIndex()), + // GMX_ASSERT(points.lastColumn() < columnCount(points.dataSetIndex()), // "Invalid columns"); GMX_ASSERT(points.frameIndex() == impl_->currIndex_, "Points do not correspond to current frame"); @@ -451,13 +426,11 @@ AnalysisDataModuleManager::notifyPointsAdd(const AnalysisDataPointSetRef &points } -void -AnalysisDataModuleManager::notifyParallelPointsAdd( - const AnalysisDataPointSetRef &points) const +void AnalysisDataModuleManager::notifyParallelPointsAdd(const AnalysisDataPointSetRef& points) const { // TODO: Add checks for column spans (requires passing the information // about the column counts from somewhere). - //GMX_ASSERT(points.lastColumn() < columnCount(points.dataSetIndex()), + // GMX_ASSERT(points.lastColumn() < columnCount(points.dataSetIndex()), // "Invalid columns"); if (impl_->bParallelModules_) { @@ -478,12 +451,10 @@ AnalysisDataModuleManager::notifyParallelPointsAdd( } -void -AnalysisDataModuleManager::notifyFrameFinish(const AnalysisDataFrameHeader &header) const +void AnalysisDataModuleManager::notifyFrameFinish(const AnalysisDataFrameHeader& header) const { GMX_ASSERT(impl_->state_ == Impl::eInFrame, "notifyFrameStart() not called"); - GMX_ASSERT(header.index() == impl_->currIndex_, - "Header does not correspond to current frame"); + GMX_ASSERT(header.index() == impl_->currIndex_, "Header does not correspond to current frame"); // TODO: Add a check for the frame count in the source data including this // frame. impl_->state_ = Impl::eInData; @@ -508,9 +479,7 @@ AnalysisDataModuleManager::notifyFrameFinish(const AnalysisDataFrameHeader &head } -void -AnalysisDataModuleManager::notifyParallelFrameFinish( - const AnalysisDataFrameHeader &header) const +void AnalysisDataModuleManager::notifyParallelFrameFinish(const AnalysisDataFrameHeader& header) const { if (impl_->bParallelModules_) { @@ -526,8 +495,7 @@ AnalysisDataModuleManager::notifyParallelFrameFinish( } -void -AnalysisDataModuleManager::notifyDataFinish() const +void AnalysisDataModuleManager::notifyDataFinish() const { GMX_RELEASE_ASSERT(impl_->state_ == Impl::eInData, "Invalid call sequence"); impl_->state_ = Impl::eFinished; diff --git a/src/gromacs/analysisdata/datamodulemanager.h b/src/gromacs/analysisdata/datamodulemanager.h index 72909dc768..09f40e219b 100644 --- a/src/gromacs/analysisdata/datamodulemanager.h +++ b/src/gromacs/analysisdata/datamodulemanager.h @@ -62,220 +62,216 @@ class AnalysisDataParallelOptions; */ class AnalysisDataModuleManager { - public: - /*! \brief - * Identifies data properties to check with data modules. - * - * \see IAnalysisDataModule::Flag - */ - enum DataProperty - { - eMultipleDataSets, //!< Data has multiple data sets. - eMultipleColumns, //!< Data has multiple columns. - eMultipoint, //!< Data is multipoint. - eDataPropertyNR //!< Number of properties; for internal use only. - }; +public: + /*! \brief + * Identifies data properties to check with data modules. + * + * \see IAnalysisDataModule::Flag + */ + enum DataProperty + { + eMultipleDataSets, //!< Data has multiple data sets. + eMultipleColumns, //!< Data has multiple columns. + eMultipoint, //!< Data is multipoint. + eDataPropertyNR //!< Number of properties; for internal use only. + }; - AnalysisDataModuleManager(); - ~AnalysisDataModuleManager(); + AnalysisDataModuleManager(); + ~AnalysisDataModuleManager(); - /*! \brief - * Allows the manager to check modules for compatibility with the data. - * - * \throws APIError if any data module already added is not compatible - * with the new setting. - * - * Does two things: checks any modules already attached to the data and - * throws if any of them is not compatible, and stores the property - * to check modules attached in the future. - * - * Strong exception safety. - */ - void dataPropertyAboutToChange(DataProperty property, bool bSet); + /*! \brief + * Allows the manager to check modules for compatibility with the data. + * + * \throws APIError if any data module already added is not compatible + * with the new setting. + * + * Does two things: checks any modules already attached to the data and + * throws if any of them is not compatible, and stores the property + * to check modules attached in the future. + * + * Strong exception safety. + */ + void dataPropertyAboutToChange(DataProperty property, bool bSet); - /*! \brief - * Whether there are modules that do not support parallel processing. - * - * Must not be called before notifyDataStart()/notifyParallelDataStart(). - * If notifyDataStart() has been called, returns true if there are any - * modules (all modules are treated as serial). - * - * Does not throw. - */ - bool hasSerialModules() const; + /*! \brief + * Whether there are modules that do not support parallel processing. + * + * Must not be called before notifyDataStart()/notifyParallelDataStart(). + * If notifyDataStart() has been called, returns true if there are any + * modules (all modules are treated as serial). + * + * Does not throw. + */ + bool hasSerialModules() const; - /*! \brief - * Adds a module to process the data. - * - * \param data Data object to add the module to. - * \param module Module to add. - * \throws std::bad_alloc if out of memory. - * \throws APIError if - * - \p module is not compatible with the data object - * - data has already been added to the data object and everything - * is not available through getDataFrame(). - * \throws unspecified Any exception thrown by \p module in its - * notification methods (if data has been added). - * - * \see AbstractAnalysisData::addModule() - */ - void addModule(AbstractAnalysisData *data, - const AnalysisDataModulePointer &module); - /*! \brief - * Applies a module to process data that is ready. - * - * \param data Data object to apply the module to. - * \param module Module to apply. - * \throws APIError in same situations as addModule(). - * \throws unspecified Any exception thrown by \p module in its - * notification methods. - * - * \see AbstractAnalysisData::applyModule() - */ - void applyModule(AbstractAnalysisData *data, - IAnalysisDataModule *module); + /*! \brief + * Adds a module to process the data. + * + * \param data Data object to add the module to. + * \param module Module to add. + * \throws std::bad_alloc if out of memory. + * \throws APIError if + * - \p module is not compatible with the data object + * - data has already been added to the data object and everything + * is not available through getDataFrame(). + * \throws unspecified Any exception thrown by \p module in its + * notification methods (if data has been added). + * + * \see AbstractAnalysisData::addModule() + */ + void addModule(AbstractAnalysisData* data, const AnalysisDataModulePointer& module); + /*! \brief + * Applies a module to process data that is ready. + * + * \param data Data object to apply the module to. + * \param module Module to apply. + * \throws APIError in same situations as addModule(). + * \throws unspecified Any exception thrown by \p module in its + * notification methods. + * + * \see AbstractAnalysisData::applyModule() + */ + void applyModule(AbstractAnalysisData* data, IAnalysisDataModule* module); - /*! \brief - * Notifies attached modules of the start of serial data. - * - * \param data Data object that is starting. - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::dataStarted(). - * - * Should be called once, after data properties have been set with - * the methods in AbstractAnalysisData, and before any other - * notification methods. - * The caller should be prepared for requestStorage() calls to \p data - * from the attached modules. - * - * \p data should typically be \c this when calling from a class - * derived from AbstractAnalysisData. - * - * This method initializes all modules for serial processing by calling - * IAnalysisDataModule::dataStarted(). - */ - void notifyDataStart(AbstractAnalysisData *data); - /*! \brief - * Notifies attached modules of the start of parallel data. - * - * \param data Data object that is starting. - * \param[in] options Parallelization properties of the input data. - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::parallelDataStarted(). - * - * Can be called instead of notifyDataStart() if \p data supports - * non-sequential creation of frames. Works as notifyDataStart(), - * but instead calls IAnalysisDataModule::parallelDataStarted() - * and records whether the module supports the parallel mode. - * Subsequent notification calls then notify the modules according to - * the mode they accept. - * - * See notifyDataStart() for general constraints. - */ - void notifyParallelDataStart( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options); - /*! \brief - * Notifies attached serial modules of the start of a frame. - * - * \param[in] header Header information for the frame that is starting. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::frameStarted(). - * - * Should be called once for each frame, before notifyPointsAdd() calls - * for that frame. - */ - void notifyFrameStart(const AnalysisDataFrameHeader &header) const; - /*! \brief - * Notifies attached parallel modules of the start of a frame. - * - * \param[in] header Header information for the frame that is starting. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::frameStarted(). - * - * If notifyParallelDataStart() has been called, should be called once - * for each frame, before notifyParallelPointsAdd() calls for that - * frame. - * It is allowed to call this method in any order for the frames, but - * should be called exactly once for each frame. - */ - void notifyParallelFrameStart(const AnalysisDataFrameHeader &header) const; - /*! \brief - * Notifies attached serial modules of the addition of points to the - * current frame. - * - * \param[in] points Set of points added (also provides access to - * frame-level data). - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::pointsAdded(). - * - * Can be called zero or more times for each frame. - * The caller should ensure that any column occurs at most once in the - * calls, unless the data is multipoint. - * For efficiency reasons, calls to this method should be aggregated - * whenever possible, i.e., it's better to handle multiple columns or - * even the whole frame in a single call rather than calling the method - * for each column separately. - */ - void notifyPointsAdd(const AnalysisDataPointSetRef &points) const; - /*! \brief - * Notifies attached parallel modules of the addition of points to a frame. - * - * \param[in] points Set of points added (also provides access to - * frame-level data). - * \throws APIError if any attached data module is not compatible. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::pointsAdded(). - * - * See notifyPointsAdd() for information on the structure of the point - * sets. - */ - void notifyParallelPointsAdd(const AnalysisDataPointSetRef &points) const; - /*! \brief - * Notifies attached serial modules of the end of a frame. - * - * \param[in] header Header information for the frame that is ending. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::frameFinished(). - * - * Should be called once for each call of notifyFrameStart(), after any - * notifyPointsAdd() calls for the frame. - * \p header should be identical to that used in the corresponding - * notifyFrameStart() call. - * - * This method also notifies parallel modules about serial end of frame. - */ - void notifyFrameFinish(const AnalysisDataFrameHeader &header) const; - /*! \brief - * Notifies attached parallel modules of the end of a frame. - * - * \param[in] header Header information for the frame that is ending. - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::frameFinished(). - * - * Should be called once for each call of notifyParallelFrameStart(), - * after any notifyParallelPointsAdd() calls for the frame. - * \p header should be identical to that used in the corresponding - * notifyParallelFrameStart() call. - */ - void notifyParallelFrameFinish(const AnalysisDataFrameHeader &header) const; - /*! \brief - * Notifies attached modules of the end of data. - * - * \throws unspecified Any exception thrown by attached data modules - * in IAnalysisDataModule::dataFinished(). - * - * Should be called once, after all the other notification calls. - */ - void notifyDataFinish() const; + /*! \brief + * Notifies attached modules of the start of serial data. + * + * \param data Data object that is starting. + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::dataStarted(). + * + * Should be called once, after data properties have been set with + * the methods in AbstractAnalysisData, and before any other + * notification methods. + * The caller should be prepared for requestStorage() calls to \p data + * from the attached modules. + * + * \p data should typically be \c this when calling from a class + * derived from AbstractAnalysisData. + * + * This method initializes all modules for serial processing by calling + * IAnalysisDataModule::dataStarted(). + */ + void notifyDataStart(AbstractAnalysisData* data); + /*! \brief + * Notifies attached modules of the start of parallel data. + * + * \param data Data object that is starting. + * \param[in] options Parallelization properties of the input data. + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::parallelDataStarted(). + * + * Can be called instead of notifyDataStart() if \p data supports + * non-sequential creation of frames. Works as notifyDataStart(), + * but instead calls IAnalysisDataModule::parallelDataStarted() + * and records whether the module supports the parallel mode. + * Subsequent notification calls then notify the modules according to + * the mode they accept. + * + * See notifyDataStart() for general constraints. + */ + void notifyParallelDataStart(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options); + /*! \brief + * Notifies attached serial modules of the start of a frame. + * + * \param[in] header Header information for the frame that is starting. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::frameStarted(). + * + * Should be called once for each frame, before notifyPointsAdd() calls + * for that frame. + */ + void notifyFrameStart(const AnalysisDataFrameHeader& header) const; + /*! \brief + * Notifies attached parallel modules of the start of a frame. + * + * \param[in] header Header information for the frame that is starting. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::frameStarted(). + * + * If notifyParallelDataStart() has been called, should be called once + * for each frame, before notifyParallelPointsAdd() calls for that + * frame. + * It is allowed to call this method in any order for the frames, but + * should be called exactly once for each frame. + */ + void notifyParallelFrameStart(const AnalysisDataFrameHeader& header) const; + /*! \brief + * Notifies attached serial modules of the addition of points to the + * current frame. + * + * \param[in] points Set of points added (also provides access to + * frame-level data). + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::pointsAdded(). + * + * Can be called zero or more times for each frame. + * The caller should ensure that any column occurs at most once in the + * calls, unless the data is multipoint. + * For efficiency reasons, calls to this method should be aggregated + * whenever possible, i.e., it's better to handle multiple columns or + * even the whole frame in a single call rather than calling the method + * for each column separately. + */ + void notifyPointsAdd(const AnalysisDataPointSetRef& points) const; + /*! \brief + * Notifies attached parallel modules of the addition of points to a frame. + * + * \param[in] points Set of points added (also provides access to + * frame-level data). + * \throws APIError if any attached data module is not compatible. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::pointsAdded(). + * + * See notifyPointsAdd() for information on the structure of the point + * sets. + */ + void notifyParallelPointsAdd(const AnalysisDataPointSetRef& points) const; + /*! \brief + * Notifies attached serial modules of the end of a frame. + * + * \param[in] header Header information for the frame that is ending. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::frameFinished(). + * + * Should be called once for each call of notifyFrameStart(), after any + * notifyPointsAdd() calls for the frame. + * \p header should be identical to that used in the corresponding + * notifyFrameStart() call. + * + * This method also notifies parallel modules about serial end of frame. + */ + void notifyFrameFinish(const AnalysisDataFrameHeader& header) const; + /*! \brief + * Notifies attached parallel modules of the end of a frame. + * + * \param[in] header Header information for the frame that is ending. + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::frameFinished(). + * + * Should be called once for each call of notifyParallelFrameStart(), + * after any notifyParallelPointsAdd() calls for the frame. + * \p header should be identical to that used in the corresponding + * notifyParallelFrameStart() call. + */ + void notifyParallelFrameFinish(const AnalysisDataFrameHeader& header) const; + /*! \brief + * Notifies attached modules of the end of data. + * + * \throws unspecified Any exception thrown by attached data modules + * in IAnalysisDataModule::dataFinished(). + * + * Should be called once, after all the other notification calls. + */ + void notifyDataFinish() const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/dataproxy.cpp b/src/gromacs/analysisdata/dataproxy.cpp index 614f84d00e..6417272fc4 100644 --- a/src/gromacs/analysisdata/dataproxy.cpp +++ b/src/gromacs/analysisdata/dataproxy.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2017, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,10 +50,11 @@ namespace gmx { -AnalysisDataProxy::AnalysisDataProxy(int firstColumn, int columnSpan, - AbstractAnalysisData *data) - : source_(*data), firstColumn_(firstColumn), columnSpan_(columnSpan), - bParallel_(false) +AnalysisDataProxy::AnalysisDataProxy(int firstColumn, int columnSpan, AbstractAnalysisData* data) : + source_(*data), + firstColumn_(firstColumn), + columnSpan_(columnSpan), + bParallel_(false) { GMX_RELEASE_ASSERT(data != nullptr, "Source data must not be NULL"); GMX_RELEASE_ASSERT(firstColumn >= 0 && columnSpan > 0, "Invalid proxy column"); @@ -61,15 +62,13 @@ AnalysisDataProxy::AnalysisDataProxy(int firstColumn, int columnSpan, } -int -AnalysisDataProxy::frameCount() const +int AnalysisDataProxy::frameCount() const { return source_.frameCount(); } -AnalysisDataFrameRef -AnalysisDataProxy::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AnalysisDataProxy::tryGetDataFrameInternal(int index) const { AnalysisDataFrameRef frame = source_.tryGetDataFrame(index); if (!frame.isValid()) @@ -80,23 +79,19 @@ AnalysisDataProxy::tryGetDataFrameInternal(int index) const } -bool -AnalysisDataProxy::requestStorageInternal(int nframes) +bool AnalysisDataProxy::requestStorageInternal(int nframes) { return source_.requestStorage(nframes); } -int -AnalysisDataProxy::flags() const +int AnalysisDataProxy::flags() const { - return efAllowMultipoint | efAllowMulticolumn | efAllowMissing - | efAllowMultipleDataSets; + return efAllowMultipoint | efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets; } -void -AnalysisDataProxy::dataStarted(AbstractAnalysisData *data) +void AnalysisDataProxy::dataStarted(AbstractAnalysisData* data) { GMX_RELEASE_ASSERT(data == &source_, "Source data mismatch"); setDataSetCount(data->dataSetCount()); @@ -108,10 +103,8 @@ AnalysisDataProxy::dataStarted(AbstractAnalysisData *data) } -bool -AnalysisDataProxy::parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) +bool AnalysisDataProxy::parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) { GMX_RELEASE_ASSERT(data == &source_, "Source data mismatch"); setDataSetCount(data->dataSetCount()); @@ -125,8 +118,7 @@ AnalysisDataProxy::parallelDataStarted( } -void -AnalysisDataProxy::frameStarted(const AnalysisDataFrameHeader &frame) +void AnalysisDataProxy::frameStarted(const AnalysisDataFrameHeader& frame) { if (bParallel_) { @@ -139,8 +131,7 @@ AnalysisDataProxy::frameStarted(const AnalysisDataFrameHeader &frame) } -void -AnalysisDataProxy::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataProxy::pointsAdded(const AnalysisDataPointSetRef& points) { AnalysisDataPointSetRef columns(points, firstColumn_, columnSpan_); if (columns.columnCount() > 0) @@ -157,8 +148,7 @@ AnalysisDataProxy::pointsAdded(const AnalysisDataPointSetRef &points) } -void -AnalysisDataProxy::frameFinished(const AnalysisDataFrameHeader &header) +void AnalysisDataProxy::frameFinished(const AnalysisDataFrameHeader& header) { if (bParallel_) { @@ -170,8 +160,7 @@ AnalysisDataProxy::frameFinished(const AnalysisDataFrameHeader &header) } } -void -AnalysisDataProxy::frameFinishedSerial(int frameIndex) +void AnalysisDataProxy::frameFinishedSerial(int frameIndex) { if (bParallel_) { @@ -182,8 +171,7 @@ AnalysisDataProxy::frameFinishedSerial(int frameIndex) } -void -AnalysisDataProxy::dataFinished() +void AnalysisDataProxy::dataFinished() { moduleManager().notifyDataFinish(); } diff --git a/src/gromacs/analysisdata/dataproxy.h b/src/gromacs/analysisdata/dataproxy.h index 3f73f75bdc..b10535a9cd 100644 --- a/src/gromacs/analysisdata/dataproxy.h +++ b/src/gromacs/analysisdata/dataproxy.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,46 +64,42 @@ namespace gmx * * \ingroup module_analysisdata */ -class AnalysisDataProxy : public AbstractAnalysisData, - public IAnalysisDataModule +class AnalysisDataProxy : public AbstractAnalysisData, public IAnalysisDataModule { - public: - /*! \brief - * Creates a proxy object that only presents certain columns. - * - * \param[in] firstColumn First column to present. - * \param[in] columnSpan Number of columns to present. - * \param[in] data Data object that should be wrapped. - * - * Does not throw. - */ - AnalysisDataProxy(int firstColumn, int columnSpan, - AbstractAnalysisData *data); +public: + /*! \brief + * Creates a proxy object that only presents certain columns. + * + * \param[in] firstColumn First column to present. + * \param[in] columnSpan Number of columns to present. + * \param[in] data Data object that should be wrapped. + * + * Does not throw. + */ + AnalysisDataProxy(int firstColumn, int columnSpan, AbstractAnalysisData* data); - int frameCount() const override; + int frameCount() const override; - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) override; - void frameStarted(const AnalysisDataFrameHeader &frame) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void frameFinishedSerial(int frameIndex) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + bool parallelDataStarted(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options) override; + void frameStarted(const AnalysisDataFrameHeader& frame) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void frameFinishedSerial(int frameIndex) override; + void dataFinished() override; - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - AbstractAnalysisData &source_; - int firstColumn_; - int columnSpan_; - bool bParallel_; + AbstractAnalysisData& source_; + int firstColumn_; + int columnSpan_; + bool bParallel_; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; } // namespace gmx diff --git a/src/gromacs/analysisdata/datastorage.cpp b/src/gromacs/analysisdata/datastorage.cpp index 1379f93f84..e5b9302340 100644 --- a/src/gromacs/analysisdata/datastorage.cpp +++ b/src/gromacs/analysisdata/datastorage.cpp @@ -63,17 +63,13 @@ namespace gmx * AnalysisDataParallelOptions */ -AnalysisDataParallelOptions::AnalysisDataParallelOptions() - : parallelizationFactor_(1) -{ -} +AnalysisDataParallelOptions::AnalysisDataParallelOptions() : parallelizationFactor_(1) {} -AnalysisDataParallelOptions::AnalysisDataParallelOptions(int parallelizationFactor) - : parallelizationFactor_(parallelizationFactor) +AnalysisDataParallelOptions::AnalysisDataParallelOptions(int parallelizationFactor) : + parallelizationFactor_(parallelizationFactor) { - GMX_RELEASE_ASSERT(parallelizationFactor >= 1, - "Invalid parallelization factor"); + GMX_RELEASE_ASSERT(parallelizationFactor >= 1, "Invalid parallelization factor"); } @@ -85,8 +81,7 @@ namespace internal { //! Smart pointer type for managing a storage frame builder. -typedef std::unique_ptr - AnalysisDataFrameBuilderPointer; +typedef std::unique_ptr AnalysisDataFrameBuilderPointer; /*! \internal \brief * Private implementation class for AnalysisDataStorage. @@ -95,181 +90,178 @@ typedef std::unique_ptr */ class AnalysisDataStorageImpl { - public: - //! Smart pointer type for managing a stored frame. - typedef std::unique_ptr FramePointer; - - //! Shorthand for a list of data frames that are currently stored. - typedef std::vector FrameList; - //! Shorthand for a list of currently unused storage frame builders. - typedef std::vector FrameBuilderList; - - AnalysisDataStorageImpl(); - - //! Returns whether the storage is set to use multipoint data. - bool isMultipoint() const; - /*! \brief - * Whether storage of all frames has been requested. - * - * Storage of all frames also works as expected if \a storageLimit_ is - * used in comparisons directly, but this method should be used to - * check how to manage \a frames_. - */ - bool storeAll() const - { - return storageLimit_ == std::numeric_limits::max(); - } - //! Returns the index of the oldest frame that may be currently stored. - int firstStoredIndex() const; - //! Returns the index of the first frame that is not fully notified. - int firstUnnotifiedIndex() const { return firstUnnotifiedIndex_; } - /*! \brief - * Computes index into \a frames_ for accessing frame \p index. - * - * \param[in] index Zero-based frame index. - * \retval -1 if \p index is not available in \a frames_. - * - * Does not throw. - */ - int computeStorageLocation(int index) const; - - /*! \brief - * Computes an index into \a frames_ that is one past the last frame - * stored. - * - * Does not throw. - */ - size_t endStorageLocation() const; - - /*! \brief - * Extends \a frames_ to a new size. - * - * \throws std::bad_alloc if out of memory. - */ - void extendBuffer(size_t newSize); - /*! \brief - * Remove oldest frame from the storage to make space for a new one. - * - * Increments \a firstFrameLocation_ and reinitializes the frame that - * was made unavailable by this operation. - * - * Does not throw. - * - * \see frames_ - */ - void rotateBuffer(); - - /*! \brief - * Returns a frame builder object for use with a new frame. - * - * \throws std::bad_alloc if out of memory. - */ - AnalysisDataFrameBuilderPointer getFrameBuilder(); - - /*! \brief - * Returns whether notifications should be immediately fired. - * - * This is used to optimize multipoint handling for non-parallel cases, - * where it is not necessary to store even a single frame. - * - * Does not throw. - */ - bool shouldNotifyImmediately() const - { - return isMultipoint() && storageLimit_ == 0 && pendingLimit_ == 1; - } - /*! \brief - * Returns whether data needs to be stored at all. - * - * This is used to optimize multipoint handling for parallel cases - * (where shouldNotifyImmediately() returns false), - * where it is not necessary to store even a single frame. - * - * \todo - * This could be extended to non-multipoint data as well. - * - * Does not throw. - */ - bool needStorage() const - { - return storageLimit_ > 0 || (pendingLimit_ > 1 && modules_->hasSerialModules()); - } - //! Implementation for AnalysisDataStorage::finishFrame(). - void finishFrame(int index); - /*! \brief - * Implementation for AnalysisDataStorage::finishFrameSerial(). - */ - void finishFrameSerial(int index); - - - //! Parent data object to access data dimensionality etc. - const AbstractAnalysisData *data_; - //! Manager to use for notification calls. - AnalysisDataModuleManager *modules_; - /*! \brief - * Number of past frames that need to be stored. - * - * Always non-negative. If storage of all frames has been requested, - * this is set to a large number. - */ - int storageLimit_; - /*! \brief - * Number of future frames that may need to be started. - * - * Should always be at least one. - * - * \todo - * Get rid of this alltogether, as it is no longer used much. - * - * \see AnalysisDataStorage::startFrame() - */ - int pendingLimit_; - /*! \brief - * Data frames that are currently stored. - * - * If storage of all frames has been requested, this is simply a vector - * of frames up to the latest frame that has been started. - * In this case, \a firstFrameLocation_ is always zero. - * - * If storage of all frames is not requested, this is a ring buffer of - * frames of size \c n=storageLimit_+pendingLimit_+1. If a frame with - * index \c index is currently stored, its location is - * \c index%frames_.size(). - * When at most \a storageLimit_ first frames have been finished, - * this contains storage for the first \c n-1 frames. - * When more than \a storageLimit_ first frames have been finished, - * the oldest stored frame is stored in the location - * \a firstFrameLocation_, and \a storageLimit_ frames starting from - * this location are the last finished frames. \a pendingLimit_ frames - * follow, and some of these may be in progress or finished. - * There is always one unused frame in the buffer, which is initialized - * such that when \a firstFrameLocation_ is incremented, it becomes - * valid. This makes it easier to rotate the buffer in concurrent - * access scenarions (which are not yet otherwise implemented). - */ - FrameList frames_; - //! Location of oldest frame in \a frames_. - size_t firstFrameLocation_; - //! Index of the first frame that is not fully notified. - int firstUnnotifiedIndex_; - /*! \brief - * Currently unused frame builders. - * - * The builders are cached to avoid repeatedly allocating memory for - * them. Typically, there are as many builders as there are concurrent - * users of the storage object. Whenever a frame is started, a builder - * is pulled from this pool by getFrameBuilder() (a new one is created - * if none are available), and assigned for that frame. When that - * frame is finished, the builder is returned to this pool. - */ - FrameBuilderList builders_; - /*! \brief - * Index of next frame that will be added to \a frames_. - * - * If all frames are not stored, this will be the index of the unused - * frame (see \a frames_). - */ - int nextIndex_; +public: + //! Smart pointer type for managing a stored frame. + typedef std::unique_ptr FramePointer; + + //! Shorthand for a list of data frames that are currently stored. + typedef std::vector FrameList; + //! Shorthand for a list of currently unused storage frame builders. + typedef std::vector FrameBuilderList; + + AnalysisDataStorageImpl(); + + //! Returns whether the storage is set to use multipoint data. + bool isMultipoint() const; + /*! \brief + * Whether storage of all frames has been requested. + * + * Storage of all frames also works as expected if \a storageLimit_ is + * used in comparisons directly, but this method should be used to + * check how to manage \a frames_. + */ + bool storeAll() const { return storageLimit_ == std::numeric_limits::max(); } + //! Returns the index of the oldest frame that may be currently stored. + int firstStoredIndex() const; + //! Returns the index of the first frame that is not fully notified. + int firstUnnotifiedIndex() const { return firstUnnotifiedIndex_; } + /*! \brief + * Computes index into \a frames_ for accessing frame \p index. + * + * \param[in] index Zero-based frame index. + * \retval -1 if \p index is not available in \a frames_. + * + * Does not throw. + */ + int computeStorageLocation(int index) const; + + /*! \brief + * Computes an index into \a frames_ that is one past the last frame + * stored. + * + * Does not throw. + */ + size_t endStorageLocation() const; + + /*! \brief + * Extends \a frames_ to a new size. + * + * \throws std::bad_alloc if out of memory. + */ + void extendBuffer(size_t newSize); + /*! \brief + * Remove oldest frame from the storage to make space for a new one. + * + * Increments \a firstFrameLocation_ and reinitializes the frame that + * was made unavailable by this operation. + * + * Does not throw. + * + * \see frames_ + */ + void rotateBuffer(); + + /*! \brief + * Returns a frame builder object for use with a new frame. + * + * \throws std::bad_alloc if out of memory. + */ + AnalysisDataFrameBuilderPointer getFrameBuilder(); + + /*! \brief + * Returns whether notifications should be immediately fired. + * + * This is used to optimize multipoint handling for non-parallel cases, + * where it is not necessary to store even a single frame. + * + * Does not throw. + */ + bool shouldNotifyImmediately() const + { + return isMultipoint() && storageLimit_ == 0 && pendingLimit_ == 1; + } + /*! \brief + * Returns whether data needs to be stored at all. + * + * This is used to optimize multipoint handling for parallel cases + * (where shouldNotifyImmediately() returns false), + * where it is not necessary to store even a single frame. + * + * \todo + * This could be extended to non-multipoint data as well. + * + * Does not throw. + */ + bool needStorage() const + { + return storageLimit_ > 0 || (pendingLimit_ > 1 && modules_->hasSerialModules()); + } + //! Implementation for AnalysisDataStorage::finishFrame(). + void finishFrame(int index); + /*! \brief + * Implementation for AnalysisDataStorage::finishFrameSerial(). + */ + void finishFrameSerial(int index); + + + //! Parent data object to access data dimensionality etc. + const AbstractAnalysisData* data_; + //! Manager to use for notification calls. + AnalysisDataModuleManager* modules_; + /*! \brief + * Number of past frames that need to be stored. + * + * Always non-negative. If storage of all frames has been requested, + * this is set to a large number. + */ + int storageLimit_; + /*! \brief + * Number of future frames that may need to be started. + * + * Should always be at least one. + * + * \todo + * Get rid of this alltogether, as it is no longer used much. + * + * \see AnalysisDataStorage::startFrame() + */ + int pendingLimit_; + /*! \brief + * Data frames that are currently stored. + * + * If storage of all frames has been requested, this is simply a vector + * of frames up to the latest frame that has been started. + * In this case, \a firstFrameLocation_ is always zero. + * + * If storage of all frames is not requested, this is a ring buffer of + * frames of size \c n=storageLimit_+pendingLimit_+1. If a frame with + * index \c index is currently stored, its location is + * \c index%frames_.size(). + * When at most \a storageLimit_ first frames have been finished, + * this contains storage for the first \c n-1 frames. + * When more than \a storageLimit_ first frames have been finished, + * the oldest stored frame is stored in the location + * \a firstFrameLocation_, and \a storageLimit_ frames starting from + * this location are the last finished frames. \a pendingLimit_ frames + * follow, and some of these may be in progress or finished. + * There is always one unused frame in the buffer, which is initialized + * such that when \a firstFrameLocation_ is incremented, it becomes + * valid. This makes it easier to rotate the buffer in concurrent + * access scenarions (which are not yet otherwise implemented). + */ + FrameList frames_; + //! Location of oldest frame in \a frames_. + size_t firstFrameLocation_; + //! Index of the first frame that is not fully notified. + int firstUnnotifiedIndex_; + /*! \brief + * Currently unused frame builders. + * + * The builders are cached to avoid repeatedly allocating memory for + * them. Typically, there are as many builders as there are concurrent + * users of the storage object. Whenever a frame is started, a builder + * is pulled from this pool by getFrameBuilder() (a new one is created + * if none are available), and assigned for that frame. When that + * frame is finished, the builder is returned to this pool. + */ + FrameBuilderList builders_; + /*! \brief + * Index of next frame that will be added to \a frames_. + * + * If all frames are not stored, this will be the index of the unused + * frame (see \a frames_). + */ + int nextIndex_; }; /******************************************************************** @@ -289,137 +281,135 @@ class AnalysisDataStorageImpl */ class AnalysisDataStorageFrameData { - public: - //! Indicates what operations have been performed on a frame. - enum Status - { - eMissing, //!< Frame has not yet been started. - eStarted, //!< startFrame() has been called. - eFinished, //!< finishFrame() has been called. - eNotified //!< Appropriate notifications have been sent. - }; - - /*! \brief - * Create a new storage frame. - * - * \param storageImpl Storage object this frame belongs to. - * \param[in] index Zero-based index for the frame. - */ - AnalysisDataStorageFrameData(AnalysisDataStorageImpl *storageImpl, - int index); - - //! Whether the frame has been started with startFrame(). - bool isStarted() const { return status_ >= eStarted; } - //! Whether the frame has been finished with finishFrame(). - bool isFinished() const { return status_ >= eFinished; } - //! Whether all notifications have been sent. - bool isNotified() const { return status_ >= eNotified; } - //! Whether the frame is ready to be available outside the storage. - bool isAvailable() const { return status_ >= eFinished; } - - //! Marks the frame as notified. - void markNotified() { status_ = eNotified; } - - //! Returns the storage implementation object. - AnalysisDataStorageImpl &storageImpl() const { return storageImpl_; } - //! Returns the underlying data object (for data dimensionalities etc.). - const AbstractAnalysisData &baseData() const { return *storageImpl().data_; } - - //! Returns header for the frame. - const AnalysisDataFrameHeader &header() const { return header_; } - //! Returns zero-based index of the frame. - int frameIndex() const { return header().index(); } - //! Returns the number of point sets for the frame. - int pointSetCount() const { return pointSets_.size(); } - - //! Clears the frame for reusing as a new frame. - void clearFrame(int newIndex); - /*! \brief - * Initializes the frame during AnalysisDataStorage::startFrame(). - * - * \param[in] header Header to use for the new frame. - * \param[in] builder Builder object to use. - */ - void startFrame(const AnalysisDataFrameHeader &header, - AnalysisDataFrameBuilderPointer builder); - //! Returns the builder for this frame. - AnalysisDataStorageFrame &builder() const - { - GMX_ASSERT(builder_, "Accessing builder for not-in-progress frame"); - return *builder_; - } - /*! \brief - * Adds a new point set to this frame. - */ - void addPointSet(int dataSetIndex, int firstColumn, - ArrayRef v); - /*! \brief - * Finalizes the frame during AnalysisDataStorage::finishFrame(). - * - * \returns The builder object used by the frame, for reusing it for - * other frames. - */ - AnalysisDataFrameBuilderPointer finishFrame(bool bMultipoint); - - //! Returns frame reference to this frame. - AnalysisDataFrameRef frameReference() const - { - return AnalysisDataFrameRef(header_, values_, pointSets_); - } - //! Returns point set reference to a given point set. - AnalysisDataPointSetRef pointSet(int index) const; - - private: - //! Storage object that contains this frame. - AnalysisDataStorageImpl &storageImpl_; - //! Header for the frame. - AnalysisDataFrameHeader header_; - //! Values for the frame. - std::vector values_; - //! Information about each point set in the frame. - std::vector pointSets_; - /*! \brief - * Builder object for the frame. - * - * Non-NULL when the frame is in progress, i.e., has been started but - * not yet finished. - */ - AnalysisDataFrameBuilderPointer builder_; - //! In what state the frame currently is. - Status status_; - - GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrameData); +public: + //! Indicates what operations have been performed on a frame. + enum Status + { + eMissing, //!< Frame has not yet been started. + eStarted, //!< startFrame() has been called. + eFinished, //!< finishFrame() has been called. + eNotified //!< Appropriate notifications have been sent. + }; + + /*! \brief + * Create a new storage frame. + * + * \param storageImpl Storage object this frame belongs to. + * \param[in] index Zero-based index for the frame. + */ + AnalysisDataStorageFrameData(AnalysisDataStorageImpl* storageImpl, int index); + + //! Whether the frame has been started with startFrame(). + bool isStarted() const { return status_ >= eStarted; } + //! Whether the frame has been finished with finishFrame(). + bool isFinished() const { return status_ >= eFinished; } + //! Whether all notifications have been sent. + bool isNotified() const { return status_ >= eNotified; } + //! Whether the frame is ready to be available outside the storage. + bool isAvailable() const { return status_ >= eFinished; } + + //! Marks the frame as notified. + void markNotified() { status_ = eNotified; } + + //! Returns the storage implementation object. + AnalysisDataStorageImpl& storageImpl() const { return storageImpl_; } + //! Returns the underlying data object (for data dimensionalities etc.). + const AbstractAnalysisData& baseData() const { return *storageImpl().data_; } + + //! Returns header for the frame. + const AnalysisDataFrameHeader& header() const { return header_; } + //! Returns zero-based index of the frame. + int frameIndex() const { return header().index(); } + //! Returns the number of point sets for the frame. + int pointSetCount() const { return pointSets_.size(); } + + //! Clears the frame for reusing as a new frame. + void clearFrame(int newIndex); + /*! \brief + * Initializes the frame during AnalysisDataStorage::startFrame(). + * + * \param[in] header Header to use for the new frame. + * \param[in] builder Builder object to use. + */ + void startFrame(const AnalysisDataFrameHeader& header, AnalysisDataFrameBuilderPointer builder); + //! Returns the builder for this frame. + AnalysisDataStorageFrame& builder() const + { + GMX_ASSERT(builder_, "Accessing builder for not-in-progress frame"); + return *builder_; + } + /*! \brief + * Adds a new point set to this frame. + */ + void addPointSet(int dataSetIndex, int firstColumn, ArrayRef v); + /*! \brief + * Finalizes the frame during AnalysisDataStorage::finishFrame(). + * + * \returns The builder object used by the frame, for reusing it for + * other frames. + */ + AnalysisDataFrameBuilderPointer finishFrame(bool bMultipoint); + + //! Returns frame reference to this frame. + AnalysisDataFrameRef frameReference() const + { + return AnalysisDataFrameRef(header_, values_, pointSets_); + } + //! Returns point set reference to a given point set. + AnalysisDataPointSetRef pointSet(int index) const; + +private: + //! Storage object that contains this frame. + AnalysisDataStorageImpl& storageImpl_; + //! Header for the frame. + AnalysisDataFrameHeader header_; + //! Values for the frame. + std::vector values_; + //! Information about each point set in the frame. + std::vector pointSets_; + /*! \brief + * Builder object for the frame. + * + * Non-NULL when the frame is in progress, i.e., has been started but + * not yet finished. + */ + AnalysisDataFrameBuilderPointer builder_; + //! In what state the frame currently is. + Status status_; + + GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrameData); }; /******************************************************************** * AnalysisDataStorageImpl implementation */ -AnalysisDataStorageImpl::AnalysisDataStorageImpl() - : data_(nullptr), modules_(nullptr), - storageLimit_(0), pendingLimit_(1), - firstFrameLocation_(0), firstUnnotifiedIndex_(0), nextIndex_(0) +AnalysisDataStorageImpl::AnalysisDataStorageImpl() : + data_(nullptr), + modules_(nullptr), + storageLimit_(0), + pendingLimit_(1), + firstFrameLocation_(0), + firstUnnotifiedIndex_(0), + nextIndex_(0) { } -bool -AnalysisDataStorageImpl::isMultipoint() const +bool AnalysisDataStorageImpl::isMultipoint() const { GMX_ASSERT(data_ != nullptr, "isMultipoint() called too early"); return data_->isMultipoint(); } -int -AnalysisDataStorageImpl::firstStoredIndex() const +int AnalysisDataStorageImpl::firstStoredIndex() const { return frames_[firstFrameLocation_]->frameIndex(); } -int -AnalysisDataStorageImpl::computeStorageLocation(int index) const +int AnalysisDataStorageImpl::computeStorageLocation(int index) const { if (index < firstStoredIndex() || index >= nextIndex_) { @@ -429,8 +419,7 @@ AnalysisDataStorageImpl::computeStorageLocation(int index) const } -size_t -AnalysisDataStorageImpl::endStorageLocation() const +size_t AnalysisDataStorageImpl::endStorageLocation() const { if (storeAll()) { @@ -444,8 +433,7 @@ AnalysisDataStorageImpl::endStorageLocation() const } -void -AnalysisDataStorageImpl::extendBuffer(size_t newSize) +void AnalysisDataStorageImpl::extendBuffer(size_t newSize) { frames_.reserve(newSize); while (frames_.size() < newSize) @@ -461,11 +449,9 @@ AnalysisDataStorageImpl::extendBuffer(size_t newSize) } -void -AnalysisDataStorageImpl::rotateBuffer() +void AnalysisDataStorageImpl::rotateBuffer() { - GMX_ASSERT(!storeAll(), - "No need to rotate internal buffer if everything is stored"); + GMX_ASSERT(!storeAll(), "No need to rotate internal buffer if everything is stored"); size_t prevFirst = firstFrameLocation_; size_t nextFirst = prevFirst + 1; if (nextFirst == frames_.size()) @@ -478,8 +464,7 @@ AnalysisDataStorageImpl::rotateBuffer() } -AnalysisDataFrameBuilderPointer -AnalysisDataStorageImpl::getFrameBuilder() +AnalysisDataFrameBuilderPointer AnalysisDataStorageImpl::getFrameBuilder() { if (builders_.empty()) { @@ -491,19 +476,16 @@ AnalysisDataStorageImpl::getFrameBuilder() } -void -AnalysisDataStorageImpl::finishFrame(int index) +void AnalysisDataStorageImpl::finishFrame(int index) { const int storageIndex = computeStorageLocation(index); GMX_RELEASE_ASSERT(storageIndex >= 0, "Out of bounds frame index"); - AnalysisDataStorageFrameData &storedFrame = *frames_[storageIndex]; + AnalysisDataStorageFrameData& storedFrame = *frames_[storageIndex]; GMX_RELEASE_ASSERT(storedFrame.isStarted(), "finishFrame() called for frame before startFrame()"); - GMX_RELEASE_ASSERT(!storedFrame.isFinished(), - "finishFrame() called twice for the same frame"); - GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, - "Inconsistent internal frame indexing"); + GMX_RELEASE_ASSERT(!storedFrame.isFinished(), "finishFrame() called twice for the same frame"); + GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, "Inconsistent internal frame indexing"); builders_.push_back(storedFrame.finishFrame(isMultipoint())); modules_->notifyParallelFrameFinish(storedFrame.header()); if (pendingLimit_ == 1) @@ -513,19 +495,15 @@ AnalysisDataStorageImpl::finishFrame(int index) } -void -AnalysisDataStorageImpl::finishFrameSerial(int index) +void AnalysisDataStorageImpl::finishFrameSerial(int index) { - GMX_RELEASE_ASSERT(index == firstUnnotifiedIndex_, - "Out of order finisFrameSerial() calls"); + GMX_RELEASE_ASSERT(index == firstUnnotifiedIndex_, "Out of order finisFrameSerial() calls"); const int storageIndex = computeStorageLocation(index); GMX_RELEASE_ASSERT(storageIndex >= 0, "Out of bounds frame index"); - AnalysisDataStorageFrameData &storedFrame = *frames_[storageIndex]; - GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, - "Inconsistent internal frame indexing"); - GMX_RELEASE_ASSERT(storedFrame.isFinished(), - "finishFrameSerial() called before finishFrame()"); + AnalysisDataStorageFrameData& storedFrame = *frames_[storageIndex]; + GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, "Inconsistent internal frame indexing"); + GMX_RELEASE_ASSERT(storedFrame.isFinished(), "finishFrameSerial() called before finishFrame()"); GMX_RELEASE_ASSERT(!storedFrame.isNotified(), "finishFrameSerial() called twice for the same frame"); // Increment before the notifications to make the frame available @@ -556,10 +534,10 @@ AnalysisDataStorageImpl::finishFrameSerial(int index) * AnalysisDataStorageFrame implementation */ -AnalysisDataStorageFrameData::AnalysisDataStorageFrameData( - AnalysisDataStorageImpl *storageImpl, - int index) - : storageImpl_(*storageImpl), header_(index, 0.0, 0.0), status_(eMissing) +AnalysisDataStorageFrameData::AnalysisDataStorageFrameData(AnalysisDataStorageImpl* storageImpl, int index) : + storageImpl_(*storageImpl), + header_(index, 0.0, 0.0), + status_(eMissing) { GMX_RELEASE_ASSERT(storageImpl->data_ != nullptr, "Storage frame constructed before data started"); @@ -578,8 +556,7 @@ AnalysisDataStorageFrameData::AnalysisDataStorageFrameData( } -void -AnalysisDataStorageFrameData::clearFrame(int newIndex) +void AnalysisDataStorageFrameData::clearFrame(int newIndex) { GMX_RELEASE_ASSERT(!builder_, "Should not clear an in-progress frame"); status_ = eMissing; @@ -592,10 +569,8 @@ AnalysisDataStorageFrameData::clearFrame(int newIndex) } -void -AnalysisDataStorageFrameData::startFrame( - const AnalysisDataFrameHeader &header, - AnalysisDataFrameBuilderPointer builder) +void AnalysisDataStorageFrameData::startFrame(const AnalysisDataFrameHeader& header, + AnalysisDataFrameBuilderPointer builder) { status_ = eStarted; header_ = header; @@ -605,13 +580,12 @@ AnalysisDataStorageFrameData::startFrame( } -void -AnalysisDataStorageFrameData::addPointSet(int dataSetIndex, int firstColumn, - ArrayRef v) +void AnalysisDataStorageFrameData::addPointSet(int dataSetIndex, + int firstColumn, + ArrayRef v) { const int valueCount = v.size(); - AnalysisDataPointSetInfo pointSetInfo(0, valueCount, - dataSetIndex, firstColumn); + AnalysisDataPointSetInfo pointSetInfo(0, valueCount, dataSetIndex, firstColumn); AnalysisDataPointSetRef pointSet(header(), pointSetInfo, v); storageImpl().modules_->notifyParallelPointsAdd(pointSet); if (storageImpl().shouldNotifyImmediately()) @@ -620,15 +594,13 @@ AnalysisDataStorageFrameData::addPointSet(int dataSetIndex, int firstColumn, } else if (storageImpl().needStorage()) { - pointSets_.emplace_back(values_.size(), valueCount, - dataSetIndex, firstColumn); + pointSets_.emplace_back(values_.size(), valueCount, dataSetIndex, firstColumn); std::copy(v.begin(), v.end(), std::back_inserter(values_)); } } -AnalysisDataFrameBuilderPointer -AnalysisDataStorageFrameData::finishFrame(bool bMultipoint) +AnalysisDataFrameBuilderPointer AnalysisDataStorageFrameData::finishFrame(bool bMultipoint) { status_ = eFinished; if (!bMultipoint) @@ -644,8 +616,7 @@ AnalysisDataStorageFrameData::finishFrame(bool bMultipoint) } else { - GMX_RELEASE_ASSERT(!builder_->bPointSetInProgress_, - "Unfinished point set"); + GMX_RELEASE_ASSERT(!builder_->bPointSetInProgress_, "Unfinished point set"); } AnalysisDataFrameBuilderPointer builder(std::move(builder_)); builder_.reset(); @@ -653,25 +624,24 @@ AnalysisDataStorageFrameData::finishFrame(bool bMultipoint) } -AnalysisDataPointSetRef -AnalysisDataStorageFrameData::pointSet(int index) const +AnalysisDataPointSetRef AnalysisDataStorageFrameData::pointSet(int index) const { - GMX_ASSERT(index >= 0 && index < pointSetCount(), - "Invalid point set index"); - return AnalysisDataPointSetRef( - header_, pointSets_[index], values_); + GMX_ASSERT(index >= 0 && index < pointSetCount(), "Invalid point set index"); + return AnalysisDataPointSetRef(header_, pointSets_[index], values_); } -} // namespace internal +} // namespace internal /******************************************************************** * AnalysisDataStorageFrame */ -AnalysisDataStorageFrame::AnalysisDataStorageFrame( - const AbstractAnalysisData &data) - : data_(nullptr), currentDataSet_(0), currentOffset_(0), - columnCount_(data.columnCount(0)), bPointSetInProgress_(false) +AnalysisDataStorageFrame::AnalysisDataStorageFrame(const AbstractAnalysisData& data) : + data_(nullptr), + currentDataSet_(0), + currentOffset_(0), + columnCount_(data.columnCount(0)), + bPointSetInProgress_(false) { int totalColumnCount = 0; for (int i = 0; i < data.dataSetCount(); ++i) @@ -682,13 +652,10 @@ AnalysisDataStorageFrame::AnalysisDataStorageFrame( } -AnalysisDataStorageFrame::~AnalysisDataStorageFrame() -{ -} +AnalysisDataStorageFrame::~AnalysisDataStorageFrame() {} -void -AnalysisDataStorageFrame::clearValues() +void AnalysisDataStorageFrame::clearValues() { if (bPointSetInProgress_) { @@ -702,11 +669,10 @@ AnalysisDataStorageFrame::clearValues() } -void -AnalysisDataStorageFrame::selectDataSet(int index) +void AnalysisDataStorageFrame::selectDataSet(int index) { GMX_RELEASE_ASSERT(data_ != nullptr, "Invalid frame accessed"); - const AbstractAnalysisData &baseData = data_->baseData(); + const AbstractAnalysisData& baseData = data_->baseData(); GMX_RELEASE_ASSERT(index >= 0 && index < baseData.dataSetCount(), "Out of range data set index"); GMX_RELEASE_ASSERT(!baseData.isMultipoint() || !bPointSetInProgress_, @@ -718,12 +684,11 @@ AnalysisDataStorageFrame::selectDataSet(int index) { currentOffset_ += baseData.columnCount(i); } - columnCount_ = baseData.columnCount(index); + columnCount_ = baseData.columnCount(index); } -void -AnalysisDataStorageFrame::finishPointSet() +void AnalysisDataStorageFrame::finishPointSet() { GMX_RELEASE_ASSERT(data_ != nullptr, "Invalid frame accessed"); GMX_RELEASE_ASSERT(data_->baseData().isMultipoint(), @@ -738,7 +703,7 @@ AnalysisDataStorageFrame::finishPointSet() ++begin; ++firstColumn; } - while (end != begin && !values_[end-1].isSet()) + while (end != begin && !values_[end - 1].isSet()) { --end; } @@ -747,15 +712,13 @@ AnalysisDataStorageFrame::finishPointSet() firstColumn = 0; } data_->addPointSet(currentDataSet_, firstColumn, - makeConstArrayRef(values_). - subArray(begin, end-begin)); + makeConstArrayRef(values_).subArray(begin, end - begin)); } clearValues(); } -void -AnalysisDataStorageFrame::finishFrame() +void AnalysisDataStorageFrame::finishFrame() { GMX_RELEASE_ASSERT(data_ != nullptr, "Invalid frame accessed"); data_->storageImpl().finishFrame(data_->frameIndex()); @@ -766,34 +729,26 @@ AnalysisDataStorageFrame::finishFrame() * AnalysisDataStorage */ -AnalysisDataStorage::AnalysisDataStorage() - : impl_(new Impl()) -{ -} +AnalysisDataStorage::AnalysisDataStorage() : impl_(new Impl()) {} -AnalysisDataStorage::~AnalysisDataStorage() -{ -} +AnalysisDataStorage::~AnalysisDataStorage() {} -int -AnalysisDataStorage::frameCount() const +int AnalysisDataStorage::frameCount() const { return impl_->firstUnnotifiedIndex(); } -AnalysisDataFrameRef -AnalysisDataStorage::tryGetDataFrame(int index) const +AnalysisDataFrameRef AnalysisDataStorage::tryGetDataFrame(int index) const { int storageIndex = impl_->computeStorageLocation(index); if (storageIndex == -1) { return AnalysisDataFrameRef(); } - const internal::AnalysisDataStorageFrameData &storedFrame - = *impl_->frames_[storageIndex]; + const internal::AnalysisDataStorageFrameData& storedFrame = *impl_->frames_[storageIndex]; if (!storedFrame.isAvailable()) { return AnalysisDataFrameRef(); @@ -802,8 +757,7 @@ AnalysisDataStorage::tryGetDataFrame(int index) const } -bool -AnalysisDataStorage::requestStorage(int nframes) +bool AnalysisDataStorage::requestStorage(int nframes) { // Handle the case when everything needs to be stored. if (nframes == -1) @@ -821,9 +775,7 @@ AnalysisDataStorage::requestStorage(int nframes) } -void -AnalysisDataStorage::startDataStorage(AbstractAnalysisData *data, - AnalysisDataModuleManager *modules) +void AnalysisDataStorage::startDataStorage(AbstractAnalysisData* data, AnalysisDataModuleManager* modules) { modules->notifyDataStart(data); // Data needs to be set before calling extendBuffer() @@ -837,11 +789,9 @@ AnalysisDataStorage::startDataStorage(AbstractAnalysisData *data, } -void -AnalysisDataStorage::startParallelDataStorage( - AbstractAnalysisData *data, - AnalysisDataModuleManager *modules, - const AnalysisDataParallelOptions &options) +void AnalysisDataStorage::startParallelDataStorage(AbstractAnalysisData* data, + AnalysisDataModuleManager* modules, + const AnalysisDataParallelOptions& options) { const int pendingLimit = options.parallelizationFactor(); impl_->pendingLimit_ = pendingLimit; @@ -856,11 +806,10 @@ AnalysisDataStorage::startParallelDataStorage( } -AnalysisDataStorageFrame & -AnalysisDataStorage::startFrame(const AnalysisDataFrameHeader &header) +AnalysisDataStorageFrame& AnalysisDataStorage::startFrame(const AnalysisDataFrameHeader& header) { GMX_ASSERT(header.isValid(), "Invalid header"); - internal::AnalysisDataStorageFrameData *storedFrame; + internal::AnalysisDataStorageFrameData* storedFrame; if (impl_->storeAll()) { size_t size = header.index() + 1; @@ -879,8 +828,7 @@ AnalysisDataStorage::startFrame(const AnalysisDataFrameHeader &header) } storedFrame = impl_->frames_[storageIndex].get(); } - GMX_RELEASE_ASSERT(!storedFrame->isStarted(), - "startFrame() called twice for the same frame"); + GMX_RELEASE_ASSERT(!storedFrame->isStarted(), "startFrame() called twice for the same frame"); GMX_RELEASE_ASSERT(storedFrame->frameIndex() == header.index(), "Inconsistent internal frame indexing"); storedFrame->startFrame(header, impl_->getFrameBuilder()); @@ -893,38 +841,33 @@ AnalysisDataStorage::startFrame(const AnalysisDataFrameHeader &header) } -AnalysisDataStorageFrame & -AnalysisDataStorage::startFrame(int index, real x, real dx) +AnalysisDataStorageFrame& AnalysisDataStorage::startFrame(int index, real x, real dx) { return startFrame(AnalysisDataFrameHeader(index, x, dx)); } -AnalysisDataStorageFrame & -AnalysisDataStorage::currentFrame(int index) +AnalysisDataStorageFrame& AnalysisDataStorage::currentFrame(int index) { const int storageIndex = impl_->computeStorageLocation(index); GMX_RELEASE_ASSERT(storageIndex >= 0, "Out of bounds frame index"); - internal::AnalysisDataStorageFrameData &storedFrame = *impl_->frames_[storageIndex]; + internal::AnalysisDataStorageFrameData& storedFrame = *impl_->frames_[storageIndex]; GMX_RELEASE_ASSERT(storedFrame.isStarted(), "currentFrame() called for frame before startFrame()"); GMX_RELEASE_ASSERT(!storedFrame.isFinished(), "currentFrame() called for frame after finishFrame()"); - GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, - "Inconsistent internal frame indexing"); + GMX_RELEASE_ASSERT(storedFrame.frameIndex() == index, "Inconsistent internal frame indexing"); return storedFrame.builder(); } -void -AnalysisDataStorage::finishFrame(int index) +void AnalysisDataStorage::finishFrame(int index) { impl_->finishFrame(index); } -void -AnalysisDataStorage::finishFrameSerial(int index) +void AnalysisDataStorage::finishFrameSerial(int index) { if (impl_->pendingLimit_ > 1) { @@ -932,8 +875,7 @@ AnalysisDataStorage::finishFrameSerial(int index) } } -void -AnalysisDataStorage::finishDataStorage() +void AnalysisDataStorage::finishDataStorage() { // TODO: Check that all frames have been finished etc. impl_->builders_.clear(); diff --git a/src/gromacs/analysisdata/datastorage.h b/src/gromacs/analysisdata/datastorage.h index 7f7aeca5dc..789e6fc126 100644 --- a/src/gromacs/analysisdata/datastorage.h +++ b/src/gromacs/analysisdata/datastorage.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,7 +65,7 @@ namespace internal { class AnalysisDataStorageImpl; class AnalysisDataStorageFrameData; -} // namespace internal +} // namespace internal /*! \libinternal \brief * Allows assigning values for a data frame in AnalysisDataStorage. @@ -80,164 +80,159 @@ class AnalysisDataStorageFrameData; */ class AnalysisDataStorageFrame { - public: - /*! \brief Frees the frame object. - * - * Should not be called outside AnalysisDataStorage. - */ - ~AnalysisDataStorageFrame(); +public: + /*! \brief Frees the frame object. + * + * Should not be called outside AnalysisDataStorage. + */ + ~AnalysisDataStorageFrame(); - /*! \brief - * Select data set that all other methods operate on. - * - * \param[in] index Zero-based data set index to select. - * - * With multipoint data, a single point set can only contain values in - * a single data set. - * With non-multipoint data, arbitrary sequences of selectDataSet() and - * setValue() are supported. The full frame is notified to the modules - * once it is finished. - * - * Does not throw. - */ - void selectDataSet(int index); + /*! \brief + * Select data set that all other methods operate on. + * + * \param[in] index Zero-based data set index to select. + * + * With multipoint data, a single point set can only contain values in + * a single data set. + * With non-multipoint data, arbitrary sequences of selectDataSet() and + * setValue() are supported. The full frame is notified to the modules + * once it is finished. + * + * Does not throw. + */ + void selectDataSet(int index); - //! Returns number of columns for the frame. - int columnCount() const { return columnCount_; } + //! Returns number of columns for the frame. + int columnCount() const { return columnCount_; } - /*! \brief - * Sets value for a column. - * - * \param[in] column Zero-based column index. - * \param[in] value Value to set for the column. - * \param[in] bPresent Present flag to set for the column. - * - * If called multiple times for a column (within one point set for - * multipoint data), old values are overwritten. - * - * Does not throw. - */ - void setValue(int column, real value, bool bPresent = true) - { - GMX_ASSERT(column >= 0 && column < columnCount(), - "Invalid column index"); - values_[currentOffset_ + column].setValue(value, bPresent); - bPointSetInProgress_ = true; - } - /*! \brief - * Sets value for a column. - * - * \param[in] column Zero-based column index. - * \param[in] value Value to set for the column. - * \param[in] error Error estimate to set for the column. - * \param[in] bPresent Present flag to set for the column. - * - * If called multiple times for a column (within one point set for - * multipoint data), old values are overwritten. - * - * Does not throw. - */ - void setValue(int column, real value, real error, bool bPresent = true) - { - GMX_ASSERT(column >= 0 && column < columnCount(), - "Invalid column index"); - values_[currentOffset_ + column].setValue(value, error, bPresent); - bPointSetInProgress_ = true; - } - /*! \brief - * Access value for a column. - * - * \param[in] column Zero-based column index. - * - * Should only be called after the column value has been set using - * setValue(); assigning a value to \c value(i) does not mark the - * column as set. - * - * Does not throw. - */ - real &value(int column) - { - GMX_ASSERT(column >= 0 && column < columnCount(), - "Invalid column index"); - return values_[currentOffset_ + column].value(); - } - /*! \brief - * Access value for a column. - * - * \param[in] column Zero-based column index. - * - * Should only be called after the column value has been set using - * setValue(). - * - * Does not throw. - */ - real value(int column) const - { - GMX_ASSERT(column >= 0 && column < columnCount(), - "Invalid column index"); - return values_[currentOffset_ + column].value(); - } - /*! \brief - * Mark point set as finished for multipoint data. - * - * Must be called after each point set for multipoint data, including - * the last (i.e., no values must be set between the last call to this - * method and AnalysisDataStorage::finishFrame()). - * Must not be called for non-multipoint data. - * - * After this method has been called, all values appear as not set. - * - * May call AnalysisDataModuleManager::notifyPointsAdd() and - * AnalysisDataModuleManager::notifyParallelPointsAdd(), and may throw - * any exception these methods throw. - */ - void finishPointSet(); - /*! \brief - * Finish storing a frame. - * - * Must be called exactly once for each frame returned by startFrame(), - * after the corresponding call. - * The frame object must not be accessed after the call. - * - * Calls notification methods in AnalysisDataModuleManager, and may - * throw any exceptions these methods throw. - */ - void finishFrame(); + /*! \brief + * Sets value for a column. + * + * \param[in] column Zero-based column index. + * \param[in] value Value to set for the column. + * \param[in] bPresent Present flag to set for the column. + * + * If called multiple times for a column (within one point set for + * multipoint data), old values are overwritten. + * + * Does not throw. + */ + void setValue(int column, real value, bool bPresent = true) + { + GMX_ASSERT(column >= 0 && column < columnCount(), "Invalid column index"); + values_[currentOffset_ + column].setValue(value, bPresent); + bPointSetInProgress_ = true; + } + /*! \brief + * Sets value for a column. + * + * \param[in] column Zero-based column index. + * \param[in] value Value to set for the column. + * \param[in] error Error estimate to set for the column. + * \param[in] bPresent Present flag to set for the column. + * + * If called multiple times for a column (within one point set for + * multipoint data), old values are overwritten. + * + * Does not throw. + */ + void setValue(int column, real value, real error, bool bPresent = true) + { + GMX_ASSERT(column >= 0 && column < columnCount(), "Invalid column index"); + values_[currentOffset_ + column].setValue(value, error, bPresent); + bPointSetInProgress_ = true; + } + /*! \brief + * Access value for a column. + * + * \param[in] column Zero-based column index. + * + * Should only be called after the column value has been set using + * setValue(); assigning a value to \c value(i) does not mark the + * column as set. + * + * Does not throw. + */ + real& value(int column) + { + GMX_ASSERT(column >= 0 && column < columnCount(), "Invalid column index"); + return values_[currentOffset_ + column].value(); + } + /*! \brief + * Access value for a column. + * + * \param[in] column Zero-based column index. + * + * Should only be called after the column value has been set using + * setValue(). + * + * Does not throw. + */ + real value(int column) const + { + GMX_ASSERT(column >= 0 && column < columnCount(), "Invalid column index"); + return values_[currentOffset_ + column].value(); + } + /*! \brief + * Mark point set as finished for multipoint data. + * + * Must be called after each point set for multipoint data, including + * the last (i.e., no values must be set between the last call to this + * method and AnalysisDataStorage::finishFrame()). + * Must not be called for non-multipoint data. + * + * After this method has been called, all values appear as not set. + * + * May call AnalysisDataModuleManager::notifyPointsAdd() and + * AnalysisDataModuleManager::notifyParallelPointsAdd(), and may throw + * any exception these methods throw. + */ + void finishPointSet(); + /*! \brief + * Finish storing a frame. + * + * Must be called exactly once for each frame returned by startFrame(), + * after the corresponding call. + * The frame object must not be accessed after the call. + * + * Calls notification methods in AnalysisDataModuleManager, and may + * throw any exceptions these methods throw. + */ + void finishFrame(); - private: +private: + /*! \brief + * Create a new storage frame. + * + * \param[in] data Data object for which the frame is for + * (used for data set and column counts). + */ + explicit AnalysisDataStorageFrame(const AbstractAnalysisData& data); - /*! \brief - * Create a new storage frame. - * - * \param[in] data Data object for which the frame is for - * (used for data set and column counts). - */ - explicit AnalysisDataStorageFrame(const AbstractAnalysisData &data); + //! Clear all column values from the frame. + void clearValues(); - //! Clear all column values from the frame. - void clearValues(); + //! Implementation data. + internal::AnalysisDataStorageFrameData* data_; + //! Values for the currently in-progress point set. + std::vector values_; - //! Implementation data. - internal::AnalysisDataStorageFrameData *data_; - //! Values for the currently in-progress point set. - std::vector values_; + //! Index of the currently active dataset. + int currentDataSet_; + //! Offset of the first value in \a values_ for the current data set. + int currentOffset_; + //! Number of columns in the current data set. + int columnCount_; - //! Index of the currently active dataset. - int currentDataSet_; - //! Offset of the first value in \a values_ for the current data set. - int currentOffset_; - //! Number of columns in the current data set. - int columnCount_; + //! Whether any values have been set in the current point set. + bool bPointSetInProgress_; - //! Whether any values have been set in the current point set. - bool bPointSetInProgress_; + //! Needed for access to the constructor. + friend class internal::AnalysisDataStorageImpl; + //! Needed for managing the frame the object points to. + friend class internal::AnalysisDataStorageFrameData; - //! Needed for access to the constructor. - friend class internal::AnalysisDataStorageImpl; - //! Needed for managing the frame the object points to. - friend class internal::AnalysisDataStorageFrameData; - - GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrame); + GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisDataStorageFrame); }; /*! \libinternal \brief @@ -265,177 +260,175 @@ class AnalysisDataStorageFrame */ class AnalysisDataStorage { - public: - //! Constructs a storage object. - AnalysisDataStorage(); - ~AnalysisDataStorage(); +public: + //! Constructs a storage object. + AnalysisDataStorage(); + ~AnalysisDataStorage(); - /*! \brief - * Returns the number of ready frames. - * - * This method is designed such that calls to - * AbstractAnalysisData::frameCount() can be directly forwarded to this - * method. See that method for more documentation. - * - * If this method returns N, this means that the first N frames have - * all been finished. - * - * \see AbstractAnalysisData::frameCount() - */ - int frameCount() const; - /*! \brief - * Implements access to data frames. - * - * This method is designed such that calls to - * AbstractAnalysisData::tryGetDataFrameInternal() can be directly - * forwarded to this method. See that method for more documentation. - * - * A valid reference for a frame will be returned after finishFrame() - * has been called for that frame. - * - * \see AbstractAnalysisData::tryGetDataFrameInternal() - */ - AnalysisDataFrameRef tryGetDataFrame(int index) const; - /*! \brief - * Implements storage requests. - * - * This method is designed such that calls to - * AbstractAnalysisData::requestStorageInternal() can be directly - * forwarded to this method. See that method for more documentation. - * - * \see AbstractAnalysisData::requestStorageInternal() - */ - bool requestStorage(int nframes); + /*! \brief + * Returns the number of ready frames. + * + * This method is designed such that calls to + * AbstractAnalysisData::frameCount() can be directly forwarded to this + * method. See that method for more documentation. + * + * If this method returns N, this means that the first N frames have + * all been finished. + * + * \see AbstractAnalysisData::frameCount() + */ + int frameCount() const; + /*! \brief + * Implements access to data frames. + * + * This method is designed such that calls to + * AbstractAnalysisData::tryGetDataFrameInternal() can be directly + * forwarded to this method. See that method for more documentation. + * + * A valid reference for a frame will be returned after finishFrame() + * has been called for that frame. + * + * \see AbstractAnalysisData::tryGetDataFrameInternal() + */ + AnalysisDataFrameRef tryGetDataFrame(int index) const; + /*! \brief + * Implements storage requests. + * + * This method is designed such that calls to + * AbstractAnalysisData::requestStorageInternal() can be directly + * forwarded to this method. See that method for more documentation. + * + * \see AbstractAnalysisData::requestStorageInternal() + */ + bool requestStorage(int nframes); - /*! \brief - * Start storing data. - * - * \param[in] data AbstractAnalysisData object containing this - * storage. - * \param modules Module manager for \p data. - * \exception std::bad_alloc if storage allocation fails. - * - * Typically called as \c startDataStorage(this, &moduleManager()) - * from a member of \p data when the data is ready to be started. - * The storage object will take responsibility of calling all - * module notification methods in AnalysisDataModuleManager using - * \p modules. - * - * Lifetime of \p data and \p modules must exceed the lifetime of the - * storage object - * (typically, the storage object will be a member in \p data). - * - * Calls AnalysisDataModuleManager::notifyDataStart(), and throws any - * exceptions this method throws. - */ - void startDataStorage(AbstractAnalysisData *data, - AnalysisDataModuleManager *modules); - /*! \brief - * Start storing data in parallel. - * - * \param[in] data AbstractAnalysisData object containing this - * storage. - * \param[in] options Parallelization options to use. - * \param modules Module manager for \p data. - * \exception std::bad_alloc if storage allocation fails. - * - * Should be called instead of startDataStorage() if the data will be - * produced in parallel. Works as startDataStorage(), but additionally - * initializes the storage and the attached modules to prepare for - * out-of-order data frames. - * - * Calls AnalysisDataModuleManager::notifyParallelDataStart(), and - * throws any exceptions this method throws. - */ - void startParallelDataStorage( - AbstractAnalysisData *data, - AnalysisDataModuleManager *modules, - const AnalysisDataParallelOptions &options); - /*! \brief - * Starts storing a new frame. - * - * \param[in] header Header for the new frame. - * \retval Frame object corresponding to the started frame. - * \exception std::bad_alloc if storage reallocation fails - * (only possible if storage of all frames has been requested). - * \exception APIError if frame is too far in the future. - * - * The returned object will be valid until the corresponding - * finishFrame() call. - * - * Must be called exactly once for each frame index. - * - * Currently, the implementation only works if the new frame is not too - * far in the future: - * If \c i is the index of the last frame such that all frames from - * 0, ..., \c i have been finished, then \p header().index() should be - * at most \c parallelizationFactor larger than \c i, where - * parallelizationFactor is the parallelization factor passed to - * setParallelOptions(). - * Throws APIError if this constraint is violated. - * - * Calls AnalysisDataModuleManager::notifyFrameStart() (in certain - * cases) and AnalysisDataModuleManager::notifyParallelFrameStart(), - * and throws any exceptions these methods throw. - */ - AnalysisDataStorageFrame &startFrame(const AnalysisDataFrameHeader &header); - /*! \brief - * Convenience method to start storing a new frame. - * - * Identical to \c startFrame(AnalysisDataFrameHeader(index, x, dx)); - */ - AnalysisDataStorageFrame &startFrame(int index, real x, real dx); - /*! \brief - * Obtains a frame object for an in-progress frame. - * - * \param[in] index Frame index. - * \retval Frame object corresponding to \p index. - * - * startFrame() should have been called for the frame with index - * \p index, and finishFrame() should not yet have been called. - * Returns the same object as returned by the original startFrame() - * call for the same index. - * - * Does not throw. - */ - AnalysisDataStorageFrame ¤tFrame(int index); - /*! \brief - * Convenience method for finishing a data frame. - * - * \param[in] index Frame index. - * - * Identical to \c currentFrame(index).finishFrame(). - * - * \see AnalysisDataStorageFrame::finishFrame() - */ - void finishFrame(int index); - /*! \brief - * Performs in-order sequential processing for a data frame. - * - * \param[in] index Frame index. - * - * If startParallelDataStorage() has been called with options that - * indicate parallelism, this method must be called after - * `finishFrame(index)` (or the equivalent call in - * AnalysisDataStorageFrame), such that it is called in the correct - * order sequentially for each frame. - * - * If there is no parallelism, this method does nothing; the equivalent - * processing is done already during finishFrame(). - */ - void finishFrameSerial(int index); - /*! \brief - * Finishes storing data. - * - * Calls AnalysisDataModuleManager::notifyDataFinish(), and throws any - * exceptions this method throws. - */ - void finishDataStorage(); + /*! \brief + * Start storing data. + * + * \param[in] data AbstractAnalysisData object containing this + * storage. + * \param modules Module manager for \p data. + * \exception std::bad_alloc if storage allocation fails. + * + * Typically called as \c startDataStorage(this, &moduleManager()) + * from a member of \p data when the data is ready to be started. + * The storage object will take responsibility of calling all + * module notification methods in AnalysisDataModuleManager using + * \p modules. + * + * Lifetime of \p data and \p modules must exceed the lifetime of the + * storage object + * (typically, the storage object will be a member in \p data). + * + * Calls AnalysisDataModuleManager::notifyDataStart(), and throws any + * exceptions this method throws. + */ + void startDataStorage(AbstractAnalysisData* data, AnalysisDataModuleManager* modules); + /*! \brief + * Start storing data in parallel. + * + * \param[in] data AbstractAnalysisData object containing this + * storage. + * \param[in] options Parallelization options to use. + * \param modules Module manager for \p data. + * \exception std::bad_alloc if storage allocation fails. + * + * Should be called instead of startDataStorage() if the data will be + * produced in parallel. Works as startDataStorage(), but additionally + * initializes the storage and the attached modules to prepare for + * out-of-order data frames. + * + * Calls AnalysisDataModuleManager::notifyParallelDataStart(), and + * throws any exceptions this method throws. + */ + void startParallelDataStorage(AbstractAnalysisData* data, + AnalysisDataModuleManager* modules, + const AnalysisDataParallelOptions& options); + /*! \brief + * Starts storing a new frame. + * + * \param[in] header Header for the new frame. + * \retval Frame object corresponding to the started frame. + * \exception std::bad_alloc if storage reallocation fails + * (only possible if storage of all frames has been requested). + * \exception APIError if frame is too far in the future. + * + * The returned object will be valid until the corresponding + * finishFrame() call. + * + * Must be called exactly once for each frame index. + * + * Currently, the implementation only works if the new frame is not too + * far in the future: + * If \c i is the index of the last frame such that all frames from + * 0, ..., \c i have been finished, then \p header().index() should be + * at most \c parallelizationFactor larger than \c i, where + * parallelizationFactor is the parallelization factor passed to + * setParallelOptions(). + * Throws APIError if this constraint is violated. + * + * Calls AnalysisDataModuleManager::notifyFrameStart() (in certain + * cases) and AnalysisDataModuleManager::notifyParallelFrameStart(), + * and throws any exceptions these methods throw. + */ + AnalysisDataStorageFrame& startFrame(const AnalysisDataFrameHeader& header); + /*! \brief + * Convenience method to start storing a new frame. + * + * Identical to \c startFrame(AnalysisDataFrameHeader(index, x, dx)); + */ + AnalysisDataStorageFrame& startFrame(int index, real x, real dx); + /*! \brief + * Obtains a frame object for an in-progress frame. + * + * \param[in] index Frame index. + * \retval Frame object corresponding to \p index. + * + * startFrame() should have been called for the frame with index + * \p index, and finishFrame() should not yet have been called. + * Returns the same object as returned by the original startFrame() + * call for the same index. + * + * Does not throw. + */ + AnalysisDataStorageFrame& currentFrame(int index); + /*! \brief + * Convenience method for finishing a data frame. + * + * \param[in] index Frame index. + * + * Identical to \c currentFrame(index).finishFrame(). + * + * \see AnalysisDataStorageFrame::finishFrame() + */ + void finishFrame(int index); + /*! \brief + * Performs in-order sequential processing for a data frame. + * + * \param[in] index Frame index. + * + * If startParallelDataStorage() has been called with options that + * indicate parallelism, this method must be called after + * `finishFrame(index)` (or the equivalent call in + * AnalysisDataStorageFrame), such that it is called in the correct + * order sequentially for each frame. + * + * If there is no parallelism, this method does nothing; the equivalent + * processing is done already during finishFrame(). + */ + void finishFrameSerial(int index); + /*! \brief + * Finishes storing data. + * + * Calls AnalysisDataModuleManager::notifyDataFinish(), and throws any + * exceptions this method throws. + */ + void finishDataStorage(); - private: - typedef internal::AnalysisDataStorageImpl Impl; +private: + typedef internal::AnalysisDataStorageImpl Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/framelocaldata.h b/src/gromacs/analysisdata/framelocaldata.h index 5d086b34a1..432926cbc8 100644 --- a/src/gromacs/analysisdata/framelocaldata.h +++ b/src/gromacs/analysisdata/framelocaldata.h @@ -67,29 +67,22 @@ namespace gmx template class AnalysisDataFrameLocalDataSetHandle { - public: - //! Constructs a handle from an array of values. - explicit AnalysisDataFrameLocalDataSetHandle(ArrayRef values) - : values_(values) - { - } +public: + //! Constructs a handle from an array of values. + explicit AnalysisDataFrameLocalDataSetHandle(ArrayRef values) : values_(values) {} - //! Clears all values in the data set. - void clear() - { - std::fill(values_.begin(), values_.end(), ValueType()); - } + //! Clears all values in the data set. + void clear() { std::fill(values_.begin(), values_.end(), ValueType()); } - //! Accesses a single value in the data set. - ValueType &value(int column) - { - GMX_ASSERT(column >= 0 && column < ssize(values_), - "Invalid column index"); - return values_[column]; - } + //! Accesses a single value in the data set. + ValueType& value(int column) + { + GMX_ASSERT(column >= 0 && column < ssize(values_), "Invalid column index"); + return values_[column]; + } - private: - ArrayRef values_; +private: + ArrayRef values_; }; /*! \internal @@ -103,55 +96,45 @@ class AnalysisDataFrameLocalDataSetHandle template class AnalysisDataFrameLocalDataHandle { - public: - //! Shorthand for the internal array of values. - typedef std::vector ValueArray; - //! Shorthand for a handle to a single data set. - typedef AnalysisDataFrameLocalDataSetHandle DataSetHandle; +public: + //! Shorthand for the internal array of values. + typedef std::vector ValueArray; + //! Shorthand for a handle to a single data set. + typedef AnalysisDataFrameLocalDataSetHandle DataSetHandle; - //! Constructs a handle from specified frame data. - AnalysisDataFrameLocalDataHandle(const std::vector *dataSetIndices, - ValueArray *values) - : dataSetIndices_(dataSetIndices), values_(values) - { - } + //! Constructs a handle from specified frame data. + AnalysisDataFrameLocalDataHandle(const std::vector* dataSetIndices, ValueArray* values) : + dataSetIndices_(dataSetIndices), + values_(values) + { + } - //! Returns the number of data sets in the array. - int dataSetCount() const - { - return dataSetIndices_->size() - 1; - } - //! Clears all values in the frame. - void clear() - { - std::fill(values_->begin(), values_->end(), ValueType()); - } + //! Returns the number of data sets in the array. + int dataSetCount() const { return dataSetIndices_->size() - 1; } + //! Clears all values in the frame. + void clear() { std::fill(values_->begin(), values_->end(), ValueType()); } - //! Returns a handle for a single data set. - DataSetHandle dataSet(int dataSet) - { - GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), - "Invalid data set index"); - const int firstIndex = (*dataSetIndices_)[dataSet]; - const int lastIndex = (*dataSetIndices_)[dataSet + 1]; - return DataSetHandle(makeArrayRef(*values_). - subArray(firstIndex, lastIndex-firstIndex)); - } - //! Accesses a single value in the frame. - ValueType &value(int dataSet, int column) - { - GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), - "Invalid data set index"); - const int firstIndex = (*dataSetIndices_)[dataSet]; - GMX_ASSERT(column >= 0 - && column < (*dataSetIndices_)[dataSet+1] - firstIndex, - "Invalid column index"); - return (*values_)[firstIndex + column]; - } + //! Returns a handle for a single data set. + DataSetHandle dataSet(int dataSet) + { + GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Invalid data set index"); + const int firstIndex = (*dataSetIndices_)[dataSet]; + const int lastIndex = (*dataSetIndices_)[dataSet + 1]; + return DataSetHandle(makeArrayRef(*values_).subArray(firstIndex, lastIndex - firstIndex)); + } + //! Accesses a single value in the frame. + ValueType& value(int dataSet, int column) + { + GMX_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Invalid data set index"); + const int firstIndex = (*dataSetIndices_)[dataSet]; + GMX_ASSERT(column >= 0 && column < (*dataSetIndices_)[dataSet + 1] - firstIndex, + "Invalid column index"); + return (*values_)[firstIndex + column]; + } - private: - const std::vector *dataSetIndices_; - ValueArray *values_; +private: + const std::vector* dataSetIndices_; + ValueArray* values_; }; /*! \internal \brief @@ -188,116 +171,107 @@ class AnalysisDataFrameLocalDataHandle template class AnalysisDataFrameLocalData { - public: - //! Shorthand for the internal array of values for a frame. - typedef std::vector ValueArray; - //! Shorthand for a handle to a single frame. - typedef AnalysisDataFrameLocalDataHandle FrameHandle; - //! Shorthand for a handle to a single data set. - typedef AnalysisDataFrameLocalDataSetHandle DataSetHandle; +public: + //! Shorthand for the internal array of values for a frame. + typedef std::vector ValueArray; + //! Shorthand for a handle to a single frame. + typedef AnalysisDataFrameLocalDataHandle FrameHandle; + //! Shorthand for a handle to a single data set. + typedef AnalysisDataFrameLocalDataSetHandle DataSetHandle; - //! Constructs an empty container with a single data set. - AnalysisDataFrameLocalData() - { - dataSetColumns_.resize(2); - } + //! Constructs an empty container with a single data set. + AnalysisDataFrameLocalData() { dataSetColumns_.resize(2); } - //! Whether init() has been called. - bool isInitialized() const { return !values_.empty(); } - /*! \brief - * Returns number of independent data frames in this object. - * - * This supports looping over all the frame arrays to, e.g., sum them - * up at the end in accumulation scenarios. - */ - int frameCount() const { return values_.size(); } + //! Whether init() has been called. + bool isInitialized() const { return !values_.empty(); } + /*! \brief + * Returns number of independent data frames in this object. + * + * This supports looping over all the frame arrays to, e.g., sum them + * up at the end in accumulation scenarios. + */ + int frameCount() const { return values_.size(); } - /*! \brief - * Sets the number of data sets stored for each frame. - * - * \throws std::bad_alloc if out of memory. - * - * If not called, there is a single data set in the object. - * Cannot be called after init(). - */ - void setDataSetCount(int dataSetCount) - { - GMX_RELEASE_ASSERT(!isInitialized(), - "Cannot change value count after init()"); - GMX_RELEASE_ASSERT(dataSetCount >= 0, - "Invalid data set count"); - dataSetColumns_.resize(dataSetCount + 1); - } - /*! \brief - * Sets the number of columns stored for a data set. - * - * Must be called for each data set that needs to have values, - * otherwise there will be zero columns for that data set. - * Cannot be called after init(). - */ - void setColumnCount(int dataSet, int columnCount) - { - GMX_RELEASE_ASSERT(!isInitialized(), - "Cannot change value count after init()"); - GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < ssize(dataSetColumns_) - 1, - "Invalid data set index"); - GMX_RELEASE_ASSERT(columnCount >= 0, - "Invalid column count"); - dataSetColumns_[dataSet + 1] = columnCount; - } + /*! \brief + * Sets the number of data sets stored for each frame. + * + * \throws std::bad_alloc if out of memory. + * + * If not called, there is a single data set in the object. + * Cannot be called after init(). + */ + void setDataSetCount(int dataSetCount) + { + GMX_RELEASE_ASSERT(!isInitialized(), "Cannot change value count after init()"); + GMX_RELEASE_ASSERT(dataSetCount >= 0, "Invalid data set count"); + dataSetColumns_.resize(dataSetCount + 1); + } + /*! \brief + * Sets the number of columns stored for a data set. + * + * Must be called for each data set that needs to have values, + * otherwise there will be zero columns for that data set. + * Cannot be called after init(). + */ + void setColumnCount(int dataSet, int columnCount) + { + GMX_RELEASE_ASSERT(!isInitialized(), "Cannot change value count after init()"); + GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < ssize(dataSetColumns_) - 1, + "Invalid data set index"); + GMX_RELEASE_ASSERT(columnCount >= 0, "Invalid column count"); + dataSetColumns_[dataSet + 1] = columnCount; + } - /*! \brief - * Initializes the storage to support specified parallelism. - * - * \throws std::bad_alloc if out of memory. - */ - void init(const AnalysisDataParallelOptions &opt) + /*! \brief + * Initializes the storage to support specified parallelism. + * + * \throws std::bad_alloc if out of memory. + */ + void init(const AnalysisDataParallelOptions& opt) + { + GMX_RELEASE_ASSERT(!isInitialized(), "init() called multiple times"); + std::partial_sum(dataSetColumns_.begin(), dataSetColumns_.end(), dataSetColumns_.begin()); + values_.resize(opt.parallelizationFactor()); + typename std::vector::iterator i; + for (i = values_.begin(); i != values_.end(); ++i) { - GMX_RELEASE_ASSERT(!isInitialized(), "init() called multiple times"); - std::partial_sum(dataSetColumns_.begin(), dataSetColumns_.end(), - dataSetColumns_.begin()); - values_.resize(opt.parallelizationFactor()); - typename std::vector::iterator i; - for (i = values_.begin(); i != values_.end(); ++i) - { - i->resize(dataSetColumns_.back()); - } + i->resize(dataSetColumns_.back()); } + } - //! Returns a handle to access data for a frame. - FrameHandle frameData(int frameIndex) - { - GMX_ASSERT(frameIndex >= 0, "Invalid frame index"); - GMX_ASSERT(isInitialized(), "Cannot access data before init()"); - return FrameHandle(&dataSetColumns_, - &values_[frameIndex % values_.size()]); - } - //! Returns a handle to access a single data set within a frame. - DataSetHandle frameDataSet(int frameIndex, int dataSet) - { - return frameData(frameIndex).dataSet(dataSet); - } + //! Returns a handle to access data for a frame. + FrameHandle frameData(int frameIndex) + { + GMX_ASSERT(frameIndex >= 0, "Invalid frame index"); + GMX_ASSERT(isInitialized(), "Cannot access data before init()"); + return FrameHandle(&dataSetColumns_, &values_[frameIndex % values_.size()]); + } + //! Returns a handle to access a single data set within a frame. + DataSetHandle frameDataSet(int frameIndex, int dataSet) + { + return frameData(frameIndex).dataSet(dataSet); + } - private: - /*! \brief - * Index to find data sets within a per-frame array in `values_`. - * - * The first entry is always zero, followed by one entry for each data - * set. Before init(), the data set entries hold the numbers set with - * setColumnCount(). After init(), the data set entries hold the - * indices of the first column for that data set in the per-frame - * arrays in `values_`. - */ - std::vector dataSetColumns_; - /*! \brief - * Data array for each frame. - * - * This is a ring buffer whose size is specified by the desired - * parallelism level. For each frame, there is a single array of - * values, where the individual data sets are indexed with - * `dataSetColumns_`. - */ - std::vector values_; +private: + /*! \brief + * Index to find data sets within a per-frame array in `values_`. + * + * The first entry is always zero, followed by one entry for each data + * set. Before init(), the data set entries hold the numbers set with + * setColumnCount(). After init(), the data set entries hold the + * indices of the first column for that data set in the per-frame + * arrays in `values_`. + */ + std::vector dataSetColumns_; + /*! \brief + * Data array for each frame. + * + * This is a ring buffer whose size is specified by the desired + * parallelism level. For each frame, there is a single array of + * values, where the individual data sets are indexed with + * `dataSetColumns_`. + */ + std::vector values_; }; //! \} diff --git a/src/gromacs/analysisdata/modules/average.cpp b/src/gromacs/analysisdata/modules/average.cpp index b4b02b9bd5..ea5c25601c 100644 --- a/src/gromacs/analysisdata/modules/average.cpp +++ b/src/gromacs/analysisdata/modules/average.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,23 +62,18 @@ namespace gmx class AnalysisDataAverageModule::Impl { - public: - Impl() : bDataSets_(false) {} +public: + Impl() : bDataSets_(false) {} - //! Averaging helper objects for each input data set. - std::vector averagers_; - //! Whether to average all columns in a data set into a single value. - bool bDataSets_; + //! Averaging helper objects for each input data set. + std::vector averagers_; + //! Whether to average all columns in a data set into a single value. + bool bDataSets_; }; -AnalysisDataAverageModule::AnalysisDataAverageModule() - : impl_(new Impl()) -{ -} +AnalysisDataAverageModule::AnalysisDataAverageModule() : impl_(new Impl()) {} -AnalysisDataAverageModule::~AnalysisDataAverageModule() -{ -} +AnalysisDataAverageModule::~AnalysisDataAverageModule() {} void AnalysisDataAverageModule::setAverageDataSets(bool bDataSets) { @@ -87,12 +82,10 @@ void AnalysisDataAverageModule::setAverageDataSets(bool bDataSets) int AnalysisDataAverageModule::flags() const { - return efAllowMultipoint | efAllowMulticolumn | efAllowMissing - | efAllowMultipleDataSets; + return efAllowMultipoint | efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets; } -void -AnalysisDataAverageModule::dataStarted(AbstractAnalysisData *data) +void AnalysisDataAverageModule::dataStarted(AbstractAnalysisData* data) { if (impl_->bDataSets_) { @@ -115,13 +108,9 @@ AnalysisDataAverageModule::dataStarted(AbstractAnalysisData *data) } } -void -AnalysisDataAverageModule::frameStarted(const AnalysisDataFrameHeader & /*header*/) -{ -} +void AnalysisDataAverageModule::frameStarted(const AnalysisDataFrameHeader& /*header*/) {} -void -AnalysisDataAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataAverageModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (impl_->bDataSets_) { @@ -140,13 +129,9 @@ AnalysisDataAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) } } -void -AnalysisDataAverageModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) -{ -} +void AnalysisDataAverageModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {} -void -AnalysisDataAverageModule::dataFinished() +void AnalysisDataAverageModule::dataFinished() { allocateValues(); for (int i = 0; i < columnCount(); ++i) @@ -170,8 +155,7 @@ real AnalysisDataAverageModule::average(int dataSet, int column) const { if (impl_->bDataSets_) { - GMX_ASSERT(column == 0, - "Column should be zero with setAverageDataSets(true)"); + GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)"); std::swap(dataSet, column); } return value(column, dataSet).value(); @@ -181,8 +165,7 @@ real AnalysisDataAverageModule::standardDeviation(int dataSet, int column) const { if (impl_->bDataSets_) { - GMX_ASSERT(column == 0, - "Column should be zero with setAverageDataSets(true)"); + GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)"); std::swap(dataSet, column); } return value(column, dataSet).error(); @@ -192,8 +175,7 @@ int AnalysisDataAverageModule::sampleCount(int dataSet, int column) const { if (impl_->bDataSets_) { - GMX_ASSERT(column == 0, - "Column should be zero with setAverageDataSets(true)"); + GMX_ASSERT(column == 0, "Column should be zero with setAverageDataSets(true)"); std::swap(dataSet, column); } return impl_->averagers_[dataSet].sampleCount(column); @@ -206,47 +188,37 @@ int AnalysisDataAverageModule::sampleCount(int dataSet, int column) const class AnalysisDataFrameAverageModule::Impl { - public: - //! Storage implementation object. - AnalysisDataStorage storage_; - //! Number of samples in a frame for each data set. - std::vector sampleCount_; +public: + //! Storage implementation object. + AnalysisDataStorage storage_; + //! Number of samples in a frame for each data set. + std::vector sampleCount_; }; -AnalysisDataFrameAverageModule::AnalysisDataFrameAverageModule() - : impl_(new Impl()) -{ -} +AnalysisDataFrameAverageModule::AnalysisDataFrameAverageModule() : impl_(new Impl()) {} -AnalysisDataFrameAverageModule::~AnalysisDataFrameAverageModule() -{ -} +AnalysisDataFrameAverageModule::~AnalysisDataFrameAverageModule() {} -int -AnalysisDataFrameAverageModule::frameCount() const +int AnalysisDataFrameAverageModule::frameCount() const { return impl_->storage_.frameCount(); } -int -AnalysisDataFrameAverageModule::flags() const +int AnalysisDataFrameAverageModule::flags() const { - return efAllowMultipoint | efAllowMulticolumn | efAllowMissing - | efAllowMultipleDataSets; + return efAllowMultipoint | efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets; } -void -AnalysisDataFrameAverageModule::dataStarted(AbstractAnalysisData *data) +void AnalysisDataFrameAverageModule::dataStarted(AbstractAnalysisData* data) { setColumnCount(0, data->dataSetCount()); impl_->sampleCount_.resize(data->dataSetCount()); impl_->storage_.startDataStorage(this, &moduleManager()); } -void -AnalysisDataFrameAverageModule::frameStarted(const AnalysisDataFrameHeader &header) +void AnalysisDataFrameAverageModule::frameStarted(const AnalysisDataFrameHeader& header) { - AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header); + AnalysisDataStorageFrame& frame = impl_->storage_.startFrame(header); for (int i = 0; i < columnCount(); ++i) { impl_->sampleCount_[i] = 0; @@ -254,12 +226,10 @@ AnalysisDataFrameAverageModule::frameStarted(const AnalysisDataFrameHeader &head } } -void -AnalysisDataFrameAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataFrameAverageModule::pointsAdded(const AnalysisDataPointSetRef& points) { const int dataSet = points.dataSetIndex(); - AnalysisDataStorageFrame &frame = - impl_->storage_.currentFrame(points.frameIndex()); + AnalysisDataStorageFrame& frame = impl_->storage_.currentFrame(points.frameIndex()); for (int i = 0; i < points.columnCount(); ++i) { if (points.present(i)) @@ -268,31 +238,27 @@ AnalysisDataFrameAverageModule::pointsAdded(const AnalysisDataPointSetRef &point const real y = points.y(i); const real delta = y - frame.value(dataSet); impl_->sampleCount_[dataSet] += 1; - frame.value(dataSet) += delta / impl_->sampleCount_[dataSet]; + frame.value(dataSet) += delta / impl_->sampleCount_[dataSet]; } } } -void -AnalysisDataFrameAverageModule::frameFinished(const AnalysisDataFrameHeader &header) +void AnalysisDataFrameAverageModule::frameFinished(const AnalysisDataFrameHeader& header) { impl_->storage_.finishFrame(header.index()); } -void -AnalysisDataFrameAverageModule::dataFinished() +void AnalysisDataFrameAverageModule::dataFinished() { impl_->storage_.finishDataStorage(); } -AnalysisDataFrameRef -AnalysisDataFrameAverageModule::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AnalysisDataFrameAverageModule::tryGetDataFrameInternal(int index) const { return impl_->storage_.tryGetDataFrame(index); } -bool -AnalysisDataFrameAverageModule::requestStorageInternal(int nframes) +bool AnalysisDataFrameAverageModule::requestStorageInternal(int nframes) { return impl_->storage_.requestStorage(nframes); } diff --git a/src/gromacs/analysisdata/modules/average.h b/src/gromacs/analysisdata/modules/average.h index de3ec3f306..7b14c44960 100644 --- a/src/gromacs/analysisdata/modules/average.h +++ b/src/gromacs/analysisdata/modules/average.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,71 +79,69 @@ namespace gmx * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataAverageModule : public AbstractAnalysisArrayData, - public AnalysisDataModuleSerial +class AnalysisDataAverageModule : public AbstractAnalysisArrayData, public AnalysisDataModuleSerial { - public: - AnalysisDataAverageModule(); - ~AnalysisDataAverageModule() override; - - using AbstractAnalysisArrayData::setXAxis; - using AbstractAnalysisArrayData::setXAxisValue; - - /*! \brief - * Sets the averaging to happen over entire data sets. - * - * If \p bDataSets is false (the default), the module averages each - * column separately. The output will have a column for each data set, - * and a row for each column. - * - * If \p bDataSets is true, the module averages all values within - * a single data set into a single average/standard deviation. - * The output will have only one column, with one row for each data - * set. - */ - void setAverageDataSets(bool bDataSets); - - int flags() const override; - - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; - - /*! \brief - * Convenience access to the average of a data column. - * - * Note that the interpretation of the parameters follows their naming: - * with \c setAverageDataSets(false), \p dataSet corresponds to a - * column in the output, but with \c setAverageDataSets(false) it - * corresponds to an output row. In both cases, it selects the data - * set; with \c setAverageDataSets(false), \p column should always be - * zero as there is only one value per data set. - */ - real average(int dataSet, int column) const; - /*! \brief - * Convenience access to the standard deviation of a data column. - * - * See average() for the interpretation of the parameters. - */ - real standardDeviation(int dataSet, int column) const; - /*! \brief - * Access the number of samples for a data column. - * - * See average() for the interpretation of the parameters. - */ - int sampleCount(int dataSet, int column) const; - - private: - class Impl; - - PrivateImplPointer impl_; +public: + AnalysisDataAverageModule(); + ~AnalysisDataAverageModule() override; + + using AbstractAnalysisArrayData::setXAxis; + using AbstractAnalysisArrayData::setXAxisValue; + + /*! \brief + * Sets the averaging to happen over entire data sets. + * + * If \p bDataSets is false (the default), the module averages each + * column separately. The output will have a column for each data set, + * and a row for each column. + * + * If \p bDataSets is true, the module averages all values within + * a single data set into a single average/standard deviation. + * The output will have only one column, with one row for each data + * set. + */ + void setAverageDataSets(bool bDataSets); + + int flags() const override; + + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; + + /*! \brief + * Convenience access to the average of a data column. + * + * Note that the interpretation of the parameters follows their naming: + * with \c setAverageDataSets(false), \p dataSet corresponds to a + * column in the output, but with \c setAverageDataSets(false) it + * corresponds to an output row. In both cases, it selects the data + * set; with \c setAverageDataSets(false), \p column should always be + * zero as there is only one value per data set. + */ + real average(int dataSet, int column) const; + /*! \brief + * Convenience access to the standard deviation of a data column. + * + * See average() for the interpretation of the parameters. + */ + real standardDeviation(int dataSet, int column) const; + /*! \brief + * Access the number of samples for a data column. + * + * See average() for the interpretation of the parameters. + */ + int sampleCount(int dataSet, int column) const; + +private: + class Impl; + + PrivateImplPointer impl_; }; //! Smart pointer to manage an AnalysisDataAverageModule object. -typedef std::shared_ptr - AnalysisDataAverageModulePointer; +typedef std::shared_ptr AnalysisDataAverageModulePointer; /*! \brief * Data module for averaging of columns for each frame. @@ -161,35 +159,33 @@ typedef std::shared_ptr * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataFrameAverageModule : public AbstractAnalysisData, - public AnalysisDataModuleSerial +class AnalysisDataFrameAverageModule : public AbstractAnalysisData, public AnalysisDataModuleSerial { - public: - AnalysisDataFrameAverageModule(); - ~AnalysisDataFrameAverageModule() override; +public: + AnalysisDataFrameAverageModule(); + ~AnalysisDataFrameAverageModule() override; - int frameCount() const override; + int frameCount() const override; - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - class Impl; + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; //! Smart pointer to manage an AnalysisDataFrameAverageModule object. -typedef std::shared_ptr - AnalysisDataFrameAverageModulePointer; +typedef std::shared_ptr AnalysisDataFrameAverageModulePointer; } // namespace gmx diff --git a/src/gromacs/analysisdata/modules/displacement.cpp b/src/gromacs/analysisdata/modules/displacement.cpp index 310572c3df..1468268f66 100644 --- a/src/gromacs/analysisdata/modules/displacement.cpp +++ b/src/gromacs/analysisdata/modules/displacement.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,46 +66,54 @@ namespace gmx */ class AnalysisDataDisplacementModule::Impl { - public: - Impl(); - ~Impl(); - - //! Maximum number of particles for which the displacements are calculated. - int nmax; - //! Maximum time for which the displacements are needed. - real tmax; - //! Number of dimensions per data point. - int ndim; - - //! true if no frames have been read. - bool bFirst; - //! Stores the time of the first frame. - real t0; - //! Stores the time interval between frames. - real dt; - //! Stores the time of the current frame. - real t; - //! Stores the index in the store for the current positions. - int ci; - - //! Maximum number of positions to store for a particle. - int max_store; - //! The total number of positions ever stored (can be larger than \p max_store). - int nstored; - //! Old values. - real *oldval; - //! The most recently calculated displacements. - std::vector currValues_; - - //! Histogram module for calculating MSD histograms, or NULL if not set. - AnalysisDataBinAverageModule *histm; +public: + Impl(); + ~Impl(); + + //! Maximum number of particles for which the displacements are calculated. + int nmax; + //! Maximum time for which the displacements are needed. + real tmax; + //! Number of dimensions per data point. + int ndim; + + //! true if no frames have been read. + bool bFirst; + //! Stores the time of the first frame. + real t0; + //! Stores the time interval between frames. + real dt; + //! Stores the time of the current frame. + real t; + //! Stores the index in the store for the current positions. + int ci; + + //! Maximum number of positions to store for a particle. + int max_store; + //! The total number of positions ever stored (can be larger than \p max_store). + int nstored; + //! Old values. + real* oldval; + //! The most recently calculated displacements. + std::vector currValues_; + + //! Histogram module for calculating MSD histograms, or NULL if not set. + AnalysisDataBinAverageModule* histm; }; -AnalysisDataDisplacementModule::Impl::Impl() - : nmax(0), tmax(0.0), ndim(3), - bFirst(true), t0(0.0), dt(0.0), t(0.0), ci(0), - max_store(-1), nstored(0), oldval(nullptr), - histm(nullptr) +AnalysisDataDisplacementModule::Impl::Impl() : + nmax(0), + tmax(0.0), + ndim(3), + bFirst(true), + t0(0.0), + dt(0.0), + t(0.0), + ci(0), + max_store(-1), + nstored(0), + oldval(nullptr), + histm(nullptr) { } @@ -117,28 +126,22 @@ AnalysisDataDisplacementModule::Impl::~Impl() * AnalysisDataDisplacementModule */ -AnalysisDataDisplacementModule::AnalysisDataDisplacementModule() - : _impl(new Impl()) +AnalysisDataDisplacementModule::AnalysisDataDisplacementModule() : _impl(new Impl()) { setMultipoint(true); } -AnalysisDataDisplacementModule::~AnalysisDataDisplacementModule() -{ -} +AnalysisDataDisplacementModule::~AnalysisDataDisplacementModule() {} -void -AnalysisDataDisplacementModule::setMaxTime(real tmax) +void AnalysisDataDisplacementModule::setMaxTime(real tmax) { _impl->tmax = tmax; } -void -AnalysisDataDisplacementModule::setMSDHistogram( - const AnalysisDataBinAverageModulePointer &histm) +void AnalysisDataDisplacementModule::setMSDHistogram(const AnalysisDataBinAverageModulePointer& histm) { GMX_RELEASE_ASSERT(_impl->histm == nullptr, "Can only set MSD histogram once"); _impl->histm = histm.get(); @@ -146,29 +149,25 @@ AnalysisDataDisplacementModule::setMSDHistogram( } -AnalysisDataFrameRef -AnalysisDataDisplacementModule::tryGetDataFrameInternal(int /*index*/) const +AnalysisDataFrameRef AnalysisDataDisplacementModule::tryGetDataFrameInternal(int /*index*/) const { return AnalysisDataFrameRef(); } -bool -AnalysisDataDisplacementModule::requestStorageInternal(int /*nframes*/) +bool AnalysisDataDisplacementModule::requestStorageInternal(int /*nframes*/) { return false; } -int -AnalysisDataDisplacementModule::flags() const +int AnalysisDataDisplacementModule::flags() const { return efAllowMulticolumn; } -void -AnalysisDataDisplacementModule::dataStarted(AbstractAnalysisData *data) +void AnalysisDataDisplacementModule::dataStarted(AbstractAnalysisData* data) { if (data->columnCount() % _impl->ndim != 0) { @@ -184,8 +183,7 @@ AnalysisDataDisplacementModule::dataStarted(AbstractAnalysisData *data) } -void -AnalysisDataDisplacementModule::frameStarted(const AnalysisDataFrameHeader &header) +void AnalysisDataDisplacementModule::frameStarted(const AnalysisDataFrameHeader& header) { // Initialize times. if (_impl->bFirst) @@ -212,7 +210,7 @@ AnalysisDataDisplacementModule::frameStarted(const AnalysisDataFrameHeader &head // Allocate memory for all the positions once it is possible. if (_impl->max_store == -1 && !_impl->bFirst) { - _impl->max_store = _impl->nmax * static_cast(_impl->tmax/_impl->dt + 1); + _impl->max_store = _impl->nmax * static_cast(_impl->tmax / _impl->dt + 1); srenew(_impl->oldval, _impl->max_store); } @@ -223,22 +221,20 @@ AnalysisDataDisplacementModule::frameStarted(const AnalysisDataFrameHeader &head _impl->ci = 0; } -/* - for (int i = 0; i < _impl->nmax; ++i) - { - _impl->p[_impl->ci + i].bPres = false; - } - */ + /* + for (int i = 0; i < _impl->nmax; ++i) + { + _impl->p[_impl->ci + i].bPres = false; + } + */ _impl->nstored++; _impl->bFirst = false; } -void -AnalysisDataDisplacementModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataDisplacementModule::pointsAdded(const AnalysisDataPointSetRef& points) { - if (points.firstColumn() % _impl->ndim != 0 - || points.columnCount() % _impl->ndim != 0) + if (points.firstColumn() % _impl->ndim != 0 || points.columnCount() % _impl->ndim != 0) { GMX_THROW(APIError("Partial data points")); } @@ -249,8 +245,7 @@ AnalysisDataDisplacementModule::pointsAdded(const AnalysisDataPointSetRef &point } -void -AnalysisDataDisplacementModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) +void AnalysisDataDisplacementModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) { if (_impl->nstored <= 1) { @@ -263,16 +258,15 @@ AnalysisDataDisplacementModule::frameFinished(const AnalysisDataFrameHeader & /* { if (_impl->histm) { - _impl->histm->init(histogramFromBins(0, _impl->max_store / _impl->nmax, - _impl->dt).integerBins()); + _impl->histm->init( + histogramFromBins(0, _impl->max_store / _impl->nmax, _impl->dt).integerBins()); } moduleManager().notifyDataStart(this); } AnalysisDataFrameHeader header(_impl->nstored - 2, _impl->t, 0); moduleManager().notifyFrameStart(header); - for (i = _impl->ci - _impl->nmax, step = 1; - step < _impl->nstored && i != _impl->ci; + for (i = _impl->ci - _impl->nmax, step = 1; step < _impl->nstored && i != _impl->ci; i -= _impl->nmax, ++step) { if (i < 0) @@ -288,8 +282,7 @@ AnalysisDataDisplacementModule::frameFinished(const AnalysisDataFrameHeader & /* for (int d = 0; d < _impl->ndim; ++d) { - real displ = _impl->oldval[_impl->ci + j + d] - - _impl->oldval[i + j + d]; + real displ = _impl->oldval[_impl->ci + j + d] - _impl->oldval[i + j + d]; dist2 += displ * displ; } _impl->currValues_.emplace_back(dist2); @@ -301,8 +294,7 @@ AnalysisDataDisplacementModule::frameFinished(const AnalysisDataFrameHeader & /* } -void -AnalysisDataDisplacementModule::dataFinished() +void AnalysisDataDisplacementModule::dataFinished() { if (_impl->nstored >= 2) { diff --git a/src/gromacs/analysisdata/modules/displacement.h b/src/gromacs/analysisdata/modules/displacement.h index 2ff25a7561..3c6cdc467c 100644 --- a/src/gromacs/analysisdata/modules/displacement.h +++ b/src/gromacs/analysisdata/modules/displacement.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,44 +66,42 @@ class AnalysisDataBinAverageModule; * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataDisplacementModule : public AbstractAnalysisData, - public AnalysisDataModuleSerial +class AnalysisDataDisplacementModule : public AbstractAnalysisData, public AnalysisDataModuleSerial { - public: - AnalysisDataDisplacementModule(); - ~AnalysisDataDisplacementModule() override; +public: + AnalysisDataDisplacementModule(); + ~AnalysisDataDisplacementModule() override; - /*! \brief - * Sets the largest displacement time to be calculated. - */ - void setMaxTime(real tmax); - /*! \brief - * Sets an histogram module that will receive a MSD histogram. - * - * If this function is not called, no histogram is calculated. - */ - void setMSDHistogram(const std::shared_ptr &histm); + /*! \brief + * Sets the largest displacement time to be calculated. + */ + void setMaxTime(real tmax); + /*! \brief + * Sets an histogram module that will receive a MSD histogram. + * + * If this function is not called, no histogram is calculated. + */ + void setMSDHistogram(const std::shared_ptr& histm); - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - class Impl; + class Impl; - PrivateImplPointer _impl; + PrivateImplPointer _impl; }; //! Smart pointer to manage an AnalysisDataDisplacementModule object. -typedef std::shared_ptr - AnalysisDataDisplacementModulePointer; +typedef std::shared_ptr AnalysisDataDisplacementModulePointer; } // namespace gmx diff --git a/src/gromacs/analysisdata/modules/frameaverager.cpp b/src/gromacs/analysisdata/modules/frameaverager.cpp index 53ffd297c9..1ba439212c 100644 --- a/src/gromacs/analysisdata/modules/frameaverager.cpp +++ b/src/gromacs/analysisdata/modules/frameaverager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,21 +52,20 @@ namespace gmx void AnalysisDataFrameAverager::setColumnCount(int columnCount) { GMX_RELEASE_ASSERT(columnCount >= 0, "Invalid column count"); - GMX_RELEASE_ASSERT(values_.empty(), - "Cannot initialize multiple times"); + GMX_RELEASE_ASSERT(values_.empty(), "Cannot initialize multiple times"); values_.resize(columnCount); } void AnalysisDataFrameAverager::addValue(int index, real value) { - AverageItem &item = values_[index]; + AverageItem& item = values_[index]; const double delta = value - item.average; - item.samples += 1; - item.average += delta / item.samples; + item.samples += 1; + item.average += delta / item.samples; item.squaredSum += delta * (value - item.average); } -void AnalysisDataFrameAverager::addPoints(const AnalysisDataPointSetRef &points) +void AnalysisDataFrameAverager::addPoints(const AnalysisDataPointSetRef& points) { const int firstColumn = points.firstColumn(); GMX_ASSERT(static_cast(firstColumn + points.columnCount()) <= values_.size(), @@ -78,7 +77,6 @@ void AnalysisDataFrameAverager::addPoints(const AnalysisDataPointSetRef &points) addValue(firstColumn + i, points.y(i)); } } - } void AnalysisDataFrameAverager::finish() diff --git a/src/gromacs/analysisdata/modules/frameaverager.h b/src/gromacs/analysisdata/modules/frameaverager.h index 96562ee384..379750facf 100644 --- a/src/gromacs/analysisdata/modules/frameaverager.h +++ b/src/gromacs/analysisdata/modules/frameaverager.h @@ -74,109 +74,103 @@ class AnalysisDataPointSetRef; */ class AnalysisDataFrameAverager { - public: - AnalysisDataFrameAverager() : bFinished_(false) {} +public: + AnalysisDataFrameAverager() : bFinished_(false) {} - /*! \brief - * Returns the number of columns in this averager. - */ - int columnCount() const { return values_.size(); } + /*! \brief + * Returns the number of columns in this averager. + */ + int columnCount() const { return values_.size(); } - /*! \brief - * Sets the number of columns in the input data. - * - * \throws std::bad_alloc if out of memory. - * - * Typically called from IAnalysisDataModule::dataStarted(). - * - * Must be called exactly once, before setting calling any other method - * in the class. - */ - void setColumnCount(int columnCount); - /*! \brief - * Adds a single value to the average for a given column. - * - * \param[in] index Index of the column to add the value to. - * \param[in] value Value to add to the sample. - */ - void addValue(int index, real value); - /*! \brief - * Accumulates data from a given point set into the average. - * - * Typically called from IAnalysisDataModule::pointsAdded(). - * - * Each call accumulates the values for those columns that are present - * in the point set. Can be called multiple times for a frame, and - * does not need to be called for every frame. - */ - void addPoints(const AnalysisDataPointSetRef &points); - /*! \brief - * Finalizes the calculation of the averages and variances. - * - * Does any computation that is not done during the accumulation in - * addPoints(). Currently, does nothing, but provided as a placeholder - * for more complex implementation. - * - * Typically called from IAnalysisDataModule::dataFinished(). - */ - void finish(); + /*! \brief + * Sets the number of columns in the input data. + * + * \throws std::bad_alloc if out of memory. + * + * Typically called from IAnalysisDataModule::dataStarted(). + * + * Must be called exactly once, before setting calling any other method + * in the class. + */ + void setColumnCount(int columnCount); + /*! \brief + * Adds a single value to the average for a given column. + * + * \param[in] index Index of the column to add the value to. + * \param[in] value Value to add to the sample. + */ + void addValue(int index, real value); + /*! \brief + * Accumulates data from a given point set into the average. + * + * Typically called from IAnalysisDataModule::pointsAdded(). + * + * Each call accumulates the values for those columns that are present + * in the point set. Can be called multiple times for a frame, and + * does not need to be called for every frame. + */ + void addPoints(const AnalysisDataPointSetRef& points); + /*! \brief + * Finalizes the calculation of the averages and variances. + * + * Does any computation that is not done during the accumulation in + * addPoints(). Currently, does nothing, but provided as a placeholder + * for more complex implementation. + * + * Typically called from IAnalysisDataModule::dataFinished(). + */ + void finish(); - /*! \brief - * Returns the computed average for a given column. - * - * If called before finish(), the results are undefined. - */ - real average(int index) const - { - GMX_ASSERT(index >= 0 && index < columnCount(), - "Invalid column index"); - GMX_ASSERT(bFinished_, - "Values available only after finished() has been called"); - return values_[index].average; - } - /*! \brief - * Returns the computed (sample) variance for a given column. - * - * If called before finish(), the results are undefined. - */ - real variance(int index) const - { - GMX_ASSERT(index >= 0 && index < columnCount(), - "Invalid column index"); - GMX_ASSERT(bFinished_, - "Values available only after finished() has been called"); - const AverageItem &item = values_[index]; - return item.samples > 1 ? item.squaredSum / (item.samples - 1) : 0.0; - } - /*! \brief - * Returns the number of samples for a given column. - * - * If called before finish(), the results are undefined. - */ - int sampleCount(int index) const - { - GMX_ASSERT(index >= 0 && index <= ssize(values_), - "Invalid column index"); - GMX_ASSERT(bFinished_, - "Values available only after finished() has been called"); - return values_[index].samples; - } + /*! \brief + * Returns the computed average for a given column. + * + * If called before finish(), the results are undefined. + */ + real average(int index) const + { + GMX_ASSERT(index >= 0 && index < columnCount(), "Invalid column index"); + GMX_ASSERT(bFinished_, "Values available only after finished() has been called"); + return values_[index].average; + } + /*! \brief + * Returns the computed (sample) variance for a given column. + * + * If called before finish(), the results are undefined. + */ + real variance(int index) const + { + GMX_ASSERT(index >= 0 && index < columnCount(), "Invalid column index"); + GMX_ASSERT(bFinished_, "Values available only after finished() has been called"); + const AverageItem& item = values_[index]; + return item.samples > 1 ? item.squaredSum / (item.samples - 1) : 0.0; + } + /*! \brief + * Returns the number of samples for a given column. + * + * If called before finish(), the results are undefined. + */ + int sampleCount(int index) const + { + GMX_ASSERT(index >= 0 && index <= ssize(values_), "Invalid column index"); + GMX_ASSERT(bFinished_, "Values available only after finished() has been called"); + return values_[index].samples; + } - private: - struct AverageItem - { - AverageItem() : average(0.0), squaredSum(0.0), samples(0) {} +private: + struct AverageItem + { + AverageItem() : average(0.0), squaredSum(0.0), samples(0) {} - //! Average of the values so far. - double average; - //! Sum of squared deviations from the average for values so far. - double squaredSum; - //! Number of values so far. - int samples; - }; + //! Average of the values so far. + double average; + //! Sum of squared deviations from the average for values so far. + double squaredSum; + //! Number of values so far. + int samples; + }; - std::vector values_; - bool bFinished_; + std::vector values_; + bool bFinished_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/modules/histogram.cpp b/src/gromacs/analysisdata/modules/histogram.cpp index f77f96e9c7..1dbecbf2ee 100644 --- a/src/gromacs/analysisdata/modules/histogram.cpp +++ b/src/gromacs/analysisdata/modules/histogram.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -78,10 +78,14 @@ namespace gmx * AnalysisHistogramSettingsInitializer */ -AnalysisHistogramSettingsInitializer::AnalysisHistogramSettingsInitializer() - : min_(UNDEFINED), max_(UNDEFINED), binWidth_(UNDEFINED), - binCount_(0), bIntegerBins_(false), bRoundRange_(false), - bIncludeAll_(false) +AnalysisHistogramSettingsInitializer::AnalysisHistogramSettingsInitializer() : + min_(UNDEFINED), + max_(UNDEFINED), + binWidth_(UNDEFINED), + binCount_(0), + bIntegerBins_(false), + bRoundRange_(false), + bIncludeAll_(false) { } @@ -90,31 +94,31 @@ AnalysisHistogramSettingsInitializer::AnalysisHistogramSettingsInitializer() * AnalysisHistogramSettings */ -AnalysisHistogramSettings::AnalysisHistogramSettings() - : firstEdge_(0.0), lastEdge_(0.0), binWidth_(0.0), inverseBinWidth_(0.0), - binCount_(0), bAll_(false) +AnalysisHistogramSettings::AnalysisHistogramSettings() : + firstEdge_(0.0), + lastEdge_(0.0), + binWidth_(0.0), + inverseBinWidth_(0.0), + binCount_(0), + bAll_(false) { } -AnalysisHistogramSettings::AnalysisHistogramSettings( - const AnalysisHistogramSettingsInitializer &settings) +AnalysisHistogramSettings::AnalysisHistogramSettings(const AnalysisHistogramSettingsInitializer& settings) { - GMX_RELEASE_ASSERT(isDefined(settings.min_), - "Histogram start value must be defined"); + GMX_RELEASE_ASSERT(isDefined(settings.min_), "Histogram start value must be defined"); GMX_RELEASE_ASSERT(!isDefined(settings.max_) || settings.max_ > settings.min_, "Histogram end value must be larger than start value"); GMX_RELEASE_ASSERT(!isDefined(settings.binWidth_) || settings.binWidth_ > 0.0, "Histogram bin width must be positive"); - GMX_RELEASE_ASSERT(settings.binCount_ >= 0, - "Histogram bin count must be positive"); + GMX_RELEASE_ASSERT(settings.binCount_ >= 0, "Histogram bin count must be positive"); if (!isDefined(settings.max_)) { GMX_RELEASE_ASSERT(isDefined(settings.binWidth_) && settings.binCount_ > 0, "Not all required values provided"); - GMX_RELEASE_ASSERT(!settings.bRoundRange_, - "Rounding only supported for min/max ranges"); + GMX_RELEASE_ASSERT(!settings.bRoundRange_, "Rounding only supported for min/max ranges"); firstEdge_ = settings.min_; binCount_ = settings.binCount_; @@ -145,8 +149,8 @@ AnalysisHistogramSettings::AnalysisHistogramSettings( } else { - firstEdge_ = settings.min_; - lastEdge_ = settings.max_; + firstEdge_ = settings.min_; + lastEdge_ = settings.max_; if (settings.binCount_ > 0) { binCount_ = settings.binCount_; @@ -154,9 +158,9 @@ AnalysisHistogramSettings::AnalysisHistogramSettings( { GMX_RELEASE_ASSERT(settings.binCount_ > 1, "Bin count must be at least two with integer bins"); - binWidth_ = (lastEdge_ - firstEdge_) / (binCount_ - 1); + binWidth_ = (lastEdge_ - firstEdge_) / (binCount_ - 1); firstEdge_ -= 0.5 * binWidth_; - lastEdge_ += 0.5 * binWidth_; + lastEdge_ += 0.5 * binWidth_; } else { @@ -182,8 +186,7 @@ AnalysisHistogramSettings::AnalysisHistogramSettings( } -int -AnalysisHistogramSettings::findBin(real y) const +int AnalysisHistogramSettings::findBin(real y) const { if (y < firstEdge_) { @@ -216,64 +219,52 @@ namespace */ class StaticAverageHistogram : public AbstractAverageHistogram { - public: - StaticAverageHistogram(); - //! Creates an average histogram module with defined bin parameters. - explicit StaticAverageHistogram(const AnalysisHistogramSettings &settings); +public: + StaticAverageHistogram(); + //! Creates an average histogram module with defined bin parameters. + explicit StaticAverageHistogram(const AnalysisHistogramSettings& settings); - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; -StaticAverageHistogram::StaticAverageHistogram() -{ -} +StaticAverageHistogram::StaticAverageHistogram() {} -StaticAverageHistogram::StaticAverageHistogram( - const AnalysisHistogramSettings &settings) - : AbstractAverageHistogram(settings) +StaticAverageHistogram::StaticAverageHistogram(const AnalysisHistogramSettings& settings) : + AbstractAverageHistogram(settings) { } -} // namespace +} // namespace /******************************************************************** * AbstractAverageHistogram */ -AbstractAverageHistogram::AbstractAverageHistogram() -{ -} +AbstractAverageHistogram::AbstractAverageHistogram() {} -AbstractAverageHistogram::AbstractAverageHistogram( - const AnalysisHistogramSettings &settings) - : settings_(settings) +AbstractAverageHistogram::AbstractAverageHistogram(const AnalysisHistogramSettings& settings) : + settings_(settings) { setRowCount(settings.binCount()); - setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), - settings.binWidth()); + setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), settings.binWidth()); } -AbstractAverageHistogram::~AbstractAverageHistogram() -{ -} +AbstractAverageHistogram::~AbstractAverageHistogram() {} -void -AbstractAverageHistogram::init(const AnalysisHistogramSettings &settings) +void AbstractAverageHistogram::init(const AnalysisHistogramSettings& settings) { settings_ = settings; setRowCount(settings.binCount()); - setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), - settings.binWidth()); + setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), settings.binWidth()); } -AverageHistogramPointer -AbstractAverageHistogram::resampleDoubleBinWidth(bool bIntegerBins) const +AverageHistogramPointer AbstractAverageHistogram::resampleDoubleBinWidth(bool bIntegerBins) const { int nbins; if (bIntegerBins) @@ -285,21 +276,19 @@ AbstractAverageHistogram::resampleDoubleBinWidth(bool bIntegerBins) const nbins = rowCount() / 2; } - AverageHistogramPointer dest( - new StaticAverageHistogram( - histogramFromBins(settings().firstEdge(), nbins, 2*xstep()) - .integerBins(bIntegerBins))); + AverageHistogramPointer dest(new StaticAverageHistogram( + histogramFromBins(settings().firstEdge(), nbins, 2 * xstep()).integerBins(bIntegerBins))); dest->setColumnCount(columnCount()); dest->allocateValues(); - int i, j; + int i, j; for (i = j = 0; i < nbins; ++i) { const bool bFirstHalfBin = (bIntegerBins && i == 0); for (int c = 0; c < columnCount(); ++c) { - real v1, v2; - real e1, e2; + real v1, v2; + real e1, e2; if (bFirstHalfBin) { v1 = value(0, c).value(); @@ -329,8 +318,7 @@ AbstractAverageHistogram::resampleDoubleBinWidth(bool bIntegerBins) const } -AverageHistogramPointer -AbstractAverageHistogram::clone() const +AverageHistogramPointer AbstractAverageHistogram::clone() const { AverageHistogramPointer dest(new StaticAverageHistogram()); copyContents(this, dest.get()); @@ -339,8 +327,7 @@ AbstractAverageHistogram::clone() const } -void -AbstractAverageHistogram::normalizeProbability() +void AbstractAverageHistogram::normalizeProbability() { for (int c = 0; c < columnCount(); ++c) { @@ -356,8 +343,7 @@ AbstractAverageHistogram::normalizeProbability() } } -void -AbstractAverageHistogram::makeCumulative() +void AbstractAverageHistogram::makeCumulative() { for (int c = 0; c < columnCount(); ++c) { @@ -370,13 +356,11 @@ AbstractAverageHistogram::makeCumulative() value(i, c).setValue(sum); } } - setXAxis(settings().firstEdge() + settings().binWidth(), - settings().binWidth()); + setXAxis(settings().firstEdge() + settings().binWidth(), settings().binWidth()); } -void -AbstractAverageHistogram::scaleSingle(int index, real factor) +void AbstractAverageHistogram::scaleSingle(int index, real factor) { for (int i = 0; i < rowCount(); ++i) { @@ -386,8 +370,7 @@ AbstractAverageHistogram::scaleSingle(int index, real factor) } -void -AbstractAverageHistogram::scaleAll(real factor) +void AbstractAverageHistogram::scaleAll(real factor) { for (int i = 0; i < columnCount(); ++i) { @@ -396,8 +379,7 @@ AbstractAverageHistogram::scaleAll(real factor) } -void -AbstractAverageHistogram::scaleAllByVector(const real factor[]) +void AbstractAverageHistogram::scaleAllByVector(const real factor[]) { for (int c = 0; c < columnCount(); ++c) { @@ -429,52 +411,46 @@ namespace internal * * \ingroup module_analysisdata */ -class BasicAverageHistogramModule : public AbstractAverageHistogram, - public AnalysisDataModuleSerial +class BasicAverageHistogramModule : public AbstractAverageHistogram, public AnalysisDataModuleSerial { - public: - BasicAverageHistogramModule(); - //! Creates an average histogram module with defined bin parameters. - explicit BasicAverageHistogramModule(const AnalysisHistogramSettings &settings); +public: + BasicAverageHistogramModule(); + //! Creates an average histogram module with defined bin parameters. + explicit BasicAverageHistogramModule(const AnalysisHistogramSettings& settings); - using AbstractAverageHistogram::init; + using AbstractAverageHistogram::init; - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - private: - //! Averaging helper objects for each input data set. - std::vector averagers_; +private: + //! Averaging helper objects for each input data set. + std::vector averagers_; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; -BasicAverageHistogramModule::BasicAverageHistogramModule() -{ -} +BasicAverageHistogramModule::BasicAverageHistogramModule() {} -BasicAverageHistogramModule::BasicAverageHistogramModule( - const AnalysisHistogramSettings &settings) - : AbstractAverageHistogram(settings) +BasicAverageHistogramModule::BasicAverageHistogramModule(const AnalysisHistogramSettings& settings) : + AbstractAverageHistogram(settings) { } -int -BasicAverageHistogramModule::flags() const +int BasicAverageHistogramModule::flags() const { return efAllowMulticolumn | efAllowMultipleDataSets; } -void -BasicAverageHistogramModule::dataStarted(AbstractAnalysisData *data) +void BasicAverageHistogramModule::dataStarted(AbstractAnalysisData* data) { setColumnCount(data->dataSetCount()); averagers_.resize(data->dataSetCount()); @@ -487,27 +463,19 @@ BasicAverageHistogramModule::dataStarted(AbstractAnalysisData *data) } -void -BasicAverageHistogramModule::frameStarted(const AnalysisDataFrameHeader & /*header*/) -{ -} +void BasicAverageHistogramModule::frameStarted(const AnalysisDataFrameHeader& /*header*/) {} -void -BasicAverageHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points) +void BasicAverageHistogramModule::pointsAdded(const AnalysisDataPointSetRef& points) { averagers_[points.dataSetIndex()].addPoints(points); } -void -BasicAverageHistogramModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) -{ -} +void BasicAverageHistogramModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {} -void -BasicAverageHistogramModule::dataFinished() +void BasicAverageHistogramModule::dataFinished() { allocateValues(); for (int i = 0; i < columnCount(); ++i) @@ -515,8 +483,7 @@ BasicAverageHistogramModule::dataFinished() averagers_[i].finish(); for (int j = 0; j < rowCount(); ++j) { - value(j, i).setValue(averagers_[i].average(j), - std::sqrt(averagers_[i].variance(j))); + value(j, i).setValue(averagers_[i].average(j), std::sqrt(averagers_[i].variance(j))); } } } @@ -539,54 +506,49 @@ BasicAverageHistogramModule::dataFinished() */ class BasicHistogramImpl { - public: - //! Smart pointer to manage an BasicAverageHistogramModule object. - typedef std::shared_ptr - BasicAverageHistogramModulePointer; - - BasicHistogramImpl(); - //! Creates an histogram impl with defined bin parameters. - explicit BasicHistogramImpl(const AnalysisHistogramSettings &settings); - // Virtual only for simplicity. - virtual ~BasicHistogramImpl(); - - /*! \brief - * (Re)initializes the histogram from settings. - */ - void init(const AnalysisHistogramSettings &settings); - - //! Storage implementation object. - AnalysisDataStorage storage_; - //! Settings for the histogram object. - AnalysisHistogramSettings settings_; - //! Averager module. - BasicAverageHistogramModulePointer averager_; +public: + //! Smart pointer to manage an BasicAverageHistogramModule object. + typedef std::shared_ptr BasicAverageHistogramModulePointer; + + BasicHistogramImpl(); + //! Creates an histogram impl with defined bin parameters. + explicit BasicHistogramImpl(const AnalysisHistogramSettings& settings); + // Virtual only for simplicity. + virtual ~BasicHistogramImpl(); + + /*! \brief + * (Re)initializes the histogram from settings. + */ + void init(const AnalysisHistogramSettings& settings); + + //! Storage implementation object. + AnalysisDataStorage storage_; + //! Settings for the histogram object. + AnalysisHistogramSettings settings_; + //! Averager module. + BasicAverageHistogramModulePointer averager_; }; -BasicHistogramImpl::BasicHistogramImpl() - : averager_(new BasicAverageHistogramModule()) -{ -} +BasicHistogramImpl::BasicHistogramImpl() : averager_(new BasicAverageHistogramModule()) {} -BasicHistogramImpl::BasicHistogramImpl(const AnalysisHistogramSettings &settings) - : settings_(settings), averager_(new BasicAverageHistogramModule(settings)) +BasicHistogramImpl::BasicHistogramImpl(const AnalysisHistogramSettings& settings) : + settings_(settings), + averager_(new BasicAverageHistogramModule(settings)) { } -BasicHistogramImpl::~BasicHistogramImpl() -{ -} +BasicHistogramImpl::~BasicHistogramImpl() {} -void BasicHistogramImpl::init(const AnalysisHistogramSettings &settings) +void BasicHistogramImpl::init(const AnalysisHistogramSettings& settings) { settings_ = settings; averager_->init(settings); } -} // namespace internal +} // namespace internal /******************************************************************** @@ -600,78 +562,62 @@ void BasicHistogramImpl::init(const AnalysisHistogramSettings &settings) */ class AnalysisDataSimpleHistogramModule::Impl : public internal::BasicHistogramImpl { - public: - //! Shorthand for the per-frame accumulation data structure type. - typedef AnalysisDataFrameLocalData FrameLocalData; +public: + //! Shorthand for the per-frame accumulation data structure type. + typedef AnalysisDataFrameLocalData FrameLocalData; - Impl() {} - //! Creates an histogram impl with defined bin parameters. - explicit Impl(const AnalysisHistogramSettings &settings) - : BasicHistogramImpl(settings) - { - } + Impl() {} + //! Creates an histogram impl with defined bin parameters. + explicit Impl(const AnalysisHistogramSettings& settings) : BasicHistogramImpl(settings) {} - //! Accumulates the histogram within a frame. - FrameLocalData accumulator_; + //! Accumulates the histogram within a frame. + FrameLocalData accumulator_; }; -AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() - : impl_(new Impl()) -{ -} +AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() : impl_(new Impl()) {} -AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule( - const AnalysisHistogramSettings &settings) - : impl_(new Impl(settings)) +AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings& settings) : + impl_(new Impl(settings)) { } -AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule() -{ -} +AnalysisDataSimpleHistogramModule::~AnalysisDataSimpleHistogramModule() {} -void AnalysisDataSimpleHistogramModule::init(const AnalysisHistogramSettings &settings) +void AnalysisDataSimpleHistogramModule::init(const AnalysisHistogramSettings& settings) { impl_->init(settings); } -AbstractAverageHistogram & -AnalysisDataSimpleHistogramModule::averager() +AbstractAverageHistogram& AnalysisDataSimpleHistogramModule::averager() { return *impl_->averager_; } -const AnalysisHistogramSettings & -AnalysisDataSimpleHistogramModule::settings() const +const AnalysisHistogramSettings& AnalysisDataSimpleHistogramModule::settings() const { return impl_->settings_; } -int -AnalysisDataSimpleHistogramModule::frameCount() const +int AnalysisDataSimpleHistogramModule::frameCount() const { return impl_->storage_.frameCount(); } -int -AnalysisDataSimpleHistogramModule::flags() const +int AnalysisDataSimpleHistogramModule::flags() const { - return efAllowMulticolumn | efAllowMultipoint | efAllowMissing - | efAllowMultipleDataSets; + return efAllowMulticolumn | efAllowMultipoint | efAllowMissing | efAllowMultipleDataSets; } -bool -AnalysisDataSimpleHistogramModule::parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) +bool AnalysisDataSimpleHistogramModule::parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) { addModule(impl_->averager_); const int dataSetCount = data->dataSetCount(); @@ -689,18 +635,16 @@ AnalysisDataSimpleHistogramModule::parallelDataStarted( } -void -AnalysisDataSimpleHistogramModule::frameStarted(const AnalysisDataFrameHeader &header) +void AnalysisDataSimpleHistogramModule::frameStarted(const AnalysisDataFrameHeader& header) { impl_->accumulator_.frameData(header.index()).clear(); } -void -AnalysisDataSimpleHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataSimpleHistogramModule::pointsAdded(const AnalysisDataPointSetRef& points) { - Impl::FrameLocalData::DataSetHandle handle - = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex()); + Impl::FrameLocalData::DataSetHandle handle = + impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex()); for (int i = 0; i < points.columnCount(); ++i) { if (points.present(i)) @@ -715,13 +659,11 @@ AnalysisDataSimpleHistogramModule::pointsAdded(const AnalysisDataPointSetRef &po } -void -AnalysisDataSimpleHistogramModule::frameFinished(const AnalysisDataFrameHeader &header) +void AnalysisDataSimpleHistogramModule::frameFinished(const AnalysisDataFrameHeader& header) { - Impl::FrameLocalData::FrameHandle handle - = impl_->accumulator_.frameData(header.index()); - AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header); - const int columnCount = settings().binCount(); + Impl::FrameLocalData::FrameHandle handle = impl_->accumulator_.frameData(header.index()); + AnalysisDataStorageFrame& frame = impl_->storage_.startFrame(header); + const int columnCount = settings().binCount(); for (int s = 0; s < dataSetCount(); ++s) { Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s); @@ -735,29 +677,25 @@ AnalysisDataSimpleHistogramModule::frameFinished(const AnalysisDataFrameHeader & } -void -AnalysisDataSimpleHistogramModule::frameFinishedSerial(int frameIndex) +void AnalysisDataSimpleHistogramModule::frameFinishedSerial(int frameIndex) { impl_->storage_.finishFrameSerial(frameIndex); } -void -AnalysisDataSimpleHistogramModule::dataFinished() +void AnalysisDataSimpleHistogramModule::dataFinished() { impl_->storage_.finishDataStorage(); } -AnalysisDataFrameRef -AnalysisDataSimpleHistogramModule::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AnalysisDataSimpleHistogramModule::tryGetDataFrameInternal(int index) const { return impl_->storage_.tryGetDataFrame(index); } -bool -AnalysisDataSimpleHistogramModule::requestStorageInternal(int nframes) +bool AnalysisDataSimpleHistogramModule::requestStorageInternal(int nframes) { return impl_->storage_.requestStorage(nframes); } @@ -774,77 +712,62 @@ AnalysisDataSimpleHistogramModule::requestStorageInternal(int nframes) */ class AnalysisDataWeightedHistogramModule::Impl : public internal::BasicHistogramImpl { - public: - //! Shorthand for the per-frame accumulation data structure type. - typedef AnalysisDataFrameLocalData FrameLocalData; +public: + //! Shorthand for the per-frame accumulation data structure type. + typedef AnalysisDataFrameLocalData FrameLocalData; - Impl() {} - //! Creates an histogram impl with defined bin parameters. - explicit Impl(const AnalysisHistogramSettings &settings) - : BasicHistogramImpl(settings) - { - } + Impl() {} + //! Creates an histogram impl with defined bin parameters. + explicit Impl(const AnalysisHistogramSettings& settings) : BasicHistogramImpl(settings) {} - //! Accumulates the histogram within a frame. - FrameLocalData accumulator_; + //! Accumulates the histogram within a frame. + FrameLocalData accumulator_; }; -AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule() - : impl_(new Impl()) -{ -} +AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule() : impl_(new Impl()) {} -AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule( - const AnalysisHistogramSettings &settings) - : impl_(new Impl(settings)) +AnalysisDataWeightedHistogramModule::AnalysisDataWeightedHistogramModule(const AnalysisHistogramSettings& settings) : + impl_(new Impl(settings)) { } -AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule() -{ -} +AnalysisDataWeightedHistogramModule::~AnalysisDataWeightedHistogramModule() {} -void AnalysisDataWeightedHistogramModule::init(const AnalysisHistogramSettings &settings) +void AnalysisDataWeightedHistogramModule::init(const AnalysisHistogramSettings& settings) { impl_->init(settings); } -AbstractAverageHistogram & -AnalysisDataWeightedHistogramModule::averager() +AbstractAverageHistogram& AnalysisDataWeightedHistogramModule::averager() { return *impl_->averager_; } -const AnalysisHistogramSettings & -AnalysisDataWeightedHistogramModule::settings() const +const AnalysisHistogramSettings& AnalysisDataWeightedHistogramModule::settings() const { return impl_->settings_; } -int -AnalysisDataWeightedHistogramModule::frameCount() const +int AnalysisDataWeightedHistogramModule::frameCount() const { return impl_->storage_.frameCount(); } -int -AnalysisDataWeightedHistogramModule::flags() const +int AnalysisDataWeightedHistogramModule::flags() const { return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets; } -bool -AnalysisDataWeightedHistogramModule::parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) +bool AnalysisDataWeightedHistogramModule::parallelDataStarted(AbstractAnalysisData* data, + const AnalysisDataParallelOptions& options) { addModule(impl_->averager_); const int dataSetCount = data->dataSetCount(); @@ -862,15 +785,13 @@ AnalysisDataWeightedHistogramModule::parallelDataStarted( } -void -AnalysisDataWeightedHistogramModule::frameStarted(const AnalysisDataFrameHeader &header) +void AnalysisDataWeightedHistogramModule::frameStarted(const AnalysisDataFrameHeader& header) { impl_->accumulator_.frameData(header.index()).clear(); } -void -AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (points.firstColumn() != 0 || points.columnCount() < 2) { @@ -879,8 +800,8 @@ AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef & int bin = settings().findBin(points.y(0)); if (bin != -1) { - Impl::FrameLocalData::DataSetHandle handle - = impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex()); + Impl::FrameLocalData::DataSetHandle handle = + impl_->accumulator_.frameDataSet(points.frameIndex(), points.dataSetIndex()); for (int i = 1; i < points.columnCount(); ++i) { handle.value(bin) += points.y(i); @@ -889,13 +810,11 @@ AnalysisDataWeightedHistogramModule::pointsAdded(const AnalysisDataPointSetRef & } -void -AnalysisDataWeightedHistogramModule::frameFinished(const AnalysisDataFrameHeader &header) +void AnalysisDataWeightedHistogramModule::frameFinished(const AnalysisDataFrameHeader& header) { - Impl::FrameLocalData::FrameHandle handle - = impl_->accumulator_.frameData(header.index()); - AnalysisDataStorageFrame &frame = impl_->storage_.startFrame(header); - const int columnCount = settings().binCount(); + Impl::FrameLocalData::FrameHandle handle = impl_->accumulator_.frameData(header.index()); + AnalysisDataStorageFrame& frame = impl_->storage_.startFrame(header); + const int columnCount = settings().binCount(); for (int s = 0; s < dataSetCount(); ++s) { Impl::FrameLocalData::DataSetHandle dataSet = handle.dataSet(s); @@ -909,29 +828,25 @@ AnalysisDataWeightedHistogramModule::frameFinished(const AnalysisDataFrameHeader } -void -AnalysisDataWeightedHistogramModule::frameFinishedSerial(int frameIndex) +void AnalysisDataWeightedHistogramModule::frameFinishedSerial(int frameIndex) { impl_->storage_.finishFrameSerial(frameIndex); } -void -AnalysisDataWeightedHistogramModule::dataFinished() +void AnalysisDataWeightedHistogramModule::dataFinished() { impl_->storage_.finishDataStorage(); } -AnalysisDataFrameRef -AnalysisDataWeightedHistogramModule::tryGetDataFrameInternal(int index) const +AnalysisDataFrameRef AnalysisDataWeightedHistogramModule::tryGetDataFrameInternal(int index) const { return impl_->storage_.tryGetDataFrame(index); } -bool -AnalysisDataWeightedHistogramModule::requestStorageInternal(int nframes) +bool AnalysisDataWeightedHistogramModule::requestStorageInternal(int nframes) { return impl_->storage_.requestStorage(nframes); } @@ -943,67 +858,54 @@ AnalysisDataWeightedHistogramModule::requestStorageInternal(int nframes) class AnalysisDataBinAverageModule::Impl { - public: - Impl() {} - explicit Impl(const AnalysisHistogramSettings &settings) - : settings_(settings) - { - } +public: + Impl() {} + explicit Impl(const AnalysisHistogramSettings& settings) : settings_(settings) {} - //! Histogram settings. - AnalysisHistogramSettings settings_; - //! Averaging helper objects for each input data set. - std::vector averagers_; + //! Histogram settings. + AnalysisHistogramSettings settings_; + //! Averaging helper objects for each input data set. + std::vector averagers_; }; -AnalysisDataBinAverageModule::AnalysisDataBinAverageModule() - : impl_(new Impl()) +AnalysisDataBinAverageModule::AnalysisDataBinAverageModule() : impl_(new Impl()) { setColumnCount(3); } -AnalysisDataBinAverageModule::AnalysisDataBinAverageModule( - const AnalysisHistogramSettings &settings) - : impl_(new Impl(settings)) +AnalysisDataBinAverageModule::AnalysisDataBinAverageModule(const AnalysisHistogramSettings& settings) : + impl_(new Impl(settings)) { setRowCount(settings.binCount()); - setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), - settings.binWidth()); + setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), settings.binWidth()); } -AnalysisDataBinAverageModule::~AnalysisDataBinAverageModule() -{ -} +AnalysisDataBinAverageModule::~AnalysisDataBinAverageModule() {} -void -AnalysisDataBinAverageModule::init(const AnalysisHistogramSettings &settings) +void AnalysisDataBinAverageModule::init(const AnalysisHistogramSettings& settings) { impl_->settings_ = settings; setRowCount(settings.binCount()); - setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), - settings.binWidth()); + setXAxis(settings.firstEdge() + 0.5 * settings.binWidth(), settings.binWidth()); } -const AnalysisHistogramSettings & -AnalysisDataBinAverageModule::settings() const +const AnalysisHistogramSettings& AnalysisDataBinAverageModule::settings() const { return impl_->settings_; } -int -AnalysisDataBinAverageModule::flags() const +int AnalysisDataBinAverageModule::flags() const { return efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets; } -void -AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData *data) +void AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData* data) { setColumnCount(data->dataSetCount()); impl_->averagers_.resize(data->dataSetCount()); @@ -1014,14 +916,10 @@ AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData *data) } -void -AnalysisDataBinAverageModule::frameStarted(const AnalysisDataFrameHeader & /*header*/) -{ -} +void AnalysisDataBinAverageModule::frameStarted(const AnalysisDataFrameHeader& /*header*/) {} -void -AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (points.firstColumn() != 0 || points.columnCount() < 2) { @@ -1030,7 +928,7 @@ AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) int bin = settings().findBin(points.y(0)); if (bin != -1) { - AnalysisDataFrameAverager &averager = impl_->averagers_[points.dataSetIndex()]; + AnalysisDataFrameAverager& averager = impl_->averagers_[points.dataSetIndex()]; for (int i = 1; i < points.columnCount(); ++i) { averager.addValue(bin, points.y(i)); @@ -1039,24 +937,19 @@ AnalysisDataBinAverageModule::pointsAdded(const AnalysisDataPointSetRef &points) } -void -AnalysisDataBinAverageModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) -{ -} +void AnalysisDataBinAverageModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {} -void -AnalysisDataBinAverageModule::dataFinished() +void AnalysisDataBinAverageModule::dataFinished() { allocateValues(); for (int i = 0; i < columnCount(); ++i) { - AnalysisDataFrameAverager &averager = impl_->averagers_[i]; + AnalysisDataFrameAverager& averager = impl_->averagers_[i]; averager.finish(); for (int j = 0; j < rowCount(); ++j) { - value(j, i).setValue(averager.average(j), - std::sqrt(averager.variance(j))); + value(j, i).setValue(averager.average(j), std::sqrt(averager.variance(j))); } } valuesReady(); diff --git a/src/gromacs/analysisdata/modules/histogram.h b/src/gromacs/analysisdata/modules/histogram.h index 4875b8926a..7a2f8c5ec9 100644 --- a/src/gromacs/analysisdata/modules/histogram.h +++ b/src/gromacs/analysisdata/modules/histogram.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,97 +67,119 @@ class AnalysisHistogramSettings; */ class AnalysisHistogramSettingsInitializer { - public: - /*! \brief - * Creates an empty initializer. - * - * Should not be called directly, but histogramFromRange() or - * histogramFromBins() should be used instead. - */ - AnalysisHistogramSettingsInitializer(); - - /*! \brief - * Sets the first bin location. - * - * Typically should not be called directly, but through - * histogramFromBins(). - */ - AnalysisHistogramSettingsInitializer &start(real min) - { min_ = min; return *this; } - /*! \brief - * Sets the number of bins in the histogram. - * - * If only the first bin location is specified, this value is required - * (and automatically provided if histogramFromBins() is used). - * If both the first and last bins are specified, either this value or - * binWidth() is required. - */ - AnalysisHistogramSettingsInitializer &binCount(int binCount) - { binCount_ = binCount; return *this; } - /*! \brief - * Sets the first and last bin locations. - * - * Typically should not be called directly, but through - * histogramFromRange(). - */ - AnalysisHistogramSettingsInitializer &range(real min, real max) - { min_ = min; max_ = max; return *this; } - /*! \brief - * Sets the bin width of the histogram. - * - * If only the first bin location is specified, this value is required - * (and automatically provided if histogramFromBins() is used). - * If both the first and last bins are specified, either this value or - * binCount() is required. - * If a bin width is provided with both first and last bin locations, - * and the given bin width does not divide the range exactly, the last - * bin location is adjusted to match. - */ - AnalysisHistogramSettingsInitializer &binWidth(real binWidth) - { binWidth_ = binWidth; return *this; } - /*! \brief - * Indicate that first and last bin locations to specify bin centers. - * - * If set, the first and last bin locations are interpreted as bin - * centers. - * If not set (the default), the first and last bin locations are - * interpreted as the edges of the whole histogram. - * - * Cannot be specified together with roundRange(). - */ - AnalysisHistogramSettingsInitializer &integerBins(bool enabled = true) - { bIntegerBins_ = enabled; return *this; } - /*! \brief - * Round first and last bin locations. - * - * If set, the resulting histogram will cover the range specified, but - * the actual bin locations will be rounded such that the edges fall - * on multiples of the bin width. - * Only implemented when both first and last bin location and bin width - * are defined. - * Cannot be specified together with integerBins() or with binCount(). - */ - AnalysisHistogramSettingsInitializer &roundRange(bool enabled = true) - { bRoundRange_ = enabled; return *this; } - /*! \brief - * Sets the histogram to match all values. - * - * If set, the histogram behaves as if the bins at the ends extended to - * +-infinity. - */ - AnalysisHistogramSettingsInitializer &includeAll(bool enabled = true) - { bIncludeAll_ = enabled; return *this; } - - private: - real min_; - real max_; - real binWidth_; - int binCount_; - bool bIntegerBins_; - bool bRoundRange_; - bool bIncludeAll_; - - friend class AnalysisHistogramSettings; +public: + /*! \brief + * Creates an empty initializer. + * + * Should not be called directly, but histogramFromRange() or + * histogramFromBins() should be used instead. + */ + AnalysisHistogramSettingsInitializer(); + + /*! \brief + * Sets the first bin location. + * + * Typically should not be called directly, but through + * histogramFromBins(). + */ + AnalysisHistogramSettingsInitializer& start(real min) + { + min_ = min; + return *this; + } + /*! \brief + * Sets the number of bins in the histogram. + * + * If only the first bin location is specified, this value is required + * (and automatically provided if histogramFromBins() is used). + * If both the first and last bins are specified, either this value or + * binWidth() is required. + */ + AnalysisHistogramSettingsInitializer& binCount(int binCount) + { + binCount_ = binCount; + return *this; + } + /*! \brief + * Sets the first and last bin locations. + * + * Typically should not be called directly, but through + * histogramFromRange(). + */ + AnalysisHistogramSettingsInitializer& range(real min, real max) + { + min_ = min; + max_ = max; + return *this; + } + /*! \brief + * Sets the bin width of the histogram. + * + * If only the first bin location is specified, this value is required + * (and automatically provided if histogramFromBins() is used). + * If both the first and last bins are specified, either this value or + * binCount() is required. + * If a bin width is provided with both first and last bin locations, + * and the given bin width does not divide the range exactly, the last + * bin location is adjusted to match. + */ + AnalysisHistogramSettingsInitializer& binWidth(real binWidth) + { + binWidth_ = binWidth; + return *this; + } + /*! \brief + * Indicate that first and last bin locations to specify bin centers. + * + * If set, the first and last bin locations are interpreted as bin + * centers. + * If not set (the default), the first and last bin locations are + * interpreted as the edges of the whole histogram. + * + * Cannot be specified together with roundRange(). + */ + AnalysisHistogramSettingsInitializer& integerBins(bool enabled = true) + { + bIntegerBins_ = enabled; + return *this; + } + /*! \brief + * Round first and last bin locations. + * + * If set, the resulting histogram will cover the range specified, but + * the actual bin locations will be rounded such that the edges fall + * on multiples of the bin width. + * Only implemented when both first and last bin location and bin width + * are defined. + * Cannot be specified together with integerBins() or with binCount(). + */ + AnalysisHistogramSettingsInitializer& roundRange(bool enabled = true) + { + bRoundRange_ = enabled; + return *this; + } + /*! \brief + * Sets the histogram to match all values. + * + * If set, the histogram behaves as if the bins at the ends extended to + * +-infinity. + */ + AnalysisHistogramSettingsInitializer& includeAll(bool enabled = true) + { + bIncludeAll_ = enabled; + return *this; + } + +private: + real min_; + real max_; + real binWidth_; + int binCount_; + bool bIntegerBins_; + bool bRoundRange_; + bool bIncludeAll_; + + friend class AnalysisHistogramSettings; }; /*! \brief @@ -167,8 +189,7 @@ class AnalysisHistogramSettingsInitializer * * \inpublicapi */ -inline AnalysisHistogramSettingsInitializer -histogramFromRange(real min, real max) +inline AnalysisHistogramSettingsInitializer histogramFromRange(real min, real max) { return AnalysisHistogramSettingsInitializer().range(min, max); } @@ -180,11 +201,9 @@ histogramFromRange(real min, real max) * * \inpublicapi */ -inline AnalysisHistogramSettingsInitializer -histogramFromBins(real start, int nbins, real binwidth) +inline AnalysisHistogramSettingsInitializer histogramFromBins(real start, int nbins, real binwidth) { - return AnalysisHistogramSettingsInitializer() - .start(start).binCount(nbins).binWidth(binwidth); + return AnalysisHistogramSettingsInitializer().start(start).binCount(nbins).binWidth(binwidth); } @@ -198,42 +217,42 @@ histogramFromBins(real start, int nbins, real binwidth) */ class AnalysisHistogramSettings { - public: - //! Initializes undefined parameters. - AnalysisHistogramSettings(); - /*! \brief - * Initializes parameters based on a named parameter object. - * - * This constructor is not explicit to allow initialization of - * histograms directly from AnalysisHistogramSettingsInitializer: - * \code - gmx::AnalysisDataSimpleHistogramModule *hist = - new gmx::AnalysisDataSimpleHistogramModule( - histogramFromRange(0.0, 5.0).binWidth(0.5)); - * \endcode - */ - AnalysisHistogramSettings(const AnalysisHistogramSettingsInitializer &settings); - - //! Returns the left edge of the first bin. - real firstEdge() const { return firstEdge_; } - //! Returns the right edge of the first bin. - real lastEdge() const { return lastEdge_; } - //! Returns the number of bins in the histogram. - int binCount() const { return binCount_; } - //! Returns the width of a bin in the histogram. - real binWidth() const { return binWidth_; } - //! Whether values beyond the edges are mapped to the edge bins. - bool includeAll() const { return bAll_; } - //! Returns a zero-based bin index for a value, or -1 if not in range. - int findBin(real y) const; - - private: - real firstEdge_; - real lastEdge_; - real binWidth_; - real inverseBinWidth_; - int binCount_; - bool bAll_; +public: + //! Initializes undefined parameters. + AnalysisHistogramSettings(); + /*! \brief + * Initializes parameters based on a named parameter object. + * + * This constructor is not explicit to allow initialization of + * histograms directly from AnalysisHistogramSettingsInitializer: + * \code + gmx::AnalysisDataSimpleHistogramModule *hist = + new gmx::AnalysisDataSimpleHistogramModule( + histogramFromRange(0.0, 5.0).binWidth(0.5)); + * \endcode + */ + AnalysisHistogramSettings(const AnalysisHistogramSettingsInitializer& settings); + + //! Returns the left edge of the first bin. + real firstEdge() const { return firstEdge_; } + //! Returns the right edge of the first bin. + real lastEdge() const { return lastEdge_; } + //! Returns the number of bins in the histogram. + int binCount() const { return binCount_; } + //! Returns the width of a bin in the histogram. + real binWidth() const { return binWidth_; } + //! Whether values beyond the edges are mapped to the edge bins. + bool includeAll() const { return bAll_; } + //! Returns a zero-based bin index for a value, or -1 if not in range. + int findBin(real y) const; + +private: + real firstEdge_; + real lastEdge_; + real binWidth_; + real inverseBinWidth_; + int binCount_; + bool bAll_; }; @@ -262,79 +281,79 @@ typedef std::unique_ptr AverageHistogramPointer; */ class AbstractAverageHistogram : public AbstractAnalysisArrayData { - public: - ~AbstractAverageHistogram() override; - - //! Returns bin properties for the histogram. - const AnalysisHistogramSettings &settings() const { return settings_; } - - /*! \brief - * Creates a copy of the histogram with double the bin width. - * - * \param[in] bIntegerBins If `true`, the first bin in the result will - * cover the first bin from the source. Otherwise, the first bin - * will cover first two bins from the source. - * \throws std::bad_alloc if out of memory. - * - * The caller is responsible of deleting the returned object. - */ - AverageHistogramPointer resampleDoubleBinWidth(bool bIntegerBins) const; - /*! \brief - * Creates a deep copy of the histogram. - * - * \throws std::bad_alloc if out of memory. - * - * The returned histogram is not necessarily of the same dynamic type - * as the original object, but contains the same data from the point of - * view of the AbstractAverageHistogram interface. - * - * The caller is responsible of deleting the returned object. - */ - AverageHistogramPointer clone() const; - //! Normalizes the histogram such that the integral over it is one. - void normalizeProbability(); - /*! \brief - * Makes the histograms cumulative by summing up each bin to all bins - * after it. - * - * The X values in the data are adjusted such that they match the right - * edges of bins instead of bin centers. - */ - void makeCumulative(); - //! Scales a single histogram by a uniform scaling factor. - void scaleSingle(int index, real factor); - //! Scales all histograms by a uniform scaling factor. - void scaleAll(real factor); - //! Scales the value of each bin by a different scaling factor. - void scaleAllByVector(const real factor[]); - /*! \brief - * Notifies attached modules of the histogram data. - * - * After this function has been called, it is no longer possible to - * alter the histogram. - */ - void done() { AbstractAnalysisArrayData::valuesReady(); } - - protected: - /*! \brief - * Creates a histogram module with undefined bins. - * - * Bin parameters must be defined with init() before data input is - * started. - */ - AbstractAverageHistogram(); - //! Creates a histogram module with defined bin parameters. - explicit AbstractAverageHistogram(const AnalysisHistogramSettings &settings); - - /*! \brief - * (Re)initializes the histogram from settings. - */ - void init(const AnalysisHistogramSettings &settings); - - private: - AnalysisHistogramSettings settings_; - - // Copy and assign disallowed by base. +public: + ~AbstractAverageHistogram() override; + + //! Returns bin properties for the histogram. + const AnalysisHistogramSettings& settings() const { return settings_; } + + /*! \brief + * Creates a copy of the histogram with double the bin width. + * + * \param[in] bIntegerBins If `true`, the first bin in the result will + * cover the first bin from the source. Otherwise, the first bin + * will cover first two bins from the source. + * \throws std::bad_alloc if out of memory. + * + * The caller is responsible of deleting the returned object. + */ + AverageHistogramPointer resampleDoubleBinWidth(bool bIntegerBins) const; + /*! \brief + * Creates a deep copy of the histogram. + * + * \throws std::bad_alloc if out of memory. + * + * The returned histogram is not necessarily of the same dynamic type + * as the original object, but contains the same data from the point of + * view of the AbstractAverageHistogram interface. + * + * The caller is responsible of deleting the returned object. + */ + AverageHistogramPointer clone() const; + //! Normalizes the histogram such that the integral over it is one. + void normalizeProbability(); + /*! \brief + * Makes the histograms cumulative by summing up each bin to all bins + * after it. + * + * The X values in the data are adjusted such that they match the right + * edges of bins instead of bin centers. + */ + void makeCumulative(); + //! Scales a single histogram by a uniform scaling factor. + void scaleSingle(int index, real factor); + //! Scales all histograms by a uniform scaling factor. + void scaleAll(real factor); + //! Scales the value of each bin by a different scaling factor. + void scaleAllByVector(const real factor[]); + /*! \brief + * Notifies attached modules of the histogram data. + * + * After this function has been called, it is no longer possible to + * alter the histogram. + */ + void done() { AbstractAnalysisArrayData::valuesReady(); } + +protected: + /*! \brief + * Creates a histogram module with undefined bins. + * + * Bin parameters must be defined with init() before data input is + * started. + */ + AbstractAverageHistogram(); + //! Creates a histogram module with defined bin parameters. + explicit AbstractAverageHistogram(const AnalysisHistogramSettings& settings); + + /*! \brief + * (Re)initializes the histogram from settings. + */ + void init(const AnalysisHistogramSettings& settings); + +private: + AnalysisHistogramSettings settings_; + + // Copy and assign disallowed by base. }; @@ -356,61 +375,58 @@ class AbstractAverageHistogram : public AbstractAnalysisArrayData * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataSimpleHistogramModule : public AbstractAnalysisData, - public AnalysisDataModuleParallel +class AnalysisDataSimpleHistogramModule : public AbstractAnalysisData, public AnalysisDataModuleParallel { - public: - /*! \brief - * Creates a histogram module with undefined bins. - * - * Bin parameters must be defined with init() before data input is - * started. - */ - AnalysisDataSimpleHistogramModule(); - //! Creates a histogram module with defined bin parameters. - explicit AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &settings); - ~AnalysisDataSimpleHistogramModule() override; - - /*! \brief - * (Re)initializes the histogram from settings. - */ - void init(const AnalysisHistogramSettings &settings); - - /*! \brief - * Returns the average histogram over all frames. - * - * Can be called already before the histogram is calculated to - * customize the way the average histogram is calculated. - * - * \see AbstractAverageHistogram - */ - AbstractAverageHistogram &averager(); - - //! Returns bin properties for the histogram. - const AnalysisHistogramSettings &settings() const; - - int frameCount() const override; - - int flags() const override; - - bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void frameFinishedSerial(int frameIndex) override; - void dataFinished() override; - - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; - - class Impl; - - PrivateImplPointer impl_; - - // Copy and assign disallowed by base. +public: + /*! \brief + * Creates a histogram module with undefined bins. + * + * Bin parameters must be defined with init() before data input is + * started. + */ + AnalysisDataSimpleHistogramModule(); + //! Creates a histogram module with defined bin parameters. + explicit AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings& settings); + ~AnalysisDataSimpleHistogramModule() override; + + /*! \brief + * (Re)initializes the histogram from settings. + */ + void init(const AnalysisHistogramSettings& settings); + + /*! \brief + * Returns the average histogram over all frames. + * + * Can be called already before the histogram is calculated to + * customize the way the average histogram is calculated. + * + * \see AbstractAverageHistogram + */ + AbstractAverageHistogram& averager(); + + //! Returns bin properties for the histogram. + const AnalysisHistogramSettings& settings() const; + + int frameCount() const override; + + int flags() const override; + + bool parallelDataStarted(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void frameFinishedSerial(int frameIndex) override; + void dataFinished() override; + +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; + + class Impl; + + PrivateImplPointer impl_; + + // Copy and assign disallowed by base. }; @@ -435,47 +451,44 @@ class AnalysisDataSimpleHistogramModule : public AbstractAnalysisData, * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataWeightedHistogramModule : public AbstractAnalysisData, - public AnalysisDataModuleParallel +class AnalysisDataWeightedHistogramModule : public AbstractAnalysisData, public AnalysisDataModuleParallel { - public: - //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() - AnalysisDataWeightedHistogramModule(); - //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &) - explicit AnalysisDataWeightedHistogramModule(const AnalysisHistogramSettings &settings); - ~AnalysisDataWeightedHistogramModule() override; +public: + //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() + AnalysisDataWeightedHistogramModule(); + //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &) + explicit AnalysisDataWeightedHistogramModule(const AnalysisHistogramSettings& settings); + ~AnalysisDataWeightedHistogramModule() override; - //! \copydoc AnalysisDataSimpleHistogramModule::init() - void init(const AnalysisHistogramSettings &settings); + //! \copydoc AnalysisDataSimpleHistogramModule::init() + void init(const AnalysisHistogramSettings& settings); - //! \copydoc AnalysisDataSimpleHistogramModule::averager() - AbstractAverageHistogram &averager(); + //! \copydoc AnalysisDataSimpleHistogramModule::averager() + AbstractAverageHistogram& averager(); - //! \copydoc AnalysisDataSimpleHistogramModule::settings() - const AnalysisHistogramSettings &settings() const; + //! \copydoc AnalysisDataSimpleHistogramModule::settings() + const AnalysisHistogramSettings& settings() const; - int frameCount() const override; + int frameCount() const override; - int flags() const override; + int flags() const override; - bool parallelDataStarted( - AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void frameFinishedSerial(int frameIndex) override; - void dataFinished() override; + bool parallelDataStarted(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void frameFinishedSerial(int frameIndex) override; + void dataFinished() override; - private: - AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; - bool requestStorageInternal(int nframes) override; +private: + AnalysisDataFrameRef tryGetDataFrameInternal(int index) const override; + bool requestStorageInternal(int nframes) override; - class Impl; + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; @@ -495,47 +508,43 @@ class AnalysisDataWeightedHistogramModule : public AbstractAnalysisData, * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataBinAverageModule : public AbstractAnalysisArrayData, - public AnalysisDataModuleSerial +class AnalysisDataBinAverageModule : public AbstractAnalysisArrayData, public AnalysisDataModuleSerial { - public: - //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() - AnalysisDataBinAverageModule(); - //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &) - explicit AnalysisDataBinAverageModule(const AnalysisHistogramSettings &settings); - ~AnalysisDataBinAverageModule() override; +public: + //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule() + AnalysisDataBinAverageModule(); + //! \copydoc AnalysisDataSimpleHistogramModule::AnalysisDataSimpleHistogramModule(const AnalysisHistogramSettings &) + explicit AnalysisDataBinAverageModule(const AnalysisHistogramSettings& settings); + ~AnalysisDataBinAverageModule() override; - //! \copydoc AnalysisDataSimpleHistogramModule::init() - void init(const AnalysisHistogramSettings &settings); + //! \copydoc AnalysisDataSimpleHistogramModule::init() + void init(const AnalysisHistogramSettings& settings); - //! \copydoc AnalysisDataSimpleHistogramModule::settings() - const AnalysisHistogramSettings &settings() const; + //! \copydoc AnalysisDataSimpleHistogramModule::settings() + const AnalysisHistogramSettings& settings() const; - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; //! Smart pointer to manage an AnalysisDataSimpleHistogramModule object. -typedef std::shared_ptr - AnalysisDataSimpleHistogramModulePointer; +typedef std::shared_ptr AnalysisDataSimpleHistogramModulePointer; //! Smart pointer to manage an AnalysisDataWeightedHistogramModule object. -typedef std::shared_ptr - AnalysisDataWeightedHistogramModulePointer; +typedef std::shared_ptr AnalysisDataWeightedHistogramModulePointer; //! Smart pointer to manage an AnalysisDataBinAverageModule object. -typedef std::shared_ptr - AnalysisDataBinAverageModulePointer; +typedef std::shared_ptr AnalysisDataBinAverageModulePointer; } // namespace gmx diff --git a/src/gromacs/analysisdata/modules/lifetime.cpp b/src/gromacs/analysisdata/modules/lifetime.cpp index 6249e8c2be..5c9727ce79 100644 --- a/src/gromacs/analysisdata/modules/lifetime.cpp +++ b/src/gromacs/analysisdata/modules/lifetime.cpp @@ -66,64 +66,57 @@ namespace gmx */ class AnalysisDataLifetimeModule::Impl { - public: - //! Container type for storing a histogram during the calculation. - typedef std::deque LifetimeHistogram; +public: + //! Container type for storing a histogram during the calculation. + typedef std::deque LifetimeHistogram; - //! Initializes the implementation class with empty/default values. - Impl() : firstx_(0.0), lastx_(0.0), frameCount_(0), bCumulative_(false) - { - } + //! Initializes the implementation class with empty/default values. + Impl() : firstx_(0.0), lastx_(0.0), frameCount_(0), bCumulative_(false) {} - /*! \brief - * Increments a lifetime histogram with a single lifetime. - * - * \param[in] dataSet Index of the histogram to increment. - * \param[in] lifetime Lifetime to add to the histogram. - */ - void addLifetime(int dataSet, int lifetime) + /*! \brief + * Increments a lifetime histogram with a single lifetime. + * + * \param[in] dataSet Index of the histogram to increment. + * \param[in] lifetime Lifetime to add to the histogram. + */ + void addLifetime(int dataSet, int lifetime) + { + if (lifetime > 0) { - if (lifetime > 0) + LifetimeHistogram& histogram = lifetimeHistograms_[dataSet]; + if (histogram.size() < static_cast(lifetime)) { - LifetimeHistogram &histogram = lifetimeHistograms_[dataSet]; - if (histogram.size() < static_cast(lifetime)) - { - histogram.resize(lifetime, 0); - } - ++histogram[lifetime - 1]; + histogram.resize(lifetime, 0); } + ++histogram[lifetime - 1]; } + } - //! X value of the first frame (used for determining output spacing). - real firstx_; - //! X value of the last frame (used for determining output spacing). - real lastx_; - //! Total number of frames (used for normalization and output spacing). - int frameCount_; - //! Whether to add subintervals of longer intervals explicitly. - bool bCumulative_; - /*! \brief - * Length of current continuously present interval for each data column. - * - * While frame N has been processed, stores the length of an interval - * for each data column where that column has been continuously present - * up to and including frame N. - */ - std::vector > currentLifetimes_; - /*! \brief - * Accumulated lifetime histograms for each data set. - */ - std::vector lifetimeHistograms_; + //! X value of the first frame (used for determining output spacing). + real firstx_; + //! X value of the last frame (used for determining output spacing). + real lastx_; + //! Total number of frames (used for normalization and output spacing). + int frameCount_; + //! Whether to add subintervals of longer intervals explicitly. + bool bCumulative_; + /*! \brief + * Length of current continuously present interval for each data column. + * + * While frame N has been processed, stores the length of an interval + * for each data column where that column has been continuously present + * up to and including frame N. + */ + std::vector> currentLifetimes_; + /*! \brief + * Accumulated lifetime histograms for each data set. + */ + std::vector lifetimeHistograms_; }; -AnalysisDataLifetimeModule::AnalysisDataLifetimeModule() - : impl_(new Impl()) -{ -} +AnalysisDataLifetimeModule::AnalysisDataLifetimeModule() : impl_(new Impl()) {} -AnalysisDataLifetimeModule::~AnalysisDataLifetimeModule() -{ -} +AnalysisDataLifetimeModule::~AnalysisDataLifetimeModule() {} void AnalysisDataLifetimeModule::setCumulative(bool bCumulative) { @@ -135,8 +128,7 @@ int AnalysisDataLifetimeModule::flags() const return efAllowMulticolumn | efAllowMissing | efAllowMultipleDataSets; } -void -AnalysisDataLifetimeModule::dataStarted(AbstractAnalysisData *data) +void AnalysisDataLifetimeModule::dataStarted(AbstractAnalysisData* data) { impl_->currentLifetimes_.reserve(data->dataSetCount()); impl_->lifetimeHistograms_.reserve(data->dataSetCount()); @@ -147,8 +139,7 @@ AnalysisDataLifetimeModule::dataStarted(AbstractAnalysisData *data) } } -void -AnalysisDataLifetimeModule::frameStarted(const AnalysisDataFrameHeader &header) +void AnalysisDataLifetimeModule::frameStarted(const AnalysisDataFrameHeader& header) { if (header.index() == 0) { @@ -159,14 +150,13 @@ AnalysisDataLifetimeModule::frameStarted(const AnalysisDataFrameHeader &header) // TODO: Check the input for even spacing. } -void -AnalysisDataLifetimeModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataLifetimeModule::pointsAdded(const AnalysisDataPointSetRef& points) { const int dataSet = points.dataSetIndex(); // This assumption is strictly not necessary, but this is how the // framework works currently, and makes the code below simpler. GMX_ASSERT(points.firstColumn() == 0 - && points.lastColumn() == ssize(impl_->currentLifetimes_[dataSet]) - 1, + && points.lastColumn() == ssize(impl_->currentLifetimes_[dataSet]) - 1, "Point set should cover all columns"); for (int i = 0; i < points.columnCount(); ++i) { @@ -184,13 +174,9 @@ AnalysisDataLifetimeModule::pointsAdded(const AnalysisDataPointSetRef &points) } } -void -AnalysisDataLifetimeModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) -{ -} +void AnalysisDataLifetimeModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {} -void -AnalysisDataLifetimeModule::dataFinished() +void AnalysisDataLifetimeModule::dataFinished() { // Need to process the elements present in the last frame explicitly. for (size_t i = 0; i < impl_->currentLifetimes_.size(); ++i) @@ -207,16 +193,14 @@ AnalysisDataLifetimeModule::dataFinished() // Sum up subintervals of longer intervals into the histograms // if explicitly requested. std::vector::iterator histogram; - for (histogram = impl_->lifetimeHistograms_.begin(); - histogram != impl_->lifetimeHistograms_.end(); - ++histogram) + for (histogram = impl_->lifetimeHistograms_.begin(); + histogram != impl_->lifetimeHistograms_.end(); ++histogram) { Impl::LifetimeHistogram::iterator shorter, longer; for (shorter = histogram->begin(); shorter != histogram->end(); ++shorter) { int subIntervalCount = 2; - for (longer = shorter + 1; longer != histogram->end(); - ++longer, ++subIntervalCount) + for (longer = shorter + 1; longer != histogram->end(); ++longer, ++subIntervalCount) { // Interval of length shorter contains (longer - shorter + 1) // continuous intervals of length longer. @@ -229,18 +213,15 @@ AnalysisDataLifetimeModule::dataFinished() // X spacing is determined by averaging from the first and last frame // instead of first two frames to avoid rounding issues. const real spacing = - (impl_->frameCount_ > 1) - ? (impl_->lastx_ - impl_->firstx_) / (impl_->frameCount_ - 1) - : 0.0; + (impl_->frameCount_ > 1) ? (impl_->lastx_ - impl_->firstx_) / (impl_->frameCount_ - 1) : 0.0; setXAxis(0.0, spacing); // Determine output dimensionality to cover all the histograms. setColumnCount(impl_->lifetimeHistograms_.size()); std::vector::const_iterator histogram; - size_t maxLifetime = 1; - for (histogram = impl_->lifetimeHistograms_.begin(); - histogram != impl_->lifetimeHistograms_.end(); - ++histogram) + size_t maxLifetime = 1; + for (histogram = impl_->lifetimeHistograms_.begin(); + histogram != impl_->lifetimeHistograms_.end(); ++histogram) { maxLifetime = std::max(maxLifetime, histogram->size()); } @@ -249,11 +230,10 @@ AnalysisDataLifetimeModule::dataFinished() // Fill up the output data from the histograms. allocateValues(); int column = 0; - for (histogram = impl_->lifetimeHistograms_.begin(); - histogram != impl_->lifetimeHistograms_.end(); - ++histogram, ++column) + for (histogram = impl_->lifetimeHistograms_.begin(); + histogram != impl_->lifetimeHistograms_.end(); ++histogram, ++column) { - int row = 0; + int row = 0; Impl::LifetimeHistogram::const_iterator i; for (i = histogram->begin(); i != histogram->end(); ++i, ++row) { diff --git a/src/gromacs/analysisdata/modules/lifetime.h b/src/gromacs/analysisdata/modules/lifetime.h index 0e34c4583e..ede0b25bab 100644 --- a/src/gromacs/analysisdata/modules/lifetime.h +++ b/src/gromacs/analysisdata/modules/lifetime.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,40 +75,38 @@ namespace gmx * \inpublicapi * \ingroup module_analysisdata */ -class AnalysisDataLifetimeModule : public AbstractAnalysisArrayData, - public AnalysisDataModuleSerial +class AnalysisDataLifetimeModule : public AbstractAnalysisArrayData, public AnalysisDataModuleSerial { - public: - AnalysisDataLifetimeModule(); - ~AnalysisDataLifetimeModule() override; +public: + AnalysisDataLifetimeModule(); + ~AnalysisDataLifetimeModule() override; - /*! \brief - * Sets a cumulative histogram mode. - * - * \param[in] bCumulative If true, all subintervals of a long - * interval are also explicitly added into the histogram. - * - * Does not throw. - */ - void setCumulative(bool bCumulative); + /*! \brief + * Sets a cumulative histogram mode. + * + * \param[in] bCumulative If true, all subintervals of a long + * interval are also explicitly added into the histogram. + * + * Does not throw. + */ + void setCumulative(bool bCumulative); - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; //! Smart pointer to manage an AnalysisDataLifetimeModule object. -typedef std::shared_ptr - AnalysisDataLifetimeModulePointer; +typedef std::shared_ptr AnalysisDataLifetimeModulePointer; } // namespace gmx diff --git a/src/gromacs/analysisdata/modules/plot.cpp b/src/gromacs/analysisdata/modules/plot.cpp index 25eccc9bd4..8227e4aee8 100644 --- a/src/gromacs/analysisdata/modules/plot.cpp +++ b/src/gromacs/analysisdata/modules/plot.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,9 +69,7 @@ namespace { //! Enum values for plot formats. -const char *const g_plotFormats[] = { - "none", "xmgrace", "xmgr" -}; +const char* const g_plotFormats[] = { "none", "xmgrace", "xmgr" }; } // namespace @@ -81,24 +80,23 @@ namespace gmx * AnalysisDataPlotSettings */ -AnalysisDataPlotSettings::AnalysisDataPlotSettings() - : selections_(nullptr), timeUnit_(TimeUnit_Default), plotFormat_(1) +AnalysisDataPlotSettings::AnalysisDataPlotSettings() : + selections_(nullptr), + timeUnit_(TimeUnit_Default), + plotFormat_(1) { } -void -AnalysisDataPlotSettings::setSelectionCollection(const SelectionCollection *selections) +void AnalysisDataPlotSettings::setSelectionCollection(const SelectionCollection* selections) { selections_ = selections; } -void -AnalysisDataPlotSettings::initOptions(IOptionsContainer *options) +void AnalysisDataPlotSettings::initOptions(IOptionsContainer* options) { - options->addOption(EnumIntOption("xvg").enumValue(g_plotFormats) - .store(&plotFormat_) - .description("Plot formatting")); + options->addOption( + EnumIntOption("xvg").enumValue(g_plotFormats).store(&plotFormat_).description("Plot formatting")); } @@ -108,33 +106,38 @@ AnalysisDataPlotSettings::initOptions(IOptionsContainer *options) class AbstractPlotModule::Impl { - public: - explicit Impl(const AnalysisDataPlotSettings &settings); - ~Impl(); - - void closeFile(); - - AnalysisDataPlotSettings settings_; - std::string filename_; - FILE *fp_; - - bool bPlain_; - bool bOmitX_; - bool bErrorsAsSeparateColumn_; - std::string title_; - std::string subtitle_; - std::string xlabel_; - std::string ylabel_; - std::vector legend_; - std::string xformat_; - std::string yformat_; - real xscale_; +public: + explicit Impl(const AnalysisDataPlotSettings& settings); + ~Impl(); + + void closeFile(); + + AnalysisDataPlotSettings settings_; + std::string filename_; + FILE* fp_; + + bool bPlain_; + bool bOmitX_; + bool bErrorsAsSeparateColumn_; + std::string title_; + std::string subtitle_; + std::string xlabel_; + std::string ylabel_; + std::vector legend_; + std::string xformat_; + std::string yformat_; + real xscale_; }; -AbstractPlotModule::Impl::Impl(const AnalysisDataPlotSettings &settings) - : settings_(settings), fp_(nullptr), bPlain_(false), bOmitX_(false), - bErrorsAsSeparateColumn_(false), - xformat_("%11.3f"), yformat_(" %8.3f"), xscale_(1.0) +AbstractPlotModule::Impl::Impl(const AnalysisDataPlotSettings& settings) : + settings_(settings), + fp_(nullptr), + bPlain_(false), + bOmitX_(false), + bErrorsAsSeparateColumn_(false), + xformat_("%11.3f"), + yformat_(" %8.3f"), + xscale_(1.0) { } @@ -144,8 +147,7 @@ AbstractPlotModule::Impl::~Impl() } -void -AbstractPlotModule::Impl::closeFile() +void AbstractPlotModule::Impl::closeFile() { if (fp_ != nullptr) { @@ -166,93 +168,77 @@ AbstractPlotModule::Impl::closeFile() * AbstractPlotModule */ /*! \cond libapi */ -AbstractPlotModule::AbstractPlotModule() - : impl_(new Impl(AnalysisDataPlotSettings())) -{ -} +AbstractPlotModule::AbstractPlotModule() : impl_(new Impl(AnalysisDataPlotSettings())) {} -AbstractPlotModule::AbstractPlotModule(const AnalysisDataPlotSettings &settings) - : impl_(new Impl(settings)) +AbstractPlotModule::AbstractPlotModule(const AnalysisDataPlotSettings& settings) : + impl_(new Impl(settings)) { } //! \endcond -AbstractPlotModule::~AbstractPlotModule() -{ -} +AbstractPlotModule::~AbstractPlotModule() {} -void -AbstractPlotModule::setSettings(const AnalysisDataPlotSettings &settings) +void AbstractPlotModule::setSettings(const AnalysisDataPlotSettings& settings) { impl_->settings_ = settings; } -void -AbstractPlotModule::setFileName(const std::string &filename) +void AbstractPlotModule::setFileName(const std::string& filename) { impl_->filename_ = filename; } -void -AbstractPlotModule::setPlainOutput(bool bPlain) +void AbstractPlotModule::setPlainOutput(bool bPlain) { impl_->bPlain_ = bPlain; } -void -AbstractPlotModule::setErrorsAsSeparateColumn(bool bSeparate) +void AbstractPlotModule::setErrorsAsSeparateColumn(bool bSeparate) { impl_->bErrorsAsSeparateColumn_ = bSeparate; } -void -AbstractPlotModule::setOmitX(bool bOmitX) +void AbstractPlotModule::setOmitX(bool bOmitX) { impl_->bOmitX_ = bOmitX; } -void -AbstractPlotModule::setTitle(const char *title) +void AbstractPlotModule::setTitle(const char* title) { impl_->title_ = title; } -void -AbstractPlotModule::setTitle(const std::string &title) +void AbstractPlotModule::setTitle(const std::string& title) { impl_->title_ = title; } -void -AbstractPlotModule::setSubtitle(const char *subtitle) +void AbstractPlotModule::setSubtitle(const char* subtitle) { impl_->subtitle_ = subtitle; } -void -AbstractPlotModule::setSubtitle(const std::string &subtitle) +void AbstractPlotModule::setSubtitle(const std::string& subtitle) { impl_->subtitle_ = subtitle; } -void -AbstractPlotModule::setXLabel(const char *label) +void AbstractPlotModule::setXLabel(const char* label) { impl_->xlabel_ = label; } -void -AbstractPlotModule::setXAxisIsTime() +void AbstractPlotModule::setXAxisIsTime() { TimeUnitManager manager(impl_->settings_.timeUnit()); impl_->xlabel_ = formatString("Time (%s)", manager.timeUnitAsString()); @@ -260,15 +246,13 @@ AbstractPlotModule::setXAxisIsTime() } -void -AbstractPlotModule::setYLabel(const char *label) +void AbstractPlotModule::setYLabel(const char* label) { impl_->ylabel_ = label; } -void -AbstractPlotModule::setLegend(int nsets, const char * const *setname) +void AbstractPlotModule::setLegend(int nsets, const char* const* setname) { impl_->legend_.reserve(impl_->legend_.size() + nsets); for (int i = 0; i < nsets; ++i) @@ -278,54 +262,43 @@ AbstractPlotModule::setLegend(int nsets, const char * const *setname) } -void -AbstractPlotModule::appendLegend(const char *setname) +void AbstractPlotModule::appendLegend(const char* setname) { impl_->legend_.emplace_back(setname); } -void -AbstractPlotModule::appendLegend(const std::string &setname) +void AbstractPlotModule::appendLegend(const std::string& setname) { impl_->legend_.push_back(setname); } -void -AbstractPlotModule::setXFormat(int width, int precision, char format) +void AbstractPlotModule::setXFormat(int width, int precision, char format) { - GMX_RELEASE_ASSERT(width >= 0 && precision >= 0 - && width <= 99 && precision <= 99, + GMX_RELEASE_ASSERT(width >= 0 && precision >= 0 && width <= 99 && precision <= 99, "Invalid width or precision"); - GMX_RELEASE_ASSERT(strchr("eEfFgG", format) != nullptr, - "Invalid format specifier"); + GMX_RELEASE_ASSERT(strchr("eEfFgG", format) != nullptr, "Invalid format specifier"); impl_->xformat_ = formatString("%%%d.%d%c", width, precision, format); } -void -AbstractPlotModule::setYFormat(int width, int precision, char format) +void AbstractPlotModule::setYFormat(int width, int precision, char format) { - GMX_RELEASE_ASSERT(width >= 0 && precision >= 0 - && width <= 99 && precision <= 99, + GMX_RELEASE_ASSERT(width >= 0 && precision >= 0 && width <= 99 && precision <= 99, "Invalid width or precision"); - GMX_RELEASE_ASSERT(strchr("eEfFgG", format) != nullptr, - "Invalid format specifier"); + GMX_RELEASE_ASSERT(strchr("eEfFgG", format) != nullptr, "Invalid format specifier"); impl_->yformat_ = formatString(" %%%d.%d%c", width, precision, format); } -int -AbstractPlotModule::flags() const +int AbstractPlotModule::flags() const { - return efAllowMissing | efAllowMulticolumn | efAllowMultipoint - | efAllowMultipleDataSets; + return efAllowMissing | efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets; } -void -AbstractPlotModule::dataStarted(AbstractAnalysisData * /* data */) +void AbstractPlotModule::dataStarted(AbstractAnalysisData* /* data */) { if (!impl_->filename_.empty()) { @@ -335,20 +308,17 @@ AbstractPlotModule::dataStarted(AbstractAnalysisData * /* data */) } else { - time_unit_t time_unit - = static_cast(impl_->settings_.timeUnit() + 1); // NOLINT(bugprone-misplaced-widening-cast) - xvg_format_t xvg_format - = (impl_->settings_.plotFormat() > 0 - ? static_cast(impl_->settings_.plotFormat()) - : exvgNONE); - gmx_output_env_t *oenv; + time_unit_t time_unit = static_cast( + impl_->settings_.timeUnit() + 1); // NOLINT(bugprone-misplaced-widening-cast) + xvg_format_t xvg_format = (impl_->settings_.plotFormat() > 0 + ? static_cast(impl_->settings_.plotFormat()) + : exvgNONE); + gmx_output_env_t* oenv; output_env_init(&oenv, getProgramContext(), time_unit, FALSE, xvg_format, 0); const unique_cptr oenvGuard(oenv); - impl_->fp_ = xvgropen(impl_->filename_.c_str(), impl_->title_.c_str(), - impl_->xlabel_, impl_->ylabel_, - oenv); - const SelectionCollection *selections - = impl_->settings_.selectionCollection(); + impl_->fp_ = xvgropen(impl_->filename_.c_str(), impl_->title_.c_str(), impl_->xlabel_, + impl_->ylabel_, oenv); + const SelectionCollection* selections = impl_->settings_.selectionCollection(); if (selections != nullptr && output_env_get_xvg_format(oenv) != exvgNONE) { selections->printXvgrInfo(impl_->fp_); @@ -357,10 +327,9 @@ AbstractPlotModule::dataStarted(AbstractAnalysisData * /* data */) { xvgr_subtitle(impl_->fp_, impl_->subtitle_.c_str(), oenv); } - if (output_env_get_print_xvgr_codes(oenv) - && !impl_->legend_.empty()) + if (output_env_get_print_xvgr_codes(oenv) && !impl_->legend_.empty()) { - std::vector legend; + std::vector legend; legend.reserve(impl_->legend_.size()); for (size_t i = 0; i < impl_->legend_.size(); ++i) { @@ -373,8 +342,7 @@ AbstractPlotModule::dataStarted(AbstractAnalysisData * /* data */) } -void -AbstractPlotModule::frameStarted(const AnalysisDataFrameHeader &header) +void AbstractPlotModule::frameStarted(const AnalysisDataFrameHeader& header) { if (!isFileOpen()) { @@ -387,8 +355,7 @@ AbstractPlotModule::frameStarted(const AnalysisDataFrameHeader &header) } -void -AbstractPlotModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) +void AbstractPlotModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) { if (!isFileOpen()) { @@ -398,22 +365,19 @@ AbstractPlotModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) } -void -AbstractPlotModule::dataFinished() +void AbstractPlotModule::dataFinished() { impl_->closeFile(); } /*! \cond libapi */ -bool -AbstractPlotModule::isFileOpen() const +bool AbstractPlotModule::isFileOpen() const { return impl_->fp_ != nullptr; } -void -AbstractPlotModule::writeValue(const AnalysisDataValue &value) const +void AbstractPlotModule::writeValue(const AnalysisDataValue& value) const { GMX_ASSERT(isFileOpen(), "File not opened, but write attempted"); const real y = value.isSet() ? value.value() : 0.0; @@ -430,19 +394,15 @@ AbstractPlotModule::writeValue(const AnalysisDataValue &value) const * DataPlotModule */ -AnalysisDataPlotModule::AnalysisDataPlotModule() -{ -} +AnalysisDataPlotModule::AnalysisDataPlotModule() {} -AnalysisDataPlotModule::AnalysisDataPlotModule( - const AnalysisDataPlotSettings &settings) - : AbstractPlotModule(settings) +AnalysisDataPlotModule::AnalysisDataPlotModule(const AnalysisDataPlotSettings& settings) : + AbstractPlotModule(settings) { } -void -AnalysisDataPlotModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataPlotModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (!isFileOpen()) { @@ -459,50 +419,41 @@ AnalysisDataPlotModule::pointsAdded(const AnalysisDataPointSetRef &points) * DataVectorPlotModule */ -AnalysisDataVectorPlotModule::AnalysisDataVectorPlotModule() - : bWrite_ {true, true, true, false} -{ -} +AnalysisDataVectorPlotModule::AnalysisDataVectorPlotModule() : bWrite_{ true, true, true, false } {} -AnalysisDataVectorPlotModule::AnalysisDataVectorPlotModule( - const AnalysisDataPlotSettings &settings) - : AbstractPlotModule(settings), - bWrite_ {true, true, true, false} +AnalysisDataVectorPlotModule::AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings& settings) : + AbstractPlotModule(settings), + bWrite_{ true, true, true, false } { } -void -AnalysisDataVectorPlotModule::setWriteX(bool bWrite) +void AnalysisDataVectorPlotModule::setWriteX(bool bWrite) { bWrite_[XX] = bWrite; } -void -AnalysisDataVectorPlotModule::setWriteY(bool bWrite) +void AnalysisDataVectorPlotModule::setWriteY(bool bWrite) { bWrite_[YY] = bWrite; } -void -AnalysisDataVectorPlotModule::setWriteZ(bool bWrite) +void AnalysisDataVectorPlotModule::setWriteZ(bool bWrite) { bWrite_[ZZ] = bWrite; } -void -AnalysisDataVectorPlotModule::setWriteNorm(bool bWrite) +void AnalysisDataVectorPlotModule::setWriteNorm(bool bWrite) { bWrite_[DIM] = bWrite; } -void -AnalysisDataVectorPlotModule::setWriteMask(const bool bWrite[DIM + 1]) +void AnalysisDataVectorPlotModule::setWriteMask(const bool bWrite[DIM + 1]) { for (int i = 0; i < DIM + 1; ++i) { @@ -511,8 +462,7 @@ AnalysisDataVectorPlotModule::setWriteMask(const bool bWrite[DIM + 1]) } -void -AnalysisDataVectorPlotModule::pointsAdded(const AnalysisDataPointSetRef &points) +void AnalysisDataVectorPlotModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (points.firstColumn() % DIM != 0 || points.columnCount() % DIM != 0) { diff --git a/src/gromacs/analysisdata/modules/plot.h b/src/gromacs/analysisdata/modules/plot.h index d926224ddd..aa64b57279 100644 --- a/src/gromacs/analysisdata/modules/plot.h +++ b/src/gromacs/analysisdata/modules/plot.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,55 +65,52 @@ class SelectionCollection; */ class AnalysisDataPlotSettings { - public: - //! Constructs default analysis plot settings. - AnalysisDataPlotSettings(); +public: + //! Constructs default analysis plot settings. + AnalysisDataPlotSettings(); - //! Returns the selection collection set with setSelectionCollection(). - const SelectionCollection *selectionCollection() const - { - return selections_; - } - //! Returns the time unit set with setTimeUnit(). - TimeUnit timeUnit() const { return timeUnit_; } - /*! \brief - * Returns the plot format. - * - * \todo Use a proper enum. - */ - int plotFormat() const { return plotFormat_; } + //! Returns the selection collection set with setSelectionCollection(). + const SelectionCollection* selectionCollection() const { return selections_; } + //! Returns the time unit set with setTimeUnit(). + TimeUnit timeUnit() const { return timeUnit_; } + /*! \brief + * Returns the plot format. + * + * \todo Use a proper enum. + */ + int plotFormat() const { return plotFormat_; } - /*! \brief - * Set selection collection to print as comments into the output. - * - * Formatted selection text from all selections in \p selections is - * printed as comments in the output file. - * If this method is not called, no selection information is written - * to the output. - */ - void setSelectionCollection(const SelectionCollection *selections); - /*! \brief - * Sets the time unit for the plot. - * - * The value is used only if AbstractPlotModule::setXAxisIsTime() is - * called, in which case it is used to print the appropriate axis label - * and to scale the values. - * If not called, the default time unit is ps. - */ - void setTimeUnit(TimeUnit timeUnit) { timeUnit_ = timeUnit; } + /*! \brief + * Set selection collection to print as comments into the output. + * + * Formatted selection text from all selections in \p selections is + * printed as comments in the output file. + * If this method is not called, no selection information is written + * to the output. + */ + void setSelectionCollection(const SelectionCollection* selections); + /*! \brief + * Sets the time unit for the plot. + * + * The value is used only if AbstractPlotModule::setXAxisIsTime() is + * called, in which case it is used to print the appropriate axis label + * and to scale the values. + * If not called, the default time unit is ps. + */ + void setTimeUnit(TimeUnit timeUnit) { timeUnit_ = timeUnit; } - /*! \brief - * Adds common options for setting plot options. - * - * \param[in,out] options Options object to which options are added. - */ - void initOptions(IOptionsContainer *options); + /*! \brief + * Adds common options for setting plot options. + * + * \param[in,out] options Options object to which options are added. + */ + void initOptions(IOptionsContainer* options); - private: - const SelectionCollection *selections_; - TimeUnit timeUnit_; - int plotFormat_; +private: + const SelectionCollection* selections_; + TimeUnit timeUnit_; + int plotFormat_; }; /*! \brief @@ -141,122 +138,122 @@ class AnalysisDataPlotSettings */ class AbstractPlotModule : public AnalysisDataModuleSerial { - public: - ~AbstractPlotModule() override; +public: + ~AbstractPlotModule() override; - /*! \brief - * Set common settings for the plotting. - */ - void setSettings(const AnalysisDataPlotSettings &settings); - /*! \brief - * Set the output file name. - * - * If no file name is set (or if \p filename is empty), no output occurs. - */ - void setFileName(const std::string &filename); - /*! \brief - * Set plain output. - * - * If \p bPlain is true, no xvgr headers are written to the file. - * In this case, only setOmitX(), setXFormat(), and setYFormat() - * methods have any effect on the output. - */ - void setPlainOutput(bool bPlain); - /*! \brief - * Plot errors as a separate output column after each value column. - */ - void setErrorsAsSeparateColumn(bool bSeparate); - /*! \brief - * Omit the X coordinates from the output. - * - * This method only makes sense when combined with setPlainOutput(). - */ - void setOmitX(bool bOmitX); - /*! \brief - * Set plot title. - */ - void setTitle(const char *title); - //! \copydoc setTitle(const char *) - void setTitle(const std::string &title); - /*! \brief - * Set plot subtitle. - */ - void setSubtitle(const char *subtitle); - //! \copydoc setSubtitle(const char *) - void setSubtitle(const std::string &subtitle); - /*! \brief - * Set X axis label. - */ - void setXLabel(const char *label); - /*! \brief - * Treat X axis as time. - * - * Sets the label for the axis accordingly and also scales output to - * take into account the correct time unit. - */ - void setXAxisIsTime(); - /*! \brief - * Set Y axis label. - */ - void setYLabel(const char *label); - /*! \brief - * Add legend from an array of strings. - * - * Multiple calls to setLegend() and/or appendLegend() are added - * together. - */ - void setLegend(int nsets, const char * const *setname); - /*! \brief - * Add a legend string for the next data set. - * - * Multiple calls to setLegend() and/or appendLegend() are added - * together. - */ - void appendLegend(const char *setname); - //! \copydoc appendLegend(const char *) - void appendLegend(const std::string &setname); - /*! \brief - * Set field width and precision for X value output. - */ - void setXFormat(int width, int precision, char format = 'f'); - /*! \brief - * Set field width and precision for Y value output. - */ - void setYFormat(int width, int precision, char format = 'f'); + /*! \brief + * Set common settings for the plotting. + */ + void setSettings(const AnalysisDataPlotSettings& settings); + /*! \brief + * Set the output file name. + * + * If no file name is set (or if \p filename is empty), no output occurs. + */ + void setFileName(const std::string& filename); + /*! \brief + * Set plain output. + * + * If \p bPlain is true, no xvgr headers are written to the file. + * In this case, only setOmitX(), setXFormat(), and setYFormat() + * methods have any effect on the output. + */ + void setPlainOutput(bool bPlain); + /*! \brief + * Plot errors as a separate output column after each value column. + */ + void setErrorsAsSeparateColumn(bool bSeparate); + /*! \brief + * Omit the X coordinates from the output. + * + * This method only makes sense when combined with setPlainOutput(). + */ + void setOmitX(bool bOmitX); + /*! \brief + * Set plot title. + */ + void setTitle(const char* title); + //! \copydoc setTitle(const char *) + void setTitle(const std::string& title); + /*! \brief + * Set plot subtitle. + */ + void setSubtitle(const char* subtitle); + //! \copydoc setSubtitle(const char *) + void setSubtitle(const std::string& subtitle); + /*! \brief + * Set X axis label. + */ + void setXLabel(const char* label); + /*! \brief + * Treat X axis as time. + * + * Sets the label for the axis accordingly and also scales output to + * take into account the correct time unit. + */ + void setXAxisIsTime(); + /*! \brief + * Set Y axis label. + */ + void setYLabel(const char* label); + /*! \brief + * Add legend from an array of strings. + * + * Multiple calls to setLegend() and/or appendLegend() are added + * together. + */ + void setLegend(int nsets, const char* const* setname); + /*! \brief + * Add a legend string for the next data set. + * + * Multiple calls to setLegend() and/or appendLegend() are added + * together. + */ + void appendLegend(const char* setname); + //! \copydoc appendLegend(const char *) + void appendLegend(const std::string& setname); + /*! \brief + * Set field width and precision for X value output. + */ + void setXFormat(int width, int precision, char format = 'f'); + /*! \brief + * Set field width and precision for Y value output. + */ + void setYFormat(int width, int precision, char format = 'f'); - int flags() const override; + int flags() const override; - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override = 0; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override = 0; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; - protected: - /*! \cond libapi */ - AbstractPlotModule(); - //! Creates AbstractPlotModule and assign common settings. - explicit AbstractPlotModule(const AnalysisDataPlotSettings &settings); +protected: + /*! \cond libapi */ + AbstractPlotModule(); + //! Creates AbstractPlotModule and assign common settings. + explicit AbstractPlotModule(const AnalysisDataPlotSettings& settings); - //! Whether an output file has been opened. - bool isFileOpen() const; - /*! \brief - * Appends a single value to the current output line. - * - * \param[in] value Value to append. - * - * Should be used from pointsAdded() implementations in derived classes - * to write out individual y values to the output. - * - * Must not be called if isFileOpen() returns false. - */ - void writeValue(const AnalysisDataValue &value) const; - //! \endcond + //! Whether an output file has been opened. + bool isFileOpen() const; + /*! \brief + * Appends a single value to the current output line. + * + * \param[in] value Value to append. + * + * Should be used from pointsAdded() implementations in derived classes + * to write out individual y values to the output. + * + * Must not be called if isFileOpen() returns false. + */ + void writeValue(const AnalysisDataValue& value) const; + //! \endcond - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; @@ -270,14 +267,14 @@ class AbstractPlotModule : public AnalysisDataModuleSerial */ class AnalysisDataPlotModule : public AbstractPlotModule { - public: - AnalysisDataPlotModule(); - //! Creates AnalysisDataPlotModule and assign common settings. - explicit AnalysisDataPlotModule(const AnalysisDataPlotSettings &settings); +public: + AnalysisDataPlotModule(); + //! Creates AnalysisDataPlotModule and assign common settings. + explicit AnalysisDataPlotModule(const AnalysisDataPlotSettings& settings); - void pointsAdded(const AnalysisDataPointSetRef &points) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; @@ -291,46 +288,44 @@ class AnalysisDataPlotModule : public AbstractPlotModule */ class AnalysisDataVectorPlotModule : public AbstractPlotModule { - public: - AnalysisDataVectorPlotModule(); - //! Creates AnalysisDataVectorPlotModule and assign common settings. - explicit AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings &settings); +public: + AnalysisDataVectorPlotModule(); + //! Creates AnalysisDataVectorPlotModule and assign common settings. + explicit AnalysisDataVectorPlotModule(const AnalysisDataPlotSettings& settings); - /*! \brief - * Set whether to write X component. - */ - void setWriteX(bool bWrite); - /*! \brief - * Set whether to write Y component. - */ - void setWriteY(bool bWrite); - /*! \brief - * Set whether to write Z component. - */ - void setWriteZ(bool bWrite); - /*! \brief - * Set whether to write norm of the vector. - */ - void setWriteNorm(bool bWrite); - /*! \brief - * Set mask for what to write. - */ - void setWriteMask(const bool bWrite[4]); + /*! \brief + * Set whether to write X component. + */ + void setWriteX(bool bWrite); + /*! \brief + * Set whether to write Y component. + */ + void setWriteY(bool bWrite); + /*! \brief + * Set whether to write Z component. + */ + void setWriteZ(bool bWrite); + /*! \brief + * Set whether to write norm of the vector. + */ + void setWriteNorm(bool bWrite); + /*! \brief + * Set mask for what to write. + */ + void setWriteMask(const bool bWrite[4]); - void pointsAdded(const AnalysisDataPointSetRef &points) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; - private: - bool bWrite_[4]; +private: + bool bWrite_[4]; - // Copy and assign disallowed by base. + // Copy and assign disallowed by base. }; //! Smart pointer to manage an AnalysisDataPlotModule object. -typedef std::shared_ptr - AnalysisDataPlotModulePointer; +typedef std::shared_ptr AnalysisDataPlotModulePointer; //! Smart pointer to manage an AnalysisDataVectorPlotModule object. -typedef std::shared_ptr - AnalysisDataVectorPlotModulePointer; +typedef std::shared_ptr AnalysisDataVectorPlotModulePointer; } // namespace gmx diff --git a/src/gromacs/analysisdata/paralleloptions.h b/src/gromacs/analysisdata/paralleloptions.h index dcbd5c482d..83db181986 100644 --- a/src/gromacs/analysisdata/paralleloptions.h +++ b/src/gromacs/analysisdata/paralleloptions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012, by the GROMACS development team, led by + * Copyright (c) 2012,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,24 +60,24 @@ namespace gmx */ class AnalysisDataParallelOptions { - public: - //! Constructs options for serial execution. - AnalysisDataParallelOptions(); - /*! \brief - * Constructs options for parallel execution with given number of - * concurrent frames. - * - * \param[in] parallelizationFactor - * Number of frames that may be constructed concurrently. - * Must be >= 1. - */ - explicit AnalysisDataParallelOptions(int parallelizationFactor); +public: + //! Constructs options for serial execution. + AnalysisDataParallelOptions(); + /*! \brief + * Constructs options for parallel execution with given number of + * concurrent frames. + * + * \param[in] parallelizationFactor + * Number of frames that may be constructed concurrently. + * Must be >= 1. + */ + explicit AnalysisDataParallelOptions(int parallelizationFactor); - //! Returns the number of frames that may be constructed concurrently. - int parallelizationFactor() const { return parallelizationFactor_; } + //! Returns the number of frames that may be constructed concurrently. + int parallelizationFactor() const { return parallelizationFactor_; } - private: - int parallelizationFactor_; +private: + int parallelizationFactor_; }; } // namespace gmx diff --git a/src/gromacs/analysisdata/tests/analysisdata.cpp b/src/gromacs/analysisdata/tests/analysisdata.cpp index a6c412c749..30dba86a34 100644 --- a/src/gromacs/analysisdata/tests/analysisdata.cpp +++ b/src/gromacs/analysisdata/tests/analysisdata.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -151,138 +151,138 @@ TEST(AnalysisDataInitializationTest, ChecksMultipointModules) // Basic input data for gmx::AnalysisData tests. class SimpleInputData { - public: - static const AnalysisDataTestInput &get() - { -#ifndef STATIC_ANON_NAMESPACE_BUG - static SimpleInputData singleton; - return singleton.data_; -#else - static SimpleInputData singleton_analysisdata; - return singleton_analysisdata.data_; -#endif - } - - SimpleInputData() : data_(1, false) - { - data_.setColumnCount(0, 3); - data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); - data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); - data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); - } - - private: - AnalysisDataTestInput data_; +public: + static const AnalysisDataTestInput& get() + { +# ifndef STATIC_ANON_NAMESPACE_BUG + static SimpleInputData singleton; + return singleton.data_; +# else + static SimpleInputData singleton_analysisdata; + return singleton_analysisdata.data_; +# endif + } + + SimpleInputData() : data_(1, false) + { + data_.setColumnCount(0, 3); + data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); + data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); + data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); + } + +private: + AnalysisDataTestInput data_; }; // Input data with multiple data sets for gmx::AnalysisData tests. class DataSetsInputData { - public: - static const AnalysisDataTestInput &get() - { -#ifndef STATIC_ANON_NAMESPACE_BUG - static DataSetsInputData singleton; - return singleton.data_; -#else - static DataSetsInputData singleton_analysisdata; - return singleton_analysisdata.data_; -#endif - } - - DataSetsInputData() : data_(2, false) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 3); - data_.setColumnCount(1, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); - frame1.addPointSetWithValues(1, 0, 2.1, 1.1); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.0, 1.0, 1.0); - frame2.addPointSetWithValues(1, 0, 0.1, 2.1); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); - frame3.addPointSetWithValues(1, 0, 1.1, 1.1); - } - - private: - AnalysisDataTestInput data_; +public: + static const AnalysisDataTestInput& get() + { +# ifndef STATIC_ANON_NAMESPACE_BUG + static DataSetsInputData singleton; + return singleton.data_; +# else + static DataSetsInputData singleton_analysisdata; + return singleton_analysisdata.data_; +# endif + } + + DataSetsInputData() : data_(2, false) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 3); + data_.setColumnCount(1, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); + frame1.addPointSetWithValues(1, 0, 2.1, 1.1); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.0, 1.0, 1.0); + frame2.addPointSetWithValues(1, 0, 0.1, 2.1); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); + frame3.addPointSetWithValues(1, 0, 1.1, 1.1); + } + +private: + AnalysisDataTestInput data_; }; // Input data for multipoint gmx::AnalysisData tests. class MultipointInputData { - public: - static const AnalysisDataTestInput &get() - { -#ifndef STATIC_ANON_NAMESPACE_BUG - static MultipointInputData singleton; - return singleton.data_; -#else - static MultipointInputData singleton_analysisdata; - return singleton_analysisdata.data_; -#endif - } - - MultipointInputData() : data_(1, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 3); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); - frame1.addPointSetWithValues(0, 0, 1.1, 2.1, 1.1); - frame1.addPointSetWithValues(0, 0, 2.2, 1.2, 0.2); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 1, 1.0, 1.0); - frame2.addPointSetWithValues(0, 0, 2.1, 1.1, 0.1); - frame2.addPointSetWithValues(0, 2, 1.2); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); - frame3.addPointSetWithValues(0, 0, 3.1, 2.1); - frame3.addPointSetWithValues(0, 1, 2.2, 1.2); - } - - private: - AnalysisDataTestInput data_; +public: + static const AnalysisDataTestInput& get() + { +# ifndef STATIC_ANON_NAMESPACE_BUG + static MultipointInputData singleton; + return singleton.data_; +# else + static MultipointInputData singleton_analysisdata; + return singleton_analysisdata.data_; +# endif + } + + MultipointInputData() : data_(1, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 3); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); + frame1.addPointSetWithValues(0, 0, 1.1, 2.1, 1.1); + frame1.addPointSetWithValues(0, 0, 2.2, 1.2, 0.2); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 1, 1.0, 1.0); + frame2.addPointSetWithValues(0, 0, 2.1, 1.1, 0.1); + frame2.addPointSetWithValues(0, 2, 1.2); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); + frame3.addPointSetWithValues(0, 0, 3.1, 2.1); + frame3.addPointSetWithValues(0, 1, 2.2, 1.2); + } + +private: + AnalysisDataTestInput data_; }; // Input data with multiple multipoint data sets for gmx::AnalysisData tests. class MultipointDataSetsInputData { - public: - static const AnalysisDataTestInput &get() - { -#ifndef STATIC_ANON_NAMESPACE_BUG - static MultipointDataSetsInputData singleton; - return singleton.data_; -#else - static MultipointDataSetsInputData singleton_analysisdata; - return singleton_analysisdata.data_; -#endif - } - - MultipointDataSetsInputData() : data_(2, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 3); - data_.setColumnCount(1, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); - frame1.addPointSetWithValues(0, 1, 2.1, 1.1); - frame1.addPointSetWithValues(1, 0, 2.01, 1.01); - frame1.addPointSetWithValues(1, 1, 0.11); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.0, 1.0, 1.0); - frame2.addPointSetWithValues(0, 0, 0.1, 2.1); - frame2.addPointSetWithValues(1, 1, 1.01); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); - frame3.addPointSetWithValues(0, 1, 1.1); - } - - private: - AnalysisDataTestInput data_; +public: + static const AnalysisDataTestInput& get() + { +# ifndef STATIC_ANON_NAMESPACE_BUG + static MultipointDataSetsInputData singleton; + return singleton.data_; +# else + static MultipointDataSetsInputData singleton_analysisdata; + return singleton_analysisdata.data_; +# endif + } + + MultipointDataSetsInputData() : data_(2, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 3); + data_.setColumnCount(1, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); + frame1.addPointSetWithValues(0, 1, 2.1, 1.1); + frame1.addPointSetWithValues(1, 0, 2.01, 1.01); + frame1.addPointSetWithValues(1, 1, 0.11); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.0, 1.0, 1.0); + frame2.addPointSetWithValues(0, 0, 0.1, 2.1); + frame2.addPointSetWithValues(1, 1, 1.01); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); + frame3.addPointSetWithValues(0, 1, 1.1); + } + +private: + AnalysisDataTestInput data_; }; /******************************************************************** @@ -293,63 +293,46 @@ using gmx::test::AnalysisDataTestFixture; class AnalysisDataTest : public AnalysisDataTestFixture { - public: - explicit AnalysisDataTest(const AnalysisDataTestInput &input) - : input_(input) - { - } - - void SetUp() override - { - ASSERT_NO_THROW_GMX(setupDataObject(input_, &data_)); - } - - void addStaticCheckerModule() - { - AnalysisDataTestFixture::addStaticCheckerModule(input_, &data_); - } - void addStaticParallelCheckerModule() - { - AnalysisDataTestFixture::addStaticParallelCheckerModule(input_, &data_); - } - void addStaticColumnCheckerModule(int firstColumn, int columnCount) - { - AnalysisDataTestFixture::addStaticColumnCheckerModule( - input_, firstColumn, columnCount, &data_); - } - void addStaticStorageCheckerModule(int storageCount) - { - AnalysisDataTestFixture::addStaticStorageCheckerModule( - input_, storageCount, &data_); - } - void presentAllData() - { - AnalysisDataTestFixture::presentAllData(input_, &data_); - } - - const AnalysisDataTestInput &input_; - gmx::AnalysisData data_; +public: + explicit AnalysisDataTest(const AnalysisDataTestInput& input) : input_(input) {} + + void SetUp() override { ASSERT_NO_THROW_GMX(setupDataObject(input_, &data_)); } + + void addStaticCheckerModule() + { + AnalysisDataTestFixture::addStaticCheckerModule(input_, &data_); + } + void addStaticParallelCheckerModule() + { + AnalysisDataTestFixture::addStaticParallelCheckerModule(input_, &data_); + } + void addStaticColumnCheckerModule(int firstColumn, int columnCount) + { + AnalysisDataTestFixture::addStaticColumnCheckerModule(input_, firstColumn, columnCount, &data_); + } + void addStaticStorageCheckerModule(int storageCount) + { + AnalysisDataTestFixture::addStaticStorageCheckerModule(input_, storageCount, &data_); + } + void presentAllData() { AnalysisDataTestFixture::presentAllData(input_, &data_); } + + const AnalysisDataTestInput& input_; + gmx::AnalysisData data_; }; -template +template class AnalysisDataCommonTest : public AnalysisDataTest { - public: - AnalysisDataCommonTest() : AnalysisDataTest(InputDataType::get()) - { - } +public: + AnalysisDataCommonTest() : AnalysisDataTest(InputDataType::get()) {} }; //! Test fixture for tests that are only applicable to simple data. -typedef AnalysisDataCommonTest AnalysisDataSimpleTest; +typedef AnalysisDataCommonTest AnalysisDataSimpleTest; //! Test fixture for tests that are only applicable to multipoint data. typedef AnalysisDataCommonTest AnalysisDataMultipointTest; //! List of input data types for tests applicable to all types of data. -typedef ::testing::Types - AllInputDataTypes; +typedef ::testing::Types AllInputDataTypes; TYPED_TEST_CASE(AnalysisDataCommonTest, AllInputDataTypes); /* @@ -460,10 +443,9 @@ TYPED_TEST(AnalysisDataCommonTest, LimitedStorageWorks) */ TEST(DISABLED_AnalysisDataCommonTest, GenericTests) { - ADD_FAILURE() - << "Tests for generic AnalysisData functionality require support for " - << "Google Test typed tests, which was not available when the tests " - << "were compiled."; + ADD_FAILURE() << "Tests for generic AnalysisData functionality require support for " + << "Google Test typed tests, which was not available when the tests " + << "were compiled."; } #endif diff --git a/src/gromacs/analysisdata/tests/arraydata.cpp b/src/gromacs/analysisdata/tests/arraydata.cpp index daab8ff38a..dac9857bbb 100644 --- a/src/gromacs/analysisdata/tests/arraydata.cpp +++ b/src/gromacs/analysisdata/tests/arraydata.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,34 +68,34 @@ typedef gmx::test::AnalysisDataTestFixture AnalysisArrayDataTest; // Input data for gmx::AnalysisArrayData tests. class SimpleInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static SimpleInputData singleton; - return singleton.data_; + static SimpleInputData singleton; + return singleton.data_; #else - static SimpleInputData singleton_arraydata; - return singleton_arraydata.data_; + static SimpleInputData singleton_arraydata; + return singleton_arraydata.data_; #endif - } - - SimpleInputData() : data_(1, false) - { - data_.setColumnCount(0, 3); - data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); - data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); - data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); - data_.addFrameWithValues(4.0, 3.0, 2.0, 1.0); - } - - private: - AnalysisDataTestInput data_; + } + + SimpleInputData() : data_(1, false) + { + data_.setColumnCount(0, 3); + data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); + data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); + data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); + data_.addFrameWithValues(4.0, 3.0, 2.0, 1.0); + } + +private: + AnalysisDataTestInput data_; }; TEST_F(AnalysisArrayDataTest, CallsModuleCorrectly) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisArrayData data; data.setXAxis(1.0, 1.0); setupArrayData(input, &data); @@ -107,7 +107,7 @@ TEST_F(AnalysisArrayDataTest, CallsModuleCorrectly) TEST_F(AnalysisArrayDataTest, StorageWorks) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisArrayData data; data.setXAxis(1.0, 1.0); setupArrayData(input, &data); @@ -118,7 +118,7 @@ TEST_F(AnalysisArrayDataTest, StorageWorks) TEST_F(AnalysisArrayDataTest, CanSetXAxis) { - gmx::AnalysisArrayData data; + gmx::AnalysisArrayData data; data.setRowCount(5); data.setXAxis(1.0, 1.0); EXPECT_FLOAT_EQ(1.0, data.xvalue(0)); @@ -135,7 +135,7 @@ TEST_F(AnalysisArrayDataTest, CanSetXAxis) TEST_F(AnalysisArrayDataTest, CanSetXAxisBeforeRowCount) { { - gmx::AnalysisArrayData data; + gmx::AnalysisArrayData data; data.setXAxis(1.0, 1.0); data.setRowCount(5); EXPECT_FLOAT_EQ(1.0, data.xvalue(0)); @@ -143,7 +143,7 @@ TEST_F(AnalysisArrayDataTest, CanSetXAxisBeforeRowCount) EXPECT_FLOAT_EQ(5.0, data.xvalue(4)); } { - gmx::AnalysisArrayData data; + gmx::AnalysisArrayData data; data.setXAxisValue(0, 2.0); data.setXAxisValue(1, 3.0); data.setXAxisValue(2, 5.0); diff --git a/src/gromacs/analysisdata/tests/average.cpp b/src/gromacs/analysisdata/tests/average.cpp index cdeabbb77d..0f9dc55457 100644 --- a/src/gromacs/analysisdata/tests/average.cpp +++ b/src/gromacs/analysisdata/tests/average.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,100 +65,100 @@ namespace // Simple input data for gmx::AnalysisDataAverageModule tests. class SimpleInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static SimpleInputData singleton; - return singleton.data_; + static SimpleInputData singleton; + return singleton.data_; #else - static SimpleInputData singleton_average; - return singleton_average.data_; + static SimpleInputData singleton_average; + return singleton_average.data_; #endif - } - - SimpleInputData() : data_(1, false) - { - data_.setColumnCount(0, 3); - data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); - data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); - data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); - } - - private: - AnalysisDataTestInput data_; + } + + SimpleInputData() : data_(1, false) + { + data_.setColumnCount(0, 3); + data_.addFrameWithValues(1.0, 0.0, 1.0, 2.0); + data_.addFrameWithValues(2.0, 1.0, 1.0, 1.0); + data_.addFrameWithValues(3.0, 2.0, 0.0, 0.0); + } + +private: + AnalysisDataTestInput data_; }; // Multipoint input data for gmx::AnalysisDataAverageModule tests. class MultipointInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static MultipointInputData singleton; - return singleton.data_; + static MultipointInputData singleton; + return singleton.data_; #else - static MultipointInputData singleton_average; - return singleton_average.data_; + static MultipointInputData singleton_average; + return singleton_average.data_; #endif - } - - MultipointInputData() : data_(1, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 3); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); - frame1.addPointSetWithValues(0, 0, 1.0, 0.0); - frame1.addPointSetWithValues(0, 0, 2.0); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.0, 1.0); - frame2.addPointSetWithValues(0, 0, 2.0); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); - } - - private: - AnalysisDataTestInput data_; + } + + MultipointInputData() : data_(1, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 3); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); + frame1.addPointSetWithValues(0, 0, 1.0, 0.0); + frame1.addPointSetWithValues(0, 0, 2.0); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.0, 1.0); + frame2.addPointSetWithValues(0, 0, 2.0); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); + } + +private: + AnalysisDataTestInput data_; }; // Input data with multiple data sets for gmx::AnalysisDataAverageModule tests. class MultiDataSetInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static MultiDataSetInputData singleton; - return singleton.data_; + static MultiDataSetInputData singleton; + return singleton.data_; #else - static MultiDataSetInputData singleton_average; - return singleton_average.data_; + static MultiDataSetInputData singleton_average; + return singleton_average.data_; #endif - } - - MultiDataSetInputData() : data_(2, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 3); - data_.setColumnCount(1, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); - frame1.addPointSetWithValues(0, 0, 1.0, 0.0); - frame1.addPointSetWithValues(1, 0, 2.0, 1.0); - frame1.addPointSetWithValues(1, 1, 2.0); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.0, 1.0); - frame2.addPointSetWithValues(0, 2, 2.0); - frame2.addPointSetWithValues(1, 0, 1.0, 0.0); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); - frame3.addPointSetWithValues(1, 0, 0.0, 2.0); - } - - private: - AnalysisDataTestInput data_; + } + + MultiDataSetInputData() : data_(2, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 3); + data_.setColumnCount(1, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.0, 1.0, 2.0); + frame1.addPointSetWithValues(0, 0, 1.0, 0.0); + frame1.addPointSetWithValues(1, 0, 2.0, 1.0); + frame1.addPointSetWithValues(1, 1, 2.0); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.0, 1.0); + frame2.addPointSetWithValues(0, 2, 2.0); + frame2.addPointSetWithValues(1, 0, 1.0, 0.0); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 2.0, 0.0, 0.0); + frame3.addPointSetWithValues(1, 0, 0.0, 2.0); + } + +private: + AnalysisDataTestInput data_; }; @@ -171,12 +171,11 @@ typedef gmx::test::AnalysisDataTestFixture AverageModuleTest; TEST_F(AverageModuleTest, BasicTest) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataAverageModulePointer module( - new gmx::AnalysisDataAverageModule); + gmx::AnalysisDataAverageModulePointer module(new gmx::AnalysisDataAverageModule); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -187,12 +186,11 @@ TEST_F(AverageModuleTest, BasicTest) TEST_F(AverageModuleTest, HandlesMultipointData) { - const AnalysisDataTestInput &input = MultipointInputData::get(); + const AnalysisDataTestInput& input = MultipointInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataAverageModulePointer module( - new gmx::AnalysisDataAverageModule); + gmx::AnalysisDataAverageModulePointer module(new gmx::AnalysisDataAverageModule); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -203,12 +201,11 @@ TEST_F(AverageModuleTest, HandlesMultipointData) TEST_F(AverageModuleTest, HandlesMultipleDataSets) { - const AnalysisDataTestInput &input = MultiDataSetInputData::get(); + const AnalysisDataTestInput& input = MultiDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataAverageModulePointer module( - new gmx::AnalysisDataAverageModule); + gmx::AnalysisDataAverageModulePointer module(new gmx::AnalysisDataAverageModule); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -219,12 +216,11 @@ TEST_F(AverageModuleTest, HandlesMultipleDataSets) TEST_F(AverageModuleTest, HandlesDataSetAveraging) { - const AnalysisDataTestInput &input = MultiDataSetInputData::get(); + const AnalysisDataTestInput& input = MultiDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataAverageModulePointer module( - new gmx::AnalysisDataAverageModule); + gmx::AnalysisDataAverageModulePointer module(new gmx::AnalysisDataAverageModule); module->setAverageDataSets(true); data.addModule(module); @@ -236,7 +232,7 @@ TEST_F(AverageModuleTest, HandlesDataSetAveraging) TEST_F(AverageModuleTest, CanCustomizeXAxis) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); @@ -252,7 +248,7 @@ TEST_F(AverageModuleTest, CanCustomizeXAxis) TEST_F(AverageModuleTest, CanCustomizeNonUniformXAxis) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); @@ -277,12 +273,11 @@ typedef gmx::test::AnalysisDataTestFixture FrameAverageModuleTest; TEST_F(FrameAverageModuleTest, BasicTest) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataFrameAverageModulePointer module( - new gmx::AnalysisDataFrameAverageModule); + gmx::AnalysisDataFrameAverageModulePointer module(new gmx::AnalysisDataFrameAverageModule); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -293,12 +288,11 @@ TEST_F(FrameAverageModuleTest, BasicTest) TEST_F(FrameAverageModuleTest, HandlesMultipleDataSets) { - const AnalysisDataTestInput &input = MultiDataSetInputData::get(); + const AnalysisDataTestInput& input = MultiDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataFrameAverageModulePointer module( - new gmx::AnalysisDataFrameAverageModule); + gmx::AnalysisDataFrameAverageModulePointer module(new gmx::AnalysisDataFrameAverageModule); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); diff --git a/src/gromacs/analysisdata/tests/datatest.cpp b/src/gromacs/analysisdata/tests/datatest.cpp index 023e7754c2..18b0b8adda 100644 --- a/src/gromacs/analysisdata/tests/datatest.cpp +++ b/src/gromacs/analysisdata/tests/datatest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,9 +65,10 @@ namespace test * AnalysisDataTestInputPointSet */ -AnalysisDataTestInputPointSet::AnalysisDataTestInputPointSet( - int index, int dataSetIndex, int firstColumn) - : index_(index), dataSetIndex_(dataSetIndex), firstColumn_(firstColumn) +AnalysisDataTestInputPointSet::AnalysisDataTestInputPointSet(int index, int dataSetIndex, int firstColumn) : + index_(index), + dataSetIndex_(dataSetIndex), + firstColumn_(firstColumn) { } @@ -76,48 +77,38 @@ AnalysisDataTestInputPointSet::AnalysisDataTestInputPointSet( * AnalysisDataTestInputFrame */ -AnalysisDataTestInputFrame::AnalysisDataTestInputFrame(int index, real x) - : index_(index), x_(x) -{ -} +AnalysisDataTestInputFrame::AnalysisDataTestInputFrame(int index, real x) : index_(index), x_(x) {} -AnalysisDataTestInputPointSet & -AnalysisDataTestInputFrame::addPointSet(int dataSet, int firstColumn) +AnalysisDataTestInputPointSet& AnalysisDataTestInputFrame::addPointSet(int dataSet, int firstColumn) { - pointSets_.push_back( - AnalysisDataTestInputPointSet(pointSets_.size(), - dataSet, firstColumn)); + pointSets_.push_back(AnalysisDataTestInputPointSet(pointSets_.size(), dataSet, firstColumn)); return pointSets_.back(); } -void AnalysisDataTestInputFrame::addPointSetWithValues( - int dataSet, int firstColumn, real y1) +void AnalysisDataTestInputFrame::addPointSetWithValues(int dataSet, int firstColumn, real y1) { - AnalysisDataTestInputPointSet &pointSet = addPointSet(dataSet, firstColumn); + AnalysisDataTestInputPointSet& pointSet = addPointSet(dataSet, firstColumn); pointSet.addValue(y1); } -void AnalysisDataTestInputFrame::addPointSetWithValues( - int dataSet, int firstColumn, real y1, real y2) +void AnalysisDataTestInputFrame::addPointSetWithValues(int dataSet, int firstColumn, real y1, real y2) { - AnalysisDataTestInputPointSet &pointSet = addPointSet(dataSet, firstColumn); + AnalysisDataTestInputPointSet& pointSet = addPointSet(dataSet, firstColumn); pointSet.addValue(y1); pointSet.addValue(y2); } -void AnalysisDataTestInputFrame::addPointSetWithValues( - int dataSet, int firstColumn, real y1, real y2, real y3) +void AnalysisDataTestInputFrame::addPointSetWithValues(int dataSet, int firstColumn, real y1, real y2, real y3) { - AnalysisDataTestInputPointSet &pointSet = addPointSet(dataSet, firstColumn); + AnalysisDataTestInputPointSet& pointSet = addPointSet(dataSet, firstColumn); pointSet.addValue(y1); pointSet.addValue(y2); pointSet.addValue(y3); } -void AnalysisDataTestInputFrame::addPointSetWithValueAndError( - int dataSet, int firstColumn, real y1, real e1) +void AnalysisDataTestInputFrame::addPointSetWithValueAndError(int dataSet, int firstColumn, real y1, real e1) { - AnalysisDataTestInputPointSet &pointSet = addPointSet(dataSet, firstColumn); + AnalysisDataTestInputPointSet& pointSet = addPointSet(dataSet, firstColumn); pointSet.addValueWithError(y1, e1); } @@ -126,34 +117,31 @@ void AnalysisDataTestInputFrame::addPointSetWithValueAndError( * AnalysisDataTestInput */ -AnalysisDataTestInput::AnalysisDataTestInput(int dataSetCount, bool bMultipoint) - : columnCounts_(dataSetCount), bMultipoint_(bMultipoint) +AnalysisDataTestInput::AnalysisDataTestInput(int dataSetCount, bool bMultipoint) : + columnCounts_(dataSetCount), + bMultipoint_(bMultipoint) { } -AnalysisDataTestInput::~AnalysisDataTestInput() -{ -} +AnalysisDataTestInput::~AnalysisDataTestInput() {} -const AnalysisDataTestInputFrame &AnalysisDataTestInput::frame(int index) const +const AnalysisDataTestInputFrame& AnalysisDataTestInput::frame(int index) const { - GMX_RELEASE_ASSERT(index >= 0 && index < frameCount(), - "Out-of-range frame index"); + GMX_RELEASE_ASSERT(index >= 0 && index < frameCount(), "Out-of-range frame index"); return frames_[index]; } void AnalysisDataTestInput::setColumnCount(int dataSet, int columnCount) { - GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), - "Out-of-range data set index"); + GMX_RELEASE_ASSERT(dataSet >= 0 && dataSet < dataSetCount(), "Out-of-range data set index"); columnCounts_[dataSet] = columnCount; } -AnalysisDataTestInputFrame &AnalysisDataTestInput::addFrame(real x) +AnalysisDataTestInputFrame& AnalysisDataTestInput::addFrame(real x) { frames_.push_back(AnalysisDataTestInputFrame(frames_.size(), x)); return frames_.back(); @@ -161,25 +149,25 @@ AnalysisDataTestInputFrame &AnalysisDataTestInput::addFrame(real x) void AnalysisDataTestInput::addFrameWithValues(real x, real y1) { - AnalysisDataTestInputFrame &frame = addFrame(x); + AnalysisDataTestInputFrame& frame = addFrame(x); frame.addPointSetWithValues(0, 0, y1); } void AnalysisDataTestInput::addFrameWithValues(real x, real y1, real y2) { - AnalysisDataTestInputFrame &frame = addFrame(x); + AnalysisDataTestInputFrame& frame = addFrame(x); frame.addPointSetWithValues(0, 0, y1, y2); } void AnalysisDataTestInput::addFrameWithValues(real x, real y1, real y2, real y3) { - AnalysisDataTestInputFrame &frame = addFrame(x); + AnalysisDataTestInputFrame& frame = addFrame(x); frame.addPointSetWithValues(0, 0, y1, y2, y3); } void AnalysisDataTestInput::addFrameWithValueAndError(real x, real y1, real e1) { - AnalysisDataTestInputFrame &frame = addFrame(x); + AnalysisDataTestInputFrame& frame = addFrame(x); frame.addPointSetWithValueAndError(0, 0, y1, e1); } @@ -188,13 +176,10 @@ void AnalysisDataTestInput::addFrameWithValueAndError(real x, real y1, real e1) * AnalysisDataTest */ -AnalysisDataTestFixture::AnalysisDataTestFixture() -{ -} +AnalysisDataTestFixture::AnalysisDataTestFixture() {} -void AnalysisDataTestFixture::setupDataObject(const AnalysisDataTestInput &input, - AnalysisData *data) +void AnalysisDataTestFixture::setupDataObject(const AnalysisDataTestInput& input, AnalysisData* data) { data->setDataSetCount(input.dataSetCount()); for (int i = 0; i < input.dataSetCount(); ++i) @@ -205,8 +190,7 @@ void AnalysisDataTestFixture::setupDataObject(const AnalysisDataTestInput &input } -void AnalysisDataTestFixture::presentAllData(const AnalysisDataTestInput &input, - AnalysisData *data) +void AnalysisDataTestFixture::presentAllData(const AnalysisDataTestInput& input, AnalysisData* data) { gmx::AnalysisDataParallelOptions options; gmx::AnalysisDataHandle handle = data->startData(options); @@ -219,26 +203,23 @@ void AnalysisDataTestFixture::presentAllData(const AnalysisDataTestInput &input, } -void AnalysisDataTestFixture::presentDataFrame(const AnalysisDataTestInput &input, - int row, AnalysisDataHandle handle) +void AnalysisDataTestFixture::presentDataFrame(const AnalysisDataTestInput& input, int row, AnalysisDataHandle handle) { - const AnalysisDataTestInputFrame &frame = input.frame(row); + const AnalysisDataTestInputFrame& frame = input.frame(row); handle.startFrame(row, frame.x(), frame.dx()); for (int i = 0; i < frame.pointSetCount(); ++i) { - const AnalysisDataTestInputPointSet &points = frame.pointSet(i); + const AnalysisDataTestInputPointSet& points = frame.pointSet(i); handle.selectDataSet(points.dataSetIndex()); for (int j = 0; j < points.size(); ++j) { if (points.hasError(j)) { - handle.setPoint(j + points.firstColumn(), - points.y(j), points.error(j), points.present(j)); + handle.setPoint(j + points.firstColumn(), points.y(j), points.error(j), points.present(j)); } else { - handle.setPoint(j + points.firstColumn(), - points.y(j), points.present(j)); + handle.setPoint(j + points.firstColumn(), points.y(j), points.present(j)); } } if (input.isMultipoint()) @@ -250,9 +231,8 @@ void AnalysisDataTestFixture::presentDataFrame(const AnalysisDataTestInput &inpu } -void -AnalysisDataTestFixture::addStaticCheckerModule(const AnalysisDataTestInput &data, - AbstractAnalysisData *source) +void AnalysisDataTestFixture::addStaticCheckerModule(const AnalysisDataTestInput& data, + AbstractAnalysisData* source) { MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0)); module->setupStaticCheck(data, source, false); @@ -260,10 +240,8 @@ AnalysisDataTestFixture::addStaticCheckerModule(const AnalysisDataTestInput &dat } -void -AnalysisDataTestFixture::addStaticParallelCheckerModule( - const AnalysisDataTestInput &data, - AbstractAnalysisData *source) +void AnalysisDataTestFixture::addStaticParallelCheckerModule(const AnalysisDataTestInput& data, + AbstractAnalysisData* source) { MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0)); module->setupStaticCheck(data, source, true); @@ -271,10 +249,10 @@ AnalysisDataTestFixture::addStaticParallelCheckerModule( } -void -AnalysisDataTestFixture::addStaticColumnCheckerModule(const AnalysisDataTestInput &data, - int firstcol, int n, - AbstractAnalysisData *source) +void AnalysisDataTestFixture::addStaticColumnCheckerModule(const AnalysisDataTestInput& data, + int firstcol, + int n, + AbstractAnalysisData* source) { MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0)); module->setupStaticColumnCheck(data, firstcol, n, source); @@ -282,10 +260,9 @@ AnalysisDataTestFixture::addStaticColumnCheckerModule(const AnalysisDataTestInpu } -void -AnalysisDataTestFixture::addStaticStorageCheckerModule(const AnalysisDataTestInput &data, - int storageCount, - AbstractAnalysisData *source) +void AnalysisDataTestFixture::addStaticStorageCheckerModule(const AnalysisDataTestInput& data, + int storageCount, + AbstractAnalysisData* source) { MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0)); module->setupStaticStorageCheck(data, storageCount, source); @@ -293,11 +270,10 @@ AnalysisDataTestFixture::addStaticStorageCheckerModule(const AnalysisDataTestInp } -void -AnalysisDataTestFixture::addReferenceCheckerModule(const TestReferenceChecker &checker, - const char *id, - AbstractAnalysisData *source, - const FloatingPointTolerance &tolerance) +void AnalysisDataTestFixture::addReferenceCheckerModule(const TestReferenceChecker& checker, + const char* id, + AbstractAnalysisData* source, + const FloatingPointTolerance& tolerance) { MockAnalysisDataModulePointer module(new MockAnalysisDataModule(0)); TestReferenceChecker tmpChecker(checker); @@ -308,12 +284,9 @@ AnalysisDataTestFixture::addReferenceCheckerModule(const TestReferenceChecker } -void -AnalysisDataTestFixture::addReferenceCheckerModule(const char *id, - AbstractAnalysisData *source) +void AnalysisDataTestFixture::addReferenceCheckerModule(const char* id, AbstractAnalysisData* source) { - addReferenceCheckerModule(data_.rootChecker(), id, source, - defaultRealTolerance()); + addReferenceCheckerModule(data_.rootChecker(), id, source, defaultRealTolerance()); } } // namespace test diff --git a/src/gromacs/analysisdata/tests/datatest.h b/src/gromacs/analysisdata/tests/datatest.h index 8111d1e481..6f1b57ee44 100644 --- a/src/gromacs/analysisdata/tests/datatest.h +++ b/src/gromacs/analysisdata/tests/datatest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,7 +55,7 @@ // currently the bug manifests itself only in AbstractAnalysisData testing #if defined __PATHSCALE__ -#define STATIC_ANON_NAMESPACE_BUG //see #1558 for details +# define STATIC_ANON_NAMESPACE_BUG // see #1558 for details #endif namespace gmx @@ -83,68 +83,64 @@ class FloatingPointTolerance; */ class AnalysisDataTestInputPointSet { - public: - //! Returns zero-based index of this point set in its frame. - int index() const { return index_; } - //! Returns zero-based index of the data set of this point set. - int dataSetIndex() const { return dataSetIndex_; } - //! Returns zero-based index of the first column in this point set. - int firstColumn() const { return firstColumn_; } - //! Returns zero-based index of the last column in this point set. - int lastColumn() const { return firstColumn_ + size() - 1; } - //! Returns the number of columns in the point set. - int size() const { return values_.size(); } - //! Returns the value in column \p i. - real y(int i) const { return values_[i].y; } - //! Returns whether the error is present for column \p i. - bool hasError(int i) const { return values_[i].bError; } - //! Returns the error in column \p i. - real error(int i) const { return values_[i].error; } - //! Returns whether the value in column \p i is present. - bool present(int /*i*/) const { return true; } - //! Returns an AnalysisDataValue for column \p i. - AnalysisDataValue value(int i) const +public: + //! Returns zero-based index of this point set in its frame. + int index() const { return index_; } + //! Returns zero-based index of the data set of this point set. + int dataSetIndex() const { return dataSetIndex_; } + //! Returns zero-based index of the first column in this point set. + int firstColumn() const { return firstColumn_; } + //! Returns zero-based index of the last column in this point set. + int lastColumn() const { return firstColumn_ + size() - 1; } + //! Returns the number of columns in the point set. + int size() const { return values_.size(); } + //! Returns the value in column \p i. + real y(int i) const { return values_[i].y; } + //! Returns whether the error is present for column \p i. + bool hasError(int i) const { return values_[i].bError; } + //! Returns the error in column \p i. + real error(int i) const { return values_[i].error; } + //! Returns whether the value in column \p i is present. + bool present(int /*i*/) const { return true; } + //! Returns an AnalysisDataValue for column \p i. + AnalysisDataValue value(int i) const + { + AnalysisDataValue result; + result.setValue(values_[i].y); + if (values_[i].bError) { - AnalysisDataValue result; - result.setValue(values_[i].y); - if (values_[i].bError) - { - result.setError(values_[i].error); - } - return result; + result.setError(values_[i].error); } + return result; + } - //! Appends a value to this point set. - void addValue(real y) { values_.emplace_back(y); } - //! Appends a value with an error estimate to this point set. - void addValueWithError(real y, real error) - { - values_.emplace_back(y, error); - } + //! Appends a value to this point set. + void addValue(real y) { values_.emplace_back(y); } + //! Appends a value with an error estimate to this point set. + void addValueWithError(real y, real error) { values_.emplace_back(y, error); } - private: - //! Creates an empty point set. - AnalysisDataTestInputPointSet(int index, int dataSetIndex, - int firstColumn); +private: + //! Creates an empty point set. + AnalysisDataTestInputPointSet(int index, int dataSetIndex, int firstColumn); - struct Value - { - Value() : y(0.0), error(0.0), bError(false) {} - explicit Value(real y) : y(y), error(0.0), bError(false) {} - Value(real y, real error) : y(y), error(error), bError(true) {} - - real y; - real error; - bool bError; - }; - - int index_; - int dataSetIndex_; - int firstColumn_; - std::vector values_; - - //! For constructing new point sets. - friend class AnalysisDataTestInputFrame; + struct Value + { + Value() : y(0.0), error(0.0), bError(false) {} + explicit Value(real y) : y(y), error(0.0), bError(false) {} + Value(real y, real error) : y(y), error(error), bError(true) {} + + real y; + real error; + bool bError; + }; + + int index_; + int dataSetIndex_; + int firstColumn_; + std::vector values_; + + //! For constructing new point sets. + friend class AnalysisDataTestInputFrame; }; /*! \libinternal \brief @@ -155,48 +151,45 @@ class AnalysisDataTestInputPointSet */ class AnalysisDataTestInputFrame { - public: - //! Returns zero-based index for the frame. - int index() const { return index_; } - //! Returns x coordinate for the frame. - real x() const { return x_; } - //! Returns error in the x coordinate for the frame. - real dx() const { return 0.0; } - - //! Number of individual point sets in the frame. - int pointSetCount() const { return pointSets_.size(); } - //! Returns a point set object for a given point set. - const AnalysisDataTestInputPointSet &pointSet(int index) const - { - GMX_ASSERT(index >= 0 && static_cast(index) < pointSets_.size(), - "Point set index out of range"); - return pointSets_[index]; - } +public: + //! Returns zero-based index for the frame. + int index() const { return index_; } + //! Returns x coordinate for the frame. + real x() const { return x_; } + //! Returns error in the x coordinate for the frame. + real dx() const { return 0.0; } + + //! Number of individual point sets in the frame. + int pointSetCount() const { return pointSets_.size(); } + //! Returns a point set object for a given point set. + const AnalysisDataTestInputPointSet& pointSet(int index) const + { + GMX_ASSERT(index >= 0 && static_cast(index) < pointSets_.size(), + "Point set index out of range"); + return pointSets_[index]; + } - //! Appends an empty point set to this frame. - AnalysisDataTestInputPointSet &addPointSet(int dataSet, int firstColumn); - //! Adds a point set with given values to this frame. - void addPointSetWithValues(int dataSet, int firstColumn, real y1); - //! Adds a point set with given values to this frame. - void addPointSetWithValues(int dataSet, int firstColumn, - real y1, real y2); - //! Adds a point set with given values to this frame. - void addPointSetWithValues(int dataSet, int firstColumn, - real y1, real y2, real y3); - //! Adds a point set with given values to this frame. - void addPointSetWithValueAndError(int dataSet, int firstColumn, - real y1, real e1); - - private: - //! Constructs a new frame object with the given values. - AnalysisDataTestInputFrame(int index, real x); - - int index_; - real x_; - std::vector pointSets_; - - //! For constructing new frames. - friend class AnalysisDataTestInput; + //! Appends an empty point set to this frame. + AnalysisDataTestInputPointSet& addPointSet(int dataSet, int firstColumn); + //! Adds a point set with given values to this frame. + void addPointSetWithValues(int dataSet, int firstColumn, real y1); + //! Adds a point set with given values to this frame. + void addPointSetWithValues(int dataSet, int firstColumn, real y1, real y2); + //! Adds a point set with given values to this frame. + void addPointSetWithValues(int dataSet, int firstColumn, real y1, real y2, real y3); + //! Adds a point set with given values to this frame. + void addPointSetWithValueAndError(int dataSet, int firstColumn, real y1, real e1); + +private: + //! Constructs a new frame object with the given values. + AnalysisDataTestInputFrame(int index, real x); + + int index_; + real x_; + std::vector pointSets_; + + //! For constructing new frames. + friend class AnalysisDataTestInput; }; /*! \libinternal \brief @@ -212,47 +205,47 @@ class AnalysisDataTestInputFrame */ class AnalysisDataTestInput { - public: - /*! \brief - * Constructs empty input data. - * - * \param[in] dataSetCount Number of data sets in the data. - * \param[in] bMultipoint Whether the data will be multipoint. - * - * The column count for each data set must be set with - * setColumnCount(). - */ - AnalysisDataTestInput(int dataSetCount, bool bMultipoint); - ~AnalysisDataTestInput(); - - //! Whether the input data is multipoint. - bool isMultipoint() const { return bMultipoint_; } - //! Returns the number of data sets in the input data. - int dataSetCount() const { return columnCounts_.size(); } - //! Returns the number of columns in a given data set. - int columnCount(int dataSet) const { return columnCounts_[dataSet]; } - //! Returns the number of frames in the input data. - int frameCount() const { return frames_.size(); } - //! Returns a frame object for the given input frame. - const AnalysisDataTestInputFrame &frame(int index) const; - - //! Sets the number of columns in a data set. - void setColumnCount(int dataSet, int columnCount); - //! Appends an empty frame to this data. - AnalysisDataTestInputFrame &addFrame(real x); - //! Adds a frame with a single point set and the given values. - void addFrameWithValues(real x, real y1); - //! Adds a frame with a single point set and the given values. - void addFrameWithValues(real x, real y1, real y2); - //! Adds a frame with a single point set and the given values. - void addFrameWithValues(real x, real y1, real y2, real y3); - //! Adds a frame with a single point set and the given values. - void addFrameWithValueAndError(real x, real y1, real e1); - - private: - std::vector columnCounts_; - bool bMultipoint_; - std::vector frames_; +public: + /*! \brief + * Constructs empty input data. + * + * \param[in] dataSetCount Number of data sets in the data. + * \param[in] bMultipoint Whether the data will be multipoint. + * + * The column count for each data set must be set with + * setColumnCount(). + */ + AnalysisDataTestInput(int dataSetCount, bool bMultipoint); + ~AnalysisDataTestInput(); + + //! Whether the input data is multipoint. + bool isMultipoint() const { return bMultipoint_; } + //! Returns the number of data sets in the input data. + int dataSetCount() const { return columnCounts_.size(); } + //! Returns the number of columns in a given data set. + int columnCount(int dataSet) const { return columnCounts_[dataSet]; } + //! Returns the number of frames in the input data. + int frameCount() const { return frames_.size(); } + //! Returns a frame object for the given input frame. + const AnalysisDataTestInputFrame& frame(int index) const; + + //! Sets the number of columns in a data set. + void setColumnCount(int dataSet, int columnCount); + //! Appends an empty frame to this data. + AnalysisDataTestInputFrame& addFrame(real x); + //! Adds a frame with a single point set and the given values. + void addFrameWithValues(real x, real y1); + //! Adds a frame with a single point set and the given values. + void addFrameWithValues(real x, real y1, real y2); + //! Adds a frame with a single point set and the given values. + void addFrameWithValues(real x, real y1, real y2, real y3); + //! Adds a frame with a single point set and the given values. + void addFrameWithValueAndError(real x, real y1, real e1); + +private: + std::vector columnCounts_; + bool bMultipoint_; + std::vector frames_; }; /*! \libinternal \brief @@ -295,178 +288,171 @@ class AnalysisDataTestInput */ class AnalysisDataTestFixture : public ::testing::Test { - public: - AnalysisDataTestFixture(); - - /*! \brief - * Initializes an AnalysisData object from input data. - * - * Sets the column count and other properties based on the input data. - */ - static void setupDataObject(const AnalysisDataTestInput &input, - AnalysisData *data); - - /*! \brief - * Adds all data from AnalysisDataTestInput into an AnalysisData. - */ - static void presentAllData(const AnalysisDataTestInput &input, - AnalysisData *data); - /*! \brief - * Adds a single frame from AnalysisDataTestInput into an AnalysisData. - */ - static void presentDataFrame(const AnalysisDataTestInput &input, int row, - AnalysisDataHandle handle); - /*! \brief - * Initializes an array data object from AnalysisDataTestInput. - * - * \tparam ArrayData Class derived from AbstractAnalysisArrayData. - * - * The ArrayData class should expose the setter methods - * (setColumnCount(), setRowCount(), allocateValues(), setValue()) - * publicly or declare the fixture class as a friend. - * The X axis in \p data must be configured to match \p input before - * calling this method. - * - * Does not call AbstractAnalysisArrayData::valuesReady(). - * The test must ensure that this method gets called, otherwise the - * mock modules never get called. - */ - template - static void setupArrayData(const AnalysisDataTestInput &input, - ArrayData *data); - - /*! \brief - * Adds a mock module that verifies output against - * AnalysisDataTestInput. - * - * \param[in] data Data to compare against. - * \param source Data object to verify. - * - * Creates a mock module that verifies that the - * IAnalysisDataModule methods are called correctly by - * \p source. Parameters for the calls are verified against \p data. - * Adds the created module to \p source using \p data->addModule(). - * Any exceptions from the called functions should be caught by the - * caller. - * - * \see AbstractAnalysisData::addModule() - */ - static void addStaticCheckerModule(const AnalysisDataTestInput &data, - AbstractAnalysisData *source); - /*! \brief - * Adds a mock module that verifies parallel output against - * AnalysisDataTestInput. - * - * \param[in] data Data to compare against. - * \param source Data object to verify. - * - * Creates a parallel mock module that verifies that the - * IAnalysisDataModule methods are called correctly by - * \p source. Parameters for the calls are verified against \p data. - * Adds the created module to \p source using \p data->addModule(). - * Any exceptions from the called functions should be caught by the - * caller. - * - * Differs from addStaticCheckerModule() in that the created mock - * module reports that it accepts parallel input data, and accepts and - * verifies notification calls following the parallel pattern. - * - * \see AbstractAnalysisData::addModule() - */ - static void addStaticParallelCheckerModule( - const AnalysisDataTestInput &data, - AbstractAnalysisData *source); - /*! \brief - * Adds a column mock module that verifies output against - * AnalysisDataTestInput. - * - * \param[in] data Data to compare against. - * \param[in] firstcol First column to check. - * \param[in] n Number of columns to check. - * \param source Data object to verify. - * - * Creates a mock module that verifies that the - * IAnalysisDataModule methods are called correctly by - * \p source. Parameters for the calls are verified against \p data. - * Adds the created module to \p source using - * \p data->addColumnModule(). - * Any exceptions from the called functions should be caught by the - * caller. - * - * \see AbstractAnalysisData::addColumnModule() - */ - static void addStaticColumnCheckerModule(const AnalysisDataTestInput &data, - int firstcol, int n, - AbstractAnalysisData *source); - /*! \brief - * Adds a mock module that verifies output and storage against - * AnalysisDataTestInput. - * - * \param[in] data Data to compare against. - * \param[in] storageCount Number of previous frames to check - * (-1 = all). - * \param source Data object to verify. - * - * Works like addStaticCheckerModule(), except that in addition, for - * each frame, the mock module also checks that previous frames can be - * accessed using AbstractAnalysisData::getDataFrame(). In the - * IAnalysisDataModule::dataStarted() callback, the mock module - * calls AbstractAnalysisData::requestStorage() with \p storageCount as - * the parameter. - */ - static void addStaticStorageCheckerModule(const AnalysisDataTestInput &data, - int storageCount, - AbstractAnalysisData *source); - /*! \brief - * Adds a mock module that verifies output against reference data. - * - * \param[in] checker Reference data checker to use for comparison. - * \param[in] id Identifier for reference data compound to use. - * \param source Data object to verify. - * \param[in] tolerance Tolerance to use for comparison. - * - * Creates a mock module that verifies that the - * IAnalysisDataModule methods are called correctly by - * \p source. Parameters for the calls are verified against reference - * data using a child compound \p id of \p checker. - * Adds the created module to \p source using \p data->addModule(). - * Any exceptions from the called functions should be caught by the - * caller. - * - * \see TestReferenceData - */ - static void addReferenceCheckerModule(const TestReferenceChecker &checker, - const char *id, - AbstractAnalysisData *source, - const FloatingPointTolerance &tolerance); - - /*! \brief - * Adds a mock module that verifies output against reference data. - * - * \param[in] id Identifier for reference data compound to use. - * \param source Data object to verify. - * - * Creates a reference checker module using a compound checker with id - * \p id at the root level of \p data_. - * - * See the static overload for other details. - */ - void addReferenceCheckerModule(const char *id, - AbstractAnalysisData *source); - - private: - /*! \brief - * Reference data object used for the reference checker modules. - * - * Tests can use the data object also for their own purposes if needed. - */ - gmx::test::TestReferenceData data_; +public: + AnalysisDataTestFixture(); + + /*! \brief + * Initializes an AnalysisData object from input data. + * + * Sets the column count and other properties based on the input data. + */ + static void setupDataObject(const AnalysisDataTestInput& input, AnalysisData* data); + + /*! \brief + * Adds all data from AnalysisDataTestInput into an AnalysisData. + */ + static void presentAllData(const AnalysisDataTestInput& input, AnalysisData* data); + /*! \brief + * Adds a single frame from AnalysisDataTestInput into an AnalysisData. + */ + static void presentDataFrame(const AnalysisDataTestInput& input, int row, AnalysisDataHandle handle); + /*! \brief + * Initializes an array data object from AnalysisDataTestInput. + * + * \tparam ArrayData Class derived from AbstractAnalysisArrayData. + * + * The ArrayData class should expose the setter methods + * (setColumnCount(), setRowCount(), allocateValues(), setValue()) + * publicly or declare the fixture class as a friend. + * The X axis in \p data must be configured to match \p input before + * calling this method. + * + * Does not call AbstractAnalysisArrayData::valuesReady(). + * The test must ensure that this method gets called, otherwise the + * mock modules never get called. + */ + template + static void setupArrayData(const AnalysisDataTestInput& input, ArrayData* data); + + /*! \brief + * Adds a mock module that verifies output against + * AnalysisDataTestInput. + * + * \param[in] data Data to compare against. + * \param source Data object to verify. + * + * Creates a mock module that verifies that the + * IAnalysisDataModule methods are called correctly by + * \p source. Parameters for the calls are verified against \p data. + * Adds the created module to \p source using \p data->addModule(). + * Any exceptions from the called functions should be caught by the + * caller. + * + * \see AbstractAnalysisData::addModule() + */ + static void addStaticCheckerModule(const AnalysisDataTestInput& data, AbstractAnalysisData* source); + /*! \brief + * Adds a mock module that verifies parallel output against + * AnalysisDataTestInput. + * + * \param[in] data Data to compare against. + * \param source Data object to verify. + * + * Creates a parallel mock module that verifies that the + * IAnalysisDataModule methods are called correctly by + * \p source. Parameters for the calls are verified against \p data. + * Adds the created module to \p source using \p data->addModule(). + * Any exceptions from the called functions should be caught by the + * caller. + * + * Differs from addStaticCheckerModule() in that the created mock + * module reports that it accepts parallel input data, and accepts and + * verifies notification calls following the parallel pattern. + * + * \see AbstractAnalysisData::addModule() + */ + static void addStaticParallelCheckerModule(const AnalysisDataTestInput& data, + AbstractAnalysisData* source); + /*! \brief + * Adds a column mock module that verifies output against + * AnalysisDataTestInput. + * + * \param[in] data Data to compare against. + * \param[in] firstcol First column to check. + * \param[in] n Number of columns to check. + * \param source Data object to verify. + * + * Creates a mock module that verifies that the + * IAnalysisDataModule methods are called correctly by + * \p source. Parameters for the calls are verified against \p data. + * Adds the created module to \p source using + * \p data->addColumnModule(). + * Any exceptions from the called functions should be caught by the + * caller. + * + * \see AbstractAnalysisData::addColumnModule() + */ + static void addStaticColumnCheckerModule(const AnalysisDataTestInput& data, + int firstcol, + int n, + AbstractAnalysisData* source); + /*! \brief + * Adds a mock module that verifies output and storage against + * AnalysisDataTestInput. + * + * \param[in] data Data to compare against. + * \param[in] storageCount Number of previous frames to check + * (-1 = all). + * \param source Data object to verify. + * + * Works like addStaticCheckerModule(), except that in addition, for + * each frame, the mock module also checks that previous frames can be + * accessed using AbstractAnalysisData::getDataFrame(). In the + * IAnalysisDataModule::dataStarted() callback, the mock module + * calls AbstractAnalysisData::requestStorage() with \p storageCount as + * the parameter. + */ + static void addStaticStorageCheckerModule(const AnalysisDataTestInput& data, + int storageCount, + AbstractAnalysisData* source); + /*! \brief + * Adds a mock module that verifies output against reference data. + * + * \param[in] checker Reference data checker to use for comparison. + * \param[in] id Identifier for reference data compound to use. + * \param source Data object to verify. + * \param[in] tolerance Tolerance to use for comparison. + * + * Creates a mock module that verifies that the + * IAnalysisDataModule methods are called correctly by + * \p source. Parameters for the calls are verified against reference + * data using a child compound \p id of \p checker. + * Adds the created module to \p source using \p data->addModule(). + * Any exceptions from the called functions should be caught by the + * caller. + * + * \see TestReferenceData + */ + static void addReferenceCheckerModule(const TestReferenceChecker& checker, + const char* id, + AbstractAnalysisData* source, + const FloatingPointTolerance& tolerance); + + /*! \brief + * Adds a mock module that verifies output against reference data. + * + * \param[in] id Identifier for reference data compound to use. + * \param source Data object to verify. + * + * Creates a reference checker module using a compound checker with id + * \p id at the root level of \p data_. + * + * See the static overload for other details. + */ + void addReferenceCheckerModule(const char* id, AbstractAnalysisData* source); + +private: + /*! \brief + * Reference data object used for the reference checker modules. + * + * Tests can use the data object also for their own purposes if needed. + */ + gmx::test::TestReferenceData data_; }; -template -void AnalysisDataTestFixture::setupArrayData(const AnalysisDataTestInput &input, - ArrayData *data) +template +void AnalysisDataTestFixture::setupArrayData(const AnalysisDataTestInput& input, ArrayData* data) { GMX_RELEASE_ASSERT(!input.isMultipoint(), "Array data cannot be initialized from multipoint data"); @@ -481,11 +467,11 @@ void AnalysisDataTestFixture::setupArrayData(const AnalysisDataTestInput &input, data->allocateValues(); for (int row = 0; row < input.frameCount(); ++row) { - const AnalysisDataTestInputFrame &frame = input.frame(row); + const AnalysisDataTestInputFrame& frame = input.frame(row); EXPECT_FLOAT_EQ(frame.x(), data->xvalue(row)); GMX_RELEASE_ASSERT(frame.pointSetCount() == 1, "Multiple point sets not supported by array data"); - const AnalysisDataTestInputPointSet &points = frame.pointSet(0); + const AnalysisDataTestInputPointSet& points = frame.pointSet(0); for (int column = 0; column < points.size(); ++column) { data->value(row, column + points.firstColumn()) = points.value(column); diff --git a/src/gromacs/analysisdata/tests/histogram.cpp b/src/gromacs/analysisdata/tests/histogram.cpp index 3fef0ef42c..8721d6b1d5 100644 --- a/src/gromacs/analysisdata/tests/histogram.cpp +++ b/src/gromacs/analysisdata/tests/histogram.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,8 +72,7 @@ namespace TEST(AnalysisHistogramSettingsTest, InitializesFromBins) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromBins(1.0, 5, 0.5)); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromBins(1.0, 5, 0.5)); EXPECT_FLOAT_EQ(1.0, settings.firstEdge()); EXPECT_EQ(5, settings.binCount()); EXPECT_FLOAT_EQ(0.5, settings.binWidth()); @@ -83,8 +82,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromBins) TEST(AnalysisHistogramSettingsTest, InitializesFromBinsWithIntegerBins) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromBins(1.0, 5, 0.5).integerBins()); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromBins(1.0, 5, 0.5).integerBins()); EXPECT_FLOAT_EQ(0.75, settings.firstEdge()); EXPECT_EQ(5, settings.binCount()); EXPECT_FLOAT_EQ(0.5, settings.binWidth()); @@ -94,8 +92,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromBinsWithIntegerBins) TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCount) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromRange(1.0, 4.0).binCount(6)); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromRange(1.0, 4.0).binCount(6)); EXPECT_FLOAT_EQ(1.0, settings.firstEdge()); EXPECT_FLOAT_EQ(4.0, settings.lastEdge()); EXPECT_EQ(6, settings.binCount()); @@ -105,8 +102,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCount) TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidth) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromRange(1.0, 4.0).binWidth(0.5)); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromRange(1.0, 4.0).binWidth(0.5)); EXPECT_FLOAT_EQ(1.0, settings.firstEdge()); EXPECT_FLOAT_EQ(4.0, settings.lastEdge()); EXPECT_FLOAT_EQ(0.5, settings.binWidth()); @@ -116,8 +112,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidth) TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCountAndIntegerBins) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromRange(1.0, 4.0).binCount(7).integerBins()); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromRange(1.0, 4.0).binCount(7).integerBins()); EXPECT_FLOAT_EQ(0.75, settings.firstEdge()); EXPECT_FLOAT_EQ(4.25, settings.lastEdge()); EXPECT_EQ(7, settings.binCount()); @@ -127,8 +122,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinCountAndIntegerBi TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidthAndIntegerBins) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromRange(1.0, 4.0).binWidth(0.5).integerBins()); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromRange(1.0, 4.0).binWidth(0.5).integerBins()); EXPECT_FLOAT_EQ(0.75, settings.firstEdge()); EXPECT_FLOAT_EQ(4.25, settings.lastEdge()); EXPECT_FLOAT_EQ(0.5, settings.binWidth()); @@ -138,8 +132,7 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithBinWidthAndIntegerBi TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithRoundedRange) { - gmx::AnalysisHistogramSettings settings( - gmx::histogramFromRange(1.2, 3.8).binWidth(0.5).roundRange()); + gmx::AnalysisHistogramSettings settings(gmx::histogramFromRange(1.2, 3.8).binWidth(0.5).roundRange()); EXPECT_FLOAT_EQ(1.0, settings.firstEdge()); EXPECT_FLOAT_EQ(4.0, settings.lastEdge()); EXPECT_FLOAT_EQ(0.5, settings.binWidth()); @@ -157,56 +150,54 @@ typedef gmx::test::AnalysisDataTestFixture SimpleHistogramModuleTest; // Input data for gmx::AnalysisDataSimpleHistogramModule tests. class SimpleInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static SimpleInputData singleton; - return singleton.data_; + static SimpleInputData singleton; + return singleton.data_; #else - static SimpleInputData singleton_histogram; - return singleton_histogram.data_; + static SimpleInputData singleton_histogram; + return singleton_histogram.data_; #endif - } - - SimpleInputData() : data_(1, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 1); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.7); - frame1.addPointSetWithValues(0, 0, 1.1); - frame1.addPointSetWithValues(0, 0, 2.3); - frame1.addPointSetWithValues(0, 0, 2.9); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.3); - frame2.addPointSetWithValues(0, 0, 2.2); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 3.3); - frame3.addPointSetWithValues(0, 0, 1.2); - frame3.addPointSetWithValues(0, 0, 1.3); - } - - private: - AnalysisDataTestInput data_; + } + + SimpleInputData() : data_(1, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 1); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.7); + frame1.addPointSetWithValues(0, 0, 1.1); + frame1.addPointSetWithValues(0, 0, 2.3); + frame1.addPointSetWithValues(0, 0, 2.9); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.3); + frame2.addPointSetWithValues(0, 0, 2.2); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 3.3); + frame3.addPointSetWithValues(0, 0, 1.2); + frame3.addPointSetWithValues(0, 0, 1.3); + } + +private: + AnalysisDataTestInput data_; }; TEST_F(SimpleHistogramModuleTest, ComputesCorrectly) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); gmx::AnalysisDataSimpleHistogramModulePointer module( - new gmx::AnalysisDataSimpleHistogramModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4))); + new gmx::AnalysisDataSimpleHistogramModule(gmx::histogramFromRange(1.0, 3.0).binCount(4))); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("Histogram", module.get())); - ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", - &module->averager())); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", &module->averager())); ASSERT_NO_THROW_GMX(presentAllData(input, &data)); ASSERT_NO_THROW_GMX(module->averager().done()); } @@ -214,20 +205,18 @@ TEST_F(SimpleHistogramModuleTest, ComputesCorrectly) TEST_F(SimpleHistogramModuleTest, ComputesCorrectlyWithAll) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataSimpleHistogramModulePointer module( - new gmx::AnalysisDataSimpleHistogramModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); + gmx::AnalysisDataSimpleHistogramModulePointer module(new gmx::AnalysisDataSimpleHistogramModule( + gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("Histogram", module.get())); - ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", - &module->averager())); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", &module->averager())); ASSERT_NO_THROW_GMX(presentAllData(input, &data)); ASSERT_NO_THROW_GMX(module->averager().done()); } @@ -243,94 +232,92 @@ typedef gmx::test::AnalysisDataTestFixture WeightedHistogramModuleTest; // Input data for both weighted histogram and bin average module tests. class WeightedSimpleInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static WeightedSimpleInputData singleton; - return singleton.data_; + static WeightedSimpleInputData singleton; + return singleton.data_; #else - static WeightedSimpleInputData singleton_histogram; - return singleton_histogram.data_; + static WeightedSimpleInputData singleton_histogram; + return singleton_histogram.data_; #endif - } - - WeightedSimpleInputData() : data_(1, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.7, 0.5); - frame1.addPointSetWithValues(0, 0, 1.1, 1.0); - frame1.addPointSetWithValues(0, 0, 2.3, 1.0); - frame1.addPointSetWithValues(0, 0, 2.9, 2.0); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.3, 1.0); - frame2.addPointSetWithValues(0, 0, 2.2, 3.0); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 3.3, 0.5); - frame3.addPointSetWithValues(0, 0, 1.2, 2.0); - frame3.addPointSetWithValues(0, 0, 1.3, 1.0); - } - - private: - AnalysisDataTestInput data_; + } + + WeightedSimpleInputData() : data_(1, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.7, 0.5); + frame1.addPointSetWithValues(0, 0, 1.1, 1.0); + frame1.addPointSetWithValues(0, 0, 2.3, 1.0); + frame1.addPointSetWithValues(0, 0, 2.9, 2.0); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.3, 1.0); + frame2.addPointSetWithValues(0, 0, 2.2, 3.0); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 3.3, 0.5); + frame3.addPointSetWithValues(0, 0, 1.2, 2.0); + frame3.addPointSetWithValues(0, 0, 1.3, 1.0); + } + +private: + AnalysisDataTestInput data_; }; // Input data for both weighted histogram and bin average module tests. class WeightedDataSetInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static WeightedDataSetInputData singleton; - return singleton.data_; + static WeightedDataSetInputData singleton; + return singleton.data_; #else - static WeightedDataSetInputData singleton_histogram; - return singleton_histogram.data_; + static WeightedDataSetInputData singleton_histogram; + return singleton_histogram.data_; #endif - } - - WeightedDataSetInputData() : data_(2, true) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 2); - data_.setColumnCount(1, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 0.7, 0.5); - frame1.addPointSetWithValues(0, 0, 1.1, 1.0); - frame1.addPointSetWithValues(1, 0, 2.3, 1.0); - frame1.addPointSetWithValues(1, 0, 2.9, 2.0); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.3, 1.0); - frame2.addPointSetWithValues(1, 0, 2.2, 3.0); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 3.3, 0.5); - frame3.addPointSetWithValues(0, 0, 1.2, 2.0); - frame3.addPointSetWithValues(1, 0, 1.3, 1.0); - } - - private: - AnalysisDataTestInput data_; + } + + WeightedDataSetInputData() : data_(2, true) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 2); + data_.setColumnCount(1, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 0.7, 0.5); + frame1.addPointSetWithValues(0, 0, 1.1, 1.0); + frame1.addPointSetWithValues(1, 0, 2.3, 1.0); + frame1.addPointSetWithValues(1, 0, 2.9, 2.0); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.3, 1.0); + frame2.addPointSetWithValues(1, 0, 2.2, 3.0); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 3.3, 0.5); + frame3.addPointSetWithValues(0, 0, 1.2, 2.0); + frame3.addPointSetWithValues(1, 0, 1.3, 1.0); + } + +private: + AnalysisDataTestInput data_; }; TEST_F(WeightedHistogramModuleTest, ComputesCorrectly) { - const AnalysisDataTestInput &input = WeightedSimpleInputData::get(); + const AnalysisDataTestInput& input = WeightedSimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); gmx::AnalysisDataWeightedHistogramModulePointer module( - new gmx::AnalysisDataWeightedHistogramModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4))); + new gmx::AnalysisDataWeightedHistogramModule(gmx::histogramFromRange(1.0, 3.0).binCount(4))); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("Histogram", module.get())); - ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", - &module->averager())); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", &module->averager())); ASSERT_NO_THROW_GMX(presentAllData(input, &data)); ASSERT_NO_THROW_GMX(module->averager().done()); } @@ -338,20 +325,18 @@ TEST_F(WeightedHistogramModuleTest, ComputesCorrectly) TEST_F(WeightedHistogramModuleTest, ComputesCorrectlyWithAll) { - const AnalysisDataTestInput &input = WeightedSimpleInputData::get(); + const AnalysisDataTestInput& input = WeightedSimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataWeightedHistogramModulePointer module( - new gmx::AnalysisDataWeightedHistogramModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); + gmx::AnalysisDataWeightedHistogramModulePointer module(new gmx::AnalysisDataWeightedHistogramModule( + gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("Histogram", module.get())); - ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", - &module->averager())); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", &module->averager())); ASSERT_NO_THROW_GMX(presentAllData(input, &data)); ASSERT_NO_THROW_GMX(module->averager().done()); } @@ -359,20 +344,18 @@ TEST_F(WeightedHistogramModuleTest, ComputesCorrectlyWithAll) TEST_F(WeightedHistogramModuleTest, HandlesMultipleDataSets) { - const AnalysisDataTestInput &input = WeightedDataSetInputData::get(); + const AnalysisDataTestInput& input = WeightedDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); gmx::AnalysisDataWeightedHistogramModulePointer module( - new gmx::AnalysisDataWeightedHistogramModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4))); + new gmx::AnalysisDataWeightedHistogramModule(gmx::histogramFromRange(1.0, 3.0).binCount(4))); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("InputData", &data)); ASSERT_NO_THROW_GMX(addReferenceCheckerModule("Histogram", module.get())); - ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", - &module->averager())); + ASSERT_NO_THROW_GMX(addReferenceCheckerModule("HistogramAverage", &module->averager())); ASSERT_NO_THROW_GMX(presentAllData(input, &data)); ASSERT_NO_THROW_GMX(module->averager().done()); } @@ -387,13 +370,12 @@ typedef gmx::test::AnalysisDataTestFixture BinAverageModuleTest; TEST_F(BinAverageModuleTest, ComputesCorrectly) { - const AnalysisDataTestInput &input = WeightedSimpleInputData::get(); + const AnalysisDataTestInput& input = WeightedSimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); gmx::AnalysisDataBinAverageModulePointer module( - new gmx::AnalysisDataBinAverageModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4))); + new gmx::AnalysisDataBinAverageModule(gmx::histogramFromRange(1.0, 3.0).binCount(4))); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -405,13 +387,12 @@ TEST_F(BinAverageModuleTest, ComputesCorrectly) TEST_F(BinAverageModuleTest, ComputesCorrectlyWithAll) { - const AnalysisDataTestInput &input = WeightedSimpleInputData::get(); + const AnalysisDataTestInput& input = WeightedSimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataBinAverageModulePointer module( - new gmx::AnalysisDataBinAverageModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); + gmx::AnalysisDataBinAverageModulePointer module(new gmx::AnalysisDataBinAverageModule( + gmx::histogramFromRange(1.0, 3.0).binCount(4).includeAll())); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -423,13 +404,12 @@ TEST_F(BinAverageModuleTest, ComputesCorrectlyWithAll) TEST_F(BinAverageModuleTest, HandlesMultipleDataSets) { - const AnalysisDataTestInput &input = WeightedDataSetInputData::get(); + const AnalysisDataTestInput& input = WeightedDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); gmx::AnalysisDataBinAverageModulePointer module( - new gmx::AnalysisDataBinAverageModule( - gmx::histogramFromRange(1.0, 3.0).binCount(4))); + new gmx::AnalysisDataBinAverageModule(gmx::histogramFromRange(1.0, 3.0).binCount(4))); data.addModule(module); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -452,32 +432,32 @@ typedef gmx::test::AnalysisDataTestFixture AbstractAverageHistogramTest; // Input data for gmx::AbstractAverageHistogram tests. class AverageInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static AverageInputData singleton; - return singleton.data_; + static AverageInputData singleton; + return singleton.data_; #else - static AverageInputData singleton_histogram; - return singleton_histogram.data_; + static AverageInputData singleton_histogram; + return singleton_histogram.data_; #endif - } - - AverageInputData() : data_(1, false) - { - data_.setColumnCount(0, 1); - data_.addFrameWithValueAndError(1.0, 2.0, 1.0); - data_.addFrameWithValueAndError(1.5, 1.0, 1.0); - data_.addFrameWithValueAndError(2.0, 3.0, 2.0); - data_.addFrameWithValueAndError(2.5, 4.0, 2.0); - data_.addFrameWithValueAndError(3.0, 2.0, 1.0); - data_.addFrameWithValueAndError(3.5, 0.0, 3.0); - data_.addFrameWithValueAndError(4.0, 1.0, 3.0); - } - - private: - AnalysisDataTestInput data_; + } + + AverageInputData() : data_(1, false) + { + data_.setColumnCount(0, 1); + data_.addFrameWithValueAndError(1.0, 2.0, 1.0); + data_.addFrameWithValueAndError(1.5, 1.0, 1.0); + data_.addFrameWithValueAndError(2.0, 3.0, 2.0); + data_.addFrameWithValueAndError(2.5, 4.0, 2.0); + data_.addFrameWithValueAndError(3.0, 2.0, 1.0); + data_.addFrameWithValueAndError(3.5, 0.0, 3.0); + data_.addFrameWithValueAndError(4.0, 1.0, 3.0); + } + +private: + AnalysisDataTestInput data_; }; /*! \brief @@ -490,26 +470,25 @@ class AverageInputData */ class MockAverageHistogram : public gmx::AbstractAverageHistogram { - public: - //! Creates a histogram module with defined bin parameters. - explicit MockAverageHistogram(const gmx::AnalysisHistogramSettings &settings) - : AbstractAverageHistogram(settings) - { - } - - using AbstractAverageHistogram::init; - using AbstractAverageHistogram::setColumnCount; - using AbstractAverageHistogram::setRowCount; - using AbstractAverageHistogram::allocateValues; - using AbstractAverageHistogram::value; +public: + //! Creates a histogram module with defined bin parameters. + explicit MockAverageHistogram(const gmx::AnalysisHistogramSettings& settings) : + AbstractAverageHistogram(settings) + { + } + + using AbstractAverageHistogram::allocateValues; + using AbstractAverageHistogram::init; + using AbstractAverageHistogram::setColumnCount; + using AbstractAverageHistogram::setRowCount; + using AbstractAverageHistogram::value; }; TEST_F(AbstractAverageHistogramTest, ClonesCorrectly) { - const AnalysisDataTestInput &input = AverageInputData::get(); - MockAverageHistogram data( - gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); + const AnalysisDataTestInput& input = AverageInputData::get(); + MockAverageHistogram data(gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); setupArrayData(input, &data); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -525,9 +504,8 @@ TEST_F(AbstractAverageHistogramTest, ClonesCorrectly) TEST_F(AbstractAverageHistogramTest, ComputesCumulativeHistogram) { - const AnalysisDataTestInput &input = AverageInputData::get(); - MockAverageHistogram data( - gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); + const AnalysisDataTestInput& input = AverageInputData::get(); + MockAverageHistogram data(gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); setupArrayData(input, &data); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -543,9 +521,8 @@ TEST_F(AbstractAverageHistogramTest, ComputesCumulativeHistogram) TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth) { - const AnalysisDataTestInput &input = AverageInputData::get(); - MockAverageHistogram data( - gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); + const AnalysisDataTestInput& input = AverageInputData::get(); + MockAverageHistogram data(gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); setupArrayData(input, &data); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); @@ -559,9 +536,8 @@ TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth) TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidthWithIntegerBins) { - const AnalysisDataTestInput &input = AverageInputData::get(); - MockAverageHistogram data( - gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); + const AnalysisDataTestInput& input = AverageInputData::get(); + MockAverageHistogram data(gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins()); setupArrayData(input, &data); ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data)); diff --git a/src/gromacs/analysisdata/tests/lifetime.cpp b/src/gromacs/analysisdata/tests/lifetime.cpp index 1549d2a89a..cc4f1be913 100644 --- a/src/gromacs/analysisdata/tests/lifetime.cpp +++ b/src/gromacs/analysisdata/tests/lifetime.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,63 +64,63 @@ namespace // Simple input data for gmx::AnalysisDataLifetimeModule tests. class SimpleInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static SimpleInputData singleton; - return singleton.data_; + static SimpleInputData singleton; + return singleton.data_; #else - static SimpleInputData singleton_lifetime; - return singleton_lifetime.data_; + static SimpleInputData singleton_lifetime; + return singleton_lifetime.data_; #endif - } - - SimpleInputData() : data_(1, false) - { - data_.setColumnCount(0, 3); - data_.addFrameWithValues(1.0, 1.0, 1.0, 1.0); - data_.addFrameWithValues(2.0, 1.0, 0.0, 1.0); - data_.addFrameWithValues(3.0, 0.0, 1.0, 1.0); - } - - private: - AnalysisDataTestInput data_; + } + + SimpleInputData() : data_(1, false) + { + data_.setColumnCount(0, 3); + data_.addFrameWithValues(1.0, 1.0, 1.0, 1.0); + data_.addFrameWithValues(2.0, 1.0, 0.0, 1.0); + data_.addFrameWithValues(3.0, 0.0, 1.0, 1.0); + } + +private: + AnalysisDataTestInput data_; }; // Input data with multiple data sets for gmx::AnalysisDataLifetimeModule tests. class MultiDataSetInputData { - public: - static const AnalysisDataTestInput &get() - { +public: + static const AnalysisDataTestInput& get() + { #ifndef STATIC_ANON_NAMESPACE_BUG - static MultiDataSetInputData singleton; - return singleton.data_; + static MultiDataSetInputData singleton; + return singleton.data_; #else - static MultiDataSetInputData singleton_lifetime; - return singleton_lifetime.data_; + static MultiDataSetInputData singleton_lifetime; + return singleton_lifetime.data_; #endif - } - - MultiDataSetInputData() : data_(2, false) - { - using gmx::test::AnalysisDataTestInputFrame; - data_.setColumnCount(0, 2); - data_.setColumnCount(1, 2); - AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0); - frame1.addPointSetWithValues(0, 0, 1.0, 1.0); - frame1.addPointSetWithValues(1, 0, 0.0, 0.0); - AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0); - frame2.addPointSetWithValues(0, 0, 1.0, 0.0); - frame2.addPointSetWithValues(1, 0, 1.0, 0.0); - AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0); - frame3.addPointSetWithValues(0, 0, 1.0, 0.0); - frame3.addPointSetWithValues(1, 0, 1.0, 1.0); - } - - private: - AnalysisDataTestInput data_; + } + + MultiDataSetInputData() : data_(2, false) + { + using gmx::test::AnalysisDataTestInputFrame; + data_.setColumnCount(0, 2); + data_.setColumnCount(1, 2); + AnalysisDataTestInputFrame& frame1 = data_.addFrame(1.0); + frame1.addPointSetWithValues(0, 0, 1.0, 1.0); + frame1.addPointSetWithValues(1, 0, 0.0, 0.0); + AnalysisDataTestInputFrame& frame2 = data_.addFrame(2.0); + frame2.addPointSetWithValues(0, 0, 1.0, 0.0); + frame2.addPointSetWithValues(1, 0, 1.0, 0.0); + AnalysisDataTestInputFrame& frame3 = data_.addFrame(3.0); + frame3.addPointSetWithValues(0, 0, 1.0, 0.0); + frame3.addPointSetWithValues(1, 0, 1.0, 1.0); + } + +private: + AnalysisDataTestInput data_; }; @@ -133,12 +133,11 @@ typedef gmx::test::AnalysisDataTestFixture LifetimeModuleTest; TEST_F(LifetimeModuleTest, BasicTest) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataLifetimeModulePointer module( - new gmx::AnalysisDataLifetimeModule); + gmx::AnalysisDataLifetimeModulePointer module(new gmx::AnalysisDataLifetimeModule); module->setCumulative(false); data.addModule(module); @@ -150,12 +149,11 @@ TEST_F(LifetimeModuleTest, BasicTest) TEST_F(LifetimeModuleTest, CumulativeTest) { - const AnalysisDataTestInput &input = SimpleInputData::get(); + const AnalysisDataTestInput& input = SimpleInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataLifetimeModulePointer module( - new gmx::AnalysisDataLifetimeModule); + gmx::AnalysisDataLifetimeModulePointer module(new gmx::AnalysisDataLifetimeModule); module->setCumulative(true); data.addModule(module); @@ -167,12 +165,11 @@ TEST_F(LifetimeModuleTest, CumulativeTest) TEST_F(LifetimeModuleTest, HandlesMultipleDataSets) { - const AnalysisDataTestInput &input = MultiDataSetInputData::get(); + const AnalysisDataTestInput& input = MultiDataSetInputData::get(); gmx::AnalysisData data; ASSERT_NO_THROW_GMX(setupDataObject(input, &data)); - gmx::AnalysisDataLifetimeModulePointer module( - new gmx::AnalysisDataLifetimeModule); + gmx::AnalysisDataLifetimeModulePointer module(new gmx::AnalysisDataLifetimeModule); module->setCumulative(false); data.addModule(module); diff --git a/src/gromacs/analysisdata/tests/mock_datamodule.cpp b/src/gromacs/analysisdata/tests/mock_datamodule.cpp index b2551ca655..05046f5d40 100644 --- a/src/gromacs/analysisdata/tests/mock_datamodule.cpp +++ b/src/gromacs/analysisdata/tests/mock_datamodule.cpp @@ -71,65 +71,65 @@ namespace test */ class MockAnalysisDataModule::Impl { - public: - //! Initializes a mock object with the given flags. - explicit Impl(int flags); - - /*! \brief - * Callback used to initialize reference data checks - * - * Called in response to dataStarted(). - * Records the source data for later use (for access to data properties). - */ - void startReferenceData(AbstractAnalysisData *data); - /*! \brief - * Callback used to check frame start against reference data. - * - * Called to check parameters and order of calls to frameStarted(). - * In addition to reference data checks, this method checks statically - * that the new frame matches \a frameIndex_. - */ - void startReferenceFrame(const AnalysisDataFrameHeader &header); - /*! \brief - * Callback used to check frame points against reference data. - * - * Called to check parameters and order of calls to pointsAdded(). - */ - void checkReferencePoints(const AnalysisDataPointSetRef &points); - /*! \brief - * Callback used to check frame finish against reference data. - * - * Called to check parameters and order of calls to frameFinished(). - */ - void finishReferenceFrame(const AnalysisDataFrameHeader &header); - /*! \brief - * Callback used to check serial frame finish with reference data. - * - * Called to check parameters and order of calls to - * frameFinishedSerial(). - * \a frameIndex_ is incremented here. - */ - void finishReferenceFrameSerial(int frameIndex); - - /*! \brief - * Reference data checker to use for checking frames. - * - * Must be initialized if startReferenceFrame() is called. - */ - TestReferenceChecker rootChecker_; - /*! \brief - * Reference data checker to use to check the current frame. - * - * Initialized between startReferenceFrame() and finishReferenceFrame() - * calls. - */ - TestReferenceChecker frameChecker_; - //! Source data. - const AbstractAnalysisData *source_; - //! Flags that will be returned by the mock module. - int flags_; - //! Index of the current/next frame. - int frameIndex_; +public: + //! Initializes a mock object with the given flags. + explicit Impl(int flags); + + /*! \brief + * Callback used to initialize reference data checks + * + * Called in response to dataStarted(). + * Records the source data for later use (for access to data properties). + */ + void startReferenceData(AbstractAnalysisData* data); + /*! \brief + * Callback used to check frame start against reference data. + * + * Called to check parameters and order of calls to frameStarted(). + * In addition to reference data checks, this method checks statically + * that the new frame matches \a frameIndex_. + */ + void startReferenceFrame(const AnalysisDataFrameHeader& header); + /*! \brief + * Callback used to check frame points against reference data. + * + * Called to check parameters and order of calls to pointsAdded(). + */ + void checkReferencePoints(const AnalysisDataPointSetRef& points); + /*! \brief + * Callback used to check frame finish against reference data. + * + * Called to check parameters and order of calls to frameFinished(). + */ + void finishReferenceFrame(const AnalysisDataFrameHeader& header); + /*! \brief + * Callback used to check serial frame finish with reference data. + * + * Called to check parameters and order of calls to + * frameFinishedSerial(). + * \a frameIndex_ is incremented here. + */ + void finishReferenceFrameSerial(int frameIndex); + + /*! \brief + * Reference data checker to use for checking frames. + * + * Must be initialized if startReferenceFrame() is called. + */ + TestReferenceChecker rootChecker_; + /*! \brief + * Reference data checker to use to check the current frame. + * + * Initialized between startReferenceFrame() and finishReferenceFrame() + * calls. + */ + TestReferenceChecker frameChecker_; + //! Source data. + const AbstractAnalysisData* source_; + //! Flags that will be returned by the mock module. + int flags_; + //! Index of the current/next frame. + int frameIndex_; }; namespace @@ -140,8 +140,7 @@ namespace * * \ingroup module_analysisdata */ -void checkReferenceDataPoint(TestReferenceChecker *checker, - const AnalysisDataValue &value) +void checkReferenceDataPoint(TestReferenceChecker* checker, const AnalysisDataValue& value) { TestReferenceChecker compound(checker->checkCompound("DataValue", nullptr)); compound.checkReal(value.value(), "Value"); @@ -155,56 +154,45 @@ void checkReferenceDataPoint(TestReferenceChecker *checker, } } -} // namespace +} // namespace -MockAnalysisDataModule::Impl::Impl(int flags) - : source_(nullptr), flags_(flags), frameIndex_(0) -{ -} +MockAnalysisDataModule::Impl::Impl(int flags) : source_(nullptr), flags_(flags), frameIndex_(0) {} -void -MockAnalysisDataModule::Impl::startReferenceData(AbstractAnalysisData *data) +void MockAnalysisDataModule::Impl::startReferenceData(AbstractAnalysisData* data) { source_ = data; } -void -MockAnalysisDataModule::Impl::startReferenceFrame( - const AnalysisDataFrameHeader &header) +void MockAnalysisDataModule::Impl::startReferenceFrame(const AnalysisDataFrameHeader& header) { - GMX_RELEASE_ASSERT(rootChecker_, - "Root checker not set, but reference data used"); + GMX_RELEASE_ASSERT(rootChecker_, "Root checker not set, but reference data used"); EXPECT_FALSE(frameChecker_.isValid()); EXPECT_EQ(frameIndex_, header.index()); - frameChecker_ = rootChecker_.checkCompound("DataFrame", - formatString("Frame%d", frameIndex_).c_str()); + frameChecker_ = + rootChecker_.checkCompound("DataFrame", formatString("Frame%d", frameIndex_).c_str()); frameChecker_.checkReal(header.x(), "X"); } -void -MockAnalysisDataModule::Impl::checkReferencePoints( - const AnalysisDataPointSetRef &points) +void MockAnalysisDataModule::Impl::checkReferencePoints(const AnalysisDataPointSetRef& points) { EXPECT_TRUE(frameChecker_.isValid()); if (frameChecker_) { - TestReferenceChecker checker( - frameChecker_.checkCompound("DataValues", nullptr)); + TestReferenceChecker checker(frameChecker_.checkCompound("DataValues", nullptr)); checker.checkInteger(points.columnCount(), "Count"); if (checker.checkPresent(source_->dataSetCount() > 1, "DataSet")) { checker.checkInteger(points.dataSetIndex(), "DataSet"); } - const int sourceColumnCount = source_->columnCount(points.dataSetIndex()); - const bool bAllColumns = (points.firstColumn() == 0 - && points.columnCount() == sourceColumnCount); + const int sourceColumnCount = source_->columnCount(points.dataSetIndex()); + const bool bAllColumns = (points.firstColumn() == 0 && points.columnCount() == sourceColumnCount); if (checker.checkPresent(!bAllColumns, "FirstColumn")) { checker.checkInteger(points.firstColumn(), "FirstColumn"); - checker.checkInteger(points.lastColumn(), "LastColumn"); + checker.checkInteger(points.lastColumn(), "LastColumn"); } AnalysisDataValuesRef::const_iterator value; @@ -216,9 +204,7 @@ MockAnalysisDataModule::Impl::checkReferencePoints( } -void -MockAnalysisDataModule::Impl::finishReferenceFrame( - const AnalysisDataFrameHeader &header) +void MockAnalysisDataModule::Impl::finishReferenceFrame(const AnalysisDataFrameHeader& header) { EXPECT_TRUE(frameChecker_.isValid()); EXPECT_EQ(frameIndex_, header.index()); @@ -226,8 +212,7 @@ MockAnalysisDataModule::Impl::finishReferenceFrame( } -void -MockAnalysisDataModule::Impl::finishReferenceFrameSerial(int frameIndex) +void MockAnalysisDataModule::Impl::finishReferenceFrameSerial(int frameIndex) { EXPECT_FALSE(frameChecker_.isValid()); EXPECT_EQ(frameIndex_, frameIndex); @@ -248,8 +233,7 @@ namespace * \param[in] header Frame header to check. * \param[in] refFrame Data to check against. */ -void checkHeader(const AnalysisDataFrameHeader &header, - const AnalysisDataTestInputFrame &refFrame) +void checkHeader(const AnalysisDataFrameHeader& header, const AnalysisDataTestInputFrame& refFrame) { EXPECT_EQ(refFrame.index(), header.index()); EXPECT_FLOAT_EQ(refFrame.x(), header.x()); @@ -263,19 +247,18 @@ void checkHeader(const AnalysisDataFrameHeader &header, * \param[in] refPoints Data to check against. * \param[in] columnOffset Offset of first column of \p points in \p refPoints. */ -void checkPoints(const AnalysisDataPointSetRef &points, - const AnalysisDataTestInputPointSet &refPoints, +void checkPoints(const AnalysisDataPointSetRef& points, + const AnalysisDataTestInputPointSet& refPoints, int columnOffset) { for (int i = 0; i < points.columnCount(); ++i) { const int column = points.firstColumn() - refPoints.firstColumn() + i + columnOffset; - EXPECT_FLOAT_EQ(refPoints.y(column), - points.y(i)) - << " Column: " << i+1 << " / " << points.columnCount() - << " (+" << points.firstColumn() << ")\n" - << "Ref. col: " << column+1 << " / " << refPoints.size() - << " (+" << refPoints.firstColumn() << ", offs " << columnOffset << ")"; + EXPECT_FLOAT_EQ(refPoints.y(column), points.y(i)) + << " Column: " << i + 1 << " / " << points.columnCount() << " (+" + << points.firstColumn() << ")\n" + << "Ref. col: " << column + 1 << " / " << refPoints.size() << " (+" + << refPoints.firstColumn() << ", offs " << columnOffset << ")"; } } @@ -285,15 +268,14 @@ void checkPoints(const AnalysisDataPointSetRef &points, * \param[in] frame Frame to check. * \param[in] refFrame Data to check against. */ -void checkFrame(const AnalysisDataFrameRef &frame, - const AnalysisDataTestInputFrame &refFrame) +void checkFrame(const AnalysisDataFrameRef& frame, const AnalysisDataTestInputFrame& refFrame) { checkHeader(frame.header(), refFrame); ASSERT_EQ(refFrame.pointSetCount(), frame.pointSetCount()); for (int i = 0; i < frame.pointSetCount(); ++i) { - const AnalysisDataPointSetRef &points = frame.pointSet(i); - const AnalysisDataTestInputPointSet &refPoints = refFrame.pointSet(i); + const AnalysisDataPointSetRef& points = frame.pointSet(i); + const AnalysisDataTestInputPointSet& refPoints = refFrame.pointSet(i); EXPECT_EQ(refPoints.firstColumn(), points.firstColumn()); checkPoints(points, refPoints, 0); } @@ -307,28 +289,25 @@ void checkFrame(const AnalysisDataFrameRef &frame, */ class StaticDataFrameHeaderChecker { - public: - /*! \brief - * Constructs a checker against a given input data frame. - * - * \param[in] frame Frame to check against. - * - * \p frame must exist for the lifetime of this object. - */ - StaticDataFrameHeaderChecker(const AnalysisDataTestInputFrame *frame) - : frame_(frame) - { - } - - //! Function call operator for the functor. - void operator()(const AnalysisDataFrameHeader &header) const - { - SCOPED_TRACE(formatString("Frame %d", frame_->index())); - checkHeader(header, *frame_); - } +public: + /*! \brief + * Constructs a checker against a given input data frame. + * + * \param[in] frame Frame to check against. + * + * \p frame must exist for the lifetime of this object. + */ + StaticDataFrameHeaderChecker(const AnalysisDataTestInputFrame* frame) : frame_(frame) {} + + //! Function call operator for the functor. + void operator()(const AnalysisDataFrameHeader& header) const + { + SCOPED_TRACE(formatString("Frame %d", frame_->index())); + checkHeader(header, *frame_); + } - private: - const AnalysisDataTestInputFrame *frame_; +private: + const AnalysisDataTestInputFrame* frame_; }; /*! \brief @@ -339,47 +318,48 @@ class StaticDataFrameHeaderChecker */ class StaticDataPointsChecker { - public: - /*! \brief - * Constructs a checker against a given input data frame and point set. - * - * \param[in] frame Frame to check against. - * \param[in] points Point set in \p frame to check against. - * \param[in] firstcol Expected first column. - * \param[in] n Expected number of columns. - * - * \p firstcol and \p n are used to create a checker that only expects - * to be called for a subset of columns. - * \p frame and \p points must exist for the lifetime of this object. - */ - StaticDataPointsChecker(const AnalysisDataTestInputFrame *frame, - const AnalysisDataTestInputPointSet *points, - int firstcol, int n) - : frame_(frame), points_(points), firstcol_(firstcol), n_(n) - { - } +public: + /*! \brief + * Constructs a checker against a given input data frame and point set. + * + * \param[in] frame Frame to check against. + * \param[in] points Point set in \p frame to check against. + * \param[in] firstcol Expected first column. + * \param[in] n Expected number of columns. + * + * \p firstcol and \p n are used to create a checker that only expects + * to be called for a subset of columns. + * \p frame and \p points must exist for the lifetime of this object. + */ + StaticDataPointsChecker(const AnalysisDataTestInputFrame* frame, + const AnalysisDataTestInputPointSet* points, + int firstcol, + int n) : + frame_(frame), + points_(points), + firstcol_(firstcol), + n_(n) + { + } - //! Function call operator for the functor. - void operator()(const AnalysisDataPointSetRef &points) const - { - SCOPED_TRACE(formatString("Frame %d, point set %d", - frame_->index(), points_->index())); - EXPECT_EQ(points_->dataSetIndex(), points.dataSetIndex()); - const int expectedFirstColumn - = std::max(0, points_->firstColumn() - firstcol_); - const int expectedLastColumn - = std::min(n_ - 1, points_->lastColumn() - firstcol_); - EXPECT_EQ(expectedFirstColumn, points.firstColumn()); - EXPECT_EQ(expectedLastColumn, points.lastColumn()); - checkHeader(points.header(), *frame_); - checkPoints(points, *points_, firstcol_); - } + //! Function call operator for the functor. + void operator()(const AnalysisDataPointSetRef& points) const + { + SCOPED_TRACE(formatString("Frame %d, point set %d", frame_->index(), points_->index())); + EXPECT_EQ(points_->dataSetIndex(), points.dataSetIndex()); + const int expectedFirstColumn = std::max(0, points_->firstColumn() - firstcol_); + const int expectedLastColumn = std::min(n_ - 1, points_->lastColumn() - firstcol_); + EXPECT_EQ(expectedFirstColumn, points.firstColumn()); + EXPECT_EQ(expectedLastColumn, points.lastColumn()); + checkHeader(points.header(), *frame_); + checkPoints(points, *points_, firstcol_); + } - private: - const AnalysisDataTestInputFrame *frame_; - const AnalysisDataTestInputPointSet *points_; - int firstcol_; - int n_; +private: + const AnalysisDataTestInputFrame* frame_; + const AnalysisDataTestInputPointSet* points_; + int firstcol_; + int n_; }; /*! \brief @@ -390,25 +370,22 @@ class StaticDataPointsChecker */ class DataStorageRequester { - public: - /*! \brief - * Constructs a functor that requests the given amount of storage. - * - * \param[in] count Number of frames of storage to request, or - * -1 for all frames. - * - * \see AbstractAnalysisData::requestStorage() - */ - explicit DataStorageRequester(int count) : count_(count) {} - - //! Function call operator for the functor. - void operator()(AbstractAnalysisData *data) const - { - EXPECT_TRUE(data->requestStorage(count_)); - } - - private: - int count_; +public: + /*! \brief + * Constructs a functor that requests the given amount of storage. + * + * \param[in] count Number of frames of storage to request, or + * -1 for all frames. + * + * \see AbstractAnalysisData::requestStorage() + */ + explicit DataStorageRequester(int count) : count_(count) {} + + //! Function call operator for the functor. + void operator()(AbstractAnalysisData* data) const { EXPECT_TRUE(data->requestStorage(count_)); } + +private: + int count_; }; /*! \brief @@ -420,65 +397,66 @@ class DataStorageRequester */ class StaticDataPointsStorageChecker { - public: - /*! \brief - * Constructs a checker for a given frame. - * - * \param[in] source Data object that is being checked. - * \param[in] data Test input data to check against. - * \param[in] frameIndex Frame index for which this functor expects - * to be called. - * \param[in] pointSetIndex Point set for which this functor expects - * to be called. - * \param[in] storageCount How many past frames should be checked for - * storage (-1 = check all frames). - * - * This checker works as StaticDataPointsChecker, but additionally - * checks that previous frames can be accessed using access methods - * in AbstractAnalysisData and that correct data is returned. - * - * \p source and \p data must exist for the lifetime of this object. - */ - StaticDataPointsStorageChecker(AbstractAnalysisData *source, - const AnalysisDataTestInput *data, - int frameIndex, int pointSetIndex, - int storageCount) - : source_(source), data_(data), - frameIndex_(frameIndex), pointSetIndex_(pointSetIndex), - storageCount_(storageCount) - { - } +public: + /*! \brief + * Constructs a checker for a given frame. + * + * \param[in] source Data object that is being checked. + * \param[in] data Test input data to check against. + * \param[in] frameIndex Frame index for which this functor expects + * to be called. + * \param[in] pointSetIndex Point set for which this functor expects + * to be called. + * \param[in] storageCount How many past frames should be checked for + * storage (-1 = check all frames). + * + * This checker works as StaticDataPointsChecker, but additionally + * checks that previous frames can be accessed using access methods + * in AbstractAnalysisData and that correct data is returned. + * + * \p source and \p data must exist for the lifetime of this object. + */ + StaticDataPointsStorageChecker(AbstractAnalysisData* source, + const AnalysisDataTestInput* data, + int frameIndex, + int pointSetIndex, + int storageCount) : + source_(source), + data_(data), + frameIndex_(frameIndex), + pointSetIndex_(pointSetIndex), + storageCount_(storageCount) + { + } - //! Function call operator for the functor. - void operator()(const AnalysisDataPointSetRef &points) const + //! Function call operator for the functor. + void operator()(const AnalysisDataPointSetRef& points) const + { + SCOPED_TRACE(formatString("Frame %d", frameIndex_)); + const AnalysisDataTestInputFrame& refFrame = data_->frame(frameIndex_); + const AnalysisDataTestInputPointSet& refPoints = refFrame.pointSet(pointSetIndex_); + EXPECT_EQ(refPoints.firstColumn(), points.firstColumn()); + EXPECT_EQ(refPoints.size(), points.columnCount()); + checkHeader(points.header(), refFrame); + checkPoints(points, refPoints, 0); + for (int past = 1; (storageCount_ < 0 || past <= storageCount_) && past <= frameIndex_; ++past) { - SCOPED_TRACE(formatString("Frame %d", frameIndex_)); - const AnalysisDataTestInputFrame &refFrame = data_->frame(frameIndex_); - const AnalysisDataTestInputPointSet &refPoints = refFrame.pointSet(pointSetIndex_); - EXPECT_EQ(refPoints.firstColumn(), points.firstColumn()); - EXPECT_EQ(refPoints.size(), points.columnCount()); - checkHeader(points.header(), refFrame); - checkPoints(points, refPoints, 0); - for (int past = 1; - (storageCount_ < 0 || past <= storageCount_) && past <= frameIndex_; - ++past) - { - int index = frameIndex_ - past; - SCOPED_TRACE(formatString("Checking storage of frame %d", index)); - ASSERT_NO_THROW_GMX({ - AnalysisDataFrameRef frame = source_->getDataFrame(index); - ASSERT_TRUE(frame.isValid()); - checkFrame(frame, data_->frame(index)); - }); - } + int index = frameIndex_ - past; + SCOPED_TRACE(formatString("Checking storage of frame %d", index)); + ASSERT_NO_THROW_GMX({ + AnalysisDataFrameRef frame = source_->getDataFrame(index); + ASSERT_TRUE(frame.isValid()); + checkFrame(frame, data_->frame(index)); + }); } + } - private: - AbstractAnalysisData *source_; - const AnalysisDataTestInput *data_; - int frameIndex_; - int pointSetIndex_; - int storageCount_; +private: + AbstractAnalysisData* source_; + const AnalysisDataTestInput* data_; + int frameIndex_; + int pointSetIndex_; + int storageCount_; }; /*! \brief @@ -488,7 +466,7 @@ class StaticDataPointsStorageChecker * object was an AnalysisDataModuleSerial object: forward the call to * MockAnalysisDataModule::dataStarted() and return false. */ -void setSerialExpectationForParallelDataStarted(MockAnalysisDataModule *mock) +void setSerialExpectationForParallelDataStarted(MockAnalysisDataModule* mock) { using ::testing::_; using ::testing::AtMost; @@ -497,23 +475,17 @@ void setSerialExpectationForParallelDataStarted(MockAnalysisDataModule *mock) using ::testing::Return; using ::testing::WithArg; EXPECT_CALL(*mock, parallelDataStarted(_, _)) - .Times(AtMost(1)) - .WillOnce(DoAll(WithArg<0>(Invoke(mock, &MockAnalysisDataModule::dataStarted)), - Return(false))); + .Times(AtMost(1)) + .WillOnce(DoAll(WithArg<0>(Invoke(mock, &MockAnalysisDataModule::dataStarted)), Return(false))); } -} // anonymous namespace +} // anonymous namespace -MockAnalysisDataModule::MockAnalysisDataModule(int flags) - : impl_(new Impl(flags)) -{ -} +MockAnalysisDataModule::MockAnalysisDataModule(int flags) : impl_(new Impl(flags)) {} -MockAnalysisDataModule::~MockAnalysisDataModule() -{ -} +MockAnalysisDataModule::~MockAnalysisDataModule() {} int MockAnalysisDataModule::flags() const @@ -522,10 +494,9 @@ int MockAnalysisDataModule::flags() const } -void -MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data, - AbstractAnalysisData *source, - bool bParallel) +void MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput& data, + AbstractAnalysisData* source, + bool bParallel) { impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets; @@ -538,42 +509,39 @@ MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data, { #ifndef __clang_analyzer__ ::testing::Expectation init = - EXPECT_CALL(*this, parallelDataStarted(source, _)) - .WillOnce(Return(true)); + EXPECT_CALL(*this, parallelDataStarted(source, _)).WillOnce(Return(true)); ::testing::ExpectationSet framesFinished; ::testing::Expectation prevFinish; for (int row = 0; row < data.frameCount(); ++row) { - ::testing::InSequence frameSequence; - const AnalysisDataTestInputFrame &frame = data.frame(row); + ::testing::InSequence frameSequence; + const AnalysisDataTestInputFrame& frame = data.frame(row); EXPECT_CALL(*this, frameStarted(Property(&AnalysisDataFrameHeader::index, row))) - .After(init) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + .After(init) + .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); for (int ps = 0; ps < frame.pointSetCount(); ++ps) { - const AnalysisDataTestInputPointSet &points = frame.pointSet(ps); + const AnalysisDataTestInputPointSet& points = frame.pointSet(ps); StaticDataPointsChecker checker(&frame, &points, 0, - data.columnCount(points.dataSetIndex())); + data.columnCount(points.dataSetIndex())); EXPECT_CALL(*this, pointsAdded(Property(&AnalysisDataPointSetRef::frameIndex, row))) - .WillOnce(Invoke(checker)); + .WillOnce(Invoke(checker)); } EXPECT_CALL(*this, frameFinished(Property(&AnalysisDataFrameHeader::index, row))) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); ::testing::Expectation finish; if (row > 0) { - finish = EXPECT_CALL(*this, frameFinishedSerial(row)) - .After(prevFinish); + finish = EXPECT_CALL(*this, frameFinishedSerial(row)).After(prevFinish); } else { finish = EXPECT_CALL(*this, frameFinishedSerial(row)); } framesFinished += finish; - prevFinish = finish; + prevFinish = finish; } - EXPECT_CALL(*this, dataFinished()) - .After(framesFinished); + EXPECT_CALL(*this, dataFinished()).After(framesFinished); #endif } else @@ -583,18 +551,16 @@ MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data, EXPECT_CALL(*this, dataStarted(source)); for (int row = 0; row < data.frameCount(); ++row) { - const AnalysisDataTestInputFrame &frame = data.frame(row); - EXPECT_CALL(*this, frameStarted(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + const AnalysisDataTestInputFrame& frame = data.frame(row); + EXPECT_CALL(*this, frameStarted(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); for (int ps = 0; ps < frame.pointSetCount(); ++ps) { - const AnalysisDataTestInputPointSet &points = frame.pointSet(ps); + const AnalysisDataTestInputPointSet& points = frame.pointSet(ps); StaticDataPointsChecker checker(&frame, &points, 0, - data.columnCount(points.dataSetIndex())); + data.columnCount(points.dataSetIndex())); EXPECT_CALL(*this, pointsAdded(_)).WillOnce(Invoke(checker)); } - EXPECT_CALL(*this, frameFinished(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + EXPECT_CALL(*this, frameFinished(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); EXPECT_CALL(*this, frameFinishedSerial(row)); } EXPECT_CALL(*this, dataFinished()); @@ -602,10 +568,10 @@ MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data, } -void -MockAnalysisDataModule::setupStaticColumnCheck( - const AnalysisDataTestInput &data, - int firstcol, int n, AbstractAnalysisData * /*source*/) +void MockAnalysisDataModule::setupStaticColumnCheck(const AnalysisDataTestInput& data, + int firstcol, + int n, + AbstractAnalysisData* /*source*/) { impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets; @@ -617,31 +583,27 @@ MockAnalysisDataModule::setupStaticColumnCheck( EXPECT_CALL(*this, dataStarted(_)); for (int row = 0; row < data.frameCount(); ++row) { - const AnalysisDataTestInputFrame &frame = data.frame(row); - EXPECT_CALL(*this, frameStarted(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + const AnalysisDataTestInputFrame& frame = data.frame(row); + EXPECT_CALL(*this, frameStarted(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); for (int ps = 0; ps < frame.pointSetCount(); ++ps) { - const AnalysisDataTestInputPointSet &points = frame.pointSet(ps); - if (points.lastColumn() >= firstcol - && points.firstColumn() <= firstcol + n - 1) + const AnalysisDataTestInputPointSet& points = frame.pointSet(ps); + if (points.lastColumn() >= firstcol && points.firstColumn() <= firstcol + n - 1) { EXPECT_CALL(*this, pointsAdded(_)) - .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, firstcol, n))); + .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, firstcol, n))); } } - EXPECT_CALL(*this, frameFinished(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + EXPECT_CALL(*this, frameFinished(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); EXPECT_CALL(*this, frameFinishedSerial(row)); } EXPECT_CALL(*this, dataFinished()); } -void -MockAnalysisDataModule::setupStaticStorageCheck( - const AnalysisDataTestInput &data, - int storageCount, AbstractAnalysisData *source) +void MockAnalysisDataModule::setupStaticStorageCheck(const AnalysisDataTestInput& data, + int storageCount, + AbstractAnalysisData* source) { GMX_RELEASE_ASSERT(data.isMultipoint() == source->isMultipoint(), "Mismatching multipoint properties"); @@ -652,33 +614,27 @@ MockAnalysisDataModule::setupStaticStorageCheck( using ::testing::Invoke; setSerialExpectationForParallelDataStarted(this); - EXPECT_CALL(*this, dataStarted(source)) - .WillOnce(Invoke(DataStorageRequester(storageCount))); + EXPECT_CALL(*this, dataStarted(source)).WillOnce(Invoke(DataStorageRequester(storageCount))); for (int row = 0; row < data.frameCount(); ++row) { - const AnalysisDataTestInputFrame &frame = data.frame(row); - EXPECT_CALL(*this, frameStarted(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + const AnalysisDataTestInputFrame& frame = data.frame(row); + EXPECT_CALL(*this, frameStarted(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); for (int pointSet = 0; pointSet < frame.pointSetCount(); ++pointSet) { - StaticDataPointsStorageChecker checker(source, &data, row, pointSet, - storageCount); + StaticDataPointsStorageChecker checker(source, &data, row, pointSet, storageCount); EXPECT_CALL(*this, pointsAdded(_)).WillOnce(Invoke(checker)); } - EXPECT_CALL(*this, frameFinished(_)) - .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); + EXPECT_CALL(*this, frameFinished(_)).WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame))); EXPECT_CALL(*this, frameFinishedSerial(row)); } EXPECT_CALL(*this, dataFinished()); } -void -MockAnalysisDataModule::setupReferenceCheck(const TestReferenceChecker &checker, - AbstractAnalysisData *source) +void MockAnalysisDataModule::setupReferenceCheck(const TestReferenceChecker& checker, + AbstractAnalysisData* source) { - impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMissing - | efAllowMultipleDataSets; + impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMissing | efAllowMultipleDataSets; impl_->rootChecker_ = TestReferenceChecker(checker); // Google Mock does not support checking the order fully, because @@ -691,22 +647,22 @@ MockAnalysisDataModule::setupReferenceCheck(const TestReferenceChecker &checker, using ::testing::Invoke; setSerialExpectationForParallelDataStarted(this); - Expectation dataStart = EXPECT_CALL(*this, dataStarted(source)) - .WillOnce(Invoke(impl_.get(), &Impl::startReferenceData)); + Expectation dataStart = + EXPECT_CALL(*this, dataStarted(source)).WillOnce(Invoke(impl_.get(), &Impl::startReferenceData)); Expectation frameStart = EXPECT_CALL(*this, frameStarted(_)) - .After(dataStart) - .WillRepeatedly(Invoke(impl_.get(), &Impl::startReferenceFrame)); + .After(dataStart) + .WillRepeatedly(Invoke(impl_.get(), &Impl::startReferenceFrame)); Expectation pointsAdd = EXPECT_CALL(*this, pointsAdded(_)) - .After(dataStart) - .WillRepeatedly(Invoke(impl_.get(), &Impl::checkReferencePoints)); + .After(dataStart) + .WillRepeatedly(Invoke(impl_.get(), &Impl::checkReferencePoints)); Expectation frameFinish = EXPECT_CALL(*this, frameFinished(_)) - .After(dataStart) - .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrame)); - Expectation frameFinishSerial = EXPECT_CALL(*this, frameFinishedSerial(_)) - .After(dataStart) - .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrameSerial)); - EXPECT_CALL(*this, dataFinished()) - .After(frameStart, pointsAdd, frameFinish, frameFinishSerial); + .After(dataStart) + .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrame)); + Expectation frameFinishSerial = + EXPECT_CALL(*this, frameFinishedSerial(_)) + .After(dataStart) + .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrameSerial)); + EXPECT_CALL(*this, dataFinished()).After(frameStart, pointsAdd, frameFinish, frameFinishSerial); } } // namespace test diff --git a/src/gromacs/analysisdata/tests/mock_datamodule.h b/src/gromacs/analysisdata/tests/mock_datamodule.h index fb451e6ac7..24226093a6 100644 --- a/src/gromacs/analysisdata/tests/mock_datamodule.h +++ b/src/gromacs/analysisdata/tests/mock_datamodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,43 +64,36 @@ class TestReferenceChecker; class MockAnalysisDataModule : public IAnalysisDataModule { - public: - explicit MockAnalysisDataModule(int flags); - ~MockAnalysisDataModule() override; +public: + explicit MockAnalysisDataModule(int flags); + ~MockAnalysisDataModule() override; - int flags() const override; + int flags() const override; - MOCK_METHOD2(parallelDataStarted, - bool(AbstractAnalysisData *data, - const AnalysisDataParallelOptions &options)); - MOCK_METHOD1(dataStarted, void(AbstractAnalysisData *data)); - MOCK_METHOD1(frameStarted, void(const AnalysisDataFrameHeader &header)); - MOCK_METHOD1(pointsAdded, void(const AnalysisDataPointSetRef &points)); - MOCK_METHOD1(frameFinished, void(const AnalysisDataFrameHeader &header)); - MOCK_METHOD1(frameFinishedSerial, void(int frameIndex)); - MOCK_METHOD0(dataFinished, void()); + MOCK_METHOD2(parallelDataStarted, + bool(AbstractAnalysisData* data, const AnalysisDataParallelOptions& options)); + MOCK_METHOD1(dataStarted, void(AbstractAnalysisData* data)); + MOCK_METHOD1(frameStarted, void(const AnalysisDataFrameHeader& header)); + MOCK_METHOD1(pointsAdded, void(const AnalysisDataPointSetRef& points)); + MOCK_METHOD1(frameFinished, void(const AnalysisDataFrameHeader& header)); + MOCK_METHOD1(frameFinishedSerial, void(int frameIndex)); + MOCK_METHOD0(dataFinished, void()); - void setupStaticCheck(const AnalysisDataTestInput &data, - AbstractAnalysisData *source, - bool bParallel); - void setupStaticColumnCheck(const AnalysisDataTestInput &data, - int firstcol, int n, - AbstractAnalysisData *source); - void setupStaticStorageCheck(const AnalysisDataTestInput &data, - int storageCount, - AbstractAnalysisData *source); - void setupReferenceCheck(const TestReferenceChecker &checker, - AbstractAnalysisData *source); + void setupStaticCheck(const AnalysisDataTestInput& data, AbstractAnalysisData* source, bool bParallel); + void setupStaticColumnCheck(const AnalysisDataTestInput& data, int firstcol, int n, AbstractAnalysisData* source); + void setupStaticStorageCheck(const AnalysisDataTestInput& data, + int storageCount, + AbstractAnalysisData* source); + void setupReferenceCheck(const TestReferenceChecker& checker, AbstractAnalysisData* source); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; //! Smart pointer to manage an MockAnalysisDataModule object. -typedef std::shared_ptr - MockAnalysisDataModulePointer; +typedef std::shared_ptr MockAnalysisDataModulePointer; } // namespace test } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfitting.cpp b/src/gromacs/applied_forces/densityfitting.cpp index eb981f9ebf..2f34d12818 100644 --- a/src/gromacs/applied_forces/densityfitting.cpp +++ b/src/gromacs/applied_forces/densityfitting.cpp @@ -87,138 +87,133 @@ namespace */ class DensityFittingSimulationParameterSetup { - public: - DensityFittingSimulationParameterSetup() = default; - - /*! \brief Set the local atom set for the density fitting. - * \param[in] localAtomSet of atoms to be fitted - */ - void setLocalAtomSet(const LocalAtomSet &localAtomSet) +public: + DensityFittingSimulationParameterSetup() = default; + + /*! \brief Set the local atom set for the density fitting. + * \param[in] localAtomSet of atoms to be fitted + */ + void setLocalAtomSet(const LocalAtomSet& localAtomSet) + { + localAtomSet_ = std::make_unique(localAtomSet); + } + + /*! \brief Return local atom set for density fitting. + * \throws InternalError if local atom set is not set + * \returns local atom set for density fitting + */ + const LocalAtomSet& localAtomSet() const + { + if (localAtomSet_ == nullptr) { - localAtomSet_ = std::make_unique(localAtomSet); + GMX_THROW( + InternalError("Local atom set is not set for density " + "guided simulation.")); } - - /*! \brief Return local atom set for density fitting. - * \throws InternalError if local atom set is not set - * \returns local atom set for density fitting - */ - const LocalAtomSet &localAtomSet() const + return *localAtomSet_; + } + + /*! \brief Return transformation into density lattice. + * \throws InternalError if transformation into density lattice is not set + * \returns transformation into density lattice + */ + const TranslateAndScale& transformationToDensityLattice() const + { + if (transformationToDensityLattice_ == nullptr) { - if (localAtomSet_ == nullptr) - { - GMX_THROW( - InternalError("Local atom set is not set for density " - "guided simulation.")); - } - return *localAtomSet_; + GMX_THROW(InternalError( + "Transformation to reference density not set for density guided simulation.")); } - - /*! \brief Return transformation into density lattice. - * \throws InternalError if transformation into density lattice is not set - * \returns transformation into density lattice - */ - const TranslateAndScale &transformationToDensityLattice() const + return *transformationToDensityLattice_; + } + /*! \brief Return reference density + * \throws InternalError if reference density is not set + * \returns the reference density + */ + basic_mdspan referenceDensity() const + { + if (referenceDensity_ == nullptr) { - if (transformationToDensityLattice_ == nullptr) - { - GMX_THROW( - InternalError("Transformation to reference density not set for density guided simulation.")); - } - return *transformationToDensityLattice_; + GMX_THROW(InternalError("Reference density not set for density guided simulation.")); } - /*! \brief Return reference density - * \throws InternalError if reference density is not set - * \returns the reference density - */ - basic_mdspan - referenceDensity() const + return referenceDensity_->asConstView(); + } + + /*! \brief Reads the reference density from file. + * + * Reads and check file, then set and communicate the internal + * parameters related to the reference density with the file data. + * + * \throws FileIOError if reading from file was not successful + */ + void readReferenceDensityFromFile(const std::string& referenceDensityFileName) + { + MrcDensityMapOfFloatFromFileReader reader(referenceDensityFileName); + referenceDensity_ = std::make_unique, dynamicExtents3D>>( + reader.densityDataCopy()); + transformationToDensityLattice_ = + std::make_unique(reader.transformationToDensityLattice()); + } + + //! Normalize the reference density so that the sum over all voxels is unity + void normalizeReferenceDensity() + { + if (referenceDensity_ == nullptr) { - if (referenceDensity_ == nullptr) - { - GMX_THROW(InternalError("Reference density not set for density guided simulation.")); - } - return referenceDensity_->asConstView(); + GMX_THROW(InternalError("Need to set reference density before normalizing it.")); } - /*! \brief Reads the reference density from file. - * - * Reads and check file, then set and communicate the internal - * parameters related to the reference density with the file data. - * - * \throws FileIOError if reading from file was not successful - */ - void readReferenceDensityFromFile(const std::string &referenceDensityFileName) + const real sumOfDensityData = std::accumulate(begin(referenceDensity_->asView()), + end(referenceDensity_->asView()), 0.); + for (float& referenceDensityVoxel : referenceDensity_->asView()) { - MrcDensityMapOfFloatFromFileReader reader(referenceDensityFileName); - referenceDensity_ = std::make_unique, dynamicExtents3D> > - (reader.densityDataCopy()); - transformationToDensityLattice_ - = std::make_unique(reader.transformationToDensityLattice()); + referenceDensityVoxel /= sumOfDensityData; } - - //! Normalize the reference density so that the sum over all voxels is unity - void normalizeReferenceDensity() + } + /*! \brief Set the periodic boundary condition via MdModuleNotifier. + * + * The pbc type is wrapped in PeriodicBoundaryConditionType to + * allow the MdModuleNotifier to statically distinguish the callback + * function type from other 'int' function callbacks. + * + * \param[in] pbc MdModuleNotification class that contains a variable + * that enumerates the periodic boundary condition. + */ + void setPeriodicBoundaryConditionType(PeriodicBoundaryConditionType pbc) + { + pbcType_ = std::make_unique(pbc.pbcType); + } + + //! Get the periodic boundary conditions + int periodicBoundaryConditionType() + { + if (pbcType_ == nullptr) { - if (referenceDensity_ == nullptr) - { - GMX_THROW(InternalError("Need to set reference density before normalizing it.")); - } - - const real sumOfDensityData = std::accumulate(begin(referenceDensity_->asView()), end(referenceDensity_->asView()), 0.); - for (float &referenceDensityVoxel : referenceDensity_->asView()) - { - referenceDensityVoxel /= sumOfDensityData; - } + GMX_THROW(InternalError( + "Periodic boundary condition enum not set for density guided simulation.")); } - /*! \brief Set the periodic boundary condition via MdModuleNotifier. - * - * The pbc type is wrapped in PeriodicBoundaryConditionType to - * allow the MdModuleNotifier to statically distinguish the callback - * function type from other 'int' function callbacks. - * - * \param[in] pbc MdModuleNotification class that contains a variable - * that enumerates the periodic boundary condition. - */ - void setPeriodicBoundaryConditionType(PeriodicBoundaryConditionType pbc) - { - pbcType_ = std::make_unique(pbc.pbcType); - } - - //! Get the periodic boundary conditions - int periodicBoundaryConditionType() - { - if (pbcType_ == nullptr) - { - GMX_THROW(InternalError("Periodic boundary condition enum not set for density guided simulation.")); - } - return *pbcType_; - } - - //! Set the simulation time step - void setSimulationTimeStep(double timeStep) - { - simulationTimeStep_ = timeStep; - } - - //! Return the simulation time step - double simulationTimeStep() - { - return simulationTimeStep_; - } - - private: - //! The reference density to fit to - std::unique_ptr, dynamicExtents3D> > referenceDensity_; - //! The coordinate transformation into the reference density - std::unique_ptr transformationToDensityLattice_; - //! The local atom set to act on - std::unique_ptr localAtomSet_; - //! The type of periodic boundary conditions in the simulation - std::unique_ptr pbcType_; - //! The simulation time step - double simulationTimeStep_ = 1; - - GMX_DISALLOW_COPY_AND_ASSIGN(DensityFittingSimulationParameterSetup); + return *pbcType_; + } + + //! Set the simulation time step + void setSimulationTimeStep(double timeStep) { simulationTimeStep_ = timeStep; } + + //! Return the simulation time step + double simulationTimeStep() { return simulationTimeStep_; } + +private: + //! The reference density to fit to + std::unique_ptr, dynamicExtents3D>> referenceDensity_; + //! The coordinate transformation into the reference density + std::unique_ptr transformationToDensityLattice_; + //! The local atom set to act on + std::unique_ptr localAtomSet_; + //! The type of periodic boundary conditions in the simulation + std::unique_ptr pbcType_; + //! The simulation time step + double simulationTimeStep_ = 1; + + GMX_DISALLOW_COPY_AND_ASSIGN(DensityFittingSimulationParameterSetup); }; /*! \internal @@ -229,248 +224,254 @@ class DensityFittingSimulationParameterSetup */ class DensityFitting final : public IMDModule { - public: - /*! \brief Construct the density fitting module. - * - * \param[in] notifier allows the module to subscribe to notifications from MdModules. - * - * The density fitting code subscribes to these notifications: - * - setting atom group indices in the densityFittingOptions_ by - * taking a parmeter const IndexGroupsAndNames & - * - storing its internal parameters in a tpr file by writing to a - * key-value-tree during pre-processing by a function taking a - * KeyValueTreeObjectBuilder as parameter - * - reading its internal parameters from a key-value-tree during - * simulation setup by taking a const KeyValueTreeObject & parameter - * - constructing local atom sets in the simulation parameter setup - * by taking a LocalAtomSetManager * as parameter - * - the type of periodic boundary conditions that are used - * by taking a PeriodicBoundaryConditionType as parameter - * - the writing of checkpoint data - * by taking a MdModulesWriteCheckpointData as parameter - * - the reading of checkpoint data - * by taking a MdModulesCheckpointReadingDataOnMaster as parameter - * - the broadcasting of checkpoint data - * by taking MdModulesCheckpointReadingBroadcast as parameter - */ - explicit DensityFitting(MdModulesNotifier *notifier) - { - // Callbacks for several kinds of MdModuleNotification are created - // and subscribed, and will be dispatched correctly at run time - // based on the type of the parameter required by the lambda. - - // Setting atom group indices - const auto setFitGroupIndicesFunction = [this](const IndexGroupsAndNames &indexGroupsAndNames) { - densityFittingOptions_.setFitGroupIndices(indexGroupsAndNames); - }; - notifier->notifier_.subscribe(setFitGroupIndicesFunction); - - // Writing internal parameters during pre-processing - const auto writeInternalParametersFunction = [this](KeyValueTreeObjectBuilder treeBuilder) { - densityFittingOptions_.writeInternalParametersToKvt(treeBuilder); - }; - notifier->notifier_.subscribe(writeInternalParametersFunction); - - // Reading internal parameters during simulation setup - const auto readInternalParametersFunction = [this](const KeyValueTreeObject &tree) { - densityFittingOptions_.readInternalParametersFromKvt(tree); - }; - notifier->notifier_.subscribe(readInternalParametersFunction); - - // Checking for consistency with all .mdp options - const auto checkEnergyCaluclationFrequencyFunction = [this](EnergyCalculationFrequencyErrors * energyCalculationFrequencyErrors) { +public: + /*! \brief Construct the density fitting module. + * + * \param[in] notifier allows the module to subscribe to notifications from MdModules. + * + * The density fitting code subscribes to these notifications: + * - setting atom group indices in the densityFittingOptions_ by + * taking a parmeter const IndexGroupsAndNames & + * - storing its internal parameters in a tpr file by writing to a + * key-value-tree during pre-processing by a function taking a + * KeyValueTreeObjectBuilder as parameter + * - reading its internal parameters from a key-value-tree during + * simulation setup by taking a const KeyValueTreeObject & parameter + * - constructing local atom sets in the simulation parameter setup + * by taking a LocalAtomSetManager * as parameter + * - the type of periodic boundary conditions that are used + * by taking a PeriodicBoundaryConditionType as parameter + * - the writing of checkpoint data + * by taking a MdModulesWriteCheckpointData as parameter + * - the reading of checkpoint data + * by taking a MdModulesCheckpointReadingDataOnMaster as parameter + * - the broadcasting of checkpoint data + * by taking MdModulesCheckpointReadingBroadcast as parameter + */ + explicit DensityFitting(MdModulesNotifier* notifier) + { + // Callbacks for several kinds of MdModuleNotification are created + // and subscribed, and will be dispatched correctly at run time + // based on the type of the parameter required by the lambda. + + // Setting atom group indices + const auto setFitGroupIndicesFunction = [this](const IndexGroupsAndNames& indexGroupsAndNames) { + densityFittingOptions_.setFitGroupIndices(indexGroupsAndNames); + }; + notifier->notifier_.subscribe(setFitGroupIndicesFunction); + + // Writing internal parameters during pre-processing + const auto writeInternalParametersFunction = [this](KeyValueTreeObjectBuilder treeBuilder) { + densityFittingOptions_.writeInternalParametersToKvt(treeBuilder); + }; + notifier->notifier_.subscribe(writeInternalParametersFunction); + + // Reading internal parameters during simulation setup + const auto readInternalParametersFunction = [this](const KeyValueTreeObject& tree) { + densityFittingOptions_.readInternalParametersFromKvt(tree); + }; + notifier->notifier_.subscribe(readInternalParametersFunction); + + // Checking for consistency with all .mdp options + const auto checkEnergyCaluclationFrequencyFunction = + [this](EnergyCalculationFrequencyErrors* energyCalculationFrequencyErrors) { densityFittingOptions_.checkEnergyCaluclationFrequency(energyCalculationFrequencyErrors); }; - notifier->notifier_.subscribe(checkEnergyCaluclationFrequencyFunction); - - // constructing local atom sets during simulation setup - const auto setLocalAtomSetFunction = [this](LocalAtomSetManager *localAtomSetManager) { - this->constructLocalAtomSet(localAtomSetManager); - }; - notifier->notifier_.subscribe(setLocalAtomSetFunction); - - // constructing local atom sets during simulation setup - const auto setPeriodicBoundaryContionsFunction = [this](PeriodicBoundaryConditionType pbc) { - this->densityFittingSimulationParameters_.setPeriodicBoundaryConditionType(pbc); - }; - notifier->notifier_.subscribe(setPeriodicBoundaryContionsFunction); - - // setting the simulation time step - const auto setSimulationTimeStepFunction = [this](const SimulationTimeStep &simulationTimeStep) { - this->densityFittingSimulationParameters_.setSimulationTimeStep(simulationTimeStep.delta_t); - }; - notifier->notifier_.subscribe(setSimulationTimeStepFunction); - - // adding output to energy file - const auto requestEnergyOutput - = [this](MdModulesEnergyOutputToDensityFittingRequestChecker *energyOutputRequest) { - this->setEnergyOutputRequest(energyOutputRequest); - }; - notifier->notifier_.subscribe(requestEnergyOutput); - - // writing checkpoint data - const auto checkpointDataWriting = [this](MdModulesWriteCheckpointData checkpointData) { - this->writeCheckpointData(checkpointData); - }; - notifier->notifier_.subscribe(checkpointDataWriting); - - // reading checkpoint data - const auto checkpointDataReading = [this](MdModulesCheckpointReadingDataOnMaster checkpointData) { - this->readCheckpointDataOnMaster(checkpointData); - }; - notifier->notifier_.subscribe(checkpointDataReading); - - // broadcasting checkpoint data - const auto checkpointDataBroadcast = [this](MdModulesCheckpointReadingBroadcast checkpointData) { - this->broadcastCheckpointData(checkpointData); + notifier->notifier_.subscribe(checkEnergyCaluclationFrequencyFunction); + + // constructing local atom sets during simulation setup + const auto setLocalAtomSetFunction = [this](LocalAtomSetManager* localAtomSetManager) { + this->constructLocalAtomSet(localAtomSetManager); + }; + notifier->notifier_.subscribe(setLocalAtomSetFunction); + + // constructing local atom sets during simulation setup + const auto setPeriodicBoundaryContionsFunction = [this](PeriodicBoundaryConditionType pbc) { + this->densityFittingSimulationParameters_.setPeriodicBoundaryConditionType(pbc); + }; + notifier->notifier_.subscribe(setPeriodicBoundaryContionsFunction); + + // setting the simulation time step + const auto setSimulationTimeStepFunction = [this](const SimulationTimeStep& simulationTimeStep) { + this->densityFittingSimulationParameters_.setSimulationTimeStep(simulationTimeStep.delta_t); + }; + notifier->notifier_.subscribe(setSimulationTimeStepFunction); + + // adding output to energy file + const auto requestEnergyOutput = + [this](MdModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) { + this->setEnergyOutputRequest(energyOutputRequest); }; - notifier->notifier_.subscribe(checkpointDataBroadcast); - } - - //! From IMDModule - IMdpOptionProvider *mdpOptionProvider() override { return &densityFittingOptions_; } - - //! Add this module to the force providers if active - void initForceProviders(ForceProviders *forceProviders) override + notifier->notifier_.subscribe(requestEnergyOutput); + + // writing checkpoint data + const auto checkpointDataWriting = [this](MdModulesWriteCheckpointData checkpointData) { + this->writeCheckpointData(checkpointData); + }; + notifier->notifier_.subscribe(checkpointDataWriting); + + // reading checkpoint data + const auto checkpointDataReading = [this](MdModulesCheckpointReadingDataOnMaster checkpointData) { + this->readCheckpointDataOnMaster(checkpointData); + }; + notifier->notifier_.subscribe(checkpointDataReading); + + // broadcasting checkpoint data + const auto checkpointDataBroadcast = [this](MdModulesCheckpointReadingBroadcast checkpointData) { + this->broadcastCheckpointData(checkpointData); + }; + notifier->notifier_.subscribe(checkpointDataBroadcast); + } + + //! From IMDModule + IMdpOptionProvider* mdpOptionProvider() override { return &densityFittingOptions_; } + + //! Add this module to the force providers if active + void initForceProviders(ForceProviders* forceProviders) override + { + if (densityFittingOptions_.active()) { - if (densityFittingOptions_.active()) + const auto& parameters = densityFittingOptions_.buildParameters(); + densityFittingSimulationParameters_.readReferenceDensityFromFile( + densityFittingOptions_.referenceDensityFileName()); + if (parameters.normalizeDensities_) { - const auto ¶meters = densityFittingOptions_.buildParameters(); - densityFittingSimulationParameters_.readReferenceDensityFromFile(densityFittingOptions_.referenceDensityFileName()); - if (parameters.normalizeDensities_) - { - densityFittingSimulationParameters_.normalizeReferenceDensity(); - } - forceProvider_ = std::make_unique( - parameters, - densityFittingSimulationParameters_.referenceDensity(), - densityFittingSimulationParameters_.transformationToDensityLattice(), - densityFittingSimulationParameters_.localAtomSet(), - densityFittingSimulationParameters_.periodicBoundaryConditionType(), - densityFittingSimulationParameters_.simulationTimeStep(), - densityFittingState_); - forceProviders->addForceProvider(forceProvider_.get()); + densityFittingSimulationParameters_.normalizeReferenceDensity(); } + forceProvider_ = std::make_unique( + parameters, densityFittingSimulationParameters_.referenceDensity(), + densityFittingSimulationParameters_.transformationToDensityLattice(), + densityFittingSimulationParameters_.localAtomSet(), + densityFittingSimulationParameters_.periodicBoundaryConditionType(), + densityFittingSimulationParameters_.simulationTimeStep(), densityFittingState_); + forceProviders->addForceProvider(forceProvider_.get()); } - - //! This MDModule provides its own output - IMDOutputProvider *outputProvider() override { return &densityFittingOutputProvider_; } - - /*! \brief Set up the local atom sets that are used by this module. - * - * \note When density fitting is set up with MdModuleNotification in - * the constructor, this function is called back. - * - * \param[in] localAtomSetManager the manager to add local atom sets. - */ - void constructLocalAtomSet(LocalAtomSetManager * localAtomSetManager) + } + + //! This MDModule provides its own output + IMDOutputProvider* outputProvider() override { return &densityFittingOutputProvider_; } + + /*! \brief Set up the local atom sets that are used by this module. + * + * \note When density fitting is set up with MdModuleNotification in + * the constructor, this function is called back. + * + * \param[in] localAtomSetManager the manager to add local atom sets. + */ + void constructLocalAtomSet(LocalAtomSetManager* localAtomSetManager) + { + if (densityFittingOptions_.active()) { - if (densityFittingOptions_.active()) - { - LocalAtomSet atomSet - = localAtomSetManager->add(densityFittingOptions_.buildParameters().indices_); - densityFittingSimulationParameters_.setLocalAtomSet(atomSet); - } + LocalAtomSet atomSet = + localAtomSetManager->add(densityFittingOptions_.buildParameters().indices_); + densityFittingSimulationParameters_.setLocalAtomSet(atomSet); } - - /*! \brief Request energy output to energy file during simulation. - */ - void setEnergyOutputRequest(MdModulesEnergyOutputToDensityFittingRequestChecker *energyOutputRequest) + } + + /*! \brief Request energy output to energy file during simulation. + */ + void setEnergyOutputRequest(MdModulesEnergyOutputToDensityFittingRequestChecker* energyOutputRequest) + { + energyOutputRequest->energyOutputToDensityFitting_ = densityFittingOptions_.active(); + } + + /*! \brief Write internal density fitting data to checkpoint file. + * \param[in] checkpointWriting enables writing to the Key-Value-Tree + * that is used for storing the checkpoint + * information + */ + void writeCheckpointData(MdModulesWriteCheckpointData checkpointWriting) + { + if (densityFittingOptions_.active()) { - energyOutputRequest->energyOutputToDensityFitting_ = densityFittingOptions_.active(); + const DensityFittingForceProviderState& state = forceProvider_->state(); + checkpointWriting.builder_.addValue( + DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation", + state.stepsSinceLastCalculation_); + checkpointWriting.builder_.addValue( + DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale", + state.adaptiveForceConstantScale_); + KeyValueTreeObjectBuilder exponentialMovingAverageKvtEntry = + checkpointWriting.builder_.addObject(DensityFittingModuleInfo::name_ + + "-exponentialMovingAverageState"); + exponentialMovingAverageStateAsKeyValueTree(exponentialMovingAverageKvtEntry, + state.exponentialMovingAverageState_); } - - /*! \brief Write internal density fitting data to checkpoint file. - * \param[in] checkpointWriting enables writing to the Key-Value-Tree - * that is used for storing the checkpoint - * information - */ - void writeCheckpointData(MdModulesWriteCheckpointData checkpointWriting) + } + + /*! \brief Read the internal parameters from the checkpoint file on master + * \param[in] checkpointReading holding the checkpoint information + */ + void readCheckpointDataOnMaster(MdModulesCheckpointReadingDataOnMaster checkpointReading) + { + if (densityFittingOptions_.active()) { - if (densityFittingOptions_.active()) + if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_ + + "-stepsSinceLastCalculation")) { - const DensityFittingForceProviderState &state = - forceProvider_->state(); - checkpointWriting.builder_.addValue( - DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation", - state.stepsSinceLastCalculation_); - checkpointWriting.builder_.addValue( - DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale", - state.adaptiveForceConstantScale_); - KeyValueTreeObjectBuilder exponentialMovingAverageKvtEntry = - checkpointWriting.builder_.addObject( - DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState"); - exponentialMovingAverageStateAsKeyValueTree(exponentialMovingAverageKvtEntry, state.exponentialMovingAverageState_); + densityFittingState_.stepsSinceLastCalculation_ = + checkpointReading + .checkpointedData_[DensityFittingModuleInfo::name_ + + "-stepsSinceLastCalculation"] + .cast(); } - } - - /*! \brief Read the internal parameters from the checkpoint file on master - * \param[in] checkpointReading holding the checkpoint information - */ - void readCheckpointDataOnMaster(MdModulesCheckpointReadingDataOnMaster checkpointReading) - { - if (densityFittingOptions_.active()) + if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_ + + "-adaptiveForceConstantScale")) { - if (checkpointReading.checkpointedData_.keyExists( - DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation")) - { - densityFittingState_.stepsSinceLastCalculation_ = - checkpointReading.checkpointedData_[ - DensityFittingModuleInfo::name_ + "-stepsSinceLastCalculation"].cast(); - } - if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale")) - { - densityFittingState_.adaptiveForceConstantScale_ - = checkpointReading - .checkpointedData_[DensityFittingModuleInfo::name_ + "-adaptiveForceConstantScale"].cast(); - } - if (checkpointReading.checkpointedData_.keyExists( - DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState")) - { - densityFittingState_.exponentialMovingAverageState_ = - exponentialMovingAverageStateFromKeyValueTree(checkpointReading - .checkpointedData_[DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState"].asObject()); - } + densityFittingState_.adaptiveForceConstantScale_ = + checkpointReading + .checkpointedData_[DensityFittingModuleInfo::name_ + + "-adaptiveForceConstantScale"] + .cast(); + } + if (checkpointReading.checkpointedData_.keyExists(DensityFittingModuleInfo::name_ + + "-exponentialMovingAverageState")) + { + densityFittingState_.exponentialMovingAverageState_ = exponentialMovingAverageStateFromKeyValueTree( + checkpointReading + .checkpointedData_[DensityFittingModuleInfo::name_ + "-exponentialMovingAverageState"] + .asObject()); } } - - /*! \brief Broadcast the internal parameters. - * \param[in] checkpointBroadcast containing the communication record to - * broadcast the checkpoint information - */ - void broadcastCheckpointData(MdModulesCheckpointReadingBroadcast checkpointBroadcast) + } + + /*! \brief Broadcast the internal parameters. + * \param[in] checkpointBroadcast containing the communication record to + * broadcast the checkpoint information + */ + void broadcastCheckpointData(MdModulesCheckpointReadingBroadcast checkpointBroadcast) + { + if (densityFittingOptions_.active()) { - if (densityFittingOptions_.active()) + if (PAR(&(checkpointBroadcast.cr_))) { - if (PAR(&(checkpointBroadcast.cr_))) - { - block_bc(&(checkpointBroadcast.cr_), densityFittingState_.stepsSinceLastCalculation_); - block_bc(&(checkpointBroadcast.cr_), densityFittingState_.adaptiveForceConstantScale_); - block_bc(&(checkpointBroadcast.cr_), densityFittingState_.exponentialMovingAverageState_); - } + block_bc(&(checkpointBroadcast.cr_), densityFittingState_.stepsSinceLastCalculation_); + block_bc(&(checkpointBroadcast.cr_), densityFittingState_.adaptiveForceConstantScale_); + block_bc(&(checkpointBroadcast.cr_), densityFittingState_.exponentialMovingAverageState_); } } - - private: - //! The output provider - DensityFittingOutputProvider densityFittingOutputProvider_; - //! The options provided for density fitting - DensityFittingOptions densityFittingOptions_; - //! Object that evaluates the forces - std::unique_ptr forceProvider_; - /*! \brief Parameters for density fitting that become available at - * simulation setup time. - */ - DensityFittingSimulationParameterSetup densityFittingSimulationParameters_; - //! The internal parameters of density fitting force provider - DensityFittingForceProviderState densityFittingState_; - - GMX_DISALLOW_COPY_AND_ASSIGN(DensityFitting); + } + +private: + //! The output provider + DensityFittingOutputProvider densityFittingOutputProvider_; + //! The options provided for density fitting + DensityFittingOptions densityFittingOptions_; + //! Object that evaluates the forces + std::unique_ptr forceProvider_; + /*! \brief Parameters for density fitting that become available at + * simulation setup time. + */ + DensityFittingSimulationParameterSetup densityFittingSimulationParameters_; + //! The internal parameters of density fitting force provider + DensityFittingForceProviderState densityFittingState_; + + GMX_DISALLOW_COPY_AND_ASSIGN(DensityFitting); }; -} // namespace +} // namespace -std::unique_ptr DensityFittingModuleInfo::create(MdModulesNotifier * notifier) +std::unique_ptr DensityFittingModuleInfo::create(MdModulesNotifier* notifier) { return std::make_unique(notifier); } diff --git a/src/gromacs/applied_forces/densityfitting.h b/src/gromacs/applied_forces/densityfitting.h index ebdf321641..c453027137 100644 --- a/src/gromacs/applied_forces/densityfitting.h +++ b/src/gromacs/applied_forces/densityfitting.h @@ -56,9 +56,9 @@ struct DensityFittingModuleInfo * Fitting an all-atom structure into an experimental cryo-EM density map is a * typical application. */ - static std::unique_ptr create(MdModulesNotifier * notifier); + static std::unique_ptr create(MdModulesNotifier* notifier); //! The name of the module - static const std::string name_; + static const std::string name_; }; } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingamplitudelookup.cpp b/src/gromacs/applied_forces/densityfittingamplitudelookup.cpp index 04c56616ad..3b7343b717 100644 --- a/src/gromacs/applied_forces/densityfittingamplitudelookup.cpp +++ b/src/gromacs/applied_forces/densityfittingamplitudelookup.cpp @@ -56,30 +56,28 @@ namespace gmx class DensityFittingAmplitudeLookupImpl { - public: - DensityFittingAmplitudeLookupImpl() = default; - DensityFittingAmplitudeLookupImpl(const DensityFittingAmplitudeLookupImpl &) = default; - virtual ~DensityFittingAmplitudeLookupImpl() = default; - - virtual const std::vector &operator()(const t_mdatoms &atoms, - ArrayRef localIndex) = 0; - virtual std::unique_ptr clone() = 0; +public: + DensityFittingAmplitudeLookupImpl() = default; + DensityFittingAmplitudeLookupImpl(const DensityFittingAmplitudeLookupImpl&) = default; + virtual ~DensityFittingAmplitudeLookupImpl() = default; + + virtual const std::vector& operator()(const t_mdatoms& atoms, ArrayRef localIndex) = 0; + virtual std::unique_ptr clone() = 0; }; namespace { class UnitAmplitudes final : public DensityFittingAmplitudeLookupImpl { - public: - UnitAmplitudes() = default; - UnitAmplitudes(const UnitAmplitudes &) = default; - ~UnitAmplitudes() override = default; - std::unique_ptr clone() override; - const std::vector &operator()(const t_mdatoms &atoms, - ArrayRef localIndex) override; +public: + UnitAmplitudes() = default; + UnitAmplitudes(const UnitAmplitudes&) = default; + ~UnitAmplitudes() override = default; + std::unique_ptr clone() override; + const std::vector& operator()(const t_mdatoms& atoms, ArrayRef localIndex) override; - private: - std::vector amplitude_; +private: + std::vector amplitude_; }; std::unique_ptr UnitAmplitudes::clone() @@ -87,8 +85,7 @@ std::unique_ptr UnitAmplitudes::clone() return std::make_unique(*this); }; -const std::vector &UnitAmplitudes::operator()(const t_mdatoms & /*atoms*/, - ArrayRef localIndex) +const std::vector& UnitAmplitudes::operator()(const t_mdatoms& /*atoms*/, ArrayRef localIndex) { if (amplitude_.size() != localIndex.size()) { @@ -100,16 +97,15 @@ const std::vector &UnitAmplitudes::operator()(const t_mdatoms & /*atom class ChargesAsAmplitudes final : public DensityFittingAmplitudeLookupImpl { - public: - ChargesAsAmplitudes() = default; - ChargesAsAmplitudes(const ChargesAsAmplitudes &) = default; - ~ChargesAsAmplitudes() override = default; - std::unique_ptr clone() override; - const std::vector &operator()(const t_mdatoms &atoms, - ArrayRef localIndex) override; +public: + ChargesAsAmplitudes() = default; + ChargesAsAmplitudes(const ChargesAsAmplitudes&) = default; + ~ChargesAsAmplitudes() override = default; + std::unique_ptr clone() override; + const std::vector& operator()(const t_mdatoms& atoms, ArrayRef localIndex) override; - private: - std::vector amplitude_; +private: + std::vector amplitude_; }; std::unique_ptr ChargesAsAmplitudes::clone() @@ -117,8 +113,7 @@ std::unique_ptr ChargesAsAmplitudes::clone() return std::make_unique(*this); }; -const std::vector &ChargesAsAmplitudes::operator()(const t_mdatoms &atoms, - ArrayRef localIndex) +const std::vector& ChargesAsAmplitudes::operator()(const t_mdatoms& atoms, ArrayRef localIndex) { if (amplitude_.size() != localIndex.size()) { @@ -126,23 +121,21 @@ const std::vector &ChargesAsAmplitudes::operator()(const t_mdatoms &ato } std::transform(std::begin(localIndex), std::end(localIndex), std::begin(amplitude_), - [&atoms](gmx::index index){return atoms.chargeA[index]; } - ); + [&atoms](gmx::index index) { return atoms.chargeA[index]; }); return amplitude_; } class MassesAsAmplitudes final : public DensityFittingAmplitudeLookupImpl { - public: - MassesAsAmplitudes() = default; - MassesAsAmplitudes(const MassesAsAmplitudes &) = default; - ~MassesAsAmplitudes() override = default; - std::unique_ptr clone() override; - const std::vector &operator()(const t_mdatoms &atoms, - ArrayRef localIndex) override; +public: + MassesAsAmplitudes() = default; + MassesAsAmplitudes(const MassesAsAmplitudes&) = default; + ~MassesAsAmplitudes() override = default; + std::unique_ptr clone() override; + const std::vector& operator()(const t_mdatoms& atoms, ArrayRef localIndex) override; - private: - std::vector amplitude_; +private: + std::vector amplitude_; }; std::unique_ptr MassesAsAmplitudes::clone() @@ -150,8 +143,7 @@ std::unique_ptr MassesAsAmplitudes::clone() return std::make_unique(*this); }; -const std::vector &MassesAsAmplitudes::operator()(const t_mdatoms &atoms, - ArrayRef localIndex) +const std::vector& MassesAsAmplitudes::operator()(const t_mdatoms& atoms, ArrayRef localIndex) { if (amplitude_.size() != localIndex.size()) { @@ -163,14 +155,14 @@ const std::vector &MassesAsAmplitudes::operator()(const t_mdatoms &atom return amplitude_; } -} // namespace +} // namespace /******************************************************************** * DensityFittingAmplitudeLookup */ -DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(const DensityFittingAmplitudeMethod &method) +DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(const DensityFittingAmplitudeMethod& method) { switch (method) { @@ -183,12 +175,11 @@ DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(const DensityFittin case DensityFittingAmplitudeMethod::Charge: impl_ = std::make_unique(); break; - default: - break; + default: break; } } -const std::vector &DensityFittingAmplitudeLookup::operator()(const t_mdatoms &atoms, +const std::vector& DensityFittingAmplitudeLookup::operator()(const t_mdatoms& atoms, ArrayRef localIndex) { return (*impl_)(atoms, localIndex); @@ -196,19 +187,20 @@ const std::vector &DensityFittingAmplitudeLookup::operator()(const t_mdato DensityFittingAmplitudeLookup::~DensityFittingAmplitudeLookup() = default; -DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(const DensityFittingAmplitudeLookup &other) - : impl_(other.impl_->clone()) +DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(const DensityFittingAmplitudeLookup& other) : + impl_(other.impl_->clone()) { } -DensityFittingAmplitudeLookup &DensityFittingAmplitudeLookup::operator=(const DensityFittingAmplitudeLookup &other) +DensityFittingAmplitudeLookup& DensityFittingAmplitudeLookup::operator=(const DensityFittingAmplitudeLookup& other) { impl_ = other.impl_->clone(); return *this; } -DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(DensityFittingAmplitudeLookup &&) noexcept = default; +DensityFittingAmplitudeLookup::DensityFittingAmplitudeLookup(DensityFittingAmplitudeLookup&&) noexcept = default; -DensityFittingAmplitudeLookup &DensityFittingAmplitudeLookup::operator=(DensityFittingAmplitudeLookup &&) noexcept = default; +DensityFittingAmplitudeLookup& DensityFittingAmplitudeLookup:: + operator=(DensityFittingAmplitudeLookup&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingamplitudelookup.h b/src/gromacs/applied_forces/densityfittingamplitudelookup.h index b7aa8932eb..e3f7f28ffb 100644 --- a/src/gromacs/applied_forces/densityfittingamplitudelookup.h +++ b/src/gromacs/applied_forces/densityfittingamplitudelookup.h @@ -66,8 +66,9 @@ enum class DensityFittingAmplitudeMethod }; //! The names of the methods to determine the amplitude of the atoms to be spread on a grid -const EnumerationArray -c_densityFittingAmplitudeMethodNames = {{"unity", "mass", "charge"}}; +const EnumerationArray c_densityFittingAmplitudeMethodNames = { + { "unity", "mass", "charge" } +}; class DensityFittingAmplitudeLookupImpl; @@ -76,29 +77,29 @@ class DensityFittingAmplitudeLookupImpl; */ class DensityFittingAmplitudeLookup { - public: - //! Construct force provider for density fitting from its parameters - explicit DensityFittingAmplitudeLookup(const DensityFittingAmplitudeMethod &method); - ~DensityFittingAmplitudeLookup(); - //! Copy constructor - DensityFittingAmplitudeLookup(const DensityFittingAmplitudeLookup &other); - //! Copy assignment - DensityFittingAmplitudeLookup &operator=(const DensityFittingAmplitudeLookup &other); - //! Move constructor - DensityFittingAmplitudeLookup(DensityFittingAmplitudeLookup &&other) noexcept; - //! Move assignment - DensityFittingAmplitudeLookup &operator=(DensityFittingAmplitudeLookup &&other) noexcept; - /*! \brief Return the amplitudes for spreading atoms of a given local index. - * \param[in] atoms the atom information - * \param[in] localIndex the local atom indices - * \returns amplitudes - */ - const std::vector &operator()(const t_mdatoms &atoms, - ArrayRef localIndex); - private: - std::unique_ptr impl_; +public: + //! Construct force provider for density fitting from its parameters + explicit DensityFittingAmplitudeLookup(const DensityFittingAmplitudeMethod& method); + ~DensityFittingAmplitudeLookup(); + //! Copy constructor + DensityFittingAmplitudeLookup(const DensityFittingAmplitudeLookup& other); + //! Copy assignment + DensityFittingAmplitudeLookup& operator=(const DensityFittingAmplitudeLookup& other); + //! Move constructor + DensityFittingAmplitudeLookup(DensityFittingAmplitudeLookup&& other) noexcept; + //! Move assignment + DensityFittingAmplitudeLookup& operator=(DensityFittingAmplitudeLookup&& other) noexcept; + /*! \brief Return the amplitudes for spreading atoms of a given local index. + * \param[in] atoms the atom information + * \param[in] localIndex the local atom indices + * \returns amplitudes + */ + const std::vector& operator()(const t_mdatoms& atoms, ArrayRef localIndex); + +private: + std::unique_ptr impl_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_APPLIED_FORCES_DENSITYFITTINGAMPLITUDELOOKUP_H diff --git a/src/gromacs/applied_forces/densityfittingforceprovider.cpp b/src/gromacs/applied_forces/densityfittingforceprovider.cpp index 37d5bae124..24e40526fb 100644 --- a/src/gromacs/applied_forces/densityfittingforceprovider.cpp +++ b/src/gromacs/applied_forces/densityfittingforceprovider.cpp @@ -73,21 +73,16 @@ namespace * \param[in] scaleToLattice the coordinate transformation into the spreading lattice * \returns A Gauss-transform kernel shape */ -GaussianSpreadKernelParameters::Shape -makeSpreadKernel(real sigma, real nSigma, const ScaleCoordinates &scaleToLattice) +GaussianSpreadKernelParameters::Shape makeSpreadKernel(real sigma, real nSigma, const ScaleCoordinates& scaleToLattice) { - RVec sigmaInLatticeCoordinates { - sigma, sigma, sigma - }; - scaleToLattice( { &sigmaInLatticeCoordinates, &sigmaInLatticeCoordinates + 1 }); - return { - DVec { - sigmaInLatticeCoordinates[XX], sigmaInLatticeCoordinates[YY], sigmaInLatticeCoordinates[ZZ] - }, nSigma - }; + RVec sigmaInLatticeCoordinates{ sigma, sigma, sigma }; + scaleToLattice({ &sigmaInLatticeCoordinates, &sigmaInLatticeCoordinates + 1 }); + return { DVec{ sigmaInLatticeCoordinates[XX], sigmaInLatticeCoordinates[YY], + sigmaInLatticeCoordinates[ZZ] }, + nSigma }; } -} // namespace +} // namespace /******************************************************************** * DensityFittingForceProvider::Impl @@ -95,50 +90,51 @@ makeSpreadKernel(real sigma, real nSigma, const ScaleCoordinates &scaleToLattice class DensityFittingForceProvider::Impl { - public: - //! \copydoc DensityFittingForceProvider(const DensityFittingParameters ¶meters) - Impl(const DensityFittingParameters ¶meters, - basic_mdspan referenceDensity, - const TranslateAndScale &transformationToDensityLattice, - const LocalAtomSet &localAtomSet, - int pbcType, - double simulationTimeStep, - const DensityFittingForceProviderState &state); - ~Impl(); - void calculateForces(const ForceProviderInput &forceProviderInput, ForceProviderOutput *forceProviderOutput); - - DensityFittingForceProviderState state(); - - private: - const DensityFittingParameters ¶meters_; - DensityFittingForceProviderState state_; - LocalAtomSet localAtomSet_; - - GaussianSpreadKernelParameters::Shape spreadKernel_; - GaussTransform3D gaussTransform_; - DensitySimilarityMeasure measure_; - DensityFittingForce densityFittingForce_; - //! the local atom coordinates transformed into the grid coordinate system - std::vector transformedCoordinates_; - std::vector forces_; - DensityFittingAmplitudeLookup amplitudeLookup_; - TranslateAndScale transformationToDensityLattice_; - RVec referenceDensityCenter_; - int pbcType_; - - //! Optionally scale the force according to a moving average of the similarity - compat::optional expAverageSimilarity_; +public: + //! \copydoc DensityFittingForceProvider(const DensityFittingParameters ¶meters) + Impl(const DensityFittingParameters& parameters, + basic_mdspan referenceDensity, + const TranslateAndScale& transformationToDensityLattice, + const LocalAtomSet& localAtomSet, + int pbcType, + double simulationTimeStep, + const DensityFittingForceProviderState& state); + ~Impl(); + void calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput); + + DensityFittingForceProviderState state(); + +private: + const DensityFittingParameters& parameters_; + DensityFittingForceProviderState state_; + LocalAtomSet localAtomSet_; + + GaussianSpreadKernelParameters::Shape spreadKernel_; + GaussTransform3D gaussTransform_; + DensitySimilarityMeasure measure_; + DensityFittingForce densityFittingForce_; + //! the local atom coordinates transformed into the grid coordinate system + std::vector transformedCoordinates_; + std::vector forces_; + DensityFittingAmplitudeLookup amplitudeLookup_; + TranslateAndScale transformationToDensityLattice_; + RVec referenceDensityCenter_; + int pbcType_; + + //! Optionally scale the force according to a moving average of the similarity + compat::optional expAverageSimilarity_; }; DensityFittingForceProvider::Impl::~Impl() = default; -DensityFittingForceProvider::Impl::Impl(const DensityFittingParameters ¶meters, +DensityFittingForceProvider::Impl::Impl(const DensityFittingParameters& parameters, basic_mdspan referenceDensity, - const TranslateAndScale &transformationToDensityLattice, - const LocalAtomSet &localAtomSet, - int pbcType, - double simulationTimeStep, - const DensityFittingForceProviderState &state) : + const TranslateAndScale& transformationToDensityLattice, + const LocalAtomSet& localAtomSet, + int pbcType, + double simulationTimeStep, + const DensityFittingForceProviderState& state) : parameters_(parameters), state_(state), localAtomSet_(localAtomSet), @@ -156,17 +152,16 @@ DensityFittingForceProvider::Impl::Impl(const DensityFittingParameters ¶mete { if (parameters_.adaptiveForceScaling_) { - GMX_ASSERT(simulationTimeStep > 0, "Simulation time step must be larger than zero for adaptive for scaling."); + GMX_ASSERT(simulationTimeStep > 0, + "Simulation time step must be larger than zero for adaptive for scaling."); expAverageSimilarity_.emplace(ExponentialMovingAverage( - parameters_.adaptiveForceScalingTimeConstant_ - / (simulationTimeStep * parameters_.calculationIntervalInSteps_), - state.exponentialMovingAverageState_)); + parameters_.adaptiveForceScalingTimeConstant_ + / (simulationTimeStep * parameters_.calculationIntervalInSteps_), + state.exponentialMovingAverageState_)); } - referenceDensityCenter_ = { - real(referenceDensity.extent(XX))/2, - real(referenceDensity.extent(YY))/2, - real(referenceDensity.extent(ZZ))/2 - }; + referenceDensityCenter_ = { real(referenceDensity.extent(XX)) / 2, + real(referenceDensity.extent(YY)) / 2, + real(referenceDensity.extent(ZZ)) / 2 }; transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale( { &referenceDensityCenter_, &referenceDensityCenter_ + 1 }); // correct the reference density center for a shift @@ -178,8 +173,8 @@ DensityFittingForceProvider::Impl::Impl(const DensityFittingParameters ¶mete referenceDensityCenter_ -= referenceDensityOriginShift; } -void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) +void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) { // do nothing but count number of steps when not in density fitting step if (state_.stepsSinceLastCalculation_ % parameters_.calculationIntervalInSteps_ != 0) @@ -197,8 +192,7 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput } transformedCoordinates_.resize(localAtomSet_.numAtomsLocal()); // pick and copy atom coordinates - std::transform(std::cbegin(localAtomSet_.localIndex()), - std::cend(localAtomSet_.localIndex()), + std::transform(std::cbegin(localAtomSet_.localIndex()), std::cend(localAtomSet_.localIndex()), std::begin(transformedCoordinates_), [&forceProviderInput](int index) { return forceProviderInput.x_[index]; }); @@ -206,7 +200,7 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput { t_pbc pbc; set_pbc(&pbc, pbcType_, forceProviderInput.box_); - for (RVec &x : transformedCoordinates_) + for (RVec& x : transformedCoordinates_) { rvec dx; pbc_dx(&pbc, x, referenceDensityCenter_, dx); @@ -220,7 +214,8 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput // spread atoms on grid gaussTransform_.setZero(); - std::vector amplitudes = amplitudeLookup_(forceProviderInput.mdatoms_, localAtomSet_.localIndex()); + std::vector amplitudes = + amplitudeLookup_(forceProviderInput.mdatoms_, localAtomSet_.localIndex()); if (parameters_.normalizeDensities_) { @@ -229,7 +224,7 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput { gmx_sum(1, &sum, &forceProviderInput.cr_); } - for (real &litude : amplitudes) + for (real& amplitude : amplitudes) { amplitude /= sum; } @@ -237,7 +232,7 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput auto amplitudeIterator = amplitudes.cbegin(); - for (const auto &r : transformedCoordinates_) + for (const auto& r : transformedCoordinates_) { gaussTransform_.add({ r, *amplitudeIterator }); ++amplitudeIterator; @@ -252,36 +247,31 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput } // calculate grid derivative - const DensitySimilarityMeasure::density &densityDerivative = - measure_.gradient(gaussTransform_.constView()); + const DensitySimilarityMeasure::density& densityDerivative = + measure_.gradient(gaussTransform_.constView()); // calculate forces forces_.resize(localAtomSet_.numAtomsLocal()); std::transform( - std::begin(transformedCoordinates_), - std::end(transformedCoordinates_), - std::begin(amplitudes), - std::begin(forces_), - [&densityDerivative, this](const RVec r, real amplitude) - { - return densityFittingForce_.evaluateForce({r, amplitude}, densityDerivative); - } - ); + std::begin(transformedCoordinates_), std::end(transformedCoordinates_), std::begin(amplitudes), + std::begin(forces_), [&densityDerivative, this](const RVec r, real amplitude) { + return densityFittingForce_.evaluateForce({ r, amplitude }, densityDerivative); + }); transformationToDensityLattice_.scaleOperationOnly().inverseIgnoringZeroScale(forces_); - auto densityForceIterator = forces_.cbegin(); - const real effectiveForceConstant = state_.adaptiveForceConstantScale_ * - parameters_.calculationIntervalInSteps_ * parameters_.forceConstant_; + auto densityForceIterator = forces_.cbegin(); + const real effectiveForceConstant = state_.adaptiveForceConstantScale_ * parameters_.calculationIntervalInSteps_ + * parameters_.forceConstant_; for (const auto localAtomIndex : localAtomSet_.localIndex()) { - forceProviderOutput->forceWithVirial_.force_[localAtomIndex] - += effectiveForceConstant * *densityForceIterator; + forceProviderOutput->forceWithVirial_.force_[localAtomIndex] += + effectiveForceConstant * *densityForceIterator; ++densityForceIterator; } // calculate corresponding potential energy - const float similarity = measure_.similarity(gaussTransform_.constView()); - const real energy = -similarity * parameters_.forceConstant_ * state_.adaptiveForceConstantScale_; + const float similarity = measure_.similarity(gaussTransform_.constView()); + const real energy = -similarity * parameters_.forceConstant_ * state_.adaptiveForceConstantScale_; forceProviderOutput->enerd_.term[F_DENSITYFITTING] += energy; if (expAverageSimilarity_.has_value()) @@ -299,8 +289,7 @@ void DensityFittingForceProvider::Impl::calculateForces(const ForceProviderInput } } -DensityFittingForceProviderState -DensityFittingForceProvider::Impl::state() +DensityFittingForceProviderState DensityFittingForceProvider::Impl::state() { if (expAverageSimilarity_.has_value()) { @@ -315,18 +304,19 @@ DensityFittingForceProvider::Impl::state() DensityFittingForceProvider::~DensityFittingForceProvider() = default; -DensityFittingForceProvider::DensityFittingForceProvider(const DensityFittingParameters ¶meters, +DensityFittingForceProvider::DensityFittingForceProvider(const DensityFittingParameters& parameters, basic_mdspan referenceDensity, - const TranslateAndScale &transformationToDensityLattice, - const LocalAtomSet &localAtomSet, - int pbcType, - double simulationTimeStep, - const DensityFittingForceProviderState &state) - : impl_(new Impl(parameters, referenceDensity, transformationToDensityLattice, localAtomSet, pbcType, simulationTimeStep, state)) -{} - -void DensityFittingForceProvider::calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput * forceProviderOutput) + const TranslateAndScale& transformationToDensityLattice, + const LocalAtomSet& localAtomSet, + int pbcType, + double simulationTimeStep, + const DensityFittingForceProviderState& state) : + impl_(new Impl(parameters, referenceDensity, transformationToDensityLattice, localAtomSet, pbcType, simulationTimeStep, state)) +{ +} + +void DensityFittingForceProvider::calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) { impl_->calculateForces(forceProviderInput, forceProviderOutput); } diff --git a/src/gromacs/applied_forces/densityfittingforceprovider.h b/src/gromacs/applied_forces/densityfittingforceprovider.h index 766fbef58e..3c979865c5 100644 --- a/src/gromacs/applied_forces/densityfittingforceprovider.h +++ b/src/gromacs/applied_forces/densityfittingforceprovider.h @@ -64,11 +64,11 @@ struct DensityFittingForceProviderState /*! \brief The steps since the last force calculation. * Used if density fitting is to be calculated every N steps. */ - std::int64_t stepsSinceLastCalculation_ = 0; + std::int64_t stepsSinceLastCalculation_ = 0; //! The state of the exponential moving average of the similarity measure ExponentialMovingAverageState exponentialMovingAverageState_ = {}; //! An additional factor scaling the force for adaptive force scaling - real adaptiveForceConstantScale_ = 1.0_real; + real adaptiveForceConstantScale_ = 1.0_real; }; /*! \internal \brief @@ -76,31 +76,31 @@ struct DensityFittingForceProviderState */ class DensityFittingForceProvider final : public IForceProvider { - public: - //! Construct force provider for density fitting from its parameters - DensityFittingForceProvider(const DensityFittingParameters ¶meters, - basic_mdspan referenceDensity, - const TranslateAndScale &transformationToDensityLattice, - const LocalAtomSet &localAtomSet, - int pbcType, - double simulationTimeStep, - const DensityFittingForceProviderState &state); - ~DensityFittingForceProvider(); - /*!\brief Calculate forces that maximise goodness-of-fit with a reference density map. - * \param[in] forceProviderInput input for force provider - * \param[out] forceProviderOutput output for force provider - */ - void calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) override; +public: + //! Construct force provider for density fitting from its parameters + DensityFittingForceProvider(const DensityFittingParameters& parameters, + basic_mdspan referenceDensity, + const TranslateAndScale& transformationToDensityLattice, + const LocalAtomSet& localAtomSet, + int pbcType, + double simulationTimeStep, + const DensityFittingForceProviderState& state); + ~DensityFittingForceProvider(); + /*!\brief Calculate forces that maximise goodness-of-fit with a reference density map. + * \param[in] forceProviderInput input for force provider + * \param[out] forceProviderOutput output for force provider + */ + void calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) override; - //! Return the state of the forceprovider. - DensityFittingForceProviderState state(); + //! Return the state of the forceprovider. + DensityFittingForceProviderState state(); - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_APPLIED_FORCES_DENSITYFITTINGFORCEPROVIDER_H diff --git a/src/gromacs/applied_forces/densityfittingoptions.cpp b/src/gromacs/applied_forces/densityfittingoptions.cpp index 4243ba0446..5a1a01d1be 100644 --- a/src/gromacs/applied_forces/densityfittingoptions.cpp +++ b/src/gromacs/applied_forces/densityfittingoptions.cpp @@ -75,15 +75,15 @@ namespace * \param[in] optionTag string tag that describes the mdp option, appended to the * default string for the density guided simulation */ -template -void densityfittingMdpTransformFromString(IKeyValueTreeTransformRules * rules, - TransformWithFunctionType transformationFunction, - const std::string &optionTag) +template +void densityfittingMdpTransformFromString(IKeyValueTreeTransformRules* rules, + TransformWithFunctionType transformationFunction, + const std::string& optionTag) { rules->addRule() - .from("/" + DensityFittingModuleInfo::name_ + "-" + optionTag) - .to("/" + DensityFittingModuleInfo::name_ +"/" + optionTag) - .transformWith(transformationFunction); + .from("/" + DensityFittingModuleInfo::name_ + "-" + optionTag) + .to("/" + DensityFittingModuleInfo::name_ + "/" + optionTag) + .transformWith(transformationFunction); } /*! \brief Helper to declare mdp output. * @@ -97,13 +97,12 @@ void densityfittingMdpTransformFromString(IKeyValueTreeTransformRules * rules, * \param[in] optionTag string tag that describes the mdp option, appended to the * default string for the density guided simulation */ -template -void addDensityFittingMdpOutputValue(KeyValueTreeObjectBuilder *builder, - const OptionType &option, - const std::string &optionTag) +template +void addDensityFittingMdpOutputValue(KeyValueTreeObjectBuilder* builder, + const OptionType& option, + const std::string& optionTag) { - builder->addValue(DensityFittingModuleInfo::name_ + "-" + optionTag, - option); + builder->addValue(DensityFittingModuleInfo::name_ + "-" + optionTag, option); } /*! \brief Helper to declare mdp output comments. @@ -116,35 +115,39 @@ void addDensityFittingMdpOutputValue(KeyValueTreeObjectBuilder *builder, * \param[in] comment on the mdp option * \param[in] optionTag string tag that describes the mdp option */ -void addDensityFittingMdpOutputValueComment(KeyValueTreeObjectBuilder *builder, - const std::string &comment, - const std::string &optionTag) +void addDensityFittingMdpOutputValueComment(KeyValueTreeObjectBuilder* builder, + const std::string& comment, + const std::string& optionTag) { builder->addValue("comment-" + DensityFittingModuleInfo::name_ + "-" + optionTag, comment); } -} // namespace +} // namespace -void DensityFittingOptions::initMdpTransform(IKeyValueTreeTransformRules * rules) +void DensityFittingOptions::initMdpTransform(IKeyValueTreeTransformRules* rules) { - const auto &stringIdentityTransform = [](std::string s){ - return s; - }; + const auto& stringIdentityTransform = [](std::string s) { return s; }; densityfittingMdpTransformFromString(rules, &fromStdString, c_activeTag_); densityfittingMdpTransformFromString(rules, stringIdentityTransform, c_groupTag_); - densityfittingMdpTransformFromString(rules, stringIdentityTransform, c_similarityMeasureTag_); + densityfittingMdpTransformFromString(rules, stringIdentityTransform, + c_similarityMeasureTag_); densityfittingMdpTransformFromString(rules, stringIdentityTransform, c_amplitudeMethodTag_); densityfittingMdpTransformFromString(rules, &fromStdString, c_forceConstantTag_); - densityfittingMdpTransformFromString(rules, &fromStdString, c_gaussianTransformSpreadingWidthTag_); - densityfittingMdpTransformFromString(rules, &fromStdString, c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_); - densityfittingMdpTransformFromString(rules, stringIdentityTransform, c_referenceDensityFileNameTag_); - densityfittingMdpTransformFromString(rules, &fromStdString, c_everyNStepsTag_); + densityfittingMdpTransformFromString(rules, &fromStdString, + c_gaussianTransformSpreadingWidthTag_); + densityfittingMdpTransformFromString( + rules, &fromStdString, c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_); + densityfittingMdpTransformFromString(rules, stringIdentityTransform, + c_referenceDensityFileNameTag_); + densityfittingMdpTransformFromString(rules, &fromStdString, + c_everyNStepsTag_); densityfittingMdpTransformFromString(rules, &fromStdString, c_normalizeDensitiesTag_); densityfittingMdpTransformFromString(rules, &fromStdString, c_adaptiveForceScalingTag_); - densityfittingMdpTransformFromString(rules, &fromStdString, c_adaptiveForceScalingTimeConstantTag_); + densityfittingMdpTransformFromString(rules, &fromStdString, + c_adaptiveForceScalingTimeConstantTag_); } -void DensityFittingOptions::buildMdpOutput(KeyValueTreeObjectBuilder *builder) const +void DensityFittingOptions::buildMdpOutput(KeyValueTreeObjectBuilder* builder) const { addDensityFittingMdpOutputValueComment(builder, "", "empty-line"); @@ -155,32 +158,49 @@ void DensityFittingOptions::buildMdpOutput(KeyValueTreeObjectBuilder *builder) c { addDensityFittingMdpOutputValue(builder, groupString_, c_groupTag_); - addDensityFittingMdpOutputValueComment(builder, "; Similarity measure between densities: inner-product, relative-entropy, or cross-correlation", c_similarityMeasureTag_); - addDensityFittingMdpOutputValue(builder, - c_densitySimilarityMeasureMethodNames[parameters_.similarityMeasureMethod_], - c_similarityMeasureTag_); + addDensityFittingMdpOutputValueComment( + builder, + "; Similarity measure between densities: inner-product, relative-entropy, or " + "cross-correlation", + c_similarityMeasureTag_); + addDensityFittingMdpOutputValue( + builder, c_densitySimilarityMeasureMethodNames[parameters_.similarityMeasureMethod_], + c_similarityMeasureTag_); - addDensityFittingMdpOutputValueComment(builder, "; Atom amplitude for spreading onto grid: unity, mass, or charge", c_amplitudeMethodTag_); - addDensityFittingMdpOutputValue(builder, - c_densityFittingAmplitudeMethodNames[parameters_.amplitudeLookupMethod_], - c_amplitudeMethodTag_); + addDensityFittingMdpOutputValueComment( + builder, "; Atom amplitude for spreading onto grid: unity, mass, or charge", + c_amplitudeMethodTag_); + addDensityFittingMdpOutputValue( + builder, c_densityFittingAmplitudeMethodNames[parameters_.amplitudeLookupMethod_], + c_amplitudeMethodTag_); addDensityFittingMdpOutputValue(builder, parameters_.forceConstant_, c_forceConstantTag_); - addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingWidth_, c_gaussianTransformSpreadingWidthTag_); - addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_, c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_); - addDensityFittingMdpOutputValueComment(builder, "; Reference density file location as absolute path or relative to the gmx mdrun calling location", c_referenceDensityFileNameTag_); + addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingWidth_, + c_gaussianTransformSpreadingWidthTag_); + addDensityFittingMdpOutputValue(builder, parameters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_, + c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_); + addDensityFittingMdpOutputValueComment(builder, + "; Reference density file location as absolute path " + "or relative to the gmx mdrun calling location", + c_referenceDensityFileNameTag_); addDensityFittingMdpOutputValue(builder, referenceDensityFileName_, c_referenceDensityFileNameTag_); addDensityFittingMdpOutputValue(builder, parameters_.calculationIntervalInSteps_, c_everyNStepsTag_); - addDensityFittingMdpOutputValueComment(builder, "; Normalize the sum of density voxel values to one", c_normalizeDensitiesTag_); + addDensityFittingMdpOutputValueComment( + builder, "; Normalize the sum of density voxel values to one", c_normalizeDensitiesTag_); addDensityFittingMdpOutputValue(builder, parameters_.normalizeDensities_, c_normalizeDensitiesTag_); - addDensityFittingMdpOutputValueComment(builder, "; Apply adaptive force scaling", c_adaptiveForceScalingTag_); - addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScaling_, c_adaptiveForceScalingTag_); - addDensityFittingMdpOutputValueComment(builder, "; Time constant for adaptive force scaling in ps", c_adaptiveForceScalingTimeConstantTag_); - addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScalingTimeConstant_, c_adaptiveForceScalingTimeConstantTag_); + addDensityFittingMdpOutputValueComment(builder, "; Apply adaptive force scaling", + c_adaptiveForceScalingTag_); + addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScaling_, + c_adaptiveForceScalingTag_); + addDensityFittingMdpOutputValueComment(builder, + "; Time constant for adaptive force scaling in ps", + c_adaptiveForceScalingTimeConstantTag_); + addDensityFittingMdpOutputValue(builder, parameters_.adaptiveForceScalingTimeConstant_, + c_adaptiveForceScalingTimeConstantTag_); } } -void DensityFittingOptions::initMdpOptions(IOptionsContainerWithSections *options) +void DensityFittingOptions::initMdpOptions(IOptionsContainerWithSections* options) { auto section = options->addSection(OptionSection(DensityFittingModuleInfo::name_.c_str())); @@ -188,21 +208,25 @@ void DensityFittingOptions::initMdpOptions(IOptionsContainerWithSections *option section.addOption(StringOption(c_groupTag_.c_str()).store(&groupString_)); section.addOption(EnumOption(c_similarityMeasureTag_.c_str()) - .enumValue(c_densitySimilarityMeasureMethodNames.m_elements) - .store(¶meters_.similarityMeasureMethod_)); + .enumValue(c_densitySimilarityMeasureMethodNames.m_elements) + .store(¶meters_.similarityMeasureMethod_)); section.addOption(EnumOption(c_amplitudeMethodTag_.c_str()) - .enumValue(c_densityFittingAmplitudeMethodNames.m_elements) - .store(¶meters_.amplitudeLookupMethod_)); + .enumValue(c_densityFittingAmplitudeMethodNames.m_elements) + .store(¶meters_.amplitudeLookupMethod_)); section.addOption(RealOption(c_forceConstantTag_.c_str()).store(¶meters_.forceConstant_)); - section.addOption(RealOption(c_gaussianTransformSpreadingWidthTag_.c_str()).store(¶meters_.gaussianTransformSpreadingWidth_)); - section.addOption(RealOption(c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_.c_str()).store(¶meters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_)); + section.addOption(RealOption(c_gaussianTransformSpreadingWidthTag_.c_str()) + .store(¶meters_.gaussianTransformSpreadingWidth_)); + section.addOption(RealOption(c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_.c_str()) + .store(¶meters_.gaussianTransformSpreadingRangeInMultiplesOfWidth_)); section.addOption(StringOption(c_referenceDensityFileNameTag_.c_str()).store(&referenceDensityFileName_)); section.addOption(Int64Option(c_everyNStepsTag_.c_str()).store(¶meters_.calculationIntervalInSteps_)); section.addOption(BooleanOption(c_normalizeDensitiesTag_.c_str()).store(¶meters_.normalizeDensities_)); - section.addOption(BooleanOption(c_adaptiveForceScalingTag_.c_str()).store(¶meters_.adaptiveForceScaling_)); - section.addOption(RealOption(c_adaptiveForceScalingTimeConstantTag_.c_str()).store(¶meters_.adaptiveForceScalingTimeConstant_)); + section.addOption( + BooleanOption(c_adaptiveForceScalingTag_.c_str()).store(¶meters_.adaptiveForceScaling_)); + section.addOption(RealOption(c_adaptiveForceScalingTimeConstantTag_.c_str()) + .store(¶meters_.adaptiveForceScalingTimeConstant_)); } bool DensityFittingOptions::active() const @@ -210,7 +234,7 @@ bool DensityFittingOptions::active() const return parameters_.active_; } -const DensityFittingParameters &DensityFittingOptions::buildParameters() +const DensityFittingParameters& DensityFittingOptions::buildParameters() { // the options modules does not know unsigned integers so any input of this // kind is rectified here @@ -221,7 +245,7 @@ const DensityFittingParameters &DensityFittingOptions::buildParameters() return parameters_; } -void DensityFittingOptions::setFitGroupIndices(const IndexGroupsAndNames &indexGroupsAndNames) +void DensityFittingOptions::setFitGroupIndices(const IndexGroupsAndNames& indexGroupsAndNames) { if (!parameters_.active_) { @@ -232,14 +256,15 @@ void DensityFittingOptions::setFitGroupIndices(const IndexGroupsAndNames &indexG void DensityFittingOptions::writeInternalParametersToKvt(KeyValueTreeObjectBuilder treeBuilder) { - auto groupIndexAdder = treeBuilder.addUniformArray(DensityFittingModuleInfo::name_ + "-" + c_groupTag_); - for (const auto &indexValue : parameters_.indices_) + auto groupIndexAdder = treeBuilder.addUniformArray(DensityFittingModuleInfo::name_ + + "-" + c_groupTag_); + for (const auto& indexValue : parameters_.indices_) { groupIndexAdder.addValue(indexValue); } } -void DensityFittingOptions::readInternalParametersFromKvt(const KeyValueTreeObject &tree) +void DensityFittingOptions::readInternalParametersFromKvt(const KeyValueTreeObject& tree) { if (!parameters_.active_) { @@ -249,26 +274,29 @@ void DensityFittingOptions::readInternalParametersFromKvt(const KeyValueTreeObje if (!tree.keyExists(DensityFittingModuleInfo::name_ + "-" + c_groupTag_)) { GMX_THROW(InconsistentInputError( - "Cannot find atom index vector required for density guided simulation.")); + "Cannot find atom index vector required for density guided simulation.")); } auto kvtIndexArray = tree[DensityFittingModuleInfo::name_ + "-" + c_groupTag_].asArray().values(); parameters_.indices_.resize(kvtIndexArray.size()); std::transform(std::begin(kvtIndexArray), std::end(kvtIndexArray), std::begin(parameters_.indices_), - [](const KeyValueTreeValue &val) { return val.cast(); }); + [](const KeyValueTreeValue& val) { return val.cast(); }); } -void DensityFittingOptions::checkEnergyCaluclationFrequency(EnergyCalculationFrequencyErrors * energyCalculationFrequencyErrors) const +void DensityFittingOptions::checkEnergyCaluclationFrequency( + EnergyCalculationFrequencyErrors* energyCalculationFrequencyErrors) const { - if (energyCalculationFrequencyErrors->energyCalculationIntervalInSteps() % parameters_.calculationIntervalInSteps_ != 0) + if (energyCalculationFrequencyErrors->energyCalculationIntervalInSteps() % parameters_.calculationIntervalInSteps_ + != 0) { - energyCalculationFrequencyErrors->addError("nstcalcenergy (" + - toString(energyCalculationFrequencyErrors->energyCalculationIntervalInSteps()) - + ") is not a multiple of " + DensityFittingModuleInfo::name_ + "-" + c_everyNStepsTag_ - + " (" + toString(parameters_.calculationIntervalInSteps_) + ") ."); + energyCalculationFrequencyErrors->addError( + "nstcalcenergy (" + + toString(energyCalculationFrequencyErrors->energyCalculationIntervalInSteps()) + + ") is not a multiple of " + DensityFittingModuleInfo::name_ + "-" + c_everyNStepsTag_ + + " (" + toString(parameters_.calculationIntervalInSteps_) + ") ."); } } -const std::string &DensityFittingOptions::referenceDensityFileName() const +const std::string& DensityFittingOptions::referenceDensityFileName() const { return referenceDensityFileName_; } diff --git a/src/gromacs/applied_forces/densityfittingoptions.h b/src/gromacs/applied_forces/densityfittingoptions.h index af5d24df02..993a94b00e 100644 --- a/src/gromacs/applied_forces/densityfittingoptions.h +++ b/src/gromacs/applied_forces/densityfittingoptions.h @@ -61,82 +61,83 @@ class KeyValueTreeBuilder; */ class DensityFittingOptions final : public IMdpOptionProvider { - public: - //! From IMdpOptionProvider - void initMdpTransform(IKeyValueTreeTransformRules * rules) override; +public: + //! From IMdpOptionProvider + void initMdpTransform(IKeyValueTreeTransformRules* rules) override; - /*! \brief - * Build mdp parameters for density fitting to be output after pre-processing. - * \param[in, out] builder the builder for the mdp options output KV-tree. - * \note This should be symmetrical to option initialization without - * employing manual prefixing with the section name string once - * the legacy code blocking this design is removed. - */ - void buildMdpOutput(KeyValueTreeObjectBuilder *builder) const override; + /*! \brief + * Build mdp parameters for density fitting to be output after pre-processing. + * \param[in, out] builder the builder for the mdp options output KV-tree. + * \note This should be symmetrical to option initialization without + * employing manual prefixing with the section name string once + * the legacy code blocking this design is removed. + */ + void buildMdpOutput(KeyValueTreeObjectBuilder* builder) const override; - /*! \brief - * Connect option name and data. - */ - void initMdpOptions(IOptionsContainerWithSections *options) override; + /*! \brief + * Connect option name and data. + */ + void initMdpOptions(IOptionsContainerWithSections* options) override; - //! Report if this set of options is active - bool active() const; + //! Report if this set of options is active + bool active() const; - //! Process input options to parameters, including input file reading. - const DensityFittingParameters &buildParameters(); + //! Process input options to parameters, including input file reading. + const DensityFittingParameters& buildParameters(); - /*! \brief Evaluate and store atom indices. - * - * During pre-processing, use the group string from the options to - * evaluate the indices of the atoms to be subject to forces from this - * module. - */ - void setFitGroupIndices(const IndexGroupsAndNames &indexGroupsAndNames); + /*! \brief Evaluate and store atom indices. + * + * During pre-processing, use the group string from the options to + * evaluate the indices of the atoms to be subject to forces from this + * module. + */ + void setFitGroupIndices(const IndexGroupsAndNames& indexGroupsAndNames); - //! Store the paramers that are not mdp options in the tpr file - void writeInternalParametersToKvt(KeyValueTreeObjectBuilder treeBuilder); + //! Store the paramers that are not mdp options in the tpr file + void writeInternalParametersToKvt(KeyValueTreeObjectBuilder treeBuilder); - //! Set the internal parameters that are stored in the tpr file - void readInternalParametersFromKvt(const KeyValueTreeObject &tree); + //! Set the internal parameters that are stored in the tpr file + void readInternalParametersFromKvt(const KeyValueTreeObject& tree); - //! Return the file name of the reference density - const std::string &referenceDensityFileName() const; + //! Return the file name of the reference density + const std::string& referenceDensityFileName() const; - //! Check if input parameters are consistent with other simulation parameters - void checkEnergyCaluclationFrequency(EnergyCalculationFrequencyErrors * energyCalculationFrequencyErrors) const; + //! Check if input parameters are consistent with other simulation parameters + void checkEnergyCaluclationFrequency(EnergyCalculationFrequencyErrors* energyCalculationFrequencyErrors) const; - private: - const std::string c_activeTag_ = "active"; +private: + const std::string c_activeTag_ = "active"; - /*! \brief Denote the .mdp option that defines the group of fit atoms. - * \note Changing this string will break .tpr backwards compability - */ - const std::string c_groupTag_ = "group"; - std::string groupString_ = "protein"; + /*! \brief Denote the .mdp option that defines the group of fit atoms. + * \note Changing this string will break .tpr backwards compability + */ + const std::string c_groupTag_ = "group"; + std::string groupString_ = "protein"; - const std::string c_similarityMeasureTag_ = "similarity-measure"; + const std::string c_similarityMeasureTag_ = "similarity-measure"; - const std::string c_amplitudeMethodTag_ = "atom-spreading-weight"; + const std::string c_amplitudeMethodTag_ = "atom-spreading-weight"; - const std::string c_forceConstantTag_ = "force-constant"; + const std::string c_forceConstantTag_ = "force-constant"; - const std::string c_gaussianTransformSpreadingWidthTag_ = "gaussian-transform-spreading-width"; - const std::string c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_ - = "gaussian-transform-spreading-range-in-multiples-of-width"; + const std::string c_gaussianTransformSpreadingWidthTag_ = "gaussian-transform-spreading-width"; + const std::string c_gaussianTransformSpreadingRangeInMultiplesOfWidthTag_ = + "gaussian-transform-spreading-range-in-multiples-of-width"; - const std::string c_referenceDensityFileNameTag_ = "reference-density-filename"; - std::string referenceDensityFileName_ = "reference.mrc"; + const std::string c_referenceDensityFileNameTag_ = "reference-density-filename"; + std::string referenceDensityFileName_ = "reference.mrc"; - const std::string c_everyNStepsTag_ = "nst"; + const std::string c_everyNStepsTag_ = "nst"; - const std::string c_normalizeDensitiesTag_ = "normalize-densities"; + const std::string c_normalizeDensitiesTag_ = "normalize-densities"; - const std::string c_adaptiveForceScalingTag_ = "adaptive-force-scaling"; + const std::string c_adaptiveForceScalingTag_ = "adaptive-force-scaling"; - const std::string c_adaptiveForceScalingTimeConstantTag_ = "adaptive-force-scaling-time-constant"; + const std::string c_adaptiveForceScalingTimeConstantTag_ = + "adaptive-force-scaling-time-constant"; - DensityFittingParameters parameters_; + DensityFittingParameters parameters_; }; } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingoutputprovider.cpp b/src/gromacs/applied_forces/densityfittingoutputprovider.cpp index c32f49af0e..8b4aebf8f5 100644 --- a/src/gromacs/applied_forces/densityfittingoutputprovider.cpp +++ b/src/gromacs/applied_forces/densityfittingoutputprovider.cpp @@ -46,11 +46,14 @@ namespace gmx { -void DensityFittingOutputProvider::initOutput(FILE * /*fplog*/, int /*nfile*/, - const t_filenm /*fnm*/[], bool /*bAppendFiles*/, const gmx_output_env_t * /*oenv*/) -{} +void DensityFittingOutputProvider::initOutput(FILE* /*fplog*/, + int /*nfile*/, + const t_filenm /*fnm*/[], + bool /*bAppendFiles*/, + const gmx_output_env_t* /*oenv*/) +{ +} -void DensityFittingOutputProvider::finishOutput() -{} +void DensityFittingOutputProvider::finishOutput() {} } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingoutputprovider.h b/src/gromacs/applied_forces/densityfittingoutputprovider.h index 6bbc3c6ed3..6958f4e2fc 100644 --- a/src/gromacs/applied_forces/densityfittingoutputprovider.h +++ b/src/gromacs/applied_forces/densityfittingoutputprovider.h @@ -52,12 +52,15 @@ namespace gmx */ class DensityFittingOutputProvider final : public IMDOutputProvider { - public: - //! Initialize output - void initOutput(FILE * /*fplog*/, int /*nfile*/, const t_filenm /*fnm*/[], - bool /*bAppendFiles*/, const gmx_output_env_t * /*oenv*/) override; - //! Finalizes output from a simulation run. - void finishOutput() override; +public: + //! Initialize output + void initOutput(FILE* /*fplog*/, + int /*nfile*/, + const t_filenm /*fnm*/[], + bool /*bAppendFiles*/, + const gmx_output_env_t* /*oenv*/) override; + //! Finalizes output from a simulation run. + void finishOutput() override; }; } // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingparameters.cpp b/src/gromacs/applied_forces/densityfittingparameters.cpp index 68af26e54e..ee7a725e47 100644 --- a/src/gromacs/applied_forces/densityfittingparameters.cpp +++ b/src/gromacs/applied_forces/densityfittingparameters.cpp @@ -40,7 +40,7 @@ namespace gmx { -bool operator==(const DensityFittingParameters &lhs, const DensityFittingParameters &rhs) +bool operator==(const DensityFittingParameters& lhs, const DensityFittingParameters& rhs) { if (lhs.active_ != rhs.active_) { @@ -66,16 +66,17 @@ bool operator==(const DensityFittingParameters &lhs, const DensityFittingParamet { return false; } - if (lhs.gaussianTransformSpreadingRangeInMultiplesOfWidth_ != rhs.gaussianTransformSpreadingRangeInMultiplesOfWidth_) + if (lhs.gaussianTransformSpreadingRangeInMultiplesOfWidth_ + != rhs.gaussianTransformSpreadingRangeInMultiplesOfWidth_) { return false; } return true; } -bool operator!=(const DensityFittingParameters &lhs, const DensityFittingParameters &rhs) +bool operator!=(const DensityFittingParameters& lhs, const DensityFittingParameters& rhs) { return !(lhs == rhs); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/applied_forces/densityfittingparameters.h b/src/gromacs/applied_forces/densityfittingparameters.h index 9e576fcb02..96ec5900b2 100644 --- a/src/gromacs/applied_forces/densityfittingparameters.h +++ b/src/gromacs/applied_forces/densityfittingparameters.h @@ -60,27 +60,27 @@ namespace gmx struct DensityFittingParameters { //! Indicate if density fitting is active - bool active_ = false; + bool active_ = false; //! Indices of the atoms that shall be fit to the density - std::vector indices_; + std::vector indices_; //! Determines how to measure similarity between simulated and reference density DensitySimilarityMeasureMethod similarityMeasureMethod_ = DensitySimilarityMeasureMethod::innerProduct; //! Determines with what weight atoms are spread - DensityFittingAmplitudeMethod amplitudeLookupMethod_ = DensityFittingAmplitudeMethod::Unity; + DensityFittingAmplitudeMethod amplitudeLookupMethod_ = DensityFittingAmplitudeMethod::Unity; //! The force constant to be used for the density fitting - real forceConstant_ = 1e9; + real forceConstant_ = 1e9; //! The spreading width used for the gauss transform of atoms onto the density grid - real gaussianTransformSpreadingWidth_ = 0.2; + real gaussianTransformSpreadingWidth_ = 0.2; //! The spreading range for spreading atoms onto the grid in multiples of the spreading width - real gaussianTransformSpreadingRangeInMultiplesOfWidth_ = 4.0; + real gaussianTransformSpreadingRangeInMultiplesOfWidth_ = 4.0; //! Apply density fitting forces only every n-steps - std::int64_t calculationIntervalInSteps_ = 1; + std::int64_t calculationIntervalInSteps_ = 1; //! Normalize reference and simulated densities - bool normalizeDensities_ = true; + bool normalizeDensities_ = true; //! Perform adaptive force scaling during the simulation - bool adaptiveForceScaling_ = false; + bool adaptiveForceScaling_ = false; //! The time constant for the adaptive force scaling in ps - real adaptiveForceScalingTimeConstant_ = 4; + real adaptiveForceScalingTimeConstant_ = 4; }; /*!\brief Check if two structs holding density fitting parameters are equal. @@ -89,7 +89,7 @@ struct DensityFittingParameters * \param[in] rhs right hand side to be compared * \returns true if all elements in DensityFittingParameters are equal, else false */ -bool operator==(const DensityFittingParameters &lhs, const DensityFittingParameters &rhs); +bool operator==(const DensityFittingParameters& lhs, const DensityFittingParameters& rhs); /*!\brief Check if two structs holding density fitting parameters are not equal. * @@ -97,8 +97,8 @@ bool operator==(const DensityFittingParameters &lhs, const DensityFittingParamet * \param[in] rhs right hand side to be compared * \returns true if lhs is not equal rhs */ -bool operator!=(const DensityFittingParameters &lhs, const DensityFittingParameters &rhs); +bool operator!=(const DensityFittingParameters& lhs, const DensityFittingParameters& rhs); -} // namespace gmx +} // namespace gmx #endif // GMX_APPLIED_FORCES_DENSITYFITTINGPARAMETERS_H diff --git a/src/gromacs/applied_forces/electricfield.cpp b/src/gromacs/applied_forces/electricfield.cpp index 77b83d715b..5bc278142d 100644 --- a/src/gromacs/applied_forces/electricfield.cpp +++ b/src/gromacs/applied_forces/electricfield.cpp @@ -83,56 +83,55 @@ namespace */ class ElectricFieldDimension { - public: - /*! \brief - * Adds an option section to specify parameters for this field component. - */ - void initMdpOptions(IOptionsContainerWithSections *options, const char *sectionName) +public: + /*! \brief + * Adds an option section to specify parameters for this field component. + */ + void initMdpOptions(IOptionsContainerWithSections* options, const char* sectionName) + { + auto section = options->addSection(OptionSection(sectionName)); + section.addOption(RealOption("E0").store(&a_)); + section.addOption(RealOption("omega").store(&omega_)); + section.addOption(RealOption("t0").store(&t0_)); + section.addOption(RealOption("sigma").store(&sigma_)); + } + /*! \brief + * Creates mdp parameters for this field component. + */ + void buildMdpOutput(KeyValueTreeObjectBuilder* builder, const std::string& name) const + { + builder->addUniformArray("electric-field-" + name, { a_, omega_, t0_, sigma_ }); + } + + /*! \brief Evaluates this field component at given time. + * + * \param[in] t The time to evualate at + * \return The electric field + */ + real evaluate(real t) const + { + if (sigma_ > 0) { - auto section = options->addSection(OptionSection(sectionName)); - section.addOption(RealOption("E0").store(&a_)); - section.addOption(RealOption("omega").store(&omega_)); - section.addOption(RealOption("t0").store(&t0_)); - section.addOption(RealOption("sigma").store(&sigma_)); + return a_ * (std::cos(omega_ * (t - t0_)) * std::exp(-square(t - t0_) / (2.0 * square(sigma_)))); } - /*! \brief - * Creates mdp parameters for this field component. - */ - void buildMdpOutput(KeyValueTreeObjectBuilder *builder, const std::string &name) const + else { - builder->addUniformArray("electric-field-" + name, {a_, omega_, t0_, sigma_}); - } - - /*! \brief Evaluates this field component at given time. - * - * \param[in] t The time to evualate at - * \return The electric field - */ - real evaluate(real t) const - { - if (sigma_ > 0) - { - return a_ * (std::cos(omega_*(t-t0_)) - * std::exp(-square(t-t0_)/(2.0*square(sigma_)))); - } - else - { - return a_ * std::cos(omega_*t); - } + return a_ * std::cos(omega_ * t); } + } - //! Return the amplitude - real a() const { return a_; } - - private: - //! Coeffient (V / nm) - real a_ = 0; - //! Frequency (1/ps) - real omega_ = 0; - //! Central time point (ps) for pulse - real t0_ = 0; - //! Width of pulse (ps, if zero there is no pulse) - real sigma_ = 0; + //! Return the amplitude + real a() const { return a_; } + +private: + //! Coeffient (V / nm) + real a_ = 0; + //! Frequency (1/ps) + real omega_ = 0; + //! Central time point (ps) for pulse + real t0_ = 0; + //! Width of pulse (ps, if zero there is no pulse) + real sigma_ = 0; }; /*! \internal @@ -142,67 +141,63 @@ class ElectricFieldDimension * The electric field can be pulsed and oscillating, simply * oscillating, or static, in each of X,Y,Z directions. */ -class ElectricField final : public IMDModule, - public IMdpOptionProvider, public IMDOutputProvider, - public IForceProvider +class ElectricField final : public IMDModule, public IMdpOptionProvider, public IMDOutputProvider, public IForceProvider { - public: - ElectricField() : fpField_(nullptr) {} +public: + ElectricField() : fpField_(nullptr) {} - // From IMDModule - IMdpOptionProvider *mdpOptionProvider() override { return this; } - IMDOutputProvider *outputProvider() override { return this; } - void initForceProviders(ForceProviders *forceProviders) override + // From IMDModule + IMdpOptionProvider* mdpOptionProvider() override { return this; } + IMDOutputProvider* outputProvider() override { return this; } + void initForceProviders(ForceProviders* forceProviders) override + { + if (isActive()) { - if (isActive()) - { - forceProviders->addForceProvider(this); - } + forceProviders->addForceProvider(this); } + } - // From IMdpOptionProvider - void initMdpTransform(IKeyValueTreeTransformRules *transform) override; - void initMdpOptions(IOptionsContainerWithSections *options) override; - void buildMdpOutput(KeyValueTreeObjectBuilder *builder) const override; - - // From IMDOutputProvider - void initOutput(FILE *fplog, int nfile, const t_filenm fnm[], - bool bAppendFiles, const gmx_output_env_t *oenv) override; - void finishOutput() override; - - // From IForceProvider - //! \copydoc IForceProvider::calculateForces() - void calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) override; - - private: - //! Return whether or not to apply a field - bool isActive() const; - - /*! \brief Return the field strength - * - * \param[in] dim The spatial direction - * \param[in] t The time (ps) - * \return The field strength in V/nm units - */ - real field(int dim, real t) const; - - /*! \brief Print the field components to a file - * - * \param[in] t The time - * Will throw and exit with fatal error if file is not open. - */ - void printComponents(double t) const; - - //! The components of the applied electric field in each coordinate dimension - ElectricFieldDimension efield_[DIM]; - //! File pointer for electric field - FILE *fpField_; + // From IMdpOptionProvider + void initMdpTransform(IKeyValueTreeTransformRules* transform) override; + void initMdpOptions(IOptionsContainerWithSections* options) override; + void buildMdpOutput(KeyValueTreeObjectBuilder* builder) const override; + + // From IMDOutputProvider + void initOutput(FILE* fplog, int nfile, const t_filenm fnm[], bool bAppendFiles, const gmx_output_env_t* oenv) override; + void finishOutput() override; + + // From IForceProvider + //! \copydoc IForceProvider::calculateForces() + void calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) override; + +private: + //! Return whether or not to apply a field + bool isActive() const; + + /*! \brief Return the field strength + * + * \param[in] dim The spatial direction + * \param[in] t The time (ps) + * \return The field strength in V/nm units + */ + real field(int dim, real t) const; + + /*! \brief Print the field components to a file + * + * \param[in] t The time + * Will throw and exit with fatal error if file is not open. + */ + void printComponents(double t) const; + + //! The components of the applied electric field in each coordinate dimension + ElectricFieldDimension efield_[DIM]; + //! File pointer for electric field + FILE* fpField_; }; //! Converts dynamic parameters from new mdp format to (E0, omega, t0, sigma). -void convertParameters(gmx::KeyValueTreeObjectBuilder *builder, - const std::string &value) +void convertParameters(gmx::KeyValueTreeObjectBuilder* builder, const std::string& value) { const std::vector sxt = splitString(value); if (sxt.empty()) @@ -219,17 +214,14 @@ void convertParameters(gmx::KeyValueTreeObjectBuilder *builder, builder->addValue("sigma", fromString(sxt[3])); } -void ElectricField::initMdpTransform(IKeyValueTreeTransformRules *rules) +void ElectricField::initMdpTransform(IKeyValueTreeTransformRules* rules) { - rules->addRule().from("/electric-field-x").toObject("/electric-field/x") - .transformWith(&convertParameters); - rules->addRule().from("/electric-field-y").toObject("/electric-field/y") - .transformWith(&convertParameters); - rules->addRule().from("/electric-field-z").toObject("/electric-field/z") - .transformWith(&convertParameters); + rules->addRule().from("/electric-field-x").toObject("/electric-field/x").transformWith(&convertParameters); + rules->addRule().from("/electric-field-y").toObject("/electric-field/y").transformWith(&convertParameters); + rules->addRule().from("/electric-field-z").toObject("/electric-field/z").transformWith(&convertParameters); } -void ElectricField::initMdpOptions(IOptionsContainerWithSections *options) +void ElectricField::initMdpOptions(IOptionsContainerWithSections* options) { auto section = options->addSection(OptionSection("electric-field")); efield_[XX].initMdpOptions(§ion, "x"); @@ -237,10 +229,10 @@ void ElectricField::initMdpOptions(IOptionsContainerWithSections *options) efield_[ZZ].initMdpOptions(§ion, "z"); } -void ElectricField::buildMdpOutput(KeyValueTreeObjectBuilder *builder) const +void ElectricField::buildMdpOutput(KeyValueTreeObjectBuilder* builder) const { std::string comment = - R"(; Electric fields + R"(; Electric fields ; Format for electric-field-x, etc. is: four real variables: ; amplitude (V/nm), frequency omega (1/ps), time for the pulse peak (ps), ; and sigma (ps) width of the pulse. Omega = 0 means static field, @@ -251,8 +243,7 @@ void ElectricField::buildMdpOutput(KeyValueTreeObjectBuilder *builder) const efield_[ZZ].buildMdpOutput(builder, "z"); } -void ElectricField::initOutput(FILE *fplog, int nfile, const t_filenm fnm[], - bool bAppendFiles, const gmx_output_env_t *oenv) +void ElectricField::initOutput(FILE* fplog, int nfile, const t_filenm fnm[], bool bAppendFiles, const gmx_output_env_t* oenv) { if (isActive()) { @@ -267,9 +258,8 @@ void ElectricField::initOutput(FILE *fplog, int nfile, const t_filenm fnm[], } else { - fpField_ = xvgropen(opt2fn("-field", nfile, fnm), - "Applied electric field", "Time (ps)", - "E (V/nm)", oenv); + fpField_ = xvgropen(opt2fn("-field", nfile, fnm), "Applied electric field", + "Time (ps)", "E (V/nm)", oenv); } } } @@ -293,32 +283,29 @@ real ElectricField::field(int dim, real t) const bool ElectricField::isActive() const { - return (efield_[XX].a() != 0 || - efield_[YY].a() != 0 || - efield_[ZZ].a() != 0); + return (efield_[XX].a() != 0 || efield_[YY].a() != 0 || efield_[ZZ].a() != 0); } void ElectricField::printComponents(double t) const { - fprintf(fpField_, "%10g %10g %10g %10g\n", t, - field(XX, t), field(YY, t), field(ZZ, t)); + fprintf(fpField_, "%10g %10g %10g %10g\n", t, field(XX, t), field(YY, t), field(ZZ, t)); } -void ElectricField::calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) +void ElectricField::calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) { if (isActive()) { - const t_mdatoms &mdatoms = forceProviderInput.mdatoms_; + const t_mdatoms& mdatoms = forceProviderInput.mdatoms_; const double t = forceProviderInput.t_; - const t_commrec &cr = forceProviderInput.cr_; + const t_commrec& cr = forceProviderInput.cr_; // NOTE: The non-conservative electric field does not have a virial ArrayRef f = forceProviderOutput->forceWithVirial_.force_; for (int m = 0; (m < DIM); m++) { - const real fieldStrength = FIELDFAC*field(m, t); + const real fieldStrength = FIELDFAC * field(m, t); if (fieldStrength != 0) { @@ -326,7 +313,7 @@ void ElectricField::calculateForces(const ForceProviderInput &forceProviderInput for (index i = 0; i != ssize(f); ++i) { // NOTE: Not correct with perturbed charges - f[i][m] += mdatoms.chargeA[i]*fieldStrength; + f[i][m] += mdatoms.chargeA[i] * fieldStrength; } } } @@ -337,7 +324,7 @@ void ElectricField::calculateForces(const ForceProviderInput &forceProviderInput } } -} // namespace +} // namespace std::unique_ptr createElectricFieldModule() { diff --git a/src/gromacs/applied_forces/tests/densityfitting.cpp b/src/gromacs/applied_forces/tests/densityfitting.cpp index dbbcc1505a..38f3cb0d4c 100644 --- a/src/gromacs/applied_forces/tests/densityfitting.cpp +++ b/src/gromacs/applied_forces/tests/densityfitting.cpp @@ -75,52 +75,51 @@ namespace class DensityFittingTest : public ::testing::Test { - public: - - void addMdpOptionDensityFittingActive() - { - mdpValueBuilder_.rootObject().addValue("density-guided-simulation-active", std::string("yes")); - } - - void addMdpOptionReferenceDensity() - { - mdpValueBuilder_.rootObject().addValue( - "density-guided-simulation-reference-density-filename", - std::string(test::TestFileManager::getInputFilePath("ellipsoid-density.mrc"))); - } - - //! build an mdp options tree that sets the options for the density fitting module - void makeDensityFittingModuleWithSetOptions() - { - KeyValueTreeObject mdpOptionsTree = mdpValueBuilder_.build(); - - densityFittingModule_ = DensityFittingModuleInfo::create(¬ifier_); - - // set up options - Options densityFittingModuleOptions; - densityFittingModule_->mdpOptionProvider()->initMdpOptions(&densityFittingModuleOptions); - - // Add rules to transform mdp inputs to densityFittingModule data - KeyValueTreeTransformer transform; - transform.rules()->addRule().keyMatchType("/", StringCompareType::CaseAndDashInsensitive); - densityFittingModule_->mdpOptionProvider()->initMdpTransform(transform.rules()); - - // Execute the transform on the mdpValues - auto transformedMdpValues = transform.transform(mdpOptionsTree, nullptr); - assignOptionsFromKeyValueTree(&densityFittingModuleOptions, transformedMdpValues.object(), nullptr); - } - - void intializeForceProviders() - { - densityFittingModule_->initForceProviders(&densityFittingForces_); - } - - protected: - - KeyValueTreeBuilder mdpValueBuilder_; - MdModulesNotifier notifier_; - ForceProviders densityFittingForces_; - std::unique_ptr densityFittingModule_; +public: + void addMdpOptionDensityFittingActive() + { + mdpValueBuilder_.rootObject().addValue("density-guided-simulation-active", + std::string("yes")); + } + + void addMdpOptionReferenceDensity() + { + mdpValueBuilder_.rootObject().addValue( + "density-guided-simulation-reference-density-filename", + std::string(test::TestFileManager::getInputFilePath("ellipsoid-density.mrc"))); + } + + //! build an mdp options tree that sets the options for the density fitting module + void makeDensityFittingModuleWithSetOptions() + { + KeyValueTreeObject mdpOptionsTree = mdpValueBuilder_.build(); + + densityFittingModule_ = DensityFittingModuleInfo::create(¬ifier_); + + // set up options + Options densityFittingModuleOptions; + densityFittingModule_->mdpOptionProvider()->initMdpOptions(&densityFittingModuleOptions); + + // Add rules to transform mdp inputs to densityFittingModule data + KeyValueTreeTransformer transform; + transform.rules()->addRule().keyMatchType("/", StringCompareType::CaseAndDashInsensitive); + densityFittingModule_->mdpOptionProvider()->initMdpTransform(transform.rules()); + + // Execute the transform on the mdpValues + auto transformedMdpValues = transform.transform(mdpOptionsTree, nullptr); + assignOptionsFromKeyValueTree(&densityFittingModuleOptions, transformedMdpValues.object(), nullptr); + } + + void intializeForceProviders() + { + densityFittingModule_->initForceProviders(&densityFittingForces_); + } + +protected: + KeyValueTreeBuilder mdpValueBuilder_; + MdModulesNotifier notifier_; + ForceProviders densityFittingForces_; + std::unique_ptr densityFittingModule_; }; TEST_F(DensityFittingTest, ForceProviderLackingInputThrows) diff --git a/src/gromacs/applied_forces/tests/densityfittingamplitudelookup.cpp b/src/gromacs/applied_forces/tests/densityfittingamplitudelookup.cpp index 9a6804733b..531052885e 100644 --- a/src/gromacs/applied_forces/tests/densityfittingamplitudelookup.cpp +++ b/src/gromacs/applied_forces/tests/densityfittingamplitudelookup.cpp @@ -54,19 +54,20 @@ namespace gmx class DensityFittingAmplitudeLookupTest : public ::testing::Test { - public: - DensityFittingAmplitudeLookupTest() - { - atoms_.nr = numberOfAtoms_; - atoms_.massT = masses_.data(); - atoms_.chargeA = charges_.data(); - } - protected: - int numberOfAtoms_ = 3; - std::vector masses_ = {2, 3, 4}; - std::vector charges_ = {20, 30, 40}; - t_mdatoms atoms_ = {}; - std::vector lookupIndices_ = { 1, 2 }; +public: + DensityFittingAmplitudeLookupTest() + { + atoms_.nr = numberOfAtoms_; + atoms_.massT = masses_.data(); + atoms_.chargeA = charges_.data(); + } + +protected: + int numberOfAtoms_ = 3; + std::vector masses_ = { 2, 3, 4 }; + std::vector charges_ = { 20, 30, 40 }; + t_mdatoms atoms_ = {}; + std::vector lookupIndices_ = { 1, 2 }; }; TEST_F(DensityFittingAmplitudeLookupTest, Unity) diff --git a/src/gromacs/applied_forces/tests/densityfittingoptions.cpp b/src/gromacs/applied_forces/tests/densityfittingoptions.cpp index 88514dc30f..4dcc3c5873 100644 --- a/src/gromacs/applied_forces/tests/densityfittingoptions.cpp +++ b/src/gromacs/applied_forces/tests/densityfittingoptions.cpp @@ -70,69 +70,64 @@ namespace class DensityFittingOptionsTest : public ::testing::Test { - public: - DensityFittingOptionsTest() - { - init_blocka(&defaultGroups_); - } - ~DensityFittingOptionsTest() override - { - done_blocka(&defaultGroups_); - } - - void setFromMdpValues(const KeyValueTreeObject &densityFittingMdpValues) - { - // set up options - Options densityFittingModuleOptions; - densityFittingOptions_.initMdpOptions(&densityFittingModuleOptions); - - // Add rules to transform mdp inputs to densityFittingModule data - KeyValueTreeTransformer transform; - transform.rules()->addRule().keyMatchType("/", StringCompareType::CaseAndDashInsensitive); - - densityFittingOptions_.initMdpTransform(transform.rules()); - - // Execute the transform on the mdpValues - auto transformedMdpValues = transform.transform(densityFittingMdpValues, nullptr); - assignOptionsFromKeyValueTree(&densityFittingModuleOptions, transformedMdpValues.object(), nullptr); - } - - KeyValueTreeObject densityFittingSetActiveAsMdpValues() - { - // Prepare MDP inputs - KeyValueTreeBuilder mdpValueBuilder; - mdpValueBuilder.rootObject().addValue("density-guided-simulation-active", - std::string("yes")); - return mdpValueBuilder.build(); - } - - IndexGroupsAndNames genericIndexGroupsAndNames() - { - done_blocka(&defaultGroups_); - stupid_fill_blocka(&defaultGroups_, 3); - std::vector groupNames = { "A", "protein", "C" }; - const char *const namesAsConstChar[3] - = { groupNames[0].c_str(), groupNames[1].c_str(), groupNames[2].c_str() }; - return {defaultGroups_, namesAsConstChar}; - } - - IndexGroupsAndNames differingIndexGroupsAndNames() - { - done_blocka(&defaultGroups_); - stupid_fill_blocka(&defaultGroups_, 3); - std::vector groupNames = { "protein", "C", "A"}; - const char *const namesAsConstChar[3] - = { groupNames[0].c_str(), groupNames[1].c_str(), groupNames[2].c_str() }; - return { defaultGroups_, namesAsConstChar }; - } - - void mangleInternalParameters() - { - densityFittingOptions_.setFitGroupIndices(differingIndexGroupsAndNames()); - } - protected: - t_blocka defaultGroups_; - DensityFittingOptions densityFittingOptions_; +public: + DensityFittingOptionsTest() { init_blocka(&defaultGroups_); } + ~DensityFittingOptionsTest() override { done_blocka(&defaultGroups_); } + + void setFromMdpValues(const KeyValueTreeObject& densityFittingMdpValues) + { + // set up options + Options densityFittingModuleOptions; + densityFittingOptions_.initMdpOptions(&densityFittingModuleOptions); + + // Add rules to transform mdp inputs to densityFittingModule data + KeyValueTreeTransformer transform; + transform.rules()->addRule().keyMatchType("/", StringCompareType::CaseAndDashInsensitive); + + densityFittingOptions_.initMdpTransform(transform.rules()); + + // Execute the transform on the mdpValues + auto transformedMdpValues = transform.transform(densityFittingMdpValues, nullptr); + assignOptionsFromKeyValueTree(&densityFittingModuleOptions, transformedMdpValues.object(), nullptr); + } + + KeyValueTreeObject densityFittingSetActiveAsMdpValues() + { + // Prepare MDP inputs + KeyValueTreeBuilder mdpValueBuilder; + mdpValueBuilder.rootObject().addValue("density-guided-simulation-active", + std::string("yes")); + return mdpValueBuilder.build(); + } + + IndexGroupsAndNames genericIndexGroupsAndNames() + { + done_blocka(&defaultGroups_); + stupid_fill_blocka(&defaultGroups_, 3); + std::vector groupNames = { "A", "protein", "C" }; + const char* const namesAsConstChar[3] = { groupNames[0].c_str(), groupNames[1].c_str(), + groupNames[2].c_str() }; + return { defaultGroups_, namesAsConstChar }; + } + + IndexGroupsAndNames differingIndexGroupsAndNames() + { + done_blocka(&defaultGroups_); + stupid_fill_blocka(&defaultGroups_, 3); + std::vector groupNames = { "protein", "C", "A" }; + const char* const namesAsConstChar[3] = { groupNames[0].c_str(), groupNames[1].c_str(), + groupNames[2].c_str() }; + return { defaultGroups_, namesAsConstChar }; + } + + void mangleInternalParameters() + { + densityFittingOptions_.setFitGroupIndices(differingIndexGroupsAndNames()); + } + +protected: + t_blocka defaultGroups_; + DensityFittingOptions densityFittingOptions_; }; TEST_F(DensityFittingOptionsTest, DefaultParameters) @@ -189,20 +184,21 @@ TEST_F(DensityFittingOptionsTest, OutputDefaultValuesWhenActive) writeKeyValueTreeAsMdp(&writer, builder.build()); } stream.close(); - std::string expectedString - = { + std::string expectedString = { "\n" "; Density guided simulation\n" "density-guided-simulation-active = true\n" "density-guided-simulation-group = protein\n" - "; Similarity measure between densities: inner-product, relative-entropy, or cross-correlation\n" + "; Similarity measure between densities: inner-product, relative-entropy, or " + "cross-correlation\n" "density-guided-simulation-similarity-measure = inner-product\n" "; Atom amplitude for spreading onto grid: unity, mass, or charge\n" "density-guided-simulation-atom-spreading-weight = unity\n" "density-guided-simulation-force-constant = 1e+09\n" "density-guided-simulation-gaussian-transform-spreading-width = 0.2\n" "density-guided-simulation-gaussian-transform-spreading-range-in-multiples-of-width = 4\n" - "; Reference density file location as absolute path or relative to the gmx mdrun calling location\n" + "; Reference density file location as absolute path or relative to the gmx mdrun calling " + "location\n" "density-guided-simulation-reference-density-filename = reference.mrc\n" "density-guided-simulation-nst = 1\n" "; Normalize the sum of density voxel values to one\n" @@ -211,7 +207,7 @@ TEST_F(DensityFittingOptionsTest, OutputDefaultValuesWhenActive) "density-guided-simulation-adaptive-force-scaling = false\n" "; Time constant for adaptive force scaling in ps\n" "density-guided-simulation-adaptive-force-scaling-time-constant = 4\n" - }; + }; EXPECT_EQ(expectedString, stream.toString()); } @@ -234,10 +230,10 @@ TEST_F(DensityFittingOptionsTest, InternalsToKvt) DensityFittingOptions densityFittingOptions; KeyValueTreeBuilder builder; densityFittingOptions.writeInternalParametersToKvt(builder.rootObject()); - const auto kvtTree = builder.build(); + const auto kvtTree = builder.build(); EXPECT_TRUE(kvtTree.keyExists("density-guided-simulation-group")); EXPECT_TRUE(kvtTree["density-guided-simulation-group"].isArray()); - auto storedIndex = kvtTree["density-guided-simulation-group"].asArray().values(); + auto storedIndex = kvtTree["density-guided-simulation-group"].asArray().values(); EXPECT_EQ(0, storedIndex.size()); } @@ -247,7 +243,8 @@ TEST_F(DensityFittingOptionsTest, KvtToInternal) setFromMdpValues(densityFittingSetActiveAsMdpValues()); KeyValueTreeBuilder builder; - auto addedArray = builder.rootObject().addUniformArray("density-guided-simulation-group"); + auto addedArray = + builder.rootObject().addUniformArray("density-guided-simulation-group"); addedArray.addValue(1); addedArray.addValue(15); const auto tree = builder.build(); @@ -269,9 +266,9 @@ TEST_F(DensityFittingOptionsTest, RoundTripForInternalsIsIdempotent) DensityFittingParameters parametersBefore = densityFittingOptions_.buildParameters(); - KeyValueTreeBuilder builder; + KeyValueTreeBuilder builder; densityFittingOptions_.writeInternalParametersToKvt(builder.rootObject()); - const auto inputTree = builder.build(); + const auto inputTree = builder.build(); mangleInternalParameters(); diff --git a/src/gromacs/applied_forces/tests/electricfield.cpp b/src/gromacs/applied_forces/tests/electricfield.cpp index 56c7093281..bef644480f 100644 --- a/src/gromacs/applied_forces/tests/electricfield.cpp +++ b/src/gromacs/applied_forces/tests/electricfield.cpp @@ -80,59 +80,53 @@ namespace class ElectricFieldTest : public ::testing::Test { - public: - void test(int dim, - real E0, - real omega, - real t0, - real sigma, - real expectedValue) +public: + void test(int dim, real E0, real omega, real t0, real sigma, real expectedValue) + { + // Make the electric field module + auto module = createElectricFieldModule(); + + // Fill the module as if from .mdp inputs { - // Make the electric field module - auto module = createElectricFieldModule(); - - // Fill the module as if from .mdp inputs - { - const char *dimXYZ[3] = { "x", "y", "z" }; - GMX_RELEASE_ASSERT(dim >= 0 && dim < DIM, "Dimension should be 0, 1 or 2"); - - KeyValueTreeBuilder mdpValues; - mdpValues.rootObject().addValue(formatString("electric-field-%s", dimXYZ[dim]), - formatString("%g %g %g %g", E0, omega, t0, sigma)); - - KeyValueTreeTransformer transform; - transform.rules()->addRule() - .keyMatchType("/", StringCompareType::CaseAndDashInsensitive); - module->mdpOptionProvider()->initMdpTransform(transform.rules()); - auto result = transform.transform(mdpValues.build(), nullptr); - Options moduleOptions; - module->mdpOptionProvider()->initMdpOptions(&moduleOptions); - assignOptionsFromKeyValueTree(&moduleOptions, result.object(), nullptr); - } - - // Prepare a ForceProviderInput - t_mdatoms md; - std::vector chargeA { 1 }; - md.homenr = ssize(chargeA); - md.chargeA = chargeA.data(); - CommrecHandle cr = init_commrec(MPI_COMM_WORLD, nullptr); - matrix boxDummy = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; - ForceProviderInput forceProviderInput({}, md, 0.0, boxDummy, *cr); - - // Prepare a ForceProviderOutput - PaddedVector f = { {0, 0, 0} }; - ForceWithVirial forceWithVirial(f, true); - gmx_enerdata_t enerdDummy(1, 0); - ForceProviderOutput forceProviderOutput(&forceWithVirial, &enerdDummy); - - // Use the ForceProviders to calculate forces - ForceProviders forceProviders; - module->initForceProviders(&forceProviders); - forceProviders.calculateForces(forceProviderInput, &forceProviderOutput); - - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 0.005)); - EXPECT_REAL_EQ_TOL(f[0][dim], expectedValue, tolerance); + const char* dimXYZ[3] = { "x", "y", "z" }; + GMX_RELEASE_ASSERT(dim >= 0 && dim < DIM, "Dimension should be 0, 1 or 2"); + + KeyValueTreeBuilder mdpValues; + mdpValues.rootObject().addValue(formatString("electric-field-%s", dimXYZ[dim]), + formatString("%g %g %g %g", E0, omega, t0, sigma)); + + KeyValueTreeTransformer transform; + transform.rules()->addRule().keyMatchType("/", StringCompareType::CaseAndDashInsensitive); + module->mdpOptionProvider()->initMdpTransform(transform.rules()); + auto result = transform.transform(mdpValues.build(), nullptr); + Options moduleOptions; + module->mdpOptionProvider()->initMdpOptions(&moduleOptions); + assignOptionsFromKeyValueTree(&moduleOptions, result.object(), nullptr); } + + // Prepare a ForceProviderInput + t_mdatoms md; + std::vector chargeA{ 1 }; + md.homenr = ssize(chargeA); + md.chargeA = chargeA.data(); + CommrecHandle cr = init_commrec(MPI_COMM_WORLD, nullptr); + matrix boxDummy = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + ForceProviderInput forceProviderInput({}, md, 0.0, boxDummy, *cr); + + // Prepare a ForceProviderOutput + PaddedVector f = { { 0, 0, 0 } }; + ForceWithVirial forceWithVirial(f, true); + gmx_enerdata_t enerdDummy(1, 0); + ForceProviderOutput forceProviderOutput(&forceWithVirial, &enerdDummy); + + // Use the ForceProviders to calculate forces + ForceProviders forceProviders; + module->initForceProviders(&forceProviders); + forceProviders.calculateForces(forceProviderInput, &forceProviderOutput); + + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 0.005)); + EXPECT_REAL_EQ_TOL(f[0][dim], expectedValue, tolerance); + } }; TEST_F(ElectricFieldTest, Static) diff --git a/src/gromacs/awh/awh.cpp b/src/gromacs/awh/awh.cpp index 98cfaf04a7..76046ff09b 100644 --- a/src/gromacs/awh/awh.cpp +++ b/src/gromacs/awh/awh.cpp @@ -97,8 +97,7 @@ struct BiasCoupledToSystem * \param[in] bias The bias. * \param[in] pullCoordIndex The pull coordinate indices. */ - BiasCoupledToSystem(Bias bias, - const std::vector &pullCoordIndex); + BiasCoupledToSystem(Bias bias, const std::vector& pullCoordIndex); Bias bias_; /**< The bias. */ const std::vector pullCoordIndex_; /**< The pull coordinates this bias acts on. */ @@ -106,22 +105,22 @@ struct BiasCoupledToSystem /* Here AWH can be extended to work on other coordinates than pull. */ }; -BiasCoupledToSystem::BiasCoupledToSystem(Bias bias, - const std::vector &pullCoordIndex) : +BiasCoupledToSystem::BiasCoupledToSystem(Bias bias, const std::vector& pullCoordIndex) : bias_(std::move(bias)), pullCoordIndex_(pullCoordIndex) { /* We already checked for this in grompp, but check again here. */ - GMX_RELEASE_ASSERT(static_cast(bias_.ndim()) == pullCoordIndex_.size(), "The bias dimensionality should match the number of pull coordinates."); + GMX_RELEASE_ASSERT(static_cast(bias_.ndim()) == pullCoordIndex_.size(), + "The bias dimensionality should match the number of pull coordinates."); } -Awh::Awh(FILE *fplog, - const t_inputrec &inputRecord, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimRecord, - const AwhParams &awhParams, - const std::string &biasInitFilename, - pull_t *pull_work) : +Awh::Awh(FILE* fplog, + const t_inputrec& inputRecord, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimRecord, + const AwhParams& awhParams, + const std::string& biasInitFilename, + pull_t* pull_work) : seed_(awhParams.seed), nstout_(awhParams.nstOut), commRecord_(commRecord), @@ -131,7 +130,8 @@ Awh::Awh(FILE *fplog, { /* We already checked for this in grompp, but check again here. */ GMX_RELEASE_ASSERT(inputRecord.pull != nullptr, "With AWH we should have pull parameters"); - GMX_RELEASE_ASSERT(pull_work != nullptr, "With AWH pull should be initialized before initializing AWH"); + GMX_RELEASE_ASSERT(pull_work != nullptr, + "With AWH pull should be initialized before initializing AWH"); if (fplog != nullptr) { @@ -141,7 +141,9 @@ Awh::Awh(FILE *fplog, if (haveBiasSharingWithinSimulation(awhParams)) { /* This has likely been checked by grompp, but throw anyhow. */ - GMX_THROW(InvalidInputError("Biases within a simulation are shared, currently sharing of biases is only supported between simulations")); + GMX_THROW( + InvalidInputError("Biases within a simulation are shared, currently sharing of " + "biases is only supported between simulations")); } int numSharingSimulations = 1; @@ -151,29 +153,34 @@ Awh::Awh(FILE *fplog, } /* Initialize all the biases */ - const double beta = 1/(BOLTZ*inputRecord.opts.ref_t[0]); + const double beta = 1 / (BOLTZ * inputRecord.opts.ref_t[0]); for (int k = 0; k < awhParams.numBias; k++) { - const AwhBiasParams &awhBiasParams = awhParams.awhBiasParams[k]; + const AwhBiasParams& awhBiasParams = awhParams.awhBiasParams[k]; - std::vector pullCoordIndex; - std::vector dimParams; + std::vector pullCoordIndex; + std::vector dimParams; for (int d = 0; d < awhBiasParams.ndim; d++) { - const AwhDimParams &awhDimParams = awhBiasParams.dimParams[d]; - GMX_RELEASE_ASSERT(awhDimParams.eCoordProvider == eawhcoordproviderPULL, "Currently only the pull code is supported as coordinate provider"); - const t_pull_coord &pullCoord = inputRecord.pull->coord[awhDimParams.coordIndex]; - GMX_RELEASE_ASSERT(pullCoord.eGeom != epullgDIRPBC, "Pull geometry 'direction-periodic' is not supported by AWH"); - double conversionFactor = pull_coordinate_is_angletype(&pullCoord) ? DEG2RAD : 1; + const AwhDimParams& awhDimParams = awhBiasParams.dimParams[d]; + GMX_RELEASE_ASSERT(awhDimParams.eCoordProvider == eawhcoordproviderPULL, + "Currently only the pull code is supported as coordinate provider"); + const t_pull_coord& pullCoord = inputRecord.pull->coord[awhDimParams.coordIndex]; + GMX_RELEASE_ASSERT(pullCoord.eGeom != epullgDIRPBC, + "Pull geometry 'direction-periodic' is not supported by AWH"); + double conversionFactor = pull_coordinate_is_angletype(&pullCoord) ? DEG2RAD : 1; dimParams.emplace_back(conversionFactor, awhDimParams.forceConstant, beta); pullCoordIndex.push_back(awhDimParams.coordIndex); } /* Construct the bias and couple it to the system. */ - Bias::ThisRankWillDoIO thisRankWillDoIO = (MASTER(commRecord_) ? Bias::ThisRankWillDoIO::Yes : Bias::ThisRankWillDoIO::No); - biasCoupledToSystem_.emplace_back(Bias(k, awhParams, awhParams.awhBiasParams[k], dimParams, beta, inputRecord.delta_t, numSharingSimulations, biasInitFilename, thisRankWillDoIO), - pullCoordIndex); + Bias::ThisRankWillDoIO thisRankWillDoIO = + (MASTER(commRecord_) ? Bias::ThisRankWillDoIO::Yes : Bias::ThisRankWillDoIO::No); + biasCoupledToSystem_.emplace_back( + Bias(k, awhParams, awhParams.awhBiasParams[k], dimParams, beta, inputRecord.delta_t, + numSharingSimulations, biasInitFilename, thisRankWillDoIO), + pullCoordIndex); biasCoupledToSystem_.back().bias_.printInitializationToLog(fplog); } @@ -184,7 +191,7 @@ Awh::Awh(FILE *fplog, if (numSharingSimulations > 1 && MASTER(commRecord_)) { std::vector pointSize; - for (auto const &biasCts : biasCoupledToSystem_) + for (auto const& biasCts : biasCoupledToSystem_) { pointSize.push_back(biasCts.bias_.state().points().size()); } @@ -200,20 +207,20 @@ bool Awh::isOutputStep(int64_t step) const return (nstout_ > 0 && step % nstout_ == 0); } -real Awh::applyBiasForcesAndUpdateBias(int ePBC, - const t_mdatoms &mdatoms, - const matrix box, - gmx::ForceWithVirial *forceWithVirial, - double t, - int64_t step, - gmx_wallcycle *wallcycle, - FILE *fplog) +real Awh::applyBiasForcesAndUpdateBias(int ePBC, + const t_mdatoms& mdatoms, + const matrix box, + gmx::ForceWithVirial* forceWithVirial, + double t, + int64_t step, + gmx_wallcycle* wallcycle, + FILE* fplog) { GMX_ASSERT(forceWithVirial, "Need a valid ForceWithVirial object"); wallcycle_start(wallcycle, ewcAWH); - t_pbc pbc; + t_pbc pbc; set_pbc(&pbc, ePBC, box); /* During the AWH update the potential can instantaneously jump due to either @@ -221,7 +228,7 @@ real Awh::applyBiasForcesAndUpdateBias(int ePBC, subtracted from the potential in order to get a useful conserved energy quantity. */ double awhPotential = potentialOffset_; - for (auto &biasCts : biasCoupledToSystem_) + for (auto& biasCts : biasCoupledToSystem_) { /* Update the AWH coordinate values with those of the corresponding * pull coordinates. @@ -236,17 +243,14 @@ real Awh::applyBiasForcesAndUpdateBias(int ePBC, * sampling observables based on the input pull coordinate value, * setting the bias force and/or updating the AWH bias state. */ - double biasPotential; - double biasPotentialJump; + double biasPotential; + double biasPotentialJump; /* Note: In the near future this call will be split in calls * to supports bias sharing within a single simulation. */ - gmx::ArrayRef biasForce = - biasCts.bias_.calcForceAndUpdateBias(coordValue, - &biasPotential, &biasPotentialJump, - commRecord_, - multiSimRecord_, - t, step, seed_, fplog); + gmx::ArrayRef biasForce = biasCts.bias_.calcForceAndUpdateBias( + coordValue, &biasPotential, &biasPotentialJump, commRecord_, multiSimRecord_, t, + step, seed_, fplog); awhPotential += biasPotential; @@ -259,9 +263,8 @@ real Awh::applyBiasForcesAndUpdateBias(int ePBC, */ for (int d = 0; d < biasCts.bias_.ndim(); d++) { - apply_external_pull_coord_force(pull_, biasCts.pullCoordIndex_[d], - biasForce[d], &mdatoms, - forceWithVirial); + apply_external_pull_coord_force(pull_, biasCts.pullCoordIndex_[d], biasForce[d], + &mdatoms, forceWithVirial); } if (isOutputStep(step)) @@ -300,16 +303,20 @@ std::shared_ptr Awh::initHistoryFromState() const } } -void Awh::restoreStateFromHistory(const AwhHistory *awhHistory) +void Awh::restoreStateFromHistory(const AwhHistory* awhHistory) { /* Restore the history to the current state */ if (MASTER(commRecord_)) { - GMX_RELEASE_ASSERT(awhHistory != nullptr, "The master rank should have a valid awhHistory when restoring the state from history."); + GMX_RELEASE_ASSERT(awhHistory != nullptr, + "The master rank should have a valid awhHistory when restoring the " + "state from history."); if (awhHistory->bias.size() != biasCoupledToSystem_.size()) { - GMX_THROW(InvalidInputError("AWH state and history contain different numbers of biases. Likely you provided a checkpoint from a different simulation.")); + GMX_THROW(InvalidInputError( + "AWH state and history contain different numbers of biases. Likely you " + "provided a checkpoint from a different simulation.")); } potentialOffset_ = awhHistory->potentialOffset; @@ -321,11 +328,12 @@ void Awh::restoreStateFromHistory(const AwhHistory *awhHistory) for (size_t k = 0; k < biasCoupledToSystem_.size(); k++) { - biasCoupledToSystem_[k].bias_.restoreStateFromHistory(awhHistory ? &awhHistory->bias[k] : nullptr, commRecord_); + biasCoupledToSystem_[k].bias_.restoreStateFromHistory( + awhHistory ? &awhHistory->bias[k] : nullptr, commRecord_); } } -void Awh::updateHistory(AwhHistory *awhHistory) const +void Awh::updateHistory(AwhHistory* awhHistory) const { if (!MASTER(commRecord_)) { @@ -333,7 +341,8 @@ void Awh::updateHistory(AwhHistory *awhHistory) const } /* This assert will also catch a non-master rank calling this function. */ - GMX_RELEASE_ASSERT(awhHistory->bias.size() == biasCoupledToSystem_.size(), "AWH state and history bias count should match"); + GMX_RELEASE_ASSERT(awhHistory->bias.size() == biasCoupledToSystem_.size(), + "AWH state and history bias count should match"); awhHistory->potentialOffset = potentialOffset_; @@ -343,30 +352,29 @@ void Awh::updateHistory(AwhHistory *awhHistory) const } } -const char * Awh::externalPotentialString() +const char* Awh::externalPotentialString() { return "AWH"; } -void Awh::registerAwhWithPull(const AwhParams &awhParams, - pull_t *pull_work) +void Awh::registerAwhWithPull(const AwhParams& awhParams, pull_t* pull_work) { GMX_RELEASE_ASSERT(pull_work, "Need a valid pull object"); for (int k = 0; k < awhParams.numBias; k++) { - const AwhBiasParams &biasParams = awhParams.awhBiasParams[k]; + const AwhBiasParams& biasParams = awhParams.awhBiasParams[k]; for (int d = 0; d < biasParams.ndim; d++) { - register_external_pull_potential(pull_work, biasParams.dimParams[d].coordIndex, Awh::externalPotentialString()); + register_external_pull_potential(pull_work, biasParams.dimParams[d].coordIndex, + Awh::externalPotentialString()); } } } /* Fill the AWH data block of an energy frame with data (if there is any). */ -void Awh::writeToEnergyFrame(int64_t step, - t_enxframe *frame) const +void Awh::writeToEnergyFrame(int64_t step, t_enxframe* frame) const { GMX_ASSERT(MASTER(commRecord_), "writeToEnergyFrame should only be called on the master rank"); GMX_ASSERT(frame != nullptr, "Need a valid energy frame"); @@ -378,8 +386,8 @@ void Awh::writeToEnergyFrame(int64_t step, } /* Get the total number of energy subblocks that AWH needs */ - int numSubblocks = 0; - for (auto &biasCoupledToSystem : biasCoupledToSystem_) + int numSubblocks = 0; + for (auto& biasCoupledToSystem : biasCoupledToSystem_) { numSubblocks += biasCoupledToSystem.bias_.numEnergySubblocksToWrite(); } @@ -389,7 +397,7 @@ void Awh::writeToEnergyFrame(int64_t step, add_blocks_enxframe(frame, frame->nblock + 1); /* Take the block that was just added and set the number of subblocks. */ - t_enxblock *awhEnergyBlock = &(frame->block[frame->nblock - 1]); + t_enxblock* awhEnergyBlock = &(frame->block[frame->nblock - 1]); add_subblocks_enxblock(awhEnergyBlock, numSubblocks); /* Claim it as an AWH block. */ @@ -397,22 +405,22 @@ void Awh::writeToEnergyFrame(int64_t step, /* Transfer AWH data blocks to energy sub blocks */ int energySubblockCount = 0; - for (auto &biasCoupledToSystem : biasCoupledToSystem_) + for (auto& biasCoupledToSystem : biasCoupledToSystem_) { - energySubblockCount += biasCoupledToSystem.bias_.writeToEnergySubblocks(&(awhEnergyBlock->sub[energySubblockCount])); + energySubblockCount += biasCoupledToSystem.bias_.writeToEnergySubblocks( + &(awhEnergyBlock->sub[energySubblockCount])); } } -std::unique_ptr -prepareAwhModule(FILE *fplog, - const t_inputrec &inputRecord, - t_state *stateGlobal, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimRecord, - const bool startingFromCheckpoint, - const bool usingShellParticles, - const std::string &biasInitFilename, - pull_t *pull_work) +std::unique_ptr prepareAwhModule(FILE* fplog, + const t_inputrec& inputRecord, + t_state* stateGlobal, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimRecord, + const bool startingFromCheckpoint, + const bool usingShellParticles, + const std::string& biasInitFilename, + pull_t* pull_work) { if (!inputRecord.bDoAwh) { @@ -423,8 +431,8 @@ prepareAwhModule(FILE *fplog, GMX_THROW(InvalidInputError("AWH biasing does not support shell particles.")); } - auto awh = std::make_unique(fplog, inputRecord, commRecord, multiSimRecord, *inputRecord.awhParams, - biasInitFilename, pull_work); + auto awh = std::make_unique(fplog, inputRecord, commRecord, multiSimRecord, + *inputRecord.awhParams, biasInitFilename, pull_work); if (startingFromCheckpoint) { diff --git a/src/gromacs/awh/awh.h b/src/gromacs/awh/awh.h index c9ce020918..5c57dfabe1 100644 --- a/src/gromacs/awh/awh.h +++ b/src/gromacs/awh/awh.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -107,145 +107,143 @@ class ForceWithVirial; */ class Awh { - public: - /*! \brief Construct an AWH at the start of a simulation. - * - * AWH will here also register itself with the pull struct as the - * potential provider for the pull coordinates given as AWH coordinates - * in the user input. This allows AWH to later apply the bias force to - * these coordinate in \ref Awh::applyBiasForcesAndUpdateBias. - * - * \param[in,out] fplog General output file, normally md.log, can be nullptr. - * \param[in] inputRecord General input parameters (as set up by grompp). - * \param[in] commRecord Struct for communication, can be nullptr. - * \param[in] multiSimRecord Multi-sim handler - * \param[in] awhParams AWH input parameters, consistent with the relevant parts of \p inputRecord (as set up by grompp). - * \param[in] biasInitFilename Name of file to read PMF and target from. - * \param[in,out] pull_work Pointer to a pull struct which AWH will couple to, has to be initialized, is assumed not to change during the lifetime of the Awh object. - */ - Awh(FILE *fplog, - const t_inputrec &inputRecord, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimRecord, - const AwhParams &awhParams, - const std::string &biasInitFilename, - pull_t *pull_work); +public: + /*! \brief Construct an AWH at the start of a simulation. + * + * AWH will here also register itself with the pull struct as the + * potential provider for the pull coordinates given as AWH coordinates + * in the user input. This allows AWH to later apply the bias force to + * these coordinate in \ref Awh::applyBiasForcesAndUpdateBias. + * + * \param[in,out] fplog General output file, normally md.log, can be nullptr. + * \param[in] inputRecord General input parameters (as set up by grompp). + * \param[in] commRecord Struct for communication, can be nullptr. + * \param[in] multiSimRecord Multi-sim handler + * \param[in] awhParams AWH input parameters, consistent with the relevant parts of \p inputRecord (as set up by grompp). + * \param[in] biasInitFilename Name of file to read PMF and target from. + * \param[in,out] pull_work Pointer to a pull struct which AWH will couple to, has to be initialized, is assumed not to change during the lifetime of the Awh object. + */ + Awh(FILE* fplog, + const t_inputrec& inputRecord, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimRecord, + const AwhParams& awhParams, + const std::string& biasInitFilename, + pull_t* pull_work); - ~Awh(); + ~Awh(); - /*! \brief Peform an AWH update, to be called every MD step. - * - * An update has two tasks: apply the bias force and improve - * the bias and the free energy estimate that AWH keeps internally. - * - * For the first task, AWH retrieves the pull coordinate values from the pull struct. - * With these, the bias potential and forces are calculated. - * The bias force together with the atom forces and virial - * are passed on to pull which applies the bias force to the atoms. - * This is done at every step. - * - * Secondly, coordinate values are regularly sampled and kept by AWH. - * Convergence of the bias and free energy estimate is achieved by - * updating the AWH bias state after a certain number of samples has been collected. - * - * \note Requires that pull_potential from pull.h has been called first - * since AWH needs the current coordinate values (the pull code checks - * for this). - * - * \param[in] mdatoms Atom properties. - * \param[in] ePBC Type of periodic boundary conditions. - * \param[in] box Box vectors. - * \param[in,out] forceWithVirial Force and virial buffers, should cover at least the local atoms. - * \param[in] t Time. - * \param[in] step The current MD step. - * \param[in,out] wallcycle Wallcycle counter, can be nullptr. - * \param[in,out] fplog General output file, normally md.log, can be nullptr. - * \returns the potential energy for the bias. - */ - real applyBiasForcesAndUpdateBias(int ePBC, - const t_mdatoms &mdatoms, - const matrix box, - gmx::ForceWithVirial *forceWithVirial, - double t, - int64_t step, - gmx_wallcycle *wallcycle, - FILE *fplog); + /*! \brief Peform an AWH update, to be called every MD step. + * + * An update has two tasks: apply the bias force and improve + * the bias and the free energy estimate that AWH keeps internally. + * + * For the first task, AWH retrieves the pull coordinate values from the pull struct. + * With these, the bias potential and forces are calculated. + * The bias force together with the atom forces and virial + * are passed on to pull which applies the bias force to the atoms. + * This is done at every step. + * + * Secondly, coordinate values are regularly sampled and kept by AWH. + * Convergence of the bias and free energy estimate is achieved by + * updating the AWH bias state after a certain number of samples has been collected. + * + * \note Requires that pull_potential from pull.h has been called first + * since AWH needs the current coordinate values (the pull code checks + * for this). + * + * \param[in] mdatoms Atom properties. + * \param[in] ePBC Type of periodic boundary conditions. + * \param[in] box Box vectors. + * \param[in,out] forceWithVirial Force and virial buffers, should cover at least the local atoms. + * \param[in] t Time. + * \param[in] step The current MD step. + * \param[in,out] wallcycle Wallcycle counter, can be nullptr. + * \param[in,out] fplog General output file, normally md.log, can be nullptr. + * \returns the potential energy for the bias. + */ + real applyBiasForcesAndUpdateBias(int ePBC, + const t_mdatoms& mdatoms, + const matrix box, + gmx::ForceWithVirial* forceWithVirial, + double t, + int64_t step, + gmx_wallcycle* wallcycle, + FILE* fplog); - /*! \brief - * Update the AWH history in preparation for writing to checkpoint file. - * - * Should be called at least on the master rank at checkpoint steps. - * - * Should be called with a valid \p awhHistory (is checked). - * - * \param[in,out] awhHistory AWH history to set. - */ - void updateHistory(AwhHistory *awhHistory) const; + /*! \brief + * Update the AWH history in preparation for writing to checkpoint file. + * + * Should be called at least on the master rank at checkpoint steps. + * + * Should be called with a valid \p awhHistory (is checked). + * + * \param[in,out] awhHistory AWH history to set. + */ + void updateHistory(AwhHistory* awhHistory) const; - /*! \brief - * Allocate and initialize an AWH history with the given AWH state. - * - * This function should be called at the start of a new simulation - * at least on the master rank. - * Note that only constant data will be initialized here. - * History data is set by \ref Awh::updateHistory. - * - * \returns a shared pointer to the AWH history on the rank that does I/O, nullptr otherwise. - */ - std::shared_ptr initHistoryFromState() const; + /*! \brief + * Allocate and initialize an AWH history with the given AWH state. + * + * This function should be called at the start of a new simulation + * at least on the master rank. + * Note that only constant data will be initialized here. + * History data is set by \ref Awh::updateHistory. + * + * \returns a shared pointer to the AWH history on the rank that does I/O, nullptr otherwise. + */ + std::shared_ptr initHistoryFromState() const; - /*! \brief Restore the AWH state from the given history. - * - * Should be called on all ranks (for internal MPI broadcast). - * Should pass a point to an AwhHistory on the master rank that - * is compatible with the AWH setup in this simulation. Will throw - * an exception if it is not compatible. - * - * \param[in] awhHistory AWH history to restore from. - */ - void restoreStateFromHistory(const AwhHistory *awhHistory); + /*! \brief Restore the AWH state from the given history. + * + * Should be called on all ranks (for internal MPI broadcast). + * Should pass a point to an AwhHistory on the master rank that + * is compatible with the AWH setup in this simulation. Will throw + * an exception if it is not compatible. + * + * \param[in] awhHistory AWH history to restore from. + */ + void restoreStateFromHistory(const AwhHistory* awhHistory); - /*! \brief Fills the AWH data block of an energy frame with data at certain steps. - * - * \param[in] step The current MD step. - * \param[in,out] fr Energy data frame. - */ - void writeToEnergyFrame(int64_t step, - t_enxframe *fr) const; + /*! \brief Fills the AWH data block of an energy frame with data at certain steps. + * + * \param[in] step The current MD step. + * \param[in,out] fr Energy data frame. + */ + void writeToEnergyFrame(int64_t step, t_enxframe* fr) const; - /*! \brief Returns string "AWH" for registering AWH as an external potential provider with the pull module. - */ - static const char *externalPotentialString(); + /*! \brief Returns string "AWH" for registering AWH as an external potential provider with the pull module. + */ + static const char* externalPotentialString(); - /*! \brief Register the AWH biased coordinates with pull. - * - * This function is public because it needs to be called by grompp - * (and is otherwise only called by Awh()). - * Pull requires all external potentials to register themselves - * before the end of pre-processing and before the first MD step. - * If this has not happened, pull with throw an error. - * - * \param[in] awhParams The AWH parameters. - * \param[in,out] pull_work Pull struct which AWH will register the bias into. - */ - static void registerAwhWithPull(const AwhParams &awhParams, - pull_t *pull_work); + /*! \brief Register the AWH biased coordinates with pull. + * + * This function is public because it needs to be called by grompp + * (and is otherwise only called by Awh()). + * Pull requires all external potentials to register themselves + * before the end of pre-processing and before the first MD step. + * If this has not happened, pull with throw an error. + * + * \param[in] awhParams The AWH parameters. + * \param[in,out] pull_work Pull struct which AWH will register the bias into. + */ + static void registerAwhWithPull(const AwhParams& awhParams, pull_t* pull_work); - private: - /*! \brief Returns whether we need to write output at the current step. - * - * \param[in] step The current MD step. - */ - bool isOutputStep(int64_t step) const; +private: + /*! \brief Returns whether we need to write output at the current step. + * + * \param[in] step The current MD step. + */ + bool isOutputStep(int64_t step) const; - private: - std::vector biasCoupledToSystem_; /**< AWH biases and definitions of their coupling to the system. */ - const int64_t seed_; /**< Random seed for MC jumping with umbrella type bias potential. */ - const int nstout_; /**< Interval in steps for writing to energy file. */ - const t_commrec *commRecord_; /**< Pointer to the communication record. */ - const gmx_multisim_t *multiSimRecord_; /**< Handler for multi-simulations. */ - pull_t *pull_; /**< Pointer to the pull working data. */ - double potentialOffset_; /**< The offset of the bias potential which changes due to bias updates. */ +private: + std::vector biasCoupledToSystem_; /**< AWH biases and definitions of their coupling to the system. */ + const int64_t seed_; /**< Random seed for MC jumping with umbrella type bias potential. */ + const int nstout_; /**< Interval in steps for writing to energy file. */ + const t_commrec* commRecord_; /**< Pointer to the communication record. */ + const gmx_multisim_t* multiSimRecord_; /**< Handler for multi-simulations. */ + pull_t* pull_; /**< Pointer to the pull working data. */ + double potentialOffset_; /**< The offset of the bias potential which changes due to bias updates. */ }; /*! \brief Makes an Awh and prepares to use it if the user input @@ -266,17 +264,16 @@ class Awh * \returns An initialized Awh module, or nullptr if none was requested. * \throws InvalidInputError If another active module is not supported. */ -std::unique_ptr -prepareAwhModule(FILE *fplog, - const t_inputrec &inputRecord, - t_state *stateGlobal, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimRecord, - bool startingFromCheckpoint, - bool usingShellParticles, - const std::string &biasInitFilename, - pull_t *pull_work); +std::unique_ptr prepareAwhModule(FILE* fplog, + const t_inputrec& inputRecord, + t_state* stateGlobal, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimRecord, + bool startingFromCheckpoint, + bool usingShellParticles, + const std::string& biasInitFilename, + pull_t* pull_work); -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_H */ diff --git a/src/gromacs/awh/bias.cpp b/src/gromacs/awh/bias.cpp index ecba420798..006dee4e87 100644 --- a/src/gromacs/awh/bias.cpp +++ b/src/gromacs/awh/bias.cpp @@ -74,20 +74,19 @@ namespace gmx { -void Bias::warnForHistogramAnomalies(double t, int64_t step, FILE *fplog) +void Bias::warnForHistogramAnomalies(double t, int64_t step, FILE* fplog) { - const int maxNumWarningsInCheck = 1; /* The maximum number of warnings to print per check */ - const int maxNumWarningsInRun = 10; /* The maximum number of warnings to print in a run */ + const int maxNumWarningsInCheck = 1; /* The maximum number of warnings to print per check */ + const int maxNumWarningsInRun = 10; /* The maximum number of warnings to print in a run */ - if (fplog == nullptr || numWarningsIssued_ >= maxNumWarningsInRun || state_.inInitialStage() || - !params_.isCheckHistogramForAnomaliesStep(step)) + if (fplog == nullptr || numWarningsIssued_ >= maxNumWarningsInRun || state_.inInitialStage() + || !params_.isCheckHistogramForAnomaliesStep(step)) { return; } numWarningsIssued_ += - state_.warnForHistogramAnomalies(grid_, biasIndex(), t, fplog, - maxNumWarningsInCheck); + state_.warnForHistogramAnomalies(grid_, biasIndex(), t, fplog, maxNumWarningsInCheck); if (numWarningsIssued_ >= maxNumWarningsInRun) { @@ -103,25 +102,25 @@ void Bias::doSkippedUpdatesForAllPoints() } } -gmx::ArrayRef -Bias::calcForceAndUpdateBias(const awh_dvec coordValue, - double *awhPotential, - double *potentialJump, - const t_commrec *commRecord, - const gmx_multisim_t *ms, - double t, - int64_t step, - int64_t seed, - FILE *fplog) +gmx::ArrayRef Bias::calcForceAndUpdateBias(const awh_dvec coordValue, + double* awhPotential, + double* potentialJump, + const t_commrec* commRecord, + const gmx_multisim_t* ms, + double t, + int64_t step, + int64_t seed, + FILE* fplog) { if (step < 0) { - GMX_THROW(InvalidInputError("The step number is negative which is not supported by the AWH code.")); + GMX_THROW(InvalidInputError( + "The step number is negative which is not supported by the AWH code.")); } state_.setCoordValue(grid_, coordValue); - std::vector < double, AlignedAllocator < double>> &probWeightNeighbor = alignedTempWorkSpace_; + std::vector>& probWeightNeighbor = alignedTempWorkSpace_; /* If the convolved force is needed or this is a sampling step, * the bias in the current neighborhood needs to be up-to-date @@ -137,7 +136,8 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, state_.doSkippedUpdatesInNeighborhood(params_, grid_); } - convolvedBias = state_.updateProbabilityWeightsAndConvolvedBias(dimParams_, grid_, &probWeightNeighbor); + convolvedBias = + state_.updateProbabilityWeightsAndConvolvedBias(dimParams_, grid_, &probWeightNeighbor); if (sampleCoord) { @@ -147,7 +147,7 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, } } - const CoordState &coordState = state_.coordState(); + const CoordState& coordState = state_.coordState(); /* Set the bias force and get the potential contribution from this bias. * The potential jump occurs at different times depending on how @@ -159,18 +159,18 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, double potential; if (params_.convolveForce) { - state_.calcConvolvedForce(dimParams_, grid_, probWeightNeighbor, - tempForce_, biasForce_); + state_.calcConvolvedForce(dimParams_, grid_, probWeightNeighbor, tempForce_, biasForce_); - potential = -convolvedBias*params_.invBeta; + potential = -convolvedBias * params_.invBeta; } else { /* Umbrella force */ GMX_RELEASE_ASSERT(state_.points()[coordState.umbrellaGridpoint()].inTargetRegion(), - "AWH bias grid point for the umbrella reference value is outside of the target region."); - potential = - state_.calcUmbrellaForceAndPotential(dimParams_, grid_, coordState.umbrellaGridpoint(), biasForce_); + "AWH bias grid point for the umbrella reference value is outside of the " + "target region."); + potential = state_.calcUmbrellaForceAndPotential( + dimParams_, grid_, coordState.umbrellaGridpoint(), biasForce_); /* Moving the umbrella results in a force correction and * a new potential. The umbrella center is sampled as often as @@ -179,7 +179,8 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, */ if (moveUmbrella) { - double newPotential = state_.moveUmbrella(dimParams_, grid_, probWeightNeighbor, biasForce_, step, seed, params_.biasIndex); + double newPotential = state_.moveUmbrella(dimParams_, grid_, probWeightNeighbor, + biasForce_, step, seed, params_.biasIndex); *potentialJump = newPotential - potential; } } @@ -187,16 +188,13 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, /* Update the free energy estimates and bias and other history dependent method parameters */ if (params_.isUpdateFreeEnergyStep(step)) { - state_.updateFreeEnergyAndAddSamplesToHistogram(dimParams_, grid_, - params_, - commRecord, ms, - t, step, fplog, - &updateList_); + state_.updateFreeEnergyAndAddSamplesToHistogram(dimParams_, grid_, params_, commRecord, ms, + t, step, fplog, &updateList_); if (params_.convolveForce) { /* The update results in a potential jump, so we need the new convolved potential. */ - double newPotential = -calcConvolvedBias(coordState.coordValue())*params_.invBeta; + double newPotential = -calcConvolvedBias(coordState.coordValue()) * params_.invBeta; *potentialJump = newPotential - potential; } } @@ -216,10 +214,10 @@ Bias::calcForceAndUpdateBias(const awh_dvec coordValue, * \param[in] pointState The state of the points in a bias. * \returns the total sample count. */ -static int64_t countSamples(const std::vector &pointState) +static int64_t countSamples(const std::vector& pointState) { double numSamples = 0; - for (const PointState &point : pointState) + for (const PointState& point : pointState) { numSamples += point.weightSumTot(); } @@ -235,20 +233,20 @@ static int64_t countSamples(const std::vector &pointState) * \param[in] params The parameters of the bias. * \param[in] state The state of the bias. */ -static void ensureStateAndRunConsistency(const BiasParams ¶ms, - const BiasState &state) +static void ensureStateAndRunConsistency(const BiasParams& params, const BiasState& state) { - int64_t numSamples = countSamples(state.points()); - int64_t numUpdatesFromSamples = numSamples/(params.numSamplesUpdateFreeEnergy_*params.numSharedUpdate); - int64_t numUpdatesExpected = state.histogramSize().numUpdates(); + int64_t numSamples = countSamples(state.points()); + int64_t numUpdatesFromSamples = + numSamples / (params.numSamplesUpdateFreeEnergy_ * params.numSharedUpdate); + int64_t numUpdatesExpected = state.histogramSize().numUpdates(); if (numUpdatesFromSamples != numUpdatesExpected) { - std::string mesg = gmx::formatString("The number of AWH updates in the checkpoint file (%" PRId64 ") does not match the total number of AWH samples divided by the number of samples per update for %d sharing AWH bias(es) (%" PRId64 "/%d=%" PRId64 ")", - numUpdatesExpected, - params.numSharedUpdate, - numSamples, - params.numSamplesUpdateFreeEnergy_*params.numSharedUpdate, - numUpdatesFromSamples); + std::string mesg = gmx::formatString( + "The number of AWH updates in the checkpoint file (%" PRId64 + ") does not match the total number of AWH samples divided by the number of samples " + "per update for %d sharing AWH bias(es) (%" PRId64 "/%d=%" PRId64 ")", + numUpdatesExpected, params.numSharedUpdate, numSamples, + params.numSamplesUpdateFreeEnergy_ * params.numSharedUpdate, numUpdatesFromSamples); mesg += " Maybe you changed AWH parameters."; /* Unfortunately we currently do not store the number of simulations * sharing the bias or the state to checkpoint. But we can hint at @@ -256,22 +254,24 @@ static void ensureStateAndRunConsistency(const BiasParams ¶ms, */ if (numUpdatesFromSamples % state.histogramSize().numUpdates() == 0) { - mesg += gmx::formatString(" Or the run you continued from used %" PRId64 " sharing simulations, whereas you now specified %d sharing simulations.", - numUpdatesFromSamples/state.histogramSize().numUpdates(), - params.numSharedUpdate); + mesg += gmx::formatString( + " Or the run you continued from used %" PRId64 + " sharing simulations, whereas you now specified %d sharing simulations.", + numUpdatesFromSamples / state.histogramSize().numUpdates(), params.numSharedUpdate); } GMX_THROW(InvalidInputError(mesg)); } } -void Bias::restoreStateFromHistory(const AwhBiasHistory *biasHistory, - const t_commrec *cr) +void Bias::restoreStateFromHistory(const AwhBiasHistory* biasHistory, const t_commrec* cr) { - GMX_RELEASE_ASSERT(thisRankDoesIO_ == MASTER(cr), "The master rank should do I/O, the other ranks should not"); + GMX_RELEASE_ASSERT(thisRankDoesIO_ == MASTER(cr), + "The master rank should do I/O, the other ranks should not"); if (MASTER(cr)) { - GMX_RELEASE_ASSERT(biasHistory != nullptr, "On the master rank we need a valid history object to restore from"); + GMX_RELEASE_ASSERT(biasHistory != nullptr, + "On the master rank we need a valid history object to restore from"); state_.restoreFromHistory(*biasHistory, grid_); /* Ensure that the state is consistent with our current run setup, @@ -292,7 +292,7 @@ void Bias::restoreStateFromHistory(const AwhBiasHistory *biasHistory, } } -void Bias::initHistoryFromState(AwhBiasHistory *biasHistory) const +void Bias::initHistoryFromState(AwhBiasHistory* biasHistory) const { GMX_RELEASE_ASSERT(biasHistory != nullptr, "Need a valid biasHistory"); @@ -304,7 +304,7 @@ void Bias::initHistoryFromState(AwhBiasHistory *biasHistory) const } } -void Bias::updateHistory(AwhBiasHistory *biasHistory) const +void Bias::updateHistory(AwhBiasHistory* biasHistory) const { GMX_RELEASE_ASSERT(biasHistory != nullptr, "Need a valid biasHistory"); @@ -316,19 +316,27 @@ void Bias::updateHistory(AwhBiasHistory *biasHistory) const } } -Bias::Bias(int biasIndexInCollection, - const AwhParams &awhParams, - const AwhBiasParams &awhBiasParams, - const std::vector &dimParamsInit, - double beta, - double mdTimeStep, - int numSharingSimulations, - const std::string &biasInitFilename, - ThisRankWillDoIO thisRankWillDoIO, - BiasParams::DisableUpdateSkips disableUpdateSkips) : +Bias::Bias(int biasIndexInCollection, + const AwhParams& awhParams, + const AwhBiasParams& awhBiasParams, + const std::vector& dimParamsInit, + double beta, + double mdTimeStep, + int numSharingSimulations, + const std::string& biasInitFilename, + ThisRankWillDoIO thisRankWillDoIO, + BiasParams::DisableUpdateSkips disableUpdateSkips) : dimParams_(dimParamsInit), grid_(dimParamsInit, awhBiasParams.dimParams), - params_(awhParams, awhBiasParams, dimParams_, beta, mdTimeStep, disableUpdateSkips, numSharingSimulations, grid_.axis(), biasIndexInCollection), + params_(awhParams, + awhBiasParams, + dimParams_, + beta, + mdTimeStep, + disableUpdateSkips, + numSharingSimulations, + grid_.axis(), + biasIndexInCollection), state_(awhBiasParams, params_.initialHistogramSize, dimParams_, grid_), thisRankDoesIO_(thisRankWillDoIO == ThisRankWillDoIO::Yes), biasForce_(ndim()), @@ -350,42 +358,41 @@ Bias::Bias(int biasIndexInCollection, */ double blockLength = 0; /* Construct the force correlation object. */ - forceCorrelationGrid_ = - std::make_unique(state_.points().size(), ndim(), - blockLength, CorrelationGrid::BlockLengthMeasure::Time, - awhParams.nstSampleCoord*mdTimeStep); + forceCorrelationGrid_ = std::make_unique( + state_.points().size(), ndim(), blockLength, + CorrelationGrid::BlockLengthMeasure::Time, awhParams.nstSampleCoord * mdTimeStep); writer_ = std::make_unique(*this); } } -void Bias::printInitializationToLog(FILE *fplog) const +void Bias::printInitializationToLog(FILE* fplog) const { if (fplog != nullptr && forceCorrelationGrid_ != nullptr) { - std::string prefix = - gmx::formatString("\nawh%d:", params_.biasIndex + 1); + std::string prefix = gmx::formatString("\nawh%d:", params_.biasIndex + 1); fprintf(fplog, "%s initial force correlation block length = %g %s" "%s force correlation number of blocks = %d", prefix.c_str(), forceCorrelationGrid().getBlockLength(), - forceCorrelationGrid().blockLengthMeasure == CorrelationGrid::BlockLengthMeasure::Weight ? "" : "ps", + forceCorrelationGrid().blockLengthMeasure == CorrelationGrid::BlockLengthMeasure::Weight + ? "" + : "ps", prefix.c_str(), forceCorrelationGrid().getNumBlocks()); } } -void Bias::updateForceCorrelationGrid(gmx::ArrayRef probWeightNeighbor, - double t) +void Bias::updateForceCorrelationGrid(gmx::ArrayRef probWeightNeighbor, double t) { if (forceCorrelationGrid_ == nullptr) { return; } - const std::vector &neighbor = grid_.point(state_.coordState().gridpointIndex()).neighbor; + const std::vector& neighbor = grid_.point(state_.coordState().gridpointIndex()).neighbor; - gmx::ArrayRef forceFromNeighbor = tempForce_; + gmx::ArrayRef forceFromNeighbor = tempForce_; for (size_t n = 0; n < neighbor.size(); n++) { double weightNeighbor = probWeightNeighbor[n]; @@ -412,7 +419,7 @@ int Bias::numEnergySubblocksToWrite() const } /* Write bias data blocks to energy subblocks. */ -int Bias::writeToEnergySubblocks(t_enxsubblock *subblock) const +int Bias::writeToEnergySubblocks(t_enxsubblock* subblock) const { GMX_RELEASE_ASSERT(writer_ != nullptr, "Should only request data from an initialized writer"); diff --git a/src/gromacs/awh/bias.h b/src/gromacs/awh/bias.h index 43ab69aec5..65943d56d7 100644 --- a/src/gromacs/awh/bias.h +++ b/src/gromacs/awh/bias.h @@ -140,241 +140,224 @@ class PointState; */ class Bias { - public: - //! Enum for requesting Bias set up with(out) I/O on this rank. - enum class ThisRankWillDoIO - { - No, //!< This rank will not do I/O. - Yes //!< This rank will do I/O. - }; - - /*! \brief - * Constructor. - * - * \param[in] biasIndexInCollection Index of the bias in collection. - * \param[in] awhParams AWH parameters. - * \param[in] awhBiasParams Bias parameters. - * \param[in] dimParams Bias dimension parameters. - * \param[in] beta 1/(k_B T). - * \param[in] mdTimeStep The MD time step. - * \param[in] numSharingSimulations The number of simulations to share the bias across. - * \param[in] biasInitFilename Name of file to read PMF and target from. - * \param[in] thisRankWillDoIO Tells whether this MPI rank will do I/O (checkpointing, AWH output), normally (only) the master rank does I/O. - * \param[in] disableUpdateSkips If to disable update skips, useful for testing. - */ - Bias(int biasIndexInCollection, - const AwhParams &awhParams, - const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - double beta, - double mdTimeStep, - int numSharingSimulations, - const std::string &biasInitFilename, - ThisRankWillDoIO thisRankWillDoIO, - BiasParams::DisableUpdateSkips disableUpdateSkips = BiasParams::DisableUpdateSkips::no); - - /*! \brief - * Print information about initialization to log file. - * - * Prints information about AWH variables that are set internally - * but might be of interest to the user. - * - * \param[in,out] fplog Log file, can be nullptr. - */ - void printInitializationToLog(FILE *fplog) const; - - /*! \brief - * Evolves the bias at every step. - * - * At each step the bias step needs to: - * - set the bias force and potential; - * - update the free energy and bias if needed; - * - reweight samples to extract the PMF. - * - * \param[in] coordValue The current coordinate value(s). - * \param[out] awhPotential Bias potential. - * \param[out] potentialJump Change in bias potential for this bias. - * \param[in] commRecord Struct for intra-simulation communication. - * \param[in] ms Struct for multi-simulation communication. - * \param[in] t Time. - * \param[in] step Time step. - * \param[in] seed Random seed. - * \param[in,out] fplog Log file. - * \returns a reference to the bias force, size \ref ndim(), valid until the next call of this method or destruction of Bias, whichever comes first. - */ - gmx::ArrayRef - calcForceAndUpdateBias(const awh_dvec coordValue, - double *awhPotential, - double *potentialJump, - const t_commrec *commRecord, - const gmx_multisim_t *ms, - double t, - int64_t step, - int64_t seed, - FILE *fplog); - - /*! \brief - * Calculates the convolved bias for a given coordinate value. - * - * The convolved bias is the effective bias acting on the coordinate. - * Since the bias here has arbitrary normalization, this only makes - * sense as a relative, to other coordinate values, measure of the bias. - * - * \param[in] coordValue The coordinate value. - * \returns the convolved bias >= -GMX_FLOAT_MAX. - */ - double calcConvolvedBias(const awh_dvec &coordValue) const - { - return state_.calcConvolvedBias(dimParams_, grid_, coordValue); - } - - /*! \brief - * Restore the bias state from history on the master rank and broadcast it. - * - * \param[in] biasHistory Bias history struct, only allowed to be nullptr on non-master ranks. - * \param[in] cr The communication record. - */ - void restoreStateFromHistory(const AwhBiasHistory *biasHistory, - const t_commrec *cr); - - /*! \brief - * Allocate and initialize a bias history with the given bias state. - * - * This function will be called at the start of a new simulation. - * Note that only constant data will be initialized here. - * History data is set by \ref updateHistory. - * - * \param[in,out] biasHistory AWH history to initialize. - */ - void initHistoryFromState(AwhBiasHistory *biasHistory) const; - - /*! \brief - * Update the bias history with the current state. - * - * \param[out] biasHistory Bias history struct. - */ - void updateHistory(AwhBiasHistory *biasHistory) const; - - /*! \brief - * Do all previously skipped updates. - * Public for use by tests. - */ - void doSkippedUpdatesForAllPoints(); - - //! Returns the dimensionality of the bias. - inline int ndim() const - { - return dimParams_.size(); - } - - /*! \brief Returns the dimension parameters. - */ - inline const std::vector &dimParams() const - { - return dimParams_; - } - - //! Returns the bias parameters - inline const BiasParams ¶ms() const - { - return params_; - } - - //! Returns the global state of the bias. - inline const BiasState &state() const - { - return state_; - } - - //! Returns the index of the bias. - inline int biasIndex() const - { - return params_.biasIndex; - } - - /*! \brief Return the coordinate value for a grid point. - * - * \param[in] gridPointIndex The index of the grid point. - */ - inline const awh_dvec &getGridCoordValue(size_t gridPointIndex) const - { - GMX_ASSERT(gridPointIndex < grid_.numPoints(), "gridPointIndex should be in the range of the grid"); - - return grid_.point(gridPointIndex).coordValue; - } - - private: - /*! \brief - * Performs statistical checks on the collected histograms and warns if issues are detected. - * - * \param[in] t Time. - * \param[in] step Time step. - * \param[in,out] fplog Output file for warnings. - */ - void warnForHistogramAnomalies(double t, - int64_t step, - FILE *fplog); - - /*! \brief - * Collect samples for the force correlation analysis on the grid. - * - * \param[in] probWeightNeighbor Probability weight of the neighboring points. - * \param[in] t The time. - */ - void updateForceCorrelationGrid(gmx::ArrayRef probWeightNeighbor, - double t); - - public: - /*! \brief Return a const reference to the force correlation grid. - */ - const CorrelationGrid &forceCorrelationGrid() const - { - GMX_RELEASE_ASSERT(forceCorrelationGrid_ != nullptr, "forceCorrelationGrid() should only be called with a valid force correlation object"); - - return *forceCorrelationGrid_; - } - - /*! \brief Return the number of data blocks that have been prepared for writing. - */ - int numEnergySubblocksToWrite() const; - - /*! \brief Write bias data blocks to energy subblocks. - * - * \param[in,out] subblock Energy subblocks to write to. - * \returns the number of subblocks written. - */ - int writeToEnergySubblocks(t_enxsubblock *subblock) const; - - /* Data members. */ - private: - const std::vector dimParams_; /**< Parameters for each dimension. */ - const Grid grid_; /**< The multidimensional grid organizing the coordinate point locations. */ - - const BiasParams params_; /**< Constant parameters for the method. */ - - BiasState state_; /**< The state, both global and of the grid points */ - std::vector updateList_; /**< List of points for update for temporary use (could be made another tempWorkSpace) */ - - const bool thisRankDoesIO_; /**< Tells whether this MPI rank will do I/O (checkpointing, AWH output) */ - - std::vector biasForce_; /**< Vector for returning the force to the caller. */ - - /* Force correlation grid */ - std::unique_ptr forceCorrelationGrid_; /**< Takes care of force correlation statistics for every grid point. */ - - /* I/O */ - std::unique_ptr writer_; /**< Takes care of AWH data output. */ - - /* Temporary working vectors used during the update. - * These are only here to avoid allocation at every MD step. - */ - std::vector < double, AlignedAllocator < double>> alignedTempWorkSpace_; /**< Working vector of doubles. */ - std::vector tempForce_; /**< Bias force work buffer. */ - - /* Run-local counter to avoid flooding log with warnings. */ - int numWarningsIssued_; /**< The number of warning issued in the current run. */ +public: + //! Enum for requesting Bias set up with(out) I/O on this rank. + enum class ThisRankWillDoIO + { + No, //!< This rank will not do I/O. + Yes //!< This rank will do I/O. + }; + + /*! \brief + * Constructor. + * + * \param[in] biasIndexInCollection Index of the bias in collection. + * \param[in] awhParams AWH parameters. + * \param[in] awhBiasParams Bias parameters. + * \param[in] dimParams Bias dimension parameters. + * \param[in] beta 1/(k_B T). + * \param[in] mdTimeStep The MD time step. + * \param[in] numSharingSimulations The number of simulations to share the bias across. + * \param[in] biasInitFilename Name of file to read PMF and target from. + * \param[in] thisRankWillDoIO Tells whether this MPI rank will do I/O (checkpointing, AWH output), normally (only) the master rank does I/O. + * \param[in] disableUpdateSkips If to disable update skips, useful for testing. + */ + Bias(int biasIndexInCollection, + const AwhParams& awhParams, + const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, + double beta, + double mdTimeStep, + int numSharingSimulations, + const std::string& biasInitFilename, + ThisRankWillDoIO thisRankWillDoIO, + BiasParams::DisableUpdateSkips disableUpdateSkips = BiasParams::DisableUpdateSkips::no); + + /*! \brief + * Print information about initialization to log file. + * + * Prints information about AWH variables that are set internally + * but might be of interest to the user. + * + * \param[in,out] fplog Log file, can be nullptr. + */ + void printInitializationToLog(FILE* fplog) const; + + /*! \brief + * Evolves the bias at every step. + * + * At each step the bias step needs to: + * - set the bias force and potential; + * - update the free energy and bias if needed; + * - reweight samples to extract the PMF. + * + * \param[in] coordValue The current coordinate value(s). + * \param[out] awhPotential Bias potential. + * \param[out] potentialJump Change in bias potential for this bias. + * \param[in] commRecord Struct for intra-simulation communication. + * \param[in] ms Struct for multi-simulation communication. + * \param[in] t Time. + * \param[in] step Time step. + * \param[in] seed Random seed. + * \param[in,out] fplog Log file. + * \returns a reference to the bias force, size \ref ndim(), valid until the next call of this method or destruction of Bias, whichever comes first. + */ + gmx::ArrayRef calcForceAndUpdateBias(const awh_dvec coordValue, + double* awhPotential, + double* potentialJump, + const t_commrec* commRecord, + const gmx_multisim_t* ms, + double t, + int64_t step, + int64_t seed, + FILE* fplog); + + /*! \brief + * Calculates the convolved bias for a given coordinate value. + * + * The convolved bias is the effective bias acting on the coordinate. + * Since the bias here has arbitrary normalization, this only makes + * sense as a relative, to other coordinate values, measure of the bias. + * + * \param[in] coordValue The coordinate value. + * \returns the convolved bias >= -GMX_FLOAT_MAX. + */ + double calcConvolvedBias(const awh_dvec& coordValue) const + { + return state_.calcConvolvedBias(dimParams_, grid_, coordValue); + } + + /*! \brief + * Restore the bias state from history on the master rank and broadcast it. + * + * \param[in] biasHistory Bias history struct, only allowed to be nullptr on non-master ranks. + * \param[in] cr The communication record. + */ + void restoreStateFromHistory(const AwhBiasHistory* biasHistory, const t_commrec* cr); + + /*! \brief + * Allocate and initialize a bias history with the given bias state. + * + * This function will be called at the start of a new simulation. + * Note that only constant data will be initialized here. + * History data is set by \ref updateHistory. + * + * \param[in,out] biasHistory AWH history to initialize. + */ + void initHistoryFromState(AwhBiasHistory* biasHistory) const; + + /*! \brief + * Update the bias history with the current state. + * + * \param[out] biasHistory Bias history struct. + */ + void updateHistory(AwhBiasHistory* biasHistory) const; + + /*! \brief + * Do all previously skipped updates. + * Public for use by tests. + */ + void doSkippedUpdatesForAllPoints(); + + //! Returns the dimensionality of the bias. + inline int ndim() const { return dimParams_.size(); } + + /*! \brief Returns the dimension parameters. + */ + inline const std::vector& dimParams() const { return dimParams_; } + + //! Returns the bias parameters + inline const BiasParams& params() const { return params_; } + + //! Returns the global state of the bias. + inline const BiasState& state() const { return state_; } + + //! Returns the index of the bias. + inline int biasIndex() const { return params_.biasIndex; } + + /*! \brief Return the coordinate value for a grid point. + * + * \param[in] gridPointIndex The index of the grid point. + */ + inline const awh_dvec& getGridCoordValue(size_t gridPointIndex) const + { + GMX_ASSERT(gridPointIndex < grid_.numPoints(), + "gridPointIndex should be in the range of the grid"); + + return grid_.point(gridPointIndex).coordValue; + } + +private: + /*! \brief + * Performs statistical checks on the collected histograms and warns if issues are detected. + * + * \param[in] t Time. + * \param[in] step Time step. + * \param[in,out] fplog Output file for warnings. + */ + void warnForHistogramAnomalies(double t, int64_t step, FILE* fplog); + + /*! \brief + * Collect samples for the force correlation analysis on the grid. + * + * \param[in] probWeightNeighbor Probability weight of the neighboring points. + * \param[in] t The time. + */ + void updateForceCorrelationGrid(gmx::ArrayRef probWeightNeighbor, double t); + +public: + /*! \brief Return a const reference to the force correlation grid. + */ + const CorrelationGrid& forceCorrelationGrid() const + { + GMX_RELEASE_ASSERT(forceCorrelationGrid_ != nullptr, + "forceCorrelationGrid() should only be called with a valid force " + "correlation object"); + + return *forceCorrelationGrid_; + } + + /*! \brief Return the number of data blocks that have been prepared for writing. + */ + int numEnergySubblocksToWrite() const; + + /*! \brief Write bias data blocks to energy subblocks. + * + * \param[in,out] subblock Energy subblocks to write to. + * \returns the number of subblocks written. + */ + int writeToEnergySubblocks(t_enxsubblock* subblock) const; + + /* Data members. */ +private: + const std::vector dimParams_; /**< Parameters for each dimension. */ + const Grid grid_; /**< The multidimensional grid organizing the coordinate point locations. */ + + const BiasParams params_; /**< Constant parameters for the method. */ + + BiasState state_; /**< The state, both global and of the grid points */ + std::vector updateList_; /**< List of points for update for temporary use (could be made another tempWorkSpace) */ + + const bool thisRankDoesIO_; /**< Tells whether this MPI rank will do I/O (checkpointing, AWH output) */ + + std::vector biasForce_; /**< Vector for returning the force to the caller. */ + + /* Force correlation grid */ + std::unique_ptr forceCorrelationGrid_; /**< Takes care of force correlation statistics for every grid point. */ + + /* I/O */ + std::unique_ptr writer_; /**< Takes care of AWH data output. */ + + /* Temporary working vectors used during the update. + * These are only here to avoid allocation at every MD step. + */ + std::vector> alignedTempWorkSpace_; /**< Working vector of doubles. */ + std::vector tempForce_; /**< Bias force work buffer. */ + + /* Run-local counter to avoid flooding log with warnings. */ + int numWarningsIssued_; /**< The number of warning issued in the current run. */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_BIAS_H */ diff --git a/src/gromacs/awh/biasparams.cpp b/src/gromacs/awh/biasparams.cpp index a02f4e4d8d..6f9b0d387d 100644 --- a/src/gromacs/awh/biasparams.cpp +++ b/src/gromacs/awh/biasparams.cpp @@ -74,8 +74,7 @@ namespace * \param[in] awhBiasParams Bias parameters. * \returns the target update interval in steps. */ -int64_t calcTargetUpdateInterval(const AwhParams &awhParams, - const AwhBiasParams &awhBiasParams) +int64_t calcTargetUpdateInterval(const AwhParams& awhParams, const AwhBiasParams& awhBiasParams) { int64_t numStepsUpdateTarget = 0; /* Set the target update frequency based on the target distrbution type @@ -84,16 +83,15 @@ int64_t calcTargetUpdateInterval(const AwhParams &awhParams, */ switch (awhBiasParams.eTarget) { - case eawhtargetCONSTANT: - numStepsUpdateTarget = 0; - break; + case eawhtargetCONSTANT: numStepsUpdateTarget = 0; break; case eawhtargetCUTOFF: case eawhtargetBOLTZMANN: - /* Updating the target generally requires updating the whole grid so to keep the cost down - we generally update the target less often than the free energy (unless the free energy - update step is set to > 100 samples). */ + /* Updating the target generally requires updating the whole grid so to keep the cost + down we generally update the target less often than the free energy (unless the free + energy update step is set to > 100 samples). */ numStepsUpdateTarget = std::max(100 % awhParams.numSamplesUpdateFreeEnergy, - awhParams.numSamplesUpdateFreeEnergy)*awhParams.nstSampleCoord; + awhParams.numSamplesUpdateFreeEnergy) + * awhParams.nstSampleCoord; break; case eawhtargetLOCALBOLTZMANN: /* The target distribution is set equal to the reference histogram which is updated every free energy update. @@ -102,11 +100,9 @@ int64_t calcTargetUpdateInterval(const AwhParams &awhParams, target distribution. One could avoid the global update by making a local target update function (and postponing target updates for non-local points as for the free energy update). We avoid such additions for now and accept that this target type always does global updates. */ - numStepsUpdateTarget = awhParams.numSamplesUpdateFreeEnergy*awhParams.nstSampleCoord; - break; - default: - GMX_RELEASE_ASSERT(false, "Unknown AWH target type"); + numStepsUpdateTarget = awhParams.numSamplesUpdateFreeEnergy * awhParams.nstSampleCoord; break; + default: GMX_RELEASE_ASSERT(false, "Unknown AWH target type"); break; } return numStepsUpdateTarget; @@ -119,23 +115,25 @@ int64_t calcTargetUpdateInterval(const AwhParams &awhParams, * \param[in] gridAxis The Grid axes. * \returns the check interval in steps. */ -int64_t calcCheckCoveringInterval(const AwhParams &awhParams, - const std::vector &dimParams, - const std::vector &gridAxis) +int64_t calcCheckCoveringInterval(const AwhParams& awhParams, + const std::vector& dimParams, + const std::vector& gridAxis) { /* Each sample will have a width of sigma. To cover the axis a minimum number of samples of width sigma is required. */ int minNumSamplesCover = 0; for (size_t d = 0; d < gridAxis.size(); d++) { - GMX_RELEASE_ASSERT(dimParams[d].betak > 0, "Inverse temperature (beta) and force constant (k) should be positive."); - double sigma = 1.0/std::sqrt(dimParams[d].betak); + GMX_RELEASE_ASSERT(dimParams[d].betak > 0, + "Inverse temperature (beta) and force constant (k) should be positive."); + double sigma = 1.0 / std::sqrt(dimParams[d].betak); /* The additional sample is here because to cover a discretized axis of length sigma one needs two samples, one for each end point. */ - GMX_RELEASE_ASSERT(gridAxis[d].length()/sigma < std::numeric_limits::max(), "The axis length in units of sigma should fit in an int"); - int numSamplesCover = static_cast(std::ceil(gridAxis[d].length()/sigma)) + 1; + GMX_RELEASE_ASSERT(gridAxis[d].length() / sigma < std::numeric_limits::max(), + "The axis length in units of sigma should fit in an int"); + int numSamplesCover = static_cast(std::ceil(gridAxis[d].length() / sigma)) + 1; /* The minimum number of samples needed for simultaneously covering all axes is limited by the axis requiring most @@ -146,12 +144,15 @@ int64_t calcCheckCoveringInterval(const AwhParams &awhParams, /* Convert to number of steps using the sampling frequency. The check interval should be a multiple of the update step interval. */ - int numStepsUpdate = awhParams.numSamplesUpdateFreeEnergy*awhParams.nstSampleCoord; - GMX_RELEASE_ASSERT(awhParams.numSamplesUpdateFreeEnergy > 0, "When checking for AWH coverings, the number of samples per AWH update need to be > 0."); - int numUpdatesCheck = std::max(1, minNumSamplesCover/awhParams.numSamplesUpdateFreeEnergy); - int numStepsCheck = numUpdatesCheck*numStepsUpdate; + int numStepsUpdate = awhParams.numSamplesUpdateFreeEnergy * awhParams.nstSampleCoord; + GMX_RELEASE_ASSERT(awhParams.numSamplesUpdateFreeEnergy > 0, + "When checking for AWH coverings, the number of samples per AWH update need " + "to be > 0."); + int numUpdatesCheck = std::max(1, minNumSamplesCover / awhParams.numSamplesUpdateFreeEnergy); + int numStepsCheck = numUpdatesCheck * numStepsUpdate; - GMX_RELEASE_ASSERT(numStepsCheck % numStepsUpdate == 0, "Only check covering at free energy update steps"); + GMX_RELEASE_ASSERT(numStepsCheck % numStepsUpdate == 0, + "Only check covering at free energy update steps"); return numStepsCheck; } @@ -169,13 +170,12 @@ int64_t calcCheckCoveringInterval(const AwhParams &awhParams, double gaussianGeometryFactor(gmx::ArrayRef xArray) { /* For convenience we give the geometry factor function a name: zeta(x) */ - constexpr size_t tableSize = 5; - std::array xTabulated = - { {1e-5, 1e-4, 1e-3, 1e-2, 1e-1} }; - std::array zetaTable1d = - { { 0.166536811948, 0.16653116886, 0.166250075882, 0.162701098306, 0.129272430287 } }; - std::array zetaTable2d = - { { 2.31985974274, 1.86307292523, 1.38159772648, 0.897554759158, 0.405578211115 } }; + constexpr size_t tableSize = 5; + std::array xTabulated = { { 1e-5, 1e-4, 1e-3, 1e-2, 1e-1 } }; + std::array zetaTable1d = { { 0.166536811948, 0.16653116886, 0.166250075882, + 0.162701098306, 0.129272430287 } }; + std::array zetaTable2d = { { 2.31985974274, 1.86307292523, 1.38159772648, + 0.897554759158, 0.405578211115 } }; gmx::ArrayRef zetaTable; @@ -196,13 +196,13 @@ double gaussianGeometryFactor(gmx::ArrayRef xArray) /* TODO. Really zeta is a function of an ndim-dimensional vector x and we shoudl have a ndim-dimensional lookup-table. Here we take the geometric average of the components of x which is ok if the x-components are not very different. */ double xScalar = 1; - for (const double &x : xArray) + for (const double& x : xArray) { xScalar *= x; } GMX_ASSERT(!xArray.empty(), "We should have a non-empty input array"); - xScalar = std::pow(xScalar, 1.0/xArray.size()); + xScalar = std::pow(xScalar, 1.0 / xArray.size()); /* Look up zeta(x) */ size_t xIndex = 0; @@ -226,8 +226,8 @@ double gaussianGeometryFactor(gmx::ArrayRef xArray) /* Interpolate */ double x0 = xTabulated[xIndex - 1]; double x1 = xTabulated[xIndex]; - double w = (xScalar - x0)/(x1 - x0); - zEstimate = w*zetaTable[xIndex - 1] + (1 - w)*zetaTable[xIndex]; + double w = (xScalar - x0) / (x1 - x0); + zEstimate = w * zetaTable[xIndex - 1] + (1 - w) * zetaTable[xIndex]; } return zEstimate; @@ -243,9 +243,9 @@ double gaussianGeometryFactor(gmx::ArrayRef xArray) * \param[in] samplingTimestep Sampling frequency of probability weights. * \returns estimate of initial histogram size. */ -double getInitialHistogramSizeEstimate(const std::vector &dimParams, - const AwhBiasParams &awhBiasParams, - const std::vector &gridAxis, +double getInitialHistogramSizeEstimate(const std::vector& dimParams, + const AwhBiasParams& awhBiasParams, + const std::vector& gridAxis, double beta, double samplingTimestep) { @@ -257,15 +257,16 @@ double getInitialHistogramSizeEstimate(const std::vector &dimParams, double axisLength = gridAxis[d].length(); if (axisLength > 0) { - crossingTime += awhBiasParams.dimParams[d].diffusion/(axisLength*axisLength); + crossingTime += awhBiasParams.dimParams[d].diffusion / (axisLength * axisLength); /* The sigma of the Gaussian distribution in the umbrella */ - double sigma = 1./std::sqrt(dimParams[d].betak); - x.push_back(sigma/axisLength); + double sigma = 1. / std::sqrt(dimParams[d].betak); + x.push_back(sigma / axisLength); } } GMX_RELEASE_ASSERT(crossingTime > 0, "We need at least one dimension with non-zero length"); - double errorInitialInKT = beta*awhBiasParams.errorInitial; - double histogramSize = gaussianGeometryFactor(x)/(crossingTime*gmx::square(errorInitialInKT)*samplingTimestep); + double errorInitialInKT = beta * awhBiasParams.errorInitial; + double histogramSize = gaussianGeometryFactor(x) + / (crossingTime * gmx::square(errorInitialInKT) * samplingTimestep); return histogramSize; } @@ -276,8 +277,7 @@ double getInitialHistogramSizeEstimate(const std::vector &dimParams, * \param[in] numSharingSimulations The number of simulations to share the bias across. * \returns the number of shared updates. */ -int getNumSharedUpdate(const AwhBiasParams &awhBiasParams, - int numSharingSimulations) +int getNumSharedUpdate(const AwhBiasParams& awhBiasParams, int numSharingSimulations) { GMX_RELEASE_ASSERT(numSharingSimulations >= 1, "We should ''share'' at least with ourselves"); @@ -287,37 +287,41 @@ int getNumSharedUpdate(const AwhBiasParams &awhBiasParams, { /* We do not yet support sharing within a simulation */ int numSharedWithinThisSimulation = 1; - numShared = numSharingSimulations*numSharedWithinThisSimulation; + numShared = numSharingSimulations * numSharedWithinThisSimulation; } return numShared; } -} // namespace +} // namespace -BiasParams::BiasParams(const AwhParams &awhParams, - const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, +BiasParams::BiasParams(const AwhParams& awhParams, + const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, double beta, double mdTimeStep, DisableUpdateSkips disableUpdateSkips, int numSharingSimulations, - const std::vector &gridAxis, + const std::vector& gridAxis, int biasIndex) : - invBeta(beta > 0 ? 1/beta : 0), + invBeta(beta > 0 ? 1 / beta : 0), numStepsSampleCoord_(awhParams.nstSampleCoord), numSamplesUpdateFreeEnergy_(awhParams.numSamplesUpdateFreeEnergy), numStepsUpdateTarget_(calcTargetUpdateInterval(awhParams, awhBiasParams)), numStepsCheckCovering_(calcCheckCoveringInterval(awhParams, dimParams, gridAxis)), eTarget(awhBiasParams.eTarget), - freeEnergyCutoffInKT(beta*awhBiasParams.targetCutoff), + freeEnergyCutoffInKT(beta * awhBiasParams.targetCutoff), temperatureScaleFactor(awhBiasParams.targetBetaScaling), idealWeighthistUpdate(eTarget != eawhtargetLOCALBOLTZMANN), numSharedUpdate(getNumSharedUpdate(awhBiasParams, numSharingSimulations)), - updateWeight(numSamplesUpdateFreeEnergy_*numSharedUpdate), + updateWeight(numSamplesUpdateFreeEnergy_ * numSharedUpdate), localWeightScaling(eTarget == eawhtargetLOCALBOLTZMANN ? temperatureScaleFactor : 1), - initialErrorInKT(beta*awhBiasParams.errorInitial), - initialHistogramSize(getInitialHistogramSizeEstimate(dimParams, awhBiasParams, gridAxis, beta, numStepsSampleCoord_*mdTimeStep)), + initialErrorInKT(beta * awhBiasParams.errorInitial), + initialHistogramSize(getInitialHistogramSizeEstimate(dimParams, + awhBiasParams, + gridAxis, + beta, + numStepsSampleCoord_ * mdTimeStep)), convolveForce(awhParams.ePotential == eawhpotentialCONVOLVED), biasIndex(biasIndex), disableUpdateSkips_(disableUpdateSkips == DisableUpdateSkips::yes) @@ -329,9 +333,9 @@ BiasParams::BiasParams(const AwhParams &awhParams, for (int d = 0; d < awhBiasParams.ndim; d++) { - double coverRadiusInNm = 0.5*awhBiasParams.dimParams[d].coverDiameter; + double coverRadiusInNm = 0.5 * awhBiasParams.dimParams[d].coverDiameter; double spacing = gridAxis[d].spacing(); - coverRadius_[d] = spacing > 0 ? static_cast(std::round(coverRadiusInNm/spacing)) : 0; + coverRadius_[d] = spacing > 0 ? static_cast(std::round(coverRadiusInNm / spacing)) : 0; } } diff --git a/src/gromacs/awh/biasparams.h b/src/gromacs/awh/biasparams.h index e3b4bd137b..938eefce1e 100644 --- a/src/gromacs/awh/biasparams.h +++ b/src/gromacs/awh/biasparams.h @@ -69,175 +69,160 @@ class GridAxis; */ class BiasParams { - public: - /*! \brief Switch to turn off update skips, useful for testing. - */ - enum class DisableUpdateSkips - { - no, /**< Allow update skips (when supported by the method) */ - yes /**< Disable update skips */ - }; - - /*! \brief - * Check if the parameters permit skipping updates. - * - * Generally, we can skip updates of points that are non-local - * at the time of the update if we for later times, when the points - * with skipped updates have become local, know exactly how to apply - * the previous updates. The free energy updates only depend - * on local sampling, but the histogram rescaling factors - * generally depend on the histogram size (all samples). - * If the histogram size is kept constant or the scaling factors - * are trivial, this is not a problem. However, if the histogram growth - * is scaled down by some factor the size at the time of the update - * needs to be known. It would be fairly simple to, for a deterministically - * growing histogram, backtrack and calculate this value, but currently - * we just disallow this case. This is not a restriction because it - * only affects the local Boltzmann target type for which every update - * is currently anyway global because the target is always updated globally. - * - * \returns true when we can skip updates. - */ - inline bool skipUpdates() const - { - return (!disableUpdateSkips_ && localWeightScaling == 1); - } - - /*! \brief - * Returns the radius that needs to be sampled around a point before it is considered covered. - */ - inline const awh_ivec &coverRadius() const - { - return coverRadius_; - } - - /*! \brief - * Returns whether we should sample the coordinate. - * - * \param[in] step The MD step number. - */ - inline bool isSampleCoordStep(int64_t step) const - { - return (step > 0 && step % numStepsSampleCoord_ == 0); - } - - /*! \brief - * Returns whether we should update the free energy. - * - * \param[in] step The MD step number. - */ - inline bool isUpdateFreeEnergyStep(int64_t step) const - { - int stepIntervalUpdateFreeEnergy = numSamplesUpdateFreeEnergy_*numStepsSampleCoord_; - return (step > 0 && step % stepIntervalUpdateFreeEnergy == 0); - } - - /*! \brief - * Returns whether we should update the target distribution. - * - * \param[in] step The MD step number. - */ - inline bool isUpdateTargetStep(int64_t step) const - { - return step % numStepsUpdateTarget_ == 0; - } - - /*! \brief - * Returns if to do checks for covering in the initial stage. - * - * To avoid overhead due to expensive checks, we do not check - * at every free energy update. However, if checks are - * performed too rarely the detection of coverings will be - * delayed, ultimately affecting free energy convergence. - * - * \param[in] step Time step. - * \returns true at steps where checks should be performed. - * \note Only returns true at free energy update steps. - */ - bool isCheckCoveringStep(int64_t step) const - { - return step % numStepsCheckCovering_ == 0; - } - - /*! \brief - * Returns if to perform checks for anomalies in the histogram. - * - * To avoid overhead due to expensive checks, we do not check - * at every free energy update. These checks are only used for - * warning the user and can be made as infrequently as - * neccessary without affecting the algorithm itself. - * - * \param[in] step Time step. - * \returns true at steps where checks should be performed. - * \note Only returns true at free energy update steps. - * \todo Currently this function just calls isCheckCoveringStep but the checks could be done less frequently. - */ - bool isCheckHistogramForAnomaliesStep(int64_t step) const - { - return isCheckCoveringStep(step); - } - - /*! \brief Constructor. - * - * The local Boltzmann target distibution is defined by - * 1) Adding the sampled weights instead of the target weights to the reference weight histogram. - * 2) Scaling the weights of these samples by the beta scaling factor. - * 3) Setting the target distribution equal the reference weight histogram. - * This requires the following special update settings: - * localWeightScaling = targetParam - * idealWeighthistUpdate = false - * Note: these variables could in principle be set to something else also for other target distribution types. - * However, localWeightScaling < 1 is in general expected to give lower efficiency and, except for local Boltzmann, - * idealWeightHistUpdate = false gives (in my experience) unstable, non-converging results. - * - * \param[in] awhParams AWH parameters. - * \param[in] awhBiasParams Bias parameters. - * \param[in] dimParams Bias dimension parameters. - * \param[in] beta 1/(k_B T) in units of 1/(kJ/mol), should be > 0. - * \param[in] mdTimeStep The MD time step. - * \param[in] numSharingSimulations The number of simulations to share the bias across. - * \param[in] gridAxis The grid axes. - * \param[in] disableUpdateSkips If to disable update skips, useful for testing. - * \param[in] biasIndex Index of the bias. - */ - BiasParams(const AwhParams &awhParams, - const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - double beta, - double mdTimeStep, - DisableUpdateSkips disableUpdateSkips, - int numSharingSimulations, - const std::vector &gridAxis, - int biasIndex); - - /* Data members */ - const double invBeta; /**< 1/beta = kT in kJ/mol */ - private: - const int64_t numStepsSampleCoord_; /**< Number of steps per coordinate value sample. */ - public: - const int numSamplesUpdateFreeEnergy_; /**< Number of samples per free energy update. */ - private: - const int64_t numStepsUpdateTarget_; /**< Number of steps per updating the target distribution. */ - const int64_t numStepsCheckCovering_; /**< Number of steps per checking for covering. */ - public: - const int eTarget; /**< Type of target distribution. */ - const double freeEnergyCutoffInKT; /**< Free energy cut-off in kT for cut-off target distribution. */ - const double temperatureScaleFactor; /**< Temperature scaling factor for temperature scaled targed distributions. */ - const bool idealWeighthistUpdate; /**< Update reference weighthistogram using the target distribution? Otherwise use the realized distribution. */ - const int numSharedUpdate; /**< The number of (multi-)simulations sharing the bias update */ - const double updateWeight; /**< The probability weight accumulated for each update. */ - const double localWeightScaling; /**< Scaling factor applied to a sample before adding it to the reference weight histogram (= 1, usually). */ - const double initialErrorInKT; /**< Estimated initial free energy error in kT. */ - const double initialHistogramSize; /**< Initial reference weight histogram size. */ - private: - awh_ivec coverRadius_; /**< The radius (in points) that needs to be sampled around a point before it is considered covered. */ - public: - const bool convolveForce; /**< True if we convolve the force, false means use MC between umbrellas. */ - const int biasIndex; /**< Index of the bias, used as a second random seed and for priting. */ - private: - const bool disableUpdateSkips_; /**< If true, we disallow update skips, even when the method supports it. */ +public: + /*! \brief Switch to turn off update skips, useful for testing. + */ + enum class DisableUpdateSkips + { + no, /**< Allow update skips (when supported by the method) */ + yes /**< Disable update skips */ + }; + + /*! \brief + * Check if the parameters permit skipping updates. + * + * Generally, we can skip updates of points that are non-local + * at the time of the update if we for later times, when the points + * with skipped updates have become local, know exactly how to apply + * the previous updates. The free energy updates only depend + * on local sampling, but the histogram rescaling factors + * generally depend on the histogram size (all samples). + * If the histogram size is kept constant or the scaling factors + * are trivial, this is not a problem. However, if the histogram growth + * is scaled down by some factor the size at the time of the update + * needs to be known. It would be fairly simple to, for a deterministically + * growing histogram, backtrack and calculate this value, but currently + * we just disallow this case. This is not a restriction because it + * only affects the local Boltzmann target type for which every update + * is currently anyway global because the target is always updated globally. + * + * \returns true when we can skip updates. + */ + inline bool skipUpdates() const { return (!disableUpdateSkips_ && localWeightScaling == 1); } + + /*! \brief + * Returns the radius that needs to be sampled around a point before it is considered covered. + */ + inline const awh_ivec& coverRadius() const { return coverRadius_; } + + /*! \brief + * Returns whether we should sample the coordinate. + * + * \param[in] step The MD step number. + */ + inline bool isSampleCoordStep(int64_t step) const + { + return (step > 0 && step % numStepsSampleCoord_ == 0); + } + + /*! \brief + * Returns whether we should update the free energy. + * + * \param[in] step The MD step number. + */ + inline bool isUpdateFreeEnergyStep(int64_t step) const + { + int stepIntervalUpdateFreeEnergy = numSamplesUpdateFreeEnergy_ * numStepsSampleCoord_; + return (step > 0 && step % stepIntervalUpdateFreeEnergy == 0); + } + + /*! \brief + * Returns whether we should update the target distribution. + * + * \param[in] step The MD step number. + */ + inline bool isUpdateTargetStep(int64_t step) const { return step % numStepsUpdateTarget_ == 0; } + + /*! \brief + * Returns if to do checks for covering in the initial stage. + * + * To avoid overhead due to expensive checks, we do not check + * at every free energy update. However, if checks are + * performed too rarely the detection of coverings will be + * delayed, ultimately affecting free energy convergence. + * + * \param[in] step Time step. + * \returns true at steps where checks should be performed. + * \note Only returns true at free energy update steps. + */ + bool isCheckCoveringStep(int64_t step) const { return step % numStepsCheckCovering_ == 0; } + + /*! \brief + * Returns if to perform checks for anomalies in the histogram. + * + * To avoid overhead due to expensive checks, we do not check + * at every free energy update. These checks are only used for + * warning the user and can be made as infrequently as + * neccessary without affecting the algorithm itself. + * + * \param[in] step Time step. + * \returns true at steps where checks should be performed. + * \note Only returns true at free energy update steps. + * \todo Currently this function just calls isCheckCoveringStep but the checks could be done less frequently. + */ + bool isCheckHistogramForAnomaliesStep(int64_t step) const { return isCheckCoveringStep(step); } + + /*! \brief Constructor. + * + * The local Boltzmann target distibution is defined by + * 1) Adding the sampled weights instead of the target weights to the reference weight histogram. + * 2) Scaling the weights of these samples by the beta scaling factor. + * 3) Setting the target distribution equal the reference weight histogram. + * This requires the following special update settings: + * localWeightScaling = targetParam + * idealWeighthistUpdate = false + * Note: these variables could in principle be set to something else also for other target distribution types. + * However, localWeightScaling < 1 is in general expected to give lower efficiency and, except for local Boltzmann, + * idealWeightHistUpdate = false gives (in my experience) unstable, non-converging results. + * + * \param[in] awhParams AWH parameters. + * \param[in] awhBiasParams Bias parameters. + * \param[in] dimParams Bias dimension parameters. + * \param[in] beta 1/(k_B T) in units of 1/(kJ/mol), should be > 0. + * \param[in] mdTimeStep The MD time step. + * \param[in] numSharingSimulations The number of simulations to share the bias across. + * \param[in] gridAxis The grid axes. + * \param[in] disableUpdateSkips If to disable update skips, useful for testing. + * \param[in] biasIndex Index of the bias. + */ + BiasParams(const AwhParams& awhParams, + const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, + double beta, + double mdTimeStep, + DisableUpdateSkips disableUpdateSkips, + int numSharingSimulations, + const std::vector& gridAxis, + int biasIndex); + + /* Data members */ + const double invBeta; /**< 1/beta = kT in kJ/mol */ +private: + const int64_t numStepsSampleCoord_; /**< Number of steps per coordinate value sample. */ +public: + const int numSamplesUpdateFreeEnergy_; /**< Number of samples per free energy update. */ +private: + const int64_t numStepsUpdateTarget_; /**< Number of steps per updating the target distribution. */ + const int64_t numStepsCheckCovering_; /**< Number of steps per checking for covering. */ +public: + const int eTarget; /**< Type of target distribution. */ + const double freeEnergyCutoffInKT; /**< Free energy cut-off in kT for cut-off target distribution. */ + const double temperatureScaleFactor; /**< Temperature scaling factor for temperature scaled targed distributions. */ + const bool idealWeighthistUpdate; /**< Update reference weighthistogram using the target distribution? Otherwise use the realized distribution. */ + const int numSharedUpdate; /**< The number of (multi-)simulations sharing the bias update */ + const double updateWeight; /**< The probability weight accumulated for each update. */ + const double localWeightScaling; /**< Scaling factor applied to a sample before adding it to the reference weight histogram (= 1, usually). */ + const double initialErrorInKT; /**< Estimated initial free energy error in kT. */ + const double initialHistogramSize; /**< Initial reference weight histogram size. */ +private: + awh_ivec coverRadius_; /**< The radius (in points) that needs to be sampled around a point before it is considered covered. */ +public: + const bool convolveForce; /**< True if we convolve the force, false means use MC between umbrellas. */ + const int biasIndex; /**< Index of the bias, used as a second random seed and for priting. */ +private: + const bool disableUpdateSkips_; /**< If true, we disallow update skips, even when the method supports it. */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_BIASPARAMS_H */ diff --git a/src/gromacs/awh/biassharing.cpp b/src/gromacs/awh/biassharing.cpp index dbf7a40ab8..52d5a89b4e 100644 --- a/src/gromacs/awh/biassharing.cpp +++ b/src/gromacs/awh/biassharing.cpp @@ -57,7 +57,7 @@ namespace gmx { -bool haveBiasSharingWithinSimulation(const AwhParams &awhParams) +bool haveBiasSharingWithinSimulation(const AwhParams& awhParams) { bool haveSharing = false; @@ -79,9 +79,9 @@ bool haveBiasSharingWithinSimulation(const AwhParams &awhParams) return haveSharing; } -void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams &awhParams, - const std::vector &pointSize, - const gmx_multisim_t *multiSimComm) +void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams& awhParams, + const std::vector& pointSize, + const gmx_multisim_t* multiSimComm) { const int numSim = multiSimComm->nsim; @@ -98,7 +98,9 @@ void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams & numShare++; if (group != numShare) { - GMX_THROW(InvalidInputError("AWH biases that are shared should use consequetive share-group values starting at 1")); + GMX_THROW( + InvalidInputError("AWH biases that are shared should use consequetive " + "share-group values starting at 1")); } } } @@ -109,23 +111,26 @@ void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams & { if (numShareAll[sim] != numShareAll[0]) { - GMX_THROW(InvalidInputError("Different simulations attempt to share different number of biases")); + GMX_THROW(InvalidInputError( + "Different simulations attempt to share different number of biases")); } } - std::vector intervals(numSim*2); - intervals[numSim*0 + multiSimComm->sim] = awhParams.nstSampleCoord; - intervals[numSim*1 + multiSimComm->sim] = awhParams.numSamplesUpdateFreeEnergy; + std::vector intervals(numSim * 2); + intervals[numSim * 0 + multiSimComm->sim] = awhParams.nstSampleCoord; + intervals[numSim * 1 + multiSimComm->sim] = awhParams.numSamplesUpdateFreeEnergy; gmx_sumi_sim(intervals.size(), intervals.data(), multiSimComm); for (int sim = 1; sim < numSim; sim++) { if (intervals[sim] != intervals[0]) { - GMX_THROW(InvalidInputError("All simulations should have the same AWH sample interval")); + GMX_THROW( + InvalidInputError("All simulations should have the same AWH sample interval")); } if (intervals[numSim + sim] != intervals[numSim]) { - GMX_THROW(InvalidInputError("All simulations should have the same AWH free-energy update interval")); + GMX_THROW(InvalidInputError( + "All simulations should have the same AWH free-energy update interval")); } } @@ -143,7 +148,10 @@ void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams & { if (pointSizes[sim] != pointSizes[0]) { - GMX_THROW(InvalidInputError(gmx::formatString("Shared AWH bias %d has different grid sizes in different simulations\n", b + 1))); + GMX_THROW(InvalidInputError( + gmx::formatString("Shared AWH bias %d has different grid sizes in " + "different simulations\n", + b + 1))); } } } diff --git a/src/gromacs/awh/biassharing.h b/src/gromacs/awh/biassharing.h index 19fdadc7d3..b98a4344a8 100644 --- a/src/gromacs/awh/biassharing.h +++ b/src/gromacs/awh/biassharing.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,7 +62,7 @@ struct AwhParams; * * \param[in] awhParams The AWH parameters. */ -bool haveBiasSharingWithinSimulation(const AwhParams &awhParams); +bool haveBiasSharingWithinSimulation(const AwhParams& awhParams); /*! \brief Checks if biases are compatible for sharing between simulations, throws if not. * @@ -75,10 +75,10 @@ bool haveBiasSharingWithinSimulation(const AwhParams &awhParams); * \param[in] pointSize Vector of grid-point sizes for each bias. * \param[in] multiSimComm Struct for multi-simulation communication. */ -void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams &awhParams, - const std::vector &pointSize, - const gmx_multisim_t *multiSimComm); +void biasesAreCompatibleForSharingBetweenSimulations(const AwhParams& awhParams, + const std::vector& pointSize, + const gmx_multisim_t* multiSimComm); -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_BIASSHARING_H */ diff --git a/src/gromacs/awh/biasstate.cpp b/src/gromacs/awh/biasstate.cpp index 7247a260eb..081fb7f13f 100644 --- a/src/gromacs/awh/biasstate.cpp +++ b/src/gromacs/awh/biasstate.cpp @@ -98,8 +98,7 @@ namespace * \param[in,out] arrayRef The data to sum. * \param[in] multiSimComm Struct for multi-simulation communication. */ -void sumOverSimulations(gmx::ArrayRef arrayRef, - const gmx_multisim_t *multiSimComm) +void sumOverSimulations(gmx::ArrayRef arrayRef, const gmx_multisim_t* multiSimComm) { gmx_sumi_sim(arrayRef.size(), arrayRef.data(), multiSimComm); } @@ -110,8 +109,7 @@ void sumOverSimulations(gmx::ArrayRef arrayRef, * \param[in,out] arrayRef The data to sum. * \param[in] multiSimComm Struct for multi-simulation communication. */ -void sumOverSimulations(gmx::ArrayRef arrayRef, - const gmx_multisim_t *multiSimComm) +void sumOverSimulations(gmx::ArrayRef arrayRef, const gmx_multisim_t* multiSimComm) { gmx_sumd_sim(arrayRef.size(), arrayRef.data(), multiSimComm); } @@ -126,9 +124,7 @@ void sumOverSimulations(gmx::ArrayRef arrayRef, * \param[in] multiSimComm Struct for multi-simulation communication. */ template -void sumOverSimulations(gmx::ArrayRef arrayRef, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm) +void sumOverSimulations(gmx::ArrayRef arrayRef, const t_commrec* commRecord, const gmx_multisim_t* multiSimComm) { if (MASTER(commRecord)) { @@ -136,7 +132,7 @@ void sumOverSimulations(gmx::ArrayRef arrayRef, } if (commRecord->nnodes > 1) { - gmx_bcast(arrayRef.size()*sizeof(T), arrayRef.data(), commRecord); + gmx_bcast(arrayRef.size() * sizeof(T), arrayRef.data(), commRecord); } } @@ -148,17 +144,19 @@ void sumOverSimulations(gmx::ArrayRef arrayRef, * \param[in] commRecord Struct for intra-simulation communication. * \param[in] multiSimComm Struct for multi-simulation communication. */ -void sumPmf(gmx::ArrayRef pointState, - int numSharedUpdate, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm) +void sumPmf(gmx::ArrayRef pointState, + int numSharedUpdate, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm) { if (numSharedUpdate == 1) { return; } - GMX_ASSERT(multiSimComm != nullptr && numSharedUpdate % multiSimComm->nsim == 0, "numSharedUpdate should be a multiple of multiSimComm->nsim"); - GMX_ASSERT(numSharedUpdate == multiSimComm->nsim, "Sharing within a simulation is not implemented (yet)"); + GMX_ASSERT(multiSimComm != nullptr && numSharedUpdate % multiSimComm->nsim == 0, + "numSharedUpdate should be a multiple of multiSimComm->nsim"); + GMX_ASSERT(numSharedUpdate == multiSimComm->nsim, + "Sharing within a simulation is not implemented (yet)"); std::vector buffer(pointState.size()); @@ -171,12 +169,12 @@ void sumPmf(gmx::ArrayRef pointState, sumOverSimulations(gmx::ArrayRef(buffer), commRecord, multiSimComm); /* Take log again to get (non-normalized) PMF */ - double normFac = 1.0/numSharedUpdate; + double normFac = 1.0 / numSharedUpdate; for (gmx::index i = 0; i < pointState.ssize(); i++) { if (pointState[i].inTargetRegion()) { - pointState[i].setLogPmfSum(-std::log(buffer[i]*normFac)); + pointState[i].setLogPmfSum(-std::log(buffer[i] * normFac)); } } } @@ -191,7 +189,7 @@ double freeEnergyMinimumValue(gmx::ArrayRef pointState) { double fMin = GMX_FLOAT_MAX; - for (auto const &ps : pointState) + for (auto const& ps : pointState) { if (ps.inTargetRegion() && ps.freeEnergy() < fMin) { @@ -217,9 +215,9 @@ double freeEnergyMinimumValue(gmx::ArrayRef pointState) * \param[in] value Coordinate value. * \returns the log of the biased probability weight. */ -double biasedLogWeightFromPoint(const std::vector &dimParams, - const std::vector &points, - const Grid &grid, +double biasedLogWeightFromPoint(const std::vector& dimParams, + const std::vector& points, + const Grid& grid, int pointIndex, double pointBias, const awh_dvec value) @@ -235,18 +233,18 @@ double biasedLogWeightFromPoint(const std::vector &dimParams, for (size_t d = 0; d < dimParams.size(); d++) { double dev = getDeviationFromPointAlongGridAxis(grid, d, pointIndex, value[d]); - logWeight -= 0.5*dimParams[d].betak*dev*dev; + logWeight -= 0.5 * dimParams[d].betak * dev * dev; } } return logWeight; } -} // namespace +} // namespace -void BiasState::calcConvolvedPmf(const std::vector &dimParams, - const Grid &grid, - std::vector *convolvedPmf) const +void BiasState::calcConvolvedPmf(const std::vector& dimParams, + const Grid& grid, + std::vector* convolvedPmf) const { size_t numPoints = grid.numPoints(); @@ -259,8 +257,8 @@ void BiasState::calcConvolvedPmf(const std::vector &dimParams, for (size_t m = 0; m < numPoints; m++) { double freeEnergyWeights = 0; - const GridPoint &point = grid.point(m); - for (auto &neighbor : point.neighbor) + const GridPoint& point = grid.point(m); + for (auto& neighbor : point.neighbor) { /* The negative PMF is a positive bias. */ double biasNeighbor = -pmf[neighbor]; @@ -268,13 +266,13 @@ void BiasState::calcConvolvedPmf(const std::vector &dimParams, /* Add the convolved PMF weights for the neighbors of this point. Note that this function only adds point within the target > 0 region. Sum weights, take the logarithm last to get the free energy. */ - double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, - neighbor, biasNeighbor, - point.coordValue); + double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, neighbor, + biasNeighbor, point.coordValue); freeEnergyWeights += std::exp(logWeight); } - GMX_RELEASE_ASSERT(freeEnergyWeights > 0, "Attempting to do log(<= 0) in AWH convolved PMF calculation."); + GMX_RELEASE_ASSERT(freeEnergyWeights > 0, + "Attempting to do log(<= 0) in AWH convolved PMF calculation."); (*convolvedPmf)[m] = -std::log(static_cast(freeEnergyWeights)); } } @@ -291,8 +289,7 @@ namespace * \param[in,out] pointState The state of all points. * \param[in] params The bias parameters. */ -void updateTargetDistribution(gmx::ArrayRef pointState, - const BiasParams ¶ms) +void updateTargetDistribution(gmx::ArrayRef pointState, const BiasParams& params) { double freeEnergyCutoff = 0; if (params.eTarget == eawhtargetCUTOFF) @@ -301,15 +298,15 @@ void updateTargetDistribution(gmx::ArrayRef pointState, } double sumTarget = 0; - for (PointState &ps : pointState) + for (PointState& ps : pointState) { sumTarget += ps.updateTargetWeight(params, freeEnergyCutoff); } GMX_RELEASE_ASSERT(sumTarget > 0, "We should have a non-zero distribution"); /* Normalize to 1 */ - double invSum = 1.0/sumTarget; - for (PointState &ps : pointState) + double invSum = 1.0 / sumTarget; + for (PointState& ps : pointState) { ps.scaleTarget(invSum); } @@ -322,7 +319,7 @@ void updateTargetDistribution(gmx::ArrayRef pointState, * \param[in] point Grid point index. * \returns a string for the point. */ -std::string gridPointValueString(const Grid &grid, int point) +std::string gridPointValueString(const Grid& grid, int point) { std::string pointString; @@ -344,40 +341,36 @@ std::string gridPointValueString(const Grid &grid, int point) return pointString; } -} // namespace +} // namespace -int BiasState::warnForHistogramAnomalies(const Grid &grid, - int biasIndex, - double t, - FILE *fplog, - int maxNumWarnings) const +int BiasState::warnForHistogramAnomalies(const Grid& grid, int biasIndex, double t, FILE* fplog, int maxNumWarnings) const { GMX_ASSERT(fplog != nullptr, "Warnings can only be issued if there is log file."); - const double maxHistogramRatio = 0.5; /* Tolerance for printing a warning about the histogram ratios */ + const double maxHistogramRatio = 0.5; /* Tolerance for printing a warning about the histogram ratios */ /* Sum up the histograms and get their normalization */ double sumVisits = 0; double sumWeights = 0; - for (auto &pointState : points_) + for (auto& pointState : points_) { if (pointState.inTargetRegion()) { - sumVisits += pointState.numVisitsTot(); + sumVisits += pointState.numVisitsTot(); sumWeights += pointState.weightSumTot(); } } GMX_RELEASE_ASSERT(sumVisits > 0, "We should have visits"); GMX_RELEASE_ASSERT(sumWeights > 0, "We should have weight"); - double invNormVisits = 1.0/sumVisits; - double invNormWeight = 1.0/sumWeights; + double invNormVisits = 1.0 / sumVisits; + double invNormWeight = 1.0 / sumWeights; /* Check all points for warnings */ - int numWarnings = 0; - size_t numPoints = grid.numPoints(); + int numWarnings = 0; + size_t numPoints = grid.numPoints(); for (size_t m = 0; m < numPoints; m++) { /* Skip points close to boundary or non-target region */ - const GridPoint &gridPoint = grid.point(m); + const GridPoint& gridPoint = grid.point(m); bool skipPoint = false; for (size_t n = 0; (n < gridPoint.neighbor.size()) && !skipPoint; n++) { @@ -385,27 +378,26 @@ int BiasState::warnForHistogramAnomalies(const Grid &grid, skipPoint = !points_[neighbor].inTargetRegion(); for (int d = 0; (d < grid.numDimensions()) && !skipPoint; d++) { - const GridPoint &neighborPoint = grid.point(neighbor); - skipPoint = - neighborPoint.index[d] == 0 || - neighborPoint.index[d] == grid.axis(d).numPoints() - 1; + const GridPoint& neighborPoint = grid.point(neighbor); + skipPoint = neighborPoint.index[d] == 0 + || neighborPoint.index[d] == grid.axis(d).numPoints() - 1; } } /* Warn if the coordinate distribution is less than the target distribution with a certain fraction somewhere */ - const double relativeWeight = points_[m].weightSumTot()*invNormWeight; - const double relativeVisits = points_[m].numVisitsTot()*invNormVisits; - if (!skipPoint && - relativeVisits < relativeWeight*maxHistogramRatio) + const double relativeWeight = points_[m].weightSumTot() * invNormWeight; + const double relativeVisits = points_[m].numVisitsTot() * invNormVisits; + if (!skipPoint && relativeVisits < relativeWeight * maxHistogramRatio) { std::string pointValueString = gridPointValueString(grid, m); - std::string warningMessage = - gmx::formatString("\nawh%d warning: " - "at t = %g ps the obtained coordinate distribution at coordinate value %s " - "is less than a fraction %g of the reference distribution at that point. " - "If you are not certain about your settings you might want to increase your pull force constant or " - "modify your sampling region.\n", - biasIndex + 1, t, pointValueString.c_str(), maxHistogramRatio); + std::string warningMessage = gmx::formatString( + "\nawh%d warning: " + "at t = %g ps the obtained coordinate distribution at coordinate value %s " + "is less than a fraction %g of the reference distribution at that point. " + "If you are not certain about your settings you might want to increase your " + "pull force constant or " + "modify your sampling region.\n", + biasIndex + 1, t, pointValueString.c_str(), maxHistogramRatio); gmx::TextLineWrapper wrapper; wrapper.settings().setLineLength(c_linewidth); fprintf(fplog, "%s", wrapper.wrapToString(warningMessage).c_str()); @@ -421,28 +413,29 @@ int BiasState::warnForHistogramAnomalies(const Grid &grid, return numWarnings; } -double BiasState::calcUmbrellaForceAndPotential(const std::vector &dimParams, - const Grid &grid, +double BiasState::calcUmbrellaForceAndPotential(const std::vector& dimParams, + const Grid& grid, int point, gmx::ArrayRef force) const { double potential = 0; for (size_t d = 0; d < dimParams.size(); d++) { - double deviation = getDeviationFromPointAlongGridAxis(grid, d, point, coordState_.coordValue()[d]); + double deviation = + getDeviationFromPointAlongGridAxis(grid, d, point, coordState_.coordValue()[d]); - double k = dimParams[d].k; + double k = dimParams[d].k; /* Force from harmonic potential 0.5*k*dev^2 */ - force[d] = -k*deviation; - potential += 0.5*k*deviation*deviation; + force[d] = -k * deviation; + potential += 0.5 * k * deviation * deviation; } return potential; } -void BiasState::calcConvolvedForce(const std::vector &dimParams, - const Grid &grid, +void BiasState::calcConvolvedForce(const std::vector& dimParams, + const Grid& grid, gmx::ArrayRef probWeightNeighbor, gmx::ArrayRef forceWorkBuffer, gmx::ArrayRef force) const @@ -453,7 +446,7 @@ void BiasState::calcConvolvedForce(const std::vector &dimParams, } /* Only neighboring points have non-negligible contribution. */ - const std::vector &neighbor = grid.point(coordState_.gridpointIndex()).neighbor; + const std::vector& neighbor = grid.point(coordState_.gridpointIndex()).neighbor; gmx::ArrayRef forceFromNeighbor = forceWorkBuffer; for (size_t n = 0; n < neighbor.size(); n++) { @@ -461,19 +454,18 @@ void BiasState::calcConvolvedForce(const std::vector &dimParams, int indexNeighbor = neighbor[n]; /* Get the umbrella force from this point. The returned potential is ignored here. */ - calcUmbrellaForceAndPotential(dimParams, grid, indexNeighbor, - forceFromNeighbor); + calcUmbrellaForceAndPotential(dimParams, grid, indexNeighbor, forceFromNeighbor); /* Add the weighted umbrella force to the convolved force. */ for (size_t d = 0; d < dimParams.size(); d++) { - force[d] += forceFromNeighbor[d]*weightNeighbor; + force[d] += forceFromNeighbor[d] * weightNeighbor; } } } -double BiasState::moveUmbrella(const std::vector &dimParams, - const Grid &grid, +double BiasState::moveUmbrella(const std::vector& dimParams, + const Grid& grid, gmx::ArrayRef probWeightNeighbor, gmx::ArrayRef biasForce, int64_t step, @@ -481,11 +473,12 @@ double BiasState::moveUmbrella(const std::vector &dimParams, int indexSeed) { /* Generate and set a new coordinate reference value */ - coordState_.sampleUmbrellaGridpoint(grid, coordState_.gridpointIndex(), probWeightNeighbor, step, seed, indexSeed); + coordState_.sampleUmbrellaGridpoint(grid, coordState_.gridpointIndex(), probWeightNeighbor, + step, seed, indexSeed); std::vector newForce(dimParams.size()); double newPotential = - calcUmbrellaForceAndPotential(dimParams, grid, coordState_.umbrellaGridpoint(), newForce); + calcUmbrellaForceAndPotential(dimParams, grid, coordState_.umbrellaGridpoint(), newForce); /* A modification of the reference value at time t will lead to a different force over t-dt/2 to t and over t to t+dt/2. For high switching rates @@ -497,7 +490,7 @@ double BiasState::moveUmbrella(const std::vector &dimParams, for (gmx::index d = 0; d < biasForce.ssize(); d++) { /* Average of the current and new force */ - biasForce[d] = 0.5*(biasForce[d] + newForce[d]); + biasForce[d] = 0.5 * (biasForce[d] + newForce[d]); } return newPotential; @@ -526,11 +519,11 @@ namespace * \param[out] weightHistScaling Scaling factor for the reference weight histogram. * \param[out] logPmfSumScaling Log of the scaling factor for the PMF histogram. */ -void setHistogramUpdateScaleFactors(const BiasParams ¶ms, +void setHistogramUpdateScaleFactors(const BiasParams& params, double newHistogramSize, double oldHistogramSize, - double *weightHistScaling, - double *logPmfSumScaling) + double* weightHistScaling, + double* logPmfSumScaling) { /* The two scaling factors below are slightly different (ignoring the log factor) because the @@ -542,25 +535,27 @@ void setHistogramUpdateScaleFactors(const BiasParams ¶ms, 1) empirically this is necessary for converging the PMF; 2) since the extraction of the PMF is theoretically only valid for a constant bias, new samples should get more weight than old ones for which the bias is fluctuating more. */ - *weightHistScaling = newHistogramSize/(oldHistogramSize + params.updateWeight*params.localWeightScaling); - *logPmfSumScaling = std::log(newHistogramSize/(oldHistogramSize + params.updateWeight)); + *weightHistScaling = + newHistogramSize / (oldHistogramSize + params.updateWeight * params.localWeightScaling); + *logPmfSumScaling = std::log(newHistogramSize / (oldHistogramSize + params.updateWeight)); } -} // namespace +} // namespace -void BiasState::getSkippedUpdateHistogramScaleFactors(const BiasParams ¶ms, - double *weightHistScaling, - double *logPmfSumScaling) const +void BiasState::getSkippedUpdateHistogramScaleFactors(const BiasParams& params, + double* weightHistScaling, + double* logPmfSumScaling) const { - GMX_ASSERT(params.skipUpdates(), "Calling function for skipped updates when skipping updates is not allowed"); + GMX_ASSERT(params.skipUpdates(), + "Calling function for skipped updates when skipping updates is not allowed"); if (inInitialStage()) { - /* In between global updates the reference histogram size is kept constant so we trivially know what the - histogram size was at the time of the skipped update. */ + /* In between global updates the reference histogram size is kept constant so we trivially + know what the histogram size was at the time of the skipped update. */ double histogramSize = histogramSize_.histogramSize(); - setHistogramUpdateScaleFactors(params, histogramSize, histogramSize, - weightHistScaling, logPmfSumScaling); + setHistogramUpdateScaleFactors(params, histogramSize, histogramSize, weightHistScaling, + logPmfSumScaling); } else { @@ -570,16 +565,17 @@ void BiasState::getSkippedUpdateHistogramScaleFactors(const BiasParams ¶ms, } } -void BiasState::doSkippedUpdatesForAllPoints(const BiasParams ¶ms) +void BiasState::doSkippedUpdatesForAllPoints(const BiasParams& params) { double weightHistScaling; double logPmfsumScaling; getSkippedUpdateHistogramScaleFactors(params, &weightHistScaling, &logPmfsumScaling); - for (auto &pointState : points_) + for (auto& pointState : points_) { - bool didUpdate = pointState.performPreviouslySkippedUpdates(params, histogramSize_.numUpdates(), weightHistScaling, logPmfsumScaling); + bool didUpdate = pointState.performPreviouslySkippedUpdates( + params, histogramSize_.numUpdates(), weightHistScaling, logPmfsumScaling); /* Update the bias for this point only if there were skipped updates in the past to avoid calculating the log unneccessarily */ if (didUpdate) @@ -589,8 +585,7 @@ void BiasState::doSkippedUpdatesForAllPoints(const BiasParams ¶ms) } } -void BiasState::doSkippedUpdatesInNeighborhood(const BiasParams ¶ms, - const Grid &grid) +void BiasState::doSkippedUpdatesInNeighborhood(const BiasParams& params, const Grid& grid) { double weightHistScaling; double logPmfsumScaling; @@ -598,10 +593,11 @@ void BiasState::doSkippedUpdatesInNeighborhood(const BiasParams ¶ms, getSkippedUpdateHistogramScaleFactors(params, &weightHistScaling, &logPmfsumScaling); /* For each neighbor point of the center point, refresh its state by adding the results of all past, skipped updates. */ - const std::vector &neighbors = grid.point(coordState_.gridpointIndex()).neighbor; - for (auto &neighbor : neighbors) + const std::vector& neighbors = grid.point(coordState_.gridpointIndex()).neighbor; + for (auto& neighbor : neighbors) { - bool didUpdate = points_[neighbor].performPreviouslySkippedUpdates(params, histogramSize_.numUpdates(), weightHistScaling, logPmfsumScaling); + bool didUpdate = points_[neighbor].performPreviouslySkippedUpdates( + params, histogramSize_.numUpdates(), weightHistScaling, logPmfsumScaling); if (didUpdate) { @@ -621,17 +617,17 @@ namespace * \param[in] commRecord Struct for intra-simulation communication. * \param[in] multiSimComm Struct for multi-simulation communication. */ -void mergeSharedUpdateLists(std::vector *updateList, +void mergeSharedUpdateLists(std::vector* updateList, int numPoints, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm) + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm) { std::vector numUpdatesOfPoint; /* Flag the update points of this sim. TODO: we can probably avoid allocating this array and just use the input array. */ numUpdatesOfPoint.resize(numPoints, 0); - for (auto &pointIndex : *updateList) + for (auto& pointIndex : *updateList) { numUpdatesOfPoint[pointIndex] = 1; } @@ -655,15 +651,15 @@ void mergeSharedUpdateLists(std::vector *updateList, * * \param[in] grid The AWH bias. * \param[in] points The point state. - * \param[in] originUpdatelist The origin of the rectangular region that has been sampled since last update. - * \param[in] endUpdatelist The end of the rectangular that has been sampled since last update. - * \param[in,out] updateList Local update list to set (assumed >= npoints long). + * \param[in] originUpdatelist The origin of the rectangular region that has been sampled since + * last update. \param[in] endUpdatelist The end of the rectangular that has been sampled since + * last update. \param[in,out] updateList Local update list to set (assumed >= npoints long). */ -void makeLocalUpdateList(const Grid &grid, - const std::vector &points, +void makeLocalUpdateList(const Grid& grid, + const std::vector& points, const awh_ivec originUpdatelist, const awh_ivec endUpdatelist, - std::vector *updateList) + std::vector* updateList) { awh_ivec origin; awh_ivec numPoints; @@ -695,9 +691,9 @@ void makeLocalUpdateList(const Grid &grid, } } -} // namespace +} // namespace -void BiasState::resetLocalUpdateRange(const Grid &grid) +void BiasState::resetLocalUpdateRange(const Grid& grid) { const int gridpointIndex = coordState_.gridpointIndex(); for (int d = 0; d < grid.numDimensions(); d++) @@ -721,25 +717,25 @@ namespace * \param[in] multiSimComm Struct for multi-simulation communication. * \param[in] localUpdateList List of points with data. */ -void sumHistograms(gmx::ArrayRef pointState, - gmx::ArrayRef weightSumCovering, - int numSharedUpdate, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm, - const std::vector &localUpdateList) +void sumHistograms(gmx::ArrayRef pointState, + gmx::ArrayRef weightSumCovering, + int numSharedUpdate, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm, + const std::vector& localUpdateList) { - /* The covering checking histograms are added before summing over simulations, so that the weights from different - simulations are kept distinguishable. */ + /* The covering checking histograms are added before summing over simulations, so that the + weights from different simulations are kept distinguishable. */ for (int globalIndex : localUpdateList) { - weightSumCovering[globalIndex] += - pointState[globalIndex].weightSumIteration(); + weightSumCovering[globalIndex] += pointState[globalIndex].weightSumIteration(); } /* Sum histograms over multiple simulations if needed. */ if (numSharedUpdate > 1) { - GMX_ASSERT(numSharedUpdate == multiSimComm->nsim, "Sharing within a simulation is not implemented (yet)"); + GMX_ASSERT(numSharedUpdate == multiSimComm->nsim, + "Sharing within a simulation is not implemented (yet)"); /* Collect the weights and counts in linear arrays to be able to use gmx_sumd_sim. */ std::vector weightSum; @@ -750,7 +746,7 @@ void sumHistograms(gmx::ArrayRef pointState, for (size_t localIndex = 0; localIndex < localUpdateList.size(); localIndex++) { - const PointState &ps = pointState[localUpdateList[localIndex]]; + const PointState& ps = pointState[localUpdateList[localIndex]]; weightSum[localIndex] = ps.weightSumIteration(); coordVisits[localIndex] = ps.numVisitsIteration(); @@ -762,10 +758,9 @@ void sumHistograms(gmx::ArrayRef pointState, /* Transfer back the result */ for (size_t localIndex = 0; localIndex < localUpdateList.size(); localIndex++) { - PointState &ps = pointState[localUpdateList[localIndex]]; + PointState& ps = pointState[localUpdateList[localIndex]]; - ps.setPartialWeightAndCount(weightSum[localIndex], - coordVisits[localIndex]); + ps.setPartialWeightAndCount(weightSum[localIndex], coordVisits[localIndex]); } } @@ -788,10 +783,11 @@ void sumHistograms(gmx::ArrayRef pointState, * \param[in] numPoints The number of grid points along this dimension. * \param[in] period Period in number of points. * \param[in] coverRadius Cover radius, in points, needed for defining a point as covered. - * \param[in,out] covered In this array elements are 1 for covered points and 0 for non-covered points, this routine assumes that \p covered has at least size \p numPoints. + * \param[in,out] covered In this array elements are 1 for covered points and 0 for + * non-covered points, this routine assumes that \p covered has at least size \p numPoints. */ -void labelCoveredPoints(const std::vector &visited, - const std::vector &checkCovering, +void labelCoveredPoints(const std::vector& visited, + const std::vector& checkCovering, int numPoints, int period, int coverRadius, @@ -819,8 +815,8 @@ void labelCoveredPoints(const std::vector &visited, notVisitedHigh = n; /* Have now an interval I = [notVisitedLow,notVisitedHigh] of visited points bounded - by unvisited points. The unvisted end points affect the coveredness of the visited - with a reach equal to the cover radius. */ + by unvisited points. The unvisted end points affect the coveredness of the + visited with a reach equal to the cover radius. */ int notCoveredLow = notVisitedLow + coverRadius; int notCoveredHigh = notVisitedHigh - coverRadius; for (int i = notVisitedLow; i <= notVisitedHigh; i++) @@ -828,8 +824,8 @@ void labelCoveredPoints(const std::vector &visited, covered[i] = static_cast((i > notCoveredLow) && (i < notCoveredHigh)); } - /* Find a new interval to set covering for. Make the notVisitedHigh of this interval the - notVisitedLow of the next. */ + /* Find a new interval to set covering for. Make the notVisitedHigh of this interval + the notVisitedLow of the next. */ notVisitedLow = notVisitedHigh; } } @@ -857,7 +853,7 @@ void labelCoveredPoints(const std::vector &visited, int notVisitedHigh = firstNotVisited; int notVisitedLow = period > 0 ? (lastNotVisited - period) : -(coverRadius + 1); - int notCoveredLow = notVisitedLow + coverRadius; + int notCoveredLow = notVisitedLow + coverRadius; int notCoveredHigh = notVisitedHigh - coverRadius; for (int i = 0; i <= notVisitedHigh; i++) @@ -881,13 +877,13 @@ void labelCoveredPoints(const std::vector &visited, } } -} // namespace +} // namespace -bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, - const std::vector &dimParams, - const Grid &grid, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm) const +bool BiasState::isSamplingRegionCovered(const BiasParams& params, + const std::vector& dimParams, + const Grid& grid, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm) const { /* Allocate and initialize arrays: one for checking visits along each dimension, one for keeping track of which points to check and one for the covered points. @@ -897,7 +893,7 @@ bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, std::vector visited; std::vector checkCovering; // We use int for the covering array since we might use gmx_sumi_sim. - std::vector covered; + std::vector covered; }; std::vector checkDim; @@ -927,13 +923,13 @@ bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, double weightThreshold = 1; for (int d = 0; d < grid.numDimensions(); d++) { - weightThreshold *= grid.axis(d).spacing()*std::sqrt(dimParams[d].betak*0.5*M_1_PI); + weightThreshold *= grid.axis(d).spacing() * std::sqrt(dimParams[d].betak * 0.5 * M_1_PI); } /* Project the sampling weights onto each dimension */ for (size_t m = 0; m < grid.numPoints(); m++) { - const PointState &pointState = points_[m]; + const PointState& pointState = points_[m]; for (int d = 0; d < grid.numDimensions(); d++) { @@ -943,15 +939,17 @@ bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, checkDim[d].visited[n] = checkDim[d].visited[n] || (weightSumCovering_[m] > weightThreshold); /* Check for covering if there is at least point in this slice that is in the target region and within the cutoff */ - checkDim[d].checkCovering[n] = checkDim[d].checkCovering[n] || (pointState.inTargetRegion() && pointState.freeEnergy() < maxFreeEnergy); + checkDim[d].checkCovering[n] = + checkDim[d].checkCovering[n] + || (pointState.inTargetRegion() && pointState.freeEnergy() < maxFreeEnergy); } } /* Label each point along each dimension as covered or not. */ for (int d = 0; d < grid.numDimensions(); d++) { - labelCoveredPoints(checkDim[d].visited, checkDim[d].checkCovering, grid.axis(d).numPoints(), grid.axis(d).numPointsInPeriod(), - params.coverRadius()[d], checkDim[d].covered); + labelCoveredPoints(checkDim[d].visited, checkDim[d].checkCovering, grid.axis(d).numPoints(), + grid.axis(d).numPointsInPeriod(), params.coverRadius()[d], checkDim[d].covered); } /* Now check for global covering. Each dimension needs to be covered separately. @@ -973,7 +971,9 @@ bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, /* For multiple dimensions this may not be the best way to do it. */ for (int d = 0; d < grid.numDimensions(); d++) { - sumOverSimulations(gmx::arrayRefFromArray(checkDim[d].covered.data(), grid.axis(d).numPoints()), commRecord, multiSimComm); + sumOverSimulations( + gmx::arrayRefFromArray(checkDim[d].covered.data(), grid.axis(d).numPoints()), + commRecord, multiSimComm); } } @@ -995,25 +995,25 @@ bool BiasState::isSamplingRegionCovered(const BiasParams ¶ms, * * \param[in] pointState The state of the points. */ -static void normalizeFreeEnergyAndPmfSum(std::vector *pointState) +static void normalizeFreeEnergyAndPmfSum(std::vector* pointState) { double minF = freeEnergyMinimumValue(*pointState); - for (PointState &ps : *pointState) + for (PointState& ps : *pointState) { ps.normalizeFreeEnergyAndPmfSum(minF); } } -void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector &dimParams, - const Grid &grid, - const BiasParams ¶ms, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm, +void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector& dimParams, + const Grid& grid, + const BiasParams& params, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm, double t, int64_t step, - FILE *fplog, - std::vector *updateList) + FILE* fplog, + std::vector* updateList) { /* Note hat updateList is only used in this scope and is always * re-initialized. We do not use a local vector, because that would @@ -1025,8 +1025,7 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector 1) { mergeSharedUpdateLists(updateList, points_.size(), commRecord, multiSimComm); @@ -1036,21 +1035,20 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector 0.5*detail::c_largePositiveExponent) + for (int& globalIndex : *updateList) + { + /* We want to keep the absolute value of the free energies to be less + c_largePositiveExponent to be able to safely pass these values to exp(). The check below + ensures this as long as the free energy values grow less than 0.5*c_largePositiveExponent + in a return time to this neighborhood. For reasonable update sizes it's unlikely that + this requirement would be broken. */ + if (std::abs(points_[globalIndex].freeEnergy()) > 0.5 * detail::c_largePositiveExponent) { needToNormalizeFreeEnergy = true; break; @@ -1059,20 +1057,20 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vectorperformPreviouslySkippedUpdates(params, histogramSize_.numUpdates(), weightHistScalingSkipped, logPmfsumScalingSkipped); + pointStateToUpdate->performPreviouslySkippedUpdates(params, histogramSize_.numUpdates(), + weightHistScalingSkipped, + logPmfsumScalingSkipped); } /* Now do an update with new sampling data. */ - pointStateToUpdate->updateWithNewSampling(params, histogramSize_.numUpdates(), weightHistScalingNew, logPmfsumScalingNew); + pointStateToUpdate->updateWithNewSampling(params, histogramSize_.numUpdates(), + weightHistScalingNew, logPmfsumScalingNew); } /* Only update the histogram size after we are done with the local point updates */ @@ -1151,26 +1152,26 @@ void BiasState::updateFreeEnergyAndAddSamplesToHistogram(const std::vector &dimParams, - const Grid &grid, - std::vector < double, AlignedAllocator < double>> *weight) const +double BiasState::updateProbabilityWeightsAndConvolvedBias(const std::vector& dimParams, + const Grid& grid, + std::vector>* weight) const { /* Only neighbors of the current coordinate value will have a non-negligible chance of getting sampled */ - const std::vector &neighbors = grid.point(coordState_.gridpointIndex()).neighbor; + const std::vector& neighbors = grid.point(coordState_.gridpointIndex()).neighbor; #if GMX_SIMD_HAVE_DOUBLE typedef SimdDouble PackType; - constexpr int packSize = GMX_SIMD_DOUBLE_WIDTH; + constexpr int packSize = GMX_SIMD_DOUBLE_WIDTH; #else typedef double PackType; - constexpr int packSize = 1; + constexpr int packSize = 1; #endif /* Round the size of the weight array up to packSize */ - const int weightSize = ((neighbors.size() + packSize - 1)/packSize)*packSize; + const int weightSize = ((neighbors.size() + packSize - 1) / packSize) * packSize; weight->resize(weightSize); - double * gmx_restrict weightData = weight->data(); - PackType weightSumPack(0.0); + double* gmx_restrict weightData = weight->data(); + PackType weightSumPack(0.0); for (size_t i = 0; i < neighbors.size(); i += packSize) { for (size_t n = i; n < i + packSize; n++) @@ -1178,9 +1179,9 @@ double BiasState::updateProbabilityWeightsAndConvolvedBias(const std::vector 0, "zero probability weight when updating AWH probability weights."); + double weightSum = reduce(weightSumPack); + GMX_RELEASE_ASSERT(weightSum > 0, + "zero probability weight when updating AWH probability weights."); /* Normalize probabilities to sum to 1 */ - double invWeightSum = 1/weightSum; - for (double &w : *weight) + double invWeightSum = 1 / weightSum; + for (double& w : *weight) { w *= invWeightSum; } @@ -1208,31 +1210,29 @@ double BiasState::updateProbabilityWeightsAndConvolvedBias(const std::vector &dimParams, - const Grid &grid, - const awh_dvec &coordValue) const +double BiasState::calcConvolvedBias(const std::vector& dimParams, + const Grid& grid, + const awh_dvec& coordValue) const { - int point = grid.nearestIndex(coordValue); - const GridPoint &gridPoint = grid.point(point); + int point = grid.nearestIndex(coordValue); + const GridPoint& gridPoint = grid.point(point); /* Sum the probability weights from the neighborhood of the given point */ double weightSum = 0; for (int neighbor : gridPoint.neighbor) { - double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, - neighbor, points_[neighbor].bias(), - coordValue); - weightSum += std::exp(logWeight); + double logWeight = biasedLogWeightFromPoint(dimParams, points_, grid, neighbor, + points_[neighbor].bias(), coordValue); + weightSum += std::exp(logWeight); } /* Returns -GMX_FLOAT_MAX if no neighboring points were in the target region. */ return (weightSum > 0) ? std::log(weightSum) : -GMX_FLOAT_MAX; } -void BiasState::sampleProbabilityWeights(const Grid &grid, - gmx::ArrayRef probWeightNeighbor) +void BiasState::sampleProbabilityWeights(const Grid& grid, gmx::ArrayRef probWeightNeighbor) { - const std::vector &neighbor = grid.point(coordState_.gridpointIndex()).neighbor; + const std::vector& neighbor = grid.point(coordState_.gridpointIndex()).neighbor; /* Save weights for next update */ for (size_t n = 0; n < neighbor.size(); n++) @@ -1250,8 +1250,8 @@ void BiasState::sampleProbabilityWeights(const Grid &grid, int neighborLast = neighbor[neighbor.size() - 1]; for (int d = 0; d < grid.numDimensions(); d++) { - int origin = grid.point(neighborStart).index[d]; - int last = grid.point(neighborLast).index[d]; + int origin = grid.point(neighborStart).index[d]; + int last = grid.point(neighborLast).index[d]; if (origin > last) { @@ -1284,9 +1284,7 @@ void BiasState::sampleProbabilityWeights(const Grid &grid, } } -void BiasState::sampleCoordAndPmf(const Grid &grid, - gmx::ArrayRef probWeightNeighbor, - double convolvedBias) +void BiasState::sampleCoordAndPmf(const Grid& grid, gmx::ArrayRef probWeightNeighbor, double convolvedBias) { /* Sampling-based deconvolution extracting the PMF. * Update the PMF histogram with the current coordinate value. @@ -1314,22 +1312,22 @@ void BiasState::sampleCoordAndPmf(const Grid &grid, sampleProbabilityWeights(grid, probWeightNeighbor); } -void BiasState::initHistoryFromState(AwhBiasHistory *biasHistory) const +void BiasState::initHistoryFromState(AwhBiasHistory* biasHistory) const { biasHistory->pointState.resize(points_.size()); } -void BiasState::updateHistory(AwhBiasHistory *biasHistory, - const Grid &grid) const +void BiasState::updateHistory(AwhBiasHistory* biasHistory, const Grid& grid) const { - GMX_RELEASE_ASSERT(biasHistory->pointState.size() == points_.size(), "The AWH history setup does not match the AWH state."); + GMX_RELEASE_ASSERT(biasHistory->pointState.size() == points_.size(), + "The AWH history setup does not match the AWH state."); - AwhBiasStateHistory *stateHistory = &biasHistory->state; + AwhBiasStateHistory* stateHistory = &biasHistory->state; stateHistory->umbrellaGridpoint = coordState_.umbrellaGridpoint(); for (size_t m = 0; m < biasHistory->pointState.size(); m++) { - AwhPointStateHistory *psh = &biasHistory->pointState[m]; + AwhPointStateHistory* psh = &biasHistory->pointState[m]; points_[m].storeState(psh); @@ -1338,22 +1336,21 @@ void BiasState::updateHistory(AwhBiasHistory *biasHistory, histogramSize_.storeState(stateHistory); - stateHistory->origin_index_updatelist = multiDimGridIndexToLinear(grid, - originUpdatelist_); - stateHistory->end_index_updatelist = multiDimGridIndexToLinear(grid, - endUpdatelist_); + stateHistory->origin_index_updatelist = multiDimGridIndexToLinear(grid, originUpdatelist_); + stateHistory->end_index_updatelist = multiDimGridIndexToLinear(grid, endUpdatelist_); } -void BiasState::restoreFromHistory(const AwhBiasHistory &biasHistory, - const Grid &grid) +void BiasState::restoreFromHistory(const AwhBiasHistory& biasHistory, const Grid& grid) { - const AwhBiasStateHistory &stateHistory = biasHistory.state; + const AwhBiasStateHistory& stateHistory = biasHistory.state; coordState_.restoreFromHistory(stateHistory); if (biasHistory.pointState.size() != points_.size()) { - GMX_THROW(InvalidInputError("Bias grid size in checkpoint and simulation do not match. Likely you provided a checkpoint from a different simulation.")); + GMX_THROW( + InvalidInputError("Bias grid size in checkpoint and simulation do not match. " + "Likely you provided a checkpoint from a different simulation.")); } for (size_t m = 0; m < points_.size(); m++) { @@ -1371,19 +1368,18 @@ void BiasState::restoreFromHistory(const AwhBiasHistory &biasHistory, linearGridindexToMultiDim(grid, stateHistory.end_index_updatelist, endUpdatelist_); } -void BiasState::broadcast(const t_commrec *commRecord) +void BiasState::broadcast(const t_commrec* commRecord) { gmx_bcast(sizeof(coordState_), &coordState_, commRecord); - gmx_bcast(points_.size()*sizeof(PointState), points_.data(), commRecord); + gmx_bcast(points_.size() * sizeof(PointState), points_.data(), commRecord); - gmx_bcast(weightSumCovering_.size()*sizeof(double), weightSumCovering_.data(), commRecord); + gmx_bcast(weightSumCovering_.size() * sizeof(double), weightSumCovering_.data(), commRecord); gmx_bcast(sizeof(histogramSize_), &histogramSize_, commRecord); } -void BiasState::setFreeEnergyToConvolvedPmf(const std::vector &dimParams, - const Grid &grid) +void BiasState::setFreeEnergyToConvolvedPmf(const std::vector& dimParams, const Grid& grid) { std::vector convolvedPmf; @@ -1403,9 +1399,7 @@ void BiasState::setFreeEnergyToConvolvedPmf(const std::vector &dimPa * \param[in] numColumns Number of cols in array. * \returns the number of trailing zero rows. */ -static int countTrailingZeroRows(const double* const *data, - int numRows, - int numColumns) +static int countTrailingZeroRows(const double* const* data, int numRows, int numColumns) { int numZeroRows = 0; for (int m = numRows - 1; m >= 0; m--) @@ -1445,12 +1439,12 @@ static int countTrailingZeroRows(const double* const *data, * \param[in] biasIndex The index of the bias. * \param[in,out] pointState The state of the points in this bias. */ -static void readUserPmfAndTargetDistribution(const std::vector &dimParams, - const Grid &grid, - const std::string &filename, +static void readUserPmfAndTargetDistribution(const std::vector& dimParams, + const Grid& grid, + const std::string& filename, int numBias, int biasIndex, - std::vector *pointState) + std::vector* pointState) { /* Read the PMF and target distribution. From the PMF, the convolved PMF, or the reference value free energy, can be calculated @@ -1460,45 +1454,47 @@ static void readUserPmfAndTargetDistribution(const std::vector &dimPa if (numBias > 1) { size_t n = filenameModified.rfind('.'); - GMX_RELEASE_ASSERT(n != std::string::npos, "The filename should contain an extension starting with ."); + GMX_RELEASE_ASSERT(n != std::string::npos, + "The filename should contain an extension starting with ."); filenameModified.insert(n, formatString("%d", biasIndex)); } - std::string correctFormatMessage = - formatString("%s is expected in the following format. " - "The first ndim column(s) should contain the coordinate values for each point, " - "each column containing values of one dimension (in ascending order). " - "For a multidimensional coordinate, points should be listed " - "in the order obtained by traversing lower dimensions first. " - "E.g. for two-dimensional grid of size nxn: " - "(1, 1), (1, 2),..., (1, n), (2, 1), (2, 2), ..., , (n, n - 1), (n, n). " - "Column ndim + 1 should contain the PMF value for each coordinate value. " - "The target distribution values should be in column ndim + 2 or column ndim + 5. " - "Make sure the input file ends with a new line but has no trailing new lines.", - filename.c_str()); + std::string correctFormatMessage = formatString( + "%s is expected in the following format. " + "The first ndim column(s) should contain the coordinate values for each point, " + "each column containing values of one dimension (in ascending order). " + "For a multidimensional coordinate, points should be listed " + "in the order obtained by traversing lower dimensions first. " + "E.g. for two-dimensional grid of size nxn: " + "(1, 1), (1, 2),..., (1, n), (2, 1), (2, 2), ..., , (n, n - 1), (n, n). " + "Column ndim + 1 should contain the PMF value for each coordinate value. " + "The target distribution values should be in column ndim + 2 or column ndim + 5. " + "Make sure the input file ends with a new line but has no trailing new lines.", + filename.c_str()); gmx::TextLineWrapper wrapper; wrapper.settings().setLineLength(c_linewidth); correctFormatMessage = wrapper.wrapToString(correctFormatMessage); - double **data; - int numColumns; - int numRows = read_xvg(filenameModified.c_str(), &data, &numColumns); + double** data; + int numColumns; + int numRows = read_xvg(filenameModified.c_str(), &data, &numColumns); /* Check basic data properties here. Grid takes care of more complicated things. */ if (numRows <= 0) { - std::string mesg = gmx::formatString("%s is empty!.\n\n%s", filename.c_str(), correctFormatMessage.c_str()); + std::string mesg = gmx::formatString("%s is empty!.\n\n%s", filename.c_str(), + correctFormatMessage.c_str()); GMX_THROW(InvalidInputError(mesg)); } /* Less than 2 points is not useful for PMF or target. */ - if (numRows < 2) + if (numRows < 2) { - std::string mesg = - gmx::formatString("%s contains too few data points (%d)." - "The minimum number of points is 2.", - filename.c_str(), numRows); + std::string mesg = gmx::formatString( + "%s contains too few data points (%d)." + "The minimum number of points is 2.", + filename.c_str(), numRows); GMX_THROW(InvalidInputError(mesg)); } @@ -1523,10 +1519,10 @@ static void readUserPmfAndTargetDistribution(const std::vector &dimPa if (numColumns < numColumnsMin) { - std::string mesg = - gmx::formatString("The number of columns in %s should be at least %d." - "\n\n%s", - filename.c_str(), numColumnsMin, correctFormatMessage.c_str()); + std::string mesg = gmx::formatString( + "The number of columns in %s should be at least %d." + "\n\n%s", + filename.c_str(), numColumnsMin, correctFormatMessage.c_str()); GMX_THROW(InvalidInputError(mesg)); } @@ -1535,8 +1531,10 @@ static void readUserPmfAndTargetDistribution(const std::vector &dimPa int numZeroRows = countTrailingZeroRows(data, numRows, numColumns); if (numZeroRows > 1) { - std::string mesg = gmx::formatString("Found %d trailing zero data rows in %s. Please remove trailing empty lines and try again.", - numZeroRows, filename.c_str()); + std::string mesg = gmx::formatString( + "Found %d trailing zero data rows in %s. Please remove trailing empty lines and " + "try again.", + numZeroRows, filename.c_str()); GMX_THROW(InvalidInputError(mesg)); } @@ -1570,8 +1568,9 @@ static void readUserPmfAndTargetDistribution(const std::vector &dimPa /* Check if the values are allowed. */ if (target < 0) { - std::string mesg = gmx::formatString("Target distribution weight at point %zu (%g) in %s is negative.", - m, target, filename.c_str()); + std::string mesg = gmx::formatString( + "Target distribution weight at point %zu (%g) in %s is negative.", m, target, + filename.c_str()); GMX_THROW(InvalidInputError(mesg)); } if (target > 0) @@ -1583,8 +1582,9 @@ static void readUserPmfAndTargetDistribution(const std::vector &dimPa if (targetDistributionIsZero) { - std::string mesg = gmx::formatString("The target weights given in column %d in %s are all 0", - columnIndexTarget, filename.c_str()); + std::string mesg = + gmx::formatString("The target weights given in column %d in %s are all 0", + columnIndexTarget, filename.c_str()); GMX_THROW(InvalidInputError(mesg)); } @@ -1606,19 +1606,19 @@ void BiasState::normalizePmf(int numSharingSims) /* Calculate the normalization factor, i.e. divide by the pmf sum, multiply by the number of samples and the f sum */ double expSumPmf = 0; double expSumF = 0; - for (const PointState &pointState : points_) + for (const PointState& pointState : points_) { if (pointState.inTargetRegion()) { - expSumPmf += std::exp( pointState.logPmfSum()); - expSumF += std::exp(-pointState.freeEnergy()); + expSumPmf += std::exp(pointState.logPmfSum()); + expSumF += std::exp(-pointState.freeEnergy()); } } - double numSamples = histogramSize_.histogramSize()/numSharingSims; + double numSamples = histogramSize_.histogramSize() / numSharingSims; /* Renormalize */ - double logRenorm = std::log(numSamples*expSumF/expSumPmf); - for (PointState &pointState : points_) + double logRenorm = std::log(numSamples * expSumF / expSumPmf); + for (PointState& pointState : points_) { if (pointState.inTargetRegion()) { @@ -1627,12 +1627,12 @@ void BiasState::normalizePmf(int numSharingSims) } } -void BiasState::initGridPointState(const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - const Grid &grid, - const BiasParams ¶ms, - const std::string &filename, - int numBias) +void BiasState::initGridPointState(const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, + const Grid& grid, + const BiasParams& params, + const std::string& filename, + int numBias) { /* Modify PMF, free energy and the constant target distribution factor * to user input values if there is data given. @@ -1644,13 +1644,13 @@ void BiasState::initGridPointState(const AwhBiasParams &awhBiasParams, } /* The local Boltzmann distribution is special because the target distribution is updated as a function of the reference weighthistogram. */ - GMX_RELEASE_ASSERT(params.eTarget != eawhtargetLOCALBOLTZMANN || - points_[0].weightSumRef() != 0, - "AWH reference weight histogram not initialized properly with local Boltzmann target distribution."); + GMX_RELEASE_ASSERT(params.eTarget != eawhtargetLOCALBOLTZMANN || points_[0].weightSumRef() != 0, + "AWH reference weight histogram not initialized properly with local " + "Boltzmann target distribution."); updateTargetDistribution(points_, params); - for (PointState &pointState : points_) + for (PointState& pointState : points_) { if (pointState.inTargetRegion()) { @@ -1665,7 +1665,7 @@ void BiasState::initGridPointState(const AwhBiasParams &awhBiasParams, /* Set the initial reference weighthistogram. */ const double histogramSize = histogramSize_.histogramSize(); - for (auto &pointState : points_) + for (auto& pointState : points_) { pointState.setInitialReferenceWeightHistogram(histogramSize); } @@ -1675,10 +1675,10 @@ void BiasState::initGridPointState(const AwhBiasParams &awhBiasParams, normalizePmf(params.numSharedUpdate); } -BiasState::BiasState(const AwhBiasParams &awhBiasParams, +BiasState::BiasState(const AwhBiasParams& awhBiasParams, double histogramSizeInitial, - const std::vector &dimParams, - const Grid &grid) : + const std::vector& dimParams, + const Grid& grid) : coordState_(awhBiasParams, dimParams, grid), points_(grid.numPoints()), weightSumCovering_(grid.numPoints()), diff --git a/src/gromacs/awh/biasstate.h b/src/gromacs/awh/biasstate.h index ecd73e32d3..66b3373b15 100644 --- a/src/gromacs/awh/biasstate.h +++ b/src/gromacs/awh/biasstate.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -92,457 +92,427 @@ class PointState; */ class BiasState { - public: - /*! \brief Constructor. - * - * Constructs the global state and the point states on a provided - * geometric grid passed in \p grid. - * - * \param[in] awhBiasParams The Bias parameters from inputrec. - * \param[in] histogramSizeInitial The estimated initial histogram size. - * This is floating-point, since histograms use weighted - * entries and grow by a floating-point scaling factor. - * \param[in] dimParams The dimension parameters. - * \param[in] grid The bias grid. - */ - BiasState(const AwhBiasParams &awhBiasParams, - double histogramSizeInitial, - const std::vector &dimParams, - const Grid &grid); - - /*! \brief - * Restore the bias state from history. - * - * \param[in] biasHistory Bias history struct. - * \param[in] grid The bias grid. - */ - void restoreFromHistory(const AwhBiasHistory &biasHistory, - const Grid &grid); - - /*! \brief - * Broadcast the bias state over the MPI ranks in this simulation. - * - * \param[in] commRecord Struct for communication. - */ - void broadcast(const t_commrec *commRecord); - - /*! \brief - * Allocate and initialize a bias history with the given bias state. - * - * This function will be called at the start of a new simulation. - * Note that this only sets the correct size and does produce - * a valid history object, but with all data set to zero. - * Actual history data is set by \ref updateHistory. - * - * \param[in,out] biasHistory AWH history to initialize. - */ - void initHistoryFromState(AwhBiasHistory *biasHistory) const; - - /*! \brief - * Update the bias state history with the current state. - * - * \param[out] biasHistory Bias history struct. - * \param[in] grid The bias grid. - */ - void updateHistory(AwhBiasHistory *biasHistory, - const Grid &grid) const; - - private: - /*! \brief Convolves the given PMF using the given AWH bias. - * - * \note: The PMF is in single precision, because it is a statistical - * quantity and therefore never reaches full float precision. - * - * \param[in] dimParams The bias dimensions parameters - * \param[in] grid The grid. - * \param[in,out] convolvedPmf Array returned will be of the same length as the AWH grid to store the convolved PMF in. - */ - void calcConvolvedPmf(const std::vector &dimParams, - const Grid &grid, - std::vector *convolvedPmf) const; - - /*! \brief - * Convolves the PMF and sets the initial free energy to its convolution. - * - * \param[in] dimParams The bias dimensions parameters - * \param[in] grid The bias grid. - */ - void setFreeEnergyToConvolvedPmf(const std::vector &dimParams, - const Grid &grid); - - /*! \brief - * Normalize the PMF histogram. - * - * \param[in] numSharingSims The number of simulations sharing the bias. - */ - void normalizePmf(int numSharingSims); - - public: - /*! \brief - * Initialize the state of grid coordinate points. - * - * \param[in] awhBiasParams Bias parameters from inputrec. - * \param[in] dimParams The dimension parameters. - * \param[in] grid The grid. - * \param[in] params The bias parameters. - * \param[in] filename Name of file to read PMF and target from. - * \param[in] numBias The number of biases. - */ - void initGridPointState(const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - const Grid &grid, - const BiasParams ¶ms, - const std::string &filename, - int numBias); - - /*! \brief - * Performs statistical checks on the collected histograms and warns if issues are detected. - * - * \param[in] grid The grid. - * \param[in] biasIndex The index of the bias we are checking for. - * \param[in] t Time. - * \param[in,out] fplog Output file for warnings. - * \param[in] maxNumWarnings Don't issue more than this number of warnings. - * \returns the number of warnings issued. - */ - int warnForHistogramAnomalies(const Grid &grid, - int biasIndex, - double t, - FILE *fplog, - int maxNumWarnings) const; - - /*! \brief - * Calculates and sets the force the coordinate experiences from an umbrella centered at the given point. - * - * The umbrella potential is an harmonic potential given by 0.5k(coord value - point value)^2. This - * value is also returned. - * - * \param[in] dimParams The bias dimensions parameters. - * \param[in] grid The grid. - * \param[in] point Point for umbrella center. - * \param[in,out] force Force vector to set. - * Returns the umbrella potential. - */ - double calcUmbrellaForceAndPotential(const std::vector &dimParams, - const Grid &grid, - int point, - gmx::ArrayRef force) const; - - /*! \brief - * Calculates and sets the convolved force acting on the coordinate. - * - * The convolved force is the weighted sum of forces from umbrellas - * located at each point in the grid. - * - * \param[in] dimParams The bias dimensions parameters. - * \param[in] grid The grid. - * \param[in] probWeightNeighbor Probability weights of the neighbors. - * \param[in] forceWorkBuffer Force work buffer, values only used internally. - * \param[in,out] force Bias force vector to set. - */ - void calcConvolvedForce(const std::vector &dimParams, - const Grid &grid, - gmx::ArrayRef probWeightNeighbor, - gmx::ArrayRef forceWorkBuffer, - gmx::ArrayRef force) const; - - /*! \brief - * Move the center point of the umbrella potential. - * - * A new umbrella center is sampled from the biased distibution. Also, the bias - * force is updated and the new potential is return. - * - * This function should only be called when the bias force is not being convolved. - * It is assumed that the probability distribution has been updated. - * - * \param[in] dimParams Bias dimension parameters. - * \param[in] grid The grid. - * \param[in] probWeightNeighbor Probability weights of the neighbors. - * \param[in,out] biasForce The AWH bias force. - * \param[in] step Step number, needed for the random number generator. - * \param[in] seed Random seed. - * \param[in] indexSeed Second random seed, should be the bias Index. - * \returns the new potential value. - */ - double moveUmbrella(const std::vector &dimParams, - const Grid &grid, +public: + /*! \brief Constructor. + * + * Constructs the global state and the point states on a provided + * geometric grid passed in \p grid. + * + * \param[in] awhBiasParams The Bias parameters from inputrec. + * \param[in] histogramSizeInitial The estimated initial histogram size. + * This is floating-point, since histograms use weighted + * entries and grow by a floating-point scaling factor. + * \param[in] dimParams The dimension parameters. + * \param[in] grid The bias grid. + */ + BiasState(const AwhBiasParams& awhBiasParams, + double histogramSizeInitial, + const std::vector& dimParams, + const Grid& grid); + + /*! \brief + * Restore the bias state from history. + * + * \param[in] biasHistory Bias history struct. + * \param[in] grid The bias grid. + */ + void restoreFromHistory(const AwhBiasHistory& biasHistory, const Grid& grid); + + /*! \brief + * Broadcast the bias state over the MPI ranks in this simulation. + * + * \param[in] commRecord Struct for communication. + */ + void broadcast(const t_commrec* commRecord); + + /*! \brief + * Allocate and initialize a bias history with the given bias state. + * + * This function will be called at the start of a new simulation. + * Note that this only sets the correct size and does produce + * a valid history object, but with all data set to zero. + * Actual history data is set by \ref updateHistory. + * + * \param[in,out] biasHistory AWH history to initialize. + */ + void initHistoryFromState(AwhBiasHistory* biasHistory) const; + + /*! \brief + * Update the bias state history with the current state. + * + * \param[out] biasHistory Bias history struct. + * \param[in] grid The bias grid. + */ + void updateHistory(AwhBiasHistory* biasHistory, const Grid& grid) const; + +private: + /*! \brief Convolves the given PMF using the given AWH bias. + * + * \note: The PMF is in single precision, because it is a statistical + * quantity and therefore never reaches full float precision. + * + * \param[in] dimParams The bias dimensions parameters + * \param[in] grid The grid. + * \param[in,out] convolvedPmf Array returned will be of the same length as the AWH grid to store the convolved PMF in. + */ + void calcConvolvedPmf(const std::vector& dimParams, + const Grid& grid, + std::vector* convolvedPmf) const; + + /*! \brief + * Convolves the PMF and sets the initial free energy to its convolution. + * + * \param[in] dimParams The bias dimensions parameters + * \param[in] grid The bias grid. + */ + void setFreeEnergyToConvolvedPmf(const std::vector& dimParams, const Grid& grid); + + /*! \brief + * Normalize the PMF histogram. + * + * \param[in] numSharingSims The number of simulations sharing the bias. + */ + void normalizePmf(int numSharingSims); + +public: + /*! \brief + * Initialize the state of grid coordinate points. + * + * \param[in] awhBiasParams Bias parameters from inputrec. + * \param[in] dimParams The dimension parameters. + * \param[in] grid The grid. + * \param[in] params The bias parameters. + * \param[in] filename Name of file to read PMF and target from. + * \param[in] numBias The number of biases. + */ + void initGridPointState(const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, + const Grid& grid, + const BiasParams& params, + const std::string& filename, + int numBias); + + /*! \brief + * Performs statistical checks on the collected histograms and warns if issues are detected. + * + * \param[in] grid The grid. + * \param[in] biasIndex The index of the bias we are checking for. + * \param[in] t Time. + * \param[in,out] fplog Output file for warnings. + * \param[in] maxNumWarnings Don't issue more than this number of warnings. + * \returns the number of warnings issued. + */ + int warnForHistogramAnomalies(const Grid& grid, int biasIndex, double t, FILE* fplog, int maxNumWarnings) const; + + /*! \brief + * Calculates and sets the force the coordinate experiences from an umbrella centered at the given point. + * + * The umbrella potential is an harmonic potential given by 0.5k(coord value - point value)^2. This + * value is also returned. + * + * \param[in] dimParams The bias dimensions parameters. + * \param[in] grid The grid. + * \param[in] point Point for umbrella center. + * \param[in,out] force Force vector to set. + * Returns the umbrella potential. + */ + double calcUmbrellaForceAndPotential(const std::vector& dimParams, + const Grid& grid, + int point, + gmx::ArrayRef force) const; + + /*! \brief + * Calculates and sets the convolved force acting on the coordinate. + * + * The convolved force is the weighted sum of forces from umbrellas + * located at each point in the grid. + * + * \param[in] dimParams The bias dimensions parameters. + * \param[in] grid The grid. + * \param[in] probWeightNeighbor Probability weights of the neighbors. + * \param[in] forceWorkBuffer Force work buffer, values only used internally. + * \param[in,out] force Bias force vector to set. + */ + void calcConvolvedForce(const std::vector& dimParams, + const Grid& grid, gmx::ArrayRef probWeightNeighbor, - gmx::ArrayRef biasForce, - int64_t step, - int64_t seed, - int indexSeed); - - private: - /*! \brief - * Gets the histogram rescaling factors needed for skipped updates. - * - * \param[in] params The bias parameters. - * \param[out] weighthistScaling Scaling factor for the reference weight histogram. - * \param[out] logPmfsumScaling Log of the scaling factor for the PMF histogram. - */ - void getSkippedUpdateHistogramScaleFactors(const BiasParams ¶ms, - double *weighthistScaling, - double *logPmfsumScaling) const; - - public: - /*! \brief - * Do all previously skipped updates. - * Public for use by tests. - * - * \param[in] params The bias parameters. - */ - void doSkippedUpdatesForAllPoints(const BiasParams ¶ms); - - /*! \brief - * Do previously skipped updates in this neighborhood. - * - * \param[in] params The bias parameters. - * \param[in] grid The grid. - */ - void doSkippedUpdatesInNeighborhood(const BiasParams ¶ms, - const Grid &grid); - - private: - /*! \brief - * Reset the range used to make the local update list. - * - * \param[in] grid The grid. - */ - void resetLocalUpdateRange(const Grid &grid); - - /*! \brief - * Returns the new size of the reference weight histogram in the initial stage. - * - * This function also takes care resetting the histogram used for covering checks - * and for exiting the initial stage. - * - * \param[in] params The bias parameters. - * \param[in] t Time. - * \param[in] detectedCovering True if we detected that the sampling interval has been sufficiently covered. - * \param[in,out] fplog Log file. - * \returns the new histogram size. - */ - double newHistogramSizeInitialStage(const BiasParams ¶ms, - double t, - bool detectedCovering, - FILE *fplog); - - /*! \brief - * Check if the sampling region has been covered "enough" or not. - * - * A one-dimensional interval is defined as covered if each point has - * accumulated the same weight as is in the peak of a discretized normal - * distribution. For multiple dimensions, the weights are simply projected - * onto each dimension and the multidimensional space is covered if each - * dimension is. - * - * \note The covering criterion for multiple dimensions could improved, e.g. - * by using a path finding algorithm. - * - * \param[in] params The bias parameters. - * \param[in] dimParams Bias dimension parameters. - * \param[in] grid The grid. - * \param[in] commRecord Struct for intra-simulation communication. - * \param[in] multiSimComm Struct for multi-simulation communication. - * \returns true if covered. - */ - bool isSamplingRegionCovered(const BiasParams ¶ms, - const std::vector &dimParams, - const Grid &grid, - const t_commrec *commRecord, - const gmx_multisim_t *multiSimComm) const; - - /*! \brief - * Return the new reference weight histogram size for the current update. - * - * This function also takes care of checking for covering in the initial stage. - * - * \param[in] params The bias parameters. - * \param[in] t Time. - * \param[in] covered True if the sampling interval has been covered enough. - * \param[in,out] fplog Log file. - * \returns the new histogram size. - */ - double newHistogramSize(const BiasParams ¶ms, - double t, - bool covered, - FILE *fplog); - - public: - /*! \brief - * Update the reaction coordinate value. - * - * \param[in] grid The bias grid. - * \param[in] coordValue The current reaction coordinate value (there are no limits on allowed values). - */ - void setCoordValue(const Grid &grid, - const awh_dvec coordValue) - { - coordState_.setCoordValue(grid, coordValue); - } - - /*! \brief - * Performs an update of the bias. - * - * The objective of the update is to use collected samples (probability weights) - * to improve the free energy estimate. For sake of efficiency, the update is - * local whenever possible, meaning that only points that have actually been sampled - * are accessed and updated here. For certain AWH settings or at certain steps - * however, global need to be performed. Besides the actual free energy update, this - * function takes care of ensuring future convergence of the free energy. Convergence - * is obtained by increasing the size of the reference weight histogram in a controlled - * (sometimes dynamic) manner. Also, there are AWH variables that are direct functions - * of the free energy or sampling history that need to be updated here, namely the target - * distribution and the bias function. - * - * \param[in] dimParams The dimension parameters. - * \param[in] grid The grid. - * \param[in] params The bias parameters. - * \param[in] commRecord Struct for intra-simulation communication. - * \param[in] ms Struct for multi-simulation communication. - * \param[in] t Time. - * \param[in] step Time step. - * \param[in,out] fplog Log file. - * \param[in,out] updateList Work space to store a temporary list. - */ - void updateFreeEnergyAndAddSamplesToHistogram(const std::vector &dimParams, - const Grid &grid, - const BiasParams ¶ms, - const t_commrec *commRecord, - const gmx_multisim_t *ms, - double t, - int64_t step, - FILE *fplog, - std::vector *updateList); - - /*! \brief - * Update the probability weights and the convolved bias. - * - * Given a coordinate value, each grid point is assigned a probability - * weight, w(point|value), that depends on the current bias function. The sum - * of these weights is needed for normalizing the probability sum to 1 but - * also equals the effective, or convolved, biasing weight for this coordinate - * value. The convolved bias is needed e.g. for extracting the PMF, so we save - * it here since this saves us from doing extra exponential function evaluations - * later on. - * - * \param[in] dimParams The bias dimensions parameters - * \param[in] grid The grid. - * \param[out] weight Probability weights of the neighbors, SIMD aligned. - * \returns the convolved bias. - */ - - double updateProbabilityWeightsAndConvolvedBias(const std::vector &dimParams, - const Grid &grid, - std::vector < double, AlignedAllocator < double>> *weight) const; - - /*! \brief - * Take samples of the current probability weights for future updates and analysis. - * - * Points in the current neighborhood will now have data meaning they - * need to be included in the local update list of the next update. - * Therefore, the local update range is also update here. - * - * \param[in] grid The grid. - * \param[in] probWeightNeighbor Probability weights of the neighbors. - */ - void sampleProbabilityWeights(const Grid &grid, - gmx::ArrayRef probWeightNeighbor); - - /*! \brief - * Sample the reaction coordinate and PMF for future updates or analysis. - * - * These samples do not affect the (future) sampling and are thus - * pure observables. Statisics of these are stored in the energy file. - * - * \param[in] grid The grid. - * \param[in] probWeightNeighbor Probability weights of the neighbors. - * \param[in] convolvedBias The convolved bias. - */ - void sampleCoordAndPmf(const Grid &grid, - gmx::ArrayRef probWeightNeighbor, - double convolvedBias); - /*! \brief - * Calculates the convolved bias for a given coordinate value. - * - * The convolved bias is the effective bias acting on the coordinate. - * Since the bias here has arbitrary normalization, this only makes - * sense as a relative, to other coordinate values, measure of the bias. - * - * \note If it turns out to be costly to calculate this pointwise - * the convolved bias for the whole grid could be returned instead. - * - * \param[in] dimParams The bias dimensions parameters - * \param[in] grid The grid. - * \param[in] coordValue Coordinate value. - * \returns the convolved bias >= -GMX_FLOAT_MAX. - */ - double calcConvolvedBias(const std::vector &dimParams, - const Grid &grid, - const awh_dvec &coordValue) const; - - /*! \brief - * Fills the given array with PMF values. - * - * Points outside of the biasing target region will get PMF = GMX_FLOAT_MAX. - * \note: The PMF is in single precision, because it is a statistical - * quantity and therefore never reaches full float precision. - * - * \param[out] pmf Array(ref) to be filled with the PMF values, should have the same size as the bias grid. - */ - void getPmf(gmx::ArrayRef /*pmf*/) const; - - /*! \brief Returns the current coordinate state. - */ - const CoordState &coordState() const - { - return coordState_; - } - - /*! \brief Returns a const reference to the point state. - */ - const std::vector &points() const - { - return points_; - } - - /*! \brief Returns true if we are in the initial stage. - */ - bool inInitialStage() const - { - return histogramSize_.inInitialStage(); - } - - /*! \brief Returns the current histogram size. - */ - inline HistogramSize histogramSize() const - { - return histogramSize_; - } - - /* Data members */ - private: - CoordState coordState_; /**< The Current coordinate state */ - - /* The grid point state */ - std::vector points_; /**< Vector of state of the grid points */ - - /* Covering values for each point on the grid */ - std::vector weightSumCovering_; /**< Accumulated weights for covering checks */ - - HistogramSize histogramSize_; /**< Global histogram size related values. */ - - /* Track the part of the grid sampled since the last update. */ - awh_ivec originUpdatelist_; /**< The origin of the rectangular region that has been sampled since last update. */ - awh_ivec endUpdatelist_; /**< The end of the rectangular region that has been sampled since last update. */ + gmx::ArrayRef forceWorkBuffer, + gmx::ArrayRef force) const; + + /*! \brief + * Move the center point of the umbrella potential. + * + * A new umbrella center is sampled from the biased distibution. Also, the bias + * force is updated and the new potential is return. + * + * This function should only be called when the bias force is not being convolved. + * It is assumed that the probability distribution has been updated. + * + * \param[in] dimParams Bias dimension parameters. + * \param[in] grid The grid. + * \param[in] probWeightNeighbor Probability weights of the neighbors. + * \param[in,out] biasForce The AWH bias force. + * \param[in] step Step number, needed for the random number generator. + * \param[in] seed Random seed. + * \param[in] indexSeed Second random seed, should be the bias Index. + * \returns the new potential value. + */ + double moveUmbrella(const std::vector& dimParams, + const Grid& grid, + gmx::ArrayRef probWeightNeighbor, + gmx::ArrayRef biasForce, + int64_t step, + int64_t seed, + int indexSeed); + +private: + /*! \brief + * Gets the histogram rescaling factors needed for skipped updates. + * + * \param[in] params The bias parameters. + * \param[out] weighthistScaling Scaling factor for the reference weight histogram. + * \param[out] logPmfsumScaling Log of the scaling factor for the PMF histogram. + */ + void getSkippedUpdateHistogramScaleFactors(const BiasParams& params, + double* weighthistScaling, + double* logPmfsumScaling) const; + +public: + /*! \brief + * Do all previously skipped updates. + * Public for use by tests. + * + * \param[in] params The bias parameters. + */ + void doSkippedUpdatesForAllPoints(const BiasParams& params); + + /*! \brief + * Do previously skipped updates in this neighborhood. + * + * \param[in] params The bias parameters. + * \param[in] grid The grid. + */ + void doSkippedUpdatesInNeighborhood(const BiasParams& params, const Grid& grid); + +private: + /*! \brief + * Reset the range used to make the local update list. + * + * \param[in] grid The grid. + */ + void resetLocalUpdateRange(const Grid& grid); + + /*! \brief + * Returns the new size of the reference weight histogram in the initial stage. + * + * This function also takes care resetting the histogram used for covering checks + * and for exiting the initial stage. + * + * \param[in] params The bias parameters. + * \param[in] t Time. + * \param[in] detectedCovering True if we detected that the sampling interval has been sufficiently covered. + * \param[in,out] fplog Log file. + * \returns the new histogram size. + */ + double newHistogramSizeInitialStage(const BiasParams& params, double t, bool detectedCovering, FILE* fplog); + + /*! \brief + * Check if the sampling region has been covered "enough" or not. + * + * A one-dimensional interval is defined as covered if each point has + * accumulated the same weight as is in the peak of a discretized normal + * distribution. For multiple dimensions, the weights are simply projected + * onto each dimension and the multidimensional space is covered if each + * dimension is. + * + * \note The covering criterion for multiple dimensions could improved, e.g. + * by using a path finding algorithm. + * + * \param[in] params The bias parameters. + * \param[in] dimParams Bias dimension parameters. + * \param[in] grid The grid. + * \param[in] commRecord Struct for intra-simulation communication. + * \param[in] multiSimComm Struct for multi-simulation communication. + * \returns true if covered. + */ + bool isSamplingRegionCovered(const BiasParams& params, + const std::vector& dimParams, + const Grid& grid, + const t_commrec* commRecord, + const gmx_multisim_t* multiSimComm) const; + + /*! \brief + * Return the new reference weight histogram size for the current update. + * + * This function also takes care of checking for covering in the initial stage. + * + * \param[in] params The bias parameters. + * \param[in] t Time. + * \param[in] covered True if the sampling interval has been covered enough. + * \param[in,out] fplog Log file. + * \returns the new histogram size. + */ + double newHistogramSize(const BiasParams& params, double t, bool covered, FILE* fplog); + +public: + /*! \brief + * Update the reaction coordinate value. + * + * \param[in] grid The bias grid. + * \param[in] coordValue The current reaction coordinate value (there are no limits on allowed values). + */ + void setCoordValue(const Grid& grid, const awh_dvec coordValue) + { + coordState_.setCoordValue(grid, coordValue); + } + + /*! \brief + * Performs an update of the bias. + * + * The objective of the update is to use collected samples (probability weights) + * to improve the free energy estimate. For sake of efficiency, the update is + * local whenever possible, meaning that only points that have actually been sampled + * are accessed and updated here. For certain AWH settings or at certain steps + * however, global need to be performed. Besides the actual free energy update, this + * function takes care of ensuring future convergence of the free energy. Convergence + * is obtained by increasing the size of the reference weight histogram in a controlled + * (sometimes dynamic) manner. Also, there are AWH variables that are direct functions + * of the free energy or sampling history that need to be updated here, namely the target + * distribution and the bias function. + * + * \param[in] dimParams The dimension parameters. + * \param[in] grid The grid. + * \param[in] params The bias parameters. + * \param[in] commRecord Struct for intra-simulation communication. + * \param[in] ms Struct for multi-simulation communication. + * \param[in] t Time. + * \param[in] step Time step. + * \param[in,out] fplog Log file. + * \param[in,out] updateList Work space to store a temporary list. + */ + void updateFreeEnergyAndAddSamplesToHistogram(const std::vector& dimParams, + const Grid& grid, + const BiasParams& params, + const t_commrec* commRecord, + const gmx_multisim_t* ms, + double t, + int64_t step, + FILE* fplog, + std::vector* updateList); + + /*! \brief + * Update the probability weights and the convolved bias. + * + * Given a coordinate value, each grid point is assigned a probability + * weight, w(point|value), that depends on the current bias function. The sum + * of these weights is needed for normalizing the probability sum to 1 but + * also equals the effective, or convolved, biasing weight for this coordinate + * value. The convolved bias is needed e.g. for extracting the PMF, so we save + * it here since this saves us from doing extra exponential function evaluations + * later on. + * + * \param[in] dimParams The bias dimensions parameters + * \param[in] grid The grid. + * \param[out] weight Probability weights of the neighbors, SIMD aligned. + * \returns the convolved bias. + */ + + double updateProbabilityWeightsAndConvolvedBias(const std::vector& dimParams, + const Grid& grid, + std::vector>* weight) const; + + /*! \brief + * Take samples of the current probability weights for future updates and analysis. + * + * Points in the current neighborhood will now have data meaning they + * need to be included in the local update list of the next update. + * Therefore, the local update range is also update here. + * + * \param[in] grid The grid. + * \param[in] probWeightNeighbor Probability weights of the neighbors. + */ + void sampleProbabilityWeights(const Grid& grid, gmx::ArrayRef probWeightNeighbor); + + /*! \brief + * Sample the reaction coordinate and PMF for future updates or analysis. + * + * These samples do not affect the (future) sampling and are thus + * pure observables. Statisics of these are stored in the energy file. + * + * \param[in] grid The grid. + * \param[in] probWeightNeighbor Probability weights of the neighbors. + * \param[in] convolvedBias The convolved bias. + */ + void sampleCoordAndPmf(const Grid& grid, gmx::ArrayRef probWeightNeighbor, double convolvedBias); + /*! \brief + * Calculates the convolved bias for a given coordinate value. + * + * The convolved bias is the effective bias acting on the coordinate. + * Since the bias here has arbitrary normalization, this only makes + * sense as a relative, to other coordinate values, measure of the bias. + * + * \note If it turns out to be costly to calculate this pointwise + * the convolved bias for the whole grid could be returned instead. + * + * \param[in] dimParams The bias dimensions parameters + * \param[in] grid The grid. + * \param[in] coordValue Coordinate value. + * \returns the convolved bias >= -GMX_FLOAT_MAX. + */ + double calcConvolvedBias(const std::vector& dimParams, + const Grid& grid, + const awh_dvec& coordValue) const; + + /*! \brief + * Fills the given array with PMF values. + * + * Points outside of the biasing target region will get PMF = GMX_FLOAT_MAX. + * \note: The PMF is in single precision, because it is a statistical + * quantity and therefore never reaches full float precision. + * + * \param[out] pmf Array(ref) to be filled with the PMF values, should have the same size as the bias grid. + */ + void getPmf(gmx::ArrayRef /*pmf*/) const; + + /*! \brief Returns the current coordinate state. + */ + const CoordState& coordState() const { return coordState_; } + + /*! \brief Returns a const reference to the point state. + */ + const std::vector& points() const { return points_; } + + /*! \brief Returns true if we are in the initial stage. + */ + bool inInitialStage() const { return histogramSize_.inInitialStage(); } + + /*! \brief Returns the current histogram size. + */ + inline HistogramSize histogramSize() const { return histogramSize_; } + + /* Data members */ +private: + CoordState coordState_; /**< The Current coordinate state */ + + /* The grid point state */ + std::vector points_; /**< Vector of state of the grid points */ + + /* Covering values for each point on the grid */ + std::vector weightSumCovering_; /**< Accumulated weights for covering checks */ + + HistogramSize histogramSize_; /**< Global histogram size related values. */ + + /* Track the part of the grid sampled since the last update. */ + awh_ivec originUpdatelist_; /**< The origin of the rectangular region that has been sampled since last update. */ + awh_ivec endUpdatelist_; /**< The end of the rectangular region that has been sampled since last update. */ }; //! Linewidth used for warning output static const int c_linewidth = 80 - 2; //! Indent used for warning output -static const int c_indent = 0; +static const int c_indent = 0; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_BIASSTATE_H */ diff --git a/src/gromacs/awh/biaswriter.cpp b/src/gromacs/awh/biaswriter.cpp index 4dcea0f7b8..9230302eac 100644 --- a/src/gromacs/awh/biaswriter.cpp +++ b/src/gromacs/awh/biaswriter.cpp @@ -65,17 +65,16 @@ namespace * the iterator of this map, which is based on the enum value * (and matches the order of the lines below). */ -const std::map outputTypeToNormalization = -{ - { AwhOutputEntryType::MetaData, Normalization::None }, - { AwhOutputEntryType::CoordValue, Normalization::Coordinate }, - { AwhOutputEntryType::Pmf, Normalization::FreeEnergy }, - { AwhOutputEntryType::Bias, Normalization::FreeEnergy }, - { AwhOutputEntryType::Visits, Normalization::Distribution }, - { AwhOutputEntryType::Weights, Normalization::Distribution }, - { AwhOutputEntryType::Target, Normalization::Distribution }, +const std::map outputTypeToNormalization = { + { AwhOutputEntryType::MetaData, Normalization::None }, + { AwhOutputEntryType::CoordValue, Normalization::Coordinate }, + { AwhOutputEntryType::Pmf, Normalization::FreeEnergy }, + { AwhOutputEntryType::Bias, Normalization::FreeEnergy }, + { AwhOutputEntryType::Visits, Normalization::Distribution }, + { AwhOutputEntryType::Weights, Normalization::Distribution }, + { AwhOutputEntryType::Target, Normalization::Distribution }, { AwhOutputEntryType::ForceCorrelationVolume, Normalization::Distribution }, - { AwhOutputEntryType::FrictionTensor, Normalization::None } + { AwhOutputEntryType::FrictionTensor, Normalization::None } }; /*! \brief @@ -85,8 +84,7 @@ const std::map outputTypeToNormalization = * \param[in] dimIndex Dimensional index. * \returns the coordinate normalization value. */ -float getCoordNormalizationValue(const Bias &bias, - int dimIndex) +float getCoordNormalizationValue(const Bias& bias, int dimIndex) { /* AWH may use different units internally but here we convert to user units */ return bias.dimParams()[dimIndex].scaleInternalToUserInput(1); @@ -100,9 +98,7 @@ float getCoordNormalizationValue(const Bias &bias, * \param[in] numBlocks The number of blocks for this output type. * \returns the normalization value. */ -float getNormalizationValue(AwhOutputEntryType outputType, - const Bias &bias, - int numBlocks) +float getNormalizationValue(AwhOutputEntryType outputType, const Bias& bias, int numBlocks) { float normalizationValue = 0; @@ -119,25 +115,22 @@ float getNormalizationValue(AwhOutputEntryType outputType, case AwhOutputEntryType::ForceCorrelationVolume: normalizationValue = static_cast(bias.state().points().size()); break; - default: - break; + default: break; } return normalizationValue; } -} // namespace +} // namespace -AwhEnergyBlock::AwhEnergyBlock(int numPoints, - Normalization normalizationType, - float normalizationValue) : +AwhEnergyBlock::AwhEnergyBlock(int numPoints, Normalization normalizationType, float normalizationValue) : normalizationType(normalizationType), normalizationValue(normalizationValue), data_(numPoints) { } -BiasWriter::BiasWriter(const Bias &bias) +BiasWriter::BiasWriter(const Bias& bias) { std::map outputTypeNumBlock; /* Number of blocks per output type */ @@ -145,7 +138,7 @@ BiasWriter::BiasWriter(const Bias &bias) * We keep track of the starting block for each variable. */ int blockCount = 0; - for (const auto &pair : outputTypeToNormalization) + for (const auto& pair : outputTypeToNormalization) { const AwhOutputEntryType outputType = pair.first; { @@ -169,7 +162,7 @@ BiasWriter::BiasWriter(const Bias &bias) } /* Initialize the data blocks for each variable */ - for (const auto &pair : outputTypeToNormalization) + for (const auto& pair : outputTypeToNormalization) { const AwhOutputEntryType outputType = pair.first; int numPoints; @@ -183,9 +176,7 @@ BiasWriter::BiasWriter(const Bias &bias) } for (int b = 0; b < outputTypeNumBlock[outputType]; b++) { - block_.emplace_back(numPoints, - pair.second, - getNormalizationValue(outputType, bias, b)); + block_.emplace_back(numPoints, pair.second, getNormalizationValue(outputType, bias, b)); } } } @@ -196,7 +187,7 @@ BiasWriter::BiasWriter(const Bias &bias) * \param[in,out] block The block to normalize. * \param[in] bias The AWH bias. */ -static void normalizeBlock(AwhEnergyBlock *block, const Bias &bias) +static void normalizeBlock(AwhEnergyBlock* block, const Bias& bias) { gmx::ArrayRef data = block->data(); @@ -210,11 +201,10 @@ static void normalizeBlock(AwhEnergyBlock *block, const Bias &bias) switch (block->normalizationType) { - case Normalization::None: - break; + case Normalization::None: break; case Normalization::Coordinate: /* Normalize coordinate values by a scale factor */ - for (float &point : data) + for (float& point : data) { point *= block->normalizationValue; } @@ -239,31 +229,30 @@ static void normalizeBlock(AwhEnergyBlock *block, const Bias &bias) break; case Normalization::Distribution: /* Normalize distribution values by normalizing their sum */ - for (float &point : data) + for (float& point : data) { sum += point; } if (sum > 0) { - recipNorm = block->normalizationValue/static_cast(sum); + recipNorm = block->normalizationValue / static_cast(sum); } - for (float &point : data) + for (float& point : data) { point *= recipNorm; } break; - default: - GMX_RELEASE_ASSERT(false, "Unknown AWH normalization type"); - break; + default: GMX_RELEASE_ASSERT(false, "Unknown AWH normalization type"); break; } } -void BiasWriter::transferMetaDataToWriter(gmx::index metaDataIndex, - AwhOutputMetaData metaDataType, - const Bias &bias) +void BiasWriter::transferMetaDataToWriter(gmx::index metaDataIndex, + AwhOutputMetaData metaDataType, + const Bias& bias) { gmx::ArrayRef data = block_[getVarStartBlock(AwhOutputEntryType::MetaData)].data(); - GMX_ASSERT(metaDataIndex < data.ssize(), "Attempt to transfer AWH meta data to block for index out of range"); + GMX_ASSERT(metaDataIndex < data.ssize(), + "Attempt to transfer AWH meta data to block for index out of range"); /* Transfer the point data of this variable to the right block(s) */ switch (metaDataType) @@ -275,31 +264,32 @@ void BiasWriter::transferMetaDataToWriter(gmx::index metaDataIndex, break; case AwhOutputMetaData::TargetError: /* The theoretical target error */ - data[metaDataIndex] = bias.params().initialErrorInKT*std::sqrt(bias.params().initialHistogramSize/bias.state().histogramSize().histogramSize()); + data[metaDataIndex] = bias.params().initialErrorInKT + * std::sqrt(bias.params().initialHistogramSize + / bias.state().histogramSize().histogramSize()); break; case AwhOutputMetaData::ScaledSampleWeight: /* The logarithm of the sample weight relative to a sample weight of 1 at the initial time. In the normal case: this will increase in the initial stage and then stay at a constant value. */ data[metaDataIndex] = bias.state().histogramSize().logScaledSampleWeight(); break; - case AwhOutputMetaData::Count: - break; + case AwhOutputMetaData::Count: break; } } -void -BiasWriter::transferPointDataToWriter(AwhOutputEntryType outputType, - int pointIndex, - const Bias &bias, - gmx::ArrayRef pmf) +void BiasWriter::transferPointDataToWriter(AwhOutputEntryType outputType, + int pointIndex, + const Bias& bias, + gmx::ArrayRef pmf) { /* The starting block index of this output type. * Note that some variables need several (contiguous) blocks. */ int blockStart = getVarStartBlock(outputType); - GMX_ASSERT(pointIndex < static_cast(block_[blockStart].data().size()), "Attempt to transfer AWH data to block for point index out of range"); + GMX_ASSERT(pointIndex < static_cast(block_[blockStart].data().size()), + "Attempt to transfer AWH data to block for point index out of range"); - const CorrelationGrid &forceCorrelation = bias.forceCorrelationGrid(); + const CorrelationGrid& forceCorrelation = bias.forceCorrelationGrid(); int numCorrelation = forceCorrelation.tensorSize(); /* Transfer the point data of this variable to the right block(s) */ @@ -311,7 +301,7 @@ BiasWriter::transferPointDataToWriter(AwhOutputEntryType outputType, break; case AwhOutputEntryType::CoordValue: { - const awh_dvec &coordValue = bias.getGridCoordValue(pointIndex); + const awh_dvec& coordValue = bias.getGridCoordValue(pointIndex); for (int d = 0; d < bias.ndim(); d++) { block_[b].data()[pointIndex] = coordValue[d]; @@ -320,12 +310,15 @@ BiasWriter::transferPointDataToWriter(AwhOutputEntryType outputType, } break; case AwhOutputEntryType::Pmf: - block_[b].data()[pointIndex] = bias.state().points()[pointIndex].inTargetRegion() ? pmf[pointIndex] : 0; + block_[b].data()[pointIndex] = + bias.state().points()[pointIndex].inTargetRegion() ? pmf[pointIndex] : 0; break; case AwhOutputEntryType::Bias: { - const awh_dvec &coordValue = bias.getGridCoordValue(pointIndex); - block_[b].data()[pointIndex] = bias.state().points()[pointIndex].inTargetRegion() ? bias.calcConvolvedBias(coordValue) : 0; + const awh_dvec& coordValue = bias.getGridCoordValue(pointIndex); + block_[b].data()[pointIndex] = bias.state().points()[pointIndex].inTargetRegion() + ? bias.calcConvolvedBias(coordValue) + : 0; } break; case AwhOutputEntryType::Visits: @@ -338,23 +331,23 @@ BiasWriter::transferPointDataToWriter(AwhOutputEntryType outputType, block_[b].data()[pointIndex] = bias.state().points()[pointIndex].target(); break; case AwhOutputEntryType::ForceCorrelationVolume: - block_[b].data()[pointIndex] = forceCorrelation.tensors()[pointIndex].getVolumeElement(forceCorrelation.dtSample); + block_[b].data()[pointIndex] = + forceCorrelation.tensors()[pointIndex].getVolumeElement(forceCorrelation.dtSample); break; case AwhOutputEntryType::FrictionTensor: /* Store force correlation in units of friction, i.e. time/length^2 */ for (int n = 0; n < numCorrelation; n++) { - block_[b].data()[pointIndex] = forceCorrelation.tensors()[pointIndex].getTimeIntegral(n, forceCorrelation.dtSample); + block_[b].data()[pointIndex] = forceCorrelation.tensors()[pointIndex].getTimeIntegral( + n, forceCorrelation.dtSample); b++; } break; - default: - GMX_RELEASE_ASSERT(false, "Unknown AWH output variable"); - break; + default: GMX_RELEASE_ASSERT(false, "Unknown AWH output variable"); break; } } -void BiasWriter::prepareBiasOutput(const Bias &bias) +void BiasWriter::prepareBiasOutput(const Bias& bias) { /* Pack the AWH data into the writer data. */ @@ -370,7 +363,7 @@ void BiasWriter::prepareBiasOutput(const Bias &bias) { transferMetaDataToWriter(i, static_cast(i), bias); } - for (const auto &pair : outputTypeToNormalization) + for (const auto& pair : outputTypeToNormalization) { const AwhOutputEntryType outputType = pair.first; /* Skip metadata (transfered above) and unused blocks */ @@ -385,14 +378,13 @@ void BiasWriter::prepareBiasOutput(const Bias &bias) } /* For looks of the output, normalize it */ - for (AwhEnergyBlock &block : block_) + for (AwhEnergyBlock& block : block_) { normalizeBlock(&block, bias); } } -int BiasWriter::writeToEnergySubblocks(const Bias &bias, - t_enxsubblock *sub) +int BiasWriter::writeToEnergySubblocks(const Bias& bias, t_enxsubblock* sub) { prepareBiasOutput(bias); @@ -406,4 +398,4 @@ int BiasWriter::writeToEnergySubblocks(const Bias &bias, return block_.size(); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/awh/biaswriter.h b/src/gromacs/awh/biaswriter.h index 5df829466e..14625b54dc 100644 --- a/src/gromacs/awh/biaswriter.h +++ b/src/gromacs/awh/biaswriter.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -83,131 +83,121 @@ enum class AwhOutputEntryType //! Enum with the types of metadata to write. enum class AwhOutputMetaData { - NumBlock, //!< The number of blocks. - TargetError, //!< The target error. + NumBlock, //!< The number of blocks. + TargetError, //!< The target error. ScaledSampleWeight, //!< The logarithm of the sample weight relative to a sample weight of 1 at the initial time. - Count //!< The number of enum values, not including Count. + Count //!< The number of enum values, not including Count. }; //! Enum with different ways of normalizing the output. enum class Normalization { - None, //!< No normalization. - Coordinate, //!< Scale using the internal/user input coordinate scaling factor. - FreeEnergy, //!< Normalize free energy values by subtracting the minimum value. - Distribution //!< Normalize the distribution to 1. + None, //!< No normalization. + Coordinate, //!< Scale using the internal/user input coordinate scaling factor. + FreeEnergy, //!< Normalize free energy values by subtracting the minimum value. + Distribution //!< Normalize the distribution to 1. }; /*! \internal \brief AWH output data block that can be written to an energy file block. */ class AwhEnergyBlock { - public: - /*! \brief Constructor - * - * \param[in] numPoints Number of points in block. - * \param[in] normalizationType Type of normalization. - * \param[in] normalizationValue Value to normalization with. - */ - AwhEnergyBlock(int numPoints, - Normalization normalizationType, - float normalizationValue); - - /*! \brief Returns an ArrarRef to the data in the block. - */ - gmx::ArrayRef data() - { - return data_; - } - - const Normalization normalizationType; /**< How to normalize the output data */ - const float normalizationValue; /**< The normalization value */ - private: - std::vector data_; /**< The data, always float which is enough since this is statistical data */ +public: + /*! \brief Constructor + * + * \param[in] numPoints Number of points in block. + * \param[in] normalizationType Type of normalization. + * \param[in] normalizationValue Value to normalization with. + */ + AwhEnergyBlock(int numPoints, Normalization normalizationType, float normalizationValue); + + /*! \brief Returns an ArrarRef to the data in the block. + */ + gmx::ArrayRef data() { return data_; } + + const Normalization normalizationType; /**< How to normalize the output data */ + const float normalizationValue; /**< The normalization value */ +private: + std::vector data_; /**< The data, always float which is enough since this is statistical data */ }; /*! \internal \brief Class organizing the output data storing and writing of an AWH bias. */ class BiasWriter { - public: - /*! \brief Constructor. - * - * \param[in] bias The AWH bias. - */ - BiasWriter(const Bias &bias); - - /*! \brief Returns the number of data blocks. - * - * \returns the number of data blocks. - */ - int numBlocks() const - { - return block_.size(); - } - - /*! \brief Collect AWH bias data in blocks and write to energy subblocks. - * - * \param[in] bias The AWH Bias. - * \param[in,out] subblock Energy subblocks to write to. - * \returns the number of blocks written. - */ - int writeToEnergySubblocks(const Bias &bias, t_enxsubblock *subblock); - - private: - /*! \brief Query if the writer has a block for the given variable. - * - * \param[in] outputType Output entry type. - */ - bool hasVarBlock(AwhOutputEntryType outputType) const - { - return outputTypeToBlock_.find(outputType)->second >= 0; - } - - /*! \brief* Find the first block containing the given variable. - * - * \param[in] outputType Output entry type. - * \returns the first block index for the variable, or -1 there is no block. - */ - int getVarStartBlock(AwhOutputEntryType outputType) const - { - return outputTypeToBlock_.find(outputType)->second; - } - - /*! \brief Transfer AWH point data to writer data blocks. - * - * \param[in] metaDataIndex Meta data block index. - * \param[in] metaDataType The type of meta data to write. - * \param[in] bias The AWH Bias. - */ - void transferMetaDataToWriter(gmx::index metaDataIndex, - AwhOutputMetaData metaDataType, - const Bias &bias); - - /*! \brief Transfer AWH point data to writer data blocks. - * - * \param[in] outputType Output entry type. - * \param[in] pointIndex The point index. - * \param[in] bias The AWH Bias. - * \param[in] pmf PMF values. - */ - void transferPointDataToWriter(AwhOutputEntryType outputType, - int pointIndex, - const Bias &bias, - gmx::ArrayRef pmf); - - /*! \brief - * Prepare the bias output data. - * - * \param[in] bias The AWH Bias. - */ - void prepareBiasOutput(const Bias &bias); - - private: - std::vector block_; /**< The data blocks */ - std::map outputTypeToBlock_; /**< Start block index for each variable, -1 when variable should not be written */ +public: + /*! \brief Constructor. + * + * \param[in] bias The AWH bias. + */ + BiasWriter(const Bias& bias); + + /*! \brief Returns the number of data blocks. + * + * \returns the number of data blocks. + */ + int numBlocks() const { return block_.size(); } + + /*! \brief Collect AWH bias data in blocks and write to energy subblocks. + * + * \param[in] bias The AWH Bias. + * \param[in,out] subblock Energy subblocks to write to. + * \returns the number of blocks written. + */ + int writeToEnergySubblocks(const Bias& bias, t_enxsubblock* subblock); + +private: + /*! \brief Query if the writer has a block for the given variable. + * + * \param[in] outputType Output entry type. + */ + bool hasVarBlock(AwhOutputEntryType outputType) const + { + return outputTypeToBlock_.find(outputType)->second >= 0; + } + + /*! \brief* Find the first block containing the given variable. + * + * \param[in] outputType Output entry type. + * \returns the first block index for the variable, or -1 there is no block. + */ + int getVarStartBlock(AwhOutputEntryType outputType) const + { + return outputTypeToBlock_.find(outputType)->second; + } + + /*! \brief Transfer AWH point data to writer data blocks. + * + * \param[in] metaDataIndex Meta data block index. + * \param[in] metaDataType The type of meta data to write. + * \param[in] bias The AWH Bias. + */ + void transferMetaDataToWriter(gmx::index metaDataIndex, AwhOutputMetaData metaDataType, const Bias& bias); + + /*! \brief Transfer AWH point data to writer data blocks. + * + * \param[in] outputType Output entry type. + * \param[in] pointIndex The point index. + * \param[in] bias The AWH Bias. + * \param[in] pmf PMF values. + */ + void transferPointDataToWriter(AwhOutputEntryType outputType, + int pointIndex, + const Bias& bias, + gmx::ArrayRef pmf); + + /*! \brief + * Prepare the bias output data. + * + * \param[in] bias The AWH Bias. + */ + void prepareBiasOutput(const Bias& bias); + +private: + std::vector block_; /**< The data blocks */ + std::map outputTypeToBlock_; /**< Start block index for each variable, -1 when variable should not be written */ }; -} // namespace gmx +} // namespace gmx -#endif /* GMX_AWH_BIASWRITER_H */ +#endif /* GMX_AWH_BIASWRITER_H */ diff --git a/src/gromacs/awh/coordstate.cpp b/src/gromacs/awh/coordstate.cpp index 29ebe7d7c3..bd07a19044 100644 --- a/src/gromacs/awh/coordstate.cpp +++ b/src/gromacs/awh/coordstate.cpp @@ -63,9 +63,9 @@ namespace gmx { -CoordState::CoordState(const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - const Grid &grid) +CoordState::CoordState(const AwhBiasParams& awhBiasParams, + const std::vector& dimParams, + const Grid& grid) { for (size_t d = 0; d < dimParams.size(); d++) { @@ -94,10 +94,7 @@ namespace * \param[in] indexSeed1 Random seed needed by the random number generator. * \returns a sample index in [0, distr.size() - 1] */ -int getSampleFromDistribution(ArrayRef distr, - int64_t seed, - int64_t indexSeed0, - int64_t indexSeed1) +int getSampleFromDistribution(ArrayRef distr, int64_t seed, int64_t indexSeed0, int64_t indexSeed1) { gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::AwhBiasing); gmx::UniformRealDistribution uniformRealDistr; @@ -114,42 +111,41 @@ int getSampleFromDistribution(ArrayRef distr, cumulativeDistribution[i] = cumulativeDistribution[i - 1] + distr[i]; } - GMX_RELEASE_ASSERT(gmx_within_tol(cumulativeDistribution.back(), 1.0, 0.01), "Attempt to get sample from non-normalized/zero distribution"); + GMX_RELEASE_ASSERT(gmx_within_tol(cumulativeDistribution.back(), 1.0, 0.01), + "Attempt to get sample from non-normalized/zero distribution"); /* Use binary search to convert the real value to an integer in [0, ndistr - 1] distributed according to distr. */ rng.restart(indexSeed0, indexSeed1); - double value = uniformRealDistr(rng); - int sample = std::upper_bound(cumulativeDistribution.begin(), cumulativeDistribution.end() - 1, value) - cumulativeDistribution.begin(); + double value = uniformRealDistr(rng); + int sample = std::upper_bound(cumulativeDistribution.begin(), cumulativeDistribution.end() - 1, value) + - cumulativeDistribution.begin(); return sample; } -} // namespace +} // namespace -void -CoordState::sampleUmbrellaGridpoint(const Grid &grid, - int gridpointIndex, - gmx::ArrayRef probWeightNeighbor, - int64_t step, - int64_t seed, - int indexSeed) +void CoordState::sampleUmbrellaGridpoint(const Grid& grid, + int gridpointIndex, + gmx::ArrayRef probWeightNeighbor, + int64_t step, + int64_t seed, + int indexSeed) { /* Sample new umbrella reference value from the probability distribution * which is defined for the neighboring points of the current coordinate. */ - const std::vector &neighbor = grid.point(gridpointIndex).neighbor; + const std::vector& neighbor = grid.point(gridpointIndex).neighbor; /* In order to use the same seed for all AWH biases and get independent samples we use the index of the bias. */ - int localIndex = getSampleFromDistribution(probWeightNeighbor, - seed, step, indexSeed); + int localIndex = getSampleFromDistribution(probWeightNeighbor, seed, step, indexSeed); umbrellaGridpoint_ = neighbor[localIndex]; } -void CoordState::setCoordValue(const Grid &grid, - const awh_dvec coordValue) +void CoordState::setCoordValue(const Grid& grid, const awh_dvec coordValue) { /* We need to check for valid (probable) coordinate values, to give * a clear error message instead of a low-level assertion failure. @@ -163,22 +159,22 @@ void CoordState::setCoordValue(const Grid &grid, for (int dim = 0; dim < grid.numDimensions(); dim++) { - const GridAxis &axis = grid.axis(dim); + const GridAxis& axis = grid.axis(dim); /* We do not check periodic coordinates, since that is more complicated * and those cases are less likely to cause problems. */ if (!axis.isPeriodic()) { - const double margin = axis.spacing()*c_marginInSigma/Grid::c_numPointsPerSigma; - if (coordValue[dim] < axis.origin() - margin || - coordValue[dim] > axis.origin() + axis.length() + margin) + const double margin = axis.spacing() * c_marginInSigma / Grid::c_numPointsPerSigma; + if (coordValue[dim] < axis.origin() - margin + || coordValue[dim] > axis.origin() + axis.length() + margin) { - std::string mesg = gmx::formatString("Coordinate %d of an AWH bias has a value %f which is more than %d sigma out of the AWH range of [%f, %f]. You seem to have an unstable reaction coordinate setup or an unequilibrated system.", - dim + 1, - coordValue[dim], - c_marginInSigma, - axis.origin(), - axis.origin() + axis.length()); + std::string mesg = gmx::formatString( + "Coordinate %d of an AWH bias has a value %f which is more than %d sigma " + "out of the AWH range of [%f, %f]. You seem to have an unstable reaction " + "coordinate setup or an unequilibrated system.", + dim + 1, coordValue[dim], c_marginInSigma, axis.origin(), + axis.origin() + axis.length()); GMX_THROW(SimulationInstabilityError(mesg)); } } @@ -193,8 +189,7 @@ void CoordState::setCoordValue(const Grid &grid, gridpointIndex_ = grid.nearestIndex(coordValue_); } -void -CoordState::restoreFromHistory(const AwhBiasStateHistory &stateHistory) +void CoordState::restoreFromHistory(const AwhBiasStateHistory& stateHistory) { umbrellaGridpoint_ = stateHistory.umbrellaGridpoint; } diff --git a/src/gromacs/awh/coordstate.h b/src/gromacs/awh/coordstate.h index 3dfec0898c..05e88c54d5 100644 --- a/src/gromacs/awh/coordstate.h +++ b/src/gromacs/awh/coordstate.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,78 +70,66 @@ class Grid; */ class CoordState { - public: - /*! \brief Constructor. - * - * \param[in] awhBiasParams The Bias parameters from inputrec. - * \param[in] dimParams The dimension Parameters. - * \param[in] grid The grid. - */ - CoordState(const AwhBiasParams &awhBiasParams, - const std::vector &dimParams, - const Grid &grid); - - /*! \brief - * Sample a new umbrella reference point given the current coordinate value. - * - * It is assumed that the probability distribution has been updated. - * - * \param[in] grid The grid. - * \param[in] gridpointIndex The grid point, sets the neighborhood. - * \param[in] probWeightNeighbor Probability weights of the neighbors. - * \param[in] step Step number, needed for the random number generator. - * \param[in] seed Random seed. - * \param[in] indexSeed Second random seed, should be the bias Index. - * \returns the index of the sampled point. - */ - void sampleUmbrellaGridpoint(const Grid &grid, - int gridpointIndex, - gmx::ArrayRef probWeightNeighbor, - int64_t step, - int64_t seed, - int indexSeed); - - /*! \brief Update the coordinate value with coordValue. - * - * \param[in] grid The grid. - * \param[in] coordValue The new coordinate value. - */ - void setCoordValue(const Grid &grid, - const awh_dvec coordValue); - - /*! \brief Restores the coordinate state from history. - * - * \param[in] stateHistory The AWH bias state history. - */ - void restoreFromHistory(const AwhBiasStateHistory &stateHistory); - - /*! \brief Returns the current coordinate value. - */ - const awh_dvec &coordValue() const - { - return coordValue_; - } - - /*! \brief Returns the grid point index for the current coordinate value. - */ - int gridpointIndex() const - { - return gridpointIndex_; - } - - /*! \brief Returns the index for the current reference grid point. - */ - int umbrellaGridpoint() const - { - return umbrellaGridpoint_; - } - - private: - awh_dvec coordValue_; /**< Current coordinate value in (nm or rad) */ - int gridpointIndex_; /**< The grid point index for the current coordinate value */ - int umbrellaGridpoint_; /**< Index for the current reference grid point for the umbrella, only used with umbrella potential type */ +public: + /*! \brief Constructor. + * + * \param[in] awhBiasParams The Bias parameters from inputrec. + * \param[in] dimParams The dimension Parameters. + * \param[in] grid The grid. + */ + CoordState(const AwhBiasParams& awhBiasParams, const std::vector& dimParams, const Grid& grid); + + /*! \brief + * Sample a new umbrella reference point given the current coordinate value. + * + * It is assumed that the probability distribution has been updated. + * + * \param[in] grid The grid. + * \param[in] gridpointIndex The grid point, sets the neighborhood. + * \param[in] probWeightNeighbor Probability weights of the neighbors. + * \param[in] step Step number, needed for the random number generator. + * \param[in] seed Random seed. + * \param[in] indexSeed Second random seed, should be the bias Index. + * \returns the index of the sampled point. + */ + void sampleUmbrellaGridpoint(const Grid& grid, + int gridpointIndex, + gmx::ArrayRef probWeightNeighbor, + int64_t step, + int64_t seed, + int indexSeed); + + /*! \brief Update the coordinate value with coordValue. + * + * \param[in] grid The grid. + * \param[in] coordValue The new coordinate value. + */ + void setCoordValue(const Grid& grid, const awh_dvec coordValue); + + /*! \brief Restores the coordinate state from history. + * + * \param[in] stateHistory The AWH bias state history. + */ + void restoreFromHistory(const AwhBiasStateHistory& stateHistory); + + /*! \brief Returns the current coordinate value. + */ + const awh_dvec& coordValue() const { return coordValue_; } + + /*! \brief Returns the grid point index for the current coordinate value. + */ + int gridpointIndex() const { return gridpointIndex_; } + + /*! \brief Returns the index for the current reference grid point. + */ + int umbrellaGridpoint() const { return umbrellaGridpoint_; } + +private: + awh_dvec coordValue_; /**< Current coordinate value in (nm or rad) */ + int gridpointIndex_; /**< The grid point index for the current coordinate value */ + int umbrellaGridpoint_; /**< Index for the current reference grid point for the umbrella, only used with umbrella potential type */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_COORDSTATE_H */ diff --git a/src/gromacs/awh/correlationgrid.cpp b/src/gromacs/awh/correlationgrid.cpp index 597ee9224d..ac1b48edb4 100644 --- a/src/gromacs/awh/correlationgrid.cpp +++ b/src/gromacs/awh/correlationgrid.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,12 +72,13 @@ int getBlockDataListSize(int numBlocks) blockDataListSize++; } - GMX_RELEASE_ASSERT((1 << (blockDataListSize - 1)) == numBlocks, "numBlocks should be a power of 2"); + GMX_RELEASE_ASSERT((1 << (blockDataListSize - 1)) == numBlocks, + "numBlocks should be a power of 2"); return blockDataListSize; } -} // namespace +} // namespace CorrelationGrid::CorrelationGrid(int numPoints, int numDim, @@ -109,14 +110,14 @@ CorrelationGrid::CorrelationGrid(int numPoints, int CorrelationGrid::getNumBlocks() const { - const auto &blockDataList = tensors()[0].blockDataList(); + const auto& blockDataList = tensors()[0].blockDataList(); double maxBlockLength = blockDataList.back().blockLength(); double minBlockLength = blockDataList[0].blockLength(); /* If we have a finite block span we have a constant number of blocks, otherwise we are always adding more blocks (and we don't keep track of the number) */ if (maxBlockLength < GMX_DOUBLE_MAX) { - return static_cast(maxBlockLength/minBlockLength); + return static_cast(maxBlockLength / minBlockLength); } else { diff --git a/src/gromacs/awh/correlationgrid.h b/src/gromacs/awh/correlationgrid.h index 5d3456b44b..022b51a4e9 100644 --- a/src/gromacs/awh/correlationgrid.h +++ b/src/gromacs/awh/correlationgrid.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,98 +70,92 @@ struct CorrelationGridHistory; */ class CorrelationGrid { - public: - //! Enum that sets how we measure block length. - enum class BlockLengthMeasure - { - Time, //!< Measure block length in time. - Weight //!< Measure block length in sampled weight. - }; - - /*! \brief Constructor. - * - * \param[in] numPoints Number of points in the grid. - * \param[in] numDims Number of dimensions of the grid. - * \param[in] blockLengthInit Initial length of the blocks used for block averaging. - * \param[in] blockLengthMeasure Sets how we measure block length. - * \param[in] dtSample Time step for sampling correlations. - */ - CorrelationGrid(int numPoints, - int numDims, - double blockLengthInit, - BlockLengthMeasure blockLengthMeasure, - double dtSample); - - /*! \brief Adds a weighted data vector to one point in the correlation grid. - * - * \param[in] pointIndex Index of the point to add data to. - * \param[in] weight Weight to assign to the data. - * \param[in] data One data point for each grid dimension. - * \param[in] t The time when the data was sampled. - */ - void addData(int pointIndex, - double weight, - gmx::ArrayRef data, - double t) - { - tensors_[pointIndex].addData(weight, data, blockLengthMeasure == BlockLengthMeasure::Weight, t); - } - - /*! \brief Restores the correlation grid state from the correlation grid history. - * - * The setup in the history should match that of this simulation. - * If this is not the case, an exception is thrown. - * - * \param[in] correlationGridHistory The correlation grid state history. - */ - void restoreStateFromHistory(const CorrelationGridHistory &correlationGridHistory); - - /*! \brief Returns the number of elements in the tensor: dim*(dim+1)/2. - */ - int tensorSize() const - { - GMX_RELEASE_ASSERT(!tensors_.empty(), "Should only call tensorSize on a valid grid"); - - return tensors_[0].blockDataList()[0].correlationIntegral().size(); - } - - /*! \brief Returns the size of the block data list. - */ - int blockDataListSize() const - { - GMX_RELEASE_ASSERT(!tensors_.empty(), "Should only call tensorSize on a valid grid"); - - return tensors_[0].blockDataList().size(); - } - - /*! \brief Get a const reference to the correlation grid data. - */ - const std::vector &tensors() const - { - return tensors_; - } - - /* Right now the below functions are only used for an initial log printing. */ - - /*! \brief Get the current blocklength. - */ - double getBlockLength() const; - - /*! \brief Get the current number of blocks. - * - * If we have a finite block span we have a constant number of blocks, - * otherwise we are always adding more blocks (and we don't keep - * track of the number), so we return -1. - */ - int getNumBlocks() const; - - public: - const double dtSample; /**< Time in between samples. */ - const BlockLengthMeasure blockLengthMeasure; /**< The measure for the block length. */ - private: - std::vector tensors_; /**< Correlation tensor grid */ +public: + //! Enum that sets how we measure block length. + enum class BlockLengthMeasure + { + Time, //!< Measure block length in time. + Weight //!< Measure block length in sampled weight. + }; + + /*! \brief Constructor. + * + * \param[in] numPoints Number of points in the grid. + * \param[in] numDims Number of dimensions of the grid. + * \param[in] blockLengthInit Initial length of the blocks used for block averaging. + * \param[in] blockLengthMeasure Sets how we measure block length. + * \param[in] dtSample Time step for sampling correlations. + */ + CorrelationGrid(int numPoints, + int numDims, + double blockLengthInit, + BlockLengthMeasure blockLengthMeasure, + double dtSample); + + /*! \brief Adds a weighted data vector to one point in the correlation grid. + * + * \param[in] pointIndex Index of the point to add data to. + * \param[in] weight Weight to assign to the data. + * \param[in] data One data point for each grid dimension. + * \param[in] t The time when the data was sampled. + */ + void addData(int pointIndex, double weight, gmx::ArrayRef data, double t) + { + tensors_[pointIndex].addData(weight, data, blockLengthMeasure == BlockLengthMeasure::Weight, t); + } + + /*! \brief Restores the correlation grid state from the correlation grid history. + * + * The setup in the history should match that of this simulation. + * If this is not the case, an exception is thrown. + * + * \param[in] correlationGridHistory The correlation grid state history. + */ + void restoreStateFromHistory(const CorrelationGridHistory& correlationGridHistory); + + /*! \brief Returns the number of elements in the tensor: dim*(dim+1)/2. + */ + int tensorSize() const + { + GMX_RELEASE_ASSERT(!tensors_.empty(), "Should only call tensorSize on a valid grid"); + + return tensors_[0].blockDataList()[0].correlationIntegral().size(); + } + + /*! \brief Returns the size of the block data list. + */ + int blockDataListSize() const + { + GMX_RELEASE_ASSERT(!tensors_.empty(), "Should only call tensorSize on a valid grid"); + + return tensors_[0].blockDataList().size(); + } + + /*! \brief Get a const reference to the correlation grid data. + */ + const std::vector& tensors() const { return tensors_; } + + /* Right now the below functions are only used for an initial log printing. */ + + /*! \brief Get the current blocklength. + */ + double getBlockLength() const; + + /*! \brief Get the current number of blocks. + * + * If we have a finite block span we have a constant number of blocks, + * otherwise we are always adding more blocks (and we don't keep + * track of the number), so we return -1. + */ + int getNumBlocks() const; + +public: + const double dtSample; /**< Time in between samples. */ + const BlockLengthMeasure blockLengthMeasure; /**< The measure for the block length. */ +private: + std::vector tensors_; /**< Correlation tensor grid */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_CORRELATIONGRID_H */ diff --git a/src/gromacs/awh/correlationhistory.cpp b/src/gromacs/awh/correlationhistory.cpp index aa36bb3e5c..3dac473fe0 100644 --- a/src/gromacs/awh/correlationhistory.cpp +++ b/src/gromacs/awh/correlationhistory.cpp @@ -61,7 +61,7 @@ namespace gmx { -void initCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory, +void initCorrelationGridHistory(CorrelationGridHistory* correlationGridHistory, int numCorrelationTensors, int tensorSize, int blockDataListSize) @@ -70,21 +70,22 @@ void initCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory, correlationGridHistory->tensorSize = tensorSize; correlationGridHistory->blockDataListSize = blockDataListSize; - correlationGridHistory->blockDataBuffer.resize(numCorrelationTensors*tensorSize*blockDataListSize); + correlationGridHistory->blockDataBuffer.resize(numCorrelationTensors * tensorSize * blockDataListSize); } -CorrelationGridHistory initCorrelationGridHistoryFromState(const CorrelationGrid &correlationGrid) +CorrelationGridHistory initCorrelationGridHistoryFromState(const CorrelationGrid& correlationGrid) { CorrelationGridHistory correlationGridHistory; - initCorrelationGridHistory(&correlationGridHistory, correlationGrid.tensors().size(), correlationGrid.tensorSize(), correlationGrid.blockDataListSize()); + initCorrelationGridHistory(&correlationGridHistory, correlationGrid.tensors().size(), + correlationGrid.tensorSize(), correlationGrid.blockDataListSize()); return correlationGridHistory; } /* Update the correlation grid history for checkpointing. */ -void updateCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory, - const CorrelationGrid &correlationGrid) +void updateCorrelationGridHistory(CorrelationGridHistory* correlationGridHistory, + const CorrelationGrid& correlationGrid) { GMX_RELEASE_ASSERT(correlationGridHistory != nullptr, "We need a valid history object"); @@ -92,30 +93,30 @@ void updateCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory /* Store the grid in a linear array */ gmx::index bufferIndex = 0; - for (const CorrelationTensor &tensor : correlationGrid.tensors()) + for (const CorrelationTensor& tensor : correlationGrid.tensors()) { - const int numDims = tensor.blockDataList()[0].coordData().size(); - const int tensorSize = tensor.blockDataList()[0].correlationIntegral().size(); + const int numDims = tensor.blockDataList()[0].coordData().size(); + const int tensorSize = tensor.blockDataList()[0].correlationIntegral().size(); /* Loop of the tensor elements, ignore the symmetric data */ - int d1 = 0; - int d2 = 0; + int d1 = 0; + int d2 = 0; for (int k = 0; k < tensorSize; k++) { /* BlockData for each correlation element */ - for (const CorrelationBlockData &blockData : tensor.blockDataList()) + for (const CorrelationBlockData& blockData : tensor.blockDataList()) { - const CorrelationBlockData::CoordData &cx = blockData.coordData()[d1]; - const CorrelationBlockData::CoordData &cy = blockData.coordData()[d2]; + const CorrelationBlockData::CoordData& cx = blockData.coordData()[d1]; + const CorrelationBlockData::CoordData& cy = blockData.coordData()[d2]; - CorrelationBlockDataHistory &bdh = blockDataBuffer[bufferIndex]; + CorrelationBlockDataHistory& bdh = blockDataBuffer[bufferIndex]; - bdh.blockSumWeight = blockData.blockSumWeight(); - bdh.blockSumSquareWeight = blockData.blockSumSquareWeight(); - bdh.blockSumWeightX = cx.blockSumWeightX; - bdh.blockSumWeightY = cy.blockSumWeightX; - bdh.sumOverBlocksSquareBlockWeight = blockData.sumOverBlocksSquareBlockWeight(); - bdh.sumOverBlocksBlockSquareWeight = blockData.sumOverBlocksBlockSquareWeight(); + bdh.blockSumWeight = blockData.blockSumWeight(); + bdh.blockSumSquareWeight = blockData.blockSumSquareWeight(); + bdh.blockSumWeightX = cx.blockSumWeightX; + bdh.blockSumWeightY = cy.blockSumWeightX; + bdh.sumOverBlocksSquareBlockWeight = blockData.sumOverBlocksSquareBlockWeight(); + bdh.sumOverBlocksBlockSquareWeight = blockData.sumOverBlocksBlockSquareWeight(); bdh.sumOverBlocksBlockWeightBlockWeightX = cx.sumOverBlocksBlockWeightBlockWeightX; bdh.sumOverBlocksBlockWeightBlockWeightY = cy.sumOverBlocksBlockWeightBlockWeightX; bdh.previousBlockIndex = blockData.previousBlockIndex(); @@ -134,12 +135,13 @@ void updateCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory } } - GMX_RELEASE_ASSERT(bufferIndex == blockDataBuffer.ssize(), "We should store exactly as many elements as the buffer size"); + GMX_RELEASE_ASSERT(bufferIndex == blockDataBuffer.ssize(), + "We should store exactly as many elements as the buffer size"); } -void CorrelationBlockData::restoreFromHistory(const CorrelationBlockDataHistory &blockHistory, - const std::vector &coordData, - const std::vector &correlationIntegral) +void CorrelationBlockData::restoreFromHistory(const CorrelationBlockDataHistory& blockHistory, + const std::vector& coordData, + const std::vector& correlationIntegral) { blockSumWeight_ = blockHistory.blockSumWeight; blockSumSquareWeight_ = blockHistory.blockSumSquareWeight; @@ -152,11 +154,11 @@ void CorrelationBlockData::restoreFromHistory(const CorrelationBlockDataHistory } /* Restore a correlation element from history. */ -void CorrelationTensor::restoreFromHistory(const std::vector &blockDataBuffer, - size_t *bufferIndex) +void CorrelationTensor::restoreFromHistory(const std::vector& blockDataBuffer, + size_t* bufferIndex) { /* Blockdata for each correlation element */ - for (CorrelationBlockData &blockData : blockDataList_) + for (CorrelationBlockData& blockData : blockDataList_) { /* Correlation elements for each tensor */ const int numDims = blockDataList_[0].coordData().size(); @@ -171,19 +173,24 @@ void CorrelationTensor::restoreFromHistory(const std::vector= blockDataBuffer.size()) { - GMX_THROW(InvalidInputError("Mismatch of the correlation tensor size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation.")); + GMX_THROW(InvalidInputError( + "Mismatch of the correlation tensor size for the force correlation between " + "checkpoint and simulation. Likely you have provided a checkpoint from a " + "different simulation.")); } - const CorrelationBlockDataHistory &blockHistory = blockDataBuffer[*bufferIndex]; + const CorrelationBlockDataHistory& blockHistory = blockDataBuffer[*bufferIndex]; /* To simplify the checkpointing, CorrelationBlockDataHistory * duplicates some weight data for all tensor elements. * Here we collect the coordinate and tensor data * in temporary buffers. */ - coordData[d1].blockSumWeightX = blockHistory.blockSumWeightX; - coordData[d2].blockSumWeightX = blockHistory.blockSumWeightY; - coordData[d1].sumOverBlocksBlockWeightBlockWeightX = blockHistory.sumOverBlocksBlockWeightBlockWeightX; - coordData[d2].sumOverBlocksBlockWeightBlockWeightX = blockHistory.sumOverBlocksBlockWeightBlockWeightY; + coordData[d1].blockSumWeightX = blockHistory.blockSumWeightX; + coordData[d2].blockSumWeightX = blockHistory.blockSumWeightY; + coordData[d1].sumOverBlocksBlockWeightBlockWeightX = + blockHistory.sumOverBlocksBlockWeightBlockWeightX; + coordData[d2].sumOverBlocksBlockWeightBlockWeightX = + blockHistory.sumOverBlocksBlockWeightBlockWeightY; correlationIntegral[k] = blockHistory.correlationIntegral; @@ -206,24 +213,28 @@ void CorrelationTensor::restoreFromHistory(const std::vector(correlationGridHistory.numCorrelationTensors)) { - GMX_THROW(InvalidInputError("Mismatch of the grid size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation.")); + GMX_THROW(InvalidInputError( + "Mismatch of the grid size for the force correlation between checkpoint and " + "simulation. Likely you have provided a checkpoint from a different simulation.")); } /* Extract the state from the linear history array */ size_t bufferIndex = 0; - for (CorrelationTensor &tensor : tensors_) + for (CorrelationTensor& tensor : tensors_) { - tensor.restoreFromHistory(correlationGridHistory.blockDataBuffer, - &bufferIndex); + tensor.restoreFromHistory(correlationGridHistory.blockDataBuffer, &bufferIndex); } if (bufferIndex != correlationGridHistory.blockDataBuffer.size()) { - GMX_THROW(InvalidInputError("Mismatch of the correlation tensor size for the force correlation between checkpoint and simulation. Likely you have provided a checkpoint from a different simulation.")); + GMX_THROW( + InvalidInputError("Mismatch of the correlation tensor size for the force " + "correlation between checkpoint and simulation. Likely you have " + "provided a checkpoint from a different simulation.")); } } diff --git a/src/gromacs/awh/correlationhistory.h b/src/gromacs/awh/correlationhistory.h index fe11e5f1d0..61e70d9507 100644 --- a/src/gromacs/awh/correlationhistory.h +++ b/src/gromacs/awh/correlationhistory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,7 +64,7 @@ struct CorrelationGridHistory; * \param[in,out] corrGrid Correlation grid state to initialize with. * \returns the correlation grid history struct. */ -CorrelationGridHistory initCorrelationGridHistoryFromState(const CorrelationGrid &corrGrid); +CorrelationGridHistory initCorrelationGridHistoryFromState(const CorrelationGrid& corrGrid); /*! \brief * Restores the correlation grid state from the correlation grid history. @@ -72,7 +72,8 @@ CorrelationGridHistory initCorrelationGridHistoryFromState(const CorrelationGrid * \param[in] corrGridHist Correlation grid history to read. * \param[in,out] corrGrid Correlation grid state to set. */ -void restoreCorrelationGridStateFromHistory(const CorrelationGridHistory &corrGridHist, CorrelationGrid *corrGrid); +void restoreCorrelationGridStateFromHistory(const CorrelationGridHistory& corrGridHist, + CorrelationGrid* corrGrid); /*! \brief * Update the correlation grid history for checkpointing. @@ -80,8 +81,8 @@ void restoreCorrelationGridStateFromHistory(const CorrelationGridHistory &corrGr * \param[in,out] corrGridHist Correlation grid history to set. * \param[in] corrGrid Correlation grid state to read. */ -void updateCorrelationGridHistory(CorrelationGridHistory *corrGridHist, const CorrelationGrid &corrGrid); +void updateCorrelationGridHistory(CorrelationGridHistory* corrGridHist, const CorrelationGrid& corrGrid); -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_CORRELATIONHISTORY_H */ diff --git a/src/gromacs/awh/correlationtensor.cpp b/src/gromacs/awh/correlationtensor.cpp index e1e973963a..ebcd1aa590 100644 --- a/src/gromacs/awh/correlationtensor.cpp +++ b/src/gromacs/awh/correlationtensor.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,29 +66,27 @@ namespace * the start time, which time weighting, or the total weight. * * \param[in] blockLength Block length. - * \param[in] currentAccumulatedLength Sampling length of all data collected up to the current step, in time or weight. - * \returns the block index. + * \param[in] currentAccumulatedLength Sampling length of all data collected up to the current + * step, in time or weight. \returns the block index. */ -int getBlockIndex(double blockLength, - double currentAccumulatedLength) +int getBlockIndex(double blockLength, double currentAccumulatedLength) { - return static_cast(currentAccumulatedLength/blockLength); + return static_cast(currentAccumulatedLength / blockLength); } -} // namespace +} // namespace -double CorrelationTensor::getTimeIntegral(int tensorIndex, - double dtSample) const +double CorrelationTensor::getTimeIntegral(int tensorIndex, double dtSample) const { - const CorrelationBlockData &blockData = blockDataList_[0]; + const CorrelationBlockData& blockData = blockDataList_[0]; double weight = blockData.sumOverBlocksBlockSquareWeight(); double correlationIntegral = 0; if (weight > 0) { - correlationIntegral = blockData.correlationIntegral()[tensorIndex]/weight; + correlationIntegral = blockData.correlationIntegral()[tensorIndex] / weight; } - return 0.5*correlationIntegral*dtSample; + return 0.5 * correlationIntegral * dtSample; } double CorrelationTensor::getVolumeElement(double dtSample) const @@ -108,7 +106,7 @@ double CorrelationTensor::getVolumeElement(double dtSample) const double b = getTimeIntegral(1, dtSample); double c = getTimeIntegral(2, dtSample); - det = a*c - b*b; + det = a * c - b * b; } break; case 6: @@ -121,7 +119,7 @@ double CorrelationTensor::getVolumeElement(double dtSample) const double e = getTimeIntegral(4, dtSample); double f = getTimeIntegral(5, dtSample); - det = a*c*f + 2*b*d*e - d*c*d - b*b*f - a*e*e; + det = a * c * f + 2 * b * d * e - d * c * d - b * b * f - a * e * e; } break; default: @@ -137,8 +135,8 @@ double CorrelationTensor::getVolumeElement(double dtSample) const void CorrelationTensor::doubleBlockLengths() { - /* We need to shift the data so that a given blockdata gets the data for double the block length. - The data for the shortest block length is not needed anymore. */ + /* We need to shift the data so that a given blockdata gets the data for double the block + length. The data for the shortest block length is not needed anymore. */ for (size_t i = 0; i < blockDataList_.size() - 1; i++) { @@ -178,11 +176,11 @@ void CorrelationBlockData::addBlockToCorrelationIntegral() int tensorIndex = 0; for (int d1 = 0; d1 < numDim; d1++) { - const CoordData &c1 = coordData_[d1]; + const CoordData& c1 = coordData_[d1]; for (int d2 = 0; d2 <= d1; d2++) { - const CoordData &c2 = coordData_[d2]; + const CoordData& c2 = coordData_[d2]; /* Compute change in correlaion integral due to adding * the block through computing the difference of the block @@ -190,20 +188,25 @@ void CorrelationBlockData::addBlockToCorrelationIntegral() * and with the new component (we use y). */ /* Need the old average, before the data of this block was added */ - GMX_ASSERT(sumOverBlocksSquareBlockWeight_, "Denominator should be > 0 (should be guaranteed by the conditional above)"); - double oldAverageX = c1.sumOverBlocksBlockWeightBlockWeightX/sumOverBlocksSquareBlockWeight_; + GMX_ASSERT(sumOverBlocksSquareBlockWeight_, + "Denominator should be > 0 (should be guaranteed by the conditional " + "above)"); + double oldAverageX = + c1.sumOverBlocksBlockWeightBlockWeightX / sumOverBlocksSquareBlockWeight_; - double newSumWeightBlockWeightY = c2.sumOverBlocksBlockWeightBlockWeightX + blockSumWeight_*c2.blockSumWeightX; - double newSumSquareBlockWeight = sumOverBlocksSquareBlockWeight_ + gmx::square(blockSumWeight_); + double newSumWeightBlockWeightY = + c2.sumOverBlocksBlockWeightBlockWeightX + blockSumWeight_ * c2.blockSumWeightX; + double newSumSquareBlockWeight = + sumOverBlocksSquareBlockWeight_ + gmx::square(blockSumWeight_); GMX_ASSERT(newSumSquareBlockWeight > 0, "Denominator should be > 0"); - double newAverageY = newSumWeightBlockWeightY/newSumSquareBlockWeight; + double newAverageY = newSumWeightBlockWeightY / newSumSquareBlockWeight; - double diffBlockWithOldAverageX = c1.blockSumWeightX - oldAverageX*blockSumWeight_; - double diffBlockWithNewAverageY = c2.blockSumWeightX - newAverageY*blockSumWeight_; + double diffBlockWithOldAverageX = c1.blockSumWeightX - oldAverageX * blockSumWeight_; + double diffBlockWithNewAverageY = c2.blockSumWeightX - newAverageY * blockSumWeight_; /* Update the correlation integral using the changes in averages. */ - correlationIntegral_[tensorIndex] += diffBlockWithOldAverageX*diffBlockWithNewAverageY; + correlationIntegral_[tensorIndex] += diffBlockWithOldAverageX * diffBlockWithNewAverageY; tensorIndex++; } } @@ -212,21 +215,18 @@ void CorrelationBlockData::addBlockToCorrelationIntegral() /* Add the weights of the block to the block sums and clear the weights */ sumOverBlocksSquareBlockWeight_ += gmx::square(blockSumWeight_); sumOverBlocksBlockSquareWeight_ += blockSumSquareWeight_; - for (auto &c : coordData_) + for (auto& c : coordData_) { - c.sumOverBlocksBlockWeightBlockWeightX += blockSumWeight_*c.blockSumWeightX; + c.sumOverBlocksBlockWeightBlockWeightX += blockSumWeight_ * c.blockSumWeightX; /* Reset */ - c.blockSumWeightX = 0; + c.blockSumWeightX = 0; } /* Reset */ blockSumWeight_ = 0; blockSumSquareWeight_ = 0; } -void CorrelationTensor::addData(double weight, - gmx::ArrayRef data, - bool blockLengthInWeight, - double t) +void CorrelationTensor::addData(double weight, gmx::ArrayRef data, bool blockLengthInWeight, double t) { /* We should avoid adding data with very small weight to avoid * divergence close to 0/0. The total spread weight for each sample is 1, @@ -244,17 +244,16 @@ void CorrelationTensor::addData(double weight, /* Make sure the blocks are long enough to fit all data */ updateBlockLengths(samplingLength); - /* Store the data for each block length considered. First update the longest block which has all data since it's - used for updating the correlation function for the other block lengths. */ + /* Store the data for each block length considered. First update the longest block which has all + data since it's used for updating the correlation function for the other block lengths. */ for (size_t i = 0; i < blockDataList_.size() - 1; i++) { - CorrelationBlockData &bd = blockDataList_[i]; + CorrelationBlockData& bd = blockDataList_[i]; /* Find current block index given the block length. */ int blockIndex = getBlockIndex(bd.blockLength(), samplingLength); - if (bd.previousBlockIndex() >= 0 && - bd.previousBlockIndex() != blockIndex) + if (bd.previousBlockIndex() >= 0 && bd.previousBlockIndex() != blockIndex) { /* Changed block. Update correlation with old data before adding to new block. */ bd.addBlockToCorrelationIntegral(); @@ -273,17 +272,16 @@ void CorrelationTensor::addData(double weight, blockDataList_.back().addData(weight, data); } -CorrelationTensor::CorrelationTensor(int numDim, - int numBlockData, - double blockLengthInit) +CorrelationTensor::CorrelationTensor(int numDim, int numBlockData, double blockLengthInit) { unsigned int scaling = 1; - GMX_RELEASE_ASSERT(numBlockData < static_cast(sizeof(scaling)*8), "numBlockData should we smaller than the number of bits in scaling"); + GMX_RELEASE_ASSERT(numBlockData < static_cast(sizeof(scaling) * 8), + "numBlockData should we smaller than the number of bits in scaling"); for (int n = 0; n < numBlockData; n++) { - blockDataList_.emplace_back(numDim, scaling*blockLengthInit); + blockDataList_.emplace_back(numDim, scaling * blockLengthInit); scaling <<= 1; /* Double block length */ } } diff --git a/src/gromacs/awh/correlationtensor.h b/src/gromacs/awh/correlationtensor.h index 6d2716e5d6..e9fe9537da 100644 --- a/src/gromacs/awh/correlationtensor.h +++ b/src/gromacs/awh/correlationtensor.h @@ -63,151 +63,116 @@ struct CorrelationBlockDataHistory; */ class CorrelationBlockData { - public: - /*! \internal \brief Correlation block averaging data. - */ - struct CoordData - { - /*! \brief Constructor. - */ - CoordData() : - blockSumWeightX(0), - sumOverBlocksBlockWeightBlockWeightX(0) - { - } - - double blockSumWeightX; /**< Weighted sum of x for current block. */ - double sumOverBlocksBlockWeightBlockWeightX; /**< Sum over all blocks in the simulation of block weight times sum_wx. */ - }; - +public: + /*! \internal \brief Correlation block averaging data. + */ + struct CoordData + { /*! \brief Constructor. - * - * \param[in] numDim The dimensionality. - * \param[in] blockLengthInit The initial block length. */ - CorrelationBlockData(int numDim, - double blockLengthInit) : - blockSumWeight_(0), - blockSumSquareWeight_(0), - sumOverBlocksSquareBlockWeight_(0), - sumOverBlocksBlockSquareWeight_(0), - blockLength_(blockLengthInit), - previousBlockIndex_(-1), - coordData_(numDim), - correlationIntegral_(numDim*(numDim + 1)/2) + CoordData() : blockSumWeightX(0), sumOverBlocksBlockWeightBlockWeightX(0) {} + + double blockSumWeightX; /**< Weighted sum of x for current block. */ + double sumOverBlocksBlockWeightBlockWeightX; /**< Sum over all blocks in the simulation of block weight times sum_wx. */ + }; + + /*! \brief Constructor. + * + * \param[in] numDim The dimensionality. + * \param[in] blockLengthInit The initial block length. + */ + CorrelationBlockData(int numDim, double blockLengthInit) : + blockSumWeight_(0), + blockSumSquareWeight_(0), + sumOverBlocksSquareBlockWeight_(0), + sumOverBlocksBlockSquareWeight_(0), + blockLength_(blockLengthInit), + previousBlockIndex_(-1), + coordData_(numDim), + correlationIntegral_(numDim * (numDim + 1) / 2) + { + } + + /*! \brief Restore the state from history. + * + * \param[in] blockHistory The block data history containing the weight sums. + * \param[in] coordData The coordinate data. + * \param[in] correlationIntegral The correlation integral for all tensor elements. + */ + void restoreFromHistory(const CorrelationBlockDataHistory& blockHistory, + const std::vector& coordData, + const std::vector& correlationIntegral); + + /*! \brief Adds a weighted data vector to one point in the correlation grid. + * + * \param[in] weight The weight of the data. + * \param[in] data One data point for each grid dimension. + */ + void addData(double weight, gmx::ArrayRef data) + { + GMX_ASSERT(data.size() == coordData_.size(), + "Size of data should match the size of coordData"); + + blockSumWeight_ += weight; + blockSumSquareWeight_ += weight * weight; + + for (size_t d = 0; d < coordData_.size(); d++) { + coordData_[d].blockSumWeightX += weight * data[d]; } + } - /*! \brief Restore the state from history. - * - * \param[in] blockHistory The block data history containing the weight sums. - * \param[in] coordData The coordinate data. - * \param[in] correlationIntegral The correlation integral for all tensor elements. - */ - void restoreFromHistory(const CorrelationBlockDataHistory &blockHistory, - const std::vector &coordData, - const std::vector &correlationIntegral); - - /*! \brief Adds a weighted data vector to one point in the correlation grid. - * - * \param[in] weight The weight of the data. - * \param[in] data One data point for each grid dimension. - */ - void addData(double weight, - gmx::ArrayRef data) - { - GMX_ASSERT(data.size() == coordData_.size(), "Size of data should match the size of coordData"); - - blockSumWeight_ += weight; - blockSumSquareWeight_ += weight*weight; + /*! \brief Adds a filled data block to correlation time integral. + */ + void addBlockToCorrelationIntegral(); - for (size_t d = 0; d < coordData_.size(); d++) - { - coordData_[d].blockSumWeightX += weight*data[d]; - } - } - - /*! \brief Adds a filled data block to correlation time integral. - */ - void addBlockToCorrelationIntegral(); - - /*! \brief Returns the sum weights for current block. */ - double blockSumWeight() const - { - return blockSumWeight_; - } + /*! \brief Returns the sum weights for current block. */ + double blockSumWeight() const { return blockSumWeight_; } - /*! \brief Returns the sum weights^2 for current block. */ - double blockSumSquareWeight() const - { - return blockSumSquareWeight_; - } + /*! \brief Returns the sum weights^2 for current block. */ + double blockSumSquareWeight() const { return blockSumSquareWeight_; } - /*! \brief Returns the sum over blocks of block weight^2. */ - double sumOverBlocksSquareBlockWeight() const - { - return sumOverBlocksSquareBlockWeight_; - } + /*! \brief Returns the sum over blocks of block weight^2. */ + double sumOverBlocksSquareBlockWeight() const { return sumOverBlocksSquareBlockWeight_; } - /*! \brief Returns the sum over blocks of weight^2. */ - double sumOverBlocksBlockSquareWeight() const - { - return sumOverBlocksBlockSquareWeight_; - } + /*! \brief Returns the sum over blocks of weight^2. */ + double sumOverBlocksBlockSquareWeight() const { return sumOverBlocksBlockSquareWeight_; } - /*! \brief Returns the length of each block used for block averaging. */ - double blockLength() const - { - return blockLength_; - } + /*! \brief Returns the length of each block used for block averaging. */ + double blockLength() const { return blockLength_; } - /*! \brief Double the length of each block used for block averaging. */ - void doubleBlockLength() - { - blockLength_ *= 2; - } + /*! \brief Double the length of each block used for block averaging. */ + void doubleBlockLength() { blockLength_ *= 2; } - /*! \brief Return the last block index data was added to (needed only for block length in terms of time). */ - int previousBlockIndex() const - { - return previousBlockIndex_; - } + /*! \brief Return the last block index data was added to (needed only for block length in terms of time). */ + int previousBlockIndex() const { return previousBlockIndex_; } - /*! \brief Set the last block index data was added to. - * - * \param[in] blockIndex The block index. - */ - void setPreviousBlockIndex(int blockIndex) - { - previousBlockIndex_ = blockIndex; - } + /*! \brief Set the last block index data was added to. + * + * \param[in] blockIndex The block index. + */ + void setPreviousBlockIndex(int blockIndex) { previousBlockIndex_ = blockIndex; } - /*! \brief Return sums for each coordinate dimension. */ - const std::vector &coordData() const - { - return coordData_; - } + /*! \brief Return sums for each coordinate dimension. */ + const std::vector& coordData() const { return coordData_; } - /*! \brief Return the correlation integral tensor. */ - const std::vector &correlationIntegral() const - { - return correlationIntegral_; - } + /*! \brief Return the correlation integral tensor. */ + const std::vector& correlationIntegral() const { return correlationIntegral_; } - private: - /* Weight sum data, indentical for all dimensions */ - double blockSumWeight_; /**< Sum weights for current block. */ - double blockSumSquareWeight_; /**< Sum weights^2 for current block. */ - double sumOverBlocksSquareBlockWeight_; /**< Sum over all blocks in the simulation of block weight^2. */ - double sumOverBlocksBlockSquareWeight_; /**< Sum over all blocks in the simulation of weight^2. */ - double blockLength_; /**< The length of each block used for block averaging */ - int previousBlockIndex_; /**< The last block index data was added to (needed only for block length in terms of time). */ +private: + /* Weight sum data, indentical for all dimensions */ + double blockSumWeight_; /**< Sum weights for current block. */ + double blockSumSquareWeight_; /**< Sum weights^2 for current block. */ + double sumOverBlocksSquareBlockWeight_; /**< Sum over all blocks in the simulation of block weight^2. */ + double sumOverBlocksBlockSquareWeight_; /**< Sum over all blocks in the simulation of weight^2. */ + double blockLength_; /**< The length of each block used for block averaging */ + int previousBlockIndex_; /**< The last block index data was added to (needed only for block length in terms of time). */ - /* Sums for each coordinate dimension. */ - std::vector coordData_; /**< Array with sums for each coordinate dimension. */ + /* Sums for each coordinate dimension. */ + std::vector coordData_; /**< Array with sums for each coordinate dimension. */ - /* Correlation tensor. */ - std::vector correlationIntegral_; /**< Array with the correlation elements corr(x, y) in the tensor, where x, y are vector components. */ + /* Correlation tensor. */ + std::vector correlationIntegral_; /**< Array with the correlation elements corr(x, y) in the tensor, where x, y are vector components. */ }; /*! \internal @@ -226,114 +191,105 @@ class CorrelationBlockData */ class CorrelationTensor { - public: - /*! \brief 64 blocks is a good trade-off between signal and noise */ - static constexpr int c_numCorrelationBlocks = 64; - - /*! \brief Constructor. - * - * \param[in] numDim The dimensionality. - * \param[in] numBlockData The number of data block data structs. - * \param[in] blockLengthInit The initial block length. - */ - CorrelationTensor(int numDim, - int numBlockData, - double blockLengthInit); - - /*! \brief Get a const reference to the list of block data. - */ - const std::vector &blockDataList() const - { - return blockDataList_; - } - - /*! \brief - * Get the total weight of the data in the correlation matrix. - * - * \returns the weight of the added data. - */ - double getWeight() const - { - /* The last blockdata has only 1 block containing all data */ - return blockDataList().back().blockSumWeight(); - } - - /*! \brief Restore a correlation element from history. - * - * \param[in] blockDataBuffer The linear correlation grid data history buffer. - * \param[in,out] bufferIndex The index in \p blockDataBuffer to start reading, is increased with the number of blocks read. - */ - void restoreFromHistory(const std::vector &blockDataBuffer, - size_t *bufferIndex); - - private: - /*! \brief Updates the block length by doubling. - * - * The length of all blocks is doubled. This is achieved by removing - * the shortest block, moving all other blocks and duplicating - * the data of longest block to a nw block of double length (but - * currenly only half filled with data). - */ - void doubleBlockLengths(); - - /*! \brief Updates the block length such that data fits. - * - * \param[in] samplingLength Sampling length of all data, in time or weight. - */ - void updateBlockLengths(double samplingLength); - - public: - /*! \brief Adds a weighted data vector to one point in the correlation grid. - * - * \note To avoid rounding noise, data with weight smaller than 1e-6 - * is ignored. - * - * \param[in] weight The weight of the data. - * \param[in] data One data point for each grid dimension. - * \param[in] blockLengthInWeight If true, a block is measured in probability weight, otherwise in time. - * \param[in] t The simulation time. - */ - void addData(double weight, - gmx::ArrayRef data, - bool blockLengthInWeight, - double t); - - /*! \brief Returns an element of the time integrated correlation tensor at a given point in the grid. - * - * The units of the integral are time*(units of data)^2. This will be friction units time/length^2 - * if the data unit is 1/length. - * - * The correlation index lists the elements of the upper-triangular - * correlation matrix row-wise, so e.g. in 3D: - * 0 (0,0), 1 (1,0), 2 (1,1), 3 (2,0), 4 (2,1), 5 (2,2). - * (TODO: this should ideally not have to be known by the caller.) - * - * \param[in] tensorIndex Index in the tensor. - * \param[in] dtSample The sampling interval length. - * \returns the integral. - */ - double getTimeIntegral(int tensorIndex, - double dtSample) const; - - /*! \brief - * Returns the volume element of the correlation metric. - * - * The matrix of the metric equals the time-integrated correlation matrix. The volume element of - * the metric therefore equals the square-root of the absolute value of its determinant according - * to the standard formula for a volume element in a metric space. - * - * Since the units of the metric matrix elements are time*(units of data)^2, the volume element has - * units of (sqrt(time)*(units of data))^(ndim of data). - * - * \param[in] dtSample The sampling interval length. - * \returns the volume element. - */ - double getVolumeElement(double dtSample) const; - - private: - std::vector blockDataList_; /**< The block data for different, consecutively doubling block lengths. */ +public: + /*! \brief 64 blocks is a good trade-off between signal and noise */ + static constexpr int c_numCorrelationBlocks = 64; + + /*! \brief Constructor. + * + * \param[in] numDim The dimensionality. + * \param[in] numBlockData The number of data block data structs. + * \param[in] blockLengthInit The initial block length. + */ + CorrelationTensor(int numDim, int numBlockData, double blockLengthInit); + + /*! \brief Get a const reference to the list of block data. + */ + const std::vector& blockDataList() const { return blockDataList_; } + + /*! \brief + * Get the total weight of the data in the correlation matrix. + * + * \returns the weight of the added data. + */ + double getWeight() const + { + /* The last blockdata has only 1 block containing all data */ + return blockDataList().back().blockSumWeight(); + } + + /*! \brief Restore a correlation element from history. + * + * \param[in] blockDataBuffer The linear correlation grid data history buffer. + * \param[in,out] bufferIndex The index in \p blockDataBuffer to start reading, is increased with the number of blocks read. + */ + void restoreFromHistory(const std::vector& blockDataBuffer, + size_t* bufferIndex); + +private: + /*! \brief Updates the block length by doubling. + * + * The length of all blocks is doubled. This is achieved by removing + * the shortest block, moving all other blocks and duplicating + * the data of longest block to a nw block of double length (but + * currenly only half filled with data). + */ + void doubleBlockLengths(); + + /*! \brief Updates the block length such that data fits. + * + * \param[in] samplingLength Sampling length of all data, in time or weight. + */ + void updateBlockLengths(double samplingLength); + +public: + /*! \brief Adds a weighted data vector to one point in the correlation grid. + * + * \note To avoid rounding noise, data with weight smaller than 1e-6 + * is ignored. + * + * \param[in] weight The weight of the data. + * \param[in] data One data point for each grid dimension. + * \param[in] blockLengthInWeight If true, a block is measured in probability weight, otherwise + * in time. \param[in] t The simulation time. + */ + void addData(double weight, gmx::ArrayRef data, bool blockLengthInWeight, double t); + + /*! \brief Returns an element of the time integrated correlation tensor at a given point in the grid. + * + * The units of the integral are time*(units of data)^2. This will be friction units time/length^2 + * if the data unit is 1/length. + * + * The correlation index lists the elements of the upper-triangular + * correlation matrix row-wise, so e.g. in 3D: + * 0 (0,0), 1 (1,0), 2 (1,1), 3 (2,0), 4 (2,1), 5 (2,2). + * (TODO: this should ideally not have to be known by the caller.) + * + * \param[in] tensorIndex Index in the tensor. + * \param[in] dtSample The sampling interval length. + * \returns the integral. + */ + double getTimeIntegral(int tensorIndex, double dtSample) const; + + /*! \brief + * Returns the volume element of the correlation metric. + * + * The matrix of the metric equals the time-integrated correlation matrix. The volume element of + * the metric therefore equals the square-root of the absolute value of its determinant + * according to the standard formula for a volume element in a metric space. + * + * Since the units of the metric matrix elements are time*(units of data)^2, the volume element + * has units of (sqrt(time)*(units of data))^(ndim of data). + * + * \param[in] dtSample The sampling interval length. + * \returns the volume element. + */ + double getVolumeElement(double dtSample) const; + +private: + std::vector blockDataList_; /**< The block data for different, consecutively doubling block lengths. */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_CORRELATIONTENSOR_H */ diff --git a/src/gromacs/awh/dimparams.h b/src/gromacs/awh/dimparams.h index 303dd32f18..8478d19ec7 100644 --- a/src/gromacs/awh/dimparams.h +++ b/src/gromacs/awh/dimparams.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -77,11 +77,9 @@ struct DimParams * \param[in] forceConstant The harmonic force constant. * \param[in] beta 1/(k_B T). */ - DimParams(double conversionFactor, - double forceConstant, - double beta) : + DimParams(double conversionFactor, double forceConstant, double beta) : k(forceConstant), - betak(beta*forceConstant), + betak(beta * forceConstant), userCoordUnitsToInternal(conversionFactor) { } @@ -91,26 +89,20 @@ struct DimParams * \param[in] value Value to convert. * \returns the converted value. */ - double scaleInternalToUserInput(double value) const - { - return value/userCoordUnitsToInternal; - } + double scaleInternalToUserInput(double value) const { return value / userCoordUnitsToInternal; } /*! \brief Convert external, user coordinate units to internal coordinate units. * * \param[in] value Value to convert. * \returns the converted value. */ - double scaleUserInputToInternal(double value) const - { - return value*userCoordUnitsToInternal; - } + double scaleUserInputToInternal(double value) const { return value * userCoordUnitsToInternal; } - const double k; /**< Force constant (kJ/mol/nm^2) for each coordinate dimension. */ - const double betak; /**< Inverse variance (1/nm^2) for each coordinate dimension. */ + const double k; /**< Force constant (kJ/mol/nm^2) for each coordinate dimension. */ + const double betak; /**< Inverse variance (1/nm^2) for each coordinate dimension. */ const double userCoordUnitsToInternal; /**< Conversion factor coordinate units. */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_DIMPARAMS_H */ diff --git a/src/gromacs/awh/grid.cpp b/src/gromacs/awh/grid.cpp index b9a188d841..7e73cb8120 100644 --- a/src/gromacs/awh/grid.cpp +++ b/src/gromacs/awh/grid.cpp @@ -77,12 +77,11 @@ namespace * \param[in,out] x Pointer to the value to modify. * \param[in] period The period, or 0 if not periodic. */ -void centerPeriodicValueAroundZero(double *x, - double period) +void centerPeriodicValueAroundZero(double* x, double period) { GMX_ASSERT(period >= 0, "Periodic should not be negative"); - const double halfPeriod = period*0.5; + const double halfPeriod = period * 0.5; if (*x >= halfPeriod) { @@ -107,8 +106,7 @@ void centerPeriodicValueAroundZero(double *x, * \param[in] period The period, or 0 if not periodic. * \returns for period>0: index value witin [0, period), otherwise: \p x. */ -int indexWithinPeriod(int x, - int period) +int indexWithinPeriod(int x, int period) { GMX_ASSERT(period >= 0, "Periodic should not be negative"); @@ -117,7 +115,8 @@ int indexWithinPeriod(int x, return x; } - GMX_ASSERT(x > -period && x < 2*period, "x should not be more shifted by more than one period"); + GMX_ASSERT(x > -period && x < 2 * period, + "x should not be more shifted by more than one period"); if (x >= period) { @@ -147,9 +146,7 @@ int indexWithinPeriod(int x, * \param[in] period The period, or 0 if not periodic. * \returns the interval length from origin to end. */ -double getIntervalLengthPeriodic(double origin, - double end, - double period) +double getIntervalLengthPeriodic(double origin, double end, double period) { double length = end - origin; if (length < 0) @@ -176,9 +173,7 @@ double getIntervalLengthPeriodic(double origin, * \param[in] period The period, or 0 if not periodic. * \returns the deviation from x to x0. */ -double getDeviationPeriodic(double x, - double x0, - double period) +double getDeviationPeriodic(double x, double x0, double period) { double dev = x - x0; @@ -190,12 +185,9 @@ double getDeviationPeriodic(double x, return dev; } -} // namespace +} // namespace -double getDeviationFromPointAlongGridAxis(const Grid &grid, - int dimIndex, - int pointIndex, - double value) +double getDeviationFromPointAlongGridAxis(const Grid& grid, int dimIndex, int pointIndex, double value) { double coordValue = grid.point(pointIndex).coordValue[dimIndex]; @@ -213,14 +205,12 @@ void linearArrayIndexToMultiDim(int indexLinear, int numDimensions, const awh_iv stride *= numPointsDim[k]; } - indexMulti[d] = indexLinear/stride; - indexLinear -= indexMulti[d]*stride; + indexMulti[d] = indexLinear / stride; + indexLinear -= indexMulti[d] * stride; } } -void linearGridindexToMultiDim(const Grid &grid, - int indexLinear, - awh_ivec indexMulti) +void linearGridindexToMultiDim(const Grid& grid, int indexLinear, awh_ivec indexMulti) { awh_ivec numPointsDim; const int numDimensions = grid.numDimensions(); @@ -233,16 +223,14 @@ void linearGridindexToMultiDim(const Grid &grid, } -int multiDimArrayIndexToLinear(const awh_ivec indexMulti, - int numDimensions, - const awh_ivec numPointsDim) +int multiDimArrayIndexToLinear(const awh_ivec indexMulti, int numDimensions, const awh_ivec numPointsDim) { int stride = 1; int indexLinear = 0; for (int d = numDimensions - 1; d >= 0; d--) { - indexLinear += stride*indexMulti[d]; - stride *= numPointsDim[d]; + indexLinear += stride * indexMulti[d]; + stride *= numPointsDim[d]; } return indexLinear; @@ -257,8 +245,7 @@ namespace * \param[in] indexMulti Multidimensional grid point index to convert to a linear one. * \returns the linear index. */ -int multiDimGridIndexToLinear(const std::vector &axis, - const awh_ivec indexMulti) +int multiDimGridIndexToLinear(const std::vector& axis, const awh_ivec indexMulti) { awh_ivec numPointsDim = { 0 }; @@ -270,10 +257,9 @@ int multiDimGridIndexToLinear(const std::vector &axis, return multiDimArrayIndexToLinear(indexMulti, axis.size(), numPointsDim); } -} // namespace +} // namespace -int multiDimGridIndexToLinear(const Grid &grid, - const awh_ivec indexMulti) +int multiDimGridIndexToLinear(const Grid& grid, const awh_ivec indexMulti) { return multiDimGridIndexToLinear(grid.axis(), indexMulti); } @@ -294,9 +280,7 @@ namespace * \param[in,out] indexDim Multidimensional index, each with values in [0, numPoints[d] - 1]. * \returns true if a step was taken, false if not. */ -bool stepInMultiDimArray(int numDim, - const awh_ivec numPoints, - awh_ivec indexDim) +bool stepInMultiDimArray(int numDim, const awh_ivec numPoints, awh_ivec indexDim) { bool haveStepped = false; @@ -342,23 +326,23 @@ bool stepInMultiDimArray(int numDim, * \param[in] point Grid point to get subgrid index for. * \param[in,out] subgridIndex Subgrid multidimensional index. */ -void gridToSubgridIndex(const Grid &grid, - const awh_ivec subgridOrigin, - const awh_ivec subgridNpoints, - int point, - awh_ivec subgridIndex) +void gridToSubgridIndex(const Grid& grid, + const awh_ivec subgridOrigin, + const awh_ivec subgridNpoints, + int point, + awh_ivec subgridIndex) { /* Get the subgrid index of the given grid point, for each dimension. */ for (int d = 0; d < grid.numDimensions(); d++) { /* The multidimensional grid point index relative to the subgrid origin. */ - subgridIndex[d] = - indexWithinPeriod(grid.point(point).index[d] - subgridOrigin[d], - grid.axis(d).numPointsInPeriod()); + subgridIndex[d] = indexWithinPeriod(grid.point(point).index[d] - subgridOrigin[d], + grid.axis(d).numPointsInPeriod()); /* The given point should be in the subgrid. */ GMX_RELEASE_ASSERT((subgridIndex[d] >= 0) && (subgridIndex[d] < subgridNpoints[d]), - "Attempted to convert an AWH grid point index not in subgrid to out of bounds subgrid index"); + "Attempted to convert an AWH grid point index not in subgrid to out of " + "bounds subgrid index"); } } @@ -375,10 +359,7 @@ void gridToSubgridIndex(const Grid &grid, * \param[in,out] gridIndex Grid point index. * \returns true if the transformation was successful. */ -bool subgridToGridIndex(const Grid &grid, - const awh_ivec subgridOrigin, - const awh_ivec subgridIndex, - int *gridIndex) +bool subgridToGridIndex(const Grid& grid, const awh_ivec subgridOrigin, const awh_ivec subgridIndex, int* gridIndex) { awh_ivec globalIndexDim; @@ -389,7 +370,7 @@ bool subgridToGridIndex(const Grid &grid, globalIndexDim[d] = subgridOrigin[d] + subgridIndex[d]; /* The local grid is allowed to stick out on the edges of the global grid. Here the boundary conditions are applied.*/ - if (globalIndexDim[d] < 0 || globalIndexDim[d] > grid.axis(d).numPoints() - 1) + if (globalIndexDim[d] < 0 || globalIndexDim[d] > grid.axis(d).numPoints() - 1) { /* Try to wrap around if periodic. Otherwise, the transformation failed so return. */ if (!grid.axis(d).isPeriodic()) @@ -434,12 +415,12 @@ bool subgridToGridIndex(const Grid &grid, return true; } -} // namespace +} // namespace -bool advancePointInSubgrid(const Grid &grid, - const awh_ivec subgridOrigin, - const awh_ivec subgridNumPoints, - int *gridPointIndex) +bool advancePointInSubgrid(const Grid& grid, + const awh_ivec subgridOrigin, + const awh_ivec subgridNumPoints, + int* gridPointIndex) { /* Initialize the subgrid index to the subgrid origin. */ awh_ivec subgridIndex = { 0 }; @@ -485,7 +466,7 @@ bool advancePointInSubgrid(const Grid &grid, * \param[in] x0 To value. * \returns (x - x0) in number of points. */ -static int pointDistanceAlongAxis(const GridAxis &axis, double x, double x0) +static int pointDistanceAlongAxis(const GridAxis& axis, double x, double x0) { int distance = 0; @@ -496,7 +477,7 @@ static int pointDistanceAlongAxis(const GridAxis &axis, double x, double x0) double dx = getDeviationPeriodic(x, x0, period); /* Transform the distance into a point distance by rounding. */ - distance = gmx::roundToInt(dx/axis.spacing()); + distance = gmx::roundToInt(dx / axis.spacing()); /* If periodic, shift the point distance to be in [0, period) */ distance = indexWithinPeriod(distance, axis.numPointsInPeriod()); @@ -512,8 +493,7 @@ static int pointDistanceAlongAxis(const GridAxis &axis, double x, double x0) * \param[in] axis The grid axes. * \returns true if the value is in the grid. */ -static bool valueIsInGrid(const awh_dvec value, - const std::vector &axis) +static bool valueIsInGrid(const awh_dvec value, const std::vector& axis) { /* For each dimension get the one-dimensional index and check if it is in range. */ for (size_t d = 0; d < axis.size(); d++) @@ -548,7 +528,7 @@ int GridAxis::nearestIndex(double value) const "Index not in periodic interval 0 for AWH periodic axis"); int endDistance = (index - (numPoints_ - 1)); int originDistance = (numPointsInPeriod_ - index); - index = originDistance < endDistance ? 0 : numPoints_ - 1; + index = originDistance < endDistance ? 0 : numPoints_ - 1; } else { @@ -566,8 +546,7 @@ int GridAxis::nearestIndex(double value) const * \param[in] axis The grid axes. * \returns the point index nearest to the value. */ -static int getNearestIndexInGrid(const awh_dvec value, - const std::vector &axis) +static int getNearestIndexInGrid(const awh_dvec value, const std::vector& axis) { awh_ivec indexMulti; @@ -598,23 +577,21 @@ namespace * \param[in] grid The grid. * \param[in,out] neighborIndexArray Array to fill with neighbor indices. */ -void setNeighborsOfGridPoint(int pointIndex, - const Grid &grid, - std::vector *neighborIndexArray) +void setNeighborsOfGridPoint(int pointIndex, const Grid& grid, std::vector* neighborIndexArray) { - const int c_maxNeighborsAlongAxis = 1 + 2*static_cast(Grid::c_numPointsPerSigma*Grid::c_scopeCutoff); + const int c_maxNeighborsAlongAxis = + 1 + 2 * static_cast(Grid::c_numPointsPerSigma * Grid::c_scopeCutoff); - awh_ivec numCandidates = {0}; - awh_ivec subgridOrigin = {0}; + awh_ivec numCandidates = { 0 }; + awh_ivec subgridOrigin = { 0 }; for (int d = 0; d < grid.numDimensions(); d++) { /* The number of candidate points along this dimension is given by the scope cutoff. */ - numCandidates[d] = std::min(c_maxNeighborsAlongAxis, - grid.axis(d).numPoints()); + numCandidates[d] = std::min(c_maxNeighborsAlongAxis, grid.axis(d).numPoints()); /* The origin of the subgrid to search */ int centerIndex = grid.point(pointIndex).index[d]; - subgridOrigin[d] = centerIndex - numCandidates[d]/2; + subgridOrigin[d] = centerIndex - numCandidates[d] / 2; } /* Find and set the neighbors */ @@ -634,12 +611,12 @@ void setNeighborsOfGridPoint(int pointIndex, } } -} // namespace +} // namespace void Grid::initPoints() { - awh_ivec numPointsDimWork = { 0 }; - awh_ivec indexWork = { 0 }; + awh_ivec numPointsDimWork = { 0 }; + awh_ivec indexWork = { 0 }; for (size_t d = 0; d < axis_.size(); d++) { @@ -647,11 +624,11 @@ void Grid::initPoints() numPointsDimWork[d] = axis_[d].numPoints(); } - for (auto &point : point_) + for (auto& point : point_) { for (size_t d = 0; d < axis_.size(); d++) { - point.coordValue[d] = axis_[d].origin() + indexWork[d]*axis_[d].spacing(); + point.coordValue[d] = axis_[d].origin() + indexWork[d] * axis_[d].spacing(); if (axis_[d].period() > 0) { @@ -666,8 +643,7 @@ void Grid::initPoints() } } -GridAxis::GridAxis(double origin, double end, - double period, double pointDensity) : +GridAxis::GridAxis(double origin, double end, double period, double pointDensity) : origin_(origin), period_(period) { @@ -687,7 +663,7 @@ GridAxis::GridAxis(double origin, double end, { /* An extra point is added here to account for the endpoints. The minimum number of points for a non-zero interval is 2. */ - numPoints_ = 1 + static_cast(std::ceil(length_*pointDensity)); + numPoints_ = 1 + static_cast(std::ceil(length_ * pointDensity)); } /* Set point spacing based on the number of points */ @@ -696,33 +672,31 @@ GridAxis::GridAxis(double origin, double end, /* Set the grid spacing so that a period is matched exactly by an integer number of points. The number of points in a period is equal to the number of grid spacings in a period since the endpoints are connected. */ - numPointsInPeriod_ = length_ > 0 ? static_cast(std::ceil(period/length_*(numPoints_ - 1))) : 1; - spacing_ = period_/numPointsInPeriod_; + numPointsInPeriod_ = + length_ > 0 ? static_cast(std::ceil(period / length_ * (numPoints_ - 1))) : 1; + spacing_ = period_ / numPointsInPeriod_; /* Modify the number of grid axis points to be compatible with the period dependent spacing. */ - numPoints_ = std::min(static_cast(round(length_/spacing_)) + 1, - numPointsInPeriod_); + numPoints_ = std::min(static_cast(round(length_ / spacing_)) + 1, numPointsInPeriod_); } else { numPointsInPeriod_ = 0; - spacing_ = numPoints_ > 1 ? length_/(numPoints_ - 1) : 0; + spacing_ = numPoints_ > 1 ? length_ / (numPoints_ - 1) : 0; } } -GridAxis::GridAxis(double origin, double end, - double period, int numPoints) : +GridAxis::GridAxis(double origin, double end, double period, int numPoints) : origin_(origin), period_(period), numPoints_(numPoints) { length_ = getIntervalLengthPeriodic(origin_, end, period_); - spacing_ = numPoints_ > 1 ? length_/(numPoints_ - 1) : period_; - numPointsInPeriod_ = static_cast(std::round(period_/spacing_)); + spacing_ = numPoints_ > 1 ? length_ / (numPoints_ - 1) : period_; + numPointsInPeriod_ = static_cast(std::round(period_ / spacing_)); } -Grid::Grid(const std::vector &dimParams, - const AwhDimParams *awhDimParams) +Grid::Grid(const std::vector& dimParams, const AwhDimParams* awhDimParams) { /* Define the discretization along each dimension */ awh_dvec period; @@ -732,8 +706,10 @@ Grid::Grid(const std::vector &dimParams, double origin = dimParams[d].scaleUserInputToInternal(awhDimParams[d].origin); double end = dimParams[d].scaleUserInputToInternal(awhDimParams[d].end); period[d] = dimParams[d].scaleUserInputToInternal(awhDimParams[d].period); - static_assert(c_numPointsPerSigma >= 1.0, "The number of points per sigma should be at least 1.0 to get a uniformly covering the reaction using Gaussians"); - double pointDensity = std::sqrt(dimParams[d].betak)*c_numPointsPerSigma; + static_assert(c_numPointsPerSigma >= 1.0, + "The number of points per sigma should be at least 1.0 to get a uniformly " + "covering the reaction using Gaussians"); + double pointDensity = std::sqrt(dimParams[d].betak) * c_numPointsPerSigma; axis_.emplace_back(origin, end, period[d], pointDensity); numPoints *= axis_[d].numPoints(); } @@ -749,18 +725,18 @@ Grid::Grid(const std::vector &dimParams, */ for (size_t m = 0; m < point_.size(); m++) { - std::vector *neighbor = &point_[m].neighbor; + std::vector* neighbor = &point_[m].neighbor; setNeighborsOfGridPoint(m, *this, neighbor); } } -void mapGridToDataGrid(std::vector *gridpointToDatapoint, - const double* const *data, +void mapGridToDataGrid(std::vector* gridpointToDatapoint, + const double* const* data, int numDataPoints, - const std::string &dataFilename, - const Grid &grid, - const std::string &correctFormatMessage) + const std::string& dataFilename, + const Grid& grid, + const std::string& correctFormatMessage) { /* Transform the data into a grid in order to map each grid point to a data point using the grid functions. */ @@ -778,25 +754,25 @@ void mapGridToDataGrid(std::vector *gridpointToDatapoint, do { numPointsInDim++; - pointIndex += stride; - } - while (pointIndex < numDataPoints && - !gmx_within_tol(firstValue, data[d][pointIndex], GMX_REAL_EPS)); + pointIndex += stride; + } while (pointIndex < numDataPoints + && !gmx_within_tol(firstValue, data[d][pointIndex], GMX_REAL_EPS)); /* The stride in dimension dimension d - 1 equals the number of points dimension d. */ stride = numPointsInDim; - numPointsCounted = (numPointsCounted == 0) ? numPointsInDim : numPointsCounted*numPointsInDim; + numPointsCounted = (numPointsCounted == 0) ? numPointsInDim : numPointsCounted * numPointsInDim; - numPoints[d] = numPointsInDim; + numPoints[d] = numPointsInDim; } if (numPointsCounted != numDataPoints) { - std::string mesg = gmx::formatString("Could not extract data properly from %s. Wrong data format?" - "\n\n%s", - dataFilename.c_str(), correctFormatMessage.c_str()); + std::string mesg = gmx::formatString( + "Could not extract data properly from %s. Wrong data format?" + "\n\n%s", + dataFilename.c_str(), correctFormatMessage.c_str()); GMX_THROW(InvalidInputError(mesg)); } @@ -805,8 +781,7 @@ void mapGridToDataGrid(std::vector *gridpointToDatapoint, /* The data grid has the data that was read and the properties of the AWH grid */ for (int d = 0; d < grid.numDimensions(); d++) { - axis_.emplace_back(data[d][0], data[d][numDataPoints - 1], - grid.axis(d).period(), numPoints[d]); + axis_.emplace_back(data[d][0], data[d][numDataPoints - 1], grid.axis(d).period(), numPoints[d]); } /* Map each grid point to a data point. No interpolation, just pick the nearest one. @@ -818,11 +793,11 @@ void mapGridToDataGrid(std::vector *gridpointToDatapoint, if (!valueIsInGrid(grid.point(m).coordValue, axis_)) { - std::string mesg = - gmx::formatString("%s does not contain data for all coordinate values. " - "Make sure your input data covers the whole sampling domain " - "and is correctly formatted. \n\n%s", - dataFilename.c_str(), correctFormatMessage.c_str()); + std::string mesg = gmx::formatString( + "%s does not contain data for all coordinate values. " + "Make sure your input data covers the whole sampling domain " + "and is correctly formatted. \n\n%s", + dataFilename.c_str(), correctFormatMessage.c_str()); GMX_THROW(InvalidInputError(mesg)); } (*gridpointToDatapoint)[m] = getNearestIndexInGrid(grid.point(m).coordValue, axis_); diff --git a/src/gromacs/awh/grid.h b/src/gromacs/awh/grid.h index b212b866cd..70e58d18cd 100644 --- a/src/gromacs/awh/grid.h +++ b/src/gromacs/awh/grid.h @@ -69,116 +69,93 @@ struct AwhDimParams; */ class GridAxis { - public: - /*! \brief Constructor. - * - * The spacing and number of points are set such that we have - * at least the requested point density. - * Requesting 0 point density results in the minimum number - * of points (2). - * - * \param[in] origin Starting value. - * \param[in] end End value. - * \param[in] period Period, pass 0 if not periodic. - * \param[in] pointDensity Requested number of point per unit of axis length. - */ - GridAxis(double origin, double end, - double period, double pointDensity); - - /*! \brief Constructor. - * - * \param[in] origin Starting value. - * \param[in] end End value. - * \param[in] period Period, pass 0 if not periodic. - * \param[in] numPoints The number of points. - */ - GridAxis(double origin, double end, - double period, int numPoints); - - /*! \brief Returns if the axis has periodic boundaries. - */ - bool isPeriodic() const - { - return period_ > 0; - } - - /*! \brief Returns the period of the grid along the axis. - */ - double period() const - { - return period_; - } - - /*! \brief Returns the grid origin along the axis. - */ - double origin() const - { - return origin_; - } - - /*! \brief Returns the grid point spacing along the axis. - */ - double spacing() const - { - return spacing_; - } - - /*! \brief Returns the number of grid points along the axis. - */ - int numPoints() const - { - return numPoints_; - } - - /*! \brief Returns the period of the grid in points along the axis. - * - * Returns 0 if the axis is not periodic. - */ - int numPointsInPeriod() const - { - return numPointsInPeriod_; - } - - /*! \brief Returns the length of the interval. - * - * This returns the distance obtained by connecting the origin point to - * the end point in the positive direction. Note that this is generally - * not the shortest distance. For period > 0, both origin and - * end are expected to take values in the same periodic interval. - */ - double length() const - { - return length_; - } - - /*! \brief Map a value to the nearest point index along an axis. - * - * \param[in] value Value along the axis. - * \returns the index nearest to the value. - */ - int nearestIndex(double value) const; - - private: - double origin_; /**< Interval start value */ - double length_; /**< Interval length */ - double period_; /**< The period, 0 if not periodic */ - double spacing_; /**< Point spacing */ - int numPoints_; /**< Number of points in the interval */ - int numPointsInPeriod_; /**< Number of points in a period (0 if no periodicity) */ +public: + /*! \brief Constructor. + * + * The spacing and number of points are set such that we have + * at least the requested point density. + * Requesting 0 point density results in the minimum number + * of points (2). + * + * \param[in] origin Starting value. + * \param[in] end End value. + * \param[in] period Period, pass 0 if not periodic. + * \param[in] pointDensity Requested number of point per unit of axis length. + */ + GridAxis(double origin, double end, double period, double pointDensity); + + /*! \brief Constructor. + * + * \param[in] origin Starting value. + * \param[in] end End value. + * \param[in] period Period, pass 0 if not periodic. + * \param[in] numPoints The number of points. + */ + GridAxis(double origin, double end, double period, int numPoints); + + /*! \brief Returns if the axis has periodic boundaries. + */ + bool isPeriodic() const { return period_ > 0; } + + /*! \brief Returns the period of the grid along the axis. + */ + double period() const { return period_; } + + /*! \brief Returns the grid origin along the axis. + */ + double origin() const { return origin_; } + + /*! \brief Returns the grid point spacing along the axis. + */ + double spacing() const { return spacing_; } + + /*! \brief Returns the number of grid points along the axis. + */ + int numPoints() const { return numPoints_; } + + /*! \brief Returns the period of the grid in points along the axis. + * + * Returns 0 if the axis is not periodic. + */ + int numPointsInPeriod() const { return numPointsInPeriod_; } + + /*! \brief Returns the length of the interval. + * + * This returns the distance obtained by connecting the origin point to + * the end point in the positive direction. Note that this is generally + * not the shortest distance. For period > 0, both origin and + * end are expected to take values in the same periodic interval. + */ + double length() const { return length_; } + + /*! \brief Map a value to the nearest point index along an axis. + * + * \param[in] value Value along the axis. + * \returns the index nearest to the value. + */ + int nearestIndex(double value) const; + +private: + double origin_; /**< Interval start value */ + double length_; /**< Interval length */ + double period_; /**< The period, 0 if not periodic */ + double spacing_; /**< Point spacing */ + int numPoints_; /**< Number of points in the interval */ + int numPointsInPeriod_; /**< Number of points in a period (0 if no periodicity) */ }; /*! \internal * \brief A point in the grid. * - * A grid point has a coordinate value and a coordinate index of the same dimensionality as the grid. - * It knows the linear indices of its neighboring point (which are useful only when handed up to - * the grid). + * A grid point has a coordinate value and a coordinate index of the same dimensionality as the + * grid. It knows the linear indices of its neighboring point (which are useful only when handed up + * to the grid). */ struct GridPoint { - awh_dvec coordValue; /**< Multidimensional coordinate value of this point */ - awh_ivec index; /**< Multidimensional point indices */ - std::vector neighbor; /**< Linear point indices of the neighboring points */ + awh_dvec coordValue; /**< Multidimensional coordinate value of this point */ + awh_ivec index; /**< Multidimensional point indices */ + std::vector neighbor; /**< Linear point indices of the neighboring points */ }; /*! \internal @@ -190,95 +167,79 @@ struct GridPoint */ class Grid { - private: - /*! \brief Initializes the grid points. - */ - void initPoints(); - - public: - /*! \brief - * The point density per sigma of the Gaussian distribution in an umbrella. - * - * This value should be at least 1 to uniformly cover the reaction coordinate - * range with density and having it larger than 1 does not add information. - */ - static constexpr double c_numPointsPerSigma = 1.0; - - //! Cut-off in sigma for considering points, neglects 4e-8 of the density. - static constexpr double c_scopeCutoff = 5.5; - - /*! \brief Construct a grid using AWH input parameters. - * - * \param[in] dimParams Dimension parameters including the expected inverse variance of the coordinate living on the grid (determines the grid spacing). - * \param[in] awhDimParams Dimension params from inputrec. - */ - Grid(const std::vector &dimParams, - const AwhDimParams *awhDimParams); - - /*! \brief Returns the number of points in the grid. - * - * \returns the number of points in the grid. - */ - size_t numPoints() const - { - return point_.size(); - } - - /*! \brief Returns a reference to a point on the grid. - * - * \returns a constant reference to a point on the grid. - */ - const GridPoint &point(size_t pointIndex) const - { - return point_[pointIndex]; - } - - /*! \brief Returns the dimensionality of the grid. - * - * \returns the dimensionality of the grid. - */ - int numDimensions() const - { - return axis_.size(); - } - - /*! \brief Returns the grid axes. - * - * \returns a constant reference to the grid axes. - */ - const std::vector &axis() const - { - return axis_; - } - - /*! \brief Returns a grid axis. - * - * param[in] dim Dimension to return the grid axis for. - * \returns a constant reference to the grid axis. - */ - const GridAxis &axis(int dim) const - { - return axis_[dim]; - } - - /*! \brief Find the grid point with value nearest to the given value. - * - * \param[in] value Value vector. - * \returns the grid point index. - */ - int nearestIndex(const awh_dvec value) const; - - /*! \brief Query if the value is in the grid. - * - * \param[in] value Value vector. - * \returns true if the value is in the grid. - * \note It is assumed that any periodicity of value has already been taken care of. - */ - bool covers(const awh_dvec value) const; - - private: - std::vector point_; /**< Points on the grid */ - std::vector axis_; /**< Axes, one for each dimension. */ +private: + /*! \brief Initializes the grid points. + */ + void initPoints(); + +public: + /*! \brief + * The point density per sigma of the Gaussian distribution in an umbrella. + * + * This value should be at least 1 to uniformly cover the reaction coordinate + * range with density and having it larger than 1 does not add information. + */ + static constexpr double c_numPointsPerSigma = 1.0; + + //! Cut-off in sigma for considering points, neglects 4e-8 of the density. + static constexpr double c_scopeCutoff = 5.5; + + /*! \brief Construct a grid using AWH input parameters. + * + * \param[in] dimParams Dimension parameters including the expected inverse variance of the coordinate living on the grid (determines the grid spacing). + * \param[in] awhDimParams Dimension params from inputrec. + */ + Grid(const std::vector& dimParams, const AwhDimParams* awhDimParams); + + /*! \brief Returns the number of points in the grid. + * + * \returns the number of points in the grid. + */ + size_t numPoints() const { return point_.size(); } + + /*! \brief Returns a reference to a point on the grid. + * + * \returns a constant reference to a point on the grid. + */ + const GridPoint& point(size_t pointIndex) const { return point_[pointIndex]; } + + /*! \brief Returns the dimensionality of the grid. + * + * \returns the dimensionality of the grid. + */ + int numDimensions() const { return axis_.size(); } + + /*! \brief Returns the grid axes. + * + * \returns a constant reference to the grid axes. + */ + const std::vector& axis() const { return axis_; } + + /*! \brief Returns a grid axis. + * + * param[in] dim Dimension to return the grid axis for. + * \returns a constant reference to the grid axis. + */ + const GridAxis& axis(int dim) const { return axis_[dim]; } + + /*! \brief Find the grid point with value nearest to the given value. + * + * \param[in] value Value vector. + * \returns the grid point index. + */ + int nearestIndex(const awh_dvec value) const; + + /*! \brief Query if the value is in the grid. + * + * \param[in] value Value vector. + * \returns true if the value is in the grid. + * \note It is assumed that any periodicity of value has already been taken care of. + */ + bool covers(const awh_dvec value) const; + +private: + std::vector point_; /**< Points on the grid */ + std::vector axis_; /**< Axes, one for each dimension. */ }; /*! \endcond */ @@ -289,7 +250,7 @@ class Grid * \param[in] indexMulti Multidimensional grid point index to convert to a linear one. * \returns the linear index. */ -int multiDimGridIndexToLinear(const Grid &grid, const awh_ivec indexMulti); +int multiDimGridIndexToLinear(const Grid& grid, const awh_ivec indexMulti); /*! \brief Convert multidimensional array index to a linear one. * @@ -299,9 +260,7 @@ int multiDimGridIndexToLinear(const Grid &grid, const awh_ivec indexMulti); * \returns the linear index. * \note This function can be used without having an initialized grid. */ -int multiDimArrayIndexToLinear(const awh_ivec indexMulti, - int numDim, - const awh_ivec numPointsDim); +int multiDimArrayIndexToLinear(const awh_ivec indexMulti, int numDim, const awh_ivec numPointsDim); /*! \brief Convert a linear grid point index to a multidimensional one. * @@ -309,9 +268,7 @@ int multiDimArrayIndexToLinear(const awh_ivec indexMulti, * \param[in] indexLinear Linear grid point index to convert to a multidimensional one. * \param[out] indexMulti The multidimensional index. */ -void linearGridindexToMultiDim(const Grid &grid, - int indexLinear, - awh_ivec indexMulti); +void linearGridindexToMultiDim(const Grid& grid, int indexLinear, awh_ivec indexMulti); /*! \brief Convert a linear array index to a multidimensional one. * @@ -320,10 +277,7 @@ void linearGridindexToMultiDim(const Grid &grid, * \param[in] numPointsDim Number of points for each dimension. * \param[out] indexMulti The multidimensional index. */ -void linearArrayIndexToMultiDim(int indexLinear, - int ndim, - const awh_ivec numPointsDim, - awh_ivec indexMulti); +void linearArrayIndexToMultiDim(int indexLinear, int ndim, const awh_ivec numPointsDim, awh_ivec indexMulti); /*! \brief * Find the next grid point in the sub-part of the grid given a starting point. @@ -344,10 +298,10 @@ void linearArrayIndexToMultiDim(int indexLinear, * \param[in,out] gridPointIndex Pointer to the starting/next grid point index. * \returns true if the grid point was updated. */ -bool advancePointInSubgrid(const Grid &grid, - const awh_ivec subgridOrigin, - const awh_ivec subgridNpoints, - int *gridPointIndex); +bool advancePointInSubgrid(const Grid& grid, + const awh_ivec subgridOrigin, + const awh_ivec subgridNpoints, + int* gridPointIndex); /*! \brief Maps each point in the grid to a point in the data grid. * @@ -363,12 +317,12 @@ bool advancePointInSubgrid(const Grid &grid, * \param[in] grid The grid. * \param[in] correctFormatMessage String to include in error message if extracting the data fails. */ -void mapGridToDataGrid(std::vector *gridpointToDatapoint, - const double* const *data, +void mapGridToDataGrid(std::vector* gridpointToDatapoint, + const double* const* data, int numDataPoints, - const std::string &dataFilename, - const Grid &grid, - const std::string &correctFormatMessage); + const std::string& dataFilename, + const Grid& grid, + const std::string& correctFormatMessage); /*! \brief * Get the deviation along one dimension from the given value to a point in the grid. @@ -379,10 +333,7 @@ void mapGridToDataGrid(std::vector *gridpointToDatapoint, * \param[in] value Value along the given dimension. * \returns the deviation of the given value to the given point. */ -double getDeviationFromPointAlongGridAxis(const Grid &grid, - int dimIndex, - int pointIndex, - double value); +double getDeviationFromPointAlongGridAxis(const Grid& grid, int dimIndex, int pointIndex, double value); } // namespace gmx diff --git a/src/gromacs/awh/histogramsize.cpp b/src/gromacs/awh/histogramsize.cpp index d732dd86e2..f405685d74 100644 --- a/src/gromacs/awh/histogramsize.cpp +++ b/src/gromacs/awh/histogramsize.cpp @@ -63,8 +63,7 @@ namespace gmx { -HistogramSize::HistogramSize(const AwhBiasParams &awhBiasParams, - double histogramSizeInitial) : +HistogramSize::HistogramSize(const AwhBiasParams& awhBiasParams, double histogramSizeInitial) : numUpdates_(0), histogramSize_(histogramSizeInitial), inInitialStage_(awhBiasParams.eGrowth == eawhgrowthEXP_LINEAR), @@ -75,17 +74,15 @@ HistogramSize::HistogramSize(const AwhBiasParams &awhBiasParams, { } -double HistogramSize::newHistogramSizeInitialStage(const BiasParams ¶ms, +double HistogramSize::newHistogramSizeInitialStage(const BiasParams& params, double t, bool detectedCovering, ArrayRef weightsumCovering, - FILE *fplog) + FILE* fplog) { /* The histogram size is kept constant until the sampling region has been covered and the current sample weight is large enough and the histogram is ready. */ - if (!detectedCovering || - (logScaledSampleWeight_ < maxLogScaledSampleWeight_) || - equilibrateHistogram_) + if (!detectedCovering || (logScaledSampleWeight_ < maxLogScaledSampleWeight_) || equilibrateHistogram_) { return histogramSize_; } @@ -97,7 +94,7 @@ double HistogramSize::newHistogramSizeInitialStage(const BiasParams ¶ms, /* The current sample weigth is now the maximum. */ double prevMaxLogScaledSampleWeight = maxLogScaledSampleWeight_; - maxLogScaledSampleWeight_ = logScaledSampleWeight_; + maxLogScaledSampleWeight_ = logScaledSampleWeight_; /* Increase the histogram size by a constant scale factor if we can, i.e. if the sample weight resulting from such a scaling is still larger than the previous maximum sample weight @@ -109,10 +106,12 @@ double HistogramSize::newHistogramSizeInitialStage(const BiasParams ¶ms, static const double growthFactor = 3; /* The scale factor is in most cases very close to the histogram growth factor. */ - double scaleFactor = growthFactor/(1. + params.updateWeight*params.localWeightScaling/histogramSize_); + double scaleFactor = + growthFactor / (1. + params.updateWeight * params.localWeightScaling / histogramSize_); - bool exitInitialStage = (logScaledSampleWeight_ - std::log(scaleFactor) <= prevMaxLogScaledSampleWeight); - double newHistogramSize = exitInitialStage ? histogramSize_ : histogramSize_*growthFactor; + bool exitInitialStage = + (logScaledSampleWeight_ - std::log(scaleFactor) <= prevMaxLogScaledSampleWeight); + double newHistogramSize = exitInitialStage ? histogramSize_ : histogramSize_ * growthFactor; /* Update the AWH bias about the exit. */ inInitialStage_ = !exitInitialStage; @@ -150,12 +149,12 @@ namespace * \param[in] pointStates The state of the bias points. * \returns true if the histogram is equilibrated. */ -bool histogramIsEquilibrated(const std::vector &pointStates) +bool histogramIsEquilibrated(const std::vector& pointStates) { /* Get the total weight of the total weight histogram; needed for normalization. */ double totalWeight = 0; int numTargetPoints = 0; - for (auto &pointState : pointStates) + for (auto& pointState : pointStates) { if (!pointState.inTargetRegion()) { @@ -165,22 +164,22 @@ bool histogramIsEquilibrated(const std::vector &pointStates) numTargetPoints++; } GMX_RELEASE_ASSERT(totalWeight > 0, "No samples when normalizing AWH histogram."); - double inverseTotalWeight = 1./totalWeight; + double inverseTotalWeight = 1. / totalWeight; /* Points with target weight below a certain cutoff are ignored. */ - static const double minTargetCutoff = 0.05; - double minTargetWeight = 1./numTargetPoints*minTargetCutoff; + static const double minTargetCutoff = 0.05; + double minTargetWeight = 1. / numTargetPoints * minTargetCutoff; /* Points with error less than this tolerance pass the check.*/ - static const double errorTolerance = 0.2; + static const double errorTolerance = 0.2; /* Sum up weight of points that do or don't pass the check. */ double equilibratedWeight = 0; double notEquilibratedWeight = 0; - for (auto &pointState : pointStates) + for (auto& pointState : pointStates) { double targetWeight = pointState.target(); - double sampledWeight = pointState.weightSumTot()*inverseTotalWeight; + double sampledWeight = pointState.weightSumTot() * inverseTotalWeight; /* Ignore these points. */ if (!pointState.inTargetRegion() || targetWeight < minTargetWeight) @@ -188,7 +187,7 @@ bool histogramIsEquilibrated(const std::vector &pointStates) continue; } - if (std::abs(sampledWeight/targetWeight - 1) > errorTolerance) + if (std::abs(sampledWeight / targetWeight - 1) > errorTolerance) { notEquilibratedWeight += targetWeight; } @@ -202,17 +201,17 @@ bool histogramIsEquilibrated(const std::vector &pointStates) distribution. Boundaries will in general fail and this should be ignored (to some extent). */ static const double minFraction = 0.8; - return equilibratedWeight/(equilibratedWeight + notEquilibratedWeight) > minFraction;; + return equilibratedWeight / (equilibratedWeight + notEquilibratedWeight) > minFraction; } -} // namespace +} // namespace -double HistogramSize::newHistogramSize(const BiasParams ¶ms, +double HistogramSize::newHistogramSize(const BiasParams& params, double t, bool covered, - const std::vector &pointStates, + const std::vector& pointStates, ArrayRef weightsumCovering, - FILE *fplog) + FILE* fplog) { double newHistogramSize; if (inInitialStage_) @@ -232,7 +231,8 @@ double HistogramSize::newHistogramSize(const BiasParams ¶ms, } else if (!havePrintedAboutCovering_) { - fprintf(fplog, "%s covered but histogram not equilibrated at t = %g ps.\n", prefix.c_str(), t); + fprintf(fplog, "%s covered but histogram not equilibrated at t = %g ps.\n", + prefix.c_str(), t); havePrintedAboutCovering_ = true; /* Just print once. */ } } @@ -244,14 +244,13 @@ double HistogramSize::newHistogramSize(const BiasParams ¶ms, else { /* If not in the initial stage, the histogram grows at a linear, possibly scaled down, rate. */ - newHistogramSize = histogramSize_ + params.updateWeight*params.localWeightScaling; + newHistogramSize = histogramSize_ + params.updateWeight * params.localWeightScaling; } return newHistogramSize; } -void HistogramSize::setHistogramSize(double histogramSize, - double weightHistogramScalingFactor) +void HistogramSize::setHistogramSize(double histogramSize, double weightHistogramScalingFactor) { GMX_ASSERT(histogramSize > 0, "The histogram should not be empty"); GMX_ASSERT(weightHistogramScalingFactor > 0, "The histogram scaling factor should be positive"); @@ -265,7 +264,7 @@ void HistogramSize::setHistogramSize(double histogramSize, logScaledSampleWeight_ -= std::log(weightHistogramScalingFactor); }; -void HistogramSize::restoreFromHistory(const AwhBiasStateHistory &stateHistory) +void HistogramSize::restoreFromHistory(const AwhBiasStateHistory& stateHistory) { numUpdates_ = stateHistory.numUpdates; histogramSize_ = stateHistory.histSize; @@ -276,7 +275,7 @@ void HistogramSize::restoreFromHistory(const AwhBiasStateHistory &stateHistory) havePrintedAboutCovering_ = false; } -void HistogramSize::storeState(AwhBiasStateHistory *stateHistory) const +void HistogramSize::storeState(AwhBiasStateHistory* stateHistory) const { stateHistory->numUpdates = numUpdates_; stateHistory->histSize = histogramSize_; diff --git a/src/gromacs/awh/histogramsize.h b/src/gromacs/awh/histogramsize.h index 112fdbc999..7fb3a21ce9 100644 --- a/src/gromacs/awh/histogramsize.h +++ b/src/gromacs/awh/histogramsize.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,127 +79,110 @@ class PointState; */ class HistogramSize { - public: - /*! \brief Constructor. - * - * \param[in] awhBiasParams The Bias parameters from inputrec. - * \param[in] histogramSizeInitial The initial histogram size. - */ - HistogramSize(const AwhBiasParams &awhBiasParams, - double histogramSizeInitial); - - private: - /*! \brief - * Returns the new size of the reference weight histogram in the initial stage. - * - * This function also takes care resetting the histogram used for covering checks - * and for exiting the initial stage. - * - * \param[in] params The bias parameters. - * \param[in] t Time. - * \param[in] detectedCovering True if we detected that the sampling interval has been sufficiently covered. - * \param[in,out] weightsumCovering The weight sum for checking covering. - * \param[in,out] fplog Log file. - * \returns the new histogram size. - */ - double newHistogramSizeInitialStage(const BiasParams ¶ms, - double t, - bool detectedCovering, - ArrayRef weightsumCovering, - FILE *fplog); - - public: - /*! \brief - * Return the new reference weight histogram size for the current update. - * - * This function also takes care of checking for covering in the initial stage. - * - * \param[in] params The bias parameters. - * \param[in] t Time. - * \param[in] covered True if the sampling interval has been covered enough. - * \param[in] pointStates The state of the grid points. - * \param[in,out] weightsumCovering The weight sum for checking covering. - * \param[in,out] fplog Log file. - * \returns the new histogram size. - */ - double newHistogramSize(const BiasParams ¶ms, - double t, - bool covered, - const std::vector &pointStates, - ArrayRef weightsumCovering, - FILE *fplog); - - /*! \brief Restores the histogram size from history. - * - * \param[in] stateHistory The AWH bias state history. - */ - void restoreFromHistory(const AwhBiasStateHistory &stateHistory); - - /*! \brief Store the histogram size state in a history struct. - * - * \param[in,out] stateHistory The AWH bias state history. - */ - void storeState(AwhBiasStateHistory *stateHistory) const; - - /*! \brief Returns the number of updates since the start of the simulation. - */ - int numUpdates() const - { - return numUpdates_; - } - - /*! \brief Increments the number of updates by 1. - */ - void incrementNumUpdates() - { - numUpdates_ += 1; - } - - /*! \brief Returns the histogram size. - */ - double histogramSize() const - { - return histogramSize_; - } - - /*! \brief Sets the histogram size. - * - * \param[in] histogramSize The new histogram size. - * \param[in] weightHistogramScalingFactor The factor to scale the weight by. - */ - void setHistogramSize(double histogramSize, - double weightHistogramScalingFactor); - - /*! \brief Returns true if we are in the initial stage of the AWH method. - */ - bool inInitialStage() const - { - return inInitialStage_; - } - - /*! \brief Returns The log of the current sample weight, scaled because of the histogram rescaling. - */ - double logScaledSampleWeight() const - { - return logScaledSampleWeight_; - } - - private: - int64_t numUpdates_; /**< The number of updates performed since the start of the simulation. */ - - /* The histogram size sets the update size and so controls the convergence rate of the free energy and bias. */ - double histogramSize_; /**< Size of reference weight histogram. */ - - /* Values that control the evolution of the histogram size. */ - bool inInitialStage_; /**< True if in the intial stage. */ - bool equilibrateHistogram_; /**< True if samples are kept from accumulating until the sampled distribution is close enough to the target. */ - double logScaledSampleWeight_; /**< The log of the current sample weight, scaled because of the histogram rescaling. */ - double maxLogScaledSampleWeight_; /**< Maximum sample weight obtained for previous (smaller) histogram sizes. */ - - /* Bool to avoid printing multiple, not so useful, messages to log */ - bool havePrintedAboutCovering_; /**< True if we have printed about covering to the log while equilibrateHistogram==true */ +public: + /*! \brief Constructor. + * + * \param[in] awhBiasParams The Bias parameters from inputrec. + * \param[in] histogramSizeInitial The initial histogram size. + */ + HistogramSize(const AwhBiasParams& awhBiasParams, double histogramSizeInitial); + +private: + /*! \brief + * Returns the new size of the reference weight histogram in the initial stage. + * + * This function also takes care resetting the histogram used for covering checks + * and for exiting the initial stage. + * + * \param[in] params The bias parameters. + * \param[in] t Time. + * \param[in] detectedCovering True if we detected that the sampling interval has been + * sufficiently covered. \param[in,out] weightsumCovering The weight sum for checking covering. + * \param[in,out] fplog Log file. + * \returns the new histogram size. + */ + double newHistogramSizeInitialStage(const BiasParams& params, + double t, + bool detectedCovering, + ArrayRef weightsumCovering, + FILE* fplog); + +public: + /*! \brief + * Return the new reference weight histogram size for the current update. + * + * This function also takes care of checking for covering in the initial stage. + * + * \param[in] params The bias parameters. + * \param[in] t Time. + * \param[in] covered True if the sampling interval has been covered enough. + * \param[in] pointStates The state of the grid points. + * \param[in,out] weightsumCovering The weight sum for checking covering. + * \param[in,out] fplog Log file. + * \returns the new histogram size. + */ + double newHistogramSize(const BiasParams& params, + double t, + bool covered, + const std::vector& pointStates, + ArrayRef weightsumCovering, + FILE* fplog); + + /*! \brief Restores the histogram size from history. + * + * \param[in] stateHistory The AWH bias state history. + */ + void restoreFromHistory(const AwhBiasStateHistory& stateHistory); + + /*! \brief Store the histogram size state in a history struct. + * + * \param[in,out] stateHistory The AWH bias state history. + */ + void storeState(AwhBiasStateHistory* stateHistory) const; + + /*! \brief Returns the number of updates since the start of the simulation. + */ + int numUpdates() const { return numUpdates_; } + + /*! \brief Increments the number of updates by 1. + */ + void incrementNumUpdates() { numUpdates_ += 1; } + + /*! \brief Returns the histogram size. + */ + double histogramSize() const { return histogramSize_; } + + /*! \brief Sets the histogram size. + * + * \param[in] histogramSize The new histogram size. + * \param[in] weightHistogramScalingFactor The factor to scale the weight by. + */ + void setHistogramSize(double histogramSize, double weightHistogramScalingFactor); + + /*! \brief Returns true if we are in the initial stage of the AWH method. + */ + bool inInitialStage() const { return inInitialStage_; } + + /*! \brief Returns The log of the current sample weight, scaled because of the histogram rescaling. + */ + double logScaledSampleWeight() const { return logScaledSampleWeight_; } + +private: + int64_t numUpdates_; /**< The number of updates performed since the start of the simulation. */ + + /* The histogram size sets the update size and so controls the convergence rate of the free energy and bias. */ + double histogramSize_; /**< Size of reference weight histogram. */ + + /* Values that control the evolution of the histogram size. */ + bool inInitialStage_; /**< True if in the intial stage. */ + bool equilibrateHistogram_; /**< True if samples are kept from accumulating until the sampled distribution is close enough to the target. */ + double logScaledSampleWeight_; /**< The log of the current sample weight, scaled because of the histogram rescaling. */ + double maxLogScaledSampleWeight_; /**< Maximum sample weight obtained for previous (smaller) histogram sizes. */ + + /* Bool to avoid printing multiple, not so useful, messages to log */ + bool havePrintedAboutCovering_; /**< True if we have printed about covering to the log while equilibrateHistogram==true */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_HISTOGRAMSIZE_H */ diff --git a/src/gromacs/awh/pointstate.cpp b/src/gromacs/awh/pointstate.cpp index 67d312ff35..5878860cb8 100644 --- a/src/gromacs/awh/pointstate.cpp +++ b/src/gromacs/awh/pointstate.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,19 +58,18 @@ namespace * \param[in] b Second exponent. * \returns c. */ -double expSum(double a, - double b) +double expSum(double a, double b) { return (a > b ? a : b) + std::log1p(std::exp(-std::fabs(a - b))); } -} // namespace +} // namespace void PointState::samplePmf(double convolvedBias) { if (inTargetRegion()) { - logPmfSum_ = expSum(logPmfSum_, -convolvedBias); + logPmfSum_ = expSum(logPmfSum_, -convolvedBias); numVisitsIteration_ += 1; } } diff --git a/src/gromacs/awh/pointstate.h b/src/gromacs/awh/pointstate.h index 4e177c42c9..a66a6371c2 100644 --- a/src/gromacs/awh/pointstate.h +++ b/src/gromacs/awh/pointstate.h @@ -68,9 +68,9 @@ namespace detail constexpr double c_largeNegativeExponent = -10000.0; //! The largest acceptable positive exponent for variables that are passed to exp(). -constexpr double c_largePositiveExponent = 700.0; +constexpr double c_largePositiveExponent = 700.0; -} // namepace detail +} // namespace detail /*! \internal * \brief The state of a coordinate point. @@ -80,442 +80,393 @@ constexpr double c_largePositiveExponent = 700.0; */ class PointState { - public: - /*! \brief Constructs a point state with default values. */ - PointState() : bias_(0), - freeEnergy_(0), - target_(1), - targetConstantWeight_(1), - weightSumIteration_(0), - weightSumTot_(0), - weightSumRef_(1), - lastUpdateIndex_(0), - logPmfSum_(0), - numVisitsIteration_(0), - numVisitsTot_(0) +public: + /*! \brief Constructs a point state with default values. */ + PointState() : + bias_(0), + freeEnergy_(0), + target_(1), + targetConstantWeight_(1), + weightSumIteration_(0), + weightSumTot_(0), + weightSumRef_(1), + lastUpdateIndex_(0), + logPmfSum_(0), + numVisitsIteration_(0), + numVisitsTot_(0) + { + } + + /*! \brief + * Set all values in the state to those from a history. + * + * \param[in] psh Coordinate point history to copy from. + */ + void setFromHistory(const AwhPointStateHistory& psh) + { + target_ = psh.target; + freeEnergy_ = psh.free_energy; + bias_ = psh.bias; + weightSumIteration_ = psh.weightsum_iteration; + weightSumTot_ = psh.weightsum_tot; + weightSumRef_ = psh.weightsum_ref; + lastUpdateIndex_ = psh.last_update_index; + logPmfSum_ = psh.log_pmfsum; + numVisitsIteration_ = psh.visits_iteration; + numVisitsTot_ = psh.visits_tot; + } + + /*! \brief + * Store the state of a point in a history struct. + * + * \param[in,out] psh Coordinate point history to copy to. + */ + void storeState(AwhPointStateHistory* psh) const + { + psh->target = target_; + psh->free_energy = freeEnergy_; + psh->bias = bias_; + psh->weightsum_iteration = weightSumIteration_; + psh->weightsum_tot = weightSumTot_; + psh->weightsum_ref = weightSumRef_; + psh->last_update_index = lastUpdateIndex_; + psh->log_pmfsum = logPmfSum_; + psh->visits_iteration = numVisitsIteration_; + psh->visits_tot = numVisitsTot_; + } + + /*! \brief + * Query if the point is in the target region. + * + * \returns true if the point is in the target region. + */ + bool inTargetRegion() const { return target_ > 0; } + + /*! \brief Return the bias function estimate. */ + double bias() const { return bias_; } + + /*! \brief Set the target to zero and the bias to minus infinity. */ + void setTargetToZero() + { + target_ = 0; + /* the bias = log(target) + const = -infty */ + bias_ = detail::c_largeNegativeExponent; + } + + /*! \brief Return the free energy. */ + double freeEnergy() const { return freeEnergy_; } + + /*! \brief Set the free energy, only to be used at initialization. + * + * \param[in] freeEnergy The free energy. + */ + void setFreeEnergy(double freeEnergy) { freeEnergy_ = freeEnergy; } + + /*! \brief Return the target distribution value. */ + double target() const { return target_; } + + /*! \brief Return the weight accumulated since the last update. */ + double weightSumIteration() const { return weightSumIteration_; } + + /*! \brief Increases the weight accumulated since the last update. + * + * \param[in] weight The amount to add to the weight + */ + void increaseWeightSumIteration(double weight) { weightSumIteration_ += weight; } + + /*! \brief Returns the accumulated weight */ + double weightSumTot() const { return weightSumTot_; } + + /*! \brief Return the reference weight histogram. */ + double weightSumRef() const { return weightSumRef_; } + + /*! \brief Return log(PmfSum). */ + double logPmfSum() const { return logPmfSum_; } + + /*! \brief Set log(PmfSum). + * + * TODO: Replace this setter function with a more elegant solution. + * + * \param[in] logPmfSum The log(PmfSum). + */ + void setLogPmfSum(double logPmfSum) { logPmfSum_ = logPmfSum; } + + /*! \brief Return the number of visits since the last update */ + double numVisitsIteration() const { return numVisitsIteration_; } + + /*! \brief Return the total number of visits */ + double numVisitsTot() const { return numVisitsTot_; } + + /*! \brief Set the constant target weight factor. + * + * \param[in] targetConstantWeight The target weight factor. + */ + void setTargetConstantWeight(double targetConstantWeight) + { + targetConstantWeight_ = targetConstantWeight; + } + + /*! \brief Updates the bias of a point. */ + void updateBias() + { + GMX_ASSERT(target_ > 0, "AWH target distribution must be > 0 to calculate the point bias."); + + bias_ = freeEnergy() + std::log(target_); + } + + /*! \brief Set the initial reference weighthistogram. + * + * \param[in] histogramSize The weight histogram size. + */ + void setInitialReferenceWeightHistogram(double histogramSize) + { + weightSumRef_ = histogramSize * target_; + } + + /*! \brief Correct free energy and PMF sum for the change in minimum. + * + * \param[in] minimumFreeEnergy The free energy at the minimum; + */ + void normalizeFreeEnergyAndPmfSum(double minimumFreeEnergy) + { + if (inTargetRegion()) { + /* The sign of the free energy and PMF constants are opposite + * because the PMF samples are reweighted with the negative + * bias e^(-bias) ~ e^(-free energy). + */ + freeEnergy_ -= minimumFreeEnergy; + logPmfSum_ += minimumFreeEnergy; } - - /*! \brief - * Set all values in the state to those from a history. - * - * \param[in] psh Coordinate point history to copy from. - */ - void setFromHistory(const AwhPointStateHistory &psh) - { - target_ = psh.target; - freeEnergy_ = psh.free_energy; - bias_ = psh.bias; - weightSumIteration_ = psh.weightsum_iteration; - weightSumTot_ = psh.weightsum_tot; - weightSumRef_ = psh.weightsum_ref; - lastUpdateIndex_ = psh.last_update_index; - logPmfSum_ = psh.log_pmfsum; - numVisitsIteration_ = psh.visits_iteration; - numVisitsTot_ = psh.visits_tot; - } - - /*! \brief - * Store the state of a point in a history struct. - * - * \param[in,out] psh Coordinate point history to copy to. - */ - void storeState(AwhPointStateHistory *psh) const - { - psh->target = target_; - psh->free_energy = freeEnergy_; - psh->bias = bias_; - psh->weightsum_iteration = weightSumIteration_; - psh->weightsum_tot = weightSumTot_; - psh->weightsum_ref = weightSumRef_; - psh->last_update_index = lastUpdateIndex_; - psh->log_pmfsum = logPmfSum_; - psh->visits_iteration = numVisitsIteration_; - psh->visits_tot = numVisitsTot_; - } - - /*! \brief - * Query if the point is in the target region. - * - * \returns true if the point is in the target region. - */ - bool inTargetRegion() const - { - return target_ > 0; - } - - /*! \brief Return the bias function estimate. */ - double bias() const - { - return bias_; - } - - /*! \brief Set the target to zero and the bias to minus infinity. */ - void setTargetToZero() - { - target_ = 0; - /* the bias = log(target) + const = -infty */ - bias_ = detail::c_largeNegativeExponent; - } - - /*! \brief Return the free energy. */ - double freeEnergy() const - { - return freeEnergy_; - } - - /*! \brief Set the free energy, only to be used at initialization. - * - * \param[in] freeEnergy The free energy. - */ - void setFreeEnergy(double freeEnergy) - { - freeEnergy_ = freeEnergy; - } - - /*! \brief Return the target distribution value. */ - double target() const - { - return target_; - } - - /*! \brief Return the weight accumulated since the last update. */ - double weightSumIteration() const + } + + /*! \brief Apply previous updates that were skipped. + * + * An update can only be skipped if the parameters needed for the update are constant or + * deterministic so that the same update can be performed at a later time. + * Here, the necessary parameters are the sampled weight and scaling factors for the + * histograms. The scaling factors are provided as arguments only to avoid recalculating + * them for each point + * + * The last update index is also updated here. + * + * \param[in] params The AWH bias parameters. + * \param[in] numUpdates The global number of updates. + * \param[in] weighthistScaling Scale factor for the reference weight histogram. + * \param[in] logPmfSumScaling Scale factor for the reference PMF histogram. + * \returns true if at least one update was applied. + */ + bool performPreviouslySkippedUpdates(const BiasParams& params, + int64_t numUpdates, + double weighthistScaling, + double logPmfSumScaling) + { + GMX_ASSERT(params.skipUpdates(), + "Calling function for skipped updates when skipping updates is not allowed"); + + if (!inTargetRegion()) { - return weightSumIteration_; + return false; } - /*! \brief Increases the weight accumulated since the last update. - * - * \param[in] weight The amount to add to the weight - */ - void increaseWeightSumIteration(double weight) - { - weightSumIteration_ += weight; - } + /* The most current past update */ + int64_t lastUpdateIndex = numUpdates; + int64_t numUpdatesSkipped = lastUpdateIndex - lastUpdateIndex_; - /*! \brief Returns the accumulated weight */ - double weightSumTot() const + if (numUpdatesSkipped == 0) { - return weightSumTot_; + /* Was not updated */ + return false; } - /*! \brief Return the reference weight histogram. */ - double weightSumRef() const + for (int64_t i = 0; i < numUpdatesSkipped; i++) { - return weightSumRef_; + /* This point was non-local at the time of the update meaning no weight */ + updateFreeEnergyAndWeight(params, 0, weighthistScaling, logPmfSumScaling); } - /*! \brief Return log(PmfSum). */ - double logPmfSum() const + /* Only past updates are applied here. */ + lastUpdateIndex_ = lastUpdateIndex; + + return true; + } + + /*! \brief Apply a point update with new sampling. + * + * \note The last update index is also updated here. + * \note The new sampling containers are cleared here. + * + * \param[in] params The AWH bias parameters. + * \param[in] numUpdates The global number of updates. + * \param[in] weighthistScaling Scaling factor for the reference weight histogram. + * \param[in] logPmfSumScaling Log of the scaling factor for the PMF histogram. + */ + void updateWithNewSampling(const BiasParams& params, int64_t numUpdates, double weighthistScaling, double logPmfSumScaling) + { + GMX_RELEASE_ASSERT(lastUpdateIndex_ == numUpdates, + "When doing a normal update, the point update index should match the " + "global index, otherwise we lost (skipped?) updates."); + + updateFreeEnergyAndWeight(params, weightSumIteration_, weighthistScaling, logPmfSumScaling); + lastUpdateIndex_ += 1; + + /* Clear the iteration collection data */ + weightSumIteration_ = 0; + numVisitsIteration_ = 0; + } + + + /*! \brief Update the PMF histogram with the current coordinate value. + * + * \param[in] convolvedBias The convolved bias. + */ + void samplePmf(double convolvedBias); + +private: + /*! \brief Update the free energy estimate of a point. + * + * The free energy update here is inherently local, i.e. it just depends on local sampling and + * on constant AWH parameters. This assumes that the variables used here are kept constant, at + * least in between global updates. + * + * \param[in] params The AWH bias parameters. + * \param[in] weightAtPoint Sampled probability weight at this point. + */ + void updateFreeEnergy(const BiasParams& params, double weightAtPoint) + { + double weighthistSampled = weightSumRef() + weightAtPoint; + double weighthistTarget = weightSumRef() + params.updateWeight * target_; + + double df = -std::log(weighthistSampled / weighthistTarget); + freeEnergy_ += df; + + GMX_RELEASE_ASSERT(std::abs(freeEnergy_) < detail::c_largePositiveExponent, + "Very large free energy differences or badly normalized free energy in " + "AWH update."); + } + + /*! \brief Update the reference weight histogram of a point. + * + * \param[in] params The AWH bias parameters. + * \param[in] weightAtPoint Sampled probability weight at this point. + * \param[in] scaleFactor Factor to rescale the histogram with. + */ + void updateWeightHistogram(const BiasParams& params, double weightAtPoint, double scaleFactor) + { + if (params.idealWeighthistUpdate) { - return logPmfSum_; - } - - /*! \brief Set log(PmfSum). - * - * TODO: Replace this setter function with a more elegant solution. - * - * \param[in] logPmfSum The log(PmfSum). - */ - void setLogPmfSum(double logPmfSum) - { - logPmfSum_ = logPmfSum; - } - - /*! \brief Return the number of visits since the last update */ - double numVisitsIteration() const - { - return numVisitsIteration_; - } - - /*! \brief Return the total number of visits */ - double numVisitsTot() const - { - return numVisitsTot_; - } - - /*! \brief Set the constant target weight factor. - * - * \param[in] targetConstantWeight The target weight factor. - */ - void setTargetConstantWeight(double targetConstantWeight) - { - targetConstantWeight_ = targetConstantWeight; - } - - /*! \brief Updates the bias of a point. */ - void updateBias() - { - GMX_ASSERT(target_ > 0, "AWH target distribution must be > 0 to calculate the point bias."); - - bias_ = freeEnergy() + std::log(target_); - } - - /*! \brief Set the initial reference weighthistogram. - * - * \param[in] histogramSize The weight histogram size. - */ - void setInitialReferenceWeightHistogram(double histogramSize) - { - weightSumRef_ = histogramSize*target_; - } - - /*! \brief Correct free energy and PMF sum for the change in minimum. - * - * \param[in] minimumFreeEnergy The free energy at the minimum; - */ - void normalizeFreeEnergyAndPmfSum(double minimumFreeEnergy) - { - if (inTargetRegion()) - { - /* The sign of the free energy and PMF constants are opposite - * because the PMF samples are reweighted with the negative - * bias e^(-bias) ~ e^(-free energy). - */ - freeEnergy_ -= minimumFreeEnergy; - logPmfSum_ += minimumFreeEnergy; - } + /* Grow histogram using the target distribution. */ + weightSumRef_ += target_ * params.updateWeight * params.localWeightScaling; } - - /*! \brief Apply previous updates that were skipped. - * - * An update can only be skipped if the parameters needed for the update are constant or - * deterministic so that the same update can be performed at a later time. - * Here, the necessary parameters are the sampled weight and scaling factors for the - * histograms. The scaling factors are provided as arguments only to avoid recalculating - * them for each point - * - * The last update index is also updated here. - * - * \param[in] params The AWH bias parameters. - * \param[in] numUpdates The global number of updates. - * \param[in] weighthistScaling Scale factor for the reference weight histogram. - * \param[in] logPmfSumScaling Scale factor for the reference PMF histogram. - * \returns true if at least one update was applied. - */ - bool performPreviouslySkippedUpdates(const BiasParams ¶ms, - int64_t numUpdates, - double weighthistScaling, - double logPmfSumScaling) + else { - GMX_ASSERT(params.skipUpdates(), "Calling function for skipped updates when skipping updates is not allowed"); - - if (!inTargetRegion()) - { - return false; - } - - /* The most current past update */ - int64_t lastUpdateIndex = numUpdates; - int64_t numUpdatesSkipped = lastUpdateIndex - lastUpdateIndex_; - - if (numUpdatesSkipped == 0) - { - /* Was not updated */ - return false; - } - - for (int64_t i = 0; i < numUpdatesSkipped; i++) - { - /* This point was non-local at the time of the update meaning no weight */ - updateFreeEnergyAndWeight(params, 0, weighthistScaling, logPmfSumScaling); - } - - /* Only past updates are applied here. */ - lastUpdateIndex_ = lastUpdateIndex; - - return true; + /* Grow using the actual samples (which are distributed ~ as target). */ + weightSumRef_ += weightAtPoint * params.localWeightScaling; } - /*! \brief Apply a point update with new sampling. - * - * \note The last update index is also updated here. - * \note The new sampling containers are cleared here. - * - * \param[in] params The AWH bias parameters. - * \param[in] numUpdates The global number of updates. - * \param[in] weighthistScaling Scaling factor for the reference weight histogram. - * \param[in] logPmfSumScaling Log of the scaling factor for the PMF histogram. - */ - void updateWithNewSampling(const BiasParams ¶ms, - int64_t numUpdates, + weightSumRef_ *= scaleFactor; + } + + /*! \brief Apply a point update. + * + * This updates local properties that can be updated without + * accessing or affecting all points. + * This excludes updating the size of reference weight histogram and + * the target distribution. The bias update is excluded only because + * if updates have been skipped this function will be called multiple + * times, while the bias only needs to be updated once (last). + * + * Since this function only performs the update with the given + * arguments and does not know anything about the time of the update, + * the last update index is not updated here. The caller should take + * care of updating the update index. + * + * \param[in] params The AWH bias parameters. + * \param[in] weightAtPoint Sampled probability weight at this point. + * \param[in] weighthistScaling Scaling factor for the reference weight histogram. + * \param[in] logPmfSumScaling Log of the scaling factor for the PMF histogram. + */ + void updateFreeEnergyAndWeight(const BiasParams& params, + double weightAtPoint, double weighthistScaling, double logPmfSumScaling) + { + updateFreeEnergy(params, weightAtPoint); + updateWeightHistogram(params, weightAtPoint, weighthistScaling); + logPmfSum_ += logPmfSumScaling; + } + + +public: + /*! \brief Update the target weight of a point. + * + * Note that renormalization over all points is needed after the update. + * + * \param[in] params The AWH bias parameters. + * \param[in] freeEnergyCutoff The cut-off for the free energy for target type "cutoff". + * \returns the updated value of the target. + */ + double updateTargetWeight(const BiasParams& params, double freeEnergyCutoff) + { + switch (params.eTarget) { - GMX_RELEASE_ASSERT(lastUpdateIndex_ == numUpdates, "When doing a normal update, the point update index should match the global index, otherwise we lost (skipped?) updates."); - - updateFreeEnergyAndWeight(params, weightSumIteration_, weighthistScaling, logPmfSumScaling); - lastUpdateIndex_ += 1; - - /* Clear the iteration collection data */ - weightSumIteration_ = 0; - numVisitsIteration_ = 0; - } - - - /*! \brief Update the PMF histogram with the current coordinate value. - * - * \param[in] convolvedBias The convolved bias. - */ - void samplePmf(double convolvedBias); - - private: - /*! \brief Update the free energy estimate of a point. - * - * The free energy update here is inherently local, i.e. it just depends on local sampling and on constant - * AWH parameters. This assumes that the variables used here are kept constant, at least in between - * global updates. - * - * \param[in] params The AWH bias parameters. - * \param[in] weightAtPoint Sampled probability weight at this point. - */ - void updateFreeEnergy(const BiasParams ¶ms, - double weightAtPoint) - { - double weighthistSampled = weightSumRef() + weightAtPoint; - double weighthistTarget = weightSumRef() + params.updateWeight*target_; - - double df = -std::log(weighthistSampled/weighthistTarget); - freeEnergy_ += df; - - GMX_RELEASE_ASSERT(std::abs(freeEnergy_) < detail::c_largePositiveExponent, - "Very large free energy differences or badly normalized free energy in AWH update."); - } - - /*! \brief Update the reference weight histogram of a point. - * - * \param[in] params The AWH bias parameters. - * \param[in] weightAtPoint Sampled probability weight at this point. - * \param[in] scaleFactor Factor to rescale the histogram with. - */ - void updateWeightHistogram(const BiasParams ¶ms, - double weightAtPoint, - double scaleFactor) - { - if (params.idealWeighthistUpdate) - { - /* Grow histogram using the target distribution. */ - weightSumRef_ += target_*params.updateWeight*params.localWeightScaling; - } - else + case eawhtargetCONSTANT: target_ = 1; break; + case eawhtargetCUTOFF: { - /* Grow using the actual samples (which are distributed ~ as target). */ - weightSumRef_ += weightAtPoint*params.localWeightScaling; + double df = freeEnergy_ - freeEnergyCutoff; + target_ = 1 / (1 + std::exp(df)); + break; } - - weightSumRef_ *= scaleFactor; - } - - /*! \brief Apply a point update. - * - * This updates local properties that can be updated without - * accessing or affecting all points. - * This excludes updating the size of reference weight histogram and - * the target distribution. The bias update is excluded only because - * if updates have been skipped this function will be called multiple - * times, while the bias only needs to be updated once (last). - * - * Since this function only performs the update with the given - * arguments and does not know anything about the time of the update, - * the last update index is not updated here. The caller should take - * care of updating the update index. - * - * \param[in] params The AWH bias parameters. - * \param[in] weightAtPoint Sampled probability weight at this point. - * \param[in] weighthistScaling Scaling factor for the reference weight histogram. - * \param[in] logPmfSumScaling Log of the scaling factor for the PMF histogram. - */ - void updateFreeEnergyAndWeight(const BiasParams ¶ms, - double weightAtPoint, - double weighthistScaling, - double logPmfSumScaling) - { - updateFreeEnergy(params, weightAtPoint); - updateWeightHistogram(params, weightAtPoint, weighthistScaling); - logPmfSum_ += logPmfSumScaling; - } - - - public: - /*! \brief Update the target weight of a point. - * - * Note that renormalization over all points is needed after the update. - * - * \param[in] params The AWH bias parameters. - * \param[in] freeEnergyCutoff The cut-off for the free energy for target type "cutoff". - * \returns the updated value of the target. - */ - double updateTargetWeight(const BiasParams ¶ms, - double freeEnergyCutoff) - { - switch (params.eTarget) - { - case eawhtargetCONSTANT: - target_ = 1; - break; - case eawhtargetCUTOFF: - { - double df = freeEnergy_ - freeEnergyCutoff; - target_ = 1/(1 + std::exp(df)); - break; - } - case eawhtargetBOLTZMANN: - target_ = std::exp(-params.temperatureScaleFactor*freeEnergy_); - break; - case eawhtargetLOCALBOLTZMANN: - target_ = weightSumRef_; - break; - } - - /* All target types can be modulated by a constant factor. */ - target_ *= targetConstantWeight_; - - return target_; - } - - /*! \brief Set the weight and count accumulated since the last update. - * - * \param[in] weightSum The weight-sum value - * \param[in] numVisits The number of visits - */ - void setPartialWeightAndCount(double weightSum, - double numVisits) - { - weightSumIteration_ = weightSum; - numVisitsIteration_ = numVisits; - } - - /*! \brief Add the weights and counts accumulated between updates. */ - void addPartialWeightAndCount() - { - weightSumTot_ += weightSumIteration_; - numVisitsTot_ += numVisitsIteration_; - } - - /*! \brief Scale the target weight of the point. - * - * \param[in] scaleFactor Factor to scale with. - */ - void scaleTarget(double scaleFactor) - { - target_ *= scaleFactor; + case eawhtargetBOLTZMANN: + target_ = std::exp(-params.temperatureScaleFactor * freeEnergy_); + break; + case eawhtargetLOCALBOLTZMANN: target_ = weightSumRef_; break; } - private: - double bias_; /**< Current biasing function estimate */ - double freeEnergy_; /**< Current estimate of the convolved free energy/PMF. */ - double target_; /**< Current target distribution, normalized to 1 */ - double targetConstantWeight_; /**< Constant target weight, from user data. */ - double weightSumIteration_; /**< Accumulated weight this iteration; note: only contains data for this Bias, even when sharing biases. */ - double weightSumTot_; /**< Accumulated weights, never reset */ - double weightSumRef_; /**< The reference weight histogram determining the free energy updates */ - int64_t lastUpdateIndex_; /**< The last update that was performed at this point, in units of number of updates. */ - double logPmfSum_; /**< Logarithm of the PMF histogram */ - double numVisitsIteration_; /**< Visits to this bin this iteration; note: only contains data for this Bias, even when sharing biases. */ - double numVisitsTot_; /**< Accumulated visits to this bin */ + /* All target types can be modulated by a constant factor. */ + target_ *= targetConstantWeight_; + + return target_; + } + + /*! \brief Set the weight and count accumulated since the last update. + * + * \param[in] weightSum The weight-sum value + * \param[in] numVisits The number of visits + */ + void setPartialWeightAndCount(double weightSum, double numVisits) + { + weightSumIteration_ = weightSum; + numVisitsIteration_ = numVisits; + } + + /*! \brief Add the weights and counts accumulated between updates. */ + void addPartialWeightAndCount() + { + weightSumTot_ += weightSumIteration_; + numVisitsTot_ += numVisitsIteration_; + } + + /*! \brief Scale the target weight of the point. + * + * \param[in] scaleFactor Factor to scale with. + */ + void scaleTarget(double scaleFactor) { target_ *= scaleFactor; } + +private: + double bias_; /**< Current biasing function estimate */ + double freeEnergy_; /**< Current estimate of the convolved free energy/PMF. */ + double target_; /**< Current target distribution, normalized to 1 */ + double targetConstantWeight_; /**< Constant target weight, from user data. */ + double weightSumIteration_; /**< Accumulated weight this iteration; note: only contains data for this Bias, even when sharing biases. */ + double weightSumTot_; /**< Accumulated weights, never reset */ + double weightSumRef_; /**< The reference weight histogram determining the free energy updates */ + int64_t lastUpdateIndex_; /**< The last update that was performed at this point, in units of number of updates. */ + double logPmfSum_; /**< Logarithm of the PMF histogram */ + double numVisitsIteration_; /**< Visits to this bin this iteration; note: only contains data for this Bias, even when sharing biases. */ + double numVisitsTot_; /**< Accumulated visits to this bin */ }; -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_POINTSTATE_H */ diff --git a/src/gromacs/awh/read_params.cpp b/src/gromacs/awh/read_params.cpp index ea4e6e2198..55837e1f88 100644 --- a/src/gromacs/awh/read_params.cpp +++ b/src/gromacs/awh/read_params.cpp @@ -62,21 +62,14 @@ namespace gmx { -const char *eawhtarget_names[eawhtargetNR+1] = { - "constant", "cutoff", "boltzmann", "local-boltzmann", nullptr -}; +const char* eawhtarget_names[eawhtargetNR + 1] = { "constant", "cutoff", "boltzmann", + "local-boltzmann", nullptr }; -const char *eawhgrowth_names[eawhgrowthNR+1] = { - "exp-linear", "linear", nullptr -}; +const char* eawhgrowth_names[eawhgrowthNR + 1] = { "exp-linear", "linear", nullptr }; -const char *eawhpotential_names[eawhpotentialNR+1] = { - "convolved", "umbrella", nullptr -}; +const char* eawhpotential_names[eawhpotentialNR + 1] = { "convolved", "umbrella", nullptr }; -const char *eawhcoordprovider_names[eawhcoordproviderNR+1] = { - "pull", nullptr -}; +const char* eawhcoordprovider_names[eawhcoordproviderNR + 1] = { "pull", nullptr }; /*! \brief * Read parameters of an AWH bias dimension. @@ -88,17 +81,21 @@ const char *eawhcoordprovider_names[eawhcoordproviderNR+1] = { * \param[in,out] wi Struct for bookeeping warnings. * \param[in] bComment True if comments should be printed. */ -static void readDimParams(std::vector *inp, const std::string &prefix, - AwhDimParams *dimParams, const pull_params_t *pull_params, - warninp_t wi, bool bComment) +static void readDimParams(std::vector* inp, + const std::string& prefix, + AwhDimParams* dimParams, + const pull_params_t* pull_params, + warninp_t wi, + bool bComment) { std::string opt; if (bComment) { - printStringNoNewline(inp, "The provider of the reaction coordinate, currently only pull is supported"); + printStringNoNewline( + inp, "The provider of the reaction coordinate, currently only pull is supported"); } - opt = prefix + "-coord-provider"; + opt = prefix + "-coord-provider"; dimParams->eCoordProvider = get_eeenum(inp, opt, eawhcoordprovider_names, wi); if (bComment) @@ -108,31 +105,35 @@ static void readDimParams(std::vector *inp, const std::string &prefix opt = prefix + "-coord-index"; int coordIndexInput; coordIndexInput = get_eint(inp, opt, 1, wi); - if (coordIndexInput < 1) + if (coordIndexInput < 1) { - gmx_fatal(FARGS, "Failed to read a valid coordinate index for %s. " - "Note that the pull coordinate indexing starts at 1.", opt.c_str()); + gmx_fatal(FARGS, + "Failed to read a valid coordinate index for %s. " + "Note that the pull coordinate indexing starts at 1.", + opt.c_str()); } /* The pull coordinate indices start at 1 in the input file, at 0 internally */ dimParams->coordIndex = coordIndexInput - 1; /* The pull settings need to be consistent with the AWH settings */ - if (!(pull_params->coord[dimParams->coordIndex].eType == epullEXTERNAL) ) + if (!(pull_params->coord[dimParams->coordIndex].eType == epullEXTERNAL)) { - gmx_fatal(FARGS, "AWH biasing can only be applied to pull type %s", - EPULLTYPE(epullEXTERNAL)); + gmx_fatal(FARGS, "AWH biasing can only be applied to pull type %s", EPULLTYPE(epullEXTERNAL)); } if (dimParams->coordIndex >= pull_params->ncoord) { - gmx_fatal(FARGS, "The given AWH coordinate index (%d) is larger than the number of pull coordinates (%d)", + gmx_fatal(FARGS, + "The given AWH coordinate index (%d) is larger than the number of pull " + "coordinates (%d)", coordIndexInput, pull_params->ncoord); } if (pull_params->coord[dimParams->coordIndex].rate != 0) { - auto message = formatString("Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate", - coordIndexInput, pull_params->coord[dimParams->coordIndex].rate); + auto message = formatString( + "Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate", + coordIndexInput, pull_params->coord[dimParams->coordIndex].rate); warning_error(wi, message); } @@ -152,9 +153,10 @@ static void readDimParams(std::vector *inp, const std::string &prefix if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS)) { - auto message = formatString("The given interval length given by %s-start (%g) and %s-end (%g) is zero. " - "This will result in only one point along this axis in the coordinate value grid.", - prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end); + auto message = formatString( + "The given interval length given by %s-start (%g) and %s-end (%g) is zero. " + "This will result in only one point along this axis in the coordinate value grid.", + prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end); warning(wi, message); } /* Check that the requested interval is in allowed range */ @@ -162,33 +164,43 @@ static void readDimParams(std::vector *inp, const std::string &prefix { if (dimParams->origin < 0 || dimParams->end < 0) { - gmx_fatal(FARGS, "%s-start (%g) or %s-end (%g) set to a negative value. With pull geometry distance coordinate values are non-negative. " + gmx_fatal(FARGS, + "%s-start (%g) or %s-end (%g) set to a negative value. With pull geometry " + "distance coordinate values are non-negative. " "Perhaps you want to use geometry %s instead?", - prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgDIR)); + prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, + EPULLGEOM(epullgDIR)); } } else if (eGeom == epullgANGLE || eGeom == epullgANGLEAXIS) { if (dimParams->origin < 0 || dimParams->end > 180) { - gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range 0 to 180 deg for pull geometries %s and %s ", - prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS)); + gmx_fatal(FARGS, + "%s-start (%g) and %s-end (%g) are outside of the allowed range 0 to 180 deg " + "for pull geometries %s and %s ", + prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, + EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS)); } } else if (eGeom == epullgDIHEDRAL) { if (dimParams->origin < -180 || dimParams->end > 180) { - gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range -180 to 180 deg for pull geometry %s. ", - prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgDIHEDRAL)); + gmx_fatal(FARGS, + "%s-start (%g) and %s-end (%g) are outside of the allowed range -180 to 180 " + "deg for pull geometry %s. ", + prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, + EPULLGEOM(epullgDIHEDRAL)); } } if (bComment) { - printStringNoNewline(inp, "The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)"); + printStringNoNewline( + inp, "The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)"); } - opt = prefix + "-force-constant"; + opt = prefix + "-force-constant"; dimParams->forceConstant = get_ereal(inp, opt, 0, wi); if (dimParams->forceConstant <= 0) { @@ -205,25 +217,27 @@ static void readDimParams(std::vector *inp, const std::string &prefix if (dimParams->diffusion <= 0) { const double diffusion_default = 1e-5; - auto message = formatString - ("%s not explicitly set by user. You can choose to use a default " + auto message = formatString( + "%s not explicitly set by user. You can choose to use a default " "value (%g nm^2/ps or rad^2/ps) but this may very well be " - "non-optimal for your system!", opt.c_str(), diffusion_default); + "non-optimal for your system!", + opt.c_str(), diffusion_default); warning(wi, message); dimParams->diffusion = diffusion_default; } if (bComment) { - printStringNoNewline(inp, "Diameter that needs to be sampled around a point before it is considered covered."); + printStringNoNewline(inp, + "Diameter that needs to be sampled around a point before it is " + "considered covered."); } - opt = prefix + "-cover-diameter"; + opt = prefix + "-cover-diameter"; dimParams->coverDiameter = get_ereal(inp, opt, 0, wi); if (dimParams->coverDiameter < 0) { - gmx_fatal(FARGS, "%s (%g) cannot be negative.", - opt.c_str(), dimParams->coverDiameter); + gmx_fatal(FARGS, "%s (%g) cannot be negative.", opt.c_str(), dimParams->coverDiameter); } } @@ -233,8 +247,7 @@ static void readDimParams(std::vector *inp, const std::string &prefix * \param[in] awhBiasParams AWH bias parameters. * \param[in,out] wi Struct for bookkeeping warnings. */ -static void checkInputConsistencyAwhBias(const AwhBiasParams &awhBiasParams, - warninp_t wi) +static void checkInputConsistencyAwhBias(const AwhBiasParams& awhBiasParams, warninp_t wi) { /* Covering diameter and sharing warning. */ for (int d = 0; d < awhBiasParams.ndim; d++) @@ -242,7 +255,8 @@ static void checkInputConsistencyAwhBias(const AwhBiasParams &awhBiasParams, double coverDiameter = awhBiasParams.dimParams[d].coverDiameter; if (awhBiasParams.shareGroup <= 0 && coverDiameter > 0) { - warning(wi, "The covering diameter is only relevant to set for bias sharing simulations."); + warning(wi, + "The covering diameter is only relevant to set for bias sharing simulations."); } } } @@ -257,8 +271,12 @@ static void checkInputConsistencyAwhBias(const AwhBiasParams &awhBiasParams, * \param[in,out] wi Struct for bookeeping warnings. * \param[in] bComment True if comments should be printed. */ -static void read_bias_params(std::vector *inp, AwhBiasParams *awhBiasParams, const std::string &prefix, - const t_inputrec *ir, warninp_t wi, bool bComment) +static void read_bias_params(std::vector* inp, + AwhBiasParams* awhBiasParams, + const std::string& prefix, + const t_inputrec* ir, + warninp_t wi, + bool bComment) { if (bComment) { @@ -275,47 +293,56 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias if (bComment) { - printStringNoNewline(inp, "Growth rate of the reference histogram determining the bias update size: exp-linear or linear"); + printStringNoNewline(inp, + "Growth rate of the reference histogram determining the bias update " + "size: exp-linear or linear"); } opt = prefix + "-growth"; awhBiasParams->eGrowth = get_eeenum(inp, opt, eawhgrowth_names, wi); if (bComment) { - printStringNoNewline(inp, "Start the simulation by equilibrating histogram towards the target distribution: no or yes"); + printStringNoNewline(inp, + "Start the simulation by equilibrating histogram towards the target " + "distribution: no or yes"); } - opt = prefix + "-equilibrate-histogram"; + opt = prefix + "-equilibrate-histogram"; awhBiasParams->equilibrateHistogram = (get_eeenum(inp, opt, yesno_names, wi) != 0); if (awhBiasParams->equilibrateHistogram && awhBiasParams->eGrowth != eawhgrowthEXP_LINEAR) { - auto message = formatString("Option %s will only have an effect for histogram growth type '%s'.", - opt.c_str(), EAWHGROWTH(eawhgrowthEXP_LINEAR)); + auto message = + formatString("Option %s will only have an effect for histogram growth type '%s'.", + opt.c_str(), EAWHGROWTH(eawhgrowthEXP_LINEAR)); warning(wi, message); } if (bComment) { - printStringNoNewline(inp, "Target distribution type: constant, cutoff, boltzmann or local-boltzmann"); + printStringNoNewline( + inp, "Target distribution type: constant, cutoff, boltzmann or local-boltzmann"); } opt = prefix + "-target"; awhBiasParams->eTarget = get_eeenum(inp, opt, eawhtarget_names, wi); - if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) && - (awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR)) + if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) + && (awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR)) { - auto message = formatString("Target type '%s' combined with histogram growth type '%s' is not " - "expected to give stable bias updates. You probably want to use growth type " - "'%s' instead.", - EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR), - EAWHGROWTH(eawhgrowthLINEAR)); + auto message = formatString( + "Target type '%s' combined with histogram growth type '%s' is not " + "expected to give stable bias updates. You probably want to use growth type " + "'%s' instead.", + EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR), + EAWHGROWTH(eawhgrowthLINEAR)); warning(wi, message); } if (bComment) { - printStringNoNewline(inp, "Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'"); + printStringNoNewline(inp, + "Boltzmann beta scaling factor for target distribution types " + "'boltzmann' and 'boltzmann-local'"); } - opt = prefix + "-target-beta-scaling"; + opt = prefix + "-target-beta-scaling"; awhBiasParams->targetBetaScaling = get_ereal(inp, opt, 0, wi); switch (awhBiasParams->eTarget) @@ -324,15 +351,18 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias case eawhtargetLOCALBOLTZMANN: if (awhBiasParams->targetBetaScaling < 0 || awhBiasParams->targetBetaScaling > 1) { - gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", - opt.c_str(), awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget)); + gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt.c_str(), + awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget)); } break; default: if (awhBiasParams->targetBetaScaling != 0) { - gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.", - opt.c_str(), awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget)); + gmx_fatal( + FARGS, + "Value for %s (%g) set explicitly but will not be used for target type %s.", + opt.c_str(), awhBiasParams->targetBetaScaling, + EAWHTARGET(awhBiasParams->eTarget)); } break; } @@ -341,7 +371,7 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias { printStringNoNewline(inp, "Free energy cutoff value for target distribution type 'cutoff'"); } - opt = prefix + "-target-cutoff"; + opt = prefix + "-target-cutoff"; awhBiasParams->targetCutoff = get_ereal(inp, opt, 0, wi); switch (awhBiasParams->eTarget) @@ -349,15 +379,17 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias case eawhtargetCUTOFF: if (awhBiasParams->targetCutoff <= 0) { - gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", - opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); + gmx_fatal(FARGS, "%s = %g is not useful for target type %s.", opt.c_str(), + awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); } break; default: if (awhBiasParams->targetCutoff != 0) { - gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.", - opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); + gmx_fatal( + FARGS, + "Value for %s (%g) set explicitly but will not be used for target type %s.", + opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget)); } break; } @@ -366,14 +398,14 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias { printStringNoNewline(inp, "Initialize PMF and target with user data: no or yes"); } - opt = prefix + "-user-data"; + opt = prefix + "-user-data"; awhBiasParams->bUserData = get_eeenum(inp, opt, yesno_names, wi); if (bComment) { printStringNoNewline(inp, "Group index to share the bias with, 0 means not shared"); } - opt = prefix + "-share-group"; + opt = prefix + "-share-group"; awhBiasParams->shareGroup = get_eint(inp, opt, 0, wi); if (awhBiasParams->shareGroup < 0) { @@ -387,20 +419,22 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias opt = prefix + "-ndim"; awhBiasParams->ndim = get_eint(inp, opt, 0, wi); - if (awhBiasParams->ndim <= 0 || - awhBiasParams->ndim > c_biasMaxNumDim) + if (awhBiasParams->ndim <= 0 || awhBiasParams->ndim > c_biasMaxNumDim) { - gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(), awhBiasParams->ndim, c_biasMaxNumDim); + gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(), + awhBiasParams->ndim, c_biasMaxNumDim); } if (awhBiasParams->ndim > 2) { - warning_note(wi, "For awh-dim > 2 the estimate based on the diffusion and the initial error is currently only a rough guideline." + warning_note(wi, + "For awh-dim > 2 the estimate based on the diffusion and the initial error is " + "currently only a rough guideline." " You should verify its usefulness for your system before production runs!"); } snew(awhBiasParams->dimParams, awhBiasParams->ndim); for (int d = 0; d < awhBiasParams->ndim; d++) { - bComment = bComment && d == 0; + bComment = bComment && d == 0; std::string prefixdim = prefix + formatString("-dim%d", d + 1); readDimParams(inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment); } @@ -415,8 +449,7 @@ static void read_bias_params(std::vector *inp, AwhBiasParams *awhBias * \param[in] awhParams AWH parameters. * \param[in,out] wi Struct for bookkeeping warnings. */ -static void checkInputConsistencyAwh(const AwhParams &awhParams, - warninp_t wi) +static void checkInputConsistencyAwh(const AwhParams& awhParams, warninp_t wi) { /* Each pull coord can map to at most 1 AWH coord. * Check that we have a shared bias when requesting multisim sharing. @@ -424,7 +457,7 @@ static void checkInputConsistencyAwh(const AwhParams &awhParams, bool haveSharedBias = false; for (int k1 = 0; k1 < awhParams.numBias; k1++) { - const AwhBiasParams &awhBiasParams1 = awhParams.awhBiasParams[k1]; + const AwhBiasParams& awhBiasParams1 = awhParams.awhBiasParams[k1]; if (awhBiasParams1.shareGroup > 0) { @@ -436,18 +469,23 @@ static void checkInputConsistencyAwh(const AwhParams &awhParams, { for (int d1 = 0; d1 < awhBiasParams1.ndim; d1++) { - const AwhBiasParams &awhBiasParams2 = awhParams.awhBiasParams[k2]; + const AwhBiasParams& awhBiasParams2 = awhParams.awhBiasParams[k2]; /* d1 is the reference dimension of the reference AWH. d2 is the dim index of the AWH to compare with. */ for (int d2 = 0; d2 < awhBiasParams2.ndim; d2++) { /* Give an error if (d1, k1) is different from (d2, k2) but the pull coordinate is the same */ - if ( (d1 != d2 || k1 != k2) && (awhBiasParams1.dimParams[d1].coordIndex == awhBiasParams2.dimParams[d2].coordIndex) ) + if ((d1 != d2 || k1 != k2) + && (awhBiasParams1.dimParams[d1].coordIndex == awhBiasParams2.dimParams[d2].coordIndex)) { char errormsg[STRLEN]; - sprintf(errormsg, "One pull coordinate (%d) cannot be mapped to two separate AWH dimensions (awh%d-dim%d and awh%d-dim%d). " - "If this is really what you want to do you will have to duplicate this pull coordinate.", - awhBiasParams1.dimParams[d1].coordIndex + 1, k1 + 1, d1 + 1, k2 + 1, d2 + 1); + sprintf(errormsg, + "One pull coordinate (%d) cannot be mapped to two separate AWH " + "dimensions (awh%d-dim%d and awh%d-dim%d). " + "If this is really what you want to do you will have to duplicate " + "this pull coordinate.", + awhBiasParams1.dimParams[d1].coordIndex + 1, k1 + 1, d1 + 1, k2 + 1, + d2 + 1); gmx_fatal(FARGS, "%s", errormsg); } } @@ -457,19 +495,23 @@ static void checkInputConsistencyAwh(const AwhParams &awhParams, if (awhParams.shareBiasMultisim && !haveSharedBias) { - warning(wi, "Sharing of biases over multiple simulations is requested, but no bias is marked as shared (share-group > 0)"); + warning(wi, + "Sharing of biases over multiple simulations is requested, but no bias is marked " + "as shared (share-group > 0)"); } /* mdrun does not support this (yet), but will check again */ if (haveBiasSharingWithinSimulation(awhParams)) { - warning(wi, "You have shared biases within a single simulation, but mdrun does not support this (yet)"); + warning(wi, + "You have shared biases within a single simulation, but mdrun does not support " + "this (yet)"); } } -AwhParams *readAndCheckAwhParams(std::vector *inp, const t_inputrec *ir, warninp_t wi) +AwhParams* readAndCheckAwhParams(std::vector* inp, const t_inputrec* ir, warninp_t wi) { - AwhParams *awhParams; + AwhParams* awhParams; snew(awhParams, 1); std::string opt; @@ -479,7 +521,9 @@ AwhParams *readAndCheckAwhParams(std::vector *inp, const t_inputrec * opt = "awh-potential"; awhParams->ePotential = get_eeenum(inp, opt, eawhpotential_names, wi); - printStringNoNewline(inp, "The random seed used for sampling the umbrella center in the case of umbrella type potential"); + printStringNoNewline(inp, + "The random seed used for sampling the umbrella center in the case of " + "umbrella type potential"); opt = "awh-seed"; awhParams->seed = get_eint(inp, opt, -1, wi); if (awhParams->seed == -1) @@ -500,25 +544,26 @@ AwhParams *readAndCheckAwhParams(std::vector *inp, const t_inputrec * /* This restriction can be removed by changing a flag of print_ebin() */ if (ir->nstenergy == 0 || awhParams->nstOut % ir->nstenergy != 0) { - auto message = formatString("%s (%d) should be a multiple of nstenergy (%d)", - opt.c_str(), awhParams->nstOut, ir->nstenergy); + auto message = formatString("%s (%d) should be a multiple of nstenergy (%d)", opt.c_str(), + awhParams->nstOut, ir->nstenergy); warning_error(wi, message); } printStringNoNewline(inp, "Coordinate sampling interval in number of steps"); - opt = "awh-nstsample"; + opt = "awh-nstsample"; awhParams->nstSampleCoord = get_eint(inp, opt, 10, wi); printStringNoNewline(inp, "Free energy and bias update interval in number of samples"); - opt = "awh-nsamples-update"; + opt = "awh-nsamples-update"; awhParams->numSamplesUpdateFreeEnergy = get_eint(inp, opt, 10, wi); if (awhParams->numSamplesUpdateFreeEnergy <= 0) { warning_error(wi, opt + " needs to be an integer > 0"); } - printStringNoNewline(inp, "When true, biases with share-group>0 are shared between multiple simulations"); - opt = "awh-share-multisim"; + printStringNoNewline( + inp, "When true, biases with share-group>0 are shared between multiple simulations"); + opt = "awh-share-multisim"; awhParams->shareBiasMultisim = (get_eeenum(inp, opt, yesno_names, wi) != 0); printStringNoNewline(inp, "The number of independent AWH biases"); @@ -558,15 +603,13 @@ AwhParams *readAndCheckAwhParams(std::vector *inp, const t_inputrec * * \param[in] intervalLength The length of the AWH interval for this pull coordinate * \returns the period (or 0 if not periodic). */ -static double get_pull_coord_period(const t_pull_coord &pullCoordParams, - const t_pbc &pbc, - const real intervalLength) +static double get_pull_coord_period(const t_pull_coord& pullCoordParams, const t_pbc& pbc, const real intervalLength) { double period = 0; if (pullCoordParams.eGeom == epullgDIR) { - const real margin = 0.001; + const real margin = 0.001; // Make dims periodic when the interval covers > 95% const real periodicFraction = 0.95; @@ -575,12 +618,11 @@ static double get_pull_coord_period(const t_pull_coord &pullCoordParams, { const real boxLength = norm(pbc.box[dim]); const real innerProduct = iprod(pullCoordParams.vec, pbc.box[dim]); - if (innerProduct >= (1 - margin)*boxLength && - innerProduct <= (1 + margin)*boxLength) + if (innerProduct >= (1 - margin) * boxLength && innerProduct <= (1 + margin) * boxLength) { - GMX_RELEASE_ASSERT(intervalLength < (1 + margin)*boxLength, + GMX_RELEASE_ASSERT(intervalLength < (1 + margin) * boxLength, "We have checked before that interval <= period"); - if (intervalLength > periodicFraction*boxLength) + if (intervalLength > periodicFraction * boxLength) { period = boxLength; } @@ -606,7 +648,7 @@ static double get_pull_coord_period(const t_pull_coord &pullCoordParams, */ static bool intervalIsInPeriodicInterval(double origin, double end, double period) { - return (period == 0) || (std::fabs(origin) <= 0.5*period && std::fabs(end) <= 0.5*period); + return (period == 0) || (std::fabs(origin) <= 0.5 * period && std::fabs(end) <= 0.5 * period); } /*! \brief @@ -632,7 +674,8 @@ static bool valueIsInInterval(double origin, double end, double period, double v else { /* The interval wraps around the periodic boundary */ - bIn_interval = ((value >= origin) && (value <= 0.5*period)) || ((value >= -0.5*period) && (value <= end)); + bIn_interval = ((value >= origin) && (value <= 0.5 * period)) + || ((value >= -0.5 * period) && (value <= end)); } } else @@ -649,21 +692,23 @@ static bool valueIsInInterval(double origin, double end, double period, double v * \param[in] awhParams AWH parameters. * \param[in,out] wi Struct for bookeeping warnings. */ -static void checkInputConsistencyInterval(const AwhParams *awhParams, warninp_t wi) +static void checkInputConsistencyInterval(const AwhParams* awhParams, warninp_t wi) { for (int k = 0; k < awhParams->numBias; k++) { - AwhBiasParams *awhBiasParams = &awhParams->awhBiasParams[k]; + AwhBiasParams* awhBiasParams = &awhParams->awhBiasParams[k]; for (int d = 0; d < awhBiasParams->ndim; d++) { - AwhDimParams *dimParams = &awhBiasParams->dimParams[d]; - int coordIndex = dimParams->coordIndex; - double origin = dimParams->origin, end = dimParams->end, period = dimParams->period; - double coordValueInit = dimParams->coordValueInit; + AwhDimParams* dimParams = &awhBiasParams->dimParams[d]; + int coordIndex = dimParams->coordIndex; + double origin = dimParams->origin, end = dimParams->end, period = dimParams->period; + double coordValueInit = dimParams->coordValueInit; if ((period == 0) && (origin > end)) { - gmx_fatal(FARGS, "For the non-periodic pull coordinates awh%d-dim%d-start (%f) cannot be larger than awh%d-dim%d-end (%f)", + gmx_fatal(FARGS, + "For the non-periodic pull coordinates awh%d-dim%d-start (%f) cannot be " + "larger than awh%d-dim%d-end (%f)", k + 1, d + 1, origin, k + 1, d + 1, end); } @@ -677,21 +722,26 @@ static void checkInputConsistencyInterval(const AwhParams *awhParams, warninp_t */ if (!intervalIsInPeriodicInterval(origin, end, period)) { - gmx_fatal(FARGS, "When using AWH with periodic pull coordinate geometries awh%d-dim%d-start (%.8g) and " - "awh%d-dim%d-end (%.8g) should cover at most one period (%.8g) and take values in between " - "minus half a period and plus half a period, i.e. in the interval [%.8g, %.8g].", - k + 1, d + 1, origin, k + 1, d + 1, end, - period, -0.5*period, 0.5*period); - + gmx_fatal(FARGS, + "When using AWH with periodic pull coordinate geometries " + "awh%d-dim%d-start (%.8g) and " + "awh%d-dim%d-end (%.8g) should cover at most one period (%.8g) and take " + "values in between " + "minus half a period and plus half a period, i.e. in the interval [%.8g, " + "%.8g].", + k + 1, d + 1, origin, k + 1, d + 1, end, period, -0.5 * period, 0.5 * period); } /* Warn if the pull initial coordinate value is not in the grid */ if (!valueIsInInterval(origin, end, period, coordValueInit)) { - auto message = formatString - ("The initial coordinate value (%.8g) for pull coordinate index %d falls outside " - "of the sampling nterval awh%d-dim%d-start (%.8g) to awh%d-dim%d-end (%.8g). " - "This can lead to large initial forces pulling the coordinate towards the sampling interval.", + auto message = formatString( + "The initial coordinate value (%.8g) for pull coordinate index %d falls " + "outside " + "of the sampling nterval awh%d-dim%d-start (%.8g) to awh%d-dim%d-end " + "(%.8g). " + "This can lead to large initial forces pulling the coordinate towards the " + "sampling interval.", coordValueInit, coordIndex + 1, k + 1, d + 1, origin, k + 1, d + 1, end); warning(wi, message); } @@ -699,17 +749,20 @@ static void checkInputConsistencyInterval(const AwhParams *awhParams, warninp_t } } -void setStateDependentAwhParams(AwhParams *awhParams, - const pull_params_t *pull_params, pull_t *pull_work, - const matrix box, int ePBC, const tensor &compressibility, - const t_grpopts *inputrecGroupOptions, warninp_t wi) +void setStateDependentAwhParams(AwhParams* awhParams, + const pull_params_t* pull_params, + pull_t* pull_work, + const matrix box, + int ePBC, + const tensor& compressibility, + const t_grpopts* inputrecGroupOptions, + warninp_t wi) { /* The temperature is not really state depenendent but is not known * when read_awhParams is called (in get ir). * It is known first after do_index has been called in grompp.cpp. */ - if (inputrecGroupOptions->ref_t == nullptr || - inputrecGroupOptions->ref_t[0] <= 0) + if (inputrecGroupOptions->ref_t == nullptr || inputrecGroupOptions->ref_t[0] <= 0) { gmx_fatal(FARGS, "AWH biasing is only supported for temperatures > 0"); } @@ -717,35 +770,38 @@ void setStateDependentAwhParams(AwhParams *awhParams, { if (inputrecGroupOptions->ref_t[i] != inputrecGroupOptions->ref_t[0]) { - gmx_fatal(FARGS, "AWH biasing is currently only supported for identical temperatures for all temperature coupling groups"); + gmx_fatal(FARGS, + "AWH biasing is currently only supported for identical temperatures for all " + "temperature coupling groups"); } } - t_pbc pbc; + t_pbc pbc; set_pbc(&pbc, ePBC, box); for (int k = 0; k < awhParams->numBias; k++) { - AwhBiasParams *awhBiasParams = &awhParams->awhBiasParams[k]; + AwhBiasParams* awhBiasParams = &awhParams->awhBiasParams[k]; for (int d = 0; d < awhBiasParams->ndim; d++) { - AwhDimParams *dimParams = &awhBiasParams->dimParams[d]; - const t_pull_coord &pullCoordParams = pull_params->coord[dimParams->coordIndex]; + AwhDimParams* dimParams = &awhBiasParams->dimParams[d]; + const t_pull_coord& pullCoordParams = pull_params->coord[dimParams->coordIndex]; if (pullCoordParams.eGeom == epullgDIRPBC) { - gmx_fatal(FARGS, "AWH does not support pull geometry '%s'. " - "If the maximum distance between the groups is always less than half the box size, " + gmx_fatal(FARGS, + "AWH does not support pull geometry '%s'. " + "If the maximum distance between the groups is always less than half the " + "box size, " "you can use geometry '%s' instead.", - EPULLGEOM(epullgDIRPBC), - EPULLGEOM(epullgDIR)); - + EPULLGEOM(epullgDIRPBC), EPULLGEOM(epullgDIR)); } - dimParams->period = get_pull_coord_period(pullCoordParams, pbc, dimParams->end - dimParams->origin); + dimParams->period = + get_pull_coord_period(pullCoordParams, pbc, dimParams->end - dimParams->origin); // We would like to check for scaling, but we don't have the full inputrec available here - if (dimParams->period > 0 && !(pullCoordParams.eGeom == epullgANGLE || - pullCoordParams.eGeom == epullgDIHEDRAL)) + if (dimParams->period > 0 + && !(pullCoordParams.eGeom == epullgANGLE || pullCoordParams.eGeom == epullgDIHEDRAL)) { bool coordIsScaled = false; for (int d2 = 0; d2 < DIM; d2++) @@ -757,16 +813,17 @@ void setStateDependentAwhParams(AwhParams *awhParams, } if (coordIsScaled) { - std::string mesg = gmx::formatString("AWH dimension %d of bias %d is periodic with pull geometry '%s', " - "while you should are applying pressure scaling to the corresponding box vector, this is not supported.", - d + 1, k + 1, EPULLGEOM(pullCoordParams.eGeom)); + std::string mesg = gmx::formatString( + "AWH dimension %d of bias %d is periodic with pull geometry '%s', " + "while you should are applying pressure scaling to the corresponding " + "box vector, this is not supported.", + d + 1, k + 1, EPULLGEOM(pullCoordParams.eGeom)); warning(wi, mesg.c_str()); } } /* The initial coordinate value, converted to external user units. */ - dimParams->coordValueInit = - get_pull_coord_value(pull_work, dimParams->coordIndex, &pbc); + dimParams->coordValueInit = get_pull_coord_value(pull_work, dimParams->coordIndex, &pbc); dimParams->coordValueInit *= pull_conversion_factor_internal2userinput(&pullCoordParams); } diff --git a/src/gromacs/awh/read_params.h b/src/gromacs/awh/read_params.h index ef2f8eab06..61098890d1 100644 --- a/src/gromacs/awh/read_params.h +++ b/src/gromacs/awh/read_params.h @@ -65,9 +65,7 @@ struct AwhParams; * \param[in,out] wi Struct for bookeeping warnings. * \returns AWH parameters. */ -AwhParams *readAndCheckAwhParams(std::vector *inp, - const t_inputrec *inputrec, - warninp_t wi); +AwhParams* readAndCheckAwhParams(std::vector* inp, const t_inputrec* inputrec, warninp_t wi); /*! \brief @@ -84,15 +82,15 @@ AwhParams *readAndCheckAwhParams(std::vector *inp, * * \note This function currently relies on the function set_pull_init to have been called. */ -void setStateDependentAwhParams(AwhParams *awhParams, - const pull_params_t *pull_params, - pull_t *pull_work, +void setStateDependentAwhParams(AwhParams* awhParams, + const pull_params_t* pull_params, + pull_t* pull_work, const matrix box, int ePBC, - const tensor &compressibility, - const t_grpopts *inputrecGroupOptions, + const tensor& compressibility, + const t_grpopts* inputrecGroupOptions, warninp_t wi); -} // namespace gmx +} // namespace gmx #endif /* GMX_AWH_READPARAMS_H */ diff --git a/src/gromacs/awh/tests/bias.cpp b/src/gromacs/awh/tests/bias.cpp index 4477b7239d..4d5b54a8ee 100644 --- a/src/gromacs/awh/tests/bias.cpp +++ b/src/gromacs/awh/tests/bias.cpp @@ -65,41 +65,43 @@ namespace test struct AwhTestParameters { AwhTestParameters() = default; - //!Move constructor - AwhTestParameters(AwhTestParameters &&o) noexcept : beta(o.beta), awhDimParams(o.awhDimParams), - awhBiasParams(o.awhBiasParams), awhParams(o.awhParams), - dimParams(std::move(o.dimParams)) + //! Move constructor + AwhTestParameters(AwhTestParameters&& o) noexcept : + beta(o.beta), + awhDimParams(o.awhDimParams), + awhBiasParams(o.awhBiasParams), + awhParams(o.awhParams), + dimParams(std::move(o.dimParams)) { awhBiasParams.dimParams = &awhDimParams; awhParams.awhBiasParams = &awhBiasParams; } - double beta; //!< 1/(kB*T) + double beta; //!< 1/(kB*T) - AwhDimParams awhDimParams; //!< Dimension parameters pointed to by \p awhBiasParams - AwhBiasParams awhBiasParams; //!< Bias parameters pointed to by \[ awhParams - AwhParams awhParams; //!< AWH parameters, this is the struct to actually use + AwhDimParams awhDimParams; //!< Dimension parameters pointed to by \p awhBiasParams + AwhBiasParams awhBiasParams; //!< Bias parameters pointed to by \[ awhParams + AwhParams awhParams; //!< AWH parameters, this is the struct to actually use - std::vector dimParams; //!< Dimension parameters for setting up Bias + std::vector dimParams; //!< Dimension parameters for setting up Bias }; //! Helper function to set up the C-style AWH parameters for the test -static AwhTestParameters getAwhTestParameters(int eawhgrowth, - int eawhpotential) +static AwhTestParameters getAwhTestParameters(int eawhgrowth, int eawhpotential) { AwhTestParameters params; params.beta = 0.4; - AwhDimParams &awhDimParams = params.awhDimParams; + AwhDimParams& awhDimParams = params.awhDimParams; - awhDimParams.period = 0; - awhDimParams.diffusion = 0.1; - awhDimParams.origin = 0.5; - awhDimParams.end = 1.5; - awhDimParams.coordValueInit = awhDimParams.origin; - awhDimParams.coverDiameter = 0; + awhDimParams.period = 0; + awhDimParams.diffusion = 0.1; + awhDimParams.origin = 0.5; + awhDimParams.end = 1.5; + awhDimParams.coordValueInit = awhDimParams.origin; + awhDimParams.coverDiameter = 0; - AwhBiasParams &awhBiasParams = params.awhBiasParams; + AwhBiasParams& awhBiasParams = params.awhBiasParams; awhBiasParams.ndim = 1; awhBiasParams.dimParams = &awhDimParams; @@ -108,17 +110,17 @@ static AwhTestParameters getAwhTestParameters(int eawhgrowth, awhBiasParams.targetCutoff = 0; awhBiasParams.eGrowth = eawhgrowth; awhBiasParams.bUserData = FALSE; - awhBiasParams.errorInitial = 0.5/params.beta; + awhBiasParams.errorInitial = 0.5 / params.beta; awhBiasParams.shareGroup = 0; awhBiasParams.equilibrateHistogram = FALSE; - double convFactor = 1; - double k = 1000; - int64_t seed = 93471803; + double convFactor = 1; + double k = 1000; + int64_t seed = 93471803; params.dimParams.emplace_back(convFactor, k, params.beta); - AwhParams &awhParams = params.awhParams; + AwhParams& awhParams = params.awhParams; awhParams.numBias = 1; awhParams.awhBiasParams = &awhBiasParams; @@ -133,29 +135,8 @@ static AwhTestParameters getAwhTestParameters(int eawhgrowth, } //! Database of 21 test coordinates that represent a trajectory */ -const double g_coords[] = { - 0.62, - 0.70, - 0.68, - 0.80, - 0.93, - 0.87, - 1.16, - 1.14, - 0.95, - 0.89, - 0.91, - 0.86, - 0.88, - 0.79, - 0.75, - 0.82, - 0.74, - 0.70, - 0.68, - 0.71, - 0.73 -}; +const double g_coords[] = { 0.62, 0.70, 0.68, 0.80, 0.93, 0.87, 1.16, 1.14, 0.95, 0.89, 0.91, + 0.86, 0.88, 0.79, 0.75, 0.82, 0.74, 0.70, 0.68, 0.71, 0.73 }; //! Convenience typedef: growth type enum, potential type enum, disable update skips typedef std::tuple BiasTestParameters; @@ -164,67 +145,72 @@ typedef std::tuple BiasTestParameters; */ class BiasTest : public ::testing::TestWithParam { - public: - //! Random seed for AWH MC sampling - int64_t seed_; +public: + //! Random seed for AWH MC sampling + int64_t seed_; - //! Coordinates representing a trajectory in time - std::vector coordinates_; - //! The awh Bias - std::unique_ptr bias_; + //! Coordinates representing a trajectory in time + std::vector coordinates_; + //! The awh Bias + std::unique_ptr bias_; - BiasTest() : - coordinates_(std::begin(g_coords), std::end(g_coords)) - { - /* We test all combinations of: - * eawhgrowth: - * eawhgrowthLINEAR: final, normal update phase - * ewahgrowthEXP_LINEAR: intial phase, updated size is constant - * eawhpotential (should only affect the force output): - * eawhpotentialUMBRELLA: MC on lambda (umbrella potential location) - * eawhpotentialCONVOLVED: MD on a convolved potential landscape - * disableUpdateSkips (should not affect the results): - * BiasParams::DisableUpdateSkips::yes: update the point state for every sample - * BiasParams::DisableUpdateSkips::no: update the point state at an interval > 1 sample - * - * Note: It would be nice to explicitly check that eawhpotential - * and disableUpdateSkips do not affect the point state. - * But the reference data will also ensure this. - */ - int eawhgrowth; - int eawhpotential; - BiasParams::DisableUpdateSkips disableUpdateSkips; - std::tie(eawhgrowth, eawhpotential, disableUpdateSkips) = GetParam(); - - /* Set up a basic AWH setup with a single, 1D bias with parameters - * such that we can measure the effects of different parameters. - * The idea is to, among other things, have part of the interval - * not covered by samples. - */ - const AwhTestParameters params = getAwhTestParameters(eawhgrowth, eawhpotential); - - seed_ = params.awhParams.seed; - - double mdTimeStep = 0.1; - - int numSamples = coordinates_.size() - 1; // No sample taken at step 0 - GMX_RELEASE_ASSERT(numSamples % params.awhParams.numSamplesUpdateFreeEnergy == 0, "This test is intended to reproduce the situation when the might need to write output during a normal AWH run, therefore the number of samples should be a multiple of the free-energy update interval (but the test should also runs fine without this condition)."); - - bias_ = std::make_unique(-1, params.awhParams, params.awhBiasParams, params.dimParams, params.beta, mdTimeStep, 1, "", Bias::ThisRankWillDoIO::No, disableUpdateSkips); - } + BiasTest() : coordinates_(std::begin(g_coords), std::end(g_coords)) + { + /* We test all combinations of: + * eawhgrowth: + * eawhgrowthLINEAR: final, normal update phase + * ewahgrowthEXP_LINEAR: intial phase, updated size is constant + * eawhpotential (should only affect the force output): + * eawhpotentialUMBRELLA: MC on lambda (umbrella potential location) + * eawhpotentialCONVOLVED: MD on a convolved potential landscape + * disableUpdateSkips (should not affect the results): + * BiasParams::DisableUpdateSkips::yes: update the point state for every sample + * BiasParams::DisableUpdateSkips::no: update the point state at an interval > 1 sample + * + * Note: It would be nice to explicitly check that eawhpotential + * and disableUpdateSkips do not affect the point state. + * But the reference data will also ensure this. + */ + int eawhgrowth; + int eawhpotential; + BiasParams::DisableUpdateSkips disableUpdateSkips; + std::tie(eawhgrowth, eawhpotential, disableUpdateSkips) = GetParam(); + + /* Set up a basic AWH setup with a single, 1D bias with parameters + * such that we can measure the effects of different parameters. + * The idea is to, among other things, have part of the interval + * not covered by samples. + */ + const AwhTestParameters params = getAwhTestParameters(eawhgrowth, eawhpotential); + + seed_ = params.awhParams.seed; + + double mdTimeStep = 0.1; + + int numSamples = coordinates_.size() - 1; // No sample taken at step 0 + GMX_RELEASE_ASSERT(numSamples % params.awhParams.numSamplesUpdateFreeEnergy == 0, + "This test is intended to reproduce the situation when the might need " + "to write output during a normal AWH run, therefore the number of " + "samples should be a multiple of the free-energy update interval (but " + "the test should also runs fine without this condition)."); + + bias_ = std::make_unique(-1, params.awhParams, params.awhBiasParams, params.dimParams, + params.beta, mdTimeStep, 1, "", Bias::ThisRankWillDoIO::No, + disableUpdateSkips); + } }; TEST_P(BiasTest, ForcesBiasPmf) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - Bias &bias = *bias_; + Bias& bias = *bias_; /* Make strings with the properties we expect to be different in the tests. * These also helps to interpret the reference data. */ - std::vector props; + std::vector props; props.push_back(formatString("stage: %s", bias.state().inInitialStage() ? "initial" : "final")); props.push_back(formatString("convolve forces: %s", bias.params().convolveForce ? "yes" : "no")); props.push_back(formatString("skip updates: %s", bias.params().skipUpdates() ? "yes" : "no")); @@ -233,20 +219,17 @@ TEST_P(BiasTest, ForcesBiasPmf) std::vector force, pot, potJump; - double coordMaxValue = 0; - double potentialJump = 0; - int64_t step = 0; - for (auto &coord : coordinates_) + double coordMaxValue = 0; + double potentialJump = 0; + int64_t step = 0; + for (auto& coord : coordinates_) { coordMaxValue = std::max(coordMaxValue, std::abs(coord)); awh_dvec coordValue = { coord, 0, 0, 0 }; double potential = 0; - gmx::ArrayRef biasForce = - bias.calcForceAndUpdateBias(coordValue, - &potential, &potentialJump, - nullptr, nullptr, step, step, seed_, - nullptr); + gmx::ArrayRef biasForce = bias.calcForceAndUpdateBias( + coordValue, &potential, &potentialJump, nullptr, nullptr, step, step, seed_, nullptr); force.push_back(biasForce[0]); pot.push_back(potential); @@ -264,7 +247,7 @@ TEST_P(BiasTest, ForcesBiasPmf) } std::vector pointBias, logPmfsum; - for (auto &point : bias.state().points()) + for (auto& point : bias.state().points()) { pointBias.push_back(point.bias()); logPmfsum.push_back(point.logPmfSum()); @@ -274,15 +257,15 @@ TEST_P(BiasTest, ForcesBiasPmf) * In taking this deviation we lose a lot of precision, so we should * compare against k*max(coord) instead of the instantaneous force. */ - const double kCoordMax = bias.dimParams()[0].k*coordMaxValue; + const double kCoordMax = bias.dimParams()[0].k * coordMaxValue; - constexpr int ulpTol = 10; + constexpr int ulpTol = 10; - checker.checkSequence(props.begin(), props.end(), "Properties"); - checker.setDefaultTolerance(absoluteTolerance(kCoordMax*GMX_DOUBLE_EPS*ulpTol)); - checker.checkSequence(force.begin(), force.end(), "Force"); - checker.checkSequence(pot.begin(), pot.end(), "Potential"); - checker.checkSequence(potJump.begin(), potJump.end(), "PotentialJump"); + checker.checkSequence(props.begin(), props.end(), "Properties"); + checker.setDefaultTolerance(absoluteTolerance(kCoordMax * GMX_DOUBLE_EPS * ulpTol)); + checker.checkSequence(force.begin(), force.end(), "Force"); + checker.checkSequence(pot.begin(), pot.end(), "Potential"); + checker.checkSequence(potJump.begin(), potJump.end(), "PotentialJump"); checker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpTol)); checker.checkSequence(pointBias.begin(), pointBias.end(), "PointBias"); checker.checkSequence(logPmfsum.begin(), logPmfsum.end(), "PointLogPmfsum"); @@ -293,45 +276,45 @@ TEST_P(BiasTest, ForcesBiasPmf) * It would be nice if the test would explicitly check for this. * Currently this is tested through identical reference data. */ -INSTANTIATE_TEST_CASE_P(WithParameters, BiasTest, - ::testing::Combine( - ::testing::Values(eawhgrowthLINEAR, eawhgrowthEXP_LINEAR), - ::testing::Values(eawhpotentialUMBRELLA, eawhpotentialCONVOLVED), - ::testing::Values(BiasParams::DisableUpdateSkips::yes, BiasParams::DisableUpdateSkips::no))); +INSTANTIATE_TEST_CASE_P(WithParameters, + BiasTest, + ::testing::Combine(::testing::Values(eawhgrowthLINEAR, eawhgrowthEXP_LINEAR), + ::testing::Values(eawhpotentialUMBRELLA, eawhpotentialCONVOLVED), + ::testing::Values(BiasParams::DisableUpdateSkips::yes, + BiasParams::DisableUpdateSkips::no))); // Test that we detect coverings and exit the initial stage at the correct step TEST(BiasTest, DetectsCovering) { - const AwhTestParameters params = getAwhTestParameters(eawhgrowthEXP_LINEAR, eawhpotentialCONVOLVED); - const AwhDimParams &awhDimParams = params.awhParams.awhBiasParams[0].dimParams[0]; + const AwhTestParameters params = getAwhTestParameters(eawhgrowthEXP_LINEAR, eawhpotentialCONVOLVED); + const AwhDimParams& awhDimParams = params.awhParams.awhBiasParams[0].dimParams[0]; - const double mdTimeStep = 0.1; + const double mdTimeStep = 0.1; - Bias bias(-1, params.awhParams, params.awhBiasParams, params.dimParams, params.beta, mdTimeStep, 1, "", Bias::ThisRankWillDoIO::No); + Bias bias(-1, params.awhParams, params.awhBiasParams, params.dimParams, params.beta, mdTimeStep, + 1, "", Bias::ThisRankWillDoIO::No); /* We use a trajectory of the sum of two sines to cover the reaction * coordinate range in a semi-realistic way. The period is 4*pi=12.57. * We get out of the initial stage after 4 coverings at step 300. */ - const int64_t exitStepRef = 300; - const double midPoint = 0.5*(awhDimParams.end + awhDimParams.origin); - const double halfWidth = 0.5*(awhDimParams.end - awhDimParams.origin); + const int64_t exitStepRef = 300; + const double midPoint = 0.5 * (awhDimParams.end + awhDimParams.origin); + const double halfWidth = 0.5 * (awhDimParams.end - awhDimParams.origin); - bool inInitialStage = bias.state().inInitialStage(); + bool inInitialStage = bias.state().inInitialStage(); /* Normally this loop exits at exitStepRef, but we extend with failure */ - int64_t step; - for (step = 0; step <= 2*exitStepRef; step++) + int64_t step; + for (step = 0; step <= 2 * exitStepRef; step++) { - double t = step*mdTimeStep; - double coord = midPoint + halfWidth*(0.5*std::sin(t) + 0.55*std::sin(1.5*t)); + double t = step * mdTimeStep; + double coord = midPoint + halfWidth * (0.5 * std::sin(t) + 0.55 * std::sin(1.5 * t)); awh_dvec coordValue = { coord, 0, 0, 0 }; double potential = 0; double potentialJump = 0; - bias.calcForceAndUpdateBias(coordValue, - &potential, &potentialJump, - nullptr, nullptr, - step, step, params.awhParams.seed, nullptr); + bias.calcForceAndUpdateBias(coordValue, &potential, &potentialJump, nullptr, nullptr, step, + step, params.awhParams.seed, nullptr); inInitialStage = bias.state().inInitialStage(); if (!inInitialStage) @@ -347,5 +330,5 @@ TEST(BiasTest, DetectsCovering) } } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/awh/tests/biasstate.cpp b/src/gromacs/awh/tests/biasstate.cpp index 85750cb543..ba2620ac06 100644 --- a/src/gromacs/awh/tests/biasstate.cpp +++ b/src/gromacs/awh/tests/biasstate.cpp @@ -64,7 +64,7 @@ namespace test */ struct AwhTestParameters { - double beta; //!< 1/(kB*T) + double beta; //!< 1/(kB*T) AwhDimParams awhDimParams[2]; //!< Dimension parameters pointed to by \p awhBiasParams AwhBiasParams awhBiasParams; //!< Bias parameters pointed to by \[ awhParams @@ -78,28 +78,28 @@ static AwhTestParameters getAwhTestParameters() params.beta = 1.0; - AwhParams &awhParams = params.awhParams; + AwhParams& awhParams = params.awhParams; snew(params.awhParams.awhBiasParams, 1); - AwhBiasParams &awhBiasParams = params.awhParams.awhBiasParams[0]; + AwhBiasParams& awhBiasParams = params.awhParams.awhBiasParams[0]; snew(awhBiasParams.dimParams, 2); - AwhDimParams &awhDimParams0 = awhBiasParams.dimParams[0]; + AwhDimParams& awhDimParams0 = awhBiasParams.dimParams[0]; - awhDimParams0.period = 0; - awhDimParams0.diffusion = 0.1; - awhDimParams0.origin = 0.5; - awhDimParams0.end = 1.5; - awhDimParams0.coordValueInit = awhDimParams0.origin; - awhDimParams0.coverDiameter = 0; + awhDimParams0.period = 0; + awhDimParams0.diffusion = 0.1; + awhDimParams0.origin = 0.5; + awhDimParams0.end = 1.5; + awhDimParams0.coordValueInit = awhDimParams0.origin; + awhDimParams0.coverDiameter = 0; - AwhDimParams &awhDimParams1 = awhBiasParams.dimParams[1]; + AwhDimParams& awhDimParams1 = awhBiasParams.dimParams[1]; - awhDimParams1.period = 0; - awhDimParams1.diffusion = 0.1; - awhDimParams1.origin = 0.8; - awhDimParams1.end = 1.3; - awhDimParams1.coordValueInit = awhDimParams1.origin; - awhDimParams1.coverDiameter = 0; + awhDimParams1.period = 0; + awhDimParams1.diffusion = 0.1; + awhDimParams1.origin = 0.8; + awhDimParams1.end = 1.3; + awhDimParams1.coordValueInit = awhDimParams1.origin; + awhDimParams1.coverDiameter = 0; awhBiasParams.ndim = 2; awhBiasParams.eTarget = eawhtargetCONSTANT; @@ -124,30 +124,32 @@ static AwhTestParameters getAwhTestParameters() /*! \brief Test fixture for testing Bias updates */ -class BiasStateTest : public ::testing::TestWithParam +class BiasStateTest : public ::testing::TestWithParam { - public: - std::unique_ptr biasState_; //!< The bias state - - BiasStateTest() - { - AwhTestParameters params = getAwhTestParameters(); - const AwhParams &awhParams = params.awhParams; - const AwhBiasParams &awhBiasParams = awhParams.awhBiasParams[0]; - std::vector dimParams; - dimParams.emplace_back(1.0, 15.0, params.beta); - dimParams.emplace_back(1.0, 15.0, params.beta); - Grid grid(dimParams, awhBiasParams.dimParams); - BiasParams biasParams(awhParams, awhBiasParams, dimParams, 1.0, 1.0, BiasParams::DisableUpdateSkips::no, 1, grid.axis(), 0); - biasState_ = std::make_unique(awhBiasParams, 1.0, dimParams, grid); - - // Here we initialize the grid point state using the input file - std::string filename = gmx::test::TestFileManager::getInputFilePath(GetParam()); - biasState_->initGridPointState(awhBiasParams, dimParams, grid, biasParams, filename, params.awhParams.numBias); - - sfree(params.awhParams.awhBiasParams[0].dimParams); - sfree(params.awhParams.awhBiasParams); - } +public: + std::unique_ptr biasState_; //!< The bias state + + BiasStateTest() + { + AwhTestParameters params = getAwhTestParameters(); + const AwhParams& awhParams = params.awhParams; + const AwhBiasParams& awhBiasParams = awhParams.awhBiasParams[0]; + std::vector dimParams; + dimParams.emplace_back(1.0, 15.0, params.beta); + dimParams.emplace_back(1.0, 15.0, params.beta); + Grid grid(dimParams, awhBiasParams.dimParams); + BiasParams biasParams(awhParams, awhBiasParams, dimParams, 1.0, 1.0, + BiasParams::DisableUpdateSkips::no, 1, grid.axis(), 0); + biasState_ = std::make_unique(awhBiasParams, 1.0, dimParams, grid); + + // Here we initialize the grid point state using the input file + std::string filename = gmx::test::TestFileManager::getInputFilePath(GetParam()); + biasState_->initGridPointState(awhBiasParams, dimParams, grid, biasParams, filename, + params.awhParams.numBias); + + sfree(params.awhParams.awhBiasParams[0].dimParams); + sfree(params.awhParams.awhBiasParams); + } }; TEST_P(BiasStateTest, InitializesFromFile) @@ -158,11 +160,11 @@ TEST_P(BiasStateTest, InitializesFromFile) * The PMF values are spaced by 0.5 per points and logPmfsum has opposite sign. * The target is (index + 1)/120. */ - double msdPmf = 0; + double msdPmf = 0; for (index i = 0; i < points.ssize(); i++) { - msdPmf += gmx::square(points[i].logPmfSum() - points[0].logPmfSum() + 0.5*i) / points.size(); - EXPECT_DOUBLE_EQ(points[i].target(), (i + 1)/120.0); + msdPmf += gmx::square(points[i].logPmfSum() - points[0].logPmfSum() + 0.5 * i) / points.size(); + EXPECT_DOUBLE_EQ(points[i].target(), (i + 1) / 120.0); } EXPECT_NEAR(0.0, msdPmf, 1e-31); @@ -170,9 +172,9 @@ TEST_P(BiasStateTest, InitializesFromFile) // Test that Bias initialization open and reads the correct initialization // files and the correct PMF and target distribution is set. -INSTANTIATE_TEST_CASE_P(WithParameters, BiasStateTest, - ::testing::Values("pmf_target_format0.xvg", - "pmf_target_format1.xvg")); +INSTANTIATE_TEST_CASE_P(WithParameters, + BiasStateTest, + ::testing::Values("pmf_target_format0.xvg", "pmf_target_format1.xvg")); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/awh/tests/grid.cpp b/src/gromacs/awh/tests/grid.cpp index 04adccf90a..0e1f417239 100644 --- a/src/gromacs/awh/tests/grid.cpp +++ b/src/gromacs/awh/tests/grid.cpp @@ -57,8 +57,10 @@ namespace test TEST(gridTest, neighborhood) { - constexpr double pointsPerScope = Grid::c_scopeCutoff*Grid::c_numPointsPerSigma; - GMX_RELEASE_ASSERT(std::abs(pointsPerScope - std::round(pointsPerScope)) > 1e-4, "If the scope is close to an integer number of points, this test can be unstable due to rounding issues"); + constexpr double pointsPerScope = Grid::c_scopeCutoff * Grid::c_numPointsPerSigma; + GMX_RELEASE_ASSERT(std::abs(pointsPerScope - std::round(pointsPerScope)) > 1e-4, + "If the scope is close to an integer number of points, this test can be " + "unstable due to rounding issues"); const int scopeInPoints = static_cast(pointsPerScope); @@ -71,34 +73,36 @@ TEST(gridTest, neighborhood) const int numDim = 2; std::vector awhDimParams(numDim); - awhDimParams[0].origin = -5; - awhDimParams[0].end = 5; - awhDimParams[0].period = 10; + awhDimParams[0].origin = -5; + awhDimParams[0].end = 5; + awhDimParams[0].period = 10; - awhDimParams[1].origin = 0.5; - awhDimParams[1].end = 2.0; - awhDimParams[1].period = 0; + awhDimParams[1].origin = 0.5; + awhDimParams[1].end = 2.0; + awhDimParams[1].period = 0; const real conversionFactor = 1; const real beta = 3.0; /* Set up dimParams to get about 15 points along each dimension */ std::vector dimParams; - dimParams.emplace_back(conversionFactor, 1/(beta*0.7*0.7), beta); - dimParams.emplace_back(conversionFactor, 1/(beta*0.1*0.1), beta); + dimParams.emplace_back(conversionFactor, 1 / (beta * 0.7 * 0.7), beta); + dimParams.emplace_back(conversionFactor, 1 / (beta * 0.1 * 0.1), beta); - Grid grid(dimParams, awhDimParams.data()); + Grid grid(dimParams, awhDimParams.data()); - const int numPoints = grid.numPoints(); + const int numPoints = grid.numPoints(); - int numPointsDim[numDim]; + int numPointsDim[numDim]; for (int d = 0; d < numDim; d++) { - numPointsDim[d] = grid.axis(d).numPoints(); + numPointsDim[d] = grid.axis(d).numPoints(); - GMX_RELEASE_ASSERT(numPointsDim[d] >= 2*scopeInPoints + 1, "The test code currently assume that the grid is larger of equal to the scope in each dimension"); + GMX_RELEASE_ASSERT(numPointsDim[d] >= 2 * scopeInPoints + 1, + "The test code currently assume that the grid is larger of equal to the " + "scope in each dimension"); } - int halfNumPoints0 = numPointsDim[0]/2; + int halfNumPoints0 = numPointsDim[0] / 2; bool haveOutOfGridNeighbors = false; bool haveDuplicateNeighbors = false; @@ -111,24 +115,25 @@ TEST(gridTest, neighborhood) /* Checking for all points is overkill, we check every 7th */ for (size_t i = 0; i < grid.numPoints(); i += 7) { - const GridPoint &point = grid.point(i); + const GridPoint& point = grid.point(i); /* NOTE: This code relies on major-minor index ordering in Grid */ - int pointIndex0 = i/numPointsDim[1]; - int pointIndex1 = i - pointIndex0*numPointsDim[1]; + int pointIndex0 = i / numPointsDim[1]; + int pointIndex1 = i - pointIndex0 * numPointsDim[1]; /* To check if we have the correct neighbors, we check the expected * number of neighbors, if all neighbors are within the grid bounds * and if they are within scope. */ int distanceFromEdge1 = std::min(pointIndex1, numPointsDim[1] - 1 - pointIndex1); - size_t numNeighbors = (2*scopeInPoints + 1)*(scopeInPoints + std::min(scopeInPoints, distanceFromEdge1) + 1); + size_t numNeighbors = (2 * scopeInPoints + 1) + * (scopeInPoints + std::min(scopeInPoints, distanceFromEdge1) + 1); if (point.neighbor.size() != numNeighbors) { haveCorrectNumNeighbors = false; } - for (auto &j : point.neighbor) + for (auto& j : point.neighbor) { if (j >= 0 && j < numPoints) { @@ -138,11 +143,11 @@ TEST(gridTest, neighborhood) } isInNeighborhood[j] = true; - int neighborIndex0 = j/numPointsDim[1]; - int neighborIndex1 = j - neighborIndex0*numPointsDim[1]; + int neighborIndex0 = j / numPointsDim[1]; + int neighborIndex1 = j - neighborIndex0 * numPointsDim[1]; - int distance0 = neighborIndex0 - pointIndex0; - int distance1 = neighborIndex1 - pointIndex1; + int distance0 = neighborIndex0 - pointIndex0; + int distance1 = neighborIndex1 - pointIndex1; /* Adjust distance for periodicity of dimension 0 */ if (distance0 < -halfNumPoints0) { @@ -153,8 +158,8 @@ TEST(gridTest, neighborhood) distance0 -= numPointsDim[0]; } /* Check if the distance is within scope */ - if (distance0 < -scopeInPoints || distance0 > scopeInPoints || - distance1 < -scopeInPoints || distance1 > scopeInPoints) + if (distance0 < -scopeInPoints || distance0 > scopeInPoints + || distance1 < -scopeInPoints || distance1 > scopeInPoints) { haveIncorrectNeighbors = true; } @@ -166,7 +171,7 @@ TEST(gridTest, neighborhood) } /* Clear the marked points in the checking grid */ - for (auto &neighbor : point.neighbor) + for (auto& neighbor : point.neighbor) { if (neighbor >= 0 && neighbor < numPoints) { @@ -181,5 +186,5 @@ TEST(gridTest, neighborhood) EXPECT_TRUE(haveCorrectNumNeighbors); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/commandline/cmdlinehelpcontext.cpp b/src/gromacs/commandline/cmdlinehelpcontext.cpp index b65a065a7d..5858579b1f 100644 --- a/src/gromacs/commandline/cmdlinehelpcontext.cpp +++ b/src/gromacs/commandline/cmdlinehelpcontext.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,9 +61,9 @@ namespace * * \ingroup module_commandline */ -const CommandLineHelpContext *g_globalContext = nullptr; +const CommandLineHelpContext* g_globalContext = nullptr; -} // namespace +} // namespace /*! \internal \brief * Private implementation class for CommandLineHelpContext. @@ -72,75 +72,72 @@ const CommandLineHelpContext *g_globalContext = nullptr; */ class CommandLineHelpContext::Impl { - public: - //! Creates the implementation class and the low-level context. - Impl(TextWriter *writer, HelpOutputFormat format, - const HelpLinks *links) - : writerContext_(writer, format, links), moduleDisplayName_("gmx"), - completionWriter_(nullptr), bHidden_(false) - { - } - //! Creates an implementation class from a low-level context. - explicit Impl(const HelpWriterContext &writerContext) - : writerContext_(writerContext), - completionWriter_(nullptr), bHidden_(false) - { - } - - //! Wrapped lower-level context. - HelpWriterContext writerContext_; - //! Display name for the module for which help is written. - std::string moduleDisplayName_; - //! Shell completion writer (`NULL` if not doing completions). - ShellCompletionWriter *completionWriter_; - //! Whether hidden options should be shown in help output. - bool bHidden_; +public: + //! Creates the implementation class and the low-level context. + Impl(TextWriter* writer, HelpOutputFormat format, const HelpLinks* links) : + writerContext_(writer, format, links), + moduleDisplayName_("gmx"), + completionWriter_(nullptr), + bHidden_(false) + { + } + //! Creates an implementation class from a low-level context. + explicit Impl(const HelpWriterContext& writerContext) : + writerContext_(writerContext), + completionWriter_(nullptr), + bHidden_(false) + { + } + + //! Wrapped lower-level context. + HelpWriterContext writerContext_; + //! Display name for the module for which help is written. + std::string moduleDisplayName_; + //! Shell completion writer (`NULL` if not doing completions). + ShellCompletionWriter* completionWriter_; + //! Whether hidden options should be shown in help output. + bool bHidden_; }; -CommandLineHelpContext::CommandLineHelpContext( - TextWriter *writer, HelpOutputFormat format, - const HelpLinks *links, const std::string &programName) - : impl_(new Impl(writer, format, links)) +CommandLineHelpContext::CommandLineHelpContext(TextWriter* writer, + HelpOutputFormat format, + const HelpLinks* links, + const std::string& programName) : + impl_(new Impl(writer, format, links)) { impl_->writerContext_.setReplacement("[PROGRAM]", programName); } -CommandLineHelpContext::CommandLineHelpContext( - const HelpWriterContext &writerContext) - : impl_(new Impl(writerContext)) +CommandLineHelpContext::CommandLineHelpContext(const HelpWriterContext& writerContext) : + impl_(new Impl(writerContext)) { } -CommandLineHelpContext::CommandLineHelpContext( - ShellCompletionWriter *writer) - : impl_(new Impl(&writer->outputWriter(), eHelpOutputFormat_Other, nullptr)) +CommandLineHelpContext::CommandLineHelpContext(ShellCompletionWriter* writer) : + impl_(new Impl(&writer->outputWriter(), eHelpOutputFormat_Other, nullptr)) { impl_->completionWriter_ = writer; } -CommandLineHelpContext::CommandLineHelpContext( - const CommandLineHelpContext &other) - : impl_(new Impl(*other.impl_)) +CommandLineHelpContext::CommandLineHelpContext(const CommandLineHelpContext& other) : + impl_(new Impl(*other.impl_)) { } -CommandLineHelpContext::CommandLineHelpContext(CommandLineHelpContext &&other) noexcept - : impl_(std::move(other.impl_)) +CommandLineHelpContext::CommandLineHelpContext(CommandLineHelpContext&& other) noexcept : + impl_(std::move(other.impl_)) { } -CommandLineHelpContext &CommandLineHelpContext::operator=( - CommandLineHelpContext &&other) noexcept +CommandLineHelpContext& CommandLineHelpContext::operator=(CommandLineHelpContext&& other) noexcept { impl_ = std::move(other.impl_); return *this; } -CommandLineHelpContext::~CommandLineHelpContext() -{ -} +CommandLineHelpContext::~CommandLineHelpContext() {} -void CommandLineHelpContext::setModuleDisplayName(const std::string &name) +void CommandLineHelpContext::setModuleDisplayName(const std::string& name) { impl_->writerContext_.setReplacement("[THISMODULE]", "[TT]" + name + "[tt]"); impl_->moduleDisplayName_ = name; @@ -151,17 +148,17 @@ void CommandLineHelpContext::setShowHidden(bool bHidden) impl_->bHidden_ = bHidden; } -void CommandLineHelpContext::enterSubSection(const std::string &title) +void CommandLineHelpContext::enterSubSection(const std::string& title) { impl_->writerContext_.enterSubSection(title); } -const HelpWriterContext &CommandLineHelpContext::writerContext() const +const HelpWriterContext& CommandLineHelpContext::writerContext() const { return impl_->writerContext_; } -const char *CommandLineHelpContext::moduleDisplayName() const +const char* CommandLineHelpContext::moduleDisplayName() const { return impl_->moduleDisplayName_.c_str(); } @@ -176,10 +173,9 @@ bool CommandLineHelpContext::isCompletionExport() const return impl_->completionWriter_ != nullptr; } -ShellCompletionWriter &CommandLineHelpContext::shellCompletionWriter() const +ShellCompletionWriter& CommandLineHelpContext::shellCompletionWriter() const { - GMX_RELEASE_ASSERT(isCompletionExport(), - "Invalid call when not writing shell completions"); + GMX_RELEASE_ASSERT(isCompletionExport(), "Invalid call when not writing shell completions"); return *impl_->completionWriter_; } @@ -188,16 +184,14 @@ ShellCompletionWriter &CommandLineHelpContext::shellCompletionWriter() const */ // static -const CommandLineHelpContext *GlobalCommandLineHelpContext::get() +const CommandLineHelpContext* GlobalCommandLineHelpContext::get() { return g_globalContext; } -GlobalCommandLineHelpContext::GlobalCommandLineHelpContext( - const CommandLineHelpContext &context) +GlobalCommandLineHelpContext::GlobalCommandLineHelpContext(const CommandLineHelpContext& context) { - GMX_RELEASE_ASSERT(g_globalContext == nullptr, - "Global context set more than once"); + GMX_RELEASE_ASSERT(g_globalContext == nullptr, "Global context set more than once"); g_globalContext = &context; } diff --git a/src/gromacs/commandline/cmdlinehelpcontext.h b/src/gromacs/commandline/cmdlinehelpcontext.h index 1b0c144f3a..a2158603a9 100644 --- a/src/gromacs/commandline/cmdlinehelpcontext.h +++ b/src/gromacs/commandline/cmdlinehelpcontext.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,65 +70,66 @@ class ShellCompletionWriter; */ class CommandLineHelpContext { - public: - /*! \brief - * Creates a context for help export. - * - * Wraps the constructor of HelpWriterContext. - */ - CommandLineHelpContext(TextWriter *writer, - HelpOutputFormat format, const HelpLinks *links, - const std::string &programName); - //! Creates a context for a particular HelpWriterContext. - explicit CommandLineHelpContext(const HelpWriterContext &writerContext); - /*! \brief - * Creates a context for shell completion. - */ - explicit CommandLineHelpContext(ShellCompletionWriter *writer); - //! Creates a copy of the context. - explicit CommandLineHelpContext(const CommandLineHelpContext &other); - //! Moves the context. - CommandLineHelpContext(CommandLineHelpContext &&other) noexcept; - //! Move-assigns the context. - CommandLineHelpContext &operator=(CommandLineHelpContext &&other) noexcept; - ~CommandLineHelpContext(); +public: + /*! \brief + * Creates a context for help export. + * + * Wraps the constructor of HelpWriterContext. + */ + CommandLineHelpContext(TextWriter* writer, + HelpOutputFormat format, + const HelpLinks* links, + const std::string& programName); + //! Creates a context for a particular HelpWriterContext. + explicit CommandLineHelpContext(const HelpWriterContext& writerContext); + /*! \brief + * Creates a context for shell completion. + */ + explicit CommandLineHelpContext(ShellCompletionWriter* writer); + //! Creates a copy of the context. + explicit CommandLineHelpContext(const CommandLineHelpContext& other); + //! Moves the context. + CommandLineHelpContext(CommandLineHelpContext&& other) noexcept; + //! Move-assigns the context. + CommandLineHelpContext& operator=(CommandLineHelpContext&& other) noexcept; + ~CommandLineHelpContext(); - /*! \brief - * Sets a display name for the module for which help is being written. - * - * \throws std::bad_alloc if out of memory. - */ - void setModuleDisplayName(const std::string &name); - //! Sets whether hidden options should be shown in help output. - void setShowHidden(bool bHidden); - //! \copydoc HelpWriterContext::enterSubSection() - void enterSubSection(const std::string &title); + /*! \brief + * Sets a display name for the module for which help is being written. + * + * \throws std::bad_alloc if out of memory. + */ + void setModuleDisplayName(const std::string& name); + //! Sets whether hidden options should be shown in help output. + void setShowHidden(bool bHidden); + //! \copydoc HelpWriterContext::enterSubSection() + void enterSubSection(const std::string& title); - //! Returns the lower-level context for writing the help. - const HelpWriterContext &writerContext() const; - /*! \brief - * Returns a display name for the module for which help is being written. - * - * Does not throw. - */ - const char *moduleDisplayName() const; - //! Returns whether hidden options should be shown in help output. - bool showHidden() const; - //! Returns whether this context is for exporting shell completions. - bool isCompletionExport() const; - /*! \brief - * Returns the shell completion writer for this context. - * - * Can only be called if isCompletionExport() returns `true`. - */ - ShellCompletionWriter &shellCompletionWriter() const; + //! Returns the lower-level context for writing the help. + const HelpWriterContext& writerContext() const; + /*! \brief + * Returns a display name for the module for which help is being written. + * + * Does not throw. + */ + const char* moduleDisplayName() const; + //! Returns whether hidden options should be shown in help output. + bool showHidden() const; + //! Returns whether this context is for exporting shell completions. + bool isCompletionExport() const; + /*! \brief + * Returns the shell completion writer for this context. + * + * Can only be called if isCompletionExport() returns `true`. + */ + ShellCompletionWriter& shellCompletionWriter() const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - GMX_DISALLOW_ASSIGN(CommandLineHelpContext); + GMX_DISALLOW_ASSIGN(CommandLineHelpContext); }; /*! \libinternal \brief @@ -146,21 +147,21 @@ class CommandLineHelpContext */ class GlobalCommandLineHelpContext { - public: - //! Returns the global context, or NULL if not set. - static const CommandLineHelpContext *get(); +public: + //! Returns the global context, or NULL if not set. + static const CommandLineHelpContext* get(); - /*! \brief - * Sets the global context for the scope. - * - * The global context is cleared when this object goes out of scope. - * - * It is an error to have more than one GlobalCommandLineHelpContext - * object in existence at the same time. - */ - explicit GlobalCommandLineHelpContext(const CommandLineHelpContext &context); - //! Clears the global context. - ~GlobalCommandLineHelpContext(); + /*! \brief + * Sets the global context for the scope. + * + * The global context is cleared when this object goes out of scope. + * + * It is an error to have more than one GlobalCommandLineHelpContext + * object in existence at the same time. + */ + explicit GlobalCommandLineHelpContext(const CommandLineHelpContext& context); + //! Clears the global context. + ~GlobalCommandLineHelpContext(); }; } // namespace gmx diff --git a/src/gromacs/commandline/cmdlinehelpmodule.cpp b/src/gromacs/commandline/cmdlinehelpmodule.cpp index 755617245e..cbcb84fefa 100644 --- a/src/gromacs/commandline/cmdlinehelpmodule.cpp +++ b/src/gromacs/commandline/cmdlinehelpmodule.cpp @@ -89,48 +89,45 @@ class IHelpExport; */ class RootHelpTopic : public AbstractCompositeHelpTopic { - public: - /*! \brief - * Creates a root help topic. - * - * Does not throw. - */ - explicit RootHelpTopic(const CommandLineHelpModuleImpl &helpModule) - : helpModule_(helpModule) +public: + /*! \brief + * Creates a root help topic. + * + * Does not throw. + */ + explicit RootHelpTopic(const CommandLineHelpModuleImpl& helpModule) : helpModule_(helpModule) {} + + const char* name() const override; + const char* title() const override { return title_.c_str(); } + + //! Adds a top-level topic and optionally marks it as exported. + void addTopic(HelpTopicPointer topic, bool bExported) + { + if (bExported) { + exportedTopics_.emplace_back(topic->name()); } + addSubTopic(std::move(topic)); + } + //! Exports all the top-level topics with the given exporter. + void exportHelp(IHelpExport* exporter); - const char *name() const override; - const char *title() const override { return title_.c_str(); } - - //! Adds a top-level topic and optionally marks it as exported. - void addTopic(HelpTopicPointer topic, bool bExported) - { - if (bExported) - { - exportedTopics_.emplace_back(topic->name()); - } - addSubTopic(std::move(topic)); - } - //! Exports all the top-level topics with the given exporter. - void exportHelp(IHelpExport *exporter); - - void writeHelp(const HelpWriterContext &context) const override; + void writeHelp(const HelpWriterContext& context) const override; - private: - // unused because of the writeHelp() override - std::string helpText() const override { return ""; } +private: + // unused because of the writeHelp() override + std::string helpText() const override { return ""; } - CommandLineHelpContext createContext(const HelpWriterContext &context) const; + CommandLineHelpContext createContext(const HelpWriterContext& context) const; - const CommandLineHelpModuleImpl &helpModule_; - std::string title_; - std::vector exportedTopics_; + const CommandLineHelpModuleImpl& helpModule_; + std::string title_; + std::vector exportedTopics_; - GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic); + GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic); }; -} // namespace +} // namespace /******************************************************************** * CommandLineHelpModuleImpl declaration @@ -138,30 +135,28 @@ class RootHelpTopic : public AbstractCompositeHelpTopic class CommandLineHelpModuleImpl { - public: - CommandLineHelpModuleImpl(const IProgramContext &programContext, - const std::string &binaryName, - const CommandLineModuleMap &modules, - const CommandLineModuleGroupList &groups); +public: + CommandLineHelpModuleImpl(const IProgramContext& programContext, + const std::string& binaryName, + const CommandLineModuleMap& modules, + const CommandLineModuleGroupList& groups); - std::unique_ptr createExporter( - const std::string &format, - IFileOutputRedirector *redirector); - void exportHelp(IHelpExport *exporter); + std::unique_ptr createExporter(const std::string& format, IFileOutputRedirector* redirector); + void exportHelp(IHelpExport* exporter); - RootHelpTopic rootTopic_; - const IProgramContext &programContext_; - std::string binaryName_; - const CommandLineModuleMap &modules_; - const CommandLineModuleGroupList &groups_; + RootHelpTopic rootTopic_; + const IProgramContext& programContext_; + std::string binaryName_; + const CommandLineModuleMap& modules_; + const CommandLineModuleGroupList& groups_; - CommandLineHelpContext *context_; - const ICommandLineModule *moduleOverride_; - bool bHidden_; + CommandLineHelpContext* context_; + const ICommandLineModule* moduleOverride_; + bool bHidden_; - IFileOutputRedirector *outputRedirector_; + IFileOutputRedirector* outputRedirector_; - GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl); + GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl); }; namespace @@ -178,67 +173,65 @@ namespace */ class IHelpExport { - public: - //! Shorthand for a list of modules contained in a group. - typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents; - - virtual ~IHelpExport() {} - - /*! \brief - * Called once before exporting individual modules. - * - * Can, e.g., open shared output files (e.g., if the output is written - * into a single file, or if a separate index is required) and write - * headers into them. - */ - virtual void startModuleExport() = 0; - /*! \brief - * Called to export the help for each module. - * - * \param[in] module Module for which the help should be exported. - * \param[in] tag Unique tag for the module (gmx-something). - * \param[in] displayName Display name for the module (gmx something). - */ - virtual void exportModuleHelp( - const ICommandLineModule &module, - const std::string &tag, - const std::string &displayName) = 0; - /*! \brief - * Called after all modules have been exported. - * - * Can close files opened in startModuleExport(), write footers to them - * etc. - */ - virtual void finishModuleExport() = 0; - - /*! \brief - * Called once before exporting module groups. - * - * Can, e.g., open a single output file for listing all the groups. - */ - virtual void startModuleGroupExport() = 0; - /*! \brief - * Called to export the help for each module group. - * - * \param[in] title Title for the group. - * \param[in] modules List of modules in the group. - */ - virtual void exportModuleGroup(const char *title, - const ModuleGroupContents &modules) = 0; - /*! \brief - * Called after all module groups have been exported. - * - * Can close files opened in startModuleGroupExport(), write footers to them - * etc. - */ - virtual void finishModuleGroupExport() = 0; - - /*! \brief - * Called to export the help for a top-level topic. - * - * \param[in] topic Topic to export. - */ - virtual void exportTopic(const IHelpTopic &topic) = 0; +public: + //! Shorthand for a list of modules contained in a group. + typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents; + + virtual ~IHelpExport() {} + + /*! \brief + * Called once before exporting individual modules. + * + * Can, e.g., open shared output files (e.g., if the output is written + * into a single file, or if a separate index is required) and write + * headers into them. + */ + virtual void startModuleExport() = 0; + /*! \brief + * Called to export the help for each module. + * + * \param[in] module Module for which the help should be exported. + * \param[in] tag Unique tag for the module (gmx-something). + * \param[in] displayName Display name for the module (gmx something). + */ + virtual void exportModuleHelp(const ICommandLineModule& module, + const std::string& tag, + const std::string& displayName) = 0; + /*! \brief + * Called after all modules have been exported. + * + * Can close files opened in startModuleExport(), write footers to them + * etc. + */ + virtual void finishModuleExport() = 0; + + /*! \brief + * Called once before exporting module groups. + * + * Can, e.g., open a single output file for listing all the groups. + */ + virtual void startModuleGroupExport() = 0; + /*! \brief + * Called to export the help for each module group. + * + * \param[in] title Title for the group. + * \param[in] modules List of modules in the group. + */ + virtual void exportModuleGroup(const char* title, const ModuleGroupContents& modules) = 0; + /*! \brief + * Called after all module groups have been exported. + * + * Can close files opened in startModuleGroupExport(), write footers to them + * etc. + */ + virtual void finishModuleGroupExport() = 0; + + /*! \brief + * Called to export the help for a top-level topic. + * + * \param[in] topic Topic to export. + */ + virtual void exportTopic(const IHelpTopic& topic) = 0; }; /******************************************************************** @@ -248,14 +241,14 @@ class IHelpExport struct RootHelpText { static const char title[]; - static const char *const text[]; + static const char* const text[]; }; // These are used for the gmx.1 man page. // TODO: Do not hardcode them here, but pass them from the outside to make this // code more generic. const char RootHelpText::title[] = "molecular dynamics simulation suite"; -const char *const RootHelpText::text[] = { +const char* const RootHelpText::text[] = { "|Gromacs| is a full-featured suite of programs to perform molecular", "dynamics simulations, i.e., to simulate the behavior of systems with", "hundreds to millions of particles using Newtonian equations of motion.", @@ -264,19 +257,17 @@ const char *const RootHelpText::text[] = { "questions.", }; -const char *RootHelpTopic::name() const +const char* RootHelpTopic::name() const { return helpModule_.binaryName_.c_str(); } -void RootHelpTopic::exportHelp(IHelpExport *exporter) +void RootHelpTopic::exportHelp(IHelpExport* exporter) { std::vector::const_iterator topicName; - for (topicName = exportedTopics_.begin(); - topicName != exportedTopics_.end(); - ++topicName) + for (topicName = exportedTopics_.begin(); topicName != exportedTopics_.end(); ++topicName) { - const IHelpTopic *topic = findSubTopic(topicName->c_str()); + const IHelpTopic* topic = findSubTopic(topicName->c_str()); GMX_RELEASE_ASSERT(topic != nullptr, "Exported help topic no longer found"); exporter->exportTopic(*topic); } @@ -287,31 +278,28 @@ void RootHelpTopic::exportHelp(IHelpExport *exporter) exporter->exportTopic(*this); } -void RootHelpTopic::writeHelp(const HelpWriterContext &context) const +void RootHelpTopic::writeHelp(const HelpWriterContext& context) const { { - CommandLineCommonOptionsHolder optionsHolder; - CommandLineHelpContext cmdlineContext(createContext(context)); + CommandLineCommonOptionsHolder optionsHolder; + CommandLineHelpContext cmdlineContext(createContext(context)); cmdlineContext.setModuleDisplayName(helpModule_.binaryName_); optionsHolder.initOptions(); - Options &options = *optionsHolder.options(); - ArrayRef helpText; + Options& options = *optionsHolder.options(); + ArrayRef helpText; if (context.outputFormat() != eHelpOutputFormat_Console) { helpText = RootHelpText::text; } // TODO: Add [] into the synopsis. - CommandLineHelpWriter(options) - .setHelpText(helpText) - .writeHelp(cmdlineContext); + CommandLineHelpWriter(options).setHelpText(helpText).writeHelp(cmdlineContext); } if (context.outputFormat() == eHelpOutputFormat_Console) { // TODO: Consider printing a list of "core" commands. Would require someone // to determine such a set... context.paragraphBreak(); - writeSubTopicList(context, - "Additional help is available on the following topics:"); + writeSubTopicList(context, "Additional help is available on the following topics:"); context.writeTextBlock("To access the help, use '[PROGRAM] help '."); context.writeTextBlock("For help on a command, use '[PROGRAM] help '."); } @@ -328,8 +316,7 @@ void RootHelpTopic::writeHelp(const HelpWriterContext &context) const } } -CommandLineHelpContext -RootHelpTopic::createContext(const HelpWriterContext &context) const +CommandLineHelpContext RootHelpTopic::createContext(const HelpWriterContext& context) const { if (helpModule_.context_ != nullptr) { @@ -352,50 +339,45 @@ RootHelpTopic::createContext(const HelpWriterContext &context) const */ class CommandsHelpTopic : public IHelpTopic { - public: - /*! \brief - * Creates a command list help topic. - * - * \param[in] helpModule Help module to get module information from. - * - * Does not throw. - */ - explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule) - : helpModule_(helpModule) - { - } +public: + /*! \brief + * Creates a command list help topic. + * + * \param[in] helpModule Help module to get module information from. + * + * Does not throw. + */ + explicit CommandsHelpTopic(const CommandLineHelpModuleImpl& helpModule) : + helpModule_(helpModule) + { + } - const char *name() const override { return "commands"; } - const char *title() const override { return "List of available commands"; } - bool hasSubTopics() const override { return false; } - const IHelpTopic *findSubTopic(const char * /*name*/) const override - { - return nullptr; - } + const char* name() const override { return "commands"; } + const char* title() const override { return "List of available commands"; } + bool hasSubTopics() const override { return false; } + const IHelpTopic* findSubTopic(const char* /*name*/) const override { return nullptr; } - void writeHelp(const HelpWriterContext &context) const override; + void writeHelp(const HelpWriterContext& context) const override; - private: - const CommandLineHelpModuleImpl &helpModule_; +private: + const CommandLineHelpModuleImpl& helpModule_; - GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic); + GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic); }; -void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const +void CommandsHelpTopic::writeHelp(const HelpWriterContext& context) const { if (context.outputFormat() != eHelpOutputFormat_Console) { - GMX_THROW(NotImplementedError( - "Module list is not implemented for this output format")); + GMX_THROW(NotImplementedError("Module list is not implemented for this output format")); } - int maxNameLength = 0; - const CommandLineModuleMap &modules = helpModule_.modules_; - CommandLineModuleMap::const_iterator module; + int maxNameLength = 0; + const CommandLineModuleMap& modules = helpModule_.modules_; + CommandLineModuleMap::const_iterator module; for (module = modules.begin(); module != modules.end(); ++module) { int nameLength = static_cast(module->first.length()); - if (module->second->shortDescription() != nullptr - && nameLength > maxNameLength) + if (module->second->shortDescription() != nullptr && nameLength > maxNameLength) { maxNameLength = nameLength; } @@ -403,15 +385,15 @@ void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const context.writeTextBlock( "Usage: [PROGRAM] [] [][PAR]" "Available commands:"); - TextWriter &file = context.outputFile(); + TextWriter& file = context.outputFile(); TextTableFormatter formatter; formatter.addColumn(nullptr, maxNameLength + 1, false); formatter.addColumn(nullptr, 72 - maxNameLength, true); formatter.setFirstColumnIndent(4); for (module = modules.begin(); module != modules.end(); ++module) { - const char *name = module->first.c_str(); - const char *description = module->second->shortDescription(); + const char* name = module->first.c_str(); + const char* description = module->second->shortDescription(); if (description != nullptr) { formatter.clear(); @@ -420,8 +402,7 @@ void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const file.writeString(formatter.formatRow()); } } - context.writeTextBlock( - "For help on a command, use '[PROGRAM] help '."); + context.writeTextBlock("For help on a command, use '[PROGRAM] help '."); } /******************************************************************** @@ -439,34 +420,31 @@ void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const */ class ModuleHelpTopic : public IHelpTopic { - public: - //! Constructs a help topic for a specific module. - ModuleHelpTopic(const ICommandLineModule &module, - const CommandLineHelpModuleImpl &helpModule) - : module_(module), helpModule_(helpModule) - { - } +public: + //! Constructs a help topic for a specific module. + ModuleHelpTopic(const ICommandLineModule& module, const CommandLineHelpModuleImpl& helpModule) : + module_(module), + helpModule_(helpModule) + { + } - const char *name() const override { return module_.name(); } - const char *title() const override { return nullptr; } - bool hasSubTopics() const override { return false; } - const IHelpTopic *findSubTopic(const char * /*name*/) const override - { - return nullptr; - } - void writeHelp(const HelpWriterContext &context) const override; + const char* name() const override { return module_.name(); } + const char* title() const override { return nullptr; } + bool hasSubTopics() const override { return false; } + const IHelpTopic* findSubTopic(const char* /*name*/) const override { return nullptr; } + void writeHelp(const HelpWriterContext& context) const override; - private: - const ICommandLineModule &module_; - const CommandLineHelpModuleImpl &helpModule_; +private: + const ICommandLineModule& module_; + const CommandLineHelpModuleImpl& helpModule_; - GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic); + GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic); }; -void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const +void ModuleHelpTopic::writeHelp(const HelpWriterContext& /*context*/) const { CommandLineHelpContext context(*helpModule_.context_); - const char *const program = helpModule_.binaryName_.c_str(); + const char* const program = helpModule_.binaryName_.c_str(); context.setModuleDisplayName(formatString("%s %s", program, module_.name())); module_.writeHelp(context); } @@ -487,22 +465,18 @@ void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const * * \ingroup module_commandline */ -void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule) +void initProgramLinks(HelpLinks* links, const CommandLineHelpModuleImpl& helpModule) { - const char *const program = helpModule.binaryName_.c_str(); + const char* const program = helpModule.binaryName_.c_str(); CommandLineModuleMap::const_iterator module; - for (module = helpModule.modules_.begin(); - module != helpModule.modules_.end(); - ++module) + for (module = helpModule.modules_.begin(); module != helpModule.modules_.end(); ++module) { if (module->second->shortDescription() != nullptr) { std::string linkName("[gmx-" + module->first + "]"); - const char *name = module->first.c_str(); - std::string reference( - formatString(":doc:`%s %s <%s-%s>`", program, name, program, name)); - std::string displayName( - formatString("[TT]%s %s[tt]", program, name)); + const char* name = module->first.c_str(); + std::string reference(formatString(":doc:`%s %s <%s-%s>`", program, name, program, name)); + std::string displayName(formatString("[TT]%s %s[tt]", program, name)); links->addLink(linkName, reference, displayName); } } @@ -515,50 +489,45 @@ void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpMod */ class HelpExportReStructuredText : public IHelpExport { - public: - //! Initializes reST exporter. - HelpExportReStructuredText( - const CommandLineHelpModuleImpl &helpModule, - IFileOutputRedirector *outputRedirector); - - void startModuleExport() override; - void exportModuleHelp( - const ICommandLineModule &module, - const std::string &tag, - const std::string &displayName) override; - void finishModuleExport() override; - - void startModuleGroupExport() override; - void exportModuleGroup(const char *title, - const ModuleGroupContents &modules) override; - void finishModuleGroupExport() override; - - void exportTopic(const IHelpTopic &topic) override; - - private: - IFileOutputRedirector *outputRedirector_; - const std::string &binaryName_; //NOLINT(google-runtime-member-string-references) - HelpLinks links_; - // These never release ownership. - std::unique_ptr indexFile_; - std::unique_ptr manPagesFile_; +public: + //! Initializes reST exporter. + HelpExportReStructuredText(const CommandLineHelpModuleImpl& helpModule, + IFileOutputRedirector* outputRedirector); + + void startModuleExport() override; + void exportModuleHelp(const ICommandLineModule& module, + const std::string& tag, + const std::string& displayName) override; + void finishModuleExport() override; + + void startModuleGroupExport() override; + void exportModuleGroup(const char* title, const ModuleGroupContents& modules) override; + void finishModuleGroupExport() override; + + void exportTopic(const IHelpTopic& topic) override; + +private: + IFileOutputRedirector* outputRedirector_; + const std::string& binaryName_; //NOLINT(google-runtime-member-string-references) + HelpLinks links_; + // These never release ownership. + std::unique_ptr indexFile_; + std::unique_ptr manPagesFile_; }; -HelpExportReStructuredText::HelpExportReStructuredText( - const CommandLineHelpModuleImpl &helpModule, - IFileOutputRedirector *outputRedirector) - : outputRedirector_(outputRedirector), - binaryName_(helpModule.binaryName_), - links_(eHelpOutputFormat_Rst) +HelpExportReStructuredText::HelpExportReStructuredText(const CommandLineHelpModuleImpl& helpModule, + IFileOutputRedirector* outputRedirector) : + outputRedirector_(outputRedirector), + binaryName_(helpModule.binaryName_), + links_(eHelpOutputFormat_Rst) { - TextReader linksFile("links.dat"); - std::string line; + TextReader linksFile("links.dat"); + std::string line; linksFile.setTrimTrailingWhiteSpace(true); while (linksFile.readLine(&line)) { links_.addLink("[REF]." + line + "[ref]", - formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()), - line); + formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()), line); links_.addLink("[REF]" + line + "[ref]", formatString(":ref:`%s`", line.c_str()), line); } linksFile.close(); @@ -568,23 +537,21 @@ HelpExportReStructuredText::HelpExportReStructuredText( void HelpExportReStructuredText::startModuleExport() { indexFile_ = std::make_unique( - outputRedirector_->openTextOutputFile("fragments/byname.rst")); - indexFile_->writeLine(formatString("* :doc:`%s ` - %s", - binaryName_.c_str(), binaryName_.c_str(), - RootHelpText::title)); - manPagesFile_ = std::make_unique( - outputRedirector_->openTextOutputFile("conf-man.py")); + outputRedirector_->openTextOutputFile("fragments/byname.rst")); + indexFile_->writeLine(formatString("* :doc:`%s ` - %s", binaryName_.c_str(), + binaryName_.c_str(), RootHelpText::title)); + manPagesFile_ = + std::make_unique(outputRedirector_->openTextOutputFile("conf-man.py")); manPagesFile_->writeLine("man_pages = ["); } -void HelpExportReStructuredText::exportModuleHelp( - const ICommandLineModule &module, - const std::string &tag, - const std::string &displayName) +void HelpExportReStructuredText::exportModuleHelp(const ICommandLineModule& module, + const std::string& tag, + const std::string& displayName) { - TextOutputStreamPointer file - = outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst"); - TextWriter writer(file); + TextOutputStreamPointer file = + outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst"); + TextWriter writer(file); writer.writeLine(formatString(".. _%s:", displayName.c_str())); if (displayName == binaryName_ + " mdrun") { @@ -607,15 +574,14 @@ void HelpExportReStructuredText::exportModuleHelp( writer.writeLine(); writer.writeLine(formatString(" :manpage:`%s(1)`", binaryName_.c_str())); writer.writeLine(); - writer.writeLine(" More information about |Gromacs| is available at ."); + writer.writeLine( + " More information about |Gromacs| is available at ."); file->close(); - indexFile_->writeLine(formatString("* :doc:`%s ` - %s", - displayName.c_str(), tag.c_str(), - module.shortDescription())); - manPagesFile_->writeLine( - formatString(" ('onlinehelp/%s', '%s', \"%s\", '', 1),", - tag.c_str(), tag.c_str(), module.shortDescription())); + indexFile_->writeLine(formatString("* :doc:`%s ` - %s", displayName.c_str(), + tag.c_str(), module.shortDescription())); + manPagesFile_->writeLine(formatString(" ('onlinehelp/%s', '%s', \"%s\", '', 1),", + tag.c_str(), tag.c_str(), module.shortDescription())); } void HelpExportReStructuredText::finishModuleExport() @@ -623,10 +589,8 @@ void HelpExportReStructuredText::finishModuleExport() indexFile_->close(); indexFile_.reset(); // TODO: Generalize. - manPagesFile_->writeLine( - formatString(" ('onlinehelp/%s', '%s', '%s', '', 1)", - binaryName_.c_str(), binaryName_.c_str(), - RootHelpText::title)); + manPagesFile_->writeLine(formatString(" ('onlinehelp/%s', '%s', '%s', '', 1)", + binaryName_.c_str(), binaryName_.c_str(), RootHelpText::title)); manPagesFile_->writeLine("]"); manPagesFile_->close(); manPagesFile_.reset(); @@ -635,14 +599,12 @@ void HelpExportReStructuredText::finishModuleExport() void HelpExportReStructuredText::startModuleGroupExport() { indexFile_ = std::make_unique( - outputRedirector_->openTextOutputFile("fragments/bytopic.rst")); + outputRedirector_->openTextOutputFile("fragments/bytopic.rst")); manPagesFile_ = std::make_unique( - outputRedirector_->openTextOutputFile("fragments/bytopic-man.rst")); + outputRedirector_->openTextOutputFile("fragments/bytopic-man.rst")); } -void HelpExportReStructuredText::exportModuleGroup( - const char *title, - const ModuleGroupContents &modules) +void HelpExportReStructuredText::exportModuleGroup(const char* title, const ModuleGroupContents& modules) { indexFile_->ensureEmptyLine(); indexFile_->writeLine(title); @@ -654,20 +616,17 @@ void HelpExportReStructuredText::exportModuleGroup( ModuleGroupContents::const_iterator module; for (module = modules.begin(); module != modules.end(); ++module) { - const std::string &tag(module->first); - std::string displayName(tag); + const std::string& tag(module->first); + std::string displayName(tag); // TODO: This does not work if the binary name would contain a dash, // but that is not currently the case. - const size_t dashPos = displayName.find('-'); + const size_t dashPos = displayName.find('-'); GMX_RELEASE_ASSERT(dashPos != std::string::npos, "There should always be at least one dash in the tag"); displayName[dashPos] = ' '; - indexFile_->writeLine(formatString(":doc:`%s `\n %s", - displayName.c_str(), tag.c_str(), - module->second)); - manPagesFile_->writeLine(formatString(":manpage:`%s(1)`\n %s", - tag.c_str(), - module->second)); + indexFile_->writeLine(formatString(":doc:`%s `\n %s", displayName.c_str(), + tag.c_str(), module->second)); + manPagesFile_->writeLine(formatString(":manpage:`%s(1)`\n %s", tag.c_str(), module->second)); } } @@ -679,13 +638,12 @@ void HelpExportReStructuredText::finishModuleGroupExport() manPagesFile_.reset(); } -void HelpExportReStructuredText::exportTopic(const IHelpTopic &topic) +void HelpExportReStructuredText::exportTopic(const IHelpTopic& topic) { - const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst"); - TextWriter writer(outputRedirector_->openTextOutputFile(path)); - CommandLineHelpContext context(&writer, eHelpOutputFormat_Rst, &links_, - binaryName_); - HelpManager manager(topic, context.writerContext()); + const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst"); + TextWriter writer(outputRedirector_->openTextOutputFile(path)); + CommandLineHelpContext context(&writer, eHelpOutputFormat_Rst, &links_, binaryName_); + HelpManager manager(topic, context.writerContext()); manager.writeCurrentTopic(); writer.close(); } @@ -701,32 +659,31 @@ void HelpExportReStructuredText::exportTopic(const IHelpTopic &topic) */ class HelpExportCompletion : public IHelpExport { - public: - //! Initializes completion exporter. - explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule); +public: + //! Initializes completion exporter. + explicit HelpExportCompletion(const CommandLineHelpModuleImpl& helpModule); - void startModuleExport() override; - void exportModuleHelp( - const ICommandLineModule &module, - const std::string &tag, - const std::string &displayName) override; - void finishModuleExport() override; + void startModuleExport() override; + void exportModuleHelp(const ICommandLineModule& module, + const std::string& tag, + const std::string& displayName) override; + void finishModuleExport() override; - void startModuleGroupExport() override {} - void exportModuleGroup(const char * /*title*/, - const ModuleGroupContents & /*modules*/) override {} - void finishModuleGroupExport() override {} + void startModuleGroupExport() override {} + void exportModuleGroup(const char* /*title*/, const ModuleGroupContents& /*modules*/) override + { + } + void finishModuleGroupExport() override {} - void exportTopic(const IHelpTopic & /*topic*/) override {} + void exportTopic(const IHelpTopic& /*topic*/) override {} - private: - ShellCompletionWriter bashWriter_; - std::vector modules_; +private: + ShellCompletionWriter bashWriter_; + std::vector modules_; }; -HelpExportCompletion::HelpExportCompletion( - const CommandLineHelpModuleImpl &helpModule) - : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash) +HelpExportCompletion::HelpExportCompletion(const CommandLineHelpModuleImpl& helpModule) : + bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash) { } @@ -735,10 +692,9 @@ void HelpExportCompletion::startModuleExport() bashWriter_.startCompletions(); } -void HelpExportCompletion::exportModuleHelp( - const ICommandLineModule &module, - const std::string & /*tag*/, - const std::string & /*displayName*/) +void HelpExportCompletion::exportModuleHelp(const ICommandLineModule& module, + const std::string& /*tag*/, + const std::string& /*displayName*/) { modules_.emplace_back(module.name()); { @@ -758,46 +714,47 @@ void HelpExportCompletion::finishModuleExport() bashWriter_.finishCompletions(); } -} // namespace +} // namespace /******************************************************************** * CommandLineHelpModuleImpl implementation */ -CommandLineHelpModuleImpl::CommandLineHelpModuleImpl( - const IProgramContext &programContext, - const std::string &binaryName, - const CommandLineModuleMap &modules, - const CommandLineModuleGroupList &groups) - : rootTopic_(*this), programContext_(programContext), - binaryName_(binaryName), modules_(modules), groups_(groups), - context_(nullptr), moduleOverride_(nullptr), bHidden_(false), - outputRedirector_(&defaultFileOutputRedirector()) +CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(const IProgramContext& programContext, + const std::string& binaryName, + const CommandLineModuleMap& modules, + const CommandLineModuleGroupList& groups) : + rootTopic_(*this), + programContext_(programContext), + binaryName_(binaryName), + modules_(modules), + groups_(groups), + context_(nullptr), + moduleOverride_(nullptr), + bHidden_(false), + outputRedirector_(&defaultFileOutputRedirector()) { } -std::unique_ptr -CommandLineHelpModuleImpl::createExporter(const std::string &format, - IFileOutputRedirector *redirector) +std::unique_ptr CommandLineHelpModuleImpl::createExporter(const std::string& format, + IFileOutputRedirector* redirector) { if (format == "rst") { - return std::unique_ptr( - new HelpExportReStructuredText(*this, redirector)); + return std::unique_ptr(new HelpExportReStructuredText(*this, redirector)); } else if (format == "completion") { - return std::unique_ptr( - new HelpExportCompletion(*this)); + return std::unique_ptr(new HelpExportCompletion(*this)); } GMX_THROW(NotImplementedError("This help format is not implemented")); } -void CommandLineHelpModuleImpl::exportHelp(IHelpExport *exporter) +void CommandLineHelpModuleImpl::exportHelp(IHelpExport* exporter) { // TODO: Would be nicer to have the file names supplied by the build system // and/or export a list of files from here. - const char *const program = binaryName_.c_str(); + const char* const program = binaryName_.c_str(); exporter->startModuleExport(); CommandLineModuleMap::const_iterator module; @@ -805,7 +762,7 @@ void CommandLineHelpModuleImpl::exportHelp(IHelpExport *exporter) { if (module->second->shortDescription() != nullptr) { - const char *const moduleName = module->first.c_str(); + const char* const moduleName = module->first.c_str(); std::string tag(formatString("%s-%s", program, moduleName)); std::string displayName(formatString("%s %s", program, moduleName)); exporter->exportModuleHelp(*module->second, tag, displayName); @@ -833,36 +790,34 @@ namespace class ModificationCheckingFileOutputStream : public TextOutputStream { - public: - ModificationCheckingFileOutputStream( - const char *path, - IFileOutputRedirector *redirector) - : path_(path), redirector_(redirector) - { - } +public: + ModificationCheckingFileOutputStream(const char* path, IFileOutputRedirector* redirector) : + path_(path), + redirector_(redirector) + { + } - void write(const char *str) override { contents_.write(str); } - void close() override + void write(const char* str) override { contents_.write(str); } + void close() override + { + const std::string& newContents = contents_.toString(); + // TODO: Redirect these for unit tests. + if (File::exists(path_, File::returnFalseOnError)) { - const std::string &newContents = contents_.toString(); - // TODO: Redirect these for unit tests. - if (File::exists(path_, File::returnFalseOnError)) + const std::string originalContents_ = TextReader::readFileToString(path_); + if (originalContents_ == newContents) { - const std::string originalContents_ - = TextReader::readFileToString(path_); - if (originalContents_ == newContents) - { - return; - } + return; } - TextWriter writer(redirector_->openTextOutputFile(path_)); - writer.writeString(newContents); } + TextWriter writer(redirector_->openTextOutputFile(path_)); + writer.writeString(newContents); + } - private: - std::string path_; - StringOutputStream contents_; - IFileOutputRedirector *redirector_; +private: + std::string path_; + StringOutputStream contents_; + IFileOutputRedirector* redirector_; }; /******************************************************************** @@ -871,48 +826,39 @@ class ModificationCheckingFileOutputStream : public TextOutputStream class ModificationCheckingFileOutputRedirector : public IFileOutputRedirector { - public: - explicit ModificationCheckingFileOutputRedirector( - IFileOutputRedirector *redirector) - : redirector_(redirector) - { - } +public: + explicit ModificationCheckingFileOutputRedirector(IFileOutputRedirector* redirector) : + redirector_(redirector) + { + } - TextOutputStream &standardOutput() override - { - return redirector_->standardOutput(); - } - TextOutputStreamPointer openTextOutputFile(const char *filename) override - { - return TextOutputStreamPointer( - new ModificationCheckingFileOutputStream(filename, redirector_)); - } + TextOutputStream& standardOutput() override { return redirector_->standardOutput(); } + TextOutputStreamPointer openTextOutputFile(const char* filename) override + { + return TextOutputStreamPointer(new ModificationCheckingFileOutputStream(filename, redirector_)); + } - private: - IFileOutputRedirector *redirector_; +private: + IFileOutputRedirector* redirector_; }; -} // namespace +} // namespace /******************************************************************** * CommandLineHelpModule */ -CommandLineHelpModule::CommandLineHelpModule( - const IProgramContext &programContext, - const std::string &binaryName, - const CommandLineModuleMap &modules, - const CommandLineModuleGroupList &groups) - : impl_(new Impl(programContext, binaryName, modules, groups)) +CommandLineHelpModule::CommandLineHelpModule(const IProgramContext& programContext, + const std::string& binaryName, + const CommandLineModuleMap& modules, + const CommandLineModuleGroupList& groups) : + impl_(new Impl(programContext, binaryName, modules, groups)) { } -CommandLineHelpModule::~CommandLineHelpModule() -{ -} +CommandLineHelpModule::~CommandLineHelpModule() {} -HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic( - const ICommandLineModule &module) const +HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(const ICommandLineModule& module) const { return HelpTopicPointer(new ModuleHelpTopic(module, *impl_)); } @@ -927,44 +873,39 @@ void CommandLineHelpModule::setShowHidden(bool bHidden) impl_->bHidden_ = bHidden; } -void CommandLineHelpModule::setModuleOverride( - const ICommandLineModule &module) +void CommandLineHelpModule::setModuleOverride(const ICommandLineModule& module) { impl_->moduleOverride_ = &module; } -void CommandLineHelpModule::setOutputRedirector( - IFileOutputRedirector *output) +void CommandLineHelpModule::setOutputRedirector(IFileOutputRedirector* output) { impl_->outputRedirector_ = output; } -int CommandLineHelpModule::run(int argc, char *argv[]) +int CommandLineHelpModule::run(int argc, char* argv[]) { // Add internal topics lazily here. addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)), false); - const char *const exportFormats[] = { "rst", "completion" }; + const char* const exportFormats[] = { "rst", "completion" }; std::string exportFormat; Options options; - options.addOption(StringOption("export").store(&exportFormat) - .enumValue(exportFormats)); + options.addOption(StringOption("export").store(&exportFormat).enumValue(exportFormats)); CommandLineParser(&options).allowPositionalArguments(true).parse(&argc, argv); if (!exportFormat.empty()) { ModificationCheckingFileOutputRedirector redirector(impl_->outputRedirector_); - const std::unique_ptr exporter( - impl_->createExporter(exportFormat, &redirector)); + const std::unique_ptr exporter(impl_->createExporter(exportFormat, &redirector)); impl_->exportHelp(exporter.get()); return 0; } - TextOutputStream &outputFile = impl_->outputRedirector_->standardOutput(); - TextWriter writer(&outputFile); - HelpLinks links(eHelpOutputFormat_Console); + TextOutputStream& outputFile = impl_->outputRedirector_->standardOutput(); + TextWriter writer(&outputFile); + HelpLinks links(eHelpOutputFormat_Console); initProgramLinks(&links, *impl_); - CommandLineHelpContext context(&writer, eHelpOutputFormat_Console, &links, - impl_->binaryName_); + CommandLineHelpContext context(&writer, eHelpOutputFormat_Console, &links, impl_->binaryName_); context.setShowHidden(impl_->bHidden_); if (impl_->moduleOverride_ != nullptr) { @@ -982,7 +923,7 @@ int CommandLineHelpModule::run(int argc, char *argv[]) helpManager.enterTopic(argv[i]); } } - catch (const InvalidInputError &ex) + catch (const InvalidInputError& ex) { fprintf(stderr, "%s\n", ex.what()); return 2; @@ -991,16 +932,15 @@ int CommandLineHelpModule::run(int argc, char *argv[]) return 0; } -void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const +void CommandLineHelpModule::writeHelp(const CommandLineHelpContext& context) const { - const HelpWriterContext &writerContext = context.writerContext(); + const HelpWriterContext& writerContext = context.writerContext(); // TODO: Implement. if (writerContext.outputFormat() != eHelpOutputFormat_Console) { return; } - writerContext.writeTextBlock( - "Usage: [PROGRAM] help [| [ [...]]]"); + writerContext.writeTextBlock("Usage: [PROGRAM] help [| [ [...]]]"); // TODO: More information. } diff --git a/src/gromacs/commandline/cmdlinehelpmodule.h b/src/gromacs/commandline/cmdlinehelpmodule.h index 8ff0bdeb82..02b0717035 100644 --- a/src/gromacs/commandline/cmdlinehelpmodule.h +++ b/src/gromacs/commandline/cmdlinehelpmodule.h @@ -68,79 +68,72 @@ class CommandLineHelpModuleImpl; */ class CommandLineHelpModule : public ICommandLineModule { - public: - /*! \brief - * Creates a command-line help module. - * - * \param[in] programContext Information about the running binary. - * \param[in] binaryName Name of the running binary - * (without Gromacs binary suffix or .exe on Windows). - * \param[in] modules List of modules for to use for module listings. - * \param[in] groups List of module groups. - * \throws std::bad_alloc if out of memory. - */ - CommandLineHelpModule(const IProgramContext &programContext, - const std::string &binaryName, - const CommandLineModuleMap &modules, - const CommandLineModuleGroupList &groups); - ~CommandLineHelpModule() override; +public: + /*! \brief + * Creates a command-line help module. + * + * \param[in] programContext Information about the running binary. + * \param[in] binaryName Name of the running binary + * (without Gromacs binary suffix or .exe on Windows). + * \param[in] modules List of modules for to use for module listings. + * \param[in] groups List of module groups. + * \throws std::bad_alloc if out of memory. + */ + CommandLineHelpModule(const IProgramContext& programContext, + const std::string& binaryName, + const CommandLineModuleMap& modules, + const CommandLineModuleGroupList& groups); + ~CommandLineHelpModule() override; - /*! \brief - * Creates a help topic for a command-line module. - * - * \param[in] module Module the create the help topic for. - * \throws std::bad_alloc if out of memory. - * - * The caller should add the topic using addTopic() if that is desired. - * This method is provided separately to allow for strong exception - * safety in CommandLineModuleManager::addModule(). - */ - HelpTopicPointer - createModuleHelpTopic(const ICommandLineModule &module) const; - /*! \brief - * Adds a top-level help topic. - * - * \param[in] topic Help topic to add. - * \param[in] bExported Whether this topic will be directly exported to - * the user guide. - * \throws std::bad_alloc if out of memory. - */ - void addTopic(HelpTopicPointer topic, bool bExported); - //! Sets whether hidden options will be shown in help. - void setShowHidden(bool bHidden); - /*! \brief - * Sets an override to show the help for the given module. - * - * If called, the help module directly prints the help for the given - * module when called, skipping any other processing. - */ - void setModuleOverride(const ICommandLineModule &module); + /*! \brief + * Creates a help topic for a command-line module. + * + * \param[in] module Module the create the help topic for. + * \throws std::bad_alloc if out of memory. + * + * The caller should add the topic using addTopic() if that is desired. + * This method is provided separately to allow for strong exception + * safety in CommandLineModuleManager::addModule(). + */ + HelpTopicPointer createModuleHelpTopic(const ICommandLineModule& module) const; + /*! \brief + * Adds a top-level help topic. + * + * \param[in] topic Help topic to add. + * \param[in] bExported Whether this topic will be directly exported to + * the user guide. + * \throws std::bad_alloc if out of memory. + */ + void addTopic(HelpTopicPointer topic, bool bExported); + //! Sets whether hidden options will be shown in help. + void setShowHidden(bool bHidden); + /*! \brief + * Sets an override to show the help for the given module. + * + * If called, the help module directly prints the help for the given + * module when called, skipping any other processing. + */ + void setModuleOverride(const ICommandLineModule& module); - /*! \brief - * Sets a file redirector for writing help output. - * - * Used for unit testing; see - * CommandLineModuleManager::setOutputRedirector() for more details. - */ - void setOutputRedirector(IFileOutputRedirector *output); + /*! \brief + * Sets a file redirector for writing help output. + * + * Used for unit testing; see + * CommandLineModuleManager::setOutputRedirector() for more details. + */ + void setOutputRedirector(IFileOutputRedirector* output); - const char *name() const override { return "help"; } - const char *shortDescription() const override - { - return "Print help information"; - } + const char* name() const override { return "help"; } + const char* shortDescription() const override { return "Print help information"; } - void init(CommandLineModuleSettings *settings) override - { - settings->setDefaultNiceLevel(0); - } - int run(int argc, char *argv[]) override; - void writeHelp(const CommandLineHelpContext &context) const override; + void init(CommandLineModuleSettings* settings) override { settings->setDefaultNiceLevel(0); } + int run(int argc, char* argv[]) override; + void writeHelp(const CommandLineHelpContext& context) const override; - private: - typedef CommandLineHelpModuleImpl Impl; +private: + typedef CommandLineHelpModuleImpl Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/commandline/cmdlinehelpwriter.cpp b/src/gromacs/commandline/cmdlinehelpwriter.cpp index 5963ed5085..df9bc173f4 100644 --- a/src/gromacs/commandline/cmdlinehelpwriter.cpp +++ b/src/gromacs/commandline/cmdlinehelpwriter.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -82,11 +83,11 @@ namespace */ class IOptionsFormatter { - public: - virtual ~IOptionsFormatter() {} +public: + virtual ~IOptionsFormatter() {} - //! Formats a single option option. - virtual void formatOption(const OptionInfo &option) = 0; + //! Formats a single option option. + virtual void formatOption(const OptionInfo& option) = 0; }; /******************************************************************** @@ -104,72 +105,61 @@ class IOptionsFormatter */ class OptionsFilter : public OptionsVisitor { - public: - //! Specifies the type of output that formatSelected() produces. - enum FilterType - { - eSelectInputFileOptions, - eSelectInputOutputFileOptions, - eSelectOutputFileOptions, - eSelectOtherOptions - }; - - /*! \brief - * Creates a new filtering object. - * - * Does not throw. - */ - OptionsFilter() - : formatter_(nullptr), filterType_(eSelectOtherOptions), - bShowHidden_(false) - { - } - - //! Sets whether hidden options will be shown. - void setShowHidden(bool bShowHidden) - { - bShowHidden_ = bShowHidden; - } - - //! Formats selected options using the formatter. - void formatSelected(FilterType type, - IOptionsFormatter *formatter, - const Options &options); - - void visitSection(const OptionSectionInfo §ion) override; - void visitOption(const OptionInfo &option) override; - - private: - IOptionsFormatter *formatter_; - FilterType filterType_; - bool bShowHidden_; - - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsFilter); +public: + //! Specifies the type of output that formatSelected() produces. + enum FilterType + { + eSelectInputFileOptions, + eSelectInputOutputFileOptions, + eSelectOutputFileOptions, + eSelectOtherOptions + }; + + /*! \brief + * Creates a new filtering object. + * + * Does not throw. + */ + OptionsFilter() : formatter_(nullptr), filterType_(eSelectOtherOptions), bShowHidden_(false) {} + + //! Sets whether hidden options will be shown. + void setShowHidden(bool bShowHidden) { bShowHidden_ = bShowHidden; } + + //! Formats selected options using the formatter. + void formatSelected(FilterType type, IOptionsFormatter* formatter, const Options& options); + + void visitSection(const OptionSectionInfo& section) override; + void visitOption(const OptionInfo& option) override; + +private: + IOptionsFormatter* formatter_; + FilterType filterType_; + bool bShowHidden_; + + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsFilter); }; -void OptionsFilter::formatSelected(FilterType type, - IOptionsFormatter *formatter, - const Options &options) +void OptionsFilter::formatSelected(FilterType type, IOptionsFormatter* formatter, const Options& options) { formatter_ = formatter; filterType_ = type; visitSection(options.rootSection()); } -void OptionsFilter::visitSection(const OptionSectionInfo §ion) +void OptionsFilter::visitSection(const OptionSectionInfo& section) { OptionsIterator iterator(section); iterator.acceptSections(this); iterator.acceptOptions(this); } -void OptionsFilter::visitOption(const OptionInfo &option) +void OptionsFilter::visitOption(const OptionInfo& option) { if (!bShowHidden_ && option.isHidden()) { return; } - const FileNameOptionInfo *const fileOption = option.toType(); + const FileNameOptionInfo* const fileOption = option.toType(); if (fileOption != nullptr && fileOption->isInputFile()) { if (filterType_ == eSelectInputFileOptions) @@ -207,13 +197,10 @@ void OptionsFilter::visitOption(const OptionInfo &option) class CommonFormatterData { - public: - explicit CommonFormatterData(const char *timeUnit) - : timeUnit(timeUnit) - { - } +public: + explicit CommonFormatterData(const char* timeUnit) : timeUnit(timeUnit) {} - const char *timeUnit; + const char* timeUnit; }; /******************************************************************** @@ -221,8 +208,7 @@ class CommonFormatterData */ //! Formats option name and value. -void formatOptionNameAndValue(const OptionInfo &option, std::string *name, - std::string *value) +void formatOptionNameAndValue(const OptionInfo& option, std::string* name, std::string* value) { *name = option.name(); *value = "<" + option.type() + ">"; @@ -248,14 +234,13 @@ void formatOptionNameAndValue(const OptionInfo &option, std::string *name, } //! Formats the default option value as a string. -std::string defaultOptionValue(const OptionInfo &option) +std::string defaultOptionValue(const OptionInfo& option) { return joinStrings(option.defaultValuesAsStrings(), " "); } //! Formats the flags for a file option as a string. -std::string -fileOptionFlagsAsString(const FileNameOptionInfo &option, bool bAbbrev) +std::string fileOptionFlagsAsString(const FileNameOptionInfo& option, bool bAbbrev) { std::string type; if (!option.isRequired()) @@ -274,14 +259,12 @@ fileOptionFlagsAsString(const FileNameOptionInfo &option, bool bAbbrev) } //! Formats the description for an option as a string. -std::string -descriptionWithOptionDetails(const CommonFormatterData &common, - const OptionInfo &option) +std::string descriptionWithOptionDetails(const CommonFormatterData& common, const OptionInfo& option) { - std::string description(option.formatDescription()); + std::string description(option.formatDescription()); - const FloatOptionInfo *floatOption = option.toType(); - const DoubleOptionInfo *doubleOption = option.toType(); + const FloatOptionInfo* floatOption = option.toType(); + const DoubleOptionInfo* doubleOption = option.toType(); if ((floatOption != nullptr && floatOption->isTime()) || (doubleOption != nullptr && doubleOption->isTime())) { @@ -301,36 +284,39 @@ descriptionWithOptionDetails(const CommonFormatterData &common, */ class SynopsisFormatter : public IOptionsFormatter { - public: - //! Creates a helper object for formatting the synopsis. - explicit SynopsisFormatter(const HelpWriterContext &context) - : context_(context), bFormatted_(false), lineLength_(0), indent_(0), - currentLength_(0) - { - } +public: + //! Creates a helper object for formatting the synopsis. + explicit SynopsisFormatter(const HelpWriterContext& context) : + context_(context), + bFormatted_(false), + lineLength_(0), + indent_(0), + currentLength_(0) + { + } - //! Starts formatting the synopsis. - void start(const char *name); - //! Finishes formatting the synopsis. - void finish(); + //! Starts formatting the synopsis. + void start(const char* name); + //! Finishes formatting the synopsis. + void finish(); - void formatOption(const OptionInfo &option) override; + void formatOption(const OptionInfo& option) override; - private: - const HelpWriterContext &context_; - bool bFormatted_; - int lineLength_; - int indent_; - int currentLength_; +private: + const HelpWriterContext& context_; + bool bFormatted_; + int lineLength_; + int indent_; + int currentLength_; - GMX_DISALLOW_COPY_AND_ASSIGN(SynopsisFormatter); + GMX_DISALLOW_COPY_AND_ASSIGN(SynopsisFormatter); }; -void SynopsisFormatter::start(const char *name) +void SynopsisFormatter::start(const char* name) { - currentLength_ = std::strlen(name) + 1; - indent_ = std::min(currentLength_, 13); - TextWriter &file = context_.outputFile(); + currentLength_ = std::strlen(name) + 1; + indent_ = std::min(currentLength_, 13); + TextWriter& file = context_.outputFile(); switch (context_.outputFormat()) { case eHelpOutputFormat_Console: @@ -340,14 +326,15 @@ void SynopsisFormatter::start(const char *name) case eHelpOutputFormat_Rst: bFormatted_ = true; lineLength_ = 74; - indent_ += 4; + indent_ += 4; file.writeLine(".. parsed-literal::"); file.writeLine(); file.writeString(" "); file.writeString(name); break; default: - GMX_THROW(NotImplementedError("Synopsis formatting not implemented for this output format")); + GMX_THROW(NotImplementedError( + "Synopsis formatting not implemented for this output format")); } } @@ -356,13 +343,12 @@ void SynopsisFormatter::finish() context_.outputFile().ensureLineBreak(); } -void SynopsisFormatter::formatOption(const OptionInfo &option) +void SynopsisFormatter::formatOption(const OptionInfo& option) { std::string name, value; formatOptionNameAndValue(option, &name, &value); - int totalLength = name.length() + 4; - std::string fullOptionText - = formatString(" [%s-%s", bFormatted_ ? ":strong:`" : "", name.c_str()); + int totalLength = name.length() + 4; + std::string fullOptionText = formatString(" [%s-%s", bFormatted_ ? ":strong:`" : "", name.c_str()); if (!value.empty()) { fullOptionText.append(bFormatted_ ? "` :emphasis:`" : " "); @@ -371,7 +357,7 @@ void SynopsisFormatter::formatOption(const OptionInfo &option) } fullOptionText.append(bFormatted_ ? "`]" : "]"); - TextWriter &file = context_.outputFile(); + TextWriter& file = context_.outputFile(); currentLength_ += totalLength; if (currentLength_ >= lineLength_) { @@ -390,80 +376,80 @@ void SynopsisFormatter::formatOption(const OptionInfo &option) */ class OptionsListFormatter : public IOptionsFormatter { - public: - //! Creates a helper object for formatting options. - OptionsListFormatter(const HelpWriterContext &context, - const CommonFormatterData &common, - const char *title); - - //! Initiates a new section in the options list. - void startSection(const char *header) - { - header_ = header; - bDidOutput_ = false; - } - //! Finishes a section in the options list. - void finishSection() +public: + //! Creates a helper object for formatting options. + OptionsListFormatter(const HelpWriterContext& context, const CommonFormatterData& common, const char* title); + + //! Initiates a new section in the options list. + void startSection(const char* header) + { + header_ = header; + bDidOutput_ = false; + } + //! Finishes a section in the options list. + void finishSection() + { + if (bDidOutput_) { - if (bDidOutput_) - { - context_.writeOptionListEnd(); - } + context_.writeOptionListEnd(); } + } - void formatOption(const OptionInfo &option) override; + void formatOption(const OptionInfo& option) override; - private: - void writeSectionStartIfNecessary() +private: + void writeSectionStartIfNecessary() + { + if (title_ != nullptr) { - if (title_ != nullptr) - { - context_.writeTitle(title_); - title_ = nullptr; - } - if (!bDidOutput_) + context_.writeTitle(title_); + title_ = nullptr; + } + if (!bDidOutput_) + { + if (header_ != nullptr) { - if (header_ != nullptr) - { - context_.paragraphBreak(); - context_.writeTextBlock(header_); - context_.paragraphBreak(); - } - context_.writeOptionListStart(); + context_.paragraphBreak(); + context_.writeTextBlock(header_); + context_.paragraphBreak(); } - bDidOutput_ = true; + context_.writeOptionListStart(); } + bDidOutput_ = true; + } - const HelpWriterContext &context_; - const CommonFormatterData &common_; - const char *title_; - const char *header_; - bool bDidOutput_; + const HelpWriterContext& context_; + const CommonFormatterData& common_; + const char* title_; + const char* header_; + bool bDidOutput_; - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsListFormatter); + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsListFormatter); }; -OptionsListFormatter::OptionsListFormatter( - const HelpWriterContext &context, - const CommonFormatterData &common, - const char *title) - : context_(context), common_(common), - title_(title), header_(nullptr), bDidOutput_(false) +OptionsListFormatter::OptionsListFormatter(const HelpWriterContext& context, + const CommonFormatterData& common, + const char* title) : + context_(context), + common_(common), + title_(title), + header_(nullptr), + bDidOutput_(false) { } -void OptionsListFormatter::formatOption(const OptionInfo &option) +void OptionsListFormatter::formatOption(const OptionInfo& option) { writeSectionStartIfNecessary(); - std::string name, value; + std::string name, value; formatOptionNameAndValue(option, &name, &value); std::string defaultValue(defaultOptionValue(option)); std::string info; - const FileNameOptionInfo *fileOption = option.toType(); + const FileNameOptionInfo* fileOption = option.toType(); if (fileOption != nullptr) { const bool bAbbrev = (context_.outputFormat() == eHelpOutputFormat_Console); - info = fileOptionFlagsAsString(*fileOption, bAbbrev); + info = fileOptionFlagsAsString(*fileOption, bAbbrev); } std::string description(descriptionWithOptionDetails(common_, option)); context_.writeOptionItem("-" + name, value, defaultValue, info, description); @@ -471,7 +457,7 @@ void OptionsListFormatter::formatOption(const OptionInfo &option) //! \} -} // namespace +} // namespace /******************************************************************** * CommandLineHelpWriter::Impl @@ -484,34 +470,31 @@ void OptionsListFormatter::formatOption(const OptionInfo &option) */ class CommandLineHelpWriter::Impl { - public: - //! Sets the Options object to use for generating help. - explicit Impl(const Options &options) - : options_(options) - { - } - - //! Format the list of known issues. - void formatBugs(const HelpWriterContext &context); - - //! Options object to use for generating help. - const Options &options_; - //! Help text. - std::string helpText_; - //! List of bugs/knows issues. - std::vector bugs_; +public: + //! Sets the Options object to use for generating help. + explicit Impl(const Options& options) : options_(options) {} + + //! Format the list of known issues. + void formatBugs(const HelpWriterContext& context); + + //! Options object to use for generating help. + const Options& options_; + //! Help text. + std::string helpText_; + //! List of bugs/knows issues. + std::vector bugs_; }; -void CommandLineHelpWriter::Impl::formatBugs(const HelpWriterContext &context) +void CommandLineHelpWriter::Impl::formatBugs(const HelpWriterContext& context) { if (bugs_.empty()) { return; } context.writeTitle("Known Issues"); - for (const auto &i : bugs_) + for (const auto& i : bugs_) { - const char *const bug = i.c_str(); + const char* const bug = i.c_str(); context.writeTextBlock(formatString("* %s", bug)); } } @@ -521,52 +504,42 @@ void CommandLineHelpWriter::Impl::formatBugs(const HelpWriterContext &context) * CommandLineHelpWriter */ -CommandLineHelpWriter::CommandLineHelpWriter(const Options &options) - : impl_(new Impl(options)) -{ -} +CommandLineHelpWriter::CommandLineHelpWriter(const Options& options) : impl_(new Impl(options)) {} -CommandLineHelpWriter::~CommandLineHelpWriter() -{ -} +CommandLineHelpWriter::~CommandLineHelpWriter() {} -CommandLineHelpWriter & -CommandLineHelpWriter::setHelpText(const std::string &help) +CommandLineHelpWriter& CommandLineHelpWriter::setHelpText(const std::string& help) { impl_->helpText_ = help; return *this; } -CommandLineHelpWriter & -CommandLineHelpWriter::setHelpText(const ArrayRef &help) +CommandLineHelpWriter& CommandLineHelpWriter::setHelpText(const ArrayRef& help) { impl_->helpText_ = joinStrings(help, "\n"); return *this; } -CommandLineHelpWriter & -CommandLineHelpWriter::setKnownIssues(ArrayRef bugs) +CommandLineHelpWriter& CommandLineHelpWriter::setKnownIssues(ArrayRef bugs) { impl_->bugs_ = std::vector(bugs.begin(), bugs.end()); return *this; } -CommandLineHelpWriter & -CommandLineHelpWriter::setKnownIssues(const ArrayRef &bugs) +CommandLineHelpWriter& CommandLineHelpWriter::setKnownIssues(const ArrayRef& bugs) { impl_->bugs_ = std::vector(bugs.begin(), bugs.end()); return *this; } -void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext &context) +void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext& context) { if (context.isCompletionExport()) { - context.shellCompletionWriter().writeModuleCompletions( - context.moduleDisplayName(), impl_->options_); + context.shellCompletionWriter().writeModuleCompletions(context.moduleDisplayName(), impl_->options_); return; } - const HelpWriterContext &writerContext = context.writerContext(); + const HelpWriterContext& writerContext = context.writerContext(); OptionsFilter filter; filter.setShowHidden(context.showHidden()); @@ -574,14 +547,11 @@ void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext &context) writerContext.writeTitle("Synopsis"); SynopsisFormatter synopsisFormatter(writerContext); synopsisFormatter.start(context.moduleDisplayName()); - filter.formatSelected(OptionsFilter::eSelectInputFileOptions, - &synopsisFormatter, impl_->options_); - filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions, - &synopsisFormatter, impl_->options_); - filter.formatSelected(OptionsFilter::eSelectOutputFileOptions, - &synopsisFormatter, impl_->options_); - filter.formatSelected(OptionsFilter::eSelectOtherOptions, - &synopsisFormatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectInputFileOptions, &synopsisFormatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions, &synopsisFormatter, + impl_->options_); + filter.formatSelected(OptionsFilter::eSelectOutputFileOptions, &synopsisFormatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectOtherOptions, &synopsisFormatter, impl_->options_); synopsisFormatter.finish(); } @@ -590,23 +560,19 @@ void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext &context) writerContext.writeTitle("Description"); writerContext.writeTextBlock(impl_->helpText_); } - CommonFormatterData common(TimeUnitManager().timeUnitAsString()); - OptionsListFormatter formatter(writerContext, common, "Options"); + CommonFormatterData common(TimeUnitManager().timeUnitAsString()); + OptionsListFormatter formatter(writerContext, common, "Options"); formatter.startSection("Options to specify input files:"); - filter.formatSelected(OptionsFilter::eSelectInputFileOptions, - &formatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectInputFileOptions, &formatter, impl_->options_); formatter.finishSection(); formatter.startSection("Options to specify input/output files:"); - filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions, - &formatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions, &formatter, impl_->options_); formatter.finishSection(); formatter.startSection("Options to specify output files:"); - filter.formatSelected(OptionsFilter::eSelectOutputFileOptions, - &formatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectOutputFileOptions, &formatter, impl_->options_); formatter.finishSection(); formatter.startSection("Other options:"); - filter.formatSelected(OptionsFilter::eSelectOtherOptions, - &formatter, impl_->options_); + filter.formatSelected(OptionsFilter::eSelectOtherOptions, &formatter, impl_->options_); formatter.finishSection(); impl_->formatBugs(writerContext); diff --git a/src/gromacs/commandline/cmdlinehelpwriter.h b/src/gromacs/commandline/cmdlinehelpwriter.h index 29b16f0472..588b95f7a4 100644 --- a/src/gromacs/commandline/cmdlinehelpwriter.h +++ b/src/gromacs/commandline/cmdlinehelpwriter.h @@ -53,7 +53,8 @@ namespace gmx class CommandLineHelpContext; class Options; -template class ArrayRef; +template +class ArrayRef; /*! \brief * Writes help information for Options. @@ -63,64 +64,62 @@ template class ArrayRef; */ class CommandLineHelpWriter { - public: - /*! \brief - * Creates an object that writer ascii-formatted help for Options. - * - * \param[in] options Options for which help should be printed. - */ - explicit CommandLineHelpWriter(const Options &options); - ~CommandLineHelpWriter(); +public: + /*! \brief + * Creates an object that writer ascii-formatted help for Options. + * + * \param[in] options Options for which help should be printed. + */ + explicit CommandLineHelpWriter(const Options& options); + ~CommandLineHelpWriter(); - /*! \brief - * Sets the help text to print as description. - * - * \param[in] help Help text to show. - * \throws std::bad_alloc if out of memory. - * - * If `help` is empty, or this method is not called, only a list of - * options is printed. - * Formatting for the help text is described on \ref page_onlinehelp. - */ - CommandLineHelpWriter &setHelpText(const std::string &help); - //! \copydoc setHelpText(const std::string &) - CommandLineHelpWriter & - setHelpText(const ArrayRef &help); - /*! \brief - * Sets the list of known bugs/limitations. - * - * \param[in] bugs Array of bugs/limitations. - * - * Each entry in the input array identifies a separate issue. - * The array passed should remain valid for the lifetime of the writer - * object. - */ - CommandLineHelpWriter & - setKnownIssues(const ArrayRef &bugs); + /*! \brief + * Sets the help text to print as description. + * + * \param[in] help Help text to show. + * \throws std::bad_alloc if out of memory. + * + * If `help` is empty, or this method is not called, only a list of + * options is printed. + * Formatting for the help text is described on \ref page_onlinehelp. + */ + CommandLineHelpWriter& setHelpText(const std::string& help); + //! \copydoc setHelpText(const std::string &) + CommandLineHelpWriter& setHelpText(const ArrayRef& help); + /*! \brief + * Sets the list of known bugs/limitations. + * + * \param[in] bugs Array of bugs/limitations. + * + * Each entry in the input array identifies a separate issue. + * The array passed should remain valid for the lifetime of the writer + * object. + */ + CommandLineHelpWriter& setKnownIssues(const ArrayRef& bugs); - /*! \brief - * Sets text for known bugs. - * - * \param[in] bug Text for bugs to show. - * \throws std::bad_alloc if out of memory. - * - * Formatting for the text is described on \ref page_onlinehelp. - */ - CommandLineHelpWriter &setKnownIssues(ArrayRef bug); + /*! \brief + * Sets text for known bugs. + * + * \param[in] bug Text for bugs to show. + * \throws std::bad_alloc if out of memory. + * + * Formatting for the text is described on \ref page_onlinehelp. + */ + CommandLineHelpWriter& setKnownIssues(ArrayRef bug); - /*! \brief - * Writes the help. - * - * \param[in] context Context object for writing the help. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - void writeHelp(const CommandLineHelpContext &context); + /*! \brief + * Writes the help. + * + * \param[in] context Context object for writing the help. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + void writeHelp(const CommandLineHelpContext& context); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/commandline/cmdlineinit.cpp b/src/gromacs/commandline/cmdlineinit.cpp index 035bcc8e09..81870708ab 100644 --- a/src/gromacs/commandline/cmdlineinit.cpp +++ b/src/gromacs/commandline/cmdlineinit.cpp @@ -73,7 +73,7 @@ namespace //! Global context instance initialized in initForCommandLine(). std::unique_ptr g_commandLineContext; //! Global library data file finder that respects GMXLIB. -std::unique_ptr g_libFileFinder; +std::unique_ptr g_libFileFinder; /*! \brief * Broadcasts command-line arguments to all ranks. @@ -82,7 +82,7 @@ std::unique_ptr g_libFileFinder; * other rank than zero, but our code wants to parse them on each rank * separately. */ -void broadcastArguments(int *argc, char ***argv) +void broadcastArguments(int* argc, char*** argv) { if (gmx_node_num() <= 1) { @@ -93,14 +93,14 @@ void broadcastArguments(int *argc, char ***argv) const bool isMaster = (gmx_node_rank() == 0); if (!isMaster) { - snew(*argv, *argc+1); + snew(*argv, *argc + 1); } for (int i = 0; i < *argc; i++) { int len; if (isMaster) { - len = std::strlen((*argv)[i])+1; + len = std::strlen((*argv)[i]) + 1; } gmx_broadcast_world(sizeof(len), &len); if (!isMaster) @@ -113,13 +113,12 @@ void broadcastArguments(int *argc, char ***argv) //! \} -} // namespace +} // namespace -CommandLineProgramContext &initForCommandLine(int *argc, char ***argv) +CommandLineProgramContext& initForCommandLine(int* argc, char*** argv) { gmx::init(argc, argv); - GMX_RELEASE_ASSERT(!g_commandLineContext, - "initForCommandLine() calls cannot be nested"); + GMX_RELEASE_ASSERT(!g_commandLineContext, "initForCommandLine() calls cannot be nested"); // TODO: Consider whether the argument broadcast would better be done // in CommandLineModuleManager. broadcastArguments(argc, argv); @@ -131,7 +130,7 @@ CommandLineProgramContext &initForCommandLine(int *argc, char ***argv) g_libFileFinder->setSearchPathFromEnv("GMXLIB"); setLibraryFileFinder(g_libFileFinder.get()); } - catch (const std::exception &ex) + catch (const std::exception& ex) { printFatalErrorMessage(stderr, ex); std::exit(processExceptionAtExit(ex)); @@ -148,30 +147,30 @@ void finalizeForCommandLine() g_commandLineContext.reset(); } -int processExceptionAtExitForCommandLine(const std::exception &ex) +int processExceptionAtExitForCommandLine(const std::exception& ex) { int rc = processExceptionAtExit(ex); // Currently this aborts for real MPI finalizeForCommandLine(); // thus this MPI_Finalize doesn't matter. return rc; } -int runCommandLineModule(int argc, char *argv[], - ICommandLineModule *module) +int runCommandLineModule(int argc, char* argv[], ICommandLineModule* module) { return CommandLineModuleManager::runAsMainSingleModule(argc, argv, module); } -int runCommandLineModule( - int argc, char *argv[], const char *name, const char *description, - std::function()> factory) +int runCommandLineModule(int argc, + char* argv[], + const char* name, + const char* description, + std::function()> factory) { - return ICommandLineOptionsModule::runAsMain( - argc, argv, name, description, std::move(factory)); + return ICommandLineOptionsModule::runAsMain(argc, argv, name, description, std::move(factory)); } } // namespace gmx -int gmx_run_cmain(int argc, char *argv[], int (*mainFunction)(int, char *[])) +int gmx_run_cmain(int argc, char* argv[], int (*mainFunction)(int, char*[])) { return gmx::CommandLineModuleManager::runAsMainCMain(argc, argv, mainFunction); } diff --git a/src/gromacs/commandline/cmdlineinit.h b/src/gromacs/commandline/cmdlineinit.h index 3edd96a265..ab7cbfa601 100644 --- a/src/gromacs/commandline/cmdlineinit.h +++ b/src/gromacs/commandline/cmdlineinit.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -83,7 +83,7 @@ class ICommandLineOptionsModule; * \see setProgramContext() * \ingroup module_commandline */ -CommandLineProgramContext &initForCommandLine(int *argc, char ***argv); +CommandLineProgramContext& initForCommandLine(int* argc, char*** argv); /*! \brief * Deinitializes the \Gromacs library after initForCommandLine(). * @@ -106,7 +106,7 @@ void finalizeForCommandLine(); * * Does not throw. */ -int processExceptionAtExitForCommandLine(const std::exception &ex); +int processExceptionAtExitForCommandLine(const std::exception& ex); /*! \brief * Implements a main() method that runs a single module. * @@ -137,8 +137,7 @@ int processExceptionAtExitForCommandLine(const std::exception &ex); * * Does not throw. All exceptions are caught and handled internally. */ -int runCommandLineModule(int argc, char *argv[], - ICommandLineModule *module); +int runCommandLineModule(int argc, char* argv[], ICommandLineModule* module); /*! \brief * Implements a main() method that runs a single module. * @@ -174,8 +173,10 @@ int runCommandLineModule(int argc, char *argv[], * * Does not throw. All exceptions are caught and handled internally. */ -int runCommandLineModule(int argc, char *argv[], - const char *name, const char *description, +int runCommandLineModule(int argc, + char* argv[], + const char* name, + const char* description, std::function()> factory); } // namespace gmx @@ -212,6 +213,6 @@ int runCommandLineModule(int argc, char *argv[], * * Does not throw. All exceptions are caught and handled internally. */ -int gmx_run_cmain(int argc, char *argv[], int (*mainFunction)(int, char *[])); +int gmx_run_cmain(int argc, char* argv[], int (*mainFunction)(int, char*[])); #endif diff --git a/src/gromacs/commandline/cmdlinemodule.cpp b/src/gromacs/commandline/cmdlinemodule.cpp index 9050a5a690..a93255199b 100644 --- a/src/gromacs/commandline/cmdlinemodule.cpp +++ b/src/gromacs/commandline/cmdlinemodule.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,20 +50,15 @@ namespace gmx class CommandLineModuleSettings::Impl { - public: - Impl() : defaultNiceLevel_(19) {} +public: + Impl() : defaultNiceLevel_(19) {} - int defaultNiceLevel_; + int defaultNiceLevel_; }; -CommandLineModuleSettings::CommandLineModuleSettings() - : impl_(new Impl) -{ -} +CommandLineModuleSettings::CommandLineModuleSettings() : impl_(new Impl) {} -CommandLineModuleSettings::~CommandLineModuleSettings() -{ -} +CommandLineModuleSettings::~CommandLineModuleSettings() {} int CommandLineModuleSettings::defaultNiceLevel() const { @@ -76,14 +71,14 @@ void CommandLineModuleSettings::setDefaultNiceLevel(int niceLevel) } //! \cond libapi -void writeCommandLineHelpCMain( - const CommandLineHelpContext &context, const char *name, - int (*mainFunction)(int argc, char *argv[])) +void writeCommandLineHelpCMain(const CommandLineHelpContext& context, + const char* name, + int (*mainFunction)(int argc, char* argv[])) { - char *argv[2]; + char* argv[2]; int argc = 1; // TODO: The constness should not be cast away. - argv[0] = const_cast(name); + argv[0] = const_cast(name); argv[1] = nullptr; GlobalCommandLineHelpContext global(context); mainFunction(argc, argv); diff --git a/src/gromacs/commandline/cmdlinemodule.h b/src/gromacs/commandline/cmdlinemodule.h index fd230241d9..f810043f5d 100644 --- a/src/gromacs/commandline/cmdlinemodule.h +++ b/src/gromacs/commandline/cmdlinemodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,24 +61,24 @@ class CommandLineHelpContext; */ class CommandLineModuleSettings { - public: - CommandLineModuleSettings(); - ~CommandLineModuleSettings(); +public: + CommandLineModuleSettings(); + ~CommandLineModuleSettings(); - //! Returns the default nice level for this module. - int defaultNiceLevel() const; + //! Returns the default nice level for this module. + int defaultNiceLevel() const; - /*! \brief - * Sets the default nice level for this module. - * - * If not called, the module will be niced. - */ - void setDefaultNiceLevel(int niceLevel); + /*! \brief + * Sets the default nice level for this module. + * + * If not called, the module will be niced. + */ + void setDefaultNiceLevel(int niceLevel); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \brief @@ -92,47 +92,47 @@ class CommandLineModuleSettings */ class ICommandLineModule { - public: - virtual ~ICommandLineModule() {} +public: + virtual ~ICommandLineModule() {} - //! Returns the name of the module. - virtual const char *name() const = 0; - //! Returns a one-line description of the module. - virtual const char *shortDescription() const = 0; + //! Returns the name of the module. + virtual const char* name() const = 0; + //! Returns a one-line description of the module. + virtual const char* shortDescription() const = 0; - /*! \brief - * Initializes the module and provides settings for the runner. - * - * This will be called before run(), and can be used to adjust - * initialization that the runner does. - * - * This method is currently not called when writing the help. - */ - virtual void init(CommandLineModuleSettings *settings) = 0; - /*! \brief - * Runs the module with the given arguments. - * - * \param[in] argc Number of elements in \p argv. - * \param[in] argv Command-line arguments. - * \throws unspecified May throw exceptions to indicate errors. - * \returns Exit code for the program. - * \retval 0 on successful termination. - * - * \p argv[0] is the name of the module, i.e., the arguments are as if - * the module was run as a standalone executable. - */ - virtual int run(int argc, char *argv[]) = 0; - /*! \brief - * Prints help for the module. - * - * \param[in] context Context object for writing the help. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * Note that for MPI-enabled builds, this is called only on the master - * rank. - */ - virtual void writeHelp(const CommandLineHelpContext &context) const = 0; + /*! \brief + * Initializes the module and provides settings for the runner. + * + * This will be called before run(), and can be used to adjust + * initialization that the runner does. + * + * This method is currently not called when writing the help. + */ + virtual void init(CommandLineModuleSettings* settings) = 0; + /*! \brief + * Runs the module with the given arguments. + * + * \param[in] argc Number of elements in \p argv. + * \param[in] argv Command-line arguments. + * \throws unspecified May throw exceptions to indicate errors. + * \returns Exit code for the program. + * \retval 0 on successful termination. + * + * \p argv[0] is the name of the module, i.e., the arguments are as if + * the module was run as a standalone executable. + */ + virtual int run(int argc, char* argv[]) = 0; + /*! \brief + * Prints help for the module. + * + * \param[in] context Context object for writing the help. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * Note that for MPI-enabled builds, this is called only on the master + * rank. + */ + virtual void writeHelp(const CommandLineHelpContext& context) const = 0; }; //! \cond libapi @@ -146,9 +146,9 @@ class ICommandLineModule * * \ingroup module_commandline */ -void writeCommandLineHelpCMain( - const CommandLineHelpContext &context, const char *name, - int (*mainFunction)(int argc, char *argv[])); +void writeCommandLineHelpCMain(const CommandLineHelpContext& context, + const char* name, + int (*mainFunction)(int argc, char* argv[])); //! \endcond } // namespace gmx diff --git a/src/gromacs/commandline/cmdlinemodulemanager.cpp b/src/gromacs/commandline/cmdlinemodulemanager.cpp index 85e88e344b..7cf4f002d7 100644 --- a/src/gromacs/commandline/cmdlinemodulemanager.cpp +++ b/src/gromacs/commandline/cmdlinemodulemanager.cpp @@ -87,107 +87,107 @@ namespace */ class CMainCommandLineModule : public ICommandLineModule { - public: - //! \copydoc gmx::CommandLineModuleManager::CMainFunction - typedef CommandLineModuleManager::CMainFunction CMainFunction; - //! \copydoc gmx::CommandLineModuleManager::InitSettingsFunction - typedef CommandLineModuleManager::InitSettingsFunction InitSettingsFunction; - - /*! \brief - * Creates a wrapper module for the given main function. - * - * \param[in] name Name for the module. - * \param[in] shortDescription One-line description for the module. - * \param[in] mainFunction Main function to wrap. - * \param[in] settingsFunction Initializer for settings (can be null). - * - * Does not throw. This is essential for correct implementation of - * CommandLineModuleManager::runAsMainCMain(). - */ - CMainCommandLineModule(const char *name, const char *shortDescription, - CMainFunction mainFunction, - InitSettingsFunction settingsFunction) - : name_(name), shortDescription_(shortDescription), - mainFunction_(mainFunction), settingsFunction_(settingsFunction) - { - } +public: + //! \copydoc gmx::CommandLineModuleManager::CMainFunction + typedef CommandLineModuleManager::CMainFunction CMainFunction; + //! \copydoc gmx::CommandLineModuleManager::InitSettingsFunction + typedef CommandLineModuleManager::InitSettingsFunction InitSettingsFunction; + + /*! \brief + * Creates a wrapper module for the given main function. + * + * \param[in] name Name for the module. + * \param[in] shortDescription One-line description for the module. + * \param[in] mainFunction Main function to wrap. + * \param[in] settingsFunction Initializer for settings (can be null). + * + * Does not throw. This is essential for correct implementation of + * CommandLineModuleManager::runAsMainCMain(). + */ + CMainCommandLineModule(const char* name, + const char* shortDescription, + CMainFunction mainFunction, + InitSettingsFunction settingsFunction) : + name_(name), + shortDescription_(shortDescription), + mainFunction_(mainFunction), + settingsFunction_(settingsFunction) + { + } - const char *name() const override - { - return name_; - } - const char *shortDescription() const override - { - return shortDescription_; - } + const char* name() const override { return name_; } + const char* shortDescription() const override { return shortDescription_; } - void init(CommandLineModuleSettings *settings) override - { - if (settingsFunction_ != nullptr) - { - settingsFunction_(settings); - } - } - int run(int argc, char *argv[]) override - { - return mainFunction_(argc, argv); - } - void writeHelp(const CommandLineHelpContext &context) const override + void init(CommandLineModuleSettings* settings) override + { + if (settingsFunction_ != nullptr) { - writeCommandLineHelpCMain(context, name_, mainFunction_); + settingsFunction_(settings); } + } + int run(int argc, char* argv[]) override { return mainFunction_(argc, argv); } + void writeHelp(const CommandLineHelpContext& context) const override + { + writeCommandLineHelpCMain(context, name_, mainFunction_); + } - private: - const char *name_; - const char *shortDescription_; - CMainFunction mainFunction_; - InitSettingsFunction settingsFunction_; +private: + const char* name_; + const char* shortDescription_; + CMainFunction mainFunction_; + InitSettingsFunction settingsFunction_; }; //! \} -} // namespace +} // namespace /******************************************************************** * CommandLineCommonOptionsHolder */ -CommandLineCommonOptionsHolder::CommandLineCommonOptionsHolder() - : bHelp_(false), bHidden_(false), - bQuiet_(false), bVersion_(false), bCopyright_(true), - niceLevel_(19), bNiceSet_(false), bBackup_(true), bFpexcept_(false), - debugLevel_(0) +CommandLineCommonOptionsHolder::CommandLineCommonOptionsHolder() : + bHelp_(false), + bHidden_(false), + bQuiet_(false), + bVersion_(false), + bCopyright_(true), + niceLevel_(19), + bNiceSet_(false), + bBackup_(true), + bFpexcept_(false), + debugLevel_(0) { binaryInfoSettings_.copyright(true); } -CommandLineCommonOptionsHolder::~CommandLineCommonOptionsHolder() -{ -} +CommandLineCommonOptionsHolder::~CommandLineCommonOptionsHolder() {} void CommandLineCommonOptionsHolder::initOptions() { - options_.addOption(BooleanOption("h").store(&bHelp_) - .description("Print help and quit")); - options_.addOption(BooleanOption("hidden").store(&bHidden_) - .hidden() - .description("Show hidden options in help")); - options_.addOption(BooleanOption("quiet").store(&bQuiet_) - .description("Do not print common startup info or quotes")); - options_.addOption(BooleanOption("version").store(&bVersion_) - .description("Print extended version information and quit")); - options_.addOption(BooleanOption("copyright").store(&bCopyright_) - .description("Print copyright information on startup")); - options_.addOption(IntegerOption("nice").store(&niceLevel_).storeIsSet(&bNiceSet_) - .description("Set the nicelevel (default depends on command)")); - options_.addOption(BooleanOption("backup").store(&bBackup_) - .description("Write backups if output files exist")); - options_.addOption(BooleanOption("fpexcept").store(&bFpexcept_) - .hidden().description("Enable floating-point exceptions")); - options_.addOption(IntegerOption("debug").store(&debugLevel_) - .hidden().defaultValueIfSet(1) - .description("Write file with debug information, " - "1: short (default), 2: also x and f")); + options_.addOption(BooleanOption("h").store(&bHelp_).description("Print help and quit")); + options_.addOption(BooleanOption("hidden").store(&bHidden_).hidden().description( + "Show hidden options in help")); + options_.addOption(BooleanOption("quiet").store(&bQuiet_).description( + "Do not print common startup info or quotes")); + options_.addOption( + BooleanOption("version").store(&bVersion_).description("Print extended version information and quit")); + options_.addOption( + BooleanOption("copyright").store(&bCopyright_).description("Print copyright information on startup")); + options_.addOption(IntegerOption("nice") + .store(&niceLevel_) + .storeIsSet(&bNiceSet_) + .description("Set the nicelevel (default depends on command)")); + options_.addOption(BooleanOption("backup").store(&bBackup_).description( + "Write backups if output files exist")); + options_.addOption( + BooleanOption("fpexcept").store(&bFpexcept_).hidden().description("Enable floating-point exceptions")); + options_.addOption(IntegerOption("debug") + .store(&debugLevel_) + .hidden() + .defaultValueIfSet(1) + .description("Write file with debug information, " + "1: short (default), 2: also x and f")); } bool CommandLineCommonOptionsHolder::finishOptions() @@ -200,8 +200,7 @@ bool CommandLineCommonOptionsHolder::finishOptions() return !bVersion_; } -void CommandLineCommonOptionsHolder::adjustFromSettings( - const CommandLineModuleSettings &settings) +void CommandLineCommonOptionsHolder::adjustFromSettings(const CommandLineModuleSettings& settings) { if (!bNiceSet_) { @@ -220,105 +219,104 @@ void CommandLineCommonOptionsHolder::adjustFromSettings( */ class CommandLineModuleManager::Impl { - public: - /*! \brief - * Initializes the implementation class. - * - * \param[in] binaryName Name of the running binary - * (without Gromacs binary suffix or .exe on Windows). - * \param programContext Program information for the running binary. - */ - Impl(const char *binaryName, CommandLineProgramContext *programContext); - - /*! \brief - * Helper method that adds a given module to the module manager. - * - * \throws std::bad_alloc if out of memory. - */ - void addModule(CommandLineModulePointer module); - /*! \brief - * Creates the help module if it does not yet exist. - * - * \throws std::bad_alloc if out of memory. - * - * This method should be called before accessing \a helpModule_. - */ - void ensureHelpModuleExists(); - - /*! \brief - * Finds a module that matches a name. - * - * \param[in] name Module name to find. - * \returns Iterator to the found module, or - * \c modules_.end() if not found. - * - * Does not throw. - */ - CommandLineModuleMap::const_iterator - findModuleByName(const std::string &name) const; - - /*! \brief - * Processes command-line options for the wrapper binary. - * - * \param[in,out] optionsHolder Common options. - * \param[in,out] argc On input, argc passed to run(). - * On output, argc to be passed to the module. - * \param[in,out] argv On input, argv passed to run(). - * On output, argv to be passed to the module. - * \throws InvalidInputError if there are invalid options. - * \returns The module that should be run. - * - * Handles command-line options that affect the wrapper binary - * (potentially changing the members of \c this in response to the - * options). Also finds the module that should be run and the - * arguments that should be passed to it. - */ - ICommandLineModule * - processCommonOptions(CommandLineCommonOptionsHolder *optionsHolder, - int *argc, char ***argv); - - //! Prints the footer at the end of execution. - void printThanks(FILE *fp); - - /*! \brief - * Maps module names to module objects. - * - * Owns the contained modules. - */ - CommandLineModuleMap modules_; - /*! \brief - * List of groupings for modules for help output. - * - * Owns the contained module group data objects. - * CommandLineModuleGroup objects point to the data objects contained - * here. - */ - CommandLineModuleGroupList moduleGroups_; - //! Information about the currently running program. - CommandLineProgramContext &programContext_; - //! Name of the binary. - std::string binaryName_; - /*! \brief - * Module that implements help for the binary. - * - * The pointed module is owned by the \a modules_ container. - */ - CommandLineHelpModule *helpModule_; - //! If non-NULL, run this module in single-module mode. - ICommandLineModule *singleModule_; - //! Stores the value set with setQuiet(). - bool bQuiet_; - - private: - GMX_DISALLOW_COPY_AND_ASSIGN(Impl); +public: + /*! \brief + * Initializes the implementation class. + * + * \param[in] binaryName Name of the running binary + * (without Gromacs binary suffix or .exe on Windows). + * \param programContext Program information for the running binary. + */ + Impl(const char* binaryName, CommandLineProgramContext* programContext); + + /*! \brief + * Helper method that adds a given module to the module manager. + * + * \throws std::bad_alloc if out of memory. + */ + void addModule(CommandLineModulePointer module); + /*! \brief + * Creates the help module if it does not yet exist. + * + * \throws std::bad_alloc if out of memory. + * + * This method should be called before accessing \a helpModule_. + */ + void ensureHelpModuleExists(); + + /*! \brief + * Finds a module that matches a name. + * + * \param[in] name Module name to find. + * \returns Iterator to the found module, or + * \c modules_.end() if not found. + * + * Does not throw. + */ + CommandLineModuleMap::const_iterator findModuleByName(const std::string& name) const; + + /*! \brief + * Processes command-line options for the wrapper binary. + * + * \param[in,out] optionsHolder Common options. + * \param[in,out] argc On input, argc passed to run(). + * On output, argc to be passed to the module. + * \param[in,out] argv On input, argv passed to run(). + * On output, argv to be passed to the module. + * \throws InvalidInputError if there are invalid options. + * \returns The module that should be run. + * + * Handles command-line options that affect the wrapper binary + * (potentially changing the members of \c this in response to the + * options). Also finds the module that should be run and the + * arguments that should be passed to it. + */ + ICommandLineModule* processCommonOptions(CommandLineCommonOptionsHolder* optionsHolder, + int* argc, + char*** argv); + + //! Prints the footer at the end of execution. + void printThanks(FILE* fp); + + /*! \brief + * Maps module names to module objects. + * + * Owns the contained modules. + */ + CommandLineModuleMap modules_; + /*! \brief + * List of groupings for modules for help output. + * + * Owns the contained module group data objects. + * CommandLineModuleGroup objects point to the data objects contained + * here. + */ + CommandLineModuleGroupList moduleGroups_; + //! Information about the currently running program. + CommandLineProgramContext& programContext_; + //! Name of the binary. + std::string binaryName_; + /*! \brief + * Module that implements help for the binary. + * + * The pointed module is owned by the \a modules_ container. + */ + CommandLineHelpModule* helpModule_; + //! If non-NULL, run this module in single-module mode. + ICommandLineModule* singleModule_; + //! Stores the value set with setQuiet(). + bool bQuiet_; + +private: + GMX_DISALLOW_COPY_AND_ASSIGN(Impl); }; -CommandLineModuleManager::Impl::Impl(const char *binaryName, - CommandLineProgramContext *programContext) - : programContext_(*programContext), - binaryName_(binaryName != nullptr ? binaryName : ""), - helpModule_(nullptr), singleModule_(nullptr), - bQuiet_(false) +CommandLineModuleManager::Impl::Impl(const char* binaryName, CommandLineProgramContext* programContext) : + programContext_(*programContext), + binaryName_(binaryName != nullptr ? binaryName : ""), + helpModule_(nullptr), + singleModule_(nullptr), + bQuiet_(false) { GMX_RELEASE_ASSERT(binaryName_.find('-') == std::string::npos, "Help export does not currently work with binary names with dashes"); @@ -330,8 +328,7 @@ void CommandLineModuleManager::Impl::addModule(CommandLineModulePointer module) "Attempted to register a duplicate module name"); ensureHelpModuleExists(); HelpTopicPointer helpTopic(helpModule_->createModuleHelpTopic(*module)); - modules_.insert(std::make_pair(std::string(module->name()), - std::move(module))); + modules_.insert(std::make_pair(std::string(module->name()), std::move(module))); helpModule_->addTopic(std::move(helpTopic), false); } @@ -339,25 +336,23 @@ void CommandLineModuleManager::Impl::ensureHelpModuleExists() { if (helpModule_ == nullptr) { - helpModule_ = new CommandLineHelpModule(programContext_, binaryName_, - modules_, moduleGroups_); + helpModule_ = new CommandLineHelpModule(programContext_, binaryName_, modules_, moduleGroups_); addModule(CommandLineModulePointer(helpModule_)); } } -CommandLineModuleMap::const_iterator -CommandLineModuleManager::Impl::findModuleByName(const std::string &name) const +CommandLineModuleMap::const_iterator CommandLineModuleManager::Impl::findModuleByName(const std::string& name) const { // TODO: Accept unambiguous prefixes? return modules_.find(name); } -ICommandLineModule * -CommandLineModuleManager::Impl::processCommonOptions( - CommandLineCommonOptionsHolder *optionsHolder, int *argc, char ***argv) +ICommandLineModule* CommandLineModuleManager::Impl::processCommonOptions(CommandLineCommonOptionsHolder* optionsHolder, + int* argc, + char*** argv) { // Check if we are directly invoking a certain module. - ICommandLineModule *module = singleModule_; + ICommandLineModule* module = singleModule_; // TODO: It would be nice to propagate at least the -quiet option to // the modules so that they can also be quiet in response to this. @@ -378,19 +373,16 @@ CommandLineModuleManager::Impl::processCommonOptions( // Process options that are provided to the wrapper // binary. These precede the module name, if one exists. int argcForWrapper = indexOfModuleName; - CommandLineParser(optionsHolder->options()) - .parse(&argcForWrapper, *argv); + CommandLineParser(optionsHolder->options()).parse(&argcForWrapper, *argv); } // If no action requested and there is a module specified, process it. if (indexOfModuleName < *argc && !optionsHolder->shouldIgnoreActualModule()) { - const char *moduleName = (*argv)[indexOfModuleName]; - CommandLineModuleMap::const_iterator moduleIter - = findModuleByName(moduleName); + const char* moduleName = (*argv)[indexOfModuleName]; + CommandLineModuleMap::const_iterator moduleIter = findModuleByName(moduleName); if (moduleIter == modules_.end()) { - std::string message = - formatString("'%s' is not a GROMACS command.", moduleName); + std::string message = formatString("'%s' is not a GROMACS command.", moduleName); GMX_THROW(InvalidInputError(message)); } module = moduleIter->second.get(); @@ -409,9 +401,7 @@ CommandLineModuleManager::Impl::processCommonOptions( // Recognize the common options also after the module name. // TODO: It could be nicer to only recognize -h/-hidden if module is not // null. - CommandLineParser(optionsHolder->options()) - .allowPositionalArguments(true) - .skipUnknown(true).parse(argc, *argv); + CommandLineParser(optionsHolder->options()).allowPositionalArguments(true).skipUnknown(true).parse(argc, *argv); } if (!optionsHolder->finishOptions()) { @@ -436,7 +426,7 @@ CommandLineModuleManager::Impl::processCommonOptions( return module; } -void CommandLineModuleManager::Impl::printThanks(FILE *fp) +void CommandLineModuleManager::Impl::printThanks(FILE* fp) { fprintf(fp, "\n%s\n\n", getCoolQuote().c_str()); } @@ -445,29 +435,26 @@ void CommandLineModuleManager::Impl::printThanks(FILE *fp) * CommandLineModuleManager */ -CommandLineModuleManager::CommandLineModuleManager( - const char *binaryName, CommandLineProgramContext *programContext) - : impl_(new Impl(binaryName, programContext)) +CommandLineModuleManager::CommandLineModuleManager(const char* binaryName, + CommandLineProgramContext* programContext) : + impl_(new Impl(binaryName, programContext)) { } -CommandLineModuleManager::~CommandLineModuleManager() -{ -} +CommandLineModuleManager::~CommandLineModuleManager() {} void CommandLineModuleManager::setQuiet(bool bQuiet) { impl_->bQuiet_ = bQuiet; } -void CommandLineModuleManager::setOutputRedirector( - IFileOutputRedirector *output) +void CommandLineModuleManager::setOutputRedirector(IFileOutputRedirector* output) { impl_->ensureHelpModuleExists(); impl_->helpModule_->setOutputRedirector(output); } -void CommandLineModuleManager::setSingleModule(ICommandLineModule *module) +void CommandLineModuleManager::setSingleModule(ICommandLineModule* module) { impl_->singleModule_ = module; } @@ -477,30 +464,26 @@ void CommandLineModuleManager::addModule(CommandLineModulePointer module) impl_->addModule(std::move(module)); } -void CommandLineModuleManager::addModuleCMain( - const char *name, const char *shortDescription, - CMainFunction mainFunction) +void CommandLineModuleManager::addModuleCMain(const char* name, const char* shortDescription, CMainFunction mainFunction) { CommandLineModulePointer module( - new CMainCommandLineModule(name, shortDescription, mainFunction, - nullptr)); + new CMainCommandLineModule(name, shortDescription, mainFunction, nullptr)); addModule(std::move(module)); } -void CommandLineModuleManager::addModuleCMainWithSettings( - const char *name, const char *shortDescription, - CMainFunction mainFunction, InitSettingsFunction settingsFunction) +void CommandLineModuleManager::addModuleCMainWithSettings(const char* name, + const char* shortDescription, + CMainFunction mainFunction, + InitSettingsFunction settingsFunction) { CommandLineModulePointer module( - new CMainCommandLineModule(name, shortDescription, mainFunction, - settingsFunction)); + new CMainCommandLineModule(name, shortDescription, mainFunction, settingsFunction)); addModule(std::move(module)); } -CommandLineModuleGroup CommandLineModuleManager::addModuleGroup( - const char *title) +CommandLineModuleGroup CommandLineModuleManager::addModuleGroup(const char* title) { - const char *const binaryName = impl_->binaryName_.c_str(); + const char* const binaryName = impl_->binaryName_.c_str(); CommandLineModuleGroupDataPointer group( new CommandLineModuleGroupData(impl_->modules_, binaryName, title)); impl_->moduleGroups_.push_back(std::move(group)); @@ -513,9 +496,9 @@ void CommandLineModuleManager::addHelpTopic(HelpTopicPointer topic) impl_->helpModule_->addTopic(std::move(topic), true); } -int CommandLineModuleManager::run(int argc, char *argv[]) +int CommandLineModuleManager::run(int argc, char* argv[]) { - ICommandLineModule *module; + ICommandLineModule* module; const bool bMaster = (gmx_node_rank() == 0); bool bQuiet = impl_->bQuiet_ || !bMaster; CommandLineCommonOptionsHolder optionsHolder; @@ -524,22 +507,20 @@ int CommandLineModuleManager::run(int argc, char *argv[]) optionsHolder.initOptions(); module = impl_->processCommonOptions(&optionsHolder, &argc, &argv); } - catch (const std::exception &) + catch (const std::exception&) { bQuiet |= optionsHolder.shouldBeQuiet(); if (!bQuiet) { - printBinaryInformation(stderr, impl_->programContext_, - optionsHolder.binaryInfoSettings()); + printBinaryInformation(stderr, impl_->programContext_, optionsHolder.binaryInfoSettings()); } throw; } bQuiet |= optionsHolder.shouldBeQuiet(); if (!bQuiet) { - FILE *out = optionsHolder.startupInfoFile(); - printBinaryInformation(out, impl_->programContext_, - optionsHolder.binaryInfoSettings()); + FILE* out = optionsHolder.startupInfoFile(); + printBinaryInformation(out, impl_->programContext_, optionsHolder.binaryInfoSettings()); fprintf(out, "\n"); } if (module == nullptr) @@ -579,7 +560,7 @@ int CommandLineModuleManager::run(int argc, char *argv[]) } if (optionsHolder.enableFPExceptions()) { - //TODO: currently it is always enabled for mdrun (verlet) and tests. + // TODO: currently it is always enabled for mdrun (verlet) and tests. gmx_feenableexcept(); } @@ -596,10 +577,9 @@ int CommandLineModuleManager::run(int argc, char *argv[]) } // static -int CommandLineModuleManager::runAsMainSingleModule( - int argc, char *argv[], ICommandLineModule *module) +int CommandLineModuleManager::runAsMainSingleModule(int argc, char* argv[], ICommandLineModule* module) { - CommandLineProgramContext &programContext = gmx::initForCommandLine(&argc, &argv); + CommandLineProgramContext& programContext = gmx::initForCommandLine(&argc, &argv); try { CommandLineModuleManager manager(nullptr, &programContext); @@ -608,7 +588,7 @@ int CommandLineModuleManager::runAsMainSingleModule( gmx::finalizeForCommandLine(); return rc; } - catch (const std::exception &ex) + catch (const std::exception& ex) { printFatalErrorMessage(stderr, ex); return processExceptionAtExitForCommandLine(ex); @@ -616,17 +596,17 @@ int CommandLineModuleManager::runAsMainSingleModule( } // static -int CommandLineModuleManager::runAsMainCMain( - int argc, char *argv[], CMainFunction mainFunction) +int CommandLineModuleManager::runAsMainCMain(int argc, char* argv[], CMainFunction mainFunction) { CMainCommandLineModule module(argv[0], nullptr, mainFunction, nullptr); return runAsMainSingleModule(argc, argv, &module); } // static -int CommandLineModuleManager::runAsMainCMainWithSettings( - int argc, char *argv[], CMainFunction mainFunction, - InitSettingsFunction settingsFunction) +int CommandLineModuleManager::runAsMainCMainWithSettings(int argc, + char* argv[], + CMainFunction mainFunction, + InitSettingsFunction settingsFunction) { CMainCommandLineModule module(argv[0], nullptr, mainFunction, settingsFunction); return runAsMainSingleModule(argc, argv, &module); @@ -636,19 +616,16 @@ int CommandLineModuleManager::runAsMainCMainWithSettings( * CommandLineModuleGroupData */ -void CommandLineModuleGroupData::addModule(const char *name, - const char *description) +void CommandLineModuleGroupData::addModule(const char* name, const char* description) { CommandLineModuleMap::const_iterator moduleIter = allModules_.find(name); - GMX_RELEASE_ASSERT(moduleIter != allModules_.end(), - "Non-existent module added to a group"); + GMX_RELEASE_ASSERT(moduleIter != allModules_.end(), "Non-existent module added to a group"); if (description == nullptr) { description = moduleIter->second->shortDescription(); - GMX_RELEASE_ASSERT(description != nullptr, - "Module without a description added to a group"); + GMX_RELEASE_ASSERT(description != nullptr, "Module without a description added to a group"); } - std::string tag(formatString("%s-%s", binaryName_, name)); + std::string tag(formatString("%s-%s", binaryName_, name)); modules_.push_back(std::make_pair(tag, description)); } @@ -656,13 +633,12 @@ void CommandLineModuleGroupData::addModule(const char *name, * CommandLineModuleGroup */ -void CommandLineModuleGroup::addModule(const char *name) +void CommandLineModuleGroup::addModule(const char* name) { impl_->addModule(name, nullptr); } -void CommandLineModuleGroup::addModuleWithDescription(const char *name, - const char *description) +void CommandLineModuleGroup::addModuleWithDescription(const char* name, const char* description) { impl_->addModule(name, description); } diff --git a/src/gromacs/commandline/cmdlinemodulemanager.h b/src/gromacs/commandline/cmdlinemodulemanager.h index 7bdd30bf8e..f850bcedcd 100644 --- a/src/gromacs/commandline/cmdlinemodulemanager.h +++ b/src/gromacs/commandline/cmdlinemodulemanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,8 +62,7 @@ class IFileOutputRedirector; //! \{ //! Smart pointer type for managing a ICommandLineModule. -typedef std::unique_ptr - CommandLineModulePointer; +typedef std::unique_ptr CommandLineModulePointer; /*! \libinternal \brief * Implements a wrapper command-line interface for multiple modules. @@ -94,259 +93,257 @@ typedef std::unique_ptr */ class CommandLineModuleManager { - public: - //! Function pointer type for a C main function. - typedef int (*CMainFunction)(int argc, char *argv[]); - //! Function pointer to a settings provider. - typedef void (*InitSettingsFunction)(CommandLineModuleSettings *settings); +public: + //! Function pointer type for a C main function. + typedef int (*CMainFunction)(int argc, char* argv[]); + //! Function pointer to a settings provider. + typedef void (*InitSettingsFunction)(CommandLineModuleSettings* settings); - /*! \brief - * Implements a main() method that runs a single module. - * - * \param argc \c argc passed to main(). - * \param argv \c argv passed to main(). - * \param module Module to run. - * - * This method allows for uniform behavior for binaries that only - * contain a single module without duplicating any of the - * implementation from CommandLineModuleManager (startup headers, - * common options etc.). - * - * The signature assumes that \p module construction does not throw - * (because otherwise the caller would need to duplicate all the - * exception handling code). It is possible to move the construction - * inside the try/catch in this method using an indirection similar to - * TrajectoryAnalysisCommandLineRunner::runAsMain(), but until that is - * necessary, the current approach leads to simpler code. - * - * Usage: - * \code - int main(int argc, char *argv[]) - { - CustomCommandLineModule module; - return gmx::CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module); - } - * \endcode - * - * Does not throw. All exceptions are caught and handled internally. - */ - static int runAsMainSingleModule(int argc, char *argv[], - ICommandLineModule *module); - /*! \brief - * Implements a main() method that runs a given function. - * - * \param argc \c argc passed to main(). - * \param argv \c argv passed to main(). - * \param mainFunction The main()-like method to wrap. - * - * This method creates a dummy command-line module that does its - * processing by calling \p mainFunction; see addModuleCMain() for - * details. It then runs this module with runAsMainSingleModule(). - * This allows the resulting executable to handle common options and do - * other common actions (e.g., startup headers) without duplicate code - * in the main methods. - * - * Usage: - * \code - int my_main(int argc, char *argv[]) - { - // <...> - } + /*! \brief + * Implements a main() method that runs a single module. + * + * \param argc \c argc passed to main(). + * \param argv \c argv passed to main(). + * \param module Module to run. + * + * This method allows for uniform behavior for binaries that only + * contain a single module without duplicating any of the + * implementation from CommandLineModuleManager (startup headers, + * common options etc.). + * + * The signature assumes that \p module construction does not throw + * (because otherwise the caller would need to duplicate all the + * exception handling code). It is possible to move the construction + * inside the try/catch in this method using an indirection similar to + * TrajectoryAnalysisCommandLineRunner::runAsMain(), but until that is + * necessary, the current approach leads to simpler code. + * + * Usage: + * \code + int main(int argc, char *argv[]) + { + CustomCommandLineModule module; + return gmx::CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module); + } + * \endcode + * + * Does not throw. All exceptions are caught and handled internally. + */ + static int runAsMainSingleModule(int argc, char* argv[], ICommandLineModule* module); + /*! \brief + * Implements a main() method that runs a given function. + * + * \param argc \c argc passed to main(). + * \param argv \c argv passed to main(). + * \param mainFunction The main()-like method to wrap. + * + * This method creates a dummy command-line module that does its + * processing by calling \p mainFunction; see addModuleCMain() for + * details. It then runs this module with runAsMainSingleModule(). + * This allows the resulting executable to handle common options and do + * other common actions (e.g., startup headers) without duplicate code + * in the main methods. + * + * Usage: + * \code + int my_main(int argc, char *argv[]) + { + // <...> + } - int main(int argc, char *argv[]) - { - return gmx::CommandLineModuleManager::runAsMainCMain(argc, argv, &my_main); - } - * \endcode - * - * Does not throw. All exceptions are caught and handled internally. - */ - static int runAsMainCMain(int argc, char *argv[], - CMainFunction mainFunction); - /*! \brief - * Implements a main() method that runs a given function with custom - * settings. - * - * This method does the same as runAsMainCMain(), but additionally - * calls \p settingsFunction to initialize CommandLineModuleSettings. - * This allows specifying, e.g., a different default nice level. - */ - static int runAsMainCMainWithSettings(int argc, char *argv[], - CMainFunction mainFunction, - InitSettingsFunction settingsFunction); + int main(int argc, char *argv[]) + { + return gmx::CommandLineModuleManager::runAsMainCMain(argc, argv, &my_main); + } + * \endcode + * + * Does not throw. All exceptions are caught and handled internally. + */ + static int runAsMainCMain(int argc, char* argv[], CMainFunction mainFunction); + /*! \brief + * Implements a main() method that runs a given function with custom + * settings. + * + * This method does the same as runAsMainCMain(), but additionally + * calls \p settingsFunction to initialize CommandLineModuleSettings. + * This allows specifying, e.g., a different default nice level. + */ + static int runAsMainCMainWithSettings(int argc, + char* argv[], + CMainFunction mainFunction, + InitSettingsFunction settingsFunction); - /*! \brief - * Initializes a command-line module manager. - * - * \param[in] binaryName Name of the running binary - * (without Gromacs binary suffix or .exe on Windows). - * \param programContext Program information for the running binary. - * \throws std::bad_alloc if out of memory. - * - * \p binaryName is used to detect when the binary is run through a - * symlink, and automatically invoke a matching module in such a case. - * - * \p programInfo is non-const to allow the manager to amend it based - * on the actual module that is getting executed. - */ - CommandLineModuleManager(const char *binaryName, - CommandLineProgramContext *programContext); - ~CommandLineModuleManager(); + /*! \brief + * Initializes a command-line module manager. + * + * \param[in] binaryName Name of the running binary + * (without Gromacs binary suffix or .exe on Windows). + * \param programContext Program information for the running binary. + * \throws std::bad_alloc if out of memory. + * + * \p binaryName is used to detect when the binary is run through a + * symlink, and automatically invoke a matching module in such a case. + * + * \p programInfo is non-const to allow the manager to amend it based + * on the actual module that is getting executed. + */ + CommandLineModuleManager(const char* binaryName, CommandLineProgramContext* programContext); + ~CommandLineModuleManager(); - /*! \brief - * Sets the module manager to quiet mode: don't print anything. - * - * \param[in] bQuiet Whether the module manager should remain silent. - * - * Normally, the module manager prints out some information to `stderr` - * before it starts the module and after it finishes. This removes - * that output, which is useful in particular for unit tests so that - * they don't spam `stderr`. - */ - void setQuiet(bool bQuiet); - /*! \brief - * Redirects the output of the module manager to a file. - * - * \param[in] output File redirector to use for output. - * - * Normally, the module manager prints explicitly requested text such - * as help output to `stdout`, but this method can be used to redirect - * that output to a file. For exporting help from the module manager, - * several files are written, and can be redirected with this method as - * well. - * - * This is used for unit tests, either to keep them quiet or to verify - * that output. To keep implementation options open, behavior with - * `output == NULL` is undefined and should not be relied on. - * For tests, there should only be need to call this a single time, - * right after creating the manager. - */ - void setOutputRedirector(IFileOutputRedirector *output); + /*! \brief + * Sets the module manager to quiet mode: don't print anything. + * + * \param[in] bQuiet Whether the module manager should remain silent. + * + * Normally, the module manager prints out some information to `stderr` + * before it starts the module and after it finishes. This removes + * that output, which is useful in particular for unit tests so that + * they don't spam `stderr`. + */ + void setQuiet(bool bQuiet); + /*! \brief + * Redirects the output of the module manager to a file. + * + * \param[in] output File redirector to use for output. + * + * Normally, the module manager prints explicitly requested text such + * as help output to `stdout`, but this method can be used to redirect + * that output to a file. For exporting help from the module manager, + * several files are written, and can be redirected with this method as + * well. + * + * This is used for unit tests, either to keep them quiet or to verify + * that output. To keep implementation options open, behavior with + * `output == NULL` is undefined and should not be relied on. + * For tests, there should only be need to call this a single time, + * right after creating the manager. + */ + void setOutputRedirector(IFileOutputRedirector* output); - /*! \brief - * Makes the manager always run a single module. - * - * \param module Module to run. - * - * This method disables all mechanisms for selecting a module, and - * directly passes all command-line arguments to \p module. - * Help arguments are an exception: these are still recognized by the - * manager and translated into a call to - * ICommandLineModule::writeHelp(). - * - * This is public mainly for unit testing purposes; for other code, - * runAsMainSingleModule() typically provides the desired - * functionality. - * - * Does not throw. - */ - void setSingleModule(ICommandLineModule *module); - /*! \brief - * Adds a given module to this manager. - * - * \param module Module to add. - * \throws std::bad_alloc if out of memory. - * - * The manager takes ownership of the object. - * - * This method is public mostly for testing purposes; for typical uses, - * registerModule() is a more convenient way of adding modules. - * - * \see registerModule() - */ - void addModule(CommandLineModulePointer module); - /*! \brief - * Adds a module that runs a given main()-like function. - * - * \param[in] name Name for the module. - * \param[in] shortDescription One-line description for the module. - * \param[in] mainFunction Main function to wrap. - * \throws std::bad_alloc if out of memory. - * - * There is normally no need to call this method outside the Gromacs - * library. User code usually wants to use runAsMainCMain(). - * - * \p name and \p shortDescription should be string constants, or the - * caller should otherwise ensure that they stay in scope for the - * duration the CommandLineModuleManager object exists. - * \p mainFunction should call parse_common_args() to process its - * command-line arguments. - */ - void addModuleCMain(const char *name, const char *shortDescription, - CMainFunction mainFunction); - /*! \brief - * Adds a module that runs a given main()-like function with custom - * settings. - * - * This method does the same as runAsMainCMain(), but additionally - * calls \p settingsFunction to initialize CommandLineModuleSettings. - * This allows specifying, e.g., a different default nice level. - */ - void addModuleCMainWithSettings(const char *name, const char *shortDescription, - CMainFunction mainFunction, - InitSettingsFunction settingsFunction); - /*! \brief - * Registers a module of a certain type to this manager. - * - * \tparam Module Type of module to register. - * \throws std::bad_alloc if out of memory. - * - * \p Module must be default-constructible and implement - * ICommandLineModule. - * - * This method is provided as a convenient alternative to addModule() - * for cases where each module is implemented by a different type - * (which should be the case for typical situations outside unit - * tests). - */ - template - void registerModule() - { - addModule(CommandLineModulePointer(new Module)); - } + /*! \brief + * Makes the manager always run a single module. + * + * \param module Module to run. + * + * This method disables all mechanisms for selecting a module, and + * directly passes all command-line arguments to \p module. + * Help arguments are an exception: these are still recognized by the + * manager and translated into a call to + * ICommandLineModule::writeHelp(). + * + * This is public mainly for unit testing purposes; for other code, + * runAsMainSingleModule() typically provides the desired + * functionality. + * + * Does not throw. + */ + void setSingleModule(ICommandLineModule* module); + /*! \brief + * Adds a given module to this manager. + * + * \param module Module to add. + * \throws std::bad_alloc if out of memory. + * + * The manager takes ownership of the object. + * + * This method is public mostly for testing purposes; for typical uses, + * registerModule() is a more convenient way of adding modules. + * + * \see registerModule() + */ + void addModule(CommandLineModulePointer module); + /*! \brief + * Adds a module that runs a given main()-like function. + * + * \param[in] name Name for the module. + * \param[in] shortDescription One-line description for the module. + * \param[in] mainFunction Main function to wrap. + * \throws std::bad_alloc if out of memory. + * + * There is normally no need to call this method outside the Gromacs + * library. User code usually wants to use runAsMainCMain(). + * + * \p name and \p shortDescription should be string constants, or the + * caller should otherwise ensure that they stay in scope for the + * duration the CommandLineModuleManager object exists. + * \p mainFunction should call parse_common_args() to process its + * command-line arguments. + */ + void addModuleCMain(const char* name, const char* shortDescription, CMainFunction mainFunction); + /*! \brief + * Adds a module that runs a given main()-like function with custom + * settings. + * + * This method does the same as runAsMainCMain(), but additionally + * calls \p settingsFunction to initialize CommandLineModuleSettings. + * This allows specifying, e.g., a different default nice level. + */ + void addModuleCMainWithSettings(const char* name, + const char* shortDescription, + CMainFunction mainFunction, + InitSettingsFunction settingsFunction); + /*! \brief + * Registers a module of a certain type to this manager. + * + * \tparam Module Type of module to register. + * \throws std::bad_alloc if out of memory. + * + * \p Module must be default-constructible and implement + * ICommandLineModule. + * + * This method is provided as a convenient alternative to addModule() + * for cases where each module is implemented by a different type + * (which should be the case for typical situations outside unit + * tests). + */ + template + void registerModule() + { + addModule(CommandLineModulePointer(new Module)); + } - /*! \brief - * Adds a group for modules to use in help output. - * - * \param[in] title Short title for the group. - * \returns Handle that can be used to add modules to the group. - * \throws std::bad_alloc if out of memory. - * - * Creates a group that is used to structure the list of all modules in - * help output. Modules are added to the group using the returned - * object. - */ - CommandLineModuleGroup addModuleGroup(const char *title); + /*! \brief + * Adds a group for modules to use in help output. + * + * \param[in] title Short title for the group. + * \returns Handle that can be used to add modules to the group. + * \throws std::bad_alloc if out of memory. + * + * Creates a group that is used to structure the list of all modules in + * help output. Modules are added to the group using the returned + * object. + */ + CommandLineModuleGroup addModuleGroup(const char* title); - /*! \brief - * Makes given help topic available through the manager's help module. - * - * \param[in] topic Help topic to add. - * \throws std::bad_alloc if out of memory. - * - * The manager takes ownership of the help topic. - */ - void addHelpTopic(HelpTopicPointer topic); + /*! \brief + * Makes given help topic available through the manager's help module. + * + * \param[in] topic Help topic to add. + * \throws std::bad_alloc if out of memory. + * + * The manager takes ownership of the help topic. + */ + void addHelpTopic(HelpTopicPointer topic); - /*! \brief - * Runs a module based on given command line. - * - * \param[in] argc Number of elements in \p argv. - * \param[in] argv Command-line arguments. - * \throws unspecified Throws any exception that the selected module - * throws. - * \returns Exit code for the program. - * \retval 0 on successful termination. - * \retval 2 if no module is specified, or if the module is not found. - * - * Runs the module whose name matches \p argv[1]. - */ - int run(int argc, char *argv[]); + /*! \brief + * Runs a module based on given command line. + * + * \param[in] argc Number of elements in \p argv. + * \param[in] argv Command-line arguments. + * \throws unspecified Throws any exception that the selected module + * throws. + * \returns Exit code for the program. + * \retval 0 on successful termination. + * \retval 2 if no module is specified, or if the module is not found. + * + * Runs the module whose name matches \p argv[1]. + */ + int run(int argc, char* argv[]); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -362,42 +359,42 @@ class CommandLineModuleManager */ class CommandLineModuleGroup { - public: - /*! \cond internal */ - //! Shorthand for the implementation type that holds all the data. - typedef CommandLineModuleGroupData Impl; +public: + /*! \cond internal */ + //! Shorthand for the implementation type that holds all the data. + typedef CommandLineModuleGroupData Impl; - //! Creates a new group (only called by CommandLineModuleManager). - explicit CommandLineModuleGroup(Impl *impl) : impl_(impl) {} - //! \endcond + //! Creates a new group (only called by CommandLineModuleManager). + explicit CommandLineModuleGroup(Impl* impl) : impl_(impl) {} + //! \endcond - /*! \brief - * Adds a module to this group. - * - * \param[in] name Name of the module. - * \throws std::bad_alloc if out of memory. - * - * This works as addModuleWithDescription(), but uses the short - * description of the module itself as the description. - * - * \see addModuleWithDescription() - */ - void addModule(const char *name); - /*! \brief - * Adds a module to this group with a custom description. - * - * \param[in] name Name of the module. - * \param[in] description Description of the module in this group. - * \throws std::bad_alloc if out of memory. - * - * \p name must name a module added into the CommandLineModuleManager. - * It is possible to add the same module into multiple groups. - */ - void addModuleWithDescription(const char *name, const char *description); + /*! \brief + * Adds a module to this group. + * + * \param[in] name Name of the module. + * \throws std::bad_alloc if out of memory. + * + * This works as addModuleWithDescription(), but uses the short + * description of the module itself as the description. + * + * \see addModuleWithDescription() + */ + void addModule(const char* name); + /*! \brief + * Adds a module to this group with a custom description. + * + * \param[in] name Name of the module. + * \param[in] description Description of the module in this group. + * \throws std::bad_alloc if out of memory. + * + * \p name must name a module added into the CommandLineModuleManager. + * It is possible to add the same module into multiple groups. + */ + void addModuleWithDescription(const char* name, const char* description); - private: - //! Pointer to the data owned by CommandLineModuleManager. - Impl *impl_; +private: + //! Pointer to the data owned by CommandLineModuleManager. + Impl* impl_; }; //! \} diff --git a/src/gromacs/commandline/cmdlinemodulemanager_impl.h b/src/gromacs/commandline/cmdlinemodulemanager_impl.h index 0141f24138..2ab9d2bb0d 100644 --- a/src/gromacs/commandline/cmdlinemodulemanager_impl.h +++ b/src/gromacs/commandline/cmdlinemodulemanager_impl.h @@ -73,65 +73,63 @@ typedef std::map CommandLineModuleMap; */ class CommandLineModuleGroupData { - public: - /*! \brief - * Shorthand for a list of modules contained in the group. - * - * The first element in the contained pair contains the tag - * (gmx-something) of the module, and the second element contains the - * description. The second element is never NULL. - */ - typedef std::vector > ModuleList; - - /*! \brief - * Constructs an empty module group. - * - * \param[in] modules List of all modules - * (used for checking and default descriptions). - * \param[in] binaryName Name of the binary containing the modules. - * \param[in] title Title of the group. - * - * Does not throw. - */ - CommandLineModuleGroupData(const CommandLineModuleMap &modules, - const char *binaryName, - const char *title) - : allModules_(modules), binaryName_(binaryName), title_(title) - { - } - - //! Returns the title for the group. - const char *title() const { return title_; } - //! Returns the list of modules in the group. - const ModuleList &modules() const { return modules_; } - - /*! \brief - * Adds a module to the group. - * - * \param[in] name Name of the module. - * \param[in] description Description of the module in this group. - * \throws std::bad_alloc if out of memory. - * - * If \p description is NULL, the description returned by the module is - * used. - */ - void addModule(const char *name, const char *description); - - private: - const CommandLineModuleMap &allModules_; - const char *binaryName_; - const char *title_; - ModuleList modules_; - - GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineModuleGroupData); +public: + /*! \brief + * Shorthand for a list of modules contained in the group. + * + * The first element in the contained pair contains the tag + * (gmx-something) of the module, and the second element contains the + * description. The second element is never NULL. + */ + typedef std::vector> ModuleList; + + /*! \brief + * Constructs an empty module group. + * + * \param[in] modules List of all modules + * (used for checking and default descriptions). + * \param[in] binaryName Name of the binary containing the modules. + * \param[in] title Title of the group. + * + * Does not throw. + */ + CommandLineModuleGroupData(const CommandLineModuleMap& modules, const char* binaryName, const char* title) : + allModules_(modules), + binaryName_(binaryName), + title_(title) + { + } + + //! Returns the title for the group. + const char* title() const { return title_; } + //! Returns the list of modules in the group. + const ModuleList& modules() const { return modules_; } + + /*! \brief + * Adds a module to the group. + * + * \param[in] name Name of the module. + * \param[in] description Description of the module in this group. + * \throws std::bad_alloc if out of memory. + * + * If \p description is NULL, the description returned by the module is + * used. + */ + void addModule(const char* name, const char* description); + +private: + const CommandLineModuleMap& allModules_; + const char* binaryName_; + const char* title_; + ModuleList modules_; + + GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineModuleGroupData); }; //! Smart pointer type for managing a CommandLineModuleGroup. -typedef std::unique_ptr - CommandLineModuleGroupDataPointer; +typedef std::unique_ptr CommandLineModuleGroupDataPointer; //! Container type for keeping a list of module groups. -typedef std::vector - CommandLineModuleGroupList; +typedef std::vector CommandLineModuleGroupList; /*! \internal * \brief @@ -139,77 +137,68 @@ typedef std::vector */ class CommandLineCommonOptionsHolder { - public: - CommandLineCommonOptionsHolder(); - ~CommandLineCommonOptionsHolder(); - - //! Initializes the common options. - void initOptions(); - /*! \brief - * Finishes option parsing. - * - * \returns `false` if the wrapper binary should quit without executing - * any module. - */ - bool finishOptions(); - - //! Adjust defaults based on module settings. - void adjustFromSettings(const CommandLineModuleSettings &settings); - - //! Returns the internal Options object. - Options *options() { return &options_; } - //! Returns the settings for printing startup information. - const BinaryInformationSettings &binaryInfoSettings() const - { - return binaryInfoSettings_; - } - - /*! \brief - * Returns `true` if common options are set such that the wrapper - * binary should quit, without running the actual module. - */ - bool shouldIgnoreActualModule() const - { - return bHelp_ || bVersion_; - } - //! Returns whether common options specify showing help. - bool shouldShowHelp() const { return bHelp_; } - //! Returns whether common options specify showing hidden options in help. - bool shouldShowHidden() const { return bHidden_; } - //! Returns whether common options specify quiet execution. - bool shouldBeQuiet() const - { - return bQuiet_ && !bVersion_; - } - //! Returns whether backups should be made. - bool shouldBackup() const { return bBackup_; } - - //! Returns the nice level. - int niceLevel() const { return niceLevel_; } - //! Returns whether floating-point exception should be enabled - bool enableFPExceptions() const { return bFpexcept_; } - //! Returns the debug level. - int debugLevel() const { return debugLevel_; } - - //! Returns the file to which startup information should be printed. - FILE *startupInfoFile() const { return (bVersion_ ? stdout : stderr); } - - private: - Options options_; - //! Settings for what to write in the startup header. - BinaryInformationSettings binaryInfoSettings_; - bool bHelp_; - bool bHidden_; - bool bQuiet_; - bool bVersion_; - bool bCopyright_; - int niceLevel_; - bool bNiceSet_; - bool bBackup_; - bool bFpexcept_; - int debugLevel_; - - GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineCommonOptionsHolder); +public: + CommandLineCommonOptionsHolder(); + ~CommandLineCommonOptionsHolder(); + + //! Initializes the common options. + void initOptions(); + /*! \brief + * Finishes option parsing. + * + * \returns `false` if the wrapper binary should quit without executing + * any module. + */ + bool finishOptions(); + + //! Adjust defaults based on module settings. + void adjustFromSettings(const CommandLineModuleSettings& settings); + + //! Returns the internal Options object. + Options* options() { return &options_; } + //! Returns the settings for printing startup information. + const BinaryInformationSettings& binaryInfoSettings() const { return binaryInfoSettings_; } + + /*! \brief + * Returns `true` if common options are set such that the wrapper + * binary should quit, without running the actual module. + */ + bool shouldIgnoreActualModule() const { return bHelp_ || bVersion_; } + //! Returns whether common options specify showing help. + bool shouldShowHelp() const { return bHelp_; } + //! Returns whether common options specify showing hidden options in help. + bool shouldShowHidden() const { return bHidden_; } + //! Returns whether common options specify quiet execution. + bool shouldBeQuiet() const { return bQuiet_ && !bVersion_; } + //! Returns whether backups should be made. + bool shouldBackup() const { return bBackup_; } + + //! Returns the nice level. + int niceLevel() const { return niceLevel_; } + //! Returns whether floating-point exception should be enabled + bool enableFPExceptions() const { return bFpexcept_; } + //! Returns the debug level. + int debugLevel() const { return debugLevel_; } + + //! Returns the file to which startup information should be printed. + FILE* startupInfoFile() const { return (bVersion_ ? stdout : stderr); } + +private: + Options options_; + //! Settings for what to write in the startup header. + BinaryInformationSettings binaryInfoSettings_; + bool bHelp_; + bool bHidden_; + bool bQuiet_; + bool bVersion_; + bool bCopyright_; + int niceLevel_; + bool bNiceSet_; + bool bBackup_; + bool bFpexcept_; + int debugLevel_; + + GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineCommonOptionsHolder); }; //! \} diff --git a/src/gromacs/commandline/cmdlineoptionsmodule.cpp b/src/gromacs/commandline/cmdlineoptionsmodule.cpp index dc842307e9..f49763e075 100644 --- a/src/gromacs/commandline/cmdlineoptionsmodule.cpp +++ b/src/gromacs/commandline/cmdlineoptionsmodule.cpp @@ -69,35 +69,34 @@ namespace class CommandLineOptionsModuleSettings : public ICommandLineOptionsModuleSettings { - public: - explicit CommandLineOptionsModuleSettings( - OptionsBehaviorCollection *behaviors) - : behaviors_(*behaviors) - { - } - - const std::string &helpText() const { return helpText_; } - - ArrayRef bugText() const { return bugText_; } - - void setHelpText(const ArrayRef &help) override - { - helpText_ = joinStrings(help, "\n"); - } - - void setBugText(const ArrayRef &bug) override - { - bugText_ = std::vector(bug.begin(), bug.end()); - } - void addOptionsBehavior(const OptionsBehaviorPointer &behavior) override - { - behaviors_.addBehavior(behavior); - } - - private: - std::string helpText_; - std::vector bugText_; - OptionsBehaviorCollection &behaviors_; +public: + explicit CommandLineOptionsModuleSettings(OptionsBehaviorCollection* behaviors) : + behaviors_(*behaviors) + { + } + + const std::string& helpText() const { return helpText_; } + + ArrayRef bugText() const { return bugText_; } + + void setHelpText(const ArrayRef& help) override + { + helpText_ = joinStrings(help, "\n"); + } + + void setBugText(const ArrayRef& bug) override + { + bugText_ = std::vector(bug.begin(), bug.end()); + } + void addOptionsBehavior(const OptionsBehaviorPointer& behavior) override + { + behaviors_.addBehavior(behavior); + } + +private: + std::string helpText_; + std::vector bugText_; + OptionsBehaviorCollection& behaviors_; }; /******************************************************************** @@ -106,37 +105,39 @@ class CommandLineOptionsModuleSettings : public ICommandLineOptionsModuleSetting class CommandLineOptionsModule : public ICommandLineModule { - public: - //! Shorthand for the factory function pointer type. - typedef ICommandLineOptionsModule::FactoryMethod FactoryMethod; - - CommandLineOptionsModule(const char *name, const char *description, - FactoryMethod factory) - : name_(name), description_(description), factory_(std::move(factory)) - { - } - CommandLineOptionsModule(const char *name, const char *description, - ICommandLineOptionsModulePointer module) - : name_(name), description_(description), module_(std::move(module)) - { - } - const char *name() const override { return name_; } - const char *shortDescription() const override { return description_; } - - void init(CommandLineModuleSettings *settings) override; - int run(int argc, char *argv[]) override; - void writeHelp(const CommandLineHelpContext &context) const override; - - private: - void parseOptions(int argc, char *argv[]); - - const char *name_; - const char *description_; - FactoryMethod factory_; - ICommandLineOptionsModulePointer module_; +public: + //! Shorthand for the factory function pointer type. + typedef ICommandLineOptionsModule::FactoryMethod FactoryMethod; + + CommandLineOptionsModule(const char* name, const char* description, FactoryMethod factory) : + name_(name), + description_(description), + factory_(std::move(factory)) + { + } + CommandLineOptionsModule(const char* name, const char* description, ICommandLineOptionsModulePointer module) : + name_(name), + description_(description), + module_(std::move(module)) + { + } + const char* name() const override { return name_; } + const char* shortDescription() const override { return description_; } + + void init(CommandLineModuleSettings* settings) override; + int run(int argc, char* argv[]) override; + void writeHelp(const CommandLineHelpContext& context) const override; + +private: + void parseOptions(int argc, char* argv[]); + + const char* name_; + const char* description_; + FactoryMethod factory_; + ICommandLineOptionsModulePointer module_; }; -void CommandLineOptionsModule::init(CommandLineModuleSettings *settings) +void CommandLineOptionsModule::init(CommandLineModuleSettings* settings) { if (!module_) { @@ -146,17 +147,17 @@ void CommandLineOptionsModule::init(CommandLineModuleSettings *settings) module_->init(settings); } -int CommandLineOptionsModule::run(int argc, char *argv[]) +int CommandLineOptionsModule::run(int argc, char* argv[]) { GMX_RELEASE_ASSERT(module_, "init() has not been called"); parseOptions(argc, argv); return module_->run(); } -void CommandLineOptionsModule::writeHelp(const CommandLineHelpContext &context) const +void CommandLineOptionsModule::writeHelp(const CommandLineHelpContext& context) const { - ICommandLineOptionsModulePointer moduleGuard; - ICommandLineOptionsModule *module = module_.get(); + ICommandLineOptionsModulePointer moduleGuard; + ICommandLineOptionsModule* module = module_.get(); if (!module) { GMX_RELEASE_ASSERT(factory_ != nullptr, "Neither factory nor module provided"); @@ -168,12 +169,12 @@ void CommandLineOptionsModule::writeHelp(const CommandLineHelpContext &context) CommandLineOptionsModuleSettings settings(&behaviors); module->initOptions(&options, &settings); CommandLineHelpWriter(options) - .setHelpText(settings.helpText()) - .setKnownIssues(settings.bugText()) - .writeHelp(context); + .setHelpText(settings.helpText()) + .setKnownIssues(settings.bugText()) + .writeHelp(context); } -void CommandLineOptionsModule::parseOptions(int argc, char *argv[]) +void CommandLineOptionsModule::parseOptions(int argc, char* argv[]) { FileNameOptionManager fileoptManager; Options options; @@ -193,60 +194,57 @@ void CommandLineOptionsModule::parseOptions(int argc, char *argv[]) behaviors.optionsFinished(); } -} // namespace +} // namespace /******************************************************************** * ICommandLineOptionsModuleSettings */ -ICommandLineOptionsModuleSettings::~ICommandLineOptionsModuleSettings() -{ -} +ICommandLineOptionsModuleSettings::~ICommandLineOptionsModuleSettings() {} /******************************************************************** * ICommandLineOptionsModule */ -ICommandLineOptionsModule::~ICommandLineOptionsModule() -{ -} +ICommandLineOptionsModule::~ICommandLineOptionsModule() {} // static -std::unique_ptr -ICommandLineOptionsModule::createModule( - const char *name, const char *description, - ICommandLineOptionsModulePointer module) +std::unique_ptr ICommandLineOptionsModule::createModule(const char* name, + const char* description, + ICommandLineOptionsModulePointer module) { return std::unique_ptr( new CommandLineOptionsModule(name, description, std::move(module))); } // static -int ICommandLineOptionsModule::runAsMain( - int argc, char *argv[], const char *name, const char *description, - FactoryMethod factory) +int ICommandLineOptionsModule::runAsMain(int argc, + char* argv[], + const char* name, + const char* description, + FactoryMethod factory) { CommandLineOptionsModule module(name, description, std::move(factory)); return CommandLineModuleManager::runAsMainSingleModule(argc, argv, &module); } // static -void ICommandLineOptionsModule::registerModuleFactory( - CommandLineModuleManager *manager, const char *name, - const char *description, FactoryMethod factory) +void ICommandLineOptionsModule::registerModuleFactory(CommandLineModuleManager* manager, + const char* name, + const char* description, + FactoryMethod factory) { - CommandLineModulePointer module( - new CommandLineOptionsModule(name, description, std::move(factory))); + CommandLineModulePointer module(new CommandLineOptionsModule(name, description, std::move(factory))); manager->addModule(std::move(module)); } // static -void ICommandLineOptionsModule::registerModuleDirect( - CommandLineModuleManager *manager, const char *name, - const char *description, ICommandLineOptionsModulePointer module) +void ICommandLineOptionsModule::registerModuleDirect(CommandLineModuleManager* manager, + const char* name, + const char* description, + ICommandLineOptionsModulePointer module) { - CommandLineModulePointer wrapperModule( - createModule(name, description, std::move(module))); + CommandLineModulePointer wrapperModule(createModule(name, description, std::move(module))); manager->addModule(std::move(wrapperModule)); } diff --git a/src/gromacs/commandline/cmdlineoptionsmodule.h b/src/gromacs/commandline/cmdlineoptionsmodule.h index e772bb0d7e..e22f6ca3ba 100644 --- a/src/gromacs/commandline/cmdlineoptionsmodule.h +++ b/src/gromacs/commandline/cmdlineoptionsmodule.h @@ -51,7 +51,8 @@ namespace gmx { -template class ArrayRef; +template +class ArrayRef; class CommandLineModuleManager; class ICommandLineModule; @@ -60,8 +61,7 @@ class IOptionsBehavior; class IOptionsContainer; //! Smart pointer to manage an ICommandLineOptionsModule. -typedef std::unique_ptr - ICommandLineOptionsModulePointer; +typedef std::unique_ptr ICommandLineOptionsModulePointer; /*! \brief * Settings to pass information between a CommandLineOptionsModule and generic @@ -72,50 +72,49 @@ typedef std::unique_ptr */ class ICommandLineOptionsModuleSettings { - public: - /*! \brief - * Sets the help text for the module from string array. - * - * \param[in] help String array to set as the description. - * \throws std::bad_alloc if out of memory. - * - * Formatting for the help text is described on \ref page_onlinehelp. - * - * Example usage: - * \code - const char *const desc[] = { - "This is the description", - "for the options" - }; +public: + /*! \brief + * Sets the help text for the module from string array. + * + * \param[in] help String array to set as the description. + * \throws std::bad_alloc if out of memory. + * + * Formatting for the help text is described on \ref page_onlinehelp. + * + * Example usage: + * \code + const char *const desc[] = { + "This is the description", + "for the options" + }; - settings->setHelpText(desc); - \endcode - */ - virtual void setHelpText(const ArrayRef &help) = 0; - /*! \brief - * Set text indicating buggy behaviour of a module from string array. - * - * \param[in] bug String array to set as the bug text. - * \throws std::bad_alloc if out of memory. - * - * Formatting for the text is described on \ref page_onlinehelp. - */ - virtual void setBugText(const ArrayRef &bug) = 0; - /*! \brief - * Adds an option behavior that performs actions before - * ICommandLineOptionsModule::run() is called. - * - * For now, this takes a shared_ptr to make it easier for the caller to - * keep a reference to the behavior, but the behavior should be treated - * as owned by the options module after this call. - */ - virtual void addOptionsBehavior( - const std::shared_ptr &behavior) = 0; + settings->setHelpText(desc); + \endcode + */ + virtual void setHelpText(const ArrayRef& help) = 0; + /*! \brief + * Set text indicating buggy behaviour of a module from string array. + * + * \param[in] bug String array to set as the bug text. + * \throws std::bad_alloc if out of memory. + * + * Formatting for the text is described on \ref page_onlinehelp. + */ + virtual void setBugText(const ArrayRef& bug) = 0; + /*! \brief + * Adds an option behavior that performs actions before + * ICommandLineOptionsModule::run() is called. + * + * For now, this takes a shared_ptr to make it easier for the caller to + * keep a reference to the behavior, but the behavior should be treated + * as owned by the options module after this call. + */ + virtual void addOptionsBehavior(const std::shared_ptr& behavior) = 0; - protected: - // Disallow deletion through the interface. - // (no need for the virtual, but some compilers warn otherwise) - virtual ~ICommandLineOptionsModuleSettings(); +protected: + // Disallow deletion through the interface. + // (no need for the virtual, but some compilers warn otherwise) + virtual ~ICommandLineOptionsModuleSettings(); }; /*! \brief @@ -152,126 +151,123 @@ class ICommandLineOptionsModuleSettings */ class ICommandLineOptionsModule { - public: - /*! \brief - * Function pointer to a factory method that returns an interface of - * this type. - * - * \returns Module to run. - * \throws std::bad_alloc if out of memory. - */ - typedef std::function FactoryMethod; +public: + /*! \brief + * Function pointer to a factory method that returns an interface of + * this type. + * + * \returns Module to run. + * \throws std::bad_alloc if out of memory. + */ + typedef std::function FactoryMethod; - /*! \brief - * Creates a ICommandLineModule to run the specified module. - * - * \param[in] name Name for the module. - * \param[in] description Short description for the module. - * \param[in] module Module to run. - * \returns ICommandLineModule object that runs \p module module. - * \throws std::bad_alloc if out of memory. - */ - static std::unique_ptr - createModule(const char *name, const char *description, - ICommandLineOptionsModulePointer module); - /*! \brief - * Implements a main() method that runs a single module. - * - * \param argc \c argc passed to main(). - * \param argv \c argv passed to main(). - * \param[in] name Name for the module. - * \param[in] description Short description for the module. - * \param[in] factory Factory that returns the module to run. - * - * This method allows for uniform behavior for binaries that only - * contain a single module without duplicating any of the - * implementation from CommandLineModuleManager (startup headers, - * common options etc.). - * - * \see runCommandLineModule() - */ - static int - runAsMain(int argc, char *argv[], const char *name, - const char *description, FactoryMethod factory); - /*! \brief - * Registers a module of a certain type to this manager. - * - * \param manager Manager to register to. - * \param[in] name Name for the module. - * \param[in] description Short description for the module. - * \param[in] factory Factory that returns the module to register. - * \throws std::bad_alloc if out of memory. - * - * This method internally creates a ICommandLineModule module - * with the given \p name and \p description, and adds that to - * \p manager. When run or asked to write the help, the module calls - * \p factory to get the actual module, and forwards the necessary - * calls. - */ - static void - registerModuleFactory(CommandLineModuleManager *manager, - const char *name, const char *description, - FactoryMethod factory); - /*! \brief - * Registers a module to this manager. - * - * \param manager Manager to register to. - * \param[in] name Name for the module. - * \param[in] description Short description for the module. - * \param[in] module Module to register. - * \throws std::bad_alloc if out of memory. - * - * This method internally creates a ICommandLineModule module - * with the given \p name and \p description, and adds that to - * \p manager. - * - * This method is mainly used by tests that need to have a reference to - * the ICommandLineOptionsModule instance (e.g., for mocking). - */ - static void - registerModuleDirect(CommandLineModuleManager *manager, - const char *name, const char *description, - ICommandLineOptionsModulePointer module); + /*! \brief + * Creates a ICommandLineModule to run the specified module. + * + * \param[in] name Name for the module. + * \param[in] description Short description for the module. + * \param[in] module Module to run. + * \returns ICommandLineModule object that runs \p module module. + * \throws std::bad_alloc if out of memory. + */ + static std::unique_ptr createModule(const char* name, + const char* description, + ICommandLineOptionsModulePointer module); + /*! \brief + * Implements a main() method that runs a single module. + * + * \param argc \c argc passed to main(). + * \param argv \c argv passed to main(). + * \param[in] name Name for the module. + * \param[in] description Short description for the module. + * \param[in] factory Factory that returns the module to run. + * + * This method allows for uniform behavior for binaries that only + * contain a single module without duplicating any of the + * implementation from CommandLineModuleManager (startup headers, + * common options etc.). + * + * \see runCommandLineModule() + */ + static int runAsMain(int argc, char* argv[], const char* name, const char* description, FactoryMethod factory); + /*! \brief + * Registers a module of a certain type to this manager. + * + * \param manager Manager to register to. + * \param[in] name Name for the module. + * \param[in] description Short description for the module. + * \param[in] factory Factory that returns the module to register. + * \throws std::bad_alloc if out of memory. + * + * This method internally creates a ICommandLineModule module + * with the given \p name and \p description, and adds that to + * \p manager. When run or asked to write the help, the module calls + * \p factory to get the actual module, and forwards the necessary + * calls. + */ + static void registerModuleFactory(CommandLineModuleManager* manager, + const char* name, + const char* description, + FactoryMethod factory); + /*! \brief + * Registers a module to this manager. + * + * \param manager Manager to register to. + * \param[in] name Name for the module. + * \param[in] description Short description for the module. + * \param[in] module Module to register. + * \throws std::bad_alloc if out of memory. + * + * This method internally creates a ICommandLineModule module + * with the given \p name and \p description, and adds that to + * \p manager. + * + * This method is mainly used by tests that need to have a reference to + * the ICommandLineOptionsModule instance (e.g., for mocking). + */ + static void registerModuleDirect(CommandLineModuleManager* manager, + const char* name, + const char* description, + ICommandLineOptionsModulePointer module); - virtual ~ICommandLineOptionsModule(); + virtual ~ICommandLineOptionsModule(); - //! \copydoc gmx::ICommandLineModule::init() - virtual void init(CommandLineModuleSettings *settings) = 0; - /*! \brief - * Initializes command-line arguments understood by the module. - * - * \param[in,out] options Options object to add the options to. - * \param[in,out] settings Settings to communicate information - * to/from generic code running the module. - * - * When running the module, this method is called after init(). - * When printing help, there is no call to init(), and this is the only - * method called. - * In both cases, the implementation should add options understood by - * the module to \p options. Output values from options should be - * stored in member variables. - */ - virtual void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) = 0; - /*! \brief - * Called after all option values have been set. - * - * When running the module, this method is called after all - * command-line arguments have been parsed. - */ - virtual void optionsFinished() = 0; + //! \copydoc gmx::ICommandLineModule::init() + virtual void init(CommandLineModuleSettings* settings) = 0; + /*! \brief + * Initializes command-line arguments understood by the module. + * + * \param[in,out] options Options object to add the options to. + * \param[in,out] settings Settings to communicate information + * to/from generic code running the module. + * + * When running the module, this method is called after init(). + * When printing help, there is no call to init(), and this is the only + * method called. + * In both cases, the implementation should add options understood by + * the module to \p options. Output values from options should be + * stored in member variables. + */ + virtual void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) = 0; + /*! \brief + * Called after all option values have been set. + * + * When running the module, this method is called after all + * command-line arguments have been parsed. + */ + virtual void optionsFinished() = 0; - /*! \brief - * Runs the module. - * - * \throws unspecified May throw exceptions to indicate errors. - * \returns Exit code for the program. - * \retval 0 on successful termination. - * - * This method is called after optionsFinished() when running the - * module, and should do all the processing for the module. - */ - virtual int run() = 0; + /*! \brief + * Runs the module. + * + * \throws unspecified May throw exceptions to indicate errors. + * \returns Exit code for the program. + * \retval 0 on successful termination. + * + * This method is called after optionsFinished() when running the + * module, and should do all the processing for the module. + */ + virtual int run() = 0; }; } // namespace gmx diff --git a/src/gromacs/commandline/cmdlineparser.cpp b/src/gromacs/commandline/cmdlineparser.cpp index b3902c00e3..8f5b50e798 100644 --- a/src/gromacs/commandline/cmdlineparser.cpp +++ b/src/gromacs/commandline/cmdlineparser.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,38 +67,40 @@ namespace gmx */ class CommandLineParser::Impl { - public: - //! Sets the options object to parse to. - explicit Impl(Options *options); +public: + //! Sets the options object to parse to. + explicit Impl(Options* options); - /*! \brief - * Determines whether a cmdline parameter starts an option and the name - * of that option. - * - * \param[in] arg Individual argument from \c argv. - * \returns The beginning of the option name in \p arg, or NULL if - * \p arg does not look like an option. - */ - const char *toOptionName(const char *arg) const; + /*! \brief + * Determines whether a cmdline parameter starts an option and the name + * of that option. + * + * \param[in] arg Individual argument from \c argv. + * \returns The beginning of the option name in \p arg, or NULL if + * \p arg does not look like an option. + */ + const char* toOptionName(const char* arg) const; - //! Helper object for assigning the options. - OptionsAssigner assigner_; - //! Whether to allow and skip unknown options. - bool bSkipUnknown_; - /*! \brief Whether to allow positional arguments - * - * These are not options (no leading hyphen), and come before - * all options. */ - bool bAllowPositionalArguments_; + //! Helper object for assigning the options. + OptionsAssigner assigner_; + //! Whether to allow and skip unknown options. + bool bSkipUnknown_; + /*! \brief Whether to allow positional arguments + * + * These are not options (no leading hyphen), and come before + * all options. */ + bool bAllowPositionalArguments_; }; -CommandLineParser::Impl::Impl(Options *options) - : assigner_(options), bSkipUnknown_(false), bAllowPositionalArguments_(false) +CommandLineParser::Impl::Impl(Options* options) : + assigner_(options), + bSkipUnknown_(false), + bAllowPositionalArguments_(false) { assigner_.setAcceptBooleanNoPrefix(true); } -const char *CommandLineParser::Impl::toOptionName(const char *arg) const +const char* CommandLineParser::Impl::toOptionName(const char* arg) const { // Lone '-' or '--' is not an option. if (arg[0] != '-' || arg[1] == '\0' || (arg[1] == '-' && arg[2] == '\0')) @@ -110,7 +113,7 @@ const char *CommandLineParser::Impl::toOptionName(const char *arg) const return arg + 2; } // Don't return numbers as option names. - char *endptr; + char* endptr; // We are only interested in endptr, not in the actual value. GMX_IGNORE_RETURN_VALUE(std::strtod(arg, &endptr)); if (*endptr == '\0') @@ -124,28 +127,23 @@ const char *CommandLineParser::Impl::toOptionName(const char *arg) const * CommandLineParser */ -CommandLineParser::CommandLineParser(Options *options) - : impl_(new Impl(options)) -{ -} +CommandLineParser::CommandLineParser(Options* options) : impl_(new Impl(options)) {} -CommandLineParser::~CommandLineParser() -{ -} +CommandLineParser::~CommandLineParser() {} -CommandLineParser &CommandLineParser::skipUnknown(bool bEnabled) +CommandLineParser& CommandLineParser::skipUnknown(bool bEnabled) { impl_->bSkipUnknown_ = bEnabled; return *this; } -CommandLineParser &CommandLineParser::allowPositionalArguments(bool bEnabled) +CommandLineParser& CommandLineParser::allowPositionalArguments(bool bEnabled) { impl_->bAllowPositionalArguments_ = bEnabled; return *this; } -void CommandLineParser::parse(int *argc, char *argv[]) +void CommandLineParser::parse(int* argc, char* argv[]) { ExceptionInitializer errors("Invalid command-line options"); std::string currentContext; @@ -160,7 +158,7 @@ void CommandLineParser::parse(int *argc, char *argv[]) // First, process any permitted leading positional arguments. for (; i < *argc; ++i) { - const char *const arg = argv[i]; + const char* const arg = argv[i]; if (impl_->toOptionName(arg) != nullptr) { // If we find an option, no more positional arguments @@ -170,9 +168,11 @@ void CommandLineParser::parse(int *argc, char *argv[]) if (!impl_->bAllowPositionalArguments_) { - GMX_THROW(InvalidInputError - ("Positional argument '" + std::string(arg) + "' cannot be accepted. " - "Perhaps you forgot to put a hyphen before an option name.")); + GMX_THROW( + InvalidInputError( + "Positional argument '" + std::string(arg) + + "' cannot be accepted. " + "Perhaps you forgot to put a hyphen before an option name.")); } // argv[i] is not an option, so preserve it in the argument list // by incrementing newi. There's no need to copy argv contents @@ -184,8 +184,8 @@ void CommandLineParser::parse(int *argc, char *argv[]) impl_->assigner_.start(); for (; i < *argc; ++i) { - const char *const arg = argv[i]; - const char *const optionName = impl_->toOptionName(arg); + const char* const arg = argv[i]; + const char* const optionName = impl_->toOptionName(arg); if (optionName != nullptr) { if (bInOption) @@ -194,7 +194,7 @@ void CommandLineParser::parse(int *argc, char *argv[]) { impl_->assigner_.finishOption(); } - catch (UserInputError &ex) + catch (UserInputError& ex) { ex.prependContext(currentContext); errors.addCurrentExceptionAsNested(); @@ -209,13 +209,12 @@ void CommandLineParser::parse(int *argc, char *argv[]) currentContext.clear(); if (!impl_->bSkipUnknown_) { - std::string message = - "Unknown command-line option " + std::string(arg); + std::string message = "Unknown command-line option " + std::string(arg); GMX_THROW(InvalidInputError(message)); } } } - catch (UserInputError &ex) + catch (UserInputError& ex) { // If tryStartOption() throws, make sure that the rest gets // ignored. @@ -236,7 +235,7 @@ void CommandLineParser::parse(int *argc, char *argv[]) } // TODO: Consider if some types of exceptions would be better left // unhandled. - catch (GromacsException &ex) + catch (GromacsException& ex) { ex.prependContext(currentContext); errors.addCurrentExceptionAsNested(); @@ -263,7 +262,7 @@ void CommandLineParser::parse(int *argc, char *argv[]) { impl_->assigner_.finishOption(); } - catch (UserInputError &ex) + catch (UserInputError& ex) { ex.prependContext(currentContext); errors.addCurrentExceptionAsNested(); diff --git a/src/gromacs/commandline/cmdlineparser.h b/src/gromacs/commandline/cmdlineparser.h index 3f6f15b9e5..171e2f2b49 100644 --- a/src/gromacs/commandline/cmdlineparser.h +++ b/src/gromacs/commandline/cmdlineparser.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,79 +70,79 @@ class Options; */ class CommandLineParser { - public: - /*! \brief - * Creates a command-line parser that sets values for options. - * - * \param[in] options Options object whose options should be set. - * \throws std::bad_alloc if out of memory. - */ - explicit CommandLineParser(Options *options); - ~CommandLineParser(); +public: + /*! \brief + * Creates a command-line parser that sets values for options. + * + * \param[in] options Options object whose options should be set. + * \throws std::bad_alloc if out of memory. + */ + explicit CommandLineParser(Options* options); + ~CommandLineParser(); - /*! \brief - * Makes the parser skip unknown options and keep them in \c argv. - * - * \param[in] bEnabled Whether to skip and keep unknown options. - * \returns *this - * - * Setting this option to true has dual effect: unknown options are - * silently skipped, and all recognized options are removed from - * \c argc and \c argv in parse(). These effects should be easy to - * separate into different flags if there is need for it. - * - * The default is false: unknown options result in exceptions and - * \c argc and \c argv are not modified. - * - * Does not throw. - */ - CommandLineParser &skipUnknown(bool bEnabled); + /*! \brief + * Makes the parser skip unknown options and keep them in \c argv. + * + * \param[in] bEnabled Whether to skip and keep unknown options. + * \returns *this + * + * Setting this option to true has dual effect: unknown options are + * silently skipped, and all recognized options are removed from + * \c argc and \c argv in parse(). These effects should be easy to + * separate into different flags if there is need for it. + * + * The default is false: unknown options result in exceptions and + * \c argc and \c argv are not modified. + * + * Does not throw. + */ + CommandLineParser& skipUnknown(bool bEnabled); - /*! \brief - * Makes the parser accept positional arguments - * - * \param[in] bEnabled Whether to skip and keep positional arguments. - * \returns *this - * - * Arguments that are not options (ie. no leading hyphen), and - * which come before all options are acceptable if this has - * been enabled. If so, these arguments are left in \c argc - * and \c argv in parse(). - * - * The default is false: unknown leading arguments result in - * exceptions and \c argc and \c argv are not modified. - * - * Does not throw. - */ - CommandLineParser &allowPositionalArguments(bool bEnabled); + /*! \brief + * Makes the parser accept positional arguments + * + * \param[in] bEnabled Whether to skip and keep positional arguments. + * \returns *this + * + * Arguments that are not options (ie. no leading hyphen), and + * which come before all options are acceptable if this has + * been enabled. If so, these arguments are left in \c argc + * and \c argv in parse(). + * + * The default is false: unknown leading arguments result in + * exceptions and \c argc and \c argv are not modified. + * + * Does not throw. + */ + CommandLineParser& allowPositionalArguments(bool bEnabled); - /*! \brief - * Parses the command line. - * - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if any errors were detected in the input. - * - * All command-line arguments are parsed, and an aggregate - * exception with all the detected errors (including unknown - * options, where applicable) is thrown in the end. - * - * If skipUnknown() was not called, or last called with a - * false value, the input arguments are not modified. If - * skipUnknown() was last called with a true value, only - * unknown options will be retained in \c argc and \c argv. - * - * All positional arguments are retained in the argument list, - * but such arguments must precede all options. - * - * \c argv[0] is never modified. - * - */ - void parse(int *argc, char *argv[]); + /*! \brief + * Parses the command line. + * + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if any errors were detected in the input. + * + * All command-line arguments are parsed, and an aggregate + * exception with all the detected errors (including unknown + * options, where applicable) is thrown in the end. + * + * If skipUnknown() was not called, or last called with a + * false value, the input arguments are not modified. If + * skipUnknown() was last called with a true value, only + * unknown options will be retained in \c argc and \c argv. + * + * All positional arguments are retained in the argument list, + * but such arguments must precede all options. + * + * \c argv[0] is never modified. + * + */ + void parse(int* argc, char* argv[]); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/commandline/cmdlineprogramcontext.cpp b/src/gromacs/commandline/cmdlineprogramcontext.cpp index f6dcffb3af..14a70beda1 100644 --- a/src/gromacs/commandline/cmdlineprogramcontext.cpp +++ b/src/gromacs/commandline/cmdlineprogramcontext.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,7 +73,7 @@ namespace /*! \brief * Quotes a string if it contains spaces. */ -std::string quoteIfNecessary(const char *str) +std::string quoteIfNecessary(const char* str) { const bool bSpaces = (std::strchr(str, ' ') != nullptr); if (bSpaces) @@ -91,29 +91,23 @@ std::string quoteIfNecessary(const char *str) */ class DefaultExecutableEnvironment : public IExecutableEnvironment { - public: - //! Allocates a default environment. - static ExecutableEnvironmentPointer create() - { - return ExecutableEnvironmentPointer(new DefaultExecutableEnvironment()); - } +public: + //! Allocates a default environment. + static ExecutableEnvironmentPointer create() + { + return ExecutableEnvironmentPointer(new DefaultExecutableEnvironment()); + } - DefaultExecutableEnvironment() - : initialWorkingDirectory_(Path::getWorkingDirectory()) - { - } + DefaultExecutableEnvironment() : initialWorkingDirectory_(Path::getWorkingDirectory()) {} - std::string getWorkingDirectory() const override - { - return initialWorkingDirectory_; - } - std::vector getExecutablePaths() const override - { - return Path::getExecutablePaths(); - } + std::string getWorkingDirectory() const override { return initialWorkingDirectory_; } + std::vector getExecutablePaths() const override + { + return Path::getExecutablePaths(); + } - private: - std::string initialWorkingDirectory_; +private: + std::string initialWorkingDirectory_; }; /*! \brief @@ -126,8 +120,7 @@ class DefaultExecutableEnvironment : public IExecutableEnvironment * If a binary with the given name cannot be located, \p invokedName is * returned. */ -std::string findFullBinaryPath(const std::string &invokedName, - const IExecutableEnvironment &env) +std::string findFullBinaryPath(const std::string& invokedName, const IExecutableEnvironment& env) { std::string searchName = invokedName; // On Windows & Cygwin we need to add the .exe extension, @@ -145,7 +138,7 @@ std::string findFullBinaryPath(const std::string &invokedName, std::vector::const_iterator i; for (i = pathEntries.begin(); i != pathEntries.end(); ++i) { - const std::string &dir = i->empty() ? env.getWorkingDirectory() : *i; + const std::string& dir = i->empty() ? env.getWorkingDirectory() : *i; std::string testPath = Path::join(dir, searchName); if (File::exists(testPath, File::returnFalseOnError)) { @@ -169,7 +162,7 @@ std::string findFullBinaryPath(const std::string &invokedName, * * Only checks for a single file that has an uncommon enough name. */ -bool isAcceptableLibraryPath(const std::string &path) +bool isAcceptableLibraryPath(const std::string& path) { return Path::exists(Path::join(path, "residuetypes.dat")); } @@ -184,7 +177,7 @@ bool isAcceptableLibraryPath(const std::string &path) * files have been installed: appends the relative installation path of the * data files and calls isAcceptableLibraryPath(). */ -bool isAcceptableLibraryPathPrefix(const std::string &path) +bool isAcceptableLibraryPathPrefix(const std::string& path) { std::string testPath = Path::join(path, GMX_INSTALL_GMXDATADIR, "top"); return isAcceptableLibraryPath(testPath); @@ -235,8 +228,7 @@ std::string findFallbackInstallationPrefixPath() * Extra logic is present to allow running binaries from the build tree such * that they use up-to-date data files from the source tree. */ -std::string findInstallationPrefixPath(const std::string &binaryPath, - bool *bSourceLayout) +std::string findInstallationPrefixPath(const std::string& binaryPath, bool* bSourceLayout) { *bSourceLayout = false; // Don't search anything if binary cannot be found. @@ -248,11 +240,11 @@ std::string findInstallationPrefixPath(const std::string &binaryPath, // directory. #if (defined CMAKE_SOURCE_DIR && defined CMAKE_BINARY_DIR) std::string buildBinPath; -#ifdef CMAKE_INTDIR /*In multi-configuration build systems the output subdirectory*/ +# ifdef CMAKE_INTDIR /*In multi-configuration build systems the output subdirectory*/ buildBinPath = Path::join(CMAKE_BINARY_DIR, "bin", CMAKE_INTDIR); -#else +# else buildBinPath = Path::join(CMAKE_BINARY_DIR, "bin"); -#endif +# endif if (Path::isEquivalent(searchPath, buildBinPath)) { std::string testPath = Path::join(CMAKE_SOURCE_DIR, "share/top"); @@ -283,7 +275,7 @@ std::string findInstallationPrefixPath(const std::string &binaryPath, //! \} -} // namespace +} // namespace /******************************************************************** * CommandLineProgramContext::Impl @@ -291,40 +283,37 @@ std::string findInstallationPrefixPath(const std::string &binaryPath, class CommandLineProgramContext::Impl { - public: - Impl(); - Impl(int argc, const char *const argv[], - ExecutableEnvironmentPointer env); - - /*! \brief - * Finds the full binary path if it isn't searched yet. - * - * Sets \a fullBinaryPath_ if it isn't set yet. - * - * The \a binaryPathMutex_ should be locked by the caller before - * calling this function. - */ - void findBinaryPath() const; - - ExecutableEnvironmentPointer executableEnv_; - std::string invokedName_; - std::string programName_; - std::string displayName_; - std::string commandLine_; - mutable std::string fullBinaryPath_; - mutable std::string installationPrefix_; - mutable bool bSourceLayout_; - mutable Mutex binaryPathMutex_; +public: + Impl(); + Impl(int argc, const char* const argv[], ExecutableEnvironmentPointer env); + + /*! \brief + * Finds the full binary path if it isn't searched yet. + * + * Sets \a fullBinaryPath_ if it isn't set yet. + * + * The \a binaryPathMutex_ should be locked by the caller before + * calling this function. + */ + void findBinaryPath() const; + + ExecutableEnvironmentPointer executableEnv_; + std::string invokedName_; + std::string programName_; + std::string displayName_; + std::string commandLine_; + mutable std::string fullBinaryPath_; + mutable std::string installationPrefix_; + mutable bool bSourceLayout_; + mutable Mutex binaryPathMutex_; }; -CommandLineProgramContext::Impl::Impl() - : programName_("GROMACS"), bSourceLayout_(false) -{ -} +CommandLineProgramContext::Impl::Impl() : programName_("GROMACS"), bSourceLayout_(false) {} -CommandLineProgramContext::Impl::Impl(int argc, const char *const argv[], - ExecutableEnvironmentPointer env) - : executableEnv_(std::move(env)), invokedName_(argc != 0 ? argv[0] : ""), bSourceLayout_(false) +CommandLineProgramContext::Impl::Impl(int argc, const char* const argv[], ExecutableEnvironmentPointer env) : + executableEnv_(std::move(env)), + invokedName_(argc != 0 ? argv[0] : ""), + bSourceLayout_(false) { programName_ = Path::getFilename(invokedName_); programName_ = stripSuffixIfPresent(programName_, ".exe"); @@ -354,57 +343,49 @@ void CommandLineProgramContext::Impl::findBinaryPath() const * CommandLineProgramContext */ -CommandLineProgramContext::CommandLineProgramContext() - : impl_(new Impl) -{ -} +CommandLineProgramContext::CommandLineProgramContext() : impl_(new Impl) {} -CommandLineProgramContext::CommandLineProgramContext(const char *binaryName) - : impl_(new Impl(1, &binaryName, DefaultExecutableEnvironment::create())) +CommandLineProgramContext::CommandLineProgramContext(const char* binaryName) : + impl_(new Impl(1, &binaryName, DefaultExecutableEnvironment::create())) { } -CommandLineProgramContext::CommandLineProgramContext( - int argc, const char *const argv[]) - : impl_(new Impl(argc, argv, DefaultExecutableEnvironment::create())) +CommandLineProgramContext::CommandLineProgramContext(int argc, const char* const argv[]) : + impl_(new Impl(argc, argv, DefaultExecutableEnvironment::create())) { } -CommandLineProgramContext::CommandLineProgramContext( - int argc, const char *const argv[], ExecutableEnvironmentPointer env) - : impl_(new Impl(argc, argv, move(env))) +CommandLineProgramContext::CommandLineProgramContext(int argc, + const char* const argv[], + ExecutableEnvironmentPointer env) : + impl_(new Impl(argc, argv, move(env))) { } -CommandLineProgramContext::~CommandLineProgramContext() -{ -} +CommandLineProgramContext::~CommandLineProgramContext() {} -void CommandLineProgramContext::setDisplayName(const std::string &name) +void CommandLineProgramContext::setDisplayName(const std::string& name) { - GMX_RELEASE_ASSERT(impl_->displayName_.empty(), - "Can only set display name once"); + GMX_RELEASE_ASSERT(impl_->displayName_.empty(), "Can only set display name once"); impl_->displayName_ = name; } -const char *CommandLineProgramContext::programName() const +const char* CommandLineProgramContext::programName() const { return impl_->programName_.c_str(); } -const char *CommandLineProgramContext::displayName() const +const char* CommandLineProgramContext::displayName() const { - return impl_->displayName_.empty() - ? impl_->programName_.c_str() - : impl_->displayName_.c_str(); + return impl_->displayName_.empty() ? impl_->programName_.c_str() : impl_->displayName_.c_str(); } -const char *CommandLineProgramContext::commandLine() const +const char* CommandLineProgramContext::commandLine() const { return impl_->commandLine_.c_str(); } -const char *CommandLineProgramContext::fullBinaryPath() const +const char* CommandLineProgramContext::fullBinaryPath() const { lock_guard lock(impl_->binaryPathMutex_); impl_->findBinaryPath(); @@ -417,13 +398,10 @@ InstallationPrefixInfo CommandLineProgramContext::installationPrefix() const if (impl_->installationPrefix_.empty()) { impl_->findBinaryPath(); - impl_->installationPrefix_ = - Path::normalize(findInstallationPrefixPath(impl_->fullBinaryPath_, - &impl_->bSourceLayout_)); + impl_->installationPrefix_ = Path::normalize( + findInstallationPrefixPath(impl_->fullBinaryPath_, &impl_->bSourceLayout_)); } - return InstallationPrefixInfo( - impl_->installationPrefix_.c_str(), - impl_->bSourceLayout_); + return InstallationPrefixInfo(impl_->installationPrefix_.c_str(), impl_->bSourceLayout_); } } // namespace gmx diff --git a/src/gromacs/commandline/cmdlineprogramcontext.h b/src/gromacs/commandline/cmdlineprogramcontext.h index d0c3502c79..e42f3ecaec 100644 --- a/src/gromacs/commandline/cmdlineprogramcontext.h +++ b/src/gromacs/commandline/cmdlineprogramcontext.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,20 +73,20 @@ namespace gmx */ class IExecutableEnvironment { - public: - virtual ~IExecutableEnvironment() {} +public: + virtual ~IExecutableEnvironment() {} - /*! \brief - * Returns the working directory when the program was launched. - */ - virtual std::string getWorkingDirectory() const = 0; - /*! \brief - * Returns list of paths where executables are searched for. - * - * The returned list should be in priority order. An empty string in - * the returned list corresponds to getWorkindDirectory(). - */ - virtual std::vector getExecutablePaths() const = 0; + /*! \brief + * Returns the working directory when the program was launched. + */ + virtual std::string getWorkingDirectory() const = 0; + /*! \brief + * Returns list of paths where executables are searched for. + * + * The returned list should be in priority order. An empty string in + * the returned list corresponds to getWorkindDirectory(). + */ + virtual std::vector getExecutablePaths() const = 0; }; //! Shorthand for a smart pointer to IExecutableEnvironment. @@ -109,111 +109,110 @@ typedef std::unique_ptr ExecutableEnvironmentPointer; */ class CommandLineProgramContext : public IProgramContext { - public: - /*! \brief - * Constructs an empty context object. - * - * All methods in the constructed object return dummy values. - */ - CommandLineProgramContext(); - /*! \brief - * Initializes a program context object with binary name only. - * - * \param[in] binaryName Name of the binary. - * - * This is needed for unit testing purposes. - * The constructed object works as if the command line consisted of - * only of the binary name. - */ - explicit CommandLineProgramContext(const char *binaryName); - /*! \brief - * Initializes a program context object based on command line. - * - * \param[in] argc argc value passed to main(). - * \param[in] argv argv array passed to main(). - */ - CommandLineProgramContext(int argc, const char *const argv[]); - /*! \brief - * Initializes a program context object based on command line. - * - * \param[in] argc argc value passed to main(). - * \param[in] argv argv array passed to main(). - * \param[in] env Customizes the way the binary name is handled. - * - * This overload allows one to customize the way the binary is located - * by providing a custom IExecutableEnvironment implementation. - * This is mainly useful for testing purposes to make it possible to - * test different paths without setting environment variables, changing - * the working directory or doing other process-wide operations. - * It may also be useful for making Gromacs behave better when linked - * into a non-Gromacs executable (with possible extensions in - * IExecutableEnvironment). - */ - CommandLineProgramContext(int argc, const char *const argv[], - ExecutableEnvironmentPointer env); - ~CommandLineProgramContext() override; +public: + /*! \brief + * Constructs an empty context object. + * + * All methods in the constructed object return dummy values. + */ + CommandLineProgramContext(); + /*! \brief + * Initializes a program context object with binary name only. + * + * \param[in] binaryName Name of the binary. + * + * This is needed for unit testing purposes. + * The constructed object works as if the command line consisted of + * only of the binary name. + */ + explicit CommandLineProgramContext(const char* binaryName); + /*! \brief + * Initializes a program context object based on command line. + * + * \param[in] argc argc value passed to main(). + * \param[in] argv argv array passed to main(). + */ + CommandLineProgramContext(int argc, const char* const argv[]); + /*! \brief + * Initializes a program context object based on command line. + * + * \param[in] argc argc value passed to main(). + * \param[in] argv argv array passed to main(). + * \param[in] env Customizes the way the binary name is handled. + * + * This overload allows one to customize the way the binary is located + * by providing a custom IExecutableEnvironment implementation. + * This is mainly useful for testing purposes to make it possible to + * test different paths without setting environment variables, changing + * the working directory or doing other process-wide operations. + * It may also be useful for making Gromacs behave better when linked + * into a non-Gromacs executable (with possible extensions in + * IExecutableEnvironment). + */ + CommandLineProgramContext(int argc, const char* const argv[], ExecutableEnvironmentPointer env); + ~CommandLineProgramContext() override; - /*! \brief - * Sets a display name for the binary. - * - * \throws std::bad_alloc if out of memory. - * - * This is used with the wrapper binary to add the name of the invoked - * module to the name of the binary shown. - * - * It is not threadsafe if there are concurrent calls to displayName() - * before this method has returned. Thread safety is not required for - * the normal initialization sequence of command line programs; it is - * called in the wrapper binary before the control passes to the actual - * module which may create threads. - */ - void setDisplayName(const std::string &name); + /*! \brief + * Sets a display name for the binary. + * + * \throws std::bad_alloc if out of memory. + * + * This is used with the wrapper binary to add the name of the invoked + * module to the name of the binary shown. + * + * It is not threadsafe if there are concurrent calls to displayName() + * before this method has returned. Thread safety is not required for + * the normal initialization sequence of command line programs; it is + * called in the wrapper binary before the control passes to the actual + * module which may create threads. + */ + void setDisplayName(const std::string& name); - /*! \brief - * Returns the name of the binary as it was invoked without any path. - * - * Does not throw. - */ - const char *programName() const override; - /*! \brief - * Returns a display name of the current module. - * - * The returned value equals programName(), unless a separate display - * name has been set with setDisplayName(). - * - * Does not throw. - */ - const char *displayName() const override; - /*! \brief - * Returns the full path of the running binary. - * - * \throws std::bad_alloc if out of memory. - * \throws tMPI::system_error on thread synchronization errors. - * - * Returns argv[0] if there was an error in finding the absolute path. - */ - const char *fullBinaryPath() const override; - /*! \brief - * Returns the installation prefix (for finding \Gromacs data files). - * - * \throws std::bad_alloc if out of memory. - * \throws tMPI::system_error on thread synchronization errors. - * - * Returns a hardcoded path set during configuration time if there is - * an error in finding the library data files. - */ - InstallationPrefixInfo installationPrefix() const override; - /*! \brief - * Returns the full command line used to invoke the binary. - * - * Does not throw. - */ - const char *commandLine() const override; + /*! \brief + * Returns the name of the binary as it was invoked without any path. + * + * Does not throw. + */ + const char* programName() const override; + /*! \brief + * Returns a display name of the current module. + * + * The returned value equals programName(), unless a separate display + * name has been set with setDisplayName(). + * + * Does not throw. + */ + const char* displayName() const override; + /*! \brief + * Returns the full path of the running binary. + * + * \throws std::bad_alloc if out of memory. + * \throws tMPI::system_error on thread synchronization errors. + * + * Returns argv[0] if there was an error in finding the absolute path. + */ + const char* fullBinaryPath() const override; + /*! \brief + * Returns the installation prefix (for finding \Gromacs data files). + * + * \throws std::bad_alloc if out of memory. + * \throws tMPI::system_error on thread synchronization errors. + * + * Returns a hardcoded path set during configuration time if there is + * an error in finding the library data files. + */ + InstallationPrefixInfo installationPrefix() const override; + /*! \brief + * Returns the full command line used to invoke the binary. + * + * Does not throw. + */ + const char* commandLine() const override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/commandline/filenm.cpp b/src/gromacs/commandline/filenm.cpp index 69af71bc36..b1044cf330 100644 --- a/src/gromacs/commandline/filenm.cpp +++ b/src/gromacs/commandline/filenm.cpp @@ -52,24 +52,24 @@ #include "gromacs/utility/stringutil.h" /* Use bitflag ... */ -static bool IS_SET(const t_filenm &fileOption) +static bool IS_SET(const t_filenm& fileOption) { return (fileOption.flag & ffSET) != 0; } -static bool IS_OPT(const t_filenm &fileOption) +static bool IS_OPT(const t_filenm& fileOption) { return (fileOption.flag & ffOPT) != 0; } -static const t_filenm *getFileOption(const char *opt, int nfile, const t_filenm fnm[]) +static const t_filenm* getFileOption(const char* opt, int nfile, const t_filenm fnm[]) { GMX_RELEASE_ASSERT(nfile == 0 || fnm, "need a valid list of filenames"); for (int i = 0; i < nfile; i++) { - if ((fnm[i].opt != nullptr && strcmp(opt, fnm[i].opt) == 0) || - (fnm[i].opt == nullptr && strcmp(opt, ftp2defopt(fnm[i].ftp)) == 0)) + if ((fnm[i].opt != nullptr && strcmp(opt, fnm[i].opt) == 0) + || (fnm[i].opt == nullptr && strcmp(opt, ftp2defopt(fnm[i].ftp)) == 0)) { return &fnm[i]; } @@ -78,9 +78,9 @@ static const t_filenm *getFileOption(const char *opt, int nfile, const t_filenm return nullptr; } -const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[]) +const char* opt2fn(const char* opt, int nfile, const t_filenm fnm[]) { - const t_filenm *fileOption = getFileOption(opt, nfile, fnm); + const t_filenm* fileOption = getFileOption(opt, nfile, fnm); if (fileOption) { @@ -92,10 +92,9 @@ const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[]) return nullptr; } -gmx::ArrayRef -opt2fns(const char *opt, int nfile, const t_filenm fnm[]) +gmx::ArrayRef opt2fns(const char* opt, int nfile, const t_filenm fnm[]) { - const t_filenm *fileOption = getFileOption(opt, nfile, fnm); + const t_filenm* fileOption = getFileOption(opt, nfile, fnm); if (fileOption) { @@ -107,8 +106,7 @@ opt2fns(const char *opt, int nfile, const t_filenm fnm[]) return {}; } -gmx::ArrayRef -opt2fnsIfOptionSet(const char *opt, int nfile, const t_filenm fnm[]) +gmx::ArrayRef opt2fnsIfOptionSet(const char* opt, int nfile, const t_filenm fnm[]) { if (opt2bSet(opt, nfile, fnm)) { @@ -120,7 +118,7 @@ opt2fnsIfOptionSet(const char *opt, int nfile, const t_filenm fnm[]) } } -const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[]) +const char* ftp2fn(int ftp, int nfile, const t_filenm fnm[]) { int i; @@ -137,8 +135,7 @@ const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[]) return nullptr; } -gmx::ArrayRef -ftp2fns(int ftp, int nfile, const t_filenm fnm[]) +gmx::ArrayRef ftp2fns(int ftp, int nfile, const t_filenm fnm[]) { for (int i = 0; (i < nfile); i++) { @@ -170,9 +167,9 @@ gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[]) return FALSE; } -gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[]) +gmx_bool opt2bSet(const char* opt, int nfile, const t_filenm fnm[]) { - const t_filenm *fileOption = getFileOption(opt, nfile, fnm); + const t_filenm* fileOption = getFileOption(opt, nfile, fnm); if (fileOption) { @@ -184,9 +181,9 @@ gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[]) return FALSE; } -const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[]) +const char* opt2fn_null(const char* opt, int nfile, const t_filenm fnm[]) { - const t_filenm *fileOption = getFileOption(opt, nfile, fnm); + const t_filenm* fileOption = getFileOption(opt, nfile, fnm); if (fileOption) { @@ -205,7 +202,7 @@ const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[]) return nullptr; } -const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[]) +const char* ftp2fn_null(int ftp, int nfile, const t_filenm fnm[]) { int i; @@ -229,17 +226,17 @@ const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[]) return nullptr; } -gmx_bool is_optional(const t_filenm *fnm) +gmx_bool is_optional(const t_filenm* fnm) { return ((fnm->flag & ffOPT) == ffOPT); } -gmx_bool is_output(const t_filenm *fnm) +gmx_bool is_output(const t_filenm* fnm) { return ((fnm->flag & ffWRITE) == ffWRITE); } -gmx_bool is_set(const t_filenm *fnm) +gmx_bool is_set(const t_filenm* fnm) { return ((fnm->flag & ffSET) == ffSET); } @@ -252,27 +249,24 @@ namespace size_t findSuffixFromNoAppendPosition(const gmx::compat::string_view filename) { size_t partPosition = filename.find(".part"); - if ((partPosition != decltype(filename) ::npos) && - (filename.length() - partPosition >= 10) && - (std::isdigit(filename[partPosition + 5])) && - (std::isdigit(filename[partPosition + 6])) && - (std::isdigit(filename[partPosition + 7])) && - (std::isdigit(filename[partPosition + 8])) && - filename[partPosition + 9] == '.') + if ((partPosition != decltype(filename)::npos) && (filename.length() - partPosition >= 10) + && (std::isdigit(filename[partPosition + 5])) && (std::isdigit(filename[partPosition + 6])) + && (std::isdigit(filename[partPosition + 7])) && (std::isdigit(filename[partPosition + 8])) + && filename[partPosition + 9] == '.') { return partPosition; } - return decltype(filename) ::npos; + return decltype(filename)::npos; } } // namespace bool hasSuffixFromNoAppend(const gmx::compat::string_view filename) { - return (findSuffixFromNoAppendPosition(filename) != decltype(filename) ::npos); + return (findSuffixFromNoAppendPosition(filename) != decltype(filename)::npos); } -int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix) +int add_suffix_to_output_names(t_filenm* fnm, int nfile, const char* suffix) { for (int i = 0; i < nfile; i++) { @@ -280,7 +274,7 @@ int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix) { /* We never use multiple _outputs_, but we might as well check for it, just in case... */ - for (std::string &filename : fnm[i].filenames) + for (std::string& filename : fnm[i].filenames) { // mdrun should not generate files like // md.part0002.part0003.log. mdrun should permit users @@ -289,7 +283,8 @@ int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix) // add the requested suffix, we need to check for // files matching mdrun's pattern for adding part // numbers. Then we can remove that if needed. - for (size_t partPosition; (partPosition = findSuffixFromNoAppendPosition(filename)) != std::string::npos; ) + for (size_t partPosition; + (partPosition = findSuffixFromNoAppendPosition(filename)) != std::string::npos;) { // Remove the ".partNNNN" that we have found, // and then run the loop again to make sure diff --git a/src/gromacs/commandline/filenm.h b/src/gromacs/commandline/filenm.h index 7100f86403..a188ebe9e2 100644 --- a/src/gromacs/commandline/filenm.h +++ b/src/gromacs/commandline/filenm.h @@ -63,61 +63,60 @@ */ struct t_filenm { - int ftp; //!< File type, see enum in filetypes.h - const char * opt; //!< Command line option, can be nullptr in which case the commandline module, including all opt2??? functions below, will use the default option for the file type - const char * fn; //!< File name (as set in source code), can be nullptr in which case the commandline module will use the default file name for the file type + int ftp; //!< File type, see enum in filetypes.h + const char* opt; //!< Command line option, can be nullptr in which case the commandline module, including all opt2??? functions below, will use the default option for the file type + const char* fn; //!< File name (as set in source code), can be nullptr in which case the commandline module will use the default file name for the file type unsigned long flag; //!< Flag for all kinds of info (see defs) std::vector filenames; //!< File names }; //! Whether a file name option is set. -#define ffSET 1<<0 +#define ffSET 1 << 0 //! Whether a file name option specifies an input file. -#define ffREAD 1<<1 +#define ffREAD 1 << 1 //! Whether a file name option specifies an output file. -#define ffWRITE 1<<2 +#define ffWRITE 1 << 2 //! Whether a file name option specifies an optional file. -#define ffOPT 1<<3 +#define ffOPT 1 << 3 //! Whether a file name option specifies a library file. -#define ffLIB 1<<4 +#define ffLIB 1 << 4 //! Whether a file name option accepts multiple file names. -#define ffMULT 1<<5 +#define ffMULT 1 << 5 //! Whether an input file name option accepts non-existent files. -#define ffALLOW_MISSING 1<<6 +#define ffALLOW_MISSING 1 << 6 //! Convenience flag for an input/output file. -#define ffRW (ffREAD | ffWRITE) +#define ffRW (ffREAD | ffWRITE) //! Convenience flag for an optional input file. #define ffOPTRD (ffREAD | ffOPT) //! Convenience flag for an optional output file. -#define ffOPTWR (ffWRITE| ffOPT) +#define ffOPTWR (ffWRITE | ffOPT) //! Convenience flag for an optional input/output file. -#define ffOPTRW (ffRW | ffOPT) +#define ffOPTRW (ffRW | ffOPT) //! Convenience flag for a library input file. #define ffLIBRD (ffREAD | ffLIB) //! Convenience flag for an optional library input file. #define ffLIBOPTRD (ffOPTRD | ffLIB) //! Convenience flag for an input file that accepts multiple files. -#define ffRDMULT (ffREAD | ffMULT) +#define ffRDMULT (ffREAD | ffMULT) //! Convenience flag for an optional input file that accepts multiple files. -#define ffOPTRDMULT (ffRDMULT | ffOPT) +#define ffOPTRDMULT (ffRDMULT | ffOPT) //! Convenience flag for an output file that accepts multiple files. -#define ffWRMULT (ffWRITE | ffMULT) +#define ffWRMULT (ffWRITE | ffMULT) //! Convenience flag for an optional output file that accepts multiple files. -#define ffOPTWRMULT (ffWRMULT | ffOPT) +#define ffOPTWRMULT (ffWRMULT | ffOPT) /*! \brief * Returns the filename belonging to cmd-line option opt, or NULL when * no such option. */ -const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[]); +const char* opt2fn(const char* opt, int nfile, const t_filenm fnm[]); /*! \brief * Returns the filenames belonging to cmd-line option opt. * * An assertion will fail when the option does not exist. */ -gmx::ArrayRef -opt2fns(const char *opt, int nfile, const t_filenm fnm[]); +gmx::ArrayRef opt2fns(const char* opt, int nfile, const t_filenm fnm[]); /*! \brief * Returns the filenames belonging to cmd-line option opt when set, @@ -125,22 +124,20 @@ opt2fns(const char *opt, int nfile, const t_filenm fnm[]); * * An assertion will fail when the option does not exist. */ -gmx::ArrayRef -opt2fnsIfOptionSet(const char *opt, int nfile, const t_filenm fnm[]); +gmx::ArrayRef opt2fnsIfOptionSet(const char* opt, int nfile, const t_filenm fnm[]); //! Returns a file pointer from the filename. #define opt2FILE(opt, nfile, fnm, mode) gmx_ffopen(opt2fn(opt, nfile, fnm), mode) //! Returns the first file name with type ftp, or NULL when none found. -const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[]); +const char* ftp2fn(int ftp, int nfile, const t_filenm fnm[]); /*! \brief * Returns the filenames for the first option with type ftp. * * An assertion will fail when when none found. */ -gmx::ArrayRef -ftp2fns(int ftp, int nfile, const t_filenm fnm[]); +gmx::ArrayRef ftp2fns(int ftp, int nfile, const t_filenm fnm[]); //! Returns a file pointer from the file type. #define ftp2FILE(ftp, nfile, fnm, mode) gmx_ffopen(ftp2fn(ftp, nfile, fnm), mode) @@ -149,7 +146,7 @@ ftp2fns(int ftp, int nfile, const t_filenm fnm[]); gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[]); //! Returns TRUE when this option has been found on the cmd-line. -gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[]); +gmx_bool opt2bSet(const char* opt, int nfile, const t_filenm fnm[]); /*! \brief * Returns the file name belonging top cmd-line option opt, or NULL when @@ -157,23 +154,23 @@ gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[]); * * Also return NULL when opt is optional and option is not set. */ -const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[]); +const char* opt2fn_null(const char* opt, int nfile, const t_filenm fnm[]); /*! \brief * Returns the first file name with type ftp, or NULL when none found. * * Also return NULL when ftp is optional and option is not set. */ -const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[]); +const char* ftp2fn_null(int ftp, int nfile, const t_filenm fnm[]); //! Returns whether or not this filenm is optional. -gmx_bool is_optional(const t_filenm *fnm); +gmx_bool is_optional(const t_filenm* fnm); //! Returns whether or not this filenm is output. -gmx_bool is_output(const t_filenm *fnm); +gmx_bool is_output(const t_filenm* fnm); //! Returns whether or not this filenm is set. -gmx_bool is_set(const t_filenm *fnm); +gmx_bool is_set(const t_filenm* fnm); /*! \brief Return whether \c filename might have been produced by mdrun -noappend. * @@ -187,7 +184,7 @@ bool hasSuffixFromNoAppend(gmx::compat::string_view filename); * If there was already a '.partNNNN' suffix before the file extension, that * is removed before the new suffix is added. */ -int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix); +int add_suffix_to_output_names(t_filenm* fnm, int nfile, const char* suffix); //! \} diff --git a/src/gromacs/commandline/pargs.cpp b/src/gromacs/commandline/pargs.cpp index 0804bbb7ba..ac63ac6442 100644 --- a/src/gromacs/commandline/pargs.cpp +++ b/src/gromacs/commandline/pargs.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,7 +68,7 @@ /* The source code in this file should be thread-safe. Please keep it that way. */ -int nenum(const char *const enumc[]) +int nenum(const char* const enumc[]) { int i; @@ -82,7 +82,7 @@ int nenum(const char *const enumc[]) return i; } -int opt2parg_int(const char *option, int nparg, t_pargs pa[]) +int opt2parg_int(const char* option, int nparg, t_pargs pa[]) { int i; @@ -97,7 +97,7 @@ int opt2parg_int(const char *option, int nparg, t_pargs pa[]) gmx_fatal(FARGS, "No integer option %s in pargs", option); } -gmx_bool opt2parg_bool(const char *option, int nparg, t_pargs pa[]) +gmx_bool opt2parg_bool(const char* option, int nparg, t_pargs pa[]) { int i; @@ -114,7 +114,7 @@ gmx_bool opt2parg_bool(const char *option, int nparg, t_pargs pa[]) return FALSE; } -real opt2parg_real(const char *option, int nparg, t_pargs pa[]) +real opt2parg_real(const char* option, int nparg, t_pargs pa[]) { int i; @@ -129,7 +129,7 @@ real opt2parg_real(const char *option, int nparg, t_pargs pa[]) gmx_fatal(FARGS, "No real option %s in pargs", option); } -const char *opt2parg_str(const char *option, int nparg, t_pargs pa[]) +const char* opt2parg_str(const char* option, int nparg, t_pargs pa[]) { int i; @@ -144,7 +144,7 @@ const char *opt2parg_str(const char *option, int nparg, t_pargs pa[]) gmx_fatal(FARGS, "No string option %s in pargs", option); } -gmx_bool opt2parg_bSet(const char *option, int nparg, const t_pargs *pa) +gmx_bool opt2parg_bSet(const char* option, int nparg, const t_pargs* pa) { int i; @@ -161,7 +161,7 @@ gmx_bool opt2parg_bSet(const char *option, int nparg, const t_pargs *pa) return FALSE; /* Too make some compilers happy */ } -const char *opt2parg_enum(const char *option, int nparg, t_pargs pa[]) +const char* opt2parg_enum(const char* option, int nparg, t_pargs pa[]) { int i; @@ -191,13 +191,13 @@ namespace * * \ingroup module_commandline */ -int getDefaultXvgFormat(gmx::ArrayRef xvgFormats) +int getDefaultXvgFormat(gmx::ArrayRef xvgFormats) { - const char *const select = getenv("GMX_VIEW_XVG"); + const char* const select = getenv("GMX_VIEW_XVG"); if (select != nullptr) { - ArrayRef::const_iterator i = - std::find(xvgFormats.begin(), xvgFormats.end(), std::string(select)); + ArrayRef::const_iterator i = + std::find(xvgFormats.begin(), xvgFormats.end(), std::string(select)); if (i != xvgFormats.end()) { return std::distance(xvgFormats.begin(), i); @@ -223,97 +223,95 @@ int getDefaultXvgFormat(gmx::ArrayRef xvgFormats) */ class OptionsAdapter { - public: - /*! \brief - * Initializes the adapter to convert from a specified command line. - * - * The command line is required, because t_pargs wants to return - * strings by reference to the original command line. - * OptionsAdapter creates a copy of the `argv` array (but not the - * strings) to make this possible, even if the parser removes - * options it has recognized. - */ - OptionsAdapter(int argc, const char *const argv[]) - : argv_(argv, argv + argc) +public: + /*! \brief + * Initializes the adapter to convert from a specified command line. + * + * The command line is required, because t_pargs wants to return + * strings by reference to the original command line. + * OptionsAdapter creates a copy of the `argv` array (but not the + * strings) to make this possible, even if the parser removes + * options it has recognized. + */ + OptionsAdapter(int argc, const char* const argv[]) : argv_(argv, argv + argc) {} + + /*! \brief + * Converts a t_filenm option into an Options option. + * + * \param options Options object to add the new option to. + * \param fnm t_filenm option to convert. + */ + void filenmToOptions(Options* options, t_filenm* fnm); + /*! \brief + * Converts a t_pargs option into an Options option. + * + * \param options Options object to add the new option to. + * \param pa t_pargs option to convert. + */ + void pargsToOptions(Options* options, t_pargs* pa); + + /*! \brief + * Copies values back from options to t_pargs/t_filenm. + */ + void copyValues(); + +private: + struct FileNameData + { + //! Creates a conversion helper for a given `t_filenm` struct. + explicit FileNameData(t_filenm* fnm) : fnm(fnm), optionInfo(nullptr) {} + + //! t_filenm structure to receive the final values. + t_filenm* fnm; + //! Option info object for the created FileNameOption. + FileNameOptionInfo* optionInfo; + //! Value storage for the created FileNameOption. + std::vector values; + }; + struct ProgramArgData + { + //! Creates a conversion helper for a given `t_pargs` struct. + explicit ProgramArgData(t_pargs* pa) : + pa(pa), + optionInfo(nullptr), + enumIndex(0), + boolValue(false) { } - /*! \brief - * Converts a t_filenm option into an Options option. - * - * \param options Options object to add the new option to. - * \param fnm t_filenm option to convert. - */ - void filenmToOptions(Options *options, t_filenm *fnm); - /*! \brief - * Converts a t_pargs option into an Options option. - * - * \param options Options object to add the new option to. - * \param pa t_pargs option to convert. - */ - void pargsToOptions(Options *options, t_pargs *pa); - - /*! \brief - * Copies values back from options to t_pargs/t_filenm. - */ - void copyValues(); - - private: - struct FileNameData - { - //! Creates a conversion helper for a given `t_filenm` struct. - explicit FileNameData(t_filenm *fnm) : fnm(fnm), optionInfo(nullptr) - { - } - - //! t_filenm structure to receive the final values. - t_filenm *fnm; - //! Option info object for the created FileNameOption. - FileNameOptionInfo *optionInfo; - //! Value storage for the created FileNameOption. - std::vector values; - }; - struct ProgramArgData - { - //! Creates a conversion helper for a given `t_pargs` struct. - explicit ProgramArgData(t_pargs *pa) - : pa(pa), optionInfo(nullptr), enumIndex(0), boolValue(false) - { - } - - //! t_pargs structure to receive the final values. - t_pargs *pa; - //! Option info object for the created option. - OptionInfo *optionInfo; - //! Value storage for a non-enum StringOption (unused for other types). - std::string stringValue; - //! Value storage for an enum option (unused for other types). - int enumIndex; - //! Value storage for a BooleanOption (unused for other types). - bool boolValue; - }; - - std::vector argv_; - // These are lists instead of vectors to avoid relocating existing - // objects in case the container is reallocated (the Options object - // contains pointes to members of the objects, which would get - // invalidated). - std::list fileNameOptions_; - std::list programArgs_; - - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsAdapter); + //! t_pargs structure to receive the final values. + t_pargs* pa; + //! Option info object for the created option. + OptionInfo* optionInfo; + //! Value storage for a non-enum StringOption (unused for other types). + std::string stringValue; + //! Value storage for an enum option (unused for other types). + int enumIndex; + //! Value storage for a BooleanOption (unused for other types). + bool boolValue; + }; + + std::vector argv_; + // These are lists instead of vectors to avoid relocating existing + // objects in case the container is reallocated (the Options object + // contains pointes to members of the objects, which would get + // invalidated). + std::list fileNameOptions_; + std::list programArgs_; + + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsAdapter); }; -void OptionsAdapter::filenmToOptions(Options *options, t_filenm *fnm) +void OptionsAdapter::filenmToOptions(Options* options, t_filenm* fnm) { - const bool bRead = ((fnm->flag & ffREAD) != 0); + const bool bRead = ((fnm->flag & ffREAD) != 0); const bool bWrite = ((fnm->flag & ffWRITE) != 0); - const bool bOptional = ((fnm->flag & ffOPT) != 0); - const bool bLibrary = ((fnm->flag & ffLIB) != 0); - const bool bMultiple = ((fnm->flag & ffMULT) != 0); + const bool bOptional = ((fnm->flag & ffOPT) != 0); + const bool bLibrary = ((fnm->flag & ffLIB) != 0); + const bool bMultiple = ((fnm->flag & ffMULT) != 0); const bool bMissing = ((fnm->flag & ffALLOW_MISSING) != 0); - const char *const name = (fnm->opt ? &fnm->opt[1] : &ftp2defopt(fnm->ftp)[1]); - const char * defName = fnm->fn; + const char* const name = (fnm->opt ? &fnm->opt[1] : &ftp2defopt(fnm->ftp)[1]); + const char* defName = fnm->fn; int defType = -1; if (defName == nullptr) { @@ -322,78 +320,79 @@ void OptionsAdapter::filenmToOptions(Options *options, t_filenm *fnm) else if (Path::hasExtension(defName)) { defType = fn2ftp(defName); - GMX_RELEASE_ASSERT(defType != efNR, - "File name option specifies an invalid extension"); + GMX_RELEASE_ASSERT(defType != efNR, "File name option specifies an invalid extension"); } fileNameOptions_.emplace_back(fnm); - FileNameData &data = fileNameOptions_.back(); - data.optionInfo = options->addOption( - FileNameOption(name).storeVector(&data.values) - .defaultBasename(defName).defaultType(defType) - .legacyType(fnm->ftp).legacyOptionalBehavior() - .readWriteFlags(bRead, bWrite).required(!bOptional) - .libraryFile(bLibrary).multiValue(bMultiple) - .allowMissing(bMissing) - .description(ftp2desc(fnm->ftp))); + FileNameData& data = fileNameOptions_.back(); + data.optionInfo = options->addOption(FileNameOption(name) + .storeVector(&data.values) + .defaultBasename(defName) + .defaultType(defType) + .legacyType(fnm->ftp) + .legacyOptionalBehavior() + .readWriteFlags(bRead, bWrite) + .required(!bOptional) + .libraryFile(bLibrary) + .multiValue(bMultiple) + .allowMissing(bMissing) + .description(ftp2desc(fnm->ftp))); } -void OptionsAdapter::pargsToOptions(Options *options, t_pargs *pa) +void OptionsAdapter::pargsToOptions(Options* options, t_pargs* pa) { const bool bHidden = startsWith(pa->desc, "HIDDEN"); - const char *const name = &pa->option[1]; - const char *const desc = (bHidden ? &pa->desc[6] : pa->desc); + const char* const name = &pa->option[1]; + const char* const desc = (bHidden ? &pa->desc[6] : pa->desc); programArgs_.emplace_back(pa); - ProgramArgData &data = programArgs_.back(); + ProgramArgData& data = programArgs_.back(); switch (pa->type) { case etINT: data.optionInfo = options->addOption( - IntegerOption(name).store(pa->u.i) - .description(desc).hidden(bHidden)); + IntegerOption(name).store(pa->u.i).description(desc).hidden(bHidden)); return; case etINT64: data.optionInfo = options->addOption( - Int64Option(name).store(pa->u.is) - .description(desc).hidden(bHidden)); + Int64Option(name).store(pa->u.is).description(desc).hidden(bHidden)); return; case etREAL: - data.optionInfo = options->addOption( - RealOption(name).store(pa->u.r) - .description(desc).hidden(bHidden)); + data.optionInfo = + options->addOption(RealOption(name).store(pa->u.r).description(desc).hidden(bHidden)); return; case etTIME: data.optionInfo = options->addOption( - RealOption(name).store(pa->u.r).timeValue() - .description(desc).hidden(bHidden)); + RealOption(name).store(pa->u.r).timeValue().description(desc).hidden(bHidden)); return; case etSTR: { - const char *const defValue = (*pa->u.c != nullptr ? *pa->u.c : ""); - data.optionInfo = options->addOption( - StringOption(name).store(&data.stringValue) - .defaultValue(defValue) - .description(desc).hidden(bHidden)); + const char* const defValue = (*pa->u.c != nullptr ? *pa->u.c : ""); + data.optionInfo = options->addOption(StringOption(name) + .store(&data.stringValue) + .defaultValue(defValue) + .description(desc) + .hidden(bHidden)); return; } case etBOOL: - data.optionInfo = options->addOption( - BooleanOption(name).store(&data.boolValue) - .defaultValue(*pa->u.b) - .description(desc).hidden(bHidden)); + data.optionInfo = options->addOption(BooleanOption(name) + .store(&data.boolValue) + .defaultValue(*pa->u.b) + .description(desc) + .hidden(bHidden)); return; case etRVEC: data.optionInfo = options->addOption( - RealOption(name).store(*pa->u.rv).vector() - .description(desc).hidden(bHidden)); + RealOption(name).store(*pa->u.rv).vector().description(desc).hidden(bHidden)); return; case etENUM: { const int defaultIndex = (pa->u.c[0] != nullptr ? nenum(pa->u.c) - 1 : 0); - data.optionInfo = options->addOption( - EnumIntOption(name).store(&data.enumIndex) - .defaultValue(defaultIndex) - .enumValueFromNullTerminatedArray(pa->u.c + 1) - .description(desc).hidden(bHidden)); + data.optionInfo = options->addOption(EnumIntOption(name) + .store(&data.enumIndex) + .defaultValue(defaultIndex) + .enumValueFromNullTerminatedArray(pa->u.c + 1) + .description(desc) + .hidden(bHidden)); return; } } @@ -421,20 +420,16 @@ void OptionsAdapter::copyValues() { if (arg->pa->bSet) { - std::vector::const_iterator pos = - std::find(argv_.begin(), argv_.end(), arg->stringValue); + std::vector::const_iterator pos = + std::find(argv_.begin(), argv_.end(), arg->stringValue); GMX_RELEASE_ASSERT(pos != argv_.end(), "String argument got a value not in argv"); *arg->pa->u.c = *pos; } break; } - case etBOOL: - *arg->pa->u.b = arg->boolValue; - break; - case etENUM: - *arg->pa->u.c = arg->pa->u.c[arg->enumIndex + 1]; - break; + case etBOOL: *arg->pa->u.b = arg->boolValue; break; + case etENUM: *arg->pa->u.c = arg->pa->u.c[arg->enumIndex + 1]; break; default: // For other types, there is nothing type-specific to do. break; @@ -446,33 +441,37 @@ void OptionsAdapter::copyValues() } // namespace gmx -gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, - int nfile, t_filenm fnm[], int npargs, t_pargs *pa, - int ndesc, const char **desc, - int nbugs, const char **bugs, - gmx_output_env_t **oenv) +gmx_bool parse_common_args(int* argc, + char* argv[], + unsigned long Flags, + int nfile, + t_filenm fnm[], + int npargs, + t_pargs* pa, + int ndesc, + const char** desc, + int nbugs, + const char** bugs, + gmx_output_env_t** oenv) { /* This array should match the order of the enum in oenv.h */ - const char *const xvg_formats[] = { "xmgrace", "xmgr", "none" }; + const char* const xvg_formats[] = { "xmgrace", "xmgr", "none" }; // Lambda function to test the (local) Flags parameter against a bit mask. - auto isFlagSet = [Flags](unsigned long bits) { - return (Flags & bits) == bits; - }; + auto isFlagSet = [Flags](unsigned long bits) { return (Flags & bits) == bits; }; try { - double tbegin = 0.0, tend = 0.0, tdelta = 0.0; - bool bBeginTimeSet = false, bEndTimeSet = false, bDtSet = false; - bool bView = false; - int xvgFormat = 0; - gmx::OptionsAdapter adapter(*argc, argv); - gmx::Options options; - gmx::OptionsBehaviorCollection behaviors(&options); - gmx::FileNameOptionManager fileOptManager; - - fileOptManager.disableInputOptionChecking( - isFlagSet(PCA_DISABLE_INPUT_FILE_CHECKING)); + double tbegin = 0.0, tend = 0.0, tdelta = 0.0; + bool bBeginTimeSet = false, bEndTimeSet = false, bDtSet = false; + bool bView = false; + int xvgFormat = 0; + gmx::OptionsAdapter adapter(*argc, argv); + gmx::Options options; + gmx::OptionsBehaviorCollection behaviors(&options); + gmx::FileNameOptionManager fileOptManager; + + fileOptManager.disableInputOptionChecking(isFlagSet(PCA_DISABLE_INPUT_FILE_CHECKING)); options.addManager(&fileOptManager); if (isFlagSet(PCA_CAN_SET_DEFFNM)) @@ -482,29 +481,22 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, if (isFlagSet(PCA_CAN_BEGIN)) { options.addOption( - gmx::DoubleOption("b") - .store(&tbegin).storeIsSet(&bBeginTimeSet).timeValue() - .description("Time of first frame to read from trajectory (default unit %t)")); + gmx::DoubleOption("b").store(&tbegin).storeIsSet(&bBeginTimeSet).timeValue().description("Time of first frame to read from trajectory (default unit %t)")); } if (isFlagSet(PCA_CAN_END)) { options.addOption( - gmx::DoubleOption("e") - .store(&tend).storeIsSet(&bEndTimeSet).timeValue() - .description("Time of last frame to read from trajectory (default unit %t)")); + gmx::DoubleOption("e").store(&tend).storeIsSet(&bEndTimeSet).timeValue().description("Time of last frame to read from trajectory (default unit %t)")); } if (isFlagSet(PCA_CAN_DT)) { - options.addOption( - gmx::DoubleOption("dt") - .store(&tdelta).storeIsSet(&bDtSet).timeValue() - .description("Only use frame when t MOD dt = first time (default unit %t)")); + options.addOption(gmx::DoubleOption("dt").store(&tdelta).storeIsSet(&bDtSet).timeValue().description( + "Only use frame when t MOD dt = first time (default unit %t)")); } - gmx::TimeUnit timeUnit = gmx::TimeUnit_Default; + gmx::TimeUnit timeUnit = gmx::TimeUnit_Default; if (isFlagSet(PCA_TIME_UNIT)) { - std::shared_ptr timeUnitBehavior( - new gmx::TimeUnitBehavior()); + std::shared_ptr timeUnitBehavior(new gmx::TimeUnitBehavior()); timeUnitBehavior->setTimeUnitStore(&timeUnit); timeUnitBehavior->setTimeUnitFromEnvironment(); timeUnitBehavior->addTimeUnitOption(&options, "tu"); @@ -512,10 +504,9 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, } if (isFlagSet(PCA_CAN_VIEW)) { - options.addOption( - gmx::BooleanOption("w").store(&bView) - .description("View output [REF].xvg[ref], [REF].xpm[ref], " - "[REF].eps[ref] and [REF].pdb[ref] files")); + options.addOption(gmx::BooleanOption("w").store(&bView).description( + "View output [REF].xvg[ref], [REF].xpm[ref], " + "[REF].eps[ref] and [REF].pdb[ref] files")); } bool bXvgr = false; @@ -527,9 +518,7 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, if (bXvgr) { options.addOption( - gmx::EnumIntOption("xvg").enumValue(xvg_formats) - .store(&xvgFormat) - .description("xvg plot formatting")); + gmx::EnumIntOption("xvg").enumValue(xvg_formats).store(&xvgFormat).description("xvg plot formatting")); } /* Now append the program specific arguments */ @@ -542,31 +531,30 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, adapter.pargsToOptions(&options, &pa[i]); } - const gmx::CommandLineHelpContext *context = - gmx::GlobalCommandLineHelpContext::get(); + const gmx::CommandLineHelpContext* context = gmx::GlobalCommandLineHelpContext::get(); if (context != nullptr) { GMX_RELEASE_ASSERT(gmx_node_rank() == 0, "Help output should be handled higher up and " "only get called only on the master rank"); gmx::CommandLineHelpWriter(options) - .setHelpText(gmx::constArrayRefFromArray(desc, ndesc)) - .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs)) - .writeHelp(*context); + .setHelpText(gmx::constArrayRefFromArray(desc, ndesc)) + .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs)) + .writeHelp(*context); return FALSE; } /* Now parse all the command-line options */ gmx::CommandLineParser(&options) - .skipUnknown(isFlagSet(PCA_NOEXIT_ON_ARGS)) - .allowPositionalArguments(isFlagSet(PCA_NOEXIT_ON_ARGS)) - .parse(argc, argv); + .skipUnknown(isFlagSet(PCA_NOEXIT_ON_ARGS)) + .allowPositionalArguments(isFlagSet(PCA_NOEXIT_ON_ARGS)) + .parse(argc, argv); behaviors.optionsFinishing(); options.finish(); /* set program name, command line, and default values for output options */ - output_env_init(oenv, gmx::getProgramContext(), - static_cast(timeUnit + 1), bView, // NOLINT(bugprone-misplaced-widening-cast) + output_env_init(oenv, gmx::getProgramContext(), static_cast(timeUnit + 1), + bView, // NOLINT(bugprone-misplaced-widening-cast) static_cast(xvgFormat + 1), 0); /* Extract Time info from arguments */ @@ -587,5 +575,5 @@ gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, return TRUE; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } diff --git a/src/gromacs/commandline/pargs.h b/src/gromacs/commandline/pargs.h index 28ae1442e5..2c2efd60fa 100644 --- a/src/gromacs/commandline/pargs.h +++ b/src/gromacs/commandline/pargs.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,7 +59,15 @@ struct gmx_output_env_t; /** Command line argument type. */ enum { - etINT, etINT64, etREAL, etTIME, etSTR, etBOOL, etRVEC, etENUM, etNR + etINT, + etINT64, + etREAL, + etTIME, + etSTR, + etBOOL, + etRVEC, + etENUM, + etNR }; /*! \brief @@ -70,11 +78,11 @@ enum typedef struct { /** Name of the argument (with leading dash included). */ - const char *option; + const char* option; /** Whether the argument is set (should be initialized to `FALSE`). */ - gmx_bool bSet; + gmx_bool bSet; /** Type of the argument (one of the enums in pargs.h). */ - int type; + int type; /*! \brief * Pointer to variable that is to receive the value. * @@ -83,20 +91,19 @@ typedef struct * changed. In other words, the initial value for the variable defines the * default value. */ - union - { + union { /*! \brief * Generic pointer for operations that do not need type information. * * Needs to be the first member to use initialized arrays. */ - void *v; + void* v; /** Integer value for etINT. */ - int *i; + int* i; /** Integer value for etINT64. */ - int64_t *is; + int64_t* is; /** Real value for etREAL and etTIME. */ - real *r; + real* r; /*! \brief * String value for etSTR and etENUM. * @@ -110,19 +117,19 @@ typedef struct * value. After the arguments are parsed, the first element in the array * points to the selected enum value (pointers will be equal). */ - const char **c; + const char** c; /** Boolean value for etBOOL. */ - gmx_bool *b; + gmx_bool* b; /** Vector value for etRVEC. */ - rvec *rv; - } u; + rvec* rv; + } u; /*! \brief * Description for the argument. * * If the string starts with `HIDDEN`, then the argument is hidden from * normal help listing and shell completions. */ - const char *desc; + const char* desc; } t_pargs; /*! \brief @@ -136,7 +143,7 @@ typedef struct * Note that the return value starts at one instead of zero: if the first enum * value is selected, this returns 1. */ -int nenum(const char *const enumc[]); +int nenum(const char* const enumc[]); /*! \brief * Returns value of an etINT option. @@ -148,7 +155,7 @@ int nenum(const char *const enumc[]); * * \p option must specify a valid argument in \p pa of the correct type. */ -int opt2parg_int(const char *option, int nparg, t_pargs pa[]); +int opt2parg_int(const char* option, int nparg, t_pargs pa[]); /*! \brief * Returns value of an etBOOL option. @@ -160,7 +167,7 @@ int opt2parg_int(const char *option, int nparg, t_pargs pa[]); * * \p option must specify a valid argument in \p pa of the correct type. */ -gmx_bool opt2parg_bool(const char *option, int nparg, t_pargs pa[]); +gmx_bool opt2parg_bool(const char* option, int nparg, t_pargs pa[]); /*! \brief * Returns value of an etREAL/etTIME option. @@ -172,7 +179,7 @@ gmx_bool opt2parg_bool(const char *option, int nparg, t_pargs pa[]); * * \p option must specify a valid argument in \p pa of the correct type. */ -real opt2parg_real(const char *option, int nparg, t_pargs pa[]); +real opt2parg_real(const char* option, int nparg, t_pargs pa[]); /*! \brief * Returns value of an etSTR option. @@ -184,7 +191,7 @@ real opt2parg_real(const char *option, int nparg, t_pargs pa[]); * * \p option must specify a valid argument in \p pa of the correct type. */ -const char *opt2parg_str(const char *option, int nparg, t_pargs pa[]); +const char* opt2parg_str(const char* option, int nparg, t_pargs pa[]); /*! \brief * Returns value of an etENUM option. @@ -196,7 +203,7 @@ const char *opt2parg_str(const char *option, int nparg, t_pargs pa[]); * * \p option must specify a valid argument in \p pa of the correct type. */ -const char *opt2parg_enum(const char *option, int nparg, t_pargs pa[]); +const char* opt2parg_enum(const char* option, int nparg, t_pargs pa[]); /*! \brief * Returns whether an argument has been set. @@ -208,27 +215,27 @@ const char *opt2parg_enum(const char *option, int nparg, t_pargs pa[]); * * \p option must specify a valid argument in \p pa. */ -gmx_bool opt2parg_bSet(const char *option, int nparg, const t_pargs *pa); +gmx_bool opt2parg_bSet(const char* option, int nparg, const t_pargs* pa); /** Add option -w to view output files (must be implemented in program). */ -#define PCA_CAN_VIEW (1<<5) +#define PCA_CAN_VIEW (1 << 5) /** Add option to set begin time for trajectory reading. */ -#define PCA_CAN_BEGIN (1<<6) +#define PCA_CAN_BEGIN (1 << 6) /** Add option to set end time for trajectory reading. */ -#define PCA_CAN_END (1<<7) +#define PCA_CAN_END (1 << 7) /** Add option to set time step for trajectory reading. */ -#define PCA_CAN_DT (1<<14) +#define PCA_CAN_DT (1 << 14) /** Add all options for trajectory time control. */ -#define PCA_CAN_TIME (PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_DT) +#define PCA_CAN_TIME (PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_DT) /** Add option -tu to set time unit for output. */ -#define PCA_TIME_UNIT (1<<15) +#define PCA_TIME_UNIT (1 << 15) /** Add option -deffnm to set default for all file options. */ -#define PCA_CAN_SET_DEFFNM (1<<10) +#define PCA_CAN_SET_DEFFNM (1 << 10) /** Do not raise a fatal error when invalid options are encountered. */ -#define PCA_NOEXIT_ON_ARGS (1<<11) +#define PCA_NOEXIT_ON_ARGS (1 << 11) /** Don't do any special processing for ffREAD files */ -#define PCA_DISABLE_INPUT_FILE_CHECKING (1<<17) +#define PCA_DISABLE_INPUT_FILE_CHECKING (1 << 17) /*! \brief * Parse command-line arguments. @@ -250,11 +257,18 @@ gmx_bool opt2parg_bSet(const char *option, int nparg, const t_pargs *pa); * * \see gmx_run_cmain(). */ -gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags, - int nfile, t_filenm fnm[], int npargs, t_pargs *pa, - int ndesc, const char **desc, - int nbugs, const char **bugs, - gmx_output_env_t **oenv); +gmx_bool parse_common_args(int* argc, + char* argv[], + unsigned long Flags, + int nfile, + t_filenm fnm[], + int npargs, + t_pargs* pa, + int ndesc, + const char** desc, + int nbugs, + const char** bugs, + gmx_output_env_t** oenv); /*! \} */ diff --git a/src/gromacs/commandline/shellcompletions.cpp b/src/gromacs/commandline/shellcompletions.cpp index 18b49bc812..d2b8256164 100644 --- a/src/gromacs/commandline/shellcompletions.cpp +++ b/src/gromacs/commandline/shellcompletions.cpp @@ -72,66 +72,64 @@ namespace class OptionsListWriter : public OptionsVisitor { - public: - const std::string &optionList() const { return optionList_; } +public: + const std::string& optionList() const { return optionList_; } - void visitSection(const OptionSectionInfo §ion) override + void visitSection(const OptionSectionInfo& section) override + { + OptionsIterator iterator(section); + iterator.acceptSections(this); + iterator.acceptOptions(this); + } + void visitOption(const OptionInfo& option) override + { + if (option.isHidden()) + { + return; + } + if (!optionList_.empty()) { - OptionsIterator iterator(section); - iterator.acceptSections(this); - iterator.acceptOptions(this); + optionList_.append("\\n"); } - void visitOption(const OptionInfo &option) override + optionList_.append("-"); + const BooleanOptionInfo* booleanOption = option.toType(); + if (booleanOption != nullptr && booleanOption->defaultValue()) { - if (option.isHidden()) - { - return; - } - if (!optionList_.empty()) - { - optionList_.append("\\n"); - } - optionList_.append("-"); - const BooleanOptionInfo *booleanOption - = option.toType(); - if (booleanOption != nullptr && booleanOption->defaultValue()) - { - optionList_.append("no"); - } - optionList_.append(option.name()); + optionList_.append("no"); } + optionList_.append(option.name()); + } - private: - std::string optionList_; +private: + std::string optionList_; }; class OptionCompletionWriter : public OptionsVisitor { - public: - explicit OptionCompletionWriter(TextWriter *out) : out_(*out) {} +public: + explicit OptionCompletionWriter(TextWriter* out) : out_(*out) {} - void visitSection(const OptionSectionInfo §ion) override - { - OptionsIterator iterator(section); - iterator.acceptSections(this); - iterator.acceptOptions(this); - } - void visitOption(const OptionInfo &option) override; + void visitSection(const OptionSectionInfo& section) override + { + OptionsIterator iterator(section); + iterator.acceptSections(this); + iterator.acceptOptions(this); + } + void visitOption(const OptionInfo& option) override; - private: - void writeOptionCompletion(const OptionInfo &option, - const std::string &completion); +private: + void writeOptionCompletion(const OptionInfo& option, const std::string& completion); - TextWriter &out_; + TextWriter& out_; }; -void OptionCompletionWriter::visitOption(const OptionInfo &option) +void OptionCompletionWriter::visitOption(const OptionInfo& option) { if (option.isHidden()) { return; } - const FileNameOptionInfo *fileOption = option.toType(); + const FileNameOptionInfo* fileOption = option.toType(); if (fileOption != nullptr) { if (fileOption->isDirectoryOption()) @@ -139,7 +137,7 @@ void OptionCompletionWriter::visitOption(const OptionInfo &option) writeOptionCompletion(option, "compgen -S ' ' -d $c"); return; } - const FileNameOptionInfo::ExtensionList &extensionList = fileOption->extensions(); + const FileNameOptionInfo::ExtensionList& extensionList = fileOption->extensions(); if (extensionList.empty()) { return; @@ -156,7 +154,7 @@ void OptionCompletionWriter::visitOption(const OptionInfo &option) writeOptionCompletion(option, completion); return; } - const StringOptionInfo *stringOption = option.toType(); + const StringOptionInfo* stringOption = option.toType(); if (stringOption != nullptr && stringOption->isEnumerated()) { std::string completion("compgen -S ' ' -W $'"); @@ -167,8 +165,7 @@ void OptionCompletionWriter::visitOption(const OptionInfo &option) } } -void OptionCompletionWriter::writeOptionCompletion( - const OptionInfo &option, const std::string &completion) +void OptionCompletionWriter::writeOptionCompletion(const OptionInfo& option, const std::string& completion) { std::string result(formatString("-%s) ", option.name().c_str())); if (option.maxValueCount() >= 0) @@ -181,40 +178,35 @@ void OptionCompletionWriter::writeOptionCompletion( out_.writeLine(result); } -} // namespace +} // namespace class ShellCompletionWriter::Impl { - public: - Impl(const std::string &binaryName, ShellCompletionFormat /*format*/) - : binaryName_(binaryName) - { - } +public: + Impl(const std::string& binaryName, ShellCompletionFormat /*format*/) : binaryName_(binaryName) + { + } - std::string completionFunctionName(const char *moduleName) const - { - std::string result = - formatString("_%s_%s_compl", binaryName_.c_str(), moduleName); - std::replace(result.begin(), result.end(), '-', '_'); - return result; - } + std::string completionFunctionName(const char* moduleName) const + { + std::string result = formatString("_%s_%s_compl", binaryName_.c_str(), moduleName); + std::replace(result.begin(), result.end(), '-', '_'); + return result; + } - std::string binaryName_; - // Never releases ownership. - std::unique_ptr file_; + std::string binaryName_; + // Never releases ownership. + std::unique_ptr file_; }; -ShellCompletionWriter::ShellCompletionWriter(const std::string &binaryName, - ShellCompletionFormat format) - : impl_(new Impl(binaryName, format)) +ShellCompletionWriter::ShellCompletionWriter(const std::string& binaryName, ShellCompletionFormat format) : + impl_(new Impl(binaryName, format)) { } -ShellCompletionWriter::~ShellCompletionWriter() -{ -} +ShellCompletionWriter::~ShellCompletionWriter() {} -TextWriter &ShellCompletionWriter::outputWriter() +TextWriter& ShellCompletionWriter::outputWriter() { return *impl_->file_; } @@ -224,22 +216,25 @@ void ShellCompletionWriter::startCompletions() impl_->file_ = std::make_unique(impl_->binaryName_ + "-completion.bash"); } -void ShellCompletionWriter::writeModuleCompletions( - const char *moduleName, - const Options &options) +void ShellCompletionWriter::writeModuleCompletions(const char* moduleName, const Options& options) { - TextWriter &out = *impl_->file_; + TextWriter& out = *impl_->file_; out.writeLine(formatString("%s() {", impl_->completionFunctionName(moduleName).c_str())); out.writeLine("local IFS=$'\\n'"); out.writeLine("local c=${COMP_WORDS[COMP_CWORD]}"); out.writeLine("local n"); - out.writeLine("for ((n=1;nfile_->writeLine("_" + impl_->binaryName_ + "_compl() {"); impl_->file_->writeLine("local i c m"); @@ -263,9 +257,8 @@ void ShellCompletionWriter::writeWrapperCompletions( impl_->file_->writeLine("c=${COMP_WORDS[COMP_CWORD]}"); OptionsListWriter lister; lister.visitSection(options.rootSection()); - std::string completions(lister.optionList()); - for (ModuleNameList::const_iterator i = modules.begin(); - i != modules.end(); ++i) + std::string completions(lister.optionList()); + for (ModuleNameList::const_iterator i = modules.begin(); i != modules.end(); ++i) { completions.append("\\n"); completions.append(*i); @@ -277,12 +270,11 @@ void ShellCompletionWriter::writeWrapperCompletions( impl_->file_->writeLine("COMP_WORDS=( \"${COMP_WORDS[@]}\" )"); impl_->file_->writeLine("COMP_CWORD=$((COMP_CWORD-i))"); impl_->file_->writeLine("case \"$m\" in"); - for (ModuleNameList::const_iterator i = modules.begin(); - i != modules.end(); ++i) + for (ModuleNameList::const_iterator i = modules.begin(); i != modules.end(); ++i) { - const char *const name = i->c_str(); - impl_->file_->writeLine(formatString("%s) %s ;;", name, - impl_->completionFunctionName(name).c_str())); + const char* const name = i->c_str(); + impl_->file_->writeLine( + formatString("%s) %s ;;", name, impl_->completionFunctionName(name).c_str())); } impl_->file_->writeLine("esac }"); } diff --git a/src/gromacs/commandline/shellcompletions.h b/src/gromacs/commandline/shellcompletions.h index 28637003e1..28db8f9bd5 100644 --- a/src/gromacs/commandline/shellcompletions.h +++ b/src/gromacs/commandline/shellcompletions.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,7 +63,7 @@ class TextWriter; //! Output format for ShellCompletionWriter. enum ShellCompletionFormat { - eShellCompletionFormat_Bash //!< Shell completions for bash. + eShellCompletionFormat_Bash //!< Shell completions for bash. }; //! \} @@ -71,26 +71,23 @@ enum ShellCompletionFormat class ShellCompletionWriter { - public: - typedef std::vector ModuleNameList; +public: + typedef std::vector ModuleNameList; - ShellCompletionWriter(const std::string &binaryName, - ShellCompletionFormat format); - ~ShellCompletionWriter(); + ShellCompletionWriter(const std::string& binaryName, ShellCompletionFormat format); + ~ShellCompletionWriter(); - TextWriter &outputWriter(); + TextWriter& outputWriter(); - void startCompletions(); - void writeModuleCompletions(const char *moduleName, - const Options &options); - void writeWrapperCompletions(const ModuleNameList &modules, - const Options &options); - void finishCompletions(); + void startCompletions(); + void writeModuleCompletions(const char* moduleName, const Options& options); + void writeWrapperCompletions(const ModuleNameList& modules, const Options& options); + void finishCompletions(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/commandline/tests/cmdlinehelpmodule.cpp b/src/gromacs/commandline/tests/cmdlinehelpmodule.cpp index a7cc763f63..b7907462df 100644 --- a/src/gromacs/commandline/tests/cmdlinehelpmodule.cpp +++ b/src/gromacs/commandline/tests/cmdlinehelpmodule.cpp @@ -68,9 +68,7 @@ typedef gmx::test::CommandLineModuleManagerTestBase CommandLineHelpModuleTest; TEST_F(CommandLineHelpModuleTest, PrintsGeneralHelp) { - const char *const cmdline[] = { - "test" - }; + const char* const cmdline[] = { "test" }; CommandLine args(cmdline); initManager(args, "test"); addModule("module", "First module"); @@ -84,13 +82,11 @@ TEST_F(CommandLineHelpModuleTest, PrintsGeneralHelp) TEST_F(CommandLineHelpModuleTest, PrintsHelpOnTopic) { - const char *const cmdline[] = { - "test", "help", "topic" - }; + const char* const cmdline[] = { "test", "help", "topic" }; CommandLine args(cmdline); initManager(args, "test"); addModule("module", "First module"); - MockHelpTopic &topic = addHelpTopic("topic", "Test topic"); + MockHelpTopic& topic = addHelpTopic("topic", "Test topic"); topic.addSubTopic("sub1", "Subtopic 1", ""); topic.addSubTopic("sub2", "Subtopic 2", ""); using ::testing::_; @@ -106,33 +102,25 @@ TEST_F(CommandLineHelpModuleTest, PrintsHelpOnTopic) * * \ingroup module_commandline */ -void initOptionsBasic(gmx::IOptionsContainer *options, - gmx::ICommandLineOptionsModuleSettings *settings) +void initOptionsBasic(gmx::IOptionsContainer* options, gmx::ICommandLineOptionsModuleSettings* settings) { - const char *const desc[] = { - "Sample description", - "for testing [THISMODULE]." - }; + const char* const desc[] = { "Sample description", "for testing [THISMODULE]." }; settings->setHelpText(desc); - const char *const bug[] = { - "Known issue for [THISMODULE].", - "With another bug for [THISMODULE]." - }; + const char* const bug[] = { "Known issue for [THISMODULE].", + "With another bug for [THISMODULE]." }; settings->setBugText(bug); options->addOption(gmx::IntegerOption("int").description("Integer option")); } TEST_F(CommandLineHelpModuleTest, ExportsHelp) { - const char *const cmdline[] = { - "test", "help", "-export", "rst" - }; + const char* const cmdline[] = { "test", "help", "-export", "rst" }; // TODO: Find a more elegant solution, or get rid of the links.dat altogether. gmx::TextWriter::writeFileFromString("links.dat", ""); - CommandLine args(cmdline); + CommandLine args(cmdline); initManager(args, "test"); - MockOptionsModule &mod1 = addOptionsModule("module", "First module"); - MockOptionsModule &mod2 = addOptionsModule("other", "Second module"); + MockOptionsModule& mod1 = addOptionsModule("module", "First module"); + MockOptionsModule& mod2 = addOptionsModule("other", "Second module"); { gmx::CommandLineModuleGroup group = manager().addModuleGroup("Group 1"); group.addModule("module"); @@ -141,11 +129,11 @@ TEST_F(CommandLineHelpModuleTest, ExportsHelp) gmx::CommandLineModuleGroup group = manager().addModuleGroup("Group 2"); group.addModule("other"); } - MockHelpTopic &topic1 = addHelpTopic("topic1", "Test topic"); - MockHelpTopic &sub1 = topic1.addSubTopic("sub1", "Subtopic 1", "Sub text"); - MockHelpTopic &sub2 = topic1.addSubTopic("sub2", "Subtopic 2", "Sub text"); - MockHelpTopic &sub3 = topic1.addSubTopic("other", "Out-of-order subtopic", "Sub text"); - MockHelpTopic &topic2 = addHelpTopic("topic2", "Another topic"); + MockHelpTopic& topic1 = addHelpTopic("topic1", "Test topic"); + MockHelpTopic& sub1 = topic1.addSubTopic("sub1", "Subtopic 1", "Sub text"); + MockHelpTopic& sub2 = topic1.addSubTopic("sub2", "Subtopic 2", "Sub text"); + MockHelpTopic& sub3 = topic1.addSubTopic("other", "Out-of-order subtopic", "Sub text"); + MockHelpTopic& topic2 = addHelpTopic("topic2", "Another topic"); using ::testing::_; using ::testing::Invoke; EXPECT_CALL(mod1, initOptions(_, _)).WillOnce(Invoke(&initOptionsBasic)); diff --git a/src/gromacs/commandline/tests/cmdlinehelpwriter.cpp b/src/gromacs/commandline/tests/cmdlinehelpwriter.cpp index 0fc925d285..3630ed1ced 100644 --- a/src/gromacs/commandline/tests/cmdlinehelpwriter.cpp +++ b/src/gromacs/commandline/tests/cmdlinehelpwriter.cpp @@ -67,20 +67,20 @@ namespace class CommandLineHelpWriterTest : public ::gmx::test::StringTestBase { - public: - CommandLineHelpWriterTest() : bHidden_(false) {} +public: + CommandLineHelpWriterTest() : bHidden_(false) {} - void checkHelp(gmx::CommandLineHelpWriter *writer); + void checkHelp(gmx::CommandLineHelpWriter* writer); - bool bHidden_; + bool bHidden_; }; -void CommandLineHelpWriterTest::checkHelp(gmx::CommandLineHelpWriter *writer) +void CommandLineHelpWriterTest::checkHelp(gmx::CommandLineHelpWriter* writer) { gmx::StringOutputStream stream; gmx::TextWriter streamWriter(&stream); - gmx::CommandLineHelpContext context(&streamWriter, gmx::eHelpOutputFormat_Console, - nullptr, "test"); + gmx::CommandLineHelpContext context(&streamWriter, gmx::eHelpOutputFormat_Console, nullptr, + "test"); context.setShowHidden(bHidden_); writer->writeHelp(context); stream.close(); @@ -102,51 +102,49 @@ TEST_F(CommandLineHelpWriterTest, HandlesOptionTypes) using namespace gmx; Options options; - options.addOption(BooleanOption("bool").description("Boolean option") - .defaultValue(true)); - options.addOption(BooleanOption("hidden").description("Hidden option") - .hidden().defaultValue(true)); - options.addOption(IntegerOption("int").description("Integer option") - .defaultValue(2)); - ivec intvec = {1, 2, 3}; - options.addOption(IntegerOption("ivec").description("Integer vector option") - .vector().store(intvec)); - options.addOption(DoubleOption("double").description("Double option") - .defaultValue(2.5)); - dvec dblvec = {1.1, 2.3, 3.2}; - options.addOption(DoubleOption("dvec").description("Double vector option") - .vector().store(dblvec)); - options.addOption(DoubleOption("time").description("Time option (%t)") - .timeValue().defaultValue(10.0)); - options.addOption(StringOption("string").description("String option") - .defaultValue("test")); - const char * const enumValues[] = { "no", "opt1", "opt2" }; - options.addOption(StringOption("enum").description("Enum option") - .enumValue(enumValues).defaultEnumIndex(0)); - options.addOption(EnumIntOption("ienum").description("Enum option") - .enumValue(enumValues).defaultValue(1)); + options.addOption(BooleanOption("bool").description("Boolean option").defaultValue(true)); + options.addOption(BooleanOption("hidden").description("Hidden option").hidden().defaultValue(true)); + options.addOption(IntegerOption("int").description("Integer option").defaultValue(2)); + ivec intvec = { 1, 2, 3 }; + options.addOption(IntegerOption("ivec").description("Integer vector option").vector().store(intvec)); + options.addOption(DoubleOption("double").description("Double option").defaultValue(2.5)); + dvec dblvec = { 1.1, 2.3, 3.2 }; + options.addOption(DoubleOption("dvec").description("Double vector option").vector().store(dblvec)); + options.addOption(DoubleOption("time").description("Time option (%t)").timeValue().defaultValue(10.0)); + options.addOption(StringOption("string").description("String option").defaultValue("test")); + const char* const enumValues[] = { "no", "opt1", "opt2" }; + options.addOption( + StringOption("enum").description("Enum option").enumValue(enumValues).defaultEnumIndex(0)); + options.addOption( + EnumIntOption("ienum").description("Enum option").enumValue(enumValues).defaultValue(1)); std::string filename; options.addOption(FileNameOption("f") - .description("Input file description") - .filetype(eftTrajectory).inputFile().required() - .defaultBasename("traj")); + .description("Input file description") + .filetype(eftTrajectory) + .inputFile() + .required() + .defaultBasename("traj")); options.addOption(FileNameOption("mult") - .description("Multiple file description") - .filetype(eftTrajectory).inputFile().multiValue() - .defaultBasename("traj")); + .description("Multiple file description") + .filetype(eftTrajectory) + .inputFile() + .multiValue() + .defaultBasename("traj")); options.addOption(FileNameOption("lib") - .description("Library file description") - .filetype(eftGenericData).inputFile().libraryFile() - .defaultBasename("libdata")); + .description("Library file description") + .filetype(eftGenericData) + .inputFile() + .libraryFile() + .defaultBasename("libdata")); options.addOption(FileNameOption("io") - .store(&filename) - .description("Input/Output file description") - .filetype(eftGenericData).inputOutputFile() - .defaultBasename("inout")); - options.addOption(FileNameOption("o") - .description("Output file description") - .filetype(eftPlot).outputFile()); + .store(&filename) + .description("Input/Output file description") + .filetype(eftGenericData) + .inputOutputFile() + .defaultBasename("inout")); + options.addOption( + FileNameOption("o").description("Output file description").filetype(eftPlot).outputFile()); CommandLineHelpWriter writer(options); bHidden_ = true; @@ -154,8 +152,10 @@ TEST_F(CommandLineHelpWriterTest, HandlesOptionTypes) } //! Enum value for testing. -enum TestEnum { - eFoo, eBar +enum TestEnum +{ + eFoo, + eBar }; /* @@ -168,27 +168,24 @@ TEST_F(CommandLineHelpWriterTest, HandlesDefaultValuesFromVariables) Options options; - bool bValue = true; - options.addOption(BooleanOption("bool").description("Boolean option") - .store(&bValue)); + bool bValue = true; + options.addOption(BooleanOption("bool").description("Boolean option").store(&bValue)); int ivalue = 3; - options.addOption(IntegerOption("int").description("Integer option") - .store(&ivalue)); + options.addOption(IntegerOption("int").description("Integer option").store(&ivalue)); - int iavalue[] = {2, 3}; - options.addOption(IntegerOption("int2").description("Integer 2-value option") - .store(iavalue).valueCount(2)); + int iavalue[] = { 2, 3 }; + options.addOption( + IntegerOption("int2").description("Integer 2-value option").store(iavalue).valueCount(2)); std::vector svalues; svalues.emplace_back("foo"); - options.addOption(StringOption("str").description("String option") - .storeVector(&svalues).multiValue()); + options.addOption(StringOption("str").description("String option").storeVector(&svalues).multiValue()); TestEnum evalue = eBar; - const char *const allowed[] = { "foo", "bar" }; - options.addOption(EnumOption("enum").description("Enum option") - .enumValue(allowed).store(&evalue)); + const char* const allowed[] = { "foo", "bar" }; + options.addOption( + EnumOption("enum").description("Enum option").enumValue(allowed).store(&evalue)); CommandLineHelpWriter writer(options); checkHelp(&writer); @@ -200,31 +197,40 @@ TEST_F(CommandLineHelpWriterTest, HandlesDefaultValuesFromVariables) */ TEST_F(CommandLineHelpWriterTest, HandlesLongFileOptions) { - using gmx::FileNameOption; using gmx::eftGenericData; using gmx::eftTrajectory; + using gmx::FileNameOption; gmx::Options options; options.addOption(FileNameOption("f") - .description("File name option with a long value") - .filetype(eftTrajectory).inputFile().required() - .defaultBasename("path/to/long/trajectory/name")); + .description("File name option with a long value") + .filetype(eftTrajectory) + .inputFile() + .required() + .defaultBasename("path/to/long/trajectory/name")); options.addOption(FileNameOption("f2") - .description("File name option with a long value") - .filetype(eftTrajectory).inputFile().required() - .defaultBasename("path/to/long/trajectory")); + .description("File name option with a long value") + .filetype(eftTrajectory) + .inputFile() + .required() + .defaultBasename("path/to/long/trajectory")); options.addOption(FileNameOption("lib") - .description("File name option with a long value and type") - .filetype(eftTrajectory).inputFile().libraryFile() - .defaultBasename("path/to/long/trajectory/name")); + .description("File name option with a long value and type") + .filetype(eftTrajectory) + .inputFile() + .libraryFile() + .defaultBasename("path/to/long/trajectory/name")); options.addOption(FileNameOption("longfileopt") - .description("File name option with a long name") - .filetype(eftGenericData).inputFile() - .defaultBasename("deffile")); + .description("File name option with a long name") + .filetype(eftGenericData) + .inputFile() + .defaultBasename("deffile")); options.addOption(FileNameOption("longfileopt2") - .description("File name option with multiple long fields") - .filetype(eftGenericData).inputFile().libraryFile() - .defaultBasename("path/to/long/file/name")); + .description("File name option with multiple long fields") + .filetype(eftGenericData) + .inputFile() + .libraryFile() + .defaultBasename("path/to/long/file/name")); gmx::CommandLineHelpWriter writer(options); checkHelp(&writer); @@ -241,20 +247,19 @@ TEST_F(CommandLineHelpWriterTest, HandlesLongOptions) using gmx::StringOption; gmx::Options options; - options.addOption(BooleanOption("longboolean") - .description("Boolean option with a long name") - .defaultValue(true)); - dvec dblvec = {1.135, 2.32, 3.2132}; - options.addOption(DoubleOption("dvec").description("Double vector option") - .vector().store(dblvec)); + options.addOption( + BooleanOption("longboolean").description("Boolean option with a long name").defaultValue(true)); + dvec dblvec = { 1.135, 2.32, 3.2132 }; + options.addOption(DoubleOption("dvec").description("Double vector option").vector().store(dblvec)); std::vector values; values.emplace_back("A very long string value that overflows even the description column"); - values.emplace_back("Another very long string value that overflows even the description column"); + values.emplace_back( + "Another very long string value that overflows even the description column"); options.addOption(StringOption("string") - .description("String option with very long values (may " - "be less relevant with selections having " - "their own option type)") - .storeVector(&values)); + .description("String option with very long values (may " + "be less relevant with selections having " + "their own option type)") + .storeVector(&values)); gmx::CommandLineHelpWriter writer(options); checkHelp(&writer); @@ -299,8 +304,8 @@ TEST_F(CommandLineHelpWriterTest, HandlesOptionGroups) using gmx::IntegerOption; gmx::Options options; - gmx::IOptionsContainer &group1 = options.addGroup(); - gmx::IOptionsContainer &group2 = options.addGroup(); + gmx::IOptionsContainer& group1 = options.addGroup(); + gmx::IOptionsContainer& group2 = options.addGroup(); group2.addOption(IntegerOption("sub2").description("Option in group 2")); group1.addOption(IntegerOption("sub11").description("Option in group 1")); options.addOption(IntegerOption("main").description("Option in root group")); @@ -315,15 +320,11 @@ TEST_F(CommandLineHelpWriterTest, HandlesOptionGroups) */ TEST_F(CommandLineHelpWriterTest, HandlesHelpText) { - const char *const help[] = { - "Help text", - "for testing." - }; + const char* const help[] = { "Help text", "for testing." }; using gmx::IntegerOption; gmx::Options options; - options.addOption(IntegerOption("int").description("Integer option") - .defaultValue(2)); + options.addOption(IntegerOption("int").description("Integer option").defaultValue(2)); gmx::CommandLineHelpWriter writer(options); writer.setHelpText(help); @@ -335,15 +336,11 @@ TEST_F(CommandLineHelpWriterTest, HandlesHelpText) */ TEST_F(CommandLineHelpWriterTest, HandlesKnownIssues) { - const char *const bugs[] = { - "This is a bug.", - "And this is another one." - }; + const char* const bugs[] = { "This is a bug.", "And this is another one." }; using gmx::IntegerOption; gmx::Options options; - options.addOption(IntegerOption("int").description("Integer option") - .defaultValue(2)); + options.addOption(IntegerOption("int").description("Integer option").defaultValue(2)); gmx::CommandLineHelpWriter writer(options); writer.setKnownIssues(bugs); diff --git a/src/gromacs/commandline/tests/cmdlinemodulemanager.cpp b/src/gromacs/commandline/tests/cmdlinemodulemanager.cpp index 6558a8da8a..8c495a6940 100644 --- a/src/gromacs/commandline/tests/cmdlinemodulemanager.cpp +++ b/src/gromacs/commandline/tests/cmdlinemodulemanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,19 +61,16 @@ typedef gmx::test::CommandLineModuleManagerTestBase CommandLineModuleManagerTest TEST_F(CommandLineModuleManagerTest, RunsModule) { - const char *const cmdline[] = { - "test", "module", "-flag", "yes" - }; + const char* const cmdline[] = { "test", "module", "-flag", "yes" }; CommandLine args(cmdline); initManager(args, "test"); - MockModule &mod1 = addModule("module", "First module"); + MockModule& mod1 = addModule("module", "First module"); addModule("other", "Second module"); using ::testing::_; using ::testing::Args; using ::testing::ElementsAreArray; EXPECT_CALL(mod1, init(_)); - EXPECT_CALL(mod1, run(_, _)) - .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1))); + EXPECT_CALL(mod1, run(_, _)).With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1))); int rc = 0; ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv())); ASSERT_EQ(0, rc); @@ -81,12 +78,10 @@ TEST_F(CommandLineModuleManagerTest, RunsModule) TEST_F(CommandLineModuleManagerTest, RunsModuleHelp) { - const char *const cmdline[] = { - "test", "help", "module" - }; + const char* const cmdline[] = { "test", "help", "module" }; CommandLine args(cmdline); initManager(args, "test"); - MockModule &mod1 = addModule("module", "First module"); + MockModule& mod1 = addModule("module", "First module"); addModule("other", "Second module"); using ::testing::_; EXPECT_CALL(mod1, writeHelp(_)); @@ -98,12 +93,10 @@ TEST_F(CommandLineModuleManagerTest, RunsModuleHelp) TEST_F(CommandLineModuleManagerTest, RunsModuleHelpAfterQuiet) { - const char *const cmdline[] = { - "test", "-quiet", "help", "module" - }; + const char* const cmdline[] = { "test", "-quiet", "help", "module" }; CommandLine args(cmdline); initManager(args, "test"); - MockModule &mod1 = addModule("module", "First module"); + MockModule& mod1 = addModule("module", "First module"); addModule("other", "Second module"); using ::testing::_; EXPECT_CALL(mod1, writeHelp(_)); @@ -115,12 +108,10 @@ TEST_F(CommandLineModuleManagerTest, RunsModuleHelpAfterQuiet) TEST_F(CommandLineModuleManagerTest, RunsModuleHelpWithDashH) { - const char *const cmdline[] = { - "test", "module", "-h" - }; + const char* const cmdline[] = { "test", "module", "-h" }; CommandLine args(cmdline); initManager(args, "test"); - MockModule &mod1 = addModule("module", "First module"); + MockModule& mod1 = addModule("module", "First module"); addModule("other", "Second module"); using ::testing::_; EXPECT_CALL(mod1, writeHelp(_)); @@ -132,12 +123,10 @@ TEST_F(CommandLineModuleManagerTest, RunsModuleHelpWithDashH) TEST_F(CommandLineModuleManagerTest, RunsModuleHelpWithDashHWithSingleModule) { - const char *const cmdline[] = { - "g_module", "-h" - }; + const char* const cmdline[] = { "g_module", "-h" }; CommandLine args(cmdline); initManager(args, "g_module"); - MockModule mod(nullptr, nullptr); + MockModule mod(nullptr, nullptr); manager().setSingleModule(&mod); using ::testing::_; EXPECT_CALL(mod, writeHelp(_)); @@ -149,19 +138,16 @@ TEST_F(CommandLineModuleManagerTest, RunsModuleHelpWithDashHWithSingleModule) TEST_F(CommandLineModuleManagerTest, HandlesConflictingBinaryAndModuleNames) { - const char *const cmdline[] = { - "test", "test", "-flag", "yes" - }; + const char* const cmdline[] = { "test", "test", "-flag", "yes" }; CommandLine args(cmdline); initManager(args, "test"); - MockModule &mod1 = addModule("test", "Test module"); + MockModule& mod1 = addModule("test", "Test module"); addModule("other", "Second module"); using ::testing::_; using ::testing::Args; using ::testing::ElementsAreArray; EXPECT_CALL(mod1, init(_)); - EXPECT_CALL(mod1, run(_, _)) - .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1))); + EXPECT_CALL(mod1, run(_, _)).With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1))); int rc = 0; ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv())); ASSERT_EQ(0, rc); diff --git a/src/gromacs/commandline/tests/cmdlinemodulemanagertest.cpp b/src/gromacs/commandline/tests/cmdlinemodulemanagertest.cpp index a868029462..fe4077ba18 100644 --- a/src/gromacs/commandline/tests/cmdlinemodulemanagertest.cpp +++ b/src/gromacs/commandline/tests/cmdlinemodulemanagertest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,40 +72,34 @@ namespace * * \ingroup module_commandline */ -void disableNice(gmx::CommandLineModuleSettings *settings) +void disableNice(gmx::CommandLineModuleSettings* settings) { settings->setDefaultNiceLevel(0); } -} // namespace +} // namespace /******************************************************************** * MockModule */ -MockModule::MockModule(const char *name, const char *description) - : name_(name), descr_(description) +MockModule::MockModule(const char* name, const char* description) : name_(name), descr_(description) { using ::testing::_; using ::testing::Invoke; - ON_CALL(*this, init(_)) - .WillByDefault(Invoke(&disableNice)); - ON_CALL(*this, writeHelp(_)) - .WillByDefault(Invoke(this, &MockModule::checkHelpContext)); + ON_CALL(*this, init(_)).WillByDefault(Invoke(&disableNice)); + ON_CALL(*this, writeHelp(_)).WillByDefault(Invoke(this, &MockModule::checkHelpContext)); } -MockModule::~MockModule() -{ -} +MockModule::~MockModule() {} -void MockModule::checkHelpContext(const gmx::CommandLineHelpContext &context) const +void MockModule::checkHelpContext(const gmx::CommandLineHelpContext& context) const { EXPECT_EQ(expectedDisplayName_, context.moduleDisplayName()); gmx::TextLineWrapperSettings settings; std::string moduleName = - context.writerContext().substituteMarkupAndWrapToString( - settings, "[THISMODULE]"); + context.writerContext().substituteMarkupAndWrapToString(settings, "[THISMODULE]"); EXPECT_EQ(expectedDisplayName_, moduleName); } @@ -117,13 +111,10 @@ MockOptionsModule::MockOptionsModule() { using ::testing::_; using ::testing::Invoke; - ON_CALL(*this, init(_)) - .WillByDefault(Invoke(&disableNice)); + ON_CALL(*this, init(_)).WillByDefault(Invoke(&disableNice)); } -MockOptionsModule::~MockOptionsModule() -{ -} +MockOptionsModule::~MockOptionsModule() {} /******************************************************************** * Test fixture for the tests @@ -131,63 +122,54 @@ MockOptionsModule::~MockOptionsModule() class CommandLineModuleManagerTestBase::Impl { - public: - Impl(const CommandLine &args, const char *realBinaryName) - : programContext_(args.argc(), args.argv()), - manager_(realBinaryName, &programContext_) - { - manager_.setQuiet(true); - manager_.setOutputRedirector(&redirector_); - } - - TestFileOutputRedirector redirector_; - CommandLineProgramContext programContext_; - CommandLineModuleManager manager_; +public: + Impl(const CommandLine& args, const char* realBinaryName) : + programContext_(args.argc(), args.argv()), + manager_(realBinaryName, &programContext_) + { + manager_.setQuiet(true); + manager_.setOutputRedirector(&redirector_); + } + + TestFileOutputRedirector redirector_; + CommandLineProgramContext programContext_; + CommandLineModuleManager manager_; }; -CommandLineModuleManagerTestBase::CommandLineModuleManagerTestBase() - : impl_(nullptr) -{ -} +CommandLineModuleManagerTestBase::CommandLineModuleManagerTestBase() : impl_(nullptr) {} -CommandLineModuleManagerTestBase::~CommandLineModuleManagerTestBase() -{ -} +CommandLineModuleManagerTestBase::~CommandLineModuleManagerTestBase() {} -void CommandLineModuleManagerTestBase::initManager( - const CommandLine &args, const char *realBinaryName) +void CommandLineModuleManagerTestBase::initManager(const CommandLine& args, const char* realBinaryName) { GMX_RELEASE_ASSERT(impl_ == nullptr, "initManager() called more than once in test"); impl_.reset(new Impl(args, realBinaryName)); } -MockModule & -CommandLineModuleManagerTestBase::addModule(const char *name, const char *description) +MockModule& CommandLineModuleManagerTestBase::addModule(const char* name, const char* description) { - MockModule *module = new MockModule(name, description); + MockModule* module = new MockModule(name, description); manager().addModule(gmx::CommandLineModulePointer(module)); return *module; } -MockOptionsModule & -CommandLineModuleManagerTestBase::addOptionsModule(const char *name, const char *description) +MockOptionsModule& CommandLineModuleManagerTestBase::addOptionsModule(const char* name, const char* description) { - std::unique_ptr modulePtr(new MockOptionsModule()); - MockOptionsModule *module = modulePtr.get(); - gmx::ICommandLineOptionsModule::registerModuleDirect( - &manager(), name, description, std::move(modulePtr)); + std::unique_ptr modulePtr(new MockOptionsModule()); + MockOptionsModule* module = modulePtr.get(); + gmx::ICommandLineOptionsModule::registerModuleDirect(&manager(), name, description, + std::move(modulePtr)); return *module; } -MockHelpTopic & -CommandLineModuleManagerTestBase::addHelpTopic(const char *name, const char *title) +MockHelpTopic& CommandLineModuleManagerTestBase::addHelpTopic(const char* name, const char* title) { - MockHelpTopic *topic = new MockHelpTopic(name, title, "Help text"); + MockHelpTopic* topic = new MockHelpTopic(name, title, "Help text"); manager().addHelpTopic(gmx::HelpTopicPointer(topic)); return *topic; } -CommandLineModuleManager &CommandLineModuleManagerTestBase::manager() +CommandLineModuleManager& CommandLineModuleManagerTestBase::manager() { GMX_RELEASE_ASSERT(impl_ != nullptr, "initManager() not called"); return impl_->manager_; diff --git a/src/gromacs/commandline/tests/cmdlinemodulemanagertest.h b/src/gromacs/commandline/tests/cmdlinemodulemanagertest.h index 56e82d17fb..3647a32ee9 100644 --- a/src/gromacs/commandline/tests/cmdlinemodulemanagertest.h +++ b/src/gromacs/commandline/tests/cmdlinemodulemanagertest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,31 +69,28 @@ class TestFileOutputRedirector; */ class MockModule : public gmx::ICommandLineModule { - public: - //! Creates a mock module with the given name and description. - MockModule(const char *name, const char *description); - ~MockModule() override; - - const char *name() const override { return name_; } - const char *shortDescription() const override { return descr_; } - - MOCK_METHOD1(init, void(gmx::CommandLineModuleSettings *settings)); - MOCK_METHOD2(run, int(int argc, char *argv[])); - MOCK_CONST_METHOD1(writeHelp, void(const gmx::CommandLineHelpContext &context)); - - //! Sets the expected display name for writeHelp() calls. - void setExpectedDisplayName(const char *expected) - { - expectedDisplayName_ = expected; - } - - private: - //! Checks the context passed to writeHelp(). - void checkHelpContext(const gmx::CommandLineHelpContext &context) const; - - const char *name_; - const char *descr_; - std::string expectedDisplayName_; +public: + //! Creates a mock module with the given name and description. + MockModule(const char* name, const char* description); + ~MockModule() override; + + const char* name() const override { return name_; } + const char* shortDescription() const override { return descr_; } + + MOCK_METHOD1(init, void(gmx::CommandLineModuleSettings* settings)); + MOCK_METHOD2(run, int(int argc, char* argv[])); + MOCK_CONST_METHOD1(writeHelp, void(const gmx::CommandLineHelpContext& context)); + + //! Sets the expected display name for writeHelp() calls. + void setExpectedDisplayName(const char* expected) { expectedDisplayName_ = expected; } + +private: + //! Checks the context passed to writeHelp(). + void checkHelpContext(const gmx::CommandLineHelpContext& context) const; + + const char* name_; + const char* descr_; + std::string expectedDisplayName_; }; /*! \internal \brief @@ -103,14 +100,15 @@ class MockModule : public gmx::ICommandLineModule */ class MockOptionsModule : public gmx::ICommandLineOptionsModule { - public: - MockOptionsModule(); - ~MockOptionsModule() override; - - MOCK_METHOD1(init, void(gmx::CommandLineModuleSettings *settings)); - MOCK_METHOD2(initOptions, void(gmx::IOptionsContainer *options, gmx::ICommandLineOptionsModuleSettings *settings)); - MOCK_METHOD0(optionsFinished, void()); - MOCK_METHOD0(run, int()); +public: + MockOptionsModule(); + ~MockOptionsModule() override; + + MOCK_METHOD1(init, void(gmx::CommandLineModuleSettings* settings)); + MOCK_METHOD2(initOptions, + void(gmx::IOptionsContainer* options, gmx::ICommandLineOptionsModuleSettings* settings)); + MOCK_METHOD0(optionsFinished, void()); + MOCK_METHOD0(run, int()); }; /*! \internal \brief @@ -120,40 +118,40 @@ class MockOptionsModule : public gmx::ICommandLineOptionsModule */ class CommandLineModuleManagerTestBase : public gmx::test::StringTestBase { - public: - CommandLineModuleManagerTestBase(); - ~CommandLineModuleManagerTestBase() override; - - //! Creates the manager to run the given command line. - void initManager(const CommandLine &args, const char *realBinaryName); - //! Adds a mock module to the manager. - MockModule &addModule(const char *name, const char *description); - //! Adds a mock module using gmx::Options to the manager. - MockOptionsModule &addOptionsModule(const char *name, const char *description); - //! Adds a mock help topic to the manager. - MockHelpTopic &addHelpTopic(const char *name, const char *title); - - /*! \brief - * Returns the manager for this test. - * - * initManager() must have been called. - */ - CommandLineModuleManager &manager(); - - /*! \brief - * Checks all output from the manager using reference data. - * - * Both output to `stdout` and to files is checked. - * - * The manager is put into quiet mode by default, so the manager will - * only print out information if, e.g., help is explicitly requested. - */ - void checkRedirectedOutput(); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + CommandLineModuleManagerTestBase(); + ~CommandLineModuleManagerTestBase() override; + + //! Creates the manager to run the given command line. + void initManager(const CommandLine& args, const char* realBinaryName); + //! Adds a mock module to the manager. + MockModule& addModule(const char* name, const char* description); + //! Adds a mock module using gmx::Options to the manager. + MockOptionsModule& addOptionsModule(const char* name, const char* description); + //! Adds a mock help topic to the manager. + MockHelpTopic& addHelpTopic(const char* name, const char* title); + + /*! \brief + * Returns the manager for this test. + * + * initManager() must have been called. + */ + CommandLineModuleManager& manager(); + + /*! \brief + * Checks all output from the manager using reference data. + * + * Both output to `stdout` and to files is checked. + * + * The manager is put into quiet mode by default, so the manager will + * only print out information if, e.g., help is explicitly requested. + */ + void checkRedirectedOutput(); + +private: + class Impl; + + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/gromacs/commandline/tests/cmdlineparser.cpp b/src/gromacs/commandline/tests/cmdlineparser.cpp index 643379f9ff..9558b9b309 100644 --- a/src/gromacs/commandline/tests/cmdlineparser.cpp +++ b/src/gromacs/commandline/tests/cmdlineparser.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,25 +64,28 @@ using gmx::test::CommandLine; class CommandLineParserTest : public ::testing::Test { - public: - CommandLineParserTest(); - - gmx::Options options_; - gmx::CommandLineParser parser_; - bool flag_; - std::vector ivalues_; - std::vector dvalues_; - int ivalue1p_; - int ivalue12_; - std::string stringValue_; +public: + CommandLineParserTest(); + + gmx::Options options_; + gmx::CommandLineParser parser_; + bool flag_; + std::vector ivalues_; + std::vector dvalues_; + int ivalue1p_; + int ivalue12_; + std::string stringValue_; }; -CommandLineParserTest::CommandLineParserTest() - : parser_(&options_), flag_(false), ivalue1p_(0), ivalue12_(0) +CommandLineParserTest::CommandLineParserTest() : + parser_(&options_), + flag_(false), + ivalue1p_(0), + ivalue12_(0) { using gmx::BooleanOption; - using gmx::IntegerOption; using gmx::DoubleOption; + using gmx::IntegerOption; using gmx::StringOption; options_.addOption(BooleanOption("flag").store(&flag_)); options_.addOption(IntegerOption("mvi").storeVector(&ivalues_).multiValue()); @@ -93,9 +97,7 @@ CommandLineParserTest::CommandLineParserTest() TEST_F(CommandLineParserTest, HandlesSingleValues) { - const char *const cmdline[] = { - "test", "-flag", "yes", "-mvi", "2", "-mvd", "2.7" - }; + const char* const cmdline[] = { "test", "-flag", "yes", "-mvi", "2", "-mvd", "2.7" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -111,9 +113,7 @@ TEST_F(CommandLineParserTest, HandlesSingleValues) TEST_F(CommandLineParserTest, HandlesBooleanWithoutArgument) { - const char *const cmdline[] = { - "test", "-flag" - }; + const char* const cmdline[] = { "test", "-flag" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -125,9 +125,7 @@ TEST_F(CommandLineParserTest, HandlesBooleanWithoutArgument) TEST_F(CommandLineParserTest, HandlesBooleanAsNoWithoutArgument) { - const char *const cmdline[] = { - "test", "-noflag" - }; + const char* const cmdline[] = { "test", "-noflag" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -139,18 +137,14 @@ TEST_F(CommandLineParserTest, HandlesBooleanAsNoWithoutArgument) TEST_F(CommandLineParserTest, ThrowsWithBooleanAsNoWithArgument) { - const char *const cmdline[] = { - "test", "-noflag", "no" - }; + const char* const cmdline[] = { "test", "-noflag", "no" }; CommandLine args(cmdline); EXPECT_THROW_GMX(parser_.parse(&args.argc(), args.argv()), gmx::InvalidInputError); } TEST_F(CommandLineParserTest, HandlesNegativeNumbers) { - const char *const cmdline[] = { - "test", "-mvi", "1", "-2", "-mvd", "-2.7" - }; + const char* const cmdline[] = { "test", "-mvi", "1", "-2", "-mvd", "-2.7" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -166,9 +160,7 @@ TEST_F(CommandLineParserTest, HandlesNegativeNumbers) TEST_F(CommandLineParserTest, HandlesString) { - const char *const cmdline[] = { - "test", "-str", "text" - }; + const char* const cmdline[] = { "test", "-str", "text" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -180,18 +172,14 @@ TEST_F(CommandLineParserTest, HandlesString) TEST_F(CommandLineParserTest, RejectsStringWithMultipleValues) { - const char *const cmdline[] = { - "test", "-str", "text", "excess text" - }; + const char* const cmdline[] = { "test", "-str", "text", "excess text" }; CommandLine args(cmdline); EXPECT_THROW_GMX(parser_.parse(&args.argc(), args.argv()), gmx::InvalidInputError); } TEST_F(CommandLineParserTest, HandlesDoubleDashOptionPrefix) { - const char *const cmdline[] = { - "test", "--mvi", "1", "-2", "--mvd", "-2.7" - }; + const char* const cmdline[] = { "test", "--mvi", "1", "-2", "--mvd", "-2.7" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -207,9 +195,7 @@ TEST_F(CommandLineParserTest, HandlesDoubleDashOptionPrefix) TEST_F(CommandLineParserTest, HandlesOptionsStartingWithNumbers) { - const char *const cmdline[] = { - "test", "--12", "1", "-1p", "-12" - }; + const char* const cmdline[] = { "test", "--12", "1", "-1p", "-12" }; CommandLine args(cmdline); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); ASSERT_NO_THROW_GMX(options_.finish()); @@ -222,9 +208,8 @@ TEST_F(CommandLineParserTest, HandlesOptionsStartingWithNumbers) TEST_F(CommandLineParserTest, HandlesSkipUnknown) { - const char *const cmdline[] = { - "test", "-unknown1", "-flag", "-unknown2", "value", "-mvi", "2", "-mvd", "2.7", "-unknown3" - }; + const char* const cmdline[] = { "test", "-unknown1", "-flag", "-unknown2", "value", + "-mvi", "2", "-mvd", "2.7", "-unknown3" }; CommandLine args(cmdline); parser_.skipUnknown(true); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); @@ -248,9 +233,7 @@ TEST_F(CommandLineParserTest, HandlesSkipUnknown) TEST_F(CommandLineParserTest, RejectsPositionalArgumentsByDefault) { // Ensures that "gmx trjconv f" gets rejected. - const char *const cmdline[] = { - "test", "module", "positional" - }; + const char* const cmdline[] = { "test", "module", "positional" }; CommandLine args(cmdline); EXPECT_THROW_GMX(parser_.parse(&args.argc(), args.argv()), gmx::InvalidInputError); } @@ -258,9 +241,7 @@ TEST_F(CommandLineParserTest, RejectsPositionalArgumentsByDefault) TEST_F(CommandLineParserTest, CanAllowPositionalArguments) { // Ensures that "gmx help trjconv" works - const char *const cmdline[] = { - "test", "module", "positional", "-flag" - }; + const char* const cmdline[] = { "test", "module", "positional", "-flag" }; CommandLine args(cmdline); parser_.allowPositionalArguments(true); ASSERT_NO_THROW_GMX(parser_.parse(&args.argc(), args.argv())); @@ -277,9 +258,7 @@ TEST_F(CommandLineParserTest, CannotHavePositionalArgumentsAfterOptions) // values, there's no way to check whether there's been enough // values provided, so we can't have positional arguments after // any options. - const char *const cmdline[] = { - "test", "module", "-1p", "2", "positional" - }; + const char* const cmdline[] = { "test", "module", "-1p", "2", "positional" }; CommandLine args(cmdline); parser_.allowPositionalArguments(true); EXPECT_THROW_GMX(parser_.parse(&args.argc(), args.argv()), gmx::InvalidInputError); diff --git a/src/gromacs/commandline/tests/cmdlineprogramcontext.cpp b/src/gromacs/commandline/tests/cmdlineprogramcontext.cpp index 3adc46c81f..52af43774f 100644 --- a/src/gromacs/commandline/tests/cmdlineprogramcontext.cpp +++ b/src/gromacs/commandline/tests/cmdlineprogramcontext.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,12 +61,12 @@ using gmx::Path; #if GMX_NATIVE_WINDOWS || GMX_CYGWIN //! Extension for executable files on the platform. -#define EXECUTABLE_EXTENSION ".exe" +# define EXECUTABLE_EXTENSION ".exe" #else //! Extension for executable files on the platform. -#define EXECUTABLE_EXTENSION "" +# define EXECUTABLE_EXTENSION "" //! Defined if the platform supports symlinks and those can be tested. -#define TEST_SYMLINKS +# define TEST_SYMLINKS #endif namespace @@ -74,56 +74,43 @@ namespace class TestExecutableEnvironment : public gmx::IExecutableEnvironment { - public: - TestExecutableEnvironment() - : workingDirectory_(CMAKE_BINARY_DIR "/src/gromacs/commandline/tests/test-bin") - { - } - - std::string getWorkingDirectory() const override - { - return workingDirectory_; - } - std::vector getExecutablePaths() const override - { - return path_; - } - - std::string workingDirectory_; - std::vector path_; - - GMX_DISALLOW_COPY_AND_ASSIGN(TestExecutableEnvironment); +public: + TestExecutableEnvironment() : + workingDirectory_(CMAKE_BINARY_DIR "/src/gromacs/commandline/tests/test-bin") + { + } + + std::string getWorkingDirectory() const override { return workingDirectory_; } + std::vector getExecutablePaths() const override { return path_; } + + std::string workingDirectory_; + std::vector path_; + + GMX_DISALLOW_COPY_AND_ASSIGN(TestExecutableEnvironment); }; //! Shorthand for a smart pointer to TestExecutableEnvironment. -typedef std::unique_ptr - TestExecutableEnvironmentPointer; +typedef std::unique_ptr TestExecutableEnvironmentPointer; class CommandLineProgramContextTest : public ::testing::Test { - public: - CommandLineProgramContextTest() - : env_(new TestExecutableEnvironment()) - { - expectedExecutable_ = - Path::normalize( - Path::join(env_->getWorkingDirectory(), - "bin/test-exe" EXECUTABLE_EXTENSION)); - } - - void testBinaryPathSearch(const char *argv0) - { - ASSERT_TRUE(env_.get() != nullptr); - gmx::CommandLineProgramContext info(1, &argv0, move(env_)); - EXPECT_EQ(expectedExecutable_, info.fullBinaryPath()); - } - void testBinaryPathSearch(const std::string &argv0) - { - testBinaryPathSearch(argv0.c_str()); - } - - std::string expectedExecutable_; - TestExecutableEnvironmentPointer env_; +public: + CommandLineProgramContextTest() : env_(new TestExecutableEnvironment()) + { + expectedExecutable_ = Path::normalize( + Path::join(env_->getWorkingDirectory(), "bin/test-exe" EXECUTABLE_EXTENSION)); + } + + void testBinaryPathSearch(const char* argv0) + { + ASSERT_TRUE(env_.get() != nullptr); + gmx::CommandLineProgramContext info(1, &argv0, move(env_)); + EXPECT_EQ(expectedExecutable_, info.fullBinaryPath()); + } + void testBinaryPathSearch(const std::string& argv0) { testBinaryPathSearch(argv0.c_str()); } + + std::string expectedExecutable_; + TestExecutableEnvironmentPointer env_; }; TEST_F(CommandLineProgramContextTest, FindsBinaryWithAbsolutePath) diff --git a/src/gromacs/commandline/tests/filenm.cpp b/src/gromacs/commandline/tests/filenm.cpp index 40db8fd4c1..31f1bc64d5 100644 --- a/src/gromacs/commandline/tests/filenm.cpp +++ b/src/gromacs/commandline/tests/filenm.cpp @@ -56,11 +56,9 @@ namespace TEST(OutputNamesTest, CanBeSuffixed) { - std::vector filenames = { - { efTRR, nullptr, nullptr, ffREAD, {"input.trr"}}, - { efTRR, nullptr, nullptr, ffWRITE, {"output.trr"}}, - { efCPT, nullptr, nullptr, ffWRITE, {"output.cpt"}} - }; + std::vector filenames = { { efTRR, nullptr, nullptr, ffREAD, { "input.trr" } }, + { efTRR, nullptr, nullptr, ffWRITE, { "output.trr" } }, + { efCPT, nullptr, nullptr, ffWRITE, { "output.cpt" } } }; add_suffix_to_output_names(filenames.data(), filenames.size(), "_suffix"); EXPECT_EQ(filenames[0].filenames[0], "input.trr"); EXPECT_EQ(filenames[1].filenames[0], "output_suffix.trr"); @@ -83,16 +81,16 @@ TEST(OutputNamesTest, HasSuffixFromNoAppend) TEST(OutputNamesTest, CanHavePartNumberAdded) { std::vector filenames = { - { efLOG, nullptr, nullptr, ffWRITE, {"output.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.part0002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.equil.part0002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.part0001.part0002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.equil.part0001.part0002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.part0002"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"part0002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.part02.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output.part002.log"}}, - { efLOG, nullptr, nullptr, ffWRITE, {"output"}} + { efLOG, nullptr, nullptr, ffWRITE, { "output.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.part0002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.equil.part0002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.part0001.part0002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.equil.part0001.part0002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.part0002" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "part0002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.part02.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output.part002.log" } }, + { efLOG, nullptr, nullptr, ffWRITE, { "output" } } }; add_suffix_to_output_names(filenames.data(), filenames.size(), ".part0003"); EXPECT_EQ(filenames[0].filenames[0], "output.part0003.log"); diff --git a/src/gromacs/commandline/tests/pargs.cpp b/src/gromacs/commandline/tests/pargs.cpp index a0441754b1..0485ff4ada 100644 --- a/src/gromacs/commandline/tests/pargs.cpp +++ b/src/gromacs/commandline/tests/pargs.cpp @@ -66,75 +66,59 @@ using gmx::test::CommandLine; class ParseCommonArgsTest : public ::testing::Test { - public: - enum FileArgumentType - { - efFull, - efNoExtension, - efEmptyValue - }; +public: + enum FileArgumentType + { + efFull, + efNoExtension, + efEmptyValue + }; - ParseCommonArgsTest() - : oenv_(nullptr), fileCount_(0) - { - } - ~ParseCommonArgsTest() override - { - output_env_done(oenv_); - } + ParseCommonArgsTest() : oenv_(nullptr), fileCount_(0) {} + ~ParseCommonArgsTest() override { output_env_done(oenv_); } - int nfile() const { return fileCount_; } + int nfile() const { return fileCount_; } - void parseFromArgs(unsigned long flags, - gmx::ArrayRef fnm, - gmx::ArrayRef pa) - { - fileCount_ = fnm.size(); - bool bOk = parse_common_args(&args_.argc(), args_.argv(), flags, - fnm.size(), fnm.data(), - pa.size(), pa.data(), - 0, nullptr, 0, nullptr, &oenv_); - EXPECT_TRUE(bOk); - } - void parseFromArray(gmx::ArrayRef cmdline, - unsigned long flags, - gmx::ArrayRef fnm, - gmx::ArrayRef pa) - { - args_.initFromArray(cmdline); - parseFromArgs(flags, fnm, pa); - } - std::string addFileArg(const char *name, const char *extension, - FileArgumentType type) + void parseFromArgs(unsigned long flags, gmx::ArrayRef fnm, gmx::ArrayRef pa) + { + fileCount_ = fnm.size(); + bool bOk = parse_common_args(&args_.argc(), args_.argv(), flags, fnm.size(), fnm.data(), + pa.size(), pa.data(), 0, nullptr, 0, nullptr, &oenv_); + EXPECT_TRUE(bOk); + } + void parseFromArray(gmx::ArrayRef cmdline, + unsigned long flags, + gmx::ArrayRef fnm, + gmx::ArrayRef pa) + { + args_.initFromArray(cmdline); + parseFromArgs(flags, fnm, pa); + } + std::string addFileArg(const char* name, const char* extension, FileArgumentType type) + { + std::string filename(tempFiles_.getTemporaryFilePath(extension)); + gmx::TextWriter::writeFileFromString(filename, "Dummy file"); + if (name != nullptr) { - std::string filename(tempFiles_.getTemporaryFilePath(extension)); - gmx::TextWriter::writeFileFromString(filename, "Dummy file"); - if (name != nullptr) + args_.append(name); + switch (type) { - args_.append(name); - switch (type) - { - case efFull: - args_.append(filename); - break; - case efNoExtension: - args_.append(gmx::Path::stripExtension(filename)); - break; - case efEmptyValue: - break; - } + case efFull: args_.append(filename); break; + case efNoExtension: args_.append(gmx::Path::stripExtension(filename)); break; + case efEmptyValue: break; } - return filename; } + return filename; + } - // This must be a member that persists until the end of the test, - // because string arguments are not duplicated in the output. - CommandLine args_; + // This must be a member that persists until the end of the test, + // because string arguments are not duplicated in the output. + CommandLine args_; - private: - gmx_output_env_t *oenv_; - size_t fileCount_; - gmx::test::TestFileManager tempFiles_; +private: + gmx_output_env_t* oenv_; + size_t fileCount_; + gmx::test::TestFileManager tempFiles_; }; /******************************************************************** @@ -144,65 +128,49 @@ class ParseCommonArgsTest : public ::testing::Test TEST_F(ParseCommonArgsTest, ParsesIntegerArgs) { int value1 = 0, value2 = 0, value3 = 3; - t_pargs pa[] = { - { "-i1", FALSE, etINT, {&value1}, "Description" }, - { "-i2", FALSE, etINT, {&value2}, "Description" }, - { "-i3", FALSE, etINT, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-i1", "2", "-i2", "-3" - }; + t_pargs pa[] = { { "-i1", FALSE, etINT, { &value1 }, "Description" }, + { "-i2", FALSE, etINT, { &value2 }, "Description" }, + { "-i3", FALSE, etINT, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-i1", "2", "-i2", "-3" }; parseFromArray(cmdline, 0, {}, pa); - EXPECT_EQ( 2, value1); + EXPECT_EQ(2, value1); EXPECT_EQ(-3, value2); - EXPECT_EQ( 3, value3); + EXPECT_EQ(3, value3); } TEST_F(ParseCommonArgsTest, ParsesInt64Args) { int64_t value1 = 0, value2 = 0, value3 = 3; - t_pargs pa[] = { - { "-i1", FALSE, etINT64, {&value1}, "Description" }, - { "-i2", FALSE, etINT64, {&value2}, "Description" }, - { "-i3", FALSE, etINT64, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-i1", "2", "-i2", "-3" - }; + t_pargs pa[] = { { "-i1", FALSE, etINT64, { &value1 }, "Description" }, + { "-i2", FALSE, etINT64, { &value2 }, "Description" }, + { "-i3", FALSE, etINT64, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-i1", "2", "-i2", "-3" }; parseFromArray(cmdline, 0, {}, pa); - EXPECT_EQ( 2, value1); + EXPECT_EQ(2, value1); EXPECT_EQ(-3, value2); - EXPECT_EQ( 3, value3); + EXPECT_EQ(3, value3); } TEST_F(ParseCommonArgsTest, ParsesRealArgs) { real value1 = 0.0, value2 = 0.0, value3 = 2.5; - t_pargs pa[] = { - { "-r1", FALSE, etREAL, {&value1}, "Description" }, - { "-r2", FALSE, etREAL, {&value2}, "Description" }, - { "-r3", FALSE, etREAL, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-r1", "2", "-r2", "-.5" - }; + t_pargs pa[] = { { "-r1", FALSE, etREAL, { &value1 }, "Description" }, + { "-r2", FALSE, etREAL, { &value2 }, "Description" }, + { "-r3", FALSE, etREAL, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-r1", "2", "-r2", "-.5" }; parseFromArray(cmdline, 0, {}, pa); - EXPECT_EQ( 2.0, value1); + EXPECT_EQ(2.0, value1); EXPECT_EQ(-0.5, value2); - EXPECT_EQ( 2.5, value3); + EXPECT_EQ(2.5, value3); } TEST_F(ParseCommonArgsTest, ParsesStringArgs) { - const char *value1 = "def", *value2 = "", *value3 = "default"; - t_pargs pa[] = { - { "-s1", FALSE, etSTR, {&value1}, "Description" }, - { "-s2", FALSE, etSTR, {&value2}, "Description" }, - { "-s3", FALSE, etSTR, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-s1", "", "-s2", "test" - }; + const char * value1 = "def", *value2 = "", *value3 = "default"; + t_pargs pa[] = { { "-s1", FALSE, etSTR, { &value1 }, "Description" }, + { "-s2", FALSE, etSTR, { &value2 }, "Description" }, + { "-s3", FALSE, etSTR, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-s1", "", "-s2", "test" }; parseFromArray(cmdline, 0, {}, pa); EXPECT_STREQ("", value1); EXPECT_STREQ("test", value2); @@ -212,14 +180,10 @@ TEST_F(ParseCommonArgsTest, ParsesStringArgs) TEST_F(ParseCommonArgsTest, ParsesBooleanArgs) { gmx_bool value1 = TRUE, value2 = FALSE, value3 = TRUE; - t_pargs pa[] = { - { "-b1", FALSE, etBOOL, {&value1}, "Description" }, - { "-b2", FALSE, etBOOL, {&value2}, "Description" }, - { "-b3", FALSE, etBOOL, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-nob1", "-b2" - }; + t_pargs pa[] = { { "-b1", FALSE, etBOOL, { &value1 }, "Description" }, + { "-b2", FALSE, etBOOL, { &value2 }, "Description" }, + { "-b3", FALSE, etBOOL, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-nob1", "-b2" }; parseFromArray(cmdline, 0, {}, pa); EXPECT_FALSE(value1); EXPECT_TRUE(value2); @@ -228,15 +192,11 @@ TEST_F(ParseCommonArgsTest, ParsesBooleanArgs) TEST_F(ParseCommonArgsTest, ParsesVectorArgs) { - rvec value1 = {0, 0, 0}, value2 = {0, 0, 0}, value3 = {1, 2, 3}; - t_pargs pa[] = { - { "-v1", FALSE, etRVEC, {&value1}, "Description" }, - { "-v2", FALSE, etRVEC, {&value2}, "Description" }, - { "-v3", FALSE, etRVEC, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-v1", "2", "1", "3", "-v2", "1" - }; + rvec value1 = { 0, 0, 0 }, value2 = { 0, 0, 0 }, value3 = { 1, 2, 3 }; + t_pargs pa[] = { { "-v1", FALSE, etRVEC, { &value1 }, "Description" }, + { "-v2", FALSE, etRVEC, { &value2 }, "Description" }, + { "-v3", FALSE, etRVEC, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-v1", "2", "1", "3", "-v2", "1" }; parseFromArray(cmdline, 0, {}, pa); EXPECT_EQ(2.0, value1[XX]); EXPECT_EQ(1.0, value1[YY]); @@ -252,50 +212,38 @@ TEST_F(ParseCommonArgsTest, ParsesVectorArgs) TEST_F(ParseCommonArgsTest, ParsesTimeArgs) { real value1 = 1.0, value2 = 2.0, value3 = 2.5; - t_pargs pa[] = { - { "-t1", FALSE, etTIME, {&value1}, "Description" }, - { "-t2", FALSE, etTIME, {&value2}, "Description" }, - { "-t3", FALSE, etTIME, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-t1", "2", "-t2", "-.5" - }; + t_pargs pa[] = { { "-t1", FALSE, etTIME, { &value1 }, "Description" }, + { "-t2", FALSE, etTIME, { &value2 }, "Description" }, + { "-t3", FALSE, etTIME, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-t1", "2", "-t2", "-.5" }; parseFromArray(cmdline, 0, {}, pa); - EXPECT_EQ( 2.0, value1); + EXPECT_EQ(2.0, value1); EXPECT_EQ(-0.5, value2); - EXPECT_EQ( 2.5, value3); + EXPECT_EQ(2.5, value3); } TEST_F(ParseCommonArgsTest, ParsesTimeArgsWithTimeUnit) { real value1 = 1.0, value2 = 2.0, value3 = 2.5; - t_pargs pa[] = { - { "-t1", FALSE, etTIME, {&value1}, "Description" }, - { "-t2", FALSE, etTIME, {&value2}, "Description" }, - { "-t3", FALSE, etTIME, {&value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-t1", "2", "-t2", "-.5", "-tu", "ns" - }; + t_pargs pa[] = { { "-t1", FALSE, etTIME, { &value1 }, "Description" }, + { "-t2", FALSE, etTIME, { &value2 }, "Description" }, + { "-t3", FALSE, etTIME, { &value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-t1", "2", "-t2", "-.5", "-tu", "ns" }; parseFromArray(cmdline, PCA_TIME_UNIT, {}, pa); - EXPECT_EQ( 2000.0, value1); + EXPECT_EQ(2000.0, value1); EXPECT_EQ(-500.0, value2); - EXPECT_EQ( 2.5, value3); + EXPECT_EQ(2.5, value3); } TEST_F(ParseCommonArgsTest, ParsesEnumArgs) { - const char *value1[] = {nullptr, "none", "on", "off", nullptr }; - const char *value2[] = {nullptr, "def", "value", "value_other", nullptr }; - const char *value3[] = {nullptr, "default", "value", nullptr }; - t_pargs pa[] = { - { "-s1", FALSE, etENUM, {value1}, "Description" }, - { "-s2", FALSE, etENUM, {value2}, "Description" }, - { "-s3", FALSE, etENUM, {value3}, "Description" } - }; - const char *const cmdline[] = { - "test", "-s1", "off", "-s2", "val" - }; + const char* value1[] = { nullptr, "none", "on", "off", nullptr }; + const char* value2[] = { nullptr, "def", "value", "value_other", nullptr }; + const char* value3[] = { nullptr, "default", "value", nullptr }; + t_pargs pa[] = { { "-s1", FALSE, etENUM, { value1 }, "Description" }, + { "-s2", FALSE, etENUM, { value2 }, "Description" }, + { "-s3", FALSE, etENUM, { value3 }, "Description" } }; + const char* const cmdline[] = { "test", "-s1", "off", "-s2", "val" }; parseFromArray(cmdline, 0, {}, pa); EXPECT_STREQ("off", value1[0]); EXPECT_STREQ("value", value2[0]); @@ -311,15 +259,12 @@ TEST_F(ParseCommonArgsTest, ParsesEnumArgs) TEST_F(ParseCommonArgsTest, ParsesFileArgs) { - t_filenm fnm[] = { - { efXVG, "-o1", "out1", ffOPTWR }, - { efXVG, "-o2", "out2", ffOPTWR }, - { efXVG, "-om", "outm", ffWRMULT }, - { efXVG, "-om2", "outm2", ffWRMULT } - }; - const char *const cmdline[] = { - "test", "-o1", "-o2", "test", "-om", "test1", "test2.xvg", "-om2" - }; + t_filenm fnm[] = { { efXVG, "-o1", "out1", ffOPTWR }, + { efXVG, "-o2", "out2", ffOPTWR }, + { efXVG, "-om", "outm", ffWRMULT }, + { efXVG, "-om2", "outm2", ffWRMULT } }; + const char* const cmdline[] = { "test", "-o1", "-o2", "test", + "-om", "test1", "test2.xvg", "-om2" }; parseFromArray(cmdline, 0, fnm, {}); EXPECT_STREQ("out1.xvg", opt2fn_null("-o1", nfile(), fnm)); EXPECT_STREQ("test.xvg", opt2fn_null("-o2", nfile(), fnm)); @@ -335,16 +280,12 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgs) TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaults) { - t_filenm fnm[] = { - { efTPS, nullptr, nullptr, ffWRITE }, - { efTRX, "-f2", nullptr, ffOPTWR }, - { efTRX, "-f3", "trj3", ffWRITE }, - { efXVG, "-o", "out", ffWRITE }, - { efXVG, "-om", "outm", ffWRMULT } - }; - const char *const cmdline[] = { - "test" - }; + t_filenm fnm[] = { { efTPS, nullptr, nullptr, ffWRITE }, + { efTRX, "-f2", nullptr, ffOPTWR }, + { efTRX, "-f3", "trj3", ffWRITE }, + { efXVG, "-o", "out", ffWRITE }, + { efXVG, "-om", "outm", ffWRMULT } }; + const char* const cmdline[] = { "test" }; parseFromArray(cmdline, 0, fnm, {}); EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm)); EXPECT_STREQ("traj.xtc", opt2fn("-f2", nfile(), fnm)); @@ -356,16 +297,12 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaults) TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaultFileName) { - t_filenm fnm[] = { - { efTPS, "-s", nullptr, ffWRITE }, - { efTRX, "-f2", nullptr, ffWRITE }, - { efTRX, "-f3", "trj3", ffWRITE }, - { efXVG, "-o", "out", ffWRITE }, - { efXVG, "-om", "outm", ffWRMULT } - }; - const char *const cmdline[] = { - "test", "-deffnm", "def", "-f2", "other", "-o" - }; + t_filenm fnm[] = { { efTPS, "-s", nullptr, ffWRITE }, + { efTRX, "-f2", nullptr, ffWRITE }, + { efTRX, "-f3", "trj3", ffWRITE }, + { efXVG, "-o", "out", ffWRITE }, + { efXVG, "-om", "outm", ffWRMULT } }; + const char* const cmdline[] = { "test", "-deffnm", "def", "-f2", "other", "-o" }; parseFromArray(cmdline, PCA_CAN_SET_DEFFNM, fnm, {}); EXPECT_STREQ("def.tpr", ftp2fn(efTPS, nfile(), fnm)); EXPECT_STREQ("other.xtc", opt2fn("-f2", nfile(), fnm)); @@ -376,14 +313,10 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaultFileName) TEST_F(ParseCommonArgsTest, ParseFileArgsWithCustomDefaultExtension) { - t_filenm fnm[] = { - { efTRX, "-o1", "conf1.gro", ffWRITE }, - { efTRX, "-o2", "conf2.pdb", ffWRITE }, - { efTRX, "-o3", "conf3.gro", ffWRITE } - }; - const char *const cmdline[] = { - "test", "-o2", "-o3", "test" - }; + t_filenm fnm[] = { { efTRX, "-o1", "conf1.gro", ffWRITE }, + { efTRX, "-o2", "conf2.pdb", ffWRITE }, + { efTRX, "-o3", "conf3.gro", ffWRITE } }; + const char* const cmdline[] = { "test", "-o2", "-o3", "test" }; parseFromArray(cmdline, PCA_CAN_SET_DEFFNM, fnm, {}); EXPECT_STREQ("conf1.gro", opt2fn("-o1", nfile(), fnm)); EXPECT_STREQ("conf2.pdb", opt2fn("-o2", nfile(), fnm)); @@ -396,18 +329,11 @@ TEST_F(ParseCommonArgsTest, ParseFileArgsWithCustomDefaultExtension) TEST_F(ParseCommonArgsTest, HandlesNonExistentInputFiles) { - t_filenm fnm[] = { - { efTPS, "-s", nullptr, ffREAD }, - { efTRX, "-f", "trj", ffREAD }, - { efTRX, "-f2", "trj2", ffREAD }, - { efTRX, "-f3", "trj3", ffREAD }, - { efTRX, "-f4", "trj4", ffREAD }, - { efGRO, "-g", "cnf", ffREAD }, - { efGRO, "-g2", "cnf2", ffREAD } - }; - const char *const cmdline[] = { - "test", "-f2", "-f3", "other", "-f4", "trj.gro", "-g2", "foo" - }; + t_filenm fnm[] = { { efTPS, "-s", nullptr, ffREAD }, { efTRX, "-f", "trj", ffREAD }, + { efTRX, "-f2", "trj2", ffREAD }, { efTRX, "-f3", "trj3", ffREAD }, + { efTRX, "-f4", "trj4", ffREAD }, { efGRO, "-g", "cnf", ffREAD }, + { efGRO, "-g2", "cnf2", ffREAD } }; + const char* const cmdline[] = { "test", "-f2", "-f3", "other", "-f4", "trj.gro", "-g2", "foo" }; parseFromArray(cmdline, PCA_DISABLE_INPUT_FILE_CHECKING, fnm, {}); EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm)); EXPECT_STREQ("trj.xtc", opt2fn("-f", nfile(), fnm)); @@ -420,13 +346,8 @@ TEST_F(ParseCommonArgsTest, HandlesNonExistentInputFiles) TEST_F(ParseCommonArgsTest, HandlesNonExistentOptionalInputFiles) { - t_filenm fnm[] = { - { efTPS, "-s", nullptr, ffOPTRD }, - { efTRX, "-f", "trj", ffOPTRD } - }; - const char *const cmdline[] = { - "test" - }; + t_filenm fnm[] = { { efTPS, "-s", nullptr, ffOPTRD }, { efTRX, "-f", "trj", ffOPTRD } }; + const char* const cmdline[] = { "test" }; parseFromArray(cmdline, 0, fnm, {}); EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm)); EXPECT_STREQ("trj.xtc", opt2fn("-f", nfile(), fnm)); @@ -434,16 +355,14 @@ TEST_F(ParseCommonArgsTest, HandlesNonExistentOptionalInputFiles) TEST_F(ParseCommonArgsTest, AcceptsNonExistentInputFilesIfSpecified) { - t_filenm fnm[] = { - { efCPT, "-c", "file1", ffOPTRD | ffALLOW_MISSING }, - { efCPT, "-c2", "file2", ffOPTRD | ffALLOW_MISSING }, - { efCPT, "-c3", "file3", ffOPTRD | ffALLOW_MISSING }, - { efCPT, "-c4", "file4", ffOPTRD | ffALLOW_MISSING }, - { efTRX, "-f", "trj", ffOPTRD | ffALLOW_MISSING } - }; - const char *const cmdline[] = { - "test", "-c2", "-c3", "nonexistent", "-c4", "nonexistent.cpt", "-f", "nonexistent" - }; + t_filenm fnm[] = { { efCPT, "-c", "file1", ffOPTRD | ffALLOW_MISSING }, + { efCPT, "-c2", "file2", ffOPTRD | ffALLOW_MISSING }, + { efCPT, "-c3", "file3", ffOPTRD | ffALLOW_MISSING }, + { efCPT, "-c4", "file4", ffOPTRD | ffALLOW_MISSING }, + { efTRX, "-f", "trj", ffOPTRD | ffALLOW_MISSING } }; + const char* const cmdline[] = { "test", "-c2", "-c3", + "nonexistent", "-c4", "nonexistent.cpt", + "-f", "nonexistent" }; parseFromArray(cmdline, 0, fnm, {}); EXPECT_STREQ("file1.cpt", opt2fn("-c", nfile(), fnm)); EXPECT_STREQ("file2.cpt", opt2fn("-c2", nfile(), fnm)); @@ -454,15 +373,12 @@ TEST_F(ParseCommonArgsTest, AcceptsNonExistentInputFilesIfSpecified) TEST_F(ParseCommonArgsTest, HandlesCompressedFiles) { - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efGRO, "-g", nullptr, ffREAD } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efGRO, "-g", nullptr, ffREAD } }; args_.append("test"); - std::string expectedF = addFileArg("-f", ".pdb.gz", efFull); - std::string expectedG = addFileArg("-g", ".gro.Z", efFull); - expectedF = gmx::Path::stripExtension(expectedF); - expectedG = gmx::Path::stripExtension(expectedG); + std::string expectedF = addFileArg("-f", ".pdb.gz", efFull); + std::string expectedG = addFileArg("-g", ".gro.Z", efFull); + expectedF = gmx::Path::stripExtension(expectedF); + expectedG = gmx::Path::stripExtension(expectedG); parseFromArgs(0, fnm, {}); EXPECT_EQ(expectedF, opt2fn("-f", nfile(), fnm)); EXPECT_EQ(expectedG, opt2fn("-g", nfile(), fnm)); @@ -470,11 +386,9 @@ TEST_F(ParseCommonArgsTest, HandlesCompressedFiles) TEST_F(ParseCommonArgsTest, AcceptsUnknownTrajectoryExtension) { - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD } }; args_.append("test"); - std::string expected = addFileArg("-f", ".foo", efFull); + std::string expected = addFileArg("-f", ".foo", efFull); parseFromArgs(0, fnm, {}); EXPECT_EQ(expected, opt2fn("-f", nfile(), fnm)); } @@ -482,17 +396,15 @@ TEST_F(ParseCommonArgsTest, AcceptsUnknownTrajectoryExtension) TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFile) { args_.append("test"); - std::string expected1 = addFileArg("-f1", "1.xtc", efNoExtension); - std::string expected2 = addFileArg("-f2", "2.gro", efNoExtension); - std::string expected3 = addFileArg("-f3", "3.tng", efNoExtension); - std::string expected4 = addFileArg("-f4", ".gro", efEmptyValue); - std::string def4 = gmx::Path::stripExtension(expected4); - t_filenm fnm[] = { - { efTRX, "-f1", nullptr, ffREAD }, - { efTRX, "-f2", nullptr, ffREAD }, - { efTRX, "-f3", nullptr, ffREAD }, - { efTRX, "-f4", def4.c_str(), ffREAD } - }; + std::string expected1 = addFileArg("-f1", "1.xtc", efNoExtension); + std::string expected2 = addFileArg("-f2", "2.gro", efNoExtension); + std::string expected3 = addFileArg("-f3", "3.tng", efNoExtension); + std::string expected4 = addFileArg("-f4", ".gro", efEmptyValue); + std::string def4 = gmx::Path::stripExtension(expected4); + t_filenm fnm[] = { { efTRX, "-f1", nullptr, ffREAD }, + { efTRX, "-f2", nullptr, ffREAD }, + { efTRX, "-f3", nullptr, ffREAD }, + { efTRX, "-f4", def4.c_str(), ffREAD } }; parseFromArgs(0, fnm, {}); EXPECT_EQ(expected1, opt2fn("-f1", nfile(), fnm)); EXPECT_EQ(expected2, opt2fn("-f2", nfile(), fnm)); @@ -502,18 +414,16 @@ TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFile) TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFileWithDefaultFileName) { - t_filenm fnm[] = { - { efTRX, "-f1", nullptr, ffREAD }, - { efSTO, "-f2", "foo", ffREAD }, - { efTRX, "-f3", nullptr, ffREAD }, - { efSTX, "-f4", nullptr, ffREAD } - }; + t_filenm fnm[] = { { efTRX, "-f1", nullptr, ffREAD }, + { efSTO, "-f2", "foo", ffREAD }, + { efTRX, "-f3", nullptr, ffREAD }, + { efSTX, "-f4", nullptr, ffREAD } }; args_.append("test"); - std::string expected1 = addFileArg("-f1", "1.trr", efNoExtension); - std::string expected2 = addFileArg("-f2", ".pdb", efEmptyValue); - std::string expected3 = addFileArg("-f3", ".trr", efEmptyValue); - std::string expected4 = addFileArg(nullptr, ".pdb", efEmptyValue); - std::string deffnm = gmx::Path::stripExtension(expected3); + std::string expected1 = addFileArg("-f1", "1.trr", efNoExtension); + std::string expected2 = addFileArg("-f2", ".pdb", efEmptyValue); + std::string expected3 = addFileArg("-f3", ".trr", efEmptyValue); + std::string expected4 = addFileArg(nullptr, ".pdb", efEmptyValue); + std::string deffnm = gmx::Path::stripExtension(expected3); args_.append("-deffnm"); args_.append(deffnm); parseFromArgs(PCA_CAN_SET_DEFFNM, fnm, {}); @@ -527,31 +437,26 @@ TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFileWithDefaultFileNam // to child mdrun processes that it spawns. TEST_F(ParseCommonArgsTest, CanKeepUnknownArgs) { - int ivalue = 0; - gmx_bool bvalue = FALSE; - t_pargs pa[] = { - { "-i", FALSE, etINT, {&ivalue}, "Description" }, - { "-b", FALSE, etBOOL, {&bvalue}, "Description" }, - }; - t_filenm fnm[] = { - { efXVG, "-o1", "out1", ffOPTWR }, - { efXVG, "-o2", "out2", ffOPTWR } - }; - const char *const cmdline[] = { - "test", "foo", "-unk", "-o1", "-unk2", "-o2", "test", - "-i", "2", "-unk3", "-b", "-unk4" - }; + int ivalue = 0; + gmx_bool bvalue = FALSE; + t_pargs pa[] = { + { "-i", FALSE, etINT, { &ivalue }, "Description" }, + { "-b", FALSE, etBOOL, { &bvalue }, "Description" }, + }; + t_filenm fnm[] = { { efXVG, "-o1", "out1", ffOPTWR }, { efXVG, "-o2", "out2", ffOPTWR } }; + const char* const cmdline[] = { "test", "foo", "-unk", "-o1", "-unk2", "-o2", + "test", "-i", "2", "-unk3", "-b", "-unk4" }; parseFromArray(cmdline, PCA_NOEXIT_ON_ARGS, fnm, pa); EXPECT_EQ(2, ivalue); EXPECT_TRUE(bvalue); EXPECT_STREQ("out1.xvg", opt2fn_null("-o1", nfile(), fnm)); EXPECT_STREQ("test.xvg", opt2fn_null("-o2", nfile(), fnm)); EXPECT_EQ(6, args_.argc()); - EXPECT_STREQ(cmdline[0], args_.arg(0)); - EXPECT_STREQ(cmdline[1], args_.arg(1)); - EXPECT_STREQ(cmdline[2], args_.arg(2)); - EXPECT_STREQ(cmdline[4], args_.arg(3)); - EXPECT_STREQ(cmdline[9], args_.arg(4)); + EXPECT_STREQ(cmdline[0], args_.arg(0)); + EXPECT_STREQ(cmdline[1], args_.arg(1)); + EXPECT_STREQ(cmdline[2], args_.arg(2)); + EXPECT_STREQ(cmdline[4], args_.arg(3)); + EXPECT_STREQ(cmdline[9], args_.arg(4)); EXPECT_STREQ(cmdline[11], args_.arg(5)); } diff --git a/src/gromacs/commandline/viewit.cpp b/src/gromacs/commandline/viewit.cpp index 252ade56f2..9a42421e15 100644 --- a/src/gromacs/commandline/viewit.cpp +++ b/src/gromacs/commandline/viewit.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,15 +48,9 @@ #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/fatalerror.h" -static const int can_view_ftp[] = { - 0, - efEPS, efXPM, efXVG, efPDB -}; +static const int can_view_ftp[] = { 0, efEPS, efXPM, efXVG, efPDB }; #define NVIEW asize(can_view_ftp) -static const char* view_program[] = { - nullptr, - "ghostview", "display", nullptr, "xterm -e rasmol" -}; +static const char* view_program[] = { nullptr, "ghostview", "display", nullptr, "xterm -e rasmol" }; static int can_view(int ftp) { @@ -73,10 +67,10 @@ static int can_view(int ftp) return 0; } -void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts) +void do_view(const gmx_output_env_t* oenv, const char* fn, const char* opts) { char buf[STRLEN], env[STRLEN]; - const char *cmd; + const char* cmd; int ftp, n; if (output_env_get_view(oenv) && fn) @@ -93,9 +87,9 @@ void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts) switch (ftp) { case efXVG: - if (!(cmd = getenv(env)) ) + if (!(cmd = getenv(env))) { - if (getenv("GMX_USE_XMGR") ) + if (getenv("GMX_USE_XMGR")) { cmd = "xmgr"; } @@ -106,9 +100,9 @@ void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts) } break; default: - if ( (n = can_view(ftp)) ) + if ((n = can_view(ftp))) { - if (!(cmd = getenv(env)) ) + if (!(cmd = getenv(env))) { cmd = view_program[n]; } @@ -119,11 +113,11 @@ void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts) return; } } - if (strlen(cmd) ) + if (strlen(cmd)) { sprintf(buf, "%s %s %s &", cmd, opts ? opts : "", fn); fprintf(stderr, "Executing '%s'\n", buf); - if (0 != system(buf) ) + if (0 != system(buf)) { gmx_fatal(FARGS, "Failed executing command: %s", buf); } @@ -132,14 +126,13 @@ void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts) } } -void view_all(const gmx_output_env_t *oenv, int nf, t_filenm fnm[]) +void view_all(const gmx_output_env_t* oenv, int nf, t_filenm fnm[]) { int i; for (i = 0; i < nf; i++) { - if (can_view(fnm[i].ftp) && is_output(&(fnm[i])) && - ( !is_optional(&(fnm[i])) || is_set(&(fnm[i])) ) ) + if (can_view(fnm[i].ftp) && is_output(&(fnm[i])) && (!is_optional(&(fnm[i])) || is_set(&(fnm[i])))) { do_view(oenv, fnm[i].filenames[0].c_str(), nullptr); } diff --git a/src/gromacs/commandline/viewit.h b/src/gromacs/commandline/viewit.h index b68d83b20e..58271c15c0 100644 --- a/src/gromacs/commandline/viewit.h +++ b/src/gromacs/commandline/viewit.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,11 +56,11 @@ struct t_filenm; * (but note that if the caller provides program-specific \p opts, setting the * environment variable most likely breaks things). */ -void do_view(const gmx_output_env_t *oenv, const char *fn, const char *opts); +void do_view(const gmx_output_env_t* oenv, const char* fn, const char* opts); /*! \brief * Calls do_view() for all viewable output files. */ -void view_all(const gmx_output_env_t *oenv, int nf, t_filenm fnm[]); +void view_all(const gmx_output_env_t* oenv, int nf, t_filenm fnm[]); #endif diff --git a/src/gromacs/compat/pointers.h b/src/gromacs/compat/pointers.h index bace5b1009..ac3099207e 100644 --- a/src/gromacs/compat/pointers.h +++ b/src/gromacs/compat/pointers.h @@ -43,8 +43,8 @@ * \ingroup module_compat * \inlibraryapi */ - #ifndef GMX_COMPAT_POINTERS_H - #define GMX_COMPAT_POINTERS_H +#ifndef GMX_COMPAT_POINTERS_H +#define GMX_COMPAT_POINTERS_H #include #include @@ -59,14 +59,14 @@ namespace compat //! Contract-assurance macros that work like a simple version of the GSL ones //! \{ #if !defined(__INTEL_COMPILER) || !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 0) -#define Expects(cond) GMX_ASSERT((cond), "Precondition violation") -#define Ensures(cond) GMX_ASSERT((cond), "Postcondition violation") +# define Expects(cond) GMX_ASSERT((cond), "Precondition violation") +# define Ensures(cond) GMX_ASSERT((cond), "Postcondition violation") #else // icc 18.0.0 in a RelWithAssert build has an ICE, even if we directly // embed the contents of GMX_ASSERT, so it seems the lambda in // GMX_ASSERT is too complex for it in this use case. -#define Expects(cond) -#define Ensures(cond) +# define Expects(cond) +# define Ensures(cond) #endif //! \} @@ -85,126 +85,122 @@ namespace compat * \todo Eliminate this when we require a version of C++ that supports * std::not_null. */ -template +template class not_null { - public: - static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); - - //! Move constructor. Asserts in debug mode if \c is nullptr. - template ::value>::type > - constexpr explicit not_null(U &&u) : ptr_(std::forward(u)) - { - Expects(ptr_ != nullptr); - } - - //! Simple constructor. Asserts in debug mode if \c u is nullptr. - template ::value>::type > - constexpr explicit not_null(T u) : ptr_(u) - { - Expects(ptr_ != nullptr); - } - - //! Copy constructor. - template ::value>::type > - constexpr not_null(const not_null &other) : not_null(other.get()) - { - } - - //! Default constructors and assignment. - //! \{ - not_null(not_null &&other) noexcept = default; - not_null(const not_null &other) = default; - not_null &operator=(const not_null &other) = default; - //! \} - - //! Getters - //! \{ - constexpr T get() const - { - Ensures(ptr_ != nullptr); - return ptr_; - } - - constexpr operator T() const { return get(); } - constexpr T operator->() const { return get(); } - //! \} - - //! Deleted to prevent compilation when someone attempts to assign a null pointer constant. - //! \{ - not_null(std::nullptr_t) = delete; - not_null &operator=(std::nullptr_t) = delete; - //! \} - - //! Deleted unwanted operators because pointers only point to single objects. - //! \{ - not_null &operator++() = delete; - not_null &operator--() = delete; - not_null operator++(int) = delete; - not_null operator--(int) = delete; - not_null &operator+=(std::ptrdiff_t) = delete; - not_null &operator-=(std::ptrdiff_t) = delete; - void operator[](std::ptrdiff_t) const = delete; - //! \} - - private: - T ptr_; +public: + static_assert(std::is_assignable::value, "T cannot be assigned nullptr."); + + //! Move constructor. Asserts in debug mode if \c is nullptr. + template::value>::type> + constexpr explicit not_null(U&& u) : ptr_(std::forward(u)) + { + Expects(ptr_ != nullptr); + } + + //! Simple constructor. Asserts in debug mode if \c u is nullptr. + template::value>::type> + constexpr explicit not_null(T u) : ptr_(u) + { + Expects(ptr_ != nullptr); + } + + //! Copy constructor. + template::value>::type> + constexpr not_null(const not_null& other) : not_null(other.get()) + { + } + + //! Default constructors and assignment. + //! \{ + not_null(not_null&& other) noexcept = default; + not_null(const not_null& other) = default; + not_null& operator=(const not_null& other) = default; + //! \} + + //! Getters + //! \{ + constexpr T get() const + { + Ensures(ptr_ != nullptr); + return ptr_; + } + + constexpr operator T() const { return get(); } + constexpr T operator->() const { return get(); } + //! \} + + //! Deleted to prevent compilation when someone attempts to assign a null pointer constant. + //! \{ + not_null(std::nullptr_t) = delete; + not_null& operator=(std::nullptr_t) = delete; + //! \} + + //! Deleted unwanted operators because pointers only point to single objects. + //! \{ + not_null& operator++() = delete; + not_null& operator--() = delete; + not_null operator++(int) = delete; + not_null operator--(int) = delete; + not_null& operator+=(std::ptrdiff_t) = delete; + not_null& operator-=(std::ptrdiff_t) = delete; + void operator[](std::ptrdiff_t) const = delete; + //! \} + +private: + T ptr_; }; //! Convenience function for making not_null pointers from plain pointers. -template -not_null -make_not_null(T &&t) +template +not_null make_not_null(T&& t) { - return not_null < typename std::remove_cv < typename std::remove_reference::type>::type >{ - std::forward(t) + return not_null::type>::type>{ + std::forward(t) }; } //! Convenience function for making not_null pointers from smart pointers. -template -not_null -make_not_null(T &t) +template +not_null make_not_null(T& t) { - return not_null < typename std::remove_reference::type::pointer >{ - t.get() - }; + return not_null::type::pointer>{ t.get() }; } //! Operators to compare not_null pointers. //! \{ -template -auto operator==(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() == rhs.get()) +template +auto operator==(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() == rhs.get()) { return lhs.get() == rhs.get(); } -template -auto operator!=(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() != rhs.get()) +template +auto operator!=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() != rhs.get()) { return lhs.get() != rhs.get(); } -template -auto operator<(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() < rhs.get()) +template +auto operator<(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() < rhs.get()) { return lhs.get() < rhs.get(); } -template -auto operator<=(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() <= rhs.get()) +template +auto operator<=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() <= rhs.get()) { return lhs.get() <= rhs.get(); } -template -auto operator>(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() > rhs.get()) +template +auto operator>(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() > rhs.get()) { return lhs.get() > rhs.get(); } -template -auto operator>=(const not_null &lhs, const not_null &rhs)->decltype(lhs.get() >= rhs.get()) +template +auto operator>=(const not_null& lhs, const not_null& rhs) -> decltype(lhs.get() >= rhs.get()) { return lhs.get() >= rhs.get(); } @@ -212,14 +208,14 @@ auto operator>=(const not_null &lhs, const not_null &rhs)->decltype(lhs.ge //! Deleted unwanted arithmetic operators. //! \{ -template -std::ptrdiff_t operator-(const not_null &, const not_null &) = delete; -template -not_null operator-(const not_null &, std::ptrdiff_t) = delete; -template -not_null operator+(const not_null &, std::ptrdiff_t) = delete; -template -not_null operator+(std::ptrdiff_t, const not_null &) = delete; +template +std::ptrdiff_t operator-(const not_null&, const not_null&) = delete; +template +not_null operator-(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(const not_null&, std::ptrdiff_t) = delete; +template +not_null operator+(std::ptrdiff_t, const not_null&) = delete; //! \} } // namespace compat diff --git a/src/gromacs/compat/tests/pointers.cpp b/src/gromacs/compat/tests/pointers.cpp index 28b7958662..8e7b3f8e4f 100644 --- a/src/gromacs/compat/tests/pointers.cpp +++ b/src/gromacs/compat/tests/pointers.cpp @@ -58,8 +58,7 @@ namespace TEST(NotNullConstruction, Works) { // shared_ptr is nullptr assignable - not_null < std::shared_ptr < int>> sharedPointer( - std::make_shared(10)); + not_null> sharedPointer(std::make_shared(10)); #ifndef NDEBUG /* The workaround here is needed because the intel implementation @@ -67,20 +66,20 @@ TEST(NotNullConstruction, Works) * a valid object. This was needed due to an internal error * being triggered instead with the compiler under this condition. */ -#if !defined(__INTEL_COMPILER) || !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 0) - int *nullPointer = nullptr; - EXPECT_DEATH_IF_SUPPORTED(not_null invalidNullPointer(nullPointer), ""); -#endif +# if !defined(__INTEL_COMPILER) || !(__INTEL_COMPILER == 1800 && __INTEL_COMPILER_UPDATE == 0) + int* nullPointer = nullptr; + EXPECT_DEATH_IF_SUPPORTED(not_null invalidNullPointer(nullPointer), ""); +# endif #endif int value = 20; - int *validPointer = &value; + int* validPointer = &value; { - not_null validNotNullPointer(validPointer); + not_null validNotNullPointer(validPointer); GMX_UNUSED_VALUE(validNotNullPointer); } { - not_null validNotNullPointer = not_null(validPointer); + not_null validNotNullPointer = not_null(validPointer); GMX_UNUSED_VALUE(validNotNullPointer); } } @@ -97,18 +96,14 @@ TEST(NotNullCasting, Works) { }; - MyBase base; - MyDerived derived; - Unrelated unrelated; + MyBase base; + MyDerived derived; + Unrelated unrelated; - not_null u { - &unrelated - }; - (void) u; - not_null p { - &derived - }; - not_null q(&base); + not_null u{ &unrelated }; + (void)u; + not_null p{ &derived }; + not_null q(&base); // Allowed with heterogeneous copy constructor q = p; @@ -126,13 +121,13 @@ TEST(NotNullAssignment, Works) TEST(MakeNotNull, Works) { { - int i = 42; + int i = 42; - const not_null x = make_not_null(&i); + const not_null x = make_not_null(&i); EXPECT_EQ(*x, 42); - not_null y = make_not_null(&i); + not_null y = make_not_null(&i); EXPECT_EQ(*y, 42); - not_null z = make_not_null(&i); + not_null z = make_not_null(&i); EXPECT_EQ(*z, 42); } @@ -154,24 +149,23 @@ TEST(MakeNotNull, Works) } { - std::unique_ptr i = std::make_unique(42); + std::unique_ptr i = std::make_unique(42); - const not_null x = make_not_null(i); + const not_null x = make_not_null(i); EXPECT_EQ(*x, 42); - not_null y = make_not_null(i); + not_null y = make_not_null(i); EXPECT_EQ(*y, 42); - not_null z = make_not_null(i); + not_null z = make_not_null(i); EXPECT_EQ(*z, 42); } { - std::unique_ptr i = std::make_unique(42); + std::unique_ptr i = std::make_unique(42); // not_null does not compile, as expected - not_null z = make_not_null(i); + not_null z = make_not_null(i); EXPECT_EQ(*z, 42); } - } TEST(NotNull, WorksInContainers) @@ -179,7 +173,7 @@ TEST(NotNull, WorksInContainers) int i = 12; not_null p(&i); - std::vector < not_null < int*>> v; + std::vector> v; v.push_back(p); EXPECT_EQ(*v.back(), 12); } diff --git a/src/gromacs/compat/utility.h b/src/gromacs/compat/utility.h index 28be2a2cc8..c3fcdc6c5f 100644 --- a/src/gromacs/compat/utility.h +++ b/src/gromacs/compat/utility.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,15 +40,15 @@ * \ingroup module_compat * \inlibraryapi */ - #ifndef GMX_COMPAT_UTILITY_H - #define GMX_COMPAT_UTILITY_H +#ifndef GMX_COMPAT_UTILITY_H +#define GMX_COMPAT_UTILITY_H namespace gmx { namespace compat { //! Forms lvalue reference to const type of t -template -constexpr const T &as_const(T &t) noexcept +template +constexpr const T& as_const(T& t) noexcept { return t; } diff --git a/src/gromacs/coordinateio/coordinatefile.cpp b/src/gromacs/coordinateio/coordinatefile.cpp index 8d9c81a636..4c245b1272 100644 --- a/src/gromacs/coordinateio/coordinatefile.cpp +++ b/src/gromacs/coordinateio/coordinatefile.cpp @@ -64,7 +64,7 @@ namespace gmx * \throws InvalidInputError When unable to work on an emoty file name. * \returns integer value of file type. */ -static int getFileType(const std::string &filename) +static int getFileType(const std::string& filename) { int filetype = efNR; if (!filename.empty()) @@ -95,31 +95,30 @@ static unsigned long getSupportedOutputAdapters(int filetype) switch (filetype) { case (efTNG): - supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireForceOutput) | - convertFlag(CoordinateFileFlags::RequireVelocityOutput) | - convertFlag(CoordinateFileFlags::RequireAtomConnections) | - convertFlag(CoordinateFileFlags::RequireAtomInformation) | - convertFlag(CoordinateFileFlags::RequireChangedOutputPrecision)); + supportedOutputAdapters |= + (convertFlag(CoordinateFileFlags::RequireForceOutput) + | convertFlag(CoordinateFileFlags::RequireVelocityOutput) + | convertFlag(CoordinateFileFlags::RequireAtomConnections) + | convertFlag(CoordinateFileFlags::RequireAtomInformation) + | convertFlag(CoordinateFileFlags::RequireChangedOutputPrecision)); break; case (efPDB): - supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireAtomConnections) | - convertFlag(CoordinateFileFlags::RequireAtomInformation)); + supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireAtomConnections) + | convertFlag(CoordinateFileFlags::RequireAtomInformation)); break; case (efGRO): - supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireAtomInformation) | - convertFlag(CoordinateFileFlags::RequireVelocityOutput)); + supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireAtomInformation) + | convertFlag(CoordinateFileFlags::RequireVelocityOutput)); break; case (efTRR): - supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireForceOutput) | - convertFlag(CoordinateFileFlags::RequireVelocityOutput)); + supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireForceOutput) + | convertFlag(CoordinateFileFlags::RequireVelocityOutput)); break; case (efXTC): supportedOutputAdapters |= (convertFlag(CoordinateFileFlags::RequireChangedOutputPrecision)); break; - case (efG96): - break; - default: - GMX_THROW(InvalidInputError("Invalid file type")); + case (efG96): break; + default: GMX_THROW(InvalidInputError("Invalid file type")); } return supportedOutputAdapters; } @@ -134,11 +133,10 @@ static unsigned long getSupportedOutputAdapters(int filetype) * \param[in] abilities Specifications for what the output method can do. * \returns New container for IoutputAdapter derived methods. */ -static OutputAdapterContainer -addOutputAdapters(const OutputRequirements &requirements, - AtomsDataPtr atoms, - const Selection &sel, - unsigned long abilities) +static OutputAdapterContainer addOutputAdapters(const OutputRequirements& requirements, + AtomsDataPtr atoms, + const Selection& sel, + unsigned long abilities) { OutputAdapterContainer output(abilities); @@ -149,28 +147,23 @@ addOutputAdapters(const OutputRequirements &requirements, */ if (requirements.velocity != ChangeSettingType::PreservedIfPresent) { - output.addAdapter( - std::make_unique(requirements.velocity), - CoordinateFileFlags::RequireVelocityOutput); + output.addAdapter(std::make_unique(requirements.velocity), + CoordinateFileFlags::RequireVelocityOutput); } if (requirements.force != ChangeSettingType::PreservedIfPresent) { - output.addAdapter( - std::make_unique(requirements.force), - CoordinateFileFlags::RequireForceOutput); + output.addAdapter(std::make_unique(requirements.force), + CoordinateFileFlags::RequireForceOutput); } if (requirements.precision != ChangeFrameInfoType::PreservedIfPresent) { - output.addAdapter( - std::make_unique(requirements.prec), - CoordinateFileFlags::RequireChangedOutputPrecision); + output.addAdapter(std::make_unique(requirements.prec), + CoordinateFileFlags::RequireChangedOutputPrecision); } if (requirements.atoms != ChangeAtomsType::PreservedIfPresent) { - output.addAdapter( - std::make_unique(requirements.atoms, - std::move(atoms)), - CoordinateFileFlags::RequireAtomInformation); + output.addAdapter(std::make_unique(requirements.atoms, std::move(atoms)), + CoordinateFileFlags::RequireAtomInformation); } if (requirements.frameTime != ChangeFrameTimeType::PreservedIfPresent) { @@ -190,31 +183,26 @@ addOutputAdapters(const OutputRequirements &requirements, output.addAdapter(std::make_unique(requirements.timeStepValue), CoordinateFileFlags::RequireNewFrameTimeStep); break; - default: - break; + default: break; } } if (requirements.box != ChangeFrameInfoType::PreservedIfPresent) { - output.addAdapter( - std::make_unique(requirements.newBox), - CoordinateFileFlags::RequireNewBox); + output.addAdapter(std::make_unique(requirements.newBox), CoordinateFileFlags::RequireNewBox); } if (sel.isValid()) { - output.addAdapter( - std::make_unique(sel), - CoordinateFileFlags::RequireCoordinateSelection); + output.addAdapter(std::make_unique(sel), + CoordinateFileFlags::RequireCoordinateSelection); } return output; } -std::unique_ptr -createTrajectoryFrameWriter(const gmx_mtop_t *top, - const Selection &sel, - const std::string &filename, - AtomsDataPtr atoms, - OutputRequirements requirements) +std::unique_ptr createTrajectoryFrameWriter(const gmx_mtop_t* top, + const Selection& sel, + const std::string& filename, + AtomsDataPtr atoms, + OutputRequirements requirements) { /* TODO * Currently the requirements object is expected to be processed and valid, @@ -223,31 +211,28 @@ createTrajectoryFrameWriter(const gmx_mtop_t *top, * This will need to get revisited when the code that builds this object from * the user options gets merged. */ - int filetype = getFileType(filename); - unsigned long abilities = getSupportedOutputAdapters(filetype); + int filetype = getFileType(filename); + unsigned long abilities = getSupportedOutputAdapters(filetype); // first, check if we have a special output format that needs atoms if ((filetype == efPDB) || (filetype == efGRO)) { if (requirements.atoms == ChangeAtomsType::Never) { - GMX_THROW(InconsistentInputError("Can not write to PDB or GRO when" - "explicitly turning atom information off")); + GMX_THROW( + InconsistentInputError("Can not write to PDB or GRO when" + "explicitly turning atom information off")); } if (requirements.atoms != ChangeAtomsType::AlwaysFromStructure) { requirements.atoms = ChangeAtomsType::Always; } } - OutputAdapterContainer outputAdapters = addOutputAdapters(requirements, std::move(atoms), - sel, abilities); + OutputAdapterContainer outputAdapters = + addOutputAdapters(requirements, std::move(atoms), sel, abilities); TrajectoryFrameWriterPointer trajectoryFrameWriter( - new TrajectoryFrameWriter(filename, - filetype, - sel, - top, - std::move(outputAdapters))); + new TrajectoryFrameWriter(filename, filetype, sel, top, std::move(outputAdapters))); return trajectoryFrameWriter; } @@ -272,12 +257,8 @@ createTrajectoryFrameWriter(const gmx_mtop_t *top, * \param[in] fvec Pointer to local force storage vector. * \param[in] indexvec Pointer to local index storage vector. */ -static void deepCopy_t_trxframe(const t_trxframe &input, - t_trxframe *copy, - RVec *xvec, - RVec *vvec, - RVec *fvec, - int *indexvec) +static void +deepCopy_t_trxframe(const t_trxframe& input, t_trxframe* copy, RVec* xvec, RVec* vvec, RVec* fvec, int* indexvec) { copy->not_ok = input.not_ok; copy->bStep = input.bStep; @@ -300,7 +281,7 @@ static void deepCopy_t_trxframe(const t_trxframe &input, { copy->atoms = input.atoms; } - copy->prec = input.prec; + copy->prec = input.prec; if (copy->bX) { copy->x = as_rvec_array(xvec); @@ -341,8 +322,8 @@ static void deepCopy_t_trxframe(const t_trxframe &input, } } copy_mat(input.box, copy->box); - copy->bPBC = input.bPBC; - copy->ePBC = input.ePBC; + copy->bPBC = input.bPBC; + copy->ePBC = input.ePBC; } /*! \brief @@ -357,30 +338,22 @@ static void deepCopy_t_trxframe(const t_trxframe &input, * \param[in] mtop Pointer to topology, tested before that it is valid. * \todo Those should be methods in a replacement for t_trxstatus instead. */ -static t_trxstatus *openTNG(const std::string &name, const Selection &sel, const gmx_mtop_t *mtop) +static t_trxstatus* openTNG(const std::string& name, const Selection& sel, const gmx_mtop_t* mtop) { - const char *filemode = "w"; + const char* filemode = "w"; if (sel.isValid()) { GMX_ASSERT(sel.hasOnlyAtoms(), "Can only work with selections consisting out of atoms"); - return trjtools_gmx_prepare_tng_writing(name.c_str(), - filemode[0], - nullptr, //infile_, //how to get the input file here? - nullptr, - sel.atomCount(), - mtop, - sel.atomIndices(), + return trjtools_gmx_prepare_tng_writing(name.c_str(), filemode[0], + nullptr, // infile_, //how to get the input file here? + nullptr, sel.atomCount(), mtop, sel.atomIndices(), sel.name()); } else { - return trjtools_gmx_prepare_tng_writing(name.c_str(), - filemode[0], - nullptr, //infile_, //how to get the input file here? - nullptr, - mtop->natoms, - mtop, - get_atom_index(mtop), + return trjtools_gmx_prepare_tng_writing(name.c_str(), filemode[0], + nullptr, // infile_, //how to get the input file here? + nullptr, mtop->natoms, mtop, get_atom_index(mtop), "System"); } } @@ -390,34 +363,26 @@ TrajectoryFileOpener::~TrajectoryFileOpener() close_trx(outputFile_); } -t_trxstatus *TrajectoryFileOpener::outputFile() +t_trxstatus* TrajectoryFileOpener::outputFile() { if (outputFile_ == nullptr) { - const char *filemode = "w"; + const char* filemode = "w"; switch (filetype_) { - case (efTNG): - outputFile_ = openTNG(outputFileName_, - sel_, - mtop_); - break; + case (efTNG): outputFile_ = openTNG(outputFileName_, sel_, mtop_); break; case (efPDB): case (efGRO): case (efTRR): case (efXTC): - case (efG96): - outputFile_ = open_trx(outputFileName_.c_str(), filemode); - break; - default: - GMX_THROW(InvalidInputError("Invalid file type")); + case (efG96): outputFile_ = open_trx(outputFileName_.c_str(), filemode); break; + default: GMX_THROW(InvalidInputError("Invalid file type")); } } return outputFile_; } -void -TrajectoryFrameWriter::prepareAndWriteFrame(const int framenumber, const t_trxframe &input) +void TrajectoryFrameWriter::prepareAndWriteFrame(const int framenumber, const t_trxframe& input) { if (!outputAdapters_.isEmpty()) { @@ -433,9 +398,9 @@ TrajectoryFrameWriter::prepareAndWriteFrame(const int framenumber, const t_trxfr { localF_.resize(input.natoms); } - deepCopy_t_trxframe(input, &local, localX_.data(), localV_.data(), - localF_.data(), localIndex_.data()); - for (const auto &outputAdapter : outputAdapters_.getAdapters()) + deepCopy_t_trxframe(input, &local, localX_.data(), localV_.data(), localF_.data(), + localIndex_.data()); + for (const auto& outputAdapter : outputAdapters_.getAdapters()) { if (outputAdapter) { @@ -446,7 +411,7 @@ TrajectoryFrameWriter::prepareAndWriteFrame(const int framenumber, const t_trxfr } else { - write_trxframe(file_.outputFile(), const_cast(&input), nullptr); + write_trxframe(file_.outputFile(), const_cast(&input), nullptr); } } diff --git a/src/gromacs/coordinateio/coordinatefile.h b/src/gromacs/coordinateio/coordinatefile.h index 17cf7ea448..dfd8227573 100644 --- a/src/gromacs/coordinateio/coordinatefile.h +++ b/src/gromacs/coordinateio/coordinatefile.h @@ -81,9 +81,9 @@ struct OutputRequirements; * OutputAdapters should be registered. * \throws InconsistentInputError When user input and requirements don't match. */ -std::unique_ptr createTrajectoryFrameWriter(const gmx_mtop_t *top, - const Selection &sel, - const std::string &filename, +std::unique_ptr createTrajectoryFrameWriter(const gmx_mtop_t* top, + const Selection& sel, + const std::string& filename, AtomsDataPtr atoms, OutputRequirements requirements); @@ -96,58 +96,60 @@ std::unique_ptr createTrajectoryFrameWriter(const gmx_mto */ class TrajectoryFileOpener { - public: - /*! \brief - * Constructor, taking all arguments needed to open valid coordinate files of any type. - * - * \param[in] name Name of the file to create. - * \param[in] filetype Internal filetype to know which kind we are going to have. - * \param[in] sel Reference to selection of atoms to write. Needs to be valid for - * longer than the lifetime of the object created here. - * \param[in] mtop Topology used to create TNG output. Needs to be valid for longer - * than the object created here. - */ - TrajectoryFileOpener(const std::string &name, - int filetype, - const Selection &sel, - const gmx_mtop_t *mtop) : - outputFileName_(name), outputFile_(nullptr), filetype_(filetype), sel_(sel), mtop_(mtop) - {} - - /*! \brief - * Closes new trajectory file after finishing the writing to it. - */ - ~TrajectoryFileOpener(); - - /*! \brief - * Get access to initialized output file object. - * - * Performs lazy initialization if needed. - */ - t_trxstatus *outputFile(); - - private: - //! Name for the new coordinate file. - std::string outputFileName_; - - //! File pointer to the coordinate file being written. - t_trxstatus *outputFile_; - - //! Storage of file type for determing what kind of file will be written to disk. - int filetype_; - - /*! \brief - * Selection of atoms to write out. - * - * Currently, CoordinateFile expects that the lifetime of the selection is longer - * than that of itself, and that the selection remains unchanged during this lifetime. - * A better approach will be to pass the selection to it and expect it to - * manage the lifetime instead. - */ - const Selection &sel_; - - //! Pointer to topology information if available. - const gmx_mtop_t *mtop_; +public: + /*! \brief + * Constructor, taking all arguments needed to open valid coordinate files of any type. + * + * \param[in] name Name of the file to create. + * \param[in] filetype Internal filetype to know which kind we are going to have. + * \param[in] sel Reference to selection of atoms to write. Needs to be valid for + * longer than the lifetime of the object created here. + * \param[in] mtop Topology used to create TNG output. Needs to be valid for longer + * than the object created here. + */ + TrajectoryFileOpener(const std::string& name, int filetype, const Selection& sel, const gmx_mtop_t* mtop) : + outputFileName_(name), + outputFile_(nullptr), + filetype_(filetype), + sel_(sel), + mtop_(mtop) + { + } + + /*! \brief + * Closes new trajectory file after finishing the writing to it. + */ + ~TrajectoryFileOpener(); + + /*! \brief + * Get access to initialized output file object. + * + * Performs lazy initialization if needed. + */ + t_trxstatus* outputFile(); + +private: + //! Name for the new coordinate file. + std::string outputFileName_; + + //! File pointer to the coordinate file being written. + t_trxstatus* outputFile_; + + //! Storage of file type for determing what kind of file will be written to disk. + int filetype_; + + /*! \brief + * Selection of atoms to write out. + * + * Currently, CoordinateFile expects that the lifetime of the selection is longer + * than that of itself, and that the selection remains unchanged during this lifetime. + * A better approach will be to pass the selection to it and expect it to + * manage the lifetime instead. + */ + const Selection& sel_; + + //! Pointer to topology information if available. + const gmx_mtop_t* mtop_; }; /*!\brief @@ -164,60 +166,59 @@ class TrajectoryFileOpener */ class TrajectoryFrameWriter { - public: - friend std::unique_ptr - createTrajectoryFrameWriter(const gmx_mtop_t *top, - const Selection &sel, - const std::string &filename, - AtomsDataPtr atoms, - OutputRequirements requirements); - - /*! \brief - * Writes the input frame, after applying any IOutputAdapters. - * - * \param[in] framenumber Number of frame being currently processed. - * \param[in] input View of the constant t_trxframe object provided by the - * method that calls the output manager. - */ - void prepareAndWriteFrame(int framenumber, const t_trxframe &input); - - private: - /*! \brief - * Creates fully initialized object. - * - * \param[in] name Name of the file to create. - * \param[in] filetype Internal filetype to know which kind we are going to have. - * \param[in] sel Reference to selection of atoms to write. Needs to be valid for - * longer than the lifetime of the object created here. - * \param[in] mtop Topology used to create TNG output. Needs to be valid for longer - * than the object created here. - * \param[in] adapters Container of methods that can modify the information written - * to the new file. - */ - TrajectoryFrameWriter(const std::string &name, - int filetype, - const Selection &sel, - const gmx_mtop_t *mtop, - OutputAdapterContainer adapters) : - file_(name, filetype, sel, mtop), - outputAdapters_(std::move(adapters)) - { - } - - //! Underlying object for open/writing to file. - TrajectoryFileOpener file_; - - //! Storage for list of output adapters. - OutputAdapterContainer outputAdapters_; - - //! Local storage for modified positions. - std::vector localX_; - //! Local storage for modified velocities. - std::vector localV_; - //! Local storage for modified forces. - std::vector localF_; - //! Local storage for modified indices. - std::vector localIndex_; +public: + friend std::unique_ptr createTrajectoryFrameWriter(const gmx_mtop_t* top, + const Selection& sel, + const std::string& filename, + AtomsDataPtr atoms, + OutputRequirements requirements); + + /*! \brief + * Writes the input frame, after applying any IOutputAdapters. + * + * \param[in] framenumber Number of frame being currently processed. + * \param[in] input View of the constant t_trxframe object provided by the + * method that calls the output manager. + */ + void prepareAndWriteFrame(int framenumber, const t_trxframe& input); + +private: + /*! \brief + * Creates fully initialized object. + * + * \param[in] name Name of the file to create. + * \param[in] filetype Internal filetype to know which kind we are going to have. + * \param[in] sel Reference to selection of atoms to write. Needs to be valid for + * longer than the lifetime of the object created here. + * \param[in] mtop Topology used to create TNG output. Needs to be valid for longer + * than the object created here. + * \param[in] adapters Container of methods that can modify the information written + * to the new file. + */ + TrajectoryFrameWriter(const std::string& name, + int filetype, + const Selection& sel, + const gmx_mtop_t* mtop, + OutputAdapterContainer adapters) : + file_(name, filetype, sel, mtop), + outputAdapters_(std::move(adapters)) + { + } + + //! Underlying object for open/writing to file. + TrajectoryFileOpener file_; + + //! Storage for list of output adapters. + OutputAdapterContainer outputAdapters_; + + //! Local storage for modified positions. + std::vector localX_; + //! Local storage for modified velocities. + std::vector localV_; + //! Local storage for modified forces. + std::vector localF_; + //! Local storage for modified indices. + std::vector localIndex_; }; //! Smart pointer to manage the TrajectoryFrameWriter object. diff --git a/src/gromacs/coordinateio/enums.h b/src/gromacs/coordinateio/enums.h index b03963b3ee..ecd2d4652c 100644 --- a/src/gromacs/coordinateio/enums.h +++ b/src/gromacs/coordinateio/enums.h @@ -71,21 +71,21 @@ enum class CoordinateFileFlags : unsigned long * Sets the flags to default setting to make sure all output methods * are supported. */ - Base = 1<<0, + Base = 1 << 0, /*! \brief * Requires output method to support force output. * * If set, only output methods supporting writing of forces will work, * others will generate an invalid input error. */ - RequireForceOutput = 1<<1, + RequireForceOutput = 1 << 1, /*! \brief * Requires output method to support velocity output. * * If set, only writing to files that support velocity output will succeed. * Other writing methods will generate an error. */ - RequireVelocityOutput = 1<<2, + RequireVelocityOutput = 1 << 2, /*! \brief * Requires support for connection information in output format. * @@ -93,40 +93,40 @@ enum class CoordinateFileFlags : unsigned long * This means for now that only PDB and TNG files can be written. Other file writing * methods will fail. */ - RequireAtomConnections = 1<<3, + RequireAtomConnections = 1 << 3, /*! \brief * Requires that output format supports the writing of atom information to the file. * * If set, files will only be written if they can output the information from t_atoms * and otherwise create an error while writing. */ - RequireAtomInformation = 1<<4, + RequireAtomInformation = 1 << 4, /*! \brief * Requires that output format supports writing user-specified output precision. * * If set, output will only be written if the format supports the writing * of custom precision of the included data. */ - RequireChangedOutputPrecision = 1<<5, + RequireChangedOutputPrecision = 1 << 5, /*! \brief * Requires that output format supports writing time to the file. */ - RequireNewFrameStartTime = 1<<6, + RequireNewFrameStartTime = 1 << 6, /*! \brief * Requires that output format supports writing time to the file. */ - RequireNewFrameTimeStep = 1<<7, + RequireNewFrameTimeStep = 1 << 7, /*! \brief * Requires that output format supports writing box information. */ - RequireNewBox = 1<<8, + RequireNewBox = 1 << 8, /*! \brief * Requires output to support changes to selection of coordinates. * * Default for most methods, will need to be able to write coordinates to * output file or generate an error. */ - RequireCoordinateSelection = 1<<9, + RequireCoordinateSelection = 1 << 9, //! Needed for enumeration array. Count }; @@ -145,9 +145,7 @@ enum class ChangeSettingType Never }; //! Mapping for enums from \ref ChangeSettingType. -const char *const cChangeSettingTypeEnum[] = { - "preserved-if-present", "always", "never" -}; +const char* const cChangeSettingTypeEnum[] = { "preserved-if-present", "always", "never" }; //! Enum class for t_atoms settings enum class ChangeAtomsType @@ -159,9 +157,8 @@ enum class ChangeAtomsType }; //! Mapping for enums from \ref ChangeAtomsType. -const char *const cChangeAtomsTypeEnum[] = { - "preserved-if-present", "always-from-structure", "never", "always" -}; +const char* const cChangeAtomsTypeEnum[] = { "preserved-if-present", "always-from-structure", + "never", "always" }; //! Enum class for setting fields new or not. enum class ChangeFrameInfoType @@ -170,9 +167,7 @@ enum class ChangeFrameInfoType Always }; //! Mapping for enums from \ref ChangeFrameInfoType. -const char *const cChangeFrameInfoTypeEnum[] = { - "preserved-if-present", "always" -}; +const char* const cChangeFrameInfoTypeEnum[] = { "preserved-if-present", "always" }; //! Enum class for setting frame time from user input. enum class ChangeFrameTimeType @@ -184,9 +179,8 @@ enum class ChangeFrameTimeType }; //! Mapping for values from \ref ChangeFrameTimeType. -const char *const cChangeFrameTimeTypeEnum[] = { - "preserved-if-present", "starttime", "timestep", "both" -}; +const char* const cChangeFrameTimeTypeEnum[] = { "preserved-if-present", "starttime", "timestep", + "both" }; } // namespace gmx diff --git a/src/gromacs/coordinateio/ioutputadapter.h b/src/gromacs/coordinateio/ioutputadapter.h index f57e6f27d1..a21ae8cd95 100644 --- a/src/gromacs/coordinateio/ioutputadapter.h +++ b/src/gromacs/coordinateio/ioutputadapter.h @@ -69,46 +69,41 @@ namespace gmx */ class IOutputAdapter { - public: - /*! \brief - * Default constructor for IOutputAdapter interface. - */ - IOutputAdapter() - { - } - virtual ~IOutputAdapter() - { - } - //! Move constructor for old object. - explicit IOutputAdapter(IOutputAdapter &&old) noexcept = default; +public: + /*! \brief + * Default constructor for IOutputAdapter interface. + */ + IOutputAdapter() {} + virtual ~IOutputAdapter() {} + //! Move constructor for old object. + explicit IOutputAdapter(IOutputAdapter&& old) noexcept = default; - /*! \brief - * Change t_trxframe according to user input. - * - * \param[in] framenumber Frame number as reported from the - * trajectoryanalysis framework or set by user. - * \param[in,out] input Pointer to trajectory analysis frame that will - * be worked on. - */ - virtual void processFrame(int framenumber, t_trxframe *input) = 0; + /*! \brief + * Change t_trxframe according to user input. + * + * \param[in] framenumber Frame number as reported from the + * trajectoryanalysis framework or set by user. + * \param[in,out] input Pointer to trajectory analysis frame that will + * be worked on. + */ + virtual void processFrame(int framenumber, t_trxframe* input) = 0; - /*! \brief - * Checks that the abilities of the output writer are sufficient for this adapter. - * - * It can happen that a method to write coordinate files does not match with - * a requested operation on the input data (e.g. the user requires velocities or - * forces to be written to a PDB file). - * To check those dependencies, derived classes need to implement a version of this - * function to make sure that only matching methods can be used. - * - * \param[in] abilities The abilities of an output method that need to be checked against - * the dependencies created by using the derived method. - * \throws InconsistentInputError If dependencies can not be matched to abilities. - */ - virtual void checkAbilityDependencies(unsigned long abilities) const = 0; - - GMX_DISALLOW_COPY_AND_ASSIGN(IOutputAdapter); + /*! \brief + * Checks that the abilities of the output writer are sufficient for this adapter. + * + * It can happen that a method to write coordinate files does not match with + * a requested operation on the input data (e.g. the user requires velocities or + * forces to be written to a PDB file). + * To check those dependencies, derived classes need to implement a version of this + * function to make sure that only matching methods can be used. + * + * \param[in] abilities The abilities of an output method that need to be checked against + * the dependencies created by using the derived method. + * \throws InconsistentInputError If dependencies can not be matched to abilities. + */ + virtual void checkAbilityDependencies(unsigned long abilities) const = 0; + GMX_DISALLOW_COPY_AND_ASSIGN(IOutputAdapter); }; //! Smart pointer to manage the frame adapter object. diff --git a/src/gromacs/coordinateio/outputadaptercontainer.cpp b/src/gromacs/coordinateio/outputadaptercontainer.cpp index bc9501f813..d2febd7064 100644 --- a/src/gromacs/coordinateio/outputadaptercontainer.cpp +++ b/src/gromacs/coordinateio/outputadaptercontainer.cpp @@ -52,9 +52,7 @@ namespace gmx { -void -OutputAdapterContainer::addAdapter(OutputAdapterPointer adapter, - CoordinateFileFlags type) +void OutputAdapterContainer::addAdapter(OutputAdapterPointer adapter, CoordinateFileFlags type) { if (outputAdapters_[type] != nullptr) { @@ -64,10 +62,9 @@ OutputAdapterContainer::addAdapter(OutputAdapterPointer adapter, outputAdapters_[type] = std::move(adapter); } -bool -OutputAdapterContainer::isEmpty() const +bool OutputAdapterContainer::isEmpty() const { return std::none_of(outputAdapters_.begin(), outputAdapters_.end(), - [](const auto &adapter){ return adapter != nullptr; }); + [](const auto& adapter) { return adapter != nullptr; }); } } // namespace gmx diff --git a/src/gromacs/coordinateio/outputadaptercontainer.h b/src/gromacs/coordinateio/outputadaptercontainer.h index 1029dd0939..f5d2fd67b2 100644 --- a/src/gromacs/coordinateio/outputadaptercontainer.h +++ b/src/gromacs/coordinateio/outputadaptercontainer.h @@ -79,43 +79,41 @@ namespace gmx */ class OutputAdapterContainer { - public: - //! Only allow constructing the container with defined output abilities. - explicit OutputAdapterContainer(unsigned long abilities) - : abilities_(abilities) - {} - //! Allow abilities to be also defined using the enum class. - explicit OutputAdapterContainer(CoordinateFileFlags abilities) - : abilities_(convertFlag(abilities)) - {} +public: + //! Only allow constructing the container with defined output abilities. + explicit OutputAdapterContainer(unsigned long abilities) : abilities_(abilities) {} + //! Allow abilities to be also defined using the enum class. + explicit OutputAdapterContainer(CoordinateFileFlags abilities) : + abilities_(convertFlag(abilities)) + { + } - /*! \brief - * Add an adapter of a type not previously added. - * - * Only one adapter of each type can be registered, and the order of adapters - * is predefined in the underlying storage object. - * Calls internal checks to make sure that the new adapter does not violate - * any of the preconditions set to make an CoordinateFile object containing - * the registered modules. - * - * \param[in] adapter unique_ptr to adapter, with container taking ownership here. - * \param[in] type What kind of adapter is being added. - * \throws InternalError When registering an adapter of a type already registered . - * \throws InconsistentInputError When incompatible modules are added. - */ - void addAdapter(OutputAdapterPointer adapter, - CoordinateFileFlags type); + /*! \brief + * Add an adapter of a type not previously added. + * + * Only one adapter of each type can be registered, and the order of adapters + * is predefined in the underlying storage object. + * Calls internal checks to make sure that the new adapter does not violate + * any of the preconditions set to make an CoordinateFile object containing + * the registered modules. + * + * \param[in] adapter unique_ptr to adapter, with container taking ownership here. + * \param[in] type What kind of adapter is being added. + * \throws InternalError When registering an adapter of a type already registered . + * \throws InconsistentInputError When incompatible modules are added. + */ + void addAdapter(OutputAdapterPointer adapter, CoordinateFileFlags type); - //! Get vector of all registered adapters. - ArrayRef getAdapters() { return outputAdapters_; } - //! Get info if we have any registered adapters. - bool isEmpty() const; + //! Get vector of all registered adapters. + ArrayRef getAdapters() { return outputAdapters_; } + //! Get info if we have any registered adapters. + bool isEmpty() const; - private: - //! Array of registered modules. - EnumerationArray outputAdapters_; - //! Construction time bitmask declaring what the OutputManager can do. - unsigned long abilities_ = convertFlag(CoordinateFileFlags::Base); +private: + //! Array of registered modules. + EnumerationArray outputAdapters_; + //! Construction time bitmask declaring what the OutputManager can do. + unsigned long abilities_ = convertFlag(CoordinateFileFlags::Base); }; } // namespace gmx diff --git a/src/gromacs/coordinateio/outputadapters/outputselector.cpp b/src/gromacs/coordinateio/outputadapters/outputselector.cpp index 44bb7517fa..375c51c6d4 100644 --- a/src/gromacs/coordinateio/outputadapters/outputselector.cpp +++ b/src/gromacs/coordinateio/outputadapters/outputselector.cpp @@ -64,9 +64,9 @@ namespace gmx * \param[in] selectionAtoms Pointer to local atoms. * \param[in] sel Reference to selection. */ -static void adjustAtomInformation(t_atoms *atoms, t_atoms *selectionAtoms, const Selection &sel) +static void adjustAtomInformation(t_atoms* atoms, t_atoms* selectionAtoms, const Selection& sel) { - int natoms = sel.atomCount(); + int natoms = sel.atomCount(); selectionAtoms->nr = natoms; selectionAtoms->nres = atoms->nres; @@ -96,7 +96,7 @@ static void adjustAtomInformation(t_atoms *atoms, t_atoms *selectionAtoms, const for (int i = 0; i < natoms; i++) { - int pos = sel.position(i).refId(); + int pos = sel.position(i).refId(); selectionAtoms->atom[i] = atoms->atom[pos]; selectionAtoms->atomname[i] = atoms->atomname[pos]; if (selectionAtoms->haveType) @@ -119,8 +119,7 @@ static void adjustAtomInformation(t_atoms *atoms, t_atoms *selectionAtoms, const } } -void -OutputSelector::processFrame(const int /*framenumber*/, t_trxframe *input) +void OutputSelector::processFrame(const int /*framenumber*/, t_trxframe* input) { size_t natoms = sel_.atomCount(); diff --git a/src/gromacs/coordinateio/outputadapters/outputselector.h b/src/gromacs/coordinateio/outputadapters/outputselector.h index 0f1a854f3c..4fc9e178f6 100644 --- a/src/gromacs/coordinateio/outputadapters/outputselector.h +++ b/src/gromacs/coordinateio/outputadapters/outputselector.h @@ -66,63 +66,61 @@ namespace gmx */ class OutputSelector : public IOutputAdapter { - public: - /*! \brief - * Construct OutputSelector object with initial selection. - * - * Can be used to initialize OutputSelector from outside of trajectoryanalysis - * framework. - */ - explicit OutputSelector(const Selection &sel) : - sel_(sel), selectionAtoms_(nullptr) - { - GMX_RELEASE_ASSERT(sel.isValid() && sel.hasOnlyAtoms(), - "Need a valid selection out of simple atom indices"); - } - /*! \brief - * Move assignment constructor for OutputSelector. - */ - OutputSelector(OutputSelector &&old) noexcept = default; +public: + /*! \brief + * Construct OutputSelector object with initial selection. + * + * Can be used to initialize OutputSelector from outside of trajectoryanalysis + * framework. + */ + explicit OutputSelector(const Selection& sel) : sel_(sel), selectionAtoms_(nullptr) + { + GMX_RELEASE_ASSERT(sel.isValid() && sel.hasOnlyAtoms(), + "Need a valid selection out of simple atom indices"); + } + /*! \brief + * Move assignment constructor for OutputSelector. + */ + OutputSelector(OutputSelector&& old) noexcept = default; - ~OutputSelector() override {} + ~OutputSelector() override {} - /*! \brief - * Change coordinate frame information for output. - * - * Takes the previously internally stored coordinates and saves them again. - * Applies correct number of atoms in this case. - * - * \param[in] input Coordinate frame to be modified later. - */ - void processFrame(int /*framenumber*/, t_trxframe *input) override; + /*! \brief + * Change coordinate frame information for output. + * + * Takes the previously internally stored coordinates and saves them again. + * Applies correct number of atoms in this case. + * + * \param[in] input Coordinate frame to be modified later. + */ + void processFrame(int /*framenumber*/, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long /* abilities */) const override {} + void checkAbilityDependencies(unsigned long /* abilities */) const override {} - private: - - /*! \brief - * Selection of atoms that will be written to disk. - * - * Internal selection of atoms chosen by the user that will be written - * to disk during processing. - */ - const Selection &sel_; - /*! \brief - * Local storage of modified atoms. - * - * When selection input information, we might will have to adjust the - * atoms content to match the new output. To perform this, we keep track - * of modified atoms information in this object that is not used by default. - */ - AtomsDataPtr selectionAtoms_; - //! Local storage for coordinates - std::vector localX_; - //! Local storage for velocities - std::vector localV_; - //! Local storage for forces - std::vector localF_; - //! Local storage for atom indices - std::vector localIndex_; +private: + /*! \brief + * Selection of atoms that will be written to disk. + * + * Internal selection of atoms chosen by the user that will be written + * to disk during processing. + */ + const Selection& sel_; + /*! \brief + * Local storage of modified atoms. + * + * When selection input information, we might will have to adjust the + * atoms content to match the new output. To perform this, we keep track + * of modified atoms information in this object that is not used by default. + */ + AtomsDataPtr selectionAtoms_; + //! Local storage for coordinates + std::vector localX_; + //! Local storage for velocities + std::vector localV_; + //! Local storage for forces + std::vector localF_; + //! Local storage for atom indices + std::vector localIndex_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/setatoms.cpp b/src/gromacs/coordinateio/outputadapters/setatoms.cpp index 7baddea6ef..a450cf6379 100644 --- a/src/gromacs/coordinateio/outputadapters/setatoms.cpp +++ b/src/gromacs/coordinateio/outputadapters/setatoms.cpp @@ -53,19 +53,18 @@ namespace gmx { -void -SetAtoms::checkAbilityDependencies(unsigned long abilities) const +void SetAtoms::checkAbilityDependencies(unsigned long abilities) const { if ((abilities & convertFlag(moduleRequirements_)) == 0U) { - std::string errorMessage = "Output file type does not support writing atom information. " - "You need to use PDB, GRO or TNG as the file type for this."; + std::string errorMessage = + "Output file type does not support writing atom information. " + "You need to use PDB, GRO or TNG as the file type for this."; GMX_THROW(InconsistentInputError(errorMessage.c_str())); } } -void -SetAtoms::processFrame(const int /*framenumber*/, t_trxframe *input) +void SetAtoms::processFrame(const int /*framenumber*/, t_trxframe* input) { switch (atomFlag_) { @@ -76,8 +75,9 @@ SetAtoms::processFrame(const int /*framenumber*/, t_trxframe *input) case (ChangeAtomsType::Always): if (!haveAtoms(*input)) { - GMX_THROW(InconsistentInputError("Atoms needed by output but not " - "available in input frame or topology")); + GMX_THROW( + InconsistentInputError("Atoms needed by output but not " + "available in input frame or topology")); } input->bAtoms = true; if (haveStructureFileAtoms()) @@ -85,24 +85,22 @@ SetAtoms::processFrame(const int /*framenumber*/, t_trxframe *input) input->atoms = atoms(); } break; - case (ChangeAtomsType::PreservedIfPresent): - break; + case (ChangeAtomsType::PreservedIfPresent): break; case (ChangeAtomsType::AlwaysFromStructure): if (!haveStructureFileAtoms()) { - GMX_THROW(InconsistentInputError("Requested to add atoms information " - "to coordinate frame when it was not available")); + GMX_THROW( + InconsistentInputError("Requested to add atoms information " + "to coordinate frame when it was not available")); } input->bAtoms = true; input->atoms = atoms(); break; - default: - GMX_THROW(InconsistentInputError("Value for atom flag not understood")); + default: GMX_THROW(InconsistentInputError("Value for atom flag not understood")); } } -bool -SetAtoms::haveFrameAtoms(const t_trxframe &input) const +bool SetAtoms::haveFrameAtoms(const t_trxframe& input) const { return input.bAtoms; } diff --git a/src/gromacs/coordinateio/outputadapters/setatoms.h b/src/gromacs/coordinateio/outputadapters/setatoms.h index 0493ab175a..58e8a7870d 100644 --- a/src/gromacs/coordinateio/outputadapters/setatoms.h +++ b/src/gromacs/coordinateio/outputadapters/setatoms.h @@ -67,94 +67,89 @@ namespace gmx */ class SetAtoms : public IOutputAdapter { - public: - /*! \brief - * Construct SetAtoms object with choice for boolean value - * for availability of the t_atoms struct. - * - * Can be used to initialize SetAtoms from outside of trajectoryanalysis - * framework. - */ - explicit SetAtoms(ChangeAtomsType atomFlag, AtomsDataPtr inputAtoms) : - atomFlag_(atomFlag), - haveStructureFileAtoms_(false), - atoms_(std::move(inputAtoms)) +public: + /*! \brief + * Construct SetAtoms object with choice for boolean value + * for availability of the t_atoms struct. + * + * Can be used to initialize SetAtoms from outside of trajectoryanalysis + * framework. + */ + explicit SetAtoms(ChangeAtomsType atomFlag, AtomsDataPtr inputAtoms) : + atomFlag_(atomFlag), + haveStructureFileAtoms_(false), + atoms_(std::move(inputAtoms)) + { + if (atoms_ != nullptr) { - if (atoms_ != nullptr) - { - haveStructureFileAtoms_ = true; - } - if (atomFlag_ == ChangeAtomsType::Never) - { - moduleRequirements_ = CoordinateFileFlags::Base; - } - else - { - moduleRequirements_ = CoordinateFileFlags::RequireAtomInformation; - } + haveStructureFileAtoms_ = true; } - /*! \brief - * Move constructor for SetAtoms. - */ - SetAtoms(SetAtoms &&old) noexcept : - atomFlag_(old.atomFlag_), - haveStructureFileAtoms_(old.haveStructureFileAtoms_), - atoms_(std::move(old.atoms_)) + if (atomFlag_ == ChangeAtomsType::Never) { + moduleRequirements_ = CoordinateFileFlags::Base; } - - ~SetAtoms() override + else { + moduleRequirements_ = CoordinateFileFlags::RequireAtomInformation; } + } + /*! \brief + * Move constructor for SetAtoms. + */ + SetAtoms(SetAtoms&& old) noexcept : + atomFlag_(old.atomFlag_), + haveStructureFileAtoms_(old.haveStructureFileAtoms_), + atoms_(std::move(old.atoms_)) + { + } - /*! \brief - * Change coordinate frame information for output. - * - * Changes the frame t_atoms struct according to user choice and - * availability. - * - * \param[in] input Coordinate frame to be modified later. - */ - void processFrame(int /*framenumber*/, t_trxframe *input) override; + ~SetAtoms() override {} - void checkAbilityDependencies(unsigned long abilities) const override; + /*! \brief + * Change coordinate frame information for output. + * + * Changes the frame t_atoms struct according to user choice and + * availability. + * + * \param[in] input Coordinate frame to be modified later. + */ + void processFrame(int /*framenumber*/, t_trxframe* input) override; - private: - //! Local function to check that we have a proper t_atoms struct available. - bool haveStructureFileAtoms() const - { - return haveStructureFileAtoms_; - } - /*! \brief - * Checking if t_trxframe has the atom information saved within. - * - * \param[in] input t_trxframe before we start modifying it. - */ - bool haveFrameAtoms(const t_trxframe &input) const; - //! Test if the atoms data is available for writing. - bool haveAtoms(const t_trxframe &input) const - { - return haveStructureFileAtoms() || haveFrameAtoms(input); - } - //! Return pointer to t_atoms. - t_atoms *atoms() - { - GMX_RELEASE_ASSERT(haveStructureFileAtoms(), "No atoms information available"); - return atoms_.get(); - } - //! Flag provided for setting atoms in coordinate frame from user. - ChangeAtomsType atomFlag_; - //! Flag set if input atoms have been valid from the beginning. - bool haveStructureFileAtoms_; - /*! \brief - * Atoms information if available. - * - * Note, the module takes ownership of the information and - * will clean it up on exit. - */ - AtomsDataPtr atoms_; - //! Requirements obtained from user input. - CoordinateFileFlags moduleRequirements_; + void checkAbilityDependencies(unsigned long abilities) const override; + +private: + //! Local function to check that we have a proper t_atoms struct available. + bool haveStructureFileAtoms() const { return haveStructureFileAtoms_; } + /*! \brief + * Checking if t_trxframe has the atom information saved within. + * + * \param[in] input t_trxframe before we start modifying it. + */ + bool haveFrameAtoms(const t_trxframe& input) const; + //! Test if the atoms data is available for writing. + bool haveAtoms(const t_trxframe& input) const + { + return haveStructureFileAtoms() || haveFrameAtoms(input); + } + //! Return pointer to t_atoms. + t_atoms* atoms() + { + GMX_RELEASE_ASSERT(haveStructureFileAtoms(), "No atoms information available"); + return atoms_.get(); + } + //! Flag provided for setting atoms in coordinate frame from user. + ChangeAtomsType atomFlag_; + //! Flag set if input atoms have been valid from the beginning. + bool haveStructureFileAtoms_; + /*! \brief + * Atoms information if available. + * + * Note, the module takes ownership of the information and + * will clean it up on exit. + */ + AtomsDataPtr atoms_; + //! Requirements obtained from user input. + CoordinateFileFlags moduleRequirements_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/setbox.h b/src/gromacs/coordinateio/outputadapters/setbox.h index df8f927287..b54f332d31 100644 --- a/src/gromacs/coordinateio/outputadapters/setbox.h +++ b/src/gromacs/coordinateio/outputadapters/setbox.h @@ -60,45 +60,36 @@ namespace gmx */ class SetBox : public IOutputAdapter { - public: - /*! \brief - * Construct SetBox object with a new user defined box. - */ - explicit SetBox(const matrix box) - { - copy_mat(box, box_); - } - /*! \brief - * Move constructor for SetBox. - */ - SetBox(SetBox &&old) noexcept - { - copy_mat(old.box_, box_); - } +public: + /*! \brief + * Construct SetBox object with a new user defined box. + */ + explicit SetBox(const matrix box) { copy_mat(box, box_); } + /*! \brief + * Move constructor for SetBox. + */ + SetBox(SetBox&& old) noexcept { copy_mat(old.box_, box_); } - ~SetBox() override - { - clear_mat(box_); - } + ~SetBox() override { clear_mat(box_); } - /*! \brief - * Change coordinate frame information for output. - * - * In this case, box information is added to the \p t_trxframe object - * depending on the user input. - * - * \param[in] input Coordinate frame to be modified later. - */ - void processFrame(int /*framenumner*/, t_trxframe *input) override - { - copy_mat(box_, input->box); - } + /*! \brief + * Change coordinate frame information for output. + * + * In this case, box information is added to the \p t_trxframe object + * depending on the user input. + * + * \param[in] input Coordinate frame to be modified later. + */ + void processFrame(int /*framenumner*/, t_trxframe* input) override + { + copy_mat(box_, input->box); + } - void checkAbilityDependencies(unsigned long /* abilities */) const override {} + void checkAbilityDependencies(unsigned long /* abilities */) const override {} - private: - //! New box information from the user. - matrix box_; +private: + //! New box information from the user. + matrix box_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/setforces.cpp b/src/gromacs/coordinateio/outputadapters/setforces.cpp index 232dd26092..1d67b85abe 100644 --- a/src/gromacs/coordinateio/outputadapters/setforces.cpp +++ b/src/gromacs/coordinateio/outputadapters/setforces.cpp @@ -51,19 +51,18 @@ namespace gmx { -void -SetForces::checkAbilityDependencies(unsigned long abilities) const +void SetForces::checkAbilityDependencies(unsigned long abilities) const { if ((abilities & convertFlag(moduleRequirements_)) == 0U) { - std::string errorMessage = "Output file type does not support writing forces. " - "Only TNG and TRR support this output."; + std::string errorMessage = + "Output file type does not support writing forces. " + "Only TNG and TRR support this output."; GMX_THROW(InconsistentInputError(errorMessage.c_str())); } } -void -SetForces::processFrame(const int /*framenumber*/, t_trxframe *input) +void SetForces::processFrame(const int /*framenumber*/, t_trxframe* input) { switch (force_) { @@ -74,11 +73,11 @@ SetForces::processFrame(const int /*framenumber*/, t_trxframe *input) case (ChangeSettingType::Always): if (!input->bF) { - GMX_THROW(InconsistentInputError("Force output requested but current frame has no forces")); + GMX_THROW(InconsistentInputError( + "Force output requested but current frame has no forces")); } break; - default: - GMX_THROW(InconsistentInputError("Value for force flag is not supported")); + default: GMX_THROW(InconsistentInputError("Value for force flag is not supported")); } } diff --git a/src/gromacs/coordinateio/outputadapters/setforces.h b/src/gromacs/coordinateio/outputadapters/setforces.h index d4f7edffe4..2244511bed 100644 --- a/src/gromacs/coordinateio/outputadapters/setforces.h +++ b/src/gromacs/coordinateio/outputadapters/setforces.h @@ -63,53 +63,53 @@ namespace gmx */ class SetForces : public IOutputAdapter { - public: - /*! \brief - * Construct SetForces object with choice for boolean value. - * - * Can be used to initialize SetForces from outside of trajectoryanalysis - * with the user specified option to write coordinate forces or not. - */ - explicit SetForces(ChangeSettingType force) : force_(force) +public: + /*! \brief + * Construct SetForces object with choice for boolean value. + * + * Can be used to initialize SetForces from outside of trajectoryanalysis + * with the user specified option to write coordinate forces or not. + */ + explicit SetForces(ChangeSettingType force) : force_(force) + { + if (force == ChangeSettingType::Never) { - if (force == ChangeSettingType::Never) - { - moduleRequirements_ = CoordinateFileFlags::Base; - } - else - { - moduleRequirements_ = CoordinateFileFlags::RequireForceOutput; - } + moduleRequirements_ = CoordinateFileFlags::Base; } - /*! \brief - * Move constructor for SetForces. - */ - SetForces(SetForces &&old) noexcept = default; + else + { + moduleRequirements_ = CoordinateFileFlags::RequireForceOutput; + } + } + /*! \brief + * Move constructor for SetForces. + */ + SetForces(SetForces&& old) noexcept = default; - ~SetForces() override {} + ~SetForces() override {} - /*! \brief - * Change coordinate frame information for output. - * - * In this case, the correct flag for writing the forces is applied - * to the output frame, depending on user selection and availability - * in the input data. - * - * \param[in] input Coordinate frame to be modified later. - */ - void processFrame(int /*framenumner*/, t_trxframe *input) override; + /*! \brief + * Change coordinate frame information for output. + * + * In this case, the correct flag for writing the forces is applied + * to the output frame, depending on user selection and availability + * in the input data. + * + * \param[in] input Coordinate frame to be modified later. + */ + void processFrame(int /*framenumner*/, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long abilities) const override; + void checkAbilityDependencies(unsigned long abilities) const override; - private: - /*! \brief - * Flag to specify if forces should be written. - * - * Internal storage for the user choice for writing coordinate forces. - */ - ChangeSettingType force_; - //! Local requirements to be determined from user input. - CoordinateFileFlags moduleRequirements_; +private: + /*! \brief + * Flag to specify if forces should be written. + * + * Internal storage for the user choice for writing coordinate forces. + */ + ChangeSettingType force_; + //! Local requirements to be determined from user input. + CoordinateFileFlags moduleRequirements_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/setprecision.cpp b/src/gromacs/coordinateio/outputadapters/setprecision.cpp index 2697d08343..71b69f0164 100644 --- a/src/gromacs/coordinateio/outputadapters/setprecision.cpp +++ b/src/gromacs/coordinateio/outputadapters/setprecision.cpp @@ -53,19 +53,18 @@ namespace gmx { -void -SetPrecision::checkAbilityDependencies(unsigned long abilities) const +void SetPrecision::checkAbilityDependencies(unsigned long abilities) const { if ((abilities & convertFlag(moduleRequirements_)) == 0U) { - std::string errorMessage = "Output file type does not support writing variable precision. " - "Only XTC and TNG support variable precision."; + std::string errorMessage = + "Output file type does not support writing variable precision. " + "Only XTC and TNG support variable precision."; GMX_THROW(InconsistentInputError(errorMessage.c_str())); } } -void -SetPrecision::processFrame(const int /*framenumber*/, t_trxframe *input) +void SetPrecision::processFrame(const int /*framenumber*/, t_trxframe* input) { input->prec = std::pow(10, precision_); input->bPrec = true; diff --git a/src/gromacs/coordinateio/outputadapters/setprecision.h b/src/gromacs/coordinateio/outputadapters/setprecision.h index f7b03eeecb..31971fe18d 100644 --- a/src/gromacs/coordinateio/outputadapters/setprecision.h +++ b/src/gromacs/coordinateio/outputadapters/setprecision.h @@ -63,43 +63,43 @@ namespace gmx */ class SetPrecision : public IOutputAdapter { - public: - /*! \brief - * Construct SetPrecision object with user defined value. - * - * Can be used to initialize SetPrecision from outside of trajectoryanalysis - * with the user specified option to change precision or not. - * - * \param[in] precision User defined value for output precision in file types that support it. - */ - explicit SetPrecision(int precision) : precision_(precision) +public: + /*! \brief + * Construct SetPrecision object with user defined value. + * + * Can be used to initialize SetPrecision from outside of trajectoryanalysis + * with the user specified option to change precision or not. + * + * \param[in] precision User defined value for output precision in file types that support it. + */ + explicit SetPrecision(int precision) : precision_(precision) + { + // Only request special treatment if precision is not the default. + if (precision == 3) { - // Only request special treatment if precision is not the default. - if (precision == 3) - { - moduleRequirements_ = CoordinateFileFlags::Base; - } - else - { - moduleRequirements_ = CoordinateFileFlags::RequireChangedOutputPrecision; - } + moduleRequirements_ = CoordinateFileFlags::Base; } - /*! \brief - * Move constructor for SetPrecision. - */ - SetPrecision(SetPrecision &&old) noexcept = default; + else + { + moduleRequirements_ = CoordinateFileFlags::RequireChangedOutputPrecision; + } + } + /*! \brief + * Move constructor for SetPrecision. + */ + SetPrecision(SetPrecision&& old) noexcept = default; - ~SetPrecision() override {} + ~SetPrecision() override {} - void processFrame(int /*framenumber*/, t_trxframe *input) override; + void processFrame(int /*framenumber*/, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long abilities) const override; + void checkAbilityDependencies(unsigned long abilities) const override; - private: - //! User specified changes to default precision. - int precision_; - //! Module requirements dependent on user input. - CoordinateFileFlags moduleRequirements_; +private: + //! User specified changes to default precision. + int precision_; + //! Module requirements dependent on user input. + CoordinateFileFlags moduleRequirements_; }; //! Smart pointer to manage the outputselector object. diff --git a/src/gromacs/coordinateio/outputadapters/setstarttime.cpp b/src/gromacs/coordinateio/outputadapters/setstarttime.cpp index 3cd08dc2b2..cbba6ead05 100644 --- a/src/gromacs/coordinateio/outputadapters/setstarttime.cpp +++ b/src/gromacs/coordinateio/outputadapters/setstarttime.cpp @@ -53,20 +53,18 @@ namespace gmx { -void -SetStartTime::processFrame(const int /* framenumber */, t_trxframe *input) +void SetStartTime::processFrame(const int /* framenumber */, t_trxframe* input) { if (!haveProcessedFirstFrame_) { setInitialTime(input->time); } - input->time = input->time + differenceToInitialTime_; - input->bTime = true; + input->time = input->time + differenceToInitialTime_; + input->bTime = true; } -void -SetStartTime::setInitialTime(real initialTimeFromFrame) +void SetStartTime::setInitialTime(real initialTimeFromFrame) { differenceToInitialTime_ = startTime_ - initialTimeFromFrame; haveProcessedFirstFrame_ = true; diff --git a/src/gromacs/coordinateio/outputadapters/setstarttime.h b/src/gromacs/coordinateio/outputadapters/setstarttime.h index b32ce541da..247f337790 100644 --- a/src/gromacs/coordinateio/outputadapters/setstarttime.h +++ b/src/gromacs/coordinateio/outputadapters/setstarttime.h @@ -61,57 +61,57 @@ namespace gmx */ class SetStartTime : public IOutputAdapter { - public: - /*! \brief - * Construct object with choice for how to change initial time. - * - * \param[in] startTime User defined value for the initial time. - */ - explicit SetStartTime(real startTime) : - startTime_(startTime), - haveProcessedFirstFrame_(false), - differenceToInitialTime_(0) - { - } - /*! \brief - * Move constructor for SetStartTime. - */ - SetStartTime(SetStartTime &&old) noexcept = default; +public: + /*! \brief + * Construct object with choice for how to change initial time. + * + * \param[in] startTime User defined value for the initial time. + */ + explicit SetStartTime(real startTime) : + startTime_(startTime), + haveProcessedFirstFrame_(false), + differenceToInitialTime_(0) + { + } + /*! \brief + * Move constructor for SetStartTime. + */ + SetStartTime(SetStartTime&& old) noexcept = default; - ~SetStartTime() override {} + ~SetStartTime() override {} - void processFrame(int /* framenumber */, t_trxframe *input) override; + void processFrame(int /* framenumber */, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long /* abilities */) const override {} + void checkAbilityDependencies(unsigned long /* abilities */) const override {} - private: - /*! \brief - * Set initial time from first processed frame. - * - * Calculates the time shift between the user set time and the time - * in the coordinate frame being processed from the first processed coordinate - * frame. This time shift is then used to calculate new frame times for each processed - * coordinate frame. - * - * \param[in] initialTime Time value obtained from first frame. - */ - void setInitialTime(real initialTime); +private: + /*! \brief + * Set initial time from first processed frame. + * + * Calculates the time shift between the user set time and the time + * in the coordinate frame being processed from the first processed coordinate + * frame. This time shift is then used to calculate new frame times for each processed + * coordinate frame. + * + * \param[in] initialTime Time value obtained from first frame. + */ + void setInitialTime(real initialTime); - /*! \brief - * Stores the value of the initial time. - * - * In case users supply a new time step, the initial time of the - * processed coordinate frame is stored here. In case the user also supplies - * a new initial time, this variable is set to the user input instead. - */ - real startTime_; - //! Has the first frame been processed? - bool haveProcessedFirstFrame_; - /*! \brief - * If the initial time is changed, we need to keep track of the initial - * time difference to adjust the time of all following frames. - */ - real differenceToInitialTime_; + /*! \brief + * Stores the value of the initial time. + * + * In case users supply a new time step, the initial time of the + * processed coordinate frame is stored here. In case the user also supplies + * a new initial time, this variable is set to the user input instead. + */ + real startTime_; + //! Has the first frame been processed? + bool haveProcessedFirstFrame_; + /*! \brief + * If the initial time is changed, we need to keep track of the initial + * time difference to adjust the time of all following frames. + */ + real differenceToInitialTime_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/settimestep.cpp b/src/gromacs/coordinateio/outputadapters/settimestep.cpp index 58c494b2c5..04d7e8e209 100644 --- a/src/gromacs/coordinateio/outputadapters/settimestep.cpp +++ b/src/gromacs/coordinateio/outputadapters/settimestep.cpp @@ -51,8 +51,7 @@ namespace gmx { -real -SetTimeStep::calculateNewFrameTime(real currentInputFrameTime) +real SetTimeStep::calculateNewFrameTime(real currentInputFrameTime) { real currentTime = 0.0; if (!haveProcessedFirstFrame_) @@ -69,8 +68,7 @@ SetTimeStep::calculateNewFrameTime(real currentInputFrameTime) return currentTime; } -void -SetTimeStep::processFrame(const int /* framenumber */, t_trxframe *input) +void SetTimeStep::processFrame(const int /* framenumber */, t_trxframe* input) { input->time = calculateNewFrameTime(input->time); input->bTime = true; diff --git a/src/gromacs/coordinateio/outputadapters/settimestep.h b/src/gromacs/coordinateio/outputadapters/settimestep.h index 4fc72546a3..6368a88583 100644 --- a/src/gromacs/coordinateio/outputadapters/settimestep.h +++ b/src/gromacs/coordinateio/outputadapters/settimestep.h @@ -61,51 +61,50 @@ namespace gmx */ class SetTimeStep : public IOutputAdapter { - public: - /*! \brief - * Construct SetTime object with choice for how to change time. - * - * Can be used to initialize SetTime from outside of trajectoryanalysis - * with the user specified option to change frame time information or not. - * - * \param[in] timeStep User defined value for the time step. - */ - explicit SetTimeStep(real timeStep) : - timeStep_(timeStep), - previousFrameTime_(0.0), - haveProcessedFirstFrame_(false) - { - } - /*! \brief - * Move constructor for SetTimeStep. - */ - SetTimeStep(SetTimeStep &&old) noexcept = default; +public: + /*! \brief + * Construct SetTime object with choice for how to change time. + * + * Can be used to initialize SetTime from outside of trajectoryanalysis + * with the user specified option to change frame time information or not. + * + * \param[in] timeStep User defined value for the time step. + */ + explicit SetTimeStep(real timeStep) : + timeStep_(timeStep), + previousFrameTime_(0.0), + haveProcessedFirstFrame_(false) + { + } + /*! \brief + * Move constructor for SetTimeStep. + */ + SetTimeStep(SetTimeStep&& old) noexcept = default; - ~SetTimeStep() override {} + ~SetTimeStep() override {} - void processFrame(int framenumber, t_trxframe *input) override; + void processFrame(int framenumber, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long /* abilities */) const override {} + void checkAbilityDependencies(unsigned long /* abilities */) const override {} - private: +private: + /*! \brief + * Calculates the time of the current coordinate frame based on user input. + * + * If the current frame is the first one, no changes to the time are made. + * For subsequent frames, the new frame time is based on the user input + * and the time of the previous frame. + * + * \param[in] currentInputFrameTime Input from processed coordinate frame. + */ + real calculateNewFrameTime(real currentInputFrameTime); - /*! \brief - * Calculates the time of the current coordinate frame based on user input. - * - * If the current frame is the first one, no changes to the time are made. - * For subsequent frames, the new frame time is based on the user input - * and the time of the previous frame. - * - * \param[in] currentInputFrameTime Input from processed coordinate frame. - */ - real calculateNewFrameTime(real currentInputFrameTime); - - //! Time difference between frames. - real timeStep_; - //! Time of the previous frame. - real previousFrameTime_; - //! Has the first frame been processed? - bool haveProcessedFirstFrame_; + //! Time difference between frames. + real timeStep_; + //! Time of the previous frame. + real previousFrameTime_; + //! Has the first frame been processed? + bool haveProcessedFirstFrame_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/outputadapters/setvelocities.cpp b/src/gromacs/coordinateio/outputadapters/setvelocities.cpp index 1742f32fdd..df411a71d9 100644 --- a/src/gromacs/coordinateio/outputadapters/setvelocities.cpp +++ b/src/gromacs/coordinateio/outputadapters/setvelocities.cpp @@ -51,19 +51,18 @@ namespace gmx { -void -SetVelocities::checkAbilityDependencies(unsigned long abilities) const +void SetVelocities::checkAbilityDependencies(unsigned long abilities) const { if ((abilities & convertFlag(moduleRequirements_)) == 0U) { - std::string errorMessage = "Output file type does not support writing velocities. " - "Only GRO, TRR and TNG support this output."; + std::string errorMessage = + "Output file type does not support writing velocities. " + "Only GRO, TRR and TNG support this output."; GMX_THROW(InconsistentInputError(errorMessage.c_str())); } } -void -SetVelocities::processFrame(const int /*framenumber*/, t_trxframe *input) +void SetVelocities::processFrame(const int /*framenumber*/, t_trxframe* input) { switch (velocity_) { @@ -74,11 +73,11 @@ SetVelocities::processFrame(const int /*framenumber*/, t_trxframe *input) case (ChangeSettingType::Always): if (!input->bV) { - GMX_THROW(InconsistentInputError("Velocity output requested but current frame has no velocities")); + GMX_THROW(InconsistentInputError( + "Velocity output requested but current frame has no velocities")); } break; - default: - GMX_THROW(InconsistentInputError("Value for velocity flag is not supported")); + default: GMX_THROW(InconsistentInputError("Value for velocity flag is not supported")); } } diff --git a/src/gromacs/coordinateio/outputadapters/setvelocities.h b/src/gromacs/coordinateio/outputadapters/setvelocities.h index 1f14f74915..5eca665c10 100644 --- a/src/gromacs/coordinateio/outputadapters/setvelocities.h +++ b/src/gromacs/coordinateio/outputadapters/setvelocities.h @@ -63,49 +63,49 @@ namespace gmx */ class SetVelocities : public IOutputAdapter { - public: - /*! \brief - * Construct SetVelocities object with choice for boolean value. - * - * Can be used to initialize SetVelocities from outside of trajectoryanalysis - * with the user specified option to write coordinate velocities or not. - */ - explicit SetVelocities(ChangeSettingType velocity) : velocity_(velocity) +public: + /*! \brief + * Construct SetVelocities object with choice for boolean value. + * + * Can be used to initialize SetVelocities from outside of trajectoryanalysis + * with the user specified option to write coordinate velocities or not. + */ + explicit SetVelocities(ChangeSettingType velocity) : velocity_(velocity) + { + if (velocity_ == ChangeSettingType::Never) { - if (velocity_ == ChangeSettingType::Never) - { - moduleRequirements_ = CoordinateFileFlags::Base; - } - else - { - moduleRequirements_ = CoordinateFileFlags::RequireVelocityOutput; - } + moduleRequirements_ = CoordinateFileFlags::Base; } - /*! \brief - * Move constructor for SetVelocities. - */ - SetVelocities(SetVelocities &&old) noexcept = default; + else + { + moduleRequirements_ = CoordinateFileFlags::RequireVelocityOutput; + } + } + /*! \brief + * Move constructor for SetVelocities. + */ + SetVelocities(SetVelocities&& old) noexcept = default; - ~SetVelocities() override {} + ~SetVelocities() override {} - /*! \brief - * Change coordinate frame information for output. - * - * In this case, the correct flag for writing the velocities is applied - * to the output frame, depending on user selection and availability - * in the input data. - * - * \param[in] input Coordinate frame to be modified later. - */ - void processFrame(int /*framenumber*/, t_trxframe *input) override; + /*! \brief + * Change coordinate frame information for output. + * + * In this case, the correct flag for writing the velocities is applied + * to the output frame, depending on user selection and availability + * in the input data. + * + * \param[in] input Coordinate frame to be modified later. + */ + void processFrame(int /*framenumber*/, t_trxframe* input) override; - void checkAbilityDependencies(unsigned long abilities) const override; + void checkAbilityDependencies(unsigned long abilities) const override; - private: - //! Flag to specify if velocities should be written. - ChangeSettingType velocity_; - //! Local requirements determined from user input. - CoordinateFileFlags moduleRequirements_; +private: + //! Flag to specify if velocities should be written. + ChangeSettingType velocity_; + //! Local requirements determined from user input. + CoordinateFileFlags moduleRequirements_; }; //! Smart pointer to manage the object. diff --git a/src/gromacs/coordinateio/requirements.cpp b/src/gromacs/coordinateio/requirements.cpp index 6bf2a4303e..71757b51d1 100644 --- a/src/gromacs/coordinateio/requirements.cpp +++ b/src/gromacs/coordinateio/requirements.cpp @@ -55,48 +55,44 @@ namespace gmx { -void -OutputRequirementOptionDirector::initOptions(IOptionsContainer *options) +void OutputRequirementOptionDirector::initOptions(IOptionsContainer* options) { options->addOption(EnumOption("vel") - .enumValue(cChangeSettingTypeEnum) - .store(&velocity_) - .description("Save velocities from frame if possible")); + .enumValue(cChangeSettingTypeEnum) + .store(&velocity_) + .description("Save velocities from frame if possible")); options->addOption(EnumOption("force") - .enumValue(cChangeSettingTypeEnum) - .store(&force_) - .description("Save forces from frame if possible")); - options->addOption(EnumOption("atoms") - .enumValue(cChangeAtomsTypeEnum) - .store(&atoms_) - .description("Decide on providing new atom information from topology or using current frame atom information")); + .enumValue(cChangeSettingTypeEnum) + .store(&force_) + .description("Save forces from frame if possible")); + options->addOption( + EnumOption("atoms").enumValue(cChangeAtomsTypeEnum).store(&atoms_).description("Decide on providing new atom information from topology or using current frame atom information")); options->addOption(IntegerOption("precision") - .store(&prec_) - .defaultValue(prec_) - .storeIsSet(&setNewPrecision_) - .description("Set output precision to custom value")); + .store(&prec_) + .defaultValue(prec_) + .storeIsSet(&setNewPrecision_) + .description("Set output precision to custom value")); options->addOption(RealOption("starttime") - .store(&startTimeValue_) - .defaultValue(startTimeValue_) - .timeValue() - .storeIsSet(&setNewStartTime_) - .description("Change start time for first frame")); + .store(&startTimeValue_) + .defaultValue(startTimeValue_) + .timeValue() + .storeIsSet(&setNewStartTime_) + .description("Change start time for first frame")); options->addOption(RealOption("timestep") - .store(&timeStepValue_) - .defaultValue(timeStepValue_) - .timeValue() - .storeIsSet(&setNewTimeStep_) - .description("Change time between different frames")); + .store(&timeStepValue_) + .defaultValue(timeStepValue_) + .timeValue() + .storeIsSet(&setNewTimeStep_) + .description("Change time between different frames")); options->addOption(RealOption("box") - .vector() - .storeVector(&newBoxVector_) - .valueCount(3) - .storeIsSet(&setNewBox_) - .description("New diagonal box vector for output frame")); + .vector() + .storeVector(&newBoxVector_) + .valueCount(3) + .storeIsSet(&setNewBox_) + .description("New diagonal box vector for output frame")); } -OutputRequirements -OutputRequirementOptionDirector::process() const +OutputRequirements OutputRequirementOptionDirector::process() const { OutputRequirements requirements; /* If the user has just set the values directly without setting the flags, diff --git a/src/gromacs/coordinateio/requirements.h b/src/gromacs/coordinateio/requirements.h index 842cd7bd5c..b49f2cd4f3 100644 --- a/src/gromacs/coordinateio/requirements.h +++ b/src/gromacs/coordinateio/requirements.h @@ -60,71 +60,69 @@ namespace gmx */ class OutputRequirementOptionDirector { - public: - /*! \brief - * Populate requirements from option interface. - * - * \param[in] options Pointer to global options framework. - */ - void initOptions(IOptionsContainer *options); +public: + /*! \brief + * Populate requirements from option interface. + * + * \param[in] options Pointer to global options framework. + */ + void initOptions(IOptionsContainer* options); - /*! \brief - * Provide processed requirements to create on coordinate file writing method. - */ - struct OutputRequirements process() const; + /*! \brief + * Provide processed requirements to create on coordinate file writing method. + */ + struct OutputRequirements process() const; - private: - - - - //! Should velocities be written. - ChangeSettingType velocity_ = ChangeSettingType::PreservedIfPresent; - //! Should forces be written. - ChangeSettingType force_ = ChangeSettingType::PreservedIfPresent; - //! Precision used in output file. - int prec_ = 3; - //! If a new precision value has been set. - bool setNewPrecision_ = false; - //! Time for first frame to start. - real startTimeValue_ = 0; - //! Time step to use between frames. - real timeStepValue_ = 0; - //! If start time value has been assigned. - bool setNewStartTime_ = false; - //! If a new time step value has been assigned. - bool setNewTimeStep_ = false; - //! User supplied diagonal box vector. - std::vector newBoxVector_; - //! If a new box vector has been set. - bool setNewBox_ = false; - //! Should frame atom setting be changed. - ChangeAtomsType atoms_ = ChangeAtomsType::PreservedIfPresent; +private: + //! Should velocities be written. + ChangeSettingType velocity_ = ChangeSettingType::PreservedIfPresent; + //! Should forces be written. + ChangeSettingType force_ = ChangeSettingType::PreservedIfPresent; + //! Precision used in output file. + int prec_ = 3; + //! If a new precision value has been set. + bool setNewPrecision_ = false; + //! Time for first frame to start. + real startTimeValue_ = 0; + //! Time step to use between frames. + real timeStepValue_ = 0; + //! If start time value has been assigned. + bool setNewStartTime_ = false; + //! If a new time step value has been assigned. + bool setNewTimeStep_ = false; + //! User supplied diagonal box vector. + std::vector newBoxVector_; + //! If a new box vector has been set. + bool setNewBox_ = false; + //! Should frame atom setting be changed. + ChangeAtomsType atoms_ = ChangeAtomsType::PreservedIfPresent; }; /*! \brief * Finalized version of requirements after processing. */ -struct OutputRequirements { +struct OutputRequirements +{ //! Should velocities be written. - ChangeSettingType velocity = ChangeSettingType::PreservedIfPresent; + ChangeSettingType velocity = ChangeSettingType::PreservedIfPresent; //! Should forces be written. - ChangeSettingType force = ChangeSettingType::PreservedIfPresent; + ChangeSettingType force = ChangeSettingType::PreservedIfPresent; //! Should precision be changed. - ChangeFrameInfoType precision = ChangeFrameInfoType::PreservedIfPresent; + ChangeFrameInfoType precision = ChangeFrameInfoType::PreservedIfPresent; //! Precision used in output file. - int prec = 3; + int prec = 3; //! Should frame start time be changed. - ChangeFrameTimeType frameTime = ChangeFrameTimeType::PreservedIfPresent; + ChangeFrameTimeType frameTime = ChangeFrameTimeType::PreservedIfPresent; //! Time for first frame to start. - real startTimeValue = 0; + real startTimeValue = 0; //! Time step to use between frames. - real timeStepValue = 0; + real timeStepValue = 0; //! Box vector converted to matrix format. - matrix newBox = {{0}}; + matrix newBox = { { 0 } }; //! Should frame box be changed. - ChangeFrameInfoType box = ChangeFrameInfoType::PreservedIfPresent; + ChangeFrameInfoType box = ChangeFrameInfoType::PreservedIfPresent; //! Should frame atom setting be changed. - ChangeAtomsType atoms = ChangeAtomsType::PreservedIfPresent; + ChangeAtomsType atoms = ChangeAtomsType::PreservedIfPresent; }; } // namespace gmx diff --git a/src/gromacs/coordinateio/tests/builder.cpp b/src/gromacs/coordinateio/tests/builder.cpp index d77f7482ca..09358de95e 100644 --- a/src/gromacs/coordinateio/tests/builder.cpp +++ b/src/gromacs/coordinateio/tests/builder.cpp @@ -63,33 +63,31 @@ namespace test */ class TrajectoryFrameWriterTest : public ModuleTest { - public: - /*! \brief - * Test basic behaviour without special requirements. - * - * \param[in] filename Name for output file. - */ - void basicTest(const char *filename) - { - addTopology(); - - OutputRequirements requirements; - - runTest(filename, requirements); - } - /*! \brief - * Test with extra requirements. - * - * \param[in] filename Name for output file. - * \param[in] requirements Specify extra reqs for output. - */ - void testWithRequirements(const char *filename, - const OutputRequirements &requirements) - { - addTopology(); - runTest(filename, requirements); - } +public: + /*! \brief + * Test basic behaviour without special requirements. + * + * \param[in] filename Name for output file. + */ + void basicTest(const char* filename) + { + addTopology(); + + OutputRequirements requirements; + runTest(filename, requirements); + } + /*! \brief + * Test with extra requirements. + * + * \param[in] filename Name for output file. + * \param[in] requirements Specify extra reqs for output. + */ + void testWithRequirements(const char* filename, const OutputRequirements& requirements) + { + addTopology(); + runTest(filename, requirements); + } }; TEST_P(TrajectoryFrameWriterTest, WorksWithFormats) @@ -104,33 +102,27 @@ TEST_F(TrajectoryFrameWriterTest, RejectsWrongFiletype) TEST_F(TrajectoryFrameWriterTest, BuilderFailsWithPdbAndNoAtoms) { - OutputRequirements requirements; + OutputRequirements requirements; requirements.atoms = ChangeAtomsType::Never; - EXPECT_THROW(testWithRequirements("test.pdb", - requirements), - InconsistentInputError); + EXPECT_THROW(testWithRequirements("test.pdb", requirements), InconsistentInputError); } TEST_F(TrajectoryFrameWriterTest, BuilderFailsWithGroAndNoAtoms) { - OutputRequirements requirements; + OutputRequirements requirements; requirements.atoms = ChangeAtomsType::Never; - EXPECT_THROW(testWithRequirements("test.gro", - requirements), - InconsistentInputError); + EXPECT_THROW(testWithRequirements("test.gro", requirements), InconsistentInputError); } TEST_F(TrajectoryFrameWriterTest, BuilderImplictlyAddsAtoms) { - OutputRequirements requirements; + OutputRequirements requirements; requirements.atoms = ChangeAtomsType::PreservedIfPresent; { - EXPECT_NO_THROW(testWithRequirements("test.pdb", - requirements)); + EXPECT_NO_THROW(testWithRequirements("test.pdb", requirements)); } { - EXPECT_NO_THROW(testWithRequirements("test.gro", - requirements)); + EXPECT_NO_THROW(testWithRequirements("test.gro", requirements)); } } @@ -145,19 +137,16 @@ TEST_F(TrajectoryFrameWriterTest, TNGOutputWorks) /*!\brief * Character array of different file names to test. */ -const char *const trajectoryFileNames[] = { - "spc2-traj.trr", +const char* const trajectoryFileNames[] = { "spc2-traj.trr", #if GMX_USE_TNG - "spc2-traj.tng", + "spc2-traj.tng", #endif - "spc2-traj.xtc", - "spc2-traj.pdb", - "spc2-traj.gro", - "spc2-traj.g96" -}; + "spc2-traj.xtc", "spc2-traj.pdb", + "spc2-traj.gro", "spc2-traj.g96" }; INSTANTIATE_TEST_CASE_P(CoordinateFileFileFormats, - TrajectoryFrameWriterTest, ::testing::ValuesIn(trajectoryFileNames)); + TrajectoryFrameWriterTest, + ::testing::ValuesIn(trajectoryFileNames)); } // namespace test diff --git a/src/gromacs/coordinateio/tests/coordinate_test.h b/src/gromacs/coordinateio/tests/coordinate_test.h index 7fbaca8891..98f278c38f 100644 --- a/src/gromacs/coordinateio/tests/coordinate_test.h +++ b/src/gromacs/coordinateio/tests/coordinate_test.h @@ -81,15 +81,12 @@ namespace test * \throws InconsistentInputError When builder can not create the CoordinateFile. * \returns unique_ptr to new CoordinateFile object. */ -inline TrajectoryFrameWriterPointer -createMinimalTrajectoryFrameWriter(const std::string &filename, - const TopologyInformation &topology, - const Selection &selection, - OutputRequirements requirements) +inline TrajectoryFrameWriterPointer createMinimalTrajectoryFrameWriter(const std::string& filename, + const TopologyInformation& topology, + const Selection& selection, + OutputRequirements requirements) { - return createTrajectoryFrameWriter(topology.mtop(), - selection, - filename, + return createTrajectoryFrameWriter(topology.mtop(), selection, filename, topology.hasTopology() ? topology.copyAtoms() : nullptr, requirements); } @@ -98,55 +95,53 @@ createMinimalTrajectoryFrameWriter(const std::string &filename, */ class ModuleSelection { - public: - ModuleSelection() : manager_(&sc_) - { - options_.addManager(&manager_); - sc_.setReferencePosType("atom"); - sc_.setOutputPosType("atom"); - top_.fillFromInputFile(TestFileManager::getInputFilePath("lysozyme.pdb")); - sc_.setTopology(top_.mtop(), 0); - } - - /*! \brief - * Method to add a valid selection option to the Module, or an invalid - * one for testing. - * - * \param[in] sel Selection to add option to. - * \param[in] useValid Set if the added selection should be valid for the module. - */ - void addOptionForSelection(Selection *sel, bool useValid); - - /*! \brief - * Set the actual values for the selection. - * - * \param[in] options Option to set values for. - * \param[in] sel Selection to use. - * \param[in] useValid Set if the added selection should be valid for the module. - */ - void setSelectionOptionValues(Options *options, Selection *sel, bool useValid); - - /*! \brief - * Get pointer to options to set values. - * - * \returns Pointer to options. - */ - Options *getOption() { return &options_; } - - private: - //! Selection collection used for handling test selection. - SelectionCollection sc_; - //! Selection manager for test selection. - SelectionOptionManager manager_; - //! Options manager for test selection input. - Options options_; - //! Topology information needed for test selection atoms. - TopologyInformation top_; +public: + ModuleSelection() : manager_(&sc_) + { + options_.addManager(&manager_); + sc_.setReferencePosType("atom"); + sc_.setOutputPosType("atom"); + top_.fillFromInputFile(TestFileManager::getInputFilePath("lysozyme.pdb")); + sc_.setTopology(top_.mtop(), 0); + } + /*! \brief + * Method to add a valid selection option to the Module, or an invalid + * one for testing. + * + * \param[in] sel Selection to add option to. + * \param[in] useValid Set if the added selection should be valid for the module. + */ + void addOptionForSelection(Selection* sel, bool useValid); + + /*! \brief + * Set the actual values for the selection. + * + * \param[in] options Option to set values for. + * \param[in] sel Selection to use. + * \param[in] useValid Set if the added selection should be valid for the module. + */ + void setSelectionOptionValues(Options* options, Selection* sel, bool useValid); + + /*! \brief + * Get pointer to options to set values. + * + * \returns Pointer to options. + */ + Options* getOption() { return &options_; } + +private: + //! Selection collection used for handling test selection. + SelectionCollection sc_; + //! Selection manager for test selection. + SelectionOptionManager manager_; + //! Options manager for test selection input. + Options options_; + //! Topology information needed for test selection atoms. + TopologyInformation top_; }; -inline void -ModuleSelection::addOptionForSelection(Selection *sel, bool useValid) +inline void ModuleSelection::addOptionForSelection(Selection* sel, bool useValid) { if (useValid) { @@ -158,8 +153,7 @@ ModuleSelection::addOptionForSelection(Selection *sel, bool useValid) } } -inline void -ModuleSelection::setSelectionOptionValues(Options *options, Selection *sel, bool useValid) +inline void ModuleSelection::setSelectionOptionValues(Options* options, Selection* sel, bool useValid) { OptionsAssigner assigner(options); assigner.start(); @@ -182,35 +176,29 @@ ModuleSelection::setSelectionOptionValues(Options *options, Selection *sel, bool /*! \libinternal \brief * Test fixture to test matching file types for modules. */ -class ModuleTest : public gmx::test::CommandLineTestBase, - public ::testing::WithParamInterface +class ModuleTest : public gmx::test::CommandLineTestBase, public ::testing::WithParamInterface { - public: - /*! \brief - * Run the builder to create an TrajectoryFrameWriter during tests. - * - * \param[in] filename Name for output file, to determine filetype during construction. - * \param[in] requirements Requirements for adding to the object. - * \returns The newly created object. - */ - TrajectoryFrameWriterPointer - runTest(const char *filename, const OutputRequirements &requirements) - { - return createMinimalTrajectoryFrameWriter(filename, - dummyTopology_, - dummySelection_, - requirements); - } - //! Add topology information to test if needed. - void addTopology() - { - dummyTopology_.fillFromInputFile( - TestFileManager::getInputFilePath("lysozyme.pdb")); - } - //! Dummy topology to use to create CoordinateFile. - TopologyInformation dummyTopology_; - //! Dummy selection. - Selection dummySelection_; +public: + /*! \brief + * Run the builder to create an TrajectoryFrameWriter during tests. + * + * \param[in] filename Name for output file, to determine filetype during construction. + * \param[in] requirements Requirements for adding to the object. + * \returns The newly created object. + */ + TrajectoryFrameWriterPointer runTest(const char* filename, const OutputRequirements& requirements) + { + return createMinimalTrajectoryFrameWriter(filename, dummyTopology_, dummySelection_, requirements); + } + //! Add topology information to test if needed. + void addTopology() + { + dummyTopology_.fillFromInputFile(TestFileManager::getInputFilePath("lysozyme.pdb")); + } + //! Dummy topology to use to create CoordinateFile. + TopologyInformation dummyTopology_; + //! Dummy selection. + Selection dummySelection_; }; } // namespace test diff --git a/src/gromacs/coordinateio/tests/outputadaptercontainer.cpp b/src/gromacs/coordinateio/tests/outputadaptercontainer.cpp index ded69bdf41..4538b6601f 100644 --- a/src/gromacs/coordinateio/tests/outputadaptercontainer.cpp +++ b/src/gromacs/coordinateio/tests/outputadaptercontainer.cpp @@ -70,9 +70,8 @@ TEST(OutputAdapterContainer, MakeEmpty) TEST(OutputAdapterContainer, AddAdapter) { OutputAdapterContainer container(CoordinateFileFlags::Base); - container.addAdapter( - std::make_unique(CoordinateFileFlags::Base), - CoordinateFileFlags::RequireNewFrameStartTime); + container.addAdapter(std::make_unique(CoordinateFileFlags::Base), + CoordinateFileFlags::RequireNewFrameStartTime); EXPECT_FALSE(container.isEmpty()); } @@ -89,26 +88,22 @@ TEST(OutputAdapterContainer, RejectBadAdapter) TEST(OutputAdapterContainer, RejectDuplicateAdapter) { OutputAdapterContainer container(CoordinateFileFlags::Base); - EXPECT_NO_THROW(container.addAdapter( - std::make_unique(CoordinateFileFlags::Base), - CoordinateFileFlags::RequireNewFrameStartTime)); + EXPECT_NO_THROW(container.addAdapter(std::make_unique(CoordinateFileFlags::Base), + CoordinateFileFlags::RequireNewFrameStartTime)); EXPECT_FALSE(container.isEmpty()); - EXPECT_THROW(container.addAdapter( - std::make_unique(CoordinateFileFlags::Base), - CoordinateFileFlags::RequireNewFrameStartTime), + EXPECT_THROW(container.addAdapter(std::make_unique(CoordinateFileFlags::Base), + CoordinateFileFlags::RequireNewFrameStartTime), InternalError); } TEST(OutputAdapterContainer, AcceptMultipleAdapters) { OutputAdapterContainer container(CoordinateFileFlags::Base); - EXPECT_NO_THROW(container.addAdapter( - std::make_unique(CoordinateFileFlags::Base), - CoordinateFileFlags::RequireForceOutput)); + EXPECT_NO_THROW(container.addAdapter(std::make_unique(CoordinateFileFlags::Base), + CoordinateFileFlags::RequireForceOutput)); EXPECT_FALSE(container.isEmpty()); - EXPECT_NO_THROW(container.addAdapter( - std::make_unique(CoordinateFileFlags::Base), - CoordinateFileFlags::RequireVelocityOutput)); + EXPECT_NO_THROW(container.addAdapter(std::make_unique(CoordinateFileFlags::Base), + CoordinateFileFlags::RequireVelocityOutput)); EXPECT_FALSE(container.isEmpty()); } diff --git a/src/gromacs/coordinateio/tests/outputadapters.cpp b/src/gromacs/coordinateio/tests/outputadapters.cpp index ecf2bc3c7c..ec4023bd95 100644 --- a/src/gromacs/coordinateio/tests/outputadapters.cpp +++ b/src/gromacs/coordinateio/tests/outputadapters.cpp @@ -106,35 +106,29 @@ TEST_P(NoOptionalOutput, Works) prepareTest(GetParam()); } -INSTANTIATE_TEST_CASE_P(ModuleSupported, - SetAtomsSupportedFiles, ::testing::ValuesIn(setAtomsSupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, SetAtomsSupportedFiles, ::testing::ValuesIn(setAtomsSupported)); -INSTANTIATE_TEST_CASE_P(ModuleUnSupported, - SetAtomsUnSupportedFiles, ::testing::ValuesIn(setAtomsUnSupported)); +INSTANTIATE_TEST_CASE_P(ModuleUnSupported, SetAtomsUnSupportedFiles, ::testing::ValuesIn(setAtomsUnSupported)); -INSTANTIATE_TEST_CASE_P(ModuleSupported, - AnyOutputSupportedFiles, ::testing::ValuesIn(anySupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, AnyOutputSupportedFiles, ::testing::ValuesIn(anySupported)); -INSTANTIATE_TEST_CASE_P(ModuleSupported, - SetVelocitySupportedFiles, ::testing::ValuesIn(setVelocitySupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, SetVelocitySupportedFiles, ::testing::ValuesIn(setVelocitySupported)); INSTANTIATE_TEST_CASE_P(ModuleUnSupported, - SetVelocityUnSupportedFiles, ::testing::ValuesIn(setVelocityUnSupported)); + SetVelocityUnSupportedFiles, + ::testing::ValuesIn(setVelocityUnSupported)); -INSTANTIATE_TEST_CASE_P(ModuleSupported, - SetForceSupportedFiles, ::testing::ValuesIn(setForceSupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, SetForceSupportedFiles, ::testing::ValuesIn(setForceSupported)); -INSTANTIATE_TEST_CASE_P(ModuleUnSupported, - SetForceUnSupportedFiles, ::testing::ValuesIn(setForceUnSupported)); +INSTANTIATE_TEST_CASE_P(ModuleUnSupported, SetForceUnSupportedFiles, ::testing::ValuesIn(setForceUnSupported)); -INSTANTIATE_TEST_CASE_P(ModuleSupported, - SetPrecisionSupportedFiles, ::testing::ValuesIn(setPrecisionSupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, SetPrecisionSupportedFiles, ::testing::ValuesIn(setPrecisionSupported)); INSTANTIATE_TEST_CASE_P(ModuleUnSupported, - SetPrecisionUnSupportedFiles, ::testing::ValuesIn(setPrecisionUnSupported)); + SetPrecisionUnSupportedFiles, + ::testing::ValuesIn(setPrecisionUnSupported)); -INSTANTIATE_TEST_CASE_P(ModuleSupported, - NoOptionalOutput, ::testing::ValuesIn(anySupported)); +INSTANTIATE_TEST_CASE_P(ModuleSupported, NoOptionalOutput, ::testing::ValuesIn(anySupported)); } // namespace test } // namespace gmx diff --git a/src/gromacs/coordinateio/tests/outputadapters.h b/src/gromacs/coordinateio/tests/outputadapters.h index 5a64fa98b5..5e0437da9e 100644 --- a/src/gromacs/coordinateio/tests/outputadapters.h +++ b/src/gromacs/coordinateio/tests/outputadapters.h @@ -71,210 +71,204 @@ namespace test /*!\libinternal \brief Helper to test supported file names. */ class SetAtomsSupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - addTopology(); - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + addTopology(); + //! Storage for requirements. + OutputRequirements requirements; - requirements.atoms = ChangeAtomsType::AlwaysFromStructure; + requirements.atoms = ChangeAtomsType::AlwaysFromStructure; - EXPECT_NO_THROW(runTest(filename, requirements)); - } + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetAtomsUnSupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + //! Storage for requirements. + OutputRequirements requirements; - requirements.atoms = ChangeAtomsType::AlwaysFromStructure; + requirements.atoms = ChangeAtomsType::AlwaysFromStructure; - EXPECT_THROW(runTest(filename, requirements), InconsistentInputError); - } + EXPECT_THROW(runTest(filename, requirements), InconsistentInputError); + } }; /*!\libinternal \brief Helper to test supported file names. */ -class AnyOutputSupportedFiles : public ModuleTest, - public ModuleSelection +class AnyOutputSupportedFiles : public ModuleTest, public ModuleSelection { - public: - void prepareTest(const char *filename) - { - addTopology(); - //! Storage for requirements. - OutputRequirements requirements; - //! Local atoms - Selection sel; - //! Local box - matrix box; - - clear_mat(box); - - addOptionForSelection(&dummySelection_, true); - setSelectionOptionValues(getOption(), &dummySelection_, true); - - copy_mat(requirements.newBox, box); - requirements.box = ChangeFrameInfoType::Always; - requirements.frameTime = ChangeFrameTimeType::Both; - - EXPECT_NO_THROW(runTest(filename, requirements)); - } +public: + void prepareTest(const char* filename) + { + addTopology(); + //! Storage for requirements. + OutputRequirements requirements; + //! Local atoms + Selection sel; + //! Local box + matrix box; + + clear_mat(box); + + addOptionForSelection(&dummySelection_, true); + setSelectionOptionValues(getOption(), &dummySelection_, true); + + copy_mat(requirements.newBox, box); + requirements.box = ChangeFrameInfoType::Always; + requirements.frameTime = ChangeFrameTimeType::Both; + + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test support for disabling all output options. */ class NoOptionalOutput : public ModuleTest { - public: - void prepareTest(const char *filename) - { - addTopology(); - //! Storage for requirements. - OutputRequirements requirements; - - requirements.atoms = ChangeAtomsType::Never; - requirements.velocity = ChangeSettingType::Never; - requirements.force = ChangeSettingType::Never; - requirements.precision = ChangeFrameInfoType::Always; - requirements.prec = 3; - - EXPECT_NO_THROW(runTest(filename, requirements)); - } +public: + void prepareTest(const char* filename) + { + addTopology(); + //! Storage for requirements. + OutputRequirements requirements; + + requirements.atoms = ChangeAtomsType::Never; + requirements.velocity = ChangeSettingType::Never; + requirements.force = ChangeSettingType::Never; + requirements.precision = ChangeFrameInfoType::Always; + requirements.prec = 3; + + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test that invalid selection is rejected */ -class OutputSelectorDeathTest : public ModuleTest, - public ModuleSelection +class OutputSelectorDeathTest : public ModuleTest, public ModuleSelection { - public: - void prepareTest() - { - //! Storage for frameadapters. - OutputAdapterContainer adapters(CoordinateFileFlags::Base); - //! Local atoms - Selection sel; - - addOptionForSelection(&sel, false); - setSelectionOptionValues(getOption(), &sel, false); - - ASSERT_DEATH_IF_SUPPORTED( - adapters.addAdapter(std::make_unique(sel), - CoordinateFileFlags::RequireCoordinateSelection), - "Need a valid selection out of simple atom indices"); - } +public: + void prepareTest() + { + //! Storage for frameadapters. + OutputAdapterContainer adapters(CoordinateFileFlags::Base); + //! Local atoms + Selection sel; + + addOptionForSelection(&sel, false); + setSelectionOptionValues(getOption(), &sel, false); + + ASSERT_DEATH_IF_SUPPORTED(adapters.addAdapter(std::make_unique(sel), + CoordinateFileFlags::RequireCoordinateSelection), + "Need a valid selection out of simple atom indices"); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetVelocitySupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - addTopology(); - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + addTopology(); + //! Storage for requirements. + OutputRequirements requirements; - requirements.velocity = ChangeSettingType::Always; + requirements.velocity = ChangeSettingType::Always; - EXPECT_NO_THROW(runTest(filename, requirements)); - } + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetVelocityUnSupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + //! Storage for requirements. + OutputRequirements requirements; - requirements.velocity = ChangeSettingType::Always; + requirements.velocity = ChangeSettingType::Always; - EXPECT_THROW(runTest(filename, requirements), - InconsistentInputError); - } + EXPECT_THROW(runTest(filename, requirements), InconsistentInputError); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetForceSupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - addTopology(); - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + addTopology(); + //! Storage for requirements. + OutputRequirements requirements; - requirements.force = ChangeSettingType::Always; + requirements.force = ChangeSettingType::Always; - EXPECT_NO_THROW(runTest(filename, requirements)); - } + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetForceUnSupportedFiles : public ModuleTest { - public: - void prepareTest(const char *filename) - { - //! Storage for requirements. - OutputRequirements requirements; +public: + void prepareTest(const char* filename) + { + //! Storage for requirements. + OutputRequirements requirements; - requirements.force = ChangeSettingType::Always; + requirements.force = ChangeSettingType::Always; - EXPECT_THROW(runTest(filename, requirements), - InconsistentInputError); - } + EXPECT_THROW(runTest(filename, requirements), InconsistentInputError); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetPrecisionSupportedFiles : public ModuleTest { - public: - /*! \brief Set up the test case before running. - * - * \param[in] filename Name of the outputfile used to specify file type. - */ - void prepareTest(const char *filename) - { - addTopology(); - OutputRequirements requirements; - - requirements.precision = ChangeFrameInfoType::Always; - requirements.prec = 5; - - EXPECT_NO_THROW(runTest(filename, requirements)); - } +public: + /*! \brief Set up the test case before running. + * + * \param[in] filename Name of the outputfile used to specify file type. + */ + void prepareTest(const char* filename) + { + addTopology(); + OutputRequirements requirements; + + requirements.precision = ChangeFrameInfoType::Always; + requirements.prec = 5; + + EXPECT_NO_THROW(runTest(filename, requirements)); + } }; /*!\libinternal \brief Helper to test supported file names. */ class SetPrecisionUnSupportedFiles : public ModuleTest { - public: - /*! \brief Set up the test case before running. - * - * \param[in] filename Name of the outputfile used to specify file type. - */ - void prepareTest(const char *filename) - { - OutputRequirements requirements; - - requirements.precision = ChangeFrameInfoType::Always; - requirements.prec = 5; - - EXPECT_THROW(runTest(filename, requirements), - InconsistentInputError); - } +public: + /*! \brief Set up the test case before running. + * + * \param[in] filename Name of the outputfile used to specify file type. + */ + void prepareTest(const char* filename) + { + OutputRequirements requirements; + + requirements.precision = ChangeFrameInfoType::Always; + requirements.prec = 5; + + EXPECT_THROW(runTest(filename, requirements), InconsistentInputError); + } }; //! Names here work for setAtoms module -const char *const setAtomsSupported[] = { +const char* const setAtomsSupported[] = { #if GMX_USE_TNG "spc2-traj.tng", #endif @@ -283,11 +277,7 @@ const char *const setAtomsSupported[] = { }; //! Names here don't work for setAtoms module -const char *const setAtomsUnSupported[] = { - "spc2-traj.trr", - "spc2-traj.xtc", - "spc2-traj.g96" -}; +const char* const setAtomsUnSupported[] = { "spc2-traj.trr", "spc2-traj.xtc", "spc2-traj.g96" }; /*! \brief * Names here work for stuff that has no specific requirements. @@ -295,17 +285,14 @@ const char *const setAtomsUnSupported[] = { * PDB and GRO format are not tested here because they also require atoms information * that is incompatible with the other output formats. */ -const char *const anySupported[] = { - "spc2-traj.trr", +const char* const anySupported[] = { "spc2-traj.trr", #if GMX_USE_TNG - "spc2-traj.tng", + "spc2-traj.tng", #endif - "spc2-traj.xtc", - "spc2-traj.g96" -}; + "spc2-traj.xtc", "spc2-traj.g96" }; //! Names here work for setVelocity module -const char *const setVelocitySupported[] = { +const char* const setVelocitySupported[] = { #if GMX_USE_TNG "spc2-traj.tng", #endif @@ -314,14 +301,10 @@ const char *const setVelocitySupported[] = { }; //! Names here don't work for setVelocity module -const char *const setVelocityUnSupported[] = { - "spc2-traj.xtc", - "spc2-traj.pdb", - "spc2-traj.g96" -}; +const char* const setVelocityUnSupported[] = { "spc2-traj.xtc", "spc2-traj.pdb", "spc2-traj.g96" }; //! Names here work for setForce module -const char *const setForceSupported[] = { +const char* const setForceSupported[] = { #if GMX_USE_TNG "spc2-traj.tng", #endif @@ -329,15 +312,11 @@ const char *const setForceSupported[] = { }; //! Names here don't work for setForce module -const char *const setForceUnSupported[] = { - "spc2-traj.xtc", - "spc2-traj.pdb", - "spc2-traj.gro", - "spc2-traj.g96" -}; +const char* const setForceUnSupported[] = { "spc2-traj.xtc", "spc2-traj.pdb", "spc2-traj.gro", + "spc2-traj.g96" }; //! Names here work for setPrecision module -const char *const setPrecisionSupported[] = { +const char* const setPrecisionSupported[] = { #if GMX_USE_TNG "spc2-traj.tng", #endif @@ -345,12 +324,8 @@ const char *const setPrecisionSupported[] = { }; //! Names here don't work for setPrecision module -const char *const setPrecisionUnSupported[] = { - "spc2-traj.trr", - "spc2-traj.pdb", - "spc2-traj.gro", - "spc2-traj.g96" -}; +const char* const setPrecisionUnSupported[] = { "spc2-traj.trr", "spc2-traj.pdb", "spc2-traj.gro", + "spc2-traj.g96" }; } // namespace test diff --git a/src/gromacs/coordinateio/tests/requirements.cpp b/src/gromacs/coordinateio/tests/requirements.cpp index 9acd3d9264..da9ced7904 100644 --- a/src/gromacs/coordinateio/tests/requirements.cpp +++ b/src/gromacs/coordinateio/tests/requirements.cpp @@ -53,26 +53,26 @@ namespace test TEST_F(FlagTest, CanSetSimpleFlag) { - std::string option = "atoms"; - std::string value = "always"; + std::string option = "atoms"; + std::string value = "always"; setModuleFlag(option, value, &options_, TestEnums::efTestString); - OutputRequirements reqs = requirementsBuilder_.process(); + OutputRequirements reqs = requirementsBuilder_.process(); EXPECT_EQ(reqs.atoms, ChangeAtomsType::Always); } TEST_F(FlagTest, CanAddNewBox) { - std::string option = "box"; - std::string value = "3 3 3"; + std::string option = "box"; + std::string value = "3 3 3"; setModuleFlag(option, value, &options_, TestEnums::efTestFloat); - OutputRequirements req = requirementsBuilder_.process(); + OutputRequirements req = requirementsBuilder_.process(); EXPECT_EQ(req.box, ChangeFrameInfoType::Always); } TEST_F(FlagTest, SetsImplicitPrecisionChange) { - std::string option = "precision"; - std::string value = "5"; + std::string option = "precision"; + std::string value = "5"; setModuleFlag(option, value, &options_, TestEnums::efTestInt); OutputRequirements req = requirementsBuilder_.process(); EXPECT_EQ(req.precision, ChangeFrameInfoType::Always); @@ -80,8 +80,8 @@ TEST_F(FlagTest, SetsImplicitPrecisionChange) TEST_F(FlagTest, SetsImplicitStartTimeChange) { - std::string option = "starttime"; - std::string value = "20"; + std::string option = "starttime"; + std::string value = "20"; setModuleFlag(option, value, &options_, TestEnums::efTestFloat); OutputRequirements req = requirementsBuilder_.process(); EXPECT_EQ(req.frameTime, ChangeFrameTimeType::StartTime); @@ -89,8 +89,8 @@ TEST_F(FlagTest, SetsImplicitStartTimeChange) TEST_F(FlagTest, SetsImplicitTimeStepChange) { - std::string option = "timestep"; - std::string value = "20"; + std::string option = "timestep"; + std::string value = "20"; setModuleFlag(option, value, &options_, TestEnums::efTestFloat); OutputRequirements req = requirementsBuilder_.process(); EXPECT_EQ(req.frameTime, ChangeFrameTimeType::TimeStep); diff --git a/src/gromacs/coordinateio/tests/requirements.h b/src/gromacs/coordinateio/tests/requirements.h index d4a55d1b9b..da4dd48b15 100644 --- a/src/gromacs/coordinateio/tests/requirements.h +++ b/src/gromacs/coordinateio/tests/requirements.h @@ -78,21 +78,20 @@ enum class TestEnums * \param[in] optionValues String to split that contains option values. * \param[in] type Determine which input time we are using. */ -static void -splitAndAddValues(OptionsAssigner *assigner, const std::string &optionValues, TestEnums type) +static void splitAndAddValues(OptionsAssigner* assigner, const std::string& optionValues, TestEnums type) { std::vector strings = splitString(optionValues); - for (const auto &entry : strings) + for (const auto& entry : strings) { switch (type) { case (TestEnums::efTestFloat): - { - real value = std::stod(entry); - Any var(value); - assigner->appendValue(var); - break; - } + { + real value = std::stod(entry); + Any var(value); + assigner->appendValue(var); + break; + } case (TestEnums::efTestString): { assigner->appendValue(entry); @@ -100,13 +99,12 @@ splitAndAddValues(OptionsAssigner *assigner, const std::string &optionValues, Te } case (TestEnums::efTestInt): { - int value = std::stoi(entry); - Any var(value); + int value = std::stoi(entry); + Any var(value); assigner->appendValue(var); break; } - default: - GMX_THROW(InternalError("No such input type")); + default: GMX_THROW(InternalError("No such input type")); } } } @@ -117,38 +115,32 @@ splitAndAddValues(OptionsAssigner *assigner, const std::string &optionValues, Te */ class FlagTest : public gmx::test::CommandLineTestBase { - public: - FlagTest() - { - requirementsBuilder_.initOptions(&options_); - } - - /*! \brief - * Set value for options in flag setting object. - * - * \param[in] optionName Name of the option to add value for. - * \param[in] optionValues Values to set for option. - * \param[in] options Container for options. - * \param[in] type Need to know type of entries. - */ - void setModuleFlag(const std::string &optionName, - const std::string &optionValues, - Options *options, - TestEnums type) - { - OptionsAssigner assigner(options); - assigner.start(); - assigner.startOption(optionName.c_str()); - splitAndAddValues(&assigner, optionValues, type); +public: + FlagTest() { requirementsBuilder_.initOptions(&options_); } + + /*! \brief + * Set value for options in flag setting object. + * + * \param[in] optionName Name of the option to add value for. + * \param[in] optionValues Values to set for option. + * \param[in] options Container for options. + * \param[in] type Need to know type of entries. + */ + void setModuleFlag(const std::string& optionName, const std::string& optionValues, Options* options, TestEnums type) + { + OptionsAssigner assigner(options); + assigner.start(); + assigner.startOption(optionName.c_str()); + splitAndAddValues(&assigner, optionValues, type); - assigner.finishOption(); - assigner.finish(); - } + assigner.finishOption(); + assigner.finish(); + } - //! Storage of requirments. - OutputRequirementOptionDirector requirementsBuilder_; - //! Options storage - Options options_; + //! Storage of requirments. + OutputRequirementOptionDirector requirementsBuilder_; + //! Options storage + Options options_; }; } // namespace test diff --git a/src/gromacs/coordinateio/tests/setatoms.cpp b/src/gromacs/coordinateio/tests/setatoms.cpp index 8dc116fa69..79ac2ad7b2 100644 --- a/src/gromacs/coordinateio/tests/setatoms.cpp +++ b/src/gromacs/coordinateio/tests/setatoms.cpp @@ -64,45 +64,42 @@ namespace test */ class SetAtomsTest : public gmx::test::CommandLineTestBase { - public: - //! Prepare test fixture topology to have atoms available. - SetAtomsTest() +public: + //! Prepare test fixture topology to have atoms available. + SetAtomsTest() + { + topology_.fillFromInputFile(TestFileManager::getInputFilePath("lysozyme.pdb")); + } + + /*! \brief + * Get access to the method for changing atom information. + * + * \param[in] type Type to use for setting up method. + * \param[in] haveAtomsAvailable Decide if method shouöd have atoms stored or not. + */ + SetAtoms* setAtoms(ChangeAtomsType type, bool haveAtomsAvailable) + { + if (!setAtoms_) { - topology_.fillFromInputFile(TestFileManager::getInputFilePath("lysozyme.pdb")); - } - - /*! \brief - * Get access to the method for changing atom information. - * - * \param[in] type Type to use for setting up method. - * \param[in] haveAtomsAvailable Decide if method shouöd have atoms stored or not. - */ - SetAtoms *setAtoms(ChangeAtomsType type, bool haveAtomsAvailable) - { - if (!setAtoms_) + if (haveAtomsAvailable) { - if (haveAtomsAvailable) - { - setAtoms_ = std::make_unique(type, topology_.copyAtoms()); - } - else - { - setAtoms_ = std::make_unique(type, nullptr); - } + setAtoms_ = std::make_unique(type, topology_.copyAtoms()); + } + else + { + setAtoms_ = std::make_unique(type, nullptr); } - return setAtoms_.get(); - } - //! Get access to a t_atoms struct to use in the dummy t_trxframe. - t_atoms *getAtomsCopy() - { - return const_cast(topology_.atoms()); } - - private: - //! Object to use for tests - SetAtomsPointer setAtoms_; - //! Local topology to get atoms from - TopologyInformation topology_; + return setAtoms_.get(); + } + //! Get access to a t_atoms struct to use in the dummy t_trxframe. + t_atoms* getAtomsCopy() { return const_cast(topology_.atoms()); } + +private: + //! Object to use for tests + SetAtomsPointer setAtoms_; + //! Local topology to get atoms from + TopologyInformation topology_; }; TEST_F(SetAtomsTest, RemovesExistingAtoms) @@ -115,7 +112,7 @@ TEST_F(SetAtomsTest, RemovesExistingAtoms) EXPECT_NE(frame.atoms, nullptr); - SetAtoms *method = setAtoms(ChangeAtomsType::Never, true); + SetAtoms* method = setAtoms(ChangeAtomsType::Never, true); EXPECT_NO_THROW(method->processFrame(0, &frame)); EXPECT_FALSE(frame.bAtoms); @@ -130,7 +127,7 @@ TEST_F(SetAtomsTest, AddsNewAtoms) frame.bAtoms = false; frame.atoms = nullptr; - SetAtoms *method = setAtoms(ChangeAtomsType::AlwaysFromStructure, true); + SetAtoms* method = setAtoms(ChangeAtomsType::AlwaysFromStructure, true); EXPECT_NO_THROW(method->processFrame(0, &frame)); EXPECT_TRUE(frame.bAtoms); @@ -145,7 +142,7 @@ TEST_F(SetAtomsTest, ThrowsOnRequiredAtomsNotAvailable) frame.bAtoms = false; frame.atoms = nullptr; - SetAtoms *method = setAtoms(ChangeAtomsType::Always, false); + SetAtoms* method = setAtoms(ChangeAtomsType::Always, false); EXPECT_THROW(method->processFrame(0, &frame), InconsistentInputError); } @@ -159,7 +156,7 @@ TEST_F(SetAtomsTest, WillUseOldAtomsWhenNoNewAvailable) EXPECT_NE(frame.atoms, nullptr); - SetAtoms *method = setAtoms(ChangeAtomsType::Always, false); + SetAtoms* method = setAtoms(ChangeAtomsType::Always, false); EXPECT_NO_THROW(method->processFrame(0, &frame)); } @@ -173,7 +170,7 @@ TEST_F(SetAtomsTest, ThrowsWhenUserAtomReplacementNotPossible) EXPECT_NE(frame.atoms, nullptr); - SetAtoms *method = setAtoms(ChangeAtomsType::AlwaysFromStructure, false); + SetAtoms* method = setAtoms(ChangeAtomsType::AlwaysFromStructure, false); EXPECT_THROW(method->processFrame(0, &frame), InconsistentInputError); } diff --git a/src/gromacs/coordinateio/tests/setbothtime.cpp b/src/gromacs/coordinateio/tests/setbothtime.cpp index b9f2206f91..b015ef7a6b 100644 --- a/src/gromacs/coordinateio/tests/setbothtime.cpp +++ b/src/gromacs/coordinateio/tests/setbothtime.cpp @@ -63,57 +63,54 @@ namespace test */ class SetBothTimeTest : public gmx::test::CommandLineTestBase { - public: - SetBothTimeTest() +public: + SetBothTimeTest() { clear_trxframe(frame(), true); } + /*! \brief + * Get access to the method for changing frame time step information. + * + * \param[in] timeStep User supplied time step to test. + */ + SetTimeStep* setTimeStep(real timeStep) + { + if (!setTimeStep_) { - clear_trxframe(frame(), true); + setTimeStep_ = std::make_unique(timeStep); } - /*! \brief - * Get access to the method for changing frame time step information. - * - * \param[in] timeStep User supplied time step to test. - */ - SetTimeStep *setTimeStep(real timeStep) + return setTimeStep_.get(); + } + /*! \brief + * Get access to the method for changing frame start time information. + * + * \param[in] startTime User supplied start time to test. + */ + SetStartTime* setStartTime(real startTime) + { + if (!setStartTime_) { - if (!setTimeStep_) - { - setTimeStep_ = std::make_unique(timeStep); - } - return setTimeStep_.get(); + setStartTime_ = std::make_unique(startTime); } - /*! \brief - * Get access to the method for changing frame start time information. - * - * \param[in] startTime User supplied start time to test. - */ - SetStartTime *setStartTime(real startTime) - { - if (!setStartTime_) - { - setStartTime_ = std::make_unique(startTime); - } - return setStartTime_.get(); - } - - //! Get access to trajectoryframe to mess with. - t_trxframe *frame() { return &frame_; } - - private: - //! Object to use for tests - SetTimeStepPointer setTimeStep_; - //! Object to use for tests - SetStartTimePointer setStartTime_; - //! Storage of trajectoryframe. - t_trxframe frame_; + return setStartTime_.get(); + } + + //! Get access to trajectoryframe to mess with. + t_trxframe* frame() { return &frame_; } + +private: + //! Object to use for tests + SetTimeStepPointer setTimeStep_; + //! Object to use for tests + SetStartTimePointer setStartTime_; + //! Storage of trajectoryframe. + t_trxframe frame_; }; TEST_F(SetBothTimeTest, StartTimeZeroWorks) { frame()->time = 23; // Set start time. - SetTimeStep *timestep = setTimeStep(7); + SetTimeStep* timestep = setTimeStep(7); // Set initial time to zero. - SetStartTime *starttime = setStartTime(0); + SetStartTime* starttime = setStartTime(0); // processing always goes through start time before time step. EXPECT_NO_THROW(starttime->processFrame(0, frame())); EXPECT_NO_THROW(timestep->processFrame(0, frame())); @@ -135,9 +132,9 @@ TEST_F(SetBothTimeTest, SetStartTimeNonZeroWorks) { frame()->time = 23; // Set start time. - SetTimeStep *timestep = setTimeStep(7); + SetTimeStep* timestep = setTimeStep(7); // Set initial time to zero. - SetStartTime *starttime = setStartTime(23); + SetStartTime* starttime = setStartTime(23); // processing always goes through start time before time step. EXPECT_NO_THROW(starttime->processFrame(0, frame())); EXPECT_NO_THROW(timestep->processFrame(0, frame())); diff --git a/src/gromacs/coordinateio/tests/setstarttime.cpp b/src/gromacs/coordinateio/tests/setstarttime.cpp index 62bedb5517..5c22753c4d 100644 --- a/src/gromacs/coordinateio/tests/setstarttime.cpp +++ b/src/gromacs/coordinateio/tests/setstarttime.cpp @@ -62,32 +62,29 @@ namespace test */ class SetStartTimeTest : public gmx::test::CommandLineTestBase { - public: - SetStartTimeTest() +public: + SetStartTimeTest() { clear_trxframe(frame(), true); } + /*! \brief + * Get access to the method for changing frame time information. + * + * \param[in] startTime User supplied start time to test. + */ + SetStartTime* setStartTime(real startTime) + { + if (!setStartTime_) { - clear_trxframe(frame(), true); + setStartTime_ = std::make_unique(startTime); } - /*! \brief - * Get access to the method for changing frame time information. - * - * \param[in] startTime User supplied start time to test. - */ - SetStartTime *setStartTime(real startTime) - { - if (!setStartTime_) - { - setStartTime_ = std::make_unique(startTime); - } - return setStartTime_.get(); - } - //! Get access to trajectoryframe to mess with. - t_trxframe *frame() { return &frame_; } + return setStartTime_.get(); + } + //! Get access to trajectoryframe to mess with. + t_trxframe* frame() { return &frame_; } - private: - //! Object to use for tests - SetStartTimePointer setStartTime_; - //! Storage of trajectoryframe. - t_trxframe frame_; +private: + //! Object to use for tests + SetStartTimePointer setStartTime_; + //! Storage of trajectoryframe. + t_trxframe frame_; }; TEST_F(SetStartTimeTest, WorksWithNonZeroStart) @@ -95,7 +92,7 @@ TEST_F(SetStartTimeTest, WorksWithNonZeroStart) frame()->bTime = false; frame()->time = 5; // Set step to nonsense value to check that it is ignored. - SetStartTime *method = setStartTime(42); + SetStartTime* method = setStartTime(42); EXPECT_NO_THROW(method->processFrame(0, frame())); EXPECT_TRUE(frame()->bTime); EXPECT_EQ(frame()->time, 42); @@ -111,8 +108,8 @@ TEST_F(SetStartTimeTest, WorksWithNonZeroStart) TEST_F(SetStartTimeTest, WorksWithZeroStart) { - frame()->time = 42; - SetStartTime *method = setStartTime(0); + frame()->time = 42; + SetStartTime* method = setStartTime(0); EXPECT_NO_THROW(method->processFrame(0, frame())); EXPECT_EQ(frame()->time, 0); // No matter what the next time in the frame is, ignore it. diff --git a/src/gromacs/coordinateio/tests/settimestep.cpp b/src/gromacs/coordinateio/tests/settimestep.cpp index ebbe9aab14..cf2a9924ea 100644 --- a/src/gromacs/coordinateio/tests/settimestep.cpp +++ b/src/gromacs/coordinateio/tests/settimestep.cpp @@ -62,39 +62,36 @@ namespace test */ class SetTimeStepTest : public gmx::test::CommandLineTestBase { - public: - SetTimeStepTest() +public: + SetTimeStepTest() { clear_trxframe(frame(), true); } + /*! \brief + * Get access to the method for changing frame time information. + * + * \param[in] timeStep User supplied time step to test. + */ + SetTimeStep* setTimeStep(real timeStep) + { + if (!setTimeStep_) { - clear_trxframe(frame(), true); + setTimeStep_ = std::make_unique(timeStep); } - /*! \brief - * Get access to the method for changing frame time information. - * - * \param[in] timeStep User supplied time step to test. - */ - SetTimeStep *setTimeStep(real timeStep) - { - if (!setTimeStep_) - { - setTimeStep_ = std::make_unique(timeStep); - } - return setTimeStep_.get(); - } - //! Get access to trajectoryframe to mess with. - t_trxframe *frame() { return &frame_; } + return setTimeStep_.get(); + } + //! Get access to trajectoryframe to mess with. + t_trxframe* frame() { return &frame_; } - private: - //! Object to use for tests - SetTimeStepPointer setTimeStep_; - //! Storage of trajectoryframe. - t_trxframe frame_; +private: + //! Object to use for tests + SetTimeStepPointer setTimeStep_; + //! Storage of trajectoryframe. + t_trxframe frame_; }; TEST_F(SetTimeStepTest, SetTimeStepWorks) { frame()->time = 23; // Set start time to nonsense to make sure it is ignored. - SetTimeStep *method = setTimeStep(7); + SetTimeStep* method = setTimeStep(7); EXPECT_NO_THROW(method->processFrame(0, frame())); EXPECT_EQ(frame()->time, 23); // No matter what the next time in the frame is, ignore it. diff --git a/src/gromacs/coordinateio/tests/testmodule.h b/src/gromacs/coordinateio/tests/testmodule.h index db5c04c754..dc68a355f5 100644 --- a/src/gromacs/coordinateio/tests/testmodule.h +++ b/src/gromacs/coordinateio/tests/testmodule.h @@ -55,23 +55,23 @@ namespace test class DummyOutputModule : public IOutputAdapter { - public: - explicit DummyOutputModule(CoordinateFileFlags requirementsFlag) : - moduleRequirements_(requirementsFlag) - {} +public: + explicit DummyOutputModule(CoordinateFileFlags requirementsFlag) : + moduleRequirements_(requirementsFlag) + { + } - DummyOutputModule(DummyOutputModule &&old) noexcept = default; + DummyOutputModule(DummyOutputModule&& old) noexcept = default; - ~DummyOutputModule() override {} + ~DummyOutputModule() override {} - void processFrame(int /*framenumber*/, t_trxframe * /*input*/) override - {} + void processFrame(int /*framenumber*/, t_trxframe* /*input*/) override {} - void checkAbilityDependencies(unsigned long abilities) const override; + void checkAbilityDependencies(unsigned long abilities) const override; - private: - //! Local requirements - CoordinateFileFlags moduleRequirements_; +private: + //! Local requirements + CoordinateFileFlags moduleRequirements_; }; } // namespace test diff --git a/src/gromacs/correlationfunctions/autocorr.cpp b/src/gromacs/correlationfunctions/autocorr.cpp index f985bd705f..1f4f5c7a3b 100644 --- a/src/gromacs/correlationfunctions/autocorr.cpp +++ b/src/gromacs/correlationfunctions/autocorr.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,7 +68,8 @@ /*! \brief Shortcut macro to select modes. */ #define MODE(x) ((mode & (x)) == (x)) -typedef struct { +typedef struct +{ unsigned long mode; int nrestart, nout, P, fitfn; gmx_bool bFour, bNormalize; @@ -76,21 +77,23 @@ typedef struct { } t_acf; /*! \brief Global variable set true if initialization routines are called. */ -static gmx_bool bACFinit = FALSE; +static gmx_bool bACFinit = FALSE; /*! \brief Data structure for storing command line variables. */ -static t_acf acf; +static t_acf acf; -enum { - enNorm, enCos, enSin +enum +{ + enNorm, + enCos, + enSin }; /*! \brief Routine to compute ACF using FFT. */ -static void low_do_four_core(int nframes, real c1[], real cfour[], - int nCos) +static void low_do_four_core(int nframes, real c1[], real cfour[], int nCos) { - int i = 0; - std::vector > data; + int i = 0; + std::vector> data; data.resize(1); data[0].resize(nframes, 0); switch (nCos) @@ -113,8 +116,7 @@ static void low_do_four_core(int nframes, real c1[], real cfour[], data[0][i] = sin(c1[i]); } break; - default: - gmx_fatal(FARGS, "nCos = %d, %s %d", nCos, __FILE__, __LINE__); + default: gmx_fatal(FARGS, "nCos = %d, %s %d", nCos, __FILE__, __LINE__); } many_auto_correl(&data); @@ -125,13 +127,11 @@ static void low_do_four_core(int nframes, real c1[], real cfour[], } /*! \brief Routine to comput ACF without FFT. */ -static void do_ac_core(int nframes, int nout, - real corr[], real c1[], int nrestart, - unsigned long mode) +static void do_ac_core(int nframes, int nout, real corr[], real c1[], int nrestart, unsigned long mode) { - int j, k, j3, jk3, m, n; - real ccc, cth; - rvec xj, xk; + int j, k, j3, jk3, m, n; + real ccc, cth; + rvec xj, xk; if (nrestart < 1) { @@ -140,9 +140,8 @@ static void do_ac_core(int nframes, int nout, } if (debug) { - fprintf(debug, - "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n", - nframes, nout, nrestart, mode); + fprintf(debug, "Starting do_ac_core: nframes=%d, nout=%d, nrestart=%d,mode=%lu\n", nframes, + nout, nrestart, mode); } for (j = 0; (j < nout); j++) @@ -153,12 +152,12 @@ static void do_ac_core(int nframes, int nout, /* Loop over starting points. */ for (j = 0; (j < nframes); j += nrestart) { - j3 = DIM*j; + j3 = DIM * j; /* Loop over the correlation length for this starting point */ - for (k = 0; (k < nout) && (j+k < nframes); k++) + for (k = 0; (k < nout) && (j + k < nframes); k++) { - jk3 = DIM*(j+k); + jk3 = DIM * (j + k); /* Switch over possible ACF types. * It might be more efficient to put the loops inside the switch, @@ -166,17 +165,17 @@ static void do_ac_core(int nframes, int nout, */ if (MODE(eacNormal)) { - corr[k] += c1[j]*c1[j+k]; + corr[k] += c1[j] * c1[j + k]; } else if (MODE(eacCos)) { /* Compute the cos (phi(t)-phi(t+dt)) */ - corr[k] += std::cos(c1[j]-c1[j+k]); + corr[k] += std::cos(c1[j] - c1[j + k]); } else if (MODE(eacIden)) { /* Check equality (phi(t)==phi(t+dt)) */ - corr[k] += (c1[j] == c1[j+k]) ? 1 : 0; + corr[k] += (c1[j] == c1[j + k]) ? 1 : 0; } else if (MODE(eacP1) || MODE(eacP2) || MODE(eacP3)) { @@ -184,15 +183,15 @@ static void do_ac_core(int nframes, int nout, for (m = 0; (m < DIM); m++) { - xj[m] = c1[j3+m]; - xk[m] = c1[jk3+m]; + xj[m] = c1[j3 + m]; + xk[m] = c1[jk3 + m]; } cth = cos_angle(xj, xk); - if (cth-1.0 > 1.0e-15) + if (cth - 1.0 > 1.0e-15) { - printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n", - j, k, xj[XX], xj[YY], xj[ZZ], xk[XX], xk[YY], xk[ZZ]); + printf("j: %d, k: %d, xj:(%g,%g,%g), xk:(%g,%g,%g)\n", j, k, xj[XX], xj[YY], + xj[ZZ], xk[XX], xk[YY], xk[ZZ]); } mmm = 1; if (MODE(eacP2)) @@ -210,8 +209,8 @@ static void do_ac_core(int nframes, int nout, rvec xj, xk, rr; for (m = 0; (m < DIM); m++) { - xj[m] = c1[j3+m]; - xk[m] = c1[jk3+m]; + xj[m] = c1[j3 + m]; + xk[m] = c1[jk3 + m]; } cprod(xj, xk, rr); @@ -221,8 +220,8 @@ static void do_ac_core(int nframes, int nout, { for (m = 0; (m < DIM); m++) { - xj[m] = c1[j3+m]; - xk[m] = c1[jk3+m]; + xj[m] = c1[j3 + m]; + xk[m] = c1[jk3 + m]; } ccc = iprod(xj, xk); @@ -237,8 +236,8 @@ static void do_ac_core(int nframes, int nout, /* Correct for the number of points and copy results to the data array */ for (j = 0; (j < nout); j++) { - n = (nframes-j+(nrestart-1))/nrestart; - c1[j] = corr[j]/n; + n = (nframes - j + (nrestart - 1)) / nrestart; + c1[j] = corr[j] / n; } } @@ -266,7 +265,7 @@ static void normalize_acf(int nout, real corr[]) } else { - c0 = 1.0/corr[0]; + c0 = 1.0 / corr[0]; } for (j = 0; (j < nout); j++) { @@ -284,7 +283,7 @@ static void normalize_acf(int nout, real corr[]) } /*! \brief Routine that averages ACFs. */ -static void average_acf(gmx_bool bVerbose, int n, int nitem, real **c1) +static void average_acf(gmx_bool bVerbose, int n, int nitem, real** c1) { real c0; int i, j; @@ -301,7 +300,7 @@ static void average_acf(gmx_bool bVerbose, int n, int nitem, real **c1) { c0 += c1[i][j]; } - c1[0][j] = c0/nitem; + c1[0][j] = c0 / nitem; } } @@ -309,11 +308,11 @@ static void average_acf(gmx_bool bVerbose, int n, int nitem, real **c1) static void norm_and_scale_vectors(int nframes, real c1[], real scale) { int j, m; - real *rij; + real* rij; for (j = 0; (j < nframes); j++) { - rij = &(c1[j*DIM]); + rij = &(c1[j * DIM]); unitv(rij, rij); for (m = 0; (m < DIM); m++) { @@ -323,9 +322,9 @@ static void norm_and_scale_vectors(int nframes, real c1[], real scale) } /*! \brief Debugging */ -static void dump_tmp(char *s, int n, real c[]) +static void dump_tmp(char* s, int n, real c[]) { - FILE *fp; + FILE* fp; int i; fp = gmx_ffopen(s, "w"); @@ -337,13 +336,12 @@ static void dump_tmp(char *s, int n, real c[]) } /*! \brief High level ACF routine. */ -static void do_four_core(unsigned long mode, int nframes, - real c1[], real csum[], real ctmp[]) +static void do_four_core(unsigned long mode, int nframes, real c1[], real csum[], real ctmp[]) { - real *cfour; - char buf[32]; - real fac; - int j, m, m1; + real* cfour; + char buf[32]; + real fac; + int j, m, m1; snew(cfour, nframes); @@ -371,14 +369,14 @@ static void do_four_core(unsigned long mode, int nframes, low_do_four_core(nframes, ctmp, cfour, enCos); for (j = 0; (j < nframes); j++) { - c1[j] = cfour[j]; + c1[j] = cfour[j]; } /* Sine term of AC function */ low_do_four_core(nframes, ctmp, cfour, enSin); for (j = 0; (j < nframes); j++) { - c1[j] += cfour[j]; + c1[j] += cfour[j]; csum[j] = c1[j]; } } @@ -425,7 +423,7 @@ static void do_four_core(unsigned long mode, int nframes, */ for (j = 0; (j < nframes); j++) { - csum[j] = -0.5*(nframes-j); + csum[j] = -0.5 * (nframes - j); } /***** DIAGONAL ELEMENTS ************/ @@ -434,7 +432,7 @@ static void do_four_core(unsigned long mode, int nframes, /* Copy the vector data in a linear array */ for (j = 0; (j < nframes); j++) { - ctmp[j] = gmx::square(c1[DIM*j+m]); + ctmp[j] = gmx::square(c1[DIM * j + m]); } if (debug) { @@ -452,17 +450,17 @@ static void do_four_core(unsigned long mode, int nframes, fac = 1.5; for (j = 0; (j < nframes); j++) { - csum[j] += fac*(cfour[j]); + csum[j] += fac * (cfour[j]); } } /******* OFF-DIAGONAL ELEMENTS **********/ for (m = 0; (m < DIM); m++) { /* Copy the vector data in a linear array */ - m1 = (m+1) % DIM; + m1 = (m + 1) % DIM; for (j = 0; (j < nframes); j++) { - ctmp[j] = c1[DIM*j+m]*c1[DIM*j+m1]; + ctmp[j] = c1[DIM * j + m] * c1[DIM * j + m1]; } if (debug) @@ -479,7 +477,7 @@ static void do_four_core(unsigned long mode, int nframes, fac = 3.0; for (j = 0; (j < nframes); j++) { - csum[j] += fac*cfour[j]; + csum[j] += fac * cfour[j]; } } } @@ -507,7 +505,7 @@ static void do_four_core(unsigned long mode, int nframes, /* Copy the vector data in a linear array */ for (j = 0; (j < nframes); j++) { - ctmp[j] = c1[DIM*j+m]; + ctmp[j] = c1[DIM * j + m]; } low_do_four_core(nframes, ctmp, cfour, enNorm); for (j = 0; (j < nframes); j++) @@ -524,29 +522,39 @@ static void do_four_core(unsigned long mode, int nframes, sfree(cfour); for (j = 0; (j < nframes); j++) { - c1[j] = csum[j]/static_cast(nframes-j); + c1[j] = csum[j] / static_cast(nframes - j); } } -void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *title, - int nframes, int nitem, int nout, real **c1, - real dt, unsigned long mode, int nrestart, - gmx_bool bAver, gmx_bool bNormalize, - gmx_bool bVerbose, real tbeginfit, real tendfit, - int eFitFn) +void low_do_autocorr(const char* fn, + const gmx_output_env_t* oenv, + const char* title, + int nframes, + int nitem, + int nout, + real** c1, + real dt, + unsigned long mode, + int nrestart, + gmx_bool bAver, + gmx_bool bNormalize, + gmx_bool bVerbose, + real tbeginfit, + real tendfit, + int eFitFn) { - FILE *fp, *gp = nullptr; - int i; - real *csum; - real *ctmp, *fit; - real sum, Ct2av, Ctav; - gmx_bool bFour = acf.bFour; + FILE * fp, *gp = nullptr; + int i; + real* csum; + real * ctmp, *fit; + real sum, Ct2av, Ctav; + gmx_bool bFour = acf.bFour; /* Check flags and parameters */ nout = get_acfnout(); if (nout == -1) { - nout = acf.nout = (nframes+1)/2; + nout = acf.nout = (nframes + 1) / 2; } else if (nout > nframes) { @@ -555,8 +563,7 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t if (MODE(eacCos) && MODE(eacVector)) { - gmx_fatal(FARGS, "Incompatible options bCos && bVector (%s, %d)", - __FILE__, __LINE__); + gmx_fatal(FARGS, "Incompatible options bCos && bVector (%s, %d)", __FILE__, __LINE__); } if ((MODE(eacP3) || MODE(eacRcross)) && bFour) { @@ -576,9 +583,8 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t { printf("Will calculate %s of %d thingies for %d frames\n", title ? title : "autocorrelation", nitem, nframes); - printf("bAver = %s, bFour = %s bNormalize= %s\n", - gmx::boolToString(bAver), gmx::boolToString(bFour), - gmx::boolToString(bNormalize)); + printf("bAver = %s, bFour = %s bNormalize= %s\n", gmx::boolToString(bAver), + gmx::boolToString(bFour), gmx::boolToString(bNormalize)); printf("mode = %lu, dt = %g, nrestart = %d\n", mode, dt, nrestart); } /* Allocate temp arrays */ @@ -591,9 +597,9 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t */ for (int i = 0; i < nitem; i++) { - if (bVerbose && (((i % 100) == 0) || (i == nitem-1))) + if (bVerbose && (((i % 100) == 0) || (i == nitem - 1))) { - fprintf(stderr, "\rThingie %d", i+1); + fprintf(stderr, "\rThingie %d", i + 1); fflush(stderr); } @@ -673,13 +679,11 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t sum = print_and_integrate(fp, nout, dt, c1[i], nullptr, 1); if (debug) { - fprintf(debug, - "CORRelation time (integral over corrfn %d): %g (ps)\n", - i, sum); + fprintf(debug, "CORRelation time (integral over corrfn %d): %g (ps)\n", i, sum); } } - Ctav += sum; - Ct2av += sum*sum; + Ctav += sum; + Ct2av += sum * sum; if (debug) { fprintf(gp, "%5d %.3f\n", i, sum); @@ -691,11 +695,11 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t } if (nitem > 1) { - Ctav /= nitem; + Ctav /= nitem; Ct2av /= nitem; - printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n", - Ctav, std::sqrt((Ct2av - gmx::square(Ctav))), - std::sqrt((Ct2av - gmx::square(Ctav))/(nitem-1))); + printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n", Ctav, + std::sqrt((Ct2av - gmx::square(Ctav))), + std::sqrt((Ct2av - gmx::square(Ctav)) / (nitem - 1))); } } if (fp) @@ -706,40 +710,53 @@ void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *t } /*! \brief Legend for selecting Legendre polynomials. */ -static const char *Leg[] = { nullptr, "0", "1", "2", "3", nullptr }; +static const char* Leg[] = { nullptr, "0", "1", "2", "3", nullptr }; -t_pargs *add_acf_pargs(int *npargs, t_pargs *pa) +t_pargs* add_acf_pargs(int* npargs, t_pargs* pa) { - t_pargs acfpa[] = { - { "-acflen", FALSE, etINT, {&acf.nout}, + t_pargs acfpa[] = { + { "-acflen", + FALSE, + etINT, + { &acf.nout }, "Length of the ACF, default is half the number of frames" }, - { "-normalize", FALSE, etBOOL, {&acf.bNormalize}, - "Normalize ACF" }, - { "-fftcorr", FALSE, etBOOL, {&acf.bFour}, + { "-normalize", FALSE, etBOOL, { &acf.bNormalize }, "Normalize ACF" }, + { "-fftcorr", + FALSE, + etBOOL, + { &acf.bFour }, "HIDDENUse fast fourier transform for correlation function" }, - { "-nrestart", FALSE, etINT, {&acf.nrestart}, + { "-nrestart", + FALSE, + etINT, + { &acf.nrestart }, "HIDDENNumber of frames between time origins for ACF when no FFT is used" }, - { "-P", FALSE, etENUM, {Leg}, - "Order of Legendre polynomial for ACF (0 indicates none)" }, - { "-fitfn", FALSE, etENUM, {s_ffn}, - "Fit function" }, - { "-beginfit", FALSE, etREAL, {&acf.tbeginfit}, + { "-P", FALSE, etENUM, { Leg }, "Order of Legendre polynomial for ACF (0 indicates none)" }, + { "-fitfn", FALSE, etENUM, { s_ffn }, "Fit function" }, + { "-beginfit", + FALSE, + etREAL, + { &acf.tbeginfit }, "Time where to begin the exponential fit of the correlation function" }, - { "-endfit", FALSE, etREAL, {&acf.tendfit}, - "Time where to end the exponential fit of the correlation function, -1 is until the end" }, + { "-endfit", + FALSE, + etREAL, + { &acf.tendfit }, + "Time where to end the exponential fit of the correlation function, -1 is until the " + "end" }, }; - t_pargs *ppa; + t_pargs* ppa; int i, npa; npa = asize(acfpa); - snew(ppa, *npargs+npa); + snew(ppa, *npargs + npa); for (i = 0; (i < *npargs); i++) { ppa[i] = pa[i]; } for (i = 0; (i < npa); i++) { - ppa[*npargs+i] = acfpa[i]; + ppa[*npargs + i] = acfpa[i]; } (*npargs) += npa; @@ -758,9 +775,15 @@ t_pargs *add_acf_pargs(int *npargs, t_pargs *pa) return ppa; } -void do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *title, - int nframes, int nitem, real **c1, - real dt, unsigned long mode, gmx_bool bAver) +void do_autocorr(const char* fn, + const gmx_output_env_t* oenv, + const char* title, + int nframes, + int nitem, + real** c1, + real dt, + unsigned long mode, + gmx_bool bAver) { if (!bACFinit) { @@ -773,23 +796,14 @@ void do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *title switch (acf.P) { - case 1: - mode = mode | eacP1; - break; - case 2: - mode = mode | eacP2; - break; - case 3: - mode = mode | eacP3; - break; - default: - break; + case 1: mode = mode | eacP1; break; + case 2: mode = mode | eacP2; break; + case 3: mode = mode | eacP3; break; + default: break; } - low_do_autocorr(fn, oenv, title, nframes, nitem, acf.nout, c1, dt, mode, - acf.nrestart, bAver, acf.bNormalize, - bDebugMode(), acf.tbeginfit, acf.tendfit, - acf.fitfn); + low_do_autocorr(fn, oenv, title, nframes, nitem, acf.nout, c1, dt, mode, acf.nrestart, bAver, + acf.bNormalize, bDebugMode(), acf.tbeginfit, acf.tendfit, acf.fitfn); } int get_acfnout() diff --git a/src/gromacs/correlationfunctions/autocorr.h b/src/gromacs/correlationfunctions/autocorr.h index 7988edc76e..3f3ccb20d6 100644 --- a/src/gromacs/correlationfunctions/autocorr.h +++ b/src/gromacs/correlationfunctions/autocorr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,25 +56,25 @@ struct gmx_output_env_t; /*! \brief Normal correlation f(t)*f(t+dt) */ -#define eacNormal (1<<0) +#define eacNormal (1 << 0) /*! \brief Cosine correlation cos(f(t)-f(t+dt)) */ -#define eacCos (1<<1) +#define eacCos (1 << 1) /*! \brief Vector correlation f(t).f(t+dt) */ -#define eacVector (1<<2) +#define eacVector (1 << 2) /*! \brief Norm of cross product |f(t) (x) f(t+dt)| */ -#define eacRcross (1<<3 | eacVector) +#define eacRcross (1 << 3 | eacVector) /*! \brief Vector with Legendre polynomial of order 0 (same as vector) */ -#define eacP0 (1<<4 | eacVector) +#define eacP0 (1 << 4 | eacVector) /*! \brief Vector with Legendre polynomial of order P_1(f(t).f(t+dt)) */ -#define eacP1 (1<<5 | eacVector) +#define eacP1 (1 << 5 | eacVector) /*! \brief Vector with Legendre polynomial of order P_2(f(t).f(t+dt)) */ -#define eacP2 (1<<6 | eacVector) +#define eacP2 (1 << 6 | eacVector) /*! \brief Vector with Legendre polynomial of order P_3(f(t).f(t+dt)) */ -#define eacP3 (1<<7 | eacVector) +#define eacP3 (1 << 7 | eacVector) /*! \brief Vector with Legendre polynomial of order P_4(f(t).f(t+dt)) */ -#define eacP4 (1<<8 | eacVector) +#define eacP4 (1 << 8 | eacVector) /*! \brief Binary identy correlation (f(t) == f(t+dt)) */ -#define eacIden (1<<9) //Not supported for multiple cores +#define eacIden (1 << 9) // Not supported for multiple cores /*! \brief * Add commandline arguments related to autocorrelations to the existing array. @@ -85,7 +85,7 @@ struct gmx_output_env_t; * \param[in] pa The initial argument list * \return the new array */ -t_pargs *add_acf_pargs(int *npargs, t_pargs *pa); +t_pargs* add_acf_pargs(int* npargs, t_pargs* pa); /*! \brief * Returns the number of points to output from a correlation function. @@ -117,10 +117,15 @@ int get_acffitfn(); * \param[in] bAver If set, all ndih C(t) functions are averaged into a single * C(t) */ -void do_autocorr(const char *fn, const gmx_output_env_t *oenv, - const char *title, - int nframes, int nitem, real **c1, - real dt, unsigned long mode, gmx_bool bAver); +void do_autocorr(const char* fn, + const gmx_output_env_t* oenv, + const char* title, + int nframes, + int nitem, + real** c1, + real dt, + unsigned long mode, + gmx_bool bAver); /*! \brief * Low level computation of autocorrelation functions @@ -171,11 +176,21 @@ void do_autocorr(const char *fn, const gmx_output_env_t *oenv, * \param[in] tendfit Time to end fitting to the ACF * \param[in] nfitparm Number of fitting parameters in a multi-exponential fit */ -void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, - const char *title, int nframes, int nitem, - int nout, real **c1, real dt, unsigned long mode, - int nrestart, gmx_bool bAver, gmx_bool bNormalize, - gmx_bool bVerbose, real tbeginfit, real tendfit, - int nfitparm); +void low_do_autocorr(const char* fn, + const gmx_output_env_t* oenv, + const char* title, + int nframes, + int nitem, + int nout, + real** c1, + real dt, + unsigned long mode, + int nrestart, + gmx_bool bAver, + gmx_bool bNormalize, + gmx_bool bVerbose, + real tbeginfit, + real tendfit, + int nfitparm); #endif diff --git a/src/gromacs/correlationfunctions/crosscorr.cpp b/src/gromacs/correlationfunctions/crosscorr.cpp index d757fba9fb..53bb594097 100644 --- a/src/gromacs/correlationfunctions/crosscorr.cpp +++ b/src/gromacs/correlationfunctions/crosscorr.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,7 +56,7 @@ */ static int zeroPaddingSize(int n) { - return 2*n; + return 2 * n; } /*! \brief @@ -65,10 +65,10 @@ static int zeroPaddingSize(int n) * \param[in] in1 first complex number * \param[in] in2 second complex number */ -static void complexConjugatMult(t_complex *in1, t_complex *in2) +static void complexConjugatMult(t_complex* in1, t_complex* in2) { t_complex res; - res.re = in1->re * in2->re + in1->im * in2->im; + res.re = in1->re * in2->re + in1->im * in2->im; res.im = in1->re * -in2->im + in1->im * in2->re; in1->re = res.re; in1->im = res.im; @@ -85,26 +85,26 @@ static void complexConjugatMult(t_complex *in1, t_complex *in2) */ static void cross_corr_low(int n, const real f[], const real g[], real corr[], gmx_fft_t fft) { - int i; - const int size = zeroPaddingSize(n); - t_complex * in1, * in2; + int i; + const int size = zeroPaddingSize(n); + t_complex *in1, *in2; snew(in1, size); snew(in2, size); for (i = 0; i < n; i++) { - in1[i].re = f[i]; - in1[i].im = 0; - in2[i].re = g[i]; - in2[i].im = 0; + in1[i].re = f[i]; + in1[i].im = 0; + in2[i].re = g[i]; + in2[i].im = 0; } for (; i < size; i++) { - in1[i].re = 0; - in1[i].im = 0; - in2[i].re = 0; - in2[i].im = 0; + in1[i].re = 0; + in1[i].im = 0; + in2[i].re = 0; + in2[i].im = 0; } gmx_fft_1d(fft, GMX_FFT_FORWARD, in1, in1); gmx_fft_1d(fft, GMX_FFT_FORWARD, in2, in2); @@ -123,22 +123,21 @@ static void cross_corr_low(int n, const real f[], const real g[], real corr[], g sfree(in1); sfree(in2); - } void cross_corr(int n, real f[], real g[], real corr[]) { gmx_fft_t fft; gmx_fft_init_1d(&fft, zeroPaddingSize(n), GMX_FFT_FLAG_CONSERVATIVE); - cross_corr_low( n, f, g, corr, fft); + cross_corr_low(n, f, g, corr, fft); gmx_fft_destroy(fft); gmx_fft_cleanup(); } -void many_cross_corr(int nFunc, int * nData, real ** f, real ** g, real ** corr) +void many_cross_corr(int nFunc, int* nData, real** f, real** g, real** corr) { #pragma omp parallel - //gmx_fft_t is not thread safe, so structure are allocated per thread. + // gmx_fft_t is not thread safe, so structure are allocated per thread. { int i; @@ -149,12 +148,11 @@ void many_cross_corr(int nFunc, int * nData, real ** f, real ** g, real ** corr) { gmx_fft_t fft; gmx_fft_init_1d(&fft, zeroPaddingSize(nData[i]), GMX_FFT_FLAG_CONSERVATIVE); - cross_corr_low( nData[i], f[i], g[i], corr[i], fft); + cross_corr_low(nData[i], f[i], g[i], corr[i], fft); gmx_fft_destroy(fft); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } gmx_fft_cleanup(); - } diff --git a/src/gromacs/correlationfunctions/crosscorr.h b/src/gromacs/correlationfunctions/crosscorr.h index d410530f55..38f9fff54d 100644 --- a/src/gromacs/correlationfunctions/crosscorr.h +++ b/src/gromacs/correlationfunctions/crosscorr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,6 +70,6 @@ void cross_corr(int n, real f[], real g[], real corr[]); * \param[in] g 2D array of second function to crosscorrelate * \param[out] corr 2D array of the cross correlations */ -void many_cross_corr(int nFunc, int * nData, real ** f, real ** g, real ** corr); +void many_cross_corr(int nFunc, int* nData, real** f, real** g, real** corr); #endif diff --git a/src/gromacs/correlationfunctions/expfit.cpp b/src/gromacs/correlationfunctions/expfit.cpp index a1bfe445be..d57ba055c9 100644 --- a/src/gromacs/correlationfunctions/expfit.cpp +++ b/src/gromacs/correlationfunctions/expfit.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,26 +69,25 @@ static const int nfp_ffn[effnNR] = { 0, 1, 2, 3, 5, 7, 9, 2, 4, 3, 6 }; * hence there are many more NULL field (which have to be at the end of * the array). */ -const char *s_ffn[effnNR+2] = { - nullptr, "none", "exp", "aexp", "exp_exp", - "exp5", "exp7", "exp9", - nullptr, nullptr, nullptr, nullptr, nullptr -}; +const char* s_ffn[effnNR + 2] = { nullptr, "none", "exp", "aexp", "exp_exp", "exp5", "exp7", + "exp9", nullptr, nullptr, nullptr, nullptr, nullptr }; +// clang-format off +// needed because clang-format wants to break the lines below /*! \brief Long description for each fitting function type */ -static const char *longs_ffn[effnNR] = { - "no fit", - "y = exp(-x/|a0|)", - "y = a1 exp(-x/|a0|)", - "y = a1 exp(-x/|a0|) + (1-a1) exp(-x/(|a2|)), a2 > a0 > 0", - "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4, a3 >= a1", - "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4 exp(-x/|a5|) + a6, a5 >= a3 >= a1", - "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4 exp(-x/|a5|) + a6 exp(-x/|a7|) + a8, a7 >= a5 >= a3 >= a1", - "y = exp(-v) (cosh(wv) + 1/w sinh(wv)), v = x/(2 a0), w = sqrt(1 - a1)", - "y = 1/2*(a0+a1) - 1/2*(a0-a1)*erf( (x-a2) /a3^2)", - "y = a1 *2*a0*((exp(-x/a0)-1)*(a0/x)+1)+(1-a1)*2*a2*((exp(-x/a2)-1)*(a2/x)+1)", - "y = (1-a0)*cos(x*a1)*exp(-(x/a2)^a3) + a0*exp(-(x/a4)^a5)" -}; +static const char* longs_ffn[effnNR] + = { "no fit", + "y = exp(-x/|a0|)", + "y = a1 exp(-x/|a0|)", + "y = a1 exp(-x/|a0|) + (1-a1) exp(-x/(|a2|)), a2 > a0 > 0", + "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4, a3 >= a1", + "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4 exp(-x/|a5|) + a6, a5 >= a3 >= a1", + "y = a0 exp(-x/|a1|) + a2 exp(-x/|a3|) + a4 exp(-x/|a5|) + a6 exp(-x/|a7|) + a8, a7 >= a5 >= a3 >= a1", + "y = exp(-v) (cosh(wv) + 1/w sinh(wv)), v = x/(2 a0), w = sqrt(1 - a1)", + "y = 1/2*(a0+a1) - 1/2*(a0-a1)*erf( (x-a2) /a3^2)", + "y = a1 *2*a0*((exp(-x/a0)-1)*(a0/x)+1)+(1-a1)*2*a2*((exp(-x/a2)-1)*(a2/x)+1)", + "y = (1-a0)*cos(x*a1)*exp(-(x/a2)^a3) + a0*exp(-(x/a4)^a5)" }; +// clang-format on int effnNparams(int effn) { @@ -102,7 +101,7 @@ int effnNparams(int effn) } } -const char *effnDescription(int effn) +const char* effnDescription(int effn) { if ((0 <= effn) && (effn < effnNR)) { @@ -114,14 +113,14 @@ const char *effnDescription(int effn) } } -int sffn2effn(const char **sffn) +int sffn2effn(const char** sffn) { int eFitFn, i; eFitFn = 0; for (i = 0; i < effnNR; i++) { - if (sffn[i+1] && strcmp(sffn[0], sffn[i+1]) == 0) + if (sffn[i + 1] && strcmp(sffn[0], sffn[i + 1]) == 0) { eFitFn = i; } @@ -137,18 +136,18 @@ static double myexp(double x, double A, double tau) { return 0; } - return A*exp(-x/tau); + return A * exp(-x / tau); } /*! \brief Compute y=(a0+a1)/2-(a0-a1)/2*erf((x-a2)/a3^2) */ -static double lmc_erffit (double x, const double *a) +static double lmc_erffit(double x, const double* a) { double erfarg; double myerf; if (a[3] != 0) { - erfarg = (x-a[2])/(a[3]*a[3]); + erfarg = (x - a[2]) / (a[3] * a[3]); myerf = std::erf(erfarg); } else @@ -163,7 +162,7 @@ static double lmc_erffit (double x, const double *a) myerf = 1; } } - return 0.5*((a[0]+a[1]) - (a[0]-a[1])*myerf); + return 0.5 * ((a[0] + a[1]) - (a[0] - a[1]) * myerf); } /*! \brief Exponent function that prevents overflow */ @@ -205,35 +204,35 @@ static double safe_expm1(double x) } /*! \brief Compute y = exp(-x/|a0|) */ -static double lmc_exp_one_parm(double x, const double *a) +static double lmc_exp_one_parm(double x, const double* a) { - return safe_exp(-x/fabs(a[0])); + return safe_exp(-x / fabs(a[0])); } /*! \brief Compute y = a1 exp(-x/|a0|) */ -static double lmc_exp_two_parm(double x, const double *a) +static double lmc_exp_two_parm(double x, const double* a) { - return a[1]*safe_exp(-x/fabs(a[0])); + return a[1] * safe_exp(-x / fabs(a[0])); } /*! \brief Compute y = a1 exp(-x/|a0|) + (1-a1) exp(-x/|a2|) */ -static double lmc_exp_exp(double x, const double *a) +static double lmc_exp_exp(double x, const double* a) { double e1, e2; - e1 = safe_exp(-x/fabs(a[0])); - e2 = safe_exp(-x/(fabs(a[0])+fabs(a[2]))); - return a[1]*e1 + (1-a[1])*e2; + e1 = safe_exp(-x / fabs(a[0])); + e2 = safe_exp(-x / (fabs(a[0]) + fabs(a[2]))); + return a[1] * e1 + (1 - a[1]) * e2; } /*! \brief Compute y = a0 exp(-x/|a1|) + a2 exp(-x/(|a1|+|a3|)) + a4 */ -static double lmc_exp_5_parm(double x, const double *a) +static double lmc_exp_5_parm(double x, const double* a) { double e1, e2; - e1 = safe_exp(-x/fabs(a[1])); - e2 = safe_exp(-x/(fabs(a[1])+fabs(a[3]))); - return a[0]*e1 + a[2]*e2 + a[4]; + e1 = safe_exp(-x / fabs(a[1])); + e2 = safe_exp(-x / (fabs(a[1]) + fabs(a[3]))); + return a[0] * e1 + a[2] * e2 + a[4]; } /*! \brief Compute 7 parameter exponential function value. @@ -241,7 +240,7 @@ static double lmc_exp_5_parm(double x, const double *a) * Compute y = a0 exp(-x/|a1|) + a2 exp(-x/(|a1|+|a3|)) + * a4 exp(-x/(|a1|+|a3|+|a5|)) + a6 */ -static double lmc_exp_7_parm(double x, const double *a) +static double lmc_exp_7_parm(double x, const double* a) { double e1, e2, e3; double fa1, fa3, fa5; @@ -249,10 +248,10 @@ static double lmc_exp_7_parm(double x, const double *a) fa1 = fabs(a[1]); fa3 = fa1 + fabs(a[3]); fa5 = fa3 + fabs(a[5]); - e1 = safe_exp(-x/fa1); - e2 = safe_exp(-x/fa3); - e3 = safe_exp(-x/fa5); - return a[0]*e1 + a[2]*e2 + a[4]*e3 + a[6]; + e1 = safe_exp(-x / fa1); + e2 = safe_exp(-x / fa3); + e3 = safe_exp(-x / fa5); + return a[0] * e1 + a[2] * e2 + a[4] * e3 + a[6]; } /*! \brief Compute 9 parameter exponential function value. @@ -260,7 +259,7 @@ static double lmc_exp_7_parm(double x, const double *a) * Compute y = a0 exp(-x/|a1|) + a2 exp(-x/(|a1|+|a3|)) + * a4 exp(-x/(|a1|+|a3|+|a5|)) + a6 exp(-x/(|a1|+|a3|+|a5|+|a7|)) + a8 */ -static double lmc_exp_9_parm(double x, const double *a) +static double lmc_exp_9_parm(double x, const double* a) { double e1, e2, e3, e4; double fa1, fa3, fa5, fa7; @@ -270,39 +269,39 @@ static double lmc_exp_9_parm(double x, const double *a) fa5 = fa3 + fabs(a[5]); fa7 = fa5 + fabs(a[7]); - e1 = safe_exp(-x/fa1); - e2 = safe_exp(-x/fa3); - e3 = safe_exp(-x/fa5); - e4 = safe_exp(-x/fa7); - return a[0]*e1 + a[2]*e2 + a[4]*e3 + a[6]*e4 + a[8]; + e1 = safe_exp(-x / fa1); + e2 = safe_exp(-x / fa3); + e3 = safe_exp(-x / fa5); + e4 = safe_exp(-x / fa7); + return a[0] * e1 + a[2] * e2 + a[4] * e3 + a[6] * e4 + a[8]; } /*! \brief Compute y = (1-a0)*exp(-(x/|a2|)^|a3|)*cos(x*|a1|) + a0*exp(-(x/|a4|)^|a5|) */ -static double lmc_pres_6_parm(double x, const double *a) +static double lmc_pres_6_parm(double x, const double* a) { double term1, term2, term3; double pow_max = 10; - term3 = 0; + term3 = 0; if ((a[4] != 0) && (a[0] != 0)) { double power = std::min(fabs(a[5]), pow_max); - term3 = a[0] * safe_exp(-pow((x/fabs(a[4])), power)); + term3 = a[0] * safe_exp(-pow((x / fabs(a[4])), power)); } - term1 = 1-a[0]; - term2 = 0; + term1 = 1 - a[0]; + term2 = 0; if ((term1 != 0) && (a[2] != 0)) { double power = std::min(fabs(a[3]), pow_max); - term2 = safe_exp(-pow((x/fabs(a[2])), power)) * cos(x*fabs(a[1])); + term2 = safe_exp(-pow((x / fabs(a[2])), power)) * cos(x * fabs(a[1])); } - return term1*term2 + term3; + return term1 * term2 + term3; } /*! \brief Compute vac function */ -static double lmc_vac_2_parm(double x, const double *a) +static double lmc_vac_2_parm(double x, const double* a) { /* Fit to function * @@ -322,44 +321,44 @@ static double lmc_vac_2_parm(double x, const double *a) double y, v, det, omega, wv, em, ec, es; double wv_max = 100; - v = x/(2*fabs(a[0])); + v = x / (2 * fabs(a[0])); det = 1 - a[1]; em = safe_exp(-v); if (det != 0) { omega = sqrt(fabs(det)); - wv = std::min(omega*v, wv_max); + wv = std::min(omega * v, wv_max); if (det > 0) { - ec = em*0.5*(safe_exp(wv)+safe_exp(-wv)); - es = em*0.5*(safe_exp(wv)-safe_exp(-wv))/omega; + ec = em * 0.5 * (safe_exp(wv) + safe_exp(-wv)); + es = em * 0.5 * (safe_exp(wv) - safe_exp(-wv)) / omega; } else { - ec = em*cos(wv); - es = em*sin(wv)/omega; + ec = em * cos(wv); + es = em * sin(wv) / omega; } - y = ec + es; + y = ec + es; } else { - y = (1+v)*em; + y = (1 + v) * em; } return y; } /*! \brief Compute error estimate */ -static double lmc_errest_3_parm(double x, const double *a) +static double lmc_errest_3_parm(double x, const double* a) { double e1, e2, v1, v2; double fa0 = fabs(a[0]); double fa1; - double fa2 = fa0+fabs(a[2]); + double fa2 = fa0 + fabs(a[2]); if (a[0] != 0) { - e1 = safe_expm1(-x/fa0); + e1 = safe_expm1(-x / fa0); } else { @@ -367,7 +366,7 @@ static double lmc_errest_3_parm(double x, const double *a) } if (a[2] != 0) { - e2 = safe_expm1(-x/fa2); + e2 = safe_expm1(-x / fa2); } else { @@ -376,12 +375,12 @@ static double lmc_errest_3_parm(double x, const double *a) if (x > 0) { - v1 = 2*fa0*(e1*fa0/x + 1); - v2 = 2*fa2*(e2*fa2/x + 1); + v1 = 2 * fa0 * (e1 * fa0 / x + 1); + v2 = 2 * fa2 * (e2 * fa2 / x + 1); /* We need 0 <= a1 <= 1 */ - fa1 = std::min(1.0, std::max(0.0, a[1])); + fa1 = std::min(1.0, std::max(0.0, a[1])); - return fa1*v1 + (1-fa1)*v2; + return fa1 * v1 + (1 - fa1) * v2; } else { @@ -390,19 +389,16 @@ static double lmc_errest_3_parm(double x, const double *a) } /*! \brief array of fitting functions corresponding to the pre-defined types */ -t_lmcurve lmcurves[effnNR+1] = { - lmc_exp_one_parm, lmc_exp_one_parm, lmc_exp_two_parm, - lmc_exp_exp, lmc_exp_5_parm, lmc_exp_7_parm, - lmc_exp_9_parm, - lmc_vac_2_parm, lmc_erffit, lmc_errest_3_parm, lmc_pres_6_parm -}; +t_lmcurve lmcurves[effnNR + 1] = { lmc_exp_one_parm, lmc_exp_one_parm, lmc_exp_two_parm, + lmc_exp_exp, lmc_exp_5_parm, lmc_exp_7_parm, + lmc_exp_9_parm, lmc_vac_2_parm, lmc_erffit, + lmc_errest_3_parm, lmc_pres_6_parm }; double fit_function(const int eFitFn, const double parm[], const double x) { if ((eFitFn < 0) || (eFitFn >= effnNR)) { - fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", - eFitFn, effnNR-1); + fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", eFitFn, effnNR - 1); return 0.0; } return lmcurves[eFitFn](x, parm); @@ -420,8 +416,7 @@ double fit_function(const int eFitFn, const double parm[], const double x) * previous ones and during fitting we enforce the they remain larger. * It may very well help the convergence of the fitting routine. */ -static void initiate_fit_params(int eFitFn, - double params[]) +static void initiate_fit_params(int eFitFn, double params[]) { int i, nparm; @@ -429,9 +424,7 @@ static void initiate_fit_params(int eFitFn, switch (eFitFn) { - case effnVAC: - GMX_ASSERT(params[0] >= 0, "parameters should be >= 0"); - break; + case effnVAC: GMX_ASSERT(params[0] >= 0, "parameters should be >= 0"); break; case effnEXP1: case effnEXP2: case effnEXPEXP: @@ -444,7 +437,7 @@ static void initiate_fit_params(int eFitFn, * params[2]-params[0] and in the add add in params[0] * again. */ - params[2] = std::max(fabs(params[2])-params[0], params[0]); + params[2] = std::max(fabs(params[2]) - params[0], params[0]); } break; case effnEXP5: @@ -456,17 +449,17 @@ static void initiate_fit_params(int eFitFn, { GMX_ASSERT(params[3] >= 0, "parameters should be >= 0"); /* See comment under effnEXPEXP */ - params[3] = std::max(fabs(params[3])-params[1], params[1]); + params[3] = std::max(fabs(params[3]) - params[1], params[1]); if (nparm > 5) { GMX_ASSERT(params[5] >= 0, "parameters should be >= 0"); /* See comment under effnEXPEXP */ - params[5] = std::max(fabs(params[5])-params[3], params[3]); + params[5] = std::max(fabs(params[5]) - params[3], params[3]); if (nparm > 7) { GMX_ASSERT(params[7] >= 0, "parameters should be >= 0"); /* See comment under effnEXPEXP */ - params[7] = std::max(fabs(params[7])-params[5], params[5]); + params[7] = std::max(fabs(params[7]) - params[5], params[5]); } } } @@ -476,7 +469,7 @@ static void initiate_fit_params(int eFitFn, GMX_ASSERT(params[1] >= 0 && params[1] <= 1, "parameter 1 should in 0 .. 1"); GMX_ASSERT(params[2] >= 0, "parameters should be >= 0"); /* See comment under effnEXPEXP */ - params[2] = fabs(params[2])-params[0]; + params[2] = fabs(params[2]) - params[0]; break; case effnPRES: for (i = 1; (i < nparm); i++) @@ -484,8 +477,7 @@ static void initiate_fit_params(int eFitFn, GMX_ASSERT(params[i] >= 0, "parameters should be >= 0"); } break; - default: - break; + default: break; } } @@ -493,8 +485,7 @@ static void initiate_fit_params(int eFitFn, * * See comment at the previous function. */ -static void extract_fit_params(int eFitFn, - double params[]) +static void extract_fit_params(int eFitFn, double params[]) { int i, nparm; @@ -502,9 +493,7 @@ static void extract_fit_params(int eFitFn, switch (eFitFn) { - case effnVAC: - params[0] = fabs(params[0]); - break; + case effnVAC: params[0] = fabs(params[0]); break; case effnEXP1: case effnEXP2: case effnEXPEXP: @@ -514,7 +503,7 @@ static void extract_fit_params(int eFitFn, /* Back conversion of parameters from the fitted difference * to the absolute value. */ - params[2] = fabs(params[2])+params[0]; + params[2] = fabs(params[2]) + params[0]; } break; case effnEXP5: @@ -524,15 +513,15 @@ static void extract_fit_params(int eFitFn, if (nparm > 3) { /* See comment under effnEXPEXP */ - params[3] = fabs(params[3])+params[1]; + params[3] = fabs(params[3]) + params[1]; if (nparm > 5) { /* See comment under effnEXPEXP */ - params[5] = fabs(params[5])+params[3]; + params[5] = fabs(params[5]) + params[3]; if (nparm > 7) { /* See comment under effnEXPEXP */ - params[7] = fabs(params[7])+params[5]; + params[7] = fabs(params[7]) + params[5]; } } } @@ -548,7 +537,7 @@ static void extract_fit_params(int eFitFn, params[1] = 1; } /* See comment under effnEXPEXP */ - params[2] = params[0]+fabs(params[2]); + params[2] = params[0] + fabs(params[2]); break; case effnPRES: for (i = 1; (i < nparm); i++) @@ -556,16 +545,15 @@ static void extract_fit_params(int eFitFn, params[i] = fabs(params[i]); } break; - default: - break; + default: break; } } /*! \brief Print chi-squared value and the parameters */ -static void print_chi2_params(FILE *fp, +static void print_chi2_params(FILE* fp, const int eFitFn, const double fitparms[], - const char *label, + const char* label, const int nfitpnts, const double x[], const double y[]) @@ -578,8 +566,8 @@ static void print_chi2_params(FILE *fp, double yfit = lmcurves[eFitFn](x[i], fitparms); chi2 += gmx::square(y[i] - yfit); } - fprintf(fp, "There are %d data points, %d parameters, %s chi2 = %g\nparams:", - nfitpnts, effnNparams(eFitFn), label, chi2); + fprintf(fp, "There are %d data points, %d parameters, %s chi2 = %g\nparams:", nfitpnts, + effnNparams(eFitFn), label, chi2); for (i = 0; (i < effnNparams(eFitFn)); i++) { fprintf(fp, " %10g", fitparms[i]); @@ -587,15 +575,24 @@ static void print_chi2_params(FILE *fp, fprintf(fp, "\n"); } -real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, - real begintimefit, real endtimefit, const gmx_output_env_t *oenv, - gmx_bool bVerbose, int eFitFn, double fitparms[], int fix, - const char *fn_fitted) +real do_lmfit(int ndata, + const real c1[], + real sig[], + real dt, + const real* x0, + real begintimefit, + real endtimefit, + const gmx_output_env_t* oenv, + gmx_bool bVerbose, + int eFitFn, + double fitparms[], + int fix, + const char* fn_fitted) { - FILE *fp; - int i, j, nfitpnts; - double integral, ttt; - double *x, *y, *dy; + FILE* fp; + int i, j, nfitpnts; + double integral, ttt; + double *x, *y, *dy; if (0 != fix) { @@ -604,21 +601,21 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, if (debug) { fprintf(debug, "There are %d points to fit %d vars!\n", ndata, effnNparams(eFitFn)); - fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", - eFitFn, begintimefit, endtimefit, dt); + fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, + endtimefit, dt); } snew(x, ndata); snew(y, ndata); snew(dy, ndata); - j = 0; + j = 0; for (i = 0; i < ndata; i++) { - ttt = x0 ? x0[i] : dt*i; + ttt = x0 ? x0[i] : dt * i; if (ttt >= begintimefit && ttt <= endtimefit) { - x[j] = ttt; - y[j] = c1[i]; + x[j] = ttt; + y[j] = c1[i]; if (nullptr == sig) { // No weighting if all values are divided by 1. @@ -630,8 +627,7 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, } if (debug) { - fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy=%g, ttt=%g\n", - j, i, x[j], y[j], dy[j], ttt); + fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy=%g, ttt=%g\n", j, i, x[j], y[j], dy[j], ttt); } j++; } @@ -640,8 +636,7 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, integral = 0; if (nfitpnts < effnNparams(eFitFn)) { - fprintf(stderr, "Not enough (%d) data points for fitting, dt = %g!\n", - nfitpnts, dt); + fprintf(stderr, "Not enough (%d) data points for fitting, dt = %g!\n", nfitpnts, dt); } else { @@ -668,33 +663,32 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, } switch (eFitFn) { - case effnEXP1: - integral = fitparms[0]*myexp(begintimefit, 1, fitparms[0]); - break; + case effnEXP1: integral = fitparms[0] * myexp(begintimefit, 1, fitparms[0]); break; case effnEXP2: - integral = fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]); + integral = fitparms[0] * myexp(begintimefit, fitparms[1], fitparms[0]); break; case effnEXPEXP: - integral = (fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]) + - fitparms[2]*myexp(begintimefit, 1-fitparms[1], fitparms[2])); + integral = (fitparms[0] * myexp(begintimefit, fitparms[1], fitparms[0]) + + fitparms[2] * myexp(begintimefit, 1 - fitparms[1], fitparms[2])); break; case effnEXP5: case effnEXP7: case effnEXP9: integral = 0; - for (i = 0; (i < (effnNparams(eFitFn)-1)/2); i++) + for (i = 0; (i < (effnNparams(eFitFn) - 1) / 2); i++) { - integral += fitparms[2*i]*myexp(begintimefit, fitparms[2*i+1], fitparms[2*i]); + integral += fitparms[2 * i] + * myexp(begintimefit, fitparms[2 * i + 1], fitparms[2 * i]); } break; default: /* Do numerical integration */ integral = 0; - for (i = 0; (i < nfitpnts-1); i++) + for (i = 0; (i < nfitpnts - 1); i++) { double y0 = lmcurves[eFitFn](x[i], fitparms); - double y1 = lmcurves[eFitFn](x[i+1], fitparms); - integral += (x[i+1]-x[i])*(y1+y0)*0.5; + double y1 = lmcurves[eFitFn](x[i + 1], fitparms); + integral += (x[i + 1] - x[i]) * (y1 + y0) * 0.5; } break; } @@ -704,23 +698,22 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, printf("FIT: Integral of fitted function: %g\n", integral); if ((effnEXP5 == eFitFn) || (effnEXP7 == eFitFn) || (effnEXP9 == eFitFn)) { - printf("FIT: Note that the constant term is not taken into account when computing integral.\n"); + printf("FIT: Note that the constant term is not taken into account when " + "computing integral.\n"); } } /* Generate debug output */ if (nullptr != fn_fitted) { - fp = xvgropen(fn_fitted, "Data + Fit", "Time (ps)", - "Data (t)", oenv); + fp = xvgropen(fn_fitted, "Data + Fit", "Time (ps)", "Data (t)", oenv); for (i = 0; (i < effnNparams(eFitFn)); i++) { fprintf(fp, "# fitparms[%d] = %g\n", i, fitparms[i]); } for (j = 0; (j < nfitpnts); j++) { - real ttt = x0 ? x0[j] : dt*j; - fprintf(fp, "%10.5e %10.5e %10.5e\n", - x[j], y[j], (lmcurves[eFitFn])(ttt, fitparms)); + real ttt = x0 ? x0[j] : dt * j; + fprintf(fp, "%10.5e %10.5e %10.5e\n", x[j], y[j], (lmcurves[eFitFn])(ttt, fitparms)); } xvgrclose(fp); } @@ -734,16 +727,23 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, return integral; } -real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbose, - real tbeginfit, real tendfit, real dt, real c1[], real *fit) +real fit_acf(int ncorr, + int fitfn, + const gmx_output_env_t* oenv, + gmx_bool bVerbose, + real tbeginfit, + real tendfit, + real dt, + real c1[], + real* fit) { - double fitparm[3]; - double tStart, tail_corr, sum, sumtot = 0, c_start, ct_estimate; - real *sig; - int i, j, jmax, nf_int; - gmx_bool bPrint; + double fitparm[3]; + double tStart, tail_corr, sum, sumtot = 0, c_start, ct_estimate; + real* sig; + int i, j, jmax, nf_int; + gmx_bool bPrint; - GMX_ASSERT(effnNparams(fitfn) < static_cast(sizeof(fitparm)/sizeof(double)), + GMX_ASSERT(effnNparams(fitfn) < static_cast(sizeof(fitparm) / sizeof(double)), "Fitting function with more than 3 parameters not supported!"); bPrint = bVerbose || bDebugMode(); @@ -754,26 +754,26 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo if (tendfit <= 0) { - tendfit = ncorr*dt; + tendfit = ncorr * dt; } - nf_int = std::min(ncorr, static_cast(tendfit/dt)); + nf_int = std::min(ncorr, static_cast(tendfit / dt)); sum = print_and_integrate(debug, nf_int, dt, c1, nullptr, 1); if (bPrint) { - printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n", - 0.0, dt*nf_int, sum); + printf("COR: Correlation time (plain integral from %6.3f to %6.3f ps) = %8.5f ps\n", 0.0, + dt * nf_int, sum); printf("COR: Relaxation times are computed as fit to an exponential:\n"); printf("COR: %s\n", effnDescription(fitfn)); - printf("COR: Fit to correlation function from %6.3f ps to %6.3f ps, results in a\n", tbeginfit, std::min(ncorr*dt, tendfit)); + printf("COR: Fit to correlation function from %6.3f ps to %6.3f ps, results in a\n", + tbeginfit, std::min(ncorr * dt, tendfit)); } tStart = 0; if (bPrint) { - printf("COR:%11s%11s%11s%11s%11s%11s%11s\n", - "Fit from", "Integral", "Tail Value", "Sum (ps)", " a1 (ps)", - (effnNparams(fitfn) >= 2) ? " a2 ()" : "", + printf("COR:%11s%11s%11s%11s%11s%11s%11s\n", "Fit from", "Integral", "Tail Value", + "Sum (ps)", " a1 (ps)", (effnNparams(fitfn) >= 2) ? " a2 ()" : "", (effnNparams(fitfn) >= 3) ? " a3 (ps)" : ""); } @@ -787,19 +787,19 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo { jmax = 1; } - for (j = 0; ((j < jmax) && (tStart < tendfit) && (tStart < ncorr*dt)); j++) + for (j = 0; ((j < jmax) && (tStart < tendfit) && (tStart < ncorr * dt)); j++) { /* Estimate the correlation time for better fitting */ c_start = -1; ct_estimate = 0; - for (i = 0; (i < ncorr) && (dt*i < tStart || c1[i] > 0); i++) + for (i = 0; (i < ncorr) && (dt * i < tStart || c1[i] > 0); i++) { if (c_start < 0) { - if (dt*i >= tStart) + if (dt * i >= tStart) { c_start = c1[i]; - ct_estimate = 0.5*c1[i]; + ct_estimate = 0.5 * c1[i]; } } else @@ -809,7 +809,7 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo } if (c_start > 0) { - ct_estimate *= dt/c_start; + ct_estimate *= dt / c_start; } else { @@ -823,9 +823,9 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo if (fitfn == effnEXPEXP) { - fitparm[0] = 0.002*ncorr*dt; + fitparm[0] = 0.002 * ncorr * dt; fitparm[1] = 0.95; - fitparm[2] = 0.2*ncorr*dt; + fitparm[2] = 0.2 * ncorr * dt; } else { @@ -838,14 +838,14 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo /* Generate more or less appropriate sigma's */ for (i = 0; i < ncorr; i++) { - sig[i] = sqrt(ct_estimate+dt*i); + sig[i] = sqrt(ct_estimate + dt * i); } - nf_int = std::min(ncorr, static_cast((tStart+1e-4)/dt)); + nf_int = std::min(ncorr, static_cast((tStart + 1e-4) / dt)); sum = print_and_integrate(debug, nf_int, dt, c1, nullptr, 1); - tail_corr = do_lmfit(ncorr, c1, sig, dt, nullptr, tStart, tendfit, oenv, - bDebugMode(), fitfn, fitparm, 0, nullptr); - sumtot = sum+tail_corr; + tail_corr = do_lmfit(ncorr, c1, sig, dt, nullptr, tStart, tendfit, oenv, bDebugMode(), + fitfn, fitparm, 0, nullptr); + sumtot = sum + tail_corr; if (fit && ((jmax == 1) || (j == 1))) { double mfp[3]; @@ -855,7 +855,7 @@ real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbo } for (i = 0; (i < ncorr); i++) { - fit[i] = lmcurves[fitfn](i*dt, mfp); + fit[i] = lmcurves[fitfn](i * dt, mfp); } } if (bPrint) diff --git a/src/gromacs/correlationfunctions/expfit.h b/src/gromacs/correlationfunctions/expfit.h index 3da32835fe..d006d55632 100644 --- a/src/gromacs/correlationfunctions/expfit.h +++ b/src/gromacs/correlationfunctions/expfit.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,20 @@ struct gmx_output_env_t; /*! \brief * Enum to select fitting functions */ -enum { - effnNONE, effnEXP1, effnEXP2, effnEXPEXP, - effnEXP5, effnEXP7, effnEXP9, - effnVAC, effnERF, effnERREST, effnPRES, effnNR +enum +{ + effnNONE, + effnEXP1, + effnEXP2, + effnEXPEXP, + effnEXP5, + effnEXP7, + effnEXP9, + effnVAC, + effnERF, + effnERREST, + effnPRES, + effnNR }; /*! \brief @@ -63,14 +73,14 @@ enum { * This is exported for now in order to use when * calling parse_common_args. */ -extern const char *s_ffn[effnNR+2]; +extern const char* s_ffn[effnNR + 2]; /*! \brief * Returns description corresponding to the enum above, or NULL if out of range * \param[in] effn Index * \return Description or NULL */ -const char *effnDescription(int effn); +const char* effnDescription(int effn); /*! \brief * Returns number of function parameters associated with a fitting function. @@ -84,7 +94,7 @@ int effnNparams(int effn); * \param[in] sffn Two dimensional string array coming from parse_common_args * \return the ffn enum */ -int sffn2effn(const char **sffn); +int sffn2effn(const char** sffn); /*! \brief * Returns the value of fit function eFitFn at x @@ -122,10 +132,19 @@ double fit_function(int eFitFn, const double parm[], double x); * \param[in] fn_fitted If not NULL file to print the data and fitted curve to * \return integral. */ -real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, - real begintimefit, real endtimefit, const gmx_output_env_t *oenv, - gmx_bool bVerbose, int eFitFn, double fitparms[], int fix, - const char *fn_fitted); +real do_lmfit(int ndata, + const real c1[], + real sig[], + real dt, + const real* x0, + real begintimefit, + real endtimefit, + const gmx_output_env_t* oenv, + gmx_bool bVerbose, + int eFitFn, + double fitparms[], + int fix, + const char* fn_fitted); /*! \brief * Fit an autocorrelation function to a pre-defined functional form @@ -142,7 +161,14 @@ real do_lmfit(int ndata, const real c1[], real sig[], real dt, const real *x0, * \param[inout] fit The fitting parameters * \return the integral over the autocorrelation function? */ -real fit_acf(int ncorr, int fitfn, const gmx_output_env_t *oenv, gmx_bool bVerbose, - real tbeginfit, real tendfit, real dt, real c1[], real *fit); +real fit_acf(int ncorr, + int fitfn, + const gmx_output_env_t* oenv, + gmx_bool bVerbose, + real tbeginfit, + real tendfit, + real dt, + real c1[], + real* fit); #endif diff --git a/src/gromacs/correlationfunctions/gmx_lmcurve.cpp b/src/gromacs/correlationfunctions/gmx_lmcurve.cpp index 256eb5918c..f31daf4f8b 100644 --- a/src/gromacs/correlationfunctions/gmx_lmcurve.cpp +++ b/src/gromacs/correlationfunctions/gmx_lmcurve.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,8 +50,8 @@ #include #if HAVE_LMFIT -#include -#include +# include +# include #endif #include "gromacs/correlationfunctions/expfit.h" @@ -61,7 +61,8 @@ #if HAVE_LMFIT -typedef struct { +typedef struct +{ const double* t; const double* y; const double* dy; @@ -69,9 +70,7 @@ typedef struct { } lmcurve_data_struct; //! Callback function used by lmmin -static void lmcurve_evaluate( - const double* par, const int m_dat, const void* data, double* fvec, - int* info) +static void lmcurve_evaluate(const double* par, const int m_dat, const void* data, double* fvec, int* info) { const lmcurve_data_struct* D = reinterpret_cast(data); for (int i = 0; i < m_dat; i++) @@ -81,22 +80,25 @@ static void lmcurve_evaluate( { dy = 1; } - fvec[i] = (D->y[i] - D->f(D->t[i], par))/dy; + fvec[i] = (D->y[i] - D->f(D->t[i], par)) / dy; } *info = 0; } //! Calls lmmin with the given data, with callback function \c f. -static void gmx_lmcurve( - const int n_par, double* par, const int m_dat, - const double* t, const double* y, const double *dy, - double (*f)(double t, const double* par), - const lm_control_struct* control, lm_status_struct* status) +static void gmx_lmcurve(const int n_par, + double* par, + const int m_dat, + const double* t, + const double* y, + const double* dy, + double (*f)(double t, const double* par), + const lm_control_struct* control, + lm_status_struct* status) { lmcurve_data_struct data = { t, y, dy, f }; - lmmin(n_par, par, m_dat, nullptr, &data, lmcurve_evaluate, - control, status); + lmmin(n_par, par, m_dat, nullptr, &data, lmcurve_evaluate, control, status); } #endif @@ -112,33 +114,32 @@ bool lmfit_exp(int nfit, { if ((eFitFn < 0) || (eFitFn >= effnNR)) { - fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", - eFitFn, effnNR-1); + fprintf(stderr, "fitfn = %d, should be in the range 0..%d\n", eFitFn, effnNR - 1); return false; } #if HAVE_LMFIT - double chisq, ochisq; - gmx_bool bCont; - int j; - int maxiter = 100; - lm_control_struct control; - lm_status_struct *status; - int nparam = effnNparams(eFitFn); - int p2; - gmx_bool bSkipLast; + double chisq, ochisq; + gmx_bool bCont; + int j; + int maxiter = 100; + lm_control_struct control; + lm_status_struct* status; + int nparam = effnNparams(eFitFn); + int p2; + gmx_bool bSkipLast; /* Using default control structure for double precision fitting that * comes with the lmfit package (i.e. from the include file). */ - control = lm_control_double; - control.verbosity = (bVerbose ? 1 : 0); - control.n_maxpri = 0; - control.m_maxpri = 0; + control = lm_control_double; + control.verbosity = (bVerbose ? 1 : 0); + control.n_maxpri = 0; + control.m_maxpri = 0; snew(status, 1); /* Initial params */ - chisq = 1e12; - j = 0; + chisq = 1e12; + j = 0; if (bVerbose) { printf("%4s %10s Parameters\n", "Step", "chi^2"); @@ -148,15 +149,14 @@ bool lmfit_exp(int nfit, { do { - p2 = 1 << (nparam-1); + p2 = 1 << (nparam - 1); bSkipLast = ((p2 & nfix) == p2); if (bSkipLast) { nparam--; nfix -= p2; } - } - while ((nparam > 0) && (bSkipLast)); + } while ((nparam > 0) && (bSkipLast)); if (bVerbose) { printf("Using %d out of %d parameters\n", nparam, effnNparams(eFitFn)); @@ -165,14 +165,12 @@ bool lmfit_exp(int nfit, do { ochisq = chisq; - gmx_lmcurve(nparam, parm, nfit, x, y, dy, - lmcurves[eFitFn], &control, status); + gmx_lmcurve(nparam, parm, nfit, x, y, dy, lmcurves[eFitFn], &control, status); chisq = gmx::square(status->fnorm); if (bVerbose) { - printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n", - status->fnorm, status->nfev, status->userbreak, - lm_infmsg[status->outcome]); + printf("status: fnorm = %g, nfev = %d, userbreak = %d\noutcome = %s\n", status->fnorm, + status->nfev, status->userbreak, lm_infmsg[status->outcome]); } if (bVerbose) { @@ -185,13 +183,13 @@ bool lmfit_exp(int nfit, printf("\n"); } j++; - bCont = (fabs(ochisq - chisq) > fabs(control.ftol*chisq)); - } - while (bCont && (j < maxiter)); + bCont = (fabs(ochisq - chisq) > fabs(control.ftol * chisq)); + } while (bCont && (j < maxiter)); sfree(status); #else - gmx_fatal(FARGS, "This build of GROMACS was not configured with support " + gmx_fatal(FARGS, + "This build of GROMACS was not configured with support " "for lmfit, so the requested fitting cannot be performed. " "See the install guide for instructions on how to build " "GROMACS with lmfit supported."); diff --git a/src/gromacs/correlationfunctions/gmx_lmcurve.h b/src/gromacs/correlationfunctions/gmx_lmcurve.h index 4d9f71d50a..473eba167c 100644 --- a/src/gromacs/correlationfunctions/gmx_lmcurve.h +++ b/src/gromacs/correlationfunctions/gmx_lmcurve.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,12 +42,9 @@ */ #ifndef GMX_CORRELATION_FUNCTIONS_GMX_LMCURVE_H #define GMX_CORRELATION_FUNCTIONS_GMX_LMCURVE_H - #include "gromacs/correlationfunctions/expfit.h" - /*! \brief function type for passing to fitting routine */ -typedef double (*t_lmcurve)(double x, const double *a); - +typedef double (*t_lmcurve)(double x, const double* a); /*! \brief lmfit_exp supports fitting of different functions * * This routine calls the Levenberg-Marquardt non-linear fitting @@ -63,6 +60,6 @@ bool lmfit_exp(int nfit, int eFitFn, int nfix); -extern t_lmcurve lmcurves[effnNR+1]; +extern t_lmcurve lmcurves[effnNR + 1]; #endif diff --git a/src/gromacs/correlationfunctions/integrate.cpp b/src/gromacs/correlationfunctions/integrate.cpp index 1180469ea9..840f816675 100644 --- a/src/gromacs/correlationfunctions/integrate.cpp +++ b/src/gromacs/correlationfunctions/integrate.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,8 +51,7 @@ #include "gromacs/utility/fatalerror.h" /*! \brief Integrate a function and printe the integral value. */ -real print_and_integrate(FILE *fp, int n, real dt, const real c[], - const real *fit, int nskip) +real print_and_integrate(FILE* fp, int n, real dt, const real c[], const real* fit, int nskip) { real c0, sum; int j; @@ -64,11 +63,11 @@ real print_and_integrate(FILE *fp, int n, real dt, const real c[], c0 = c[j]; if (fp && (nskip == 0 || j % nskip == 0)) { - fprintf(fp, "%10.3f %10.5f\n", j*dt, c0); + fprintf(fp, "%10.3f %10.5f\n", j * dt, c0); } if (j > 0) { - sum += dt*(c0+c[j-1]); + sum += dt * (c0 + c[j - 1]); } } if (fp) @@ -80,29 +79,26 @@ real print_and_integrate(FILE *fp, int n, real dt, const real c[], { if (nskip == 0 || j % nskip == 0) { - fprintf(fp, "%10.3f %10.5f\n", j*dt, fit[j]); + fprintf(fp, "%10.3f %10.5f\n", j * dt, fit[j]); } } fprintf(fp, "&\n"); } } - return sum*0.5; + return sum * 0.5; } /*! \brief Compute and return the integral of a function. */ -real evaluate_integral(int n, const real x[], const real y[], - const real dy[], real aver_start, - real *stddev) +real evaluate_integral(int n, const real x[], const real y[], const real dy[], real aver_start, real* stddev) { double sum, sum_var, w; double sum_tail = 0, sum2_tail = 0; - int j, nsum_tail = 0; + int j, nsum_tail = 0; /* Use trapezoidal rule for calculating integral */ if (n <= 0) { - gmx_fatal(FARGS, "Evaluating integral: n = %d (file %s, line %d)", - n, __FILE__, __LINE__); + gmx_fatal(FARGS, "Evaluating integral: n = %d (file %s, line %d)", n, __FILE__, __LINE__); } sum = 0; @@ -112,22 +108,22 @@ real evaluate_integral(int n, const real x[], const real y[], w = 0; if (j > 0) { - w += 0.5*(x[j] - x[j-1]); + w += 0.5 * (x[j] - x[j - 1]); } - if (j < n-1) + if (j < n - 1) { - w += 0.5*(x[j+1] - x[j]); + w += 0.5 * (x[j + 1] - x[j]); } - sum += w*y[j]; + sum += w * y[j]; if (dy) { /* Assume all errors are uncorrelated */ - sum_var += gmx::square(w*dy[j]); + sum_var += gmx::square(w * dy[j]); } if ((aver_start > 0) && (x[j] >= aver_start)) { - sum_tail += sum; + sum_tail += sum; sum2_tail += std::sqrt(sum_var); nsum_tail += 1; } @@ -135,9 +131,9 @@ real evaluate_integral(int n, const real x[], const real y[], if (nsum_tail > 0) { - sum = sum_tail/nsum_tail; + sum = sum_tail / nsum_tail; /* This is a worst case estimate, assuming all stddev's are correlated. */ - *stddev = sum2_tail/nsum_tail; + *stddev = sum2_tail / nsum_tail; } else { diff --git a/src/gromacs/correlationfunctions/integrate.h b/src/gromacs/correlationfunctions/integrate.h index 21e18a85c9..9e2ec82f23 100644 --- a/src/gromacs/correlationfunctions/integrate.h +++ b/src/gromacs/correlationfunctions/integrate.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +60,7 @@ * (written when i % nskip == 0) * \return The integral */ -real print_and_integrate(FILE *fp, int n, real dt, const real c[], const real *fit, int nskip); +real print_and_integrate(FILE* fp, int n, real dt, const real c[], const real* fit, int nskip); /*! \brief * Integrate data in y using the trapezium rule, and, if given, use dy as weighting @@ -74,7 +74,6 @@ real print_and_integrate(FILE *fp, int n, real dt, const real c[], const real *f * \param[out] stddev The standard deviation in the integral * \return the integral */ -real evaluate_integral(int n, const real x[], const real y[], const real dy[], real aver_start, - real *stddev); +real evaluate_integral(int n, const real x[], const real y[], const real dy[], real aver_start, real* stddev); #endif diff --git a/src/gromacs/correlationfunctions/manyautocorrelation.cpp b/src/gromacs/correlationfunctions/manyautocorrelation.cpp index 423351343e..c23d4c694e 100644 --- a/src/gromacs/correlationfunctions/manyautocorrelation.cpp +++ b/src/gromacs/correlationfunctions/manyautocorrelation.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,7 +49,7 @@ #include "gromacs/utility/exceptions.h" #include "gromacs/utility/gmxomp.h" -int many_auto_correl(std::vector > *c) +int many_auto_correl(std::vector>* c) { size_t nfunc = (*c).size(); if (nfunc == 0) @@ -68,60 +68,60 @@ int many_auto_correl(std::vector > *c) { char buf[256]; snprintf(buf, sizeof(buf), "Vectors of different lengths supplied (%d %d)", - static_cast((*c)[i].size()), - static_cast(ndata)); + static_cast((*c)[i].size()), static_cast(ndata)); GMX_THROW(gmx::InconsistentInputError(buf)); } } #endif // Add buffer size to the arrays. - size_t nfft = (3*ndata/2) + 1; + size_t nfft = (3 * ndata / 2) + 1; // Pad arrays with zeros - for (auto &i : *c) + for (auto& i : *c) { i.resize(nfft, 0); } - #pragma omp parallel +#pragma omp parallel { try { gmx_fft_t fft1; std::vector in, out; - int nthreads = gmx_omp_get_max_threads(); - int thread_id = gmx_omp_get_thread_num(); - int i0 = (thread_id*nfunc)/nthreads; - int i1 = std::min(nfunc, ((thread_id+1)*nfunc)/nthreads); + int nthreads = gmx_omp_get_max_threads(); + int thread_id = gmx_omp_get_thread_num(); + int i0 = (thread_id * nfunc) / nthreads; + int i1 = std::min(nfunc, ((thread_id + 1) * nfunc) / nthreads); gmx_fft_init_1d(&fft1, nfft, GMX_FFT_FLAG_CONSERVATIVE); /* Allocate temporary arrays */ - in.resize(2*nfft, 0); - out.resize(2*nfft, 0); + in.resize(2 * nfft, 0); + out.resize(2 * nfft, 0); for (int i = i0; (i < i1); i++) { for (size_t j = 0; j < ndata; j++) { - in[2*j+0] = (*c)[i][j]; - in[2*j+1] = 0; + in[2 * j + 0] = (*c)[i][j]; + in[2 * j + 1] = 0; } gmx_fft_1d(fft1, GMX_FFT_BACKWARD, in.data(), out.data()); for (size_t j = 0; j < nfft; j++) { - in[2*j+0] = (out[2*j+0]*out[2*j+0] + out[2*j+1]*out[2*j+1])/nfft; - in[2*j+1] = 0; + in[2 * j + 0] = + (out[2 * j + 0] * out[2 * j + 0] + out[2 * j + 1] * out[2 * j + 1]) / nfft; + in[2 * j + 1] = 0; } gmx_fft_1d(fft1, GMX_FFT_FORWARD, in.data(), out.data()); for (size_t j = 0; (j < nfft); j++) { - (*c)[i][j] = out[2*j+0]; + (*c)[i][j] = out[2 * j + 0]; } } /* Free the memory */ gmx_fft_destroy(fft1); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - for (auto &i : *c) + for (auto& i : *c) { i.resize(ndata); } diff --git a/src/gromacs/correlationfunctions/manyautocorrelation.h b/src/gromacs/correlationfunctions/manyautocorrelation.h index 63409bcef5..49f9796920 100644 --- a/src/gromacs/correlationfunctions/manyautocorrelation.h +++ b/src/gromacs/correlationfunctions/manyautocorrelation.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,6 +68,6 @@ * \return fft error code, or zero if everything went fine (see fft/fft.h) * \throws gmx::InconsistentInputError if the input is inconsistent. */ -int many_auto_correl(std::vector > *c); +int many_auto_correl(std::vector>* c); #endif diff --git a/src/gromacs/correlationfunctions/polynomials.cpp b/src/gromacs/correlationfunctions/polynomials.cpp index 18765ab1ff..a357f30022 100644 --- a/src/gromacs/correlationfunctions/polynomials.cpp +++ b/src/gromacs/correlationfunctions/polynomials.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,31 +55,26 @@ real LegendreP(real x, unsigned int m) switch (m) { - case 0: - polynomial = 1.0; - break; - case 1: - polynomial = x; - break; + case 0: polynomial = 1.0; break; + case 1: polynomial = x; break; case 2: - x2 = x*x; - polynomial = 1.5*x2 - 0.5; + x2 = x * x; + polynomial = 1.5 * x2 - 0.5; break; case 3: - x2 = x*x; - polynomial = (5*x2*x - 3*x )* 0.5; + x2 = x * x; + polynomial = (5 * x2 * x - 3 * x) * 0.5; break; case 4: - x2 = x*x; - polynomial = (35*x2*x2 - 30*x2 + 3)/8; + x2 = x * x; + polynomial = (35 * x2 * x2 - 30 * x2 + 3) / 8; break; case 5: - x2 = x*x; - x3 = x2*x; - polynomial = (63*x3*x2 - 70*x3 + 15*x)/8; + x2 = x * x; + x3 = x2 * x; + polynomial = (63 * x3 * x2 - 70 * x3 + 15 * x) / 8; break; - default: - gmx_fatal(FARGS, "Legendre polynomials of order %u are not supported", m); + default: gmx_fatal(FARGS, "Legendre polynomials of order %u are not supported", m); } return (polynomial); } diff --git a/src/gromacs/correlationfunctions/tests/autocorr.cpp b/src/gromacs/correlationfunctions/tests/autocorr.cpp index 2da64bd675..9c1dd7ebc3 100644 --- a/src/gromacs/correlationfunctions/tests/autocorr.cpp +++ b/src/gromacs/correlationfunctions/tests/autocorr.cpp @@ -71,164 +71,145 @@ typedef std::unique_ptr CorrelationDataSetPointer; class AutocorrTest : public ::testing::Test { - protected: - - static int nrFrames_; - static CorrelationDataSetPointer data_; - // Need raw pointer for passing this to C routines - static t_pargs * tempArgs_; - - test::TestReferenceData refData_; - test::TestReferenceChecker checker_; - - // Use erefdataCreateMissing for creating new files - AutocorrTest( ) - : checker_(refData_.rootChecker()) - { +protected: + static int nrFrames_; + static CorrelationDataSetPointer data_; + // Need raw pointer for passing this to C routines + static t_pargs* tempArgs_; + + test::TestReferenceData refData_; + test::TestReferenceChecker checker_; + + // Use erefdataCreateMissing for creating new files + AutocorrTest() : checker_(refData_.rootChecker()) + { #if GMX_DOUBLE - checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-6)); + checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-6)); #else - checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-3)); + checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-3)); #endif - } - - // Static initiation, only run once every test. - static void SetUpTestCase() - { - int n = 0; - std::string fileName = "testCOS3.xvg"; - data_ = std::make_unique(fileName); - nrFrames_ = data_->getNrLines(); - tempArgs_ = add_acf_pargs(&n, nullptr); - } - - static void TearDownTestCase() - { - sfree(tempArgs_); - tempArgs_ = nullptr; - gmx_fft_cleanup(); - } - - void test(unsigned long mode, bool bNormalize) + } + + // Static initiation, only run once every test. + static void SetUpTestCase() + { + int n = 0; + std::string fileName = "testCOS3.xvg"; + data_ = std::make_unique(fileName); + nrFrames_ = data_->getNrLines(); + tempArgs_ = add_acf_pargs(&n, nullptr); + } + + static void TearDownTestCase() + { + sfree(tempArgs_); + tempArgs_ = nullptr; + gmx_fft_cleanup(); + } + + void test(unsigned long mode, bool bNormalize) + { + bool bAverage = true; + bool bVerbose = false; + int nrRestart = 1; + int dim = getDim(mode); + std::vector result; + + for (int i = 0; i < nrFrames_; i++) { - bool bAverage = true; - bool bVerbose = false; - int nrRestart = 1; - int dim = getDim(mode); - std::vector result; - - for (int i = 0; i < nrFrames_; i++) - { - for (int m = 0; m < dim; m++) - { - result.push_back(data_->getValue(m, i)); - } - } - real *ptr = result.data(); - low_do_autocorr(nullptr, nullptr, nullptr, nrFrames_, 1, - get_acfnout(), &ptr, data_->getDt(), mode, - nrRestart, bAverage, bNormalize, - bVerbose, data_->getStartTime(), data_->getEndTime(), - effnNONE); - - double testResult = 0; - for (int i = 0; i < get_acfnout(); i++) + for (int m = 0; m < dim; m++) { - testResult += result[i]; + result.push_back(data_->getValue(m, i)); } - checker_.checkSequenceArray(get_acfnout(), ptr, - "AutocorrelationFunction"); - checker_.checkReal(testResult, "Integral"); } + real* ptr = result.data(); + low_do_autocorr(nullptr, nullptr, nullptr, nrFrames_, 1, get_acfnout(), &ptr, + data_->getDt(), mode, nrRestart, bAverage, bNormalize, bVerbose, + data_->getStartTime(), data_->getEndTime(), effnNONE); - int getDim(unsigned long type) + double testResult = 0; + for (int i = 0; i < get_acfnout(); i++) { - switch (type) - { - case eacNormal: - return 1; - case eacVector: - return 3; - case eacCos: - return 1; - case eacRcross: - return 3; - case eacP0: - return 3; - case eacP1: - return 3; - case eacP2: - return 3; - case eacP3: - return 3; - case eacP4: - return 3; - case eacIden: - return 1; - default: - GMX_RELEASE_ASSERT(false, "Invalid auto correlation option"); - return -1; - } - + testResult += result[i]; } + checker_.checkSequenceArray(get_acfnout(), ptr, "AutocorrelationFunction"); + checker_.checkReal(testResult, "Integral"); + } + int getDim(unsigned long type) + { + switch (type) + { + case eacNormal: return 1; + case eacVector: return 3; + case eacCos: return 1; + case eacRcross: return 3; + case eacP0: return 3; + case eacP1: return 3; + case eacP2: return 3; + case eacP3: return 3; + case eacP4: return 3; + case eacIden: return 1; + default: GMX_RELEASE_ASSERT(false, "Invalid auto correlation option"); return -1; + } + } }; -int AutocorrTest::nrFrames_; -CorrelationDataSetPointer AutocorrTest::data_; -t_pargs * AutocorrTest::tempArgs_; +int AutocorrTest::nrFrames_; +CorrelationDataSetPointer AutocorrTest::data_; +t_pargs* AutocorrTest::tempArgs_; -TEST_F (AutocorrTest, EacNormal) +TEST_F(AutocorrTest, EacNormal) { test(eacNormal, true); } -TEST_F (AutocorrTest, EacNoNormalize) +TEST_F(AutocorrTest, EacNoNormalize) { test(eacNormal, false); } -TEST_F (AutocorrTest, EacCos) +TEST_F(AutocorrTest, EacCos) { test(eacCos, true); } -TEST_F (AutocorrTest, EacVector) +TEST_F(AutocorrTest, EacVector) { test(eacVector, true); } -TEST_F (AutocorrTest, EacRcross) +TEST_F(AutocorrTest, EacRcross) { test(eacRcross, true); } -TEST_F (AutocorrTest, EacP0) +TEST_F(AutocorrTest, EacP0) { test(eacP0, true); } -TEST_F (AutocorrTest, EacP1) +TEST_F(AutocorrTest, EacP1) { test(eacP1, true); } -TEST_F (AutocorrTest, EacP2) +TEST_F(AutocorrTest, EacP2) { test(eacP2, true); } -TEST_F (AutocorrTest, EacP3) +TEST_F(AutocorrTest, EacP3) { test(eacP3, true); } -TEST_F (AutocorrTest, EacP4) +TEST_F(AutocorrTest, EacP4) { test(eacP4, true); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/correlationfunctions/tests/correlationdataset.cpp b/src/gromacs/correlationfunctions/tests/correlationdataset.cpp index 593b606443..589a674c0d 100644 --- a/src/gromacs/correlationfunctions/tests/correlationdataset.cpp +++ b/src/gromacs/correlationfunctions/tests/correlationdataset.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,14 +52,14 @@ #include "testutils/testfilemanager.h" -CorrelationDataSet::CorrelationDataSet(const std::string &fileName) +CorrelationDataSet::CorrelationDataSet(const std::string& fileName) { std::string fileNm = gmx::test::TestFileManager::getInputFilePath(fileName.c_str()); - nrLines_ = read_xvg(fileNm.c_str(), &tempValues_, &nrColumns_); + nrLines_ = read_xvg(fileNm.c_str(), &tempValues_, &nrColumns_); - dt_ = tempValues_[0][1] - tempValues_[0][0]; - startTime_ = tempValues_[0][0]; - endTime_ = tempValues_[0][nrLines_-1]; + dt_ = tempValues_[0][1] - tempValues_[0][0]; + startTime_ = tempValues_[0][0]; + endTime_ = tempValues_[0][nrLines_ - 1]; } CorrelationDataSet::~CorrelationDataSet() @@ -76,9 +76,9 @@ CorrelationDataSet::~CorrelationDataSet() real CorrelationDataSet::getValue(int set, int time) const { - if (set+1 < nrColumns_) + if (set + 1 < nrColumns_) { - return tempValues_[set+1][time]; + return tempValues_[set + 1][time]; } else { diff --git a/src/gromacs/correlationfunctions/tests/correlationdataset.h b/src/gromacs/correlationfunctions/tests/correlationdataset.h index db73201026..3b49626e95 100644 --- a/src/gromacs/correlationfunctions/tests/correlationdataset.h +++ b/src/gromacs/correlationfunctions/tests/correlationdataset.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014, by the GROMACS development team, led by + * Copyright (c) 2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,62 +50,61 @@ class CorrelationDataSet { - double ** tempValues_; + double** tempValues_; - int nrLines_; - int nrColumns_; - double startTime_; - double endTime_; - double dt_; + int nrLines_; + int nrColumns_; + double startTime_; + double endTime_; + double dt_; - public: +public: + /*! \brief + * Constructor + * \param[in] fileName containing function to test. *.xvg + */ + explicit CorrelationDataSet(const std::string& fileName); - /*! \brief - * Constructor - * \param[in] fileName containing function to test. *.xvg - */ - explicit CorrelationDataSet(const std::string &fileName); + /*! \brief + * Return a value at an index + * \param[in] set the set number + * \param[in] t the time index of the value + */ + real getValue(int set, int t) const; - /*! \brief - * Return a value at an index - * \param[in] set the set number - * \param[in] t the time index of the value - */ - real getValue(int set, int t) const; + /*! \brief + * Return the nummber of columns + */ + int getNrColumns() const { return nrColumns_; } - /*! \brief - * Return the nummber of columns - */ - int getNrColumns() const { return nrColumns_; } + /*! \brief + * Return the nummber of Lines + */ + int getNrLines() const { return nrLines_; } - /*! \brief - * Return the nummber of Lines - */ - int getNrLines() const { return nrLines_; } + /*! \brief + * Return the time witch the function starts at + */ + real getStartTime() const { return startTime_; } - /*! \brief - * Return the time witch the function starts at - */ - real getStartTime() const { return startTime_; } + /*! \brief + * Return the time the function ends at + */ + real getEndTime() const { return endTime_; } - /*! \brief - * Return the time the function ends at - */ - real getEndTime() const { return endTime_; } + /*! \brief + * return delta time + */ + real getDt() const { return dt_; } - /*! \brief - * return delta time - */ - real getDt() const { return dt_; } + /*! \brief + * Destructor + */ + ~CorrelationDataSet(); - /*! \brief - * Destructor - */ - ~CorrelationDataSet(); - - private: - //! This class should not be copyable or assignable - GMX_DISALLOW_COPY_AND_ASSIGN(CorrelationDataSet); +private: + //! This class should not be copyable or assignable + GMX_DISALLOW_COPY_AND_ASSIGN(CorrelationDataSet); }; #endif diff --git a/src/gromacs/correlationfunctions/tests/expfit.cpp b/src/gromacs/correlationfunctions/tests/expfit.cpp index 162123bc06..c7427688f3 100644 --- a/src/gromacs/correlationfunctions/tests/expfit.cpp +++ b/src/gromacs/correlationfunctions/tests/expfit.cpp @@ -66,149 +66,148 @@ namespace #if HAVE_LMFIT class ExpfitData { - public: - int nrLines_; - std::vector x_, y_; - real startTime_, endTime_, dt_; +public: + int nrLines_; + std::vector x_, y_; + real startTime_, endTime_, dt_; }; class ExpfitTest : public ::testing::Test { - protected: - static std::vector data_; - test::TestReferenceData refData_; - test::TestReferenceChecker checker_; - ExpfitTest( ) - : checker_(refData_.rootChecker()) +protected: + static std::vector data_; + test::TestReferenceData refData_; + test::TestReferenceChecker checker_; + ExpfitTest() : checker_(refData_.rootChecker()) {} + + // Static initiation, only run once every test. + static void SetUpTestCase() + { + double** tempValues = nullptr; + std::vector fileName; + fileName.push_back(test::TestFileManager::getInputFilePath("testINVEXP.xvg")); + fileName.push_back(test::TestFileManager::getInputFilePath("testPRES.xvg")); + fileName.push_back(test::TestFileManager::getInputFilePath("testINVEXP79.xvg")); + fileName.push_back(test::TestFileManager::getInputFilePath("testERF.xvg")); + fileName.push_back(test::TestFileManager::getInputFilePath("testERREST.xvg")); + for (std::vector::iterator i = fileName.begin(); i < fileName.end(); ++i) { - } + const char* name = i->c_str(); + int nrColumns; + ExpfitData ed; + ed.nrLines_ = read_xvg(name, &tempValues, &nrColumns); + ed.dt_ = tempValues[0][1] - tempValues[0][0]; + ed.startTime_ = tempValues[0][0]; + ed.endTime_ = tempValues[0][ed.nrLines_ - 1]; + for (int j = 0; j < ed.nrLines_; j++) + { + ed.x_.push_back(static_cast(tempValues[0][j])); + ed.y_.push_back(static_cast(tempValues[1][j])); + } + data_.push_back(ed); - // Static initiation, only run once every test. - static void SetUpTestCase() - { - double ** tempValues = nullptr; - std::vector fileName; - fileName.push_back(test::TestFileManager::getInputFilePath("testINVEXP.xvg")); - fileName.push_back(test::TestFileManager::getInputFilePath("testPRES.xvg")); - fileName.push_back(test::TestFileManager::getInputFilePath("testINVEXP79.xvg")); - fileName.push_back(test::TestFileManager::getInputFilePath("testERF.xvg")); - fileName.push_back(test::TestFileManager::getInputFilePath("testERREST.xvg")); - for (std::vector::iterator i = fileName.begin(); i < fileName.end(); ++i) + // Free memory that was allocated in read_xvg + for (int j = 0; j < nrColumns; j++) { - const char * name = i->c_str(); - int nrColumns; - ExpfitData ed; - ed.nrLines_ = read_xvg(name, &tempValues, &nrColumns); - ed.dt_ = tempValues[0][1] - tempValues[0][0]; - ed.startTime_ = tempValues[0][0]; - ed.endTime_ = tempValues[0][ed.nrLines_-1]; - for (int j = 0; j < ed.nrLines_; j++) - { - ed.x_.push_back(static_cast(tempValues[0][j])); - ed.y_.push_back(static_cast(tempValues[1][j])); - } - data_.push_back(ed); - - // Free memory that was allocated in read_xvg - for (int j = 0; j < nrColumns; j++) - { - sfree(tempValues[j]); - tempValues[j] = nullptr; - } - sfree(tempValues); - tempValues = nullptr; + sfree(tempValues[j]); + tempValues[j] = nullptr; } + sfree(tempValues); + tempValues = nullptr; } + } - static void TearDownTestCase() - { - } + static void TearDownTestCase() {} - void test(int type, double result[], double tolerance, - unsigned int testType) - { - int nfitparm = effnNparams(type); - gmx_output_env_t *oenv; + void test(int type, double result[], double tolerance, unsigned int testType) + { + int nfitparm = effnNparams(type); + gmx_output_env_t* oenv; - if (testType >= data_.size()) - { - GMX_THROW(InvalidInputError("testType out of range")); - } - output_env_init_default(&oenv); - do_lmfit(data_[testType].nrLines_, - &(data_[testType].y_[0]), - nullptr, - data_[testType].dt_, - &(data_[testType].x_[0]), - data_[testType].startTime_, - data_[testType].endTime_, - oenv, false, type, result, 0, nullptr); - output_env_done(oenv); - checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, tolerance)); - checker_.checkSequenceArray(nfitparm, result, "result"); + if (testType >= data_.size()) + { + GMX_THROW(InvalidInputError("testType out of range")); } + output_env_init_default(&oenv); + do_lmfit(data_[testType].nrLines_, &(data_[testType].y_[0]), nullptr, data_[testType].dt_, + &(data_[testType].x_[0]), data_[testType].startTime_, data_[testType].endTime_, + oenv, false, type, result, 0, nullptr); + output_env_done(oenv); + checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, tolerance)); + checker_.checkSequenceArray(nfitparm, result, "result"); + } }; -//static var +// static var std::vector ExpfitTest::data_; // TODO calling test() leads to a fatal error, which we could in // principle test for. -TEST_F (ExpfitTest, EffnEXP1) { - double param[] = {25}; +TEST_F(ExpfitTest, EffnEXP1) +{ + double param[] = { 25 }; test(effnEXP1, param, 1e-5, 0); } -TEST_F (ExpfitTest, EffnEXP2) { - double param[] = {35, 0.5}; +TEST_F(ExpfitTest, EffnEXP2) +{ + double param[] = { 35, 0.5 }; test(effnEXP2, param, 3e-5, 0); } -TEST_F (ExpfitTest, EffnEXPEXP) { - double param[] = {5, 0.5, 45}; +TEST_F(ExpfitTest, EffnEXPEXP) +{ + double param[] = { 5, 0.5, 45 }; test(effnEXPEXP, param, 1e-2, 0); } -TEST_F (ExpfitTest, EffnEXP5) { - double param[] = {0.5, 5, 0.5, 50, 0.002}; +TEST_F(ExpfitTest, EffnEXP5) +{ + double param[] = { 0.5, 5, 0.5, 50, 0.002 }; test(effnEXP5, param, 1e-2, 2); } -TEST_F (ExpfitTest, EffnEXP7) { - double param[] = {0.1, 2, 0.5, 30, 0.3, 50, -0.002}; +TEST_F(ExpfitTest, EffnEXP7) +{ + double param[] = { 0.1, 2, 0.5, 30, 0.3, 50, -0.002 }; test(effnEXP7, param, 1e-2, 2); } -TEST_F (ExpfitTest, EffnEXP9) { - double param[] = {0.4, 5, 0.2, 30, 0.1, 70, 0.2, 200, -0.05}; +TEST_F(ExpfitTest, EffnEXP9) +{ + double param[] = { 0.4, 5, 0.2, 30, 0.1, 70, 0.2, 200, -0.05 }; test(effnEXP9, param, 4e-2, 2); } -TEST_F (ExpfitTest, EffnERF) { - double param[] = {80, 120, 180, 5}; +TEST_F(ExpfitTest, EffnERF) +{ + double param[] = { 80, 120, 180, 5 }; test(effnERF, param, 1e-1, 3); } -TEST_F (ExpfitTest, EffnERREST) { - double param[] = {1, 0.9, 100}; +TEST_F(ExpfitTest, EffnERREST) +{ + double param[] = { 1, 0.9, 100 }; test(effnERREST, param, 5e-3, 4); } -TEST_F (ExpfitTest, EffnVAC) { - double param[] = {0.6, 0.1}; +TEST_F(ExpfitTest, EffnVAC) +{ + double param[] = { 0.6, 0.1 }; test(effnVAC, param, 0.05, 0); } -TEST_F (ExpfitTest, EffnPRES) { - double param[] = {0.6, 10, 7, 1, 0.25, 2}; +TEST_F(ExpfitTest, EffnPRES) +{ + double param[] = { 0.6, 10, 7, 1, 0.25, 2 }; test(effnPRES, param, 1e-4, 1); } #endif -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/correlationfunctions/tests/manyautocorrelation.cpp b/src/gromacs/correlationfunctions/tests/manyautocorrelation.cpp index a634322371..586fbc7a42 100644 --- a/src/gromacs/correlationfunctions/tests/manyautocorrelation.cpp +++ b/src/gromacs/correlationfunctions/tests/manyautocorrelation.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,16 +63,16 @@ class ManyAutocorrelationTest : public ::testing::Test { }; -TEST_F (ManyAutocorrelationTest, Empty) +TEST_F(ManyAutocorrelationTest, Empty) { - std::vector > c; + std::vector> c; EXPECT_THROW_GMX(many_auto_correl(&c), gmx::InconsistentInputError); } #ifndef NDEBUG -TEST_F (ManyAutocorrelationTest, DifferentLength) +TEST_F(ManyAutocorrelationTest, DifferentLength) { - std::vector > c; + std::vector> c; c.resize(3); c[0].resize(10); c[1].resize(10); @@ -81,6 +81,6 @@ TEST_F (ManyAutocorrelationTest, DifferentLength) } #endif -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/domdec/atomdistribution.cpp b/src/gromacs/domdec/atomdistribution.cpp index 93e0cc629d..52a2d1f9dd 100644 --- a/src/gromacs/domdec/atomdistribution.cpp +++ b/src/gromacs/domdec/atomdistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,15 +51,13 @@ /*! \brief Returns the total number of rank, determined from the DD grid dimensions */ static int numRanks(const ivec numCells) { - return numCells[XX]*numCells[YY]*numCells[ZZ]; + return numCells[XX] * numCells[YY] * numCells[ZZ]; } -AtomDistribution::AtomDistribution(const ivec numCells, - int numAtomGroups, - int numAtoms) : +AtomDistribution::AtomDistribution(const ivec numCells, int numAtomGroups, int numAtoms) : domainGroups(numRanks(numCells)), atomGroups(numAtomGroups), - intBuffer(2*numRanks(numCells)), + intBuffer(2 * numRanks(numCells)), rvecBuffer(numRanks(numCells) > c_maxNumRanksUseSendRecvForScatterAndGather ? numAtoms : 0) { for (int d = 0; d < DIM; d++) @@ -68,19 +66,17 @@ AtomDistribution::AtomDistribution(const ivec numCells, } } -void get_commbuffer_counts(AtomDistribution *ma, - int **counts, - int **disps) +void get_commbuffer_counts(AtomDistribution* ma, int** counts, int** disps) { GMX_ASSERT(ma != nullptr, "Need a valid AtomDistribution struct (on the master rank)"); /* Make the rvec count and displacement arrays */ - int numRanks = ma->intBuffer.size()/2; + int numRanks = ma->intBuffer.size() / 2; *counts = ma->intBuffer.data(); *disps = ma->intBuffer.data() + numRanks; for (int rank = 0; rank < numRanks; rank++) { - (*counts)[rank] = ma->domainGroups[rank].numAtoms*sizeof(rvec); + (*counts)[rank] = ma->domainGroups[rank].numAtoms * sizeof(rvec); (*disps)[rank] = (rank == 0 ? 0 : (*disps)[rank - 1] + (*counts)[rank - 1]); } } diff --git a/src/gromacs/domdec/atomdistribution.h b/src/gromacs/domdec/atomdistribution.h index a4132dc3d8..604505de06 100644 --- a/src/gromacs/domdec/atomdistribution.h +++ b/src/gromacs/domdec/atomdistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,22 +58,20 @@ struct AtomDistribution */ struct DomainAtomGroups { - gmx::ArrayRef atomGroups; /**< List of our atom groups */ - int numAtoms; /**< Our number of local atoms */ + gmx::ArrayRef atomGroups; /**< List of our atom groups */ + int numAtoms; /**< Our number of local atoms */ }; /*! \brief Constructor */ - AtomDistribution(const ivec numCells, - int numAtomGroups, - int numAtoms); + AtomDistribution(const ivec numCells, int numAtomGroups, int numAtoms); std::vector domainGroups; /**< Group and atom division over ranks/domains */ - std::vector atomGroups; /**< The atom group division of the whole system, pointed into by counts[].atomGroups */ + std::vector atomGroups; /**< The atom group division of the whole system, pointed into by counts[].atomGroups */ /* Temporary buffers, stored permanently here to avoid reallocation */ std::array, DIM> cellSizesBuffer; /**< Cell boundaries, sizes: num_cells_in_dim + 1 */ - std::vector intBuffer; /**< Buffer for communicating cg and atom counts */ - std::vector rvecBuffer; /**< Buffer for state scattering and gathering */ + std::vector intBuffer; /**< Buffer for communicating cg and atom counts */ + std::vector rvecBuffer; /**< Buffer for state scattering and gathering */ }; /*! \brief Returns state scatter/gather buffer element counts and displacements @@ -81,8 +79,6 @@ struct AtomDistribution * NOTE: Should only be called with a pointer to a valid ma struct * (only available on the master rank). */ -void get_commbuffer_counts(AtomDistribution *ma, - int **counts, - int **disps); +void get_commbuffer_counts(AtomDistribution* ma, int** counts, int** disps); #endif diff --git a/src/gromacs/domdec/box.cpp b/src/gromacs/domdec/box.cpp index 42bcd2bc3c..0e9f4e611b 100644 --- a/src/gromacs/domdec/box.cpp +++ b/src/gromacs/domdec/box.cpp @@ -65,22 +65,19 @@ #include "domdec_internal.h" /*! \brief Calculates the average and standard deviation in 3D of atoms */ -static void calc_pos_av_stddev(gmx::ArrayRef x, - rvec av, - rvec stddev, - const MPI_Comm *mpiCommunicator) +static void calc_pos_av_stddev(gmx::ArrayRef x, rvec av, rvec stddev, const MPI_Comm* mpiCommunicator) { - dvec s1, s2; + dvec s1, s2; clear_dvec(s1); clear_dvec(s2); - for (const gmx::RVec &coord : x) + for (const gmx::RVec& coord : x) { for (int d = 0; d < DIM; d++) { s1[d] += coord[d]; - s2[d] += coord[d]*coord[d]; + s2[d] += coord[d] * coord[d]; } } @@ -100,8 +97,7 @@ static void calc_pos_av_stddev(gmx::ArrayRef x, } sendBuffer[6] = numAtoms; - MPI_Allreduce(sendBuffer, receiveBuffer, c_bufSize, MPI_DOUBLE, - MPI_SUM, *mpiCommunicator); + MPI_Allreduce(sendBuffer, receiveBuffer, c_bufSize, MPI_DOUBLE, MPI_SUM, *mpiCommunicator); for (int d = 0; d < DIM; d++) { @@ -114,18 +110,18 @@ static void calc_pos_av_stddev(gmx::ArrayRef x, GMX_UNUSED_VALUE(mpiCommunicator); #endif // GMX_MPI - dsvmul(1.0/numAtoms, s1, s1); - dsvmul(1.0/numAtoms, s2, s2); + dsvmul(1.0 / numAtoms, s1, s1); + dsvmul(1.0 / numAtoms, s2, s2); for (int d = 0; d < DIM; d++) { av[d] = s1[d]; - stddev[d] = std::sqrt(s2[d] - s1[d]*s1[d]); + stddev[d] = std::sqrt(s2[d] - s1[d] * s1[d]); } } /*! \brief Determines if dimensions require triclinic treatment and stores this info in ddbox */ -static void set_tric_dir(const ivec *dd_nc, gmx_ddbox_t *ddbox, const matrix box) +static void set_tric_dir(const ivec* dd_nc, gmx_ddbox_t* ddbox, const matrix box) { int npbcdim, d, i, j; rvec *v, *normal; @@ -136,16 +132,19 @@ static void set_tric_dir(const ivec *dd_nc, gmx_ddbox_t *ddbox, const matrix box for (d = 0; d < DIM; d++) { ddbox->tric_dir[d] = 0; - for (j = d+1; j < npbcdim; j++) + for (j = d + 1; j < npbcdim; j++) { if (box[j][d] != 0) { ddbox->tric_dir[d] = 1; if (dd_nc != nullptr && (*dd_nc)[j] > 1 && (*dd_nc)[d] == 1) { - gmx_fatal(FARGS, "Domain decomposition has not been implemented for box vectors that have non-zero components in directions that do not use domain decomposition: ncells = %d %d %d, box vector[%d] = %f %f %f", - (*dd_nc)[XX], (*dd_nc)[YY], (*dd_nc)[ZZ], - j+1, box[j][XX], box[j][YY], box[j][ZZ]); + gmx_fatal(FARGS, + "Domain decomposition has not been implemented for box vectors that " + "have non-zero components in directions that do not use domain " + "decomposition: ncells = %d %d %d, box vector[%d] = %f %f %f", + (*dd_nc)[XX], (*dd_nc)[YY], (*dd_nc)[ZZ], j + 1, box[j][XX], + box[j][YY], box[j][ZZ]); } } } @@ -166,54 +165,52 @@ static void set_tric_dir(const ivec *dd_nc, gmx_ddbox_t *ddbox, const matrix box if (d == XX || d == YY) { /* Normalize such that the "diagonal" is 1 */ - svmul(1/box[d+1][d+1], box[d+1], v[d+1]); + svmul(1 / box[d + 1][d + 1], box[d + 1], v[d + 1]); for (i = 0; i < d; i++) { - v[d+1][i] = 0; + v[d + 1][i] = 0; } - inv_skew_fac2 += gmx::square(v[d+1][d]); + inv_skew_fac2 += gmx::square(v[d + 1][d]); if (d == XX) { /* Normalize such that the "diagonal" is 1 */ - svmul(1/box[d+2][d+2], box[d+2], v[d+2]); + svmul(1 / box[d + 2][d + 2], box[d + 2], v[d + 2]); /* Set v[d+2][d+1] to zero by shifting along v[d+1] */ - dep = v[d+2][d+1]/v[d+1][d+1]; + dep = v[d + 2][d + 1] / v[d + 1][d + 1]; for (i = 0; i < DIM; i++) { - v[d+2][i] -= dep*v[d+1][i]; + v[d + 2][i] -= dep * v[d + 1][i]; } - inv_skew_fac2 += gmx::square(v[d+2][d]); + inv_skew_fac2 += gmx::square(v[d + 2][d]); - cprod(v[d+1], v[d+2], normal[d]); + cprod(v[d + 1], v[d + 2], normal[d]); } else { /* cross product with (1,0,0) */ - normal[d][XX] = 0; - normal[d][YY] = v[d+1][ZZ]; - normal[d][ZZ] = -v[d+1][YY]; + normal[d][XX] = 0; + normal[d][YY] = v[d + 1][ZZ]; + normal[d][ZZ] = -v[d + 1][YY]; } if (debug) { - fprintf(debug, "box[%d] %.3f %.3f %.3f\n", - d, box[d][XX], box[d][YY], box[d][ZZ]); - for (i = d+1; i < DIM; i++) + fprintf(debug, "box[%d] %.3f %.3f %.3f\n", d, box[d][XX], box[d][YY], box[d][ZZ]); + for (i = d + 1; i < DIM; i++) { - fprintf(debug, " v[%d] %.3f %.3f %.3f\n", - i, v[i][XX], v[i][YY], v[i][ZZ]); + fprintf(debug, " v[%d] %.3f %.3f %.3f\n", i, v[i][XX], v[i][YY], v[i][ZZ]); } } } - ddbox->skew_fac[d] = 1.0/std::sqrt(inv_skew_fac2); + ddbox->skew_fac[d] = 1.0 / std::sqrt(inv_skew_fac2); /* Set the normal vector length to skew_fac */ - dep = ddbox->skew_fac[d]/norm(normal[d]); + dep = ddbox->skew_fac[d] / norm(normal[d]); svmul(dep, normal[d], normal[d]); if (debug) { fprintf(debug, "skew_fac[%d] = %f\n", d, ddbox->skew_fac[d]); - fprintf(debug, "normal[%d] %.3f %.3f %.3f\n", - d, normal[d][XX], normal[d][YY], normal[d][ZZ]); + fprintf(debug, "normal[%d] %.3f %.3f %.3f\n", d, normal[d][XX], normal[d][YY], + normal[d][ZZ]); } } else @@ -232,14 +229,14 @@ static void set_tric_dir(const ivec *dd_nc, gmx_ddbox_t *ddbox, const matrix box } /*! \brief This function calculates bounding box and pbc info and populates ddbox */ -static void low_set_ddbox(int numPbcDimensions, - int numBoundedDimensions, - const ivec *dd_nc, - const matrix box, - bool calculateUnboundedSize, - gmx::ArrayRef x, - const MPI_Comm *mpiCommunicator, - gmx_ddbox_t *ddbox) +static void low_set_ddbox(int numPbcDimensions, + int numBoundedDimensions, + const ivec* dd_nc, + const matrix box, + bool calculateUnboundedSize, + gmx::ArrayRef x, + const MPI_Comm* mpiCommunicator, + gmx_ddbox_t* ddbox) { rvec av, stddev; real b0, b1; @@ -264,12 +261,11 @@ static void low_set_ddbox(int numPbcDimensions, */ for (d = ddbox->nboundeddim; d < DIM; d++) { - b0 = av[d] - GRID_STDDEV_FAC*stddev[d]; - b1 = av[d] + GRID_STDDEV_FAC*stddev[d]; + b0 = av[d] - GRID_STDDEV_FAC * stddev[d]; + b1 = av[d] + GRID_STDDEV_FAC * stddev[d]; if (debug) { - fprintf(debug, "Setting global DD grid boundaries to %f - %f\n", - b0, b1); + fprintf(debug, "Setting global DD grid boundaries to %f - %f\n", b0, b1); } ddbox->box0[d] = b0; ddbox->box_size[d] = b1 - b0; @@ -279,24 +275,22 @@ static void low_set_ddbox(int numPbcDimensions, set_tric_dir(dd_nc, ddbox, box); } -void set_ddbox(const gmx_domdec_t &dd, - bool masterRankHasTheSystemState, - const matrix box, - bool calculateUnboundedSize, - gmx::ArrayRef x, - gmx_ddbox_t *ddbox) +void set_ddbox(const gmx_domdec_t& dd, + bool masterRankHasTheSystemState, + const matrix box, + bool calculateUnboundedSize, + gmx::ArrayRef x, + gmx_ddbox_t* ddbox) { if (!masterRankHasTheSystemState || DDMASTER(dd)) { - bool needToReduceCoordinateData = - (!masterRankHasTheSystemState && dd.nnodes > 1); - gmx::ArrayRef xRef = - constArrayRefFromArray(x.data(), masterRankHasTheSystemState ? x.size() : dd.comm->atomRanges.numHomeAtoms()); - - low_set_ddbox(dd.unitCellInfo.npbcdim, dd.unitCellInfo.numBoundedDimensions, - &dd.nc, box, calculateUnboundedSize, xRef, - needToReduceCoordinateData ? &dd.mpi_comm_all : nullptr, - ddbox); + bool needToReduceCoordinateData = (!masterRankHasTheSystemState && dd.nnodes > 1); + gmx::ArrayRef xRef = constArrayRefFromArray( + x.data(), masterRankHasTheSystemState ? x.size() : dd.comm->atomRanges.numHomeAtoms()); + + low_set_ddbox(dd.unitCellInfo.npbcdim, dd.unitCellInfo.numBoundedDimensions, &dd.nc, box, + calculateUnboundedSize, xRef, + needToReduceCoordinateData ? &dd.mpi_comm_all : nullptr, ddbox); } if (masterRankHasTheSystemState) @@ -305,17 +299,16 @@ void set_ddbox(const gmx_domdec_t &dd, } } -void set_ddbox_cr(const t_commrec &cr, - const ivec *dd_nc, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef x, - gmx_ddbox_t *ddbox) +void set_ddbox_cr(const t_commrec& cr, + const ivec* dd_nc, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef x, + gmx_ddbox_t* ddbox) { if (MASTER(&cr)) { - low_set_ddbox(ePBC2npbcdim(ir.ePBC), inputrec2nboundeddim(&ir), - dd_nc, box, true, x, nullptr, ddbox); + low_set_ddbox(ePBC2npbcdim(ir.ePBC), inputrec2nboundeddim(&ir), dd_nc, box, true, x, nullptr, ddbox); } gmx_bcast(sizeof(gmx_ddbox_t), ddbox, &cr); diff --git a/src/gromacs/domdec/box.h b/src/gromacs/domdec/box.h index 8e8b396da3..d02c34b9d8 100644 --- a/src/gromacs/domdec/box.h +++ b/src/gromacs/domdec/box.h @@ -55,19 +55,19 @@ struct t_commrec; struct t_inputrec; /*! \brief Set the box and PBC data in \p ddbox */ -void set_ddbox(const gmx_domdec_t &dd, - bool masterRankHasTheSystemState, - const matrix box, - bool calculateUnboundedSize, - gmx::ArrayRef x, - gmx_ddbox_t *ddbox); +void set_ddbox(const gmx_domdec_t& dd, + bool masterRankHasTheSystemState, + const matrix box, + bool calculateUnboundedSize, + gmx::ArrayRef x, + gmx_ddbox_t* ddbox); /*! \brief Set the box and PBC data in \p ddbox */ -void set_ddbox_cr(const t_commrec &cr, - const ivec *dd_nc, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef x, - gmx_ddbox_t *ddbox); +void set_ddbox_cr(const t_commrec& cr, + const ivec* dd_nc, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef x, + gmx_ddbox_t* ddbox); #endif diff --git a/src/gromacs/domdec/builder.h b/src/gromacs/domdec/builder.h index 0d4ffa4c2f..067524997d 100644 --- a/src/gromacs/domdec/builder.h +++ b/src/gromacs/domdec/builder.h @@ -62,7 +62,8 @@ class LocalAtomSetManager; struct DomdecOptions; struct MdrunOptions; -template class ArrayRef; +template +class ArrayRef; /*! \libinternal * \brief Builds a domain decomposition management object @@ -72,26 +73,26 @@ template class ArrayRef; * for transfer operations. */ class DomainDecompositionBuilder { - public: - //! Constructor - DomainDecompositionBuilder(const MDLogger &mdlog, - t_commrec *cr, - const DomdecOptions &options, - const MdrunOptions &mdrunOptions, - bool prefer1DAnd1Pulse, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - ArrayRef xGlobal); - //! Destructor - ~DomainDecompositionBuilder(); - //! Build the resulting DD manager - gmx_domdec_t *build(LocalAtomSetManager *atomSets); +public: + //! Constructor + DomainDecompositionBuilder(const MDLogger& mdlog, + t_commrec* cr, + const DomdecOptions& options, + const MdrunOptions& mdrunOptions, + bool prefer1DAnd1Pulse, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + ArrayRef xGlobal); + //! Destructor + ~DomainDecompositionBuilder(); + //! Build the resulting DD manager + gmx_domdec_t* build(LocalAtomSetManager* atomSets); - private: - class Impl; - //! Pimpl to hide implementation details - PrivateImplPointer impl_; +private: + class Impl; + //! Pimpl to hide implementation details + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/domdec/cellsizes.cpp b/src/gromacs/domdec/cellsizes.cpp index f9d47b3e41..28078ffc54 100644 --- a/src/gromacs/domdec/cellsizes.cpp +++ b/src/gromacs/domdec/cellsizes.cpp @@ -57,13 +57,15 @@ #include "domdec_internal.h" #include "utility.h" -static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, - gmx_bool bUniform, const gmx_ddbox_t *ddbox, - const real *cellFrac) +static void set_pme_maxshift(gmx_domdec_t* dd, + gmx_ddpme_t* ddpme, + gmx_bool bUniform, + const gmx_ddbox_t* ddbox, + const real* cellFrac) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int nc, ns, s; - int *xmin, *xmax; + int * xmin, *xmax; real range, pme_boundary; int sh; @@ -74,7 +76,7 @@ static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, if (!ddpme->dim_match) { /* PP decomposition is not along dim: the worst situation */ - sh = ns/2; + sh = ns / 2; } else if (ns <= 3 || (bUniform && ns == nc)) { @@ -93,7 +95,7 @@ static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, * between performance and support for most charge-group/cut-off * combinations. */ - range = 2.0/3.0*comm->systemInfo.cutoff/ddbox->box_size[ddpme->dim]; + range = 2.0 / 3.0 * comm->systemInfo.cutoff / ddbox->box_size[ddpme->dim]; /* Avoid extra communication when we are exactly at a boundary */ range *= 0.999; @@ -101,21 +103,17 @@ static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, for (s = 0; s < ns; s++) { /* PME slab s spreads atoms between box frac. s/ns and (s+1)/ns */ - pme_boundary = static_cast(s)/ns; - while (sh + 1 < ns && - ((s - (sh + 1) >= 0 && - cellFrac[xmax[s - (sh + 1) ] + 1] + range > pme_boundary) || - (s - (sh + 1) < 0 && - cellFrac[xmax[s - (sh + 1) + ns] + 1] - 1 + range > pme_boundary))) + pme_boundary = static_cast(s) / ns; + while (sh + 1 < ns + && ((s - (sh + 1) >= 0 && cellFrac[xmax[s - (sh + 1)] + 1] + range > pme_boundary) + || (s - (sh + 1) < 0 && cellFrac[xmax[s - (sh + 1) + ns] + 1] - 1 + range > pme_boundary))) { sh++; } - pme_boundary = static_cast(s+1)/ns; - while (sh + 1 < ns && - ((s + (sh + 1) < ns && - cellFrac[xmin[s + (sh + 1) ] ] - range < pme_boundary) || - (s + (sh + 1) >= ns && - cellFrac[xmin[s +(sh + 1) - ns] ] + 1 - range < pme_boundary))) + pme_boundary = static_cast(s + 1) / ns; + while (sh + 1 < ns + && ((s + (sh + 1) < ns && cellFrac[xmin[s + (sh + 1)]] - range < pme_boundary) + || (s + (sh + 1) >= ns && cellFrac[xmin[s + (sh + 1) - ns]] + 1 - range < pme_boundary))) { sh++; } @@ -126,33 +124,32 @@ static void set_pme_maxshift(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, if (debug) { - fprintf(debug, "PME slab communication range for dim %d is %d\n", - ddpme->dim, ddpme->maxshift); + fprintf(debug, "PME slab communication range for dim %d is %d\n", ddpme->dim, ddpme->maxshift); } } -static void check_box_size(const gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox) +static void check_box_size(const gmx_domdec_t* dd, const gmx_ddbox_t* ddbox) { int d, dim; for (d = 0; d < dd->ndim; d++) { dim = dd->dim[d]; - if (dim < ddbox->nboundeddim && - ddbox->box_size[dim]*ddbox->skew_fac[dim] < - dd->nc[dim]*dd->comm->cellsize_limit*DD_CELL_MARGIN) + if (dim < ddbox->nboundeddim + && ddbox->box_size[dim] * ddbox->skew_fac[dim] + < dd->nc[dim] * dd->comm->cellsize_limit * DD_CELL_MARGIN) { - gmx_fatal(FARGS, "The %c-size of the box (%f) times the triclinic skew factor (%f) is smaller than the number of DD cells (%d) times the smallest allowed cell size (%f)\n", - dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim], - dd->nc[dim], dd->comm->cellsize_limit); + gmx_fatal( + FARGS, + "The %c-size of the box (%f) times the triclinic skew factor (%f) is smaller " + "than the number of DD cells (%d) times the smallest allowed cell size (%f)\n", + dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim], dd->nc[dim], + dd->comm->cellsize_limit); } } } -real grid_jump_limit(const gmx_domdec_comm_t *comm, - real cutoff, - int dim_ind) +real grid_jump_limit(const gmx_domdec_comm_t* comm, real cutoff, int dim_ind) { real grid_jump_limit; @@ -169,8 +166,7 @@ real grid_jump_limit(const gmx_domdec_comm_t *comm, { cutoff = std::max(cutoff, comm->PMELoadBal_max_cutoff); } - grid_jump_limit = std::max(grid_jump_limit, - cutoff/comm->cd[dim_ind].numPulses()); + grid_jump_limit = std::max(grid_jump_limit, cutoff / comm->cd[dim_ind].numPulses()); } return grid_jump_limit; @@ -181,7 +177,7 @@ real grid_jump_limit(const gmx_domdec_comm_t *comm, * comm->cellsize_min, for bonded and initial non-bonded cut-offs, * and, possibly, a longer cut-off limit set for PME load balancing. */ -static real cellsize_min_dlb(gmx_domdec_comm_t *comm, int dim_ind, int dim) +static real cellsize_min_dlb(gmx_domdec_comm_t* comm, int dim_ind, int dim) { real cellsize_min; @@ -192,12 +188,12 @@ static real cellsize_min_dlb(gmx_domdec_comm_t *comm, int dim_ind, int dim) /* The cut-off might have changed, e.g. by PME load balacning, * from the value used to set comm->cellsize_min, so check it. */ - cellsize_min = std::max(cellsize_min, comm->systemInfo.cutoff/comm->cd[dim_ind].np_dlb); + cellsize_min = std::max(cellsize_min, comm->systemInfo.cutoff / comm->cd[dim_ind].np_dlb); if (comm->bPMELoadBalDLBLimits) { /* Check for the cut-off limit set by the PME load balancing */ - cellsize_min = std::max(cellsize_min, comm->PMELoadBal_max_cutoff/comm->cd[dim_ind].np_dlb); + cellsize_min = std::max(cellsize_min, comm->PMELoadBal_max_cutoff / comm->cd[dim_ind].np_dlb); } } @@ -209,13 +205,12 @@ static real cellsize_min_dlb(gmx_domdec_comm_t *comm, int dim_ind, int dim) * setmode determine if and where the boundaries are stored, use enum above. * Returns the number communication pulses in npulse. */ -gmx::ArrayRef < const std::vector < real>> -set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, - int setmode, ivec npulse) +gmx::ArrayRef> +set_dd_cell_sizes_slb(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox, int setmode, ivec npulse) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; - gmx::ArrayRef < std::vector < real>> cell_x_master; + gmx::ArrayRef> cell_x_master; if (setmode == setcellsizeslbMASTER) { cell_x_master = dd->ma->cellSizesBuffer; @@ -224,29 +219,28 @@ set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, rvec cellsize_min; for (int d = 0; d < DIM; d++) { - cellsize_min[d] = ddbox->box_size[d]*ddbox->skew_fac[d]; + cellsize_min[d] = ddbox->box_size[d] * ddbox->skew_fac[d]; npulse[d] = 1; if (dd->nc[d] == 1 || comm->slb_frac[d] == nullptr) { /* Uniform grid */ - real cell_dx = ddbox->box_size[d]/dd->nc[d]; + real cell_dx = ddbox->box_size[d] / dd->nc[d]; switch (setmode) { case setcellsizeslbMASTER: - for (int j = 0; j < dd->nc[d]+1; j++) + for (int j = 0; j < dd->nc[d] + 1; j++) { - cell_x_master[d][j] = ddbox->box0[d] + j*cell_dx; + cell_x_master[d][j] = ddbox->box0[d] + j * cell_dx; } break; case setcellsizeslbLOCAL: - comm->cell_x0[d] = ddbox->box0[d] + (dd->ci[d] )*cell_dx; - comm->cell_x1[d] = ddbox->box0[d] + (dd->ci[d]+1)*cell_dx; - break; - default: + comm->cell_x0[d] = ddbox->box0[d] + (dd->ci[d]) * cell_dx; + comm->cell_x1[d] = ddbox->box0[d] + (dd->ci[d] + 1) * cell_dx; break; + default: break; } - real cellsize = cell_dx*ddbox->skew_fac[d]; - while (cellsize*npulse[d] < comm->systemInfo.cutoff) + real cellsize = cell_dx * ddbox->skew_fac[d]; + while (cellsize * npulse[d] < comm->systemInfo.cutoff) { npulse[d]++; } @@ -273,11 +267,10 @@ set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, cell_x[0] = ddbox->box0[d]; for (int j = 0; j < dd->nc[d]; j++) { - real cell_dx = ddbox->box_size[d]*comm->slb_frac[d][j]; - cell_x[j+1] = cell_x[j] + cell_dx; - real cellsize = cell_dx*ddbox->skew_fac[d]; - while (cellsize*npulse[d] < comm->systemInfo.cutoff && - npulse[d] < dd->nc[d]-1) + real cell_dx = ddbox->box_size[d] * comm->slb_frac[d][j]; + cell_x[j + 1] = cell_x[j] + cell_dx; + real cellsize = cell_dx * ddbox->skew_fac[d]; + while (cellsize * npulse[d] < comm->systemInfo.cutoff && npulse[d] < dd->nc[d] - 1) { npulse[d]++; } @@ -286,29 +279,27 @@ set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, if (setmode == setcellsizeslbLOCAL) { comm->cell_x0[d] = cell_x[dd->ci[d]]; - comm->cell_x1[d] = cell_x[dd->ci[d]+1]; + comm->cell_x1[d] = cell_x[dd->ci[d] + 1]; } } /* The following limitation is to avoid that a cell would receive * some of its own home charge groups back over the periodic boundary. * Double charge groups cause trouble with the global indices. */ - if (d < ddbox->npbcdim && - dd->nc[d] > 1 && npulse[d] >= dd->nc[d]) + if (d < ddbox->npbcdim && dd->nc[d] > 1 && npulse[d] >= dd->nc[d]) { char error_string[STRLEN]; sprintf(error_string, - "The box size in direction %c (%f) times the triclinic skew factor (%f) is too small for a cut-off of %f with %d domain decomposition cells, use 1 or more than %d %s or increase the box size in this direction", - dim2char(d), ddbox->box_size[d], ddbox->skew_fac[d], - comm->systemInfo.cutoff, - dd->nc[d], dd->nc[d], - dd->nnodes > dd->nc[d] ? "cells" : "ranks"); + "The box size in direction %c (%f) times the triclinic skew factor (%f) is too " + "small for a cut-off of %f with %d domain decomposition cells, use 1 or more " + "than %d %s or increase the box size in this direction", + dim2char(d), ddbox->box_size[d], ddbox->skew_fac[d], comm->systemInfo.cutoff, + dd->nc[d], dd->nc[d], dd->nnodes > dd->nc[d] ? "cells" : "ranks"); if (setmode == setcellsizeslbLOCAL) { - gmx_fatal_collective(FARGS, dd->mpi_comm_all, DDMASTER(dd), - "%s", error_string); + gmx_fatal_collective(FARGS, dd->mpi_comm_all, DDMASTER(dd), "%s", error_string); } else { @@ -322,11 +313,10 @@ set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, copy_rvec(cellsize_min, comm->cellsize_min); } - DDRankSetup &ddRankSetup = comm->ddRankSetup; + DDRankSetup& ddRankSetup = comm->ddRankSetup; for (int d = 0; d < ddRankSetup.npmedecompdim; d++) { - set_pme_maxshift(dd, &ddRankSetup.ddpme[d], - comm->slb_frac[dd->dim[d]] == nullptr, ddbox, + set_pme_maxshift(dd, &ddRankSetup.ddpme[d], comm->slb_frac[dd->dim[d]] == nullptr, ddbox, ddRankSetup.ddpme[d].slb_dim_f); } @@ -334,26 +324,31 @@ set_dd_cell_sizes_slb(gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, } -static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, - int d, int dim, RowMaster *rowMaster, - const gmx_ddbox_t *ddbox, - gmx_bool bUniform, int64_t step, real cellsize_limit_f, int range[]) +static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t* dd, + int d, + int dim, + RowMaster* rowMaster, + const gmx_ddbox_t* ddbox, + gmx_bool bUniform, + int64_t step, + real cellsize_limit_f, + int range[]) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; real halfway, cellsize_limit_f_i, region_size; gmx_bool bLastHi = FALSE; - int nrange[] = {range[0], range[1]}; + int nrange[] = { range[0], range[1] }; region_size = rowMaster->cellFrac[range[1]] - rowMaster->cellFrac[range[0]]; - GMX_ASSERT(region_size >= (range[1] - range[0])*cellsize_limit_f, + GMX_ASSERT(region_size >= (range[1] - range[0]) * cellsize_limit_f, "The region should fit all cells at minimum size"); comm = dd->comm; - const int ncd = dd->nc[dim]; + const int ncd = dd->nc[dim]; - const bool dimHasPbc = (dim < ddbox->npbcdim); + const bool dimHasPbc = (dim < ddbox->npbcdim); gmx::ArrayRef cell_size = rowMaster->buf_ncd; @@ -388,7 +383,8 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, } /* This condition is ensured by the assertion at the end of the loop */ GMX_ASSERT(fac > 0, "We cannot have 0 size to work with"); - fac = (region_size - nmin*cellsize_limit_f)/fac; /* substracting cells already set to cellsize_limit_f */ + fac = (region_size - nmin * cellsize_limit_f) + / fac; /* substracting cells already set to cellsize_limit_f */ /* Determine the cell boundaries */ for (int i = range[0]; i < range[1]; i++) { @@ -415,8 +411,7 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, /* This is ensured by the assertion at the beginning of this function */ GMX_ASSERT(nmin < range[1] - range[0], "We can not have all cells limited"); - } - while (nmin > nmin_old); + } while (nmin > nmin_old); const int i = range[1] - 1; cell_size[i] = rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]; @@ -424,14 +419,14 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, * but a slightly smaller factor, * since rounding could get use below the limit. */ - if (dimHasPbc && - cell_size[i] < cellsize_limit_f*DD_CELL_MARGIN2/DD_CELL_MARGIN) + if (dimHasPbc && cell_size[i] < cellsize_limit_f * DD_CELL_MARGIN2 / DD_CELL_MARGIN) { char buf[22]; - gmx_fatal(FARGS, "step %s: the dynamic load balancing could not balance dimension %c: box size %f, triclinic skew factor %f, #cells %d, minimum cell size %f\n", - gmx_step_str(step, buf), - dim2char(dim), ddbox->box_size[dim], ddbox->skew_fac[dim], - ncd, comm->cellsize_min[dim]); + gmx_fatal(FARGS, + "step %s: the dynamic load balancing could not balance dimension %c: box size " + "%f, triclinic skew factor %f, #cells %d, minimum cell size %f\n", + gmx_step_str(step, buf), dim2char(dim), ddbox->box_size[dim], + ddbox->skew_fac[dim], ncd, comm->cellsize_min[dim]); } rowMaster->dlbIsLimited = (nmin > 0) || (range[0] > 0) || (range[1] < ncd); @@ -446,9 +441,9 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, * might be affected by a change and if the old state was ok, * the cells will at most be shrunk back to their old size. */ - for (int i = range[0]+1; i < range[1]; i++) + for (int i = range[0] + 1; i < range[1]; i++) { - halfway = 0.5*(rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i - 1]); + halfway = 0.5 * (rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i - 1]); if (rowMaster->cellFrac[i] < halfway) { rowMaster->cellFrac[i] = halfway; @@ -457,11 +452,11 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, { if (rowMaster->cellFrac[j] < rowMaster->cellFrac[j - 1] + cellsize_limit_f) { - rowMaster->cellFrac[j] = rowMaster->cellFrac[j - 1] + cellsize_limit_f; + rowMaster->cellFrac[j] = rowMaster->cellFrac[j - 1] + cellsize_limit_f; } } } - halfway = 0.5*(rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i + 1]); + halfway = 0.5 * (rowMaster->oldCellFrac[i] + rowMaster->oldCellFrac[i + 1]); if (rowMaster->cellFrac[i] > halfway) { rowMaster->cellFrac[i] = halfway; @@ -478,9 +473,9 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, } /* nrange is defined as [lower, upper) range for new call to enforce_limits */ - /* find highest violation of LimLo (a) and the following violation of LimHi (thus the lowest following) (b) - * then call enforce_limits for (oldb,a), (a,b). In the next step: (b,nexta). oldb and nexta can be the boundaries. - * for a and b nrange is used */ + /* find highest violation of LimLo (a) and the following violation of LimHi (thus the lowest + * following) (b) then call enforce_limits for (oldb,a), (a,b). In the next step: (b,nexta). + * oldb and nexta can be the boundaries. for a and b nrange is used */ if (d > 0) { /* Take care of the staggering of the cell boundaries */ @@ -496,80 +491,90 @@ static void dd_cell_sizes_dlb_root_enforce_limits(gmx_domdec_t *dd, { for (int i = range[0] + 1; i < range[1]; i++) { - const RowMaster::Bounds &bounds = rowMaster->bounds[i]; + const RowMaster::Bounds& bounds = rowMaster->bounds[i]; - bool bLimLo = (rowMaster->cellFrac[i] < bounds.boundMin); - bool bLimHi = (rowMaster->cellFrac[i] > bounds.boundMax); + bool bLimLo = (rowMaster->cellFrac[i] < bounds.boundMin); + bool bLimHi = (rowMaster->cellFrac[i] > bounds.boundMax); if (bLimLo && bLimHi) { /* Both limits violated, try the best we can */ /* For this case we split the original range (range) in two parts and care about the other limitiations in the next iteration. */ - rowMaster->cellFrac[i] = 0.5*(bounds.boundMin + bounds.boundMax); + rowMaster->cellFrac[i] = 0.5 * (bounds.boundMin + bounds.boundMax); nrange[0] = range[0]; nrange[1] = i; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, + step, cellsize_limit_f, nrange); nrange[0] = i; nrange[1] = range[1]; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, + step, cellsize_limit_f, nrange); return; } else if (bLimLo) { /* rowMaster->cellFrac[i] = rowMaster->boundMin[i]; */ - nrange[1] = i; /* only store violation location. There could be a LimLo violation following with an higher index */ + nrange[1] = i; /* only store violation location. There could be a LimLo violation following with an higher index */ bLastHi = FALSE; } else if (bLimHi && !bLastHi) { bLastHi = TRUE; - if (nrange[1] < range[1]) /* found a LimLo before */ + if (nrange[1] < range[1]) /* found a LimLo before */ { rowMaster->cellFrac[nrange[1]] = rowMaster->bounds[nrange[1]].boundMin; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, + step, cellsize_limit_f, nrange); nrange[0] = nrange[1]; } rowMaster->cellFrac[i] = rowMaster->bounds[i].boundMax; nrange[1] = i; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, + step, cellsize_limit_f, nrange); nrange[0] = i; nrange[1] = range[1]; } } - if (nrange[1] < range[1]) /* found last a LimLo */ + if (nrange[1] < range[1]) /* found last a LimLo */ { rowMaster->cellFrac[nrange[1]] = rowMaster->bounds[nrange[1]].boundMin; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, + cellsize_limit_f, nrange); nrange[0] = nrange[1]; nrange[1] = range[1]; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, + cellsize_limit_f, nrange); } else if (nrange[0] > range[0]) /* found at least one LimHi */ { - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, nrange); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, + cellsize_limit_f, nrange); } } } } -static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, - int d, int dim, RowMaster *rowMaster, - const gmx_ddbox_t *ddbox, - gmx_bool bDynamicBox, - gmx_bool bUniform, int64_t step) +static void set_dd_cell_sizes_dlb_root(gmx_domdec_t* dd, + int d, + int dim, + RowMaster* rowMaster, + const gmx_ddbox_t* ddbox, + gmx_bool bDynamicBox, + gmx_bool bUniform, + int64_t step) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; constexpr real c_relax = 0.5; int range[] = { 0, 0 }; /* Convert the maximum change from the input percentage to a fraction */ - const real change_limit = comm->ddSettings.dlb_scale_lim*0.01; + const real change_limit = comm->ddSettings.dlb_scale_lim * 0.01; - const int ncd = dd->nc[dim]; + const int ncd = dd->nc[dim]; - const bool bPBC = (dim < ddbox->npbcdim); + const bool bPBC = (dim < ddbox->npbcdim); gmx::ArrayRef cell_size = rowMaster->buf_ncd; @@ -582,22 +587,22 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, { for (int i = 0; i < ncd; i++) { - cell_size[i] = 1.0/ncd; + cell_size[i] = 1.0 / ncd; } } else if (dd_load_count(comm) > 0) { - real load_aver = comm->load[d].sum_m/ncd; + real load_aver = comm->load[d].sum_m / ncd; real change_max = 0; real load_i; real change; for (int i = 0; i < ncd; i++) { /* Determine the relative imbalance of cell i */ - load_i = comm->load[d].load[i*comm->load[d].nload+2]; - real imbalance = (load_i - load_aver)/(load_aver > 0 ? load_aver : 1); + load_i = comm->load[d].load[i * comm->load[d].nload + 2]; + real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1); /* Determine the change of the cell size using underrelaxation */ - change = -c_relax*imbalance; + change = -c_relax * imbalance; change_max = std::max(change_max, std::max(change, -change)); } /* Limit the amount of scaling. @@ -607,27 +612,27 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, real sc = c_relax; if (change_max > change_limit) { - sc *= change_limit/change_max; + sc *= change_limit / change_max; } for (int i = 0; i < ncd; i++) { /* Determine the relative imbalance of cell i */ - load_i = comm->load[d].load[i*comm->load[d].nload+2]; - real imbalance = (load_i - load_aver)/(load_aver > 0 ? load_aver : 1); + load_i = comm->load[d].load[i * comm->load[d].nload + 2]; + real imbalance = (load_i - load_aver) / (load_aver > 0 ? load_aver : 1); /* Determine the change of the cell size using underrelaxation */ - change = -sc*imbalance; - cell_size[i] = (rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i])*(1 + change); + change = -sc * imbalance; + cell_size[i] = (rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]) * (1 + change); } } - real cellsize_limit_f = cellsize_min_dlb(comm, d, dim)/ddbox->box_size[dim]; - cellsize_limit_f *= DD_CELL_MARGIN; - real dist_min_f_hard = grid_jump_limit(comm, comm->systemInfo.cutoff, d)/ddbox->box_size[dim]; - real dist_min_f = dist_min_f_hard * DD_CELL_MARGIN; + real cellsize_limit_f = cellsize_min_dlb(comm, d, dim) / ddbox->box_size[dim]; + cellsize_limit_f *= DD_CELL_MARGIN; + real dist_min_f_hard = grid_jump_limit(comm, comm->systemInfo.cutoff, d) / ddbox->box_size[dim]; + real dist_min_f = dist_min_f_hard * DD_CELL_MARGIN; if (ddbox->tric_dir[dim]) { cellsize_limit_f /= ddbox->skew_fac[dim]; - dist_min_f /= ddbox->skew_fac[dim]; + dist_min_f /= ddbox->skew_fac[dim]; } if (bDynamicBox && d > 0) { @@ -638,40 +643,38 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, /* Make sure that the grid is not shifted too much */ for (int i = 1; i < ncd; i++) { - const RowMaster::Bounds &boundsNeighbor = rowMaster->bounds[i - 1]; - RowMaster::Bounds &bounds = rowMaster->bounds[i]; + const RowMaster::Bounds& boundsNeighbor = rowMaster->bounds[i - 1]; + RowMaster::Bounds& bounds = rowMaster->bounds[i]; if (bounds.cellFracUpperMin - boundsNeighbor.cellFracLowerMax < 2 * dist_min_f_hard) { gmx_incons("Inconsistent DD boundary staggering limits!"); } bounds.boundMin = boundsNeighbor.cellFracLowerMax + dist_min_f; - real space = rowMaster->cellFrac[i] - (boundsNeighbor.cellFracLowerMax + dist_min_f); + real space = rowMaster->cellFrac[i] - (boundsNeighbor.cellFracLowerMax + dist_min_f); if (space > 0) { - bounds.boundMin += 0.5*space; + bounds.boundMin += 0.5 * space; } - bounds.boundMax = bounds.cellFracUpperMin - dist_min_f; - space = rowMaster->cellFrac[i] - (bounds.cellFracUpperMin - dist_min_f); + bounds.boundMax = bounds.cellFracUpperMin - dist_min_f; + space = rowMaster->cellFrac[i] - (bounds.cellFracUpperMin - dist_min_f); if (space < 0) { - rowMaster->bounds[i].boundMax += 0.5*space; + rowMaster->bounds[i].boundMax += 0.5 * space; } if (debug) { - fprintf(debug, - "dim %d boundary %d %.3f < %.3f < %.3f < %.3f < %.3f\n", - d, i, - boundsNeighbor.cellFracLowerMax + dist_min_f, - bounds.boundMin, rowMaster->cellFrac[i], bounds.boundMax, - bounds.cellFracUpperMin - dist_min_f); + fprintf(debug, "dim %d boundary %d %.3f < %.3f < %.3f < %.3f < %.3f\n", d, i, + boundsNeighbor.cellFracLowerMax + dist_min_f, bounds.boundMin, + rowMaster->cellFrac[i], bounds.boundMax, bounds.cellFracUpperMin - dist_min_f); } } } range[1] = ncd; rowMaster->cellFrac[0] = 0; rowMaster->cellFrac[ncd] = 1; - dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, cellsize_limit_f, range); + dd_cell_sizes_dlb_root_enforce_limits(dd, d, dim, rowMaster, ddbox, bUniform, step, + cellsize_limit_f, range); /* After the checks above, the cells should obey the cut-off @@ -681,20 +684,18 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, { if (debug) { - fprintf(debug, "Relative bounds dim %d cell %d: %f %f\n", - dim, i, rowMaster->cellFrac[i], rowMaster->cellFrac[i + 1]); + fprintf(debug, "Relative bounds dim %d cell %d: %f %f\n", dim, i, + rowMaster->cellFrac[i], rowMaster->cellFrac[i + 1]); } - if ((bPBC || (i != 0 && i != dd->nc[dim]-1)) && - rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i] < - cellsize_limit_f/DD_CELL_MARGIN) + if ((bPBC || (i != 0 && i != dd->nc[dim] - 1)) + && rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i] < cellsize_limit_f / DD_CELL_MARGIN) { char buf[22]; - fprintf(stderr, - "\nWARNING step %s: direction %c, cell %d too small: %f\n", + fprintf(stderr, "\nWARNING step %s: direction %c, cell %d too small: %f\n", gmx_step_str(step, buf), dim2char(dim), i, - (rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]) - *ddbox->box_size[dim]*ddbox->skew_fac[dim]); + (rowMaster->cellFrac[i + 1] - rowMaster->cellFrac[i]) * ddbox->box_size[dim] + * ddbox->skew_fac[dim]); } } @@ -706,7 +707,7 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, rowMaster->cellFrac[pos++] = comm->cellsizesWithDlb[d1].fracUpper; } - DDRankSetup &ddRankSetup = comm->ddRankSetup; + DDRankSetup& ddRankSetup = comm->ddRankSetup; if (d < ddRankSetup.npmedecompdim) { /* The master determines the maximum shift for @@ -721,17 +722,15 @@ static void set_dd_cell_sizes_dlb_root(gmx_domdec_t *dd, } } -static void relative_to_absolute_cell_bounds(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, - int dimind) +static void relative_to_absolute_cell_bounds(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox, int dimind) { - gmx_domdec_comm_t *comm = dd->comm; - const DDCellsizesWithDlb &cellsizes = comm->cellsizesWithDlb[dimind]; + gmx_domdec_comm_t* comm = dd->comm; + const DDCellsizesWithDlb& cellsizes = comm->cellsizesWithDlb[dimind]; /* Set the cell dimensions */ int dim = dd->dim[dimind]; - comm->cell_x0[dim] = cellsizes.fracLower*ddbox->box_size[dim]; - comm->cell_x1[dim] = cellsizes.fracUpper*ddbox->box_size[dim]; + comm->cell_x0[dim] = cellsizes.fracLower * ddbox->box_size[dim]; + comm->cell_x1[dim] = cellsizes.fracUpper * ddbox->box_size[dim]; if (dim >= ddbox->nboundeddim) { comm->cell_x0[dim] += ddbox->box0[dim]; @@ -739,22 +738,23 @@ static void relative_to_absolute_cell_bounds(gmx_domdec_t *dd, } } -static void distribute_dd_cell_sizes_dlb(gmx_domdec_t *dd, - int d, int dim, +static void distribute_dd_cell_sizes_dlb(gmx_domdec_t* dd, + int d, + int dim, gmx::ArrayRef cellFracRow, - const gmx_ddbox_t *ddbox) + const gmx_ddbox_t* ddbox) { - gmx_domdec_comm_t &comm = *dd->comm; + gmx_domdec_comm_t& comm = *dd->comm; #if GMX_MPI /* Each node would only need to know two fractions, * but it is probably cheaper to broadcast the whole array. */ - MPI_Bcast(cellFracRow.data(), ddCellFractionBufferSize(dd, d)*sizeof(real), MPI_BYTE, - 0, comm.mpi_comm_load[d]); + MPI_Bcast(cellFracRow.data(), ddCellFractionBufferSize(dd, d) * sizeof(real), MPI_BYTE, 0, + comm.mpi_comm_load[d]); #endif /* Copy the fractions for this dimension from the buffer */ - comm.cellsizesWithDlb[d].fracLower = cellFracRow[dd->ci[dim] ]; + comm.cellsizesWithDlb[d].fracLower = cellFracRow[dd->ci[dim]]; comm.cellsizesWithDlb[d].fracUpper = cellFracRow[dd->ci[dim] + 1]; /* The whole array was communicated, so set the buffer position */ int pos = dd->nc[dim] + 1; @@ -776,10 +776,11 @@ static void distribute_dd_cell_sizes_dlb(gmx_domdec_t *dd, } } -static void set_dd_cell_sizes_dlb_change(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, - gmx_bool bDynamicBox, - gmx_bool bUniform, int64_t step) +static void set_dd_cell_sizes_dlb_change(gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + gmx_bool bDynamicBox, + gmx_bool bUniform, + int64_t step) { for (int d = 0; d < dd->ndim; d++) { @@ -799,14 +800,13 @@ static void set_dd_cell_sizes_dlb_change(gmx_domdec_t *dd, } if (isRowMember) { - DDCellsizesWithDlb &cellsizes = dd->comm->cellsizesWithDlb[d]; - gmx::ArrayRef cellFracRow; + DDCellsizesWithDlb& cellsizes = dd->comm->cellsizesWithDlb[d]; + gmx::ArrayRef cellFracRow; if (isRowRoot) { - RowMaster *rowMaster = cellsizes.rowMaster.get(); - set_dd_cell_sizes_dlb_root(dd, d, dim, rowMaster, - ddbox, bDynamicBox, bUniform, step); + RowMaster* rowMaster = cellsizes.rowMaster.get(); + set_dd_cell_sizes_dlb_root(dd, d, dim, rowMaster, ddbox, bDynamicBox, bUniform, step); cellFracRow = rowMaster->cellFrac; } else @@ -818,8 +818,7 @@ static void set_dd_cell_sizes_dlb_change(gmx_domdec_t *dd, } } -static void set_dd_cell_sizes_dlb_nochange(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox) +static void set_dd_cell_sizes_dlb_nochange(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox) { int d; @@ -834,13 +833,15 @@ static void set_dd_cell_sizes_dlb_nochange(gmx_domdec_t *dd, } - -static void set_dd_cell_sizes_dlb(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, gmx_bool bDynamicBox, - gmx_bool bUniform, gmx_bool bDoDLB, int64_t step, - gmx_wallcycle_t wcycle) +static void set_dd_cell_sizes_dlb(gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + gmx_bool bDynamicBox, + gmx_bool bUniform, + gmx_bool bDoDLB, + int64_t step, + gmx_wallcycle_t wcycle) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int dim; comm = dd->comm; @@ -872,12 +873,15 @@ static void set_dd_cell_sizes_dlb(gmx_domdec_t *dd, } } -void set_dd_cell_sizes(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, gmx_bool bDynamicBox, - gmx_bool bUniform, gmx_bool bDoDLB, int64_t step, - gmx_wallcycle_t wcycle) +void set_dd_cell_sizes(gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + gmx_bool bDynamicBox, + gmx_bool bUniform, + gmx_bool bDoDLB, + int64_t step, + gmx_wallcycle_t wcycle) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; /* Copy the old cell boundaries for the cg displacement check */ copy_rvec(comm->cell_x0, comm->old_cell_x0); @@ -901,13 +905,15 @@ void set_dd_cell_sizes(gmx_domdec_t *dd, */ for (int d = 0; d < dd->ndim; d++) { - gmx_domdec_comm_dim_t &cd = comm->cd[d]; + gmx_domdec_comm_dim_t& cd = comm->cd[d]; int numPulsesDim = numPulses[dd->dim[d]]; if (cd.numPulses() != numPulsesDim) { if (debug) { - fprintf(debug, "Changing the number of halo communication pulses along dim %c from %d to %d\n", + fprintf(debug, + "Changing the number of halo communication pulses along dim %c from %d " + "to %d\n", dim2char(dd->dim[d]), cd.numPulses(), numPulsesDim); } cd.ind.resize(numPulsesDim); @@ -919,8 +925,8 @@ void set_dd_cell_sizes(gmx_domdec_t *dd, { for (int d = 0; d < DIM; d++) { - fprintf(debug, "cell_x[%d] %f - %f skew_fac %f\n", - d, comm->cell_x0[d], comm->cell_x1[d], ddbox->skew_fac[d]); + fprintf(debug, "cell_x[%d] %f - %f skew_fac %f\n", d, comm->cell_x0[d], + comm->cell_x1[d], ddbox->skew_fac[d]); } } } diff --git a/src/gromacs/domdec/cellsizes.h b/src/gromacs/domdec/cellsizes.h index 9238f01332..d35da8357f 100644 --- a/src/gromacs/domdec/cellsizes.h +++ b/src/gromacs/domdec/cellsizes.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,15 +56,13 @@ struct gmx_domdec_t; /*! \brief Options for setting up a regular, possibly static load balanced, cell grid geometry */ enum { - setcellsizeslbLOCAL, //!< Set cell sizes locally on each rank - setcellsizeslbMASTER, //!< Set cell sizes on master rank only - setcellsizeslbPULSE_ONLY //!< Only set the communication pulses, not the cell sizes + setcellsizeslbLOCAL, //!< Set cell sizes locally on each rank + setcellsizeslbMASTER, //!< Set cell sizes on master rank only + setcellsizeslbPULSE_ONLY //!< Only set the communication pulses, not the cell sizes }; /*! \brief Returns the minimum allowed distance between lower and upper bounds of zones along dimension dim_ind */ -real grid_jump_limit(const gmx_domdec_comm_t *comm, - real cutoff, - int dim_ind); +real grid_jump_limit(const gmx_domdec_comm_t* comm, real cutoff, int dim_ind); /*! \brief Sets up an initial, non-staggered grid geometry, possibly using static load balancing * @@ -72,16 +70,16 @@ real grid_jump_limit(const gmx_domdec_comm_t *comm, * When setmode==setcellsizeslbMASTER, the cell boundaries per dimension are * returned, otherwise an empty arrayref is returned. */ -gmx::ArrayRef < const std::vector < real>> -set_dd_cell_sizes_slb(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, - int setmode, - ivec numPulses); +gmx::ArrayRef> +set_dd_cell_sizes_slb(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox, int setmode, ivec numPulses); /*! \brief General cell size adjustment, possibly applying dynamic load balancing */ -void set_dd_cell_sizes(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, gmx_bool bDynamicBox, - gmx_bool bUniform, gmx_bool bDoDLB, int64_t step, - gmx_wallcycle_t wcycle); +void set_dd_cell_sizes(gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + gmx_bool bDynamicBox, + gmx_bool bUniform, + gmx_bool bDoDLB, + int64_t step, + gmx_wallcycle_t wcycle); #endif diff --git a/src/gromacs/domdec/collect.cpp b/src/gromacs/domdec/collect.cpp index 5463864739..431fe7f9fa 100644 --- a/src/gromacs/domdec/collect.cpp +++ b/src/gromacs/domdec/collect.cpp @@ -55,8 +55,7 @@ #include "distribute.h" #include "domdec_internal.h" -static void dd_collect_cg(gmx_domdec_t *dd, - const t_state *state_local) +static void dd_collect_cg(gmx_domdec_t* dd, const t_state* state_local) { if (state_local->ddp_count == dd->comm->master_cg_ddp_count) { @@ -83,29 +82,31 @@ static void dd_collect_cg(gmx_domdec_t *dd, } else { - gmx_incons("Attempted to collect a vector for a state for which the charge group distribution is unknown"); + gmx_incons( + "Attempted to collect a vector for a state for which the charge group distribution " + "is unknown"); } - AtomDistribution *ma = dd->ma.get(); + AtomDistribution* ma = dd->ma.get(); /* Collect the charge group and atom counts on the master */ int localBuffer[2] = { static_cast(atomGroups.size()), nat_home }; - dd_gather(dd, 2*sizeof(int), localBuffer, - DDMASTER(dd) ? ma->intBuffer.data() : nullptr); + dd_gather(dd, 2 * sizeof(int), localBuffer, DDMASTER(dd) ? ma->intBuffer.data() : nullptr); if (DDMASTER(dd)) { int groupOffset = 0; for (int rank = 0; rank < dd->nnodes; rank++) { - auto &domainGroups = ma->domainGroups[rank]; - int numGroups = ma->intBuffer[2*rank]; + auto& domainGroups = ma->domainGroups[rank]; + int numGroups = ma->intBuffer[2 * rank]; - domainGroups.atomGroups = gmx::constArrayRefFromArray(ma->atomGroups.data() + groupOffset, numGroups); + domainGroups.atomGroups = + gmx::constArrayRefFromArray(ma->atomGroups.data() + groupOffset, numGroups); - domainGroups.numAtoms = ma->intBuffer[2*rank + 1]; + domainGroups.numAtoms = ma->intBuffer[2 * rank + 1]; - groupOffset += numGroups; + groupOffset += numGroups; } if (debug) @@ -122,16 +123,15 @@ static void dd_collect_cg(gmx_domdec_t *dd, int offset = 0; for (int rank = 0; rank < dd->nnodes; rank++) { - int numGroups = ma->domainGroups[rank].atomGroups.size(); - ma->intBuffer[rank] = numGroups*sizeof(int); - ma->intBuffer[dd->nnodes + rank] = offset*sizeof(int); - offset += numGroups; + int numGroups = ma->domainGroups[rank].atomGroups.size(); + ma->intBuffer[rank] = numGroups * sizeof(int); + ma->intBuffer[dd->nnodes + rank] = offset * sizeof(int); + offset += numGroups; } } /* Collect the charge group indices on the master */ - dd_gatherv(dd, - atomGroups.size()*sizeof(int), atomGroups.data(), + dd_gatherv(dd, atomGroups.size() * sizeof(int), atomGroups.data(), DDMASTER(dd) ? ma->intBuffer.data() : nullptr, DDMASTER(dd) ? ma->intBuffer.data() + dd->nnodes : nullptr, DDMASTER(dd) ? ma->atomGroups.data() : nullptr); @@ -139,7 +139,7 @@ static void dd_collect_cg(gmx_domdec_t *dd, dd->comm->master_cg_ddp_count = state_local->ddp_count; } -static void dd_collect_vec_sendrecv(gmx_domdec_t *dd, +static void dd_collect_vec_sendrecv(gmx_domdec_t* dd, gmx::ArrayRef lv, gmx::ArrayRef v) { @@ -147,17 +147,17 @@ static void dd_collect_vec_sendrecv(gmx_domdec_t *dd, { #if GMX_MPI const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms(); - MPI_Send(const_cast(static_cast(lv.data())), numHomeAtoms*sizeof(rvec), MPI_BYTE, - dd->masterrank, dd->rank, dd->mpi_comm_all); + MPI_Send(const_cast(static_cast(lv.data())), + numHomeAtoms * sizeof(rvec), MPI_BYTE, dd->masterrank, dd->rank, dd->mpi_comm_all); #endif } else { - AtomDistribution &ma = *dd->ma; + AtomDistribution& ma = *dd->ma; - int rank = dd->masterrank; - int localAtom = 0; - for (const int &globalAtom : ma.domainGroups[rank].atomGroups) + int rank = dd->masterrank; + int localAtom = 0; + for (const int& globalAtom : ma.domainGroups[rank].atomGroups) { copy_rvec(lv[localAtom++], v[globalAtom]); } @@ -166,9 +166,10 @@ static void dd_collect_vec_sendrecv(gmx_domdec_t *dd, { if (rank != dd->rank) { - const auto &domainGroups = ma.domainGroups[rank]; + const auto& domainGroups = ma.domainGroups[rank]; - GMX_RELEASE_ASSERT(v.data() != ma.rvecBuffer.data(), "We need different communication and return buffers"); + GMX_RELEASE_ASSERT(v.data() != ma.rvecBuffer.data(), + "We need different communication and return buffers"); /* When we send/recv instead of scatter/gather, we might need * to increase the communication buffer size here. @@ -179,11 +180,11 @@ static void dd_collect_vec_sendrecv(gmx_domdec_t *dd, } #if GMX_MPI - MPI_Recv(ma.rvecBuffer.data(), domainGroups.numAtoms*sizeof(rvec), MPI_BYTE, rank, + MPI_Recv(ma.rvecBuffer.data(), domainGroups.numAtoms * sizeof(rvec), MPI_BYTE, rank, rank, dd->mpi_comm_all, MPI_STATUS_IGNORE); #endif int localAtom = 0; - for (const int &globalAtom : domainGroups.atomGroups) + for (const int& globalAtom : domainGroups.atomGroups) { copy_rvec(ma.rvecBuffer[localAtom++], v[globalAtom]); } @@ -192,12 +193,12 @@ static void dd_collect_vec_sendrecv(gmx_domdec_t *dd, } } -static void dd_collect_vec_gatherv(gmx_domdec_t *dd, +static void dd_collect_vec_gatherv(gmx_domdec_t* dd, gmx::ArrayRef lv, gmx::ArrayRef v) { - int *recvCounts = nullptr; - int *displacements = nullptr; + int* recvCounts = nullptr; + int* displacements = nullptr; if (DDMASTER(dd)) { @@ -205,18 +206,18 @@ static void dd_collect_vec_gatherv(gmx_domdec_t *dd, } const int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms(); - dd_gatherv(dd, numHomeAtoms*sizeof(rvec), lv.data(), recvCounts, displacements, + dd_gatherv(dd, numHomeAtoms * sizeof(rvec), lv.data(), recvCounts, displacements, DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr); if (DDMASTER(dd)) { - const AtomDistribution &ma = *dd->ma; + const AtomDistribution& ma = *dd->ma; - int bufferAtom = 0; + int bufferAtom = 0; for (int rank = 0; rank < dd->nnodes; rank++) { - const auto &domainGroups = ma.domainGroups[rank]; - for (const int &globalAtom : domainGroups.atomGroups) + const auto& domainGroups = ma.domainGroups[rank]; + for (const int& globalAtom : domainGroups.atomGroups) { copy_rvec(ma.rvecBuffer[bufferAtom++], v[globalAtom]); } @@ -224,8 +225,8 @@ static void dd_collect_vec_gatherv(gmx_domdec_t *dd, } } -void dd_collect_vec(gmx_domdec_t *dd, - const t_state *state_local, +void dd_collect_vec(gmx_domdec_t* dd, + const t_state* state_local, gmx::ArrayRef lv, gmx::ArrayRef v) { @@ -242,14 +243,14 @@ void dd_collect_vec(gmx_domdec_t *dd, } -void dd_collect_state(gmx_domdec_t *dd, - const t_state *state_local, t_state *state) +void dd_collect_state(gmx_domdec_t* dd, const t_state* state_local, t_state* state) { int nh = state_local->nhchainlength; if (DDMASTER(dd)) { - GMX_RELEASE_ASSERT(state->nhchainlength == nh, "The global and local Nose-Hoover chain lengths should match"); + GMX_RELEASE_ASSERT(state->nhchainlength == nh, + "The global and local Nose-Hoover chain lengths should match"); for (int i = 0; i < efptNR; i++) { @@ -268,8 +269,8 @@ void dd_collect_state(gmx_domdec_t *dd, { for (int j = 0; j < nh; j++) { - state->nosehoover_xi[i*nh+j] = state_local->nosehoover_xi[i*nh+j]; - state->nosehoover_vxi[i*nh+j] = state_local->nosehoover_vxi[i*nh+j]; + state->nosehoover_xi[i * nh + j] = state_local->nosehoover_xi[i * nh + j]; + state->nosehoover_vxi[i * nh + j] = state_local->nosehoover_vxi[i * nh + j]; } state->therm_integral[i] = state_local->therm_integral[i]; } @@ -277,12 +278,12 @@ void dd_collect_state(gmx_domdec_t *dd, { for (int j = 0; j < nh; j++) { - state->nhpres_xi[i*nh+j] = state_local->nhpres_xi[i*nh+j]; - state->nhpres_vxi[i*nh+j] = state_local->nhpres_vxi[i*nh+j]; + state->nhpres_xi[i * nh + j] = state_local->nhpres_xi[i * nh + j]; + state->nhpres_vxi[i * nh + j] = state_local->nhpres_vxi[i * nh + j]; } } - state->baros_integral = state_local->baros_integral; - state->pull_com_prev_step = state_local->pull_com_prev_step; + state->baros_integral = state_local->baros_integral; + state->pull_com_prev_step = state_local->pull_com_prev_step; } if (state_local->flags & (1 << estX)) { diff --git a/src/gromacs/domdec/collect.h b/src/gromacs/domdec/collect.h index 1a319d4cb5..4d4b3b766f 100644 --- a/src/gromacs/domdec/collect.h +++ b/src/gromacs/domdec/collect.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,14 +50,12 @@ struct gmx_domdec_t; class t_state; /*! \brief Gathers rvec arrays \p localVector to \p globalVector on the master rank */ -void dd_collect_vec(gmx_domdec_t *dd, - const t_state *localState, - gmx::ArrayRef localVector, - gmx::ArrayRef globalVector); +void dd_collect_vec(gmx_domdec_t* dd, + const t_state* localState, + gmx::ArrayRef localVector, + gmx::ArrayRef globalVector); /*! \brief Gathers state \p localState to \p globalState on the master rank */ -void dd_collect_state(gmx_domdec_t *dd, - const t_state *localState, - t_state *globalState); +void dd_collect_state(gmx_domdec_t* dd, const t_state* localState, t_state* globalState); #endif diff --git a/src/gromacs/domdec/distribute.cpp b/src/gromacs/domdec/distribute.cpp index 4bd48ac93f..50b17507ce 100644 --- a/src/gromacs/domdec/distribute.cpp +++ b/src/gromacs/domdec/distribute.cpp @@ -62,9 +62,9 @@ #include "domdec_internal.h" #include "utility.h" -static void distributeVecSendrecv(gmx_domdec_t *dd, - gmx::ArrayRef globalVec, - gmx::ArrayRef localVec) +static void distributeVecSendrecv(gmx_domdec_t* dd, + gmx::ArrayRef globalVec, + gmx::ArrayRef localVec) { if (DDMASTER(dd)) { @@ -74,27 +74,28 @@ static void distributeVecSendrecv(gmx_domdec_t *dd, { if (rank != dd->rank) { - const auto &domainGroups = dd->ma->domainGroups[rank]; + const auto& domainGroups = dd->ma->domainGroups[rank]; buffer.resize(domainGroups.numAtoms); - int localAtom = 0; - for (const int &globalAtom : domainGroups.atomGroups) + int localAtom = 0; + for (const int& globalAtom : domainGroups.atomGroups) { buffer[localAtom++] = globalVec[globalAtom]; } - GMX_RELEASE_ASSERT(localAtom == domainGroups.numAtoms, "The index count and number of indices should match"); + GMX_RELEASE_ASSERT(localAtom == domainGroups.numAtoms, + "The index count and number of indices should match"); #if GMX_MPI - MPI_Send(buffer.data(), domainGroups.numAtoms*sizeof(gmx::RVec), MPI_BYTE, - rank, rank, dd->mpi_comm_all); + MPI_Send(buffer.data(), domainGroups.numAtoms * sizeof(gmx::RVec), MPI_BYTE, rank, + rank, dd->mpi_comm_all); #endif } } - const auto &domainGroups = dd->ma->domainGroups[dd->masterrank]; + const auto& domainGroups = dd->ma->domainGroups[dd->masterrank]; int localAtom = 0; - for (const int &globalAtom : domainGroups.atomGroups) + for (const int& globalAtom : domainGroups.atomGroups) { localVec[localAtom++] = globalVec[globalAtom]; } @@ -103,31 +104,31 @@ static void distributeVecSendrecv(gmx_domdec_t *dd, { #if GMX_MPI int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms(); - MPI_Recv(localVec.data(), numHomeAtoms*sizeof(gmx::RVec), MPI_BYTE, dd->masterrank, + MPI_Recv(localVec.data(), numHomeAtoms * sizeof(gmx::RVec), MPI_BYTE, dd->masterrank, MPI_ANY_TAG, dd->mpi_comm_all, MPI_STATUS_IGNORE); #endif } } -static void distributeVecScatterv(gmx_domdec_t *dd, - gmx::ArrayRef globalVec, - gmx::ArrayRef localVec) +static void distributeVecScatterv(gmx_domdec_t* dd, + gmx::ArrayRef globalVec, + gmx::ArrayRef localVec) { - int *sendCounts = nullptr; - int *displacements = nullptr; + int* sendCounts = nullptr; + int* displacements = nullptr; if (DDMASTER(dd)) { - AtomDistribution &ma = *dd->ma; + AtomDistribution& ma = *dd->ma; get_commbuffer_counts(&ma, &sendCounts, &displacements); - gmx::ArrayRef buffer = ma.rvecBuffer; - int localAtom = 0; + gmx::ArrayRef buffer = ma.rvecBuffer; + int localAtom = 0; for (int rank = 0; rank < dd->nnodes; rank++) { - const auto &domainGroups = ma.domainGroups[rank]; - for (const int &globalAtom : domainGroups.atomGroups) + const auto& domainGroups = ma.domainGroups[rank]; + for (const int& globalAtom : domainGroups.atomGroups) { buffer[localAtom++] = globalVec[globalAtom]; } @@ -135,14 +136,13 @@ static void distributeVecScatterv(gmx_domdec_t *dd, } int numHomeAtoms = dd->comm->atomRanges.numHomeAtoms(); - dd_scatterv(dd, sendCounts, displacements, - DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr, - numHomeAtoms*sizeof(gmx::RVec), localVec.data()); + dd_scatterv(dd, sendCounts, displacements, DDMASTER(dd) ? dd->ma->rvecBuffer.data() : nullptr, + numHomeAtoms * sizeof(gmx::RVec), localVec.data()); } -static void distributeVec(gmx_domdec_t *dd, - gmx::ArrayRef globalVec, - gmx::ArrayRef localVec) +static void distributeVec(gmx_domdec_t* dd, + gmx::ArrayRef globalVec, + gmx::ArrayRef localVec) { if (dd->nnodes <= c_maxNumRanksUseSendRecvForScatterAndGather) { @@ -154,7 +154,7 @@ static void distributeVec(gmx_domdec_t *dd, } } -static void dd_distribute_dfhist(gmx_domdec_t *dd, df_history_t *dfhist) +static void dd_distribute_dfhist(gmx_domdec_t* dd, df_history_t* dfhist) { if (dfhist == nullptr) { @@ -168,34 +168,36 @@ static void dd_distribute_dfhist(gmx_domdec_t *dd, df_history_t *dfhist) if (dfhist->nlambda > 0) { int nlam = dfhist->nlambda; - dd_bcast(dd, sizeof(int)*nlam, dfhist->n_at_lam); - dd_bcast(dd, sizeof(real)*nlam, dfhist->wl_histo); - dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_weights); - dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_dg); - dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_minvar); - dd_bcast(dd, sizeof(real)*nlam, dfhist->sum_variance); + dd_bcast(dd, sizeof(int) * nlam, dfhist->n_at_lam); + dd_bcast(dd, sizeof(real) * nlam, dfhist->wl_histo); + dd_bcast(dd, sizeof(real) * nlam, dfhist->sum_weights); + dd_bcast(dd, sizeof(real) * nlam, dfhist->sum_dg); + dd_bcast(dd, sizeof(real) * nlam, dfhist->sum_minvar); + dd_bcast(dd, sizeof(real) * nlam, dfhist->sum_variance); for (int i = 0; i < nlam; i++) { - dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_p[i]); - dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_m[i]); - dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_p2[i]); - dd_bcast(dd, sizeof(real)*nlam, dfhist->accum_m2[i]); - dd_bcast(dd, sizeof(real)*nlam, dfhist->Tij[i]); - dd_bcast(dd, sizeof(real)*nlam, dfhist->Tij_empirical[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->accum_p[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->accum_m[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->accum_p2[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->accum_m2[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->Tij[i]); + dd_bcast(dd, sizeof(real) * nlam, dfhist->Tij_empirical[i]); } } } -static void dd_distribute_state(gmx_domdec_t *dd, - const t_state *state, t_state *state_local, - PaddedHostVector *f) +static void dd_distribute_state(gmx_domdec_t* dd, + const t_state* state, + t_state* state_local, + PaddedHostVector* f) { int nh = state_local->nhchainlength; if (DDMASTER(dd)) { - GMX_RELEASE_ASSERT(state->nhchainlength == nh, "The global and local Nose-Hoover chain lengths should match"); + GMX_RELEASE_ASSERT(state->nhchainlength == nh, + "The global and local Nose-Hoover chain lengths should match"); for (int i = 0; i < efptNR; i++) { @@ -217,8 +219,8 @@ static void dd_distribute_state(gmx_domdec_t *dd, { for (int j = 0; j < nh; j++) { - state_local->nosehoover_xi[i*nh+j] = state->nosehoover_xi[i*nh+j]; - state_local->nosehoover_vxi[i*nh+j] = state->nosehoover_vxi[i*nh+j]; + state_local->nosehoover_xi[i * nh + j] = state->nosehoover_xi[i * nh + j]; + state_local->nosehoover_vxi[i * nh + j] = state->nosehoover_vxi[i * nh + j]; } state_local->therm_integral[i] = state->therm_integral[i]; } @@ -226,13 +228,13 @@ static void dd_distribute_state(gmx_domdec_t *dd, { for (int j = 0; j < nh; j++) { - state_local->nhpres_xi[i*nh+j] = state->nhpres_xi[i*nh+j]; - state_local->nhpres_vxi[i*nh+j] = state->nhpres_vxi[i*nh+j]; + state_local->nhpres_xi[i * nh + j] = state->nhpres_xi[i * nh + j]; + state_local->nhpres_vxi[i * nh + j] = state->nhpres_vxi[i * nh + j]; } } state_local->baros_integral = state->baros_integral; } - dd_bcast(dd, ((efptNR)*sizeof(real)), state_local->lambda.data()); + dd_bcast(dd, ((efptNR) * sizeof(real)), state_local->lambda.data()); dd_bcast(dd, sizeof(int), &state_local->fep_state); dd_bcast(dd, sizeof(real), &state_local->veta); dd_bcast(dd, sizeof(real), &state_local->vol0); @@ -241,11 +243,11 @@ static void dd_distribute_state(gmx_domdec_t *dd, dd_bcast(dd, sizeof(state_local->boxv), state_local->boxv); dd_bcast(dd, sizeof(state_local->svir_prev), state_local->svir_prev); dd_bcast(dd, sizeof(state_local->fvir_prev), state_local->fvir_prev); - dd_bcast(dd, ((state_local->ngtc*nh)*sizeof(double)), state_local->nosehoover_xi.data()); - dd_bcast(dd, ((state_local->ngtc*nh)*sizeof(double)), state_local->nosehoover_vxi.data()); - dd_bcast(dd, state_local->ngtc*sizeof(double), state_local->therm_integral.data()); - dd_bcast(dd, ((state_local->nnhpres*nh)*sizeof(double)), state_local->nhpres_xi.data()); - dd_bcast(dd, ((state_local->nnhpres*nh)*sizeof(double)), state_local->nhpres_vxi.data()); + dd_bcast(dd, ((state_local->ngtc * nh) * sizeof(double)), state_local->nosehoover_xi.data()); + dd_bcast(dd, ((state_local->ngtc * nh) * sizeof(double)), state_local->nosehoover_vxi.data()); + dd_bcast(dd, state_local->ngtc * sizeof(double), state_local->therm_integral.data()); + dd_bcast(dd, ((state_local->nnhpres * nh) * sizeof(double)), state_local->nhpres_xi.data()); + dd_bcast(dd, ((state_local->nnhpres * nh) * sizeof(double)), state_local->nhpres_vxi.data()); /* communicate df_history -- required for restarting from checkpoint */ dd_distribute_dfhist(dd, state_local->dfhist); @@ -270,15 +272,14 @@ static void dd_distribute_state(gmx_domdec_t *dd, * * Also updates the coordinates in pos for PBC, when necessary. */ -static inline int -computeAtomGroupDomainIndex(const gmx_domdec_t &dd, - const gmx_ddbox_t &ddbox, - const matrix &triclinicCorrectionMatrix, - gmx::ArrayRef < const std::vector < real>> cellBoundaries, - int atomBegin, - int atomEnd, - const matrix box, - rvec *pos) +static inline int computeAtomGroupDomainIndex(const gmx_domdec_t& dd, + const gmx_ddbox_t& ddbox, + const matrix& triclinicCorrectionMatrix, + gmx::ArrayRef> cellBoundaries, + int atomBegin, + int atomEnd, + const matrix box, + rvec* pos) { /* Set the reference location cg_cm for assigning the group */ rvec cog; @@ -289,7 +290,7 @@ computeAtomGroupDomainIndex(const gmx_domdec_t &dd, } else { - real invNumAtoms = 1/static_cast(numAtoms); + real invNumAtoms = 1 / static_cast(numAtoms); clear_rvec(cog); for (int a = atomBegin; a < atomEnd; a++) @@ -314,7 +315,7 @@ computeAtomGroupDomainIndex(const gmx_domdec_t &dd, /* Use triclinic coordinates for this dimension */ for (int j = d + 1; j < DIM; j++) { - pos_d += cog[j]*triclinicCorrectionMatrix[j][d]; + pos_d += cog[j] * triclinicCorrectionMatrix[j][d]; } } while (pos_d >= box[d][d]) @@ -368,14 +369,14 @@ computeAtomGroupDomainIndex(const gmx_domdec_t &dd, } -static std::vector < std::vector < int>> -getAtomGroupDistribution(const gmx::MDLogger &mdlog, - const gmx_mtop_t &mtop, - const matrix box, const gmx_ddbox_t &ddbox, - rvec pos[], - gmx_domdec_t *dd) +static std::vector> getAtomGroupDistribution(const gmx::MDLogger& mdlog, + const gmx_mtop_t& mtop, + const matrix box, + const gmx_ddbox_t& ddbox, + rvec pos[], + gmx_domdec_t* dd) { - AtomDistribution &ma = *dd->ma; + AtomDistribution& ma = *dd->ma; /* Clear the count */ for (int rank = 0; rank < dd->nnodes; rank++) @@ -387,30 +388,28 @@ getAtomGroupDistribution(const gmx::MDLogger &mdlog, make_tric_corr_matrix(dd->unitCellInfo.npbcdim, box, triclinicCorrectionMatrix); ivec npulse; - const auto cellBoundaries = - set_dd_cell_sizes_slb(dd, &ddbox, setcellsizeslbMASTER, npulse); + const auto cellBoundaries = set_dd_cell_sizes_slb(dd, &ddbox, setcellsizeslbMASTER, npulse); - std::vector < std::vector < int>> indices(dd->nnodes); + std::vector> indices(dd->nnodes); if (dd->comm->systemInfo.useUpdateGroups) { int atomOffset = 0; - for (const gmx_molblock_t &molblock : mtop.molblock) + for (const gmx_molblock_t& molblock : mtop.molblock) { - const auto &updateGrouping = dd->comm->systemInfo.updateGroupingPerMoleculetype[molblock.type]; + const auto& updateGrouping = + dd->comm->systemInfo.updateGroupingPerMoleculetype[molblock.type]; for (int mol = 0; mol < molblock.nmol; mol++) { for (int g = 0; g < updateGrouping.numBlocks(); g++) { - const auto &block = updateGrouping.block(g); - const int atomBegin = atomOffset + block.begin(); - const int atomEnd = atomOffset + block.end(); + const auto& block = updateGrouping.block(g); + const int atomBegin = atomOffset + block.begin(); + const int atomEnd = atomOffset + block.end(); const int domainIndex = - computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix, - cellBoundaries, - atomBegin, atomEnd, box, - pos); + computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix, + cellBoundaries, atomBegin, atomEnd, box, pos); for (int atomIndex : block) { @@ -430,11 +429,8 @@ getAtomGroupDistribution(const gmx::MDLogger &mdlog, /* Compute the center of geometry for all atoms */ for (int atom = 0; atom < mtop.natoms; atom++) { - int domainIndex = - computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix, - cellBoundaries, - atom, atom + 1, box, - pos); + int domainIndex = computeAtomGroupDomainIndex(*dd, ddbox, triclinicCorrectionMatrix, + cellBoundaries, atom, atom + 1, box, pos); indices[domainIndex].push_back(atom); ma.domainGroups[domainIndex].numAtoms += 1; @@ -453,38 +449,39 @@ getAtomGroupDistribution(const gmx::MDLogger &mdlog, nat_max = ma.domainGroups[0].numAtoms; for (int rank = 0; rank < dd->nnodes; rank++) { - int numAtoms = ma.domainGroups[rank].numAtoms; - nat_sum += numAtoms; + int numAtoms = ma.domainGroups[rank].numAtoms; + nat_sum += numAtoms; // convert to double to avoid integer overflows when squaring - nat2_sum += gmx::square(double(numAtoms)); - nat_min = std::min(nat_min, numAtoms); - nat_max = std::max(nat_max, numAtoms); + nat2_sum += gmx::square(double(numAtoms)); + nat_min = std::min(nat_min, numAtoms); + nat_max = std::max(nat_max, numAtoms); } - nat_sum /= dd->nnodes; + nat_sum /= dd->nnodes; nat2_sum /= dd->nnodes; - GMX_LOG(mdlog.info).appendTextFormatted( - "Atom distribution over %d domains: av %d stddev %d min %d max %d", - dd->nnodes, - nat_sum, - gmx::roundToInt(std::sqrt(nat2_sum - gmx::square(static_cast(nat_sum)))), - nat_min, nat_max); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Atom distribution over %d domains: av %d stddev %d min %d max %d", + dd->nnodes, nat_sum, + gmx::roundToInt(std::sqrt(nat2_sum - gmx::square(static_cast(nat_sum)))), + nat_min, nat_max); } return indices; } -static void distributeAtomGroups(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - const gmx_mtop_t &mtop, - const matrix box, const gmx_ddbox_t *ddbox, - rvec pos[]) +static void distributeAtomGroups(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + const gmx_mtop_t& mtop, + const matrix box, + const gmx_ddbox_t* ddbox, + rvec pos[]) { - AtomDistribution *ma = dd->ma.get(); - int *ibuf, buf2[2] = { 0, 0 }; + AtomDistribution* ma = dd->ma.get(); + int * ibuf, buf2[2] = { 0, 0 }; gmx_bool bMaster = DDMASTER(dd); - std::vector < std::vector < int>> groupIndices; + std::vector> groupIndices; if (bMaster) { @@ -499,8 +496,8 @@ static void distributeAtomGroups(const gmx::MDLogger &mdlog, for (int rank = 0; rank < dd->nnodes; rank++) { - ma->intBuffer[rank*2] = groupIndices[rank].size(); - ma->intBuffer[rank*2 + 1] = ma->domainGroups[rank].numAtoms; + ma->intBuffer[rank * 2] = groupIndices[rank].size(); + ma->intBuffer[rank * 2 + 1] = ma->domainGroups[rank].numAtoms; } ibuf = ma->intBuffer.data(); } @@ -508,7 +505,7 @@ static void distributeAtomGroups(const gmx::MDLogger &mdlog, { ibuf = nullptr; } - dd_scatter(dd, 2*sizeof(int), ibuf, buf2); + dd_scatter(dd, 2 * sizeof(int), ibuf, buf2); dd->ncg_home = buf2[0]; dd->comm->atomRanges.setEnd(DDAtomRanges::Type::Home, buf2[1]); @@ -522,23 +519,23 @@ static void distributeAtomGroups(const gmx::MDLogger &mdlog, int groupOffset = 0; for (int rank = 0; rank < dd->nnodes; rank++) { - ma->intBuffer[rank] = groupIndices[rank].size()*sizeof(int); - ma->intBuffer[dd->nnodes + rank] = groupOffset*sizeof(int); + ma->intBuffer[rank] = groupIndices[rank].size() * sizeof(int); + ma->intBuffer[dd->nnodes + rank] = groupOffset * sizeof(int); - ma->atomGroups.insert(ma->atomGroups.end(), - groupIndices[rank].begin(), groupIndices[rank].end()); + ma->atomGroups.insert(ma->atomGroups.end(), groupIndices[rank].begin(), + groupIndices[rank].end()); - ma->domainGroups[rank].atomGroups = gmx::constArrayRefFromArray(ma->atomGroups.data() + groupOffset, groupIndices[rank].size()); + ma->domainGroups[rank].atomGroups = gmx::constArrayRefFromArray( + ma->atomGroups.data() + groupOffset, groupIndices[rank].size()); - groupOffset += groupIndices[rank].size(); + groupOffset += groupIndices[rank].size(); } } - dd_scatterv(dd, - bMaster ? ma->intBuffer.data() : nullptr, + dd_scatterv(dd, bMaster ? ma->intBuffer.data() : nullptr, bMaster ? ma->intBuffer.data() + dd->nnodes : nullptr, - bMaster ? ma->atomGroups.data() : nullptr, - dd->ncg_home*sizeof(int), dd->globalAtomGroupIndices.data()); + bMaster ? ma->atomGroups.data() : nullptr, dd->ncg_home * sizeof(int), + dd->globalAtomGroupIndices.data()); if (debug) { @@ -555,19 +552,17 @@ static void distributeAtomGroups(const gmx::MDLogger &mdlog, } } -void distributeState(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - const gmx_mtop_t &mtop, - t_state *state_global, - const gmx_ddbox_t &ddbox, - t_state *state_local, - PaddedHostVector *f) +void distributeState(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + const gmx_mtop_t& mtop, + t_state* state_global, + const gmx_ddbox_t& ddbox, + t_state* state_local, + PaddedHostVector* f) { - rvec *xGlobal = (DDMASTER(dd) ? state_global->x.rvec_array() : nullptr); + rvec* xGlobal = (DDMASTER(dd) ? state_global->x.rvec_array() : nullptr); - distributeAtomGroups(mdlog, dd, mtop, - DDMASTER(dd) ? state_global->box : nullptr, - &ddbox, xGlobal); + distributeAtomGroups(mdlog, dd, mtop, DDMASTER(dd) ? state_global->box : nullptr, &ddbox, xGlobal); dd_distribute_state(dd, state_global, state_local, f); } diff --git a/src/gromacs/domdec/distribute.h b/src/gromacs/domdec/distribute.h index a5c4668fa5..7dc1a7b53d 100644 --- a/src/gromacs/domdec/distribute.h +++ b/src/gromacs/domdec/distribute.h @@ -57,12 +57,12 @@ class MDLogger; } /*! \brief Distributes the state from the master rank to all DD ranks */ -void distributeState(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - const gmx_mtop_t &mtop, - t_state *state_global, - const gmx_ddbox_t &ddbox, - t_state *state_local, - gmx::PaddedHostVector *f); +void distributeState(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + const gmx_mtop_t& mtop, + t_state* state_global, + const gmx_ddbox_t& ddbox, + t_state* state_local, + gmx::PaddedHostVector* f); #endif diff --git a/src/gromacs/domdec/dlb.cpp b/src/gromacs/domdec/dlb.cpp index 5ed8292108..22ba069161 100644 --- a/src/gromacs/domdec/dlb.cpp +++ b/src/gromacs/domdec/dlb.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,13 +52,13 @@ #include "domdec_internal.h" #include "utility.h" -float dd_pme_f_ratio(const gmx_domdec_t *dd) +float dd_pme_f_ratio(const gmx_domdec_t* dd) { GMX_ASSERT(DDMASTER(dd), "This function should only be called on the master rank"); if (dd->comm->load[0].mdf > 0 && dd->comm->cycl_n[ddCyclPME] > 0) { - return dd->comm->load[0].pme/dd->comm->load[0].mdf; + return dd->comm->load[0].pme / dd->comm->load[0].mdf; } else { @@ -66,7 +66,7 @@ float dd_pme_f_ratio(const gmx_domdec_t *dd) } } -void set_dlb_limits(gmx_domdec_t *dd) +void set_dlb_limits(gmx_domdec_t* dd) { for (int d = 0; d < dd->ndim; d++) @@ -74,12 +74,11 @@ void set_dlb_limits(gmx_domdec_t *dd) /* Set the number of pulses to the value for DLB */ dd->comm->cd[d].ind.resize(dd->comm->cd[d].np_dlb); - dd->comm->cellsize_min[dd->dim[d]] = - dd->comm->cellsize_min_dlb[dd->dim[d]]; + dd->comm->cellsize_min[dd->dim[d]] = dd->comm->cellsize_min_dlb[dd->dim[d]]; } } -void dd_dlb_set_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd, gmx_bool bValue) +void dd_dlb_set_should_check_whether_to_turn_dlb_on(gmx_domdec_t* dd, gmx_bool bValue) { if (dd->comm->dlbState == DlbState::offCanTurnOn) { @@ -95,7 +94,7 @@ void dd_dlb_set_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd, gmx_bool b } } -gmx_bool dd_dlb_get_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd) +gmx_bool dd_dlb_get_should_check_whether_to_turn_dlb_on(gmx_domdec_t* dd) { if (dd->comm->dlbState != DlbState::offCanTurnOn) { @@ -136,17 +135,17 @@ gmx_bool dd_dlb_get_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd) return dd->comm->n_load_have % c_checkTurnDlbOnInterval == c_checkTurnDlbOnInterval - 1; } -gmx_bool dd_dlb_is_on(const gmx_domdec_t *dd) +gmx_bool dd_dlb_is_on(const gmx_domdec_t* dd) { return isDlbOn(dd->comm); } -gmx_bool dd_dlb_is_locked(const gmx_domdec_t *dd) +gmx_bool dd_dlb_is_locked(const gmx_domdec_t* dd) { return (dd->comm->dlbState == DlbState::offTemporarilyLocked); } -void dd_dlb_lock(gmx_domdec_t *dd) +void dd_dlb_lock(gmx_domdec_t* dd) { /* We can only lock the DLB when it is set to auto, otherwise don't do anything */ if (dd->comm->dlbState == DlbState::offCanTurnOn) @@ -155,7 +154,7 @@ void dd_dlb_lock(gmx_domdec_t *dd) } } -void dd_dlb_unlock(gmx_domdec_t *dd) +void dd_dlb_unlock(gmx_domdec_t* dd) { /* We can only lock the DLB when it is set to auto, otherwise don't do anything */ if (dd->comm->dlbState == DlbState::offTemporarilyLocked) diff --git a/src/gromacs/domdec/dlb.h b/src/gromacs/domdec/dlb.h index f5aa6924b7..4769697f0a 100644 --- a/src/gromacs/domdec/dlb.h +++ b/src/gromacs/domdec/dlb.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,24 +55,24 @@ struct t_commrec; * With large imbalance DLB will turn on at the first step, so we can * make the interval so large that the MPI overhead of the check is negligible. */ -constexpr int c_checkTurnDlbOnInterval = 100; +constexpr int c_checkTurnDlbOnInterval = 100; /*! \brief We need to check if DLB results in worse performance and then turn it off. * We check this more often then for turning DLB on, because the DLB can scale * the domains very rapidly, so if unlucky the load imbalance can go up quickly * and furthermore, we are already synchronizing often with DLB, so * the overhead of the MPI Bcast is not that high. */ -constexpr int c_checkTurnDlbOffInterval = 20; +constexpr int c_checkTurnDlbOffInterval = 20; /*! \brief Return the PME/PP force load ratio, or -1 if nothing was measured. * * Should only be called on the DD master node. */ -float dd_pme_f_ratio(const gmx_domdec_t *dd); +float dd_pme_f_ratio(const gmx_domdec_t* dd); //! Sets the cell size limits for DD to suit dynamic load balancing. -void set_dlb_limits(gmx_domdec_t *dd); +void set_dlb_limits(gmx_domdec_t* dd); /*! \brief Limit DLB to preserve the option of returning to the current cut-off. * @@ -82,7 +82,7 @@ void set_dlb_limits(gmx_domdec_t *dd); * should still be possible after subsequently setting a shorter cut-off * with change_dd_cutoff. */ -void set_dd_dlb_max_cutoff(struct t_commrec *cr, real cutoff); +void set_dd_dlb_max_cutoff(struct t_commrec* cr, real cutoff); /*! \brief Sets whether we should later check the load imbalance data, so that * we can trigger dynamic load balancing if enough imbalance has @@ -91,25 +91,25 @@ void set_dd_dlb_max_cutoff(struct t_commrec *cr, real cutoff); * Used after PME load balancing unlocks DLB, so that the check * whether DLB will be useful can happen immediately. */ -void dd_dlb_set_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd, bool bValue); +void dd_dlb_set_should_check_whether_to_turn_dlb_on(gmx_domdec_t* dd, bool bValue); /*! \brief Returns if we should check whether there has been enough * load imbalance to trigger dynamic load balancing. * * We need to check whether we check because it might be always off. */ -bool dd_dlb_get_should_check_whether_to_turn_dlb_on(gmx_domdec_t *dd); +bool dd_dlb_get_should_check_whether_to_turn_dlb_on(gmx_domdec_t* dd); /*! \brief Return if we are currently using dynamic load balancing */ -bool dd_dlb_is_on(const gmx_domdec_t *dd); +bool dd_dlb_is_on(const gmx_domdec_t* dd); /*! \brief Return if the DLB lock is set */ -bool dd_dlb_is_locked(const gmx_domdec_t *dd); +bool dd_dlb_is_locked(const gmx_domdec_t* dd); /*! \brief Set a lock such that with DLB=auto DLB cannot get turned on */ -void dd_dlb_lock(struct gmx_domdec_t *dd); +void dd_dlb_lock(struct gmx_domdec_t* dd); /*! \brief Clear a lock such that with DLB=auto DLB may get turned on later */ -void dd_dlb_unlock(struct gmx_domdec_t *dd); +void dd_dlb_unlock(struct gmx_domdec_t* dd); #endif diff --git a/src/gromacs/domdec/dlbtiming.cpp b/src/gromacs/domdec/dlbtiming.cpp index 6e920ea3b4..1c1fd9376e 100644 --- a/src/gromacs/domdec/dlbtiming.cpp +++ b/src/gromacs/domdec/dlbtiming.cpp @@ -58,14 +58,14 @@ struct BalanceRegion { } - bool isOpen; /**< Are we in an open balancing region? */ - bool isOpenOnCpu; /**< Is the, currently open, region still open on the CPU side? */ - bool isOpenOnGpu; /**< Is the, currently open, region open on the GPU side? */ - gmx_cycles_t cyclesOpenCpu; /**< Cycle count when opening the CPU region */ - gmx_cycles_t cyclesLastCpu; /**< Cycle count at the last call to \p ddCloseBalanceRegionCpu() */ + bool isOpen; /**< Are we in an open balancing region? */ + bool isOpenOnCpu; /**< Is the, currently open, region still open on the CPU side? */ + bool isOpenOnGpu; /**< Is the, currently open, region open on the GPU side? */ + gmx_cycles_t cyclesOpenCpu; /**< Cycle count when opening the CPU region */ + gmx_cycles_t cyclesLastCpu; /**< Cycle count at the last call to \p ddCloseBalanceRegionCpu() */ }; -BalanceRegion *ddBalanceRegionAllocate() +BalanceRegion* ddBalanceRegionAllocate() { return new BalanceRegion; } @@ -75,20 +75,21 @@ BalanceRegion *ddBalanceRegionAllocate() * This should be replaced by a properly managed BalanceRegion class, * but that requires a lot of refactoring in domdec.cpp. */ -static BalanceRegion *getBalanceRegion(const gmx_domdec_t *dd) +static BalanceRegion* getBalanceRegion(const gmx_domdec_t* dd) { GMX_ASSERT(dd != nullptr && dd->comm != nullptr, "Balance regions should only be used with DD"); - BalanceRegion *region = dd->comm->balanceRegion; + BalanceRegion* region = dd->comm->balanceRegion; GMX_ASSERT(region != nullptr, "Balance region should be initialized before use"); return region; } void DDBalanceRegionHandler::openRegionCpuImpl(DdAllowBalanceRegionReopen gmx_unused allowReopen) const { - BalanceRegion *reg = getBalanceRegion(dd_); + BalanceRegion* reg = getBalanceRegion(dd_); if (dd_->comm->ddSettings.recordLoad) { - GMX_ASSERT(allowReopen == DdAllowBalanceRegionReopen::yes || !reg->isOpen, "Should not open an already opened region"); + GMX_ASSERT(allowReopen == DdAllowBalanceRegionReopen::yes || !reg->isOpen, + "Should not open an already opened region"); reg->cyclesOpenCpu = gmx_cycles_read(); reg->isOpen = true; @@ -99,15 +100,15 @@ void DDBalanceRegionHandler::openRegionCpuImpl(DdAllowBalanceRegionReopen gmx_un void DDBalanceRegionHandler::openRegionGpuImpl() const { - BalanceRegion *reg = getBalanceRegion(dd_); + BalanceRegion* reg = getBalanceRegion(dd_); GMX_ASSERT(reg->isOpen, "Can only open a GPU region inside an open CPU region"); GMX_ASSERT(!reg->isOpenOnGpu, "Can not re-open a GPU balance region"); reg->isOpenOnGpu = true; } -void ddReopenBalanceRegionCpu(const gmx_domdec_t *dd) +void ddReopenBalanceRegionCpu(const gmx_domdec_t* dd) { - BalanceRegion *reg = getBalanceRegion(dd); + BalanceRegion* reg = getBalanceRegion(dd); /* If the GPU is busy, don't reopen as we are overlapping with work */ if (reg->isOpen && !reg->isOpenOnGpu) { @@ -117,7 +118,7 @@ void ddReopenBalanceRegionCpu(const gmx_domdec_t *dd) void DDBalanceRegionHandler::closeRegionCpuImpl() const { - BalanceRegion *reg = getBalanceRegion(dd_); + BalanceRegion* reg = getBalanceRegion(dd_); if (reg->isOpen && reg->isOpenOnCpu) { GMX_ASSERT(reg->isOpenOnCpu, "Can only close an open region"); @@ -132,21 +133,22 @@ void DDBalanceRegionHandler::closeRegionCpuImpl() const else { /* We can close the region */ - float cyclesCpu = cycles - reg->cyclesOpenCpu; + float cyclesCpu = cycles - reg->cyclesOpenCpu; dd_cycles_add(dd_, cyclesCpu, ddCyclF); - reg->isOpen = false; + reg->isOpen = false; } } } -void DDBalanceRegionHandler::closeRegionGpuImpl(float waitGpuCyclesInCpuRegion, +void DDBalanceRegionHandler::closeRegionGpuImpl(float waitGpuCyclesInCpuRegion, DdBalanceRegionWaitedForGpu waitedForGpu) const { - BalanceRegion *reg = getBalanceRegion(dd_); + BalanceRegion* reg = getBalanceRegion(dd_); if (reg->isOpen) { GMX_ASSERT(reg->isOpenOnGpu, "Can not close a non-open GPU balance region"); - GMX_ASSERT(!reg->isOpenOnCpu, "The GPU region should be closed after closing the CPU region"); + GMX_ASSERT(!reg->isOpenOnCpu, + "The GPU region should be closed after closing the CPU region"); float waitGpuCyclesEstimate = gmx_cycles_read() - reg->cyclesLastCpu; if (waitedForGpu == DdBalanceRegionWaitedForGpu::no) @@ -171,11 +173,11 @@ void DDBalanceRegionHandler::closeRegionGpuImpl(float wait } //! Accumulates flop counts for force calculations. -static double force_flop_count(const t_nrnb *nrnb) +static double force_flop_count(const t_nrnb* nrnb) { int i; double sum; - const char *name; + const char* name; sum = 0; for (i = 0; i < eNR_NBKERNEL_FREE_ENERGY; i++) @@ -186,11 +188,11 @@ static double force_flop_count(const t_nrnb *nrnb) name = nrnb_str(i); if (strstr(name, "W3") != nullptr || strstr(name, "W4") != nullptr) { - sum += nrnb->n[i]*0.25*cost_nrnb(i); + sum += nrnb->n[i] * 0.25 * cost_nrnb(i); } else { - sum += nrnb->n[i]*0.50*cost_nrnb(i); + sum += nrnb->n[i] * 0.50 * cost_nrnb(i); } } for (i = eNR_NBKERNEL_FREE_ENERGY; i <= eNR_NB14; i++) @@ -198,18 +200,18 @@ static double force_flop_count(const t_nrnb *nrnb) name = nrnb_str(i); if (strstr(name, "W3") != nullptr || strstr(name, "W4") != nullptr) { - sum += nrnb->n[i]*cost_nrnb(i); + sum += nrnb->n[i] * cost_nrnb(i); } } for (i = eNR_BONDS; i <= eNR_WALLS; i++) { - sum += nrnb->n[i]*cost_nrnb(i); + sum += nrnb->n[i] * cost_nrnb(i); } return sum; } -void dd_force_flop_start(gmx_domdec_t *dd, t_nrnb *nrnb) +void dd_force_flop_start(gmx_domdec_t* dd, t_nrnb* nrnb) { if (dd->comm->ddSettings.eFlop) { @@ -217,7 +219,7 @@ void dd_force_flop_start(gmx_domdec_t *dd, t_nrnb *nrnb) } } -void dd_force_flop_stop(gmx_domdec_t *dd, t_nrnb *nrnb) +void dd_force_flop_stop(gmx_domdec_t* dd, t_nrnb* nrnb) { if (dd->comm->ddSettings.eFlop) { @@ -226,7 +228,7 @@ void dd_force_flop_stop(gmx_domdec_t *dd, t_nrnb *nrnb) } } -void clear_dd_cycle_counts(gmx_domdec_t *dd) +void clear_dd_cycle_counts(gmx_domdec_t* dd) { int i; diff --git a/src/gromacs/domdec/dlbtiming.h b/src/gromacs/domdec/dlbtiming.h index ebd84e6eac..39b2aed86f 100644 --- a/src/gromacs/domdec/dlbtiming.h +++ b/src/gromacs/domdec/dlbtiming.h @@ -54,15 +54,15 @@ struct t_nrnb; /*! \brief Tells if we should open the balancing region */ enum class DdAllowBalanceRegionReopen { - no, //!< Do not allow opening an already open region - yes //!< Allow opening an already open region + no, //!< Do not allow opening an already open region + yes //!< Allow opening an already open region }; /*! \brief Tells if we had to wait for a GPU to finish computation */ enum class DdBalanceRegionWaitedForGpu { - no, //!< The GPU finished computation before the CPU needed the result - yes //!< We had to wait for the GPU to finish computation + no, //!< The GPU finished computation before the CPU needed the result + yes //!< We had to wait for the GPU to finish computation }; /*! \brief Re-open the, already opened, load balance timing region @@ -76,135 +76,131 @@ enum class DdBalanceRegionWaitedForGpu * * \param[in,out] dd The domain decomposition struct */ -void ddReopenBalanceRegionCpu(const gmx_domdec_t *dd); +void ddReopenBalanceRegionCpu(const gmx_domdec_t* dd); /*! \libinternal * \brief Manager for starting and stopping the dynamic load balancing region */ class DDBalanceRegionHandler { - public: - //! Constructor, pass a pointer to t_commrec or nullptr when not using domain decomposition - DDBalanceRegionHandler(const t_commrec *cr) : - useBalancingRegion_(cr != nullptr ? havePPDomainDecomposition(cr) : false), - dd_(cr != nullptr ? cr->dd : nullptr) +public: + //! Constructor, pass a pointer to t_commrec or nullptr when not using domain decomposition + DDBalanceRegionHandler(const t_commrec* cr) : + useBalancingRegion_(cr != nullptr ? havePPDomainDecomposition(cr) : false), + dd_(cr != nullptr ? cr->dd : nullptr) + { + } + + /*! \brief Returns whether were are actually using the balancing region + */ + bool useBalancingRegion() const { return useBalancingRegion_; } + + /*! \brief Open the load balance timing region on the CPU + * + * Opens the balancing region for timing how much time it takes to perform + * the (balancable part of) the MD step. This should be called right after + * the last communication during the previous step to maximize the region. + * In practice this means right after the force communication finished + * or just before neighbor search at search steps. + * It is assumed that computation done in the region either scales along + * with the domain size or takes constant time. + * + * \param[in] allowReopen Allows calling with a potentially already opened region + */ + void openBeforeForceComputationCpu(DdAllowBalanceRegionReopen allowReopen) const + { + if (useBalancingRegion_) { + openRegionCpuImpl(allowReopen); } - - /*! \brief Returns whether were are actually using the balancing region - */ - bool useBalancingRegion() const - { - return useBalancingRegion_; - } - - /*! \brief Open the load balance timing region on the CPU - * - * Opens the balancing region for timing how much time it takes to perform - * the (balancable part of) the MD step. This should be called right after - * the last communication during the previous step to maximize the region. - * In practice this means right after the force communication finished - * or just before neighbor search at search steps. - * It is assumed that computation done in the region either scales along - * with the domain size or takes constant time. - * - * \param[in] allowReopen Allows calling with a potentially already opened region - */ - void openBeforeForceComputationCpu(DdAllowBalanceRegionReopen allowReopen) const - { - if (useBalancingRegion_) - { - openRegionCpuImpl(allowReopen); - } - } - - /*! \brief Open the load balance timing region for the CPU - * - * This can only be called within a region that is open on the CPU side. - */ - void openBeforeForceComputationGpu() const + } + + /*! \brief Open the load balance timing region for the CPU + * + * This can only be called within a region that is open on the CPU side. + */ + void openBeforeForceComputationGpu() const + { + if (useBalancingRegion_) { - if (useBalancingRegion_) - { - openRegionGpuImpl(); - } + openRegionGpuImpl(); } - - /*! \brief Re-open the, already opened, load balance timing region - * - * This function should be called after every MPI communication that occurs - * in the main MD loop. - * Note that the current setup assumes that all MPI communication acts like - * a global barrier. But if some ranks don't participate in communication - * or if some ranks communicate faster with neighbors than others, - * the obtained timings might not accurately reflect the computation time. - */ - void reopenRegionCpu() const + } + + /*! \brief Re-open the, already opened, load balance timing region + * + * This function should be called after every MPI communication that occurs + * in the main MD loop. + * Note that the current setup assumes that all MPI communication acts like + * a global barrier. But if some ranks don't participate in communication + * or if some ranks communicate faster with neighbors than others, + * the obtained timings might not accurately reflect the computation time. + */ + void reopenRegionCpu() const + { + if (useBalancingRegion_) { - if (useBalancingRegion_) - { - ddReopenBalanceRegionCpu(dd_); - } + ddReopenBalanceRegionCpu(dd_); } + } - /*! \brief Close the load balance timing region on the CPU side - */ - void closeAfterForceComputationCpu() const + /*! \brief Close the load balance timing region on the CPU side + */ + void closeAfterForceComputationCpu() const + { + if (useBalancingRegion_) { - if (useBalancingRegion_) - { - closeRegionCpuImpl(); - } + closeRegionCpuImpl(); } - - /*! \brief Close the load balance timing region on the GPU side - * - * This should be called after the CPU receives the last (local) results - * from the GPU. The wait time for these results is estimated, depending - * on the \p waitedForGpu parameter. - * If called on an already closed region, this call does nothing. - * - * \param[in] waitCyclesGpuInCpuRegion The time we waited for the GPU earlier, overlapping completely with the open CPU region - * \param[in] waitedForGpu Tells if we waited for the GPU to finish now - */ - void closeAfterForceComputationGpu(float waitCyclesGpuInCpuRegion, - DdBalanceRegionWaitedForGpu waitedForGpu) const + } + + /*! \brief Close the load balance timing region on the GPU side + * + * This should be called after the CPU receives the last (local) results + * from the GPU. The wait time for these results is estimated, depending + * on the \p waitedForGpu parameter. + * If called on an already closed region, this call does nothing. + * + * \param[in] waitCyclesGpuInCpuRegion The time we waited for the GPU earlier, overlapping completely with the open CPU region + * \param[in] waitedForGpu Tells if we waited for the GPU to finish now + */ + void closeAfterForceComputationGpu(float waitCyclesGpuInCpuRegion, + DdBalanceRegionWaitedForGpu waitedForGpu) const + { + if (useBalancingRegion_) { - if (useBalancingRegion_) - { - closeRegionGpuImpl(waitCyclesGpuInCpuRegion, waitedForGpu); - } + closeRegionGpuImpl(waitCyclesGpuInCpuRegion, waitedForGpu); } - - private: - /*! \brief Open the load balance timing region on the CPU - * - * \param[in] allowReopen Allows calling with a potentially already opened region - */ - void openRegionCpuImpl(DdAllowBalanceRegionReopen allowReopen) const; - - /*! \brief Open the load balance timing region for the GPU - * - * This can only be called within a region that is open on the CPU side. - */ - void openRegionGpuImpl() const; - - /*! \brief Close the load balance timing region on the CPU side - */ - void closeRegionCpuImpl() const; - - /*! \brief Close the load balance timing region on the GPU side - * - * \param[in] waitCyclesGpuInCpuRegion The time we waited for the GPU earlier, overlapping completely with the open CPU region - * \param[in] waitedForGpu Tells if we waited for the GPU to finish now - */ - void closeRegionGpuImpl(float waitCyclesGpuInCpuRegion, - DdBalanceRegionWaitedForGpu waitedForGpu) const; - - //! Tells whether the balancing region should be active - bool useBalancingRegion_; - //! A pointer to the DD struct, only valid with useBalancingRegion_=true - gmx_domdec_t *dd_; + } + +private: + /*! \brief Open the load balance timing region on the CPU + * + * \param[in] allowReopen Allows calling with a potentially already opened region + */ + void openRegionCpuImpl(DdAllowBalanceRegionReopen allowReopen) const; + + /*! \brief Open the load balance timing region for the GPU + * + * This can only be called within a region that is open on the CPU side. + */ + void openRegionGpuImpl() const; + + /*! \brief Close the load balance timing region on the CPU side + */ + void closeRegionCpuImpl() const; + + /*! \brief Close the load balance timing region on the GPU side + * + * \param[in] waitCyclesGpuInCpuRegion The time we waited for the GPU earlier, overlapping completely with the open CPU region + * \param[in] waitedForGpu Tells if we waited for the GPU to finish now + */ + void closeRegionGpuImpl(float waitCyclesGpuInCpuRegion, DdBalanceRegionWaitedForGpu waitedForGpu) const; + + //! Tells whether the balancing region should be active + bool useBalancingRegion_; + //! A pointer to the DD struct, only valid with useBalancingRegion_=true + gmx_domdec_t* dd_; }; /*! \brief Returns a pointer to a constructed \p BalanceRegion struct @@ -212,15 +208,15 @@ class DDBalanceRegionHandler * Should be replaced by a proper constructor once BalanceRegion is a proper * class (requires restructering in domdec.cpp). */ -BalanceRegion *ddBalanceRegionAllocate(); +BalanceRegion* ddBalanceRegionAllocate(); /*! \brief Start the force flop count */ -void dd_force_flop_start(struct gmx_domdec_t *dd, t_nrnb *nrnb); +void dd_force_flop_start(struct gmx_domdec_t* dd, t_nrnb* nrnb); /*! \brief Stop the force flop count */ -void dd_force_flop_stop(struct gmx_domdec_t *dd, t_nrnb *nrnb); +void dd_force_flop_stop(struct gmx_domdec_t* dd, t_nrnb* nrnb); //! Clear the cycle counts used for tuning. -void clear_dd_cycle_counts(gmx_domdec_t *dd); +void clear_dd_cycle_counts(gmx_domdec_t* dd); #endif diff --git a/src/gromacs/domdec/domdec.cpp b/src/gromacs/domdec/domdec.cpp index 84e3b898eb..2f931240e4 100644 --- a/src/gromacs/domdec/domdec.cpp +++ b/src/gromacs/domdec/domdec.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -116,19 +117,19 @@ using gmx::DdRankOrder; using gmx::DlbOption; using gmx::DomdecOptions; -static const char *edlbs_names[int(DlbState::nr)] = { "off", "auto", "locked", "on", "on" }; +static const char* edlbs_names[int(DlbState::nr)] = { "off", "auto", "locked", "on", "on" }; /* The size per atom group of the cggl_flag buffer in gmx_domdec_comm_t */ #define DD_CGIBS 2 /* The flags for the cggl_flag buffer in gmx_domdec_comm_t */ -#define DD_FLAG_NRCG 65535 -#define DD_FLAG_FW(d) (1<<(16+(d)*2)) -#define DD_FLAG_BW(d) (1<<(16+(d)*2+1)) +#define DD_FLAG_NRCG 65535 +#define DD_FLAG_FW(d) (1 << (16 + (d)*2)) +#define DD_FLAG_BW(d) (1 << (16 + (d)*2 + 1)) /* The DD zone order */ -static const ivec dd_zo[DD_MAXZONE] = -{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}, {1, 0, 1}, {1, 1, 1}}; +static const ivec dd_zo[DD_MAXZONE] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, + { 0, 1, 1 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }; /* The non-bonded zone-pair setup for domain decomposition * The first number is the i-zone, the second number the first j-zone seen by @@ -137,11 +138,10 @@ static const ivec dd_zo[DD_MAXZONE] = * With 2D decomposition use only the first 2 i-zones and a last+1 j-zone of 4. * With 1D decomposition use only the first i-zone and a last+1 j-zone of 2. */ -static const int - ddNonbondedZonePairRanges[DD_MAXIZONE][3] = {{0, 0, 8}, - {1, 3, 6}, - {2, 5, 6}, - {3, 5, 7}}; +static const int ddNonbondedZonePairRanges[DD_MAXIZONE][3] = { { 0, 0, 8 }, + { 1, 3, 6 }, + { 2, 5, 6 }, + { 3, 5, 7 } }; /* @@ -157,16 +157,16 @@ static const int static void ddindex2xyz(const ivec nc, int ind, ivec xyz) { - xyz[XX] = ind / (nc[YY]*nc[ZZ]); + xyz[XX] = ind / (nc[YY] * nc[ZZ]); xyz[YY] = (ind / nc[ZZ]) % nc[YY]; xyz[ZZ] = ind % nc[ZZ]; } -static int ddcoord2ddnodeid(gmx_domdec_t *dd, ivec c) +static int ddcoord2ddnodeid(gmx_domdec_t* dd, ivec c) { - int ddnodeid = -1; + int ddnodeid = -1; - const CartesianRankSetup &cartSetup = dd->comm->cartesianRankSetup; + const CartesianRankSetup& cartSetup = dd->comm->cartesianRankSetup; const int ddindex = dd_index(dd->nc, c); if (cartSetup.bCartesianPP_PME) { @@ -186,7 +186,7 @@ static int ddcoord2ddnodeid(gmx_domdec_t *dd, ivec c) return ddnodeid; } -int ddglatnr(const gmx_domdec_t *dd, int i) +int ddglatnr(const gmx_domdec_t* dd, int i) { int atnr; @@ -198,7 +198,9 @@ int ddglatnr(const gmx_domdec_t *dd, int i) { if (i >= dd->comm->atomRanges.numAtomsTotal()) { - gmx_fatal(FARGS, "glatnr called with %d, which is larger than the local number of atoms (%d)", i, dd->comm->atomRanges.numAtomsTotal()); + gmx_fatal(FARGS, + "glatnr called with %d, which is larger than the local number of atoms (%d)", + i, dd->comm->atomRanges.numAtomsTotal()); } atnr = dd->globalAtomIndices[i] + 1; } @@ -206,13 +208,13 @@ int ddglatnr(const gmx_domdec_t *dd, int i) return atnr; } -gmx::ArrayRef getUpdateGroupingPerMoleculetype(const gmx_domdec_t &dd) +gmx::ArrayRef getUpdateGroupingPerMoleculetype(const gmx_domdec_t& dd) { GMX_RELEASE_ASSERT(dd.comm, "Need a valid dd.comm"); return dd.comm->systemInfo.updateGroupingPerMoleculetype; } -void dd_store_state(gmx_domdec_t *dd, t_state *state) +void dd_store_state(gmx_domdec_t* dd, t_state* state) { int i; @@ -230,22 +232,22 @@ void dd_store_state(gmx_domdec_t *dd, t_state *state) state->ddp_count_cg_gl = dd->ddp_count; } -gmx_domdec_zones_t *domdec_zones(gmx_domdec_t *dd) +gmx_domdec_zones_t* domdec_zones(gmx_domdec_t* dd) { return &dd->comm->zones; } -int dd_numAtomsZones(const gmx_domdec_t &dd) +int dd_numAtomsZones(const gmx_domdec_t& dd) { return dd.comm->atomRanges.end(DDAtomRanges::Type::Zones); } -int dd_numHomeAtoms(const gmx_domdec_t &dd) +int dd_numHomeAtoms(const gmx_domdec_t& dd) { return dd.comm->atomRanges.numHomeAtoms(); } -int dd_natoms_mdatoms(const gmx_domdec_t *dd) +int dd_natoms_mdatoms(const gmx_domdec_t* dd) { /* We currently set mdatoms entries for all atoms: * local + non-local + communicated for vsite + constraints @@ -254,28 +256,25 @@ int dd_natoms_mdatoms(const gmx_domdec_t *dd) return dd->comm->atomRanges.numAtomsTotal(); } -int dd_natoms_vsite(const gmx_domdec_t *dd) +int dd_natoms_vsite(const gmx_domdec_t* dd) { return dd->comm->atomRanges.end(DDAtomRanges::Type::Vsites); } -void dd_get_constraint_range(const gmx_domdec_t *dd, int *at_start, int *at_end) +void dd_get_constraint_range(const gmx_domdec_t* dd, int* at_start, int* at_end) { *at_start = dd->comm->atomRanges.start(DDAtomRanges::Type::Constraints); *at_end = dd->comm->atomRanges.end(DDAtomRanges::Type::Constraints); } -void dd_move_x(gmx_domdec_t *dd, - const matrix box, - gmx::ArrayRef x, - gmx_wallcycle *wcycle) +void dd_move_x(gmx_domdec_t* dd, const matrix box, gmx::ArrayRef x, gmx_wallcycle* wcycle) { wallcycle_start(wcycle, ewcMOVEX); int nzone, nat_tot; - gmx_domdec_comm_t *comm; - gmx_domdec_comm_dim_t *cd; - rvec shift = {0, 0, 0}; + gmx_domdec_comm_t* comm; + gmx_domdec_comm_dim_t* cd; + rvec shift = { 0, 0, 0 }; gmx_bool bPBC, bScrew; comm = dd->comm; @@ -291,11 +290,11 @@ void dd_move_x(gmx_domdec_t *dd, copy_rvec(box[dd->dim[d]], shift); } cd = &comm->cd[d]; - for (const gmx_domdec_ind_t &ind : cd->ind) + for (const gmx_domdec_ind_t& ind : cd->ind) { - DDBufferAccess sendBufferAccess(comm->rvecBuffer, ind.nsend[nzone + 1]); - gmx::ArrayRef &sendBuffer = sendBufferAccess.buffer; - int n = 0; + DDBufferAccess sendBufferAccess(comm->rvecBuffer, ind.nsend[nzone + 1]); + gmx::ArrayRef& sendBuffer = sendBufferAccess.buffer; + int n = 0; if (!bPBC) { for (int j : ind.index) @@ -332,9 +331,10 @@ void dd_move_x(gmx_domdec_t *dd, } } - DDBufferAccess receiveBufferAccess(comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); + DDBufferAccess receiveBufferAccess( + comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); - gmx::ArrayRef receiveBuffer; + gmx::ArrayRef receiveBuffer; if (cd->receiveInPlace) { receiveBuffer = gmx::arrayRefFromArray(x.data() + nat_tot, ind.nrecv[nzone + 1]); @@ -344,8 +344,7 @@ void dd_move_x(gmx_domdec_t *dd, receiveBuffer = receiveBufferAccess.buffer; } /* Send and receive the coordinates */ - ddSendrecv(dd, d, dddirBackward, - sendBuffer, receiveBuffer); + ddSendrecv(dd, d, dddirBackward, sendBuffer, receiveBuffer); if (!cd->receiveInPlace) { @@ -358,7 +357,7 @@ void dd_move_x(gmx_domdec_t *dd, } } } - nat_tot += ind.nrecv[nzone+1]; + nat_tot += ind.nrecv[nzone + 1]; } nzone += nzone; } @@ -366,42 +365,43 @@ void dd_move_x(gmx_domdec_t *dd, wallcycle_stop(wcycle, ewcMOVEX); } -void dd_move_f(gmx_domdec_t *dd, - gmx::ForceWithShiftForces *forceWithShiftForces, - gmx_wallcycle *wcycle) +void dd_move_f(gmx_domdec_t* dd, gmx::ForceWithShiftForces* forceWithShiftForces, gmx_wallcycle* wcycle) { wallcycle_start(wcycle, ewcMOVEF); - gmx::ArrayRef f = forceWithShiftForces->force(); - gmx::ArrayRef fshift = forceWithShiftForces->shiftForces(); + gmx::ArrayRef f = forceWithShiftForces->force(); + gmx::ArrayRef fshift = forceWithShiftForces->shiftForces(); - gmx_domdec_comm_t &comm = *dd->comm; - int nzone = comm.zones.n/2; - int nat_tot = comm.atomRanges.end(DDAtomRanges::Type::Zones); - for (int d = dd->ndim-1; d >= 0; d--) + gmx_domdec_comm_t& comm = *dd->comm; + int nzone = comm.zones.n / 2; + int nat_tot = comm.atomRanges.end(DDAtomRanges::Type::Zones); + for (int d = dd->ndim - 1; d >= 0; d--) { /* Only forces in domains near the PBC boundaries need to consider PBC in the treatment of fshift */ - const bool shiftForcesNeedPbc = (forceWithShiftForces->computeVirial() && dd->ci[dd->dim[d]] == 0); - const bool applyScrewPbc = (shiftForcesNeedPbc && dd->unitCellInfo.haveScrewPBC && dd->dim[d] == XX); + const bool shiftForcesNeedPbc = + (forceWithShiftForces->computeVirial() && dd->ci[dd->dim[d]] == 0); + const bool applyScrewPbc = + (shiftForcesNeedPbc && dd->unitCellInfo.haveScrewPBC && dd->dim[d] == XX); /* Determine which shift vector we need */ - ivec vis = { 0, 0, 0 }; - vis[dd->dim[d]] = 1; - const int is = IVEC2IS(vis); + ivec vis = { 0, 0, 0 }; + vis[dd->dim[d]] = 1; + const int is = IVEC2IS(vis); /* Loop over the pulses */ - const gmx_domdec_comm_dim_t &cd = comm.cd[d]; + const gmx_domdec_comm_dim_t& cd = comm.cd[d]; for (int p = cd.numPulses() - 1; p >= 0; p--) { - const gmx_domdec_ind_t &ind = cd.ind[p]; - DDBufferAccess receiveBufferAccess(comm.rvecBuffer, ind.nsend[nzone + 1]); - gmx::ArrayRef &receiveBuffer = receiveBufferAccess.buffer; + const gmx_domdec_ind_t& ind = cd.ind[p]; + DDBufferAccess receiveBufferAccess(comm.rvecBuffer, ind.nsend[nzone + 1]); + gmx::ArrayRef& receiveBuffer = receiveBufferAccess.buffer; - nat_tot -= ind.nrecv[nzone+1]; + nat_tot -= ind.nrecv[nzone + 1]; - DDBufferAccess sendBufferAccess(comm.rvecBuffer2, cd.receiveInPlace ? 0 : ind.nrecv[nzone + 1]); + DDBufferAccess sendBufferAccess( + comm.rvecBuffer2, cd.receiveInPlace ? 0 : ind.nrecv[nzone + 1]); - gmx::ArrayRef sendBuffer; + gmx::ArrayRef sendBuffer; if (cd.receiveInPlace) { sendBuffer = gmx::arrayRefFromArray(f.data() + nat_tot, ind.nrecv[nzone + 1]); @@ -409,7 +409,7 @@ void dd_move_f(gmx_domdec_t *dd, else { sendBuffer = sendBufferAccess.buffer; - int j = 0; + int j = 0; for (int zone = 0; zone < nzone; zone++) { for (int i = ind.cell2at0[zone]; i < ind.cell2at1[zone]; i++) @@ -419,8 +419,7 @@ void dd_move_f(gmx_domdec_t *dd, } } /* Communicate the forces */ - ddSendrecv(dd, d, dddirForward, - sendBuffer, receiveBuffer); + ddSendrecv(dd, d, dddirForward, sendBuffer, receiveBuffer); /* Add the received forces */ int n = 0; if (!shiftForcesNeedPbc) @@ -482,18 +481,16 @@ void dd_move_f(gmx_domdec_t *dd, * This functions return a real buffer reference with the same number * of elements as the gmx::RVec buffer (so 1/3 of the size in bytes). */ -static gmx::ArrayRef -realArrayRefFromRvecArrayRef(gmx::ArrayRef arrayRef) +static gmx::ArrayRef realArrayRefFromRvecArrayRef(gmx::ArrayRef arrayRef) { - return gmx::arrayRefFromArray(as_rvec_array(arrayRef.data())[0], - arrayRef.size()); + return gmx::arrayRefFromArray(as_rvec_array(arrayRef.data())[0], arrayRef.size()); } -void dd_atom_spread_real(gmx_domdec_t *dd, real v[]) +void dd_atom_spread_real(gmx_domdec_t* dd, real v[]) { int nzone, nat_tot; - gmx_domdec_comm_t *comm; - gmx_domdec_comm_dim_t *cd; + gmx_domdec_comm_t* comm; + gmx_domdec_comm_dim_t* cd; comm = dd->comm; @@ -502,23 +499,24 @@ void dd_atom_spread_real(gmx_domdec_t *dd, real v[]) for (int d = 0; d < dd->ndim; d++) { cd = &comm->cd[d]; - for (const gmx_domdec_ind_t &ind : cd->ind) + for (const gmx_domdec_ind_t& ind : cd->ind) { /* Note: We provision for RVec instead of real, so a factor of 3 * more than needed. The buffer actually already has this size * and we pass a plain pointer below, so this does not matter. */ DDBufferAccess sendBufferAccess(comm->rvecBuffer, ind.nsend[nzone + 1]); - gmx::ArrayRef sendBuffer = realArrayRefFromRvecArrayRef(sendBufferAccess.buffer); - int n = 0; + gmx::ArrayRef sendBuffer = realArrayRefFromRvecArrayRef(sendBufferAccess.buffer); + int n = 0; for (int j : ind.index) { sendBuffer[n++] = v[j]; } - DDBufferAccess receiveBufferAccess(comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); + DDBufferAccess receiveBufferAccess( + comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); - gmx::ArrayRef receiveBuffer; + gmx::ArrayRef receiveBuffer; if (cd->receiveInPlace) { receiveBuffer = gmx::arrayRefFromArray(v + nat_tot, ind.nrecv[nzone + 1]); @@ -528,8 +526,7 @@ void dd_atom_spread_real(gmx_domdec_t *dd, real v[]) receiveBuffer = realArrayRefFromRvecArrayRef(receiveBufferAccess.buffer); } /* Send and receive the data */ - ddSendrecv(dd, d, dddirBackward, - sendBuffer, receiveBuffer); + ddSendrecv(dd, d, dddirBackward, sendBuffer, receiveBuffer); if (!cd->receiveInPlace) { int j = 0; @@ -541,40 +538,41 @@ void dd_atom_spread_real(gmx_domdec_t *dd, real v[]) } } } - nat_tot += ind.nrecv[nzone+1]; + nat_tot += ind.nrecv[nzone + 1]; } nzone += nzone; } } -void dd_atom_sum_real(gmx_domdec_t *dd, real v[]) +void dd_atom_sum_real(gmx_domdec_t* dd, real v[]) { int nzone, nat_tot; - gmx_domdec_comm_t *comm; - gmx_domdec_comm_dim_t *cd; + gmx_domdec_comm_t* comm; + gmx_domdec_comm_dim_t* cd; comm = dd->comm; - nzone = comm->zones.n/2; + nzone = comm->zones.n / 2; nat_tot = comm->atomRanges.end(DDAtomRanges::Type::Zones); - for (int d = dd->ndim-1; d >= 0; d--) + for (int d = dd->ndim - 1; d >= 0; d--) { cd = &comm->cd[d]; for (int p = cd->numPulses() - 1; p >= 0; p--) { - const gmx_domdec_ind_t &ind = cd->ind[p]; + const gmx_domdec_ind_t& ind = cd->ind[p]; /* Note: We provision for RVec instead of real, so a factor of 3 * more than needed. The buffer actually already has this size * and we typecast, so this works as intended. */ DDBufferAccess receiveBufferAccess(comm->rvecBuffer, ind.nsend[nzone + 1]); - gmx::ArrayRef receiveBuffer = realArrayRefFromRvecArrayRef(receiveBufferAccess.buffer); + gmx::ArrayRef receiveBuffer = realArrayRefFromRvecArrayRef(receiveBufferAccess.buffer); nat_tot -= ind.nrecv[nzone + 1]; - DDBufferAccess sendBufferAccess(comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); + DDBufferAccess sendBufferAccess( + comm->rvecBuffer2, cd->receiveInPlace ? 0 : ind.nrecv[nzone + 1]); - gmx::ArrayRef sendBuffer; + gmx::ArrayRef sendBuffer; if (cd->receiveInPlace) { sendBuffer = gmx::arrayRefFromArray(v + nat_tot, ind.nrecv[nzone + 1]); @@ -582,7 +580,7 @@ void dd_atom_sum_real(gmx_domdec_t *dd, real v[]) else { sendBuffer = realArrayRefFromRvecArrayRef(sendBufferAccess.buffer); - int j = 0; + int j = 0; for (int zone = 0; zone < nzone; zone++) { for (int i = ind.cell2at0[zone]; i < ind.cell2at1[zone]; i++) @@ -592,8 +590,7 @@ void dd_atom_sum_real(gmx_domdec_t *dd, real v[]) } } /* Communicate the forces */ - ddSendrecv(dd, d, dddirForward, - sendBuffer, receiveBuffer); + ddSendrecv(dd, d, dddirForward, sendBuffer, receiveBuffer); /* Add the received forces */ int n = 0; for (int j : ind.index) @@ -606,12 +603,12 @@ void dd_atom_sum_real(gmx_domdec_t *dd, real v[]) } } -real dd_cutoff_multibody(const gmx_domdec_t *dd) +real dd_cutoff_multibody(const gmx_domdec_t* dd) { - const gmx_domdec_comm_t &comm = *dd->comm; - const DDSystemInfo &systemInfo = comm.systemInfo; + const gmx_domdec_comm_t& comm = *dd->comm; + const DDSystemInfo& systemInfo = comm.systemInfo; - real r = -1; + real r = -1; if (systemInfo.haveInterDomainMultiBodyBondeds) { if (comm.cutoff_mbody > 0) @@ -640,7 +637,7 @@ real dd_cutoff_multibody(const gmx_domdec_t *dd) return r; } -real dd_cutoff_twobody(const gmx_domdec_t *dd) +real dd_cutoff_twobody(const gmx_domdec_t* dd) { real r_mb; @@ -650,8 +647,8 @@ real dd_cutoff_twobody(const gmx_domdec_t *dd) } -static void dd_cart_coord2pmecoord(const DDRankSetup &ddRankSetup, - const CartesianRankSetup &cartSetup, +static void dd_cart_coord2pmecoord(const DDRankSetup& ddRankSetup, + const CartesianRankSetup& cartSetup, const ivec coord, ivec coord_pme) { @@ -659,12 +656,11 @@ static void dd_cart_coord2pmecoord(const DDRankSetup &ddRankSetup, const int ntot = cartSetup.ntot[cartSetup.cartpmedim]; copy_ivec(coord, coord_pme); coord_pme[cartSetup.cartpmedim] = - nc + (coord[cartSetup.cartpmedim]*(ntot - nc) + (ntot - nc)/2)/nc; + nc + (coord[cartSetup.cartpmedim] * (ntot - nc) + (ntot - nc) / 2) / nc; } /* Returns the PME rank index in 0...npmenodes-1 for the PP cell with index ddCellIndex */ -static int ddindex2pmeindex(const DDRankSetup &ddRankSetup, - const int ddCellIndex) +static int ddindex2pmeindex(const DDRankSetup& ddRankSetup, const int ddCellIndex) { const int npp = ddRankSetup.numPPRanks; const int npme = ddRankSetup.numRanksDoingPme; @@ -673,14 +669,14 @@ static int ddindex2pmeindex(const DDRankSetup &ddRankSetup, * by assuming that the major index of both is x. * We add npme/2 to obtain an even distribution. */ - return (ddCellIndex*npme + npme/2)/npp; + return (ddCellIndex * npme + npme / 2) / npp; } -static std::vector dd_interleaved_pme_ranks(const DDRankSetup &ddRankSetup) +static std::vector dd_interleaved_pme_ranks(const DDRankSetup& ddRankSetup) { std::vector pmeRanks(ddRankSetup.numRanksDoingPme); - int n = 0; + int n = 0; for (int i = 0; i < ddRankSetup.numPPRanks; i++) { const int p0 = ddindex2pmeindex(ddRankSetup, i); @@ -689,7 +685,7 @@ static std::vector dd_interleaved_pme_ranks(const DDRankSetup &ddRankSetup) { if (debug) { - fprintf(debug, "pme_rank[%d] = %d\n", n, i+1+n); + fprintf(debug, "pme_rank[%d] = %d\n", n, i + 1 + n); } pmeRanks[n] = i + 1 + n; n++; @@ -699,9 +695,9 @@ static std::vector dd_interleaved_pme_ranks(const DDRankSetup &ddRankSetup) return pmeRanks; } -static int gmx_ddcoord2pmeindex(const t_commrec *cr, int x, int y, int z) +static int gmx_ddcoord2pmeindex(const t_commrec* cr, int x, int y, int z) { - gmx_domdec_t *dd; + gmx_domdec_t* dd; ivec coords; int slab; @@ -727,9 +723,9 @@ static int gmx_ddcoord2pmeindex(const t_commrec *cr, int x, int y, int z) return slab; } -static int ddcoord2simnodeid(const t_commrec *cr, int x, int y, int z) +static int ddcoord2simnodeid(const t_commrec* cr, int x, int y, int z) { - const CartesianRankSetup &cartSetup = cr->dd->comm->cartesianRankSetup; + const CartesianRankSetup& cartSetup = cr->dd->comm->cartesianRankSetup; ivec coords = { x, y, z }; int nodeid = -1; @@ -762,13 +758,13 @@ static int ddcoord2simnodeid(const t_commrec *cr, int x, int y, int z) return nodeid; } -static int dd_simnode2pmenode(const DDRankSetup &ddRankSetup, - const CartesianRankSetup &cartSetup, - gmx::ArrayRef pmeRanks, - const t_commrec gmx_unused *cr, +static int dd_simnode2pmenode(const DDRankSetup& ddRankSetup, + const CartesianRankSetup& cartSetup, + gmx::ArrayRef pmeRanks, + const t_commrec gmx_unused* cr, const int sim_nodeid) { - int pmenode = -1; + int pmenode = -1; /* This assumes a uniform x domain decomposition grid cell size */ if (cartSetup.bCartesianPP_PME) @@ -821,31 +817,26 @@ static int dd_simnode2pmenode(const DDRankSetup &ddRankSetup, return pmenode; } -NumPmeDomains getNumPmeDomains(const gmx_domdec_t *dd) +NumPmeDomains getNumPmeDomains(const gmx_domdec_t* dd) { if (dd != nullptr) { - return { - dd->comm->ddRankSetup.npmenodes_x, - dd->comm->ddRankSetup.npmenodes_y - }; + return { dd->comm->ddRankSetup.npmenodes_x, dd->comm->ddRankSetup.npmenodes_y }; } else { - return { - 1, 1 - }; + return { 1, 1 }; } } -std::vector get_pme_ddranks(const t_commrec *cr, - const int pmenodeid) +std::vector get_pme_ddranks(const t_commrec* cr, const int pmenodeid) { - const DDRankSetup &ddRankSetup = cr->dd->comm->ddRankSetup; - const CartesianRankSetup &cartSetup = cr->dd->comm->cartesianRankSetup; - GMX_RELEASE_ASSERT(ddRankSetup.usePmeOnlyRanks, "This function should only be called when PME-only ranks are in use"); - std::vector ddranks; - ddranks.reserve((ddRankSetup.numPPRanks + ddRankSetup.numRanksDoingPme - 1)/ddRankSetup.numRanksDoingPme); + const DDRankSetup& ddRankSetup = cr->dd->comm->ddRankSetup; + const CartesianRankSetup& cartSetup = cr->dd->comm->cartesianRankSetup; + GMX_RELEASE_ASSERT(ddRankSetup.usePmeOnlyRanks, + "This function should only be called when PME-only ranks are in use"); + std::vector ddranks; + ddranks.reserve((ddRankSetup.numPPRanks + ddRankSetup.numRanksDoingPme - 1) / ddRankSetup.numRanksDoingPme); for (int x = 0; x < ddRankSetup.numPPCells[XX]; x++) { @@ -858,9 +849,8 @@ std::vector get_pme_ddranks(const t_commrec *cr, ivec coord = { x, y, z }; ivec coord_pme; dd_cart_coord2pmecoord(ddRankSetup, cartSetup, coord, coord_pme); - if (cr->dd->ci[XX] == coord_pme[XX] && - cr->dd->ci[YY] == coord_pme[YY] && - cr->dd->ci[ZZ] == coord_pme[ZZ]) + if (cr->dd->ci[XX] == coord_pme[XX] && cr->dd->ci[YY] == coord_pme[YY] + && cr->dd->ci[ZZ] == coord_pme[ZZ]) { ddranks.push_back(ddcoord2simnodeid(cr, x, y, z)); } @@ -879,16 +869,14 @@ std::vector get_pme_ddranks(const t_commrec *cr, return ddranks; } -static gmx_bool receive_vir_ener(const gmx_domdec_t *dd, - gmx::ArrayRef pmeRanks, - const t_commrec *cr) +static gmx_bool receive_vir_ener(const gmx_domdec_t* dd, gmx::ArrayRef pmeRanks, const t_commrec* cr) { - gmx_bool bReceive = TRUE; + gmx_bool bReceive = TRUE; - const DDRankSetup &ddRankSetup = dd->comm->ddRankSetup; + const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup; if (ddRankSetup.usePmeOnlyRanks) { - const CartesianRankSetup &cartSetup = dd->comm->cartesianRankSetup; + const CartesianRankSetup& cartSetup = dd->comm->cartesianRankSetup; if (cartSetup.bCartesianPP_PME) { #if GMX_MPI @@ -907,14 +895,16 @@ static gmx_bool receive_vir_ener(const gmx_domdec_t *dd, } } #else - GMX_RELEASE_ASSERT(false, "Without MPI we should not have Cartesian PP-PME with #PMEnodes < #DDnodes"); + GMX_RELEASE_ASSERT( + false, + "Without MPI we should not have Cartesian PP-PME with #PMEnodes < #DDnodes"); #endif } else { int pmenode = dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, cr->sim_nodeid); - if (cr->sim_nodeid+1 < cr->nnodes && - dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, cr->sim_nodeid + 1) == pmenode) + if (cr->sim_nodeid + 1 < cr->nnodes + && dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, cr->sim_nodeid + 1) == pmenode) { /* This is not the last PP node for pmenode */ bReceive = FALSE; @@ -925,32 +915,32 @@ static gmx_bool receive_vir_ener(const gmx_domdec_t *dd, return bReceive; } -static void set_slb_pme_dim_f(gmx_domdec_t *dd, int dim, real **dim_f) +static void set_slb_pme_dim_f(gmx_domdec_t* dd, int dim, real** dim_f) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int i; comm = dd->comm; - snew(*dim_f, dd->nc[dim]+1); + snew(*dim_f, dd->nc[dim] + 1); (*dim_f)[0] = 0; for (i = 1; i < dd->nc[dim]; i++) { if (comm->slb_frac[dim]) { - (*dim_f)[i] = (*dim_f)[i-1] + comm->slb_frac[dim][i-1]; + (*dim_f)[i] = (*dim_f)[i - 1] + comm->slb_frac[dim][i - 1]; } else { - (*dim_f)[i] = static_cast(i)/static_cast(dd->nc[dim]); + (*dim_f)[i] = static_cast(i) / static_cast(dd->nc[dim]); } } (*dim_f)[dd->nc[dim]] = 1; } -static void init_ddpme(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, int dimind) +static void init_ddpme(gmx_domdec_t* dd, gmx_ddpme_t* ddpme, int dimind) { - const DDRankSetup &ddRankSetup = dd->comm->ddRankSetup; + const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup; if (dimind == 0 && dd->dim[0] == YY && ddRankSetup.npmenodes_x == 1) { @@ -962,16 +952,14 @@ static void init_ddpme(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, int dimind) } ddpme->dim_match = (ddpme->dim == dd->dim[dimind]); - ddpme->nslab = (ddpme->dim == 0 ? - ddRankSetup.npmenodes_x : - ddRankSetup.npmenodes_y); + ddpme->nslab = (ddpme->dim == 0 ? ddRankSetup.npmenodes_x : ddRankSetup.npmenodes_y); if (ddpme->nslab <= 1) { return; } - const int nso = ddRankSetup.numRanksDoingPme/ddpme->nslab; + const int nso = ddRankSetup.numRanksDoingPme / ddpme->nslab; /* Determine for each PME slab the PP location range for dimension dim */ snew(ddpme->pp_min, ddpme->nslab); snew(ddpme->pp_max, ddpme->nslab); @@ -993,7 +981,7 @@ static void init_ddpme(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, int dimind) int slab; if (dimind == 0) { - slab = pmeindex/nso; + slab = pmeindex / nso; } else { @@ -1007,9 +995,9 @@ static void init_ddpme(gmx_domdec_t *dd, gmx_ddpme_t *ddpme, int dimind) set_slb_pme_dim_f(dd, ddpme->dim, &ddpme->slb_dim_f); } -int dd_pme_maxshift_x(const gmx_domdec_t *dd) +int dd_pme_maxshift_x(const gmx_domdec_t* dd) { - const DDRankSetup &ddRankSetup = dd->comm->ddRankSetup; + const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup; if (ddRankSetup.ddpme[0].dim == XX) { @@ -1021,9 +1009,9 @@ int dd_pme_maxshift_x(const gmx_domdec_t *dd) } } -int dd_pme_maxshift_y(const gmx_domdec_t *dd) +int dd_pme_maxshift_y(const gmx_domdec_t* dd) { - const DDRankSetup &ddRankSetup = dd->comm->ddRankSetup; + const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup; if (ddRankSetup.ddpme[0].dim == YY) { @@ -1039,12 +1027,12 @@ int dd_pme_maxshift_y(const gmx_domdec_t *dd) } } -bool ddHaveSplitConstraints(const gmx_domdec_t &dd) +bool ddHaveSplitConstraints(const gmx_domdec_t& dd) { return dd.comm->systemInfo.haveSplitConstraints; } -void dd_cycles_add(const gmx_domdec_t *dd, float cycles, int ddCycl) +void dd_cycles_add(const gmx_domdec_t* dd, float cycles, int ddCycl) { /* Note that the cycles value can be incorrect, either 0 or some * extremely large value, when our thread migrated to another core @@ -1065,12 +1053,12 @@ void dd_cycles_add(const gmx_domdec_t *dd, float cycles, int ddCycl) } #if GMX_MPI -static void make_load_communicator(gmx_domdec_t *dd, int dim_ind, ivec loc) +static void make_load_communicator(gmx_domdec_t* dd, int dim_ind, ivec loc) { - MPI_Comm c_row; - int dim, i, rank; - ivec loc_c; - gmx_bool bPartOfGroup = FALSE; + MPI_Comm c_row; + int dim, i, rank; + ivec loc_c; + gmx_bool bPartOfGroup = FALSE; dim = dd->dim[dim_ind]; copy_ivec(loc, loc_c); @@ -1084,21 +1072,20 @@ static void make_load_communicator(gmx_domdec_t *dd, int dim_ind, ivec loc) bPartOfGroup = TRUE; } } - MPI_Comm_split(dd->mpi_comm_all, bPartOfGroup ? 0 : MPI_UNDEFINED, dd->rank, - &c_row); + MPI_Comm_split(dd->mpi_comm_all, bPartOfGroup ? 0 : MPI_UNDEFINED, dd->rank, &c_row); if (bPartOfGroup) { dd->comm->mpi_comm_load[dim_ind] = c_row; if (!isDlbDisabled(dd->comm)) { - DDCellsizesWithDlb &cellsizes = dd->comm->cellsizesWithDlb[dim_ind]; + DDCellsizesWithDlb& cellsizes = dd->comm->cellsizesWithDlb[dim_ind]; if (dd->ci[dim] == dd->master_ci[dim]) { /* This is the root process of this row */ - cellsizes.rowMaster = std::make_unique(); + cellsizes.rowMaster = std::make_unique(); - RowMaster &rowMaster = *cellsizes.rowMaster; + RowMaster& rowMaster = *cellsizes.rowMaster; rowMaster.cellFrac.resize(ddCellFractionBufferSize(dd, dim_ind)); rowMaster.oldCellFrac.resize(dd->nc[dim] + 1); rowMaster.isCellMin.resize(dd->nc[dim]); @@ -1116,18 +1103,17 @@ static void make_load_communicator(gmx_domdec_t *dd, int dim_ind, ivec loc) } if (dd->ci[dim] == dd->master_ci[dim]) { - snew(dd->comm->load[dim_ind].load, dd->nc[dim]*DD_NLOAD_MAX); + snew(dd->comm->load[dim_ind].load, dd->nc[dim] * DD_NLOAD_MAX); } } } #endif -void dd_setup_dlb_resource_sharing(const t_commrec *cr, - int gpu_id) +void dd_setup_dlb_resource_sharing(const t_commrec* cr, int gpu_id) { #if GMX_MPI int physicalnode_id_hash; - gmx_domdec_t *dd; + gmx_domdec_t* dd; MPI_Comm mpi_comm_pp_physicalnode; if (!thisRankHasDuty(cr, DUTY_PP) || gpu_id < 0) @@ -1145,8 +1131,8 @@ void dd_setup_dlb_resource_sharing(const t_commrec *cr, if (debug) { fprintf(debug, "dd_setup_dd_dlb_gpu_sharing:\n"); - fprintf(debug, "DD PP rank %d physical node hash %d gpu_id %d\n", - dd->rank, physicalnode_id_hash, gpu_id); + fprintf(debug, "DD PP rank %d physical node hash %d gpu_id %d\n", dd->rank, + physicalnode_id_hash, gpu_id); } /* Split the PP communicator over the physical nodes */ /* TODO: See if we should store this (before), as it's also used for @@ -1154,10 +1140,8 @@ void dd_setup_dlb_resource_sharing(const t_commrec *cr, */ // TODO PhysicalNodeCommunicator could be extended/used to handle // the need for per-node per-group communicators. - MPI_Comm_split(dd->mpi_comm_all, physicalnode_id_hash, dd->rank, - &mpi_comm_pp_physicalnode); - MPI_Comm_split(mpi_comm_pp_physicalnode, gpu_id, dd->rank, - &dd->comm->mpi_comm_gpu_shared); + MPI_Comm_split(dd->mpi_comm_all, physicalnode_id_hash, dd->rank, &mpi_comm_pp_physicalnode); + MPI_Comm_split(mpi_comm_pp_physicalnode, gpu_id, dd->rank, &dd->comm->mpi_comm_gpu_shared); MPI_Comm_free(&mpi_comm_pp_physicalnode); MPI_Comm_size(dd->comm->mpi_comm_gpu_shared, &dd->comm->nrank_gpu_shared); @@ -1178,7 +1162,7 @@ void dd_setup_dlb_resource_sharing(const t_commrec *cr, #endif } -static void make_load_communicators(gmx_domdec_t gmx_unused *dd) +static void make_load_communicators(gmx_domdec_t gmx_unused* dd) { #if GMX_MPI int dim0, dim1, i, j; @@ -1231,11 +1215,11 @@ static void make_load_communicators(gmx_domdec_t gmx_unused *dd) } /*! \brief Sets up the relation between neighboring domains and zones */ -static void setup_neighbor_relations(gmx_domdec_t *dd) +static void setup_neighbor_relations(gmx_domdec_t* dd) { - int d, dim, m; - ivec tmp, s; - gmx_domdec_zones_t *zones; + int d, dim, m; + ivec tmp, s; + gmx_domdec_zones_t* zones; GMX_ASSERT((dd->ndim >= 0) && (dd->ndim <= DIM), "Must have valid number of dimensions for DD"); for (d = 0; d < dd->ndim; d++) @@ -1249,10 +1233,8 @@ static void setup_neighbor_relations(gmx_domdec_t *dd) dd->neighbor[d][1] = ddcoord2ddnodeid(dd, tmp); if (debug) { - fprintf(debug, "DD rank %d neighbor ranks in dir %d are + %d - %d\n", - dd->rank, dim, - dd->neighbor[d][0], - dd->neighbor[d][1]); + fprintf(debug, "DD rank %d neighbor ranks in dir %d are + %d - %d\n", dd->rank, dim, + dd->neighbor[d][0], dd->neighbor[d][1]); } } @@ -1290,17 +1272,17 @@ static void setup_neighbor_relations(gmx_domdec_t *dd) } for (int iZoneIndex = 0; iZoneIndex < nizone; iZoneIndex++) { - GMX_RELEASE_ASSERT(ddNonbondedZonePairRanges[iZoneIndex][0] == iZoneIndex, - "The first element for each ddNonbondedZonePairRanges should match its index"); + GMX_RELEASE_ASSERT( + ddNonbondedZonePairRanges[iZoneIndex][0] == iZoneIndex, + "The first element for each ddNonbondedZonePairRanges should match its index"); DDPairInteractionRanges iZone; iZone.iZoneIndex = iZoneIndex; /* dd_zp3 is for 3D decomposition, for fewer dimensions use only * j-zones up to nzone. */ - iZone.jZoneRange = - gmx::Range(std::min(ddNonbondedZonePairRanges[iZoneIndex][1], nzone), - std::min(ddNonbondedZonePairRanges[iZoneIndex][2], nzone)); + iZone.jZoneRange = gmx::Range(std::min(ddNonbondedZonePairRanges[iZoneIndex][1], nzone), + std::min(ddNonbondedZonePairRanges[iZoneIndex][2], nzone)); for (dim = 0; dim < DIM; dim++) { if (dd->nc[dim] == 1) @@ -1343,21 +1325,21 @@ static void setup_neighbor_relations(gmx_domdec_t *dd) } } -static void make_pp_communicator(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - t_commrec gmx_unused *cr, - bool gmx_unused reorder) +static void make_pp_communicator(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + t_commrec gmx_unused* cr, + bool gmx_unused reorder) { #if GMX_MPI - gmx_domdec_comm_t *comm = dd->comm; - CartesianRankSetup &cartSetup = comm->cartesianRankSetup; + gmx_domdec_comm_t* comm = dd->comm; + CartesianRankSetup& cartSetup = comm->cartesianRankSetup; if (cartSetup.bCartesianPP) { /* Set up cartesian communication for the particle-particle part */ - GMX_LOG(mdlog.info).appendTextFormatted( - "Will use a Cartesian communicator: %d x %d x %d", - dd->nc[XX], dd->nc[YY], dd->nc[ZZ]); + GMX_LOG(mdlog.info) + .appendTextFormatted("Will use a Cartesian communicator: %d x %d x %d", dd->nc[XX], + dd->nc[YY], dd->nc[ZZ]); ivec periods; for (int i = 0; i < DIM; i++) @@ -1365,8 +1347,7 @@ static void make_pp_communicator(const gmx::MDLogger &mdlog, periods[i] = TRUE; } MPI_Comm comm_cart; - MPI_Cart_create(cr->mpi_comm_mygroup, DIM, dd->nc, periods, static_cast(reorder), - &comm_cart); + MPI_Cart_create(cr->mpi_comm_mygroup, DIM, dd->nc, periods, static_cast(reorder), &comm_cart); /* We overwrite the old communicator with the new cartesian one */ cr->mpi_comm_mygroup = comm_cart; } @@ -1449,22 +1430,20 @@ static void make_pp_communicator(const gmx::MDLogger &mdlog, } #endif - GMX_LOG(mdlog.info).appendTextFormatted( - "Domain decomposition rank %d, coordinates %d %d %d\n", - dd->rank, dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); + GMX_LOG(mdlog.info) + .appendTextFormatted("Domain decomposition rank %d, coordinates %d %d %d\n", dd->rank, + dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); if (debug) { - fprintf(debug, - "Domain decomposition rank %d, coordinates %d %d %d\n\n", - dd->rank, dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); + fprintf(debug, "Domain decomposition rank %d, coordinates %d %d %d\n\n", dd->rank, + dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); } } -static void receive_ddindex2simnodeid(gmx_domdec_t *dd, - t_commrec *cr) +static void receive_ddindex2simnodeid(gmx_domdec_t* dd, t_commrec* cr) { #if GMX_MPI - CartesianRankSetup &cartSetup = dd->comm->cartesianRankSetup; + CartesianRankSetup& cartSetup = dd->comm->cartesianRankSetup; if (!cartSetup.bCartesianPP_PME && cartSetup.bCartesianPP) { @@ -1484,21 +1463,20 @@ static void receive_ddindex2simnodeid(gmx_domdec_t *dd, #endif } -static CartesianRankSetup -split_communicator(const gmx::MDLogger &mdlog, - t_commrec *cr, - const DdRankOrder ddRankOrder, - bool gmx_unused reorder, - const DDRankSetup &ddRankSetup, - ivec ddCellIndex, - std::vector *pmeRanks) +static CartesianRankSetup split_communicator(const gmx::MDLogger& mdlog, + t_commrec* cr, + const DdRankOrder ddRankOrder, + bool gmx_unused reorder, + const DDRankSetup& ddRankSetup, + ivec ddCellIndex, + std::vector* pmeRanks) { CartesianRankSetup cartSetup; cartSetup.bCartesianPP = (ddRankOrder == DdRankOrder::cartesian); cartSetup.bCartesianPP_PME = false; - const ivec &numDDCells = ddRankSetup.numPPCells; + const ivec& numDDCells = ddRankSetup.numPPCells; /* Initially we set ntot to the number of PP cells */ copy_ivec(numDDCells, cartSetup.ntot); @@ -1508,7 +1486,7 @@ split_communicator(const gmx::MDLogger &mdlog, bool bDiv[DIM]; for (int i = 1; i < DIM; i++) { - bDiv[i] = ((ddRankSetup.numRanksDoingPme*numDDCells[i]) % numDDCellsTot == 0); + bDiv[i] = ((ddRankSetup.numRanksDoingPme * numDDCells[i]) % numDDCellsTot == 0); } if (bDiv[YY] || bDiv[ZZ]) { @@ -1520,9 +1498,7 @@ split_communicator(const gmx::MDLogger &mdlog, * on the PP communication. * But for the PME communication the opposite might be better. */ - if (bDiv[ZZ] && (ddRankSetup.npmenodes_y > 1 || - !bDiv[YY] || - numDDCells[YY] > numDDCells[ZZ])) + if (bDiv[ZZ] && (ddRankSetup.npmenodes_y > 1 || !bDiv[YY] || numDDCells[YY] > numDDCells[ZZ])) { cartSetup.cartpmedim = ZZ; } @@ -1530,17 +1506,19 @@ split_communicator(const gmx::MDLogger &mdlog, { cartSetup.cartpmedim = YY; } - cartSetup.ntot[cartSetup.cartpmedim] - += (ddRankSetup.numRanksDoingPme*numDDCells[cartSetup.cartpmedim])/numDDCellsTot; + cartSetup.ntot[cartSetup.cartpmedim] += + (ddRankSetup.numRanksDoingPme * numDDCells[cartSetup.cartpmedim]) / numDDCellsTot; } else { - GMX_LOG(mdlog.info).appendTextFormatted( - "Number of PME-only ranks (%d) is not a multiple of nx*ny (%d*%d) or nx*nz (%d*%d)", - ddRankSetup.numRanksDoingPme, - numDDCells[XX], numDDCells[YY], - numDDCells[XX], numDDCells[ZZ]); - GMX_LOG(mdlog.info).appendText("Will not use a Cartesian communicator for PP <-> PME\n"); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Number of PME-only ranks (%d) is not a multiple of nx*ny (%d*%d) or " + "nx*nz (%d*%d)", + ddRankSetup.numRanksDoingPme, numDDCells[XX], numDDCells[YY], + numDDCells[XX], numDDCells[ZZ]); + GMX_LOG(mdlog.info) + .appendText("Will not use a Cartesian communicator for PP <-> PME\n"); } } @@ -1550,9 +1528,10 @@ split_communicator(const gmx::MDLogger &mdlog, int rank; ivec periods; - GMX_LOG(mdlog.info).appendTextFormatted( - "Will use a Cartesian communicator for PP <-> PME: %d x %d x %d", - cartSetup.ntot[XX], cartSetup.ntot[YY], cartSetup.ntot[ZZ]); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Will use a Cartesian communicator for PP <-> PME: %d x %d x %d", + cartSetup.ntot[XX], cartSetup.ntot[YY], cartSetup.ntot[ZZ]); for (int i = 0; i < DIM; i++) { @@ -1575,25 +1554,23 @@ split_communicator(const gmx::MDLogger &mdlog, MPI_Cart_coords(cr->mpi_comm_mysim, cr->sim_nodeid, DIM, ddCellIndex); - GMX_LOG(mdlog.info).appendTextFormatted( - "Cartesian rank %d, coordinates %d %d %d\n", - cr->sim_nodeid, ddCellIndex[XX], ddCellIndex[YY], ddCellIndex[ZZ]); + GMX_LOG(mdlog.info) + .appendTextFormatted("Cartesian rank %d, coordinates %d %d %d\n", cr->sim_nodeid, + ddCellIndex[XX], ddCellIndex[YY], ddCellIndex[ZZ]); if (ddCellIndex[cartSetup.cartpmedim] < numDDCells[cartSetup.cartpmedim]) { cr->duty = DUTY_PP; } - if (!ddRankSetup.usePmeOnlyRanks || - ddCellIndex[cartSetup.cartpmedim] >= numDDCells[cartSetup.cartpmedim]) + if (!ddRankSetup.usePmeOnlyRanks + || ddCellIndex[cartSetup.cartpmedim] >= numDDCells[cartSetup.cartpmedim]) { cr->duty = DUTY_PME; } /* Split the sim communicator into PP and PME only nodes */ - MPI_Comm_split(cr->mpi_comm_mysim, - getThisRankDuties(cr), - dd_index(cartSetup.ntot, ddCellIndex), - &cr->mpi_comm_mygroup); + MPI_Comm_split(cr->mpi_comm_mysim, getThisRankDuties(cr), + dd_index(cartSetup.ntot, ddCellIndex), &cr->mpi_comm_mygroup); #else GMX_UNUSED_VALUE(ddCellIndex); #endif @@ -1610,10 +1587,8 @@ split_communicator(const gmx::MDLogger &mdlog, GMX_LOG(mdlog.info).appendText("Interleaving PP and PME ranks"); *pmeRanks = dd_interleaved_pme_ranks(ddRankSetup); break; - case DdRankOrder::cartesian: - break; - default: - gmx_fatal(FARGS, "Invalid ddRankOrder=%d", static_cast(ddRankOrder)); + case DdRankOrder::cartesian: break; + default: gmx_fatal(FARGS, "Invalid ddRankOrder=%d", static_cast(ddRankOrder)); } if (dd_simnode2pmenode(ddRankSetup, cartSetup, *pmeRanks, cr, cr->sim_nodeid) == -1) @@ -1626,17 +1601,14 @@ split_communicator(const gmx::MDLogger &mdlog, } #if GMX_MPI /* Split the sim communicator into PP and PME only nodes */ - MPI_Comm_split(cr->mpi_comm_mysim, - getThisRankDuties(cr), - cr->nodeid, - &cr->mpi_comm_mygroup); + MPI_Comm_split(cr->mpi_comm_mysim, getThisRankDuties(cr), cr->nodeid, &cr->mpi_comm_mygroup); MPI_Comm_rank(cr->mpi_comm_mygroup, &cr->nodeid); #endif } - GMX_LOG(mdlog.info).appendTextFormatted( - "This rank does only %s work.\n", - thisRankHasDuty(cr, DUTY_PP) ? "particle-particle" : "PME-mesh"); + GMX_LOG(mdlog.info) + .appendTextFormatted("This rank does only %s work.\n", + thisRankHasDuty(cr, DUTY_PP) ? "particle-particle" : "PME-mesh"); return cartSetup; } @@ -1648,23 +1620,21 @@ split_communicator(const gmx::MDLogger &mdlog, * For PP ranks, sets the DD PP cell index in \p ddCellIndex. * With separate PME ranks in interleaved order, set the PME ranks in \p pmeRanks. */ -static CartesianRankSetup -makeGroupCommunicators(const gmx::MDLogger &mdlog, - const DDSettings &ddSettings, - const DdRankOrder ddRankOrder, - const DDRankSetup &ddRankSetup, - t_commrec *cr, - ivec ddCellIndex, - std::vector *pmeRanks) +static CartesianRankSetup makeGroupCommunicators(const gmx::MDLogger& mdlog, + const DDSettings& ddSettings, + const DdRankOrder ddRankOrder, + const DDRankSetup& ddRankSetup, + t_commrec* cr, + ivec ddCellIndex, + std::vector* pmeRanks) { CartesianRankSetup cartSetup; if (ddRankSetup.usePmeOnlyRanks) { /* Split the communicator into a PP and PME part */ - cartSetup = - split_communicator(mdlog, cr, ddRankOrder, ddSettings.useCartesianReorder, - ddRankSetup, ddCellIndex, pmeRanks); + cartSetup = split_communicator(mdlog, cr, ddRankOrder, ddSettings.useCartesianReorder, + ddRankSetup, ddCellIndex, pmeRanks); } else { @@ -1684,15 +1654,15 @@ makeGroupCommunicators(const gmx::MDLogger &mdlog, * For PME ranks get the rank id. * For PP only ranks, sets the PME-only rank. */ -static void setupGroupCommunication(const gmx::MDLogger &mdlog, - const DDSettings &ddSettings, - gmx::ArrayRef pmeRanks, - t_commrec *cr, - const int numAtomsInSystem, - gmx_domdec_t *dd) +static void setupGroupCommunication(const gmx::MDLogger& mdlog, + const DDSettings& ddSettings, + gmx::ArrayRef pmeRanks, + t_commrec* cr, + const int numAtomsInSystem, + gmx_domdec_t* dd) { - const DDRankSetup &ddRankSetup = dd->comm->ddRankSetup; - const CartesianRankSetup &cartSetup = dd->comm->cartesianRankSetup; + const DDRankSetup& ddRankSetup = dd->comm->ddRankSetup; + const CartesianRankSetup& cartSetup = dd->comm->cartesianRankSetup; if (thisRankHasDuty(cr, DUTY_PP)) { @@ -1701,9 +1671,7 @@ static void setupGroupCommunication(const gmx::MDLogger &mdlog, /* We (possibly) reordered the nodes in split_communicator, * so it is no longer required in make_pp_communicator. */ - const bool useCartesianReorder = - (ddSettings.useCartesianReorder && - !cartSetup.bCartesianPP_PME); + const bool useCartesianReorder = (ddSettings.useCartesianReorder && !cartSetup.bCartesianPP_PME); make_pp_communicator(mdlog, dd, cr, useCartesianReorder); } @@ -1715,12 +1683,12 @@ static void setupGroupCommunication(const gmx::MDLogger &mdlog, if (!thisRankHasDuty(cr, DUTY_PME)) { /* Set up the commnuication to our PME node */ - dd->pme_nodeid = dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, cr->sim_nodeid); + dd->pme_nodeid = dd_simnode2pmenode(ddRankSetup, cartSetup, pmeRanks, cr, cr->sim_nodeid); dd->pme_receive_vir_ener = receive_vir_ener(dd, pmeRanks, cr); if (debug) { - fprintf(debug, "My pme_nodeid %d receive ener %s\n", - dd->pme_nodeid, gmx::boolToString(dd->pme_receive_vir_ener)); + fprintf(debug, "My pme_nodeid %d receive ener %s\n", dd->pme_nodeid, + gmx::boolToString(dd->pme_receive_vir_ener)); } } else @@ -1731,24 +1699,20 @@ static void setupGroupCommunication(const gmx::MDLogger &mdlog, /* We can not use DDMASTER(dd), because dd->masterrank is set later */ if (MASTER(cr)) { - dd->ma = std::make_unique(dd->nc, - numAtomsInSystem, - numAtomsInSystem); + dd->ma = std::make_unique(dd->nc, numAtomsInSystem, numAtomsInSystem); } } -static real *get_slb_frac(const gmx::MDLogger &mdlog, - const char *dir, int nc, const char *size_string) +static real* get_slb_frac(const gmx::MDLogger& mdlog, const char* dir, int nc, const char* size_string) { - real *slb_frac, tot; + real * slb_frac, tot; int i, n; double dbl; slb_frac = nullptr; if (nc > 1 && size_string != nullptr) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Using static load balancing for the %s direction", dir); + GMX_LOG(mdlog.info).appendTextFormatted("Using static load balancing for the %s direction", dir); snew(slb_frac, nc); tot = 0; for (i = 0; i < nc; i++) @@ -1757,17 +1721,19 @@ static real *get_slb_frac(const gmx::MDLogger &mdlog, sscanf(size_string, "%20lf%n", &dbl, &n); if (dbl == 0) { - gmx_fatal(FARGS, "Incorrect or not enough DD cell size entries for direction %s: '%s'", dir, size_string); + gmx_fatal(FARGS, + "Incorrect or not enough DD cell size entries for direction %s: '%s'", + dir, size_string); } - slb_frac[i] = dbl; + slb_frac[i] = dbl; size_string += n; - tot += slb_frac[i]; + tot += slb_frac[i]; } /* Normalize */ std::string relativeCellSizes = "Relative cell sizes:"; for (i = 0; i < nc; i++) { - slb_frac[i] /= tot; + slb_frac[i] /= tot; relativeCellSizes += gmx::formatString(" %5.3f", slb_frac[i]); } GMX_LOG(mdlog.info).appendText(relativeCellSizes); @@ -1776,18 +1742,18 @@ static real *get_slb_frac(const gmx::MDLogger &mdlog, return slb_frac; } -static int multi_body_bondeds_count(const gmx_mtop_t *mtop) +static int multi_body_bondeds_count(const gmx_mtop_t* mtop) { int n = 0; gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); int nmol; - while (const InteractionLists *ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) + while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) { - for (auto &ilist : extractILists(*ilists, IF_BOND)) + for (auto& ilist : extractILists(*ilists, IF_BOND)) { - if (NRAL(ilist.functionType) > 2) + if (NRAL(ilist.functionType) > 2) { - n += nmol*(ilist.iatoms.size()/ilistStride(ilist)); + n += nmol * (ilist.iatoms.size() / ilistStride(ilist)); } } } @@ -1795,10 +1761,9 @@ static int multi_body_bondeds_count(const gmx_mtop_t *mtop) return n; } -static int dd_getenv(const gmx::MDLogger &mdlog, - const char *env_var, int def) +static int dd_getenv(const gmx::MDLogger& mdlog, const char* env_var, int def) { - char *val; + char* val; int nst; nst = def; @@ -1809,22 +1774,18 @@ static int dd_getenv(const gmx::MDLogger &mdlog, { nst = 1; } - GMX_LOG(mdlog.info).appendTextFormatted( - "Found env.var. %s = %s, using value %d", - env_var, val, nst); + GMX_LOG(mdlog.info).appendTextFormatted("Found env.var. %s = %s, using value %d", env_var, val, nst); } return nst; } -static void check_dd_restrictions(const gmx_domdec_t *dd, - const t_inputrec *ir, - const gmx::MDLogger &mdlog) +static void check_dd_restrictions(const gmx_domdec_t* dd, const t_inputrec* ir, const gmx::MDLogger& mdlog) { - if (ir->ePBC == epbcSCREW && - (dd->nc[XX] == 1 || dd->nc[YY] > 1 || dd->nc[ZZ] > 1)) + if (ir->ePBC == epbcSCREW && (dd->nc[XX] == 1 || dd->nc[YY] > 1 || dd->nc[ZZ] > 1)) { - gmx_fatal(FARGS, "With pbc=%s can only do domain decomposition in the x-direction", epbc_names[ir->ePBC]); + gmx_fatal(FARGS, "With pbc=%s can only do domain decomposition in the x-direction", + epbc_names[ir->ePBC]); } if (ir->nstlist == 0) @@ -1834,12 +1795,14 @@ static void check_dd_restrictions(const gmx_domdec_t *dd, if (ir->comm_mode == ecmANGULAR && ir->ePBC != epbcNONE) { - GMX_LOG(mdlog.warning).appendText("comm-mode angular will give incorrect results when the comm group partially crosses a periodic boundary"); + GMX_LOG(mdlog.warning) + .appendText( + "comm-mode angular will give incorrect results when the comm group " + "partially crosses a periodic boundary"); } } -static real average_cellsize_min(const gmx_ddbox_t &ddbox, - const ivec numDomains) +static real average_cellsize_min(const gmx_ddbox_t& ddbox, const ivec numDomains) { real r = ddbox.box_size[XX]; for (int d = 0; d < DIM; d++) @@ -1847,7 +1810,7 @@ static real average_cellsize_min(const gmx_ddbox_t &ddbox, if (numDomains[d] > 1) { /* Check using the initial average cell size */ - r = std::min(r, ddbox.box_size[d]*ddbox.skew_fac[d]/numDomains[d]); + r = std::min(r, ddbox.box_size[d] * ddbox.skew_fac[d] / numDomains[d]); } } @@ -1857,11 +1820,11 @@ static real average_cellsize_min(const gmx_ddbox_t &ddbox, /*! \brief Depending on the DLB initial value return the DLB switched off state or issue an error. */ static DlbState forceDlbOffOrBail(DlbState cmdlineDlbState, - const std::string &reasonStr, - const gmx::MDLogger &mdlog) + const std::string& reasonStr, + const gmx::MDLogger& mdlog) { - std::string dlbNotSupportedErr = "Dynamic load balancing requested, but "; - std::string dlbDisableNote = "NOTE: disabling dynamic load balancing as "; + std::string dlbNotSupportedErr = "Dynamic load balancing requested, but "; + std::string dlbDisableNote = "NOTE: disabling dynamic load balancing as "; if (cmdlineDlbState == DlbState::onUser) { @@ -1888,18 +1851,19 @@ static DlbState forceDlbOffOrBail(DlbState cmdlineDlbState, * \param [in] ir Pointer mdrun to input parameters. * \returns DLB initial/startup state. */ -static DlbState determineInitialDlbState(const gmx::MDLogger &mdlog, - DlbOption dlbOption, gmx_bool bRecordLoad, - const gmx::MdrunOptions &mdrunOptions, - const t_inputrec *ir) +static DlbState determineInitialDlbState(const gmx::MDLogger& mdlog, + DlbOption dlbOption, + gmx_bool bRecordLoad, + const gmx::MdrunOptions& mdrunOptions, + const t_inputrec* ir) { DlbState dlbState = DlbState::offCanTurnOn; switch (dlbOption) { case DlbOption::turnOnWhenUseful: dlbState = DlbState::offCanTurnOn; break; - case DlbOption::no: dlbState = DlbState::offUser; break; - case DlbOption::yes: dlbState = DlbState::onUser; break; + case DlbOption::no: dlbState = DlbState::offUser; break; + case DlbOption::yes: dlbState = DlbState::onUser; break; default: gmx_incons("Invalid dlbOption enum value"); } @@ -1913,14 +1877,16 @@ static DlbState determineInitialDlbState(const gmx::MDLogger &mdlog, /* Unsupported integrators */ if (!EI_DYNAMICS(ir->eI)) { - auto reasonStr = gmx::formatString("it is only supported with dynamics, not with integrator '%s'.", EI(ir->eI)); + auto reasonStr = gmx::formatString( + "it is only supported with dynamics, not with integrator '%s'.", EI(ir->eI)); return forceDlbOffOrBail(dlbState, reasonStr, mdlog); } /* Without cycle counters we can't time work to balance on */ if (!bRecordLoad) { - std::string reasonStr = "cycle counters unsupported or not enabled in the operating system kernel."; + std::string reasonStr = + "cycle counters unsupported or not enabled in the operating system kernel."; return forceDlbOffOrBail(dlbState, reasonStr, mdlog); } @@ -1929,32 +1895,36 @@ static DlbState determineInitialDlbState(const gmx::MDLogger &mdlog, std::string reasonStr = "you started a reproducible run."; switch (dlbState) { - case DlbState::offUser: - break; + case DlbState::offUser: break; case DlbState::offForever: GMX_RELEASE_ASSERT(false, "DlbState::offForever is not a valid initial state"); break; - case DlbState::offCanTurnOn: - return forceDlbOffOrBail(dlbState, reasonStr, mdlog); + case DlbState::offCanTurnOn: return forceDlbOffOrBail(dlbState, reasonStr, mdlog); case DlbState::onCanTurnOff: GMX_RELEASE_ASSERT(false, "DlbState::offCanTurnOff is not a valid initial state"); break; case DlbState::onUser: - return forceDlbOffOrBail(dlbState, reasonStr + " In load balanced runs binary reproducibility cannot be ensured.", mdlog); + return forceDlbOffOrBail( + dlbState, + reasonStr + + " In load balanced runs binary reproducibility cannot be " + "ensured.", + mdlog); default: - gmx_fatal(FARGS, "Death horror: undefined case (%d) for load balancing choice", static_cast(dlbState)); + gmx_fatal(FARGS, "Death horror: undefined case (%d) for load balancing choice", + static_cast(dlbState)); } } return dlbState; } -static gmx_domdec_comm_t *init_dd_comm() +static gmx_domdec_comm_t* init_dd_comm() { - gmx_domdec_comm_t *comm = new gmx_domdec_comm_t; + gmx_domdec_comm_t* comm = new gmx_domdec_comm_t; - comm->n_load_have = 0; - comm->n_load_collect = 0; + comm->n_load_have = 0; + comm->n_load_collect = 0; comm->haveTurnedOffDlb = false; @@ -1968,8 +1938,8 @@ static gmx_domdec_comm_t *init_dd_comm() comm->load_sum = 0; comm->load_max = 0; clear_ivec(comm->load_lim); - comm->load_mdf = 0; - comm->load_pme = 0; + comm->load_mdf = 0; + comm->load_pme = 0; /* This should be replaced by a unique pointer */ comm->balanceRegion = ddBalanceRegionAllocate(); @@ -1978,11 +1948,11 @@ static gmx_domdec_comm_t *init_dd_comm() } /* Returns whether mtop contains constraints and/or vsites */ -static bool systemHasConstraintsOrVsites(const gmx_mtop_t &mtop) +static bool systemHasConstraintsOrVsites(const gmx_mtop_t& mtop) { auto ilistLoop = gmx_mtop_ilistloop_init(mtop); int nmol; - while (const InteractionLists *ilists = gmx_mtop_ilistloop_next(ilistLoop, &nmol)) + while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(ilistLoop, &nmol)) { if (!extractILists(*ilists, IF_CONSTRAINT | IF_VSITE).empty()) { @@ -1993,11 +1963,11 @@ static bool systemHasConstraintsOrVsites(const gmx_mtop_t &mtop) return false; } -static void setupUpdateGroups(const gmx::MDLogger &mdlog, - const gmx_mtop_t &mtop, - const t_inputrec &inputrec, +static void setupUpdateGroups(const gmx::MDLogger& mdlog, + const gmx_mtop_t& mtop, + const t_inputrec& inputrec, const real cutoffMargin, - DDSystemInfo *systemInfo) + DDSystemInfo* systemInfo) { /* When we have constraints and/or vsites, it is beneficial to use * update groups (when possible) to allow independent update of groups. @@ -2009,22 +1979,20 @@ static void setupUpdateGroups(const gmx::MDLogger &mdlog, } systemInfo->updateGroupingPerMoleculetype = gmx::makeUpdateGroups(mtop); - systemInfo->useUpdateGroups = - (!systemInfo->updateGroupingPerMoleculetype.empty() && - getenv("GMX_NO_UPDATEGROUPS") == nullptr); + systemInfo->useUpdateGroups = (!systemInfo->updateGroupingPerMoleculetype.empty() + && getenv("GMX_NO_UPDATEGROUPS") == nullptr); if (systemInfo->useUpdateGroups) { int numUpdateGroups = 0; - for (const auto &molblock : mtop.molblock) + for (const auto& molblock : mtop.molblock) { - numUpdateGroups += molblock.nmol*systemInfo->updateGroupingPerMoleculetype[molblock.type].numBlocks(); + numUpdateGroups += molblock.nmol + * systemInfo->updateGroupingPerMoleculetype[molblock.type].numBlocks(); } - systemInfo->maxUpdateGroupRadius = - computeMaxUpdateGroupRadius(mtop, - systemInfo->updateGroupingPerMoleculetype, - maxReferenceTemperature(inputrec)); + systemInfo->maxUpdateGroupRadius = computeMaxUpdateGroupRadius( + mtop, systemInfo->updateGroupingPerMoleculetype, maxReferenceTemperature(inputrec)); /* To use update groups, the large domain-to-domain cutoff distance * should be compatible with the box size. @@ -2033,21 +2001,25 @@ static void setupUpdateGroups(const gmx::MDLogger &mdlog, if (systemInfo->useUpdateGroups) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Using update groups, nr %d, average size %.1f atoms, max. radius %.3f nm\n", - numUpdateGroups, - mtop.natoms/static_cast(numUpdateGroups), - systemInfo->maxUpdateGroupRadius); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Using update groups, nr %d, average size %.1f atoms, max. radius %.3f " + "nm\n", + numUpdateGroups, mtop.natoms / static_cast(numUpdateGroups), + systemInfo->maxUpdateGroupRadius); } else { - GMX_LOG(mdlog.info).appendTextFormatted("The combination of rlist and box size prohibits the use of update groups\n"); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "The combination of rlist and box size prohibits the use of update " + "groups\n"); systemInfo->updateGroupingPerMoleculetype.clear(); } } } -UnitCellInfo::UnitCellInfo(const t_inputrec &ir) : +UnitCellInfo::UnitCellInfo(const t_inputrec& ir) : npbcdim(ePBC2npbcdim(ir.ePBC)), numBoundedDimensions(inputrec2nboundeddim(&ir)), ddBoxIsDynamic(numBoundedDimensions < DIM || inputrecDynamicBox(&ir)), @@ -2056,10 +2028,9 @@ UnitCellInfo::UnitCellInfo(const t_inputrec &ir) : } /* Returns whether molecules are always whole, i.e. not broken by PBC */ -static bool -moleculesAreAlwaysWhole(const gmx_mtop_t &mtop, - const bool useUpdateGroups, - gmx::ArrayRef updateGroupingPerMoleculetype) +static bool moleculesAreAlwaysWhole(const gmx_mtop_t& mtop, + const bool useUpdateGroups, + gmx::ArrayRef updateGroupingPerMoleculetype) { if (useUpdateGroups) { @@ -2075,7 +2046,7 @@ moleculesAreAlwaysWhole(const gmx_mtop_t &mtop, } else { - for (const auto &moltype : mtop.moltype) + for (const auto& moltype : mtop.moltype) { if (moltype.atoms.nr > 1) { @@ -2088,18 +2059,17 @@ moleculesAreAlwaysWhole(const gmx_mtop_t &mtop, } /*! \brief Generate the simulation system information */ -static DDSystemInfo -getSystemInfo(const gmx::MDLogger &mdlog, - const t_commrec *cr, - const DomdecOptions &options, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef xGlobal) +static DDSystemInfo getSystemInfo(const gmx::MDLogger& mdlog, + const t_commrec* cr, + const DomdecOptions& options, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef xGlobal) { - const real tenPercentMargin = 1.1; + const real tenPercentMargin = 1.1; - DDSystemInfo systemInfo; + DDSystemInfo systemInfo; /* We need to decide on update groups early, as this affects communication distances */ systemInfo.useUpdateGroups = false; @@ -2109,14 +2079,12 @@ getSystemInfo(const gmx::MDLogger &mdlog, setupUpdateGroups(mdlog, mtop, ir, cutoffMargin, &systemInfo); } - systemInfo.moleculesAreAlwaysWhole = - moleculesAreAlwaysWhole(mtop, - systemInfo.useUpdateGroups, - systemInfo.updateGroupingPerMoleculetype); - systemInfo.haveInterDomainBondeds = (!systemInfo.moleculesAreAlwaysWhole || - mtop.bIntermolecularInteractions); - systemInfo.haveInterDomainMultiBodyBondeds = (systemInfo.haveInterDomainBondeds && - multi_body_bondeds_count(&mtop) > 0); + systemInfo.moleculesAreAlwaysWhole = moleculesAreAlwaysWhole( + mtop, systemInfo.useUpdateGroups, systemInfo.updateGroupingPerMoleculetype); + systemInfo.haveInterDomainBondeds = + (!systemInfo.moleculesAreAlwaysWhole || mtop.bIntermolecularInteractions); + systemInfo.haveInterDomainMultiBodyBondeds = + (systemInfo.haveInterDomainBondeds && multi_body_bondeds_count(&mtop) > 0); if (systemInfo.useUpdateGroups) { @@ -2125,8 +2093,8 @@ getSystemInfo(const gmx::MDLogger &mdlog, } else { - systemInfo.haveSplitConstraints = (gmx_mtop_ftype_count(mtop, F_CONSTR) > 0 || - gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0); + systemInfo.haveSplitConstraints = (gmx_mtop_ftype_count(mtop, F_CONSTR) > 0 + || gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0); systemInfo.haveSplitSettles = (gmx_mtop_ftype_count(mtop, F_SETTLE) > 0); } @@ -2156,16 +2124,11 @@ getSystemInfo(const gmx::MDLogger &mdlog, * We set the chance to 1 in a trillion steps. */ constexpr real c_chanceThatAtomMovesBeyondDomain = 1e-12; - const real limitForAtomDisplacement = - minCellSizeForAtomDisplacement(mtop, ir, - systemInfo.updateGroupingPerMoleculetype, - c_chanceThatAtomMovesBeyondDomain); - GMX_LOG(mdlog.info).appendTextFormatted( - "Minimum cell size due to atom displacement: %.3f nm", - limitForAtomDisplacement); + const real limitForAtomDisplacement = minCellSizeForAtomDisplacement( + mtop, ir, systemInfo.updateGroupingPerMoleculetype, c_chanceThatAtomMovesBeyondDomain); + GMX_LOG(mdlog.info).appendTextFormatted("Minimum cell size due to atom displacement: %.3f nm", limitForAtomDisplacement); - systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, - limitForAtomDisplacement); + systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, limitForAtomDisplacement); /* TODO: PME decomposition currently requires atoms not to be more than * 2/3 of comm->cutoff, which is >=rlist, outside of their domain. @@ -2181,22 +2144,28 @@ getSystemInfo(const gmx::MDLogger &mdlog, if (options.minimumCommunicationRange > 0) { systemInfo.minCutoffForMultiBody = - atomToAtomIntoDomainToDomainCutoff(systemInfo, options.minimumCommunicationRange); + atomToAtomIntoDomainToDomainCutoff(systemInfo, options.minimumCommunicationRange); if (options.useBondedCommunication) { - systemInfo.filterBondedCommunication = (systemInfo.minCutoffForMultiBody > systemInfo.cutoff); + systemInfo.filterBondedCommunication = + (systemInfo.minCutoffForMultiBody > systemInfo.cutoff); } else { - systemInfo.cutoff = std::max(systemInfo.cutoff, - systemInfo.minCutoffForMultiBody); + systemInfo.cutoff = std::max(systemInfo.cutoff, systemInfo.minCutoffForMultiBody); } } else if (ir.bPeriodicMols) { /* Can not easily determine the required cut-off */ - GMX_LOG(mdlog.warning).appendText("NOTE: Periodic molecules are present in this system. Because of this, the domain decomposition algorithm cannot easily determine the minimum cell size that it requires for treating bonded interactions. Instead, domain decomposition will assume that half the non-bonded cut-off will be a suitable lower bound."); - systemInfo.minCutoffForMultiBody = systemInfo.cutoff/2; + GMX_LOG(mdlog.warning) + .appendText( + "NOTE: Periodic molecules are present in this system. Because of this, " + "the domain decomposition algorithm cannot easily determine the " + "minimum cell size that it requires for treating bonded interactions. " + "Instead, domain decomposition will assume that half the non-bonded " + "cut-off will be a suitable lower bound."); + systemInfo.minCutoffForMultiBody = systemInfo.cutoff / 2; } else { @@ -2205,8 +2174,7 @@ getSystemInfo(const gmx::MDLogger &mdlog, if (MASTER(cr)) { dd_bonded_cg_distance(mdlog, &mtop, &ir, as_rvec_array(xGlobal.data()), box, - options.checkBondedInteractions, - &r_2b, &r_mb); + options.checkBondedInteractions, &r_2b, &r_mb); } gmx_bcast(sizeof(r_2b), &r_2b, cr); gmx_bcast(sizeof(r_mb), &r_mb, cr); @@ -2219,15 +2187,15 @@ getSystemInfo(const gmx::MDLogger &mdlog, if (std::max(r_2b, r_mb) > systemInfo.cutoff) { const real r_bonded = std::max(r_2b, r_mb); - systemInfo.minCutoffForMultiBody = tenPercentMargin*r_bonded; + systemInfo.minCutoffForMultiBody = tenPercentMargin * r_bonded; /* This is the (only) place where we turn on the filtering */ systemInfo.filterBondedCommunication = true; } else { - const real r_bonded = r_mb; - systemInfo.minCutoffForMultiBody = std::min(tenPercentMargin*r_bonded, - systemInfo.cutoff); + const real r_bonded = r_mb; + systemInfo.minCutoffForMultiBody = + std::min(tenPercentMargin * r_bonded, systemInfo.cutoff); } /* We determine cutoff_mbody later */ systemInfo.increaseMultiBodyCutoff = true; @@ -2237,17 +2205,15 @@ getSystemInfo(const gmx::MDLogger &mdlog, /* No special bonded communication, * simply increase the DD cut-off. */ - systemInfo.minCutoffForMultiBody = tenPercentMargin*std::max(r_2b, r_mb); - systemInfo.cutoff = std::max(systemInfo.cutoff, - systemInfo.minCutoffForMultiBody); + systemInfo.minCutoffForMultiBody = tenPercentMargin * std::max(r_2b, r_mb); + systemInfo.cutoff = std::max(systemInfo.cutoff, systemInfo.minCutoffForMultiBody); } } - GMX_LOG(mdlog.info).appendTextFormatted( - "Minimum cell size due to bonded interactions: %.3f nm", - systemInfo.minCutoffForMultiBody); + GMX_LOG(mdlog.info) + .appendTextFormatted("Minimum cell size due to bonded interactions: %.3f nm", + systemInfo.minCutoffForMultiBody); - systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, - systemInfo.minCutoffForMultiBody); + systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, systemInfo.minCutoffForMultiBody); } systemInfo.constraintCommunicationRange = 0; @@ -2255,12 +2221,15 @@ getSystemInfo(const gmx::MDLogger &mdlog, { /* There is a cell size limit due to the constraints (P-LINCS) */ systemInfo.constraintCommunicationRange = gmx::constr_r_max(mdlog, &mtop, &ir); - GMX_LOG(mdlog.info).appendTextFormatted( - "Estimated maximum distance required for P-LINCS: %.3f nm", - systemInfo.constraintCommunicationRange); + GMX_LOG(mdlog.info) + .appendTextFormatted("Estimated maximum distance required for P-LINCS: %.3f nm", + systemInfo.constraintCommunicationRange); if (systemInfo.constraintCommunicationRange > systemInfo.cellsizeLimit) { - GMX_LOG(mdlog.info).appendText("This distance will limit the DD cell size, you can override this with -rcon"); + GMX_LOG(mdlog.info) + .appendText( + "This distance will limit the DD cell size, you can override this with " + "-rcon"); } } else if (options.constraintCommunicationRange > 0) @@ -2269,45 +2238,41 @@ getSystemInfo(const gmx::MDLogger &mdlog, * because one can also set a cell size limit for virtual sites only * and at this point we don't know yet if there are intercg v-sites. */ - GMX_LOG(mdlog.info).appendTextFormatted( - "User supplied maximum distance required for P-LINCS: %.3f nm", - options.constraintCommunicationRange); + GMX_LOG(mdlog.info) + .appendTextFormatted("User supplied maximum distance required for P-LINCS: %.3f nm", + options.constraintCommunicationRange); systemInfo.constraintCommunicationRange = options.constraintCommunicationRange; } - systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, - systemInfo.constraintCommunicationRange); + systemInfo.cellsizeLimit = std::max(systemInfo.cellsizeLimit, systemInfo.constraintCommunicationRange); return systemInfo; } /*! \brief Exit with a fatal error if the DDGridSetup cannot be * implemented. */ -static void -checkDDGridSetup(const DDGridSetup &ddGridSetup, - const t_commrec *cr, - const DomdecOptions &options, - const DDSettings &ddSettings, - const DDSystemInfo &systemInfo, - const real cellsizeLimit, - const gmx_ddbox_t &ddbox) +static void checkDDGridSetup(const DDGridSetup& ddGridSetup, + const t_commrec* cr, + const DomdecOptions& options, + const DDSettings& ddSettings, + const DDSystemInfo& systemInfo, + const real cellsizeLimit, + const gmx_ddbox_t& ddbox) { if (options.numCells[XX] <= 0 && (ddGridSetup.numDomains[XX] == 0)) { char buf[STRLEN]; - gmx_bool bC = (systemInfo.haveSplitConstraints && - systemInfo.constraintCommunicationRange > systemInfo.minCutoffForMultiBody); - sprintf(buf, "Change the number of ranks or mdrun option %s%s%s", - !bC ? "-rdd" : "-rcon", + gmx_bool bC = (systemInfo.haveSplitConstraints + && systemInfo.constraintCommunicationRange > systemInfo.minCutoffForMultiBody); + sprintf(buf, "Change the number of ranks or mdrun option %s%s%s", !bC ? "-rdd" : "-rcon", ddSettings.initialDlbState != DlbState::offUser ? " or -dds" : "", bC ? " or your LINCS settings" : ""); gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "There is no domain decomposition for %d ranks that is compatible with the given box and a minimum cell size of %g nm\n" + "There is no domain decomposition for %d ranks that is compatible " + "with the given box and a minimum cell size of %g nm\n" "%s\n" "Look in the log file for details on the domain decomposition", - cr->nnodes - ddGridSetup.numPmeOnlyRanks, - cellsizeLimit, - buf); + cr->nnodes - ddGridSetup.numPmeOnlyRanks, cellsizeLimit, buf); } const real acs = average_cellsize_min(ddbox, ddGridSetup.numDomains); @@ -2315,41 +2280,48 @@ checkDDGridSetup(const DDGridSetup &ddGridSetup, { if (options.numCells[XX] <= 0) { - GMX_RELEASE_ASSERT(false, "dd_choose_grid() should return a grid that satisfies the cell size limits"); + GMX_RELEASE_ASSERT( + false, + "dd_choose_grid() should return a grid that satisfies the cell size limits"); } else { - gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "The initial cell size (%f) is smaller than the cell size limit (%f), change options -dd, -rdd or -rcon, see the log file for details", - acs, cellsizeLimit); + gmx_fatal_collective( + FARGS, cr->mpi_comm_mysim, MASTER(cr), + "The initial cell size (%f) is smaller than the cell size limit (%f), change " + "options -dd, -rdd or -rcon, see the log file for details", + acs, cellsizeLimit); } } - const int numPPRanks = ddGridSetup.numDomains[XX]*ddGridSetup.numDomains[YY]*ddGridSetup.numDomains[ZZ]; + const int numPPRanks = + ddGridSetup.numDomains[XX] * ddGridSetup.numDomains[YY] * ddGridSetup.numDomains[ZZ]; if (cr->nnodes - numPPRanks != ddGridSetup.numPmeOnlyRanks) { gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "The size of the domain decomposition grid (%d) does not match the number of PP ranks (%d). The total number of ranks is %d", + "The size of the domain decomposition grid (%d) does not match the " + "number of PP ranks (%d). The total number of ranks is %d", numPPRanks, cr->nnodes - ddGridSetup.numPmeOnlyRanks, cr->nnodes); } if (ddGridSetup.numPmeOnlyRanks > numPPRanks) { gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "The number of separate PME ranks (%d) is larger than the number of PP ranks (%d), this is not supported.", ddGridSetup.numPmeOnlyRanks, numPPRanks); + "The number of separate PME ranks (%d) is larger than the number of " + "PP ranks (%d), this is not supported.", + ddGridSetup.numPmeOnlyRanks, numPPRanks); } } /*! \brief Set the cell size and interaction limits, as well as the DD grid */ -static DDRankSetup -getDDRankSetup(const gmx::MDLogger &mdlog, - t_commrec *cr, - const DDGridSetup &ddGridSetup, - const t_inputrec &ir) +static DDRankSetup getDDRankSetup(const gmx::MDLogger& mdlog, + t_commrec* cr, + const DDGridSetup& ddGridSetup, + const t_inputrec& ir) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Domain decomposition grid %d x %d x %d, separate PME ranks %d", - ddGridSetup.numDomains[XX], ddGridSetup.numDomains[YY], ddGridSetup.numDomains[ZZ], - ddGridSetup.numPmeOnlyRanks); + GMX_LOG(mdlog.info) + .appendTextFormatted("Domain decomposition grid %d x %d x %d, separate PME ranks %d", + ddGridSetup.numDomains[XX], ddGridSetup.numDomains[YY], + ddGridSetup.numDomains[ZZ], ddGridSetup.numPmeOnlyRanks); DDRankSetup ddRankSetup; @@ -2363,7 +2335,8 @@ getDDRankSetup(const gmx::MDLogger &mdlog, } else { - ddRankSetup.numRanksDoingPme = ddGridSetup.numDomains[XX]*ddGridSetup.numDomains[YY]*ddGridSetup.numDomains[ZZ]; + ddRankSetup.numRanksDoingPme = + ddGridSetup.numDomains[XX] * ddGridSetup.numDomains[YY] * ddGridSetup.numDomains[ZZ]; } if (EEL_PME(ir.coulombtype) || EVDW_PME(ir.vdwtype)) @@ -2376,16 +2349,15 @@ getDDRankSetup(const gmx::MDLogger &mdlog, * in which case they will not match those in comm_cost_est, * but since that is mainly for testing purposes that's fine. */ - if (ddGridSetup.numDDDimensions >= 2 && - ddGridSetup.ddDimensions[0] == XX && - ddGridSetup.ddDimensions[1] == YY && - ddRankSetup.numRanksDoingPme > ddGridSetup.numDomains[XX] && - ddRankSetup.numRanksDoingPme % ddGridSetup.numDomains[XX] == 0 && - getenv("GMX_PMEONEDD") == nullptr) + if (ddGridSetup.numDDDimensions >= 2 && ddGridSetup.ddDimensions[0] == XX + && ddGridSetup.ddDimensions[1] == YY + && ddRankSetup.numRanksDoingPme > ddGridSetup.numDomains[XX] + && ddRankSetup.numRanksDoingPme % ddGridSetup.numDomains[XX] == 0 + && getenv("GMX_PMEONEDD") == nullptr) { ddRankSetup.npmedecompdim = 2; ddRankSetup.npmenodes_x = ddGridSetup.numDomains[XX]; - ddRankSetup.npmenodes_y = ddRankSetup.numRanksDoingPme/ddRankSetup.npmenodes_x; + ddRankSetup.npmenodes_y = ddRankSetup.numRanksDoingPme / ddRankSetup.npmenodes_x; } else { @@ -2404,9 +2376,9 @@ getDDRankSetup(const gmx::MDLogger &mdlog, ddRankSetup.npmenodes_y = 1; } } - GMX_LOG(mdlog.info).appendTextFormatted( - "PME domain decomposition: %d x %d x %d", - ddRankSetup.npmenodes_x, ddRankSetup.npmenodes_y, 1); + GMX_LOG(mdlog.info) + .appendTextFormatted("PME domain decomposition: %d x %d x %d", + ddRankSetup.npmenodes_x, ddRankSetup.npmenodes_y, 1); } else { @@ -2419,31 +2391,32 @@ getDDRankSetup(const gmx::MDLogger &mdlog, } /*! \brief Set the cell size and interaction limits */ -static void set_dd_limits(const gmx::MDLogger &mdlog, - t_commrec *cr, gmx_domdec_t *dd, - const DomdecOptions &options, - const DDSettings &ddSettings, - const DDSystemInfo &systemInfo, - const DDGridSetup &ddGridSetup, - const int numPPRanks, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const gmx_ddbox_t &ddbox) -{ - gmx_domdec_comm_t *comm = dd->comm; +static void set_dd_limits(const gmx::MDLogger& mdlog, + t_commrec* cr, + gmx_domdec_t* dd, + const DomdecOptions& options, + const DDSettings& ddSettings, + const DDSystemInfo& systemInfo, + const DDGridSetup& ddGridSetup, + const int numPPRanks, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const gmx_ddbox_t& ddbox) +{ + gmx_domdec_comm_t* comm = dd->comm; comm->ddSettings = ddSettings; /* Initialize to GPU share count to 0, might change later */ comm->nrank_gpu_shared = 0; - comm->dlbState = comm->ddSettings.initialDlbState; + comm->dlbState = comm->ddSettings.initialDlbState; dd_dlb_set_should_check_whether_to_turn_dlb_on(dd, TRUE); /* To consider turning DLB on after 2*nstlist steps we need to check * at partitioning count 3. Thus we need to increase the first count by 2. */ comm->ddPartioningCountFirstDlbOff += 2; - comm->bPMELoadBalDLBLimits = FALSE; + comm->bPMELoadBalDLBLimits = FALSE; /* Allocate the charge group/atom sorting struct */ comm->sort = std::make_unique(); @@ -2456,12 +2429,10 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, * but that is not yet available here. But this anyhow only * affect performance up to the second dd_partition_system call. */ - const int homeAtomCountEstimate = mtop->natoms/numPPRanks; - comm->updateGroupsCog = - std::make_unique(*mtop, - systemInfo.updateGroupingPerMoleculetype, - maxReferenceTemperature(*ir), - homeAtomCountEstimate); + const int homeAtomCountEstimate = mtop->natoms / numPPRanks; + comm->updateGroupsCog = std::make_unique( + *mtop, systemInfo.updateGroupingPerMoleculetype, maxReferenceTemperature(*ir), + homeAtomCountEstimate); } /* Set the DD setup given by ddGridSetup */ @@ -2469,7 +2440,7 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, dd->ndim = ddGridSetup.numDDDimensions; copy_ivec(ddGridSetup.ddDimensions, dd->dim); - dd->nnodes = dd->nc[XX]*dd->nc[YY]*dd->nc[ZZ]; + dd->nnodes = dd->nc[XX] * dd->nc[YY] * dd->nc[ZZ]; snew(comm->slb_frac, DIM); if (isDlbDisabled(comm)) @@ -2491,12 +2462,11 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, * since the extra communication cost is nearly zero. */ real acs = average_cellsize_min(ddbox, dd->nc); - comm->cutoff_mbody = 0.5*(systemInfo.minCutoffForMultiBody + acs); + comm->cutoff_mbody = 0.5 * (systemInfo.minCutoffForMultiBody + acs); if (!isDlbDisabled(comm)) { /* Check if this does not limit the scaling */ - comm->cutoff_mbody = std::min(comm->cutoff_mbody, - options.dlbScaling*acs); + comm->cutoff_mbody = std::min(comm->cutoff_mbody, options.dlbScaling * acs); } if (!systemInfo.filterBondedCommunication) { @@ -2513,8 +2483,7 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, } } /* Check if we did not end up below our original limit */ - comm->cutoff_mbody = std::max(comm->cutoff_mbody, - systemInfo.minCutoffForMultiBody); + comm->cutoff_mbody = std::max(comm->cutoff_mbody, systemInfo.minCutoffForMultiBody); if (comm->cutoff_mbody > comm->cellsize_limit) { @@ -2526,10 +2495,10 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, if (debug) { - fprintf(debug, "Bonded atom communication beyond the cut-off: %s\n" + fprintf(debug, + "Bonded atom communication beyond the cut-off: %s\n" "cellsize limit %f\n", - gmx::boolToString(systemInfo.filterBondedCommunication), - comm->cellsize_limit); + gmx::boolToString(systemInfo.filterBondedCommunication), comm->cellsize_limit); } if (MASTER(cr)) @@ -2538,15 +2507,15 @@ static void set_dd_limits(const gmx::MDLogger &mdlog, } } -void dd_init_bondeds(FILE *fplog, - gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const gmx_vsite_t *vsite, - const t_inputrec *ir, - gmx_bool bBCheck, - cginfo_mb_t *cginfo_mb) +void dd_init_bondeds(FILE* fplog, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const gmx_vsite_t* vsite, + const t_inputrec* ir, + gmx_bool bBCheck, + cginfo_mb_t* cginfo_mb) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; dd_make_reverse_top(fplog, dd, mtop, vsite, ir, bBCheck); @@ -2564,15 +2533,15 @@ void dd_init_bondeds(FILE *fplog, } } -static void writeSettings(gmx::TextWriter *log, - gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - gmx_bool bDynLoadBal, - real dlb_scale, - const gmx_ddbox_t *ddbox) +static void writeSettings(gmx::TextWriter* log, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + gmx_bool bDynLoadBal, + real dlb_scale, + const gmx_ddbox_t* ddbox) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int d; ivec np; real limit, shrink; @@ -2587,7 +2556,8 @@ static void writeSettings(gmx::TextWriter *log, log->writeStringFormatted(" %c %d", dim2char(dd->dim[d]), comm->cd[d].np_dlb); } log->ensureLineBreak(); - log->writeLineFormatted("The minimum size for domain decomposition cells is %.3f nm", comm->cellsize_limit); + log->writeLineFormatted("The minimum size for domain decomposition cells is %.3f nm", + comm->cellsize_limit); log->writeLineFormatted("The requested allowed shrink of DD cells (option -dds) is: %.2f", dlb_scale); log->writeString("The allowed shrink of domain decomposition cells is:"); for (d = 0; d < DIM; d++) @@ -2600,9 +2570,8 @@ static void writeSettings(gmx::TextWriter *log, } else { - shrink = - comm->cellsize_min_dlb[d]/ - (ddbox->box_size[d]*ddbox->skew_fac[d]/dd->nc[d]); + shrink = comm->cellsize_min_dlb[d] + / (ddbox->box_size[d] * ddbox->skew_fac[d] / dd->nc[d]); } log->writeStringFormatted(" %c %.2f", dim2char(d), shrink); } @@ -2623,8 +2592,7 @@ static void writeSettings(gmx::TextWriter *log, { if (dd->nc[d] > 1) { - log->writeStringFormatted(" %c %.2f nm", - dim2char(d), dd->comm->cellsize_min[d]); + log->writeStringFormatted(" %c %.2f nm", dim2char(d), dd->comm->cellsize_min[d]); } } log->ensureLineBreak(); @@ -2632,12 +2600,10 @@ static void writeSettings(gmx::TextWriter *log, } const bool haveInterDomainVsites = - (countInterUpdategroupVsites(*mtop, comm->systemInfo.updateGroupingPerMoleculetype) != 0); + (countInterUpdategroupVsites(*mtop, comm->systemInfo.updateGroupingPerMoleculetype) != 0); - if (comm->systemInfo.haveInterDomainBondeds || - haveInterDomainVsites || - comm->systemInfo.haveSplitConstraints || - comm->systemInfo.haveSplitSettles) + if (comm->systemInfo.haveInterDomainBondeds || haveInterDomainVsites + || comm->systemInfo.haveSplitConstraints || comm->systemInfo.haveSplitSettles) { std::string decompUnits; if (comm->systemInfo.useUpdateGroups) @@ -2649,8 +2615,10 @@ static void writeSettings(gmx::TextWriter *log, decompUnits = "atoms"; } - log->writeLineFormatted("The maximum allowed distance for %s involved in interactions is:", decompUnits.c_str()); - log->writeLineFormatted("%40s %-7s %6.3f nm", "non-bonded interactions", "", comm->systemInfo.cutoff); + log->writeLineFormatted("The maximum allowed distance for %s involved in interactions is:", + decompUnits.c_str()); + log->writeLineFormatted("%40s %-7s %6.3f nm", "non-bonded interactions", "", + comm->systemInfo.cutoff); if (bDynLoadBal) { @@ -2660,7 +2628,9 @@ static void writeSettings(gmx::TextWriter *log, { if (dd->unitCellInfo.ddBoxIsDynamic) { - log->writeLine("(the following are initial values, they could change due to box deformation)"); + log->writeLine( + "(the following are initial values, they could change due to box " + "deformation)"); } limit = dd->comm->cellsize_min[XX]; for (d = 1; d < DIM; d++) @@ -2671,35 +2641,34 @@ static void writeSettings(gmx::TextWriter *log, if (comm->systemInfo.haveInterDomainBondeds) { - log->writeLineFormatted("%40s %-7s %6.3f nm", - "two-body bonded interactions", "(-rdd)", + log->writeLineFormatted("%40s %-7s %6.3f nm", "two-body bonded interactions", "(-rdd)", std::max(comm->systemInfo.cutoff, comm->cutoff_mbody)); - log->writeLineFormatted("%40s %-7s %6.3f nm", - "multi-body bonded interactions", "(-rdd)", - (comm->systemInfo.filterBondedCommunication || isDlbOn(dd->comm)) ? comm->cutoff_mbody : std::min(comm->systemInfo.cutoff, limit)); + log->writeLineFormatted("%40s %-7s %6.3f nm", "multi-body bonded interactions", + "(-rdd)", + (comm->systemInfo.filterBondedCommunication || isDlbOn(dd->comm)) + ? comm->cutoff_mbody + : std::min(comm->systemInfo.cutoff, limit)); } if (haveInterDomainVsites) { - log->writeLineFormatted("%40s %-7s %6.3f nm", - "virtual site constructions", "(-rcon)", limit); + log->writeLineFormatted("%40s %-7s %6.3f nm", "virtual site constructions", "(-rcon)", limit); } if (comm->systemInfo.haveSplitConstraints || comm->systemInfo.haveSplitSettles) { - std::string separation = gmx::formatString("atoms separated by up to %d constraints", - 1+ir->nProjOrder); - log->writeLineFormatted("%40s %-7s %6.3f nm\n", - separation.c_str(), "(-rcon)", limit); + std::string separation = + gmx::formatString("atoms separated by up to %d constraints", 1 + ir->nProjOrder); + log->writeLineFormatted("%40s %-7s %6.3f nm\n", separation.c_str(), "(-rcon)", limit); } log->ensureLineBreak(); } } -static void logSettings(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const t_inputrec *ir, +static void logSettings(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const t_inputrec* ir, real dlb_scale, - const gmx_ddbox_t *ddbox) + const gmx_ddbox_t* ddbox) { gmx::StringOutputStream stream; gmx::TextWriter log(&stream); @@ -2708,20 +2677,21 @@ static void logSettings(const gmx::MDLogger &mdlog, { { log.ensureEmptyLine(); - log.writeLine("When dynamic load balancing gets turned on, these settings will change to:"); + log.writeLine( + "When dynamic load balancing gets turned on, these settings will change to:"); } writeSettings(&log, dd, mtop, ir, true, dlb_scale, ddbox); } GMX_LOG(mdlog.info).asParagraph().appendText(stream.toString()); } -static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, +static void set_cell_limits_dlb(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, real dlb_scale, - const t_inputrec *ir, - const gmx_ddbox_t *ddbox) + const t_inputrec* ir, + const gmx_ddbox_t* ddbox) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int d, dim, npulse, npulse_d_max, npulse_d; gmx_bool bNoCutOff; @@ -2747,12 +2717,12 @@ static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, * Later cellsize_limit is redetermined, * so we can not miss interactions due to this rounding. */ - npulse = static_cast(0.96 + comm->systemInfo.cutoff/comm->cellsize_limit); + npulse = static_cast(0.96 + comm->systemInfo.cutoff / comm->cellsize_limit); } else { /* There is no cell size limit */ - npulse = std::max(dd->nc[XX]-1, std::max(dd->nc[YY]-1, dd->nc[ZZ]-1)); + npulse = std::max(dd->nc[XX] - 1, std::max(dd->nc[YY] - 1, dd->nc[ZZ] - 1)); } if (!bNoCutOff && npulse > 1) @@ -2762,8 +2732,10 @@ static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, for (d = 0; d < dd->ndim; d++) { dim = dd->dim[d]; - npulse_d = static_cast(1 + dd->nc[dim]*comm->systemInfo.cutoff - /(ddbox->box_size[dim]*ddbox->skew_fac[dim]*dlb_scale)); + npulse_d = static_cast( + 1 + + dd->nc[dim] * comm->systemInfo.cutoff + / (ddbox->box_size[dim] * ddbox->skew_fac[dim] * dlb_scale)); npulse_d_max = std::max(npulse_d_max, npulse_d); } npulse = std::min(npulse, npulse_d_max); @@ -2786,10 +2758,10 @@ static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, } else { - comm->cd[d].np_dlb = std::min(npulse, dd->nc[dd->dim[d]]-1); + comm->cd[d].np_dlb = std::min(npulse, dd->nc[dd->dim[d]] - 1); comm->maxpulse = std::max(comm->maxpulse, comm->cd[d].np_dlb); } - if (comm->cd[d].np_dlb < dd->nc[dd->dim[d]]-1) + if (comm->cd[d].np_dlb < dd->nc[dd->dim[d]] - 1) { comm->bVacDLBNoLimit = FALSE; } @@ -2798,22 +2770,19 @@ static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, /* cellsize_limit is set for LINCS in init_domain_decomposition */ if (!comm->bVacDLBNoLimit) { - comm->cellsize_limit = std::max(comm->cellsize_limit, - comm->systemInfo.cutoff/comm->maxpulse); + comm->cellsize_limit = std::max(comm->cellsize_limit, comm->systemInfo.cutoff / comm->maxpulse); } comm->cellsize_limit = std::max(comm->cellsize_limit, comm->cutoff_mbody); /* Set the minimum cell size for each DD dimension */ for (d = 0; d < dd->ndim; d++) { - if (comm->bVacDLBNoLimit || - comm->cd[d].np_dlb*comm->cellsize_limit >= comm->systemInfo.cutoff) + if (comm->bVacDLBNoLimit || comm->cd[d].np_dlb * comm->cellsize_limit >= comm->systemInfo.cutoff) { comm->cellsize_min_dlb[dd->dim[d]] = comm->cellsize_limit; } else { - comm->cellsize_min_dlb[dd->dim[d]] = - comm->systemInfo.cutoff/comm->cd[d].np_dlb; + comm->cellsize_min_dlb[dd->dim[d]] = comm->systemInfo.cutoff / comm->cd[d].np_dlb; } } if (comm->cutoff_mbody <= 0) @@ -2826,31 +2795,31 @@ static void set_cell_limits_dlb(const gmx::MDLogger &mdlog, } } -bool dd_moleculesAreAlwaysWhole(const gmx_domdec_t &dd) +bool dd_moleculesAreAlwaysWhole(const gmx_domdec_t& dd) { return dd.comm->systemInfo.moleculesAreAlwaysWhole; } -gmx_bool dd_bonded_molpbc(const gmx_domdec_t *dd, int ePBC) +gmx_bool dd_bonded_molpbc(const gmx_domdec_t* dd, int ePBC) { /* If each molecule is a single charge group * or we use domain decomposition for each periodic dimension, * we do not need to take pbc into account for the bonded interactions. */ - return (ePBC != epbcNONE && dd->comm->systemInfo.haveInterDomainBondeds && - !(dd->nc[XX] > 1 && - dd->nc[YY] > 1 && - (dd->nc[ZZ] > 1 || ePBC == epbcXY))); + return (ePBC != epbcNONE && dd->comm->systemInfo.haveInterDomainBondeds + && !(dd->nc[XX] > 1 && dd->nc[YY] > 1 && (dd->nc[ZZ] > 1 || ePBC == epbcXY))); } /*! \brief Sets grid size limits and PP-PME setup, prints settings to log */ -static void set_ddgrid_parameters(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, real dlb_scale, - const gmx_mtop_t *mtop, const t_inputrec *ir, - const gmx_ddbox_t *ddbox) +static void set_ddgrid_parameters(const gmx::MDLogger& mdlog, + gmx_domdec_t* dd, + real dlb_scale, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const gmx_ddbox_t* ddbox) { - gmx_domdec_comm_t *comm = dd->comm; - DDRankSetup &ddRankSetup = comm->ddRankSetup; + gmx_domdec_comm_t* comm = dd->comm; + DDRankSetup& ddRankSetup = comm->ddRankSetup; if (EEL_PME(ir->coulombtype) || EVDW_PME(ir->vdwtype)) { @@ -2884,12 +2853,12 @@ static void set_ddgrid_parameters(const gmx::MDLogger &mdlog, real vol_frac; if (ir->ePBC == epbcNONE) { - vol_frac = 1 - 1/static_cast(dd->nnodes); + vol_frac = 1 - 1 / static_cast(dd->nnodes); } else { - vol_frac = - (1 + comm_box_frac(dd->nc, comm->systemInfo.cutoff, *ddbox))/static_cast(dd->nnodes); + vol_frac = (1 + comm_box_frac(dd->nc, comm->systemInfo.cutoff, *ddbox)) + / static_cast(dd->nnodes); } if (debug) { @@ -2897,16 +2866,14 @@ static void set_ddgrid_parameters(const gmx::MDLogger &mdlog, } int natoms_tot = mtop->natoms; - dd->ga2la = new gmx_ga2la_t(natoms_tot, - static_cast(vol_frac*natoms_tot)); + dd->ga2la = new gmx_ga2la_t(natoms_tot, static_cast(vol_frac * natoms_tot)); } /*! \brief Get some important DD parameters which can be modified by env.vars */ -static DDSettings -getDDSettings(const gmx::MDLogger &mdlog, - const DomdecOptions &options, - const gmx::MdrunOptions &mdrunOptions, - const t_inputrec &ir) +static DDSettings getDDSettings(const gmx::MDLogger& mdlog, + const DomdecOptions& options, + const gmx::MdrunOptions& mdrunOptions, + const t_inputrec& ir) { DDSettings ddSettings; @@ -2923,7 +2890,11 @@ getDDSettings(const gmx::MDLogger &mdlog, if (ddSettings.useSendRecv2) { - GMX_LOG(mdlog.info).appendText("Will use two sequential MPI_Sendrecv calls instead of two simultaneous non-blocking MPI_Irecv and MPI_Isend pairs for constraint and vsite communication"); + GMX_LOG(mdlog.info) + .appendText( + "Will use two sequential MPI_Sendrecv calls instead of two simultaneous " + "non-blocking MPI_Irecv and MPI_Isend pairs for constraint and vsite " + "communication"); } if (ddSettings.eFlop) @@ -2936,18 +2907,16 @@ getDDSettings(const gmx::MDLogger &mdlog, ddSettings.recordLoad = (wallcycle_have_counter() && recload > 0); } - ddSettings.initialDlbState = - determineInitialDlbState(mdlog, options.dlbOption, ddSettings.recordLoad, mdrunOptions, &ir); - GMX_LOG(mdlog.info).appendTextFormatted("Dynamic load balancing: %s", - edlbs_names[static_cast(ddSettings.initialDlbState)]); + ddSettings.initialDlbState = determineInitialDlbState(mdlog, options.dlbOption, + ddSettings.recordLoad, mdrunOptions, &ir); + GMX_LOG(mdlog.info) + .appendTextFormatted("Dynamic load balancing: %s", + edlbs_names[static_cast(ddSettings.initialDlbState)]); return ddSettings; } -gmx_domdec_t::gmx_domdec_t(const t_inputrec &ir) : - unitCellInfo(ir) -{ -} +gmx_domdec_t::gmx_domdec_t(const t_inputrec& ir) : unitCellInfo(ir) {} /*! \brief Return whether the simulation described can run a 1D single-pulse DD. * @@ -2966,49 +2935,46 @@ gmx_domdec_t::gmx_domdec_t(const t_inputrec &ir) : * exchange code path. The number of PME ranks, if any, should be set * in \c options.numPmeRanks. */ -static bool -canMake1DAnd1PulseDomainDecomposition(const DDSettings &ddSettingsOriginal, - const t_commrec *cr, - const int numRanksRequested, - const DomdecOptions &options, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef xGlobal) +static bool canMake1DAnd1PulseDomainDecomposition(const DDSettings& ddSettingsOriginal, + const t_commrec* cr, + const int numRanksRequested, + const DomdecOptions& options, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef xGlobal) { // Ensure we don't write any output from this checking routine gmx::MDLogger dummyLogger; - DDSystemInfo systemInfo = getSystemInfo(dummyLogger, cr, options, mtop, ir, box, xGlobal); + DDSystemInfo systemInfo = getSystemInfo(dummyLogger, cr, options, mtop, ir, box, xGlobal); - DDSettings ddSettings = ddSettingsOriginal; - ddSettings.request1DAnd1Pulse = true; - const real gridSetupCellsizeLimit = getDDGridSetupCellSizeLimit(dummyLogger, ddSettings.request1DAnd1Pulse, - !isDlbDisabled(ddSettings.initialDlbState), - options.dlbScaling, ir, - systemInfo.cellsizeLimit); - gmx_ddbox_t ddbox = {0}; - DDGridSetup ddGridSetup = getDDGridSetup(dummyLogger, cr, numRanksRequested, options, - ddSettings, systemInfo, gridSetupCellsizeLimit, - mtop, ir, box, xGlobal, &ddbox); + DDSettings ddSettings = ddSettingsOriginal; + ddSettings.request1DAnd1Pulse = true; + const real gridSetupCellsizeLimit = getDDGridSetupCellSizeLimit( + dummyLogger, ddSettings.request1DAnd1Pulse, !isDlbDisabled(ddSettings.initialDlbState), + options.dlbScaling, ir, systemInfo.cellsizeLimit); + gmx_ddbox_t ddbox = { 0 }; + DDGridSetup ddGridSetup = + getDDGridSetup(dummyLogger, cr, numRanksRequested, options, ddSettings, systemInfo, + gridSetupCellsizeLimit, mtop, ir, box, xGlobal, &ddbox); const bool canMakeDDWith1DAnd1Pulse = (ddGridSetup.numDomains[XX] != 0); return canMakeDDWith1DAnd1Pulse; } -bool is1DAnd1PulseDD(const gmx_domdec_t &dd) +bool is1DAnd1PulseDD(const gmx_domdec_t& dd) { const int maxDimensionSize = std::max(dd.nc[XX], std::max(dd.nc[YY], dd.nc[ZZ])); - const int productOfDimensionSizes = dd.nc[XX]*dd.nc[YY]*dd.nc[ZZ]; + const int productOfDimensionSizes = dd.nc[XX] * dd.nc[YY] * dd.nc[ZZ]; const bool decompositionHasOneDimension = (maxDimensionSize == productOfDimensionSizes); const bool hasMax1Pulse = - ((isDlbDisabled(dd.comm) && dd.comm->cellsize_limit >= dd.comm->systemInfo.cutoff) || - (!isDlbDisabled(dd.comm) && dd.comm->maxpulse == 1)); + ((isDlbDisabled(dd.comm) && dd.comm->cellsize_limit >= dd.comm->systemInfo.cutoff) + || (!isDlbDisabled(dd.comm) && dd.comm->maxpulse == 1)); return decompositionHasOneDimension && hasMax1Pulse; - } namespace gmx @@ -3019,80 +2985,78 @@ namespace gmx /*! \brief Impl class for DD builder */ class DomainDecompositionBuilder::Impl { - public: - //! Constructor - Impl(const MDLogger &mdlog, - t_commrec *cr, - const DomdecOptions &options, - const MdrunOptions &mdrunOptions, - bool prefer1DAnd1Pulse, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - ArrayRef xGlobal); - - //! Build the resulting DD manager - gmx_domdec_t *build(LocalAtomSetManager *atomSets); - - //! Objects used in constructing and configuring DD - //! { - //! Logging object - const MDLogger &mdlog_; - //! Communication object - t_commrec *cr_; - //! User-supplied options configuring DD behavior - const DomdecOptions options_; - //! Global system topology - const gmx_mtop_t &mtop_; - //! User input values from the tpr file - const t_inputrec &ir_; - //! } - - //! Internal objects used in constructing DD - //! { - //! Settings combined from the user input - DDSettings ddSettings_; - //! Information derived from the simulation system - DDSystemInfo systemInfo_; - //! Box structure - gmx_ddbox_t ddbox_ = { 0 }; - //! Organization of the DD grids - DDGridSetup ddGridSetup_; - //! Organzation of the DD ranks - DDRankSetup ddRankSetup_; - //! Number of DD cells in each dimension - ivec ddCellIndex_ = { 0, 0, 0 }; - //! IDs of PME-only ranks - std::vector pmeRanks_; - //! Contains a valid Cartesian-communicator-based setup, or defaults. - CartesianRankSetup cartSetup_; - //! } - +public: + //! Constructor + Impl(const MDLogger& mdlog, + t_commrec* cr, + const DomdecOptions& options, + const MdrunOptions& mdrunOptions, + bool prefer1DAnd1Pulse, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + ArrayRef xGlobal); + + //! Build the resulting DD manager + gmx_domdec_t* build(LocalAtomSetManager* atomSets); + + //! Objects used in constructing and configuring DD + //! { + //! Logging object + const MDLogger& mdlog_; + //! Communication object + t_commrec* cr_; + //! User-supplied options configuring DD behavior + const DomdecOptions options_; + //! Global system topology + const gmx_mtop_t& mtop_; + //! User input values from the tpr file + const t_inputrec& ir_; + //! } + + //! Internal objects used in constructing DD + //! { + //! Settings combined from the user input + DDSettings ddSettings_; + //! Information derived from the simulation system + DDSystemInfo systemInfo_; + //! Box structure + gmx_ddbox_t ddbox_ = { 0 }; + //! Organization of the DD grids + DDGridSetup ddGridSetup_; + //! Organzation of the DD ranks + DDRankSetup ddRankSetup_; + //! Number of DD cells in each dimension + ivec ddCellIndex_ = { 0, 0, 0 }; + //! IDs of PME-only ranks + std::vector pmeRanks_; + //! Contains a valid Cartesian-communicator-based setup, or defaults. + CartesianRankSetup cartSetup_; + //! } }; -DomainDecompositionBuilder::Impl::Impl(const MDLogger &mdlog, - t_commrec *cr, - const DomdecOptions &options, - const MdrunOptions &mdrunOptions, +DomainDecompositionBuilder::Impl::Impl(const MDLogger& mdlog, + t_commrec* cr, + const DomdecOptions& options, + const MdrunOptions& mdrunOptions, const bool prefer1DAnd1Pulse, - const gmx_mtop_t &mtop, - const t_inputrec &ir, + const gmx_mtop_t& mtop, + const t_inputrec& ir, const matrix box, - ArrayRef xGlobal) - : mdlog_(mdlog), - cr_(cr), - options_(options), - mtop_(mtop), - ir_(ir) + ArrayRef xGlobal) : + mdlog_(mdlog), + cr_(cr), + options_(options), + mtop_(mtop), + ir_(ir) { - GMX_LOG(mdlog_.info).appendTextFormatted( - "\nInitializing Domain Decomposition on %d ranks", cr_->nnodes); + GMX_LOG(mdlog_.info).appendTextFormatted("\nInitializing Domain Decomposition on %d ranks", cr_->nnodes); ddSettings_ = getDDSettings(mdlog_, options_, mdrunOptions, ir_); - if (prefer1DAnd1Pulse && - canMake1DAnd1PulseDomainDecomposition(ddSettings_, cr_, cr_->nnodes, options_, - mtop_, ir_, box, xGlobal)) + if (prefer1DAnd1Pulse + && canMake1DAnd1PulseDomainDecomposition(ddSettings_, cr_, cr_->nnodes, options_, mtop_, + ir_, box, xGlobal)) { ddSettings_.request1DAnd1Pulse = true; } @@ -3111,13 +3075,11 @@ DomainDecompositionBuilder::Impl::Impl(const MDLogger &mdlog, // DD grid setup uses a more different cell size limit for // automated setup than the one in systemInfo_. The latter is used // in set_dd_limits() to configure DLB, for example. - const real gridSetupCellsizeLimit = getDDGridSetupCellSizeLimit(mdlog_, ddSettings_.request1DAnd1Pulse, - !isDlbDisabled(ddSettings_.initialDlbState), - options_.dlbScaling, ir_, - systemInfo_.cellsizeLimit); - ddGridSetup_ = getDDGridSetup(mdlog_, cr_, numRanksRequested, options_, - ddSettings_, systemInfo_, gridSetupCellsizeLimit, - mtop_, ir_, box, xGlobal, &ddbox_); + const real gridSetupCellsizeLimit = getDDGridSetupCellSizeLimit( + mdlog_, ddSettings_.request1DAnd1Pulse, !isDlbDisabled(ddSettings_.initialDlbState), + options_.dlbScaling, ir_, systemInfo_.cellsizeLimit); + ddGridSetup_ = getDDGridSetup(mdlog_, cr_, numRanksRequested, options_, ddSettings_, systemInfo_, + gridSetupCellsizeLimit, mtop_, ir_, box, xGlobal, &ddbox_); checkDDGridSetup(ddGridSetup_, cr_, options_, ddSettings_, systemInfo_, gridSetupCellsizeLimit, ddbox_); cr_->npmenodes = ddGridSetup_.numPmeOnlyRanks; @@ -3125,15 +3087,13 @@ DomainDecompositionBuilder::Impl::Impl(const MDLogger &mdlog, ddRankSetup_ = getDDRankSetup(mdlog_, cr_, ddGridSetup_, ir_); /* Generate the group communicator, also decides the duty of each rank */ - cartSetup_ = - makeGroupCommunicators(mdlog_, ddSettings_, options_.rankOrder, - ddRankSetup_, cr_, - ddCellIndex_, &pmeRanks_); + cartSetup_ = makeGroupCommunicators(mdlog_, ddSettings_, options_.rankOrder, ddRankSetup_, cr_, + ddCellIndex_, &pmeRanks_); } -gmx_domdec_t *DomainDecompositionBuilder::Impl::build(LocalAtomSetManager *atomSets) +gmx_domdec_t* DomainDecompositionBuilder::Impl::build(LocalAtomSetManager* atomSets) { - gmx_domdec_t *dd = new gmx_domdec_t(ir_); + gmx_domdec_t* dd = new gmx_domdec_t(ir_); copy_ivec(ddCellIndex_, dd->ci); @@ -3142,12 +3102,8 @@ gmx_domdec_t *DomainDecompositionBuilder::Impl::build(LocalAtomSetManager *atomS dd->comm->ddRankSetup = ddRankSetup_; dd->comm->cartesianRankSetup = cartSetup_; - set_dd_limits(mdlog_, cr_, dd, options_, - ddSettings_, systemInfo_, - ddGridSetup_, - ddRankSetup_.numPPRanks, - &mtop_, &ir_, - ddbox_); + set_dd_limits(mdlog_, cr_, dd, options_, ddSettings_, systemInfo_, ddGridSetup_, + ddRankSetup_.numPPRanks, &mtop_, &ir_, ddbox_); setupGroupCommunication(mdlog_, ddSettings_, pmeRanks_, cr_, mtop_.natoms, dd); @@ -3166,20 +3122,20 @@ gmx_domdec_t *DomainDecompositionBuilder::Impl::build(LocalAtomSetManager *atomS return dd; } -DomainDecompositionBuilder::DomainDecompositionBuilder(const MDLogger &mdlog, - t_commrec *cr, - const DomdecOptions &options, - const MdrunOptions &mdrunOptions, +DomainDecompositionBuilder::DomainDecompositionBuilder(const MDLogger& mdlog, + t_commrec* cr, + const DomdecOptions& options, + const MdrunOptions& mdrunOptions, const bool prefer1DAnd1Pulse, - const gmx_mtop_t &mtop, - const t_inputrec &ir, + const gmx_mtop_t& mtop, + const t_inputrec& ir, const matrix box, - ArrayRef xGlobal) - : impl_(new Impl(mdlog, cr, options, mdrunOptions, prefer1DAnd1Pulse, mtop, ir, box, xGlobal)) + ArrayRef xGlobal) : + impl_(new Impl(mdlog, cr, options, mdrunOptions, prefer1DAnd1Pulse, mtop, ir, box, xGlobal)) { } -gmx_domdec_t *DomainDecompositionBuilder::build(LocalAtomSetManager *atomSets) +gmx_domdec_t* DomainDecompositionBuilder::build(LocalAtomSetManager* atomSets) { return impl_->build(atomSets); } @@ -3188,12 +3144,9 @@ DomainDecompositionBuilder::~DomainDecompositionBuilder() = default; } // namespace gmx -static gmx_bool test_dd_cutoff(t_commrec *cr, - const matrix box, - gmx::ArrayRef x, - real cutoffRequested) +static gmx_bool test_dd_cutoff(t_commrec* cr, const matrix box, gmx::ArrayRef x, real cutoffRequested) { - gmx_domdec_t *dd; + gmx_domdec_t* dd; gmx_ddbox_t ddbox; int d, dim, np; real inv_cell_size; @@ -3209,13 +3162,13 @@ static gmx_bool test_dd_cutoff(t_commrec *cr, { dim = dd->dim[d]; - inv_cell_size = DD_CELL_MARGIN*dd->nc[dim]/ddbox.box_size[dim]; + inv_cell_size = DD_CELL_MARGIN * dd->nc[dim] / ddbox.box_size[dim]; if (dd->unitCellInfo.ddBoxIsDynamic) { inv_cell_size *= DD_PRES_SCALE_MARGIN; } - np = 1 + static_cast(cutoffRequested*inv_cell_size*ddbox.skew_fac[dim]); + np = 1 + static_cast(cutoffRequested * inv_cell_size * ddbox.skew_fac[dim]); if (dd->comm->ddSettings.request1DAnd1Pulse && np > 1) { @@ -3233,8 +3186,9 @@ static gmx_bool test_dd_cutoff(t_commrec *cr, * cut-off, we could still fix it, but this gets very complicated. * Without fixing here, we might actually need more checks. */ - real cellSizeAlongDim = (dd->comm->cell_x1[dim] - dd->comm->cell_x0[dim])*ddbox.skew_fac[dim]; - if (cellSizeAlongDim*dd->comm->cd[d].np_dlb < cutoffRequested) + real cellSizeAlongDim = + (dd->comm->cell_x1[dim] - dd->comm->cell_x0[dim]) * ddbox.skew_fac[dim]; + if (cellSizeAlongDim * dd->comm->cd[d].np_dlb < cutoffRequested) { LocallyLimited = 1; } @@ -3246,8 +3200,7 @@ static gmx_bool test_dd_cutoff(t_commrec *cr, /* If DLB is not active yet, we don't need to check the grid jumps. * Actually we shouldn't, because then the grid jump data is not set. */ - if (isDlbOn(dd->comm) && - check_grid_jump(0, dd, cutoffRequested, &ddbox, FALSE)) + if (isDlbOn(dd->comm) && check_grid_jump(0, dd, cutoffRequested, &ddbox, FALSE)) { LocallyLimited = 1; } @@ -3263,10 +3216,7 @@ static gmx_bool test_dd_cutoff(t_commrec *cr, return TRUE; } -gmx_bool change_dd_cutoff(t_commrec *cr, - const matrix box, - gmx::ArrayRef x, - real cutoffRequested) +gmx_bool change_dd_cutoff(t_commrec* cr, const matrix box, gmx::ArrayRef x, real cutoffRequested) { gmx_bool bCutoffAllowed; diff --git a/src/gromacs/domdec/domdec.h b/src/gromacs/domdec/domdec.h index 97b38a4300..61691d63e3 100644 --- a/src/gromacs/domdec/domdec.h +++ b/src/gromacs/domdec/domdec.h @@ -88,7 +88,7 @@ namespace gmx class ForceWithShiftForces; class MDLogger; class RangePartitioning; -} // namespace +} // namespace gmx /*! \brief Returns the global topology atom number belonging to local atom index i. * @@ -96,35 +96,34 @@ class RangePartitioning; * and returns atom numbers starting at 1. * When dd=NULL returns i+1. */ -int ddglatnr(const gmx_domdec_t *dd, int i); +int ddglatnr(const gmx_domdec_t* dd, int i); /*! \brief Returns a list of update group partitioning for each molecule type or empty when update groups are not used */ -gmx::ArrayRef getUpdateGroupingPerMoleculetype(const gmx_domdec_t &dd); +gmx::ArrayRef getUpdateGroupingPerMoleculetype(const gmx_domdec_t& dd); /*! \brief Store the global cg indices of the home cgs in state, * * This means it can be reset, even after a new DD partitioning. */ -void dd_store_state(struct gmx_domdec_t *dd, t_state *state); +void dd_store_state(struct gmx_domdec_t* dd, t_state* state); /*! \brief Returns a pointer to the gmx_domdec_zones_t struct */ -struct gmx_domdec_zones_t *domdec_zones(struct gmx_domdec_t *dd); +struct gmx_domdec_zones_t* domdec_zones(struct gmx_domdec_t* dd); /*! \brief Returns the range for atoms in zones*/ -int dd_numAtomsZones(const gmx_domdec_t &dd); +int dd_numAtomsZones(const gmx_domdec_t& dd); /*! \brief Returns the number of home atoms */ -int dd_numHomeAtoms(const gmx_domdec_t &dd); +int dd_numHomeAtoms(const gmx_domdec_t& dd); /*! \brief Returns the atom range in the local state for atoms that need to be present in mdatoms */ -int dd_natoms_mdatoms(const gmx_domdec_t *dd); +int dd_natoms_mdatoms(const gmx_domdec_t* dd); /*! \brief Returns the atom range in the local state for atoms involved in virtual sites */ -int dd_natoms_vsite(const gmx_domdec_t *dd); +int dd_natoms_vsite(const gmx_domdec_t* dd); /*! \brief Sets the atom range for atom in the local state for atoms received in constraints communication */ -void dd_get_constraint_range(const gmx_domdec_t *dd, - int *at_start, int *at_end); +void dd_get_constraint_range(const gmx_domdec_t* dd, int* at_start, int* at_end); /*! \libinternal \brief Struct for passing around the number of PME domains */ struct NumPmeDomains @@ -134,41 +133,41 @@ struct NumPmeDomains }; /*! \brief Returns the number of PME domains, can be called with dd=NULL */ -NumPmeDomains getNumPmeDomains(const gmx_domdec_t *dd); +NumPmeDomains getNumPmeDomains(const gmx_domdec_t* dd); /*! \brief Returns the set of DD ranks that communicate with pme node cr->nodeid */ -std::vector get_pme_ddranks(const t_commrec *cr, int pmenodeid); +std::vector get_pme_ddranks(const t_commrec* cr, int pmenodeid); /*! \brief Returns the maximum shift for coordinate communication in PME, dim x */ -int dd_pme_maxshift_x(const gmx_domdec_t *dd); +int dd_pme_maxshift_x(const gmx_domdec_t* dd); /*! \brief Returns the maximum shift for coordinate communication in PME, dim y */ -int dd_pme_maxshift_y(const gmx_domdec_t *dd); +int dd_pme_maxshift_y(const gmx_domdec_t* dd); /*! \brief Return whether constraints, not including settles, cross domain boundaries */ -bool ddHaveSplitConstraints(const gmx_domdec_t &dd); +bool ddHaveSplitConstraints(const gmx_domdec_t& dd); /*! \brief Return whether the DD has a single dimension with a single pulse * * The GPU halo exchange code requires a 1D single-pulse DD, and its * setup code can use the returned value to understand what it should * do. */ -bool is1DAnd1PulseDD(const gmx_domdec_t &dd); +bool is1DAnd1PulseDD(const gmx_domdec_t& dd); /*! \brief Initialize data structures for bonded interactions */ -void dd_init_bondeds(FILE *fplog, - gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const gmx_vsite_t *vsite, - const t_inputrec *ir, +void dd_init_bondeds(FILE* fplog, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const gmx_vsite_t* vsite, + const t_inputrec* ir, gmx_bool bBCheck, - cginfo_mb_t *cginfo_mb); + cginfo_mb_t* cginfo_mb); /*! \brief Returns whether molecules are always whole, i.e. not broken by PBC */ -bool dd_moleculesAreAlwaysWhole(const gmx_domdec_t &dd); +bool dd_moleculesAreAlwaysWhole(const gmx_domdec_t& dd); /*! \brief Returns if we need to do pbc for calculating bonded interactions */ -gmx_bool dd_bonded_molpbc(const gmx_domdec_t *dd, int ePBC); +gmx_bool dd_bonded_molpbc(const gmx_domdec_t* dd, int ePBC); /*! \brief Change the DD non-bonded communication cut-off. * @@ -180,10 +179,7 @@ gmx_bool dd_bonded_molpbc(const gmx_domdec_t *dd, int ePBC); * \param[in] x Position vector, used for computing the dimensions of the system * \param[in] cutoffRequested The requested atom to atom cut-off distance, usually the pair-list cutoff distance */ -gmx_bool change_dd_cutoff(t_commrec *cr, - const matrix box, - gmx::ArrayRef x, - real cutoffRequested); +gmx_bool change_dd_cutoff(t_commrec* cr, const matrix box, gmx::ArrayRef x, real cutoffRequested); /*! \brief Set up communication for averaging GPU wait times over domains * @@ -192,55 +188,54 @@ gmx_bool change_dd_cutoff(t_commrec *cr, * GPU finish. Therefore there wait times need to be averaged over the ranks * sharing the same GPU. This function sets up the communication for that. */ -void dd_setup_dlb_resource_sharing(const t_commrec *cr, - int gpu_id); +void dd_setup_dlb_resource_sharing(const t_commrec* cr, int gpu_id); /*! \brief Cycle counter indices used internally in the domain decomposition */ -enum { - ddCyclStep, ddCyclPPduringPME, ddCyclF, ddCyclWaitGPU, ddCyclPME, ddCyclNr +enum +{ + ddCyclStep, + ddCyclPPduringPME, + ddCyclF, + ddCyclWaitGPU, + ddCyclPME, + ddCyclNr }; /*! \brief Add the wallcycle count to the DD counter */ -void dd_cycles_add(const gmx_domdec_t *dd, float cycles, int ddCycl); +void dd_cycles_add(const gmx_domdec_t* dd, float cycles, int ddCycl); /*! \brief Communicate the coordinates to the neighboring cells and do pbc. */ -void dd_move_x(struct gmx_domdec_t *dd, - const matrix box, - gmx::ArrayRef x, - gmx_wallcycle *wcycle); +void dd_move_x(struct gmx_domdec_t* dd, const matrix box, gmx::ArrayRef x, gmx_wallcycle* wcycle); /*! \brief Sum the forces over the neighboring cells. * * When fshift!=NULL the shift forces are updated to obtain * the correct virial from the single sum including f. */ -void dd_move_f(struct gmx_domdec_t *dd, - gmx::ForceWithShiftForces *forceWithShiftForces, - gmx_wallcycle *wcycle); +void dd_move_f(struct gmx_domdec_t* dd, gmx::ForceWithShiftForces* forceWithShiftForces, gmx_wallcycle* wcycle); /*! \brief Communicate a real for each atom to the neighboring cells. */ -void dd_atom_spread_real(struct gmx_domdec_t *dd, real v[]); +void dd_atom_spread_real(struct gmx_domdec_t* dd, real v[]); /*! \brief Sum the contributions to a real for each atom over the neighboring cells. */ -void dd_atom_sum_real(struct gmx_domdec_t *dd, real v[]); +void dd_atom_sum_real(struct gmx_domdec_t* dd, real v[]); /*! \brief Reset all the statistics and counters for total run counting */ -void reset_dd_statistics_counters(struct gmx_domdec_t *dd); +void reset_dd_statistics_counters(struct gmx_domdec_t* dd); /* In domdec_con.c */ /*! \brief Communicates the virtual site forces, reduces the shift forces when \p fshift != NULL */ -void dd_move_f_vsites(struct gmx_domdec_t *dd, rvec *f, rvec *fshift); +void dd_move_f_vsites(struct gmx_domdec_t* dd, rvec* f, rvec* fshift); /*! \brief Clears the forces for virtual sites */ -void dd_clear_f_vsites(struct gmx_domdec_t *dd, rvec *f); +void dd_clear_f_vsites(struct gmx_domdec_t* dd, rvec* f); /*! \brief Move x0 and also x1 if x1!=NULL. bX1IsCoord tells if to do PBC on x1 */ -void dd_move_x_constraints(struct gmx_domdec_t *dd, const matrix box, - rvec *x0, rvec *x1, gmx_bool bX1IsCoord); +void dd_move_x_constraints(struct gmx_domdec_t* dd, const matrix box, rvec* x0, rvec* x1, gmx_bool bX1IsCoord); /*! \brief Communicates the coordinates involved in virtual sites */ -void dd_move_x_vsites(struct gmx_domdec_t *dd, const matrix box, rvec *x); +void dd_move_x_vsites(struct gmx_domdec_t* dd, const matrix box, rvec* x); /*! \brief Returns the local atom count array for all constraints * @@ -250,67 +245,66 @@ void dd_move_x_vsites(struct gmx_domdec_t *dd, const matrix box, rvec *x); * * \note When \p dd = nullptr, an empty reference is returned. */ -gmx::ArrayRef dd_constraints_nlocalatoms(const gmx_domdec_t *dd); +gmx::ArrayRef dd_constraints_nlocalatoms(const gmx_domdec_t* dd); /* In domdec_top.c */ /*! \brief Print error output when interactions are missing */ -[[ noreturn ]] -void dd_print_missing_interactions(const gmx::MDLogger &mdlog, - t_commrec *cr, - int local_count, - const gmx_mtop_t *top_global, - const gmx_localtop_t *top_local, - const rvec *x, - const matrix box); +[[noreturn]] void dd_print_missing_interactions(const gmx::MDLogger& mdlog, + t_commrec* cr, + int local_count, + const gmx_mtop_t* top_global, + const gmx_localtop_t* top_local, + const rvec* x, + const matrix box); /*! \brief Generate and store the reverse topology */ -void dd_make_reverse_top(FILE *fplog, - gmx_domdec_t *dd, const gmx_mtop_t *mtop, - const gmx_vsite_t *vsite, - const t_inputrec *ir, gmx_bool bBCheck); +void dd_make_reverse_top(FILE* fplog, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const gmx_vsite_t* vsite, + const t_inputrec* ir, + gmx_bool bBCheck); /*! \brief Generate the local topology and virtual site data */ -void dd_make_local_top(struct gmx_domdec_t *dd, - struct gmx_domdec_zones_t *zones, +void dd_make_local_top(struct gmx_domdec_t* dd, + struct gmx_domdec_zones_t* zones, int npbcdim, matrix box, rvec cellsize_min, const ivec npulse, - t_forcerec *fr, - rvec *cgcm_or_x, - const gmx_mtop_t &top, - gmx_localtop_t *ltop); + t_forcerec* fr, + rvec* cgcm_or_x, + const gmx_mtop_t& top, + gmx_localtop_t* ltop); /*! \brief Sort ltop->ilist when we are doing free energy. */ -void dd_sort_local_top(gmx_domdec_t *dd, const t_mdatoms *mdatoms, - gmx_localtop_t *ltop); +void dd_sort_local_top(gmx_domdec_t* dd, const t_mdatoms* mdatoms, gmx_localtop_t* ltop); /*! \brief Initialize local topology * * \param[in] top_global Reference to global topology. * \param[in,out] top Pointer to new local topology */ -void dd_init_local_top(const gmx_mtop_t &top_global, - gmx_localtop_t *top); +void dd_init_local_top(const gmx_mtop_t& top_global, gmx_localtop_t* top); /*! \brief Construct local state */ -void dd_init_local_state(struct gmx_domdec_t *dd, - const t_state *state_global, t_state *local_state); +void dd_init_local_state(struct gmx_domdec_t* dd, const t_state* state_global, t_state* local_state); /*! \brief Generate a list of links between atoms that are linked by bonded interactions * * Also stores whether atoms are linked in \p cginfo_mb. */ -t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, - cginfo_mb_t *cginfo_mb); +t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb); /*! \brief Calculate the maximum distance involved in 2-body and multi-body bonded interactions */ -void dd_bonded_cg_distance(const gmx::MDLogger &mdlog, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const rvec *x, const matrix box, - gmx_bool bBCheck, - real *r_2b, real *r_mb); +void dd_bonded_cg_distance(const gmx::MDLogger& mdlog, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const rvec* x, + const matrix box, + gmx_bool bBCheck, + real* r_2b, + real* r_mb); #endif diff --git a/src/gromacs/domdec/domdec_constraints.cpp b/src/gromacs/domdec/domdec_constraints.cpp index 8005f7a8fd..0a62ae980e 100644 --- a/src/gromacs/domdec/domdec_constraints.cpp +++ b/src/gromacs/domdec/domdec_constraints.cpp @@ -76,31 +76,30 @@ struct gmx_domdec_constraints_t { //! @cond Doxygen_Suppress - std::vector molb_con_offset; /**< Offset in the constraint array for each molblock */ - std::vector molb_ncon_mol; /**< The number of constraints per molecule for each molblock */ + std::vector molb_con_offset; /**< Offset in the constraint array for each molblock */ + std::vector molb_ncon_mol; /**< The number of constraints per molecule for each molblock */ - int ncon; /**< The fully local and conneced constraints */ + int ncon; /**< The fully local and conneced constraints */ /* The global constraint number, only required for clearing gc_req */ - std::vector con_gl; /**< Global constraint indices for local constraints */ - std::vector con_nlocat; /**< Number of local atoms (2/1/0) for each constraint */ + std::vector con_gl; /**< Global constraint indices for local constraints */ + std::vector con_nlocat; /**< Number of local atoms (2/1/0) for each constraint */ - std::vector gc_req; /**< Boolean that tells if a global constraint index has been requested; note: size global #constraints */ + std::vector gc_req; /**< Boolean that tells if a global constraint index has been requested; note: size global #constraints */ /* Hash table for keeping track of requests */ - std::unique_ptr < gmx::HashedMap < int>> ga2la; /**< Global to local communicated constraint atom only index */ + std::unique_ptr> ga2la; /**< Global to local communicated constraint atom only index */ /* Multi-threading stuff */ int nthread; /**< Number of threads used for DD constraint setup */ std::vector ils; /**< Constraint ilist working arrays, size \p nthread */ /* Buffers for requesting atoms */ - std::vector < std::vector < int>> requestedGlobalAtomIndices; /**< Buffers for requesting global atom indices, one per thread */ + std::vector> requestedGlobalAtomIndices; /**< Buffers for requesting global atom indices, one per thread */ //! @endcond }; -void dd_move_x_constraints(gmx_domdec_t *dd, const matrix box, - rvec *x0, rvec *x1, gmx_bool bX1IsCoord) +void dd_move_x_constraints(gmx_domdec_t* dd, const matrix box, rvec* x0, rvec* x1, gmx_bool bX1IsCoord) { if (dd->constraint_comm) { @@ -110,7 +109,7 @@ void dd_move_x_constraints(gmx_domdec_t *dd, const matrix box, } } -gmx::ArrayRef dd_constraints_nlocalatoms(const gmx_domdec_t *dd) +gmx::ArrayRef dd_constraints_nlocalatoms(const gmx_domdec_t* dd) { if (dd && dd->constraints) { @@ -122,9 +121,9 @@ gmx::ArrayRef dd_constraints_nlocalatoms(const gmx_domdec_t *dd) } } -void dd_clear_local_constraint_indices(gmx_domdec_t *dd) +void dd_clear_local_constraint_indices(gmx_domdec_t* dd) { - gmx_domdec_constraints_t *dc = dd->constraints; + gmx_domdec_constraints_t* dc = dd->constraints; std::fill(dc->gc_req.begin(), dc->gc_req.end(), false); @@ -135,18 +134,23 @@ void dd_clear_local_constraint_indices(gmx_domdec_t *dd) } /*! \brief Walks over the constraints out from the local atoms into the non-local atoms and adds them to a list */ -static void walk_out(int con, int con_offset, int a, int offset, int nrec, - gmx::ArrayRef ia1, - gmx::ArrayRef ia2, - const t_blocka *at2con, - const gmx_ga2la_t &ga2la, gmx_bool bHomeConnect, - gmx_domdec_constraints_t *dc, - gmx_domdec_specat_comm_t *dcc, - t_ilist *il_local, - std::vector *ireq) +static void walk_out(int con, + int con_offset, + int a, + int offset, + int nrec, + gmx::ArrayRef ia1, + gmx::ArrayRef ia2, + const t_blocka* at2con, + const gmx_ga2la_t& ga2la, + gmx_bool bHomeConnect, + gmx_domdec_constraints_t* dc, + gmx_domdec_specat_comm_t* dcc, + t_ilist* il_local, + std::vector* ireq) { int a1_gl, a2_gl, i, coni, b; - const t_iatom *iap; + const t_iatom* iap; if (!dc->gc_req[con_offset + con]) { @@ -156,15 +160,15 @@ static void walk_out(int con, int con_offset, int a, int offset, int nrec, dc->gc_req[con_offset + con] = true; if (il_local->nr + 3 > il_local->nalloc) { - il_local->nalloc = over_alloc_dd(il_local->nr+3); + il_local->nalloc = over_alloc_dd(il_local->nr + 3); srenew(il_local->iatoms, il_local->nalloc); } - iap = constr_iatomptr(ia1, ia2, con); + iap = constr_iatomptr(ia1, ia2, con); il_local->iatoms[il_local->nr++] = iap[0]; - a1_gl = offset + iap[1]; - a2_gl = offset + iap[2]; + a1_gl = offset + iap[1]; + a2_gl = offset + iap[2]; /* The following indexing code can probably be optizimed */ - if (const int *a_loc = ga2la.findHome(a1_gl)) + if (const int* a_loc = ga2la.findHome(a1_gl)) { il_local->iatoms[il_local->nr++] = *a_loc; } @@ -173,7 +177,7 @@ static void walk_out(int con, int con_offset, int a, int offset, int nrec, /* We set this index later */ il_local->iatoms[il_local->nr++] = -a1_gl - 1; } - if (const int *a_loc = ga2la.findHome(a2_gl)) + if (const int* a_loc = ga2la.findHome(a2_gl)) { il_local->iatoms[il_local->nr++] = *a_loc; } @@ -196,7 +200,7 @@ static void walk_out(int con, int con_offset, int a, int offset, int nrec, if (nrec > 0) { - for (i = at2con->index[a]; i < at2con->index[a+1]; i++) + for (i = at2con->index[a]; i < at2con->index[a + 1]; i++) { coni = at2con->a[i]; if (coni != con) @@ -213,9 +217,8 @@ static void walk_out(int con, int con_offset, int a, int offset, int nrec, } if (!ga2la.findHome(offset + b)) { - walk_out(coni, con_offset, b, offset, nrec-1, - ia1, ia2, at2con, - ga2la, FALSE, dc, dcc, il_local, ireq); + walk_out(coni, con_offset, b, offset, nrec - 1, ia1, ia2, at2con, ga2la, FALSE, + dc, dcc, il_local, ireq); } } } @@ -223,18 +226,19 @@ static void walk_out(int con, int con_offset, int a, int offset, int nrec, } /*! \brief Looks up SETTLE constraints for a range of charge-groups */ -static void atoms_to_settles(gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const int *cginfo, - gmx::ArrayRef < const std::vector < int>> at2settle_mt, - int cg_start, int cg_end, - t_ilist *ils_local, - std::vector *ireq) +static void atoms_to_settles(gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const int* cginfo, + gmx::ArrayRef> at2settle_mt, + int cg_start, + int cg_end, + t_ilist* ils_local, + std::vector* ireq) { - const gmx_ga2la_t &ga2la = *dd->ga2la; + const gmx_ga2la_t& ga2la = *dd->ga2la; int nral = NRAL(F_SETTLE); - int mb = 0; + int mb = 0; for (int a = cg_start; a < cg_end; a++) { if (GET_CGINFO_SETTLE(cginfo[a])) @@ -243,21 +247,21 @@ static void atoms_to_settles(gmx_domdec_t *dd, int a_mol; mtopGetMolblockIndex(mtop, a_gl, &mb, nullptr, &a_mol); - const gmx_molblock_t *molb = &mtop->molblock[mb]; + const gmx_molblock_t* molb = &mtop->molblock[mb]; int settle = at2settle_mt[molb->type][a_mol]; if (settle >= 0) { - int offset = a_gl - a_mol; + int offset = a_gl - a_mol; - const int *ia1 = mtop->moltype[molb->type].ilist[F_SETTLE].iatoms.data(); + const int* ia1 = mtop->moltype[molb->type].ilist[F_SETTLE].iatoms.data(); - int a_gls[3]; - gmx_bool bAssign = FALSE; - int nlocal = 0; + int a_gls[3]; + gmx_bool bAssign = FALSE; + int nlocal = 0; for (int sa = 0; sa < nral; sa++) { - int a_glsa = offset + ia1[settle*(1+nral)+1+sa]; + int a_glsa = offset + ia1[settle * (1 + nral) + 1 + sa]; a_gls[sa] = a_glsa; if (ga2la.findHome(a_glsa)) { @@ -271,17 +275,17 @@ static void atoms_to_settles(gmx_domdec_t *dd, if (bAssign) { - if (ils_local->nr+1+nral > ils_local->nalloc) + if (ils_local->nr + 1 + nral > ils_local->nalloc) { - ils_local->nalloc = over_alloc_dd(ils_local->nr+1+nral); + ils_local->nalloc = over_alloc_dd(ils_local->nr + 1 + nral); srenew(ils_local->iatoms, ils_local->nalloc); } - ils_local->iatoms[ils_local->nr++] = ia1[settle*4]; + ils_local->iatoms[ils_local->nr++] = ia1[settle * 4]; for (int sa = 0; sa < nral; sa++) { - if (const int *a_loc = ga2la.findHome(a_gls[sa])) + if (const int* a_loc = ga2la.findHome(a_gls[sa])) { ils_local->iatoms[ils_local->nr++] = *a_loc; } @@ -302,20 +306,21 @@ static void atoms_to_settles(gmx_domdec_t *dd, } /*! \brief Looks up constraint for the local atoms */ -static void atoms_to_constraints(gmx_domdec_t *dd, - const gmx_mtop_t *mtop, - const int *cginfo, - gmx::ArrayRef at2con_mt, int nrec, - t_ilist *ilc_local, - std::vector *ireq) +static void atoms_to_constraints(gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const int* cginfo, + gmx::ArrayRef at2con_mt, + int nrec, + t_ilist* ilc_local, + std::vector* ireq) { - const t_blocka *at2con; - int b_lo, offset, b_mol, i, con, con_offset; + const t_blocka* at2con; + int b_lo, offset, b_mol, i, con, con_offset; - gmx_domdec_constraints_t *dc = dd->constraints; - gmx_domdec_specat_comm_t *dcc = dd->constraint_comm; + gmx_domdec_constraints_t* dc = dd->constraints; + gmx_domdec_specat_comm_t* dcc = dd->constraint_comm; - const gmx_ga2la_t &ga2la = *dd->ga2la; + const gmx_ga2la_t& ga2la = *dd->ga2la; dc->con_gl.clear(); dc->con_nlocat.clear(); @@ -330,25 +335,24 @@ static void atoms_to_constraints(gmx_domdec_t *dd, int molnr, a_mol; mtopGetMolblockIndex(mtop, a_gl, &mb, &molnr, &a_mol); - const gmx_molblock_t &molb = mtop->molblock[mb]; + const gmx_molblock_t& molb = mtop->molblock[mb]; - gmx::ArrayRef ia1 = mtop->moltype[molb.type].ilist[F_CONSTR].iatoms; - gmx::ArrayRef ia2 = mtop->moltype[molb.type].ilist[F_CONSTRNC].iatoms; + gmx::ArrayRef ia1 = mtop->moltype[molb.type].ilist[F_CONSTR].iatoms; + gmx::ArrayRef ia2 = mtop->moltype[molb.type].ilist[F_CONSTRNC].iatoms; /* Calculate the global constraint number offset for the molecule. * This is only required for the global index to make sure * that we use each constraint only once. */ - con_offset = - dc->molb_con_offset[mb] + molnr*dc->molb_ncon_mol[mb]; + con_offset = dc->molb_con_offset[mb] + molnr * dc->molb_ncon_mol[mb]; /* The global atom number offset for this molecule */ offset = a_gl - a_mol; at2con = &at2con_mt[molb.type]; - for (i = at2con->index[a_mol]; i < at2con->index[a_mol+1]; i++) + for (i = at2con->index[a_mol]; i < at2con->index[a_mol + 1]; i++) { con = at2con->a[i]; - const int *iap = constr_iatomptr(ia1, ia2, con); + const int* iap = constr_iatomptr(ia1, ia2, con); if (a_mol == iap[1]) { b_mol = iap[2]; @@ -357,7 +361,7 @@ static void atoms_to_constraints(gmx_domdec_t *dd, { b_mol = iap[1]; } - if (const int *a_loc = ga2la.findHome(offset + b_mol)) + if (const int* a_loc = ga2la.findHome(offset + b_mol)) { /* Add this fully home constraint at the first atom */ if (a_mol < b_mol) @@ -369,10 +373,10 @@ static void atoms_to_constraints(gmx_domdec_t *dd, ilc_local->nalloc = over_alloc_dd(ilc_local->nr + 3); srenew(ilc_local->iatoms, ilc_local->nalloc); } - b_lo = *a_loc; + b_lo = *a_loc; ilc_local->iatoms[ilc_local->nr++] = iap[0]; - ilc_local->iatoms[ilc_local->nr++] = (a_gl == iap[1] ? a : b_lo); - ilc_local->iatoms[ilc_local->nr++] = (a_gl == iap[1] ? b_lo : a ); + ilc_local->iatoms[ilc_local->nr++] = (a_gl == iap[1] ? a : b_lo); + ilc_local->iatoms[ilc_local->nr++] = (a_gl == iap[1] ? b_lo : a); dc->ncon++; nhome++; } @@ -385,49 +389,51 @@ static void atoms_to_constraints(gmx_domdec_t *dd, * Therefore we call walk_out with nrec recursions to go * after this first call. */ - walk_out(con, con_offset, b_mol, offset, nrec, - ia1, ia2, at2con, - ga2la, TRUE, dc, dcc, ilc_local, ireq); + walk_out(con, con_offset, b_mol, offset, nrec, ia1, ia2, at2con, ga2la, TRUE, + dc, dcc, ilc_local, ireq); } } } } - GMX_ASSERT(dc->con_gl.size() == static_cast(dc->ncon), "con_gl size should match the number of constraints"); - GMX_ASSERT(dc->con_nlocat.size() == static_cast(dc->ncon), "con_nlocat size should match the number of constraints"); + GMX_ASSERT(dc->con_gl.size() == static_cast(dc->ncon), + "con_gl size should match the number of constraints"); + GMX_ASSERT(dc->con_nlocat.size() == static_cast(dc->ncon), + "con_nlocat size should match the number of constraints"); if (debug) { - fprintf(debug, - "Constraints: home %3d border %3d atoms: %3zu\n", - nhome, dc->ncon-nhome, + fprintf(debug, "Constraints: home %3d border %3d atoms: %3zu\n", nhome, dc->ncon - nhome, dd->constraint_comm ? ireq->size() : 0); } } -int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, - const struct gmx_mtop_t *mtop, - const int *cginfo, - gmx::Constraints *constr, int nrec, - t_ilist *il_local) +int dd_make_local_constraints(gmx_domdec_t* dd, + int at_start, + const struct gmx_mtop_t* mtop, + const int* cginfo, + gmx::Constraints* constr, + int nrec, + t_ilist* il_local) { - gmx_domdec_constraints_t *dc; - t_ilist *ilc_local, *ils_local; - std::vector *ireq; + gmx_domdec_constraints_t* dc; + t_ilist * ilc_local, *ils_local; + std::vector* ireq; gmx::ArrayRef at2con_mt; - gmx::HashedMap *ga2la_specat; - int at_end, i, j; - t_iatom *iap; + gmx::HashedMap* ga2la_specat; + int at_end, i, j; + t_iatom* iap; // This code should not be called unless this condition is true, // because that's the only time init_domdec_constraints is // called... - GMX_RELEASE_ASSERT(dd->comm->systemInfo.haveSplitConstraints || - dd->comm->systemInfo.haveSplitSettles, + GMX_RELEASE_ASSERT(dd->comm->systemInfo.haveSplitConstraints || dd->comm->systemInfo.haveSplitSettles, "dd_make_local_constraints called when there are no local constraints"); // ... and init_domdec_constraints always sets // dd->constraint_comm... - GMX_RELEASE_ASSERT(dd->constraint_comm, "Invalid use of dd_make_local_constraints before construction of constraint_comm"); + GMX_RELEASE_ASSERT( + dd->constraint_comm, + "Invalid use of dd_make_local_constraints before construction of constraint_comm"); // ... which static analysis needs to be reassured about, because // otherwise, when dd->splitSettles is // true. dd->constraint_comm is unilaterally dereferenced before @@ -455,7 +461,7 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, ireq = nullptr; } - gmx::ArrayRef < const std::vector < int>> at2settle_mt; + gmx::ArrayRef> at2settle_mt; /* When settle works inside charge groups, we assigned them already */ if (dd->comm->systemInfo.haveSplitSettles) { @@ -467,8 +473,7 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, if (at2settle_mt.empty()) { - atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, - ilc_local, ireq); + atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, ilc_local, ireq); } else { @@ -486,20 +491,19 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, { if (!at2con_mt.empty() && thread == 0) { - atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, - ilc_local, ireq); + atoms_to_constraints(dd, mtop, cginfo, at2con_mt, nrec, ilc_local, ireq); } if (thread >= t0_set) { - int cg0, cg1; - t_ilist *ilst; + int cg0, cg1; + t_ilist* ilst; /* Distribute the settle check+assignments over * dc->nthread or dc->nthread-1 threads. */ - cg0 = (dd->ncg_home*(thread-t0_set ))/(dc->nthread-t0_set); - cg1 = (dd->ncg_home*(thread-t0_set+1))/(dc->nthread-t0_set); + cg0 = (dd->ncg_home * (thread - t0_set)) / (dc->nthread - t0_set); + cg1 = (dd->ncg_home * (thread - t0_set + 1)) / (dc->nthread - t0_set); if (thread == t0_set) { @@ -511,25 +515,23 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, } ilst->nr = 0; - std::vector &ireqt = dc->requestedGlobalAtomIndices[thread]; + std::vector& ireqt = dc->requestedGlobalAtomIndices[thread]; if (thread > 0) { ireqt.clear(); } - atoms_to_settles(dd, mtop, cginfo, at2settle_mt, - cg0, cg1, - ilst, &ireqt); + atoms_to_settles(dd, mtop, cginfo, at2settle_mt, cg0, cg1, ilst, &ireqt); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Combine the generate settles and requested indices */ for (int thread = 1; thread < dc->nthread; thread++) { - t_ilist *ilst; - int ia; + t_ilist* ilst; + int ia; if (thread > t0_set) { @@ -541,18 +543,18 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, } for (ia = 0; ia < ilst->nr; ia++) { - ils_local->iatoms[ils_local->nr+ia] = ilst->iatoms[ia]; + ils_local->iatoms[ils_local->nr + ia] = ilst->iatoms[ia]; } ils_local->nr += ilst->nr; } - const std::vector &ireqt = dc->requestedGlobalAtomIndices[thread]; + const std::vector& ireqt = dc->requestedGlobalAtomIndices[thread]; ireq->insert(ireq->end(), ireqt.begin(), ireqt.end()); } if (debug) { - fprintf(debug, "Settles: total %3d\n", ils_local->nr/4); + fprintf(debug, "Settles: total %3d\n", ils_local->nr / 4); } } @@ -560,11 +562,8 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, { int nral1; - at_end = - setup_specat_communication(dd, ireq, dd->constraint_comm, - dd->constraints->ga2la.get(), - at_start, 2, - "constraint", " or lincs-order"); + at_end = setup_specat_communication(dd, ireq, dd->constraint_comm, dd->constraints->ga2la.get(), + at_start, 2, "constraint", " or lincs-order"); /* Fill in the missing indices */ ga2la_specat = dd->constraints->ga2la.get(); @@ -577,7 +576,7 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, { if (iap[j] < 0) { - const int *a = ga2la_specat->find(-iap[j] - 1); + const int* a = ga2la_specat->find(-iap[j] - 1); GMX_ASSERT(a, "We have checked before that this atom index has been set"); iap[j] = *a; } @@ -592,7 +591,7 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, { if (iap[j] < 0) { - const int *a = ga2la_specat->find(-iap[j] - 1); + const int* a = ga2la_specat->find(-iap[j] - 1); GMX_ASSERT(a, "We have checked before that this atom index has been set"); iap[j] = *a; } @@ -608,11 +607,10 @@ int dd_make_local_constraints(gmx_domdec_t *dd, int at_start, return at_end; } -void init_domdec_constraints(gmx_domdec_t *dd, - const gmx_mtop_t *mtop) +void init_domdec_constraints(gmx_domdec_t* dd, const gmx_mtop_t* mtop) { - gmx_domdec_constraints_t *dc; - const gmx_molblock_t *molb; + gmx_domdec_constraints_t* dc; + const gmx_molblock_t* molb; if (debug) { @@ -630,10 +628,9 @@ void init_domdec_constraints(gmx_domdec_t *dd, { molb = &mtop->molblock[mb]; dc->molb_con_offset[mb] = ncon; - dc->molb_ncon_mol[mb] = - mtop->moltype[molb->type].ilist[F_CONSTR].size()/3 + - mtop->moltype[molb->type].ilist[F_CONSTRNC].size()/3; - ncon += molb->nmol*dc->molb_ncon_mol[mb]; + dc->molb_ncon_mol[mb] = mtop->moltype[molb->type].ilist[F_CONSTR].size() / 3 + + mtop->moltype[molb->type].ilist[F_CONSTRNC].size() / 3; + ncon += molb->nmol * dc->molb_ncon_mol[mb]; } if (ncon > 0) @@ -644,9 +641,8 @@ void init_domdec_constraints(gmx_domdec_t *dd, /* Use a hash table for the global to local index. * The number of keys is a rough estimate, it will be optimized later. */ - int numKeysEstimate = std::min(mtop->natoms/20, - mtop->natoms/(2*dd->nnodes)); - dc->ga2la = std::make_unique < gmx::HashedMap < int>>(numKeysEstimate); + int numKeysEstimate = std::min(mtop->natoms / 20, mtop->natoms / (2 * dd->nnodes)); + dc->ga2la = std::make_unique>(numKeysEstimate); dc->nthread = gmx_omp_nthreads_get(emntDomdec); dc->ils.resize(dc->nthread); diff --git a/src/gromacs/domdec/domdec_constraints.h b/src/gromacs/domdec/domdec_constraints.h index d8d8294037..1ca1028e16 100644 --- a/src/gromacs/domdec/domdec_constraints.h +++ b/src/gromacs/domdec/domdec_constraints.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,17 +54,18 @@ struct gmx_mtop_t; struct t_ilist; /*! \brief Clears the local indices for the constraint communication setup */ -void dd_clear_local_constraint_indices(gmx_domdec_t *dd); +void dd_clear_local_constraint_indices(gmx_domdec_t* dd); /*! \brief Sets up communication and atom indices for all local+connected constraints */ -int dd_make_local_constraints(struct gmx_domdec_t *dd, int at_start, - const struct gmx_mtop_t *mtop, - const int *cginfo, - gmx::Constraints *constr, int nrec, - struct t_ilist *il_local); +int dd_make_local_constraints(struct gmx_domdec_t* dd, + int at_start, + const struct gmx_mtop_t* mtop, + const int* cginfo, + gmx::Constraints* constr, + int nrec, + struct t_ilist* il_local); /*! \brief Initializes the data structures for constraint communication */ -void init_domdec_constraints(gmx_domdec_t *dd, - const gmx_mtop_t *mtop); +void init_domdec_constraints(gmx_domdec_t* dd, const gmx_mtop_t* mtop); #endif diff --git a/src/gromacs/domdec/domdec_internal.h b/src/gromacs/domdec/domdec_internal.h index 36f66a6258..1b62f894b0 100644 --- a/src/gromacs/domdec/domdec_internal.h +++ b/src/gromacs/domdec/domdec_internal.h @@ -67,15 +67,15 @@ struct gmx_domdec_ind_t * cell that requires communication, the last entry contains the total * number of atoms that needs to be communicated. */ - int nsend[DD_MAXIZONE+2] = {}; - int nrecv[DD_MAXIZONE+2] = {}; + int nsend[DD_MAXIZONE + 2] = {}; + int nrecv[DD_MAXIZONE + 2] = {}; //! @} //! The charge groups to send std::vector index; //! @{ /* The atom range for non-in-place communication */ - int cell2at0[DD_MAXIZONE] = {}; - int cell2at1[DD_MAXIZONE] = {}; + int cell2at0[DD_MAXIZONE] = {}; + int cell2at1[DD_MAXIZONE] = {}; //! @} }; @@ -83,17 +83,14 @@ struct gmx_domdec_ind_t struct gmx_domdec_comm_dim_t { /* Returns the number of grid pulses (the number of domains in the halo along this dimension) */ - int numPulses() const - { - return ind.size(); - } + int numPulses() const { return ind.size(); } /**< For dlb, for use with edlbAUTO */ - int np_dlb = 0; + int np_dlb = 0; /**< The indices to communicate, size np */ std::vector ind; /**< Can we receive data in place? */ - bool receiveInPlace = false; + bool receiveInPlace = false; }; /*! \brief Load balancing data along a dim used on the master rank of that dim */ @@ -112,17 +109,17 @@ struct RowMaster }; /**< Temp. var.: is this cell size at the limit */ - std::vector isCellMin; + std::vector isCellMin; /**< State var.: cell boundaries, box relative */ - std::vector cellFrac; + std::vector cellFrac; /**< Temp. var.: old cell size */ - std::vector oldCellFrac; + std::vector oldCellFrac; /**< Cell bounds */ std::vector bounds; /**< State var.: is DLB limited in this row */ - bool dlbIsLimited = false; + bool dlbIsLimited = false; /**< Temp. var. */ - std::vector buf_ncd; + std::vector buf_ncd; }; /*! \brief Struct for managing cell sizes with DLB along a dimension */ @@ -131,15 +128,15 @@ struct DDCellsizesWithDlb /**< Cell row root struct, only available on the first rank in a row */ std::unique_ptr rowMaster; /**< The cell sizes, in fractions, along a row, not available on the first rank in a row */ - std::vector fracRow; + std::vector fracRow; /**< The lower corner, in fractions, in triclinic space */ - real fracLower = 0; + real fracLower = 0; /**< The upper corner, in fractions, in triclinic space */ - real fracUpper = 0; + real fracUpper = 0; /**< The maximum lower corner among all our neighbors */ - real fracLowerMax = 0; + real fracLowerMax = 0; /**< The minimum upper corner among all our neighbors */ - real fracUpperMin = 0; + real fracUpperMin = 0; }; /*! \brief Struct for compute load commuication @@ -150,34 +147,34 @@ struct DDCellsizesWithDlb typedef struct { /**< The number of load recordings */ - int nload = 0; + int nload = 0; /**< Scan of the sum of load over dimensions */ - float *load = nullptr; + float* load = nullptr; /**< The sum of the load over the ranks up to our current dimension */ - float sum = 0; + float sum = 0; /**< The maximum over the ranks contributing to \p sum */ - float max = 0; + float max = 0; /**< Like \p sum, but takes the maximum when the load balancing is limited */ - float sum_m = 0; + float sum_m = 0; /**< Minimum cell volume, relative to the box */ - float cvol_min = 0; + float cvol_min = 0; /**< The PP time during which PME can overlap */ - float mdf = 0; + float mdf = 0; /**< The PME-only rank load */ - float pme = 0; + float pme = 0; /**< Bit flags that tell if DLB was limited, per dimension */ - int flags = 0; + int flags = 0; } domdec_load_t; /*! \brief Data needed to sort an atom to the desired location in the local state */ typedef struct { /**< Neighborsearch grid cell index */ - int nsc = 0; + int nsc = 0; /**< Global atom/charge group index */ - int ind_gl = 0; + int ind_gl = 0; /**< Local atom/charge group index */ - int ind = 0; + int ind = 0; } gmx_cgsort_t; /*! \brief Temporary buffers for sorting atoms */ @@ -190,82 +187,73 @@ typedef struct /**< Array of moved atom/charge group indices */ std::vector moved; /**< Integer buffer for sorting */ - std::vector intBuffer; + std::vector intBuffer; } gmx_domdec_sort_t; /*! \brief Manages atom ranges and order for the local state atom vectors */ class DDAtomRanges { - public: - /*! \brief The local state atom order - * - * This enum determines the order of the atoms in the local state. - * ddnatHOME and ddnatZONE should be first and second, - * the others can be ordered as wanted. - */ - enum class Type : int - { - Home, /**< The home atoms */ - Zones, /**< All zones in the eighth shell */ - Vsites, /**< Atoms communicated for virtual sites */ - Constraints, /**< Atoms communicated for constraints */ - Number /**< Not a count, only present for convenience */ - }; - - /*! \brief Returns the start atom index for range \p rangeType */ - int start(Type rangeType) const - { - if (rangeType == Type::Home) - { - return 0; - } - else - { - return end_[static_cast(rangeType) - 1]; - } - } +public: + /*! \brief The local state atom order + * + * This enum determines the order of the atoms in the local state. + * ddnatHOME and ddnatZONE should be first and second, + * the others can be ordered as wanted. + */ + enum class Type : int + { + Home, /**< The home atoms */ + Zones, /**< All zones in the eighth shell */ + Vsites, /**< Atoms communicated for virtual sites */ + Constraints, /**< Atoms communicated for constraints */ + Number /**< Not a count, only present for convenience */ + }; - /*! \brief Returns the end atom index for range \p rangeType */ - int end(Type rangeType) const + /*! \brief Returns the start atom index for range \p rangeType */ + int start(Type rangeType) const + { + if (rangeType == Type::Home) { - return end_[static_cast(rangeType)]; + return 0; } - - /*! \brief Returns the number of home atoms */ - int numHomeAtoms() const + else { - return end_[static_cast(Type::Home)]; + return end_[static_cast(rangeType) - 1]; } + } - /*! \brief Returns the total number of atoms */ - int numAtomsTotal() const - { - return end_[static_cast(Type::Number) - 1]; - } + /*! \brief Returns the end atom index for range \p rangeType */ + int end(Type rangeType) const { return end_[static_cast(rangeType)]; } - /*! \brief Sets the end index of range \p rangeType to \p end - * - * This should be called either with Type::Home or with a type - * that is larger than that passed in the previous call to setEnd. - * A release assertion for these conditions are present. - */ - void setEnd(Type rangeType, - int end) - { - GMX_RELEASE_ASSERT(rangeType == Type::Home || rangeType > lastTypeSet_, "Can only set either home or a larger type than the last one"); + /*! \brief Returns the number of home atoms */ + int numHomeAtoms() const { return end_[static_cast(Type::Home)]; } + + /*! \brief Returns the total number of atoms */ + int numAtomsTotal() const { return end_[static_cast(Type::Number) - 1]; } - for (int i = static_cast(rangeType); i < static_cast(Type::Number); i++) - { - end_[i] = end; - } + /*! \brief Sets the end index of range \p rangeType to \p end + * + * This should be called either with Type::Home or with a type + * that is larger than that passed in the previous call to setEnd. + * A release assertion for these conditions are present. + */ + void setEnd(Type rangeType, int end) + { + GMX_RELEASE_ASSERT(rangeType == Type::Home || rangeType > lastTypeSet_, + "Can only set either home or a larger type than the last one"); - lastTypeSet_ = rangeType; + for (int i = static_cast(rangeType); i < static_cast(Type::Number); i++) + { + end_[i] = end; } - private: - /*! \brief The list of end atom indices */ - std::array(Type::Number)> end_; - Type lastTypeSet_ = Type::Number; + lastTypeSet_ = rangeType; + } + +private: + /*! \brief The list of end atom indices */ + std::array(Type::Number)> end_; + Type lastTypeSet_ = Type::Number; }; /*! \brief Enum of dynamic load balancing states @@ -285,8 +273,8 @@ class DDAtomRanges */ enum class DlbState { - offUser, /**< DLB is permanently off per user request */ - offForever, /**< DLB is off due to a runtime condition (not supported or causes performance loss) and will never be turned on */ + offUser, /**< DLB is permanently off per user request */ + offForever, /**< DLB is off due to a runtime condition (not supported or causes performance loss) and will never be turned on */ offCanTurnOn, /**< DLB is off and will turn on on imbalance */ offTemporarilyLocked, /**< DLB is off and temporarily can't turn on */ onCanTurnOff, /**< DLB is on and can turn off when slow */ @@ -298,19 +286,19 @@ enum class DlbState typedef struct { /**< The dimension */ - int dim = 0; + int dim = 0; /**< Tells if DD and PME dims match */ gmx_bool dim_match = false; /**< The number of PME ranks/domains in this dimension */ - int nslab = 0; + int nslab = 0; /**< Cell sizes for determining the PME comm. with SLB */ - real *slb_dim_f = nullptr; + real* slb_dim_f = nullptr; /**< The minimum pp node location, size nslab */ - int *pp_min = nullptr; + int* pp_min = nullptr; /**< The maximum pp node location, size nslab */ - int *pp_max = nullptr; + int* pp_max = nullptr; /**< The maximum shift for coordinate redistribution in PME */ - int maxshift = 0; + int maxshift = 0; } gmx_ddpme_t; struct gmx_ddzone_t @@ -336,7 +324,8 @@ struct gmx_ddzone_t /*! \brief The number of reals in gmx_ddzone_t */ constexpr int c_ddzoneNumReals = 8; -template class DDBufferAccess; +template +class DDBufferAccess; /*! \brief Temporary storage container that minimizes (re)allocation and clearing * @@ -346,109 +335,101 @@ template class DDBufferAccess; template class DDBuffer { - private: - /*! \brief Returns a buffer of size \p numElements, the elements are undefined */ - gmx::ArrayRef resize(size_t numElements) - { - GMX_ASSERT(isInUse_, "Should only operate on acquired buffers"); - - if (numElements > buffer_.size()) - { - buffer_.resize(numElements); - } +private: + /*! \brief Returns a buffer of size \p numElements, the elements are undefined */ + gmx::ArrayRef resize(size_t numElements) + { + GMX_ASSERT(isInUse_, "Should only operate on acquired buffers"); - return gmx::arrayRefFromArray(buffer_.data(), numElements); + if (numElements > buffer_.size()) + { + buffer_.resize(numElements); } - /*! \brief Acquire the buffer for use with size set to \p numElements, the elements are undefined */ - gmx::ArrayRef acquire(size_t numElements) - { - GMX_RELEASE_ASSERT(!isInUse_, "Should only request free buffers"); - isInUse_ = true; + return gmx::arrayRefFromArray(buffer_.data(), numElements); + } - return resize(numElements); - } + /*! \brief Acquire the buffer for use with size set to \p numElements, the elements are undefined */ + gmx::ArrayRef acquire(size_t numElements) + { + GMX_RELEASE_ASSERT(!isInUse_, "Should only request free buffers"); + isInUse_ = true; - /*! \brief Releases the buffer, buffer_ should not be used after this */ - void release() - { - GMX_RELEASE_ASSERT(isInUse_, "Should only release buffers in use"); - isInUse_ = false; - } + return resize(numElements); + } + + /*! \brief Releases the buffer, buffer_ should not be used after this */ + void release() + { + GMX_RELEASE_ASSERT(isInUse_, "Should only release buffers in use"); + isInUse_ = false; + } - std::vector buffer_; /**< The actual memory buffer */ - bool isInUse_ = false; /**< Flag that tells whether the buffer is in use */ + std::vector buffer_; /**< The actual memory buffer */ + bool isInUse_ = false; /**< Flag that tells whether the buffer is in use */ - friend class DDBufferAccess; + friend class DDBufferAccess; }; /*! \brief Class that manages access to a temporary memory buffer */ template class DDBufferAccess { - public: - /*! \brief Constructor, returns a buffer of size \p numElements, element values are undefined - * - * \note The actual memory buffer \p ddBuffer can not be used to - * create other DDBufferAccess objects until the one created - * here is destroyed. - */ - DDBufferAccess(DDBuffer &ddBuffer, - size_t numElements) : - ddBuffer_(ddBuffer) - { - buffer = ddBuffer_.acquire(numElements); - } +public: + /*! \brief Constructor, returns a buffer of size \p numElements, element values are undefined + * + * \note The actual memory buffer \p ddBuffer can not be used to + * create other DDBufferAccess objects until the one created + * here is destroyed. + */ + DDBufferAccess(DDBuffer& ddBuffer, size_t numElements) : ddBuffer_(ddBuffer) + { + buffer = ddBuffer_.acquire(numElements); + } - ~DDBufferAccess() - { - ddBuffer_.release(); - } + ~DDBufferAccess() { ddBuffer_.release(); } - /*! \brief Resizes the buffer to \p numElements, new elements are undefined - * - * \note The buffer arrayref is updated after this call. - */ - void resize(size_t numElements) - { - buffer = ddBuffer_.resize(numElements); - } + /*! \brief Resizes the buffer to \p numElements, new elements are undefined + * + * \note The buffer arrayref is updated after this call. + */ + void resize(size_t numElements) { buffer = ddBuffer_.resize(numElements); } - private: - DDBuffer &ddBuffer_; /**< Reference to the storage class */ - public: - gmx::ArrayRef buffer; /**< The access to the memory buffer */ +private: + DDBuffer& ddBuffer_; /**< Reference to the storage class */ +public: + gmx::ArrayRef buffer; /**< The access to the memory buffer */ }; /*! \brief Temporary buffer for setting up communiation over one pulse and all zones in the halo */ struct dd_comm_setup_work_t { /**< The local atom group indices to send */ - std::vector localAtomGroupBuffer; + std::vector localAtomGroupBuffer; /**< Buffer for collecting the global atom group indices to send */ - std::vector atomGroupBuffer; + std::vector atomGroupBuffer; /**< Buffer for collecting the atom group positions to send */ std::vector positionBuffer; /**< The number of atoms contained in the atom groups to send */ - int nat = 0; + int nat = 0; /**< The number of atom groups to send for the last zone */ - int nsend_zone = 0; + int nsend_zone = 0; }; /*! \brief Information about the simulated system */ struct DDSystemInfo { //! True when update groups are used - bool useUpdateGroups = false; + bool useUpdateGroups = false; //! Update atom grouping for each molecule type std::vector updateGroupingPerMoleculetype; //! The maximum radius over all update groups - real maxUpdateGroupRadius; + real maxUpdateGroupRadius; //! Are molecules always whole, i.e. not broken by PBC? - bool moleculesAreAlwaysWhole = false; + bool moleculesAreAlwaysWhole = false; //! Are there inter-domain bonded interactions? - bool haveInterDomainBondeds = false; + bool haveInterDomainBondeds = false; //! Are there inter-domain multi-body interactions? bool haveInterDomainMultiBodyBondeds = false; @@ -487,9 +468,9 @@ struct DDSettings /* Information for managing the dynamic load balancing */ //! Maximum DLB scaling per load balancing step in percent - int dlb_scale_lim = 0; + int dlb_scale_lim = 0; //! Flop counter (0=no,1=yes,2=with (eFlop-1)*5% noise - int eFlop = 0; + int eFlop = 0; //! Request 1D domain decomposition with maximum one communication pulse bool request1DAnd1Pulse; @@ -505,11 +486,11 @@ struct DDSettings /* Debugging */ //! Step interval for dumping the local+non-local atoms to pdb - int nstDDDump = 0; + int nstDDDump = 0; //! Step interval for duming the DD grid to pdb - int nstDDDumpGrid = 0; + int nstDDDumpGrid = 0; //! DD debug print level: 0, 1, 2 - int DD_debug = 0; + int DD_debug = 0; //! The DLB state at the start of the run DlbState initialDlbState = DlbState::offCanTurnOn; @@ -519,20 +500,20 @@ struct DDSettings struct DDRankSetup { /**< The number of particle-particle (non PME-only) ranks */ - int numPPRanks = 0; + int numPPRanks = 0; /**< The DD PP grid */ - ivec numPPCells = { 0, 0, 0 }; + ivec numPPCells = { 0, 0, 0 }; /* PME and Cartesian communicator stuff */ - bool usePmeOnlyRanks = false; + bool usePmeOnlyRanks = false; /**< The number of decomposition dimensions for PME, 0: no PME */ - int npmedecompdim = 0; + int npmedecompdim = 0; /**< The number of ranks doing PME (PP/PME or only PME) */ - int numRanksDoingPme = 0; + int numRanksDoingPme = 0; /**< The number of PME ranks/domains along x */ - int npmenodes_x = 0; + int npmenodes_x = 0; /**< The number of PME ranks/domains along y */ - int npmenodes_y = 0; + int npmenodes_y = 0; /**< The 1D or 2D PME domain decomposition setup */ gmx_ddpme_t ddpme[2]; }; @@ -541,17 +522,17 @@ struct DDRankSetup struct CartesianRankSetup { /**< Use Cartesian communication between PP and PME ranks */ - bool bCartesianPP_PME = false; + bool bCartesianPP_PME = false; /**< Cartesian grid for combinted PP+PME ranks */ - ivec ntot = { }; + ivec ntot = {}; /**< The number of dimensions for the PME setup that are Cartesian */ - int cartpmedim = 0; + int cartpmedim = 0; /**< The Cartesian index to sim rank conversion, used with bCartesianPP_PME */ std::vector ddindex2simnodeid; /* The DD particle-particle nodes only */ /**< Use a Cartesian communicator for PP */ - bool bCartesianPP = false; + bool bCartesianPP = false; /**< The Cartesian index to DD rank conversion, used with bCartesianPP */ std::vector ddindex2ddnodeid; }; @@ -572,7 +553,7 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) DDSettings ddSettings; /**< Information on how the DD ranks are set up */ - DDRankSetup ddRankSetup; + DDRankSetup ddRankSetup; /**< Information on the Cartesian part of the DD rank setup */ CartesianRankSetup cartesianRankSetup; @@ -585,30 +566,30 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) /* Data for the optional filtering of communication of atoms for bonded interactions */ /**< Links between atoms through bonded interactions */ - t_blocka *bondedLinks = nullptr; + t_blocka* bondedLinks = nullptr; /* The DLB state, possible values are defined above */ DlbState dlbState; /* With dlbState=DlbState::offCanTurnOn, should we check if to DLB on at the next DD? */ gmx_bool bCheckWhetherToTurnDlbOn = false; /* The first DD count since we are running without DLB */ - int ddPartioningCountFirstDlbOff = 0; + int ddPartioningCountFirstDlbOff = 0; /* Cell sizes for static load balancing, first index cartesian */ - real **slb_frac = nullptr; + real** slb_frac = nullptr; /**< Information about the simulated system */ DDSystemInfo systemInfo; /* The width of the communicated boundaries */ /**< Cut-off for multi-body interactions, also 2-body bonded when \p cutoff_mody > \p cutoff */ - real cutoff_mbody = 0; + real cutoff_mbody = 0; /**< The minimum guaranteed cell-size, Cartesian indexing */ - rvec cellsize_min = { }; + rvec cellsize_min = {}; /**< The minimum guaranteed cell-size with dlb=auto */ - rvec cellsize_min_dlb = { }; + rvec cellsize_min_dlb = {}; /**< The lower limit for the DD cell size with DLB */ - real cellsize_limit = 0; + real cellsize_limit = 0; /**< Effectively no NB cut-off limit with DLB for systems without PBC? */ gmx_bool bVacDLBNoLimit = false; @@ -620,19 +601,19 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) real PMELoadBal_max_cutoff = 0; /**< box lower corner, required with dim's without pbc and -gcom */ - rvec box0 = { }; + rvec box0 = {}; /**< box size, required with dim's without pbc and -gcom */ - rvec box_size = { }; + rvec box_size = {}; /**< The DD cell lower corner, in triclinic space */ - rvec cell_x0 = { }; + rvec cell_x0 = {}; /**< The DD cell upper corner, in triclinic space */ - rvec cell_x1 = { }; + rvec cell_x1 = {}; /**< The old \p cell_x0, to check cg displacements */ - rvec old_cell_x0 = { }; + rvec old_cell_x0 = {}; /**< The old \p cell_x1, to check cg displacements */ - rvec old_cell_x1 = { }; + rvec old_cell_x1 = {}; /** The communication setup and charge group boundaries for the zones */ gmx_domdec_zones_t zones; @@ -652,7 +633,7 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) * * Dynamic load balancing is not permitted to change sizes if it * would violate this restriction. */ - int maxpulse = 0; + int maxpulse = 0; /** Which cg distribution is stored on the master node, * stored as DD partitioning call count. @@ -660,7 +641,7 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) int64_t master_cg_ddp_count = 0; /** The number of cg's received from the direct neighbors */ - int zone_ncg1[DD_MAXZONE] = {0}; + int zone_ncg1[DD_MAXZONE] = { 0 }; /** The atom ranges in the local state */ DDAtomRanges atomRanges; @@ -684,63 +665,63 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) /* Communication buffers for local redistribution */ /**< Charge group flag comm. buffers */ - std::array, DIM*2> cggl_flag; + std::array, DIM * 2> cggl_flag; /**< Charge group center comm. buffers */ - std::array, DIM*2> cgcm_state; + std::array, DIM * 2> cgcm_state; /* Cell sizes for dynamic load balancing */ std::vector cellsizesWithDlb; /* Stuff for load communication */ /**< The recorded load data */ - domdec_load_t *load = nullptr; + domdec_load_t* load = nullptr; /**< The number of MPI ranks sharing the GPU our rank is using */ - int nrank_gpu_shared = 0; + int nrank_gpu_shared = 0; #if GMX_MPI /**< The MPI load communicator */ - MPI_Comm *mpi_comm_load = nullptr; + MPI_Comm* mpi_comm_load = nullptr; /**< The MPI load communicator for ranks sharing a GPU */ - MPI_Comm mpi_comm_gpu_shared; + MPI_Comm mpi_comm_gpu_shared; #endif /**< Struct for timing the force load balancing region */ - BalanceRegion *balanceRegion = nullptr; + BalanceRegion* balanceRegion = nullptr; /* Cycle counters over nstlist steps */ /**< Total cycles counted */ - float cycl[ddCyclNr] = { }; + float cycl[ddCyclNr] = {}; /**< The number of cycle recordings */ - int cycl_n[ddCyclNr] = { }; + int cycl_n[ddCyclNr] = {}; /**< The maximum cycle count */ - float cycl_max[ddCyclNr] = { }; + float cycl_max[ddCyclNr] = {}; /**< Total flops counted */ double flop = 0.0; /**< The number of flop recordings */ - int flop_n = 0; + int flop_n = 0; /** How many times did we have load measurements */ - int n_load_have = 0; + int n_load_have = 0; /** How many times have we collected the load measurements */ - int n_load_collect = 0; + int n_load_collect = 0; /* Cycle count history for DLB checks */ /**< The averaged cycles per step over the last nstlist step before turning on DLB */ - float cyclesPerStepBeforeDLB = 0; + float cyclesPerStepBeforeDLB = 0; /**< The running average of the cycles per step during DLB */ - float cyclesPerStepDlbExpAverage = 0; + float cyclesPerStepDlbExpAverage = 0; /**< Have we turned off DLB (after turning DLB on)? */ - bool haveTurnedOffDlb = false; + bool haveTurnedOffDlb = false; /**< The DD step at which we last measured that DLB off was faster than DLB on, 0 if there was no such step */ - int64_t dlbSlowerPartitioningCount = 0; + int64_t dlbSlowerPartitioningCount = 0; /* Statistics for atoms */ /**< The atoms per range, summed over the steps */ - double sum_nat[static_cast(DDAtomRanges::Type::Number)] = { }; + double sum_nat[static_cast(DDAtomRanges::Type::Number)] = {}; /* Statistics for calls and times */ /**< The number of partioning calls */ - int ndecomp = 0; + int ndecomp = 0; /**< The number of load recordings */ - int nload = 0; + int nload = 0; /**< Total MD step time */ double load_step = 0.0; /**< Total PP force time */ @@ -748,7 +729,7 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) /**< Max \p load_sum over the ranks */ double load_max = 0.0; /**< Was load balancing limited, per DD dim */ - ivec load_lim = { }; + ivec load_lim = {}; /**< Total time on PP done during PME overlap time */ double load_mdf = 0.0; /**< Total time on our PME-only rank */ @@ -764,7 +745,7 @@ struct gmx_domdec_comm_t // NOLINT (clang-analyzer-optin.performance.Padding) * that leads to consecutive charge groups for neighbor searching. * TODO: It should be possible to remove this now that the group scheme is removed */ -static const int zone_perm[3][4] = { {0, 0, 0, 0}, {1, 0, 0, 0}, {3, 0, 1, 2} }; +static const int zone_perm[3][4] = { { 0, 0, 0, 0 }, { 1, 0, 0, 0 }, { 3, 0, 1, 2 } }; /*! \brief DD zone reordering to Cartesian order * @@ -778,27 +759,26 @@ static const int zone_reorder_cartesian[DD_MAXZONE] = { 0, 1, 3, 2, 5, 4, 6, 7 } */ /*! \brief Returns the DD cut-off distance for multi-body interactions */ -real dd_cutoff_multibody(const gmx_domdec_t *dd); +real dd_cutoff_multibody(const gmx_domdec_t* dd); /*! \brief Returns the DD cut-off distance for two-body interactions */ -real dd_cutoff_twobody(const gmx_domdec_t *dd); +real dd_cutoff_twobody(const gmx_domdec_t* dd); /*! \brief Returns the domain index given the number of domains and the domain coordinates * * This order is required to minimize the coordinate communication in PME * which uses decomposition in the x direction. */ -static inline int dd_index(const ivec numDomains, - const ivec domainCoordinates) +static inline int dd_index(const ivec numDomains, const ivec domainCoordinates) { - return ((domainCoordinates[XX]*numDomains[YY] + domainCoordinates[YY])*numDomains[ZZ]) + domainCoordinates[ZZ]; + return ((domainCoordinates[XX] * numDomains[YY] + domainCoordinates[YY]) * numDomains[ZZ]) + + domainCoordinates[ZZ]; }; /*! Returns the size of the buffer to hold fractional cell boundaries for DD dimension index dimIndex */ -static inline int ddCellFractionBufferSize(const gmx_domdec_t *dd, - int dimIndex) +static inline int ddCellFractionBufferSize(const gmx_domdec_t* dd, int dimIndex) { - return dd->nc[dd->dim[dimIndex ]] + 1 + dimIndex*2 + 1 + dimIndex; + return dd->nc[dd->dim[dimIndex]] + 1 + dimIndex * 2 + 1 + dimIndex; } /*! \brief Maximum number of ranks for using send/recv for state scattering and gathering @@ -811,10 +791,10 @@ static inline int ddCellFractionBufferSize(const gmx_domdec_t *dd, static constexpr int c_maxNumRanksUseSendRecvForScatterAndGather = 4; /*! \brief Make DD cells larger by this factor than the limit to avoid rounding issues */ -static constexpr double DD_CELL_MARGIN = 1.0001; +static constexpr double DD_CELL_MARGIN = 1.0001; /*! \brief Factor for checking DD cell size limitation during DLB, should be in between 1 and DD_CELL_MARGIN */ -static constexpr double DD_CELL_MARGIN2 = 1.00005; +static constexpr double DD_CELL_MARGIN2 = 1.00005; /*! \brief With pressure scaling, keep cell sizes 2% above the limit to allow for some scaling */ static constexpr double DD_PRES_SCALE_MARGIN = 1.02; diff --git a/src/gromacs/domdec/domdec_network.cpp b/src/gromacs/domdec/domdec_network.cpp index 28f71eaf8b..9bc3b99344 100644 --- a/src/gromacs/domdec/domdec_network.cpp +++ b/src/gromacs/domdec/domdec_network.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2008,2009,2010,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2008-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,7 +57,7 @@ /*! \brief Returns the MPI rank of the domain decomposition master rank */ -#define DDMASTERRANK(dd) ((dd)->masterrank) +#define DDMASTERRANK(dd) ((dd)->masterrank) /*! \brief Move data of type \p T in the communication region one cell along @@ -66,45 +66,37 @@ * Moves in the dimension indexed by ddDimensionIndex, either forward * (direction=dddirFoward) or backward (direction=dddirBackward). */ -template -void -ddSendrecv(const struct gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - T *sendBuffer, - int numElementsToSend, - T *receiveBuffer, - int numElementsToReceive) +template +void ddSendrecv(const struct gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + T* sendBuffer, + int numElementsToSend, + T* receiveBuffer, + int numElementsToReceive) { #if GMX_MPI - int sendRank = dd->neighbor[ddDimensionIndex][direction == dddirForward ? 0 : 1]; - int receiveRank = dd->neighbor[ddDimensionIndex][direction == dddirForward ? 1 : 0]; + int sendRank = dd->neighbor[ddDimensionIndex][direction == dddirForward ? 0 : 1]; + int receiveRank = dd->neighbor[ddDimensionIndex][direction == dddirForward ? 1 : 0]; - constexpr int mpiTag = 0; + constexpr int mpiTag = 0; MPI_Status mpiStatus; if (numElementsToSend > 0 && numElementsToReceive > 0) { - MPI_Sendrecv(sendBuffer, numElementsToSend*sizeof(T), MPI_BYTE, - sendRank, mpiTag, - receiveBuffer, numElementsToReceive*sizeof(T), MPI_BYTE, - receiveRank, mpiTag, - dd->mpi_comm_all, - &mpiStatus); + MPI_Sendrecv(sendBuffer, numElementsToSend * sizeof(T), MPI_BYTE, sendRank, mpiTag, + receiveBuffer, numElementsToReceive * sizeof(T), MPI_BYTE, receiveRank, mpiTag, + dd->mpi_comm_all, &mpiStatus); } else if (numElementsToSend > 0) { - MPI_Send( sendBuffer, numElementsToSend*sizeof(T), MPI_BYTE, - sendRank, mpiTag, - dd->mpi_comm_all); + MPI_Send(sendBuffer, numElementsToSend * sizeof(T), MPI_BYTE, sendRank, mpiTag, dd->mpi_comm_all); } else if (numElementsToReceive > 0) { - MPI_Recv( receiveBuffer, numElementsToReceive*sizeof(T), MPI_BYTE, - receiveRank, mpiTag, - dd->mpi_comm_all, - &mpiStatus); + MPI_Recv(receiveBuffer, numElementsToReceive * sizeof(T), MPI_BYTE, receiveRank, mpiTag, + dd->mpi_comm_all, &mpiStatus); } -#else // GMX_MPI +#else // GMX_MPI GMX_UNUSED_VALUE(dd); GMX_UNUSED_VALUE(ddDimensionIndex); GMX_UNUSED_VALUE(direction); @@ -116,44 +108,40 @@ ddSendrecv(const struct gmx_domdec_t *dd, } //! Specialization of extern template for int -template void ddSendrecv(const gmx_domdec_t *, int, int, - int *, int, int *, int); +template void ddSendrecv(const gmx_domdec_t*, int, int, int*, int, int*, int); //! Specialization of extern template for real -template void ddSendrecv(const gmx_domdec_t *, int, int, - real *, int, real *, int); +template void ddSendrecv(const gmx_domdec_t*, int, int, real*, int, real*, int); //! Specialization of extern template for gmx::RVec -template void ddSendrecv(const gmx_domdec_t *, int, int, - rvec *, int, rvec *, int); +template void ddSendrecv(const gmx_domdec_t*, int, int, rvec*, int, rvec*, int); -template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - gmx::ArrayRef sendBuffer, - gmx::ArrayRef receiveBuffer) +template +void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + gmx::ArrayRef sendBuffer, + gmx::ArrayRef receiveBuffer) { - ddSendrecv(dd, ddDimensionIndex, direction, - sendBuffer.data(), sendBuffer.size(), + ddSendrecv(dd, ddDimensionIndex, direction, sendBuffer.data(), sendBuffer.size(), receiveBuffer.data(), receiveBuffer.size()); } //! Specialization of extern template for int -template void ddSendrecv(const gmx_domdec_t *, int, int, - gmx::ArrayRef, gmx::ArrayRef); +template void ddSendrecv(const gmx_domdec_t*, int, int, gmx::ArrayRef, gmx::ArrayRef); //! Specialization of extern template for real -template void ddSendrecv(const gmx_domdec_t *, int, int, - gmx::ArrayRef, gmx::ArrayRef); +template void ddSendrecv(const gmx_domdec_t*, int, int, gmx::ArrayRef, gmx::ArrayRef); //! Specialization of extern template for gmx::RVec -template void ddSendrecv(const gmx_domdec_t *, int, int, - gmx::ArrayRef, gmx::ArrayRef); +template void ddSendrecv(const gmx_domdec_t*, int, int, gmx::ArrayRef, gmx::ArrayRef); -void dd_sendrecv2_rvec(const struct gmx_domdec_t gmx_unused *dd, +void dd_sendrecv2_rvec(const struct gmx_domdec_t gmx_unused* dd, int gmx_unused ddimind, - rvec gmx_unused *buf_s_fw, int gmx_unused n_s_fw, - rvec gmx_unused *buf_r_fw, int gmx_unused n_r_fw, - rvec gmx_unused *buf_s_bw, int gmx_unused n_s_bw, - rvec gmx_unused *buf_r_bw, int gmx_unused n_r_bw) + rvec gmx_unused* buf_s_fw, + int gmx_unused n_s_fw, + rvec gmx_unused* buf_r_fw, + int gmx_unused n_r_fw, + rvec gmx_unused* buf_s_bw, + int gmx_unused n_s_bw, + rvec gmx_unused* buf_r_bw, + int gmx_unused n_r_bw) { #if GMX_MPI int rank_fw, rank_bw, nreq; @@ -176,23 +164,23 @@ void dd_sendrecv2_rvec(const struct gmx_domdec_t gmx_unused *dd, nreq = 0; if (n_r_fw) { - MPI_Irecv(buf_r_fw[0], n_r_fw*sizeof(rvec), MPI_BYTE, - rank_bw, 0, dd->mpi_comm_all, &req[nreq++]); + MPI_Irecv(buf_r_fw[0], n_r_fw * sizeof(rvec), MPI_BYTE, rank_bw, 0, dd->mpi_comm_all, + &req[nreq++]); } if (n_r_bw) { - MPI_Irecv(buf_r_bw[0], n_r_bw*sizeof(rvec), MPI_BYTE, - rank_fw, 1, dd->mpi_comm_all, &req[nreq++]); + MPI_Irecv(buf_r_bw[0], n_r_bw * sizeof(rvec), MPI_BYTE, rank_fw, 1, dd->mpi_comm_all, + &req[nreq++]); } if (n_s_fw) { - MPI_Isend(buf_s_fw[0], n_s_fw*sizeof(rvec), MPI_BYTE, - rank_fw, 0, dd->mpi_comm_all, &req[nreq++]); + MPI_Isend(buf_s_fw[0], n_s_fw * sizeof(rvec), MPI_BYTE, rank_fw, 0, dd->mpi_comm_all, + &req[nreq++]); } if (n_s_bw) { - MPI_Isend(buf_s_bw[0], n_s_bw*sizeof(rvec), MPI_BYTE, - rank_bw, 1, dd->mpi_comm_all, &req[nreq++]); + MPI_Isend(buf_s_bw[0], n_s_bw * sizeof(rvec), MPI_BYTE, rank_bw, 1, dd->mpi_comm_all, + &req[nreq++]); } if (nreq) { @@ -206,29 +194,26 @@ void dd_sendrecv2_rvec(const struct gmx_domdec_t gmx_unused *dd, * with a single full-duplex network connection per machine. */ /* Forward */ - MPI_Sendrecv(buf_s_fw[0], n_s_fw*sizeof(rvec), MPI_BYTE, rank_fw, 0, - buf_r_fw[0], n_r_fw*sizeof(rvec), MPI_BYTE, rank_bw, 0, - dd->mpi_comm_all, &stat[0]); + MPI_Sendrecv(buf_s_fw[0], n_s_fw * sizeof(rvec), MPI_BYTE, rank_fw, 0, buf_r_fw[0], + n_r_fw * sizeof(rvec), MPI_BYTE, rank_bw, 0, dd->mpi_comm_all, &stat[0]); /* Backward */ - MPI_Sendrecv(buf_s_bw[0], n_s_bw*sizeof(rvec), MPI_BYTE, rank_bw, 0, - buf_r_bw[0], n_r_bw*sizeof(rvec), MPI_BYTE, rank_fw, 0, - dd->mpi_comm_all, &stat[0]); + MPI_Sendrecv(buf_s_bw[0], n_s_bw * sizeof(rvec), MPI_BYTE, rank_bw, 0, buf_r_bw[0], + n_r_bw * sizeof(rvec), MPI_BYTE, rank_fw, 0, dd->mpi_comm_all, &stat[0]); } #endif } -void dd_bcast(const gmx_domdec_t gmx_unused *dd, int gmx_unused nbytes, void gmx_unused *data) +void dd_bcast(const gmx_domdec_t gmx_unused* dd, int gmx_unused nbytes, void gmx_unused* data) { #if GMX_MPI if (dd->nnodes > 1) { - MPI_Bcast(data, nbytes, MPI_BYTE, - DDMASTERRANK(dd), dd->mpi_comm_all); + MPI_Bcast(data, nbytes, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all); } #endif } -void dd_bcastc(const gmx_domdec_t *dd, int nbytes, void *src, void *dest) +void dd_bcastc(const gmx_domdec_t* dd, int nbytes, void* src, void* dest) { if (DDMASTER(dd) || dd->nnodes == 1) { @@ -237,20 +222,18 @@ void dd_bcastc(const gmx_domdec_t *dd, int nbytes, void *src, void *dest) #if GMX_MPI if (dd->nnodes > 1) { - MPI_Bcast(dest, nbytes, MPI_BYTE, - DDMASTERRANK(dd), dd->mpi_comm_all); + MPI_Bcast(dest, nbytes, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all); } #endif } -void dd_scatter(const gmx_domdec_t gmx_unused *dd, int gmx_unused nbytes, const void gmx_unused *src, void *dest) +void dd_scatter(const gmx_domdec_t gmx_unused* dd, int gmx_unused nbytes, const void gmx_unused* src, void* dest) { #if GMX_MPI if (dd->nnodes > 1) { /* Some MPI implementions don't specify const */ - MPI_Scatter(const_cast(src), nbytes, MPI_BYTE, - dest, nbytes, MPI_BYTE, + MPI_Scatter(const_cast(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all); } else @@ -264,19 +247,24 @@ void dd_scatter(const gmx_domdec_t gmx_unused *dd, int gmx_unused nbytes, const } } -void dd_gather(const gmx_domdec_t gmx_unused *dd, int gmx_unused nbytes, const void gmx_unused *src, void gmx_unused *dest) +void dd_gather(const gmx_domdec_t gmx_unused* dd, + int gmx_unused nbytes, + const void gmx_unused* src, + void gmx_unused* dest) { #if GMX_MPI /* Some MPI implementions don't specify const */ - MPI_Gather(const_cast(src), nbytes, MPI_BYTE, - dest, nbytes, MPI_BYTE, - DDMASTERRANK(dd), dd->mpi_comm_all); + MPI_Gather(const_cast(src), nbytes, MPI_BYTE, dest, nbytes, MPI_BYTE, DDMASTERRANK(dd), + dd->mpi_comm_all); #endif } -void dd_scatterv(const gmx_domdec_t gmx_unused *dd, - int gmx_unused *scounts, int gmx_unused *disps, const void *sbuf, - int rcount, void *rbuf) +void dd_scatterv(const gmx_domdec_t gmx_unused* dd, + int gmx_unused* scounts, + int gmx_unused* disps, + const void* sbuf, + int rcount, + void* rbuf) { #if GMX_MPI int dum; @@ -289,8 +277,7 @@ void dd_scatterv(const gmx_domdec_t gmx_unused *dd, rbuf = &dum; } /* Some MPI implementions don't specify const */ - MPI_Scatterv(const_cast(sbuf), scounts, disps, MPI_BYTE, - rbuf, rcount, MPI_BYTE, + MPI_Scatterv(const_cast(sbuf), scounts, disps, MPI_BYTE, rbuf, rcount, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all); } else @@ -304,9 +291,12 @@ void dd_scatterv(const gmx_domdec_t gmx_unused *dd, } } -void dd_gatherv(const gmx_domdec_t gmx_unused *dd, - int gmx_unused scount, const void gmx_unused *sbuf, - int gmx_unused *rcounts, int gmx_unused *disps, void gmx_unused *rbuf) +void dd_gatherv(const gmx_domdec_t gmx_unused* dd, + int gmx_unused scount, + const void gmx_unused* sbuf, + int gmx_unused* rcounts, + int gmx_unused* disps, + void gmx_unused* rbuf) { #if GMX_MPI int dum; @@ -317,8 +307,7 @@ void dd_gatherv(const gmx_domdec_t gmx_unused *dd, sbuf = &dum; } /* Some MPI implementions don't specify const */ - MPI_Gatherv(const_cast(sbuf), scount, MPI_BYTE, - rbuf, rcounts, disps, MPI_BYTE, + MPI_Gatherv(const_cast(sbuf), scount, MPI_BYTE, rbuf, rcounts, disps, MPI_BYTE, DDMASTERRANK(dd), dd->mpi_comm_all); #endif } diff --git a/src/gromacs/domdec/domdec_network.h b/src/gromacs/domdec/domdec_network.h index e9917b1949..902dbb768a 100644 --- a/src/gromacs/domdec/domdec_network.h +++ b/src/gromacs/domdec/domdec_network.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2008,2009,2010,2012,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2008-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,8 +55,10 @@ struct gmx_domdec_t; /* \brief */ -enum { - dddirForward, dddirBackward +enum +{ + dddirForward, + dddirBackward }; /*! \brief Move T values in the communication region one cell along @@ -68,39 +71,41 @@ enum { * made to the version taking ArrayRef parameters and this function * template removed when unused. */ -template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - T *sendBuffer, - int numElementsToSend, - T *receiveBuffer, - int numElementsToReceive); +template +void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + T* sendBuffer, + int numElementsToSend, + T* receiveBuffer, + int numElementsToReceive); //! Extern declaration for int specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, int direction, - int *buf_s, int n_s, - int *buf_r, int n_r); +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + int* buf_s, + int n_s, + int* buf_r, + int n_r); //! Extern declaration for real specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, int direction, - real *buf_s, int n_s, - real *buf_r, int n_r); +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + real* buf_s, + int n_s, + real* buf_r, + int n_r); //! Extern declaration for rvec specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, int direction, - rvec *buf_s, int n_s, - rvec *buf_r, int n_r); +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + rvec* buf_s, + int n_s, + rvec* buf_r, + int n_r); /*! \brief Move a view of T values in the communication region one * cell along the domain decomposition @@ -108,53 +113,49 @@ ddSendrecv(const gmx_domdec_t *dd, * Moves in the dimension indexed by ddDimensionIndex, either forward * (direction=dddirFoward) or backward (direction=dddirBackward). */ -template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - gmx::ArrayRef sendBuffer, - gmx::ArrayRef receiveBuffer); - -//! Extern declaration for int specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, +template +void ddSendrecv(const gmx_domdec_t* dd, int ddDimensionIndex, int direction, - gmx::ArrayRef sendBuffer, - gmx::ArrayRef receiveBuffer); + gmx::ArrayRef sendBuffer, + gmx::ArrayRef receiveBuffer); + +//! Extern declaration for int specialization +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + gmx::ArrayRef sendBuffer, + gmx::ArrayRef receiveBuffer); //! Extern declaration for real specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - gmx::ArrayRef sendBuffer, - gmx::ArrayRef receiveBuffer); +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + gmx::ArrayRef sendBuffer, + gmx::ArrayRef receiveBuffer); //! Extern declaration for gmx::RVec specialization -extern template -void -ddSendrecv(const gmx_domdec_t *dd, - int ddDimensionIndex, - int direction, - gmx::ArrayRef sendBuffer, - gmx::ArrayRef receiveBuffer); +extern template void ddSendrecv(const gmx_domdec_t* dd, + int ddDimensionIndex, + int direction, + gmx::ArrayRef sendBuffer, + gmx::ArrayRef receiveBuffer); /*! \brief Move revc's in the comm. region one cell along the domain decomposition * * Moves in dimension indexed by ddimind, simultaneously in the forward * and backward directions. */ -void -dd_sendrecv2_rvec(const struct gmx_domdec_t *dd, - int ddimind, - rvec *buf_s_fw, int n_s_fw, - rvec *buf_r_fw, int n_r_fw, - rvec *buf_s_bw, int n_s_bw, - rvec *buf_r_bw, int n_r_bw); +void dd_sendrecv2_rvec(const struct gmx_domdec_t* dd, + int ddimind, + rvec* buf_s_fw, + int n_s_fw, + rvec* buf_r_fw, + int n_r_fw, + rvec* buf_s_bw, + int n_s_bw, + rvec* buf_r_bw, + int n_r_bw); /* The functions below perform the same operations as the MPI functions @@ -164,39 +165,29 @@ dd_sendrecv2_rvec(const struct gmx_domdec_t *dd, */ /*! \brief Broadcasts \p nbytes from \p data on \p DDMASTERRANK to all PP ranks */ -void -dd_bcast(const gmx_domdec_t *dd, int nbytes, void *data); +void dd_bcast(const gmx_domdec_t* dd, int nbytes, void* data); /*! \brief Copies \p nbytes from \p src to \p dest on \p DDMASTERRANK * and then broadcasts to \p dest on all PP ranks */ -void -dd_bcastc(const gmx_domdec_t *dd, int nbytes, void *src, void *dest); +void dd_bcastc(const gmx_domdec_t* dd, int nbytes, void* src, void* dest); /*! \brief Scatters \p nbytes from \p src on \p DDMASTERRANK to all PP ranks, received in \p dest */ -void -dd_scatter(const gmx_domdec_t *dd, int nbytes, const void *src, void *dest); +void dd_scatter(const gmx_domdec_t* dd, int nbytes, const void* src, void* dest); /*! \brief Gathers \p nbytes from \p src on all PP ranks, received in \p dest on \p DDMASTERRANK */ -void -dd_gather(const gmx_domdec_t *dd, int nbytes, const void *src, void *dest); +void dd_gather(const gmx_domdec_t* dd, int nbytes, const void* src, void* dest); /*! \brief Scatters \p scounts bytes from \p src on \p DDMASTERRANK to all PP ranks, receiving \p rcount bytes in \p dest. * * See man MPI_Scatterv for details of how to construct scounts and disps. * If rcount==0, rbuf is allowed to be NULL */ -void -dd_scatterv(const gmx_domdec_t *dd, - int *scounts, int *disps, const void *sbuf, - int rcount, void *rbuf); +void dd_scatterv(const gmx_domdec_t* dd, int* scounts, int* disps, const void* sbuf, int rcount, void* rbuf); /*! \brief Gathers \p rcount bytes from \p src on all PP ranks, received in \p scounts bytes in \p dest on \p DDMASTERRANK. * * See man MPI_Gatherv for details of how to construct scounts and disps. * * If scount==0, sbuf is allowed to be NULL */ -void -dd_gatherv(const gmx_domdec_t *dd, - int scount, const void *sbuf, - int *rcounts, int *disps, void *rbuf); +void dd_gatherv(const gmx_domdec_t* dd, int scount, const void* sbuf, int* rcounts, int* disps, void* rbuf); #endif diff --git a/src/gromacs/domdec/domdec_setup.cpp b/src/gromacs/domdec/domdec_setup.cpp index 165fa395cc..ea5a190c98 100644 --- a/src/gromacs/domdec/domdec_setup.cpp +++ b/src/gromacs/domdec/domdec_setup.cpp @@ -84,9 +84,7 @@ using gmx::DomdecOptions; * \param[out] fac Vector of factors (to be allocated in this function) * \param[out] mfac Vector with the number of times each factor repeats in the factorization (to be allocated in this function) */ -static void factorize(int n, - std::vector *fac, - std::vector *mfac) +static void factorize(int n, std::vector* fac, std::vector* mfac) { if (n <= 0) { @@ -146,7 +144,7 @@ static int lcd(int n1, int n2) /*! \brief Returns TRUE when there are enough PME ranks for the ratio */ static gmx_bool fits_pme_ratio(int nrank_tot, int nrank_pme, float ratio) { - return (static_cast(nrank_pme)/static_cast(nrank_tot) > 0.95*ratio); + return (static_cast(nrank_pme) / static_cast(nrank_tot) > 0.95 * ratio); } /*! \brief Returns TRUE when npme out of ntot ranks doing PME is expected to give reasonable performance */ @@ -174,7 +172,7 @@ static gmx_bool fits_pp_pme_perf(int ntot, int npme, float ratio) * The factor of 2 allows for a maximum ratio of 2^2=4 * between nx_pme and ny_pme. */ - if (lcd(ntot - npme, npme)*2 < npme_root2) + if (lcd(ntot - npme, npme) * 2 < npme_root2) { return FALSE; } @@ -184,26 +182,25 @@ static gmx_bool fits_pp_pme_perf(int ntot, int npme, float ratio) } /*! \brief Make a guess for the number of PME ranks to use. */ -static int guess_npme(const gmx::MDLogger &mdlog, - const gmx_mtop_t &mtop, - const t_inputrec &ir, +static int guess_npme(const gmx::MDLogger& mdlog, + const gmx_mtop_t& mtop, + const t_inputrec& ir, const matrix box, int nrank_tot) { - float ratio; - int npme; + float ratio; + int npme; ratio = pme_load_estimate(mtop, ir, box); - GMX_LOG(mdlog.info).appendTextFormatted( - "Guess for relative PME load: %.2f", ratio); + GMX_LOG(mdlog.info).appendTextFormatted("Guess for relative PME load: %.2f", ratio); /* We assume the optimal rank ratio is close to the load ratio. * The communication load is neglected, * but (hopefully) this will balance out between PP and PME. */ - if (!fits_pme_ratio(nrank_tot, nrank_tot/2, ratio)) + if (!fits_pme_ratio(nrank_tot, nrank_tot / 2, ratio)) { /* We would need more than nrank_tot/2 PME only nodes, * which is not possible. Since the PME load is very high, @@ -217,8 +214,8 @@ static int guess_npme(const gmx::MDLogger &mdlog, * We start with a minimum PME node fraction of 1/16 * and avoid ratios which lead to large prime factors in nnodes-npme. */ - npme = (nrank_tot + 15)/16; - while (npme <= nrank_tot/3) + npme = (nrank_tot + 15) / 16; + while (npme <= nrank_tot / 3) { if (nrank_tot % npme == 0) { @@ -232,11 +229,11 @@ static int guess_npme(const gmx::MDLogger &mdlog, } npme++; } - if (npme > nrank_tot/3) + if (npme > nrank_tot / 3) { /* Try any possible number for npme */ npme = 1; - while (npme <= nrank_tot/2) + while (npme <= nrank_tot / 2) { /* Note that fits_perf may change the PME grid */ if (fits_pp_pme_perf(nrank_tot, npme, ratio)) @@ -246,18 +243,23 @@ static int guess_npme(const gmx::MDLogger &mdlog, npme++; } } - if (npme > nrank_tot/2) + if (npme > nrank_tot / 2) { - gmx_fatal(FARGS, "Could not find an appropriate number of separate PME ranks. i.e. >= %5f*#ranks (%d) and <= #ranks/2 (%d) and reasonable performance wise (grid_x=%d, grid_y=%d).\n" - "Use the -npme option of mdrun or change the number of ranks or the PME grid dimensions, see the manual for details.", - ratio, gmx::roundToInt(0.95*ratio*nrank_tot), nrank_tot/2, ir.nkx, ir.nky); + gmx_fatal(FARGS, + "Could not find an appropriate number of separate PME ranks. i.e. >= %5f*#ranks " + "(%d) and <= #ranks/2 (%d) and reasonable performance wise (grid_x=%d, " + "grid_y=%d).\n" + "Use the -npme option of mdrun or change the number of ranks or the PME grid " + "dimensions, see the manual for details.", + ratio, gmx::roundToInt(0.95 * ratio * nrank_tot), nrank_tot / 2, ir.nkx, ir.nky); } else { - GMX_LOG(mdlog.info).appendTextFormatted( - "Will use %d particle-particle and %d PME only ranks\n" - "This is a guess, check the performance at the end of the log file", - nrank_tot - npme, npme); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Will use %d particle-particle and %d PME only ranks\n" + "This is a guess, check the performance at the end of the log file", + nrank_tot - npme, npme); } return npme; @@ -266,10 +268,10 @@ static int guess_npme(const gmx::MDLogger &mdlog, /*! \brief Return \p n divided by \p f rounded up to the next integer. */ static int div_up(int n, int f) { - return (n + f - 1)/f; + return (n + f - 1) / f; } -real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox) +real comm_box_frac(const gmx::IVec& dd_nc, real cutoff, const gmx_ddbox_t& ddbox) { int i, j, k; rvec nw; @@ -277,8 +279,8 @@ real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox for (i = 0; i < DIM; i++) { - real bt = ddbox.box_size[i]*ddbox.skew_fac[i]; - nw[i] = dd_nc[i]*cutoff/bt; + real bt = ddbox.box_size[i] * ddbox.skew_fac[i]; + nw[i] = dd_nc[i] * cutoff / bt; } comm_vol = 0; @@ -287,16 +289,16 @@ real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox if (dd_nc[i] > 1) { comm_vol += nw[i]; - for (j = i+1; j < DIM; j++) + for (j = i + 1; j < DIM; j++) { if (dd_nc[j] > 1) { - comm_vol += nw[i]*nw[j]*M_PI/4; - for (k = j+1; k < DIM; k++) + comm_vol += nw[i] * nw[j] * M_PI / 4; + for (k = j + 1; k < DIM; k++) { if (dd_nc[k] > 1) { - comm_vol += nw[i]*nw[j]*nw[k]*M_PI/6; + comm_vol += nw[i] * nw[j] * nw[k] * M_PI / 6; } } } @@ -308,10 +310,10 @@ real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox } /*! \brief Return whether the DD inhomogeneous in the z direction */ -static gmx_bool inhomogeneous_z(const t_inputrec &ir) +static gmx_bool inhomogeneous_z(const t_inputrec& ir) { - return ((EEL_PME(ir.coulombtype) || ir.coulombtype == eelEWALD) && - ir.ePBC == epbcXYZ && ir.ewald_geometry == eewg3DC); + return ((EEL_PME(ir.coulombtype) || ir.coulombtype == eelEWALD) && ir.ePBC == epbcXYZ + && ir.ewald_geometry == eewg3DC); } /*! \brief Estimate cost of PME FFT communication @@ -326,7 +328,7 @@ static float comm_pme_cost_vol(int npme, int a, int b, int c) /* We use a float here, since an integer might overflow */ float comm_vol; - comm_vol = npme - 1; + comm_vol = npme - 1; comm_vol *= npme; comm_vol *= div_up(a, npme); comm_vol *= div_up(b, npme); @@ -336,13 +338,17 @@ static float comm_pme_cost_vol(int npme, int a, int b, int c) } /*! \brief Estimate cost of communication for a possible domain decomposition. */ -static float comm_cost_est(real limit, real cutoff, - const matrix box, const gmx_ddbox_t &ddbox, - int natoms, const t_inputrec &ir, - float pbcdxr, - int npme_tot, const gmx::IVec &nc) +static float comm_cost_est(real limit, + real cutoff, + const matrix box, + const gmx_ddbox_t& ddbox, + int natoms, + const t_inputrec& ir, + float pbcdxr, + int npme_tot, + const gmx::IVec& nc) { - gmx::IVec npme = {1, 1, 1}; + gmx::IVec npme = { 1, 1, 1 }; int i, j, nk, overlap; rvec bt; float comm_vol, comm_vol_xf, comm_pme, cost_pbcdx; @@ -356,8 +362,8 @@ static float comm_cost_est(real limit, real cutoff, float temp; /* Check the DD algorithm restrictions */ - if ((ir.ePBC == epbcXY && ir.nwall < 2 && nc[ZZ] > 1) || - (ir.ePBC == epbcSCREW && (nc[XX] == 1 || nc[YY] > 1 || nc[ZZ] > 1))) + if ((ir.ePBC == epbcXY && ir.nwall < 2 && nc[ZZ] > 1) + || (ir.ePBC == epbcSCREW && (nc[XX] == 1 || nc[YY] > 1 || nc[ZZ] > 1))) { return -1; } @@ -372,10 +378,9 @@ static float comm_cost_est(real limit, real cutoff, /* Check if the triclinic requirements are met */ for (i = 0; i < DIM; i++) { - for (j = i+1; j < ddbox.npbcdim; j++) + for (j = i + 1; j < ddbox.npbcdim; j++) { - if (box[j][i] != 0 || ir.deform[j][i] != 0 || - (ir.epc != epcNO && ir.compress[j][i] != 0)) + if (box[j][i] != 0 || ir.deform[j][i] != 0 || (ir.epc != epcNO && ir.compress[j][i] != 0)) { if (nc[j] > 1 && nc[i] == 1) { @@ -387,15 +392,15 @@ static float comm_cost_est(real limit, real cutoff, for (i = 0; i < DIM; i++) { - bt[i] = ddbox.box_size[i]*ddbox.skew_fac[i]; + bt[i] = ddbox.box_size[i] * ddbox.skew_fac[i]; /* Without PBC and with 2 cells, there are no lower limits on the cell size */ - if (!(i >= ddbox.npbcdim && nc[i] <= 2) && bt[i] < nc[i]*limit) + if (!(i >= ddbox.npbcdim && nc[i] <= 2) && bt[i] < nc[i] * limit) { return -1; } /* With PBC, check if the cut-off fits in nc[i]-1 cells */ - if (i < ddbox.npbcdim && nc[i] > 1 && (nc[i] - 1)*bt[i] < nc[i]*cutoff) + if (i < ddbox.npbcdim && nc[i] > 1 && (nc[i] - 1) * bt[i] < nc[i] * cutoff) { return -1; } @@ -420,7 +425,7 @@ static float comm_cost_est(real limit, real cutoff, { /* Will we use 1D or 2D PME decomposition? */ npme[XX] = (npme_tot % nc[XX] == 0) ? nc[XX] : npme_tot; - npme[YY] = npme_tot/npme[XX]; + npme[YY] = npme_tot / npme[XX]; } } @@ -439,8 +444,8 @@ static float comm_cost_est(real limit, real cutoff, */ bool useThreads = true; bool errorsAreFatal = false; - if (!gmx_pme_check_restrictions(ir.pme_order, ir.nkx, ir.nky, ir.nkz, - npme_x, useThreads, errorsAreFatal)) + if (!gmx_pme_check_restrictions(ir.pme_order, ir.nkx, ir.nky, ir.nkz, npme_x, useThreads, + errorsAreFatal)) { return -1; } @@ -452,12 +457,12 @@ static float comm_cost_est(real limit, real cutoff, */ for (i = 0; i < DIM; i++) { - for (j = i+1; j < DIM; j++) + for (j = i + 1; j < DIM; j++) { /* Check if the box size is nearly identical, * in that case we prefer nx > ny and ny > nz. */ - if (std::fabs(bt[j] - bt[i]) < 0.01*bt[i] && nc[j] > nc[i]) + if (std::fabs(bt[j] - bt[i]) < 0.01 * bt[i] && nc[j] > nc[i]) { /* The XX/YY check is a bit compact. If nc[YY]==npme[YY] * this means the swapped nc has nc[XX]==npme[XX], @@ -467,9 +472,8 @@ static float comm_cost_est(real limit, real cutoff, * For x/y: if nc[YY]!=npme[YY], we can not swap x/y * For y/z: we can not have PME decomposition in z */ - if (npme_tot <= 1 || - !((i == XX && j == YY && nc[YY] != npme[YY]) || - (i == YY && j == ZZ && npme[YY] > 1))) + if (npme_tot <= 1 + || !((i == XX && j == YY && nc[YY] != npme[YY]) || (i == YY && j == ZZ && npme[YY] > 1))) { return -1; } @@ -492,28 +496,28 @@ static float comm_cost_est(real limit, real cutoff, { if (nc[i] > npme[i]) { - comm_vol_xf = (npme[i] == 2 ? 1.0/3.0 : 0.5); + comm_vol_xf = (npme[i] == 2 ? 1.0 / 3.0 : 0.5); } else { - comm_vol_xf = 1.0 - lcd(nc[i], npme[i])/static_cast(npme[i]); + comm_vol_xf = 1.0 - lcd(nc[i], npme[i]) / static_cast(npme[i]); } - comm_pme += 3*natoms*comm_vol_xf; + comm_pme += 3 * natoms * comm_vol_xf; } /* Grid overlap communication */ if (npme[i] > 1) { - nk = (i == 0 ? ir.nkx : ir.nky); - overlap = (nk % npme[i] == 0 ? ir.pme_order-1 : ir.pme_order); - temp = npme[i]; - temp *= overlap; - temp *= ir.nkx; - temp *= ir.nky; - temp *= ir.nkz; - temp /= nk; + nk = (i == 0 ? ir.nkx : ir.nky); + overlap = (nk % npme[i] == 0 ? ir.pme_order - 1 : ir.pme_order); + temp = npme[i]; + temp *= overlap; + temp *= ir.nkx; + temp *= ir.nky; + temp *= ir.nkz; + temp /= nk; comm_pme += temp; -/* Old line comm_pme += npme[i]*overlap*ir.nkx*ir.nky*ir.nkz/nk; */ + /* Old line comm_pme += npme[i]*overlap*ir.nkx*ir.nky*ir.nkz/nk; */ } } @@ -524,48 +528,51 @@ static float comm_cost_est(real limit, real cutoff, cost_pbcdx = 0; if ((nc[XX] == 1 || nc[YY] == 1) || (nc[ZZ] == 1 && ir.ePBC != epbcXY)) { - if ((ddbox.tric_dir[XX] && nc[XX] == 1) || - (ddbox.tric_dir[YY] && nc[YY] == 1)) + if ((ddbox.tric_dir[XX] && nc[XX] == 1) || (ddbox.tric_dir[YY] && nc[YY] == 1)) { - cost_pbcdx = pbcdxr*pbcdx_tric_fac; + cost_pbcdx = pbcdxr * pbcdx_tric_fac; } else { - cost_pbcdx = pbcdxr*pbcdx_rect_fac; + cost_pbcdx = pbcdxr * pbcdx_rect_fac; } } if (debug) { - fprintf(debug, - "nc %2d %2d %2d %2d %2d vol pp %6.4f pbcdx %6.4f pme %9.3e tot %9.3e\n", - nc[XX], nc[YY], nc[ZZ], npme[XX], npme[YY], - comm_vol, cost_pbcdx, comm_pme/(3*natoms), - comm_vol + cost_pbcdx + comm_pme/(3*natoms)); + fprintf(debug, "nc %2d %2d %2d %2d %2d vol pp %6.4f pbcdx %6.4f pme %9.3e tot %9.3e\n", + nc[XX], nc[YY], nc[ZZ], npme[XX], npme[YY], comm_vol, cost_pbcdx, + comm_pme / (3 * natoms), comm_vol + cost_pbcdx + comm_pme / (3 * natoms)); } - return 3*natoms*(comm_vol + cost_pbcdx) + comm_pme; + return 3 * natoms * (comm_vol + cost_pbcdx) + comm_pme; } /*! \brief Assign penalty factors to possible domain decompositions, * based on the estimated communication costs. */ -static void assign_factors(const real limit, const bool request1D, - const real cutoff, - const matrix box, const gmx_ddbox_t &ddbox, - int natoms, const t_inputrec &ir, - float pbcdxr, int npme, - int ndiv, const int *div, const int *mdiv, - gmx::IVec *irTryPtr, - gmx::IVec *opt) +static void assign_factors(const real limit, + const bool request1D, + const real cutoff, + const matrix box, + const gmx_ddbox_t& ddbox, + int natoms, + const t_inputrec& ir, + float pbcdxr, + int npme, + int ndiv, + const int* div, + const int* mdiv, + gmx::IVec* irTryPtr, + gmx::IVec* opt) { int x, y, i; float ce; - gmx::IVec &ir_try = *irTryPtr; + gmx::IVec& ir_try = *irTryPtr; if (ndiv == 0) { - const int maxDimensionSize = std::max(ir_try[XX], std::max(ir_try[YY], ir_try[ZZ])); - const int productOfDimensionSizes = ir_try[XX]*ir_try[YY]*ir_try[ZZ]; + const int maxDimensionSize = std::max(ir_try[XX], std::max(ir_try[YY], ir_try[ZZ])); + const int productOfDimensionSizes = ir_try[XX] * ir_try[YY] * ir_try[ZZ]; const bool decompositionHasOneDimension = (maxDimensionSize == productOfDimensionSizes); if (request1D && !decompositionHasOneDimension) { @@ -573,12 +580,10 @@ static void assign_factors(const real limit, const bool request1D, return; } - ce = comm_cost_est(limit, cutoff, box, ddbox, - natoms, ir, pbcdxr, npme, ir_try); - if (ce >= 0 && ((*opt)[XX] == 0 || - ce < comm_cost_est(limit, cutoff, box, ddbox, - natoms, ir, pbcdxr, - npme, *opt))) + ce = comm_cost_est(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ir_try); + if (ce >= 0 + && ((*opt)[XX] == 0 + || ce < comm_cost_est(limit, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, *opt))) { *opt = ir_try; } @@ -592,23 +597,22 @@ static void assign_factors(const real limit, const bool request1D, { ir_try[XX] *= div[0]; } - for (y = mdiv[0]-x; y >= 0; y--) + for (y = mdiv[0] - x; y >= 0; y--) { for (i = 0; i < y; i++) { ir_try[YY] *= div[0]; } - for (i = 0; i < mdiv[0]-x-y; i++) + for (i = 0; i < mdiv[0] - x - y; i++) { ir_try[ZZ] *= div[0]; } /* recurse */ - assign_factors(limit, request1D, - cutoff, box, ddbox, natoms, ir, pbcdxr, npme, - ndiv-1, div+1, mdiv+1, irTryPtr, opt); + assign_factors(limit, request1D, cutoff, box, ddbox, natoms, ir, pbcdxr, npme, ndiv - 1, + div + 1, mdiv + 1, irTryPtr, opt); - for (i = 0; i < mdiv[0]-x-y; i++) + for (i = 0; i < mdiv[0] - x - y; i++) { ir_try[ZZ] /= div[0]; } @@ -629,39 +633,40 @@ static void assign_factors(const real limit, const bool request1D, * * \returns The optimal grid cell choice. The latter will contain all * zeros if no valid cell choice exists. */ -static gmx::IVec -optimizeDDCells(const gmx::MDLogger &mdlog, - const int numRanksRequested, - const int numPmeOnlyRanks, - const real cellSizeLimit, - const bool request1DAnd1Pulse, - const gmx_mtop_t &mtop, - const matrix box, - const gmx_ddbox_t &ddbox, - const t_inputrec &ir, - const DDSystemInfo &systemInfo) +static gmx::IVec optimizeDDCells(const gmx::MDLogger& mdlog, + const int numRanksRequested, + const int numPmeOnlyRanks, + const real cellSizeLimit, + const bool request1DAnd1Pulse, + const gmx_mtop_t& mtop, + const matrix box, + const gmx_ddbox_t& ddbox, + const t_inputrec& ir, + const DDSystemInfo& systemInfo) { - double pbcdxr; + double pbcdxr; const int numPPRanks = numRanksRequested - numPmeOnlyRanks; - GMX_LOG(mdlog.info).appendTextFormatted( - "Optimizing the DD grid for %d cells with a minimum initial size of %.3f nm", - numPPRanks, cellSizeLimit); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Optimizing the DD grid for %d cells with a minimum initial size of %.3f nm", + numPPRanks, cellSizeLimit); if (inhomogeneous_z(ir)) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Ewald_geometry=%s: assuming inhomogeneous particle distribution in z, will not decompose in z.", - eewg_names[ir.ewald_geometry]); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Ewald_geometry=%s: assuming inhomogeneous particle distribution in z, " + "will not decompose in z.", + eewg_names[ir.ewald_geometry]); } // For cost estimates, we need the number of ranks doing PME work, // which is the number of PP ranks when not using separate // PME-only ranks. - const int numRanksDoingPmeWork = (EEL_PME(ir.coulombtype) ? - ((numPmeOnlyRanks > 0) ? numPmeOnlyRanks : numPPRanks) : - 0); + const int numRanksDoingPmeWork = + (EEL_PME(ir.coulombtype) ? ((numPmeOnlyRanks > 0) ? numPmeOnlyRanks : numPPRanks) : 0); if (systemInfo.haveInterDomainBondeds) { @@ -683,7 +688,7 @@ optimizeDDCells(const gmx::MDLogger &mdlog, std::string maximumCells = "The maximum allowed number of cells is:"; for (int d = 0; d < DIM; d++) { - int nmax = static_cast(ddbox.box_size[d]*ddbox.skew_fac[d]/cellSizeLimit); + int nmax = static_cast(ddbox.box_size[d] * ddbox.skew_fac[d] / cellSizeLimit); if (d >= ddbox.npbcdim && nmax < 2) { nmax = 2; @@ -709,20 +714,18 @@ optimizeDDCells(const gmx::MDLogger &mdlog, gmx::IVec itry = { 1, 1, 1 }; gmx::IVec numDomains = { 0, 0, 0 }; - assign_factors(cellSizeLimit, request1DAnd1Pulse, - systemInfo.cutoff, box, ddbox, mtop.natoms, ir, pbcdxr, - numRanksDoingPmeWork, div.size(), div.data(), mdiv.data(), &itry, &numDomains); + assign_factors(cellSizeLimit, request1DAnd1Pulse, systemInfo.cutoff, box, ddbox, mtop.natoms, ir, + pbcdxr, numRanksDoingPmeWork, div.size(), div.data(), mdiv.data(), &itry, &numDomains); return numDomains; } -real -getDDGridSetupCellSizeLimit(const gmx::MDLogger &mdlog, - const bool request1DAnd1Pulse, - const bool bDynLoadBal, - const real dlb_scale, - const t_inputrec &ir, - const real systemInfoCellSizeLimit) +real getDDGridSetupCellSizeLimit(const gmx::MDLogger& mdlog, + const bool request1DAnd1Pulse, + const bool bDynLoadBal, + const real dlb_scale, + const t_inputrec& ir, + const real systemInfoCellSizeLimit) { real cellSizeLimit = systemInfoCellSizeLimit; if (request1DAnd1Pulse) @@ -737,25 +740,24 @@ getDDGridSetupCellSizeLimit(const gmx::MDLogger &mdlog, { gmx_fatal(FARGS, "The value for option -dds should be smaller than 1"); } - GMX_LOG(mdlog.info).appendTextFormatted( - "Scaling the initial minimum size with 1/%g (option -dds) = %g", - dlb_scale, 1/dlb_scale); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Scaling the initial minimum size with 1/%g (option -dds) = %g", dlb_scale, + 1 / dlb_scale); cellSizeLimit /= dlb_scale; } else if (ir.epc != epcNO) { - GMX_LOG(mdlog.info).appendTextFormatted( - "To account for pressure scaling, scaling the initial minimum size with %g", - DD_GRID_MARGIN_PRES_SCALE); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "To account for pressure scaling, scaling the initial minimum size with %g", + DD_GRID_MARGIN_PRES_SCALE); cellSizeLimit *= DD_GRID_MARGIN_PRES_SCALE; } return cellSizeLimit; } -void -checkForValidRankCountRequests(const int numRanksRequested, - const bool usingPme, - const int numPmeRanksRequested) +void checkForValidRankCountRequests(const int numRanksRequested, const bool usingPme, const int numPmeRanksRequested) { int numPPRanksRequested = numRanksRequested; if (usingPme && numPmeRanksRequested > 0) @@ -764,7 +766,8 @@ checkForValidRankCountRequests(const int numRanksRequested, if (numPmeRanksRequested > numPPRanksRequested) { gmx_fatal(FARGS, - "Cannot have %d separate PME ranks with only %d PP ranks, choose fewer or no separate PME ranks", + "Cannot have %d separate PME ranks with only %d PP ranks, choose fewer or no " + "separate PME ranks", numPmeRanksRequested, numPPRanksRequested); } } @@ -776,10 +779,10 @@ checkForValidRankCountRequests(const int numRanksRequested, { const int largestDivisor = largest_divisor(numPPRanksRequested); /* Check if the largest divisor is more than numPPRanks ^ (2/3) */ - if (largestDivisor*largestDivisor*largestDivisor > - numPPRanksRequested*numPPRanksRequested) + if (largestDivisor * largestDivisor * largestDivisor > numPPRanksRequested * numPPRanksRequested) { - gmx_fatal(FARGS, "The number of ranks selected for particle-particle work (%d) " + gmx_fatal(FARGS, + "The number of ranks selected for particle-particle work (%d) " "contains a large prime factor %d. In most cases this will lead to " "bad performance. Choose a number with smaller prime factors or " "set the decomposition (option -dd) manually.", @@ -791,16 +794,15 @@ checkForValidRankCountRequests(const int numRanksRequested, /*! \brief Return the number of PME-only ranks used by the simulation * * If the user did not choose a number, then decide for them. */ -static int -getNumPmeOnlyRanksToUse(const gmx::MDLogger &mdlog, - const DomdecOptions &options, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - const int numRanksRequested) +static int getNumPmeOnlyRanksToUse(const gmx::MDLogger& mdlog, + const DomdecOptions& options, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + const int numRanksRequested) { int numPmeOnlyRanks; - const char *extraMessage = ""; + const char* extraMessage = ""; if (options.numCells[XX] > 0) { @@ -838,8 +840,9 @@ getNumPmeOnlyRanksToUse(const gmx::MDLogger &mdlog, if (numRanksRequested < minRankCountToDefaultToSeparatePmeRanks) { numPmeOnlyRanks = 0; - extraMessage = ", as there are too few total\n" - " ranks for efficient splitting"; + extraMessage = + ", as there are too few total\n" + " ranks for efficient splitting"; } else { @@ -848,23 +851,19 @@ getNumPmeOnlyRanksToUse(const gmx::MDLogger &mdlog, } } } - } GMX_RELEASE_ASSERT(numPmeOnlyRanks <= numRanksRequested, "Cannot have more PME ranks than total ranks"); if (EEL_PME(ir.coulombtype)) { - GMX_LOG(mdlog.info).appendTextFormatted - ("Using %d separate PME ranks%s", numPmeOnlyRanks, extraMessage); + GMX_LOG(mdlog.info).appendTextFormatted("Using %d separate PME ranks%s", numPmeOnlyRanks, extraMessage); } return numPmeOnlyRanks; } /*! \brief Sets the order of the DD dimensions, returns the number of DD dimensions */ -static int set_dd_dim(const gmx::IVec &numDDCells, - const DDSettings &ddSettings, - ivec *dims) +static int set_dd_dim(const gmx::IVec& numDDCells, const DDSettings& ddSettings, ivec* dims) { int ndim = 0; if (ddSettings.useDDOrderZYX) @@ -899,35 +898,33 @@ static int set_dd_dim(const gmx::IVec &numDDCells, return ndim; } -DDGridSetup -getDDGridSetup(const gmx::MDLogger &mdlog, - const t_commrec *cr, - const int numRanksRequested, - const DomdecOptions &options, - const DDSettings &ddSettings, - const DDSystemInfo &systemInfo, - const real cellSizeLimit, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef xGlobal, - gmx_ddbox_t *ddbox) +DDGridSetup getDDGridSetup(const gmx::MDLogger& mdlog, + const t_commrec* cr, + const int numRanksRequested, + const DomdecOptions& options, + const DDSettings& ddSettings, + const DDSystemInfo& systemInfo, + const real cellSizeLimit, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef xGlobal, + gmx_ddbox_t* ddbox) { int numPmeOnlyRanks = getNumPmeOnlyRanksToUse(mdlog, options, mtop, ir, box, numRanksRequested); - if (ddSettings.request1DAnd1Pulse && - (numRanksRequested - numPmeOnlyRanks == 1)) + if (ddSettings.request1DAnd1Pulse && (numRanksRequested - numPmeOnlyRanks == 1)) { // With only one PP rank, there will not be a need for // GPU-based halo exchange that wants to request that any DD // has only 1 dimension and 1 pulse. - return DDGridSetup {}; + return DDGridSetup{}; } gmx::IVec numDomains; if (options.numCells[XX] > 0) { - numDomains = gmx::IVec(options.numCells); + numDomains = gmx::IVec(options.numCells); const ivec numDomainsLegacyIvec = { numDomains[XX], numDomains[YY], numDomains[ZZ] }; set_ddbox_cr(*cr, &numDomainsLegacyIvec, ir, box, xGlobal, ddbox); } @@ -937,12 +934,8 @@ getDDGridSetup(const gmx::MDLogger &mdlog, if (MASTER(cr)) { - numDomains = - optimizeDDCells(mdlog, numRanksRequested, numPmeOnlyRanks, - cellSizeLimit, - ddSettings.request1DAnd1Pulse, - mtop, box, *ddbox, ir, - systemInfo); + numDomains = optimizeDDCells(mdlog, numRanksRequested, numPmeOnlyRanks, cellSizeLimit, + ddSettings.request1DAnd1Pulse, mtop, box, *ddbox, ir, systemInfo); } } diff --git a/src/gromacs/domdec/domdec_setup.h b/src/gromacs/domdec/domdec_setup.h index feb0a73f00..9e9bf5fa66 100644 --- a/src/gromacs/domdec/domdec_setup.h +++ b/src/gromacs/domdec/domdec_setup.h @@ -55,11 +55,12 @@ namespace gmx { struct DomdecOptions; class MDLogger; -template class ArrayRef; -} // namespace +template +class ArrayRef; +} // namespace gmx /*! \brief Returns the volume fraction of the system that is communicated */ -real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox); +real comm_box_frac(const gmx::IVec& dd_nc, real cutoff, const gmx_ddbox_t& ddbox); /*! \internal * \brief Describes the DD grid setup @@ -70,13 +71,13 @@ real comm_box_frac(const gmx::IVec &dd_nc, real cutoff, const gmx_ddbox_t &ddbox struct DDGridSetup { //! The number of separate PME ranks, 0 if none or all ranks do PME - int numPmeOnlyRanks = 0; + int numPmeOnlyRanks = 0; //! The number of domains along each dimension - ivec numDomains = { 0, 0, 0 }; + ivec numDomains = { 0, 0, 0 }; //! The number of dimensions which we decompose in domains - int numDDDimensions = 0; + int numDDDimensions = 0; //! The domain decomposition dimensions, the first numDDDimensions entries are used - ivec ddDimensions = { -1, -1, -1 }; + ivec ddDimensions = { -1, -1, -1 }; }; /*! \brief Checks that requests for PP and PME ranks honor basic expectations @@ -84,19 +85,15 @@ struct DDGridSetup * Issues a fatal error if there are more PME ranks than PP, or if the * count of PP ranks has a prime factor that is too large to be likely * to have good performance. */ -void -checkForValidRankCountRequests(int numRanksRequested, - bool usingPme, - int numPmeRanksRequested); +void checkForValidRankCountRequests(int numRanksRequested, bool usingPme, int numPmeRanksRequested); /*! \brief Return the minimum cell size (in nm) required for DD */ -real -getDDGridSetupCellSizeLimit(const gmx::MDLogger &mdlog, - bool request1DAnd1Pulse, - bool bDynLoadBal, - real dlb_scale, - const t_inputrec &ir, - real systemInfoCellSizeLimit); +real getDDGridSetupCellSizeLimit(const gmx::MDLogger& mdlog, + bool request1DAnd1Pulse, + bool bDynLoadBal, + real dlb_scale, + const t_inputrec& ir, + real systemInfoCellSizeLimit); /*! \brief Determines the DD grid setup * @@ -104,18 +101,17 @@ getDDGridSetupCellSizeLimit(const gmx::MDLogger &mdlog, * chooses estimated optimal number of separate PME ranks and DD grid * cell setup, DD cell size limits, and the initial ddbox. */ -DDGridSetup -getDDGridSetup(const gmx::MDLogger &mdlog, - const t_commrec *cr, - int numRanksRequested, - const gmx::DomdecOptions &options, - const DDSettings &ddSettings, - const DDSystemInfo &systemInfo, - real cellSizeLimit, - const gmx_mtop_t &mtop, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef xGlobal, - gmx_ddbox_t *ddbox); +DDGridSetup getDDGridSetup(const gmx::MDLogger& mdlog, + const t_commrec* cr, + int numRanksRequested, + const gmx::DomdecOptions& options, + const DDSettings& ddSettings, + const DDSystemInfo& systemInfo, + real cellSizeLimit, + const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef xGlobal, + gmx_ddbox_t* ddbox); #endif diff --git a/src/gromacs/domdec/domdec_specatomcomm.cpp b/src/gromacs/domdec/domdec_specatomcomm.cpp index 91e50f7240..04faddad43 100644 --- a/src/gromacs/domdec/domdec_specatomcomm.cpp +++ b/src/gromacs/domdec/domdec_specatomcomm.cpp @@ -63,11 +63,10 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxassert.h" -void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, - rvec *f, rvec *fshift) +void dd_move_f_specat(gmx_domdec_t* dd, gmx_domdec_specat_comm_t* spac, rvec* f, rvec* fshift) { - gmx_specatsend_t *spas; - rvec *vbuf; + gmx_specatsend_t* spas; + rvec* vbuf; int n, n0, n1, dim, dir; ivec vis; int is; @@ -83,17 +82,14 @@ void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, spas = spac->spas[d]; n0 = spas[0].nrecv; n1 = spas[1].nrecv; - n -= n1 + n0; + n -= n1 + n0; vbuf = as_rvec_array(spac->vbuf.data()); /* Send and receive the coordinates */ - dd_sendrecv2_rvec(dd, d, - f + n + n1, n0, vbuf, spas[0].a.size(), - f + n, n1, vbuf + spas[0].a.size(), - spas[1].a.size()); + dd_sendrecv2_rvec(dd, d, f + n + n1, n0, vbuf, spas[0].a.size(), f + n, n1, + vbuf + spas[0].a.size(), spas[1].a.size()); for (dir = 0; dir < 2; dir++) { - bPBC = ((dir == 0 && dd->ci[dim] == 0) || - (dir == 1 && dd->ci[dim] == dd->nc[dim]-1)); + bPBC = ((dir == 0 && dd->ci[dim] == 0) || (dir == 1 && dd->ci[dim] == dd->nc[dim] - 1)); bScrew = (bPBC && dd->unitCellInfo.haveScrewPBC && dim == XX); spas = &spac->spas[d][dir]; @@ -143,15 +139,13 @@ void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, { /* Two cells, so we only need to communicate one way */ spas = &spac->spas[d][0]; - n -= spas->nrecv; + n -= spas->nrecv; /* Send and receive the coordinates */ - ddSendrecv(dd, d, dddirForward, - f + n, spas->nrecv, - as_rvec_array(spac->vbuf.data()), spas->a.size()); + ddSendrecv(dd, d, dddirForward, f + n, spas->nrecv, as_rvec_array(spac->vbuf.data()), + spas->a.size()); /* Sum the buffer into the required forces */ - if (dd->unitCellInfo.haveScrewPBC && dim == XX && - (dd->ci[dim] == 0 || - dd->ci[dim] == dd->nc[dim]-1)) + if (dd->unitCellInfo.haveScrewPBC && dim == XX + && (dd->ci[dim] == 0 || dd->ci[dim] == dd->nc[dim] - 1)) { int i = 0; for (int a : spas->a) @@ -176,15 +170,12 @@ void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, } } -void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, - const matrix box, - rvec *x0, - rvec *x1, gmx_bool bX1IsCoord) +void dd_move_x_specat(gmx_domdec_t* dd, gmx_domdec_specat_comm_t* spac, const matrix box, rvec* x0, rvec* x1, gmx_bool bX1IsCoord) { - gmx_specatsend_t *spas; + gmx_specatsend_t* spas; int nvec, v, n, nn, ns0, ns1, nr0, nr1, nr, d, dim, dir, i; gmx_bool bPBC, bScrew = FALSE; - rvec shift = {0, 0, 0}; + rvec shift = { 0, 0, 0 }; nvec = 1; if (x1 != nullptr) @@ -199,7 +190,7 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, if (dd->nc[dim] > 2) { /* Pulse the grid forward and backward */ - rvec *vbuf = as_rvec_array(spac->vbuf.data()); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); for (dir = 0; dir < 2; dir++) { if (dir == 0 && dd->ci[dim] == 0) @@ -208,7 +199,7 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, bScrew = (dd->unitCellInfo.haveScrewPBC && dim == XX); copy_rvec(box[dim], shift); } - else if (dir == 1 && dd->ci[dim] == dd->nc[dim]-1) + else if (dir == 1 && dd->ci[dim] == dd->nc[dim] - 1) { bPBC = TRUE; bScrew = (dd->unitCellInfo.haveScrewPBC && dim == XX); @@ -225,7 +216,7 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, spas = &spac->spas[d][dir]; for (v = 0; v < nvec; v++) { - rvec *x = (v == 0 ? x0 : x1); + rvec* x = (v == 0 ? x0 : x1); /* Copy the required coordinates to the send buffer */ if (!bPBC || (v == 1 && !bX1IsCoord)) { @@ -250,7 +241,7 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, /* Shift and rotate coordinates */ for (int a : spas->a) { - (*vbuf)[XX] = x[a][XX] + shift[XX]; + (*vbuf)[XX] = x[a][XX] + shift[XX]; (*vbuf)[YY] = box[YY][YY] - x[a][YY] + shift[YY]; (*vbuf)[ZZ] = box[ZZ][ZZ] - x[a][ZZ] + shift[ZZ]; vbuf++; @@ -266,19 +257,16 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, nr1 = spas[1].nrecv; if (nvec == 1) { - rvec *vbuf = as_rvec_array(spac->vbuf.data()); - dd_sendrecv2_rvec(dd, d, - vbuf + ns0, ns1, x0 + n, nr1, - vbuf, ns0, x0 + n + nr1, nr0); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); + dd_sendrecv2_rvec(dd, d, vbuf + ns0, ns1, x0 + n, nr1, vbuf, ns0, x0 + n + nr1, nr0); } else { - rvec *vbuf = as_rvec_array(spac->vbuf.data()); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); /* Communicate both vectors in one buffer */ - rvec *rbuf = as_rvec_array(spac->vbuf2.data()); - dd_sendrecv2_rvec(dd, d, - vbuf + 2*ns0, 2*ns1, rbuf, 2*nr1, - vbuf, 2*ns0, rbuf + 2*nr1, 2*nr0); + rvec* rbuf = as_rvec_array(spac->vbuf2.data()); + dd_sendrecv2_rvec(dd, d, vbuf + 2 * ns0, 2 * ns1, rbuf, 2 * nr1, vbuf, 2 * ns0, + rbuf + 2 * nr1, 2 * nr0); /* Split the buffer into the two vectors */ nn = n; for (dir = 1; dir >= 0; dir--) @@ -286,10 +274,10 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, nr = spas[dir].nrecv; for (v = 0; v < 2; v++) { - rvec *x = (v == 0 ? x0 : x1); + rvec* x = (v == 0 ? x0 : x1); for (i = 0; i < nr; i++) { - copy_rvec(*rbuf, x[nn+i]); + copy_rvec(*rbuf, x[nn + i]); rbuf++; } } @@ -302,19 +290,19 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, { spas = &spac->spas[d][0]; /* Copy the required coordinates to the send buffer */ - rvec *vbuf = as_rvec_array(spac->vbuf.data()); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); for (v = 0; v < nvec; v++) { - rvec *x = (v == 0 ? x0 : x1); - if (dd->unitCellInfo.haveScrewPBC && dim == XX && - (dd->ci[XX] == 0 || dd->ci[XX] == dd->nc[XX]-1)) + rvec* x = (v == 0 ? x0 : x1); + if (dd->unitCellInfo.haveScrewPBC && dim == XX + && (dd->ci[XX] == 0 || dd->ci[XX] == dd->nc[XX] - 1)) { /* Here we only perform the rotation, the rest of the pbc * is handled in the constraint or viste routines. */ for (int a : spas->a) { - (*vbuf)[XX] = x[a][XX]; + (*vbuf)[XX] = x[a][XX]; (*vbuf)[YY] = box[YY][YY] - x[a][YY]; (*vbuf)[ZZ] = box[ZZ][ZZ] - x[a][ZZ]; vbuf++; @@ -332,25 +320,23 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, /* Send and receive the coordinates */ if (nvec == 1) { - rvec *vbuf = as_rvec_array(spac->vbuf.data()); - ddSendrecv(dd, d, dddirBackward, - vbuf, spas->a.size(), x0 + n, spas->nrecv); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); + ddSendrecv(dd, d, dddirBackward, vbuf, spas->a.size(), x0 + n, spas->nrecv); } else { - rvec *vbuf = as_rvec_array(spac->vbuf.data()); + rvec* vbuf = as_rvec_array(spac->vbuf.data()); /* Communicate both vectors in one buffer */ - rvec *rbuf = as_rvec_array(spac->vbuf2.data()); - ddSendrecv(dd, d, dddirBackward, - vbuf, 2*spas->a.size(), rbuf, 2*spas->nrecv); + rvec* rbuf = as_rvec_array(spac->vbuf2.data()); + ddSendrecv(dd, d, dddirBackward, vbuf, 2 * spas->a.size(), rbuf, 2 * spas->nrecv); /* Split the buffer into the two vectors */ nr = spas[0].nrecv; for (v = 0; v < 2; v++) { - rvec *x = (v == 0 ? x0 : x1); + rvec* x = (v == 0 ? x0 : x1); for (i = 0; i < nr; i++) { - copy_rvec(*rbuf, x[n+i]); + copy_rvec(*rbuf, x[n + i]); rbuf++; } } @@ -360,20 +346,20 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, } } -int setup_specat_communication(gmx_domdec_t *dd, - std::vector *ireq, - gmx_domdec_specat_comm_t *spac, - gmx::HashedMap *ga2la_specat, - int at_start, - int vbuf_fac, - const char *specat_type, - const char *add_err) +int setup_specat_communication(gmx_domdec_t* dd, + std::vector* ireq, + gmx_domdec_specat_comm_t* spac, + gmx::HashedMap* ga2la_specat, + int at_start, + int vbuf_fac, + const char* specat_type, + const char* add_err) { - int nsend[2], nlast, nsend_zero[2] = {0, 0}, *nsend_ptr; + int nsend[2], nlast, nsend_zero[2] = { 0, 0 }, *nsend_ptr; int dim, ndir, nr, ns, nrecv_local, n0, start, buf[2]; int nat_tot_specat, nat_tot_prev; gmx_bool bPBC; - gmx_specatsend_t *spas; + gmx_specatsend_t* spas; if (debug) { @@ -388,7 +374,7 @@ int setup_specat_communication(gmx_domdec_t *dd, nsend[0] = ireq->size(); nsend[1] = nsend[0]; nlast = nsend[1]; - for (int d = dd->ndim-1; d >= 0; d--) + for (int d = dd->ndim - 1; d >= 0; d--) { /* Pulse the grid forward and backward */ dim = dd->dim[d]; @@ -404,10 +390,8 @@ int setup_specat_communication(gmx_domdec_t *dd, } for (int dir = 0; dir < ndir; dir++) { - if (!bPBC && - dd->nc[dim] > 2 && - ((dir == 0 && dd->ci[dim] == dd->nc[dim] - 1) || - (dir == 1 && dd->ci[dim] == 0))) + if (!bPBC && dd->nc[dim] > 2 + && ((dir == 0 && dd->ci[dim] == dd->nc[dim] - 1) || (dir == 1 && dd->ci[dim] == 0))) { /* No pbc: the fist/last cell should not request atoms */ nsend_ptr = nsend_zero; @@ -417,13 +401,13 @@ int setup_specat_communication(gmx_domdec_t *dd, nsend_ptr = nsend; } /* Communicate the number of indices */ - ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, - nsend_ptr, 2, spac->nreq[d][dir], 2); + ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, nsend_ptr, 2, + spac->nreq[d][dir], 2); nr = spac->nreq[d][dir][1]; ireq->resize(nlast + nr); /* Communicate the indices */ - ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, - ireq->data(), nsend_ptr[1], ireq->data() + nlast, nr); + ddSendrecv(dd, d, dir == 0 ? dddirForward : dddirBackward, ireq->data(), nsend_ptr[1], + ireq->data() + nlast, nr); nlast += nr; } nsend[1] = nlast; @@ -461,26 +445,25 @@ int setup_specat_communication(gmx_domdec_t *dd, nr = spac->nreq[d][dir][1]; if (debug) { - fprintf(debug, "dim=%d, dir=%d, searching for %d atoms\n", - d, dir, nr); + fprintf(debug, "dim=%d, dir=%d, searching for %d atoms\n", d, dir, nr); } - start = nlast - nr; + start = nlast - nr; spas->a.clear(); spac->ibuf.clear(); - nsend[0] = 0; + nsend[0] = 0; for (int i = 0; i < nr; i++) { const int indr = (*ireq)[start + i]; int ind; /* Check if this is a home atom and if so ind will be set */ - if (const int *homeIndex = dd->ga2la->findHome(indr)) + if (const int* homeIndex = dd->ga2la->findHome(indr)) { ind = *homeIndex; } else { /* Search in the communicated atoms */ - if (const int *a = ga2la_specat->find(indr)) + if (const int* a = ga2la_specat->find(indr)) { ind = *a; } @@ -515,14 +498,14 @@ int setup_specat_communication(gmx_domdec_t *dd, } /* Send and receive the number of indices to communicate */ nsend[1] = spas->a.size(); - ddSendrecv(dd, d, dir == 0 ? dddirBackward : dddirForward, - nsend, 2, buf, 2); + ddSendrecv(dd, d, dir == 0 ? dddirBackward : dddirForward, nsend, 2, buf, 2); if (debug) { - fprintf(debug, "Send to rank %d, %d (%d) indices, " + fprintf(debug, + "Send to rank %d, %d (%d) indices, " "receive from rank %d, %d (%d) indices\n", - dd->neighbor[d][1-dir], nsend[1], nsend[0], - dd->neighbor[d][dir], buf[1], buf[0]); + dd->neighbor[d][1 - dir], nsend[1], nsend[0], dd->neighbor[d][dir], buf[1], + buf[0]); if (gmx_debug_at) { for (int i : spac->ibuf) @@ -533,12 +516,11 @@ int setup_specat_communication(gmx_domdec_t *dd, } } nrecv_local += buf[0]; - spas->nrecv = buf[1]; + spas->nrecv = buf[1]; dd->globalAtomIndices.resize(nat_tot_specat + spas->nrecv); /* Send and receive the indices */ - ddSendrecv(dd, d, dir == 0 ? dddirBackward : dddirForward, - spac->ibuf.data(), spac->ibuf.size(), - dd->globalAtomIndices.data() + nat_tot_specat, spas->nrecv); + ddSendrecv(dd, d, dir == 0 ? dddirBackward : dddirForward, spac->ibuf.data(), + spac->ibuf.size(), dd->globalAtomIndices.data() + nat_tot_specat, spas->nrecv); nat_tot_specat += spas->nrecv; } @@ -550,13 +532,13 @@ int setup_specat_communication(gmx_domdec_t *dd, ns += spac->spas[d][1].a.size(); nr += spac->spas[d][1].nrecv; } - if (vbuf_fac*ns > gmx::index(spac->vbuf.size())) + if (vbuf_fac * ns > gmx::index(spac->vbuf.size())) { - spac->vbuf.resize(vbuf_fac*ns); + spac->vbuf.resize(vbuf_fac * ns); } - if (vbuf_fac == 2 && vbuf_fac*nr > gmx::index(spac->vbuf2.size())) + if (vbuf_fac == 2 && vbuf_fac * nr > gmx::index(spac->vbuf2.size())) { - spac->vbuf2.resize(vbuf_fac*nr); + spac->vbuf2.resize(vbuf_fac * nr); } /* Make a global to local index for the communication atoms */ @@ -571,22 +553,20 @@ int setup_specat_communication(gmx_domdec_t *dd, { if (debug) { - fprintf(debug, "Requested %d, received %d (tot recv %d)\n", - numRequested, nrecv_local, nat_tot_specat - at_start); + fprintf(debug, "Requested %d, received %d (tot recv %d)\n", numRequested, nrecv_local, + nat_tot_specat - at_start); if (gmx_debug_at) { for (int i = 0; i < numRequested; i++) { - const int *ind = ga2la_specat->find((*ireq)[i]); - fprintf(debug, " %s%d", - ind ? "" : "!", - (*ireq)[i] + 1); + const int* ind = ga2la_specat->find((*ireq)[i]); + fprintf(debug, " %s%d", ind ? "" : "!", (*ireq)[i] + 1); } fprintf(debug, "\n"); } } - fprintf(stderr, "\nDD cell %d %d %d: Neighboring cells do not have atoms:", - dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); + fprintf(stderr, "\nDD cell %d %d %d: Neighboring cells do not have atoms:", dd->ci[XX], + dd->ci[YY], dd->ci[ZZ]); for (int i = 0; i < numRequested; i++) { if (!ga2la_specat->find((*ireq)[i])) @@ -595,11 +575,13 @@ int setup_specat_communication(gmx_domdec_t *dd, } } fprintf(stderr, "\n"); - gmx_fatal(FARGS, "DD cell %d %d %d could only obtain %d of the %d atoms that are connected via %ss from the neighboring cells. This probably means your %s lengths are too long compared to the domain decomposition cell size. Decrease the number of domain decomposition grid cells%s%s.", - dd->ci[XX], dd->ci[YY], dd->ci[ZZ], - nrecv_local, numRequested, specat_type, - specat_type, add_err, - dd_dlb_is_on(dd) ? " or use the -rcon option of mdrun" : ""); + gmx_fatal(FARGS, + "DD cell %d %d %d could only obtain %d of the %d atoms that are connected via " + "%ss from the neighboring cells. This probably means your %s lengths are too " + "long compared to the domain decomposition cell size. Decrease the number of " + "domain decomposition grid cells%s%s.", + dd->ci[XX], dd->ci[YY], dd->ci[ZZ], nrecv_local, numRequested, specat_type, + specat_type, add_err, dd_dlb_is_on(dd) ? " or use the -rcon option of mdrun" : ""); } spac->at_start = at_start; diff --git a/src/gromacs/domdec/domdec_specatomcomm.h b/src/gromacs/domdec/domdec_specatomcomm.h index ca6af16d07..a051190d75 100644 --- a/src/gromacs/domdec/domdec_specatomcomm.h +++ b/src/gromacs/domdec/domdec_specatomcomm.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,8 +54,9 @@ struct t_commrec; namespace gmx { -template class HashedMap; -} // namespace +template +class HashedMap; +} // namespace gmx /*! \internal \brief The communication setup along a single dimension */ struct gmx_specatsend_t @@ -68,23 +69,22 @@ struct gmx_specatsend_t struct gmx_domdec_specat_comm_t { /* The number of indices to receive during the setup */ - int nreq[DIM][2][2] = {{{0}}}; /**< The nr. of atoms requested, per DIM, direction and direct/indirect */ + int nreq[DIM][2][2] = { { { 0 } } }; /**< The nr. of atoms requested, per DIM, direction and direct/indirect */ /* The atoms to send */ - gmx_specatsend_t spas[DIM][2]; /**< The communication setup per DIM, direction */ - std::vector sendAtom; /**< Work buffer that tells if spec.atoms should be sent */ + gmx_specatsend_t spas[DIM][2]; /**< The communication setup per DIM, direction */ + std::vector sendAtom; /**< Work buffer that tells if spec.atoms should be sent */ /* Send buffers */ - std::vector ibuf; /**< Integer send buffer */ - std::vector vbuf; /**< rvec send buffer */ - std::vector vbuf2; /**< rvec send buffer */ + std::vector ibuf; /**< Integer send buffer */ + std::vector vbuf; /**< rvec send buffer */ + std::vector vbuf2; /**< rvec send buffer */ /* The range in the local buffer(s) for received atoms */ - int at_start; /**< Start index of received atoms */ - int at_end; /**< End index of received atoms */ + int at_start; /**< Start index of received atoms */ + int at_end; /**< End index of received atoms */ }; /*! \brief Communicates the force for special atoms, the shift forces are reduced with \p fshift != NULL */ -void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, - rvec *f, rvec *fshift); +void dd_move_f_specat(gmx_domdec_t* dd, gmx_domdec_specat_comm_t* spac, rvec* f, rvec* fshift); /*! \brief Communicates the coordinates for special atoms * @@ -95,10 +95,12 @@ void dd_move_f_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, * \param[in,out] x1 Vector to communicate, when != NULL * \param[in] bX1IsCoord Tells is \p x1 is a coordinate vector (needs pbc) */ -void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, - const matrix box, - rvec *x0, - rvec *x1, gmx_bool bX1IsCoord); +void dd_move_x_specat(gmx_domdec_t* dd, + gmx_domdec_specat_comm_t* spac, + const matrix box, + rvec* x0, + rvec* x1, + gmx_bool bX1IsCoord); /*! \brief Sets up the communication for special atoms * @@ -111,13 +113,13 @@ void dd_move_x_specat(gmx_domdec_t *dd, gmx_domdec_specat_comm_t *spac, * \param[in] specat_type Name of the special atom, used for error message * \param[in] add_err Text to add at the end of error message when atoms can't be found */ -int setup_specat_communication(gmx_domdec_t *dd, - std::vector *ireq, - gmx_domdec_specat_comm_t *spac, - gmx::HashedMap *ga2la_specat, - int at_start, - int vbuf_fac, - const char *specat_type, - const char *add_err); +int setup_specat_communication(gmx_domdec_t* dd, + std::vector* ireq, + gmx_domdec_specat_comm_t* spac, + gmx::HashedMap* ga2la_specat, + int at_start, + int vbuf_fac, + const char* specat_type, + const char* add_err); #endif diff --git a/src/gromacs/domdec/domdec_struct.h b/src/gromacs/domdec/domdec_struct.h index c2be7bc66e..55a6a3e969 100644 --- a/src/gromacs/domdec/domdec_struct.h +++ b/src/gromacs/domdec/domdec_struct.h @@ -59,7 +59,7 @@ #include "gromacs/utility/real.h" //! Max number of zones in domain decomposition -#define DD_MAXZONE 8 +#define DD_MAXZONE 8 //! Max number of izones in domain decomposition #define DD_MAXIZONE 4 @@ -74,10 +74,11 @@ struct t_inputrec; namespace gmx { -template class HashedMap; +template +class HashedMap; class LocalAtomSetManager; class GpuHaloExchange; -} +} // namespace gmx /*! \internal * \brief Pair interaction zone and atom range for an i-zone @@ -85,7 +86,7 @@ class GpuHaloExchange; struct DDPairInteractionRanges { //! The index of this i-zone in the i-zone list - int iZoneIndex = -1; + int iZoneIndex = -1; //! The range of j-zones gmx::Range jZoneRange; //! The i-atom range @@ -93,38 +94,41 @@ struct DDPairInteractionRanges //! The j-atom range gmx::Range jAtomRange; //! Minimum shifts to consider - ivec shift0 = { }; + ivec shift0 = {}; //! Maximum shifts to consider - ivec shift1 = { }; + ivec shift1 = {}; }; -typedef struct { +typedef struct +{ /* Zone lower corner in triclinic coordinates */ - rvec x0 = { }; + rvec x0 = {}; /* Zone upper corner in triclinic coordinates */ - rvec x1 = { }; + rvec x1 = {}; /* Zone bounding box lower corner in Cartesian coords */ - rvec bb_x0 = { }; + rvec bb_x0 = {}; /* Zone bounding box upper corner in Cartesian coords */ - rvec bb_x1 = { }; + rvec bb_x1 = {}; } gmx_domdec_zone_size_t; -struct gmx_domdec_zones_t { +struct gmx_domdec_zones_t +{ /* The number of zones including the home zone */ - int n = 0; + int n = 0; /* The shift of the zones with respect to the home zone */ - ivec shift[DD_MAXZONE] = { }; + ivec shift[DD_MAXZONE] = {}; /* The charge group boundaries for the zones */ - int cg_range[DD_MAXZONE+1] = { }; + int cg_range[DD_MAXZONE + 1] = {}; /* The pair interaction zone and atom ranges per each i-zone */ std::vector iZones; /* Boundaries of the zones */ - gmx_domdec_zone_size_t size[DD_MAXZONE]; + gmx_domdec_zone_size_t size[DD_MAXZONE]; /* The cg density of the home zone */ - real dens_zone0 = 0; + real dens_zone0 = 0; }; -struct gmx_ddbox_t { +struct gmx_ddbox_t +{ int npbcdim; int nboundeddim; rvec box0; @@ -142,90 +146,91 @@ struct gmx_ddbox_t { struct UnitCellInfo { //! Constructor - UnitCellInfo(const t_inputrec &ir); + UnitCellInfo(const t_inputrec& ir); //! We have PBC from dim 0 (X) up to npbcdim - int npbcdim; + int npbcdim; //! The system is bounded from 0 (X) to numBoundedDimensions - int numBoundedDimensions; + int numBoundedDimensions; //! Tells whether the box bounding the atoms is dynamic bool ddBoxIsDynamic; //! Screw PBC? bool haveScrewPBC; }; -struct gmx_domdec_t { //NOLINT(clang-analyzer-optin.performance.Padding) +struct gmx_domdec_t +{ //NOLINT(clang-analyzer-optin.performance.Padding) //! Constructor, only partial for now - gmx_domdec_t(const t_inputrec &ir); + gmx_domdec_t(const t_inputrec& ir); /* The DD particle-particle nodes only */ /* The communication setup within the communicator all * defined in dd->comm in domdec.c */ - int nnodes = 0; - MPI_Comm mpi_comm_all = MPI_COMM_NULL; + int nnodes = 0; + MPI_Comm mpi_comm_all = MPI_COMM_NULL; /* The local DD cell index and rank */ - ivec ci = { 0, 0, 0 }; - int rank = 0; - ivec master_ci = { 0, 0, 0 }; - int masterrank = 0; + ivec ci = { 0, 0, 0 }; + int rank = 0; + ivec master_ci = { 0, 0, 0 }; + int masterrank = 0; /* Communication with the PME only nodes */ - int pme_nodeid = 0; - gmx_bool pme_receive_vir_ener = false; - gmx_pme_comm_n_box_t *cnb = nullptr; - int nreq_pme = 0; - MPI_Request req_pme[8]; + int pme_nodeid = 0; + gmx_bool pme_receive_vir_ener = false; + gmx_pme_comm_n_box_t* cnb = nullptr; + int nreq_pme = 0; + MPI_Request req_pme[8]; /* Properties of the unit cell */ UnitCellInfo unitCellInfo; /* The communication setup, identical for each cell, cartesian index */ - ivec nc = { 0, 0, 0 }; - int ndim = 0; - ivec dim = { 0, 0, 0 }; /* indexed by 0 to ndim */ + ivec nc = { 0, 0, 0 }; + int ndim = 0; + ivec dim = { 0, 0, 0 }; /* indexed by 0 to ndim */ /* Forward and backward neighboring cells, indexed by 0 to ndim */ - int neighbor[DIM][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 } }; + int neighbor[DIM][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 } }; /* Only available on the master node */ std::unique_ptr ma; /* Global atom number to interaction list */ - gmx_reverse_top_t *reverse_top = nullptr; - int nbonded_global = 0; - int nbonded_local = 0; + gmx_reverse_top_t* reverse_top = nullptr; + int nbonded_global = 0; + int nbonded_local = 0; /* Whether we have non-self exclusion */ bool haveExclusions = false; /* Vsite stuff */ - gmx::HashedMap *ga2la_vsite = nullptr; - gmx_domdec_specat_comm_t *vsite_comm = nullptr; - std::vector vsite_requestedGlobalAtomIndices; + gmx::HashedMap* ga2la_vsite = nullptr; + gmx_domdec_specat_comm_t* vsite_comm = nullptr; + std::vector vsite_requestedGlobalAtomIndices; /* Constraint stuff */ - gmx_domdec_constraints_t *constraints = nullptr; - gmx_domdec_specat_comm_t *constraint_comm = nullptr; + gmx_domdec_constraints_t* constraints = nullptr; + gmx_domdec_specat_comm_t* constraint_comm = nullptr; /* The number of home atom groups */ - int ncg_home = 0; + int ncg_home = 0; /* Global atom group indices for the home and all non-home groups */ - std::vector globalAtomGroupIndices; + std::vector globalAtomGroupIndices; /* Index from the local atoms to the global atoms, covers home and received zones */ std::vector globalAtomIndices; /* Global atom number to local atom number list */ - gmx_ga2la_t *ga2la = nullptr; + gmx_ga2la_t* ga2la = nullptr; /* Communication stuff */ - gmx_domdec_comm_t *comm = nullptr; + gmx_domdec_comm_t* comm = nullptr; /* The partioning count, to keep track of the state */ int64_t ddp_count = 0; /* The managed atom sets that are updated in domain decomposition */ - gmx::LocalAtomSetManager * atomSets = nullptr; + gmx::LocalAtomSetManager* atomSets = nullptr; /* gmx_pme_recv_f buffer */ std::vector pmeForceReceiveBuffer; @@ -235,13 +240,13 @@ struct gmx_domdec_t { //NOLINT(clang-analyzer-optin.performance.Padding) }; //! Are we the master node for domain decomposition -static inline bool DDMASTER(const gmx_domdec_t &dd) +static inline bool DDMASTER(const gmx_domdec_t& dd) { return dd.rank == dd.masterrank; }; //! Are we the master node for domain decomposition, deprecated -static inline bool DDMASTER(const gmx_domdec_t *dd) +static inline bool DDMASTER(const gmx_domdec_t* dd) { return dd->rank == dd->masterrank; }; diff --git a/src/gromacs/domdec/domdec_topology.cpp b/src/gromacs/domdec/domdec_topology.cpp index 3df773af05..a426057672 100644 --- a/src/gromacs/domdec/domdec_topology.cpp +++ b/src/gromacs/domdec/domdec_topology.cpp @@ -99,10 +99,10 @@ struct reverse_ilist_t struct MolblockIndices { - int a_start; - int a_end; - int natoms_mol; - int type; + int a_start; + int a_end; + int natoms_mol; + int type; }; /*! \brief Struct for thread local work data for local topology generation */ @@ -120,28 +120,28 @@ struct gmx_reverse_top_t { //! @cond Doxygen_Suppress //! \brief The maximum number of exclusions one atom can have - int n_excl_at_max = 0; + int n_excl_at_max = 0; //! \brief Are there constraints in this revserse top? - bool bConstr = false; + bool bConstr = false; //! \brief Are there settles in this revserse top? - bool bSettle = false; + bool bSettle = false; //! \brief All bonded interactions have to be assigned? - bool bBCheck = false; + bool bBCheck = false; //! \brief Are there bondeds/exclusions between atoms? - bool bInterAtomicInteractions = false; + bool bInterAtomicInteractions = false; //! \brief Reverse ilist for all moltypes std::vector ril_mt; //! \brief The size of ril_mt[?].index summed over all entries - int ril_mt_tot_size = 0; + int ril_mt_tot_size = 0; //! \brief The sorting state of bondeds for free energy - int ilsort = ilsortUNKNOWN; + int ilsort = ilsortUNKNOWN; //! \brief molblock to global atom index for quick lookup of molblocks on atom index std::vector mbi; //! \brief Do we have intermolecular interactions? - bool bIntermolecularInteractions = false; + bool bIntermolecularInteractions = false; //! \brief Intermolecular reverse ilist - reverse_ilist_t ril_intermol; + reverse_ilist_t ril_intermol; /* Work data structures for multi-threading */ //! \brief Thread work array for local topology generation @@ -167,31 +167,30 @@ static int nral_rt(int ftype) } /*! \brief Return whether interactions of type \p ftype need to be assigned exactly once */ -static gmx_bool dd_check_ftype(int ftype, gmx_bool bBCheck, - gmx_bool bConstr, gmx_bool bSettle) +static gmx_bool dd_check_ftype(int ftype, gmx_bool bBCheck, gmx_bool bConstr, gmx_bool bSettle) { - return ((((interaction_function[ftype].flags & IF_BOND) != 0U) && - ((interaction_function[ftype].flags & IF_VSITE) == 0U) && - (bBCheck || ((interaction_function[ftype].flags & IF_LIMZERO) == 0U))) || - (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) || - (bSettle && ftype == F_SETTLE)); + return ((((interaction_function[ftype].flags & IF_BOND) != 0U) + && ((interaction_function[ftype].flags & IF_VSITE) == 0U) + && (bBCheck || ((interaction_function[ftype].flags & IF_LIMZERO) == 0U))) + || (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) || (bSettle && ftype == F_SETTLE)); } /*! \brief Help print error output when interactions are missing */ -static std::string -print_missing_interactions_mb(t_commrec *cr, - const gmx_reverse_top_t *rt, - const char *moltypename, - const reverse_ilist_t *ril, - int a_start, int a_end, - int nat_mol, int nmol, - const t_idef *idef) +static std::string print_missing_interactions_mb(t_commrec* cr, + const gmx_reverse_top_t* rt, + const char* moltypename, + const reverse_ilist_t* ril, + int a_start, + int a_end, + int nat_mol, + int nmol, + const t_idef* idef) { - int *assigned; - int nril_mol = ril->index[nat_mol]; - snew(assigned, nmol*nril_mol); - gmx::StringOutputStream stream; - gmx::TextWriter log(&stream); + int* assigned; + int nril_mol = ril->index[nat_mol]; + snew(assigned, nmol * nril_mol); + gmx::StringOutputStream stream; + gmx::TextWriter log(&stream); gmx::ArrayRef gatindex = cr->dd->globalAtomIndices; for (int ftype = 0; ftype < F_NRE; ftype++) @@ -199,9 +198,9 @@ print_missing_interactions_mb(t_commrec *cr, if (dd_check_ftype(ftype, rt->bBCheck, rt->bConstr, rt->bSettle)) { int nral = NRAL(ftype); - const t_ilist *il = &idef->il[ftype]; - const t_iatom *ia = il->iatoms; - for (int i = 0; i < il->nr; i += 1+nral) + const t_ilist* il = &idef->il[ftype]; + const t_iatom* ia = il->iatoms; + for (int i = 0; i < il->nr; i += 1 + nral) { int a0 = gatindex[ia[1]]; /* Check if this interaction is in @@ -209,27 +208,25 @@ print_missing_interactions_mb(t_commrec *cr, */ if (a0 >= a_start && a0 < a_end) { - int mol = (a0 - a_start)/nat_mol; - int a0_mol = (a0 - a_start) - mol*nat_mol; + int mol = (a0 - a_start) / nat_mol; + int a0_mol = (a0 - a_start) - mol * nat_mol; int j_mol = ril->index[a0_mol]; bool found = false; - while (j_mol < ril->index[a0_mol+1] && !found) + while (j_mol < ril->index[a0_mol + 1] && !found) { - int j = mol*nril_mol + j_mol; + int j = mol * nril_mol + j_mol; int ftype_j = ril->il[j_mol]; /* Here we need to check if this interaction has * not already been assigned, since we could have * multiply defined interactions. */ - if (ftype == ftype_j && ia[0] == ril->il[j_mol+1] && - assigned[j] == 0) + if (ftype == ftype_j && ia[0] == ril->il[j_mol + 1] && assigned[j] == 0) { /* Check the atoms */ found = true; for (int a = 0; a < nral; a++) { - if (gatindex[ia[1+a]] != - a_start + mol*nat_mol + ril->il[j_mol+2+a]) + if (gatindex[ia[1 + a]] != a_start + mol * nat_mol + ril->il[j_mol + 2 + a]) { found = false; } @@ -251,7 +248,7 @@ print_missing_interactions_mb(t_commrec *cr, } } - gmx_sumi(nmol*nril_mol, assigned, cr); + gmx_sumi(nmol * nril_mol, assigned, cr); int nprint = 10; int i = 0; @@ -262,9 +259,8 @@ print_missing_interactions_mb(t_commrec *cr, { int ftype = ril->il[j_mol]; int nral = NRAL(ftype); - int j = mol*nril_mol + j_mol; - if (assigned[j] == 0 && - !(interaction_function[ftype].flags & IF_VSITE)) + int j = mol * nril_mol + j_mol; + if (assigned[j] == 0 && !(interaction_function[ftype].flags & IF_VSITE)) { if (DDMASTER(cr->dd)) { @@ -274,12 +270,11 @@ print_missing_interactions_mb(t_commrec *cr, log.writeLineFormatted( "the first %d missing interactions, except for exclusions:", nprint); } - log.writeStringFormatted("%20s atoms", - interaction_function[ftype].longname); + log.writeStringFormatted("%20s atoms", interaction_function[ftype].longname); int a; for (a = 0; a < nral; a++) { - log.writeStringFormatted("%5d", ril->il[j_mol+2+a]+1); + log.writeStringFormatted("%5d", ril->il[j_mol + 2 + a] + 1); } while (a < 4) { @@ -289,8 +284,8 @@ print_missing_interactions_mb(t_commrec *cr, log.writeString(" global"); for (a = 0; a < nral; a++) { - log.writeStringFormatted("%6d", - a_start+mol*nat_mol+ril->il[j_mol+2+a]+1); + log.writeStringFormatted( + "%6d", a_start + mol * nat_mol + ril->il[j_mol + 2 + a] + 1); } log.ensureLineBreak(); } @@ -309,54 +304,53 @@ print_missing_interactions_mb(t_commrec *cr, } /*! \brief Help print error output when interactions are missing */ -static void print_missing_interactions_atoms(const gmx::MDLogger &mdlog, - t_commrec *cr, - const gmx_mtop_t *mtop, - const t_idef *idef) +static void print_missing_interactions_atoms(const gmx::MDLogger& mdlog, + t_commrec* cr, + const gmx_mtop_t* mtop, + const t_idef* idef) { - const gmx_reverse_top_t *rt = cr->dd->reverse_top; + const gmx_reverse_top_t* rt = cr->dd->reverse_top; /* Print the atoms in the missing interactions per molblock */ int a_end = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const gmx_moltype_t &moltype = mtop->moltype[molb.type]; - int a_start = a_end; - a_end = a_start + molb.nmol*moltype.atoms.nr; + const gmx_moltype_t& moltype = mtop->moltype[molb.type]; + int a_start = a_end; + a_end = a_start + molb.nmol * moltype.atoms.nr; - GMX_LOG(mdlog.warning).appendText( - print_missing_interactions_mb(cr, rt, - *(moltype.name), - &rt->ril_mt[molb.type], - a_start, a_end, moltype.atoms.nr, - molb.nmol, - idef)); + GMX_LOG(mdlog.warning) + .appendText(print_missing_interactions_mb(cr, rt, *(moltype.name), + &rt->ril_mt[molb.type], a_start, a_end, + moltype.atoms.nr, molb.nmol, idef)); } } -void dd_print_missing_interactions(const gmx::MDLogger &mdlog, - t_commrec *cr, +void dd_print_missing_interactions(const gmx::MDLogger& mdlog, + t_commrec* cr, int local_count, - const gmx_mtop_t *top_global, - const gmx_localtop_t *top_local, - const rvec *x, + const gmx_mtop_t* top_global, + const gmx_localtop_t* top_local, + const rvec* x, const matrix box) { - int ndiff_tot, cl[F_NRE], n, ndiff, rest_global, rest_local; - int ftype, nral; - gmx_domdec_t *dd; + int ndiff_tot, cl[F_NRE], n, ndiff, rest_global, rest_local; + int ftype, nral; + gmx_domdec_t* dd; dd = cr->dd; - GMX_LOG(mdlog.warning).appendText( - "Not all bonded interactions have been properly assigned to the domain decomposition cells"); + GMX_LOG(mdlog.warning) + .appendText( + "Not all bonded interactions have been properly assigned to the domain " + "decomposition cells"); ndiff_tot = local_count - dd->nbonded_global; for (ftype = 0; ftype < F_NRE; ftype++) { nral = NRAL(ftype); - cl[ftype] = top_local->idef.il[ftype].nr/(1+nral); + cl[ftype] = top_local->idef.il[ftype].nr / (1 + nral); } gmx_sumi(F_NRE, cl, cr); @@ -372,13 +366,12 @@ void dd_print_missing_interactions(const gmx::MDLogger &mdlog, * into F_CONSTR. So in the if statement we skip F_CONSTRNC * and add these constraints when doing F_CONSTR. */ - if (((interaction_function[ftype].flags & IF_BOND) && - (dd->reverse_top->bBCheck - || !(interaction_function[ftype].flags & IF_LIMZERO))) + if (((interaction_function[ftype].flags & IF_BOND) + && (dd->reverse_top->bBCheck || !(interaction_function[ftype].flags & IF_LIMZERO))) || (dd->reverse_top->bConstr && ftype == F_CONSTR) || (dd->reverse_top->bSettle && ftype == F_SETTLE)) { - n = gmx_mtop_ftype_count(top_global, ftype); + n = gmx_mtop_ftype_count(top_global, ftype); if (ftype == F_CONSTR) { n += gmx_mtop_ftype_count(top_global, F_CONSTRNC); @@ -386,47 +379,49 @@ void dd_print_missing_interactions(const gmx::MDLogger &mdlog, ndiff = cl[ftype] - n; if (ndiff != 0) { - GMX_LOG(mdlog.warning).appendTextFormatted( - "%20s of %6d missing %6d", - interaction_function[ftype].longname, n, -ndiff); + GMX_LOG(mdlog.warning) + .appendTextFormatted("%20s of %6d missing %6d", + interaction_function[ftype].longname, n, -ndiff); } rest_global -= n; - rest_local -= cl[ftype]; + rest_local -= cl[ftype]; } } ndiff = rest_local - rest_global; if (ndiff != 0) { - GMX_LOG(mdlog.warning).appendTextFormatted( - "%20s of %6d missing %6d", "exclusions", - rest_global, -ndiff); + GMX_LOG(mdlog.warning).appendTextFormatted("%20s of %6d missing %6d", "exclusions", rest_global, -ndiff); } } print_missing_interactions_atoms(mdlog, cr, top_global, &top_local->idef); - write_dd_pdb("dd_dump_err", 0, "dump", top_global, cr, - -1, x, box); + write_dd_pdb("dd_dump_err", 0, "dump", top_global, cr, -1, x, box); std::string errorMessage; if (ndiff_tot > 0) { - errorMessage = "One or more interactions were assigned to multiple domains of the domain decompostion. Please report this bug."; + errorMessage = + "One or more interactions were assigned to multiple domains of the domain " + "decompostion. Please report this bug."; } else { - errorMessage = gmx::formatString("%d of the %d bonded interactions could not be calculated because some atoms involved moved further apart than the multi-body cut-off distance (%g nm) or the two-body cut-off distance (%g nm), see option -rdd, for pairs and tabulated bonds also see option -ddcheck", -ndiff_tot, cr->dd->nbonded_global, dd_cutoff_multibody(dd), dd_cutoff_twobody(dd)); + errorMessage = gmx::formatString( + "%d of the %d bonded interactions could not be calculated because some atoms " + "involved moved further apart than the multi-body cut-off distance (%g nm) or the " + "two-body cut-off distance (%g nm), see option -rdd, for pairs and tabulated bonds " + "also see option -ddcheck", + -ndiff_tot, cr->dd->nbonded_global, dd_cutoff_multibody(dd), dd_cutoff_twobody(dd)); } gmx_fatal_collective(FARGS, cr->mpi_comm_mygroup, MASTER(cr), "%s", errorMessage.c_str()); } /*! \brief Return global topology molecule information for global atom index \p i_gl */ -static void global_atomnr_to_moltype_ind(const gmx_reverse_top_t *rt, - int i_gl, - int *mb, int *mt, int *mol, int *i_mol) +static void global_atomnr_to_moltype_ind(const gmx_reverse_top_t* rt, int i_gl, int* mb, int* mt, int* mol, int* i_mol) { - const MolblockIndices *mbi = rt->mbi.data(); + const MolblockIndices* mbi = rt->mbi.data(); int start = 0; int end = rt->mbi.size(); /* exclusive */ int mid; @@ -434,10 +429,10 @@ static void global_atomnr_to_moltype_ind(const gmx_reverse_top_t *rt, /* binary search for molblock_ind */ while (TRUE) { - mid = (start+end)/2; + mid = (start + end) / 2; if (i_gl >= mbi[mid].a_end) { - start = mid+1; + start = mid + 1; } else if (i_gl < mbi[mid].a_start) { @@ -449,16 +444,16 @@ static void global_atomnr_to_moltype_ind(const gmx_reverse_top_t *rt, } } - *mb = mid; + *mb = mid; mbi += mid; *mt = mbi->type; *mol = (i_gl - mbi->a_start) / mbi->natoms_mol; - *i_mol = (i_gl - mbi->a_start) - (*mol)*mbi->natoms_mol; + *i_mol = (i_gl - mbi->a_start) - (*mol) * mbi->natoms_mol; } /*! \brief Returns the maximum number of exclusions per atom */ -static int getMaxNumExclusionsPerAtom(const t_blocka &excls) +static int getMaxNumExclusionsPerAtom(const t_blocka& excls) { int maxNumExcls = 0; for (int at = 0; at < excls.nr; at++) @@ -475,31 +470,31 @@ static int getMaxNumExclusionsPerAtom(const t_blocka &excls) } /*! \brief Run the reverse ilist generation and store it in r_il when \p bAssign = TRUE */ -static int low_make_reverse_ilist(const InteractionLists &il_mt, - const t_atom *atom, - int *count, - gmx_bool bConstr, gmx_bool bSettle, - gmx_bool bBCheck, +static int low_make_reverse_ilist(const InteractionLists& il_mt, + const t_atom* atom, + int* count, + gmx_bool bConstr, + gmx_bool bSettle, + gmx_bool bBCheck, gmx::ArrayRef r_index, gmx::ArrayRef r_il, - gmx_bool bLinkToAllAtoms, - gmx_bool bAssign) + gmx_bool bLinkToAllAtoms, + gmx_bool bAssign) { - int ftype, j, nlink, link; - int a; - int nint; + int ftype, j, nlink, link; + int a; + int nint; nint = 0; for (ftype = 0; ftype < F_NRE; ftype++) { - if ((interaction_function[ftype].flags & (IF_BOND | IF_VSITE)) || - (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) || - (bSettle && ftype == F_SETTLE)) + if ((interaction_function[ftype].flags & (IF_BOND | IF_VSITE)) + || (bConstr && (ftype == F_CONSTR || ftype == F_CONSTRNC)) || (bSettle && ftype == F_SETTLE)) { const bool bVSite = ((interaction_function[ftype].flags & IF_VSITE) != 0U); const int nral = NRAL(ftype); - const auto &il = il_mt[ftype]; - for (int i = 0; i < il.size(); i += 1+nral) + const auto& il = il_mt[ftype]; + for (int i = 0; i < il.size(); i += 1 + nral) { const int* ia = il.iatoms.data() + i; if (bLinkToAllAtoms) @@ -521,18 +516,17 @@ static int low_make_reverse_ilist(const InteractionLists &il_mt, } for (link = 0; link < nlink; link++) { - a = ia[1+link]; + a = ia[1 + link]; if (bAssign) { GMX_ASSERT(!r_il.empty(), "with bAssign not allowed to be empty"); GMX_ASSERT(!r_index.empty(), "with bAssign not allowed to be empty"); - r_il[r_index[a]+count[a]] = - (ftype == F_CONSTRNC ? F_CONSTR : ftype); - r_il[r_index[a]+count[a]+1] = ia[0]; - for (j = 1; j < 1+nral; j++) + r_il[r_index[a] + count[a]] = (ftype == F_CONSTRNC ? F_CONSTR : ftype); + r_il[r_index[a] + count[a] + 1] = ia[0]; + for (j = 1; j < 1 + nral; j++) { /* Store the molecular atom number */ - r_il[r_index[a]+count[a]+1+j] = ia[j]; + r_il[r_index[a] + count[a] + 1 + j] = ia[j]; } } if (interaction_function[ftype].flags & IF_VSITE) @@ -543,12 +537,12 @@ static int low_make_reverse_ilist(const InteractionLists &il_mt, * which of the constructing atoms are * vsites again. */ - r_il[r_index[a]+count[a]+2+nral] = 0; - for (j = 2; j < 1+nral; j++) + r_il[r_index[a] + count[a] + 2 + nral] = 0; + for (j = 2; j < 1 + nral; j++) { if (atom[ia[j]].ptype == eptVSite) { - r_il[r_index[a]+count[a]+2+nral] |= (2<nr; snew(count, nat_mt); - low_make_reverse_ilist(ilist, atoms->atom, - count, - bConstr, bSettle, bBCheck, - {}, {}, + low_make_reverse_ilist(ilist, atoms->atom, count, bConstr, bSettle, bBCheck, {}, {}, bLinkToAllAtoms, FALSE); ril_mt->index.push_back(0); @@ -602,12 +593,8 @@ static int make_reverse_ilist(const InteractionLists &ilist, ril_mt->il.resize(ril_mt->index[nat_mt]); /* Store the interactions */ - nint_mt = - low_make_reverse_ilist(ilist, atoms->atom, - count, - bConstr, bSettle, bBCheck, - ril_mt->index, ril_mt->il, - bLinkToAllAtoms, TRUE); + nint_mt = low_make_reverse_ilist(ilist, atoms->atom, count, bConstr, bSettle, bBCheck, + ril_mt->index, ril_mt->il, bLinkToAllAtoms, TRUE); sfree(count); @@ -617,11 +604,14 @@ static int make_reverse_ilist(const InteractionLists &ilist, } /*! \brief Generate the reverse topology */ -static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t *mtop, gmx_bool bFE, - gmx_bool bConstr, gmx_bool bSettle, - gmx_bool bBCheck, int *nint) +static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t* mtop, + gmx_bool bFE, + gmx_bool bConstr, + gmx_bool bSettle, + gmx_bool bBCheck, + int* nint) { - gmx_reverse_top_t rt; + gmx_reverse_top_t rt; /* Should we include constraints (for SHAKE) in rt? */ rt.bConstr = bConstr; @@ -634,30 +624,29 @@ static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t *mtop, gmx_bool bFE, std::vector nint_mt; for (size_t mt = 0; mt < mtop->moltype.size(); mt++) { - const gmx_moltype_t &molt = mtop->moltype[mt]; + const gmx_moltype_t& molt = mtop->moltype[mt]; if (molt.atoms.nr > 1) { rt.bInterAtomicInteractions = true; } /* Make the atom to interaction list for this molecule type */ - int numberOfInteractions = - make_reverse_ilist(molt.ilist, &molt.atoms, - rt.bConstr, rt.bSettle, rt.bBCheck, FALSE, - &rt.ril_mt[mt]); + int numberOfInteractions = make_reverse_ilist( + molt.ilist, &molt.atoms, rt.bConstr, rt.bSettle, rt.bBCheck, FALSE, &rt.ril_mt[mt]); nint_mt.push_back(numberOfInteractions); rt.ril_mt_tot_size += rt.ril_mt[mt].index[molt.atoms.nr]; } if (debug) { - fprintf(debug, "The total size of the atom to interaction index is %d integers\n", rt.ril_mt_tot_size); + fprintf(debug, "The total size of the atom to interaction index is %d integers\n", + rt.ril_mt_tot_size); } *nint = 0; - for (const gmx_molblock_t &molblock : mtop->molblock) + for (const gmx_molblock_t& molblock : mtop->molblock) { - *nint += molblock.nmol*nint_mt[molblock.type]; + *nint += molblock.nmol * nint_mt[molblock.type]; } /* Make an intermolecular reverse top, if necessary */ @@ -669,13 +658,11 @@ static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t *mtop, gmx_bool bFE, atoms_global.nr = mtop->natoms; atoms_global.atom = nullptr; /* Only used with virtual sites */ - GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, "We should have an ilist when intermolecular interactions are on"); + GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, + "We should have an ilist when intermolecular interactions are on"); - *nint += - make_reverse_ilist(*mtop->intermolecular_ilist, - &atoms_global, - rt.bConstr, rt.bSettle, rt.bBCheck, FALSE, - &rt.ril_intermol); + *nint += make_reverse_ilist(*mtop->intermolecular_ilist, &atoms_global, rt.bConstr, + rt.bSettle, rt.bBCheck, FALSE, &rt.ril_intermol); } if (bFE && gmx_mtop_bondeds_free_energy(mtop)) @@ -688,17 +675,17 @@ static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t *mtop, gmx_bool bFE, } /* Make a molblock index for fast searching */ - int i = 0; + int i = 0; for (size_t mb = 0; mb < mtop->molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop->molblock[mb]; + const gmx_molblock_t& molb = mtop->molblock[mb]; const int numAtomsPerMol = mtop->moltype[molb.type].atoms.nr; MolblockIndices mbi; - mbi.a_start = i; - i += molb.nmol*numAtomsPerMol; - mbi.a_end = i; - mbi.natoms_mol = numAtomsPerMol; - mbi.type = molb.type; + mbi.a_start = i; + i += molb.nmol * numAtomsPerMol; + mbi.a_end = i; + mbi.natoms_mol = numAtomsPerMol; + mbi.type = molb.type; rt.mbi.push_back(mbi); } @@ -707,10 +694,12 @@ static gmx_reverse_top_t make_reverse_top(const gmx_mtop_t *mtop, gmx_bool bFE, return rt; } -void dd_make_reverse_top(FILE *fplog, - gmx_domdec_t *dd, const gmx_mtop_t *mtop, - const gmx_vsite_t *vsite, - const t_inputrec *ir, gmx_bool bBCheck) +void dd_make_reverse_top(FILE* fplog, + gmx_domdec_t* dd, + const gmx_mtop_t* mtop, + const gmx_vsite_t* vsite, + const t_inputrec* ir, + gmx_bool bBCheck) { if (fplog) { @@ -723,21 +712,18 @@ void dd_make_reverse_top(FILE *fplog, * the parallel version constraint algorithm(s). */ - dd->reverse_top = new gmx_reverse_top_t; + dd->reverse_top = new gmx_reverse_top_t; *dd->reverse_top = - make_reverse_top(mtop, ir->efep != efepNO, - !dd->comm->systemInfo.haveSplitConstraints, - !dd->comm->systemInfo.haveSplitSettles, - bBCheck, &dd->nbonded_global); + make_reverse_top(mtop, ir->efep != efepNO, !dd->comm->systemInfo.haveSplitConstraints, + !dd->comm->systemInfo.haveSplitSettles, bBCheck, &dd->nbonded_global); - gmx_reverse_top_t *rt = dd->reverse_top; + gmx_reverse_top_t* rt = dd->reverse_top; dd->haveExclusions = false; rt->n_excl_at_max = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const int maxNumExclusionsPerAtom = - getMaxNumExclusionsPerAtom(mtop->moltype[molb.type].excls); + const int maxNumExclusionsPerAtom = getMaxNumExclusionsPerAtom(mtop->moltype[molb.type].excls); // We checked above that max 1 exclusion means only self exclusions if (maxNumExclusionsPerAtom > 1) { @@ -750,7 +736,8 @@ void dd_make_reverse_top(FILE *fplog, { if (fplog) { - fprintf(fplog, "There are %d inter update-group virtual sites,\n" + fprintf(fplog, + "There are %d inter update-group virtual sites,\n" "will an extra communication step for selected coordinates and forces\n", vsite->numInterUpdategroupVsites); } @@ -775,18 +762,21 @@ void dd_make_reverse_top(FILE *fplog, * confuses static analysis tools unless we fuse the vsite * atom-indexing organization code with the ifunc-adding code, so that * they can see that nral is the same value. */ -static inline void -add_ifunc_for_vsites(t_iatom *tiatoms, const gmx_ga2la_t &ga2la, - int nral, gmx_bool bHomeA, - int a, int a_gl, int a_mol, - const t_iatom *iatoms, - t_ilist *il) +static inline void add_ifunc_for_vsites(t_iatom* tiatoms, + const gmx_ga2la_t& ga2la, + int nral, + gmx_bool bHomeA, + int a, + int a_gl, + int a_mol, + const t_iatom* iatoms, + t_ilist* il) { - t_iatom *liatoms; + t_iatom* liatoms; - if (il->nr+1+nral > il->nalloc) + if (il->nr + 1 + nral > il->nalloc) { - il->nalloc = over_alloc_large(il->nr+1+nral); + il->nalloc = over_alloc_large(il->nr + 1 + nral); srenew(il->iatoms, il->nalloc); } liatoms = il->iatoms + il->nr; @@ -806,10 +796,10 @@ add_ifunc_for_vsites(t_iatom *tiatoms, const gmx_ga2la_t &ga2la, tiatoms[1] = -a_gl - 1; } - for (int k = 2; k < 1+nral; k++) + for (int k = 2; k < 1 + nral; k++) { int ak_gl = a_gl + iatoms[k] - a_mol; - if (const int *homeIndex = ga2la.findHome(ak_gl)) + if (const int* homeIndex = ga2la.findHome(ak_gl)) { tiatoms[k] = *homeIndex; } @@ -821,21 +811,21 @@ add_ifunc_for_vsites(t_iatom *tiatoms, const gmx_ga2la_t &ga2la, // Note that ga2la_get_home always sets the third parameter if // it returns TRUE } - for (int k = 0; k < 1+nral; k++) + for (int k = 0; k < 1 + nral; k++) { liatoms[k] = tiatoms[k]; } } /*! \brief Store a bonded interaction at the end of \p il */ -static inline void add_ifunc(int nral, const t_iatom *tiatoms, t_ilist *il) +static inline void add_ifunc(int nral, const t_iatom* tiatoms, t_ilist* il) { - t_iatom *liatoms; + t_iatom* liatoms; int k; - if (il->nr+1+nral > il->nalloc) + if (il->nr + 1 + nral > il->nalloc) { - il->nalloc = over_alloc_large(il->nr+1+nral); + il->nalloc = over_alloc_large(il->nr + 1 + nral); srenew(il->iatoms, il->nalloc); } liatoms = il->iatoms + il->nr; @@ -847,21 +837,24 @@ static inline void add_ifunc(int nral, const t_iatom *tiatoms, t_ilist *il) } /*! \brief Store a position restraint in idef and iatoms, complex because the parameters are different for each entry */ -static void add_posres(int mol, int a_mol, int numAtomsInMolecule, - const gmx_molblock_t *molb, - t_iatom *iatoms, const t_iparams *ip_in, - t_idef *idef) +static void add_posres(int mol, + int a_mol, + int numAtomsInMolecule, + const gmx_molblock_t* molb, + t_iatom* iatoms, + const t_iparams* ip_in, + t_idef* idef) { int n, a_molb; - t_iparams *ip; + t_iparams* ip; /* This position restraint has not been added yet, * so it's index is the current number of position restraints. */ - n = idef->il[F_POSRES].nr/2; - if (n+1 > idef->iparams_posres_nalloc) + n = idef->il[F_POSRES].nr / 2; + if (n + 1 > idef->iparams_posres_nalloc) { - idef->iparams_posres_nalloc = over_alloc_dd(n+1); + idef->iparams_posres_nalloc = over_alloc_dd(n + 1); srenew(idef->iparams_posres, idef->iparams_posres_nalloc); } ip = &idef->iparams_posres[n]; @@ -869,8 +862,9 @@ static void add_posres(int mol, int a_mol, int numAtomsInMolecule, *ip = ip_in[iatoms[0]]; /* Get the position restraint coordinates from the molblock */ - a_molb = mol*numAtomsInMolecule + a_mol; - GMX_ASSERT(a_molb < ssize(molb->posres_xA), "We need a sufficient number of position restraint coordinates"); + a_molb = mol * numAtomsInMolecule + a_mol; + GMX_ASSERT(a_molb < ssize(molb->posres_xA), + "We need a sufficient number of position restraint coordinates"); ip->posres.pos0A[XX] = molb->posres_xA[a_molb][XX]; ip->posres.pos0A[YY] = molb->posres_xA[a_molb][YY]; ip->posres.pos0A[ZZ] = molb->posres_xA[a_molb][ZZ]; @@ -891,21 +885,24 @@ static void add_posres(int mol, int a_mol, int numAtomsInMolecule, } /*! \brief Store a flat-bottomed position restraint in idef and iatoms, complex because the parameters are different for each entry */ -static void add_fbposres(int mol, int a_mol, int numAtomsInMolecule, - const gmx_molblock_t *molb, - t_iatom *iatoms, const t_iparams *ip_in, - t_idef *idef) +static void add_fbposres(int mol, + int a_mol, + int numAtomsInMolecule, + const gmx_molblock_t* molb, + t_iatom* iatoms, + const t_iparams* ip_in, + t_idef* idef) { int n, a_molb; - t_iparams *ip; + t_iparams* ip; /* This flat-bottom position restraint has not been added yet, * so it's index is the current number of position restraints. */ - n = idef->il[F_FBPOSRES].nr/2; - if (n+1 > idef->iparams_fbposres_nalloc) + n = idef->il[F_FBPOSRES].nr / 2; + if (n + 1 > idef->iparams_fbposres_nalloc) { - idef->iparams_fbposres_nalloc = over_alloc_dd(n+1); + idef->iparams_fbposres_nalloc = over_alloc_dd(n + 1); srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc); } ip = &idef->iparams_fbposres[n]; @@ -913,8 +910,9 @@ static void add_fbposres(int mol, int a_mol, int numAtomsInMolecule, *ip = ip_in[iatoms[0]]; /* Get the position restraint coordinats from the molblock */ - a_molb = mol*numAtomsInMolecule + a_mol; - GMX_ASSERT(a_molb < ssize(molb->posres_xA), "We need a sufficient number of position restraint coordinates"); + a_molb = mol * numAtomsInMolecule + a_mol; + GMX_ASSERT(a_molb < ssize(molb->posres_xA), + "We need a sufficient number of position restraint coordinates"); /* Take reference positions from A position of normal posres */ ip->fbposres.pos0[XX] = molb->posres_xA[a_molb][XX]; ip->fbposres.pos0[YY] = molb->posres_xA[a_molb][YY]; @@ -927,48 +925,51 @@ static void add_fbposres(int mol, int a_mol, int numAtomsInMolecule, } /*! \brief Store a virtual site interaction, complex because of PBC and recursion */ -static void add_vsite(const gmx_ga2la_t &ga2la, +static void add_vsite(const gmx_ga2la_t& ga2la, gmx::ArrayRef index, gmx::ArrayRef rtil, - int ftype, int nral, - gmx_bool bHomeA, int a, int a_gl, int a_mol, - const t_iatom *iatoms, - t_idef *idef) + int ftype, + int nral, + gmx_bool bHomeA, + int a, + int a_gl, + int a_mol, + const t_iatom* iatoms, + t_idef* idef) { int k; - t_iatom tiatoms[1+MAXATOMLIST]; + t_iatom tiatoms[1 + MAXATOMLIST]; int j, ftype_r, nral_r; /* Add this interaction to the local topology */ add_ifunc_for_vsites(tiatoms, ga2la, nral, bHomeA, a, a_gl, a_mol, iatoms, &idef->il[ftype]); - if (iatoms[1+nral]) + if (iatoms[1 + nral]) { /* Check for recursion */ - for (k = 2; k < 1+nral; k++) + for (k = 2; k < 1 + nral; k++) { - if ((iatoms[1+nral] & (2< src) +static void combine_blocka(t_blocka* dest, gmx::ArrayRef src) { int ni = src.back().excl.nr; int na = 0; - for (const thread_work_t &th_work : src) + for (const thread_work_t& th_work : src) { na += th_work.excl.nra; } if (ni + 1 > dest->nalloc_index) { - dest->nalloc_index = over_alloc_large(ni+1); + dest->nalloc_index = over_alloc_large(ni + 1); srenew(dest->index, dest->nalloc_index); } if (dest->nra + na > dest->nalloc_a) { - dest->nalloc_a = over_alloc_large(dest->nra+na); + dest->nalloc_a = over_alloc_large(dest->nra + na); srenew(dest->a, dest->nalloc_a); } for (gmx::index s = 1; s < src.ssize(); s++) @@ -1022,16 +1022,15 @@ static void combine_blocka(t_blocka *dest, } for (int i = 0; i < src[s].excl.nra; i++) { - dest->a[dest->nra+i] = src[s].excl.a[i]; + dest->a[dest->nra + i] = src[s].excl.a[i]; } - dest->nr = src[s].excl.nr; + dest->nr = src[s].excl.nr; dest->nra += src[s].excl.nra; } } /*! \brief Append t_idef structures 1 to nsrc in src to *dest */ -static void combine_idef(t_idef *dest, - gmx::ArrayRef src) +static void combine_idef(t_idef* dest, gmx::ArrayRef src) { int ftype; @@ -1044,19 +1043,19 @@ static void combine_idef(t_idef *dest, } if (n > 0) { - t_ilist *ild; + t_ilist* ild; ild = &dest->il[ftype]; if (ild->nr + n > ild->nalloc) { - ild->nalloc = over_alloc_large(ild->nr+n); + ild->nalloc = over_alloc_large(ild->nr + n); srenew(ild->iatoms, ild->nalloc); } for (gmx::index s = 1; s < src.ssize(); s++) { - const t_ilist &ils = src[s].idef.il[ftype]; + const t_ilist& ils = src[s].idef.il[ftype]; for (int i = 0; i < ils.nr; i++) { @@ -1069,10 +1068,12 @@ static void combine_idef(t_idef *dest, /* Position restraints need an additional treatment */ if (ftype == F_POSRES || ftype == F_FBPOSRES) { - int nposres = dest->il[ftype].nr/2; + int nposres = dest->il[ftype].nr / 2; // TODO: Simplify this code using std::vector - t_iparams * &iparams_dest = (ftype == F_POSRES ? dest->iparams_posres : dest->iparams_fbposres); - int &posres_nalloc = (ftype == F_POSRES ? dest->iparams_posres_nalloc : dest->iparams_fbposres_nalloc); + t_iparams*& iparams_dest = + (ftype == F_POSRES ? dest->iparams_posres : dest->iparams_fbposres); + int& posres_nalloc = (ftype == F_POSRES ? dest->iparams_posres_nalloc + : dest->iparams_fbposres_nalloc); if (nposres > posres_nalloc) { posres_nalloc = over_alloc_large(nposres); @@ -1082,19 +1083,20 @@ static void combine_idef(t_idef *dest, /* Set nposres to the number of original position restraints in dest */ for (gmx::index s = 1; s < src.ssize(); s++) { - nposres -= src[s].idef.il[ftype].nr/2; + nposres -= src[s].idef.il[ftype].nr / 2; } for (gmx::index s = 1; s < src.ssize(); s++) { - const t_iparams *iparams_src = (ftype == F_POSRES ? src[s].idef.iparams_posres : src[s].idef.iparams_fbposres); + const t_iparams* iparams_src = (ftype == F_POSRES ? src[s].idef.iparams_posres + : src[s].idef.iparams_fbposres); - for (int i = 0; i < src[s].idef.il[ftype].nr/2; i++) + for (int i = 0; i < src[s].idef.il[ftype].nr / 2; i++) { /* Correct the index into iparams_posres */ - dest->il[ftype].iatoms[nposres*2] = nposres; + dest->il[ftype].iatoms[nposres * 2] = nposres; /* Copy the position restraint force parameters */ - iparams_dest[nposres] = iparams_src[i]; + iparams_dest[nposres] = iparams_src[i]; nposres++; } } @@ -1105,33 +1107,37 @@ static void combine_idef(t_idef *dest, /*! \brief Check and when available assign bonded interactions for local atom i */ -static inline void -check_assign_interactions_atom(int i, int i_gl, - int mol, int i_mol, - int numAtomsInMolecule, - gmx::ArrayRef index, - gmx::ArrayRef rtil, - gmx_bool bInterMolInteractions, - int ind_start, int ind_end, - const gmx_domdec_t *dd, - const gmx_domdec_zones_t *zones, - const gmx_molblock_t *molb, - gmx_bool bRCheckMB, const ivec rcheck, gmx_bool bRCheck2B, - real rc2, - t_pbc *pbc_null, - rvec *cg_cm, - const t_iparams *ip_in, - t_idef *idef, - int iz, - gmx_bool bBCheck, - int *nbonded_local) +static inline void check_assign_interactions_atom(int i, + int i_gl, + int mol, + int i_mol, + int numAtomsInMolecule, + gmx::ArrayRef index, + gmx::ArrayRef rtil, + gmx_bool bInterMolInteractions, + int ind_start, + int ind_end, + const gmx_domdec_t* dd, + const gmx_domdec_zones_t* zones, + const gmx_molblock_t* molb, + gmx_bool bRCheckMB, + const ivec rcheck, + gmx_bool bRCheck2B, + real rc2, + t_pbc* pbc_null, + rvec* cg_cm, + const t_iparams* ip_in, + t_idef* idef, + int iz, + gmx_bool bBCheck, + int* nbonded_local) { gmx::ArrayRef iZones = zones->iZones; int j = ind_start; while (j < ind_end) { - t_iatom tiatoms[1 + MAXATOMLIST]; + t_iatom tiatoms[1 + MAXATOMLIST]; const int ftype = rtil[j++]; auto iatoms = gmx::constArrayRefFromArray(rtil.data() + j, rtil.size() - j); @@ -1142,9 +1148,7 @@ check_assign_interactions_atom(int i, int i_gl, /* The vsite construction goes where the vsite itself is */ if (iz == 0) { - add_vsite(*dd->ga2la, index, rtil, ftype, nral, - TRUE, i, i_gl, i_mol, - iatoms.data(), idef); + add_vsite(*dd->ga2la, index, rtil, ftype, nral, TRUE, i, i_gl, i_mol, iatoms.data(), idef); } j += 1 + nral + 2; } @@ -1165,13 +1169,11 @@ check_assign_interactions_atom(int i, int i_gl, tiatoms[1] = i; if (ftype == F_POSRES) { - add_posres(mol, i_mol, numAtomsInMolecule, - molb, tiatoms, ip_in, idef); + add_posres(mol, i_mol, numAtomsInMolecule, molb, tiatoms, ip_in, idef); } else if (ftype == F_FBPOSRES) { - add_fbposres(mol, i_mol, numAtomsInMolecule, - molb, tiatoms, ip_in, idef); + add_fbposres(mol, i_mol, numAtomsInMolecule, molb, tiatoms, ip_in, idef); } } else @@ -1195,7 +1197,7 @@ check_assign_interactions_atom(int i, int i_gl, { k_gl = iatoms[2]; } - if (const auto *entry = dd->ga2la->find(k_gl)) + if (const auto* entry = dd->ga2la->find(k_gl)) { int kz = entry->cell; if (kz >= zones->n) @@ -1203,12 +1205,8 @@ check_assign_interactions_atom(int i, int i_gl, kz -= zones->n; } /* Check zone interaction assignments */ - bUse = ((iz < iZones.ssize() && - iz <= kz && - iZones[iz].jZoneRange.isInRange(kz)) || - (kz < iZones.ssize() && - iz > kz && - iZones[kz].jZoneRange.isInRange(iz))); + bUse = ((iz < iZones.ssize() && iz <= kz && iZones[iz].jZoneRange.isInRange(kz)) + || (kz < iZones.ssize() && iz > kz && iZones[kz].jZoneRange.isInRange(iz))); if (bUse) { GMX_ASSERT(ftype != F_CONSTR || (iz == 0 && kz == 0), @@ -1217,9 +1215,7 @@ check_assign_interactions_atom(int i, int i_gl, tiatoms[1] = i; tiatoms[2] = entry->la; /* If necessary check the cgcm distance */ - if (bRCheck2B && - dd_dist2(pbc_null, cg_cm, - tiatoms[1], tiatoms[2]) >= rc2) + if (bRCheck2B && dd_dist2(pbc_null, cg_cm, tiatoms[1], tiatoms[2]) >= rc2) { bUse = FALSE; } @@ -1256,7 +1252,7 @@ check_assign_interactions_atom(int i, int i_gl, { k_gl = iatoms[k]; } - const auto *entry = dd->ga2la->find(k_gl); + const auto* entry = dd->ga2la->find(k_gl); if (entry == nullptr || entry->cell >= zones->n) { /* We do not have this atom of this interaction @@ -1283,8 +1279,7 @@ check_assign_interactions_atom(int i, int i_gl, } } } - bUse = (bUse && - (k_zero[XX] != 0) && (k_zero[YY] != 0) && (k_zero[ZZ] != 0)); + bUse = (bUse && (k_zero[XX] != 0) && (k_zero[YY] != 0) && (k_zero[ZZ] != 0)); if (bRCheckMB) { int d; @@ -1295,10 +1290,8 @@ check_assign_interactions_atom(int i, int i_gl, * the cut-off to avoid possible multiple * assignments of bonded interactions. */ - if (rcheck[d] && - k_plus[d] && - dd_dist2(pbc_null, cg_cm, - tiatoms[k_zero[d]], tiatoms[k_plus[d]]) >= rc2) + if (rcheck[d] && k_plus[d] + && dd_dist2(pbc_null, cg_cm, tiatoms[k_zero[d]], tiatoms[k_plus[d]]) >= rc2) { bUse = FALSE; } @@ -1312,8 +1305,7 @@ check_assign_interactions_atom(int i, int i_gl, /* Sum so we can check in global_stat * if we have everything. */ - if (bBCheck || - !(interaction_function[ftype].flags & IF_LIMZERO)) + if (bBCheck || !(interaction_function[ftype].flags & IF_LIMZERO)) { (*nbonded_local)++; } @@ -1328,20 +1320,23 @@ check_assign_interactions_atom(int i, int i_gl, * With thread parallelizing each thread acts on a different atom range: * at_start to at_end. */ -static int make_bondeds_zone(gmx_domdec_t *dd, - const gmx_domdec_zones_t *zones, - const std::vector &molb, - gmx_bool bRCheckMB, ivec rcheck, gmx_bool bRCheck2B, - real rc2, - t_pbc *pbc_null, rvec *cg_cm, - const t_iparams *ip_in, - t_idef *idef, - int izone, - const gmx::Range &atomRange) +static int make_bondeds_zone(gmx_domdec_t* dd, + const gmx_domdec_zones_t* zones, + const std::vector& molb, + gmx_bool bRCheckMB, + ivec rcheck, + gmx_bool bRCheck2B, + real rc2, + t_pbc* pbc_null, + rvec* cg_cm, + const t_iparams* ip_in, + t_idef* idef, + int izone, + const gmx::Range& atomRange) { int mb, mt, mol, i_mol; gmx_bool bBCheck; - gmx_reverse_top_t *rt; + gmx_reverse_top_t* rt; int nbonded_local; rt = dd->reverse_top; @@ -1356,23 +1351,13 @@ static int make_bondeds_zone(gmx_domdec_t *dd, const int i_gl = dd->globalAtomIndices[i]; global_atomnr_to_moltype_ind(rt, i_gl, &mb, &mt, &mol, &i_mol); /* Check all intramolecular interactions assigned to this atom */ - gmx::ArrayRef index = rt->ril_mt[mt].index; - gmx::ArrayRef rtil = rt->ril_mt[mt].il; - - check_assign_interactions_atom(i, i_gl, mol, i_mol, - rt->ril_mt[mt].numAtomsInMolecule, - index, rtil, FALSE, - index[i_mol], index[i_mol+1], - dd, zones, - &molb[mb], - bRCheckMB, rcheck, bRCheck2B, rc2, - pbc_null, - cg_cm, - ip_in, - idef, - izone, - bBCheck, - &nbonded_local); + gmx::ArrayRef index = rt->ril_mt[mt].index; + gmx::ArrayRef rtil = rt->ril_mt[mt].il; + + check_assign_interactions_atom(i, i_gl, mol, i_mol, rt->ril_mt[mt].numAtomsInMolecule, + index, rtil, FALSE, index[i_mol], index[i_mol + 1], dd, + zones, &molb[mb], bRCheckMB, rcheck, bRCheck2B, rc2, + pbc_null, cg_cm, ip_in, idef, izone, bBCheck, &nbonded_local); if (rt->bIntermolecularInteractions) @@ -1381,20 +1366,10 @@ static int make_bondeds_zone(gmx_domdec_t *dd, index = rt->ril_intermol.index; rtil = rt->ril_intermol.il; - check_assign_interactions_atom(i, i_gl, mol, i_mol, - rt->ril_mt[mt].numAtomsInMolecule, - index, rtil, TRUE, - index[i_gl], index[i_gl + 1], - dd, zones, - &molb[mb], - bRCheckMB, rcheck, bRCheck2B, rc2, - pbc_null, - cg_cm, - ip_in, - idef, - izone, - bBCheck, - &nbonded_local); + check_assign_interactions_atom(i, i_gl, mol, i_mol, rt->ril_mt[mt].numAtomsInMolecule, + index, rtil, TRUE, index[i_gl], index[i_gl + 1], dd, zones, + &molb[mb], bRCheckMB, rcheck, bRCheck2B, rc2, pbc_null, + cg_cm, ip_in, idef, izone, bBCheck, &nbonded_local); } } @@ -1402,9 +1377,7 @@ static int make_bondeds_zone(gmx_domdec_t *dd, } /*! \brief Set the exclusion data for i-zone \p iz for the case of no exclusions */ -static void set_no_exclusions_zone(const gmx_domdec_zones_t *zones, - int iz, - t_blocka *lexcls) +static void set_no_exclusions_zone(const gmx_domdec_zones_t* zones, int iz, t_blocka* lexcls) { for (int a = zones->cg_range[iz]; a < zones->cg_range[iz + 1]; a++) { @@ -1413,17 +1386,21 @@ static void set_no_exclusions_zone(const gmx_domdec_zones_t *zones, } /*! \brief Set the exclusion data for i-zone \p iz */ -static void make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, - const std::vector &moltype, - const int *cginfo, t_blocka *lexcls, int iz, - int at_start, int at_end, - const gmx::ArrayRef intermolecularExclusionGroup) +static void make_exclusions_zone(gmx_domdec_t* dd, + gmx_domdec_zones_t* zones, + const std::vector& moltype, + const int* cginfo, + t_blocka* lexcls, + int iz, + int at_start, + int at_end, + const gmx::ArrayRef intermolecularExclusionGroup) { - int n_excl_at_max, n, at; + int n_excl_at_max, n, at; - const gmx_ga2la_t &ga2la = *dd->ga2la; + const gmx_ga2la_t& ga2la = *dd->ga2la; - const auto &jAtomRange = zones->iZones[iz].jAtomRange; + const auto& jAtomRange = zones->iZones[iz].jAtomRange; n_excl_at_max = dd->reverse_top->n_excl_at_max; @@ -1442,7 +1419,7 @@ static void make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, if (GET_CGINFO_EXCL_INTER(cginfo[at])) { int a_gl, mb, mt, mol, a_mol, j; - const t_blocka *excls; + const t_blocka* excls; if (n + n_excl_at_max > lexcls->nalloc_a) { @@ -1453,14 +1430,13 @@ static void make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, /* Copy the exclusions from the global top */ lexcls->index[at] = n; a_gl = dd->globalAtomIndices[at]; - global_atomnr_to_moltype_ind(dd->reverse_top, a_gl, - &mb, &mt, &mol, &a_mol); + global_atomnr_to_moltype_ind(dd->reverse_top, a_gl, &mb, &mt, &mol, &a_mol); excls = &moltype[mt].excls; for (j = excls->index[a_mol]; j < excls->index[a_mol + 1]; j++) { const int aj_mol = excls->a[j]; - if (const auto *jEntry = ga2la.find(a_gl + aj_mol - a_mol)) + if (const auto* jEntry = ga2la.find(a_gl + aj_mol - a_mol)) { /* This check is not necessary, but it can reduce * the number of exclusions in the list, which in turn @@ -1479,23 +1455,21 @@ static void make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, lexcls->index[at] = n; } - bool isExcludedAtom = !intermolecularExclusionGroup.empty() && - std::find(intermolecularExclusionGroup.begin(), - intermolecularExclusionGroup.end(), - dd->globalAtomIndices[at]) != - intermolecularExclusionGroup.end(); + bool isExcludedAtom = !intermolecularExclusionGroup.empty() + && std::find(intermolecularExclusionGroup.begin(), + intermolecularExclusionGroup.end(), dd->globalAtomIndices[at]) + != intermolecularExclusionGroup.end(); if (isExcludedAtom) { if (n + intermolecularExclusionGroup.ssize() > lexcls->nalloc_a) { - lexcls->nalloc_a = - over_alloc_large(n + intermolecularExclusionGroup.size()); + lexcls->nalloc_a = over_alloc_large(n + intermolecularExclusionGroup.size()); srenew(lexcls->a, lexcls->nalloc_a); } for (int qmAtomGlobalIndex : intermolecularExclusionGroup) { - if (const auto *entry = dd->ga2la->find(qmAtomGlobalIndex)) + if (const auto* entry = dd->ga2la->find(qmAtomGlobalIndex)) { lexcls->a[n++] = entry->la; } @@ -1509,19 +1483,17 @@ static void make_exclusions_zone(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, /*! \brief Ensure we have enough space in \p ba for \p nindex_max indices */ -static void check_alloc_index(t_blocka *ba, int nindex_max) +static void check_alloc_index(t_blocka* ba, int nindex_max) { - if (nindex_max+1 > ba->nalloc_index) + if (nindex_max + 1 > ba->nalloc_index) { - ba->nalloc_index = over_alloc_dd(nindex_max+1); + ba->nalloc_index = over_alloc_dd(nindex_max + 1); srenew(ba->index, ba->nalloc_index); } } /*! \brief Ensure that we have enough space for exclusion storate in \p lexcls */ -static void check_exclusions_alloc(const gmx_domdec_t *dd, - const gmx_domdec_zones_t *zones, - t_blocka *lexcls) +static void check_exclusions_alloc(const gmx_domdec_t* dd, const gmx_domdec_zones_t* zones, t_blocka* lexcls) { const int nr = zones->iZones.back().iAtomRange.end(); @@ -1534,8 +1506,7 @@ static void check_exclusions_alloc(const gmx_domdec_t *dd, } /*! \brief Set the total count indexes for the local exclusions, needed by several functions */ -static void finish_local_exclusions(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, - t_blocka *lexcls) +static void finish_local_exclusions(gmx_domdec_t* dd, gmx_domdec_zones_t* zones, t_blocka* lexcls) { const gmx::Range nonhomeIzonesAtomRange(zones->iZones[0].iAtomRange.end(), zones->iZones.back().iAtomRange.end()); @@ -1562,9 +1533,9 @@ static void finish_local_exclusions(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, } /*! \brief Clear a t_idef struct */ -static void clear_idef(t_idef *idef) +static void clear_idef(t_idef* idef) { - int ftype; + int ftype; /* Clear the counts */ for (ftype = 0; ftype < F_NRE; ftype++) @@ -1574,21 +1545,25 @@ static void clear_idef(t_idef *idef) } /*! \brief Generate and store all required local bonded interactions in \p idef and local exclusions in \p lexcls */ -static int make_local_bondeds_excls(gmx_domdec_t *dd, - gmx_domdec_zones_t *zones, - const gmx_mtop_t *mtop, - const int *cginfo, - gmx_bool bRCheckMB, ivec rcheck, gmx_bool bRCheck2B, - real rc, - t_pbc *pbc_null, rvec *cg_cm, - t_idef *idef, - t_blocka *lexcls, int *excl_count) +static int make_local_bondeds_excls(gmx_domdec_t* dd, + gmx_domdec_zones_t* zones, + const gmx_mtop_t* mtop, + const int* cginfo, + gmx_bool bRCheckMB, + ivec rcheck, + gmx_bool bRCheck2B, + real rc, + t_pbc* pbc_null, + rvec* cg_cm, + t_idef* idef, + t_blocka* lexcls, + int* excl_count) { int nzone_bondeds, nzone_excl; int cg0, cg1; real rc2; int nbonded_local; - gmx_reverse_top_t *rt; + gmx_reverse_top_t* rt; if (dd->reverse_top->bInterAtomicInteractions) { @@ -1617,15 +1592,15 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, rt = dd->reverse_top; - rc2 = rc*rc; + rc2 = rc * rc; /* Clear the counts */ clear_idef(idef); nbonded_local = 0; - lexcls->nr = 0; - lexcls->nra = 0; - *excl_count = 0; + lexcls->nr = 0; + lexcls->nra = 0; + *excl_count = 0; for (int izone = 0; izone < nzone_bondeds; izone++) { @@ -1639,11 +1614,11 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, try { int cg0t, cg1t; - t_idef *idef_t; - t_blocka *excl_t; + t_idef* idef_t; + t_blocka* excl_t; - cg0t = cg0 + ((cg1 - cg0)* thread )/numThreads; - cg1t = cg0 + ((cg1 - cg0)*(thread+1))/numThreads; + cg0t = cg0 + ((cg1 - cg0) * thread) / numThreads; + cg1t = cg0 + ((cg1 - cg0) * (thread + 1)) / numThreads; if (thread == 0) { @@ -1655,14 +1630,9 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, clear_idef(idef_t); } - rt->th_work[thread].nbonded = - make_bondeds_zone(dd, zones, - mtop->molblock, - bRCheckMB, rcheck, bRCheck2B, rc2, - pbc_null, cg_cm, idef->iparams, - idef_t, - izone, - gmx::Range(cg0t, cg1t)); + rt->th_work[thread].nbonded = make_bondeds_zone( + dd, zones, mtop->molblock, bRCheckMB, rcheck, bRCheck2B, rc2, pbc_null, + cg_cm, idef->iparams, idef_t, izone, gmx::Range(cg0t, cg1t)); if (izone < nzone_excl) { @@ -1678,13 +1648,11 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, } /* No charge groups and no distance check required */ - make_exclusions_zone(dd, zones, mtop->moltype, cginfo, - excl_t, izone, cg0t, - cg1t, - mtop->intermolecularExclusionGroup); + make_exclusions_zone(dd, zones, mtop->moltype, cginfo, excl_t, izone, cg0t, + cg1t, mtop->intermolecularExclusionGroup); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (rt->th_work.size() > 1) @@ -1692,7 +1660,7 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, combine_idef(idef, rt->th_work); } - for (const thread_work_t &th_work : rt->th_work) + for (const thread_work_t& th_work : rt->th_work) { nbonded_local += th_work.nbonded; } @@ -1704,7 +1672,7 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, combine_blocka(lexcls, rt->th_work); } - for (const thread_work_t &th_work : rt->th_work) + for (const thread_work_t& th_work : rt->th_work) { *excl_count += th_work.excl_count; } @@ -1722,19 +1690,22 @@ static int make_local_bondeds_excls(gmx_domdec_t *dd, finish_local_exclusions(dd, zones, lexcls); if (debug) { - fprintf(debug, "We have %d exclusions, check count %d\n", - lexcls->nra, *excl_count); + fprintf(debug, "We have %d exclusions, check count %d\n", lexcls->nra, *excl_count); } return nbonded_local; } -void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, - int npbcdim, matrix box, - rvec cellsize_min, const ivec npulse, - t_forcerec *fr, - rvec *cgcm_or_x, - const gmx_mtop_t &mtop, gmx_localtop_t *ltop) +void dd_make_local_top(gmx_domdec_t* dd, + gmx_domdec_zones_t* zones, + int npbcdim, + matrix box, + rvec cellsize_min, + const ivec npulse, + t_forcerec* fr, + rvec* cgcm_or_x, + const gmx_mtop_t& mtop, + gmx_localtop_t* ltop) { gmx_bool bRCheckMB, bRCheck2B; real rc = -1; @@ -1747,8 +1718,8 @@ void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, fprintf(debug, "Making local topology\n"); } - bRCheckMB = FALSE; - bRCheck2B = FALSE; + bRCheckMB = FALSE; + bRCheck2B = FALSE; if (dd->reverse_top->bInterAtomicInteractions) { @@ -1766,8 +1737,7 @@ void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, /* Only need to check for dimensions where the part of the box * that is not communicated is smaller than the cut-off. */ - if (d < npbcdim && dd->nc[d] > 1 && - (dd->nc[d] - npulse[d])*cellsize_min[d] < 2*rc) + if (d < npbcdim && dd->nc[d] > 1 && (dd->nc[d] - npulse[d]) * cellsize_min[d] < 2 * rc) { if (dd->nc[d] == 2) { @@ -1782,9 +1752,8 @@ void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, } if (debug) { - fprintf(debug, - "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %s\n", - d, cellsize_min[d], d, rcheck[d], gmx::boolToString(bRCheck2B)); + fprintf(debug, "dim %d cellmin %f bonded rcheck[%d] = %d, bRCheck2B = %s\n", d, + cellsize_min[d], d, rcheck[d], gmx::boolToString(bRCheck2B)); } } if (bRCheckMB || bRCheck2B) @@ -1800,23 +1769,19 @@ void dd_make_local_top(gmx_domdec_t *dd, gmx_domdec_zones_t *zones, } } - dd->nbonded_local = - make_local_bondeds_excls(dd, zones, &mtop, fr->cginfo.data(), - bRCheckMB, rcheck, bRCheck2B, rc, - pbc_null, cgcm_or_x, - <op->idef, - <op->excls, &nexcl); + dd->nbonded_local = make_local_bondeds_excls(dd, zones, &mtop, fr->cginfo.data(), bRCheckMB, + rcheck, bRCheck2B, rc, pbc_null, cgcm_or_x, + <op->idef, <op->excls, &nexcl); /* The ilist is not sorted yet, * we can only do this when we have the charge arrays. */ ltop->idef.ilsort = ilsortUNKNOWN; - ltop->atomtypes = mtop.atomtypes; + ltop->atomtypes = mtop.atomtypes; } -void dd_sort_local_top(gmx_domdec_t *dd, const t_mdatoms *mdatoms, - gmx_localtop_t *ltop) +void dd_sort_local_top(gmx_domdec_t* dd, const t_mdatoms* mdatoms, gmx_localtop_t* ltop) { if (dd->reverse_top->ilsort == ilsortNO_FE) { @@ -1828,14 +1793,13 @@ void dd_sort_local_top(gmx_domdec_t *dd, const t_mdatoms *mdatoms, } } -void dd_init_local_top(const gmx_mtop_t &top_global, - gmx_localtop_t *top) +void dd_init_local_top(const gmx_mtop_t& top_global, gmx_localtop_t* top) { /* TODO: Get rid of the const casts below, e.g. by using a reference */ top->idef.ntypes = top_global.ffparams.numTypes(); top->idef.atnr = top_global.ffparams.atnr; - top->idef.functype = const_cast(top_global.ffparams.functype.data()); - top->idef.iparams = const_cast(top_global.ffparams.iparams.data()); + top->idef.functype = const_cast(top_global.ffparams.functype.data()); + top->idef.iparams = const_cast(top_global.ffparams.iparams.data()); top->idef.fudgeQQ = top_global.ffparams.fudgeQQ; top->idef.cmap_grid = new gmx_cmap_t; *top->idef.cmap_grid = top_global.ffparams.cmap_grid; @@ -1844,8 +1808,7 @@ void dd_init_local_top(const gmx_mtop_t &top_global, top->useInDomainDecomp_ = true; } -void dd_init_local_state(gmx_domdec_t *dd, - const t_state *state_global, t_state *state_local) +void dd_init_local_state(gmx_domdec_t* dd, const t_state* state_global, t_state* state_local) { int buf[NITEM_DD_INIT_LOCAL_STATE]; @@ -1857,7 +1820,7 @@ void dd_init_local_state(gmx_domdec_t *dd, buf[3] = state_global->nhchainlength; buf[4] = state_global->dfhist ? state_global->dfhist->nlambda : 0; } - dd_bcast(dd, NITEM_DD_INIT_LOCAL_STATE*sizeof(int), buf); + dd_bcast(dd, NITEM_DD_INIT_LOCAL_STATE * sizeof(int), buf); init_gtc_state(state_local, buf[1], buf[2], buf[3]); init_dfhist_state(state_local, buf[4]); @@ -1865,13 +1828,13 @@ void dd_init_local_state(gmx_domdec_t *dd, } /*! \brief Check if a link is stored in \p link between charge groups \p cg_gl and \p cg_gl_j and if not so, store a link */ -static void check_link(t_blocka *link, int cg_gl, int cg_gl_j) +static void check_link(t_blocka* link, int cg_gl, int cg_gl_j) { int k; gmx_bool bFound; bFound = FALSE; - for (k = link->index[cg_gl]; k < link->index[cg_gl+1]; k++) + for (k = link->index[cg_gl]; k < link->index[cg_gl + 1]; k++) { GMX_RELEASE_ASSERT(link->a, "Inconsistent NULL pointer while making charge-group links"); if (link->a[k] == cg_gl_j) @@ -1881,24 +1844,23 @@ static void check_link(t_blocka *link, int cg_gl, int cg_gl_j) } if (!bFound) { - GMX_RELEASE_ASSERT(link->a || link->index[cg_gl+1]+1 > link->nalloc_a, + GMX_RELEASE_ASSERT(link->a || link->index[cg_gl + 1] + 1 > link->nalloc_a, "Inconsistent allocation of link"); /* Add this charge group link */ - if (link->index[cg_gl+1]+1 > link->nalloc_a) + if (link->index[cg_gl + 1] + 1 > link->nalloc_a) { - link->nalloc_a = over_alloc_large(link->index[cg_gl+1]+1); + link->nalloc_a = over_alloc_large(link->index[cg_gl + 1] + 1); srenew(link->a, link->nalloc_a); } - link->a[link->index[cg_gl+1]] = cg_gl_j; - link->index[cg_gl+1]++; + link->a[link->index[cg_gl + 1]] = cg_gl_j; + link->index[cg_gl + 1]++; } } -t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, - cginfo_mb_t *cginfo_mb) +t_blocka* makeBondedLinks(const gmx_mtop_t* mtop, cginfo_mb_t* cginfo_mb) { - t_blocka *link; - cginfo_mb_t *cgi_mb; + t_blocka* link; + cginfo_mb_t* cgi_mb; /* For each atom make a list of other atoms in the system * that a linked to it via bonded interactions @@ -1913,11 +1875,10 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, atoms.nr = mtop->natoms; atoms.atom = nullptr; - GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, "We should have an ilist when intermolecular interactions are on"); + GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, + "We should have an ilist when intermolecular interactions are on"); - make_reverse_ilist(*mtop->intermolecular_ilist, - &atoms, - FALSE, FALSE, FALSE, TRUE, &ril_intermol); + make_reverse_ilist(*mtop->intermolecular_ilist, &atoms, FALSE, FALSE, FALSE, TRUE, &ril_intermol); } snew(link, 1); @@ -1930,19 +1891,18 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, int ncgi = 0; for (size_t mb = 0; mb < mtop->molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop->molblock[mb]; + const gmx_molblock_t& molb = mtop->molblock[mb]; if (molb.nmol == 0) { continue; } - const gmx_moltype_t &molt = mtop->moltype[molb.type]; + const gmx_moltype_t& molt = mtop->moltype[molb.type]; /* Make a reverse ilist in which the interactions are linked * to all atoms, not only the first atom as in gmx_reverse_top. * The constraints are discarded here. */ reverse_ilist_t ril; - make_reverse_ilist(molt.ilist, &molt.atoms, - FALSE, FALSE, FALSE, TRUE, &ril); + make_reverse_ilist(molt.ilist, &molt.atoms, FALSE, FALSE, FALSE, TRUE, &ril); cgi_mb = &cginfo_mb[mb]; @@ -1951,10 +1911,10 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, { for (int a = 0; a < molt.atoms.nr; a++) { - int cg_gl = cg_offset + a; - link->index[cg_gl+1] = link->index[cg_gl]; - int i = ril.index[a]; - while (i < ril.index[a+1]) + int cg_gl = cg_offset + a; + link->index[cg_gl + 1] = link->index[cg_gl]; + int i = ril.index[a]; + while (i < ril.index[a + 1]) { int ftype = ril.il[i++]; int nral = NRAL(ftype); @@ -1974,7 +1934,7 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, if (mtop->bIntermolecularInteractions) { int i = ril_intermol.index[a]; - while (i < ril_intermol.index[a+1]) + while (i < ril_intermol.index[a + 1]) { int ftype = ril_intermol.il[i++]; int nral = NRAL(ftype); @@ -1991,7 +1951,7 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, i += nral_rt(ftype); } } - if (link->index[cg_gl+1] - link->index[cg_gl] > 0) + if (link->index[cg_gl + 1] - link->index[cg_gl] > 0) { SET_CGINFO_BOND_INTER(cgi_mb->cginfo[a]); ncgi++; @@ -2004,27 +1964,27 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, if (debug) { - fprintf(debug, "molecule type '%s' %d atoms has %d atom links through bonded interac.\n", *molt.name, molt.atoms.nr, nlink_mol); + fprintf(debug, "molecule type '%s' %d atoms has %d atom links through bonded interac.\n", + *molt.name, molt.atoms.nr, nlink_mol); } if (molb.nmol > mol) { /* Copy the data for the rest of the molecules in this block */ - link->nalloc_a += (molb.nmol - mol)*nlink_mol; + link->nalloc_a += (molb.nmol - mol) * nlink_mol; srenew(link->a, link->nalloc_a); for (; mol < molb.nmol; mol++) { for (int a = 0; a < molt.atoms.nr; a++) { int cg_gl = cg_offset + a; - link->index[cg_gl + 1] = - link->index[cg_gl + 1 - molt.atoms.nr] + nlink_mol; - for (int j = link->index[cg_gl]; j < link->index[cg_gl+1]; j++) + link->index[cg_gl + 1] = link->index[cg_gl + 1 - molt.atoms.nr] + nlink_mol; + for (int j = link->index[cg_gl]; j < link->index[cg_gl + 1]; j++) { link->a[j] = link->a[j - nlink_mol] + molt.atoms.nr; } - if (link->index[cg_gl+1] - link->index[cg_gl] > 0 && - cg_gl - cgi_mb->cg_start < cgi_mb->cg_mod) + if (link->index[cg_gl + 1] - link->index[cg_gl] > 0 + && cg_gl - cgi_mb->cg_start < cgi_mb->cg_mod) { SET_CGINFO_BOND_INTER(cgi_mb->cginfo[cg_gl - cgi_mb->cg_start]); ncgi++; @@ -2037,14 +1997,14 @@ t_blocka *makeBondedLinks(const gmx_mtop_t *mtop, if (debug) { - fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", - mtop->natoms, ncgi); + fprintf(debug, "Of the %d atoms %d are linked via bonded interactions\n", mtop->natoms, ncgi); } return link; } -typedef struct { +typedef struct +{ real r2; int ftype; int a1; @@ -2052,8 +2012,7 @@ typedef struct { } bonded_distance_t; /*! \brief Compare distance^2 \p r2 against the distance in \p bd and if larger store it along with \p ftype and atom indices \p a1 and \p a2 */ -static void update_max_bonded_distance(real r2, int ftype, int a1, int a2, - bonded_distance_t *bd) +static void update_max_bonded_distance(real r2, int ftype, int a1, int a2, bonded_distance_t* bd) { if (r2 > bd->r2) { @@ -2065,20 +2024,22 @@ static void update_max_bonded_distance(real r2, int ftype, int a1, int a2, } /*! \brief Set the distance, function type and atom indices for the longest distance between charge-groups of molecule type \p molt for two-body and multi-body bonded interactions */ -static void bonded_cg_distance_mol(const gmx_moltype_t *molt, - gmx_bool bBCheck, gmx_bool bExcl, rvec *cg_cm, - bonded_distance_t *bd_2b, - bonded_distance_t *bd_mb) +static void bonded_cg_distance_mol(const gmx_moltype_t* molt, + gmx_bool bBCheck, + gmx_bool bExcl, + rvec* cg_cm, + bonded_distance_t* bd_2b, + bonded_distance_t* bd_mb) { for (int ftype = 0; ftype < F_NRE; ftype++) { if (dd_check_ftype(ftype, bBCheck, FALSE, FALSE)) { - const auto &il = molt->ilist[ftype]; - int nral = NRAL(ftype); + const auto& il = molt->ilist[ftype]; + int nral = NRAL(ftype); if (nral > 1) { - for (int i = 0; i < il.size(); i += 1+nral) + for (int i = 0; i < il.size(); i += 1 + nral) { for (int ai = 0; ai < nral; ai++) { @@ -2090,8 +2051,7 @@ static void bonded_cg_distance_mol(const gmx_moltype_t *molt, { real rij2 = distance2(cg_cm[atomI], cg_cm[atomJ]); - update_max_bonded_distance(rij2, ftype, - atomI, atomJ, + update_max_bonded_distance(rij2, ftype, atomI, atomJ, (nral == 2) ? bd_2b : bd_mb); } } @@ -2102,10 +2062,10 @@ static void bonded_cg_distance_mol(const gmx_moltype_t *molt, } if (bExcl) { - const t_blocka *excls = &molt->excls; + const t_blocka* excls = &molt->excls; for (int ai = 0; ai < excls->nr; ai++) { - for (int j = excls->index[ai]; j < excls->index[ai+1]; j++) + for (int j = excls->index[ai]; j < excls->index[ai + 1]; j++) { int aj = excls->a[j]; if (ai != aj) @@ -2121,11 +2081,13 @@ static void bonded_cg_distance_mol(const gmx_moltype_t *molt, } /*! \brief Set the distance, function type and atom indices for the longest atom distance involved in intermolecular interactions for two-body and multi-body bonded interactions */ -static void bonded_distance_intermol(const InteractionLists &ilists_intermol, - gmx_bool bBCheck, - const rvec *x, int ePBC, const matrix box, - bonded_distance_t *bd_2b, - bonded_distance_t *bd_mb) +static void bonded_distance_intermol(const InteractionLists& ilists_intermol, + gmx_bool bBCheck, + const rvec* x, + int ePBC, + const matrix box, + bonded_distance_t* bd_2b, + bonded_distance_t* bd_mb) { t_pbc pbc; @@ -2135,13 +2097,13 @@ static void bonded_distance_intermol(const InteractionLists &ilists_intermol, { if (dd_check_ftype(ftype, bBCheck, FALSE, FALSE)) { - const auto &il = ilists_intermol[ftype]; - int nral = NRAL(ftype); + const auto& il = ilists_intermol[ftype]; + int nral = NRAL(ftype); /* No nral>1 check here, since intermol interactions always * have nral>=2 (and the code is also correct for nral=1). */ - for (int i = 0; i < il.size(); i += 1+nral) + for (int i = 0; i < il.size(); i += 1 + nral) { for (int ai = 0; ai < nral; ai++) { @@ -2152,15 +2114,13 @@ static void bonded_distance_intermol(const InteractionLists &ilists_intermol, rvec dx; real rij2; - int atom_j = il.iatoms[i + 1 + aj]; + int atom_j = il.iatoms[i + 1 + aj]; pbc_dx(&pbc, x[atom_i], x[atom_j], dx); rij2 = norm2(dx); - update_max_bonded_distance(rij2, ftype, - atom_i, atom_j, - (nral == 2) ? bd_2b : bd_mb); + update_max_bonded_distance(rij2, ftype, atom_i, atom_j, (nral == 2) ? bd_2b : bd_mb); } } } @@ -2169,13 +2129,12 @@ static void bonded_distance_intermol(const InteractionLists &ilists_intermol, } //! Returns whether \p molt has at least one virtual site -static bool moltypeHasVsite(const gmx_moltype_t &molt) +static bool moltypeHasVsite(const gmx_moltype_t& molt) { bool hasVsite = false; for (int i = 0; i < F_NRE; i++) { - if ((interaction_function[i].flags & IF_VSITE) && - molt.ilist[i].size() > 0) + if ((interaction_function[i].flags & IF_VSITE) && molt.ilist[i].size() > 0) { hasVsite = true; } @@ -2185,10 +2144,13 @@ static bool moltypeHasVsite(const gmx_moltype_t &molt) } //! Returns coordinates not broken over PBC for a molecule -static void getWholeMoleculeCoordinates(const gmx_moltype_t *molt, - const gmx_ffparams_t *ffparams, - int ePBC, t_graph *graph, const matrix box, - const rvec *x, rvec *xs) +static void getWholeMoleculeCoordinates(const gmx_moltype_t* molt, + const gmx_ffparams_t* ffparams, + int ePBC, + t_graph* graph, + const matrix box, + const rvec* x, + rvec* xs) { int n, i; @@ -2226,41 +2188,42 @@ static void getWholeMoleculeCoordinates(const gmx_moltype_t *molt, if (interaction_function[ftype].flags & IF_VSITE) { ilist[ftype].nr = molt->ilist[ftype].size(); - ilist[ftype].iatoms = const_cast(molt->ilist[ftype].iatoms.data()); + ilist[ftype].iatoms = const_cast(molt->ilist[ftype].iatoms.data()); } } - construct_vsites(nullptr, xs, 0.0, nullptr, - ffparams->iparams.data(), ilist, - epbcNONE, TRUE, nullptr, nullptr); + construct_vsites(nullptr, xs, 0.0, nullptr, ffparams->iparams.data(), ilist, epbcNONE, TRUE, + nullptr, nullptr); } } -void dd_bonded_cg_distance(const gmx::MDLogger &mdlog, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const rvec *x, const matrix box, - gmx_bool bBCheck, - real *r_2b, real *r_mb) +void dd_bonded_cg_distance(const gmx::MDLogger& mdlog, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const rvec* x, + const matrix box, + gmx_bool bBCheck, + real* r_2b, + real* r_mb) { - gmx_bool bExclRequired; - int at_offset; - t_graph graph; - rvec *xs; - bonded_distance_t bd_2b = { 0, -1, -1, -1 }; - bonded_distance_t bd_mb = { 0, -1, -1, -1 }; + gmx_bool bExclRequired; + int at_offset; + t_graph graph; + rvec* xs; + bonded_distance_t bd_2b = { 0, -1, -1, -1 }; + bonded_distance_t bd_mb = { 0, -1, -1, -1 }; bExclRequired = inputrecExclForces(ir); *r_2b = 0; *r_mb = 0; at_offset = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const gmx_moltype_t &molt = mtop->moltype[molb.type]; + const gmx_moltype_t& molt = mtop->moltype[molb.type]; if (molt.atoms.nr == 1 || molb.nmol == 0) { - at_offset += molb.nmol*molt.atoms.nr; + at_offset += molb.nmol * molt.atoms.nr; } else { @@ -2273,23 +2236,18 @@ void dd_bonded_cg_distance(const gmx::MDLogger &mdlog, for (int mol = 0; mol < molb.nmol; mol++) { getWholeMoleculeCoordinates(&molt, &mtop->ffparams, ir->ePBC, &graph, box, - x+at_offset, xs); + x + at_offset, xs); bonded_distance_t bd_mol_2b = { 0, -1, -1, -1 }; bonded_distance_t bd_mol_mb = { 0, -1, -1, -1 }; - bonded_cg_distance_mol(&molt, bBCheck, bExclRequired, xs, - &bd_mol_2b, &bd_mol_mb); + bonded_cg_distance_mol(&molt, bBCheck, bExclRequired, xs, &bd_mol_2b, &bd_mol_mb); /* Process the mol data adding the atom index offset */ - update_max_bonded_distance(bd_mol_2b.r2, bd_mol_2b.ftype, - at_offset + bd_mol_2b.a1, - at_offset + bd_mol_2b.a2, - &bd_2b); - update_max_bonded_distance(bd_mol_mb.r2, bd_mol_mb.ftype, - at_offset + bd_mol_mb.a1, - at_offset + bd_mol_mb.a2, - &bd_mb); + update_max_bonded_distance(bd_mol_2b.r2, bd_mol_2b.ftype, at_offset + bd_mol_2b.a1, + at_offset + bd_mol_2b.a2, &bd_2b); + update_max_bonded_distance(bd_mol_mb.r2, bd_mol_mb.ftype, at_offset + bd_mol_mb.a1, + at_offset + bd_mol_mb.a2, &bd_mb); at_offset += molt.atoms.nr; } @@ -2303,12 +2261,10 @@ void dd_bonded_cg_distance(const gmx::MDLogger &mdlog, if (mtop->bIntermolecularInteractions) { - GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, "We should have an ilist when intermolecular interactions are on"); + GMX_RELEASE_ASSERT(mtop->intermolecular_ilist, + "We should have an ilist when intermolecular interactions are on"); - bonded_distance_intermol(*mtop->intermolecular_ilist, - bBCheck, - x, ir->ePBC, box, - &bd_2b, &bd_mb); + bonded_distance_intermol(*mtop->intermolecular_ilist, bBCheck, x, ir->ePBC, box, &bd_2b, &bd_mb); } *r_2b = sqrt(bd_2b.r2); @@ -2319,17 +2275,18 @@ void dd_bonded_cg_distance(const gmx::MDLogger &mdlog, GMX_LOG(mdlog.info).appendText("Initial maximum distances in bonded interactions:"); if (*r_2b > 0) { - GMX_LOG(mdlog.info).appendTextFormatted( - " two-body bonded interactions: %5.3f nm, %s, atoms %d %d", - *r_2b, (bd_2b.ftype >= 0) ? interaction_function[bd_2b.ftype].longname : "Exclusion", - bd_2b.a1 + 1, bd_2b.a2 + 1); + GMX_LOG(mdlog.info) + .appendTextFormatted( + " two-body bonded interactions: %5.3f nm, %s, atoms %d %d", *r_2b, + (bd_2b.ftype >= 0) ? interaction_function[bd_2b.ftype].longname : "Exclusion", + bd_2b.a1 + 1, bd_2b.a2 + 1); } if (*r_mb > 0) { - GMX_LOG(mdlog.info).appendTextFormatted( - " multi-body bonded interactions: %5.3f nm, %s, atoms %d %d", - *r_mb, interaction_function[bd_mb.ftype].longname, - bd_mb.a1 + 1, bd_mb.a2 + 1); + GMX_LOG(mdlog.info) + .appendTextFormatted( + " multi-body bonded interactions: %5.3f nm, %s, atoms %d %d", *r_mb, + interaction_function[bd_mb.ftype].longname, bd_mb.a1 + 1, bd_mb.a2 + 1); } } } diff --git a/src/gromacs/domdec/domdec_vsite.cpp b/src/gromacs/domdec/domdec_vsite.cpp index c5395529c3..5d2001dbc0 100644 --- a/src/gromacs/domdec/domdec_vsite.cpp +++ b/src/gromacs/domdec/domdec_vsite.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2006,2007,2008,2009,2010,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2006,2007,2008,2009,2010,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,7 +64,7 @@ #include "domdec_specatomcomm.h" -void dd_move_f_vsites(gmx_domdec_t *dd, rvec *f, rvec *fshift) +void dd_move_f_vsites(gmx_domdec_t* dd, rvec* f, rvec* fshift) { if (dd->vsite_comm) { @@ -72,7 +72,7 @@ void dd_move_f_vsites(gmx_domdec_t *dd, rvec *f, rvec *fshift) } } -void dd_clear_f_vsites(gmx_domdec_t *dd, rvec *f) +void dd_clear_f_vsites(gmx_domdec_t* dd, rvec* f) { int i; @@ -85,7 +85,7 @@ void dd_clear_f_vsites(gmx_domdec_t *dd, rvec *f) } } -void dd_move_x_vsites(gmx_domdec_t *dd, const matrix box, rvec *x) +void dd_move_x_vsites(gmx_domdec_t* dd, const matrix box, rvec* x) { if (dd->vsite_comm) { @@ -93,7 +93,7 @@ void dd_move_x_vsites(gmx_domdec_t *dd, const matrix box, rvec *x) } } -void dd_clear_local_vsite_indices(gmx_domdec_t *dd) +void dd_clear_local_vsite_indices(gmx_domdec_t* dd) { if (dd->vsite_comm) { @@ -101,10 +101,10 @@ void dd_clear_local_vsite_indices(gmx_domdec_t *dd) } } -int dd_make_local_vsites(gmx_domdec_t *dd, int at_start, t_ilist *lil) +int dd_make_local_vsites(gmx_domdec_t* dd, int at_start, t_ilist* lil) { - std::vector &ireq = dd->vsite_requestedGlobalAtomIndices; - gmx::HashedMap *ga2la_specat = dd->ga2la_vsite; + std::vector& ireq = dd->vsite_requestedGlobalAtomIndices; + gmx::HashedMap* ga2la_specat = dd->ga2la_vsite; ireq.clear(); /* Loop over all the home vsites */ @@ -113,10 +113,10 @@ int dd_make_local_vsites(gmx_domdec_t *dd, int at_start, t_ilist *lil) if (interaction_function[ftype].flags & IF_VSITE) { const int nral = NRAL(ftype); - const t_ilist &lilf = lil[ftype]; + const t_ilist& lilf = lil[ftype]; for (int i = 0; i < lilf.nr; i += 1 + nral) { - const t_iatom *iatoms = lilf.iatoms + i; + const t_iatom* iatoms = lilf.iatoms + i; /* Check if we have the other atoms */ for (int j = 1; j < 1 + nral; j++) { @@ -142,25 +142,24 @@ int dd_make_local_vsites(gmx_domdec_t *dd, int at_start, t_ilist *lil) } } - int at_end = - setup_specat_communication(dd, &ireq, dd->vsite_comm, ga2la_specat, - at_start, 1, "vsite", ""); + int at_end = setup_specat_communication(dd, &ireq, dd->vsite_comm, ga2la_specat, at_start, 1, + "vsite", ""); /* Fill in the missing indices */ for (int ftype = 0; ftype < F_NRE; ftype++) { if (interaction_function[ftype].flags & IF_VSITE) { - const int nral = NRAL(ftype); - t_ilist &lilf = lil[ftype]; + const int nral = NRAL(ftype); + t_ilist& lilf = lil[ftype]; for (int i = 0; i < lilf.nr; i += 1 + nral) { - t_iatom *iatoms = lilf.iatoms + i; + t_iatom* iatoms = lilf.iatoms + i; for (int j = 1; j < 1 + nral; j++) { if (iatoms[j] < 0) { - const int *a = ga2la_specat->find(-iatoms[j] - 1); + const int* a = ga2la_specat->find(-iatoms[j] - 1); GMX_ASSERT(a, "We have checked before that this atom index has been set"); iatoms[j] = *a; } @@ -172,7 +171,7 @@ int dd_make_local_vsites(gmx_domdec_t *dd, int at_start, t_ilist *lil) return at_end; } -void init_domdec_vsites(gmx_domdec_t *dd, int n_intercg_vsite) +void init_domdec_vsites(gmx_domdec_t* dd, int n_intercg_vsite) { if (debug) { @@ -182,9 +181,8 @@ void init_domdec_vsites(gmx_domdec_t *dd, int n_intercg_vsite) /* Use a hash table for the global to local index. * The number of keys is a rough estimate, it will be optimized later. */ - int numKeysEstimate = std::min(n_intercg_vsite/20, - n_intercg_vsite/(2*dd->nnodes)); - dd->ga2la_vsite = new gmx::HashedMap(numKeysEstimate); + int numKeysEstimate = std::min(n_intercg_vsite / 20, n_intercg_vsite / (2 * dd->nnodes)); + dd->ga2la_vsite = new gmx::HashedMap(numKeysEstimate); dd->vsite_comm = new gmx_domdec_specat_comm_t; } diff --git a/src/gromacs/domdec/domdec_vsite.h b/src/gromacs/domdec/domdec_vsite.h index 2061d9a877..0ce2a4d22b 100644 --- a/src/gromacs/domdec/domdec_vsite.h +++ b/src/gromacs/domdec/domdec_vsite.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,13 +48,12 @@ struct t_ilist; struct gmx_domdec_t; /*! \brief Clears the local indices for the virtual site communication setup */ -void dd_clear_local_vsite_indices(struct gmx_domdec_t *dd); +void dd_clear_local_vsite_indices(struct gmx_domdec_t* dd); /*! \brief Sets up communication and atom indices for all local vsites */ -int dd_make_local_vsites(struct gmx_domdec_t *dd, int at_start, - struct t_ilist *lil); +int dd_make_local_vsites(struct gmx_domdec_t* dd, int at_start, struct t_ilist* lil); /*! \brief Initializes the data structures for virtual site communication */ -void init_domdec_vsites(struct gmx_domdec_t *dd, int n_intercg_vsite); +void init_domdec_vsites(struct gmx_domdec_t* dd, int n_intercg_vsite); #endif diff --git a/src/gromacs/domdec/dump.cpp b/src/gromacs/domdec/dump.cpp index 0a37a06269..28db18d212 100644 --- a/src/gromacs/domdec/dump.cpp +++ b/src/gromacs/domdec/dump.cpp @@ -56,12 +56,11 @@ #include "domdec_internal.h" -void write_dd_grid_pdb(const char *fn, int64_t step, - gmx_domdec_t *dd, matrix box, gmx_ddbox_t *ddbox) +void write_dd_grid_pdb(const char* fn, int64_t step, gmx_domdec_t* dd, matrix box, gmx_ddbox_t* ddbox) { rvec grid_s[2], *grid_r = nullptr, cx, r; char fname[STRLEN], buf[22]; - FILE *out; + FILE* out; int a, i, d, z, y, x; matrix tric; real vol; @@ -71,10 +70,10 @@ void write_dd_grid_pdb(const char *fn, int64_t step, if (DDMASTER(dd)) { - snew(grid_r, 2*dd->nnodes); + snew(grid_r, 2 * dd->nnodes); } - dd_gather(dd, 2*sizeof(rvec), grid_s, DDMASTER(dd) ? grid_r : nullptr); + dd_gather(dd, 2 * sizeof(rvec), grid_s, DDMASTER(dd) ? grid_r : nullptr); if (DDMASTER(dd)) { @@ -90,7 +89,7 @@ void write_dd_grid_pdb(const char *fn, int64_t step, { if (d < ddbox->npbcdim && dd->nc[d] > 1) { - tric[d][i] = box[i][d]/box[i][i]; + tric[d][i] = box[i][d] / box[i][i]; } else { @@ -105,10 +104,10 @@ void write_dd_grid_pdb(const char *fn, int64_t step, a = 1; for (i = 0; i < dd->nnodes; i++) { - vol = dd->nnodes/(box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]); + vol = dd->nnodes / (box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]); for (d = 0; d < DIM; d++) { - vol *= grid_r[i*2+1][d] - grid_r[i*2][d]; + vol *= grid_r[i * 2 + 1][d] - grid_r[i * 2][d]; } for (z = 0; z < 2; z++) { @@ -116,12 +115,12 @@ void write_dd_grid_pdb(const char *fn, int64_t step, { for (x = 0; x < 2; x++) { - cx[XX] = grid_r[i*2+x][XX]; - cx[YY] = grid_r[i*2+y][YY]; - cx[ZZ] = grid_r[i*2+z][ZZ]; + cx[XX] = grid_r[i * 2 + x][XX]; + cx[YY] = grid_r[i * 2 + y][YY]; + cx[ZZ] = grid_r[i * 2 + z][ZZ]; mvmul(tric, cx, r); - gmx_fprintf_pdb_atomline(out, epdbATOM, a++, "CA", ' ', "GLY", ' ', i+1, ' ', - 10*r[XX], 10*r[YY], 10*r[ZZ], 1.0, vol, ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, a++, "CA", ' ', "GLY", ' ', i + 1, ' ', + 10 * r[XX], 10 * r[YY], 10 * r[ZZ], 1.0, vol, ""); } } } @@ -131,11 +130,11 @@ void write_dd_grid_pdb(const char *fn, int64_t step, { switch (d) { - case 0: y = 1 + i*8 + 2*x; break; - case 1: y = 1 + i*8 + 2*x - (x % 2); break; - case 2: y = 1 + i*8 + x; break; + case 0: y = 1 + i * 8 + 2 * x; break; + case 1: y = 1 + i * 8 + 2 * x - (x % 2); break; + case 2: y = 1 + i * 8 + x; break; } - fprintf(out, "%6s%5d%5d\n", "CONECT", y, y+(1<dd; if (natoms == -1) @@ -169,7 +173,7 @@ void write_dd_pdb(const char *fn, int64_t step, const char *title, int molb = 0; for (int i = 0; i < natoms; i++) { - int ii = dd->globalAtomIndices[i]; + int ii = dd->globalAtomIndices[i]; mtopGetAtomAndResidueName(mtop, ii, &molb, &atomname, &resnr, &resname, nullptr); int c; real b; @@ -190,8 +194,8 @@ void write_dd_pdb(const char *fn, int64_t step, const char *title, { b = dd->comm->zones.n + 1; } - gmx_fprintf_pdb_atomline(out, epdbATOM, ii+1, atomname, ' ', resname, ' ', resnr, ' ', - 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, b, ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, ii + 1, atomname, ' ', resname, ' ', resnr, ' ', + 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, b, ""); } fprintf(out, "TER\n"); diff --git a/src/gromacs/domdec/dump.h b/src/gromacs/domdec/dump.h index e70cfe7e7b..fabc6a5887 100644 --- a/src/gromacs/domdec/dump.h +++ b/src/gromacs/domdec/dump.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,16 +54,19 @@ struct gmx_mtop_t; struct t_commrec; //! Write the DD grid to a PDB file -void write_dd_grid_pdb(const char *fn, int64_t step, - gmx_domdec_t *dd, matrix box, gmx_ddbox_t *ddbox); +void write_dd_grid_pdb(const char* fn, int64_t step, gmx_domdec_t* dd, matrix box, gmx_ddbox_t* ddbox); /*! \brief Dump a pdb file with the current DD home + communicated atoms. * * When natoms=-1, dump all known atoms. */ -void write_dd_pdb(const char *fn, int64_t step, const char *title, - const gmx_mtop_t *mtop, - const t_commrec *cr, - int natoms, const rvec x[], const matrix box); +void write_dd_pdb(const char* fn, + int64_t step, + const char* title, + const gmx_mtop_t* mtop, + const t_commrec* cr, + int natoms, + const rvec x[], + const matrix box); #endif diff --git a/src/gromacs/domdec/ga2la.cpp b/src/gromacs/domdec/ga2la.cpp index 071e9697e4..5895532d41 100644 --- a/src/gromacs/domdec/ga2la.cpp +++ b/src/gromacs/domdec/ga2la.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,26 +59,24 @@ * Method 1 is faster for low parallelization, 2 for high parallelization. * We switch to method 2 when it uses less than half the memory method 1. */ -static bool directListIsFaster(int numAtomsTotal, - int numAtomsLocal) +static bool directListIsFaster(int numAtomsTotal, int numAtomsLocal) { constexpr int c_numAtomsSmallRelativeToCache = 1024; constexpr int c_memoryRatioHashedVersusDirect = 9; - return (numAtomsTotal <= c_numAtomsSmallRelativeToCache || - numAtomsTotal <= numAtomsLocal*c_memoryRatioHashedVersusDirect); + return (numAtomsTotal <= c_numAtomsSmallRelativeToCache + || numAtomsTotal <= numAtomsLocal * c_memoryRatioHashedVersusDirect); } -gmx_ga2la_t::gmx_ga2la_t(int numAtomsTotal, - int numAtomsLocal) : +gmx_ga2la_t::gmx_ga2la_t(int numAtomsTotal, int numAtomsLocal) : usingDirect_(directListIsFaster(numAtomsTotal, numAtomsLocal)) { if (usingDirect_) { - new(&(data_.direct)) std::vector(numAtomsTotal, {-1, -1}); + new (&(data_.direct)) std::vector(numAtomsTotal, { -1, -1 }); } else { - new(&(data_.hashed)) gmx::HashedMap(numAtomsLocal); + new (&(data_.hashed)) gmx::HashedMap(numAtomsLocal); } } diff --git a/src/gromacs/domdec/ga2la.h b/src/gromacs/domdec/ga2la.h index ff1e514683..6d1f7b818c 100644 --- a/src/gromacs/domdec/ga2la.h +++ b/src/gromacs/domdec/ga2la.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,121 +60,119 @@ */ class gmx_ga2la_t { - public: - /*! \libinternal \brief Structure for the local atom info */ - struct Entry - { - int la; /**< The local atom index */ - int cell; /**< The DD zone index for neighboring domains, zone+zone otherwise */ - }; +public: + /*! \libinternal \brief Structure for the local atom info */ + struct Entry + { + int la; /**< The local atom index */ + int cell; /**< The DD zone index for neighboring domains, zone+zone otherwise */ + }; + + /*! \brief Constructor + * + * \param[in] numAtomsTotal The total number of atoms in the system + * \param[in] numAtomsLocal An estimate of the number of home+communicated atoms + */ + gmx_ga2la_t(int numAtomsTotal, int numAtomsLocal); + ~gmx_ga2la_t() { usingDirect_ ? data_.direct.~vector() : data_.hashed.~HashedMap(); } - /*! \brief Constructor - * - * \param[in] numAtomsTotal The total number of atoms in the system - * \param[in] numAtomsLocal An estimate of the number of home+communicated atoms - */ - gmx_ga2la_t(int numAtomsTotal, - int numAtomsLocal); - ~gmx_ga2la_t() + /*! \brief Inserts an entry, there should not already be an entry for \p a_gl + * + * \param[in] a_gl The global atom index + * \param[in] value The value to set for this index + */ + void insert(int a_gl, const Entry& value) + { + GMX_ASSERT(a_gl >= 0, "Only global atom indices >= 0 are supported"); + if (usingDirect_) { - usingDirect_ ? data_.direct.~vector() : data_.hashed.~HashedMap(); + GMX_ASSERT(data_.direct[a_gl].cell == -1, + "The key to be inserted should not be present"); + data_.direct[a_gl] = value; } - - /*! \brief Inserts an entry, there should not already be an entry for \p a_gl - * - * \param[in] a_gl The global atom index - * \param[in] value The value to set for this index - */ - void insert(int a_gl, - const Entry &value) + else { - GMX_ASSERT(a_gl >= 0, "Only global atom indices >= 0 are supported"); - if (usingDirect_) - { - GMX_ASSERT(data_.direct[a_gl].cell == -1, "The key to be inserted should not be present"); - data_.direct[a_gl] = value; - } - else - { - data_.hashed.insert(a_gl, value); - } + data_.hashed.insert(a_gl, value); } + } - //! Delete the entry for global atom a_gl - void erase(int a_gl) + //! Delete the entry for global atom a_gl + void erase(int a_gl) + { + if (usingDirect_) { - if (usingDirect_) - { - data_.direct[a_gl].cell = -1; - } - else - { - data_.hashed.erase(a_gl); - } + data_.direct[a_gl].cell = -1; } - - //! Returns a pointer to the entry when present, nullptr otherwise - const Entry* find(int a_gl) const + else { - if (usingDirect_) - { - return (data_.direct[a_gl].cell == -1) ? nullptr : &(data_.direct[a_gl]); - } - else - { - return (data_.hashed.find(a_gl)); - } + data_.hashed.erase(a_gl); } + } - //! Returns the local atom index if it is a home atom, nullptr otherwise - const int* findHome(int a_gl) const + //! Returns a pointer to the entry when present, nullptr otherwise + const Entry* find(int a_gl) const + { + if (usingDirect_) + { + return (data_.direct[a_gl].cell == -1) ? nullptr : &(data_.direct[a_gl]); + } + else { - const Entry* const e = find(a_gl); - return (e && e->cell == 0) ? &(e->la) : nullptr; + return (data_.hashed.find(a_gl)); } + } + + //! Returns the local atom index if it is a home atom, nullptr otherwise + const int* findHome(int a_gl) const + { + const Entry* const e = find(a_gl); + return (e && e->cell == 0) ? &(e->la) : nullptr; + } - /*! \brief Returns a reference to the entry for a_gl - * - * A non-release assert checks that a_gl is present. - */ - Entry &at(int a_gl) + /*! \brief Returns a reference to the entry for a_gl + * + * A non-release assert checks that a_gl is present. + */ + Entry& at(int a_gl) + { + if (usingDirect_) { - if (usingDirect_) - { - GMX_ASSERT(data_.direct[a_gl].cell >= 0, "a_gl should be present"); - return data_.direct[a_gl]; - } - else - { - Entry *search = data_.hashed.find(a_gl); - GMX_ASSERT(search, "a_gl should be present"); - return *search; - } + GMX_ASSERT(data_.direct[a_gl].cell >= 0, "a_gl should be present"); + return data_.direct[a_gl]; } + else + { + Entry* search = data_.hashed.find(a_gl); + GMX_ASSERT(search, "a_gl should be present"); + return *search; + } + } - //! Clear all the entries in the list. - void clear() + //! Clear all the entries in the list. + void clear() + { + if (usingDirect_) { - if (usingDirect_) - { - for (Entry &entry : data_.direct) {entry.cell = -1; } - } - else + for (Entry& entry : data_.direct) { - data_.hashed.clear(); + entry.cell = -1; } } - - private: - union Data + else { - std::vector direct; - gmx::HashedMap hashed; - // constructor and destructor function in parent class - Data() {} - ~Data() {} - } data_; - const bool usingDirect_; + data_.hashed.clear(); + } + } + +private: + union Data { + std::vector direct; + gmx::HashedMap hashed; + // constructor and destructor function in parent class + Data() {} + ~Data() {} + } data_; + const bool usingDirect_; }; #endif diff --git a/src/gromacs/domdec/gpuhaloexchange.h b/src/gromacs/domdec/gpuhaloexchange.h index d5d8ee9953..f577124ada 100644 --- a/src/gromacs/domdec/gpuhaloexchange.h +++ b/src/gromacs/domdec/gpuhaloexchange.h @@ -59,68 +59,63 @@ namespace gmx class GpuHaloExchange { - public: - /*! \brief Creates GPU Halo Exchange object. - * - * Coordinate Halo exchange will be performed in \c - * StreamNonLocal, and the \c communicateHaloCoordinates - * method must be called before any subsequent operations that - * access non-local parts of the coordinate buffer (such as - * the non-local non-bonded kernels). It also must be called - * after the local coordinates buffer operations (where the - * coordinates are copied to the device and hence the \c - * coordinatesReadyOnDeviceEvent is recorded). Force Halo exchange - * will be performed in \c streamNonLocal (also potentally - * with buffer clearing in \c streamLocal)and the \c - * communicateHaloForces method must be called after the - * non-local buffer operations, after the local force buffer - * has been copied to the GPU (if CPU forces are present), and - * before the local buffer operations. The force halo exchange - * does not yet support virial steps. - * - * \param [inout] dd domdec structure - * \param [in] mpi_comm_mysim communicator used for simulation - * \param [in] streamLocal local NB CUDA stream. - * \param [in] streamNonLocal non-local NB CUDA stream. - */ - GpuHaloExchange(gmx_domdec_t *dd, - MPI_Comm mpi_comm_mysim, - void *streamLocal, - void *streamNonLocal); - ~GpuHaloExchange(); +public: + /*! \brief Creates GPU Halo Exchange object. + * + * Coordinate Halo exchange will be performed in \c + * StreamNonLocal, and the \c communicateHaloCoordinates + * method must be called before any subsequent operations that + * access non-local parts of the coordinate buffer (such as + * the non-local non-bonded kernels). It also must be called + * after the local coordinates buffer operations (where the + * coordinates are copied to the device and hence the \c + * coordinatesReadyOnDeviceEvent is recorded). Force Halo exchange + * will be performed in \c streamNonLocal (also potentally + * with buffer clearing in \c streamLocal)and the \c + * communicateHaloForces method must be called after the + * non-local buffer operations, after the local force buffer + * has been copied to the GPU (if CPU forces are present), and + * before the local buffer operations. The force halo exchange + * does not yet support virial steps. + * + * \param [inout] dd domdec structure + * \param [in] mpi_comm_mysim communicator used for simulation + * \param [in] streamLocal local NB CUDA stream. + * \param [in] streamNonLocal non-local NB CUDA stream. + */ + GpuHaloExchange(gmx_domdec_t* dd, MPI_Comm mpi_comm_mysim, void* streamLocal, void* streamNonLocal); + ~GpuHaloExchange(); - /*! \brief - * - * Initialization for GPU halo exchange of coordinates buffer - * \param [in] d_coordinateBuffer pointer to coordinates buffer in GPU memory - * \param [in] d_forcesBuffer pointer to coordinates buffer in GPU memory - */ - void reinitHalo(DeviceBuffer d_coordinateBuffer, - DeviceBuffer d_forcesBuffer); + /*! \brief + * + * Initialization for GPU halo exchange of coordinates buffer + * \param [in] d_coordinateBuffer pointer to coordinates buffer in GPU memory + * \param [in] d_forcesBuffer pointer to coordinates buffer in GPU memory + */ + void reinitHalo(DeviceBuffer d_coordinateBuffer, DeviceBuffer d_forcesBuffer); - /*! \brief GPU halo exchange of coordinates buffer. - * - * Must be called after local setCoordinates (which records an - * event when the coordinate data has been copied to the - * device). - * \param [in] box Coordinate box (from which shifts will be constructed) - * \param [in] coordinatesReadyOnDeviceEvent event recorded when coordinates have been copied to device - */ - void communicateHaloCoordinates(const matrix box, GpuEventSynchronizer *coordinatesReadyOnDeviceEvent); + /*! \brief GPU halo exchange of coordinates buffer. + * + * Must be called after local setCoordinates (which records an + * event when the coordinate data has been copied to the + * device). + * \param [in] box Coordinate box (from which shifts will be constructed) + * \param [in] coordinatesReadyOnDeviceEvent event recorded when coordinates have been copied to device + */ + void communicateHaloCoordinates(const matrix box, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); - /*! \brief GPU halo exchange of force buffer. - * \param[in] accumulateForces True if forces should accumulate, otherwise they are set - */ - void communicateHaloForces(bool accumulateForces); + /*! \brief GPU halo exchange of force buffer. + * \param[in] accumulateForces True if forces should accumulate, otherwise they are set + */ + void communicateHaloForces(bool accumulateForces); - private: - class Impl; - gmx::PrivateImplPointer impl_; - +private: + class Impl; + gmx::PrivateImplPointer impl_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/domdec/gpuhaloexchange_impl.cpp b/src/gromacs/domdec/gpuhaloexchange_impl.cpp index 2bb917d6b4..7ea94ac6a4 100644 --- a/src/gromacs/domdec/gpuhaloexchange_impl.cpp +++ b/src/gromacs/domdec/gpuhaloexchange_impl.cpp @@ -60,13 +60,14 @@ class GpuHaloExchange::Impl }; /*!\brief Constructor stub. */ -GpuHaloExchange::GpuHaloExchange(gmx_domdec_t * /* dd */, - MPI_Comm /* mpi_comm_mysim */, - void * /*streamLocal */, - void * /*streamNonLocal */) - : impl_(nullptr) +GpuHaloExchange::GpuHaloExchange(gmx_domdec_t* /* dd */, + MPI_Comm /* mpi_comm_mysim */, + void* /*streamLocal */, + void* /*streamNonLocal */) : + impl_(nullptr) { - GMX_ASSERT(false, "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); } GpuHaloExchange::~GpuHaloExchange() = default; @@ -75,22 +76,26 @@ GpuHaloExchange::~GpuHaloExchange() = default; void GpuHaloExchange::reinitHalo(DeviceBuffer /* d_coordinatesBuffer */, DeviceBuffer /* d_forcesBuffer */) { - GMX_ASSERT(false, "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); } /*!\brief apply X halo exchange stub. */ void GpuHaloExchange::communicateHaloCoordinates(const matrix /* box */, - GpuEventSynchronizer * /*coordinatesOnDeviceEvent*/) + GpuEventSynchronizer* /*coordinatesOnDeviceEvent*/) { - GMX_ASSERT(false, "A CPU stub for GPU Halo Exchange exchange was called insted of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for GPU Halo Exchange exchange was called insted of the correct " + "implementation."); } /*!\brief apply F halo exchange stub. */ void GpuHaloExchange::communicateHaloForces(bool gmx_unused accumulateForces) { - GMX_ASSERT(false, "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for GPU Halo Exchange was called insted of the correct implementation."); } -} // namespace gmx +} // namespace gmx #endif /* GMX_GPU != GMX_GPU_CUDA */ diff --git a/src/gromacs/domdec/gpuhaloexchange_impl.cu b/src/gromacs/domdec/gpuhaloexchange_impl.cu index 73b2dbb341..d917be3f39 100644 --- a/src/gromacs/domdec/gpuhaloexchange_impl.cu +++ b/src/gromacs/domdec/gpuhaloexchange_impl.cu @@ -65,19 +65,19 @@ namespace gmx { //! Number of CUDA threads in a block -//TODO Optimize this through experimentation +// TODO Optimize this through experimentation constexpr static int c_threadsPerBlock = 256; -template -__global__ void packSendBufKernel(float3 * __restrict__ dataPacked, - const float3 * __restrict__ data, - const int * __restrict__ map, - const int mapSize, - const float3 coordinateShift) +template +__global__ void packSendBufKernel(float3* __restrict__ dataPacked, + const float3* __restrict__ data, + const int* __restrict__ map, + const int mapSize, + const float3 coordinateShift) { - int threadIndex = blockIdx.x*blockDim.x+threadIdx.x; - float3 *gm_dataDest = &dataPacked[threadIndex]; - const float3 *gm_dataSrc = &data[map[threadIndex]]; + int threadIndex = blockIdx.x * blockDim.x + threadIdx.x; + float3* gm_dataDest = &dataPacked[threadIndex]; + const float3* gm_dataSrc = &data[map[threadIndex]]; if (threadIndex < mapSize) { @@ -89,28 +89,26 @@ __global__ void packSendBufKernel(float3 * __restrict__ dataPacked, { *gm_dataDest = *gm_dataSrc; } - } return; } -/*! \brief unpack non-local force data buffer on the GPU using pre-populated "map" containing index information - * \param[out] data full array of force values - * \param[in] dataPacked packed array of force values to be transferred - * \param[in] map array of indices defining mapping from full to packed array - * \param[in] mapSize number of elements in map array +/*! \brief unpack non-local force data buffer on the GPU using pre-populated "map" containing index + * information \param[out] data full array of force values \param[in] dataPacked packed + * array of force values to be transferred \param[in] map array of indices defining mapping + * from full to packed array \param[in] mapSize number of elements in map array */ -template -__global__ void unpackRecvBufKernel(float3 * __restrict__ data, - const float3 * __restrict__ dataPacked, - const int * __restrict__ map, - const int mapSize) +template +__global__ void unpackRecvBufKernel(float3* __restrict__ data, + const float3* __restrict__ dataPacked, + const int* __restrict__ map, + const int mapSize) { - int threadIndex = blockIdx.x*blockDim.x+threadIdx.x; - const float3 *gm_dataSrc = &dataPacked[threadIndex]; - float3 *gm_dataDest = &data[map[threadIndex]]; + int threadIndex = blockIdx.x * blockDim.x + threadIdx.x; + const float3* gm_dataSrc = &dataPacked[threadIndex]; + float3* gm_dataDest = &data[map[threadIndex]]; if (threadIndex < mapSize) { @@ -127,21 +125,21 @@ __global__ void unpackRecvBufKernel(float3 * __restrict__ data, return; } -void GpuHaloExchange::Impl::reinitHalo(float3 *d_coordinatesBuffer, - float3 *d_forcesBuffer) +void GpuHaloExchange::Impl::reinitHalo(float3* d_coordinatesBuffer, float3* d_forcesBuffer) { d_x_ = d_coordinatesBuffer; d_f_ = d_forcesBuffer; - cudaStream_t stream = nonLocalStream_; - int nzone = 1; - const gmx_domdec_comm_t &comm = *dd_->comm; - const gmx_domdec_comm_dim_t &cd = comm.cd[0]; - const gmx_domdec_ind_t &ind = cd.ind[0]; - int newSize = ind.nsend[nzone+1]; + cudaStream_t stream = nonLocalStream_; + int nzone = 1; + const gmx_domdec_comm_t& comm = *dd_->comm; + const gmx_domdec_comm_dim_t& cd = comm.cd[0]; + const gmx_domdec_ind_t& ind = cd.ind[0]; + int newSize = ind.nsend[nzone + 1]; - GMX_RELEASE_ASSERT(cd.numPulses() == 1, "Multiple pulses are not yet supported in GPU halo exchange"); + GMX_RELEASE_ASSERT(cd.numPulses() == 1, + "Multiple pulses are not yet supported in GPU halo exchange"); GMX_ASSERT(cd.receiveInPlace, "Out-of-place receive is not yet supported in GPU halo exchange"); // reallocates only if needed @@ -157,37 +155,35 @@ void GpuHaloExchange::Impl::reinitHalo(float3 *d_coordinatesBuffer, xSendSize_ = newSize; #if GMX_MPI - MPI_Sendrecv(&xSendSize_, sizeof(int), MPI_BYTE, sendRankX_, 0, - &xRecvSize_, sizeof(int), MPI_BYTE, recvRankX_, 0, - mpi_comm_mysim_, MPI_STATUS_IGNORE); + MPI_Sendrecv(&xSendSize_, sizeof(int), MPI_BYTE, sendRankX_, 0, &xRecvSize_, sizeof(int), + MPI_BYTE, recvRankX_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE); #endif fSendSize_ = xRecvSize_; fRecvSize_ = xSendSize_; - numHomeAtoms_ = comm.atomRanges.numHomeAtoms(); //offset for data recieved by this rank + numHomeAtoms_ = comm.atomRanges.numHomeAtoms(); // offset for data recieved by this rank GMX_ASSERT(ind.index.size() == h_indexMap_.size(), "Size mismatch"); std::copy(ind.index.begin(), ind.index.end(), h_indexMap_.begin()); - copyToDeviceBuffer(&d_indexMap_, h_indexMap_.data(), 0, newSize, stream, GpuApiCallBehavior::Async, nullptr); + copyToDeviceBuffer(&d_indexMap_, h_indexMap_.data(), 0, newSize, stream, + GpuApiCallBehavior::Async, nullptr); // This rank will push data to its neighbor, so needs to know // the remote receive address and similarly send its receive // address to other neighbour. We can do this here in reinit fn // since the pointers will not change until the next NS step. - //Coordinates buffer: + // Coordinates buffer: #if GMX_MPI - void* recvPtr = static_cast (&d_coordinatesBuffer[numHomeAtoms_]); - MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankX_, 0, - &remoteXPtr_, sizeof(void*), MPI_BYTE, sendRankX_, 0, - mpi_comm_mysim_, MPI_STATUS_IGNORE); - - //Force buffer: - recvPtr = static_cast (d_recvBuf_); - MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankF_, 0, - &remoteFPtr_, sizeof(void*), MPI_BYTE, sendRankF_, 0, - mpi_comm_mysim_, MPI_STATUS_IGNORE); + void* recvPtr = static_cast(&d_coordinatesBuffer[numHomeAtoms_]); + MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankX_, 0, &remoteXPtr_, sizeof(void*), + MPI_BYTE, sendRankX_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE); + + // Force buffer: + recvPtr = static_cast(d_recvBuf_); + MPI_Sendrecv(&recvPtr, sizeof(void*), MPI_BYTE, recvRankF_, 0, &remoteFPtr_, sizeof(void*), + MPI_BYTE, sendRankF_, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE); #endif @@ -195,10 +191,10 @@ void GpuHaloExchange::Impl::reinitHalo(float3 *d_coordinatesBuffer, } void GpuHaloExchange::Impl::communicateHaloCoordinates(const matrix box, - GpuEventSynchronizer *coordinatesReadyOnDeviceEvent) + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) { - //ensure stream waits until coordinate data is available on device + // ensure stream waits until coordinate data is available on device coordinatesReadyOnDeviceEvent->enqueueWaitEvent(nonLocalStream_); // launch kernel to pack send buffer @@ -206,16 +202,16 @@ void GpuHaloExchange::Impl::communicateHaloCoordinates(const matrix box config.blockSize[0] = c_threadsPerBlock; config.blockSize[1] = 1; config.blockSize[2] = 1; - config.gridSize[0] = (xSendSize_+c_threadsPerBlock-1)/c_threadsPerBlock; + config.gridSize[0] = (xSendSize_ + c_threadsPerBlock - 1) / c_threadsPerBlock; config.gridSize[1] = 1; config.gridSize[2] = 1; config.sharedMemorySize = 0; config.stream = nonLocalStream_; - const float3 *sendBuf = d_sendBuf_; - const float3 *d_x = d_x_; - const int *indexMap = d_indexMap_; - const int size = xSendSize_; + const float3* sendBuf = d_sendBuf_; + const float3* d_x = d_x_; + const int* indexMap = d_indexMap_; + const int size = xSendSize_; // The coordinateShift changes between steps when we have // performed a DD partition, or have updated the box e.g. when // performing pressure coupling. So, for simplicity, the box @@ -224,18 +220,17 @@ void GpuHaloExchange::Impl::communicateHaloCoordinates(const matrix box // // Because only one-dimensional DD is supported, the coordinate // shift only needs to handle that dimension. - const int dimensionIndex = dd_->dim[0]; - const float3 coordinateShift { - box[dimensionIndex][XX], box[dimensionIndex][YY], box[dimensionIndex][ZZ] - }; + const int dimensionIndex = dd_->dim[0]; + const float3 coordinateShift{ box[dimensionIndex][XX], box[dimensionIndex][YY], + box[dimensionIndex][ZZ] }; // Avoid launching kernel when there is no work to do if (size > 0) { - auto kernelFn = usePBC_ ? packSendBufKernel : packSendBufKernel; + auto kernelFn = usePBC_ ? packSendBufKernel : packSendBufKernel; - const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &sendBuf, &d_x, &indexMap, - &size, &coordinateShift); + const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &sendBuf, &d_x, + &indexMap, &size, &coordinateShift); launchGpuKernel(kernelFn, config, nullptr, "Domdec GPU Apply X Halo Exchange", kernelArgs); } @@ -253,12 +248,12 @@ void GpuHaloExchange::Impl::communicateHaloForces(bool accumulateForces) // Communicate halo data (in non-local stream) communicateHaloData(d_f_, HaloQuantity::HaloForces); - float3 *d_f = d_f_; + float3* d_f = d_f_; if (!accumulateForces) { - //Clear local portion of force array (in local stream) - cudaMemsetAsync(d_f, 0, numHomeAtoms_*sizeof(rvec), localStream_); + // Clear local portion of force array (in local stream) + cudaMemsetAsync(d_f, 0, numHomeAtoms_ * sizeof(rvec), localStream_); } // ensure non-local stream waits for local stream, due to dependence on @@ -269,64 +264,61 @@ void GpuHaloExchange::Impl::communicateHaloForces(bool accumulateForces) eventLocal.markEvent(localStream_); eventLocal.enqueueWaitEvent(nonLocalStream_); - //Unpack halo buffer into force array + // Unpack halo buffer into force array KernelLaunchConfig config; config.blockSize[0] = c_threadsPerBlock; config.blockSize[1] = 1; config.blockSize[2] = 1; - config.gridSize[0] = (fRecvSize_+c_threadsPerBlock-1)/c_threadsPerBlock; + config.gridSize[0] = (fRecvSize_ + c_threadsPerBlock - 1) / c_threadsPerBlock; config.gridSize[1] = 1; config.gridSize[2] = 1; config.sharedMemorySize = 0; config.stream = nonLocalStream_; - const float3 *recvBuf = d_recvBuf_; - const int *indexMap = d_indexMap_; - const int size = fRecvSize_; + const float3* recvBuf = d_recvBuf_; + const int* indexMap = d_indexMap_; + const int size = fRecvSize_; if (size > 0) { - auto kernelFn = accumulateForces ? unpackRecvBufKernel : unpackRecvBufKernel; + auto kernelFn = accumulateForces ? unpackRecvBufKernel : unpackRecvBufKernel; - const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &d_f, - &recvBuf, &indexMap, - &size); + const auto kernelArgs = + prepareGpuKernelArguments(kernelFn, config, &d_f, &recvBuf, &indexMap, &size); launchGpuKernel(kernelFn, config, nullptr, "Domdec GPU Apply F Halo Exchange", kernelArgs); } } -void GpuHaloExchange::Impl::communicateHaloData(float3 * d_ptr, - HaloQuantity haloQuantity) +void GpuHaloExchange::Impl::communicateHaloData(float3* d_ptr, HaloQuantity haloQuantity) { - void * sendPtr; - int sendSize; - void * remotePtr; - int sendRank; - int recvRank; + void* sendPtr; + int sendSize; + void* remotePtr; + int sendRank; + int recvRank; if (haloQuantity == HaloQuantity::HaloCoordinates) { - sendPtr = static_cast (d_sendBuf_); + sendPtr = static_cast(d_sendBuf_); sendSize = xSendSize_; remotePtr = remoteXPtr_; sendRank = sendRankX_; recvRank = recvRankX_; #if GMX_MPI - //Wait for signal from receiving task that it is ready, and similarly send signal to task that will push data to this task + // Wait for signal from receiving task that it is ready, and similarly send signal to task that will push data to this task char thisTaskIsReady, remoteTaskIsReady; - MPI_Sendrecv(&thisTaskIsReady, sizeof(char), MPI_BYTE, recvRank, 0, - &remoteTaskIsReady, sizeof(char), MPI_BYTE, sendRank, 0, - mpi_comm_mysim_, MPI_STATUS_IGNORE); + MPI_Sendrecv(&thisTaskIsReady, sizeof(char), MPI_BYTE, recvRank, 0, &remoteTaskIsReady, + sizeof(char), MPI_BYTE, sendRank, 0, mpi_comm_mysim_, MPI_STATUS_IGNORE); #endif } else { - sendPtr = static_cast (&(d_ptr[numHomeAtoms_])); + sendPtr = static_cast(&(d_ptr[numHomeAtoms_])); sendSize = fSendSize_; remotePtr = remoteFPtr_; sendRank = sendRankF_; @@ -336,10 +328,10 @@ void GpuHaloExchange::Impl::communicateHaloData(float3 * d_ptr, communicateHaloDataWithCudaDirect(sendPtr, sendSize, sendRank, remotePtr, recvRank); } -void GpuHaloExchange::Impl::communicateHaloDataWithCudaDirect(void *sendPtr, +void GpuHaloExchange::Impl::communicateHaloDataWithCudaDirect(void* sendPtr, int sendSize, int sendRank, - void *remotePtr, + void* remotePtr, int recvRank) { @@ -355,16 +347,17 @@ void GpuHaloExchange::Impl::communicateHaloDataWithCudaDirect(void *sendPtr, // send data to neighbor, if any data exists to send if (sendSize > 0) { - stat = cudaMemcpyAsync(remotePtr, sendPtr, sendSize*DIM*sizeof(float), cudaMemcpyDeviceToDevice, stream); + stat = cudaMemcpyAsync(remotePtr, sendPtr, sendSize * DIM * sizeof(float), + cudaMemcpyDeviceToDevice, stream); CU_RET_ERR(stat, "cudaMemcpyAsync on GPU Domdec CUDA direct data transfer failed"); } #if GMX_MPI - //ensure pushed data has arrived before remote rank progresses + // ensure pushed data has arrived before remote rank progresses // This rank records an event and sends it to the remote rank which has just been pushed data. - // This rank recieves event from remote rank which has pushed data here, and enqueues that event to - // its stream. - GpuEventSynchronizer *haloDataTransferRemote; + // This rank recieves event from remote rank which has pushed data here, and enqueues that event + // to its stream. + GpuEventSynchronizer* haloDataTransferRemote; haloDataTransferLaunched_->markEvent(stream); @@ -377,27 +370,24 @@ void GpuHaloExchange::Impl::communicateHaloDataWithCudaDirect(void *sendPtr, GMX_UNUSED_VALUE(sendRank); GMX_UNUSED_VALUE(recvRank); #endif - } /*! \brief Create Domdec GPU object */ -GpuHaloExchange::Impl::Impl(gmx_domdec_t *dd, - MPI_Comm mpi_comm_mysim, - void * localStream, - void * nonLocalStream) - : dd_(dd), - sendRankX_(dd->neighbor[0][1]), - recvRankX_(dd->neighbor[0][0]), - sendRankF_(dd->neighbor[0][0]), - recvRankF_(dd->neighbor[0][1]), - usePBC_(dd->ci[dd->dim[0]] == 0), - haloDataTransferLaunched_(new GpuEventSynchronizer()), - mpi_comm_mysim_(mpi_comm_mysim), - localStream_(*static_cast (localStream)), - nonLocalStream_(*static_cast (nonLocalStream)) +GpuHaloExchange::Impl::Impl(gmx_domdec_t* dd, MPI_Comm mpi_comm_mysim, void* localStream, void* nonLocalStream) : + dd_(dd), + sendRankX_(dd->neighbor[0][1]), + recvRankX_(dd->neighbor[0][0]), + sendRankF_(dd->neighbor[0][0]), + recvRankF_(dd->neighbor[0][1]), + usePBC_(dd->ci[dd->dim[0]] == 0), + haloDataTransferLaunched_(new GpuEventSynchronizer()), + mpi_comm_mysim_(mpi_comm_mysim), + localStream_(*static_cast(localStream)), + nonLocalStream_(*static_cast(nonLocalStream)) { - GMX_RELEASE_ASSERT(GMX_THREAD_MPI, "GPU Halo exchange is currently only supported with thread-MPI enabled"); + GMX_RELEASE_ASSERT(GMX_THREAD_MPI, + "GPU Halo exchange is currently only supported with thread-MPI enabled"); if (dd->ndim > 1) { @@ -412,7 +402,6 @@ GpuHaloExchange::Impl::Impl(gmx_domdec_t *dd, changePinningPolicy(&h_indexMap_, gmx::PinningPolicy::PinnedIfSupported); allocateDeviceBuffer(&d_fShift_, 1, nullptr); - } GpuHaloExchange::Impl::~Impl() @@ -424,23 +413,21 @@ GpuHaloExchange::Impl::~Impl() delete haloDataTransferLaunched_; } -GpuHaloExchange::GpuHaloExchange(gmx_domdec_t *dd, - MPI_Comm mpi_comm_mysim, - void *localStream, - void *nonLocalStream) - : impl_(new Impl(dd, mpi_comm_mysim, localStream, nonLocalStream)) +GpuHaloExchange::GpuHaloExchange(gmx_domdec_t* dd, MPI_Comm mpi_comm_mysim, void* localStream, void* nonLocalStream) : + impl_(new Impl(dd, mpi_comm_mysim, localStream, nonLocalStream)) { } GpuHaloExchange::~GpuHaloExchange() = default; -void GpuHaloExchange::reinitHalo(DeviceBuffer d_coordinatesBuffer, - DeviceBuffer d_forcesBuffer) +void GpuHaloExchange::reinitHalo(DeviceBuffer d_coordinatesBuffer, DeviceBuffer d_forcesBuffer) { - impl_->reinitHalo(reinterpret_cast(d_coordinatesBuffer), reinterpret_cast(d_forcesBuffer)); + impl_->reinitHalo(reinterpret_cast(d_coordinatesBuffer), + reinterpret_cast(d_forcesBuffer)); } -void GpuHaloExchange::communicateHaloCoordinates(const matrix box, GpuEventSynchronizer *coordinatesReadyOnDeviceEvent) +void GpuHaloExchange::communicateHaloCoordinates(const matrix box, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) { impl_->communicateHaloCoordinates(box, coordinatesReadyOnDeviceEvent); } @@ -450,4 +437,4 @@ void GpuHaloExchange::communicateHaloForces(bool accumulateForces) impl_->communicateHaloForces(accumulateForces); } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/domdec/gpuhaloexchange_impl.cuh b/src/gromacs/domdec/gpuhaloexchange_impl.cuh index 2a41dcfa95..626810b04a 100644 --- a/src/gromacs/domdec/gpuhaloexchange_impl.cuh +++ b/src/gromacs/domdec/gpuhaloexchange_impl.cuh @@ -57,134 +57,123 @@ namespace gmx /*! \brief switch for whether coordinates or force halo is being applied */ enum class HaloQuantity { - HaloCoordinates, HaloForces + HaloCoordinates, + HaloForces }; /*! \internal \brief Class with interfaces and data for GPU Halo Exchange */ class GpuHaloExchange::Impl { - public: - /*! \brief Creates GPU Halo Exchange object. - * - * \param [inout] dd domdec structure - * \param [in] mpi_comm_mysim communicator used for simulation - * \param [in] localStream local NB CUDA stream - * \param [in] nonLocalStream non-local NB CUDA stream - */ - Impl(gmx_domdec_t *dd, - MPI_Comm mpi_comm_mysim, - void *localStream, - void *nonLocalStream); - ~Impl(); - - /*! \brief - * (Re-) Initialization for GPU halo exchange - * \param [in] d_coordinatesBuffer pointer to coordinates buffer in GPU memory - * \param [in] d_forcesBuffer pointer to forces buffer in GPU memory - */ - void reinitHalo(float3 *d_coordinatesBuffer, - float3 *d_forcesBuffer); - - - /*! \brief - * GPU halo exchange of coordinates buffer - * \param [in] box Coordinate box (from which shifts will be constructed) - * \param [in] coordinatesReadyOnDeviceEvent event recorded when coordinates have been copied to device - */ - void communicateHaloCoordinates(const matrix box, - GpuEventSynchronizer *coordinatesReadyOnDeviceEvent); - - /*! \brief GPU halo exchange of force buffer - * \param[in] accumulateForces True if forces should accumulate, otherwise they are set - */ - void communicateHaloForces(bool accumulateForces); - - private: - - /*! \brief Data transfer wrapper for GPU halo exchange - * \param [inout] d_ptr pointer to coordinates or force buffer in GPU memory - * \param [in] haloQuantity switch on whether X or F halo exchange is being performed - */ - void communicateHaloData(float3 *d_ptr, - HaloQuantity haloQuantity); - - /*! \brief Data transfer for GPU halo exchange using CUDA memcopies - * \param [inout] sendPtr address to send data from - * \param [in] sendSize number of atoms to be sent - * \param [in] sendRank rank to send data to - * \param [inout] remotePtr remote address to recv data - * \param [in] recvRank rank to recv data from - */ - void communicateHaloDataWithCudaDirect(void *sendPtr, - int sendSize, - int sendRank, - void * remotePtr, - int recvRank); - - //! Domain decomposition object - gmx_domdec_t *dd_ = nullptr; - //! map of indices to be sent from this rank - gmx::HostVector h_indexMap_; - //! device copy of index map - int *d_indexMap_ = nullptr; - //! number of elements in index map array - int indexMapSize_ = -1; - //! number of elements allocated in index map array - int indexMapSizeAlloc_ = -1; - //! device buffer for sending packed data - float3 *d_sendBuf_ = nullptr; - //! number of atoms in sendbuf array - int sendBufSize_ = -1; - //! number of atoms allocated in sendbuf array - int sendBufSizeAlloc_ = -1; - //! device buffer for receiving packed data - float3 *d_recvBuf_ = nullptr; - //! maximum size of packed buffer - int maxPackedBufferSize_ = 0; - //! number of atoms in recvbuf array - int recvBufSize_ = -1; - //! number of atoms allocated in recvbuf array - int recvBufSizeAlloc_ = -1; - //! rank to send data to for X - int sendRankX_ = 0; - //! rank to recv data from for X - int recvRankX_ = 0; - //! rank to send data to for F - int sendRankF_ = 0; - //! rank to recv data from for F - int recvRankF_ = 0; - //! send copy size from this rank for X - int xSendSize_ = 0; - //! recv copy size to this rank for X - int xRecvSize_ = 0; - //! send copy size from this rank for F - int fSendSize_ = 0; - //! recv copy size to this rank for F - int fRecvSize_ = 0; - //! number of home atoms - offset of local halo region - int numHomeAtoms_ = 0; - //! remote GPU coordinates buffer pointer for pushing data - void *remoteXPtr_ = nullptr; - //! remote GPU force buffer pointer for pushing data - void *remoteFPtr_ = nullptr; - //! Periodic Boundary Conditions for this rank - bool usePBC_ = false; - //! force shift buffer on device - float3 * d_fShift_ = nullptr; - //! Event triggered when halo transfer has been launched with direct CUD memory copy - GpuEventSynchronizer *haloDataTransferLaunched_ = nullptr; - //! MPI communicator used for simulation - MPI_Comm mpi_comm_mysim_; - //! CUDA stream for local non-bonded calculations - cudaStream_t localStream_ = nullptr; - //! CUDA stream for non-local non-bonded calculations - cudaStream_t nonLocalStream_ = nullptr; - //! full coordinates buffer in GPU memory - float3 *d_x_ = nullptr; - //! full forces buffer in GPU memory - float3 *d_f_ = nullptr; - +public: + /*! \brief Creates GPU Halo Exchange object. + * + * \param [inout] dd domdec structure + * \param [in] mpi_comm_mysim communicator used for simulation + * \param [in] localStream local NB CUDA stream + * \param [in] nonLocalStream non-local NB CUDA stream + */ + Impl(gmx_domdec_t* dd, MPI_Comm mpi_comm_mysim, void* localStream, void* nonLocalStream); + ~Impl(); + + /*! \brief + * (Re-) Initialization for GPU halo exchange + * \param [in] d_coordinatesBuffer pointer to coordinates buffer in GPU memory + * \param [in] d_forcesBuffer pointer to forces buffer in GPU memory + */ + void reinitHalo(float3* d_coordinatesBuffer, float3* d_forcesBuffer); + + + /*! \brief + * GPU halo exchange of coordinates buffer + * \param [in] box Coordinate box (from which shifts will be constructed) + * \param [in] coordinatesReadyOnDeviceEvent event recorded when coordinates have been copied to device + */ + void communicateHaloCoordinates(const matrix box, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); + + /*! \brief GPU halo exchange of force buffer + * \param[in] accumulateForces True if forces should accumulate, otherwise they are set + */ + void communicateHaloForces(bool accumulateForces); + +private: + /*! \brief Data transfer wrapper for GPU halo exchange + * \param [inout] d_ptr pointer to coordinates or force buffer in GPU memory + * \param [in] haloQuantity switch on whether X or F halo exchange is being performed + */ + void communicateHaloData(float3* d_ptr, HaloQuantity haloQuantity); + + /*! \brief Data transfer for GPU halo exchange using CUDA memcopies + * \param [inout] sendPtr address to send data from + * \param [in] sendSize number of atoms to be sent + * \param [in] sendRank rank to send data to + * \param [inout] remotePtr remote address to recv data + * \param [in] recvRank rank to recv data from + */ + void communicateHaloDataWithCudaDirect(void* sendPtr, int sendSize, int sendRank, void* remotePtr, int recvRank); + + //! Domain decomposition object + gmx_domdec_t* dd_ = nullptr; + //! map of indices to be sent from this rank + gmx::HostVector h_indexMap_; + //! device copy of index map + int* d_indexMap_ = nullptr; + //! number of elements in index map array + int indexMapSize_ = -1; + //! number of elements allocated in index map array + int indexMapSizeAlloc_ = -1; + //! device buffer for sending packed data + float3* d_sendBuf_ = nullptr; + //! number of atoms in sendbuf array + int sendBufSize_ = -1; + //! number of atoms allocated in sendbuf array + int sendBufSizeAlloc_ = -1; + //! device buffer for receiving packed data + float3* d_recvBuf_ = nullptr; + //! maximum size of packed buffer + int maxPackedBufferSize_ = 0; + //! number of atoms in recvbuf array + int recvBufSize_ = -1; + //! number of atoms allocated in recvbuf array + int recvBufSizeAlloc_ = -1; + //! rank to send data to for X + int sendRankX_ = 0; + //! rank to recv data from for X + int recvRankX_ = 0; + //! rank to send data to for F + int sendRankF_ = 0; + //! rank to recv data from for F + int recvRankF_ = 0; + //! send copy size from this rank for X + int xSendSize_ = 0; + //! recv copy size to this rank for X + int xRecvSize_ = 0; + //! send copy size from this rank for F + int fSendSize_ = 0; + //! recv copy size to this rank for F + int fRecvSize_ = 0; + //! number of home atoms - offset of local halo region + int numHomeAtoms_ = 0; + //! remote GPU coordinates buffer pointer for pushing data + void* remoteXPtr_ = nullptr; + //! remote GPU force buffer pointer for pushing data + void* remoteFPtr_ = nullptr; + //! Periodic Boundary Conditions for this rank + bool usePBC_ = false; + //! force shift buffer on device + float3* d_fShift_ = nullptr; + //! Event triggered when halo transfer has been launched with direct CUD memory copy + GpuEventSynchronizer* haloDataTransferLaunched_ = nullptr; + //! MPI communicator used for simulation + MPI_Comm mpi_comm_mysim_; + //! CUDA stream for local non-bonded calculations + cudaStream_t localStream_ = nullptr; + //! CUDA stream for non-local non-bonded calculations + cudaStream_t nonLocalStream_ = nullptr; + //! full coordinates buffer in GPU memory + float3* d_x_ = nullptr; + //! full forces buffer in GPU memory + float3* d_f_ = nullptr; }; } // namespace gmx diff --git a/src/gromacs/domdec/hashedmap.h b/src/gromacs/domdec/hashedmap.h index c12706f36f..32bc3ceb25 100644 --- a/src/gromacs/domdec/hashedmap.h +++ b/src/gromacs/domdec/hashedmap.h @@ -65,279 +65,261 @@ namespace gmx * Note that this basically implements a subset of the functionality of * std::unordered_map, but is an order of magnitude faster. */ -template +template class HashedMap { - private: - /*! \libinternal \brief Structure for the key/value hash table */ - struct hashEntry - { - int key = -1; /**< The key */ - T value; /**< The value(s) */ - int next = -1; /**< Index in the list of the next element with the same hash, -1 if none */ - }; - - /*! \brief The table size is set to at least this factor time the nr of keys */ - static constexpr float c_relTableSizeSetMin = 1.5; - /*! \brief Threshold for increasing the table size */ - static constexpr float c_relTableSizeThresholdMin = 1.3; - /*! \brief Threshold for decreasing the table size */ - static constexpr float c_relTableSizeThresholdMax = 3.5; - - /*! \brief Resizes the table - * - * \param[in] numElementsEstimate An estimate of the number of elements that will be stored +private: + /*! \libinternal \brief Structure for the key/value hash table */ + struct hashEntry + { + int key = -1; /**< The key */ + T value; /**< The value(s) */ + int next = -1; /**< Index in the list of the next element with the same hash, -1 if none */ + }; + + /*! \brief The table size is set to at least this factor time the nr of keys */ + static constexpr float c_relTableSizeSetMin = 1.5; + /*! \brief Threshold for increasing the table size */ + static constexpr float c_relTableSizeThresholdMin = 1.3; + /*! \brief Threshold for decreasing the table size */ + static constexpr float c_relTableSizeThresholdMax = 3.5; + + /*! \brief Resizes the table + * + * \param[in] numElementsEstimate An estimate of the number of elements that will be stored + */ + void resize(int numElementsEstimate) + { + GMX_RELEASE_ASSERT(numElements_ == 0, "Table needs to be empty for resize"); + + /* The fraction of table entries with 0 size lists is e^-f. + * The fraction of table entries with >=1 size lists is 1 - e^-f + * where f is: the #elements / tableSize + * The fraction of elements not in the direct list is: 1 - (1 - e^-f)/f. + * Thus the optimal table size is roughly double #elements. */ - void resize(int numElementsEstimate) + /* Make the hash table a power of 2 and at least 1.5 * #elements */ + int tableSize = 64; + while (tableSize <= INT_MAX / 2 + && static_cast(numElementsEstimate) * c_relTableSizeSetMin > tableSize) { - GMX_RELEASE_ASSERT(numElements_ == 0, "Table needs to be empty for resize"); - - /* The fraction of table entries with 0 size lists is e^-f. - * The fraction of table entries with >=1 size lists is 1 - e^-f - * where f is: the #elements / tableSize - * The fraction of elements not in the direct list is: 1 - (1 - e^-f)/f. - * Thus the optimal table size is roughly double #elements. + tableSize *= 2; + } + table_.resize(tableSize); + + /* Table size is a power of 2, so a binary mask gives the hash */ + bitMask_ = tableSize - 1; + startIndexForSpaceForListEntry_ = tableSize; + } + +public: + /*! \brief Constructor + * + * \param[in] numElementsEstimate An estimate of the number of elements that will be stored, used for optimizing initial performance + * + * Note that the estimate of the number of elements is only relevant + * for the performance up until the first call to clear(), after which + * table size is optimized based on the actual number of elements. + */ + HashedMap(int numElementsEstimate) { resize(numElementsEstimate); } + + /*! \brief Returns the number of elements */ + int size() const { return numElements_; } + + /*! \brief Returns the number of buckets, i.e. the number of possible hashes */ + int bucket_count() const { return bitMask_ + 1; } + +private: + /*! \brief Inserts or assigns a key and value + * + * \tparam allowAssign Sets whether assignment of a key that is present is allowed + * \param[in] key The key for the entry + * \param[in] value The value for the entry + * \throws InvalidInputError from a debug build when attempting to insert a duplicate key with \p allowAssign=true + */ + // cppcheck-suppress unusedPrivateFunction + template + void insert_assign(int key, const T& value) + { + size_t ind = (key & bitMask_); + + if (table_[ind].key >= 0) + { + /* Loop over the entries for this hash. + * If we find the matching key, return the value. */ - /* Make the hash table a power of 2 and at least 1.5 * #elements */ - int tableSize = 64; - while (tableSize <= INT_MAX/2 && - static_cast(numElementsEstimate)*c_relTableSizeSetMin > tableSize) + int ind_prev = ind; + if (table_[ind_prev].key == key) { - tableSize *= 2; + if (allowAssign) + { + table_[ind].value = value; + return; + } + else + { +// Note: This is performance critical, so we only throw in debug mode +#ifndef NDEBUG + GMX_THROW(InvalidInputError("Attempt to insert duplicate key")); +#endif + } } - table_.resize(tableSize); - - /* Table size is a power of 2, so a binary mask gives the hash */ - bitMask_ = tableSize - 1; - startIndexForSpaceForListEntry_ = tableSize; - } - - public: - /*! \brief Constructor - * - * \param[in] numElementsEstimate An estimate of the number of elements that will be stored, used for optimizing initial performance - * - * Note that the estimate of the number of elements is only relevant - * for the performance up until the first call to clear(), after which - * table size is optimized based on the actual number of elements. - */ - HashedMap(int numElementsEstimate) - { - resize(numElementsEstimate); - } - - /*! \brief Returns the number of elements */ - int size() const - { - return numElements_; - } - - /*! \brief Returns the number of buckets, i.e. the number of possible hashes */ - int bucket_count() const - { - return bitMask_ + 1; - } - - private: - /*! \brief Inserts or assigns a key and value - * - * \tparam allowAssign Sets whether assignment of a key that is present is allowed - * \param[in] key The key for the entry - * \param[in] value The value for the entry - * \throws InvalidInputError from a debug build when attempting to insert a duplicate key with \p allowAssign=true - */ - // cppcheck-suppress unusedPrivateFunction - template void insert_assign(int key, - const T &value) - { - size_t ind = (key & bitMask_); - - if (table_[ind].key >= 0) + while (table_[ind_prev].next >= 0) { - /* Loop over the entries for this hash. - * If we find the matching key, return the value. - */ - int ind_prev = ind; + ind_prev = table_[ind_prev].next; if (table_[ind_prev].key == key) { if (allowAssign) { - table_[ind].value = value; + table_[ind_prev].value = value; return; } else { -// Note: This is performance critical, so we only throw in debug mode #ifndef NDEBUG GMX_THROW(InvalidInputError("Attempt to insert duplicate key")); #endif } } - while (table_[ind_prev].next >= 0) - { - ind_prev = table_[ind_prev].next; - if (table_[ind_prev].key == key) - { - if (allowAssign) - { - table_[ind_prev].value = value; - return; - } - else - { -#ifndef NDEBUG - GMX_THROW(InvalidInputError("Attempt to insert duplicate key")); -#endif - } - } - } - /* Search for space in table_ */ - ind = startIndexForSpaceForListEntry_; - while (ind < table_.size() && table_[ind].key >= 0) - { - ind++; - } - /* If we are at the end of the list we need to increase the size */ - if (ind == table_.size()) - { - table_.resize(table_.size() + 1); - } - table_[ind_prev].next = ind; - - startIndexForSpaceForListEntry_ = ind + 1; } + /* Search for space in table_ */ + ind = startIndexForSpaceForListEntry_; + while (ind < table_.size() && table_[ind].key >= 0) + { + ind++; + } + /* If we are at the end of the list we need to increase the size */ + if (ind == table_.size()) + { + table_.resize(table_.size() + 1); + } + table_[ind_prev].next = ind; - table_[ind].key = key; - table_[ind].value = value; - - numElements_ += 1; - } - - public: - /*! \brief Inserts entry, key should not already be present - * - * \param[in] key The key for the entry - * \param[in] value The value for the entry - * \throws InvalidInputError from a debug build when attempting to inser */ - void insert(int key, - const T &value) - { - insert_assign(key, value); - } - - /*! \brief Inserts an entry when the key is not present, otherwise sets the value - * - * \param[in] key The key for the entry - * \param[in] value The value for the entry - */ - void insert_or_assign(int key, - const T &value) - { - insert_assign(key, value); + startIndexForSpaceForListEntry_ = ind + 1; } - /*! \brief Delete the entry for key \p key, when present - * - * \param[in] key The key - */ - void erase(int key) + table_[ind].key = key; + table_[ind].value = value; + + numElements_ += 1; + } + +public: + /*! \brief Inserts entry, key should not already be present + * + * \param[in] key The key for the entry + * \param[in] value The value for the entry + * \throws InvalidInputError from a debug build when attempting to inser */ + void insert(int key, const T& value) { insert_assign(key, value); } + + /*! \brief Inserts an entry when the key is not present, otherwise sets the value + * + * \param[in] key The key for the entry + * \param[in] value The value for the entry + */ + void insert_or_assign(int key, const T& value) { insert_assign(key, value); } + + /*! \brief Delete the entry for key \p key, when present + * + * \param[in] key The key + */ + void erase(int key) + { + int ind_prev = -1; + int ind = (key & bitMask_); + do { - int ind_prev = -1; - int ind = (key & bitMask_); - do + if (table_[ind].key == key) { - if (table_[ind].key == key) + if (ind_prev >= 0) { - if (ind_prev >= 0) + table_[ind_prev].next = table_[ind].next; + + /* This index is a linked entry, so we free an entry. + * Check if we are creating the first empty space. + */ + if (ind < startIndexForSpaceForListEntry_) { - table_[ind_prev].next = table_[ind].next; - - /* This index is a linked entry, so we free an entry. - * Check if we are creating the first empty space. - */ - if (ind < startIndexForSpaceForListEntry_) - { - startIndexForSpaceForListEntry_ = ind; - } + startIndexForSpaceForListEntry_ = ind; } - table_[ind].key = -1; - table_[ind].next = -1; - - numElements_ -= 1; - - return; } - ind_prev = ind; - ind = table_[ind].next; - } - while (ind >= 0); - } + table_[ind].key = -1; + table_[ind].next = -1; - /*! \brief Returns a pointer to the value for the given key or nullptr when not present - * - * \param[in] key The key - * \return a pointer to value for the given key or nullptr when not present - */ - T *find(int key) { return const_cast(gmx::compat::as_const(*this).find(key)); } + numElements_ -= 1; - /*! \brief Returns a pointer to the value for the given key or nullptr when not present - * - * \param[in] key The key - * \return a pointer to value for the given key or nullptr when not present - */ - const T *find(int key) const + return; + } + ind_prev = ind; + ind = table_[ind].next; + } while (ind >= 0); + } + + /*! \brief Returns a pointer to the value for the given key or nullptr when not present + * + * \param[in] key The key + * \return a pointer to value for the given key or nullptr when not present + */ + T* find(int key) { return const_cast(gmx::compat::as_const(*this).find(key)); } + + /*! \brief Returns a pointer to the value for the given key or nullptr when not present + * + * \param[in] key The key + * \return a pointer to value for the given key or nullptr when not present + */ + const T* find(int key) const + { + int ind = (key & bitMask_); + do { - int ind = (key & bitMask_); - do + if (table_[ind].key == key) { - if (table_[ind].key == key) - { - return &table_[ind].value; - } - ind = table_[ind].next; + return &table_[ind].value; } - while (ind >= 0); - - return nullptr; + ind = table_[ind].next; + } while (ind >= 0); + + return nullptr; + } + + /*! \brief Clear all the entries in the list + * + * Also optimizes the size of the table based on the current + * number of elements stored. + */ + void clear() + { + const int oldNumElements = numElements_; + + for (hashEntry& entry : table_) + { + entry.key = -1; + entry.next = -1; } + startIndexForSpaceForListEntry_ = bucket_count(); + numElements_ = 0; - /*! \brief Clear all the entries in the list - * - * Also optimizes the size of the table based on the current - * number of elements stored. + /* Resize the hash table when the occupation is far from optimal. + * Do not resize with 0 elements to avoid minimal size when clear() + * is called twice in a row. */ - void clear() + if (oldNumElements > 0 + && (oldNumElements * c_relTableSizeThresholdMax < bucket_count() + || oldNumElements * c_relTableSizeThresholdMin > bucket_count())) { - const int oldNumElements = numElements_; - - for (hashEntry &entry : table_) - { - entry.key = -1; - entry.next = -1; - } - startIndexForSpaceForListEntry_ = bucket_count(); - numElements_ = 0; - - /* Resize the hash table when the occupation is far from optimal. - * Do not resize with 0 elements to avoid minimal size when clear() - * is called twice in a row. - */ - if (oldNumElements > 0 && (oldNumElements*c_relTableSizeThresholdMax < bucket_count() || - oldNumElements*c_relTableSizeThresholdMin > bucket_count())) - { - resize(oldNumElements); - } + resize(oldNumElements); } - - private: - /*! \brief The hash table list */ - std::vector table_; - /*! \brief The bit mask for computing the hash of a key */ - int bitMask_ = 0; - /*! \brief Index in table_ at which to start looking for empty space for a new linked list entry */ - int startIndexForSpaceForListEntry_ = 0; - /*! \brief The number of elements currently stored in the table */ - int numElements_ = 0; + } + +private: + /*! \brief The hash table list */ + std::vector table_; + /*! \brief The bit mask for computing the hash of a key */ + int bitMask_ = 0; + /*! \brief Index in table_ at which to start looking for empty space for a new linked list entry */ + int startIndexForSpaceForListEntry_ = 0; + /*! \brief The number of elements currently stored in the table */ + int numElements_ = 0; }; } // namespace gmx diff --git a/src/gromacs/domdec/localatomset.cpp b/src/gromacs/domdec/localatomset.cpp index 02271a296b..4e22e3eecd 100644 --- a/src/gromacs/domdec/localatomset.cpp +++ b/src/gromacs/domdec/localatomset.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,9 +48,7 @@ namespace gmx { -LocalAtomSet::LocalAtomSet(const internal::LocalAtomSetData &data) : data_(&data) -{ -} +LocalAtomSet::LocalAtomSet(const internal::LocalAtomSetData& data) : data_(&data) {} ArrayRef LocalAtomSet::globalIndex() const { diff --git a/src/gromacs/domdec/localatomset.h b/src/gromacs/domdec/localatomset.h index 6396505153..594c18b5c2 100644 --- a/src/gromacs/domdec/localatomset.h +++ b/src/gromacs/domdec/localatomset.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,7 @@ namespace gmx namespace internal { class LocalAtomSetData; -} // namespace internal +} // namespace internal /*! \libinternal \brief * A local atom set collects local, global and collective indices of * the home atoms on a rank. The indices of the home atoms are automatically @@ -67,55 +67,55 @@ class LocalAtomSetData; */ class LocalAtomSet { - public: - friend class LocalAtomSetManager; - /*! \brief Maps indices on rank [0..numAtomsLocal_) to global atom indicices. - * - * \returns the collective index. - */ - ArrayRef collectiveIndex() const; - /*! \brief Global indices of the atoms in this set. - * - * \note For best performance, store and use a local copy of the arrayref. - * - * \returns the global index. - */ - ArrayRef globalIndex() const; - /*! \brief Local indices of the atoms. - * - * For example, the i-th local atom coordinate of this set is - * x[atomSet.localIndex()[i]]. - * - * When using in a loop other than a range-based for loop, - * performance may improve if the ArrayRef is stored in - * a local variable before the loop is entered. - * Updated within domain-decomposition. - * - * \note For best performance, store and use a local copy of the ArrayRef. - * - * \returns the local index. - */ - ArrayRef localIndex() const; - /*! \brief The number of atoms from this group index on this rank. - * - * \note For best performance, store and use a local copy of the ArrayRef. - */ - std::size_t numAtomsLocal() const; - /*! \brief The number of all atoms from this group index on all ranks together. - * - * \note For best performance, store and use a local copy. - */ - std::size_t numAtomsGlobal() const; - private: - /*! \brief Constructs a new atom set by setting a reference to its - * internal data. - * \param[in] data The data for the atom set is stored - * in LocalAtomSetData, which is manged by \ref gmx::LocalAtomSetManager. - */ - explicit LocalAtomSet(const internal::LocalAtomSetData &data); +public: + friend class LocalAtomSetManager; + /*! \brief Maps indices on rank [0..numAtomsLocal_) to global atom indicices. + * + * \returns the collective index. + */ + ArrayRef collectiveIndex() const; + /*! \brief Global indices of the atoms in this set. + * + * \note For best performance, store and use a local copy of the arrayref. + * + * \returns the global index. + */ + ArrayRef globalIndex() const; + /*! \brief Local indices of the atoms. + * + * For example, the i-th local atom coordinate of this set is + * x[atomSet.localIndex()[i]]. + * + * When using in a loop other than a range-based for loop, + * performance may improve if the ArrayRef is stored in + * a local variable before the loop is entered. + * Updated within domain-decomposition. + * + * \note For best performance, store and use a local copy of the ArrayRef. + * + * \returns the local index. + */ + ArrayRef localIndex() const; + /*! \brief The number of atoms from this group index on this rank. + * + * \note For best performance, store and use a local copy of the ArrayRef. + */ + std::size_t numAtomsLocal() const; + /*! \brief The number of all atoms from this group index on all ranks together. + * + * \note For best performance, store and use a local copy. + */ + std::size_t numAtomsGlobal() const; - const internal::LocalAtomSetData * data_; +private: + /*! \brief Constructs a new atom set by setting a reference to its + * internal data. + * \param[in] data The data for the atom set is stored + * in LocalAtomSetData, which is manged by \ref gmx::LocalAtomSetManager. + */ + explicit LocalAtomSet(const internal::LocalAtomSetData& data); + const internal::LocalAtomSetData* data_; }; } // namespace gmx diff --git a/src/gromacs/domdec/localatomsetdata.cpp b/src/gromacs/domdec/localatomsetdata.cpp index 3d0e7d53b7..ef4ea7bb14 100644 --- a/src/gromacs/domdec/localatomsetdata.cpp +++ b/src/gromacs/domdec/localatomsetdata.cpp @@ -59,19 +59,19 @@ namespace internal */ LocalAtomSetData::LocalAtomSetData(ArrayRef globalIndex) : - globalIndex_(globalIndex.begin(), globalIndex.end()), localIndex_(globalIndex.begin(), globalIndex.end()) + globalIndex_(globalIndex.begin(), globalIndex.end()), + localIndex_(globalIndex.begin(), globalIndex.end()) { collectiveIndex_.resize(localIndex_.size()); std::iota(collectiveIndex_.begin(), collectiveIndex_.end(), 0); } -void -LocalAtomSetData::setLocalAndCollectiveIndices(const gmx_ga2la_t &ga2la) +void LocalAtomSetData::setLocalAndCollectiveIndices(const gmx_ga2la_t& ga2la) { /* Loop over all the atom indices of the set to check which ones are local. * cf. dd_make_local_group_indices in groupcoord.cpp */ - int numAtomsGlobal = globalIndex_.size(); + int numAtomsGlobal = globalIndex_.size(); /* Clear vector without changing capacity, * because we expect the size of the vectors to vary little. */ @@ -80,7 +80,7 @@ LocalAtomSetData::setLocalAndCollectiveIndices(const gmx_ga2la_t &ga2la) for (int iCollective = 0; iCollective < numAtomsGlobal; iCollective++) { - if (const int *iLocal = ga2la.findHome(globalIndex_[iCollective])) + if (const int* iLocal = ga2la.findHome(globalIndex_[iCollective])) { /* Save the atoms index in the local atom numbers array */ /* The atom with this index is a home atom. */ diff --git a/src/gromacs/domdec/localatomsetdata.h b/src/gromacs/domdec/localatomsetdata.h index 5665370fbd..c6dd2cb85e 100644 --- a/src/gromacs/domdec/localatomsetdata.h +++ b/src/gromacs/domdec/localatomsetdata.h @@ -60,64 +60,64 @@ namespace internal */ class LocalAtomSetData { - public: - /*! \brief Store the data for an atom set with an index group. - * - * Prior to domain decomposition, local atom indices are global atom indices - * and the collective index runs from 0..numberOfAtoms-1. - * local and collective indices will be updated in setLocalAndCollectiveIndices - * to match domain decompostion if domain decomposition is performed. - * - * \todo remove this constructor once all indices are represented - * as gmx::index instead of int. - * - * \note Not created if the internal int type does match gmx::index - * - * \param[in] globalAtomIndex Indices of the atoms to be managed - */ - template ::value, T> > - explicit LocalAtomSetData(ArrayRef globalAtomIndex) : - globalIndex_(globalAtomIndex.begin(), globalAtomIndex.end()), - localIndex_(globalAtomIndex.begin(), globalAtomIndex.end()) - { - collectiveIndex_.resize(localIndex_.size()); - std::iota(collectiveIndex_.begin(), collectiveIndex_.end(), 0); - } +public: + /*! \brief Store the data for an atom set with an index group. + * + * Prior to domain decomposition, local atom indices are global atom indices + * and the collective index runs from 0..numberOfAtoms-1. + * local and collective indices will be updated in setLocalAndCollectiveIndices + * to match domain decompostion if domain decomposition is performed. + * + * \todo remove this constructor once all indices are represented + * as gmx::index instead of int. + * + * \note Not created if the internal int type does match gmx::index + * + * \param[in] globalAtomIndex Indices of the atoms to be managed + */ + template::value, T>> + explicit LocalAtomSetData(ArrayRef globalAtomIndex) : + globalIndex_(globalAtomIndex.begin(), globalAtomIndex.end()), + localIndex_(globalAtomIndex.begin(), globalAtomIndex.end()) + { + collectiveIndex_.resize(localIndex_.size()); + std::iota(collectiveIndex_.begin(), collectiveIndex_.end(), 0); + } - /*! \brief Store the data for an atom set with an index group. - * - * Prior to domain decomposition, local atom indices are global atom indices - * and the collective index runs from 0..numberOfAtoms-1. - * local and collective indices will be updated in setLocalAndCollectiveIndices - * to match domain decompostion if domain decomposition is performed. - * - * \param[in] globalAtomIndex Indices of the atoms to be managed - */ - explicit LocalAtomSetData(ArrayRef globalAtomIndex); + /*! \brief Store the data for an atom set with an index group. + * + * Prior to domain decomposition, local atom indices are global atom indices + * and the collective index runs from 0..numberOfAtoms-1. + * local and collective indices will be updated in setLocalAndCollectiveIndices + * to match domain decompostion if domain decomposition is performed. + * + * \param[in] globalAtomIndex Indices of the atoms to be managed + */ + explicit LocalAtomSetData(ArrayRef globalAtomIndex); - /*! \brief Sets the local and collective indices from a lookup in ga2la. - * - * Calculate local and collective indices of home atoms, assuming a valid - * global atom to local atom look-up table. - * - * \param[in] ga2la lookup table that reports if an atom is local. - */ - void setLocalAndCollectiveIndices(const gmx_ga2la_t &ga2la); - /*! \brief Global indices of the atoms in this set. */ - const std::vector globalIndex_; - /*! \brief Maps indices on this rank [0..num_atoms_local_) to global atom indicices, - * so that localIndex[i] = globalIndex[collectiveIndex[i]]. - * - * This translation of locally dense atom data to global representation, - * allows to adresses per-atom properties, e.g., scattering factors, - * that are stored in a global continuous array for each atom of the atom set. - */ - std::vector collectiveIndex_; - /*! \brief Local indices of the atoms. - * Access the i-th local atom coordinate of this set by x[local_index_[i]]. - * Constructed and updated every domain-decomposition step. - */ - std::vector localIndex_; + /*! \brief Sets the local and collective indices from a lookup in ga2la. + * + * Calculate local and collective indices of home atoms, assuming a valid + * global atom to local atom look-up table. + * + * \param[in] ga2la lookup table that reports if an atom is local. + */ + void setLocalAndCollectiveIndices(const gmx_ga2la_t& ga2la); + /*! \brief Global indices of the atoms in this set. */ + const std::vector globalIndex_; + /*! \brief Maps indices on this rank [0..num_atoms_local_) to global atom indicices, + * so that localIndex[i] = globalIndex[collectiveIndex[i]]. + * + * This translation of locally dense atom data to global representation, + * allows to adresses per-atom properties, e.g., scattering factors, + * that are stored in a global continuous array for each atom of the atom set. + */ + std::vector collectiveIndex_; + /*! \brief Local indices of the atoms. + * Access the i-th local atom coordinate of this set by x[local_index_[i]]. + * Constructed and updated every domain-decomposition step. + */ + std::vector localIndex_; }; } // namespace internal @@ -125,6 +125,4 @@ class LocalAtomSetData } // namespace gmx - - #endif diff --git a/src/gromacs/domdec/localatomsetmanager.cpp b/src/gromacs/domdec/localatomsetmanager.cpp index 28c5d02c69..63a996485f 100644 --- a/src/gromacs/domdec/localatomsetmanager.cpp +++ b/src/gromacs/domdec/localatomsetmanager.cpp @@ -62,35 +62,33 @@ namespace gmx */ class LocalAtomSetManager::Impl { - public: - std::vector < std::unique_ptr < internal::LocalAtomSetData>> atomSetData_; /**< handles to the managed atom sets */ +public: + std::vector> atomSetData_; /**< handles to the managed atom sets */ }; /******************************************************************** * LocalAtomSetManager */ -LocalAtomSetManager::LocalAtomSetManager() : impl_(new Impl()) -{} +LocalAtomSetManager::LocalAtomSetManager() : impl_(new Impl()) {} -LocalAtomSetManager::~LocalAtomSetManager(){} +LocalAtomSetManager::~LocalAtomSetManager() {} -template<> LocalAtomSet LocalAtomSetManager::add(ArrayRef globalAtomIndex) +template<> +LocalAtomSet LocalAtomSetManager::add(ArrayRef globalAtomIndex) { impl_->atomSetData_.push_back(std::make_unique(globalAtomIndex)); return LocalAtomSet(*impl_->atomSetData_.back()); } -LocalAtomSet -LocalAtomSetManager::add(ArrayRef globalAtomIndex) +LocalAtomSet LocalAtomSetManager::add(ArrayRef globalAtomIndex) { impl_->atomSetData_.push_back(std::make_unique(globalAtomIndex)); return LocalAtomSet(*impl_->atomSetData_.back()); } -void -LocalAtomSetManager::setIndicesInDomainDecomposition(const gmx_ga2la_t &ga2la) +void LocalAtomSetManager::setIndicesInDomainDecomposition(const gmx_ga2la_t& ga2la) { - for (const auto &atomSet : impl_->atomSetData_) + for (const auto& atomSet : impl_->atomSetData_) { atomSet->setLocalAndCollectiveIndices(ga2la); } diff --git a/src/gromacs/domdec/localatomsetmanager.h b/src/gromacs/domdec/localatomsetmanager.h index 8d6aed5309..2c7bafed20 100644 --- a/src/gromacs/domdec/localatomsetmanager.h +++ b/src/gromacs/domdec/localatomsetmanager.h @@ -66,43 +66,43 @@ class LocalAtomSet; */ class LocalAtomSetManager { - public: - LocalAtomSetManager(); - ~LocalAtomSetManager(); +public: + LocalAtomSetManager(); + ~LocalAtomSetManager(); #ifndef DOXYGEN - /*! \brief Add a new atom set to be managed and give back a handle. - * - * \todo remove this routine once all indices are represented as - * gmx::index instead of int. - * - * \note Not created if the internal int type does match index - * - * \tparam T template parameter to use SFINAE for conditional function - * activation - * \tparam U template parameter for conditional function activation - * - * \param[in] globalAtomIndex Indices of the atoms to be managed - * \returns Handle to LocalAtomSet. - */ - template::value, T> > - LocalAtomSet add(ArrayRef globalAtomIndex); + /*! \brief Add a new atom set to be managed and give back a handle. + * + * \todo remove this routine once all indices are represented as + * gmx::index instead of int. + * + * \note Not created if the internal int type does match index + * + * \tparam T template parameter to use SFINAE for conditional function + * activation + * \tparam U template parameter for conditional function activation + * + * \param[in] globalAtomIndex Indices of the atoms to be managed + * \returns Handle to LocalAtomSet. + */ + template::value, T>> + LocalAtomSet add(ArrayRef globalAtomIndex); #endif - /*! \brief Add a new atom set to be managed and give back a handle. - * - * \param[in] globalAtomIndex Indices of the atoms to be managed - * \returns Handle to LocalAtomSet. - */ - LocalAtomSet add(ArrayRef globalAtomIndex); + /*! \brief Add a new atom set to be managed and give back a handle. + * + * \param[in] globalAtomIndex Indices of the atoms to be managed + * \returns Handle to LocalAtomSet. + */ + LocalAtomSet add(ArrayRef globalAtomIndex); - /*! \brief Recalculate local and collective indices from ga2la. - * Uses global atom to local atom lookup structure to - * update atom indices. - */ - void setIndicesInDomainDecomposition(const gmx_ga2la_t &ga2la); + /*! \brief Recalculate local and collective indices from ga2la. + * Uses global atom to local atom lookup structure to + * update atom indices. + */ + void setIndicesInDomainDecomposition(const gmx_ga2la_t& ga2la); - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/domdec/mdsetup.cpp b/src/gromacs/domdec/mdsetup.cpp index 22a084ed46..5ba8445574 100644 --- a/src/gromacs/domdec/mdsetup.cpp +++ b/src/gromacs/domdec/mdsetup.cpp @@ -58,21 +58,21 @@ * The final solution should be an MD algorithm base class with methods * for initialization and atom-data setup. */ -void mdAlgorithmsSetupAtomData(const t_commrec *cr, - const t_inputrec *ir, - const gmx_mtop_t &top_global, - gmx_localtop_t *top, - t_forcerec *fr, - t_graph **graph, - gmx::MDAtoms *mdAtoms, - gmx::Constraints *constr, - gmx_vsite_t *vsite, - gmx_shellfc_t *shellfc) +void mdAlgorithmsSetupAtomData(const t_commrec* cr, + const t_inputrec* ir, + const gmx_mtop_t& top_global, + gmx_localtop_t* top, + t_forcerec* fr, + t_graph** graph, + gmx::MDAtoms* mdAtoms, + gmx::Constraints* constr, + gmx_vsite_t* vsite, + gmx_shellfc_t* shellfc) { - bool usingDomDec = DOMAINDECOMP(cr); + bool usingDomDec = DOMAINDECOMP(cr); - int numAtomIndex, numHomeAtoms; - int *atomIndex; + int numAtomIndex, numHomeAtoms; + int* atomIndex; if (usingDomDec) { @@ -105,8 +105,7 @@ void mdAlgorithmsSetupAtomData(const t_commrec *cr, /* The vsites were already assigned by the domdec topology code. * We only need to do the thread division here. */ - split_vsites_over_threads(top->idef.il, top->idef.iparams, - mdatoms, vsite); + split_vsites_over_threads(top->idef.il, top->idef.iparams, mdatoms, vsite); } else { @@ -136,10 +135,7 @@ void mdAlgorithmsSetupAtomData(const t_commrec *cr, make_local_shells(cr, mdatoms, shellfc); } - setup_bonded_threading(fr->bondedThreading, - fr->natoms_force, - fr->gpuBonded != nullptr, - top->idef); + setup_bonded_threading(fr->bondedThreading, fr->natoms_force, fr->gpuBonded != nullptr, top->idef); if (EEL_PME(fr->ic->eeltype) && (cr->duty & DUTY_PME)) { diff --git a/src/gromacs/domdec/mdsetup.h b/src/gromacs/domdec/mdsetup.h index ab8cd0110c..3752118133 100644 --- a/src/gromacs/domdec/mdsetup.h +++ b/src/gromacs/domdec/mdsetup.h @@ -58,7 +58,7 @@ namespace gmx { class Constraints; class MDAtoms; -} +} // namespace gmx /*! \brief Gets the local shell with domain decomposition * @@ -66,9 +66,7 @@ class MDAtoms; * \param[in] md The MD atom data * \param[in,out] shfc The shell/flexible-constraint data */ -void make_local_shells(const t_commrec *cr, - const t_mdatoms *md, - gmx_shellfc_t *shfc); +void make_local_shells(const t_commrec* cr, const t_mdatoms* md, gmx_shellfc_t* shfc); /*! \brief Sets atom data for several MD algorithms * @@ -88,15 +86,15 @@ void make_local_shells(const t_commrec *cr, * \param[in,out] vsite The virtual site data, can be NULL * \param[in,out] shellfc The shell/flexible-constraint data, can be NULL */ -void mdAlgorithmsSetupAtomData(const t_commrec *cr, - const t_inputrec *ir, - const gmx_mtop_t &top_global, - gmx_localtop_t *top, - t_forcerec *fr, - t_graph **graph, - gmx::MDAtoms *mdAtoms, - gmx::Constraints *constr, - gmx_vsite_t *vsite, - gmx_shellfc_t *shellfc); +void mdAlgorithmsSetupAtomData(const t_commrec* cr, + const t_inputrec* ir, + const gmx_mtop_t& top_global, + gmx_localtop_t* top, + t_forcerec* fr, + t_graph** graph, + gmx::MDAtoms* mdAtoms, + gmx::Constraints* constr, + gmx_vsite_t* vsite, + gmx_shellfc_t* shellfc); #endif diff --git a/src/gromacs/domdec/options.h b/src/gromacs/domdec/options.h index d5e06b7dce..0ed617f677 100644 --- a/src/gromacs/domdec/options.h +++ b/src/gromacs/domdec/options.h @@ -77,32 +77,32 @@ enum class DlbOption struct DomdecOptions { //! If true, check that all bonded interactions have been assigned to exactly one domain/rank. - bool checkBondedInteractions = true; + bool checkBondedInteractions = true; //! If true, don't communicate all atoms between the non-bonded cut-off and the larger bonded cut-off, but only those that have non-local bonded interactions. This significantly reduces the communication volume. - bool useBondedCommunication = true; + bool useBondedCommunication = true; //! The domain decomposition grid cell count, 0 means let domdec choose based on the number of ranks. - ivec numCells = {0}; + ivec numCells = { 0 }; //! The number of separate PME ranks requested, -1 = auto. - int numPmeRanks = -1; + int numPmeRanks = -1; //! Ordering of the PP and PME ranks, values from enum above. - DdRankOrder rankOrder = DdRankOrder::interleave; + DdRankOrder rankOrder = DdRankOrder::interleave; //! The minimum communication range, used for extended the communication range for bonded interactions (nm). - real minimumCommunicationRange = 0; + real minimumCommunicationRange = 0; //! Communication range for atom involved in constraints (P-LINCS) (nm). - real constraintCommunicationRange = 0; + real constraintCommunicationRange = 0; //! Dynamic load balancing option, values from enum above. - DlbOption dlbOption = DlbOption::turnOnWhenUseful; + DlbOption dlbOption = DlbOption::turnOnWhenUseful; /*! \brief Fraction in (0,1) by whose reciprocal the initial * DD cell size will be increased in order to provide a margin * in which dynamic load balancing can act, while preserving * the minimum cell size. */ - real dlbScaling = 0.8; + real dlbScaling = 0.8; //! String containing a vector of the relative sizes in the x direction of the corresponding DD cells. - const char *cellSizeX = nullptr; + const char* cellSizeX = nullptr; //! String containing a vector of the relative sizes in the y direction of the corresponding DD cells. - const char *cellSizeY = nullptr; + const char* cellSizeY = nullptr; //! String containing a vector of the relative sizes in the z direction of the corresponding DD cells. - const char *cellSizeZ = nullptr; + const char* cellSizeZ = nullptr; }; } // namespace gmx diff --git a/src/gromacs/domdec/partition.cpp b/src/gromacs/domdec/partition.cpp index 8282b239dc..dbd52b2049 100644 --- a/src/gromacs/domdec/partition.cpp +++ b/src/gromacs/domdec/partition.cpp @@ -107,20 +107,19 @@ * There is a bit of overhead with DLB and it's difficult to achieve * a load imbalance of less than 2% with DLB. */ -#define DD_PERF_LOSS_DLB_ON 0.02 +#define DD_PERF_LOSS_DLB_ON 0.02 //! Warn about imbalance due to PP or PP/PME load imbalance at this loss. -#define DD_PERF_LOSS_WARN 0.05 +#define DD_PERF_LOSS_WARN 0.05 //! Debug helper printing a DD zone -static void print_ddzone(FILE *fp, int d, int i, int j, gmx_ddzone_t *zone) +static void print_ddzone(FILE* fp, int d, int i, int j, gmx_ddzone_t* zone) { - fprintf(fp, "zone d0 %d d1 %d d2 %d min0 %6.3f max1 %6.3f mch0 %6.3f mch1 %6.3f p1_0 %6.3f p1_1 %6.3f\n", - d, i, j, - zone->min0, zone->max1, - zone->mch0, zone->mch0, - zone->p1_0, zone->p1_1); + fprintf(fp, + "zone d0 %d d1 %d d2 %d min0 %6.3f max1 %6.3f mch0 %6.3f mch1 %6.3f p1_0 %6.3f p1_1 " + "%6.3f\n", + d, i, j, zone->min0, zone->max1, zone->mch0, zone->mch0, zone->p1_0, zone->p1_1); } /*! \brief Using the home grid size as input in cell_ns_x0 and cell_ns_x1 @@ -128,23 +127,20 @@ static void print_ddzone(FILE *fp, int d, int i, int j, gmx_ddzone_t *zone) * and returns the results in cell_ns_x0 and cell_ns_x1. * Note: only used with the group cut-off scheme. */ -static void dd_move_cellx(gmx_domdec_t *dd, - const gmx_ddbox_t *ddbox, - rvec cell_ns_x0, - rvec cell_ns_x1) +static void dd_move_cellx(gmx_domdec_t* dd, const gmx_ddbox_t* ddbox, rvec cell_ns_x0, rvec cell_ns_x1) { constexpr int c_ddZoneCommMaxNumZones = 5; gmx_ddzone_t buf_s[c_ddZoneCommMaxNumZones]; gmx_ddzone_t buf_r[c_ddZoneCommMaxNumZones]; gmx_ddzone_t buf_e[c_ddZoneCommMaxNumZones]; - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; - rvec extr_s[2]; - rvec extr_r[2]; + rvec extr_s[2]; + rvec extr_r[2]; for (int d = 1; d < dd->ndim; d++) { int dim = dd->dim[d]; - gmx_ddzone_t &zp = (d == 1) ? comm->zone_d1[0] : comm->zone_d2[0][0]; + gmx_ddzone_t& zp = (d == 1) ? comm->zone_d1[0] : comm->zone_d2[0][0]; /* Copy the base sizes of the home zone */ zp.min0 = cell_ns_x0[dim]; @@ -177,16 +173,16 @@ static void dd_move_cellx(gmx_domdec_t *dd, /* Store the extremes in the backward sending buffer, * so they get updated separately from the forward communication. */ - for (int d1 = d; d1 < dd->ndim-1; d1++) + for (int d1 = d; d1 < dd->ndim - 1; d1++) { - gmx_ddzone_t &buf = buf_s[pos]; + gmx_ddzone_t& buf = buf_s[pos]; /* We invert the order to be able to use the same loop for buf_e */ - buf.min0 = extr_s[d1][1]; - buf.max1 = extr_s[d1][0]; - buf.min1 = extr_s[d1][2]; - buf.mch0 = 0; - buf.mch1 = 0; + buf.min0 = extr_s[d1][1]; + buf.max1 = extr_s[d1][0]; + buf.min1 = extr_s[d1][2]; + buf.mch0 = 0; + buf.mch1 = 0; /* Store the cell corner of the dimension we communicate along */ buf.p1_0 = comm->cell_x0[dim]; buf.p1_1 = 0; @@ -229,10 +225,8 @@ static void dd_move_cellx(gmx_domdec_t *dd, /* Communicate the extremes forward */ bool receiveValidData = (applyPbc || dd->ci[dim] > 0); - int numElements = dd->ndim - d - 1; - ddSendrecv(dd, d, dddirForward, - extr_s + d, numElements, - extr_r + d, numElements); + int numElements = dd->ndim - d - 1; + ddSendrecv(dd, d, dddirForward, extr_s + d, numElements, extr_r + d, numElements); if (receiveValidData) { @@ -251,11 +245,12 @@ static void dd_move_cellx(gmx_domdec_t *dd, /* Communicate all the zone information backward */ bool receiveValidData = (applyPbc || dd->ci[dim] < dd->nc[dim] - 1); - static_assert(sizeof(gmx_ddzone_t) == c_ddzoneNumReals*sizeof(real), "Here we expect gmx_ddzone_t to consist of c_ddzoneNumReals reals (only)"); + static_assert( + sizeof(gmx_ddzone_t) == c_ddzoneNumReals * sizeof(real), + "Here we expect gmx_ddzone_t to consist of c_ddzoneNumReals reals (only)"); - int numReals = numElementsInBuffer*c_ddzoneNumReals; - ddSendrecv(dd, d, dddirBackward, - gmx::arrayRefFromArray(&buf_s[0].min0, numReals), + int numReals = numElementsInBuffer * c_ddzoneNumReals; + ddSendrecv(dd, d, dddirBackward, gmx::arrayRefFromArray(&buf_s[0].min0, numReals), gmx::arrayRefFromArray(&buf_r[0].min0, numReals)); rvec dh = { 0 }; @@ -281,10 +276,10 @@ static void dd_move_cellx(gmx_domdec_t *dd, { c = 0; } - real det = (1 + c*c)*gmx::square(comm->systemInfo.cutoff) - dist_d*dist_d; + real det = (1 + c * c) * gmx::square(comm->systemInfo.cutoff) - dist_d * dist_d; if (det > 0) { - dh[d1] = comm->systemInfo.cutoff - (c*dist_d + std::sqrt(det))/(1 + c*c); + dh[d1] = comm->systemInfo.cutoff - (c * dist_d + std::sqrt(det)) / (1 + c * c); } else { @@ -321,8 +316,8 @@ static void dd_move_cellx(gmx_domdec_t *dd, } if (receiveValidData && dh[d1] >= 0) { - buf_e[i].mch0 = std::max(buf_e[i].mch0, buf_r[i].mch0-dh[d1]); - buf_e[i].mch1 = std::max(buf_e[i].mch1, buf_r[i].mch1-dh[d1]); + buf_e[i].mch0 = std::max(buf_e[i].mch0, buf_r[i].mch0 - dh[d1]); + buf_e[i].mch1 = std::max(buf_e[i].mch1, buf_r[i].mch1 - dh[d1]); } } /* Copy the received buffer to the send buffer, @@ -330,13 +325,13 @@ static void dd_move_cellx(gmx_domdec_t *dd, */ buf_s[i] = buf_r[i]; } - if (((applyPbc || dd->ci[dim] + numPulses < dd->nc[dim]) && pulse == numPulses - 1) || - (!applyPbc && dd->ci[dim] + 1 + pulse == dd->nc[dim] - 1)) + if (((applyPbc || dd->ci[dim] + numPulses < dd->nc[dim]) && pulse == numPulses - 1) + || (!applyPbc && dd->ci[dim] + 1 + pulse == dd->nc[dim] - 1)) { /* Store the extremes */ int pos = 0; - for (int d1 = d; d1 < dd->ndim-1; d1++) + for (int d1 = d; d1 < dd->ndim - 1; d1++) { extr_s[d1][1] = std::min(extr_s[d1][1], buf_e[pos].min0); extr_s[d1][0] = std::max(extr_s[d1][0], buf_e[pos].max1); @@ -348,7 +343,7 @@ static void dd_move_cellx(gmx_domdec_t *dd, { for (int i = d; i < 2; i++) { - comm->zone_d2[1-d][i] = buf_e[pos]; + comm->zone_d2[1 - d][i] = buf_e[pos]; pos++; } } @@ -412,26 +407,26 @@ static void dd_move_cellx(gmx_domdec_t *dd, } for (int d = 1; d < dd->ndim; d++) { - cellsizes[d].fracLowerMax = extr_s[d-1][0]; - cellsizes[d].fracUpperMin = extr_s[d-1][1]; + cellsizes[d].fracLowerMax = extr_s[d - 1][0]; + cellsizes[d].fracUpperMin = extr_s[d - 1][1]; if (debug) { - fprintf(debug, "Cell fraction d %d, max0 %f, min1 %f\n", - d, cellsizes[d].fracLowerMax, cellsizes[d].fracUpperMin); + fprintf(debug, "Cell fraction d %d, max0 %f, min1 %f\n", d, cellsizes[d].fracLowerMax, + cellsizes[d].fracUpperMin); } } } //! Sets the charge-group zones to be equal to the home zone. -static void set_zones_ncg_home(gmx_domdec_t *dd) +static void set_zones_ncg_home(gmx_domdec_t* dd) { - gmx_domdec_zones_t *zones; + gmx_domdec_zones_t* zones; int i; zones = &dd->comm->zones; zones->cg_range[0] = 0; - for (i = 1; i < zones->n+1; i++) + for (i = 1; i < zones->n + 1; i++) { zones->cg_range[i] = dd->ncg_home; } @@ -440,12 +435,11 @@ static void set_zones_ncg_home(gmx_domdec_t *dd) } //! Restore atom groups for the charge groups. -static void restoreAtomGroups(gmx_domdec_t *dd, - const t_state *state) +static void restoreAtomGroups(gmx_domdec_t* dd, const t_state* state) { - gmx::ArrayRef atomGroupsState = state->cg_gl; + gmx::ArrayRef atomGroupsState = state->cg_gl; - std::vector &globalAtomGroupIndices = dd->globalAtomGroupIndices; + std::vector& globalAtomGroupIndices = dd->globalAtomGroupIndices; globalAtomGroupIndices.resize(atomGroupsState.size()); @@ -464,12 +458,11 @@ static void restoreAtomGroups(gmx_domdec_t *dd, } //! Sets the cginfo structures. -static void dd_set_cginfo(gmx::ArrayRef index_gl, int cg0, int cg1, - t_forcerec *fr) +static void dd_set_cginfo(gmx::ArrayRef index_gl, int cg0, int cg1, t_forcerec* fr) { if (fr != nullptr) { - const cginfo_mb_t *cginfo_mb = fr->cginfo_mb; + const cginfo_mb_t* cginfo_mb = fr->cginfo_mb; gmx::ArrayRef cginfo = fr->cginfo; for (int cg = cg0; cg < cg1; cg++) @@ -480,16 +473,15 @@ static void dd_set_cginfo(gmx::ArrayRef index_gl, int cg0, int cg1, } //! Makes the mappings between global and local atom indices during DD repartioning. -static void make_dd_indices(gmx_domdec_t *dd, - const int atomStart) +static void make_dd_indices(gmx_domdec_t* dd, const int atomStart) { - const int numZones = dd->comm->zones.n; - const int *zone2cg = dd->comm->zones.cg_range; - const int *zone_ncg1 = dd->comm->zone_ncg1; - gmx::ArrayRef globalAtomGroupIndices = dd->globalAtomGroupIndices; + const int numZones = dd->comm->zones.n; + const int* zone2cg = dd->comm->zones.cg_range; + const int* zone_ncg1 = dd->comm->zone_ncg1; + gmx::ArrayRef globalAtomGroupIndices = dd->globalAtomGroupIndices; - std::vector &globalAtomIndices = dd->globalAtomIndices; - gmx_ga2la_t &ga2la = *dd->ga2la; + std::vector& globalAtomIndices = dd->globalAtomIndices; + gmx_ga2la_t& ga2la = *dd->ga2la; if (zone2cg[1] != dd->ncg_home) { @@ -510,7 +502,7 @@ static void make_dd_indices(gmx_domdec_t *dd, { cg0 = zone2cg[zone]; } - int cg1 = zone2cg[zone+1]; + int cg1 = zone2cg[zone + 1]; int cg1_p1 = cg0 + zone_ncg1[zone]; for (int cg = cg0; cg < cg1; cg++) @@ -523,18 +515,16 @@ static void make_dd_indices(gmx_domdec_t *dd, } int cg_gl = globalAtomGroupIndices[cg]; globalAtomIndices.push_back(cg_gl); - ga2la.insert(cg_gl, {a, zone1}); + ga2la.insert(cg_gl, { a, zone1 }); a++; } } } //! Checks whether global and local atom indices are consistent. -static void check_index_consistency(const gmx_domdec_t *dd, - int natoms_sys, - const char *where) +static void check_index_consistency(const gmx_domdec_t* dd, int natoms_sys, const char* where) { - int nerr = 0; + int nerr = 0; const int numAtomsInZones = dd->comm->atomRanges.end(DDAtomRanges::Type::Zones); @@ -546,7 +536,8 @@ static void check_index_consistency(const gmx_domdec_t *dd, int globalAtomIndex = dd->globalAtomIndices[a]; if (have[globalAtomIndex] > 0) { - fprintf(stderr, "DD rank %d: global atom %d occurs twice: index %d and %d\n", dd->rank, globalAtomIndex + 1, have[globalAtomIndex], a+1); + fprintf(stderr, "DD rank %d: global atom %d occurs twice: index %d and %d\n", + dd->rank, globalAtomIndex + 1, have[globalAtomIndex], a + 1); } else { @@ -557,7 +548,7 @@ static void check_index_consistency(const gmx_domdec_t *dd, std::vector have(numAtomsInZones); - int ngl = 0; + int ngl = 0; for (int i = 0; i < natoms_sys; i++) { if (const auto entry = dd->ga2la->find(i)) @@ -565,7 +556,10 @@ static void check_index_consistency(const gmx_domdec_t *dd, const int a = entry->la; if (a >= numAtomsInZones) { - fprintf(stderr, "DD rank %d: global atom %d marked as local atom %d, which is larger than nat_tot (%d)\n", dd->rank, i+1, a+1, numAtomsInZones); + fprintf(stderr, + "DD rank %d: global atom %d marked as local atom %d, which is larger than " + "nat_tot (%d)\n", + dd->rank, i + 1, a + 1, numAtomsInZones); nerr++; } else @@ -573,7 +567,10 @@ static void check_index_consistency(const gmx_domdec_t *dd, have[a] = 1; if (dd->globalAtomIndices[a] != i) { - fprintf(stderr, "DD rank %d: global atom %d marked as local atom %d, which has global atom index %d\n", dd->rank, i+1, a+1, dd->globalAtomIndices[a]+1); + fprintf(stderr, + "DD rank %d: global atom %d marked as local atom %d, which has global " + "atom index %d\n", + dd->rank, i + 1, a + 1, dd->globalAtomIndices[a] + 1); nerr++; } } @@ -582,32 +579,28 @@ static void check_index_consistency(const gmx_domdec_t *dd, } if (ngl != numAtomsInZones) { - fprintf(stderr, - "DD rank %d, %s: %d global atom indices, %d local atoms\n", - dd->rank, where, ngl, numAtomsInZones); + fprintf(stderr, "DD rank %d, %s: %d global atom indices, %d local atoms\n", dd->rank, where, + ngl, numAtomsInZones); } for (int a = 0; a < numAtomsInZones; a++) { if (have[a] == 0) { - fprintf(stderr, - "DD rank %d, %s: local atom %d, global %d has no global index\n", + fprintf(stderr, "DD rank %d, %s: local atom %d, global %d has no global index\n", dd->rank, where, a + 1, dd->globalAtomIndices[a] + 1); } } if (nerr > 0) { - gmx_fatal(FARGS, "DD rank %d, %s: %d atom(group) index inconsistencies", - dd->rank, where, nerr); + gmx_fatal(FARGS, "DD rank %d, %s: %d atom(group) index inconsistencies", dd->rank, where, nerr); } } //! Clear all DD global state indices -static void clearDDStateIndices(gmx_domdec_t *dd, - const bool keepLocalAtomIndices) +static void clearDDStateIndices(gmx_domdec_t* dd, const bool keepLocalAtomIndices) { - gmx_ga2la_t &ga2la = *dd->ga2la; + gmx_ga2la_t& ga2la = *dd->ga2la; if (!keepLocalAtomIndices) { @@ -631,18 +624,14 @@ static void clearDDStateIndices(gmx_domdec_t *dd, } } -bool check_grid_jump(int64_t step, - const gmx_domdec_t *dd, - real cutoff, - const gmx_ddbox_t *ddbox, - gmx_bool bFatal) +bool check_grid_jump(int64_t step, const gmx_domdec_t* dd, real cutoff, const gmx_ddbox_t* ddbox, gmx_bool bFatal) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; bool invalid = false; for (int d = 1; d < dd->ndim; d++) { - const DDCellsizesWithDlb &cellsizes = comm->cellsizesWithDlb[d]; + const DDCellsizesWithDlb& cellsizes = comm->cellsizesWithDlb[d]; const int dim = dd->dim[d]; const real limit = grid_jump_limit(comm, cutoff, d); real bfac = ddbox->box_size[dim]; @@ -650,8 +639,8 @@ bool check_grid_jump(int64_t step, { bfac *= ddbox->skew_fac[dim]; } - if ((cellsizes.fracUpper - cellsizes.fracLowerMax)*bfac < limit || - (cellsizes.fracLower - cellsizes.fracUpperMin)*bfac > -limit) + if ((cellsizes.fracUpper - cellsizes.fracLowerMax) * bfac < limit + || (cellsizes.fracLower - cellsizes.fracUpperMin) * bfac > -limit) { invalid = true; @@ -662,9 +651,11 @@ bool check_grid_jump(int64_t step, /* This error should never be triggered under normal * circumstances, but you never know ... */ - gmx_fatal(FARGS, "step %s: The domain decomposition grid has shifted too much in the %c-direction around cell %d %d %d. This should not have happened. Running with fewer ranks might avoid this issue.", - gmx_step_str(step, buf), - dim2char(dim), dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); + gmx_fatal(FARGS, + "step %s: The domain decomposition grid has shifted too much in the " + "%c-direction around cell %d %d %d. This should not have happened. " + "Running with fewer ranks might avoid this issue.", + gmx_step_str(step, buf), dim2char(dim), dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); } } } @@ -672,7 +663,7 @@ bool check_grid_jump(int64_t step, return invalid; } //! Return the duration of force calculations on this rank. -static float dd_force_load(gmx_domdec_comm_t *comm) +static float dd_force_load(gmx_domdec_comm_t* comm) { float load; @@ -681,7 +672,7 @@ static float dd_force_load(gmx_domdec_comm_t *comm) load = comm->flop; if (comm->ddSettings.eFlop > 1) { - load *= 1.0 + (comm->ddSettings.eFlop - 1)*(0.1*rand()/RAND_MAX - 0.05); + load *= 1.0 + (comm->ddSettings.eFlop - 1) * (0.1 * rand() / RAND_MAX - 0.05); } } else @@ -715,13 +706,12 @@ static float dd_force_load(gmx_domdec_comm_t *comm) * is spurious CPU activity or MPI time, so we don't expect * that changes in the GPU wait time matter a lot here. */ - gpu_wait *= (comm->cycl_n[ddCyclF] - 1)/static_cast(comm->cycl_n[ddCyclF]); + gpu_wait *= (comm->cycl_n[ddCyclF] - 1) / static_cast(comm->cycl_n[ddCyclF]); } /* Sum the wait times over the ranks that share the same GPU */ - MPI_Allreduce(&gpu_wait, &gpu_wait_sum, 1, MPI_FLOAT, MPI_SUM, - comm->mpi_comm_gpu_shared); + MPI_Allreduce(&gpu_wait, &gpu_wait_sum, 1, MPI_FLOAT, MPI_SUM, comm->mpi_comm_gpu_shared); /* Replace the wait time by the average over the ranks */ - load += -gpu_wait + gpu_wait_sum/comm->nrank_gpu_shared; + load += -gpu_wait + gpu_wait_sum / comm->nrank_gpu_shared; } #endif } @@ -730,12 +720,9 @@ static float dd_force_load(gmx_domdec_comm_t *comm) } //! Runs cell size checks and communicates the boundaries. -static void comm_dd_ns_cell_sizes(gmx_domdec_t *dd, - gmx_ddbox_t *ddbox, - rvec cell_ns_x0, rvec cell_ns_x1, - int64_t step) +static void comm_dd_ns_cell_sizes(gmx_domdec_t* dd, gmx_ddbox_t* ddbox, rvec cell_ns_x0, rvec cell_ns_x1, int64_t step) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; int dim_ind, dim; comm = dd->comm; @@ -745,19 +732,18 @@ static void comm_dd_ns_cell_sizes(gmx_domdec_t *dd, dim = dd->dim[dim_ind]; /* Without PBC we don't have restrictions on the outer cells */ - if (!(dim >= ddbox->npbcdim && - (dd->ci[dim] == 0 || dd->ci[dim] == dd->nc[dim] - 1)) && - isDlbOn(comm) && - (comm->cell_x1[dim] - comm->cell_x0[dim])*ddbox->skew_fac[dim] < - comm->cellsize_min[dim]) + if (!(dim >= ddbox->npbcdim && (dd->ci[dim] == 0 || dd->ci[dim] == dd->nc[dim] - 1)) + && isDlbOn(comm) + && (comm->cell_x1[dim] - comm->cell_x0[dim]) * ddbox->skew_fac[dim] < comm->cellsize_min[dim]) { char buf[22]; - gmx_fatal(FARGS, "step %s: The %c-size (%f) times the triclinic skew factor (%f) is smaller than the smallest allowed cell size (%f) for domain decomposition grid cell %d %d %d", + gmx_fatal(FARGS, + "step %s: The %c-size (%f) times the triclinic skew factor (%f) is smaller " + "than the smallest allowed cell size (%f) for domain decomposition grid cell " + "%d %d %d", gmx_step_str(step, buf), dim2char(dim), - comm->cell_x1[dim] - comm->cell_x0[dim], - ddbox->skew_fac[dim], - dd->comm->cellsize_min[dim], - dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); + comm->cell_x1[dim] - comm->cell_x0[dim], ddbox->skew_fac[dim], + dd->comm->cellsize_min[dim], dd->ci[XX], dd->ci[YY], dd->ci[ZZ]); } } @@ -773,10 +759,10 @@ static void comm_dd_ns_cell_sizes(gmx_domdec_t *dd, } //! Compute and communicate to determine the load distribution across PP ranks. -static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) +static void get_load_distribution(gmx_domdec_t* dd, gmx_wallcycle_t wcycle) { - gmx_domdec_comm_t *comm; - domdec_load_t *load; + gmx_domdec_comm_t* comm; + domdec_load_t* load; float cell_frac = 0, sbuf[DD_NLOAD_MAX]; gmx_bool bSepPME; @@ -800,11 +786,10 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) for (int d = dd->ndim - 1; d >= 0; d--) { - const DDCellsizesWithDlb *cellsizes = (isDlbOn(dd->comm) ? &comm->cellsizesWithDlb[d] : nullptr); + const DDCellsizesWithDlb* cellsizes = (isDlbOn(dd->comm) ? &comm->cellsizesWithDlb[d] : nullptr); const int dim = dd->dim[d]; /* Check if we participate in the communication in this dimension */ - if (d == dd->ndim-1 || - (dd->ci[dd->dim[d+1]] == 0 && dd->ci[dd->dim[dd->ndim-1]] == 0)) + if (d == dd->ndim - 1 || (dd->ci[dd->dim[d + 1]] == 0 && dd->ci[dd->dim[dd->ndim - 1]] == 0)) { load = &comm->load[d]; if (isDlbOn(dd->comm)) @@ -812,7 +797,7 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) cell_frac = cellsizes->fracUpper - cellsizes->fracLower; } int pos = 0; - if (d == dd->ndim-1) + if (d == dd->ndim - 1) { sbuf[pos++] = dd_force_load(comm); sbuf[pos++] = sbuf[0]; @@ -834,13 +819,13 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) } else { - sbuf[pos++] = comm->load[d+1].sum; - sbuf[pos++] = comm->load[d+1].max; + sbuf[pos++] = comm->load[d + 1].sum; + sbuf[pos++] = comm->load[d + 1].max; if (isDlbOn(dd->comm)) { - sbuf[pos++] = comm->load[d+1].sum_m; - sbuf[pos++] = comm->load[d+1].cvol_min*cell_frac; - sbuf[pos++] = comm->load[d+1].flags; + sbuf[pos++] = comm->load[d + 1].sum_m; + sbuf[pos++] = comm->load[d + 1].cvol_min * cell_frac; + sbuf[pos++] = comm->load[d + 1].flags; if (d > 0) { sbuf[pos++] = cellsizes->fracLowerMax; @@ -849,8 +834,8 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) } if (bSepPME) { - sbuf[pos++] = comm->load[d+1].mdf; - sbuf[pos++] = comm->load[d+1].pme; + sbuf[pos++] = comm->load[d + 1].mdf; + sbuf[pos++] = comm->load[d + 1].pme; } } load->nload = pos; @@ -858,14 +843,13 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) * The communicators are setup such that the root always has rank 0. */ #if GMX_MPI - MPI_Gather(sbuf, load->nload*sizeof(float), MPI_BYTE, - load->load, load->nload*sizeof(float), MPI_BYTE, - 0, comm->mpi_comm_load[d]); + MPI_Gather(sbuf, load->nload * sizeof(float), MPI_BYTE, load->load, + load->nload * sizeof(float), MPI_BYTE, 0, comm->mpi_comm_load[d]); #endif if (dd->ci[dim] == dd->master_ci[dim]) { /* We are the master along this row, process this row */ - RowMaster *rowMaster = nullptr; + RowMaster* rowMaster = nullptr; if (isDlbOn(comm)) { @@ -882,7 +866,7 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) for (int i = 0; i < dd->nc[dim]; i++) { load->sum += load->load[pos++]; - load->max = std::max(load->max, load->load[pos]); + load->max = std::max(load->max, load->load[pos]); pos++; if (isDlbOn(dd->comm)) { @@ -900,7 +884,7 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) pos++; load->cvol_min = std::min(load->cvol_min, load->load[pos]); pos++; - if (d < dd->ndim-1) + if (d < dd->ndim - 1) { load->flags = gmx::roundToInt(load->load[pos++]); } @@ -921,7 +905,7 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) if (isDlbOn(comm) && rowMaster->dlbIsLimited) { load->sum_m *= dd->nc[dim]; - load->flags |= (1<flags |= (1 << d); } } } @@ -929,15 +913,15 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) if (DDMASTER(dd)) { - comm->nload += dd_load_count(comm); - comm->load_step += comm->cycl[ddCyclStep]; - comm->load_sum += comm->load[0].sum; - comm->load_max += comm->load[0].max; + comm->nload += dd_load_count(comm); + comm->load_step += comm->cycl[ddCyclStep]; + comm->load_sum += comm->load[0].sum; + comm->load_max += comm->load[0].max; if (isDlbOn(comm)) { for (int d = 0; d < dd->ndim; d++) { - if (comm->load[0].flags & (1<load[0].flags & (1 << d)) { comm->load_lim[d]++; } @@ -960,11 +944,11 @@ static void get_load_distribution(gmx_domdec_t *dd, gmx_wallcycle_t wcycle) /*! \brief Return the relative performance loss on the total run time * due to the force calculation load imbalance. */ -static float dd_force_load_fraction(gmx_domdec_t *dd) +static float dd_force_load_fraction(gmx_domdec_t* dd) { if (dd->comm->nload > 0 && dd->comm->load_step > 0) { - return dd->comm->load_sum/(dd->comm->load_step*dd->nnodes); + return dd->comm->load_sum / (dd->comm->load_step * dd->nnodes); } else { @@ -974,13 +958,11 @@ static float dd_force_load_fraction(gmx_domdec_t *dd) /*! \brief Return the relative performance loss on the total run time * due to the force calculation load imbalance. */ -static float dd_force_imb_perf_loss(gmx_domdec_t *dd) +static float dd_force_imb_perf_loss(gmx_domdec_t* dd) { if (dd->comm->nload > 0 && dd->comm->load_step > 0) { - return - (dd->comm->load_max*dd->nnodes - dd->comm->load_sum)/ - (dd->comm->load_step*dd->nnodes); + return (dd->comm->load_max * dd->nnodes - dd->comm->load_sum) / (dd->comm->load_step * dd->nnodes); } else { @@ -989,9 +971,9 @@ static float dd_force_imb_perf_loss(gmx_domdec_t *dd) } //! Print load-balance report e.g. at the end of a run. -static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) +static void print_dd_load_av(FILE* fplog, gmx_domdec_t* dd) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; /* Only the master rank prints loads and only if we measured loads */ if (!DDMASTER(dd) || comm->nload == 0) @@ -999,19 +981,19 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) return; } - char buf[STRLEN]; - int numPpRanks = dd->nnodes; - int numPmeRanks = (comm->ddRankSetup.usePmeOnlyRanks ? comm->ddRankSetup.numRanksDoingPme : 0); - int numRanks = numPpRanks + numPmeRanks; + char buf[STRLEN]; + int numPpRanks = dd->nnodes; + int numPmeRanks = (comm->ddRankSetup.usePmeOnlyRanks ? comm->ddRankSetup.numRanksDoingPme : 0); + int numRanks = numPpRanks + numPmeRanks; float lossFraction = 0; /* Print the average load imbalance and performance loss */ if (dd->nnodes > 1 && comm->load_sum > 0) { - float imbalance = comm->load_max*numPpRanks/comm->load_sum - 1; + float imbalance = comm->load_max * numPpRanks / comm->load_sum - 1; lossFraction = dd_force_imb_perf_loss(dd); - std::string msg = "\nDynamic load balancing report:\n"; + std::string msg = "\nDynamic load balancing report:\n"; std::string dlbStateStr; switch (dd->comm->dlbState) @@ -1029,7 +1011,9 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) dlbStateStr = "DLB was off during the run due to low measured imbalance."; break; case DlbState::offTemporarilyLocked: - dlbStateStr = "DLB was locked at the end of the run due to unfinished PP-PME balancing."; + dlbStateStr = + "DLB was locked at the end of the run due to unfinished PP-PME " + "balancing."; break; case DlbState::onCanTurnOff: dlbStateStr = "DLB was turned on during the run due to measured imbalance."; @@ -1037,16 +1021,18 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) case DlbState::onUser: dlbStateStr = "DLB was permanently on during the run per user request."; break; - default: - GMX_ASSERT(false, "Undocumented DLB state"); + default: GMX_ASSERT(false, "Undocumented DLB state"); } msg += " " + dlbStateStr + "\n"; - msg += gmx::formatString(" Average load imbalance: %.1f%%.\n", imbalance*100); - msg += gmx::formatString(" The balanceable part of the MD step is %d%%, load imbalance is computed from this.\n", - gmx::roundToInt(dd_force_load_fraction(dd)*100)); - msg += gmx::formatString(" Part of the total run time spent waiting due to load imbalance: %.1f%%.\n", - lossFraction*100); + msg += gmx::formatString(" Average load imbalance: %.1f%%.\n", imbalance * 100); + msg += gmx::formatString( + " The balanceable part of the MD step is %d%%, load imbalance is computed from " + "this.\n", + gmx::roundToInt(dd_force_load_fraction(dd) * 100)); + msg += gmx::formatString( + " Part of the total run time spent waiting due to load imbalance: %.1f%%.\n", + lossFraction * 100); fprintf(fplog, "%s", msg.c_str()); fprintf(stderr, "\n%s", msg.c_str()); } @@ -1058,9 +1044,8 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) sprintf(buf, " Steps where the load balancing was limited by -rdd, -rcon and/or -dds:"); for (int d = 0; d < dd->ndim; d++) { - int limitPercentage = (200*comm->load_lim[d] + 1)/(2*comm->nload); - sprintf(buf+strlen(buf), " %c %d %%", - dim2char(dd->dim[d]), limitPercentage); + int limitPercentage = (200 * comm->load_lim[d] + 1) / (2 * comm->nload); + sprintf(buf + strlen(buf), " %c %d %%", dim2char(dd->dim[d]), limitPercentage); if (limitPercentage >= 50) { dlbWasLimited = true; @@ -1075,20 +1060,21 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) float lossFractionPme = 0; if (numPmeRanks > 0 && comm->load_mdf > 0 && comm->load_step > 0) { - float pmeForceRatio = comm->load_pme/comm->load_mdf; - lossFractionPme = (comm->load_pme - comm->load_mdf)/comm->load_step; + float pmeForceRatio = comm->load_pme / comm->load_mdf; + lossFractionPme = (comm->load_pme - comm->load_mdf) / comm->load_step; if (lossFractionPme <= 0) { - lossFractionPme *= numPmeRanks/static_cast(numRanks); + lossFractionPme *= numPmeRanks / static_cast(numRanks); } else { - lossFractionPme *= numPpRanks/static_cast(numRanks); + lossFractionPme *= numPpRanks / static_cast(numRanks); } sprintf(buf, " Average PME mesh/force load: %5.3f\n", pmeForceRatio); fprintf(fplog, "%s", buf); fprintf(stderr, "%s", buf); - sprintf(buf, " Part of the total run time spent waiting due to PP/PME imbalance: %.1f %%\n", std::fabs(lossFractionPme)*100); + sprintf(buf, " Part of the total run time spent waiting due to PP/PME imbalance: %.1f %%\n", + std::fabs(lossFractionPme) * 100); fprintf(fplog, "%s", buf); fprintf(stderr, "%s", buf); } @@ -1098,25 +1084,28 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) if (lossFraction >= DD_PERF_LOSS_WARN) { std::string message = gmx::formatString( - "NOTE: %.1f %% of the available CPU time was lost due to load imbalance\n" - " in the domain decomposition.\n", lossFraction*100); + "NOTE: %.1f %% of the available CPU time was lost due to load imbalance\n" + " in the domain decomposition.\n", + lossFraction * 100); bool hadSuggestion = false; if (!isDlbOn(comm)) { - message += " You might want to use dynamic load balancing (option -dlb.)\n"; + message += " You might want to use dynamic load balancing (option -dlb.)\n"; hadSuggestion = true; } else if (dlbWasLimited) { - message += " You might want to decrease the cell size limit (options -rdd, -rcon and/or -dds).\n"; + message += + " You might want to decrease the cell size limit (options -rdd, -rcon " + "and/or -dds).\n"; hadSuggestion = true; } message += gmx::formatString( - " You can %sconsider manually changing the decomposition (option -dd);\n" - " e.g. by using fewer domains along the box dimension in which there is\n" - " considerable inhomogeneity in the simulated system.", - hadSuggestion ? "also " : ""); + " You can %sconsider manually changing the decomposition (option -dd);\n" + " e.g. by using fewer domains along the box dimension in which there is\n" + " considerable inhomogeneity in the simulated system.", + hadSuggestion ? "also " : ""); fprintf(fplog, "%s\n", message.c_str()); @@ -1129,8 +1118,7 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) " had %s work to do than the PP ranks.\n" " You might want to %s the number of PME ranks\n" " or %s the cut-off and the grid spacing.\n", - std::fabs(lossFractionPme*100), - (lossFractionPme < 0) ? "less" : "more", + std::fabs(lossFractionPme * 100), (lossFractionPme < 0) ? "less" : "more", (lossFractionPme < 0) ? "decrease" : "increase", (lossFractionPme < 0) ? "decrease" : "increase"); fprintf(fplog, "%s\n", buf); @@ -1139,23 +1127,23 @@ static void print_dd_load_av(FILE *fplog, gmx_domdec_t *dd) } //! Return the minimum communication volume. -static float dd_vol_min(gmx_domdec_t *dd) +static float dd_vol_min(gmx_domdec_t* dd) { - return dd->comm->load[0].cvol_min*dd->nnodes; + return dd->comm->load[0].cvol_min * dd->nnodes; } //! Return the DD load flags. -static int dd_load_flags(gmx_domdec_t *dd) +static int dd_load_flags(gmx_domdec_t* dd) { return dd->comm->load[0].flags; } //! Return the reported load imbalance in force calculations. -static float dd_f_imbal(gmx_domdec_t *dd) +static float dd_f_imbal(gmx_domdec_t* dd) { if (dd->comm->load[0].sum > 0) { - return dd->comm->load[0].max*dd->nnodes/dd->comm->load[0].sum - 1.0F; + return dd->comm->load[0].max * dd->nnodes / dd->comm->load[0].sum - 1.0F; } else { @@ -1165,20 +1153,18 @@ static float dd_f_imbal(gmx_domdec_t *dd) } //! Returns DD load balance report. -static std::string -dd_print_load(gmx_domdec_t *dd, - int64_t step) +static std::string dd_print_load(gmx_domdec_t* dd, int64_t step) { gmx::StringOutputStream stream; gmx::TextWriter log(&stream); - int flags = dd_load_flags(dd); + int flags = dd_load_flags(dd); if (flags) { log.writeString("DD load balancing is limited by minimum cell size in dimension"); for (int d = 0; d < dd->ndim; d++) { - if (flags & (1<dim[d])); } @@ -1188,12 +1174,11 @@ dd_print_load(gmx_domdec_t *dd, log.writeString("DD step " + gmx::toString(step)); if (isDlbOn(dd->comm)) { - log.writeStringFormatted(" vol min/aver %5.3f%c", - dd_vol_min(dd), flags ? '!' : ' '); + log.writeStringFormatted(" vol min/aver %5.3f%c", dd_vol_min(dd), flags ? '!' : ' '); } if (dd->nnodes > 1) { - log.writeStringFormatted(" load imb.: force %4.1f%%", dd_f_imbal(dd)*100); + log.writeStringFormatted(" load imb.: force %4.1f%%", dd_f_imbal(dd) * 100); } if (dd->comm->cycl_n[ddCyclPME]) { @@ -1204,16 +1189,15 @@ dd_print_load(gmx_domdec_t *dd, } //! Prints DD load balance report in mdrun verbose mode. -static void dd_print_load_verbose(gmx_domdec_t *dd) +static void dd_print_load_verbose(gmx_domdec_t* dd) { if (isDlbOn(dd->comm)) { - fprintf(stderr, "vol %4.2f%c ", - dd_vol_min(dd), dd_load_flags(dd) ? '!' : ' '); + fprintf(stderr, "vol %4.2f%c ", dd_vol_min(dd), dd_load_flags(dd) ? '!' : ' '); } if (dd->nnodes > 1) { - fprintf(stderr, "imb F %2d%% ", gmx::roundToInt(dd_f_imbal(dd)*100)); + fprintf(stderr, "imb F %2d%% ", gmx::roundToInt(dd_f_imbal(dd) * 100)); } if (dd->comm->cycl_n[ddCyclPME]) { @@ -1222,41 +1206,43 @@ static void dd_print_load_verbose(gmx_domdec_t *dd) } //! Turns on dynamic load balancing if possible and needed. -static void turn_on_dlb(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - int64_t step) +static void turn_on_dlb(const gmx::MDLogger& mdlog, gmx_domdec_t* dd, int64_t step) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; - real cellsize_min = comm->cellsize_min[dd->dim[0]]; + real cellsize_min = comm->cellsize_min[dd->dim[0]]; for (int d = 1; d < dd->ndim; d++) { cellsize_min = std::min(cellsize_min, comm->cellsize_min[dd->dim[d]]); } /* Turn off DLB if we're too close to the cell size limit. */ - if (cellsize_min < comm->cellsize_limit*1.05) + if (cellsize_min < comm->cellsize_limit * 1.05) { - GMX_LOG(mdlog.info).appendTextFormatted( - "step %s Measured %.1f %% performance loss due to load imbalance, " - "but the minimum cell size is smaller than 1.05 times the cell size limit. " - "Will no longer try dynamic load balancing.", - gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd)*100); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "step %s Measured %.1f %% performance loss due to load imbalance, " + "but the minimum cell size is smaller than 1.05 times the cell size limit. " + "Will no longer try dynamic load balancing.", + gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd) * 100); comm->dlbState = DlbState::offForever; return; } - GMX_LOG(mdlog.info).appendTextFormatted( - "step %s Turning on dynamic load balancing, because the performance loss due to load imbalance is %.1f %%.", - gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd)*100); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "step %s Turning on dynamic load balancing, because the performance loss due " + "to load imbalance is %.1f %%.", + gmx::toString(step).c_str(), dd_force_imb_perf_loss(dd) * 100); comm->dlbState = DlbState::onCanTurnOff; /* Store the non-DLB performance, so we can check if DLB actually * improves performance. */ - GMX_RELEASE_ASSERT(comm->cycl_n[ddCyclStep] > 0, "When we turned on DLB, we should have measured cycles"); - comm->cyclesPerStepBeforeDLB = comm->cycl[ddCyclStep]/comm->cycl_n[ddCyclStep]; + GMX_RELEASE_ASSERT(comm->cycl_n[ddCyclStep] > 0, + "When we turned on DLB, we should have measured cycles"); + comm->cyclesPerStepBeforeDLB = comm->cycl[ddCyclStep] / comm->cycl_n[ddCyclStep]; set_dlb_limits(dd); @@ -1266,7 +1252,7 @@ static void turn_on_dlb(const gmx::MDLogger &mdlog, */ for (int d = 0; d < dd->ndim; d++) { - RowMaster *rowMaster = comm->cellsizesWithDlb[d].rowMaster.get(); + RowMaster* rowMaster = comm->cellsizesWithDlb[d].rowMaster.get(); if (rowMaster) { @@ -1275,11 +1261,11 @@ static void turn_on_dlb(const gmx::MDLogger &mdlog, int nc = dd->nc[dd->dim[d]]; for (int i = 0; i < nc; i++) { - rowMaster->cellFrac[i] = i/static_cast(nc); + rowMaster->cellFrac[i] = i / static_cast(nc); if (d > 0) { - rowMaster->bounds[i].cellFracLowerMax = i /static_cast(nc); - rowMaster->bounds[i].cellFracUpperMin = (i + 1)/static_cast(nc); + rowMaster->bounds[i].cellFracLowerMax = i / static_cast(nc); + rowMaster->bounds[i].cellFracUpperMin = (i + 1) / static_cast(nc); } } rowMaster->cellFrac[nc] = 1.0; @@ -1288,31 +1274,32 @@ static void turn_on_dlb(const gmx::MDLogger &mdlog, } //! Turns off dynamic load balancing (but leave it able to turn back on). -static void turn_off_dlb(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - int64_t step) +static void turn_off_dlb(const gmx::MDLogger& mdlog, gmx_domdec_t* dd, int64_t step) { - GMX_LOG(mdlog.info).appendText( - "step " + gmx::toString(step) + " Turning off dynamic load balancing, because it is degrading performance."); + GMX_LOG(mdlog.info) + .appendText( + "step " + gmx::toString(step) + + " Turning off dynamic load balancing, because it is degrading performance."); dd->comm->dlbState = DlbState::offCanTurnOn; dd->comm->haveTurnedOffDlb = true; dd->comm->ddPartioningCountFirstDlbOff = dd->ddp_count; } //! Turns off dynamic load balancing permanently. -static void turn_off_dlb_forever(const gmx::MDLogger &mdlog, - gmx_domdec_t *dd, - int64_t step) +static void turn_off_dlb_forever(const gmx::MDLogger& mdlog, gmx_domdec_t* dd, int64_t step) { - GMX_RELEASE_ASSERT(dd->comm->dlbState == DlbState::offCanTurnOn, "Can only turn off DLB forever when it was in the can-turn-on state"); - GMX_LOG(mdlog.info).appendText( - "step " + gmx::toString(step) + " Will no longer try dynamic load balancing, as it degraded performance."); + GMX_RELEASE_ASSERT(dd->comm->dlbState == DlbState::offCanTurnOn, + "Can only turn off DLB forever when it was in the can-turn-on state"); + GMX_LOG(mdlog.info) + .appendText( + "step " + gmx::toString(step) + + " Will no longer try dynamic load balancing, as it degraded performance."); dd->comm->dlbState = DlbState::offForever; } -void set_dd_dlb_max_cutoff(t_commrec *cr, real cutoff) +void set_dd_dlb_max_cutoff(t_commrec* cr, real cutoff) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; comm = cr->dd->comm; @@ -1324,21 +1311,24 @@ void set_dd_dlb_max_cutoff(t_commrec *cr, real cutoff) if (debug) { - fprintf(debug, "PME load balancing set a limit to the DLB staggering such that a %f cut-off will continue to fit\n", + fprintf(debug, + "PME load balancing set a limit to the DLB staggering such that a %f cut-off will " + "continue to fit\n", comm->PMELoadBal_max_cutoff); } } //! Merge atom buffers. -static void merge_cg_buffers(int ncell, - gmx_domdec_comm_dim_t *cd, int pulse, - int *ncg_cell, - gmx::ArrayRef index_gl, - const int *recv_i, - gmx::ArrayRef x, +static void merge_cg_buffers(int ncell, + gmx_domdec_comm_dim_t* cd, + int pulse, + int* ncg_cell, + gmx::ArrayRef index_gl, + const int* recv_i, + gmx::ArrayRef x, gmx::ArrayRef recv_vr, - cginfo_mb_t *cginfo_mb, - gmx::ArrayRef cginfo) + cginfo_mb_t* cginfo_mb, + gmx::ArrayRef cginfo) { gmx_domdec_ind_t *ind, *ind_p; int p, cell, c, cg, cg0, cg1, cg_gl; @@ -1348,15 +1338,15 @@ static void merge_cg_buffers(int ncell, /* First correct the already stored data */ shift = ind->nrecv[ncell]; - for (cell = ncell-1; cell >= 0; cell--) + for (cell = ncell - 1; cell >= 0; cell--) { shift -= ind->nrecv[cell]; if (shift > 0) { /* Move the cg's present from previous grid pulses */ - cg0 = ncg_cell[ncell+cell]; - cg1 = ncg_cell[ncell+cell+1]; - for (cg = cg1-1; cg >= cg0; cg--) + cg0 = ncg_cell[ncell + cell]; + cg1 = ncg_cell[ncell + cell + 1]; + for (cg = cg1 - 1; cg >= cg0; cg--) { index_gl[cg + shift] = index_gl[cg]; x[cg + shift] = x[cg]; @@ -1381,50 +1371,46 @@ static void merge_cg_buffers(int ncell, } /* Merge in the communicated buffers */ - shift = 0; - cg0 = 0; + shift = 0; + cg0 = 0; for (cell = 0; cell < ncell; cell++) { - cg1 = ncg_cell[ncell+cell+1] + shift; + cg1 = ncg_cell[ncell + cell + 1] + shift; for (cg = 0; cg < ind->nrecv[cell]; cg++) { /* Copy this atom from the buffer */ index_gl[cg1] = recv_i[cg0]; x[cg1] = recv_vr[cg0]; /* Copy information */ - cg_gl = index_gl[cg1]; - cginfo[cg1] = ddcginfo(cginfo_mb, cg_gl); + cg_gl = index_gl[cg1]; + cginfo[cg1] = ddcginfo(cginfo_mb, cg_gl); cg0++; cg1++; } - shift += ind->nrecv[cell]; - ncg_cell[ncell+cell+1] = cg1; + shift += ind->nrecv[cell]; + ncg_cell[ncell + cell + 1] = cg1; } } //! Makes a range partitioning for the atom groups wthin a cell -static void make_cell2at_index(gmx_domdec_comm_dim_t *cd, - int nzone, - int atomGroupStart) +static void make_cell2at_index(gmx_domdec_comm_dim_t* cd, int nzone, int atomGroupStart) { /* Store the atom block boundaries for easy copying of communication buffers */ int g = atomGroupStart; for (int zone = 0; zone < nzone; zone++) { - for (gmx_domdec_ind_t &ind : cd->ind) + for (gmx_domdec_ind_t& ind : cd->ind) { - ind.cell2at0[zone] = g; - g += ind.nrecv[zone]; - ind.cell2at1[zone] = g; + ind.cell2at0[zone] = g; + g += ind.nrecv[zone]; + ind.cell2at1[zone] = g; } } } //! Returns whether a link is missing. -static gmx_bool missing_link(const t_blocka &link, - const int globalAtomIndex, - const gmx_ga2la_t &ga2la) +static gmx_bool missing_link(const t_blocka& link, const int globalAtomIndex, const gmx_ga2la_t& ga2la) { for (int i = link.index[globalAtomIndex]; i < link.index[globalAtomIndex + 1]; i++) { @@ -1438,7 +1424,8 @@ static gmx_bool missing_link(const t_blocka &link, } //! Domain corners for communication, a maximum of 4 i-zones see a j domain -typedef struct { +typedef struct +{ //! The corners for the non-bonded communication. real c[DIM][4]; //! Corner for rounding. @@ -1452,14 +1439,10 @@ typedef struct { } dd_corners_t; //! Determine the corners of the domain(s) we are communicating with. -static void -set_dd_corners(const gmx_domdec_t *dd, - int dim0, int dim1, int dim2, - gmx_bool bDistMB, - dd_corners_t *c) +static void set_dd_corners(const gmx_domdec_t* dd, int dim0, int dim1, int dim2, gmx_bool bDistMB, dd_corners_t* c) { - const gmx_domdec_comm_t *comm; - const gmx_domdec_zones_t *zones; + const gmx_domdec_comm_t* comm; + const gmx_domdec_zones_t* zones; comm = dd->comm; @@ -1504,16 +1487,17 @@ set_dd_corners(const gmx_domdec_t *dd, if (isDlbOn(dd->comm)) { /* Use the maximum of the i-cells that see a j-cell */ - for (const auto &iZone : zones->iZones) + for (const auto& iZone : zones->iZones) { const int iZoneIndex = iZone.iZoneIndex; for (int jZone : iZone.jZoneRange) { if (jZone >= 4) { - c->c[2][jZone - 4] = - std::max(c->c[2][jZone - 4], - comm->zone_d2[zones->shift[iZoneIndex][dim0]][zones->shift[iZoneIndex][dim1]].mch0); + c->c[2][jZone - 4] = std::max( + c->c[2][jZone - 4], + comm->zone_d2[zones->shift[iZoneIndex][dim0]][zones->shift[iZoneIndex][dim1]] + .mch0); } } } @@ -1552,31 +1536,39 @@ set_dd_corners(const gmx_domdec_t *dd, /*! \brief Add the atom groups we need to send in this pulse from this * zone to \p localAtomGroups and \p work. */ -static void -get_zone_pulse_cgs(gmx_domdec_t *dd, - int zonei, int zone, - int cg0, int cg1, - gmx::ArrayRef globalAtomGroupIndices, - int dim, int dim_ind, - int dim0, int dim1, int dim2, - real r_comm2, real r_bcomm2, - matrix box, - bool distanceIsTriclinic, - rvec *normal, - real skew_fac2_d, real skew_fac_01, - rvec *v_d, rvec *v_0, rvec *v_1, - const dd_corners_t *c, - const rvec sf2_round, - gmx_bool bDistBonded, - gmx_bool bBondComm, - gmx_bool bDist2B, - gmx_bool bDistMB, - rvec *cg_cm, - gmx::ArrayRef cginfo, - std::vector *localAtomGroups, - dd_comm_setup_work_t *work) +static void get_zone_pulse_cgs(gmx_domdec_t* dd, + int zonei, + int zone, + int cg0, + int cg1, + gmx::ArrayRef globalAtomGroupIndices, + int dim, + int dim_ind, + int dim0, + int dim1, + int dim2, + real r_comm2, + real r_bcomm2, + matrix box, + bool distanceIsTriclinic, + rvec* normal, + real skew_fac2_d, + real skew_fac_01, + rvec* v_d, + rvec* v_0, + rvec* v_1, + const dd_corners_t* c, + const rvec sf2_round, + gmx_bool bDistBonded, + gmx_bool bBondComm, + gmx_bool bDist2B, + gmx_bool bDistMB, + rvec* cg_cm, + gmx::ArrayRef cginfo, + std::vector* localAtomGroups, + dd_comm_setup_work_t* work) { - gmx_domdec_comm_t *comm; + gmx_domdec_comm_t* comm; gmx_bool bScrew; gmx_bool bDistMB_pulse; int cg, i; @@ -1592,8 +1584,8 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, bDistMB_pulse = (bDistMB && bDistBonded); /* Unpack the work data */ - std::vector &ibuf = work->atomGroupBuffer; - std::vector &vbuf = work->positionBuffer; + std::vector& ibuf = work->atomGroupBuffer; + std::vector& vbuf = work->positionBuffer; nsend_z = 0; nat = work->nat; @@ -1607,14 +1599,14 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, r = cg_cm[cg][dim] - c->c[dim_ind][zone]; if (r > 0) { - r2 += r*r; + r2 += r * r; } if (bDistMB_pulse) { r = cg_cm[cg][dim] - c->bc[dim_ind]; if (r > 0) { - rb2 += r*r; + rb2 += r * r; } } /* Rounding gives at most a 16% reduction @@ -1624,10 +1616,10 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, { r = cg_cm[cg][dim0] - c->cr0; /* This is the first dimension, so always r >= 0 */ - r2 += r*r; + r2 += r * r; if (bDistMB_pulse) { - rb2 += r*r; + rb2 += r * r; } } if (dim_ind == 2 && (zonei == 2 || zonei == 3)) @@ -1635,14 +1627,14 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, r = cg_cm[cg][dim1] - c->cr1[zone]; if (r > 0) { - r2 += r*r; + r2 += r * r; } if (bDistMB_pulse) { r = cg_cm[cg][dim1] - c->bcr1; if (r > 0) { - rb2 += r*r; + rb2 += r * r; } } } @@ -1658,11 +1650,11 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, if (dim_ind >= 1 && (zonei == 1 || zonei == 2)) { rn[dim0] = cg_cm[cg][dim0] - c->cr0; - for (i = dim0+1; i < DIM; i++) + for (i = dim0 + 1; i < DIM; i++) { - rn[dim0] -= cg_cm[cg][i]*v_0[i][dim0]; + rn[dim0] -= cg_cm[cg][i] * v_0[i][dim0]; } - r2 = rn[dim0]*rn[dim0]*sf2_round[dim0]; + r2 = rn[dim0] * rn[dim0] * sf2_round[dim0]; if (bDistMB_pulse) { rb[dim0] = rn[dim0]; @@ -1676,10 +1668,10 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, dimd = dd->dim[i]; if (normal[dim0][dimd] > 0) { - rn[dimd] -= rn[dim0]*normal[dim0][dimd]; + rn[dimd] -= rn[dim0] * normal[dim0][dimd]; if (bDistMB_pulse) { - rb[dimd] -= rb[dim0]*normal[dim0][dimd]; + rb[dimd] -= rb[dim0] * normal[dim0][dimd]; } } } @@ -1688,65 +1680,64 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, { GMX_ASSERT(dim1 >= 0 && dim1 < DIM, "Must have a valid dimension index"); rn[dim1] += cg_cm[cg][dim1] - c->cr1[zone]; - tric_sh = 0; - for (i = dim1+1; i < DIM; i++) + tric_sh = 0; + for (i = dim1 + 1; i < DIM; i++) { - tric_sh -= cg_cm[cg][i]*v_1[i][dim1]; + tric_sh -= cg_cm[cg][i] * v_1[i][dim1]; } rn[dim1] += tric_sh; if (rn[dim1] > 0) { - r2 += rn[dim1]*rn[dim1]*sf2_round[dim1]; + r2 += rn[dim1] * rn[dim1] * sf2_round[dim1]; /* Take care of coupling of the distances * to the planes along dim0 and dim1 through dim2. */ - r2 -= rn[dim0]*rn[dim1]*skew_fac_01; + r2 -= rn[dim0] * rn[dim1] * skew_fac_01; /* Take care that the cell planes along dim1 * might not be orthogonal to that along dim2. */ if (normal[dim1][dim2] > 0) { - rn[dim2] -= rn[dim1]*normal[dim1][dim2]; + rn[dim2] -= rn[dim1] * normal[dim1][dim2]; } } if (bDistMB_pulse) { - rb[dim1] += - cg_cm[cg][dim1] - c->bcr1 + tric_sh; + rb[dim1] += cg_cm[cg][dim1] - c->bcr1 + tric_sh; if (rb[dim1] > 0) { - rb2 += rb[dim1]*rb[dim1]*sf2_round[dim1]; + rb2 += rb[dim1] * rb[dim1] * sf2_round[dim1]; /* Take care of coupling of the distances * to the planes along dim0 and dim1 through dim2. */ - rb2 -= rb[dim0]*rb[dim1]*skew_fac_01; + rb2 -= rb[dim0] * rb[dim1] * skew_fac_01; /* Take care that the cell planes along dim1 * might not be orthogonal to that along dim2. */ if (normal[dim1][dim2] > 0) { - rb[dim2] -= rb[dim1]*normal[dim1][dim2]; + rb[dim2] -= rb[dim1] * normal[dim1][dim2]; } } } } /* The distance along the communication direction */ rn[dim] += cg_cm[cg][dim] - c->c[dim_ind][zone]; - tric_sh = 0; - for (i = dim+1; i < DIM; i++) + tric_sh = 0; + for (i = dim + 1; i < DIM; i++) { - tric_sh -= cg_cm[cg][i]*v_d[i][dim]; + tric_sh -= cg_cm[cg][i] * v_d[i][dim]; } rn[dim] += tric_sh; if (rn[dim] > 0) { - r2 += rn[dim]*rn[dim]*skew_fac2_d; + r2 += rn[dim] * rn[dim] * skew_fac2_d; /* Take care of coupling of the distances * to the planes along dim0 and dim1 through dim2. */ if (dim_ind == 1 && zonei == 1) { - r2 -= rn[dim0]*rn[dim]*skew_fac_01; + r2 -= rn[dim0] * rn[dim] * skew_fac_01; } } if (bDistMB_pulse) @@ -1756,26 +1747,23 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, rb[dim] += cg_cm[cg][dim] - c->bc[dim_ind] + tric_sh; if (rb[dim] > 0) { - rb2 += rb[dim]*rb[dim]*skew_fac2_d; + rb2 += rb[dim] * rb[dim] * skew_fac2_d; /* Take care of coupling of the distances * to the planes along dim0 and dim1 through dim2. */ if (dim_ind == 1 && zonei == 1) { - rb2 -= rb[dim0]*rb[dim]*skew_fac_01; + rb2 -= rb[dim0] * rb[dim] * skew_fac_01; } } } } - if (r2 < r_comm2 || - (bDistBonded && - ((bDistMB && rb2 < r_bcomm2) || - (bDist2B && r2 < r_bcomm2)) && - (!bBondComm || - (GET_CGINFO_BOND_INTER(cginfo[cg]) && - missing_link(*comm->bondedLinks, globalAtomGroupIndices[cg], - *dd->ga2la))))) + if (r2 < r_comm2 + || (bDistBonded && ((bDistMB && rb2 < r_bcomm2) || (bDist2B && r2 < r_bcomm2)) + && (!bBondComm + || (GET_CGINFO_BOND_INTER(cginfo[cg]) + && missing_link(*comm->bondedLinks, globalAtomGroupIndices[cg], *dd->ga2la))))) { /* Store the local and global atom group indices and position */ localAtomGroups->push_back(cg); @@ -1808,7 +1796,7 @@ get_zone_pulse_cgs(gmx_domdec_t *dd, } //! Clear data. -static void clearCommSetupData(dd_comm_setup_work_t *work) +static void clearCommSetupData(dd_comm_setup_work_t* work) { work->localAtomGroupBuffer.clear(); work->atomGroupBuffer.clear(); @@ -1818,23 +1806,24 @@ static void clearCommSetupData(dd_comm_setup_work_t *work) } //! Prepare DD communication. -static void setup_dd_communication(gmx_domdec_t *dd, - matrix box, gmx_ddbox_t *ddbox, - t_forcerec *fr, - t_state *state, - PaddedHostVector *f) +static void setup_dd_communication(gmx_domdec_t* dd, + matrix box, + gmx_ddbox_t* ddbox, + t_forcerec* fr, + t_state* state, + PaddedHostVector* f) { int dim_ind, dim, dim0, dim1, dim2, dimd, nat_tot; int nzone, nzone_send, zone, zonei, cg0, cg1; int c; - int *zone_cg_range, pos_cg; - gmx_domdec_comm_t *comm; - gmx_domdec_zones_t *zones; - gmx_domdec_comm_dim_t *cd; - cginfo_mb_t *cginfo_mb; + int * zone_cg_range, pos_cg; + gmx_domdec_comm_t* comm; + gmx_domdec_zones_t* zones; + gmx_domdec_comm_dim_t* cd; + cginfo_mb_t* cginfo_mb; gmx_bool bBondComm, bDist2B, bDistMB, bDistBonded; dd_corners_t corners; - rvec *normal, *v_d, *v_0 = nullptr, *v_1 = nullptr; + rvec * normal, *v_d, *v_0 = nullptr, *v_1 = nullptr; real skew_fac2_d, skew_fac_01; rvec sf2_round; @@ -1843,7 +1832,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, fprintf(debug, "Setting up DD communication\n"); } - comm = dd->comm; + comm = dd->comm; if (comm->dth.empty()) { @@ -1863,8 +1852,10 @@ static void setup_dd_communication(gmx_domdec_t *dd, /* Do we need to determine extra distances for only two-body bondeds? */ bDist2B = (bBondComm && !bDistMB); - const real r_comm2 = gmx::square(domainToDomainIntoAtomToDomainCutoff(comm->systemInfo, comm->systemInfo.cutoff)); - const real r_bcomm2 = gmx::square(domainToDomainIntoAtomToDomainCutoff(comm->systemInfo, comm->cutoff_mbody)); + const real r_comm2 = + gmx::square(domainToDomainIntoAtomToDomainCutoff(comm->systemInfo, comm->systemInfo.cutoff)); + const real r_bcomm2 = + gmx::square(domainToDomainIntoAtomToDomainCutoff(comm->systemInfo, comm->cutoff_mbody)); if (debug) { @@ -1891,8 +1882,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, * to the cell planes along dim0 and dim1 through dim2. * This is required for correct rounding. */ - skew_fac_01 = - ddbox->v[dim0][dim1+1][dim0]*ddbox->v[dim1][dim1+1][dim1]; + skew_fac_01 = ddbox->v[dim0][dim1 + 1][dim0] * ddbox->v[dim1][dim1 + 1][dim1]; if (debug) { fprintf(debug, "\nskew_fac_01 %f\n", skew_fac_01); @@ -1939,8 +1929,8 @@ static void setup_dd_communication(gmx_domdec_t *dd, nzone_send = nzone; } - v_d = ddbox->v[dim]; - skew_fac2_d = gmx::square(ddbox->skew_fac[dim]); + v_d = ddbox->v[dim]; + skew_fac2_d = gmx::square(ddbox->skew_fac[dim]); cd->receiveInPlace = true; for (int p = 0; p < cd->numPulses(); p++) @@ -1950,7 +1940,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, */ bDistBonded = ((bDistMB || bDist2B) && p == 0); - gmx_domdec_ind_t *ind = &cd->ind[p]; + gmx_domdec_ind_t* ind = &cd->ind[p]; /* Thread 0 writes in the global index array */ ind->index.clear(); @@ -1976,14 +1966,12 @@ static void setup_dd_communication(gmx_domdec_t *dd, * and the cell plane is tilted forward * in dimension i, skip this coupling. */ - if (!(zones->shift[nzone+zone][i] && - ddbox->v[dimd][i][dimd] >= 0)) + if (!(zones->shift[nzone + zone][i] && ddbox->v[dimd][i][dimd] >= 0)) { - sf2_round[dimd] += - gmx::square(ddbox->v[dimd][i][dimd]); + sf2_round[dimd] += gmx::square(ddbox->v[dimd][i][dimd]); } } - sf2_round[dimd] = 1/sf2_round[dimd]; + sf2_round[dimd] = 1 / sf2_round[dimd]; } } } @@ -1995,14 +1983,14 @@ static void setup_dd_communication(gmx_domdec_t *dd, * for neighbor searching */ cg0 = zone_cg_range[zonei]; - cg1 = zone_cg_range[zonei+1]; + cg1 = zone_cg_range[zonei + 1]; } else { /* Look only at the cg's received in the previous grid pulse */ - cg1 = zone_cg_range[nzone+zone+1]; - cg0 = cg1 - cd->ind[p-1].nrecv[zone]; + cg1 = zone_cg_range[nzone + zone + 1]; + cg0 = cg1 - cd->ind[p - 1].nrecv[zone]; } const int numThreads = gmx::ssize(comm->dth); @@ -2011,7 +1999,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, { try { - dd_comm_setup_work_t &work = comm->dth[th]; + dd_comm_setup_work_t& work = comm->dth[th]; /* Retain data accumulated into buffers of thread 0 */ if (th > 0) @@ -2019,38 +2007,34 @@ static void setup_dd_communication(gmx_domdec_t *dd, clearCommSetupData(&work); } - int cg0_th = cg0 + ((cg1 - cg0)* th )/numThreads; - int cg1_th = cg0 + ((cg1 - cg0)*(th+1))/numThreads; + int cg0_th = cg0 + ((cg1 - cg0) * th) / numThreads; + int cg1_th = cg0 + ((cg1 - cg0) * (th + 1)) / numThreads; /* Get the cg's for this pulse in this zone */ - get_zone_pulse_cgs(dd, zonei, zone, cg0_th, cg1_th, - dd->globalAtomGroupIndices, - dim, dim_ind, dim0, dim1, dim2, - r_comm2, r_bcomm2, - box, distanceIsTriclinic, - normal, skew_fac2_d, skew_fac_01, - v_d, v_0, v_1, &corners, sf2_round, - bDistBonded, bBondComm, - bDist2B, bDistMB, - state->x.rvec_array(), - fr->cginfo, - th == 0 ? &ind->index : &work.localAtomGroupBuffer, - &work); + get_zone_pulse_cgs(dd, zonei, zone, cg0_th, cg1_th, dd->globalAtomGroupIndices, + dim, dim_ind, dim0, dim1, dim2, r_comm2, r_bcomm2, box, + distanceIsTriclinic, normal, skew_fac2_d, skew_fac_01, + v_d, v_0, v_1, &corners, sf2_round, bDistBonded, bBondComm, + bDist2B, bDistMB, state->x.rvec_array(), fr->cginfo, + th == 0 ? &ind->index : &work.localAtomGroupBuffer, &work); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } // END - std::vector &atomGroups = comm->dth[0].atomGroupBuffer; - std::vector &positions = comm->dth[0].positionBuffer; - ind->nsend[zone] = comm->dth[0].nsend_zone; + std::vector& atomGroups = comm->dth[0].atomGroupBuffer; + std::vector& positions = comm->dth[0].positionBuffer; + ind->nsend[zone] = comm->dth[0].nsend_zone; /* Append data of threads>=1 to the communication buffers */ for (int th = 1; th < numThreads; th++) { - const dd_comm_setup_work_t &dth = comm->dth[th]; + const dd_comm_setup_work_t& dth = comm->dth[th]; - ind->index.insert(ind->index.end(), dth.localAtomGroupBuffer.begin(), dth.localAtomGroupBuffer.end()); - atomGroups.insert(atomGroups.end(), dth.atomGroupBuffer.begin(), dth.atomGroupBuffer.end()); - positions.insert(positions.end(), dth.positionBuffer.begin(), dth.positionBuffer.end()); + ind->index.insert(ind->index.end(), dth.localAtomGroupBuffer.begin(), + dth.localAtomGroupBuffer.end()); + atomGroups.insert(atomGroups.end(), dth.atomGroupBuffer.begin(), + dth.atomGroupBuffer.end()); + positions.insert(positions.end(), dth.positionBuffer.begin(), + dth.positionBuffer.end()); comm->dth[0].nat += dth.nat; ind->nsend[zone] += dth.nsend_zone; } @@ -2063,14 +2047,12 @@ static void setup_dd_communication(gmx_domdec_t *dd, ind->nsend[nzone] = ind->index.size(); ind->nsend[nzone + 1] = comm->dth[0].nat; /* Communicate the number of cg's and atoms to receive */ - ddSendrecv(dd, dim_ind, dddirBackward, - ind->nsend, nzone+2, - ind->nrecv, nzone+2); + ddSendrecv(dd, dim_ind, dddirBackward, ind->nsend, nzone + 2, ind->nrecv, nzone + 2); if (p > 0) { /* We can receive in place if only the last zone is not empty */ - for (zone = 0; zone < nzone-1; zone++) + for (zone = 0; zone < nzone - 1; zone++) { if (ind->nrecv[zone] > 0) { @@ -2088,7 +2070,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, DDBufferAccess globalAtomGroupBuffer(comm->intBuffer, receiveBufferSize); DDBufferAccess rvecBuffer(comm->rvecBuffer, receiveBufferSize); - dd_comm_setup_work_t &work = comm->dth[0]; + dd_comm_setup_work_t& work = comm->dth[0]; /* Make space for the global cg indices */ int numAtomGroupsNew = pos_cg + ind->nrecv[nzone]; @@ -2097,14 +2079,14 @@ static void setup_dd_communication(gmx_domdec_t *dd, gmx::ArrayRef integerBufferRef; if (cd->receiveInPlace) { - integerBufferRef = gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data() + pos_cg, ind->nrecv[nzone]); + integerBufferRef = gmx::arrayRefFromArray( + dd->globalAtomGroupIndices.data() + pos_cg, ind->nrecv[nzone]); } else { integerBufferRef = globalAtomGroupBuffer.buffer; } - ddSendrecv(dd, dim_ind, dddirBackward, - work.atomGroupBuffer, integerBufferRef); + ddSendrecv(dd, dim_ind, dddirBackward, work.atomGroupBuffer, integerBufferRef); /* Make space for cg_cm */ dd_check_alloc_ncg(fr, state, f, pos_cg + ind->nrecv[nzone]); @@ -2119,8 +2101,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, { rvecBufferRef = rvecBuffer.buffer; } - ddSendrecv(dd, dim_ind, dddirBackward, - work.positionBuffer, rvecBufferRef); + ddSendrecv(dd, dim_ind, dddirBackward, work.positionBuffer, rvecBufferRef); /* Make the charge group index */ if (cd->receiveInPlace) @@ -2136,22 +2117,21 @@ static void setup_dd_communication(gmx_domdec_t *dd, } if (p == 0) { - comm->zone_ncg1[nzone+zone] = ind->nrecv[zone]; + comm->zone_ncg1[nzone + zone] = ind->nrecv[zone]; } zone++; - zone_cg_range[nzone+zone] = pos_cg; + zone_cg_range[nzone + zone] = pos_cg; } } else { /* This part of the code is never executed with bBondComm. */ - merge_cg_buffers(nzone, cd, p, zone_cg_range, - dd->globalAtomGroupIndices, integerBufferRef.data(), - state->x, rvecBufferRef, - fr->cginfo_mb, fr->cginfo); + merge_cg_buffers(nzone, cd, p, zone_cg_range, dd->globalAtomGroupIndices, + integerBufferRef.data(), state->x, rvecBufferRef, fr->cginfo_mb, + fr->cginfo); pos_cg += ind->nrecv[nzone]; } - nat_tot += ind->nrecv[nzone+1]; + nat_tot += ind->nrecv[nzone + 1]; } if (!cd->receiveInPlace) { @@ -2168,9 +2148,7 @@ static void setup_dd_communication(gmx_domdec_t *dd, /* We don't need to update cginfo, since that was alrady done above. * So we pass NULL for the forcerec. */ - dd_set_cginfo(dd->globalAtomGroupIndices, - dd->ncg_home, dd->globalAtomGroupIndices.size(), - nullptr); + dd_set_cginfo(dd->globalAtomGroupIndices, dd->ncg_home, dd->globalAtomGroupIndices.size(), nullptr); } if (debug) @@ -2178,21 +2156,20 @@ static void setup_dd_communication(gmx_domdec_t *dd, fprintf(debug, "Finished setting up DD communication, zones:"); for (c = 0; c < zones->n; c++) { - fprintf(debug, " %d", zones->cg_range[c+1]-zones->cg_range[c]); + fprintf(debug, " %d", zones->cg_range[c + 1] - zones->cg_range[c]); } fprintf(debug, "\n"); } } //! Set boundaries for the charge group range. -static void set_cg_boundaries(gmx_domdec_zones_t *zones) +static void set_cg_boundaries(gmx_domdec_zones_t* zones) { - for (auto &iZone : zones->iZones) + for (auto& iZone : zones->iZones) { iZone.iAtomRange = gmx::Range(0, zones->cg_range[iZone.iZoneIndex + 1]); - iZone.jAtomRange = - gmx::Range(zones->cg_range[iZone.jZoneRange.begin()], - zones->cg_range[iZone.jZoneRange.end()]); + iZone.jAtomRange = gmx::Range(zones->cg_range[iZone.jZoneRange.begin()], + zones->cg_range[iZone.jZoneRange.end()]); } } @@ -2212,13 +2189,15 @@ static void set_cg_boundaries(gmx_domdec_zones_t *zones) * \param[in] zone_end The end of the zone range to set sizes for * \param[in] numMovedChargeGroupsInHomeZone The number of charge groups in the home zone that should moved but are still present in dd->comm->zones.cg_range */ -static void set_zones_size(gmx_domdec_t *dd, - matrix box, const gmx_ddbox_t *ddbox, - int zone_start, int zone_end, - int numMovedChargeGroupsInHomeZone) +static void set_zones_size(gmx_domdec_t* dd, + matrix box, + const gmx_ddbox_t* ddbox, + int zone_start, + int zone_end, + int numMovedChargeGroupsInHomeZone) { - gmx_domdec_comm_t *comm; - gmx_domdec_zones_t *zones; + gmx_domdec_comm_t* comm; + gmx_domdec_zones_t* zones; gmx_bool bDistMB; int z, d, dim; real rcs, rcmbs; @@ -2230,9 +2209,7 @@ static void set_zones_size(gmx_domdec_t *dd, zones = &comm->zones; /* Do we need to determine extra distances for multi-body bondeds? */ - bDistMB = (comm->systemInfo.haveInterDomainMultiBodyBondeds && - isDlbOn(dd->comm) && - dd->ndim > 1); + bDistMB = (comm->systemInfo.haveInterDomainMultiBodyBondeds && isDlbOn(dd->comm) && dd->ndim > 1); for (z = zone_start; z < zone_end; z++) { @@ -2256,13 +2233,17 @@ static void set_zones_size(gmx_domdec_t *dd, { if (d == 1) { - zones->size[z].x0[dim] = comm->zone_d1[zones->shift[z][dd->dim[d-1]]].min0; - zones->size[z].x1[dim] = comm->zone_d1[zones->shift[z][dd->dim[d-1]]].max1; + zones->size[z].x0[dim] = comm->zone_d1[zones->shift[z][dd->dim[d - 1]]].min0; + zones->size[z].x1[dim] = comm->zone_d1[zones->shift[z][dd->dim[d - 1]]].max1; } else if (d == 2) { - zones->size[z].x0[dim] = comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].min0; - zones->size[z].x1[dim] = comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].max1; + zones->size[z].x0[dim] = + comm->zone_d2[zones->shift[z][dd->dim[d - 2]]][zones->shift[z][dd->dim[d - 1]]] + .min0; + zones->size[z].x1[dim] = + comm->zone_d2[zones->shift[z][dd->dim[d - 2]]][zones->shift[z][dd->dim[d - 1]]] + .max1; } } } @@ -2271,7 +2252,7 @@ static void set_zones_size(gmx_domdec_t *dd, rcmbs = comm->cutoff_mbody; if (ddbox->tric_dir[dim]) { - rcs /= ddbox->skew_fac[dim]; + rcs /= ddbox->skew_fac[dim]; rcmbs /= ddbox->skew_fac[dim]; } @@ -2293,20 +2274,19 @@ static void set_zones_size(gmx_domdec_t *dd, */ if (z < 4) { - zones->size[z].x0[dim] = - comm->zone_d1[zones->shift[z][dd->dim[d-1]]].min1; + zones->size[z].x0[dim] = comm->zone_d1[zones->shift[z][dd->dim[d - 1]]].min1; } else { if (d == 1) { - zones->size[z].x0[dim] = - zones->size[zone_perm[2][z-4]].x0[dim]; + zones->size[z].x0[dim] = zones->size[zone_perm[2][z - 4]].x0[dim]; } else { zones->size[z].x0[dim] = - comm->zone_d2[zones->shift[z][dd->dim[d-2]]][zones->shift[z][dd->dim[d-1]]].min1; + comm->zone_d2[zones->shift[z][dd->dim[d - 2]]][zones->shift[z][dd->dim[d - 1]]] + .min1; } } /* A temporary limit, is updated below */ @@ -2323,7 +2303,7 @@ static void set_zones_size(gmx_domdec_t *dd, * to a larger zone then strictly necessary. */ zones->size[z].x1[dim] = std::max(zones->size[z].x1[dim], - zones->size[zi].x1[dim]+rcmbs); + zones->size[zi].x1[dim] + rcmbs); } } } @@ -2334,13 +2314,13 @@ static void set_zones_size(gmx_domdec_t *dd, /* Loop over the i-zones to set the upper limit of each * j-zone they see. */ - for (const auto &iZone : zones->iZones) + for (const auto& iZone : zones->iZones) { const int zi = iZone.iZoneIndex; if (zones->shift[zi][dim] == 0) { /* We should only use zones up to zone_end */ - const auto &jZoneRangeFull = iZone.jZoneRange; + const auto& jZoneRangeFull = iZone.jZoneRange; if (zone_end <= *jZoneRangeFull.begin()) { continue; @@ -2351,8 +2331,8 @@ static void set_zones_size(gmx_domdec_t *dd, { if (zones->shift[jZone][dim] > 0) { - zones->size[jZone].x1[dim] = std::max(zones->size[jZone].x1[dim], - zones->size[zi].x1[dim]+rcs); + zones->size[jZone].x1[dim] = + std::max(zones->size[jZone].x1[dim], zones->size[zi].x1[dim] + rcs); } } } @@ -2362,7 +2342,7 @@ static void set_zones_size(gmx_domdec_t *dd, for (z = zone_start; z < zone_end; z++) { /* Initialization only required to keep the compiler happy */ - rvec corner_min = {0, 0, 0}, corner_max = {0, 0, 0}, corner; + rvec corner_min = { 0, 0, 0 }, corner_max = { 0, 0, 0 }, corner; int nc, c; /* To determine the bounding box for a zone we need to find @@ -2390,8 +2370,8 @@ static void set_zones_size(gmx_domdec_t *dd, { corner[ZZ] = zones->size[z].x1[ZZ]; } - if (dd->ndim == 1 && dd->dim[0] < ZZ && ZZ < dd->unitCellInfo.npbcdim && - box[ZZ][1 - dd->dim[0]] != 0) + if (dd->ndim == 1 && dd->dim[0] < ZZ && ZZ < dd->unitCellInfo.npbcdim + && box[ZZ][1 - dd->dim[0]] != 0) { /* With 1D domain decomposition the cg's are not in * the triclinic box, but triclinic x-y and rectangular y/x-z. @@ -2402,14 +2382,14 @@ static void set_zones_size(gmx_domdec_t *dd, */ int d = 1 - dd->dim[0]; - corner[d] -= corner[ZZ]*box[ZZ][d]/box[ZZ][ZZ]; + corner[d] -= corner[ZZ] * box[ZZ][d] / box[ZZ][ZZ]; } /* Apply the triclinic couplings */ for (i = YY; i < ddbox->npbcdim && i < DIM; i++) { for (j = XX; j < i; j++) { - corner[j] += corner[i]*box[i][j]/box[i][i]; + corner[j] += corner[i] * box[i][j] / box[i][i]; } } if (c == 0) @@ -2444,23 +2424,20 @@ static void set_zones_size(gmx_domdec_t *dd, { vol *= zones->size[0].x1[dim] - zones->size[0].x0[dim]; } - zones->dens_zone0 = (zones->cg_range[1] - zones->cg_range[0] - numMovedChargeGroupsInHomeZone)/vol; + zones->dens_zone0 = + (zones->cg_range[1] - zones->cg_range[0] - numMovedChargeGroupsInHomeZone) / vol; } if (debug) { for (z = zone_start; z < zone_end; z++) { - fprintf(debug, "zone %d %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", - z, - zones->size[z].x0[XX], zones->size[z].x1[XX], - zones->size[z].x0[YY], zones->size[z].x1[YY], - zones->size[z].x0[ZZ], zones->size[z].x1[ZZ]); - fprintf(debug, "zone %d bb %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", - z, - zones->size[z].bb_x0[XX], zones->size[z].bb_x1[XX], - zones->size[z].bb_x0[YY], zones->size[z].bb_x1[YY], - zones->size[z].bb_x0[ZZ], zones->size[z].bb_x1[ZZ]); + fprintf(debug, "zone %d %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", z, + zones->size[z].x0[XX], zones->size[z].x1[XX], zones->size[z].x0[YY], + zones->size[z].x1[YY], zones->size[z].x0[ZZ], zones->size[z].x1[ZZ]); + fprintf(debug, "zone %d bb %6.3f - %6.3f %6.3f - %6.3f %6.3f - %6.3f\n", z, + zones->size[z].bb_x0[XX], zones->size[z].bb_x1[XX], zones->size[z].bb_x0[YY], + zones->size[z].bb_x1[YY], zones->size[z].bb_x0[ZZ], zones->size[z].bb_x1[ZZ]); } } } @@ -2469,25 +2446,24 @@ static void set_zones_size(gmx_domdec_t *dd, * * Note: both buffers should have at least \p sort.size() elements. */ -template -static void -orderVector(gmx::ArrayRef sort, - gmx::ArrayRef dataToSort, - gmx::ArrayRef sortBuffer) +template +static void orderVector(gmx::ArrayRef sort, + gmx::ArrayRef dataToSort, + gmx::ArrayRef sortBuffer) { GMX_ASSERT(dataToSort.size() >= sort.size(), "The vector needs to be sufficiently large"); - GMX_ASSERT(sortBuffer.size() >= sort.size(), "The sorting buffer needs to be sufficiently large"); + GMX_ASSERT(sortBuffer.size() >= sort.size(), + "The sorting buffer needs to be sufficiently large"); /* Order the data into the temporary buffer */ size_t i = 0; - for (const gmx_cgsort_t &entry : sort) + for (const gmx_cgsort_t& entry : sort) { sortBuffer[i++] = dataToSort[entry.ind]; } /* Copy back to the original array */ - std::copy(sortBuffer.begin(), sortBuffer.begin() + sort.size(), - dataToSort.begin()); + std::copy(sortBuffer.begin(), sortBuffer.begin() + sort.size(), dataToSort.begin()); } /*! \brief Order data in \p dataToSort according to \p sort @@ -2495,11 +2471,10 @@ orderVector(gmx::ArrayRef sort, * Note: \p vectorToSort should have at least \p sort.size() elements, * \p workVector is resized when it is too small. */ -template -static void -orderVector(gmx::ArrayRef sort, - gmx::ArrayRef vectorToSort, - std::vector *workVector) +template +static void orderVector(gmx::ArrayRef sort, + gmx::ArrayRef vectorToSort, + std::vector* workVector) { if (gmx::index(workVector->size()) < sort.ssize()) { @@ -2509,8 +2484,7 @@ orderVector(gmx::ArrayRef sort, } //! Returns the sorting order for atoms based on the nbnxn grid order in sort -static void dd_sort_order_nbnxn(const t_forcerec *fr, - std::vector *sort) +static void dd_sort_order_nbnxn(const t_forcerec* fr, std::vector* sort) { gmx::ArrayRef atomOrder = fr->nbv->getLocalAtomOrder(); @@ -2530,21 +2504,20 @@ static void dd_sort_order_nbnxn(const t_forcerec *fr, } //! Returns the sorting state for DD. -static void dd_sort_state(gmx_domdec_t *dd, t_forcerec *fr, t_state *state) +static void dd_sort_state(gmx_domdec_t* dd, t_forcerec* fr, t_state* state) { - gmx_domdec_sort_t *sort = dd->comm->sort.get(); + gmx_domdec_sort_t* sort = dd->comm->sort.get(); dd_sort_order_nbnxn(fr, &sort->sorted); /* We alloc with the old size, since cgindex is still old */ - DDBufferAccess rvecBuffer(dd->comm->rvecBuffer, dd->ncg_home); + DDBufferAccess rvecBuffer(dd->comm->rvecBuffer, dd->ncg_home); /* Set the new home atom/charge group count */ dd->ncg_home = sort->sorted.size(); if (debug) { - fprintf(debug, "Set the new home atom count to %d\n", - dd->ncg_home); + fprintf(debug, "Set the new home atom count to %d\n", dd->ncg_home); } /* Reorder the state */ @@ -2576,22 +2549,21 @@ static void dd_sort_state(gmx_domdec_t *dd, t_forcerec *fr, t_state *state) } //! Accumulates load statistics. -static void add_dd_statistics(gmx_domdec_t *dd) +static void add_dd_statistics(gmx_domdec_t* dd) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; for (int i = 0; i < static_cast(DDAtomRanges::Type::Number); i++) { auto range = static_cast(i); - comm->sum_nat[i] += - comm->atomRanges.end(range) - comm->atomRanges.start(range); + comm->sum_nat[i] += comm->atomRanges.end(range) - comm->atomRanges.start(range); } comm->ndecomp++; } -void reset_dd_statistics_counters(gmx_domdec_t *dd) +void reset_dd_statistics_counters(gmx_domdec_t* dd) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; /* Reset all the statistics and counters for total run counting */ for (int i = 0; i < static_cast(DDAtomRanges::Type::Number); i++) @@ -2608,11 +2580,11 @@ void reset_dd_statistics_counters(gmx_domdec_t *dd) comm->load_pme = 0; } -void print_dd_statistics(const t_commrec *cr, const t_inputrec *ir, FILE *fplog) +void print_dd_statistics(const t_commrec* cr, const t_inputrec* ir, FILE* fplog) { - gmx_domdec_comm_t *comm = cr->dd->comm; + gmx_domdec_comm_t* comm = cr->dd->comm; - const int numRanges = static_cast(DDAtomRanges::Type::Number); + const int numRanges = static_cast(DDAtomRanges::Type::Number); gmx_sumd(numRanges, comm->sum_nat, cr); if (fplog == nullptr) @@ -2625,33 +2597,27 @@ void print_dd_statistics(const t_commrec *cr, const t_inputrec *ir, FILE *fplog) for (int i = static_cast(DDAtomRanges::Type::Zones); i < numRanges; i++) { auto range = static_cast(i); - double av = comm->sum_nat[i]/comm->ndecomp; + double av = comm->sum_nat[i] / comm->ndecomp; switch (range) { case DDAtomRanges::Type::Zones: - fprintf(fplog, - " av. #atoms communicated per step for force: %d x %.1f\n", - 2, av); + fprintf(fplog, " av. #atoms communicated per step for force: %d x %.1f\n", 2, av); break; case DDAtomRanges::Type::Vsites: if (cr->dd->vsite_comm) { - fprintf(fplog, - " av. #atoms communicated per step for vsites: %d x %.1f\n", - (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2, - av); + fprintf(fplog, " av. #atoms communicated per step for vsites: %d x %.1f\n", + (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2, av); } break; case DDAtomRanges::Type::Constraints: if (cr->dd->constraint_comm) { - fprintf(fplog, - " av. #atoms communicated per step for LINCS: %d x %.1f\n", + fprintf(fplog, " av. #atoms communicated per step for LINCS: %d x %.1f\n", 1 + ir->nLincsIter, av); } break; - default: - gmx_incons(" Unknown type for DD statistics"); + default: gmx_incons(" Unknown type for DD statistics"); } } fprintf(fplog, "\n"); @@ -2663,31 +2629,31 @@ void print_dd_statistics(const t_commrec *cr, const t_inputrec *ir, FILE *fplog) } //!\brief TODO Remove fplog when group scheme and charge groups are gone -void dd_partition_system(FILE *fplog, - const gmx::MDLogger &mdlog, +void dd_partition_system(FILE* fplog, + const gmx::MDLogger& mdlog, int64_t step, - const t_commrec *cr, + const t_commrec* cr, gmx_bool bMasterState, int nstglobalcomm, - t_state *state_global, - const gmx_mtop_t &top_global, - const t_inputrec *ir, - gmx::ImdSession *imdSession, - pull_t *pull_work, - t_state *state_local, - PaddedHostVector *f, - gmx::MDAtoms *mdAtoms, - gmx_localtop_t *top_local, - t_forcerec *fr, - gmx_vsite_t *vsite, - gmx::Constraints *constr, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, + t_state* state_global, + const gmx_mtop_t& top_global, + const t_inputrec* ir, + gmx::ImdSession* imdSession, + pull_t* pull_work, + t_state* state_local, + PaddedHostVector* f, + gmx::MDAtoms* mdAtoms, + gmx_localtop_t* top_local, + t_forcerec* fr, + gmx_vsite_t* vsite, + gmx::Constraints* constr, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, gmx_bool bVerbose) { - gmx_domdec_t *dd; - gmx_domdec_comm_t *comm; - gmx_ddbox_t ddbox = {0}; + gmx_domdec_t* dd; + gmx_domdec_comm_t* comm; + gmx_ddbox_t ddbox = { 0 }; int64_t step_pcoupl; rvec cell_ns_x0, cell_ns_x1; int ncgindex_set, ncg_moved, nat_f_novirsum; @@ -2723,7 +2689,7 @@ void dd_partition_system(FILE *fplog, } else { - step_pcoupl = ((step - 1)/n)*n + 1; + step_pcoupl = ((step - 1) / n) * n + 1; } if (step_pcoupl >= comm->partition_step) { @@ -2759,23 +2725,21 @@ void dd_partition_system(FILE *fplog, bCheckWhetherToTurnDlbOn = dd_dlb_get_should_check_whether_to_turn_dlb_on(dd); /* Print load every nstlog, first and last step to the log file */ - bLogLoad = ((ir->nstlog > 0 && step % ir->nstlog == 0) || - comm->n_load_collect == 0 || - (ir->nsteps >= 0 && - (step + ir->nstlist > ir->init_step + ir->nsteps))); + bLogLoad = ((ir->nstlog > 0 && step % ir->nstlog == 0) || comm->n_load_collect == 0 + || (ir->nsteps >= 0 && (step + ir->nstlist > ir->init_step + ir->nsteps))); /* Avoid extra communication due to verbose screen output * when nstglobalcomm is set. */ - if (bDoDLB || bLogLoad || bCheckWhetherToTurnDlbOn || - (bVerbose && (ir->nstlist == 0 || nstglobalcomm <= ir->nstlist))) + if (bDoDLB || bLogLoad || bCheckWhetherToTurnDlbOn + || (bVerbose && (ir->nstlist == 0 || nstglobalcomm <= ir->nstlist))) { get_load_distribution(dd, wcycle); if (DDMASTER(dd)) { if (bLogLoad) { - GMX_LOG(mdlog.info).asParagraph().appendText(dd_print_load(dd, step-1)); + GMX_LOG(mdlog.info).asParagraph().appendText(dd_print_load(dd, step - 1)); } if (bVerbose) { @@ -2789,13 +2753,13 @@ void dd_partition_system(FILE *fplog, if (DDMASTER(dd)) { /* Add the measured cycles to the running average */ - const float averageFactor = 0.1F; + const float averageFactor = 0.1F; comm->cyclesPerStepDlbExpAverage = - (1 - averageFactor)*comm->cyclesPerStepDlbExpAverage + - averageFactor*comm->cycl[ddCyclStep]/comm->cycl_n[ddCyclStep]; + (1 - averageFactor) * comm->cyclesPerStepDlbExpAverage + + averageFactor * comm->cycl[ddCyclStep] / comm->cycl_n[ddCyclStep]; } - if (comm->dlbState == DlbState::onCanTurnOff && - dd->comm->n_load_have % c_checkTurnDlbOffInterval == c_checkTurnDlbOffInterval - 1) + if (comm->dlbState == DlbState::onCanTurnOff + && dd->comm->n_load_have % c_checkTurnDlbOffInterval == c_checkTurnDlbOffInterval - 1) { gmx_bool turnOffDlb; if (DDMASTER(dd)) @@ -2805,8 +2769,7 @@ void dd_partition_system(FILE *fplog, * We will again run and check the cycles without DLB * and we can then decide if to turn off DLB forever. */ - turnOffDlb = (comm->cyclesPerStepDlbExpAverage > - comm->cyclesPerStepBeforeDLB); + turnOffDlb = (comm->cyclesPerStepDlbExpAverage > comm->cyclesPerStepBeforeDLB); } dd_bcast(dd, sizeof(turnOffDlb), &turnOffDlb); if (turnOffDlb) @@ -2833,9 +2796,8 @@ void dd_partition_system(FILE *fplog, * incorrectly conclude that DLB was causing the slowdown. * So we measure one nstlist block, no running average. */ - if (comm->haveTurnedOffDlb && - comm->cycl[ddCyclStep]/comm->cycl_n[ddCyclStep] < - comm->cyclesPerStepDlbExpAverage) + if (comm->haveTurnedOffDlb + && comm->cycl[ddCyclStep] / comm->cycl_n[ddCyclStep] < comm->cyclesPerStepDlbExpAverage) { /* After turning off DLB we ran nstlist steps in fewer * cycles than with DLB. This likely means that DLB @@ -2844,12 +2806,12 @@ void dd_partition_system(FILE *fplog, * observations in close succession to turn off DLB * forever. */ - if (comm->dlbSlowerPartitioningCount > 0 && - dd->ddp_count < comm->dlbSlowerPartitioningCount + 10*c_checkTurnDlbOnInterval) + if (comm->dlbSlowerPartitioningCount > 0 + && dd->ddp_count < comm->dlbSlowerPartitioningCount + 10 * c_checkTurnDlbOnInterval) { turnOffDlbForever = TRUE; } - comm->haveTurnedOffDlb = false; + comm->haveTurnedOffDlb = false; /* Register when we last measured DLB slowdown */ comm->dlbSlowerPartitioningCount = dd->ddp_count; } @@ -2862,8 +2824,7 @@ void dd_partition_system(FILE *fplog, * cost on the PME ranks, which will then surely result * in lower total performance. */ - if (comm->ddRankSetup.usePmeOnlyRanks && - dd_pme_f_ratio(dd) > 1 - DD_PERF_LOSS_DLB_ON) + if (comm->ddRankSetup.usePmeOnlyRanks && dd_pme_f_ratio(dd) > 1 - DD_PERF_LOSS_DLB_ON) { turnOnDlb = FALSE; } @@ -2877,10 +2838,7 @@ void dd_partition_system(FILE *fplog, { gmx_bool turnOffDlbForever; gmx_bool turnOnDlb; - } - bools { - turnOffDlbForever, turnOnDlb - }; + } bools{ turnOffDlbForever, turnOnDlb }; dd_bcast(dd, sizeof(bools), &bools); if (bools.turnOffDlbForever) { @@ -2905,10 +2863,7 @@ void dd_partition_system(FILE *fplog, auto xGlobal = positionsFromStatePointer(state_global); - set_ddbox(*dd, true, - DDMASTER(dd) ? state_global->box : nullptr, - true, xGlobal, - &ddbox); + set_ddbox(*dd, true, DDMASTER(dd) ? state_global->box : nullptr, true, xGlobal, &ddbox); distributeState(mdlog, dd, top_global, state_global, ddbox, state_local, f); @@ -2923,12 +2878,18 @@ void dd_partition_system(FILE *fplog, { if (state_local->ddp_count > dd->ddp_count) { - gmx_fatal(FARGS, "Internal inconsistency state_local->ddp_count (%d) > dd->ddp_count (%" PRId64 ")", state_local->ddp_count, dd->ddp_count); + gmx_fatal(FARGS, + "Internal inconsistency state_local->ddp_count (%d) > dd->ddp_count (%" PRId64 + ")", + state_local->ddp_count, dd->ddp_count); } if (state_local->ddp_count_cg_gl != state_local->ddp_count) { - gmx_fatal(FARGS, "Internal inconsistency state_local->ddp_count_cg_gl (%d) != state_local->ddp_count (%d)", state_local->ddp_count_cg_gl, state_local->ddp_count); + gmx_fatal(FARGS, + "Internal inconsistency state_local->ddp_count_cg_gl (%d) != " + "state_local->ddp_count (%d)", + state_local->ddp_count_cg_gl, state_local->ddp_count); } /* Clear the old state */ @@ -2943,8 +2904,7 @@ void dd_partition_system(FILE *fplog, dd_set_cginfo(dd->globalAtomGroupIndices, 0, dd->ncg_home, fr); - set_ddbox(*dd, bMasterState, state_local->box, - true, state_local->x, &ddbox); + set_ddbox(*dd, bMasterState, state_local->box, true, state_local->x, &ddbox); bRedist = isDlbOn(comm); } @@ -2962,21 +2922,19 @@ void dd_partition_system(FILE *fplog, */ if (!bNStGlobalComm) { - copy_rvec(comm->box0, ddbox.box0 ); + copy_rvec(comm->box0, ddbox.box0); copy_rvec(comm->box_size, ddbox.box_size); } - set_ddbox(*dd, bMasterState, state_local->box, - bNStGlobalComm, state_local->x, &ddbox); + set_ddbox(*dd, bMasterState, state_local->box, bNStGlobalComm, state_local->x, &ddbox); bBoxChanged = TRUE; bRedist = TRUE; } /* Copy needed for dim's without pbc when avoiding communication */ - copy_rvec(ddbox.box0, comm->box0 ); + copy_rvec(ddbox.box0, comm->box0); copy_rvec(ddbox.box_size, comm->box_size); - set_dd_cell_sizes(dd, &ddbox, dd->unitCellInfo.ddBoxIsDynamic, bMasterState, bDoDLB, - step, wcycle); + set_dd_cell_sizes(dd, &ddbox, dd->unitCellInfo.ddBoxIsDynamic, bMasterState, bDoDLB, step, wcycle); if (comm->ddSettings.nstDDDumpGrid > 0 && step % comm->ddSettings.nstDDDumpGrid == 0) { @@ -2985,8 +2943,8 @@ void dd_partition_system(FILE *fplog, if (comm->systemInfo.useUpdateGroups) { - comm->updateGroupsCog->addCogs(gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home), - state_local->x); + comm->updateGroupsCog->addCogs( + gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home), state_local->x); } /* Check if we should sort the charge groups */ @@ -3003,26 +2961,23 @@ void dd_partition_system(FILE *fplog, wallcycle_sub_start(wcycle, ewcsDD_REDIST); ncgindex_set = dd->ncg_home; - dd_redistribute_cg(fplog, step, dd, ddbox.tric_dir, - state_local, f, fr, - nrnb, &ncg_moved); + dd_redistribute_cg(fplog, step, dd, ddbox.tric_dir, state_local, f, fr, nrnb, &ncg_moved); GMX_RELEASE_ASSERT(bSortCG, "Sorting is required after redistribution"); if (comm->systemInfo.useUpdateGroups) { - comm->updateGroupsCog->addCogs(gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home), - state_local->x); + comm->updateGroupsCog->addCogs( + gmx::arrayRefFromArray(dd->globalAtomGroupIndices.data(), dd->ncg_home), + state_local->x); } wallcycle_sub_stop(wcycle, ewcsDD_REDIST); } // TODO: Integrate this code in the nbnxm module - get_nsgrid_boundaries(ddbox.nboundeddim, state_local->box, - dd, &ddbox, - &comm->cell_x0, &comm->cell_x1, - dd->ncg_home, as_rvec_array(state_local->x.data()), + get_nsgrid_boundaries(ddbox.nboundeddim, state_local->box, dd, &ddbox, &comm->cell_x0, + &comm->cell_x1, dd->ncg_home, as_rvec_array(state_local->x.data()), cell_ns_x0, cell_ns_x1, &grid_density); if (bBoxChanged) @@ -3047,21 +3002,15 @@ void dd_partition_system(FILE *fplog, set_zones_size(dd, state_local->box, &ddbox, 0, 1, ncg_moved); - nbnxn_put_on_grid(fr->nbv.get(), state_local->box, - 0, - comm->zones.size[0].bb_x0, - comm->zones.size[0].bb_x1, - comm->updateGroupsCog.get(), - { 0, dd->ncg_home }, - comm->zones.dens_zone0, - fr->cginfo, - state_local->x, + nbnxn_put_on_grid(fr->nbv.get(), state_local->box, 0, comm->zones.size[0].bb_x0, + comm->zones.size[0].bb_x1, comm->updateGroupsCog.get(), + { 0, dd->ncg_home }, comm->zones.dens_zone0, fr->cginfo, state_local->x, ncg_moved, bRedist ? comm->movedBuffer.data() : nullptr); if (debug) { - fprintf(debug, "Step %s, sorting the %d home charge groups\n", - gmx_step_str(step, sbuf), dd->ncg_home); + fprintf(debug, "Step %s, sorting the %d home charge groups\n", gmx_step_str(step, sbuf), + dd->ncg_home); } dd_sort_state(dd, fr, state_local); @@ -3107,9 +3056,7 @@ void dd_partition_system(FILE *fplog, if (fr->cutoff_scheme == ecutsVERLET) { /* When bSortCG=true, we have already set the size for zone 0 */ - set_zones_size(dd, state_local->box, &ddbox, - bSortCG ? 1 : 0, comm->zones.n, - 0); + set_zones_size(dd, state_local->box, &ddbox, bSortCG ? 1 : 0, comm->zones.n, 0); } wallcycle_sub_stop(wcycle, ewcsDD_SETUPCOMM); @@ -3127,10 +3074,7 @@ void dd_partition_system(FILE *fplog, np[dd->dim[i]] = comm->cd[i].numPulses(); } dd_make_local_top(dd, &comm->zones, dd->unitCellInfo.npbcdim, state_local->box, - comm->cellsize_min, np, - fr, - state_local->x.rvec_array(), - top_global, top_local); + comm->cellsize_min, np, fr, state_local->x.rvec_array(), top_global, top_local); wallcycle_sub_stop(wcycle, ewcsDD_MAKETOP); @@ -3138,7 +3082,8 @@ void dd_partition_system(FILE *fplog, /* Set up the special atom communication */ int n = comm->atomRanges.end(DDAtomRanges::Type::Zones); - for (int i = static_cast(DDAtomRanges::Type::Zones) + 1; i < static_cast(DDAtomRanges::Type::Number); i++) + for (int i = static_cast(DDAtomRanges::Type::Zones) + 1; + i < static_cast(DDAtomRanges::Type::Number); i++) { auto range = static_cast(i); switch (range) @@ -3153,13 +3098,11 @@ void dd_partition_system(FILE *fplog, if (dd->comm->systemInfo.haveSplitConstraints || dd->comm->systemInfo.haveSplitSettles) { /* Only for inter-cg constraints we need special code */ - n = dd_make_local_constraints(dd, n, &top_global, fr->cginfo.data(), - constr, ir->nProjOrder, - top_local->idef.il); + n = dd_make_local_constraints(dd, n, &top_global, fr->cginfo.data(), constr, + ir->nProjOrder, top_local->idef.il); } break; - default: - gmx_incons("Unknown special atom type setup"); + default: gmx_incons("Unknown special atom type setup"); } comm->atomRanges.setEnd(range, n); } @@ -3204,26 +3147,20 @@ void dd_partition_system(FILE *fplog, * allocation, zeroing and copying, but this is probably not worth * the complications and checking. */ - forcerec_set_ranges(fr, - comm->atomRanges.end(DDAtomRanges::Type::Zones), - comm->atomRanges.end(DDAtomRanges::Type::Constraints), - nat_f_novirsum); + forcerec_set_ranges(fr, comm->atomRanges.end(DDAtomRanges::Type::Zones), + comm->atomRanges.end(DDAtomRanges::Type::Constraints), nat_f_novirsum); /* Update atom data for mdatoms and several algorithms */ - mdAlgorithmsSetupAtomData(cr, ir, top_global, top_local, fr, - nullptr, mdAtoms, constr, vsite, nullptr); + mdAlgorithmsSetupAtomData(cr, ir, top_global, top_local, fr, nullptr, mdAtoms, constr, vsite, nullptr); auto mdatoms = mdAtoms->mdatoms(); if (!thisRankHasDuty(cr, DUTY_PME)) { /* Send the charges and/or c6/sigmas to our PME only node */ - gmx_pme_send_parameters(cr, - fr->ic, - mdatoms->nChargePerturbed != 0, mdatoms->nTypePerturbed != 0, - mdatoms->chargeA, mdatoms->chargeB, - mdatoms->sqrt_c6A, mdatoms->sqrt_c6B, - mdatoms->sigmaA, mdatoms->sigmaB, - dd_pme_maxshift_x(dd), dd_pme_maxshift_y(dd)); + gmx_pme_send_parameters(cr, fr->ic, mdatoms->nChargePerturbed != 0, + mdatoms->nTypePerturbed != 0, mdatoms->chargeA, mdatoms->chargeB, + mdatoms->sqrt_c6A, mdatoms->sqrt_c6B, mdatoms->sigmaA, + mdatoms->sigmaB, dd_pme_maxshift_x(dd), dd_pme_maxshift_y(dd)); } if (ir->bPull) @@ -3257,8 +3194,8 @@ void dd_partition_system(FILE *fplog, if (comm->ddSettings.nstDDDump > 0 && step % comm->ddSettings.nstDDDump == 0) { dd_move_x(dd, state_local->box, state_local->x, nullWallcycle); - write_dd_pdb("dd_dump", step, "dump", &top_global, cr, - -1, state_local->x.rvec_array(), state_local->box); + write_dd_pdb("dd_dump", step, "dump", &top_global, cr, -1, state_local->x.rvec_array(), + state_local->box); } /* Store the partitioning step */ @@ -3286,20 +3223,21 @@ void dd_partition_system(FILE *fplog, } /*! \brief Check whether bonded interactions are missing, if appropriate */ -void checkNumberOfBondedInteractions(const gmx::MDLogger &mdlog, - t_commrec *cr, +void checkNumberOfBondedInteractions(const gmx::MDLogger& mdlog, + t_commrec* cr, int totalNumberOfBondedInteractions, - const gmx_mtop_t *top_global, - const gmx_localtop_t *top_local, - const rvec *x, + const gmx_mtop_t* top_global, + const gmx_localtop_t* top_local, + const rvec* x, const matrix box, - bool *shouldCheckNumberOfBondedInteractions) + bool* shouldCheckNumberOfBondedInteractions) { if (*shouldCheckNumberOfBondedInteractions) { if (totalNumberOfBondedInteractions != cr->dd->nbonded_global) { - dd_print_missing_interactions(mdlog, cr, totalNumberOfBondedInteractions, top_global, top_local, x, box); // Does not return + dd_print_missing_interactions(mdlog, cr, totalNumberOfBondedInteractions, top_global, + top_local, x, box); // Does not return } *shouldCheckNumberOfBondedInteractions = false; } diff --git a/src/gromacs/domdec/partition.h b/src/gromacs/domdec/partition.h index 68fd8c2fcb..fc07a745b1 100644 --- a/src/gromacs/domdec/partition.h +++ b/src/gromacs/domdec/partition.h @@ -69,17 +69,13 @@ class Constraints; class ImdSession; class MDAtoms; class MDLogger; -} // namespace +} // namespace gmx //! Check whether the DD grid has moved too far for correctness. -bool check_grid_jump(int64_t step, - const gmx_domdec_t *dd, - real cutoff, - const gmx_ddbox_t *ddbox, - gmx_bool bFatal); +bool check_grid_jump(int64_t step, const gmx_domdec_t* dd, real cutoff, const gmx_ddbox_t* ddbox, gmx_bool bFatal); /*! \brief Print statistics for domain decomposition communication */ -void print_dd_statistics(const t_commrec *cr, const t_inputrec *ir, FILE *fplog); +void print_dd_statistics(const t_commrec* cr, const t_inputrec* ir, FILE* fplog); /*! \brief Partition the system over the nodes. * @@ -110,26 +106,26 @@ void print_dd_statistics(const t_commrec *cr, const t_inputrec *ir, FILE *fplog) * \param[in] wcycle Timers * \param[in] bVerbose Be verbose */ -void dd_partition_system(FILE *fplog, - const gmx::MDLogger &mdlog, +void dd_partition_system(FILE* fplog, + const gmx::MDLogger& mdlog, int64_t step, - const t_commrec *cr, + const t_commrec* cr, gmx_bool bMasterState, int nstglobalcomm, - t_state *state_global, - const gmx_mtop_t &top_global, - const t_inputrec *ir, - gmx::ImdSession *imdSession, - pull_t *pull_work, - t_state *state_local, - gmx::PaddedHostVector *f, - gmx::MDAtoms *mdatoms, - gmx_localtop_t *top_local, - t_forcerec *fr, - gmx_vsite_t *vsite, - gmx::Constraints *constr, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, + t_state* state_global, + const gmx_mtop_t& top_global, + const t_inputrec* ir, + gmx::ImdSession* imdSession, + pull_t* pull_work, + t_state* state_local, + gmx::PaddedHostVector* f, + gmx::MDAtoms* mdatoms, + gmx_localtop_t* top_local, + t_forcerec* fr, + gmx_vsite_t* vsite, + gmx::Constraints* constr, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, gmx_bool bVerbose); /*! \brief Check whether bonded interactions are missing, if appropriate @@ -143,13 +139,13 @@ void dd_partition_system(FILE *fplog, * \param[in] box Box matrix for the error message * \param[in,out] shouldCheckNumberOfBondedInteractions Whether we should do the check. Always set to false. */ -void checkNumberOfBondedInteractions(const gmx::MDLogger &mdlog, - t_commrec *cr, +void checkNumberOfBondedInteractions(const gmx::MDLogger& mdlog, + t_commrec* cr, int totalNumberOfBondedInteractions, - const gmx_mtop_t *top_global, - const gmx_localtop_t *top_local, - const rvec *x, + const gmx_mtop_t* top_global, + const gmx_localtop_t* top_local, + const rvec* x, const matrix box, - bool *shouldCheckNumberOfBondedInteractions); + bool* shouldCheckNumberOfBondedInteractions); #endif diff --git a/src/gromacs/domdec/redistribute.cpp b/src/gromacs/domdec/redistribute.cpp index d27455043b..eb130157c6 100644 --- a/src/gromacs/domdec/redistribute.cpp +++ b/src/gromacs/domdec/redistribute.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,21 +74,22 @@ static constexpr int DD_FLAG_NRCG = 65535; /* Returns which bit tells whether to move a group forward along dimension d */ static inline int DD_FLAG_FW(int d) { - return 1 << (16 + d*2); + return 1 << (16 + d * 2); } /* Returns which bit tells whether to move a group backward along dimension d */ static inline int DD_FLAG_BW(int d) { - return 1 << (16 + d*2 + 1); + return 1 << (16 + d * 2 + 1); } -static void -copyMovedAtomsToBufferPerAtom(gmx::ArrayRef move, - int nvec, int vec, - rvec *src, gmx_domdec_comm_t *comm) +static void copyMovedAtomsToBufferPerAtom(gmx::ArrayRef move, + int nvec, + int vec, + rvec* src, + gmx_domdec_comm_t* comm) { - int pos_vec[DIM*2] = { 0 }; + int pos_vec[DIM * 2] = { 0 }; for (gmx::index i = 0; i < move.ssize(); i++) { @@ -103,12 +105,12 @@ copyMovedAtomsToBufferPerAtom(gmx::ArrayRef move, } } -static void -copyMovedUpdateGroupCogs(gmx::ArrayRef move, - int nvec, gmx::ArrayRef coordinates, - gmx_domdec_comm_t *comm) +static void copyMovedUpdateGroupCogs(gmx::ArrayRef move, + int nvec, + gmx::ArrayRef coordinates, + gmx_domdec_comm_t* comm) { - int pos_vec[DIM*2] = { 0 }; + int pos_vec[DIM * 2] = { 0 }; for (gmx::index g = 0; g < move.ssize(); g++) { @@ -117,19 +119,19 @@ copyMovedUpdateGroupCogs(gmx::ArrayRef move, if (m >= 0) { /* Copy to the communication buffer */ - const gmx::RVec &cog = (comm->systemInfo.useUpdateGroups ? - comm->updateGroupsCog->cogForAtom(g) : - coordinates[g]); + const gmx::RVec& cog = + (comm->systemInfo.useUpdateGroups ? comm->updateGroupsCog->cogForAtom(g) + : coordinates[g]); copy_rvec(cog, comm->cgcm_state[m][pos_vec[m]]); pos_vec[m] += 1 + nvec; } } } -static void clear_and_mark_ind(gmx::ArrayRef move, - gmx::ArrayRef globalAtomIndices, - gmx_ga2la_t *ga2la, - int *cell_index) +static void clear_and_mark_ind(gmx::ArrayRef move, + gmx::ArrayRef globalAtomIndices, + gmx_ga2la_t* ga2la, + int* cell_index) { for (gmx::index a = 0; a < move.ssize(); a++) { @@ -146,13 +148,19 @@ static void clear_and_mark_ind(gmx::ArrayRef move, } } -static void print_cg_move(FILE *fplog, - const gmx_domdec_t *dd, - int64_t step, int cg, int dim, int dir, - gmx_bool bHaveCgcmOld, real limitd, - rvec cm_old, rvec cm_new, real pos_d) +static void print_cg_move(FILE* fplog, + const gmx_domdec_t* dd, + int64_t step, + int cg, + int dim, + int dir, + gmx_bool bHaveCgcmOld, + real limitd, + rvec cm_old, + rvec cm_new, + real pos_d) { - const gmx_domdec_comm_t *comm = dd->comm; + const gmx_domdec_comm_t* comm = dd->comm; std::string mesg; fprintf(fplog, "\nStep %" PRId64 ":\n", step); @@ -165,8 +173,8 @@ static void print_cg_move(FILE *fplog, { mesg += "Atom"; } - mesg += gmx::formatString(" %d moved more than the distance allowed by the domain decomposition", - ddglatnr(dd, cg)); + mesg += gmx::formatString( + " %d moved more than the distance allowed by the domain decomposition", ddglatnr(dd, cg)); if (limitd > 0) { mesg += gmx::formatString(" (%f)", limitd); @@ -178,39 +186,38 @@ static void print_cg_move(FILE *fplog, dir == 1 ? pos_d - comm->cell_x1[dim] : pos_d - comm->cell_x0[dim]); if (bHaveCgcmOld) { - fprintf(fplog, "Old coordinates: %8.3f %8.3f %8.3f\n", - cm_old[XX], cm_old[YY], cm_old[ZZ]); + fprintf(fplog, "Old coordinates: %8.3f %8.3f %8.3f\n", cm_old[XX], cm_old[YY], cm_old[ZZ]); } - fprintf(fplog, "New coordinates: %8.3f %8.3f %8.3f\n", - cm_new[XX], cm_new[YY], cm_new[ZZ]); - fprintf(fplog, "Old cell boundaries in direction %c: %8.3f %8.3f\n", - dim2char(dim), + fprintf(fplog, "New coordinates: %8.3f %8.3f %8.3f\n", cm_new[XX], cm_new[YY], cm_new[ZZ]); + fprintf(fplog, "Old cell boundaries in direction %c: %8.3f %8.3f\n", dim2char(dim), comm->old_cell_x0[dim], comm->old_cell_x1[dim]); - fprintf(fplog, "New cell boundaries in direction %c: %8.3f %8.3f\n", - dim2char(dim), + fprintf(fplog, "New cell boundaries in direction %c: %8.3f %8.3f\n", dim2char(dim), comm->cell_x0[dim], comm->cell_x1[dim]); } -[[ noreturn ]] -static void cg_move_error(FILE *fplog, - const gmx_domdec_t *dd, - int64_t step, int cg, int dim, int dir, - gmx_bool bHaveCgcmOld, real limitd, - rvec cm_old, rvec cm_new, real pos_d) +[[noreturn]] static void cg_move_error(FILE* fplog, + const gmx_domdec_t* dd, + int64_t step, + int cg, + int dim, + int dir, + gmx_bool bHaveCgcmOld, + real limitd, + rvec cm_old, + rvec cm_new, + real pos_d) { if (fplog) { - print_cg_move(fplog, dd, step, cg, dim, dir, - bHaveCgcmOld, limitd, cm_old, cm_new, pos_d); + print_cg_move(fplog, dd, step, cg, dim, dir, bHaveCgcmOld, limitd, cm_old, cm_new, pos_d); } - print_cg_move(stderr, dd, step, cg, dim, dir, - bHaveCgcmOld, limitd, cm_old, cm_new, pos_d); + print_cg_move(stderr, dd, step, cg, dim, dir, bHaveCgcmOld, limitd, cm_old, cm_new, pos_d); gmx_fatal(FARGS, "One or more atoms moved too far between two domain decomposition steps.\n" "This usually means that your system is not well equilibrated"); } -static void rotate_state_atom(t_state *state, int a) +static void rotate_state_atom(t_state* state, int a) { if (state->flags & (1 << estX)) { @@ -221,13 +228,13 @@ static void rotate_state_atom(t_state *state, int a) } if (state->flags & (1 << estV)) { - auto v = makeArrayRef(state->v); + auto v = makeArrayRef(state->v); v[a][YY] = -v[a][YY]; v[a][ZZ] = -v[a][ZZ]; } if (state->flags & (1 << estCGP)) { - auto cg_p = makeArrayRef(state->cg_p); + auto cg_p = makeArrayRef(state->cg_p); cg_p[a][YY] = -cg_p[a][YY]; cg_p[a][ZZ] = -cg_p[a][ZZ]; } @@ -237,13 +244,12 @@ static void rotate_state_atom(t_state *state, int a) * * Note: numAtomsOld should either be 0 or match the current buffer size. */ -static int *getMovedBuffer(gmx_domdec_comm_t *comm, - size_t numAtomsOld, - size_t numAtomsNew) +static int* getMovedBuffer(gmx_domdec_comm_t* comm, size_t numAtomsOld, size_t numAtomsNew) { - std::vector &movedBuffer = comm->movedBuffer; + std::vector& movedBuffer = comm->movedBuffer; - GMX_RELEASE_ASSERT(numAtomsOld == 0 || movedBuffer.size() == numAtomsOld, "numAtomsOld should either be 0 or match the current size"); + GMX_RELEASE_ASSERT(numAtomsOld == 0 || movedBuffer.size() == numAtomsOld, + "numAtomsOld should either be 0 or match the current size"); /* Contents up to numAtomsOld should be preserved, clear from numAtomsOld */ if (numAtomsOld == 0) @@ -273,8 +279,7 @@ struct MoveLimits * needs to be moved along and in which direction (bit 0 not set for fw * and set for bw). */ -static int computeMoveFlag(const gmx_domdec_t &dd, - const ivec &dev) +static int computeMoveFlag(const gmx_domdec_t& dd, const ivec& dev) { int flag = 0; int firstMoveDimValue = -1; @@ -286,7 +291,7 @@ static int computeMoveFlag(const gmx_domdec_t &dd, flag |= DD_FLAG_FW(d); if (firstMoveDimValue == -1) { - firstMoveDimValue = d*2; + firstMoveDimValue = d * 2; } } else if (dev[dim] == -1) @@ -296,11 +301,11 @@ static int computeMoveFlag(const gmx_domdec_t &dd, { if (dd.nc[dim] > 2) { - firstMoveDimValue = d*2 + 1; + firstMoveDimValue = d * 2 + 1; } else { - firstMoveDimValue = d*2; + firstMoveDimValue = d * 2; } } } @@ -313,13 +318,17 @@ static int computeMoveFlag(const gmx_domdec_t &dd, * * Returns in the move array where the atoms should go. */ -static void calc_cg_move(FILE *fplog, int64_t step, - gmx_domdec_t *dd, - t_state *state, - const ivec tric_dir, matrix tcm, - const rvec cell_x0, const rvec cell_x1, - const MoveLimits &moveLimits, - int cg_start, int cg_end, +static void calc_cg_move(FILE* fplog, + int64_t step, + gmx_domdec_t* dd, + t_state* state, + const ivec tric_dir, + matrix tcm, + const rvec cell_x0, + const rvec cell_x1, + const MoveLimits& moveLimits, + int cg_start, + int cg_end, gmx::ArrayRef move) { const int npbcdim = dd->unitCellInfo.npbcdim; @@ -328,7 +337,7 @@ static void calc_cg_move(FILE *fplog, int64_t step, for (int a = cg_start; a < cg_end; a++) { // TODO: Rename this center of geometry variable to cogNew - rvec cm_new; + rvec cm_new; copy_rvec(x[a], cm_new); ivec dev = { 0 }; @@ -344,7 +353,7 @@ static void calc_cg_move(FILE *fplog, int64_t step, { for (int d2 = d + 1; d2 < DIM; d2++) { - pos_d += cm_new[d2]*tcm[d2][d]; + pos_d += cm_new[d2] * tcm[d2][d]; } } /* Put the charge group in the triclinic unit-cell */ @@ -352,8 +361,7 @@ static void calc_cg_move(FILE *fplog, int64_t step, { if (pos_d >= moveLimits.upper[d]) { - cg_move_error(fplog, dd, step, a, d, 1, - false, moveLimits.distance[d], + cg_move_error(fplog, dd, step, a, d, 1, false, moveLimits.distance[d], cm_new, cm_new, pos_d); } dev[d] = 1; @@ -376,8 +384,7 @@ static void calc_cg_move(FILE *fplog, int64_t step, { if (pos_d < moveLimits.lower[d]) { - cg_move_error(fplog, dd, step, a, d, -1, - false, moveLimits.distance[d], + cg_move_error(fplog, dd, step, a, d, -1, false, moveLimits.distance[d], cm_new, cm_new, pos_d); } dev[d] = -1; @@ -421,9 +428,7 @@ static void calc_cg_move(FILE *fplog, int64_t step, struct PbcAndFlag { /* Constructor that purposely does not initialize anything */ - PbcAndFlag() - { - } + PbcAndFlag() {} gmx::RVec pbcShift; int moveFlag; @@ -434,28 +439,32 @@ struct PbcAndFlag * Returns in the move array where the groups should go. * Also updates the COGs and coordinates for jumps over periodic boundaries. */ -static void calcGroupMove(FILE *fplog, int64_t step, - const gmx_domdec_t *dd, - const t_state *state, - const ivec tric_dir, matrix tcm, - const rvec cell_x0, const rvec cell_x1, - const MoveLimits &moveLimits, - int groupBegin, int groupEnd, +static void calcGroupMove(FILE* fplog, + int64_t step, + const gmx_domdec_t* dd, + const t_state* state, + const ivec tric_dir, + matrix tcm, + const rvec cell_x0, + const rvec cell_x1, + const MoveLimits& moveLimits, + int groupBegin, + int groupEnd, gmx::ArrayRef pbcAndFlags) { GMX_RELEASE_ASSERT(!dd->unitCellInfo.haveScrewPBC, "Screw PBC is not supported here"); - const int npbcdim = dd->unitCellInfo.npbcdim; + const int npbcdim = dd->unitCellInfo.npbcdim; - gmx::UpdateGroupsCog *updateGroupsCog = dd->comm->updateGroupsCog.get(); + gmx::UpdateGroupsCog* updateGroupsCog = dd->comm->updateGroupsCog.get(); for (int g = groupBegin; g < groupEnd; g++) { - gmx::RVec &cog = updateGroupsCog->cog(g); + gmx::RVec& cog = updateGroupsCog->cog(g); gmx::RVec cogOld = cog; - ivec dev = { 0 }; + ivec dev = { 0 }; /* Do pbc and check DD cell boundary crossings */ for (int d = DIM - 1; d >= 0; d--) { @@ -467,7 +476,7 @@ static void calcGroupMove(FILE *fplog, int64_t step, { for (int d2 = d + 1; d2 < DIM; d2++) { - pos_d += cog[d2]*tcm[d2][d]; + pos_d += cog[d2] * tcm[d2][d]; } } /* Put the COG in the triclinic unit-cell */ @@ -475,8 +484,7 @@ static void calcGroupMove(FILE *fplog, int64_t step, { if (pos_d >= moveLimits.upper[d]) { - cg_move_error(fplog, dd, step, g, d, 1, - true, moveLimits.distance[d], + cg_move_error(fplog, dd, step, g, d, 1, true, moveLimits.distance[d], cogOld, cog, pos_d); } dev[d] = 1; @@ -489,8 +497,7 @@ static void calcGroupMove(FILE *fplog, int64_t step, { if (pos_d < moveLimits.lower[d]) { - cg_move_error(fplog, dd, step, g, d, -1, - true, moveLimits.distance[d], + cg_move_error(fplog, dd, step, g, d, -1, true, moveLimits.distance[d], cogOld, cog, pos_d); } dev[d] = -1; @@ -515,39 +522,40 @@ static void calcGroupMove(FILE *fplog, int64_t step, } /* Store the PBC and move flag, so we can later apply them to the atoms */ - PbcAndFlag &pbcAndFlag = pbcAndFlags[g]; + PbcAndFlag& pbcAndFlag = pbcAndFlags[g]; rvec_sub(cog, cogOld, pbcAndFlag.pbcShift); pbcAndFlag.moveFlag = computeMoveFlag(*dd, dev); } } -static void -applyPbcAndSetMoveFlags(const gmx::UpdateGroupsCog &updateGroupsCog, - gmx::ArrayRef pbcAndFlags, - int atomBegin, - int atomEnd, - gmx::ArrayRef atomCoords, - gmx::ArrayRef move) +static void applyPbcAndSetMoveFlags(const gmx::UpdateGroupsCog& updateGroupsCog, + gmx::ArrayRef pbcAndFlags, + int atomBegin, + int atomEnd, + gmx::ArrayRef atomCoords, + gmx::ArrayRef move) { for (int a = atomBegin; a < atomEnd; a++) { - const PbcAndFlag &pbcAndFlag = pbcAndFlags[updateGroupsCog.cogIndex(a)]; + const PbcAndFlag& pbcAndFlag = pbcAndFlags[updateGroupsCog.cogIndex(a)]; rvec_inc(atomCoords[a], pbcAndFlag.pbcShift); /* Temporarily store the flag in move */ move[a] = pbcAndFlag.moveFlag; } } -void dd_redistribute_cg(FILE *fplog, int64_t step, - gmx_domdec_t *dd, ivec tric_dir, - t_state *state, - PaddedHostVector *f, - t_forcerec *fr, - t_nrnb *nrnb, - int *ncg_moved) +void dd_redistribute_cg(FILE* fplog, + int64_t step, + gmx_domdec_t* dd, + ivec tric_dir, + t_state* state, + PaddedHostVector* f, + t_forcerec* fr, + t_nrnb* nrnb, + int* ncg_moved) { - gmx_domdec_comm_t *comm = dd->comm; + gmx_domdec_comm_t* comm = dd->comm; if (dd->unitCellInfo.haveScrewPBC) { @@ -555,16 +563,16 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, } // Positions are always present, so there's nothing to flag - bool bV = (state->flags & (1<flags & (1<flags & (1 << estV)) != 0; + bool bCGP = (state->flags & (1 << estCGP)) != 0; DDBufferAccess moveBuffer(comm->intBuffer, dd->ncg_home); gmx::ArrayRef move = moveBuffer.buffer; - const int npbcdim = dd->unitCellInfo.npbcdim; + const int npbcdim = dd->unitCellInfo.npbcdim; - rvec cell_x0, cell_x1; - MoveLimits moveLimits; + rvec cell_x0, cell_x1; + MoveLimits moveLimits; for (int d = 0; (d < DIM); d++) { moveLimits.distance[d] = dd->comm->cellsize_min[d]; @@ -595,19 +603,20 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, * more than one cell. Set the pre-comm check limit to float_max. */ moveLimits.lower[d] = -GMX_FLOAT_MAX; - moveLimits.upper[d] = GMX_FLOAT_MAX; + moveLimits.upper[d] = GMX_FLOAT_MAX; } } matrix tcm; make_tric_corr_matrix(npbcdim, state->box, tcm); - const int nthread = gmx_omp_nthreads_get(emntDomdec); + const int nthread = gmx_omp_nthreads_get(emntDomdec); /* Compute the center of geometry for all home charge groups * and put them in the box and determine where they should go. */ - std::vector pbcAndFlags(comm->systemInfo.useUpdateGroups ? comm->updateGroupsCog->numCogs() : 0); + std::vector pbcAndFlags( + comm->systemInfo.useUpdateGroups ? comm->updateGroupsCog->numCogs() : 0); #pragma omp parallel num_threads(nthread) { @@ -617,37 +626,30 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, if (comm->systemInfo.useUpdateGroups) { - const auto &updateGroupsCog = *comm->updateGroupsCog; + const auto& updateGroupsCog = *comm->updateGroupsCog; const int numGroups = updateGroupsCog.numCogs(); - calcGroupMove(fplog, step, dd, state, tric_dir, tcm, - cell_x0, cell_x1, moveLimits, - ( thread *numGroups)/nthread, - ((thread+1)*numGroups)/nthread, + calcGroupMove(fplog, step, dd, state, tric_dir, tcm, cell_x0, cell_x1, moveLimits, + (thread * numGroups) / nthread, ((thread + 1) * numGroups) / nthread, pbcAndFlags); /* We need a barrier as atoms below can be in a COG of a different thread */ #pragma omp barrier const int numHomeAtoms = comm->atomRanges.numHomeAtoms(); - applyPbcAndSetMoveFlags(updateGroupsCog, pbcAndFlags, - ( thread *numHomeAtoms)/nthread, - ((thread+1)*numHomeAtoms)/nthread, - state->x, - move); + applyPbcAndSetMoveFlags(updateGroupsCog, pbcAndFlags, (thread * numHomeAtoms) / nthread, + ((thread + 1) * numHomeAtoms) / nthread, state->x, move); } else { /* Here we handle single atoms or charge groups */ - calc_cg_move(fplog, step, dd, state, tric_dir, tcm, - cell_x0, cell_x1, moveLimits, - ( thread *dd->ncg_home)/nthread, - ((thread+1)*dd->ncg_home)/nthread, - move); + calc_cg_move(fplog, step, dd, state, tric_dir, tcm, cell_x0, cell_x1, moveLimits, + (thread * dd->ncg_home) / nthread, + ((thread + 1) * dd->ncg_home) / nthread, move); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - int ncg[DIM*2] = { 0 }; - int nat[DIM*2] = { 0 }; + int ncg[DIM * 2] = { 0 }; + int nat[DIM * 2] = { 0 }; for (int cg = 0; cg < dd->ncg_home; cg++) { if (move[cg] >= 0) @@ -656,22 +658,22 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, const int mc = move[cg] & DD_FLAG_NRCG; move[cg] = mc; - std::vector &cggl_flag = comm->cggl_flag[mc]; + std::vector& cggl_flag = comm->cggl_flag[mc]; /* TODO: See if we can use push_back instead */ - if ((ncg[mc] + 1)*DD_CGIBS > gmx::index(cggl_flag.size())) + if ((ncg[mc] + 1) * DD_CGIBS > gmx::index(cggl_flag.size())) { - cggl_flag.resize((ncg[mc] + 1)*DD_CGIBS); + cggl_flag.resize((ncg[mc] + 1) * DD_CGIBS); } - cggl_flag[ncg[mc]*DD_CGIBS ] = dd->globalAtomGroupIndices[cg]; + cggl_flag[ncg[mc] * DD_CGIBS] = dd->globalAtomGroupIndices[cg]; /* We store the cg size in the lower 16 bits * and the place where the charge group should go * in the next 6 bits. This saves some communication volume. * * TODO: Remove the size, as it is now always 1. */ - const int numAtomsInGroup = 1; - cggl_flag[ncg[mc]*DD_CGIBS+1] = numAtomsInGroup | flag; + const int numAtomsInGroup = 1; + cggl_flag[ncg[mc] * DD_CGIBS + 1] = numAtomsInGroup | flag; ncg[mc] += 1; nat[mc] += numAtomsInGroup; } @@ -681,7 +683,7 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, inc_nrnb(nrnb, eNR_RESETX, dd->ncg_home); *ncg_moved = 0; - for (int i = 0; i < dd->ndim*2; i++) + for (int i = 0; i < dd->ndim * 2; i++) { *ncg_moved += ncg[i]; } @@ -697,9 +699,9 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, } /* Make sure the communication buffers are large enough */ - for (int mc = 0; mc < dd->ndim*2; mc++) + for (int mc = 0; mc < dd->ndim * 2; mc++) { - size_t nvr = ncg[mc] + nat[mc]*nvec; + size_t nvr = ncg[mc] + nat[mc] * nvec; if (nvr > comm->cgcm_state[mc].size()) { comm->cgcm_state[mc].resize(nvr); @@ -714,39 +716,27 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, copyMovedUpdateGroupCogs(move, nvec, state->x, comm); int vectorIndex = 0; - copyMovedAtomsToBufferPerAtom(move, - nvec, vectorIndex++, - state->x.rvec_array(), - comm); + copyMovedAtomsToBufferPerAtom(move, nvec, vectorIndex++, state->x.rvec_array(), comm); if (bV) { - copyMovedAtomsToBufferPerAtom(move, - nvec, vectorIndex++, - state->v.rvec_array(), - comm); + copyMovedAtomsToBufferPerAtom(move, nvec, vectorIndex++, state->v.rvec_array(), comm); } if (bCGP) { - copyMovedAtomsToBufferPerAtom(move, - nvec, vectorIndex++, - state->cg_p.rvec_array(), - comm); + copyMovedAtomsToBufferPerAtom(move, nvec, vectorIndex++, state->cg_p.rvec_array(), comm); } - int *moved = getMovedBuffer(comm, 0, dd->ncg_home); + int* moved = getMovedBuffer(comm, 0, dd->ncg_home); - clear_and_mark_ind(move, - dd->globalAtomIndices, - dd->ga2la, - moved); + clear_and_mark_ind(move, dd->globalAtomIndices, dd->ga2la, moved); /* Now we can remove the excess global atom-group indices from the list */ dd->globalAtomGroupIndices.resize(dd->ncg_home); /* We reuse the intBuffer without reacquiring since we are in the same scope */ - DDBufferAccess &flagBuffer = moveBuffer; + DDBufferAccess& flagBuffer = moveBuffer; - const cginfo_mb_t *cginfo_mb = fr->cginfo_mb; + const cginfo_mb_t* cginfo_mb = fr->cginfo_mb; /* Temporarily store atoms passed to our rank at the end of the range */ int home_pos_cg = dd->ncg_home; @@ -755,39 +745,36 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, { DDBufferAccess rvecBuffer(comm->rvecBuffer, 0); - const int dim = dd->dim[d]; - int ncg_recv = 0; - int nvr = 0; + const int dim = dd->dim[d]; + int ncg_recv = 0; + int nvr = 0; for (int dir = 0; dir < (dd->nc[dim] == 2 ? 1 : 2); dir++) { - const int cdd = d*2 + dir; + const int cdd = d * 2 + dir; /* Communicate the cg and atom counts */ - int sbuf[2] = { ncg[cdd], nat[cdd] }; + int sbuf[2] = { ncg[cdd], nat[cdd] }; if (debug) { - fprintf(debug, "Sending ddim %d dir %d: ncg %d nat %d\n", - d, dir, sbuf[0], sbuf[1]); + fprintf(debug, "Sending ddim %d dir %d: ncg %d nat %d\n", d, dir, sbuf[0], sbuf[1]); } int rbuf[2]; ddSendrecv(dd, d, dir, sbuf, 2, rbuf, 2); - flagBuffer.resize((ncg_recv + rbuf[0])*DD_CGIBS); + flagBuffer.resize((ncg_recv + rbuf[0]) * DD_CGIBS); /* Communicate the charge group indices, sizes and flags */ - ddSendrecv(dd, d, dir, - comm->cggl_flag[cdd].data(), sbuf[0]*DD_CGIBS, - flagBuffer.buffer.data() + ncg_recv*DD_CGIBS, rbuf[0]*DD_CGIBS); + ddSendrecv(dd, d, dir, comm->cggl_flag[cdd].data(), sbuf[0] * DD_CGIBS, + flagBuffer.buffer.data() + ncg_recv * DD_CGIBS, rbuf[0] * DD_CGIBS); - const int nvs = ncg[cdd] + nat[cdd]*nvec; - const int i = rbuf[0] + rbuf[1] *nvec; + const int nvs = ncg[cdd] + nat[cdd] * nvec; + const int i = rbuf[0] + rbuf[1] * nvec; rvecBuffer.resize(nvr + i); /* Communicate cgcm and state */ - ddSendrecv(dd, d, dir, - as_rvec_array(comm->cgcm_state[cdd].data()), nvs, + ddSendrecv(dd, d, dir, as_rvec_array(comm->cgcm_state[cdd].data()), nvs, as_rvec_array(rvecBuffer.buffer.data()) + nvr, i); ncg_recv += rbuf[0]; - nvr += i; + nvr += i; } dd_check_alloc_ncg(fr, state, f, home_pos_cg + ncg_recv); @@ -797,29 +784,25 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, for (int cg = 0; cg < ncg_recv; cg++) { /* Extract the move flags and COG for the charge or update group */ - int flag = flagBuffer.buffer[cg*DD_CGIBS + 1]; - const gmx::RVec &cog = rvecBuffer.buffer[buf_pos]; + int flag = flagBuffer.buffer[cg * DD_CGIBS + 1]; + const gmx::RVec& cog = rvecBuffer.buffer[buf_pos]; if (dim >= npbcdim && dd->nc[dim] > 2) { /* No pbc in this dim and more than one domain boundary. * We do a separate check if a charge group didn't move too far. */ - if (((flag & DD_FLAG_FW(d)) && - cog[dim] > cell_x1[dim]) || - ((flag & DD_FLAG_BW(d)) && - cog[dim] < cell_x0[dim])) + if (((flag & DD_FLAG_FW(d)) && cog[dim] > cell_x1[dim]) + || ((flag & DD_FLAG_BW(d)) && cog[dim] < cell_x0[dim])) { rvec pos = { cog[0], cog[1], cog[2] }; - cg_move_error(fplog, dd, step, cg, dim, - (flag & DD_FLAG_FW(d)) ? 1 : 0, - false, 0, - pos, pos, pos[dim]); + cg_move_error(fplog, dd, step, cg, dim, (flag & DD_FLAG_FW(d)) ? 1 : 0, false, + 0, pos, pos, pos[dim]); } } int mc = -1; - if (d < dd->ndim-1) + if (d < dd->ndim - 1) { /* Check which direction this cg should go */ for (int d2 = d + 1; (d2 < dd->ndim && mc == -1); d2++) @@ -836,10 +819,8 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, * so we do not need to handle boundary crossings. * This also means we do not have to handle PBC here. */ - if (!((dd->ci[dim2] == dd->nc[dim2]-1 && - (flag & DD_FLAG_FW(d2))) || - (dd->ci[dim2] == 0 && - (flag & DD_FLAG_BW(d2))))) + if (!((dd->ci[dim2] == dd->nc[dim2] - 1 && (flag & DD_FLAG_FW(d2))) + || (dd->ci[dim2] == 0 && (flag & DD_FLAG_BW(d2))))) { /* Clear the two flags for this dimension */ flag &= ~(DD_FLAG_FW(d2) | DD_FLAG_BW(d2)); @@ -849,9 +830,9 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, real pos_d = cog[dim2]; if (tric_dir[dim2]) { - for (int d3 = dim2+1; d3 < DIM; d3++) + for (int d3 = dim2 + 1; d3 < DIM; d3++) { - pos_d += cog[d3]*tcm[d3][dim2]; + pos_d += cog[d3] * tcm[d3][dim2]; } } @@ -861,76 +842,71 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, * to an adjacent cell because of the * staggering. */ - if (pos_d >= cell_x1[dim2] && - dd->ci[dim2] != dd->nc[dim2]-1) + if (pos_d >= cell_x1[dim2] && dd->ci[dim2] != dd->nc[dim2] - 1) { flag |= DD_FLAG_FW(d2); } - else if (pos_d < cell_x0[dim2] && - dd->ci[dim2] != 0) + else if (pos_d < cell_x0[dim2] && dd->ci[dim2] != 0) { flag |= DD_FLAG_BW(d2); } - flagBuffer.buffer[cg*DD_CGIBS + 1] = flag; + flagBuffer.buffer[cg * DD_CGIBS + 1] = flag; } } /* Set to which neighboring cell this cg should go */ if (flag & DD_FLAG_FW(d2)) { - mc = d2*2; + mc = d2 * 2; } else if (flag & DD_FLAG_BW(d2)) { if (dd->nc[dd->dim[d2]] > 2) { - mc = d2*2+1; + mc = d2 * 2 + 1; } else { - mc = d2*2; + mc = d2 * 2; } } } } - GMX_ASSERT((flag & DD_FLAG_NRCG) == 1, "Charge groups are gone, so all groups should have size 1"); + GMX_ASSERT((flag & DD_FLAG_NRCG) == 1, + "Charge groups are gone, so all groups should have size 1"); constexpr int nrcg = 1; if (mc == -1) { /* Set the global charge group index and size */ - const int globalAtomGroupIndex = flagBuffer.buffer[cg*DD_CGIBS]; + const int globalAtomGroupIndex = flagBuffer.buffer[cg * DD_CGIBS]; dd->globalAtomGroupIndices.push_back(globalAtomGroupIndex); /* Skip the COG entry in the buffer */ buf_pos++; /* Set the cginfo */ - fr->cginfo[home_pos_cg] = ddcginfo(cginfo_mb, - globalAtomGroupIndex); + fr->cginfo[home_pos_cg] = ddcginfo(cginfo_mb, globalAtomGroupIndex); auto x = makeArrayRef(state->x); auto v = makeArrayRef(state->v); auto cg_p = makeArrayRef(state->cg_p); - rvec *rvecPtr = as_rvec_array(rvecBuffer.buffer.data()); + rvec* rvecPtr = as_rvec_array(rvecBuffer.buffer.data()); for (int i = 0; i < nrcg; i++) { - copy_rvec(rvecPtr[buf_pos++], - x[home_pos_at+i]); + copy_rvec(rvecPtr[buf_pos++], x[home_pos_at + i]); } if (bV) { for (int i = 0; i < nrcg; i++) { - copy_rvec(rvecPtr[buf_pos++], - v[home_pos_at+i]); + copy_rvec(rvecPtr[buf_pos++], v[home_pos_at + i]); } } if (bCGP) { for (int i = 0; i < nrcg; i++) { - copy_rvec(rvecPtr[buf_pos++], - cg_p[home_pos_at+i]); + copy_rvec(rvecPtr[buf_pos++], cg_p[home_pos_at + i]); } } home_pos_cg += 1; @@ -939,23 +915,21 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, else { /* Reallocate the buffers if necessary */ - if ((ncg[mc] + 1)*DD_CGIBS > gmx::index(comm->cggl_flag[mc].size())) + if ((ncg[mc] + 1) * DD_CGIBS > gmx::index(comm->cggl_flag[mc].size())) { - comm->cggl_flag[mc].resize((ncg[mc] + 1)*DD_CGIBS); + comm->cggl_flag[mc].resize((ncg[mc] + 1) * DD_CGIBS); } - size_t nvr = ncg[mc] + nat[mc]*nvec; - if (nvr + 1 + nrcg*nvec > comm->cgcm_state[mc].size()) + size_t nvr = ncg[mc] + nat[mc] * nvec; + if (nvr + 1 + nrcg * nvec > comm->cgcm_state[mc].size()) { - comm->cgcm_state[mc].resize(nvr + 1 + nrcg*nvec); + comm->cgcm_state[mc].resize(nvr + 1 + nrcg * nvec); } /* Copy from the receive to the send buffers */ - memcpy(comm->cggl_flag[mc].data() + ncg[mc]*DD_CGIBS, - flagBuffer.buffer.data() + cg*DD_CGIBS, - DD_CGIBS*sizeof(int)); - memcpy(comm->cgcm_state[mc][nvr], - rvecBuffer.buffer.data() + buf_pos, - (1 + nrcg*nvec)*sizeof(rvec)); - buf_pos += 1 + nrcg*nvec; + memcpy(comm->cggl_flag[mc].data() + ncg[mc] * DD_CGIBS, + flagBuffer.buffer.data() + cg * DD_CGIBS, DD_CGIBS * sizeof(int)); + memcpy(comm->cgcm_state[mc][nvr], rvecBuffer.buffer.data() + buf_pos, + (1 + nrcg * nvec) * sizeof(rvec)); + buf_pos += 1 + nrcg * nvec; ncg[mc] += 1; nat[mc] += nrcg; } @@ -972,7 +946,7 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, */ moved = getMovedBuffer(comm, dd->ncg_home, home_pos_cg); - for (int i = dd->ncg_home; i < home_pos_cg; i++) + for (int i = dd->ncg_home; i < home_pos_cg; i++) { moved[i] = 0; } @@ -982,9 +956,7 @@ void dd_redistribute_cg(FILE *fplog, int64_t step, if (debug) { - fprintf(debug, - "Finished repartitioning: cgs moved out %d, new home %d\n", - *ncg_moved, dd->ncg_home-*ncg_moved); - + fprintf(debug, "Finished repartitioning: cgs moved out %d, new home %d\n", *ncg_moved, + dd->ncg_home - *ncg_moved); } } diff --git a/src/gromacs/domdec/redistribute.h b/src/gromacs/domdec/redistribute.h index 64803a346b..732094f4d7 100644 --- a/src/gromacs/domdec/redistribute.h +++ b/src/gromacs/domdec/redistribute.h @@ -53,14 +53,14 @@ struct t_nrnb; class t_state; /*! \brief Redistribute the atoms to their, new, local domains */ -void dd_redistribute_cg(FILE *fplog, +void dd_redistribute_cg(FILE* fplog, int64_t step, - gmx_domdec_t *dd, + gmx_domdec_t* dd, ivec tric_dir, - t_state *state, - gmx::PaddedHostVector *f, - t_forcerec *fr, - t_nrnb *nrnb, - int *ncg_moved); + t_state* state, + gmx::PaddedHostVector* f, + t_forcerec* fr, + t_nrnb* nrnb, + int* ncg_moved); #endif diff --git a/src/gromacs/domdec/tests/hashedmap.cpp b/src/gromacs/domdec/tests/hashedmap.cpp index 0a91defb91..7157633e1d 100644 --- a/src/gromacs/domdec/tests/hashedmap.cpp +++ b/src/gromacs/domdec/tests/hashedmap.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,11 +51,9 @@ namespace { /*! \brief Checks that the key is found and if so also checks the value */ -void checkFinds(const gmx::HashedMap &map, - int key, - char value) +void checkFinds(const gmx::HashedMap& map, int key, char value) { - const char *pointer = map.find(key); + const char* pointer = map.find(key); EXPECT_FALSE(pointer == nullptr); if (pointer) { @@ -64,10 +62,9 @@ void checkFinds(const gmx::HashedMap &map, } /*! \brief Checks that the key is not found */ -void checkDoesNotFind(const gmx::HashedMap &map, - int key) +void checkDoesNotFind(const gmx::HashedMap& map, int key) { - const char *pointer = map.find(key); + const char* pointer = map.find(key); EXPECT_TRUE(pointer == nullptr); } @@ -76,12 +73,12 @@ TEST(HashedMap, InsertsFinds) gmx::HashedMap map(2); map.insert(10, 'a'); - map.insert(5, 'b'); - map.insert(7, 'c'); + map.insert(5, 'b'); + map.insert(7, 'c'); checkFinds(map, 10, 'a'); - checkFinds(map, 5, 'b'); - checkFinds(map, 7, 'c'); + checkFinds(map, 5, 'b'); + checkFinds(map, 7, 'c'); checkDoesNotFind(map, 4); } @@ -90,11 +87,11 @@ TEST(HashedMap, NegativeKeysWork) gmx::HashedMap map(5); map.insert(-1, 'a'); - map.insert(1, 'b'); + map.insert(1, 'b'); map.insert(-3, 'c'); checkFinds(map, -1, 'a'); - checkFinds(map, 1, 'b'); + checkFinds(map, 1, 'b'); checkFinds(map, -3, 'c'); } @@ -103,8 +100,8 @@ TEST(HashedMap, InsertsErases) gmx::HashedMap map(3); map.insert(10, 'a'); - map.insert(5, 'b'); - map.insert(7, 'c'); + map.insert(5, 'b'); + map.insert(7, 'c'); checkFinds(map, 10, 'a'); map.erase(10); @@ -116,7 +113,7 @@ TEST(HashedMap, InsertsOrAssigns) gmx::HashedMap map(3); map.insert(10, 'a'); - map.insert(5, 'b'); + map.insert(5, 'b'); map.insert_or_assign(7, 'c'); checkFinds(map, 7, 'c'); @@ -131,8 +128,8 @@ TEST(HashedMap, Clears) gmx::HashedMap map(3); map.insert(10, 'a'); - map.insert(5, 'b'); - map.insert(7, 'c'); + map.insert(5, 'b'); + map.insert(7, 'c'); map.clear(); checkDoesNotFind(map, 10); @@ -148,22 +145,22 @@ TEST(HashedMap, LinkedEntries) gmx::HashedMap map(20); - const int largePowerOf2 = 2048; + const int largePowerOf2 = 2048; - map.insert(3 + 0*largePowerOf2, 'a'); - map.insert(3 + 1*largePowerOf2, 'b'); - map.insert(3 + 2*largePowerOf2, 'c'); + map.insert(3 + 0 * largePowerOf2, 'a'); + map.insert(3 + 1 * largePowerOf2, 'b'); + map.insert(3 + 2 * largePowerOf2, 'c'); - checkFinds(map, 3 + 0*largePowerOf2, 'a'); - checkFinds(map, 3 + 1*largePowerOf2, 'b'); - checkFinds(map, 3 + 2*largePowerOf2, 'c'); + checkFinds(map, 3 + 0 * largePowerOf2, 'a'); + checkFinds(map, 3 + 1 * largePowerOf2, 'b'); + checkFinds(map, 3 + 2 * largePowerOf2, 'c'); // Erase the middle entry in the linked list - map.erase(3 + 1*largePowerOf2); + map.erase(3 + 1 * largePowerOf2); - checkFinds(map, 3 + 0*largePowerOf2, 'a'); - checkDoesNotFind(map, 3 + 1*largePowerOf2); - checkFinds(map, 3 + 2*largePowerOf2, 'c'); + checkFinds(map, 3 + 0 * largePowerOf2, 'a'); + checkDoesNotFind(map, 3 + 1 * largePowerOf2); + checkFinds(map, 3 + 2 * largePowerOf2, 'c'); } // HashedMap only throws in debug mode, so only test in debug mode @@ -174,7 +171,7 @@ TEST(HashedMap, CatchesDuplicateKey) gmx::HashedMap map(15); map.insert(10, 'a'); - map.insert(5, 'b'); + map.insert(5, 'b'); EXPECT_THROW_GMX(map.insert(10, 'c'), gmx::InvalidInputError); } @@ -190,7 +187,7 @@ TEST(HashedMap, ResizesTable) for (int i = 0; i < 60; i++) { - map.insert(2*i + 3, 'a'); + map.insert(2 * i + 3, 'a'); } EXPECT_LT(map.bucket_count(), 128); @@ -210,4 +207,4 @@ TEST(HashedMap, ResizesTable) EXPECT_LT(map.bucket_count(), 128); } -} // namespace +} // namespace diff --git a/src/gromacs/domdec/tests/localatomsetmanager.cpp b/src/gromacs/domdec/tests/localatomsetmanager.cpp index aaf2129b54..282ad6824e 100644 --- a/src/gromacs/domdec/tests/localatomsetmanager.cpp +++ b/src/gromacs/domdec/tests/localatomsetmanager.cpp @@ -65,21 +65,22 @@ namespace test TEST(LocalAtomSetManager, CanAddEmptyLocalAtomSet) { - LocalAtomSetManager manager; - const std::vector emptyIndex = {}; - LocalAtomSet emptyGroup(manager.add(emptyIndex)); - const std::vector globalIndexFromGroup(emptyGroup.globalIndex().begin(), emptyGroup.globalIndex().end()); + LocalAtomSetManager manager; + const std::vector emptyIndex = {}; + LocalAtomSet emptyGroup(manager.add(emptyIndex)); + const std::vector globalIndexFromGroup(emptyGroup.globalIndex().begin(), + emptyGroup.globalIndex().end()); ASSERT_THAT(globalIndexFromGroup, testing::ContainerEq(emptyIndex)); } TEST(LocalAtomSetManager, CanAddandReadLocalAtomSetIndices) { - LocalAtomSetManager manager; + LocalAtomSetManager manager; - const std::vector index = {5, 10}; + const std::vector index = { 5, 10 }; LocalAtomSet newGroup(manager.add(index)); std::vector readIndex; - for (const auto &i : newGroup.localIndex()) + for (const auto& i : newGroup.localIndex()) { readIndex.push_back(i); } diff --git a/src/gromacs/domdec/utility.cpp b/src/gromacs/domdec/utility.cpp index 04db3df952..01db3ead59 100644 --- a/src/gromacs/domdec/utility.cpp +++ b/src/gromacs/domdec/utility.cpp @@ -69,7 +69,7 @@ void make_tric_corr_matrix(int npbcdim, const matrix box, matrix tcm) { if (YY < npbcdim) { - tcm[YY][XX] = -box[YY][XX]/box[YY][YY]; + tcm[YY][XX] = -box[YY][XX] / box[YY][YY]; } else { @@ -77,8 +77,8 @@ void make_tric_corr_matrix(int npbcdim, const matrix box, matrix tcm) } if (ZZ < npbcdim) { - tcm[ZZ][XX] = -(box[ZZ][YY]*tcm[YY][XX] + box[ZZ][XX])/box[ZZ][ZZ]; - tcm[ZZ][YY] = -box[ZZ][YY]/box[ZZ][ZZ]; + tcm[ZZ][XX] = -(box[ZZ][YY] * tcm[YY][XX] + box[ZZ][XX]) / box[ZZ][ZZ]; + tcm[ZZ][YY] = -box[ZZ][YY] / box[ZZ][ZZ]; } else { @@ -92,7 +92,8 @@ void check_screw_box(const matrix box) /* Mathematical limitation */ if (box[YY][XX] != 0 || box[ZZ][XX] != 0) { - gmx_fatal(FARGS, "With screw pbc the unit cell can not have non-zero off-diagonal x-components"); + gmx_fatal(FARGS, + "With screw pbc the unit cell can not have non-zero off-diagonal x-components"); } /* Limitation due to the asymmetry of the eighth shell method */ @@ -102,9 +103,7 @@ void check_screw_box(const matrix box) } } /*! \brief Resize the state and f*/ -void dd_resize_state(t_state *state, - PaddedHostVector *f, - int natoms) +void dd_resize_state(t_state* state, PaddedHostVector* f, int natoms) { if (debug) { @@ -127,10 +126,7 @@ void dd_resize_state(t_state *state, * * todo refactor this now that group scheme is removed */ -void dd_check_alloc_ncg(t_forcerec *fr, - t_state *state, - PaddedHostVector *f, - int numChargeGroups) +void dd_check_alloc_ncg(t_forcerec* fr, t_state* state, PaddedHostVector* f, int numChargeGroups) { fr->cginfo.resize(numChargeGroups); diff --git a/src/gromacs/domdec/utility.h b/src/gromacs/domdec/utility.h index dbab6cbe99..9d7db1f112 100644 --- a/src/gromacs/domdec/utility.h +++ b/src/gromacs/domdec/utility.h @@ -48,23 +48,21 @@ #include "domdec_internal.h" /*! \brief Returns true if the DLB state indicates that the balancer is on. */ -static inline bool isDlbOn(const gmx_domdec_comm_t *comm) +static inline bool isDlbOn(const gmx_domdec_comm_t* comm) { - return (comm->dlbState == DlbState::onCanTurnOff || - comm->dlbState == DlbState::onUser); + return (comm->dlbState == DlbState::onCanTurnOff || comm->dlbState == DlbState::onUser); }; /*! \brief Returns true if the DLB state indicates that the balancer is off/disabled. */ -static inline bool isDlbDisabled(const DlbState &dlbState) +static inline bool isDlbDisabled(const DlbState& dlbState) { - return (dlbState == DlbState::offUser || - dlbState == DlbState::offForever); + return (dlbState == DlbState::offUser || dlbState == DlbState::offForever); }; /*! \brief Returns true if the DLB state indicates that the balancer is off/disabled. */ -static inline bool isDlbDisabled(const gmx_domdec_comm_t *comm) +static inline bool isDlbDisabled(const gmx_domdec_comm_t* comm) { return isDlbDisabled(comm->dlbState); }; @@ -79,8 +77,7 @@ void make_tric_corr_matrix(int npbcdim, const matrix box, matrix tcm); void check_screw_box(const matrix box); /*! \brief Return the charge group information flags for charge group cg */ -static inline int ddcginfo(const cginfo_mb_t *cginfo_mb, - int cg) +static inline int ddcginfo(const cginfo_mb_t* cginfo_mb, int cg) { while (cg >= cginfo_mb->cg_end) { @@ -91,7 +88,7 @@ static inline int ddcginfo(const cginfo_mb_t *cginfo_mb, }; /*! \brief Returns the number of MD steps for which load has been recorded */ -static inline int dd_load_count(const gmx_domdec_comm_t *comm) +static inline int dd_load_count(const gmx_domdec_comm_t* comm) { return (comm->ddSettings.eFlop ? comm->flop_n : comm->cycl_n[ddCyclF]); } @@ -102,9 +99,7 @@ static inline int dd_load_count(const gmx_domdec_comm_t *comm) * \param[in] f The vector of forces to be resized * \param[out] natoms New number of atoms to accommodate */ -void dd_resize_state(t_state *state, - gmx::PaddedHostVector *f, - int natoms); +void dd_resize_state(t_state* state, gmx::PaddedHostVector* f, int natoms); /*! \brief Enrsure fr, state and f, if != nullptr, can hold numChargeGroups atoms for the Verlet scheme and charge groups for the group scheme * @@ -113,28 +108,21 @@ void dd_resize_state(t_state *state, * \param[in] f The force buffer * \param[out] numChargeGroups Number of charged groups */ -void dd_check_alloc_ncg(t_forcerec *fr, - t_state *state, - gmx::PaddedHostVector *f, - int numChargeGroups); +void dd_check_alloc_ncg(t_forcerec* fr, t_state* state, gmx::PaddedHostVector* f, int numChargeGroups); /*! \brief Returns a domain-to-domain cutoff distance given an atom-to-atom cutoff */ -static inline real -atomToAtomIntoDomainToDomainCutoff(const DDSystemInfo &systemInfo, - real cutoff) +static inline real atomToAtomIntoDomainToDomainCutoff(const DDSystemInfo& systemInfo, real cutoff) { if (systemInfo.useUpdateGroups) { - cutoff += 2*systemInfo.maxUpdateGroupRadius; + cutoff += 2 * systemInfo.maxUpdateGroupRadius; } return cutoff; } /*! \brief Returns an atom-to-domain cutoff distance given a domain-to-domain cutoff */ -static inline real -domainToDomainIntoAtomToDomainCutoff(const DDSystemInfo &systemInfo, - real cutoff) +static inline real domainToDomainIntoAtomToDomainCutoff(const DDSystemInfo& systemInfo, real cutoff) { if (systemInfo.useUpdateGroups) { diff --git a/src/gromacs/energyanalysis/tests/legacyenergy.cpp b/src/gromacs/energyanalysis/tests/legacyenergy.cpp index cf7b5e25b1..871c687094 100644 --- a/src/gromacs/energyanalysis/tests/legacyenergy.cpp +++ b/src/gromacs/energyanalysis/tests/legacyenergy.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,19 +65,19 @@ namespace class DhdlTest : public CommandLineTestBase { - public: - void runTest() - { - auto &cmdline = commandLine(); +public: + void runTest() + { + auto& cmdline = commandLine(); - setInputFile("-s", "dhdl.tpr"); - setInputFile("-f", "dhdl.edr"); - setOutputFile("-odh", "dhdl.xvg", XvgMatch()); + setInputFile("-s", "dhdl.tpr"); + setInputFile("-f", "dhdl.edr"); + setOutputFile("-odh", "dhdl.xvg", XvgMatch()); - ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); + ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } + checkOutputFiles(); + } }; TEST_F(DhdlTest, ExtractDhdl) @@ -87,28 +87,28 @@ TEST_F(DhdlTest, ExtractDhdl) class OriresTest : public CommandLineTestBase { - public: - void runTest(const char *stringForStdin) - { - auto &cmdline = commandLine(); - - setInputFile("-s", "orires.tpr"); - setInputFile("-f", "orires.edr"); - test::XvgMatch xvg; - test::XvgMatch &toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, 1e-4)); - - setOutputFile("-oten", ".xvg", toler); - setOutputFile("-ora", ".xvg", toler); - setOutputFile("-ort", ".xvg", toler); - setOutputFile("-oda", ".xvg", toler); - setOutputFile("-odr", ".xvg", toler); - - StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin(stringForStdin); - ASSERT_EQ(0, gmx_nmr(cmdline.argc(), cmdline.argv())); - - checkOutputFiles(); - } +public: + void runTest(const char* stringForStdin) + { + auto& cmdline = commandLine(); + + setInputFile("-s", "orires.tpr"); + setInputFile("-f", "orires.edr"); + test::XvgMatch xvg; + test::XvgMatch& toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, 1e-4)); + + setOutputFile("-oten", ".xvg", toler); + setOutputFile("-ora", ".xvg", toler); + setOutputFile("-ort", ".xvg", toler); + setOutputFile("-oda", ".xvg", toler); + setOutputFile("-odr", ".xvg", toler); + + StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin(stringForStdin); + ASSERT_EQ(0, gmx_nmr(cmdline.argc(), cmdline.argv())); + + checkOutputFiles(); + } }; TEST_F(OriresTest, ExtractOrires) @@ -118,25 +118,25 @@ TEST_F(OriresTest, ExtractOrires) class EnergyTest : public CommandLineTestBase { - public: - void runTest(const char *stringForStdin) - { - auto &cmdline = commandLine(); - - setInputFile("-f", "ener.edr"); - setOutputFile("-o", "energy.xvg", XvgMatch()); - - StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin(stringForStdin); - ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); - - // All the .edr files used in the tests contain only - // single-precision values, so even from a - // double-precision build they should conform to - // tolerances suitable for single-precision values. - setDefaultTolerance(defaultFloatTolerance()); - checkOutputFiles(); - } +public: + void runTest(const char* stringForStdin) + { + auto& cmdline = commandLine(); + + setInputFile("-f", "ener.edr"); + setOutputFile("-o", "energy.xvg", XvgMatch()); + + StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin(stringForStdin); + ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); + + // All the .edr files used in the tests contain only + // single-precision values, so even from a + // double-precision build they should conform to + // tolerances suitable for single-precision values. + setDefaultTolerance(defaultFloatTolerance()); + checkOutputFiles(); + } }; TEST_F(EnergyTest, ExtractEnergy) @@ -156,34 +156,34 @@ TEST_F(EnergyTest, ExtractEnergyMixed) class ViscosityTest : public CommandLineTestBase { - public: - void runTest() +public: + void runTest() + { + auto& cmdline = commandLine(); + setInputFile("-f", "ener.edr"); + setOutputFile("-vis", "visco.xvg", NoTextMatch()); + setOutputFile("-o", "energy.xvg", NoTextMatch()); + + /* -vis can write a lot of non-conditional output files, + so we use temporary paths to clean up files that are + not the ones being tested in this test */ + if (!cmdline.contains("-evisco")) + { + setOutputFile("-evisco", "evisco.xvg", NoTextMatch()); + } + if (!cmdline.contains("-eviscoi")) { - auto &cmdline = commandLine(); - setInputFile("-f", "ener.edr"); - setOutputFile("-vis", "visco.xvg", NoTextMatch()); - setOutputFile("-o", "energy.xvg", NoTextMatch()); - - /* -vis can write a lot of non-conditional output files, - so we use temporary paths to clean up files that are - not the ones being tested in this test */ - if (!cmdline.contains("-evisco")) - { - setOutputFile("-evisco", "evisco.xvg", NoTextMatch()); - } - if (!cmdline.contains("-eviscoi")) - { - setOutputFile("-eviscoi", "eviscoi.xvg", NoTextMatch()); - } - if (!cmdline.contains("-corr")) - { - setOutputFile("-corr", "corr.xvg", NoTextMatch()); - } - - ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); - - checkOutputFiles(); + setOutputFile("-eviscoi", "eviscoi.xvg", NoTextMatch()); } + if (!cmdline.contains("-corr")) + { + setOutputFile("-corr", "corr.xvg", NoTextMatch()); + } + + ASSERT_EQ(0, gmx_energy(cmdline.argc(), cmdline.argv())); + + checkOutputFiles(); + } }; TEST_F(ViscosityTest, EinsteinViscosity) diff --git a/src/gromacs/essentialdynamics/edsam.cpp b/src/gromacs/essentialdynamics/edsam.cpp index 2b9fd374a6..70a2a6b86a 100644 --- a/src/gromacs/essentialdynamics/edsam.cpp +++ b/src/gromacs/essentialdynamics/edsam.cpp @@ -113,21 +113,21 @@ enum class EssentialDynamicsStructure struct t_eigvec { //! nr of eigenvectors - int neig = 0; + int neig = 0; //! index nrs of eigenvectors - int *ieig = nullptr; + int* ieig = nullptr; //! stepsizes (per eigenvector) - real *stpsz = nullptr; + real* stpsz = nullptr; //! eigenvector components - rvec **vec = nullptr; + rvec** vec = nullptr; //! instantaneous x projections - real *xproj = nullptr; + real* xproj = nullptr; //! instantaneous f projections - real *fproj = nullptr; + real* fproj = nullptr; //! instantaneous radius - real radius = 0.; + real radius = 0.; //! starting or target projections - real *refproj = nullptr; + real* refproj = nullptr; }; /*! \brief Essential dynamics vectors per method implementation. @@ -135,17 +135,17 @@ struct t_eigvec struct t_edvecs { //! only monitored, no constraints - t_eigvec mon = {}; + t_eigvec mon = {}; //! fixed linear constraints - t_eigvec linfix = {}; + t_eigvec linfix = {}; //! acceptance linear constraints - t_eigvec linacc = {}; + t_eigvec linacc = {}; //! fixed radial constraints (exp) - t_eigvec radfix = {}; + t_eigvec radfix = {}; //! acceptance radial constraints (exp) - t_eigvec radacc = {}; + t_eigvec radacc = {}; //! acceptance rad. contraction constr. - t_eigvec radcon = {}; + t_eigvec radcon = {}; }; /*! \brief Essential dynamics flooding parameters and work data. @@ -160,35 +160,35 @@ struct t_edflood /*! \brief Target destabilisation free energy. * Controls the flooding potential strength. * Linked to the expected speed-up of mean first passage time out of flooded minimum */ - real deltaF0 = 0; + real deltaF0 = 0; //! Do not calculate a flooding potential, instead flood with a constant force - bool bConstForce = false; + bool bConstForce = false; //! Relaxation time scale for slowest flooded degree of freedom - real tau = 0; + real tau = 0; //! Current estimated destabilisation free energy - real deltaF = 0; + real deltaF = 0; //! Flooding energy, acting as a proportionality factor for the flooding potential - real Efl = 0; + real Efl = 0; //! Boltzmann constant times temperature, provided by user - real kT = 0; + real kT = 0; //! The flooding potential - real Vfl = 0; + real Vfl = 0; //! Integration time step - real dt = 0; + real dt = 0; //! Inital flooding strenth - real constEfl = 0; + real constEfl = 0; //! Empirical global scaling parameter of the essential dynamics vectors. - real alpha2 = 0; + real alpha2 = 0; //! The forces from flooding in atom coordinate space (in contrast to projections onto essential dynamics vectors) - rvec *forces_cartesian = nullptr; + rvec* forces_cartesian = nullptr; //! The vectors along which to flood t_eigvec vecs = {}; //! Use flooding for harmonic restraint on the eigenvector - bool bHarmonic = false; + bool bHarmonic = false; //! The initial reference projection of the flooding vectors. Only with harmonic restraint. - real *initialReferenceProjection = nullptr; + real* initialReferenceProjection = nullptr; //! The current reference projection is the initialReferenceProjection + step * slope. Only with harmonic restraint. - real *referenceProjectionSlope = nullptr; + real* referenceProjectionSlope = nullptr; }; } // namespace @@ -196,53 +196,53 @@ struct t_edflood /* This type is for the average, reference, target, and origin structure */ struct gmx_edx { - int nr = 0; /* number of atoms this structure contains */ - int nr_loc = 0; /* number of atoms on local node */ - int *anrs = nullptr; /* atom index numbers */ - int *anrs_loc = nullptr; /* local atom index numbers */ - int nalloc_loc = 0; /* allocation size of anrs_loc */ - int *c_ind = nullptr; /* at which position of the whole anrs - * array is a local atom?, i.e. - * c_ind[0...nr_loc-1] gives the atom index - * with respect to the collective - * anrs[0...nr-1] array */ - rvec *x = nullptr; /* positions for this structure */ - rvec *x_old = nullptr; /* Last positions which have the correct PBC - representation of the ED group. In - combination with keeping track of the - shift vectors, the ED group can always - be made whole */ - real *m = nullptr; /* masses */ - real mtot = 0.; /* total mass (only used in sref) */ - real *sqrtm = nullptr; /* sqrt of the masses used for mass- - * weighting of analysis (only used in sav) */ + int nr = 0; /* number of atoms this structure contains */ + int nr_loc = 0; /* number of atoms on local node */ + int* anrs = nullptr; /* atom index numbers */ + int* anrs_loc = nullptr; /* local atom index numbers */ + int nalloc_loc = 0; /* allocation size of anrs_loc */ + int* c_ind = nullptr; /* at which position of the whole anrs + * array is a local atom?, i.e. + * c_ind[0...nr_loc-1] gives the atom index + * with respect to the collective + * anrs[0...nr-1] array */ + rvec* x = nullptr; /* positions for this structure */ + rvec* x_old = nullptr; /* Last positions which have the correct PBC + representation of the ED group. In + combination with keeping track of the + shift vectors, the ED group can always + be made whole */ + real* m = nullptr; /* masses */ + real mtot = 0.; /* total mass (only used in sref) */ + real* sqrtm = nullptr; /* sqrt of the masses used for mass- + * weighting of analysis (only used in sav) */ }; typedef struct edpar { - int nini = 0; /* total Nr of atoms */ - gmx_bool fitmas = false; /* true if trans fit with cm */ - gmx_bool pcamas = false; /* true if mass-weighted PCA */ - int presteps = 0; /* number of steps to run without any - * perturbations ... just monitoring */ - int outfrq = 0; /* freq (in steps) of writing to edo */ - int maxedsteps = 0; /* max nr of steps per cycle */ + int nini = 0; /* total Nr of atoms */ + gmx_bool fitmas = false; /* true if trans fit with cm */ + gmx_bool pcamas = false; /* true if mass-weighted PCA */ + int presteps = 0; /* number of steps to run without any + * perturbations ... just monitoring */ + int outfrq = 0; /* freq (in steps) of writing to edo */ + int maxedsteps = 0; /* max nr of steps per cycle */ /* all gmx_edx datasets are copied to all nodes in the parallel case */ - gmx_edx sref = {}; /* reference positions, to these fitting - * will be done */ - gmx_bool bRefEqAv = false; /* If true, reference & average indices - * are the same. Used for optimization */ - gmx_edx sav = {}; /* average positions */ - gmx_edx star = {}; /* target positions */ - gmx_edx sori = {}; /* origin positions */ - - t_edvecs vecs = {}; /* eigenvectors */ - real slope = 0; /* minimal slope in acceptance radexp */ - - t_edflood flood = {}; /* parameters especially for flooding */ - struct t_ed_buffer *buf = nullptr; /* handle to local buffers */ + gmx_edx sref = {}; /* reference positions, to these fitting + * will be done */ + gmx_bool bRefEqAv = false; /* If true, reference & average indices + * are the same. Used for optimization */ + gmx_edx sav = {}; /* average positions */ + gmx_edx star = {}; /* target positions */ + gmx_edx sori = {}; /* origin positions */ + + t_edvecs vecs = {}; /* eigenvectors */ + real slope = 0; /* minimal slope in acceptance radexp */ + + t_edflood flood = {}; /* parameters especially for flooding */ + struct t_ed_buffer* buf = nullptr; /* handle to local buffers */ } t_edpar; @@ -252,9 +252,9 @@ struct gmx_edsam //! The type of ED EssentialDynamicsType eEDtype = EssentialDynamicsType::None; //! output file pointer - FILE *edo = nullptr; - std::vector edpar; - gmx_bool bFirst = false; + FILE* edo = nullptr; + std::vector edpar; + gmx_bool bFirst = false; }; gmx_edsam::~gmx_edsam() { @@ -272,15 +272,15 @@ struct t_do_edsam matrix old_rotmat; real oldrad; rvec old_transvec, older_transvec, transvec_compact; - rvec *xcoll; /* Positions from all nodes, this is the + rvec* xcoll; /* Positions from all nodes, this is the collective set we work on. These are the positions of atoms with average structure indices */ - rvec *xc_ref; /* same but with reference structure indices */ - ivec *shifts_xcoll; /* Shifts for xcoll */ - ivec *extra_shifts_xcoll; /* xcoll shift changes since last NS step */ - ivec *shifts_xc_ref; /* Shifts for xc_ref */ - ivec *extra_shifts_xc_ref; /* xc_ref shift changes since last NS step */ + rvec* xc_ref; /* same but with reference structure indices */ + ivec* shifts_xcoll; /* Shifts for xcoll */ + ivec* extra_shifts_xcoll; /* xcoll shift changes since last NS step */ + ivec* shifts_xc_ref; /* Shifts for xc_ref */ + ivec* extra_shifts_xc_ref; /* xc_ref shift changes since last NS step */ gmx_bool bUpdateShifts; /* TRUE in NS steps to indicate that the ED shifts for this ED group need to be updated */ @@ -290,35 +290,33 @@ struct t_do_edsam /* definition of ED buffer structure */ struct t_ed_buffer { - struct t_fit_to_ref * fit_to_ref; - struct t_do_edfit * do_edfit; - struct t_do_edsam * do_edsam; - struct t_do_radcon * do_radcon; + struct t_fit_to_ref* fit_to_ref; + struct t_do_edfit* do_edfit; + struct t_do_edsam* do_edsam; + struct t_do_radcon* do_radcon; }; namespace gmx { class EssentialDynamics::Impl { - public: - // TODO: move all fields from gmx_edsam here and remove gmx_edsam - gmx_edsam essentialDynamics_; +public: + // TODO: move all fields from gmx_edsam here and remove gmx_edsam + gmx_edsam essentialDynamics_; }; -EssentialDynamics::EssentialDynamics() : impl_(new Impl) -{ -} +EssentialDynamics::EssentialDynamics() : impl_(new Impl) {} EssentialDynamics::~EssentialDynamics() = default; -gmx_edsam *EssentialDynamics::getLegacyED() +gmx_edsam* EssentialDynamics::getLegacyED() { return &impl_->essentialDynamics_; } } // namespace gmx /* Function declarations */ -static void fit_to_reference(rvec *xcoll, rvec transvec, matrix rotmat, t_edpar *edi); -static void translate_and_rotate(rvec *x, int nat, rvec transvec, matrix rotmat); -static real rmsd_from_structure(rvec *x, struct gmx_edx *s); +static void fit_to_reference(rvec* xcoll, rvec transvec, matrix rotmat, t_edpar* edi); +static void translate_and_rotate(rvec* x, int nat, rvec transvec, matrix rotmat); +static real rmsd_from_structure(rvec* x, struct gmx_edx* s); namespace { /*! \brief Read in the essential dynamics input file and return its contents. @@ -327,20 +325,20 @@ namespace * \returns A vector of containing the essentiail dyanmics parameters. * NOTE: edi files may that it may contain several ED data sets from concatenated edi files. * The standard case would be a single ED data set, though. */ -std::vector read_edi_file(const char *fn, int nr_mdatoms); -} -static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_t *EDstate); -static void init_edsamstate(const gmx_edsam &ed, edsamhistory_t *EDstate); -static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oenv); +std::vector read_edi_file(const char* fn, int nr_mdatoms); +} // namespace +static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam& ed, edsamhistory_t* EDstate); +static void init_edsamstate(const gmx_edsam& ed, edsamhistory_t* EDstate); +static void write_edo_legend(gmx_edsam* ed, int nED, const gmx_output_env_t* oenv); /* End function declarations */ /* Define formats for the column width in the output file */ -const char EDcol_sfmt[] = "%17s"; -const char EDcol_efmt[] = "%17.5e"; -const char EDcol_ffmt[] = "%17f"; +const char EDcol_sfmt[] = "%17s"; +const char EDcol_efmt[] = "%17.5e"; +const char EDcol_ffmt[] = "%17f"; /* Define a formats for reading, otherwise cppcheck complains for scanf without width limits */ -const char max_ev_fmt_d[] = "%7d"; /* Number of eigenvectors. 9,999,999 should be enough */ +const char max_ev_fmt_d[] = "%7d"; /* Number of eigenvectors. 9,999,999 should be enough */ const char max_ev_fmt_lf[] = "%12lf"; const char max_ev_fmt_dlf[] = "%7d%12lf"; const char max_ev_fmt_dlflflf[] = "%7d%12lf%12lf%12lf"; @@ -352,16 +350,12 @@ namespace * \param[in] edi the essential dynamics parameters * \returns true if essential dyanmics constraints need to be performed */ -bool bNeedDoEdsam(const t_edpar &edi) +bool bNeedDoEdsam(const t_edpar& edi) { - return (edi.vecs.mon.neig != 0) - || (edi.vecs.linfix.neig != 0) - || (edi.vecs.linacc.neig != 0) - || (edi.vecs.radfix.neig != 0) - || (edi.vecs.radacc.neig != 0) - || (edi.vecs.radcon.neig != 0); + return (edi.vecs.mon.neig != 0) || (edi.vecs.linfix.neig != 0) || (edi.vecs.linacc.neig != 0) + || (edi.vecs.radfix.neig != 0) || (edi.vecs.radacc.neig != 0) || (edi.vecs.radcon.neig != 0); } -} // namespace +} // namespace /* Multiple ED groups will be labeled with letters instead of numbers @@ -390,7 +384,7 @@ namespace * \param[in] vec vector of coordinates to project onto * \return mass-weighted projection. */ -real projectx(const t_edpar &edi, rvec *xcoll, rvec *vec) +real projectx(const t_edpar& edi, rvec* xcoll, rvec* vec) { int i; real proj = 0.0; @@ -398,7 +392,7 @@ real projectx(const t_edpar &edi, rvec *xcoll, rvec *vec) for (i = 0; i < edi.sav.nr; i++) { - proj += edi.sav.sqrtm[i]*iprod(vec[i], xcoll[i]); + proj += edi.sav.sqrtm[i] * iprod(vec[i], xcoll[i]); } return proj; @@ -411,7 +405,7 @@ real projectx(const t_edpar &edi, rvec *xcoll, rvec *vec) * \param[in] x Coordinates to be projected * \param[out] vec eigenvector, radius and refproj are overwritten here */ -void rad_project(const t_edpar &edi, rvec *x, t_eigvec *vec) +void rad_project(const t_edpar& edi, rvec* x, t_eigvec* vec) { int i; real rad = 0.0; @@ -425,7 +419,7 @@ void rad_project(const t_edpar &edi, rvec *x, t_eigvec *vec) for (i = 0; i < vec->neig; i++) { vec->refproj[i] = projectx(edi, x, vec->vec[i]); - rad += gmx::square((vec->refproj[i]-vec->xproj[i])); + rad += gmx::square((vec->refproj[i] - vec->xproj[i])); } vec->radius = sqrt(rad); @@ -443,7 +437,7 @@ void rad_project(const t_edpar &edi, rvec *x, t_eigvec *vec) * \param[in,out] vec The eigenvectors * \param[in] edi essential dynamics parameters holding average structure and masses */ -void project_to_eigvectors(rvec *x, t_eigvec *vec, const t_edpar &edi) +void project_to_eigvectors(rvec* x, t_eigvec* vec, const t_edpar& edi) { if (!vec->neig) { @@ -470,8 +464,8 @@ void project_to_eigvectors(rvec *x, t_eigvec *vec, const t_edpar &edi) } // namespace /* Project vector x onto all edi->vecs (mon, linfix,...) */ -static void project(rvec *x, /* positions to project */ - t_edpar *edi) /* edi data set */ +static void project(rvec* x, /* positions to project */ + t_edpar* edi) /* edi data set */ { /* It is not more work to subtract the average position in every * subroutine again, because these routines are rarely used simultaneously */ @@ -489,34 +483,35 @@ namespace * \param[in] vec eigenvector * \returns distance */ -real calc_radius(const t_eigvec &vec) +real calc_radius(const t_eigvec& vec) { real rad = 0.0; for (int i = 0; i < vec.neig; i++) { - rad += gmx::square((vec.refproj[i]-vec.xproj[i])); + rad += gmx::square((vec.refproj[i] - vec.xproj[i])); } return rad = sqrt(rad); } -} // namespace +} // namespace -struct t_do_edfit { - double **omega; - double **om; +struct t_do_edfit +{ + double** omega; + double** om; }; -static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) +static void do_edfit(int natoms, rvec* xp, rvec* x, matrix R, t_edpar* edi) { /* this is a copy of do_fit with some modifications */ - int c, r, n, j, i, irot; - double d[6], xnr, xpc; - matrix vh, vk, u; - int index; - real max_d; + int c, r, n, j, i, irot; + double d[6], xnr, xpc; + matrix vh, vk, u; + int index; + real max_d; - struct t_do_edfit *loc; + struct t_do_edfit* loc; gmx_bool bFirst; if (edi->buf->do_edfit != nullptr) @@ -532,12 +527,12 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) if (bFirst) { - snew(loc->omega, 2*DIM); - snew(loc->om, 2*DIM); - for (i = 0; i < 2*DIM; i++) + snew(loc->omega, 2 * DIM); + snew(loc->om, 2 * DIM); + for (i = 0; i < 2 * DIM; i++) { - snew(loc->omega[i], 2*DIM); - snew(loc->om[i], 2*DIM); + snew(loc->omega[i], 2 * DIM); + snew(loc->om[i], 2 * DIM); } } @@ -560,8 +555,8 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) xpc = xp[n][c]; for (r = 0; (r < DIM); r++) { - xnr = x[n][r]; - u[c][r] += xnr*xpc; + xnr = x[n][r]; + u[c][r] += xnr * xpc; } } } @@ -574,8 +569,8 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) { if ((r >= 3) && (c < 3)) { - loc->omega[r][c] = u[r-3][c]; - loc->omega[c][r] = u[r-3][c]; + loc->omega[r][c] = u[r - 3][c]; + loc->omega[c][r] = u[r - 3][c]; } else { @@ -609,8 +604,8 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) d[index] = -10000; for (i = 0; (i < 3); i++) { - vh[j][i] = M_SQRT2*loc->om[i][index]; - vk[j][i] = M_SQRT2*loc->om[i+DIM][index]; + vh[j][i] = M_SQRT2 * loc->om[i][index]; + vk[j][i] = M_SQRT2 * loc->om[i + DIM][index]; } } @@ -619,9 +614,7 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) { for (r = 0; (r < 3); r++) { - R[c][r] = vk[0][r]*vh[0][c]+ - vk[1][r]*vh[1][c]+ - vk[2][r]*vh[2][c]; + R[c][r] = vk[0][r] * vh[0][c] + vk[1][r] * vh[1][c] + vk[2][r] * vh[2][c]; } } if (det(R) < 0) @@ -630,16 +623,14 @@ static void do_edfit(int natoms, rvec *xp, rvec *x, matrix R, t_edpar *edi) { for (r = 0; (r < 3); r++) { - R[c][r] = vk[0][r]*vh[0][c]+ - vk[1][r]*vh[1][c]- - vk[2][r]*vh[2][c]; + R[c][r] = vk[0][r] * vh[0][c] + vk[1][r] * vh[1][c] - vk[2][r] * vh[2][c]; } } } } -static void rmfit(int nat, rvec *xcoll, const rvec transvec, matrix rotmat) +static void rmfit(int nat, rvec* xcoll, const rvec transvec, matrix rotmat) { rvec vec; matrix tmat; @@ -720,7 +711,7 @@ namespace * \param[in] fp output file * \param[in] rmsd rmsd to reference structure */ -void write_edo_flood(const t_edpar &edi, FILE *fp, real rmsd) +void write_edo_flood(const t_edpar& edi, FILE* fp, real rmsd) { /* Output how well we fit to the reference structure */ fprintf(fp, EDcol_ffmt, rmsd); @@ -756,7 +747,7 @@ void write_edo_flood(const t_edpar &edi, FILE *fp, real rmsd) /* From flood.xproj compute the Vfl(x) at this point */ -static real flood_energy(t_edpar *edi, int64_t step) +static real flood_energy(t_edpar* edi, int64_t step) { /* compute flooding energy Vfl Vfl = Efl * exp( - \frac {kT} {2Efl alpha^2} * sum_i { \lambda_i c_i^2 } ) @@ -778,7 +769,8 @@ static real flood_energy(t_edpar *edi, int64_t step) { for (i = 0; i < edi->flood.vecs.neig; i++) { - edi->flood.vecs.refproj[i] = edi->flood.initialReferenceProjection[i] + step * edi->flood.referenceProjectionSlope[i]; + edi->flood.vecs.refproj[i] = edi->flood.initialReferenceProjection[i] + + step * edi->flood.referenceProjectionSlope[i]; } } @@ -787,17 +779,21 @@ static real flood_energy(t_edpar *edi, int64_t step) for (i = 0; i < edi->flood.vecs.neig; i++) { /* stpsz stores the reciprocal eigenvalue 1/sigma_i */ - sum += edi->flood.vecs.stpsz[i]*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i])*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i]); + sum += edi->flood.vecs.stpsz[i] * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]) + * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]); } /* Compute the Gauss function*/ if (edi->flood.bHarmonic) { - Vfl = -0.5*edi->flood.Efl*sum; /* minus sign because Efl is negative, if restrain is on. */ + Vfl = -0.5 * edi->flood.Efl * sum; /* minus sign because Efl is negative, if restrain is on. */ } else { - Vfl = edi->flood.Efl != 0 ? edi->flood.Efl*std::exp(-edi->flood.kT/2/edi->flood.Efl/edi->flood.alpha2*sum) : 0; + Vfl = edi->flood.Efl != 0 + ? edi->flood.Efl + * std::exp(-edi->flood.kT / 2 / edi->flood.Efl / edi->flood.alpha2 * sum) + : 0; } return Vfl; @@ -805,7 +801,7 @@ static real flood_energy(t_edpar *edi, int64_t step) /* From the position and from Vfl compute forces in subspace -> store in edi->vec.flood.fproj */ -static void flood_forces(t_edpar *edi) +static void flood_forces(t_edpar* edi) { /* compute the forces in the subspace of the flooding eigenvectors * by the formula F_i= V_{fl}(c) * ( \frac {kT} {E_{fl}} \lambda_i c_i */ @@ -818,7 +814,8 @@ static void flood_forces(t_edpar *edi) { for (i = 0; i < edi->flood.vecs.neig; i++) { - edi->flood.vecs.fproj[i] = edi->flood.Efl* edi->flood.vecs.stpsz[i]*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i]); + edi->flood.vecs.fproj[i] = edi->flood.Efl * edi->flood.vecs.stpsz[i] + * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]); } } else @@ -826,7 +823,12 @@ static void flood_forces(t_edpar *edi) for (i = 0; i < edi->flood.vecs.neig; i++) { /* if Efl is zero the forces are zero if not use the formula */ - edi->flood.vecs.fproj[i] = edi->flood.Efl != 0 ? edi->flood.kT/edi->flood.Efl/edi->flood.alpha2*energy*edi->flood.vecs.stpsz[i]*(edi->flood.vecs.xproj[i]-edi->flood.vecs.refproj[i]) : 0; + edi->flood.vecs.fproj[i] = + edi->flood.Efl != 0 + ? edi->flood.kT / edi->flood.Efl / edi->flood.alpha2 * energy + * edi->flood.vecs.stpsz[i] + * (edi->flood.vecs.xproj[i] - edi->flood.vecs.refproj[i]) + : 0; } } } @@ -848,9 +850,9 @@ namespace * \param[out] forces_cart The cartesian forces */ -void flood_blowup(const t_edpar &edi, rvec *forces_cart) +void flood_blowup(const t_edpar& edi, rvec* forces_cart) { - const real * forces_sub = edi.flood.vecs.fproj; + const real* forces_sub = edi.flood.vecs.fproj; /* Calculate the cartesian forces for the local atoms */ /* Clear forces first */ @@ -878,42 +880,43 @@ void flood_blowup(const t_edpar &edi, rvec *forces_cart) /* Update the values of Efl, deltaF depending on tau and Vfl */ -static void update_adaption(t_edpar *edi) +static void update_adaption(t_edpar* edi) { /* this function updates the parameter Efl and deltaF according to the rules given in * 'predicting unimolecular chemical reactions: chemical flooding' M Mueller et al, * J. chem Phys. */ - if ((edi->flood.tau < 0 ? -edi->flood.tau : edi->flood.tau ) > 0.00000001) + if ((edi->flood.tau < 0 ? -edi->flood.tau : edi->flood.tau) > 0.00000001) { - edi->flood.Efl = edi->flood.Efl+edi->flood.dt/edi->flood.tau*(edi->flood.deltaF0-edi->flood.deltaF); + edi->flood.Efl = edi->flood.Efl + + edi->flood.dt / edi->flood.tau * (edi->flood.deltaF0 - edi->flood.deltaF); /* check if restrain (inverted flooding) -> don't let EFL become positive */ if (edi->flood.alpha2 < 0 && edi->flood.Efl > -0.00000001) { edi->flood.Efl = 0; } - edi->flood.deltaF = (1-edi->flood.dt/edi->flood.tau)*edi->flood.deltaF+edi->flood.dt/edi->flood.tau*edi->flood.Vfl; + edi->flood.deltaF = (1 - edi->flood.dt / edi->flood.tau) * edi->flood.deltaF + + edi->flood.dt / edi->flood.tau * edi->flood.Vfl; } } -static void do_single_flood( - FILE *edo, - const rvec x[], - rvec force[], - t_edpar *edi, - int64_t step, - const matrix box, - const t_commrec *cr, - gmx_bool bNS) /* Are we in a neighbor searching step? */ +static void do_single_flood(FILE* edo, + const rvec x[], + rvec force[], + t_edpar* edi, + int64_t step, + const matrix box, + const t_commrec* cr, + gmx_bool bNS) /* Are we in a neighbor searching step? */ { int i; matrix rotmat; /* rotation matrix */ matrix tmat; /* inverse rotation */ rvec transvec; /* translation vector */ real rmsdev; - struct t_do_edsam *buf; + struct t_do_edsam* buf; buf = edi->buf->do_edsam; @@ -923,13 +926,15 @@ static void do_single_flood( * every processor. Each node contributes its local positions x and stores them in * the collective ED array buf->xcoll */ communicate_group_positions(cr, buf->xcoll, buf->shifts_xcoll, buf->extra_shifts_xcoll, bNS, x, - edi->sav.nr, edi->sav.nr_loc, edi->sav.anrs_loc, edi->sav.c_ind, edi->sav.x_old, box); + edi->sav.nr, edi->sav.nr_loc, edi->sav.anrs_loc, edi->sav.c_ind, + edi->sav.x_old, box); /* Only assembly REFERENCE positions if their indices differ from the average ones */ if (!edi->bRefEqAv) { - communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, bNS, x, - edi->sref.nr, edi->sref.nr_loc, edi->sref.anrs_loc, edi->sref.c_ind, edi->sref.x_old, box); + communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, + bNS, x, edi->sref.nr, edi->sref.nr_loc, edi->sref.anrs_loc, + edi->sref.c_ind, edi->sref.x_old, box); } /* If bUpdateShifts was TRUE, the shifts have just been updated in get_positions. @@ -1003,11 +1008,11 @@ static void do_single_flood( /* Main flooding routine, called from do_force */ -extern void do_flood(const t_commrec *cr, - const t_inputrec *ir, +extern void do_flood(const t_commrec* cr, + const t_inputrec* ir, const rvec x[], rvec force[], - gmx_edsam *ed, + gmx_edsam* ed, const matrix box, int64_t step, gmx_bool bNS) @@ -1016,7 +1021,7 @@ extern void do_flood(const t_commrec *cr, * it in the output file for ED constraints. */ if (MASTER(cr) && do_per_step(step, ed->edpar.begin()->outfrq)) { - fprintf(ed->edo, "\n%12f", ir->init_t + step*ir->delta_t); + fprintf(ed->edo, "\n%12f", ir->init_t + step * ir->delta_t); } if (ed->eEDtype != EssentialDynamicsType::Flooding) @@ -1024,7 +1029,7 @@ extern void do_flood(const t_commrec *cr, return; } - for (auto &edi : ed->edpar) + for (auto& edi : ed->edpar) { /* Call flooding for one matrix */ if (edi.flood.vecs.neig) @@ -1037,7 +1042,7 @@ extern void do_flood(const t_commrec *cr, /* Called by init_edi, configure some flooding related variables and structures, * print headers to output files */ -static void init_flood(t_edpar *edi, gmx_edsam * ed, real dt) +static void init_flood(t_edpar* edi, gmx_edsam* ed, real dt) { int i; @@ -1051,7 +1056,8 @@ static void init_flood(t_edpar *edi, gmx_edsam * ed, real dt) /* If in any of the ED groups we find a flooding vector, flooding is turned on */ ed->eEDtype = EssentialDynamicsType::Flooding; - fprintf(stderr, "ED: Flooding %d eigenvector%s.\n", edi->flood.vecs.neig, edi->flood.vecs.neig > 1 ? "s" : ""); + fprintf(stderr, "ED: Flooding %d eigenvector%s.\n", edi->flood.vecs.neig, + edi->flood.vecs.neig > 1 ? "s" : ""); if (edi->flood.bConstForce) { @@ -1072,9 +1078,9 @@ static void init_flood(t_edpar *edi, gmx_edsam * ed, real dt) #ifdef DEBUGHELPERS /*********** Energy book keeping ******/ -static void get_flood_enx_names(t_edpar *edi, char** names, int *nnames) /* get header of energies */ +static void get_flood_enx_names(t_edpar* edi, char** names, int* nnames) /* get header of energies */ { - t_edpar *actual; + t_edpar* actual; int count; char buf[STRLEN]; actual = edi; @@ -1083,18 +1089,18 @@ static void get_flood_enx_names(t_edpar *edi, char** names, int *nnames) /* get { srenew(names, count); sprintf(buf, "Vfl_%d", count); - names[count-1] = gmx_strdup(buf); - actual = actual->next_edi; + names[count - 1] = gmx_strdup(buf); + actual = actual->next_edi; count++; } - *nnames = count-1; + *nnames = count - 1; } -static void get_flood_energies(t_edpar *edi, real Vfl[], int nnames) +static void get_flood_energies(t_edpar* edi, real Vfl[], int nnames) { /*fl has to be big enough to capture nnames-many entries*/ - t_edpar *actual; + t_edpar* actual; int count; @@ -1102,11 +1108,11 @@ static void get_flood_energies(t_edpar *edi, real Vfl[], int nnames) count = 1; while (actual) { - Vfl[count-1] = actual->flood.Vfl; - actual = actual->next_edi; + Vfl[count - 1] = actual->flood.Vfl; + actual = actual->next_edi; count++; } - if (nnames != count-1) + if (nnames != count - 1) { gmx_fatal(FARGS, "Number of energies is not consistent with t_edi structure"); } @@ -1120,17 +1126,16 @@ static void get_flood_energies(t_edpar *edi, real Vfl[], int nnames) * with the essential dynamics data found in the checkpoint file (if present). * gmx make_edi can be used to create an .edi input file. */ -static std::unique_ptr ed_open( - int natoms, - ObservablesHistory *oh, - const char *ediFileName, - const char *edoFileName, - const gmx::StartingBehavior startingBehavior, - const gmx_output_env_t *oenv, - const t_commrec *cr) -{ - auto edHandle = std::make_unique(); - auto ed = edHandle->getLegacyED(); +static std::unique_ptr ed_open(int natoms, + ObservablesHistory* oh, + const char* ediFileName, + const char* edoFileName, + const gmx::StartingBehavior startingBehavior, + const gmx_output_env_t* oenv, + const t_commrec* cr) +{ + auto edHandle = std::make_unique(); + auto ed = edHandle->getLegacyED(); /* We want to perform ED (this switch might later be upgraded to EssentialDynamicsType::Flooding) */ ed->eEDtype = EssentialDynamicsType::EDSampling; @@ -1139,9 +1144,9 @@ static std::unique_ptr ed_open( // If we start from a checkpoint file, we already have an edsamHistory struct if (oh->edsamHistory == nullptr) { - oh->edsamHistory = std::make_unique(edsamhistory_t {}); + oh->edsamHistory = std::make_unique(edsamhistory_t{}); } - edsamhistory_t *EDstate = oh->edsamHistory.get(); + edsamhistory_t* EDstate = oh->edsamHistory.get(); /* Read the edi input file: */ ed->edpar = read_edi_file(ediFileName, natoms); @@ -1164,9 +1169,7 @@ static std::unique_ptr ed_open( } else { - ed->edo = xvgropen(edoFileName, - "Essential dynamics / flooding output", - "Time (ps)", + ed->edo = xvgropen(edoFileName, "Essential dynamics / flooding output", "Time (ps)", "RMSDs (nm), projections on EVs (nm), ...", oenv); /* Make a descriptive legend */ @@ -1178,23 +1181,23 @@ static std::unique_ptr ed_open( /* Broadcasts the structure data */ -static void bc_ed_positions(const t_commrec *cr, struct gmx_edx *s, EssentialDynamicsStructure stype) +static void bc_ed_positions(const t_commrec* cr, struct gmx_edx* s, EssentialDynamicsStructure stype) { - snew_bc(cr, s->anrs, s->nr ); /* Index numbers */ - snew_bc(cr, s->x, s->nr ); /* Positions */ - nblock_bc(cr, s->nr, s->anrs ); - nblock_bc(cr, s->nr, s->x ); + snew_bc(cr, s->anrs, s->nr); /* Index numbers */ + snew_bc(cr, s->x, s->nr); /* Positions */ + nblock_bc(cr, s->nr, s->anrs); + nblock_bc(cr, s->nr, s->x); /* For the average & reference structures we need an array for the collective indices, * and we need to broadcast the masses as well */ if (stype == EssentialDynamicsStructure::Average || stype == EssentialDynamicsStructure::Reference) { /* We need these additional variables in the parallel case: */ - snew(s->c_ind, s->nr ); /* Collective indices */ + snew(s->c_ind, s->nr); /* Collective indices */ /* Local atom indices get assigned in dd_make_local_group_indices. * There, also memory is allocated */ - s->nalloc_loc = 0; /* allocation size of s->anrs_loc */ - snew_bc(cr, s->x_old, s->nr); /* To be able to always make the ED molecule whole, ... */ + s->nalloc_loc = 0; /* allocation size of s->anrs_loc */ + snew_bc(cr, s->x_old, s->nr); /* To be able to always make the ED molecule whole, ... */ nblock_bc(cr, s->nr, s->x_old); /* ... keep track of shift changes with the help of old coords */ } @@ -1217,35 +1220,34 @@ static void bc_ed_positions(const t_commrec *cr, struct gmx_edx *s, EssentialDyn /* Broadcasts the eigenvector data */ -static void bc_ed_vecs(const t_commrec *cr, t_eigvec *ev, int length) +static void bc_ed_vecs(const t_commrec* cr, t_eigvec* ev, int length) { int i; - snew_bc(cr, ev->ieig, ev->neig); /* index numbers of eigenvector */ - snew_bc(cr, ev->stpsz, ev->neig); /* stepsizes per eigenvector */ - snew_bc(cr, ev->xproj, ev->neig); /* instantaneous x projection */ - snew_bc(cr, ev->fproj, ev->neig); /* instantaneous f projection */ - snew_bc(cr, ev->refproj, ev->neig); /* starting or target projection */ + snew_bc(cr, ev->ieig, ev->neig); /* index numbers of eigenvector */ + snew_bc(cr, ev->stpsz, ev->neig); /* stepsizes per eigenvector */ + snew_bc(cr, ev->xproj, ev->neig); /* instantaneous x projection */ + snew_bc(cr, ev->fproj, ev->neig); /* instantaneous f projection */ + snew_bc(cr, ev->refproj, ev->neig); /* starting or target projection */ - nblock_bc(cr, ev->neig, ev->ieig ); - nblock_bc(cr, ev->neig, ev->stpsz ); - nblock_bc(cr, ev->neig, ev->xproj ); - nblock_bc(cr, ev->neig, ev->fproj ); + nblock_bc(cr, ev->neig, ev->ieig); + nblock_bc(cr, ev->neig, ev->stpsz); + nblock_bc(cr, ev->neig, ev->xproj); + nblock_bc(cr, ev->neig, ev->fproj); nblock_bc(cr, ev->neig, ev->refproj); - snew_bc(cr, ev->vec, ev->neig); /* Eigenvector components */ + snew_bc(cr, ev->vec, ev->neig); /* Eigenvector components */ for (i = 0; i < ev->neig; i++) { snew_bc(cr, ev->vec[i], length); nblock_bc(cr, length, ev->vec[i]); } - } /* Broadcasts the ED / flooding data to other nodes * and allocates memory where needed */ -static void broadcast_ed_data(const t_commrec *cr, gmx_edsam * ed) +static void broadcast_ed_data(const t_commrec* cr, gmx_edsam* ed) { /* Master lets the other nodes know if its ED only or also flooding */ gmx_bcast(sizeof(ed->eEDtype), &(ed->eEDtype), cr); @@ -1255,16 +1257,18 @@ static void broadcast_ed_data(const t_commrec *cr, gmx_edsam * ed) gmx_bcast(sizeof(numedis), &numedis, cr); nblock_abc(cr, numedis, &(ed->edpar)); /* Now transfer the ED data set(s) */ - for (auto &edi : ed->edpar) + for (auto& edi : ed->edpar) { /* Broadcast a single ED data set */ block_bc(cr, edi); /* Broadcast positions */ - bc_ed_positions(cr, &(edi.sref), EssentialDynamicsStructure::Reference); /* reference positions (don't broadcast masses) */ - bc_ed_positions(cr, &(edi.sav ), EssentialDynamicsStructure::Average ); /* average positions (do broadcast masses as well) */ - bc_ed_positions(cr, &(edi.star), EssentialDynamicsStructure::Target); /* target positions */ - bc_ed_positions(cr, &(edi.sori), EssentialDynamicsStructure::Origin); /* origin positions */ + bc_ed_positions(cr, &(edi.sref), + EssentialDynamicsStructure::Reference); /* reference positions (don't broadcast masses) */ + bc_ed_positions(cr, &(edi.sav), + EssentialDynamicsStructure::Average); /* average positions (do broadcast masses as well) */ + bc_ed_positions(cr, &(edi.star), EssentialDynamicsStructure::Target); /* target positions */ + bc_ed_positions(cr, &(edi.sori), EssentialDynamicsStructure::Origin); /* origin positions */ /* Broadcast eigenvectors */ bc_ed_vecs(cr, &edi.vecs.mon, edi.sav.nr); @@ -1274,7 +1278,7 @@ static void broadcast_ed_data(const t_commrec *cr, gmx_edsam * ed) bc_ed_vecs(cr, &edi.vecs.radacc, edi.sav.nr); bc_ed_vecs(cr, &edi.vecs.radcon, edi.sav.nr); /* Broadcast flooding eigenvectors and, if needed, values for the moving reference */ - bc_ed_vecs(cr, &edi.flood.vecs, edi.sav.nr); + bc_ed_vecs(cr, &edi.flood.vecs, edi.sav.nr); /* For harmonic restraints the reference projections can change with time */ if (edi.flood.bHarmonic) @@ -1289,11 +1293,11 @@ static void broadcast_ed_data(const t_commrec *cr, gmx_edsam * ed) /* init-routine called for every *.edi-cycle, initialises t_edpar structure */ -static void init_edi(const gmx_mtop_t *mtop, t_edpar *edi) +static void init_edi(const gmx_mtop_t* mtop, t_edpar* edi) { - int i; - real totalmass = 0.0; - rvec com; + int i; + real totalmass = 0.0; + rvec com; /* NOTE Init_edi is executed on the master process only * The initialized data sets are then transmitted to the @@ -1316,11 +1320,13 @@ static void init_edi(const gmx_mtop_t *mtop, t_edpar *edi) /* Check that every m > 0. Bad things will happen otherwise. */ if (edi->sref.m[i] <= 0.0) { - gmx_fatal(FARGS, "Reference structure atom %d (sam.edi index %d) has a mass of %g.\n" - "For a mass-weighted fit, all reference structure atoms need to have a mass >0.\n" + gmx_fatal(FARGS, + "Reference structure atom %d (sam.edi index %d) has a mass of %g.\n" + "For a mass-weighted fit, all reference structure atoms need to have a mass " + ">0.\n" "Either make the covariance analysis non-mass-weighted, or exclude massless\n" "atoms from the reference structure by creating a proper index group.\n", - i, edi->sref.anrs[i]+1, edi->sref.m[i]); + i, edi->sref.anrs[i] + 1, edi->sref.m[i]); } totalmass += edi->sref.m[i]; @@ -1329,8 +1335,8 @@ static void init_edi(const gmx_mtop_t *mtop, t_edpar *edi) /* Masses m and sqrt(m) for the average structure. Note that m * is needed if forces have to be evaluated in do_edsam */ - snew(edi->sav.sqrtm, edi->sav.nr ); - snew(edi->sav.m, edi->sav.nr ); + snew(edi->sav.sqrtm, edi->sav.nr); + snew(edi->sav.m, edi->sav.nr); for (i = 0; i < edi->sav.nr; i++) { edi->sav.m[i] = mtopGetAtomMass(mtop, edi->sav.anrs[i], &molb); @@ -1346,8 +1352,10 @@ static void init_edi(const gmx_mtop_t *mtop, t_edpar *edi) /* Check that every m > 0. Bad things will happen otherwise. */ if (edi->sav.sqrtm[i] <= 0.0) { - gmx_fatal(FARGS, "Average structure atom %d (sam.edi index %d) has a mass of %g.\n" - "For ED with mass-weighting, all average structure atoms need to have a mass >0.\n" + gmx_fatal(FARGS, + "Average structure atom %d (sam.edi index %d) has a mass of %g.\n" + "For ED with mass-weighting, all average structure atoms need to have a mass " + ">0.\n" "Either make the covariance analysis non-mass-weighted, or exclude massless\n" "atoms from the average structure by creating a proper index group.\n", i, edi->sav.anrs[i] + 1, edi->sav.m[i]); @@ -1366,82 +1374,85 @@ static void init_edi(const gmx_mtop_t *mtop, t_edpar *edi) } -static void check(const char *line, const char *label) +static void check(const char* line, const char* label) { if (!strstr(line, label)) { - gmx_fatal(FARGS, "Could not find input parameter %s at expected position in edsam input-file (.edi)\nline read instead is %s", label, line); + gmx_fatal(FARGS, + "Could not find input parameter %s at expected position in edsam input-file " + "(.edi)\nline read instead is %s", + label, line); } } -static int read_checked_edint(FILE *file, const char *label) +static int read_checked_edint(FILE* file, const char* label) { - char line[STRLEN+1]; + char line[STRLEN + 1]; int idum; - fgets2 (line, STRLEN, file); + fgets2(line, STRLEN, file); check(line, label); - fgets2 (line, STRLEN, file); - sscanf (line, max_ev_fmt_d, &idum); + fgets2(line, STRLEN, file); + sscanf(line, max_ev_fmt_d, &idum); return idum; } -static bool read_checked_edbool(FILE *file, const char *label) +static bool read_checked_edbool(FILE* file, const char* label) { return read_checked_edint(file, label) != 0; } -static int read_edint(FILE *file, bool *bEOF) +static int read_edint(FILE* file, bool* bEOF) { - char line[STRLEN+1]; + char line[STRLEN + 1]; int idum; - char *eof; + char* eof; - eof = fgets2 (line, STRLEN, file); + eof = fgets2(line, STRLEN, file); if (eof == nullptr) { *bEOF = TRUE; return -1; } - eof = fgets2 (line, STRLEN, file); + eof = fgets2(line, STRLEN, file); if (eof == nullptr) { *bEOF = TRUE; return -1; } - sscanf (line, max_ev_fmt_d, &idum); + sscanf(line, max_ev_fmt_d, &idum); *bEOF = FALSE; return idum; } -static real read_checked_edreal(FILE *file, const char *label) +static real read_checked_edreal(FILE* file, const char* label) { - char line[STRLEN+1]; + char line[STRLEN + 1]; double rdum; - fgets2 (line, STRLEN, file); + fgets2(line, STRLEN, file); check(line, label); - fgets2 (line, STRLEN, file); - sscanf (line, max_ev_fmt_lf, &rdum); + fgets2(line, STRLEN, file); + sscanf(line, max_ev_fmt_lf, &rdum); return static_cast(rdum); /* always read as double and convert to single */ } -static void read_edx(FILE *file, int number, int *anrs, rvec *x) +static void read_edx(FILE* file, int number, int* anrs, rvec* x) { int i, j; - char line[STRLEN+1]; + char line[STRLEN + 1]; double d[3]; for (i = 0; i < number; i++) { - fgets2 (line, STRLEN, file); - sscanf (line, max_ev_fmt_dlflflf, &anrs[i], &d[0], &d[1], &d[2]); + fgets2(line, STRLEN, file); + sscanf(line, max_ev_fmt_dlflflf, &anrs[i], &d[0], &d[1], &d[2]); anrs[i]--; /* we are reading FORTRAN indices */ for (j = 0; j < 3; j++) { @@ -1458,7 +1469,7 @@ namespace * \param[out] vec the eigen-vectors * \param[in] nEig the number of eigenvectors */ -void scan_edvec(FILE *in, int numAtoms, rvec ***vec, int nEig) +void scan_edvec(FILE* in, int numAtoms, rvec*** vec, int nEig) { snew(*vec, nEig); for (int iEigenvector = 0; iEigenvector < nEig; iEigenvector++) @@ -1466,7 +1477,7 @@ void scan_edvec(FILE *in, int numAtoms, rvec ***vec, int nEig) snew((*vec)[iEigenvector], numAtoms); for (int iAtom = 0; iAtom < numAtoms; iAtom++) { - char line[STRLEN+1]; + char line[STRLEN + 1]; double x, y, z; fgets2(line, STRLEN, in); sscanf(line, max_ev_fmt_lelele, &x, &y, &z); @@ -1475,14 +1486,13 @@ void scan_edvec(FILE *in, int numAtoms, rvec ***vec, int nEig) (*vec)[iEigenvector][iAtom][ZZ] = z; } } - } /*!\brief Read an essential dynamics eigenvector and corresponding step size. * \param[in] in input file * \param[in] nrAtoms number of atoms/coordinates * \param[out] tvec the eigenvector */ -void read_edvec(FILE *in, int nrAtoms, t_eigvec *tvec) +void read_edvec(FILE* in, int nrAtoms, t_eigvec* tvec) { tvec->neig = read_checked_edint(in, "NUMBER OF EIGENVECTORS"); if (tvec->neig <= 0) @@ -1494,7 +1504,7 @@ void read_edvec(FILE *in, int nrAtoms, t_eigvec *tvec) snew(tvec->stpsz, tvec->neig); for (int i = 0; i < tvec->neig; i++) { - char line[STRLEN+1]; + char line[STRLEN + 1]; fgets2(line, STRLEN, in); int numEigenVectors; double stepSize; @@ -1505,7 +1515,7 @@ void read_edvec(FILE *in, int nrAtoms, t_eigvec *tvec) } tvec->ieig[i] = numEigenVectors; tvec->stpsz[i] = stepSize; - } /* end of loop over eigenvectors */ + } /* end of loop over eigenvectors */ scan_edvec(in, nrAtoms, &tvec->vec, tvec->neig); } @@ -1521,10 +1531,14 @@ void read_edvec(FILE *in, int nrAtoms, t_eigvec *tvec) * \param[out] initialReferenceProjection The projection onto eigenvectors as read from file. * \param[out] referenceProjectionSlope The slope of the reference projections. */ -bool readEdVecWithReferenceProjection(FILE *in, int nrAtoms, t_eigvec *tvec, real ** initialReferenceProjection, real ** referenceProjectionSlope) +bool readEdVecWithReferenceProjection(FILE* in, + int nrAtoms, + t_eigvec* tvec, + real** initialReferenceProjection, + real** referenceProjectionSlope) { bool providesReference = false; - tvec->neig = read_checked_edint(in, "NUMBER OF EIGENVECTORS"); + tvec->neig = read_checked_edint(in, "NUMBER OF EIGENVECTORS"); if (tvec->neig <= 0) { return false; @@ -1536,13 +1550,14 @@ bool readEdVecWithReferenceProjection(FILE *in, int nrAtoms, t_eigvec *tvec, rea snew(*referenceProjectionSlope, tvec->neig); for (int i = 0; i < tvec->neig; i++) { - char line[STRLEN+1]; - fgets2 (line, STRLEN, in); + char line[STRLEN + 1]; + fgets2(line, STRLEN, in); int numEigenVectors; double stepSize = 0.; double referenceProjection = 0.; double referenceSlope = 0.; - const int nscan = sscanf(line, max_ev_fmt_dlflflf, &numEigenVectors, &stepSize, &referenceProjection, &referenceSlope); + const int nscan = sscanf(line, max_ev_fmt_dlflflf, &numEigenVectors, &stepSize, + &referenceProjection, &referenceSlope); /* Zero out values which were not scanned */ switch (nscan) { @@ -1562,14 +1577,17 @@ bool readEdVecWithReferenceProjection(FILE *in, int nrAtoms, t_eigvec *tvec, rea referenceSlope = 0.0; break; default: - gmx_fatal(FARGS, "Expected 2 - 4 (not %d) values for flooding vec: \n", nscan); + gmx_fatal(FARGS, + "Expected 2 - 4 (not %d) values for flooding vec: " + " \n", + nscan); } - (*initialReferenceProjection)[i] = referenceProjection; - (*referenceProjectionSlope)[i] = referenceSlope; + (*initialReferenceProjection)[i] = referenceProjection; + (*referenceProjectionSlope)[i] = referenceSlope; tvec->ieig[i] = numEigenVectors; tvec->stpsz[i] = stepSize; - } /* end of loop over eigenvectors */ + } /* end of loop over eigenvectors */ scan_edvec(in, nrAtoms, &tvec->vec, tvec->neig); return providesReference; @@ -1578,13 +1596,13 @@ bool readEdVecWithReferenceProjection(FILE *in, int nrAtoms, t_eigvec *tvec, rea /*!\brief Allocate working memory for the eigenvectors. * \param[in,out] tvec eigenvector for which memory will be allocated */ -void setup_edvec(t_eigvec *tvec) +void setup_edvec(t_eigvec* tvec) { snew(tvec->xproj, tvec->neig); snew(tvec->fproj, tvec->neig); snew(tvec->refproj, tvec->neig); } -} // namespace +} // namespace /* Check if the same atom indices are used for reference and average positions */ @@ -1609,7 +1627,8 @@ static gmx_bool check_if_same(struct gmx_edx sref, struct gmx_edx sav) return FALSE; } } - fprintf(stderr, "ED: Note: Reference and average structure are composed of the same atom indices.\n"); + fprintf(stderr, + "ED: Note: Reference and average structure are composed of the same atom indices.\n"); return TRUE; } @@ -1620,25 +1639,25 @@ namespace //! Oldest (lowest) magic number indicating unsupported essential dynamics input constexpr int c_oldestUnsupportedMagicNumber = 666; //! Oldest (lowest) magic number indicating supported essential dynamics input -constexpr int c_oldestSupportedMagicNumber = 669; +constexpr int c_oldestSupportedMagicNumber = 669; //! Latest (highest) magic number indicating supported essential dynamics input -constexpr int c_latestSupportedMagicNumber = 670; +constexpr int c_latestSupportedMagicNumber = 670; /*!\brief Set up essential dynamics work parameters. * \param[in] edi Essential dynamics working structure. */ -void setup_edi(t_edpar *edi) +void setup_edi(t_edpar* edi) { snew(edi->sref.x_old, edi->sref.nr); - edi->sref.sqrtm = nullptr; + edi->sref.sqrtm = nullptr; snew(edi->sav.x_old, edi->sav.nr); if (edi->star.nr > 0) { - edi->star.sqrtm = nullptr; + edi->star.sqrtm = nullptr; } if (edi->sori.nr > 0) { - edi->sori.sqrtm = nullptr; + edi->sori.sqrtm = nullptr; } setup_edvec(&edi->vecs.linacc); setup_edvec(&edi->vecs.mon); @@ -1664,7 +1683,7 @@ bool ediFileHasConstForceFlooding(int magicNumber) * \param[out] magicNumber determines the edi file version * \returns true if setting file version from input file was successful. */ -bool ediFileHasValidDataSet(FILE *in, int * magicNumber) +bool ediFileHasValidDataSet(FILE* in, int* magicNumber) { /* the edi file is not free format, so expect problems if the input is corrupt. */ bool reachedEndOfFile = true; @@ -1678,14 +1697,15 @@ bool ediFileHasValidDataSet(FILE *in, int * magicNumber) * \param[in] magicNumber A magic number read from the edi file * \param[in] fn name of input file for error reporting */ -void exitWhenMagicNumberIsInvalid(int magicNumber, const char * fn) +void exitWhenMagicNumberIsInvalid(int magicNumber, const char* fn) { if (magicNumber < c_oldestSupportedMagicNumber || magicNumber > c_latestSupportedMagicNumber) { if (magicNumber >= c_oldestUnsupportedMagicNumber && magicNumber < c_oldestSupportedMagicNumber) { - gmx_fatal(FARGS, "Wrong magic number: Use newest version of make_edi to produce edi file"); + gmx_fatal(FARGS, + "Wrong magic number: Use newest version of make_edi to produce edi file"); } else { @@ -1702,7 +1722,7 @@ void exitWhenMagicNumberIsInvalid(int magicNumber, const char * fn) * \param[in] fn the file name of the input file for error reporting * \returns edi essential dynamics parameters */ -t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const char *fn) +t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const char* fn) { t_edpar edi; bool bEOF; @@ -1710,15 +1730,16 @@ t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const cha edi.nini = read_edint(in, &bEOF); if (edi.nini != nr_mdatoms) { - gmx_fatal(FARGS, "Nr of atoms in %s (%d) does not match nr of md atoms (%d)", fn, edi.nini, nr_mdatoms); + gmx_fatal(FARGS, "Nr of atoms in %s (%d) does not match nr of md atoms (%d)", fn, edi.nini, + nr_mdatoms); } /* Done checking. For the rest we blindly trust the input */ - edi.fitmas = read_checked_edbool(in, "FITMAS"); - edi.pcamas = read_checked_edbool(in, "ANALYSIS_MAS"); - edi.outfrq = read_checked_edint(in, "OUTFRQ"); - edi.maxedsteps = read_checked_edint(in, "MAXLEN"); - edi.slope = read_checked_edreal(in, "SLOPECRIT"); + edi.fitmas = read_checked_edbool(in, "FITMAS"); + edi.pcamas = read_checked_edbool(in, "ANALYSIS_MAS"); + edi.outfrq = read_checked_edint(in, "OUTFRQ"); + edi.maxedsteps = read_checked_edint(in, "MAXLEN"); + edi.slope = read_checked_edreal(in, "SLOPECRIT"); edi.presteps = read_checked_edint(in, "PRESTEPS"); edi.flood.deltaF0 = read_checked_edreal(in, "DELTA_F0"); @@ -1736,7 +1757,7 @@ t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const cha { edi.flood.bConstForce = FALSE; } - edi.sref.nr = read_checked_edint(in, "NREF"); + edi.sref.nr = read_checked_edint(in, "NREF"); /* allocate space for reference positions and read them */ snew(edi.sref.anrs, edi.sref.nr); @@ -1762,10 +1783,12 @@ t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const cha read_edvec(in, edi.sav.nr, &edi.vecs.radcon); /* Was a specific reference point for the flooding/umbrella potential provided in the edi file? */ - bool bHaveReference = false; + bool bHaveReference = false; if (edi.flood.bHarmonic) { - bHaveReference = readEdVecWithReferenceProjection(in, edi.sav.nr, &edi.flood.vecs, &edi.flood.initialReferenceProjection, &edi.flood.referenceProjectionSlope); + bHaveReference = readEdVecWithReferenceProjection(in, edi.sav.nr, &edi.flood.vecs, + &edi.flood.initialReferenceProjection, + &edi.flood.referenceProjectionSlope); } else { @@ -1789,8 +1812,11 @@ t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const cha { /* Both an -ori structure and a at least one manual reference point have been * specified. That's ambiguous and probably not intentional. */ - gmx_fatal(FARGS, "ED: An origin structure has been provided and a at least one (moving) reference\n" - " point was manually specified in the edi file. That is ambiguous. Aborting.\n"); + gmx_fatal(FARGS, + "ED: An origin structure has been provided and a at least one (moving) " + "reference\n" + " point was manually specified in the edi file. That is ambiguous. " + "Aborting.\n"); } snew(edi.sori.anrs, edi.sori.nr); snew(edi.sori.x, edi.sori.nr); @@ -1799,10 +1825,10 @@ t_edpar read_edi(FILE* in, int nr_mdatoms, bool hasConstForceFlooding, const cha return edi; } -std::vector read_edi_file(const char *fn, int nr_mdatoms) +std::vector read_edi_file(const char* fn, int nr_mdatoms) { std::vector essentialDynamicsParameters; - FILE *in; + FILE* in; /* This routine is executed on the master only */ /* Open the .edi parameter input file */ @@ -1827,7 +1853,8 @@ std::vector read_edi_file(const char *fn, int nr_mdatoms) gmx_fatal(FARGS, "No complete ED data set found in edi file %s.", fn); } - fprintf(stderr, "ED: Found %zu ED group%s.\n", essentialDynamicsParameters.size(), essentialDynamicsParameters.size() > 1 ? "s" : ""); + fprintf(stderr, "ED: Found %zu ED group%s.\n", essentialDynamicsParameters.size(), + essentialDynamicsParameters.size() > 1 ? "s" : ""); /* Close the .edi file again */ gmx_fio_fclose(in); @@ -1837,22 +1864,23 @@ std::vector read_edi_file(const char *fn, int nr_mdatoms) } // anonymous namespace -struct t_fit_to_ref { - rvec *xcopy; /* Working copy of the positions in fit_to_reference */ +struct t_fit_to_ref +{ + rvec* xcopy; /* Working copy of the positions in fit_to_reference */ }; /* Fit the current positions to the reference positions * Do not actually do the fit, just return rotation and translation. * Note that the COM of the reference structure was already put into * the origin by init_edi. */ -static void fit_to_reference(rvec *xcoll, /* The positions to be fitted */ - rvec transvec, /* The translation vector */ - matrix rotmat, /* The rotation matrix */ - t_edpar *edi) /* Just needed for do_edfit */ +static void fit_to_reference(rvec* xcoll, /* The positions to be fitted */ + rvec transvec, /* The translation vector */ + matrix rotmat, /* The rotation matrix */ + t_edpar* edi) /* Just needed for do_edfit */ { - rvec com; /* center of mass */ + rvec com; /* center of mass */ int i; - struct t_fit_to_ref *loc; + struct t_fit_to_ref* loc; /* Allocate memory the first time this routine is called for each edi group */ @@ -1884,7 +1912,7 @@ static void fit_to_reference(rvec *xcoll, /* The positions to be fitted } -static void translate_and_rotate(rvec *x, /* The positions to be translated and rotated */ +static void translate_and_rotate(rvec* x, /* The positions to be translated and rotated */ int nat, /* How many positions are there? */ rvec transvec, /* The translation vector */ matrix rotmat) /* The rotation matrix */ @@ -1899,11 +1927,11 @@ static void translate_and_rotate(rvec *x, /* The positions to be transla /* Gets the rms deviation of the positions to the structure s */ /* fit_to_structure has to be called before calling this routine! */ -static real rmsd_from_structure(rvec *x, /* The positions under consideration */ - struct gmx_edx *s) /* The structure from which the rmsd shall be computed */ +static real rmsd_from_structure(rvec* x, /* The positions under consideration */ + struct gmx_edx* s) /* The structure from which the rmsd shall be computed */ { - real rmsd = 0.0; - int i; + real rmsd = 0.0; + int i; for (i = 0; i < s->nr; i++) @@ -1912,31 +1940,31 @@ static real rmsd_from_structure(rvec *x, /* The positions under consi } rmsd /= static_cast(s->nr); - rmsd = sqrt(rmsd); + rmsd = sqrt(rmsd); return rmsd; } -void dd_make_local_ed_indices(gmx_domdec_t *dd, struct gmx_edsam *ed) +void dd_make_local_ed_indices(gmx_domdec_t* dd, struct gmx_edsam* ed) { if (ed->eEDtype != EssentialDynamicsType::None) { /* Loop over ED groups */ - for (auto &edi : ed->edpar) + for (auto& edi : ed->edpar) { /* Local atoms of the reference structure (for fitting), need only be assembled * if their indices differ from the average ones */ if (!edi.bRefEqAv) { - dd_make_local_group_indices(dd->ga2la, edi.sref.nr, edi.sref.anrs, - &edi.sref.nr_loc, &edi.sref.anrs_loc, &edi.sref.nalloc_loc, edi.sref.c_ind); + dd_make_local_group_indices(dd->ga2la, edi.sref.nr, edi.sref.anrs, &edi.sref.nr_loc, + &edi.sref.anrs_loc, &edi.sref.nalloc_loc, edi.sref.c_ind); } /* Local atoms of the average structure (on these ED will be performed) */ - dd_make_local_group_indices(dd->ga2la, edi.sav.nr, edi.sav.anrs, - &edi.sav.nr_loc, &edi.sav.anrs_loc, &edi.sav.nalloc_loc, edi.sav.c_ind); + dd_make_local_group_indices(dd->ga2la, edi.sav.nr, edi.sav.anrs, &edi.sav.nr_loc, + &edi.sav.anrs_loc, &edi.sav.nalloc_loc, edi.sav.c_ind); /* Indicate that the ED shift vectors for this structure need to be updated * at the next call to communicate_group_positions, since obviously we are in a NS step */ @@ -1957,15 +1985,15 @@ static inline void ed_unshift_single_coord(const matrix box, const rvec x, const if (TRICLINIC(box)) { - xu[XX] = x[XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX]; - xu[YY] = x[YY]-ty*box[YY][YY]-tz*box[ZZ][YY]; - xu[ZZ] = x[ZZ]-tz*box[ZZ][ZZ]; + xu[XX] = x[XX] - tx * box[XX][XX] - ty * box[YY][XX] - tz * box[ZZ][XX]; + xu[YY] = x[YY] - ty * box[YY][YY] - tz * box[ZZ][YY]; + xu[ZZ] = x[ZZ] - tz * box[ZZ][ZZ]; } else { - xu[XX] = x[XX]-tx*box[XX][XX]; - xu[YY] = x[YY]-ty*box[YY][YY]; - xu[ZZ] = x[ZZ]-tz*box[ZZ][ZZ]; + xu[XX] = x[XX] - tx * box[XX][XX]; + xu[YY] = x[YY] - ty * box[YY][YY]; + xu[ZZ] = x[ZZ] - tz * box[ZZ][ZZ]; } } @@ -1976,7 +2004,7 @@ namespace * \param[in] edi the essential dynamics parameters * \param[in] step the current simulation step */ -void do_linfix(rvec *xcoll, const t_edpar &edi, int64_t step) +void do_linfix(rvec* xcoll, const t_edpar& edi, int64_t step) { /* loop over linfix vectors */ for (int i = 0; i < edi.vecs.linfix.neig; i++) @@ -1985,7 +2013,7 @@ void do_linfix(rvec *xcoll, const t_edpar &edi, int64_t step) real proj = projectx(edi, xcoll, edi.vecs.linfix.vec[i]); /* calculate the correction */ - real preFactor = edi.vecs.linfix.refproj[i] + step*edi.vecs.linfix.stpsz[i] - proj; + real preFactor = edi.vecs.linfix.refproj[i] + step * edi.vecs.linfix.stpsz[i] - proj; /* apply the correction */ preFactor /= edi.sav.sqrtm[i]; @@ -2002,7 +2030,7 @@ void do_linfix(rvec *xcoll, const t_edpar &edi, int64_t step) * \param[in,out] xcoll The collected coordinates. * \param[in] edi the essential dynamics parameters */ -void do_linacc(rvec *xcoll, t_edpar *edi) +void do_linacc(rvec* xcoll, t_edpar* edi) { /* loop over linacc vectors */ for (int i = 0; i < edi->vecs.linacc.neig; i++) @@ -2014,14 +2042,14 @@ void do_linacc(rvec *xcoll, t_edpar *edi) real preFactor = 0.0; if (edi->vecs.linacc.stpsz[i] > 0.0) { - if ((proj-edi->vecs.linacc.refproj[i]) < 0.0) + if ((proj - edi->vecs.linacc.refproj[i]) < 0.0) { preFactor = edi->vecs.linacc.refproj[i] - proj; } } if (edi->vecs.linacc.stpsz[i] < 0.0) { - if ((proj-edi->vecs.linacc.refproj[i]) > 0.0) + if ((proj - edi->vecs.linacc.refproj[i]) > 0.0) { preFactor = edi->vecs.linacc.refproj[i] - proj; } @@ -2043,7 +2071,7 @@ void do_linacc(rvec *xcoll, t_edpar *edi) } // namespace -static void do_radfix(rvec *xcoll, t_edpar *edi) +static void do_radfix(rvec* xcoll, t_edpar* edi) { int i, j; real *proj, rad = 0.0, ratio; @@ -2062,11 +2090,11 @@ static void do_radfix(rvec *xcoll, t_edpar *edi) { /* calculate the projections, radius */ proj[i] = projectx(*edi, xcoll, edi->vecs.radfix.vec[i]); - rad += gmx::square(proj[i] - edi->vecs.radfix.refproj[i]); + rad += gmx::square(proj[i] - edi->vecs.radfix.refproj[i]); } - rad = sqrt(rad); - ratio = (edi->vecs.radfix.stpsz[0]+edi->vecs.radfix.radius)/rad - 1.0; + rad = sqrt(rad); + ratio = (edi->vecs.radfix.stpsz[0] + edi->vecs.radfix.radius) / rad - 1.0; edi->vecs.radfix.radius += edi->vecs.radfix.stpsz[0]; /* loop over radfix vectors */ @@ -2088,7 +2116,7 @@ static void do_radfix(rvec *xcoll, t_edpar *edi) } -static void do_radacc(rvec *xcoll, t_edpar *edi) +static void do_radacc(rvec* xcoll, t_edpar* edi) { int i, j; real *proj, rad = 0.0, ratio = 0.0; @@ -2107,14 +2135,14 @@ static void do_radacc(rvec *xcoll, t_edpar *edi) { /* calculate the projections, radius */ proj[i] = projectx(*edi, xcoll, edi->vecs.radacc.vec[i]); - rad += gmx::square(proj[i] - edi->vecs.radacc.refproj[i]); + rad += gmx::square(proj[i] - edi->vecs.radacc.refproj[i]); } rad = sqrt(rad); /* only correct when radius decreased */ if (rad < edi->vecs.radacc.radius) { - ratio = edi->vecs.radacc.radius/rad - 1.0; + ratio = edi->vecs.radacc.radius / rad - 1.0; } else { @@ -2139,15 +2167,16 @@ static void do_radacc(rvec *xcoll, t_edpar *edi) } -struct t_do_radcon { - real *proj; +struct t_do_radcon +{ + real* proj; }; -static void do_radcon(rvec *xcoll, t_edpar *edi) +static void do_radcon(rvec* xcoll, t_edpar* edi) { int i, j; real rad = 0.0, ratio = 0.0; - struct t_do_radcon *loc; + struct t_do_radcon* loc; gmx_bool bFirst; rvec vec_dum; @@ -2178,13 +2207,13 @@ static void do_radcon(rvec *xcoll, t_edpar *edi) { /* calculate the projections, radius */ loc->proj[i] = projectx(*edi, xcoll, edi->vecs.radcon.vec[i]); - rad += gmx::square(loc->proj[i] - edi->vecs.radcon.refproj[i]); + rad += gmx::square(loc->proj[i] - edi->vecs.radcon.refproj[i]); } rad = sqrt(rad); /* only correct when radius increased */ if (rad > edi->vecs.radcon.radius) { - ratio = edi->vecs.radcon.radius/rad - 1.0; + ratio = edi->vecs.radcon.radius / rad - 1.0; /* loop over radcon vectors */ for (i = 0; i < edi->vecs.radcon.neig; i++) @@ -2200,17 +2229,15 @@ static void do_radcon(rvec *xcoll, t_edpar *edi) rvec_inc(xcoll[j], vec_dum); } } - } else { edi->vecs.radcon.radius = rad; } - } -static void ed_apply_constraints(rvec *xcoll, t_edpar *edi, int64_t step) +static void ed_apply_constraints(rvec* xcoll, t_edpar* edi, int64_t step) { int i; @@ -2250,7 +2277,7 @@ namespace * \param[in] fp The output file * \param[in] rmsd the rmsd to the reference structure */ -void write_edo(const t_edpar &edi, FILE *fp, real rmsd) +void write_edo(const t_edpar& edi, FILE* fp, real rmsd) { /* Output how well we fit to the reference structure */ fprintf(fp, EDcol_ffmt, rmsd); @@ -2301,21 +2328,20 @@ void write_edo(const t_edpar &edi, FILE *fp, real rmsd) /* Returns if any constraints are switched on */ -static bool ed_constraints(EssentialDynamicsType edtype, const t_edpar &edi) +static bool ed_constraints(EssentialDynamicsType edtype, const t_edpar& edi) { if (edtype == EssentialDynamicsType::EDSampling || edtype == EssentialDynamicsType::Flooding) { - return ((edi.vecs.linfix.neig != 0) || (edi.vecs.linacc.neig != 0) || - (edi.vecs.radfix.neig != 0) || (edi.vecs.radacc.neig != 0) || - (edi.vecs.radcon.neig != 0)); + return ((edi.vecs.linfix.neig != 0) || (edi.vecs.linacc.neig != 0) || (edi.vecs.radfix.neig != 0) + || (edi.vecs.radacc.neig != 0) || (edi.vecs.radcon.neig != 0)); } return false; } -/* Copies reference projection 'refproj' to fixed 'initialReferenceProjection' variable for flooding/ - * umbrella sampling simulations. */ -static void copyEvecReference(t_eigvec* floodvecs, real * initialReferenceProjection) +/* Copies reference projection 'refproj' to fixed 'initialReferenceProjection' variable for + * flooding/ umbrella sampling simulations. */ +static void copyEvecReference(t_eigvec* floodvecs, real* initialReferenceProjection) { int i; @@ -2334,11 +2360,12 @@ static void copyEvecReference(t_eigvec* floodvecs, real * initialReferenceProjec /* Call on MASTER only. Check whether the essential dynamics / flooding * groups of the checkpoint file are consistent with the provided .edi file. */ -static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_t *EDstate) +static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam& ed, edsamhistory_t* EDstate) { if (nullptr == EDstate->nref || nullptr == EDstate->nav) { - gmx_fatal(FARGS, "Essential dynamics and flooding can only be switched on (or off) at the\n" + gmx_fatal(FARGS, + "Essential dynamics and flooding can only be switched on (or off) at the\n" "start of a new simulation. If a simulation runs with/without ED constraints,\n" "it must also continue with/without ED constraints when checkpointing.\n" "To switch on (or off) ED constraints, please prepare a new .tpr to start\n" @@ -2350,23 +2377,27 @@ static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_ /* Check number of atoms in the reference and average structures */ if (EDstate->nref[edinum] != ed.edpar[edinum].sref.nr) { - gmx_fatal(FARGS, "The number of reference structure atoms in ED group %c is\n" + gmx_fatal(FARGS, + "The number of reference structure atoms in ED group %c is\n" "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n", - get_EDgroupChar(edinum+1, 0), EDstate->nref[edinum], ed.edpar[edinum].sref.nr); + get_EDgroupChar(edinum + 1, 0), EDstate->nref[edinum], ed.edpar[edinum].sref.nr); } if (EDstate->nav[edinum] != ed.edpar[edinum].sav.nr) { - gmx_fatal(FARGS, "The number of average structure atoms in ED group %c is\n" + gmx_fatal(FARGS, + "The number of average structure atoms in ED group %c is\n" "not the same in .cpt (NREF=%d) and .edi (NREF=%d) files!\n", - get_EDgroupChar(edinum+1, 0), EDstate->nav[edinum], ed.edpar[edinum].sav.nr); + get_EDgroupChar(edinum + 1, 0), EDstate->nav[edinum], ed.edpar[edinum].sav.nr); } } if (gmx::ssize(ed.edpar) != EDstate->nED) { - gmx_fatal(FARGS, "The number of essential dynamics / flooding groups is not consistent.\n" + gmx_fatal(FARGS, + "The number of essential dynamics / flooding groups is not consistent.\n" "There are %d ED groups in the .cpt file, but %zu in the .edi file!\n" - "Are you sure this is the correct .edi file?\n", EDstate->nED, ed.edpar.size()); + "Are you sure this is the correct .edi file?\n", + EDstate->nED, ed.edpar.size()); } } @@ -2378,7 +2409,7 @@ static void crosscheck_edi_file_vs_checkpoint(const gmx_edsam &ed, edsamhistory_ * c) in any case, for subsequent checkpoint writing, we set the pointers in * edsamstate to the x_old arrays, which contain the correct PBC representation of * all ED structures at the last time step. */ -static void init_edsamstate(const gmx_edsam &ed, edsamhistory_t *EDstate) +static void init_edsamstate(const gmx_edsam& ed, edsamhistory_t* EDstate) { snew(EDstate->old_sref_p, EDstate->nED); snew(EDstate->old_sav_p, EDstate->nED); @@ -2393,7 +2424,7 @@ static void init_edsamstate(const gmx_edsam &ed, edsamhistory_t *EDstate) /* Loop over all ED/flooding data sets (usually only one, though) */ for (int nr_edi = 0; nr_edi < EDstate->nED; nr_edi++) { - const auto &edi = ed.edpar[nr_edi]; + const auto& edi = ed.edpar[nr_edi]; /* We always need the last reference and average positions such that * in the next time step we can make the ED group whole again * if the atoms do not have the correct PBC representation */ @@ -2406,24 +2437,24 @@ static void init_edsamstate(const gmx_edsam &ed, edsamhistory_t *EDstate) } for (int i = 0; i < edi.sav.nr; i++) { - copy_rvec(EDstate->old_sav [nr_edi][i], edi.sav.x_old [i]); + copy_rvec(EDstate->old_sav[nr_edi][i], edi.sav.x_old[i]); } } else { EDstate->nref[nr_edi] = edi.sref.nr; - EDstate->nav [nr_edi] = edi.sav.nr; + EDstate->nav[nr_edi] = edi.sav.nr; } /* For subsequent checkpoint writing, set the edsamstate pointers to the edi arrays: */ EDstate->old_sref_p[nr_edi] = edi.sref.x_old; - EDstate->old_sav_p [nr_edi] = edi.sav.x_old; + EDstate->old_sav_p[nr_edi] = edi.sav.x_old; } } /* Adds 'buf' to 'str' */ -static void add_to_string(char **str, const char *buf) +static void add_to_string(char** str, const char* buf) { int len; @@ -2434,7 +2465,7 @@ static void add_to_string(char **str, const char *buf) } -static void add_to_string_aligned(char **str, const char *buf) +static void add_to_string_aligned(char** str, const char* buf) { char buf_aligned[STRLEN]; @@ -2443,17 +2474,27 @@ static void add_to_string_aligned(char **str, const char *buf) } -static void nice_legend(const char ***setname, int *nsets, char **LegendStr, const char *value, const char *unit, char EDgroupchar) +static void nice_legend(const char*** setname, + int* nsets, + char** LegendStr, + const char* value, + const char* unit, + char EDgroupchar) { auto tmp = gmx::formatString("%c %s", EDgroupchar, value); add_to_string_aligned(LegendStr, tmp.c_str()); - tmp += gmx::formatString(" (%s)", unit); + tmp += gmx::formatString(" (%s)", unit); (*setname)[*nsets] = gmx_strdup(tmp.c_str()); (*nsets)++; } -static void nice_legend_evec(const char ***setname, int *nsets, char **LegendStr, t_eigvec *evec, char EDgroupChar, const char *EDtype) +static void nice_legend_evec(const char*** setname, + int* nsets, + char** LegendStr, + t_eigvec* evec, + char EDgroupChar, + const char* EDtype) { int i; char tmp[STRLEN]; @@ -2468,31 +2509,40 @@ static void nice_legend_evec(const char ***setname, int *nsets, char **LegendStr /* Makes a legend for the xvg output file. Call on MASTER only! */ -static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oenv) +static void write_edo_legend(gmx_edsam* ed, int nED, const gmx_output_env_t* oenv) { int i; int nr_edi, nsets, n_flood, n_edsam; - const char **setname; + const char** setname; char buf[STRLEN]; - char *LegendStr = nullptr; + char* LegendStr = nullptr; - auto edi = ed->edpar.begin(); + auto edi = ed->edpar.begin(); - fprintf(ed->edo, "# Output will be written every %d step%s\n", edi->outfrq, edi->outfrq != 1 ? "s" : ""); + fprintf(ed->edo, "# Output will be written every %d step%s\n", edi->outfrq, + edi->outfrq != 1 ? "s" : ""); for (nr_edi = 1; nr_edi <= nED; nr_edi++) { fprintf(ed->edo, "#\n"); - fprintf(ed->edo, "# Summary of applied con/restraints for the ED group %c\n", get_EDgroupChar(nr_edi, nED)); + fprintf(ed->edo, "# Summary of applied con/restraints for the ED group %c\n", + get_EDgroupChar(nr_edi, nED)); fprintf(ed->edo, "# Atoms in average structure: %d\n", edi->sav.nr); - fprintf(ed->edo, "# monitor : %d vec%s\n", edi->vecs.mon.neig, edi->vecs.mon.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# LINFIX : %d vec%s\n", edi->vecs.linfix.neig, edi->vecs.linfix.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# LINACC : %d vec%s\n", edi->vecs.linacc.neig, edi->vecs.linacc.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# RADFIX : %d vec%s\n", edi->vecs.radfix.neig, edi->vecs.radfix.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# RADACC : %d vec%s\n", edi->vecs.radacc.neig, edi->vecs.radacc.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# RADCON : %d vec%s\n", edi->vecs.radcon.neig, edi->vecs.radcon.neig != 1 ? "s" : ""); - fprintf(ed->edo, "# FLOODING : %d vec%s ", edi->flood.vecs.neig, edi->flood.vecs.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# monitor : %d vec%s\n", edi->vecs.mon.neig, + edi->vecs.mon.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# LINFIX : %d vec%s\n", edi->vecs.linfix.neig, + edi->vecs.linfix.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# LINACC : %d vec%s\n", edi->vecs.linacc.neig, + edi->vecs.linacc.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# RADFIX : %d vec%s\n", edi->vecs.radfix.neig, + edi->vecs.radfix.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# RADACC : %d vec%s\n", edi->vecs.radacc.neig, + edi->vecs.radacc.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# RADCON : %d vec%s\n", edi->vecs.radcon.neig, + edi->vecs.radcon.neig != 1 ? "s" : ""); + fprintf(ed->edo, "# FLOODING : %d vec%s ", edi->flood.vecs.neig, + edi->flood.vecs.neig != 1 ? "s" : ""); if (edi->flood.vecs.neig) { @@ -2525,17 +2575,13 @@ static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oe add_to_string(&LegendStr, buf); /* Calculate the maximum number of columns we could end up with */ - edi = ed->edpar.begin(); - nsets = 0; + edi = ed->edpar.begin(); + nsets = 0; for (nr_edi = 1; nr_edi <= nED; nr_edi++) { - nsets += 5 +edi->vecs.mon.neig - +edi->vecs.linfix.neig - +edi->vecs.linacc.neig - +edi->vecs.radfix.neig - +edi->vecs.radacc.neig - +edi->vecs.radcon.neig - + 6*edi->flood.vecs.neig; + nsets += 5 + edi->vecs.mon.neig + edi->vecs.linfix.neig + edi->vecs.linacc.neig + + edi->vecs.radfix.neig + edi->vecs.radacc.neig + edi->vecs.radcon.neig + + 6 * edi->flood.vecs.neig; ++edi; } snew(setname, nsets); @@ -2549,14 +2595,14 @@ static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oe nsets = 0; if (EssentialDynamicsType::Flooding == ed->eEDtype) { - edi = ed->edpar.begin(); + edi = ed->edpar.begin(); for (nr_edi = 1; nr_edi <= nED; nr_edi++) { /* Always write out the projection on the flooding EVs. Of course, this can also * be achieved with the monitoring option in do_edsam() (if switched on by the * user), but in that case the positions need to be communicated in do_edsam(), * which is not necessary when doing flooding only. */ - nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED) ); + nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED)); for (i = 0; i < edi->flood.vecs.neig; i++) { @@ -2597,31 +2643,40 @@ static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oe n_flood = nsets; /* Now the ED-related entries, if essential dynamics is done */ - edi = ed->edpar.begin(); + edi = ed->edpar.begin(); for (nr_edi = 1; nr_edi <= nED; nr_edi++) { - if (bNeedDoEdsam(*edi)) /* Only print ED legend if at least one ED option is on */ + if (bNeedDoEdsam(*edi)) /* Only print ED legend if at least one ED option is on */ { - nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED) ); + nice_legend(&setname, &nsets, &LegendStr, "RMSD to ref", "nm", get_EDgroupChar(nr_edi, nED)); /* Essential dynamics, projections on eigenvectors */ - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.mon, get_EDgroupChar(nr_edi, nED), "MON" ); - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linfix, get_EDgroupChar(nr_edi, nED), "LINFIX"); - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linacc, get_EDgroupChar(nr_edi, nED), "LINACC"); - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radfix, get_EDgroupChar(nr_edi, nED), "RADFIX"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.mon, + get_EDgroupChar(nr_edi, nED), "MON"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linfix, + get_EDgroupChar(nr_edi, nED), "LINFIX"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.linacc, + get_EDgroupChar(nr_edi, nED), "LINACC"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radfix, + get_EDgroupChar(nr_edi, nED), "RADFIX"); if (edi->vecs.radfix.neig) { - nice_legend(&setname, &nsets, &LegendStr, "RADFIX radius", "nm", get_EDgroupChar(nr_edi, nED)); + nice_legend(&setname, &nsets, &LegendStr, "RADFIX radius", "nm", + get_EDgroupChar(nr_edi, nED)); } - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radacc, get_EDgroupChar(nr_edi, nED), "RADACC"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radacc, + get_EDgroupChar(nr_edi, nED), "RADACC"); if (edi->vecs.radacc.neig) { - nice_legend(&setname, &nsets, &LegendStr, "RADACC radius", "nm", get_EDgroupChar(nr_edi, nED)); + nice_legend(&setname, &nsets, &LegendStr, "RADACC radius", "nm", + get_EDgroupChar(nr_edi, nED)); } - nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radcon, get_EDgroupChar(nr_edi, nED), "RADCON"); + nice_legend_evec(&setname, &nsets, &LegendStr, &edi->vecs.radcon, + get_EDgroupChar(nr_edi, nED), "RADCON"); if (edi->vecs.radcon.neig) { - nice_legend(&setname, &nsets, &LegendStr, "RADCON radius", "nm", get_EDgroupChar(nr_edi, nED)); + nice_legend(&setname, &nsets, &LegendStr, "RADCON radius", "nm", + get_EDgroupChar(nr_edi, nED)); } } ++edi; @@ -2631,10 +2686,10 @@ static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oe xvgr_legend(ed->edo, nsets, setname, oenv); sfree(setname); - fprintf(ed->edo, "#\n" + fprintf(ed->edo, + "#\n" "# Legend for %d column%s of flooding plus %d column%s of essential dynamics data:\n", - n_flood, 1 == n_flood ? "" : "s", - n_edsam, 1 == n_edsam ? "" : "s"); + n_flood, 1 == n_flood ? "" : "s", n_edsam, 1 == n_edsam ? "" : "s"); fprintf(ed->edo, "%s", LegendStr); sfree(LegendStr); @@ -2644,42 +2699,43 @@ static void write_edo_legend(gmx_edsam * ed, int nED, const gmx_output_env_t *oe /* Init routine for ED and flooding. Calls init_edi in a loop for every .edi-cycle * contained in the input file, creates a NULL terminated list of t_edpar structures */ -std::unique_ptr init_edsam( - const gmx::MDLogger &mdlog, - const char *ediFileName, - const char *edoFileName, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_commrec *cr, - gmx::Constraints *constr, - const t_state *globalState, - ObservablesHistory *oh, - const gmx_output_env_t *oenv, - const gmx::StartingBehavior startingBehavior) -{ - int i, avindex; - rvec *x_pbc = nullptr; /* positions of the whole MD system with pbc removed */ - rvec *xfit = nullptr, *xstart = nullptr; /* dummy arrays to determine initial RMSDs */ - rvec fit_transvec; /* translation ... */ - matrix fit_rotmat; /* ... and rotation from fit to reference structure */ - rvec *ref_x_old = nullptr; /* helper pointer */ +std::unique_ptr init_edsam(const gmx::MDLogger& mdlog, + const char* ediFileName, + const char* edoFileName, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const t_commrec* cr, + gmx::Constraints* constr, + const t_state* globalState, + ObservablesHistory* oh, + const gmx_output_env_t* oenv, + const gmx::StartingBehavior startingBehavior) +{ + int i, avindex; + rvec* x_pbc = nullptr; /* positions of the whole MD system with pbc removed */ + rvec * xfit = nullptr, *xstart = nullptr; /* dummy arrays to determine initial RMSDs */ + rvec fit_transvec; /* translation ... */ + matrix fit_rotmat; /* ... and rotation from fit to reference structure */ + rvec* ref_x_old = nullptr; /* helper pointer */ if (MASTER(cr)) { fprintf(stderr, "ED: Initializing essential dynamics constraints.\n"); - if (oh->edsamHistory != nullptr && oh->edsamHistory->bFromCpt && !gmx_fexist(ediFileName) ) + if (oh->edsamHistory != nullptr && oh->edsamHistory->bFromCpt && !gmx_fexist(ediFileName)) { - gmx_fatal(FARGS, "The checkpoint file you provided is from an essential dynamics or flooding\n" + gmx_fatal(FARGS, + "The checkpoint file you provided is from an essential dynamics or flooding\n" "simulation. Please also set the .edi file on the command line with -ei.\n"); } - } - GMX_LOG(mdlog.info).asParagraph(). - appendText("Activating essential dynamics via files passed to " - "gmx mdrun -edi will change in future to be files passed to " - "gmx grompp and the related .mdp options may change also."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Activating essential dynamics via files passed to " + "gmx mdrun -edi will change in future to be files passed to " + "gmx grompp and the related .mdp options may change also."); /* Open input and output files, allocate space for ED data structure */ auto edHandle = ed_open(mtop->natoms, oh, ediFileName, edoFileName, startingBehavior, oenv, cr); @@ -2699,7 +2755,7 @@ std::unique_ptr init_edsam( * flooding vector, Essential dynamics can be applied to more than one structure * as well, but will be done in the order given in the edi file, so * expect different results for different order of edi file concatenation! */ - for (auto &edi : ed->edpar) + for (auto& edi : ed->edpar) { init_edi(mtop, &edi); init_flood(&edi, ed, ir->delta_t); @@ -2710,7 +2766,7 @@ std::unique_ptr init_edsam( * not before dd_partition_system which is called after init_edsam */ if (MASTER(cr)) { - edsamhistory_t *EDstate = oh->edsamHistory.get(); + edsamhistory_t* EDstate = oh->edsamHistory.get(); if (!EDstate->bFromCpt) { @@ -2755,8 +2811,8 @@ std::unique_ptr init_edsam( average structure. We copy that over to dummy arrays on which we can apply fitting to print out the RMSD. We srenew the memory since the size of the buffers is likely different for every ED group */ - srenew(xfit, edi->sref.nr ); - srenew(xstart, edi->sav.nr ); + srenew(xfit, edi->sref.nr); + srenew(xstart, edi->sav.nr); if (edi->bRefEqAv) { /* Reference indices are the same as average indices */ @@ -2823,9 +2879,10 @@ std::unique_ptr init_edsam( } /* process structure that will serve as origin of expansion circle */ - if ( (EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce) ) + if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce)) { - fprintf(stderr, "ED: Setting center of flooding potential (0 = average structure)\n"); + fprintf(stderr, + "ED: Setting center of flooding potential (0 = average structure)\n"); } if (edi->sori.nr > 0) @@ -2848,9 +2905,11 @@ std::unique_ptr init_edsam( rad_project(*edi, &edi->sori.x[avindex], &edi->vecs.radacc); rad_project(*edi, &edi->sori.x[avindex], &edi->vecs.radfix); - if ( (EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce) ) + if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce)) { - fprintf(stderr, "ED: The ORIGIN structure will define the flooding potential center.\n"); + fprintf(stderr, + "ED: The ORIGIN structure will define the flooding potential " + "center.\n"); /* Set center of flooding potential to the ORIGIN structure */ rad_project(*edi, &edi->sori.x[avindex], &edi->flood.vecs); /* We already know that no (moving) reference position was provided, @@ -2862,11 +2921,13 @@ std::unique_ptr init_edsam( { rad_project(*edi, xstart, &edi->vecs.radacc); rad_project(*edi, xstart, &edi->vecs.radfix); - if ( (EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce) ) + if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce)) { if (edi->flood.bHarmonic) { - fprintf(stderr, "ED: A (possibly changing) ref. projection will define the flooding potential center.\n"); + fprintf(stderr, + "ED: A (possibly changing) ref. projection will define the " + "flooding potential center.\n"); for (i = 0; i < edi->flood.vecs.neig; i++) { edi->flood.vecs.refproj[i] = edi->flood.initialReferenceProjection[i]; @@ -2874,7 +2935,9 @@ std::unique_ptr init_edsam( } else { - fprintf(stderr, "ED: The AVERAGE structure will define the flooding potential center.\n"); + fprintf(stderr, + "ED: The AVERAGE structure will define the flooding potential " + "center.\n"); /* Set center of flooding potential to the center of the covariance matrix, * i.e. the average structure, i.e. zero in the projected system */ for (i = 0; i < edi->flood.vecs.neig; i++) @@ -2885,14 +2948,16 @@ std::unique_ptr init_edsam( } } /* For convenience, output the center of the flooding potential for the eigenvectors */ - if ( (EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce) ) + if ((EssentialDynamicsType::Flooding == ed->eEDtype) && (!edi->flood.bConstForce)) { for (i = 0; i < edi->flood.vecs.neig; i++) { - fprintf(stdout, "ED: EV %d flooding potential center: %11.4e", edi->flood.vecs.ieig[i], edi->flood.vecs.refproj[i]); + fprintf(stdout, "ED: EV %d flooding potential center: %11.4e", + edi->flood.vecs.ieig[i], edi->flood.vecs.refproj[i]); if (edi->flood.bHarmonic) { - fprintf(stdout, " (adding %11.4e/timestep)", edi->flood.referenceProjectionSlope[i]); + fprintf(stdout, " (adding %11.4e/timestep)", + edi->flood.referenceProjectionSlope[i]); } fprintf(stdout, "\n"); } @@ -2970,13 +3035,13 @@ std::unique_ptr init_edsam( /* Collective positions of atoms with the average indices */ snew(edi->buf->do_edsam->xcoll, edi->sav.nr); - snew(edi->buf->do_edsam->shifts_xcoll, edi->sav.nr); /* buffer for xcoll shifts */ + snew(edi->buf->do_edsam->shifts_xcoll, edi->sav.nr); /* buffer for xcoll shifts */ snew(edi->buf->do_edsam->extra_shifts_xcoll, edi->sav.nr); /* Collective positions of atoms with the reference indices */ if (!edi->bRefEqAv) { snew(edi->buf->do_edsam->xc_ref, edi->sref.nr); - snew(edi->buf->do_edsam->shifts_xc_ref, edi->sref.nr); /* To store the shifts in */ + snew(edi->buf->do_edsam->shifts_xc_ref, edi->sref.nr); /* To store the shifts in */ snew(edi->buf->do_edsam->extra_shifts_xc_ref, edi->sref.nr); } @@ -2995,22 +3060,16 @@ std::unique_ptr init_edsam( } -void do_edsam(const t_inputrec *ir, - int64_t step, - const t_commrec *cr, - rvec xs[], - rvec v[], - const matrix box, - gmx_edsam *ed) +void do_edsam(const t_inputrec* ir, int64_t step, const t_commrec* cr, rvec xs[], rvec v[], const matrix box, gmx_edsam* ed) { - int i, edinr, iupdate = 500; - matrix rotmat; /* rotation matrix */ - rvec transvec; /* translation vector */ - rvec dv, dx, x_unsh; /* tmp vectors for velocity, distance, unshifted x coordinate */ - real dt_1; /* 1/dt */ - struct t_do_edsam *buf; - real rmsdev = -1; /* RMSD from reference structure prior to applying the constraints */ - gmx_bool bSuppress = FALSE; /* Write .xvg output file on master? */ + int i, edinr, iupdate = 500; + matrix rotmat; /* rotation matrix */ + rvec transvec; /* translation vector */ + rvec dv, dx, x_unsh; /* tmp vectors for velocity, distance, unshifted x coordinate */ + real dt_1; /* 1/dt */ + struct t_do_edsam* buf; + real rmsdev = -1; /* RMSD from reference structure prior to applying the constraints */ + gmx_bool bSuppress = FALSE; /* Write .xvg output file on master? */ /* Check if ED sampling has to be performed */ @@ -3019,11 +3078,11 @@ void do_edsam(const t_inputrec *ir, return; } - dt_1 = 1.0/ir->delta_t; + dt_1 = 1.0 / ir->delta_t; /* Loop over all ED groups (usually one) */ edinr = 0; - for (auto &edi : ed->edpar) + for (auto& edi : ed->edpar) { edinr++; if (bNeedDoEdsam(edi)) @@ -3045,14 +3104,17 @@ void do_edsam(const t_inputrec *ir, * the collective buf->xcoll array. Note that for edinr > 1 * xs could already have been modified by an earlier ED */ - communicate_group_positions(cr, buf->xcoll, buf->shifts_xcoll, buf->extra_shifts_xcoll, PAR(cr) ? buf->bUpdateShifts : TRUE, xs, - edi.sav.nr, edi.sav.nr_loc, edi.sav.anrs_loc, edi.sav.c_ind, edi.sav.x_old, box); + communicate_group_positions(cr, buf->xcoll, buf->shifts_xcoll, buf->extra_shifts_xcoll, + PAR(cr) ? buf->bUpdateShifts : TRUE, xs, edi.sav.nr, edi.sav.nr_loc, + edi.sav.anrs_loc, edi.sav.c_ind, edi.sav.x_old, box); /* Only assembly reference positions if their indices differ from the average ones */ if (!edi.bRefEqAv) { - communicate_group_positions(cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, PAR(cr) ? buf->bUpdateShifts : TRUE, xs, - edi.sref.nr, edi.sref.nr_loc, edi.sref.anrs_loc, edi.sref.c_ind, edi.sref.x_old, box); + communicate_group_positions( + cr, buf->xc_ref, buf->shifts_xc_ref, buf->extra_shifts_xc_ref, + PAR(cr) ? buf->bUpdateShifts : TRUE, xs, edi.sref.nr, edi.sref.nr_loc, + edi.sref.anrs_loc, edi.sref.c_ind, edi.sref.x_old, box); } /* If bUpdateShifts was TRUE then the shifts have just been updated in communicate_group_positions. @@ -3123,7 +3185,7 @@ void do_edsam(const t_inputrec *ir, { /* ED constraints should be applied already in the first MD step * (which is step 0), therefore we pass step+1 to the routine */ - ed_apply_constraints(buf->xcoll, &edi, step+1 - ir->init_step); + ed_apply_constraints(buf->xcoll, &edi, step + 1 - ir->init_step); } /* write to edo, when required */ diff --git a/src/gromacs/essentialdynamics/edsam.h b/src/gromacs/essentialdynamics/edsam.h index 7fd2d28dc9..7ec53375d7 100644 --- a/src/gromacs/essentialdynamics/edsam.h +++ b/src/gromacs/essentialdynamics/edsam.h @@ -74,19 +74,20 @@ enum class StartingBehavior; class Constraints; class EssentialDynamics { - public: - EssentialDynamics(); - ~EssentialDynamics(); +public: + EssentialDynamics(); + ~EssentialDynamics(); - /*! \brief Getter for working data - * - * This is needed while the module is still under - * construction. */ - gmx_edsam *getLegacyED(); - private: - class Impl; + /*! \brief Getter for working data + * + * This is needed while the module is still under + * construction. */ + gmx_edsam* getLegacyED(); - PrivateImplPointer impl_; +private: + class Impl; + + PrivateImplPointer impl_; }; class MDLogger; } // namespace gmx @@ -101,8 +102,13 @@ class MDLogger; * \param box The simulation box. * \param ed The essential dynamics data. */ -void do_edsam(const t_inputrec *ir, int64_t step, - const t_commrec *cr, rvec xs[], rvec v[], const matrix box, gmx_edsam *ed); +void do_edsam(const t_inputrec* ir, + int64_t step, + const t_commrec* cr, + rvec xs[], + rvec v[], + const matrix box, + gmx_edsam* ed); /*! \brief Initializes the essential dynamics and flooding module. @@ -121,18 +127,17 @@ void do_edsam(const t_inputrec *ir, int64_t step, * * \returns A pointer to the ED data structure. */ -std::unique_ptr init_edsam( - const gmx::MDLogger &mdlog, - const char *ediFileName, - const char *edoFileName, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_commrec *cr, - gmx::Constraints *constr, - const t_state *globalState, - ObservablesHistory *oh, - const gmx_output_env_t *oenv, - gmx::StartingBehavior startingBehavior); +std::unique_ptr init_edsam(const gmx::MDLogger& mdlog, + const char* ediFileName, + const char* edoFileName, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const t_commrec* cr, + gmx::Constraints* constr, + const t_state* globalState, + ObservablesHistory* oh, + const gmx_output_env_t* oenv, + gmx::StartingBehavior startingBehavior); /*! \brief Make a selection of the home atoms for the ED groups. * @@ -141,7 +146,7 @@ std::unique_ptr init_edsam( * \param dd Domain decomposition data. * \param ed Essential dynamics and flooding data. */ -void dd_make_local_ed_indices(gmx_domdec_t *dd, gmx_edsam * ed); +void dd_make_local_ed_indices(gmx_domdec_t* dd, gmx_edsam* ed); /*! \brief Evaluate the flooding potential(s) and forces as requested in the .edi input file. @@ -155,11 +160,11 @@ void dd_make_local_ed_indices(gmx_domdec_t *dd, gmx_edsam * ed); * \param step Number of the time step. * \param bNS Are we in a neighbor searching step? */ -void do_flood(const t_commrec *cr, - const t_inputrec *ir, +void do_flood(const t_commrec* cr, + const t_inputrec* ir, const rvec x[], rvec force[], - gmx_edsam *ed, + gmx_edsam* ed, const matrix box, int64_t step, gmx_bool bNS); diff --git a/src/gromacs/ewald/calculate_spline_moduli.cpp b/src/gromacs/ewald/calculate_spline_moduli.cpp index ac2136e5c0..3471ac0a7a 100644 --- a/src/gromacs/ewald/calculate_spline_moduli.cpp +++ b/src/gromacs/ewald/calculate_spline_moduli.cpp @@ -50,8 +50,7 @@ #include "pme_internal.h" -static void make_dft_mod(real *mod, - const double *data, int splineOrder, int ndata) +static void make_dft_mod(real* mod, const double* data, int splineOrder, int ndata) { for (int i = 0; i < ndata; i++) { @@ -63,16 +62,18 @@ static void make_dft_mod(real *mod, double ss = 0; for (int j = 0; j < splineOrder; j++) { - double arg = (2.0*M_PI*i*(j + 1))/ndata; - sc += data[j]*cos(arg); - ss += data[j]*sin(arg); + double arg = (2.0 * M_PI * i * (j + 1)) / ndata; + sc += data[j] * cos(arg); + ss += data[j] * sin(arg); } - mod[i] = sc*sc + ss*ss; + mod[i] = sc * sc + ss * ss; } if (splineOrder % 2 == 0 && ndata % 2 == 0) { /* Note that pme_order = splineOrder + 1 */ - GMX_RELEASE_ASSERT(mod[ndata/2] < GMX_DOUBLE_EPS, "With even spline order and even grid size (ndata), dft_mod[ndata/2] should first come out as zero"); + GMX_RELEASE_ASSERT(mod[ndata / 2] < GMX_DOUBLE_EPS, + "With even spline order and even grid size (ndata), dft_mod[ndata/2] " + "should first come out as zero"); /* This factor causes a division by zero. But since this occurs in * the tail of the distribution, the term with this factor can * be ignored (see Essmann et al. JCP 103, 8577). @@ -80,18 +81,17 @@ static void make_dft_mod(real *mod, * Tom Darden's original PME code. It seems to give slighlty better * accuracy than using a large value. */ - mod[ndata/2] = (mod[ndata/2 - 1] + mod[ndata/2 + 1])*0.5; + mod[ndata / 2] = (mod[ndata / 2 - 1] + mod[ndata / 2 + 1]) * 0.5; } } -void make_bspline_moduli(splinevec bsp_mod, - int nx, int ny, int nz, int pme_order) +void make_bspline_moduli(splinevec bsp_mod, int nx, int ny, int nz, int pme_order) { /* We use double precision, since this is only called once per grid. * But for single precision bsp_mod, single precision also seems * to give full accuracy. */ - double *data; + double* data; /* In GROMACS we, confusingly, defined pme-order as the order * of the cardinal B-spline + 1. This probably happened because @@ -102,7 +102,7 @@ void make_bspline_moduli(splinevec bsp_mod, snew(data, splineOrder); - data[0] = 1; + data[0] = 1; for (int k = 1; k < splineOrder; k++) { data[k] = 0; @@ -110,12 +110,12 @@ void make_bspline_moduli(splinevec bsp_mod, for (int k = 2; k <= splineOrder; k++) { - double div = 1.0/k; + double div = 1.0 / k; for (int m = k - 1; m > 0; m--) { - data[m] = div*((k - m)*data[m - 1] + (m + 1)*data[m]); + data[m] = div * ((k - m) * data[m - 1] + (m + 1) * data[m]); } - data[0] = div*data[0]; + data[0] = div * data[0]; } make_dft_mod(bsp_mod[XX], data, splineOrder, nx); @@ -130,35 +130,36 @@ static double do_p3m_influence(double z, int order) { double z2, z4; - z2 = z*z; - z4 = z2*z2; + z2 = z * z; + z4 = z2 * z2; /* The formula and most constants can be found in: * Ballenegger et al., JCTC 8, 936 (2012) */ switch (order) { - case 2: - return 1.0 - 2.0*z2/3.0; - case 3: - return 1.0 - z2 + 2.0*z4/15.0; - case 4: - return 1.0 - 4.0*z2/3.0 + 2.0*z4/5.0 + 4.0*z2*z4/315.0; + case 2: return 1.0 - 2.0 * z2 / 3.0; + case 3: return 1.0 - z2 + 2.0 * z4 / 15.0; + case 4: return 1.0 - 4.0 * z2 / 3.0 + 2.0 * z4 / 5.0 + 4.0 * z2 * z4 / 315.0; case 5: - return 1.0 - 5.0*z2/3.0 + 7.0*z4/9.0 - 17.0*z2*z4/189.0 + 2.0*z4*z4/2835.0; + return 1.0 - 5.0 * z2 / 3.0 + 7.0 * z4 / 9.0 - 17.0 * z2 * z4 / 189.0 + 2.0 * z4 * z4 / 2835.0; case 6: - return 1.0 - 2.0*z2 + 19.0*z4/15.0 - 256.0*z2*z4/945.0 + 62.0*z4*z4/4725.0 + 4.0*z2*z4*z4/155925.0; + return 1.0 - 2.0 * z2 + 19.0 * z4 / 15.0 - 256.0 * z2 * z4 / 945.0 + + 62.0 * z4 * z4 / 4725.0 + 4.0 * z2 * z4 * z4 / 155925.0; case 7: - return 1.0 - 7.0*z2/3.0 + 28.0*z4/15.0 - 16.0*z2*z4/27.0 + 26.0*z4*z4/405.0 - 2.0*z2*z4*z4/1485.0 + 4.0*z4*z4*z4/6081075.0; + return 1.0 - 7.0 * z2 / 3.0 + 28.0 * z4 / 15.0 - 16.0 * z2 * z4 / 27.0 + 26.0 * z4 * z4 / 405.0 + - 2.0 * z2 * z4 * z4 / 1485.0 + 4.0 * z4 * z4 * z4 / 6081075.0; case 8: - return 1.0 - 8.0*z2/3.0 + 116.0*z4/45.0 - 344.0*z2*z4/315.0 + 914.0*z4*z4/4725.0 - 248.0*z4*z4*z2/22275.0 + 21844.0*z4*z4*z4/212837625.0 - 8.0*z4*z4*z4*z2/638512875.0; + return 1.0 - 8.0 * z2 / 3.0 + 116.0 * z4 / 45.0 - 344.0 * z2 * z4 / 315.0 + + 914.0 * z4 * z4 / 4725.0 - 248.0 * z4 * z4 * z2 / 22275.0 + + 21844.0 * z4 * z4 * z4 / 212837625.0 - 8.0 * z4 * z4 * z4 * z2 / 638512875.0; } return 0.0; } /* Calculate the P3M B-spline moduli for one dimension */ -static void make_p3m_bspline_moduli_dim(real *bsp_mod, int n, int order) +static void make_p3m_bspline_moduli_dim(real* bsp_mod, int n, int order) { double zarg, zai, sinzai, infl; int maxk, i; @@ -168,30 +169,29 @@ static void make_p3m_bspline_moduli_dim(real *bsp_mod, int n, int order) GMX_THROW(gmx::InconsistentInputError("The current P3M code only supports orders up to 8")); } - zarg = M_PI/n; + zarg = M_PI / n; - maxk = (n + 1)/2; + maxk = (n + 1) / 2; for (i = -maxk; i < 0; i++) { - zai = zarg*i; - sinzai = sin(zai); - infl = do_p3m_influence(sinzai, order); - bsp_mod[n+i] = infl*infl*pow(sinzai/zai, -2.0*order); + zai = zarg * i; + sinzai = sin(zai); + infl = do_p3m_influence(sinzai, order); + bsp_mod[n + i] = infl * infl * pow(sinzai / zai, -2.0 * order); } bsp_mod[0] = 1.0; for (i = 1; i < maxk; i++) { - zai = zarg*i; + zai = zarg * i; sinzai = sin(zai); infl = do_p3m_influence(sinzai, order); - bsp_mod[i] = infl*infl*pow(sinzai/zai, -2.0*order); + bsp_mod[i] = infl * infl * pow(sinzai / zai, -2.0 * order); } } /* Calculate the P3M B-spline moduli */ -void make_p3m_bspline_moduli(splinevec bsp_mod, - int nx, int ny, int nz, int order) +void make_p3m_bspline_moduli(splinevec bsp_mod, int nx, int ny, int nz, int order) { make_p3m_bspline_moduli_dim(bsp_mod[XX], nx, order); make_p3m_bspline_moduli_dim(bsp_mod[YY], ny, order); diff --git a/src/gromacs/ewald/calculate_spline_moduli.h b/src/gromacs/ewald/calculate_spline_moduli.h index 35746f60e5..24c8fef6df 100644 --- a/src/gromacs/ewald/calculate_spline_moduli.h +++ b/src/gromacs/ewald/calculate_spline_moduli.h @@ -40,11 +40,9 @@ #include "pme_internal.h" /* Calulate plain SPME B-spline interpolation */ -void make_bspline_moduli(splinevec bsp_mod, - int nx, int ny, int nz, int order); +void make_bspline_moduli(splinevec bsp_mod, int nx, int ny, int nz, int order); /* Calculate the P3M B-spline moduli */ -void make_p3m_bspline_moduli(splinevec bsp_mod, - int nx, int ny, int nz, int order); +void make_p3m_bspline_moduli(splinevec bsp_mod, int nx, int ny, int nz, int order); #endif diff --git a/src/gromacs/ewald/ewald.cpp b/src/gromacs/ewald/ewald.cpp index 1f44debc33..a114edbf50 100644 --- a/src/gromacs/ewald/ewald.cpp +++ b/src/gromacs/ewald/ewald.cpp @@ -72,11 +72,11 @@ struct gmx_ewald_tab_t { int nx, ny, nz, kmax; - cvec **eir; + cvec** eir; t_complex *tab_xy, *tab_qxyz; }; -void init_ewald_tab(struct gmx_ewald_tab_t **et, const t_inputrec *ir, FILE *fp) +void init_ewald_tab(struct gmx_ewald_tab_t** et, const t_inputrec* ir, FILE* fp) { snew(*et, 1); if (fp) @@ -84,9 +84,9 @@ void init_ewald_tab(struct gmx_ewald_tab_t **et, const t_inputrec *ir, FILE *fp) fprintf(fp, "Will do ordinary reciprocal space Ewald sum.\n"); } - (*et)->nx = ir->nkx+1; - (*et)->ny = ir->nky+1; - (*et)->nz = ir->nkz+1; + (*et)->nx = ir->nkx + 1; + (*et)->ny = ir->nky + 1; + (*et)->nz = ir->nkz + 1; (*et)->kmax = std::max((*et)->nx, std::max((*et)->ny, (*et)->nz)); (*et)->eir = nullptr; (*et)->tab_xy = nullptr; @@ -96,15 +96,15 @@ void init_ewald_tab(struct gmx_ewald_tab_t **et, const t_inputrec *ir, FILE *fp) //! Calculates wave vectors. static void calc_lll(const rvec box, rvec lll) { - lll[XX] = 2.0*M_PI/box[XX]; - lll[YY] = 2.0*M_PI/box[YY]; - lll[ZZ] = 2.0*M_PI/box[ZZ]; + lll[XX] = 2.0 * M_PI / box[XX]; + lll[YY] = 2.0 * M_PI / box[YY]; + lll[ZZ] = 2.0 * M_PI / box[ZZ]; } //! Make tables for the structure factor parts -static void tabulateStructureFactors(int natom, const rvec x[], int kmax, cvec **eir, const rvec lll) +static void tabulateStructureFactors(int natom, const rvec x[], int kmax, cvec** eir, const rvec lll) { - int i, j, m; + int i, j, m; if (kmax < 1) { @@ -122,35 +122,35 @@ static void tabulateStructureFactors(int natom, const rvec x[], int kmax, cvec * for (m = 0; (m < 3); m++) { - eir[1][i][m].re = std::cos(x[i][m]*lll[m]); - eir[1][i][m].im = std::sin(x[i][m]*lll[m]); + eir[1][i][m].re = std::cos(x[i][m] * lll[m]); + eir[1][i][m].im = std::sin(x[i][m] * lll[m]); } for (j = 2; (j < kmax); j++) { for (m = 0; (m < 3); m++) { - eir[j][i][m] = cmul(eir[j-1][i][m], eir[1][i][m]); + eir[j][i][m] = cmul(eir[j - 1][i][m], eir[1][i][m]); } } } } -real do_ewald(const t_inputrec *ir, +real do_ewald(const t_inputrec* ir, const rvec x[], rvec f[], const real chargeA[], const real chargeB[], const matrix box, - const t_commrec *cr, + const t_commrec* cr, int natoms, matrix lrvir, real ewaldcoeff, real lambda, - real *dvdlambda, - gmx_ewald_tab_t *et) + real* dvdlambda, + gmx_ewald_tab_t* et) { - real factor = -1.0/(4*ewaldcoeff*ewaldcoeff); - const real *charge; + real factor = -1.0 / (4 * ewaldcoeff * ewaldcoeff); + const real* charge; real energy_AB[2], energy; rvec lll; int lowiy, lowiz, ix, iy, iz, n, q; @@ -177,7 +177,7 @@ real do_ewald(const t_inputrec *ir, } /* 1/(Vol*e0) */ - real scaleRecip = 4.0*M_PI/(boxDiag[XX]*boxDiag[YY]*boxDiag[ZZ])*ONE_4PI_EPS0/ir->epsilon_r; + real scaleRecip = 4.0 * M_PI / (boxDiag[XX] * boxDiag[YY] * boxDiag[ZZ]) * ONE_4PI_EPS0 / ir->epsilon_r; if (!et->eir) /* allocate if we need to */ { @@ -219,10 +219,10 @@ real do_ewald(const t_inputrec *ir, energy_AB[q] = 0; for (ix = 0; ix < et->nx; ix++) { - mx = ix*lll[XX]; + mx = ix * lll[XX]; for (iy = lowiy; iy < et->ny; iy++) { - my = iy*lll[YY]; + my = iy * lll[YY]; if (iy >= 0) { for (n = 0; n < natoms; n++) @@ -239,24 +239,23 @@ real do_ewald(const t_inputrec *ir, } for (iz = lowiz; iz < et->nz; iz++) { - mz = iz*lll[ZZ]; - m2 = mx*mx+my*my+mz*mz; - ak = std::exp(m2*factor)/m2; - akv = 2.0*ak*(1.0/m2-factor); + mz = iz * lll[ZZ]; + m2 = mx * mx + my * my + mz * mz; + ak = std::exp(m2 * factor) / m2; + akv = 2.0 * ak * (1.0 / m2 - factor); if (iz >= 0) { for (n = 0; n < natoms; n++) { - et->tab_qxyz[n] = rcmul(charge[n], cmul(et->tab_xy[n], - et->eir[iz][n][ZZ])); + et->tab_qxyz[n] = rcmul(charge[n], cmul(et->tab_xy[n], et->eir[iz][n][ZZ])); } } else { for (n = 0; n < natoms; n++) { - et->tab_qxyz[n] = rcmul(charge[n], cmul(et->tab_xy[n], - conjugate(et->eir[-iz][n][ZZ]))); + et->tab_qxyz[n] = rcmul( + charge[n], cmul(et->tab_xy[n], conjugate(et->eir[-iz][n][ZZ]))); } } @@ -266,30 +265,30 @@ real do_ewald(const t_inputrec *ir, cs += et->tab_qxyz[n].re; ss += et->tab_qxyz[n].im; } - energy_AB[q] += ak*(cs*cs+ss*ss); - tmp = scale*akv*(cs*cs+ss*ss); - lrvir[XX][XX] -= tmp*mx*mx; - lrvir[XX][YY] -= tmp*mx*my; - lrvir[XX][ZZ] -= tmp*mx*mz; - lrvir[YY][YY] -= tmp*my*my; - lrvir[YY][ZZ] -= tmp*my*mz; - lrvir[ZZ][ZZ] -= tmp*mz*mz; + energy_AB[q] += ak * (cs * cs + ss * ss); + tmp = scale * akv * (cs * cs + ss * ss); + lrvir[XX][XX] -= tmp * mx * mx; + lrvir[XX][YY] -= tmp * mx * my; + lrvir[XX][ZZ] -= tmp * mx * mz; + lrvir[YY][YY] -= tmp * my * my; + lrvir[YY][ZZ] -= tmp * my * mz; + lrvir[ZZ][ZZ] -= tmp * mz * mz; for (n = 0; n < natoms; n++) { /*tmp=scale*ak*(cs*tab_qxyz[n].im-ss*tab_qxyz[n].re);*/ - tmp = scale*ak*(cs*et->tab_qxyz[n].im-ss*et->tab_qxyz[n].re); - f[n][XX] += tmp*mx*2*scaleRecip; - f[n][YY] += tmp*my*2*scaleRecip; - f[n][ZZ] += tmp*mz*2*scaleRecip; + tmp = scale * ak * (cs * et->tab_qxyz[n].im - ss * et->tab_qxyz[n].re); + f[n][XX] += tmp * mx * 2 * scaleRecip; + f[n][YY] += tmp * my * 2 * scaleRecip; + f[n][ZZ] += tmp * mz * 2 * scaleRecip; #if 0 f[n][XX] += tmp*mx; f[n][YY] += tmp*my; f[n][ZZ] += tmp*mz; #endif } - lowiz = 1-et->nz; + lowiz = 1 - et->nz; } - lowiy = 1-et->ny; + lowiy = 1 - et->ny; } } } @@ -300,16 +299,16 @@ real do_ewald(const t_inputrec *ir, } else { - energy = (1.0 - lambda)*energy_AB[0] + lambda*energy_AB[1]; - *dvdlambda += scaleRecip*(energy_AB[1] - energy_AB[0]); + energy = (1.0 - lambda) * energy_AB[0] + lambda * energy_AB[1]; + *dvdlambda += scaleRecip * (energy_AB[1] - energy_AB[0]); } - lrvir[XX][XX] = -0.5*scaleRecip*(lrvir[XX][XX]+energy); - lrvir[XX][YY] = -0.5*scaleRecip*(lrvir[XX][YY]); - lrvir[XX][ZZ] = -0.5*scaleRecip*(lrvir[XX][ZZ]); - lrvir[YY][YY] = -0.5*scaleRecip*(lrvir[YY][YY]+energy); - lrvir[YY][ZZ] = -0.5*scaleRecip*(lrvir[YY][ZZ]); - lrvir[ZZ][ZZ] = -0.5*scaleRecip*(lrvir[ZZ][ZZ]+energy); + lrvir[XX][XX] = -0.5 * scaleRecip * (lrvir[XX][XX] + energy); + lrvir[XX][YY] = -0.5 * scaleRecip * (lrvir[XX][YY]); + lrvir[XX][ZZ] = -0.5 * scaleRecip * (lrvir[XX][ZZ]); + lrvir[YY][YY] = -0.5 * scaleRecip * (lrvir[YY][YY] + energy); + lrvir[YY][ZZ] = -0.5 * scaleRecip * (lrvir[YY][ZZ]); + lrvir[ZZ][ZZ] = -0.5 * scaleRecip * (lrvir[ZZ][ZZ] + energy); lrvir[YY][XX] = lrvir[XX][YY]; lrvir[ZZ][XX] = lrvir[XX][ZZ]; @@ -320,11 +319,11 @@ real do_ewald(const t_inputrec *ir, return energy; } -real ewald_charge_correction(const t_commrec *cr, - const t_forcerec *fr, +real ewald_charge_correction(const t_commrec* cr, + const t_forcerec* fr, const real lambda, const matrix box, - real *dvdlambda, + real* dvdlambda, tensor vir) { @@ -334,18 +333,19 @@ real ewald_charge_correction(const t_commrec *cr, if (MASTER(cr)) { /* Apply charge correction */ - vol = box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]; + vol = box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]; - fac = M_PI*ONE_4PI_EPS0/(fr->ic->epsilon_r*2.0*vol*vol*gmx::square(fr->ic->ewaldcoeff_q)); + fac = M_PI * ONE_4PI_EPS0 + / (fr->ic->epsilon_r * 2.0 * vol * vol * gmx::square(fr->ic->ewaldcoeff_q)); - qs2A = fr->qsum[0]*fr->qsum[0]; - qs2B = fr->qsum[1]*fr->qsum[1]; + qs2A = fr->qsum[0] * fr->qsum[0]; + qs2B = fr->qsum[1] * fr->qsum[1]; - vc = (qs2A*(1 - lambda) + qs2B*lambda)*fac; + vc = (qs2A * (1 - lambda) + qs2B * lambda) * fac; - enercorr = -vol*vc; + enercorr = -vol * vc; - *dvdlambda += -vol*(qs2B - qs2A)*fac; + *dvdlambda += -vol * (qs2B - qs2A) * fac; for (d = 0; d < DIM; d++) { diff --git a/src/gromacs/ewald/ewald.h b/src/gromacs/ewald/ewald.h index a75ceddc47..6166927640 100644 --- a/src/gromacs/ewald/ewald.h +++ b/src/gromacs/ewald/ewald.h @@ -78,36 +78,32 @@ struct t_inputrec; struct gmx_ewald_tab_t; /*! \brief Initialize the tables used in the Ewald long-ranged part */ -void -init_ewald_tab(struct gmx_ewald_tab_t **et, const t_inputrec *ir, - FILE *fp); +void init_ewald_tab(struct gmx_ewald_tab_t** et, const t_inputrec* ir, FILE* fp); /*! \brief Do the long-ranged part of an Ewald calculation */ -real -do_ewald(const t_inputrec *ir, - const rvec x[], - rvec f[], - const real chargeA[], - const real chargeB[], - const matrix box, - const t_commrec *cr, - int natoms, - matrix lrvir, - real ewaldcoeff, - real lambda, - real *dvdlambda, - gmx_ewald_tab_t *et); +real do_ewald(const t_inputrec* ir, + const rvec x[], + rvec f[], + const real chargeA[], + const real chargeB[], + const matrix box, + const t_commrec* cr, + int natoms, + matrix lrvir, + real ewaldcoeff, + real lambda, + real* dvdlambda, + gmx_ewald_tab_t* et); /*! \brief Calculate the correction to the Ewald sum, due to a net system * charge. * * Should only be called on one thread. */ -real -ewald_charge_correction(const t_commrec *cr, - const t_forcerec *fr, - real lambda, - const matrix box, - real *dvdlambda, - tensor vir); +real ewald_charge_correction(const t_commrec* cr, + const t_forcerec* fr, + real lambda, + const matrix box, + real* dvdlambda, + tensor vir); #endif diff --git a/src/gromacs/ewald/ewald_utils.cpp b/src/gromacs/ewald/ewald_utils.cpp index be6727af06..3d5ccaf0d5 100644 --- a/src/gromacs/ewald/ewald_utils.cpp +++ b/src/gromacs/ewald/ewald_utils.cpp @@ -52,17 +52,16 @@ real calc_ewaldcoeff_q(real rc, real rtol) { i++; beta *= 2; - } - while (std::erfc(beta*rc) > rtol); + } while (std::erfc(beta * rc) > rtol); /* Do a binary search with tolerance 2^-60 */ - n = i+60; + n = i + 60; low = 0; high = beta; for (i = 0; i < n; i++) { - beta = (low+high)/2; - if (std::erfc(beta*rc) > rtol) + beta = (low + high) / 2; + if (std::erfc(beta * rc) > rtol) { low = beta; } @@ -77,10 +76,10 @@ real calc_ewaldcoeff_q(real rc, real rtol) static real compute_lj_function(real beta, real rc) { real xrc, xrc2, xrc4, result; - xrc = beta*rc; - xrc2 = xrc*xrc; - xrc4 = xrc2*xrc2; - result = std::exp(-xrc2)*(1 + xrc2 + xrc4/2.0); + xrc = beta * rc; + xrc2 = xrc * xrc; + xrc4 = xrc2 * xrc2; + result = std::exp(-xrc2) * (1 + xrc2 + xrc4 / 2.0); return result; } @@ -94,8 +93,7 @@ real calc_ewaldcoeff_lj(real rc, real rtol) { i++; beta *= 2.0; - } - while (compute_lj_function(beta, rc) > rtol); + } while (compute_lj_function(beta, rc) > rtol); /* Do a binary search with tolerance 2^-60 */ n = i + 60; diff --git a/src/gromacs/ewald/ewald_utils.h b/src/gromacs/ewald/ewald_utils.h index ab760f8efb..9f77967c37 100644 --- a/src/gromacs/ewald/ewald_utils.h +++ b/src/gromacs/ewald/ewald_utils.h @@ -65,8 +65,7 @@ * \return The value of the splitting coefficient that * produces the required dtol at rc. */ -real -calc_ewaldcoeff_q(real rc, real rtol); +real calc_ewaldcoeff_q(real rc, real rtol); /*! \brief Computes the Ewald splitting coefficient for LJ * @@ -80,8 +79,7 @@ calc_ewaldcoeff_q(real rc, real rtol); * \return The value of the splitting coefficient that * produces the required dtol at rc. */ -real -calc_ewaldcoeff_lj(real rc, real rtol); +real calc_ewaldcoeff_lj(real rc, real rtol); /*! \libinternal \brief Class to handle box scaling for Ewald and PME. @@ -94,48 +92,47 @@ calc_ewaldcoeff_lj(real rc, real rtol); class EwaldBoxZScaler { - private: - bool scaleWithWalls_; /**< True if the simulation uses two walls and the box needs to be scaled in PME */ - real scalingFactor_; /**< Box The scaling factor PME uses with walls */ +private: + bool scaleWithWalls_; /**< True if the simulation uses two walls and the box needs to be scaled in PME */ + real scalingFactor_; /**< Box The scaling factor PME uses with walls */ - public: - EwaldBoxZScaler() = delete; +public: + EwaldBoxZScaler() = delete; - /*! \brief Constructor that takes the input record to initialize Ewald box scaling appropriately. */ - EwaldBoxZScaler(const t_inputrec &ir) + /*! \brief Constructor that takes the input record to initialize Ewald box scaling appropriately. */ + EwaldBoxZScaler(const t_inputrec& ir) + { + if (inputrecPbcXY2Walls(&ir)) { - if (inputrecPbcXY2Walls(&ir)) - { - scaleWithWalls_ = true; - scalingFactor_ = ir.wall_ewald_zfac; - } - else - { - scaleWithWalls_ = false; - scalingFactor_ = 1; - } + scaleWithWalls_ = true; + scalingFactor_ = ir.wall_ewald_zfac; } - - /*! \brief Copy and scale the box for PME. - * - * When PME is used with 2D periodicity and two walls, the - * copy of the \p box passed is scaled with the Z scaling factor. - * - * \param[in] box The current box matrix - * \param[out] scaledBox Scaled copy of the box matrix. - */ - void scaleBox(const matrix box, - matrix scaledBox) + else { - GMX_ASSERT(box, "invalid source box pointer"); - GMX_ASSERT(scaledBox, "invalid target box pointer"); + scaleWithWalls_ = false; + scalingFactor_ = 1; + } + } - copy_mat(box, scaledBox); - if (scaleWithWalls_) - { - svmul(scalingFactor_, scaledBox[ZZ], scaledBox[ZZ]); - } + /*! \brief Copy and scale the box for PME. + * + * When PME is used with 2D periodicity and two walls, the + * copy of the \p box passed is scaled with the Z scaling factor. + * + * \param[in] box The current box matrix + * \param[out] scaledBox Scaled copy of the box matrix. + */ + void scaleBox(const matrix box, matrix scaledBox) + { + GMX_ASSERT(box, "invalid source box pointer"); + GMX_ASSERT(scaledBox, "invalid target box pointer"); + + copy_mat(box, scaledBox); + if (scaleWithWalls_) + { + svmul(scalingFactor_, scaledBox[ZZ], scaledBox[ZZ]); } + } }; #endif diff --git a/src/gromacs/ewald/long_range_correction.cpp b/src/gromacs/ewald/long_range_correction.cpp index b65b315021..16733a15f7 100644 --- a/src/gromacs/ewald/long_range_correction.cpp +++ b/src/gromacs/ewald/long_range_correction.cpp @@ -64,93 +64,92 @@ * perturbations. The parameter vectors for LJ-PME are likewise * undefined when LJ-PME is not active. This works because * bHaveChargeOrTypePerturbed handles the control flow. */ -void ewald_LRcorrection(const int numAtomsLocal, - const t_commrec *cr, - int numThreads, int thread, - const t_forcerec &fr, - const t_inputrec &ir, - const real *chargeA, const real *chargeB, - gmx_bool bHaveChargePerturbed, - const rvec x[], - const matrix box, - const rvec mu_tot[], - rvec *f, - real *Vcorr_q, - real lambda_q, - real *dvdlambda_q) +void ewald_LRcorrection(const int numAtomsLocal, + const t_commrec* cr, + int numThreads, + int thread, + const t_forcerec& fr, + const t_inputrec& ir, + const real* chargeA, + const real* chargeB, + gmx_bool bHaveChargePerturbed, + const rvec x[], + const matrix box, + const rvec mu_tot[], + rvec* f, + real* Vcorr_q, + real lambda_q, + real* dvdlambda_q) { /* We need to correct only self interactions */ - const int start = (numAtomsLocal* thread )/numThreads; - const int end = (numAtomsLocal*(thread + 1))/numThreads; + const int start = (numAtomsLocal * thread) / numThreads; + const int end = (numAtomsLocal * (thread + 1)) / numThreads; - int i, j, q; - double Vexcl_q, dvdl_excl_q; /* Necessary for precision */ - real one_4pi_eps; - real Vself_q[2], Vdipole[2]; - rvec mutot[2], dipcorrA, dipcorrB; - real L1_q, dipole_coeff; - real chargecorr[2] = { 0, 0 }; + int i, j, q; + double Vexcl_q, dvdl_excl_q; /* Necessary for precision */ + real one_4pi_eps; + real Vself_q[2], Vdipole[2]; + rvec mutot[2], dipcorrA, dipcorrB; + real L1_q, dipole_coeff; + real chargecorr[2] = { 0, 0 }; /* Scale the Ewald unit cell when dimension z is not periodic */ matrix scaledBox; EwaldBoxZScaler boxScaler(ir); boxScaler.scaleBox(box, scaledBox); - one_4pi_eps = ONE_4PI_EPS0/fr.ic->epsilon_r; - Vexcl_q = 0; - dvdl_excl_q = 0; - Vdipole[0] = 0; - Vdipole[1] = 0; - L1_q = 1.0-lambda_q; + one_4pi_eps = ONE_4PI_EPS0 / fr.ic->epsilon_r; + Vexcl_q = 0; + dvdl_excl_q = 0; + Vdipole[0] = 0; + Vdipole[1] = 0; + L1_q = 1.0 - lambda_q; /* Note that we have to transform back to gromacs units, since * mu_tot contains the dipole in debye units (for output). */ for (i = 0; (i < DIM); i++) { - mutot[0][i] = mu_tot[0][i]*DEBYE2ENM; - mutot[1][i] = mu_tot[1][i]*DEBYE2ENM; + mutot[0][i] = mu_tot[0][i] * DEBYE2ENM; + mutot[1][i] = mu_tot[1][i] * DEBYE2ENM; dipcorrA[i] = 0; dipcorrB[i] = 0; } dipole_coeff = 0; - real boxVolume = scaledBox[XX][XX]*scaledBox[YY][YY]*scaledBox[ZZ][ZZ]; + real boxVolume = scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ]; switch (ir.ewald_geometry) { case eewg3D: if (ir.epsilon_surface != 0) { - dipole_coeff = - 2*M_PI*ONE_4PI_EPS0/((2*ir.epsilon_surface + fr.ic->epsilon_r)*boxVolume); + dipole_coeff = 2 * M_PI * ONE_4PI_EPS0 + / ((2 * ir.epsilon_surface + fr.ic->epsilon_r) * boxVolume); for (i = 0; (i < DIM); i++) { - dipcorrA[i] = 2*dipole_coeff*mutot[0][i]; - dipcorrB[i] = 2*dipole_coeff*mutot[1][i]; + dipcorrA[i] = 2 * dipole_coeff * mutot[0][i]; + dipcorrB[i] = 2 * dipole_coeff * mutot[1][i]; } } break; case eewg3DC: - dipole_coeff = 2*M_PI*one_4pi_eps/boxVolume; - dipcorrA[ZZ] = 2*dipole_coeff*mutot[0][ZZ]; - dipcorrB[ZZ] = 2*dipole_coeff*mutot[1][ZZ]; + dipole_coeff = 2 * M_PI * one_4pi_eps / boxVolume; + dipcorrA[ZZ] = 2 * dipole_coeff * mutot[0][ZZ]; + dipcorrB[ZZ] = 2 * dipole_coeff * mutot[1][ZZ]; for (int q = 0; q < (bHaveChargePerturbed ? 2 : 1); q++) { /* Avoid charge corrections with near-zero net charge */ if (fabs(fr.qsum[q]) > 1e-4) { - chargecorr[q] = 2*dipole_coeff*fr.qsum[q]; + chargecorr[q] = 2 * dipole_coeff * fr.qsum[q]; } } break; - default: - gmx_incons("Unsupported Ewald geometry"); + default: gmx_incons("Unsupported Ewald geometry"); } if (debug) { - fprintf(debug, "dipcorr = %8.3f %8.3f %8.3f\n", - dipcorrA[XX], dipcorrA[YY], dipcorrA[ZZ]); - fprintf(debug, "mutot = %8.3f %8.3f %8.3f\n", - mutot[0][XX], mutot[0][YY], mutot[0][ZZ]); + fprintf(debug, "dipcorr = %8.3f %8.3f %8.3f\n", dipcorrA[XX], dipcorrA[YY], dipcorrA[ZZ]); + fprintf(debug, "mutot = %8.3f %8.3f %8.3f\n", mutot[0][XX], mutot[0][YY], mutot[0][ZZ]); } const bool bNeedLongRangeCorrection = (dipole_coeff != 0); if (bNeedLongRangeCorrection && !bHaveChargePerturbed) @@ -159,11 +158,11 @@ void ewald_LRcorrection(const int numAtomsLocal, { for (j = 0; (j < DIM); j++) { - f[i][j] -= dipcorrA[j]*chargeA[i]; + f[i][j] -= dipcorrA[j] * chargeA[i]; } if (chargecorr[0] != 0) { - f[i][ZZ] += chargecorr[0]*chargeA[i]*x[i][ZZ]; + f[i][ZZ] += chargecorr[0] * chargeA[i] * x[i][ZZ]; } } } @@ -173,19 +172,17 @@ void ewald_LRcorrection(const int numAtomsLocal, { for (j = 0; (j < DIM); j++) { - f[i][j] -= L1_q*dipcorrA[j]*chargeA[i] - + lambda_q*dipcorrB[j]*chargeB[i]; + f[i][j] -= L1_q * dipcorrA[j] * chargeA[i] + lambda_q * dipcorrB[j] * chargeB[i]; } if (chargecorr[0] != 0 || chargecorr[1] != 0) { - f[i][ZZ] += (L1_q*chargecorr[0]*chargeA[i] - + lambda_q*chargecorr[1])*x[i][ZZ]; + f[i][ZZ] += (L1_q * chargecorr[0] * chargeA[i] + lambda_q * chargecorr[1]) * x[i][ZZ]; } } } - Vself_q[0] = 0; - Vself_q[1] = 0; + Vself_q[0] = 0; + Vself_q[1] = 0; /* Global corrections only on master process */ if (MASTER(cr) && thread == 0) @@ -200,11 +197,11 @@ void ewald_LRcorrection(const int numAtomsLocal, { if (ir.ewald_geometry == eewg3D) { - Vdipole[q] = dipole_coeff*iprod(mutot[q], mutot[q]); + Vdipole[q] = dipole_coeff * iprod(mutot[q], mutot[q]); } else if (ir.ewald_geometry == eewg3DC) { - Vdipole[q] = dipole_coeff*mutot[q][ZZ]*mutot[q][ZZ]; + Vdipole[q] = dipole_coeff * mutot[q][ZZ] * mutot[q][ZZ]; if (chargecorr[q] != 0) { @@ -214,13 +211,14 @@ void ewald_LRcorrection(const int numAtomsLocal, * We could implement a reduction over threads, * but this case is rarely used. */ - const real *qPtr = (q == 0 ? chargeA : chargeB); + const real* qPtr = (q == 0 ? chargeA : chargeB); real sumQZ2 = 0; for (int i = 0; i < numAtomsLocal; i++) { - sumQZ2 += qPtr[i]*x[i][ZZ]*x[i][ZZ]; + sumQZ2 += qPtr[i] * x[i][ZZ] * x[i][ZZ]; } - Vdipole[q] -= dipole_coeff*fr.qsum[q]*(sumQZ2 + fr.qsum[q]*box[ZZ][ZZ]*box[ZZ][ZZ]/12); + Vdipole[q] -= dipole_coeff * fr.qsum[q] + * (sumQZ2 + fr.qsum[q] * box[ZZ][ZZ] * box[ZZ][ZZ] / 12); } } } @@ -232,25 +230,22 @@ void ewald_LRcorrection(const int numAtomsLocal, } else { - *Vcorr_q = L1_q*(Vdipole[0] - Vself_q[0]) - + lambda_q*(Vdipole[1] - Vself_q[1]) - - Vexcl_q; - *dvdlambda_q += Vdipole[1] - Vself_q[1] - - (Vdipole[0] - Vself_q[0]) - dvdl_excl_q; + *Vcorr_q = L1_q * (Vdipole[0] - Vself_q[0]) + lambda_q * (Vdipole[1] - Vself_q[1]) - Vexcl_q; + *dvdlambda_q += Vdipole[1] - Vself_q[1] - (Vdipole[0] - Vself_q[0]) - dvdl_excl_q; } if (debug) { fprintf(debug, "Long Range corrections for Ewald interactions:\n"); - fprintf(debug, "q2sum = %g, Vself_q=%g\n", - L1_q*fr.q2sum[0] + lambda_q*fr.q2sum[1], L1_q*Vself_q[0] + lambda_q*Vself_q[1]); + fprintf(debug, "q2sum = %g, Vself_q=%g\n", L1_q * fr.q2sum[0] + lambda_q * fr.q2sum[1], + L1_q * Vself_q[0] + lambda_q * Vself_q[1]); fprintf(debug, "Electrostatic Long Range correction: Vexcl=%g\n", Vexcl_q); if (MASTER(cr) && thread == 0) { if (ir.epsilon_surface > 0 || ir.ewald_geometry == eewg3DC) { fprintf(debug, "Total dipole correction: Vdipole=%g\n", - L1_q*Vdipole[0] + lambda_q*Vdipole[1]); + L1_q * Vdipole[0] + lambda_q * Vdipole[1]); } } } diff --git a/src/gromacs/ewald/long_range_correction.h b/src/gromacs/ewald/long_range_correction.h index 0e366a758c..786318dda7 100644 --- a/src/gromacs/ewald/long_range_correction.h +++ b/src/gromacs/ewald/long_range_correction.h @@ -63,20 +63,21 @@ struct t_inputrec; * * Calculate correction for electrostatic surface dipole terms. */ -void -ewald_LRcorrection(int numAtomsLocal, - const t_commrec *cr, - int numThreads, int thread, - const t_forcerec &fr, - const t_inputrec &ir, - const real *chargeA, const real *chargeB, - gmx_bool bHaveChargePerturbed, - const rvec x[], - const matrix box, - const rvec mu_tot[], - rvec *f, - real *Vcorr_q, - real lambda_q, - real *dvdlambda_q); +void ewald_LRcorrection(int numAtomsLocal, + const t_commrec* cr, + int numThreads, + int thread, + const t_forcerec& fr, + const t_inputrec& ir, + const real* chargeA, + const real* chargeB, + gmx_bool bHaveChargePerturbed, + const rvec x[], + const matrix box, + const rvec mu_tot[], + rvec* f, + real* Vcorr_q, + real lambda_q, + real* dvdlambda_q); #endif diff --git a/src/gromacs/ewald/pme.cpp b/src/gromacs/ewald/pme.cpp index 0d7e986893..73323842c5 100644 --- a/src/gromacs/ewald/pme.cpp +++ b/src/gromacs/ewald/pme.cpp @@ -129,9 +129,7 @@ * \c errorReasons why PME on GPU is not supported. * * \returns Whether the lack of errorReasons indicate there is support. */ -static bool -addMessageIfNotSupported(const std::list &errorReasons, - std::string *error) +static bool addMessageIfNotSupported(const std::list& errorReasons, std::string* error) { bool isSupported = errorReasons.empty(); if (!isSupported && error) @@ -152,7 +150,7 @@ addMessageIfNotSupported(const std::list &errorReasons, return isSupported; } -bool pme_gpu_supports_build(std::string *error) +bool pme_gpu_supports_build(std::string* error) { std::list errorReasons; if (GMX_DOUBLE) @@ -166,8 +164,7 @@ bool pme_gpu_supports_build(std::string *error) return addMessageIfNotSupported(errorReasons, error); } -bool pme_gpu_supports_hardware(const gmx_hw_info_t gmx_unused &hwinfo, - std::string *error) +bool pme_gpu_supports_hardware(const gmx_hw_info_t gmx_unused& hwinfo, std::string* error) { std::list errorReasons; @@ -180,7 +177,7 @@ bool pme_gpu_supports_hardware(const gmx_hw_info_t gmx_unused &hwinfo, return addMessageIfNotSupported(errorReasons, error); } -bool pme_gpu_supports_input(const t_inputrec &ir, const gmx_mtop_t &mtop, std::string *error) +bool pme_gpu_supports_input(const t_inputrec& ir, const gmx_mtop_t& mtop, std::string* error) { std::list errorReasons; if (!EEL_PME(ir.coulombtype)) @@ -195,7 +192,8 @@ bool pme_gpu_supports_input(const t_inputrec &ir, const gmx_mtop_t &mtop, std::s { if (gmx_mtop_has_perturbed_charges(mtop)) { - errorReasons.emplace_back("free energy calculations with perturbed charges (multiple grids)"); + errorReasons.emplace_back( + "free energy calculations with perturbed charges (multiple grids)"); } } if (EVDW_PME(ir.vdwtype)) @@ -218,7 +216,7 @@ bool pme_gpu_supports_input(const t_inputrec &ir, const gmx_mtop_t &mtop, std::s * \param[out] error The error message if the input is not supported on GPU. * \returns True if this PME input is possible to run on GPU, false otherwise. */ -static bool pme_gpu_check_restrictions(const gmx_pme_t *pme, std::string *error) +static bool pme_gpu_check_restrictions(const gmx_pme_t* pme, std::string* error) { std::list errorReasons; if (pme->nnodes != 1) @@ -249,7 +247,7 @@ static bool pme_gpu_check_restrictions(const gmx_pme_t *pme, std::string *error) return addMessageIfNotSupported(errorReasons, error); } -PmeRunMode pme_run_mode(const gmx_pme_t *pme) +PmeRunMode pme_run_mode(const gmx_pme_t* pme) { GMX_ASSERT(pme != nullptr, "Expecting valid PME data pointer"); return pme->runMode; @@ -268,7 +266,7 @@ gmx::PinningPolicy pme_get_pinning_policy() const int gmxCacheLineSize = 64; //! Set up coordinate communication -static void setup_coordinate_communication(PmeAtomComm *atc) +static void setup_coordinate_communication(PmeAtomComm* atc) { int nslab, n, i; int fw, bw; @@ -276,7 +274,7 @@ static void setup_coordinate_communication(PmeAtomComm *atc) nslab = atc->nslab; n = 0; - for (i = 1; i <= nslab/2; i++) + for (i = 1; i <= nslab / 2; i++) { fw = (atc->nodeid + i) % nslab; bw = (atc->nodeid - i + nslab) % nslab; @@ -298,11 +296,11 @@ static void setup_coordinate_communication(PmeAtomComm *atc) /*! \brief Round \p n up to the next multiple of \p f */ static int mult_up(int n, int f) { - return ((n + f - 1)/f)*f; + return ((n + f - 1) / f) * f; } /*! \brief Return estimate of the load imbalance from the PME grid not being a good match for the number of PME ranks */ -static double estimate_pme_load_imbalance(struct gmx_pme_t *pme) +static double estimate_pme_load_imbalance(struct gmx_pme_t* pme) { int nma, nmi; double n1, n2, n3; @@ -310,13 +308,13 @@ static double estimate_pme_load_imbalance(struct gmx_pme_t *pme) nma = pme->nnodes_major; nmi = pme->nnodes_minor; - n1 = mult_up(pme->nkx, nma)*mult_up(pme->nky, nmi)*pme->nkz; - n2 = mult_up(pme->nkx, nma)*mult_up(pme->nkz, nmi)*pme->nky; - n3 = mult_up(pme->nky, nma)*mult_up(pme->nkz, nmi)*pme->nkx; + n1 = mult_up(pme->nkx, nma) * mult_up(pme->nky, nmi) * pme->nkz; + n2 = mult_up(pme->nkx, nma) * mult_up(pme->nkz, nmi) * pme->nky; + n3 = mult_up(pme->nky, nma) * mult_up(pme->nkz, nmi) * pme->nkx; /* pme_solve is roughly double the cost of an fft */ - return (n1 + n2 + 3*n3)/static_cast(6*pme->nkx*pme->nky*pme->nkz); + return (n1 + n2 + 3 * n3) / static_cast(6 * pme->nkx * pme->nky * pme->nkz); } #ifndef DOXYGEN @@ -335,10 +333,10 @@ PmeAtomComm::PmeAtomComm(MPI_Comm PmeMpiCommunicator, if (PmeMpiCommunicator != MPI_COMM_NULL) { mpi_comm = PmeMpiCommunicator; -#if GMX_MPI +# if GMX_MPI MPI_Comm_size(mpi_comm, &nslab); MPI_Comm_rank(mpi_comm, &nodeid); -#endif +# endif } if (debug) { @@ -351,7 +349,7 @@ PmeAtomComm::PmeAtomComm(MPI_Comm PmeMpiCommunicator, setup_coordinate_communication(this); count_thread.resize(nthread); - for (auto &countThread : count_thread) + for (auto& countThread : count_thread) { countThread.resize(nslab); } @@ -361,16 +359,16 @@ PmeAtomComm::PmeAtomComm(MPI_Comm PmeMpiCommunicator, { threadMap.resize(nthread); -#pragma omp parallel for num_threads(nthread) schedule(static) +# pragma omp parallel for num_threads(nthread) schedule(static) for (int thread = 0; thread < nthread; thread++) { try { /* Allocate buffer with padding to avoid cache polution */ - threadMap[thread].nBuffer.resize(nthread + 2*gmxCacheLineSize); + threadMap[thread].nBuffer.resize(nthread + 2 * gmxCacheLineSize); threadMap[thread].n = threadMap[thread].nBuffer.data() + gmxCacheLineSize; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } } @@ -378,16 +376,9 @@ PmeAtomComm::PmeAtomComm(MPI_Comm PmeMpiCommunicator, #endif // !DOXYGEN /*! \brief Initialize data structure for communication */ -static void -init_overlap_comm(pme_overlap_t * ol, - int norder, - MPI_Comm comm, - int nnodes, - int nodeid, - int ndata, - int commplainsize) +static void init_overlap_comm(pme_overlap_t* ol, int norder, MPI_Comm comm, int nnodes, int nodeid, int ndata, int commplainsize) { - gmx_bool bCont; + gmx_bool bCont; ol->mpi_comm = comm; ol->nnodes = nnodes; @@ -436,42 +427,41 @@ init_overlap_comm(pme_overlap_t * ol, bCont = FALSE; for (int i = 0; i < nnodes; i++) { - if ((i + testRankCount < nnodes && ol->s2g1[i] > ol->s2g0[i + testRankCount]) || - (i + testRankCount >= nnodes && ol->s2g1[i] > ol->s2g0[i + testRankCount - nnodes] + ndata)) + if ((i + testRankCount < nnodes && ol->s2g1[i] > ol->s2g0[i + testRankCount]) + || (i + testRankCount >= nnodes && ol->s2g1[i] > ol->s2g0[i + testRankCount - nnodes] + ndata)) { bCont = TRUE; } } - } - while (bCont && testRankCount < nnodes); + } while (bCont && testRankCount < nnodes); ol->comm_data.resize(testRankCount - 1); ol->send_size = 0; for (size_t b = 0; b < ol->comm_data.size(); b++) { - pme_grid_comm_t *pgc = &ol->comm_data[b]; + pme_grid_comm_t* pgc = &ol->comm_data[b]; /* Send */ - pgc->send_id = (ol->nodeid + (b + 1)) % ol->nnodes; + pgc->send_id = (ol->nodeid + (b + 1)) % ol->nnodes; int fft_start = ol->s2g0[pgc->send_id]; int fft_end = ol->s2g0[pgc->send_id + 1]; if (pgc->send_id < nodeid) { fft_start += ndata; - fft_end += ndata; + fft_end += ndata; } int send_index1 = ol->s2g1[nodeid]; send_index1 = std::min(send_index1, fft_end); pgc->send_index0 = fft_start; pgc->send_nindex = std::max(0, send_index1 - pgc->send_index0); - ol->send_size += pgc->send_nindex; + ol->send_size += pgc->send_nindex; /* We always start receiving to the first index of our slab */ - pgc->recv_id = (ol->nodeid - (b + 1) + ol->nnodes) % ol->nnodes; - fft_start = ol->s2g0[ol->nodeid]; - fft_end = ol->s2g0[ol->nodeid + 1]; - int recv_index1 = ol->s2g1[pgc->recv_id]; + pgc->recv_id = (ol->nodeid - (b + 1) + ol->nnodes) % ol->nnodes; + fft_start = ol->s2g0[ol->nodeid]; + fft_end = ol->s2g0[ol->nodeid + 1]; + int recv_index1 = ol->s2g1[pgc->recv_id]; if (pgc->recv_id > nodeid) { recv_index1 -= ndata; @@ -483,12 +473,11 @@ init_overlap_comm(pme_overlap_t * ol, #if GMX_MPI /* Communicate the buffer sizes to receive */ - MPI_Status stat; + MPI_Status stat; for (size_t b = 0; b < ol->comm_data.size(); b++) { - MPI_Sendrecv(&ol->send_size, 1, MPI_INT, ol->comm_data[b].send_id, b, - &ol->comm_data[b].recv_size, 1, MPI_INT, ol->comm_data[b].recv_id, b, - ol->mpi_comm, &stat); + MPI_Sendrecv(&ol->send_size, 1, MPI_INT, ol->comm_data[b].send_id, b, &ol->comm_data[b].recv_size, + 1, MPI_INT, ol->comm_data[b].recv_id, b, ol->mpi_comm, &stat); } #endif @@ -506,7 +495,7 @@ int minimalPmeGridSize(int pmeOrder) * But we use the maximum for simplicity since in practice there is not * much performance difference between pme_order and 2*(pme_order -1). */ - int minimalSize = 2*(pmeOrder - 1); + int minimalSize = 2 * (pmeOrder - 1); GMX_RELEASE_ASSERT(pmeOrder >= 3, "pmeOrder has to be >= 3"); GMX_RELEASE_ASSERT(minimalSize >= pmeOrder + 1, "The grid size should be >= pmeOrder + 1"); @@ -514,11 +503,7 @@ int minimalPmeGridSize(int pmeOrder) return minimalSize; } -bool gmx_pme_check_restrictions(int pme_order, - int nkx, int nky, int nkz, - int numPmeDomainsAlongX, - bool useThreads, - bool errorsAreFatal) +bool gmx_pme_check_restrictions(int pme_order, int nkx, int nky, int nkz, int numPmeDomainsAlongX, bool useThreads, bool errorsAreFatal) { if (pme_order > PME_ORDER_MAX) { @@ -528,38 +513,40 @@ bool gmx_pme_check_restrictions(int pme_order, } std::string message = gmx::formatString( - "pme_order (%d) is larger than the maximum allowed value (%d). Modify and recompile the code if you really need such a high order.", - pme_order, PME_ORDER_MAX); + "pme_order (%d) is larger than the maximum allowed value (%d). Modify and " + "recompile the code if you really need such a high order.", + pme_order, PME_ORDER_MAX); GMX_THROW(gmx::InconsistentInputError(message)); } const int minGridSize = minimalPmeGridSize(pme_order); - if (nkx < minGridSize || - nky < minGridSize || - nkz < minGridSize) + if (nkx < minGridSize || nky < minGridSize || nkz < minGridSize) { if (!errorsAreFatal) { return false; } - std::string message = gmx::formatString( - "The PME grid sizes need to be >= 2*(pme_order-1) (%d)", - minGridSize); + std::string message = + gmx::formatString("The PME grid sizes need to be >= 2*(pme_order-1) (%d)", minGridSize); GMX_THROW(gmx::InconsistentInputError(message)); } /* Check for a limitation of the (current) sum_fftgrid_dd code. * We only allow multiple communication pulses in dim 1, not in dim 0. */ - if (useThreads && (nkx < numPmeDomainsAlongX*pme_order && - nkx != numPmeDomainsAlongX*(pme_order - 1))) + if (useThreads + && (nkx < numPmeDomainsAlongX * pme_order && nkx != numPmeDomainsAlongX * (pme_order - 1))) { if (!errorsAreFatal) { return false; } - gmx_fatal(FARGS, "The number of PME grid lines per rank along x is %g. But when using OpenMP threads, the number of grid lines per rank along x should be >= pme_order (%d) or = pmeorder-1. To resolve this issue, use fewer ranks along x (and possibly more along y and/or z) by specifying -dd manually.", - nkx/static_cast(numPmeDomainsAlongX), pme_order); + gmx_fatal(FARGS, + "The number of PME grid lines per rank along x is %g. But when using OpenMP " + "threads, the number of grid lines per rank along x should be >= pme_order (%d) " + "or = pmeorder-1. To resolve this issue, use fewer ranks along x (and possibly " + "more along y and/or z) by specifying -dd manually.", + nkx / static_cast(numPmeDomainsAlongX), pme_order); } return true; @@ -568,12 +555,12 @@ bool gmx_pme_check_restrictions(int pme_order, /*! \brief Round \p enumerator */ static int div_round_up(int enumerator, int denominator) { - return (enumerator + denominator - 1)/denominator; + return (enumerator + denominator - 1) / denominator; } -gmx_pme_t *gmx_pme_init(const t_commrec *cr, - const NumPmeDomains &numPmeDomains, - const t_inputrec *ir, +gmx_pme_t* gmx_pme_init(const t_commrec* cr, + const NumPmeDomains& numPmeDomains, + const t_inputrec* ir, gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj, gmx_bool bReproducible, @@ -581,13 +568,13 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, real ewaldcoeff_lj, int nthread, PmeRunMode runMode, - PmeGpu *pmeGpu, - const gmx_device_info_t *gpuInfo, + PmeGpu* pmeGpu, + const gmx_device_info_t* gpuInfo, PmeGpuProgramHandle pmeGpuProgram, - const gmx::MDLogger & /*mdlog*/) + const gmx::MDLogger& /*mdlog*/) { - int use_threads, sum_use_threads, i; - ivec ndata; + int use_threads, sum_use_threads, i; + ivec ndata; if (debug) { @@ -596,18 +583,18 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, gmx::unique_cptr pme(new gmx_pme_t()); - pme->sum_qgrid_tmp = nullptr; - pme->sum_qgrid_dd_tmp = nullptr; + pme->sum_qgrid_tmp = nullptr; + pme->sum_qgrid_dd_tmp = nullptr; - pme->buf_nalloc = 0; + pme->buf_nalloc = 0; - pme->nnodes = 1; - pme->bPPnode = TRUE; + pme->nnodes = 1; + pme->bPPnode = TRUE; - pme->nnodes_major = numPmeDomains.x; - pme->nnodes_minor = numPmeDomains.y; + pme->nnodes_major = numPmeDomains.x; + pme->nnodes_minor = numPmeDomains.y; - if (numPmeDomains.x*numPmeDomains.y > 1) + if (numPmeDomains.x * numPmeDomains.y > 1) { pme->mpi_comm = cr->mpi_comm_mygroup; @@ -615,7 +602,7 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, MPI_Comm_rank(pme->mpi_comm, &pme->nodeid); MPI_Comm_size(pme->mpi_comm, &pme->nnodes); #endif - if (pme->nnodes != numPmeDomains.x*numPmeDomains.y) + if (pme->nnodes != numPmeDomains.x * numPmeDomains.y) { gmx_incons("PME rank count mismatch"); } @@ -642,7 +629,6 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, pme->ndecompdim = 1; pme->nodeid_major = pme->nodeid; pme->nodeid_minor = 0; - } else if (numPmeDomains.x == 1) { @@ -656,15 +642,17 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, { if (pme->nnodes % numPmeDomains.x != 0) { - gmx_incons("For 2D PME decomposition, #PME ranks must be divisible by the number of domains along x"); + gmx_incons( + "For 2D PME decomposition, #PME ranks must be divisible by the number of " + "domains along x"); } pme->ndecompdim = 2; #if GMX_MPI - MPI_Comm_split(pme->mpi_comm, pme->nodeid % numPmeDomains.y, - pme->nodeid, &pme->mpi_comm_d[0]); /* My communicator along major dimension */ - MPI_Comm_split(pme->mpi_comm, pme->nodeid/numPmeDomains.y, - pme->nodeid, &pme->mpi_comm_d[1]); /* My communicator along minor dimension */ + MPI_Comm_split(pme->mpi_comm, pme->nodeid % numPmeDomains.y, pme->nodeid, + &pme->mpi_comm_d[0]); /* My communicator along major dimension */ + MPI_Comm_split(pme->mpi_comm, pme->nodeid / numPmeDomains.y, pme->nodeid, + &pme->mpi_comm_d[1]); /* My communicator along minor dimension */ MPI_Comm_rank(pme->mpi_comm_d[0], &pme->nodeid_major); MPI_Comm_size(pme->mpi_comm_d[0], &pme->nnodes_major); @@ -675,8 +663,7 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, } // cr is always initialized if there is a a PP rank, so we can safely assume // that when it is not, like in ewald tests, we not on a PP rank. - pme->bPPnode = ((cr != nullptr && cr->duty != 0) && - thisRankHasDuty(cr, DUTY_PP)); + pme->bPPnode = ((cr != nullptr && cr->duty != 0) && thisRankHasDuty(cr, DUTY_PP)); pme->nthread = nthread; @@ -685,8 +672,7 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, #if GMX_MPI if (pme->nnodes > 1) { - MPI_Allreduce(&use_threads, &sum_use_threads, 1, MPI_INT, - MPI_SUM, pme->mpi_comm); + MPI_Allreduce(&use_threads, &sum_use_threads, 1, MPI_INT, MPI_SUM, pme->mpi_comm); } else #endif @@ -722,7 +708,7 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, pme->ewaldcoeff_lj = ewaldcoeff_lj; /* Always constant electrostatics coefficients */ - pme->epsilon_r = ir->epsilon_r; + pme->epsilon_r = ir->epsilon_r; /* Always constant LJ coefficients */ pme->ljpme_combination_rule = ir->ljpme_combination_rule; @@ -733,11 +719,8 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, pme->boxScaler = new EwaldBoxZScaler(*ir); /* If we violate restrictions, generate a fatal error here */ - gmx_pme_check_restrictions(pme->pme_order, - pme->nkx, pme->nky, pme->nkz, - pme->nnodes_major, - pme->bUseThreads, - true); + gmx_pme_check_restrictions(pme->pme_order, pme->nkx, pme->nky, pme->nkz, pme->nnodes_major, + pme->bUseThreads, true); if (pme->nnodes > 1) { @@ -761,11 +744,12 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, "\n" "NOTE: The load imbalance in PME FFT and solve is %d%%.\n" " For optimal PME load balancing\n" - " PME grid_x (%d) and grid_y (%d) should be divisible by #PME_ranks_x (%d)\n" - " and PME grid_y (%d) and grid_z (%d) should be divisible by #PME_ranks_y (%d)\n" + " PME grid_x (%d) and grid_y (%d) should be divisible by #PME_ranks_x " + "(%d)\n" + " and PME grid_y (%d) and grid_z (%d) should be divisible by #PME_ranks_y " + "(%d)\n" "\n", - gmx::roundToInt((imbal-1)*100), - pme->nkx, pme->nky, pme->nnodes_major, + gmx::roundToInt((imbal - 1) * 100), pme->nkx, pme->nky, pme->nnodes_major, pme->nky, pme->nkz, pme->nnodes_minor); } } @@ -775,28 +759,27 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, * y is always copied through a buffer: we don't need padding in z, * but we do need the overlap in x because of the communication order. */ - init_overlap_comm(&pme->overlap[0], pme->pme_order, - pme->mpi_comm_d[0], - pme->nnodes_major, pme->nodeid_major, - pme->nkx, - (div_round_up(pme->nky, pme->nnodes_minor)+pme->pme_order)*(pme->nkz+pme->pme_order-1)); + init_overlap_comm(&pme->overlap[0], pme->pme_order, pme->mpi_comm_d[0], pme->nnodes_major, + pme->nodeid_major, pme->nkx, + (div_round_up(pme->nky, pme->nnodes_minor) + pme->pme_order) + * (pme->nkz + pme->pme_order - 1)); /* Along overlap dim 1 we can send in multiple pulses in sum_fftgrid_dd. * We do this with an offset buffer of equal size, so we need to allocate * extra for the offset. That's what the (+1)*pme->nkz is for. */ - init_overlap_comm(&pme->overlap[1], pme->pme_order, - pme->mpi_comm_d[1], - pme->nnodes_minor, pme->nodeid_minor, - pme->nky, - (div_round_up(pme->nkx, pme->nnodes_major)+pme->pme_order+1)*pme->nkz); + init_overlap_comm(&pme->overlap[1], pme->pme_order, pme->mpi_comm_d[1], pme->nnodes_minor, + pme->nodeid_minor, pme->nky, + (div_round_up(pme->nkx, pme->nnodes_major) + pme->pme_order + 1) * pme->nkz); /* Double-check for a limitation of the (current) sum_fftgrid_dd code. * Note that gmx_pme_check_restrictions checked for this already. */ if (pme->bUseThreads && (pme->overlap[0].comm_data.size() > 1)) { - gmx_incons("More than one communication pulse required for grid overlap communication along the major dimension while using threads"); + gmx_incons( + "More than one communication pulse required for grid overlap communication along " + "the major dimension while using threads"); } snew(pme->bsp_mod[XX], pme->nkx); @@ -809,10 +792,8 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, /* The required size of the interpolation grid, including overlap. * The allocated size (pmegrid_n?) might be slightly larger. */ - pme->pmegrid_nx = pme->overlap[0].s2g1[pme->nodeid_major] - - pme->overlap[0].s2g0[pme->nodeid_major]; - pme->pmegrid_ny = pme->overlap[1].s2g1[pme->nodeid_minor] - - pme->overlap[1].s2g0[pme->nodeid_minor]; + pme->pmegrid_nx = pme->overlap[0].s2g1[pme->nodeid_major] - pme->overlap[0].s2g0[pme->nodeid_major]; + pme->pmegrid_ny = pme->overlap[1].s2g1[pme->nodeid_minor] - pme->overlap[1].s2g0[pme->nodeid_minor]; pme->pmegrid_nz_base = pme->nkz; pme->pmegrid_nz = pme->pmegrid_nz_base + pme->pme_order - 1; set_grid_alignment(&pme->pmegrid_nz, pme->pme_order); @@ -820,24 +801,18 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, pme->pmegrid_start_iy = pme->overlap[1].s2g0[pme->nodeid_minor]; pme->pmegrid_start_iz = 0; - make_gridindex_to_localindex(pme->nkx, - pme->pmegrid_start_ix, - pme->pmegrid_nx - (pme->pme_order-1), - &pme->nnx, &pme->fshx); - make_gridindex_to_localindex(pme->nky, - pme->pmegrid_start_iy, - pme->pmegrid_ny - (pme->pme_order-1), - &pme->nny, &pme->fshy); - make_gridindex_to_localindex(pme->nkz, - pme->pmegrid_start_iz, - pme->pmegrid_nz_base, - &pme->nnz, &pme->fshz); + make_gridindex_to_localindex(pme->nkx, pme->pmegrid_start_ix, + pme->pmegrid_nx - (pme->pme_order - 1), &pme->nnx, &pme->fshx); + make_gridindex_to_localindex(pme->nky, pme->pmegrid_start_iy, + pme->pmegrid_ny - (pme->pme_order - 1), &pme->nny, &pme->fshy); + make_gridindex_to_localindex(pme->nkz, pme->pmegrid_start_iz, pme->pmegrid_nz_base, &pme->nnz, + &pme->fshz); pme->spline_work = make_pme_spline_work(pme->pme_order); - ndata[0] = pme->nkx; - ndata[1] = pme->nky; - ndata[2] = pme->nkz; + ndata[0] = pme->nkx; + ndata[1] = pme->nky; + ndata[2] = pme->nkz; /* It doesn't matter if we allocate too many grids here, * we only allocate and use the ones we need. */ @@ -855,27 +830,22 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, for (i = 0; i < pme->ngrids; ++i) { - if ((i < DO_Q && pme->doCoulomb && (i == 0 || - bFreeEnergy_q)) || - (i >= DO_Q && pme->doLJ && (i == 2 || - bFreeEnergy_lj || - ir->ljpme_combination_rule == eljpmeLB))) + if ((i < DO_Q && pme->doCoulomb && (i == 0 || bFreeEnergy_q)) + || (i >= DO_Q && pme->doLJ + && (i == 2 || bFreeEnergy_lj || ir->ljpme_combination_rule == eljpmeLB))) { - pmegrids_init(&pme->pmegrid[i], - pme->pmegrid_nx, pme->pmegrid_ny, pme->pmegrid_nz, - pme->pmegrid_nz_base, - pme->pme_order, - pme->bUseThreads, - pme->nthread, - pme->overlap[0].s2g1[pme->nodeid_major]-pme->overlap[0].s2g0[pme->nodeid_major+1], - pme->overlap[1].s2g1[pme->nodeid_minor]-pme->overlap[1].s2g0[pme->nodeid_minor+1]); + pmegrids_init(&pme->pmegrid[i], pme->pmegrid_nx, pme->pmegrid_ny, pme->pmegrid_nz, + pme->pmegrid_nz_base, pme->pme_order, pme->bUseThreads, pme->nthread, + pme->overlap[0].s2g1[pme->nodeid_major] + - pme->overlap[0].s2g0[pme->nodeid_major + 1], + pme->overlap[1].s2g1[pme->nodeid_minor] + - pme->overlap[1].s2g0[pme->nodeid_minor + 1]); /* This routine will allocate the grid data to fit the FFTs */ - const auto allocateRealGridForGpu = (pme->runMode == PmeRunMode::Mixed) ? gmx::PinningPolicy::PinnedIfSupported : gmx::PinningPolicy::CannotBePinned; - gmx_parallel_3dfft_init(&pme->pfft_setup[i], ndata, - &pme->fftgrid[i], &pme->cfftgrid[i], - pme->mpi_comm_d, - bReproducible, pme->nthread, allocateRealGridForGpu); - + const auto allocateRealGridForGpu = (pme->runMode == PmeRunMode::Mixed) + ? gmx::PinningPolicy::PinnedIfSupported + : gmx::PinningPolicy::CannotBePinned; + gmx_parallel_3dfft_init(&pme->pfft_setup[i], ndata, &pme->fftgrid[i], &pme->cfftgrid[i], + pme->mpi_comm_d, bReproducible, pme->nthread, allocateRealGridForGpu); } } @@ -894,16 +864,12 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, const int firstDimIndex = (numPmeDomains.x > 1 ? 0 : 1); MPI_Comm mpiCommFirstDim = (pme->nnodes > 1 ? pme->mpi_comm_d[firstDimIndex] : MPI_COMM_NULL); bool doSpread = true; - pme->atc.emplace_back(mpiCommFirstDim, pme->nthread, - pme->pme_order, - firstDimIndex, doSpread); + pme->atc.emplace_back(mpiCommFirstDim, pme->nthread, pme->pme_order, firstDimIndex, doSpread); if (pme->ndecompdim >= 2) { const int secondDimIndex = 1; doSpread = false; - pme->atc.emplace_back(pme->mpi_comm_d[1], pme->nthread, - pme->pme_order, - secondDimIndex, doSpread); + pme->atc.emplace_back(pme->mpi_comm_d[1], pme->nthread, pme->pme_order, secondDimIndex, doSpread); } if (pme_gpu_active(pme.get())) @@ -928,10 +894,10 @@ gmx_pme_t *gmx_pme_init(const t_commrec *cr, return pme.release(); } -void gmx_pme_reinit(struct gmx_pme_t **pmedata, - const t_commrec *cr, - struct gmx_pme_t * pme_src, - const t_inputrec * ir, +void gmx_pme_reinit(struct gmx_pme_t** pmedata, + const t_commrec* cr, + struct gmx_pme_t* pme_src, + const t_inputrec* ir, const ivec grid_size, real ewaldcoeff_q, real ewaldcoeff_lj) @@ -959,9 +925,9 @@ void gmx_pme_reinit(struct gmx_pme_t **pmedata, // TODO: when PME is an object, it should take reference to mdlog on construction and save it. GMX_ASSERT(pmedata, "Invalid PME pointer"); NumPmeDomains numPmeDomains = { pme_src->nnodes_major, pme_src->nnodes_minor }; - *pmedata = gmx_pme_init(cr, numPmeDomains, - &irc, pme_src->bFEP_q, pme_src->bFEP_lj, FALSE, ewaldcoeff_q, ewaldcoeff_lj, - pme_src->nthread, pme_src->runMode, pme_src->gpu, nullptr, nullptr, dummyLogger); + *pmedata = gmx_pme_init(cr, numPmeDomains, &irc, pme_src->bFEP_q, pme_src->bFEP_lj, FALSE, + ewaldcoeff_q, ewaldcoeff_lj, pme_src->nthread, pme_src->runMode, + pme_src->gpu, nullptr, nullptr, dummyLogger); /* When running PME on the CPU not using domain decomposition, * the atom data is allocated once only in gmx_pme_(re)init(). */ @@ -969,21 +935,18 @@ void gmx_pme_reinit(struct gmx_pme_t **pmedata, { gmx_pme_reinit_atoms(*pmedata, pme_src->atc[0].numAtoms(), nullptr); } - //TODO this is mostly passing around current values + // TODO this is mostly passing around current values } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR /* We can easily reuse the allocated pme grids in pme_src */ reuse_pmegrids(&pme_src->pmegrid[PME_GRID_QA], &(*pmedata)->pmegrid[PME_GRID_QA]); /* We would like to reuse the fft grids, but that's harder */ } -void gmx_pme_calc_energy(gmx_pme_t *pme, - gmx::ArrayRef x, - gmx::ArrayRef q, - real *V) +void gmx_pme_calc_energy(gmx_pme_t* pme, gmx::ArrayRef x, gmx::ArrayRef q, real* V) { - pmegrids_t *grid; + pmegrids_t* grid; if (pme->nnodes > 1) { @@ -996,10 +959,9 @@ void gmx_pme_calc_energy(gmx_pme_t *pme, if (!pme->atc_energy) { - pme->atc_energy = std::make_unique(MPI_COMM_NULL, 1, pme->pme_order, - 0, true); + pme->atc_energy = std::make_unique(MPI_COMM_NULL, 1, pme->pme_order, 0, true); } - PmeAtomComm *atc = pme->atc_energy.get(); + PmeAtomComm* atc = pme->atc_energy.get(); atc->setNumAtoms(x.ssize()); atc->x = x; atc->coefficient = q; @@ -1014,24 +976,19 @@ void gmx_pme_calc_energy(gmx_pme_t *pme, } /*! \brief Calculate initial Lorentz-Berthelot coefficients for LJ-PME */ -static void -calc_initial_lb_coeffs(gmx::ArrayRef coefficient, - const real *local_c6, - const real *local_sigma) +static void calc_initial_lb_coeffs(gmx::ArrayRef coefficient, const real* local_c6, const real* local_sigma) { for (gmx::index i = 0; i < coefficient.ssize(); ++i) { real sigma4 = local_sigma[i]; - sigma4 = sigma4*sigma4; - sigma4 = sigma4*sigma4; + sigma4 = sigma4 * sigma4; + sigma4 = sigma4 * sigma4; coefficient[i] = local_c6[i] / sigma4; } } /*! \brief Calculate next Lorentz-Berthelot coefficients for LJ-PME */ -static void -calc_next_lb_coeffs(gmx::ArrayRef coefficient, - const real *local_sigma) +static void calc_next_lb_coeffs(gmx::ArrayRef coefficient, const real* local_sigma) { for (gmx::index i = 0; i < coefficient.ssize(); ++i) { @@ -1039,46 +996,57 @@ calc_next_lb_coeffs(gmx::ArrayRef coefficient, } } -int gmx_pme_do(struct gmx_pme_t *pme, +int gmx_pme_do(struct gmx_pme_t* pme, gmx::ArrayRef coordinates, gmx::ArrayRef forces, - real chargeA[], real chargeB[], - real c6A[], real c6B[], - real sigmaA[], real sigmaB[], - const matrix box, const t_commrec *cr, - int maxshift_x, int maxshift_y, - t_nrnb *nrnb, gmx_wallcycle *wcycle, - matrix vir_q, matrix vir_lj, - real *energy_q, real *energy_lj, - real lambda_q, real lambda_lj, - real *dvdlambda_q, real *dvdlambda_lj, - int flags) + real chargeA[], + real chargeB[], + real c6A[], + real c6B[], + real sigmaA[], + real sigmaB[], + const matrix box, + const t_commrec* cr, + int maxshift_x, + int maxshift_y, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + matrix vir_q, + matrix vir_lj, + real* energy_q, + real* energy_lj, + real lambda_q, + real lambda_lj, + real* dvdlambda_q, + real* dvdlambda_lj, + int flags) { - GMX_ASSERT(pme->runMode == PmeRunMode::CPU, "gmx_pme_do should not be called on the GPU PME run."); + GMX_ASSERT(pme->runMode == PmeRunMode::CPU, + "gmx_pme_do should not be called on the GPU PME run."); int d, npme, grid_index, max_grid_index; - PmeAtomComm &atc = pme->atc[0]; - pmegrids_t *pmegrid = nullptr; - real *grid = nullptr; - real *coefficient = nullptr; + PmeAtomComm& atc = pme->atc[0]; + pmegrids_t* pmegrid = nullptr; + real* grid = nullptr; + real* coefficient = nullptr; PmeOutput output[2]; // The second is used for the B state with FEP real scale, lambda; gmx_bool bClearF; gmx_parallel_3dfft_t pfft_setup; - real * fftgrid; - t_complex * cfftgrid; + real* fftgrid; + t_complex* cfftgrid; int thread; gmx_bool bFirst, bDoSplines; int fep_state; - int fep_states_lj = pme->bFEP_lj ? 2 : 1; - const gmx_bool bCalcEnerVir = (flags & GMX_PME_CALC_ENER_VIR) != 0; - const gmx_bool bBackFFT = (flags & (GMX_PME_CALC_F | GMX_PME_CALC_POT)) != 0; - const gmx_bool bCalcF = (flags & GMX_PME_CALC_F) != 0; + int fep_states_lj = pme->bFEP_lj ? 2 : 1; + const gmx_bool bCalcEnerVir = (flags & GMX_PME_CALC_ENER_VIR) != 0; + const gmx_bool bBackFFT = (flags & (GMX_PME_CALC_F | GMX_PME_CALC_POT)) != 0; + const gmx_bool bCalcF = (flags & GMX_PME_CALC_F) != 0; /* We could be passing lambda!=1 while no q or LJ is actually perturbed */ if (!pme->bFEP_q) { - lambda_q = 1; + lambda_q = 1; } if (!pme->bFEP_lj) { @@ -1091,16 +1059,17 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (pme->nnodes > 1) { atc.pd.resize(coordinates.ssize()); - for (int d = pme->ndecompdim-1; d >= 0; d--) + for (int d = pme->ndecompdim - 1; d >= 0; d--) { - PmeAtomComm &atc = pme->atc[d]; - atc.maxshift = (atc.dimind == 0 ? maxshift_x : maxshift_y); + PmeAtomComm& atc = pme->atc[d]; + atc.maxshift = (atc.dimind == 0 ? maxshift_x : maxshift_y); } } else { GMX_ASSERT(coordinates.ssize() == atc.numAtoms(), "We expect atc.numAtoms() coordinates"); - GMX_ASSERT(forces.ssize() >= atc.numAtoms(), "We need a force buffer with at least atc.numAtoms() elements"); + GMX_ASSERT(forces.ssize() >= atc.numAtoms(), + "We need a force buffer with at least atc.numAtoms() elements"); atc.x = coordinates; atc.f = forces; @@ -1140,10 +1109,8 @@ int gmx_pme_do(struct gmx_pme_t *pme, * If grid_index < 2 we should be doing electrostatic PME * If grid_index >= 2 we should be doing LJ-PME */ - if ((grid_index < DO_Q && (!pme->doCoulomb || - (grid_index == 1 && !pme->bFEP_q))) || - (grid_index >= DO_Q && (!pme->doLJ || - (grid_index == 3 && !pme->bFEP_lj)))) + if ((grid_index < DO_Q && (!pme->doCoulomb || (grid_index == 1 && !pme->bFEP_q))) + || (grid_index >= DO_Q && (!pme->doLJ || (grid_index == 3 && !pme->bFEP_lj)))) { continue; } @@ -1164,8 +1131,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (debug) { - fprintf(debug, "PME: number of ranks = %d, rank = %d\n", - cr->nnodes, cr->nodeid); + fprintf(debug, "PME: number of ranks = %d, rank = %d\n", cr->nnodes, cr->nodeid); fprintf(debug, "Grid = %p\n", static_cast(grid)); if (grid == nullptr) { @@ -1187,8 +1153,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (debug) { - fprintf(debug, "Rank= %6d, pme local particles=%6d\n", - cr->nodeid, atc.numAtoms()); + fprintf(debug, "Rank= %6d, pme local particles=%6d\n", cr->nodeid, atc.numAtoms()); } if (flags & GMX_PME_SPREAD) @@ -1200,10 +1165,10 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (bFirst) { - inc_nrnb(nrnb, eNR_WEIGHTS, DIM*atc.numAtoms()); + inc_nrnb(nrnb, eNR_WEIGHTS, DIM * atc.numAtoms()); } inc_nrnb(nrnb, eNR_SPREADBSP, - pme->pme_order*pme->pme_order*pme->pme_order*atc.numAtoms()); + pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms()); if (!pme->bUseThreads) { @@ -1242,8 +1207,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, { wallcycle_start(wcycle, ewcPME_FFT); } - gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_REAL_TO_COMPLEX, - thread, wcycle); + gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_REAL_TO_COMPLEX, thread, wcycle); if (thread == 0) { wallcycle_stop(wcycle, ewcPME_FFT); @@ -1256,19 +1220,16 @@ int gmx_pme_do(struct gmx_pme_t *pme, } if (grid_index < DO_Q) { - loop_count = - solve_pme_yzx(pme, cfftgrid, - scaledBox[XX][XX]*scaledBox[YY][YY]*scaledBox[ZZ][ZZ], - bCalcEnerVir, - pme->nthread, thread); + loop_count = solve_pme_yzx( + pme, cfftgrid, scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ], + bCalcEnerVir, pme->nthread, thread); } else { - loop_count = - solve_pme_lj_yzx(pme, &cfftgrid, FALSE, - scaledBox[XX][XX]*scaledBox[YY][YY]*scaledBox[ZZ][ZZ], - bCalcEnerVir, - pme->nthread, thread); + loop_count = solve_pme_lj_yzx( + pme, &cfftgrid, FALSE, + scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ], + bCalcEnerVir, pme->nthread, thread); } if (thread == 0) @@ -1285,8 +1246,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, { wallcycle_start(wcycle, ewcPME_FFT); } - gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_COMPLEX_TO_REAL, - thread, wcycle); + gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_COMPLEX_TO_REAL, thread, wcycle); if (thread == 0) { wallcycle_stop(wcycle, ewcPME_FFT); @@ -1294,9 +1254,9 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (pme->nodeid == 0) { - real ntot = pme->nkx*pme->nky*pme->nkz; - npme = static_cast(ntot*std::log(ntot)/std::log(2.0)); - inc_nrnb(nrnb, eNR_FFT, 2*npme); + real ntot = pme->nkx * pme->nky * pme->nkz; + npme = static_cast(ntot * std::log(ntot) / std::log(2.0)); + inc_nrnb(nrnb, eNR_FFT, 2 * npme); } /* Note: this wallcycle region is closed below @@ -1307,7 +1267,8 @@ int gmx_pme_do(struct gmx_pme_t *pme, copy_fftgrid_to_pmegrid(pme, fftgrid, grid, grid_index, pme->nthread, thread); } - } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + } + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* End of thread parallel section. * With MPI we have to synchronize here before gmx_sum_qgrid_dd. @@ -1340,16 +1301,15 @@ int gmx_pme_do(struct gmx_pme_t *pme, { try { - gather_f_bsplines(pme, grid, bClearF, &atc, - &atc.spline[thread], - pme->bFEP ? (grid_index % 2 == 0 ? 1.0-lambda : lambda) : 1.0); + gather_f_bsplines(pme, grid, bClearF, &atc, &atc.spline[thread], + pme->bFEP ? (grid_index % 2 == 0 ? 1.0 - lambda : lambda) : 1.0); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } inc_nrnb(nrnb, eNR_GATHERFBSP, - pme->pme_order*pme->pme_order*pme->pme_order*atc.numAtoms()); + pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms()); /* Note: this wallcycle region is opened above inside an OpenMP region, so take care if refactoring code here. */ wallcycle_stop(wcycle, ewcPME_GATHER); @@ -1380,7 +1340,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, /* Loop over A- and B-state if we are doing FEP */ for (fep_state = 0; fep_state < fep_states_lj; ++fep_state) { - real *local_c6 = nullptr, *local_sigma = nullptr, *RedistC6 = nullptr, *RedistSigma = nullptr; + real *local_c6 = nullptr, *local_sigma = nullptr, *RedistC6 = nullptr, *RedistSigma = nullptr; gmx::ArrayRef coefficientBuffer; if (pme->nnodes == 1) { @@ -1389,15 +1349,14 @@ int gmx_pme_do(struct gmx_pme_t *pme, switch (fep_state) { case 0: - local_c6 = c6A; - local_sigma = sigmaA; + local_c6 = c6A; + local_sigma = sigmaA; break; case 1: - local_c6 = c6B; - local_sigma = sigmaB; + local_c6 = c6B; + local_sigma = sigmaB; break; - default: - gmx_incons("Trying to access wrong FEP-state in LJ-PME routine"); + default: gmx_incons("Trying to access wrong FEP-state in LJ-PME routine"); } } else @@ -1406,15 +1365,14 @@ int gmx_pme_do(struct gmx_pme_t *pme, switch (fep_state) { case 0: - RedistC6 = c6A; - RedistSigma = sigmaA; + RedistC6 = c6A; + RedistSigma = sigmaA; break; case 1: - RedistC6 = c6B; - RedistSigma = sigmaB; + RedistC6 = c6B; + RedistSigma = sigmaB; break; - default: - gmx_incons("Trying to access wrong FEP-state in LJ-PME routine"); + default: gmx_incons("Trying to access wrong FEP-state in LJ-PME routine"); } wallcycle_start(wcycle, ewcPME_REDISTXF); @@ -1457,11 +1415,11 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (bFirst) { - inc_nrnb(nrnb, eNR_WEIGHTS, DIM*atc.numAtoms()); + inc_nrnb(nrnb, eNR_WEIGHTS, DIM * atc.numAtoms()); } inc_nrnb(nrnb, eNR_SPREADBSP, - pme->pme_order*pme->pme_order*pme->pme_order*atc.numAtoms()); + pme->pme_order * pme->pme_order * pme->pme_order * atc.numAtoms()); if (pme->nthread == 1) { wrap_periodic_pmegrid(pme, grid); @@ -1488,15 +1446,14 @@ int gmx_pme_do(struct gmx_pme_t *pme, wallcycle_start(wcycle, ewcPME_FFT); } - gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_REAL_TO_COMPLEX, - thread, wcycle); + gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_REAL_TO_COMPLEX, thread, wcycle); if (thread == 0) { wallcycle_stop(wcycle, ewcPME_FFT); } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } bFirst = FALSE; } @@ -1514,18 +1471,17 @@ int gmx_pme_do(struct gmx_pme_t *pme, wallcycle_start(wcycle, ewcLJPME); } - loop_count = - solve_pme_lj_yzx(pme, &pme->cfftgrid[2], TRUE, - scaledBox[XX][XX]*scaledBox[YY][YY]*scaledBox[ZZ][ZZ], - bCalcEnerVir, - pme->nthread, thread); + loop_count = solve_pme_lj_yzx( + pme, &pme->cfftgrid[2], TRUE, + scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ], + bCalcEnerVir, pme->nthread, thread); if (thread == 0) { wallcycle_stop(wcycle, ewcLJPME); inc_nrnb(nrnb, eNR_SOLVEPME, loop_count); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } @@ -1560,8 +1516,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, wallcycle_start(wcycle, ewcPME_FFT); } - gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_COMPLEX_TO_REAL, - thread, wcycle); + gmx_parallel_3dfft_execute(pfft_setup, GMX_FFT_COMPLEX_TO_REAL, thread, wcycle); if (thread == 0) { wallcycle_stop(wcycle, ewcPME_FFT); @@ -1569,16 +1524,16 @@ int gmx_pme_do(struct gmx_pme_t *pme, if (pme->nodeid == 0) { - real ntot = pme->nkx*pme->nky*pme->nkz; - npme = static_cast(ntot*std::log(ntot)/std::log(2.0)); - inc_nrnb(nrnb, eNR_FFT, 2*npme); + real ntot = pme->nkx * pme->nky * pme->nkz; + npme = static_cast(ntot * std::log(ntot) / std::log(2.0)); + inc_nrnb(nrnb, eNR_FFT, 2 * npme); } wallcycle_start(wcycle, ewcPME_GATHER); } copy_fftgrid_to_pmegrid(pme, fftgrid, grid, grid_index, pme->nthread, thread); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /*#pragma omp parallel*/ /* distribute local grid to all nodes */ @@ -1593,8 +1548,8 @@ int gmx_pme_do(struct gmx_pme_t *pme, { /* interpolate forces for our local atoms */ bClearF = (bFirst && PAR(cr)); - scale = pme->bFEP ? (fep_state < 1 ? 1.0-lambda_lj : lambda_lj) : 1.0; - scale *= lb_scale_factor[grid_index-2]; + scale = pme->bFEP ? (fep_state < 1 ? 1.0 - lambda_lj : lambda_lj) : 1.0; + scale *= lb_scale_factor[grid_index - 2]; #pragma omp parallel for num_threads(pme->nthread) schedule(static) for (thread = 0; thread < pme->nthread; thread++) @@ -1602,15 +1557,14 @@ int gmx_pme_do(struct gmx_pme_t *pme, try { gather_f_bsplines(pme, grid, bClearF, &pme->atc[0], - &pme->atc[0].spline[thread], - scale); + &pme->atc[0].spline[thread], scale); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } inc_nrnb(nrnb, eNR_GATHERFBSP, - pme->pme_order*pme->pme_order*pme->pme_order*pme->atc[0].numAtoms()); + pme->pme_order * pme->pme_order * pme->pme_order * pme->atc[0].numAtoms()); } wallcycle_stop(wcycle, ewcPME_GATHER); @@ -1638,8 +1592,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, } if (DOMAINDECOMP(cr)) { - dd_pmeredist_f(pme, &pme->atc[d], forcesRef, - d == pme->ndecompdim-1 && pme->bPPnode); + dd_pmeredist_f(pme, &pme->atc[d], forcesRef, d == pme->ndecompdim - 1 && pme->bPPnode); } } @@ -1657,14 +1610,14 @@ int gmx_pme_do(struct gmx_pme_t *pme, } else { - *energy_q = (1.0-lambda_q)*output[0].coulombEnergy_ + lambda_q*output[1].coulombEnergy_; - *dvdlambda_q += output[1].coulombEnergy_ - output[0].coulombEnergy_; + *energy_q = (1.0 - lambda_q) * output[0].coulombEnergy_ + lambda_q * output[1].coulombEnergy_; + *dvdlambda_q += output[1].coulombEnergy_ - output[0].coulombEnergy_; for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - vir_q[i][j] += (1.0-lambda_q)*output[0].coulombVirial_[i][j] + - lambda_q*output[1].coulombVirial_[i][j]; + vir_q[i][j] += (1.0 - lambda_q) * output[0].coulombVirial_[i][j] + + lambda_q * output[1].coulombVirial_[i][j]; } } } @@ -1687,13 +1640,15 @@ int gmx_pme_do(struct gmx_pme_t *pme, } else { - *energy_lj = (1.0-lambda_lj)*output[0].lennardJonesEnergy_ + lambda_lj*output[1].lennardJonesEnergy_; + *energy_lj = (1.0 - lambda_lj) * output[0].lennardJonesEnergy_ + + lambda_lj * output[1].lennardJonesEnergy_; *dvdlambda_lj += output[1].lennardJonesEnergy_ - output[0].lennardJonesEnergy_; for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - vir_lj[i][j] += (1.0-lambda_lj)*output[0].lennardJonesVirial_[i][j] + lambda_lj*output[1].lennardJonesVirial_[i][j]; + vir_lj[i][j] += (1.0 - lambda_lj) * output[0].lennardJonesVirial_[i][j] + + lambda_lj * output[1].lennardJonesVirial_[i][j]; } } } @@ -1710,7 +1665,7 @@ int gmx_pme_do(struct gmx_pme_t *pme, return 0; } -void gmx_pme_destroy(gmx_pme_t *pme) +void gmx_pme_destroy(gmx_pme_t* pme) { if (!pme) { @@ -1767,9 +1722,7 @@ void gmx_pme_destroy(gmx_pme_t *pme) delete pme; } -void gmx_pme_reinit_atoms(gmx_pme_t *pme, - const int numAtoms, - const real *charges) +void gmx_pme_reinit_atoms(gmx_pme_t* pme, const int numAtoms, const real* charges) { if (pme_gpu_active(pme)) { diff --git a/src/gromacs/ewald/pme.cuh b/src/gromacs/ewald/pme.cuh index 3994a84d83..f30a975a22 100644 --- a/src/gromacs/ewald/pme.cuh +++ b/src/gromacs/ewald/pme.cuh @@ -46,7 +46,7 @@ #include "gromacs/math/vectypes.h" // for DIM #include "pme_gpu_constants.h" -#include "pme_gpu_internal.h" // for GridOrdering +#include "pme_gpu_internal.h" // for GridOrdering #include "pme_gpu_types.h" /*! \brief \internal diff --git a/src/gromacs/ewald/pme.h b/src/gromacs/ewald/pme.h index 507af05bc2..c7efd52f99 100644 --- a/src/gromacs/ewald/pme.h +++ b/src/gromacs/ewald/pme.h @@ -77,7 +77,7 @@ enum class GpuTaskCompletion; class PmeGpuProgram; class GpuEventSynchronizer; //! Convenience name. -using PmeGpuProgramHandle = const PmeGpuProgram *; +using PmeGpuProgramHandle = const PmeGpuProgram*; namespace gmx { @@ -85,10 +85,12 @@ class PmePpCommGpu; class ForceWithVirial; class MDLogger; enum class PinningPolicy : int; -} +} // namespace gmx -enum { - GMX_SUM_GRID_FORWARD, GMX_SUM_GRID_BACKWARD +enum +{ + GMX_SUM_GRID_FORWARD, + GMX_SUM_GRID_BACKWARD }; /*! \brief Possible PME codepaths on a rank. @@ -96,10 +98,10 @@ enum { */ enum class PmeRunMode { - None, //!< No PME task is done - CPU, //!< Whole PME computation is done on CPU - GPU, //!< Whole PME computation is done on GPU - Mixed, //!< Mixed mode: only spread and gather run on GPU; FFT and solving are done on CPU. + None, //!< No PME task is done + CPU, //!< Whole PME computation is done on CPU + GPU, //!< Whole PME computation is done on GPU + Mixed, //!< Mixed mode: only spread and gather run on GPU; FFT and solving are done on CPU. }; //! PME gathering output forces treatment @@ -124,9 +126,11 @@ int minimalPmeGridSize(int pmeOrder); * * The PME GPU restrictions are checked separately during pme_gpu_init(). */ -bool gmx_pme_check_restrictions(int pme_order, - int nkx, int nky, int nkz, - int numPmeDomainsAlongX, +bool gmx_pme_check_restrictions(int pme_order, + int nkx, + int nky, + int nkz, + int numPmeDomainsAlongX, bool useThreads, bool errorsAreFatal); @@ -140,35 +144,37 @@ bool gmx_pme_check_restrictions(int pme_order, * related things whose lifetime can/should exceed that of a task (or * perhaps task manager). See Redmine #2522. */ -gmx_pme_t *gmx_pme_init(const t_commrec *cr, - const NumPmeDomains &numPmeDomains, - const t_inputrec *ir, - gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj, - gmx_bool bReproducible, - real ewaldcoeff_q, real ewaldcoeff_lj, - int nthread, - PmeRunMode runMode, - PmeGpu *pmeGpu, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram, - const gmx::MDLogger &mdlog); +gmx_pme_t* gmx_pme_init(const t_commrec* cr, + const NumPmeDomains& numPmeDomains, + const t_inputrec* ir, + gmx_bool bFreeEnergy_q, + gmx_bool bFreeEnergy_lj, + gmx_bool bReproducible, + real ewaldcoeff_q, + real ewaldcoeff_lj, + int nthread, + PmeRunMode runMode, + PmeGpu* pmeGpu, + const gmx_device_info_t* gpuInfo, + PmeGpuProgramHandle pmeGpuProgram, + const gmx::MDLogger& mdlog); /*! \brief Destroys the PME data structure.*/ -void gmx_pme_destroy(gmx_pme_t *pme); +void gmx_pme_destroy(gmx_pme_t* pme); //@{ /*! \brief Flag values that control what gmx_pme_do() will calculate * * These can be combined with bitwise-OR if more than one thing is required. */ -#define GMX_PME_SPREAD (1<<0) -#define GMX_PME_SOLVE (1<<1) -#define GMX_PME_CALC_F (1<<2) -#define GMX_PME_CALC_ENER_VIR (1<<3) +#define GMX_PME_SPREAD (1 << 0) +#define GMX_PME_SOLVE (1 << 1) +#define GMX_PME_CALC_F (1 << 2) +#define GMX_PME_CALC_ENER_VIR (1 << 3) /* This forces the grid to be backtransformed even without GMX_PME_CALC_F */ -#define GMX_PME_CALC_POT (1<<4) +#define GMX_PME_CALC_POT (1 << 4) -#define GMX_PME_DO_ALL_F (GMX_PME_SPREAD | GMX_PME_SOLVE | GMX_PME_CALC_F) +#define GMX_PME_DO_ALL_F (GMX_PME_SPREAD | GMX_PME_SOLVE | GMX_PME_CALC_F) //@} /*! \brief Do a PME calculation on a CPU for the long range electrostatics and/or LJ. @@ -182,27 +188,39 @@ void gmx_pme_destroy(gmx_pme_t *pme); * * \return 0 indicates all well, non zero is an error code. */ -int gmx_pme_do(struct gmx_pme_t *pme, +int gmx_pme_do(struct gmx_pme_t* pme, gmx::ArrayRef coordinates, gmx::ArrayRef forces, - real chargeA[], real chargeB[], - real c6A[], real c6B[], - real sigmaA[], real sigmaB[], - const matrix box, const t_commrec *cr, - int maxshift_x, int maxshift_y, - t_nrnb *nrnb, gmx_wallcycle *wcycle, - matrix vir_q, matrix vir_lj, - real *energy_q, real *energy_lj, - real lambda_q, real lambda_lj, - real *dvdlambda_q, real *dvdlambda_lj, - int flags); + real chargeA[], + real chargeB[], + real c6A[], + real c6B[], + real sigmaA[], + real sigmaB[], + const matrix box, + const t_commrec* cr, + int maxshift_x, + int maxshift_y, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + matrix vir_q, + matrix vir_lj, + real* energy_q, + real* energy_lj, + real lambda_q, + real lambda_lj, + real* dvdlambda_q, + real* dvdlambda_lj, + int flags); /*! \brief Called on the nodes that do PME exclusively */ -int gmx_pmeonly(struct gmx_pme_t *pme, - const t_commrec *cr, t_nrnb *mynrnb, - gmx_wallcycle *wcycle, +int gmx_pmeonly(struct gmx_pme_t* pme, + const t_commrec* cr, + t_nrnb* mynrnb, + gmx_wallcycle* wcycle, gmx_walltime_accounting_t walltime_accounting, - t_inputrec *ir, PmeRunMode runMode); + t_inputrec* ir, + PmeRunMode runMode); /*! \brief Calculate the PME grid energy V for n charges. * @@ -212,43 +230,54 @@ int gmx_pmeonly(struct gmx_pme_t *pme, * pme struct. Currently does not work in parallel or with free * energy. */ -void gmx_pme_calc_energy(gmx_pme_t *pme, - gmx::ArrayRef x, - gmx::ArrayRef q, - real *V); +void gmx_pme_calc_energy(gmx_pme_t* pme, gmx::ArrayRef x, gmx::ArrayRef q, real* V); /*! \brief Send the charges and maxshift to out PME-only node. */ -void gmx_pme_send_parameters(const t_commrec *cr, - const interaction_const_t *ic, - gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj, - real *chargeA, real *chargeB, - real *sqrt_c6A, real *sqrt_c6B, - real *sigmaA, real *sigmaB, - int maxshift_x, int maxshift_y); +void gmx_pme_send_parameters(const t_commrec* cr, + const interaction_const_t* ic, + gmx_bool bFreeEnergy_q, + gmx_bool bFreeEnergy_lj, + real* chargeA, + real* chargeB, + real* sqrt_c6A, + real* sqrt_c6B, + real* sigmaA, + real* sigmaB, + int maxshift_x, + int maxshift_y); /*! \brief Send the coordinates to our PME-only node and request a PME calculation */ -void gmx_pme_send_coordinates(t_forcerec *fr, const t_commrec *cr, const matrix box, const rvec *x, - real lambda_q, real lambda_lj, - gmx_bool bEnerVir, - int64_t step, bool useGpuPmePpComms, - bool reinitGpuPmePpComms, - bool sendCoordinatesFromGpu, - GpuEventSynchronizer *coordinatesReadyOnDeviceEvent, gmx_wallcycle *wcycle); +void gmx_pme_send_coordinates(t_forcerec* fr, + const t_commrec* cr, + const matrix box, + const rvec* x, + real lambda_q, + real lambda_lj, + gmx_bool bEnerVir, + int64_t step, + bool useGpuPmePpComms, + bool reinitGpuPmePpComms, + bool sendCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent, + gmx_wallcycle* wcycle); /*! \brief Tell our PME-only node to finish */ -void gmx_pme_send_finish(const t_commrec *cr); +void gmx_pme_send_finish(const t_commrec* cr); /*! \brief Tell our PME-only node to reset all cycle and flop counters */ -void gmx_pme_send_resetcounters(const t_commrec *cr, int64_t step); +void gmx_pme_send_resetcounters(const t_commrec* cr, int64_t step); /*! \brief PP nodes receive the long range forces from the PME nodes */ -void gmx_pme_receive_f(gmx::PmePpCommGpu *pmePpCommGpu, - const t_commrec *cr, - gmx::ForceWithVirial *forceWithVirial, - real *energy_q, real *energy_lj, - real *dvdlambda_q, real *dvdlambda_lj, - bool useGpuPmePpComms, bool receivePmeForceToGpu, - float *pme_cycles); +void gmx_pme_receive_f(gmx::PmePpCommGpu* pmePpCommGpu, + const t_commrec* cr, + gmx::ForceWithVirial* forceWithVirial, + real* energy_q, + real* energy_lj, + real* dvdlambda_q, + real* dvdlambda_lj, + bool useGpuPmePpComms, + bool receivePmeForceToGpu, + float* pme_cycles); /*! \brief * This function updates the local atom data on GPU after DD (charges, coordinates, etc.). @@ -259,9 +288,7 @@ void gmx_pme_receive_f(gmx::PmePpCommGpu *pmePpCommGpu, * \param[in] numAtoms The number of particles. * \param[in] charges The pointer to the array of particle charges. */ -void gmx_pme_reinit_atoms(gmx_pme_t *pme, - int numAtoms, - const real *charges); +void gmx_pme_reinit_atoms(gmx_pme_t* pme, int numAtoms, const real* charges); /* A block of PME GPU functions */ @@ -274,7 +301,7 @@ void gmx_pme_reinit_atoms(gmx_pme_t *pme, * * \returns true if PME can run on GPU on this build, false otherwise. */ -bool pme_gpu_supports_build(std::string *error); +bool pme_gpu_supports_build(std::string* error); /*! \brief Checks whether the detected (GPU) hardware allows to run PME on GPU. * @@ -283,8 +310,7 @@ bool pme_gpu_supports_build(std::string *error); * * \returns true if PME can run on GPU on this build, false otherwise. */ -bool pme_gpu_supports_hardware(const gmx_hw_info_t &hwinfo, - std::string *error); +bool pme_gpu_supports_hardware(const gmx_hw_info_t& hwinfo, std::string* error); /*! \brief Checks whether the input system allows to run PME on GPU. * TODO: this partly duplicates an internal PME assert function @@ -297,7 +323,7 @@ bool pme_gpu_supports_hardware(const gmx_hw_info_t &hwinfo, * * \returns true if PME can run on GPU with this input, false otherwise. */ -bool pme_gpu_supports_input(const t_inputrec &ir, const gmx_mtop_t &mtop, std::string *error); +bool pme_gpu_supports_input(const t_inputrec& ir, const gmx_mtop_t& mtop, std::string* error); /*! \brief * Returns the active PME codepath (CPU, GPU, mixed). @@ -306,7 +332,7 @@ bool pme_gpu_supports_input(const t_inputrec &ir, const gmx_mtop_t &mtop, std::s * \param[in] pme The PME data structure. * \returns active PME codepath. */ -PmeRunMode pme_run_mode(const gmx_pme_t *pme); +PmeRunMode pme_run_mode(const gmx_pme_t* pme); /*! \libinternal \brief * Return the pinning policy appropriate for this build configuration @@ -322,7 +348,7 @@ gmx::PinningPolicy pme_get_pinning_policy(); * \param[in] pme The PME data structure. * \returns true if PME can run on GPU, false otherwise. */ -inline bool pme_gpu_task_enabled(const gmx_pme_t *pme) +inline bool pme_gpu_task_enabled(const gmx_pme_t* pme) { return (pme != nullptr) && (pme_run_mode(pme) != PmeRunMode::CPU); } @@ -331,7 +357,8 @@ inline bool pme_gpu_task_enabled(const gmx_pme_t *pme) * * \param[in] pme The PME data structure. */ -GPU_FUNC_QUALIFIER int pme_gpu_get_padding_size(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(0); +GPU_FUNC_QUALIFIER int pme_gpu_get_padding_size(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(0); // The following functions are all the PME GPU entry points, // currently inlining to nothing on non-CUDA builds. @@ -341,7 +368,7 @@ GPU_FUNC_QUALIFIER int pme_gpu_get_padding_size(const gmx_pme_t *GPU_FUNC_ARGUME * * \param[in] pme The PME structure. */ -GPU_FUNC_QUALIFIER void pme_gpu_reset_timings(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_reset_timings(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM; /*! \brief * Copies the PME GPU timings to the gmx_wallclock_gpu_pme_t structure (for log output). To be called at the run end. @@ -349,8 +376,8 @@ GPU_FUNC_QUALIFIER void pme_gpu_reset_timings(const gmx_pme_t *GPU_FUNC_ARGUMENT * \param[in] pme The PME structure. * \param[in] timings The gmx_wallclock_gpu_pme_t structure. */ -GPU_FUNC_QUALIFIER void pme_gpu_get_timings(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - gmx_wallclock_gpu_pme_t *GPU_FUNC_ARGUMENT(timings)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_get_timings(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + gmx_wallclock_gpu_pme_t* GPU_FUNC_ARGUMENT(timings)) GPU_FUNC_TERM; /* The main PME GPU functions */ @@ -364,12 +391,12 @@ GPU_FUNC_QUALIFIER void pme_gpu_get_timings(const gmx_pme_t *GPU_FUNC_AR * The flags are the GMX_PME_ flags from pme.h. * \param[in] useGpuForceReduction Whether PME forces are reduced on GPU this step or should be downloaded for CPU reduction */ -GPU_FUNC_QUALIFIER void pme_gpu_prepare_computation(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - bool GPU_FUNC_ARGUMENT(needToUpdateBox), - const matrix GPU_FUNC_ARGUMENT(box), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle), - int GPU_FUNC_ARGUMENT(flags), - bool GPU_FUNC_ARGUMENT(useGpuForceReduction)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_prepare_computation(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + bool GPU_FUNC_ARGUMENT(needToUpdateBox), + const matrix GPU_FUNC_ARGUMENT(box), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle), + int GPU_FUNC_ARGUMENT(flags), + bool GPU_FUNC_ARGUMENT(useGpuForceReduction)) GPU_FUNC_TERM; /*! \brief * Launches first stage of PME on GPU - spreading kernel. @@ -378,9 +405,9 @@ GPU_FUNC_QUALIFIER void pme_gpu_prepare_computation(gmx_pme_t *GPU_FUNC_ARG * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory; nullptr allowed only on separate PME ranks. * \param[in] wcycle The wallclock counter. */ -GPU_FUNC_QUALIFIER void pme_gpu_launch_spread(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - GpuEventSynchronizer *GPU_FUNC_ARGUMENT(xReadyOnDevice), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_launch_spread(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + GpuEventSynchronizer* GPU_FUNC_ARGUMENT(xReadyOnDevice), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; /*! \brief * Launches middle stages of PME (FFT R2C, solving, FFT C2R) either on GPU or on CPU, depending on the run mode. @@ -388,21 +415,21 @@ GPU_FUNC_QUALIFIER void pme_gpu_launch_spread(gmx_pme_t *GPU_FUNC_ARG * \param[in] pme The PME data structure. * \param[in] wcycle The wallclock counter. */ -GPU_FUNC_QUALIFIER void pme_gpu_launch_complex_transforms(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_launch_complex_transforms(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; /*! \brief * Launches last stage of PME on GPU - force gathering and D2H force transfer. * * \param[in] pme The PME data structure. * \param[in] wcycle The wallclock counter. - * \param[in] forceTreatment Tells how data should be treated. The gathering kernel either stores - * the output reciprocal forces into the host array, or copies its contents to the GPU first + * \param[in] forceTreatment Tells how data should be treated. The gathering kernel either + * stores the output reciprocal forces into the host array, or copies its contents to the GPU first * and accumulates. The reduction is non-atomic. */ -GPU_FUNC_QUALIFIER void pme_gpu_launch_gather(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle), - PmeForceOutputHandling GPU_FUNC_ARGUMENT(forceTreatment)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_launch_gather(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle), + PmeForceOutputHandling GPU_FUNC_ARGUMENT(forceTreatment)) GPU_FUNC_TERM; /*! \brief * Attempts to complete PME GPU tasks. @@ -422,16 +449,16 @@ GPU_FUNC_QUALIFIER void pme_gpu_launch_gather(const gmx_pme_t *GPU_FUNC_A * \param[out] enerd The output energies * \param[in] flags The combination of flags to affect this PME computation. * The flags are the GMX_PME_ flags from pme.h. - * \param[in] completionKind Indicates whether PME task completion should only be checked rather than waited for - * \returns True if the PME GPU tasks have completed + * \param[in] completionKind Indicates whether PME task completion should only be checked rather + * than waited for \returns True if the PME GPU tasks have completed */ -GPU_FUNC_QUALIFIER bool - pme_gpu_try_finish_task(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - int GPU_FUNC_ARGUMENT(flags), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle), - gmx::ForceWithVirial *GPU_FUNC_ARGUMENT(forceWithVirial), - gmx_enerdata_t *GPU_FUNC_ARGUMENT(enerd), - GpuTaskCompletion GPU_FUNC_ARGUMENT(completionKind)) GPU_FUNC_TERM_WITH_RETURN(false); +GPU_FUNC_QUALIFIER bool pme_gpu_try_finish_task(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + int GPU_FUNC_ARGUMENT(flags), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle), + gmx::ForceWithVirial* GPU_FUNC_ARGUMENT(forceWithVirial), + gmx_enerdata_t* GPU_FUNC_ARGUMENT(enerd), + GpuTaskCompletion GPU_FUNC_ARGUMENT(completionKind)) + GPU_FUNC_TERM_WITH_RETURN(false); /*! \brief * Blocks until PME GPU tasks are completed, and gets the output forces and virial/energy @@ -444,12 +471,11 @@ GPU_FUNC_QUALIFIER bool * \param[out] forceWithVirial The output force and virial * \param[out] enerd The output energies */ -GPU_FUNC_QUALIFIER void - pme_gpu_wait_and_reduce(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - int GPU_FUNC_ARGUMENT(flags), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle), - gmx::ForceWithVirial *GPU_FUNC_ARGUMENT(forceWithVirial), - gmx_enerdata_t *GPU_FUNC_ARGUMENT(enerd)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_wait_and_reduce(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + int GPU_FUNC_ARGUMENT(flags), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle), + gmx::ForceWithVirial* GPU_FUNC_ARGUMENT(forceWithVirial), + gmx_enerdata_t* GPU_FUNC_ARGUMENT(enerd)) GPU_FUNC_TERM; /*! \brief * The PME GPU reinitialization function that is called both at the end of any PME computation and on any load balancing. @@ -464,45 +490,50 @@ GPU_FUNC_QUALIFIER void * \param[in] pme The PME data structure. * \param[in] wcycle The wallclock counter. */ -GPU_FUNC_QUALIFIER void pme_gpu_reinit_computation(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_reinit_computation(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM; /*! \brief Get pointer to device copy of coordinate data. * \param[in] pme The PME data structure. * \returns Pointer to coordinate data */ -GPU_FUNC_QUALIFIER DeviceBuffer pme_gpu_get_device_x(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(DeviceBuffer {}); +GPU_FUNC_QUALIFIER DeviceBuffer pme_gpu_get_device_x(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(DeviceBuffer{}); /*! \brief Set pointer to device copy of coordinate data. * \param[in] pme The PME data structure. * \param[in] d_x The pointer to the positions buffer to be set */ -GPU_FUNC_QUALIFIER void pme_gpu_set_device_x(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - DeviceBuffer GPU_FUNC_ARGUMENT(d_x)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_set_device_x(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + DeviceBuffer GPU_FUNC_ARGUMENT(d_x)) GPU_FUNC_TERM; /*! \brief Get pointer to device copy of force data. * \param[in] pme The PME data structure. * \returns Pointer to force data */ -GPU_FUNC_QUALIFIER void *pme_gpu_get_device_f(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_device_f(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Returns the pointer to the GPU stream. * \param[in] pme The PME data structure. * \returns Pointer to GPU stream object. */ -GPU_FUNC_QUALIFIER void *pme_gpu_get_device_stream(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_device_stream(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Returns the pointer to the GPU context. * \param[in] pme The PME data structure. * \returns Pointer to GPU context object. */ -GPU_FUNC_QUALIFIER void *pme_gpu_get_device_context(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_device_context(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Get pointer to the device synchronizer object that allows syncing on PME force calculation completion * \param[in] pme The PME data structure. * \returns Pointer to sychronizer */ -GPU_FUNC_QUALIFIER GpuEventSynchronizer *pme_gpu_get_f_ready_synchronizer(const gmx_pme_t *GPU_FUNC_ARGUMENT(pme)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER GpuEventSynchronizer* pme_gpu_get_f_ready_synchronizer(const gmx_pme_t* GPU_FUNC_ARGUMENT(pme)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); #endif diff --git a/src/gromacs/ewald/pme_calculate_splines.cuh b/src/gromacs/ewald/pme_calculate_splines.cuh index 7220e1ed53..f52c81c599 100644 --- a/src/gromacs/ewald/pme_calculate_splines.cuh +++ b/src/gromacs/ewald/pme_calculate_splines.cuh @@ -62,21 +62,21 @@ static const bool c_useAtomDataPrefetch = true; * \param[out] sm_destination Shared memory array for output. * \param[in] gm_source Global memory array for input. */ -template -__device__ __forceinline__ -void pme_gpu_stage_atom_data(const PmeGpuCudaKernelParams kernelParams, - T * __restrict__ sm_destination, - const T * __restrict__ gm_source) +template +__device__ __forceinline__ void pme_gpu_stage_atom_data(const PmeGpuCudaKernelParams kernelParams, + T* __restrict__ sm_destination, + const T* __restrict__ gm_source) { - static_assert(c_usePadding, "With padding disabled, index checking should be fixed to account for spline theta/dtheta pr-warp alignment"); + static_assert(c_usePadding, + "With padding disabled, index checking should be fixed to account for spline " + "theta/dtheta pr-warp alignment"); const int blockIndex = blockIdx.y * gridDim.x + blockIdx.x; const int threadLocalIndex = ((threadIdx.z * blockDim.y + threadIdx.y) * blockDim.x) + threadIdx.x; const int localIndex = threadLocalIndex; - const int globalIndexBase = blockIndex * atomsPerBlock * dataCountPerAtom; - const int globalIndex = globalIndexBase + localIndex; - const int globalCheck = pme_gpu_check_atom_data_index(globalIndex, kernelParams.atoms.nAtoms * dataCountPerAtom); + const int globalIndexBase = blockIndex * atomsPerBlock * dataCountPerAtom; + const int globalIndex = globalIndexBase + localIndex; + const int globalCheck = + pme_gpu_check_atom_data_index(globalIndex, kernelParams.atoms.nAtoms * dataCountPerAtom); if ((localIndex < atomsPerBlock * dataCountPerAtom) & globalCheck) { assert(isfinite(float(gm_source[globalIndex]))); @@ -104,34 +104,30 @@ void pme_gpu_stage_atom_data(const PmeGpuCudaKernelParams kernelParams, * \param[out] sm_gridlineIndices Atom gridline indices in the shared memory. */ -template -__device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams kernelParams, - const int atomIndexOffset, - const float3 atomX, - const float atomCharge, - float * __restrict__ sm_theta, - float * __restrict__ sm_dtheta, - int * __restrict__ sm_gridlineIndices) +template +__device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams kernelParams, + const int atomIndexOffset, + const float3 atomX, + const float atomCharge, + float* __restrict__ sm_theta, + float* __restrict__ sm_dtheta, + int* __restrict__ sm_gridlineIndices) { /* Global memory pointers for output */ - float * __restrict__ gm_theta = kernelParams.atoms.d_theta; - float * __restrict__ gm_dtheta = kernelParams.atoms.d_dtheta; - int * __restrict__ gm_gridlineIndices = kernelParams.atoms.d_gridlineIndices; + float* __restrict__ gm_theta = kernelParams.atoms.d_theta; + float* __restrict__ gm_dtheta = kernelParams.atoms.d_dtheta; + int* __restrict__ gm_gridlineIndices = kernelParams.atoms.d_gridlineIndices; /* Fractional coordinates */ __shared__ float sm_fractCoords[atomsPerBlock * DIM]; /* Thread index w.r.t. block */ - const int threadLocalId = (threadIdx.z * (blockDim.x * blockDim.y)) - + (threadIdx.y * blockDim.x) + threadIdx.x; + const int threadLocalId = + (threadIdx.z * (blockDim.x * blockDim.y)) + (threadIdx.y * blockDim.x) + threadIdx.x; /* Warp index w.r.t. block - could probably be obtained easier? */ const int warpIndex = threadLocalId / warp_size; /* Atom index w.r.t. warp - alternating 0 1 0 1 .. */ - const int atomWarpIndex = threadIdx.z %atomsPerWarp; + const int atomWarpIndex = threadIdx.z % atomsPerWarp; /* Atom index w.r.t. block/shared memory */ const int atomIndexLocal = warpIndex * atomsPerWarp + atomWarpIndex; @@ -144,12 +140,12 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams const int dimIndex = threadLocalIdXY % DIM; /* Multi-purpose index of rvec/ivec atom data */ - const int sharedMemoryIndex = atomIndexLocal * DIM + dimIndex; + const int sharedMemoryIndex = atomIndexLocal * DIM + dimIndex; - float splineData[order]; + float splineData[order]; - const int localCheck = (dimIndex < DIM) && (orderIndex < 1); - const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); + const int localCheck = (dimIndex < DIM) && (orderIndex < 1); + const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); /* we have 4 threads per atom, but can only use 3 here for the dimensions */ if (localCheck && globalCheck) @@ -158,9 +154,9 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams if (orderIndex == 0) { - int tableIndex, tInt; - float n, t; - assert(atomIndexLocal < DIM*atomsPerBlock); + int tableIndex, tInt; + float n, t; + assert(atomIndexLocal < DIM * atomsPerBlock); /* Accessing fields in fshOffset/nXYZ/recipbox/... with dimIndex offset * puts them into local memory(!) instead of accessing the constant memory directly. * That's the reason for the switch, to unroll explicitly. @@ -169,46 +165,51 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams switch (dimIndex) { case XX: - tableIndex = kernelParams.grid.tablesOffsets[XX]; - n = kernelParams.grid.realGridSizeFP[XX]; - t = atomX.x * kernelParams.current.recipBox[dimIndex][XX] + atomX.y * kernelParams.current.recipBox[dimIndex][YY] + atomX.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[XX]; + n = kernelParams.grid.realGridSizeFP[XX]; + t = atomX.x * kernelParams.current.recipBox[dimIndex][XX] + + atomX.y * kernelParams.current.recipBox[dimIndex][YY] + + atomX.z * kernelParams.current.recipBox[dimIndex][ZZ]; break; case YY: - tableIndex = kernelParams.grid.tablesOffsets[YY]; - n = kernelParams.grid.realGridSizeFP[YY]; - t = /*atomX.x * kernelParams.current.recipBox[dimIndex][XX] + */ atomX.y * kernelParams.current.recipBox[dimIndex][YY] + atomX.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[YY]; + n = kernelParams.grid.realGridSizeFP[YY]; + t = /*atomX.x * kernelParams.current.recipBox[dimIndex][XX] + */ atomX.y + * kernelParams.current.recipBox[dimIndex][YY] + + atomX.z * kernelParams.current.recipBox[dimIndex][ZZ]; break; case ZZ: - tableIndex = kernelParams.grid.tablesOffsets[ZZ]; - n = kernelParams.grid.realGridSizeFP[ZZ]; - t = /*atomX.x * kernelParams.current.recipBox[dimIndex][XX] + atomX.y * kernelParams.current.recipBox[dimIndex][YY] + */ atomX.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[ZZ]; + n = kernelParams.grid.realGridSizeFP[ZZ]; + t = /*atomX.x * kernelParams.current.recipBox[dimIndex][XX] + atomX.y * kernelParams.current.recipBox[dimIndex][YY] + */ atomX + .z + * kernelParams.current.recipBox[dimIndex][ZZ]; break; } const float shift = c_pmeMaxUnitcellShift; /* Fractional coordinates along box vectors, adding a positive shift to ensure t is positive for triclinic boxes */ t = (t + shift) * n; tInt = (int)t; - assert(sharedMemoryIndex < atomsPerBlock*DIM); + assert(sharedMemoryIndex < atomsPerBlock * DIM); sm_fractCoords[sharedMemoryIndex] = t - tInt; - tableIndex += tInt; + tableIndex += tInt; assert(tInt >= 0); assert(tInt < c_pmeNeighborUnitcellCount * n); // TODO have shared table for both parameters to share the fetch, as index is always same? // TODO compare texture/LDG performance sm_fractCoords[sharedMemoryIndex] += - fetchFromParamLookupTable(kernelParams.grid.d_fractShiftsTable, - kernelParams.fractShiftsTableTexture, - tableIndex); + fetchFromParamLookupTable(kernelParams.grid.d_fractShiftsTable, + kernelParams.fractShiftsTableTexture, tableIndex); sm_gridlineIndices[sharedMemoryIndex] = - fetchFromParamLookupTable(kernelParams.grid.d_gridlineIndicesTable, - kernelParams.gridlineIndicesTableTexture, - tableIndex); + fetchFromParamLookupTable(kernelParams.grid.d_gridlineIndicesTable, + kernelParams.gridlineIndicesTableTexture, tableIndex); if (writeGlobal) { - gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] = sm_gridlineIndices[sharedMemoryIndex]; + gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] = + sm_gridlineIndices[sharedMemoryIndex]; } } @@ -217,31 +218,33 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams const int chargeCheck = pme_gpu_check_atom_charge(atomCharge); if (chargeCheck) { - float div; - int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1 + float div; + int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1 const float dr = sm_fractCoords[sharedMemoryIndex]; assert(isfinite(dr)); /* dr is relative offset from lower cell limit */ - splineData[order-1] = 0.0f; - splineData[1] = dr; - splineData[0] = 1.0f - dr; + splineData[order - 1] = 0.0f; + splineData[1] = dr; + splineData[0] = 1.0f - dr; #pragma unroll for (int k = 3; k < order; k++) { - div = 1.0f / (k - 1.0f); - splineData[k - 1] = div * dr * splineData[k - 2]; + div = 1.0f / (k - 1.0f); + splineData[k - 1] = div * dr * splineData[k - 2]; #pragma unroll for (int l = 1; l < (k - 1); l++) { - splineData[k - l - 1] = div * ((dr + l) * splineData[k - l - 2] + (k - l - dr) * splineData[k - l - 1] ); + splineData[k - l - 1] = + div * ((dr + l) * splineData[k - l - 2] + (k - l - dr) * splineData[k - l - 1]); } splineData[0] = div * (1.0f - dr) * splineData[0]; } - const int thetaIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); + const int thetaIndexBase = + getSplineParamIndexBase(warpIndex, atomWarpIndex); const int thetaGlobalOffsetBase = atomIndexOffset * DIM * order; /* only calculate dtheta if we are saving it to shared or global memory */ if (writeSmDtheta || writeGlobal) @@ -250,18 +253,19 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams #pragma unroll for (o = 0; o < order; o++) { - const int thetaIndex = getSplineParamIndex(thetaIndexBase, dimIndex, o); + const int thetaIndex = + getSplineParamIndex(thetaIndexBase, dimIndex, o); const float dtheta = ((o > 0) ? splineData[o - 1] : 0.0f) - splineData[o]; assert(isfinite(dtheta)); - assert(thetaIndex < order*DIM*atomsPerBlock); + assert(thetaIndex < order * DIM * atomsPerBlock); if (writeSmDtheta) { sm_dtheta[thetaIndex] = dtheta; } if (writeGlobal) { - const int thetaGlobalIndex = thetaGlobalOffsetBase + thetaIndex; + const int thetaGlobalIndex = thetaGlobalOffsetBase + thetaIndex; gm_dtheta[thetaGlobalIndex] = dtheta; } } @@ -272,7 +276,9 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams #pragma unroll for (int k = 1; k < (order - 1); k++) { - splineData[order - k - 1] = div * ((dr + k) * splineData[order - k - 2] + (order - k - dr) * splineData[order - k - 1]); + splineData[order - k - 1] = div + * ((dr + k) * splineData[order - k - 2] + + (order - k - dr) * splineData[order - k - 1]); } splineData[0] = div * (1.0f - dr) * splineData[0]; @@ -280,9 +286,10 @@ __device__ __forceinline__ void calculate_splines(const PmeGpuCudaKernelParams #pragma unroll for (o = 0; o < order; o++) { - const int thetaIndex = getSplineParamIndex(thetaIndexBase, dimIndex, o); - assert(thetaIndex < order*DIM*atomsPerBlock); - sm_theta[thetaIndex] = splineData[o]; + const int thetaIndex = + getSplineParamIndex(thetaIndexBase, dimIndex, o); + assert(thetaIndex < order * DIM * atomsPerBlock); + sm_theta[thetaIndex] = splineData[o]; assert(isfinite(sm_theta[thetaIndex])); if (writeGlobal) { diff --git a/src/gromacs/ewald/pme_coordinate_receiver_gpu.h b/src/gromacs/ewald/pme_coordinate_receiver_gpu.h index c2c00e3e30..774c831f03 100644 --- a/src/gromacs/ewald/pme_coordinate_receiver_gpu.h +++ b/src/gromacs/ewald/pme_coordinate_receiver_gpu.h @@ -53,34 +53,33 @@ namespace gmx class PmeCoordinateReceiverGpu { - public: - /*! \brief Creates PME GPU coordinate receiver object - * \param[in] pmeStream CUDA stream used for PME computations - * \param[in] comm Communicator used for simulation - * \param[in] ppRanks List of PP ranks - */ - PmeCoordinateReceiverGpu(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); - ~PmeCoordinateReceiverGpu(); +public: + /*! \brief Creates PME GPU coordinate receiver object + * \param[in] pmeStream CUDA stream used for PME computations + * \param[in] comm Communicator used for simulation + * \param[in] ppRanks List of PP ranks + */ + PmeCoordinateReceiverGpu(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); + ~PmeCoordinateReceiverGpu(); - /*! \brief - * send coordinates buffer address to PP rank - * \param[in] d_x coordinates buffer in GPU memory - */ - void sendCoordinateBufferAddressToPpRanks(rvec *d_x); + /*! \brief + * send coordinates buffer address to PP rank + * \param[in] d_x coordinates buffer in GPU memory + */ + void sendCoordinateBufferAddressToPpRanks(rvec* d_x); - /*! \brief - * receive coordinate data from PP rank - * \param[in] ppRank PP rank to send data - */ - void receiveCoordinatesFromPpCudaDirect(int ppRank); - - private: - class Impl; - gmx::PrivateImplPointer impl_; + /*! \brief + * receive coordinate data from PP rank + * \param[in] ppRank PP rank to send data + */ + void receiveCoordinatesFromPpCudaDirect(int ppRank); +private: + class Impl; + gmx::PrivateImplPointer impl_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cpp b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cpp old mode 100755 new mode 100644 index 329cd2f5be..b92637f046 --- a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cpp +++ b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cpp @@ -60,25 +60,33 @@ class PmeCoordinateReceiverGpu::Impl }; /*!\brief Constructor stub. */ -PmeCoordinateReceiverGpu::PmeCoordinateReceiverGpu(void gmx_unused *pmeStream, MPI_Comm gmx_unused comm, gmx::ArrayRef gmx_unused ppRanks) - : impl_(nullptr) +PmeCoordinateReceiverGpu::PmeCoordinateReceiverGpu(void gmx_unused* pmeStream, + MPI_Comm gmx_unused comm, + gmx::ArrayRef gmx_unused ppRanks) : + impl_(nullptr) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } PmeCoordinateReceiverGpu::~PmeCoordinateReceiverGpu() = default; /*!\brief init PME-PP GPU communication stub */ -void PmeCoordinateReceiverGpu::sendCoordinateBufferAddressToPpRanks(rvec gmx_unused *d_x) +void PmeCoordinateReceiverGpu::sendCoordinateBufferAddressToPpRanks(rvec gmx_unused* d_x) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication initialization was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication initialization was called instead of the " + "correct implementation."); } void PmeCoordinateReceiverGpu::receiveCoordinatesFromPpCudaDirect(int gmx_unused ppRank) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } -} // namespace gmx +} // namespace gmx #endif /* GMX_GPU != GMX_GPU_CUDA */ diff --git a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cu b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cu index b04b3c181f..171896b528 100644 --- a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cu +++ b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.cu @@ -58,34 +58,34 @@ namespace gmx { -PmeCoordinateReceiverGpu::Impl::Impl(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) - : pmeStream_(*static_cast (pmeStream)), - comm_(comm), - ppRanks_(ppRanks) +PmeCoordinateReceiverGpu::Impl::Impl(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) : + pmeStream_(*static_cast(pmeStream)), + comm_(comm), + ppRanks_(ppRanks) { - GMX_RELEASE_ASSERT(GMX_THREAD_MPI, "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); + GMX_RELEASE_ASSERT( + GMX_THREAD_MPI, + "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); } PmeCoordinateReceiverGpu::Impl::~Impl() = default; -void PmeCoordinateReceiverGpu::Impl::sendCoordinateBufferAddressToPpRanks(rvec *d_x) +void PmeCoordinateReceiverGpu::Impl::sendCoordinateBufferAddressToPpRanks(rvec* d_x) { int ind_start = 0; int ind_end = 0; - for (const auto &receiver : ppRanks_) + for (const auto& receiver : ppRanks_) { ind_start = ind_end; ind_end = ind_start + receiver.numAtoms; - //Data will be transferred directly from GPU. - void* sendBuf = reinterpret_cast (&d_x[ind_start]); + // Data will be transferred directly from GPU. + void* sendBuf = reinterpret_cast(&d_x[ind_start]); #if GMX_MPI - MPI_Send(&sendBuf, sizeof(void**), MPI_BYTE, receiver.rankId, - 0, comm_); + MPI_Send(&sendBuf, sizeof(void**), MPI_BYTE, receiver.rankId, 0, comm_); #endif - } } @@ -97,16 +97,16 @@ void PmeCoordinateReceiverGpu::Impl::receiveCoordinatesFromPpCudaDirect(int ppRa #if GMX_MPI // Receive event from PP task and add to PME stream, to ensure PME calculation doesn't // commence until coordinate data has been transferred - GpuEventSynchronizer *ppSync; - MPI_Recv(&ppSync, sizeof(GpuEventSynchronizer*), - MPI_BYTE, ppRank, 0, - comm_, MPI_STATUS_IGNORE); + GpuEventSynchronizer* ppSync; + MPI_Recv(&ppSync, sizeof(GpuEventSynchronizer*), MPI_BYTE, ppRank, 0, comm_, MPI_STATUS_IGNORE); ppSync->enqueueWaitEvent(pmeStream_); #endif } -PmeCoordinateReceiverGpu::PmeCoordinateReceiverGpu(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) - : impl_(new Impl(pmeStream, comm, ppRanks)) +PmeCoordinateReceiverGpu::PmeCoordinateReceiverGpu(void* pmeStream, + MPI_Comm comm, + gmx::ArrayRef ppRanks) : + impl_(new Impl(pmeStream, comm, ppRanks)) { } @@ -122,4 +122,4 @@ void PmeCoordinateReceiverGpu::receiveCoordinatesFromPpCudaDirect(int ppRank) impl_->receiveCoordinatesFromPpCudaDirect(ppRank); } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.h b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.h index ee87af4008..015ae346d4 100644 --- a/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.h +++ b/src/gromacs/ewald/pme_coordinate_receiver_gpu_impl.h @@ -54,34 +54,34 @@ namespace gmx class PmeCoordinateReceiverGpu::Impl { - public: - /*! \brief Creates PME GPU coordinate receiver object - * \param[in] pmeStream CUDA stream used for PME computations - * \param[in] comm Communicator used for simulation - * \param[in] ppRanks List of PP ranks - */ - Impl(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); - ~Impl(); +public: + /*! \brief Creates PME GPU coordinate receiver object + * \param[in] pmeStream CUDA stream used for PME computations + * \param[in] comm Communicator used for simulation + * \param[in] ppRanks List of PP ranks + */ + Impl(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); + ~Impl(); - /*! \brief - * send coordinates buffer address to PP rank - * \param[in] d_x coordinates buffer in GPU memory - */ - void sendCoordinateBufferAddressToPpRanks(rvec *d_x); + /*! \brief + * send coordinates buffer address to PP rank + * \param[in] d_x coordinates buffer in GPU memory + */ + void sendCoordinateBufferAddressToPpRanks(rvec* d_x); - /*! \brief - * receive coordinate data from PP rank - * \param[in] ppRank PP rank to send data - */ - void receiveCoordinatesFromPpCudaDirect(int ppRank); + /*! \brief + * receive coordinate data from PP rank + * \param[in] ppRank PP rank to send data + */ + void receiveCoordinatesFromPpCudaDirect(int ppRank); - private: - //! CUDA stream for PME operations - cudaStream_t pmeStream_ = nullptr; - //! communicator for simulation - MPI_Comm comm_; - //! list of PP ranks - gmx::ArrayRef ppRanks_; +private: + //! CUDA stream for PME operations + cudaStream_t pmeStream_ = nullptr; + //! communicator for simulation + MPI_Comm comm_; + //! list of PP ranks + gmx::ArrayRef ppRanks_; }; } // namespace gmx diff --git a/src/gromacs/ewald/pme_force_sender_gpu.h b/src/gromacs/ewald/pme_force_sender_gpu.h index 8bd5fd7ebd..479e01ad52 100644 --- a/src/gromacs/ewald/pme_force_sender_gpu.h +++ b/src/gromacs/ewald/pme_force_sender_gpu.h @@ -59,7 +59,7 @@ struct PpRanks namespace gmx { -template +template class ArrayRef; /*! \libinternal @@ -67,33 +67,32 @@ class ArrayRef; class PmeForceSenderGpu { - public: - /*! \brief Creates PME GPU Force sender object - * \param[in] pmeStream CUDA stream used for PME computations - * \param[in] comm Communicator used for simulation - * \param[in] ppRanks List of PP ranks - */ - PmeForceSenderGpu(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); - ~PmeForceSenderGpu(); +public: + /*! \brief Creates PME GPU Force sender object + * \param[in] pmeStream CUDA stream used for PME computations + * \param[in] comm Communicator used for simulation + * \param[in] ppRanks List of PP ranks + */ + PmeForceSenderGpu(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); + ~PmeForceSenderGpu(); - /*! \brief - * Initialization of GPU PME Force sender - * \param[in] d_f force buffer in GPU memory - */ - void sendForceBufferAddressToPpRanks(rvec *d_f); + /*! \brief + * Initialization of GPU PME Force sender + * \param[in] d_f force buffer in GPU memory + */ + void sendForceBufferAddressToPpRanks(rvec* d_f); - /*! \brief - * Send PP data to PP rank - * \param[in] ppRank PP rank to receive data - */ - void sendFToPpCudaDirect(int ppRank); - - private: - class Impl; - gmx::PrivateImplPointer impl_; + /*! \brief + * Send PP data to PP rank + * \param[in] ppRank PP rank to receive data + */ + void sendFToPpCudaDirect(int ppRank); +private: + class Impl; + gmx::PrivateImplPointer impl_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/ewald/pme_force_sender_gpu_impl.cpp b/src/gromacs/ewald/pme_force_sender_gpu_impl.cpp old mode 100755 new mode 100644 index 3279c6279d..0877beecf9 --- a/src/gromacs/ewald/pme_force_sender_gpu_impl.cpp +++ b/src/gromacs/ewald/pme_force_sender_gpu_impl.cpp @@ -61,25 +61,33 @@ class PmeForceSenderGpu::Impl }; /*!\brief Constructor stub. */ -PmeForceSenderGpu::PmeForceSenderGpu(void gmx_unused *pmeStream, MPI_Comm gmx_unused comm, gmx::ArrayRef gmx_unused ppRanks) - : impl_(nullptr) +PmeForceSenderGpu::PmeForceSenderGpu(void gmx_unused* pmeStream, + MPI_Comm gmx_unused comm, + gmx::ArrayRef gmx_unused ppRanks) : + impl_(nullptr) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } PmeForceSenderGpu::~PmeForceSenderGpu() = default; /*!\brief init PME-PP GPU communication stub */ -void PmeForceSenderGpu::sendForceBufferAddressToPpRanks(rvec gmx_unused *d_f) +void PmeForceSenderGpu::sendForceBufferAddressToPpRanks(rvec gmx_unused* d_f) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication initialization was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication initialization was called instead of the " + "correct implementation."); } void PmeForceSenderGpu::sendFToPpCudaDirect(int gmx_unused ppRank) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } -} // namespace gmx +} // namespace gmx #endif /* GMX_GPU != GMX_GPU_CUDA */ diff --git a/src/gromacs/ewald/pme_force_sender_gpu_impl.cu b/src/gromacs/ewald/pme_force_sender_gpu_impl.cu index 03218b4cf5..73a7c19c91 100644 --- a/src/gromacs/ewald/pme_force_sender_gpu_impl.cu +++ b/src/gromacs/ewald/pme_force_sender_gpu_impl.cu @@ -55,34 +55,34 @@ namespace gmx { /*! \brief Create PME-PP GPU communication object */ -PmeForceSenderGpu::Impl::Impl(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) - : pmeStream_(*static_cast (pmeStream)), - comm_(comm), - ppRanks_(ppRanks) +PmeForceSenderGpu::Impl::Impl(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) : + pmeStream_(*static_cast(pmeStream)), + comm_(comm), + ppRanks_(ppRanks) { - GMX_RELEASE_ASSERT(GMX_THREAD_MPI, "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); + GMX_RELEASE_ASSERT( + GMX_THREAD_MPI, + "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); } PmeForceSenderGpu::Impl::~Impl() = default; /*! \brief sends force buffer address to PP ranks */ -void PmeForceSenderGpu::Impl::sendForceBufferAddressToPpRanks(rvec *d_f) +void PmeForceSenderGpu::Impl::sendForceBufferAddressToPpRanks(rvec* d_f) { int ind_start = 0; int ind_end = 0; - for (const auto &receiver : ppRanks_) + for (const auto& receiver : ppRanks_) { ind_start = ind_end; ind_end = ind_start + receiver.numAtoms; - //Data will be transferred directly from GPU. - void* sendBuf = reinterpret_cast (&d_f[ind_start]); + // Data will be transferred directly from GPU. + void* sendBuf = reinterpret_cast(&d_f[ind_start]); #if GMX_MPI - MPI_Send(&sendBuf, sizeof(void**), MPI_BYTE, receiver.rankId, - 0, comm_); + MPI_Send(&sendBuf, sizeof(void**), MPI_BYTE, receiver.rankId, 0, comm_); #endif - } } @@ -93,18 +93,16 @@ void PmeForceSenderGpu::Impl::sendFToPpCudaDirect(int ppRank) // Record and send event to ensure PME force calcs are completed before PP task pulls data pmeSync_.markEvent(pmeStream_); - GpuEventSynchronizer *pmeSyncPtr = &pmeSync_; + GpuEventSynchronizer* pmeSyncPtr = &pmeSync_; #if GMX_MPI // TODO Using MPI_Isend would be more efficient, particularly when // sending to multiple PP ranks - MPI_Send(&pmeSyncPtr, sizeof(GpuEventSynchronizer*), MPI_BYTE, ppRank, - 0, comm_); + MPI_Send(&pmeSyncPtr, sizeof(GpuEventSynchronizer*), MPI_BYTE, ppRank, 0, comm_); #endif - } -PmeForceSenderGpu::PmeForceSenderGpu(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) - : impl_(new Impl(pmeStream, comm, ppRanks)) +PmeForceSenderGpu::PmeForceSenderGpu(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks) : + impl_(new Impl(pmeStream, comm, ppRanks)) { } @@ -121,4 +119,4 @@ void PmeForceSenderGpu::sendFToPpCudaDirect(int ppRank) } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/ewald/pme_force_sender_gpu_impl.h b/src/gromacs/ewald/pme_force_sender_gpu_impl.h index 1cfa8c298a..4ba9702fa1 100644 --- a/src/gromacs/ewald/pme_force_sender_gpu_impl.h +++ b/src/gromacs/ewald/pme_force_sender_gpu_impl.h @@ -55,36 +55,36 @@ namespace gmx class PmeForceSenderGpu::Impl { - public: - /*! \brief Creates PME GPU Force sender object - * \param[in] pmeStream CUDA stream used for PME computations - * \param[in] comm Communicator used for simulation - * \param[in] ppRanks List of PP ranks - */ - Impl(void *pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); - ~Impl(); +public: + /*! \brief Creates PME GPU Force sender object + * \param[in] pmeStream CUDA stream used for PME computations + * \param[in] comm Communicator used for simulation + * \param[in] ppRanks List of PP ranks + */ + Impl(void* pmeStream, MPI_Comm comm, gmx::ArrayRef ppRanks); + ~Impl(); - /*! \brief - * sends force buffer address to PP rank - * \param[in] d_f force buffer in GPU memory - */ - void sendForceBufferAddressToPpRanks(rvec *d_f); + /*! \brief + * sends force buffer address to PP rank + * \param[in] d_f force buffer in GPU memory + */ + void sendForceBufferAddressToPpRanks(rvec* d_f); - /*! \brief - * Send PP data to PP rank - * \param[in] ppRank PP rank to receive data - */ - void sendFToPpCudaDirect(int ppRank); + /*! \brief + * Send PP data to PP rank + * \param[in] ppRank PP rank to receive data + */ + void sendFToPpCudaDirect(int ppRank); - private: - //! CUDA stream for PME operations - cudaStream_t pmeStream_ = nullptr; - //! Event triggered when to allow remote PP stream to syn with pme stream - GpuEventSynchronizer pmeSync_; - //! communicator for simulation - MPI_Comm comm_; - //! list of PP ranks - gmx::ArrayRef ppRanks_; +private: + //! CUDA stream for PME operations + cudaStream_t pmeStream_ = nullptr; + //! Event triggered when to allow remote PP stream to syn with pme stream + GpuEventSynchronizer pmeSync_; + //! communicator for simulation + MPI_Comm comm_; + //! list of PP ranks + gmx::ArrayRef ppRanks_; }; } // namespace gmx diff --git a/src/gromacs/ewald/pme_gather.clh b/src/gromacs/ewald/pme_gather.clh index 52ed41d70f..3b760e9d02 100644 --- a/src/gromacs/ewald/pme_gather.clh +++ b/src/gromacs/ewald/pme_gather.clh @@ -55,13 +55,12 @@ #include "pme_gpu_utils.clh" #ifndef COMPILE_GATHER_HELPERS_ONCE -#define COMPILE_GATHER_HELPERS_ONCE +# define COMPILE_GATHER_HELPERS_ONCE /*! \brief * Unrolls the dynamic index accesses to the constant grid sizes to avoid local memory operations. */ -inline float read_grid_size(const float *realGridSizeFP, - const int dimIndex) +inline float read_grid_size(const float* realGridSizeFP, const int dimIndex) { switch (dimIndex) { @@ -90,47 +89,46 @@ inline float read_grid_size(const float *realGridSizeFP, * \param[in,out] sm_forceReduction Reduction working buffer * \param[in] sm_forceTemp Convenience pointers into \p sm_forceReduction */ -inline void reduce_atom_forces(__local float * __restrict__ sm_forces, - const int atomIndexLocal, - const int splineIndex, - const int lineIndex, - const float *realGridSizeFP, - float fx, - float fy, - float fz, - __local float * __restrict__ sm_forceReduction, - __local float ** __restrict__ sm_forceTemp - ) +inline void reduce_atom_forces(__local float* __restrict__ sm_forces, + const int atomIndexLocal, + const int splineIndex, + const int lineIndex, + const float* realGridSizeFP, + float fx, + float fy, + float fz, + __local float* __restrict__ sm_forceReduction, + __local float** __restrict__ sm_forceTemp) { // TODO: implement AMD intrinsics reduction, like with shuffles in CUDA version. #2514 /* Number of data components and threads for a single atom */ -#define atomDataSize threadsPerAtom +# define atomDataSize threadsPerAtom // We use blockSize local memory elements to read fx, or fy, or fz, and then reduce them to fit into smemPerDim elements // All those guys are defines and not consts, because they go into the local memory array size. -#define blockSize (atomsPerBlock * atomDataSize) -#define smemPerDim warp_size -#define smemReserved (DIM * smemPerDim) +# define blockSize (atomsPerBlock * atomDataSize) +# define smemPerDim warp_size +# define smemReserved (DIM * smemPerDim) const int numWarps = blockSize / smemPerDim; const int minStride = max(1, atomDataSize / numWarps); -#pragma unroll DIM +# pragma unroll DIM for (int dimIndex = 0; dimIndex < DIM; dimIndex++) { int elementIndex = smemReserved + lineIndex; // Store input force contributions sm_forceReduction[elementIndex] = (dimIndex == XX) ? fx : (dimIndex == YY) ? fy : fz; -#if (warp_size < 48) +# if (warp_size < 48) // sync here when exec width is smaller than the size of the sm_forceReduction // buffer flushed to local mem above (size 3*16) as different warps will consume // the data below. barrier(CLK_LOCAL_MEM_FENCE); -#endif +# endif // Reduce to fit into smemPerDim (warp size) -#pragma unroll +# pragma unroll for (int redStride = atomDataSize >> 1; redStride > minStride; redStride >>= 1) { if (splineIndex < redStride) @@ -141,24 +139,25 @@ inline void reduce_atom_forces(__local float * __restrict__ sm_forces, barrier(CLK_LOCAL_MEM_FENCE); // Last iteration - packing everything to be nearby, storing convenience pointer sm_forceTemp[dimIndex] = sm_forceReduction + dimIndex * smemPerDim; - int redStride = minStride; + int redStride = minStride; if (splineIndex < redStride) { const int packedIndex = atomIndexLocal * redStride + splineIndex; - sm_forceTemp[dimIndex][packedIndex] = sm_forceReduction[elementIndex] + sm_forceReduction[elementIndex + redStride]; + sm_forceTemp[dimIndex][packedIndex] = + sm_forceReduction[elementIndex] + sm_forceReduction[elementIndex + redStride]; } // barrier only needed for the last iteration on hardware with >=64-wide execution (e.g. AMD) -#if (warp_size < 64) +# if (warp_size < 64) barrier(CLK_LOCAL_MEM_FENCE); -#endif +# endif } -#if (warp_size >= 64) +# if (warp_size >= 64) barrier(CLK_LOCAL_MEM_FENCE); -#endif +# endif - assert ((blockSize / warp_size) >= DIM); + assert((blockSize / warp_size) >= DIM); const int warpIndex = lineIndex / warp_size; const int dimIndex = warpIndex; @@ -167,7 +166,7 @@ inline void reduce_atom_forces(__local float * __restrict__ sm_forces, if (dimIndex < DIM) { const int sourceIndex = lineIndex % warp_size; -#pragma unroll +# pragma unroll for (int redStride = minStride >> 1; redStride > 1; redStride >>= 1) { if (!(splineIndex & redStride)) @@ -180,12 +179,13 @@ inline void reduce_atom_forces(__local float * __restrict__ sm_forces, const int atomIndex = sourceIndex / minStride; if (sourceIndex == minStride * atomIndex) { - sm_forces[atomIndex * DIM + dimIndex] = (sm_forceTemp[dimIndex][sourceIndex] + sm_forceTemp[dimIndex][sourceIndex + 1]) * n; + sm_forces[atomIndex * DIM + dimIndex] = + (sm_forceTemp[dimIndex][sourceIndex] + sm_forceTemp[dimIndex][sourceIndex + 1]) * n; } } } -#endif //COMPILE_GATHER_HELPERS_ONCE +#endif // COMPILE_GATHER_HELPERS_ONCE /*! \brief * An OpenCL kernel which gathers the atom forces from the grid. @@ -201,46 +201,49 @@ inline void reduce_atom_forces(__local float * __restrict__ sm_forces, * \param[in,out] gm_forces Atom forces (rvec) */ __attribute__((reqd_work_group_size(order, order, atomsPerBlock))) -__kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKernelParams kernelParams, - __global const float * __restrict__ gm_coefficients, - __global const float * __restrict__ gm_grid, - __global const float * __restrict__ gm_theta, - __global const float * __restrict__ gm_dtheta, - __global const int * __restrict__ gm_gridlineIndices, - __global float * __restrict__ gm_forces - ) +__kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKernelParams kernelParams, + __global const float* __restrict__ gm_coefficients, + __global const float* __restrict__ gm_grid, + __global const float* __restrict__ gm_theta, + __global const float* __restrict__ gm_dtheta, + __global const int* __restrict__ gm_gridlineIndices, + __global float* __restrict__ gm_forces) { /* These are the atom indices - for the shared and global memory */ - const int atomIndexLocal = get_local_id(ZZ); - const int atomIndexOffset = get_group_id(XX) * atomsPerBlock; - const int atomIndexGlobal = atomIndexOffset + atomIndexLocal; + const int atomIndexLocal = get_local_id(ZZ); + const int atomIndexOffset = get_group_id(XX) * atomsPerBlock; + const int atomIndexGlobal = atomIndexOffset + atomIndexLocal; - /* Some sizes which are defines and not consts because they go into the array size */ - #define blockSize (atomsPerBlock * atomDataSize) +/* Some sizes which are defines and not consts because they go into the array size */ +#define blockSize (atomsPerBlock * atomDataSize) assert(blockSize == (get_local_size(0) * get_local_size(1) * get_local_size(2))); - #define smemPerDim warp_size - #define smemReserved (DIM * smemPerDim) - #define totalSharedMemory (smemReserved + blockSize) - #define gridlineIndicesSize (atomsPerBlock * DIM) - #define splineParamsSize (atomsPerBlock * DIM * order) +#define smemPerDim warp_size +#define smemReserved (DIM * smemPerDim) +#define totalSharedMemory (smemReserved + blockSize) +#define gridlineIndicesSize (atomsPerBlock * DIM) +#define splineParamsSize (atomsPerBlock * DIM * order) - __local int sm_gridlineIndices[gridlineIndicesSize]; + __local int sm_gridlineIndices[gridlineIndicesSize]; __local float2 sm_splineParams[splineParamsSize]; /* Theta/dtheta pairs as .x/.y */ /* Spline Y/Z coordinates */ const int ithy = get_local_id(YY); const int ithz = get_local_id(XX); - const int threadLocalId = (get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0); + const int threadLocalId = (get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + + get_local_id(0); /* These are the spline contribution indices in shared memory */ - const int splineIndex = (get_local_id(1) * get_local_size(0) + get_local_id(0)); /* Relative to the current particle , 0..15 for order 4 */ - const int lineIndex = threadLocalId; /* And to all the block's particles */ + const int splineIndex = (get_local_id(1) * get_local_size(0) + + get_local_id(0)); /* Relative to the current particle , 0..15 for order 4 */ + const int lineIndex = threadLocalId; /* And to all the block's particles */ /* Staging the atom gridline indices, DIM * atomsPerBlock threads */ - const int localGridlineIndicesIndex = threadLocalId; - const int globalGridlineIndicesIndex = get_group_id(XX) * gridlineIndicesSize + localGridlineIndicesIndex; - const int globalCheckIndices = pme_gpu_check_atom_data_index(globalGridlineIndicesIndex, kernelParams.atoms.nAtoms * DIM); + const int localGridlineIndicesIndex = threadLocalId; + const int globalGridlineIndicesIndex = + get_group_id(XX) * gridlineIndicesSize + localGridlineIndicesIndex; + const int globalCheckIndices = + pme_gpu_check_atom_data_index(globalGridlineIndicesIndex, kernelParams.atoms.nAtoms * DIM); if ((localGridlineIndicesIndex < gridlineIndicesSize) & globalCheckIndices) { sm_gridlineIndices[localGridlineIndicesIndex] = gm_gridlineIndices[globalGridlineIndicesIndex]; @@ -249,7 +252,8 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe /* Staging the spline parameters, DIM * order * atomsPerBlock threads */ const int localSplineParamsIndex = threadLocalId; const int globalSplineParamsIndex = get_group_id(XX) * splineParamsSize + localSplineParamsIndex; - const int globalCheckSplineParams = pme_gpu_check_atom_data_index(globalSplineParamsIndex, kernelParams.atoms.nAtoms * DIM * order); + const int globalCheckSplineParams = pme_gpu_check_atom_data_index( + globalSplineParamsIndex, kernelParams.atoms.nAtoms * DIM * order); if ((localSplineParamsIndex < splineParamsSize) && globalCheckSplineParams) { sm_splineParams[localSplineParamsIndex].x = gm_theta[globalSplineParamsIndex]; @@ -259,23 +263,23 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe } barrier(CLK_LOCAL_MEM_FENCE); - float fx = 0.0f; - float fy = 0.0f; - float fz = 0.0f; + float fx = 0.0f; + float fy = 0.0f; + float fz = 0.0f; - const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); - const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficients[atomIndexGlobal]); + const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); + const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficients[atomIndexGlobal]); if (chargeCheck & globalCheck) { - const int nx = kernelParams.grid.realGridSize[XX]; - const int ny = kernelParams.grid.realGridSize[YY]; - const int nz = kernelParams.grid.realGridSize[ZZ]; - const int pny = kernelParams.grid.realGridSizePadded[YY]; - const int pnz = kernelParams.grid.realGridSizePadded[ZZ]; + const int nx = kernelParams.grid.realGridSize[XX]; + const int ny = kernelParams.grid.realGridSize[YY]; + const int nz = kernelParams.grid.realGridSize[ZZ]; + const int pny = kernelParams.grid.realGridSizePadded[YY]; + const int pnz = kernelParams.grid.realGridSizePadded[ZZ]; - const int atomWarpIndex = atomIndexLocal % atomsPerWarp; - const int warpIndex = atomIndexLocal / atomsPerWarp; + const int atomWarpIndex = atomIndexLocal % atomsPerWarp; + const int warpIndex = atomIndexLocal / atomsPerWarp; const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); @@ -283,18 +287,18 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); const float2 tdz = sm_splineParams[splineIndexZ]; - const int ixBase = sm_gridlineIndices[atomIndexLocal * DIM + XX]; - int iy = sm_gridlineIndices[atomIndexLocal * DIM + YY] + ithy; + const int ixBase = sm_gridlineIndices[atomIndexLocal * DIM + XX]; + int iy = sm_gridlineIndices[atomIndexLocal * DIM + YY] + ithy; if (wrapY & (iy >= ny)) { iy -= ny; } - int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] + ithz; + int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] + ithz; if (iz >= nz) { iz -= nz; } - const int constOffset = iy * pnz + iz; + const int constOffset = iy * pnz + iz; #pragma unroll order for (int ithx = 0; (ithx < order); ithx++) @@ -304,14 +308,14 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe { ix -= nx; } - const int gridIndexGlobal = ix * pny * pnz + constOffset; + const int gridIndexGlobal = ix * pny * pnz + constOffset; assert(gridIndexGlobal >= 0); - const float gridValue = gm_grid[gridIndexGlobal]; + const float gridValue = gm_grid[gridIndexGlobal]; assert(isfinite(gridValue)); - const int splineIndexX = getSplineParamIndex(splineIndexBase, XX, ithx); - const float2 tdx = sm_splineParams[splineIndexX]; - const float fxy1 = tdz.x * gridValue; - const float fz1 = tdz.y * gridValue; + const int splineIndexX = getSplineParamIndex(splineIndexBase, XX, ithx); + const float2 tdx = sm_splineParams[splineIndexX]; + const float fxy1 = tdz.x * gridValue; + const float fz1 = tdz.y * gridValue; fx += tdx.y * tdy.x * fxy1; fy += tdx.x * tdy.y * fxy1; fz += tdx.x * tdy.x * fz1; @@ -319,40 +323,38 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe } // Reduction of partial force contributions - __local float sm_forces[atomsPerBlock * DIM]; + __local float sm_forces[atomsPerBlock * DIM]; __local float sm_forceReduction[totalSharedMemory]; - __local float *sm_forceTemp[DIM]; - - reduce_atom_forces(sm_forces, - atomIndexLocal, splineIndex, lineIndex, - kernelParams.grid.realGridSizeFP, - fx, fy, fz, - sm_forceReduction, - sm_forceTemp); + __local float* sm_forceTemp[DIM]; + + reduce_atom_forces(sm_forces, atomIndexLocal, splineIndex, lineIndex, + kernelParams.grid.realGridSizeFP, fx, fy, fz, sm_forceReduction, sm_forceTemp); barrier(CLK_LOCAL_MEM_FENCE); /* Calculating the final forces with no component branching, atomsPerBlock threads */ const int forceIndexLocal = threadLocalId; const int forceIndexGlobal = atomIndexOffset + forceIndexLocal; - const int calcIndexCheck = pme_gpu_check_atom_data_index(forceIndexGlobal, kernelParams.atoms.nAtoms); + const int calcIndexCheck = pme_gpu_check_atom_data_index(forceIndexGlobal, kernelParams.atoms.nAtoms); if ((forceIndexLocal < atomsPerBlock) & calcIndexCheck) { - const float3 atomForces = vload3(forceIndexLocal, sm_forces); - const float negCoefficient = -gm_coefficients[forceIndexGlobal]; - float3 result; - result.x = negCoefficient * kernelParams.current.recipBox[XX][XX] * atomForces.x; - result.y = negCoefficient * (kernelParams.current.recipBox[XX][YY] * atomForces.x + - kernelParams.current.recipBox[YY][YY] * atomForces.y); - result.z = negCoefficient * (kernelParams.current.recipBox[XX][ZZ] * atomForces.x + - kernelParams.current.recipBox[YY][ZZ] * atomForces.y + - kernelParams.current.recipBox[ZZ][ZZ] * atomForces.z); + const float3 atomForces = vload3(forceIndexLocal, sm_forces); + const float negCoefficient = -gm_coefficients[forceIndexGlobal]; + float3 result; + result.x = negCoefficient * kernelParams.current.recipBox[XX][XX] * atomForces.x; + result.y = negCoefficient + * (kernelParams.current.recipBox[XX][YY] * atomForces.x + + kernelParams.current.recipBox[YY][YY] * atomForces.y); + result.z = negCoefficient + * (kernelParams.current.recipBox[XX][ZZ] * atomForces.x + + kernelParams.current.recipBox[YY][ZZ] * atomForces.y + + kernelParams.current.recipBox[ZZ][ZZ] * atomForces.z); vstore3(result, forceIndexLocal, sm_forces); } #if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_) - /* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was __syncwarp() in CUDA. - * #2519 + /* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was + * __syncwarp() in CUDA. #2519 */ barrier(CLK_LOCAL_MEM_FENCE); #endif @@ -370,7 +372,8 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_gather_kernel)(const struct PmeOpenCLKe { const int outputIndexLocal = i * iterThreads + threadLocalId; const int outputIndexGlobal = get_group_id(XX) * blockForcesSize + outputIndexLocal; - const int globalOutputCheck = pme_gpu_check_atom_data_index(outputIndexGlobal, kernelParams.atoms.nAtoms * DIM); + const int globalOutputCheck = + pme_gpu_check_atom_data_index(outputIndexGlobal, kernelParams.atoms.nAtoms * DIM); if (globalOutputCheck) { const float outputForceComponent = sm_forces[outputIndexLocal]; diff --git a/src/gromacs/ewald/pme_gather.cpp b/src/gromacs/ewald/pme_gather.cpp index d4cc6772ef..315cb3aefb 100644 --- a/src/gromacs/ewald/pme_gather.cpp +++ b/src/gromacs/ewald/pme_gather.cpp @@ -76,81 +76,85 @@ using namespace gmx; // TODO: Remove when this file is moved into gmx namespace */ struct do_fspline { - do_fspline ( - const gmx_pme_t * pme, - const real * gmx_restrict grid, - const PmeAtomComm * gmx_restrict atc, - const splinedata_t * gmx_restrict spline, - int nn) - : pme(pme), grid(grid), atc(atc), spline(spline), nn(nn) {} - - template + do_fspline(const gmx_pme_t* pme, + const real* gmx_restrict grid, + const PmeAtomComm* gmx_restrict atc, + const splinedata_t* gmx_restrict spline, + int nn) : + pme(pme), + grid(grid), + atc(atc), + spline(spline), + nn(nn) + { + } + + template RVec operator()(Int order) const { static_assert(isIntegralConstant::value || std::is_same::value, "'order' needs to be either of type integral_constant or int."); - const int norder = nn*order; + const int norder = nn * order; /* Pointer arithmetic alert, next six statements */ - const real *const gmx_restrict thx = spline->theta.coefficients[XX] + norder; - const real *const gmx_restrict thy = spline->theta.coefficients[YY] + norder; - const real *const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; - const real *const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; - const real *const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; - const real *const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; + const real* const gmx_restrict thx = spline->theta.coefficients[XX] + norder; + const real* const gmx_restrict thy = spline->theta.coefficients[YY] + norder; + const real* const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; + const real* const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; + const real* const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; + const real* const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; - RVec f(0, 0, 0); + RVec f(0, 0, 0); for (int ithx = 0; (ithx < order); ithx++) { - const int index_x = (idxX + ithx)*gridNY*gridNZ; + const int index_x = (idxX + ithx) * gridNY * gridNZ; const real tx = thx[ithx]; const real dx = dthx[ithx]; for (int ithy = 0; (ithy < order); ithy++) { - const int index_xy = index_x + (idxY + ithy)*gridNZ; + const int index_xy = index_x + (idxY + ithy) * gridNZ; const real ty = thy[ithy]; const real dy = dthy[ithy]; - real fxy1 = 0, fz1 = 0; + real fxy1 = 0, fz1 = 0; for (int ithz = 0; (ithz < order); ithz++) { const real gval = grid[index_xy + (idxZ + ithz)]; - fxy1 += thz[ithz]*gval; - fz1 += dthz[ithz]*gval; + fxy1 += thz[ithz] * gval; + fz1 += dthz[ithz] * gval; } - f[XX] += dx*ty*fxy1; - f[YY] += tx*dy*fxy1; - f[ZZ] += tx*ty*fz1; + f[XX] += dx * ty * fxy1; + f[YY] += tx * dy * fxy1; + f[ZZ] += tx * ty * fz1; } } return f; } -//TODO: Consider always have at least a dummy implementation of Simd (enough for first phase of two-phase lookup) and then use enable_if instead of #ifdef +// TODO: Consider always have at least a dummy implementation of Simd (enough for first phase of two-phase lookup) and then use enable_if instead of #ifdef #if PME_4NSIMD_GATHER -/* Gather for one charge with pme_order=4 with unaligned SIMD4 load+store. - * Uses 4N SIMD where N is SIMD_WIDTH/4 to operate on all of z and N of y. - * This code does not assume any memory alignment for the grid. - */ - RVec - operator()(std::integral_constant /*unused*/) const + /* Gather for one charge with pme_order=4 with unaligned SIMD4 load+store. + * Uses 4N SIMD where N is SIMD_WIDTH/4 to operate on all of z and N of y. + * This code does not assume any memory alignment for the grid. + */ + RVec operator()(std::integral_constant /*unused*/) const { - const int norder = nn*4; + const int norder = nn * 4; /* Pointer arithmetic alert, next six statements */ - const real *const gmx_restrict thx = spline->theta.coefficients[XX] + norder; - const real *const gmx_restrict thy = spline->theta.coefficients[YY] + norder; - const real *const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; - const real *const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; - const real *const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; - const real *const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; + const real* const gmx_restrict thx = spline->theta.coefficients[XX] + norder; + const real* const gmx_restrict thy = spline->theta.coefficients[YY] + norder; + const real* const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; + const real* const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; + const real* const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; + const real* const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; - Simd4NReal fx_S = setZero(); - Simd4NReal fy_S = setZero(); - Simd4NReal fz_S = setZero(); + Simd4NReal fx_S = setZero(); + Simd4NReal fy_S = setZero(); + Simd4NReal fz_S = setZero(); /* With order 4 the z-spline is actually aligned */ const Simd4NReal tz_S = load4DuplicateN(thz); @@ -158,18 +162,18 @@ struct do_fspline for (int ithx = 0; ithx < 4; ithx++) { - const int index_x = (idxX + ithx)*gridNY*gridNZ; + const int index_x = (idxX + ithx) * gridNY * gridNZ; const Simd4NReal tx_S = Simd4NReal(thx[ithx]); const Simd4NReal dx_S = Simd4NReal(dthx[ithx]); - for (int ithy = 0; ithy < 4; ithy += GMX_SIMD4N_REAL_WIDTH/4) + for (int ithy = 0; ithy < 4; ithy += GMX_SIMD4N_REAL_WIDTH / 4) { - const int index_xy = index_x + (idxY+ithy)*gridNZ; + const int index_xy = index_x + (idxY + ithy) * gridNZ; - const Simd4NReal ty_S = loadUNDuplicate4(thy +ithy); - const Simd4NReal dy_S = loadUNDuplicate4(dthy+ithy); + const Simd4NReal ty_S = loadUNDuplicate4(thy + ithy); + const Simd4NReal dy_S = loadUNDuplicate4(dthy + ithy); - const Simd4NReal gval_S = loadU4NOffset(grid+index_xy+idxZ, gridNZ); + const Simd4NReal gval_S = loadU4NOffset(grid + index_xy + idxZ, gridNZ); const Simd4NReal fxy1_S = tz_S * gval_S; @@ -181,63 +185,65 @@ struct do_fspline } } - return { - reduce(fx_S), reduce(fy_S), reduce(fz_S) - }; + return { reduce(fx_S), reduce(fy_S), reduce(fz_S) }; } #endif #ifdef PME_SIMD4_SPREAD_GATHER -/* Load order elements from unaligned memory into two 4-wide SIMD */ + /* Load order elements from unaligned memory into two 4-wide SIMD */ template - static inline void loadOrderU(const real* data, std::integral_constant /*unused*/, - int offset, Simd4Real* S0, Simd4Real* S1) + static inline void loadOrderU(const real* data, + std::integral_constant /*unused*/, + int offset, + Simd4Real* S0, + Simd4Real* S1) { -#ifdef PME_SIMD4_UNALIGNED - *S0 = load4U(data-offset); - *S1 = load4U(data-offset+4); -#else - alignas(GMX_SIMD_ALIGNMENT) real buf_aligned[GMX_SIMD4_WIDTH*2]; +# ifdef PME_SIMD4_UNALIGNED + *S0 = load4U(data - offset); + *S1 = load4U(data - offset + 4); +# else + alignas(GMX_SIMD_ALIGNMENT) real buf_aligned[GMX_SIMD4_WIDTH * 2]; /* Copy data to an aligned buffer */ for (int i = 0; i < order; i++) { - buf_aligned[offset+i] = data[i]; + buf_aligned[offset + i] = data[i]; } *S0 = load4(buf_aligned); - *S1 = load4(buf_aligned+4); -#endif + *S1 = load4(buf_aligned + 4); +# endif } #endif #ifdef PME_SIMD4_SPREAD_GATHER -/* This code assumes that the grid is allocated 4-real aligned - * and that pme->pmegrid_nz is a multiple of 4. - * This code supports pme_order <= 5. - */ - template - std::enable_if_t - operator()(std::integral_constant order) const + /* This code assumes that the grid is allocated 4-real aligned + * and that pme->pmegrid_nz is a multiple of 4. + * This code supports pme_order <= 5. + */ + template + std::enable_if_t operator()(std::integral_constant order) const { - const int norder = nn*order; - GMX_ASSERT(gridNZ % 4 == 0, "For aligned SIMD4 operations the grid size has to be padded up to a multiple of 4"); + const int norder = nn * order; + GMX_ASSERT(gridNZ % 4 == 0, + "For aligned SIMD4 operations the grid size has to be padded up to a multiple " + "of 4"); /* Pointer arithmetic alert, next six statements */ - const real *const gmx_restrict thx = spline->theta.coefficients[XX] + norder; - const real *const gmx_restrict thy = spline->theta.coefficients[YY] + norder; - const real *const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; - const real *const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; - const real *const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; - const real *const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; + const real* const gmx_restrict thx = spline->theta.coefficients[XX] + norder; + const real* const gmx_restrict thy = spline->theta.coefficients[YY] + norder; + const real* const gmx_restrict thz = spline->theta.coefficients[ZZ] + norder; + const real* const gmx_restrict dthx = spline->dtheta.coefficients[XX] + norder; + const real* const gmx_restrict dthy = spline->dtheta.coefficients[YY] + norder; + const real* const gmx_restrict dthz = spline->dtheta.coefficients[ZZ] + norder; - struct pme_spline_work *const work = pme->spline_work; + struct pme_spline_work* const work = pme->spline_work; - const int offset = idxZ & 3; + const int offset = idxZ & 3; - Simd4Real fx_S = setZero(); - Simd4Real fy_S = setZero(); - Simd4Real fz_S = setZero(); + Simd4Real fx_S = setZero(); + Simd4Real fy_S = setZero(); + Simd4Real fz_S = setZero(); - Simd4Real tz_S0, tz_S1, dz_S0, dz_S1; - loadOrderU(thz, order, offset, &tz_S0, &tz_S1); + Simd4Real tz_S0, tz_S1, dz_S0, dz_S1; + loadOrderU(thz, order, offset, &tz_S0, &tz_S1); loadOrderU(dthz, order, offset, &dz_S0, &dz_S1); tz_S0 = selectByMask(tz_S0, work->mask_S0[offset]); @@ -247,13 +253,13 @@ struct do_fspline for (int ithx = 0; (ithx < order); ithx++) { - const int index_x = (idxX + ithx)*gridNY*gridNZ; - const Simd4Real tx_S = Simd4Real(thx[ithx]); - const Simd4Real dx_S = Simd4Real(dthx[ithx]); + const int index_x = (idxX + ithx) * gridNY * gridNZ; + const Simd4Real tx_S = Simd4Real(thx[ithx]); + const Simd4Real dx_S = Simd4Real(dthx[ithx]); for (int ithy = 0; (ithy < order); ithy++) { - const int index_xy = index_x + (idxY + ithy)*gridNZ; + const int index_xy = index_x + (idxY + ithy) * gridNZ; const Simd4Real ty_S = Simd4Real(thy[ithy]); const Simd4Real dy_S = Simd4Real(dthy[ithy]); @@ -274,49 +280,49 @@ struct do_fspline } } - return { - reduce(fx_S), reduce(fy_S), reduce(fz_S) - }; + return { reduce(fx_S), reduce(fy_S), reduce(fz_S) }; } #endif - private: - const gmx_pme_t *const pme; - const real *const gmx_restrict grid; - const PmeAtomComm *const gmx_restrict atc; - const splinedata_t *const gmx_restrict spline; - const int nn; - - const int gridNY = pme->pmegrid_ny; - const int gridNZ = pme->pmegrid_nz; - - const int *const idxptr = atc->idx[spline->ind[nn]]; - const int idxX = idxptr[XX]; - const int idxY = idxptr[YY]; - const int idxZ = idxptr[ZZ]; +private: + const gmx_pme_t* const pme; + const real* const gmx_restrict grid; + const PmeAtomComm* const gmx_restrict atc; + const splinedata_t* const gmx_restrict spline; + const int nn; + + const int gridNY = pme->pmegrid_ny; + const int gridNZ = pme->pmegrid_nz; + + const int* const idxptr = atc->idx[spline->ind[nn]]; + const int idxX = idxptr[XX]; + const int idxY = idxptr[YY]; + const int idxZ = idxptr[ZZ]; }; -void gather_f_bsplines(const gmx_pme_t *pme, const real *grid, - gmx_bool bClearF, const PmeAtomComm *atc, - const splinedata_t *spline, - real scale) +void gather_f_bsplines(const gmx_pme_t* pme, + const real* grid, + gmx_bool bClearF, + const PmeAtomComm* atc, + const splinedata_t* spline, + real scale) { /* sum forces for local particles */ - const int order = pme->pme_order; - const int nx = pme->nkx; - const int ny = pme->nky; - const int nz = pme->nkz; + const int order = pme->pme_order; + const int nx = pme->nkx; + const int ny = pme->nky; + const int nz = pme->nkz; - const real rxx = pme->recipbox[XX][XX]; - const real ryx = pme->recipbox[YY][XX]; - const real ryy = pme->recipbox[YY][YY]; - const real rzx = pme->recipbox[ZZ][XX]; - const real rzy = pme->recipbox[ZZ][YY]; - const real rzz = pme->recipbox[ZZ][ZZ]; + const real rxx = pme->recipbox[XX][XX]; + const real ryx = pme->recipbox[YY][XX]; + const real ryy = pme->recipbox[YY][YY]; + const real rzx = pme->recipbox[ZZ][XX]; + const real rzy = pme->recipbox[ZZ][YY]; + const real rzz = pme->recipbox[ZZ][ZZ]; /* Extract the buffer for force output */ - rvec * gmx_restrict force = as_rvec_array(atc->f.data()); + rvec* gmx_restrict force = as_rvec_array(atc->f.data()); /* Note that unrolling this loop by templating this function on order * deteriorates performance significantly with gcc5/6/7. @@ -324,7 +330,7 @@ void gather_f_bsplines(const gmx_pme_t *pme, const real *grid, for (int nn = 0; nn < spline->n; nn++) { const int n = spline->ind[nn]; - const real coefficient = scale*atc->coefficient[n]; + const real coefficient = scale * atc->coefficient[n]; if (bClearF) { @@ -339,20 +345,14 @@ void gather_f_bsplines(const gmx_pme_t *pme, const real *grid, switch (order) { - case 4: - f = spline_func(std::integral_constant()); - break; - case 5: - f = spline_func(std::integral_constant()); - break; - default: - f = spline_func(order); - break; + case 4: f = spline_func(std::integral_constant()); break; + case 5: f = spline_func(std::integral_constant()); break; + default: f = spline_func(order); break; } - force[n][XX] += -coefficient*( f[XX]*nx*rxx ); - force[n][YY] += -coefficient*( f[XX]*nx*ryx + f[YY]*ny*ryy ); - force[n][ZZ] += -coefficient*( f[XX]*nx*rzx + f[YY]*ny*rzy + f[ZZ]*nz*rzz ); + force[n][XX] += -coefficient * (f[XX] * nx * rxx); + force[n][YY] += -coefficient * (f[XX] * nx * ryx + f[YY] * ny * ryy); + force[n][ZZ] += -coefficient * (f[XX] * nx * rzx + f[YY] * ny * rzy + f[ZZ] * nz * rzz); } } /* Since the energy and not forces are interpolated @@ -367,15 +367,14 @@ void gather_f_bsplines(const gmx_pme_t *pme, const real *grid, } -real gather_energy_bsplines(gmx_pme_t *pme, const real *grid, - PmeAtomComm *atc) +real gather_energy_bsplines(gmx_pme_t* pme, const real* grid, PmeAtomComm* atc) { - splinedata_t *spline; + splinedata_t* spline; int ithx, ithy, ithz, i0, j0, k0; int index_x, index_xy; - int *idxptr; + int* idxptr; real energy, pot, tx, ty, coefficient, gval; - real *thx, *thy, *thz; + real * thx, *thy, *thz; int norder; int order; @@ -386,43 +385,42 @@ real gather_energy_bsplines(gmx_pme_t *pme, const real *grid, energy = 0; for (int n = 0; n < atc->numAtoms(); n++) { - coefficient = atc->coefficient[n]; + coefficient = atc->coefficient[n]; if (coefficient != 0) { idxptr = atc->idx[n]; - norder = n*order; + norder = n * order; - i0 = idxptr[XX]; - j0 = idxptr[YY]; - k0 = idxptr[ZZ]; + i0 = idxptr[XX]; + j0 = idxptr[YY]; + k0 = idxptr[ZZ]; /* Pointer arithmetic alert, next three statements */ - thx = spline->theta.coefficients[XX] + norder; - thy = spline->theta.coefficients[YY] + norder; - thz = spline->theta.coefficients[ZZ] + norder; + thx = spline->theta.coefficients[XX] + norder; + thy = spline->theta.coefficients[YY] + norder; + thz = spline->theta.coefficients[ZZ] + norder; pot = 0; for (ithx = 0; (ithx < order); ithx++) { - index_x = (i0+ithx)*pme->pmegrid_ny*pme->pmegrid_nz; + index_x = (i0 + ithx) * pme->pmegrid_ny * pme->pmegrid_nz; tx = thx[ithx]; for (ithy = 0; (ithy < order); ithy++) { - index_xy = index_x+(j0+ithy)*pme->pmegrid_nz; + index_xy = index_x + (j0 + ithy) * pme->pmegrid_nz; ty = thy[ithy]; for (ithz = 0; (ithz < order); ithz++) { - gval = grid[index_xy+(k0+ithz)]; - pot += tx*ty*thz[ithz]*gval; + gval = grid[index_xy + (k0 + ithz)]; + pot += tx * ty * thz[ithz] * gval; } - } } - energy += pot*coefficient; + energy += pot * coefficient; } } diff --git a/src/gromacs/ewald/pme_gather.cu b/src/gromacs/ewald/pme_gather.cu index ead734c687..8b2ff5f80e 100644 --- a/src/gromacs/ewald/pme_gather.cu +++ b/src/gromacs/ewald/pme_gather.cu @@ -53,8 +53,7 @@ /*! \brief * An inline CUDA function: unroll the dynamic index accesses to the constant grid sizes to avoid local memory operations. */ -__device__ __forceinline__ float read_grid_size(const float *realGridSizeFP, - const int dimIndex) +__device__ __forceinline__ float read_grid_size(const float* realGridSizeFP, const int dimIndex) { switch (dimIndex) { @@ -69,30 +68,23 @@ __device__ __forceinline__ float read_grid_size(const float *realGridSizeFP, /*! \brief Reduce the partial force contributions. * * \tparam[in] order The PME order (must be 4). - * \tparam[in] atomDataSize The number of partial force contributions for each atom (currently order^2 == 16) - * \tparam[in] blockSize The CUDA block size - * \param[out] sm_forces Shared memory array with the output forces (number of elements is number of atoms per block) - * \param[in] atomIndexLocal Local atom index - * \param[in] splineIndex Spline index - * \param[in] lineIndex Line index (same as threadLocalId) - * \param[in] realGridSizeFP Local grid size constant - * \param[in] fx Input force partial component X - * \param[in] fy Input force partial component Y - * \param[in] fz Input force partial component Z + * \tparam[in] atomDataSize The number of partial force contributions for each atom (currently + * order^2 == 16) \tparam[in] blockSize The CUDA block size \param[out] sm_forces Shared + * memory array with the output forces (number of elements is number of atoms per block) \param[in] + * atomIndexLocal Local atom index \param[in] splineIndex Spline index \param[in] + * lineIndex Line index (same as threadLocalId) \param[in] realGridSizeFP Local grid + * size constant \param[in] fx Input force partial component X \param[in] fy Input + * force partial component Y \param[in] fz Input force partial component Z */ -template < - const int order, - const int atomDataSize, - const int blockSize - > -__device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forces, - const int atomIndexLocal, - const int splineIndex, - const int lineIndex, - const float *realGridSizeFP, - float &fx, - float &fy, - float &fz) +template +__device__ __forceinline__ void reduce_atom_forces(float3* __restrict__ sm_forces, + const int atomIndexLocal, + const int splineIndex, + const int lineIndex, + const float* realGridSizeFP, + float& fx, + float& fy, + float& fz) { if (!(order & (order - 1))) // Only for orders of power of 2 { @@ -101,11 +93,12 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc // A tricky shuffle reduction inspired by reduce_force_j_warp_shfl // TODO: find out if this is the best in terms of transactions count static_assert(order == 4, "Only order of 4 is implemented"); - static_assert(atomDataSize <= warp_size, "TODO: rework for atomDataSize > warp_size (order 8 or larger)"); + static_assert(atomDataSize <= warp_size, + "TODO: rework for atomDataSize > warp_size (order 8 or larger)"); const int width = atomDataSize; fx += __shfl_down_sync(activeMask, fx, 1, width); - fy += __shfl_up_sync (activeMask, fy, 1, width); + fy += __shfl_up_sync(activeMask, fy, 1, width); fz += __shfl_down_sync(activeMask, fz, 1, width); if (splineIndex & 1) @@ -114,7 +107,7 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc } fx += __shfl_down_sync(activeMask, fx, 2, width); - fz += __shfl_up_sync (activeMask, fz, 2, width); + fz += __shfl_up_sync(activeMask, fz, 2, width); if (splineIndex & 2) { @@ -122,8 +115,8 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc } // By now fx contains intermediate quad sums of all 3 components: - // splineIndex 0 1 2 and 3 4 5 6 and 7 8... - // sum of... fx0 to fx3 fy0 to fy3 fz0 to fz3 fx4 to fx7 fy4 to fy7 fz4 to fz7 etc. + // splineIndex 0 1 2 and 3 4 5 6 and 7 8... + // sum of... fx0 to fx3 fy0 to fy3 fz0 to fz3 fx4 to fx7 fy4 to fy7 fz4 to fz7 etc. // We have to just further reduce those groups of 4 for (int delta = 4; delta < atomDataSize; delta <<= 1) @@ -135,20 +128,21 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc if (dimIndex < DIM) { const float n = read_grid_size(realGridSizeFP, dimIndex); - *((float *)(&sm_forces[atomIndexLocal]) + dimIndex) = fx * n; + *((float*)(&sm_forces[atomIndexLocal]) + dimIndex) = fx * n; } } else { - // We use blockSize shared memory elements to read fx, or fy, or fz, and then reduce them to fit into smemPerDim elements - // which are stored separately (first 2 dimensions only) + // We use blockSize shared memory elements to read fx, or fy, or fz, and then reduce them to + // fit into smemPerDim elements which are stored separately (first 2 dimensions only) const int smemPerDim = warp_size; - const int smemReserved = (DIM) *smemPerDim; + const int smemReserved = (DIM)*smemPerDim; __shared__ float sm_forceReduction[smemReserved + blockSize]; - __shared__ float *sm_forceTemp[DIM]; + __shared__ float* sm_forceTemp[DIM]; - const int numWarps = blockSize / smemPerDim; - const int minStride = max(1, atomDataSize / numWarps); // order 4: 128 threads => 4, 256 threads => 2, etc + const int numWarps = blockSize / smemPerDim; + const int minStride = + max(1, atomDataSize / numWarps); // order 4: 128 threads => 4, 256 threads => 2, etc #pragma unroll for (int dimIndex = 0; dimIndex < DIM; dimIndex++) @@ -170,17 +164,18 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc __syncthreads(); // Last iteration - packing everything to be nearby, storing convenience pointer sm_forceTemp[dimIndex] = sm_forceReduction + dimIndex * smemPerDim; - int redStride = minStride; + int redStride = minStride; if (splineIndex < redStride) { const int packedIndex = atomIndexLocal * redStride + splineIndex; - sm_forceTemp[dimIndex][packedIndex] = sm_forceReduction[elementIndex] + sm_forceReduction[elementIndex + redStride]; + sm_forceTemp[dimIndex][packedIndex] = + sm_forceReduction[elementIndex] + sm_forceReduction[elementIndex + redStride]; } __syncthreads(); } - assert ((blockSize / warp_size) >= DIM); - //assert (atomsPerBlock <= warp_size); + assert((blockSize / warp_size) >= DIM); + // assert (atomsPerBlock <= warp_size); const int warpIndex = lineIndex / warp_size; const int dimIndex = warpIndex; @@ -205,7 +200,8 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc if (sourceIndex == minStride * atomIndex) { - *((float *)(&sm_forces[atomIndex]) + dimIndex) = (sm_forceTemp[dimIndex][sourceIndex] + sm_forceTemp[dimIndex][sourceIndex + 1]) * n; + *((float*)(&sm_forces[atomIndex]) + dimIndex) = + (sm_forceTemp[dimIndex][sourceIndex] + sm_forceTemp[dimIndex][sourceIndex + 1]) * n; } } } @@ -224,46 +220,42 @@ __device__ __forceinline__ void reduce_atom_forces(float3 * __restrict__ sm_forc * \tparam[in] useOrderThreads Tells if we should use order threads per atom (order*order used if false) * \param[in] kernelParams All the PME GPU data. */ -template < - const int order, - const bool overwriteForces, - const bool wrapX, - const bool wrapY, - const bool readGlobal, - const bool useOrderThreads - > -__launch_bounds__(c_gatherMaxThreadsPerBlock, c_gatherMinBlocksPerMP) -__global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) +template +__launch_bounds__(c_gatherMaxThreadsPerBlock, c_gatherMinBlocksPerMP) __global__ + void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) { /* Global memory pointers */ - const float * __restrict__ gm_coefficients = kernelParams.atoms.d_coefficients; - const float * __restrict__ gm_grid = kernelParams.grid.d_realGrid; - float * __restrict__ gm_forces = kernelParams.atoms.d_forces; + const float* __restrict__ gm_coefficients = kernelParams.atoms.d_coefficients; + const float* __restrict__ gm_grid = kernelParams.grid.d_realGrid; + float* __restrict__ gm_forces = kernelParams.atoms.d_forces; /* Global memory pointers for readGlobal */ - const float * __restrict__ gm_theta = kernelParams.atoms.d_theta; - const float * __restrict__ gm_dtheta = kernelParams.atoms.d_dtheta; - const int * __restrict__ gm_gridlineIndices = kernelParams.atoms.d_gridlineIndices; + const float* __restrict__ gm_theta = kernelParams.atoms.d_theta; + const float* __restrict__ gm_dtheta = kernelParams.atoms.d_dtheta; + const int* __restrict__ gm_gridlineIndices = kernelParams.atoms.d_gridlineIndices; float3 atomX; float atomCharge; /* Some sizes */ - const int atomsPerBlock = useOrderThreads ? (c_gatherMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom) : - (c_gatherMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom); - const int blockIndex = blockIdx.y * gridDim.x + blockIdx.x; + const int atomsPerBlock = + useOrderThreads ? (c_gatherMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom) + : (c_gatherMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom); + const int blockIndex = blockIdx.y * gridDim.x + blockIdx.x; /* Number of data components and threads for a single atom */ - const int atomDataSize = useOrderThreads ? c_pmeSpreadGatherThreadsPerAtom4ThPerAtom : c_pmeSpreadGatherThreadsPerAtom; - const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom : c_pmeSpreadGatherAtomsPerWarp; + const int atomDataSize = useOrderThreads ? c_pmeSpreadGatherThreadsPerAtom4ThPerAtom + : c_pmeSpreadGatherThreadsPerAtom; + const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom + : c_pmeSpreadGatherAtomsPerWarp; - const int blockSize = atomsPerBlock * atomDataSize; + const int blockSize = atomsPerBlock * atomDataSize; assert(blockSize == blockDim.x * blockDim.y * blockDim.z); /* These are the atom indices - for the shared and global memory */ - const int atomIndexLocal = threadIdx.z; - const int atomIndexOffset = blockIndex * atomsPerBlock; - const int atomIndexGlobal = atomIndexOffset + atomIndexLocal; + const int atomIndexLocal = threadIdx.z; + const int atomIndexOffset = blockIndex * atomsPerBlock; + const int atomIndexGlobal = atomIndexOffset + atomIndexLocal; /* Early return for fully empty blocks at the end * (should only happen for billions of input atoms) @@ -273,28 +265,31 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) return; } // 4 warps per block, 8 atoms per warp *3 *4 - const int splineParamsSize = atomsPerBlock * DIM * order; - const int gridlineIndicesSize = atomsPerBlock * DIM; - __shared__ int sm_gridlineIndices[gridlineIndicesSize]; - __shared__ float sm_theta[splineParamsSize]; - __shared__ float sm_dtheta[splineParamsSize]; + const int splineParamsSize = atomsPerBlock * DIM * order; + const int gridlineIndicesSize = atomsPerBlock * DIM; + __shared__ int sm_gridlineIndices[gridlineIndicesSize]; + __shared__ float sm_theta[splineParamsSize]; + __shared__ float sm_dtheta[splineParamsSize]; /* Spline Z coordinates */ const int ithz = threadIdx.x; /* These are the spline contribution indices in shared memory */ - const int splineIndex = threadIdx.y * blockDim.x + threadIdx.x; - const int lineIndex = (threadIdx.z * (blockDim.x * blockDim.y)) + splineIndex; /* And to all the block's particles */ + const int splineIndex = threadIdx.y * blockDim.x + threadIdx.x; + const int lineIndex = (threadIdx.z * (blockDim.x * blockDim.y)) + + splineIndex; /* And to all the block's particles */ - const int threadLocalId = (threadIdx.z * (blockDim.x * blockDim.y)) + blockDim.x*threadIdx.y + threadIdx.x; - const int threadLocalIdMax = blockDim.x * blockDim.y * blockDim.z; + const int threadLocalId = + (threadIdx.z * (blockDim.x * blockDim.y)) + blockDim.x * threadIdx.y + threadIdx.x; + const int threadLocalIdMax = blockDim.x * blockDim.y * blockDim.z; if (readGlobal) { /* Read splines */ - const int localGridlineIndicesIndex = threadLocalId; + const int localGridlineIndicesIndex = threadLocalId; const int globalGridlineIndicesIndex = blockIndex * gridlineIndicesSize + localGridlineIndicesIndex; - const int globalCheckIndices = pme_gpu_check_atom_data_index(globalGridlineIndicesIndex, kernelParams.atoms.nAtoms * DIM); + const int globalCheckIndices = pme_gpu_check_atom_data_index( + globalGridlineIndicesIndex, kernelParams.atoms.nAtoms * DIM); if ((localGridlineIndicesIndex < gridlineIndicesSize) & globalCheckIndices) { sm_gridlineIndices[localGridlineIndicesIndex] = gm_gridlineIndices[globalGridlineIndicesIndex]; @@ -308,9 +303,12 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) for (int i = iMin; i < iMax; i++) { - int localSplineParamsIndex = threadLocalId + i*threadLocalIdMax; /* i will always be zero for order*order threads per atom */ + int localSplineParamsIndex = + threadLocalId + + i * threadLocalIdMax; /* i will always be zero for order*order threads per atom */ int globalSplineParamsIndex = blockIndex * splineParamsSize + localSplineParamsIndex; - int globalCheckSplineParams = pme_gpu_check_atom_data_index(globalSplineParamsIndex, kernelParams.atoms.nAtoms * DIM * order); + int globalCheckSplineParams = pme_gpu_check_atom_data_index( + globalSplineParamsIndex, kernelParams.atoms.nAtoms * DIM * order); if ((localSplineParamsIndex < splineParamsSize) && globalCheckSplineParams) { sm_theta[localSplineParamsIndex] = gm_theta[globalSplineParamsIndex]; @@ -326,79 +324,78 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) /* Recaclulate Splines */ if (c_useAtomDataPrefetch) { - //charges + // charges __shared__ float sm_coefficients[atomsPerBlock]; // Coordinates __shared__ float sm_coordinates[DIM * atomsPerBlock]; /* Staging coefficients/charges */ - pme_gpu_stage_atom_data(kernelParams, sm_coefficients, kernelParams.atoms.d_coefficients); + pme_gpu_stage_atom_data(kernelParams, sm_coefficients, + kernelParams.atoms.d_coefficients); /* Staging coordinates */ - pme_gpu_stage_atom_data(kernelParams, sm_coordinates, kernelParams.atoms.d_coordinates); + pme_gpu_stage_atom_data(kernelParams, sm_coordinates, + kernelParams.atoms.d_coordinates); __syncthreads(); - atomX.x = sm_coordinates[atomIndexLocal*DIM+XX]; - atomX.y = sm_coordinates[atomIndexLocal*DIM+YY]; - atomX.z = sm_coordinates[atomIndexLocal*DIM+ZZ]; + atomX.x = sm_coordinates[atomIndexLocal * DIM + XX]; + atomX.y = sm_coordinates[atomIndexLocal * DIM + YY]; + atomX.z = sm_coordinates[atomIndexLocal * DIM + ZZ]; atomCharge = sm_coefficients[atomIndexLocal]; - } else { - atomCharge = gm_coefficients[atomIndexGlobal]; - atomX.x = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + XX]; - atomX.y = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + YY]; - atomX.z = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + ZZ]; + atomCharge = gm_coefficients[atomIndexGlobal]; + atomX.x = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + XX]; + atomX.y = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + YY]; + atomX.z = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + ZZ]; } - calculate_splines(kernelParams, atomIndexOffset, - atomX, atomCharge, - sm_theta, sm_dtheta, - sm_gridlineIndices); + calculate_splines( + kernelParams, atomIndexOffset, atomX, atomCharge, sm_theta, sm_dtheta, sm_gridlineIndices); __syncwarp(); } - float fx = 0.0f; - float fy = 0.0f; - float fz = 0.0f; + float fx = 0.0f; + float fy = 0.0f; + float fz = 0.0f; - const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); - const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficients[atomIndexGlobal]); + const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); + const int chargeCheck = pme_gpu_check_atom_charge(gm_coefficients[atomIndexGlobal]); if (chargeCheck & globalCheck) { - const int nx = kernelParams.grid.realGridSize[XX]; - const int ny = kernelParams.grid.realGridSize[YY]; - const int nz = kernelParams.grid.realGridSize[ZZ]; - const int pny = kernelParams.grid.realGridSizePadded[YY]; - const int pnz = kernelParams.grid.realGridSizePadded[ZZ]; + const int nx = kernelParams.grid.realGridSize[XX]; + const int ny = kernelParams.grid.realGridSize[YY]; + const int nz = kernelParams.grid.realGridSize[ZZ]; + const int pny = kernelParams.grid.realGridSizePadded[YY]; + const int pnz = kernelParams.grid.realGridSizePadded[ZZ]; - const int atomWarpIndex = atomIndexLocal % atomsPerWarp; - const int warpIndex = atomIndexLocal / atomsPerWarp; + const int atomWarpIndex = atomIndexLocal % atomsPerWarp; + const int warpIndex = atomIndexLocal / atomsPerWarp; - const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); - const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); - const float2 tdz = make_float2(sm_theta[splineIndexZ], sm_dtheta[splineIndexZ] ); + const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); + const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); + const float2 tdz = make_float2(sm_theta[splineIndexZ], sm_dtheta[splineIndexZ]); - int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] + ithz; - const int ixBase = sm_gridlineIndices[atomIndexLocal * DIM + XX]; + int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] + ithz; + const int ixBase = sm_gridlineIndices[atomIndexLocal * DIM + XX]; if (iz >= nz) { iz -= nz; } - int constOffset, iy; + int constOffset, iy; const int ithyMin = useOrderThreads ? 0 : threadIdx.y; const int ithyMax = useOrderThreads ? order : threadIdx.y + 1; for (int ithy = ithyMin; ithy < ithyMax; ithy++) { - const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); - const float2 tdy = make_float2(sm_theta[splineIndexY], sm_dtheta[splineIndexY] ); + const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); + const float2 tdy = make_float2(sm_theta[splineIndexY], sm_dtheta[splineIndexY]); - iy = sm_gridlineIndices[atomIndexLocal * DIM + YY] + ithy; + iy = sm_gridlineIndices[atomIndexLocal * DIM + YY] + ithy; if (wrapY & (iy >= ny)) { iy -= ny; } - constOffset = iy * pnz + iz; + constOffset = iy * pnz + iz; #pragma unroll for (int ithx = 0; (ithx < order); ithx++) @@ -408,14 +405,15 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) { ix -= nx; } - const int gridIndexGlobal = ix * pny * pnz + constOffset; + const int gridIndexGlobal = ix * pny * pnz + constOffset; assert(gridIndexGlobal >= 0); - const float gridValue = gm_grid[gridIndexGlobal]; + const float gridValue = gm_grid[gridIndexGlobal]; assert(isfinite(gridValue)); - const int splineIndexX = getSplineParamIndex(splineIndexBase, XX, ithx); - const float2 tdx = make_float2( sm_theta[splineIndexX], sm_dtheta[splineIndexX]); - const float fxy1 = tdz.x * gridValue; - const float fz1 = tdz.y * gridValue; + const int splineIndexX = + getSplineParamIndex(splineIndexBase, XX, ithx); + const float2 tdx = make_float2(sm_theta[splineIndexX], sm_dtheta[splineIndexX]); + const float fxy1 = tdz.x * gridValue; + const float fz1 = tdz.y * gridValue; fx += tdx.y * tdy.x * fxy1; fy += tdx.x * tdy.y * fxy1; fz += tdx.x * tdy.x * fz1; @@ -425,24 +423,27 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) // Reduction of partial force contributions __shared__ float3 sm_forces[atomsPerBlock]; - reduce_atom_forces(sm_forces, - atomIndexLocal, splineIndex, lineIndex, - kernelParams.grid.realGridSizeFP, - fx, fy, fz); + reduce_atom_forces(sm_forces, atomIndexLocal, splineIndex, lineIndex, + kernelParams.grid.realGridSizeFP, fx, fy, fz); __syncthreads(); /* Calculating the final forces with no component branching, atomsPerBlock threads */ const int forceIndexLocal = threadLocalId; const int forceIndexGlobal = atomIndexOffset + forceIndexLocal; - const int calcIndexCheck = pme_gpu_check_atom_data_index(forceIndexGlobal, kernelParams.atoms.nAtoms); + const int calcIndexCheck = pme_gpu_check_atom_data_index(forceIndexGlobal, kernelParams.atoms.nAtoms); if ((forceIndexLocal < atomsPerBlock) & calcIndexCheck) { - const float3 atomForces = sm_forces[forceIndexLocal]; - const float negCoefficient = -gm_coefficients[forceIndexGlobal]; - float3 result; - result.x = negCoefficient * kernelParams.current.recipBox[XX][XX] * atomForces.x; - result.y = negCoefficient * (kernelParams.current.recipBox[XX][YY] * atomForces.x + kernelParams.current.recipBox[YY][YY] * atomForces.y); - result.z = negCoefficient * (kernelParams.current.recipBox[XX][ZZ] * atomForces.x + kernelParams.current.recipBox[YY][ZZ] * atomForces.y + kernelParams.current.recipBox[ZZ][ZZ] * atomForces.z); + const float3 atomForces = sm_forces[forceIndexLocal]; + const float negCoefficient = -gm_coefficients[forceIndexGlobal]; + float3 result; + result.x = negCoefficient * kernelParams.current.recipBox[XX][XX] * atomForces.x; + result.y = negCoefficient + * (kernelParams.current.recipBox[XX][YY] * atomForces.x + + kernelParams.current.recipBox[YY][YY] * atomForces.y); + result.z = negCoefficient + * (kernelParams.current.recipBox[XX][ZZ] * atomForces.x + + kernelParams.current.recipBox[YY][ZZ] * atomForces.y + + kernelParams.current.recipBox[ZZ][ZZ] * atomForces.z); sm_forces[forceIndexLocal] = result; } @@ -458,12 +459,13 @@ __global__ void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams) #pragma unroll for (int i = 0; i < numIter; i++) { - int outputIndexLocal = i * iterThreads + threadLocalId; - int outputIndexGlobal = blockIndex * blockForcesSize + outputIndexLocal; - const int globalOutputCheck = pme_gpu_check_atom_data_index(outputIndexGlobal, kernelParams.atoms.nAtoms * DIM); + int outputIndexLocal = i * iterThreads + threadLocalId; + int outputIndexGlobal = blockIndex * blockForcesSize + outputIndexLocal; + const int globalOutputCheck = + pme_gpu_check_atom_data_index(outputIndexGlobal, kernelParams.atoms.nAtoms * DIM); if (globalOutputCheck) { - const float outputForceComponent = ((float *)sm_forces)[outputIndexLocal]; + const float outputForceComponent = ((float*)sm_forces)[outputIndexLocal]; if (overwriteForces) { gm_forces[outputIndexGlobal] = outputForceComponent; diff --git a/src/gromacs/ewald/pme_gather.h b/src/gromacs/ewald/pme_gather.h index 8bb174a5f8..846794c949 100644 --- a/src/gromacs/ewald/pme_gather.h +++ b/src/gromacs/ewald/pme_gather.h @@ -39,14 +39,13 @@ #include "pme_internal.h" -void -gather_f_bsplines(const struct gmx_pme_t *pme, const real *grid, - gmx_bool bClearF, const PmeAtomComm *atc, - const splinedata_t *spline, - real scale); +void gather_f_bsplines(const struct gmx_pme_t* pme, + const real* grid, + gmx_bool bClearF, + const PmeAtomComm* atc, + const splinedata_t* spline, + real scale); -real -gather_energy_bsplines(struct gmx_pme_t *pme, const real *grid, - PmeAtomComm *atc); +real gather_energy_bsplines(struct gmx_pme_t* pme, const real* grid, PmeAtomComm* atc); #endif diff --git a/src/gromacs/ewald/pme_gpu.cpp b/src/gromacs/ewald/pme_gpu.cpp index 565a63946a..31467da6da 100644 --- a/src/gromacs/ewald/pme_gpu.cpp +++ b/src/gromacs/ewald/pme_gpu.cpp @@ -64,7 +64,7 @@ #include "pme_internal.h" #include "pme_solve.h" -void pme_gpu_reset_timings(const gmx_pme_t *pme) +void pme_gpu_reset_timings(const gmx_pme_t* pme) { if (pme_gpu_active(pme)) { @@ -72,7 +72,7 @@ void pme_gpu_reset_timings(const gmx_pme_t *pme) } } -void pme_gpu_get_timings(const gmx_pme_t *pme, gmx_wallclock_gpu_pme_t *timings) +void pme_gpu_get_timings(const gmx_pme_t* pme, gmx_wallclock_gpu_pme_t* timings) { if (pme_gpu_active(pme)) { @@ -80,7 +80,7 @@ void pme_gpu_get_timings(const gmx_pme_t *pme, gmx_wallclock_gpu_pme_t *timings) } } -int pme_gpu_get_padding_size(const gmx_pme_t *pme) +int pme_gpu_get_padding_size(const gmx_pme_t* pme) { if (!pme || !pme_gpu_active(pme)) @@ -101,10 +101,10 @@ int pme_gpu_get_padding_size(const gmx_pme_t *pme) * \param[in] dir The FFT direction enum. * \param[in] wcycle The wallclock counter. */ -void inline parallel_3dfft_execute_gpu_wrapper(gmx_pme_t *pme, - const int gridIndex, - enum gmx_fft_direction dir, - gmx_wallcycle_t wcycle) +void inline parallel_3dfft_execute_gpu_wrapper(gmx_pme_t* pme, + const int gridIndex, + enum gmx_fft_direction dir, + gmx_wallcycle_t wcycle) { GMX_ASSERT(gridIndex == 0, "Only single grid supported"); if (pme_gpu_performs_FFT(pme->gpu)) @@ -129,19 +129,19 @@ void inline parallel_3dfft_execute_gpu_wrapper(gmx_pme_t *pme, /* The PME computation code split into a few separate functions. */ -void pme_gpu_prepare_computation(gmx_pme_t *pme, - bool needToUpdateBox, - const matrix box, - gmx_wallcycle *wcycle, - int flags, - bool useGpuForceReduction) +void pme_gpu_prepare_computation(gmx_pme_t* pme, + bool needToUpdateBox, + const matrix box, + gmx_wallcycle* wcycle, + int flags, + bool useGpuForceReduction) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); GMX_ASSERT(pme->nnodes > 0, ""); GMX_ASSERT(pme->nnodes == 1 || pme->ndecompdim > 0, ""); - PmeGpu *pmeGpu = pme->gpu; - pmeGpu->settings.currentFlags = flags; + PmeGpu* pmeGpu = pme->gpu; + pmeGpu->settings.currentFlags = flags; // TODO these flags are only here to honor the CPU PME code, and probably should be removed pmeGpu->settings.useGpuForceReduction = useGpuForceReduction; @@ -150,7 +150,7 @@ void pme_gpu_prepare_computation(gmx_pme_t *pme, { for (int j = 0; j <= i; ++j) { - shouldUpdateBox |= (pmeGpu->common->previousBox[i][j] != box[i][j]); + shouldUpdateBox |= (pmeGpu->common->previousBox[i][j] != box[i][j]); pmeGpu->common->previousBox[i][j] = box[i][j]; } } @@ -174,17 +174,16 @@ void pme_gpu_prepare_computation(gmx_pme_t *pme, } } -void pme_gpu_launch_spread(gmx_pme_t *pme, - GpuEventSynchronizer *xReadyOnDevice, - gmx_wallcycle *wcycle) +void pme_gpu_launch_spread(gmx_pme_t* pme, GpuEventSynchronizer* xReadyOnDevice, gmx_wallcycle* wcycle) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); - GMX_ASSERT(xReadyOnDevice || !pme->bPPnode || (GMX_GPU != GMX_GPU_CUDA), "Need a valid xReadyOnDevice on PP+PME ranks with CUDA."); + GMX_ASSERT(xReadyOnDevice || !pme->bPPnode || (GMX_GPU != GMX_GPU_CUDA), + "Need a valid xReadyOnDevice on PP+PME ranks with CUDA."); - PmeGpu *pmeGpu = pme->gpu; + PmeGpu* pmeGpu = pme->gpu; - const unsigned int gridIndex = 0; - real *fftgrid = pme->fftgrid[gridIndex]; + const unsigned int gridIndex = 0; + real* fftgrid = pme->fftgrid[gridIndex]; if (pmeGpu->settings.currentFlags & GMX_PME_SPREAD) { /* Spread the coefficients on a grid */ @@ -198,14 +197,13 @@ void pme_gpu_launch_spread(gmx_pme_t *pme, } } -void pme_gpu_launch_complex_transforms(gmx_pme_t *pme, - gmx_wallcycle *wcycle) +void pme_gpu_launch_complex_transforms(gmx_pme_t* pme, gmx_wallcycle* wcycle) { - PmeGpu *pmeGpu = pme->gpu; - const bool computeEnergyAndVirial = (pmeGpu->settings.currentFlags & GMX_PME_CALC_ENER_VIR) != 0; - const bool performBackFFT = (pmeGpu->settings.currentFlags & (GMX_PME_CALC_F | GMX_PME_CALC_POT)) != 0; - const unsigned int gridIndex = 0; - t_complex *cfftgrid = pme->cfftgrid[gridIndex]; + PmeGpu* pmeGpu = pme->gpu; + const bool computeEnergyAndVirial = (pmeGpu->settings.currentFlags & GMX_PME_CALC_ENER_VIR) != 0; + const bool performBackFFT = (pmeGpu->settings.currentFlags & (GMX_PME_CALC_F | GMX_PME_CALC_POT)) != 0; + const unsigned int gridIndex = 0; + t_complex* cfftgrid = pme->cfftgrid[gridIndex]; if (pmeGpu->settings.currentFlags & GMX_PME_SPREAD) { @@ -240,8 +238,8 @@ void pme_gpu_launch_complex_transforms(gmx_pme_t *pme, #pragma omp parallel for num_threads(pme->nthread) schedule(static) for (int thread = 0; thread < pme->nthread; thread++) { - solve_pme_yzx(pme, cfftgrid, pme->boxVolume, - computeEnergyAndVirial, pme->nthread, thread); + solve_pme_yzx(pme, cfftgrid, pme->boxVolume, computeEnergyAndVirial, + pme->nthread, thread); } wallcycle_stop(wcycle, ewcPME_SOLVE_MIXED_MODE); } @@ -251,12 +249,11 @@ void pme_gpu_launch_complex_transforms(gmx_pme_t *pme, { parallel_3dfft_execute_gpu_wrapper(pme, gridIndex, GMX_FFT_COMPLEX_TO_REAL, wcycle); } - } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + } + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; } -void pme_gpu_launch_gather(const gmx_pme_t *pme, - gmx_wallcycle gmx_unused *wcycle, - PmeForceOutputHandling forceTreatment) +void pme_gpu_launch_gather(const gmx_pme_t* pme, gmx_wallcycle gmx_unused* wcycle, PmeForceOutputHandling forceTreatment) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); @@ -267,18 +264,17 @@ void pme_gpu_launch_gather(const gmx_pme_t *pme, wallcycle_start_nocount(wcycle, ewcLAUNCH_GPU); wallcycle_sub_start_nocount(wcycle, ewcsLAUNCH_GPU_PME); - const unsigned int gridIndex = 0; - real *fftgrid = pme->fftgrid[gridIndex]; - pme_gpu_gather(pme->gpu, forceTreatment, reinterpret_cast(fftgrid)); + const unsigned int gridIndex = 0; + real* fftgrid = pme->fftgrid[gridIndex]; + pme_gpu_gather(pme->gpu, forceTreatment, reinterpret_cast(fftgrid)); wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_PME); wallcycle_stop(wcycle, ewcLAUNCH_GPU); } //! Accumulate the \c forcesToAdd to \c f, using the available threads. -static void sum_forces(gmx::ArrayRef f, - gmx::ArrayRef forceToAdd) +static void sum_forces(gmx::ArrayRef f, gmx::ArrayRef forceToAdd) { - const int end = forceToAdd.size(); + const int end = forceToAdd.size(); int gmx_unused nt = gmx_omp_nthreads_get(emntPME); #pragma omp parallel for num_threads(nt) schedule(static) @@ -290,10 +286,10 @@ static void sum_forces(gmx::ArrayRef f, //! Reduce quantities from \c output to \c forceWithVirial and \c enerd. static void pme_gpu_reduce_outputs(const int flags, - const PmeOutput &output, - gmx_wallcycle *wcycle, - gmx::ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd) + const PmeOutput& output, + gmx_wallcycle* wcycle, + gmx::ForceWithVirial* forceWithVirial, + gmx_enerdata_t* enerd) { wallcycle_start(wcycle, ewcPME_GPU_F_REDUCTION); GMX_ASSERT(forceWithVirial, "Invalid force pointer"); @@ -312,15 +308,16 @@ static void pme_gpu_reduce_outputs(const int flags, wallcycle_stop(wcycle, ewcPME_GPU_F_REDUCTION); } -bool pme_gpu_try_finish_task(gmx_pme_t *pme, +bool pme_gpu_try_finish_task(gmx_pme_t* pme, const int flags, - gmx_wallcycle *wcycle, - gmx::ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd, + gmx_wallcycle* wcycle, + gmx::ForceWithVirial* forceWithVirial, + gmx_enerdata_t* enerd, GpuTaskCompletion completionKind) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); - GMX_ASSERT(!pme->gpu->settings.useGpuForceReduction, "GPU force reduction should not be active on the pme_gpu_try_finish_task() path"); + GMX_ASSERT(!pme->gpu->settings.useGpuForceReduction, + "GPU force reduction should not be active on the pme_gpu_try_finish_task() path"); // First, if possible, check whether all tasks on the stream have // completed, and return fast if not. Accumulate to wcycle the @@ -356,16 +353,15 @@ bool pme_gpu_try_finish_task(gmx_pme_t *pme, PmeOutput output = pme_gpu_getOutput(*pme, flags); wallcycle_stop(wcycle, ewcWAIT_GPU_PME_GATHER); - GMX_ASSERT(pme->gpu->settings.useGpuForceReduction == !output.haveForceOutput_, "When forces are reduced on the CPU, there needs to be force output"); + GMX_ASSERT(pme->gpu->settings.useGpuForceReduction == !output.haveForceOutput_, + "When forces are reduced on the CPU, there needs to be force output"); pme_gpu_reduce_outputs(flags, output, wcycle, forceWithVirial, enerd); return true; } // This is used by PME-only ranks -PmeOutput pme_gpu_wait_finish_task(gmx_pme_t *pme, - const int flags, - gmx_wallcycle *wcycle) +PmeOutput pme_gpu_wait_finish_task(gmx_pme_t* pme, const int flags, gmx_wallcycle* wcycle) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); @@ -386,19 +382,19 @@ PmeOutput pme_gpu_wait_finish_task(gmx_pme_t *pme, } // This is used when not using the alternate-waiting reduction -void pme_gpu_wait_and_reduce(gmx_pme_t *pme, +void pme_gpu_wait_and_reduce(gmx_pme_t* pme, const int flags, - gmx_wallcycle *wcycle, - gmx::ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd) + gmx_wallcycle* wcycle, + gmx::ForceWithVirial* forceWithVirial, + gmx_enerdata_t* enerd) { PmeOutput output = pme_gpu_wait_finish_task(pme, flags, wcycle); - GMX_ASSERT(pme->gpu->settings.useGpuForceReduction == !output.haveForceOutput_, "When forces are reduced on the CPU, there needs to be force output"); + GMX_ASSERT(pme->gpu->settings.useGpuForceReduction == !output.haveForceOutput_, + "When forces are reduced on the CPU, there needs to be force output"); pme_gpu_reduce_outputs(flags, output, wcycle, forceWithVirial, enerd); } -void pme_gpu_reinit_computation(const gmx_pme_t *pme, - gmx_wallcycle *wcycle) +void pme_gpu_reinit_computation(const gmx_pme_t* pme, gmx_wallcycle* wcycle) { GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); @@ -414,13 +410,14 @@ void pme_gpu_reinit_computation(const gmx_pme_t *pme, wallcycle_stop(wcycle, ewcLAUNCH_GPU); } -DeviceBuffer pme_gpu_get_device_x(const gmx_pme_t *pme) +DeviceBuffer pme_gpu_get_device_x(const gmx_pme_t* pme) { - GMX_ASSERT((pme && pme_gpu_active(pme)), "PME GPU coordinates buffer was requested from uninitialized PME module"); + GMX_ASSERT((pme && pme_gpu_active(pme)), + "PME GPU coordinates buffer was requested from uninitialized PME module"); return pme_gpu_get_kernelparam_coordinates(pme->gpu); } -void *pme_gpu_get_device_f(const gmx_pme_t *pme) +void* pme_gpu_get_device_f(const gmx_pme_t* pme) { if (!pme || !pme_gpu_active(pme)) { @@ -429,8 +426,7 @@ void *pme_gpu_get_device_f(const gmx_pme_t *pme) return pme_gpu_get_kernelparam_forces(pme->gpu); } -void pme_gpu_set_device_x(const gmx_pme_t *pme, - DeviceBuffer d_x) +void pme_gpu_set_device_x(const gmx_pme_t* pme, DeviceBuffer d_x) { GMX_ASSERT(pme != nullptr, "Null pointer is passed as a PME to the set coordinates function."); GMX_ASSERT(pme_gpu_active(pme), "This should be a GPU run of PME but it is not enabled."); @@ -438,7 +434,7 @@ void pme_gpu_set_device_x(const gmx_pme_t *pme, pme_gpu_set_kernelparam_coordinates(pme->gpu, d_x); } -void *pme_gpu_get_device_stream(const gmx_pme_t *pme) +void* pme_gpu_get_device_stream(const gmx_pme_t* pme) { if (!pme || !pme_gpu_active(pme)) { @@ -447,7 +443,7 @@ void *pme_gpu_get_device_stream(const gmx_pme_t *pme) return pme_gpu_get_stream(pme->gpu); } -void *pme_gpu_get_device_context(const gmx_pme_t *pme) +void* pme_gpu_get_device_context(const gmx_pme_t* pme) { if (!pme || !pme_gpu_active(pme)) { @@ -456,7 +452,7 @@ void *pme_gpu_get_device_context(const gmx_pme_t *pme) return pme_gpu_get_context(pme->gpu); } -GpuEventSynchronizer * pme_gpu_get_f_ready_synchronizer(const gmx_pme_t *pme) +GpuEventSynchronizer* pme_gpu_get_f_ready_synchronizer(const gmx_pme_t* pme) { if (!pme || !pme_gpu_active(pme)) { diff --git a/src/gromacs/ewald/pme_gpu_3dfft.cu b/src/gromacs/ewald/pme_gpu_3dfft.cu index c36d440b14..16bde23684 100644 --- a/src/gromacs/ewald/pme_gpu_3dfft.cu +++ b/src/gromacs/ewald/pme_gpu_3dfft.cu @@ -52,7 +52,7 @@ #include "pme_gpu_types_host.h" #include "pme_gpu_types_host_impl.h" -static void handleCufftError(cufftResult_t status, const char *msg) +static void handleCufftError(cufftResult_t status, const char* msg) { if (status != CUFFT_SUCCESS) { @@ -60,10 +60,10 @@ static void handleCufftError(cufftResult_t status, const char *msg) } } -GpuParallel3dFft::GpuParallel3dFft(const PmeGpu *pmeGpu) +GpuParallel3dFft::GpuParallel3dFft(const PmeGpu* pmeGpu) { - const PmeGpuCudaKernelParams *kernelParamsPtr = pmeGpu->kernelParams.get(); - ivec realGridSize, realGridSizePadded, complexGridSizePadded; + const PmeGpuCudaKernelParams* kernelParamsPtr = pmeGpu->kernelParams.get(); + ivec realGridSize, realGridSizePadded, complexGridSizePadded; for (int i = 0; i < DIM; i++) { realGridSize[i] = kernelParamsPtr->grid.realGridSize[i]; @@ -73,37 +73,34 @@ GpuParallel3dFft::GpuParallel3dFft(const PmeGpu *pmeGpu) GMX_RELEASE_ASSERT(!pme_gpu_uses_dd(pmeGpu), "FFT decomposition not implemented"); - const int complexGridSizePaddedTotal = complexGridSizePadded[XX] * complexGridSizePadded[YY] * complexGridSizePadded[ZZ]; - const int realGridSizePaddedTotal = realGridSizePadded[XX] * realGridSizePadded[YY] * realGridSizePadded[ZZ]; + const int complexGridSizePaddedTotal = + complexGridSizePadded[XX] * complexGridSizePadded[YY] * complexGridSizePadded[ZZ]; + const int realGridSizePaddedTotal = + realGridSizePadded[XX] * realGridSizePadded[YY] * realGridSizePadded[ZZ]; - realGrid_ = (cufftReal *)kernelParamsPtr->grid.d_realGrid; + realGrid_ = (cufftReal*)kernelParamsPtr->grid.d_realGrid; GMX_RELEASE_ASSERT(realGrid_, "Bad (null) input real-space grid"); - complexGrid_ = (cufftComplex *)kernelParamsPtr->grid.d_fourierGrid; + complexGrid_ = (cufftComplex*)kernelParamsPtr->grid.d_fourierGrid; GMX_RELEASE_ASSERT(complexGrid_, "Bad (null) input complex grid"); cufftResult_t result; /* Commented code for a simple 3D grid with no padding */ /* - result = cufftPlan3d(&planR2C_, realGridSize[XX], realGridSize[YY], realGridSize[ZZ], CUFFT_R2C); - handleCufftError(result, "cufftPlan3d R2C plan failure"); + result = cufftPlan3d(&planR2C_, realGridSize[XX], realGridSize[YY], realGridSize[ZZ], + CUFFT_R2C); handleCufftError(result, "cufftPlan3d R2C plan failure"); - result = cufftPlan3d(&planC2R_, realGridSize[XX], realGridSize[YY], realGridSize[ZZ], CUFFT_C2R); - handleCufftError(result, "cufftPlan3d C2R plan failure"); + result = cufftPlan3d(&planC2R_, realGridSize[XX], realGridSize[YY], realGridSize[ZZ], + CUFFT_C2R); handleCufftError(result, "cufftPlan3d C2R plan failure"); */ - const int rank = 3, batch = 1; - result = cufftPlanMany(&planR2C_, rank, realGridSize, - realGridSizePadded, 1, realGridSizePaddedTotal, - complexGridSizePadded, 1, complexGridSizePaddedTotal, - CUFFT_R2C, - batch); + const int rank = 3, batch = 1; + result = cufftPlanMany(&planR2C_, rank, realGridSize, realGridSizePadded, 1, realGridSizePaddedTotal, + complexGridSizePadded, 1, complexGridSizePaddedTotal, CUFFT_R2C, batch); handleCufftError(result, "cufftPlanMany R2C plan failure"); - result = cufftPlanMany(&planC2R_, rank, realGridSize, - complexGridSizePadded, 1, complexGridSizePaddedTotal, - realGridSizePadded, 1, realGridSizePaddedTotal, - CUFFT_C2R, - batch); + result = cufftPlanMany(&planC2R_, rank, realGridSize, complexGridSizePadded, 1, + complexGridSizePaddedTotal, realGridSizePadded, 1, + realGridSizePaddedTotal, CUFFT_C2R, batch); handleCufftError(result, "cufftPlanMany C2R plan failure"); cudaStream_t stream = pmeGpu->archSpecific->pmeStream; @@ -125,8 +122,7 @@ GpuParallel3dFft::~GpuParallel3dFft() handleCufftError(result, "cufftDestroy C2R failure"); } -void GpuParallel3dFft::perform3dFft(gmx_fft_direction dir, - CommandEvent */*timingEvent*/) +void GpuParallel3dFft::perform3dFft(gmx_fft_direction dir, CommandEvent* /*timingEvent*/) { cufftResult_t result; if (dir == GMX_FFT_REAL_TO_COMPLEX) diff --git a/src/gromacs/ewald/pme_gpu_3dfft.h b/src/gromacs/ewald/pme_gpu_3dfft.h index cee64552e8..07d3b1af57 100644 --- a/src/gromacs/ewald/pme_gpu_3dfft.h +++ b/src/gromacs/ewald/pme_gpu_3dfft.h @@ -48,17 +48,17 @@ #include #if GMX_GPU == GMX_GPU_CUDA -#include +# include -#include "gromacs/gpu_utils/gputraits.cuh" +# include "gromacs/gpu_utils/gputraits.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include +# include -#include "gromacs/gpu_utils/gmxopencl.h" -#include "gromacs/gpu_utils/gputraits_ocl.h" +# include "gromacs/gpu_utils/gmxopencl.h" +# include "gromacs/gpu_utils/gputraits_ocl.h" #endif -#include "gromacs/fft/fft.h" // for the enum gmx_fft_direction +#include "gromacs/fft/fft.h" // for the enum gmx_fft_direction struct PmeGpu; @@ -68,37 +68,35 @@ struct PmeGpu; */ class GpuParallel3dFft { - public: - /*! \brief - * Constructs CUDA/OpenCL FFT plans for performing 3D FFT on a PME grid. - * - * \param[in] pmeGpu The PME GPU structure. - */ - GpuParallel3dFft(const PmeGpu *pmeGpu); - /*! \brief Destroys the FFT plans. */ - ~GpuParallel3dFft(); - /*! \brief Performs the FFT transform in given direction - * - * \param[in] dir FFT transform direction specifier - * \param[out] timingEvent pointer to the timing event where timing data is recorded - */ - void perform3dFft(gmx_fft_direction dir, - CommandEvent *timingEvent); +public: + /*! \brief + * Constructs CUDA/OpenCL FFT plans for performing 3D FFT on a PME grid. + * + * \param[in] pmeGpu The PME GPU structure. + */ + GpuParallel3dFft(const PmeGpu* pmeGpu); + /*! \brief Destroys the FFT plans. */ + ~GpuParallel3dFft(); + /*! \brief Performs the FFT transform in given direction + * + * \param[in] dir FFT transform direction specifier + * \param[out] timingEvent pointer to the timing event where timing data is recorded + */ + void perform3dFft(gmx_fft_direction dir, CommandEvent* timingEvent); - private: +private: #if GMX_GPU == GMX_GPU_CUDA - cufftHandle planR2C_; - cufftHandle planC2R_; - cufftReal *realGrid_; - cufftComplex *complexGrid_; + cufftHandle planR2C_; + cufftHandle planC2R_; + cufftReal* realGrid_; + cufftComplex* complexGrid_; #elif GMX_GPU == GMX_GPU_OPENCL - clfftPlanHandle planR2C_; - clfftPlanHandle planC2R_; - std::vector commandStreams_; - cl_mem realGrid_; - cl_mem complexGrid_; + clfftPlanHandle planR2C_; + clfftPlanHandle planC2R_; + std::vector commandStreams_; + cl_mem realGrid_; + cl_mem complexGrid_; #endif - }; #endif diff --git a/src/gromacs/ewald/pme_gpu_3dfft_ocl.cpp b/src/gromacs/ewald/pme_gpu_3dfft_ocl.cpp index e2019ba558..cd0a18e0a5 100644 --- a/src/gromacs/ewald/pme_gpu_3dfft_ocl.cpp +++ b/src/gromacs/ewald/pme_gpu_3dfft_ocl.cpp @@ -54,7 +54,7 @@ #include "pme_gpu_types_host_impl.h" //! Throws the exception on clFFT error -static void handleClfftError(clfftStatus status, const char *msg) +static void handleClfftError(clfftStatus status, const char* msg) { // Supposedly it's just a superset of standard OpenCL errors if (status != CLFFT_SUCCESS) @@ -63,69 +63,73 @@ static void handleClfftError(clfftStatus status, const char *msg) } } -GpuParallel3dFft::GpuParallel3dFft(const PmeGpu *pmeGpu) +GpuParallel3dFft::GpuParallel3dFft(const PmeGpu* pmeGpu) { // Extracting all the data from PME GPU std::array realGridSize, realGridSizePadded, complexGridSizePadded; GMX_RELEASE_ASSERT(!pme_gpu_uses_dd(pmeGpu), "FFT decomposition not implemented"); - PmeGpuKernelParamsBase *kernelParamsPtr = pmeGpu->kernelParams.get(); + PmeGpuKernelParamsBase* kernelParamsPtr = pmeGpu->kernelParams.get(); for (int i = 0; i < DIM; i++) { realGridSize[i] = kernelParamsPtr->grid.realGridSize[i]; realGridSizePadded[i] = kernelParamsPtr->grid.realGridSizePadded[i]; complexGridSizePadded[i] = kernelParamsPtr->grid.complexGridSizePadded[i]; - GMX_ASSERT(kernelParamsPtr->grid.complexGridSizePadded[i] == kernelParamsPtr->grid.complexGridSize[i], "Complex padding not implemented"); + GMX_ASSERT(kernelParamsPtr->grid.complexGridSizePadded[i] + == kernelParamsPtr->grid.complexGridSize[i], + "Complex padding not implemented"); } cl_context context = pmeGpu->archSpecific->context; commandStreams_.push_back(pmeGpu->archSpecific->pmeStream); - realGrid_ = kernelParamsPtr->grid.d_realGrid; - complexGrid_ = kernelParamsPtr->grid.d_fourierGrid; + realGrid_ = kernelParamsPtr->grid.d_realGrid; + complexGrid_ = kernelParamsPtr->grid.d_fourierGrid; const bool performOutOfPlaceFFT = pmeGpu->archSpecific->performOutOfPlaceFFT; // clFFT expects row-major, so dimensions/strides are reversed (ZYX instead of XYZ) - std::array realGridDimensions = { - realGridSize[ZZ], - realGridSize[YY], - realGridSize[XX] - }; - std::array realGridStrides = { - 1, - realGridSizePadded[ZZ], - realGridSizePadded[YY] * realGridSizePadded[ZZ] - }; - std::array complexGridStrides = { - 1, - complexGridSizePadded[ZZ], - complexGridSizePadded[YY] * complexGridSizePadded[ZZ] - }; - - constexpr clfftDim dims = CLFFT_3D; - handleClfftError(clfftCreateDefaultPlan(&planR2C_, context, dims, realGridDimensions.data()), "clFFT planning failure"); - handleClfftError(clfftSetResultLocation(planR2C_, performOutOfPlaceFFT ? CLFFT_OUTOFPLACE : CLFFT_INPLACE), "clFFT planning failure"); + std::array realGridDimensions = { realGridSize[ZZ], realGridSize[YY], realGridSize[XX] }; + std::array realGridStrides = { 1, realGridSizePadded[ZZ], + realGridSizePadded[YY] * realGridSizePadded[ZZ] }; + std::array complexGridStrides = { 1, complexGridSizePadded[ZZ], + complexGridSizePadded[YY] * complexGridSizePadded[ZZ] }; + + constexpr clfftDim dims = CLFFT_3D; + handleClfftError(clfftCreateDefaultPlan(&planR2C_, context, dims, realGridDimensions.data()), + "clFFT planning failure"); + handleClfftError(clfftSetResultLocation(planR2C_, performOutOfPlaceFFT ? CLFFT_OUTOFPLACE : CLFFT_INPLACE), + "clFFT planning failure"); handleClfftError(clfftSetPlanPrecision(planR2C_, CLFFT_SINGLE), "clFFT planning failure"); constexpr cl_float scale = 1.0; - handleClfftError(clfftSetPlanScale(planR2C_, CLFFT_FORWARD, scale), "clFFT coefficient setup failure"); - handleClfftError(clfftSetPlanScale(planR2C_, CLFFT_BACKWARD, scale), "clFFT coefficient setup failure"); + handleClfftError(clfftSetPlanScale(planR2C_, CLFFT_FORWARD, scale), + "clFFT coefficient setup failure"); + handleClfftError(clfftSetPlanScale(planR2C_, CLFFT_BACKWARD, scale), + "clFFT coefficient setup failure"); // The only difference between 2 plans is direction handleClfftError(clfftCopyPlan(&planC2R_, context, planR2C_), "clFFT plan copying failure"); - handleClfftError(clfftSetLayout(planR2C_, CLFFT_REAL, CLFFT_HERMITIAN_INTERLEAVED), "clFFT R2C layout failure"); - handleClfftError(clfftSetLayout(planC2R_, CLFFT_HERMITIAN_INTERLEAVED, CLFFT_REAL), "clFFT C2R layout failure"); + handleClfftError(clfftSetLayout(planR2C_, CLFFT_REAL, CLFFT_HERMITIAN_INTERLEAVED), + "clFFT R2C layout failure"); + handleClfftError(clfftSetLayout(planC2R_, CLFFT_HERMITIAN_INTERLEAVED, CLFFT_REAL), + "clFFT C2R layout failure"); - handleClfftError(clfftSetPlanInStride(planR2C_, dims, realGridStrides.data()), "clFFT stride setting failure"); - handleClfftError(clfftSetPlanOutStride(planR2C_, dims, complexGridStrides.data()), "clFFT stride setting failure"); + handleClfftError(clfftSetPlanInStride(planR2C_, dims, realGridStrides.data()), + "clFFT stride setting failure"); + handleClfftError(clfftSetPlanOutStride(planR2C_, dims, complexGridStrides.data()), + "clFFT stride setting failure"); - handleClfftError(clfftSetPlanInStride(planC2R_, dims, complexGridStrides.data()), "clFFT stride setting failure"); - handleClfftError(clfftSetPlanOutStride(planC2R_, dims, realGridStrides.data()), "clFFT stride setting failure"); + handleClfftError(clfftSetPlanInStride(planC2R_, dims, complexGridStrides.data()), + "clFFT stride setting failure"); + handleClfftError(clfftSetPlanOutStride(planC2R_, dims, realGridStrides.data()), + "clFFT stride setting failure"); - handleClfftError(clfftBakePlan(planR2C_, commandStreams_.size(), commandStreams_.data(), nullptr, nullptr), "clFFT precompiling failure"); - handleClfftError(clfftBakePlan(planC2R_, commandStreams_.size(), commandStreams_.data(), nullptr, nullptr), "clFFT precompiling failure"); + handleClfftError(clfftBakePlan(planR2C_, commandStreams_.size(), commandStreams_.data(), nullptr, nullptr), + "clFFT precompiling failure"); + handleClfftError(clfftBakePlan(planC2R_, commandStreams_.size(), commandStreams_.data(), nullptr, nullptr), + "clFFT precompiling failure"); - //TODO: implement solve kernel as R2C FFT callback - //TODO: disable last transpose (clfftSetPlanTransposeResult) + // TODO: implement solve kernel as R2C FFT callback + // TODO: disable last transpose (clfftSetPlanTransposeResult) } GpuParallel3dFft::~GpuParallel3dFft() @@ -134,15 +138,14 @@ GpuParallel3dFft::~GpuParallel3dFft() clfftDestroyPlan(&planC2R_); } -void GpuParallel3dFft::perform3dFft(gmx_fft_direction dir, - CommandEvent *timingEvent) +void GpuParallel3dFft::perform3dFft(gmx_fft_direction dir, CommandEvent* timingEvent) { cl_mem tempBuffer = nullptr; - constexpr std::array waitEvents {{}}; + constexpr std::array waitEvents{ {} }; - clfftPlanHandle plan; - clfftDirection direction; - cl_mem *inputGrids, *outputGrids; + clfftPlanHandle plan; + clfftDirection direction; + cl_mem * inputGrids, *outputGrids; switch (dir) { @@ -159,10 +162,11 @@ void GpuParallel3dFft::perform3dFft(gmx_fft_direction dir, outputGrids = &realGrid_; break; default: - GMX_THROW(gmx::NotImplementedError("The chosen 3D-FFT case is not implemented on GPUs")); + GMX_THROW( + gmx::NotImplementedError("The chosen 3D-FFT case is not implemented on GPUs")); } - handleClfftError(clfftEnqueueTransform(plan, direction, - commandStreams_.size(), commandStreams_.data(), - waitEvents.size(), waitEvents.data(), timingEvent, - inputGrids, outputGrids, tempBuffer), "clFFT execution failure"); + handleClfftError(clfftEnqueueTransform(plan, direction, commandStreams_.size(), + commandStreams_.data(), waitEvents.size(), waitEvents.data(), + timingEvent, inputGrids, outputGrids, tempBuffer), + "clFFT execution failure"); } diff --git a/src/gromacs/ewald/pme_gpu_constants.h b/src/gromacs/ewald/pme_gpu_constants.h index cbbab88c7c..35299ca6b1 100644 --- a/src/gromacs/ewald/pme_gpu_constants.h +++ b/src/gromacs/ewald/pme_gpu_constants.h @@ -54,7 +54,7 @@ #include "config.h" #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/cuda_arch_utils.cuh" // for warp_size +# include "gromacs/gpu_utils/cuda_arch_utils.cuh" // for warp_size #endif /* General settings for PME GPU behaviour */ @@ -125,7 +125,7 @@ constexpr int c_pmeGpuOrder = 4; * The assumption is currently that any thread processes only a single atom's contributions. * TODO: this assumption leads to minimum execution width of 16. See Redmine #2516 */ -constexpr int c_pmeSpreadGatherThreadsPerAtom = c_pmeGpuOrder*c_pmeGpuOrder; +constexpr int c_pmeSpreadGatherThreadsPerAtom = c_pmeGpuOrder * c_pmeGpuOrder; //! Number of threads per atom when order threads are used constexpr int c_pmeSpreadGatherThreadsPerAtom4ThPerAtom = c_pmeGpuOrder; @@ -135,7 +135,7 @@ constexpr int c_pmeSpreadGatherThreadsPerAtom4ThPerAtom = c_pmeGpuOrder; * Due to the one thread per atom and order=4 implementation constraints, order^2 threads * should execute without synchronization needed. See c_pmeSpreadGatherThreadsPerAtom */ -constexpr int c_pmeSpreadGatherMinWarpSize = c_pmeSpreadGatherThreadsPerAtom; +constexpr int c_pmeSpreadGatherMinWarpSize = c_pmeSpreadGatherThreadsPerAtom; //! Minimum warp size if order threads pera atom are used instead of order^2 constexpr int c_pmeSpreadGatherMinWarpSize4ThPerAtom = c_pmeSpreadGatherThreadsPerAtom4ThPerAtom; @@ -161,8 +161,8 @@ constexpr int c_pmeAtomDataAlignment = 64; //! Spreading max block width in warps picked among powers of 2 (2, 4, 8, 16) for max. occupancy and min. runtime in most cases constexpr int c_spreadMaxWarpsPerBlock = 8; -//! Solving kernel max block width in warps picked among powers of 2 (2, 4, 8, 16) for max. occupancy and min. runtime -//! (560Ti (CC2.1), 660Ti (CC3.0) and 750 (CC5.0))) +//! Solving kernel max block width in warps picked among powers of 2 (2, 4, 8, 16) for max. +//! occupancy and min. runtime (560Ti (CC2.1), 660Ti (CC3.0) and 750 (CC5.0))) constexpr int c_solveMaxWarpsPerBlock = 8; //! Gathering max block width in warps - picked empirically among 2, 4, 8, 16 for max. occupancy and min. runtime @@ -179,13 +179,14 @@ constexpr int c_gatherMaxWarpsPerBlock = 4; /*! \brief * The number of atoms processed by a single warp in spread/gather. - * This macro depends on the templated order parameter (2 atoms per warp for order 4 and warp_size of 32). - * It is mostly used for spline data layout tweaked for coalesced access. + * This macro depends on the templated order parameter (2 atoms per warp for order 4 and warp_size + * of 32). It is mostly used for spline data layout tweaked for coalesced access. */ -constexpr int c_pmeSpreadGatherAtomsPerWarp = (warp_size / c_pmeSpreadGatherThreadsPerAtom); +constexpr int c_pmeSpreadGatherAtomsPerWarp = (warp_size / c_pmeSpreadGatherThreadsPerAtom); //! number of atoms per warp when order threads are used per atom -constexpr int c_pmeSpreadGatherAtomsPerWarp4ThPerAtom = (warp_size / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom); +constexpr int c_pmeSpreadGatherAtomsPerWarp4ThPerAtom = + (warp_size / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom); //! Spreading max block size in threads constexpr int c_spreadMaxThreadsPerBlock = c_spreadMaxWarpsPerBlock * warp_size; diff --git a/src/gromacs/ewald/pme_gpu_internal.cpp b/src/gromacs/ewald/pme_gpu_internal.cpp index caa7911409..df5f8e84cc 100644 --- a/src/gromacs/ewald/pme_gpu_internal.cpp +++ b/src/gromacs/ewald/pme_gpu_internal.cpp @@ -67,11 +67,11 @@ #include "gromacs/utility/stringutil.h" #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/pmalloc_cuda.h" +# include "gromacs/gpu_utils/pmalloc_cuda.h" -#include "pme.cuh" +# include "pme.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gmxopencl.h" +# include "gromacs/gpu_utils/gmxopencl.h" #endif #include "gromacs/ewald/pme.h" @@ -108,16 +108,16 @@ constexpr bool c_recalculateSplines = false; * \param[in] pmeGpu The PME GPU structure. * \returns The pointer to the kernel parameters. */ -static PmeGpuKernelParamsBase *pme_gpu_get_kernel_params_base_ptr(const PmeGpu *pmeGpu) +static PmeGpuKernelParamsBase* pme_gpu_get_kernel_params_base_ptr(const PmeGpu* pmeGpu) { // reinterpret_cast is needed because the derived CUDA structure is not known in this file - auto *kernelParamsPtr = reinterpret_cast(pmeGpu->kernelParams.get()); + auto* kernelParamsPtr = reinterpret_cast(pmeGpu->kernelParams.get()); return kernelParamsPtr; } -int pme_gpu_get_atom_data_alignment(const PmeGpu * /*unused*/) +int pme_gpu_get_atom_data_alignment(const PmeGpu* /*unused*/) { - //TODO: this can be simplified, as c_pmeAtomDataAlignment is now constant + // TODO: this can be simplified, as c_pmeAtomDataAlignment is now constant if (c_usePadding) { return c_pmeAtomDataAlignment; @@ -126,10 +126,9 @@ int pme_gpu_get_atom_data_alignment(const PmeGpu * /*unused*/) { return 0; } - } -int pme_gpu_get_atoms_per_warp(const PmeGpu *pmeGpu) +int pme_gpu_get_atoms_per_warp(const PmeGpu* pmeGpu) { if (c_useOrderThreadsPerAtom) { @@ -141,107 +140,111 @@ int pme_gpu_get_atoms_per_warp(const PmeGpu *pmeGpu) } } -void pme_gpu_synchronize(const PmeGpu *pmeGpu) +void pme_gpu_synchronize(const PmeGpu* pmeGpu) { gpuStreamSynchronize(pmeGpu->archSpecific->pmeStream); } -void pme_gpu_alloc_energy_virial(PmeGpu *pmeGpu) +void pme_gpu_alloc_energy_virial(PmeGpu* pmeGpu) { const size_t energyAndVirialSize = c_virialAndEnergyCount * sizeof(float); - allocateDeviceBuffer(&pmeGpu->kernelParams->constants.d_virialAndEnergy, c_virialAndEnergyCount, pmeGpu->archSpecific->context); - pmalloc(reinterpret_cast(&pmeGpu->staging.h_virialAndEnergy), energyAndVirialSize); + allocateDeviceBuffer(&pmeGpu->kernelParams->constants.d_virialAndEnergy, c_virialAndEnergyCount, + pmeGpu->archSpecific->context); + pmalloc(reinterpret_cast(&pmeGpu->staging.h_virialAndEnergy), energyAndVirialSize); } -void pme_gpu_free_energy_virial(PmeGpu *pmeGpu) +void pme_gpu_free_energy_virial(PmeGpu* pmeGpu) { freeDeviceBuffer(&pmeGpu->kernelParams->constants.d_virialAndEnergy); pfree(pmeGpu->staging.h_virialAndEnergy); pmeGpu->staging.h_virialAndEnergy = nullptr; } -void pme_gpu_clear_energy_virial(const PmeGpu *pmeGpu) +void pme_gpu_clear_energy_virial(const PmeGpu* pmeGpu) { clearDeviceBufferAsync(&pmeGpu->kernelParams->constants.d_virialAndEnergy, 0, c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream); } -void pme_gpu_realloc_and_copy_bspline_values(PmeGpu *pmeGpu) +void pme_gpu_realloc_and_copy_bspline_values(PmeGpu* pmeGpu) { - const int splineValuesOffset[DIM] = { - 0, - pmeGpu->kernelParams->grid.realGridSize[XX], - pmeGpu->kernelParams->grid.realGridSize[XX] + pmeGpu->kernelParams->grid.realGridSize[YY] - }; + const int splineValuesOffset[DIM] = { 0, pmeGpu->kernelParams->grid.realGridSize[XX], + pmeGpu->kernelParams->grid.realGridSize[XX] + + pmeGpu->kernelParams->grid.realGridSize[YY] }; memcpy(&pmeGpu->kernelParams->grid.splineValuesOffset, &splineValuesOffset, sizeof(splineValuesOffset)); - const int newSplineValuesSize = pmeGpu->kernelParams->grid.realGridSize[XX] + - pmeGpu->kernelParams->grid.realGridSize[YY] + - pmeGpu->kernelParams->grid.realGridSize[ZZ]; + const int newSplineValuesSize = pmeGpu->kernelParams->grid.realGridSize[XX] + + pmeGpu->kernelParams->grid.realGridSize[YY] + + pmeGpu->kernelParams->grid.realGridSize[ZZ]; const bool shouldRealloc = (newSplineValuesSize > pmeGpu->archSpecific->splineValuesSize); reallocateDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli, newSplineValuesSize, - &pmeGpu->archSpecific->splineValuesSize, &pmeGpu->archSpecific->splineValuesSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->splineValuesSize, + &pmeGpu->archSpecific->splineValuesSizeAlloc, pmeGpu->archSpecific->context); if (shouldRealloc) { /* Reallocate the host buffer */ pfree(pmeGpu->staging.h_splineModuli); - pmalloc(reinterpret_cast(&pmeGpu->staging.h_splineModuli), newSplineValuesSize * sizeof(float)); + pmalloc(reinterpret_cast(&pmeGpu->staging.h_splineModuli), + newSplineValuesSize * sizeof(float)); } for (int i = 0; i < DIM; i++) { - memcpy(pmeGpu->staging.h_splineModuli + splineValuesOffset[i], pmeGpu->common->bsp_mod[i].data(), pmeGpu->common->bsp_mod[i].size() * sizeof(float)); + memcpy(pmeGpu->staging.h_splineModuli + splineValuesOffset[i], + pmeGpu->common->bsp_mod[i].data(), pmeGpu->common->bsp_mod[i].size() * sizeof(float)); } /* TODO: pin original buffer instead! */ copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli, pmeGpu->staging.h_splineModuli, - 0, newSplineValuesSize, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + 0, newSplineValuesSize, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_free_bspline_values(const PmeGpu *pmeGpu) +void pme_gpu_free_bspline_values(const PmeGpu* pmeGpu) { pfree(pmeGpu->staging.h_splineModuli); freeDeviceBuffer(&pmeGpu->kernelParams->grid.d_splineModuli); } -void pme_gpu_realloc_forces(PmeGpu *pmeGpu) +void pme_gpu_realloc_forces(PmeGpu* pmeGpu) { const size_t newForcesSize = pmeGpu->nAtomsAlloc * DIM; GMX_ASSERT(newForcesSize > 0, "Bad number of atoms in PME GPU"); reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, newForcesSize, - &pmeGpu->archSpecific->forcesSize, &pmeGpu->archSpecific->forcesSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->forcesSize, + &pmeGpu->archSpecific->forcesSizeAlloc, pmeGpu->archSpecific->context); pmeGpu->staging.h_forces.reserveWithPadding(pmeGpu->nAtomsAlloc); pmeGpu->staging.h_forces.resizeWithPadding(pmeGpu->kernelParams->atoms.nAtoms); } -void pme_gpu_free_forces(const PmeGpu *pmeGpu) +void pme_gpu_free_forces(const PmeGpu* pmeGpu) { freeDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces); } -void pme_gpu_copy_input_forces(PmeGpu *pmeGpu) +void pme_gpu_copy_input_forces(PmeGpu* pmeGpu) { GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU"); - float *h_forcesFloat = reinterpret_cast(pmeGpu->staging.h_forces.data()); - copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, h_forcesFloat, - 0, DIM * pmeGpu->kernelParams->atoms.nAtoms, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + float* h_forcesFloat = reinterpret_cast(pmeGpu->staging.h_forces.data()); + copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_forces, h_forcesFloat, 0, + DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_copy_output_forces(PmeGpu *pmeGpu) +void pme_gpu_copy_output_forces(PmeGpu* pmeGpu) { GMX_ASSERT(pmeGpu->kernelParams->atoms.nAtoms > 0, "Bad number of atoms in PME GPU"); - float *h_forcesFloat = reinterpret_cast(pmeGpu->staging.h_forces.data()); - copyFromDeviceBuffer(h_forcesFloat, &pmeGpu->kernelParams->atoms.d_forces, - 0, DIM * pmeGpu->kernelParams->atoms.nAtoms, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + float* h_forcesFloat = reinterpret_cast(pmeGpu->staging.h_forces.data()); + copyFromDeviceBuffer(h_forcesFloat, &pmeGpu->kernelParams->atoms.d_forces, 0, + DIM * pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_realloc_coordinates(const PmeGpu *pmeGpu) +void pme_gpu_realloc_coordinates(const PmeGpu* pmeGpu) { const size_t newCoordinatesSize = pmeGpu->nAtomsAlloc * DIM; GMX_ASSERT(newCoordinatesSize > 0, "Bad number of atoms in PME GPU"); reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coordinates, newCoordinatesSize, - &pmeGpu->archSpecific->coordinatesSize, &pmeGpu->archSpecific->coordinatesSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->coordinatesSize, + &pmeGpu->archSpecific->coordinatesSizeAlloc, pmeGpu->archSpecific->context); if (c_usePadding) { const size_t paddingIndex = DIM * pmeGpu->kernelParams->atoms.nAtoms; @@ -254,20 +257,21 @@ void pme_gpu_realloc_coordinates(const PmeGpu *pmeGpu) } } -void pme_gpu_free_coordinates(const PmeGpu *pmeGpu) +void pme_gpu_free_coordinates(const PmeGpu* pmeGpu) { freeDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coordinates); } -void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu *pmeGpu, const float *h_coefficients) +void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu* pmeGpu, const float* h_coefficients) { GMX_ASSERT(h_coefficients, "Bad host-side charge buffer in PME GPU"); const size_t newCoefficientsSize = pmeGpu->nAtomsAlloc; GMX_ASSERT(newCoefficientsSize > 0, "Bad number of atoms in PME GPU"); reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients, newCoefficientsSize, - &pmeGpu->archSpecific->coefficientsSize, &pmeGpu->archSpecific->coefficientsSizeAlloc, pmeGpu->archSpecific->context); - copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients, const_cast(h_coefficients), - 0, pmeGpu->kernelParams->atoms.nAtoms, + &pmeGpu->archSpecific->coefficientsSize, + &pmeGpu->archSpecific->coefficientsSizeAlloc, pmeGpu->archSpecific->context); + copyToDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients, + const_cast(h_coefficients), 0, pmeGpu->kernelParams->atoms.nAtoms, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); if (c_usePadding) { @@ -281,16 +285,16 @@ void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu *pmeGpu, const flo } } -void pme_gpu_free_coefficients(const PmeGpu *pmeGpu) +void pme_gpu_free_coefficients(const PmeGpu* pmeGpu) { freeDeviceBuffer(&pmeGpu->kernelParams->atoms.d_coefficients); } -void pme_gpu_realloc_spline_data(PmeGpu *pmeGpu) +void pme_gpu_realloc_spline_data(PmeGpu* pmeGpu) { - const int order = pmeGpu->common->pme_order; - const int alignment = pme_gpu_get_atoms_per_warp(pmeGpu); - const size_t nAtomsPadded = ((pmeGpu->nAtomsAlloc + alignment - 1) / alignment) * alignment; + const int order = pmeGpu->common->pme_order; + const int alignment = pme_gpu_get_atoms_per_warp(pmeGpu); + const size_t nAtomsPadded = ((pmeGpu->nAtomsAlloc + alignment - 1) / alignment) * alignment; const int newSplineDataSize = DIM * order * nAtomsPadded; GMX_ASSERT(newSplineDataSize > 0, "Bad number of atoms in PME GPU"); /* Two arrays of the same size */ @@ -300,18 +304,19 @@ void pme_gpu_realloc_spline_data(PmeGpu *pmeGpu) reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta, newSplineDataSize, ¤tSizeTemp, ¤tSizeTempAlloc, pmeGpu->archSpecific->context); reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_dtheta, newSplineDataSize, - &pmeGpu->archSpecific->splineDataSize, &pmeGpu->archSpecific->splineDataSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->splineDataSize, + &pmeGpu->archSpecific->splineDataSizeAlloc, pmeGpu->archSpecific->context); // the host side reallocation if (shouldRealloc) { pfree(pmeGpu->staging.h_theta); - pmalloc(reinterpret_cast(&pmeGpu->staging.h_theta), newSplineDataSize * sizeof(float)); + pmalloc(reinterpret_cast(&pmeGpu->staging.h_theta), newSplineDataSize * sizeof(float)); pfree(pmeGpu->staging.h_dtheta); - pmalloc(reinterpret_cast(&pmeGpu->staging.h_dtheta), newSplineDataSize * sizeof(float)); + pmalloc(reinterpret_cast(&pmeGpu->staging.h_dtheta), newSplineDataSize * sizeof(float)); } } -void pme_gpu_free_spline_data(const PmeGpu *pmeGpu) +void pme_gpu_free_spline_data(const PmeGpu* pmeGpu) { /* Two arrays of the same size */ freeDeviceBuffer(&pmeGpu->kernelParams->atoms.d_theta); @@ -320,53 +325,57 @@ void pme_gpu_free_spline_data(const PmeGpu *pmeGpu) pfree(pmeGpu->staging.h_dtheta); } -void pme_gpu_realloc_grid_indices(PmeGpu *pmeGpu) +void pme_gpu_realloc_grid_indices(PmeGpu* pmeGpu) { const size_t newIndicesSize = DIM * pmeGpu->nAtomsAlloc; GMX_ASSERT(newIndicesSize > 0, "Bad number of atoms in PME GPU"); reallocateDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices, newIndicesSize, - &pmeGpu->archSpecific->gridlineIndicesSize, &pmeGpu->archSpecific->gridlineIndicesSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->gridlineIndicesSize, + &pmeGpu->archSpecific->gridlineIndicesSizeAlloc, pmeGpu->archSpecific->context); pfree(pmeGpu->staging.h_gridlineIndices); - pmalloc(reinterpret_cast(&pmeGpu->staging.h_gridlineIndices), newIndicesSize * sizeof(int)); + pmalloc(reinterpret_cast(&pmeGpu->staging.h_gridlineIndices), newIndicesSize * sizeof(int)); } -void pme_gpu_free_grid_indices(const PmeGpu *pmeGpu) +void pme_gpu_free_grid_indices(const PmeGpu* pmeGpu) { freeDeviceBuffer(&pmeGpu->kernelParams->atoms.d_gridlineIndices); pfree(pmeGpu->staging.h_gridlineIndices); } -void pme_gpu_realloc_grids(PmeGpu *pmeGpu) +void pme_gpu_realloc_grids(PmeGpu* pmeGpu) { - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); - const int newRealGridSize = kernelParamsPtr->grid.realGridSizePadded[XX] * - kernelParamsPtr->grid.realGridSizePadded[YY] * - kernelParamsPtr->grid.realGridSizePadded[ZZ]; - const int newComplexGridSize = kernelParamsPtr->grid.complexGridSizePadded[XX] * - kernelParamsPtr->grid.complexGridSizePadded[YY] * - kernelParamsPtr->grid.complexGridSizePadded[ZZ] * 2; + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); + const int newRealGridSize = kernelParamsPtr->grid.realGridSizePadded[XX] + * kernelParamsPtr->grid.realGridSizePadded[YY] + * kernelParamsPtr->grid.realGridSizePadded[ZZ]; + const int newComplexGridSize = kernelParamsPtr->grid.complexGridSizePadded[XX] + * kernelParamsPtr->grid.complexGridSizePadded[YY] + * kernelParamsPtr->grid.complexGridSizePadded[ZZ] * 2; // Multiplied by 2 because we count complex grid size for complex numbers, but all allocations/pointers are float if (pmeGpu->archSpecific->performOutOfPlaceFFT) { /* 2 separate grids */ reallocateDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid, newComplexGridSize, - &pmeGpu->archSpecific->complexGridSize, &pmeGpu->archSpecific->complexGridSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->complexGridSize, + &pmeGpu->archSpecific->complexGridSizeAlloc, pmeGpu->archSpecific->context); reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid, newRealGridSize, - &pmeGpu->archSpecific->realGridSize, &pmeGpu->archSpecific->realGridSizeAlloc, pmeGpu->archSpecific->context); + &pmeGpu->archSpecific->realGridSize, + &pmeGpu->archSpecific->realGridSizeAlloc, pmeGpu->archSpecific->context); } else { /* A single buffer so that any grid will fit */ const int newGridsSize = std::max(newRealGridSize, newComplexGridSize); - reallocateDeviceBuffer(&kernelParamsPtr->grid.d_realGrid, newGridsSize, - &pmeGpu->archSpecific->realGridSize, &pmeGpu->archSpecific->realGridSizeAlloc, pmeGpu->archSpecific->context); + reallocateDeviceBuffer( + &kernelParamsPtr->grid.d_realGrid, newGridsSize, &pmeGpu->archSpecific->realGridSize, + &pmeGpu->archSpecific->realGridSizeAlloc, pmeGpu->archSpecific->context); kernelParamsPtr->grid.d_fourierGrid = kernelParamsPtr->grid.d_realGrid; pmeGpu->archSpecific->complexGridSize = pmeGpu->archSpecific->realGridSize; // the size might get used later for copying the grid } } -void pme_gpu_free_grids(const PmeGpu *pmeGpu) +void pme_gpu_free_grids(const PmeGpu* pmeGpu) { if (pmeGpu->archSpecific->performOutOfPlaceFFT) { @@ -375,54 +384,53 @@ void pme_gpu_free_grids(const PmeGpu *pmeGpu) freeDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid); } -void pme_gpu_clear_grids(const PmeGpu *pmeGpu) +void pme_gpu_clear_grids(const PmeGpu* pmeGpu) { clearDeviceBufferAsync(&pmeGpu->kernelParams->grid.d_realGrid, 0, pmeGpu->archSpecific->realGridSize, pmeGpu->archSpecific->pmeStream); } -void pme_gpu_realloc_and_copy_fract_shifts(PmeGpu *pmeGpu) +void pme_gpu_realloc_and_copy_fract_shifts(PmeGpu* pmeGpu) { pme_gpu_free_fract_shifts(pmeGpu); - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); - const int nx = kernelParamsPtr->grid.realGridSize[XX]; - const int ny = kernelParamsPtr->grid.realGridSize[YY]; - const int nz = kernelParamsPtr->grid.realGridSize[ZZ]; - const int cellCount = c_pmeNeighborUnitcellCount; - const int gridDataOffset[DIM] = {0, cellCount * nx, cellCount * (nx + ny)}; + const int nx = kernelParamsPtr->grid.realGridSize[XX]; + const int ny = kernelParamsPtr->grid.realGridSize[YY]; + const int nz = kernelParamsPtr->grid.realGridSize[ZZ]; + const int cellCount = c_pmeNeighborUnitcellCount; + const int gridDataOffset[DIM] = { 0, cellCount * nx, cellCount * (nx + ny) }; memcpy(kernelParamsPtr->grid.tablesOffsets, &gridDataOffset, sizeof(gridDataOffset)); - const int newFractShiftsSize = cellCount * (nx + ny + nz); + const int newFractShiftsSize = cellCount * (nx + ny + nz); #if GMX_GPU == GMX_GPU_CUDA - initParamLookupTable(kernelParamsPtr->grid.d_fractShiftsTable, - kernelParamsPtr->fractShiftsTableTexture, - pmeGpu->common->fsh.data(), - newFractShiftsSize); + initParamLookupTable(kernelParamsPtr->grid.d_fractShiftsTable, kernelParamsPtr->fractShiftsTableTexture, + pmeGpu->common->fsh.data(), newFractShiftsSize); initParamLookupTable(kernelParamsPtr->grid.d_gridlineIndicesTable, - kernelParamsPtr->gridlineIndicesTableTexture, - pmeGpu->common->nn.data(), + kernelParamsPtr->gridlineIndicesTableTexture, pmeGpu->common->nn.data(), newFractShiftsSize); #elif GMX_GPU == GMX_GPU_OPENCL // No dedicated texture routines.... - allocateDeviceBuffer(&kernelParamsPtr->grid.d_fractShiftsTable, newFractShiftsSize, pmeGpu->archSpecific->context); - allocateDeviceBuffer(&kernelParamsPtr->grid.d_gridlineIndicesTable, newFractShiftsSize, pmeGpu->archSpecific->context); - copyToDeviceBuffer(&kernelParamsPtr->grid.d_fractShiftsTable, pmeGpu->common->fsh.data(), - 0, newFractShiftsSize, - pmeGpu->archSpecific->pmeStream, GpuApiCallBehavior::Async, nullptr); - copyToDeviceBuffer(&kernelParamsPtr->grid.d_gridlineIndicesTable, pmeGpu->common->nn.data(), - 0, newFractShiftsSize, - pmeGpu->archSpecific->pmeStream, GpuApiCallBehavior::Async, nullptr); + allocateDeviceBuffer(&kernelParamsPtr->grid.d_fractShiftsTable, newFractShiftsSize, + pmeGpu->archSpecific->context); + allocateDeviceBuffer(&kernelParamsPtr->grid.d_gridlineIndicesTable, newFractShiftsSize, + pmeGpu->archSpecific->context); + copyToDeviceBuffer(&kernelParamsPtr->grid.d_fractShiftsTable, pmeGpu->common->fsh.data(), 0, + newFractShiftsSize, pmeGpu->archSpecific->pmeStream, + GpuApiCallBehavior::Async, nullptr); + copyToDeviceBuffer(&kernelParamsPtr->grid.d_gridlineIndicesTable, pmeGpu->common->nn.data(), 0, + newFractShiftsSize, pmeGpu->archSpecific->pmeStream, + GpuApiCallBehavior::Async, nullptr); #endif } -void pme_gpu_free_fract_shifts(const PmeGpu *pmeGpu) +void pme_gpu_free_fract_shifts(const PmeGpu* pmeGpu) { - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); #if GMX_GPU == GMX_GPU_CUDA destroyParamLookupTable(kernelParamsPtr->grid.d_fractShiftsTable, kernelParamsPtr->fractShiftsTableTexture); @@ -434,76 +442,73 @@ void pme_gpu_free_fract_shifts(const PmeGpu *pmeGpu) #endif } -bool pme_gpu_stream_query(const PmeGpu *pmeGpu) +bool pme_gpu_stream_query(const PmeGpu* pmeGpu) { return haveStreamTasksCompleted(pmeGpu->archSpecific->pmeStream); } -void pme_gpu_copy_input_gather_grid(const PmeGpu *pmeGpu, float *h_grid) +void pme_gpu_copy_input_gather_grid(const PmeGpu* pmeGpu, float* h_grid) { - copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid, h_grid, - 0, pmeGpu->archSpecific->realGridSize, + copyToDeviceBuffer(&pmeGpu->kernelParams->grid.d_realGrid, h_grid, 0, pmeGpu->archSpecific->realGridSize, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_copy_output_spread_grid(const PmeGpu *pmeGpu, float *h_grid) +void pme_gpu_copy_output_spread_grid(const PmeGpu* pmeGpu, float* h_grid) { - copyFromDeviceBuffer(h_grid, &pmeGpu->kernelParams->grid.d_realGrid, - 0, pmeGpu->archSpecific->realGridSize, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + copyFromDeviceBuffer(h_grid, &pmeGpu->kernelParams->grid.d_realGrid, 0, + pmeGpu->archSpecific->realGridSize, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); pmeGpu->archSpecific->syncSpreadGridD2H.markEvent(pmeGpu->archSpecific->pmeStream); } -void pme_gpu_copy_output_spread_atom_data(const PmeGpu *pmeGpu) +void pme_gpu_copy_output_spread_atom_data(const PmeGpu* pmeGpu) { - const int alignment = pme_gpu_get_atoms_per_warp(pmeGpu); - const size_t nAtomsPadded = ((pmeGpu->nAtomsAlloc + alignment - 1) / alignment) * alignment; - const size_t splinesCount = DIM * nAtomsPadded * pmeGpu->common->pme_order; - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); - copyFromDeviceBuffer(pmeGpu->staging.h_dtheta, &kernelParamsPtr->atoms.d_dtheta, - 0, splinesCount, + const int alignment = pme_gpu_get_atoms_per_warp(pmeGpu); + const size_t nAtomsPadded = ((pmeGpu->nAtomsAlloc + alignment - 1) / alignment) * alignment; + const size_t splinesCount = DIM * nAtomsPadded * pmeGpu->common->pme_order; + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); + copyFromDeviceBuffer(pmeGpu->staging.h_dtheta, &kernelParamsPtr->atoms.d_dtheta, 0, splinesCount, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); - copyFromDeviceBuffer(pmeGpu->staging.h_theta, &kernelParamsPtr->atoms.d_theta, - 0, splinesCount, + copyFromDeviceBuffer(pmeGpu->staging.h_theta, &kernelParamsPtr->atoms.d_theta, 0, splinesCount, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); copyFromDeviceBuffer(pmeGpu->staging.h_gridlineIndices, &kernelParamsPtr->atoms.d_gridlineIndices, - 0, kernelParamsPtr->atoms.nAtoms * DIM, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_copy_input_gather_atom_data(const PmeGpu *pmeGpu) +void pme_gpu_copy_input_gather_atom_data(const PmeGpu* pmeGpu) { const int alignment = pme_gpu_get_atoms_per_warp(pmeGpu); const size_t nAtomsPadded = ((pmeGpu->nAtomsAlloc + alignment - 1) / alignment) * alignment; const size_t splinesCount = DIM * nAtomsPadded * pmeGpu->common->pme_order; - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); if (c_usePadding) { // TODO: could clear only the padding and not the whole thing, but this is a test-exclusive code anyway clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_gridlineIndices, 0, pmeGpu->nAtomsAlloc * DIM, pmeGpu->archSpecific->pmeStream); clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_dtheta, 0, - pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM, pmeGpu->archSpecific->pmeStream); + pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM, + pmeGpu->archSpecific->pmeStream); clearDeviceBufferAsync(&kernelParamsPtr->atoms.d_theta, 0, - pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM, pmeGpu->archSpecific->pmeStream); + pmeGpu->nAtomsAlloc * pmeGpu->common->pme_order * DIM, + pmeGpu->archSpecific->pmeStream); } - copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta, pmeGpu->staging.h_dtheta, - 0, splinesCount, + copyToDeviceBuffer(&kernelParamsPtr->atoms.d_dtheta, pmeGpu->staging.h_dtheta, 0, splinesCount, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); - copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta, pmeGpu->staging.h_theta, - 0, splinesCount, + copyToDeviceBuffer(&kernelParamsPtr->atoms.d_theta, pmeGpu->staging.h_theta, 0, splinesCount, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); copyToDeviceBuffer(&kernelParamsPtr->atoms.d_gridlineIndices, pmeGpu->staging.h_gridlineIndices, - 0, kernelParamsPtr->atoms.nAtoms * DIM, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + 0, kernelParamsPtr->atoms.nAtoms * DIM, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } -void pme_gpu_sync_spread_grid(const PmeGpu *pmeGpu) +void pme_gpu_sync_spread_grid(const PmeGpu* pmeGpu) { pmeGpu->archSpecific->syncSpreadGridD2H.waitForEvent(); } -void pme_gpu_init_internal(PmeGpu *pmeGpu) +void pme_gpu_init_internal(PmeGpu* pmeGpu) { #if GMX_GPU == GMX_GPU_CUDA // Prepare to use the device that this PME task was assigned earlier. @@ -555,15 +560,16 @@ void pme_gpu_init_internal(PmeGpu *pmeGpu) stat = cudaDeviceGetStreamPriorityRange(&lowest_priority, &highest_priority); CU_RET_ERR(stat, "PME cudaDeviceGetStreamPriorityRange failed"); stat = cudaStreamCreateWithPriority(&pmeGpu->archSpecific->pmeStream, - cudaStreamDefault, //cudaStreamNonBlocking, + cudaStreamDefault, // cudaStreamNonBlocking, highest_priority); CU_RET_ERR(stat, "cudaStreamCreateWithPriority on the PME stream failed"); #elif GMX_GPU == GMX_GPU_OPENCL - cl_command_queue_properties queueProperties = pmeGpu->archSpecific->useTiming ? CL_QUEUE_PROFILING_ENABLE : 0; - cl_device_id device_id = pmeGpu->deviceInfo->ocl_gpu_id.ocl_device_id; - cl_int clError; - pmeGpu->archSpecific->pmeStream = clCreateCommandQueue(pmeGpu->archSpecific->context, - device_id, queueProperties, &clError); + cl_command_queue_properties queueProperties = + pmeGpu->archSpecific->useTiming ? CL_QUEUE_PROFILING_ENABLE : 0; + cl_device_id device_id = pmeGpu->deviceInfo->ocl_gpu_id.ocl_device_id; + cl_int clError; + pmeGpu->archSpecific->pmeStream = + clCreateCommandQueue(pmeGpu->archSpecific->context, device_id, queueProperties, &clError); if (clError != CL_SUCCESS) { GMX_THROW(gmx::InternalError("Failed to create PME command queue")); @@ -571,7 +577,7 @@ void pme_gpu_init_internal(PmeGpu *pmeGpu) #endif } -void pme_gpu_destroy_specific(const PmeGpu *pmeGpu) +void pme_gpu_destroy_specific(const PmeGpu* pmeGpu) { #if GMX_GPU == GMX_GPU_CUDA /* Destroy the CUDA stream */ @@ -586,7 +592,7 @@ void pme_gpu_destroy_specific(const PmeGpu *pmeGpu) #endif } -void pme_gpu_reinit_3dfft(const PmeGpu *pmeGpu) +void pme_gpu_reinit_3dfft(const PmeGpu* pmeGpu) { if (pme_gpu_performs_FFT(pmeGpu)) { @@ -598,7 +604,7 @@ void pme_gpu_reinit_3dfft(const PmeGpu *pmeGpu) } } -void pme_gpu_destroy_3dfft(const PmeGpu *pmeGpu) +void pme_gpu_destroy_3dfft(const PmeGpu* pmeGpu) { pmeGpu->archSpecific->fftSetup.resize(0); } @@ -638,28 +644,34 @@ int getSplineParamFullIndex(int order, int splineIndex, int dimIndex, int atomIn break; default: - GMX_THROW(gmx::NotImplementedError(gmx::formatString("Test function call not unrolled for atomsPerWarp = %d in getSplineParamFullIndex", atomsPerWarp))); + GMX_THROW(gmx::NotImplementedError( + gmx::formatString("Test function call not unrolled for atomsPerWarp = %d in " + "getSplineParamFullIndex", + atomsPerWarp))); } return result; } -void pme_gpu_getEnergyAndVirial(const gmx_pme_t &pme, - PmeOutput *output) +void pme_gpu_getEnergyAndVirial(const gmx_pme_t& pme, PmeOutput* output) { - const PmeGpu *pmeGpu = pme.gpu; + const PmeGpu* pmeGpu = pme.gpu; for (int j = 0; j < c_virialAndEnergyCount; j++) { - GMX_ASSERT(std::isfinite(pmeGpu->staging.h_virialAndEnergy[j]), "PME GPU produces incorrect energy/virial."); + GMX_ASSERT(std::isfinite(pmeGpu->staging.h_virialAndEnergy[j]), + "PME GPU produces incorrect energy/virial."); } - unsigned int j = 0; + unsigned int j = 0; output->coulombVirial_[XX][XX] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; output->coulombVirial_[YY][YY] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; output->coulombVirial_[ZZ][ZZ] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; - output->coulombVirial_[XX][YY] = output->coulombVirial_[YY][XX] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; - output->coulombVirial_[XX][ZZ] = output->coulombVirial_[ZZ][XX] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; - output->coulombVirial_[YY][ZZ] = output->coulombVirial_[ZZ][YY] = 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; - output->coulombEnergy_ = 0.5F * pmeGpu->staging.h_virialAndEnergy[j++]; + output->coulombVirial_[XX][YY] = output->coulombVirial_[YY][XX] = + 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; + output->coulombVirial_[XX][ZZ] = output->coulombVirial_[ZZ][XX] = + 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; + output->coulombVirial_[YY][ZZ] = output->coulombVirial_[ZZ][YY] = + 0.25F * pmeGpu->staging.h_virialAndEnergy[j++]; + output->coulombEnergy_ = 0.5F * pmeGpu->staging.h_virialAndEnergy[j++]; } /*! \brief Sets the force-related members in \p output @@ -667,23 +679,21 @@ void pme_gpu_getEnergyAndVirial(const gmx_pme_t &pme, * \param[in] pmeGpu PME GPU data structure * \param[out] output Pointer to PME output data structure */ -static void pme_gpu_getForceOutput(PmeGpu *pmeGpu, - PmeOutput *output) +static void pme_gpu_getForceOutput(PmeGpu* pmeGpu, PmeOutput* output) { output->haveForceOutput_ = !pmeGpu->settings.useGpuForceReduction; if (output->haveForceOutput_) { - output->forces_ = pmeGpu->staging.h_forces; + output->forces_ = pmeGpu->staging.h_forces; } } -PmeOutput pme_gpu_getOutput(const gmx_pme_t &pme, - const int flags) +PmeOutput pme_gpu_getOutput(const gmx_pme_t& pme, const int flags) { - PmeGpu *pmeGpu = pme.gpu; + PmeGpu* pmeGpu = pme.gpu; const bool haveComputedEnergyAndVirial = (flags & GMX_PME_CALC_ENER_VIR) != 0; - PmeOutput output; + PmeOutput output; pme_gpu_getForceOutput(pmeGpu, &output); @@ -703,15 +713,14 @@ PmeOutput pme_gpu_getOutput(const gmx_pme_t &pme, return output; } -void pme_gpu_update_input_box(PmeGpu gmx_unused *pmeGpu, - const matrix gmx_unused box) +void pme_gpu_update_input_box(PmeGpu gmx_unused* pmeGpu, const matrix gmx_unused box) { #if GMX_DOUBLE GMX_THROW(gmx::NotImplementedError("PME is implemented for single-precision only on GPU")); #else - matrix scaledBox; + matrix scaledBox; pmeGpu->common->boxScaler->scaleBox(box, scaledBox); - auto *kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); + auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); kernelParamsPtr->current.boxVolume = scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ]; GMX_ASSERT(kernelParamsPtr->current.boxVolume != 0.0F, "Zero volume of the unit cell"); matrix recipBox; @@ -721,12 +730,9 @@ void pme_gpu_update_input_box(PmeGpu gmx_unused *pmeGpu, * Spread uses matrix columns (while solve and gather use rows). * There is no particular reason for this; it might be further rethought/optimized for better access patterns. */ - const real newRecipBox[DIM][DIM] = - { - {recipBox[XX][XX], recipBox[YY][XX], recipBox[ZZ][XX]}, - { 0.0, recipBox[YY][YY], recipBox[ZZ][YY]}, - { 0.0, 0.0, recipBox[ZZ][ZZ]} - }; + const real newRecipBox[DIM][DIM] = { { recipBox[XX][XX], recipBox[YY][XX], recipBox[ZZ][XX] }, + { 0.0, recipBox[YY][YY], recipBox[ZZ][YY] }, + { 0.0, 0.0, recipBox[ZZ][ZZ] } }; memcpy(kernelParamsPtr->current.recipBox, newRecipBox, sizeof(matrix)); #endif } @@ -736,16 +742,18 @@ void pme_gpu_update_input_box(PmeGpu gmx_unused *pmeGpu, * * \param[in] pmeGpu The PME GPU structure. */ -static void pme_gpu_reinit_grids(PmeGpu *pmeGpu) +static void pme_gpu_reinit_grids(PmeGpu* pmeGpu) { - auto *kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); - kernelParamsPtr->grid.ewaldFactor = (M_PI * M_PI) / (pmeGpu->common->ewaldcoeff_q * pmeGpu->common->ewaldcoeff_q); + auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); + kernelParamsPtr->grid.ewaldFactor = + (M_PI * M_PI) / (pmeGpu->common->ewaldcoeff_q * pmeGpu->common->ewaldcoeff_q); /* The grid size variants */ for (int i = 0; i < DIM; i++) { - kernelParamsPtr->grid.realGridSize[i] = pmeGpu->common->nk[i]; - kernelParamsPtr->grid.realGridSizeFP[i] = static_cast(kernelParamsPtr->grid.realGridSize[i]); + kernelParamsPtr->grid.realGridSize[i] = pmeGpu->common->nk[i]; + kernelParamsPtr->grid.realGridSizeFP[i] = + static_cast(kernelParamsPtr->grid.realGridSize[i]); kernelParamsPtr->grid.realGridSizePadded[i] = kernelParamsPtr->grid.realGridSize[i]; // The complex grid currently uses no padding; @@ -757,7 +765,8 @@ static void pme_gpu_reinit_grids(PmeGpu *pmeGpu) if (!pme_gpu_performs_FFT(pmeGpu)) { // This allows for GPU spreading grid and CPU fftgrid to have the same layout, so that we can copy the data directly - kernelParamsPtr->grid.realGridSizePadded[ZZ] = (kernelParamsPtr->grid.realGridSize[ZZ] / 2 + 1) * 2; + kernelParamsPtr->grid.realGridSizePadded[ZZ] = + (kernelParamsPtr->grid.realGridSize[ZZ] / 2 + 1) * 2; } /* GPU FFT: n real elements correspond to (n / 2 + 1) complex elements in minor dimension */ @@ -782,18 +791,18 @@ static void pme_gpu_reinit_grids(PmeGpu *pmeGpu) * * \param[in] pme The PME structure. */ -static void pme_gpu_copy_common_data_from(const gmx_pme_t *pme) +static void pme_gpu_copy_common_data_from(const gmx_pme_t* pme) { /* TODO: Consider refactoring the CPU PME code to use the same structure, * so that this function becomes 2 lines */ - PmeGpu *pmeGpu = pme->gpu; - pmeGpu->common->ngrids = pme->ngrids; - pmeGpu->common->epsilon_r = pme->epsilon_r; - pmeGpu->common->ewaldcoeff_q = pme->ewaldcoeff_q; - pmeGpu->common->nk[XX] = pme->nkx; - pmeGpu->common->nk[YY] = pme->nky; - pmeGpu->common->nk[ZZ] = pme->nkz; - pmeGpu->common->pme_order = pme->pme_order; + PmeGpu* pmeGpu = pme->gpu; + pmeGpu->common->ngrids = pme->ngrids; + pmeGpu->common->epsilon_r = pme->epsilon_r; + pmeGpu->common->ewaldcoeff_q = pme->ewaldcoeff_q; + pmeGpu->common->nk[XX] = pme->nkx; + pmeGpu->common->nk[YY] = pme->nky; + pmeGpu->common->nk[ZZ] = pme->nkz; + pmeGpu->common->pme_order = pme->pme_order; if (pmeGpu->common->pme_order != c_pmeGpuOrder) { GMX_THROW(gmx::NotImplementedError("pme_order != 4 is not implemented!")); @@ -824,12 +833,10 @@ static void pme_gpu_copy_common_data_from(const gmx_pme_t *pme) * \param[in,out] gpuInfo The GPU information structure. * \param[in] pmeGpuProgram The handle to the program/kernel data created outside (e.g. in unit tests/runner) */ -static void pme_gpu_init(gmx_pme_t *pme, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram) +static void pme_gpu_init(gmx_pme_t* pme, const gmx_device_info_t* gpuInfo, PmeGpuProgramHandle pmeGpuProgram) { - pme->gpu = new PmeGpu(); - PmeGpu *pmeGpu = pme->gpu; + pme->gpu = new PmeGpu(); + PmeGpu* pmeGpu = pme->gpu; changePinningPolicy(&pmeGpu->staging.h_forces, pme_get_pinning_policy()); pmeGpu->common = std::make_shared(); @@ -856,18 +863,21 @@ static void pme_gpu_init(gmx_pme_t *pme, GMX_ASSERT(pmeGpu->common->epsilon_r != 0.0F, "PME GPU: bad electrostatic coefficient"); - auto *kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); + auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); kernelParamsPtr->constants.elFactor = ONE_4PI_EPS0 / pmeGpu->common->epsilon_r; } -void pme_gpu_transform_spline_atom_data(const PmeGpu *pmeGpu, const PmeAtomComm *atc, - PmeSplineDataType type, int dimIndex, PmeLayoutTransform transform) +void pme_gpu_transform_spline_atom_data(const PmeGpu* pmeGpu, + const PmeAtomComm* atc, + PmeSplineDataType type, + int dimIndex, + PmeLayoutTransform transform) { // The GPU atom spline data is laid out in a different way currently than the CPU one. // This function converts the data from GPU to CPU layout (in the host memory). // It is only intended for testing purposes so far. - // Ideally we should use similar layouts on CPU and GPU if we care about mixed modes and their performance - // (e.g. spreading on GPU, gathering on CPU). + // Ideally we should use similar layouts on CPU and GPU if we care about mixed modes and their + // performance (e.g. spreading on GPU, gathering on CPU). GMX_RELEASE_ASSERT(atc->nthread == 1, "Only the serial PME data layout is supported"); const uintmax_t threadIndex = 0; const auto atomCount = pme_gpu_get_kernel_params_base_ptr(pmeGpu)->atoms.nAtoms; @@ -875,8 +885,8 @@ void pme_gpu_transform_spline_atom_data(const PmeGpu *pmeGpu, const PmeAtomComm const auto pmeOrder = pmeGpu->common->pme_order; GMX_ASSERT(pmeOrder == c_pmeGpuOrder, "Only PME order 4 is implemented"); - real *cpuSplineBuffer; - float *h_splineBuffer; + real* cpuSplineBuffer; + float* h_splineBuffer; switch (type) { case PmeSplineDataType::Values: @@ -889,17 +899,19 @@ void pme_gpu_transform_spline_atom_data(const PmeGpu *pmeGpu, const PmeAtomComm h_splineBuffer = pmeGpu->staging.h_dtheta; break; - default: - GMX_THROW(gmx::InternalError("Unknown spline data type")); + default: GMX_THROW(gmx::InternalError("Unknown spline data type")); } for (auto atomIndex = 0; atomIndex < atomCount; atomIndex++) { for (auto orderIndex = 0; orderIndex < pmeOrder; orderIndex++) { - const auto gpuValueIndex = getSplineParamFullIndex(pmeOrder, orderIndex, dimIndex, atomIndex, atomsPerWarp); + const auto gpuValueIndex = + getSplineParamFullIndex(pmeOrder, orderIndex, dimIndex, atomIndex, atomsPerWarp); const auto cpuValueIndex = atomIndex * pmeOrder + orderIndex; - GMX_ASSERT(cpuValueIndex < atomCount * pmeOrder, "Atom spline data index out of bounds (while transforming GPU data layout for host)"); + GMX_ASSERT(cpuValueIndex < atomCount * pmeOrder, + "Atom spline data index out of bounds (while transforming GPU data layout " + "for host)"); switch (transform) { case PmeLayoutTransform::GpuToHost: @@ -910,19 +922,18 @@ void pme_gpu_transform_spline_atom_data(const PmeGpu *pmeGpu, const PmeAtomComm h_splineBuffer[gpuValueIndex] = cpuSplineBuffer[cpuValueIndex]; break; - default: - GMX_THROW(gmx::InternalError("Unknown layout transform")); + default: GMX_THROW(gmx::InternalError("Unknown layout transform")); } } } } -void pme_gpu_get_real_grid_sizes(const PmeGpu *pmeGpu, gmx::IVec *gridSize, gmx::IVec *paddedGridSize) +void pme_gpu_get_real_grid_sizes(const PmeGpu* pmeGpu, gmx::IVec* gridSize, gmx::IVec* paddedGridSize) { GMX_ASSERT(gridSize != nullptr, ""); GMX_ASSERT(paddedGridSize != nullptr, ""); GMX_ASSERT(pmeGpu != nullptr, ""); - auto *kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); + auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); for (int i = 0; i < DIM; i++) { (*gridSize)[i] = kernelParamsPtr->grid.realGridSize[i]; @@ -930,9 +941,7 @@ void pme_gpu_get_real_grid_sizes(const PmeGpu *pmeGpu, gmx::IVec *gridSize, gmx: } } -void pme_gpu_reinit(gmx_pme_t *pme, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram) +void pme_gpu_reinit(gmx_pme_t* pme, const gmx_device_info_t* gpuInfo, PmeGpuProgramHandle pmeGpuProgram) { if (!pme_gpu_active(pme)) { @@ -950,7 +959,8 @@ void pme_gpu_reinit(gmx_pme_t *pme, pme_gpu_copy_common_data_from(pme); } /* GPU FFT will only get used for a single rank.*/ - pme->gpu->settings.performGPUFFT = (pme->gpu->common->runMode == PmeRunMode::GPU) && !pme_gpu_uses_dd(pme->gpu); + pme->gpu->settings.performGPUFFT = + (pme->gpu->common->runMode == PmeRunMode::GPU) && !pme_gpu_uses_dd(pme->gpu); pme->gpu->settings.performGPUSolve = (pme->gpu->common->runMode == PmeRunMode::GPU); /* Reinit active timers */ @@ -966,7 +976,7 @@ void pme_gpu_reinit(gmx_pme_t *pme, std::memset(pme->gpu->common->previousBox, 0, sizeof(pme->gpu->common->previousBox)); } -void pme_gpu_destroy(PmeGpu *pmeGpu) +void pme_gpu_destroy(PmeGpu* pmeGpu) { /* Free lots of data */ pme_gpu_free_energy_virial(pmeGpu); @@ -986,21 +996,22 @@ void pme_gpu_destroy(PmeGpu *pmeGpu) delete pmeGpu; } -void pme_gpu_reinit_atoms(PmeGpu *pmeGpu, const int nAtoms, const real *charges) +void pme_gpu_reinit_atoms(PmeGpu* pmeGpu, const int nAtoms, const real* charges) { - auto *kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); + auto* kernelParamsPtr = pme_gpu_get_kernel_params_base_ptr(pmeGpu); kernelParamsPtr->atoms.nAtoms = nAtoms; - const int alignment = pme_gpu_get_atom_data_alignment(pmeGpu); - pmeGpu->nAtomsPadded = ((nAtoms + alignment - 1) / alignment) * alignment; - const int nAtomsAlloc = c_usePadding ? pmeGpu->nAtomsPadded : nAtoms; - const bool haveToRealloc = (pmeGpu->nAtomsAlloc < nAtomsAlloc); /* This check might be redundant, but is logical */ + const int alignment = pme_gpu_get_atom_data_alignment(pmeGpu); + pmeGpu->nAtomsPadded = ((nAtoms + alignment - 1) / alignment) * alignment; + const int nAtomsAlloc = c_usePadding ? pmeGpu->nAtomsPadded : nAtoms; + const bool haveToRealloc = + (pmeGpu->nAtomsAlloc < nAtomsAlloc); /* This check might be redundant, but is logical */ pmeGpu->nAtomsAlloc = nAtomsAlloc; #if GMX_DOUBLE GMX_RELEASE_ASSERT(false, "Only single precision supported"); GMX_UNUSED_VALUE(charges); #else - pme_gpu_realloc_and_copy_input_coefficients(pmeGpu, reinterpret_cast(charges)); + pme_gpu_realloc_and_copy_input_coefficients(pmeGpu, reinterpret_cast(charges)); /* Could also be checked for haveToRealloc, but the copy always needs to be performed */ #endif @@ -1012,12 +1023,13 @@ void pme_gpu_reinit_atoms(PmeGpu *pmeGpu, const int nAtoms, const real *charges) } } -void pme_gpu_3dfft(const PmeGpu *pmeGpu, gmx_fft_direction dir, int grid_index) +void pme_gpu_3dfft(const PmeGpu* pmeGpu, gmx_fft_direction dir, int grid_index) { - int timerId = (dir == GMX_FFT_REAL_TO_COMPLEX) ? gtPME_FFT_R2C : gtPME_FFT_C2R; + int timerId = (dir == GMX_FFT_REAL_TO_COMPLEX) ? gtPME_FFT_R2C : gtPME_FFT_C2R; pme_gpu_start_timing(pmeGpu, timerId); - pmeGpu->archSpecific->fftSetup[grid_index]->perform3dFft(dir, pme_gpu_fetch_timing_event(pmeGpu, timerId)); + pmeGpu->archSpecific->fftSetup[grid_index]->perform3dFft( + dir, pme_gpu_fetch_timing_event(pmeGpu, timerId)); pme_gpu_stop_timing(pmeGpu, timerId); } @@ -1025,14 +1037,15 @@ void pme_gpu_3dfft(const PmeGpu *pmeGpu, gmx_fft_direction dir, int grid_index) * Given possibly large \p blockCount, returns a compact 1D or 2D grid for kernel scheduling, * to minimize number of unused blocks. */ -std::pair inline pmeGpuCreateGrid(const PmeGpu *pmeGpu, int blockCount) +std::pair inline pmeGpuCreateGrid(const PmeGpu* pmeGpu, int blockCount) { // How many maximum widths in X do we need (hopefully just one) const int minRowCount = (blockCount + pmeGpu->maxGridWidthX - 1) / pmeGpu->maxGridWidthX; // Trying to make things even const int colCount = (blockCount + minRowCount - 1) / minRowCount; GMX_ASSERT((colCount * minRowCount - blockCount) >= 0, "pmeGpuCreateGrid: totally wrong"); - GMX_ASSERT((colCount * minRowCount - blockCount) < minRowCount, "pmeGpuCreateGrid: excessive blocks"); + GMX_ASSERT((colCount * minRowCount - blockCount) < minRowCount, + "pmeGpuCreateGrid: excessive blocks"); return std::pair(colCount, minRowCount); } @@ -1045,9 +1058,7 @@ std::pair inline pmeGpuCreateGrid(const PmeGpu *pmeGpu, int blockCount * * \return Pointer to CUDA kernel */ -static auto selectSplineAndSpreadKernelPtr(const PmeGpu *pmeGpu, - bool useOrderThreadsPerAtom, - bool writeSplinesToGlobal) +static auto selectSplineAndSpreadKernelPtr(const PmeGpu* pmeGpu, bool useOrderThreadsPerAtom, bool writeSplinesToGlobal) { PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr; if (writeSplinesToGlobal) @@ -1085,12 +1096,12 @@ static auto selectSplineAndSpreadKernelPtr(const PmeGpu *pmeGpu, * * \return Pointer to CUDA kernel */ -static auto selectSplineKernelPtr(const PmeGpu *pmeGpu, - bool useOrderThreadsPerAtom, - bool gmx_unused writeSplinesToGlobal) +static auto selectSplineKernelPtr(const PmeGpu* pmeGpu, bool useOrderThreadsPerAtom, bool gmx_unused writeSplinesToGlobal) { PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr; - GMX_ASSERT(writeSplinesToGlobal, "Spline data should always be written to global memory when just calculating splines"); + GMX_ASSERT( + writeSplinesToGlobal, + "Spline data should always be written to global memory when just calculating splines"); if (useOrderThreadsPerAtom) { @@ -1112,9 +1123,7 @@ static auto selectSplineKernelPtr(const PmeGpu *pmeGpu, * * \return Pointer to CUDA kernel */ -static auto selectSpreadKernelPtr(const PmeGpu *pmeGpu, - bool useOrderThreadsPerAtom, - bool writeSplinesToGlobal) +static auto selectSpreadKernelPtr(const PmeGpu* pmeGpu, bool useOrderThreadsPerAtom, bool writeSplinesToGlobal) { PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr; if (writeSplinesToGlobal) @@ -1144,28 +1153,29 @@ static auto selectSpreadKernelPtr(const PmeGpu *pmeGpu, return kernelPtr; } -void pme_gpu_spread(const PmeGpu *pmeGpu, - GpuEventSynchronizer *xReadyOnDevice, - int gmx_unused gridIndex, - real *h_grid, - bool computeSplines, - bool spreadCharges) +void pme_gpu_spread(const PmeGpu* pmeGpu, + GpuEventSynchronizer* xReadyOnDevice, + int gmx_unused gridIndex, + real* h_grid, + bool computeSplines, + bool spreadCharges) { - GMX_ASSERT(computeSplines || spreadCharges, "PME spline/spread kernel has invalid input (nothing to do)"); - const auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + GMX_ASSERT(computeSplines || spreadCharges, + "PME spline/spread kernel has invalid input (nothing to do)"); + const auto* kernelParamsPtr = pmeGpu->kernelParams.get(); GMX_ASSERT(kernelParamsPtr->atoms.nAtoms > 0, "No atom data in PME GPU spread"); - const size_t blockSize = pmeGpu->programHandle_->impl_->spreadWorkGroupSize; + const size_t blockSize = pmeGpu->programHandle_->impl_->spreadWorkGroupSize; - const int order = pmeGpu->common->pme_order; + const int order = pmeGpu->common->pme_order; GMX_ASSERT(order == c_pmeGpuOrder, "Only PME order 4 is implemented"); - const bool writeGlobal = pmeGpu->settings.copyAllOutputs; + const bool writeGlobal = pmeGpu->settings.copyAllOutputs; #if GMX_GPU == GMX_GPU_OPENCL GMX_ASSERT(!c_useOrderThreadsPerAtom, "Only 16 threads per atom supported in OpenCL"); GMX_ASSERT(!c_recalculateSplines, "Recalculating splines not supported in OpenCL"); #endif - const int atomsPerBlock = c_useOrderThreadsPerAtom ? blockSize / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom : - blockSize / c_pmeSpreadGatherThreadsPerAtom; + const int atomsPerBlock = c_useOrderThreadsPerAtom ? blockSize / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom + : blockSize / c_pmeSpreadGatherThreadsPerAtom; // TODO: pick smaller block size in runtime if needed // (e.g. on 660 Ti where 50% occupancy is ~25% faster than 100% occupancy with RNAse (~17.8k atoms)) @@ -1173,21 +1183,22 @@ void pme_gpu_spread(const PmeGpu *pmeGpu, // TODO: test varying block sizes on modern arch-s as well // TODO: also consider using cudaFuncSetCacheConfig() for preferring shared memory on older architectures //(for spline data mostly) - GMX_ASSERT(!c_usePadding || !(c_pmeAtomDataAlignment % atomsPerBlock), "inconsistent atom data padding vs. spreading block size"); + GMX_ASSERT(!c_usePadding || !(c_pmeAtomDataAlignment % atomsPerBlock), + "inconsistent atom data padding vs. spreading block size"); // Ensure that coordinates are ready on the device before launching spread; // only needed with CUDA on PP+PME ranks, not on separate PME ranks, in unit tests // nor in OpenCL as these cases use a single stream (hence xReadyOnDevice == nullptr). - GMX_ASSERT(xReadyOnDevice != nullptr || - (GMX_GPU != GMX_GPU_CUDA) || pmeGpu->common->isRankPmeOnly || pme_gpu_is_testing(pmeGpu), + GMX_ASSERT(xReadyOnDevice != nullptr || (GMX_GPU != GMX_GPU_CUDA) + || pmeGpu->common->isRankPmeOnly || pme_gpu_is_testing(pmeGpu), "Need a valid coordinate synchronizer on PP+PME ranks with CUDA."); if (xReadyOnDevice) { xReadyOnDevice->enqueueWaitEvent(pmeGpu->archSpecific->pmeStream); } - const int blockCount = pmeGpu->nAtomsPadded / atomsPerBlock; - auto dimGrid = pmeGpuCreateGrid(pmeGpu, blockCount); + const int blockCount = pmeGpu->nAtomsPadded / atomsPerBlock; + auto dimGrid = pmeGpuCreateGrid(pmeGpu, blockCount); KernelLaunchConfig config; config.blockSize[0] = order; @@ -1197,79 +1208,73 @@ void pme_gpu_spread(const PmeGpu *pmeGpu, config.gridSize[1] = dimGrid.second; config.stream = pmeGpu->archSpecific->pmeStream; - int timingId; + int timingId; PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr; if (computeSplines) { if (spreadCharges) { timingId = gtPME_SPLINEANDSPREAD; - kernelPtr = selectSplineAndSpreadKernelPtr( pmeGpu, - c_useOrderThreadsPerAtom, - writeGlobal || (!c_recalculateSplines)); + kernelPtr = selectSplineAndSpreadKernelPtr(pmeGpu, c_useOrderThreadsPerAtom, + writeGlobal || (!c_recalculateSplines)); } else { timingId = gtPME_SPLINE; - kernelPtr = selectSplineKernelPtr( pmeGpu, - c_useOrderThreadsPerAtom, - writeGlobal || (!c_recalculateSplines)); + kernelPtr = selectSplineKernelPtr(pmeGpu, c_useOrderThreadsPerAtom, + writeGlobal || (!c_recalculateSplines)); } } else { timingId = gtPME_SPREAD; - kernelPtr = selectSpreadKernelPtr( pmeGpu, - c_useOrderThreadsPerAtom, - writeGlobal || (!c_recalculateSplines)); + kernelPtr = selectSpreadKernelPtr(pmeGpu, c_useOrderThreadsPerAtom, + writeGlobal || (!c_recalculateSplines)); } pme_gpu_start_timing(pmeGpu, timingId); - auto *timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); + auto* timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); #if c_canEmbedBuffers const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr); #else - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr, - &kernelParamsPtr->atoms.d_theta, - &kernelParamsPtr->atoms.d_dtheta, - &kernelParamsPtr->atoms.d_gridlineIndices, - &kernelParamsPtr->grid.d_realGrid, - &kernelParamsPtr->grid.d_fractShiftsTable, - &kernelParamsPtr->grid.d_gridlineIndicesTable, - &kernelParamsPtr->atoms.d_coefficients, - &kernelParamsPtr->atoms.d_coordinates - ); + const auto kernelArgs = prepareGpuKernelArguments( + kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_theta, + &kernelParamsPtr->atoms.d_dtheta, &kernelParamsPtr->atoms.d_gridlineIndices, + &kernelParamsPtr->grid.d_realGrid, &kernelParamsPtr->grid.d_fractShiftsTable, + &kernelParamsPtr->grid.d_gridlineIndicesTable, &kernelParamsPtr->atoms.d_coefficients, + &kernelParamsPtr->atoms.d_coordinates); #endif launchGpuKernel(kernelPtr, config, timingEvent, "PME spline/spread", kernelArgs); pme_gpu_stop_timing(pmeGpu, timingId); - const bool copyBackGrid = spreadCharges && (pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_FFT(pmeGpu)); + const bool copyBackGrid = + spreadCharges && (pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_FFT(pmeGpu)); if (copyBackGrid) { pme_gpu_copy_output_spread_grid(pmeGpu, h_grid); } - const bool copyBackAtomData = computeSplines && (pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_gather(pmeGpu)); + const bool copyBackAtomData = + computeSplines && (pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_gather(pmeGpu)); if (copyBackAtomData) { pme_gpu_copy_output_spread_atom_data(pmeGpu); } } -void pme_gpu_solve(const PmeGpu *pmeGpu, t_complex *h_grid, - GridOrdering gridOrdering, bool computeEnergyAndVirial) +void pme_gpu_solve(const PmeGpu* pmeGpu, t_complex* h_grid, GridOrdering gridOrdering, bool computeEnergyAndVirial) { - const bool copyInputAndOutputGrid = pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_FFT(pmeGpu); + const bool copyInputAndOutputGrid = pme_gpu_is_testing(pmeGpu) || !pme_gpu_performs_FFT(pmeGpu); - auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + auto* kernelParamsPtr = pmeGpu->kernelParams.get(); - float *h_gridFloat = reinterpret_cast(h_grid); + float* h_gridFloat = reinterpret_cast(h_grid); if (copyInputAndOutputGrid) { - copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid, h_gridFloat, - 0, pmeGpu->archSpecific->complexGridSize, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + copyToDeviceBuffer(&kernelParamsPtr->grid.d_fourierGrid, h_gridFloat, 0, + pmeGpu->archSpecific->complexGridSize, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } int majorDim = -1, middleDim = -1, minorDim = -1; @@ -1287,28 +1292,27 @@ void pme_gpu_solve(const PmeGpu *pmeGpu, t_complex *h_grid, minorDim = ZZ; break; - default: - GMX_ASSERT(false, "Implement grid ordering here and below for the kernel launch"); + default: GMX_ASSERT(false, "Implement grid ordering here and below for the kernel launch"); } - const int maxBlockSize = pmeGpu->programHandle_->impl_->solveMaxWorkGroupSize; + const int maxBlockSize = pmeGpu->programHandle_->impl_->solveMaxWorkGroupSize; - const int gridLineSize = pmeGpu->kernelParams->grid.complexGridSize[minorDim]; - const int gridLinesPerBlock = std::max(maxBlockSize / gridLineSize, 1); - const int blocksPerGridLine = (gridLineSize + maxBlockSize - 1) / maxBlockSize; - int cellsPerBlock; + const int gridLineSize = pmeGpu->kernelParams->grid.complexGridSize[minorDim]; + const int gridLinesPerBlock = std::max(maxBlockSize / gridLineSize, 1); + const int blocksPerGridLine = (gridLineSize + maxBlockSize - 1) / maxBlockSize; + int cellsPerBlock; if (blocksPerGridLine == 1) { - cellsPerBlock = gridLineSize * gridLinesPerBlock; + cellsPerBlock = gridLineSize * gridLinesPerBlock; } else { - cellsPerBlock = (gridLineSize + blocksPerGridLine - 1) / blocksPerGridLine; + cellsPerBlock = (gridLineSize + blocksPerGridLine - 1) / blocksPerGridLine; } - const int warpSize = pmeGpu->programHandle_->impl_->warpSize; - const int blockSize = (cellsPerBlock + warpSize - 1) / warpSize * warpSize; + const int warpSize = pmeGpu->programHandle_->impl_->warpSize; + const int blockSize = (cellsPerBlock + warpSize - 1) / warpSize * warpSize; - static_assert(GMX_GPU != GMX_GPU_CUDA || c_solveMaxWarpsPerBlock/2 >= 4, + static_assert(GMX_GPU != GMX_GPU_CUDA || c_solveMaxWarpsPerBlock / 2 >= 4, "The CUDA solve energy kernels needs at least 4 warps. " "Here we launch at least half of the max warps."); @@ -1316,50 +1320,48 @@ void pme_gpu_solve(const PmeGpu *pmeGpu, t_complex *h_grid, config.blockSize[0] = blockSize; config.gridSize[0] = blocksPerGridLine; // rounding up to full warps so that shuffle operations produce defined results - config.gridSize[1] = (pmeGpu->kernelParams->grid.complexGridSize[middleDim] + gridLinesPerBlock - 1) / gridLinesPerBlock; - config.gridSize[2] = pmeGpu->kernelParams->grid.complexGridSize[majorDim]; - config.stream = pmeGpu->archSpecific->pmeStream; + config.gridSize[1] = (pmeGpu->kernelParams->grid.complexGridSize[middleDim] + gridLinesPerBlock - 1) + / gridLinesPerBlock; + config.gridSize[2] = pmeGpu->kernelParams->grid.complexGridSize[majorDim]; + config.stream = pmeGpu->archSpecific->pmeStream; - int timingId = gtPME_SOLVE; + int timingId = gtPME_SOLVE; PmeGpuProgramImpl::PmeKernelHandle kernelPtr = nullptr; if (gridOrdering == GridOrdering::YZX) { - kernelPtr = computeEnergyAndVirial ? - pmeGpu->programHandle_->impl_->solveYZXEnergyKernel : - pmeGpu->programHandle_->impl_->solveYZXKernel; + kernelPtr = computeEnergyAndVirial ? pmeGpu->programHandle_->impl_->solveYZXEnergyKernel + : pmeGpu->programHandle_->impl_->solveYZXKernel; } else if (gridOrdering == GridOrdering::XYZ) { - kernelPtr = computeEnergyAndVirial ? - pmeGpu->programHandle_->impl_->solveXYZEnergyKernel : - pmeGpu->programHandle_->impl_->solveXYZKernel; + kernelPtr = computeEnergyAndVirial ? pmeGpu->programHandle_->impl_->solveXYZEnergyKernel + : pmeGpu->programHandle_->impl_->solveXYZKernel; } pme_gpu_start_timing(pmeGpu, timingId); - auto *timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); + auto* timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); #if c_canEmbedBuffers const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr); #else - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr, - &kernelParamsPtr->grid.d_splineModuli, - &kernelParamsPtr->constants.d_virialAndEnergy, - &kernelParamsPtr->grid.d_fourierGrid); + const auto kernelArgs = prepareGpuKernelArguments( + kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->grid.d_splineModuli, + &kernelParamsPtr->constants.d_virialAndEnergy, &kernelParamsPtr->grid.d_fourierGrid); #endif launchGpuKernel(kernelPtr, config, timingEvent, "PME solve", kernelArgs); pme_gpu_stop_timing(pmeGpu, timingId); if (computeEnergyAndVirial) { - copyFromDeviceBuffer(pmeGpu->staging.h_virialAndEnergy, &kernelParamsPtr->constants.d_virialAndEnergy, - 0, c_virialAndEnergyCount, + copyFromDeviceBuffer(pmeGpu->staging.h_virialAndEnergy, + &kernelParamsPtr->constants.d_virialAndEnergy, 0, c_virialAndEnergyCount, pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); } if (copyInputAndOutputGrid) { - copyFromDeviceBuffer(h_gridFloat, &kernelParamsPtr->grid.d_fourierGrid, - 0, pmeGpu->archSpecific->complexGridSize, - pmeGpu->archSpecific->pmeStream, pmeGpu->settings.transferKind, nullptr); + copyFromDeviceBuffer(h_gridFloat, &kernelParamsPtr->grid.d_fourierGrid, 0, + pmeGpu->archSpecific->complexGridSize, pmeGpu->archSpecific->pmeStream, + pmeGpu->settings.transferKind, nullptr); } } @@ -1373,9 +1375,9 @@ void pme_gpu_solve(const PmeGpu *pmeGpu, t_complex *h_grid, * * \return Pointer to CUDA kernel */ -inline auto selectGatherKernelPtr(const PmeGpu *pmeGpu, - bool useOrderThreadsPerAtom, - bool readSplinesFromGlobal, +inline auto selectGatherKernelPtr(const PmeGpu* pmeGpu, + bool useOrderThreadsPerAtom, + bool readSplinesFromGlobal, PmeForceOutputHandling forceTreatment) { @@ -1385,39 +1387,37 @@ inline auto selectGatherKernelPtr(const PmeGpu *pmeGpu, { if (useOrderThreadsPerAtom) { - kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) ? - pmeGpu->programHandle_->impl_->gatherKernelReadSplinesThPerAtom4 : - pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelReadSplinesThPerAtom4; + kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) + ? pmeGpu->programHandle_->impl_->gatherKernelReadSplinesThPerAtom4 + : pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelReadSplinesThPerAtom4; } else { - kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) ? - pmeGpu->programHandle_->impl_->gatherKernelReadSplines : - pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelReadSplines; + kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) + ? pmeGpu->programHandle_->impl_->gatherKernelReadSplines + : pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelReadSplines; } } else { if (useOrderThreadsPerAtom) { - kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) ? - pmeGpu->programHandle_->impl_->gatherKernelThPerAtom4 : - pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelThPerAtom4; + kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) + ? pmeGpu->programHandle_->impl_->gatherKernelThPerAtom4 + : pmeGpu->programHandle_->impl_->gatherReduceWithInputKernelThPerAtom4; } else { - kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) ? - pmeGpu->programHandle_->impl_->gatherKernel : - pmeGpu->programHandle_->impl_->gatherReduceWithInputKernel; + kernelPtr = (forceTreatment == PmeForceOutputHandling::Set) + ? pmeGpu->programHandle_->impl_->gatherKernel + : pmeGpu->programHandle_->impl_->gatherReduceWithInputKernel; } } return kernelPtr; } -void pme_gpu_gather(PmeGpu *pmeGpu, - PmeForceOutputHandling forceTreatment, - const float *h_grid) +void pme_gpu_gather(PmeGpu* pmeGpu, PmeForceOutputHandling forceTreatment, const float* h_grid) { /* Copying the input CPU forces for reduction */ if (forceTreatment != PmeForceOutputHandling::Set) @@ -1427,7 +1427,7 @@ void pme_gpu_gather(PmeGpu *pmeGpu, if (!pme_gpu_performs_FFT(pmeGpu) || pme_gpu_is_testing(pmeGpu)) { - pme_gpu_copy_input_gather_grid(pmeGpu, const_cast(h_grid)); + pme_gpu_copy_input_gather_grid(pmeGpu, const_cast(h_grid)); } if (pme_gpu_is_testing(pmeGpu)) @@ -1436,21 +1436,22 @@ void pme_gpu_gather(PmeGpu *pmeGpu, } /* Set if we have unit tests */ - const bool readGlobal = pmeGpu->settings.copyAllOutputs; - const size_t blockSize = pmeGpu->programHandle_->impl_->gatherWorkGroupSize; + const bool readGlobal = pmeGpu->settings.copyAllOutputs; + const size_t blockSize = pmeGpu->programHandle_->impl_->gatherWorkGroupSize; #if GMX_GPU == GMX_GPU_OPENCL GMX_ASSERT(!c_useOrderThreadsPerAtom, "Only 16 threads per atom supported in OpenCL"); GMX_ASSERT(!c_recalculateSplines, "Recalculating splines not supported in OpenCL"); #endif - const int atomsPerBlock = c_useOrderThreadsPerAtom ? blockSize / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom : - blockSize / c_pmeSpreadGatherThreadsPerAtom; + const int atomsPerBlock = c_useOrderThreadsPerAtom ? blockSize / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom + : blockSize / c_pmeSpreadGatherThreadsPerAtom; - GMX_ASSERT(!c_usePadding || !(c_pmeAtomDataAlignment % atomsPerBlock), "inconsistent atom data padding vs. gathering block size"); + GMX_ASSERT(!c_usePadding || !(c_pmeAtomDataAlignment % atomsPerBlock), + "inconsistent atom data padding vs. gathering block size"); - const int blockCount = pmeGpu->nAtomsPadded / atomsPerBlock; - auto dimGrid = pmeGpuCreateGrid(pmeGpu, blockCount); + const int blockCount = pmeGpu->nAtomsPadded / atomsPerBlock; + auto dimGrid = pmeGpuCreateGrid(pmeGpu, blockCount); - const int order = pmeGpu->common->pme_order; + const int order = pmeGpu->common->pme_order; GMX_ASSERT(order == c_pmeGpuOrder, "Only PME order 4 is implemented"); KernelLaunchConfig config; @@ -1463,26 +1464,22 @@ void pme_gpu_gather(PmeGpu *pmeGpu, // TODO test different cache configs - int timingId = gtPME_GATHER; - PmeGpuProgramImpl::PmeKernelHandle kernelPtr = selectGatherKernelPtr( pmeGpu, - c_useOrderThreadsPerAtom, - readGlobal || (!c_recalculateSplines), - forceTreatment); + int timingId = gtPME_GATHER; + PmeGpuProgramImpl::PmeKernelHandle kernelPtr = selectGatherKernelPtr( + pmeGpu, c_useOrderThreadsPerAtom, readGlobal || (!c_recalculateSplines), forceTreatment); // TODO design kernel selection getters and make PmeGpu a friend of PmeGpuProgramImpl pme_gpu_start_timing(pmeGpu, timingId); - auto *timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); - const auto *kernelParamsPtr = pmeGpu->kernelParams.get(); + auto* timingEvent = pme_gpu_fetch_timing_event(pmeGpu, timingId); + const auto* kernelParamsPtr = pmeGpu->kernelParams.get(); #if c_canEmbedBuffers - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr); + const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr); #else - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, kernelParamsPtr, - &kernelParamsPtr->atoms.d_coefficients, - &kernelParamsPtr->grid.d_realGrid, - &kernelParamsPtr->atoms.d_theta, - &kernelParamsPtr->atoms.d_dtheta, - &kernelParamsPtr->atoms.d_gridlineIndices, - &kernelParamsPtr->atoms.d_forces); + const auto kernelArgs = prepareGpuKernelArguments( + kernelPtr, config, kernelParamsPtr, &kernelParamsPtr->atoms.d_coefficients, + &kernelParamsPtr->grid.d_realGrid, &kernelParamsPtr->atoms.d_theta, + &kernelParamsPtr->atoms.d_dtheta, &kernelParamsPtr->atoms.d_gridlineIndices, + &kernelParamsPtr->atoms.d_forces); #endif launchGpuKernel(kernelPtr, config, timingEvent, "PME gather", kernelArgs); pme_gpu_stop_timing(pmeGpu, timingId); @@ -1497,14 +1494,16 @@ void pme_gpu_gather(PmeGpu *pmeGpu, } } -DeviceBuffer pme_gpu_get_kernelparam_coordinates(const PmeGpu *pmeGpu) +DeviceBuffer pme_gpu_get_kernelparam_coordinates(const PmeGpu* pmeGpu) { - GMX_ASSERT(pmeGpu && pmeGpu->kernelParams, "PME GPU device buffer was requested in non-GPU build or before the GPU PME was initialized."); + GMX_ASSERT(pmeGpu && pmeGpu->kernelParams, + "PME GPU device buffer was requested in non-GPU build or before the GPU PME was " + "initialized."); return pmeGpu->kernelParams->atoms.d_coordinates; } -void * pme_gpu_get_kernelparam_forces(const PmeGpu *pmeGpu) +void* pme_gpu_get_kernelparam_forces(const PmeGpu* pmeGpu) { if (pmeGpu && pmeGpu->kernelParams) { @@ -1536,8 +1535,10 @@ static bool checkDeviceBuffer(gmx_unused DeviceBuffer buffer, gmx_unused int #elif GMX_GPU == GMX_GPU_OPENCL size_t size; int retval = clGetMemObjectInfo(buffer, CL_MEM_SIZE, sizeof(size), &size, nullptr); - GMX_ASSERT(retval == CL_SUCCESS, gmx::formatString("clGetMemObjectInfo failed with error code #%d", retval).c_str()); - GMX_ASSERT(static_cast(size) >= requiredSize, "Number of atoms in device buffer is smaller then required size."); + GMX_ASSERT(retval == CL_SUCCESS, + gmx::formatString("clGetMemObjectInfo failed with error code #%d", retval).c_str()); + GMX_ASSERT(static_cast(size) >= requiredSize, + "Number of atoms in device buffer is smaller then required size."); return retval == CL_SUCCESS && static_cast(size) >= requiredSize; #elif GMX_GPU == GMX_GPU_NONE GMX_ASSERT(false, "Setter for device-side coordinates was called in non-GPU build."); @@ -1545,20 +1546,23 @@ static bool checkDeviceBuffer(gmx_unused DeviceBuffer buffer, gmx_unused int #endif } -void pme_gpu_set_kernelparam_coordinates(const PmeGpu *pmeGpu, DeviceBuffer d_x) +void pme_gpu_set_kernelparam_coordinates(const PmeGpu* pmeGpu, DeviceBuffer d_x) { - GMX_ASSERT(pmeGpu && pmeGpu->kernelParams, "PME GPU device buffer can not be set in non-GPU builds or before the GPU PME was initialized."); + GMX_ASSERT(pmeGpu && pmeGpu->kernelParams, + "PME GPU device buffer can not be set in non-GPU builds or before the GPU PME was " + "initialized."); - GMX_ASSERT(checkDeviceBuffer(d_x, pmeGpu->kernelParams->atoms.nAtoms), "The device-side buffer can not be set."); + GMX_ASSERT(checkDeviceBuffer(d_x, pmeGpu->kernelParams->atoms.nAtoms), + "The device-side buffer can not be set."); pmeGpu->kernelParams->atoms.d_coordinates = d_x; } -void * pme_gpu_get_stream(const PmeGpu *pmeGpu) +void* pme_gpu_get_stream(const PmeGpu* pmeGpu) { if (pmeGpu) { - return static_cast(&pmeGpu->archSpecific->pmeStream); + return static_cast(&pmeGpu->archSpecific->pmeStream); } else { @@ -1566,11 +1570,11 @@ void * pme_gpu_get_stream(const PmeGpu *pmeGpu) } } -void * pme_gpu_get_context(const PmeGpu *pmeGpu) +void* pme_gpu_get_context(const PmeGpu* pmeGpu) { if (pmeGpu) { - return static_cast(&pmeGpu->archSpecific->context); + return static_cast(&pmeGpu->archSpecific->context); } else { @@ -1578,7 +1582,7 @@ void * pme_gpu_get_context(const PmeGpu *pmeGpu) } } -GpuEventSynchronizer *pme_gpu_get_forces_ready_synchronizer(const PmeGpu *pmeGpu) +GpuEventSynchronizer* pme_gpu_get_forces_ready_synchronizer(const PmeGpu* pmeGpu) { if (pmeGpu && pmeGpu->kernelParams) { diff --git a/src/gromacs/ewald/pme_gpu_internal.h b/src/gromacs/ewald/pme_gpu_internal.h index 0f66915b0d..443b97a60e 100644 --- a/src/gromacs/ewald/pme_gpu_internal.h +++ b/src/gromacs/ewald/pme_gpu_internal.h @@ -46,15 +46,15 @@ #ifndef GMX_EWALD_PME_GPU_INTERNAL_H #define GMX_EWALD_PME_GPU_INTERNAL_H -#include "gromacs/fft/fft.h" // for the gmx_fft_direction enum -#include "gromacs/gpu_utils/gpu_macros.h" // for the GPU_FUNC_ macros +#include "gromacs/fft/fft.h" // for the gmx_fft_direction enum +#include "gromacs/gpu_utils/gpu_macros.h" // for the GPU_FUNC_ macros #include "gromacs/utility/arrayref.h" -#include "pme_gpu_types_host.h" // for the inline functions accessing PmeGpu members +#include "pme_gpu_types_host.h" // for the inline functions accessing PmeGpu members struct gmx_hw_info_t; struct gmx_gpu_opt_t; -struct gmx_pme_t; // only used in pme_gpu_reinit +struct gmx_pme_t; // only used in pme_gpu_reinit struct gmx_wallclock_gpu_pme_t; class PmeAtomComm; struct t_complex; @@ -69,7 +69,7 @@ enum class PmeSplineDataType { Values, // theta Derivatives, // dtheta -}; //TODO move this into new and shiny pme.h (pme-types.h?) +}; // TODO move this into new and shiny pme.h (pme-types.h?) //! PME grid dimension ordering (from major to minor) enum class GridOrdering @@ -85,7 +85,7 @@ enum class GridOrdering * \param[in] pmeGpu The PME GPU structure. * \returns Number of atoms in a single GPU atom data chunk. */ -int pme_gpu_get_atom_data_alignment(const PmeGpu *pmeGpu); +int pme_gpu_get_atom_data_alignment(const PmeGpu* pmeGpu); /*! \libinternal \brief * Returns the number of atoms per chunk in the atom spline theta/dtheta data layout. @@ -93,28 +93,28 @@ int pme_gpu_get_atom_data_alignment(const PmeGpu *pmeGpu); * \param[in] pmeGpu The PME GPU structure. * \returns Number of atoms in a single GPU atom spline data chunk. */ -int pme_gpu_get_atoms_per_warp(const PmeGpu *pmeGpu); +int pme_gpu_get_atoms_per_warp(const PmeGpu* pmeGpu); /*! \libinternal \brief * Synchronizes the current computation, waiting for the GPU kernels/transfers to finish. * * \param[in] pmeGpu The PME GPU structure. */ -GPU_FUNC_QUALIFIER void pme_gpu_synchronize(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_synchronize(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM; /*! \libinternal \brief * Allocates the fixed size energy and virial buffer both on GPU and CPU. * * \param[in,out] pmeGpu The PME GPU structure. */ -void pme_gpu_alloc_energy_virial(PmeGpu *pmeGpu); +void pme_gpu_alloc_energy_virial(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the energy and virial memory both on GPU and CPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_energy_virial(PmeGpu *pmeGpu); +void pme_gpu_free_energy_virial(PmeGpu* pmeGpu); /*! \libinternal \brief * Clears the energy and virial memory on GPU with 0. @@ -122,50 +122,50 @@ void pme_gpu_free_energy_virial(PmeGpu *pmeGpu); * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_clear_energy_virial(const PmeGpu *pmeGpu); +void pme_gpu_clear_energy_virial(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates and copies the pre-computed B-spline values to the GPU. * * \param[in,out] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_and_copy_bspline_values(PmeGpu *pmeGpu); +void pme_gpu_realloc_and_copy_bspline_values(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the pre-computed B-spline values on the GPU (and the transfer CPU buffers). * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_bspline_values(const PmeGpu *pmeGpu); +void pme_gpu_free_bspline_values(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the GPU buffer for the PME forces. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_forces(PmeGpu *pmeGpu); +void pme_gpu_realloc_forces(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the GPU buffer for the PME forces. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_forces(const PmeGpu *pmeGpu); +void pme_gpu_free_forces(const PmeGpu* pmeGpu); /*! \libinternal \brief - * Copies the forces from the CPU buffer to the GPU (to reduce them with the PME GPU gathered forces). - * To be called e.g. after the bonded calculations. + * Copies the forces from the CPU buffer to the GPU (to reduce them with the PME GPU gathered + * forces). To be called e.g. after the bonded calculations. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_copy_input_forces(PmeGpu *pmeGpu); +void pme_gpu_copy_input_forces(PmeGpu* pmeGpu); /*! \libinternal \brief * Copies the forces from the GPU to the CPU buffer. To be called after the gathering stage. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_copy_output_forces(PmeGpu *pmeGpu); +void pme_gpu_copy_output_forces(PmeGpu* pmeGpu); /*! \libinternal \brief * Checks whether work in the PME GPU stream has completed. @@ -174,7 +174,7 @@ void pme_gpu_copy_output_forces(PmeGpu *pmeGpu); * * \returns True if work in the PME stream has completed. */ -bool pme_gpu_stream_query(const PmeGpu *pmeGpu); +bool pme_gpu_stream_query(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the input coordinates buffer on the GPU (and clears the padded part if needed). @@ -183,14 +183,14 @@ bool pme_gpu_stream_query(const PmeGpu *pmeGpu); * * Needs to be called on every DD step/in the beginning. */ -void pme_gpu_realloc_coordinates(const PmeGpu *pmeGpu); +void pme_gpu_realloc_coordinates(const PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the coordinates on the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_coordinates(const PmeGpu *pmeGpu); +void pme_gpu_free_coordinates(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the buffer on the GPU and copies the charges/coefficients from the CPU buffer. @@ -202,57 +202,56 @@ void pme_gpu_free_coordinates(const PmeGpu *pmeGpu); * Does not need to be done for every PME computation, only whenever the local charges change. * (So, in the beginning of the run, or on DD step). */ -void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu *pmeGpu, - const float *h_coefficients); +void pme_gpu_realloc_and_copy_input_coefficients(const PmeGpu* pmeGpu, const float* h_coefficients); /*! \libinternal \brief * Frees the charges/coefficients on the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_coefficients(const PmeGpu *pmeGpu); +void pme_gpu_free_coefficients(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the buffers on the GPU and the host for the atoms spline data. * * \param[in,out] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_spline_data(PmeGpu *pmeGpu); +void pme_gpu_realloc_spline_data(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the buffers on the GPU for the atoms spline data. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_spline_data(const PmeGpu *pmeGpu); +void pme_gpu_free_spline_data(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the buffers on the GPU and the host for the particle gridline indices. * * \param[in,out] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_grid_indices(PmeGpu *pmeGpu); +void pme_gpu_realloc_grid_indices(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the buffer on the GPU for the particle gridline indices. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_grid_indices(const PmeGpu *pmeGpu); +void pme_gpu_free_grid_indices(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates the real space grid and the complex reciprocal grid (if needed) on the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_grids(PmeGpu *pmeGpu); +void pme_gpu_realloc_grids(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the real space grid and the complex reciprocal grid (if needed) on the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_grids(const PmeGpu *pmeGpu); +void pme_gpu_free_grids(const PmeGpu* pmeGpu); /*! \libinternal \brief * Clears the real space grid on the GPU. @@ -260,21 +259,21 @@ void pme_gpu_free_grids(const PmeGpu *pmeGpu); * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_clear_grids(const PmeGpu *pmeGpu); +void pme_gpu_clear_grids(const PmeGpu* pmeGpu); /*! \libinternal \brief * Reallocates and copies the pre-computed fractional coordinates' shifts to the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_realloc_and_copy_fract_shifts(PmeGpu *pmeGpu); +void pme_gpu_realloc_and_copy_fract_shifts(PmeGpu* pmeGpu); /*! \libinternal \brief * Frees the pre-computed fractional coordinates' shifts on the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_free_fract_shifts(const PmeGpu *pmeGpu); +void pme_gpu_free_fract_shifts(const PmeGpu* pmeGpu); /*! \libinternal \brief * Copies the input real-space grid from the host to the GPU. @@ -282,8 +281,7 @@ void pme_gpu_free_fract_shifts(const PmeGpu *pmeGpu); * \param[in] pmeGpu The PME GPU structure. * \param[in] h_grid The host-side grid buffer. */ -void pme_gpu_copy_input_gather_grid(const PmeGpu *pmeGpu, - float *h_grid); +void pme_gpu_copy_input_gather_grid(const PmeGpu* pmeGpu, float* h_grid); /*! \libinternal \brief * Copies the output real-space grid from the GPU to the host. @@ -291,29 +289,28 @@ void pme_gpu_copy_input_gather_grid(const PmeGpu *pmeGpu, * \param[in] pmeGpu The PME GPU structure. * \param[out] h_grid The host-side grid buffer. */ -void pme_gpu_copy_output_spread_grid(const PmeGpu *pmeGpu, - float *h_grid); +void pme_gpu_copy_output_spread_grid(const PmeGpu* pmeGpu, float* h_grid); /*! \libinternal \brief * Copies the spread output spline data and gridline indices from the GPU to the host. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_copy_output_spread_atom_data(const PmeGpu *pmeGpu); +void pme_gpu_copy_output_spread_atom_data(const PmeGpu* pmeGpu); /*! \libinternal \brief * Copies the gather input spline data and gridline indices from the host to the GPU. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_copy_input_gather_atom_data(const PmeGpu *pmeGpu); +void pme_gpu_copy_input_gather_atom_data(const PmeGpu* pmeGpu); /*! \libinternal \brief * Waits for the grid copying to the host-side buffer after spreading to finish. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_sync_spread_grid(const PmeGpu *pmeGpu); +void pme_gpu_sync_spread_grid(const PmeGpu* pmeGpu); /*! \libinternal \brief * Does the one-time GPU-framework specific PME initialization. @@ -321,7 +318,7 @@ void pme_gpu_sync_spread_grid(const PmeGpu *pmeGpu); * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_init_internal(PmeGpu *pmeGpu); +void pme_gpu_init_internal(PmeGpu* pmeGpu); /*! \libinternal \brief * Destroys the PME GPU-framework specific data. @@ -329,21 +326,21 @@ void pme_gpu_init_internal(PmeGpu *pmeGpu); * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_destroy_specific(const PmeGpu *pmeGpu); +void pme_gpu_destroy_specific(const PmeGpu* pmeGpu); /*! \libinternal \brief * Initializes the CUDA FFT structures. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_reinit_3dfft(const PmeGpu *pmeGpu); +void pme_gpu_reinit_3dfft(const PmeGpu* pmeGpu); /*! \libinternal \brief * Destroys the CUDA FFT structures. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_destroy_3dfft(const PmeGpu *pmeGpu); +void pme_gpu_destroy_3dfft(const PmeGpu* pmeGpu); /* Several GPU event-based timing functions that live in pme_gpu_timings.cpp */ @@ -352,21 +349,21 @@ void pme_gpu_destroy_3dfft(const PmeGpu *pmeGpu); * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_update_timings(const PmeGpu *pmeGpu); +void pme_gpu_update_timings(const PmeGpu* pmeGpu); /*! \libinternal \brief * Updates the internal list of active PME GPU stages (if timings are enabled). * * \param[in] pmeGpu The PME GPU data structure. */ -void pme_gpu_reinit_timings(const PmeGpu *pmeGpu); +void pme_gpu_reinit_timings(const PmeGpu* pmeGpu); /*! \brief * Resets the PME GPU timings. To be called at the reset MD step. * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_reset_timings(const PmeGpu *pmeGpu); +void pme_gpu_reset_timings(const PmeGpu* pmeGpu); /*! \libinternal \brief * Copies the PME GPU timings to the gmx_wallclock_gpu_t structure (for log output). To be called at the run end. @@ -374,8 +371,7 @@ void pme_gpu_reset_timings(const PmeGpu *pmeGpu); * \param[in] pmeGpu The PME GPU structure. * \param[in] timings The gmx_wallclock_gpu_pme_t structure. */ -void pme_gpu_get_timings(const PmeGpu *pmeGpu, - gmx_wallclock_gpu_pme_t *timings); +void pme_gpu_get_timings(const PmeGpu* pmeGpu, gmx_wallclock_gpu_pme_t* timings); /* The PME stages themselves */ @@ -391,12 +387,12 @@ void pme_gpu_get_timings(const PmeGpu *pmeGpu, * \param[in] computeSplines Should the computation of spline parameters and gridline indices be performed. * \param[in] spreadCharges Should the charges/coefficients be spread on the grid. */ -GPU_FUNC_QUALIFIER void pme_gpu_spread(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), - GpuEventSynchronizer *GPU_FUNC_ARGUMENT(xReadyOnDevice), +GPU_FUNC_QUALIFIER void pme_gpu_spread(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), + GpuEventSynchronizer* GPU_FUNC_ARGUMENT(xReadyOnDevice), int GPU_FUNC_ARGUMENT(gridIndex), - real *GPU_FUNC_ARGUMENT(h_grid), + real* GPU_FUNC_ARGUMENT(h_grid), bool GPU_FUNC_ARGUMENT(computeSplines), - bool GPU_FUNC_ARGUMENT(spreadCharges)) GPU_FUNC_TERM; + bool GPU_FUNC_ARGUMENT(spreadCharges)) GPU_FUNC_TERM; /*! \libinternal \brief * 3D FFT R2C/C2R routine. @@ -405,9 +401,7 @@ GPU_FUNC_QUALIFIER void pme_gpu_spread(const PmeGpu *GPU_FUNC_ARGUMENT(p * \param[in] direction Transform direction (real-to-complex or complex-to-real) * \param[in] gridIndex Index of the PME grid - unused, assumed to be 0. */ -void pme_gpu_3dfft(const PmeGpu *pmeGpu, - enum gmx_fft_direction direction, - int gridIndex); +void pme_gpu_3dfft(const PmeGpu* pmeGpu, enum gmx_fft_direction direction, int gridIndex); /*! \libinternal \brief * A GPU Fourier space solving function. @@ -417,59 +411,64 @@ void pme_gpu_3dfft(const PmeGpu *pmeGpu, * \param[in] gridOrdering Specifies the dimenion ordering of the complex grid. TODO: store this information? * \param[in] computeEnergyAndVirial Tells if the energy and virial computation should also be performed. */ -GPU_FUNC_QUALIFIER void pme_gpu_solve(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), - t_complex *GPU_FUNC_ARGUMENT(h_grid), - GridOrdering GPU_FUNC_ARGUMENT(gridOrdering), - bool GPU_FUNC_ARGUMENT(computeEnergyAndVirial)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_solve(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), + t_complex* GPU_FUNC_ARGUMENT(h_grid), + GridOrdering GPU_FUNC_ARGUMENT(gridOrdering), + bool GPU_FUNC_ARGUMENT(computeEnergyAndVirial)) GPU_FUNC_TERM; /*! \libinternal \brief * A GPU force gathering function. * * \param[in] pmeGpu The PME GPU structure. * \param[in] forceTreatment Tells how data in h_forces should be treated. - * TODO: determine efficiency/balance of host/device-side reductions. - * \param[in] h_grid The host-side grid buffer (used only in testing mode) + * TODO: determine efficiency/balance of host/device-side + * reductions. \param[in] h_grid The host-side grid buffer (used only in testing mode) */ -GPU_FUNC_QUALIFIER void pme_gpu_gather(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), +GPU_FUNC_QUALIFIER void pme_gpu_gather(PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), PmeForceOutputHandling GPU_FUNC_ARGUMENT(forceTreatment), - const float *GPU_FUNC_ARGUMENT(h_grid)) GPU_FUNC_TERM; + const float* GPU_FUNC_ARGUMENT(h_grid)) GPU_FUNC_TERM; /*! \brief Return pointer to device copy of coordinate data. * \param[in] pmeGpu The PME GPU structure. * \returns Pointer to coordinate data */ -GPU_FUNC_QUALIFIER DeviceBuffer pme_gpu_get_kernelparam_coordinates(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(DeviceBuffer {}); +GPU_FUNC_QUALIFIER DeviceBuffer pme_gpu_get_kernelparam_coordinates(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) + GPU_FUNC_TERM_WITH_RETURN(DeviceBuffer{}); /*! \brief Sets the device pointer to coordinate data * \param[in] pmeGpu The PME GPU structure. * \param[in] d_x Pointer to coordinate data */ -GPU_FUNC_QUALIFIER void pme_gpu_set_kernelparam_coordinates(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), - DeviceBuffer GPU_FUNC_ARGUMENT(d_x)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_set_kernelparam_coordinates(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), + DeviceBuffer GPU_FUNC_ARGUMENT(d_x)) GPU_FUNC_TERM; /*! \brief Return pointer to device copy of force data. * \param[in] pmeGpu The PME GPU structure. * \returns Pointer to force data */ -GPU_FUNC_QUALIFIER void * pme_gpu_get_kernelparam_forces(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_kernelparam_forces(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Return pointer to GPU stream. * \param[in] pmeGpu The PME GPU structure. * \returns Pointer to stream object. */ -GPU_FUNC_QUALIFIER void * pme_gpu_get_stream(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_stream(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Return pointer to GPU context (for OpenCL builds). * \param[in] pmeGpu The PME GPU structure. * \returns Pointer to context object. */ -GPU_FUNC_QUALIFIER void * pme_gpu_get_context(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER void* pme_gpu_get_context(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Return pointer to the sync object triggered after the PME force calculation completion * \param[in] pmeGpu The PME GPU structure. * \returns Pointer to sync object */ -GPU_FUNC_QUALIFIER GpuEventSynchronizer *pme_gpu_get_forces_ready_synchronizer(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(nullptr); +GPU_FUNC_QUALIFIER GpuEventSynchronizer* pme_gpu_get_forces_ready_synchronizer( + const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM_WITH_RETURN(nullptr); /* The inlined convenience PME GPU status getters */ @@ -479,7 +478,7 @@ GPU_FUNC_QUALIFIER GpuEventSynchronizer *pme_gpu_get_forces_ready_synchronizer(c * \param[in] pmeGpu The PME GPU structure. * \returns True if PME runs on multiple GPUs, false otherwise. */ -inline bool pme_gpu_uses_dd(const PmeGpu *pmeGpu) +inline bool pme_gpu_uses_dd(const PmeGpu* pmeGpu) { return !pmeGpu->settings.useDecomposition; } @@ -490,7 +489,7 @@ inline bool pme_gpu_uses_dd(const PmeGpu *pmeGpu) * \param[in] pmeGpu The PME GPU structure. * \returns True if the gathering is performed on GPU, false otherwise. */ -inline bool pme_gpu_performs_gather(const PmeGpu *pmeGpu) +inline bool pme_gpu_performs_gather(const PmeGpu* pmeGpu) { return pmeGpu->settings.performGPUGather; } @@ -501,7 +500,7 @@ inline bool pme_gpu_performs_gather(const PmeGpu *pmeGpu) * \param[in] pmeGpu The PME GPU structure. * \returns True if FFT is performed on GPU, false otherwise. */ -inline bool pme_gpu_performs_FFT(const PmeGpu *pmeGpu) +inline bool pme_gpu_performs_FFT(const PmeGpu* pmeGpu) { return pmeGpu->settings.performGPUFFT; } @@ -512,7 +511,7 @@ inline bool pme_gpu_performs_FFT(const PmeGpu *pmeGpu) * \param[in] pmeGpu The PME GPU structure. * \returns True if (un-)wrapping is performed on GPU, false otherwise. */ -inline bool pme_gpu_performs_wrapping(const PmeGpu *pmeGpu) +inline bool pme_gpu_performs_wrapping(const PmeGpu* pmeGpu) { return pmeGpu->settings.useDecomposition; } @@ -523,7 +522,7 @@ inline bool pme_gpu_performs_wrapping(const PmeGpu *pmeGpu) * \param[in] pmeGpu The PME GPU structure. * \returns True if solving is performed on GPU, false otherwise. */ -inline bool pme_gpu_performs_solve(const PmeGpu *pmeGpu) +inline bool pme_gpu_performs_solve(const PmeGpu* pmeGpu) { return pmeGpu->settings.performGPUSolve; } @@ -536,12 +535,12 @@ inline bool pme_gpu_performs_solve(const PmeGpu *pmeGpu) * \param[in] pmeGpu The PME GPU structure. * \param[in] testing Should the testing mode be enabled, or disabled. */ -inline void pme_gpu_set_testing(PmeGpu *pmeGpu, bool testing) +inline void pme_gpu_set_testing(PmeGpu* pmeGpu, bool testing) { if (pmeGpu) { pmeGpu->settings.copyAllOutputs = testing; - pmeGpu->settings.transferKind = testing ? GpuApiCallBehavior::Sync : GpuApiCallBehavior::Async; + pmeGpu->settings.transferKind = testing ? GpuApiCallBehavior::Sync : GpuApiCallBehavior::Async; } } @@ -551,7 +550,7 @@ inline void pme_gpu_set_testing(PmeGpu *pmeGpu, bool testing) * \param[in] pmeGpu The PME GPU structure. * \returns true if testing mode is enabled, false otherwise. */ -inline bool pme_gpu_is_testing(const PmeGpu *pmeGpu) +inline bool pme_gpu_is_testing(const PmeGpu* pmeGpu) { return pmeGpu->settings.copyAllOutputs; } @@ -567,9 +566,8 @@ inline bool pme_gpu_is_testing(const PmeGpu *pmeGpu) * \param[in] pme The PME structure. * \param[out] output Pointer to output where energy and virial should be stored. */ -GPU_FUNC_QUALIFIER void - pme_gpu_getEnergyAndVirial(const gmx_pme_t &GPU_FUNC_ARGUMENT(pme), - PmeOutput *GPU_FUNC_ARGUMENT(output)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_getEnergyAndVirial(const gmx_pme_t& GPU_FUNC_ARGUMENT(pme), + PmeOutput* GPU_FUNC_ARGUMENT(output)) GPU_FUNC_TERM; /*! \libinternal \brief * Returns the GPU outputs (forces, energy and virial) @@ -579,9 +577,9 @@ GPU_FUNC_QUALIFIER void * The flags are the GMX_PME_ flags from pme.h. * \returns The output object. */ -GPU_FUNC_QUALIFIER PmeOutput - pme_gpu_getOutput(const gmx_pme_t &GPU_FUNC_ARGUMENT(pme), - int GPU_FUNC_ARGUMENT(flags)) GPU_FUNC_TERM_WITH_RETURN(PmeOutput {}); +GPU_FUNC_QUALIFIER PmeOutput pme_gpu_getOutput(const gmx_pme_t& GPU_FUNC_ARGUMENT(pme), + int GPU_FUNC_ARGUMENT(flags)) + GPU_FUNC_TERM_WITH_RETURN(PmeOutput{}); /*! \libinternal \brief * Updates the unit cell parameters. Does not check if update is necessary - that is done in pme_gpu_prepare_computation(). @@ -589,7 +587,7 @@ GPU_FUNC_QUALIFIER PmeOutput * \param[in] pmeGpu The PME GPU structure. * \param[in] box The unit cell box. */ -GPU_FUNC_QUALIFIER void pme_gpu_update_input_box(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), +GPU_FUNC_QUALIFIER void pme_gpu_update_input_box(PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), const matrix GPU_FUNC_ARGUMENT(box)) GPU_FUNC_TERM; /*! \libinternal \brief @@ -602,7 +600,7 @@ GPU_FUNC_QUALIFIER void pme_gpu_update_input_box(PmeGpu *GPU_FUNC_ARGUMENT(pmeGp * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_finish_computation(const PmeGpu *pmeGpu); +void pme_gpu_finish_computation(const PmeGpu* pmeGpu); //! A binary enum for spline data layout transformation enum class PmeLayoutTransform @@ -621,8 +619,8 @@ enum class PmeLayoutTransform * \param[in] dimIndex Dimension index. * \param[in] transform Layout transform type */ -GPU_FUNC_QUALIFIER void pme_gpu_transform_spline_atom_data(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), - const PmeAtomComm *GPU_FUNC_ARGUMENT(atc), +GPU_FUNC_QUALIFIER void pme_gpu_transform_spline_atom_data(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), + const PmeAtomComm* GPU_FUNC_ARGUMENT(atc), PmeSplineDataType GPU_FUNC_ARGUMENT(type), int GPU_FUNC_ARGUMENT(dimIndex), PmeLayoutTransform GPU_FUNC_ARGUMENT(transform)) GPU_FUNC_TERM; @@ -640,11 +638,7 @@ GPU_FUNC_QUALIFIER void pme_gpu_transform_spline_atom_data(const PmeGpu *GPU_FUN * * \returns Index into theta or dtheta array using GPU layout. */ -int getSplineParamFullIndex(int order, - int splineIndex, - int dimIndex, - int atomIndex, - int atomsPerWarp); +int getSplineParamFullIndex(int order, int splineIndex, int dimIndex, int atomIndex, int atomsPerWarp); /*! \libinternal \brief * Get the normal/padded grid dimensions of the real-space PME grid on GPU. Only used in tests. @@ -653,9 +647,9 @@ int getSplineParamFullIndex(int order, * \param[out] gridSize Pointer to the grid dimensions to fill in. * \param[out] paddedGridSize Pointer to the padded grid dimensions to fill in. */ -GPU_FUNC_QUALIFIER void pme_gpu_get_real_grid_sizes(const PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), - gmx::IVec *GPU_FUNC_ARGUMENT(gridSize), - gmx::IVec *GPU_FUNC_ARGUMENT(paddedGridSize)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_get_real_grid_sizes(const PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), + gmx::IVec* GPU_FUNC_ARGUMENT(gridSize), + gmx::IVec* GPU_FUNC_ARGUMENT(paddedGridSize)) GPU_FUNC_TERM; /*! \libinternal \brief * (Re-)initializes the PME GPU data at the beginning of the run or on DLB. @@ -665,8 +659,8 @@ GPU_FUNC_QUALIFIER void pme_gpu_get_real_grid_sizes(const PmeGpu *GPU_FUNC_ARGUM * \param[in] pmeGpuProgram The PME GPU program data * \throws gmx::NotImplementedError if this generally valid PME structure is not valid for GPU runs. */ -GPU_FUNC_QUALIFIER void pme_gpu_reinit(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - const gmx_device_info_t *GPU_FUNC_ARGUMENT(gpuInfo), +GPU_FUNC_QUALIFIER void pme_gpu_reinit(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + const gmx_device_info_t* GPU_FUNC_ARGUMENT(gpuInfo), PmeGpuProgramHandle GPU_FUNC_ARGUMENT(pmeGpuProgram)) GPU_FUNC_TERM; /*! \libinternal \brief @@ -674,7 +668,7 @@ GPU_FUNC_QUALIFIER void pme_gpu_reinit(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), * * \param[in] pmeGpu The PME GPU structure. */ -GPU_FUNC_QUALIFIER void pme_gpu_destroy(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM; +GPU_FUNC_QUALIFIER void pme_gpu_destroy(PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu)) GPU_FUNC_TERM; /*! \libinternal \brief * Reallocates the local atoms data (charges, coordinates, etc.). Copies the charges to the GPU. @@ -683,12 +677,12 @@ GPU_FUNC_QUALIFIER void pme_gpu_destroy(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu)) GPU_F * \param[in] nAtoms The number of particles. * \param[in] charges The pointer to the host-side array of particle charges. * - * This is a function that should only be called in the beginning of the run and on domain decomposition. - * Should be called before the pme_gpu_set_io_ranges. + * This is a function that should only be called in the beginning of the run and on domain + * decomposition. Should be called before the pme_gpu_set_io_ranges. */ -GPU_FUNC_QUALIFIER void pme_gpu_reinit_atoms(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), +GPU_FUNC_QUALIFIER void pme_gpu_reinit_atoms(PmeGpu* GPU_FUNC_ARGUMENT(pmeGpu), int GPU_FUNC_ARGUMENT(nAtoms), - const real *GPU_FUNC_ARGUMENT(charges)) GPU_FUNC_TERM; + const real* GPU_FUNC_ARGUMENT(charges)) GPU_FUNC_TERM; /*! \brief \libinternal * The PME GPU reinitialization function that is called both at the end of any PME computation and on any load balancing. @@ -697,7 +691,7 @@ GPU_FUNC_QUALIFIER void pme_gpu_reinit_atoms(PmeGpu *GPU_FUNC_ARGUMENT(pmeGpu), * * \param[in] pmeGpu The PME GPU structure. */ -void pme_gpu_reinit_computation(const PmeGpu *pmeGpu); +void pme_gpu_reinit_computation(const PmeGpu* pmeGpu); /*! \brief * Blocks until PME GPU tasks are completed, and gets the output forces and virial/energy @@ -709,10 +703,9 @@ void pme_gpu_reinit_computation(const PmeGpu *pmeGpu); * \param[out] wcycle The wallclock counter. * \return The output forces, energy and virial */ -GPU_FUNC_QUALIFIER PmeOutput - pme_gpu_wait_finish_task(gmx_pme_t *GPU_FUNC_ARGUMENT(pme), - int GPU_FUNC_ARGUMENT(flags), - gmx_wallcycle *GPU_FUNC_ARGUMENT(wcycle)) GPU_FUNC_TERM_WITH_RETURN(PmeOutput {} - ); +GPU_FUNC_QUALIFIER PmeOutput pme_gpu_wait_finish_task(gmx_pme_t* GPU_FUNC_ARGUMENT(pme), + int GPU_FUNC_ARGUMENT(flags), + gmx_wallcycle* GPU_FUNC_ARGUMENT(wcycle)) + GPU_FUNC_TERM_WITH_RETURN(PmeOutput{}); #endif diff --git a/src/gromacs/ewald/pme_gpu_program.cpp b/src/gromacs/ewald/pme_gpu_program.cpp index 67e6a4e1c9..5227eca063 100644 --- a/src/gromacs/ewald/pme_gpu_program.cpp +++ b/src/gromacs/ewald/pme_gpu_program.cpp @@ -51,14 +51,14 @@ #include "pme_gpu_program_impl.h" -PmeGpuProgram::PmeGpuProgram(const gmx_device_info_t *deviceInfo) : +PmeGpuProgram::PmeGpuProgram(const gmx_device_info_t* deviceInfo) : impl_(std::make_unique(deviceInfo)) { } PmeGpuProgram::~PmeGpuProgram() = default; -PmeGpuProgramStorage buildPmeGpuProgram(const gmx_device_info_t *deviceInfo) +PmeGpuProgramStorage buildPmeGpuProgram(const gmx_device_info_t* deviceInfo) { if (!deviceInfo) { diff --git a/src/gromacs/ewald/pme_gpu_program.h b/src/gromacs/ewald/pme_gpu_program.h index de4eb562a6..3045feb973 100644 --- a/src/gromacs/ewald/pme_gpu_program.h +++ b/src/gromacs/ewald/pme_gpu_program.h @@ -54,12 +54,12 @@ struct gmx_device_info_t; class PmeGpuProgram { - public: - explicit PmeGpuProgram(const gmx_device_info_t *deviceInfo); - ~PmeGpuProgram(); +public: + explicit PmeGpuProgram(const gmx_device_info_t* deviceInfo); + ~PmeGpuProgram(); - // TODO: design getters for information inside, if needed for PME, and make this private? - std::unique_ptr impl_; + // TODO: design getters for information inside, if needed for PME, and make this private? + std::unique_ptr impl_; }; /*! \brief This is an owning handle for the compiled PME GPU kernels. @@ -69,11 +69,11 @@ using PmeGpuProgramStorage = std::unique_ptr; /*! \brief This is a handle for passing references to PME GPU program data. * TODO: it should be a const reference, but for that the PmeGpu types need to be C++ */ -using PmeGpuProgramHandle = const PmeGpuProgram *; +using PmeGpuProgramHandle = const PmeGpuProgram*; /*! \brief * Factory function used to build persistent PME GPU program for the device at once. */ -PmeGpuProgramStorage buildPmeGpuProgram(const gmx_device_info_t * /*deviceInfo*/); +PmeGpuProgramStorage buildPmeGpuProgram(const gmx_device_info_t* /*deviceInfo*/); #endif diff --git a/src/gromacs/ewald/pme_gpu_program_impl.cpp b/src/gromacs/ewald/pme_gpu_program_impl.cpp index cb993bea8b..078f97ee4f 100644 --- a/src/gromacs/ewald/pme_gpu_program_impl.cpp +++ b/src/gromacs/ewald/pme_gpu_program_impl.cpp @@ -45,11 +45,12 @@ #include "pme_gpu_program_impl.h" -PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t * /*unused*/) : +PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t* /*unused*/) : warpSize(0), spreadWorkGroupSize(0), gatherWorkGroupSize(0), solveMaxWorkGroupSize(0) -{} +{ +} PmeGpuProgramImpl::~PmeGpuProgramImpl() = default; diff --git a/src/gromacs/ewald/pme_gpu_program_impl.cu b/src/gromacs/ewald/pme_gpu_program_impl.cu index 347d69f910..f34f7a2741 100644 --- a/src/gromacs/ewald/pme_gpu_program_impl.cu +++ b/src/gromacs/ewald/pme_gpu_program_impl.cu @@ -46,93 +46,63 @@ #include "pme_gpu_program_impl.h" #include "pme_gpu_constants.h" -#include "pme_gpu_internal.h" // for GridOrdering enum +#include "pme_gpu_internal.h" // for GridOrdering enum #include "pme_gpu_types_host.h" // PME interpolation order -constexpr int c_pmeOrder = 4; +constexpr int c_pmeOrder = 4; // These hardcoded spread/gather parameters refer to not-implemented PME GPU 2D decomposition in X/Y constexpr bool c_wrapX = true; constexpr bool c_wrapY = true; //! PME CUDA kernels forward declarations. Kernels are documented in their respective files. -template < - const int order, - const bool computeSplines, - const bool spreadCharges, - const bool wrapX, - const bool wrapY, - const bool writeGlobal, - const bool orderThreads - > +template void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernelParams); // Add extern declarations to inform that there will be a definition // provided in another translation unit. -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); +extern template void pme_spline_and_spread_kernel( + const PmeGpuCudaKernelParams); -template< - GridOrdering gridOrdering, - bool computeEnergyAndVirial - > +template void pme_solve_kernel(const PmeGpuCudaKernelParams kernelParams); // Add extern declarations to inform that there will be a definition // provided in another translation unit. -extern template -void pme_solve_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_solve_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_solve_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_solve_kernel(const PmeGpuCudaKernelParams); +extern template void pme_solve_kernel(const PmeGpuCudaKernelParams); +extern template void pme_solve_kernel(const PmeGpuCudaKernelParams); +extern template void pme_solve_kernel(const PmeGpuCudaKernelParams); +extern template void pme_solve_kernel(const PmeGpuCudaKernelParams); -template < - const int order, - const bool overwriteForces, - const bool wrapX, - const bool wrapY, - const bool readGlobal, - const bool orderThreads - > +template void pme_gather_kernel(const PmeGpuCudaKernelParams kernelParams); // Add extern declarations to inform that there will be a definition // provided in another translation unit. -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); -extern template -void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); +extern template void pme_gather_kernel(const PmeGpuCudaKernelParams); -PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t *) +PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t*) { // kernel parameters warpSize = warp_size; @@ -140,33 +110,40 @@ PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t *) solveMaxWorkGroupSize = c_solveMaxThreadsPerBlock; gatherWorkGroupSize = c_gatherMaxThreadsPerBlock; -/*! - * Not all combinations of the splineAndSpread, spline and Spread kernels are required - * If only the spline (without the spread) then it does not make sense not to write the data to global memory - * Similarly the spread kernel (without the spline) implies that we should read the spline data from global memory - */ - splineAndSpreadKernel = pme_spline_and_spread_kernel; - splineAndSpreadKernelThPerAtom4 = pme_spline_and_spread_kernel; - splineAndSpreadKernelWriteSplines = pme_spline_and_spread_kernel; - splineAndSpreadKernelWriteSplinesThPerAtom4 = pme_spline_and_spread_kernel; - splineKernel = pme_spline_and_spread_kernel; - splineKernelThPerAtom4 = pme_spline_and_spread_kernel; - spreadKernel = pme_spline_and_spread_kernel; - spreadKernelThPerAtom4 = pme_spline_and_spread_kernel; - gatherKernel = pme_gather_kernel; - gatherKernelThPerAtom4 = pme_gather_kernel; - gatherKernelReadSplines = pme_gather_kernel; - gatherKernelReadSplinesThPerAtom4 = pme_gather_kernel; - gatherReduceWithInputKernel = pme_gather_kernel; - gatherReduceWithInputKernelThPerAtom4 = pme_gather_kernel; - gatherReduceWithInputKernelReadSplines = pme_gather_kernel; - gatherReduceWithInputKernelReadSplinesThPerAtom4 = pme_gather_kernel; - solveXYZKernel = pme_solve_kernel; - solveXYZEnergyKernel = pme_solve_kernel; - solveYZXKernel = pme_solve_kernel; - solveYZXEnergyKernel = pme_solve_kernel; + /*! + * Not all combinations of the splineAndSpread, spline and Spread kernels are required + * If only the spline (without the spread) then it does not make sense not to write the data to global memory + * Similarly the spread kernel (without the spline) implies that we should read the spline data from global memory + */ + splineAndSpreadKernel = + pme_spline_and_spread_kernel; + splineAndSpreadKernelThPerAtom4 = + pme_spline_and_spread_kernel; + splineAndSpreadKernelWriteSplines = + pme_spline_and_spread_kernel; + splineAndSpreadKernelWriteSplinesThPerAtom4 = + pme_spline_and_spread_kernel; + splineKernel = pme_spline_and_spread_kernel; + splineKernelThPerAtom4 = + pme_spline_and_spread_kernel; + spreadKernel = pme_spline_and_spread_kernel; + spreadKernelThPerAtom4 = + pme_spline_and_spread_kernel; + gatherKernel = pme_gather_kernel; + gatherKernelThPerAtom4 = pme_gather_kernel; + gatherKernelReadSplines = pme_gather_kernel; + gatherKernelReadSplinesThPerAtom4 = pme_gather_kernel; + gatherReduceWithInputKernel = pme_gather_kernel; + gatherReduceWithInputKernelThPerAtom4 = + pme_gather_kernel; + gatherReduceWithInputKernelReadSplines = + pme_gather_kernel; + gatherReduceWithInputKernelReadSplinesThPerAtom4 = + pme_gather_kernel; + solveXYZKernel = pme_solve_kernel; + solveXYZEnergyKernel = pme_solve_kernel; + solveYZXKernel = pme_solve_kernel; + solveYZXEnergyKernel = pme_solve_kernel; } -PmeGpuProgramImpl::~PmeGpuProgramImpl() -{ -} +PmeGpuProgramImpl::~PmeGpuProgramImpl() {} diff --git a/src/gromacs/ewald/pme_gpu_program_impl.h b/src/gromacs/ewald/pme_gpu_program_impl.h index e45a3110f5..8867ea0bdc 100644 --- a/src/gromacs/ewald/pme_gpu_program_impl.h +++ b/src/gromacs/ewald/pme_gpu_program_impl.h @@ -81,11 +81,11 @@ struct PmeGpuProgramImpl //! Conveniently all the PME kernels use the same single argument type #if GMX_GPU == GMX_GPU_CUDA - using PmeKernelHandle = void(*)(const struct PmeGpuCudaKernelParams); + using PmeKernelHandle = void (*)(const struct PmeGpuCudaKernelParams); #elif GMX_GPU == GMX_GPU_OPENCL using PmeKernelHandle = cl_kernel; #else - using PmeKernelHandle = void *; + using PmeKernelHandle = void*; #endif /*! \brief @@ -100,13 +100,13 @@ struct PmeGpuProgramImpl /** * Spread/spline kernels are compiled only for order of 4. * There are multiple versions of each kernel, paramaretized according to - * Number of threads per atom. Using either order(4) or order*order (16) threads per atom is supported - * If the spline data is written in the spline/spread kernel and loaded in the gather + * Number of threads per atom. Using either order(4) or order*order (16) threads per atom is + * supported If the spline data is written in the spline/spread kernel and loaded in the gather * or recalculated in the gather. * Spreading kernels also have hardcoded X/Y indices wrapping parameters, * as a placeholder for implementing 1/2D decomposition. */ - size_t spreadWorkGroupSize; + size_t spreadWorkGroupSize; PmeKernelHandle splineKernel; PmeKernelHandle splineKernelThPerAtom4; @@ -124,7 +124,7 @@ struct PmeGpuProgramImpl * Also similarly to the gather we can use either order(4) or order*order (16) threads per atom * and either recalculate the splines or read the ones written by the spread */ - size_t gatherWorkGroupSize; + size_t gatherWorkGroupSize; PmeKernelHandle gatherReduceWithInputKernel; PmeKernelHandle gatherReduceWithInputKernelThPerAtom4; @@ -140,7 +140,7 @@ struct PmeGpuProgramImpl /** Solve kernel doesn't care about the interpolation order, but can optionally * compute energy and virial, and supports XYZ and YZX grid orderings. */ - size_t solveMaxWorkGroupSize; + size_t solveMaxWorkGroupSize; PmeKernelHandle solveYZXKernel; PmeKernelHandle solveXYZKernel; @@ -150,13 +150,13 @@ struct PmeGpuProgramImpl PmeGpuProgramImpl() = delete; //! Constructor for the given device - explicit PmeGpuProgramImpl(const gmx_device_info_t *deviceInfo); + explicit PmeGpuProgramImpl(const gmx_device_info_t* deviceInfo); ~PmeGpuProgramImpl(); GMX_DISALLOW_COPY_AND_ASSIGN(PmeGpuProgramImpl); - private: - // Compiles kernels, if supported. Called by the constructor. - void compileKernels(const gmx_device_info_t *deviceInfo); +private: + // Compiles kernels, if supported. Called by the constructor. + void compileKernels(const gmx_device_info_t* deviceInfo); }; #endif diff --git a/src/gromacs/ewald/pme_gpu_program_impl_ocl.cpp b/src/gromacs/ewald/pme_gpu_program_impl_ocl.cpp index 423eaf2c8a..800f43ea9e 100644 --- a/src/gromacs/ewald/pme_gpu_program_impl_ocl.cpp +++ b/src/gromacs/ewald/pme_gpu_program_impl_ocl.cpp @@ -53,7 +53,7 @@ #include "pme_gpu_types_host.h" #include "pme_grid.h" -PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t *deviceInfo) +PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t* deviceInfo) { // Context creation (which should happen outside of this class: #2522) cl_platform_id platformId = deviceInfo->ocl_gpu_id.ocl_platform_id; @@ -63,25 +63,23 @@ PmeGpuProgramImpl::PmeGpuProgramImpl(const gmx_device_info_t *deviceInfo) contextProperties[1] = reinterpret_cast(platformId); contextProperties[2] = 0; /* Terminates the list of properties */ - cl_int clError; + cl_int clError; context = clCreateContext(contextProperties, 1, &deviceId, nullptr, nullptr, &clError); if (clError != CL_SUCCESS) { - const std::string errorString = gmx::formatString("Failed to create context for PME on GPU #%s:\n OpenCL error %d: %s", - deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); + const std::string errorString = gmx::formatString( + "Failed to create context for PME on GPU #%s:\n OpenCL error %d: %s", + deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); GMX_THROW(gmx::InternalError(errorString)); } // kernel parameters - warpSize = gmx::ocl::getDeviceWarpSize(context, deviceId); + warpSize = gmx::ocl::getDeviceWarpSize(context, deviceId); // TODO: for Intel ideally we'd want to set these based on the compiler warp size // but given that we've done no tuning for Intel iGPU, this is as good as anything. - spreadWorkGroupSize = std::min(c_spreadMaxWarpsPerBlock * warpSize, - deviceInfo->maxWorkGroupSize); - solveMaxWorkGroupSize = std::min(c_solveMaxWarpsPerBlock * warpSize, - deviceInfo->maxWorkGroupSize); - gatherWorkGroupSize = std::min(c_gatherMaxWarpsPerBlock * warpSize, - deviceInfo->maxWorkGroupSize); + spreadWorkGroupSize = std::min(c_spreadMaxWarpsPerBlock * warpSize, deviceInfo->maxWorkGroupSize); + solveMaxWorkGroupSize = std::min(c_solveMaxWarpsPerBlock * warpSize, deviceInfo->maxWorkGroupSize); + gatherWorkGroupSize = std::min(c_gatherMaxWarpsPerBlock * warpSize, deviceInfo->maxWorkGroupSize); compileKernels(deviceInfo); } @@ -100,8 +98,10 @@ PmeGpuProgramImpl::~PmeGpuProgramImpl() stat |= clReleaseKernel(solveYZXKernel); stat |= clReleaseKernel(solveYZXEnergyKernel); stat |= clReleaseContext(context); - GMX_ASSERT(stat == CL_SUCCESS, gmx::formatString("Failed to release PME OpenCL resources %d: %s", - stat, ocl_get_error_string(stat).c_str()).c_str()); + GMX_ASSERT(stat == CL_SUCCESS, + gmx::formatString("Failed to release PME OpenCL resources %d: %s", stat, + ocl_get_error_string(stat).c_str()) + .c_str()); } /*! \brief Ensure that spread/gather kernels have been compiled to a suitable warp size @@ -110,9 +110,7 @@ PmeGpuProgramImpl::~PmeGpuProgramImpl() * smaller than the minimum order^2 required in spread/gather ATM which * we need to check for. */ -static void checkRequiredWarpSize(cl_kernel kernel, - const char* kernelName, - const gmx_device_info_t *deviceInfo) +static void checkRequiredWarpSize(cl_kernel kernel, const char* kernelName, const gmx_device_info_t* deviceInfo) { if (deviceInfo->vendor_e == OCL_VENDOR_INTEL) { @@ -120,16 +118,17 @@ static void checkRequiredWarpSize(cl_kernel kernel, if (kernelWarpSize < c_pmeSpreadGatherMinWarpSize) { - const std::string errorString = gmx::formatString("PME OpenCL kernels require >=%d execution width, but the %s kernel " - "has been compiled for the device %s to a %zu width and therefore it can not execute correctly.", - c_pmeSpreadGatherMinWarpSize, kernelName, - deviceInfo->device_name, kernelWarpSize); + const std::string errorString = gmx::formatString( + "PME OpenCL kernels require >=%d execution width, but the %s kernel " + "has been compiled for the device %s to a %zu width and therefore it can not " + "execute correctly.", + c_pmeSpreadGatherMinWarpSize, kernelName, deviceInfo->device_name, kernelWarpSize); GMX_THROW(gmx::InternalError(errorString)); } } } -void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t *deviceInfo) +void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t* deviceInfo) { // We might consider storing program as a member variable if it's needed later cl_program program = nullptr; @@ -141,49 +140,37 @@ void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t *deviceInfo) * in the JIT compilation that happens at runtime. */ const std::string commonDefines = gmx::formatString( - "-Dwarp_size=%zd " - "-Dorder=%d " - "-DatomsPerWarp=%zd " - "-DthreadsPerAtom=%d " - // forwarding from pme_grid.h, used for spline computation table sizes only - "-Dc_pmeMaxUnitcellShift=%f " - // forwarding PME behavior constants from pme_gpu_constants.h - "-Dc_usePadding=%d " - "-Dc_skipNeutralAtoms=%d " - "-Dc_virialAndEnergyCount=%d " - // forwarding kernel work sizes - "-Dc_spreadWorkGroupSize=%zd " - "-Dc_solveMaxWorkGroupSize=%zd " - "-Dc_gatherWorkGroupSize=%zd " - // forwarding from vectypes.h - "-DDIM=%d -DXX=%d -DYY=%d -DZZ=%d " - // decomposition parameter placeholders - "-DwrapX=true -DwrapY=true ", - warpSize, - c_pmeGpuOrder, - warpSize / c_pmeSpreadGatherThreadsPerAtom, - c_pmeSpreadGatherThreadsPerAtom, - static_cast(c_pmeMaxUnitcellShift), - static_cast(c_usePadding), - static_cast(c_skipNeutralAtoms), - c_virialAndEnergyCount, - spreadWorkGroupSize, - solveMaxWorkGroupSize, - gatherWorkGroupSize, - DIM, XX, YY, ZZ); + "-Dwarp_size=%zd " + "-Dorder=%d " + "-DatomsPerWarp=%zd " + "-DthreadsPerAtom=%d " + // forwarding from pme_grid.h, used for spline computation table sizes only + "-Dc_pmeMaxUnitcellShift=%f " + // forwarding PME behavior constants from pme_gpu_constants.h + "-Dc_usePadding=%d " + "-Dc_skipNeutralAtoms=%d " + "-Dc_virialAndEnergyCount=%d " + // forwarding kernel work sizes + "-Dc_spreadWorkGroupSize=%zd " + "-Dc_solveMaxWorkGroupSize=%zd " + "-Dc_gatherWorkGroupSize=%zd " + // forwarding from vectypes.h + "-DDIM=%d -DXX=%d -DYY=%d -DZZ=%d " + // decomposition parameter placeholders + "-DwrapX=true -DwrapY=true ", + warpSize, c_pmeGpuOrder, warpSize / c_pmeSpreadGatherThreadsPerAtom, + c_pmeSpreadGatherThreadsPerAtom, static_cast(c_pmeMaxUnitcellShift), + static_cast(c_usePadding), static_cast(c_skipNeutralAtoms), c_virialAndEnergyCount, + spreadWorkGroupSize, solveMaxWorkGroupSize, gatherWorkGroupSize, DIM, XX, YY, ZZ); try { /* TODO when we have a proper MPI-aware logging module, the log output here should be written there */ - program = gmx::ocl::compileProgram(stderr, - "gromacs/ewald", - "pme_program.cl", - commonDefines, - context, - deviceInfo->ocl_gpu_id.ocl_device_id, + program = gmx::ocl::compileProgram(stderr, "gromacs/ewald", "pme_program.cl", commonDefines, + context, deviceInfo->ocl_gpu_id.ocl_device_id, deviceInfo->vendor_e); } - catch (gmx::GromacsException &e) + catch (gmx::GromacsException& e) { e.prependContext(gmx::formatString("Failed to compile PME kernels for GPU #%s\n", deviceInfo->device_name)); @@ -192,29 +179,31 @@ void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t *deviceInfo) } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; - constexpr cl_uint expectedKernelCount = 9; + constexpr cl_uint expectedKernelCount = 9; // Has to be equal or larger than the number of kernel instances. // If it is not, CL_INVALID_VALUE will be thrown. std::vector kernels(expectedKernelCount, nullptr); cl_uint actualKernelCount = 0; - cl_int clError = clCreateKernelsInProgram(program, kernels.size(), kernels.data(), &actualKernelCount); + cl_int clError = clCreateKernelsInProgram(program, kernels.size(), kernels.data(), &actualKernelCount); if (clError != CL_SUCCESS) { - const std::string errorString = gmx::formatString("Failed to create kernels for PME on GPU #%s:\n OpenCL error %d: %s", - deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); + const std::string errorString = gmx::formatString( + "Failed to create kernels for PME on GPU #%s:\n OpenCL error %d: %s", + deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); GMX_THROW(gmx::InternalError(errorString)); } kernels.resize(actualKernelCount); std::array kernelNamesBuffer; - for (const auto &kernel : kernels) + for (const auto& kernel : kernels) { - clError = clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, - kernelNamesBuffer.size(), kernelNamesBuffer.data(), nullptr); + clError = clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, kernelNamesBuffer.size(), + kernelNamesBuffer.data(), nullptr); if (clError != CL_SUCCESS) { - const std::string errorString = gmx::formatString("Failed to parse kernels for PME on GPU #%s:\n OpenCL error %d: %s", - deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); + const std::string errorString = gmx::formatString( + "Failed to parse kernels for PME on GPU #%s:\n OpenCL error %d: %s", + deviceInfo->device_name, clError, ocl_get_error_string(clError).c_str()); GMX_THROW(gmx::InternalError(errorString)); } @@ -222,7 +211,7 @@ void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t *deviceInfo) // TODO use a map with string key instead? if (!strcmp(kernelNamesBuffer.data(), "pmeSplineKernel")) { - splineKernel = kernel; + splineKernel = kernel; } else if (!strcmp(kernelNamesBuffer.data(), "pmeSplineAndSpreadKernel")) { @@ -232,7 +221,7 @@ void PmeGpuProgramImpl::compileKernels(const gmx_device_info_t *deviceInfo) } else if (!strcmp(kernelNamesBuffer.data(), "pmeSpreadKernel")) { - spreadKernel = kernel; + spreadKernel = kernel; checkRequiredWarpSize(spreadKernel, kernelNamesBuffer.data(), deviceInfo); } else if (!strcmp(kernelNamesBuffer.data(), "pmeGatherKernel")) diff --git a/src/gromacs/ewald/pme_gpu_timings.cpp b/src/gromacs/ewald/pme_gpu_timings.cpp index 58361a59f0..d725cd968a 100644 --- a/src/gromacs/ewald/pme_gpu_timings.cpp +++ b/src/gromacs/ewald/pme_gpu_timings.cpp @@ -56,41 +56,44 @@ * \param[in] pmeGpu The PME GPU data structure. * \returns True if timings are enabled, false otherwise. */ -inline bool pme_gpu_timings_enabled(const PmeGpu *pmeGpu) +inline bool pme_gpu_timings_enabled(const PmeGpu* pmeGpu) { return pmeGpu->archSpecific->useTiming; } -void pme_gpu_start_timing(const PmeGpu *pmeGpu, size_t PMEStageId) +void pme_gpu_start_timing(const PmeGpu* pmeGpu, size_t PMEStageId) { if (pme_gpu_timings_enabled(pmeGpu)) { - GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), "Wrong PME GPU timing event index"); + GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), + "Wrong PME GPU timing event index"); pmeGpu->archSpecific->timingEvents[PMEStageId].openTimingRegion(pmeGpu->archSpecific->pmeStream); } } -CommandEvent *pme_gpu_fetch_timing_event(const PmeGpu *pmeGpu, size_t PMEStageId) +CommandEvent* pme_gpu_fetch_timing_event(const PmeGpu* pmeGpu, size_t PMEStageId) { - CommandEvent *timingEvent = nullptr; + CommandEvent* timingEvent = nullptr; if (pme_gpu_timings_enabled(pmeGpu)) { - GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), "Wrong PME GPU timing event index"); + GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), + "Wrong PME GPU timing event index"); timingEvent = pmeGpu->archSpecific->timingEvents[PMEStageId].fetchNextEvent(); } return timingEvent; } -void pme_gpu_stop_timing(const PmeGpu *pmeGpu, size_t PMEStageId) +void pme_gpu_stop_timing(const PmeGpu* pmeGpu, size_t PMEStageId) { if (pme_gpu_timings_enabled(pmeGpu)) { - GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), "Wrong PME GPU timing event index"); + GMX_ASSERT(PMEStageId < pmeGpu->archSpecific->timingEvents.size(), + "Wrong PME GPU timing event index"); pmeGpu->archSpecific->timingEvents[PMEStageId].closeTimingRegion(pmeGpu->archSpecific->pmeStream); } } -void pme_gpu_get_timings(const PmeGpu *pmeGpu, gmx_wallclock_gpu_pme_t *timings) +void pme_gpu_get_timings(const PmeGpu* pmeGpu, gmx_wallclock_gpu_pme_t* timings) { if (pme_gpu_timings_enabled(pmeGpu)) { @@ -103,18 +106,18 @@ void pme_gpu_get_timings(const PmeGpu *pmeGpu, gmx_wallclock_gpu_pme_t *timings) } } -void pme_gpu_update_timings(const PmeGpu *pmeGpu) +void pme_gpu_update_timings(const PmeGpu* pmeGpu) { if (pme_gpu_timings_enabled(pmeGpu)) { - for (const size_t &activeTimer : pmeGpu->archSpecific->activeTimers) + for (const size_t& activeTimer : pmeGpu->archSpecific->activeTimers) { pmeGpu->archSpecific->timingEvents[activeTimer].getLastRangeTime(); } } } -void pme_gpu_reinit_timings(const PmeGpu *pmeGpu) +void pme_gpu_reinit_timings(const PmeGpu* pmeGpu) { if (pme_gpu_timings_enabled(pmeGpu)) { @@ -137,7 +140,7 @@ void pme_gpu_reinit_timings(const PmeGpu *pmeGpu) } } -void pme_gpu_reset_timings(const PmeGpu *pmeGpu) +void pme_gpu_reset_timings(const PmeGpu* pmeGpu) { if (pme_gpu_timings_enabled(pmeGpu)) { diff --git a/src/gromacs/ewald/pme_gpu_timings.h b/src/gromacs/ewald/pme_gpu_timings.h index df8c80398b..b2d09e21f7 100644 --- a/src/gromacs/ewald/pme_gpu_timings.h +++ b/src/gromacs/ewald/pme_gpu_timings.h @@ -46,9 +46,9 @@ #include "config.h" #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/gputraits.cuh" +# include "gromacs/gpu_utils/gputraits.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gputraits_ocl.h" +# include "gromacs/gpu_utils/gputraits_ocl.h" #endif struct PmeGpu; @@ -59,7 +59,7 @@ struct PmeGpu; * \param[in] pmeGpu The PME GPU data structure. * \param[in] PMEStageId The PME GPU stage gtPME_ index from the enum in src/gromacs/timing/gpu_timing.h */ -void pme_gpu_start_timing(const PmeGpu *pmeGpu, size_t PMEStageId); +void pme_gpu_start_timing(const PmeGpu* pmeGpu, size_t PMEStageId); /*! \libinternal \brief * Returns raw timing event from the corresponding GpuRegionTimer (if timings are enabled). @@ -68,7 +68,7 @@ void pme_gpu_start_timing(const PmeGpu *pmeGpu, size_t PMEStageId); * \param[in] pmeGpu The PME GPU data structure. * \param[in] PMEStageId The PME GPU stage gtPME_ index from the enum in src/gromacs/timing/gpu_timing.h */ -CommandEvent *pme_gpu_fetch_timing_event(const PmeGpu *pmeGpu, size_t PMEStageId); +CommandEvent* pme_gpu_fetch_timing_event(const PmeGpu* pmeGpu, size_t PMEStageId); /*! \libinternal \brief * Stops timing the certain PME GPU stage during a single computation (if timings are enabled). @@ -76,6 +76,6 @@ CommandEvent *pme_gpu_fetch_timing_event(const PmeGpu *pmeGpu, size_t PMEStageId * \param[in] pmeGpu The PME GPU data structure. * \param[in] PMEStageId The PME GPU stage gtPME_ index from the enum in src/gromacs/timing/gpu_timing.h */ -void pme_gpu_stop_timing(const PmeGpu *pmeGpu, size_t PMEStageId); +void pme_gpu_stop_timing(const PmeGpu* pmeGpu, size_t PMEStageId); #endif diff --git a/src/gromacs/ewald/pme_gpu_types.h b/src/gromacs/ewald/pme_gpu_types.h index 0598aacbbf..3749d5748b 100644 --- a/src/gromacs/ewald/pme_gpu_types.h +++ b/src/gromacs/ewald/pme_gpu_types.h @@ -46,8 +46,8 @@ /* * In OpenCL, the structures must be laid out on the host and device exactly the same way. - * If something is off, one might get an error CL_INVALID_ARG_SIZE if any structure's sizes don't match. - * What's worse, structures might be of same size but members might be aligned differently, + * If something is off, one might get an error CL_INVALID_ARG_SIZE if any structure's sizes don't + * match. What's worse, structures might be of same size but members might be aligned differently, * resulting in wrong kernel results. The structures below are aligned manually. * The pattern is ordering the members of structs from smallest to largest sizeof * (arrays behave the same way as sequences of separate fields), @@ -72,12 +72,14 @@ * then there would be no need for macro. */ #ifndef __OPENCL_C_VERSION__ -#include "gromacs/gpu_utils/devicebuffer.h" -#define HIDE_FROM_OPENCL_COMPILER(x) x -static_assert(sizeof(DeviceBuffer) == 8, "DeviceBuffer is defined as an 8 byte stub for OpenCL C"); -static_assert(sizeof(DeviceBuffer) == 8, "DeviceBuffer is defined as an 8 byte stub for OpenCL C"); +# include "gromacs/gpu_utils/devicebuffer.h" +# define HIDE_FROM_OPENCL_COMPILER(x) x +static_assert(sizeof(DeviceBuffer) == 8, + "DeviceBuffer is defined as an 8 byte stub for OpenCL C"); +static_assert(sizeof(DeviceBuffer) == 8, + "DeviceBuffer is defined as an 8 byte stub for OpenCL C"); #else -#define HIDE_FROM_OPENCL_COMPILER(x) char8 +# define HIDE_FROM_OPENCL_COMPILER(x) char8 #endif /* What follows is all the PME GPU function arguments, @@ -111,20 +113,20 @@ struct PmeGpuGridParams /* Grid sizes */ /*! \brief Real-space grid data dimensions. */ - int realGridSize[DIM]; + int realGridSize[DIM]; /*! \brief Real-space grid dimensions, only converted to floating point. */ float realGridSizeFP[DIM]; /*! \brief Real-space grid dimensions (padded). The padding as compared to realGridSize includes the (order - 1) overlap. */ - int realGridSizePadded[DIM]; /* Is major dimension of this ever used in kernels? */ + int realGridSizePadded[DIM]; /* Is major dimension of this ever used in kernels? */ /*! \brief Fourier grid dimensions. This counts the complex numbers! */ - int complexGridSize[DIM]; + int complexGridSize[DIM]; /*! \brief Fourier grid dimensions (padded). This counts the complex numbers! */ - int complexGridSizePadded[DIM]; + int complexGridSizePadded[DIM]; /*! \brief Offsets for X/Y/Z components of d_splineModuli */ - int splineValuesOffset[DIM]; + int splineValuesOffset[DIM]; /*! \brief Offsets for X/Y/Z components of d_fractShiftsTable and d_gridlineIndicesTable */ - int tablesOffsets[DIM]; + int tablesOffsets[DIM]; /* Grid arrays */ /*! \brief Real space grid. */ @@ -144,13 +146,13 @@ struct PmeGpuGridParams }; /*! \internal \brief - * A GPU data structure for storing the PME data of the atoms, local to this process' domain partition. - * This only has to be updated every DD step. + * A GPU data structure for storing the PME data of the atoms, local to this process' domain + * partition. This only has to be updated every DD step. */ struct PmeGpuAtomParams { /*! \brief Number of local atoms */ - int nAtoms; + int nAtoms; /*! \brief Global GPU memory array handle with input rvec atom coordinates. * The coordinates themselves change and need to be copied to the GPU for every PME computation, * but reallocation happens only at DD. @@ -161,8 +163,8 @@ struct PmeGpuAtomParams */ HIDE_FROM_OPENCL_COMPILER(DeviceBuffer) d_coefficients; /*! \brief Global GPU memory array handle with input/output rvec atom forces. - * The forces change and need to be copied from (and possibly to) the GPU for every PME computation, - * but reallocation happens only at DD. + * The forces change and need to be copied from (and possibly to) the GPU for every PME + * computation, but reallocation happens only at DD. */ HIDE_FROM_OPENCL_COMPILER(DeviceBuffer) d_forces; /*! \brief Global GPU memory array handle with ivec atom gridline indices. @@ -191,9 +193,9 @@ struct PmeGpuDynamicParams * Basically, spread uses matrix columns (while solve and gather use rows). * This storage format might be not the most optimal since the box is always triangular so there are zeroes. */ - float recipBox[DIM][DIM]; + float recipBox[DIM][DIM]; /*! \brief The unit cell volume for solving. */ - float boxVolume; + float boxVolume; }; /*! \internal \brief @@ -206,11 +208,11 @@ struct PmeGpuDynamicParams struct PmeGpuKernelParamsBase { /*! \brief Constant data that is set once. */ - struct PmeGpuConstParams constants; + struct PmeGpuConstParams constants; /*! \brief Data dependent on the grid size/cutoff. */ - struct PmeGpuGridParams grid; + struct PmeGpuGridParams grid; /*! \brief Data dependent on the DD and local atoms. */ - struct PmeGpuAtomParams atoms; + struct PmeGpuAtomParams atoms; /*! \brief Data that possibly changes for every new PME computation. * This should be kept up-to-date by calling pme_gpu_prepare_computation(...) * before launching spreading. diff --git a/src/gromacs/ewald/pme_gpu_types_host.h b/src/gromacs/ewald/pme_gpu_types_host.h index a35be1e884..3ffabeff31 100644 --- a/src/gromacs/ewald/pme_gpu_types_host.h +++ b/src/gromacs/ewald/pme_gpu_types_host.h @@ -56,7 +56,7 @@ #include "gromacs/ewald/pme.h" #include "gromacs/ewald/pme_gpu_program.h" #include "gromacs/gpu_utils/clfftinitializer.h" -#include "gromacs/gpu_utils/gpu_utils.h" // for GpuApiCallBehavior +#include "gromacs/gpu_utils/gpu_utils.h" // for GpuApiCallBehavior #include "gromacs/gpu_utils/hostallocator.h" #include "gromacs/math/vectypes.h" @@ -103,14 +103,14 @@ struct PmeGpuSettings */ bool useGpuForceReduction; - /*! \brief A boolean which tells if any PME GPU stage should copy all of its outputs to the host. - * Only intended to be used by the test framework. + /*! \brief A boolean which tells if any PME GPU stage should copy all of its outputs to the + * host. Only intended to be used by the test framework. */ - bool copyAllOutputs; + bool copyAllOutputs; /*! \brief An enum which tells whether most PME GPU D2H/H2D data transfers should be synchronous. */ GpuApiCallBehavior transferKind; /*! \brief Various flags for the current PME computation, corresponding to the GMX_PME_ flags in pme.h. */ - int currentFlags; + int currentFlags; }; // TODO There's little value in computing the Coulomb and LJ virial @@ -119,13 +119,13 @@ struct PmeGpuSettings // possible. Use mdspan? struct PmeOutput { - gmx::ArrayRef forces_; //!< Host staging area for PME forces - bool haveForceOutput_ = false; //!< True if forces have been staged other false (when forces are reduced on the GPU). - real coulombEnergy_ = 0; //!< Host staging area for PME coulomb energy - matrix coulombVirial_ = {{0}}; //!< Host staging area for PME coulomb virial contributions - real lennardJonesEnergy_ = 0; //!< Host staging area for PME LJ energy - matrix lennardJonesVirial_ = {{0}}; //!< Host staging area for PME LJ virial contributions - + gmx::ArrayRef forces_; //!< Host staging area for PME forces + bool haveForceOutput_ = + false; //!< True if forces have been staged other false (when forces are reduced on the GPU). + real coulombEnergy_ = 0; //!< Host staging area for PME coulomb energy + matrix coulombVirial_ = { { 0 } }; //!< Host staging area for PME coulomb virial contributions + real lennardJonesEnergy_ = 0; //!< Host staging area for PME LJ energy + matrix lennardJonesVirial_ = { { 0 } }; //!< Host staging area for PME LJ virial contributions }; /*! \internal \brief @@ -138,16 +138,16 @@ struct PmeGpuStaging gmx::PaddedHostVector h_forces; /*! \brief Virial and energy intermediate host-side buffer. Size is PME_GPU_VIRIAL_AND_ENERGY_COUNT. */ - float *h_virialAndEnergy; + float* h_virialAndEnergy; /*! \brief B-spline values intermediate host-side buffer. */ - float *h_splineModuli; + float* h_splineModuli; /*! \brief Pointer to the host memory with B-spline values. Only used for host-side gather, or unit tests */ - float *h_theta; + float* h_theta; /*! \brief Pointer to the host memory with B-spline derivative values. Only used for host-side gather, or unit tests */ - float *h_dtheta; + float* h_dtheta; /*! \brief Pointer to the host memory with ivec atom gridline indices. Only used for host-side gather, or unit tests */ - int *h_gridlineIndices; + int* h_gridlineIndices; }; /*! \internal \brief @@ -162,27 +162,27 @@ struct PmeGpuStaging struct PmeShared { /*! \brief Grid count - currently always 1 on GPU */ - int ngrids; + int ngrids; /*! \brief Grid dimensions - nkx, nky, nkz */ - int nk[DIM]; + int nk[DIM]; /*! \brief PME interpolation order */ - int pme_order; + int pme_order; /*! \brief Ewald splitting coefficient for Coulomb */ - real ewaldcoeff_q; + real ewaldcoeff_q; /*! \brief Electrostatics parameter */ - real epsilon_r; + real epsilon_r; /*! \brief Gridline indices - nnx, nny, nnz */ - std::vector nn; + std::vector nn; /*! \brief Fractional shifts - fshx, fshy, fshz */ - std::vector fsh; + std::vector fsh; /*! \brief Precomputed B-spline values */ - std::vector bsp_mod[DIM]; + std::vector bsp_mod[DIM]; /*! \brief The PME codepath being taken */ - PmeRunMode runMode; + PmeRunMode runMode; /*! \brief Whether PME execution is happening on a PME-only rank (from gmx_pme_t.bPPnode). */ - bool isRankPmeOnly; + bool isRankPmeOnly; /*! \brief The box scaler based on inputrec - created in pme_init and managed by CPU structure */ - class EwaldBoxZScaler *boxScaler; + class EwaldBoxZScaler* boxScaler; /*! \brief The previous computation box to know if we even need to update the current box params. * \todo Manage this on higher level. * \todo Alternatively, when this structure is used by CPU PME code, make use of this field there as well. @@ -229,7 +229,7 @@ struct PmeGpu int nAtomsAlloc; /*! \brief A pointer to the device used during the execution. */ - const gmx_device_info_t *deviceInfo; + const gmx_device_info_t* deviceInfo; /*! \brief Kernel scheduling grid width limit in X - derived from deviceinfo compute capability in CUDA. * Declared as very large int to make it useful in computations with type promotion, to avoid overflows. diff --git a/src/gromacs/ewald/pme_gpu_types_host_impl.h b/src/gromacs/ewald/pme_gpu_types_host_impl.h index b113fcba4e..be4f986957 100644 --- a/src/gromacs/ewald/pme_gpu_types_host_impl.h +++ b/src/gromacs/ewald/pme_gpu_types_host_impl.h @@ -51,11 +51,11 @@ #include #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/gpueventsynchronizer.cuh" -#include "gromacs/gpu_utils/gpuregiontimer.cuh" +# include "gromacs/gpu_utils/gpueventsynchronizer.cuh" +# include "gromacs/gpu_utils/gpuregiontimer.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gpueventsynchronizer_ocl.h" -#include "gromacs/gpu_utils/gpuregiontimer_ocl.h" +# include "gromacs/gpu_utils/gpueventsynchronizer_ocl.h" +# include "gromacs/gpu_utils/gpuregiontimer_ocl.h" #endif #include "gromacs/timing/gpu_timing.h" // for gtPME_EVENT_COUNT @@ -89,19 +89,19 @@ struct PmeGpuSpecific bool performOutOfPlaceFFT; /*! \brief A boolean which tells if the GPU timing events are enabled. * False by default, can be enabled by setting the environment variable GMX_ENABLE_GPU_TIMING. - * Note: will not be reliable when multiple GPU tasks are running concurrently on the same device context, - * as CUDA events on multiple streams are untrustworthy. + * Note: will not be reliable when multiple GPU tasks are running concurrently on the same + * device context, as CUDA events on multiple streams are untrustworthy. */ - bool useTiming; + bool useTiming; //! Vector of FFT setups - std::vector > fftSetup; + std::vector> fftSetup; //! All the timers one might use - std::array timingEvents; + std::array timingEvents; //! Indices of timingEvents actually used - std::set activeTimers; + std::set activeTimers; /* GPU arrays element counts (not the arrays sizes in bytes!). * They might be larger than the actual meaningful data sizes. diff --git a/src/gromacs/ewald/pme_gpu_utils.h b/src/gromacs/ewald/pme_gpu_utils.h index c706f071ec..9e4ca2a8bc 100644 --- a/src/gromacs/ewald/pme_gpu_utils.h +++ b/src/gromacs/ewald/pme_gpu_utils.h @@ -53,9 +53,9 @@ //! A macro for inline GPU functions. #if GMX_GPU == GMX_GPU_CUDA -#define INLINE_EVERYWHERE __host__ __device__ __forceinline__ +# define INLINE_EVERYWHERE __host__ __device__ __forceinline__ #else -#define INLINE_EVERYWHERE inline +# define INLINE_EVERYWHERE inline #endif /*! \internal \brief @@ -73,7 +73,7 @@ * * \returns Index into theta or dtheta array using GPU layout. */ -template +template int INLINE_EVERYWHERE getSplineParamIndexBase(int warpIndex, int atomWarpIndex) { assert((atomWarpIndex >= 0) && (atomWarpIndex < atomsPerWarp)); @@ -97,7 +97,7 @@ int INLINE_EVERYWHERE getSplineParamIndexBase(int warpIndex, int atomWarpIndex) * * \returns Index into theta or dtheta array using GPU layout. */ -template +template int INLINE_EVERYWHERE getSplineParamIndex(int paramIndexBase, int dimIndex, int splineIndex) { assert((dimIndex >= XX) && (dimIndex < DIM)); diff --git a/src/gromacs/ewald/pme_grid.cpp b/src/gromacs/ewald/pme_grid.cpp index a3e42e9c63..ab759f30de 100644 --- a/src/gromacs/ewald/pme_grid.cpp +++ b/src/gromacs/ewald/pme_grid.cpp @@ -53,9 +53,9 @@ #include "pme_internal.h" #ifdef DEBUG_PME -#include "gromacs/fileio/pdbio.h" -#include "gromacs/utility/cstringutil.h" -#include "gromacs/utility/futil.h" +# include "gromacs/fileio/pdbio.h" +# include "gromacs/utility/cstringutil.h" +# include "gromacs/utility/futil.h" #endif #include "pme_simd.h" @@ -65,19 +65,17 @@ */ #define GMX_CACHE_SEP 64 -void gmx_sum_qgrid_dd(gmx_pme_t *pme, - real *grid, - const int direction) +void gmx_sum_qgrid_dd(gmx_pme_t* pme, real* grid, const int direction) { #if GMX_MPI - pme_overlap_t *overlap; + pme_overlap_t* overlap; int send_index0, send_nindex; int recv_index0, recv_nindex; MPI_Status stat; int i, j, k, ix, iy, iz, icnt; int send_id, recv_id, datasize; - real *p; - real *sendptr, *recvptr; + real* p; + real * sendptr, *recvptr; /* Start with minor-rank communication. This is a bit of a pain since it is not contiguous */ overlap = &pme->overlap[1]; @@ -89,31 +87,30 @@ void gmx_sum_qgrid_dd(gmx_pme_t *pme, */ if (direction == GMX_SUM_GRID_FORWARD) { - send_id = overlap->comm_data[ipulse].send_id; - recv_id = overlap->comm_data[ipulse].recv_id; - send_index0 = overlap->comm_data[ipulse].send_index0; - send_nindex = overlap->comm_data[ipulse].send_nindex; - recv_index0 = overlap->comm_data[ipulse].recv_index0; - recv_nindex = overlap->comm_data[ipulse].recv_nindex; + send_id = overlap->comm_data[ipulse].send_id; + recv_id = overlap->comm_data[ipulse].recv_id; + send_index0 = overlap->comm_data[ipulse].send_index0; + send_nindex = overlap->comm_data[ipulse].send_nindex; + recv_index0 = overlap->comm_data[ipulse].recv_index0; + recv_nindex = overlap->comm_data[ipulse].recv_nindex; } else { - send_id = overlap->comm_data[ipulse].recv_id; - recv_id = overlap->comm_data[ipulse].send_id; - send_index0 = overlap->comm_data[ipulse].recv_index0; - send_nindex = overlap->comm_data[ipulse].recv_nindex; - recv_index0 = overlap->comm_data[ipulse].send_index0; - recv_nindex = overlap->comm_data[ipulse].send_nindex; + send_id = overlap->comm_data[ipulse].recv_id; + recv_id = overlap->comm_data[ipulse].send_id; + send_index0 = overlap->comm_data[ipulse].recv_index0; + send_nindex = overlap->comm_data[ipulse].recv_nindex; + recv_index0 = overlap->comm_data[ipulse].send_index0; + recv_nindex = overlap->comm_data[ipulse].send_nindex; } /* Copy data to contiguous send buffer */ if (debug) { fprintf(debug, "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n", - pme->nodeid, overlap->nodeid, send_id, - pme->pmegrid_start_iy, - send_index0-pme->pmegrid_start_iy, - send_index0-pme->pmegrid_start_iy+send_nindex); + pme->nodeid, overlap->nodeid, send_id, pme->pmegrid_start_iy, + send_index0 - pme->pmegrid_start_iy, + send_index0 - pme->pmegrid_start_iy + send_nindex); } icnt = 0; for (i = 0; i < pme->pmegrid_nx; i++) @@ -125,27 +122,25 @@ void gmx_sum_qgrid_dd(gmx_pme_t *pme, for (k = 0; k < pme->nkz; k++) { iz = k; - overlap->sendbuf[icnt++] = grid[ix*(pme->pmegrid_ny*pme->pmegrid_nz)+iy*(pme->pmegrid_nz)+iz]; + overlap->sendbuf[icnt++] = + grid[ix * (pme->pmegrid_ny * pme->pmegrid_nz) + iy * (pme->pmegrid_nz) + iz]; } } } - datasize = pme->pmegrid_nx * pme->nkz; + datasize = pme->pmegrid_nx * pme->nkz; - MPI_Sendrecv(overlap->sendbuf.data(), send_nindex*datasize, GMX_MPI_REAL, - send_id, ipulse, - overlap->recvbuf.data(), recv_nindex*datasize, GMX_MPI_REAL, - recv_id, ipulse, + MPI_Sendrecv(overlap->sendbuf.data(), send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse, + overlap->recvbuf.data(), recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat); /* Get data from contiguous recv buffer */ if (debug) { fprintf(debug, "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n", - pme->nodeid, overlap->nodeid, recv_id, - pme->pmegrid_start_iy, - recv_index0-pme->pmegrid_start_iy, - recv_index0-pme->pmegrid_start_iy+recv_nindex); + pme->nodeid, overlap->nodeid, recv_id, pme->pmegrid_start_iy, + recv_index0 - pme->pmegrid_start_iy, + recv_index0 - pme->pmegrid_start_iy + recv_nindex); } icnt = 0; for (i = 0; i < pme->pmegrid_nx; i++) @@ -159,11 +154,13 @@ void gmx_sum_qgrid_dd(gmx_pme_t *pme, iz = k; if (direction == GMX_SUM_GRID_FORWARD) { - grid[ix*(pme->pmegrid_ny*pme->pmegrid_nz)+iy*(pme->pmegrid_nz)+iz] += overlap->recvbuf[icnt++]; + grid[ix * (pme->pmegrid_ny * pme->pmegrid_nz) + iy * (pme->pmegrid_nz) + iz] += + overlap->recvbuf[icnt++]; } else { - grid[ix*(pme->pmegrid_ny*pme->pmegrid_nz)+iy*(pme->pmegrid_nz)+iz] = overlap->recvbuf[icnt++]; + grid[ix * (pme->pmegrid_ny * pme->pmegrid_nz) + iy * (pme->pmegrid_nz) + iz] = + overlap->recvbuf[icnt++]; } } } @@ -181,53 +178,48 @@ void gmx_sum_qgrid_dd(gmx_pme_t *pme, { if (direction == GMX_SUM_GRID_FORWARD) { - send_id = overlap->comm_data[ipulse].send_id; - recv_id = overlap->comm_data[ipulse].recv_id; - send_index0 = overlap->comm_data[ipulse].send_index0; - send_nindex = overlap->comm_data[ipulse].send_nindex; - recv_index0 = overlap->comm_data[ipulse].recv_index0; - recv_nindex = overlap->comm_data[ipulse].recv_nindex; - recvptr = overlap->recvbuf.data(); + send_id = overlap->comm_data[ipulse].send_id; + recv_id = overlap->comm_data[ipulse].recv_id; + send_index0 = overlap->comm_data[ipulse].send_index0; + send_nindex = overlap->comm_data[ipulse].send_nindex; + recv_index0 = overlap->comm_data[ipulse].recv_index0; + recv_nindex = overlap->comm_data[ipulse].recv_nindex; + recvptr = overlap->recvbuf.data(); } else { - send_id = overlap->comm_data[ipulse].recv_id; - recv_id = overlap->comm_data[ipulse].send_id; - send_index0 = overlap->comm_data[ipulse].recv_index0; - send_nindex = overlap->comm_data[ipulse].recv_nindex; - recv_index0 = overlap->comm_data[ipulse].send_index0; - recv_nindex = overlap->comm_data[ipulse].send_nindex; - recvptr = grid + (recv_index0-pme->pmegrid_start_ix)*(pme->pmegrid_ny*pme->pmegrid_nz); + send_id = overlap->comm_data[ipulse].recv_id; + recv_id = overlap->comm_data[ipulse].send_id; + send_index0 = overlap->comm_data[ipulse].recv_index0; + send_nindex = overlap->comm_data[ipulse].recv_nindex; + recv_index0 = overlap->comm_data[ipulse].send_index0; + recv_nindex = overlap->comm_data[ipulse].send_nindex; + recvptr = grid + (recv_index0 - pme->pmegrid_start_ix) * (pme->pmegrid_ny * pme->pmegrid_nz); } - sendptr = grid + (send_index0-pme->pmegrid_start_ix)*(pme->pmegrid_ny*pme->pmegrid_nz); - datasize = pme->pmegrid_ny * pme->pmegrid_nz; + sendptr = grid + (send_index0 - pme->pmegrid_start_ix) * (pme->pmegrid_ny * pme->pmegrid_nz); + datasize = pme->pmegrid_ny * pme->pmegrid_nz; if (debug) { fprintf(debug, "PME send rank %d %d -> %d grid start %d Communicating %d to %d\n", - pme->nodeid, overlap->nodeid, send_id, - pme->pmegrid_start_ix, - send_index0-pme->pmegrid_start_ix, - send_index0-pme->pmegrid_start_ix+send_nindex); + pme->nodeid, overlap->nodeid, send_id, pme->pmegrid_start_ix, + send_index0 - pme->pmegrid_start_ix, + send_index0 - pme->pmegrid_start_ix + send_nindex); fprintf(debug, "PME recv rank %d %d <- %d grid start %d Communicating %d to %d\n", - pme->nodeid, overlap->nodeid, recv_id, - pme->pmegrid_start_ix, - recv_index0-pme->pmegrid_start_ix, - recv_index0-pme->pmegrid_start_ix+recv_nindex); + pme->nodeid, overlap->nodeid, recv_id, pme->pmegrid_start_ix, + recv_index0 - pme->pmegrid_start_ix, + recv_index0 - pme->pmegrid_start_ix + recv_nindex); } - MPI_Sendrecv(sendptr, send_nindex*datasize, GMX_MPI_REAL, - send_id, ipulse, - recvptr, recv_nindex*datasize, GMX_MPI_REAL, - recv_id, ipulse, - overlap->mpi_comm, &stat); + MPI_Sendrecv(sendptr, send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr, + recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat); /* ADD data from contiguous recv buffer */ if (direction == GMX_SUM_GRID_FORWARD) { - p = grid + (recv_index0-pme->pmegrid_start_ix)*(pme->pmegrid_ny*pme->pmegrid_nz); - for (i = 0; i < recv_nindex*datasize; i++) + p = grid + (recv_index0 - pme->pmegrid_start_ix) * (pme->pmegrid_ny * pme->pmegrid_nz); + for (i = 0; i < recv_nindex * datasize; i++) { p[i] += overlap->recvbuf[i]; } @@ -243,17 +235,15 @@ void gmx_sum_qgrid_dd(gmx_pme_t *pme, } -int copy_pmegrid_to_fftgrid(const gmx_pme_t *pme, const real *pmegrid, real *fftgrid, int grid_index) +int copy_pmegrid_to_fftgrid(const gmx_pme_t* pme, const real* pmegrid, real* fftgrid, int grid_index) { - ivec local_fft_ndata, local_fft_offset, local_fft_size; - ivec local_pme_size; - int ix, iy, iz; - int pmeidx, fftidx; + ivec local_fft_ndata, local_fft_offset, local_fft_size; + ivec local_pme_size; + int ix, iy, iz; + int pmeidx, fftidx; /* Dimensions should be identical for A/B grid, so we just use A here */ - gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], - local_fft_ndata, - local_fft_offset, + gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size); local_pme_size[0] = pme->pmegrid_nx; @@ -280,24 +270,23 @@ int copy_pmegrid_to_fftgrid(const gmx_pme_t *pme, const real *pmegrid, real *fft { for (iz = 0; iz < local_fft_ndata[ZZ]; iz++) { - pmeidx = ix*(local_pme_size[YY]*local_pme_size[ZZ])+iy*(local_pme_size[ZZ])+iz; - fftidx = ix*(local_fft_size[YY]*local_fft_size[ZZ])+iy*(local_fft_size[ZZ])+iz; + pmeidx = ix * (local_pme_size[YY] * local_pme_size[ZZ]) + + iy * (local_pme_size[ZZ]) + iz; + fftidx = ix * (local_fft_size[YY] * local_fft_size[ZZ]) + + iy * (local_fft_size[ZZ]) + iz; fftgrid[fftidx] = pmegrid[pmeidx]; #ifdef DEBUG_PME - val = 100*pmegrid[pmeidx]; + val = 100 * pmegrid[pmeidx]; if (pmegrid[pmeidx] != 0) { - gmx_fprintf_pdb_atomline(fp, epdbATOM, pmeidx, "CA", ' ', "GLY", ' ', pmeidx, ' ', - 5.0*ix, 5.0*iy, 5.0*iz, 1.0, val, ""); + gmx_fprintf_pdb_atomline(fp, epdbATOM, pmeidx, "CA", ' ', "GLY", ' ', pmeidx, + ' ', 5.0 * ix, 5.0 * iy, 5.0 * iz, 1.0, val, ""); } if (pmegrid[pmeidx] != 0) { - fprintf(fp2, "%-12s %5d %5d %5d %12.5e\n", - "qgrid", - pme->pmegrid_start_ix + ix, - pme->pmegrid_start_iy + iy, - pme->pmegrid_start_iz + iz, - pmegrid[pmeidx]); + fprintf(fp2, "%-12s %5d %5d %5d %12.5e\n", "qgrid", + pme->pmegrid_start_ix + ix, pme->pmegrid_start_iy + iy, + pme->pmegrid_start_iz + iz, pmegrid[pmeidx]); } #endif } @@ -325,13 +314,12 @@ static gmx_cycles_t omp_cyc_end(gmx_cycles_t c) #endif -int copy_fftgrid_to_pmegrid(struct gmx_pme_t *pme, const real *fftgrid, real *pmegrid, int grid_index, - int nthread, int thread) +int copy_fftgrid_to_pmegrid(struct gmx_pme_t* pme, const real* fftgrid, real* pmegrid, int grid_index, int nthread, int thread) { - ivec local_fft_ndata, local_fft_offset, local_fft_size; - ivec local_pme_size; - int ixy0, ixy1, ixy, ix, iy, iz; - int pmeidx, fftidx; + ivec local_fft_ndata, local_fft_offset, local_fft_size; + ivec local_pme_size; + int ixy0, ixy1, ixy, ix, iy, iz; + int pmeidx, fftidx; #ifdef PME_TIME_THREADS gmx_cycles_t c1; static double cs1 = 0; @@ -342,9 +330,7 @@ int copy_fftgrid_to_pmegrid(struct gmx_pme_t *pme, const real *fftgrid, real *pm c1 = omp_cyc_start(); #endif /* Dimensions should be identical for A/B grid, so we just use A here */ - gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], - local_fft_ndata, - local_fft_offset, + gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size); local_pme_size[0] = pme->pmegrid_nx; @@ -354,29 +340,29 @@ int copy_fftgrid_to_pmegrid(struct gmx_pme_t *pme, const real *fftgrid, real *pm /* The fftgrid is always 'justified' to the lower-left corner of the PME grid, the offset is identical, and the PME grid always has more data (due to overlap) */ - ixy0 = ((thread )*local_fft_ndata[XX]*local_fft_ndata[YY])/nthread; - ixy1 = ((thread+1)*local_fft_ndata[XX]*local_fft_ndata[YY])/nthread; + ixy0 = ((thread)*local_fft_ndata[XX] * local_fft_ndata[YY]) / nthread; + ixy1 = ((thread + 1) * local_fft_ndata[XX] * local_fft_ndata[YY]) / nthread; for (ixy = ixy0; ixy < ixy1; ixy++) { - ix = ixy/local_fft_ndata[YY]; - iy = ixy - ix*local_fft_ndata[YY]; + ix = ixy / local_fft_ndata[YY]; + iy = ixy - ix * local_fft_ndata[YY]; - pmeidx = (ix*local_pme_size[YY] + iy)*local_pme_size[ZZ]; - fftidx = (ix*local_fft_size[YY] + iy)*local_fft_size[ZZ]; + pmeidx = (ix * local_pme_size[YY] + iy) * local_pme_size[ZZ]; + fftidx = (ix * local_fft_size[YY] + iy) * local_fft_size[ZZ]; for (iz = 0; iz < local_fft_ndata[ZZ]; iz++) { - pmegrid[pmeidx+iz] = fftgrid[fftidx+iz]; + pmegrid[pmeidx + iz] = fftgrid[fftidx + iz]; } } #ifdef PME_TIME_THREADS - c1 = omp_cyc_end(c1); + c1 = omp_cyc_end(c1); cs1 += (double)c1; cnt++; if (cnt % 20 == 0) { - printf("copy %.2f\n", cs1*1e-9); + printf("copy %.2f\n", cs1 * 1e-9); } #endif @@ -384,9 +370,9 @@ int copy_fftgrid_to_pmegrid(struct gmx_pme_t *pme, const real *fftgrid, real *pm } -void wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid) +void wrap_periodic_pmegrid(const gmx_pme_t* pme, real* pmegrid) { - int nx, ny, nz, pny, pnz, ny_x, overlap, ix, iy, iz; + int nx, ny, nz, pny, pnz, ny_x, overlap, ix, iy, iz; nx = pme->nkx; ny = pme->nky; @@ -404,8 +390,7 @@ void wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < overlap; iz++) { - pmegrid[(ix*pny+iy)*pnz+iz] += - pmegrid[(ix*pny+iy)*pnz+nz+iz]; + pmegrid[(ix * pny + iy) * pnz + iz] += pmegrid[(ix * pny + iy) * pnz + nz + iz]; } } } @@ -418,8 +403,7 @@ void wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < nz; iz++) { - pmegrid[(ix*pny+iy)*pnz+iz] += - pmegrid[(ix*pny+ny+iy)*pnz+iz]; + pmegrid[(ix * pny + iy) * pnz + iz] += pmegrid[(ix * pny + ny + iy) * pnz + iz]; } } } @@ -435,8 +419,7 @@ void wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < nz; iz++) { - pmegrid[(ix*pny+iy)*pnz+iz] += - pmegrid[((nx+ix)*pny+iy)*pnz+iz]; + pmegrid[(ix * pny + iy) * pnz + iz] += pmegrid[((nx + ix) * pny + iy) * pnz + iz]; } } } @@ -444,9 +427,9 @@ void wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid) } -void unwrap_periodic_pmegrid(struct gmx_pme_t *pme, real *pmegrid) +void unwrap_periodic_pmegrid(struct gmx_pme_t* pme, real* pmegrid) { - int nx, ny, nz, pny, pnz, ny_x, overlap, ix; + int nx, ny, nz, pny, pnz, ny_x, overlap, ix; nx = pme->nkx; ny = pme->nky; @@ -469,8 +452,7 @@ void unwrap_periodic_pmegrid(struct gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < nz; iz++) { - pmegrid[((nx+ix)*pny+iy)*pnz+iz] = - pmegrid[(ix*pny+iy)*pnz+iz]; + pmegrid[((nx + ix) * pny + iy) * pnz + iz] = pmegrid[(ix * pny + iy) * pnz + iz]; } } } @@ -488,8 +470,7 @@ void unwrap_periodic_pmegrid(struct gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < nz; iz++) { - pmegrid[(ix*pny+ny+iy)*pnz+iz] = - pmegrid[(ix*pny+iy)*pnz+iz]; + pmegrid[(ix * pny + ny + iy) * pnz + iz] = pmegrid[(ix * pny + iy) * pnz + iz]; } } } @@ -506,21 +487,20 @@ void unwrap_periodic_pmegrid(struct gmx_pme_t *pme, real *pmegrid) { for (iz = 0; iz < overlap; iz++) { - pmegrid[(ix*pny+iy)*pnz+nz+iz] = - pmegrid[(ix*pny+iy)*pnz+iz]; + pmegrid[(ix * pny + iy) * pnz + nz + iz] = pmegrid[(ix * pny + iy) * pnz + iz]; } } } } -void set_grid_alignment(int gmx_unused *pmegrid_nz, int gmx_unused pme_order) +void set_grid_alignment(int gmx_unused* pmegrid_nz, int gmx_unused pme_order) { #ifdef PME_SIMD4_SPREAD_GATHER if (pme_order == 5 -#if !PME_4NSIMD_GATHER +# if !PME_4NSIMD_GATHER || pme_order == 4 -#endif - ) +# endif + ) { /* Round nz up to a multiple of 4 to ensure alignment */ *pmegrid_nz = ((*pmegrid_nz + 3) & ~3); @@ -528,10 +508,10 @@ void set_grid_alignment(int gmx_unused *pmegrid_nz, int gmx_unused pme_order) #endif } -static void set_gridsize_alignment(int gmx_unused *gridsize, int gmx_unused pme_order) +static void set_gridsize_alignment(int gmx_unused* gridsize, int gmx_unused pme_order) { #ifdef PME_SIMD4_SPREAD_GATHER -#if !PME_4NSIMD_GATHER +# if !PME_4NSIMD_GATHER if (pme_order == 4) { /* Add extra elements to ensured aligned operations do not go @@ -541,17 +521,23 @@ static void set_gridsize_alignment(int gmx_unused *gridsize, int gmx_unused pme_ */ *gridsize += 4; } -#endif +# endif #endif } -void pmegrid_init(pmegrid_t *grid, - int cx, int cy, int cz, - int x0, int y0, int z0, - int x1, int y1, int z1, - gmx_bool set_alignment, - int pme_order, - real *ptr) +void pmegrid_init(pmegrid_t* grid, + int cx, + int cy, + int cz, + int x0, + int y0, + int z0, + int x1, + int y1, + int z1, + gmx_bool set_alignment, + int pme_order, + real* ptr) { int nz, gridsize; @@ -580,7 +566,7 @@ void pmegrid_init(pmegrid_t *grid, grid->order = pme_order; if (ptr == nullptr) { - gridsize = grid->s[XX]*grid->s[YY]*grid->s[ZZ]; + gridsize = grid->s[XX] * grid->s[YY] * grid->s[ZZ]; set_gridsize_alignment(&gridsize, pme_order); snew_aligned(grid->grid, gridsize, SIMD4_ALIGNMENT); } @@ -592,15 +578,14 @@ void pmegrid_init(pmegrid_t *grid, static int div_round_up(int enumerator, int denominator) { - return (enumerator + denominator - 1)/denominator; + return (enumerator + denominator - 1) / denominator; } -static void make_subgrid_division(const ivec n, int ovl, int nthread, - ivec nsub) +static void make_subgrid_division(const ivec n, int ovl, int nthread, ivec nsub) { int gsize_opt, gsize; int nsx, nsy, nsz; - char *env; + char* env; gsize_opt = -1; for (nsx = 1; nsx <= nthread; nsx++) @@ -609,23 +594,19 @@ static void make_subgrid_division(const ivec n, int ovl, int nthread, { for (nsy = 1; nsy <= nthread; nsy++) { - if (nsx*nsy <= nthread && nthread % (nsx*nsy) == 0) + if (nsx * nsy <= nthread && nthread % (nsx * nsy) == 0) { - nsz = nthread/(nsx*nsy); + nsz = nthread / (nsx * nsy); /* Determine the number of grid points per thread */ - gsize = - (div_round_up(n[XX], nsx) + ovl)* - (div_round_up(n[YY], nsy) + ovl)* - (div_round_up(n[ZZ], nsz) + ovl); + gsize = (div_round_up(n[XX], nsx) + ovl) * (div_round_up(n[YY], nsy) + ovl) + * (div_round_up(n[ZZ], nsz) + ovl); /* Minimize the number of grids points per thread * and, secondarily, the number of cuts in minor dimensions. */ - if (gsize_opt == -1 || - gsize < gsize_opt || - (gsize == gsize_opt && - (nsz < nsub[ZZ] || (nsz == nsub[ZZ] && nsy < nsub[YY])))) + if (gsize_opt == -1 || gsize < gsize_opt + || (gsize == gsize_opt && (nsz < nsub[ZZ] || (nsz == nsub[ZZ] && nsy < nsub[YY])))) { nsub[XX] = nsx; nsub[YY] = nsy; @@ -643,19 +624,25 @@ static void make_subgrid_division(const ivec n, int ovl, int nthread, sscanf(env, "%20d %20d %20d", &nsub[XX], &nsub[YY], &nsub[ZZ]); } - if (nsub[XX]*nsub[YY]*nsub[ZZ] != nthread) + if (nsub[XX] * nsub[YY] * nsub[ZZ] != nthread) { - gmx_fatal(FARGS, "PME grid thread division (%d x %d x %d) does not match the total number of threads (%d)", nsub[XX], nsub[YY], nsub[ZZ], nthread); + gmx_fatal(FARGS, + "PME grid thread division (%d x %d x %d) does not match the total number of " + "threads (%d)", + nsub[XX], nsub[YY], nsub[ZZ], nthread); } } -void pmegrids_init(pmegrids_t *grids, - int nx, int ny, int nz, int nz_base, - int pme_order, - gmx_bool bUseThreads, - int nthread, - int overlap_x, - int overlap_y) +void pmegrids_init(pmegrids_t* grids, + int nx, + int ny, + int nz, + int nz_base, + int pme_order, + gmx_bool bUseThreads, + int nthread, + int overlap_x, + int overlap_y) { ivec n, n_base; int t, x, y, z, d, i, tfac; @@ -668,12 +655,11 @@ void pmegrids_init(pmegrids_t *grids, copy_ivec(n, n_base); n_base[ZZ] = nz_base; - pmegrid_init(&grids->grid, 0, 0, 0, 0, 0, 0, n[XX], n[YY], n[ZZ], FALSE, pme_order, - nullptr); + pmegrid_init(&grids->grid, 0, 0, 0, 0, 0, 0, n[XX], n[YY], n[ZZ], FALSE, pme_order, nullptr); grids->nthread = nthread; - make_subgrid_division(n_base, pme_order-1, grids->nthread, grids->nc); + make_subgrid_division(n_base, pme_order - 1, grids->nthread, grids->nc); if (bUseThreads) { @@ -688,19 +674,17 @@ void pmegrids_init(pmegrids_t *grids, if (debug) { - fprintf(debug, "pmegrid thread local division: %d x %d x %d\n", - grids->nc[XX], grids->nc[YY], grids->nc[ZZ]); - fprintf(debug, "pmegrid %d %d %d max thread pmegrid %d %d %d\n", - nx, ny, nz, - nst[XX], nst[YY], nst[ZZ]); + fprintf(debug, "pmegrid thread local division: %d x %d x %d\n", grids->nc[XX], + grids->nc[YY], grids->nc[ZZ]); + fprintf(debug, "pmegrid %d %d %d max thread pmegrid %d %d %d\n", nx, ny, nz, nst[XX], + nst[YY], nst[ZZ]); } snew(grids->grid_th, grids->nthread); t = 0; - gridsize = nst[XX]*nst[YY]*nst[ZZ]; + gridsize = nst[XX] * nst[YY] * nst[ZZ]; set_gridsize_alignment(&gridsize, pme_order); - snew_aligned(grids->grid_all, - grids->nthread*gridsize+(grids->nthread+1)*GMX_CACHE_SEP, + snew_aligned(grids->grid_all, grids->nthread * gridsize + (grids->nthread + 1) * GMX_CACHE_SEP, SIMD4_ALIGNMENT); for (x = 0; x < grids->nc[XX]; x++) @@ -709,17 +693,11 @@ void pmegrids_init(pmegrids_t *grids, { for (z = 0; z < grids->nc[ZZ]; z++) { - pmegrid_init(&grids->grid_th[t], - x, y, z, - (n[XX]*(x ))/grids->nc[XX], - (n[YY]*(y ))/grids->nc[YY], - (n[ZZ]*(z ))/grids->nc[ZZ], - (n[XX]*(x+1))/grids->nc[XX], - (n[YY]*(y+1))/grids->nc[YY], - (n[ZZ]*(z+1))/grids->nc[ZZ], - TRUE, - pme_order, - grids->grid_all+GMX_CACHE_SEP+t*(gridsize+GMX_CACHE_SEP)); + pmegrid_init(&grids->grid_th[t], x, y, z, (n[XX] * (x)) / grids->nc[XX], + (n[YY] * (y)) / grids->nc[YY], (n[ZZ] * (z)) / grids->nc[ZZ], + (n[XX] * (x + 1)) / grids->nc[XX], (n[YY] * (y + 1)) / grids->nc[YY], + (n[ZZ] * (z + 1)) / grids->nc[ZZ], TRUE, pme_order, + grids->grid_all + GMX_CACHE_SEP + t * (gridsize + GMX_CACHE_SEP)); t++; } } @@ -731,7 +709,7 @@ void pmegrids_init(pmegrids_t *grids, } tfac = 1; - for (d = DIM-1; d >= 0; d--) + for (d = DIM - 1; d >= 0; d--) { snew(grids->g2t[d], n[d]); t = 0; @@ -740,43 +718,46 @@ void pmegrids_init(pmegrids_t *grids, /* The second check should match the parameters * of the pmegrid_init call above. */ - while (t + 1 < grids->nc[d] && i >= (n[d]*(t+1))/grids->nc[d]) + while (t + 1 < grids->nc[d] && i >= (n[d] * (t + 1)) / grids->nc[d]) { t++; } - grids->g2t[d][i] = t*tfac; + grids->g2t[d][i] = t * tfac; } tfac *= grids->nc[d]; switch (d) { - case XX: max_comm_lines = overlap_x; break; - case YY: max_comm_lines = overlap_y; break; + case XX: max_comm_lines = overlap_x; break; + case YY: max_comm_lines = overlap_y; break; case ZZ: max_comm_lines = pme_order - 1; break; } grids->nthread_comm[d] = 0; - while ((n[d]*grids->nthread_comm[d])/grids->nc[d] < max_comm_lines && - grids->nthread_comm[d] < grids->nc[d]) + while ((n[d] * grids->nthread_comm[d]) / grids->nc[d] < max_comm_lines + && grids->nthread_comm[d] < grids->nc[d]) { grids->nthread_comm[d]++; } if (debug != nullptr) { - fprintf(debug, "pmegrid thread grid communication range in %c: %d\n", - 'x'+d, grids->nthread_comm[d]); + fprintf(debug, "pmegrid thread grid communication range in %c: %d\n", 'x' + d, + grids->nthread_comm[d]); } /* It should be possible to make grids->nthread_comm[d]==grids->nc[d] * work, but this is not a problematic restriction. */ if (grids->nc[d] > 1 && grids->nthread_comm[d] > grids->nc[d]) { - gmx_fatal(FARGS, "Too many threads for PME (%d) compared to the number of grid lines, reduce the number of threads doing PME", grids->nthread); + gmx_fatal(FARGS, + "Too many threads for PME (%d) compared to the number of grid lines, reduce " + "the number of threads doing PME", + grids->nthread); } } } -void pmegrids_destroy(pmegrids_t *grids) +void pmegrids_destroy(pmegrids_t* grids) { if (grids->grid.grid != nullptr) { @@ -794,10 +775,7 @@ void pmegrids_destroy(pmegrids_t *grids) } } -void -make_gridindex_to_localindex(int n, int local_start, int local_range, - int **global_to_local, - real **fraction_shift) +void make_gridindex_to_localindex(int n, int local_start, int local_range, int** global_to_local, real** fraction_shift) { /* Here we construct array for looking up the grid line index and * fraction for particles. This is done because it is slighlty @@ -807,8 +785,8 @@ make_gridindex_to_localindex(int n, int local_start, int local_range, * to allow for particles to be out of the triclinic unit-cell. */ const int arraySize = c_pmeNeighborUnitcellCount * n; - int * gtl; - real * fsh; + int* gtl; + real* fsh; snew(gtl, arraySize); snew(fsh, arraySize); @@ -855,7 +833,7 @@ make_gridindex_to_localindex(int n, int local_start, int local_range, *fraction_shift = fsh; } -void reuse_pmegrids(const pmegrids_t *oldgrid, pmegrids_t *newgrid) +void reuse_pmegrids(const pmegrids_t* oldgrid, pmegrids_t* newgrid) { int d, t; diff --git a/src/gromacs/ewald/pme_grid.h b/src/gromacs/ewald/pme_grid.h index d14f84cb30..99dca07d43 100644 --- a/src/gromacs/ewald/pme_grid.h +++ b/src/gromacs/ewald/pme_grid.h @@ -51,57 +51,52 @@ constexpr int c_pmeMaxUnitcellShift = 2; * This affects the size of the lookup table of the modulo operation result, * when working with PME local grid indices of the particles. */ -constexpr int c_pmeNeighborUnitcellCount = 2*c_pmeMaxUnitcellShift + 1; +constexpr int c_pmeNeighborUnitcellCount = 2 * c_pmeMaxUnitcellShift + 1; struct pmegrid_t; struct pmegrids_t; -void -gmx_sum_qgrid_dd(gmx_pme_t *pme, real *grid, int direction); - -int -copy_pmegrid_to_fftgrid(const gmx_pme_t *pme, const real *pmegrid, real *fftgrid, int grid_index); - -int -copy_fftgrid_to_pmegrid(gmx_pme_t *pme, const real *fftgrid, real *pmegrid, int grid_index, - int nthread, int thread); - -void -wrap_periodic_pmegrid(const gmx_pme_t *pme, real *pmegrid); - -void -unwrap_periodic_pmegrid(gmx_pme_t *pme, real *pmegrid); - -void -pmegrid_init(pmegrid_t *grid, - int cx, int cy, int cz, - int x0, int y0, int z0, - int x1, int y1, int z1, - gmx_bool set_alignment, - int pme_order, - real *ptr); - -void -pmegrids_init(pmegrids_t *grids, - int nx, int ny, int nz, int nz_base, - int pme_order, - gmx_bool bUseThreads, - int nthread, - int overlap_x, - int overlap_y); - -void -pmegrids_destroy(pmegrids_t *grids); - -void -make_gridindex_to_localindex(int n, int local_start, int local_range, - int **global_to_local, - real **fraction_shift); - -void -set_grid_alignment(int *pmegrid_nz, int pme_order); - -void -reuse_pmegrids(const pmegrids_t *oldgrid, pmegrids_t *newgrid); +void gmx_sum_qgrid_dd(gmx_pme_t* pme, real* grid, int direction); + +int copy_pmegrid_to_fftgrid(const gmx_pme_t* pme, const real* pmegrid, real* fftgrid, int grid_index); + +int copy_fftgrid_to_pmegrid(gmx_pme_t* pme, const real* fftgrid, real* pmegrid, int grid_index, int nthread, int thread); + +void wrap_periodic_pmegrid(const gmx_pme_t* pme, real* pmegrid); + +void unwrap_periodic_pmegrid(gmx_pme_t* pme, real* pmegrid); + +void pmegrid_init(pmegrid_t* grid, + int cx, + int cy, + int cz, + int x0, + int y0, + int z0, + int x1, + int y1, + int z1, + gmx_bool set_alignment, + int pme_order, + real* ptr); + +void pmegrids_init(pmegrids_t* grids, + int nx, + int ny, + int nz, + int nz_base, + int pme_order, + gmx_bool bUseThreads, + int nthread, + int overlap_x, + int overlap_y); + +void pmegrids_destroy(pmegrids_t* grids); + +void make_gridindex_to_localindex(int n, int local_start, int local_range, int** global_to_local, real** fraction_shift); + +void set_grid_alignment(int* pmegrid_nz, int pme_order); + +void reuse_pmegrids(const pmegrids_t* oldgrid, pmegrids_t* newgrid); #endif diff --git a/src/gromacs/ewald/pme_internal.h b/src/gromacs/ewald/pme_internal.h index ee88e0ed28..028cd90e99 100644 --- a/src/gromacs/ewald/pme_internal.h +++ b/src/gromacs/ewald/pme_internal.h @@ -64,7 +64,7 @@ #include "pme_gpu_types_host.h" //! A repeat of typedef from parallel_3dfft.h -typedef struct gmx_parallel_3dfft *gmx_parallel_3dfft_t; +typedef struct gmx_parallel_3dfft* gmx_parallel_3dfft_t; struct t_commrec; struct t_inputrec; @@ -72,25 +72,23 @@ struct PmeGpu; //@{ //! Grid indices for A state for charge and Lennard-Jones C6 -#define PME_GRID_QA 0 -#define PME_GRID_C6A 2 +#define PME_GRID_QA 0 +#define PME_GRID_C6A 2 //@} //@{ /*! \brief Flags that indicate the number of PME grids in use */ -#define DO_Q 2 /* Electrostatic grids have index q<2 */ -#define DO_Q_AND_LJ 4 /* non-LB LJ grids have index 2 <= q < 4 */ +#define DO_Q 2 /* Electrostatic grids have index q<2 */ +#define DO_Q_AND_LJ 4 /* non-LB LJ grids have index 2 <= q < 4 */ #define DO_Q_AND_LJ_LB 9 /* With LB rules we need a total of 2+7 grids */ //@} /*! \brief Pascal triangle coefficients scaled with (1/2)^6 for LJ-PME with LB-rules */ -static const real lb_scale_factor[] = { - 1.0/64, 6.0/64, 15.0/64, 20.0/64, - 15.0/64, 6.0/64, 1.0/64 -}; +static const real lb_scale_factor[] = { 1.0 / 64, 6.0 / 64, 15.0 / 64, 20.0 / 64, + 15.0 / 64, 6.0 / 64, 1.0 / 64 }; /*! \brief Pascal triangle coefficients used in solve_pme_lj_yzx, only need to do 4 calculations due to symmetry */ -static const real lb_scale_factor_symm[] = { 2.0/64, 12.0/64, 30.0/64, 20.0/64 }; +static const real lb_scale_factor_symm[] = { 2.0 / 64, 12.0 / 64, 30.0 / 64, 20.0 / 64 }; /*! \brief We only define a maximum to be able to use local arrays without allocation. * An order larger than 12 should never be needed, even for test cases. @@ -98,13 +96,13 @@ static const real lb_scale_factor_symm[] = { 2.0/64, 12.0/64, 30.0/64, 20.0/64 } */ #define PME_ORDER_MAX 12 -/*! \brief As gmx_pme_init, but takes most settings, except the grid/Ewald coefficients, from pme_src. - * This is only called when the PME cut-off/grid size changes. +/*! \brief As gmx_pme_init, but takes most settings, except the grid/Ewald coefficients, from + * pme_src. This is only called when the PME cut-off/grid size changes. */ -void gmx_pme_reinit(struct gmx_pme_t **pmedata, - const t_commrec *cr, - struct gmx_pme_t * pme_src, - const t_inputrec * ir, +void gmx_pme_reinit(struct gmx_pme_t** pmedata, + const t_commrec* cr, + struct gmx_pme_t* pme_src, + const t_inputrec* ir, const ivec grid_size, real ewaldcoeff_q, real ewaldcoeff_lj); @@ -119,77 +117,78 @@ void gmx_pme_reinit(struct gmx_pme_t **pmedata, /*! \brief Data structure for grid communication */ struct pme_grid_comm_t { - int send_id; //!< Source rank id + int send_id; //!< Source rank id int send_index0; int send_nindex; - int recv_id; //!< Destination rank id + int recv_id; //!< Destination rank id int recv_index0; int recv_nindex; - int recv_size = 0; //!< Receive buffer width, used with OpenMP + int recv_size = 0; //!< Receive buffer width, used with OpenMP }; /*! \brief Data structure for grid overlap communication in a single dimension */ struct pme_overlap_t { - MPI_Comm mpi_comm; //!< MPI communcator - int nnodes; //!< Number of ranks - int nodeid; //!< Unique rank identifcator - std::vector s2g0; //!< The local interpolation grid start - std::vector s2g1; //!< The local interpolation grid end - int send_size; //!< Send buffer width, used with OpenMP - std::vector comm_data; //!< All the individual communication data for each rank - std::vector sendbuf; //!< Shared buffer for sending - std::vector recvbuf; //!< Shared buffer for receiving + MPI_Comm mpi_comm; //!< MPI communcator + int nnodes; //!< Number of ranks + int nodeid; //!< Unique rank identifcator + std::vector s2g0; //!< The local interpolation grid start + std::vector s2g1; //!< The local interpolation grid end + int send_size; //!< Send buffer width, used with OpenMP + std::vector comm_data; //!< All the individual communication data for each rank + std::vector sendbuf; //!< Shared buffer for sending + std::vector recvbuf; //!< Shared buffer for receiving }; template -using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; +using AlignedVector = std::vector>; template -using FastVector = std::vector < T, gmx::DefaultInitializationAllocator < T>>; +using FastVector = std::vector>; /*! \brief Data structure for organizing particle allocation to threads */ struct AtomToThreadMap { //! Cumulative counts of the number of particles per thread - int *n = nullptr; + int* n = nullptr; //! Storage buffer for n std::vector nBuffer; //! Particle indices ordered on thread index (n) - FastVector i; + FastVector i; }; /*! \brief Helper typedef for spline vectors */ -typedef real *splinevec[DIM]; +typedef real* splinevec[DIM]; /*! \internal * \brief Coefficients for theta or dtheta */ class SplineCoefficients { - public: - //! Reallocate for use with up to nalloc coefficients - void realloc(int nalloc); - - //! Pointers to the coefficient buffer for x, y, z - splinevec coefficients = { nullptr }; - private: - //! Storage for x coefficients - std::vector bufferX_; - //! Storage for y coefficients - std::vector bufferY_; - //! Storage for z coefficients, aligned for SIMD load - AlignedVector bufferZ_; +public: + //! Reallocate for use with up to nalloc coefficients + void realloc(int nalloc); + + //! Pointers to the coefficient buffer for x, y, z + splinevec coefficients = { nullptr }; + +private: + //! Storage for x coefficients + std::vector bufferX_; + //! Storage for y coefficients + std::vector bufferY_; + //! Storage for z coefficients, aligned for SIMD load + AlignedVector bufferZ_; }; /*! \brief Data structure for beta-spline interpolation */ struct splinedata_t { - int n = 0; - FastVector ind; - SplineCoefficients theta; - SplineCoefficients dtheta; - int nalloc = 0; + int n = 0; + FastVector ind; + SplineCoefficients theta; + SplineCoefficients dtheta; + int nalloc = 0; }; /*! \brief PME slab MPI communication setup */ @@ -212,100 +211,96 @@ struct SlabCommSetup */ class PmeAtomComm { - public: - //! Constructor, \p PmeMpiCommunicator is the communicator for this dimension - PmeAtomComm(MPI_Comm PmeMpiCommunicator, - int numThreads, - int pmeOrder, - int dimIndex, - bool doSpread); - - //! Set the atom count and when necessary resizes atom buffers - void setNumAtoms(int numAtoms); - - //! Returns the atom count - int numAtoms() const - { - return numAtoms_; - } - - //! Returns the number of atoms to send to each rank - gmx::ArrayRef sendCount() - { - GMX_ASSERT(!count_thread.empty(), "Need at least one thread_count"); - return count_thread[0]; - } - - //! The index of the dimension, 0=x, 1=y - int dimind = 0; - //! The number of slabs and ranks this dimension is decomposed over - int nslab = 1; - //! Our MPI rank index - int nodeid = 0; - //! Communicator for this dimension - MPI_Comm mpi_comm; - - //! Communication setup for each slab, only present with nslab > 1 - std::vector slabCommSetup; - //! The maximum communication distance counted in MPI ranks - int maxshift = 0; - - //! The target slab index for each particle - FastVector pd; - //! Target particle counts for each slab, for each thread - std::vector < std::vector < int>> count_thread; - - private: - //! The number of atoms - int numAtoms_ = 0; - public: - //! The coordinates - gmx::ArrayRef x; - //! The coefficient, charges or LJ C6 - gmx::ArrayRef coefficient; - //! The forces - gmx::ArrayRef f; - //! Coordinate buffer, used only with nslab > 1 - FastVector xBuffer; - //! Coefficient buffer, used only with nslab > 1 - FastVector coefficientBuffer; - //! Force buffer, used only with nslab > 1 - FastVector fBuffer; - //! Tells whether these coordinates are used for spreading - bool bSpread; - //! The PME order - int pme_order; - //! The grid index per atom - FastVector idx; - //! Fractional atom coordinates relative to the lower cell boundary - FastVector fractx; - - //! The number of threads to use in PME - int nthread; - //! Thread index for each atom - FastVector thread_idx; - std::vector threadMap; - std::vector spline; +public: + //! Constructor, \p PmeMpiCommunicator is the communicator for this dimension + PmeAtomComm(MPI_Comm PmeMpiCommunicator, int numThreads, int pmeOrder, int dimIndex, bool doSpread); + + //! Set the atom count and when necessary resizes atom buffers + void setNumAtoms(int numAtoms); + + //! Returns the atom count + int numAtoms() const { return numAtoms_; } + + //! Returns the number of atoms to send to each rank + gmx::ArrayRef sendCount() + { + GMX_ASSERT(!count_thread.empty(), "Need at least one thread_count"); + return count_thread[0]; + } + + //! The index of the dimension, 0=x, 1=y + int dimind = 0; + //! The number of slabs and ranks this dimension is decomposed over + int nslab = 1; + //! Our MPI rank index + int nodeid = 0; + //! Communicator for this dimension + MPI_Comm mpi_comm; + + //! Communication setup for each slab, only present with nslab > 1 + std::vector slabCommSetup; + //! The maximum communication distance counted in MPI ranks + int maxshift = 0; + + //! The target slab index for each particle + FastVector pd; + //! Target particle counts for each slab, for each thread + std::vector> count_thread; + +private: + //! The number of atoms + int numAtoms_ = 0; + +public: + //! The coordinates + gmx::ArrayRef x; + //! The coefficient, charges or LJ C6 + gmx::ArrayRef coefficient; + //! The forces + gmx::ArrayRef f; + //! Coordinate buffer, used only with nslab > 1 + FastVector xBuffer; + //! Coefficient buffer, used only with nslab > 1 + FastVector coefficientBuffer; + //! Force buffer, used only with nslab > 1 + FastVector fBuffer; + //! Tells whether these coordinates are used for spreading + bool bSpread; + //! The PME order + int pme_order; + //! The grid index per atom + FastVector idx; + //! Fractional atom coordinates relative to the lower cell boundary + FastVector fractx; + + //! The number of threads to use in PME + int nthread; + //! Thread index for each atom + FastVector thread_idx; + std::vector threadMap; + std::vector spline; }; /*! \brief Data structure for a single PME grid */ -struct pmegrid_t{ +struct pmegrid_t +{ ivec ci; /* The spatial location of this grid */ ivec n; /* The used size of *grid, including order-1 */ ivec offset; /* The grid offset from the full node grid */ int order; /* PME spreading order */ ivec s; /* The allocated size of *grid, s >= n */ - real *grid; /* The grid local thread, size n */ + real* grid; /* The grid local thread, size n */ }; /*! \brief Data structures for PME grids */ -struct pmegrids_t{ +struct pmegrids_t +{ pmegrid_t grid; /* The full node grid (non thread-local) */ int nthread; /* The number of threads operating on this grid */ ivec nc; /* The local spatial decomposition over the threads */ - pmegrid_t *grid_th; /* Array of grids for each thread */ - real *grid_all; /* Allocated array for the grids in *grid_th */ - int *g2t[DIM]; /* The grid to thread index */ + pmegrid_t* grid_th; /* Array of grids for each thread */ + real* grid_all; /* Allocated array for the grids in *grid_th */ + int* g2t[DIM]; /* The grid to thread index */ ivec nthread_comm; /* The number of threads to communicate with */ }; @@ -316,61 +311,62 @@ struct pme_spline_work; struct pme_solve_work_t; /*! \brief Master PME data structure */ -struct gmx_pme_t { //NOLINT(clang-analyzer-optin.performance.Padding) - int ndecompdim; /* The number of decomposition dimensions */ - int nodeid; /* Our nodeid in mpi->mpi_comm */ - int nodeid_major; - int nodeid_minor; - int nnodes; /* The number of nodes doing PME */ - int nnodes_major; - int nnodes_minor; - - MPI_Comm mpi_comm; - MPI_Comm mpi_comm_d[2]; /* Indexed on dimension, 0=x, 1=y */ +struct gmx_pme_t +{ //NOLINT(clang-analyzer-optin.performance.Padding) + int ndecompdim; /* The number of decomposition dimensions */ + int nodeid; /* Our nodeid in mpi->mpi_comm */ + int nodeid_major; + int nodeid_minor; + int nnodes; /* The number of nodes doing PME */ + int nnodes_major; + int nnodes_minor; + + MPI_Comm mpi_comm; + MPI_Comm mpi_comm_d[2]; /* Indexed on dimension, 0=x, 1=y */ #if GMX_MPI - MPI_Datatype rvec_mpi; /* the pme vector's MPI type */ + MPI_Datatype rvec_mpi; /* the pme vector's MPI type */ #endif - gmx_bool bUseThreads; /* Does any of the PME ranks have nthread>1 ? */ - int nthread; /* The number of threads doing PME on our rank */ + gmx_bool bUseThreads; /* Does any of the PME ranks have nthread>1 ? */ + int nthread; /* The number of threads doing PME on our rank */ - gmx_bool bPPnode; /* Node also does particle-particle forces */ - bool doCoulomb; /* Apply PME to electrostatics */ - bool doLJ; /* Apply PME to Lennard-Jones r^-6 interactions */ - gmx_bool bFEP; /* Compute Free energy contribution */ - gmx_bool bFEP_q; - gmx_bool bFEP_lj; - int nkx, nky, nkz; /* Grid dimensions */ - gmx_bool bP3M; /* Do P3M: optimize the influence function */ - int pme_order; - real ewaldcoeff_q; /* Ewald splitting coefficient for Coulomb */ - real ewaldcoeff_lj; /* Ewald splitting coefficient for r^-6 */ - real epsilon_r; + gmx_bool bPPnode; /* Node also does particle-particle forces */ + bool doCoulomb; /* Apply PME to electrostatics */ + bool doLJ; /* Apply PME to Lennard-Jones r^-6 interactions */ + gmx_bool bFEP; /* Compute Free energy contribution */ + gmx_bool bFEP_q; + gmx_bool bFEP_lj; + int nkx, nky, nkz; /* Grid dimensions */ + gmx_bool bP3M; /* Do P3M: optimize the influence function */ + int pme_order; + real ewaldcoeff_q; /* Ewald splitting coefficient for Coulomb */ + real ewaldcoeff_lj; /* Ewald splitting coefficient for r^-6 */ + real epsilon_r; enum PmeRunMode runMode; /* Which codepath is the PME runner taking - CPU, GPU, mixed; - * TODO: this is the information that should be owned by the task scheduler, - * and ideally not be duplicated here. + * TODO: this is the information that should be owned by the task + * scheduler, and ideally not be duplicated here. */ - PmeGpu *gpu; /* A pointer to the GPU data. - * TODO: this should be unique or a shared pointer. - * Currently in practice there is a single gmx_pme_t instance while a code - * is partially set up for many of them. The PME tuning calls gmx_pme_reinit() - * which fully reinitializes the one and only PME structure anew while maybe - * keeping the old grid buffers if they were already large enough. - * This small choice should be made clear in the later refactoring - - * do we store many PME objects for different grid sizes, - * or a single PME object that handles different grid sizes gracefully. - */ + PmeGpu* gpu; /* A pointer to the GPU data. + * TODO: this should be unique or a shared pointer. + * Currently in practice there is a single gmx_pme_t instance while a code + * is partially set up for many of them. The PME tuning calls gmx_pme_reinit() + * which fully reinitializes the one and only PME structure anew while maybe + * keeping the old grid buffers if they were already large enough. + * This small choice should be made clear in the later refactoring - + * do we store many PME objects for different grid sizes, + * or a single PME object that handles different grid sizes gracefully. + */ - class EwaldBoxZScaler *boxScaler; /**< The scaling data Ewald uses with walls (set at pme_init constant for the entire run) */ + class EwaldBoxZScaler* boxScaler; /**< The scaling data Ewald uses with walls (set at pme_init constant for the entire run) */ - int ljpme_combination_rule; /* Type of combination rule in LJ-PME */ + int ljpme_combination_rule; /* Type of combination rule in LJ-PME */ - int ngrids; /* number of grids we maintain for pmegrid, (c)fftgrid and pfft_setups*/ + int ngrids; /* number of grids we maintain for pmegrid, (c)fftgrid and pfft_setups*/ pmegrids_t pmegrid[DO_Q_AND_LJ_LB]; /* Grids on which we do spreading/interpolation, * includes overlap Grid indices are ordered as @@ -383,58 +379,58 @@ struct gmx_pme_t { //NOLINT(clang-analyzer-optin.performance.Padding) */ /* The PME coefficient spreading grid sizes/strides, includes pme_order-1 */ - int pmegrid_nx, pmegrid_ny, pmegrid_nz; + int pmegrid_nx, pmegrid_ny, pmegrid_nz; /* pmegrid_nz might be larger than strictly necessary to ensure * memory alignment, pmegrid_nz_base gives the real base size. */ - int pmegrid_nz_base; + int pmegrid_nz_base; /* The local PME grid starting indices */ - int pmegrid_start_ix, pmegrid_start_iy, pmegrid_start_iz; + int pmegrid_start_ix, pmegrid_start_iy, pmegrid_start_iz; /* Work data for spreading and gathering */ - pme_spline_work *spline_work; + pme_spline_work* spline_work; - real **fftgrid; /* Grids for FFT. With 1D FFT decomposition this can be a pointer */ + real** fftgrid; /* Grids for FFT. With 1D FFT decomposition this can be a pointer */ /* inside the interpolation grid, but separate for 2D PME decomp. */ - int fftgrid_nx, fftgrid_ny, fftgrid_nz; + int fftgrid_nx, fftgrid_ny, fftgrid_nz; - t_complex **cfftgrid; /* Grids for complex FFT data */ + t_complex** cfftgrid; /* Grids for complex FFT data */ - int cfftgrid_nx, cfftgrid_ny, cfftgrid_nz; + int cfftgrid_nx, cfftgrid_ny, cfftgrid_nz; - gmx_parallel_3dfft_t *pfft_setup; + gmx_parallel_3dfft_t* pfft_setup; - int *nnx, *nny, *nnz; - real *fshx, *fshy, *fshz; + int * nnx, *nny, *nnz; + real *fshx, *fshy, *fshz; - std::vector atc; /* Indexed on decomposition index */ - matrix recipbox; - real boxVolume; - splinevec bsp_mod; + std::vector atc; /* Indexed on decomposition index */ + matrix recipbox; + real boxVolume; + splinevec bsp_mod; /* Buffers to store data for local atoms for L-B combination rule * calculations in LJ-PME. lb_buf1 stores either the coefficients * for spreading/gathering (in serial), or the C6 coefficient for * local atoms (in parallel). lb_buf2 is only used in parallel, * and stores the sigma values for local atoms. */ - FastVector lb_buf1; - FastVector lb_buf2; + FastVector lb_buf1; + FastVector lb_buf2; - pme_overlap_t overlap[2]; /* Indexed on dimension, 0=x, 1=y */ + pme_overlap_t overlap[2]; /* Indexed on dimension, 0=x, 1=y */ /* Atom step for energy only calculation in gmx_pme_calc_energy() */ std::unique_ptr atc_energy; /* Communication buffers */ - rvec *bufv; /* Communication buffer */ - real *bufr; /* Communication buffer */ - int buf_nalloc; /* The communication buffer size */ + rvec* bufv; /* Communication buffer */ + real* bufr; /* Communication buffer */ + int buf_nalloc; /* The communication buffer size */ /* thread local work data for solve_pme */ - struct pme_solve_work_t *solve_work; + struct pme_solve_work_t* solve_work; /* Work data for sum_qgrid */ - real * sum_qgrid_tmp; - real * sum_qgrid_dd_tmp; + real* sum_qgrid_tmp; + real* sum_qgrid_dd_tmp; }; //! @endcond @@ -446,15 +442,12 @@ struct gmx_pme_t { //NOLINT(clang-analyzer-optin.performance.Padding) * \param[in] pme The PME structure. * \returns True if PME runs on GPU currently, false otherwise. */ -inline bool pme_gpu_active(const gmx_pme_t *pme) +inline bool pme_gpu_active(const gmx_pme_t* pme) { return (pme != nullptr) && (pme->runMode != PmeRunMode::CPU); } /*! \brief Tell our PME-only node to switch to a new grid size */ -void gmx_pme_send_switchgrid(const t_commrec *cr, - ivec grid_size, - real ewaldcoeff_q, - real ewaldcoeff_lj); +void gmx_pme_send_switchgrid(const t_commrec* cr, ivec grid_size, real ewaldcoeff_q, real ewaldcoeff_lj); #endif diff --git a/src/gromacs/ewald/pme_load_balancing.cpp b/src/gromacs/ewald/pme_load_balancing.cpp index 60611d8f6e..98d0d9e2fc 100644 --- a/src/gromacs/ewald/pme_load_balancing.cpp +++ b/src/gromacs/ewald/pme_load_balancing.cpp @@ -81,22 +81,23 @@ #include "pme_internal.h" /*! \brief Parameters and settings for one PP-PME setup */ -struct pme_setup_t { - real rcut_coulomb; /**< Coulomb cut-off */ - real rlistOuter; /**< cut-off for the outer pair-list */ - real rlistInner; /**< cut-off for the inner pair-list */ - real spacing; /**< (largest) PME grid spacing */ - ivec grid; /**< the PME grid dimensions */ - real grid_efficiency; /**< ineffiency factor for non-uniform grids <= 1 */ - real ewaldcoeff_q; /**< Electrostatic Ewald coefficient */ - real ewaldcoeff_lj; /**< LJ Ewald coefficient, only for the call to send_switchgrid */ - struct gmx_pme_t *pmedata; /**< the data structure used in the PME code */ - int count; /**< number of times this setup has been timed */ - double cycles; /**< the fastest time for this setup in cycles */ +struct pme_setup_t +{ + real rcut_coulomb; /**< Coulomb cut-off */ + real rlistOuter; /**< cut-off for the outer pair-list */ + real rlistInner; /**< cut-off for the inner pair-list */ + real spacing; /**< (largest) PME grid spacing */ + ivec grid; /**< the PME grid dimensions */ + real grid_efficiency; /**< ineffiency factor for non-uniform grids <= 1 */ + real ewaldcoeff_q; /**< Electrostatic Ewald coefficient */ + real ewaldcoeff_lj; /**< LJ Ewald coefficient, only for the call to send_switchgrid */ + struct gmx_pme_t* pmedata; /**< the data structure used in the PME code */ + int count; /**< number of times this setup has been timed */ + double cycles; /**< the fastest time for this setup in cycles */ }; /*! \brief After 50 nstlist periods of not observing imbalance: never tune PME */ -const int PMETunePeriod = 50; +const int PMETunePeriod = 50; /*! \brief Trigger PME load balancing at more than 5% PME overload */ const real loadBalanceTriggerFactor = 1.05; /*! \brief Scale the grid by a most at factor 1.7. @@ -124,21 +125,29 @@ const real maxRelativeSlowdownAccepted = 1.12; const real maxFluctuationAccepted = 1.02; /*! \brief Enumeration whose values describe the effect limiting the load balancing */ -enum epmelb { - epmelblimNO, epmelblimBOX, epmelblimDD, epmelblimPMEGRID, epmelblimMAXSCALING, epmelblimNR +enum epmelb +{ + epmelblimNO, + epmelblimBOX, + epmelblimDD, + epmelblimPMEGRID, + epmelblimMAXSCALING, + epmelblimNR }; /*! \brief Descriptive strings matching ::epmelb */ -static const char *pmelblim_str[epmelblimNR] = -{ "no", "box size", "domain decompostion", "PME grid restriction", "maximum allowed grid scaling" }; +static const char* pmelblim_str[epmelblimNR] = { "no", "box size", "domain decompostion", + "PME grid restriction", + "maximum allowed grid scaling" }; -struct pme_load_balancing_t { - gmx_bool bSepPMERanks; /**< do we have separate PME ranks? */ - gmx_bool bActive; /**< is PME tuning active? */ - int64_t step_rel_stop; /**< stop the tuning after this value of step_rel */ - gmx_bool bTriggerOnDLB; /**< trigger balancing only on DD DLB */ - gmx_bool bBalance; /**< are we in the balancing phase, i.e. trying different setups? */ - int nstage; /**< the current maximum number of stages */ +struct pme_load_balancing_t +{ + gmx_bool bSepPMERanks; /**< do we have separate PME ranks? */ + gmx_bool bActive; /**< is PME tuning active? */ + int64_t step_rel_stop; /**< stop the tuning after this value of step_rel */ + gmx_bool bTriggerOnDLB; /**< trigger balancing only on DD DLB */ + gmx_bool bBalance; /**< are we in the balancing phase, i.e. trying different setups? */ + int nstage; /**< the current maximum number of stages */ real cut_spacing; /**< the minimum cutoff / PME grid spacing ratio */ real rcut_vdw; /**< Vdw cutoff (does not change) */ @@ -152,58 +161,60 @@ struct pme_load_balancing_t { int cur; /**< the index (in setup) of the current setup */ int fastest; /**< index of the fastest setup up till now */ int lower_limit; /**< don't go below this setup index */ - int start; /**< start of setup index range to consider in stage>0 */ - int end; /**< end of setup index range to consider in stage>0 */ - int elimited; /**< was the balancing limited, uses enum above */ - int cutoff_scheme; /**< Verlet or group cut-offs */ + int start; /**< start of setup index range to consider in stage>0 */ + int end; /**< end of setup index range to consider in stage>0 */ + int elimited; /**< was the balancing limited, uses enum above */ + int cutoff_scheme; /**< Verlet or group cut-offs */ - int stage; /**< the current stage */ + int stage; /**< the current stage */ - int cycles_n; /**< step cycle counter cummulative count */ - double cycles_c; /**< step cycle counter cummulative cycles */ + int cycles_n; /**< step cycle counter cummulative count */ + double cycles_c; /**< step cycle counter cummulative cycles */ }; /* TODO The code in this file should call this getter, rather than * read bActive anywhere */ -bool pme_loadbal_is_active(const pme_load_balancing_t *pme_lb) +bool pme_loadbal_is_active(const pme_load_balancing_t* pme_lb) { return pme_lb != nullptr && pme_lb->bActive; } // TODO Return a unique_ptr to pme_load_balancing_t -void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, - t_commrec *cr, - const gmx::MDLogger &mdlog, - const t_inputrec &ir, +void pme_loadbal_init(pme_load_balancing_t** pme_lb_p, + t_commrec* cr, + const gmx::MDLogger& mdlog, + const t_inputrec& ir, const matrix box, - const interaction_const_t &ic, - const nonbonded_verlet_t &nbv, - gmx_pme_t *pmedata, + const interaction_const_t& ic, + const nonbonded_verlet_t& nbv, + gmx_pme_t* pmedata, gmx_bool bUseGPU, - gmx_bool *bPrinting) + gmx_bool* bPrinting) { - pme_load_balancing_t *pme_lb; + pme_load_balancing_t* pme_lb; real spm, sp; int d; // Note that we don't (yet) support PME load balancing with LJ-PME only. - GMX_RELEASE_ASSERT(EEL_PME(ir.coulombtype), "pme_loadbal_init called without PME electrostatics"); + GMX_RELEASE_ASSERT(EEL_PME(ir.coulombtype), + "pme_loadbal_init called without PME electrostatics"); // To avoid complexity, we require a single cut-off with PME for q+LJ. // This is checked by grompp, but it doesn't hurt to check again. - GMX_RELEASE_ASSERT(!(EEL_PME(ir.coulombtype) && EVDW_PME(ir.vdwtype) && ir.rcoulomb != ir.rvdw), "With Coulomb and LJ PME, rcoulomb should be equal to rvdw"); + GMX_RELEASE_ASSERT(!(EEL_PME(ir.coulombtype) && EVDW_PME(ir.vdwtype) && ir.rcoulomb != ir.rvdw), + "With Coulomb and LJ PME, rcoulomb should be equal to rvdw"); pme_lb = new pme_load_balancing_t; - pme_lb->bSepPMERanks = !thisRankHasDuty(cr, DUTY_PME); + pme_lb->bSepPMERanks = !thisRankHasDuty(cr, DUTY_PME); /* Initially we turn on balancing directly on based on PP/PME imbalance */ - pme_lb->bTriggerOnDLB = FALSE; + pme_lb->bTriggerOnDLB = FALSE; /* Any number of stages >= 2 is supported */ - pme_lb->nstage = 2; + pme_lb->nstage = 2; - pme_lb->cutoff_scheme = ir.cutoff_scheme; + pme_lb->cutoff_scheme = ir.cutoff_scheme; pme_lb->rbufOuter_coulomb = nbv.pairlistOuterRadius() - ic.rcoulomb; pme_lb->rbufOuter_vdw = nbv.pairlistOuterRadius() - ic.rvdw; @@ -218,29 +229,30 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, pme_lb->setup.resize(1); - pme_lb->rcut_vdw = ic.rvdw; - pme_lb->rcut_coulomb_start = ir.rcoulomb; + pme_lb->rcut_vdw = ic.rvdw; + pme_lb->rcut_coulomb_start = ir.rcoulomb; - pme_lb->cur = 0; - pme_lb->setup[0].rcut_coulomb = ic.rcoulomb; - pme_lb->setup[0].rlistOuter = nbv.pairlistOuterRadius(); - pme_lb->setup[0].rlistInner = nbv.pairlistInnerRadius(); - pme_lb->setup[0].grid[XX] = ir.nkx; - pme_lb->setup[0].grid[YY] = ir.nky; - pme_lb->setup[0].grid[ZZ] = ir.nkz; - pme_lb->setup[0].ewaldcoeff_q = ic.ewaldcoeff_q; - pme_lb->setup[0].ewaldcoeff_lj = ic.ewaldcoeff_lj; + pme_lb->cur = 0; + pme_lb->setup[0].rcut_coulomb = ic.rcoulomb; + pme_lb->setup[0].rlistOuter = nbv.pairlistOuterRadius(); + pme_lb->setup[0].rlistInner = nbv.pairlistInnerRadius(); + pme_lb->setup[0].grid[XX] = ir.nkx; + pme_lb->setup[0].grid[YY] = ir.nky; + pme_lb->setup[0].grid[ZZ] = ir.nkz; + pme_lb->setup[0].ewaldcoeff_q = ic.ewaldcoeff_q; + pme_lb->setup[0].ewaldcoeff_lj = ic.ewaldcoeff_lj; if (!pme_lb->bSepPMERanks) { - GMX_RELEASE_ASSERT(pmedata, "On ranks doing both PP and PME we need a valid pmedata object"); - pme_lb->setup[0].pmedata = pmedata; + GMX_RELEASE_ASSERT(pmedata, + "On ranks doing both PP and PME we need a valid pmedata object"); + pme_lb->setup[0].pmedata = pmedata; } spm = 0; for (d = 0; d < DIM; d++) { - sp = norm(pme_lb->box_start[d])/pme_lb->setup[0].grid[d]; + sp = norm(pme_lb->box_start[d]) / pme_lb->setup[0].grid[d]; if (sp > spm) { spm = sp; @@ -250,11 +262,11 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, if (ir.fourier_spacing > 0) { - pme_lb->cut_spacing = ir.rcoulomb/ir.fourier_spacing; + pme_lb->cut_spacing = ir.rcoulomb / ir.fourier_spacing; } else { - pme_lb->cut_spacing = ir.rcoulomb/pme_lb->setup[0].spacing; + pme_lb->cut_spacing = ir.rcoulomb / pme_lb->setup[0].spacing; } pme_lb->stage = 0; @@ -270,15 +282,18 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, if (!wallcycle_have_counter()) { - GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: Cycle counters unsupported or not enabled in kernel. Cannot use PME-PP balancing."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: Cycle counters unsupported or not enabled in kernel. Cannot use " + "PME-PP balancing."); } /* Tune with GPUs and/or separate PME ranks. * When running only on a CPU without PME ranks, PME tuning will only help * with small numbers of atoms in the cut-off sphere. */ - pme_lb->bActive = (wallcycle_have_counter() && (bUseGPU || - pme_lb->bSepPMERanks)); + pme_lb->bActive = (wallcycle_have_counter() && (bUseGPU || pme_lb->bSepPMERanks)); /* With GPUs and no separate PME ranks we can't measure the PP/PME * imbalance, so we start balancing right away. @@ -286,7 +301,7 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, */ pme_lb->bBalance = (pme_lb->bActive && (bUseGPU && !pme_lb->bSepPMERanks)); - pme_lb->step_rel_stop = PMETunePeriod*ir.nstlist; + pme_lb->step_rel_stop = PMETunePeriod * ir.nstlist; /* Delay DD load balancing when GPUs are used */ if (pme_lb->bActive && DOMAINDECOMP(cr) && cr->dd->nnodes > 1 && bUseGPU) @@ -300,7 +315,9 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, dd_dlb_lock(cr->dd); if (dd_dlb_is_locked(cr->dd)) { - GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB will not turn on during the first phase of PME tuning"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: DLB will not turn on during the first phase of PME tuning"); } } @@ -310,14 +327,12 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, } /*! \brief Try to increase the cutoff during load balancing */ -static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t *pme_lb, - int pme_order, - const gmx_domdec_t *dd) +static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t* pme_lb, int pme_order, const gmx_domdec_t* dd) { - real fac, sp; - real tmpr_coulomb, tmpr_vdw; - int d; - bool grid_ok; + real fac, sp; + real tmpr_coulomb, tmpr_vdw; + int d; + bool grid_ok; /* Try to add a new setup with next larger cut-off to the list */ pme_setup_t set; @@ -341,27 +356,19 @@ static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t *pme_lb, fac *= 1.01; clear_ivec(set.grid); - sp = calcFftGrid(nullptr, pme_lb->box_start, - fac*pme_lb->setup[pme_lb->cur].spacing, - minimalPmeGridSize(pme_order), - &set.grid[XX], - &set.grid[YY], - &set.grid[ZZ]); + sp = calcFftGrid(nullptr, pme_lb->box_start, fac * pme_lb->setup[pme_lb->cur].spacing, + minimalPmeGridSize(pme_order), &set.grid[XX], &set.grid[YY], &set.grid[ZZ]); /* As here we can't easily check if one of the PME ranks * uses threading, we do a conservative grid check. * This means we can't use pme_order or less grid lines * per PME rank along x, which is not a strong restriction. */ - grid_ok = gmx_pme_check_restrictions(pme_order, - set.grid[XX], set.grid[YY], set.grid[ZZ], - numPmeDomains.x, - true, - false); - } - while (sp <= 1.001*pme_lb->setup[pme_lb->cur].spacing || !grid_ok); + grid_ok = gmx_pme_check_restrictions(pme_order, set.grid[XX], set.grid[YY], set.grid[ZZ], + numPmeDomains.x, true, false); + } while (sp <= 1.001 * pme_lb->setup[pme_lb->cur].spacing || !grid_ok); - set.rcut_coulomb = pme_lb->cut_spacing*sp; + set.rcut_coulomb = pme_lb->cut_spacing * sp; if (set.rcut_coulomb < pme_lb->rcut_coulomb_start) { /* This is unlikely, but can happen when e.g. continuing from @@ -375,63 +382,56 @@ static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t *pme_lb, if (pme_lb->cutoff_scheme == ecutsVERLET) { /* Never decrease the Coulomb and VdW list buffers */ - set.rlistOuter = std::max(set.rcut_coulomb + pme_lb->rbufOuter_coulomb, - pme_lb->rcut_vdw + pme_lb->rbufOuter_vdw); - set.rlistInner = std::max(set.rcut_coulomb + pme_lb->rbufInner_coulomb, - pme_lb->rcut_vdw + pme_lb->rbufInner_vdw); + set.rlistOuter = std::max(set.rcut_coulomb + pme_lb->rbufOuter_coulomb, + pme_lb->rcut_vdw + pme_lb->rbufOuter_vdw); + set.rlistInner = std::max(set.rcut_coulomb + pme_lb->rbufInner_coulomb, + pme_lb->rcut_vdw + pme_lb->rbufInner_vdw); } else { /* TODO Remove these lines and pme_lb->cutoff_scheme */ - tmpr_coulomb = set.rcut_coulomb + pme_lb->rbufOuter_coulomb; - tmpr_vdw = pme_lb->rcut_vdw + pme_lb->rbufOuter_vdw; + tmpr_coulomb = set.rcut_coulomb + pme_lb->rbufOuter_coulomb; + tmpr_vdw = pme_lb->rcut_vdw + pme_lb->rbufOuter_vdw; /* Two (known) bugs with cutoff-scheme=group here: * - This modification of rlist results in incorrect DD comunication. * - We should set fr->bTwinRange = (fr->rlistlong > fr->rlist). */ - set.rlistOuter = std::min(tmpr_coulomb, tmpr_vdw); - set.rlistInner = set.rlistOuter; + set.rlistOuter = std::min(tmpr_coulomb, tmpr_vdw); + set.rlistInner = set.rlistOuter; } - set.spacing = sp; + set.spacing = sp; /* The grid efficiency is the size wrt a grid with uniform x/y/z spacing */ set.grid_efficiency = 1; for (d = 0; d < DIM; d++) { - set.grid_efficiency *= (set.grid[d]*sp)/norm(pme_lb->box_start[d]); + set.grid_efficiency *= (set.grid[d] * sp) / norm(pme_lb->box_start[d]); } /* The Ewald coefficient is inversly proportional to the cut-off */ - set.ewaldcoeff_q = - pme_lb->setup[0].ewaldcoeff_q*pme_lb->setup[0].rcut_coulomb/set.rcut_coulomb; + set.ewaldcoeff_q = pme_lb->setup[0].ewaldcoeff_q * pme_lb->setup[0].rcut_coulomb / set.rcut_coulomb; /* We set ewaldcoeff_lj in set, even when LJ-PME is not used */ - set.ewaldcoeff_lj = - pme_lb->setup[0].ewaldcoeff_lj*pme_lb->setup[0].rcut_coulomb/set.rcut_coulomb; + set.ewaldcoeff_lj = pme_lb->setup[0].ewaldcoeff_lj * pme_lb->setup[0].rcut_coulomb / set.rcut_coulomb; - set.count = 0; - set.cycles = 0; + set.count = 0; + set.cycles = 0; if (debug) { - fprintf(debug, "PME loadbal: grid %d %d %d, coulomb cutoff %f\n", - set.grid[XX], set.grid[YY], set.grid[ZZ], set.rcut_coulomb); + fprintf(debug, "PME loadbal: grid %d %d %d, coulomb cutoff %f\n", set.grid[XX], + set.grid[YY], set.grid[ZZ], set.rcut_coulomb); } pme_lb->setup.push_back(set); return TRUE; } /*! \brief Print the PME grid */ -static void print_grid(FILE *fp_err, FILE *fp_log, - const char *pre, - const char *desc, - const pme_setup_t *set, - double cycles) +static void print_grid(FILE* fp_err, FILE* fp_log, const char* pre, const char* desc, const pme_setup_t* set, double cycles) { - auto buf = gmx::formatString("%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f", - pre, desc, + auto buf = gmx::formatString("%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f", pre, desc, set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb); if (cycles >= 0) { - buf += gmx::formatString(": %.1f M-cycles", cycles*1e-6); + buf += gmx::formatString(": %.1f M-cycles", cycles * 1e-6); } if (fp_err != nullptr) { @@ -445,7 +445,7 @@ static void print_grid(FILE *fp_err, FILE *fp_log, } /*! \brief Return the index of the last setup used in PME load balancing */ -static int pme_loadbal_end(pme_load_balancing_t *pme_lb) +static int pme_loadbal_end(pme_load_balancing_t* pme_lb) { /* In the initial stage only n is set; end is not set yet */ if (pme_lb->end > 0) @@ -459,14 +459,12 @@ static int pme_loadbal_end(pme_load_balancing_t *pme_lb) } /*! \brief Print descriptive string about what limits PME load balancing */ -static void print_loadbal_limited(FILE *fp_err, FILE *fp_log, - int64_t step, - pme_load_balancing_t *pme_lb) +static void print_loadbal_limited(FILE* fp_err, FILE* fp_log, int64_t step, pme_load_balancing_t* pme_lb) { - auto buf = gmx::formatString("step %4s: the %s limits the PME load balancing to a coulomb cut-off of %.3f", - gmx::int64ToString(step).c_str(), - pmelblim_str[pme_lb->elimited], - pme_lb->setup[pme_loadbal_end(pme_lb)-1].rcut_coulomb); + auto buf = gmx::formatString( + "step %4s: the %s limits the PME load balancing to a coulomb cut-off of %.3f", + gmx::int64ToString(step).c_str(), pmelblim_str[pme_lb->elimited], + pme_lb->setup[pme_loadbal_end(pme_lb) - 1].rcut_coulomb); if (fp_err != nullptr) { fprintf(fp_err, "\r%s\n", buf.c_str()); @@ -481,16 +479,16 @@ static void print_loadbal_limited(FILE *fp_err, FILE *fp_log, /*! \brief Switch load balancing to stage 1 * * In this stage, only reasonably fast setups are run again. */ -static void switch_to_stage1(pme_load_balancing_t *pme_lb) +static void switch_to_stage1(pme_load_balancing_t* pme_lb) { /* Increase start until we find a setup that is not slower than * maxRelativeSlowdownAccepted times the fastest setup. */ pme_lb->start = pme_lb->lower_limit; - while (pme_lb->start + 1 < gmx::ssize(pme_lb->setup) && - (pme_lb->setup[pme_lb->start].count == 0 || - pme_lb->setup[pme_lb->start].cycles > - pme_lb->setup[pme_lb->fastest].cycles*maxRelativeSlowdownAccepted)) + while (pme_lb->start + 1 < gmx::ssize(pme_lb->setup) + && (pme_lb->setup[pme_lb->start].count == 0 + || pme_lb->setup[pme_lb->start].cycles + > pme_lb->setup[pme_lb->fastest].cycles * maxRelativeSlowdownAccepted)) { pme_lb->start++; } @@ -499,17 +497,16 @@ static void switch_to_stage1(pme_load_balancing_t *pme_lb) * any skipped setups that lie between setups that were measured to be * acceptably fast and too slow. */ - while (pme_lb->start > pme_lb->lower_limit && - pme_lb->setup[pme_lb->start - 1].count == 0) + while (pme_lb->start > pme_lb->lower_limit && pme_lb->setup[pme_lb->start - 1].count == 0) { pme_lb->start--; } /* Decrease end only with setups that we timed and that are slow. */ pme_lb->end = pme_lb->setup.size(); - if (pme_lb->setup[pme_lb->end - 1].count > 0 && - pme_lb->setup[pme_lb->end - 1].cycles > - pme_lb->setup[pme_lb->fastest].cycles*maxRelativeSlowdownAccepted) + if (pme_lb->setup[pme_lb->end - 1].count > 0 + && pme_lb->setup[pme_lb->end - 1].cycles + > pme_lb->setup[pme_lb->fastest].cycles * maxRelativeSlowdownAccepted) { pme_lb->end--; } @@ -534,23 +531,22 @@ static void switch_to_stage1(pme_load_balancing_t *pme_lb) * Here we try to take into account fluctuations and changes due to external * factors as well as DD load balancing. */ -static void -pme_load_balance(pme_load_balancing_t *pme_lb, - t_commrec *cr, - FILE *fp_err, - FILE *fp_log, - const gmx::MDLogger &mdlog, - const t_inputrec &ir, - const matrix box, - gmx::ArrayRef x, - double cycles, - interaction_const_t *ic, - struct nonbonded_verlet_t *nbv, - struct gmx_pme_t ** pmedata, - int64_t step) +static void pme_load_balance(pme_load_balancing_t* pme_lb, + t_commrec* cr, + FILE* fp_err, + FILE* fp_log, + const gmx::MDLogger& mdlog, + const t_inputrec& ir, + const matrix box, + gmx::ArrayRef x, + double cycles, + interaction_const_t* ic, + struct nonbonded_verlet_t* nbv, + struct gmx_pme_t** pmedata, + int64_t step) { gmx_bool OK; - pme_setup_t *set; + pme_setup_t* set; double cycles_fast; char buf[STRLEN], sbuf[22]; @@ -580,8 +576,7 @@ pme_load_balance(pme_load_balancing_t *pme_lb, } else { - if (cycles*maxFluctuationAccepted < set->cycles && - pme_lb->stage == pme_lb->nstage - 1) + if (cycles * maxFluctuationAccepted < set->cycles && pme_lb->stage == pme_lb->nstage - 1) { /* The performance went up a lot (due to e.g. DD load balancing). * Add a stage, keep the minima, but rescan all setups. @@ -590,12 +585,13 @@ pme_load_balance(pme_load_balancing_t *pme_lb, if (debug) { - fprintf(debug, "The performance for grid %d %d %d went from %.3f to %.1f M-cycles, this is more than %f\n" + fprintf(debug, + "The performance for grid %d %d %d went from %.3f to %.1f M-cycles, this " + "is more than %f\n" "Increased the number stages to %d" " and ignoring the previous performance\n", - set->grid[XX], set->grid[YY], set->grid[ZZ], - set->cycles*1e-6, cycles*1e-6, maxFluctuationAccepted, - pme_lb->nstage); + set->grid[XX], set->grid[YY], set->grid[ZZ], set->cycles * 1e-6, + cycles * 1e-6, maxFluctuationAccepted, pme_lb->nstage); } } set->cycles = std::min(set->cycles, cycles); @@ -627,8 +623,8 @@ pme_load_balance(pme_load_balancing_t *pme_lb, /* Check in stage 0 if we should stop scanning grids. * Stop when the time is more than maxRelativeSlowDownAccepted longer than the fastest. */ - if (pme_lb->stage == 0 && pme_lb->cur > 0 && - cycles > pme_lb->setup[pme_lb->fastest].cycles*maxRelativeSlowdownAccepted) + if (pme_lb->stage == 0 && pme_lb->cur > 0 + && cycles > pme_lb->setup[pme_lb->fastest].cycles * maxRelativeSlowdownAccepted) { pme_lb->setup.resize(pme_lb->cur + 1); /* Done with scanning, go to stage 1 */ @@ -639,11 +635,11 @@ pme_load_balance(pme_load_balancing_t *pme_lb, { int gridsize_start; - gridsize_start = set->grid[XX]*set->grid[YY]*set->grid[ZZ]; + gridsize_start = set->grid[XX] * set->grid[YY] * set->grid[ZZ]; do { - if (pme_lb->cur+1 < gmx::ssize(pme_lb->setup)) + if (pme_lb->cur + 1 < gmx::ssize(pme_lb->setup)) { /* We had already generated the next setup */ OK = TRUE; @@ -659,8 +655,8 @@ pme_load_balance(pme_load_balancing_t *pme_lb, } } - if (OK && - pme_lb->setup[pme_lb->cur+1].spacing > c_maxSpacingScaling*pme_lb->setup[0].spacing) + if (OK + && pme_lb->setup[pme_lb->cur + 1].spacing > c_maxSpacingScaling * pme_lb->setup[0].spacing) { OK = FALSE; pme_lb->elimited = epmelblimMAXSCALING; @@ -668,8 +664,7 @@ pme_load_balance(pme_load_balancing_t *pme_lb, if (OK && ir.ePBC != epbcNONE) { - OK = (gmx::square(pme_lb->setup[pme_lb->cur+1].rlistOuter) - <= max_cutoff2(ir.ePBC, box)); + OK = (gmx::square(pme_lb->setup[pme_lb->cur + 1].rlistOuter) <= max_cutoff2(ir.ePBC, box)); if (!OK) { pme_lb->elimited = epmelblimBOX; @@ -682,8 +677,7 @@ pme_load_balance(pme_load_balancing_t *pme_lb, if (DOMAINDECOMP(cr)) { - OK = change_dd_cutoff(cr, box, x, - pme_lb->setup[pme_lb->cur].rlistOuter); + OK = change_dd_cutoff(cr, box, x, pme_lb->setup[pme_lb->cur].rlistOuter); if (!OK) { /* Failed: do not use this setup */ @@ -702,15 +696,12 @@ pme_load_balance(pme_load_balancing_t *pme_lb, /* Switch to the next stage */ switch_to_stage1(pme_lb); } - } - while (OK && - !(pme_lb->setup[pme_lb->cur].grid[XX]* - pme_lb->setup[pme_lb->cur].grid[YY]* - pme_lb->setup[pme_lb->cur].grid[ZZ] < - gridsize_start*gridpointsScaleFactor - && - pme_lb->setup[pme_lb->cur].grid_efficiency < - pme_lb->setup[pme_lb->cur-1].grid_efficiency*relativeEfficiencyFactor)); + } while (OK + && !(pme_lb->setup[pme_lb->cur].grid[XX] * pme_lb->setup[pme_lb->cur].grid[YY] + * pme_lb->setup[pme_lb->cur].grid[ZZ] + < gridsize_start * gridpointsScaleFactor + && pme_lb->setup[pme_lb->cur].grid_efficiency + < pme_lb->setup[pme_lb->cur - 1].grid_efficiency * relativeEfficiencyFactor)); } if (pme_lb->stage > 0 && pme_lb->end == 1) @@ -741,10 +732,8 @@ pme_load_balance(pme_load_balancing_t *pme_lb, pme_lb->cur = pme_lb->end - 1; } - } - while (pme_lb->stage == pme_lb->nstage - 1 && - pme_lb->setup[pme_lb->cur].count > 0 && - pme_lb->setup[pme_lb->cur].cycles > cycles_fast*maxRelativeSlowdownAccepted); + } while (pme_lb->stage == pme_lb->nstage - 1 && pme_lb->setup[pme_lb->cur].count > 0 + && pme_lb->setup[pme_lb->cur].cycles > cycles_fast * maxRelativeSlowdownAccepted); if (pme_lb->stage == pme_lb->nstage) { @@ -773,15 +762,19 @@ pme_load_balance(pme_load_balancing_t *pme_lb, /* This should not happen, as we set limits on the DLB bounds. * But we implement a complete failsafe solution anyhow. */ - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "The fastest PP/PME load balancing setting (cutoff %.3d nm) is no longer available due to DD DLB or box size limitations", pme_lb->fastest); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "The fastest PP/PME load balancing setting (cutoff %.3d nm) is no " + "longer available due to DD DLB or box size limitations", + pme_lb->fastest); pme_lb->fastest = pme_lb->lower_limit; pme_lb->start = pme_lb->lower_limit; } /* Limit the range to below the current cut-off, scan from start */ - pme_lb->end = pme_lb->cur; - pme_lb->cur = pme_lb->start; - pme_lb->elimited = epmelblimDD; + pme_lb->end = pme_lb->cur; + pme_lb->cur = pme_lb->start; + pme_lb->elimited = epmelblimDD; print_loadbal_limited(fp_err, fp_log, step, pme_lb); } } @@ -790,28 +783,29 @@ pme_load_balance(pme_load_balancing_t *pme_lb, set = &pme_lb->setup[pme_lb->cur]; - ic->rcoulomb = set->rcut_coulomb; + ic->rcoulomb = set->rcut_coulomb; nbv->changePairlistRadii(set->rlistOuter, set->rlistInner); - ic->ewaldcoeff_q = set->ewaldcoeff_q; + ic->ewaldcoeff_q = set->ewaldcoeff_q; /* TODO: centralize the code that sets the potentials shifts */ if (ic->coulomb_modifier == eintmodPOTSHIFT) { GMX_RELEASE_ASSERT(ic->rcoulomb != 0, "Cutoff radius cannot be zero"); - ic->sh_ewald = std::erfc(ic->ewaldcoeff_q*ic->rcoulomb) / ic->rcoulomb; + ic->sh_ewald = std::erfc(ic->ewaldcoeff_q * ic->rcoulomb) / ic->rcoulomb; } if (EVDW_PME(ic->vdwtype)) { /* We have PME for both Coulomb and VdW, set rvdw equal to rcoulomb */ - ic->rvdw = set->rcut_coulomb; - ic->ewaldcoeff_lj = set->ewaldcoeff_lj; + ic->rvdw = set->rcut_coulomb; + ic->ewaldcoeff_lj = set->ewaldcoeff_lj; if (ic->vdw_modifier == eintmodPOTSHIFT) { - real crc2; + real crc2; - ic->dispersion_shift.cpot = -1.0/gmx::power6(static_cast(ic->rvdw)); - ic->repulsion_shift.cpot = -1.0/gmx::power12(static_cast(ic->rvdw)); - crc2 = gmx::square(ic->ewaldcoeff_lj*ic->rvdw); - ic->sh_lj_ewald = (std::exp(-crc2)*(1 + crc2 + 0.5*crc2*crc2) - 1)/gmx::power6(ic->rvdw); + ic->dispersion_shift.cpot = -1.0 / gmx::power6(static_cast(ic->rvdw)); + ic->repulsion_shift.cpot = -1.0 / gmx::power12(static_cast(ic->rvdw)); + crc2 = gmx::square(ic->ewaldcoeff_lj * ic->rvdw); + ic->sh_lj_ewald = + (std::exp(-crc2) * (1 + crc2 + 0.5 * crc2 * crc2) - 1) / gmx::power6(ic->rvdw); } } @@ -829,14 +823,14 @@ pme_load_balance(pme_load_balancing_t *pme_lb, * This can lead to a lot of reallocations for PME GPU. * Would be nicer if the allocated grid list was hidden within a single pmedata structure. */ - if ((pme_lb->setup[pme_lb->cur].pmedata == nullptr) || pme_gpu_task_enabled(pme_lb->setup[pme_lb->cur].pmedata)) + if ((pme_lb->setup[pme_lb->cur].pmedata == nullptr) + || pme_gpu_task_enabled(pme_lb->setup[pme_lb->cur].pmedata)) { /* Generate a new PME data structure, * copying part of the old pointers. */ - gmx_pme_reinit(&set->pmedata, - cr, pme_lb->setup[0].pmedata, &ir, - set->grid, set->ewaldcoeff_q, set->ewaldcoeff_lj); + gmx_pme_reinit(&set->pmedata, cr, pme_lb->setup[0].pmedata, &ir, set->grid, + set->ewaldcoeff_q, set->ewaldcoeff_lj); } *pmedata = set->pmedata; } @@ -866,35 +860,34 @@ pme_load_balance(pme_load_balancing_t *pme_lb, * the PP/PME balance might change and re-balancing can improve performance. * This function adds 2 stages and adjusts the considered setup range. */ -static void continue_pme_loadbal(pme_load_balancing_t *pme_lb, - gmx_bool bDlbUnlocked) +static void continue_pme_loadbal(pme_load_balancing_t* pme_lb, gmx_bool bDlbUnlocked) { /* Add 2 tuning stages, keep the detected end of the setup range */ - pme_lb->nstage += 2; + pme_lb->nstage += 2; if (bDlbUnlocked && pme_lb->bSepPMERanks) { /* With separate PME ranks, DLB should always lower the PP load and * can only increase the PME load (more communication and imbalance), * so we only need to scan longer cut-off's. */ - pme_lb->lower_limit = pme_lb->cur; + pme_lb->lower_limit = pme_lb->cur; } - pme_lb->start = pme_lb->lower_limit; + pme_lb->start = pme_lb->lower_limit; } -void pme_loadbal_do(pme_load_balancing_t *pme_lb, - t_commrec *cr, - FILE *fp_err, - FILE *fp_log, - const gmx::MDLogger &mdlog, - const t_inputrec &ir, - t_forcerec *fr, +void pme_loadbal_do(pme_load_balancing_t* pme_lb, + t_commrec* cr, + FILE* fp_err, + FILE* fp_log, + const gmx::MDLogger& mdlog, + const t_inputrec& ir, + t_forcerec* fr, const matrix box, gmx::ArrayRef x, gmx_wallcycle_t wcycle, int64_t step, int64_t step_rel, - gmx_bool *bPrinting) + gmx_bool* bPrinting) { int n_prev; double cycles_prev; @@ -937,19 +930,17 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb, * is not over the last nstlist steps, but the nstlist steps before * that. So the first useful ratio is available at step_rel=3*nstlist. */ - else if (step_rel >= 3*ir.nstlist) + else if (step_rel >= 3 * ir.nstlist) { if (DDMASTER(cr->dd)) { /* If PME rank load is too high, start tuning */ - pme_lb->bBalance = - (dd_pme_f_ratio(cr->dd) >= loadBalanceTriggerFactor); + pme_lb->bBalance = (dd_pme_f_ratio(cr->dd) >= loadBalanceTriggerFactor); } dd_bcast(cr->dd, sizeof(gmx_bool), &pme_lb->bBalance); } - pme_lb->bActive = (pme_lb->bBalance || - step_rel <= pme_lb->step_rel_stop); + pme_lb->bActive = (pme_lb->bBalance || step_rel <= pme_lb->step_rel_stop); } /* The location in the code of this balancing termination is strange. @@ -969,14 +960,16 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb, { /* Unlock the DLB=auto, DLB is allowed to activate */ dd_dlb_unlock(cr->dd); - GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB can now turn on, when beneficial"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: DLB can now turn on, when beneficial"); /* We don't deactivate the tuning yet, since we will balance again * after DLB gets turned on, if it does within PMETune_period. */ continue_pme_loadbal(pme_lb, TRUE); pme_lb->bTriggerOnDLB = TRUE; - pme_lb->step_rel_stop = step_rel + PMETunePeriod*ir.nstlist; + pme_lb->step_rel_stop = step_rel + PMETunePeriod * ir.nstlist; } else { @@ -1001,14 +994,11 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb, * since init_step might not be a multiple of nstlist, * but the first data collected is skipped anyhow. */ - pme_load_balance(pme_lb, cr, - fp_err, fp_log, mdlog, - ir, box, x, pme_lb->cycles_c - cycles_prev, - fr->ic, fr->nbv.get(), &fr->pmedata, - step); + pme_load_balance(pme_lb, cr, fp_err, fp_log, mdlog, ir, box, x, + pme_lb->cycles_c - cycles_prev, fr->ic, fr->nbv.get(), &fr->pmedata, step); /* Update deprecated rlist in forcerec to stay in sync with fr->nbv */ - fr->rlist = fr->nbv->pairlistOuterRadius(); + fr->rlist = fr->nbv->pairlistOuterRadius(); if (ir.eDispCorr != edispcNO) { @@ -1016,8 +1006,7 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb, } } - if (!pme_lb->bBalance && - (!pme_lb->bSepPMERanks || step_rel > pme_lb->step_rel_stop)) + if (!pme_lb->bBalance && (!pme_lb->bSepPMERanks || step_rel > pme_lb->step_rel_stop)) { /* We have just deactivated the balancing and we're not measuring PP/PME * imbalance during the first steps of the run: deactivate the tuning. @@ -1029,51 +1018,47 @@ void pme_loadbal_do(pme_load_balancing_t *pme_lb, { /* Make sure DLB is allowed when we deactivate PME tuning */ dd_dlb_unlock(cr->dd); - GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: DLB can now turn on, when beneficial"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: DLB can now turn on, when beneficial"); } *bPrinting = pme_lb->bBalance; } /*! \brief Return product of the number of PME grid points in each dimension */ -static int pme_grid_points(const pme_setup_t *setup) +static int pme_grid_points(const pme_setup_t* setup) { - return setup->grid[XX]*setup->grid[YY]*setup->grid[ZZ]; + return setup->grid[XX] * setup->grid[YY] * setup->grid[ZZ]; } /*! \brief Print one load-balancing setting */ -static void print_pme_loadbal_setting(FILE *fplog, - const char *name, - const pme_setup_t *setup) +static void print_pme_loadbal_setting(FILE* fplog, const char* name, const pme_setup_t* setup) { - fprintf(fplog, - " %-7s %6.3f nm %6.3f nm %3d %3d %3d %5.3f nm %5.3f nm\n", - name, - setup->rcut_coulomb, setup->rlistInner, - setup->grid[XX], setup->grid[YY], setup->grid[ZZ], - setup->spacing, 1/setup->ewaldcoeff_q); + fprintf(fplog, " %-7s %6.3f nm %6.3f nm %3d %3d %3d %5.3f nm %5.3f nm\n", name, + setup->rcut_coulomb, setup->rlistInner, setup->grid[XX], setup->grid[YY], + setup->grid[ZZ], setup->spacing, 1 / setup->ewaldcoeff_q); } /*! \brief Print all load-balancing settings */ -static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb, - FILE *fplog, - const gmx::MDLogger &mdlog, +static void print_pme_loadbal_settings(pme_load_balancing_t* pme_lb, + FILE* fplog, + const gmx::MDLogger& mdlog, gmx_bool bNonBondedOnGPU) { - double pp_ratio, grid_ratio; - real pp_ratio_temporary; + double pp_ratio, grid_ratio; + real pp_ratio_temporary; pp_ratio_temporary = pme_lb->setup[pme_lb->cur].rlistInner / pme_lb->setup[0].rlistInner; pp_ratio = gmx::power3(pp_ratio_temporary); - grid_ratio = pme_grid_points(&pme_lb->setup[pme_lb->cur])/ - static_cast(pme_grid_points(&pme_lb->setup[0])); + grid_ratio = pme_grid_points(&pme_lb->setup[pme_lb->cur]) + / static_cast(pme_grid_points(&pme_lb->setup[0])); fprintf(fplog, "\n"); fprintf(fplog, " P P - P M E L O A D B A L A N C I N G\n"); fprintf(fplog, "\n"); /* Here we only warn when the optimal setting is the last one */ - if (pme_lb->elimited != epmelblimNO && - pme_lb->cur == pme_loadbal_end(pme_lb)-1) + if (pme_lb->elimited != epmelblimNO && pme_lb->cur == pme_loadbal_end(pme_lb) - 1) { fprintf(fplog, " NOTE: The PP/PME load balancing was limited by the %s,\n", pmelblim_str[pme_lb->elimited]); @@ -1089,16 +1074,19 @@ static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb, fprintf(fplog, " rcoulomb rlist grid spacing 1/beta\n"); print_pme_loadbal_setting(fplog, "initial", &pme_lb->setup[0]); print_pme_loadbal_setting(fplog, "final", &pme_lb->setup[pme_lb->cur]); - fprintf(fplog, " cost-ratio %4.2f %4.2f\n", - pp_ratio, grid_ratio); + fprintf(fplog, " cost-ratio %4.2f %4.2f\n", pp_ratio, grid_ratio); fprintf(fplog, " (note that these numbers concern only part of the total PP and PME load)\n"); if (pp_ratio > 1.5 && !bNonBondedOnGPU) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: PME load balancing increased the non-bonded workload by more than 50%.\n" - " For better performance, use (more) PME ranks (mdrun -npme),\n" - " or if you are beyond the scaling limit, use fewer total ranks (or nodes)."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: PME load balancing increased the non-bonded workload by more than " + "50%.\n" + " For better performance, use (more) PME ranks (mdrun -npme),\n" + " or if you are beyond the scaling limit, use fewer total ranks (or " + "nodes)."); } else { @@ -1106,10 +1094,7 @@ static void print_pme_loadbal_settings(pme_load_balancing_t *pme_lb, } } -void pme_loadbal_done(pme_load_balancing_t *pme_lb, - FILE *fplog, - const gmx::MDLogger &mdlog, - gmx_bool bNonBondedOnGPU) +void pme_loadbal_done(pme_load_balancing_t* pme_lb, FILE* fplog, const gmx::MDLogger& mdlog, gmx_bool bNonBondedOnGPU) { if (fplog != nullptr && (pme_lb->cur > 0 || pme_lb->elimited != epmelblimNO)) { diff --git a/src/gromacs/ewald/pme_load_balancing.h b/src/gromacs/ewald/pme_load_balancing.h index 4fc2947d44..929188917a 100644 --- a/src/gromacs/ewald/pme_load_balancing.h +++ b/src/gromacs/ewald/pme_load_balancing.h @@ -58,14 +58,15 @@ class t_state; namespace gmx { class MDLogger; -template class ArrayRef; -} +template +class ArrayRef; +} // namespace gmx /*! \brief Object to manage PME load balancing */ struct pme_load_balancing_t; /*! \brief Return whether PME load balancing is active */ -bool pme_loadbal_is_active(const pme_load_balancing_t *pme_lb); +bool pme_loadbal_is_active(const pme_load_balancing_t* pme_lb); /*! \brief Initialize the PP-PME load balacing data and infrastructure * @@ -75,16 +76,16 @@ bool pme_loadbal_is_active(const pme_load_balancing_t *pme_lb); * The PME grid in pmedata is reused for smaller grids to lower the memory * usage. */ -void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, - t_commrec *cr, - const gmx::MDLogger &mdlog, - const t_inputrec &ir, +void pme_loadbal_init(pme_load_balancing_t** pme_lb_p, + t_commrec* cr, + const gmx::MDLogger& mdlog, + const t_inputrec& ir, const matrix box, - const interaction_const_t &ic, - const nonbonded_verlet_t &nbv, - gmx_pme_t *pmedata, + const interaction_const_t& ic, + const nonbonded_verlet_t& nbv, + gmx_pme_t* pmedata, gmx_bool bUseGPU, - gmx_bool *bPrinting); + gmx_bool* bPrinting); /*! \brief Process cycles and PME load balance when necessary * @@ -93,24 +94,21 @@ void pme_loadbal_init(pme_load_balancing_t **pme_lb_p, * Should be called after the ewcSTEP cycle counter has been stopped. * Returns if the load balancing is printing to fp_err. */ -void pme_loadbal_do(pme_load_balancing_t *pme_lb, - struct t_commrec *cr, - FILE *fp_err, - FILE *fp_log, - const gmx::MDLogger &mdlog, - const t_inputrec &ir, - t_forcerec *fr, +void pme_loadbal_do(pme_load_balancing_t* pme_lb, + struct t_commrec* cr, + FILE* fp_err, + FILE* fp_log, + const gmx::MDLogger& mdlog, + const t_inputrec& ir, + t_forcerec* fr, const matrix box, gmx::ArrayRef x, gmx_wallcycle_t wcycle, int64_t step, int64_t step_rel, - gmx_bool *bPrinting); + gmx_bool* bPrinting); /*! \brief Finish the PME load balancing and print the settings when fplog!=NULL */ -void pme_loadbal_done(pme_load_balancing_t *pme_lb, - FILE *fplog, - const gmx::MDLogger &mdlog, - gmx_bool bNonBondedOnGPU); +void pme_loadbal_done(pme_load_balancing_t* pme_lb, FILE* fplog, const gmx::MDLogger& mdlog, gmx_bool bNonBondedOnGPU); #endif diff --git a/src/gromacs/ewald/pme_only.cpp b/src/gromacs/ewald/pme_only.cpp index d6a14be72d..5d99b07139 100644 --- a/src/gromacs/ewald/pme_only.cpp +++ b/src/gromacs/ewald/pme_only.cpp @@ -100,11 +100,12 @@ #include "pme_pp_communication.h" /*! \brief environment variable to enable GPU P2P communication */ -static const bool c_enableGpuPmePpComms = (getenv("GMX_GPU_PME_PP_COMMS") != nullptr) - && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA); +static const bool c_enableGpuPmePpComms = + (getenv("GMX_GPU_PME_PP_COMMS") != nullptr) && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA); /*! \brief Master PP-PME communication data structure */ -struct gmx_pme_pp { +struct gmx_pme_pp +{ MPI_Comm mpi_comm_mysim; /**< MPI communicator for this simulation */ std::vector ppRanks; /**< The PP partner ranks */ int peerRankId; /**< The peer PP rank id */ @@ -117,8 +118,8 @@ struct gmx_pme_pp { std::vector sigmaA; std::vector sigmaB; //@} - gmx::HostVector x; /**< Vector of atom coordinates to transfer to PME ranks */ - std::vector f; /**< Vector of atom forces received from PME ranks */ + gmx::HostVector x; /**< Vector of atom coordinates to transfer to PME ranks */ + std::vector f; /**< Vector of atom forces received from PME ranks */ //@{ /**< Vectors of MPI objects used in non-blocking communication between multiple PP ranks per PME rank */ std::vector req; @@ -128,14 +129,14 @@ struct gmx_pme_pp { /*! \brief object for receiving coordinates using communications operating on GPU memory space */ std::unique_ptr pmeCoordinateReceiverGpu; /*! \brief object for sending PME force using communications operating on GPU memory space */ - std::unique_ptr pmeForceSenderGpu; + std::unique_ptr pmeForceSenderGpu; /*! \brief whether GPU direct communications are active for PME-PP transfers */ bool useGpuDirectComm = false; }; /*! \brief Initialize the PME-only side of the PME <-> PP communication */ -static std::unique_ptr gmx_pme_pp_init(const t_commrec *cr) +static std::unique_ptr gmx_pme_pp_init(const t_commrec* cr) { auto pme_pp = std::make_unique(); @@ -146,14 +147,14 @@ static std::unique_ptr gmx_pme_pp_init(const t_commrec *cr) MPI_Comm_rank(cr->mpi_comm_mygroup, &rank); auto ppRanks = get_pme_ddranks(cr, rank); pme_pp->ppRanks.reserve(ppRanks.size()); - for (const auto &ppRankId : ppRanks) + for (const auto& ppRankId : ppRanks) { - pme_pp->ppRanks.push_back({ppRankId, 0}); + pme_pp->ppRanks.push_back({ ppRankId, 0 }); } // The peer PP rank is the last one. pme_pp->peerRankId = pme_pp->ppRanks.back().rankId; - pme_pp->req.resize(eCommType_NR*pme_pp->ppRanks.size()); - pme_pp->stat.resize(eCommType_NR*pme_pp->ppRanks.size()); + pme_pp->req.resize(eCommType_NR * pme_pp->ppRanks.size()); + pme_pp->stat.resize(eCommType_NR * pme_pp->ppRanks.size()); #else GMX_UNUSED_VALUE(cr); #endif @@ -163,7 +164,7 @@ static std::unique_ptr gmx_pme_pp_init(const t_commrec *cr) static void reset_pmeonly_counters(gmx_wallcycle_t wcycle, gmx_walltime_accounting_t walltime_accounting, - t_nrnb *nrnb, + t_nrnb* nrnb, int64_t step, bool useGpuForPme) { @@ -180,18 +181,18 @@ static void reset_pmeonly_counters(gmx_wallcycle_t wcycle, } } -static gmx_pme_t *gmx_pmeonly_switch(std::vector *pmedata, - const ivec grid_size, - real ewaldcoeff_q, real ewaldcoeff_lj, - const t_commrec *cr, const t_inputrec *ir) +static gmx_pme_t* gmx_pmeonly_switch(std::vector* pmedata, + const ivec grid_size, + real ewaldcoeff_q, + real ewaldcoeff_lj, + const t_commrec* cr, + const t_inputrec* ir) { GMX_ASSERT(pmedata, "Bad PME tuning list pointer"); - for (auto &pme : *pmedata) + for (auto& pme : *pmedata) { GMX_ASSERT(pme, "Bad PME tuning list element pointer"); - if (pme->nkx == grid_size[XX] && - pme->nky == grid_size[YY] && - pme->nkz == grid_size[ZZ]) + if (pme->nkx == grid_size[XX] && pme->nky == grid_size[YY] && pme->nkz == grid_size[ZZ]) { /* Here we have found an existing PME data structure that suits us. * However, in the GPU case, we have to reinitialize it - there's only one GPU structure. @@ -204,8 +205,8 @@ static gmx_pme_t *gmx_pmeonly_switch(std::vector *pmedata, } } - const auto &pme = pmedata->back(); - gmx_pme_t *newStructure = nullptr; + const auto& pme = pmedata->back(); + gmx_pme_t* newStructure = nullptr; // Copy last structure with new grid params gmx_pme_reinit(&newStructure, cr, pme, ir, grid_size, ewaldcoeff_q, ewaldcoeff_lj); pmedata->push_back(newStructure); @@ -222,36 +223,34 @@ static gmx_pme_t *gmx_pmeonly_switch(std::vector *pmedata, * \param[out] maxshift_y Maximum shift in Y direction, if received. * \param[out] lambda_q Free-energy lambda for electrostatics, if received. * \param[out] lambda_lj Free-energy lambda for Lennard-Jones, if received. - * \param[out] bEnerVir Set to true if this is an energy/virial calculation step, otherwise set to false. - * \param[out] step MD integration step number. - * \param[out] grid_size PME grid size, if received. - * \param[out] ewaldcoeff_q Ewald cut-off parameter for electrostatics, if received. - * \param[out] ewaldcoeff_lj Ewald cut-off parameter for Lennard-Jones, if received. - * \param[in] useGpuForPme flag on whether PME is on GPU - * \param[in] stateGpu GPU state propagator object - * \param[in] runMode PME run mode + * \param[out] bEnerVir Set to true if this is an energy/virial calculation step, otherwise + * set to false. \param[out] step MD integration step number. \param[out] grid_size PME + * grid size, if received. \param[out] ewaldcoeff_q Ewald cut-off parameter for + * electrostatics, if received. \param[out] ewaldcoeff_lj Ewald cut-off parameter for + * Lennard-Jones, if received. \param[in] useGpuForPme flag on whether PME is on GPU \param[in] + * stateGpu GPU state propagator object \param[in] runMode PME run mode * * \retval pmerecvqxX All parameters were set, chargeA and chargeB can be NULL. * \retval pmerecvqxFINISH No parameters were set. * \retval pmerecvqxSWITCHGRID Only grid_size and *ewaldcoeff were set. * \retval pmerecvqxRESETCOUNTERS *step was set. */ -static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, - gmx_pme_pp *pme_pp, - int *natoms, +static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t* pme, + gmx_pme_pp* pme_pp, + int* natoms, matrix box, - int *maxshift_x, - int *maxshift_y, - real *lambda_q, - real *lambda_lj, - gmx_bool *bEnerVir, - int64_t *step, - ivec *grid_size, - real *ewaldcoeff_q, - real *ewaldcoeff_lj, + int* maxshift_x, + int* maxshift_y, + real* lambda_q, + real* lambda_lj, + gmx_bool* bEnerVir, + int64_t* step, + ivec* grid_size, + real* ewaldcoeff_q, + real* ewaldcoeff_lj, bool useGpuForPme, - gmx::StatePropagatorDataGpu *stateGpu, - PmeRunMode gmx_unused runMode) + gmx::StatePropagatorDataGpu* stateGpu, + PmeRunMode gmx_unused runMode) { int status = -1; int nat = 0; @@ -267,29 +266,28 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, cnb.flags = 0; /* Receive the send count, box and time step from the peer PP node */ - MPI_Recv(&cnb, sizeof(cnb), MPI_BYTE, - pme_pp->peerRankId, eCommType_CNB, + MPI_Recv(&cnb, sizeof(cnb), MPI_BYTE, pme_pp->peerRankId, eCommType_CNB, pme_pp->mpi_comm_mysim, MPI_STATUS_IGNORE); /* We accumulate all received flags */ flags |= cnb.flags; - *step = cnb.step; + *step = cnb.step; if (debug) { fprintf(debug, "PME only rank receiving:%s%s%s%s%s\n", - (cnb.flags & PP_PME_CHARGE) ? " charges" : "", - (cnb.flags & PP_PME_COORD ) ? " coordinates" : "", - (cnb.flags & PP_PME_FINISH) ? " finish" : "", - (cnb.flags & PP_PME_SWITCHGRID) ? " switch grid" : "", + (cnb.flags & PP_PME_CHARGE) ? " charges" : "", + (cnb.flags & PP_PME_COORD) ? " coordinates" : "", + (cnb.flags & PP_PME_FINISH) ? " finish" : "", + (cnb.flags & PP_PME_SWITCHGRID) ? " switch grid" : "", (cnb.flags & PP_PME_RESETCOUNTERS) ? " reset counters" : ""); } pme_pp->useGpuDirectComm = ((cnb.flags & PP_PME_GPUCOMMS) != 0); GMX_ASSERT(!pme_pp->useGpuDirectComm || (pme_pp->pmeForceSenderGpu != nullptr), "The use of GPU direct communication for PME-PP is enabled, " - "but the PME GPU force reciever object does not exist" ); + "but the PME GPU force reciever object does not exist"); if (cnb.flags & PP_PME_FINISH) { @@ -303,7 +301,7 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, *ewaldcoeff_q = cnb.ewaldcoeff_q; *ewaldcoeff_lj = cnb.ewaldcoeff_lj; - status = pmerecvqxSWITCHGRID; + status = pmerecvqxSWITCHGRID; } if (cnb.flags & PP_PME_RESETCOUNTERS) @@ -317,7 +315,7 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, atomSetChanged = true; /* Receive the send counts from the other PP nodes */ - for (auto &sender : pme_pp->ppRanks) + for (auto& sender : pme_pp->ppRanks) { if (sender.rankId == pme_pp->peerRankId) { @@ -325,17 +323,15 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, } else { - MPI_Irecv(&sender.numAtoms, sizeof(sender.numAtoms), - MPI_BYTE, - sender.rankId, eCommType_CNB, - pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); + MPI_Irecv(&sender.numAtoms, sizeof(sender.numAtoms), MPI_BYTE, sender.rankId, + eCommType_CNB, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); } } MPI_Waitall(messages, pme_pp->req.data(), pme_pp->stat.data()); messages = 0; nat = 0; - for (const auto &sender : pme_pp->ppRanks) + for (const auto& sender : pme_pp->ppRanks) { nat += sender.numAtoms; } @@ -374,40 +370,36 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, /* Receive the charges in place */ for (int q = 0; q < eCommType_NR; q++) { - real *bufferPtr; + real* bufferPtr; - if (!(cnb.flags & (PP_PME_CHARGE<chargeA.data(); break; - case eCommType_ChargeB: bufferPtr = pme_pp->chargeB.data(); break; + case eCommType_ChargeA: bufferPtr = pme_pp->chargeA.data(); break; + case eCommType_ChargeB: bufferPtr = pme_pp->chargeB.data(); break; case eCommType_SQRTC6A: bufferPtr = pme_pp->sqrt_c6A.data(); break; case eCommType_SQRTC6B: bufferPtr = pme_pp->sqrt_c6B.data(); break; - case eCommType_SigmaA: bufferPtr = pme_pp->sigmaA.data(); break; - case eCommType_SigmaB: bufferPtr = pme_pp->sigmaB.data(); break; + case eCommType_SigmaA: bufferPtr = pme_pp->sigmaA.data(); break; + case eCommType_SigmaB: bufferPtr = pme_pp->sigmaB.data(); break; default: gmx_incons("Wrong eCommType"); } nat = 0; - for (const auto &sender : pme_pp->ppRanks) + for (const auto& sender : pme_pp->ppRanks) { if (sender.numAtoms > 0) { - MPI_Irecv(bufferPtr+nat, - sender.numAtoms*sizeof(real), - MPI_BYTE, - sender.rankId, q, - pme_pp->mpi_comm_mysim, - &pme_pp->req[messages++]); + MPI_Irecv(bufferPtr + nat, sender.numAtoms * sizeof(real), MPI_BYTE, + sender.rankId, q, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); nat += sender.numAtoms; if (debug) { - fprintf(debug, "Received from PP rank %d: %d %s\n", - sender.rankId, sender.numAtoms, - (q == eCommType_ChargeA || - q == eCommType_ChargeB) ? "charges" : "params"); + fprintf(debug, "Received from PP rank %d: %d %s\n", sender.rankId, + sender.numAtoms, + (q == eCommType_ChargeA || q == eCommType_ChargeB) ? "charges" + : "params"); } } } @@ -426,16 +418,17 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, } if (pme_pp->useGpuDirectComm) { - GMX_ASSERT(runMode == PmeRunMode::GPU, "GPU Direct PME-PP communication has been enabled, " + GMX_ASSERT(runMode == PmeRunMode::GPU, + "GPU Direct PME-PP communication has been enabled, " "but PME run mode is not PmeRunMode::GPU\n"); // This rank will have its data accessed directly by PP rank, so needs to send the remote addresses. rvec* d_x = nullptr; rvec* d_f = nullptr; -#if (GMX_GPU == GMX_GPU_CUDA) //avoid invalid cast for OpenCL - d_x = reinterpret_cast (pme_gpu_get_device_x(pme)); - d_f = reinterpret_cast (pme_gpu_get_device_f(pme)); -#endif +# if (GMX_GPU == GMX_GPU_CUDA) // avoid invalid cast for OpenCL + d_x = reinterpret_cast(pme_gpu_get_device_x(pme)); + d_f = reinterpret_cast(pme_gpu_get_device_f(pme)); +# endif pme_pp->pmeCoordinateReceiverGpu->sendCoordinateBufferAddressToPpRanks(d_x); pme_pp->pmeForceSenderGpu->sendForceBufferAddressToPpRanks(d_f); } @@ -445,14 +438,14 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, /* The box, FE flag and lambda are sent along with the coordinates * */ copy_mat(cnb.box, box); - *lambda_q = cnb.lambda_q; - *lambda_lj = cnb.lambda_lj; - *bEnerVir = ((cnb.flags & PP_PME_ENER_VIR) != 0U); - *step = cnb.step; + *lambda_q = cnb.lambda_q; + *lambda_lj = cnb.lambda_lj; + *bEnerVir = ((cnb.flags & PP_PME_ENER_VIR) != 0U); + *step = cnb.step; /* Receive the coordinates in place */ nat = 0; - for (const auto &sender : pme_pp->ppRanks) + for (const auto& sender : pme_pp->ppRanks) { if (sender.numAtoms > 0) { @@ -462,16 +455,14 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, } else { - MPI_Irecv(pme_pp->x[nat], - sender.numAtoms*sizeof(rvec), - MPI_BYTE, - sender.rankId, eCommType_COORD, - pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); + MPI_Irecv(pme_pp->x[nat], sender.numAtoms * sizeof(rvec), MPI_BYTE, sender.rankId, + eCommType_COORD, pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); } nat += sender.numAtoms; if (debug) { - fprintf(debug, "Received from PP rank %d: %d " + fprintf(debug, + "Received from PP rank %d: %d " "coordinates\n", sender.rankId, sender.numAtoms); } @@ -484,8 +475,7 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, /* Wait for the coordinates and/or charges to arrive */ MPI_Waitall(messages, pme_pp->req.data(), pme_pp->stat.data()); messages = 0; - } - while (status == -1); + } while (status == -1); #else GMX_UNUSED_VALUE(pme_pp); GMX_UNUSED_VALUE(box); @@ -504,42 +494,42 @@ static int gmx_pme_recv_coeffs_coords(struct gmx_pme_t *pme, if (status == pmerecvqxX) { - *natoms = nat; + *natoms = nat; } return status; } /*! \brief Send force data to PP ranks */ -static void sendFToPP(void* sendbuf, PpRanks receiver, gmx_pme_pp *pme_pp, int *messages) +static void sendFToPP(void* sendbuf, PpRanks receiver, gmx_pme_pp* pme_pp, int* messages) { if (pme_pp->useGpuDirectComm) { GMX_ASSERT((pme_pp->pmeForceSenderGpu != nullptr), "The use of GPU direct communication for PME-PP is enabled, " - "but the PME GPU force reciever object does not exist" ); + "but the PME GPU force reciever object does not exist"); pme_pp->pmeForceSenderGpu->sendFToPpCudaDirect(receiver.rankId); } else { #if GMX_MPI - //Send using MPI - MPI_Isend(sendbuf, receiver.numAtoms*sizeof(rvec), MPI_BYTE, receiver.rankId, - 0, pme_pp->mpi_comm_mysim, &pme_pp->req[*messages]); - *messages = *messages+1; + // Send using MPI + MPI_Isend(sendbuf, receiver.numAtoms * sizeof(rvec), MPI_BYTE, receiver.rankId, 0, + pme_pp->mpi_comm_mysim, &pme_pp->req[*messages]); + *messages = *messages + 1; #endif } - } /*! \brief Send the PME mesh force, virial and energy to the PP-only ranks. */ -static void gmx_pme_send_force_vir_ener(const gmx_pme_t &pme, - gmx_pme_pp *pme_pp, - const PmeOutput &output, - real dvdlambda_q, real dvdlambda_lj, - float cycles) +static void gmx_pme_send_force_vir_ener(const gmx_pme_t& pme, + gmx_pme_pp* pme_pp, + const PmeOutput& output, + real dvdlambda_q, + real dvdlambda_lj, + float cycles) { #if GMX_MPI gmx_pme_comm_vir_ene_t cve; @@ -549,16 +539,16 @@ static void gmx_pme_send_force_vir_ener(const gmx_pme_t &pme, /* Now the evaluated forces have to be transferred to the PP nodes */ messages = 0; ind_end = 0; - for (const auto &receiver : pme_pp->ppRanks) + for (const auto& receiver : pme_pp->ppRanks) { - ind_start = ind_end; - ind_end = ind_start + receiver.numAtoms; - void *sendbuf = const_cast(static_cast(output.forces_[ind_start])); + ind_start = ind_end; + ind_end = ind_start + receiver.numAtoms; + void* sendbuf = const_cast(static_cast(output.forces_[ind_start])); if (pme_pp->useGpuDirectComm) { - //Data will be transferred directly from GPU. - rvec* d_f = reinterpret_cast (pme_gpu_get_device_f(&pme)); - sendbuf = reinterpret_cast (&d_f[ind_start]); + // Data will be transferred directly from GPU. + rvec* d_f = reinterpret_cast(pme_gpu_get_device_f(&pme)); + sendbuf = reinterpret_cast(&d_f[ind_start]); } sendFToPP(sendbuf, receiver, pme_pp, &messages); } @@ -577,12 +567,10 @@ static void gmx_pme_send_force_vir_ener(const gmx_pme_t &pme, if (debug) { - fprintf(debug, "PME rank sending to PP rank %d: virial and energy\n", - pme_pp->peerRankId); + fprintf(debug, "PME rank sending to PP rank %d: virial and energy\n", pme_pp->peerRankId); } - MPI_Isend(&cve, sizeof(cve), MPI_BYTE, - pme_pp->peerRankId, 1, - pme_pp->mpi_comm_mysim, &pme_pp->req[messages++]); + MPI_Isend(&cve, sizeof(cve), MPI_BYTE, pme_pp->peerRankId, 1, pme_pp->mpi_comm_mysim, + &pme_pp->req[messages++]); /* Wait for the forces to arrive */ MPI_Waitall(messages, pme_pp->req.data(), pme_pp->stat.data()); @@ -596,48 +584,46 @@ static void gmx_pme_send_force_vir_ener(const gmx_pme_t &pme, #endif } -int gmx_pmeonly(struct gmx_pme_t *pme, - const t_commrec *cr, t_nrnb *mynrnb, - gmx_wallcycle *wcycle, +int gmx_pmeonly(struct gmx_pme_t* pme, + const t_commrec* cr, + t_nrnb* mynrnb, + gmx_wallcycle* wcycle, gmx_walltime_accounting_t walltime_accounting, - t_inputrec *ir, PmeRunMode runMode) + t_inputrec* ir, + PmeRunMode runMode) { - int ret; - int natoms = 0; - matrix box; - real lambda_q = 0; - real lambda_lj = 0; - int maxshift_x = 0, maxshift_y = 0; - real dvdlambda_q, dvdlambda_lj; - float cycles; - int count; - gmx_bool bEnerVir = FALSE; - int64_t step; + int ret; + int natoms = 0; + matrix box; + real lambda_q = 0; + real lambda_lj = 0; + int maxshift_x = 0, maxshift_y = 0; + real dvdlambda_q, dvdlambda_lj; + float cycles; + int count; + gmx_bool bEnerVir = FALSE; + int64_t step; /* This data will only use with PME tuning, i.e. switching PME grids */ - std::vector pmedata; + std::vector pmedata; pmedata.push_back(pme); - auto pme_pp = gmx_pme_pp_init(cr); - //TODO the variable below should be queried from the task assignment info - const bool useGpuForPme = (runMode == PmeRunMode::GPU) || (runMode == PmeRunMode::Mixed); - const void *commandStream = useGpuForPme ? pme_gpu_get_device_stream(pme) : nullptr; - const void *deviceContext = useGpuForPme ? pme_gpu_get_device_context(pme) : nullptr; - const int paddingSize = pme_gpu_get_padding_size(pme); + auto pme_pp = gmx_pme_pp_init(cr); + // TODO the variable below should be queried from the task assignment info + const bool useGpuForPme = (runMode == PmeRunMode::GPU) || (runMode == PmeRunMode::Mixed); + const void* commandStream = useGpuForPme ? pme_gpu_get_device_stream(pme) : nullptr; + const void* deviceContext = useGpuForPme ? pme_gpu_get_device_context(pme) : nullptr; + const int paddingSize = pme_gpu_get_padding_size(pme); if (useGpuForPme) { changePinningPolicy(&pme_pp->chargeA, pme_get_pinning_policy()); changePinningPolicy(&pme_pp->x, pme_get_pinning_policy()); if (c_enableGpuPmePpComms) { - pme_pp->pmeCoordinateReceiverGpu = - std::make_unique(pme_gpu_get_device_stream(pme), - pme_pp->mpi_comm_mysim, - pme_pp->ppRanks); - pme_pp->pmeForceSenderGpu = - std::make_unique(pme_gpu_get_device_stream(pme), - pme_pp->mpi_comm_mysim, - pme_pp->ppRanks); + pme_pp->pmeCoordinateReceiverGpu = std::make_unique( + pme_gpu_get_device_stream(pme), pme_pp->mpi_comm_mysim, pme_pp->ppRanks); + pme_pp->pmeForceSenderGpu = std::make_unique( + pme_gpu_get_device_stream(pme), pme_pp->mpi_comm_mysim, pme_pp->ppRanks); } } @@ -646,7 +632,8 @@ int gmx_pmeonly(struct gmx_pme_t *pme, { // TODO: Special PME-only constructor is used here. There is no mechanism to prevent from using the other constructor here. // This should be made safer. - stateGpu = std::make_unique(commandStream, deviceContext, GpuApiCallBehavior::Async, paddingSize); + stateGpu = std::make_unique( + commandStream, deviceContext, GpuApiCallBehavior::Async, paddingSize); } @@ -660,21 +647,11 @@ int gmx_pmeonly(struct gmx_pme_t *pme, { /* Domain decomposition */ ivec newGridSize; - real ewaldcoeff_q = 0, ewaldcoeff_lj = 0; - ret = gmx_pme_recv_coeffs_coords(pme, - pme_pp.get(), - &natoms, - box, - &maxshift_x, &maxshift_y, - &lambda_q, &lambda_lj, - &bEnerVir, - &step, - &newGridSize, - &ewaldcoeff_q, - &ewaldcoeff_lj, - useGpuForPme, - stateGpu.get(), - runMode); + real ewaldcoeff_q = 0, ewaldcoeff_lj = 0; + ret = gmx_pme_recv_coeffs_coords(pme, pme_pp.get(), &natoms, box, &maxshift_x, + &maxshift_y, &lambda_q, &lambda_lj, &bEnerVir, &step, + &newGridSize, &ewaldcoeff_q, &ewaldcoeff_lj, + useGpuForPme, stateGpu.get(), runMode); if (ret == pmerecvqxSWITCHGRID) { @@ -687,8 +664,7 @@ int gmx_pmeonly(struct gmx_pme_t *pme, /* Reset the cycle and flop counters */ reset_pmeonly_counters(wcycle, walltime_accounting, mynrnb, step, useGpuForPme); } - } - while (ret == pmerecvqxSWITCHGRID || ret == pmerecvqxRESETCOUNTERS); + } while (ret == pmerecvqxSWITCHGRID || ret == pmerecvqxRESETCOUNTERS); if (ret == pmerecvqxFINISH) { @@ -717,7 +693,7 @@ int gmx_pmeonly(struct gmx_pme_t *pme, { const bool boxChanged = false; const bool useGpuPmeForceReduction = pme_pp->useGpuDirectComm; - //TODO this should be set properly by gmx_pme_recv_coeffs_coords, + // TODO this should be set properly by gmx_pme_recv_coeffs_coords, // or maybe use inputrecDynamicBox(ir), at the very least - change this when this codepath is tested! pme_gpu_prepare_computation(pme, boxChanged, box, wcycle, pmeFlags, useGpuPmeForceReduction); if (!pme_pp->useGpuDirectComm) @@ -736,23 +712,20 @@ int gmx_pmeonly(struct gmx_pme_t *pme, } else { - GMX_ASSERT(pme_pp->x.size() == static_cast(natoms), "The coordinate buffer should have size natoms"); - - gmx_pme_do(pme, pme_pp->x, pme_pp->f, - pme_pp->chargeA.data(), pme_pp->chargeB.data(), - pme_pp->sqrt_c6A.data(), pme_pp->sqrt_c6B.data(), - pme_pp->sigmaA.data(), pme_pp->sigmaB.data(), box, - cr, maxshift_x, maxshift_y, mynrnb, wcycle, - output.coulombVirial_, output.lennardJonesVirial_, - &output.coulombEnergy_, &output.lennardJonesEnergy_, - lambda_q, lambda_lj, &dvdlambda_q, &dvdlambda_lj, - pmeFlags); + GMX_ASSERT(pme_pp->x.size() == static_cast(natoms), + "The coordinate buffer should have size natoms"); + + gmx_pme_do(pme, pme_pp->x, pme_pp->f, pme_pp->chargeA.data(), pme_pp->chargeB.data(), + pme_pp->sqrt_c6A.data(), pme_pp->sqrt_c6B.data(), pme_pp->sigmaA.data(), + pme_pp->sigmaB.data(), box, cr, maxshift_x, maxshift_y, mynrnb, wcycle, + output.coulombVirial_, output.lennardJonesVirial_, &output.coulombEnergy_, + &output.lennardJonesEnergy_, lambda_q, lambda_lj, &dvdlambda_q, + &dvdlambda_lj, pmeFlags); output.forces_ = pme_pp->f; } cycles = wallcycle_stop(wcycle, ewcPMEMESH); - gmx_pme_send_force_vir_ener(*pme, pme_pp.get(), output, - dvdlambda_q, dvdlambda_lj, cycles); + gmx_pme_send_force_vir_ener(*pme, pme_pp.get(), output, dvdlambda_q, dvdlambda_lj, cycles); count++; } /***** end of quasi-loop, we stop with the break above */ diff --git a/src/gromacs/ewald/pme_pp.cpp b/src/gromacs/ewald/pme_pp.cpp index cbf6781b10..fd9de7ed5f 100644 --- a/src/gromacs/ewald/pme_pp.cpp +++ b/src/gromacs/ewald/pme_pp.cpp @@ -80,7 +80,7 @@ static constexpr bool c_useDelayedWait = false; /*! \brief Wait for the pending data send requests to PME ranks to complete */ -static void gmx_pme_send_coeffs_coords_wait(gmx_domdec_t *dd) +static void gmx_pme_send_coeffs_coords_wait(gmx_domdec_t* dd) { if (dd->nreq_pme) { @@ -92,20 +92,29 @@ static void gmx_pme_send_coeffs_coords_wait(gmx_domdec_t *dd) } /*! \brief Send data to PME ranks */ -static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsigned int flags, - real gmx_unused *chargeA, real gmx_unused *chargeB, - real gmx_unused *c6A, real gmx_unused *c6B, - real gmx_unused *sigmaA, real gmx_unused *sigmaB, - const matrix box, const rvec gmx_unused *x, - real lambda_q, real lambda_lj, - int maxshift_x, int maxshift_y, - int64_t step, bool useGpuPmePpComms, - bool reinitGpuPmePpComms, - bool sendCoordinatesFromGpu, - GpuEventSynchronizer *coordinatesReadyOnDeviceEvent) +static void gmx_pme_send_coeffs_coords(t_forcerec* fr, + const t_commrec* cr, + unsigned int flags, + real gmx_unused* chargeA, + real gmx_unused* chargeB, + real gmx_unused* c6A, + real gmx_unused* c6B, + real gmx_unused* sigmaA, + real gmx_unused* sigmaB, + const matrix box, + const rvec gmx_unused* x, + real lambda_q, + real lambda_lj, + int maxshift_x, + int maxshift_y, + int64_t step, + bool useGpuPmePpComms, + bool reinitGpuPmePpComms, + bool sendCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) { - gmx_domdec_t *dd; - gmx_pme_comm_n_box_t *cnb; + gmx_domdec_t* dd; + gmx_pme_comm_n_box_t* cnb; int n; dd = cr->dd; @@ -113,12 +122,9 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi if (debug) { - fprintf(debug, "PP rank %d sending to PME rank %d: %d%s%s%s%s\n", - cr->sim_nodeid, dd->pme_nodeid, n, - (flags & PP_PME_CHARGE) ? " charges" : "", - (flags & PP_PME_SQRTC6) ? " sqrtC6" : "", - (flags & PP_PME_SIGMA) ? " sigma" : "", - (flags & PP_PME_COORD) ? " coordinates" : ""); + fprintf(debug, "PP rank %d sending to PME rank %d: %d%s%s%s%s\n", cr->sim_nodeid, dd->pme_nodeid, + n, (flags & PP_PME_CHARGE) ? " charges" : "", (flags & PP_PME_SQRTC6) ? " sqrtC6" : "", + (flags & PP_PME_SIGMA) ? " sigma" : "", (flags & PP_PME_COORD) ? " coordinates" : ""); } if (useGpuPmePpComms) @@ -153,8 +159,7 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi copy_mat(box, cnb->box); } #if GMX_MPI - MPI_Isend(cnb, sizeof(*cnb), MPI_BYTE, - dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim, + MPI_Isend(cnb, sizeof(*cnb), MPI_BYTE, dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); #endif } @@ -162,8 +167,7 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi { #if GMX_MPI /* Communicate only the number of atoms */ - MPI_Isend(&n, sizeof(n), MPI_BYTE, - dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim, + MPI_Isend(&n, sizeof(n), MPI_BYTE, dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); #endif } @@ -173,39 +177,33 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi { if (flags & PP_PME_CHARGE) { - MPI_Isend(chargeA, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_ChargeA, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(chargeA, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_ChargeA, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_CHARGEB) { - MPI_Isend(chargeB, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_ChargeB, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(chargeB, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_ChargeB, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_SQRTC6) { - MPI_Isend(c6A, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_SQRTC6A, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(c6A, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SQRTC6A, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_SQRTC6B) { - MPI_Isend(c6B, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_SQRTC6B, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(c6B, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SQRTC6B, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_SIGMA) { - MPI_Isend(sigmaA, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_SigmaA, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(sigmaA, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SigmaA, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_SIGMAB) { - MPI_Isend(sigmaB, n*sizeof(real), MPI_BYTE, - dd->pme_nodeid, eCommType_SigmaB, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(sigmaB, n * sizeof(real), MPI_BYTE, dd->pme_nodeid, eCommType_SigmaB, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } if (flags & PP_PME_COORD) { @@ -216,18 +214,19 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi /* MPI_Isend does not accept a const buffer pointer */ - real *xRealPtr = const_cast(x[0]); + real* xRealPtr = const_cast(x[0]); if (useGpuPmePpComms && (fr != nullptr)) { - void *sendPtr = sendCoordinatesFromGpu ? static_cast (fr->stateGpu->getCoordinates()) : - static_cast (xRealPtr); - fr->pmePpCommGpu->sendCoordinatesToPmeCudaDirect(sendPtr, n, sendCoordinatesFromGpu, coordinatesReadyOnDeviceEvent); + void* sendPtr = sendCoordinatesFromGpu + ? static_cast(fr->stateGpu->getCoordinates()) + : static_cast(xRealPtr); + fr->pmePpCommGpu->sendCoordinatesToPmeCudaDirect(sendPtr, n, sendCoordinatesFromGpu, + coordinatesReadyOnDeviceEvent); } else { - MPI_Isend(xRealPtr, n*sizeof(rvec), MPI_BYTE, - dd->pme_nodeid, eCommType_COORD, cr->mpi_comm_mysim, - &dd->req_pme[dd->nreq_pme++]); + MPI_Isend(xRealPtr, n * sizeof(rvec), MPI_BYTE, dd->pme_nodeid, eCommType_COORD, + cr->mpi_comm_mysim, &dd->req_pme[dd->nreq_pme++]); } } } @@ -243,13 +242,18 @@ static void gmx_pme_send_coeffs_coords(t_forcerec *fr, const t_commrec *cr, unsi } } -void gmx_pme_send_parameters(const t_commrec *cr, - const interaction_const_t *ic, - gmx_bool bFreeEnergy_q, gmx_bool bFreeEnergy_lj, - real *chargeA, real *chargeB, - real *sqrt_c6A, real *sqrt_c6B, - real *sigmaA, real *sigmaB, - int maxshift_x, int maxshift_y) +void gmx_pme_send_parameters(const t_commrec* cr, + const interaction_const_t* ic, + gmx_bool bFreeEnergy_q, + gmx_bool bFreeEnergy_lj, + real* chargeA, + real* chargeB, + real* sqrt_c6A, + real* sqrt_c6B, + real* sigmaA, + real* sigmaB, + int maxshift_x, + int maxshift_y) { unsigned int flags = 0; @@ -268,19 +272,24 @@ void gmx_pme_send_parameters(const t_commrec *cr, flags |= (flags << 1); } - gmx_pme_send_coeffs_coords(nullptr, cr, flags, - chargeA, chargeB, - sqrt_c6A, sqrt_c6B, sigmaA, sigmaB, - nullptr, nullptr, 0, 0, maxshift_x, maxshift_y, -1, false, false, false, nullptr); + gmx_pme_send_coeffs_coords(nullptr, cr, flags, chargeA, chargeB, sqrt_c6A, sqrt_c6B, sigmaA, + sigmaB, nullptr, nullptr, 0, 0, maxshift_x, maxshift_y, -1, false, + false, false, nullptr); } -void gmx_pme_send_coordinates(t_forcerec *fr, const t_commrec *cr, const matrix box, const rvec *x, - real lambda_q, real lambda_lj, - gmx_bool bEnerVir, - int64_t step, bool useGpuPmePpComms, - bool receiveCoordinateAddressFromPme, - bool sendCoordinatesFromGpu, - GpuEventSynchronizer *coordinatesReadyOnDeviceEvent, gmx_wallcycle *wcycle) +void gmx_pme_send_coordinates(t_forcerec* fr, + const t_commrec* cr, + const matrix box, + const rvec* x, + real lambda_q, + real lambda_lj, + gmx_bool bEnerVir, + int64_t step, + bool useGpuPmePpComms, + bool receiveCoordinateAddressFromPme, + bool sendCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent, + gmx_wallcycle* wcycle) { wallcycle_start(wcycle, ewcPP_PMESENDX); @@ -290,23 +299,22 @@ void gmx_pme_send_coordinates(t_forcerec *fr, const t_commrec *cr, const matrix flags |= PP_PME_ENER_VIR; } gmx_pme_send_coeffs_coords(fr, cr, flags, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - box, x, lambda_q, lambda_lj, 0, 0, step, useGpuPmePpComms, receiveCoordinateAddressFromPme, - sendCoordinatesFromGpu, coordinatesReadyOnDeviceEvent); + box, x, lambda_q, lambda_lj, 0, 0, step, useGpuPmePpComms, + receiveCoordinateAddressFromPme, sendCoordinatesFromGpu, + coordinatesReadyOnDeviceEvent); wallcycle_stop(wcycle, ewcPP_PMESENDX); } -void gmx_pme_send_finish(const t_commrec *cr) +void gmx_pme_send_finish(const t_commrec* cr) { unsigned int flags = PP_PME_FINISH; - gmx_pme_send_coeffs_coords(nullptr, cr, flags, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0, 0, 0, 0, -1, false, false, false, nullptr); + gmx_pme_send_coeffs_coords(nullptr, cr, flags, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, 0, 0, 0, 0, -1, false, false, false, nullptr); } -void gmx_pme_send_switchgrid(const t_commrec *cr, - ivec grid_size, - real ewaldcoeff_q, - real ewaldcoeff_lj) +void gmx_pme_send_switchgrid(const t_commrec* cr, ivec grid_size, real ewaldcoeff_q, real ewaldcoeff_lj) { #if GMX_MPI gmx_pme_comm_n_box_t cnb; @@ -320,8 +328,7 @@ void gmx_pme_send_switchgrid(const t_commrec *cr, cnb.ewaldcoeff_lj = ewaldcoeff_lj; /* We send this, uncommon, message blocking to simplify the code */ - MPI_Send(&cnb, sizeof(cnb), MPI_BYTE, - cr->dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim); + MPI_Send(&cnb, sizeof(cnb), MPI_BYTE, cr->dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim); } #else GMX_UNUSED_VALUE(cr); @@ -331,7 +338,7 @@ void gmx_pme_send_switchgrid(const t_commrec *cr, #endif } -void gmx_pme_send_resetcounters(const t_commrec gmx_unused *cr, int64_t gmx_unused step) +void gmx_pme_send_resetcounters(const t_commrec gmx_unused* cr, int64_t gmx_unused step) { #if GMX_MPI gmx_pme_comm_n_box_t cnb; @@ -343,18 +350,19 @@ void gmx_pme_send_resetcounters(const t_commrec gmx_unused *cr, int64_t gmx_unus cnb.step = step; /* We send this, uncommon, message blocking to simplify the code */ - MPI_Send(&cnb, sizeof(cnb), MPI_BYTE, - cr->dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim); + MPI_Send(&cnb, sizeof(cnb), MPI_BYTE, cr->dd->pme_nodeid, eCommType_CNB, cr->mpi_comm_mysim); } #endif } /*! \brief Receive virial and energy from PME rank */ -static void receive_virial_energy(const t_commrec *cr, - gmx::ForceWithVirial *forceWithVirial, - real *energy_q, real *energy_lj, - real *dvdlambda_q, real *dvdlambda_lj, - float *pme_cycles) +static void receive_virial_energy(const t_commrec* cr, + gmx::ForceWithVirial* forceWithVirial, + real* energy_q, + real* energy_lj, + real* dvdlambda_q, + real* dvdlambda_lj, + float* pme_cycles) { gmx_pme_comm_vir_ene_t cve; @@ -362,24 +370,22 @@ static void receive_virial_energy(const t_commrec *cr, { if (debug) { - fprintf(debug, - "PP rank %d receiving from PME rank %d: virial and energy\n", + fprintf(debug, "PP rank %d receiving from PME rank %d: virial and energy\n", cr->sim_nodeid, cr->dd->pme_nodeid); } #if GMX_MPI - MPI_Recv(&cve, sizeof(cve), MPI_BYTE, cr->dd->pme_nodeid, 1, cr->mpi_comm_mysim, - MPI_STATUS_IGNORE); + MPI_Recv(&cve, sizeof(cve), MPI_BYTE, cr->dd->pme_nodeid, 1, cr->mpi_comm_mysim, MPI_STATUS_IGNORE); #else memset(&cve, 0, sizeof(cve)); #endif forceWithVirial->addVirialContribution(cve.vir_q); forceWithVirial->addVirialContribution(cve.vir_lj); - *energy_q = cve.energy_q; - *energy_lj = cve.energy_lj; - *dvdlambda_q += cve.dvdlambda_q; + *energy_q = cve.energy_q; + *energy_lj = cve.energy_lj; + *dvdlambda_q += cve.dvdlambda_q; *dvdlambda_lj += cve.dvdlambda_lj; - *pme_cycles = cve.cycles; + *pme_cycles = cve.cycles; if (cve.stop_cond != gmx_stop_cond_none) { @@ -395,38 +401,40 @@ static void receive_virial_energy(const t_commrec *cr, } /*! \brief Recieve force data from PME ranks */ -static void recvFFromPme(gmx::PmePpCommGpu *pmePpCommGpu, - void * recvptr, +static void recvFFromPme(gmx::PmePpCommGpu* pmePpCommGpu, + void* recvptr, int n, - const t_commrec *cr, + const t_commrec* cr, bool useGpuPmePpComms, bool receivePmeForceToGpu) { if (useGpuPmePpComms) { GMX_ASSERT(pmePpCommGpu != nullptr, "Need valid pmePpCommGpu"); - //Receive directly using CUDA memory copy + // Receive directly using CUDA memory copy pmePpCommGpu->receiveForceFromPmeCudaDirect(recvptr, n, receivePmeForceToGpu); } else { - //Receive data using MPI + // Receive data using MPI #if GMX_MPI - MPI_Recv(recvptr, n*sizeof(rvec), MPI_BYTE, - cr->dd->pme_nodeid, 0, cr->mpi_comm_mysim, + MPI_Recv(recvptr, n * sizeof(rvec), MPI_BYTE, cr->dd->pme_nodeid, 0, cr->mpi_comm_mysim, MPI_STATUS_IGNORE); #endif } } -void gmx_pme_receive_f(gmx::PmePpCommGpu *pmePpCommGpu, - const t_commrec *cr, - gmx::ForceWithVirial *forceWithVirial, - real *energy_q, real *energy_lj, - real *dvdlambda_q, real *dvdlambda_lj, - bool useGpuPmePpComms, bool receivePmeForceToGpu, - float *pme_cycles) +void gmx_pme_receive_f(gmx::PmePpCommGpu* pmePpCommGpu, + const t_commrec* cr, + gmx::ForceWithVirial* forceWithVirial, + real* energy_q, + real* energy_lj, + real* dvdlambda_q, + real* dvdlambda_lj, + bool useGpuPmePpComms, + bool receivePmeForceToGpu, + float* pme_cycles) { if (c_useDelayedWait) { @@ -435,10 +443,10 @@ void gmx_pme_receive_f(gmx::PmePpCommGpu *pmePpCommGpu, } const int natoms = dd_numHomeAtoms(*cr->dd); - std::vector &buffer = cr->dd->pmeForceReceiveBuffer; + std::vector& buffer = cr->dd->pmeForceReceiveBuffer; buffer.resize(natoms); - void *recvptr = reinterpret_cast(buffer.data()); + void* recvptr = reinterpret_cast(buffer.data()); recvFFromPme(pmePpCommGpu, recvptr, natoms, cr, useGpuPmePpComms, receivePmeForceToGpu); int nt = gmx_omp_nthreads_get_simple_rvec_task(emntDefault, natoms); diff --git a/src/gromacs/ewald/pme_pp_comm_gpu.h b/src/gromacs/ewald/pme_pp_comm_gpu.h index b58125513e..e9d8c4ff69 100644 --- a/src/gromacs/ewald/pme_pp_comm_gpu.h +++ b/src/gromacs/ewald/pme_pp_comm_gpu.h @@ -57,51 +57,53 @@ namespace gmx class PmePpCommGpu { - public: - /*! \brief Creates PME-PP GPU communication object - * \param[in] comm Communicator used for simulation - * \param[in] pmeRank Rank of PME task - */ - PmePpCommGpu(MPI_Comm comm, int pmeRank); - ~PmePpCommGpu(); +public: + /*! \brief Creates PME-PP GPU communication object + * \param[in] comm Communicator used for simulation + * \param[in] pmeRank Rank of PME task + */ + PmePpCommGpu(MPI_Comm comm, int pmeRank); + ~PmePpCommGpu(); - /*! \brief Perform steps required when buffer size changes - * \param[in] size Number of elements in buffer - */ - void reinit(int size); + /*! \brief Perform steps required when buffer size changes + * \param[in] size Number of elements in buffer + */ + void reinit(int size); - /*! \brief - * Pull data from PME GPU directly using CUDA Memory copy. - * \param[out] recvPtr Buffer to receive PME force data - * \param[in] recvSize Number of elements to receive - * \param[in] recvPmeForceToGpu Whether receive is to GPU, otherwise CPU - */ - void receiveForceFromPmeCudaDirect(void *recvPtr, int recvSize, bool recvPmeForceToGpu); + /*! \brief + * Pull data from PME GPU directly using CUDA Memory copy. + * \param[out] recvPtr Buffer to receive PME force data + * \param[in] recvSize Number of elements to receive + * \param[in] recvPmeForceToGpu Whether receive is to GPU, otherwise CPU + */ + void receiveForceFromPmeCudaDirect(void* recvPtr, int recvSize, bool recvPmeForceToGpu); - /*! \brief Push coordinates buffer directly to GPU memory on PME task - * \param[in] sendPtr Buffer with coordinate data - * \param[in] sendSize Number of elements to send - * \param[in] sendPmeCoordinatesFromGpu Whether send is from GPU, otherwise CPU - * \param[in] coordinatesReadyOnDeviceEvent Event recorded when coordinates are available on device - */ - void sendCoordinatesToPmeCudaDirect(void *sendPtr, int sendSize, bool sendPmeCoordinatesFromGpu, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); + /*! \brief Push coordinates buffer directly to GPU memory on PME task + * \param[in] sendPtr Buffer with coordinate data + * \param[in] sendSize Number of elements to send + * \param[in] sendPmeCoordinatesFromGpu Whether send is from GPU, otherwise CPU + * \param[in] coordinatesReadyOnDeviceEvent Event recorded when coordinates are available on device + */ + void sendCoordinatesToPmeCudaDirect(void* sendPtr, + int sendSize, + bool sendPmeCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); - /*! \brief - * Return pointer to buffer used for staging PME force on GPU - */ - void* getGpuForceStagingPtr(); + /*! \brief + * Return pointer to buffer used for staging PME force on GPU + */ + void* getGpuForceStagingPtr(); - /*! \brief - * Return pointer to event recorded when forces are ready - */ - void* getForcesReadySynchronizer(); - - private: - class Impl; - gmx::PrivateImplPointer impl_; + /*! \brief + * Return pointer to event recorded when forces are ready + */ + void* getForcesReadySynchronizer(); +private: + class Impl; + gmx::PrivateImplPointer impl_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp b/src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp old mode 100755 new mode 100644 index 5324343a8e..0b59ff9212 --- a/src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp +++ b/src/gromacs/ewald/pme_pp_comm_gpu_impl.cpp @@ -62,10 +62,11 @@ class PmePpCommGpu::Impl }; /*!\brief Constructor stub. */ -PmePpCommGpu::PmePpCommGpu(MPI_Comm gmx_unused comm, int gmx_unused pmeRank) - : impl_(nullptr) +PmePpCommGpu::PmePpCommGpu(MPI_Comm gmx_unused comm, int gmx_unused pmeRank) : impl_(nullptr) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } PmePpCommGpu::~PmePpCommGpu() = default; @@ -73,31 +74,46 @@ PmePpCommGpu::~PmePpCommGpu() = default; /*!\brief init PME-PP GPU communication stub */ void PmePpCommGpu::reinit(int gmx_unused size) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication initialization was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication initialization was called instead of the " + "correct implementation."); } -void PmePpCommGpu::receiveForceFromPmeCudaDirect(void gmx_unused *recvPtr, int gmx_unused recvSize, bool gmx_unused receivePmeForceToGpu) +void PmePpCommGpu::receiveForceFromPmeCudaDirect(void gmx_unused* recvPtr, + int gmx_unused recvSize, + bool gmx_unused receivePmeForceToGpu) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } -void PmePpCommGpu::sendCoordinatesToPmeCudaDirect(void gmx_unused *sendPtr, int gmx_unused sendSize, bool gmx_unused sendPmeCoordinatesFromGpu, GpuEventSynchronizer gmx_unused *coordinatesOnDeviceEvent) +void PmePpCommGpu::sendCoordinatesToPmeCudaDirect(void gmx_unused* sendPtr, + int gmx_unused sendSize, + bool gmx_unused sendPmeCoordinatesFromGpu, + GpuEventSynchronizer gmx_unused* coordinatesOnDeviceEvent) { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); } void* PmePpCommGpu::getGpuForceStagingPtr() { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); return nullptr; } void* PmePpCommGpu::getForcesReadySynchronizer() { - GMX_ASSERT(false, "A CPU stub for PME-PP GPU communication was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for PME-PP GPU communication was called instead of the correct " + "implementation."); return nullptr; } -} // namespace gmx +} // namespace gmx #endif /* GMX_GPU != GMX_GPU_CUDA */ diff --git a/src/gromacs/ewald/pme_pp_comm_gpu_impl.cu b/src/gromacs/ewald/pme_pp_comm_gpu_impl.cu index 621f18893f..9a87e951e5 100644 --- a/src/gromacs/ewald/pme_pp_comm_gpu_impl.cu +++ b/src/gromacs/ewald/pme_pp_comm_gpu_impl.cu @@ -55,11 +55,11 @@ namespace gmx { -PmePpCommGpu::Impl::Impl(MPI_Comm comm, int pmeRank) - : comm_(comm), - pmeRank_(pmeRank) +PmePpCommGpu::Impl::Impl(MPI_Comm comm, int pmeRank) : comm_(comm), pmeRank_(pmeRank) { - GMX_RELEASE_ASSERT(GMX_THREAD_MPI, "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); + GMX_RELEASE_ASSERT( + GMX_THREAD_MPI, + "PME-PP GPU Communication is currently only supported with thread-MPI enabled"); cudaStreamCreate(&pmePpCommStream_); } @@ -68,10 +68,8 @@ PmePpCommGpu::Impl::~Impl() = default; void PmePpCommGpu::Impl::reinit(int size) { // This rank will access PME rank memory directly, so needs to receive the remote PME buffer addresses. - MPI_Recv(&remotePmeXBuffer_, sizeof(void**), MPI_BYTE, pmeRank_, - 0, comm_, MPI_STATUS_IGNORE); - MPI_Recv(&remotePmeFBuffer_, sizeof(void**), MPI_BYTE, pmeRank_, - 0, comm_, MPI_STATUS_IGNORE); + MPI_Recv(&remotePmeXBuffer_, sizeof(void**), MPI_BYTE, pmeRank_, 0, comm_, MPI_STATUS_IGNORE); + MPI_Recv(&remotePmeFBuffer_, sizeof(void**), MPI_BYTE, pmeRank_, 0, comm_, MPI_STATUS_IGNORE); // Reallocate buffer used for staging PME force on GPU reallocateDeviceBuffer(&d_pmeForces_, size, &d_pmeForcesSize_, &d_pmeForcesSizeAlloc_, nullptr); @@ -81,22 +79,19 @@ void PmePpCommGpu::Impl::reinit(int size) // TODO make this asynchronous by splitting into this into // launchRecvForceFromPmeCudaDirect() and sycnRecvForceFromPmeCudaDirect() -void PmePpCommGpu::Impl::receiveForceFromPmeCudaDirect(void *recvPtr, int recvSize, bool receivePmeForceToGpu) +void PmePpCommGpu::Impl::receiveForceFromPmeCudaDirect(void* recvPtr, int recvSize, bool receivePmeForceToGpu) { // Receive event from PME task and add to stream, to ensure pull of data doesn't // occur before PME force calc is completed - GpuEventSynchronizer *pmeSync; - MPI_Recv(&pmeSync, sizeof(GpuEventSynchronizer*), - MPI_BYTE, pmeRank_, 0, - comm_, MPI_STATUS_IGNORE); + GpuEventSynchronizer* pmeSync; + MPI_Recv(&pmeSync, sizeof(GpuEventSynchronizer*), MPI_BYTE, pmeRank_, 0, comm_, MPI_STATUS_IGNORE); pmeSync->enqueueWaitEvent(pmePpCommStream_); // Pull force data from remote GPU - void * pmeForcePtr = receivePmeForceToGpu ? static_cast (d_pmeForces_) : recvPtr; - cudaError_t stat = cudaMemcpyAsync(pmeForcePtr, remotePmeFBuffer_, - recvSize*DIM*sizeof(float), cudaMemcpyDefault, - pmePpCommStream_); + void* pmeForcePtr = receivePmeForceToGpu ? static_cast(d_pmeForces_) : recvPtr; + cudaError_t stat = cudaMemcpyAsync(pmeForcePtr, remotePmeFBuffer_, recvSize * DIM * sizeof(float), + cudaMemcpyDefault, pmePpCommStream_); CU_RET_ERR(stat, "cudaMemcpyAsync on Recv from PME CUDA direct data transfer failed"); if (receivePmeForceToGpu) @@ -114,39 +109,35 @@ void PmePpCommGpu::Impl::receiveForceFromPmeCudaDirect(void *recvPtr, int recvSi } } -void PmePpCommGpu::Impl::sendCoordinatesToPmeCudaDirect(void *sendPtr, int sendSize, bool gmx_unused sendPmeCoordinatesFromGpu, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) +void PmePpCommGpu::Impl::sendCoordinatesToPmeCudaDirect(void* sendPtr, + int sendSize, + bool gmx_unused sendPmeCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) { - //ensure stream waits until coordinate data is available on device + // ensure stream waits until coordinate data is available on device coordinatesReadyOnDeviceEvent->enqueueWaitEvent(pmePpCommStream_); - cudaError_t stat = cudaMemcpyAsync(remotePmeXBuffer_, sendPtr, - sendSize*DIM*sizeof(float), cudaMemcpyDefault, - pmePpCommStream_); + cudaError_t stat = cudaMemcpyAsync(remotePmeXBuffer_, sendPtr, sendSize * DIM * sizeof(float), + cudaMemcpyDefault, pmePpCommStream_); CU_RET_ERR(stat, "cudaMemcpyAsync on Send to PME CUDA direct data transfer failed"); // Record and send event to allow PME task to sync to above transfer before commencing force calculations pmeCoordinatesSynchronizer_.markEvent(pmePpCommStream_); - GpuEventSynchronizer *pmeSync = &pmeCoordinatesSynchronizer_; - MPI_Send(&pmeSync, sizeof(GpuEventSynchronizer*), - MPI_BYTE, pmeRank_, 0, - comm_); - + GpuEventSynchronizer* pmeSync = &pmeCoordinatesSynchronizer_; + MPI_Send(&pmeSync, sizeof(GpuEventSynchronizer*), MPI_BYTE, pmeRank_, 0, comm_); } void* PmePpCommGpu::Impl::getGpuForceStagingPtr() { - return static_cast (d_pmeForces_); + return static_cast(d_pmeForces_); } void* PmePpCommGpu::Impl::getForcesReadySynchronizer() { - return static_cast (&forcesReadySynchronizer_); + return static_cast(&forcesReadySynchronizer_); } -PmePpCommGpu::PmePpCommGpu(MPI_Comm comm, int pmeRank) - : impl_(new Impl(comm, pmeRank)) -{ -} +PmePpCommGpu::PmePpCommGpu(MPI_Comm comm, int pmeRank) : impl_(new Impl(comm, pmeRank)) {} PmePpCommGpu::~PmePpCommGpu() = default; @@ -155,14 +146,18 @@ void PmePpCommGpu::reinit(int size) impl_->reinit(size); } -void PmePpCommGpu::receiveForceFromPmeCudaDirect(void *recvPtr, int recvSize, bool receivePmeForceToGpu) +void PmePpCommGpu::receiveForceFromPmeCudaDirect(void* recvPtr, int recvSize, bool receivePmeForceToGpu) { impl_->receiveForceFromPmeCudaDirect(recvPtr, recvSize, receivePmeForceToGpu); } -void PmePpCommGpu::sendCoordinatesToPmeCudaDirect(void *sendPtr, int sendSize, bool sendPmeCoordinatesFromGpu, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) +void PmePpCommGpu::sendCoordinatesToPmeCudaDirect(void* sendPtr, + int sendSize, + bool sendPmeCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent) { - impl_->sendCoordinatesToPmeCudaDirect(sendPtr, sendSize, sendPmeCoordinatesFromGpu, coordinatesReadyOnDeviceEvent); + impl_->sendCoordinatesToPmeCudaDirect(sendPtr, sendSize, sendPmeCoordinatesFromGpu, + coordinatesReadyOnDeviceEvent); } void* PmePpCommGpu::getGpuForceStagingPtr() @@ -175,4 +170,4 @@ void* PmePpCommGpu::getForcesReadySynchronizer() return impl_->getForcesReadySynchronizer(); } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/ewald/pme_pp_comm_gpu_impl.h b/src/gromacs/ewald/pme_pp_comm_gpu_impl.h index be408acbf4..5565bea370 100644 --- a/src/gromacs/ewald/pme_pp_comm_gpu_impl.h +++ b/src/gromacs/ewald/pme_pp_comm_gpu_impl.h @@ -55,83 +55,86 @@ namespace gmx class PmePpCommGpu::Impl { - public: - /*! \brief Creates PME-PP GPU communication object. - * \param[in] comm Communicator used for simulation - * \param[in] pmeRank Rank of PME task - */ - Impl(MPI_Comm comm, int pmeRank); - ~Impl(); +public: + /*! \brief Creates PME-PP GPU communication object. + * \param[in] comm Communicator used for simulation + * \param[in] pmeRank Rank of PME task + */ + Impl(MPI_Comm comm, int pmeRank); + ~Impl(); - /*! \brief Perform steps required when buffer size changes - * \param[in] size Number of elements in buffer - */ - void reinit(int size); + /*! \brief Perform steps required when buffer size changes + * \param[in] size Number of elements in buffer + */ + void reinit(int size); - /*! \brief Pull force buffer directly from GPU memory on PME - * rank to either GPU or CPU memory on PP task using CUDA - * Memory copy. - * - * recvPtr should be in GPU or CPU memory if recvPmeForceToGpu - * is true or false, respectively. If receiving to GPU, this - * method should be called before the local GPU buffer - * operations. If receiving to CPU it should be called - * before forces are reduced with the other force - * contributions on the CPU. It will automatically wait for - * remote PME force data to be ready. - * - * \param[out] recvPtr CPU buffer to receive PME force data - * \param[in] recvSize Number of elements to receive - * \param[in] receivePmeForceToGpu Whether receive is to GPU, otherwise CPU - */ - void receiveForceFromPmeCudaDirect(void *recvPtr, int recvSize, bool receivePmeForceToGpu); + /*! \brief Pull force buffer directly from GPU memory on PME + * rank to either GPU or CPU memory on PP task using CUDA + * Memory copy. + * + * recvPtr should be in GPU or CPU memory if recvPmeForceToGpu + * is true or false, respectively. If receiving to GPU, this + * method should be called before the local GPU buffer + * operations. If receiving to CPU it should be called + * before forces are reduced with the other force + * contributions on the CPU. It will automatically wait for + * remote PME force data to be ready. + * + * \param[out] recvPtr CPU buffer to receive PME force data + * \param[in] recvSize Number of elements to receive + * \param[in] receivePmeForceToGpu Whether receive is to GPU, otherwise CPU + */ + void receiveForceFromPmeCudaDirect(void* recvPtr, int recvSize, bool receivePmeForceToGpu); - /*! \brief Push coordinates buffer directly to GPU memory on PME - * task, from either GPU or CPU memory on PP task using CUDA - * Memory copy. sendPtr should be in GPU or CPU memory if - * sendPmeCoordinatesFromGpu is true or false respectively. If - * sending from GPU, this method should be called after the - * local GPU coordinate buffer operations. The remote PME task will - * automatically wait for data to be copied before commencing PME force calculations. - * \param[in] sendPtr Buffer with coordinate data - * \param[in] sendSize Number of elements to send - * \param[in] sendPmeCoordinatesFromGpu Whether send is from GPU, otherwise CPU - * \param[in] coordinatesReadyOnDeviceEvent Event recorded when coordinates are available on device - */ - void sendCoordinatesToPmeCudaDirect(void *sendPtr, int sendSize, bool sendPmeCoordinatesFromGpu, GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); + /*! \brief Push coordinates buffer directly to GPU memory on PME + * task, from either GPU or CPU memory on PP task using CUDA + * Memory copy. sendPtr should be in GPU or CPU memory if + * sendPmeCoordinatesFromGpu is true or false respectively. If + * sending from GPU, this method should be called after the + * local GPU coordinate buffer operations. The remote PME task will + * automatically wait for data to be copied before commencing PME force calculations. + * \param[in] sendPtr Buffer with coordinate data + * \param[in] sendSize Number of elements to send + * \param[in] sendPmeCoordinatesFromGpu Whether send is from GPU, otherwise CPU + * \param[in] coordinatesReadyOnDeviceEvent Event recorded when coordinates are available on device + */ + void sendCoordinatesToPmeCudaDirect(void* sendPtr, + int sendSize, + bool sendPmeCoordinatesFromGpu, + GpuEventSynchronizer* coordinatesReadyOnDeviceEvent); - /*! \brief - * Return pointer to buffer used for staging PME force on GPU - */ - void* getGpuForceStagingPtr(); + /*! \brief + * Return pointer to buffer used for staging PME force on GPU + */ + void* getGpuForceStagingPtr(); - /*! \brief - * Return pointer to event recorded when forces are ready - */ - void* getForcesReadySynchronizer(); + /*! \brief + * Return pointer to event recorded when forces are ready + */ + void* getForcesReadySynchronizer(); - private: - //! CUDA stream used for the communication operations in this class - cudaStream_t pmePpCommStream_ = nullptr; - //! Remote location of PME coordinate data buffer - void *remotePmeXBuffer_ = nullptr; - //! Remote location of PME force data buffer - void *remotePmeFBuffer_ = nullptr; - //! communicator for simulation - MPI_Comm comm_; - //! Rank of PME task - int pmeRank_ = -1; - //! Buffer for staging PME force on GPU - rvec *d_pmeForces_ = nullptr; - //! number of atoms in PME force staging array - int d_pmeForcesSize_ = -1; - //! number of atoms allocated in recvbuf array - int d_pmeForcesSizeAlloc_ = -1; - //! Event recorded when PME forces are ready on PME task - GpuEventSynchronizer forcesReadySynchronizer_; - //! Event recorded when coordinates have been transferred to PME task - GpuEventSynchronizer pmeCoordinatesSynchronizer_; +private: + //! CUDA stream used for the communication operations in this class + cudaStream_t pmePpCommStream_ = nullptr; + //! Remote location of PME coordinate data buffer + void* remotePmeXBuffer_ = nullptr; + //! Remote location of PME force data buffer + void* remotePmeFBuffer_ = nullptr; + //! communicator for simulation + MPI_Comm comm_; + //! Rank of PME task + int pmeRank_ = -1; + //! Buffer for staging PME force on GPU + rvec* d_pmeForces_ = nullptr; + //! number of atoms in PME force staging array + int d_pmeForcesSize_ = -1; + //! number of atoms allocated in recvbuf array + int d_pmeForcesSizeAlloc_ = -1; + //! Event recorded when PME forces are ready on PME task + GpuEventSynchronizer forcesReadySynchronizer_; + //! Event recorded when coordinates have been transferred to PME task + GpuEventSynchronizer pmeCoordinatesSynchronizer_; }; } // namespace gmx diff --git a/src/gromacs/ewald/pme_pp_communication.h b/src/gromacs/ewald/pme_pp_communication.h index 972bb283a9..3ba294d17d 100644 --- a/src/gromacs/ewald/pme_pp_communication.h +++ b/src/gromacs/ewald/pme_pp_communication.h @@ -51,9 +51,16 @@ #include "gromacs/utility/real.h" /*! \brief MPI Tags used to separate communication of different types of quantities */ -enum { - eCommType_ChargeA, eCommType_ChargeB, eCommType_SQRTC6A, eCommType_SQRTC6B, - eCommType_SigmaA, eCommType_SigmaB, eCommType_NR, eCommType_COORD, +enum +{ + eCommType_ChargeA, + eCommType_ChargeB, + eCommType_SQRTC6A, + eCommType_SQRTC6B, + eCommType_SigmaA, + eCommType_SigmaB, + eCommType_NR, + eCommType_COORD, eCommType_CNB }; @@ -64,22 +71,23 @@ enum { * that the six first flags are exactly in this order. */ -#define PP_PME_CHARGE (1<<0) -#define PP_PME_CHARGEB (1<<1) -#define PP_PME_SQRTC6 (1<<2) -#define PP_PME_SQRTC6B (1<<3) -#define PP_PME_SIGMA (1<<4) -#define PP_PME_SIGMAB (1<<5) -#define PP_PME_COORD (1<<6) -#define PP_PME_ENER_VIR (1<<9) -#define PP_PME_FINISH (1<<10) -#define PP_PME_SWITCHGRID (1<<11) -#define PP_PME_RESETCOUNTERS (1<<12) -#define PP_PME_GPUCOMMS (1<<13) +#define PP_PME_CHARGE (1 << 0) +#define PP_PME_CHARGEB (1 << 1) +#define PP_PME_SQRTC6 (1 << 2) +#define PP_PME_SQRTC6B (1 << 3) +#define PP_PME_SIGMA (1 << 4) +#define PP_PME_SIGMAB (1 << 5) +#define PP_PME_COORD (1 << 6) +#define PP_PME_ENER_VIR (1 << 9) +#define PP_PME_FINISH (1 << 10) +#define PP_PME_SWITCHGRID (1 << 11) +#define PP_PME_RESETCOUNTERS (1 << 12) +#define PP_PME_GPUCOMMS (1 << 13) //@} /*! \brief Return values for gmx_pme_recv_q_x */ -enum { +enum +{ pmerecvqxX, /* calculate PME mesh interactions for new x */ pmerecvqxFINISH, /* the simulation should finish, we should quit */ pmerecvqxSWITCHGRID, /* change the PME grid size */ @@ -94,19 +102,19 @@ enum { */ struct gmx_pme_comm_n_box_t { - int natoms; /**< Number of atoms */ - matrix box; /**< Box */ - int maxshift_x; /**< Maximum shift in x direction */ - int maxshift_y; /**< Maximum shift in y direction */ - real lambda_q; /**< Free-energy lambda for electrostatics */ - real lambda_lj; /**< Free-energy lambda for Lennard-Jones */ - unsigned int flags; /**< Control flags */ - int64_t step; /**< MD integration step number */ + int natoms; /**< Number of atoms */ + matrix box; /**< Box */ + int maxshift_x; /**< Maximum shift in x direction */ + int maxshift_y; /**< Maximum shift in y direction */ + real lambda_q; /**< Free-energy lambda for electrostatics */ + real lambda_lj; /**< Free-energy lambda for Lennard-Jones */ + unsigned int flags; /**< Control flags */ + int64_t step; /**< MD integration step number */ //@{ /*! \brief Used in PME grid tuning */ - ivec grid_size; - real ewaldcoeff_q; - real ewaldcoeff_lj; + ivec grid_size; + real ewaldcoeff_q; + real ewaldcoeff_lj; //@} }; @@ -120,13 +128,13 @@ struct gmx_pme_comm_vir_ene_t { //@{ /*! \brief Virial, energy, and derivative of potential w.r.t. lambda for charge and Lennard-Jones */ - matrix vir_q; - matrix vir_lj; - real energy_q; - real energy_lj; - real dvdlambda_q; - real dvdlambda_lj; + matrix vir_q; + matrix vir_lj; + real energy_q; + real energy_lj; + real dvdlambda_q; + real dvdlambda_lj; //@} - float cycles; /**< Counter of CPU cycles used */ - gmx_stop_cond_t stop_cond; /**< Flag used in responding to an external signal to terminate */ + float cycles; /**< Counter of CPU cycles used */ + gmx_stop_cond_t stop_cond; /**< Flag used in responding to an external signal to terminate */ }; diff --git a/src/gromacs/ewald/pme_program.cl b/src/gromacs/ewald/pme_program.cl index 58fa2c6c31..493fb5f8f2 100644 --- a/src/gromacs/ewald/pme_program.cl +++ b/src/gromacs/ewald/pme_program.cl @@ -57,7 +57,7 @@ /* SPREAD/SPLINE */ -#define atomsPerBlock (c_spreadWorkGroupSize / threadsPerAtom) +#define atomsPerBlock (c_spreadWorkGroupSize / threadsPerAtom) // spline/spread fused #define computeSplines 1 diff --git a/src/gromacs/ewald/pme_redistribute.cpp b/src/gromacs/ewald/pme_redistribute.cpp index 11258fd0ad..d06e44921d 100644 --- a/src/gromacs/ewald/pme_redistribute.cpp +++ b/src/gromacs/ewald/pme_redistribute.cpp @@ -62,16 +62,14 @@ #include "pme_internal.h" //! Calculate the slab indices and store in \p atc, store counts in \p count -static void pme_calc_pidx(int start, int end, - const matrix recipbox, const rvec x[], - PmeAtomComm *atc, int *count) +static void pme_calc_pidx(int start, int end, const matrix recipbox, const rvec x[], PmeAtomComm* atc, int* count) { int nslab, i; int si; - const real *xptr; + const real* xptr; real s; real rxx, ryx, rzx, ryy, rzy; - int *pd; + int* pd; /* Calculate PME task index (pidx) for each grid index. * Here we always assign equally sized slabs to each node @@ -95,10 +93,10 @@ static void pme_calc_pidx(int start, int end, /* Calculate the node index in x-dimension */ for (i = start; i < end; i++) { - xptr = x[i]; + xptr = x[i]; /* Fractional coordinates along box vectors */ - s = nslab*(xptr[XX]*rxx + xptr[YY]*ryx + xptr[ZZ]*rzx); - si = static_cast(s + 2*nslab) % nslab; + s = nslab * (xptr[XX] * rxx + xptr[YY] * ryx + xptr[ZZ] * rzx); + si = static_cast(s + 2 * nslab) % nslab; pd[i] = si; count[si]++; } @@ -110,10 +108,10 @@ static void pme_calc_pidx(int start, int end, /* Calculate the node index in y-dimension */ for (i = start; i < end; i++) { - xptr = x[i]; + xptr = x[i]; /* Fractional coordinates along box vectors */ - s = nslab*(xptr[YY]*ryy + xptr[ZZ]*rzy); - si = static_cast(s + 2*nslab) % nslab; + s = nslab * (xptr[YY] * ryy + xptr[ZZ] * rzy); + si = static_cast(s + 2 * nslab) % nslab; pd[i] = si; count[si]++; } @@ -121,9 +119,7 @@ static void pme_calc_pidx(int start, int end, } //! Wrapper function for calculating slab indices, stored in \p atc -static void pme_calc_pidx_wrapper(gmx::ArrayRef x, - const matrix recipbox, - PmeAtomComm *atc) +static void pme_calc_pidx_wrapper(gmx::ArrayRef x, const matrix recipbox, PmeAtomComm* atc) { int nthread = atc->nthread; @@ -133,12 +129,10 @@ static void pme_calc_pidx_wrapper(gmx::ArrayRef x, try { const int natoms = x.ssize(); - pme_calc_pidx(natoms* thread /nthread, - natoms*(thread+1)/nthread, - recipbox, as_rvec_array(x.data()), - atc, atc->count_thread[thread].data()); + pme_calc_pidx(natoms * thread / nthread, natoms * (thread + 1) / nthread, recipbox, + as_rvec_array(x.data()), atc, atc->count_thread[thread].data()); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Non-parallel reduction, since nslab is small */ @@ -162,18 +156,16 @@ void SplineCoefficients::realloc(const int nalloc) bufferY_.resize(nalloc); coefficients[YY] = bufferY_.data(); /* In z we add padding, this is only required for the aligned 4-wide SIMD code */ - bufferZ_.resize(nalloc + 2*padding); + bufferZ_.resize(nalloc + 2 * padding); coefficients[ZZ] = bufferZ_.data() + padding; } #endif // !DOXYGEN //! Reallocates all buffers in \p spline to fit atoms in \p atc -static void pme_realloc_splinedata(splinedata_t *spline, - const PmeAtomComm *atc) +static void pme_realloc_splinedata(splinedata_t* spline, const PmeAtomComm* atc) { - if (spline->nalloc >= atc->x.ssize() && - spline->nalloc >= atc->numAtoms()) + if (spline->nalloc >= atc->x.ssize() && spline->nalloc >= atc->numAtoms()) { return; } @@ -186,8 +178,8 @@ static void pme_realloc_splinedata(splinedata_t *spline, spline->ind[i] = i; } - spline->theta.realloc(atc->pme_order*spline->nalloc); - spline->dtheta.realloc(atc->pme_order*spline->nalloc); + spline->theta.realloc(atc->pme_order * spline->nalloc); + spline->dtheta.realloc(atc->pme_order * spline->nalloc); } #ifndef DOXYGEN @@ -212,7 +204,7 @@ void PmeAtomComm::setNumAtoms(const int numAtoms) { coefficientBuffer.reserve(1); } - coefficient = coefficientBuffer; + coefficient = coefficientBuffer; const int nalloc_old = fBuffer.size(); fBuffer.resize(numAtoms_); for (int i = nalloc_old; i < numAtoms_; i++) @@ -241,10 +233,13 @@ void PmeAtomComm::setNumAtoms(const int numAtoms) #endif // !DOXYGEN //! Communicates buffers between rank separated by \p shift slabs -static void pme_dd_sendrecv(PmeAtomComm gmx_unused *atc, - gmx_bool gmx_unused bBackward, int gmx_unused shift, - void gmx_unused *buf_s, int gmx_unused nbyte_s, - void gmx_unused *buf_r, int gmx_unused nbyte_r) +static void pme_dd_sendrecv(PmeAtomComm gmx_unused* atc, + gmx_bool gmx_unused bBackward, + int gmx_unused shift, + void gmx_unused* buf_s, + int gmx_unused nbyte_s, + void gmx_unused* buf_r, + int gmx_unused nbyte_r) { #if GMX_MPI int dest, src; @@ -263,54 +258,49 @@ static void pme_dd_sendrecv(PmeAtomComm gmx_unused *atc, if (nbyte_s > 0 && nbyte_r > 0) { - MPI_Sendrecv(buf_s, nbyte_s, MPI_BYTE, - dest, shift, - buf_r, nbyte_r, MPI_BYTE, - src, shift, + MPI_Sendrecv(buf_s, nbyte_s, MPI_BYTE, dest, shift, buf_r, nbyte_r, MPI_BYTE, src, shift, atc->mpi_comm, &stat); } else if (nbyte_s > 0) { - MPI_Send(buf_s, nbyte_s, MPI_BYTE, - dest, shift, - atc->mpi_comm); + MPI_Send(buf_s, nbyte_s, MPI_BYTE, dest, shift, atc->mpi_comm); } else if (nbyte_r > 0) { - MPI_Recv(buf_r, nbyte_r, MPI_BYTE, - src, shift, - atc->mpi_comm, &stat); + MPI_Recv(buf_r, nbyte_r, MPI_BYTE, src, shift, atc->mpi_comm, &stat); } #endif } //! Redistristributes \p data and optionally coordinates between MPI ranks -static void dd_pmeredist_pos_coeffs(gmx_pme_t *pme, - const gmx_bool bX, - gmx::ArrayRef x, - const real *data, - PmeAtomComm *atc) +static void dd_pmeredist_pos_coeffs(gmx_pme_t* pme, + const gmx_bool bX, + gmx::ArrayRef x, + const real* data, + PmeAtomComm* atc) { - int nnodes_comm, i, local_pos, buf_pos, node; + int nnodes_comm, i, local_pos, buf_pos, node; - nnodes_comm = std::min(2*atc->maxshift, atc->nslab-1); + nnodes_comm = std::min(2 * atc->maxshift, atc->nslab - 1); auto sendCount = atc->sendCount(); int nsend = 0; for (i = 0; i < nnodes_comm; i++) { - const int commnode = atc->slabCommSetup[i].node_dest; - atc->slabCommSetup[commnode].buf_index = nsend; - nsend += sendCount[commnode]; + const int commnode = atc->slabCommSetup[i].node_dest; + atc->slabCommSetup[commnode].buf_index = nsend; + nsend += sendCount[commnode]; } if (bX) { if (sendCount[atc->nodeid] + nsend != x.ssize()) { - gmx_fatal(FARGS, "%zd particles communicated to PME rank %d are more than 2/3 times the cut-off out of the domain decomposition cell of their charge group in dimension %c.\n" - "This usually means that your system is not well equilibrated.", - x.ssize() - (sendCount[atc->nodeid] + nsend), - pme->nodeid, 'x'+atc->dimind); + gmx_fatal( + FARGS, + "%zd particles communicated to PME rank %d are more than 2/3 times the cut-off " + "out of the domain decomposition cell of their charge group in dimension %c.\n" + "This usually means that your system is not well equilibrated.", + x.ssize() - (sendCount[atc->nodeid] + nsend), pme->nodeid, 'x' + atc->dimind); } if (nsend > pme->buf_nalloc) @@ -328,12 +318,11 @@ static void dd_pmeredist_pos_coeffs(gmx_pme_t *pme, /* Communicate the count */ if (debug) { - fprintf(debug, "dimind %d PME rank %d send to rank %d: %d\n", - atc->dimind, atc->nodeid, commnode, scount); + fprintf(debug, "dimind %d PME rank %d send to rank %d: %d\n", atc->dimind, + atc->nodeid, commnode, scount); } - pme_dd_sendrecv(atc, FALSE, i, - &scount, sizeof(int), - &atc->slabCommSetup[i].rcount, sizeof(int)); + pme_dd_sendrecv(atc, FALSE, i, &scount, sizeof(int), &atc->slabCommSetup[i].rcount, + sizeof(int)); numAtoms += atc->slabCommSetup[i].rcount; } @@ -357,7 +346,7 @@ static void dd_pmeredist_pos_coeffs(gmx_pme_t *pme, else { /* Copy to the send buffer */ - int &buf_index = atc->slabCommSetup[node].buf_index; + int& buf_index = atc->slabCommSetup[node].buf_index; if (bX) { copy_rvec(x[i], pme->bufv[buf_index]); @@ -377,27 +366,23 @@ static void dd_pmeredist_pos_coeffs(gmx_pme_t *pme, if (bX) { /* Communicate the coordinates */ - pme_dd_sendrecv(atc, FALSE, i, - pme->bufv[buf_pos], scount*sizeof(rvec), - atc->xBuffer[local_pos], rcount*sizeof(rvec)); + pme_dd_sendrecv(atc, FALSE, i, pme->bufv[buf_pos], scount * sizeof(rvec), + atc->xBuffer[local_pos], rcount * sizeof(rvec)); } /* Communicate the coefficients */ - pme_dd_sendrecv(atc, FALSE, i, - pme->bufr+buf_pos, scount*sizeof(real), - atc->coefficientBuffer.data() + local_pos, rcount*sizeof(real)); - buf_pos += scount; + pme_dd_sendrecv(atc, FALSE, i, pme->bufr + buf_pos, scount * sizeof(real), + atc->coefficientBuffer.data() + local_pos, rcount * sizeof(real)); + buf_pos += scount; local_pos += atc->slabCommSetup[i].rcount; } } } -void dd_pmeredist_f(struct gmx_pme_t *pme, PmeAtomComm *atc, - gmx::ArrayRef f, - gmx_bool bAddF) +void dd_pmeredist_f(struct gmx_pme_t* pme, PmeAtomComm* atc, gmx::ArrayRef f, gmx_bool bAddF) { - int nnodes_comm, local_pos, buf_pos, i, node; + int nnodes_comm, local_pos, buf_pos, i, node; - nnodes_comm = std::min(2*atc->maxshift, atc->nslab-1); + nnodes_comm = std::min(2 * atc->maxshift, atc->nslab - 1); local_pos = atc->sendCount()[atc->nodeid]; buf_pos = 0; @@ -409,13 +394,12 @@ void dd_pmeredist_f(struct gmx_pme_t *pme, PmeAtomComm *atc, if (scount > 0 || rcount > 0) { /* Communicate the forces */ - pme_dd_sendrecv(atc, TRUE, i, - atc->f[local_pos], scount*sizeof(rvec), - pme->bufv[buf_pos], rcount*sizeof(rvec)); + pme_dd_sendrecv(atc, TRUE, i, atc->f[local_pos], scount * sizeof(rvec), + pme->bufv[buf_pos], rcount * sizeof(rvec)); local_pos += scount; } - atc->slabCommSetup[commnode].buf_index = buf_pos; - buf_pos += rcount; + atc->slabCommSetup[commnode].buf_index = buf_pos; + buf_pos += rcount; } local_pos = 0; @@ -459,14 +443,16 @@ void dd_pmeredist_f(struct gmx_pme_t *pme, PmeAtomComm *atc, } } -void -do_redist_pos_coeffs(struct gmx_pme_t *pme, const t_commrec *cr, - gmx_bool bFirst, gmx::ArrayRef x, const real *data) +void do_redist_pos_coeffs(struct gmx_pme_t* pme, + const t_commrec* cr, + gmx_bool bFirst, + gmx::ArrayRef x, + const real* data) { for (int d = pme->ndecompdim - 1; d >= 0; d--) { - gmx::ArrayRef xRef; - const real *param_d; + gmx::ArrayRef xRef; + const real* param_d; if (d == pme->ndecompdim - 1) { /* Start out with the local coordinates and charges */ @@ -476,11 +462,11 @@ do_redist_pos_coeffs(struct gmx_pme_t *pme, const t_commrec *cr, else { /* Redistribute the data collected along the previous dimension */ - const PmeAtomComm &atc = pme->atc[d + 1]; + const PmeAtomComm& atc = pme->atc[d + 1]; xRef = atc.x; param_d = atc.coefficient.data(); } - PmeAtomComm &atc = pme->atc[d]; + PmeAtomComm& atc = pme->atc[d]; atc.pd.resize(xRef.size()); pme_calc_pidx_wrapper(xRef, pme->recipbox, &atc); /* Redistribute x (only once) and qA/c6A or qB/c6B */ diff --git a/src/gromacs/ewald/pme_redistribute.h b/src/gromacs/ewald/pme_redistribute.h index aa630b15b3..975b298d16 100644 --- a/src/gromacs/ewald/pme_redistribute.h +++ b/src/gromacs/ewald/pme_redistribute.h @@ -47,14 +47,13 @@ #include "pme_internal.h" //! Redistributes forces along the dimension gives by \p atc -void -dd_pmeredist_f(struct gmx_pme_t *pme, PmeAtomComm *atc, - gmx::ArrayRef f, - gmx_bool bAddF); +void dd_pmeredist_f(struct gmx_pme_t* pme, PmeAtomComm* atc, gmx::ArrayRef f, gmx_bool bAddF); //! Redistributes coefficients and when \p bFirst=true coordinates over MPI ranks -void -do_redist_pos_coeffs(struct gmx_pme_t *pme, const t_commrec *cr, - gmx_bool bFirst, gmx::ArrayRef x, const real *data); +void do_redist_pos_coeffs(struct gmx_pme_t* pme, + const t_commrec* cr, + gmx_bool bFirst, + gmx::ArrayRef x, + const real* data); #endif diff --git a/src/gromacs/ewald/pme_simd.h b/src/gromacs/ewald/pme_simd.h index 2e4475e346..03c03dfdd9 100644 --- a/src/gromacs/ewald/pme_simd.h +++ b/src/gromacs/ewald/pme_simd.h @@ -54,17 +54,17 @@ #endif #ifdef PME_SIMD4_SPREAD_GATHER -# define SIMD4_ALIGNMENT (GMX_SIMD4_WIDTH*sizeof(real)) +# define SIMD4_ALIGNMENT (GMX_SIMD4_WIDTH * sizeof(real)) #else /* We can use any alignment, apart from 0, so we use 4 reals */ -# define SIMD4_ALIGNMENT (4*sizeof(real)) +# define SIMD4_ALIGNMENT (4 * sizeof(real)) #endif /* Check if we can use SIMD with packs of 4 for gather with order 4 */ #if GMX_SIMD_HAVE_4NSIMD_UTIL_REAL && GMX_SIMD_REAL_WIDTH <= 16 -# define PME_4NSIMD_GATHER 1 +# define PME_4NSIMD_GATHER 1 #else -# define PME_4NSIMD_GATHER 0 +# define PME_4NSIMD_GATHER 0 #endif #endif diff --git a/src/gromacs/ewald/pme_simd4.h b/src/gromacs/ewald/pme_simd4.h index 0fdc3170b1..8b948c2fab 100644 --- a/src/gromacs/ewald/pme_simd4.h +++ b/src/gromacs/ewald/pme_simd4.h @@ -57,34 +57,34 @@ Simd4Real gri_S0, gri_S1, gri_S2, gri_S3; /* With order 4 the z-spline is actually aligned */ - tz_S = load4(thz); + tz_S = load4(thz); for (ithx = 0; (ithx < 4); ithx++) { - index_x = (i0+ithx)*pny*pnz; - valx = coefficient*thx[ithx]; + index_x = (i0 + ithx) * pny * pnz; + valx = coefficient * thx[ithx]; - vx_S = Simd4Real(valx); + vx_S = Simd4Real(valx); vx_tz_S = vx_S * tz_S; - gri_S0 = load4U(grid+index_x+(j0+0)*pnz+k0); - gri_S1 = load4U(grid+index_x+(j0+1)*pnz+k0); - gri_S2 = load4U(grid+index_x+(j0+2)*pnz+k0); - gri_S3 = load4U(grid+index_x+(j0+3)*pnz+k0); + gri_S0 = load4U(grid + index_x + (j0 + 0) * pnz + k0); + gri_S1 = load4U(grid + index_x + (j0 + 1) * pnz + k0); + gri_S2 = load4U(grid + index_x + (j0 + 2) * pnz + k0); + gri_S3 = load4U(grid + index_x + (j0 + 3) * pnz + k0); sum_S0 = fma(vx_tz_S, ty_S0, gri_S0); sum_S1 = fma(vx_tz_S, ty_S1, gri_S1); sum_S2 = fma(vx_tz_S, ty_S2, gri_S2); sum_S3 = fma(vx_tz_S, ty_S3, gri_S3); - store4U(grid+index_x+(j0+0)*pnz+k0, sum_S0); - store4U(grid+index_x+(j0+1)*pnz+k0, sum_S1); - store4U(grid+index_x+(j0+2)*pnz+k0, sum_S2); - store4U(grid+index_x+(j0+3)*pnz+k0, sum_S3); + store4U(grid + index_x + (j0 + 0) * pnz + k0, sum_S0); + store4U(grid + index_x + (j0 + 1) * pnz + k0, sum_S1); + store4U(grid + index_x + (j0 + 2) * pnz + k0, sum_S2); + store4U(grid + index_x + (j0 + 3) * pnz + k0, sum_S3); } } -#undef PME_SPREAD_SIMD4_ORDER4 +# undef PME_SPREAD_SIMD4_ORDER4 #endif @@ -95,105 +95,105 @@ */ { using namespace gmx; - int offset; - int index; - Simd4Real ty_S0(thy[0]); - Simd4Real ty_S1(thy[1]); - Simd4Real ty_S2(thy[2]); - Simd4Real ty_S3(thy[3]); - Simd4Real tz_S0; - Simd4Real tz_S1; - Simd4Real vx_S; - Simd4Real vx_tz_S0; - Simd4Real vx_tz_S1; - Simd4Real sum_S00, sum_S01, sum_S02, sum_S03; - Simd4Real sum_S10, sum_S11, sum_S12, sum_S13; - Simd4Real gri_S00, gri_S01, gri_S02, gri_S03; - Simd4Real gri_S10, gri_S11, gri_S12, gri_S13; -#if PME_ORDER == 5 - Simd4Real ty_S4(thy[4]); - Simd4Real sum_S04; - Simd4Real sum_S14; - Simd4Real gri_S04; - Simd4Real gri_S14; -#endif + int offset; + int index; + Simd4Real ty_S0(thy[0]); + Simd4Real ty_S1(thy[1]); + Simd4Real ty_S2(thy[2]); + Simd4Real ty_S3(thy[3]); + Simd4Real tz_S0; + Simd4Real tz_S1; + Simd4Real vx_S; + Simd4Real vx_tz_S0; + Simd4Real vx_tz_S1; + Simd4Real sum_S00, sum_S01, sum_S02, sum_S03; + Simd4Real sum_S10, sum_S11, sum_S12, sum_S13; + Simd4Real gri_S00, gri_S01, gri_S02, gri_S03; + Simd4Real gri_S10, gri_S11, gri_S12, gri_S13; +# if PME_ORDER == 5 + Simd4Real ty_S4(thy[4]); + Simd4Real sum_S04; + Simd4Real sum_S14; + Simd4Real gri_S04; + Simd4Real gri_S14; +# endif offset = k0 & 3; -#ifdef PME_SIMD4_UNALIGNED - tz_S0 = load4U(thz-offset); - tz_S1 = load4U(thz-offset+4); -#else +# ifdef PME_SIMD4_UNALIGNED + tz_S0 = load4U(thz - offset); + tz_S1 = load4U(thz - offset + 4); +# else { int i; /* Copy thz to an aligned buffer (unused buffer parts are masked) */ for (i = 0; i < PME_ORDER; i++) { - thz_aligned[offset+i] = thz[i]; + thz_aligned[offset + i] = thz[i]; } tz_S0 = load4(thz_aligned); - tz_S1 = load4(thz_aligned+4); + tz_S1 = load4(thz_aligned + 4); } -#endif +# endif tz_S0 = selectByMask(tz_S0, work->mask_S0[offset]); tz_S1 = selectByMask(tz_S1, work->mask_S1[offset]); for (ithx = 0; (ithx < PME_ORDER); ithx++) { - index = (i0+ithx)*pny*pnz + j0*pnz + k0 - offset; - valx = coefficient*thx[ithx]; + index = (i0 + ithx) * pny * pnz + j0 * pnz + k0 - offset; + valx = coefficient * thx[ithx]; - vx_S = Simd4Real(valx); + vx_S = Simd4Real(valx); vx_tz_S0 = vx_S * tz_S0; vx_tz_S1 = vx_S * tz_S1; - gri_S00 = load4(grid+index+0*pnz); - gri_S01 = load4(grid+index+1*pnz); - gri_S02 = load4(grid+index+2*pnz); - gri_S03 = load4(grid+index+3*pnz); -#if PME_ORDER == 5 - gri_S04 = load4(grid+index+4*pnz); -#endif - gri_S10 = load4(grid+index+0*pnz+4); - gri_S11 = load4(grid+index+1*pnz+4); - gri_S12 = load4(grid+index+2*pnz+4); - gri_S13 = load4(grid+index+3*pnz+4); -#if PME_ORDER == 5 - gri_S14 = load4(grid+index+4*pnz+4); -#endif + gri_S00 = load4(grid + index + 0 * pnz); + gri_S01 = load4(grid + index + 1 * pnz); + gri_S02 = load4(grid + index + 2 * pnz); + gri_S03 = load4(grid + index + 3 * pnz); +# if PME_ORDER == 5 + gri_S04 = load4(grid + index + 4 * pnz); +# endif + gri_S10 = load4(grid + index + 0 * pnz + 4); + gri_S11 = load4(grid + index + 1 * pnz + 4); + gri_S12 = load4(grid + index + 2 * pnz + 4); + gri_S13 = load4(grid + index + 3 * pnz + 4); +# if PME_ORDER == 5 + gri_S14 = load4(grid + index + 4 * pnz + 4); +# endif sum_S00 = fma(vx_tz_S0, ty_S0, gri_S00); sum_S01 = fma(vx_tz_S0, ty_S1, gri_S01); sum_S02 = fma(vx_tz_S0, ty_S2, gri_S02); sum_S03 = fma(vx_tz_S0, ty_S3, gri_S03); -#if PME_ORDER == 5 +# if PME_ORDER == 5 sum_S04 = fma(vx_tz_S0, ty_S4, gri_S04); -#endif +# endif sum_S10 = fma(vx_tz_S1, ty_S0, gri_S10); sum_S11 = fma(vx_tz_S1, ty_S1, gri_S11); sum_S12 = fma(vx_tz_S1, ty_S2, gri_S12); sum_S13 = fma(vx_tz_S1, ty_S3, gri_S13); -#if PME_ORDER == 5 +# if PME_ORDER == 5 sum_S14 = fma(vx_tz_S1, ty_S4, gri_S14); -#endif - - store4(grid+index+0*pnz, sum_S00); - store4(grid+index+1*pnz, sum_S01); - store4(grid+index+2*pnz, sum_S02); - store4(grid+index+3*pnz, sum_S03); -#if PME_ORDER == 5 - store4(grid+index+4*pnz, sum_S04); -#endif - store4(grid+index+0*pnz+4, sum_S10); - store4(grid+index+1*pnz+4, sum_S11); - store4(grid+index+2*pnz+4, sum_S12); - store4(grid+index+3*pnz+4, sum_S13); -#if PME_ORDER == 5 - store4(grid+index+4*pnz+4, sum_S14); -#endif +# endif + + store4(grid + index + 0 * pnz, sum_S00); + store4(grid + index + 1 * pnz, sum_S01); + store4(grid + index + 2 * pnz, sum_S02); + store4(grid + index + 3 * pnz, sum_S03); +# if PME_ORDER == 5 + store4(grid + index + 4 * pnz, sum_S04); +# endif + store4(grid + index + 0 * pnz + 4, sum_S10); + store4(grid + index + 1 * pnz + 4, sum_S11); + store4(grid + index + 2 * pnz + 4, sum_S12); + store4(grid + index + 3 * pnz + 4, sum_S13); +# if PME_ORDER == 5 + store4(grid + index + 4 * pnz + 4, sum_S14); +# endif } } -#undef PME_ORDER -#undef PME_SPREAD_SIMD4_ALIGNED +# undef PME_ORDER +# undef PME_SPREAD_SIMD4_ALIGNED #endif diff --git a/src/gromacs/ewald/pme_solve.clh b/src/gromacs/ewald/pme_solve.clh index a4b877e0dd..ac38117d38 100644 --- a/src/gromacs/ewald/pme_solve.clh +++ b/src/gromacs/ewald/pme_solve.clh @@ -58,14 +58,14 @@ * * \param[in] kernelParams Input PME GPU data in constant memory. * \param[in] gm_splineModuli B-Spline moduli. - * \param[out] gm_virialAndEnergy Reduced virial and enrgy (only with computeEnergyAndVirial == true) - * \param[in,out] gm_grid Fourier grid to transform. + * \param[out] gm_virialAndEnergy Reduced virial and enrgy (only with computeEnergyAndVirial == + * true) \param[in,out] gm_grid Fourier grid to transform. */ __attribute__((work_group_size_hint(c_solveMaxWorkGroupSize, 1, 1))) -__kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKernelParams kernelParams, - __global const float * __restrict__ gm_splineModuli, - __global float * __restrict__ gm_virialAndEnergy, - __global float2 * __restrict__ gm_grid) +__kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKernelParams kernelParams, + __global const float* __restrict__ gm_splineModuli, + __global float* __restrict__ gm_virialAndEnergy, + __global float2* __restrict__ gm_grid) { /* This kernel supports 2 different grid dimension orderings: YZX and XYZ */ int majorDim, middleDim, minorDim; @@ -82,12 +82,15 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKer minorDim = ZZ; } - __global const float * __restrict__ gm_splineValueMajor = gm_splineModuli + kernelParams.grid.splineValuesOffset[majorDim]; - __global const float * __restrict__ gm_splineValueMiddle = gm_splineModuli + kernelParams.grid.splineValuesOffset[middleDim]; - __global const float * __restrict__ gm_splineValueMinor = gm_splineModuli + kernelParams.grid.splineValuesOffset[minorDim]; + __global const float* __restrict__ gm_splineValueMajor = + gm_splineModuli + kernelParams.grid.splineValuesOffset[majorDim]; + __global const float* __restrict__ gm_splineValueMiddle = + gm_splineModuli + kernelParams.grid.splineValuesOffset[middleDim]; + __global const float* __restrict__ gm_splineValueMinor = + gm_splineModuli + kernelParams.grid.splineValuesOffset[minorDim]; /* Various grid sizes and indices */ - const int localOffsetMinor = 0, localOffsetMajor = 0, localOffsetMiddle = 0; //unused + const int localOffsetMinor = 0, localOffsetMajor = 0, localOffsetMiddle = 0; // unused const int localSizeMinor = kernelParams.grid.complexGridSizePadded[minorDim]; const int localSizeMiddle = kernelParams.grid.complexGridSizePadded[middleDim]; const int localCountMiddle = kernelParams.grid.complexGridSize[middleDim]; @@ -124,34 +127,35 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKer float virzz = 0.0f; assert(indexMajor < kernelParams.grid.complexGridSize[majorDim]); - if ((indexMiddle < localCountMiddle) & (indexMinor < localCountMinor) & (gridLineIndex < gridLinesPerBlock)) + if ((indexMiddle < localCountMiddle) & (indexMinor < localCountMinor) + & (gridLineIndex < gridLinesPerBlock)) { /* The offset should be equal to the global thread index for coalesced access */ - const int gridIndex = (indexMajor * localSizeMiddle + indexMiddle) * localSizeMinor + indexMinor; - __global float2 * __restrict__ gm_gridCell = gm_grid + gridIndex; + const int gridIndex = (indexMajor * localSizeMiddle + indexMiddle) * localSizeMinor + indexMinor; + __global float2* __restrict__ gm_gridCell = gm_grid + gridIndex; - const int kMajor = indexMajor + localOffsetMajor; + const int kMajor = indexMajor + localOffsetMajor; /* Checking either X in XYZ, or Y in YZX cases */ - const float mMajor = (kMajor < maxkMajor) ? kMajor : (kMajor - nMajor); + const float mMajor = (kMajor < maxkMajor) ? kMajor : (kMajor - nMajor); - const int kMiddle = indexMiddle + localOffsetMiddle; - float mMiddle = kMiddle; + const int kMiddle = indexMiddle + localOffsetMiddle; + float mMiddle = kMiddle; /* Checking Y in XYZ case */ if (gridOrdering == XYZ) { mMiddle = (kMiddle < maxkMiddle) ? kMiddle : (kMiddle - nMiddle); } - const int kMinor = localOffsetMinor + indexMinor; - float mMinor = kMinor; + const int kMinor = localOffsetMinor + indexMinor; + float mMinor = kMinor; /* Checking X in YZX case */ if (gridOrdering == YZX) { mMinor = (kMinor < maxkMinor) ? kMinor : (kMinor - nMinor); } /* We should skip the k-space point (0,0,0) */ - const bool notZeroPoint = (kMinor > 0) | (kMajor > 0) | (kMiddle > 0); + const bool notZeroPoint = (kMinor > 0) | (kMajor > 0) | (kMiddle > 0); - float mX, mY, mZ; + float mX, mY, mZ; if (gridOrdering == YZX) { mX = mMinor; @@ -185,40 +189,45 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKer if (notZeroPoint) { const float mhxk = mX * kernelParams.current.recipBox[XX][XX]; - const float mhyk = mX * kernelParams.current.recipBox[XX][YY] + mY * kernelParams.current.recipBox[YY][YY]; - const float mhzk = mX * kernelParams.current.recipBox[XX][ZZ] + mY * kernelParams.current.recipBox[YY][ZZ] + mZ * kernelParams.current.recipBox[ZZ][ZZ]; + const float mhyk = mX * kernelParams.current.recipBox[XX][YY] + + mY * kernelParams.current.recipBox[YY][YY]; + const float mhzk = mX * kernelParams.current.recipBox[XX][ZZ] + + mY * kernelParams.current.recipBox[YY][ZZ] + + mZ * kernelParams.current.recipBox[ZZ][ZZ]; - const float m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; + const float m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; assert(m2k != 0.0f); - const float denom = m2k * M_PI_F * kernelParams.current.boxVolume * gm_splineValueMajor[kMajor] * gm_splineValueMiddle[kMiddle] * gm_splineValueMinor[kMinor]; + const float denom = m2k * M_PI_F * kernelParams.current.boxVolume * gm_splineValueMajor[kMajor] + * gm_splineValueMiddle[kMiddle] * gm_splineValueMinor[kMinor]; assert(isfinite(denom)); assert(denom != 0.0f); - const float tmp1 = exp(-kernelParams.grid.ewaldFactor * m2k); - const float etermk = kernelParams.constants.elFactor * tmp1 / denom; + const float tmp1 = exp(-kernelParams.grid.ewaldFactor * m2k); + const float etermk = kernelParams.constants.elFactor * tmp1 / denom; - float2 gridValue = *gm_gridCell; - const float2 oldGridValue = gridValue; + float2 gridValue = *gm_gridCell; + const float2 oldGridValue = gridValue; - gridValue.x *= etermk; - gridValue.y *= etermk; - *gm_gridCell = gridValue; + gridValue.x *= etermk; + gridValue.y *= etermk; + *gm_gridCell = gridValue; if (computeEnergyAndVirial) { - const float tmp1k = 2.0f * (gridValue.x * oldGridValue.x + gridValue.y * oldGridValue.y); + const float tmp1k = + 2.0f * (gridValue.x * oldGridValue.x + gridValue.y * oldGridValue.y); const float vfactor = (kernelParams.grid.ewaldFactor + 1.0f / m2k) * 2.0f; const float ets2 = corner_fac * tmp1k; - energy = ets2; + energy = ets2; - const float ets2vf = ets2 * vfactor; + const float ets2vf = ets2 * vfactor; - virxx = ets2vf * mhxk * mhxk - ets2; - virxy = ets2vf * mhxk * mhyk; - virxz = ets2vf * mhxk * mhzk; - viryy = ets2vf * mhyk * mhyk - ets2; - viryz = ets2vf * mhyk * mhzk; - virzz = ets2vf * mhzk * mhzk - ets2; + virxx = ets2vf * mhxk * mhxk - ets2; + virxy = ets2vf * mhxk * mhyk; + virxz = ets2vf * mhxk * mhzk; + viryy = ets2vf * mhyk * mhyk - ets2; + viryz = ets2vf * mhyk * mhzk; + virzz = ets2vf * mhzk * mhzk - ets2; } } } @@ -271,16 +280,17 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_solve_kernel)(const struct PmeOpenCLKer if (componentIndex < c_virialAndEnergyCount) { const int targetIndex = componentIndex * warp_size + lane; - #pragma unroll +#pragma unroll for (int reductionStride = warp_size >> 1; reductionStride >= 1; reductionStride >>= 1) { if (lane < reductionStride) { - sm_virialAndEnergy[targetIndex] += sm_virialAndEnergy[targetIndex + reductionStride]; + sm_virialAndEnergy[targetIndex] += + sm_virialAndEnergy[targetIndex + reductionStride]; } #ifdef _NVIDIA_SOURCE_ - /* FIXME: this execution happens within execution width aka warp, but somehow NVIDIA OpenCL of all things - * fails without the memory barrier here. #2519 + /* FIXME: this execution happens within execution width aka warp, but somehow + * NVIDIA OpenCL of all things fails without the memory barrier here. #2519 */ barrier(CLK_LOCAL_MEM_FENCE); #endif diff --git a/src/gromacs/ewald/pme_solve.cpp b/src/gromacs/ewald/pme_solve.cpp index 23d181367e..406e701e2d 100644 --- a/src/gromacs/ewald/pme_solve.cpp +++ b/src/gromacs/ewald/pme_solve.cpp @@ -63,22 +63,22 @@ using namespace gmx; // TODO: Remove when this file is moved into gmx namespace struct pme_solve_work_t { /* work data for solve_pme */ - int nalloc; - real * mhx; - real * mhy; - real * mhz; - real * m2; - real * denom; - real * tmp1_alloc; - real * tmp1; - real * tmp2; - real * eterm; - real * m2inv; - - real energy_q; - matrix vir_q; - real energy_lj; - matrix vir_lj; + int nalloc; + real* mhx; + real* mhy; + real* mhz; + real* m2; + real* denom; + real* tmp1_alloc; + real* tmp1; + real* tmp2; + real* eterm; + real* m2inv; + + real energy_q; + matrix vir_q; + real energy_lj; + matrix vir_lj; }; #ifdef PME_SIMD_SOLVE @@ -89,10 +89,11 @@ constexpr int c_simdWidth = 4; #endif /* Returns the smallest number >= \p that is a multiple of \p factor, \p factor must be a power of 2 */ -template +template static size_t roundUpToMultipleOfFactor(size_t number) { - static_assert(factor > 0 && (factor & (factor - 1)) == 0, "factor should be >0 and a power of 2"); + static_assert(factor > 0 && (factor & (factor - 1)) == 0, + "factor should be >0 and a power of 2"); /* We need to add a most factor-1 and because factor is a power of 2, * we get the result by masking out the bits corresponding to factor-1. @@ -104,13 +105,14 @@ static size_t roundUpToMultipleOfFactor(size_t number) * at the end for padding. */ /* TODO: Replace this SIMD reallocator with a general, C++ solution */ -static void reallocSimdAlignedAndPadded(real **ptr, int unpaddedNumElements) +static void reallocSimdAlignedAndPadded(real** ptr, int unpaddedNumElements) { sfree_aligned(*ptr); - snew_aligned(*ptr, roundUpToMultipleOfFactor(unpaddedNumElements), c_simdWidth*sizeof(real)); + snew_aligned(*ptr, roundUpToMultipleOfFactor(unpaddedNumElements), + c_simdWidth * sizeof(real)); } -static void realloc_work(struct pme_solve_work_t *work, int nkx) +static void realloc_work(struct pme_solve_work_t* work, int nkx) { if (nkx > work->nalloc) { @@ -128,14 +130,14 @@ static void realloc_work(struct pme_solve_work_t *work, int nkx) /* Init all allocated elements of denom to 1 to avoid 1/0 exceptions * of simd padded elements. */ - for (size_t i = 0; i < roundUpToMultipleOfFactor(work->nalloc ); i++) + for (size_t i = 0; i < roundUpToMultipleOfFactor(work->nalloc); i++) { work->denom[i] = 1; } } } -void pme_init_all_work(struct pme_solve_work_t **work, int nthread, int nkx) +void pme_init_all_work(struct pme_solve_work_t** work, int nthread, int nkx) { /* Use fft5d, order after FFT is y major, z, x minor */ @@ -148,11 +150,11 @@ void pme_init_all_work(struct pme_solve_work_t **work, int nthread, int nkx) { realloc_work(&((*work)[thread]), nkx); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } -static void free_work(struct pme_solve_work_t *work) +static void free_work(struct pme_solve_work_t* work) { if (work) { @@ -168,7 +170,7 @@ static void free_work(struct pme_solve_work_t *work) } } -void pme_free_all_work(struct pme_solve_work_t **work, int nthread) +void pme_free_all_work(struct pme_solve_work_t** work, int nthread) { if (*work) { @@ -181,7 +183,7 @@ void pme_free_all_work(struct pme_solve_work_t **work, int nthread) *work = nullptr; } -void get_pme_ener_vir_q(pme_solve_work_t *work, int nthread, PmeOutput *output) +void get_pme_ener_vir_q(pme_solve_work_t* work, int nthread, PmeOutput* output) { GMX_ASSERT(output != nullptr, "Need valid output buffer"); /* This function sums output over threads and should therefore @@ -197,7 +199,7 @@ void get_pme_ener_vir_q(pme_solve_work_t *work, int nthread, PmeOutput *output) } } -void get_pme_ener_vir_lj(pme_solve_work_t *work, int nthread, PmeOutput *output) +void get_pme_ener_vir_lj(pme_solve_work_t* work, int nthread, PmeOutput* output) { GMX_ASSERT(output != nullptr, "Need valid output buffer"); /* This function sums output over threads and should therefore @@ -215,11 +217,16 @@ void get_pme_ener_vir_lj(pme_solve_work_t *work, int nthread, PmeOutput *output) #if defined PME_SIMD_SOLVE /* Calculate exponentials through SIMD */ -inline static void calc_exponentials_q(int /*unused*/, int /*unused*/, real f, ArrayRef d_aligned, ArrayRef r_aligned, ArrayRef e_aligned) +inline static void calc_exponentials_q(int /*unused*/, + int /*unused*/, + real f, + ArrayRef d_aligned, + ArrayRef r_aligned, + ArrayRef e_aligned) { { - SimdReal f_simd(f); - SimdReal tmp_d1, tmp_r, tmp_e; + SimdReal f_simd(f); + SimdReal tmp_d1, tmp_r, tmp_e; /* We only need to calculate from start. But since start is 0 or 1 * and we want to use aligned loads/stores, we always start from 0. @@ -238,14 +245,15 @@ inline static void calc_exponentials_q(int /*unused*/, int /*unused*/, real f, A } } #else -inline static void calc_exponentials_q(int start, int end, real f, ArrayRef d, ArrayRef r, ArrayRef e) +inline static void +calc_exponentials_q(int start, int end, real f, ArrayRef d, ArrayRef r, ArrayRef e) { GMX_ASSERT(d.size() == r.size(), "d and r must have same size"); GMX_ASSERT(d.size() == e.size(), "d and e must have same size"); int kx; for (kx = start; kx < end; kx++) { - d[kx] = 1.0/d[kx]; + d[kx] = 1.0 / d[kx]; } for (kx = start; kx < end; kx++) { @@ -253,17 +261,21 @@ inline static void calc_exponentials_q(int start, int end, real f, ArrayRef r_aligned, ArrayRef factor_aligned, ArrayRef d_aligned) +inline static void calc_exponentials_lj(int /*unused*/, + int /*unused*/, + ArrayRef r_aligned, + ArrayRef factor_aligned, + ArrayRef d_aligned) { - SimdReal tmp_r, tmp_d, tmp_fac, d_inv, tmp_mk; - const SimdReal sqr_PI = sqrt(SimdReal(M_PI)); + SimdReal tmp_r, tmp_d, tmp_fac, d_inv, tmp_mk; + const SimdReal sqr_PI = sqrt(SimdReal(M_PI)); GMX_ASSERT(d_aligned.size() == r_aligned.size(), "d and r must have same size"); GMX_ASSERT(d_aligned.size() == factor_aligned.size(), "d and factor must have same size"); @@ -284,7 +296,8 @@ inline static void calc_exponentials_lj(int /*unused*/, int /*unused*/, ArrayRef } } #else -inline static void calc_exponentials_lj(int start, int end, ArrayRef r, ArrayRef tmp2, ArrayRef d) +inline static void +calc_exponentials_lj(int start, int end, ArrayRef r, ArrayRef tmp2, ArrayRef d) { int kx; real mk; @@ -292,7 +305,7 @@ inline static void calc_exponentials_lj(int start, int end, ArrayRef r, Ar GMX_ASSERT(d.size() == tmp2.size(), "d and tmp2 must have same size"); for (kx = start; kx < end; kx++) { - d[kx] = 1.0/d[kx]; + d[kx] = 1.0 / d[kx]; } for (kx = start; kx < end; kx++) @@ -303,7 +316,7 @@ inline static void calc_exponentials_lj(int start, int end, ArrayRef r, Ar for (kx = start; kx < end; kx++) { mk = tmp2[kx]; - tmp2[kx] = sqrt(M_PI)*mk*std::erfc(mk); + tmp2[kx] = sqrt(M_PI) * mk * std::erfc(mk); } } #endif @@ -314,43 +327,38 @@ using PME_T = SimdReal; using PME_T = real; #endif -int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, - gmx_bool bEnerVir, - int nthread, int thread) +int solve_pme_yzx(const gmx_pme_t* pme, t_complex* grid, real vol, gmx_bool bEnerVir, int nthread, int thread) { /* do recip sum over local cells in grid */ /* y major, z middle, x minor or continuous */ - t_complex *p0; + t_complex* p0; int kx, ky, kz, maxkx, maxky; int nx, ny, nz, iyz0, iyz1, iyz, iy, iz, kxstart, kxend; real mx, my, mz; real ewaldcoeff = pme->ewaldcoeff_q; - real factor = M_PI*M_PI/(ewaldcoeff*ewaldcoeff); + real factor = M_PI * M_PI / (ewaldcoeff * ewaldcoeff); real ets2, struct2, vfactor, ets2vf; real d1, d2, energy = 0; real by, bz; real virxx = 0, virxy = 0, virxz = 0, viryy = 0, viryz = 0, virzz = 0; real rxx, ryx, ryy, rzx, rzy, rzz; - struct pme_solve_work_t *work; - real *mhx, *mhy, *mhz, *m2, *denom, *tmp1, *eterm, *m2inv; + struct pme_solve_work_t* work; + real * mhx, *mhy, *mhz, *m2, *denom, *tmp1, *eterm, *m2inv; real mhxk, mhyk, mhzk, m2k; real corner_fac; ivec complex_order; ivec local_ndata, local_offset, local_size; real elfac; - elfac = ONE_4PI_EPS0/pme->epsilon_r; + elfac = ONE_4PI_EPS0 / pme->epsilon_r; nx = pme->nkx; ny = pme->nky; nz = pme->nkz; /* Dimensions should be identical for A/B grid, so we just use A here */ - gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_QA], - complex_order, - local_ndata, - local_offset, - local_size); + gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_QA], complex_order, local_ndata, + local_offset, local_size); rxx = pme->recipbox[XX][XX]; ryx = pme->recipbox[YY][XX]; @@ -361,8 +369,8 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, GMX_ASSERT(rxx != 0.0, "Someone broke the reciprocal box again"); - maxkx = (nx+1)/2; - maxky = (ny+1)/2; + maxkx = (nx + 1) / 2; + maxky = (ny + 1) / 2; work = &pme->solve_work[thread]; mhx = work->mhx; @@ -374,13 +382,13 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, eterm = work->eterm; m2inv = work->m2inv; - iyz0 = local_ndata[YY]*local_ndata[ZZ]* thread /nthread; - iyz1 = local_ndata[YY]*local_ndata[ZZ]*(thread+1)/nthread; + iyz0 = local_ndata[YY] * local_ndata[ZZ] * thread / nthread; + iyz1 = local_ndata[YY] * local_ndata[ZZ] * (thread + 1) / nthread; for (iyz = iyz0; iyz < iyz1; iyz++) { - iy = iyz/local_ndata[ZZ]; - iz = iyz - iy*local_ndata[ZZ]; + iy = iyz / local_ndata[ZZ]; + iz = iyz - iy * local_ndata[ZZ]; ky = iy + local_offset[YY]; @@ -393,7 +401,7 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, my = (ky - ny); } - by = M_PI*vol*pme->bsp_mod[YY][ky]; + by = M_PI * vol * pme->bsp_mod[YY][ky]; kz = iz + local_offset[ZZ]; @@ -403,12 +411,12 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, /* 0.5 correction for corner points */ corner_fac = 1; - if (kz == 0 || kz == (nz+1)/2) + if (kz == 0 || kz == (nz + 1) / 2) { corner_fac = 0.5; } - p0 = grid + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; + p0 = grid + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; /* We should skip the k-space point (0,0,0) */ /* Note that since here x is the minor index, local_offset[XX]=0 */ @@ -439,13 +447,13 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; mhx[kx] = mhxk; mhy[kx] = mhyk; mhz[kx] = mhzk; m2[kx] = m2k; - denom[kx] = m2k*bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; + denom[kx] = m2k * bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; } for (kx = maxkx; kx < kxend; kx++) @@ -455,51 +463,52 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; mhx[kx] = mhxk; mhy[kx] = mhyk; mhz[kx] = mhzk; m2[kx] = m2k; - denom[kx] = m2k*bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; + denom[kx] = m2k * bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; } for (kx = kxstart; kx < kxend; kx++) { - m2inv[kx] = 1.0/m2[kx]; + m2inv[kx] = 1.0 / m2[kx]; } - calc_exponentials_q(kxstart, kxend, elfac, - ArrayRef(denom, denom+roundUpToMultipleOfFactor(kxend)), - ArrayRef(tmp1, tmp1+roundUpToMultipleOfFactor(kxend)), - ArrayRef(eterm, eterm+roundUpToMultipleOfFactor(kxend))); + calc_exponentials_q( + kxstart, kxend, elfac, + ArrayRef(denom, denom + roundUpToMultipleOfFactor(kxend)), + ArrayRef(tmp1, tmp1 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(eterm, eterm + roundUpToMultipleOfFactor(kxend))); for (kx = kxstart; kx < kxend; kx++, p0++) { - d1 = p0->re; - d2 = p0->im; + d1 = p0->re; + d2 = p0->im; - p0->re = d1*eterm[kx]; - p0->im = d2*eterm[kx]; + p0->re = d1 * eterm[kx]; + p0->im = d2 * eterm[kx]; - struct2 = 2.0*(d1*d1+d2*d2); + struct2 = 2.0 * (d1 * d1 + d2 * d2); - tmp1[kx] = eterm[kx]*struct2; + tmp1[kx] = eterm[kx] * struct2; } for (kx = kxstart; kx < kxend; kx++) { - ets2 = corner_fac*tmp1[kx]; - vfactor = (factor*m2[kx] + 1.0)*2.0*m2inv[kx]; - energy += ets2; - - ets2vf = ets2*vfactor; - virxx += ets2vf*mhx[kx]*mhx[kx] - ets2; - virxy += ets2vf*mhx[kx]*mhy[kx]; - virxz += ets2vf*mhx[kx]*mhz[kx]; - viryy += ets2vf*mhy[kx]*mhy[kx] - ets2; - viryz += ets2vf*mhy[kx]*mhz[kx]; - virzz += ets2vf*mhz[kx]*mhz[kx] - ets2; + ets2 = corner_fac * tmp1[kx]; + vfactor = (factor * m2[kx] + 1.0) * 2.0 * m2inv[kx]; + energy += ets2; + + ets2vf = ets2 * vfactor; + virxx += ets2vf * mhx[kx] * mhx[kx] - ets2; + virxy += ets2vf * mhx[kx] * mhy[kx]; + virxz += ets2vf * mhx[kx] * mhz[kx]; + viryy += ets2vf * mhy[kx] * mhy[kx] - ets2; + viryz += ets2vf * mhy[kx] * mhz[kx]; + virzz += ets2vf * mhz[kx] * mhz[kx] - ets2; } } else @@ -517,9 +526,9 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; - denom[kx] = m2k*bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; + denom[kx] = m2k * bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; } for (kx = maxkx; kx < kxend; kx++) @@ -529,24 +538,25 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; - denom[kx] = m2k*bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; + denom[kx] = m2k * bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; } - calc_exponentials_q(kxstart, kxend, elfac, - ArrayRef(denom, denom+roundUpToMultipleOfFactor(kxend)), - ArrayRef(tmp1, tmp1+roundUpToMultipleOfFactor(kxend)), - ArrayRef(eterm, eterm+roundUpToMultipleOfFactor(kxend))); + calc_exponentials_q( + kxstart, kxend, elfac, + ArrayRef(denom, denom + roundUpToMultipleOfFactor(kxend)), + ArrayRef(tmp1, tmp1 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(eterm, eterm + roundUpToMultipleOfFactor(kxend))); for (kx = kxstart; kx < kxend; kx++, p0++) { - d1 = p0->re; - d2 = p0->im; + d1 = p0->re; + d2 = p0->im; - p0->re = d1*eterm[kx]; - p0->im = d2*eterm[kx]; + p0->re = d1 * eterm[kx]; + p0->im = d2 * eterm[kx]; } } } @@ -559,23 +569,22 @@ int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, real vol, * experiencing problems on semiisotropic membranes. * IS THAT COMMENT STILL VALID??? (DvdS, 2001/02/07). */ - work->vir_q[XX][XX] = 0.25*virxx; - work->vir_q[YY][YY] = 0.25*viryy; - work->vir_q[ZZ][ZZ] = 0.25*virzz; - work->vir_q[XX][YY] = work->vir_q[YY][XX] = 0.25*virxy; - work->vir_q[XX][ZZ] = work->vir_q[ZZ][XX] = 0.25*virxz; - work->vir_q[YY][ZZ] = work->vir_q[ZZ][YY] = 0.25*viryz; + work->vir_q[XX][XX] = 0.25 * virxx; + work->vir_q[YY][YY] = 0.25 * viryy; + work->vir_q[ZZ][ZZ] = 0.25 * virzz; + work->vir_q[XX][YY] = work->vir_q[YY][XX] = 0.25 * virxy; + work->vir_q[XX][ZZ] = work->vir_q[ZZ][XX] = 0.25 * virxz; + work->vir_q[YY][ZZ] = work->vir_q[ZZ][YY] = 0.25 * viryz; /* This energy should be corrected for a charged system */ - work->energy_q = 0.5*energy; + work->energy_q = 0.5 * energy; } /* Return the loop count */ - return local_ndata[YY]*local_ndata[XX]; + return local_ndata[YY] * local_ndata[XX]; } -int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real vol, - gmx_bool bEnerVir, int nthread, int thread) +int solve_pme_lj_yzx(const gmx_pme_t* pme, t_complex** grid, gmx_bool bLB, real vol, gmx_bool bEnerVir, int nthread, int thread) { /* do recip sum over local cells in grid */ /* y major, z middle, x minor or continuous */ @@ -584,15 +593,15 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real int nx, ny, nz, iy, iyz0, iyz1, iyz, iz, kxstart, kxend; real mx, my, mz; real ewaldcoeff = pme->ewaldcoeff_lj; - real factor = M_PI*M_PI/(ewaldcoeff*ewaldcoeff); + real factor = M_PI * M_PI / (ewaldcoeff * ewaldcoeff); real ets2, ets2vf; real eterm, vterm, d1, d2, energy = 0; real by, bz; real virxx = 0, virxy = 0, virxz = 0, viryy = 0, viryz = 0, virzz = 0; real rxx, ryx, ryy, rzx, rzy, rzz; - real *mhx, *mhy, *mhz, *m2, *denom, *tmp1, *tmp2; + real * mhx, *mhy, *mhz, *m2, *denom, *tmp1, *tmp2; real mhxk, mhyk, mhzk, m2k; - struct pme_solve_work_t *work; + struct pme_solve_work_t* work; real corner_fac; ivec complex_order; ivec local_ndata, local_offset, local_size; @@ -601,11 +610,8 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real nz = pme->nkz; /* Dimensions should be identical for A/B grid, so we just use A here */ - gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_C6A], - complex_order, - local_ndata, - local_offset, - local_size); + gmx_parallel_3dfft_complex_limits(pme->pfft_setup[PME_GRID_C6A], complex_order, local_ndata, + local_offset, local_size); rxx = pme->recipbox[XX][XX]; ryx = pme->recipbox[YY][XX]; ryy = pme->recipbox[YY][YY]; @@ -613,8 +619,8 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real rzy = pme->recipbox[ZZ][YY]; rzz = pme->recipbox[ZZ][ZZ]; - maxkx = (nx+1)/2; - maxky = (ny+1)/2; + maxkx = (nx + 1) / 2; + maxky = (ny + 1) / 2; work = &pme->solve_work[thread]; mhx = work->mhx; @@ -625,13 +631,13 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real tmp1 = work->tmp1; tmp2 = work->tmp2; - iyz0 = local_ndata[YY]*local_ndata[ZZ]* thread /nthread; - iyz1 = local_ndata[YY]*local_ndata[ZZ]*(thread+1)/nthread; + iyz0 = local_ndata[YY] * local_ndata[ZZ] * thread / nthread; + iyz1 = local_ndata[YY] * local_ndata[ZZ] * (thread + 1) / nthread; for (iyz = iyz0; iyz < iyz1; iyz++) { - iy = iyz/local_ndata[ZZ]; - iz = iyz - iy*local_ndata[ZZ]; + iy = iyz / local_ndata[ZZ]; + iz = iyz - iy * local_ndata[ZZ]; ky = iy + local_offset[YY]; @@ -644,8 +650,7 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real my = (ky - ny); } - by = 3.0*vol*pme->bsp_mod[YY][ky] - / (M_PI*sqrt(M_PI)*ewaldcoeff*ewaldcoeff*ewaldcoeff); + by = 3.0 * vol * pme->bsp_mod[YY][ky] / (M_PI * sqrt(M_PI) * ewaldcoeff * ewaldcoeff * ewaldcoeff); kz = iz + local_offset[ZZ]; @@ -655,7 +660,7 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real /* 0.5 correction for corner points */ corner_fac = 1; - if (kz == 0 || kz == (nz+1)/2) + if (kz == 0 || kz == (nz + 1) / 2) { corner_fac = 0.5; } @@ -678,14 +683,14 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; mhx[kx] = mhxk; mhy[kx] = mhyk; mhz[kx] = mhzk; m2[kx] = m2k; - denom[kx] = bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; - tmp2[kx] = sqrt(factor*m2k); + denom[kx] = bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; + tmp2[kx] = sqrt(factor * m2k); } for (kx = maxkx; kx < kxend; kx++) @@ -695,14 +700,14 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; mhx[kx] = mhxk; mhy[kx] = mhyk; mhz[kx] = mhzk; m2[kx] = m2k; - denom[kx] = bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; - tmp2[kx] = sqrt(factor*m2k); + denom[kx] = bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; + tmp2[kx] = sqrt(factor * m2k); } /* Clear padding elements to avoid (harmless) fp exceptions */ const int kxendSimd = roundUpToMultipleOfFactor(kxend); @@ -712,46 +717,46 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real tmp2[kx] = 0; } - calc_exponentials_lj(kxstart, kxend, - ArrayRef(tmp1, tmp1+roundUpToMultipleOfFactor(kxend)), - ArrayRef(tmp2, tmp2+roundUpToMultipleOfFactor(kxend)), - ArrayRef(denom, denom+roundUpToMultipleOfFactor(kxend))); + calc_exponentials_lj( + kxstart, kxend, + ArrayRef(tmp1, tmp1 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(tmp2, tmp2 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(denom, denom + roundUpToMultipleOfFactor(kxend))); for (kx = kxstart; kx < kxend; kx++) { - m2k = factor*m2[kx]; - eterm = -((1.0 - 2.0*m2k)*tmp1[kx] - + 2.0*m2k*tmp2[kx]); - vterm = 3.0*(-tmp1[kx] + tmp2[kx]); - tmp1[kx] = eterm*denom[kx]; - tmp2[kx] = vterm*denom[kx]; + m2k = factor * m2[kx]; + eterm = -((1.0 - 2.0 * m2k) * tmp1[kx] + 2.0 * m2k * tmp2[kx]); + vterm = 3.0 * (-tmp1[kx] + tmp2[kx]); + tmp1[kx] = eterm * denom[kx]; + tmp2[kx] = vterm * denom[kx]; } if (!bLB) { - t_complex *p0; + t_complex* p0; real struct2; - p0 = grid[0] + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; + p0 = grid[0] + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; for (kx = kxstart; kx < kxend; kx++, p0++) { - d1 = p0->re; - d2 = p0->im; + d1 = p0->re; + d2 = p0->im; - eterm = tmp1[kx]; - vterm = tmp2[kx]; - p0->re = d1*eterm; - p0->im = d2*eterm; + eterm = tmp1[kx]; + vterm = tmp2[kx]; + p0->re = d1 * eterm; + p0->im = d2 * eterm; - struct2 = 2.0*(d1*d1+d2*d2); + struct2 = 2.0 * (d1 * d1 + d2 * d2); - tmp1[kx] = eterm*struct2; - tmp2[kx] = vterm*struct2; + tmp1[kx] = eterm * struct2; + tmp2[kx] = vterm * struct2; } } else { - real *struct2 = denom; + real* struct2 = denom; real str2; for (kx = kxstart; kx < kxend; kx++) @@ -764,28 +769,27 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real t_complex *p0, *p1; real scale; - p0 = grid[ig] + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; - p1 = grid[6-ig] + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; - scale = 2.0*lb_scale_factor_symm[ig]; + p0 = grid[ig] + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; + p1 = grid[6 - ig] + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; + scale = 2.0 * lb_scale_factor_symm[ig]; for (kx = kxstart; kx < kxend; ++kx, ++p0, ++p1) { - struct2[kx] += scale*(p0->re*p1->re + p0->im*p1->im); + struct2[kx] += scale * (p0->re * p1->re + p0->im * p1->im); } - } for (ig = 0; ig <= 6; ++ig) { - t_complex *p0; + t_complex* p0; - p0 = grid[ig] + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; + p0 = grid[ig] + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; for (kx = kxstart; kx < kxend; kx++, p0++) { - d1 = p0->re; - d2 = p0->im; + d1 = p0->re; + d2 = p0->im; eterm = tmp1[kx]; - p0->re = d1*eterm; - p0->im = d2*eterm; + p0->re = d1 * eterm; + p0->im = d2 * eterm; } } for (kx = kxstart; kx < kxend; kx++) @@ -793,23 +797,23 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real eterm = tmp1[kx]; vterm = tmp2[kx]; str2 = struct2[kx]; - tmp1[kx] = eterm*str2; - tmp2[kx] = vterm*str2; + tmp1[kx] = eterm * str2; + tmp2[kx] = vterm * str2; } } for (kx = kxstart; kx < kxend; kx++) { - ets2 = corner_fac*tmp1[kx]; - vterm = 2.0*factor*tmp2[kx]; - energy += ets2; - ets2vf = corner_fac*vterm; - virxx += ets2vf*mhx[kx]*mhx[kx] - ets2; - virxy += ets2vf*mhx[kx]*mhy[kx]; - virxz += ets2vf*mhx[kx]*mhz[kx]; - viryy += ets2vf*mhy[kx]*mhy[kx] - ets2; - viryz += ets2vf*mhy[kx]*mhz[kx]; - virzz += ets2vf*mhz[kx]*mhz[kx] - ets2; + ets2 = corner_fac * tmp1[kx]; + vterm = 2.0 * factor * tmp2[kx]; + energy += ets2; + ets2vf = corner_fac * vterm; + virxx += ets2vf * mhx[kx] * mhx[kx] - ets2; + virxy += ets2vf * mhx[kx] * mhy[kx]; + virxz += ets2vf * mhx[kx] * mhz[kx]; + viryy += ets2vf * mhy[kx] * mhy[kx] - ets2; + viryz += ets2vf * mhy[kx] * mhz[kx]; + virzz += ets2vf * mhz[kx] * mhz[kx] - ets2; } } else @@ -827,11 +831,11 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; m2[kx] = m2k; - denom[kx] = bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; - tmp2[kx] = sqrt(factor*m2k); + denom[kx] = bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; + tmp2[kx] = sqrt(factor * m2k); } for (kx = maxkx; kx < kxend; kx++) @@ -841,11 +845,11 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real mhxk = mx * rxx; mhyk = mx * ryx + my * ryy; mhzk = mx * rzx + my * rzy + mz * rzz; - m2k = mhxk*mhxk + mhyk*mhyk + mhzk*mhzk; + m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; m2[kx] = m2k; - denom[kx] = bz*by*pme->bsp_mod[XX][kx]; - tmp1[kx] = -factor*m2k; - tmp2[kx] = sqrt(factor*m2k); + denom[kx] = bz * by * pme->bsp_mod[XX][kx]; + tmp1[kx] = -factor * m2k; + tmp2[kx] = sqrt(factor * m2k); } /* Clear padding elements to avoid (harmless) fp exceptions */ const int kxendSimd = roundUpToMultipleOfFactor(kxend); @@ -855,49 +859,49 @@ int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, real tmp2[kx] = 0; } - calc_exponentials_lj(kxstart, kxend, - ArrayRef(tmp1, tmp1+roundUpToMultipleOfFactor(kxend)), - ArrayRef(tmp2, tmp2+roundUpToMultipleOfFactor(kxend)), - ArrayRef(denom, denom+roundUpToMultipleOfFactor(kxend))); + calc_exponentials_lj( + kxstart, kxend, + ArrayRef(tmp1, tmp1 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(tmp2, tmp2 + roundUpToMultipleOfFactor(kxend)), + ArrayRef(denom, denom + roundUpToMultipleOfFactor(kxend))); for (kx = kxstart; kx < kxend; kx++) { - m2k = factor*m2[kx]; - eterm = -((1.0 - 2.0*m2k)*tmp1[kx] - + 2.0*m2k*tmp2[kx]); - tmp1[kx] = eterm*denom[kx]; + m2k = factor * m2[kx]; + eterm = -((1.0 - 2.0 * m2k) * tmp1[kx] + 2.0 * m2k * tmp2[kx]); + tmp1[kx] = eterm * denom[kx]; } gcount = (bLB ? 7 : 1); for (ig = 0; ig < gcount; ++ig) { - t_complex *p0; + t_complex* p0; - p0 = grid[ig] + iy*local_size[ZZ]*local_size[XX] + iz*local_size[XX]; + p0 = grid[ig] + iy * local_size[ZZ] * local_size[XX] + iz * local_size[XX]; for (kx = kxstart; kx < kxend; kx++, p0++) { - d1 = p0->re; - d2 = p0->im; + d1 = p0->re; + d2 = p0->im; - eterm = tmp1[kx]; + eterm = tmp1[kx]; - p0->re = d1*eterm; - p0->im = d2*eterm; + p0->re = d1 * eterm; + p0->im = d2 * eterm; } } } } if (bEnerVir) { - work->vir_lj[XX][XX] = 0.25*virxx; - work->vir_lj[YY][YY] = 0.25*viryy; - work->vir_lj[ZZ][ZZ] = 0.25*virzz; - work->vir_lj[XX][YY] = work->vir_lj[YY][XX] = 0.25*virxy; - work->vir_lj[XX][ZZ] = work->vir_lj[ZZ][XX] = 0.25*virxz; - work->vir_lj[YY][ZZ] = work->vir_lj[ZZ][YY] = 0.25*viryz; + work->vir_lj[XX][XX] = 0.25 * virxx; + work->vir_lj[YY][YY] = 0.25 * viryy; + work->vir_lj[ZZ][ZZ] = 0.25 * virzz; + work->vir_lj[XX][YY] = work->vir_lj[YY][XX] = 0.25 * virxy; + work->vir_lj[XX][ZZ] = work->vir_lj[ZZ][XX] = 0.25 * virxz; + work->vir_lj[YY][ZZ] = work->vir_lj[ZZ][YY] = 0.25 * viryz; /* This energy should be corrected for a charged system */ - work->energy_lj = 0.5*energy; + work->energy_lj = 0.5 * energy; } /* Return the loop count */ - return local_ndata[YY]*local_ndata[XX]; + return local_ndata[YY] * local_ndata[XX]; } diff --git a/src/gromacs/ewald/pme_solve.cu b/src/gromacs/ewald/pme_solve.cu index 401d82f218..784de81f96 100644 --- a/src/gromacs/ewald/pme_solve.cu +++ b/src/gromacs/ewald/pme_solve.cu @@ -53,16 +53,12 @@ * PME complex grid solver kernel function. * * \tparam[in] gridOrdering Specifies the dimension ordering of the complex grid. - * \tparam[in] computeEnergyAndVirial Tells if the reciprocal energy and virial should be computed. - * \param[in] kernelParams Input PME CUDA data in constant memory. + * \tparam[in] computeEnergyAndVirial Tells if the reciprocal energy and virial should be + * computed. \param[in] kernelParams Input PME CUDA data in constant memory. */ -template< - GridOrdering gridOrdering, - bool computeEnergyAndVirial - > -__launch_bounds__(c_solveMaxThreadsPerBlock) -CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE -__global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParams) +template +__launch_bounds__(c_solveMaxThreadsPerBlock) CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE __global__ + void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParams) { /* This kernel supports 2 different grid dimension orderings: YZX and XYZ */ int majorDim, middleDim, minorDim; @@ -80,19 +76,21 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam minorDim = ZZ; break; - default: - assert(false); + default: assert(false); } /* Global memory pointers */ - const float * __restrict__ gm_splineValueMajor = kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[majorDim]; - const float * __restrict__ gm_splineValueMiddle = kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[middleDim]; - const float * __restrict__ gm_splineValueMinor = kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[minorDim]; - float * __restrict__ gm_virialAndEnergy = kernelParams.constants.d_virialAndEnergy; - float2 * __restrict__ gm_grid = (float2 *)kernelParams.grid.d_fourierGrid; + const float* __restrict__ gm_splineValueMajor = + kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[majorDim]; + const float* __restrict__ gm_splineValueMiddle = + kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[middleDim]; + const float* __restrict__ gm_splineValueMinor = + kernelParams.grid.d_splineModuli + kernelParams.grid.splineValuesOffset[minorDim]; + float* __restrict__ gm_virialAndEnergy = kernelParams.constants.d_virialAndEnergy; + float2* __restrict__ gm_grid = (float2*)kernelParams.grid.d_fourierGrid; /* Various grid sizes and indices */ - const int localOffsetMinor = 0, localOffsetMajor = 0, localOffsetMiddle = 0; //unused + const int localOffsetMinor = 0, localOffsetMajor = 0, localOffsetMiddle = 0; // unused const int localSizeMinor = kernelParams.grid.complexGridSizePadded[minorDim]; const int localSizeMiddle = kernelParams.grid.complexGridSizePadded[middleDim]; const int localCountMiddle = kernelParams.grid.complexGridSize[middleDim]; @@ -129,34 +127,35 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam float virzz = 0.0f; assert(indexMajor < kernelParams.grid.complexGridSize[majorDim]); - if ((indexMiddle < localCountMiddle) & (indexMinor < localCountMinor) & (gridLineIndex < gridLinesPerBlock)) + if ((indexMiddle < localCountMiddle) & (indexMinor < localCountMinor) + & (gridLineIndex < gridLinesPerBlock)) { /* The offset should be equal to the global thread index for coalesced access */ - const int gridIndex = (indexMajor * localSizeMiddle + indexMiddle) * localSizeMinor + indexMinor; - float2 * __restrict__ gm_gridCell = gm_grid + gridIndex; + const int gridIndex = (indexMajor * localSizeMiddle + indexMiddle) * localSizeMinor + indexMinor; + float2* __restrict__ gm_gridCell = gm_grid + gridIndex; - const int kMajor = indexMajor + localOffsetMajor; + const int kMajor = indexMajor + localOffsetMajor; /* Checking either X in XYZ, or Y in YZX cases */ - const float mMajor = (kMajor < maxkMajor) ? kMajor : (kMajor - nMajor); + const float mMajor = (kMajor < maxkMajor) ? kMajor : (kMajor - nMajor); - const int kMiddle = indexMiddle + localOffsetMiddle; - float mMiddle = kMiddle; + const int kMiddle = indexMiddle + localOffsetMiddle; + float mMiddle = kMiddle; /* Checking Y in XYZ case */ if (gridOrdering == GridOrdering::XYZ) { mMiddle = (kMiddle < maxkMiddle) ? kMiddle : (kMiddle - nMiddle); } - const int kMinor = localOffsetMinor + indexMinor; - float mMinor = kMinor; + const int kMinor = localOffsetMinor + indexMinor; + float mMinor = kMinor; /* Checking X in YZX case */ if (gridOrdering == GridOrdering::YZX) { mMinor = (kMinor < maxkMinor) ? kMinor : (kMinor - nMinor); } /* We should skip the k-space point (0,0,0) */ - const bool notZeroPoint = (kMinor > 0) | (kMajor > 0) | (kMiddle > 0); + const bool notZeroPoint = (kMinor > 0) | (kMajor > 0) | (kMiddle > 0); - float mX, mY, mZ; + float mX, mY, mZ; switch (gridOrdering) { case GridOrdering::YZX: @@ -171,8 +170,7 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam mZ = mMinor; break; - default: - assert(false); + default: assert(false); } /* 0.5 correction factor for the first and last components of a Z dimension */ @@ -193,48 +191,53 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam } break; - default: - assert(false); + default: assert(false); } if (notZeroPoint) { const float mhxk = mX * kernelParams.current.recipBox[XX][XX]; - const float mhyk = mX * kernelParams.current.recipBox[XX][YY] + mY * kernelParams.current.recipBox[YY][YY]; - const float mhzk = mX * kernelParams.current.recipBox[XX][ZZ] + mY * kernelParams.current.recipBox[YY][ZZ] + mZ * kernelParams.current.recipBox[ZZ][ZZ]; + const float mhyk = mX * kernelParams.current.recipBox[XX][YY] + + mY * kernelParams.current.recipBox[YY][YY]; + const float mhzk = mX * kernelParams.current.recipBox[XX][ZZ] + + mY * kernelParams.current.recipBox[YY][ZZ] + + mZ * kernelParams.current.recipBox[ZZ][ZZ]; - const float m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; + const float m2k = mhxk * mhxk + mhyk * mhyk + mhzk * mhzk; assert(m2k != 0.0f); - //TODO: use LDG/textures for gm_splineValue - float denom = m2k * float(CUDART_PI_F) * kernelParams.current.boxVolume * gm_splineValueMajor[kMajor] * gm_splineValueMiddle[kMiddle] * gm_splineValueMinor[kMinor]; + // TODO: use LDG/textures for gm_splineValue + float denom = m2k * float(CUDART_PI_F) * kernelParams.current.boxVolume + * gm_splineValueMajor[kMajor] * gm_splineValueMiddle[kMiddle] + * gm_splineValueMinor[kMinor]; assert(isfinite(denom)); assert(denom != 0.0f); - const float tmp1 = expf(-kernelParams.grid.ewaldFactor * m2k); - const float etermk = kernelParams.constants.elFactor * tmp1 / denom; + const float tmp1 = expf(-kernelParams.grid.ewaldFactor * m2k); + const float etermk = kernelParams.constants.elFactor * tmp1 / denom; - float2 gridValue = *gm_gridCell; - const float2 oldGridValue = gridValue; - gridValue.x *= etermk; - gridValue.y *= etermk; - *gm_gridCell = gridValue; + float2 gridValue = *gm_gridCell; + const float2 oldGridValue = gridValue; + gridValue.x *= etermk; + gridValue.y *= etermk; + *gm_gridCell = gridValue; if (computeEnergyAndVirial) { - const float tmp1k = 2.0f * (gridValue.x * oldGridValue.x + gridValue.y * oldGridValue.y); + const float tmp1k = + 2.0f * (gridValue.x * oldGridValue.x + gridValue.y * oldGridValue.y); - float vfactor = (kernelParams.grid.ewaldFactor + 1.0f / m2k) * 2.0f; - float ets2 = corner_fac * tmp1k; - energy = ets2; + float vfactor = (kernelParams.grid.ewaldFactor + 1.0f / m2k) * 2.0f; + float ets2 = corner_fac * tmp1k; + energy = ets2; - float ets2vf = ets2 * vfactor; + float ets2vf = ets2 * vfactor; - virxx = ets2vf * mhxk * mhxk - ets2; - virxy = ets2vf * mhxk * mhyk; - virxz = ets2vf * mhxk * mhzk; - viryy = ets2vf * mhyk * mhyk - ets2; - viryz = ets2vf * mhyk * mhzk; - virzz = ets2vf * mhzk * mhzk - ets2; + virxx = ets2vf * mhxk * mhxk - ets2; + virxy = ets2vf * mhxk * mhyk; + virxz = ets2vf * mhxk * mhzk; + viryy = ets2vf * mhyk * mhyk - ets2; + viryz = ets2vf * mhyk * mhzk; + virzz = ets2vf * mhzk * mhzk - ets2; } } } @@ -252,12 +255,12 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam const unsigned int activeMask = c_fullWarpMask; /* Making pair sums */ - virxx += __shfl_down_sync(activeMask, virxx, 1, width); - viryy += __shfl_up_sync (activeMask, viryy, 1, width); - virzz += __shfl_down_sync(activeMask, virzz, 1, width); - virxy += __shfl_up_sync (activeMask, virxy, 1, width); - virxz += __shfl_down_sync(activeMask, virxz, 1, width); - viryz += __shfl_up_sync (activeMask, viryz, 1, width); + virxx += __shfl_down_sync(activeMask, virxx, 1, width); + viryy += __shfl_up_sync(activeMask, viryy, 1, width); + virzz += __shfl_down_sync(activeMask, virzz, 1, width); + virxy += __shfl_up_sync(activeMask, virxy, 1, width); + virxz += __shfl_down_sync(activeMask, virxz, 1, width); + viryz += __shfl_up_sync(activeMask, viryz, 1, width); energy += __shfl_down_sync(activeMask, energy, 1, width); if (threadLocalId & 1) { @@ -267,10 +270,10 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam } /* Making quad sums */ - virxx += __shfl_down_sync(activeMask, virxx, 2, width); - virzz += __shfl_up_sync (activeMask, virzz, 2, width); - virxz += __shfl_down_sync(activeMask, virxz, 2, width); - energy += __shfl_up_sync (activeMask, energy, 2, width); + virxx += __shfl_down_sync(activeMask, virxx, 2, width); + virzz += __shfl_up_sync(activeMask, virzz, 2, width); + virxz += __shfl_down_sync(activeMask, virxz, 2, width); + energy += __shfl_up_sync(activeMask, energy, 2, width); if (threadLocalId & 2) { virxx = virzz; // virxx now holds quad sums of virxx, virxy, virzz and virxy @@ -279,7 +282,7 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam /* Making octet sums */ virxx += __shfl_down_sync(activeMask, virxx, 4, width); - virxz += __shfl_up_sync (activeMask, virxz, 4, width); + virxz += __shfl_up_sync(activeMask, virxz, 4, width); if (threadLocalId & 4) { virxx = virxz; // virxx now holds all 7 components' octet sums + unused paddings @@ -293,17 +296,18 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam } /* Now first 7 threads of each warp have the full output contributions in virxx */ - const int componentIndex = threadLocalId & (warp_size - 1); - const bool validComponentIndex = (componentIndex < c_virialAndEnergyCount); + const int componentIndex = threadLocalId & (warp_size - 1); + const bool validComponentIndex = (componentIndex < c_virialAndEnergyCount); /* Reduce 7 outputs per warp in the shared memory */ - const int stride = 8; // this is c_virialAndEnergyCount==7 rounded up to power of 2 for convenience, hence the assert + const int stride = + 8; // this is c_virialAndEnergyCount==7 rounded up to power of 2 for convenience, hence the assert assert(c_virialAndEnergyCount == 7); const int reductionBufferSize = (c_solveMaxThreadsPerBlock / warp_size) * stride; __shared__ float sm_virialAndEnergy[reductionBufferSize]; if (validComponentIndex) { - const int warpIndex = threadLocalId / warp_size; + const int warpIndex = threadLocalId / warp_size; sm_virialAndEnergy[warpIndex * stride + componentIndex] = virxx; } __syncthreads(); @@ -311,7 +315,8 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam /* Reduce to the single warp size */ const int targetIndex = threadLocalId; #pragma unroll - for (int reductionStride = reductionBufferSize >> 1; reductionStride >= warp_size; reductionStride >>= 1) + for (int reductionStride = reductionBufferSize >> 1; reductionStride >= warp_size; + reductionStride >>= 1) { const int sourceIndex = targetIndex + reductionStride; if ((targetIndex < reductionStride) & (sourceIndex < activeWarps * stride)) @@ -327,7 +332,7 @@ __global__ void pme_solve_kernel(const struct PmeGpuCudaKernelParams kernelParam * To use fewer warps, add to the conditional: * && threadLocalId < activeWarps * stride */ - assert(activeWarps*stride >= warp_size); + assert(activeWarps * stride >= warp_size); if (threadLocalId < warp_size) { float output = sm_virialAndEnergy[threadLocalId]; diff --git a/src/gromacs/ewald/pme_solve.h b/src/gromacs/ewald/pme_solve.h index ed6457dcdd..bcf33c740d 100644 --- a/src/gromacs/ewald/pme_solve.h +++ b/src/gromacs/ewald/pme_solve.h @@ -49,32 +49,33 @@ struct PmeOutput; * this function. Upon return it will point at * an array of work structures. */ -void pme_init_all_work(struct pme_solve_work_t **work, int nthread, int nkx); +void pme_init_all_work(struct pme_solve_work_t** work, int nthread, int nkx); /*! \brief Frees array of work structures * * Frees work and sets it to NULL. */ -void pme_free_all_work(struct pme_solve_work_t **work, int nthread); +void pme_free_all_work(struct pme_solve_work_t** work, int nthread); /*! \brief Get energy and virial for electrostatics * * Note that work is an array of work structures */ -void get_pme_ener_vir_q(pme_solve_work_t *work, int nthread, PmeOutput *output); +void get_pme_ener_vir_q(pme_solve_work_t* work, int nthread, PmeOutput* output); /*! \brief Get energy and virial for L-J * * Note that work is an array of work structures */ -void get_pme_ener_vir_lj(pme_solve_work_t *work, int nthread, PmeOutput *output); +void get_pme_ener_vir_lj(pme_solve_work_t* work, int nthread, PmeOutput* output); -int solve_pme_yzx(const gmx_pme_t *pme, t_complex *grid, - real vol, - gmx_bool bEnerVir, - int nthread, int thread); +int solve_pme_yzx(const gmx_pme_t* pme, t_complex* grid, real vol, gmx_bool bEnerVir, int nthread, int thread); -int solve_pme_lj_yzx(const gmx_pme_t *pme, t_complex **grid, gmx_bool bLB, - real vol, - gmx_bool bEnerVir, int nthread, int thread); +int solve_pme_lj_yzx(const gmx_pme_t* pme, + t_complex** grid, + gmx_bool bLB, + real vol, + gmx_bool bEnerVir, + int nthread, + int thread); #endif diff --git a/src/gromacs/ewald/pme_spline_work.cpp b/src/gromacs/ewald/pme_spline_work.cpp index 09f9ebdc07..3a7b7fa403 100644 --- a/src/gromacs/ewald/pme_spline_work.cpp +++ b/src/gromacs/ewald/pme_spline_work.cpp @@ -49,17 +49,17 @@ using namespace gmx; // TODO: Remove when this file is moved into gmx namespace -pme_spline_work *make_pme_spline_work(int gmx_unused order) +pme_spline_work* make_pme_spline_work(int gmx_unused order) { - pme_spline_work *work; + pme_spline_work* work; #ifdef PME_SIMD4_SPREAD_GATHER - alignas(GMX_SIMD_ALIGNMENT) real tmp[GMX_SIMD4_WIDTH*2]; - Simd4Real zero_S; - Simd4Real real_mask_S0, real_mask_S1; - int of, i; + alignas(GMX_SIMD_ALIGNMENT) real tmp[GMX_SIMD4_WIDTH * 2]; + Simd4Real zero_S; + Simd4Real real_mask_S0, real_mask_S1; + int of, i; - work = new(gmx::AlignedAllocationPolicy::malloc(sizeof(pme_spline_work)))pme_spline_work; + work = new (gmx::AlignedAllocationPolicy::malloc(sizeof(pme_spline_work))) pme_spline_work; zero_S = setZero(); @@ -67,14 +67,14 @@ pme_spline_work *make_pme_spline_work(int gmx_unused order) * as we only operate on order of the 8 grid entries that are * load into 2 SIMD registers. */ - for (of = 0; of < 2*GMX_SIMD4_WIDTH-(order-1); of++) + for (of = 0; of < 2 * GMX_SIMD4_WIDTH - (order - 1); of++) { - for (i = 0; i < 2*GMX_SIMD4_WIDTH; i++) + for (i = 0; i < 2 * GMX_SIMD4_WIDTH; i++) { - tmp[i] = (i >= of && i < of+order ? -1.0 : 1.0); + tmp[i] = (i >= of && i < of + order ? -1.0 : 1.0); } real_mask_S0 = load4(tmp); - real_mask_S1 = load4(tmp+GMX_SIMD4_WIDTH); + real_mask_S1 = load4(tmp + GMX_SIMD4_WIDTH); work->mask_S0[of] = (real_mask_S0 < zero_S); work->mask_S1[of] = (real_mask_S1 < zero_S); } @@ -85,7 +85,7 @@ pme_spline_work *make_pme_spline_work(int gmx_unused order) return work; } -void destroy_pme_spline_work(pme_spline_work *work) +void destroy_pme_spline_work(pme_spline_work* work) { if (work != nullptr) { diff --git a/src/gromacs/ewald/pme_spline_work.h b/src/gromacs/ewald/pme_spline_work.h index 1d0ad410a7..cef9cec3c2 100644 --- a/src/gromacs/ewald/pme_spline_work.h +++ b/src/gromacs/ewald/pme_spline_work.h @@ -43,14 +43,14 @@ struct pme_spline_work { #ifdef PME_SIMD4_SPREAD_GATHER /* Masks for 4-wide SIMD aligned spreading and gathering */ - gmx::Simd4Bool mask_S0[6], mask_S1[6]; + gmx::Simd4Bool mask_S0[6], mask_S1[6]; #else - int dummy; /* C89 requires that struct has at least one member */ + int dummy; /* C89 requires that struct has at least one member */ #endif }; -pme_spline_work *make_pme_spline_work(int order); +pme_spline_work* make_pme_spline_work(int order); -void destroy_pme_spline_work(pme_spline_work *work); +void destroy_pme_spline_work(pme_spline_work* work); #endif diff --git a/src/gromacs/ewald/pme_spread.clh b/src/gromacs/ewald/pme_spread.clh index e64d223822..8215614ef0 100644 --- a/src/gromacs/ewald/pme_spread.clh +++ b/src/gromacs/ewald/pme_spread.clh @@ -57,16 +57,17 @@ /* * This define affects the spline calculation behaviour in the kernel. - * 0: a single GPU thread handles a single dimension of a single particle (calculating and storing (order) spline values and derivatives). - * 1: (order) threads do redundant work on this same task, each one stores only a single theta and single dtheta into global arrays. - * The only efficiency difference is less global store operations, countered by more redundant spline computation. + * 0: a single GPU thread handles a single dimension of a single particle (calculating and storing + * (order) spline values and derivatives). 1: (order) threads do redundant work on this same task, + * each one stores only a single theta and single dtheta into global arrays. The only efficiency + * difference is less global store operations, countered by more redundant spline computation. * * TODO: estimate if this should be a boolean parameter (and add it to the unit test if so). */ #define PME_GPU_PARALLEL_SPLINE 0 #ifndef COMPILE_SPREAD_HELPERS_ONCE -#define COMPILE_SPREAD_HELPERS_ONCE +# define COMPILE_SPREAD_HELPERS_ONCE /*! \brief * General purpose function for loading atom-related data from global to shared memory. @@ -77,16 +78,18 @@ * \param[in] dataCountPerAtom Number of data elements per single atom (e.g. DIM for an rvec coordinates array). * */ -inline void pme_gpu_stage_atom_data(const struct PmeOpenCLKernelParams kernelParams, - __local float * __restrict__ sm_destination, - __global const float * __restrict__ gm_source, - const int dataCountPerAtom) +inline void pme_gpu_stage_atom_data(const struct PmeOpenCLKernelParams kernelParams, + __local float* __restrict__ sm_destination, + __global const float* __restrict__ gm_source, + const int dataCountPerAtom) { - const size_t threadLocalIndex = ((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0)); - const size_t localIndex = threadLocalIndex; - const size_t globalIndexBase = get_group_id(XX) * atomsPerBlock * dataCountPerAtom; - const size_t globalIndex = globalIndexBase + localIndex; - const int globalCheck = pme_gpu_check_atom_data_index(globalIndex, kernelParams.atoms.nAtoms * dataCountPerAtom); + const size_t threadLocalIndex = + ((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0)); + const size_t localIndex = threadLocalIndex; + const size_t globalIndexBase = get_group_id(XX) * atomsPerBlock * dataCountPerAtom; + const size_t globalIndex = globalIndexBase + localIndex; + const int globalCheck = + pme_gpu_check_atom_data_index(globalIndex, kernelParams.atoms.nAtoms * dataCountPerAtom); if ((localIndex < atomsPerBlock * dataCountPerAtom) & globalCheck) { assert(isfinite(float(gm_source[globalIndex]))); @@ -112,21 +115,22 @@ inline void pme_gpu_stage_atom_data(const struct PmeOpenCLKernelParams * \param[in] gm_fractShiftsTable Atom fractional coordinates correction table * \param[in] gm_gridlineIndicesTable Atom fractional coordinates correction table */ -inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, - const int atomIndexOffset, - __local const float * __restrict__ sm_coordinates, - __local const float * __restrict__ sm_coefficients, - __local float * __restrict__ sm_theta, - __local int * __restrict__ sm_gridlineIndices, - __local float * __restrict__ sm_fractCoords, - __global float * __restrict__ gm_theta, - __global float * __restrict__ gm_dtheta, - __global int * __restrict__ gm_gridlineIndices, - __global const float * __restrict__ gm_fractShiftsTable, - __global const int * __restrict__ gm_gridlineIndicesTable) +inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, + const int atomIndexOffset, + __local const float* __restrict__ sm_coordinates, + __local const float* __restrict__ sm_coefficients, + __local float* __restrict__ sm_theta, + __local int* __restrict__ sm_gridlineIndices, + __local float* __restrict__ sm_fractCoords, + __global float* __restrict__ gm_theta, + __global float* __restrict__ gm_dtheta, + __global int* __restrict__ gm_gridlineIndices, + __global const float* __restrict__ gm_fractShiftsTable, + __global const int* __restrict__ gm_gridlineIndicesTable) { /* Thread index w.r.t. block */ - const int threadLocalIndex = ((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0)); + const int threadLocalIndex = + ((get_local_id(2) * get_local_size(1) + get_local_id(1)) * get_local_size(0) + get_local_id(0)); /* Warp index w.r.t. block - could probably be obtained easier? */ const int warpIndex = threadLocalIndex / warp_size; /* Thread index w.r.t. warp */ @@ -152,22 +156,22 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, * The buffer's size, striding and indexing are adjusted accordingly. * The buffer is accessed with SPLINE_DATA_PTR and SPLINE_DATA macros. */ -#if PME_GPU_PARALLEL_SPLINE - #define splineDataStride (atomsPerBlock * DIM) - const int splineDataIndex = sharedMemoryIndex; - __local float sm_splineData[splineDataStride * order]; - __local float *splineDataPtr = sm_splineData; -#else - #define splineDataStride 1 - const int splineDataIndex = 0; - float splineData[splineDataStride * order]; - float *splineDataPtr = splineData; -#endif - -#define SPLINE_DATA_PTR(i) (splineDataPtr + ((i) * splineDataStride + splineDataIndex)) -#define SPLINE_DATA(i) (*SPLINE_DATA_PTR(i)) - - const int localCheck = (dimIndex < DIM) && (orderIndex < (PME_GPU_PARALLEL_SPLINE ? order : 1)); +# if PME_GPU_PARALLEL_SPLINE +# define splineDataStride (atomsPerBlock * DIM) + const int splineDataIndex = sharedMemoryIndex; + __local float sm_splineData[splineDataStride * order]; + __local float* splineDataPtr = sm_splineData; +# else +# define splineDataStride 1 + const int splineDataIndex = 0; + float splineData[splineDataStride * order]; + float* splineDataPtr = splineData; +# endif + +# define SPLINE_DATA_PTR(i) (splineDataPtr + ((i)*splineDataStride + splineDataIndex)) +# define SPLINE_DATA(i) (*SPLINE_DATA_PTR(i)) + + const int localCheck = (dimIndex < DIM) && (orderIndex < (PME_GPU_PARALLEL_SPLINE ? order : 1)); const int globalCheck = pme_gpu_check_atom_data_index(atomIndexGlobal, kernelParams.atoms.nAtoms); if (localCheck && globalCheck) @@ -175,9 +179,9 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, /* Indices interpolation */ if (orderIndex == 0) { - int tableIndex, tInt; - float n, t; - const float3 x = vload3(atomIndexLocal, sm_coordinates); + int tableIndex, tInt; + float n, t; + const float3 x = vload3(atomIndexLocal, sm_coordinates); /* Accessing fields in fshOffset/nXYZ/recipbox/... with dimIndex offset * puts them into local memory(!) instead of accessing the constant memory directly. @@ -187,35 +191,42 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, switch (dimIndex) { case XX: - tableIndex = kernelParams.grid.tablesOffsets[XX]; - n = kernelParams.grid.realGridSizeFP[XX]; - t = x.x * kernelParams.current.recipBox[dimIndex][XX] + x.y * kernelParams.current.recipBox[dimIndex][YY] + x.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[XX]; + n = kernelParams.grid.realGridSizeFP[XX]; + t = x.x * kernelParams.current.recipBox[dimIndex][XX] + + x.y * kernelParams.current.recipBox[dimIndex][YY] + + x.z * kernelParams.current.recipBox[dimIndex][ZZ]; break; case YY: - tableIndex = kernelParams.grid.tablesOffsets[YY]; - n = kernelParams.grid.realGridSizeFP[YY]; - t = /*x.x * kernelParams.current.recipbox[dimIndex][XX] + */ x.y * kernelParams.current.recipBox[dimIndex][YY] + x.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[YY]; + n = kernelParams.grid.realGridSizeFP[YY]; + t = /*x.x * kernelParams.current.recipbox[dimIndex][XX] + */ x.y + * kernelParams.current.recipBox[dimIndex][YY] + + x.z * kernelParams.current.recipBox[dimIndex][ZZ]; break; case ZZ: - tableIndex = kernelParams.grid.tablesOffsets[ZZ]; - n = kernelParams.grid.realGridSizeFP[ZZ]; - t = /*x.x * kernelParams.current.recipbox[dimIndex][XX] + x.y * kernelParams.current.recipbox[dimIndex][YY] + */ x.z * kernelParams.current.recipBox[dimIndex][ZZ]; + tableIndex = kernelParams.grid.tablesOffsets[ZZ]; + n = kernelParams.grid.realGridSizeFP[ZZ]; + t = /*x.x * kernelParams.current.recipbox[dimIndex][XX] + x.y * kernelParams.current.recipbox[dimIndex][YY] + */ x + .z + * kernelParams.current.recipBox[dimIndex][ZZ]; break; } const float shift = c_pmeMaxUnitcellShift; /* Fractional coordinates along box vectors, adding a positive shift to ensure t is positive for triclinic boxes */ - t = (t + shift) * n; - tInt = (int)t; + t = (t + shift) * n; + tInt = (int)t; sm_fractCoords[sharedMemoryIndex] = t - tInt; - tableIndex += tInt; + tableIndex += tInt; assert(tInt >= 0); assert(tInt < c_pmeNeighborUnitcellCount * n); - sm_fractCoords[sharedMemoryIndex] += gm_fractShiftsTable[tableIndex]; + sm_fractCoords[sharedMemoryIndex] += gm_fractShiftsTable[tableIndex]; sm_gridlineIndices[sharedMemoryIndex] = gm_gridlineIndicesTable[tableIndex]; - gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] = sm_gridlineIndices[sharedMemoryIndex]; + gm_gridlineIndices[atomIndexOffset * DIM + sharedMemoryIndex] = + sm_gridlineIndices[sharedMemoryIndex]; } /* B-spline calculation */ @@ -223,8 +234,8 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, const int chargeCheck = pme_gpu_check_atom_charge(sm_coefficients[atomIndexLocal]); if (chargeCheck) { - float div; - int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1 + float div; + int o = orderIndex; // This is an index that is set once for PME_GPU_PARALLEL_SPLINE == 1 const float dr = sm_fractCoords[sharedMemoryIndex]; assert(isfinite(dr)); @@ -234,15 +245,17 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, *SPLINE_DATA_PTR(1) = dr; *SPLINE_DATA_PTR(0) = 1.0f - dr; -#pragma unroll order +# pragma unroll order for (int k = 3; k < order; k++) { div = 1.0f / (k - 1.0f); *SPLINE_DATA_PTR(k - 1) = div * dr * SPLINE_DATA(k - 2); -#pragma unroll +# pragma unroll for (int l = 1; l < (k - 1); l++) { - *SPLINE_DATA_PTR(k - l - 1) = div * ((dr + l) * SPLINE_DATA(k - l - 2) + (k - l - dr) * SPLINE_DATA(k - l - 1)); + *SPLINE_DATA_PTR(k - l - 1) = div + * ((dr + l) * SPLINE_DATA(k - l - 2) + + (k - l - dr) * SPLINE_DATA(k - l - 1)); } *SPLINE_DATA_PTR(0) = div * (1.0f - dr) * SPLINE_DATA(0); } @@ -251,41 +264,43 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, const int thetaGlobalOffsetBase = atomIndexOffset * DIM * order; /* Differentiation and storing the spline derivatives (dtheta) */ -#if !PME_GPU_PARALLEL_SPLINE +# if !PME_GPU_PARALLEL_SPLINE // With PME_GPU_PARALLEL_SPLINE == 1, o is already set to orderIndex; // With PME_GPU_PARALLEL_SPLINE == 0, we loop o over range(order). -#pragma unroll order +# pragma unroll order for (o = 0; o < order; o++) -#endif +# endif { - const int thetaIndex = getSplineParamIndex(thetaIndexBase, dimIndex, o); - const int thetaGlobalIndex = thetaGlobalOffsetBase + thetaIndex; + const int thetaIndex = getSplineParamIndex(thetaIndexBase, dimIndex, o); + const int thetaGlobalIndex = thetaGlobalOffsetBase + thetaIndex; const float dtheta = ((o > 0) ? SPLINE_DATA(o - 1) : 0.0f) - SPLINE_DATA(o); assert(isfinite(dtheta)); gm_dtheta[thetaGlobalIndex] = dtheta; } - div = 1.0f / (order - 1.0f); + div = 1.0f / (order - 1.0f); *SPLINE_DATA_PTR(order - 1) = div * dr * SPLINE_DATA(order - 2); -#pragma unroll +# pragma unroll for (int k = 1; k < (order - 1); k++) { - *SPLINE_DATA_PTR(order - k - 1) = div * ((dr + k) * SPLINE_DATA(order - k - 2) + (order - k - dr) * SPLINE_DATA(order - k - 1)); + *SPLINE_DATA_PTR(order - k - 1) = div + * ((dr + k) * SPLINE_DATA(order - k - 2) + + (order - k - dr) * SPLINE_DATA(order - k - 1)); } *SPLINE_DATA_PTR(0) = div * (1.0f - dr) * SPLINE_DATA(0); /* Storing the spline values (theta) */ -#if !PME_GPU_PARALLEL_SPLINE +# if !PME_GPU_PARALLEL_SPLINE // See comment for the loop above -#pragma unroll order +# pragma unroll order for (o = 0; o < order; o++) -#endif +# endif { const int thetaIndex = getSplineParamIndex(thetaIndexBase, dimIndex, o); const int thetaGlobalIndex = thetaGlobalOffsetBase + thetaIndex; - sm_theta[thetaIndex] = SPLINE_DATA(o); + sm_theta[thetaIndex] = SPLINE_DATA(o); assert(isfinite(sm_theta[thetaIndex])); gm_theta[thetaGlobalIndex] = SPLINE_DATA(o); } @@ -299,18 +314,17 @@ inline void calculate_splines(const struct PmeOpenCLKernelParams kernelParams, * Second stage of the whole kernel. * * \param[in] kernelParams Input PME GPU data in constant memory. - * \param[in] atomIndexOffset Starting atom index for the execution block w.r.t. global memory. - * \param[in] sm_coefficients Atom coefficents/charges in the shared memory. - * \param[in] sm_gridlineIndices Atom gridline indices in the shared memory. - * \param[in] sm_theta Atom spline values in the shared memory. - * \param[out] gm_grid Global 3D grid for spreading. + * \param[in] atomIndexOffset Starting atom index for the execution block w.r.t. global + * memory. \param[in] sm_coefficients Atom coefficents/charges in the shared memory. \param[in] + * sm_gridlineIndices Atom gridline indices in the shared memory. \param[in] sm_theta Atom spline + * values in the shared memory. \param[out] gm_grid Global 3D grid for spreading. */ -inline void spread_charges(const struct PmeOpenCLKernelParams kernelParams, - int atomIndexOffset, - __local const float * __restrict__ sm_coefficients, - __local const int * __restrict__ sm_gridlineIndices, - __local const float * __restrict__ sm_theta, - __global float * __restrict__ gm_grid) +inline void spread_charges(const struct PmeOpenCLKernelParams kernelParams, + int atomIndexOffset, + __local const float* __restrict__ sm_coefficients, + __local const int* __restrict__ sm_gridlineIndices, + __local const float* __restrict__ sm_theta, + __global float* __restrict__ gm_grid) { const int nx = kernelParams.grid.realGridSize[XX]; const int ny = kernelParams.grid.realGridSize[YY]; @@ -336,27 +350,27 @@ inline void spread_charges(const struct PmeOpenCLKernelParams kernelParams, { iy -= ny; } - int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] - offz + ithz; + int iz = sm_gridlineIndices[atomIndexLocal * DIM + ZZ] - offz + ithz; if (iz >= nz) { iz -= nz; } /* Atom index w.r.t. warp - alternating 0 1 0 1 .. */ - const int atomWarpIndex = atomIndexLocal % atomsPerWarp; + const int atomWarpIndex = atomIndexLocal % atomsPerWarp; /* Warp index w.r.t. block - could probably be obtained easier? */ - const int warpIndex = atomIndexLocal / atomsPerWarp; - - const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); - const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); - const float thetaZ = sm_theta[splineIndexZ]; - const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); - const float thetaY = sm_theta[splineIndexY]; - const float constVal = thetaZ * thetaY * sm_coefficients[atomIndexLocal]; + const int warpIndex = atomIndexLocal / atomsPerWarp; + + const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); + const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); + const float thetaZ = sm_theta[splineIndexZ]; + const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); + const float thetaY = sm_theta[splineIndexY]; + const float constVal = thetaZ * thetaY * sm_coefficients[atomIndexLocal]; assert(isfinite(constVal)); - const int constOffset = iy * pnz + iz; + const int constOffset = iy * pnz + iz; -#pragma unroll order +# pragma unroll order for (int ithx = 0; (ithx < order); ithx++) { int ix = ixBase + ithx; @@ -374,7 +388,7 @@ inline void spread_charges(const struct PmeOpenCLKernelParams kernelParams, } } -#endif //COMPILE_SPREAD_HELPERS_ONCE +#endif // COMPILE_SPREAD_HELPERS_ONCE /*! \brief * A spline computation and/or charge spreading kernel function. @@ -390,29 +404,29 @@ inline void spread_charges(const struct PmeOpenCLKernelParams kernelParams, * \param[in] gm_coefficients Atom charges/coefficients. * \param[in] gm_coordinates Atom coordinates (rvec) */ -__attribute__((reqd_work_group_size(order, order, atomsPerBlock))) -__kernel void CUSTOMIZED_KERNEL_NAME(pme_spline_and_spread_kernel)(const struct PmeOpenCLKernelParams kernelParams, - __global float * __restrict__ gm_theta, - __global float * __restrict__ gm_dtheta, - __global int * __restrict__ gm_gridlineIndices, - __global float *__restrict__ gm_grid, - __global const float * __restrict__ gm_fractShiftsTable, - __global const int * __restrict__ gm_gridlineIndicesTable, - __global const float * __restrict__ gm_coefficients, - __global const float * __restrict__ gm_coordinates) +__attribute__((reqd_work_group_size(order, order, atomsPerBlock))) __kernel void CUSTOMIZED_KERNEL_NAME( + pme_spline_and_spread_kernel)(const struct PmeOpenCLKernelParams kernelParams, + __global float* __restrict__ gm_theta, + __global float* __restrict__ gm_dtheta, + __global int* __restrict__ gm_gridlineIndices, + __global float* __restrict__ gm_grid, + __global const float* __restrict__ gm_fractShiftsTable, + __global const int* __restrict__ gm_gridlineIndicesTable, + __global const float* __restrict__ gm_coefficients, + __global const float* __restrict__ gm_coordinates) { // Gridline indices, ivec - __local int sm_gridlineIndices[atomsPerBlock * DIM]; + __local int sm_gridlineIndices[atomsPerBlock * DIM]; // Charges - __local float sm_coefficients[atomsPerBlock]; + __local float sm_coefficients[atomsPerBlock]; // Spline values - __local float sm_theta[atomsPerBlock * DIM * order]; + __local float sm_theta[atomsPerBlock * DIM * order]; // Fractional coordinates - only for spline computation - __local float sm_fractCoords[atomsPerBlock * DIM]; + __local float sm_fractCoords[atomsPerBlock * DIM]; // Staging coordinates - only for spline computation - __local float sm_coordinates[DIM * atomsPerBlock]; + __local float sm_coordinates[DIM * atomsPerBlock]; - const int atomIndexOffset = get_group_id(XX) * atomsPerBlock; + const int atomIndexOffset = get_group_id(XX) * atomsPerBlock; /* Staging coefficients/charges for both spline and spread */ pme_gpu_stage_atom_data(kernelParams, sm_coefficients, gm_coefficients, 1); @@ -423,13 +437,12 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_spline_and_spread_kernel)(const struct pme_gpu_stage_atom_data(kernelParams, sm_coordinates, gm_coordinates, DIM); barrier(CLK_LOCAL_MEM_FENCE); - calculate_splines(kernelParams, atomIndexOffset, sm_coordinates, - sm_coefficients, sm_theta, sm_gridlineIndices, - sm_fractCoords, gm_theta, gm_dtheta, gm_gridlineIndices, - gm_fractShiftsTable, gm_gridlineIndicesTable); + calculate_splines(kernelParams, atomIndexOffset, sm_coordinates, sm_coefficients, sm_theta, + sm_gridlineIndices, sm_fractCoords, gm_theta, gm_dtheta, + gm_gridlineIndices, gm_fractShiftsTable, gm_gridlineIndicesTable); #if !defined(_AMD_SOURCE_) && !defined(_NVIDIA_SOURCE_) - /* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was __syncwarp() in CUDA. - * #2519 + /* This is only here for execution of e.g. 32-sized warps on 16-wide hardware; this was + * __syncwarp() in CUDA. #2519 */ barrier(CLK_LOCAL_MEM_FENCE); #endif @@ -443,7 +456,8 @@ __kernel void CUSTOMIZED_KERNEL_NAME(pme_spline_and_spread_kernel)(const struct /* Spline data - only thetas (dthetas will only be needed in gather) */ pme_gpu_stage_atom_data(kernelParams, sm_theta, gm_theta, DIM * order); /* Gridline indices - they're actually int and not float, but C99 is angry about overloads */ - pme_gpu_stage_atom_data(kernelParams, (__local float *)sm_gridlineIndices, (__global const float *)gm_gridlineIndices, DIM); + pme_gpu_stage_atom_data(kernelParams, (__local float*)sm_gridlineIndices, + (__global const float*)gm_gridlineIndices, DIM); barrier(CLK_LOCAL_MEM_FENCE); } diff --git a/src/gromacs/ewald/pme_spread.cpp b/src/gromacs/ewald/pme_spread.cpp index 8e3b31be21..c9adf39c92 100644 --- a/src/gromacs/ewald/pme_spread.cpp +++ b/src/gromacs/ewald/pme_spread.cpp @@ -60,24 +60,23 @@ /* TODO consider split of pme-spline from this file */ -static void calc_interpolation_idx(const gmx_pme_t *pme, PmeAtomComm *atc, - int start, int grid_index, int end, int thread) +static void calc_interpolation_idx(const gmx_pme_t* pme, PmeAtomComm* atc, int start, int grid_index, int end, int thread) { - int i; - int *idxptr, tix, tiy, tiz; - const real *xptr; - real *fptr, tx, ty, tz; - real rxx, ryx, ryy, rzx, rzy, rzz; - int nx, ny, nz; - int *g2tx, *g2ty, *g2tz; - gmx_bool bThreads; - int *thread_idx = nullptr; - int *tpl_n = nullptr; - int thread_i; - - nx = pme->nkx; - ny = pme->nky; - nz = pme->nkz; + int i; + int * idxptr, tix, tiy, tiz; + const real* xptr; + real * fptr, tx, ty, tz; + real rxx, ryx, ryy, rzx, rzy, rzz; + int nx, ny, nz; + int * g2tx, *g2ty, *g2tz; + gmx_bool bThreads; + int* thread_idx = nullptr; + int* tpl_n = nullptr; + int thread_i; + + nx = pme->nkx; + ny = pme->nky; + nz = pme->nkz; rxx = pme->recipbox[XX][XX]; ryx = pme->recipbox[YY][XX]; @@ -111,9 +110,9 @@ static void calc_interpolation_idx(const gmx_pme_t *pme, PmeAtomComm *atc, fptr = atc->fractx[i]; /* Fractional coordinates along box vectors, add a positive shift to ensure tx/ty/tz are positive for triclinic boxes */ - tx = nx * ( xptr[XX] * rxx + xptr[YY] * ryx + xptr[ZZ] * rzx + shift ); - ty = ny * ( xptr[YY] * ryy + xptr[ZZ] * rzy + shift ); - tz = nz * ( xptr[ZZ] * rzz + shift ); + tx = nx * (xptr[XX] * rxx + xptr[YY] * ryx + xptr[ZZ] * rzx + shift); + ty = ny * (xptr[YY] * ryy + xptr[ZZ] * rzy + shift); + tz = nz * (xptr[ZZ] * rzz + shift); tix = static_cast(tx); tiy = static_cast(ty); @@ -156,18 +155,18 @@ static void calc_interpolation_idx(const gmx_pme_t *pme, PmeAtomComm *atc, /* Get the cumulative count */ for (i = 1; i < atc->nthread; i++) { - tpl_n[i] += tpl_n[i-1]; + tpl_n[i] += tpl_n[i - 1]; } /* The current implementation distributes particles equally * over the threads, so we could actually allocate for that * in pme_realloc_atomcomm_things. */ - AtomToThreadMap &threadMap = atc->threadMap[thread]; + AtomToThreadMap& threadMap = atc->threadMap[thread]; threadMap.i.resize(tpl_n[atc->nthread - 1]); /* Set tpl_n to the cumulative start */ - for (i = atc->nthread-1; i >= 1; i--) + for (i = atc->nthread - 1; i >= 1; i--) { - tpl_n[i] = tpl_n[i-1]; + tpl_n[i] = tpl_n[i - 1]; } tpl_n[0] = 0; @@ -180,10 +179,9 @@ static void calc_interpolation_idx(const gmx_pme_t *pme, PmeAtomComm *atc, } } -static void make_thread_local_ind(const PmeAtomComm *atc, - int thread, splinedata_t *spline) +static void make_thread_local_ind(const PmeAtomComm* atc, int thread, splinedata_t* spline) { - int n, t, i, start, end; + int n, t, i, start, end; /* Combine the indices made by each thread into one index */ @@ -191,11 +189,11 @@ static void make_thread_local_ind(const PmeAtomComm *atc, start = 0; for (t = 0; t < atc->nthread; t++) { - const AtomToThreadMap &threadMap = atc->threadMap[t]; + const AtomToThreadMap& threadMap = atc->threadMap[t]; /* Copy our part (start - end) from the list of thread t */ if (thread > 0) { - start = threadMap.n[thread-1]; + start = threadMap.n[thread - 1]; } end = threadMap.n[thread]; for (i = start; i < end; i++) @@ -217,61 +215,66 @@ static void make_thread_local_ind(const PmeAtomComm *atc, /* Macro to force loop unrolling by fixing order. * This gives a significant performance gain. */ -#define CALC_SPLINE(order) \ - { \ - for (int j = 0; (j < DIM); j++) \ - { \ - real dr, div; \ - real data[PME_ORDER_MAX]; \ - \ - dr = xptr[j]; \ - \ - /* dr is relative offset from lower cell limit */ \ - data[(order)-1] = 0; \ - data[1] = dr; \ - data[0] = 1 - dr; \ - \ - for (int k = 3; (k < (order)); k++) \ - { \ - div = 1.0/(k - 1.0); \ - data[k-1] = div*dr*data[k-2]; \ - for (int l = 1; (l < (k-1)); l++) \ - { \ - data[k-l-1] = div*((dr+l)*data[k-l-2]+(k-l-dr)* \ - data[k-l-1]); \ - } \ - data[0] = div*(1-dr)*data[0]; \ - } \ - /* differentiate */ \ - dtheta[j][i*(order)+0] = -data[0]; \ - for (int k = 1; (k < (order)); k++) \ - { \ - dtheta[j][i*(order)+k] = data[k-1] - data[k]; \ - } \ - \ - div = 1.0/((order) - 1); \ - data[(order)-1] = div*dr*data[(order)-2]; \ - for (int l = 1; (l < ((order)-1)); l++) \ - { \ - data[(order)-l-1] = div*((dr+l)*data[(order)-l-2]+ \ - ((order)-l-dr)*data[(order)-l-1]); \ - } \ - data[0] = div*(1 - dr)*data[0]; \ - \ - for (int k = 0; k < (order); k++) \ - { \ - theta[j][i*(order)+k] = data[k]; \ - } \ - } \ +#define CALC_SPLINE(order) \ + { \ + for (int j = 0; (j < DIM); j++) \ + { \ + real dr, div; \ + real data[PME_ORDER_MAX]; \ + \ + dr = xptr[j]; \ + \ + /* dr is relative offset from lower cell limit */ \ + data[(order)-1] = 0; \ + data[1] = dr; \ + data[0] = 1 - dr; \ + \ + for (int k = 3; (k < (order)); k++) \ + { \ + div = 1.0 / (k - 1.0); \ + data[k - 1] = div * dr * data[k - 2]; \ + for (int l = 1; (l < (k - 1)); l++) \ + { \ + data[k - l - 1] = \ + div * ((dr + l) * data[k - l - 2] + (k - l - dr) * data[k - l - 1]); \ + } \ + data[0] = div * (1 - dr) * data[0]; \ + } \ + /* differentiate */ \ + dtheta[j][i * (order) + 0] = -data[0]; \ + for (int k = 1; (k < (order)); k++) \ + { \ + dtheta[j][i * (order) + k] = data[k - 1] - data[k]; \ + } \ + \ + div = 1.0 / ((order)-1); \ + data[(order)-1] = div * dr * data[(order)-2]; \ + for (int l = 1; (l < ((order)-1)); l++) \ + { \ + data[(order)-l - 1] = \ + div * ((dr + l) * data[(order)-l - 2] + ((order)-l - dr) * data[(order)-l - 1]); \ + } \ + data[0] = div * (1 - dr) * data[0]; \ + \ + for (int k = 0; k < (order); k++) \ + { \ + theta[j][i * (order) + k] = data[k]; \ + } \ + } \ } -static void make_bsplines(splinevec theta, splinevec dtheta, int order, - rvec fractx[], int nr, const int ind[], const real coefficient[], - gmx_bool bDoSplines) +static void make_bsplines(splinevec theta, + splinevec dtheta, + int order, + rvec fractx[], + int nr, + const int ind[], + const real coefficient[], + gmx_bool bDoSplines) { /* construct splines for local atoms */ int i, ii; - real *xptr; + real* xptr; for (i = 0; i < nr; i++) { @@ -286,9 +289,9 @@ static void make_bsplines(splinevec theta, splinevec dtheta, int order, assert(order >= 3 && order <= PME_ORDER_MAX); switch (order) { - case 4: CALC_SPLINE(4); break; - case 5: CALC_SPLINE(5); break; - default: CALC_SPLINE(order); break; + case 4: CALC_SPLINE(4) break; + case 5: CALC_SPLINE(5) break; + default: CALC_SPLINE(order) break; } } } @@ -297,44 +300,44 @@ static void make_bsplines(splinevec theta, splinevec dtheta, int order, #pragma GCC diagnostic pop /* This has to be a macro to enable full compiler optimization with xlC (and probably others too) */ -#define DO_BSPLINE(order) \ - for (ithx = 0; (ithx < (order)); ithx++) \ - { \ - index_x = (i0+ithx)*pny*pnz; \ - valx = coefficient*thx[ithx]; \ - \ - for (ithy = 0; (ithy < (order)); ithy++) \ - { \ - valxy = valx*thy[ithy]; \ - index_xy = index_x+(j0+ithy)*pnz; \ - \ - for (ithz = 0; (ithz < (order)); ithz++) \ - { \ - index_xyz = index_xy+(k0+ithz); \ - grid[index_xyz] += valxy*thz[ithz]; \ - } \ - } \ +#define DO_BSPLINE(order) \ + for (ithx = 0; (ithx < (order)); ithx++) \ + { \ + index_x = (i0 + ithx) * pny * pnz; \ + valx = coefficient * thx[ithx]; \ + \ + for (ithy = 0; (ithy < (order)); ithy++) \ + { \ + valxy = valx * thy[ithy]; \ + index_xy = index_x + (j0 + ithy) * pnz; \ + \ + for (ithz = 0; (ithz < (order)); ithz++) \ + { \ + index_xyz = index_xy + (k0 + ithz); \ + grid[index_xyz] += valxy * thz[ithz]; \ + } \ + } \ } -static void spread_coefficients_bsplines_thread(const pmegrid_t *pmegrid, - const PmeAtomComm *atc, - splinedata_t *spline, - struct pme_spline_work gmx_unused *work) +static void spread_coefficients_bsplines_thread(const pmegrid_t* pmegrid, + const PmeAtomComm* atc, + splinedata_t* spline, + struct pme_spline_work gmx_unused* work) { /* spread coefficients from home atoms to local grid */ - real *grid; - int i, nn, n, ithx, ithy, ithz, i0, j0, k0; - const int *idxptr; - int order, norder, index_x, index_xy, index_xyz; - real valx, valxy, coefficient; - real *thx, *thy, *thz; - int pnx, pny, pnz, ndatatot; - int offx, offy, offz; + real* grid; + int i, nn, n, ithx, ithy, ithz, i0, j0, k0; + const int* idxptr; + int order, norder, index_x, index_xy, index_xyz; + real valx, valxy, coefficient; + real * thx, *thy, *thz; + int pnx, pny, pnz, ndatatot; + int offx, offy, offz; #if defined PME_SIMD4_SPREAD_GATHER && !defined PME_SIMD4_UNALIGNED - alignas(GMX_SIMD_ALIGNMENT) real thz_aligned[GMX_SIMD4_WIDTH*2]; + alignas(GMX_SIMD_ALIGNMENT) real thz_aligned[GMX_SIMD4_WIDTH * 2]; #endif pnx = pmegrid->s[XX]; @@ -345,7 +348,7 @@ static void spread_coefficients_bsplines_thread(const pmegrid_t offy = pmegrid->offset[YY]; offz = pmegrid->offset[ZZ]; - ndatatot = pnx*pny*pnz; + ndatatot = pnx * pny * pnz; grid = pmegrid->grid; for (i = 0; i < ndatatot; i++) { @@ -362,11 +365,11 @@ static void spread_coefficients_bsplines_thread(const pmegrid_t if (coefficient != 0) { idxptr = atc->idx[n]; - norder = nn*order; + norder = nn * order; - i0 = idxptr[XX] - offx; - j0 = idxptr[YY] - offy; - k0 = idxptr[ZZ] - offz; + i0 = idxptr[XX] - offx; + j0 = idxptr[YY] - offy; + k0 = idxptr[ZZ] - offz; thx = spline->theta.coefficients[XX] + norder; thy = spline->theta.coefficients[YY] + norder; @@ -376,61 +379,55 @@ static void spread_coefficients_bsplines_thread(const pmegrid_t { case 4: #ifdef PME_SIMD4_SPREAD_GATHER -#ifdef PME_SIMD4_UNALIGNED -#define PME_SPREAD_SIMD4_ORDER4 +# ifdef PME_SIMD4_UNALIGNED +# define PME_SPREAD_SIMD4_ORDER4 +# else +# define PME_SPREAD_SIMD4_ALIGNED +# define PME_ORDER 4 +# endif +# include "pme_simd4.h" #else -#define PME_SPREAD_SIMD4_ALIGNED -#define PME_ORDER 4 -#endif -#include "pme_simd4.h" -#else - DO_BSPLINE(4); + DO_BSPLINE(4) #endif break; case 5: #ifdef PME_SIMD4_SPREAD_GATHER -#define PME_SPREAD_SIMD4_ALIGNED -#define PME_ORDER 5 -#include "pme_simd4.h" +# define PME_SPREAD_SIMD4_ALIGNED +# define PME_ORDER 5 +# include "pme_simd4.h" #else - DO_BSPLINE(5); + DO_BSPLINE(5) #endif break; - default: - DO_BSPLINE(order); - break; + default: DO_BSPLINE(order) break; } } } } -static void copy_local_grid(const gmx_pme_t *pme, const pmegrids_t *pmegrids, - int grid_index, int thread, real *fftgrid) +static void copy_local_grid(const gmx_pme_t* pme, const pmegrids_t* pmegrids, int grid_index, int thread, real* fftgrid) { - ivec local_fft_ndata, local_fft_offset, local_fft_size; - int fft_my, fft_mz; - int nsy, nsz; - ivec nf; - int offx, offy, offz, x, y, z, i0, i0t; - int d; - real *grid_th; - - gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], - local_fft_ndata, - local_fft_offset, + ivec local_fft_ndata, local_fft_offset, local_fft_size; + int fft_my, fft_mz; + int nsy, nsz; + ivec nf; + int offx, offy, offz, x, y, z, i0, i0t; + int d; + real* grid_th; + + gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size); fft_my = local_fft_size[YY]; fft_mz = local_fft_size[ZZ]; - const pmegrid_t *pmegrid = &pmegrids->grid_th[thread]; + const pmegrid_t* pmegrid = &pmegrids->grid_th[thread]; nsy = pmegrid->s[YY]; nsz = pmegrid->s[ZZ]; for (d = 0; d < DIM; d++) { - nf[d] = std::min(pmegrid->n[d] - (pmegrid->order - 1), - local_fft_ndata[d] - pmegrid->offset[d]); + nf[d] = std::min(pmegrid->n[d] - (pmegrid->order - 1), local_fft_ndata[d] - pmegrid->offset[d]); } offx = pmegrid->offset[XX]; @@ -445,41 +442,41 @@ static void copy_local_grid(const gmx_pme_t *pme, const pmegrids_t *pmegrids, { for (y = 0; y < nf[YY]; y++) { - i0 = ((offx + x)*fft_my + (offy + y))*fft_mz + offz; - i0t = (x*nsy + y)*nsz; + i0 = ((offx + x) * fft_my + (offy + y)) * fft_mz + offz; + i0t = (x * nsy + y) * nsz; for (z = 0; z < nf[ZZ]; z++) { - fftgrid[i0+z] = grid_th[i0t+z]; + fftgrid[i0 + z] = grid_th[i0t + z]; } } } } -static void -reduce_threadgrid_overlap(const gmx_pme_t *pme, - const pmegrids_t *pmegrids, int thread, - real *fftgrid, real *commbuf_x, real *commbuf_y, - int grid_index) +static void reduce_threadgrid_overlap(const gmx_pme_t* pme, + const pmegrids_t* pmegrids, + int thread, + real* fftgrid, + real* commbuf_x, + real* commbuf_y, + int grid_index) { - ivec local_fft_ndata, local_fft_offset, local_fft_size; - int fft_nx, fft_ny, fft_nz; - int fft_my, fft_mz; - int buf_my = -1; - int nsy, nsz; - ivec localcopy_end, commcopy_end; - int offx, offy, offz, x, y, z, i0, i0t; - int sx, sy, sz, fx, fy, fz, tx1, ty1, tz1, ox, oy, oz; - gmx_bool bClearBufX, bClearBufY, bClearBufXY, bClearBuf; - gmx_bool bCommX, bCommY; - int d; - int thread_f; + ivec local_fft_ndata, local_fft_offset, local_fft_size; + int fft_nx, fft_ny, fft_nz; + int fft_my, fft_mz; + int buf_my = -1; + int nsy, nsz; + ivec localcopy_end, commcopy_end; + int offx, offy, offz, x, y, z, i0, i0t; + int sx, sy, sz, fx, fy, fz, tx1, ty1, tz1, ox, oy, oz; + gmx_bool bClearBufX, bClearBufY, bClearBufXY, bClearBuf; + gmx_bool bCommX, bCommY; + int d; + int thread_f; const pmegrid_t *pmegrid, *pmegrid_g, *pmegrid_f; - const real *grid_th; - real *commbuf = nullptr; + const real* grid_th; + real* commbuf = nullptr; - gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], - local_fft_ndata, - local_fft_offset, + gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size); fft_nx = local_fft_ndata[XX]; fft_ny = local_fft_ndata[YY]; @@ -507,15 +504,14 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, * This is up to our spreading grid end minus order-1 and * not beyond the local FFT grid. */ - localcopy_end[d] = - std::min(pmegrid->offset[d] + pmegrid->n[d] - (pmegrid->order - 1), - local_fft_ndata[d]); + localcopy_end[d] = std::min(pmegrid->offset[d] + pmegrid->n[d] - (pmegrid->order - 1), + local_fft_ndata[d]); /* Determine up to where our thread needs to copy from the * thread-local charge spreading grid to the communication buffer. * Note: only relevant with communication, ignored otherwise. */ - commcopy_end[d] = localcopy_end[d]; + commcopy_end[d] = localcopy_end[d]; if (pmegrid->ci[d] == pmegrids->nc[d] - 1) { /* The last thread should copy up to the last pme grid line. @@ -548,17 +544,16 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, bCommX = FALSE; if (fx < 0) { - fx += pmegrids->nc[XX]; - ox -= fft_nx; + fx += pmegrids->nc[XX]; + ox -= fft_nx; bCommX = (pme->nnodes_major > 1); } - pmegrid_g = &pmegrids->grid_th[fx*pmegrids->nc[YY]*pmegrids->nc[ZZ]]; - ox += pmegrid_g->offset[XX]; + pmegrid_g = &pmegrids->grid_th[fx * pmegrids->nc[YY] * pmegrids->nc[ZZ]]; + ox += pmegrid_g->offset[XX]; /* Determine the end of our part of the source grid. * Use our thread local source grid and target grid part */ - tx1 = std::min(ox + pmegrid_g->n[XX], - !bCommX ? localcopy_end[XX] : commcopy_end[XX]); + tx1 = std::min(ox + pmegrid_g->n[XX], !bCommX ? localcopy_end[XX] : commcopy_end[XX]); for (sy = 0; sy >= -pmegrids->nthread_comm[YY]; sy--) { @@ -567,17 +562,16 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, bCommY = FALSE; if (fy < 0) { - fy += pmegrids->nc[YY]; - oy -= fft_ny; + fy += pmegrids->nc[YY]; + oy -= fft_ny; bCommY = (pme->nnodes_minor > 1); } - pmegrid_g = &pmegrids->grid_th[fy*pmegrids->nc[ZZ]]; - oy += pmegrid_g->offset[YY]; + pmegrid_g = &pmegrids->grid_th[fy * pmegrids->nc[ZZ]]; + oy += pmegrid_g->offset[YY]; /* Determine the end of our part of the source grid. * Use our thread local source grid and target grid part */ - ty1 = std::min(oy + pmegrid_g->n[YY], - !bCommY ? localcopy_end[YY] : commcopy_end[YY]); + ty1 = std::min(oy + pmegrid_g->n[YY], !bCommY ? localcopy_end[YY] : commcopy_end[YY]); for (sz = 0; sz >= -pmegrids->nthread_comm[ZZ]; sz--) { @@ -589,8 +583,8 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, oz -= fft_nz; } pmegrid_g = &pmegrids->grid_th[fz]; - oz += pmegrid_g->offset[ZZ]; - tz1 = std::min(oz + pmegrid_g->n[ZZ], localcopy_end[ZZ]); + oz += pmegrid_g->offset[ZZ]; + tz1 = std::min(oz + pmegrid_g->n[ZZ], localcopy_end[ZZ]); if (sx == 0 && sy == 0 && sz == 0) { @@ -600,7 +594,7 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, continue; } - thread_f = (fx*pmegrids->nc[YY] + fy)*pmegrids->nc[ZZ] + fz; + thread_f = (fx * pmegrids->nc[YY] + fy) * pmegrids->nc[ZZ] + fz; pmegrid_f = &pmegrids->grid_th[thread_f]; @@ -610,15 +604,11 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, nsz = pmegrid_f->s[ZZ]; #ifdef DEBUG_PME_REDUCE - printf("n%d t%d add %d %2d %2d %2d %2d %2d %2d %2d-%2d %2d-%2d, %2d-%2d %2d-%2d, %2d-%2d %2d-%2d\n", - pme->nodeid, thread, thread_f, - pme->pmegrid_start_ix, - pme->pmegrid_start_iy, - pme->pmegrid_start_iz, - sx, sy, sz, - offx-ox, tx1-ox, offx, tx1, - offy-oy, ty1-oy, offy, ty1, - offz-oz, tz1-oz, offz, tz1); + printf("n%d t%d add %d %2d %2d %2d %2d %2d %2d %2d-%2d %2d-%2d, %2d-%2d " + "%2d-%2d, %2d-%2d %2d-%2d\n", + pme->nodeid, thread, thread_f, pme->pmegrid_start_ix, pme->pmegrid_start_iy, + pme->pmegrid_start_iz, sx, sy, sz, offx - ox, tx1 - ox, offx, tx1, offy - oy, + ty1 - oy, offy, ty1, offz - oz, tz1 - oz, offz, tz1); #endif if (!(bCommX || bCommY)) @@ -628,11 +618,11 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, { for (y = offy; y < ty1; y++) { - i0 = (x*fft_my + y)*fft_mz; - i0t = ((x - ox)*nsy + (y - oy))*nsz - oz; + i0 = (x * fft_my + y) * fft_mz; + i0t = ((x - ox) * nsy + (y - oy)) * nsz - oz; for (z = offz; z < tz1; z++) { - fftgrid[i0+z] += grid_th[i0t+z]; + fftgrid[i0 + z] += grid_th[i0t + z]; } } } @@ -649,13 +639,12 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, * the overlap of the grid part of our local slab * with the part starting at the next slab. */ - buf_my = - pme->overlap[1].s2g1[pme->nodeid_minor] - - pme->overlap[1].s2g0[pme->nodeid_minor+1]; + buf_my = pme->overlap[1].s2g1[pme->nodeid_minor] + - pme->overlap[1].s2g0[pme->nodeid_minor + 1]; if (bCommX) { /* We index commbuf modulo the local grid size */ - commbuf += buf_my*fft_nx*fft_nz; + commbuf += buf_my * fft_nx * fft_nz; bClearBuf = bClearBufXY; bClearBufXY = FALSE; @@ -679,22 +668,22 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, { for (y = offy; y < ty1; y++) { - i0 = (x*buf_my + y)*fft_nz; - i0t = ((x - ox)*nsy + (y - oy))*nsz - oz; + i0 = (x * buf_my + y) * fft_nz; + i0t = ((x - ox) * nsy + (y - oy)) * nsz - oz; if (bClearBuf) { /* First access of commbuf, initialize it */ for (z = offz; z < tz1; z++) { - commbuf[i0+z] = grid_th[i0t+z]; + commbuf[i0 + z] = grid_th[i0t + z]; } } else { for (z = offz; z < tz1; z++) { - commbuf[i0+z] += grid_th[i0t+z]; + commbuf[i0 + z] += grid_th[i0t + z]; } } } @@ -706,7 +695,7 @@ reduce_threadgrid_overlap(const gmx_pme_t *pme, } -static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) +static void sum_fftgrid_dd(const gmx_pme_t* pme, real* fftgrid, int grid_index) { ivec local_fft_ndata, local_fft_offset, local_fft_size; int send_index0, send_nindex; @@ -714,9 +703,9 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) #if GMX_MPI MPI_Status stat; #endif - int recv_size_y; - int size_yx; - int x, y, z, indg, indb; + int recv_size_y; + int size_yx; + int x, y, z, indg, indb; /* Note that this routine is only used for forward communication. * Since the force gathering, unlike the coefficient spreading, @@ -725,15 +714,13 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) * communication setup. */ - gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], - local_fft_ndata, - local_fft_offset, + gmx_parallel_3dfft_real_limits(pme->pfft_setup[grid_index], local_fft_ndata, local_fft_offset, local_fft_size); if (pme->nnodes_minor > 1) { /* Major dimension */ - const pme_overlap_t *overlap = &pme->overlap[1]; + const pme_overlap_t* overlap = &pme->overlap[1]; if (pme->nnodes_major > 1) { @@ -744,49 +731,45 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) size_yx = 0; } #if GMX_MPI - int datasize = (local_fft_ndata[XX] + size_yx)*local_fft_ndata[ZZ]; + int datasize = (local_fft_ndata[XX] + size_yx) * local_fft_ndata[ZZ]; int send_size_y = overlap->send_size; #endif for (size_t ipulse = 0; ipulse < overlap->comm_data.size(); ipulse++) { - send_index0 = - overlap->comm_data[ipulse].send_index0 - - overlap->comm_data[0].send_index0; - send_nindex = overlap->comm_data[ipulse].send_nindex; + send_index0 = overlap->comm_data[ipulse].send_index0 - overlap->comm_data[0].send_index0; + send_nindex = overlap->comm_data[ipulse].send_nindex; /* We don't use recv_index0, as we always receive starting at 0 */ - recv_nindex = overlap->comm_data[ipulse].recv_nindex; - recv_size_y = overlap->comm_data[ipulse].recv_size; + recv_nindex = overlap->comm_data[ipulse].recv_nindex; + recv_size_y = overlap->comm_data[ipulse].recv_size; - auto *sendptr = const_cast(overlap->sendbuf.data()) + send_index0 * local_fft_ndata[ZZ]; - auto *recvptr = const_cast(overlap->recvbuf.data()); + auto* sendptr = + const_cast(overlap->sendbuf.data()) + send_index0 * local_fft_ndata[ZZ]; + auto* recvptr = const_cast(overlap->recvbuf.data()); if (debug != nullptr) { - fprintf(debug, "PME fftgrid comm y %2d x %2d x %2d\n", - local_fft_ndata[XX], send_nindex, local_fft_ndata[ZZ]); + fprintf(debug, "PME fftgrid comm y %2d x %2d x %2d\n", local_fft_ndata[XX], + send_nindex, local_fft_ndata[ZZ]); } #if GMX_MPI int send_id = overlap->comm_data[ipulse].send_id; int recv_id = overlap->comm_data[ipulse].recv_id; - MPI_Sendrecv(sendptr, send_size_y*datasize, GMX_MPI_REAL, - send_id, ipulse, - recvptr, recv_size_y*datasize, GMX_MPI_REAL, - recv_id, ipulse, - overlap->mpi_comm, &stat); + MPI_Sendrecv(sendptr, send_size_y * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr, + recv_size_y * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat); #endif for (x = 0; x < local_fft_ndata[XX]; x++) { for (y = 0; y < recv_nindex; y++) { - indg = (x*local_fft_size[YY] + y)*local_fft_size[ZZ]; - indb = (x*recv_size_y + y)*local_fft_ndata[ZZ]; + indg = (x * local_fft_size[YY] + y) * local_fft_size[ZZ]; + indb = (x * recv_size_y + y) * local_fft_ndata[ZZ]; for (z = 0; z < local_fft_ndata[ZZ]; z++) { - fftgrid[indg+z] += recvptr[indb+z]; + fftgrid[indg + z] += recvptr[indb + z]; } } } @@ -794,16 +777,16 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) if (pme->nnodes_major > 1) { /* Copy from the received buffer to the send buffer for dim 0 */ - sendptr = const_cast(pme->overlap[0].sendbuf.data()); + sendptr = const_cast(pme->overlap[0].sendbuf.data()); for (x = 0; x < size_yx; x++) { for (y = 0; y < recv_nindex; y++) { - indg = (x*local_fft_ndata[YY] + y)*local_fft_ndata[ZZ]; - indb = ((local_fft_ndata[XX] + x)*recv_size_y + y)*local_fft_ndata[ZZ]; + indg = (x * local_fft_ndata[YY] + y) * local_fft_ndata[ZZ]; + indb = ((local_fft_ndata[XX] + x) * recv_size_y + y) * local_fft_ndata[ZZ]; for (z = 0; z < local_fft_ndata[ZZ]; z++) { - sendptr[indg+z] += recvptr[indb+z]; + sendptr[indg + z] += recvptr[indb + z]; } } } @@ -818,39 +801,36 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) if (pme->nnodes_major > 1) { /* Major dimension */ - const pme_overlap_t *overlap = &pme->overlap[0]; + const pme_overlap_t* overlap = &pme->overlap[0]; size_t ipulse = 0; - send_nindex = overlap->comm_data[ipulse].send_nindex; + send_nindex = overlap->comm_data[ipulse].send_nindex; /* We don't use recv_index0, as we always receive starting at 0 */ - recv_nindex = overlap->comm_data[ipulse].recv_nindex; + recv_nindex = overlap->comm_data[ipulse].recv_nindex; if (debug != nullptr) { - fprintf(debug, "PME fftgrid comm x %2d x %2d x %2d\n", - send_nindex, local_fft_ndata[YY], local_fft_ndata[ZZ]); + fprintf(debug, "PME fftgrid comm x %2d x %2d x %2d\n", send_nindex, local_fft_ndata[YY], + local_fft_ndata[ZZ]); } #if GMX_MPI - int datasize = local_fft_ndata[YY]*local_fft_ndata[ZZ]; - int send_id = overlap->comm_data[ipulse].send_id; - int recv_id = overlap->comm_data[ipulse].recv_id; - auto *sendptr = const_cast(overlap->sendbuf.data()); - auto *recvptr = const_cast(overlap->recvbuf.data()); - MPI_Sendrecv(sendptr, send_nindex*datasize, GMX_MPI_REAL, - send_id, ipulse, - recvptr, recv_nindex*datasize, GMX_MPI_REAL, - recv_id, ipulse, - overlap->mpi_comm, &stat); + int datasize = local_fft_ndata[YY] * local_fft_ndata[ZZ]; + int send_id = overlap->comm_data[ipulse].send_id; + int recv_id = overlap->comm_data[ipulse].recv_id; + auto* sendptr = const_cast(overlap->sendbuf.data()); + auto* recvptr = const_cast(overlap->recvbuf.data()); + MPI_Sendrecv(sendptr, send_nindex * datasize, GMX_MPI_REAL, send_id, ipulse, recvptr, + recv_nindex * datasize, GMX_MPI_REAL, recv_id, ipulse, overlap->mpi_comm, &stat); #endif for (x = 0; x < recv_nindex; x++) { for (y = 0; y < local_fft_ndata[YY]; y++) { - indg = (x*local_fft_size[YY] + y)*local_fft_size[ZZ]; - indb = (x*local_fft_ndata[YY] + y)*local_fft_ndata[ZZ]; + indg = (x * local_fft_size[YY] + y) * local_fft_size[ZZ]; + indb = (x * local_fft_ndata[YY] + y) * local_fft_ndata[ZZ]; for (z = 0; z < local_fft_ndata[ZZ]; z++) { fftgrid[indg + z] += overlap->recvbuf[indb + z]; @@ -860,17 +840,21 @@ static void sum_fftgrid_dd(const gmx_pme_t *pme, real *fftgrid, int grid_index) } } -void spread_on_grid(const gmx_pme_t *pme, - PmeAtomComm *atc, const pmegrids_t *grids, - gmx_bool bCalcSplines, gmx_bool bSpread, - real *fftgrid, gmx_bool bDoSplines, int grid_index) +void spread_on_grid(const gmx_pme_t* pme, + PmeAtomComm* atc, + const pmegrids_t* grids, + gmx_bool bCalcSplines, + gmx_bool bSpread, + real* fftgrid, + gmx_bool bDoSplines, + int grid_index) { int nthread, thread; #ifdef PME_TIME_THREADS - gmx_cycles_t c1, c2, c3, ct1a, ct1b, ct1c; - static double cs1 = 0, cs2 = 0, cs3 = 0; - static double cs1a[6] = {0, 0, 0, 0, 0, 0}; - static int cnt = 0; + gmx_cycles_t c1, c2, c3, ct1a, ct1b, ct1c; + static double cs1 = 0, cs2 = 0, cs3 = 0; + static double cs1a[6] = { 0, 0, 0, 0, 0, 0 }; + static int cnt = 0; #endif nthread = pme->nthread; @@ -889,19 +873,19 @@ void spread_on_grid(const gmx_pme_t *pme, { int start, end; - start = atc->numAtoms()* thread /nthread; - end = atc->numAtoms()*(thread+1)/nthread; + start = atc->numAtoms() * thread / nthread; + end = atc->numAtoms() * (thread + 1) / nthread; /* Compute fftgrid index for all atoms, * with help of some extra variables. */ calc_interpolation_idx(pme, atc, start, grid_index, end, thread); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } #ifdef PME_TIME_THREADS - c1 = omp_cyc_end(c1); + c1 = omp_cyc_end(c1); cs1 += (double)c1; #endif @@ -913,7 +897,7 @@ void spread_on_grid(const gmx_pme_t *pme, { try { - splinedata_t *spline; + splinedata_t* spline; /* make local bsplines */ if (grids == nullptr || !pme->bUseThreads) @@ -940,17 +924,15 @@ void spread_on_grid(const gmx_pme_t *pme, if (bCalcSplines) { - make_bsplines(spline->theta.coefficients, - spline->dtheta.coefficients, - pme->pme_order, - as_rvec_array(atc->fractx.data()), spline->n, spline->ind.data(), - atc->coefficient.data(), bDoSplines); + make_bsplines(spline->theta.coefficients, spline->dtheta.coefficients, + pme->pme_order, as_rvec_array(atc->fractx.data()), spline->n, + spline->ind.data(), atc->coefficient.data(), bDoSplines); } if (bSpread) { /* put local atoms on grid. */ - const pmegrid_t *grid = pme->bUseThreads ? &grids->grid_th[thread] : &grids->grid; + const pmegrid_t* grid = pme->bUseThreads ? &grids->grid_th[thread] : &grids->grid; #ifdef PME_TIME_SPREAD ct1a = omp_cyc_start(); @@ -962,15 +944,15 @@ void spread_on_grid(const gmx_pme_t *pme, copy_local_grid(pme, grids, grid_index, thread, fftgrid); } #ifdef PME_TIME_SPREAD - ct1a = omp_cyc_end(ct1a); + ct1a = omp_cyc_end(ct1a); cs1a[thread] += (double)ct1a; #endif } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #ifdef PME_TIME_THREADS - c2 = omp_cyc_end(c2); + c2 = omp_cyc_end(c2); cs2 += (double)c2; #endif @@ -984,16 +966,14 @@ void spread_on_grid(const gmx_pme_t *pme, { try { - reduce_threadgrid_overlap(pme, grids, thread, - fftgrid, - const_cast(pme->overlap[0].sendbuf.data()), - const_cast(pme->overlap[1].sendbuf.data()), - grid_index); + reduce_threadgrid_overlap(pme, grids, thread, fftgrid, + const_cast(pme->overlap[0].sendbuf.data()), + const_cast(pme->overlap[1].sendbuf.data()), grid_index); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #ifdef PME_TIME_THREADS - c3 = omp_cyc_end(c3); + c3 = omp_cyc_end(c3); cs3 += (double)c3; #endif @@ -1011,14 +991,13 @@ void spread_on_grid(const gmx_pme_t *pme, cnt++; if (cnt % 20 == 0) { - printf("idx %.2f spread %.2f red %.2f", - cs1*1e-9, cs2*1e-9, cs3*1e-9); -#ifdef PME_TIME_SPREAD + printf("idx %.2f spread %.2f red %.2f", cs1 * 1e-9, cs2 * 1e-9, cs3 * 1e-9); +# ifdef PME_TIME_SPREAD for (thread = 0; thread < nthread; thread++) { - printf(" %.2f", cs1a[thread]*1e-9); + printf(" %.2f", cs1a[thread] * 1e-9); } -#endif +# endif printf("\n"); } #endif diff --git a/src/gromacs/ewald/pme_spread.cu b/src/gromacs/ewald/pme_spread.cu index 3fbd4dca0f..3d02e43d0d 100644 --- a/src/gromacs/ewald/pme_spread.cu +++ b/src/gromacs/ewald/pme_spread.cu @@ -59,28 +59,28 @@ * Optional second stage of the spline_and_spread_kernel. * * \tparam[in] order PME interpolation order. - * \tparam[in] wrapX A boolean which tells if the grid overlap in dimension X should be wrapped. - * \tparam[in] wrapY A boolean which tells if the grid overlap in dimension Y should be wrapped. - * \tparam[in] useOrderThreads A boolean which Tells if we should use order threads per atom (order*order used if false) - * \param[in] kernelParams Input PME CUDA data in constant memory. - * \param[in] atomIndexOffset Starting atom index for the execution block w.r.t. global memory. - * \param[in] atomCharge Atom charge/coefficient of atom processed by thread. - * \param[in] sm_gridlineIndices Atom gridline indices in the shared memory. - * \param[in] sm_theta Atom spline values in the shared memory. + * \tparam[in] wrapX A boolean which tells if the grid overlap in dimension X should + * be wrapped. \tparam[in] wrapY A boolean which tells if the grid overlap in + * dimension Y should be wrapped. \tparam[in] useOrderThreads A boolean which Tells if we + * should use order threads per atom (order*order used if false) \param[in] kernelParams Input PME + * CUDA data in constant memory. \param[in] atomIndexOffset Starting atom index for the + * execution block w.r.t. global memory. \param[in] atomCharge Atom charge/coefficient of + * atom processed by thread. \param[in] sm_gridlineIndices Atom gridline indices in the shared + * memory. \param[in] sm_theta Atom spline values in the shared memory. */ -template < - const int order, const bool wrapX, const bool wrapY, const bool useOrderThreads > -__device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams kernelParams, - int atomIndexOffset, - const float * atomCharge, - const int * __restrict__ sm_gridlineIndices, - const float * __restrict__ sm_theta) +template +__device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams kernelParams, + int atomIndexOffset, + const float* atomCharge, + const int* __restrict__ sm_gridlineIndices, + const float* __restrict__ sm_theta) { /* Global memory pointer to the output grid */ - float * __restrict__ gm_grid = kernelParams.grid.d_realGrid; + float* __restrict__ gm_grid = kernelParams.grid.d_realGrid; - const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom : c_pmeSpreadGatherAtomsPerWarp; + const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom + : c_pmeSpreadGatherAtomsPerWarp; const int nx = kernelParams.grid.realGridSize[XX]; const int ny = kernelParams.grid.realGridSize[YY]; @@ -98,7 +98,7 @@ __device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams if (chargeCheck & globalCheck) { // Spline Z coordinates - const int ithz = threadIdx.x; + const int ithz = threadIdx.x; const int ixBase = sm_gridlineIndices[atomIndexLocal * DIM + XX] - offx; const int iyBase = sm_gridlineIndices[atomIndexLocal * DIM + YY] - offy; @@ -108,30 +108,30 @@ __device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams iz -= nz; } /* Atom index w.r.t. warp - alternating 0 1 0 1 .. */ - const int atomWarpIndex = atomIndexLocal % atomsPerWarp; + const int atomWarpIndex = atomIndexLocal % atomsPerWarp; /* Warp index w.r.t. block - could probably be obtained easier? */ - const int warpIndex = atomIndexLocal / atomsPerWarp; + const int warpIndex = atomIndexLocal / atomsPerWarp; - const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); - const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); - const float thetaZ = sm_theta[splineIndexZ]; + const int splineIndexBase = getSplineParamIndexBase(warpIndex, atomWarpIndex); + const int splineIndexZ = getSplineParamIndex(splineIndexBase, ZZ, ithz); + const float thetaZ = sm_theta[splineIndexZ]; /* loop not used if order*order threads per atom */ const int ithyMin = useOrderThreads ? 0 : threadIdx.y; const int ithyMax = useOrderThreads ? order : threadIdx.y + 1; for (int ithy = ithyMin; ithy < ithyMax; ithy++) { - int iy = iyBase + ithy; + int iy = iyBase + ithy; if (wrapY & (iy >= ny)) { iy -= ny; } - const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); - float thetaY = sm_theta[splineIndexY]; - const float Val = thetaZ * thetaY * (*atomCharge); + const int splineIndexY = getSplineParamIndex(splineIndexBase, YY, ithy); + float thetaY = sm_theta[splineIndexY]; + const float Val = thetaZ * thetaY * (*atomCharge); assert(isfinite(Val)); - const int offset = iy * pnz + iz; + const int offset = iy * pnz + iz; #pragma unroll for (int ithx = 0; (ithx < order); ithx++) @@ -141,9 +141,10 @@ __device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams { ix -= nx; } - const int gridIndexGlobal = ix * pny * pnz + offset; - const int splineIndexX = getSplineParamIndex(splineIndexBase, XX, ithx); - const float thetaX = sm_theta[splineIndexX]; + const int gridIndexGlobal = ix * pny * pnz + offset; + const int splineIndexX = + getSplineParamIndex(splineIndexBase, XX, ithx); + const float thetaX = sm_theta[splineIndexX]; assert(isfinite(thetaX)); assert(isfinite(gm_grid[gridIndexGlobal])); atomicAdd(gm_grid + gridIndexGlobal, thetaX * Val); @@ -169,44 +170,36 @@ __device__ __forceinline__ void spread_charges(const PmeGpuCudaKernelParams * \tparam[in] useOrderThreads A boolean which tells if we should use order threads per atom (order*order used if false). * \param[in] kernelParams Input PME CUDA data in constant memory. */ -template < - const int order, - const bool computeSplines, - const bool spreadCharges, - const bool wrapX, - const bool wrapY, - const bool writeGlobal, - const bool useOrderThreads - > -__launch_bounds__(c_spreadMaxThreadsPerBlock) -CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE -__global__ void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernelParams) +template +__launch_bounds__(c_spreadMaxThreadsPerBlock) CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE __global__ + void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernelParams) { - const int atomsPerBlock = useOrderThreads ? c_spreadMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom : - c_spreadMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom; + const int atomsPerBlock = + useOrderThreads ? c_spreadMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom4ThPerAtom + : c_spreadMaxThreadsPerBlock / c_pmeSpreadGatherThreadsPerAtom; // Gridline indices, ivec - __shared__ int sm_gridlineIndices[atomsPerBlock * DIM]; + __shared__ int sm_gridlineIndices[atomsPerBlock * DIM]; // Spline values - __shared__ float sm_theta[atomsPerBlock * DIM * order]; - float dtheta; + __shared__ float sm_theta[atomsPerBlock * DIM * order]; + float dtheta; - const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom : - c_pmeSpreadGatherAtomsPerWarp; + const int atomsPerWarp = useOrderThreads ? c_pmeSpreadGatherAtomsPerWarp4ThPerAtom + : c_pmeSpreadGatherAtomsPerWarp; - float3 atomX; - float atomCharge; + float3 atomX; + float atomCharge; - const int blockIndex = blockIdx.y * gridDim.x + blockIdx.x; - const int atomIndexOffset = blockIndex * atomsPerBlock; + const int blockIndex = blockIdx.y * gridDim.x + blockIdx.x; + const int atomIndexOffset = blockIndex * atomsPerBlock; /* Thread index w.r.t. block */ - const int threadLocalId = (threadIdx.z * (blockDim.x * blockDim.y)) - + (threadIdx.y * blockDim.x) + threadIdx.x; + const int threadLocalId = + (threadIdx.z * (blockDim.x * blockDim.y)) + (threadIdx.y * blockDim.x) + threadIdx.x; /* Warp index w.r.t. block - could probably be obtained easier? */ const int warpIndex = threadLocalId / warp_size; /* Atom index w.r.t. warp */ - const int atomWarpIndex = threadIdx.z %atomsPerWarp; + const int atomWarpIndex = threadIdx.z % atomsPerWarp; /* Atom index w.r.t. block/shared memory */ const int atomIndexLocal = warpIndex * atomsPerWarp + atomWarpIndex; /* Atom index w.r.t. global memory */ @@ -223,13 +216,14 @@ __global__ void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernel if (c_useAtomDataPrefetch) { __shared__ float sm_coefficients[atomsPerBlock]; - pme_gpu_stage_atom_data(kernelParams, sm_coefficients, kernelParams.atoms.d_coefficients); + pme_gpu_stage_atom_data(kernelParams, sm_coefficients, + kernelParams.atoms.d_coefficients); __syncthreads(); atomCharge = sm_coefficients[atomIndexLocal]; } else { - atomCharge = kernelParams.atoms.d_coefficients[atomIndexGlobal]; + atomCharge = kernelParams.atoms.d_coefficients[atomIndexGlobal]; } if (computeSplines) @@ -240,21 +234,21 @@ __global__ void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernel __shared__ float sm_coordinates[DIM * atomsPerBlock]; /* Staging coordinates */ - pme_gpu_stage_atom_data(kernelParams, sm_coordinates, kernelParams.atoms.d_coordinates); + pme_gpu_stage_atom_data(kernelParams, sm_coordinates, + kernelParams.atoms.d_coordinates); __syncthreads(); - atomX.x = sm_coordinates[atomIndexLocal*DIM+XX]; - atomX.y = sm_coordinates[atomIndexLocal*DIM+YY]; - atomX.z = sm_coordinates[atomIndexLocal*DIM+ZZ]; + atomX.x = sm_coordinates[atomIndexLocal * DIM + XX]; + atomX.y = sm_coordinates[atomIndexLocal * DIM + YY]; + atomX.z = sm_coordinates[atomIndexLocal * DIM + ZZ]; } else { - atomX.x = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + XX]; - atomX.y = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + YY]; - atomX.z = kernelParams.atoms.d_coordinates[ atomIndexGlobal*DIM + ZZ]; + atomX.x = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + XX]; + atomX.y = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + YY]; + atomX.z = kernelParams.atoms.d_coordinates[atomIndexGlobal * DIM + ZZ]; } - calculate_splines - (kernelParams, atomIndexOffset, atomX, atomCharge, - sm_theta, &dtheta, sm_gridlineIndices); + calculate_splines( + kernelParams, atomIndexOffset, atomX, atomCharge, sm_theta, &dtheta, sm_gridlineIndices); __syncwarp(); } else @@ -264,9 +258,11 @@ __global__ void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernel * as in after running the spline kernel) */ /* Spline data - only thetas (dthetas will only be needed in gather) */ - pme_gpu_stage_atom_data(kernelParams, sm_theta, kernelParams.atoms.d_theta); + pme_gpu_stage_atom_data(kernelParams, sm_theta, + kernelParams.atoms.d_theta); /* Gridline indices */ - pme_gpu_stage_atom_data(kernelParams, sm_gridlineIndices, kernelParams.atoms.d_gridlineIndices); + pme_gpu_stage_atom_data(kernelParams, sm_gridlineIndices, + kernelParams.atoms.d_gridlineIndices); __syncthreads(); } @@ -274,20 +270,27 @@ __global__ void pme_spline_and_spread_kernel(const PmeGpuCudaKernelParams kernel /* Spreading */ if (spreadCharges) { - spread_charges(kernelParams, atomIndexOffset, &atomCharge, - sm_gridlineIndices, sm_theta); + spread_charges( + kernelParams, atomIndexOffset, &atomCharge, sm_gridlineIndices, sm_theta); } } //! Kernel instantiations template __global__ void pme_spline_and_spread_kernel<4, true, true, true, true, true, true>(const PmeGpuCudaKernelParams); -template __global__ void pme_spline_and_spread_kernel<4, true, false, true, true, true, true>(const PmeGpuCudaKernelParams); -template __global__ void pme_spline_and_spread_kernel<4, false, true, true, true, true, true>(const PmeGpuCudaKernelParams); - -template __global__ void pme_spline_and_spread_kernel<4, true, true, true, true, false, true>(const PmeGpuCudaKernelParams); - -template __global__ void pme_spline_and_spread_kernel<4, true, true, true, true, true, false>(const PmeGpuCudaKernelParams); -template __global__ void pme_spline_and_spread_kernel<4, true, false, true, true, true, false>(const PmeGpuCudaKernelParams); -template __global__ void pme_spline_and_spread_kernel<4, false, true, true, true, true, false>(const PmeGpuCudaKernelParams); - -template __global__ void pme_spline_and_spread_kernel<4, true, true, true, true, false, false>(const PmeGpuCudaKernelParams); +template __global__ void +pme_spline_and_spread_kernel<4, true, false, true, true, true, true>(const PmeGpuCudaKernelParams); +template __global__ void +pme_spline_and_spread_kernel<4, false, true, true, true, true, true>(const PmeGpuCudaKernelParams); + +template __global__ void +pme_spline_and_spread_kernel<4, true, true, true, true, false, true>(const PmeGpuCudaKernelParams); + +template __global__ void +pme_spline_and_spread_kernel<4, true, true, true, true, true, false>(const PmeGpuCudaKernelParams); +template __global__ void +pme_spline_and_spread_kernel<4, true, false, true, true, true, false>(const PmeGpuCudaKernelParams); +template __global__ void +pme_spline_and_spread_kernel<4, false, true, true, true, true, false>(const PmeGpuCudaKernelParams); + +template __global__ void +pme_spline_and_spread_kernel<4, true, true, true, true, false, false>(const PmeGpuCudaKernelParams); diff --git a/src/gromacs/ewald/pme_spread.h b/src/gromacs/ewald/pme_spread.h index 5ecbf07107..93e52528f2 100644 --- a/src/gromacs/ewald/pme_spread.h +++ b/src/gromacs/ewald/pme_spread.h @@ -41,10 +41,13 @@ #include "pme_internal.h" -void -spread_on_grid(const gmx_pme_t *pme, - PmeAtomComm *atc, const pmegrids_t *grids, - gmx_bool bCalcSplines, gmx_bool bSpread, - real *fftgrid, gmx_bool bDoSplines, int grid_index); +void spread_on_grid(const gmx_pme_t* pme, + PmeAtomComm* atc, + const pmegrids_t* grids, + gmx_bool bCalcSplines, + gmx_bool bSpread, + real* fftgrid, + gmx_bool bDoSplines, + int grid_index); #endif diff --git a/src/gromacs/ewald/tests/pmebsplinetest.cpp b/src/gromacs/ewald/tests/pmebsplinetest.cpp index c7a952a714..19157f758e 100644 --- a/src/gromacs/ewald/tests/pmebsplinetest.cpp +++ b/src/gromacs/ewald/tests/pmebsplinetest.cpp @@ -75,49 +75,48 @@ typedef std::tuple BSplineModuliInputParameters; /*! \brief Test fixture for testing PME B-spline moduli creation */ class PmeBSplineModuliTest : public ::testing::TestWithParam { - public: - PmeBSplineModuliTest() = default; - //! The whole logic being tested is contained here - void runTest() +public: + PmeBSplineModuliTest() = default; + //! The whole logic being tested is contained here + void runTest() + { + /* Getting the input */ + const BSplineModuliInputParameters parameters = GetParam(); + int pmeOrder; + IVec gridSize; + ModuliType moduliType; + std::tie(gridSize, pmeOrder, moduliType) = parameters; + + /* Describing the test in case it fails */ + SCOPED_TRACE(formatString( + "Testing B-spline moduli creation (%s) for PME order %d, grid size %d %d %d", + (moduliType == ModuliType::P3M) ? "P3M" : "plain", pmeOrder, gridSize[XX], + gridSize[YY], gridSize[ZZ])); + + /* Storing the input where it's needed */ + t_inputrec inputRec; + inputRec.nkx = gridSize[XX]; + inputRec.nky = gridSize[YY]; + inputRec.nkz = gridSize[ZZ]; + inputRec.coulombtype = (moduliType == ModuliType::P3M) ? eelP3M_AD : eelPME; + inputRec.pme_order = pmeOrder; + + /* PME initialization call which checks the inputs and computes the B-spline moduli according to the grid sizes. */ + PmeSafePointer pme = pmeInitEmpty(&inputRec); + + /* Setting up the checker */ + TestReferenceData refData; + TestReferenceChecker checker(refData.rootChecker()); + checker.setDefaultTolerance(relativeToleranceAsPrecisionDependentUlp( + 1.0, c_splineModuliSinglePrecisionUlps, getSplineModuliDoublePrecisionUlps(pmeOrder + 1))); + + /* Perform a correctness check */ + const char* dimString[] = { "X", "Y", "Z" }; + for (int i = 0; i < DIM; i++) { - /* Getting the input */ - const BSplineModuliInputParameters parameters = GetParam(); - int pmeOrder; - IVec gridSize; - ModuliType moduliType; - std::tie(gridSize, pmeOrder, moduliType) = parameters; - - /* Describing the test in case it fails */ - SCOPED_TRACE(formatString("Testing B-spline moduli creation (%s) for PME order %d, grid size %d %d %d", - (moduliType == ModuliType::P3M) ? "P3M" : "plain", - pmeOrder, - gridSize[XX], gridSize[YY], gridSize[ZZ])); - - /* Storing the input where it's needed */ - t_inputrec inputRec; - inputRec.nkx = gridSize[XX]; - inputRec.nky = gridSize[YY]; - inputRec.nkz = gridSize[ZZ]; - inputRec.coulombtype = (moduliType == ModuliType::P3M) ? eelP3M_AD : eelPME; - inputRec.pme_order = pmeOrder; - - /* PME initialization call which checks the inputs and computes the B-spline moduli according to the grid sizes. */ - PmeSafePointer pme = pmeInitEmpty(&inputRec); - - /* Setting up the checker */ - TestReferenceData refData; - TestReferenceChecker checker(refData.rootChecker()); - checker.setDefaultTolerance(relativeToleranceAsPrecisionDependentUlp(1.0, - c_splineModuliSinglePrecisionUlps, - getSplineModuliDoublePrecisionUlps(pmeOrder+1))); - - /* Perform a correctness check */ - const char *dimString[] = { "X", "Y", "Z" }; - for (int i = 0; i < DIM; i++) - { - checker.checkSequenceArray(gridSize[i], pme->bsp_mod[i], dimString[i]); - } + checker.checkSequenceArray(gridSize[i], pme->bsp_mod[i], dimString[i]); } + } }; // Different aliases are needed to reuse the test class without instantiating tests more than once @@ -137,35 +136,20 @@ TEST_P(PmeBSplineModuliCorrectnessTest, ReproducesValues) /* Invalid input instances */ //! Sane interpolation order -const int sanePmeOrder = 4; +const int sanePmeOrder = 4; //! Sane grid size -const IVec saneGridSize = {32, 25, 47}; +const IVec saneGridSize = { 32, 25, 47 }; /*! \brief Hand-picked invalid input for the exception tests */ -std::vector const invalidInputs -{ +std::vector const invalidInputs{ /* Invalid grid sizes */ - BSplineModuliInputParameters { - IVec { - -1, 10, 10 - }, sanePmeOrder, ModuliType::P3M - }, - BSplineModuliInputParameters { - IVec { - 40, 0, 20 - }, sanePmeOrder, ModuliType::P3M - }, - BSplineModuliInputParameters { - IVec { - 64, 2, 64 - }, sanePmeOrder, ModuliType::PME - }, + BSplineModuliInputParameters{ IVec{ -1, 10, 10 }, sanePmeOrder, ModuliType::P3M }, + BSplineModuliInputParameters{ IVec{ 40, 0, 20 }, sanePmeOrder, ModuliType::P3M }, + BSplineModuliInputParameters{ IVec{ 64, 2, 64 }, sanePmeOrder, ModuliType::PME }, /* Invalid interpolation orders */ - BSplineModuliInputParameters { - saneGridSize, 8 + 1, ModuliType::P3M // P3M only supports orders up to 8 - }, - BSplineModuliInputParameters { - saneGridSize, PME_ORDER_MAX + 1, ModuliType::PME + BSplineModuliInputParameters{ + saneGridSize, 8 + 1, ModuliType::P3M // P3M only supports orders up to 8 }, + BSplineModuliInputParameters{ saneGridSize, PME_ORDER_MAX + 1, ModuliType::PME }, }; /*! \brief Instantiation of the PME B-spline moduli creation test with invalid input */ @@ -174,22 +158,14 @@ INSTANTIATE_TEST_CASE_P(InsaneInput, PmeBSplineModuliFailureTest, ::testing::Val /* Valid input instances */ //! A couple of valid inputs for grid sizes. It is good to test both even and odd dimensions. -std::vector const sampleGridSizes -{ - IVec { - 64, 32, 64 - }, - IVec { - 57, 84, 29 - } -}; +std::vector const sampleGridSizes{ IVec{ 64, 32, 64 }, IVec{ 57, 84, 29 } }; /*! \brief Instantiation of the PME B-spline moduli creation test with valid input - up to order of 8 */ -INSTANTIATE_TEST_CASE_P(SaneInput1, PmeBSplineModuliCorrectnessTest, ::testing::Combine( - ::testing::ValuesIn(sampleGridSizes), - ::testing::Range(3, 8 + 1), - ::testing::Values(ModuliType::PME, ModuliType::P3M) - )); -} // namespace -} // namespace test -} // namespace gmx +INSTANTIATE_TEST_CASE_P(SaneInput1, + PmeBSplineModuliCorrectnessTest, + ::testing::Combine(::testing::ValuesIn(sampleGridSizes), + ::testing::Range(3, 8 + 1), + ::testing::Values(ModuliType::PME, ModuliType::P3M))); +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/pmegathertest.cpp b/src/gromacs/ewald/tests/pmegathertest.cpp index 077970b4a9..325a0cdc69 100644 --- a/src/gromacs/ewald/tests/pmegathertest.cpp +++ b/src/gromacs/ewald/tests/pmegathertest.cpp @@ -64,233 +64,122 @@ namespace /* Valid input instances */ //! A couple of valid inputs for boxes. -std::vector const c_sampleBoxes -{ +std::vector const c_sampleBoxes{ // normal box - Matrix3x3 {{ - 8.0F, 0.0F, 0.0F, - 0.0F, 3.4F, 0.0F, - 0.0F, 0.0F, 2.0F - }}, + Matrix3x3{ { 8.0F, 0.0F, 0.0F, 0.0F, 3.4F, 0.0F, 0.0F, 0.0F, 2.0F } }, // triclinic box - Matrix3x3 {{ - 7.0F, 0.0F, 0.0F, - 0.0F, 4.1F, 0.0F, - 3.5F, 2.0F, 12.2F - }}, + Matrix3x3{ { 7.0F, 0.0F, 0.0F, 0.0F, 4.1F, 0.0F, 3.5F, 2.0F, 12.2F } }, }; //! A couple of valid inputs for grid sizes -std::vector const c_sampleGridSizes -{ - IVec { - 16, 12, 14 - }, - IVec { - 13, 15, 11 - } -}; +std::vector const c_sampleGridSizes{ IVec{ 16, 12, 14 }, IVec{ 13, 15, 11 } }; //! Random charges -std::vector const c_sampleChargesFull -{ - 4.95F, 3.11F, 3.97F, 1.08F, 2.09F, 1.1F, 4.13F, 3.31F, 2.8F, 5.83F, 5.09F, 6.1F, 2.86F, 0.24F, 5.76F, 5.19F, 0.72F -}; +std::vector const c_sampleChargesFull{ 4.95F, 3.11F, 3.97F, 1.08F, 2.09F, 1.1F, + 4.13F, 3.31F, 2.8F, 5.83F, 5.09F, 6.1F, + 2.86F, 0.24F, 5.76F, 5.19F, 0.72F }; //! All the input atom gridline indices -std::vector const c_sampleGridLineIndicesFull -{ - IVec { - 4, 2, 6 - }, - IVec { - 1, 4, 10 - }, - IVec { - 0, 6, 6 - }, - IVec { - 0, 1, 4 - }, - IVec { - 6, 3, 0 - }, - IVec { - 7, 2, 2 - }, - IVec { - 8, 3, 1 - }, - IVec { - 4, 0, 3 - }, - IVec { - 0, 0, 0 - }, - IVec { - 8, 5, 8 - }, - IVec { - 4, 4, 2 - }, - IVec { - 7, 1, 7 - }, - IVec { - 8, 5, 5 - }, - IVec { - 2, 6, 5 - }, - IVec { - 1, 6, 2 - }, - IVec { - 7, 1, 8 - }, - IVec { - 3, 5, 1 - }, +std::vector const c_sampleGridLineIndicesFull{ + IVec{ 4, 2, 6 }, IVec{ 1, 4, 10 }, IVec{ 0, 6, 6 }, IVec{ 0, 1, 4 }, IVec{ 6, 3, 0 }, + IVec{ 7, 2, 2 }, IVec{ 8, 3, 1 }, IVec{ 4, 0, 3 }, IVec{ 0, 0, 0 }, IVec{ 8, 5, 8 }, + IVec{ 4, 4, 2 }, IVec{ 7, 1, 7 }, IVec{ 8, 5, 5 }, IVec{ 2, 6, 5 }, IVec{ 1, 6, 2 }, + IVec{ 7, 1, 8 }, IVec{ 3, 5, 1 }, }; // Spline values/derivatives below are also generated randomly, so they are bogus, // but that should not affect the reproducibility, which we're after //! A lot of bogus input spline values - should have at list (max PME order = 5) * (DIM = 3) * (total unique atom number in all test cases = 16) values -std::vector const c_sampleSplineValuesFull -{ - 0.12F, 0.81F, 0.29F, 0.22F, 0.13F, 0.19F, 0.12F, 0.8F, 0.44F, 0.38F, 0.32F, 0.36F, 0.27F, 0.11F, 0.17F, 0.94F, 0.07F, 0.9F, 0.98F, 0.96F, 0.07F, 0.94F, 0.77F, 0.24F, 0.84F, 0.16F, 0.77F, 0.57F, 0.52F, 0.27F, 0.39F, 0.45F, 0.6F, 0.59F, 0.44F, 0.91F, 0.97F, 0.43F, 0.24F, 0.52F, 0.73F, 0.55F, 0.99F, 0.39F, 0.97F, 0.35F, 0.1F, 0.68F, 0.19F, 0.1F, 0.77F, 0.2F, 0.43F, 0.69F, 0.76F, 0.32F, 0.31F, 0.94F, 0.53F, 0.6F, 0.93F, 0.57F, 0.94F, 0.88F, 0.75F, 0.77F, 0.91F, 0.72F, 0.07F, 0.78F, 0.09F, 0.02F, 0.48F, 0.97F, 0.89F, 0.39F, 0.48F, 0.19F, 0.02F, 0.92F, 0.8F, 0.41F, 0.53F, 0.32F, 0.38F, 0.58F, 0.36F, 0.46F, 0.92F, 0.91F, 0.01F, 0.86F, 0.54F, 0.86F, 0.94F, 0.37F, 0.35F, 0.81F, 0.89F, 0.48F, - 0.34F, 0.18F, 0.11F, 0.02F, 0.87F, 0.95F, 0.66F, 0.67F, 0.38F, 0.45F, 0.04F, 0.94F, 0.54F, 0.76F, 0.58F, 0.83F, 0.31F, 0.73F, 0.71F, 0.06F, 0.35F, 0.32F, 0.35F, 0.61F, 0.27F, 0.98F, 0.83F, 0.11F, 0.3F, 0.42F, 0.95F, 0.69F, 0.58F, 0.29F, 0.1F, 0.68F, 0.94F, 0.62F, 0.51F, 0.47F, 0.04F, 0.47F, 0.34F, 0.71F, 0.52F, 0.19F, 0.69F, 0.5F, 0.59F, 0.05F, 0.74F, 0.11F, 0.4F, 0.81F, 0.24F, 0.53F, 0.71F, 0.07F, 0.17F, 0.41F, 0.23F, 0.78F, 0.27F, 0.1F, 0.71F, 0.36F, 0.67F, 0.6F, 0.94F, 0.69F, 0.19F, 0.58F, 0.68F, 0.5F, 0.62F, 0.38F, 0.29F, 0.44F, 0.04F, 0.89F, 0.0F, 0.76F, 0.22F, 0.16F, 0.08F, 0.62F, 0.51F, 0.62F, 0.83F, 0.72F, 0.96F, 0.99F, 0.4F, 0.79F, 0.83F, 0.21F, 0.43F, 0.32F, 0.44F, 0.72F, - 0.21F, 0.4F, 0.93F, 0.07F, 0.11F, 0.41F, 0.24F, 0.04F, 0.36F, 0.15F, 0.92F, 0.08F, 0.99F, 0.35F, 0.42F, 0.7F, 0.17F, 0.39F, 0.69F, 0.0F, 0.86F, 0.89F, 0.59F, 0.81F, 0.77F, 0.15F, 0.89F, 0.17F, 0.76F, 0.67F, 0.58F, 0.78F, 0.26F, 0.19F, 0.69F, 0.18F, 0.46F, 0.6F, 0.69F, 0.23F, 0.34F, 0.3F, 0.64F, 0.34F, 0.6F, 0.99F, 0.69F, 0.57F, 0.75F, 0.07F, 0.36F, 0.75F, 0.81F, 0.8F, 0.42F, 0.09F, 0.94F, 0.66F, 0.35F, 0.67F, 0.34F, 0.66F, 0.02F, 0.47F, 0.78F, 0.21F, 0.02F, 0.18F, 0.42F, 0.2F, 0.46F, 0.34F, 0.4F, 0.46F, 0.96F, 0.86F, 0.25F, 0.25F, 0.22F, 0.37F, 0.59F, 0.19F, 0.45F, 0.61F, 0.04F, 0.71F, 0.77F, 0.51F, 0.77F, 0.15F, 0.78F, 0.36F, 0.62F, 0.24F, 0.86F, 0.2F, 0.77F, 0.08F, 0.09F, 0.3F, - 0.0F, 0.6F, 0.99F, 0.69F, +std::vector const c_sampleSplineValuesFull{ + 0.12F, 0.81F, 0.29F, 0.22F, 0.13F, 0.19F, 0.12F, 0.8F, 0.44F, 0.38F, 0.32F, 0.36F, 0.27F, + 0.11F, 0.17F, 0.94F, 0.07F, 0.9F, 0.98F, 0.96F, 0.07F, 0.94F, 0.77F, 0.24F, 0.84F, 0.16F, + 0.77F, 0.57F, 0.52F, 0.27F, 0.39F, 0.45F, 0.6F, 0.59F, 0.44F, 0.91F, 0.97F, 0.43F, 0.24F, + 0.52F, 0.73F, 0.55F, 0.99F, 0.39F, 0.97F, 0.35F, 0.1F, 0.68F, 0.19F, 0.1F, 0.77F, 0.2F, + 0.43F, 0.69F, 0.76F, 0.32F, 0.31F, 0.94F, 0.53F, 0.6F, 0.93F, 0.57F, 0.94F, 0.88F, 0.75F, + 0.77F, 0.91F, 0.72F, 0.07F, 0.78F, 0.09F, 0.02F, 0.48F, 0.97F, 0.89F, 0.39F, 0.48F, 0.19F, + 0.02F, 0.92F, 0.8F, 0.41F, 0.53F, 0.32F, 0.38F, 0.58F, 0.36F, 0.46F, 0.92F, 0.91F, 0.01F, + 0.86F, 0.54F, 0.86F, 0.94F, 0.37F, 0.35F, 0.81F, 0.89F, 0.48F, 0.34F, 0.18F, 0.11F, 0.02F, + 0.87F, 0.95F, 0.66F, 0.67F, 0.38F, 0.45F, 0.04F, 0.94F, 0.54F, 0.76F, 0.58F, 0.83F, 0.31F, + 0.73F, 0.71F, 0.06F, 0.35F, 0.32F, 0.35F, 0.61F, 0.27F, 0.98F, 0.83F, 0.11F, 0.3F, 0.42F, + 0.95F, 0.69F, 0.58F, 0.29F, 0.1F, 0.68F, 0.94F, 0.62F, 0.51F, 0.47F, 0.04F, 0.47F, 0.34F, + 0.71F, 0.52F, 0.19F, 0.69F, 0.5F, 0.59F, 0.05F, 0.74F, 0.11F, 0.4F, 0.81F, 0.24F, 0.53F, + 0.71F, 0.07F, 0.17F, 0.41F, 0.23F, 0.78F, 0.27F, 0.1F, 0.71F, 0.36F, 0.67F, 0.6F, 0.94F, + 0.69F, 0.19F, 0.58F, 0.68F, 0.5F, 0.62F, 0.38F, 0.29F, 0.44F, 0.04F, 0.89F, 0.0F, 0.76F, + 0.22F, 0.16F, 0.08F, 0.62F, 0.51F, 0.62F, 0.83F, 0.72F, 0.96F, 0.99F, 0.4F, 0.79F, 0.83F, + 0.21F, 0.43F, 0.32F, 0.44F, 0.72F, 0.21F, 0.4F, 0.93F, 0.07F, 0.11F, 0.41F, 0.24F, 0.04F, + 0.36F, 0.15F, 0.92F, 0.08F, 0.99F, 0.35F, 0.42F, 0.7F, 0.17F, 0.39F, 0.69F, 0.0F, 0.86F, + 0.89F, 0.59F, 0.81F, 0.77F, 0.15F, 0.89F, 0.17F, 0.76F, 0.67F, 0.58F, 0.78F, 0.26F, 0.19F, + 0.69F, 0.18F, 0.46F, 0.6F, 0.69F, 0.23F, 0.34F, 0.3F, 0.64F, 0.34F, 0.6F, 0.99F, 0.69F, + 0.57F, 0.75F, 0.07F, 0.36F, 0.75F, 0.81F, 0.8F, 0.42F, 0.09F, 0.94F, 0.66F, 0.35F, 0.67F, + 0.34F, 0.66F, 0.02F, 0.47F, 0.78F, 0.21F, 0.02F, 0.18F, 0.42F, 0.2F, 0.46F, 0.34F, 0.4F, + 0.46F, 0.96F, 0.86F, 0.25F, 0.25F, 0.22F, 0.37F, 0.59F, 0.19F, 0.45F, 0.61F, 0.04F, 0.71F, + 0.77F, 0.51F, 0.77F, 0.15F, 0.78F, 0.36F, 0.62F, 0.24F, 0.86F, 0.2F, 0.77F, 0.08F, 0.09F, + 0.3F, 0.0F, 0.6F, 0.99F, 0.69F, }; //! A lot of bogus input spline derivatives - should have at list (max PME order = 5) * (DIM = 3) * (total unique atom number in all test cases = 16) values -std::vector const c_sampleSplineDerivativesFull -{ - 0.82F, 0.88F, 0.83F, 0.11F, 0.93F, 0.32F, 0.71F, 0.37F, 0.69F, 0.88F, 0.11F, 0.38F, 0.25F, 0.5F, 0.36F, 0.81F, 0.78F, 0.31F, 0.66F, 0.32F, 0.27F, 0.35F, 0.53F, 0.83F, 0.08F, 0.08F, 0.94F, 0.71F, 0.65F, 0.24F, 0.13F, 0.01F, 0.33F, 0.65F, 0.24F, 0.53F, 0.45F, 0.84F, 0.33F, 0.97F, 0.31F, 0.7F, 0.03F, 0.31F, 0.41F, 0.76F, 0.12F, 0.3F, 0.57F, 0.65F, 0.87F, 0.99F, 0.42F, 0.97F, 0.32F, 0.39F, 0.73F, 0.23F, 0.03F, 0.67F, 0.97F, 0.57F, 0.42F, 0.38F, 0.54F, 0.17F, 0.53F, 0.54F, 0.18F, 0.8F, 0.76F, 0.13F, 0.29F, 0.83F, 0.77F, 0.56F, 0.4F, 0.87F, 0.36F, 0.18F, 0.59F, 0.04F, 0.05F, 0.61F, 0.26F, 0.91F, 0.62F, 0.16F, 0.89F, 0.23F, 0.26F, 0.59F, 0.33F, 0.2F, 0.49F, 0.41F, 0.25F, 0.4F, 0.16F, 0.83F, - 0.44F, 0.82F, 0.21F, 0.95F, 0.14F, 0.8F, 0.37F, 0.31F, 0.41F, 0.53F, 0.15F, 0.85F, 0.78F, 0.17F, 0.92F, 0.03F, 0.13F, 0.2F, 0.03F, 0.33F, 0.87F, 0.38F, 0, 0.08F, 0.79F, 0.36F, 0.53F, 0.05F, 0.07F, 0.94F, 0.23F, 0.85F, 0.13F, 0.27F, 0.23F, 0.22F, 0.26F, 0.38F, 0.15F, 0.48F, 0.18F, 0.33F, 0.23F, 0.62F, 0.1F, 0.36F, 0.99F, 0.07F, 0.02F, 0.04F, 0.09F, 0.29F, 0.52F, 0.29F, 0.83F, 0.97F, 0.61F, 0.81F, 0.49F, 0.56F, 0.08F, 0.09F, 0.03F, 0.65F, 0.46F, 0.1F, 0.06F, 0.06F, 0.39F, 0.29F, 0.04F, 0.03F, 0.1F, 0.83F, 0.94F, 0.59F, 0.97F, 0.82F, 0.2F, 0.66F, 0.23F, 0.11F, 0.03F, 0.16F, 0.27F, 0.53F, 0.94F, 0.46F, 0.43F, 0.29F, 0.97F, 0.64F, 0.46F, 0.37F, 0.43F, 0.48F, 0.37F, 0.93F, 0.5F, 0.2F, - 0.92F, 0.09F, 0.74F, 0.55F, 0.44F, 0.05F, 0.13F, 0.17F, 0.79F, 0.44F, 0.11F, 0.6F, 0.64F, 0.05F, 0.96F, 0.3F, 0.45F, 0.47F, 0.42F, 0.74F, 0.91F, 0.06F, 0.89F, 0.24F, 0.26F, 0.68F, 0.4F, 0.88F, 0.5F, 0.65F, 0.48F, 0.15F, 0.0F, 0.41F, 0.67F, 0.4F, 0.31F, 0.73F, 0.77F, 0.36F, 0.26F, 0.74F, 0.46F, 0.56F, 0.78F, 0.92F, 0.32F, 0.9F, 0.06F, 0.55F, 0.6F, 0.13F, 0.38F, 0.93F, 0.5F, 0.92F, 0.96F, 0.82F, 0.0F, 0.04F, 0.9F, 0.55F, 0.97F, 1.0F, 0.23F, 0.46F, 0.52F, 0.49F, 0.0F, 0.32F, 0.16F, 0.4F, 0.62F, 0.36F, 0.03F, 0.63F, 0.16F, 0.58F, 0.97F, 0.03F, 0.44F, 0.07F, 0.22F, 0.75F, 0.32F, 0.61F, 0.94F, 0.33F, 0.7F, 0.57F, 0.5F, 0.84F, 0.7F, 0.47F, 0.18F, 0.09F, 0.25F, 0.77F, 0.94F, 0.85F, - 0.09F, 0.83F, 0.02F, 0.91F, +std::vector const c_sampleSplineDerivativesFull{ + 0.82F, 0.88F, 0.83F, 0.11F, 0.93F, 0.32F, 0.71F, 0.37F, 0.69F, 0.88F, 0.11F, 0.38F, 0.25F, + 0.5F, 0.36F, 0.81F, 0.78F, 0.31F, 0.66F, 0.32F, 0.27F, 0.35F, 0.53F, 0.83F, 0.08F, 0.08F, + 0.94F, 0.71F, 0.65F, 0.24F, 0.13F, 0.01F, 0.33F, 0.65F, 0.24F, 0.53F, 0.45F, 0.84F, 0.33F, + 0.97F, 0.31F, 0.7F, 0.03F, 0.31F, 0.41F, 0.76F, 0.12F, 0.3F, 0.57F, 0.65F, 0.87F, 0.99F, + 0.42F, 0.97F, 0.32F, 0.39F, 0.73F, 0.23F, 0.03F, 0.67F, 0.97F, 0.57F, 0.42F, 0.38F, 0.54F, + 0.17F, 0.53F, 0.54F, 0.18F, 0.8F, 0.76F, 0.13F, 0.29F, 0.83F, 0.77F, 0.56F, 0.4F, 0.87F, + 0.36F, 0.18F, 0.59F, 0.04F, 0.05F, 0.61F, 0.26F, 0.91F, 0.62F, 0.16F, 0.89F, 0.23F, 0.26F, + 0.59F, 0.33F, 0.2F, 0.49F, 0.41F, 0.25F, 0.4F, 0.16F, 0.83F, 0.44F, 0.82F, 0.21F, 0.95F, + 0.14F, 0.8F, 0.37F, 0.31F, 0.41F, 0.53F, 0.15F, 0.85F, 0.78F, 0.17F, 0.92F, 0.03F, 0.13F, + 0.2F, 0.03F, 0.33F, 0.87F, 0.38F, 0, 0.08F, 0.79F, 0.36F, 0.53F, 0.05F, 0.07F, 0.94F, + 0.23F, 0.85F, 0.13F, 0.27F, 0.23F, 0.22F, 0.26F, 0.38F, 0.15F, 0.48F, 0.18F, 0.33F, 0.23F, + 0.62F, 0.1F, 0.36F, 0.99F, 0.07F, 0.02F, 0.04F, 0.09F, 0.29F, 0.52F, 0.29F, 0.83F, 0.97F, + 0.61F, 0.81F, 0.49F, 0.56F, 0.08F, 0.09F, 0.03F, 0.65F, 0.46F, 0.1F, 0.06F, 0.06F, 0.39F, + 0.29F, 0.04F, 0.03F, 0.1F, 0.83F, 0.94F, 0.59F, 0.97F, 0.82F, 0.2F, 0.66F, 0.23F, 0.11F, + 0.03F, 0.16F, 0.27F, 0.53F, 0.94F, 0.46F, 0.43F, 0.29F, 0.97F, 0.64F, 0.46F, 0.37F, 0.43F, + 0.48F, 0.37F, 0.93F, 0.5F, 0.2F, 0.92F, 0.09F, 0.74F, 0.55F, 0.44F, 0.05F, 0.13F, 0.17F, + 0.79F, 0.44F, 0.11F, 0.6F, 0.64F, 0.05F, 0.96F, 0.3F, 0.45F, 0.47F, 0.42F, 0.74F, 0.91F, + 0.06F, 0.89F, 0.24F, 0.26F, 0.68F, 0.4F, 0.88F, 0.5F, 0.65F, 0.48F, 0.15F, 0.0F, 0.41F, + 0.67F, 0.4F, 0.31F, 0.73F, 0.77F, 0.36F, 0.26F, 0.74F, 0.46F, 0.56F, 0.78F, 0.92F, 0.32F, + 0.9F, 0.06F, 0.55F, 0.6F, 0.13F, 0.38F, 0.93F, 0.5F, 0.92F, 0.96F, 0.82F, 0.0F, 0.04F, + 0.9F, 0.55F, 0.97F, 1.0F, 0.23F, 0.46F, 0.52F, 0.49F, 0.0F, 0.32F, 0.16F, 0.4F, 0.62F, + 0.36F, 0.03F, 0.63F, 0.16F, 0.58F, 0.97F, 0.03F, 0.44F, 0.07F, 0.22F, 0.75F, 0.32F, 0.61F, + 0.94F, 0.33F, 0.7F, 0.57F, 0.5F, 0.84F, 0.7F, 0.47F, 0.18F, 0.09F, 0.25F, 0.77F, 0.94F, + 0.85F, 0.09F, 0.83F, 0.02F, 0.91F, }; //! 2 c_sample grids - only non-zero values have to be listed -std::vector const c_sampleGrids -{ - SparseRealGridValuesInput {{ - IVec { - 0, 0, 0 - }, 3.5F - }, { - IVec { - 7, 0, 0 - }, -2.5F - }, - { - IVec { - 3, 5, 7 - }, -0.006F - }, { - IVec { - 1, 6, 7 - }, -2.76F - }, { - IVec { - 3, 1, 2 - }, 0.6F - }, { - IVec { - 6, 2, 4 - }, 7.1F - }, { - IVec { - 4, 5, 6 - }, 4.1F - }, { - IVec { - 4, 4, 6 - }, -3.7F - }, }, - SparseRealGridValuesInput {{ - IVec { - 0, 4, 0 - }, 6.F - }, { - IVec { - 4, 2, 7 - }, 13.76F - }, { - IVec { - 0, 6, 7 - }, 3.6F - }, { - IVec { - 3, 2, 8 - }, 0.61F - }, - { - IVec { - 5, 4, 3 - }, 2.1F - }, - { - IVec { - 2, 5, 10 - }, 3.6F - }, { - IVec { - 5, 3, 6 - }, 2.1F - }, { - IVec { - 6, 6, 6 - }, 6.1F - }, } -}; +std::vector const c_sampleGrids{ SparseRealGridValuesInput{ + { IVec{ 0, 0, 0 }, 3.5F }, + { IVec{ 7, 0, 0 }, -2.5F }, + { IVec{ 3, 5, 7 }, -0.006F }, + { IVec{ 1, 6, 7 }, -2.76F }, + { IVec{ 3, 1, 2 }, 0.6F }, + { IVec{ 6, 2, 4 }, 7.1F }, + { IVec{ 4, 5, 6 }, 4.1F }, + { IVec{ 4, 4, 6 }, -3.7F }, + }, + SparseRealGridValuesInput{ + { IVec{ 0, 4, 0 }, 6.F }, + { IVec{ 4, 2, 7 }, 13.76F }, + { IVec{ 0, 6, 7 }, 3.6F }, + { IVec{ 3, 2, 8 }, 0.61F }, + { IVec{ 5, 4, 3 }, 2.1F }, + { IVec{ 2, 5, 10 }, 3.6F }, + { IVec{ 5, 3, 6 }, 2.1F }, + { IVec{ 6, 6, 6 }, 6.1F }, + } }; //! Input forces for reduction -std::vector const c_sampleForcesFull { - RVec { - 0.02F, 0.87F, 0.95F - }, RVec { - 0.66F, 0.67F, 0.38F - }, RVec { - 0.45F, 0.04F, 0.94F - }, RVec { - 0.54F, 0.76F, 0.58F - }, - RVec { - 0.83F, 0.31F, 0.73F - }, RVec { - 0.71F, 0.06F, 0.35F - }, RVec { - 0.32F, 0.35F, 0.61F - }, RVec { - 0.27F, 0.98F, 0.83F - }, - RVec { - 0.11F, 0.3F, 0.42F - }, RVec { - 0.95F, 0.69F, 0.58F - }, RVec { - 0.29F, 0.1F, 0.68F - }, RVec { - 0.94F, 0.62F, 0.51F - }, - RVec { - 0.47F, 0.04F, 0.47F - }, RVec { - 0.34F, 0.71F, 0.52F - } +std::vector const c_sampleForcesFull{ + RVec{ 0.02F, 0.87F, 0.95F }, RVec{ 0.66F, 0.67F, 0.38F }, RVec{ 0.45F, 0.04F, 0.94F }, + RVec{ 0.54F, 0.76F, 0.58F }, RVec{ 0.83F, 0.31F, 0.73F }, RVec{ 0.71F, 0.06F, 0.35F }, + RVec{ 0.32F, 0.35F, 0.61F }, RVec{ 0.27F, 0.98F, 0.83F }, RVec{ 0.11F, 0.3F, 0.42F }, + RVec{ 0.95F, 0.69F, 0.58F }, RVec{ 0.29F, 0.1F, 0.68F }, RVec{ 0.94F, 0.62F, 0.51F }, + RVec{ 0.47F, 0.04F, 0.47F }, RVec{ 0.34F, 0.71F, 0.52F } }; //! PME orders to test -std::vector const pmeOrders { - 3, 4, 5 -}; +std::vector const pmeOrders{ 3, 4, 5 }; //! Atom counts to test -std::vector const atomCounts { - 1, 2, 13 -}; +std::vector const atomCounts{ 1, 2, 13 }; /* Helper structures for test input */ @@ -307,11 +196,11 @@ struct AtomAndPmeOrderSizedData struct AtomSizedData { //! Gridline indices - GridLineIndicesVector gridLineIndices; + GridLineIndicesVector gridLineIndices; //! Charges - ChargesVector charges; + ChargesVector charges; //! Coordinates - CoordinatesVector coordinates; + CoordinatesVector coordinates; //! Spline data for different orders std::map splineDataByPmeOrder; }; @@ -319,124 +208,133 @@ struct AtomSizedData //! A range of the test input data sets, uniquely identified by the atom count typedef std::map InputDataByAtomCount; -/*! \brief Convenience typedef of the test input parameters - unit cell box, PME interpolation order, grid dimensions, - * grid values, overwriting/reducing the input forces, atom count. +/*! \brief Convenience typedef of the test input parameters - unit cell box, PME interpolation + * order, grid dimensions, grid values, overwriting/reducing the input forces, atom count. * - * The rest of the atom-related input data - gridline indices, spline theta values, spline dtheta values, atom charges - - * is looked up in the inputAtomDataSets_ test fixture variable. + * The rest of the atom-related input data - gridline indices, spline theta values, spline dtheta + * values, atom charges - is looked up in the inputAtomDataSets_ test fixture variable. */ typedef std::tuple GatherInputParameters; //! Test fixture class PmeGatherTest : public ::testing::TestWithParam { - private: - //! Storage of all the input atom datasets - static InputDataByAtomCount s_inputAtomDataSets_; - - public: - PmeGatherTest() = default; - //! Sets the input atom data references once - static void SetUpTestCase() +private: + //! Storage of all the input atom datasets + static InputDataByAtomCount s_inputAtomDataSets_; + +public: + PmeGatherTest() = default; + //! Sets the input atom data references once + static void SetUpTestCase() + { + size_t start = 0; + for (auto atomCount : atomCounts) { - size_t start = 0; - for (auto atomCount : atomCounts) + AtomSizedData atomData; + atomData.gridLineIndices = + GridLineIndicesVector(c_sampleGridLineIndicesFull).subArray(start, atomCount); + atomData.charges = ChargesVector(c_sampleChargesFull).subArray(start, atomCount); + start += atomCount; + atomData.coordinates.resize(atomCount, RVec{ 1e6, 1e7, -1e8 }); + /* The coordinates are intentionally bogus in this test - only the size matters; the gridline indices are fed directly as inputs */ + for (auto pmeOrder : pmeOrders) { - AtomSizedData atomData; - atomData.gridLineIndices = GridLineIndicesVector(c_sampleGridLineIndicesFull).subArray(start, atomCount); - atomData.charges = ChargesVector(c_sampleChargesFull).subArray(start, atomCount); - start += atomCount; - atomData.coordinates.resize(atomCount, RVec {1e6, 1e7, -1e8}); - /* The coordinates are intentionally bogus in this test - only the size matters; the gridline indices are fed directly as inputs */ - for (auto pmeOrder : pmeOrders) + AtomAndPmeOrderSizedData splineData; + const size_t dimSize = atomCount * pmeOrder; + for (int dimIndex = 0; dimIndex < DIM; dimIndex++) { - AtomAndPmeOrderSizedData splineData; - const size_t dimSize = atomCount * pmeOrder; - for (int dimIndex = 0; dimIndex < DIM; dimIndex++) - { - splineData.splineValues[dimIndex] = SplineParamsDimVector(c_sampleSplineValuesFull).subArray(dimIndex * dimSize, dimSize); - splineData.splineDerivatives[dimIndex] = SplineParamsDimVector(c_sampleSplineDerivativesFull).subArray(dimIndex * dimSize, dimSize); - } - atomData.splineDataByPmeOrder[pmeOrder] = splineData; + splineData.splineValues[dimIndex] = + SplineParamsDimVector(c_sampleSplineValuesFull).subArray(dimIndex * dimSize, dimSize); + splineData.splineDerivatives[dimIndex] = + SplineParamsDimVector(c_sampleSplineDerivativesFull).subArray(dimIndex * dimSize, dimSize); } - s_inputAtomDataSets_[atomCount] = atomData; + atomData.splineDataByPmeOrder[pmeOrder] = splineData; } + s_inputAtomDataSets_[atomCount] = atomData; } - //! The test - void runTest() + } + //! The test + void runTest() + { + /* Getting the input */ + Matrix3x3 box; + int pmeOrder; + IVec gridSize; + size_t atomCount; + SparseRealGridValuesInput nonZeroGridValues; + PmeForceOutputHandling inputForceTreatment; + std::tie(box, pmeOrder, gridSize, nonZeroGridValues, inputForceTreatment, atomCount) = GetParam(); + auto inputAtomData = s_inputAtomDataSets_[atomCount]; + auto inputAtomSplineData = inputAtomData.splineDataByPmeOrder[pmeOrder]; + + /* Storing the input where it's needed, running the test */ + t_inputrec inputRec; + inputRec.nkx = gridSize[XX]; + inputRec.nky = gridSize[YY]; + inputRec.nkz = gridSize[ZZ]; + inputRec.pme_order = pmeOrder; + inputRec.coulombtype = eelPME; + inputRec.epsilon_r = 1.0; + + TestReferenceData refData; + for (const auto& context : getPmeTestEnv()->getHardwareContexts()) { - /* Getting the input */ - Matrix3x3 box; - int pmeOrder; - IVec gridSize; - size_t atomCount; - SparseRealGridValuesInput nonZeroGridValues; - PmeForceOutputHandling inputForceTreatment; - std::tie(box, pmeOrder, gridSize, nonZeroGridValues, inputForceTreatment, atomCount) = GetParam(); - auto inputAtomData = s_inputAtomDataSets_[atomCount]; - auto inputAtomSplineData = inputAtomData.splineDataByPmeOrder[pmeOrder]; - - /* Storing the input where it's needed, running the test */ - t_inputrec inputRec; - inputRec.nkx = gridSize[XX]; - inputRec.nky = gridSize[YY]; - inputRec.nkz = gridSize[ZZ]; - inputRec.pme_order = pmeOrder; - inputRec.coulombtype = eelPME; - inputRec.epsilon_r = 1.0; - - TestReferenceData refData; - for (const auto &context : getPmeTestEnv()->getHardwareContexts()) + CodePath codePath = context->getCodePath(); + const bool supportedInput = + pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); + if (!supportedInput) { - CodePath codePath = context->getCodePath(); - const bool supportedInput = pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); - if (!supportedInput) - { - /* Testing the failure for the unsupported input */ - EXPECT_THROW(pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, box), NotImplementedError); - continue; - } - - /* Describing the test uniquely */ - SCOPED_TRACE(formatString("Testing force gathering with %s %sfor PME grid size %d %d %d" - ", order %d, %zu atoms, %s", - codePathToString(codePath), context->getDescription().c_str(), - gridSize[XX], gridSize[YY], gridSize[ZZ], - pmeOrder, - atomCount, - (inputForceTreatment == PmeForceOutputHandling::ReduceWithInput) ? "with reduction" : "without reduction" - )); - - PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec, codePath, context->getDeviceInfo(), context->getPmeGpuProgram(), box); - std::unique_ptr stateGpu = (codePath == CodePath::GPU) ? makeStatePropagatorDataGpu(*pmeSafe.get()) : nullptr; - - pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, inputAtomData.coordinates, inputAtomData.charges); + /* Testing the failure for the unsupported input */ + EXPECT_THROW(pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, box), NotImplementedError); + continue; + } - /* Setting some more inputs */ - pmeSetRealGrid(pmeSafe.get(), codePath, nonZeroGridValues); - pmeSetGridLineIndices(pmeSafe.get(), codePath, inputAtomData.gridLineIndices); - for (int dimIndex = 0; dimIndex < DIM; dimIndex++) - { - pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineValues[dimIndex], PmeSplineDataType::Values, dimIndex); - pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineDerivatives[dimIndex], PmeSplineDataType::Derivatives, dimIndex); - } + /* Describing the test uniquely */ + SCOPED_TRACE( + formatString("Testing force gathering with %s %sfor PME grid size %d %d %d" + ", order %d, %zu atoms, %s", + codePathToString(codePath), context->getDescription().c_str(), + gridSize[XX], gridSize[YY], gridSize[ZZ], pmeOrder, atomCount, + (inputForceTreatment == PmeForceOutputHandling::ReduceWithInput) + ? "with reduction" + : "without reduction")); + + PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec, codePath, context->getDeviceInfo(), + context->getPmeGpuProgram(), box); + std::unique_ptr stateGpu = + (codePath == CodePath::GPU) ? makeStatePropagatorDataGpu(*pmeSafe.get()) : nullptr; + + pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, inputAtomData.coordinates, + inputAtomData.charges); + + /* Setting some more inputs */ + pmeSetRealGrid(pmeSafe.get(), codePath, nonZeroGridValues); + pmeSetGridLineIndices(pmeSafe.get(), codePath, inputAtomData.gridLineIndices); + for (int dimIndex = 0; dimIndex < DIM; dimIndex++) + { + pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineValues[dimIndex], + PmeSplineDataType::Values, dimIndex); + pmeSetSplineData(pmeSafe.get(), codePath, inputAtomSplineData.splineDerivatives[dimIndex], + PmeSplineDataType::Derivatives, dimIndex); + } - /* Explicitly copying the sample forces to be able to modify them */ - auto inputForcesFull(c_sampleForcesFull); - GMX_RELEASE_ASSERT(inputForcesFull.size() >= atomCount, "Bad input forces size"); - auto forces = ForcesVector(inputForcesFull).subArray(0, atomCount); + /* Explicitly copying the sample forces to be able to modify them */ + auto inputForcesFull(c_sampleForcesFull); + GMX_RELEASE_ASSERT(inputForcesFull.size() >= atomCount, "Bad input forces size"); + auto forces = ForcesVector(inputForcesFull).subArray(0, atomCount); - /* Running the force gathering itself */ - pmePerformGather(pmeSafe.get(), codePath, inputForceTreatment, forces); - pmeFinalizeTest(pmeSafe.get(), codePath); + /* Running the force gathering itself */ + pmePerformGather(pmeSafe.get(), codePath, inputForceTreatment, forces); + pmeFinalizeTest(pmeSafe.get(), codePath); - /* Check the output forces correctness */ - TestReferenceChecker forceChecker(refData.rootChecker()); - const auto ulpTolerance = 3 * pmeOrder; - forceChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpTolerance)); - forceChecker.checkSequence(forces.begin(), forces.end(), "Forces"); - } + /* Check the output forces correctness */ + TestReferenceChecker forceChecker(refData.rootChecker()); + const auto ulpTolerance = 3 * pmeOrder; + forceChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpTolerance)); + forceChecker.checkSequence(forces.begin(), forces.end(), "Forces"); } + } }; // An instance of static atom data @@ -449,13 +347,16 @@ TEST_P(PmeGatherTest, ReproducesOutputs) } //! Instantiation of the PME gathering test -INSTANTIATE_TEST_CASE_P(SaneInput, PmeGatherTest, ::testing::Combine(::testing::ValuesIn(c_sampleBoxes), - ::testing::ValuesIn(pmeOrders), - ::testing::ValuesIn(c_sampleGridSizes), - ::testing::ValuesIn(c_sampleGrids), - ::testing::Values(PmeForceOutputHandling::Set, PmeForceOutputHandling::ReduceWithInput), - ::testing::ValuesIn(atomCounts))); - -} // namespace -} // namespace test -} // namespace gmx +INSTANTIATE_TEST_CASE_P(SaneInput, + PmeGatherTest, + ::testing::Combine(::testing::ValuesIn(c_sampleBoxes), + ::testing::ValuesIn(pmeOrders), + ::testing::ValuesIn(c_sampleGridSizes), + ::testing::ValuesIn(c_sampleGrids), + ::testing::Values(PmeForceOutputHandling::Set, + PmeForceOutputHandling::ReduceWithInput), + ::testing::ValuesIn(atomCounts))); + +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/pmesolvetest.cpp b/src/gromacs/ewald/tests/pmesolvetest.cpp index af049a2e39..99af453394 100644 --- a/src/gromacs/ewald/tests/pmesolvetest.cpp +++ b/src/gromacs/ewald/tests/pmesolvetest.cpp @@ -71,173 +71,178 @@ typedef std::tuple { - public: - PmeSolveTest() = default; - - //! The test - void runTest() +public: + PmeSolveTest() = default; + + //! The test + void runTest() + { + /* Getting the input */ + Matrix3x3 box; + IVec gridSize; + SparseComplexGridValuesInput nonZeroGridValues; + double epsilon_r; + double ewaldCoeff_q; + double ewaldCoeff_lj; + PmeSolveAlgorithm method; + std::tie(box, gridSize, nonZeroGridValues, epsilon_r, ewaldCoeff_q, ewaldCoeff_lj, method) = + GetParam(); + + /* Storing the input where it's needed, running the test */ + t_inputrec inputRec; + inputRec.nkx = gridSize[XX]; + inputRec.nky = gridSize[YY]; + inputRec.nkz = gridSize[ZZ]; + inputRec.pme_order = 4; + inputRec.coulombtype = eelPME; + inputRec.epsilon_r = epsilon_r; + switch (method) { - /* Getting the input */ - Matrix3x3 box; - IVec gridSize; - SparseComplexGridValuesInput nonZeroGridValues; - double epsilon_r; - double ewaldCoeff_q; - double ewaldCoeff_lj; - PmeSolveAlgorithm method; - std::tie(box, gridSize, nonZeroGridValues, epsilon_r, ewaldCoeff_q, ewaldCoeff_lj, method) = GetParam(); - - /* Storing the input where it's needed, running the test */ - t_inputrec inputRec; - inputRec.nkx = gridSize[XX]; - inputRec.nky = gridSize[YY]; - inputRec.nkz = gridSize[ZZ]; - inputRec.pme_order = 4; - inputRec.coulombtype = eelPME; - inputRec.epsilon_r = epsilon_r; - switch (method) - { - case PmeSolveAlgorithm::Coulomb: - break; + case PmeSolveAlgorithm::Coulomb: break; - case PmeSolveAlgorithm::LennardJones: - inputRec.vdwtype = evdwPME; - break; + case PmeSolveAlgorithm::LennardJones: inputRec.vdwtype = evdwPME; break; - default: - GMX_THROW(InternalError("Unknown PME solver")); - } + default: GMX_THROW(InternalError("Unknown PME solver")); + } - TestReferenceData refData; - for (const auto &context : getPmeTestEnv()->getHardwareContexts()) + TestReferenceData refData; + for (const auto& context : getPmeTestEnv()->getHardwareContexts()) + { + CodePath codePath = context->getCodePath(); + const bool supportedInput = + pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); + if (!supportedInput) { - CodePath codePath = context->getCodePath(); - const bool supportedInput = pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); - if (!supportedInput) - { - /* Testing the failure for the unsupported input */ - EXPECT_THROW(pmeInitEmpty(&inputRec, codePath, nullptr, nullptr, box, ewaldCoeff_q, ewaldCoeff_lj), NotImplementedError); - continue; - } + /* Testing the failure for the unsupported input */ + EXPECT_THROW(pmeInitEmpty(&inputRec, codePath, nullptr, nullptr, box, ewaldCoeff_q, + ewaldCoeff_lj), + NotImplementedError); + continue; + } - std::map gridOrderingsToTest = {{GridOrdering::YZX, "YZX"}}; - if (codePath == CodePath::GPU) - { - gridOrderingsToTest[GridOrdering::XYZ] = "XYZ"; - } - for (const auto &gridOrdering : gridOrderingsToTest) + std::map gridOrderingsToTest = { { GridOrdering::YZX, + "YZX" } }; + if (codePath == CodePath::GPU) + { + gridOrderingsToTest[GridOrdering::XYZ] = "XYZ"; + } + for (const auto& gridOrdering : gridOrderingsToTest) + { + for (bool computeEnergyAndVirial : { false, true }) { - for (bool computeEnergyAndVirial : {false, true}) + /* Describing the test*/ + SCOPED_TRACE(formatString( + "Testing solving (%s, %s, %s energy/virial) with %s %sfor PME grid " + "size %d %d %d, Ewald coefficients %g %g", + (method == PmeSolveAlgorithm::LennardJones) ? "Lennard-Jones" : "Coulomb", + gridOrdering.second.c_str(), computeEnergyAndVirial ? "with" : "without", + codePathToString(codePath), context->getDescription().c_str(), + gridSize[XX], gridSize[YY], gridSize[ZZ], ewaldCoeff_q, ewaldCoeff_lj)); + + /* Running the test */ + PmeSafePointer pmeSafe = + pmeInitEmpty(&inputRec, codePath, context->getDeviceInfo(), + context->getPmeGpuProgram(), box, ewaldCoeff_q, ewaldCoeff_lj); + pmeSetComplexGrid(pmeSafe.get(), codePath, gridOrdering.first, nonZeroGridValues); + const real cellVolume = box[0] * box[4] * box[8]; + // FIXME - this is box[XX][XX] * box[YY][YY] * box[ZZ][ZZ], should be stored in the PME structure + pmePerformSolve(pmeSafe.get(), codePath, method, cellVolume, gridOrdering.first, + computeEnergyAndVirial); + pmeFinalizeTest(pmeSafe.get(), codePath); + + /* Check the outputs */ + TestReferenceChecker checker(refData.rootChecker()); + + SparseComplexGridValuesOutput nonZeroGridValuesOutput = + pmeGetComplexGrid(pmeSafe.get(), codePath, gridOrdering.first); + /* Transformed grid */ + TestReferenceChecker gridValuesChecker( + checker.checkCompound("NonZeroGridValues", "ComplexSpaceGrid")); + + real gridValuesMagnitude = 1.0; + for (const auto& point : nonZeroGridValuesOutput) { - /* Describing the test*/ - SCOPED_TRACE(formatString("Testing solving (%s, %s, %s energy/virial) with %s %sfor PME grid size %d %d %d, Ewald coefficients %g %g", - (method == PmeSolveAlgorithm::LennardJones) ? "Lennard-Jones" : "Coulomb", - gridOrdering.second.c_str(), - computeEnergyAndVirial ? "with" : "without", - codePathToString(codePath), - context->getDescription().c_str(), - gridSize[XX], gridSize[YY], gridSize[ZZ], - ewaldCoeff_q, ewaldCoeff_lj - )); - - /* Running the test */ - PmeSafePointer pmeSafe = pmeInitEmpty(&inputRec, codePath, context->getDeviceInfo(), - context->getPmeGpuProgram(), box, ewaldCoeff_q, ewaldCoeff_lj); - pmeSetComplexGrid(pmeSafe.get(), codePath, gridOrdering.first, nonZeroGridValues); - const real cellVolume = box[0] * box[4] * box[8]; - //FIXME - this is box[XX][XX] * box[YY][YY] * box[ZZ][ZZ], should be stored in the PME structure - pmePerformSolve(pmeSafe.get(), codePath, method, cellVolume, gridOrdering.first, computeEnergyAndVirial); - pmeFinalizeTest(pmeSafe.get(), codePath); - - /* Check the outputs */ - TestReferenceChecker checker(refData.rootChecker()); - - SparseComplexGridValuesOutput nonZeroGridValuesOutput = pmeGetComplexGrid(pmeSafe.get(), codePath, gridOrdering.first); - /* Transformed grid */ - TestReferenceChecker gridValuesChecker(checker.checkCompound("NonZeroGridValues", "ComplexSpaceGrid")); - - real gridValuesMagnitude = 1.0; - for (const auto &point : nonZeroGridValuesOutput) - { - gridValuesMagnitude = std::max(std::fabs(point.second.re), gridValuesMagnitude); - gridValuesMagnitude = std::max(std::fabs(point.second.im), gridValuesMagnitude); - } - // Spline moduli participate 3 times in the computation; 2 is an additional factor for SIMD exp() precision - uint64_t gridUlpToleranceFactor = DIM * 2; - if (method == PmeSolveAlgorithm::LennardJones) + gridValuesMagnitude = std::max(std::fabs(point.second.re), gridValuesMagnitude); + gridValuesMagnitude = std::max(std::fabs(point.second.im), gridValuesMagnitude); + } + // Spline moduli participate 3 times in the computation; 2 is an additional factor for SIMD exp() precision + uint64_t gridUlpToleranceFactor = DIM * 2; + if (method == PmeSolveAlgorithm::LennardJones) + { + // Lennard Jones is more complex and also uses erfc(), relax more + gridUlpToleranceFactor *= 2; + } + const uint64_t splineModuliDoublePrecisionUlps = + getSplineModuliDoublePrecisionUlps(inputRec.pme_order + 1); + auto gridTolerance = relativeToleranceAsPrecisionDependentUlp( + gridValuesMagnitude, gridUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, + gridUlpToleranceFactor * splineModuliDoublePrecisionUlps); + gridValuesChecker.setDefaultTolerance(gridTolerance); + + for (const auto& point : nonZeroGridValuesOutput) + { + // we want an additional safeguard for denormal numbers as they cause an exception in string conversion; + // however, using GMX_REAL_MIN causes an "unused item warning" for single precision builds + if (fabs(point.second.re) >= GMX_FLOAT_MIN) { - // Lennard Jones is more complex and also uses erfc(), relax more - gridUlpToleranceFactor *= 2; + gridValuesChecker.checkReal(point.second.re, (point.first + " re").c_str()); } - const uint64_t splineModuliDoublePrecisionUlps - = getSplineModuliDoublePrecisionUlps(inputRec.pme_order + 1); - auto gridTolerance - = relativeToleranceAsPrecisionDependentUlp(gridValuesMagnitude, - gridUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, - gridUlpToleranceFactor * splineModuliDoublePrecisionUlps); - gridValuesChecker.setDefaultTolerance(gridTolerance); - - for (const auto &point : nonZeroGridValuesOutput) + if (fabs(point.second.im) >= GMX_FLOAT_MIN) { - // we want an additional safeguard for denormal numbers as they cause an exception in string conversion; - // however, using GMX_REAL_MIN causes an "unused item warning" for single precision builds - if (fabs(point.second.re) >= GMX_FLOAT_MIN) - { - gridValuesChecker.checkReal(point.second.re, (point.first + " re").c_str()); - } - if (fabs(point.second.im) >= GMX_FLOAT_MIN) - { - gridValuesChecker.checkReal(point.second.im, (point.first + " im").c_str()); - } + gridValuesChecker.checkReal(point.second.im, (point.first + " im").c_str()); } + } - if (computeEnergyAndVirial) + if (computeEnergyAndVirial) + { + // Extract the energy and virial + const auto output = + pmeGetReciprocalEnergyAndVirial(pmeSafe.get(), codePath, method); + const auto& energy = (method == PmeSolveAlgorithm::Coulomb) + ? output.coulombEnergy_ + : output.lennardJonesEnergy_; + const auto& virial = (method == PmeSolveAlgorithm::Coulomb) + ? output.coulombVirial_ + : output.lennardJonesVirial_; + + // These quantities are computed based on the grid values, so must have + // checking relative tolerances at least as large. Virial needs more flops + // than energy, so needs a larger tolerance. + + /* Energy */ + double energyMagnitude = 10.0; + // TODO This factor is arbitrary, do a proper error-propagation analysis + uint64_t energyUlpToleranceFactor = gridUlpToleranceFactor * 2; + auto energyTolerance = relativeToleranceAsPrecisionDependentUlp( + energyMagnitude, energyUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, + energyUlpToleranceFactor * splineModuliDoublePrecisionUlps); + TestReferenceChecker energyChecker(checker); + energyChecker.setDefaultTolerance(energyTolerance); + energyChecker.checkReal(energy, "Energy"); + + /* Virial */ + double virialMagnitude = 1000.0; + // TODO This factor is arbitrary, do a proper error-propagation analysis + uint64_t virialUlpToleranceFactor = energyUlpToleranceFactor * 2; + auto virialTolerance = relativeToleranceAsPrecisionDependentUlp( + virialMagnitude, virialUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, + virialUlpToleranceFactor * splineModuliDoublePrecisionUlps); + TestReferenceChecker virialChecker( + checker.checkCompound("Matrix", "Virial")); + virialChecker.setDefaultTolerance(virialTolerance); + for (int i = 0; i < DIM; i++) { - // Extract the energy and virial - const auto output = pmeGetReciprocalEnergyAndVirial(pmeSafe.get(), codePath, method); - const auto &energy = (method == PmeSolveAlgorithm::Coulomb) ? output.coulombEnergy_ : output.lennardJonesEnergy_; - const auto &virial = (method == PmeSolveAlgorithm::Coulomb) ? output.coulombVirial_ : output.lennardJonesVirial_; - - // These quantities are computed based on the grid values, so must have - // checking relative tolerances at least as large. Virial needs more flops - // than energy, so needs a larger tolerance. - - /* Energy */ - double energyMagnitude = 10.0; - // TODO This factor is arbitrary, do a proper error-propagation analysis - uint64_t energyUlpToleranceFactor = gridUlpToleranceFactor * 2; - auto energyTolerance - = relativeToleranceAsPrecisionDependentUlp(energyMagnitude, - energyUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, - energyUlpToleranceFactor * splineModuliDoublePrecisionUlps); - TestReferenceChecker energyChecker(checker); - energyChecker.setDefaultTolerance(energyTolerance); - energyChecker.checkReal(energy, "Energy"); - - /* Virial */ - double virialMagnitude = 1000.0; - // TODO This factor is arbitrary, do a proper error-propagation analysis - uint64_t virialUlpToleranceFactor = energyUlpToleranceFactor * 2; - auto virialTolerance - = relativeToleranceAsPrecisionDependentUlp(virialMagnitude, - virialUlpToleranceFactor * c_splineModuliSinglePrecisionUlps, - virialUlpToleranceFactor * splineModuliDoublePrecisionUlps); - TestReferenceChecker virialChecker(checker.checkCompound("Matrix", "Virial")); - virialChecker.setDefaultTolerance(virialTolerance); - for (int i = 0; i < DIM; i++) + for (int j = 0; j <= i; j++) { - for (int j = 0; j <= i; j++) - { - std::string valueId = formatString("Cell %d %d", i, j); - virialChecker.checkReal(virial[i][j], valueId.c_str()); - } + std::string valueId = formatString("Cell %d %d", i, j); + virialChecker.checkReal(virial[i][j], valueId.c_str()); } } } } - } } + } }; /*! \brief Test for PME solving */ @@ -249,97 +254,36 @@ TEST_P(PmeSolveTest, ReproducesOutputs) /* Valid input instances */ //! A couple of valid inputs for boxes. -std::vector const c_sampleBoxes -{ +std::vector const c_sampleBoxes{ // normal box - Matrix3x3 {{ - 8.0F, 0.0F, 0.0F, - 0.0F, 3.4F, 0.0F, - 0.0F, 0.0F, 2.0F - }}, + Matrix3x3{ { 8.0F, 0.0F, 0.0F, 0.0F, 3.4F, 0.0F, 0.0F, 0.0F, 2.0F } }, // triclinic box - Matrix3x3 {{ - 7.0F, 0.0F, 0.0F, - 0.0F, 4.1F, 0.0F, - 3.5F, 2.0F, 12.2F - }}, + Matrix3x3{ { 7.0F, 0.0F, 0.0F, 0.0F, 4.1F, 0.0F, 3.5F, 2.0F, 12.2F } }, }; //! A couple of valid inputs for grid sizes -std::vector const c_sampleGridSizes -{ - IVec { - 16, 12, 28 - }, - IVec { - 9, 7, 23 - } -}; +std::vector const c_sampleGridSizes{ IVec{ 16, 12, 28 }, IVec{ 9, 7, 23 } }; //! Moved out from instantiations for readability -const auto c_inputBoxes = ::testing::ValuesIn(c_sampleBoxes); +const auto c_inputBoxes = ::testing::ValuesIn(c_sampleBoxes); //! Moved out from instantiations for readability const auto c_inputGridSizes = ::testing::ValuesIn(c_sampleGridSizes); //! 2 sample complex grids - only non-zero values have to be listed -std::vector const c_sampleGrids -{ - SparseComplexGridValuesInput {{ - IVec { - 0, 0, 0 - }, t_complex { - 3.5F, 6.7F - } - }, { - IVec { - 7, 0, 0 - }, t_complex { - -2.5F, -0.7F - } - }, { - IVec { - 3, 5, 7 - }, t_complex { - -0.006F, 1e-8F - } - }, { - IVec { - 3, 1, 2 - }, t_complex { - 0.6F, 7.9F - } - }, { - IVec { - 6, 2, 4 - }, t_complex { - 30.1F, 2.45F - } - }, }, - SparseComplexGridValuesInput {{ - IVec { - 0, 4, 0 - }, t_complex { - 0.0F, 0.3F - } - }, { - IVec { - 4, 2, 7 - }, t_complex { - 13.76F, -40.0F - } - }, { - IVec { - 0, 6, 7 - }, t_complex { - 3.6F, 0.0F - } - }, { - IVec { - 2, 5, 10 - }, t_complex { - 3.6F, 10.65F - } - }, } +std::vector const c_sampleGrids{ + SparseComplexGridValuesInput{ + { IVec{ 0, 0, 0 }, t_complex{ 3.5F, 6.7F } }, + { IVec{ 7, 0, 0 }, t_complex{ -2.5F, -0.7F } }, + { IVec{ 3, 5, 7 }, t_complex{ -0.006F, 1e-8F } }, + { IVec{ 3, 1, 2 }, t_complex{ 0.6F, 7.9F } }, + { IVec{ 6, 2, 4 }, t_complex{ 30.1F, 2.45F } }, + }, + SparseComplexGridValuesInput{ + { IVec{ 0, 4, 0 }, t_complex{ 0.0F, 0.3F } }, + { IVec{ 4, 2, 7 }, t_complex{ 13.76F, -40.0F } }, + { IVec{ 0, 6, 7 }, t_complex{ 3.6F, 0.0F } }, + { IVec{ 2, 5, 10 }, t_complex{ 3.6F, 10.65F } }, + } }; //! Moved out from instantiations for readability @@ -354,26 +298,51 @@ const auto c_inputEwaldCoeff_lj = ::testing::Values(0.7); const auto c_inputMethods = ::testing::Values(PmeSolveAlgorithm::Coulomb, PmeSolveAlgorithm::LennardJones); //! Instantiation of the PME solving test -INSTANTIATE_TEST_CASE_P(SaneInput, PmeSolveTest, ::testing::Combine(c_inputBoxes, c_inputGridSizes, c_inputGrids, - c_inputEpsilon_r, c_inputEwaldCoeff_q, c_inputEwaldCoeff_lj, c_inputMethods)); +INSTANTIATE_TEST_CASE_P(SaneInput, + PmeSolveTest, + ::testing::Combine(c_inputBoxes, + c_inputGridSizes, + c_inputGrids, + c_inputEpsilon_r, + c_inputEwaldCoeff_q, + c_inputEwaldCoeff_lj, + c_inputMethods)); //! A few more instances to check that different ewaldCoeff_q actually affects results of the Coulomb solver -INSTANTIATE_TEST_CASE_P(DifferentEwaldCoeffQ, PmeSolveTest, ::testing::Combine(c_inputBoxes, c_inputGridSizes, c_inputGrids, - c_inputEpsilon_r, ::testing::Values(0.4), c_inputEwaldCoeff_lj, - ::testing::Values(PmeSolveAlgorithm::Coulomb))); +INSTANTIATE_TEST_CASE_P(DifferentEwaldCoeffQ, + PmeSolveTest, + ::testing::Combine(c_inputBoxes, + c_inputGridSizes, + c_inputGrids, + c_inputEpsilon_r, + ::testing::Values(0.4), + c_inputEwaldCoeff_lj, + ::testing::Values(PmeSolveAlgorithm::Coulomb))); //! A few more instances to check that different ewaldCoeff_lj actually affects results of the Lennard-Jones solver. //! The value has to be approximately larger than 1 / (box dimensions) to have a meaningful output grid. //! Previous value of 0.3 caused one of the grid cells to be less or greater than GMX_FLOAT_MIN, depending on the architecture. -INSTANTIATE_TEST_CASE_P(DifferentEwaldCoeffLJ, PmeSolveTest, ::testing::Combine(c_inputBoxes, c_inputGridSizes, c_inputGrids, - c_inputEpsilon_r, c_inputEwaldCoeff_q, ::testing::Values(2.35), - ::testing::Values(PmeSolveAlgorithm::LennardJones))); +INSTANTIATE_TEST_CASE_P(DifferentEwaldCoeffLJ, + PmeSolveTest, + ::testing::Combine(c_inputBoxes, + c_inputGridSizes, + c_inputGrids, + c_inputEpsilon_r, + c_inputEwaldCoeff_q, + ::testing::Values(2.35), + ::testing::Values(PmeSolveAlgorithm::LennardJones))); //! A few more instances to check that different epsilon_r actually affects results of all solvers -INSTANTIATE_TEST_CASE_P(DifferentEpsilonR, PmeSolveTest, ::testing::Combine(c_inputBoxes, c_inputGridSizes, c_inputGrids, - testing::Values(1.9), c_inputEwaldCoeff_q, c_inputEwaldCoeff_lj, - c_inputMethods)); - -} // namespace -} // namespace test -} // namespace gmx +INSTANTIATE_TEST_CASE_P(DifferentEpsilonR, + PmeSolveTest, + ::testing::Combine(c_inputBoxes, + c_inputGridSizes, + c_inputGrids, + testing::Values(1.9), + c_inputEwaldCoeff_q, + c_inputEwaldCoeff_lj, + c_inputMethods)); + +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/pmesplinespreadtest.cpp b/src/gromacs/ewald/tests/pmesplinespreadtest.cpp index 4a30d4d1c5..4da26ccd68 100644 --- a/src/gromacs/ewald/tests/pmesplinespreadtest.cpp +++ b/src/gromacs/ewald/tests/pmesplinespreadtest.cpp @@ -69,8 +69,8 @@ enum class PmeSplineAndSpreadOptions SplineAndSpreadUnified }; -/*! \brief Convenience typedef of input parameters - unit cell box, PME interpolation order, grid dimensions, - * particle coordinates, particle charges +/*! \brief Convenience typedef of input parameters - unit cell box, PME interpolation order, grid + * dimensions, particle coordinates, particle charges * TODO: consider inclusion of local grid offsets/sizes or PME nodes counts to test the PME DD */ typedef std::tuple SplineAndSpreadInputParameters; @@ -80,160 +80,182 @@ typedef std::tuple Splin */ class PmeSplineAndSpreadTest : public ::testing::TestWithParam { - public: - PmeSplineAndSpreadTest() = default; - //! The test - void runTest() +public: + PmeSplineAndSpreadTest() = default; + //! The test + void runTest() + { + /* Getting the input */ + Matrix3x3 box; + int pmeOrder; + IVec gridSize; + CoordinatesVector coordinates; + ChargesVector charges; + + std::tie(box, pmeOrder, gridSize, coordinates, charges) = GetParam(); + const size_t atomCount = coordinates.size(); + + /* Storing the input where it's needed */ + t_inputrec inputRec; + inputRec.nkx = gridSize[XX]; + inputRec.nky = gridSize[YY]; + inputRec.nkz = gridSize[ZZ]; + inputRec.pme_order = pmeOrder; + inputRec.coulombtype = eelPME; + inputRec.epsilon_r = 1.0; + + TestReferenceData refData; + + const std::map optionsToTest = { + { PmeSplineAndSpreadOptions::SplineAndSpreadUnified, + "spline computation and charge spreading (fused)" }, + { PmeSplineAndSpreadOptions::SplineOnly, "spline computation" }, + { PmeSplineAndSpreadOptions::SpreadOnly, "charge spreading" } + }; + + // There is a subtle problem with multiple comparisons against same reference data: + // The subsequent (GPU) spreading runs at one point didn't actually copy the output grid + // into the proper buffer, but the reference data was already marked as checked + // (hasBeenChecked_) by the CPU run, so nothing failed. For now we will manually track that + // the count of the grid entries is the same on each run. This is just a hack for a single + // specific output though. What would be much better TODO is to split different codepaths + // into separate tests, while making them use the same reference files. + bool gridValuesSizeAssigned = false; + size_t previousGridValuesSize; + + for (const auto& context : getPmeTestEnv()->getHardwareContexts()) { - /* Getting the input */ - Matrix3x3 box; - int pmeOrder; - IVec gridSize; - CoordinatesVector coordinates; - ChargesVector charges; - - std::tie(box, pmeOrder, gridSize, coordinates, charges) = GetParam(); - const size_t atomCount = coordinates.size(); - - /* Storing the input where it's needed */ - t_inputrec inputRec; - inputRec.nkx = gridSize[XX]; - inputRec.nky = gridSize[YY]; - inputRec.nkz = gridSize[ZZ]; - inputRec.pme_order = pmeOrder; - inputRec.coulombtype = eelPME; - inputRec.epsilon_r = 1.0; - - TestReferenceData refData; - - const std::map optionsToTest = {{PmeSplineAndSpreadOptions::SplineAndSpreadUnified, "spline computation and charge spreading (fused)"}, - {PmeSplineAndSpreadOptions::SplineOnly, "spline computation"}, - {PmeSplineAndSpreadOptions::SpreadOnly, "charge spreading"}}; - - // There is a subtle problem with multiple comparisons against same reference data: - // The subsequent (GPU) spreading runs at one point didn't actually copy the output grid into the proper buffer, - // but the reference data was already marked as checked (hasBeenChecked_) by the CPU run, so nothing failed. - // For now we will manually track that the count of the grid entries is the same on each run. - // This is just a hack for a single specific output though. - // What would be much better TODO is to split different codepaths into separate tests, - // while making them use the same reference files. - bool gridValuesSizeAssigned = false; - size_t previousGridValuesSize; - - for (const auto &context : getPmeTestEnv()->getHardwareContexts()) + CodePath codePath = context->getCodePath(); + const bool supportedInput = + pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); + if (!supportedInput) { - CodePath codePath = context->getCodePath(); - const bool supportedInput = pmeSupportsInputForMode(*getPmeTestEnv()->hwinfo(), &inputRec, codePath); - if (!supportedInput) - { - /* Testing the failure for the unsupported input */ - EXPECT_THROW(pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, box), NotImplementedError); - continue; - } + /* Testing the failure for the unsupported input */ + EXPECT_THROW(pmeInitWrapper(&inputRec, codePath, nullptr, nullptr, box), NotImplementedError); + continue; + } - for (const auto &option : optionsToTest) - { - /* Describing the test uniquely in case it fails */ + for (const auto& option : optionsToTest) + { + /* Describing the test uniquely in case it fails */ - SCOPED_TRACE(formatString("Testing %s with %s %sfor PME grid size %d %d %d" - ", order %d, %zu atoms", - option.second.c_str(), codePathToString(codePath), - context->getDescription().c_str(), - gridSize[XX], gridSize[YY], gridSize[ZZ], - pmeOrder, - atomCount)); + SCOPED_TRACE( + formatString("Testing %s with %s %sfor PME grid size %d %d %d" + ", order %d, %zu atoms", + option.second.c_str(), codePathToString(codePath), + context->getDescription().c_str(), gridSize[XX], gridSize[YY], + gridSize[ZZ], pmeOrder, atomCount)); - /* Running the test */ + /* Running the test */ - PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec, codePath, context->getDeviceInfo(), context->getPmeGpuProgram(), box); - std::unique_ptr stateGpu = (codePath == CodePath::GPU) ? makeStatePropagatorDataGpu(*pmeSafe.get()) : nullptr; + PmeSafePointer pmeSafe = pmeInitWrapper(&inputRec, codePath, context->getDeviceInfo(), + context->getPmeGpuProgram(), box); + std::unique_ptr stateGpu = + (codePath == CodePath::GPU) ? makeStatePropagatorDataGpu(*pmeSafe.get()) : nullptr; - pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, coordinates, charges); + pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, coordinates, charges); - const bool computeSplines = (option.first == PmeSplineAndSpreadOptions::SplineOnly) || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified); - const bool spreadCharges = (option.first == PmeSplineAndSpreadOptions::SpreadOnly) || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified); + const bool computeSplines = + (option.first == PmeSplineAndSpreadOptions::SplineOnly) + || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified); + const bool spreadCharges = + (option.first == PmeSplineAndSpreadOptions::SpreadOnly) + || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified); - if (!computeSplines) - { - // Here we should set up the results of the spline computation so that the spread can run. - // What is lazy and works is running the separate spline so that it will set it up for us: - pmePerformSplineAndSpread(pmeSafe.get(), codePath, true, false); - // We know that it is tested in another iteration. - // TODO: Clean alternative: read and set the reference gridline indices, spline params - } + if (!computeSplines) + { + // Here we should set up the results of the spline computation so that the spread can run. + // What is lazy and works is running the separate spline so that it will set it up for us: + pmePerformSplineAndSpread(pmeSafe.get(), codePath, true, false); + // We know that it is tested in another iteration. + // TODO: Clean alternative: read and set the reference gridline indices, spline params + } - pmePerformSplineAndSpread(pmeSafe.get(), codePath, computeSplines, spreadCharges); - pmeFinalizeTest(pmeSafe.get(), codePath); + pmePerformSplineAndSpread(pmeSafe.get(), codePath, computeSplines, spreadCharges); + pmeFinalizeTest(pmeSafe.get(), codePath); - /* Outputs correctness check */ - /* All tolerances were picked empirically for single precision on CPU */ + /* Outputs correctness check */ + /* All tolerances were picked empirically for single precision on CPU */ - TestReferenceChecker rootChecker(refData.rootChecker()); + TestReferenceChecker rootChecker(refData.rootChecker()); - const auto maxGridSize = std::max(std::max(gridSize[XX], gridSize[YY]), gridSize[ZZ]); - const auto ulpToleranceSplineValues = 4 * (pmeOrder - 2) * maxGridSize; - /* 4 is a modest estimate for amount of operations; (pmeOrder - 2) is a number of iterations; - * maxGridSize is inverse of the smallest positive fractional coordinate (which are interpolated by the splines). - */ + const auto maxGridSize = std::max(std::max(gridSize[XX], gridSize[YY]), gridSize[ZZ]); + const auto ulpToleranceSplineValues = 4 * (pmeOrder - 2) * maxGridSize; + /* 4 is a modest estimate for amount of operations; (pmeOrder - 2) is a number of iterations; + * maxGridSize is inverse of the smallest positive fractional coordinate (which are interpolated by the splines). + */ - if (computeSplines) + if (computeSplines) + { + const char* dimString[] = { "X", "Y", "Z" }; + + /* Spline values */ + SCOPED_TRACE(formatString("Testing spline values with tolerance of %d", + ulpToleranceSplineValues)); + TestReferenceChecker splineValuesChecker( + rootChecker.checkCompound("Splines", "Values")); + splineValuesChecker.setDefaultTolerance( + relativeToleranceAsUlp(1.0, ulpToleranceSplineValues)); + for (int i = 0; i < DIM; i++) { - const char *dimString[] = { "X", "Y", "Z" }; - - /* Spline values */ - SCOPED_TRACE(formatString("Testing spline values with tolerance of %d", ulpToleranceSplineValues)); - TestReferenceChecker splineValuesChecker(rootChecker.checkCompound("Splines", "Values")); - splineValuesChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpToleranceSplineValues)); - for (int i = 0; i < DIM; i++) - { - auto splineValuesDim = pmeGetSplineData(pmeSafe.get(), codePath, PmeSplineDataType::Values, i); - splineValuesChecker.checkSequence(splineValuesDim.begin(), splineValuesDim.end(), dimString[i]); - } - - /* Spline derivatives */ - const auto ulpToleranceSplineDerivatives = 4 * ulpToleranceSplineValues; - /* 4 is just a wild guess since the derivatives are deltas of neighbor spline values which could differ greatly */ - SCOPED_TRACE(formatString("Testing spline derivatives with tolerance of %d", ulpToleranceSplineDerivatives)); - TestReferenceChecker splineDerivativesChecker(rootChecker.checkCompound("Splines", "Derivatives")); - splineDerivativesChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpToleranceSplineDerivatives)); - for (int i = 0; i < DIM; i++) - { - auto splineDerivativesDim = pmeGetSplineData(pmeSafe.get(), codePath, PmeSplineDataType::Derivatives, i); - splineDerivativesChecker.checkSequence(splineDerivativesDim.begin(), splineDerivativesDim.end(), dimString[i]); - } - - /* Particle gridline indices */ - auto gridLineIndices = pmeGetGridlineIndices(pmeSafe.get(), codePath); - rootChecker.checkSequence(gridLineIndices.begin(), gridLineIndices.end(), "Gridline indices"); + auto splineValuesDim = + pmeGetSplineData(pmeSafe.get(), codePath, PmeSplineDataType::Values, i); + splineValuesChecker.checkSequence(splineValuesDim.begin(), + splineValuesDim.end(), dimString[i]); } - if (spreadCharges) + /* Spline derivatives */ + const auto ulpToleranceSplineDerivatives = 4 * ulpToleranceSplineValues; + /* 4 is just a wild guess since the derivatives are deltas of neighbor spline values which could differ greatly */ + SCOPED_TRACE(formatString("Testing spline derivatives with tolerance of %d", + ulpToleranceSplineDerivatives)); + TestReferenceChecker splineDerivativesChecker( + rootChecker.checkCompound("Splines", "Derivatives")); + splineDerivativesChecker.setDefaultTolerance( + relativeToleranceAsUlp(1.0, ulpToleranceSplineDerivatives)); + for (int i = 0; i < DIM; i++) { - /* The wrapped grid */ - SparseRealGridValuesOutput nonZeroGridValues = pmeGetRealGrid(pmeSafe.get(), codePath); - TestReferenceChecker gridValuesChecker(rootChecker.checkCompound("NonZeroGridValues", "RealSpaceGrid")); - const auto ulpToleranceGrid = 2 * ulpToleranceSplineValues * static_cast(ceil(sqrt(atomCount))); - /* 2 is empiric; sqrt(atomCount) assumes all the input charges may spread onto the same cell */ - SCOPED_TRACE(formatString("Testing grid values with tolerance of %d", ulpToleranceGrid)); - if (!gridValuesSizeAssigned) - { - previousGridValuesSize = nonZeroGridValues.size(); - gridValuesSizeAssigned = true; - } - else - { - EXPECT_EQ(previousGridValuesSize, nonZeroGridValues.size()); - } - - gridValuesChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpToleranceGrid)); - for (const auto &point : nonZeroGridValues) - { - gridValuesChecker.checkReal(point.second, point.first.c_str()); - } + auto splineDerivativesDim = pmeGetSplineData( + pmeSafe.get(), codePath, PmeSplineDataType::Derivatives, i); + splineDerivativesChecker.checkSequence( + splineDerivativesDim.begin(), splineDerivativesDim.end(), dimString[i]); + } + + /* Particle gridline indices */ + auto gridLineIndices = pmeGetGridlineIndices(pmeSafe.get(), codePath); + rootChecker.checkSequence(gridLineIndices.begin(), gridLineIndices.end(), + "Gridline indices"); + } + + if (spreadCharges) + { + /* The wrapped grid */ + SparseRealGridValuesOutput nonZeroGridValues = pmeGetRealGrid(pmeSafe.get(), codePath); + TestReferenceChecker gridValuesChecker( + rootChecker.checkCompound("NonZeroGridValues", "RealSpaceGrid")); + const auto ulpToleranceGrid = + 2 * ulpToleranceSplineValues * static_cast(ceil(sqrt(atomCount))); + /* 2 is empiric; sqrt(atomCount) assumes all the input charges may spread onto the same cell */ + SCOPED_TRACE(formatString("Testing grid values with tolerance of %d", ulpToleranceGrid)); + if (!gridValuesSizeAssigned) + { + previousGridValuesSize = nonZeroGridValues.size(); + gridValuesSizeAssigned = true; + } + else + { + EXPECT_EQ(previousGridValuesSize, nonZeroGridValues.size()); + } + + gridValuesChecker.setDefaultTolerance(relativeToleranceAsUlp(1.0, ulpToleranceGrid)); + for (const auto& point : nonZeroGridValues) + { + gridValuesChecker.checkReal(point.second, point.first.c_str()); } } } } + } }; @@ -246,38 +268,20 @@ TEST_P(PmeSplineAndSpreadTest, ReproducesOutputs) /* Valid input instances */ //! A couple of valid inputs for boxes. -std::vector const c_sampleBoxes -{ +std::vector const c_sampleBoxes{ // normal box - Matrix3x3 {{ - 8.0F, 0.0F, 0.0F, - 0.0F, 3.4F, 0.0F, - 0.0F, 0.0F, 2.0F - }}, + Matrix3x3{ { 8.0F, 0.0F, 0.0F, 0.0F, 3.4F, 0.0F, 0.0F, 0.0F, 2.0F } }, // triclinic box - Matrix3x3 {{ - 7.0F, 0.0F, 0.0F, - 0.0F, 4.1F, 0.0F, - 3.5F, 2.0F, 12.2F - }}, + Matrix3x3{ { 7.0F, 0.0F, 0.0F, 0.0F, 4.1F, 0.0F, 3.5F, 2.0F, 12.2F } }, }; //! A couple of valid inputs for grid sizes. -std::vector const c_sampleGridSizes -{ - IVec { - 16, 12, 14 - }, - IVec { - 19, 17, 11 - } -}; +std::vector const c_sampleGridSizes{ IVec{ 16, 12, 14 }, IVec{ 19, 17, 11 } }; //! Random charges -std::vector const c_sampleChargesFull -{ - 4.95F, 3.11F, 3.97F, 1.08F, 2.09F, 1.1F, 4.13F, 3.31F, 2.8F, 5.83F, 5.09F, 6.1F, 2.86F, 0.24F, 5.76F, 5.19F, 0.72F -}; +std::vector const c_sampleChargesFull{ 4.95F, 3.11F, 3.97F, 1.08F, 2.09F, 1.1F, + 4.13F, 3.31F, 2.8F, 5.83F, 5.09F, 6.1F, + 2.86F, 0.24F, 5.76F, 5.19F, 0.72F }; //! 1 charge auto const c_sampleCharges1 = ChargesVector(c_sampleChargesFull).subArray(0, 1); //! 2 charges @@ -286,74 +290,77 @@ auto const c_sampleCharges2 = ChargesVector(c_sampleChargesFull).subArray(1, 2); auto const c_sampleCharges13 = ChargesVector(c_sampleChargesFull).subArray(3, 13); //! Random coordinate vectors -CoordinatesVector const c_sampleCoordinatesFull -{ - { - 5.59F, 1.37F, 0.95F - }, { - 16.0F, 1.02F, 0.22F // 2 box lengths in x - }, { - 0.034F, 1.65F, 0.22F - }, { - 0.33F, 0.92F, 1.56F - }, { - 1.16F, 0.75F, 0.39F - }, { - 0.5F, 1.63F, 1.14F - }, { - 16.0001F, 1.52F, 1.19F // > 2 box lengths in x - }, { - 1.43F, 1.1F, 4.1F // > 2 box lengths in z - }, { - -1.08F, 1.19F, 0.08F // negative x - }, { - 1.6F, 0.93F, 0.53F - }, { - 1.32F, -1.48F, 0.16F // negative y - }, { - 0.87F, 0.0F, 0.33F - }, { - 0.95F, 7.7F, -0.48F // > 2 box lengths in y, negative z - }, { - 1.23F, 0.91F, 0.68F - }, { - 0.19F, 1.45F, 0.94F - }, { - 1.28F, 0.46F, 0.38F - }, { - 1.21F, 0.23F, 1.0F - } -}; +CoordinatesVector const c_sampleCoordinatesFull{ { 5.59F, 1.37F, 0.95F }, + { + 16.0F, 1.02F, 0.22F // 2 box lengths in x + }, + { 0.034F, 1.65F, 0.22F }, + { 0.33F, 0.92F, 1.56F }, + { 1.16F, 0.75F, 0.39F }, + { 0.5F, 1.63F, 1.14F }, + { + 16.0001F, 1.52F, 1.19F // > 2 box lengths in x + }, + { + 1.43F, 1.1F, 4.1F // > 2 box lengths in z + }, + { + -1.08F, 1.19F, 0.08F // negative x + }, + { 1.6F, 0.93F, 0.53F }, + { + 1.32F, -1.48F, 0.16F // negative y + }, + { 0.87F, 0.0F, 0.33F }, + { + 0.95F, 7.7F, -0.48F // > 2 box lengths in y, negative z + }, + { 1.23F, 0.91F, 0.68F }, + { 0.19F, 1.45F, 0.94F }, + { 1.28F, 0.46F, 0.38F }, + { 1.21F, 0.23F, 1.0F } }; //! 1 coordinate vector -CoordinatesVector const c_sampleCoordinates1(c_sampleCoordinatesFull.begin(), c_sampleCoordinatesFull.begin() + 1); +CoordinatesVector const c_sampleCoordinates1(c_sampleCoordinatesFull.begin(), + c_sampleCoordinatesFull.begin() + 1); //! 2 coordinate vectors -CoordinatesVector const c_sampleCoordinates2(c_sampleCoordinatesFull.begin() + 1, c_sampleCoordinatesFull.begin() + 3); +CoordinatesVector const c_sampleCoordinates2(c_sampleCoordinatesFull.begin() + 1, + c_sampleCoordinatesFull.begin() + 3); //! 13 coordinate vectors -CoordinatesVector const c_sampleCoordinates13(c_sampleCoordinatesFull.begin() + 3, c_sampleCoordinatesFull.begin() + 16); +CoordinatesVector const c_sampleCoordinates13(c_sampleCoordinatesFull.begin() + 3, + c_sampleCoordinatesFull.begin() + 16); //! moved out from instantiantions for readability -auto c_inputBoxes = ::testing::ValuesIn(c_sampleBoxes); +auto c_inputBoxes = ::testing::ValuesIn(c_sampleBoxes); //! moved out from instantiantions for readability auto c_inputPmeOrders = ::testing::Range(3, 5 + 1); //! moved out from instantiantions for readability auto c_inputGridSizes = ::testing::ValuesIn(c_sampleGridSizes); /*! \brief Instantiation of the test with valid input and 1 atom */ -INSTANTIATE_TEST_CASE_P(SaneInput1, PmeSplineAndSpreadTest, ::testing::Combine(c_inputBoxes, c_inputPmeOrders, c_inputGridSizes, - ::testing::Values(c_sampleCoordinates1), - ::testing::Values(c_sampleCharges1) - )); +INSTANTIATE_TEST_CASE_P(SaneInput1, + PmeSplineAndSpreadTest, + ::testing::Combine(c_inputBoxes, + c_inputPmeOrders, + c_inputGridSizes, + ::testing::Values(c_sampleCoordinates1), + ::testing::Values(c_sampleCharges1))); /*! \brief Instantiation of the test with valid input and 2 atoms */ -INSTANTIATE_TEST_CASE_P(SaneInput2, PmeSplineAndSpreadTest, ::testing::Combine(c_inputBoxes, c_inputPmeOrders, c_inputGridSizes, - ::testing::Values(c_sampleCoordinates2), - ::testing::Values(c_sampleCharges2) - )); +INSTANTIATE_TEST_CASE_P(SaneInput2, + PmeSplineAndSpreadTest, + ::testing::Combine(c_inputBoxes, + c_inputPmeOrders, + c_inputGridSizes, + ::testing::Values(c_sampleCoordinates2), + ::testing::Values(c_sampleCharges2))); /*! \brief Instantiation of the test with valid input and 13 atoms */ -INSTANTIATE_TEST_CASE_P(SaneInput13, PmeSplineAndSpreadTest, ::testing::Combine(c_inputBoxes, c_inputPmeOrders, c_inputGridSizes, - ::testing::Values(c_sampleCoordinates13), - ::testing::Values(c_sampleCharges13) - )); -} // namespace -} // namespace test -} // namespace gmx +INSTANTIATE_TEST_CASE_P(SaneInput13, + PmeSplineAndSpreadTest, + ::testing::Combine(c_inputBoxes, + c_inputPmeOrders, + c_inputGridSizes, + ::testing::Values(c_sampleCoordinates13), + ::testing::Values(c_sampleCharges13))); +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/pmetestcommon.cpp b/src/gromacs/ewald/tests/pmetestcommon.cpp index 30c0c042a7..a57195d1f6 100644 --- a/src/gromacs/ewald/tests/pmetestcommon.cpp +++ b/src/gromacs/ewald/tests/pmetestcommon.cpp @@ -73,26 +73,20 @@ namespace gmx namespace test { -bool pmeSupportsInputForMode(const gmx_hw_info_t &hwinfo, - const t_inputrec *inputRec, - CodePath mode) +bool pmeSupportsInputForMode(const gmx_hw_info_t& hwinfo, const t_inputrec* inputRec, CodePath mode) { bool implemented; gmx_mtop_t mtop; switch (mode) { - case CodePath::CPU: - implemented = true; - break; + case CodePath::CPU: implemented = true; break; case CodePath::GPU: - implemented = (pme_gpu_supports_build(nullptr) && - pme_gpu_supports_hardware(hwinfo, nullptr) && - pme_gpu_supports_input(*inputRec, mtop, nullptr)); + implemented = (pme_gpu_supports_build(nullptr) && pme_gpu_supports_hardware(hwinfo, nullptr) + && pme_gpu_supports_input(*inputRec, mtop, nullptr)); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return implemented; } @@ -107,20 +101,21 @@ uint64_t getSplineModuliDoublePrecisionUlps(int splineOrder) } //! PME initialization -PmeSafePointer pmeInitWrapper(const t_inputrec *inputRec, - const CodePath mode, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram, - const Matrix3x3 &box, - const real ewaldCoeff_q, - const real ewaldCoeff_lj) +PmeSafePointer pmeInitWrapper(const t_inputrec* inputRec, + const CodePath mode, + const gmx_device_info_t* gpuInfo, + PmeGpuProgramHandle pmeGpuProgram, + const Matrix3x3& box, + const real ewaldCoeff_q, + const real ewaldCoeff_lj) { const MDLogger dummyLogger; const auto runMode = (mode == CodePath::CPU) ? PmeRunMode::CPU : PmeRunMode::Mixed; - t_commrec dummyCommrec = {0}; + t_commrec dummyCommrec = { 0 }; NumPmeDomains numPmeDomains = { 1, 1 }; - gmx_pme_t *pmeDataRaw = gmx_pme_init(&dummyCommrec, numPmeDomains, inputRec, false, false, true, - ewaldCoeff_q, ewaldCoeff_lj, 1, runMode, nullptr, gpuInfo, pmeGpuProgram, dummyLogger); + gmx_pme_t* pmeDataRaw = + gmx_pme_init(&dummyCommrec, numPmeDomains, inputRec, false, false, true, ewaldCoeff_q, + ewaldCoeff_lj, 1, runMode, nullptr, gpuInfo, pmeGpuProgram, dummyLogger); PmeSafePointer pme(pmeDataRaw); // taking ownership // TODO get rid of this with proper matrix type @@ -132,64 +127,58 @@ PmeSafePointer pmeInitWrapper(const t_inputrec *inputRec, boxTemp[i][j] = box[i * DIM + j]; } } - const char *boxError = check_box(-1, boxTemp); + const char* boxError = check_box(-1, boxTemp); GMX_RELEASE_ASSERT(boxError == nullptr, boxError); switch (mode) { - case CodePath::CPU: - invertBoxMatrix(boxTemp, pme->recipbox); - break; + case CodePath::CPU: invertBoxMatrix(boxTemp, pme->recipbox); break; case CodePath::GPU: pme_gpu_set_testing(pme->gpu, true); pme_gpu_update_input_box(pme->gpu, boxTemp); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return pme; } //! Simple PME initialization based on input, no atom data -PmeSafePointer pmeInitEmpty(const t_inputrec *inputRec, - const CodePath mode, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram, - const Matrix3x3 &box, - real ewaldCoeff_q, - real ewaldCoeff_lj - ) +PmeSafePointer pmeInitEmpty(const t_inputrec* inputRec, + const CodePath mode, + const gmx_device_info_t* gpuInfo, + PmeGpuProgramHandle pmeGpuProgram, + const Matrix3x3& box, + real ewaldCoeff_q, + real ewaldCoeff_lj) { return pmeInitWrapper(inputRec, mode, gpuInfo, pmeGpuProgram, box, ewaldCoeff_q, ewaldCoeff_lj); // hiding the fact that PME actually needs to know the number of atoms in advance } //! Make a GPU state-propagator manager -std::unique_ptr -makeStatePropagatorDataGpu(const gmx_pme_t &pme) +std::unique_ptr makeStatePropagatorDataGpu(const gmx_pme_t& pme) { // TODO: Pin the host buffer and use async memory copies // TODO: Special constructor for PME-only rank / PME-tests is used here. There should be a mechanism to // restrict one from using other constructor here. - return std::make_unique(pme_gpu_get_device_stream(&pme), - pme_gpu_get_device_context(&pme), - GpuApiCallBehavior::Sync, - pme_gpu_get_padding_size(&pme)); + return std::make_unique( + pme_gpu_get_device_stream(&pme), pme_gpu_get_device_context(&pme), + GpuApiCallBehavior::Sync, pme_gpu_get_padding_size(&pme)); } //! PME initialization with atom data -void pmeInitAtoms(gmx_pme_t *pme, - StatePropagatorDataGpu *stateGpu, +void pmeInitAtoms(gmx_pme_t* pme, + StatePropagatorDataGpu* stateGpu, const CodePath mode, - const CoordinatesVector &coordinates, - const ChargesVector &charges) + const CoordinatesVector& coordinates, + const ChargesVector& charges) { - const index atomCount = coordinates.size(); + const index atomCount = coordinates.size(); GMX_RELEASE_ASSERT(atomCount == charges.ssize(), "Mismatch in atom data"); - PmeAtomComm *atc = nullptr; + PmeAtomComm* atc = nullptr; switch (mode) { @@ -203,100 +192,114 @@ void pmeInitAtoms(gmx_pme_t *pme, case CodePath::GPU: // TODO: Avoid use of atc in the GPU code path - atc = &(pme->atc[0]); + atc = &(pme->atc[0]); // We need to set atc->n for passing the size in the tests atc->setNumAtoms(atomCount); gmx_pme_reinit_atoms(pme, atomCount, charges.data()); stateGpu->reinit(atomCount, atomCount); - stateGpu->copyCoordinatesToGpu(arrayRefFromArray(coordinates.data(), coordinates.size()), gmx::AtomLocality::All); + stateGpu->copyCoordinatesToGpu(arrayRefFromArray(coordinates.data(), coordinates.size()), + gmx::AtomLocality::All); pme_gpu_set_kernelparam_coordinates(pme->gpu, stateGpu->getCoordinates()); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Getting local PME real grid pointer for test I/O -static real *pmeGetRealGridInternal(const gmx_pme_t *pme) +static real* pmeGetRealGridInternal(const gmx_pme_t* pme) { const size_t gridIndex = 0; return pme->fftgrid[gridIndex]; } //! Getting local PME real grid dimensions -static void pmeGetRealGridSizesInternal(const gmx_pme_t *pme, - CodePath mode, - IVec &gridSize, //NOLINT(google-runtime-references) - IVec &paddedGridSize) //NOLINT(google-runtime-references) +static void pmeGetRealGridSizesInternal(const gmx_pme_t* pme, + CodePath mode, + IVec& gridSize, //NOLINT(google-runtime-references) + IVec& paddedGridSize) //NOLINT(google-runtime-references) { const size_t gridIndex = 0; IVec gridOffsetUnused; switch (mode) { case CodePath::CPU: - gmx_parallel_3dfft_real_limits(pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused, paddedGridSize); + gmx_parallel_3dfft_real_limits(pme->pfft_setup[gridIndex], gridSize, gridOffsetUnused, + paddedGridSize); break; case CodePath::GPU: pme_gpu_get_real_grid_sizes(pme->gpu, &gridSize, &paddedGridSize); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Getting local PME complex grid pointer for test I/O -static t_complex *pmeGetComplexGridInternal(const gmx_pme_t *pme) +static t_complex* pmeGetComplexGridInternal(const gmx_pme_t* pme) { const size_t gridIndex = 0; return pme->cfftgrid[gridIndex]; } //! Getting local PME complex grid dimensions -static void pmeGetComplexGridSizesInternal(const gmx_pme_t *pme, - IVec &gridSize, //NOLINT(google-runtime-references) - IVec &paddedGridSize) //NOLINT(google-runtime-references) +static void pmeGetComplexGridSizesInternal(const gmx_pme_t* pme, + IVec& gridSize, //NOLINT(google-runtime-references) + IVec& paddedGridSize) //NOLINT(google-runtime-references) { const size_t gridIndex = 0; IVec gridOffsetUnused, complexOrderUnused; - gmx_parallel_3dfft_complex_limits(pme->pfft_setup[gridIndex], complexOrderUnused, gridSize, gridOffsetUnused, paddedGridSize); //TODO: what about YZX ordering? + gmx_parallel_3dfft_complex_limits(pme->pfft_setup[gridIndex], complexOrderUnused, gridSize, + gridOffsetUnused, paddedGridSize); // TODO: what about YZX ordering? } //! Getting the PME grid memory buffer and its sizes - template definition -template static void pmeGetGridAndSizesInternal(const gmx_pme_t * /*unused*/, CodePath /*unused*/, ValueType * & /*unused*/, IVec & /*unused*/, IVec & /*unused*/) //NOLINT(google-runtime-references) +template +static void pmeGetGridAndSizesInternal(const gmx_pme_t* /*unused*/, + CodePath /*unused*/, + ValueType*& /*unused*/, //NOLINT(google-runtime-references) + IVec& /*unused*/, //NOLINT(google-runtime-references) + IVec& /*unused*/) //NOLINT(google-runtime-references) { GMX_THROW(InternalError("Deleted function call")); // explicitly deleting general template does not compile in clang/icc, see https://llvm.org/bugs/show_bug.cgi?id=17537 } //! Getting the PME real grid memory buffer and its sizes -template<> void pmeGetGridAndSizesInternal(const gmx_pme_t *pme, CodePath mode, real * &grid, IVec &gridSize, IVec &paddedGridSize) +template<> +void pmeGetGridAndSizesInternal(const gmx_pme_t* pme, CodePath mode, real*& grid, IVec& gridSize, IVec& paddedGridSize) { grid = pmeGetRealGridInternal(pme); pmeGetRealGridSizesInternal(pme, mode, gridSize, paddedGridSize); } //! Getting the PME complex grid memory buffer and its sizes -template<> void pmeGetGridAndSizesInternal(const gmx_pme_t *pme, CodePath /*unused*/, t_complex * &grid, IVec &gridSize, IVec &paddedGridSize) +template<> +void pmeGetGridAndSizesInternal(const gmx_pme_t* pme, + CodePath /*unused*/, + t_complex*& grid, + IVec& gridSize, + IVec& paddedGridSize) { grid = pmeGetComplexGridInternal(pme); pmeGetComplexGridSizesInternal(pme, gridSize, paddedGridSize); } //! PME spline calculation and charge spreading -void pmePerformSplineAndSpread(gmx_pme_t *pme, CodePath mode, // TODO const qualifiers elsewhere - bool computeSplines, bool spreadCharges) +void pmePerformSplineAndSpread(gmx_pme_t* pme, + CodePath mode, // TODO const qualifiers elsewhere + bool computeSplines, + bool spreadCharges) { GMX_RELEASE_ASSERT(pme != nullptr, "PME data is not initialized"); - PmeAtomComm *atc = &(pme->atc[0]); - const size_t gridIndex = 0; - const bool computeSplinesForZeroCharges = true; - real *fftgrid = spreadCharges ? pme->fftgrid[gridIndex] : nullptr; - real *pmegrid = pme->pmegrid[gridIndex].grid.grid; + PmeAtomComm* atc = &(pme->atc[0]); + const size_t gridIndex = 0; + const bool computeSplinesForZeroCharges = true; + real* fftgrid = spreadCharges ? pme->fftgrid[gridIndex] : nullptr; + real* pmegrid = pme->pmegrid[gridIndex].grid.grid; switch (mode) { @@ -313,23 +316,22 @@ void pmePerformSplineAndSpread(gmx_pme_t *pme, CodePath mode, // TODO const qual case CodePath::GPU: { // no synchronization needed as x is transferred in the PME stream - GpuEventSynchronizer *xReadyOnDevice = nullptr; + GpuEventSynchronizer* xReadyOnDevice = nullptr; pme_gpu_spread(pme->gpu, xReadyOnDevice, gridIndex, fftgrid, computeSplines, spreadCharges); } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Getting the internal spline data buffer pointer -static real *pmeGetSplineDataInternal(const gmx_pme_t *pme, PmeSplineDataType type, int dimIndex) +static real* pmeGetSplineDataInternal(const gmx_pme_t* pme, PmeSplineDataType type, int dimIndex) { GMX_ASSERT((0 <= dimIndex) && (dimIndex < DIM), "Invalid dimension index"); - const PmeAtomComm *atc = &(pme->atc[0]); - const size_t threadIndex = 0; - real *splineBuffer = nullptr; + const PmeAtomComm* atc = &(pme->atc[0]); + const size_t threadIndex = 0; + real* splineBuffer = nullptr; switch (type) { case PmeSplineDataType::Values: @@ -340,20 +342,22 @@ static real *pmeGetSplineDataInternal(const gmx_pme_t *pme, PmeSplineDataType ty splineBuffer = atc->spline[threadIndex].dtheta.coefficients[dimIndex]; break; - default: - GMX_THROW(InternalError("Unknown spline data type")); + default: GMX_THROW(InternalError("Unknown spline data type")); } return splineBuffer; } //! PME solving -void pmePerformSolve(const gmx_pme_t *pme, CodePath mode, - PmeSolveAlgorithm method, real cellVolume, - GridOrdering gridOrdering, bool computeEnergyAndVirial) -{ - t_complex *h_grid = pmeGetComplexGridInternal(pme); - const bool useLorentzBerthelot = false; - const size_t threadIndex = 0; +void pmePerformSolve(const gmx_pme_t* pme, + CodePath mode, + PmeSolveAlgorithm method, + real cellVolume, + GridOrdering gridOrdering, + bool computeEnergyAndVirial) +{ + t_complex* h_grid = pmeGetComplexGridInternal(pme); + const bool useLorentzBerthelot = false; + const size_t threadIndex = 0; switch (mode) { case CodePath::CPU: @@ -364,17 +368,15 @@ void pmePerformSolve(const gmx_pme_t *pme, CodePath mode, switch (method) { case PmeSolveAlgorithm::Coulomb: - solve_pme_yzx(pme, h_grid, cellVolume, - computeEnergyAndVirial, pme->nthread, threadIndex); + solve_pme_yzx(pme, h_grid, cellVolume, computeEnergyAndVirial, pme->nthread, threadIndex); break; case PmeSolveAlgorithm::LennardJones: - solve_pme_lj_yzx(pme, &h_grid, useLorentzBerthelot, - cellVolume, computeEnergyAndVirial, pme->nthread, threadIndex); + solve_pme_lj_yzx(pme, &h_grid, useLorentzBerthelot, cellVolume, + computeEnergyAndVirial, pme->nthread, threadIndex); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } break; @@ -385,29 +387,26 @@ void pmePerformSolve(const gmx_pme_t *pme, CodePath mode, pme_gpu_solve(pme->gpu, h_grid, gridOrdering, computeEnergyAndVirial); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! PME force gathering -void pmePerformGather(gmx_pme_t *pme, CodePath mode, - PmeForceOutputHandling inputTreatment, ForcesVector &forces) +void pmePerformGather(gmx_pme_t* pme, CodePath mode, PmeForceOutputHandling inputTreatment, ForcesVector& forces) { - PmeAtomComm *atc = &(pme->atc[0]); - const index atomCount = atc->numAtoms(); + PmeAtomComm* atc = &(pme->atc[0]); + const index atomCount = atc->numAtoms(); GMX_RELEASE_ASSERT(forces.ssize() == atomCount, "Invalid force buffer size"); - const bool forceReductionWithInput = (inputTreatment == PmeForceOutputHandling::ReduceWithInput); - const real scale = 1.0; - const size_t threadIndex = 0; - const size_t gridIndex = 0; - real *pmegrid = pme->pmegrid[gridIndex].grid.grid; - real *fftgrid = pme->fftgrid[gridIndex]; + const bool forceReductionWithInput = (inputTreatment == PmeForceOutputHandling::ReduceWithInput); + const real scale = 1.0; + const size_t threadIndex = 0; + const size_t gridIndex = 0; + real* pmegrid = pme->pmegrid[gridIndex].grid.grid; + real* fftgrid = pme->fftgrid[gridIndex]; switch (mode) { @@ -427,48 +426,47 @@ void pmePerformGather(gmx_pme_t *pme, CodePath mode, { // Variable initialization needs a non-switch scope PmeOutput output = pme_gpu_getOutput(*pme, GMX_PME_CALC_F); - GMX_ASSERT(forces.size() == output.forces_.size(), "Size of force buffers did not match"); + GMX_ASSERT(forces.size() == output.forces_.size(), + "Size of force buffers did not match"); if (forceReductionWithInput) { std::copy(std::begin(forces), std::end(forces), std::begin(output.forces_)); } - pme_gpu_gather(pme->gpu, inputTreatment, reinterpret_cast(fftgrid)); + pme_gpu_gather(pme->gpu, inputTreatment, reinterpret_cast(fftgrid)); std::copy(std::begin(output.forces_), std::end(output.forces_), std::begin(forces)); } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! PME test finalization before fetching the outputs -void pmeFinalizeTest(const gmx_pme_t *pme, CodePath mode) +void pmeFinalizeTest(const gmx_pme_t* pme, CodePath mode) { switch (mode) { - case CodePath::CPU: - break; + case CodePath::CPU: break; - case CodePath::GPU: - pme_gpu_synchronize(pme->gpu); - break; + case CodePath::GPU: pme_gpu_synchronize(pme->gpu); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Setting atom spline values/derivatives to be used in spread/gather -void pmeSetSplineData(const gmx_pme_t *pme, CodePath mode, - const SplineParamsDimVector &splineValues, PmeSplineDataType type, int dimIndex) -{ - const PmeAtomComm *atc = &(pme->atc[0]); - const index atomCount = atc->numAtoms(); - const index pmeOrder = pme->pme_order; - const index dimSize = pmeOrder * atomCount; +void pmeSetSplineData(const gmx_pme_t* pme, + CodePath mode, + const SplineParamsDimVector& splineValues, + PmeSplineDataType type, + int dimIndex) +{ + const PmeAtomComm* atc = &(pme->atc[0]); + const index atomCount = atc->numAtoms(); + const index pmeOrder = pme->pme_order; + const index dimSize = pmeOrder * atomCount; GMX_RELEASE_ASSERT(dimSize == splineValues.ssize(), "Mismatch in spline data"); - real *splineBuffer = pmeGetSplineDataInternal(pme, type, dimIndex); + real* splineBuffer = pmeGetSplineDataInternal(pme, type, dimIndex); switch (mode) { @@ -481,47 +479,46 @@ void pmeSetSplineData(const gmx_pme_t *pme, CodePath mode, pme_gpu_transform_spline_atom_data(pme->gpu, atc, type, dimIndex, PmeLayoutTransform::HostToGpu); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Setting gridline indices to be used in spread/gather -void pmeSetGridLineIndices(gmx_pme_t *pme, CodePath mode, - const GridLineIndicesVector &gridLineIndices) +void pmeSetGridLineIndices(gmx_pme_t* pme, CodePath mode, const GridLineIndicesVector& gridLineIndices) { - PmeAtomComm *atc = &(pme->atc[0]); - const index atomCount = atc->numAtoms(); + PmeAtomComm* atc = &(pme->atc[0]); + const index atomCount = atc->numAtoms(); GMX_RELEASE_ASSERT(atomCount == gridLineIndices.ssize(), "Mismatch in gridline indices size"); IVec paddedGridSizeUnused, gridSize(0, 0, 0); pmeGetRealGridSizesInternal(pme, mode, gridSize, paddedGridSizeUnused); - for (const auto &index : gridLineIndices) + for (const auto& index : gridLineIndices) { for (int i = 0; i < DIM; i++) { - GMX_RELEASE_ASSERT((0 <= index[i]) && (index[i] < gridSize[i]), "Invalid gridline index"); + GMX_RELEASE_ASSERT((0 <= index[i]) && (index[i] < gridSize[i]), + "Invalid gridline index"); } } switch (mode) { case CodePath::GPU: - memcpy(pme->gpu->staging.h_gridlineIndices, gridLineIndices.data(), atomCount * sizeof(gridLineIndices[0])); + memcpy(pme->gpu->staging.h_gridlineIndices, gridLineIndices.data(), + atomCount * sizeof(gridLineIndices[0])); break; case CodePath::CPU: atc->idx.resize(gridLineIndices.size()); std::copy(gridLineIndices.begin(), gridLineIndices.end(), atc->idx.begin()); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Getting plain index into the complex 3d grid -inline size_t pmeGetGridPlainIndexInternal(const IVec &index, const IVec &paddedGridSize, GridOrdering gridOrdering) +inline size_t pmeGetGridPlainIndexInternal(const IVec& index, const IVec& paddedGridSize, GridOrdering gridOrdering) { size_t result; switch (gridOrdering) @@ -534,70 +531,71 @@ inline size_t pmeGetGridPlainIndexInternal(const IVec &index, const IVec &padded result = (index[XX] * paddedGridSize[YY] + index[YY]) * paddedGridSize[ZZ] + index[ZZ]; break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return result; } //! Setting real or complex grid template -static void pmeSetGridInternal(const gmx_pme_t *pme, CodePath mode, - GridOrdering gridOrdering, - const SparseGridValuesInput &gridValues) +static void pmeSetGridInternal(const gmx_pme_t* pme, + CodePath mode, + GridOrdering gridOrdering, + const SparseGridValuesInput& gridValues) { IVec gridSize(0, 0, 0), paddedGridSize(0, 0, 0); - ValueType *grid; + ValueType* grid; pmeGetGridAndSizesInternal(pme, mode, grid, gridSize, paddedGridSize); switch (mode) { case CodePath::GPU: // intentional absence of break, the grid will be copied from the host buffer in testing mode case CodePath::CPU: - std::memset(grid, 0, paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType)); - for (const auto &gridValue : gridValues) + std::memset(grid, 0, + paddedGridSize[XX] * paddedGridSize[YY] * paddedGridSize[ZZ] * sizeof(ValueType)); + for (const auto& gridValue : gridValues) { for (int i = 0; i < DIM; i++) { - GMX_RELEASE_ASSERT((0 <= gridValue.first[i]) && (gridValue.first[i] < gridSize[i]), "Invalid grid value index"); + GMX_RELEASE_ASSERT((0 <= gridValue.first[i]) && (gridValue.first[i] < gridSize[i]), + "Invalid grid value index"); } - const size_t gridValueIndex = pmeGetGridPlainIndexInternal(gridValue.first, paddedGridSize, gridOrdering); + const size_t gridValueIndex = + pmeGetGridPlainIndexInternal(gridValue.first, paddedGridSize, gridOrdering); grid[gridValueIndex] = gridValue.second; } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } } //! Setting real grid to be used in gather -void pmeSetRealGrid(const gmx_pme_t *pme, CodePath mode, - const SparseRealGridValuesInput &gridValues) +void pmeSetRealGrid(const gmx_pme_t* pme, CodePath mode, const SparseRealGridValuesInput& gridValues) { pmeSetGridInternal(pme, mode, GridOrdering::XYZ, gridValues); } //! Setting complex grid to be used in solve -void pmeSetComplexGrid(const gmx_pme_t *pme, CodePath mode, - GridOrdering gridOrdering, - const SparseComplexGridValuesInput &gridValues) +void pmeSetComplexGrid(const gmx_pme_t* pme, + CodePath mode, + GridOrdering gridOrdering, + const SparseComplexGridValuesInput& gridValues) { pmeSetGridInternal(pme, mode, gridOrdering, gridValues); } //! Getting the single dimension's spline values or derivatives -SplineParamsDimVector pmeGetSplineData(const gmx_pme_t *pme, CodePath mode, - PmeSplineDataType type, int dimIndex) +SplineParamsDimVector pmeGetSplineData(const gmx_pme_t* pme, CodePath mode, PmeSplineDataType type, int dimIndex) { GMX_RELEASE_ASSERT(pme != nullptr, "PME data is not initialized"); - const PmeAtomComm *atc = &(pme->atc[0]); - const size_t atomCount = atc->numAtoms(); - const size_t pmeOrder = pme->pme_order; - const size_t dimSize = pmeOrder * atomCount; + const PmeAtomComm* atc = &(pme->atc[0]); + const size_t atomCount = atc->numAtoms(); + const size_t pmeOrder = pme->pme_order; + const size_t dimSize = pmeOrder * atomCount; - real *sourceBuffer = pmeGetSplineDataInternal(pme, type, dimIndex); - SplineParamsDimVector result; + real* sourceBuffer = pmeGetSplineDataInternal(pme, type, dimIndex); + SplineParamsDimVector result; switch (mode) { case CodePath::GPU: @@ -605,46 +603,43 @@ SplineParamsDimVector pmeGetSplineData(const gmx_pme_t *pme, CodePath mode, result = arrayRefFromArray(sourceBuffer, dimSize); break; - case CodePath::CPU: - result = arrayRefFromArray(sourceBuffer, dimSize); - break; + case CodePath::CPU: result = arrayRefFromArray(sourceBuffer, dimSize); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return result; } //! Getting the gridline indices -GridLineIndicesVector pmeGetGridlineIndices(const gmx_pme_t *pme, CodePath mode) +GridLineIndicesVector pmeGetGridlineIndices(const gmx_pme_t* pme, CodePath mode) { GMX_RELEASE_ASSERT(pme != nullptr, "PME data is not initialized"); - const PmeAtomComm *atc = &(pme->atc[0]); - const size_t atomCount = atc->numAtoms(); + const PmeAtomComm* atc = &(pme->atc[0]); + const size_t atomCount = atc->numAtoms(); GridLineIndicesVector gridLineIndices; switch (mode) { case CodePath::GPU: - gridLineIndices = arrayRefFromArray(reinterpret_cast(pme->gpu->staging.h_gridlineIndices), atomCount); + gridLineIndices = arrayRefFromArray( + reinterpret_cast(pme->gpu->staging.h_gridlineIndices), atomCount); break; - case CodePath::CPU: - gridLineIndices = atc->idx; - break; + case CodePath::CPU: gridLineIndices = atc->idx; break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return gridLineIndices; } //! Getting real or complex grid - only non zero values template -static SparseGridValuesOutput pmeGetGridInternal(const gmx_pme_t *pme, CodePath mode, GridOrdering gridOrdering) +static SparseGridValuesOutput pmeGetGridInternal(const gmx_pme_t* pme, + CodePath mode, + GridOrdering gridOrdering) { IVec gridSize(0, 0, 0), paddedGridSize(0, 0, 0); - ValueType *grid; + ValueType* grid; pmeGetGridAndSizesInternal(pme, mode, grid, gridSize, paddedGridSize); SparseGridValuesOutput gridValues; switch (mode) @@ -658,12 +653,13 @@ static SparseGridValuesOutput pmeGetGridInternal(const gmx_pme_t *pme { for (int iz = 0; iz < gridSize[ZZ]; iz++) { - IVec temp(ix, iy, iz); - const size_t gridValueIndex = pmeGetGridPlainIndexInternal(temp, paddedGridSize, gridOrdering); - const ValueType value = grid[gridValueIndex]; - if (value != ValueType {}) + IVec temp(ix, iy, iz); + const size_t gridValueIndex = + pmeGetGridPlainIndexInternal(temp, paddedGridSize, gridOrdering); + const ValueType value = grid[gridValueIndex]; + if (value != ValueType{}) { - auto key = formatString("Cell %d %d %d", ix, iy, iz); + auto key = formatString("Cell %d %d %d", ix, iy, iz); gridValues[key] = value; } } @@ -671,28 +667,25 @@ static SparseGridValuesOutput pmeGetGridInternal(const gmx_pme_t *pme } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return gridValues; } //! Getting the real grid (spreading output of pmePerformSplineAndSpread()) -SparseRealGridValuesOutput pmeGetRealGrid(const gmx_pme_t *pme, CodePath mode) +SparseRealGridValuesOutput pmeGetRealGrid(const gmx_pme_t* pme, CodePath mode) { return pmeGetGridInternal(pme, mode, GridOrdering::XYZ); } //! Getting the complex grid output of pmePerformSolve() -SparseComplexGridValuesOutput pmeGetComplexGrid(const gmx_pme_t *pme, CodePath mode, - GridOrdering gridOrdering) +SparseComplexGridValuesOutput pmeGetComplexGrid(const gmx_pme_t* pme, CodePath mode, GridOrdering gridOrdering) { return pmeGetGridInternal(pme, mode, gridOrdering); } //! Getting the reciprocal energy and virial -PmeOutput pmeGetReciprocalEnergyAndVirial(const gmx_pme_t *pme, CodePath mode, - PmeSolveAlgorithm method) +PmeOutput pmeGetReciprocalEnergyAndVirial(const gmx_pme_t* pme, CodePath mode, PmeSolveAlgorithm method) { PmeOutput output; switch (mode) @@ -708,27 +701,22 @@ PmeOutput pmeGetReciprocalEnergyAndVirial(const gmx_pme_t *pme, CodePath mode, get_pme_ener_vir_lj(pme->solve_work, pme->nthread, &output); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } break; case CodePath::GPU: switch (method) { - case PmeSolveAlgorithm::Coulomb: - pme_gpu_getEnergyAndVirial(*pme, &output); - break; + case PmeSolveAlgorithm::Coulomb: pme_gpu_getEnergyAndVirial(*pme, &output); break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } break; - default: - GMX_THROW(InternalError("Test not implemented for this mode")); + default: GMX_THROW(InternalError("Test not implemented for this mode")); } return output; } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/pmetestcommon.h b/src/gromacs/ewald/tests/pmetestcommon.h index 0f00f57e38..1679dfb6c1 100644 --- a/src/gromacs/ewald/tests/pmetestcommon.h +++ b/src/gromacs/ewald/tests/pmetestcommon.h @@ -82,13 +82,15 @@ typedef ArrayRef SplineParamsDimVector; typedef std::array SplineParamsVector; //! Non-zero grid values for test input; keys are 3d indices (IVec) -templateusing SparseGridValuesInput = std::map; +template +using SparseGridValuesInput = std::map; //! Non-zero real grid values typedef SparseGridValuesInput SparseRealGridValuesInput; //! Non-zero complex grid values typedef SparseGridValuesInput SparseComplexGridValuesInput; //! Non-zero grid values for test output; keys are string representations of the cells' 3d indices (IVec); this allows for better sorting. -templateusing SparseGridValuesOutput = std::map; +template +using SparseGridValuesOutput = std::map; //! Non-zero real grid values typedef SparseGridValuesOutput SparseRealGridValuesOutput; //! Non-zero complex grid values @@ -105,9 +107,7 @@ enum class PmeSolveAlgorithm // Misc. //! Tells if this generally valid PME input is supported for this mode -bool pmeSupportsInputForMode(const gmx_hw_info_t &hwinfo, - const t_inputrec *inputRec, - CodePath mode); +bool pmeSupportsInputForMode(const gmx_hw_info_t& hwinfo, const t_inputrec* inputRec, CodePath mode); //! Spline moduli are computed in double precision, so they're very good in single precision constexpr int64_t c_splineModuliSinglePrecisionUlps = 1; @@ -119,72 +119,76 @@ uint64_t getSplineModuliDoublePrecisionUlps(int splineOrder); // PME stages //! PME initialization -PmeSafePointer pmeInitWrapper(const t_inputrec *inputRec, - CodePath mode, - const gmx_device_info_t *gpuInfo, - PmeGpuProgramHandle pmeGpuProgram, - const Matrix3x3 &box, - real ewaldCoeff_q = 1.0F, - real ewaldCoeff_lj = 1.0F); +PmeSafePointer pmeInitWrapper(const t_inputrec* inputRec, + CodePath mode, + const gmx_device_info_t* gpuInfo, + PmeGpuProgramHandle pmeGpuProgram, + const Matrix3x3& box, + real ewaldCoeff_q = 1.0F, + real ewaldCoeff_lj = 1.0F); //! Simple PME initialization (no atom data) -PmeSafePointer pmeInitEmpty(const t_inputrec *inputRec, - CodePath mode = CodePath::CPU, - const gmx_device_info_t *gpuInfo = nullptr, - PmeGpuProgramHandle pmeGpuProgram = nullptr, - const Matrix3x3 &box = {{1.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 1.0F}}, - real ewaldCoeff_q = 0.0F, real ewaldCoeff_lj = 0.0F); +PmeSafePointer pmeInitEmpty(const t_inputrec* inputRec, + CodePath mode = CodePath::CPU, + const gmx_device_info_t* gpuInfo = nullptr, + PmeGpuProgramHandle pmeGpuProgram = nullptr, + const Matrix3x3& box = { { 1.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 1.0F } }, + real ewaldCoeff_q = 0.0F, + real ewaldCoeff_lj = 0.0F); //! Make a GPU state-propagator manager -std::unique_ptr -makeStatePropagatorDataGpu(const gmx_pme_t &pme); +std::unique_ptr makeStatePropagatorDataGpu(const gmx_pme_t& pme); //! PME initialization with atom data and system box -void pmeInitAtoms(gmx_pme_t *pme, - StatePropagatorDataGpu *stateGpu, +void pmeInitAtoms(gmx_pme_t* pme, + StatePropagatorDataGpu* stateGpu, CodePath mode, - const CoordinatesVector &coordinates, - const ChargesVector &charges); + const CoordinatesVector& coordinates, + const ChargesVector& charges); //! PME spline computation and charge spreading -void pmePerformSplineAndSpread(gmx_pme_t *pme, CodePath mode, - bool computeSplines, bool spreadCharges); +void pmePerformSplineAndSpread(gmx_pme_t* pme, CodePath mode, bool computeSplines, bool spreadCharges); //! PME solving -void pmePerformSolve(const gmx_pme_t *pme, CodePath mode, - PmeSolveAlgorithm method, real cellVolume, - GridOrdering gridOrdering, bool computeEnergyAndVirial); +void pmePerformSolve(const gmx_pme_t* pme, + CodePath mode, + PmeSolveAlgorithm method, + real cellVolume, + GridOrdering gridOrdering, + bool computeEnergyAndVirial); //! PME force gathering -void pmePerformGather(gmx_pme_t *pme, CodePath mode, - PmeForceOutputHandling inputTreatment, ForcesVector &forces); //NOLINT(google-runtime-references) +void pmePerformGather(gmx_pme_t* pme, + CodePath mode, + PmeForceOutputHandling inputTreatment, + ForcesVector& forces); //NOLINT(google-runtime-references) //! PME test finalization before fetching the outputs -void pmeFinalizeTest(const gmx_pme_t *pme, CodePath mode); +void pmeFinalizeTest(const gmx_pme_t* pme, CodePath mode); // PME state setters //! Setting atom spline values or derivatives to be used in spread/gather -void pmeSetSplineData(const gmx_pme_t *pme, CodePath mode, - const SplineParamsDimVector &splineValues, PmeSplineDataType type, int dimIndex); +void pmeSetSplineData(const gmx_pme_t* pme, + CodePath mode, + const SplineParamsDimVector& splineValues, + PmeSplineDataType type, + int dimIndex); //! Setting gridline indices be used in spread/gather -void pmeSetGridLineIndices(gmx_pme_t *pme, CodePath mode, - const GridLineIndicesVector &gridLineIndices); +void pmeSetGridLineIndices(gmx_pme_t* pme, CodePath mode, const GridLineIndicesVector& gridLineIndices); //! Setting real grid to be used in gather -void pmeSetRealGrid(const gmx_pme_t *pme, CodePath mode, - const SparseRealGridValuesInput &gridValues); -void pmeSetComplexGrid(const gmx_pme_t *pme, CodePath mode, GridOrdering gridOrdering, - const SparseComplexGridValuesInput &gridValues); +void pmeSetRealGrid(const gmx_pme_t* pme, CodePath mode, const SparseRealGridValuesInput& gridValues); +void pmeSetComplexGrid(const gmx_pme_t* pme, + CodePath mode, + GridOrdering gridOrdering, + const SparseComplexGridValuesInput& gridValues); // PME state getters //! Getting the single dimension's spline values or derivatives -SplineParamsDimVector pmeGetSplineData(const gmx_pme_t *pme, CodePath mode, - PmeSplineDataType type, int dimIndex); +SplineParamsDimVector pmeGetSplineData(const gmx_pme_t* pme, CodePath mode, PmeSplineDataType type, int dimIndex); //! Getting the gridline indices -GridLineIndicesVector pmeGetGridlineIndices(const gmx_pme_t *pme, CodePath mode); +GridLineIndicesVector pmeGetGridlineIndices(const gmx_pme_t* pme, CodePath mode); //! Getting the real grid (spreading output of pmePerformSplineAndSpread()) -SparseRealGridValuesOutput pmeGetRealGrid(const gmx_pme_t *pme, CodePath mode); +SparseRealGridValuesOutput pmeGetRealGrid(const gmx_pme_t* pme, CodePath mode); //! Getting the complex grid output of pmePerformSolve() -SparseComplexGridValuesOutput pmeGetComplexGrid(const gmx_pme_t *pme, CodePath mode, - GridOrdering gridOrdering); +SparseComplexGridValuesOutput pmeGetComplexGrid(const gmx_pme_t* pme, CodePath mode, GridOrdering gridOrdering); //! Getting the reciprocal energy and virial -PmeOutput pmeGetReciprocalEnergyAndVirial(const gmx_pme_t *pme, CodePath mode, - PmeSolveAlgorithm method); -} // namespace test -} // namespace gmx +PmeOutput pmeGetReciprocalEnergyAndVirial(const gmx_pme_t* pme, CodePath mode, PmeSolveAlgorithm method); +} // namespace test +} // namespace gmx #endif diff --git a/src/gromacs/ewald/tests/testhardwarecontexts.cpp b/src/gromacs/ewald/tests/testhardwarecontexts.cpp index de6eba183e..6e0a888402 100644 --- a/src/gromacs/ewald/tests/testhardwarecontexts.cpp +++ b/src/gromacs/ewald/tests/testhardwarecontexts.cpp @@ -62,16 +62,13 @@ namespace test TestHardwareContext::~TestHardwareContext() = default; -const char *codePathToString(CodePath codePath) +const char* codePathToString(CodePath codePath) { switch (codePath) { - case CodePath::CPU: - return "CPU"; - case CodePath::GPU: - return "GPU"; - default: - GMX_THROW(NotImplementedError("This CodePath should support codePathToString")); + case CodePath::CPU: return "CPU"; + case CodePath::GPU: return "GPU"; + default: GMX_THROW(NotImplementedError("This CodePath should support codePathToString")); } } @@ -85,13 +82,14 @@ const char *codePathToString(CodePath codePath) * so there is no deinitialization issue. See * https://isocpp.org/wiki/faq/ctors for discussion of alternatives * and trade-offs. */ -const PmeTestEnvironment *getPmeTestEnv() +const PmeTestEnvironment* getPmeTestEnv() { - static PmeTestEnvironment *pmeTestEnvironment = nullptr; + static PmeTestEnvironment* pmeTestEnvironment = nullptr; if (pmeTestEnvironment == nullptr) { // Ownership of the TestEnvironment is taken by GoogleTest, so nothing can leak - pmeTestEnvironment = static_cast(::testing::AddGlobalTestEnvironment(new PmeTestEnvironment)); + pmeTestEnvironment = static_cast( + ::testing::AddGlobalTestEnvironment(new PmeTestEnvironment)); } return pmeTestEnvironment; } @@ -102,10 +100,10 @@ void callAddGlobalTestEnvironment() } //! Simple hardware initialization -static gmx_hw_info_t *hardwareInit() +static gmx_hw_info_t* hardwareInit() { - PhysicalNodeCommunicator physicalNodeComm(MPI_COMM_WORLD, gmx_physicalnode_id_hash()); - return gmx_detect_hardware(MDLogger {}, physicalNodeComm); + PhysicalNodeCommunicator physicalNodeComm(MPI_COMM_WORLD, gmx_physicalnode_id_hash()); + return gmx_detect_hardware(MDLogger{}, physicalNodeComm); } void PmeTestEnvironment::SetUp() @@ -113,8 +111,7 @@ void PmeTestEnvironment::SetUp() hardwareContexts_.emplace_back(std::make_unique(CodePath::CPU, "", nullptr)); hardwareInfo_ = hardwareInit(); - if (!pme_gpu_supports_build(nullptr) || - !pme_gpu_supports_hardware(*hardwareInfo_, nullptr)) + if (!pme_gpu_supports_build(nullptr) || !pme_gpu_supports_hardware(*hardwareInfo_, nullptr)) { // PME can only run on the CPU, so don't make any more test contexts. return; @@ -122,17 +119,16 @@ void PmeTestEnvironment::SetUp() // Constructing contexts for all compatible GPUs - will be empty on non-GPU builds for (int gpuIndex : getCompatibleGpus(hardwareInfo_->gpu_info)) { - const gmx_device_info_t *deviceInfo = getDeviceInfo(hardwareInfo_->gpu_info, gpuIndex); + const gmx_device_info_t* deviceInfo = getDeviceInfo(hardwareInfo_->gpu_info, gpuIndex); init_gpu(deviceInfo); - char stmp[200] = {}; + char stmp[200] = {}; get_gpu_device_info_string(stmp, hardwareInfo_->gpu_info, gpuIndex); std::string description = "(GPU " + std::string(stmp) + ") "; - hardwareContexts_.emplace_back(std::make_unique - (CodePath::GPU, description.c_str(), - deviceInfo)); + hardwareContexts_.emplace_back(std::make_unique( + CodePath::GPU, description.c_str(), deviceInfo)); } } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/ewald/tests/testhardwarecontexts.h b/src/gromacs/ewald/tests/testhardwarecontexts.h index c92b016759..20d208d870 100644 --- a/src/gromacs/ewald/tests/testhardwarecontexts.h +++ b/src/gromacs/ewald/tests/testhardwarecontexts.h @@ -65,7 +65,7 @@ enum class CodePath }; //! Return a string useful for human-readable messages describing a \c codePath. -const char *codePathToString(CodePath codePath); +const char* codePathToString(CodePath codePath); /*! \internal \brief * A structure to describe a hardware context that persists over the lifetime @@ -74,60 +74,64 @@ const char *codePathToString(CodePath codePath); struct TestHardwareContext { //! Hardware path for the code being tested. - CodePath codePath_; + CodePath codePath_; //! Readable description - std::string description_; + std::string description_; //! Device information pointer - const gmx_device_info_t *deviceInfo_; + const gmx_device_info_t* deviceInfo_; //! Persistent compiled GPU kernels for PME. - PmeGpuProgramStorage program_; + PmeGpuProgramStorage program_; - public: - //! Retuns the code path for this context. - CodePath getCodePath() const { return codePath_; } - //! Returns a human-readable context description line - std::string getDescription() const{return description_; } - //! Returns the device info pointer - const gmx_device_info_t *getDeviceInfo() const{return deviceInfo_; } - //! Returns the persistent PME GPU kernels - PmeGpuProgramHandle getPmeGpuProgram() const{return program_.get(); } - //! Constructs the context - TestHardwareContext(CodePath codePath, const char *description, const gmx_device_info_t *deviceInfo) : - codePath_(codePath), description_(description), deviceInfo_(deviceInfo), - program_(buildPmeGpuProgram(deviceInfo_)) {} - ~TestHardwareContext(); +public: + //! Retuns the code path for this context. + CodePath getCodePath() const { return codePath_; } + //! Returns a human-readable context description line + std::string getDescription() const { return description_; } + //! Returns the device info pointer + const gmx_device_info_t* getDeviceInfo() const { return deviceInfo_; } + //! Returns the persistent PME GPU kernels + PmeGpuProgramHandle getPmeGpuProgram() const { return program_.get(); } + //! Constructs the context + TestHardwareContext(CodePath codePath, const char* description, const gmx_device_info_t* deviceInfo) : + codePath_(codePath), + description_(description), + deviceInfo_(deviceInfo), + program_(buildPmeGpuProgram(deviceInfo_)) + { + } + ~TestHardwareContext(); }; //! A container of handles to hardware contexts -typedef std::vector < std::unique_ptr < TestHardwareContext>> TestHardwareContexts; +typedef std::vector> TestHardwareContexts; /*! \internal \brief * This class performs one-time test initialization (enumerating the hardware) */ class PmeTestEnvironment : public ::testing::Environment { - private: - //! General hardware info - gmx_hw_info_t *hardwareInfo_; - //! Storage of hardware contexts - TestHardwareContexts hardwareContexts_; +private: + //! General hardware info + gmx_hw_info_t* hardwareInfo_; + //! Storage of hardware contexts + TestHardwareContexts hardwareContexts_; - public: - //! This is called by GTest framework once to query the hardware - void SetUp() override; - //! Get available hardware contexts. - const TestHardwareContexts &getHardwareContexts() const {return hardwareContexts_; } - //! Get available hardware information. - const gmx_hw_info_t *hwinfo() const { return hardwareInfo_; } +public: + //! This is called by GTest framework once to query the hardware + void SetUp() override; + //! Get available hardware contexts. + const TestHardwareContexts& getHardwareContexts() const { return hardwareContexts_; } + //! Get available hardware information. + const gmx_hw_info_t* hwinfo() const { return hardwareInfo_; } }; //! Get the test environment -const PmeTestEnvironment *getPmeTestEnv(); +const PmeTestEnvironment* getPmeTestEnv(); /*! \brief This constructs the test environment during setup of the * unit test so that they can use the hardware context. */ void callAddGlobalTestEnvironment(); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/gromacs/fft/calcgrid.cpp b/src/gromacs/fft/calcgrid.cpp index 4850ee2590..6817cb0890 100644 --- a/src/gromacs/fft/calcgrid.cpp +++ b/src/gromacs/fft/calcgrid.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,9 +59,7 @@ const int grid_init[g_initNR] = { 6, 8, 10, 12, 14, 16, 20, 24, 25, 28, 32, 36, #define g_baseNR 14 const int grid_base[g_baseNR] = { 45, 48, 50, 52, 54, 56, 60, 64, 70, 72, 75, 80, 81, 84 }; -real calcFftGrid(FILE *fp, - const matrix box, real gridSpacing, int minGridPointsPerDim, - int *nx, int *ny, int *nz) +real calcFftGrid(FILE* fp, const matrix box, real gridSpacing, int minGridPointsPerDim, int* nx, int* ny, int* nz) { int d, n[DIM]; int i; @@ -75,7 +73,7 @@ real calcFftGrid(FILE *fp, gmx_fatal(FARGS, "invalid fourier grid spacing: %g", gridSpacing); } - if (grid_base[g_baseNR-1] % 4 != 0) + if (grid_base[g_baseNR - 1] % 4 != 0) { gmx_incons("the last entry in grid_base is not a multiple of 4"); } @@ -97,7 +95,7 @@ real calcFftGrid(FILE *fp, box_size[d] = 0; for (i = 0; i < DIM; i++) { - box_size[d] += box[d][i]*box[d][i]; + box_size[d] += box[d][i] * box[d][i]; } box_size[d] = std::sqrt(box_size[d]); } @@ -110,8 +108,8 @@ real calcFftGrid(FILE *fp, { if (nullptr != fp) { - fprintf(fp, "Calculating fourier grid dimensions for%s%s%s\n", - *nx > 0 ? "" : " X", *ny > 0 ? "" : " Y", *nz > 0 ? "" : " Z"); + fprintf(fp, "Calculating fourier grid dimensions for%s%s%s\n", *nx > 0 ? "" : " X", + *ny > 0 ? "" : " Y", *nz > 0 ? "" : " Z"); } } @@ -120,14 +118,14 @@ real calcFftGrid(FILE *fp, { if (n[d] <= 0) { - nmin = static_cast(box_size[d]/gridSpacing + 0.999); + nmin = static_cast(box_size[d] / gridSpacing + 0.999); nmin = std::max(nmin, minGridPointsPerDim); i = g_initNR - 1; if (grid_init[i] >= nmin) { /* Take the smallest possible grid in the list */ - while (i > 0 && grid_init[i-1] >= nmin) + while (i > 0 && grid_init[i - 1] >= nmin) { i--; } @@ -138,27 +136,25 @@ real calcFftGrid(FILE *fp, /* Determine how many pre-factors of 2 we need */ fac2 = 1; i = g_baseNR - 1; - while (fac2*grid_base[i] < nmin) + while (fac2 * grid_base[i] < nmin) { fac2 *= 2; } /* Find the smallest grid that is >= nmin */ do { - attempt = fac2*grid_base[i]; + attempt = fac2 * grid_base[i]; /* We demand a factor of 4, avoid 140, allow 90 */ - if (((attempt % 4 == 0 && attempt != 140) || attempt == 90) && - attempt >= nmin) + if (((attempt % 4 == 0 && attempt != 140) || attempt == 90) && attempt >= nmin) { n[d] = attempt; } i--; - } - while (i > 0); + } while (i > 0); } } - spacing[d] = box_size[d]/n[d]; + spacing[d] = box_size[d] / n[d]; max_spacing = std::max(max_spacing, spacing[d]); } *nx = n[XX]; @@ -166,8 +162,8 @@ real calcFftGrid(FILE *fp, *nz = n[ZZ]; if (nullptr != fp) { - fprintf(fp, "Using a fourier grid of %dx%dx%d, spacing %.3f %.3f %.3f\n", - *nx, *ny, *nz, spacing[XX], spacing[YY], spacing[ZZ]); + fprintf(fp, "Using a fourier grid of %dx%dx%d, spacing %.3f %.3f %.3f\n", *nx, *ny, *nz, + spacing[XX], spacing[YY], spacing[ZZ]); } return max_spacing; diff --git a/src/gromacs/fft/calcgrid.h b/src/gromacs/fft/calcgrid.h index 4da6326132..c1bb1d90a5 100644 --- a/src/gromacs/fft/calcgrid.h +++ b/src/gromacs/fft/calcgrid.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,9 +42,7 @@ #include "gromacs/math/vectypes.h" #include "gromacs/utility/real.h" -real calcFftGrid(FILE *fp, - const matrix box, real gridSpacing, int minGridPointsPerDim, - int *nx, int *ny, int *nz); +real calcFftGrid(FILE* fp, const matrix box, real gridSpacing, int minGridPointsPerDim, int* nx, int* ny, int* nz); /* Sets the number of grid points for each zero n* to the first reasonable * number which gives a spacing equal to or smaller than gridSpacing * and is >= minGridPointsPerDim. diff --git a/src/gromacs/fft/fft.cpp b/src/gromacs/fft/fft.cpp index 23f1d25d92..62526196ff 100644 --- a/src/gromacs/fft/fft.cpp +++ b/src/gromacs/fft/fft.cpp @@ -55,7 +55,8 @@ #if !GMX_FFT_FFTW3 && !GMX_FFT_ARMPL_FFTW3 -struct gmx_many_fft { +struct gmx_many_fft +{ int howmany; int dist; gmx_fft_t fft; @@ -63,11 +64,7 @@ struct gmx_many_fft { typedef struct gmx_many_fft* gmx_many_fft_t; -int -gmx_fft_init_many_1d(gmx_fft_t * pfft, - int nx, - int howmany, - gmx_fft_flag flags) +int gmx_fft_init_many_1d(gmx_fft_t* pfft, int nx, int howmany, gmx_fft_flag flags) { gmx_many_fft_t fft; if (pfft == nullptr) @@ -77,24 +74,20 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, } *pfft = nullptr; - if ( (fft = static_cast(malloc(sizeof(struct gmx_many_fft)))) == nullptr) + if ((fft = static_cast(malloc(sizeof(struct gmx_many_fft)))) == nullptr) { return ENOMEM; } gmx_fft_init_1d(&fft->fft, nx, flags); fft->howmany = howmany; - fft->dist = 2*nx; + fft->dist = 2 * nx; *pfft = reinterpret_cast(fft); return 0; } -int -gmx_fft_init_many_1d_real(gmx_fft_t * pfft, - int nx, - int howmany, - gmx_fft_flag flags) +int gmx_fft_init_many_1d_real(gmx_fft_t* pfft, int nx, int howmany, gmx_fft_flag flags) { gmx_many_fft_t fft; if (pfft == nullptr) @@ -104,24 +97,20 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, } *pfft = nullptr; - if ( (fft = static_cast(malloc(sizeof(struct gmx_many_fft)))) == nullptr) + if ((fft = static_cast(malloc(sizeof(struct gmx_many_fft)))) == nullptr) { return ENOMEM; } gmx_fft_init_1d_real(&fft->fft, nx, flags); fft->howmany = howmany; - fft->dist = 2*(nx/2+1); + fft->dist = 2 * (nx / 2 + 1); *pfft = reinterpret_cast(fft); return 0; } -int -gmx_fft_many_1d (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_many_1d(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { gmx_many_fft_t mfft = reinterpret_cast(fft); int i, ret; @@ -132,17 +121,13 @@ gmx_fft_many_1d (gmx_fft_t fft, { return ret; } - in_data = static_cast(in_data)+mfft->dist; - out_data = static_cast(out_data)+mfft->dist; + in_data = static_cast(in_data) + mfft->dist; + out_data = static_cast(out_data) + mfft->dist; } return 0; } -int -gmx_fft_many_1d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_many_1d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { gmx_many_fft_t mfft = reinterpret_cast(fft); int i, ret; @@ -153,15 +138,14 @@ gmx_fft_many_1d_real (gmx_fft_t fft, { return ret; } - in_data = static_cast(in_data)+mfft->dist; - out_data = static_cast(out_data)+mfft->dist; + in_data = static_cast(in_data) + mfft->dist; + out_data = static_cast(out_data) + mfft->dist; } return 0; } -void -gmx_many_fft_destroy(gmx_fft_t fft) +void gmx_many_fft_destroy(gmx_fft_t fft) { gmx_many_fft_t mfft = reinterpret_cast(fft); if (mfft != nullptr) @@ -174,31 +158,28 @@ gmx_many_fft_destroy(gmx_fft_t fft) } } -#endif //not GMX_FFT_FFTW3 +#endif // not GMX_FFT_FFTW3 -int gmx_fft_transpose_2d(t_complex * in_data, - t_complex * out_data, - int nx, - int ny) +int gmx_fft_transpose_2d(t_complex* in_data, t_complex* out_data, int nx, int ny) { - int i, j, k, im, n, ncount; - bool done1, done2; - int i1, i1c, i2, i2c, kmi, max; + int i, j, k, im, n, ncount; + bool done1, done2; + int i1, i1c, i2, i2c, kmi, max; t_complex tmp1, tmp2, tmp3; - t_complex *data; + t_complex* data; /* Use 500 bytes on stack to indicate moves. * This is just for optimization, it does not limit any dimensions. */ - char move[500]; - int nmove = 500; + char move[500]; + int nmove = 500; if (nx < 2 || ny < 2) { if (in_data != out_data) { - memcpy(out_data, in_data, sizeof(t_complex)*nx*ny); + memcpy(out_data, in_data, sizeof(t_complex) * nx * ny); } return 0; } @@ -210,8 +191,8 @@ int gmx_fft_transpose_2d(t_complex * in_data, { for (j = 0; j < ny; j++) { - out_data[j*nx+i].re = in_data[i*ny+j].re; - out_data[j*nx+i].im = in_data[i*ny+j].im; + out_data[j * nx + i].re = in_data[i * ny + j].re; + out_data[j * nx + i].im = in_data[i * ny + j].im; } } return 0; @@ -225,14 +206,14 @@ int gmx_fft_transpose_2d(t_complex * in_data, /* trivial case, just swap elements */ for (i = 0; i < nx; i++) { - for (j = i+1; j < nx; j++) + for (j = i + 1; j < nx; j++) { - tmp1.re = data[i*nx+j].re; - tmp1.im = data[i*nx+j].im; - data[i*nx+j].re = data[j*nx+i].re; - data[i*nx+j].im = data[j*nx+i].im; - data[j*nx+i].re = tmp1.re; - data[j*nx+i].im = tmp1.im; + tmp1.re = data[i * nx + j].re; + tmp1.im = data[i * nx + j].im; + data[i * nx + j].re = data[j * nx + i].re; + data[i * nx + j].im = data[j * nx + i].im; + data[j * nx + i].re = tmp1.re; + data[j * nx + i].im = tmp1.im; } } return 0; @@ -247,19 +228,18 @@ int gmx_fft_transpose_2d(t_complex * in_data, if (nx > 2 && ny > 2) { - i = nx-1; - j = ny-1; + i = nx - 1; + j = ny - 1; do { k = i % j; i = j; j = k; - } - while (k != 0); - ncount += i-1; + } while (k != 0); + ncount += i - 1; } - n = nx*ny; + n = nx * ny; k = n - 1; i = 1; im = ny; @@ -268,7 +248,7 @@ int gmx_fft_transpose_2d(t_complex * in_data, do { i1 = i; - kmi = k-i; + kmi = k - i; tmp1.re = data[i1].re; tmp1.im = data[i1].im; i1c = kmi; @@ -278,8 +258,8 @@ int gmx_fft_transpose_2d(t_complex * in_data, done2 = false; do { - i2 = ny*i1-k*(i1/nx); - i2c = k-i2; + i2 = ny * i1 - k * (i1 / nx); + i2c = k - i2; if (i1 < nmove) { move[i1] = 1; @@ -312,8 +292,7 @@ int gmx_fft_transpose_2d(t_complex * in_data, i1 = i2; i1c = i2c; } - } - while (!done2); + } while (!done2); data[i1].re = tmp1.re; data[i1].im = tmp1.im; @@ -329,7 +308,7 @@ int gmx_fft_transpose_2d(t_complex * in_data, done2 = false; do { - max = k-i; + max = k - i; i++; im += ny; if (im > k) @@ -344,7 +323,7 @@ int gmx_fft_transpose_2d(t_complex * in_data, while (i2 > i && i2 < max) { i1 = i2; - i2 = ny*i1-k*(i1/nx); + i2 = ny * i1 - k * (i1 / nx); } if (i2 == i) { @@ -356,11 +335,9 @@ int gmx_fft_transpose_2d(t_complex * in_data, done2 = true; } } - } - while (!done2); + } while (!done2); } - } - while (!done1); + } while (!done1); return 0; } diff --git a/src/gromacs/fft/fft.h b/src/gromacs/fft/fft.h index be54a756aa..46c5f89e99 100644 --- a/src/gromacs/fft/fft.h +++ b/src/gromacs/fft/fft.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,10 +68,7 @@ * handles this datatype should only be used for one thread at a time, i.e. * they should allocate one instance each when executing in parallel. */ -typedef struct gmx_fft * - gmx_fft_t; - - +typedef struct gmx_fft* gmx_fft_t; /*! \brief Specifier for FFT direction. @@ -116,7 +113,7 @@ typedef int gmx_fft_flag; /** Macro to indicate no special flags for FFT routines. */ static const int GMX_FFT_FLAG_NONE = 0; /** Flag to disable FFT optimizations based on timings, see ::gmx_fft_flag. */ -static const int GMX_FFT_FLAG_CONSERVATIVE = (1<<0); +static const int GMX_FFT_FLAG_CONSERVATIVE = (1 << 0); /*! \brief Setup a 1-dimensional complex-to-complex transform * @@ -130,10 +127,7 @@ static const int GMX_FFT_FLAG_CONSERVATIVE = (1<<0); * handles this datatype should only be used for one thread at a time, * i.e. you should create one copy per thread when executing in parallel. */ -int -gmx_fft_init_1d (gmx_fft_t * fft, - int nx, - gmx_fft_flag flags); +int gmx_fft_init_1d(gmx_fft_t* fft, int nx, gmx_fft_flag flags); /*! \brief Setup multiple 1-dimensional complex-to-complex transform @@ -149,11 +143,7 @@ gmx_fft_init_1d (gmx_fft_t * fft, * handles this datatype should only be used for one thread at a time, * i.e. you should create one copy per thread when executing in parallel. */ -int -gmx_fft_init_many_1d (gmx_fft_t * fft, - int nx, - int howmany, - gmx_fft_flag flags); +int gmx_fft_init_many_1d(gmx_fft_t* fft, int nx, int howmany, gmx_fft_flag flags); /*! \brief Setup a 1-dimensional real-to-complex transform @@ -168,10 +158,7 @@ gmx_fft_init_many_1d (gmx_fft_t * fft, * handles this datatype should only be used for one thread at a time, * i.e. you should create one copy per thread when executing in parallel. */ -int -gmx_fft_init_1d_real (gmx_fft_t * fft, - int nx, - gmx_fft_flag flags); +int gmx_fft_init_1d_real(gmx_fft_t* fft, int nx, gmx_fft_flag flags); /*! \brief Setup multiple 1-dimensional real-to-complex transform @@ -187,11 +174,7 @@ gmx_fft_init_1d_real (gmx_fft_t * fft, * handles this datatype should only be used for one thread at a time, * i.e. you should create one copy per thread when executing in parallel. */ -int -gmx_fft_init_many_1d_real (gmx_fft_t * fft, - int nx, - int howmany, - gmx_fft_flag flags); +int gmx_fft_init_many_1d_real(gmx_fft_t* fft, int nx, int howmany, gmx_fft_flag flags); /*! \brief Setup a 2-dimensional real-to-complex transform @@ -210,11 +193,7 @@ gmx_fft_init_many_1d_real (gmx_fft_t * fft, * handles this datatype should only be used for one thread at a time, * i.e. you should create one copy per thread when executing in parallel. */ -int -gmx_fft_init_2d_real (gmx_fft_t * fft, - int nx, - int ny, - gmx_fft_flag flags); +int gmx_fft_init_2d_real(gmx_fft_t* fft, int nx, int ny, gmx_fft_flag flags); /*! \brief Perform a 1-dimensional complex-to-complex transform @@ -235,11 +214,7 @@ gmx_fft_init_2d_real (gmx_fft_t * fft, * \note Data pointers are declared as void, to avoid casting pointers * depending on your grid type. */ -int -gmx_fft_1d (gmx_fft_t setup, - enum gmx_fft_direction dir, - void * in_data, - void * out_data); +int gmx_fft_1d(gmx_fft_t setup, enum gmx_fft_direction dir, void* in_data, void* out_data); /*! \brief Perform many 1-dimensional complex-to-complex transforms @@ -260,11 +235,7 @@ gmx_fft_1d (gmx_fft_t setup, * \note Data pointers are declared as void, to avoid casting pointers * depending on your grid type. */ -int -gmx_fft_many_1d (gmx_fft_t setup, - enum gmx_fft_direction dir, - void * in_data, - void * out_data); +int gmx_fft_many_1d(gmx_fft_t setup, enum gmx_fft_direction dir, void* in_data, void* out_data); /*! \brief Perform a 1-dimensional real-to-complex transform @@ -289,11 +260,7 @@ gmx_fft_many_1d (gmx_fft_t setup, * \note Data pointers are declared as void, to avoid casting pointers * depending on transform direction. */ -int -gmx_fft_1d_real (gmx_fft_t setup, - enum gmx_fft_direction dir, - void * in_data, - void * out_data); +int gmx_fft_1d_real(gmx_fft_t setup, enum gmx_fft_direction dir, void* in_data, void* out_data); /*! \brief Perform many 1-dimensional real-to-complex transforms * @@ -317,11 +284,7 @@ gmx_fft_1d_real (gmx_fft_t setup, * \note Data pointers are declared as void, to avoid casting pointers * depending on transform direction. */ -int -gmx_fft_many_1d_real (gmx_fft_t setup, - enum gmx_fft_direction dir, - void * in_data, - void * out_data); +int gmx_fft_many_1d_real(gmx_fft_t setup, enum gmx_fft_direction dir, void* in_data, void* out_data); /*! \brief Perform a 2-dimensional real-to-complex transform * @@ -352,11 +315,7 @@ gmx_fft_many_1d_real (gmx_fft_t setup, * \note Data pointers are declared as void, to avoid casting pointers * depending on transform direction. */ -int -gmx_fft_2d_real (gmx_fft_t setup, - enum gmx_fft_direction dir, - void * in_data, - void * out_data); +int gmx_fft_2d_real(gmx_fft_t setup, enum gmx_fft_direction dir, void* in_data, void* out_data); /*! \brief Release an FFT setup structure * @@ -366,8 +325,7 @@ gmx_fft_2d_real (gmx_fft_t setup, * of the other initializers. * */ -void -gmx_fft_destroy (gmx_fft_t setup); +void gmx_fft_destroy(gmx_fft_t setup); /*! \brief Release a many FFT setup structure * @@ -377,8 +335,7 @@ gmx_fft_destroy (gmx_fft_t setup); * of the other initializers. * */ -void -gmx_many_fft_destroy (gmx_fft_t setup); +void gmx_many_fft_destroy(gmx_fft_t setup); /*! \brief Transpose 2d complex matrix, in-place or out-of-place. @@ -395,11 +352,7 @@ gmx_many_fft_destroy (gmx_fft_t setup); * * \return GMX_SUCCESS, or an error code from gmx_errno.h */ -int -gmx_fft_transpose_2d (t_complex * in_data, - t_complex * out_data, - int nx, - int ny); +int gmx_fft_transpose_2d(t_complex* in_data, t_complex* out_data, int nx, int ny); /*! \brief Cleanup global data of FFT * diff --git a/src/gromacs/fft/fft5d.cpp b/src/gromacs/fft/fft5d.cpp index 6392d3b093..430c1b9abd 100644 --- a/src/gromacs/fft/fft5d.cpp +++ b/src/gromacs/fft/fft5d.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,25 +58,25 @@ #include "gromacs/utility/smalloc.h" #ifdef NOGMX -#define GMX_PARALLEL_ENV_INITIALIZED 1 +# define GMX_PARALLEL_ENV_INITIALIZED 1 #else -#if GMX_MPI -#define GMX_PARALLEL_ENV_INITIALIZED 1 -#else -#define GMX_PARALLEL_ENV_INITIALIZED 0 -#endif +# if GMX_MPI +# define GMX_PARALLEL_ENV_INITIALIZED 1 +# else +# define GMX_PARALLEL_ENV_INITIALIZED 0 +# endif #endif #if GMX_OPENMP /* TODO: Do we still need this? Are we still planning ot use fftw + OpenMP? */ -#define FFT5D_THREADS +# define FFT5D_THREADS /* requires fftw compiled with openmp */ /* #define FFT5D_FFTW_THREADS (now set by cmake) */ #endif #ifndef __FLT_EPSILON__ -#define __FLT_EPSILON__ FLT_EPSILON -#define __DBL_EPSILON__ DBL_EPSILON +# define __FLT_EPSILON__ FLT_EPSILON +# define __DBL_EPSILON__ DBL_EPSILON #endif #ifdef NOGMX @@ -84,13 +85,23 @@ FILE* debug = 0; #if GMX_FFT_FFTW3 -#include "gromacs/utility/exceptions.h" -#include "gromacs/utility/mutex.h" +# include "gromacs/utility/exceptions.h" +# include "gromacs/utility/mutex.h" /* none of the fftw3 calls, except execute(), are thread-safe, so we need to serialize them with this mutex. */ static gmx::Mutex big_fftw_mutex; -#define FFTW_LOCK try { big_fftw_mutex.lock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR -#define FFTW_UNLOCK try { big_fftw_mutex.unlock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR +# define FFTW_LOCK \ + try \ + { \ + big_fftw_mutex.lock(); \ + } \ + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR +# define FFTW_UNLOCK \ + try \ + { \ + big_fftw_mutex.unlock(); \ + } \ + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR #endif /* GMX_FFT_FFTW3 */ #if GMX_MPI @@ -98,7 +109,7 @@ static gmx::Mutex big_fftw_mutex; static int lfactor(int z) { int i = static_cast(sqrt(static_cast(z))); - while (z%i != 0) + while (z % i != 0) { i--; } @@ -107,20 +118,20 @@ static int lfactor(int z) #endif #if !GMX_MPI -#if HAVE_GETTIMEOFDAY -#include +# if HAVE_GETTIMEOFDAY +# include double MPI_Wtime() { struct timeval tv; gettimeofday(&tv, 0); - return tv.tv_sec+tv.tv_usec*1e-6; + return tv.tv_sec + tv.tv_usec * 1e-6; } -#else +# else double MPI_Wtime() { return 0.0; } -#endif +# endif #endif static int vmax(const int* a, int s) @@ -143,14 +154,27 @@ static int vmax(const int* a, int s) * lin is allocated by fft5d because size of array is only known after planning phase * rlout2 is only used as intermediate buffer - only returned after allocation to reuse for back transform - should not be used by caller */ -fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_complex** rlin, t_complex** rlout, t_complex** rlout2, t_complex** rlout3, int nthreads, gmx::PinningPolicy realGridAllocationPinningPolicy) +fft5d_plan fft5d_plan_3d(int NG, + int MG, + int KG, + MPI_Comm comm[2], + int flags, + t_complex** rlin, + t_complex** rlout, + t_complex** rlout2, + t_complex** rlout3, + int nthreads, + gmx::PinningPolicy realGridAllocationPinningPolicy) { - int P[2], prank[2], i; - bool bMaster; - int rNG, rMG, rKG; - int *N0 = nullptr, *N1 = nullptr, *M0 = nullptr, *M1 = nullptr, *K0 = nullptr, *K1 = nullptr, *oN0 = nullptr, *oN1 = nullptr, *oM0 = nullptr, *oM1 = nullptr, *oK0 = nullptr, *oK1 = nullptr; - int N[3], M[3], K[3], pN[3], pM[3], pK[3], oM[3], oK[3], *iNin[3] = {nullptr}, *oNin[3] = {nullptr}, *iNout[3] = {nullptr}, *oNout[3] = {nullptr}; + int P[2], prank[2], i; + bool bMaster; + int rNG, rMG, rKG; + int *N0 = nullptr, *N1 = nullptr, *M0 = nullptr, *M1 = nullptr, *K0 = nullptr, *K1 = nullptr, + *oN0 = nullptr, *oN1 = nullptr, *oM0 = nullptr, *oM1 = nullptr, *oK0 = nullptr, *oK1 = nullptr; + int N[3], M[3], K[3], pN[3], pM[3], pK[3], oM[3], oK[3], + *iNin[3] = { nullptr }, *oNin[3] = { nullptr }, *iNout[3] = { nullptr }, + *oNout[3] = { nullptr }; int C[3], rC[3], nP[2]; int lsize; t_complex *lin = nullptr, *lout = nullptr, *lout2 = nullptr, *lout3 = nullptr; @@ -188,16 +212,19 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ if (debug) { - fprintf(debug, "FFT5D: Using %dx%d rank grid, rank %d,%d\n", - P[0], P[1], prank[0], prank[1]); + fprintf(debug, "FFT5D: Using %dx%d rank grid, rank %d,%d\n", P[0], P[1], prank[0], prank[1]); } if (bMaster) { if (debug) { - fprintf(debug, "FFT5D: N: %d, M: %d, K: %d, P: %dx%d, real2complex: %d, backward: %d, order yz: %d, debug %d\n", - NG, MG, KG, P[0], P[1], int((flags&FFT5D_REALCOMPLEX) > 0), int((flags&FFT5D_BACKWARD) > 0), int((flags&FFT5D_ORDER_YZ) > 0), int((flags&FFT5D_DEBUG) > 0)); + fprintf(debug, + "FFT5D: N: %d, M: %d, K: %d, P: %dx%d, real2complex: %d, backward: %d, order " + "yz: %d, debug %d\n", + NG, MG, KG, P[0], P[1], int((flags & FFT5D_REALCOMPLEX) > 0), + int((flags & FFT5D_BACKWARD) > 0), int((flags & FFT5D_ORDER_YZ) > 0), + int((flags & FFT5D_DEBUG) > 0)); } /* The check below is not correct, one prime factor 11 or 13 is ok. if (fft5d_fmax(fft5d_fmax(lpfactor(NG),lpfactor(MG)),lpfactor(KG))>7) { @@ -217,23 +244,25 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ return nullptr; } - rNG = NG; rMG = MG; rKG = KG; + rNG = NG; + rMG = MG; + rKG = KG; - if (flags&FFT5D_REALCOMPLEX) + if (flags & FFT5D_REALCOMPLEX) { - if (!(flags&FFT5D_BACKWARD)) + if (!(flags & FFT5D_BACKWARD)) { - NG = NG/2+1; + NG = NG / 2 + 1; } else { - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { - MG = MG/2+1; + MG = MG / 2 + 1; } else { - KG = KG/2+1; + KG = KG / 2 + 1; } } } @@ -241,56 +270,62 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ /*for transpose we need to know the size for each processor not only our own size*/ - N0 = static_cast(malloc(P[0]*sizeof(int))); N1 = static_cast(malloc(P[1]*sizeof(int))); - M0 = static_cast(malloc(P[0]*sizeof(int))); M1 = static_cast(malloc(P[1]*sizeof(int))); - K0 = static_cast(malloc(P[0]*sizeof(int))); K1 = static_cast(malloc(P[1]*sizeof(int))); - oN0 = static_cast(malloc(P[0]*sizeof(int))); oN1 = static_cast(malloc(P[1]*sizeof(int))); - oM0 = static_cast(malloc(P[0]*sizeof(int))); oM1 = static_cast(malloc(P[1]*sizeof(int))); - oK0 = static_cast(malloc(P[0]*sizeof(int))); oK1 = static_cast(malloc(P[1]*sizeof(int))); + N0 = static_cast(malloc(P[0] * sizeof(int))); + N1 = static_cast(malloc(P[1] * sizeof(int))); + M0 = static_cast(malloc(P[0] * sizeof(int))); + M1 = static_cast(malloc(P[1] * sizeof(int))); + K0 = static_cast(malloc(P[0] * sizeof(int))); + K1 = static_cast(malloc(P[1] * sizeof(int))); + oN0 = static_cast(malloc(P[0] * sizeof(int))); + oN1 = static_cast(malloc(P[1] * sizeof(int))); + oM0 = static_cast(malloc(P[0] * sizeof(int))); + oM1 = static_cast(malloc(P[1] * sizeof(int))); + oK0 = static_cast(malloc(P[0] * sizeof(int))); + oK1 = static_cast(malloc(P[1] * sizeof(int))); for (i = 0; i < P[0]; i++) { - #define EVENDIST - #ifndef EVENDIST - oN0[i] = i*ceil((double)NG/P[0]); - oM0[i] = i*ceil((double)MG/P[0]); - oK0[i] = i*ceil((double)KG/P[0]); - #else - oN0[i] = (NG*i)/P[0]; - oM0[i] = (MG*i)/P[0]; - oK0[i] = (KG*i)/P[0]; - #endif +#define EVENDIST +#ifndef EVENDIST + oN0[i] = i * ceil((double)NG / P[0]); + oM0[i] = i * ceil((double)MG / P[0]); + oK0[i] = i * ceil((double)KG / P[0]); +#else + oN0[i] = (NG * i) / P[0]; + oM0[i] = (MG * i) / P[0]; + oK0[i] = (KG * i) / P[0]; +#endif } for (i = 0; i < P[1]; i++) { - #ifndef EVENDIST - oN1[i] = i*ceil((double)NG/P[1]); - oM1[i] = i*ceil((double)MG/P[1]); - oK1[i] = i*ceil((double)KG/P[1]); - #else - oN1[i] = (NG*i)/P[1]; - oM1[i] = (MG*i)/P[1]; - oK1[i] = (KG*i)/P[1]; - #endif +#ifndef EVENDIST + oN1[i] = i * ceil((double)NG / P[1]); + oM1[i] = i * ceil((double)MG / P[1]); + oK1[i] = i * ceil((double)KG / P[1]); +#else + oN1[i] = (NG * i) / P[1]; + oM1[i] = (MG * i) / P[1]; + oK1[i] = (KG * i) / P[1]; +#endif } - for (i = 0; P[0] > 0 && i < P[0]-1; i++) + for (i = 0; P[0] > 0 && i < P[0] - 1; i++) { - N0[i] = oN0[i+1]-oN0[i]; - M0[i] = oM0[i+1]-oM0[i]; - K0[i] = oK0[i+1]-oK0[i]; + N0[i] = oN0[i + 1] - oN0[i]; + M0[i] = oM0[i + 1] - oM0[i]; + K0[i] = oK0[i + 1] - oK0[i]; } - N0[P[0]-1] = NG-oN0[P[0]-1]; - M0[P[0]-1] = MG-oM0[P[0]-1]; - K0[P[0]-1] = KG-oK0[P[0]-1]; - for (i = 0; P[1] > 0 && i < P[1]-1; i++) + N0[P[0] - 1] = NG - oN0[P[0] - 1]; + M0[P[0] - 1] = MG - oM0[P[0] - 1]; + K0[P[0] - 1] = KG - oK0[P[0] - 1]; + for (i = 0; P[1] > 0 && i < P[1] - 1; i++) { - N1[i] = oN1[i+1]-oN1[i]; - M1[i] = oM1[i+1]-oM1[i]; - K1[i] = oK1[i+1]-oK1[i]; + N1[i] = oN1[i + 1] - oN1[i]; + M1[i] = oM1[i + 1] - oM1[i]; + K1[i] = oK1[i + 1] - oK1[i]; } - N1[P[1]-1] = NG-oN1[P[1]-1]; - M1[P[1]-1] = MG-oM1[P[1]-1]; - K1[P[1]-1] = KG-oK1[P[1]-1]; + N1[P[1] - 1] = NG - oN1[P[1] - 1]; + M1[P[1] - 1] = MG - oM1[P[1] - 1]; + K1[P[1] - 1] = KG - oK1[P[1] - 1]; /* for step 1-3 the local N,M,K sizes of the transposed system C: contiguous dimension, and nP: number of processor in subcommunicator @@ -304,7 +339,7 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ oK[0] = oK1[prank[1]]; C[0] = NG; rC[0] = rNG; - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { N[0] = vmax(N1, P[1]); M[0] = M0[prank[0]]; @@ -338,8 +373,10 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ K[2] = vmax(N1, P[1]); pK[2] = N1[prank[1]]; oK[2] = oN1[prank[1]]; - free(N0); free(oN0); /*these are not used for this order*/ - free(M1); free(oM1); /*the rest is freed in destroy*/ + free(N0); + free(oN0); /*these are not used for this order*/ + free(M1); + free(oM1); /*the rest is freed in destroy*/ } else { @@ -375,10 +412,12 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ K[2] = vmax(M1, P[1]); pK[2] = M1[prank[1]]; oK[2] = oM1[prank[1]]; - free(N1); free(oN1); /*these are not used for this order*/ - free(K0); free(oK0); /*the rest is freed in destroy*/ + free(N1); + free(oN1); /*these are not used for this order*/ + free(K0); + free(oK0); /*the rest is freed in destroy*/ } - N[2] = pN[2] = -1; /*not used*/ + N[2] = pN[2] = -1; /*not used*/ /* Difference between x-y-z regarding 2d decomposition is whether they are @@ -386,16 +425,15 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ */ /* int lsize = fmax(N[0]*M[0]*K[0]*nP[0],N[1]*M[1]*K[1]*nP[1]); */ - lsize = std::max(N[0]*M[0]*K[0]*nP[0], std::max(N[1]*M[1]*K[1]*nP[1], C[2]*M[2]*K[2])); + lsize = std::max(N[0] * M[0] * K[0] * nP[0], std::max(N[1] * M[1] * K[1] * nP[1], C[2] * M[2] * K[2])); /* int lsize = fmax(C[0]*M[0]*K[0],fmax(C[1]*M[1]*K[1],C[2]*M[2]*K[2])); */ - if (!(flags&FFT5D_NOMALLOC)) + if (!(flags & FFT5D_NOMALLOC)) { // only needed for PME GPU mixed mode - if (realGridAllocationPinningPolicy == gmx::PinningPolicy::PinnedIfSupported && - GMX_GPU == GMX_GPU_CUDA) + if (realGridAllocationPinningPolicy == gmx::PinningPolicy::PinnedIfSupported && GMX_GPU == GMX_GPU_CUDA) { const std::size_t numBytes = lsize * sizeof(t_complex); - lin = static_cast(gmx::PageAlignedAllocationPolicy::malloc(numBytes)); + lin = static_cast(gmx::PageAlignedAllocationPolicy::malloc(numBytes)); gmx::pinBuffer(lin, numBytes); } else @@ -448,30 +486,31 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ */ /*if not FFTW - then we don't do a 3d plan but instead use only 1D plans */ - /* It is possible to use the 3d plan with OMP threads - but in that case it is not allowed to be called from - * within a parallel region. For now deactivated. If it should be supported it has to made sure that - * that the execute of the 3d plan is in a master/serial block (since it contains it own parallel region) - * and that the 3d plan is faster than the 1d plan. + /* It is possible to use the 3d plan with OMP threads - but in that case it is not allowed to be + * called from within a parallel region. For now deactivated. If it should be supported it has + * to made sure that that the execute of the 3d plan is in a master/serial block (since it + * contains it own parallel region) and that the 3d plan is faster than the 1d plan. */ - if ((!(flags&FFT5D_INPLACE)) && (!(P[0] > 1 || P[1] > 1)) && nthreads == 1) /*don't do 3d plan in parallel or if in_place requested */ + if ((!(flags & FFT5D_INPLACE)) && (!(P[0] > 1 || P[1] > 1)) + && nthreads == 1) /*don't do 3d plan in parallel or if in_place requested */ { int fftwflags = FFTW_DESTROY_INPUT; FFTW(iodim) dims[3]; int inNG = NG, outMG = MG, outKG = KG; - FFTW_LOCK; + FFTW_LOCK fftwflags |= (flags & FFT5D_NOMEASURE) ? FFTW_ESTIMATE : FFTW_MEASURE; - if (flags&FFT5D_REALCOMPLEX) + if (flags & FFT5D_REALCOMPLEX) { - if (!(flags&FFT5D_BACKWARD)) /*input pointer is not complex*/ + if (!(flags & FFT5D_BACKWARD)) /*input pointer is not complex*/ { inNG *= 2; } - else /*output pointer is not complex*/ + else /*output pointer is not complex*/ { - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { outMG *= 2; } @@ -482,152 +521,166 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ } } - if (!(flags&FFT5D_BACKWARD)) + if (!(flags & FFT5D_BACKWARD)) { - dims[0].n = KG; - dims[1].n = MG; - dims[2].n = rNG; + dims[0].n = KG; + dims[1].n = MG; + dims[2].n = rNG; - dims[0].is = inNG*MG; /*N M K*/ + dims[0].is = inNG * MG; /*N M K*/ dims[1].is = inNG; dims[2].is = 1; - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { - dims[0].os = MG; /*M K N*/ + dims[0].os = MG; /*M K N*/ dims[1].os = 1; - dims[2].os = MG*KG; + dims[2].os = MG * KG; } else { - dims[0].os = 1; /*K N M*/ - dims[1].os = KG*NG; + dims[0].os = 1; /*K N M*/ + dims[1].os = KG * NG; dims[2].os = KG; } } else { - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { - dims[0].n = NG; - dims[1].n = KG; - dims[2].n = rMG; + dims[0].n = NG; + dims[1].n = KG; + dims[2].n = rMG; dims[0].is = 1; - dims[1].is = NG*MG; + dims[1].is = NG * MG; dims[2].is = NG; - dims[0].os = outMG*KG; + dims[0].os = outMG * KG; dims[1].os = outMG; dims[2].os = 1; } else { - dims[0].n = MG; - dims[1].n = NG; - dims[2].n = rKG; + dims[0].n = MG; + dims[1].n = NG; + dims[2].n = rKG; dims[0].is = NG; dims[1].is = 1; - dims[2].is = NG*MG; + dims[2].is = NG * MG; - dims[0].os = outKG*NG; + dims[0].os = outKG * NG; dims[1].os = outKG; dims[2].os = 1; } } -#ifdef FFT5D_THREADS -#ifdef FFT5D_FFTW_THREADS +# ifdef FFT5D_THREADS +# ifdef FFT5D_FFTW_THREADS FFTW(plan_with_nthreads)(nthreads); -#endif -#endif - if ((flags&FFT5D_REALCOMPLEX) && !(flags&FFT5D_BACKWARD)) +# endif +# endif + if ((flags & FFT5D_REALCOMPLEX) && !(flags & FFT5D_BACKWARD)) { plan->p3d = FFTW(plan_guru_dft_r2c)(/*rank*/ 3, dims, - /*howmany*/ 0, /*howmany_dims*/ nullptr, - reinterpret_cast(lin), reinterpret_cast(lout), - /*flags*/ fftwflags); + /*howmany*/ 0, /*howmany_dims*/ nullptr, + reinterpret_cast(lin), + reinterpret_cast(lout), + /*flags*/ fftwflags); } - else if ((flags&FFT5D_REALCOMPLEX) && (flags&FFT5D_BACKWARD)) + else if ((flags & FFT5D_REALCOMPLEX) && (flags & FFT5D_BACKWARD)) { plan->p3d = FFTW(plan_guru_dft_c2r)(/*rank*/ 3, dims, - /*howmany*/ 0, /*howmany_dims*/ nullptr, - reinterpret_cast(lin), reinterpret_cast(lout), - /*flags*/ fftwflags); + /*howmany*/ 0, /*howmany_dims*/ nullptr, + reinterpret_cast(lin), + reinterpret_cast(lout), + /*flags*/ fftwflags); } else { - plan->p3d = FFTW(plan_guru_dft)(/*rank*/ 3, dims, - /*howmany*/ 0, /*howmany_dims*/ nullptr, - reinterpret_cast(lin), reinterpret_cast(lout), - /*sign*/ (flags&FFT5D_BACKWARD) ? 1 : -1, /*flags*/ fftwflags); + plan->p3d = FFTW(plan_guru_dft)( + /*rank*/ 3, dims, + /*howmany*/ 0, /*howmany_dims*/ nullptr, reinterpret_cast(lin), + reinterpret_cast(lout), + /*sign*/ (flags & FFT5D_BACKWARD) ? 1 : -1, /*flags*/ fftwflags); } -#ifdef FFT5D_THREADS -#ifdef FFT5D_FFTW_THREADS +# ifdef FFT5D_THREADS +# ifdef FFT5D_FFTW_THREADS FFTW(plan_with_nthreads)(1); -#endif -#endif - FFTW_UNLOCK; +# endif +# endif + FFTW_UNLOCK } if (!plan->p3d) /* for decomposition and if 3d plan did not work */ { -#endif /* GMX_FFT_FFTW3 */ - for (s = 0; s < 3; s++) - { - if (debug) +#endif /* GMX_FFT_FFTW3 */ + for (s = 0; s < 3; s++) { - fprintf(debug, "FFT5D: Plan s %d rC %d M %d pK %d C %d lsize %d\n", - s, rC[s], M[s], pK[s], C[s], lsize); - } - plan->p1d[s] = static_cast(malloc(sizeof(gmx_fft_t)*nthreads)); + if (debug) + { + fprintf(debug, "FFT5D: Plan s %d rC %d M %d pK %d C %d lsize %d\n", s, rC[s], M[s], + pK[s], C[s], lsize); + } + plan->p1d[s] = static_cast(malloc(sizeof(gmx_fft_t) * nthreads)); - /* Make sure that the init routines are only called by one thread at a time and in order - (later is only important to not confuse valgrind) - */ + /* Make sure that the init routines are only called by one thread at a time and in order + (later is only important to not confuse valgrind) + */ #pragma omp parallel for num_threads(nthreads) schedule(static) ordered - for (int t = 0; t < nthreads; t++) - { -#pragma omp ordered + for (int t = 0; t < nthreads; t++) { - try +#pragma omp ordered { - int tsize = ((t+1)*pM[s]*pK[s]/nthreads)-(t*pM[s]*pK[s]/nthreads); - - if ((flags&FFT5D_REALCOMPLEX) && ((!(flags&FFT5D_BACKWARD) && s == 0) || ((flags&FFT5D_BACKWARD) && s == 2))) + try { - gmx_fft_init_many_1d_real( &plan->p1d[s][t], rC[s], tsize, (flags&FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0 ); - } - else - { - gmx_fft_init_many_1d ( &plan->p1d[s][t], C[s], tsize, (flags&FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0 ); + int tsize = ((t + 1) * pM[s] * pK[s] / nthreads) - (t * pM[s] * pK[s] / nthreads); + + if ((flags & FFT5D_REALCOMPLEX) + && ((!(flags & FFT5D_BACKWARD) && s == 0) + || ((flags & FFT5D_BACKWARD) && s == 2))) + { + gmx_fft_init_many_1d_real( + &plan->p1d[s][t], rC[s], tsize, + (flags & FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0); + } + else + { + gmx_fft_init_many_1d(&plan->p1d[s][t], C[s], tsize, + (flags & FFT5D_NOMEASURE) ? GMX_FFT_FLAG_CONSERVATIVE : 0); + } } + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; } } - } #if GMX_FFT_FFTW3 -} + } #endif - if ((flags&FFT5D_ORDER_YZ)) /*plan->cart is in the order of transposes */ + if ((flags & FFT5D_ORDER_YZ)) /*plan->cart is in the order of transposes */ { - plan->cart[0] = comm[0]; plan->cart[1] = comm[1]; + plan->cart[0] = comm[0]; + plan->cart[1] = comm[1]; } else { - plan->cart[1] = comm[0]; plan->cart[0] = comm[1]; + plan->cart[1] = comm[0]; + plan->cart[0] = comm[1]; } #ifdef FFT5D_MPI_TRANSPOSE FFTW_LOCK; for (s = 0; s < 2; s++) { - if ((s == 0 && !(flags&FFT5D_ORDER_YZ)) || (s == 1 && (flags&FFT5D_ORDER_YZ))) + if ((s == 0 && !(flags & FFT5D_ORDER_YZ)) || (s == 1 && (flags & FFT5D_ORDER_YZ))) { - plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s]*K[s]*pM[s]*2, 1, 1, (real*)lout2, (real*)lout3, plan->cart[s], FFTW_PATIENT); + plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s] * K[s] * pM[s] * 2, 1, + 1, (real*)lout2, (real*)lout3, + plan->cart[s], FFTW_PATIENT); } else { - plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s]*pK[s]*M[s]*2, 1, 1, (real*)lout2, (real*)lout3, plan->cart[s], FFTW_PATIENT); + plan->mpip[s] = FFTW(mpi_plan_many_transpose)(nP[s], nP[s], N[s] * pK[s] * M[s] * 2, 1, + 1, (real*)lout2, (real*)lout3, + plan->cart[s], FFTW_PATIENT); } } FFTW_UNLOCK; @@ -639,24 +692,37 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ plan->lout2 = lout2; plan->lout3 = lout3; - plan->NG = NG; plan->MG = MG; plan->KG = KG; + plan->NG = NG; + plan->MG = MG; + plan->KG = KG; for (s = 0; s < 3; s++) { - plan->N[s] = N[s]; plan->M[s] = M[s]; plan->K[s] = K[s]; plan->pN[s] = pN[s]; plan->pM[s] = pM[s]; plan->pK[s] = pK[s]; - plan->oM[s] = oM[s]; plan->oK[s] = oK[s]; - plan->C[s] = C[s]; plan->rC[s] = rC[s]; - plan->iNin[s] = iNin[s]; plan->oNin[s] = oNin[s]; plan->iNout[s] = iNout[s]; plan->oNout[s] = oNout[s]; + plan->N[s] = N[s]; + plan->M[s] = M[s]; + plan->K[s] = K[s]; + plan->pN[s] = pN[s]; + plan->pM[s] = pM[s]; + plan->pK[s] = pK[s]; + plan->oM[s] = oM[s]; + plan->oK[s] = oK[s]; + plan->C[s] = C[s]; + plan->rC[s] = rC[s]; + plan->iNin[s] = iNin[s]; + plan->oNin[s] = oNin[s]; + plan->iNout[s] = iNout[s]; + plan->oNout[s] = oNout[s]; } for (s = 0; s < 2; s++) { - plan->P[s] = nP[s]; plan->coor[s] = prank[s]; + plan->P[s] = nP[s]; + plan->coor[s] = prank[s]; } -/* plan->fftorder=fftorder; - plan->direction=direction; - plan->realcomplex=realcomplex; - */ + /* plan->fftorder=fftorder; + plan->direction=direction; + plan->realcomplex=realcomplex; + */ plan->flags = flags; plan->nthreads = nthreads; plan->pinningPolicy = realGridAllocationPinningPolicy; @@ -668,7 +734,8 @@ fft5d_plan fft5d_plan_3d(int NG, int MG, int KG, MPI_Comm comm[2], int flags, t_ } -enum order { +enum order +{ XYZ, XZY, YXZ, @@ -678,21 +745,31 @@ enum order { }; - /*here x,y,z and N,M,K is in rotated coordinate system!! x (and N) is mayor (consecutive) dimension, y (M) middle and z (K) major maxN,maxM,maxK is max size of local data pN, pM, pK is local size specific to current processor (only different to max if not divisible) NG, MG, KG is size of global data*/ -static void splitaxes(t_complex* lout, const t_complex* lin, - int maxN, int maxM, int maxK, int pM, - int P, int NG, const int *N, const int* oN, int starty, int startz, int endy, int endz) +static void splitaxes(t_complex* lout, + const t_complex* lin, + int maxN, + int maxM, + int maxK, + int pM, + int P, + int NG, + const int* N, + const int* oN, + int starty, + int startz, + int endy, + int endz) { int x, y, z, i; int in_i, out_i, in_z, out_z, in_y, out_y; int s_y, e_y; - for (z = startz; z < endz+1; z++) /*3. z l*/ + for (z = startz; z < endz + 1; z++) /*3. z l*/ { if (z == startz) { @@ -710,20 +787,20 @@ static void splitaxes(t_complex* lout, const t_complex* lin, { e_y = pM; } - out_z = z*maxN*maxM; - in_z = z*NG*pM; + out_z = z * maxN * maxM; + in_z = z * NG * pM; for (i = 0; i < P; i++) /*index cube along long axis*/ { - out_i = out_z + i*maxN*maxM*maxK; - in_i = in_z + oN[i]; - for (y = s_y; y < e_y; y++) /*2. y k*/ + out_i = out_z + i * maxN * maxM * maxK; + in_i = in_z + oN[i]; + for (y = s_y; y < e_y; y++) /*2. y k*/ { - out_y = out_i + y*maxN; - in_y = in_i + y*NG; - for (x = 0; x < N[i]; x++) /*1. x j*/ + out_y = out_i + y * maxN; + in_y = in_i + y * NG; + for (x = 0; x < N[i]; x++) /*1. x j*/ { - lout[out_y+x] = lin[in_y+x]; /*in=z*NG*pM+oN[i]+y*NG+x*/ + lout[out_y + x] = lin[in_y + x]; /*in=z*NG*pM+oN[i]+y*NG+x*/ /*after split important that each processor chunk i has size maxN*maxM*maxK and thus being the same size*/ /*before split data contiguos - thus if different processor get different amount oN is different*/ } @@ -738,15 +815,26 @@ static void splitaxes(t_complex* lout, const t_complex* lin, the major, middle, minor order is only correct for x,y,z (N,M,K) for the input N,M,K local dimensions KG global size*/ -static void joinAxesTrans13(t_complex* lout, const t_complex* lin, - int maxN, int maxM, int maxK, int pM, - int P, int KG, const int* K, const int* oK, int starty, int startx, int endy, int endx) +static void joinAxesTrans13(t_complex* lout, + const t_complex* lin, + int maxN, + int maxM, + int maxK, + int pM, + int P, + int KG, + const int* K, + const int* oK, + int starty, + int startx, + int endy, + int endx) { int i, x, y, z; int out_i, in_i, out_x, in_x, out_z, in_z; int s_y, e_y; - for (x = startx; x < endx+1; x++) /*1.j*/ + for (x = startx; x < endx + 1; x++) /*1.j*/ { if (x == startx) { @@ -765,20 +853,20 @@ static void joinAxesTrans13(t_complex* lout, const t_complex* lin, e_y = pM; } - out_x = x*KG*pM; - in_x = x; + out_x = x * KG * pM; + in_x = x; for (i = 0; i < P; i++) /*index cube along long axis*/ { - out_i = out_x + oK[i]; - in_i = in_x + i*maxM*maxN*maxK; + out_i = out_x + oK[i]; + in_i = in_x + i * maxM * maxN * maxK; for (z = 0; z < K[i]; z++) /*3.l*/ { - out_z = out_i + z; - in_z = in_i + z*maxM*maxN; - for (y = s_y; y < e_y; y++) /*2.k*/ + out_z = out_i + z; + in_z = in_i + z * maxM * maxN; + for (y = s_y; y < e_y; y++) /*2.k*/ { - lout[out_z+y*KG] = lin[in_z+y*maxN]; /*out=x*KG*pM+oK[i]+z+y*KG*/ + lout[out_z + y * KG] = lin[in_z + y * maxN]; /*out=x*KG*pM+oK[i]+z+y*KG*/ } } } @@ -791,14 +879,26 @@ static void joinAxesTrans13(t_complex* lout, const t_complex* lin, the minor, middle, major order is only correct for x,y,z (N,M,K) for the input N,M,K local size MG, global size*/ -static void joinAxesTrans12(t_complex* lout, const t_complex* lin, int maxN, int maxM, int maxK, int pN, - int P, int MG, const int* M, const int* oM, int startx, int startz, int endx, int endz) +static void joinAxesTrans12(t_complex* lout, + const t_complex* lin, + int maxN, + int maxM, + int maxK, + int pN, + int P, + int MG, + const int* M, + const int* oM, + int startx, + int startz, + int endx, + int endz) { int i, z, y, x; int out_i, in_i, out_z, in_z, out_x, in_x; int s_x, e_x; - for (z = startz; z < endz+1; z++) + for (z = startz; z < endz + 1; z++) { if (z == startz) { @@ -816,20 +916,20 @@ static void joinAxesTrans12(t_complex* lout, const t_complex* lin, int maxN, int { e_x = pN; } - out_z = z*MG*pN; - in_z = z*maxM*maxN; + out_z = z * MG * pN; + in_z = z * maxM * maxN; for (i = 0; i < P; i++) /*index cube along long axis*/ { - out_i = out_z + oM[i]; - in_i = in_z + i*maxM*maxN*maxK; + out_i = out_z + oM[i]; + in_i = in_z + i * maxM * maxN * maxK; for (x = s_x; x < e_x; x++) { - out_x = out_i + x*MG; - in_x = in_i + x; + out_x = out_i + x * MG; + in_x = in_i + x; for (y = 0; y < M[i]; y++) { - lout[out_x+y] = lin[in_x+y*maxN]; /*out=z*MG*pN+oM[i]+x*MG+y*/ + lout[out_x + y] = lin[in_x + y * maxN]; /*out=z*MG*pN+oM[i]+x*MG+y*/ } } } @@ -840,9 +940,9 @@ static void joinAxesTrans12(t_complex* lout, const t_complex* lin, int maxN, int static void rotate_offsets(int x[]) { int t = x[0]; -/* x[0]=x[2]; - x[2]=x[1]; - x[1]=t;*/ + /* x[0]=x[2]; + x[2]=x[1]; + x[1]=t;*/ x[0] = x[1]; x[1] = x[2]; x[2] = t; @@ -853,17 +953,18 @@ static void rotate_offsets(int x[]) s: step in computation = number of transposes*/ static void compute_offsets(fft5d_plan plan, int xs[], int xl[], int xc[], int NG[], int s) { -/* int direction = plan->direction; - int fftorder = plan->fftorder;*/ + /* int direction = plan->direction; + int fftorder = plan->fftorder;*/ int o = 0; int pos[3], i; - int *pM = plan->pM, *pK = plan->pK, *oM = plan->oM, *oK = plan->oK, - *C = plan->C, *rC = plan->rC; + int *pM = plan->pM, *pK = plan->pK, *oM = plan->oM, *oK = plan->oK, *C = plan->C, *rC = plan->rC; - NG[0] = plan->NG; NG[1] = plan->MG; NG[2] = plan->KG; + NG[0] = plan->NG; + NG[1] = plan->MG; + NG[2] = plan->KG; - if (!(plan->flags&FFT5D_ORDER_YZ)) + if (!(plan->flags & FFT5D_ORDER_YZ)) { switch (s) { @@ -886,12 +987,36 @@ static void compute_offsets(fft5d_plan plan, int xs[], int xl[], int xc[], int N switch (o) { - case XYZ: pos[0] = 1; pos[1] = 2; pos[2] = 3; break; - case XZY: pos[0] = 1; pos[1] = 3; pos[2] = 2; break; - case YXZ: pos[0] = 2; pos[1] = 1; pos[2] = 3; break; - case YZX: pos[0] = 3; pos[1] = 1; pos[2] = 2; break; - case ZXY: pos[0] = 2; pos[1] = 3; pos[2] = 1; break; - case ZYX: pos[0] = 3; pos[1] = 2; pos[2] = 1; break; + case XYZ: + pos[0] = 1; + pos[1] = 2; + pos[2] = 3; + break; + case XZY: + pos[0] = 1; + pos[1] = 3; + pos[2] = 2; + break; + case YXZ: + pos[0] = 2; + pos[1] = 1; + pos[2] = 3; + break; + case YZX: + pos[0] = 3; + pos[1] = 1; + pos[2] = 2; + break; + case ZXY: + pos[0] = 2; + pos[1] = 3; + pos[2] = 1; + break; + case ZYX: + pos[0] = 3; + pos[1] = 2; + pos[2] = 1; + break; } /*if (debug) printf("pos: %d %d %d\n",pos[0],pos[1],pos[2]);*/ @@ -901,20 +1026,32 @@ static void compute_offsets(fft5d_plan plan, int xs[], int xl[], int xc[], int N { switch (pos[i]) { - case 1: xs[i] = 1; xc[i] = 0; xl[i] = C[s]; break; - case 2: xs[i] = C[s]; xc[i] = oM[s]; xl[i] = pM[s]; break; - case 3: xs[i] = C[s]*pM[s]; xc[i] = oK[s]; xl[i] = pK[s]; break; + case 1: + xs[i] = 1; + xc[i] = 0; + xl[i] = C[s]; + break; + case 2: + xs[i] = C[s]; + xc[i] = oM[s]; + xl[i] = pM[s]; + break; + case 3: + xs[i] = C[s] * pM[s]; + xc[i] = oK[s]; + xl[i] = pK[s]; + break; } } /*input order is different for test program to match FFTW order (important for complex to real)*/ - if (plan->flags&FFT5D_BACKWARD) + if (plan->flags & FFT5D_BACKWARD) { rotate_offsets(xs); rotate_offsets(xl); rotate_offsets(xc); rotate_offsets(NG); - if (plan->flags&FFT5D_ORDER_YZ) + if (plan->flags & FFT5D_ORDER_YZ) { rotate_offsets(xs); rotate_offsets(xl); @@ -922,7 +1059,8 @@ static void compute_offsets(fft5d_plan plan, int xs[], int xl[], int xc[], int N rotate_offsets(NG); } } - if ((plan->flags&FFT5D_REALCOMPLEX) && ((!(plan->flags&FFT5D_BACKWARD) && s == 0) || ((plan->flags&FFT5D_BACKWARD) && s == 2))) + if ((plan->flags & FFT5D_REALCOMPLEX) + && ((!(plan->flags & FFT5D_BACKWARD) && s == 0) || ((plan->flags & FFT5D_BACKWARD) && s == 2))) { xl[0] = rC[s]; } @@ -931,9 +1069,9 @@ static void compute_offsets(fft5d_plan plan, int xs[], int xl[], int xc[], int N static void print_localdata(const t_complex* lin, const char* txt, int s, fft5d_plan plan) { int x, y, z, l; - int *coor = plan->coor; + int* coor = plan->coor; int xs[3], xl[3], xc[3], NG[3]; - int ll = (plan->flags&FFT5D_REALCOMPLEX) ? 1 : 2; + int ll = (plan->flags & FFT5D_REALCOMPLEX) ? 1 : 2; compute_offsets(plan, xs, xl, xc, NG, s); fprintf(debug, txt, coor[0], coor[1]); /*printf("xs: %d %d %d, xl: %d %d %d\n",xs[0],xs[1],xs[2],xl[0],xl[1],xl[2]);*/ @@ -946,7 +1084,9 @@ static void print_localdata(const t_complex* lin, const char* txt, int s, fft5d_ { for (l = 0; l < ll; l++) { - fprintf(debug, "%f ", reinterpret_cast(lin)[(z*xs[2]+y*xs[1])*2+(x*xs[0])*ll+l]); + fprintf(debug, "%f ", + reinterpret_cast( + lin)[(z * xs[2] + y * xs[1]) * 2 + (x * xs[0]) * ll + l]); } fprintf(debug, ","); } @@ -957,25 +1097,26 @@ static void print_localdata(const t_complex* lin, const char* txt, int s, fft5d_ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) { - t_complex *lin = plan->lin; - t_complex *lout = plan->lout; - t_complex *lout2 = plan->lout2; - t_complex *lout3 = plan->lout3; - t_complex *fftout, *joinin; + t_complex* lin = plan->lin; + t_complex* lout = plan->lout; + t_complex* lout2 = plan->lout2; + t_complex* lout3 = plan->lout3; + t_complex *fftout, *joinin; - gmx_fft_t **p1d = plan->p1d; + gmx_fft_t** p1d = plan->p1d; #ifdef FFT5D_MPI_TRANSPOSE - FFTW(plan) *mpip = plan->mpip; + FFTW(plan)* mpip = plan->mpip; #endif #if GMX_MPI - MPI_Comm *cart = plan->cart; + MPI_Comm* cart = plan->cart; #endif #ifdef NOGMX - double time_fft = 0, time_local = 0, time_mpi[2] = {0}, time = 0; + double time_fft = 0, time_local = 0, time_mpi[2] = { 0 }, time = 0; #endif - int *N = plan->N, *M = plan->M, *K = plan->K, *pN = plan->pN, *pM = plan->pM, *pK = plan->pK, - *C = plan->C, *P = plan->P, **iNin = plan->iNin, **oNin = plan->oNin, **iNout = plan->iNout, **oNout = plan->oNout; - int s = 0, tstart, tend, bParallelDim; + int *N = plan->N, *M = plan->M, *K = plan->K, *pN = plan->pN, *pM = plan->pM, *pK = plan->pK, + *C = plan->C, *P = plan->P, **iNin = plan->iNin, **oNin = plan->oNin, **iNout = plan->iNout, + **oNout = plan->oNout; + int s = 0, tstart, tend, bParallelDim; #if GMX_FFT_FFTW3 @@ -983,19 +1124,19 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) { if (thread == 0) { -#ifdef NOGMX +# ifdef NOGMX if (times != 0) { time = MPI_Wtime(); } -#endif +# endif FFTW(execute)(plan->p3d); -#ifdef NOGMX +# ifdef NOGMX if (times != 0) { - times->fft += MPI_Wtime()-time; + times->fft += MPI_Wtime() - time; } -#endif +# endif } return; } @@ -1004,12 +1145,12 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) s = 0; /*lin: x,y,z*/ - if ((plan->flags&FFT5D_DEBUG) && thread == 0) + if ((plan->flags & FFT5D_DEBUG) && thread == 0) { print_localdata(lin, "%d %d: copy in lin\n", s, plan); } - for (s = 0; s < 2; s++) /*loop over first two FFT steps (corner rotations)*/ + for (s = 0; s < 2; s++) /*loop over first two FFT steps (corner rotations)*/ { #if GMX_MPI @@ -1047,24 +1188,28 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) } } - tstart = (thread*pM[s]*pK[s]/plan->nthreads)*C[s]; - if ((plan->flags&FFT5D_REALCOMPLEX) && !(plan->flags&FFT5D_BACKWARD) && s == 0) + tstart = (thread * pM[s] * pK[s] / plan->nthreads) * C[s]; + if ((plan->flags & FFT5D_REALCOMPLEX) && !(plan->flags & FFT5D_BACKWARD) && s == 0) { - gmx_fft_many_1d_real(p1d[s][thread], (plan->flags&FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL : GMX_FFT_REAL_TO_COMPLEX, lin+tstart, fftout+tstart); + gmx_fft_many_1d_real(p1d[s][thread], + (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL + : GMX_FFT_REAL_TO_COMPLEX, + lin + tstart, fftout + tstart); } else { - gmx_fft_many_1d( p1d[s][thread], (plan->flags&FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD, lin+tstart, fftout+tstart); - + gmx_fft_many_1d(p1d[s][thread], + (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD, + lin + tstart, fftout + tstart); } #ifdef NOGMX if (times != NULL && thread == 0) { - time_fft += MPI_Wtime()-time; + time_fft += MPI_Wtime() - time; } #endif - if ((plan->flags&FFT5D_DEBUG) && thread == 0) + if ((plan->flags & FFT5D_DEBUG) && thread == 0) { print_localdata(lout, "%d %d: FFT %d\n", s, plan); } @@ -1085,15 +1230,16 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) for sending*/ if (pM[s] > 0) { - tend = ((thread+1)*pM[s]*pK[s]/plan->nthreads); + tend = ((thread + 1) * pM[s] * pK[s] / plan->nthreads); tstart /= C[s]; - splitaxes(lout2, lout, N[s], M[s], K[s], pM[s], P[s], C[s], iNout[s], oNout[s], tstart%pM[s], tstart/pM[s], tend%pM[s], tend/pM[s]); + splitaxes(lout2, lout, N[s], M[s], K[s], pM[s], P[s], C[s], iNout[s], oNout[s], + tstart % pM[s], tstart / pM[s], tend % pM[s], tend / pM[s]); } #pragma omp barrier /*barrier required before AllToAll (all input has to be their) - before timing to make timing more acurate*/ #ifdef NOGMX if (times != NULL && thread == 0) { - time_local += MPI_Wtime()-time; + time_local += MPI_Wtime() - time; } #endif @@ -1112,30 +1258,39 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) #ifdef FFT5D_MPI_TRANSPOSE FFTW(execute)(mpip[s]); #else -#if GMX_MPI - if ((s == 0 && !(plan->flags&FFT5D_ORDER_YZ)) || (s == 1 && (plan->flags&FFT5D_ORDER_YZ))) +# if GMX_MPI + if ((s == 0 && !(plan->flags & FFT5D_ORDER_YZ)) + || (s == 1 && (plan->flags & FFT5D_ORDER_YZ))) { - MPI_Alltoall(reinterpret_cast(lout2), N[s]*pM[s]*K[s]*sizeof(t_complex)/sizeof(real), GMX_MPI_REAL, reinterpret_cast(lout3), N[s]*pM[s]*K[s]*sizeof(t_complex)/sizeof(real), GMX_MPI_REAL, cart[s]); + MPI_Alltoall(reinterpret_cast(lout2), + N[s] * pM[s] * K[s] * sizeof(t_complex) / sizeof(real), + GMX_MPI_REAL, reinterpret_cast(lout3), + N[s] * pM[s] * K[s] * sizeof(t_complex) / sizeof(real), + GMX_MPI_REAL, cart[s]); } else { - MPI_Alltoall(reinterpret_cast(lout2), N[s]*M[s]*pK[s]*sizeof(t_complex)/sizeof(real), GMX_MPI_REAL, reinterpret_cast(lout3), N[s]*M[s]*pK[s]*sizeof(t_complex)/sizeof(real), GMX_MPI_REAL, cart[s]); + MPI_Alltoall(reinterpret_cast(lout2), + N[s] * M[s] * pK[s] * sizeof(t_complex) / sizeof(real), + GMX_MPI_REAL, reinterpret_cast(lout3), + N[s] * M[s] * pK[s] * sizeof(t_complex) / sizeof(real), + GMX_MPI_REAL, cart[s]); } -#else +# else gmx_incons("fft5d MPI call without MPI configuration"); -#endif /*GMX_MPI*/ -#endif /*FFT5D_MPI_TRANSPOSE*/ +# endif /*GMX_MPI*/ +#endif /*FFT5D_MPI_TRANSPOSE*/ #ifdef NOGMX if (times != 0) { - time_mpi[s] = MPI_Wtime()-time; + time_mpi[s] = MPI_Wtime() - time; } #else wallcycle_stop(times, ewcPME_FFTCOMM); #endif - } /*master*/ - } /* bPrallelDim */ -#pragma omp barrier /*both needed for parallel and non-parallel dimension (either have to wait on data from AlltoAll or from last FFT*/ + } /*master*/ + } /* bPrallelDim */ +#pragma omp barrier /*both needed for parallel and non-parallel dimension (either have to wait on data from AlltoAll or from last FFT*/ /* ---------- END SPLIT + TRANSPOSE------------ */ @@ -1160,39 +1315,41 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) also local transpose 1 and 2/3 runs on thread used for following FFT (thus needing a barrier before but not afterwards) */ - if ((s == 0 && !(plan->flags&FFT5D_ORDER_YZ)) || (s == 1 && (plan->flags&FFT5D_ORDER_YZ))) + if ((s == 0 && !(plan->flags & FFT5D_ORDER_YZ)) || (s == 1 && (plan->flags & FFT5D_ORDER_YZ))) { if (pM[s] > 0) { - tstart = ( thread *pM[s]*pN[s]/plan->nthreads); - tend = ((thread+1)*pM[s]*pN[s]/plan->nthreads); - joinAxesTrans13(lin, joinin, N[s], pM[s], K[s], pM[s], P[s], C[s+1], iNin[s+1], oNin[s+1], tstart%pM[s], tstart/pM[s], tend%pM[s], tend/pM[s]); + tstart = (thread * pM[s] * pN[s] / plan->nthreads); + tend = ((thread + 1) * pM[s] * pN[s] / plan->nthreads); + joinAxesTrans13(lin, joinin, N[s], pM[s], K[s], pM[s], P[s], C[s + 1], iNin[s + 1], + oNin[s + 1], tstart % pM[s], tstart / pM[s], tend % pM[s], tend / pM[s]); } } else { if (pN[s] > 0) { - tstart = ( thread *pK[s]*pN[s]/plan->nthreads); - tend = ((thread+1)*pK[s]*pN[s]/plan->nthreads); - joinAxesTrans12(lin, joinin, N[s], M[s], pK[s], pN[s], P[s], C[s+1], iNin[s+1], oNin[s+1], tstart%pN[s], tstart/pN[s], tend%pN[s], tend/pN[s]); + tstart = (thread * pK[s] * pN[s] / plan->nthreads); + tend = ((thread + 1) * pK[s] * pN[s] / plan->nthreads); + joinAxesTrans12(lin, joinin, N[s], M[s], pK[s], pN[s], P[s], C[s + 1], iNin[s + 1], + oNin[s + 1], tstart % pN[s], tstart / pN[s], tend % pN[s], tend / pN[s]); } } #ifdef NOGMX if (times != NULL && thread == 0) { - time_local += MPI_Wtime()-time; + time_local += MPI_Wtime() - time; } #endif - if ((plan->flags&FFT5D_DEBUG) && thread == 0) + if ((plan->flags & FFT5D_DEBUG) && thread == 0) { - print_localdata(lin, "%d %d: tranposed %d\n", s+1, plan); + print_localdata(lin, "%d %d: tranposed %d\n", s + 1, plan); } /* ---------- END JOIN ------------ */ /*if (debug) print_localdata(lin, "%d %d: transposed x-z\n", N1, M0, K, ZYX, coor);*/ - } /* for(s=0;s<2;s++) */ + } /* for(s=0;s<2;s++) */ #ifdef NOGMX if (times != NULL && thread == 0) { @@ -1200,36 +1357,38 @@ void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times) } #endif - if (plan->flags&FFT5D_INPLACE) + if (plan->flags & FFT5D_INPLACE) { - lout = lin; /*in place currently not supported*/ - + lout = lin; /*in place currently not supported*/ } /* ----------- FFT ----------- */ - tstart = (thread*pM[s]*pK[s]/plan->nthreads)*C[s]; - if ((plan->flags&FFT5D_REALCOMPLEX) && (plan->flags&FFT5D_BACKWARD)) + tstart = (thread * pM[s] * pK[s] / plan->nthreads) * C[s]; + if ((plan->flags & FFT5D_REALCOMPLEX) && (plan->flags & FFT5D_BACKWARD)) { - gmx_fft_many_1d_real(p1d[s][thread], (plan->flags&FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL : GMX_FFT_REAL_TO_COMPLEX, lin+tstart, lout+tstart); + gmx_fft_many_1d_real(p1d[s][thread], + (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_COMPLEX_TO_REAL : GMX_FFT_REAL_TO_COMPLEX, + lin + tstart, lout + tstart); } else { - gmx_fft_many_1d( p1d[s][thread], (plan->flags&FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD, lin+tstart, lout+tstart); + gmx_fft_many_1d(p1d[s][thread], (plan->flags & FFT5D_BACKWARD) ? GMX_FFT_BACKWARD : GMX_FFT_FORWARD, + lin + tstart, lout + tstart); } /* ------------ END FFT ---------*/ #ifdef NOGMX if (times != NULL && thread == 0) { - time_fft += MPI_Wtime()-time; + time_fft += MPI_Wtime() - time; - times->fft += time_fft; + times->fft += time_fft; times->local += time_local; - times->mpi2 += time_mpi[1]; - times->mpi1 += time_mpi[0]; + times->mpi2 += time_mpi[1]; + times->mpi1 += time_mpi[0]; } #endif - if ((plan->flags&FFT5D_DEBUG) && thread == 0) + if ((plan->flags & FFT5D_DEBUG) && thread == 0) { print_localdata(lout, "%d %d: FFT %d\n", s, plan); } @@ -1271,25 +1430,24 @@ void fft5d_destroy(fft5d_plan plan) } } #if GMX_FFT_FFTW3 - FFTW_LOCK; -#ifdef FFT5D_MPI_TRANSPOS + FFTW_LOCK +# ifdef FFT5D_MPI_TRANSPOS for (s = 0; s < 2; s++) { FFTW(destroy_plan)(plan->mpip[s]); } -#endif /* FFT5D_MPI_TRANSPOS */ +# endif /* FFT5D_MPI_TRANSPOS */ if (plan->p3d) { FFTW(destroy_plan)(plan->p3d); } - FFTW_UNLOCK; + FFTW_UNLOCK #endif /* GMX_FFT_FFTW3 */ - if (!(plan->flags&FFT5D_NOMALLOC)) + if (!(plan->flags & FFT5D_NOMALLOC)) { // only needed for PME GPU mixed mode - if (plan->pinningPolicy == gmx::PinningPolicy::PinnedIfSupported && - isHostMemoryPinned(plan->lin)) + if (plan->pinningPolicy == gmx::PinningPolicy::PinnedIfSupported && isHostMemoryPinned(plan->lin)) { gmx::unpinBuffer(plan->lin); } @@ -1303,9 +1461,9 @@ void fft5d_destroy(fft5d_plan plan) } #ifdef FFT5D_THREADS -#ifdef FFT5D_FFTW_THREADS +# ifdef FFT5D_FFTW_THREADS /*FFTW(cleanup_threads)();*/ -#endif +# endif #endif free(plan); @@ -1326,16 +1484,26 @@ void fft5d_local_size(fft5d_plan plan, int* N1, int* M0, int* K0, int* K1, int** /*same as fft5d_plan_3d but with cartesian coordinator and automatic splitting of processor dimensions*/ -fft5d_plan fft5d_plan_3d_cart(int NG, int MG, int KG, MPI_Comm comm, int P0, int flags, t_complex** rlin, t_complex** rlout, t_complex** rlout2, t_complex** rlout3, int nthreads) +fft5d_plan fft5d_plan_3d_cart(int NG, + int MG, + int KG, + MPI_Comm comm, + int P0, + int flags, + t_complex** rlin, + t_complex** rlout, + t_complex** rlout2, + t_complex** rlout3, + int nthreads) { - MPI_Comm cart[2] = {MPI_COMM_NULL, MPI_COMM_NULL}; + MPI_Comm cart[2] = { MPI_COMM_NULL, MPI_COMM_NULL }; #if GMX_MPI int size = 1, prank = 0; int P[2]; int coor[2]; - int wrap[] = {0, 0}; + int wrap[] = { 0, 0 }; MPI_Comm gcart; - int rdim1[] = {0, 1}, rdim2[] = {1, 0}; + int rdim1[] = { 0, 1 }, rdim2[] = { 1, 0 }; MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &prank); @@ -1344,7 +1512,7 @@ fft5d_plan fft5d_plan_3d_cart(int NG, int MG, int KG, MPI_Comm comm, int P0, int { P0 = lfactor(size); } - if (size%P0 != 0) + if (size % P0 != 0) { if (prank == 0) { @@ -1353,7 +1521,8 @@ fft5d_plan fft5d_plan_3d_cart(int NG, int MG, int KG, MPI_Comm comm, int P0, int P0 = lfactor(size); } - P[0] = P0; P[1] = size/P0; /*number of processors in the two dimensions*/ + P[0] = P0; + P[1] = size / P0; /*number of processors in the two dimensions*/ /*Difference between x-y-z regarding 2d decomposition is whether they are distributed along axis 1, 2 or both*/ @@ -1370,21 +1539,20 @@ fft5d_plan fft5d_plan_3d_cart(int NG, int MG, int KG, MPI_Comm comm, int P0, int } - /*prints in original coordinate system of data (as the input to FFT)*/ void fft5d_compare_data(const t_complex* lin, const t_complex* in, fft5d_plan plan, int bothLocal, int normalize) { int xs[3], xl[3], xc[3], NG[3]; int x, y, z, l; - int *coor = plan->coor; + int* coor = plan->coor; int ll = 2; /*compare ll values per element (has to be 2 for complex)*/ - if ((plan->flags&FFT5D_REALCOMPLEX) && (plan->flags&FFT5D_BACKWARD)) + if ((plan->flags & FFT5D_REALCOMPLEX) && (plan->flags & FFT5D_BACKWARD)) { ll = 1; } compute_offsets(plan, xs, xl, xc, NG, 2); - if (plan->flags&FFT5D_DEBUG) + if (plan->flags & FFT5D_DEBUG) { printf("Compare2\n"); } @@ -1392,51 +1560,53 @@ void fft5d_compare_data(const t_complex* lin, const t_complex* in, fft5d_plan pl { for (y = 0; y < xl[1]; y++) { - if (plan->flags&FFT5D_DEBUG) + if (plan->flags & FFT5D_DEBUG) { printf("%d %d: ", coor[0], coor[1]); } for (x = 0; x < xl[0]; x++) { - for (l = 0; l < ll; l++) /*loop over real/complex parts*/ + for (l = 0; l < ll; l++) /*loop over real/complex parts*/ { real a, b; - a = reinterpret_cast(lin)[(z*xs[2]+y*xs[1])*2+x*xs[0]*ll+l]; + a = reinterpret_cast(lin)[(z * xs[2] + y * xs[1]) * 2 + x * xs[0] * ll + l]; if (normalize) { - a /= plan->rC[0]*plan->rC[1]*plan->rC[2]; + a /= plan->rC[0] * plan->rC[1] * plan->rC[2]; } if (!bothLocal) { - b = reinterpret_cast(in)[((z+xc[2])*NG[0]*NG[1]+(y+xc[1])*NG[0])*2+(x+xc[0])*ll+l]; + b = reinterpret_cast( + in)[((z + xc[2]) * NG[0] * NG[1] + (y + xc[1]) * NG[0]) * 2 + (x + xc[0]) * ll + l]; } else { - b = reinterpret_cast(in)[(z*xs[2]+y*xs[1])*2+x*xs[0]*ll+l]; + b = reinterpret_cast( + in)[(z * xs[2] + y * xs[1]) * 2 + x * xs[0] * ll + l]; } - if (plan->flags&FFT5D_DEBUG) + if (plan->flags & FFT5D_DEBUG) { printf("%f %f, ", a, b); } else { - if (std::fabs(a-b) > 2*NG[0]*NG[1]*NG[2]*GMX_REAL_EPS) + if (std::fabs(a - b) > 2 * NG[0] * NG[1] * NG[2] * GMX_REAL_EPS) { - printf("result incorrect on %d,%d at %d,%d,%d: FFT5D:%f reference:%f\n", coor[0], coor[1], x, y, z, a, b); + printf("result incorrect on %d,%d at %d,%d,%d: FFT5D:%f reference:%f\n", + coor[0], coor[1], x, y, z, a, b); } -/* assert(fabs(a-b)<2*NG[0]*NG[1]*NG[2]*GMX_REAL_EPS);*/ + /* assert(fabs(a-b)<2*NG[0]*NG[1]*NG[2]*GMX_REAL_EPS);*/ } } - if (plan->flags&FFT5D_DEBUG) + if (plan->flags & FFT5D_DEBUG) { printf(","); } } - if (plan->flags&FFT5D_DEBUG) + if (plan->flags & FFT5D_DEBUG) { printf("\n"); } } } - } diff --git a/src/gromacs/fft/fft5d.h b/src/gromacs/fft/fft5d.h index 39f945aeaa..71d86817a0 100644 --- a/src/gromacs/fft/fft5d.h +++ b/src/gromacs/fft/fft5d.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2009-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,31 +56,33 @@ double MPI_Wtime(); /*currently only special optimization for FFTE*/ #if GMX_FFT_FFTW3 -#include +# include #endif #if !GMX_DOUBLE -#define FFTW(x) fftwf_ ## x +# define FFTW(x) fftwf_##x #else -#define FFTW(x) fftw_ ## x +# define FFTW(x) fftw_##x #endif #ifdef NOGMX -struct fft5d_time_t { +struct fft5d_time_t +{ double fft, local, mpi1, mpi2; }; -typedef struct fft5d_time_t *fft5d_time; +typedef struct fft5d_time_t* fft5d_time; #else -#include "gromacs/timing/wallcycle.h" +# include "gromacs/timing/wallcycle.h" typedef gmx_wallcycle_t fft5d_time; #endif namespace gmx { enum class PinningPolicy : int; -} // namespace +} // namespace gmx -typedef enum fft5d_flags_t { +typedef enum fft5d_flags_t +{ FFT5D_ORDER_YZ = 1, FFT5D_BACKWARD = 2, FFT5D_REALCOMPLEX = 4, @@ -89,44 +92,66 @@ typedef enum fft5d_flags_t { FFT5D_NOMALLOC = 64 } fft5d_flags; -struct fft5d_plan_t { - t_complex *lin; +struct fft5d_plan_t +{ + t_complex* lin; t_complex *lout, *lout2, *lout3; gmx_fft_t* p1d[3]; /*1D plans*/ #if GMX_FFT_FFTW3 - FFTW(plan) p2d; /*2D plan: used for 1D decomposition if FFT supports transposed output*/ - FFTW(plan) p3d; /*3D plan: used for 0D decomposition if FFT supports transposed output*/ + FFTW(plan) p2d; /*2D plan: used for 1D decomposition if FFT supports transposed output*/ + FFTW(plan) p3d; /*3D plan: used for 0D decomposition if FFT supports transposed output*/ FFTW(plan) mpip[2]; #endif MPI_Comm cart[2]; - int N[3], M[3], K[3]; /*local length in transposed coordinate system (if not divisisable max)*/ - int pN[3], pM[3], pK[3]; /*local length - not max but length for this processor*/ - int oM[3], oK[3]; /*offset for current processor*/ - int *iNin[3], *oNin[3], *iNout[3], *oNout[3]; /*size for each processor (if divisisable=max) for out(=split) - and in (=join) and offsets in transposed coordinate system*/ - int C[3], rC[3]; /*global length (of the one global axes) */ + int N[3], M[3], K[3]; /*local length in transposed coordinate system (if not divisisable max)*/ + int pN[3], pM[3], pK[3]; /*local length - not max but length for this processor*/ + int oM[3], oK[3]; /*offset for current processor*/ + int *iNin[3], *oNin[3], *iNout[3], + *oNout[3]; /*size for each processor (if divisisable=max) for out(=split) + and in (=join) and offsets in transposed coordinate system*/ + int C[3], rC[3]; /*global length (of the one global axes) */ /* C!=rC for real<->complex. then C=rC/2 but with potential padding*/ - int P[2]; /*size of processor grid*/ -/* int fftorder;*/ -/* int direction;*/ -/* int realcomplex;*/ - int flags; + int P[2]; /*size of processor grid*/ + /* int fftorder;*/ + /* int direction;*/ + /* int realcomplex;*/ + int flags; /*int N0,N1,M0,M1,K0,K1;*/ - int NG, MG, KG; + int NG, MG, KG; /*int P[2];*/ int coor[2]; int nthreads; gmx::PinningPolicy pinningPolicy; }; -typedef struct fft5d_plan_t *fft5d_plan; +typedef struct fft5d_plan_t* fft5d_plan; -void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times); -fft5d_plan fft5d_plan_3d(int N, int M, int K, MPI_Comm comm[2], int flags, t_complex**lin, t_complex**lin2, t_complex**lout2, t_complex**lout3, int nthreads, gmx::PinningPolicy realGridAllocationPinningPolicy = gmx::PinningPolicy::CannotBePinned); -void fft5d_local_size(fft5d_plan plan, int* N1, int* M0, int* K0, int* K1, int** coor); -void fft5d_destroy(fft5d_plan plan); -fft5d_plan fft5d_plan_3d_cart(int N, int M, int K, MPI_Comm comm, int P0, int flags, t_complex** lin, t_complex** lin2, t_complex** lout2, t_complex** lout3, int nthreads); -void fft5d_compare_data(const t_complex* lin, const t_complex* in, fft5d_plan plan, int bothLocal, int normarlize); +void fft5d_execute(fft5d_plan plan, int thread, fft5d_time times); +fft5d_plan fft5d_plan_3d(int N, + int M, + int K, + MPI_Comm comm[2], + int flags, + t_complex** lin, + t_complex** lin2, + t_complex** lout2, + t_complex** lout3, + int nthreads, + gmx::PinningPolicy realGridAllocationPinningPolicy = gmx::PinningPolicy::CannotBePinned); +void fft5d_local_size(fft5d_plan plan, int* N1, int* M0, int* K0, int* K1, int** coor); +void fft5d_destroy(fft5d_plan plan); +fft5d_plan fft5d_plan_3d_cart(int N, + int M, + int K, + MPI_Comm comm, + int P0, + int flags, + t_complex** lin, + t_complex** lin2, + t_complex** lout2, + t_complex** lout3, + int nthreads); +void fft5d_compare_data(const t_complex* lin, const t_complex* in, fft5d_plan plan, int bothLocal, int normarlize); #endif diff --git a/src/gromacs/fft/fft_fftpack.cpp b/src/gromacs/fft/fft_fftpack.cpp index f87426fa67..49615f9ec0 100644 --- a/src/gromacs/fft/fft_fftpack.cpp +++ b/src/gromacs/fft/fft_fftpack.cpp @@ -68,16 +68,13 @@ struct gmx_fft int ndim; /**< Dimensions, including our subdimensions. */ int n; /**< Number of points in this dimension. */ int ifac[15]; /**< 15 bytes needed for cfft and rfft */ - struct gmx_fft *next; /**< Pointer to next dimension, or NULL. */ - real * work; /**< 1st 4n reserved for cfft, 1st 2n for rfft */ + struct gmx_fft* next; /**< Pointer to next dimension, or NULL. */ + real* work; /**< 1st 4n reserved for cfft, 1st 2n for rfft */ }; -int -gmx_fft_init_1d(gmx_fft_t * pfft, - int nx, - int gmx_unused flags) +int gmx_fft_init_1d(gmx_fft_t* pfft, int nx, int gmx_unused flags) { - gmx_fft_t fft; + gmx_fft_t fft; if (pfft == nullptr) { @@ -86,7 +83,7 @@ gmx_fft_init_1d(gmx_fft_t * pfft, } *pfft = nullptr; - if ( (fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) + if ((fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) { return ENOMEM; } @@ -95,7 +92,7 @@ gmx_fft_init_1d(gmx_fft_t * pfft, fft->n = nx; /* Need 4*n storage for 1D complex FFT */ - if ( (fft->work = static_cast(malloc(sizeof(real)*(4*nx)))) == nullptr) + if ((fft->work = static_cast(malloc(sizeof(real) * (4 * nx)))) == nullptr) { free(fft); return ENOMEM; @@ -111,13 +108,9 @@ gmx_fft_init_1d(gmx_fft_t * pfft, }; - -int -gmx_fft_init_1d_real(gmx_fft_t * pfft, - int nx, - int gmx_unused flags) +int gmx_fft_init_1d_real(gmx_fft_t* pfft, int nx, int gmx_unused flags) { - gmx_fft_t fft; + gmx_fft_t fft; if (pfft == nullptr) { @@ -126,7 +119,7 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, } *pfft = nullptr; - if ( (fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) + if ((fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) { return ENOMEM; } @@ -135,7 +128,7 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, fft->n = nx; /* Need 2*n storage for 1D real FFT */ - if ((fft->work = static_cast(malloc(sizeof(real)*(2*nx)))) == nullptr) + if ((fft->work = static_cast(malloc(sizeof(real) * (2 * nx)))) == nullptr) { free(fft); return ENOMEM; @@ -150,15 +143,11 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, return 0; } -int -gmx_fft_init_2d_real(gmx_fft_t * pfft, - int nx, - int ny, - int flags) +int gmx_fft_init_2d_real(gmx_fft_t* pfft, int nx, int ny, int flags) { - gmx_fft_t fft; - int nyc = (ny/2 + 1); - int rc; + gmx_fft_t fft; + int nyc = (ny / 2 + 1); + int rc; if (pfft == nullptr) { @@ -168,17 +157,17 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, *pfft = nullptr; /* Create the X transform */ - if ( (fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) + if ((fft = static_cast(malloc(sizeof(struct gmx_fft)))) == nullptr) { return ENOMEM; } - fft->n = nx; + fft->n = nx; /* Need 4*nx storage for 1D complex FFT, and another * 2*nx*nyc elements for complex-to-real storage in our high-level routine. */ - if ( (fft->work = static_cast(malloc(sizeof(real)*(4*nx+2*nx*nyc)))) == nullptr) + if ((fft->work = static_cast(malloc(sizeof(real) * (4 * nx + 2 * nx * nyc)))) == nullptr) { free(fft); return ENOMEM; @@ -186,7 +175,7 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, fftpack_cffti1(nx, fft->work, fft->ifac); /* Create real Y transform as a link from X */ - if ( (rc = gmx_fft_init_1d_real(&(fft->next), ny, flags)) != 0) + if ((rc = gmx_fft_init_1d_real(&(fft->next), ny, flags)) != 0) { free(fft); return rc; @@ -197,22 +186,18 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, } -int -gmx_fft_1d (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - int i, n; - real * p1; - real * p2; + int i, n; + real* p1; + real* p2; n = fft->n; if (n == 1) { - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); p2[0] = p1[0]; p2[1] = p1[1]; } @@ -222,11 +207,11 @@ gmx_fft_1d (gmx_fft_t fft, */ if (in_data != out_data) { - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); /* n complex = 2*n real elements */ - for (i = 0; i < 2*n; i++) + for (i = 0; i < 2 * n; i++) { p2[i] = p1[i]; } @@ -238,11 +223,11 @@ gmx_fft_1d (gmx_fft_t fft, if (dir == GMX_FFT_FORWARD) { - fftpack_cfftf1(n, static_cast(out_data), fft->work+2*n, fft->work, fft->ifac, -1); + fftpack_cfftf1(n, static_cast(out_data), fft->work + 2 * n, fft->work, fft->ifac, -1); } else if (dir == GMX_FFT_BACKWARD) { - fftpack_cfftf1(n, static_cast(out_data), fft->work+2*n, fft->work, fft->ifac, 1); + fftpack_cfftf1(n, static_cast(out_data), fft->work + 2 * n, fft->work, fft->ifac, 1); } else { @@ -254,23 +239,18 @@ gmx_fft_1d (gmx_fft_t fft, } - -int -gmx_fft_1d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - int i, n; - real * p1; - real * p2; + int i, n; + real* p1; + real* p2; n = fft->n; if (n == 1) { - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); p2[0] = p1[0]; if (dir == GMX_FFT_REAL_TO_COMPLEX) { @@ -286,10 +266,10 @@ gmx_fft_1d_real (gmx_fft_t fft, */ if (in_data != out_data) { - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); - for (i = 0; i < 2*(n/2+1); i++) + for (i = 0; i < 2 * (n / 2 + 1); i++) { p2[i] = p1[i]; } @@ -298,27 +278,26 @@ gmx_fft_1d_real (gmx_fft_t fft, /* Elements 0 .. n-1 in work are used for ffac values, * Elements n .. 2*n-1 are internal FFTPACK work space. */ - fftpack_rfftf1(n, static_cast(out_data), fft->work+n, fft->work, fft->ifac); + fftpack_rfftf1(n, static_cast(out_data), fft->work + n, fft->work, fft->ifac); /* * FFTPACK has a slightly more compact storage than we, time to * convert it: ove most of the array one step up to make room for * zero imaginary parts. */ - p2 = static_cast(out_data); - for (i = n-1; i > 0; i--) + p2 = static_cast(out_data); + for (i = n - 1; i > 0; i--) { - p2[i+1] = p2[i]; + p2[i + 1] = p2[i]; } /* imaginary zero freq. */ p2[1] = 0; /* Is n even? */ - if ( (n & 0x1) == 0) + if ((n & 0x1) == 0) { - p2[n+1] = 0; + p2[n + 1] = 0; } - } else if (dir == GMX_FFT_COMPLEX_TO_REAL) { @@ -328,15 +307,15 @@ gmx_fft_1d_real (gmx_fft_t fft, * is more compact than ours (2 reals) it will fit, so compact it * and copy on-the-fly to the output array. */ - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); p2[0] = p1[0]; for (i = 1; i < n; i++) { - p2[i] = p1[i+1]; + p2[i] = p1[i + 1]; } - fftpack_rfftb1(n, static_cast(out_data), fft->work+n, fft->work, fft->ifac); + fftpack_rfftb1(n, static_cast(out_data), fft->work + n, fft->work, fft->ifac); } else { @@ -348,24 +327,20 @@ gmx_fft_1d_real (gmx_fft_t fft, } -int -gmx_fft_2d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_2d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - int i, j, nx, ny, nyc; - t_complex * data; - real * work; - real * p1; - real * p2; + int i, j, nx, ny, nyc; + t_complex* data; + real* work; + real* p1; + real* p2; nx = fft->n; ny = fft->next->n; /* Number of complex elements in y direction */ - nyc = (ny/2+1); + nyc = (ny / 2 + 1); - work = fft->work+4*nx; + work = fft->work + 4 * nx; if (dir == GMX_FFT_REAL_TO_COMPLEX) { @@ -378,23 +353,23 @@ gmx_fft_2d_real (gmx_fft_t fft, */ if (in_data != out_data) { - p1 = static_cast(in_data); - p2 = static_cast(out_data); + p1 = static_cast(in_data); + p2 = static_cast(out_data); for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { - p2[i*nyc*2+j] = p1[i*ny+j]; + p2[i * nyc * 2 + j] = p1[i * ny + j]; } } } - data = static_cast(out_data); + data = static_cast(out_data); /* y real-to-complex FFTs */ for (i = 0; i < nx; i++) { - gmx_fft_1d_real(fft->next, GMX_FFT_REAL_TO_COMPLEX, data+i*nyc, data+i*nyc); + gmx_fft_1d_real(fft->next, GMX_FFT_REAL_TO_COMPLEX, data + i * nyc, data + i * nyc); } /* Transform to get X data in place */ @@ -403,12 +378,11 @@ gmx_fft_2d_real (gmx_fft_t fft, /* Complex-to-complex X FFTs */ for (i = 0; i < nyc; i++) { - gmx_fft_1d(fft, GMX_FFT_FORWARD, data+i*nx, data+i*nx); + gmx_fft_1d(fft, GMX_FFT_FORWARD, data + i * nx, data + i * nx); } /* Transpose back */ gmx_fft_transpose_2d(data, data, nyc, nx); - } else if (dir == GMX_FFT_COMPLEX_TO_REAL) { @@ -422,13 +396,13 @@ gmx_fft_2d_real (gmx_fft_t fft, */ if (in_data != out_data) { - memcpy(work, in_data, sizeof(t_complex)*nx*nyc); - data = reinterpret_cast(work); + memcpy(work, in_data, sizeof(t_complex) * nx * nyc); + data = reinterpret_cast(work); } else { /* in-place */ - data = reinterpret_cast(out_data); + data = reinterpret_cast(out_data); } /* Transpose to get X arrays */ @@ -437,7 +411,7 @@ gmx_fft_2d_real (gmx_fft_t fft, /* Do X iFFTs */ for (i = 0; i < nyc; i++) { - gmx_fft_1d(fft, GMX_FFT_BACKWARD, data+i*nx, data+i*nx); + gmx_fft_1d(fft, GMX_FFT_BACKWARD, data + i * nx, data + i * nx); } /* Transpose to get Y arrays */ @@ -446,7 +420,7 @@ gmx_fft_2d_real (gmx_fft_t fft, /* Do Y iFFTs */ for (i = 0; i < nx; i++) { - gmx_fft_1d_real(fft->next, GMX_FFT_COMPLEX_TO_REAL, data+i*nyc, data+i*nyc); + gmx_fft_1d_real(fft->next, GMX_FFT_COMPLEX_TO_REAL, data + i * nyc, data + i * nyc); } if (in_data != out_data) @@ -454,14 +428,14 @@ gmx_fft_2d_real (gmx_fft_t fft, /* Output (pointed to by data) is now in padded format. * Pack it into out_data if we were doing an out-of-place transform. */ - p1 = reinterpret_cast(data); - p2 = static_cast(out_data); + p1 = reinterpret_cast(data); + p2 = static_cast(out_data); for (i = 0; i < nx; i++) { for (j = 0; j < ny; j++) { - p2[i*ny+j] = p1[i*nyc*2+j]; + p2[i * ny + j] = p1[i * nyc * 2 + j]; } } } @@ -475,8 +449,7 @@ gmx_fft_2d_real (gmx_fft_t fft, return 0; } -void -gmx_fft_destroy(gmx_fft_t fft) +void gmx_fft_destroy(gmx_fft_t fft) { if (fft != nullptr) { @@ -489,6 +462,4 @@ gmx_fft_destroy(gmx_fft_t fft) } } -void gmx_fft_cleanup() -{ -} +void gmx_fft_cleanup() {} diff --git a/src/gromacs/fft/fft_fftw3.cpp b/src/gromacs/fft/fft_fftw3.cpp index 69f314cfe2..7dc332f607 100644 --- a/src/gromacs/fft/fft_fftw3.cpp +++ b/src/gromacs/fft/fft_fftw3.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,16 +48,26 @@ #include "gromacs/utility/mutex.h" #if GMX_DOUBLE -#define FFTWPREFIX(name) fftw_ ## name +# define FFTWPREFIX(name) fftw_##name #else -#define FFTWPREFIX(name) fftwf_ ## name +# define FFTWPREFIX(name) fftwf_##name #endif /* none of the fftw3 calls, except execute(), are thread-safe, so we need to serialize them with this mutex. */ static gmx::Mutex big_fftw_mutex; -#define FFTW_LOCK try { big_fftw_mutex.lock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR -#define FFTW_UNLOCK try { big_fftw_mutex.unlock(); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR +#define FFTW_LOCK \ + try \ + { \ + big_fftw_mutex.lock(); \ + } \ + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR +#define FFTW_UNLOCK \ + try \ + { \ + big_fftw_mutex.unlock(); \ + } \ + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR /* We assume here that aligned memory starts at multiple of 16 bytes and unaligned memory starts at multiple of 8 bytes. The later is guranteed for all malloc implementation. Consequesences: @@ -86,33 +96,26 @@ struct gmx_fft * second index: 0=out-of-place, 1=in-place * third index: 0=backward, 1=forward */ - FFTWPREFIX(plan) plan[2][2][2]; + FFTWPREFIX(plan) plan[2][2][2]; /** Used to catch user mistakes */ - int real_transform; + int real_transform; /** Number of dimensions in the FFT */ - int ndim; + int ndim; }; -int -gmx_fft_init_1d(gmx_fft_t * pfft, - int nx, - gmx_fft_flag flags) +int gmx_fft_init_1d(gmx_fft_t* pfft, int nx, gmx_fft_flag flags) { return gmx_fft_init_many_1d(pfft, nx, 1, flags); } -int -gmx_fft_init_many_1d(gmx_fft_t * pfft, - int nx, - int howmany, - gmx_fft_flag flags) +int gmx_fft_init_many_1d(gmx_fft_t* pfft, int nx, int howmany, gmx_fft_flag flags) { - gmx_fft_t fft; - FFTWPREFIX(complex) *p1, *p2, *up1, *up2; - char* pc; - int i, j, k; - int fftw_flags; + gmx_fft_t fft; + FFTWPREFIX(complex) * p1, *p2, *up1, *up2; + char* pc; + int i, j, k; + int fftw_flags; #if GMX_DISABLE_FFTW_MEASURE flags |= GMX_FFT_FLAG_CONSERVATIVE; @@ -127,28 +130,30 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, } *pfft = nullptr; - FFTW_LOCK; - if ( (fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) + FFTW_LOCK + if ((fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) { - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } /* allocate aligned, and extra memory to make it unaligned */ - p1 = static_cast(FFTWPREFIX(malloc)(sizeof(FFTWPREFIX(complex))*(nx+2)*howmany)); + p1 = static_cast( + FFTWPREFIX(malloc)(sizeof(FFTWPREFIX(complex)) * (nx + 2) * howmany)); if (p1 == nullptr) { FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } - p2 = static_cast(FFTWPREFIX(malloc)(sizeof(FFTWPREFIX(complex))*(nx+2)*howmany)); + p2 = static_cast( + FFTWPREFIX(malloc)(sizeof(FFTWPREFIX(complex)) * (nx + 2) * howmany)); if (p2 == nullptr) { FFTWPREFIX(free)(p1); FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } @@ -156,13 +161,13 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, * In double precision the actual complex datatype will be 16 bytes, * so go to a char pointer and force an offset of 8 bytes instead. */ - pc = reinterpret_cast(p1); + pc = reinterpret_cast(p1); pc += 8; - up1 = reinterpret_cast(pc); + up1 = reinterpret_cast(pc); - pc = reinterpret_cast(p2); + pc = reinterpret_cast(p2); pc += 8; - up2 = reinterpret_cast(pc); + up2 = reinterpret_cast(pc); /* int rank, const int *n, int howmany, fftw_complex *in, const int *inembed, @@ -170,14 +175,22 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, fftw_complex *out, const int *onembed, int ostride, int odist, int sign, unsigned flags */ - fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, nx, FFTW_BACKWARD, fftw_flags); - fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, nx, FFTW_FORWARD, fftw_flags); - fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, nx, FFTW_BACKWARD, fftw_flags); - fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, nx, FFTW_FORWARD, fftw_flags); - fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, FFTW_BACKWARD, fftw_flags); - fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, FFTW_FORWARD, fftw_flags); - fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, FFTW_BACKWARD, fftw_flags); - fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, FFTW_FORWARD, fftw_flags); + fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, + nx, FFTW_BACKWARD, fftw_flags); + fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up2, &nx, 1, + nx, FFTW_FORWARD, fftw_flags); + fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, + nx, FFTW_BACKWARD, fftw_flags); + fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, up1, &nx, 1, nx, up1, &nx, 1, + nx, FFTW_FORWARD, fftw_flags); + fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, + FFTW_BACKWARD, fftw_flags); + fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p2, &nx, 1, nx, + FFTW_FORWARD, fftw_flags); + fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, + FFTW_BACKWARD, fftw_flags); + fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft)(1, &nx, howmany, p1, &nx, 1, nx, p1, &nx, 1, nx, + FFTW_FORWARD, fftw_flags); for (i = 0; i < 2; i++) { @@ -188,12 +201,12 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, if (fft->plan[i][j][k] == nullptr) { gmx_fatal(FARGS, "Error initializing FFTW3 plan."); - FFTW_UNLOCK; + FFTW_UNLOCK gmx_fft_destroy(fft); - FFTW_LOCK; + FFTW_LOCK FFTWPREFIX(free)(p1); FFTWPREFIX(free)(p2); - FFTW_UNLOCK; + FFTW_UNLOCK return -1; } } @@ -207,29 +220,22 @@ gmx_fft_init_many_1d(gmx_fft_t * pfft, fft->ndim = 1; *pfft = fft; - FFTW_UNLOCK; + FFTW_UNLOCK return 0; } -int -gmx_fft_init_1d_real(gmx_fft_t * pfft, - int nx, - gmx_fft_flag flags) +int gmx_fft_init_1d_real(gmx_fft_t* pfft, int nx, gmx_fft_flag flags) { return gmx_fft_init_many_1d_real(pfft, nx, 1, flags); } -int -gmx_fft_init_many_1d_real(gmx_fft_t * pfft, - int nx, - int howmany, - gmx_fft_flag flags) +int gmx_fft_init_many_1d_real(gmx_fft_t* pfft, int nx, int howmany, gmx_fft_flag flags) { - gmx_fft_t fft; - real *p1, *p2, *up1, *up2; - char* pc; - int i, j, k; - int fftw_flags; + gmx_fft_t fft; + real * p1, *p2, *up1, *up2; + char* pc; + int i, j, k; + int fftw_flags; #if GMX_DISABLE_FFTW_MEASURE flags |= GMX_FFT_FLAG_CONSERVATIVE; @@ -244,28 +250,28 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, } *pfft = nullptr; - FFTW_LOCK; - if ( (fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) + FFTW_LOCK + if ((fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) { - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } /* allocate aligned, and extra memory to make it unaligned */ - p1 = static_cast(FFTWPREFIX(malloc)(sizeof(real)*(nx/2+1)*2*howmany + 8)); + p1 = static_cast(FFTWPREFIX(malloc)(sizeof(real) * (nx / 2 + 1) * 2 * howmany + 8)); if (p1 == nullptr) { FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } - p2 = static_cast(FFTWPREFIX(malloc)(sizeof(real)*(nx/2+1)*2*howmany + 8)); + p2 = static_cast(FFTWPREFIX(malloc)(sizeof(real) * (nx / 2 + 1) * 2 * howmany + 8)); if (p2 == nullptr) { FFTWPREFIX(free)(p1); FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } @@ -273,11 +279,11 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, * In double precision the actual complex datatype will be 16 bytes, * so go to a char pointer and force an offset of 8 bytes instead. */ - pc = reinterpret_cast(p1); + pc = reinterpret_cast(p1); pc += 8; up1 = reinterpret_cast(pc); - pc = reinterpret_cast(p2); + pc = reinterpret_cast(p2); pc += 8; up2 = reinterpret_cast(pc); @@ -287,15 +293,31 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, fftw_complex *out, const int *onembed, int ostride, int odist, unsigned flag */ - fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft_r2c)(1, &nx, howmany, up1, nullptr, 1, (nx/2+1) *2, reinterpret_cast(up2), nullptr, 1, (nx/2+1), fftw_flags); - fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft_r2c)(1, &nx, howmany, up1, nullptr, 1, (nx/2+1) *2, reinterpret_cast(up1), nullptr, 1, (nx/2+1), fftw_flags); - fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft_r2c)(1, &nx, howmany, p1, nullptr, 1, (nx/2+1) *2, reinterpret_cast(p2), nullptr, 1, (nx/2+1), fftw_flags); - fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft_r2c)(1, &nx, howmany, p1, nullptr, 1, (nx/2+1) *2, reinterpret_cast(p1), nullptr, 1, (nx/2+1), fftw_flags); - - fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft_c2r)(1, &nx, howmany, reinterpret_cast(up1), nullptr, 1, (nx/2+1), up2, nullptr, 1, (nx/2+1) *2, fftw_flags); - fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft_c2r)(1, &nx, howmany, reinterpret_cast(up1), nullptr, 1, (nx/2+1), up1, nullptr, 1, (nx/2+1) *2, fftw_flags); - fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft_c2r)(1, &nx, howmany, reinterpret_cast(p1), nullptr, 1, (nx/2+1), p2, nullptr, 1, (nx/2+1) *2, fftw_flags); - fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft_c2r)(1, &nx, howmany, reinterpret_cast(p1), nullptr, 1, (nx/2+1), p1, nullptr, 1, (nx/2+1) *2, fftw_flags); + fft->plan[0][0][1] = FFTWPREFIX(plan_many_dft_r2c)( + 1, &nx, howmany, up1, nullptr, 1, (nx / 2 + 1) * 2, + reinterpret_cast(up2), nullptr, 1, (nx / 2 + 1), fftw_flags); + fft->plan[0][1][1] = FFTWPREFIX(plan_many_dft_r2c)( + 1, &nx, howmany, up1, nullptr, 1, (nx / 2 + 1) * 2, + reinterpret_cast(up1), nullptr, 1, (nx / 2 + 1), fftw_flags); + fft->plan[1][0][1] = FFTWPREFIX(plan_many_dft_r2c)( + 1, &nx, howmany, p1, nullptr, 1, (nx / 2 + 1) * 2, + reinterpret_cast(p2), nullptr, 1, (nx / 2 + 1), fftw_flags); + fft->plan[1][1][1] = FFTWPREFIX(plan_many_dft_r2c)( + 1, &nx, howmany, p1, nullptr, 1, (nx / 2 + 1) * 2, + reinterpret_cast(p1), nullptr, 1, (nx / 2 + 1), fftw_flags); + + fft->plan[0][0][0] = FFTWPREFIX(plan_many_dft_c2r)( + 1, &nx, howmany, reinterpret_cast(up1), nullptr, 1, (nx / 2 + 1), + up2, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags); + fft->plan[0][1][0] = FFTWPREFIX(plan_many_dft_c2r)( + 1, &nx, howmany, reinterpret_cast(up1), nullptr, 1, (nx / 2 + 1), + up1, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags); + fft->plan[1][0][0] = FFTWPREFIX(plan_many_dft_c2r)( + 1, &nx, howmany, reinterpret_cast(p1), nullptr, 1, (nx / 2 + 1), + p2, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags); + fft->plan[1][1][0] = FFTWPREFIX(plan_many_dft_c2r)( + 1, &nx, howmany, reinterpret_cast(p1), nullptr, 1, (nx / 2 + 1), + p1, nullptr, 1, (nx / 2 + 1) * 2, fftw_flags); for (i = 0; i < 2; i++) { @@ -306,12 +328,12 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, if (fft->plan[i][j][k] == nullptr) { gmx_fatal(FARGS, "Error initializing FFTW3 plan."); - FFTW_UNLOCK; + FFTW_UNLOCK gmx_fft_destroy(fft); - FFTW_LOCK; + FFTW_LOCK FFTWPREFIX(free)(p1); FFTWPREFIX(free)(p2); - FFTW_UNLOCK; + FFTW_UNLOCK return -1; } } @@ -325,22 +347,18 @@ gmx_fft_init_many_1d_real(gmx_fft_t * pfft, fft->ndim = 1; *pfft = fft; - FFTW_UNLOCK; + FFTW_UNLOCK return 0; } -int -gmx_fft_init_2d_real(gmx_fft_t * pfft, - int nx, - int ny, - gmx_fft_flag flags) +int gmx_fft_init_2d_real(gmx_fft_t* pfft, int nx, int ny, gmx_fft_flag flags) { - gmx_fft_t fft; - real *p1, *p2, *up1, *up2; - char* pc; - int i, j, k; - int fftw_flags; + gmx_fft_t fft; + real * p1, *p2, *up1, *up2; + char* pc; + int i, j, k; + int fftw_flags; #if GMX_DISABLE_FFTW_MEASURE flags |= GMX_FFT_FLAG_CONSERVATIVE; @@ -355,28 +373,28 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, } *pfft = nullptr; - FFTW_LOCK; - if ( (fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) + FFTW_LOCK + if ((fft = static_cast(FFTWPREFIX(malloc)(sizeof(struct gmx_fft)))) == nullptr) { - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } /* allocate aligned, and extra memory to make it unaligned */ - p1 = static_cast(FFTWPREFIX(malloc)(sizeof(real) *( nx*(ny/2+1)*2 + 2) )); + p1 = static_cast(FFTWPREFIX(malloc)(sizeof(real) * (nx * (ny / 2 + 1) * 2 + 2))); if (p1 == nullptr) { FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } - p2 = static_cast(FFTWPREFIX(malloc)(sizeof(real) *( nx*(ny/2+1)*2 + 2) )); + p2 = static_cast(FFTWPREFIX(malloc)(sizeof(real) * (nx * (ny / 2 + 1) * 2 + 2))); if (p2 == nullptr) { FFTWPREFIX(free)(p1); FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK return ENOMEM; } @@ -384,24 +402,32 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, * In double precision the actual complex datatype will be 16 bytes, * so go to a char pointer and force an offset of 8 bytes instead. */ - pc = reinterpret_cast(p1); + pc = reinterpret_cast(p1); pc += 8; up1 = reinterpret_cast(pc); - pc = reinterpret_cast(p2); + pc = reinterpret_cast(p2); pc += 8; up2 = reinterpret_cast(pc); - fft->plan[0][0][0] = FFTWPREFIX(plan_dft_c2r_2d)(nx, ny, reinterpret_cast(up1), up2, fftw_flags); - fft->plan[0][0][1] = FFTWPREFIX(plan_dft_r2c_2d)(nx, ny, up1, reinterpret_cast(up2), fftw_flags); - fft->plan[0][1][0] = FFTWPREFIX(plan_dft_c2r_2d)(nx, ny, reinterpret_cast(up1), up1, fftw_flags); - fft->plan[0][1][1] = FFTWPREFIX(plan_dft_r2c_2d)(nx, ny, up1, reinterpret_cast(up1), fftw_flags); + fft->plan[0][0][0] = FFTWPREFIX(plan_dft_c2r_2d)( + nx, ny, reinterpret_cast(up1), up2, fftw_flags); + fft->plan[0][0][1] = FFTWPREFIX(plan_dft_r2c_2d)( + nx, ny, up1, reinterpret_cast(up2), fftw_flags); + fft->plan[0][1][0] = FFTWPREFIX(plan_dft_c2r_2d)( + nx, ny, reinterpret_cast(up1), up1, fftw_flags); + fft->plan[0][1][1] = FFTWPREFIX(plan_dft_r2c_2d)( + nx, ny, up1, reinterpret_cast(up1), fftw_flags); - fft->plan[1][0][0] = FFTWPREFIX(plan_dft_c2r_2d)(nx, ny, reinterpret_cast(p1), p2, fftw_flags); - fft->plan[1][0][1] = FFTWPREFIX(plan_dft_r2c_2d)(nx, ny, p1, reinterpret_cast(p2), fftw_flags); - fft->plan[1][1][0] = FFTWPREFIX(plan_dft_c2r_2d)(nx, ny, reinterpret_cast(p1), p1, fftw_flags); - fft->plan[1][1][1] = FFTWPREFIX(plan_dft_r2c_2d)(nx, ny, p1, reinterpret_cast(p1), fftw_flags); + fft->plan[1][0][0] = FFTWPREFIX(plan_dft_c2r_2d)( + nx, ny, reinterpret_cast(p1), p2, fftw_flags); + fft->plan[1][0][1] = FFTWPREFIX(plan_dft_r2c_2d)( + nx, ny, p1, reinterpret_cast(p2), fftw_flags); + fft->plan[1][1][0] = FFTWPREFIX(plan_dft_c2r_2d)( + nx, ny, reinterpret_cast(p1), p1, fftw_flags); + fft->plan[1][1][1] = FFTWPREFIX(plan_dft_r2c_2d)( + nx, ny, p1, reinterpret_cast(p1), fftw_flags); for (i = 0; i < 2; i++) @@ -413,12 +439,12 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, if (fft->plan[i][j][k] == nullptr) { gmx_fatal(FARGS, "Error initializing FFTW3 plan."); - FFTW_UNLOCK; + FFTW_UNLOCK gmx_fft_destroy(fft); - FFTW_LOCK; + FFTW_LOCK FFTWPREFIX(free)(p1); FFTWPREFIX(free)(p2); - FFTW_UNLOCK; + FFTW_UNLOCK return -1; } } @@ -432,57 +458,45 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, fft->ndim = 2; *pfft = fft; - FFTW_UNLOCK; + FFTW_UNLOCK return 0; } -int -gmx_fft_1d (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); - bool inplace = (in_data == out_data); - bool isforward = (dir == GMX_FFT_FORWARD); + bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); + bool inplace = (in_data == out_data); + bool isforward = (dir == GMX_FFT_FORWARD); /* Some checks */ - if ( (fft->real_transform == 1) || (fft->ndim != 1) || - ((dir != GMX_FFT_FORWARD) && (dir != GMX_FFT_BACKWARD)) ) + if ((fft->real_transform == 1) || (fft->ndim != 1) + || ((dir != GMX_FFT_FORWARD) && (dir != GMX_FFT_BACKWARD))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; } - FFTWPREFIX(execute_dft)(fft->plan[aligned][inplace][isforward], - static_cast(in_data), - static_cast(out_data)); + FFTWPREFIX(execute_dft) + (fft->plan[aligned][inplace][isforward], static_cast(in_data), + static_cast(out_data)); return 0; } -int -gmx_fft_many_1d (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_many_1d(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { return gmx_fft_1d(fft, dir, in_data, out_data); } -int -gmx_fft_1d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); - bool inplace = (in_data == out_data); - bool isforward = (dir == GMX_FFT_REAL_TO_COMPLEX); + bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); + bool inplace = (in_data == out_data); + bool isforward = (dir == GMX_FFT_REAL_TO_COMPLEX); /* Some checks */ - if ( (fft->real_transform != 1) || (fft->ndim != 1) || - ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL)) ) + if ((fft->real_transform != 1) || (fft->ndim != 1) + || ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; @@ -490,40 +504,34 @@ gmx_fft_1d_real (gmx_fft_t fft, if (isforward) { - FFTWPREFIX(execute_dft_r2c)(fft->plan[aligned][inplace][isforward], - static_cast(in_data), static_cast(out_data)); + FFTWPREFIX(execute_dft_r2c) + (fft->plan[aligned][inplace][isforward], static_cast(in_data), + static_cast(out_data)); } else { - FFTWPREFIX(execute_dft_c2r)(fft->plan[aligned][inplace][isforward], - static_cast(in_data), static_cast(out_data)); + FFTWPREFIX(execute_dft_c2r) + (fft->plan[aligned][inplace][isforward], static_cast(in_data), + static_cast(out_data)); } return 0; } -int -gmx_fft_many_1d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_many_1d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { return gmx_fft_1d_real(fft, dir, in_data, out_data); } -int -gmx_fft_2d_real (gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_2d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { - bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); - bool inplace = (in_data == out_data); - bool isforward = (dir == GMX_FFT_REAL_TO_COMPLEX); + bool aligned = (((size_t(in_data) | size_t(out_data)) & 0xf) == 0); + bool inplace = (in_data == out_data); + bool isforward = (dir == GMX_FFT_REAL_TO_COMPLEX); /* Some checks */ - if ( (fft->real_transform != 1) || (fft->ndim != 2) || - ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL)) ) + if ((fft->real_transform != 1) || (fft->ndim != 2) + || ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; @@ -531,25 +539,24 @@ gmx_fft_2d_real (gmx_fft_t fft, if (isforward) { - FFTWPREFIX(execute_dft_r2c)(fft->plan[aligned][inplace][isforward], - static_cast(in_data), - static_cast(out_data)); + FFTWPREFIX(execute_dft_r2c) + (fft->plan[aligned][inplace][isforward], static_cast(in_data), + static_cast(out_data)); } else { - FFTWPREFIX(execute_dft_c2r)(fft->plan[aligned][inplace][isforward], - static_cast(in_data), - static_cast(out_data)); + FFTWPREFIX(execute_dft_c2r) + (fft->plan[aligned][inplace][isforward], static_cast(in_data), + static_cast(out_data)); } return 0; } -void -gmx_fft_destroy(gmx_fft_t fft) +void gmx_fft_destroy(gmx_fft_t fft) { - int i, j, k; + int i, j, k; if (fft != nullptr) { @@ -561,23 +568,21 @@ gmx_fft_destroy(gmx_fft_t fft) { if (fft->plan[i][j][k] != nullptr) { - FFTW_LOCK; + FFTW_LOCK FFTWPREFIX(destroy_plan)(fft->plan[i][j][k]); - FFTW_UNLOCK; + FFTW_UNLOCK fft->plan[i][j][k] = nullptr; } } } } - FFTW_LOCK; + FFTW_LOCK FFTWPREFIX(free)(fft); - FFTW_UNLOCK; + FFTW_UNLOCK } - } -void -gmx_many_fft_destroy(gmx_fft_t fft) +void gmx_many_fft_destroy(gmx_fft_t fft) { gmx_fft_destroy(fft); } diff --git a/src/gromacs/fft/fft_mkl.cpp b/src/gromacs/fft/fft_mkl.cpp index a120ee5d00..abf1ae038f 100644 --- a/src/gromacs/fft/fft_mkl.cpp +++ b/src/gromacs/fft/fft_mkl.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2003 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,14 +47,14 @@ /* For MKL version (<10.0), we should define MKL_LONG. */ #ifndef MKL_LONG -#define MKL_LONG long int +# define MKL_LONG long int #endif #if GMX_DOUBLE -#define GMX_DFTI_PREC DFTI_DOUBLE +# define GMX_DFTI_PREC DFTI_DOUBLE #else -#define GMX_DFTI_PREC DFTI_SINGLE +# define GMX_DFTI_PREC DFTI_SINGLE #endif /*! \internal @@ -98,26 +98,22 @@ struct gmx_fft_mkl struct gmx_fft #endif { - int ndim; /**< Number of dimensions in FFT */ - int nx; /**< Length of X transform */ - int ny; /**< Length of Y transform */ - int nz; /**< Length of Z transform */ - int real_fft; /**< 1 if real FFT, otherwise 0 */ - DFTI_DESCRIPTOR * inplace[3]; /**< in-place FFT */ - DFTI_DESCRIPTOR * ooplace[4]; /**< out-of-place FFT */ - t_complex * work; /**< Enable out-of-place c2r FFT */ + int ndim; /**< Number of dimensions in FFT */ + int nx; /**< Length of X transform */ + int ny; /**< Length of Y transform */ + int nz; /**< Length of Z transform */ + int real_fft; /**< 1 if real FFT, otherwise 0 */ + DFTI_DESCRIPTOR* inplace[3]; /**< in-place FFT */ + DFTI_DESCRIPTOR* ooplace[4]; /**< out-of-place FFT */ + t_complex* work; /**< Enable out-of-place c2r FFT */ }; - -int -gmx_fft_init_1d(gmx_fft_t * pfft, - int nx, - gmx_fft_flag gmx_unused flags) +int gmx_fft_init_1d(gmx_fft_t* pfft, int nx, gmx_fft_flag gmx_unused flags) { - gmx_fft_t fft; - int d; - int status; + gmx_fft_t fft; + int d; + int status; if (pfft == NULL) { @@ -126,7 +122,7 @@ gmx_fft_init_1d(gmx_fft_t * pfft, } *pfft = NULL; - if ( (fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) + if ((fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) { return ENOMEM; } @@ -185,15 +181,11 @@ gmx_fft_init_1d(gmx_fft_t * pfft, } - -int -gmx_fft_init_1d_real(gmx_fft_t * pfft, - int nx, - gmx_fft_flag gmx_unused flags) +int gmx_fft_init_1d_real(gmx_fft_t* pfft, int nx, gmx_fft_flag gmx_unused flags) { - gmx_fft_t fft; - int d; - int status; + gmx_fft_t fft; + int d; + int status; if (pfft == NULL) { @@ -202,7 +194,7 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, } *pfft = NULL; - if ( (fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) + if ((fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) { return ENOMEM; } @@ -245,8 +237,7 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, if (status == DFTI_UNIMPLEMENTED) { - gmx_fatal(FARGS, - "The linked Intel MKL version (<6.0?) cannot do real FFTs."); + gmx_fatal(FARGS, "The linked Intel MKL version (<6.0?) cannot do real FFTs."); gmx_fft_destroy(fft); return status; } @@ -269,18 +260,13 @@ gmx_fft_init_1d_real(gmx_fft_t * pfft, } - -int -gmx_fft_init_2d_real(gmx_fft_t * pfft, - int nx, - int ny, - gmx_fft_flag gmx_unused flags) +int gmx_fft_init_2d_real(gmx_fft_t* pfft, int nx, int ny, gmx_fft_flag gmx_unused flags) { - gmx_fft_t fft; - int d; - int status; - MKL_LONG stride[2]; - MKL_LONG nyc; + gmx_fft_t fft; + int d; + int status; + MKL_LONG stride[2]; + MKL_LONG nyc; if (pfft == NULL) { @@ -289,12 +275,12 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, } *pfft = NULL; - if ( (fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) + if ((fft = (gmx_fft_t)malloc(sizeof(struct gmx_fft))) == NULL) { return ENOMEM; } - nyc = (ny/2 + 1); + nyc = (ny / 2 + 1); /* Mark all handles invalid */ for (d = 0; d < 3; d++) @@ -313,16 +299,15 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, if (status == 0) { - stride[0] = 0; - stride[1] = nyc; + stride[0] = 0; + stride[1] = nyc; - status = - (DftiSetValue(fft->inplace[0], DFTI_PLACEMENT, DFTI_INPLACE) || - DftiSetValue(fft->inplace[0], DFTI_NUMBER_OF_TRANSFORMS, nyc) || - DftiSetValue(fft->inplace[0], DFTI_INPUT_DISTANCE, 1) || - DftiSetValue(fft->inplace[0], DFTI_INPUT_STRIDES, stride) || - DftiSetValue(fft->inplace[0], DFTI_OUTPUT_DISTANCE, 1) || - DftiSetValue(fft->inplace[0], DFTI_OUTPUT_STRIDES, stride)); + status = (DftiSetValue(fft->inplace[0], DFTI_PLACEMENT, DFTI_INPLACE) + || DftiSetValue(fft->inplace[0], DFTI_NUMBER_OF_TRANSFORMS, nyc) + || DftiSetValue(fft->inplace[0], DFTI_INPUT_DISTANCE, 1) + || DftiSetValue(fft->inplace[0], DFTI_INPUT_STRIDES, stride) + || DftiSetValue(fft->inplace[0], DFTI_OUTPUT_DISTANCE, 1) + || DftiSetValue(fft->inplace[0], DFTI_OUTPUT_STRIDES, stride)); } if (status == 0) @@ -341,13 +326,12 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, stride[0] = 0; stride[1] = nyc; - status = - (DftiSetValue(fft->ooplace[0], DFTI_PLACEMENT, DFTI_NOT_INPLACE) || - DftiSetValue(fft->ooplace[0], DFTI_NUMBER_OF_TRANSFORMS, nyc) || - DftiSetValue(fft->ooplace[0], DFTI_INPUT_DISTANCE, 1) || - DftiSetValue(fft->ooplace[0], DFTI_INPUT_STRIDES, stride) || - DftiSetValue(fft->ooplace[0], DFTI_OUTPUT_DISTANCE, 1) || - DftiSetValue(fft->ooplace[0], DFTI_OUTPUT_STRIDES, stride)); + status = (DftiSetValue(fft->ooplace[0], DFTI_PLACEMENT, DFTI_NOT_INPLACE) + || DftiSetValue(fft->ooplace[0], DFTI_NUMBER_OF_TRANSFORMS, nyc) + || DftiSetValue(fft->ooplace[0], DFTI_INPUT_DISTANCE, 1) + || DftiSetValue(fft->ooplace[0], DFTI_INPUT_STRIDES, stride) + || DftiSetValue(fft->ooplace[0], DFTI_OUTPUT_DISTANCE, 1) + || DftiSetValue(fft->ooplace[0], DFTI_OUTPUT_STRIDES, stride)); } if (status == 0) @@ -367,14 +351,13 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, stride[0] = 0; stride[1] = 1; - status = - (DftiSetValue(fft->inplace[1], DFTI_PLACEMENT, DFTI_INPLACE) || - DftiSetValue(fft->inplace[1], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) || - DftiSetValue(fft->inplace[1], DFTI_INPUT_DISTANCE, 2*nyc) || - DftiSetValue(fft->inplace[1], DFTI_INPUT_STRIDES, stride) || - DftiSetValue(fft->inplace[1], DFTI_OUTPUT_DISTANCE, 2*nyc) || - DftiSetValue(fft->inplace[1], DFTI_OUTPUT_STRIDES, stride) || - DftiCommitDescriptor(fft->inplace[1])); + status = (DftiSetValue(fft->inplace[1], DFTI_PLACEMENT, DFTI_INPLACE) + || DftiSetValue(fft->inplace[1], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) + || DftiSetValue(fft->inplace[1], DFTI_INPUT_DISTANCE, 2 * nyc) + || DftiSetValue(fft->inplace[1], DFTI_INPUT_STRIDES, stride) + || DftiSetValue(fft->inplace[1], DFTI_OUTPUT_DISTANCE, 2 * nyc) + || DftiSetValue(fft->inplace[1], DFTI_OUTPUT_STRIDES, stride) + || DftiCommitDescriptor(fft->inplace[1])); } @@ -389,14 +372,13 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, stride[0] = 0; stride[1] = 1; - status = - (DftiSetValue(fft->ooplace[1], DFTI_PLACEMENT, DFTI_NOT_INPLACE) || - DftiSetValue(fft->ooplace[1], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) || - DftiSetValue(fft->ooplace[1], DFTI_INPUT_DISTANCE, (MKL_LONG)ny) || - DftiSetValue(fft->ooplace[1], DFTI_INPUT_STRIDES, stride) || - DftiSetValue(fft->ooplace[1], DFTI_OUTPUT_DISTANCE, 2*nyc) || - DftiSetValue(fft->ooplace[1], DFTI_OUTPUT_STRIDES, stride) || - DftiCommitDescriptor(fft->ooplace[1])); + status = (DftiSetValue(fft->ooplace[1], DFTI_PLACEMENT, DFTI_NOT_INPLACE) + || DftiSetValue(fft->ooplace[1], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) + || DftiSetValue(fft->ooplace[1], DFTI_INPUT_DISTANCE, (MKL_LONG)ny) + || DftiSetValue(fft->ooplace[1], DFTI_INPUT_STRIDES, stride) + || DftiSetValue(fft->ooplace[1], DFTI_OUTPUT_DISTANCE, 2 * nyc) + || DftiSetValue(fft->ooplace[1], DFTI_OUTPUT_STRIDES, stride) + || DftiCommitDescriptor(fft->ooplace[1])); } @@ -411,25 +393,24 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, stride[0] = 0; stride[1] = 1; - status = - (DftiSetValue(fft->ooplace[2], DFTI_PLACEMENT, DFTI_NOT_INPLACE) || - DftiSetValue(fft->ooplace[2], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) || - DftiSetValue(fft->ooplace[2], DFTI_INPUT_DISTANCE, 2*nyc) || - DftiSetValue(fft->ooplace[2], DFTI_INPUT_STRIDES, stride) || - DftiSetValue(fft->ooplace[2], DFTI_OUTPUT_DISTANCE, (MKL_LONG)ny) || - DftiSetValue(fft->ooplace[2], DFTI_OUTPUT_STRIDES, stride) || - DftiCommitDescriptor(fft->ooplace[2])); + status = (DftiSetValue(fft->ooplace[2], DFTI_PLACEMENT, DFTI_NOT_INPLACE) + || DftiSetValue(fft->ooplace[2], DFTI_NUMBER_OF_TRANSFORMS, (MKL_LONG)nx) + || DftiSetValue(fft->ooplace[2], DFTI_INPUT_DISTANCE, 2 * nyc) + || DftiSetValue(fft->ooplace[2], DFTI_INPUT_STRIDES, stride) + || DftiSetValue(fft->ooplace[2], DFTI_OUTPUT_DISTANCE, (MKL_LONG)ny) + || DftiSetValue(fft->ooplace[2], DFTI_OUTPUT_STRIDES, stride) + || DftiCommitDescriptor(fft->ooplace[2])); } if (status == 0) { - void *memory = malloc(sizeof(t_complex)*(nx*(ny/2+1))); + void* memory = malloc(sizeof(t_complex) * (nx * (ny / 2 + 1))); if (nullptr == memory) { status = ENOMEM; } - fft->work = static_cast(memory); + fft->work = static_cast(memory); } if (status != 0) @@ -448,17 +429,12 @@ gmx_fft_init_2d_real(gmx_fft_t * pfft, return 0; } -int -gmx_fft_1d(gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { int inplace = (in_data == out_data); int status = 0; - if ( (fft->real_fft == 1) || (fft->ndim != 1) || - ((dir != GMX_FFT_FORWARD) && (dir != GMX_FFT_BACKWARD)) ) + if ((fft->real_fft == 1) || (fft->ndim != 1) || ((dir != GMX_FFT_FORWARD) && (dir != GMX_FFT_BACKWARD))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; @@ -497,18 +473,13 @@ gmx_fft_1d(gmx_fft_t fft, } - -int -gmx_fft_1d_real(gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_1d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { int inplace = (in_data == out_data); int status = 0; - if ( (fft->real_fft != 1) || (fft->ndim != 1) || - ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL)) ) + if ((fft->real_fft != 1) || (fft->ndim != 1) + || ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; @@ -547,17 +518,13 @@ gmx_fft_1d_real(gmx_fft_t fft, } -int -gmx_fft_2d_real(gmx_fft_t fft, - enum gmx_fft_direction dir, - void * in_data, - void * out_data) +int gmx_fft_2d_real(gmx_fft_t fft, enum gmx_fft_direction dir, void* in_data, void* out_data) { int inplace = (in_data == out_data); int status = 0; - if ( (fft->real_fft != 1) || (fft->ndim != 2) || - ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL)) ) + if ((fft->real_fft != 1) || (fft->ndim != 2) + || ((dir != GMX_FFT_REAL_TO_COMPLEX) && (dir != GMX_FFT_COMPLEX_TO_REAL))) { gmx_fatal(FARGS, "FFT plan mismatch - bad plan or direction."); return EINVAL; @@ -603,8 +570,7 @@ gmx_fft_2d_real(gmx_fft_t fft, return status; } -void -gmx_fft_destroy(gmx_fft_t fft) +void gmx_fft_destroy(gmx_fft_t fft) { int d; diff --git a/src/gromacs/fft/parallel_3dfft.cpp b/src/gromacs/fft/parallel_3dfft.cpp index e05e7bf18d..8b842fe5ac 100644 --- a/src/gromacs/fft/parallel_3dfft.cpp +++ b/src/gromacs/fft/parallel_3dfft.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2005 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2013,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,25 +48,25 @@ #include "gromacs/utility/gmxmpi.h" #include "gromacs/utility/smalloc.h" -struct gmx_parallel_3dfft { +struct gmx_parallel_3dfft +{ fft5d_plan p1, p2; }; -int -gmx_parallel_3dfft_init (gmx_parallel_3dfft_t * pfft_setup, - const ivec ndata, - real ** real_data, - t_complex ** complex_data, - MPI_Comm comm[2], - gmx_bool bReproducible, - int nthreads, - gmx::PinningPolicy realGridAllocation) +int gmx_parallel_3dfft_init(gmx_parallel_3dfft_t* pfft_setup, + const ivec ndata, + real** real_data, + t_complex** complex_data, + MPI_Comm comm[2], + gmx_bool bReproducible, + int nthreads, + gmx::PinningPolicy realGridAllocation) { - int rN = ndata[2], M = ndata[1], K = ndata[0]; + int rN = ndata[2], M = ndata[1], K = ndata[0]; int flags = FFT5D_REALCOMPLEX | FFT5D_ORDER_YZ; /* FFT5D_DEBUG */ - MPI_Comm rcomm[] = {comm[1], comm[0]}; - int Nb, Mb, Kb; /* dimension for backtransform (in starting order) */ - t_complex *buf1, *buf2; /*intermediate buffers - used internally.*/ + MPI_Comm rcomm[] = { comm[1], comm[0] }; + int Nb, Mb, Kb; /* dimension for backtransform (in starting order) */ + t_complex *buf1, *buf2; /*intermediate buffers - used internally.*/ snew(*pfft_setup, 1); if (bReproducible) @@ -74,42 +74,44 @@ gmx_parallel_3dfft_init (gmx_parallel_3dfft_t * pfft_setup, flags |= FFT5D_NOMEASURE; } - if (!(flags&FFT5D_ORDER_YZ)) + if (!(flags & FFT5D_ORDER_YZ)) { - Nb = M; Mb = K; Kb = rN; + Nb = M; + Mb = K; + Kb = rN; } else { - Nb = K; Mb = rN; Kb = M; /* currently always true because ORDER_YZ always set */ + Nb = K; + Mb = rN; + Kb = M; /* currently always true because ORDER_YZ always set */ } - (*pfft_setup)->p1 = fft5d_plan_3d(rN, M, K, rcomm, flags, reinterpret_cast(real_data), complex_data, &buf1, &buf2, nthreads, realGridAllocation); + (*pfft_setup)->p1 = fft5d_plan_3d(rN, M, K, rcomm, flags, reinterpret_cast(real_data), + complex_data, &buf1, &buf2, nthreads, realGridAllocation); - (*pfft_setup)->p2 = fft5d_plan_3d(Nb, Mb, Kb, rcomm, - (flags|FFT5D_BACKWARD|FFT5D_NOMALLOC)^FFT5D_ORDER_YZ, complex_data, reinterpret_cast(real_data), &buf1, &buf2, nthreads); + (*pfft_setup)->p2 = fft5d_plan_3d( + Nb, Mb, Kb, rcomm, (flags | FFT5D_BACKWARD | FFT5D_NOMALLOC) ^ FFT5D_ORDER_YZ, + complex_data, reinterpret_cast(real_data), &buf1, &buf2, nthreads); return static_cast((*pfft_setup)->p1 != nullptr && (*pfft_setup)->p2 != nullptr); } -static int -fft5d_limits(fft5d_plan p, - ivec local_ndata, - ivec local_offset, - ivec local_size) +static int fft5d_limits(fft5d_plan p, ivec local_ndata, ivec local_offset, ivec local_size) { local_offset[2] = 0; - local_offset[1] = p->oM[0]; /*=p->coor[0]*p->MG/p->P[0]; */ - local_offset[0] = p->oK[0]; /*=p->coor[1]*p->KG/p->P[1]; */ + local_offset[1] = p->oM[0]; /*=p->coor[0]*p->MG/p->P[0]; */ + local_offset[0] = p->oK[0]; /*=p->coor[1]*p->KG/p->P[1]; */ local_ndata[2] = p->rC[0]; local_ndata[1] = p->pM[0]; local_ndata[0] = p->pK[0]; - if ((!(p->flags&FFT5D_BACKWARD)) && (p->flags&FFT5D_REALCOMPLEX)) + if ((!(p->flags & FFT5D_BACKWARD)) && (p->flags & FFT5D_REALCOMPLEX)) { - //C is length in multiples of complex local_size in multiples of real - local_size[2] = p->C[0]*2; + // C is length in multiples of complex local_size in multiples of real + local_size[2] = p->C[0] * 2; } else { @@ -120,11 +122,7 @@ fft5d_limits(fft5d_plan p, return 0; } -int -gmx_parallel_3dfft_real_limits(gmx_parallel_3dfft_t pfft_setup, - ivec local_ndata, - ivec local_offset, - ivec local_size) +int gmx_parallel_3dfft_real_limits(gmx_parallel_3dfft_t pfft_setup, ivec local_ndata, ivec local_offset, ivec local_size) { return fft5d_limits(pfft_setup->p1, local_ndata, local_offset, local_size); } @@ -139,12 +137,11 @@ static void reorder_ivec_yzx(ivec v) v[YY] = tmp; } -int -gmx_parallel_3dfft_complex_limits(gmx_parallel_3dfft_t pfft_setup, - ivec complex_order, - ivec local_ndata, - ivec local_offset, - ivec local_size) +int gmx_parallel_3dfft_complex_limits(gmx_parallel_3dfft_t pfft_setup, + ivec complex_order, + ivec local_ndata, + ivec local_offset, + ivec local_size) { int ret; @@ -163,15 +160,16 @@ gmx_parallel_3dfft_complex_limits(gmx_parallel_3dfft_t pfft_setup, } -int -gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, - enum gmx_fft_direction dir, - int thread, - gmx_wallcycle_t wcycle) +int gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, + enum gmx_fft_direction dir, + int thread, + gmx_wallcycle_t wcycle) { - if (((pfft_setup->p1->flags&FFT5D_REALCOMPLEX) == 0) ^ (dir == GMX_FFT_FORWARD || dir == GMX_FFT_BACKWARD)) + if (((pfft_setup->p1->flags & FFT5D_REALCOMPLEX) == 0) + ^ (dir == GMX_FFT_FORWARD || dir == GMX_FFT_BACKWARD)) { - gmx_fatal(FARGS, "Invalid transform. Plan and execution don't match regarding reel/complex"); + gmx_fatal(FARGS, + "Invalid transform. Plan and execution don't match regarding reel/complex"); } if (dir == GMX_FFT_FORWARD || dir == GMX_FFT_REAL_TO_COMPLEX) { @@ -184,8 +182,7 @@ gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, return 0; } -int -gmx_parallel_3dfft_destroy(gmx_parallel_3dfft_t pfft_setup) +int gmx_parallel_3dfft_destroy(gmx_parallel_3dfft_t pfft_setup) { if (pfft_setup) { diff --git a/src/gromacs/fft/parallel_3dfft.h b/src/gromacs/fft/parallel_3dfft.h index b0a8948e83..91cd66103f 100644 --- a/src/gromacs/fft/parallel_3dfft.h +++ b/src/gromacs/fft/parallel_3dfft.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2005 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2013,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,9 +45,7 @@ #include "gromacs/utility/gmxmpi.h" #include "gromacs/utility/real.h" -typedef struct gmx_parallel_3dfft * - gmx_parallel_3dfft_t; - +typedef struct gmx_parallel_3dfft* gmx_parallel_3dfft_t; /*! \brief Initialize parallel MPI-based 3D-FFT. @@ -76,44 +74,37 @@ typedef struct gmx_parallel_3dfft * * * \return 0 or a standard error code. */ -int - gmx_parallel_3dfft_init (gmx_parallel_3dfft_t * pfft_setup, - const ivec ndata, - real **real_data, - t_complex **complex_data, - MPI_Comm comm[2], - gmx_bool bReproducible, - int nthreads, - gmx::PinningPolicy realGridAllocation = gmx::PinningPolicy::CannotBePinned); - - - +int gmx_parallel_3dfft_init(gmx_parallel_3dfft_t* pfft_setup, + const ivec ndata, + real** real_data, + t_complex** complex_data, + MPI_Comm comm[2], + gmx_bool bReproducible, + int nthreads, + gmx::PinningPolicy realGridAllocation = gmx::PinningPolicy::CannotBePinned); /*! \brief Get direct space grid index limits */ -int -gmx_parallel_3dfft_real_limits(gmx_parallel_3dfft_t pfft_setup, - ivec local_ndata, - ivec local_offset, - ivec local_size); +int gmx_parallel_3dfft_real_limits(gmx_parallel_3dfft_t pfft_setup, + ivec local_ndata, + ivec local_offset, + ivec local_size); /*! \brief Get reciprocal space grid index limits */ -int -gmx_parallel_3dfft_complex_limits(gmx_parallel_3dfft_t pfft_setup, - ivec complex_order, - ivec local_ndata, - ivec local_offset, - ivec local_size); +int gmx_parallel_3dfft_complex_limits(gmx_parallel_3dfft_t pfft_setup, + ivec complex_order, + ivec local_ndata, + ivec local_offset, + ivec local_size); -int -gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, - enum gmx_fft_direction dir, - int thread, - gmx_wallcycle_t wcycle); +int gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, + enum gmx_fft_direction dir, + int thread, + gmx_wallcycle_t wcycle); /*! \brief Release all data in parallel fft setup @@ -125,7 +116,6 @@ gmx_parallel_3dfft_execute(gmx_parallel_3dfft_t pfft_setup, * * \return 0 or a standard error code. */ -int -gmx_parallel_3dfft_destroy(gmx_parallel_3dfft_t pfft_setup); +int gmx_parallel_3dfft_destroy(gmx_parallel_3dfft_t pfft_setup); #endif diff --git a/src/gromacs/fft/tests/fft.cpp b/src/gromacs/fft/tests/fft.cpp index ac55d38452..4fb26f2532 100644 --- a/src/gromacs/fft/tests/fft.cpp +++ b/src/gromacs/fft/tests/fft.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,151 +68,151 @@ namespace * initializers, and we would not have to do so much useless copying * during the unit tests below. */ -const double inputdata[] = { //print ",\n".join([",".join(["%4s"%(random.randint(-99,99)/10.,) for i in range(25)]) for j in range(20)]) - -3.5, 6.3, 1.2, 0.3, 1.1, -5.7, 5.8, -1.9, -6.3, -1.4, 7.4, 2.4, -9.9, -7.2, 5.4, 6.1, -1.9, -7.6, 1.4, -3.5, 0.7, 5.6, -4.2, -1.1, -4.4, - -6.3, -7.2, 4.6, -3.0, -0.9, 7.2, 2.5, -3.6, 6.1, -3.2, -2.1, 6.5, -0.4, -9.0, 2.3, 8.4, 4.0, -5.2, -9.0, 4.7, -3.7, -2.0, -9.5, -3.9, -3.6, - 7.1, 0.8, -0.6, 5.2, -9.3, -4.5, 5.9, 2.2, -5.8, 5.0, 1.2, -0.1, 2.2, 0.2, -7.7, 1.9, -8.4, 4.4, 2.3, -2.9, 6.7, 2.7, 5.8, -3.6, 8.9, - 8.9, 4.3, 9.1, 9.3, -8.7, 4.1, 9.6, -6.2, 6.6, -9.3, 8.2, 4.5, 6.2, 9.4, -8.0, -6.8, -3.3, 7.2, 1.7, 0.6, -4.9, 9.8, 1.3, 3.2, -0.2, - 9.9, 4.4, -9.9, -7.2, 4.4, 4.7, 7.2, -0.3, 0.3, -2.1, 8.4, -2.1, -6.1, 4.1, -5.9, -2.2, -3.8, 5.2, -8.2, -7.8, -8.8, 6.7, -9.5, -4.2, 0.8, - 8.3, 5.2, -9.0, 8.7, 9.8, -9.9, -7.8, -8.3, 9.0, -2.8, -9.2, -9.6, 8.4, 2.5, 6.0, -0.4, 1.3, -0.5, 9.1, -9.5, -0.8, 1.9, -6.2, 4.3, -3.8, - 8.6, -1.9, -2.1, -0.4, -7.1, -3.7, 9.1, -6.4, -0.6, 2.5, 8.0, -5.2, -9.8, -4.3, 4.5, 1.7, 9.3, 9.2, 1.0, 5.3, -4.5, 6.4, -6.6, 3.1, -6.8, - 2.1, 2.0, 7.3, 8.6, 5.0, 5.2, 0.4, -7.1, 4.5, -9.2, -9.1, 0.2, -6.3, -1.1, -9.6, 7.4, -3.7, -5.5, 2.6, -3.5, -0.7, 9.0, 9.8, -8.0, 3.6, - 3.0, -2.2, -2.8, 0.8, 9.0, 2.8, 7.7, -0.7, -5.0, -1.8, -2.3, -0.4, -6.2, -9.1, -9.2, 0.5, 5.7, -3.9, 2.1, 0.6, 0.4, 9.1, 7.4, 7.1, -2.5, - 7.3, 7.8, -4.3, 6.3, -0.8, -3.8, -1.5, 6.6, 2.3, 3.9, -4.6, 5.8, -7.4, 5.9, 2.8, 4.7, 3.9, -5.4, 9.1, -1.6, -1.9, -4.2, -2.6, 0.6, -5.1, - 1.8, 5.2, 4.0, -6.2, 6.5, -9.1, 0.5, 2.1, 7.1, -8.6, 7.6, -9.7, -4.6, -5.7, 6.1, -1.8, -7.3, 9.4, 8.0, -2.6, -1.8, 5.7, 9.3, -7.9, 7.4, - 6.3, 2.0, 9.6, -4.5, -6.2, 6.1, 2.3, 0.8, 5.9, -2.8, -3.5, -1.5, 6.0, -4.9, 3.5, 7.7, -4.2, -9.7, 2.4, 8.1, 5.9, 3.4, -7.5, 7.5, 2.6, - 4.7, 2.7, 2.2, 2.6, 6.2, 7.5, 0.2, -6.4, -2.8, -0.5, -0.3, 0.4, 1.2, 3.5, -4.0, -0.5, 9.3, -7.2, 8.5, -5.5, -1.7, -5.3, 0.3, 3.9, -3.6, - -3.6, 4.7, -8.1, 1.4, 4.0, 1.3, -4.3, -8.8, -7.3, 6.3, -7.5, -9.0, 9.1, 4.5, -1.9, 1.9, 9.9, -1.7, -9.1, -5.1, 8.5, -9.3, 2.1, -5.8, -3.6, - -0.8, -0.9, -3.3, -2.7, 7.0, -7.2, -5.0, 7.4, -1.4, 0.0, -4.5, -9.7, 0.7, -1.0, -9.1, -5.3, 4.3, 3.4, -6.6, 9.8, -1.1, 8.9, 5.0, 2.9, 0.2, - -2.9, 0.8, 6.7, -0.6, 0.6, 4.1, 5.3, -1.7, -0.3, 4.2, 3.7, -8.3, 4.0, 1.3, 6.3, 0.2, 1.3, -1.1, -3.5, 2.8, -7.7, 6.2, -4.9, -9.9, 9.6, - 3.0, -9.2, -8.0, -3.9, 7.9, -6.1, 6.0, 5.9, 9.6, 1.2, 6.2, 3.6, 2.1, 5.8, 9.2, -8.8, 8.8, -3.3, -9.2, 4.6, 1.8, 4.6, 2.9, -2.7, 4.2, - 7.3, -0.4, 7.7, -7.0, 2.1, 0.3, 3.7, 3.3, -8.6, 9.8, 3.6, 3.1, 6.5, -2.4, 7.8, 7.5, 8.4, -2.8, -6.3, -5.1, -2.7, 9.3, -0.8, -9.2, 7.9, - 8.9, 3.4, 0.1, -5.3, -6.8, 4.9, 4.3, -0.7, -2.2, -3.2, -7.5, -2.3, 0.0, 8.1, -9.2, -2.3, -5.7, 2.1, 2.6, 2.0, 0.3, -8.0, -2.0, -7.9, 6.6, - 8.4, 4.0, -6.2, -6.9, -7.2, 7.7, -5.0, 5.3, 1.9, -5.3, -7.5, 8.8, 8.3, 9.0, 8.1, 3.2, 1.2, -5.4, -0.2, 2.1, -5.2, 9.5, 5.9, 5.6, -7.8, +const double inputdata[] = { + // print ",\n".join([",".join(["%4s"%(random.randint(-99,99)/10.,) for i in range(25)]) for j in range(20)]) + -3.5, 6.3, 1.2, 0.3, 1.1, -5.7, 5.8, -1.9, -6.3, -1.4, 7.4, 2.4, -9.9, -7.2, 5.4, 6.1, + -1.9, -7.6, 1.4, -3.5, 0.7, 5.6, -4.2, -1.1, -4.4, -6.3, -7.2, 4.6, -3.0, -0.9, 7.2, 2.5, + -3.6, 6.1, -3.2, -2.1, 6.5, -0.4, -9.0, 2.3, 8.4, 4.0, -5.2, -9.0, 4.7, -3.7, -2.0, -9.5, + -3.9, -3.6, 7.1, 0.8, -0.6, 5.2, -9.3, -4.5, 5.9, 2.2, -5.8, 5.0, 1.2, -0.1, 2.2, 0.2, + -7.7, 1.9, -8.4, 4.4, 2.3, -2.9, 6.7, 2.7, 5.8, -3.6, 8.9, 8.9, 4.3, 9.1, 9.3, -8.7, + 4.1, 9.6, -6.2, 6.6, -9.3, 8.2, 4.5, 6.2, 9.4, -8.0, -6.8, -3.3, 7.2, 1.7, 0.6, -4.9, + 9.8, 1.3, 3.2, -0.2, 9.9, 4.4, -9.9, -7.2, 4.4, 4.7, 7.2, -0.3, 0.3, -2.1, 8.4, -2.1, + -6.1, 4.1, -5.9, -2.2, -3.8, 5.2, -8.2, -7.8, -8.8, 6.7, -9.5, -4.2, 0.8, 8.3, 5.2, -9.0, + 8.7, 9.8, -9.9, -7.8, -8.3, 9.0, -2.8, -9.2, -9.6, 8.4, 2.5, 6.0, -0.4, 1.3, -0.5, 9.1, + -9.5, -0.8, 1.9, -6.2, 4.3, -3.8, 8.6, -1.9, -2.1, -0.4, -7.1, -3.7, 9.1, -6.4, -0.6, 2.5, + 8.0, -5.2, -9.8, -4.3, 4.5, 1.7, 9.3, 9.2, 1.0, 5.3, -4.5, 6.4, -6.6, 3.1, -6.8, 2.1, + 2.0, 7.3, 8.6, 5.0, 5.2, 0.4, -7.1, 4.5, -9.2, -9.1, 0.2, -6.3, -1.1, -9.6, 7.4, -3.7, + -5.5, 2.6, -3.5, -0.7, 9.0, 9.8, -8.0, 3.6, 3.0, -2.2, -2.8, 0.8, 9.0, 2.8, 7.7, -0.7, + -5.0, -1.8, -2.3, -0.4, -6.2, -9.1, -9.2, 0.5, 5.7, -3.9, 2.1, 0.6, 0.4, 9.1, 7.4, 7.1, + -2.5, 7.3, 7.8, -4.3, 6.3, -0.8, -3.8, -1.5, 6.6, 2.3, 3.9, -4.6, 5.8, -7.4, 5.9, 2.8, + 4.7, 3.9, -5.4, 9.1, -1.6, -1.9, -4.2, -2.6, 0.6, -5.1, 1.8, 5.2, 4.0, -6.2, 6.5, -9.1, + 0.5, 2.1, 7.1, -8.6, 7.6, -9.7, -4.6, -5.7, 6.1, -1.8, -7.3, 9.4, 8.0, -2.6, -1.8, 5.7, + 9.3, -7.9, 7.4, 6.3, 2.0, 9.6, -4.5, -6.2, 6.1, 2.3, 0.8, 5.9, -2.8, -3.5, -1.5, 6.0, + -4.9, 3.5, 7.7, -4.2, -9.7, 2.4, 8.1, 5.9, 3.4, -7.5, 7.5, 2.6, 4.7, 2.7, 2.2, 2.6, + 6.2, 7.5, 0.2, -6.4, -2.8, -0.5, -0.3, 0.4, 1.2, 3.5, -4.0, -0.5, 9.3, -7.2, 8.5, -5.5, + -1.7, -5.3, 0.3, 3.9, -3.6, -3.6, 4.7, -8.1, 1.4, 4.0, 1.3, -4.3, -8.8, -7.3, 6.3, -7.5, + -9.0, 9.1, 4.5, -1.9, 1.9, 9.9, -1.7, -9.1, -5.1, 8.5, -9.3, 2.1, -5.8, -3.6, -0.8, -0.9, + -3.3, -2.7, 7.0, -7.2, -5.0, 7.4, -1.4, 0.0, -4.5, -9.7, 0.7, -1.0, -9.1, -5.3, 4.3, 3.4, + -6.6, 9.8, -1.1, 8.9, 5.0, 2.9, 0.2, -2.9, 0.8, 6.7, -0.6, 0.6, 4.1, 5.3, -1.7, -0.3, + 4.2, 3.7, -8.3, 4.0, 1.3, 6.3, 0.2, 1.3, -1.1, -3.5, 2.8, -7.7, 6.2, -4.9, -9.9, 9.6, + 3.0, -9.2, -8.0, -3.9, 7.9, -6.1, 6.0, 5.9, 9.6, 1.2, 6.2, 3.6, 2.1, 5.8, 9.2, -8.8, + 8.8, -3.3, -9.2, 4.6, 1.8, 4.6, 2.9, -2.7, 4.2, 7.3, -0.4, 7.7, -7.0, 2.1, 0.3, 3.7, + 3.3, -8.6, 9.8, 3.6, 3.1, 6.5, -2.4, 7.8, 7.5, 8.4, -2.8, -6.3, -5.1, -2.7, 9.3, -0.8, + -9.2, 7.9, 8.9, 3.4, 0.1, -5.3, -6.8, 4.9, 4.3, -0.7, -2.2, -3.2, -7.5, -2.3, 0.0, 8.1, + -9.2, -2.3, -5.7, 2.1, 2.6, 2.0, 0.3, -8.0, -2.0, -7.9, 6.6, 8.4, 4.0, -6.2, -6.9, -7.2, + 7.7, -5.0, 5.3, 1.9, -5.3, -7.5, 8.8, 8.3, 9.0, 8.1, 3.2, 1.2, -5.4, -0.2, 2.1, -5.2, + 9.5, 5.9, 5.6, -7.8, }; class BaseFFTTest : public ::testing::Test { - public: - BaseFFTTest() - : checker_(data_.rootChecker()), flags_(GMX_FFT_FLAG_CONSERVATIVE) - { - // TODO: These tolerances are just something that has been observed - // to be sufficient to pass the tests. It would be nicer to - // actually argue about why they are sufficient (or what is). - checker_.setDefaultTolerance( - gmx::test::relativeToleranceAsPrecisionDependentUlp(10.0, 64, 512)); - } - ~BaseFFTTest() override - { - gmx_fft_cleanup(); - } +public: + BaseFFTTest() : checker_(data_.rootChecker()), flags_(GMX_FFT_FLAG_CONSERVATIVE) + { + // TODO: These tolerances are just something that has been observed + // to be sufficient to pass the tests. It would be nicer to + // actually argue about why they are sufficient (or what is). + checker_.setDefaultTolerance(gmx::test::relativeToleranceAsPrecisionDependentUlp(10.0, 64, 512)); + } + ~BaseFFTTest() override { gmx_fft_cleanup(); } - gmx::test::TestReferenceData data_; - gmx::test::TestReferenceChecker checker_; - std::vector in_, out_; - int flags_; + gmx::test::TestReferenceData data_; + gmx::test::TestReferenceChecker checker_; + std::vector in_, out_; + int flags_; }; class FFTTest : public BaseFFTTest { - public: - FFTTest() : fft_(nullptr) - { - } - ~FFTTest() override +public: + FFTTest() : fft_(nullptr) {} + ~FFTTest() override + { + if (fft_) { - if (fft_) - { - gmx_fft_destroy(fft_); - } + gmx_fft_destroy(fft_); } - gmx_fft_t fft_; + } + gmx_fft_t fft_; }; class ManyFFTTest : public BaseFFTTest { - public: - ManyFFTTest() : fft_(nullptr) - { - } - ~ManyFFTTest() override +public: + ManyFFTTest() : fft_(nullptr) {} + ~ManyFFTTest() override + { + if (fft_) { - if (fft_) - { - gmx_many_fft_destroy(fft_); - } + gmx_many_fft_destroy(fft_); } - gmx_fft_t fft_; + } + gmx_fft_t fft_; }; -//TODO: Add tests for aligned/not-aligned input/output memory +// TODO: Add tests for aligned/not-aligned input/output memory class FFTTest1D : public FFTTest, public ::testing::WithParamInterface { - }; class FFFTest3D : public BaseFFTTest { - public: - FFFTest3D() : fft_(nullptr) - { - } - ~FFFTest3D() override +public: + FFFTest3D() : fft_(nullptr) {} + ~FFFTest3D() override + { + if (fft_) { - if (fft_) - { - gmx_parallel_3dfft_destroy(fft_); - } + gmx_parallel_3dfft_destroy(fft_); } - gmx_parallel_3dfft_t fft_; + } + gmx_parallel_3dfft_t fft_; }; TEST_P(FFTTest1D, Complex) { const int nx = GetParam(); - ASSERT_LE(nx*2, static_cast(sizeof(inputdata)/sizeof(inputdata[0]))); + ASSERT_LE(nx * 2, static_cast(sizeof(inputdata) / sizeof(inputdata[0]))); - in_ = std::vector(nx*2); - std::copy(inputdata, inputdata+nx*2, in_.begin()); - out_ = std::vector(nx*2); + in_ = std::vector(nx * 2); + std::copy(inputdata, inputdata + nx * 2, in_.begin()); + out_ = std::vector(nx * 2); real* in = &in_[0]; real* out = &out_[0]; gmx_fft_init_1d(&fft_, nx, flags_); gmx_fft_1d(fft_, GMX_FFT_FORWARD, in, out); - checker_.checkSequenceArray(nx*2, out, "forward"); + checker_.checkSequenceArray(nx * 2, out, "forward"); gmx_fft_1d(fft_, GMX_FFT_BACKWARD, in, out); - checker_.checkSequenceArray(nx*2, out, "backward"); + checker_.checkSequenceArray(nx * 2, out, "backward"); } TEST_P(FFTTest1D, Real) { const int rx = GetParam(); - const int cx = (rx/2+1); - ASSERT_LE(cx*2, static_cast(sizeof(inputdata)/sizeof(inputdata[0]))); + const int cx = (rx / 2 + 1); + ASSERT_LE(cx * 2, static_cast(sizeof(inputdata) / sizeof(inputdata[0]))); - in_ = std::vector(cx*2); - std::copy(inputdata, inputdata+cx*2, in_.begin()); - out_ = std::vector(cx*2); + in_ = std::vector(cx * 2); + std::copy(inputdata, inputdata + cx * 2, in_.begin()); + out_ = std::vector(cx * 2); real* in = &in_[0]; real* out = &out_[0]; gmx_fft_init_1d_real(&fft_, rx, flags_); gmx_fft_1d_real(fft_, GMX_FFT_REAL_TO_COMPLEX, in, out); - checker_.checkSequenceArray(cx*2, out, "forward"); + checker_.checkSequenceArray(cx * 2, out, "forward"); gmx_fft_1d_real(fft_, GMX_FFT_COMPLEX_TO_REAL, in, out); checker_.checkSequenceArray(rx, out, "backward"); } -INSTANTIATE_TEST_CASE_P(7_8_25_36_60, - FFTTest1D, ::testing::Values(7, 8, 25, 36, 60)); +INSTANTIATE_TEST_CASE_P(7_8_25_36_60, FFTTest1D, ::testing::Values(7, 8, 25, 36, 60)); TEST_F(ManyFFTTest, Complex1DLength48Multi5Test) @@ -220,100 +220,97 @@ TEST_F(ManyFFTTest, Complex1DLength48Multi5Test) const int nx = 48; const int N = 5; - in_ = std::vector(nx*2*N); - std::copy(inputdata, inputdata+nx*2*N, in_.begin()); - out_ = std::vector(nx*2*N); + in_ = std::vector(nx * 2 * N); + std::copy(inputdata, inputdata + nx * 2 * N, in_.begin()); + out_ = std::vector(nx * 2 * N); real* in = &in_[0]; real* out = &out_[0]; gmx_fft_init_many_1d(&fft_, nx, N, flags_); gmx_fft_many_1d(fft_, GMX_FFT_FORWARD, in, out); - checker_.checkSequenceArray(nx*2*N, out, "forward"); + checker_.checkSequenceArray(nx * 2 * N, out, "forward"); gmx_fft_many_1d(fft_, GMX_FFT_BACKWARD, in, out); - checker_.checkSequenceArray(nx*2*N, out, "backward"); + checker_.checkSequenceArray(nx * 2 * N, out, "backward"); } TEST_F(ManyFFTTest, Real1DLength48Multi5Test) { const int rx = 48; - const int cx = (rx/2+1); + const int cx = (rx / 2 + 1); const int N = 5; - in_ = std::vector(cx*2*N); - std::copy(inputdata, inputdata+cx*2*N, in_.begin()); - out_ = std::vector(cx*2*N); + in_ = std::vector(cx * 2 * N); + std::copy(inputdata, inputdata + cx * 2 * N, in_.begin()); + out_ = std::vector(cx * 2 * N); real* in = &in_[0]; real* out = &out_[0]; gmx_fft_init_many_1d_real(&fft_, rx, N, flags_); gmx_fft_many_1d_real(fft_, GMX_FFT_REAL_TO_COMPLEX, in, out); - checker_.checkSequenceArray(cx*2*N, out, "forward"); + checker_.checkSequenceArray(cx * 2 * N, out, "forward"); gmx_fft_many_1d_real(fft_, GMX_FFT_COMPLEX_TO_REAL, in, out); - checker_.checkSequenceArray(rx*N, out, "backward"); + checker_.checkSequenceArray(rx * N, out, "backward"); } TEST_F(FFTTest, Real2DLength18_15Test) { const int rx = 18; - const int cx = (rx/2+1); + const int cx = (rx / 2 + 1); const int ny = 15; - in_ = std::vector(cx*2*ny); - std::copy(inputdata, inputdata+cx*2*ny, in_.begin()); - out_ = std::vector(cx*2*ny); + in_ = std::vector(cx * 2 * ny); + std::copy(inputdata, inputdata + cx * 2 * ny, in_.begin()); + out_ = std::vector(cx * 2 * ny); real* in = &in_[0]; real* out = &out_[0]; gmx_fft_init_2d_real(&fft_, rx, ny, flags_); gmx_fft_2d_real(fft_, GMX_FFT_REAL_TO_COMPLEX, in, out); - checker_.checkSequenceArray(cx*2*ny, out, "forward"); -// known to be wrong for gmx_fft_mkl. And not used. -// gmx_fft_2d_real(_fft,GMX_FFT_COMPLEX_TO_REAL,in,out); -// _checker.checkSequenceArray(rx*ny, out, "backward"); + checker_.checkSequenceArray(cx * 2 * ny, out, "forward"); + // known to be wrong for gmx_fft_mkl. And not used. + // gmx_fft_2d_real(_fft,GMX_FFT_COMPLEX_TO_REAL,in,out); + // _checker.checkSequenceArray(rx*ny, out, "backward"); } -//TODO: test with threads and more than 1 MPI ranks +// TODO: test with threads and more than 1 MPI ranks TEST_F(FFFTest3D, Real5_6_9) { - int ndata[] = {5, 6, 9}; - MPI_Comm comm[] = {MPI_COMM_NULL, MPI_COMM_NULL}; - real * rdata; + int ndata[] = { 5, 6, 9 }; + MPI_Comm comm[] = { MPI_COMM_NULL, MPI_COMM_NULL }; + real* rdata; t_complex* cdata; ivec local_ndata, offset, rsize, csize, complex_order; - gmx_parallel_3dfft_init(&fft_, ndata, &rdata, &cdata, - comm, TRUE, 1); + gmx_parallel_3dfft_init(&fft_, ndata, &rdata, &cdata, comm, TRUE, 1); gmx_parallel_3dfft_real_limits(fft_, local_ndata, offset, rsize); - gmx_parallel_3dfft_complex_limits(fft_, complex_order, - local_ndata, offset, csize); + gmx_parallel_3dfft_complex_limits(fft_, complex_order, local_ndata, offset, csize); checker_.checkVector(rsize, "rsize"); checker_.checkVector(csize, "csize"); - int size = csize[0]*csize[1]*csize[2]; - int sizeInBytes = size*sizeof(t_complex); - int sizeInReals = sizeInBytes/sizeof(real); + int size = csize[0] * csize[1] * csize[2]; + int sizeInBytes = size * sizeof(t_complex); + int sizeInReals = sizeInBytes / sizeof(real); - in_ = std::vector(sizeInReals); + in_ = std::vector(sizeInReals); // Use std::copy to convert from double to real easily - std::copy(inputdata, inputdata+sizeInReals, in_.begin()); + std::copy(inputdata, inputdata + sizeInReals, in_.begin()); // Use memcpy to convert to t_complex easily memcpy(rdata, in_.data(), sizeInBytes); gmx_parallel_3dfft_execute(fft_, GMX_FFT_REAL_TO_COMPLEX, 0, nullptr); - //TODO use std::complex and add checkComplex for it - checker_.checkSequenceArray(size*2, - reinterpret_cast(cdata), "forward"); + // TODO use std::complex and add checkComplex for it + checker_.checkSequenceArray(size * 2, reinterpret_cast(cdata), "forward"); // Use std::copy to convert from double to real easily - std::copy(inputdata, inputdata+sizeInReals, in_.begin()); + std::copy(inputdata, inputdata + sizeInReals, in_.begin()); // Use memcpy to convert to t_complex easily memcpy(cdata, in_.data(), sizeInBytes); gmx_parallel_3dfft_execute(fft_, GMX_FFT_COMPLEX_TO_REAL, 0, nullptr); - for (int i = 0; i < ndata[0]*ndata[1]; i++) //check sequence but skip unused data + for (int i = 0; i < ndata[0] * ndata[1]; i++) // check sequence but skip unused data { - checker_.checkSequenceArray(ndata[2], rdata+i*rsize[2], + checker_.checkSequenceArray(ndata[2], rdata + i * rsize[2], gmx::formatString("backward %d", i).c_str()); } } diff --git a/src/gromacs/fileio/checkpoint.cpp b/src/gromacs/fileio/checkpoint.cpp index 7cd4037ec2..b842bcc013 100644 --- a/src/gromacs/fileio/checkpoint.cpp +++ b/src/gromacs/fileio/checkpoint.cpp @@ -89,7 +89,7 @@ #include "gromacs/utility/txtdump.h" #if GMX_FAHCORE -#include "corewrap.h" +# include "corewrap.h" #endif #define CPT_MAGIC1 171817 @@ -104,13 +104,14 @@ * in this enumeration, and write code below that does the right thing * according to the value of file_version. */ -enum cptv { - cptv_Unknown = 17, /**< Version before numbering scheme */ - cptv_RemoveBuildMachineInformation, /**< remove functionality that makes mdrun builds non-reproducible */ - cptv_ComPrevStepAsPullGroupReference, /**< Allow using COM of previous step as pull group PBC reference */ - cptv_PullAverage, /**< Added possibility to output average pull force and position */ - cptv_MdModules, /**< Added checkpointing for MdModules */ - cptv_Count /**< the total number of cptv versions */ +enum cptv +{ + cptv_Unknown = 17, /**< Version before numbering scheme */ + cptv_RemoveBuildMachineInformation, /**< remove functionality that makes mdrun builds non-reproducible */ + cptv_ComPrevStepAsPullGroupReference, /**< Allow using COM of previous step as pull group PBC reference */ + cptv_PullAverage, /**< Added possibility to output average pull force and position */ + cptv_MdModules, /**< Added checkpointing for MdModules */ + cptv_Count /**< the total number of cptv versions */ }; /*! \brief Version number of the file format written to checkpoint @@ -131,32 +132,65 @@ enum cptv { static const int cpt_version = cptv_Count - 1; -const char *est_names[estNR] = -{ - "FE-lambda", - "box", "box-rel", "box-v", "pres_prev", - "nosehoover-xi", "thermostat-integral", - "x", "v", "sdx-unsupported", "CGp", "LD-rng-unsupported", "LD-rng-i-unsupported", - "disre_initf", "disre_rm3tav", - "orire_initf", "orire_Dtav", - "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng-unsupported", "MC-rng-i-unsupported", - "barostat-integral" -}; - -enum { - eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR +const char* est_names[estNR] = { "FE-lambda", + "box", + "box-rel", + "box-v", + "pres_prev", + "nosehoover-xi", + "thermostat-integral", + "x", + "v", + "sdx-unsupported", + "CGp", + "LD-rng-unsupported", + "LD-rng-i-unsupported", + "disre_initf", + "disre_rm3tav", + "orire_initf", + "orire_Dtav", + "svir_prev", + "nosehoover-vxi", + "v_eta", + "vol0", + "nhpres_xi", + "nhpres_vxi", + "fvir_prev", + "fep_state", + "MC-rng-unsupported", + "MC-rng-i-unsupported", + "barostat-integral" }; + +enum +{ + eeksEKIN_N, + eeksEKINH, + eeksDEKINDL, + eeksMVCOS, + eeksEKINF, + eeksEKINO, + eeksEKINSCALEF, + eeksEKINSCALEH, + eeksVSCALE, + eeksEKINTOTAL, + eeksNR }; -static const char *eeks_names[eeksNR] = -{ - "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos", - "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total" -}; - -enum { - eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM, - eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM, - eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM, +static const char* eeks_names[eeksNR] = { "Ekin_n", "Ekinh", "dEkindlambda", + "mv_cos", "Ekinf", "Ekinh_old", + "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", + "Ekin_Total" }; + +enum +{ + eenhENERGY_N, + eenhENERGY_AVER, + eenhENERGY_SUM, + eenhENERGY_NSUM, + eenhENERGY_SUM_SIM, + eenhENERGY_NSUM_SIM, + eenhENERGY_NSTEPS, + eenhENERGY_NSTEPS_SIM, eenhENERGY_DELTA_H_NN, eenhENERGY_DELTA_H_LIST, eenhENERGY_DELTA_H_STARTTIME, @@ -164,57 +198,94 @@ enum { eenhNR }; -enum { - epullhPULL_NUMCOORDINATES, epullhPULL_NUMGROUPS, epullhPULL_NUMVALUESINXSUM, - epullhPULL_NUMVALUESINFSUM, epullhNR -}; - -enum { - epullcoordh_VALUE_REF_SUM, epullcoordh_VALUE_SUM, epullcoordh_DR01_SUM, - epullcoordh_DR23_SUM, epullcoordh_DR45_SUM, epullcoordh_FSCAL_SUM, - epullcoordh_DYNAX_SUM, epullcoordh_NR -}; - -enum { - epullgrouph_X_SUM, epullgrouph_NR +enum +{ + epullhPULL_NUMCOORDINATES, + epullhPULL_NUMGROUPS, + epullhPULL_NUMVALUESINXSUM, + epullhPULL_NUMVALUESINFSUM, + epullhNR }; -static const char *eenh_names[eenhNR] = +enum { - "energy_n", "energy_aver", "energy_sum", "energy_nsum", - "energy_sum_sim", "energy_nsum_sim", - "energy_nsteps", "energy_nsteps_sim", - "energy_delta_h_nn", - "energy_delta_h_list", - "energy_delta_h_start_time", - "energy_delta_h_start_lambda" + epullcoordh_VALUE_REF_SUM, + epullcoordh_VALUE_SUM, + epullcoordh_DR01_SUM, + epullcoordh_DR23_SUM, + epullcoordh_DR45_SUM, + epullcoordh_FSCAL_SUM, + epullcoordh_DYNAX_SUM, + epullcoordh_NR }; -static const char *ePullhNames[epullhNR] = +enum { - "pullhistory_numcoordinates", "pullhistory_numgroups", "pullhistory_numvaluesinxsum", - "pullhistory_numvaluesinfsum" + epullgrouph_X_SUM, + epullgrouph_NR }; +static const char* eenh_names[eenhNR] = { "energy_n", + "energy_aver", + "energy_sum", + "energy_nsum", + "energy_sum_sim", + "energy_nsum_sim", + "energy_nsteps", + "energy_nsteps_sim", + "energy_delta_h_nn", + "energy_delta_h_list", + "energy_delta_h_start_time", + "energy_delta_h_start_lambda" }; + +static const char* ePullhNames[epullhNR] = { "pullhistory_numcoordinates", "pullhistory_numgroups", + "pullhistory_numvaluesinxsum", + "pullhistory_numvaluesinfsum" }; + /* free energy history variables -- need to be preserved over checkpoint */ -enum { - edfhBEQUIL, edfhNATLAMBDA, edfhWLHISTO, edfhWLDELTA, edfhSUMWEIGHTS, edfhSUMDG, edfhSUMMINVAR, edfhSUMVAR, - edfhACCUMP, edfhACCUMM, edfhACCUMP2, edfhACCUMM2, edfhTIJ, edfhTIJEMP, edfhNR +enum +{ + edfhBEQUIL, + edfhNATLAMBDA, + edfhWLHISTO, + edfhWLDELTA, + edfhSUMWEIGHTS, + edfhSUMDG, + edfhSUMMINVAR, + edfhSUMVAR, + edfhACCUMP, + edfhACCUMM, + edfhACCUMP2, + edfhACCUMM2, + edfhTIJ, + edfhTIJEMP, + edfhNR }; /* free energy history variable names */ -static const char *edfh_names[edfhNR] = -{ - "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance", - "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical" -}; +static const char* edfh_names[edfhNR] = { "bEquilibrated", + "N_at_state", + "Wang-Landau Histogram", + "Wang-Landau Delta", + "Weights", + "Free Energies", + "minvar", + "variance", + "accumulated_plus", + "accumulated_minus", + "accumulated_plus_2", + "accumulated_minus_2", + "Tij", + "Tij_empirical" }; /* AWH biasing history variables */ -enum { +enum +{ eawhhIN_INITIAL, eawhhEQUILIBRATEHISTOGRAM, eawhhHISTSIZE, eawhhNPOINTS, - eawhhCOORDPOINT, eawhhUMBRELLAGRIDPOINT, + eawhhCOORDPOINT, + eawhhUMBRELLAGRIDPOINT, eawhhUPDATELIST, eawhhLOGSCALEDSAMPLEWEIGHT, eawhhNUMUPDATES, @@ -222,37 +293,28 @@ enum { eawhhNR }; -static const char *eawhh_names[eawhhNR] = -{ - "awh_in_initial", - "awh_equilibrateHistogram", - "awh_histsize", - "awh_npoints", - "awh_coordpoint", "awh_umbrellaGridpoint", - "awh_updatelist", - "awh_logScaledSampleWeight", - "awh_numupdates", - "awh_forceCorrelationGrid" -}; +static const char* eawhh_names[eawhhNR] = { "awh_in_initial", "awh_equilibrateHistogram", + "awh_histsize", "awh_npoints", + "awh_coordpoint", "awh_umbrellaGridpoint", + "awh_updatelist", "awh_logScaledSampleWeight", + "awh_numupdates", "awh_forceCorrelationGrid" }; -enum { +enum +{ epullsPREVSTEPCOM, epullsNR }; -static const char *epull_prev_step_com_names[epullsNR] = -{ - "Pull groups prev step COM" -}; +static const char* epull_prev_step_com_names[epullsNR] = { "Pull groups prev step COM" }; //! Higher level vector element type, only used for formatting checkpoint dumps enum class CptElementType { - integer, //!< integer - real, //!< float or double, not linked to precision of type real - real3, //!< float[3] or double[3], not linked to precision of type real - matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real + integer, //!< integer + real, //!< float or double, not linked to precision of type real + real3, //!< float[3] or double[3], not linked to precision of type real + matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real }; //! \brief Parts of the checkpoint state, only used for reporting @@ -268,35 +330,35 @@ enum class StatePart }; //! \brief Return the name of a checkpoint entry based on part and part entry -static const char *entryName(StatePart part, int ecpt) +static const char* entryName(StatePart part, int ecpt) { switch (part) { - case StatePart::microState: return est_names [ecpt]; - case StatePart::kineticEnergy: return eeks_names[ecpt]; - case StatePart::energyHistory: return eenh_names[ecpt]; - case StatePart::freeEnergyHistory: return edfh_names[ecpt]; + case StatePart::microState: return est_names[ecpt]; + case StatePart::kineticEnergy: return eeks_names[ecpt]; + case StatePart::energyHistory: return eenh_names[ecpt]; + case StatePart::freeEnergyHistory: return edfh_names[ecpt]; case StatePart::accWeightHistogram: return eawhh_names[ecpt]; - case StatePart::pullState: return epull_prev_step_com_names[ecpt]; - case StatePart::pullHistory: return ePullhNames[ecpt]; + case StatePart::pullState: return epull_prev_step_com_names[ecpt]; + case StatePart::pullHistory: return ePullhNames[ecpt]; } return nullptr; } -static void cp_warning(FILE *fp) +static void cp_warning(FILE* fp) { fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n"); } -[[ noreturn ]] static void cp_error() +[[noreturn]] static void cp_error() { gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?"); } -static void do_cpt_string_err(XDR *xd, const char *desc, gmx::ArrayRef s, FILE *list) +static void do_cpt_string_err(XDR* xd, const char* desc, gmx::ArrayRef s, FILE* list) { - char *data = s.data(); + char* data = s.data(); if (xdr_string(xd, &data, s.size()) == 0) { cp_error(); @@ -307,7 +369,7 @@ static void do_cpt_string_err(XDR *xd, const char *desc, gmx::ArrayRef s, } } -static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list) +static int do_cpt_int(XDR* xd, const char* desc, int* i, FILE* list) { if (xdr_int(xd, i) == 0) { @@ -320,7 +382,7 @@ static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list) return 0; } -static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FILE *list) +static int do_cpt_u_chars(XDR* xd, const char* desc, int n, unsigned char* i, FILE* list) { if (list) { @@ -347,7 +409,7 @@ static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FI return 0; } -static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list) +static void do_cpt_int_err(XDR* xd, const char* desc, int* i, FILE* list) { if (do_cpt_int(xd, desc, i, list) < 0) { @@ -355,9 +417,9 @@ static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list) } } -static void do_cpt_bool_err(XDR *xd, const char *desc, bool *b, FILE *list) +static void do_cpt_bool_err(XDR* xd, const char* desc, bool* b, FILE* list) { - int i = static_cast(*b); + int i = static_cast(*b); if (do_cpt_int(xd, desc, &i, list) < 0) { @@ -367,9 +429,9 @@ static void do_cpt_bool_err(XDR *xd, const char *desc, bool *b, FILE *list) *b = (i != 0); } -static void do_cpt_step_err(XDR *xd, const char *desc, int64_t *i, FILE *list) +static void do_cpt_step_err(XDR* xd, const char* desc, int64_t* i, FILE* list) { - char buf[STEPSTRSIZE]; + char buf[STEPSTRSIZE]; if (xdr_int64(xd, i) == 0) { @@ -381,7 +443,7 @@ static void do_cpt_step_err(XDR *xd, const char *desc, int64_t *i, FILE *list) } } -static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list) +static void do_cpt_double_err(XDR* xd, const char* desc, double* f, FILE* list) { if (xdr_double(xd, f) == 0) { @@ -393,7 +455,7 @@ static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list) } } -static void do_cpt_real_err(XDR *xd, real *f) +static void do_cpt_real_err(XDR* xd, real* f) { #if GMX_DOUBLE bool_t res = xdr_double(xd, f); @@ -406,7 +468,7 @@ static void do_cpt_real_err(XDR *xd, real *f) } } -static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE *list) +static void do_cpt_n_rvecs_err(XDR* xd, const char* desc, int n, rvec f[], FILE* list) { for (int i = 0; i < n; i++) { @@ -422,24 +484,24 @@ static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE } } -template +template struct xdr_type { }; -template <> +template<> struct xdr_type { static const int value = xdr_datatype_int; }; -template <> +template<> struct xdr_type { static const int value = xdr_datatype_float; }; -template <> +template<> struct xdr_type { static const int value = xdr_datatype_double; @@ -450,12 +512,9 @@ static inline unsigned int sizeOfXdrType(int xdrType) { switch (xdrType) { - case xdr_datatype_int: - return sizeof(int); - case xdr_datatype_float: - return sizeof(float); - case xdr_datatype_double: - return sizeof(double); + case xdr_datatype_int: return sizeof(int); + case xdr_datatype_float: return sizeof(float); + case xdr_datatype_double: return sizeof(double); default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented"); } @@ -467,12 +526,9 @@ static inline xdrproc_t xdrProc(int xdrType) { switch (xdrType) { - case xdr_datatype_int: - return reinterpret_cast(xdr_int); - case xdr_datatype_float: - return reinterpret_cast(xdr_float); - case xdr_datatype_double: - return reinterpret_cast(xdr_double); + case xdr_datatype_int: return reinterpret_cast(xdr_int); + case xdr_datatype_float: return reinterpret_cast(xdr_float); + case xdr_datatype_double: return reinterpret_cast(xdr_double); default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented"); } @@ -486,13 +542,12 @@ static inline xdrproc_t xdrProc(int xdrType) * The formatting of the printing is set by \p cptElementType. * When list==NULL only reads the elements. */ -static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrType, - FILE *list, CptElementType cptElementType) +static bool_t listXdrVector(XDR* xd, StatePart part, int ecpt, int nf, int xdrType, FILE* list, CptElementType cptElementType) { - bool_t res = 0; + bool_t res = 0; const unsigned int elemSize = sizeOfXdrType(xdrType); - std::vector data(nf*elemSize); + std::vector data(nf * elemSize); res = xdr_vector(xd, data.data(), nf, elemSize, xdrProc(xdrType)); if (list != nullptr) @@ -500,32 +555,36 @@ static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrTy switch (xdrType) { case xdr_datatype_int: - pr_ivec(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf, TRUE); + pr_ivec(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf, TRUE); break; case xdr_datatype_float: #if !GMX_DOUBLE if (cptElementType == CptElementType::real3) { - pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf/3); + pr_rvecs(list, 0, entryName(part, ecpt), + reinterpret_cast(data.data()), nf / 3); } else #endif { /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */ - pr_fvec(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf, TRUE); + pr_fvec(list, 0, entryName(part, ecpt), + reinterpret_cast(data.data()), nf, TRUE); } break; case xdr_datatype_double: #if GMX_DOUBLE if (cptElementType == CptElementType::real3) { - pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf/3); + pr_rvecs(list, 0, entryName(part, ecpt), + reinterpret_cast(data.data()), nf / 3); } else #endif { /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */ - pr_dvec(list, 0, entryName(part, ecpt), reinterpret_cast(data.data()), nf, TRUE); + pr_dvec(list, 0, entryName(part, ecpt), + reinterpret_cast(data.data()), nf, TRUE); } break; default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing"); @@ -536,9 +595,9 @@ static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrTy } //! \brief Convert a double array, typed char*, to float -gmx_unused static void convertArrayRealPrecision(const char *c, float *v, int n) +gmx_unused static void convertArrayRealPrecision(const char* c, float* v, int n) { - const double *d = reinterpret_cast(c); + const double* d = reinterpret_cast(c); for (int i = 0; i < n; i++) { v[i] = static_cast(d[i]); @@ -546,9 +605,9 @@ gmx_unused static void convertArrayRealPrecision(const char *c, float *v, int n) } //! \brief Convert a float array, typed char*, to double -static void convertArrayRealPrecision(const char *c, double *v, int n) +static void convertArrayRealPrecision(const char* c, double* v, int n) { - const float *f = reinterpret_cast(c); + const float* f = reinterpret_cast(c); for (int i = 0; i < n; i++) { v[i] = static_cast(f[i]); @@ -556,9 +615,10 @@ static void convertArrayRealPrecision(const char *c, double *v, int n) } //! \brief Generate an error for trying to convert to integer -static void convertArrayRealPrecision(const char gmx_unused *c, int gmx_unused *v, int gmx_unused n) +static void convertArrayRealPrecision(const char gmx_unused* c, int gmx_unused* v, int gmx_unused n) { - GMX_RELEASE_ASSERT(false, "We only expect type mismatches between float and double, not integer"); + GMX_RELEASE_ASSERT(false, + "We only expect type mismatches between float and double, not integer"); } /*! \brief Low-level routine for reading/writing a vector of reals from/to file. @@ -581,16 +641,24 @@ static void convertArrayRealPrecision(const char gmx_unused *c, int gmx_unused * * the value is stored in nptr */ template -static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, - int nval, int *nptr, - T **v, std::vector *vector, - FILE *list, CptElementType cptElementType) -{ - GMX_RELEASE_ASSERT(list != nullptr || (v != nullptr && vector == nullptr) || (v == nullptr && vector != nullptr), "Without list, we should have exactly one of v and vector != NULL"); +static int doVectorLow(XDR* xd, + StatePart part, + int ecpt, + int sflags, + int nval, + int* nptr, + T** v, + std::vector* vector, + FILE* list, + CptElementType cptElementType) +{ + GMX_RELEASE_ASSERT(list != nullptr || (v != nullptr && vector == nullptr) + || (v == nullptr && vector != nullptr), + "Without list, we should have exactly one of v and vector != NULL"); bool_t res = 0; - int numElemInTheFile; + int numElemInTheFile; if (list == nullptr) { if (nval >= 0) @@ -620,7 +688,7 @@ static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, /* Read/write the element data type */ constexpr int xdrTypeInTheCode = xdr_type::value; int xdrTypeInTheFile = xdrTypeInTheCode; - res = xdr_int(xd, &xdrTypeInTheFile); + res = xdr_int(xd, &xdrTypeInTheFile); if (res == 0) { return -1; @@ -632,7 +700,9 @@ static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, { if (numElemInTheFile != nval) { - gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), nval, numElemInTheFile); + gmx_fatal(FARGS, + "Count mismatch for state entry %s, code count is %d, file count is %d\n", + entryName(part, ecpt), nval, numElemInTheFile); } } else if (nptr != nullptr) @@ -645,19 +715,18 @@ static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, { char buf[STRLEN]; sprintf(buf, "mismatch for state entry %s, code precision is %s, file precision is %s", - entryName(part, ecpt), - xdr_datatype_names[xdrTypeInTheCode], + entryName(part, ecpt), xdr_datatype_names[xdrTypeInTheCode], xdr_datatype_names[xdrTypeInTheFile]); /* Matching int and real should never occur, but check anyhow */ - if (xdrTypeInTheFile == xdr_datatype_int || - xdrTypeInTheCode == xdr_datatype_int) + if (xdrTypeInTheFile == xdr_datatype_int || xdrTypeInTheCode == xdr_datatype_int) { - gmx_fatal(FARGS, "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf); + gmx_fatal(FARGS, + "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf); } } - T *vp; + T* vp; if (v != nullptr) { if (*v == nullptr) @@ -680,17 +749,16 @@ static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, vp = vector->data(); } - char *vChar; + char* vChar; if (typesMatch) { - vChar = reinterpret_cast(vp); + vChar = reinterpret_cast(vp); } else { - snew(vChar, numElemInTheFile*sizeOfXdrType(xdrTypeInTheFile)); + snew(vChar, numElemInTheFile * sizeOfXdrType(xdrTypeInTheFile)); } - res = xdr_vector(xd, vChar, - numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile), + res = xdr_vector(xd, vChar, numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile), xdrProc(xdrTypeInTheFile)); if (res == 0) { @@ -710,46 +778,47 @@ static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags, } else { - res = listXdrVector(xd, part, ecpt, numElemInTheFile, xdrTypeInTheFile, - list, cptElementType); + res = listXdrVector(xd, part, ecpt, numElemInTheFile, xdrTypeInTheFile, list, cptElementType); } return 0; } //! \brief Read/Write a std::vector, on read checks the number of elements matches \p numElements, if specified. -template -static int doVector(XDR *xd, StatePart part, int ecpt, int sflags, - std::vector *vector, FILE *list, int numElements = -1) +template +static int +doVector(XDR* xd, StatePart part, int ecpt, int sflags, std::vector* vector, FILE* list, int numElements = -1) { - return doVectorLow(xd, part, ecpt, sflags, numElements, nullptr, nullptr, vector, list, CptElementType::real); + return doVectorLow(xd, part, ecpt, sflags, numElements, nullptr, nullptr, vector, list, + CptElementType::real); } //! \brief Read/Write an ArrayRef. -static int doRealArrayRef(XDR *xd, StatePart part, int ecpt, int sflags, - gmx::ArrayRef vector, FILE *list) +static int doRealArrayRef(XDR* xd, StatePart part, int ecpt, int sflags, gmx::ArrayRef vector, FILE* list) { - real *v_real = vector.data(); - return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, vector.size(), nullptr, &v_real, nullptr, list, CptElementType::real); + real* v_real = vector.data(); + return doVectorLow>(xd, part, ecpt, sflags, vector.size(), nullptr, + &v_real, nullptr, list, CptElementType::real); } //! Convert from view of RVec to view of real. -static gmx::ArrayRef -realArrayRefFromRVecArrayRef(gmx::ArrayRef ofRVecs) +static gmx::ArrayRef realArrayRefFromRVecArrayRef(gmx::ArrayRef ofRVecs) { - return gmx::arrayRefFromArray(reinterpret_cast(ofRVecs.data()), ofRVecs.size() * DIM); + return gmx::arrayRefFromArray(reinterpret_cast(ofRVecs.data()), ofRVecs.size() * DIM); } //! \brief Read/Write a PaddedVector whose value_type is RVec. -template -static int doRvecVector(XDR *xd, StatePart part, int ecpt, int sflags, - PaddedVectorOfRVecType *v, int numAtoms, FILE *list) +template +static int +doRvecVector(XDR* xd, StatePart part, int ecpt, int sflags, PaddedVectorOfRVecType* v, int numAtoms, FILE* list) { - const int numReals = numAtoms*DIM; + const int numReals = numAtoms * DIM; if (list == nullptr) { - GMX_RELEASE_ASSERT(sflags & (1 << ecpt), "When not listing, the flag for the entry should be set when requesting i/o"); + GMX_RELEASE_ASSERT( + sflags & (1 << ecpt), + "When not listing, the flag for the entry should be set when requesting i/o"); GMX_RELEASE_ASSERT(v->size() == numAtoms, "v should have sufficient size for numAtoms"); return doRealArrayRef(xd, part, ecpt, sflags, realArrayRefFromRVecArrayRef(makeArrayRef(*v)), list); @@ -758,8 +827,10 @@ static int doRvecVector(XDR *xd, StatePart part, int ecpt, int sflags, { // Use the rebind facility to change the value_type of the // allocator from RVec to real. - using realAllocator = typename std::allocator_traits::template rebind_alloc; - return doVectorLow(xd, part, ecpt, sflags, numReals, nullptr, nullptr, nullptr, list, CptElementType::real); + using realAllocator = + typename std::allocator_traits::template rebind_alloc; + return doVectorLow(xd, part, ecpt, sflags, numReals, nullptr, nullptr, + nullptr, list, CptElementType::real); } } @@ -767,70 +838,66 @@ static int doRvecVector(XDR *xd, StatePart part, int ecpt, int sflags, * but on reading it assumes that n matches the value in the checkpoint file, * a fatal error is generated when this is not the case. */ -static int do_cpte_reals(XDR *xd, StatePart part, int ecpt, int sflags, - int n, real **v, FILE *list) +static int do_cpte_reals(XDR* xd, StatePart part, int ecpt, int sflags, int n, real** v, FILE* list) { - return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real); + return doVectorLow>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, + list, CptElementType::real); } /* This function does the same as do_cpte_reals, * except that on reading it ignores the passed value of *n * and stores the value read from the checkpoint file in *n. */ -static int do_cpte_n_reals(XDR *xd, StatePart part, int ecpt, int sflags, - int *n, real **v, FILE *list) +static int do_cpte_n_reals(XDR* xd, StatePart part, int ecpt, int sflags, int* n, real** v, FILE* list) { - return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, -1, n, v, nullptr, list, CptElementType::real); + return doVectorLow>(xd, part, ecpt, sflags, -1, n, v, nullptr, list, + CptElementType::real); } -static int do_cpte_real(XDR *xd, StatePart part, int ecpt, int sflags, - real *r, FILE *list) +static int do_cpte_real(XDR* xd, StatePart part, int ecpt, int sflags, real* r, FILE* list) { - return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, 1, nullptr, &r, nullptr, list, CptElementType::real); + return doVectorLow>(xd, part, ecpt, sflags, 1, nullptr, &r, nullptr, + list, CptElementType::real); } -static int do_cpte_ints(XDR *xd, StatePart part, int ecpt, int sflags, - int n, int **v, FILE *list) +static int do_cpte_ints(XDR* xd, StatePart part, int ecpt, int sflags, int n, int** v, FILE* list) { - return doVectorLow < int, std::allocator < int>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::integer); + return doVectorLow>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, + list, CptElementType::integer); } -static int do_cpte_int(XDR *xd, StatePart part, int ecpt, int sflags, - int *i, FILE *list) +static int do_cpte_int(XDR* xd, StatePart part, int ecpt, int sflags, int* i, FILE* list) { return do_cpte_ints(xd, part, ecpt, sflags, 1, &i, list); } -static int do_cpte_bool(XDR *xd, StatePart part, int ecpt, int sflags, - bool *b, FILE *list) +static int do_cpte_bool(XDR* xd, StatePart part, int ecpt, int sflags, bool* b, FILE* list) { int i = static_cast(*b); int ret = do_cpte_int(xd, part, ecpt, sflags, &i, list); - *b = (i != 0); + *b = (i != 0); return ret; } -static int do_cpte_doubles(XDR *xd, StatePart part, int ecpt, int sflags, - int n, double **v, FILE *list) +static int do_cpte_doubles(XDR* xd, StatePart part, int ecpt, int sflags, int n, double** v, FILE* list) { - return doVectorLow < double, std::allocator < double>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real); + return doVectorLow>(xd, part, ecpt, sflags, n, nullptr, v, + nullptr, list, CptElementType::real); } -static int do_cpte_double(XDR *xd, StatePart part, int ecpt, int sflags, - double *r, FILE *list) +static int do_cpte_double(XDR* xd, StatePart part, int ecpt, int sflags, double* r, FILE* list) { return do_cpte_doubles(xd, part, ecpt, sflags, 1, &r, list); } -static int do_cpte_matrix(XDR *xd, StatePart part, int ecpt, int sflags, - matrix v, FILE *list) +static int do_cpte_matrix(XDR* xd, StatePart part, int ecpt, int sflags, matrix v, FILE* list) { - real *vr; + real* vr; int ret; vr = &(v[0][0]); - ret = doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, - DIM*DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3); + ret = doVectorLow>(xd, part, ecpt, sflags, DIM * DIM, nullptr, &vr, + nullptr, nullptr, CptElementType::matrix3x3); if (list && ret == 0) { @@ -841,12 +908,11 @@ static int do_cpte_matrix(XDR *xd, StatePart part, int ecpt, int sflags, } -static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags, - int n, real **v, FILE *list) +static int do_cpte_nmatrix(XDR* xd, StatePart part, int ecpt, int sflags, int n, real** v, FILE* list) { - int i; - int ret, reti; - char name[CPTSTRLEN]; + int i; + int ret, reti; + char name[CPTSTRLEN]; ret = 0; if (v == nullptr) @@ -855,7 +921,8 @@ static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags, } for (i = 0; i < n; i++) { - reti = doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, n, nullptr, &(v[i]), nullptr, nullptr, CptElementType::matrix3x3); + reti = doVectorLow>(xd, part, ecpt, sflags, n, nullptr, &(v[i]), + nullptr, nullptr, CptElementType::matrix3x3); if (list && reti == 0) { sprintf(name, "%s[%d]", entryName(part, ecpt), i); @@ -869,12 +936,11 @@ static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags, return ret; } -static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags, - int n, matrix **v, FILE *list) +static int do_cpte_matrices(XDR* xd, StatePart part, int ecpt, int sflags, int n, matrix** v, FILE* list) { bool_t res = 0; matrix *vp, *va = nullptr; - real *vr; + real* vr; int nf, i, j, k; int ret; @@ -886,9 +952,10 @@ static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags, } if (list == nullptr && nf != n) { - gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), n, nf); + gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", + entryName(part, ecpt), n, nf); } - if (list || !(sflags & (1<>(xd, part, ecpt, sflags, - nf*DIM*DIM, nullptr, &vr, nullptr, nullptr, - CptElementType::matrix3x3); + ret = doVectorLow>(xd, part, ecpt, sflags, nf * DIM * DIM, nullptr, + &vr, nullptr, nullptr, CptElementType::matrix3x3); for (i = 0; i < nf; i++) { for (j = 0; j < DIM; j++) { for (k = 0; k < DIM; k++) { - vp[i][j][k] = vr[(i*DIM+j)*DIM+k]; + vp[i][j][k] = vr[(i * DIM + j) * DIM + k]; } } } @@ -942,8 +1008,7 @@ static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags, return ret; } -static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list, - CheckpointHeaderContents *contents) +static void do_cpt_header(XDR* xd, gmx_bool bRead, FILE* list, CheckpointHeaderContents* contents) { bool_t res = 0; int magic; @@ -959,11 +1024,13 @@ static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list, res = xdr_int(xd, &magic); if (res == 0) { - gmx_fatal(FARGS, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?"); + gmx_fatal(FARGS, + "The checkpoint file is empty/corrupted, or maybe you are out of disk space?"); } if (magic != CPT_MAGIC1) { - gmx_fatal(FARGS, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n" + gmx_fatal(FARGS, + "Start of file magic number mismatch, checkpoint file has %d, should be %d\n" "The checkpoint file is corrupted or not a checkpoint file", magic, CPT_MAGIC1); } @@ -988,7 +1055,9 @@ static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list, do_cpt_int_err(xd, "checkpoint file version", &contents->file_version, list); if (contents->file_version > cpt_version) { - gmx_fatal(FARGS, "Attempting to read a checkpoint file of version %d with code of version %d\n", contents->file_version, cpt_version); + gmx_fatal(FARGS, + "Attempting to read a checkpoint file of version %d with code of version %d\n", + contents->file_version, cpt_version); } if (contents->file_version >= 13) { @@ -1062,10 +1131,10 @@ static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list, else { contents->flags_eks = 0; - contents->flags_enh = (contents->flags_state >> (estORIRE_DTAV+1)); - contents->flags_state = (contents->flags_state & ~((1<<(estORIRE_DTAV+1)) | - (1<<(estORIRE_DTAV+2)) | - (1<<(estORIRE_DTAV+3)))); + contents->flags_enh = (contents->flags_state >> (estORIRE_DTAV + 1)); + contents->flags_state = (contents->flags_state + & ~((1 << (estORIRE_DTAV + 1)) | (1 << (estORIRE_DTAV + 2)) + | (1 << (estORIRE_DTAV + 3)))); } if (contents->file_version >= 14) { @@ -1113,7 +1182,7 @@ static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list, } } -static int do_cpt_footer(XDR *xd, int file_version) +static int do_cpt_footer(XDR* xd, int file_version) { bool_t res = 0; int magic; @@ -1135,9 +1204,7 @@ static int do_cpt_footer(XDR *xd, int file_version) return 0; } -static int do_cpt_state(XDR *xd, - int fflags, t_state *state, - FILE *list) +static int do_cpt_state(XDR* xd, int fflags, t_state* state, FILE* list) { int ret = 0; const StatePart part = StatePart::microState; @@ -1148,75 +1215,148 @@ static int do_cpt_state(XDR *xd, state_change_natoms(state, state->natoms); for (int i = 0; (i < estNR && ret == 0); i++) { - if (fflags & (1<(state->lambda.data(), state->lambda.size()), list); break; - case estFEPSTATE: ret = do_cpte_int (xd, part, i, sflags, &state->fep_state, list); break; - case estBOX: ret = do_cpte_matrix(xd, part, i, sflags, state->box, list); break; - case estBOX_REL: ret = do_cpte_matrix(xd, part, i, sflags, state->box_rel, list); break; - case estBOXV: ret = do_cpte_matrix(xd, part, i, sflags, state->boxv, list); break; - case estPRES_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->pres_prev, list); break; - case estSVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->svir_prev, list); break; - case estFVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->fvir_prev, list); break; - case estNH_XI: ret = doVector(xd, part, i, sflags, &state->nosehoover_xi, list); break; - case estNH_VXI: ret = doVector(xd, part, i, sflags, &state->nosehoover_vxi, list); break; - case estNHPRES_XI: ret = doVector(xd, part, i, sflags, &state->nhpres_xi, list); break; - case estNHPRES_VXI: ret = doVector(xd, part, i, sflags, &state->nhpres_vxi, list); break; - case estTHERM_INT: ret = doVector(xd, part, i, sflags, &state->therm_integral, list); break; - case estBAROS_INT: ret = do_cpte_double(xd, part, i, sflags, &state->baros_integral, list); break; - case estVETA: ret = do_cpte_real(xd, part, i, sflags, &state->veta, list); break; - case estVOL0: ret = do_cpte_real(xd, part, i, sflags, &state->vol0, list); break; - case estX: ret = doRvecVector(xd, part, i, sflags, &state->x, state->natoms, list); break; - case estV: ret = doRvecVector(xd, part, i, sflags, &state->v, state->natoms, list); break; + case estLAMBDA: + ret = doRealArrayRef( + xd, part, i, sflags, + gmx::arrayRefFromArray(state->lambda.data(), state->lambda.size()), + list); + break; + case estFEPSTATE: + ret = do_cpte_int(xd, part, i, sflags, &state->fep_state, list); + break; + case estBOX: ret = do_cpte_matrix(xd, part, i, sflags, state->box, list); break; + case estBOX_REL: + ret = do_cpte_matrix(xd, part, i, sflags, state->box_rel, list); + break; + case estBOXV: ret = do_cpte_matrix(xd, part, i, sflags, state->boxv, list); break; + case estPRES_PREV: + ret = do_cpte_matrix(xd, part, i, sflags, state->pres_prev, list); + break; + case estSVIR_PREV: + ret = do_cpte_matrix(xd, part, i, sflags, state->svir_prev, list); + break; + case estFVIR_PREV: + ret = do_cpte_matrix(xd, part, i, sflags, state->fvir_prev, list); + break; + case estNH_XI: + ret = doVector(xd, part, i, sflags, &state->nosehoover_xi, list); + break; + case estNH_VXI: + ret = doVector(xd, part, i, sflags, &state->nosehoover_vxi, list); + break; + case estNHPRES_XI: + ret = doVector(xd, part, i, sflags, &state->nhpres_xi, list); + break; + case estNHPRES_VXI: + ret = doVector(xd, part, i, sflags, &state->nhpres_vxi, list); + break; + case estTHERM_INT: + ret = doVector(xd, part, i, sflags, &state->therm_integral, list); + break; + case estBAROS_INT: + ret = do_cpte_double(xd, part, i, sflags, &state->baros_integral, list); + break; + case estVETA: ret = do_cpte_real(xd, part, i, sflags, &state->veta, list); break; + case estVOL0: ret = do_cpte_real(xd, part, i, sflags, &state->vol0, list); break; + case estX: + ret = doRvecVector(xd, part, i, sflags, &state->x, state->natoms, list); + break; + case estV: + ret = doRvecVector(xd, part, i, sflags, &state->v, state->natoms, list); + break; /* The RNG entries are no longer written, * the next 4 lines are only for reading old files. */ - case estLD_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break; - case estLD_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break; - case estMC_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break; - case estMC_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break; - case estDISRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.disre_initf, list); break; - case estDISRE_RM3TAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list); break; - case estORIRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.orire_initf, list); break; - case estORIRE_DTAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list); break; - case estPULLCOMPREVSTEP: ret = doVector(xd, part, i, sflags, &state->pull_com_prev_step, list); break; + case estLD_RNG_NOTSUPPORTED: + ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); + break; + case estLD_RNGI_NOTSUPPORTED: + ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); + break; + case estMC_RNG_NOTSUPPORTED: + ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); + break; + case estMC_RNGI_NOTSUPPORTED: + ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); + break; + case estDISRE_INITF: + ret = do_cpte_real(xd, part, i, sflags, &state->hist.disre_initf, list); + break; + case estDISRE_RM3TAV: + ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs, + &state->hist.disre_rm3tav, list); + break; + case estORIRE_INITF: + ret = do_cpte_real(xd, part, i, sflags, &state->hist.orire_initf, list); + break; + case estORIRE_DTAV: + ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav, + &state->hist.orire_Dtav, list); + break; + case estPULLCOMPREVSTEP: + ret = doVector(xd, part, i, sflags, &state->pull_com_prev_step, list); + break; default: - gmx_fatal(FARGS, "Unknown state entry %d\n" - "You are reading a checkpoint file written by different code, which is not supported", i); + gmx_fatal(FARGS, + "Unknown state entry %d\n" + "You are reading a checkpoint file written by different code, which " + "is not supported", + i); } } } return ret; } -static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins, - FILE *list) +static int do_cpt_ekinstate(XDR* xd, int fflags, ekinstate_t* ekins, FILE* list) { - int ret = 0; + int ret = 0; const StatePart part = StatePart::kineticEnergy; for (int i = 0; (i < eeksNR && ret == 0); i++) { - if (fflags & (1<ekin_n, list); break; - case eeksEKINH: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh, list); break; - case eeksEKINF: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinf, list); break; - case eeksEKINO: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); break; - case eeksEKINTOTAL: ret = do_cpte_matrix(xd, part, i, fflags, ekins->ekin_total, list); break; - case eeksEKINSCALEF: ret = doVector(xd, part, i, fflags, &ekins->ekinscalef_nhc, list); break; - case eeksVSCALE: ret = doVector(xd, part, i, fflags, &ekins->vscale_nhc, list); break; - case eeksEKINSCALEH: ret = doVector(xd, part, i, fflags, &ekins->ekinscaleh_nhc, list); break; - case eeksDEKINDL: ret = do_cpte_real(xd, part, i, fflags, &ekins->dekindl, list); break; - case eeksMVCOS: ret = do_cpte_real(xd, part, i, fflags, &ekins->mvcos, list); break; + case eeksEKIN_N: + ret = do_cpte_int(xd, part, i, fflags, &ekins->ekin_n, list); + break; + case eeksEKINH: + ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh, list); + break; + case eeksEKINF: + ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinf, list); + break; + case eeksEKINO: + ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); + break; + case eeksEKINTOTAL: + ret = do_cpte_matrix(xd, part, i, fflags, ekins->ekin_total, list); + break; + case eeksEKINSCALEF: + ret = doVector(xd, part, i, fflags, &ekins->ekinscalef_nhc, list); + break; + case eeksVSCALE: + ret = doVector(xd, part, i, fflags, &ekins->vscale_nhc, list); + break; + case eeksEKINSCALEH: + ret = doVector(xd, part, i, fflags, &ekins->ekinscaleh_nhc, list); + break; + case eeksDEKINDL: + ret = do_cpte_real(xd, part, i, fflags, &ekins->dekindl, list); + break; + case eeksMVCOS: ret = do_cpte_real(xd, part, i, fflags, &ekins->mvcos, list); break; default: - gmx_fatal(FARGS, "Unknown ekin data state entry %d\n" - "You are probably reading a new checkpoint file with old code", i); + gmx_fatal(FARGS, + "Unknown ekin data state entry %d\n" + "You are probably reading a new checkpoint file with old code", + i); } } } @@ -1225,8 +1365,7 @@ static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins, } -static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, - int eSwapCoords, swaphistory_t *swapstate, FILE *list) +static int do_cpt_swapstate(XDR* xd, gmx_bool bRead, int eSwapCoords, swaphistory_t* swapstate, FILE* list) { int swap_cpt_version = 2; @@ -1241,7 +1380,8 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list); if (bRead && swap_cpt_version < 2) { - gmx_fatal(FARGS, "Cannot read checkpoint files that were written with old versions" + gmx_fatal(FARGS, + "Cannot read checkpoint files that were written with old versions" "of the ion/water position swapping protocol.\n"); } @@ -1259,7 +1399,7 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, { for (int ii = 0; ii < swapstate->nIonTypes; ii++) { - swapstateIons_t *gs = &swapstate->ionType[ii]; + swapstateIons_t* gs = &swapstate->ionType[ii]; if (bRead) { @@ -1279,7 +1419,7 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, do_cpt_int_err(xd, "swap influx net p", gs->inflow_net_p[ic], list); } - if (bRead && (nullptr == gs->nMolPast[ic]) ) + if (bRead && (nullptr == gs->nMolPast[ic])) { snew(gs->nMolPast[ic], swapstate->nAverage); } @@ -1303,7 +1443,7 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, { for (int ii = 0; ii < swapstate->nIonTypes; ii++) { - swapstateIons_t *gs = &swapstate->ionType[ii]; + swapstateIons_t* gs = &swapstate->ionType[ii]; if (bRead) { @@ -1329,7 +1469,7 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, /* Ion history */ for (int ii = 0; ii < swapstate->nIonTypes; ii++) { - swapstateIons_t *gs = &swapstate->ionType[ii]; + swapstateIons_t* gs = &swapstate->ionType[ii]; do_cpt_int_err(xd, "number of ions", &gs->nMol, list); @@ -1356,17 +1496,17 @@ static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, } else { - do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list); - do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list); + do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], + *swapstate->xc_old_whole_p[eChan0], list); + do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], + *swapstate->xc_old_whole_p[eChan1], list); } return 0; } -static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, - int fflags, energyhistory_t *enerhist, - FILE *list) +static int do_cpt_enerhist(XDR* xd, gmx_bool bRead, int fflags, energyhistory_t* enerhist, FILE* list) { int ret = 0; @@ -1375,10 +1515,11 @@ static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, return ret; } - GMX_RELEASE_ASSERT(enerhist != nullptr, "With energy history, we need a valid enerhist pointer"); + GMX_RELEASE_ASSERT(enerhist != nullptr, + "With energy history, we need a valid enerhist pointer"); /* This is stored/read for backward compatibility */ - int energyHistoryNumEnergies = 0; + int energyHistoryNumEnergies = 0; if (bRead) { enerhist->nsteps = 0; @@ -1391,22 +1532,38 @@ static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, energyHistoryNumEnergies = enerhist->ener_sum_sim.size(); } - delta_h_history_t *deltaH = enerhist->deltaHForeignLambdas.get(); + delta_h_history_t* deltaH = enerhist->deltaHForeignLambdas.get(); const StatePart part = StatePart::energyHistory; for (int i = 0; (i < eenhNR && ret == 0); i++) { - if (fflags & (1<(xd, part, i, fflags, &enerhist->ener_ave, list); break; - case eenhENERGY_SUM: ret = doVector(xd, part, i, fflags, &enerhist->ener_sum, list); break; - case eenhENERGY_NSUM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); break; - case eenhENERGY_SUM_SIM: ret = doVector(xd, part, i, fflags, &enerhist->ener_sum_sim, list); break; - case eenhENERGY_NSUM_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); break; - case eenhENERGY_NSTEPS: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); break; - case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); break; + case eenhENERGY_N: + ret = do_cpte_int(xd, part, i, fflags, &energyHistoryNumEnergies, list); + break; + case eenhENERGY_AVER: + ret = doVector(xd, part, i, fflags, &enerhist->ener_ave, list); + break; + case eenhENERGY_SUM: + ret = doVector(xd, part, i, fflags, &enerhist->ener_sum, list); + break; + case eenhENERGY_NSUM: + do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); + break; + case eenhENERGY_SUM_SIM: + ret = doVector(xd, part, i, fflags, &enerhist->ener_sum_sim, list); + break; + case eenhENERGY_NSUM_SIM: + do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); + break; + case eenhENERGY_NSTEPS: + do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); + break; + case eenhENERGY_NSTEPS_SIM: + do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); + break; case eenhENERGY_DELTA_H_NN: { int numDeltaH = 0; @@ -1420,7 +1577,7 @@ static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, if (deltaH == nullptr) { enerhist->deltaHForeignLambdas = std::make_unique(); - deltaH = enerhist->deltaHForeignLambdas.get(); + deltaH = enerhist->deltaHForeignLambdas.get(); } deltaH->dh.resize(numDeltaH); deltaH->start_lambda_set = FALSE; @@ -1434,30 +1591,32 @@ static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, } break; case eenhENERGY_DELTA_H_STARTTIME: - ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_time), list); break; + ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_time), list); + break; case eenhENERGY_DELTA_H_STARTLAMBDA: - ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_lambda), list); break; + ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_lambda), list); + break; default: - gmx_fatal(FARGS, "Unknown energy history entry %d\n" - "You are probably reading a new checkpoint file with old code", i); + gmx_fatal(FARGS, + "Unknown energy history entry %d\n" + "You are probably reading a new checkpoint file with old code", + i); } } } - if ((fflags & (1<ener_sum_sim = enerhist->ener_sum; } - if ( (fflags & (1<nsteps = enerhist->nsum; } - if ( (fflags & (1<nsteps_sim = enerhist->nsum_sim; @@ -1466,21 +1625,25 @@ static int do_cpt_enerhist(XDR *xd, gmx_bool bRead, return ret; } -static int doCptPullCoordHist(XDR *xd, PullCoordinateHistory *pullCoordHist, - const StatePart part, FILE *list) +static int doCptPullCoordHist(XDR* xd, PullCoordinateHistory* pullCoordHist, const StatePart part, FILE* list) { int ret = 0; int flags = 0; - flags |= ((1<valueRef), list); break; - case epullcoordh_VALUE_SUM: ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->value), list); break; + case epullcoordh_VALUE_REF_SUM: + ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->valueRef), list); + break; + case epullcoordh_VALUE_SUM: + ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->value), list); + break; case epullcoordh_DR01_SUM: for (int j = 0; j < DIM && ret == 0; j++) { @@ -1499,7 +1662,9 @@ static int doCptPullCoordHist(XDR *xd, PullCoordinateHistory *pullCoordHist, ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->dr45[j]), list); } break; - case epullcoordh_FSCAL_SUM: ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->scalarForce), list); break; + case epullcoordh_FSCAL_SUM: + ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->scalarForce), list); + break; case epullcoordh_DYNAX_SUM: for (int j = 0; j < DIM && ret == 0; j++) { @@ -1512,13 +1677,12 @@ static int doCptPullCoordHist(XDR *xd, PullCoordinateHistory *pullCoordHist, return ret; } -static int doCptPullGroupHist(XDR *xd, PullGroupHistory *pullGroupHist, - const StatePart part, FILE *list) +static int doCptPullGroupHist(XDR* xd, PullGroupHistory* pullGroupHist, const StatePart part, FILE* list) { int ret = 0; int flags = 0; - flags |= ((1<numValuesInXSum, list); break; - case epullhPULL_NUMVALUESINFSUM: do_cpt_int_err(xd, eenh_names[i], &pullHist->numValuesInFSum, list); break; + case epullhPULL_NUMCOORDINATES: + ret = do_cpte_int(xd, part, i, fflags, &pullHistoryNumCoordinates, list); + break; + case epullhPULL_NUMGROUPS: + do_cpt_int_err(xd, eenh_names[i], &pullHistoryNumGroups, list); + break; + case epullhPULL_NUMVALUESINXSUM: + do_cpt_int_err(xd, eenh_names[i], &pullHist->numValuesInXSum, list); + break; + case epullhPULL_NUMVALUESINFSUM: + do_cpt_int_err(xd, eenh_names[i], &pullHist->numValuesInFSum, list); + break; default: - gmx_fatal(FARGS, "Unknown pull history entry %d\n" - "You are probably reading a new checkpoint file with old code", i); + gmx_fatal(FARGS, + "Unknown pull history entry %d\n" + "You are probably reading a new checkpoint file with old code", + i); } } } @@ -1600,7 +1771,7 @@ static int doCptPullHist(XDR *xd, gmx_bool bRead, return ret; } -static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhistPtr, FILE *list) +static int do_cpt_df_hist(XDR* xd, int fflags, int nlambda, df_history_t** dfhistPtr, FILE* list) { int ret = 0; @@ -1615,33 +1786,63 @@ static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhis (*dfhistPtr)->nlambda = nlambda; init_df_history(*dfhistPtr, nlambda); } - df_history_t *dfhist = *dfhistPtr; + df_history_t* dfhist = *dfhistPtr; - const StatePart part = StatePart::freeEnergyHistory; + const StatePart part = StatePart::freeEnergyHistory; for (int i = 0; (i < edfhNR && ret == 0); i++) { - if (fflags & (1<bEquil, list); break; - case edfhNATLAMBDA: ret = do_cpte_ints(xd, part, i, fflags, nlambda, &dfhist->n_at_lam, list); break; - case edfhWLHISTO: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->wl_histo, list); break; - case edfhWLDELTA: ret = do_cpte_real(xd, part, i, fflags, &dfhist->wl_delta, list); break; - case edfhSUMWEIGHTS: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_weights, list); break; - case edfhSUMDG: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_dg, list); break; - case edfhSUMMINVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_minvar, list); break; - case edfhSUMVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_variance, list); break; - case edfhACCUMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p, list); break; - case edfhACCUMM: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m, list); break; - case edfhACCUMP2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p2, list); break; - case edfhACCUMM2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m2, list); break; - case edfhTIJ: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij, list); break; - case edfhTIJEMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij_empirical, list); break; + case edfhBEQUIL: + ret = do_cpte_bool(xd, part, i, fflags, &dfhist->bEquil, list); + break; + case edfhNATLAMBDA: + ret = do_cpte_ints(xd, part, i, fflags, nlambda, &dfhist->n_at_lam, list); + break; + case edfhWLHISTO: + ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->wl_histo, list); + break; + case edfhWLDELTA: + ret = do_cpte_real(xd, part, i, fflags, &dfhist->wl_delta, list); + break; + case edfhSUMWEIGHTS: + ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_weights, list); + break; + case edfhSUMDG: + ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_dg, list); + break; + case edfhSUMMINVAR: + ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_minvar, list); + break; + case edfhSUMVAR: + ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_variance, list); + break; + case edfhACCUMP: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p, list); + break; + case edfhACCUMM: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m, list); + break; + case edfhACCUMP2: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p2, list); + break; + case edfhACCUMM2: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m2, list); + break; + case edfhTIJ: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij, list); + break; + case edfhTIJEMP: + ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij_empirical, list); + break; default: - gmx_fatal(FARGS, "Unknown df history entry %d\n" - "You are probably reading a new checkpoint file with old code", i); + gmx_fatal(FARGS, + "Unknown df history entry %d\n" + "You are probably reading a new checkpoint file with old code", + i); } } } @@ -1653,16 +1854,15 @@ static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhis /* This function stores the last whole configuration of the reference and * average structure in the .cpt file */ -static int do_cpt_EDstate(XDR *xd, gmx_bool bRead, - int nED, edsamhistory_t *EDstate, FILE *list) +static int do_cpt_EDstate(XDR* xd, gmx_bool bRead, int nED, edsamhistory_t* EDstate, FILE* list) { if (nED == 0) { return 0; } - EDstate->bFromCpt = bRead; - EDstate->nED = nED; + EDstate->bFromCpt = bRead; + EDstate->nED = nED; /* When reading, init_edsam has not been called yet, * so we have to allocate memory first. */ @@ -1680,9 +1880,9 @@ static int do_cpt_EDstate(XDR *xd, gmx_bool bRead, char buf[STRLEN]; /* Reference structure SREF */ - sprintf(buf, "ED%d # of atoms in reference structure", i+1); + sprintf(buf, "ED%d # of atoms in reference structure", i + 1); do_cpt_int_err(xd, buf, &EDstate->nref[i], list); - sprintf(buf, "ED%d x_ref", i+1); + sprintf(buf, "ED%d x_ref", i + 1); if (bRead) { snew(EDstate->old_sref[i], EDstate->nref[i]); @@ -1694,9 +1894,9 @@ static int do_cpt_EDstate(XDR *xd, gmx_bool bRead, } /* Average structure SAV */ - sprintf(buf, "ED%d # of atoms in average structure", i+1); + sprintf(buf, "ED%d # of atoms in average structure", i + 1); do_cpt_int_err(xd, buf, &EDstate->nav[i], list); - sprintf(buf, "ED%d x_av", i+1); + sprintf(buf, "ED%d x_av", i + 1); if (bRead) { snew(EDstate->old_sav[i], EDstate->nav[i]); @@ -1711,9 +1911,12 @@ static int do_cpt_EDstate(XDR *xd, gmx_bool bRead, return 0; } -static int do_cpt_correlation_grid(XDR *xd, gmx_bool bRead, gmx_unused int fflags, - gmx::CorrelationGridHistory *corrGrid, - FILE *list, int eawhh) +static int do_cpt_correlation_grid(XDR* xd, + gmx_bool bRead, + gmx_unused int fflags, + gmx::CorrelationGridHistory* corrGrid, + FILE* list, + int eawhh) { int ret = 0; @@ -1723,10 +1926,11 @@ static int do_cpt_correlation_grid(XDR *xd, gmx_bool bRead, gmx_unused int fflag if (bRead) { - initCorrelationGridHistory(corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize, corrGrid->blockDataListSize); + initCorrelationGridHistory(corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize, + corrGrid->blockDataListSize); } - for (gmx::CorrelationBlockDataHistory &blockData : corrGrid->blockDataBuffer) + for (gmx::CorrelationBlockDataHistory& blockData : corrGrid->blockDataBuffer) { do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumWeight), list); do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumSquareWeight), list); @@ -1744,25 +1948,26 @@ static int do_cpt_correlation_grid(XDR *xd, gmx_bool bRead, gmx_unused int fflag return ret; } -static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead, - int fflags, gmx::AwhBiasHistory *biasHistory, - FILE *list) +static int do_cpt_awh_bias(XDR* xd, gmx_bool bRead, int fflags, gmx::AwhBiasHistory* biasHistory, FILE* list) { - int ret = 0; + int ret = 0; - gmx::AwhBiasStateHistory *state = &biasHistory->state; + gmx::AwhBiasStateHistory* state = &biasHistory->state; for (int i = 0; (i < eawhhNR && ret == 0); i++) { - if (fflags & (1<in_initial, list); break; + do_cpt_bool_err(xd, eawhh_names[i], &state->in_initial, list); + break; case eawhhEQUILIBRATEHISTOGRAM: - do_cpt_bool_err(xd, eawhh_names[i], &state->equilibrateHistogram, list); break; + do_cpt_bool_err(xd, eawhh_names[i], &state->equilibrateHistogram, list); + break; case eawhhHISTSIZE: - do_cpt_double_err(xd, eawhh_names[i], &state->histSize, list); break; + do_cpt_double_err(xd, eawhh_names[i], &state->histSize, list); + break; case eawhhNPOINTS: { int numPoints; @@ -1778,7 +1983,7 @@ static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead, } break; case eawhhCOORDPOINT: - for (auto &psh : biasHistory->pointState) + for (auto& psh : biasHistory->pointState) { do_cpt_double_err(xd, eawhh_names[i], &psh.target, list); do_cpt_double_err(xd, eawhh_names[i], &psh.free_energy, list); @@ -1794,7 +1999,8 @@ static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead, } break; case eawhhUMBRELLAGRIDPOINT: - do_cpt_int_err(xd, eawhh_names[i], &(state->umbrellaGridpoint), list); break; + do_cpt_int_err(xd, eawhh_names[i], &(state->umbrellaGridpoint), list); + break; case eawhhUPDATELIST: do_cpt_int_err(xd, eawhh_names[i], &(state->origin_index_updatelist), list); do_cpt_int_err(xd, eawhh_names[i], &(state->end_index_updatelist), list); @@ -1807,10 +2013,10 @@ static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead, do_cpt_step_err(xd, eawhh_names[i], &(state->numUpdates), list); break; case eawhhFORCECORRELATIONGRID: - ret = do_cpt_correlation_grid(xd, bRead, fflags, &biasHistory->forceCorrelationGrid, list, i); + ret = do_cpt_correlation_grid(xd, bRead, fflags, + &biasHistory->forceCorrelationGrid, list, i); break; - default: - gmx_fatal(FARGS, "Unknown awh history entry %d\n", i); + default: gmx_fatal(FARGS, "Unknown awh history entry %d\n", i); } } } @@ -1818,9 +2024,7 @@ static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead, return ret; } -static int do_cpt_awh(XDR *xd, gmx_bool bRead, - int fflags, gmx::AwhHistory *awhHistory, - FILE *list) +static int do_cpt_awh(XDR* xd, gmx_bool bRead, int fflags, gmx::AwhHistory* awhHistory, FILE* list) { int ret = 0; @@ -1830,7 +2034,8 @@ static int do_cpt_awh(XDR *xd, gmx_bool bRead, if (awhHistory == nullptr) { - GMX_RELEASE_ASSERT(bRead, "do_cpt_awh should not be called for writing without an AwhHistory"); + GMX_RELEASE_ASSERT(bRead, + "do_cpt_awh should not be called for writing without an AwhHistory"); awhHistoryLocal = std::make_shared(); awhHistory = awhHistoryLocal.get(); @@ -1857,7 +2062,7 @@ static int do_cpt_awh(XDR *xd, gmx_bool bRead, { awhHistory->bias.resize(numBias); } - for (auto &bias : awhHistory->bias) + for (auto& bias : awhHistory->bias) { ret = do_cpt_awh_bias(xd, bRead, fflags, &bias, list); if (ret) @@ -1870,21 +2075,23 @@ static int do_cpt_awh(XDR *xd, gmx_bool bRead, return ret; } -static void do_cpt_mdmodules(int fileVersion, t_fileio *checkpointFileHandle, const gmx::MdModulesNotifier &mdModulesNotifier) +static void do_cpt_mdmodules(int fileVersion, + t_fileio* checkpointFileHandle, + const gmx::MdModulesNotifier& mdModulesNotifier) { if (fileVersion >= cptv_MdModules) { - gmx::FileIOXdrSerializer serializer(checkpointFileHandle); - gmx::KeyValueTreeObject mdModuleCheckpointParameterTree = gmx::deserializeKeyValueTree(&serializer); - gmx::MdModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster - = { mdModuleCheckpointParameterTree, fileVersion }; + gmx::FileIOXdrSerializer serializer(checkpointFileHandle); + gmx::KeyValueTreeObject mdModuleCheckpointParameterTree = + gmx::deserializeKeyValueTree(&serializer); + gmx::MdModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster = { + mdModuleCheckpointParameterTree, fileVersion + }; mdModulesNotifier.notifier_.notify(mdModuleCheckpointReadingDataOnMaster); } } -static int do_cpt_files(XDR *xd, gmx_bool bRead, - std::vector *outputfiles, - FILE *list, int file_version) +static int do_cpt_files(XDR* xd, gmx_bool bRead, std::vector* outputfiles, FILE* list, int file_version) { gmx_off_t offset; gmx_off_t mask = 0xFFFFFFFFL; @@ -1904,7 +2111,7 @@ static int do_cpt_files(XDR *xd, gmx_bool bRead, outputfiles->resize(nfiles); } - for (auto &outputfile : *outputfiles) + for (auto& outputfile : *outputfiles) { /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */ if (bRead) @@ -1920,13 +2127,14 @@ static int do_cpt_files(XDR *xd, gmx_bool bRead, { return -1; } - outputfile.offset = (static_cast(offset_high) << 32 ) | ( static_cast(offset_low) & mask ); + outputfile.offset = (static_cast(offset_high) << 32) + | (static_cast(offset_low) & mask); } else { do_cpt_string_err(xd, "output filename", outputfile.filename, list); /* writing */ - offset = outputfile.offset; + offset = outputfile.offset; if (offset == -1) { offset_low = -1; @@ -1948,12 +2156,13 @@ static int do_cpt_files(XDR *xd, gmx_bool bRead, } if (file_version >= 8) { - if (do_cpt_int(xd, "file_checksum_size", &outputfile.checksumSize, - list) != 0) + if (do_cpt_int(xd, "file_checksum_size", &outputfile.checksumSize, list) != 0) { return -1; } - if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(), outputfile.checksum.data(), list) != 0) + if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(), + outputfile.checksum.data(), list) + != 0) { return -1; } @@ -1967,20 +2176,27 @@ static int do_cpt_files(XDR *xd, gmx_bool bRead, } -void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, - FILE *fplog, const t_commrec *cr, - ivec domdecCells, int nppnodes, - int eIntegrator, int simulation_part, - gmx_bool bExpanded, int elamstats, - int64_t step, double t, - t_state *state, ObservablesHistory *observablesHistory, - const gmx::MdModulesNotifier &mdModulesNotifier) -{ - t_fileio *fp; - char *fntemp; /* the temporary checkpoint file name */ - int npmenodes; - char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE]; - t_fileio *ret; +void write_checkpoint(const char* fn, + gmx_bool bNumberAndKeep, + FILE* fplog, + const t_commrec* cr, + ivec domdecCells, + int nppnodes, + int eIntegrator, + int simulation_part, + gmx_bool bExpanded, + int elamstats, + int64_t step, + double t, + t_state* state, + ObservablesHistory* observablesHistory, + const gmx::MdModulesNotifier& mdModulesNotifier) +{ + t_fileio* fp; + char* fntemp; /* the temporary checkpoint file name */ + int npmenodes; + char buf[1024], suffix[5 + STEPSTRSIZE], sbuf[STEPSTRSIZE]; + t_fileio* ret; if (DOMAINDECOMP(cr)) { @@ -1993,12 +2209,12 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, #if !GMX_NO_RENAME /* make the new temporary filename */ - snew(fntemp, std::strlen(fn)+5+STEPSTRSIZE); + snew(fntemp, std::strlen(fn) + 5 + STEPSTRSIZE); std::strcpy(fntemp, fn); fntemp[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0'; sprintf(suffix, "_%s%s", "step", gmx_step_str(step, sbuf)); std::strcat(fntemp, suffix); - std::strcat(fntemp, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1); + std::strcat(fntemp, fn + std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1); #else /* if we can't rename, we just overwrite the cpt file. * dangerous if interrupted. @@ -2010,8 +2226,7 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, if (fplog) { - fprintf(fplog, "Writing checkpoint, step %s at %s\n\n", - gmx_step_str(step, buf), timebuf.c_str()); + fprintf(fplog, "Writing checkpoint, step %s at %s\n\n", gmx_step_str(step, buf), timebuf.c_str()); } /* Get offsets for open files */ @@ -2022,60 +2237,58 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, int flags_eks; if (state->ekinstate.bUpToDate) { - flags_eks = - ((1<energyHistory.get(); + energyhistory_t* enerhist = observablesHistory->energyHistory.get(); int flags_enh = 0; if (enerhist != nullptr && (enerhist->nsum > 0 || enerhist->nsum_sim > 0)) { - flags_enh |= (1<nsum > 0) { - flags_enh |= ((1<nsum_sim > 0) { - flags_enh |= ((1<deltaHForeignLambdas != nullptr) { - flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) | - (1<< eenhENERGY_DELTA_H_LIST) | - (1<< eenhENERGY_DELTA_H_STARTTIME) | - (1<< eenhENERGY_DELTA_H_STARTLAMBDA) ); + flags_enh |= ((1 << eenhENERGY_DELTA_H_NN) | (1 << eenhENERGY_DELTA_H_LIST) + | (1 << eenhENERGY_DELTA_H_STARTTIME) | (1 << eenhENERGY_DELTA_H_STARTLAMBDA)); } } - PullHistory *pullHist = observablesHistory->pullHistory.get(); + PullHistory* pullHist = observablesHistory->pullHistory.get(); int flagsPullHistory = 0; if (pullHist != nullptr && (pullHist->numValuesInXSum > 0 || pullHist->numValuesInFSum > 0)) { - flagsPullHistory |= (1<awhHistory != nullptr && !state->awhHistory->bias.empty()) { - flags_awhh |= ( (1 << eawhhIN_INITIAL) | - (1 << eawhhEQUILIBRATEHISTOGRAM) | - (1 << eawhhHISTSIZE) | - (1 << eawhhNPOINTS) | - (1 << eawhhCOORDPOINT) | - (1 << eawhhUMBRELLAGRIDPOINT) | - (1 << eawhhUPDATELIST) | - (1 << eawhhLOGSCALEDSAMPLEWEIGHT) | - (1 << eawhhNUMUPDATES) | - (1 << eawhhFORCECORRELATIONGRID)); + flags_awhh |= ((1 << eawhhIN_INITIAL) | (1 << eawhhEQUILIBRATEHISTOGRAM) | (1 << eawhhHISTSIZE) + | (1 << eawhhNPOINTS) | (1 << eawhhCOORDPOINT) | (1 << eawhhUMBRELLAGRIDPOINT) + | (1 << eawhhUPDATELIST) | (1 << eawhhLOGSCALEDSAMPLEWEIGHT) + | (1 << eawhhNUMUPDATES) | (1 << eawhhFORCECORRELATIONGRID)); } /* We can check many more things now (CPU, acceleration, etc), but @@ -2103,24 +2310,42 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, * the same version, user, time, and build host! */ - int nlambda = (state->dfhist ? state->dfhist->nlambda : 0); - - edsamhistory_t *edsamhist = observablesHistory->edsamHistory.get(); - int nED = (edsamhist ? edsamhist->nED : 0); - - swaphistory_t *swaphist = observablesHistory->swapHistory.get(); - int eSwapCoords = (swaphist ? swaphist->eSwapCoords : eswapNO); - - CheckpointHeaderContents headerContents = - { - 0, {0}, {0}, {0}, {0}, GMX_DOUBLE, {0}, {0}, - eIntegrator, simulation_part, step, t, nppnodes, - {0}, npmenodes, - state->natoms, state->ngtc, state->nnhpres, - state->nhchainlength, nlambda, state->flags, flags_eks, flags_enh, - flagsPullHistory, flags_dfh, flags_awhh, - nED, eSwapCoords - }; + int nlambda = (state->dfhist ? state->dfhist->nlambda : 0); + + edsamhistory_t* edsamhist = observablesHistory->edsamHistory.get(); + int nED = (edsamhist ? edsamhist->nED : 0); + + swaphistory_t* swaphist = observablesHistory->swapHistory.get(); + int eSwapCoords = (swaphist ? swaphist->eSwapCoords : eswapNO); + + CheckpointHeaderContents headerContents = { 0, + { 0 }, + { 0 }, + { 0 }, + { 0 }, + GMX_DOUBLE, + { 0 }, + { 0 }, + eIntegrator, + simulation_part, + step, + t, + nppnodes, + { 0 }, + npmenodes, + state->natoms, + state->ngtc, + state->nnhpres, + state->nhchainlength, + nlambda, + state->flags, + flags_eks, + flags_enh, + flagsPullHistory, + flags_dfh, + flags_awhh, + nED, + eSwapCoords }; std::strcpy(headerContents.version, gmx_version()); std::strcpy(headerContents.fprog, gmx::getProgramContext().fullBinaryPath()); std::strcpy(headerContents.ftime, timebuf.c_str()); @@ -2131,16 +2356,16 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, do_cpt_header(gmx_fio_getxdr(fp), FALSE, nullptr, &headerContents); - if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0) || - (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr) < 0) || - (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, enerhist, nullptr) < 0) || - (doCptPullHist(gmx_fio_getxdr(fp), FALSE, flagsPullHistory, pullHist, StatePart::pullHistory, nullptr) < 0) || - (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr) < 0) || - (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, nED, edsamhist, nullptr) < 0) || - (do_cpt_awh(gmx_fio_getxdr(fp), FALSE, flags_awhh, state->awhHistory.get(), nullptr) < 0) || - (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, eSwapCoords, swaphist, nullptr) < 0) || - (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, nullptr, - headerContents.file_version) < 0)) + if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0) + || (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr) < 0) + || (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, enerhist, nullptr) < 0) + || (doCptPullHist(gmx_fio_getxdr(fp), FALSE, flagsPullHistory, pullHist, StatePart::pullHistory, nullptr) + < 0) + || (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr) < 0) + || (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, nED, edsamhist, nullptr) < 0) + || (do_cpt_awh(gmx_fio_getxdr(fp), FALSE, flags_awhh, state->awhHistory.get(), nullptr) < 0) + || (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, eSwapCoords, swaphist, nullptr) < 0) + || (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, nullptr, headerContents.file_version) < 0)) { gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?"); } @@ -2148,10 +2373,11 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, // Checkpointing MdModules { gmx::KeyValueTreeBuilder builder; - gmx::MdModulesWriteCheckpointData mdModulesWriteCheckpoint = {builder.rootObject(), headerContents.file_version}; + gmx::MdModulesWriteCheckpointData mdModulesWriteCheckpoint = { builder.rootObject(), + headerContents.file_version }; mdModulesNotifier.notifier_.notify(mdModulesWriteCheckpoint); - auto tree = builder.build(); - gmx::FileIOXdrSerializer serializer(fp); + auto tree = builder.build(); + gmx::FileIOXdrSerializer serializer(fp); gmx::serializeKeyValueTree(tree, &serializer); } @@ -2166,9 +2392,7 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, if (ret) { char buf[STRLEN]; - sprintf(buf, - "Cannot fsync '%s'; maybe you are out of disk space?", - gmx_fio_getname(ret)); + sprintf(buf, "Cannot fsync '%s'; maybe you are out of disk space?", gmx_fio_getname(ret)); if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV) == nullptr) { @@ -2196,7 +2420,7 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, std::strcpy(buf, fn); buf[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0'; std::strcat(buf, "_prev"); - std::strcat(buf, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1); + std::strcat(buf, fn + std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1); if (!GMX_FAHCORE) { /* we copy here so that if something goes wrong between now and @@ -2219,7 +2443,7 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?"); } } -#endif /* GMX_NO_RENAME */ +#endif /* GMX_NO_RENAME */ sfree(fntemp); @@ -2227,14 +2451,14 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, /*code for alternate checkpointing scheme. moved from top of loop over steps */ fcRequestCheckPoint(); - if (fcCheckPointParallel( cr->nodeid, NULL, 0) == 0) + if (fcCheckPointParallel(cr->nodeid, NULL, 0) == 0) { - gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step ); + gmx_fatal(3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step); } #endif /* end GMX_FAHCORE block */ } -static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm) +static void check_int(FILE* fplog, const char* type, int p, int f, gmx_bool* mm) { bool foundMismatch = (p != f); if (!foundMismatch) @@ -2251,8 +2475,7 @@ static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm) } } -static void check_string(FILE *fplog, const char *type, const char *p, - const char *f, gmx_bool *mm) +static void check_string(FILE* fplog, const char* type, const char* p, const char* f, gmx_bool* mm) { bool foundMismatch = (std::strcmp(p, f) != 0); if (!foundMismatch) @@ -2269,9 +2492,11 @@ static void check_string(FILE *fplog, const char *type, const char *p, } } -static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, - const CheckpointHeaderContents &headerContents, - gmx_bool reproducibilityRequested) +static void check_match(FILE* fplog, + const t_commrec* cr, + const ivec dd_nc, + const CheckpointHeaderContents& headerContents, + gmx_bool reproducibilityRequested) { /* Note that this check_string on the version will also print a message * when only the minor version differs. But we only print a warning @@ -2281,12 +2506,12 @@ static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, check_string(fplog, "Version", gmx_version(), headerContents.version, &versionDiffers); gmx_bool precisionDiffers = FALSE; - check_int (fplog, "Double prec.", GMX_DOUBLE, headerContents.double_prec, &precisionDiffers); + check_int(fplog, "Double prec.", GMX_DOUBLE, headerContents.double_prec, &precisionDiffers); if (precisionDiffers) { const char msg_precision_difference[] = - "You are continuing a simulation with a different precision. Not matching\n" - "single/double precision will lead to precision or performance loss.\n"; + "You are continuing a simulation with a different precision. Not matching\n" + "single/double precision will lead to precision or performance loss.\n"; if (fplog) { fprintf(fplog, "%s\n", msg_precision_difference); @@ -2297,14 +2522,15 @@ static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, if (reproducibilityRequested) { - check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), headerContents.fprog, &mm); + check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), + headerContents.fprog, &mm); - check_int (fplog, "#ranks", cr->nnodes, headerContents.nnodes, &mm); + check_int(fplog, "#ranks", cr->nnodes, headerContents.nnodes, &mm); } if (cr->nnodes > 1 && reproducibilityRequested) { - check_int (fplog, "#PME-ranks", cr->npmenodes, headerContents.npme, &mm); + check_int(fplog, "#PME-ranks", cr->npmenodes, headerContents.npme, &mm); int npp = cr->nnodes; if (cr->npmenodes >= 0) @@ -2318,9 +2544,9 @@ static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, } if (npp == npp_f) { - check_int (fplog, "#DD-cells[x]", dd_nc[XX], headerContents.dd_nc[XX], &mm); - check_int (fplog, "#DD-cells[y]", dd_nc[YY], headerContents.dd_nc[YY], &mm); - check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], headerContents.dd_nc[ZZ], &mm); + check_int(fplog, "#DD-cells[x]", dd_nc[XX], headerContents.dd_nc[XX], &mm); + check_int(fplog, "#DD-cells[y]", dd_nc[YY], headerContents.dd_nc[YY], &mm); + check_int(fplog, "#DD-cells[z]", dd_nc[ZZ], headerContents.dd_nc[ZZ], &mm); } } @@ -2330,24 +2556,24 @@ static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, * different patch level versions, but we do not guarantee * compatibility between different major/minor versions - check this. */ - int gmx_major; - int cpt_major; + int gmx_major; + int cpt_major; sscanf(gmx_version(), "%5d", &gmx_major); - int ret = sscanf(headerContents.version, "%5d", &cpt_major); - gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major); + int ret = sscanf(headerContents.version, "%5d", &cpt_major); + gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major); const char msg_major_version_difference[] = - "The current GROMACS major version is not identical to the one that\n" - "generated the checkpoint file. In principle GROMACS does not support\n" - "continuation from checkpoints between different versions, so we advise\n" - "against this. If you still want to try your luck we recommend that you use\n" - "the -noappend flag to keep your output files from the two versions separate.\n" - "This might also work around errors where the output fields in the energy\n" - "file have changed between the different versions.\n"; + "The current GROMACS major version is not identical to the one that\n" + "generated the checkpoint file. In principle GROMACS does not support\n" + "continuation from checkpoints between different versions, so we advise\n" + "against this. If you still want to try your luck we recommend that you use\n" + "the -noappend flag to keep your output files from the two versions separate.\n" + "This might also work around errors where the output fields in the energy\n" + "file have changed between the different versions.\n"; const char msg_mismatch_notice[] = - "GROMACS patchlevel, binary or parallel settings differ from previous run.\n" - "Continuation is exact, but not guaranteed to be binary identical.\n"; + "GROMACS patchlevel, binary or parallel settings differ from previous run.\n" + "Continuation is exact, but not guaranteed to be binary identical.\n"; if (majorVersionDiffers) { @@ -2367,20 +2593,21 @@ static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc, } } -static void read_checkpoint(const char *fn, t_fileio *logfio, - const t_commrec *cr, - const ivec dd_nc, - int eIntegrator, - int *init_fep_state, - CheckpointHeaderContents *headerContents, - t_state *state, - ObservablesHistory *observablesHistory, - gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier &mdModulesNotifier) -{ - t_fileio *fp; - char buf[STEPSTRSIZE]; - int ret; +static void read_checkpoint(const char* fn, + t_fileio* logfio, + const t_commrec* cr, + const ivec dd_nc, + int eIntegrator, + int* init_fep_state, + CheckpointHeaderContents* headerContents, + t_state* state, + ObservablesHistory* observablesHistory, + gmx_bool reproducibilityRequested, + const gmx::MdModulesNotifier& mdModulesNotifier) +{ + t_fileio* fp; + char buf[STEPSTRSIZE]; + int ret; fp = gmx_fio_open(fn, "r"); do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, headerContents); @@ -2390,7 +2617,7 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, // that case, the filehandle will be nullptr. Otherwise, we report // to the new log file about the checkpoint file that we are // reading from. - FILE *fplog = gmx_fio_getfp(logfio); + FILE* fplog = gmx_fio_getfp(logfio); if (fplog) { fprintf(fplog, "\n"); @@ -2406,45 +2633,63 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, if (headerContents->natoms != state->natoms) { - gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", headerContents->natoms, state->natoms); + gmx_fatal(FARGS, + "Checkpoint file is for a system of %d atoms, while the current system consists " + "of %d atoms", + headerContents->natoms, state->natoms); } if (headerContents->ngtc != state->ngtc) { - gmx_fatal(FARGS, "Checkpoint file is for a system of %d T-coupling groups, while the current system consists of %d T-coupling groups", headerContents->ngtc, state->ngtc); + gmx_fatal(FARGS, + "Checkpoint file is for a system of %d T-coupling groups, while the current " + "system consists of %d T-coupling groups", + headerContents->ngtc, state->ngtc); } if (headerContents->nnhpres != state->nnhpres) { - gmx_fatal(FARGS, "Checkpoint file is for a system of %d NH-pressure-coupling variables, while the current system consists of %d NH-pressure-coupling variables", headerContents->nnhpres, state->nnhpres); + gmx_fatal(FARGS, + "Checkpoint file is for a system of %d NH-pressure-coupling variables, while the " + "current system consists of %d NH-pressure-coupling variables", + headerContents->nnhpres, state->nnhpres); } int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0); if (headerContents->nlambda != nlambdaHistory) { - gmx_fatal(FARGS, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", headerContents->nlambda, nlambdaHistory); + gmx_fatal(FARGS, + "Checkpoint file is for a system with %d lambda states, while the current system " + "consists of %d lambda states", + headerContents->nlambda, nlambdaHistory); } - init_gtc_state(state, state->ngtc, state->nnhpres, headerContents->nhchainlength); /* need to keep this here to keep the tpr format working */ + init_gtc_state(state, state->ngtc, state->nnhpres, + headerContents->nhchainlength); /* need to keep this here to keep the tpr format working */ /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */ if (headerContents->eIntegrator != eIntegrator) { - gmx_fatal(FARGS, "Cannot change integrator during a checkpoint restart. Perhaps you should make a new .tpr with grompp -f new.mdp -t %s", fn); + gmx_fatal(FARGS, + "Cannot change integrator during a checkpoint restart. Perhaps you should make a " + "new .tpr with grompp -f new.mdp -t %s", + fn); } if (headerContents->flags_state != state->flags) { - gmx_fatal(FARGS, "Cannot change a simulation algorithm during a checkpoint restart. Perhaps you should make a new .tpr with grompp -f new.mdp -t %s", fn); + gmx_fatal(FARGS, + "Cannot change a simulation algorithm during a checkpoint restart. Perhaps you " + "should make a new .tpr with grompp -f new.mdp -t %s", + fn); } if (MASTER(cr)) { - check_match(fplog, cr, dd_nc, *headerContents, - reproducibilityRequested); + check_match(fplog, cr, dd_nc, *headerContents, reproducibilityRequested); } ret = do_cpt_state(gmx_fio_getxdr(fp), headerContents->flags_state, state, nullptr); - *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it here. - Investigate for 5.0. */ + *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it + here. Investigate for 5.0. */ if (ret) { cp_error(); @@ -2454,19 +2699,20 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, { cp_error(); } - state->ekinstate.hasReadEkinState = (((headerContents->flags_eks & (1<flags_eks & (1<flags_eks & (1<flags_eks & (1<flags_eks & (1<flags_eks & (1<ekinstate.hasReadEkinState = (((headerContents->flags_eks & (1 << eeksEKINH)) != 0) + || ((headerContents->flags_eks & (1 << eeksEKINF)) != 0) + || ((headerContents->flags_eks & (1 << eeksEKINO)) != 0) + || (((headerContents->flags_eks & (1 << eeksEKINSCALEF)) + | (headerContents->flags_eks & (1 << eeksEKINSCALEH)) + | (headerContents->flags_eks & (1 << eeksVSCALE))) + != 0)); if (headerContents->flags_enh && observablesHistory->energyHistory == nullptr) { observablesHistory->energyHistory = std::make_unique(); } - ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, - headerContents->flags_enh, observablesHistory->energyHistory.get(), nullptr); + ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents->flags_enh, + observablesHistory->energyHistory.get(), nullptr); if (ret) { cp_error(); @@ -2478,8 +2724,8 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, { observablesHistory->pullHistory = std::make_unique(); } - ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, - headerContents->flagsPullHistory, observablesHistory->pullHistory.get(), StatePart::pullHistory, nullptr); + ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents->flagsPullHistory, + observablesHistory->pullHistory.get(), StatePart::pullHistory, nullptr); if (ret) { cp_error(); @@ -2488,10 +2734,12 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, if (headerContents->file_version < 6) { - gmx_fatal(FARGS, "Continuing from checkpoint files written before GROMACS 4.5 is not supported"); + gmx_fatal(FARGS, + "Continuing from checkpoint files written before GROMACS 4.5 is not supported"); } - ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda, &state->dfhist, nullptr); + ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda, + &state->dfhist, nullptr); if (ret) { cp_error(); @@ -2499,9 +2747,10 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, if (headerContents->nED > 0 && observablesHistory->edsamHistory == nullptr) { - observablesHistory->edsamHistory = std::make_unique(edsamhistory_t {}); + observablesHistory->edsamHistory = std::make_unique(edsamhistory_t{}); } - ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents->nED, observablesHistory->edsamHistory.get(), nullptr); + ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents->nED, + observablesHistory->edsamHistory.get(), nullptr); if (ret) { cp_error(); @@ -2511,8 +2760,7 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, { state->awhHistory = std::make_shared(); } - ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, - headerContents->flags_awhh, state->awhHistory.get(), nullptr); + ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents->flags_awhh, state->awhHistory.get(), nullptr); if (ret) { cp_error(); @@ -2520,9 +2768,10 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, if (headerContents->eSwapCoords != eswapNO && observablesHistory->swapHistory == nullptr) { - observablesHistory->swapHistory = std::make_unique(swaphistory_t {}); + observablesHistory->swapHistory = std::make_unique(swaphistory_t{}); } - ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords, observablesHistory->swapHistory.get(), nullptr); + ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords, + observablesHistory->swapHistory.get(), nullptr); if (ret) { cp_error(); @@ -2547,31 +2796,30 @@ static void read_checkpoint(const char *fn, t_fileio *logfio, } -void load_checkpoint(const char *fn, t_fileio *logfio, - const t_commrec *cr, const ivec dd_nc, - t_inputrec *ir, t_state *state, - ObservablesHistory *observablesHistory, - gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier &mdModulesNotifier) +void load_checkpoint(const char* fn, + t_fileio* logfio, + const t_commrec* cr, + const ivec dd_nc, + t_inputrec* ir, + t_state* state, + ObservablesHistory* observablesHistory, + gmx_bool reproducibilityRequested, + const gmx::MdModulesNotifier& mdModulesNotifier) { CheckpointHeaderContents headerContents; if (SIMMASTER(cr)) { /* Read the state from the checkpoint file */ - read_checkpoint(fn, logfio, - cr, dd_nc, - ir->eI, &(ir->fepvals->init_fep_state), - &headerContents, - state, observablesHistory, - reproducibilityRequested, mdModulesNotifier); + read_checkpoint(fn, logfio, cr, dd_nc, ir->eI, &(ir->fepvals->init_fep_state), &headerContents, + state, observablesHistory, reproducibilityRequested, mdModulesNotifier); } if (PAR(cr)) { gmx_bcast(sizeof(headerContents.step), &headerContents.step, cr); - gmx::MdModulesCheckpointReadingBroadcast broadcastCheckPointData = {*cr, headerContents.file_version}; + gmx::MdModulesCheckpointReadingBroadcast broadcastCheckPointData = { *cr, headerContents.file_version }; mdModulesNotifier.notifier_.notify(broadcastCheckPointData); } - ir->bContinuation = TRUE; + ir->bContinuation = TRUE; // TODO Should the following condition be <=? Currently if you // pass a checkpoint written by an normal completion to a restart, // mdrun will read all input, does some work but no steps, and @@ -2583,7 +2831,8 @@ void load_checkpoint(const char *fn, t_fileio *logfio, char nstepsString[STEPSTRSIZE], stepString[STEPSTRSIZE]; gmx_step_str(ir->nsteps, nstepsString); gmx_step_str(headerContents.step, stepString); - gmx_fatal(FARGS, "The input requested %s steps, however the checkpoint " + gmx_fatal(FARGS, + "The input requested %s steps, however the checkpoint " "file has already reached step %s. The simulation will not " "proceed, because either your simulation is already complete, " "or your combination of input files don't match.", @@ -2591,21 +2840,17 @@ void load_checkpoint(const char *fn, t_fileio *logfio, } if (ir->nsteps >= 0) { - ir->nsteps += ir->init_step - headerContents.step; + ir->nsteps += ir->init_step - headerContents.step; } - ir->init_step = headerContents.step; - ir->simulation_part = headerContents.simulation_part + 1; + ir->init_step = headerContents.step; + ir->simulation_part = headerContents.simulation_part + 1; } -void read_checkpoint_part_and_step(const char *filename, - int *simulation_part, - int64_t *step) +void read_checkpoint_part_and_step(const char* filename, int* simulation_part, int64_t* step) { - t_fileio *fp; + t_fileio* fp; - if (filename == nullptr || - !gmx_fexist(filename) || - ((fp = gmx_fio_open(filename, "r")) == nullptr)) + if (filename == nullptr || !gmx_fexist(filename) || ((fp = gmx_fio_open(filename, "r")) == nullptr)) { *simulation_part = 0; *step = 0; @@ -2619,10 +2864,9 @@ void read_checkpoint_part_and_step(const char *filename, *step = headerContents.step; } -static CheckpointHeaderContents -read_checkpoint_data(t_fileio *fp, - t_state *state, - std::vector *outputfiles) +static CheckpointHeaderContents read_checkpoint_data(t_fileio* fp, + t_state* state, + std::vector* outputfiles) { CheckpointHeaderContents headerContents; do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents); @@ -2631,8 +2875,7 @@ read_checkpoint_data(t_fileio *fp, state->nnhpres = headerContents.nnhpres; state->nhchainlength = headerContents.nhchainlength; state->flags = headerContents.flags_state; - int ret = - do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr); + int ret = do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr); if (ret) { cp_error(); @@ -2644,21 +2887,21 @@ read_checkpoint_data(t_fileio *fp, } energyhistory_t enerhist; - ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, - headerContents.flags_enh, &enerhist, nullptr); + ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents.flags_enh, &enerhist, nullptr); if (ret) { cp_error(); } PullHistory pullHist = {}; - ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, - headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, nullptr); + ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, + StatePart::pullHistory, nullptr); if (ret) { cp_error(); } - ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr); + ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, + &state->dfhist, nullptr); if (ret) { cp_error(); @@ -2671,8 +2914,7 @@ read_checkpoint_data(t_fileio *fp, cp_error(); } - ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, - headerContents.flags_awhh, state->awhHistory.get(), nullptr); + ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents.flags_awhh, state->awhHistory.get(), nullptr); if (ret) { cp_error(); @@ -2685,9 +2927,7 @@ read_checkpoint_data(t_fileio *fp, cp_error(); } - ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, - outputfiles, - nullptr, headerContents.file_version); + ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, outputfiles, nullptr, headerContents.file_version); if (ret) { @@ -2703,47 +2943,45 @@ read_checkpoint_data(t_fileio *fp, return headerContents; } -void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr) +void read_checkpoint_trxframe(t_fileio* fp, t_trxframe* fr) { t_state state; std::vector outputfiles; - CheckpointHeaderContents headerContents = - read_checkpoint_data(fp, &state, &outputfiles); - - fr->natoms = state.natoms; - fr->bStep = TRUE; - fr->step = int64_to_int(headerContents.step, - "conversion of checkpoint to trajectory"); - fr->bTime = TRUE; - fr->time = headerContents.t; - fr->bLambda = TRUE; - fr->lambda = state.lambda[efptFEP]; - fr->fep_state = state.fep_state; - fr->bAtoms = FALSE; - fr->bX = ((state.flags & (1<natoms = state.natoms; + fr->bStep = TRUE; + fr->step = int64_to_int(headerContents.step, "conversion of checkpoint to trajectory"); + fr->bTime = TRUE; + fr->time = headerContents.t; + fr->bLambda = TRUE; + fr->lambda = state.lambda[efptFEP]; + fr->fep_state = state.fep_state; + fr->bAtoms = FALSE; + fr->bX = ((state.flags & (1 << estX)) != 0); if (fr->bX) { - fr->x = makeRvecArray(state.x, state.natoms); + fr->x = makeRvecArray(state.x, state.natoms); } - fr->bV = ((state.flags & (1<bV = ((state.flags & (1 << estV)) != 0); if (fr->bV) { - fr->v = makeRvecArray(state.v, state.natoms); + fr->v = makeRvecArray(state.v, state.natoms); } - fr->bF = FALSE; - fr->bBox = ((state.flags & (1<bF = FALSE; + fr->bBox = ((state.flags & (1 << estBOX)) != 0); if (fr->bBox) { copy_mat(state.box, fr->box); } } -void list_checkpoint(const char *fn, FILE *out) +void list_checkpoint(const char* fn, FILE* out) { - t_fileio *fp; - int ret; + t_fileio* fp; + int ret; - t_state state; + t_state state; fp = gmx_fio_open(fn, "r"); CheckpointHeaderContents headerContents; @@ -2765,20 +3003,19 @@ void list_checkpoint(const char *fn, FILE *out) } energyhistory_t enerhist; - ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, - headerContents.flags_enh, &enerhist, out); + ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents.flags_enh, &enerhist, out); if (ret == 0) { PullHistory pullHist = {}; - ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, - headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, out); + ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, + StatePart::pullHistory, out); } if (ret == 0) { - ret = do_cpt_df_hist(gmx_fio_getxdr(fp), - headerContents.flags_dfh, headerContents.nlambda, &state.dfhist, out); + ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, + &state.dfhist, out); } if (ret == 0) @@ -2789,8 +3026,7 @@ void list_checkpoint(const char *fn, FILE *out) if (ret == 0) { - ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, - headerContents.flags_awhh, state.awhHistory.get(), out); + ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents.flags_awhh, state.awhHistory.get(), out); } if (ret == 0) @@ -2821,13 +3057,11 @@ void list_checkpoint(const char *fn, FILE *out) } /* This routine cannot print tons of data, since it is called before the log file is opened. */ -CheckpointHeaderContents -read_checkpoint_simulation_part_and_filenames(t_fileio *fp, - std::vector *outputfiles) +CheckpointHeaderContents read_checkpoint_simulation_part_and_filenames(t_fileio* fp, + std::vector* outputfiles) { t_state state; - CheckpointHeaderContents headerContents = - read_checkpoint_data(fp, &state, outputfiles); + CheckpointHeaderContents headerContents = read_checkpoint_data(fp, &state, outputfiles); if (gmx_fio_close(fp) != 0) { gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?"); diff --git a/src/gromacs/fileio/checkpoint.h b/src/gromacs/fileio/checkpoint.h index db1d62f11e..c15e7321af 100644 --- a/src/gromacs/fileio/checkpoint.h +++ b/src/gromacs/fileio/checkpoint.h @@ -64,9 +64,9 @@ class KeyValueTreeObject; struct MdModulesCheckpointReadingDataOnMaster { //! The data of the MdModules that is stored in the checkpoint file - const KeyValueTreeObject &checkpointedData_; + const KeyValueTreeObject& checkpointedData_; //! The version of the read ceckpoint file - int checkpointFileVersion_; + int checkpointFileVersion_; }; /*! \libinternal @@ -75,9 +75,9 @@ struct MdModulesCheckpointReadingDataOnMaster struct MdModulesCheckpointReadingBroadcast { //! The communication record - const t_commrec &cr_; + const t_commrec& cr_; //! The version of the read file version - int checkpointFileVersion_; + int checkpointFileVersion_; }; /*! \libinternal \brief Writing the MdModules data to a checkpoint file. @@ -87,7 +87,7 @@ struct MdModulesWriteCheckpointData //! Builder for the Key-Value-Tree to store the MdModule checkpoint data KeyValueTreeObjectBuilder builder_; //! The version of the read file version - int checkpointFileVersion_; + int checkpointFileVersion_; }; } // namespace gmx @@ -118,75 +118,82 @@ struct MdModulesWriteCheckpointData struct CheckpointHeaderContents { //! Version of checkpoint file read from disk. - int file_version; + int file_version; //! Version string. - char version[CPTSTRLEN]; + char version[CPTSTRLEN]; //! Deprecated string for time. - char btime_UNUSED[CPTSTRLEN]; + char btime_UNUSED[CPTSTRLEN]; //! Deprecated string for user. - char buser_UNUSED[CPTSTRLEN]; + char buser_UNUSED[CPTSTRLEN]; //! Deprecated string for host. - char bhost_UNUSED[CPTSTRLEN]; + char bhost_UNUSED[CPTSTRLEN]; //! Value for precision. - int double_prec; + int double_prec; //! Program string. - char fprog[CPTSTRLEN]; + char fprog[CPTSTRLEN]; //! Time string. - char ftime[CPTSTRLEN]; + char ftime[CPTSTRLEN]; //! Which integrator is in use. - int eIntegrator; + int eIntegrator; //! Which part of the simulation this is. - int simulation_part; + int simulation_part; //! Which step the checkpoint is at. - int64_t step; + int64_t step; //! Current simulation time. - double t; + double t; //! Number of nodes used for simulation, - int nnodes; + int nnodes; //! Domain decomposition settings? - ivec dd_nc; + ivec dd_nc; //! Number of separate PME ranks. - int npme; + int npme; //! Number of atoms. - int natoms; + int natoms; //! Number of temperature coupling groups. - int ngtc; + int ngtc; //! Number of Nose-Hoover pressure coupling chains. - int nnhpres; + int nnhpres; //! Length of Nose-Hoover chains. - int nhchainlength; + int nhchainlength; //! Current FEP lambda state. - int nlambda; + int nlambda; //! Current state flags. - int flags_state; + int flags_state; //! Flags for kinetic energy. - int flags_eks; + int flags_eks; //! Flags for energy history. - int flags_enh; + int flags_enh; //! Flags for pull history. - int flagsPullHistory; + int flagsPullHistory; //! Flags for mystery history. - int flags_dfh; + int flags_dfh; //! Flags for AWH history. - int flags_awhh; + int flags_awhh; //! Essential dynamics states. - int nED; + int nED; //! Enum for coordinate swapping. - int eSwapCoords; + int eSwapCoords; }; /* Write a checkpoint to .cpt * Appends the _step.cpt with bNumberAndKeep, * otherwise moves the previous .cpt to _prev.cpt */ -void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, - FILE *fplog, const t_commrec *cr, - ivec domdecCells, int nppnodes, - int eIntegrator, int simulation_part, - gmx_bool bExpanded, int elamstats, - int64_t step, double t, - t_state *state, ObservablesHistory *observablesHistory, - const gmx::MdModulesNotifier ¬ifier); +void write_checkpoint(const char* fn, + gmx_bool bNumberAndKeep, + FILE* fplog, + const t_commrec* cr, + ivec domdecCells, + int nppnodes, + int eIntegrator, + int simulation_part, + gmx_bool bExpanded, + int elamstats, + int64_t step, + double t, + t_state* state, + ObservablesHistory* observablesHistory, + const gmx::MdModulesNotifier& notifier); /* Loads a checkpoint from fn for run continuation. * Generates a fatal error on system size mismatch. @@ -195,18 +202,21 @@ void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep, * but not the state itself. * With reproducibilityRequested warns about version, build, #ranks differences. */ -void load_checkpoint(const char *fn, t_fileio *logfio, - const t_commrec *cr, const ivec dd_nc, - t_inputrec *ir, t_state *state, - ObservablesHistory *observablesHistory, - gmx_bool reproducibilityRequested, - const gmx::MdModulesNotifier &mdModulesNotifier); +void load_checkpoint(const char* fn, + t_fileio* logfio, + const t_commrec* cr, + const ivec dd_nc, + t_inputrec* ir, + t_state* state, + ObservablesHistory* observablesHistory, + gmx_bool reproducibilityRequested, + const gmx::MdModulesNotifier& mdModulesNotifier); /* Read everything that can be stored in t_trxframe from a checkpoint file */ -void read_checkpoint_trxframe(struct t_fileio *fp, t_trxframe *fr); +void read_checkpoint_trxframe(struct t_fileio* fp, t_trxframe* fr); /* Print the complete contents of checkpoint file fn to out */ -void list_checkpoint(const char *fn, FILE *out); +void list_checkpoint(const char* fn, FILE* out); /*!\brief Read simulation step and part from a checkpoint file * @@ -218,9 +228,7 @@ void list_checkpoint(const char *fn, FILE *out); * * The output variables will both contain 0 if filename is NULL, the file * does not exist, or is not readable. */ -void read_checkpoint_part_and_step(const char *filename, - int *simulation_part, - int64_t *step); +void read_checkpoint_part_and_step(const char* filename, int* simulation_part, int64_t* step); /*!\brief Return header information from an open checkpoint file. * @@ -229,7 +237,6 @@ void read_checkpoint_part_and_step(const char *filename, * \param[in] fp Handle to open checkpoint file * \param[out] outputfiles Container of output file names from the previous run. */ CheckpointHeaderContents -read_checkpoint_simulation_part_and_filenames(t_fileio *fp, - std::vector *outputfiles); +read_checkpoint_simulation_part_and_filenames(t_fileio* fp, std::vector* outputfiles); #endif diff --git a/src/gromacs/fileio/confio.cpp b/src/gromacs/fileio/confio.cpp index f5638b366f..f822d09be5 100644 --- a/src/gromacs/fileio/confio.cpp +++ b/src/gromacs/fileio/confio.cpp @@ -61,14 +61,19 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -void write_sto_conf_indexed(const char *outfile, const char *title, - const t_atoms *atoms, - const rvec x[], const rvec *v, int ePBC, const matrix box, - int nindex, int index[]) +void write_sto_conf_indexed(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box, + int nindex, + int index[]) { - FILE *out; - int ftp; - t_trxframe fr; + FILE* out; + int ftp; + t_trxframe fr; ftp = fn2ftp(outfile); switch (ftp) @@ -82,13 +87,13 @@ void write_sto_conf_indexed(const char *outfile, const char *title, clear_trxframe(&fr, TRUE); fr.natoms = atoms->nr; fr.bAtoms = TRUE; - fr.atoms = const_cast(atoms); + fr.atoms = const_cast(atoms); fr.bX = TRUE; - fr.x = const_cast(x); + fr.x = const_cast(x); if (v) { fr.bV = TRUE; - fr.v = const_cast(v); + fr.v = const_cast(v); } fr.bBox = TRUE; copy_mat(box, fr.box); @@ -101,7 +106,8 @@ void write_sto_conf_indexed(const char *outfile, const char *title, case efENT: case efPQR: out = gmx_fio_fopen(outfile, "w"); - write_pdbfile_indexed(out, title, atoms, x, ePBC, box, ' ', -1, nindex, index, nullptr, ftp == efPQR); + write_pdbfile_indexed(out, title, atoms, x, ePBC, box, ' ', -1, nindex, index, nullptr, + ftp == efPQR); gmx_fio_fclose(out); break; case efESP: @@ -109,37 +115,38 @@ void write_sto_conf_indexed(const char *outfile, const char *title, write_espresso_conf_indexed(out, title, atoms, nindex, index, x, v, box); gmx_fio_fclose(out); break; - case efTPR: - gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile); - default: - gmx_incons("Not supported in write_sto_conf_indexed"); + case efTPR: gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile); + default: gmx_incons("Not supported in write_sto_conf_indexed"); } } -void write_sto_conf(const char *outfile, const char *title, const t_atoms *atoms, - const rvec x[], const rvec *v, int ePBC, const matrix box) +void write_sto_conf(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box) { - FILE *out; - int ftp; - t_trxframe fr; + FILE* out; + int ftp; + t_trxframe fr; ftp = fn2ftp(outfile); switch (ftp) { - case efGRO: - write_conf_p(outfile, title, atoms, x, v, box); - break; + case efGRO: write_conf_p(outfile, title, atoms, x, v, box); break; case efG96: clear_trxframe(&fr, TRUE); fr.natoms = atoms->nr; fr.bAtoms = TRUE; - fr.atoms = const_cast(atoms); // TODO check + fr.atoms = const_cast(atoms); // TODO check fr.bX = TRUE; - fr.x = const_cast(x); + fr.x = const_cast(x); if (v) { fr.bV = TRUE; - fr.v = const_cast(v); + fr.v = const_cast(v); } fr.bBox = TRUE; copy_mat(box, fr.box); @@ -159,19 +166,21 @@ void write_sto_conf(const char *outfile, const char *title, const t_atoms *atoms write_espresso_conf_indexed(out, title, atoms, atoms->nr, nullptr, x, v, box); gmx_fio_fclose(out); break; - case efTPR: - gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile); - default: - gmx_incons("Not supported in write_sto_conf"); + case efTPR: gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile); + default: gmx_incons("Not supported in write_sto_conf"); } } -void write_sto_conf_mtop(const char *outfile, const char *title, - const gmx_mtop_t *mtop, - const rvec x[], const rvec *v, int ePBC, const matrix box) +void write_sto_conf_mtop(const char* outfile, + const char* title, + const gmx_mtop_t* mtop, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box) { int ftp; - FILE *out; + FILE* out; t_atoms atoms; ftp = fn2ftp(outfile); @@ -195,20 +204,18 @@ void write_sto_conf_mtop(const char *outfile, const char *title, } } -static void get_stx_coordnum(const char *infile, int *natoms) +static void get_stx_coordnum(const char* infile, int* natoms) { - FILE *in; + FILE* in; int ftp; t_trxframe fr; - char g96_line[STRLEN+1]; + char g96_line[STRLEN + 1]; ftp = fn2ftp(infile); range_check(ftp, 0, efNR); switch (ftp) { - case efGRO: - get_coordnum(infile, natoms); - break; + case efGRO: get_coordnum(infile, natoms); break; case efG96: { in = gmx_fio_fopen(infile, "r"); @@ -228,42 +235,33 @@ static void get_stx_coordnum(const char *infile, int *natoms) get_pdb_coordnum(in, natoms); gmx_fio_fclose(in); break; - case efESP: - *natoms = get_espresso_coordnum(infile); - break; - default: - gmx_fatal(FARGS, "File type %s not supported in get_stx_coordnum", - ftp2ext(ftp)); + case efESP: *natoms = get_espresso_coordnum(infile); break; + default: gmx_fatal(FARGS, "File type %s not supported in get_stx_coordnum", ftp2ext(ftp)); } } //! Constructs plausible chain IDs for multi-molecule systems, e.g. when read from .tpr files class ChainIdFiller { - public: - //! Fill in the chain ID for the indicated atom range, which might be a molecule. - void fill(t_atoms *atoms, - int startAtomIndex, - int endAtomIndex); - //! If only one chain was found, we don't add a chain ID. - void clearIfNeeded(t_atoms *atoms) const; - - private: - //! Minimum size for a chain worth giving an ID - static constexpr int s_chainMinAtoms = 15; - - //! The number of the next chain that will be assigned. - int nextChainNumber_ = 0; - //! The chain ID of the next chain that will be assigned. - char nextChainId_ = 'A'; - //! Whether the set of chain IDs (ie. upper- and lower-case letters and single digits) is exhausted. - bool outOfIds_ = false; +public: + //! Fill in the chain ID for the indicated atom range, which might be a molecule. + void fill(t_atoms* atoms, int startAtomIndex, int endAtomIndex); + //! If only one chain was found, we don't add a chain ID. + void clearIfNeeded(t_atoms* atoms) const; + +private: + //! Minimum size for a chain worth giving an ID + static constexpr int s_chainMinAtoms = 15; + + //! The number of the next chain that will be assigned. + int nextChainNumber_ = 0; + //! The chain ID of the next chain that will be assigned. + char nextChainId_ = 'A'; + //! Whether the set of chain IDs (ie. upper- and lower-case letters and single digits) is exhausted. + bool outOfIds_ = false; }; -void -ChainIdFiller::fill(t_atoms *atoms, - const int startAtomIndex, - const int endAtomIndex) +void ChainIdFiller::fill(t_atoms* atoms, const int startAtomIndex, const int endAtomIndex) { // TODO remove these some time, extra braces added for review convenience { @@ -305,8 +303,7 @@ ChainIdFiller::fill(t_atoms *atoms, } } -void -ChainIdFiller::clearIfNeeded(t_atoms *atoms) const +void ChainIdFiller::clearIfNeeded(t_atoms* atoms) const { /* Blank out the chain id if there was only one chain */ if (nextChainId_ == 'B') @@ -319,7 +316,7 @@ ChainIdFiller::clearIfNeeded(t_atoms *atoms) const } //! Make chain IDs in the t_atoms for a gmx_mtop_t built from a .tpr file -static void makeChainIdentifiersAfterTprReading(t_atoms *atoms, const gmx::RangePartitioning &mols) +static void makeChainIdentifiersAfterTprReading(t_atoms* atoms, const gmx::RangePartitioning& mols) { ChainIdFiller filler; for (auto m = 0; m != mols.numBlocks(); ++m) @@ -330,24 +327,29 @@ static void makeChainIdentifiersAfterTprReading(t_atoms *atoms, const gmx::Range } //! Make chain IDs in the t_atoms for a legacy t_topology built from a .tpr file -static void tpx_make_chain_identifiers(t_atoms *atoms, const t_block *mols) +static void tpx_make_chain_identifiers(t_atoms* atoms, const t_block* mols) { ChainIdFiller filler; for (int m = 0; m < mols->nr; m++) { - filler.fill(atoms, mols->index[m], mols->index[m+1]); + filler.fill(atoms, mols->index[m], mols->index[m + 1]); } filler.clearIfNeeded(atoms); } -static void read_stx_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], rvec *v, int *ePBC, matrix box) +static void read_stx_conf(const char* infile, + t_symtab* symtab, + char** name, + t_atoms* atoms, + rvec x[], + rvec* v, + int* ePBC, + matrix box) { - FILE *in; - t_trxframe fr; - int ftp; - char g96_line[STRLEN+1]; + FILE* in; + t_trxframe fr; + int ftp; + char g96_line[STRLEN + 1]; if (atoms->nr == 0) { @@ -366,9 +368,7 @@ static void read_stx_conf(const char *infile, ftp = fn2ftp(infile); switch (ftp) { - case efGRO: - gmx_gro_read_conf(infile, symtab, name, atoms, x, v, box); - break; + case efGRO: gmx_gro_read_conf(infile, symtab, name, atoms, x, v, box); break; case efG96: fr.natoms = atoms->nr; fr.atoms = atoms; @@ -382,21 +382,20 @@ static void read_stx_conf(const char *infile, break; case efPDB: case efBRK: - case efENT: - gmx_pdb_read_conf(infile, symtab, name, atoms, x, ePBC, box); - break; - case efESP: - gmx_espresso_read_conf(infile, symtab, name, atoms, x, v, box); - break; - default: - gmx_incons("Not supported in read_stx_conf"); + case efENT: gmx_pdb_read_conf(infile, symtab, name, atoms, x, ePBC, box); break; + case efESP: gmx_espresso_read_conf(infile, symtab, name, atoms, x, v, box); break; + default: gmx_incons("Not supported in read_stx_conf"); } } -void readConfAndAtoms(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - int *ePBC, - rvec **x, rvec **v, matrix box) +void readConfAndAtoms(const char* infile, + t_symtab* symtab, + char** name, + t_atoms* atoms, + int* ePBC, + rvec** x, + rvec** v, + matrix box) { GMX_RELEASE_ASSERT(infile, "Need a valid file name string"); @@ -405,9 +404,9 @@ void readConfAndAtoms(const char *infile, bool haveTopology; gmx_mtop_t mtop; readConfAndTopology(infile, &haveTopology, &mtop, ePBC, x, v, box); - *symtab = mtop.symtab; - *name = gmx_strdup(*mtop.name); - *atoms = gmx_mtop_global_atoms(&mtop); + *symtab = mtop.symtab; + *name = gmx_strdup(*mtop.name); + *atoms = gmx_mtop_global_atoms(&mtop); gmx::RangePartitioning molecules = gmx_mtop_molecules(mtop); makeChainIdentifiersAfterTprReading(atoms, molecules); @@ -437,9 +436,7 @@ void readConfAndAtoms(const char *infile, { snew(*v, natoms); } - read_stx_conf(infile, - symtab, name, atoms, - *x, (v == nullptr) ? nullptr : *v, ePBC, box); + read_stx_conf(infile, symtab, name, atoms, *x, (v == nullptr) ? nullptr : *v, ePBC, box); if (xIsNull) { sfree(*x); @@ -447,10 +444,7 @@ void readConfAndAtoms(const char *infile, } } -void readConfAndTopology(const char *infile, - bool *haveTopology, gmx_mtop_t *mtop, - int *ePBC, - rvec **x, rvec **v, matrix box) +void readConfAndTopology(const char* infile, bool* haveTopology, gmx_mtop_t* mtop, int* ePBC, rvec** x, rvec** v, matrix box) { GMX_RELEASE_ASSERT(mtop != nullptr, "readConfAndTopology requires mtop!=NULL"); @@ -472,9 +466,8 @@ void readConfAndTopology(const char *infile, snew(*v, header.natoms); } int natoms; - int ePBC_tmp - = read_tpx(infile, nullptr, box, &natoms, - (x == nullptr) ? nullptr : *x, (v == nullptr) ? nullptr : *v, mtop); + int ePBC_tmp = read_tpx(infile, nullptr, box, &natoms, (x == nullptr) ? nullptr : *x, + (v == nullptr) ? nullptr : *v, mtop); if (ePBC != nullptr) { *ePBC = ePBC_tmp; @@ -482,9 +475,9 @@ void readConfAndTopology(const char *infile, } else { - t_symtab symtab; - char *name; - t_atoms atoms; + t_symtab symtab; + char* name; + t_atoms atoms; open_symtab(&symtab); @@ -495,11 +488,10 @@ void readConfAndTopology(const char *infile, } } -gmx_bool read_tps_conf(const char *infile, t_topology *top, int *ePBC, - rvec **x, rvec **v, matrix box, gmx_bool requireMasses) +gmx_bool read_tps_conf(const char* infile, t_topology* top, int* ePBC, rvec** x, rvec** v, matrix box, gmx_bool requireMasses) { - bool haveTopology; - gmx_mtop_t mtop; + bool haveTopology; + gmx_mtop_t mtop; readConfAndTopology(infile, &haveTopology, &mtop, ePBC, x, v, box); @@ -513,7 +505,10 @@ gmx_bool read_tps_conf(const char *infile, t_topology *top, int *ePBC, if (!top->atoms.haveMass) { - gmx_fatal(FARGS, "Masses were requested, but for some atom(s) masses could not be found in the database. Use a tpr file as input, if possible, or add these atoms to the mass database."); + gmx_fatal(FARGS, + "Masses were requested, but for some atom(s) masses could not be found in " + "the database. Use a tpr file as input, if possible, or add these atoms to " + "the mass database."); } } diff --git a/src/gromacs/fileio/confio.h b/src/gromacs/fileio/confio.h index d3825c9e9d..6fa060b649 100644 --- a/src/gromacs/fileio/confio.h +++ b/src/gromacs/fileio/confio.h @@ -48,21 +48,34 @@ struct t_atoms; struct t_symtab; struct t_topology; -void write_sto_conf_indexed(const char *outfile, const char *title, - const t_atoms *atoms, - const rvec x[], const rvec *v, int ePBC, const matrix box, - int nindex, int index[]); +void write_sto_conf_indexed(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box, + int nindex, + int index[]); /* like write_sto_conf, but indexed */ -void write_sto_conf(const char *outfile, const char *title, - const t_atoms *atoms, - const rvec x[], const rvec *v, int ePBC, const matrix box); +void write_sto_conf(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box); /* write atoms, x, v (if .gro and not NULL) and box (if not NULL) * to an STO (.gro or .pdb) file */ -void write_sto_conf_mtop(const char *outfile, const char *title, - const gmx_mtop_t *mtop, - const rvec x[], const rvec *v, int ePBC, const matrix box); +void write_sto_conf_mtop(const char* outfile, + const char* title, + const gmx_mtop_t* mtop, + const rvec x[], + const rvec* v, + int ePBC, + const matrix box); /* As write_sto_conf, but uses a gmx_mtop_t struct */ /*! \brief Read a configuration and, when available, a topology from a tpr or structure file. @@ -78,10 +91,13 @@ void write_sto_conf_mtop(const char *outfile, const char *title, * \param[in,out] v Velocities will be stored when *v!=NULL * \param[out] box Box dimensions */ -void readConfAndTopology(const char *infile, - bool *haveTopology, gmx_mtop_t *mtop, - int *ePBC, - rvec **x, rvec **v, matrix box); +void readConfAndTopology(const char* infile, + bool* haveTopology, + gmx_mtop_t* mtop, + int* ePBC, + rvec** x, + rvec** v, + matrix box); /*! \brief Read a configuration from a structure file. * @@ -96,10 +112,14 @@ void readConfAndTopology(const char *infile, * \param[in,out] v Velocities will be stored when *v!=NULL * \param[out] box Box dimensions */ -void readConfAndAtoms(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - int *ePBC, - rvec **x, rvec **v, matrix box); +void readConfAndAtoms(const char* infile, + t_symtab* symtab, + char** name, + t_atoms* atoms, + int* ePBC, + rvec** x, + rvec** v, + matrix box); /*! \brief Read a configuration and, when available, a topology from a tpr or structure file. * @@ -112,16 +132,20 @@ void readConfAndAtoms(const char *infile, * their presence is signaled with the \p haveMass flag in t_atoms of \p top. * * \param[in] infile Input file name - * \param[out] top The topology, either complete or only atom data. Caller is responsible for calling done_top(). - * \param[out] ePBC Enum reporting the type of PBC + * \param[out] top The topology, either complete or only atom data. Caller is + * responsible for calling done_top(). \param[out] ePBC Enum reporting the type of PBC * \param[in,out] x Coordinates will be stored when *x!=NULL * \param[in,out] v Velocities will be stored when *v!=NULL * \param[out] box Box dimensions - * \param[in] requireMasses Require masses to be present, either from tpr or from the mass database - * \returns if a topology is available + * \param[in] requireMasses Require masses to be present, either from tpr or from the mass + * database \returns if a topology is available */ -gmx_bool read_tps_conf(const char *infile, struct t_topology *top, - int *ePBC, rvec **x, rvec **v, matrix box, - gmx_bool requireMasses); +gmx_bool read_tps_conf(const char* infile, + struct t_topology* top, + int* ePBC, + rvec** x, + rvec** v, + matrix box, + gmx_bool requireMasses); #endif diff --git a/src/gromacs/fileio/enxio.cpp b/src/gromacs/fileio/enxio.cpp index f0d22ae4a9..58d8a9622a 100644 --- a/src/gromacs/fileio/enxio.cpp +++ b/src/gromacs/fileio/enxio.cpp @@ -66,43 +66,42 @@ /* This number should be increased whenever the file format changes! */ static const int enx_version = 5; -const char *enx_block_id_name[] = { - "Averaged orientation restraints", - "Instantaneous orientation restraints", - "Orientation restraint order tensor(s)", - "Distance restraints", - "Free energy data", - "BAR histogram", - "Delta H raw data", - "AWH data" -}; +const char* enx_block_id_name[] = { "Averaged orientation restraints", + "Instantaneous orientation restraints", + "Orientation restraint order tensor(s)", + "Distance restraints", + "Free energy data", + "BAR histogram", + "Delta H raw data", + "AWH data" }; /* Stuff for reading pre 4.1 energy files */ -typedef struct { - gmx_bool bOldFileOpen; /* Is this an open old file? */ - gmx_bool bReadFirstStep; /* Did we read the first step? */ - int first_step; /* First step in the energy file */ - int step_prev; /* Previous step */ - int nsum_prev; /* Previous step sum length */ - t_energy *ener_prev; /* Previous energy sums */ +typedef struct +{ + gmx_bool bOldFileOpen; /* Is this an open old file? */ + gmx_bool bReadFirstStep; /* Did we read the first step? */ + int first_step; /* First step in the energy file */ + int step_prev; /* Previous step */ + int nsum_prev; /* Previous step sum length */ + t_energy* ener_prev; /* Previous energy sums */ } ener_old_t; struct ener_file { ener_old_t eo; - t_fileio *fio; + t_fileio* fio; int framenr; real frametime; }; -static void enxsubblock_init(t_enxsubblock *sb) +static void enxsubblock_init(t_enxsubblock* sb) { sb->nr = 0; #if GMX_DOUBLE sb->type = xdr_datatype_double; #else - sb->type = xdr_datatype_float; + sb->type = xdr_datatype_float; #endif sb->fval = nullptr; sb->dval = nullptr; @@ -118,7 +117,7 @@ static void enxsubblock_init(t_enxsubblock *sb) sb->sval_alloc = 0; } -static void enxsubblock_free(t_enxsubblock *sb) +static void enxsubblock_free(t_enxsubblock* sb) { if (sb->fval_alloc) { @@ -168,7 +167,7 @@ static void enxsubblock_free(t_enxsubblock *sb) } /* allocate the appropriate amount of memory for the given type and nr */ -static void enxsubblock_alloc(t_enxsubblock *sb) +static void enxsubblock_alloc(t_enxsubblock* sb) { /* allocate the appropriate amount of memory */ switch (sb->type) @@ -221,12 +220,11 @@ static void enxsubblock_alloc(t_enxsubblock *sb) sb->sval_alloc = sb->nr; } break; - default: - gmx_incons("Unknown block type: this file is corrupted or from the future"); + default: gmx_incons("Unknown block type: this file is corrupted or from the future"); } } -static void enxblock_init(t_enxblock *eb) +static void enxblock_init(t_enxblock* eb) { eb->id = enxOR; eb->nsub = 0; @@ -234,7 +232,7 @@ static void enxblock_init(t_enxblock *eb) eb->nsub_alloc = 0; } -static void enxblock_free(t_enxblock *eb) +static void enxblock_free(t_enxblock* eb) { if (eb->nsub_alloc > 0) { @@ -249,7 +247,7 @@ static void enxblock_free(t_enxblock *eb) } } -void init_enxframe(t_enxframe *fr) +void init_enxframe(t_enxframe* fr) { fr->e_alloc = 0; fr->ener = nullptr; @@ -263,7 +261,7 @@ void init_enxframe(t_enxframe *fr) } -void free_enxframe(t_enxframe *fr) +void free_enxframe(t_enxframe* fr) { int b; @@ -278,7 +276,7 @@ void free_enxframe(t_enxframe *fr) sfree(fr->block); } -void add_blocks_enxframe(t_enxframe *fr, int n) +void add_blocks_enxframe(t_enxframe* fr, int n) { fr->nblock = n; if (n > fr->nblock_alloc) @@ -294,7 +292,7 @@ void add_blocks_enxframe(t_enxframe *fr, int n) } } -t_enxblock *find_block_id_enxframe(t_enxframe *ef, int id, t_enxblock *prev) +t_enxblock* find_block_id_enxframe(t_enxframe* ef, int id, t_enxblock* prev) { gmx_off_t starti = 0; gmx_off_t i; @@ -313,7 +311,7 @@ t_enxblock *find_block_id_enxframe(t_enxframe *ef, int id, t_enxblock *prev) return nullptr; } -void add_subblocks_enxblock(t_enxblock *eb, int n) +void add_subblocks_enxblock(t_enxblock* eb, int n) { eb->nsub = n; if (eb->nsub > eb->nsub_alloc) @@ -329,7 +327,7 @@ void add_subblocks_enxblock(t_enxblock *eb, int n) } } -static void enx_warning(const char *msg) +static void enx_warning(const char* msg) { if (getenv("GMX_ENX_NO_FATAL") != nullptr) { @@ -337,17 +335,16 @@ static void enx_warning(const char *msg) } else { - gmx_fatal(FARGS, "%s\n%s", - msg, - "If you want to use the correct frames before the corrupted frame and avoid this fatal error set the env.var. GMX_ENX_NO_FATAL"); + gmx_fatal(FARGS, "%s\n%s", msg, + "If you want to use the correct frames before the corrupted frame and avoid this " + "fatal error set the env.var. GMX_ENX_NO_FATAL"); } } -static void edr_strings(XDR *xdr, gmx_bool bRead, int file_version, - int n, gmx_enxnm_t **nms) +static void edr_strings(XDR* xdr, gmx_bool bRead, int file_version, int n, gmx_enxnm_t** nms) { int i; - gmx_enxnm_t *nm; + gmx_enxnm_t* nm; if (*nms == nullptr) { @@ -387,10 +384,10 @@ static void edr_strings(XDR *xdr, gmx_bool bRead, int file_version, } } -void do_enxnms(ener_file_t ef, int *nre, gmx_enxnm_t **nms) +void do_enxnms(ener_file_t ef, int* nre, gmx_enxnm_t** nms) { int magic = -55555; - XDR *xdr; + XDR* xdr; gmx_bool bRead = gmx_fio_getread(ef->fio); int file_version; @@ -426,28 +423,32 @@ void do_enxnms(ener_file_t ef, int *nre, gmx_enxnm_t **nms) xdr_int(xdr, &file_version); if (file_version > enx_version) { - gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", gmx_fio_getname(ef->fio), file_version, enx_version); + gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", + gmx_fio_getname(ef->fio), file_version, enx_version); } xdr_int(xdr, nre); } if (file_version != enx_version) { - fprintf(stderr, "Note: enx file_version %d, software version %d\n", - file_version, enx_version); + fprintf(stderr, "Note: enx file_version %d, software version %d\n", file_version, enx_version); } edr_strings(xdr, bRead, file_version, *nre, nms); } -static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, - int nre_test, gmx_bool *bWrongPrecision, gmx_bool *bOK) +static gmx_bool do_eheader(ener_file_t ef, + int* file_version, + t_enxframe* fr, + int nre_test, + gmx_bool* bWrongPrecision, + gmx_bool* bOK) { - int magic = -7777777; - real first_real_to_check; - int b, zero = 0, dum = 0; - gmx_bool bRead = gmx_fio_getread(ef->fio); - int ndisre = 0; - int startb = 0; + int magic = -7777777; + real first_real_to_check; + int b, zero = 0, dum = 0; + gmx_bool bRead = gmx_fio_getread(ef->fio); + int ndisre = 0; + int startb = 0; #if !GMX_DOUBLE xdr_datatype dtreal = xdr_datatype_float; #else @@ -505,7 +506,8 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, } if (*bOK && *file_version > enx_version) { - gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", gmx_fio_getname(ef->fio), *file_version, enx_version); + gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", + gmx_fio_getname(ef->fio), *file_version, enx_version); } if (!gmx_fio_do_double(ef->fio, fr->t)) { @@ -597,9 +599,8 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, /* Frames could have nre=0, so we can not rely only on the fr->nre check */ - if (bRead && nre_test >= 0 && - ((fr->nre > 0 && fr->nre != nre_test) || - fr->nre < 0 || ndisre < 0 || fr->nblock < 0)) + if (bRead && nre_test >= 0 + && ((fr->nre > 0 && fr->nre != nre_test) || fr->nre < 0 || ndisre < 0 || fr->nblock < 0)) { if (bWrongPrecision) { @@ -610,9 +611,11 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, /* we now know what these should be, or we've already bailed out because of wrong precision */ - if (*file_version == 1 && (fr->t < 0 || fr->t > 1e20 || fr->step < 0 ) ) + if (*file_version == 1 && (fr->t < 0 || fr->t > 1e20 || fr->step < 0)) { - enx_warning("edr file with negative step number or unreasonable time (and without version number)."); + enx_warning( + "edr file with negative step number or unreasonable time (and without version " + "number)."); *bOK = FALSE; return FALSE; } @@ -676,8 +679,8 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, /* in the new version files, the block header only contains the ID and the number of subblocks */ int nsub = fr->block[b].nsub; - *bOK = *bOK && gmx_fio_do_int(ef->fio, fr->block[b].id); - *bOK = *bOK && gmx_fio_do_int(ef->fio, nsub); + *bOK = *bOK && gmx_fio_do_int(ef->fio, fr->block[b].id); + *bOK = *bOK && gmx_fio_do_int(ef->fio, nsub); fr->block[b].nsub = nsub; if (bRead) @@ -688,7 +691,7 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, /* read/write type & size for each subblock */ for (i = 0; i < nsub; i++) { - t_enxsubblock *sub = &(fr->block[b].sub[i]); /* shortcut */ + t_enxsubblock* sub = &(fr->block[b].sub[i]); /* shortcut */ int typenr = sub->type; *bOK = *bOK && gmx_fio_do_int(ef->fio, typenr); @@ -733,7 +736,7 @@ static gmx_bool do_eheader(ener_file_t ef, int *file_version, t_enxframe *fr, return *bOK; } -void free_enxnms(int n, gmx_enxnm_t *nms) +void free_enxnms(int n, gmx_enxnm_t* nms) { int i; @@ -755,7 +758,9 @@ void close_enx(ener_file_t ef) } if (gmx_fio_close(ef->fio) != 0) { - gmx_file("Cannot close energy file; it might be corrupt, or maybe you are out of disk space?"); + gmx_file( + "Cannot close energy file; it might be corrupt, or maybe you are out of disk " + "space?"); } } @@ -775,10 +780,9 @@ void done_ener_file(ener_file_t ef) * * \return TRUE if file could be open but is empty, otherwise FALSE. */ -static gmx_bool -empty_file(const char *fn) +static gmx_bool empty_file(const char* fn) { - FILE *fp; + FILE* fp; char dum; int ret; gmx_bool bEmpty; @@ -794,14 +798,14 @@ empty_file(const char *fn) } -ener_file_t open_enx(const char *fn, const char *mode) +ener_file_t open_enx(const char* fn, const char* mode) { int nre; - gmx_enxnm_t *nms = nullptr; + gmx_enxnm_t* nms = nullptr; int file_version = -1; - t_enxframe *fr; + t_enxframe* fr; gmx_bool bWrongPrecision, bOK = TRUE; - struct ener_file *ef; + struct ener_file* ef; snew(ef, 1); @@ -818,9 +822,9 @@ ener_file_t open_enx(const char *fn, const char *mode) } /* Now check whether this file is in single precision */ - if (!bWrongPrecision && - ((fr->e_size && (fr->nre == nre) && - (nre*4*static_cast(sizeof(float)) == fr->e_size)) ) ) + if (!bWrongPrecision + && ((fr->e_size && (fr->nre == nre) + && (nre * 4 * static_cast(sizeof(float)) == fr->e_size)))) { fprintf(stderr, "Opened %s as single precision energy file\n", fn); free_enxnms(nre, nms); @@ -836,11 +840,10 @@ ener_file_t open_enx(const char *fn, const char *mode) gmx_file("Cannot write energy file header; maybe you are out of disk space?"); } - if (((fr->e_size && (fr->nre == nre) && - (nre*4*static_cast(sizeof(double)) == fr->e_size)) )) + if (((fr->e_size && (fr->nre == nre) + && (nre * 4 * static_cast(sizeof(double)) == fr->e_size)))) { - fprintf(stderr, "Opened %s as double precision energy file\n", - fn); + fprintf(stderr, "Opened %s as double precision energy file\n", fn); } else { @@ -850,8 +853,7 @@ ener_file_t open_enx(const char *fn, const char *mode) } else { - gmx_fatal(FARGS, "Energy file %s not recognized, maybe different CPU?", - fn); + gmx_fatal(FARGS, "Energy file %s not recognized, maybe different CPU?", fn); } } free_enxnms(nre, nms); @@ -870,12 +872,12 @@ ener_file_t open_enx(const char *fn, const char *mode) return ef; } -t_fileio *enx_file_pointer(const ener_file* ef) +t_fileio* enx_file_pointer(const ener_file* ef) { return ef->fio; } -static void convert_full_sums(ener_old_t *ener_old, t_enxframe *fr) +static void convert_full_sums(ener_old_t* ener_old, t_enxframe* fr) { int nstep_all; int ne, ns, i; @@ -887,7 +889,7 @@ static void convert_full_sums(ener_old_t *ener_old, t_enxframe *fr) ns = 0; for (i = 0; i < fr->nre; i++) { - if (fr->ener[i].e != 0) + if (fr->ener[i].e != 0) { ne++; } @@ -914,10 +916,10 @@ static void convert_full_sums(ener_old_t *ener_old, t_enxframe *fr) esum_all = fr->ener[i].esum; eav_all = fr->ener[i].eav; fr->ener[i].esum = esum_all - ener_old->ener_prev[i].esum; - fr->ener[i].eav = eav_all - ener_old->ener_prev[i].eav - - gmx::square(ener_old->ener_prev[i].esum/(nstep_all - fr->nsum) - - esum_all/nstep_all)* - (nstep_all - fr->nsum)*nstep_all/static_cast(fr->nsum); + fr->ener[i].eav = + eav_all - ener_old->ener_prev[i].eav + - gmx::square(ener_old->ener_prev[i].esum / (nstep_all - fr->nsum) - esum_all / nstep_all) + * (nstep_all - fr->nsum) * nstep_all / static_cast(fr->nsum); ener_old->ener_prev[i].esum = esum_all; ener_old->ener_prev[i].eav = eav_all; } @@ -927,7 +929,9 @@ static void convert_full_sums(ener_old_t *ener_old, t_enxframe *fr) { if (fr->nsum != nstep_all) { - fprintf(stderr, "\nWARNING: something is wrong with the energy sums, will not use exact averages\n"); + fprintf(stderr, + "\nWARNING: something is wrong with the energy sums, will not use exact " + "averages\n"); ener_old->nsum_prev = 0; } else @@ -945,19 +949,19 @@ static void convert_full_sums(ener_old_t *ener_old, t_enxframe *fr) ener_old->step_prev = fr->step; } -gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) +gmx_bool do_enx(ener_file_t ef, t_enxframe* fr) { - int file_version = -1; - int i, b; - gmx_bool bRead, bOK, bOK1, bSane; - real tmp1, tmp2, rdum; + int file_version = -1; + int i, b; + gmx_bool bRead, bOK, bOK1, bSane; + real tmp1, tmp2, rdum; /*int d_size;*/ bOK = TRUE; bRead = gmx_fio_getread(ef->fio); if (!bRead) { - fr->e_size = fr->nre*sizeof(fr->ener[0].e)*4; + fr->e_size = fr->nre * sizeof(fr->ener[0].e) * 4; /*d_size = fr->ndisre*(sizeof(real)*2);*/ } @@ -965,14 +969,13 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) { if (bRead) { - fprintf(stderr, "\rLast energy frame read %d time %8.3f ", - ef->framenr-1, ef->frametime); + fprintf(stderr, "\rLast energy frame read %d time %8.3f ", ef->framenr - 1, + ef->frametime); fflush(stderr); if (!bOK) { - fprintf(stderr, - "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", + fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", ef->framenr, fr->t); } } @@ -984,12 +987,10 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) } if (bRead) { - if ((ef->framenr < 20 || ef->framenr % 10 == 0) && - (ef->framenr < 200 || ef->framenr % 100 == 0) && - (ef->framenr < 2000 || ef->framenr % 1000 == 0)) + if ((ef->framenr < 20 || ef->framenr % 10 == 0) && (ef->framenr < 200 || ef->framenr % 100 == 0) + && (ef->framenr < 2000 || ef->framenr % 1000 == 0)) { - fprintf(stderr, "\rReading energy frame %6d time %8.3f ", - ef->framenr, fr->t); + fprintf(stderr, "\rReading energy frame %6d time %8.3f ", ef->framenr, fr->t); } ef->framenr++; ef->frametime = fr->t; @@ -1004,8 +1005,8 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) { fprintf(stderr, "\nWARNING: there may be something wrong with energy file %s\n", gmx_fio_getname(ef->fio)); - fprintf(stderr, "Found: step=%" PRId64 ", nre=%d, nblock=%d, time=%g.\n", - fr->step, fr->nre, fr->nblock, fr->t); + fprintf(stderr, "Found: step=%" PRId64 ", nre=%d, nblock=%d, time=%g.\n", fr->step, fr->nre, + fr->nblock, fr->t); } if (bRead && fr->nre > fr->e_alloc) { @@ -1026,8 +1027,7 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) /* Do not store sums of length 1, * since this does not add information. */ - if (file_version == 1 || - (bRead && fr->nsum > 0) || fr->nsum > 1) + if (file_version == 1 || (bRead && fr->nsum > 0) || fr->nsum > 1) { tmp1 = fr->ener[i].eav; bOK = bOK && gmx_fio_do_real(ef->fio, tmp1); @@ -1070,7 +1070,7 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) for (i = 0; i < nsub; i++) { - t_enxsubblock *sub = &(fr->block[b].sub[i]); /* shortcut */ + t_enxsubblock* sub = &(fr->block[b].sub[i]); /* shortcut */ if (bRead) { @@ -1086,9 +1086,7 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) case xdr_datatype_double: bOK1 = gmx_fio_ndo_double(ef->fio, sub->dval, sub->nr); break; - case xdr_datatype_int: - bOK1 = gmx_fio_ndo_int(ef->fio, sub->ival, sub->nr); - break; + case xdr_datatype_int: bOK1 = gmx_fio_ndo_int(ef->fio, sub->ival, sub->nr); break; case xdr_datatype_int64: bOK1 = gmx_fio_ndo_int64(ef->fio, sub->lval, sub->nr); break; @@ -1099,7 +1097,9 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) bOK1 = gmx_fio_ndo_string(ef->fio, sub->sval, sub->nr); break; default: - gmx_incons("Reading unknown block data type: this file is corrupted or from the future"); + gmx_incons( + "Reading unknown block data type: this file is corrupted or from the " + "future"); } bOK = bOK && bOK1; } @@ -1117,10 +1117,8 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) { if (bRead) { - fprintf(stderr, "\nLast energy frame read %d", - ef->framenr-1); - fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", - ef->framenr, fr->t); + fprintf(stderr, "\nLast energy frame read %d", ef->framenr - 1); + fprintf(stderr, "\nWARNING: Incomplete energy frame: nr %d time %8.3f\n", ef->framenr, fr->t); } else { @@ -1132,8 +1130,7 @@ gmx_bool do_enx(ener_file_t ef, t_enxframe *fr) return TRUE; } -static real find_energy(const char *name, int nre, gmx_enxnm_t *enm, - t_enxframe *fr) +static real find_energy(const char* name, int nre, gmx_enxnm_t* enm, t_enxframe* fr) { int i; @@ -1145,31 +1142,31 @@ static real find_energy(const char *name, int nre, gmx_enxnm_t *enm, } } - gmx_fatal(FARGS, "Could not find energy term named '%s'. Either the energy file is from a different run or this state variable is not stored in the energy file. In the latter case (and if you did not modify the T/P-coupling setup), you can read the state in mdrun instead, by passing in a checkpoint file.", name); + gmx_fatal(FARGS, + "Could not find energy term named '%s'. Either the energy file is from a different " + "run or this state variable is not stored in the energy file. In the latter case " + "(and if you did not modify the T/P-coupling setup), you can read the state in mdrun " + "instead, by passing in a checkpoint file.", + name); } -void get_enx_state(const char *fn, real t, const SimulationGroups &groups, t_inputrec *ir, - t_state *state) +void get_enx_state(const char* fn, real t, const SimulationGroups& groups, t_inputrec* ir, t_state* state) { /* Should match the names in mdebin.c */ - static const char *boxvel_nm[] = { - "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ", - "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY" - }; + static const char* boxvel_nm[] = { "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ", + "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY" }; - static const char *baro_nm[] = { - "Barostat" - }; + static const char* baro_nm[] = { "Barostat" }; int ind0[] = { XX, YY, ZZ, YY, ZZ, ZZ }; int ind1[] = { XX, YY, ZZ, XX, XX, YY }; int nre, nfr, i, j, ni, npcoupl; char buf[STRLEN]; - const char *bufi; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; + const char* bufi; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; ener_file_t in; in = open_enx(fn, "r"); @@ -1194,8 +1191,7 @@ void get_enx_state(const char *fn, real t, const SimulationGroups &groups, t_inp clear_mat(state->boxv); for (i = 0; i < npcoupl; i++) { - state->boxv[ind0[i]][ind1[i]] = - find_energy(boxvel_nm[i], nre, enm, fr); + state->boxv[ind0[i]][ind1[i]] = find_energy(boxvel_nm[i], nre, enm, fr); } fprintf(stderr, "\nREAD %d BOX VELOCITIES FROM %s\n\n", npcoupl, fn); } @@ -1221,7 +1217,6 @@ void get_enx_state(const char *fn, real t, const SimulationGroups &groups, t_inp sprintf(buf, "vXi%s-%s", cns, bufi); state->nosehoover_vxi[i] = find_energy(buf, nre, enm, fr); } - } fprintf(stderr, "\nREAD %d NOSE-HOOVER Xi chains FROM %s\n\n", state->ngtc, fn); @@ -1247,10 +1242,14 @@ void get_enx_state(const char *fn, real t, const SimulationGroups &groups, t_inp sfree(fr); } -static real ener_tensor_diag(int n, const int *ind1, const int *ind2, - gmx_enxnm_t *enm1, - const int *tensi, int i, - t_energy e1[], t_energy e2[]) +static real ener_tensor_diag(int n, + const int* ind1, + const int* ind2, + gmx_enxnm_t* enm1, + const int* tensi, + int i, + t_energy e1[], + t_energy e2[]) { int d1, d2; int j; @@ -1258,8 +1257,8 @@ static real ener_tensor_diag(int n, const int *ind1, const int *ind2, int nfound; size_t len; - d1 = tensi[i]/DIM; - d2 = tensi[i] - d1*DIM; + d1 = tensi[i] / DIM; + d2 = tensi[i] - d1 * DIM; /* Find the diagonal elements d1 and d2 */ len = std::strlen(enm1[ind1[i]].name); @@ -1268,10 +1267,9 @@ static real ener_tensor_diag(int n, const int *ind1, const int *ind2, nfound = 0; for (j = 0; j < n; j++) { - if (tensi[j] >= 0 && - std::strlen(enm1[ind1[j]].name) == len && - std::strncmp(enm1[ind1[i]].name, enm1[ind1[j]].name, len-2) == 0 && - (tensi[j] == d1*DIM+d1 || tensi[j] == d2*DIM+d2)) + if (tensi[j] >= 0 && std::strlen(enm1[ind1[j]].name) == len + && std::strncmp(enm1[ind1[i]].name, enm1[ind1[j]].name, len - 2) == 0 + && (tensi[j] == d1 * DIM + d1 || tensi[j] == d2 * DIM + d2)) { prod1 *= fabs(e1[ind1[j]].e); prod2 *= fabs(e2[ind2[j]].e); @@ -1281,7 +1279,7 @@ static real ener_tensor_diag(int n, const int *ind1, const int *ind2, if (nfound == 2) { - return 0.5*(std::sqrt(prod1) + std::sqrt(prod2)); + return 0.5 * (std::sqrt(prod1) + std::sqrt(prod2)); } else { @@ -1289,7 +1287,7 @@ static real ener_tensor_diag(int n, const int *ind1, const int *ind2, } } -static gmx_bool enernm_equal(const char *nm1, const char *nm2) +static gmx_bool enernm_equal(const char* nm1, const char* nm2) { int len1, len2; @@ -1297,11 +1295,11 @@ static gmx_bool enernm_equal(const char *nm1, const char *nm2) len2 = std::strlen(nm2); /* Remove " (bar)" at the end of a name */ - if (len1 > 6 && std::strcmp(nm1+len1-6, " (bar)") == 0) + if (len1 > 6 && std::strcmp(nm1 + len1 - 6, " (bar)") == 0) { len1 -= 6; } - if (len2 > 6 && std::strcmp(nm2+len2-6, " (bar)") == 0) + if (len2 > 6 && std::strcmp(nm2 + len2 - 6, " (bar)") == 0) { len2 -= 6; } @@ -1309,15 +1307,22 @@ static gmx_bool enernm_equal(const char *nm1, const char *nm2) return (len1 == len2 && gmx_strncasecmp(nm1, nm2, len1) == 0); } -static void cmp_energies(FILE *fp, int step1, int step2, - t_energy e1[], t_energy e2[], - gmx_enxnm_t *enm1, - real ftol, real abstol, - int nre, int *ind1, int *ind2, int maxener) +static void cmp_energies(FILE* fp, + int step1, + int step2, + t_energy e1[], + t_energy e2[], + gmx_enxnm_t* enm1, + real ftol, + real abstol, + int nre, + int* ind1, + int* ind2, + int maxener) { - int i, ii; - int *tensi, len, d1, d2; - real ftol_i, abstol_i; + int i, ii; + int *tensi, len, d1, d2; + real ftol_i, abstol_i; snew(tensi, maxener); /* Check for tensor elements ending on "-XX", "-XY", ... , "-ZZ" */ @@ -1326,14 +1331,13 @@ static void cmp_energies(FILE *fp, int step1, int step2, ii = ind1[i]; tensi[i] = -1; len = std::strlen(enm1[ii].name); - if (len > 3 && enm1[ii].name[len-3] == '-') + if (len > 3 && enm1[ii].name[len - 3] == '-') { - d1 = enm1[ii].name[len-2] - 'X'; - d2 = enm1[ii].name[len-1] - 'X'; - if (d1 >= 0 && d1 < DIM && - d2 >= 0 && d2 < DIM) + d1 = enm1[ii].name[len - 2] - 'X'; + d2 = enm1[ii].name[len - 1] - 'X'; + if (d1 >= 0 && d1 < DIM && d2 >= 0 && d2 < DIM) { - tensi[i] = d1*DIM + d2; + tensi[i] = d1 * DIM + d2; } } } @@ -1348,11 +1352,10 @@ static void cmp_energies(FILE *fp, int step1, int step2, /* Do the relative tolerance through an absolute tolerance times * the size of diagonal components of the tensor. */ - abstol_i = ftol*ener_tensor_diag(nre, ind1, ind2, enm1, tensi, i, e1, e2); + abstol_i = ftol * ener_tensor_diag(nre, ind1, ind2, enm1, tensi, i, e1, e2); if (debug) { - fprintf(debug, "tensor '%s' val %f diag %f\n", - enm1[i].name, e1[i].e, abstol_i/ftol); + fprintf(debug, "tensor '%s' val %f diag %f\n", enm1[i].name, e1[i].e, abstol_i / ftol); } if (abstol_i > 0) { @@ -1372,10 +1375,8 @@ static void cmp_energies(FILE *fp, int step1, int step2, } if (!equal_real(e1[ind1[i]].e, e2[ind2[i]].e, ftol_i, abstol_i)) { - fprintf(fp, "%-15s step %3d: %12g, step %3d: %12g\n", - enm1[ind1[i]].name, - step1, e1[ind1[i]].e, - step2, e2[ind2[i]].e); + fprintf(fp, "%-15s step %3d: %12g, step %3d: %12g\n", enm1[ind1[i]].name, step1, + e1[ind1[i]].e, step2, e2[ind2[i]].e); } } @@ -1402,7 +1403,7 @@ static void cmp_disres(t_enxframe *fr1, t_enxframe *fr2, real ftol, real abstol) } #endif -static void cmp_eblocks(t_enxframe *fr1, t_enxframe *fr2, real ftol, real abstol) +static void cmp_eblocks(t_enxframe* fr1, t_enxframe* fr2, real ftol, real abstol) { int i, j, k; char buf[64], bs[22]; @@ -1421,7 +1422,7 @@ static void cmp_eblocks(t_enxframe *fr1, t_enxframe *fr2, real ftol, real abstol cmp_int(stdout, buf, -1, b1->nsub, b2->nsub); cmp_int(stdout, buf, -1, b1->id, b2->id); - if ( (b1->nsub == b2->nsub) && (b1->id == b2->id) ) + if ((b1->nsub == b2->nsub) && (b1->id == b2->id)) { for (i = 0; i < b1->nsub; i++) { @@ -1440,49 +1441,40 @@ static void cmp_eblocks(t_enxframe *fr1, t_enxframe *fr2, real ftol, real abstol case xdr_datatype_float: for (k = 0; k < s1->nr; k++) { - cmp_float(stdout, buf, i, - s1->fval[k], s2->fval[k], - ftol, abstol); + cmp_float(stdout, buf, i, s1->fval[k], s2->fval[k], ftol, abstol); } break; case xdr_datatype_double: for (k = 0; k < s1->nr; k++) { - cmp_double(stdout, buf, i, - s1->dval[k], s2->dval[k], - ftol, abstol); + cmp_double(stdout, buf, i, s1->dval[k], s2->dval[k], ftol, abstol); } break; case xdr_datatype_int: for (k = 0; k < s1->nr; k++) { - cmp_int(stdout, buf, i, - s1->ival[k], s2->ival[k]); + cmp_int(stdout, buf, i, s1->ival[k], s2->ival[k]); } break; case xdr_datatype_int64: for (k = 0; k < s1->nr; k++) { - cmp_int64(stdout, buf, - s1->lval[k], s2->lval[k]); + cmp_int64(stdout, buf, s1->lval[k], s2->lval[k]); } break; case xdr_datatype_char: for (k = 0; k < s1->nr; k++) { - cmp_uc(stdout, buf, i, - s1->cval[k], s2->cval[k]); + cmp_uc(stdout, buf, i, s1->cval[k], s2->cval[k]); } break; case xdr_datatype_string: for (k = 0; k < s1->nr; k++) { - cmp_str(stdout, buf, i, - s1->sval[k], s2->sval[k]); + cmp_str(stdout, buf, i, s1->sval[k], s2->sval[k]); } break; - default: - gmx_incons("Unknown data type!!"); + default: gmx_incons("Unknown data type!!"); } } } @@ -1491,14 +1483,14 @@ static void cmp_eblocks(t_enxframe *fr1, t_enxframe *fr2, real ftol, real abstol } } -void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const char *lastener) +void comp_enx(const char* fn1, const char* fn2, real ftol, real abstol, const char* lastener) { - int nre, nre1, nre2; - ener_file_t in1, in2; - int i, j, maxener, *ind1, *ind2, *have; - gmx_enxnm_t *enm1 = nullptr, *enm2 = nullptr; - t_enxframe *fr1, *fr2; - gmx_bool b1, b2; + int nre, nre1, nre2; + ener_file_t in1, in2; + int i, j, maxener, *ind1, *ind2, *have; + gmx_enxnm_t *enm1 = nullptr, *enm2 = nullptr; + t_enxframe * fr1, *fr2; + gmx_bool b1, b2; fprintf(stdout, "comparing energy file %s and %s\n\n", fn1, fn2); @@ -1508,8 +1500,7 @@ void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const ch do_enxnms(in2, &nre2, &enm2); if (nre1 != nre2) { - fprintf(stdout, "There are %d and %d terms in the energy files\n\n", - nre1, nre2); + fprintf(stdout, "There are %d and %d terms in the energy files\n\n", nre1, nre2); } else { @@ -1533,7 +1524,7 @@ void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const ch break; } } - if (nre == 0 || ind1[nre-1] != i) + if (nre == 0 || ind1[nre - 1] != i) { cmp_str(stdout, "enm", i, enm1[i].name, "-"); } @@ -1551,13 +1542,12 @@ void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const ch { if ((lastener != nullptr) && (std::strstr(enm1[i].name, lastener) != nullptr)) { - maxener = i+1; + maxener = i + 1; break; } } - fprintf(stdout, "There are %d terms to compare in the energy files\n\n", - maxener); + fprintf(stdout, "There are %d terms to compare in the energy files\n\n", maxener); for (i = 0; i < maxener; i++) { @@ -1590,14 +1580,13 @@ void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, const ch /* cmp_int(stdout,"nre",-1,fr1->nre,fr2->nre); */ if ((fr1->nre >= nre) && (fr2->nre >= nre)) { - cmp_energies(stdout, fr1->step, fr1->step, fr1->ener, fr2->ener, - enm1, ftol, abstol, nre, ind1, ind2, maxener); + cmp_energies(stdout, fr1->step, fr1->step, fr1->ener, fr2->ener, enm1, ftol, abstol, + nre, ind1, ind2, maxener); } /*cmp_disres(fr1,fr2,ftol,abstol);*/ cmp_eblocks(fr1, fr2, ftol, abstol); } - } - while (b1 && b2); + } while (b1 && b2); close_enx(in1); close_enx(in2); diff --git a/src/gromacs/fileio/enxio.h b/src/gromacs/fileio/enxio.h index 209bff6398..d5d83a5068 100644 --- a/src/gromacs/fileio/enxio.h +++ b/src/gromacs/fileio/enxio.h @@ -61,9 +61,10 @@ class t_state; * **************************************************************/ -typedef struct { - char *name; - char *unit; +typedef struct +{ + char* name; + char* unit; } gmx_enxnm_t; /* @@ -73,42 +74,43 @@ typedef struct { * * For backward compatibility, the order of these should not be changed. */ -enum { - enxOR, /* Time and ensemble averaged data for orientation restraints */ - enxORI, /* Instantaneous data for orientation restraints */ - enxORT, /* Order tensor(s) for orientation restraints */ - enxDISRE, /* Distance restraint blocks */ +enum +{ + enxOR, /* Time and ensemble averaged data for orientation restraints */ + enxORI, /* Instantaneous data for orientation restraints */ + enxORT, /* Order tensor(s) for orientation restraints */ + enxDISRE, /* Distance restraint blocks */ enxDHCOLL, /* Data about the free energy blocks in this frame. */ enxDHHIST, /* BAR histogram */ enxDH, /* BAR raw delta H data */ - enxAWH, /* AWH data */ + enxAWH, /* AWH data */ - enxNR /* Total number of extra blocks in the current code, - * note that the enxio code can read files written by - * future code which contain more blocks. - */ + enxNR /* Total number of extra blocks in the current code, + * note that the enxio code can read files written by + * future code which contain more blocks. + */ }; /* names for the above enum */ -extern const char *enx_block_id_name[]; +extern const char* enx_block_id_name[]; /* the subblocks that are contained in energy file blocks. Each of these has a number of values of a single data type in a .edr file. */ struct t_enxsubblock { - int nr; /* number of items in subblock */ - xdr_datatype type; /* the block type */ + int nr; /* number of items in subblock */ + xdr_datatype type; /* the block type */ /* the values: pointers for each type */ - float* fval; - double* dval; - int* ival; - int64_t * lval; - unsigned char* cval; - char** sval; + float* fval; + double* dval; + int* ival; + int64_t* lval; + unsigned char* cval; + char** sval; /* the allocated sizes, defined separately. (nonzero sizes can be free()d later): */ @@ -126,12 +128,12 @@ struct t_enxblock { int id; /* block id, from the enx enums above */ int nsub; /* number of subblocks */ - t_enxsubblock *sub; /* the subblocks */ + t_enxsubblock* sub; /* the subblocks */ int nsub_alloc; /* number of allocated subblocks */ }; /* file handle */ -typedef struct ener_file *ener_file_t; +typedef struct ener_file* ener_file_t; /* * An energy file is read like this: @@ -152,14 +154,14 @@ typedef struct ener_file *ener_file_t; /* initialize a pre-allocated frame */ -void init_enxframe(t_enxframe *ef); +void init_enxframe(t_enxframe* ef); /* delete a frame's memory (except the ef itself) */ -void free_enxframe(t_enxframe *ef); +void free_enxframe(t_enxframe* ef); -ener_file_t open_enx(const char *fn, const char *mode); +ener_file_t open_enx(const char* fn, const char* mode); -struct t_fileio *enx_file_pointer(const ener_file* ef); +struct t_fileio* enx_file_pointer(const ener_file* ef); /* Free the contents of ef */ void close_enx(ener_file_t ef); @@ -167,17 +169,15 @@ void close_enx(ener_file_t ef); /* Free the contents of ef, and ef itself */ void done_ener_file(ener_file_t ef); -void do_enxnms(ener_file_t ef, int *nre, gmx_enxnm_t **enms); +void do_enxnms(ener_file_t ef, int* nre, gmx_enxnm_t** enms); -void free_enxnms(int n, gmx_enxnm_t *nms); +void free_enxnms(int n, gmx_enxnm_t* nms); /* Frees nms and all strings in it */ -gmx_bool do_enx(ener_file_t ef, t_enxframe *fr); +gmx_bool do_enx(ener_file_t ef, t_enxframe* fr); /* Reads enx_frames, memory in fr is (re)allocated if necessary */ -void get_enx_state(const char *fn, real t, - const SimulationGroups &groups, t_inputrec *ir, - t_state *state); +void get_enx_state(const char* fn, real t, const SimulationGroups& groups, t_inputrec* ir, t_state* state); /* * Reads state variables from enx file fn at time t. * atoms and ir are required for determining which things must be read. @@ -188,20 +188,19 @@ void get_enx_state(const char *fn, real t, /* block funtions */ /* allocate n blocks to a frame (if neccesary). Don't touch existing blocks */ -void add_blocks_enxframe(t_enxframe *ef, int n); +void add_blocks_enxframe(t_enxframe* ef, int n); /* find a block by id number; if prev!=NULL, it searches from that block's next block. Returns NULL if no block is found with the given id. */ -t_enxblock *find_block_id_enxframe(t_enxframe *ef, int id, t_enxblock *prev); +t_enxblock* find_block_id_enxframe(t_enxframe* ef, int id, t_enxblock* prev); /* allocate n subblocks to a block (if neccesary). Don't touch existing subbblocks. */ -void add_subblocks_enxblock(t_enxblock *eb, int n); +void add_subblocks_enxblock(t_enxblock* eb, int n); -void comp_enx(const char *fn1, const char *fn2, real ftol, real abstol, - const char *lastener); +void comp_enx(const char* fn1, const char* fn2, real ftol, real abstol, const char* lastener); /* Compare two binary energy files */ #endif diff --git a/src/gromacs/fileio/espio.cpp b/src/gromacs/fileio/espio.cpp index 6e146861b7..4d5580b3d7 100644 --- a/src/gromacs/fileio/espio.cpp +++ b/src/gromacs/fileio/espio.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2005, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,9 +51,9 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static int get_espresso_word(FILE *fp, char word[]) +static int get_espresso_word(FILE* fp, char word[]) { - int ret, nc, i; + int ret, nc, i; ret = 0; nc = 0; @@ -91,16 +91,14 @@ static int get_espresso_word(FILE *fp, char word[]) word[nc++] = static_cast(i); } } - } - while (i != EOF && ret == 0); + } while (i != EOF && ret == 0); word[nc] = '\0'; return ret; } -static int check_open_parenthesis(FILE *fp, int r, - const char *infile, const char *keyword) +static int check_open_parenthesis(FILE* fp, int r, const char* infile, const char* keyword) { int level_inc; char word[STRLEN]; @@ -119,16 +117,14 @@ static int check_open_parenthesis(FILE *fp, int r, } else { - gmx_fatal(FARGS, "Expected '{' after '%s' in file '%s'", - keyword, infile); + gmx_fatal(FARGS, "Expected '{' after '%s' in file '%s'", keyword, infile); } } return level_inc; } -static int check_close_parenthesis(FILE *fp, int r, - const char *infile, const char *keyword) +static int check_close_parenthesis(FILE* fp, int r, const char* infile, const char* keyword) { int level_inc; char word[STRLEN]; @@ -147,32 +143,34 @@ static int check_close_parenthesis(FILE *fp, int r, } else { - gmx_fatal(FARGS, "Expected '}' after section '%s' in file '%s'", - keyword, infile); + gmx_fatal(FARGS, "Expected '}' after section '%s' in file '%s'", keyword, infile); } } return level_inc; } -enum { - espID, espPOS, espTYPE, espQ, espV, espF, espMOLECULE, espNR -}; -static const char *const esp_prop[espNR] = { - "id", "pos", "type", "q", "v", "f", - "molecule" +enum +{ + espID, + espPOS, + espTYPE, + espQ, + espV, + espF, + espMOLECULE, + espNR }; +static const char* const esp_prop[espNR] = { "id", "pos", "type", "q", "v", "f", "molecule" }; -void gmx_espresso_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], rvec *v, matrix box) +void gmx_espresso_read_conf(const char* infile, t_symtab* symtab, char** name, t_atoms* atoms, rvec x[], rvec* v, matrix box) { - FILE *fp; - char word[STRLEN], buf[STRLEN]; - int level, r, nprop, p, i, m, molnr; - int prop[32]; - double d; - gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol; + FILE* fp; + char word[STRLEN], buf[STRLEN]; + int level, r, nprop, p, i, m, molnr; + int prop[32]; + double d; + gmx_bool bFoundParticles, bFoundProp, bFoundVariable, bMol; if (name != nullptr) { @@ -199,8 +197,8 @@ void gmx_espresso_read_conf(const char *infile, if (level == 1 && std::strcmp(word, "particles") == 0 && !bFoundParticles) { bFoundParticles = TRUE; - level += check_open_parenthesis(fp, r, infile, "particles"); - nprop = 0; + level += check_open_parenthesis(fp, r, infile, "particles"); + nprop = 0; while (level == 2 && (r = get_espresso_word(fp, word))) { bFoundProp = FALSE; @@ -217,7 +215,7 @@ void gmx_espresso_read_conf(const char *infile, if (debug) { - fprintf(debug, " prop[%d] = %s\n", nprop-1, esp_prop[prop[nprop-1]]); + fprintf(debug, " prop[%d] = %s\n", nprop - 1, esp_prop[prop[nprop - 1]]); } } } @@ -291,19 +289,18 @@ void gmx_espresso_read_conf(const char *infile, case espMOLECULE: r = get_espresso_word(fp, word); molnr = std::strtol(word, nullptr, 10); - if (i == 0 || - atoms->resinfo[atoms->atom[i-1].resind].nr != molnr) + if (i == 0 || atoms->resinfo[atoms->atom[i - 1].resind].nr != molnr) { - atoms->atom[i].resind = - (i == 0 ? 0 : atoms->atom[i-1].resind+1); - atoms->resinfo[atoms->atom[i].resind].nr = molnr; - atoms->resinfo[atoms->atom[i].resind].ic = ' '; - atoms->resinfo[atoms->atom[i].resind].chainid = ' '; - atoms->resinfo[atoms->atom[i].resind].chainnum = molnr; /* Not sure if this is right? */ + atoms->atom[i].resind = (i == 0 ? 0 : atoms->atom[i - 1].resind + 1); + atoms->resinfo[atoms->atom[i].resind].nr = molnr; + atoms->resinfo[atoms->atom[i].resind].ic = ' '; + atoms->resinfo[atoms->atom[i].resind].chainid = ' '; + atoms->resinfo[atoms->atom[i].resind].chainnum = + molnr; /* Not sure if this is right? */ } else { - atoms->atom[i].resind = atoms->atom[i-1].resind; + atoms->atom[i].resind = atoms->atom[i - 1].resind; } break; } @@ -313,10 +310,9 @@ void gmx_espresso_read_conf(const char *infile, atoms->atomname[i] = put_symtab(symtab, buf); if (bMol) { - if (i == 0 || atoms->atom[i].resind != atoms->atom[i-1].resind) + if (i == 0 || atoms->atom[i].resind != atoms->atom[i - 1].resind) { - atoms->resinfo[atoms->atom[i].resind].name = - put_symtab(symtab, "MOL"); + atoms->resinfo[atoms->atom[i].resind].name = put_symtab(symtab, "MOL"); } } else @@ -326,12 +322,12 @@ void gmx_espresso_read_conf(const char *infile, /* Generate an residue name from the particle type */ if (atoms->atom[i].type < 26) { - sprintf(buf, "T%c", 'A'+atoms->atom[i].type); + sprintf(buf, "T%c", 'A' + atoms->atom[i].type); } else { - sprintf(buf, "T%c%c", - 'A'+atoms->atom[i].type/26, 'A'+atoms->atom[i].type%26); + sprintf(buf, "T%c%c", 'A' + atoms->atom[i].type / 26, + 'A' + atoms->atom[i].type % 26); } t_atoms_set_resinfo(atoms, i, symtab, buf, i, ' ', 0, ' '); } @@ -347,13 +343,16 @@ void gmx_espresso_read_conf(const char *infile, if (i != atoms->nr) { - gmx_fatal(FARGS, "Internal inconsistency in Espresso routines, read %d atoms, expected %d atoms", i, atoms->nr); + gmx_fatal(FARGS, + "Internal inconsistency in Espresso routines, read %d atoms, expected %d " + "atoms", + i, atoms->nr); } } else if (level == 1 && std::strcmp(word, "variable") == 0 && !bFoundVariable) { bFoundVariable = TRUE; - level += check_open_parenthesis(fp, r, infile, "variable"); + level += check_open_parenthesis(fp, r, infile, "variable"); while (level == 2 && (r = get_espresso_word(fp, word))) { if (level == 2 && std::strcmp(word, "box_l") == 0) @@ -380,16 +379,15 @@ void gmx_espresso_read_conf(const char *infile, if (!bFoundParticles) { - fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n", - infile); + fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n", infile); } gmx_fio_fclose(fp); } -int get_espresso_coordnum(const char *infile) +int get_espresso_coordnum(const char* infile) { - FILE *fp; + FILE* fp; char word[STRLEN]; int natoms, level, r; gmx_bool bFoundParticles; @@ -405,7 +403,7 @@ int get_espresso_coordnum(const char *infile) if (level == 1 && strcmp(word, "particles") == 0 && !bFoundParticles) { bFoundParticles = TRUE; - level += check_open_parenthesis(fp, r, infile, "particles"); + level += check_open_parenthesis(fp, r, infile, "particles"); while (level > 0 && (r = get_espresso_word(fp, word))) { if (r == 2) @@ -433,8 +431,7 @@ int get_espresso_coordnum(const char *infile) } if (!bFoundParticles) { - fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n", - infile); + fprintf(stderr, "Did not find a particles section in Espresso file '%s'\n", infile); } gmx_fio_fclose(fp); @@ -442,9 +439,14 @@ int get_espresso_coordnum(const char *infile) return natoms; } -void write_espresso_conf_indexed(FILE *out, const char *title, - const t_atoms *atoms, int nx, const int *index, - const rvec *x, const rvec *v, const matrix box) +void write_espresso_conf_indexed(FILE* out, + const char* title, + const t_atoms* atoms, + int nx, + const int* index, + const rvec* x, + const rvec* v, + const matrix box) { int i, j; @@ -466,9 +468,8 @@ void write_espresso_conf_indexed(FILE *out, const char *title, { j = i; } - fprintf(out, "\t{%d %f %f %f %hu %g", - j, x[j][XX], x[j][YY], x[j][ZZ], - atoms->atom[j].type, atoms->atom[j].q); + fprintf(out, "\t{%d %f %f %f %hu %g", j, x[j][XX], x[j][YY], x[j][ZZ], atoms->atom[j].type, + atoms->atom[j].q); if (v) { fprintf(out, " %f %f %f", v[j][XX], v[j][YY], v[j][ZZ]); diff --git a/src/gromacs/fileio/espio.h b/src/gromacs/fileio/espio.h index bcbee55cb3..f22fd1c930 100644 --- a/src/gromacs/fileio/espio.h +++ b/src/gromacs/fileio/espio.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2005, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,17 +43,26 @@ struct t_atoms; struct t_symtab; -void gmx_espresso_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], rvec *v, matrix box); +void gmx_espresso_read_conf(const char* infile, + t_symtab* symtab, + char** name, + t_atoms* atoms, + rvec x[], + rvec* v, + matrix box); /* If name is not nullptr, gmx_strdup the title string into * it. Reading a title from espresso format is not , so this will * always be an empty string. */ -int get_espresso_coordnum(const char *infile); +int get_espresso_coordnum(const char* infile); -void write_espresso_conf_indexed(FILE *out, const char *title, - const t_atoms *atoms, int nx, const int *index, - const rvec *x, const rvec *v, const matrix box); +void write_espresso_conf_indexed(FILE* out, + const char* title, + const t_atoms* atoms, + int nx, + const int* index, + const rvec* x, + const rvec* v, + const matrix box); #endif diff --git a/src/gromacs/fileio/filetypes.cpp b/src/gromacs/fileio/filetypes.cpp index ff15328876..380f91248a 100644 --- a/src/gromacs/fileio/filetypes.cpp +++ b/src/gromacs/fileio/filetypes.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,121 +45,102 @@ enum { - eftASC, eftXDR, eftTNG, eftGEN, eftNR + eftASC, + eftXDR, + eftTNG, + eftGEN, + eftNR }; /* To support multiple file types with one general (eg TRX) we have * these arrays. */ -static const int trxs[] = -{ - efXTC, efTRR, efCPT, - efGRO, efG96, efPDB, efTNG -}; +static const int trxs[] = { efXTC, efTRR, efCPT, efGRO, efG96, efPDB, efTNG }; #define NTRXS asize(trxs) -static const int trcompressed[] = -{ - efXTC, - efTNG -}; +static const int trcompressed[] = { efXTC, efTNG }; #define NTRCOMPRESSED asize(trcompressed) -static const int tros[] = -{ - efXTC, efTRR, - efGRO, efG96, efPDB, efTNG -}; +static const int tros[] = { efXTC, efTRR, efGRO, efG96, efPDB, efTNG }; #define NTROS asize(tros) -static const int trns[] = -{ - efTRR, efCPT, - efTNG -}; +static const int trns[] = { efTRR, efCPT, efTNG }; #define NTRNS asize(trns) -static const int stos[] = -{ efGRO, efG96, efPDB, efBRK, efENT, efESP }; +static const int stos[] = { efGRO, efG96, efPDB, efBRK, efENT, efESP }; #define NSTOS asize(stos) -static const int stxs[] = -{ - efGRO, efG96, efPDB, efBRK, efENT, efESP, - efTPR -}; +static const int stxs[] = { efGRO, efG96, efPDB, efBRK, efENT, efESP, efTPR }; #define NSTXS asize(stxs) -static const int tpss[] = -{ - efTPR, - efGRO, efG96, efPDB, efBRK, efENT -}; +static const int tpss[] = { efTPR, efGRO, efG96, efPDB, efBRK, efENT }; #define NTPSS asize(tpss) typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) { int ftype; - const char *ext; - const char *defnm; - const char *defopt; - const char *descr; + const char* ext; + const char* defnm; + const char* defopt; + const char* descr; int ntps; - const int *tps; + const int* tps; } t_deffile; /* this array should correspond to the enum in filetypes.h */ -static const t_deffile deffile[efNR] = -{ +static const t_deffile deffile[efNR] = { { eftASC, ".mdp", "grompp", "-f", "grompp input file with MD parameters" }, { eftGEN, ".???", "traj", "-f", "Trajectory", NTRXS, trxs }, { eftGEN, ".???", "trajout", "-f", "Trajectory", NTROS, tros }, - { eftGEN, ".???", "traj", nullptr, - "Full precision trajectory", NTRNS, trns }, + { eftGEN, ".???", "traj", nullptr, "Full precision trajectory", NTRNS, trns }, { eftXDR, ".trr", "traj", nullptr, "Trajectory in portable xdr format" }, { eftGEN, ".???", "traj_comp", nullptr, - "Compressed trajectory (tng format or portable xdr format)", NTRCOMPRESSED, trcompressed}, - { eftXDR, ".xtc", "traj", nullptr, - "Compressed trajectory (portable xdr format): xtc" }, - { eftTNG, ".tng", "traj", nullptr, - "Trajectory file (tng format)" }, - { eftXDR, ".edr", "ener", nullptr, "Energy file"}, + "Compressed trajectory (tng format or portable xdr format)", NTRCOMPRESSED, trcompressed }, + { eftXDR, ".xtc", "traj", nullptr, "Compressed trajectory (portable xdr format): xtc" }, + { eftTNG, ".tng", "traj", nullptr, "Trajectory file (tng format)" }, + { eftXDR, ".edr", "ener", nullptr, "Energy file" }, { eftGEN, ".???", "conf", "-c", "Structure file", NSTXS, stxs }, { eftGEN, ".???", "out", "-o", "Structure file", NSTOS, stos }, { eftASC, ".gro", "conf", "-c", "Coordinate file in Gromos-87 format" }, { eftASC, ".g96", "conf", "-c", "Coordinate file in Gromos-96 format" }, - { eftASC, ".pdb", "eiwit", "-f", "Protein data bank file"}, - { eftASC, ".brk", "eiwit", "-f", "Brookhaven data bank file"}, + { eftASC, ".pdb", "eiwit", "-f", "Protein data bank file" }, + { eftASC, ".brk", "eiwit", "-f", "Brookhaven data bank file" }, { eftASC, ".ent", "eiwit", "-f", "Entry in the protein date bank" }, { eftASC, ".esp", "conf", "-f", "Coordinate file in Espresso format" }, - { eftASC, ".pqr", "state", "-o", "Coordinate file for MEAD"}, - { eftXDR, ".cpt", "state", "-cp", "Checkpoint file"}, - { eftASC, ".log", "run", "-l", "Log file"}, - { eftASC, ".xvg", "graph", "-o", "xvgr/xmgr file"}, - { eftASC, ".out", "hello", "-o", "Generic output file"}, - { eftASC, ".ndx", "index", "-n", "Index file", }, - { eftASC, ".top", "topol", "-p", "Topology file"}, - { eftASC, ".itp", "topinc", nullptr, "Include file for topology"}, + { eftASC, ".pqr", "state", "-o", "Coordinate file for MEAD" }, + { eftXDR, ".cpt", "state", "-cp", "Checkpoint file" }, + { eftASC, ".log", "run", "-l", "Log file" }, + { eftASC, ".xvg", "graph", "-o", "xvgr/xmgr file" }, + { eftASC, ".out", "hello", "-o", "Generic output file" }, + { + eftASC, + ".ndx", + "index", + "-n", + "Index file", + }, + { eftASC, ".top", "topol", "-p", "Topology file" }, + { eftASC, ".itp", "topinc", nullptr, "Include file for topology" }, { eftGEN, ".???", "topol", "-s", "Structure+mass(db)", NTPSS, tpss }, - { eftXDR, ".tpr", "topol", "-s", "Portable xdr run input file"}, - { eftASC, ".tex", "doc", "-o", "LaTeX file"}, + { eftXDR, ".tpr", "topol", "-s", "Portable xdr run input file" }, + { eftASC, ".tex", "doc", "-o", "LaTeX file" }, { eftASC, ".rtp", "residue", nullptr, "Residue Type file used by pdb2gmx" }, { eftASC, ".atp", "atomtp", nullptr, "Atomtype file used by pdb2gmx" }, - { eftASC, ".hdb", "polar", nullptr, "Hydrogen data base"}, - { eftASC, ".dat", "nnnice", nullptr, "Generic data file"}, - { eftASC, ".dlg", "user", nullptr, "Dialog Box data for ngmx"}, + { eftASC, ".hdb", "polar", nullptr, "Hydrogen data base" }, + { eftASC, ".dat", "nnnice", nullptr, "Generic data file" }, + { eftASC, ".dlg", "user", nullptr, "Dialog Box data for ngmx" }, { eftASC, ".map", "ss", nullptr, "File that maps matrix data to colors" }, { eftASC, ".eps", "plot", nullptr, "Encapsulated PostScript (tm) file" }, - { eftASC, ".mat", "ss", nullptr, "Matrix Data file"}, - { eftASC, ".m2p", "ps", nullptr, "Input file for mat2ps"}, - { eftXDR, ".mtx", "hessian", "-m", "Hessian matrix"}, - { eftASC, ".edi", "sam", nullptr, "ED sampling input"}, - { eftASC, ".cub", "pot", nullptr, "Gaussian cube file" }, + { eftASC, ".mat", "ss", nullptr, "Matrix Data file" }, + { eftASC, ".m2p", "ps", nullptr, "Input file for mat2ps" }, + { eftXDR, ".mtx", "hessian", "-m", "Hessian matrix" }, + { eftASC, ".edi", "sam", nullptr, "ED sampling input" }, + { eftASC, ".cub", "pot", nullptr, "Gaussian cube file" }, { eftASC, ".xpm", "root", nullptr, "X PixMap compatible matrix file" }, { eftASC, "", "rundir", nullptr, "Run directory" } }; -const char *ftp2ext(int ftp) +const char* ftp2ext(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -171,24 +152,18 @@ const char *ftp2ext(int ftp) } } -const char *ftp2ext_generic(int ftp) +const char* ftp2ext_generic(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { switch (ftp) { - case efTRX: - return "trx"; - case efTRN: - return "trn"; - case efSTO: - return "sto"; - case efSTX: - return "stx"; - case efTPS: - return "tps"; - default: - return ftp2ext(ftp); + case efTRX: return "trx"; + case efTRN: return "trn"; + case efSTO: return "sto"; + case efSTX: return "stx"; + case efTPS: return "tps"; + default: return ftp2ext(ftp); } } else @@ -197,7 +172,7 @@ const char *ftp2ext_generic(int ftp) } } -const char *ftp2ext_with_dot(int ftp) +const char* ftp2ext_with_dot(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -221,7 +196,7 @@ int ftp2generic_count(int ftp) } } -const int *ftp2generic_list(int ftp) +const int* ftp2generic_list(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -233,7 +208,7 @@ const int *ftp2generic_list(int ftp) } } -const char *ftp2desc(int ftp) +const char* ftp2desc(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -263,7 +238,7 @@ gmx_bool ftp_is_xdr(int ftp) return FALSE; } -const char *ftp2defnm(int ftp) +const char* ftp2defnm(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -275,7 +250,7 @@ const char *ftp2defnm(int ftp) } } -const char *ftp2defopt(int ftp) +const char* ftp2defopt(int ftp) { if ((0 <= ftp) && (ftp < efNR)) { @@ -287,11 +262,11 @@ const char *ftp2defopt(int ftp) } } -int fn2ftp(const char *fn) +int fn2ftp(const char* fn) { int i, len; - const char *feptr; - const char *eptr; + const char* feptr; + const char* eptr; if (!fn) { diff --git a/src/gromacs/fileio/filetypes.h b/src/gromacs/fileio/filetypes.h index c6008d5a25..d56e1997b1 100644 --- a/src/gromacs/fileio/filetypes.h +++ b/src/gromacs/fileio/filetypes.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,19 +40,45 @@ #include "gromacs/utility/basedefinitions.h" /* this enum should correspond to the array deffile in filetypes.cpp */ -enum GromacsFileType { +enum GromacsFileType +{ efMDP, - efTRX, efTRO, efTRN, efTRR, efCOMPRESSED, efXTC, efTNG, + efTRX, + efTRO, + efTRN, + efTRR, + efCOMPRESSED, + efXTC, + efTNG, efEDR, - efSTX, efSTO, efGRO, efG96, efPDB, efBRK, efENT, efESP, efPQR, + efSTX, + efSTO, + efGRO, + efG96, + efPDB, + efBRK, + efENT, + efESP, + efPQR, efCPT, - efLOG, efXVG, efOUT, + efLOG, + efXVG, + efOUT, efNDX, - efTOP, efITP, - efTPS, efTPR, - efTEX, efRTP, efATP, efHDB, - efDAT, efDLG, - efMAP, efEPS, efMAT, efM2P, + efTOP, + efITP, + efTPS, + efTPR, + efTEX, + efRTP, + efATP, + efHDB, + efDAT, + efDLG, + efMAP, + efEPS, + efMAT, + efM2P, efMTX, efEDI, efCUB, @@ -61,35 +87,35 @@ enum GromacsFileType { efNR }; -const char *ftp2ext(int ftp); +const char* ftp2ext(int ftp); /* Return extension for filetype */ -const char *ftp2ext_generic(int ftp); +const char* ftp2ext_generic(int ftp); /* Return extension for filetype, and a generic name for generic types (e.g. trx)*/ -const char *ftp2ext_with_dot(int ftp); +const char* ftp2ext_with_dot(int ftp); /* Return extension for filetype with a leading dot */ int ftp2generic_count(int ftp); /* Return the number of filetypes for a generic filetype */ -const int *ftp2generic_list(int ftp); +const int* ftp2generic_list(int ftp); /* Return the list of filetypes for a generic filetype */ -const char *ftp2desc(int ftp); +const char* ftp2desc(int ftp); /* Return description for file type */ -const char *ftp2defnm(int ftp); +const char* ftp2defnm(int ftp); /* Return default file name for file type */ -const char *ftp2defopt(int ftp); +const char* ftp2defopt(int ftp); /* Return default option name for file type */ gmx_bool ftp_is_text(int ftp); gmx_bool ftp_is_xdr(int ftp); -int fn2ftp(const char *fn); +int fn2ftp(const char* fn); /* Return the filetype corrsponding to filename */ #endif diff --git a/src/gromacs/fileio/g96io.cpp b/src/gromacs/fileio/g96io.cpp index ff4dfbf16e..89c3557f51 100644 --- a/src/gromacs/fileio/g96io.cpp +++ b/src/gromacs/fileio/g96io.cpp @@ -53,22 +53,22 @@ #define CHAR_SHIFT 24 -static int read_g96_pos(char line[], t_symtab *symtab, - FILE *fp, const char *infile, - t_trxframe *fr) +static int read_g96_pos(char line[], t_symtab* symtab, FILE* fp, const char* infile, t_trxframe* fr) { - t_atoms *atoms; - gmx_bool bEnd; - int nwanted, natoms, atnr, resnr = 0, oldres, newres, shift; - char anm[STRLEN], resnm[STRLEN]; - char c1, c2; - double db1, db2, db3; + t_atoms* atoms; + gmx_bool bEnd; + int nwanted, natoms, atnr, resnr = 0, oldres, newres, shift; + char anm[STRLEN], resnm[STRLEN]; + char c1, c2; + double db1, db2, db3; nwanted = fr->natoms; if (fr->atoms != nullptr) { - GMX_RELEASE_ASSERT(symtab != nullptr, "Reading a conformation from a g96 format with atom data requires a valid symbol table"); + GMX_RELEASE_ASSERT(symtab != nullptr, + "Reading a conformation from a g96 format with atom data requires a " + "valid symbol table"); } atoms = fr->atoms; if (atoms != nullptr) @@ -92,30 +92,27 @@ static int read_g96_pos(char line[], t_symtab *symtab, { shift = 0; } - newres = -1; - oldres = -666; /* Unlikely number for the first residue! */ - bEnd = FALSE; + newres = -1; + oldres = -666; /* Unlikely number for the first residue! */ + bEnd = FALSE; while (!bEnd && fgets2(line, STRLEN, fp)) { bEnd = (std::strncmp(line, "END", 3) == 0); - if (!bEnd && (line[0] != '#')) + if (!bEnd && (line[0] != '#')) { - if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3) + if (sscanf(line + shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3) { - gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n", - natoms+1, infile); + gmx_fatal(FARGS, "Did not find 3 coordinates for atom %d in %s\n", natoms + 1, infile); } if ((nwanted != -1) && (natoms >= nwanted)) { - gmx_fatal(FARGS, - "Found more coordinates (%d) in %s than expected %d\n", - natoms, infile, nwanted); + gmx_fatal(FARGS, "Found more coordinates (%d) in %s than expected %d\n", natoms, + infile, nwanted); } if (atoms) { - if (fr->bAtoms && - (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr) - != 6)) + if (fr->bAtoms + && (sscanf(line, "%5d%c%5s%c%5s%7d", &resnr, &c1, resnm, &c2, anm, &atnr) != 6)) { if (oldres >= 0) { @@ -123,10 +120,10 @@ static int read_g96_pos(char line[], t_symtab *symtab, } else { - resnr = 1; - strncpy(resnm, "???", sizeof(resnm)-1); + resnr = 1; + strncpy(resnm, "???", sizeof(resnm) - 1); } - strncpy(anm, "???", sizeof(anm)-1); + strncpy(anm, "???", sizeof(anm) - 1); } atoms->atomname[natoms] = put_symtab(symtab, anm); if (resnr != oldres) @@ -135,13 +132,13 @@ static int read_g96_pos(char line[], t_symtab *symtab, newres++; if (newres >= atoms->nr) { - gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", - infile, atoms->nr); + gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", infile, + atoms->nr); } atoms->atom[natoms].resind = newres; - if (newres+1 > atoms->nres) + if (newres + 1 > atoms->nres) { - atoms->nres = newres+1; + atoms->nres = newres + 1; } t_atoms_set_resinfo(atoms, natoms, symtab, resnm, resnr, ' ', 0, ' '); } @@ -161,9 +158,8 @@ static int read_g96_pos(char line[], t_symtab *symtab, } if ((nwanted != -1) && natoms != nwanted) { - fprintf(stderr, - "Warning: found less coordinates (%d) in %s than expected %d\n", - natoms, infile, nwanted); + fprintf(stderr, "Warning: found less coordinates (%d) in %s than expected %d\n", natoms, + infile, nwanted); } } @@ -172,12 +168,11 @@ static int read_g96_pos(char line[], t_symtab *symtab, return natoms; } -static int read_g96_vel(char line[], FILE *fp, const char *infile, - t_trxframe *fr) +static int read_g96_vel(char line[], FILE* fp, const char* infile, t_trxframe* fr) { - gmx_bool bEnd; - int nwanted, natoms = -1, shift; - double db1, db2, db3; + gmx_bool bEnd; + int nwanted, natoms = -1, shift; + double db1, db2, db3; nwanted = fr->natoms; @@ -198,15 +193,14 @@ static int read_g96_vel(char line[], FILE *fp, const char *infile, bEnd = (strncmp(line, "END", 3) == 0); if (!bEnd && (line[0] != '#')) { - if (sscanf(line+shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3) + if (sscanf(line + shift, "%15lf%15lf%15lf", &db1, &db2, &db3) != 3) { - gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s", - natoms+1, infile); + gmx_fatal(FARGS, "Did not find 3 velocities for atom %d in %s", natoms + 1, infile); } if ((nwanted != -1) && (natoms >= nwanted)) { - gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n", - natoms, infile, nwanted); + gmx_fatal(FARGS, "Found more velocities (%d) in %s than expected %d\n", natoms, + infile, nwanted); } if (fr->v) { @@ -219,21 +213,19 @@ static int read_g96_vel(char line[], FILE *fp, const char *infile, } if ((nwanted != -1) && (natoms != nwanted)) { - fprintf(stderr, - "Warning: found less velocities (%d) in %s than expected %d\n", - natoms, infile, nwanted); + fprintf(stderr, "Warning: found less velocities (%d) in %s than expected %d\n", natoms, + infile, nwanted); } } return natoms; } -int read_g96_conf(FILE *fp, const char *infile, char **name, t_trxframe *fr, - t_symtab *symtab, char *line) +int read_g96_conf(FILE* fp, const char* infile, char** name, t_trxframe* fr, t_symtab* symtab, char* line) { - gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished; - int natoms, nbp; - double db1, db2, db3, db4, db5, db6, db7, db8, db9; + gmx_bool bAtStart, bTime, bAtoms, bPos, bVel, bBox, bEnd, bFinished; + int natoms, nbp; + double db1, db2, db3, db4, db5, db6, db7, db8, db9; bAtStart = (ftell(fp) == 0); @@ -282,8 +274,7 @@ int read_g96_conf(FILE *fp, const char *infile, char **name, t_trxframe *fr, do { bFinished = (fgets2(line, STRLEN, fp) == nullptr); - } - while (!bFinished && (line[0] == '#')); + } while (!bFinished && (line[0] == '#')); sscanf(line, "%15" SCNd64 "%15lf", &(fr->step), &db1); fr->time = db1; } @@ -320,8 +311,8 @@ int read_g96_conf(FILE *fp, const char *infile, char **name, t_trxframe *fr, bEnd = (strncmp(line, "END", 3) == 0); if (!bEnd && (line[0] != '#')) { - nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf", - &db1, &db2, &db3, &db4, &db5, &db6, &db7, &db8, &db9); + nbp = sscanf(line, "%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf%15lf", &db1, &db2, + &db3, &db4, &db5, &db6, &db7, &db8, &db9); if (nbp < 3) { gmx_fatal(FARGS, "Found a BOX line, but no box in %s", infile); @@ -342,18 +333,16 @@ int read_g96_conf(FILE *fp, const char *infile, char **name, t_trxframe *fr, } bFinished = TRUE; } - } - while (!bFinished && (fgets2(line, STRLEN, fp) != nullptr)); + } while (!bFinished && (fgets2(line, STRLEN, fp) != nullptr)); fr->natoms = natoms; return natoms; } -void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, - int nindex, const int *index) +void write_g96_conf(FILE* out, const char* title, const t_trxframe* fr, int nindex, const int* index) { - t_atoms *atoms; + t_atoms* atoms; int nout, i, a; atoms = fr->atoms; @@ -390,9 +379,8 @@ void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, } fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n", (atoms->resinfo[atoms->atom[a].resind].nr) % 100000, - *atoms->resinfo[atoms->atom[a].resind].name, - *atoms->atomname[a], (i+1) % 10000000, - fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]); + *atoms->resinfo[atoms->atom[a].resind].name, *atoms->atomname[a], + (i + 1) % 10000000, fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]); } } else @@ -408,8 +396,7 @@ void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, { a = i; } - fprintf(out, "%15.9f%15.9f%15.9f\n", - fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]); + fprintf(out, "%15.9f%15.9f%15.9f\n", fr->x[a][XX], fr->x[a][YY], fr->x[a][ZZ]); } } fprintf(out, "END\n"); @@ -431,9 +418,8 @@ void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, } fprintf(out, "%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n", (atoms->resinfo[atoms->atom[a].resind].nr) % 100000, - *atoms->resinfo[atoms->atom[a].resind].name, - *atoms->atomname[a], (i+1) % 10000000, - fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]); + *atoms->resinfo[atoms->atom[a].resind].name, *atoms->atomname[a], + (i + 1) % 10000000, fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]); } } else @@ -449,8 +435,7 @@ void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, { a = i; } - fprintf(out, "%15.9f%15.9f%15.9f\n", - fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]); + fprintf(out, "%15.9f%15.9f%15.9f\n", fr->v[a][XX], fr->v[a][YY], fr->v[a][ZZ]); } } fprintf(out, "END\n"); @@ -458,14 +443,12 @@ void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, if (fr->bBox) { fprintf(out, "BOX\n"); - fprintf(out, "%15.9f%15.9f%15.9f", - fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]); - if ((fr->box[XX][YY] != 0.0F) || (fr->box[XX][ZZ] != 0.0F) || (fr->box[YY][XX] != 0.0F) || - (fr->box[YY][ZZ] != 0.0F) || (fr->box[ZZ][XX] != 0.0F) || (fr->box[ZZ][YY] != 0.0F)) + fprintf(out, "%15.9f%15.9f%15.9f", fr->box[XX][XX], fr->box[YY][YY], fr->box[ZZ][ZZ]); + if ((fr->box[XX][YY] != 0.0F) || (fr->box[XX][ZZ] != 0.0F) || (fr->box[YY][XX] != 0.0F) + || (fr->box[YY][ZZ] != 0.0F) || (fr->box[ZZ][XX] != 0.0F) || (fr->box[ZZ][YY] != 0.0F)) { - fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f", - fr->box[XX][YY], fr->box[XX][ZZ], fr->box[YY][XX], - fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]); + fprintf(out, "%15.9f%15.9f%15.9f%15.9f%15.9f%15.9f", fr->box[XX][YY], fr->box[XX][ZZ], + fr->box[YY][XX], fr->box[YY][ZZ], fr->box[ZZ][XX], fr->box[ZZ][YY]); } fprintf(out, "\n"); fprintf(out, "END\n"); diff --git a/src/gromacs/fileio/g96io.h b/src/gromacs/fileio/g96io.h index 92eb63e774..11ab938959 100644 --- a/src/gromacs/fileio/g96io.h +++ b/src/gromacs/fileio/g96io.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,8 +43,7 @@ struct t_symtab; struct t_trxframe; -int read_g96_conf(FILE *fp, const char *infile, char **name, struct t_trxframe *fr, - struct t_symtab *symtab, char *line); +int read_g96_conf(FILE* fp, const char* infile, char** name, struct t_trxframe* fr, struct t_symtab* symtab, char* line); /* read a Gromos96 coordinate or trajectory file, * * returns the number of atoms * * sets what's in the frame in info * @@ -58,7 +57,7 @@ int read_g96_conf(FILE *fp, const char *infile, char **name, struct t_trxframe * * * If name is not nullptr, gmx_strdup the first g96 title string into it. */ -void write_g96_conf(FILE *out, const char *title, const t_trxframe *fr, int nindex, const int *index); +void write_g96_conf(FILE* out, const char* title, const t_trxframe* fr, int nindex, const int* index); /* write a Gromos96 coordinate file or trajectory frame * * index can be NULL */ diff --git a/src/gromacs/fileio/gmx_internal_xdr.cpp b/src/gromacs/fileio/gmx_internal_xdr.cpp index 22760e89ff..2ae62422b5 100644 --- a/src/gromacs/fileio/gmx_internal_xdr.cpp +++ b/src/gromacs/fileio/gmx_internal_xdr.cpp @@ -41,10 +41,10 @@ #if GMX_INTERNAL_XDR -#include "gmx_internal_xdr.h" +# include "gmx_internal_xdr.h" -#include -#include +# include +# include /* NB - THIS FILE IS ONLY USED ON MICROSOFT WINDOWS, since that @@ -92,22 +92,21 @@ */ - /* * for unit alignment */ -static char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0}; +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; static xdr_uint32_t xdr_swapbytes(xdr_uint32_t x) { xdr_uint32_t y; int i; - char *px = reinterpret_cast(&x); - char *py = reinterpret_cast(&y); + char* px = reinterpret_cast(&x); + char* py = reinterpret_cast(&y); for (i = 0; i < 4; i++) { - py[i] = px[3-i]; + py[i] = px[3 - i]; } return y; @@ -116,7 +115,7 @@ static xdr_uint32_t xdr_swapbytes(xdr_uint32_t x) static xdr_uint32_t xdr_htonl(xdr_uint32_t x) { short s = 0x0F00; - if (*(reinterpret_cast(&s)) == static_cast(0x0F)) + if (*(reinterpret_cast(&s)) == static_cast(0x0F)) { /* bigendian, do nothing */ return x; @@ -131,7 +130,7 @@ static xdr_uint32_t xdr_htonl(xdr_uint32_t x) static xdr_uint32_t xdr_ntohl(xdr_uint32_t x) { short s = 0x0F00; - if (*(reinterpret_cast(&s)) == static_cast(0x0F)) + if (*(reinterpret_cast(&s)) == static_cast(0x0F)) { /* bigendian, do nothing */ return x; @@ -148,20 +147,18 @@ static xdr_uint32_t xdr_ntohl(xdr_uint32_t x) * Free a data structure using XDR * Not a filter, but a convenient utility nonetheless */ -void -xdr_free (xdrproc_t proc, char *objp) +void xdr_free(xdrproc_t proc, char* objp) { XDR x; x.x_op = XDR_FREE; - (*proc) ( &x, objp); + (*proc)(&x, objp); } /* * XDR nothing */ -bool_t -xdr_void () +bool_t xdr_void() { return TRUE; } @@ -169,27 +166,23 @@ xdr_void () /* * XDR integers */ -bool_t -xdr_int (XDR *xdrs, int *ip) +bool_t xdr_int(XDR* xdrs, int* ip) { xdr_int32_t l; switch (xdrs->x_op) { - case XDR_ENCODE: - l = static_cast(*ip); - return xdr_putint32 (xdrs, &l); + case XDR_ENCODE: l = static_cast(*ip); return xdr_putint32(xdrs, &l); case XDR_DECODE: - if (!xdr_getint32 (xdrs, &l)) + if (!xdr_getint32(xdrs, &l)) { return FALSE; } *ip = static_cast(l); return TRUE; - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; } @@ -198,58 +191,48 @@ xdr_int (XDR *xdrs, int *ip) /* * XDR unsigned integers */ -bool_t -xdr_u_int (XDR *xdrs, unsigned int *up) +bool_t xdr_u_int(XDR* xdrs, unsigned int* up) { xdr_uint32_t l; switch (xdrs->x_op) { - case XDR_ENCODE: - l = static_cast(*up); - return xdr_putuint32 (xdrs, &l); + case XDR_ENCODE: l = static_cast(*up); return xdr_putuint32(xdrs, &l); case XDR_DECODE: - if (!xdr_getuint32 (xdrs, &l)) + if (!xdr_getuint32(xdrs, &l)) { return FALSE; } *up = static_cast(l); return TRUE; - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; } - - /* * XDR short integers */ -bool_t -xdr_short (XDR *xdrs, short *sp) +bool_t xdr_short(XDR* xdrs, short* sp) { xdr_int32_t l; switch (xdrs->x_op) { - case XDR_ENCODE: - l = static_cast(*sp); - return xdr_putint32 (xdrs, &l); + case XDR_ENCODE: l = static_cast(*sp); return xdr_putint32(xdrs, &l); case XDR_DECODE: - if (!xdr_getint32 (xdrs, &l)) + if (!xdr_getint32(xdrs, &l)) { return FALSE; } *sp = static_cast(l); return TRUE; - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; } @@ -258,27 +241,23 @@ xdr_short (XDR *xdrs, short *sp) /* * XDR unsigned short integers */ -bool_t -xdr_u_short (XDR *xdrs, unsigned short *usp) +bool_t xdr_u_short(XDR* xdrs, unsigned short* usp) { xdr_uint32_t l; switch (xdrs->x_op) { - case XDR_ENCODE: - l = static_cast(*usp); - return xdr_putuint32 (xdrs, &l); + case XDR_ENCODE: l = static_cast(*usp); return xdr_putuint32(xdrs, &l); case XDR_DECODE: - if (!xdr_getuint32 (xdrs, &l)) + if (!xdr_getuint32(xdrs, &l)) { return FALSE; } *usp = static_cast(l); return TRUE; - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; } @@ -287,13 +266,12 @@ xdr_u_short (XDR *xdrs, unsigned short *usp) /* * XDR a char */ -bool_t -xdr_char (XDR *xdrs, char *cp) +bool_t xdr_char(XDR* xdrs, char* cp) { int i; i = (*cp); - if (!xdr_int (xdrs, &i)) + if (!xdr_int(xdrs, &i)) { return FALSE; } @@ -304,13 +282,12 @@ xdr_char (XDR *xdrs, char *cp) /* * XDR an unsigned char */ -bool_t -xdr_u_char (XDR *xdrs, unsigned char *cp) +bool_t xdr_u_char(XDR* xdrs, unsigned char* cp) { unsigned int u; u = (*cp); - if (!xdr_u_int (xdrs, &u)) + if (!xdr_u_int(xdrs, &u)) { return FALSE; } @@ -321,45 +298,39 @@ xdr_u_char (XDR *xdrs, unsigned char *cp) /* * XDR booleans */ -bool_t -xdr_bool (XDR *xdrs, int *bp) +bool_t xdr_bool(XDR* xdrs, int* bp) { -#define XDR_FALSE ((xdr_int32_t) 0) -#define XDR_TRUE ((xdr_int32_t) 1) +# define XDR_FALSE ((xdr_int32_t)0) +# define XDR_TRUE ((xdr_int32_t)1) xdr_int32_t lb; switch (xdrs->x_op) { - case XDR_ENCODE: - lb = *bp ? XDR_TRUE : XDR_FALSE; - return xdr_putint32 (xdrs, &lb); + case XDR_ENCODE: lb = *bp ? XDR_TRUE : XDR_FALSE; return xdr_putint32(xdrs, &lb); case XDR_DECODE: - if (!xdr_getint32 (xdrs, &lb)) + if (!xdr_getint32(xdrs, &lb)) { return FALSE; } *bp = (lb == XDR_FALSE) ? FALSE : TRUE; return TRUE; - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; -#undef XDR_FALSE -#undef XDR_TRUE +# undef XDR_FALSE +# undef XDR_TRUE } - /* * XDR opaque data * Allows the specification of a fixed size sequence of opaque bytes. * cp points to the opaque object and cnt gives the byte length. */ -bool_t -xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt) +bool_t xdr_opaque(XDR* xdrs, char* cp, unsigned int cnt) { unsigned int rndup; char crud[BYTES_PER_XDR_UNIT]; @@ -384,7 +355,7 @@ xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt) switch (xdrs->x_op) { case XDR_DECODE: - if (!xdr_getbytes (xdrs, cp, cnt)) + if (!xdr_getbytes(xdrs, cp, cnt)) { return FALSE; } @@ -392,10 +363,10 @@ xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt) { return TRUE; } - return xdr_getbytes (xdrs, crud, rndup); + return xdr_getbytes(xdrs, crud, rndup); case XDR_ENCODE: - if (!xdr_putbytes (xdrs, cp, cnt)) + if (!xdr_putbytes(xdrs, cp, cnt)) { return FALSE; } @@ -403,10 +374,9 @@ xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt) { return TRUE; } - return xdr_putbytes (xdrs, xdr_zero, rndup); + return xdr_putbytes(xdrs, xdr_zero, rndup); - case XDR_FREE: - return TRUE; + case XDR_FREE: return TRUE; } return FALSE; } @@ -420,9 +390,9 @@ xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt) * storage is allocated. The last parameter is the max allowed length * of the string as specified by a protocol. */ -bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize) +bool_t xdr_string(XDR* xdrs, char** cpp, unsigned int maxsize) { - char *sp = *cpp; /* sp is the actual string pointer */ + char* sp = *cpp; /* sp is the actual string pointer */ unsigned int size = 0; unsigned int nodesize = 0; @@ -436,7 +406,7 @@ bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize) { return TRUE; /* already free */ } - size = std::strlen (sp); + size = std::strlen(sp); break; case XDR_ENCODE: @@ -444,13 +414,12 @@ bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize) { return FALSE; } - size = std::strlen (sp); - break; - case XDR_DECODE: + size = std::strlen(sp); break; + case XDR_DECODE: break; } - if (!xdr_u_int (xdrs, &size)) + if (!xdr_u_int(xdrs, &size)) { return FALSE; } @@ -472,21 +441,20 @@ bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize) } if (sp == nullptr) { - *cpp = sp = static_cast(std::malloc (nodesize)); + *cpp = sp = static_cast(std::malloc(nodesize)); } if (sp == nullptr) { - (void) fputs ("xdr_string: out of memory\n", stderr); + (void)fputs("xdr_string: out of memory\n", stderr); return FALSE; } sp[size] = 0; - return xdr_opaque (xdrs, sp, size); + return xdr_opaque(xdrs, sp, size); - case XDR_ENCODE: - return xdr_opaque (xdrs, sp, size); + case XDR_ENCODE: return xdr_opaque(xdrs, sp, size); case XDR_FREE: - free (sp); + free(sp); *cpp = nullptr; return TRUE; } @@ -494,10 +462,9 @@ bool_t xdr_string (XDR *xdrs, char ** cpp, unsigned int maxsize) } - /* Floating-point stuff */ -bool_t xdr_float(XDR * xdrs, float * fp) +bool_t xdr_float(XDR* xdrs, float* fp) { xdr_int32_t tmp; @@ -505,26 +472,25 @@ bool_t xdr_float(XDR * xdrs, float * fp) { case XDR_ENCODE: - tmp = *(reinterpret_cast(fp)); + tmp = *(reinterpret_cast(fp)); return (xdr_putint32(xdrs, &tmp)); case XDR_DECODE: if (xdr_getint32(xdrs, &tmp)) { - *(reinterpret_cast(fp)) = tmp; + *(reinterpret_cast(fp)) = tmp; return (TRUE); } break; - case XDR_FREE: - return (TRUE); + case XDR_FREE: return (TRUE); } return (FALSE); } -bool_t xdr_double(XDR * xdrs, double * dp) +bool_t xdr_double(XDR* xdrs, double* dp) { /* Windows and some other systems dont define double-precision @@ -535,10 +501,10 @@ bool_t xdr_double(XDR * xdrs, double * dp) * be more expensive. */ /*static int LSW=-1;*/ /* Least significant fp word */ - int LSW = -1; /* Least significant fp word */ + int LSW = -1; /* Least significant fp word */ - int *ip; + int* ip; xdr_int32_t tmp[2]; if (LSW < 0) @@ -555,7 +521,7 @@ bool_t xdr_double(XDR * xdrs, double * dp) * B B 3f ef 9a dd 3c 0e 56 b8 */ - unsigned char ix = *(reinterpret_cast(&x)); + unsigned char ix = *(reinterpret_cast(&x)); if (ix == 0xdd || ix == 0x3f) { @@ -565,7 +531,7 @@ bool_t xdr_double(XDR * xdrs, double * dp) { LSW = 0; /* Small endian word order */ } - else /* Catch strange errors */ + else /* Catch strange errors */ { printf("Error when detecting floating-point word order.\n" "Do you have a non-IEEE system?\n" @@ -579,16 +545,14 @@ bool_t xdr_double(XDR * xdrs, double * dp) { case XDR_ENCODE: - ip = reinterpret_cast(dp); + ip = reinterpret_cast(dp); tmp[0] = ip[bool(LSW == 0)]; tmp[1] = ip[LSW]; - return static_cast(bool(xdr_putint32(xdrs, tmp)) && - bool(xdr_putint32(xdrs, tmp+1))); + return static_cast(bool(xdr_putint32(xdrs, tmp)) && bool(xdr_putint32(xdrs, tmp + 1))); case XDR_DECODE: - ip = reinterpret_cast(dp); - if (xdr_getint32(xdrs, tmp+!LSW) && - xdr_getint32(xdrs, tmp+LSW)) + ip = reinterpret_cast(dp); + if (xdr_getint32(xdrs, tmp + !LSW) && xdr_getint32(xdrs, tmp + LSW)) { ip[0] = tmp[0]; ip[1] = tmp[1]; @@ -597,8 +561,7 @@ bool_t xdr_double(XDR * xdrs, double * dp) break; - case XDR_FREE: - return (TRUE); + case XDR_FREE: return (TRUE); } return (FALSE); } @@ -616,87 +579,80 @@ bool_t xdr_double(XDR * xdrs, double * dp) * > elemsize: size of each element * > xdr_elem: routine to XDR each element */ -bool_t xdr_vector (XDR * xdrs, char * basep, unsigned int nelem, - unsigned int elemsize, xdrproc_t xdr_elem) +bool_t xdr_vector(XDR* xdrs, char* basep, unsigned int nelem, unsigned int elemsize, xdrproc_t xdr_elem) { -#define LASTUNSIGNED ((unsigned int)0-1) +# define LASTUNSIGNED ((unsigned int)0 - 1) unsigned int i; - char *elptr; + char* elptr; elptr = basep; for (i = 0; i < nelem; i++) { - if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED)) + if (!(*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { return FALSE; } elptr += elemsize; } return TRUE; -#undef LASTUNSIGNED +# undef LASTUNSIGNED } - -static bool_t xdrstdio_getbytes (XDR * /*xdrs*/, char * /*addr*/, unsigned int /*len*/); -static bool_t xdrstdio_putbytes (XDR * /*xdrs*/, char * /*addr*/, unsigned int /*len*/); -static unsigned int xdrstdio_getpos (XDR * /*xdrs*/); -static bool_t xdrstdio_setpos (XDR * /*xdrs*/, unsigned int /*pos*/); -static xdr_int32_t *xdrstdio_inline (XDR * /*xdrs*/, int /*len*/); -static void xdrstdio_destroy (XDR * /*xdrs*/); -static bool_t xdrstdio_getint32 (XDR * /*xdrs*/, xdr_int32_t * /*ip*/); -static bool_t xdrstdio_putint32 (XDR * /*xdrs*/, xdr_int32_t * /*ip*/); -static bool_t xdrstdio_getuint32 (XDR * /*xdrs*/, xdr_uint32_t * /*ip*/); -static bool_t xdrstdio_putuint32 (XDR * /*xdrs*/, xdr_uint32_t * /*ip*/); +static bool_t xdrstdio_getbytes(XDR* /*xdrs*/, char* /*addr*/, unsigned int /*len*/); +static bool_t xdrstdio_putbytes(XDR* /*xdrs*/, char* /*addr*/, unsigned int /*len*/); +static unsigned int xdrstdio_getpos(XDR* /*xdrs*/); +static bool_t xdrstdio_setpos(XDR* /*xdrs*/, unsigned int /*pos*/); +static xdr_int32_t* xdrstdio_inline(XDR* /*xdrs*/, int /*len*/); +static void xdrstdio_destroy(XDR* /*xdrs*/); +static bool_t xdrstdio_getint32(XDR* /*xdrs*/, xdr_int32_t* /*ip*/); +static bool_t xdrstdio_putint32(XDR* /*xdrs*/, xdr_int32_t* /*ip*/); +static bool_t xdrstdio_getuint32(XDR* /*xdrs*/, xdr_uint32_t* /*ip*/); +static bool_t xdrstdio_putuint32(XDR* /*xdrs*/, xdr_uint32_t* /*ip*/); /* * Destroy a stdio xdr stream. * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. */ -static void -xdrstdio_destroy (XDR *xdrs) +static void xdrstdio_destroy(XDR* xdrs) { - fflush (reinterpret_cast(xdrs->x_private)); + fflush(reinterpret_cast(xdrs->x_private)); /* xx should we close the file ?? */ } -static bool_t -xdrstdio_getbytes (XDR *xdrs, char *addr, unsigned int len) +static bool_t xdrstdio_getbytes(XDR* xdrs, char* addr, unsigned int len) { - if ((len != 0) && (fread (addr, static_cast(len), 1, - reinterpret_cast(xdrs->x_private)) != 1)) + if ((len != 0) + && (fread(addr, static_cast(len), 1, reinterpret_cast(xdrs->x_private)) != 1)) { return FALSE; } return TRUE; } -static bool_t -xdrstdio_putbytes (XDR *xdrs, char *addr, unsigned int len) +static bool_t xdrstdio_putbytes(XDR* xdrs, char* addr, unsigned int len) { - if ((len != 0) && (fwrite (addr, static_cast(len), 1, - reinterpret_cast(xdrs->x_private)) != 1)) + if ((len != 0) + && (fwrite(addr, static_cast(len), 1, reinterpret_cast(xdrs->x_private)) != 1)) { return FALSE; } return TRUE; } -static unsigned int -xdrstdio_getpos (XDR *xdrs) +static unsigned int xdrstdio_getpos(XDR* xdrs) { - return static_cast(ftell (reinterpret_cast(xdrs->x_private))); + return static_cast(ftell(reinterpret_cast(xdrs->x_private))); } -static bool_t -xdrstdio_setpos (XDR *xdrs, unsigned int pos) +static bool_t xdrstdio_setpos(XDR* xdrs, unsigned int pos) { - return fseek (reinterpret_cast(xdrs->x_private), static_cast(pos), 0) < 0 ? FALSE : TRUE; + return fseek(reinterpret_cast(xdrs->x_private), static_cast(pos), 0) < 0 ? FALSE + : TRUE; } -static xdr_int32_t * -xdrstdio_inline (XDR *xdrs, int len) +static xdr_int32_t* xdrstdio_inline(XDR* xdrs, int len) { (void)xdrs; (void)len; @@ -712,52 +668,48 @@ xdrstdio_inline (XDR *xdrs, int len) return nullptr; } -static bool_t -xdrstdio_getint32 (XDR *xdrs, xdr_int32_t *ip) +static bool_t xdrstdio_getint32(XDR* xdrs, xdr_int32_t* ip) { xdr_int32_t mycopy; - if (fread (&mycopy, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) + if (fread(&mycopy, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) { return FALSE; } - *ip = xdr_ntohl (mycopy); + *ip = xdr_ntohl(mycopy); return TRUE; } -static bool_t -xdrstdio_putint32 (XDR *xdrs, xdr_int32_t *ip) +static bool_t xdrstdio_putint32(XDR* xdrs, xdr_int32_t* ip) { - xdr_int32_t mycopy = xdr_htonl (*ip); + xdr_int32_t mycopy = xdr_htonl(*ip); ip = &mycopy; - if (fwrite (ip, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) + if (fwrite(ip, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) { return FALSE; } return TRUE; } -static bool_t -xdrstdio_getuint32 (XDR *xdrs, xdr_uint32_t *ip) +static bool_t xdrstdio_getuint32(XDR* xdrs, xdr_uint32_t* ip) { xdr_uint32_t mycopy; - if (fread (&mycopy, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) + if (fread(&mycopy, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) { return FALSE; } - *ip = xdr_ntohl (mycopy); + *ip = xdr_ntohl(mycopy); return TRUE; } -static bool_t -xdrstdio_putuint32 (XDR *xdrs, xdr_uint32_t *ip) +static bool_t xdrstdio_putuint32(XDR* xdrs, xdr_uint32_t* ip) { - xdr_uint32_t mycopy = xdr_htonl (*ip); + xdr_uint32_t mycopy = xdr_htonl(*ip); ip = &mycopy; - if (fwrite (ip, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) + if (fwrite(ip, 4, 1, reinterpret_cast(xdrs->x_private)) != 1) { return FALSE; } @@ -767,8 +719,7 @@ xdrstdio_putuint32 (XDR *xdrs, xdr_uint32_t *ip) /* * Ops vector for stdio type XDR */ -static struct XDR::xdr_ops xdrstdio_ops = -{ +static struct XDR::xdr_ops xdrstdio_ops = { xdrstdio_getbytes, /* deserialize counted bytes */ xdrstdio_putbytes, /* serialize counted bytes */ xdrstdio_getpos, /* get offset in the stream */ @@ -786,13 +737,12 @@ static struct XDR::xdr_ops xdrstdio_ops = * Sets the xdr stream handle xdrs for use on the stream file. * Operation flag is set to op. */ -void -xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op) +void xdrstdio_create(XDR* xdrs, FILE* file, enum xdr_op op) { - xdrs->x_op = op; - xdrs->x_ops = &xdrstdio_ops; - xdrs->x_private = reinterpret_cast(file); - xdrs->x_handy = 0; - xdrs->x_base = nullptr; + xdrs->x_op = op; + xdrs->x_ops = &xdrstdio_ops; + xdrs->x_private = reinterpret_cast(file); + xdrs->x_handy = 0; + xdrs->x_base = nullptr; } #endif /* GMX_INTERNAL_XDR */ diff --git a/src/gromacs/fileio/gmx_internal_xdr.h b/src/gromacs/fileio/gmx_internal_xdr.h index 008e025335..2af1d5ff83 100644 --- a/src/gromacs/fileio/gmx_internal_xdr.h +++ b/src/gromacs/fileio/gmx_internal_xdr.h @@ -104,35 +104,36 @@ typedef int bool_t; * long or short is 32 bits and die if none of them is :-) */ #if (INT_MAX == 2147483647) -typedef int xdr_int32_t; +typedef int xdr_int32_t; typedef unsigned int xdr_uint32_t; #elif (LONG_MAX == 2147483647L) -typedef long xdr_int32_t; +typedef long xdr_int32_t; typedef unsigned long xdr_uint32_t; #elif (SHRT_MAX == 2147483647) -typedef short xdr_int32_t; +typedef short xdr_int32_t; typedef unsigned short xdr_uint32_t; #else -# error ERROR: No 32 bit wide integer type found! +# error ERROR: No 32 bit wide integer type found! #endif -enum xdr_op { +enum xdr_op +{ XDR_ENCODE = 0, XDR_DECODE = 1, XDR_FREE = 2 }; #ifndef FALSE -# define FALSE (0) +# define FALSE (0) #endif #ifndef TRUE -# define TRUE (1) +# define TRUE (1) #endif -#define BYTES_PER_XDR_UNIT (4) +#define BYTES_PER_XDR_UNIT (4) /* Macro to round up to units of 4. */ -#define XDR_RNDUP(x) (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1)) +#define XDR_RNDUP(x) (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1)) /* @@ -144,35 +145,34 @@ enum xdr_op { typedef struct XDR XDR; struct XDR { - enum xdr_op x_op; /* operation; fast additional param */ + enum xdr_op x_op; /* operation; fast additional param */ struct xdr_ops { - bool_t (*x_getbytes) (XDR *__xdrs, char *__addr, unsigned int __len); + bool_t (*x_getbytes)(XDR* __xdrs, char* __addr, unsigned int __len); /* get some bytes from " */ - bool_t (*x_putbytes) (XDR *__xdrs, char *__addr, unsigned int __len); + bool_t (*x_putbytes)(XDR* __xdrs, char* __addr, unsigned int __len); /* put some bytes to " */ - unsigned int (*x_getpostn) (XDR *__xdrs); + unsigned int (*x_getpostn)(XDR* __xdrs); /* returns bytes off from beginning */ - bool_t (*x_setpostn) (XDR *__xdrs, unsigned int __pos); + bool_t (*x_setpostn)(XDR* __xdrs, unsigned int __pos); /* lets you reposition the stream */ - xdr_int32_t *(*x_inline) (XDR *__xdrs, int __len); + xdr_int32_t* (*x_inline)(XDR* __xdrs, int __len); /* buf quick ptr to buffered data */ - void (*x_destroy) (XDR *__xdrs); + void (*x_destroy)(XDR* __xdrs); /* free privates of this xdr_stream */ - bool_t (*x_getint32) (XDR *__xdrs, xdr_int32_t *__ip); + bool_t (*x_getint32)(XDR* __xdrs, xdr_int32_t* __ip); /* get a int from underlying stream */ - bool_t (*x_putint32) (XDR *__xdrs, xdr_int32_t *__ip); + bool_t (*x_putint32)(XDR* __xdrs, xdr_int32_t* __ip); /* put a int to " */ - bool_t (*x_getuint32) (XDR *__xdrs, xdr_uint32_t *__ip); + bool_t (*x_getuint32)(XDR* __xdrs, xdr_uint32_t* __ip); /* get a unsigned int from underlying stream */ - bool_t (*x_putuint32) (XDR *__xdrs, xdr_uint32_t *__ip); + bool_t (*x_putuint32)(XDR* __xdrs, xdr_uint32_t* __ip); /* put a int to " */ - } - *x_ops; - char *x_public; /* users' data */ - char *x_private; /* pointer to private data */ - char *x_base; /* private used for position info */ - int x_handy; /* extra private word */ + } * x_ops; + char* x_public; /* users' data */ + char* x_private; /* pointer to private data */ + char* x_base; /* private used for position info */ + int x_handy; /* extra private word */ }; /* @@ -184,7 +184,7 @@ struct XDR * allocate dynamic storage of the appropriate size and return it. */ -typedef bool_t (*xdrproc_t) (XDR *, void *, ...); +typedef bool_t (*xdrproc_t)(XDR*, void*, ...); /* * Operations defined on a XDR handle @@ -198,57 +198,50 @@ typedef bool_t (*xdrproc_t) (XDR *, void *, ...); */ -#define xdr_getint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) +#define xdr_getint32(xdrs, int32p) (*(xdrs)->x_ops->x_getint32)(xdrs, int32p) -#define xdr_putint32(xdrs, int32p) \ - (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) +#define xdr_putint32(xdrs, int32p) (*(xdrs)->x_ops->x_putint32)(xdrs, int32p) -#define xdr_getuint32(xdrs, uint32p) \ - (*(xdrs)->x_ops->x_getuint32)(xdrs, uint32p) +#define xdr_getuint32(xdrs, uint32p) (*(xdrs)->x_ops->x_getuint32)(xdrs, uint32p) -#define xdr_putuint32(xdrs, uint32p) \ - (*(xdrs)->x_ops->x_putuint32)(xdrs, uint32p) +#define xdr_putuint32(xdrs, uint32p) (*(xdrs)->x_ops->x_putuint32)(xdrs, uint32p) -#define xdr_getbytes(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) -#define xdr_putbytes(xdrs, addr, len) \ - (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) -#define xdr_getpos(xdrs) \ - (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) (*(xdrs)->x_ops->x_getpostn)(xdrs) -#define xdr_setpos(xdrs, pos) \ - (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) -#define xdr_inline(xdrs, len) \ - (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) (*(xdrs)->x_ops->x_inline)(xdrs, len) -#define xdr_destroy(xdrs) \ - do { \ - if ((xdrs)->x_ops->x_destroy) { \ - (*(xdrs)->x_ops->x_destroy)(xdrs); } \ +#define xdr_destroy(xdrs) \ + do \ + { \ + if ((xdrs)->x_ops->x_destroy) \ + { \ + (*(xdrs)->x_ops->x_destroy)(xdrs); \ + } \ } while (0) -bool_t xdr_void (); -bool_t xdr_int (XDR *__xdrs, int *__ip); -bool_t xdr_u_int (XDR *__xdrs, unsigned int *__ip); -bool_t xdr_short (XDR *__xdrs, short *__ip); -bool_t xdr_u_short (XDR *__xdrs, unsigned short *__ip); -bool_t xdr_bool (XDR *__xdrs, int *__bp); -bool_t xdr_opaque (XDR *__xdrs, char *__cp, unsigned int __cnt); -bool_t xdr_string (XDR *__xdrs, char **__cpp, unsigned int __maxsize); -bool_t xdr_char (XDR *__xdrs, char *__cp); -bool_t xdr_u_char (XDR *__xdrs, unsigned char *__cp); -bool_t xdr_vector (XDR *__xdrs, char *__basep, unsigned int __nelem, - unsigned int __elemsize, xdrproc_t __xdr_elem); -bool_t xdr_float (XDR *__xdrs, float *__fp); -bool_t xdr_double (XDR *__xdrs, double *__dp); -void xdrstdio_create (XDR *__xdrs, FILE *__file, enum xdr_op __xop); +bool_t xdr_void(); +bool_t xdr_int(XDR* __xdrs, int* __ip); +bool_t xdr_u_int(XDR* __xdrs, unsigned int* __ip); +bool_t xdr_short(XDR* __xdrs, short* __ip); +bool_t xdr_u_short(XDR* __xdrs, unsigned short* __ip); +bool_t xdr_bool(XDR* __xdrs, int* __bp); +bool_t xdr_opaque(XDR* __xdrs, char* __cp, unsigned int __cnt); +bool_t xdr_string(XDR* __xdrs, char** __cpp, unsigned int __maxsize); +bool_t xdr_char(XDR* __xdrs, char* __cp); +bool_t xdr_u_char(XDR* __xdrs, unsigned char* __cp); +bool_t xdr_vector(XDR* __xdrs, char* __basep, unsigned int __nelem, unsigned int __elemsize, xdrproc_t __xdr_elem); +bool_t xdr_float(XDR* __xdrs, float* __fp); +bool_t xdr_double(XDR* __xdrs, double* __dp); +void xdrstdio_create(XDR* __xdrs, FILE* __file, enum xdr_op __xop); /* free memory buffers for xdr */ -void xdr_free (xdrproc_t __proc, char *__objp); +void xdr_free(xdrproc_t __proc, char* __objp); #endif /* GMX_FILEIO_GMX_SYSTEM_XDR_H */ diff --git a/src/gromacs/fileio/gmxfio.cpp b/src/gromacs/fileio/gmxfio.cpp index a9fc9c0b05..ab2b183296 100644 --- a/src/gromacs/fileio/gmxfio.cpp +++ b/src/gromacs/fileio/gmxfio.cpp @@ -47,10 +47,10 @@ #include #if HAVE_IO_H -#include +# include #endif #ifdef HAVE_UNISTD_H -#include +# include #endif #include "thread_mpi/threads.h" @@ -67,10 +67,9 @@ /* This is the new improved and thread safe version of gmxfio. */ - /* the list of open files is a linked list, with a dummy element at its head; it is initialized when the first file is opened. */ -static t_fileio *open_files = nullptr; +static t_fileio* open_files = nullptr; /* this mutex locks the open_files structure so that no two threads can @@ -106,12 +105,12 @@ static int gmx_fio_int_flush(t_fileio* fio) /* lock the mutex associated with this fio. This needs to be done for every type of access to the fio's elements. */ -void gmx_fio_lock(t_fileio *fio) +void gmx_fio_lock(t_fileio* fio) { tMPI_Lock_lock(&(fio->mtx)); } /* unlock the mutex associated with this fio. */ -void gmx_fio_unlock(t_fileio *fio) +void gmx_fio_unlock(t_fileio* fio) { tMPI_Lock_unlock(&(fio->mtx)); } @@ -121,7 +120,7 @@ static void gmx_fio_make_dummy() { if (!open_files) { - open_files = new t_fileio {}; + open_files = new t_fileio{}; open_files->fp = nullptr; open_files->fn = nullptr; open_files->next = open_files; @@ -131,11 +130,6 @@ static void gmx_fio_make_dummy() } - - - - - /*********************************************************************** * * FILE LIST OPERATIONS @@ -144,9 +138,9 @@ static void gmx_fio_make_dummy() /* insert a new t_fileio into the list */ -static void gmx_fio_insert(t_fileio *fio) +static void gmx_fio_insert(t_fileio* fio) { - t_fileio *prev; + t_fileio* prev; Lock openFilesLock(open_file_mutex); gmx_fio_make_dummy(); @@ -178,7 +172,7 @@ static void gmx_fio_insert(t_fileio *fio) /* remove a t_fileio into the list. We assume the fio is locked, and we leave it locked. NOTE: We also assume that the open_file_mutex has been locked */ -static void gmx_fio_remove(t_fileio *fio) +static void gmx_fio_remove(t_fileio* fio) { /* lock prev, because we're changing it */ gmx_fio_lock(fio->prev); @@ -199,9 +193,9 @@ static void gmx_fio_remove(t_fileio *fio) /* get the first open file, or NULL if there is none. Returns a locked fio. Assumes open_files_mutex is locked. */ -static t_fileio *gmx_fio_get_first() +static t_fileio* gmx_fio_get_first() { - t_fileio *ret; + t_fileio* ret; gmx_fio_make_dummy(); @@ -228,9 +222,9 @@ static t_fileio *gmx_fio_get_first() /* get the next open file, or NULL if there is none. Unlocks the previous fio and locks the next one. Assumes open_file_mutex is locked. */ -static t_fileio *gmx_fio_get_next(t_fileio *fio) +static t_fileio* gmx_fio_get_next(t_fileio* fio) { - t_fileio *ret; + t_fileio* ret; ret = fio->next; /* check if that was the last one */ @@ -248,22 +242,20 @@ static t_fileio *gmx_fio_get_next(t_fileio *fio) } /* Stop looping through the open_files. Assumes open_file_mutex is locked. */ -static void gmx_fio_stop_getting_next(t_fileio *fio) +static void gmx_fio_stop_getting_next(t_fileio* fio) { gmx_fio_unlock(fio); } - - /***************************************************************** * * EXPORTED SECTION * *****************************************************************/ -t_fileio *gmx_fio_open(const char *fn, const char *mode) +t_fileio* gmx_fio_open(const char* fn, const char* mode) { - t_fileio *fio = nullptr; + t_fileio* fio = nullptr; char newmode[5]; gmx_bool bRead, bReadWrite; @@ -303,7 +295,7 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode) strcat(newmode, "b"); } - fio = new t_fileio {}; + fio = new t_fileio{}; tMPI_Lock_init(&(fio->mtx)); bRead = (newmode[0] == 'r' && newmode[1] != '+'); bReadWrite = (newmode[1] == '+'); @@ -315,8 +307,8 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode) { gmx_incons("gmx_fio_open may not be used to open TNG files"); } - fio->iFTP = fn2ftp(fn); - fio->fn = gmx_strdup(fn); + fio->iFTP = fn2ftp(fn); + fio->fn = gmx_strdup(fn); fio->fp = gmx_ffopen(fn, newmode); /* If this file type is in the list of XDR files, open it like that */ @@ -347,16 +339,16 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode) gmx_fatal(FARGS, "Cannot open file with NULL filename string"); } - fio->bRead = bRead; - fio->bReadWrite = bReadWrite; - fio->bDouble = (sizeof(real) == sizeof(double)); + fio->bRead = bRead; + fio->bReadWrite = bReadWrite; + fio->bDouble = (sizeof(real) == sizeof(double)); /* and now insert this file into the list of open files. */ gmx_fio_insert(fio); return fio; } -static int gmx_fio_close_locked(t_fileio *fio) +static int gmx_fio_close_locked(t_fileio* fio) { int rc = 0; @@ -369,15 +361,14 @@ static int gmx_fio_close_locked(t_fileio *fio) if (fio->fp != nullptr) { rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */ - } return rc; } -int gmx_fio_close(t_fileio *fio) +int gmx_fio_close(t_fileio* fio) { - int rc = 0; + int rc = 0; Lock openFilesLock(open_file_mutex); @@ -394,7 +385,7 @@ int gmx_fio_close(t_fileio *fio) } /* close only fp but keep FIO entry. */ -int gmx_fio_fp_close(t_fileio *fio) +int gmx_fio_fp_close(t_fileio* fio) { int rc = 0; gmx_fio_lock(fio); @@ -408,10 +399,10 @@ int gmx_fio_fp_close(t_fileio *fio) return rc; } -FILE * gmx_fio_fopen(const char *fn, const char *mode) +FILE* gmx_fio_fopen(const char* fn, const char* mode) { - FILE *ret; - t_fileio *fio; + FILE* ret; + t_fileio* fio; fio = gmx_fio_open(fn, mode); gmx_fio_lock(fio); @@ -421,12 +412,12 @@ FILE * gmx_fio_fopen(const char *fn, const char *mode) return ret; } -int gmx_fio_fclose(FILE *fp) +int gmx_fio_fclose(FILE* fp) { - t_fileio *cur; - int rc = -1; + t_fileio* cur; + int rc = -1; - Lock openFilesLock(open_file_mutex); + Lock openFilesLock(open_file_mutex); cur = gmx_fio_get_first(); while (cur) { @@ -451,7 +442,7 @@ struct MD5Checksum //! Checksum md5 digest. std::array checksum; //! The length of the file that contributed to the digest. - gmx_off_t readLength; + gmx_off_t readLength; }; /*! \brief Internal variant of get_file_md5 that operates on a locked @@ -459,8 +450,7 @@ struct MD5Checksum * * \return -1 any time a checksum cannot be computed, otherwise the * length of the data from which the checksum was computed. */ -static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset, - std::array *checksum) +static int gmx_fio_int_get_file_md5(t_fileio* fio, gmx_off_t offset, std::array* checksum) { /*1MB: large size important to catch almost identical files */ constexpr size_t maximumChecksumInputSize = 1048576; @@ -512,15 +502,11 @@ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset, // md5sum check to prevent overwriting files is not vital. if (ferror(fio->fp)) { - fprintf(stderr, "\nTrying to get md5sum: %s: %s\n", fio->fn, - strerror(errno)); + fprintf(stderr, "\nTrying to get md5sum: %s: %s\n", fio->fn, strerror(errno)); } else if (!feof(fio->fp)) { - fprintf( - stderr, - "\nTrying to get md5sum: Unknown reason for short read: %s\n", - fio->fn); + fprintf(stderr, "\nTrying to get md5sum: Unknown reason for short read: %s\n", fio->fn); } gmx_fseek(fio->fp, 0, SEEK_END); @@ -546,8 +532,7 @@ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset, * offset: starting pointer of region to use for md5 * digest: return array of md5 sum */ -int gmx_fio_get_file_md5(t_fileio *fio, gmx_off_t offset, - std::array *checksum) +int gmx_fio_get_file_md5(t_fileio* fio, gmx_off_t offset, std::array* checksum) { int ret; @@ -559,16 +544,13 @@ int gmx_fio_get_file_md5(t_fileio *fio, gmx_off_t offset, } /* The fio_mutex should ALWAYS be locked when this function is called */ -static int gmx_fio_int_get_file_position(t_fileio *fio, gmx_off_t *offset) +static int gmx_fio_int_get_file_position(t_fileio* fio, gmx_off_t* offset) { /* Flush the file, so we are sure it is written */ if (gmx_fio_int_flush(fio)) { char buf[STRLEN]; - sprintf( - buf, - "Cannot write file '%s'; maybe you are out of disk space?", - fio->fn); + sprintf(buf, "Cannot write file '%s'; maybe you are out of disk space?", fio->fn); gmx_file(buf); } @@ -586,7 +568,7 @@ static int gmx_fio_int_get_file_position(t_fileio *fio, gmx_off_t *offset) std::vector gmx_fio_get_output_file_positions() { std::vector outputfiles; - t_fileio *cur; + t_fileio* cur; Lock openFilesLock(open_file_mutex); cur = gmx_fio_get_first(); @@ -604,10 +586,8 @@ std::vector gmx_fio_get_output_file_positions() gmx_fio_int_get_file_position(cur, &outputfiles.back().offset); if (!GMX_FAHCORE) { - outputfiles.back().checksumSize - = gmx_fio_int_get_file_md5(cur, - outputfiles.back().offset, - &outputfiles.back().checksum); + outputfiles.back().checksumSize = gmx_fio_int_get_file_md5( + cur, outputfiles.back().offset, &outputfiles.back().checksum); } } @@ -618,9 +598,9 @@ std::vector gmx_fio_get_output_file_positions() } -char *gmx_fio_getname(t_fileio *fio) +char* gmx_fio_getname(t_fileio* fio) { - char *ret; + char* ret; gmx_fio_lock(fio); ret = fio->fn; gmx_fio_unlock(fio); @@ -669,10 +649,9 @@ int gmx_fio_flush(t_fileio* fio) } - -static int gmx_fio_int_fsync(t_fileio *fio) +static int gmx_fio_int_fsync(t_fileio* fio) { - int rc = 0; + int rc = 0; if (fio->fp) { @@ -682,7 +661,7 @@ static int gmx_fio_int_fsync(t_fileio *fio) } -int gmx_fio_fsync(t_fileio *fio) +int gmx_fio_fsync(t_fileio* fio) { int rc; @@ -694,13 +673,12 @@ int gmx_fio_fsync(t_fileio *fio) } - -t_fileio *gmx_fio_all_output_fsync() +t_fileio* gmx_fio_all_output_fsync() { - t_fileio *ret = nullptr; - t_fileio *cur; + t_fileio* ret = nullptr; + t_fileio* cur; - Lock openFilesLock(open_file_mutex); + Lock openFilesLock(open_file_mutex); cur = gmx_fio_get_first(); while (cur) { @@ -761,9 +739,9 @@ int gmx_fio_seek(t_fileio* fio, gmx_off_t fpos) return rc; } -FILE *gmx_fio_getfp(t_fileio *fio) +FILE* gmx_fio_getfp(t_fileio* fio) { - FILE *ret = nullptr; + FILE* ret = nullptr; gmx_fio_lock(fio); if (fio->fp) @@ -785,7 +763,7 @@ gmx_bool gmx_fio_getread(t_fileio* fio) return ret; } -int xtc_seek_time(t_fileio *fio, real time, int natoms, gmx_bool bSeekForwardOnly) +int xtc_seek_time(t_fileio* fio, real time, int natoms, gmx_bool bSeekForwardOnly) { int ret; diff --git a/src/gromacs/fileio/gmxfio.h b/src/gromacs/fileio/gmxfio.h index fc5df706b0..3472904e1e 100644 --- a/src/gromacs/fileio/gmxfio.h +++ b/src/gromacs/fileio/gmxfio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,18 +61,18 @@ typedef struct t_fileio t_fileio; * Open and Close ********************************************************/ -t_fileio *gmx_fio_open(const char *fn, const char *mode); +t_fileio* gmx_fio_open(const char* fn, const char* mode); /* Open a new file for reading or writing. * The file type will be deduced from the file name. */ -int gmx_fio_close(t_fileio *fp); +int gmx_fio_close(t_fileio* fp); /* Close the file corresponding to fp (if not stdio) * The routine will exit when an invalid fio is handled. * Returns 0 on success. */ -int gmx_fio_fp_close(t_fileio *fp); +int gmx_fio_fp_close(t_fileio* fp); /* Close the file corresponding to fp without closing the FIO entry * Needed e.g. for trxio because the FIO entries are used to store * additional data. @@ -83,55 +83,54 @@ int gmx_fio_fp_close(t_fileio *fp); /* Open a file, return a stream, record the entry in internal FIO object */ -FILE* gmx_fio_fopen(const char *fn, const char *mode); +FILE* gmx_fio_fopen(const char* fn, const char* mode); /* Close a file previously opened with gmx_fio_fopen. * Do not mix these calls with standard fopen/fclose ones! * Returns 0 on success. */ -int gmx_fio_fclose(FILE *fp); - +int gmx_fio_fclose(FILE* fp); /******************************************************** * Change properties of the open file ********************************************************/ -char *gmx_fio_getname(t_fileio *fio); +char* gmx_fio_getname(t_fileio* fio); /* Return the filename corresponding to the fio index */ -int gmx_fio_getftp(t_fileio *fio); +int gmx_fio_getftp(t_fileio* fio); /* Return the filetype corresponding to the fio index. There is as of now no corresponding setftp function because the file was opened as a specific file type and changing that midway is most likely an evil hack. */ -gmx_bool gmx_fio_getread(t_fileio *fio); +gmx_bool gmx_fio_getread(t_fileio* fio); /* Return whether read mode is on in fio */ /*************************************************** * FILE Operations ***************************************************/ -void gmx_fio_rewind(t_fileio *fio); +void gmx_fio_rewind(t_fileio* fio); /* Rewind the file in fio */ -int gmx_fio_flush(t_fileio *fio); +int gmx_fio_flush(t_fileio* fio); /* Flush the fio, returns 0 on success */ -int gmx_fio_fsync(t_fileio *fio); +int gmx_fio_fsync(t_fileio* fio); /* fsync the fio, returns 0 on success. NOTE: don't use fsync function unless you're absolutely sure you need it because it deliberately interferes with the OS's caching mechanisms and can cause dramatically slowed down IO performance. Some OSes (Linux, for example), may implement fsync as a full sync() point. */ -gmx_off_t gmx_fio_ftell(t_fileio *fio); +gmx_off_t gmx_fio_ftell(t_fileio* fio); /* Return file position if possible */ -int gmx_fio_seek(t_fileio *fio, gmx_off_t fpos); +int gmx_fio_seek(t_fileio* fio, gmx_off_t fpos); /* Set file position if possible, quit otherwise */ -FILE *gmx_fio_getfp(t_fileio *fio); +FILE* gmx_fio_getfp(t_fileio* fio); /* Return the file pointer itself */ @@ -142,10 +141,10 @@ FILE *gmx_fio_getfp(t_fileio *fio); * enable large files). */ struct gmx_file_position_t { - char filename[STRLEN] = {0}; - gmx_off_t offset = 0; - std::array checksum = {{0}}; - int checksumSize = 0; + char filename[STRLEN] = { 0 }; + gmx_off_t offset = 0; + std::array checksum = { { 0 } }; + int checksumSize = 0; }; /*! \brief Return data about output files. @@ -154,7 +153,7 @@ struct gmx_file_position_t * we can truncate output files upon restart-with-appending. */ std::vector gmx_fio_get_output_file_positions(); -t_fileio *gmx_fio_all_output_fsync(); +t_fileio* gmx_fio_all_output_fsync(); /* fsync all open output files. This is used for checkpointing, where we need to ensure that all output is actually written out to disk. @@ -168,11 +167,10 @@ t_fileio *gmx_fio_all_output_fsync(); */ -int gmx_fio_get_file_md5(t_fileio *fio, gmx_off_t offset, - std::array *checksum); +int gmx_fio_get_file_md5(t_fileio* fio, gmx_off_t offset, std::array* checksum); -int xtc_seek_time(t_fileio *fio, real time, int natoms, gmx_bool bSeekForwardOnly); +int xtc_seek_time(t_fileio* fio, real time, int natoms, gmx_bool bSeekForwardOnly); #endif diff --git a/src/gromacs/fileio/gmxfio_impl.h b/src/gromacs/fileio/gmxfio_impl.h index 1cc7d40b31..d234cbc6ff 100644 --- a/src/gromacs/fileio/gmxfio_impl.h +++ b/src/gromacs/fileio/gmxfio_impl.h @@ -60,26 +60,26 @@ struct t_fileio { - FILE *fp; /* the file pointer */ - gmx_bool bRead, /* the file is open for reading */ - bDouble, /* write doubles instead of floats */ - bReadWrite; /* the file is open for reading and writing */ - char *fn; /* the file name */ - XDR *xdr; /* the xdr data pointer */ - enum xdr_op xdrmode; /* the xdr mode */ - int iFTP; /* the file type identifier */ + FILE* fp; /* the file pointer */ + gmx_bool bRead, /* the file is open for reading */ + bDouble, /* write doubles instead of floats */ + bReadWrite; /* the file is open for reading and writing */ + char* fn; /* the file name */ + XDR* xdr; /* the xdr data pointer */ + enum xdr_op xdrmode; /* the xdr mode */ + int iFTP; /* the file type identifier */ - t_fileio *next, *prev; /* next and previous file pointers in the - linked list */ - tMPI_Lock_t mtx; /* content locking mutex. This is a fast lock - for performance reasons: in some cases every - single byte that gets read/written requires - a lock */ + t_fileio *next, *prev; /* next and previous file pointers in the + linked list */ + tMPI_Lock_t mtx; /* content locking mutex. This is a fast lock + for performance reasons: in some cases every + single byte that gets read/written requires + a lock */ }; /** lock the mutex associated with a fio */ -void gmx_fio_lock(t_fileio *fio); +void gmx_fio_lock(t_fileio* fio); /** unlock the mutex associated with a fio */ -void gmx_fio_unlock(t_fileio *fio); +void gmx_fio_unlock(t_fileio* fio); #endif diff --git a/src/gromacs/fileio/gmxfio_xdr.cpp b/src/gromacs/fileio/gmxfio_xdr.cpp index 55606a9f31..254dc37fb8 100644 --- a/src/gromacs/fileio/gmxfio_xdr.cpp +++ b/src/gromacs/fileio/gmxfio_xdr.cpp @@ -50,27 +50,38 @@ #include "gmxfio_impl.h" /* Enumerated for data types in files */ -enum { - eioREAL, eioFLOAT, eioDOUBLE, eioINT, eioINT32, eioINT64, - eioUCHAR, eioCHAR, eioNCHAR, eioNUCHAR, eioUSHORT, - eioRVEC, eioNRVEC, eioIVEC, eioSTRING, eioNR +enum +{ + eioREAL, + eioFLOAT, + eioDOUBLE, + eioINT, + eioINT32, + eioINT64, + eioUCHAR, + eioCHAR, + eioNCHAR, + eioNUCHAR, + eioUSHORT, + eioRVEC, + eioNRVEC, + eioIVEC, + eioSTRING, + eioNR }; -static const char *eioNames[eioNR] = -{ - "REAL", "FLOAT", "DOUBLE", "INT", "INT32", "INT64", - "UCHAR", "CHAR", "NCHAR", "NUCHAR", "USHORT", - "RVEC", "NRVEC", "IVEC", "STRING" -}; +static const char* eioNames[eioNR] = { "REAL", "FLOAT", "DOUBLE", "INT", "INT32", + "INT64", "UCHAR", "CHAR", "NCHAR", "NUCHAR", + "USHORT", "RVEC", "NRVEC", "IVEC", "STRING" }; -void gmx_fio_setprecision(t_fileio *fio, gmx_bool bDouble) +void gmx_fio_setprecision(t_fileio* fio, gmx_bool bDouble) { gmx_fio_lock(fio); fio->bDouble = bDouble; gmx_fio_unlock(fio); } -bool gmx_fio_is_double(t_fileio *fio) +bool gmx_fio_is_double(t_fileio* fio) { bool isDouble = false; gmx_fio_lock(fio); @@ -79,58 +90,54 @@ bool gmx_fio_is_double(t_fileio *fio) return isDouble; } -XDR *gmx_fio_getxdr(t_fileio *fio) +XDR* gmx_fio_getxdr(t_fileio* fio) { - XDR *ret = nullptr; + XDR* ret = nullptr; gmx_fio_lock(fio); - GMX_RELEASE_ASSERT( fio->xdr != nullptr, "Implementation error: NULL XDR pointers"); + GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers"); ret = fio->xdr; gmx_fio_unlock(fio); return ret; } /* check the number of items given against the type */ -static void gmx_fio_check_nitem(int eio, int nitem, const char *file, int line) +static void gmx_fio_check_nitem(int eio, int nitem, const char* file, int line) { if ((nitem != 1) && !((eio == eioNRVEC) || (eio == eioNUCHAR) || (eio == eioNCHAR))) { gmx_fatal(FARGS, "nitem (%d) may differ from 1 only for %s, %s or %s, not for %s" - "(%s, %d)", nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC], - eioNames[eioNCHAR], eioNames[eio], file, line); + "(%s, %d)", + nitem, eioNames[eioNUCHAR], eioNames[eioNRVEC], eioNames[eioNCHAR], eioNames[eio], + file, line); } } /* output a data type error. */ -[[ noreturn ]] -static void gmx_fio_fe(t_fileio *fio, int eio, const char *desc, - const char *srcfile, int line) +[[noreturn]] static void gmx_fio_fe(t_fileio* fio, int eio, const char* desc, const char* srcfile, int line) { - gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d", - fio->bRead ? "read" : "write", desc, eio, - ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown", - srcfile, line); + gmx_fatal(FARGS, "Trying to %s %s type %d (%s), src %s, line %d", fio->bRead ? "read" : "write", + desc, eio, ((eio >= 0) && (eio < eioNR)) ? eioNames[eio] : "unknown", srcfile, line); } /* This is the part that reads xdr files. */ -static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, - const char *desc, const char *srcfile, int line) -{ - unsigned char ucdum, *ucptr; - char cdum, *cptr; - bool_t res = 0; - float fvec[DIM]; - double dvec[DIM]; - int j, m, *iptr, idum; - int32_t s32dum; - int64_t s64dum; - real *ptr; - unsigned short us; - double d = 0; - float f = 0; - - GMX_RELEASE_ASSERT( fio->xdr != nullptr, "Implementation error: NULL XDR pointers"); +static gmx_bool do_xdr(t_fileio* fio, void* item, int nitem, int eio, const char* desc, const char* srcfile, int line) +{ + unsigned char ucdum, *ucptr; + char cdum, *cptr; + bool_t res = 0; + float fvec[DIM]; + double dvec[DIM]; + int j, m, *iptr, idum; + int32_t s32dum; + int64_t s64dum; + real* ptr; + unsigned short us; + double d = 0; + float f = 0; + + GMX_RELEASE_ASSERT(fio->xdr != nullptr, "Implementation error: NULL XDR pointers"); gmx_fio_check_nitem(eio, nitem, srcfile, line); switch (eio) { @@ -139,125 +146,124 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, { if (item && !fio->bRead) { - d = *(static_cast(item)); + d = *(static_cast(item)); } res = xdr_double(fio->xdr, &d); if (item) { - *(static_cast(item)) = d; + *(static_cast(item)) = d; } } else { if (item && !fio->bRead) { - f = *(static_cast(item)); + f = *(static_cast(item)); } res = xdr_float(fio->xdr, &f); if (item) { - *(static_cast(item)) = f; + *(static_cast(item)) = f; } } break; case eioFLOAT: if (item && !fio->bRead) { - f = *(static_cast(item)); + f = *(static_cast(item)); } res = xdr_float(fio->xdr, &f); if (item) { - *(static_cast(item)) = f; + *(static_cast(item)) = f; } break; case eioDOUBLE: if (item && !fio->bRead) { - d = *(static_cast(item)); + d = *(static_cast(item)); } res = xdr_double(fio->xdr, &d); if (item) { - *(static_cast(item)) = d; + *(static_cast(item)) = d; } break; case eioINT: if (item && !fio->bRead) { - idum = *static_cast(item); + idum = *static_cast(item); } res = xdr_int(fio->xdr, &idum); if (item) { - *static_cast(item) = idum; + *static_cast(item) = idum; } break; case eioINT32: if (item && !fio->bRead) { - s32dum = *static_cast(item); + s32dum = *static_cast(item); } res = xdr_int32(fio->xdr, &s32dum); if (item) { - *static_cast(item) = s32dum; + *static_cast(item) = s32dum; } break; case eioINT64: if (item && !fio->bRead) { - s64dum = *static_cast(item); + s64dum = *static_cast(item); } res = xdr_int64(fio->xdr, &s64dum); if (item) { - *static_cast(item) = s64dum; + *static_cast(item) = s64dum; } break; case eioUCHAR: if (item && !fio->bRead) { - ucdum = *static_cast(item); + ucdum = *static_cast(item); } res = xdr_u_char(fio->xdr, &ucdum); if (item) { - *static_cast(item) = ucdum; + *static_cast(item) = ucdum; } break; case eioCHAR: if (item && !fio->bRead) { - cdum = *static_cast(item); + cdum = *static_cast(item); } res = xdr_char(fio->xdr, &cdum); if (item) { - *static_cast(item) = cdum; + *static_cast(item) = cdum; } break; case eioNCHAR: - cptr = static_cast(item); - res = xdr_vector(fio->xdr, cptr, nitem, - static_cast(sizeof(char)), - reinterpret_cast(xdr_char)); + cptr = static_cast(item); + res = xdr_vector(fio->xdr, cptr, nitem, static_cast(sizeof(char)), + reinterpret_cast(xdr_char)); break; case eioNUCHAR: - ucptr = static_cast(item); - res = xdr_vector(fio->xdr, reinterpret_cast(ucptr), nitem, - static_cast(sizeof(unsigned char)), - reinterpret_cast(xdr_u_char)); + ucptr = static_cast(item); + res = xdr_vector(fio->xdr, reinterpret_cast(ucptr), nitem, + static_cast(sizeof(unsigned char)), + reinterpret_cast(xdr_u_char)); break; case eioUSHORT: if (item && !fio->bRead) { - us = *static_cast(item); + us = *static_cast(item); } res = xdr_u_short(fio->xdr, &us); if (item) { - *static_cast(item) = us; + *static_cast(item) = us; } break; case eioRVEC: @@ -267,17 +273,17 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, { for (m = 0; (m < DIM); m++) { - dvec[m] = (static_cast(item))[m]; + dvec[m] = (static_cast(item))[m]; } } - res = xdr_vector(fio->xdr, reinterpret_cast(dvec), DIM, + res = xdr_vector(fio->xdr, reinterpret_cast(dvec), DIM, static_cast(sizeof(double)), reinterpret_cast(xdr_double)); if (item) { for (m = 0; (m < DIM); m++) { - (static_cast(item))[m] = dvec[m]; + (static_cast(item))[m] = dvec[m]; } } } @@ -287,17 +293,17 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, { for (m = 0; (m < DIM); m++) { - fvec[m] = (static_cast(item))[m]; + fvec[m] = (static_cast(item))[m]; } } - res = xdr_vector(fio->xdr, reinterpret_cast(fvec), DIM, + res = xdr_vector(fio->xdr, reinterpret_cast(fvec), DIM, static_cast(sizeof(float)), reinterpret_cast(xdr_float)); if (item) { for (m = 0; (m < DIM); m++) { - (static_cast(item))[m] = fvec[m]; + (static_cast(item))[m] = fvec[m]; } } } @@ -309,13 +315,13 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, { if (item) { - ptr = (static_cast(item))[j]; + ptr = (static_cast(item))[j]; } res = static_cast(do_xdr(fio, ptr, 1, eioRVEC, desc, srcfile, line)); } break; case eioIVEC: - iptr = static_cast(item); + iptr = static_cast(item); res = 1; for (m = 0; (m < DIM) && res; m++) { @@ -332,14 +338,14 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, break; case eioSTRING: { - char *cptr; + char* cptr; int slen; if (item) { if (!fio->bRead) { - slen = strlen(static_cast(item)) + 1; + slen = strlen(static_cast(item)) + 1; } else { @@ -353,8 +359,10 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, if (xdr_int(fio->xdr, &slen) <= 0) { - gmx_fatal(FARGS, "wrong string length %d for string %s" - " (source %s, line %d)", slen, desc, srcfile, line); + gmx_fatal(FARGS, + "wrong string length %d for string %s" + " (source %s, line %d)", + slen, desc, srcfile, line); } if (!item && fio->bRead) { @@ -362,7 +370,7 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, } else { - cptr = static_cast(item); + cptr = static_cast(item); } if (cptr) { @@ -378,8 +386,7 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, } break; } - default: - gmx_fio_fe(fio, eio, desc, srcfile, line); + default: gmx_fio_fe(fio, eio, desc, srcfile, line); } return (res != 0); @@ -391,30 +398,26 @@ static gmx_bool do_xdr(t_fileio *fio, void *item, int nitem, int eio, * *******************************************************************/ -gmx_bool gmx_fio_writee_string(t_fileio *fio, const char *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_writee_string(t_fileio* fio, const char* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; - void *it = const_cast(item); /* ugh.. */ + void* it = const_cast(item); /* ugh.. */ gmx_fio_lock(fio); ret = do_xdr(fio, it, 1, eioSTRING, desc, srcfile, line); gmx_fio_unlock(fio); return ret; } -gmx_bool gmx_fio_doe_real(t_fileio *fio, real *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_real(t_fileio* fio, real* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); ret = do_xdr(fio, item, 1, eioREAL, desc, srcfile, line); gmx_fio_unlock(fio); return ret; - } -gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_float(t_fileio* fio, float* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -423,8 +426,7 @@ gmx_bool gmx_fio_doe_float(t_fileio *fio, float *item, return ret; } -gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_double(t_fileio* fio, double* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -434,8 +436,7 @@ gmx_bool gmx_fio_doe_double(t_fileio *fio, double *item, } -gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_gmx_bool(t_fileio* fio, gmx_bool* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; @@ -455,8 +456,7 @@ gmx_bool gmx_fio_doe_gmx_bool(t_fileio *fio, gmx_bool *item, return ret; } -gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_int(t_fileio* fio, int* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -465,8 +465,7 @@ gmx_bool gmx_fio_doe_int(t_fileio *fio, int *item, return ret; } -gmx_bool gmx_fio_doe_int32(t_fileio *fio, int32_t *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_int32(t_fileio* fio, int32_t* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -475,8 +474,7 @@ gmx_bool gmx_fio_doe_int32(t_fileio *fio, int32_t *item, return ret; } -gmx_bool gmx_fio_doe_int64(t_fileio *fio, int64_t *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_int64(t_fileio* fio, int64_t* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -485,8 +483,7 @@ gmx_bool gmx_fio_doe_int64(t_fileio *fio, int64_t *item, return ret; } -gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_uchar(t_fileio* fio, unsigned char* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -495,8 +492,7 @@ gmx_bool gmx_fio_doe_uchar(t_fileio *fio, unsigned char *item, return ret; } -gmx_bool gmx_fio_doe_char(t_fileio *fio, char *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_char(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -505,8 +501,7 @@ gmx_bool gmx_fio_doe_char(t_fileio *fio, char *item, return ret; } -gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_ushort(t_fileio* fio, unsigned short* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -515,8 +510,7 @@ gmx_bool gmx_fio_doe_ushort(t_fileio *fio, unsigned short *item, return ret; } -gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_rvec(t_fileio* fio, rvec* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -525,8 +519,7 @@ gmx_bool gmx_fio_doe_rvec(t_fileio *fio, rvec *item, return ret; } -gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_ivec(t_fileio* fio, ivec* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -535,8 +528,7 @@ gmx_bool gmx_fio_doe_ivec(t_fileio *fio, ivec *item, return ret; } -gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_doe_string(t_fileio* fio, char* item, const char* desc, const char* srcfile, int line) { gmx_bool ret; gmx_fio_lock(fio); @@ -548,59 +540,49 @@ gmx_bool gmx_fio_doe_string(t_fileio *fio, char *item, /* Array reading & writing */ -gmx_bool gmx_fio_ndoe_real(t_fileio *fio, real *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_real(t_fileio* fio, real* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioREAL, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_float(t_fileio *fio, float *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_float(t_fileio* fio, float* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioFLOAT, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_double(t_fileio *fio, double *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_double(t_fileio* fio, double* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioDOUBLE, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio* fio, gmx_bool* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; @@ -624,53 +606,44 @@ gmx_bool gmx_fio_ndoe_gmx_bool(t_fileio *fio, gmx_bool *item, int n, return ret; } -gmx_bool gmx_fio_ndoe_int(t_fileio *fio, int *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_int(t_fileio* fio, int* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioINT, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_int64(t_fileio *fio, int64_t *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_int64(t_fileio* fio, int64_t* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioINT64, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_uchar(t_fileio *fio, unsigned char *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_uchar(t_fileio* fio, unsigned char* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; gmx_fio_lock(fio); - ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc, - srcfile, line); + ret = ret && do_xdr(fio, item, n, eioNUCHAR, desc, srcfile, line); gmx_fio_unlock(fio); return ret; } -gmx_bool gmx_fio_ndoe_char(t_fileio *fio, char *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_char(t_fileio* fio, char* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; gmx_fio_lock(fio); @@ -680,25 +653,21 @@ gmx_bool gmx_fio_ndoe_char(t_fileio *fio, char *item, int n, } -gmx_bool gmx_fio_ndoe_ushort(t_fileio *fio, unsigned short *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_ushort(t_fileio* fio, unsigned short* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioUSHORT, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_rvec(t_fileio* fio, rvec* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; gmx_fio_lock(fio); @@ -708,34 +677,28 @@ gmx_bool gmx_fio_ndoe_rvec(t_fileio *fio, rvec *item, int n, } - -gmx_bool gmx_fio_ndoe_ivec(t_fileio *fio, ivec *item, int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_ivec(t_fileio* fio, ivec* item, int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioIVEC, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; } - -gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n, - const char *desc, const char *srcfile, int line) +gmx_bool gmx_fio_ndoe_string(t_fileio* fio, char* item[], int n, const char* desc, const char* srcfile, int line) { gmx_bool ret = TRUE; int i; gmx_fio_lock(fio); for (i = 0; i < n; i++) { - ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc, - srcfile, line); + ret = ret && do_xdr(fio, &(item[i]), 1, eioSTRING, desc, srcfile, line); } gmx_fio_unlock(fio); return ret; @@ -744,8 +707,7 @@ gmx_bool gmx_fio_ndoe_string(t_fileio *fio, char *item[], int n, namespace gmx { -FileIOXdrSerializer::FileIOXdrSerializer(t_fileio *fio) - : fio_(fio) +FileIOXdrSerializer::FileIOXdrSerializer(t_fileio* fio) : fio_(fio) { GMX_RELEASE_ASSERT(fio, "Need valid file io handle"); } @@ -755,82 +717,82 @@ bool FileIOXdrSerializer::reading() const return fio_->bRead; } -void FileIOXdrSerializer::doBool(bool *value) +void FileIOXdrSerializer::doBool(bool* value) { gmx_fio_do_gmx_bool(fio_, *value); } -void FileIOXdrSerializer::doUChar(unsigned char *value) +void FileIOXdrSerializer::doUChar(unsigned char* value) { gmx_fio_do_uchar(fio_, *value); } -void FileIOXdrSerializer::doChar(char *value) +void FileIOXdrSerializer::doChar(char* value) { gmx_fio_do_char(fio_, *value); } -void FileIOXdrSerializer::doUShort(unsigned short *value) +void FileIOXdrSerializer::doUShort(unsigned short* value) { gmx_fio_do_ushort(fio_, *value); } -void FileIOXdrSerializer::doInt(int *value) +void FileIOXdrSerializer::doInt(int* value) { gmx_fio_do_int(fio_, *value); } -void FileIOXdrSerializer::doInt32(int32_t *value) +void FileIOXdrSerializer::doInt32(int32_t* value) { gmx_fio_do_int32(fio_, *value); } -void FileIOXdrSerializer::doInt64(int64_t *value) +void FileIOXdrSerializer::doInt64(int64_t* value) { gmx_fio_do_int64(fio_, *value); } -void FileIOXdrSerializer::doFloat(float *value) +void FileIOXdrSerializer::doFloat(float* value) { gmx_fio_do_float(fio_, *value); } -void FileIOXdrSerializer::doDouble(double *value) +void FileIOXdrSerializer::doDouble(double* value) { gmx_fio_do_double(fio_, *value); } -void FileIOXdrSerializer::doReal(real *value) +void FileIOXdrSerializer::doReal(real* value) { gmx_fio_do_real(fio_, *value); } -void FileIOXdrSerializer::doIvec(ivec *value) +void FileIOXdrSerializer::doIvec(ivec* value) { gmx_fio_do_ivec(fio_, *value); } -void FileIOXdrSerializer::doRvec(rvec *value) +void FileIOXdrSerializer::doRvec(rvec* value) { gmx_fio_do_rvec(fio_, *value); } -void FileIOXdrSerializer::doCharArray(char *values, int elements) +void FileIOXdrSerializer::doCharArray(char* values, int elements) { gmx_fio_ndo_char(fio_, values, elements); } -void FileIOXdrSerializer::doUCharArray(unsigned char *values, int elements) +void FileIOXdrSerializer::doUCharArray(unsigned char* values, int elements) { gmx_fio_ndo_uchar(fio_, values, elements); } -void FileIOXdrSerializer::doRvecArray(rvec *values, int elements) +void FileIOXdrSerializer::doRvecArray(rvec* values, int elements) { gmx_fio_ndo_rvec(fio_, values, elements); } -void FileIOXdrSerializer::doString(std::string *value) +void FileIOXdrSerializer::doString(std::string* value) { // TODO: Use an arbitrary length buffer (but that is not supported in // gmx_fio, either). @@ -838,7 +800,7 @@ void FileIOXdrSerializer::doString(std::string *value) if (!fio_->bRead) { std::strncpy(buf, value->c_str(), STRLEN); - buf[STRLEN-1] = 0; + buf[STRLEN - 1] = 0; } gmx_fio_do_string(fio_, buf); if (fio_->bRead) diff --git a/src/gromacs/fileio/gmxfio_xdr.h b/src/gromacs/fileio/gmxfio_xdr.h index 1007f6d12a..b70011e686 100644 --- a/src/gromacs/fileio/gmxfio_xdr.h +++ b/src/gromacs/fileio/gmxfio_xdr.h @@ -47,108 +47,107 @@ struct t_fileio; -void gmx_fio_setprecision(struct t_fileio *fio, gmx_bool bDouble); +void gmx_fio_setprecision(struct t_fileio* fio, gmx_bool bDouble); /* Select the floating point precision for reading and writing files */ -bool gmx_fio_is_double(struct t_fileio *fio); +bool gmx_fio_is_double(struct t_fileio* fio); -XDR *gmx_fio_getxdr(struct t_fileio *fio); +XDR* gmx_fio_getxdr(struct t_fileio* fio); /* Return the file pointer itself */ -gmx_bool gmx_fio_writee_string(struct t_fileio *fio, const char *item, - const char *desc, const char *srcfile, int line); +gmx_bool gmx_fio_writee_string(struct t_fileio* fio, const char* item, const char* desc, const char* srcfile, int line); /* reading or writing, depending on the file's opening mode string */ -gmx_bool gmx_fio_doe_real(struct t_fileio *fio, real *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_float(struct t_fileio *fio, float *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_double(struct t_fileio *fio, double *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_gmx_bool(struct t_fileio *fio, gmx_bool *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_int(struct t_fileio *fio, int *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_int32(struct t_fileio *fio, int32_t *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_int64(struct t_fileio *fio, int64_t *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_uchar(struct t_fileio *fio, unsigned char *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_char(struct t_fileio *fio, char *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_ushort(struct t_fileio *fio, unsigned short *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_rvec(struct t_fileio *fio, rvec *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_ivec(struct t_fileio *fio, ivec *item, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_doe_string(struct t_fileio *fio, char *item, - const char *desc, const char *srcfile, int line); +gmx_bool gmx_fio_doe_real(struct t_fileio* fio, real* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_float(struct t_fileio* fio, float* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_double(struct t_fileio* fio, double* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_gmx_bool(struct t_fileio* fio, gmx_bool* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_int(struct t_fileio* fio, int* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_int32(struct t_fileio* fio, int32_t* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_int64(struct t_fileio* fio, int64_t* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_uchar(struct t_fileio* fio, unsigned char* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_char(struct t_fileio* fio, char* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_ushort(struct t_fileio* fio, + unsigned short* item, + const char* desc, + const char* srcfile, + int line); +gmx_bool gmx_fio_doe_rvec(struct t_fileio* fio, rvec* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_ivec(struct t_fileio* fio, ivec* item, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_doe_string(struct t_fileio* fio, char* item, const char* desc, const char* srcfile, int line); /* array reading & writing */ -gmx_bool gmx_fio_ndoe_real(struct t_fileio *fio, real *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_float(struct t_fileio *fio, float *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_double(struct t_fileio *fio, double *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_gmx_bool(struct t_fileio *fio, gmx_bool *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_int(struct t_fileio *fio, int *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_int32(struct t_fileio *fio, int32_t *item, int n, - const char *desc, const char *srcfile, - int line); -gmx_bool gmx_fio_ndoe_int64(struct t_fileio *fio, int64_t *item, int n, - const char *desc, const char *srcfile, - int line); -gmx_bool gmx_fio_ndoe_uchar(struct t_fileio *fio, unsigned char *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_char(struct t_fileio *fio, char *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_ushort(struct t_fileio *fio, unsigned short *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_rvec(struct t_fileio *fio, rvec *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_ivec(struct t_fileio *fio, ivec *item, int n, - const char *desc, const char *srcfile, int line); -gmx_bool gmx_fio_ndoe_string(struct t_fileio *fio, char *item[], int n, - const char *desc, const char *srcfile, int line); - +gmx_bool gmx_fio_ndoe_real(struct t_fileio* fio, real* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_float(struct t_fileio* fio, float* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_double(struct t_fileio* fio, double* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_gmx_bool(struct t_fileio* fio, + gmx_bool* item, + int n, + const char* desc, + const char* srcfile, + int line); +gmx_bool gmx_fio_ndoe_int(struct t_fileio* fio, int* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_int32(struct t_fileio* fio, int32_t* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_int64(struct t_fileio* fio, int64_t* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_uchar(struct t_fileio* fio, + unsigned char* item, + int n, + const char* desc, + const char* srcfile, + int line); +gmx_bool gmx_fio_ndoe_char(struct t_fileio* fio, char* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_ushort(struct t_fileio* fio, + unsigned short* item, + int n, + const char* desc, + const char* srcfile, + int line); +gmx_bool gmx_fio_ndoe_rvec(struct t_fileio* fio, rvec* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_ivec(struct t_fileio* fio, ivec* item, int n, const char* desc, const char* srcfile, int line); +gmx_bool gmx_fio_ndoe_string(struct t_fileio* fio, char* item[], int n, const char* desc, const char* srcfile, int line); /* convenience macros */ -#define gmx_fio_write_string(fio, item) gmx_fio_writee_string(fio, item, (#item), __FILE__, __LINE__) - -#define gmx_fio_do_real(fio, item) gmx_fio_doe_real(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_float(fio, item) gmx_fio_doe_float(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_double(fio, item) gmx_fio_doe_double(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_gmx_bool(fio, item) gmx_fio_doe_gmx_bool(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_int(fio, item) gmx_fio_doe_int(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_int32(fio, item) gmx_fio_doe_int32(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_int64(fio, item) gmx_fio_doe_int64(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_uchar(fio, item) gmx_fio_doe_uchar(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_char(fio, item) gmx_fio_doe_char(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_ushort(fio, item) gmx_fio_doe_ushort(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_rvec(fio, item) gmx_fio_doe_rvec(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_ivec(fio, item) gmx_fio_doe_ivec(fio, &(item), (#item), __FILE__, __LINE__) -#define gmx_fio_do_string(fio, item) gmx_fio_doe_string(fio, item, (#item), __FILE__, __LINE__) - - -#define gmx_fio_ndo_real(fio, item, n) gmx_fio_ndoe_real(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_float(fio, item, n) gmx_fio_ndoe_float(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_double(fio, item, n) gmx_fio_ndoe_double(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_gmx_bool(fio, item, n) gmx_fio_ndoe_gmx_bool(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_int(fio, item, n) gmx_fio_ndoe_int(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_int32(fio, item, n) gmx_fio_ndoe_int32(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_int64(fio, item, n) gmx_fio_ndoe_int64(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_uchar(fio, item, n) gmx_fio_ndoe_uchar(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_char(fio, item, n) gmx_fio_ndoe_char(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_ushort(fio, item, n) gmx_fio_ndoe_ushort(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_rvec(fio, item, n) gmx_fio_ndoe_rvec(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_ivec(fio, item, n) gmx_fio_ndoe_ivec(fio, item, n, (#item), __FILE__, __LINE__) -#define gmx_fio_ndo_string(fio, item, n) gmx_fio_ndoe_string(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_write_string(fio, item) \ + gmx_fio_writee_string(fio, item, (#item), __FILE__, __LINE__) + +#define gmx_fio_do_real(fio, item) gmx_fio_doe_real(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_float(fio, item) gmx_fio_doe_float(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_double(fio, item) gmx_fio_doe_double(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_gmx_bool(fio, item) \ + gmx_fio_doe_gmx_bool(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_int(fio, item) gmx_fio_doe_int(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_int32(fio, item) gmx_fio_doe_int32(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_int64(fio, item) gmx_fio_doe_int64(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_uchar(fio, item) gmx_fio_doe_uchar(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_char(fio, item) gmx_fio_doe_char(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_ushort(fio, item) gmx_fio_doe_ushort(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_rvec(fio, item) gmx_fio_doe_rvec(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_ivec(fio, item) gmx_fio_doe_ivec(fio, &(item), (#item), __FILE__, __LINE__) +#define gmx_fio_do_string(fio, item) gmx_fio_doe_string(fio, item, (#item), __FILE__, __LINE__) + + +#define gmx_fio_ndo_real(fio, item, n) gmx_fio_ndoe_real(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_float(fio, item, n) \ + gmx_fio_ndoe_float(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_double(fio, item, n) \ + gmx_fio_ndoe_double(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_gmx_bool(fio, item, n) \ + gmx_fio_ndoe_gmx_bool(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_int(fio, item, n) gmx_fio_ndoe_int(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_int32(fio, item, n) \ + gmx_fio_ndoe_int32(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_int64(fio, item, n) \ + gmx_fio_ndoe_int64(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_uchar(fio, item, n) \ + gmx_fio_ndoe_uchar(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_char(fio, item, n) gmx_fio_ndoe_char(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_ushort(fio, item, n) \ + gmx_fio_ndoe_ushort(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_rvec(fio, item, n) gmx_fio_ndoe_rvec(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_ivec(fio, item, n) gmx_fio_ndoe_ivec(fio, item, n, (#item), __FILE__, __LINE__) +#define gmx_fio_ndo_string(fio, item, n) \ + gmx_fio_ndoe_string(fio, item, n, (#item), __FILE__, __LINE__) namespace gmx { @@ -157,48 +156,48 @@ namespace gmx */ class FileIOXdrSerializer : public ISerializer { - public: - //! Only create with valid file I/O handle. - explicit FileIOXdrSerializer(t_fileio *fio); - - //! If file is open in reading mode. - bool reading() const override; - //! Handle bool I/O. - void doBool(bool *value) override; - //! Handle unsigned char I/O. - void doUChar(unsigned char *value) override; - //! Handle char I/O. - void doChar(char *value) override; - //! Handle unsigned short I/O. - void doUShort(unsigned short *value) override; - //! Handle default integer I/O. - void doInt(int *value) override; - //! Handle int32 I/O. - void doInt32(int32_t *value) override; - //! Handle int64 I/O. - void doInt64(int64_t *value) override; - //! Handle single precision float I/O. - void doFloat(float *value) override; - //! Handle double precision float I/O. - void doDouble(double *value) override; - //! Handle GROMACS floating point number I/O. - void doReal(real *value) override; - //! Handle I/O of integer vector of size DIM. - void doIvec(ivec *value) override; - //! Handle I/O of GROMACS real vector of size DIM. - void doRvec(rvec *value) override; - //! Handle I/O if string. - void doString(std::string *value) override; - //! Special case for handling I/O of a vector of characters. - void doCharArray(char *values, int elements) override; - //! Special case for handling I/O of a vector of unsigned characters. - void doUCharArray(unsigned char *values, int elements) override; - //! Special case for handling I/O of a vector of rvecs. - void doRvecArray(rvec *values, int elements) override; - - private: - //! File I/O handle. - t_fileio *fio_; +public: + //! Only create with valid file I/O handle. + explicit FileIOXdrSerializer(t_fileio* fio); + + //! If file is open in reading mode. + bool reading() const override; + //! Handle bool I/O. + void doBool(bool* value) override; + //! Handle unsigned char I/O. + void doUChar(unsigned char* value) override; + //! Handle char I/O. + void doChar(char* value) override; + //! Handle unsigned short I/O. + void doUShort(unsigned short* value) override; + //! Handle default integer I/O. + void doInt(int* value) override; + //! Handle int32 I/O. + void doInt32(int32_t* value) override; + //! Handle int64 I/O. + void doInt64(int64_t* value) override; + //! Handle single precision float I/O. + void doFloat(float* value) override; + //! Handle double precision float I/O. + void doDouble(double* value) override; + //! Handle GROMACS floating point number I/O. + void doReal(real* value) override; + //! Handle I/O of integer vector of size DIM. + void doIvec(ivec* value) override; + //! Handle I/O of GROMACS real vector of size DIM. + void doRvec(rvec* value) override; + //! Handle I/O if string. + void doString(std::string* value) override; + //! Special case for handling I/O of a vector of characters. + void doCharArray(char* values, int elements) override; + //! Special case for handling I/O of a vector of unsigned characters. + void doUCharArray(unsigned char* values, int elements) override; + //! Special case for handling I/O of a vector of rvecs. + void doRvecArray(rvec* values, int elements) override; + +private: + //! File I/O handle. + t_fileio* fio_; }; } // namespace gmx diff --git a/src/gromacs/fileio/groio.cpp b/src/gromacs/fileio/groio.cpp index cb6736efd3..1ad96c29ba 100644 --- a/src/gromacs/fileio/groio.cpp +++ b/src/gromacs/fileio/groio.cpp @@ -56,9 +56,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void get_coordnum_fp(FILE *in, char *title, int *natoms) +static void get_coordnum_fp(FILE* in, char* title, int* natoms) { - char line[STRLEN+1]; + char line[STRLEN + 1]; fgets2(title, STRLEN, in); fgets2(line, STRLEN, in); @@ -68,9 +68,9 @@ static void get_coordnum_fp(FILE *in, char *title, int *natoms) } } -void get_coordnum(const char *infile, int *natoms) +void get_coordnum(const char* infile, int* natoms) { - FILE *in; + FILE* in; char title[STRLEN]; in = gmx_fio_fopen(infile, "r"); @@ -83,19 +83,25 @@ void get_coordnum(const char *infile, int *natoms) * We have removed writing of variable precision to avoid compatibility * issues with other software packages. */ -static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, - t_symtab *symtab, t_atoms *atoms, int *ndec, - rvec x[], rvec *v, matrix box) +static gmx_bool get_w_conf(FILE* in, + const char* infile, + char* title, + t_symtab* symtab, + t_atoms* atoms, + int* ndec, + rvec x[], + rvec* v, + matrix box) { - char name[6]; - char resname[6], oldresname[6]; - char line[STRLEN+1], *ptr; - char buf[256]; - double x1, y1, z1, x2, y2, z2; - rvec xmin, xmax; - int natoms, i, m, resnr, newres, oldres, ddist, c; - gmx_bool bFirst, bVel, oldResFirst; - char *p1, *p2, *p3; + char name[6]; + char resname[6], oldresname[6]; + char line[STRLEN + 1], *ptr; + char buf[256]; + double x1, y1, z1, x2, y2, z2; + rvec xmin, xmax; + int natoms, i, m, resnr, newres, oldres, ddist, c; + gmx_bool bFirst, bVel, oldResFirst; + char * p1, *p2, *p3; oldres = -1; newres = -1; @@ -107,13 +113,14 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, if (natoms > atoms->nr) { - gmx_fatal(FARGS, "gro file contains more atoms (%d) than expected (%d)", - natoms, atoms->nr); + gmx_fatal(FARGS, "gro file contains more atoms (%d) than expected (%d)", natoms, atoms->nr); } - else if (natoms < atoms->nr) + else if (natoms < atoms->nr) { - fprintf(stderr, "Warning: gro file contains less atoms (%d) than expected" - " (%d)\n", natoms, atoms->nr); + fprintf(stderr, + "Warning: gro file contains less atoms (%d) than expected" + " (%d)\n", + natoms, atoms->nr); } atoms->haveMass = FALSE; @@ -126,20 +133,19 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, bVel = FALSE; - resname[0] = '\0'; - oldresname[0] = '\0'; + resname[0] = '\0'; + oldresname[0] = '\0'; /* just pray the arrays are big enough */ for (i = 0; (i < natoms); i++) { if ((fgets2(line, STRLEN, in)) == nullptr) { - gmx_fatal(FARGS, "Unexpected end of file in file %s at line %d", - infile, i+2); + gmx_fatal(FARGS, "Unexpected end of file in file %s at line %d", infile, i + 2); } if (strlen(line) < 39) { - gmx_fatal(FARGS, "Invalid line in %s for atom %d:\n%s", infile, i+1, line); + gmx_fatal(FARGS, "Invalid line in %s for atom %d:\n%s", infile, i + 1, line); } /* determine read precision from distance between periods @@ -168,7 +174,10 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, if (p3 - p2 != ddist) { - gmx_fatal(FARGS, "The spacing of the decimal points in file %s is not consistent for x, y and z", infile); + gmx_fatal(FARGS, + "The spacing of the decimal points in file %s is not consistent for x, y " + "and z", + infile); } } @@ -176,7 +185,7 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, memcpy(name, line, 5); name[5] = '\0'; sscanf(name, "%d", &resnr); - sscanf(line+5, "%5s", resname); + sscanf(line + 5, "%5s", resname); if (!oldResFirst || oldres != resnr || strncmp(resname, oldresname, sizeof(resname)) != 0) { @@ -185,8 +194,7 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, newres++; if (newres >= natoms) { - gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", - infile, natoms); + gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)", infile, natoms); } atoms->atom[i].resind = newres; t_atoms_set_resinfo(atoms, i, symtab, resname, resnr, ' ', 0, ' '); @@ -197,7 +205,7 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, } /* atomname */ - std::memcpy(name, line+10, 5); + std::memcpy(name, line + 10, 5); atoms->atomname[i] = put_symtab(symtab, name); /* Copy resname to oldresname after we are done with the sanity check above */ @@ -218,7 +226,10 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, buf[c] = '\0'; if (sscanf(buf, "%lf %lf", &x1, &x2) != 1) { - gmx_fatal(FARGS, "Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)", infile); + gmx_fatal(FARGS, + "Something is wrong in the coordinate formatting of file %s. Note that " + "gro is fixed format (see the manual)", + infile); } else { @@ -280,10 +291,10 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, } for (m = 0; (m < DIM); m++) { - box[m][m] = (xmax[m]-xmin[m]); + box[m][m] = (xmax[m] - xmin[m]); } - fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n", - box[XX][XX], box[YY][YY], box[ZZ][ZZ]); + fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n", box[XX][XX], box[YY][YY], + box[ZZ][ZZ]); } else { @@ -291,8 +302,7 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, box[XX][XX] = x1; box[YY][YY] = y1; box[ZZ][ZZ] = z1; - if (sscanf (line, "%*f%*f%*f%lf%lf%lf%lf%lf%lf", - &x1, &y1, &z1, &x2, &y2, &z2) != 6) + if (sscanf(line, "%*f%*f%*f%lf%lf%lf%lf%lf%lf", &x1, &y1, &z1, &x2, &y2, &z2) != 6) { x1 = y1 = z1 = x2 = y2 = z2 = 0.0; } @@ -307,11 +317,9 @@ static gmx_bool get_w_conf(FILE *in, const char *infile, char *title, return bVel; } -void gmx_gro_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], rvec *v, matrix box) +void gmx_gro_read_conf(const char* infile, t_symtab* symtab, char** name, t_atoms* atoms, rvec x[], rvec* v, matrix box) { - FILE *in = gmx_fio_fopen(infile, "r"); + FILE* in = gmx_fio_fopen(infile, "r"); int ndec; char title[STRLEN]; get_w_conf(in, infile, title, symtab, atoms, &ndec, x, v, box); @@ -322,7 +330,7 @@ void gmx_gro_read_conf(const char *infile, gmx_fio_fclose(in); } -static gmx_bool gmx_one_before_eof(FILE *fp) +static gmx_bool gmx_one_before_eof(FILE* fp) { char data[4]; gmx_bool beof = fread(data, 1, 1, fp) != 1; @@ -334,7 +342,7 @@ static gmx_bool gmx_one_before_eof(FILE *fp) return beof; } -gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr) +gmx_bool gro_next_x_or_v(FILE* status, t_trxframe* fr) { t_atoms atoms; t_symtab symtab; @@ -362,8 +370,8 @@ gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr) { fr->prec *= 10; } - fr->bX = TRUE; - fr->bBox = TRUE; + fr->bX = TRUE; + fr->bBox = TRUE; sfree(atoms.atom); sfree(atoms.resinfo); @@ -387,20 +395,23 @@ gmx_bool gro_next_x_or_v(FILE *status, t_trxframe *fr) if ((p = std::strstr(title, "step=")) != nullptr) { - p += 5; + p += 5; fr->step = 0; // Default value if fr-bStep is false fr->bStep = (sscanf(p, "%" SCNd64, &fr->step) == 1); } if (atoms.nr != fr->natoms) { - gmx_fatal(FARGS, "Number of atoms in gro frame (%d) doesn't match the number in the previous frame (%d)", atoms.nr, fr->natoms); + gmx_fatal(FARGS, + "Number of atoms in gro frame (%d) doesn't match the number in the previous " + "frame (%d)", + atoms.nr, fr->natoms); } return TRUE; } -int gro_first_x_or_v(FILE *status, t_trxframe *fr) +int gro_first_x_or_v(FILE* status, t_trxframe* fr) { char title[STRLEN]; @@ -421,7 +432,7 @@ int gro_first_x_or_v(FILE *status, t_trxframe *fr) return fr->natoms; } -static const char *get_hconf_format(bool haveVelocities) +static const char* get_hconf_format(bool haveVelocities) { if (haveVelocities) { @@ -431,36 +442,38 @@ static const char *get_hconf_format(bool haveVelocities) { return "%8.3f%8.3f%8.3f\n"; } - } -static void write_hconf_box(FILE *out, const matrix box) +static void write_hconf_box(FILE* out, const matrix box) { - if ((box[XX][YY] != 0.0F) || (box[XX][ZZ] != 0.0F) || (box[YY][XX] != 0.0F) || (box[YY][ZZ] != 0.0F) || - (box[ZZ][XX] != 0.0F) || (box[ZZ][YY] != 0.0F)) + if ((box[XX][YY] != 0.0F) || (box[XX][ZZ] != 0.0F) || (box[YY][XX] != 0.0F) + || (box[YY][ZZ] != 0.0F) || (box[ZZ][XX] != 0.0F) || (box[ZZ][YY] != 0.0F)) { - fprintf(out, "%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n", - box[XX][XX], box[YY][YY], box[ZZ][ZZ], - box[XX][YY], box[XX][ZZ], box[YY][XX], - box[YY][ZZ], box[ZZ][XX], box[ZZ][YY]); + fprintf(out, "%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n", box[XX][XX], + box[YY][YY], box[ZZ][ZZ], box[XX][YY], box[XX][ZZ], box[YY][XX], box[YY][ZZ], + box[ZZ][XX], box[ZZ][YY]); } else { - fprintf(out, "%10.5f%10.5f%10.5f\n", - box[XX][XX], box[YY][YY], box[ZZ][ZZ]); + fprintf(out, "%10.5f%10.5f%10.5f\n", box[XX][XX], box[YY][YY], box[ZZ][ZZ]); } } -void write_hconf_indexed_p(FILE *out, const char *title, const t_atoms *atoms, - int nx, const int index[], - const rvec *x, const rvec *v, const matrix box) +void write_hconf_indexed_p(FILE* out, + const char* title, + const t_atoms* atoms, + int nx, + const int index[], + const rvec* x, + const rvec* v, + const matrix box) { - int ai, i, resind, resnr; + int ai, i, resind, resnr; fprintf(out, "%s\n", (title && title[0]) ? title : gmx::bromacs().c_str()); fprintf(out, "%5d\n", nx); - const char *format = get_hconf_format(v != nullptr); + const char* format = get_hconf_format(v != nullptr); for (i = 0; (i < nx); i++) { @@ -489,17 +502,15 @@ void write_hconf_indexed_p(FILE *out, const char *title, const t_atoms *atoms, nm = " ??? "; } - fprintf(out, "%5d%-5.5s%5.5s%5d", resnr%100000, resnm.c_str(), nm.c_str(), (ai+1)%100000); + fprintf(out, "%5d%-5.5s%5.5s%5d", resnr % 100000, resnm.c_str(), nm.c_str(), (ai + 1) % 100000); /* next fprintf uses built format string */ if (v) { - fprintf(out, format, - x[ai][XX], x[ai][YY], x[ai][ZZ], v[ai][XX], v[ai][YY], v[ai][ZZ]); + fprintf(out, format, x[ai][XX], x[ai][YY], x[ai][ZZ], v[ai][XX], v[ai][YY], v[ai][ZZ]); } else { - fprintf(out, format, - x[ai][XX], x[ai][YY], x[ai][ZZ]); + fprintf(out, format, x[ai][XX], x[ai][YY], x[ai][ZZ]); } } @@ -508,33 +519,29 @@ void write_hconf_indexed_p(FILE *out, const char *title, const t_atoms *atoms, fflush(out); } -void write_hconf_mtop(FILE *out, const char *title, const gmx_mtop_t *mtop, - const rvec *x, const rvec *v, const matrix box) +void write_hconf_mtop(FILE* out, const char* title, const gmx_mtop_t* mtop, const rvec* x, const rvec* v, const matrix box) { fprintf(out, "%s\n", (title && title[0]) ? title : gmx::bromacs().c_str()); fprintf(out, "%5d\n", mtop->natoms); - const char *format = get_hconf_format(v != nullptr); + const char* format = get_hconf_format(v != nullptr); for (const AtomProxy atomP : AtomRange(*mtop)) { int i = atomP.globalAtomNumber(); int residueNumber = atomP.residueNumber(); - const char *atomName = atomP.atomName(); - const char *residueName = atomP.residueName(); + const char* atomName = atomP.atomName(); + const char* residueName = atomP.residueName(); - fprintf(out, "%5d%-5.5s%5.5s%5d", - residueNumber%100000, residueName, atomName, (i+1)%100000); + fprintf(out, "%5d%-5.5s%5.5s%5d", residueNumber % 100000, residueName, atomName, (i + 1) % 100000); /* next fprintf uses built format string */ if (v) { - fprintf(out, format, - x[i][XX], x[i][YY], x[i][ZZ], v[i][XX], v[i][YY], v[i][ZZ]); + fprintf(out, format, x[i][XX], x[i][YY], x[i][ZZ], v[i][XX], v[i][YY], v[i][ZZ]); } else { - fprintf(out, format, - x[i][XX], x[i][YY], x[i][ZZ]); + fprintf(out, format, x[i][XX], x[i][YY], x[i][ZZ]); } } @@ -543,11 +550,10 @@ void write_hconf_mtop(FILE *out, const char *title, const gmx_mtop_t *mtop, fflush(out); } -void write_hconf_p(FILE *out, const char *title, const t_atoms *atoms, - const rvec *x, const rvec *v, const matrix box) +void write_hconf_p(FILE* out, const char* title, const t_atoms* atoms, const rvec* x, const rvec* v, const matrix box) { - int *aa; - int i; + int* aa; + int i; snew(aa, atoms->nr); for (i = 0; (i < atoms->nr); i++) @@ -558,11 +564,14 @@ void write_hconf_p(FILE *out, const char *title, const t_atoms *atoms, sfree(aa); } -void write_conf_p(const char *outfile, const char *title, - const t_atoms *atoms, - const rvec *x, const rvec *v, const matrix box) +void write_conf_p(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec* x, + const rvec* v, + const matrix box) { - FILE *out; + FILE* out; out = gmx_fio_fopen(outfile, "w"); write_hconf_p(out, title, atoms, x, v, box); diff --git a/src/gromacs/fileio/groio.h b/src/gromacs/fileio/groio.h index e0230498fd..0c8c8cc517 100644 --- a/src/gromacs/fileio/groio.h +++ b/src/gromacs/fileio/groio.h @@ -47,30 +47,34 @@ struct t_atoms; struct t_symtab; struct t_trxframe; -void get_coordnum(const char *infile, int *natoms); -void gmx_gro_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], rvec *v, matrix box); +void get_coordnum(const char* infile, int* natoms); +void gmx_gro_read_conf(const char* infile, t_symtab* symtab, char** name, t_atoms* atoms, rvec x[], rvec* v, matrix box); /* If name is not nullptr, gmx_strdup the title string into it. */ -gmx_bool gro_next_x_or_v(FILE *status, struct t_trxframe *fr); -int gro_first_x_or_v(FILE *status, struct t_trxframe *fr); +gmx_bool gro_next_x_or_v(FILE* status, struct t_trxframe* fr); +int gro_first_x_or_v(FILE* status, struct t_trxframe* fr); /* read first/next x and/or v frame from gro file */ -void write_hconf_indexed_p(FILE *out, const char *title, const t_atoms *atoms, - int nx, const int index[], - const rvec *x, const rvec *v, const matrix box); +void write_hconf_indexed_p(FILE* out, + const char* title, + const t_atoms* atoms, + int nx, + const int index[], + const rvec* x, + const rvec* v, + const matrix box); -void write_hconf_mtop(FILE *out, const char *title, const gmx_mtop_t *mtop, - const rvec *x, const rvec *v, const matrix box); +void write_hconf_mtop(FILE* out, const char* title, const gmx_mtop_t* mtop, const rvec* x, const rvec* v, const matrix box); -void write_hconf_p(FILE *out, const char *title, const t_atoms *atoms, - const rvec *x, const rvec *v, const matrix box); +void write_hconf_p(FILE* out, const char* title, const t_atoms* atoms, const rvec* x, const rvec* v, const matrix box); /* Write a Gromos file with precision ndec: number of decimal places in x, * v has one place more. */ -void write_conf_p(const char *outfile, const char *title, - const t_atoms *atoms, - const rvec *x, const rvec *v, const matrix box); +void write_conf_p(const char* outfile, + const char* title, + const t_atoms* atoms, + const rvec* x, + const rvec* v, + const matrix box); #endif diff --git a/src/gromacs/fileio/libxdrf.cpp b/src/gromacs/fileio/libxdrf.cpp index c6be3354de..683860cda3 100644 --- a/src/gromacs/fileio/libxdrf.cpp +++ b/src/gromacs/fileio/libxdrf.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,15 +52,7 @@ #define XDR_INT_SIZE 4 /* same order as the definition of xdr_datatype */ -const char *xdr_datatype_names[] = -{ - "int", - "float", - "double", - "large int", - "char", - "string" -}; +const char* xdr_datatype_names[] = { "int", "float", "double", "large int", "char", "string" }; /*___________________________________________________________________________ @@ -69,20 +61,20 @@ const char *xdr_datatype_names[] = | with some routines to assist in this task (those are marked | static and cannot be called from user programs) */ -#define MAXABS (INT_MAX-2) +#define MAXABS (INT_MAX - 2) #ifndef SQR -#define SQR(x) ((x)*(x)) +# define SQR(x) ((x) * (x)) #endif static const int magicints[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8, 10, 12, 16, 20, 25, 32, 40, 50, 64, - 80, 101, 128, 161, 203, 256, 322, 406, 512, 645, - 812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501, - 8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536, - 82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, - 832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042, - 8388607, 10568983, 13316085, 16777216 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, + 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, + 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, + 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536, 82570, + 104031, 131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255, + 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304, 5284491, 6658042, 8388607, + 10568983, 13316085, 16777216 }; #define FIRSTIDX 9 @@ -104,27 +96,27 @@ static const int magicints[] = { static void sendbits(int buf[], int num_of_bits, int num) { - unsigned int cnt, lastbyte; - int lastbits; - unsigned char * cbuf; + unsigned int cnt, lastbyte; + int lastbits; + unsigned char* cbuf; - cbuf = (reinterpret_cast(buf)) + 3 * sizeof(*buf); + cbuf = (reinterpret_cast(buf)) + 3 * sizeof(*buf); cnt = static_cast(buf[0]); lastbits = buf[1]; lastbyte = static_cast(buf[2]); while (num_of_bits >= 8) { - lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/); - cbuf[cnt++] = lastbyte >> lastbits; + lastbyte = (lastbyte << 8) | ((num >> (num_of_bits - 8)) /* & 0xff*/); + cbuf[cnt++] = lastbyte >> lastbits; num_of_bits -= 8; } if (num_of_bits > 0) { - lastbyte = (lastbyte << num_of_bits) | num; + lastbyte = (lastbyte << num_of_bits) | num; lastbits += num_of_bits; if (lastbits >= 8) { - lastbits -= 8; + lastbits -= 8; cbuf[cnt++] = lastbyte >> lastbits; } } @@ -170,7 +162,7 @@ static int sizeofint(const int size) | So I don't need to call 'sizeofints for those calls. */ -static int sizeofints( const int num_of_ints, const unsigned int sizes[]) +static int sizeofints(const int num_of_ints, const unsigned int sizes[]) { int i, num; int bytes[32]; @@ -185,12 +177,12 @@ static int sizeofints( const int num_of_ints, const unsigned int sizes[]) { tmp = bytes[bytecnt] * sizes[i] + tmp; bytes[bytecnt] = tmp & 0xff; - tmp >>= 8; + tmp >>= 8; } while (tmp != 0) { bytes[bytecnt++] = tmp & 0xff; - tmp >>= 8; + tmp >>= 8; } num_of_bytes = bytecnt; } @@ -202,7 +194,6 @@ static int sizeofints( const int num_of_ints, const unsigned int sizes[]) num *= 2; } return num_of_bits + num_of_bytes * 8; - } /*____________________________________________________________________________ @@ -220,8 +211,11 @@ static int sizeofints( const int num_of_ints, const unsigned int sizes[]) | */ -static void sendints(int buf[], const int num_of_ints, const int num_of_bits, - unsigned int sizes[], unsigned int nums[]) +static void sendints(int buf[], + const int num_of_ints, + const int num_of_bits, + unsigned int sizes[], + unsigned int nums[]) { int i, num_of_bytes, bytecnt; @@ -232,16 +226,17 @@ static void sendints(int buf[], const int num_of_ints, const int num_of_bits, do { bytes[num_of_bytes++] = tmp & 0xff; - tmp >>= 8; - } - while (tmp != 0); + tmp >>= 8; + } while (tmp != 0); for (i = 1; i < num_of_ints; i++) { if (nums[i] >= sizes[i]) { - fprintf(stderr, "major breakdown in sendints num %u doesn't " - "match size %u\n", nums[i], sizes[i]); + fprintf(stderr, + "major breakdown in sendints num %u doesn't " + "match size %u\n", + nums[i], sizes[i]); exit(1); } /* use one step multiply */ @@ -250,12 +245,12 @@ static void sendints(int buf[], const int num_of_ints, const int num_of_bits, { tmp = bytes[bytecnt] * sizes[i] + tmp; bytes[bytecnt] = tmp & 0xff; - tmp >>= 8; + tmp >>= 8; } while (tmp != 0) { bytes[bytecnt++] = tmp & 0xff; - tmp >>= 8; + tmp >>= 8; } num_of_bytes = bytecnt; } @@ -269,11 +264,11 @@ static void sendints(int buf[], const int num_of_ints, const int num_of_bits, } else { - for (i = 0; i < num_of_bytes-1; i++) + for (i = 0; i < num_of_bytes - 1; i++) { sendbits(buf, 8, bytes[i]); } - sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]); + sendbits(buf, num_of_bits - (num_of_bytes - 1) * 8, bytes[i]); } } @@ -290,12 +285,12 @@ static void sendints(int buf[], const int num_of_ints, const int num_of_bits, static int receivebits(int buf[], int num_of_bits) { - int cnt, num, lastbits; - unsigned int lastbyte; - unsigned char * cbuf; - int mask = (1 << num_of_bits) -1; + int cnt, num, lastbits; + unsigned int lastbyte; + unsigned char* cbuf; + int mask = (1 << num_of_bits) - 1; - cbuf = reinterpret_cast(buf) + 3 * sizeof(*buf); + cbuf = reinterpret_cast(buf) + 3 * sizeof(*buf); cnt = buf[0]; lastbits = static_cast(buf[1]); lastbyte = static_cast(buf[2]); @@ -303,8 +298,8 @@ static int receivebits(int buf[], int num_of_bits) num = 0; while (num_of_bits >= 8) { - lastbyte = ( lastbyte << 8 ) | cbuf[cnt++]; - num |= (lastbyte >> lastbits) << (num_of_bits - 8); + lastbyte = (lastbyte << 8) | cbuf[cnt++]; + num |= (lastbyte >> lastbits) << (num_of_bits - 8); num_of_bits -= 8; } if (num_of_bits > 0) @@ -312,12 +307,12 @@ static int receivebits(int buf[], int num_of_bits) if (lastbits < num_of_bits) { lastbits += 8; - lastbyte = (lastbyte << 8) | cbuf[cnt++]; + lastbyte = (lastbyte << 8) | cbuf[cnt++]; } lastbits -= num_of_bits; - num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1); + num |= (lastbyte >> lastbits) & ((1 << num_of_bits) - 1); } - num &= mask; + num &= mask; buf[0] = cnt; buf[1] = lastbits; buf[2] = lastbyte; @@ -335,27 +330,26 @@ static int receivebits(int buf[], int num_of_bits) | */ -static void receiveints(int buf[], const int num_of_ints, int num_of_bits, - const unsigned int sizes[], int nums[]) +static void receiveints(int buf[], const int num_of_ints, int num_of_bits, const unsigned int sizes[], int nums[]) { int bytes[32]; int i, j, num_of_bytes, p, num; - bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0; - num_of_bytes = 0; + bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0; + num_of_bytes = 0; while (num_of_bits > 8) { bytes[num_of_bytes++] = receivebits(buf, 8); - num_of_bits -= 8; + num_of_bits -= 8; } if (num_of_bits > 0) { bytes[num_of_bytes++] = receivebits(buf, num_of_bits); } - for (i = num_of_ints-1; i > 0; i--) + for (i = num_of_ints - 1; i > 0; i--) { num = 0; - for (j = num_of_bytes-1; j >= 0; j--) + for (j = num_of_bytes - 1; j >= 0; j--) { num = (num << 8) | bytes[j]; p = num / sizes[i]; @@ -394,17 +388,17 @@ static void receiveints(int buf[], const int num_of_ints, int num_of_bits, | */ -int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) +int xdr3dfcoord(XDR* xdrs, float* fp, int* size, float* precision) { - int *ip = nullptr; - int *buf = nullptr; + int* ip = nullptr; + int* buf = nullptr; gmx_bool bRead; /* preallocate a small buffer and ip on the stack - if we need more we can always malloc(). This is faster for small values of size: */ - unsigned prealloc_size = 3*16; - int prealloc_ip[3*16], prealloc_buf[3*20]; - int we_should_free = 0; + unsigned prealloc_size = 3 * 16; + int prealloc_ip[3 * 16], prealloc_buf[3 * 20]; + int we_should_free = 0; int minint[3], maxint[3], mindiff, *lip, diff; int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx; @@ -412,8 +406,8 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip; int flag, k; int smallnum, smaller, larger, i, is_small, is_smaller, run, prevrun; - float *lfp, lf; - int tmp, *thiscoord, prevcoord[3]; + float * lfp, lf; + int tmp, *thiscoord, prevcoord[3]; unsigned int tmpcoord[30]; int bufsize, lsize; @@ -424,7 +418,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) bRead = (xdrs->x_op == XDR_DECODE); bitsizeint[0] = bitsizeint[1] = bitsizeint[2] = 0; - prevcoord[0] = prevcoord[1] = prevcoord[2] = 0; + prevcoord[0] = prevcoord[1] = prevcoord[2] = 0; // The static analyzer warns about garbage values for thiscoord[] further // down. It might be thrown off by all the reinterpret_casts, but we might @@ -448,8 +442,9 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) */ if (*size <= 9) { - return (xdr_vector(xdrs, reinterpret_cast(fp), static_cast(size3), - static_cast(sizeof(*fp)), reinterpret_cast(xdr_float))); + return (xdr_vector(xdrs, reinterpret_cast(fp), static_cast(size3), + static_cast(sizeof(*fp)), + reinterpret_cast(xdr_float))); } if (xdr_float(xdrs, precision) == 0) @@ -466,8 +461,8 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { we_should_free = 1; bufsize = static_cast(size3 * 1.2); - ip = reinterpret_cast(malloc(size3 * sizeof(*ip))); - buf = reinterpret_cast(malloc(bufsize * sizeof(*buf))); + ip = reinterpret_cast(malloc(size3 * sizeof(*ip))); + buf = reinterpret_cast(malloc(bufsize * sizeof(*buf))); if (ip == nullptr || buf == nullptr) { fprintf(stderr, "malloc failed\n"); @@ -475,14 +470,14 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } } /* buf[0-2] are special and do not contain actual data */ - buf[0] = buf[1] = buf[2] = 0; + buf[0] = buf[1] = buf[2] = 0; minint[0] = minint[1] = minint[2] = INT_MAX; maxint[0] = maxint[1] = maxint[2] = INT_MIN; - prevrun = -1; - lfp = fp; - lip = ip; - mindiff = INT_MAX; - oldlint1 = oldlint2 = oldlint3 = 0; + prevrun = -1; + lfp = fp; + lip = ip; + mindiff = INT_MAX; + oldlint1 = oldlint2 = oldlint3 = 0; while (lfp < fp + size3) { /* find nearest integer */ @@ -558,7 +553,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } *lip++ = lint3; lfp++; - diff = std::abs(oldlint1-lint1)+std::abs(oldlint2-lint2)+std::abs(oldlint3-lint3); + diff = std::abs(oldlint1 - lint1) + std::abs(oldlint2 - lint2) + std::abs(oldlint3 - lint3); if (diff < mindiff && lfp > fp + 3) { mindiff = diff; @@ -567,12 +562,9 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) oldlint2 = lint2; oldlint3 = lint3; } - if ( (xdr_int(xdrs, &(minint[0])) == 0) || - (xdr_int(xdrs, &(minint[1])) == 0) || - (xdr_int(xdrs, &(minint[2])) == 0) || - (xdr_int(xdrs, &(maxint[0])) == 0) || - (xdr_int(xdrs, &(maxint[1])) == 0) || - (xdr_int(xdrs, &(maxint[2])) == 0)) + if ((xdr_int(xdrs, &(minint[0])) == 0) || (xdr_int(xdrs, &(minint[1])) == 0) + || (xdr_int(xdrs, &(minint[2])) == 0) || (xdr_int(xdrs, &(maxint[0])) == 0) + || (xdr_int(xdrs, &(maxint[1])) == 0) || (xdr_int(xdrs, &(maxint[2])) == 0)) { if (we_should_free) { @@ -582,21 +574,21 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) return 0; } - if (static_cast(maxint[0]) - static_cast(minint[0]) >= MAXABS || - static_cast(maxint[1]) - static_cast(minint[1]) >= MAXABS || - static_cast(maxint[2]) - static_cast(minint[2]) >= MAXABS) + if (static_cast(maxint[0]) - static_cast(minint[0]) >= MAXABS + || static_cast(maxint[1]) - static_cast(minint[1]) >= MAXABS + || static_cast(maxint[2]) - static_cast(minint[2]) >= MAXABS) { /* turning value in unsigned by subtracting minint * would cause overflow */ errval = 0; } - sizeint[0] = maxint[0] - minint[0]+1; - sizeint[1] = maxint[1] - minint[1]+1; - sizeint[2] = maxint[2] - minint[2]+1; + sizeint[0] = maxint[0] - minint[0] + 1; + sizeint[1] = maxint[1] - minint[1] + 1; + sizeint[2] = maxint[2] - minint[2] + 1; /* check if one of the sizes is to big to be multiplied */ - if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) + if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff) { bitsizeint[0] = sizeofint(sizeint[0]); bitsizeint[1] = sizeofint(sizeint[1]); @@ -607,7 +599,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { bitsize = sizeofints(3, sizeint); } - luip = reinterpret_cast(ip); + luip = reinterpret_cast(ip); smallidx = FIRSTIDX; while (smallidx < LASTIDX && magicints[smallidx] < mindiff) { @@ -625,19 +617,18 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) maxidx = std::min(LASTIDX, smallidx + 8); minidx = maxidx - 8; /* often this equal smallidx */ - smaller = magicints[std::max(FIRSTIDX, smallidx-1)] / 2; + smaller = magicints[std::max(FIRSTIDX, smallidx - 1)] / 2; smallnum = magicints[smallidx] / 2; sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx]; - larger = magicints[maxidx] / 2; - i = 0; + larger = magicints[maxidx] / 2; + i = 0; while (i < *size) { is_small = 0; - thiscoord = reinterpret_cast(luip) + i * 3; - if (smallidx < maxidx && i >= 1 && - std::abs(thiscoord[0] - prevcoord[0]) < larger && - std::abs(thiscoord[1] - prevcoord[1]) < larger && - std::abs(thiscoord[2] - prevcoord[2]) < larger) + thiscoord = reinterpret_cast(luip) + i * 3; + if (smallidx < maxidx && i >= 1 && std::abs(thiscoord[0] - prevcoord[0]) < larger + && std::abs(thiscoord[1] - prevcoord[1]) < larger + && std::abs(thiscoord[2] - prevcoord[2]) < larger) { is_smaller = 1; } @@ -651,22 +642,24 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } if (i + 1 < *size) { - if (std::abs(thiscoord[0] - thiscoord[3]) < smallnum && - std::abs(thiscoord[1] - thiscoord[4]) < smallnum && - std::abs(thiscoord[2] - thiscoord[5]) < smallnum) + if (std::abs(thiscoord[0] - thiscoord[3]) < smallnum + && std::abs(thiscoord[1] - thiscoord[4]) < smallnum + && std::abs(thiscoord[2] - thiscoord[5]) < smallnum) { /* interchange first with second atom for better * compression of water molecules */ - tmp = thiscoord[0]; thiscoord[0] = thiscoord[3]; + tmp = thiscoord[0]; + thiscoord[0] = thiscoord[3]; thiscoord[3] = tmp; - tmp = thiscoord[1]; thiscoord[1] = thiscoord[4]; + tmp = thiscoord[1]; + thiscoord[1] = thiscoord[4]; thiscoord[4] = tmp; - tmp = thiscoord[2]; thiscoord[2] = thiscoord[5]; + tmp = thiscoord[2]; + thiscoord[2] = thiscoord[5]; thiscoord[5] = tmp; is_small = 1; } - } tmpcoord[0] = thiscoord[0] - minint[0]; tmpcoord[1] = thiscoord[1] - minint[1]; @@ -692,12 +685,12 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { is_smaller = 0; } - while (is_small && run < 8*3) + while (is_small && run < 8 * 3) { - if (is_smaller == -1 && ( - SQR(thiscoord[0] - prevcoord[0]) + - SQR(thiscoord[1] - prevcoord[1]) + - SQR(thiscoord[2] - prevcoord[2]) >= smaller * smaller)) + if (is_smaller == -1 + && (SQR(thiscoord[0] - prevcoord[0]) + SQR(thiscoord[1] - prevcoord[1]) + + SQR(thiscoord[2] - prevcoord[2]) + >= smaller * smaller)) { is_smaller = 0; } @@ -713,10 +706,9 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) i++; thiscoord = thiscoord + 3; is_small = 0; - if (i < *size && - abs(thiscoord[0] - prevcoord[0]) < smallnum && - abs(thiscoord[1] - prevcoord[1]) < smallnum && - abs(thiscoord[2] - prevcoord[2]) < smallnum) + if (i < *size && abs(thiscoord[0] - prevcoord[0]) < smallnum + && abs(thiscoord[1] - prevcoord[1]) < smallnum + && abs(thiscoord[2] - prevcoord[2]) < smallnum) { is_small = 1; } @@ -725,7 +717,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { prevrun = run; sendbits(buf, 1, 1); /* flag the change in run-length */ - sendbits(buf, 5, run+is_smaller+1); + sendbits(buf, 5, run + is_smaller + 1); } else { @@ -741,7 +733,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) if (is_smaller < 0) { smallnum = smaller; - smaller = magicints[smallidx-1] / 2; + smaller = magicints[smallidx - 1] / 2; } else { @@ -767,14 +759,14 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } - rc = errval * (xdr_opaque(xdrs, reinterpret_cast(&(buf[3])), static_cast(buf[0]))); + rc = errval + * (xdr_opaque(xdrs, reinterpret_cast(&(buf[3])), static_cast(buf[0]))); if (we_should_free) { free(ip); free(buf); } return rc; - } else { @@ -787,16 +779,19 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } if (*size != 0 && lsize != *size) { - fprintf(stderr, "wrong number of coordinates in xdr3dfcoord; " - "%d arg vs %d in file", *size, lsize); + fprintf(stderr, + "wrong number of coordinates in xdr3dfcoord; " + "%d arg vs %d in file", + *size, lsize); } *size = lsize; size3 = *size * 3; if (*size <= 9) { *precision = -1; - return (xdr_vector(xdrs, reinterpret_cast(fp), static_cast(size3), - static_cast(sizeof(*fp)), reinterpret_cast(xdr_float))); + return (xdr_vector(xdrs, reinterpret_cast(fp), static_cast(size3), + static_cast(sizeof(*fp)), + reinterpret_cast(xdr_float))); } if (xdr_float(xdrs, precision) == 0) { @@ -812,8 +807,8 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { we_should_free = 1; bufsize = static_cast(size3 * 1.2); - ip = reinterpret_cast(malloc(size3 * sizeof(*ip))); - buf = reinterpret_cast(malloc(bufsize * sizeof(*buf))); + ip = reinterpret_cast(malloc(size3 * sizeof(*ip))); + buf = reinterpret_cast(malloc(bufsize * sizeof(*buf))); if (ip == nullptr || buf == nullptr) { fprintf(stderr, "malloc failed\n"); @@ -823,12 +818,9 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) buf[0] = buf[1] = buf[2] = 0; - if ( (xdr_int(xdrs, &(minint[0])) == 0) || - (xdr_int(xdrs, &(minint[1])) == 0) || - (xdr_int(xdrs, &(minint[2])) == 0) || - (xdr_int(xdrs, &(maxint[0])) == 0) || - (xdr_int(xdrs, &(maxint[1])) == 0) || - (xdr_int(xdrs, &(maxint[2])) == 0)) + if ((xdr_int(xdrs, &(minint[0])) == 0) || (xdr_int(xdrs, &(minint[1])) == 0) + || (xdr_int(xdrs, &(minint[2])) == 0) || (xdr_int(xdrs, &(maxint[0])) == 0) + || (xdr_int(xdrs, &(maxint[1])) == 0) || (xdr_int(xdrs, &(maxint[2])) == 0)) { if (we_should_free) { @@ -838,12 +830,12 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) return 0; } - sizeint[0] = maxint[0] - minint[0]+1; - sizeint[1] = maxint[1] - minint[1]+1; - sizeint[2] = maxint[2] - minint[2]+1; + sizeint[0] = maxint[0] - minint[0] + 1; + sizeint[1] = maxint[1] - minint[1] + 1; + sizeint[2] = maxint[2] - minint[2] + 1; /* check if one of the sizes is to big to be multiplied */ - if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) + if ((sizeint[0] | sizeint[1] | sizeint[2]) > 0xffffff) { bitsizeint[0] = sizeofint(sizeint[0]); bitsizeint[1] = sizeofint(sizeint[1]); @@ -865,7 +857,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) return 0; } - smaller = magicints[std::max(FIRSTIDX, smallidx-1)] / 2; + smaller = magicints[std::max(FIRSTIDX, smallidx - 1)] / 2; smallnum = magicints[smallidx] / 2; sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx]; @@ -882,7 +874,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } - if (xdr_opaque(xdrs, reinterpret_cast(&(buf[3])), static_cast(buf[0])) == 0) + if (xdr_opaque(xdrs, reinterpret_cast(&(buf[3])), static_cast(buf[0])) == 0) { if (we_should_free) { @@ -893,7 +885,6 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } - buf[0] = buf[1] = buf[2] = 0; lfp = fp; @@ -903,7 +894,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) lip = ip; while (i < lsize) { - thiscoord = reinterpret_cast(lip) + i * 3; + thiscoord = reinterpret_cast(lip) + i * 3; if (bitsize == 0) { @@ -932,7 +923,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) { run = receivebits(buf, 5); is_smaller = run % 3; - run -= is_smaller; + run -= is_smaller; is_smaller--; } if (run > 0) @@ -950,11 +941,14 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) /* interchange first with second atom for better * compression of water molecules */ - tmp = thiscoord[0]; thiscoord[0] = prevcoord[0]; + tmp = thiscoord[0]; + thiscoord[0] = prevcoord[0]; prevcoord[0] = tmp; - tmp = thiscoord[1]; thiscoord[1] = prevcoord[1]; + tmp = thiscoord[1]; + thiscoord[1] = prevcoord[1]; prevcoord[1] = tmp; - tmp = thiscoord[2]; thiscoord[2] = prevcoord[2]; + tmp = thiscoord[2]; + thiscoord[2] = prevcoord[2]; prevcoord[2] = tmp; *lfp++ = prevcoord[0] * inv_precision; *lfp++ = prevcoord[1] * inv_precision; @@ -983,7 +977,7 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) smallnum = smaller; if (smallidx > FIRSTIDX) { - smaller = magicints[smallidx - 1] /2; + smaller = magicints[smallidx - 1] / 2; } else { @@ -1007,7 +1001,6 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) } - /****************************************************************** XTC files have a relatively simple structure. @@ -1025,15 +1018,14 @@ int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision) /* Must match definition in xtcio.c */ #ifndef XTC_MAGIC -#define XTC_MAGIC 1995 +# define XTC_MAGIC 1995 #endif static const int header_size = 16; /* Check if we are at the header start. At the same time it will also read 1 int */ -static int xtc_at_header_start(FILE *fp, XDR *xdrs, - int natoms, int * timestep, float * time) +static int xtc_at_header_start(FILE* fp, XDR* xdrs, int natoms, int* timestep, float* time) { int i_inp[3]; float f_inp[10]; @@ -1050,14 +1042,14 @@ static int xtc_at_header_start(FILE *fp, XDR *xdrs, { if (!xdr_int(xdrs, &(i_inp[i]))) { - gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET); + gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET); return -1; } } /* quick return */ if (i_inp[0] != XTC_MAGIC) { - if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET)) + if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET)) { return -1; } @@ -1068,7 +1060,7 @@ static int xtc_at_header_start(FILE *fp, XDR *xdrs, { if (!xdr_float(xdrs, &(f_inp[i]))) { - gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET); + gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET); return -1; } } @@ -1077,11 +1069,10 @@ static int xtc_at_header_start(FILE *fp, XDR *xdrs, /* This check makes use of the fact that the box matrix has 3 zeroes on the upper right triangle and that the first element must be nonzero unless the entire matrix is zero */ - if (i_inp[1] == natoms && - ((f_inp[1] != 0 && f_inp[6] == 0) || - (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0))) + if (i_inp[1] == natoms + && ((f_inp[1] != 0 && f_inp[6] == 0) || (f_inp[1] == 0 && f_inp[5] == 0 && f_inp[9] == 0))) { - if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET)) + if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET)) { return -1; } @@ -1089,15 +1080,14 @@ static int xtc_at_header_start(FILE *fp, XDR *xdrs, *timestep = i_inp[2]; return 1; } - if (gmx_fseek(fp, off+XDR_INT_SIZE, SEEK_SET)) + if (gmx_fseek(fp, off + XDR_INT_SIZE, SEEK_SET)) { return -1; } return 0; } -static int -xtc_get_next_frame_number(FILE *fp, XDR *xdrs, int natoms) +static int xtc_get_next_frame_number(FILE* fp, XDR* xdrs, int natoms) { gmx_off_t off; int step; @@ -1133,8 +1123,7 @@ xtc_get_next_frame_number(FILE *fp, XDR *xdrs, int natoms) } -static float xtc_get_next_frame_time(FILE *fp, XDR *xdrs, int natoms, - gmx_bool * bOK) +static float xtc_get_next_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { gmx_off_t off; float time; @@ -1173,8 +1162,7 @@ static float xtc_get_next_frame_time(FILE *fp, XDR *xdrs, int natoms, } -static float -xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) +static float xtc_get_current_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { gmx_off_t off; int step; @@ -1211,7 +1199,7 @@ xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) else if (ret == 0) { /*Go back.*/ - if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR)) + if (gmx_fseek(fp, -2 * XDR_INT_SIZE, SEEK_CUR)) { return -1; } @@ -1220,8 +1208,7 @@ xtc_get_current_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) } /* Currently not used, just for completeness */ -static int -xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) +static int xtc_get_current_frame_number(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { gmx_off_t off; int ret; @@ -1255,12 +1242,11 @@ xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) return -1; } return -1; - } else if (ret == 0) { /*Go back.*/ - if (gmx_fseek(fp, -2*XDR_INT_SIZE, SEEK_CUR)) + if (gmx_fseek(fp, -2 * XDR_INT_SIZE, SEEK_CUR)) { return -1; } @@ -1269,8 +1255,7 @@ xtc_get_current_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) } - -static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms) +static gmx_off_t xtc_get_next_frame_start(FILE* fp, XDR* xdrs, int natoms) { gmx_off_t res; int ret; @@ -1300,16 +1285,14 @@ static gmx_off_t xtc_get_next_frame_start(FILE *fp, XDR *xdrs, int natoms) } -static -float -xdr_xtc_estimate_dt(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) +static float xdr_xtc_estimate_dt(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { float res; float tinit; gmx_off_t off; *bOK = false; - if ((off = gmx_ftell(fp)) < 0) + if ((off = gmx_ftell(fp)) < 0) { return -1; } @@ -1337,16 +1320,15 @@ xdr_xtc_estimate_dt(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) return res; } -int -xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms) +int xdr_xtc_seek_frame(int frame, FILE* fp, XDR* xdrs, int natoms) { gmx_off_t low = 0; gmx_off_t high, pos; /* round to 4 bytes */ - int fr; - gmx_off_t offset; + int fr; + gmx_off_t offset; if (gmx_fseek(fp, 0, SEEK_END)) { return -1; @@ -1358,9 +1340,9 @@ xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms) } /* round to 4 bytes */ - high /= XDR_INT_SIZE; - high *= XDR_INT_SIZE; - offset = ((high/2)/XDR_INT_SIZE)*XDR_INT_SIZE; + high /= XDR_INT_SIZE; + high *= XDR_INT_SIZE; + offset = ((high / 2) / XDR_INT_SIZE) * XDR_INT_SIZE; if (gmx_fseek(fp, offset, SEEK_SET)) { @@ -1374,7 +1356,7 @@ xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms) { return -1; } - if (fr != frame && llabs(low-high) > header_size) + if (fr != frame && llabs(low - high) > header_size) { if (fr < frame) { @@ -1385,7 +1367,7 @@ xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms) high = offset; } /* round to 4 bytes */ - offset = (((high+low)/2)/4)*4; + offset = (((high + low) / 2) / 4) * 4; if (gmx_fseek(fp, offset, SEEK_SET)) { @@ -1422,8 +1404,7 @@ xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms) } - -int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeekForwardOnly) +int xdr_xtc_seek_time(real time, FILE* fp, XDR* xdrs, int natoms, gmx_bool bSeekForwardOnly) { float t; float dt; @@ -1434,7 +1415,7 @@ int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeek if (bSeekForwardOnly) { - low = gmx_ftell(fp)-header_size; + low = gmx_ftell(fp) - header_size; } if (gmx_fseek(fp, 0, SEEK_END)) { @@ -1446,9 +1427,9 @@ int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeek return -1; } /* round to int */ - high /= XDR_INT_SIZE; - high *= XDR_INT_SIZE; - offset = (((high-low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE; + high /= XDR_INT_SIZE; + high *= XDR_INT_SIZE; + offset = (((high - low) / 2) / XDR_INT_SIZE) * XDR_INT_SIZE; if (gmx_fseek(fp, offset, SEEK_SET)) { @@ -1457,8 +1438,8 @@ int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeek /* - * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in the loop - dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK); + * No need to call xdr_xtc_estimate_dt here - since xdr_xtc_estimate_dt is called first thing in + the loop dt = xdr_xtc_estimate_dt(fp, xdrs, natoms, &bOK); if (!bOK) { @@ -1504,12 +1485,12 @@ int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeek /* If we are before the target time and the time step is positive or 0, or we have after the target time and the time step is negative, or the difference between - the current time and the target time is bigger than dt and above all the distance between high - and low is bigger than 1 frame, then do another step of binary search. Otherwise stop and check - if we reached the solution */ - if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1)) || - ((t - time) >= dt && dt_sign >= 0) || ((time - t) >= -dt && dt_sign < 0)) && - (llabs(low - high) > header_size)) + the current time and the target time is bigger than dt and above all the distance between + high and low is bigger than 1 frame, then do another step of binary search. Otherwise + stop and check if we reached the solution */ + if ((((t < time && dt_sign >= 0) || (t > time && dt_sign == -1)) + || ((t - time) >= dt && dt_sign >= 0) || ((time - t) >= -dt && dt_sign < 0)) + && (llabs(low - high) > header_size)) { if (dt >= 0 && dt_sign != -1) { @@ -1585,11 +1566,10 @@ int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeek return 0; } -float -xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) +float xdr_xtc_get_last_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { - float time; - gmx_off_t off; + float time; + gmx_off_t off; *bOK = true; off = gmx_ftell(fp); if (off < 0) @@ -1598,7 +1578,7 @@ xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) return -1; } - if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END) != 0) + if (gmx_fseek(fp, -3 * XDR_INT_SIZE, SEEK_END) != 0) { *bOK = false; return -1; @@ -1619,11 +1599,10 @@ xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) } -int -xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) +int xdr_xtc_get_last_frame_number(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK) { - int frame; - gmx_off_t off; + int frame; + gmx_off_t off; *bOK = true; if ((off = gmx_ftell(fp)) < 0) @@ -1633,7 +1612,7 @@ xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK) } - if (gmx_fseek(fp, -3*XDR_INT_SIZE, SEEK_END)) + if (gmx_fseek(fp, -3 * XDR_INT_SIZE, SEEK_END)) { *bOK = false; return -1; diff --git a/src/gromacs/fileio/matio.cpp b/src/gromacs/fileio/matio.cpp index ed0e806714..dadcee08ab 100644 --- a/src/gromacs/fileio/matio.cpp +++ b/src/gromacs/fileio/matio.cpp @@ -60,27 +60,29 @@ using namespace gmx; -static const char mapper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?"; -#define NMAP static_cast(sizeof(mapper)/sizeof(mapper[0])) +static const char mapper[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/" + "?"; +#define NMAP static_cast(sizeof(mapper) / sizeof(mapper[0])) #define MAX_XPM_LINELENGTH 4096 -real **mk_matrix(int nx, int ny, gmx_bool b1D) +real** mk_matrix(int nx, int ny, gmx_bool b1D) { int i; - real **m; + real** m; snew(m, nx); if (b1D) { - snew(m[0], nx*ny); + snew(m[0], nx * ny); } for (i = 0; (i < nx); i++) { if (b1D) { - m[i] = &(m[0][i*ny]); + m[i] = &(m[0][i * ny]); } else { @@ -91,7 +93,7 @@ real **mk_matrix(int nx, int ny, gmx_bool b1D) return m; } -void done_matrix(int nx, real ***m) +void done_matrix(int nx, real*** m) { int i; @@ -111,13 +113,12 @@ static bool operator==(t_xpmelmt e1, t_xpmelmt e2) //! Return the index of the first element that matches \c c, or -1 if not found. t_matelmt searchcmap(ArrayRef map, t_xpmelmt c) { - auto findIt = std::find_if(map.begin(), map.end(), [&c](const auto &m) - { return (m.code == c); }); + auto findIt = std::find_if(map.begin(), map.end(), [&c](const auto& m) { return (m.code == c); }); return (findIt == map.end()) ? -1 : (findIt - map.begin()); } //! Read the mapping table from in, return number of entries -static std::vector getcmap(FILE *in, const char *fn) +static std::vector getcmap(FILE* in, const char* fn) { int i, n; char line[STRLEN]; @@ -125,19 +126,23 @@ static std::vector getcmap(FILE *in, const char *fn) double r, g, b; std::vector m; - if (fgets2(line, STRLEN-1, in) == nullptr) + if (fgets2(line, STRLEN - 1, in) == nullptr) { - gmx_fatal(FARGS, "Not enough lines in colormap file %s" - "(just wanted to read number of entries)", fn); + gmx_fatal(FARGS, + "Not enough lines in colormap file %s" + "(just wanted to read number of entries)", + fn); } sscanf(line, "%d", &n); m.resize(n); for (i = 0; (i < n); i++) { - if (fgets2(line, STRLEN-1, in) == nullptr) + if (fgets2(line, STRLEN - 1, in) == nullptr) { - gmx_fatal(FARGS, "Not enough lines in colormap file %s" - "(should be %d, found only %d)", fn, n+1, i); + gmx_fatal(FARGS, + "Not enough lines in colormap file %s" + "(should be %d, found only %d)", + fn, n + 1, i); } sscanf(line, "%s%s%lf%lf%lf", code, desc, &r, &g, &b); m[i].code.c1 = code[0]; @@ -151,42 +156,41 @@ static std::vector getcmap(FILE *in, const char *fn) return m; } -std::vector readcmap(const char *fn) +std::vector readcmap(const char* fn) { FilePtr in = openLibraryFile(fn); return getcmap(in.get(), fn); } -void printcmap(FILE *out, int n, t_mapping map[]) +void printcmap(FILE* out, int n, t_mapping map[]) { int i; fprintf(out, "%d\n", n); for (i = 0; (i < n); i++) { - fprintf(out, "%c%c %20s %10g %10g %10g\n", - map[i].code.c1 ? map[i].code.c1 : ' ', - map[i].code.c2 ? map[i].code.c2 : ' ', - map[i].desc, map[i].rgb.r, map[i].rgb.g, map[i].rgb.b); + fprintf(out, "%c%c %20s %10g %10g %10g\n", map[i].code.c1 ? map[i].code.c1 : ' ', + map[i].code.c2 ? map[i].code.c2 : ' ', map[i].desc, map[i].rgb.r, map[i].rgb.g, + map[i].rgb.b); } } -void writecmap(const char *fn, int n, t_mapping map[]) +void writecmap(const char* fn, int n, t_mapping map[]) { - FILE *out; + FILE* out; out = gmx_fio_fopen(fn, "w"); printcmap(out, n, map); gmx_fio_fclose(out); } -static char *fgetline(char **line, int llmax, int *llalloc, FILE *in) +static char* fgetline(char** line, int llmax, int* llalloc, FILE* in) { - char *fg; + char* fg; if (llmax > *llalloc) { - srenew(*line, llmax+1); + srenew(*line, llmax + 1); *llalloc = llmax; } fg = fgets(*line, llmax, in); @@ -195,7 +199,7 @@ static char *fgetline(char **line, int llmax, int *llalloc, FILE *in) return fg; } -static void skipstr(char *line) +static void skipstr(char* line) { int i, c; @@ -208,19 +212,19 @@ static void skipstr(char *line) i = c; while (line[c] != '\0') { - line[c-i] = line[c]; + line[c - i] = line[c]; c++; } - line[c-i] = '\0'; + line[c - i] = '\0'; } -static char *line2string(char **line) +static char* line2string(char** line) { int i; if (*line != nullptr) { - while (((*line)[0] != '\"' ) && ( (*line)[0] != '\0' )) + while (((*line)[0] != '\"') && ((*line)[0] != '\0')) { (*line)++; } @@ -232,7 +236,7 @@ static char *line2string(char **line) (*line)++; i = 0; - while (( (*line)[i] != '\"' ) && ( (*line)[i] != '\0' )) + while (((*line)[i] != '\"') && ((*line)[i] != '\0')) { i++; } @@ -251,8 +255,7 @@ static char *line2string(char **line) } //! If a label named \c label is found in \c line, return it. Otherwise return empty string. -static std::string findLabelInLine(const std::string &line, - const std::string &label) +static std::string findLabelInLine(const std::string& line, const std::string& label) { std::regex re(".*" + label + "\"(.*)\""); std::smatch match; @@ -264,28 +267,28 @@ static std::string findLabelInLine(const std::string &line, } //! Read and return a matrix from \c in -static t_matrix read_xpm_entry(FILE *in) +static t_matrix read_xpm_entry(FILE* in) { - char *line_buf = nullptr, *line = nullptr, *str, buf[256] = {0}; - int i, m, col_len, nch = 0, llmax; + char * line_buf = nullptr, *line = nullptr, *str, buf[256] = { 0 }; + int i, m, col_len, nch = 0, llmax; int llalloc = 0; unsigned int r, g, b; double u; gmx_bool bGetOnWithIt, bSetLine; t_xpmelmt c; - t_matrix mm; + t_matrix mm; llmax = STRLEN; - while ((nullptr != fgetline(&line_buf, llmax, &llalloc, in)) && - (std::strncmp(line_buf, "static", 6) != 0)) + while ((nullptr != fgetline(&line_buf, llmax, &llalloc, in)) + && (std::strncmp(line_buf, "static", 6) != 0)) { std::string lineString = line_buf; - mm.title = findLabelInLine(lineString, "title"); - mm.legend = findLabelInLine(lineString, "legend"); - mm.label_x = findLabelInLine(lineString, "x-label"); - mm.label_y = findLabelInLine(lineString, "y-label"); + mm.title = findLabelInLine(lineString, "title"); + mm.legend = findLabelInLine(lineString, "legend"); + mm.label_x = findLabelInLine(lineString, "x-label"); + mm.label_y = findLabelInLine(lineString, "y-label"); findLabelInLine(lineString, "type"); // discard the returned string } @@ -301,22 +304,22 @@ static t_matrix read_xpm_entry(FILE *in) if (debug) { - fprintf(debug, "%s %s %s %s\n", - mm.title.c_str(), mm.legend.c_str(), mm.label_x.c_str(), mm.label_y.c_str()); + fprintf(debug, "%s %s %s %s\n", mm.title.c_str(), mm.legend.c_str(), mm.label_x.c_str(), + mm.label_y.c_str()); } /* Read sizes */ - int nmap = 0; + int nmap = 0; bGetOnWithIt = FALSE; while (!bGetOnWithIt && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))) { line = line_buf; - while (( line[0] != '\"' ) && ( line[0] != '\0' )) + while ((line[0] != '\"') && (line[0] != '\0')) { line++; } - if (line[0] == '\"') + if (line[0] == '\"') { line2string(&line); sscanf(line, "%d %d %d %d", &(mm.nx), &(mm.ny), &nmap, &nch); @@ -328,14 +331,13 @@ static t_matrix read_xpm_entry(FILE *in) { gmx_fatal(FARGS, "Dimensions of xpm-file have to be larger than 0\n"); } - llmax = std::max(STRLEN, mm.nx+10); + llmax = std::max(STRLEN, mm.nx + 10); bGetOnWithIt = TRUE; } } if (debug) { - fprintf(debug, "mm.nx %d mm.ny %d nmap %d nch %d\n", - mm.nx, mm.ny, nmap, nch); + fprintf(debug, "mm.nx %d mm.ny %d nmap %d nch %d\n", mm.nx, mm.ny, nmap, nch); } if (nch == 0) { @@ -348,7 +350,7 @@ static t_matrix read_xpm_entry(FILE *in) while ((m < nmap) && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))) { line = std::strchr(line_buf, '\"'); - if (line) + if (line) { line++; /* Read xpm color map entry */ @@ -362,7 +364,7 @@ static t_matrix read_xpm_entry(FILE *in) mm.map[m].code.c2 = line[1]; } line += nch; - str = std::strchr(line, '#'); + str = std::strchr(line, '#'); if (str) { str++; @@ -374,16 +376,16 @@ static t_matrix read_xpm_entry(FILE *in) if (col_len == 6) { sscanf(line, "%*s #%2x%2x%2x", &r, &g, &b); - mm.map[m].rgb.r = r/255.0; - mm.map[m].rgb.g = g/255.0; - mm.map[m].rgb.b = b/255.0; + mm.map[m].rgb.r = r / 255.0; + mm.map[m].rgb.g = g / 255.0; + mm.map[m].rgb.b = b / 255.0; } else if (col_len == 12) { sscanf(line, "%*s #%4x%4x%4x", &r, &g, &b); - mm.map[m].rgb.r = r/65535.0; - mm.map[m].rgb.g = g/65535.0; - mm.map[m].rgb.b = b/65535.0; + mm.map[m].rgb.r = r / 65535.0; + mm.map[m].rgb.g = g / 65535.0; + mm.map[m].rgb.b = b / 65535.0; } else { @@ -413,13 +415,16 @@ static t_matrix read_xpm_entry(FILE *in) m++; } } - if (m != nmap) + if (m != nmap) { - gmx_fatal(FARGS, "Number of read colors map entries (%d) does not match the number in the header (%d)", m, nmap); + gmx_fatal(FARGS, + "Number of read colors map entries (%d) does not match the number in the header " + "(%d)", + m, nmap); } /* Read axes, if there are any */ - bSetLine = FALSE; + bSetLine = FALSE; do { if (bSetLine) @@ -467,13 +472,12 @@ static t_matrix read_xpm_entry(FILE *in) skipstr(line); } } - } - while ((line[0] != '\"') && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))); + } while ((line[0] != '\"') && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))); /* Read matrix */ mm.matrix.resize(mm.nx, mm.ny); int rowIndex = mm.ny - 1; - bSetLine = FALSE; + bSetLine = FALSE; do { if (bSetLine) @@ -481,9 +485,9 @@ static t_matrix read_xpm_entry(FILE *in) line = line_buf; } bSetLine = TRUE; - if (rowIndex%(1+mm.ny/100) == 0) + if (rowIndex % (1 + mm.ny / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (100*(mm.ny-rowIndex))/mm.ny); + fprintf(stderr, "%3d%%\b\b\b\b", (100 * (mm.ny - rowIndex)) / mm.ny); } while ((line[0] != '\"') && (line[0] != '\0')) { @@ -491,28 +495,27 @@ static t_matrix read_xpm_entry(FILE *in) } if (line[0] != '\"') { - gmx_fatal(FARGS, "Not enough characters in row %d of the matrix\n", rowIndex+1); + gmx_fatal(FARGS, "Not enough characters in row %d of the matrix\n", rowIndex + 1); } else { line++; for (i = 0; i < mm.nx; i++) { - c.c1 = line[nch*i]; + c.c1 = line[nch * i]; if (nch == 1) { c.c2 = 0; } else { - c.c2 = line[nch*i+1]; + c.c2 = line[nch * i + 1]; } mm.matrix(i, rowIndex) = searchcmap(mm.map, c); } rowIndex--; } - } - while ((rowIndex >= 0) && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))); + } while ((rowIndex >= 0) && (nullptr != fgetline(&line_buf, llmax, &llalloc, in))); if (rowIndex >= 0) { gmx_incons("Not enough rows in the matrix"); @@ -522,10 +525,10 @@ static t_matrix read_xpm_entry(FILE *in) return mm; } -std::vector read_xpm_matrix(const char *fnm) +std::vector read_xpm_matrix(const char* fnm) { - FILE *in; - char *line = nullptr; + FILE* in; + char* line = nullptr; int llalloc = 0; in = gmx_fio_fopen(fnm, "r"); @@ -550,9 +553,9 @@ std::vector read_xpm_matrix(const char *fnm) return mat; } -real **matrix2real(t_matrix *in, real **out) +real** matrix2real(t_matrix* in, real** out) { - double tmp; + double tmp; std::vector rmap(in->map.size()); @@ -560,7 +563,8 @@ real **matrix2real(t_matrix *in, real **out) { if ((in->map[i].desc == nullptr) || (sscanf(in->map[i].desc, "%lf", &tmp) != 1)) { - fprintf(stderr, "Could not convert matrix to reals,\n" + fprintf(stderr, + "Could not convert matrix to reals,\n" "color map entry %zd has a non-real description: \"%s\"\n", i, in->map[i].desc); return nullptr; @@ -584,23 +588,24 @@ real **matrix2real(t_matrix *in, real **out) } } - fprintf(stderr, "Converted a %dx%d matrix with %zu levels to reals\n", - in->nx, in->ny, in->map.size()); + fprintf(stderr, "Converted a %dx%d matrix with %zu levels to reals\n", in->nx, in->ny, in->map.size()); return out; } -static void write_xpm_header(FILE *out, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - gmx_bool bDiscrete) +static void write_xpm_header(FILE* out, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + gmx_bool bDiscrete) { - fprintf(out, "/* XPM */\n"); - fprintf(out, "/* This file can be converted to EPS by the GROMACS program xpm2ps */\n"); - fprintf(out, "/* title: \"%s\" */\n", title.c_str()); - fprintf(out, "/* legend: \"%s\" */\n", legend.c_str()); - fprintf(out, "/* x-label: \"%s\" */\n", label_x.c_str()); - fprintf(out, "/* y-label: \"%s\" */\n", label_y.c_str()); + fprintf(out, "/* XPM */\n"); + fprintf(out, "/* This file can be converted to EPS by the GROMACS program xpm2ps */\n"); + fprintf(out, "/* title: \"%s\" */\n", title.c_str()); + fprintf(out, "/* legend: \"%s\" */\n", legend.c_str()); + fprintf(out, "/* x-label: \"%s\" */\n", label_x.c_str()); + fprintf(out, "/* y-label: \"%s\" */\n", label_y.c_str()); if (bDiscrete) { fprintf(out, "/* type: \"Discrete\" */\n"); @@ -615,27 +620,24 @@ static int calc_nmid(int nlevels, real lo, real mid, real hi) { /* Take care that we have at least 1 entry in the mid to hi range */ - return std::min(std::max(0, static_cast(((mid-lo)/(hi-lo))*(nlevels-1))), - nlevels-1); + return std::min(std::max(0, static_cast(((mid - lo) / (hi - lo)) * (nlevels - 1))), nlevels - 1); } -static void write_xpm_map3(FILE *out, int n_x, int n_y, int *nlevels, - real lo, real mid, real hi, - t_rgb rlo, t_rgb rmid, t_rgb rhi) +static void +write_xpm_map3(FILE* out, int n_x, int n_y, int* nlevels, real lo, real mid, real hi, t_rgb rlo, t_rgb rmid, t_rgb rhi) { int i, nmid; double r, g, b, clev_lo, clev_hi; - if (*nlevels > NMAP*NMAP) + if (*nlevels > NMAP * NMAP) { - fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", - *nlevels, static_cast(NMAP*NMAP)); - *nlevels = NMAP*NMAP; + fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", *nlevels, + static_cast(NMAP * NMAP)); + *nlevels = NMAP * NMAP; } else if (*nlevels < 2) { - fprintf(stderr, "Warning, too few levels (%d) in matrix, using 2 instead\n", - *nlevels); + fprintf(stderr, "Warning, too few levels (%d) in matrix, using 2 instead\n", *nlevels); *nlevels = 2; } if (!((mid >= lo) && (mid < hi))) @@ -644,65 +646,58 @@ static void write_xpm_map3(FILE *out, int n_x, int n_y, int *nlevels, } fprintf(out, "static char *gromacs_xpm[] = {\n"); - fprintf(out, "\"%d %d %d %d\",\n", - n_x, n_y, *nlevels, (*nlevels <= NMAP) ? 1 : 2); + fprintf(out, "\"%d %d %d %d\",\n", n_x, n_y, *nlevels, (*nlevels <= NMAP) ? 1 : 2); nmid = calc_nmid(*nlevels, lo, mid, hi); clev_lo = nmid; clev_hi = (*nlevels - 1 - nmid); for (i = 0; (i < nmid); i++) { - r = rlo.r+(i*(rmid.r-rlo.r)/clev_lo); - g = rlo.g+(i*(rmid.g-rlo.g)/clev_lo); - b = rlo.b+(i*(rmid.b-rlo.b)/clev_lo); - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", - mapper[i % NMAP], - (*nlevels <= NMAP) ? ' ' : mapper[i/NMAP], - static_cast(std::round(255*r)), - static_cast(std::round(255*g)), - static_cast(std::round(255*b)), - ((nmid - i)*lo + i*mid)/clev_lo); + r = rlo.r + (i * (rmid.r - rlo.r) / clev_lo); + g = rlo.g + (i * (rmid.g - rlo.g) / clev_lo); + b = rlo.b + (i * (rmid.b - rlo.b) / clev_lo); + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[i % NMAP], + (*nlevels <= NMAP) ? ' ' : mapper[i / NMAP], + static_cast(std::round(255 * r)), + static_cast(std::round(255 * g)), + static_cast(std::round(255 * b)), ((nmid - i) * lo + i * mid) / clev_lo); } - for (i = 0; (i < (*nlevels-nmid)); i++) + for (i = 0; (i < (*nlevels - nmid)); i++) { - r = rmid.r+(i*(rhi.r-rmid.r)/clev_hi); - g = rmid.g+(i*(rhi.g-rmid.g)/clev_hi); - b = rmid.b+(i*(rhi.b-rmid.b)/clev_hi); - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", - mapper[(i+nmid) % NMAP], - (*nlevels <= NMAP) ? ' ' : mapper[(i+nmid)/NMAP], - static_cast(std::round(255*r)), - static_cast(std::round(255*g)), - static_cast(std::round(255*b)), - ((*nlevels - 1 - nmid - i)*mid + i*hi)/clev_hi); + r = rmid.r + (i * (rhi.r - rmid.r) / clev_hi); + g = rmid.g + (i * (rhi.g - rmid.g) / clev_hi); + b = rmid.b + (i * (rhi.b - rmid.b) / clev_hi); + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[(i + nmid) % NMAP], + (*nlevels <= NMAP) ? ' ' : mapper[(i + nmid) / NMAP], + static_cast(std::round(255 * r)), + static_cast(std::round(255 * g)), + static_cast(std::round(255 * b)), + ((*nlevels - 1 - nmid - i) * mid + i * hi) / clev_hi); } } -static void pr_simple_cmap(FILE *out, real lo, real hi, int nlevel, t_rgb rlo, - t_rgb rhi, int i0) +static void pr_simple_cmap(FILE* out, real lo, real hi, int nlevel, t_rgb rlo, t_rgb rhi, int i0) { - int i; - real r, g, b, fac; + int i; + real r, g, b, fac; for (i = 0; (i < nlevel); i++) { - fac = (i+1.0)/(nlevel); - r = rlo.r+fac*(rhi.r-rlo.r); - g = rlo.g+fac*(rhi.g-rlo.g); - b = rlo.b+fac*(rhi.b-rlo.b); - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", - mapper[(i+i0) % NMAP], - (nlevel <= NMAP) ? ' ' : mapper[(i+i0)/NMAP], - static_cast(std::round(255*r)), - static_cast(std::round(255*g)), - static_cast(std::round(255*b)), - lo+fac*(hi-lo)); + fac = (i + 1.0) / (nlevel); + r = rlo.r + fac * (rhi.r - rlo.r); + g = rlo.g + fac * (rhi.g - rlo.g); + b = rlo.b + fac * (rhi.b - rlo.b); + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[(i + i0) % NMAP], + (nlevel <= NMAP) ? ' ' : mapper[(i + i0) / NMAP], + static_cast(std::round(255 * r)), + static_cast(std::round(255 * g)), + static_cast(std::round(255 * b)), lo + fac * (hi - lo)); } } -static void pr_discrete_cmap(FILE *out, int *nlevel, int i0) +static void pr_discrete_cmap(FILE* out, int* nlevel, int i0) { - t_rgb rgbd[16] = { + t_rgb rgbd[16] = { { 1.0, 1.0, 1.0 }, /* white */ { 1.0, 0.0, 0.0 }, /* red */ { 1.0, 1.0, 0.0 }, /* yellow */ @@ -721,32 +716,37 @@ static void pr_discrete_cmap(FILE *out, int *nlevel, int i0) { 0.0, 0.0, 0.0 } /* black */ }; - int i, n; + int i, n; *nlevel = std::min(16, *nlevel); n = *nlevel; for (i = 0; (i < n); i++) { - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n", - mapper[(i+i0) % NMAP], - (n <= NMAP) ? ' ' : mapper[(i+i0)/NMAP], - static_cast(round(255*rgbd[i].r)), - static_cast(round(255*rgbd[i].g)), - static_cast(round(255*rgbd[i].b)), - i); + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%3d\" */,\n", mapper[(i + i0) % NMAP], + (n <= NMAP) ? ' ' : mapper[(i + i0) / NMAP], + static_cast(round(255 * rgbd[i].r)), + static_cast(round(255 * rgbd[i].g)), + static_cast(round(255 * rgbd[i].b)), i); } } - -static void write_xpm_map_split(FILE *out, int n_x, int n_y, - const int *nlevel_top, real lo_top, real hi_top, - t_rgb rlo_top, t_rgb rhi_top, - gmx_bool bDiscreteColor, - int *nlevel_bot, real lo_bot, real hi_bot, - t_rgb rlo_bot, t_rgb rhi_bot) +static void write_xpm_map_split(FILE* out, + int n_x, + int n_y, + const int* nlevel_top, + real lo_top, + real hi_top, + t_rgb rlo_top, + t_rgb rhi_top, + gmx_bool bDiscreteColor, + int* nlevel_bot, + real lo_bot, + real hi_bot, + t_rgb rlo_bot, + t_rgb rhi_bot) { - int ntot; + int ntot; ntot = *nlevel_top + *nlevel_bot; if (ntot > NMAP) @@ -770,17 +770,16 @@ static void write_xpm_map_split(FILE *out, int n_x, int n_y, } -static void write_xpm_map(FILE *out, int n_x, int n_y, int *nlevels, - real lo, real hi, t_rgb rlo, t_rgb rhi) +static void write_xpm_map(FILE* out, int n_x, int n_y, int* nlevels, real lo, real hi, t_rgb rlo, t_rgb rhi) { - int i, nlo; - real invlevel, r, g, b; + int i, nlo; + real invlevel, r, g, b; - if (*nlevels > NMAP*NMAP) + if (*nlevels > NMAP * NMAP) { - fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", - *nlevels, static_cast(NMAP*NMAP)); - *nlevels = NMAP*NMAP; + fprintf(stderr, "Warning, too many levels (%d) in matrix, using %d only\n", *nlevels, + static_cast(NMAP * NMAP)); + *nlevels = NMAP * NMAP; } else if (*nlevels < 2) { @@ -789,27 +788,24 @@ static void write_xpm_map(FILE *out, int n_x, int n_y, int *nlevels, } fprintf(out, "static char *gromacs_xpm[] = {\n"); - fprintf(out, "\"%d %d %d %d\",\n", - n_x, n_y, *nlevels, (*nlevels <= NMAP) ? 1 : 2); + fprintf(out, "\"%d %d %d %d\",\n", n_x, n_y, *nlevels, (*nlevels <= NMAP) ? 1 : 2); - invlevel = 1.0/(*nlevels-1); + invlevel = 1.0 / (*nlevels - 1); for (i = 0; (i < *nlevels); i++) { - nlo = *nlevels-1-i; - r = (nlo*rlo.r+i*rhi.r)*invlevel; - g = (nlo*rlo.g+i*rhi.g)*invlevel; - b = (nlo*rlo.b+i*rhi.b)*invlevel; - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", - mapper[i % NMAP], (*nlevels <= NMAP) ? ' ' : mapper[i/NMAP], - static_cast(std::round(255*r)), - static_cast(std::round(255*g)), - static_cast(std::round(255*b)), - (nlo*lo+i*hi)*invlevel); + nlo = *nlevels - 1 - i; + r = (nlo * rlo.r + i * rhi.r) * invlevel; + g = (nlo * rlo.g + i * rhi.g) * invlevel; + b = (nlo * rlo.b + i * rhi.b) * invlevel; + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%.3g\" */,\n", mapper[i % NMAP], + (*nlevels <= NMAP) ? ' ' : mapper[i / NMAP], + static_cast(std::round(255 * r)), + static_cast(std::round(255 * g)), + static_cast(std::round(255 * b)), (nlo * lo + i * hi) * invlevel); } } -static void writeXpmAxis(FILE *out, const char *axis, - ArrayRef label) +static void writeXpmAxis(FILE* out, const char* axis, ArrayRef label) { if (label.empty()) { @@ -830,30 +826,29 @@ static void writeXpmAxis(FILE *out, const char *axis, fprintf(out, "*/\n"); } -static void write_xpm_data(FILE *out, int n_x, int n_y, real **mat, - real lo, real hi, int nlevels) +static void write_xpm_data(FILE* out, int n_x, int n_y, real** mat, real lo, real hi, int nlevels) { int i, j, c; real invlevel; - invlevel = (nlevels-1)/(hi-lo); - for (j = n_y-1; (j >= 0); j--) + invlevel = (nlevels - 1) / (hi - lo); + for (j = n_y - 1; (j >= 0); j--) { - if (j%(1+n_y/100) == 0) + if (j % (1 + n_y / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (100*(n_y-j))/n_y); + fprintf(stderr, "%3d%%\b\b\b\b", (100 * (n_y - j)) / n_y); } fprintf(out, "\""); for (i = 0; (i < n_x); i++) { - c = roundToInt((mat[i][j]-lo)*invlevel); + c = roundToInt((mat[i][j] - lo) * invlevel); if (c < 0) { c = 0; } if (c >= nlevels) { - c = nlevels-1; + c = nlevels - 1; } if (nlevels <= NMAP) { @@ -875,32 +870,31 @@ static void write_xpm_data(FILE *out, int n_x, int n_y, real **mat, } } -static void write_xpm_data3(FILE *out, int n_x, int n_y, real **mat, - real lo, real mid, real hi, int nlevels) +static void write_xpm_data3(FILE* out, int n_x, int n_y, real** mat, real lo, real mid, real hi, int nlevels) { int i, j, c = 0, nmid; real invlev_lo, invlev_hi; nmid = calc_nmid(nlevels, lo, mid, hi); - invlev_hi = (nlevels-1-nmid)/(hi-mid); - invlev_lo = (nmid)/(mid-lo); + invlev_hi = (nlevels - 1 - nmid) / (hi - mid); + invlev_lo = (nmid) / (mid - lo); - for (j = n_y-1; (j >= 0); j--) + for (j = n_y - 1; (j >= 0); j--) { - if (j%(1+n_y/100) == 0) + if (j % (1 + n_y / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (100*(n_y-j))/n_y); + fprintf(stderr, "%3d%%\b\b\b\b", (100 * (n_y - j)) / n_y); } fprintf(out, "\""); for (i = 0; (i < n_x); i++) { if (mat[i][j] >= mid) { - c = nmid+roundToInt((mat[i][j]-mid)*invlev_hi); + c = nmid + roundToInt((mat[i][j] - mid) * invlev_hi); } else if (mat[i][j] >= lo) { - c = roundToInt((mat[i][j]-lo)*invlev_lo); + c = roundToInt((mat[i][j] - lo) * invlev_lo); } else { @@ -913,7 +907,7 @@ static void write_xpm_data3(FILE *out, int n_x, int n_y, real **mat, } if (c >= nlevels) { - c = nlevels-1; + c = nlevels - 1; } if (nlevels <= NMAP) { @@ -935,39 +929,52 @@ static void write_xpm_data3(FILE *out, int n_x, int n_y, real **mat, } } -static void write_xpm_data_split(FILE *out, int n_x, int n_y, real **mat, - real lo_top, real hi_top, int nlevel_top, - real lo_bot, real hi_bot, int nlevel_bot) +static void write_xpm_data_split(FILE* out, + int n_x, + int n_y, + real** mat, + real lo_top, + real hi_top, + int nlevel_top, + real lo_bot, + real hi_bot, + int nlevel_bot) { int i, j, c; real invlev_top, invlev_bot; - invlev_top = (nlevel_top-1)/(hi_top-lo_top); - invlev_bot = (nlevel_bot-1)/(hi_bot-lo_bot); + invlev_top = (nlevel_top - 1) / (hi_top - lo_top); + invlev_bot = (nlevel_bot - 1) / (hi_bot - lo_bot); - for (j = n_y-1; (j >= 0); j--) + for (j = n_y - 1; (j >= 0); j--) { - if (j % (1+n_y/100) == 0) + if (j % (1 + n_y / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (100*(n_y-j))/n_y); + fprintf(stderr, "%3d%%\b\b\b\b", (100 * (n_y - j)) / n_y); } fprintf(out, "\""); for (i = 0; (i < n_x); i++) { if (i < j) { - c = nlevel_bot+roundToInt((mat[i][j]-lo_top)*invlev_top); - if ((c < nlevel_bot) || (c >= nlevel_bot+nlevel_top)) + c = nlevel_bot + roundToInt((mat[i][j] - lo_top) * invlev_top); + if ((c < nlevel_bot) || (c >= nlevel_bot + nlevel_top)) { - gmx_fatal(FARGS, "Range checking i = %d, j = %d, c = %d, bot = %d, top = %d matrix[i,j] = %f", i, j, c, nlevel_bot, nlevel_top, mat[i][j]); + gmx_fatal(FARGS, + "Range checking i = %d, j = %d, c = %d, bot = %d, top = %d " + "matrix[i,j] = %f", + i, j, c, nlevel_bot, nlevel_top, mat[i][j]); } } else if (i > j) { - c = roundToInt((mat[i][j]-lo_bot)*invlev_bot); - if ((c < 0) || (c >= nlevel_bot+nlevel_bot)) + c = roundToInt((mat[i][j] - lo_bot) * invlev_bot); + if ((c < 0) || (c >= nlevel_bot + nlevel_bot)) { - gmx_fatal(FARGS, "Range checking i = %d, j = %d, c = %d, bot = %d, top = %d matrix[i,j] = %f", i, j, c, nlevel_bot, nlevel_top, mat[i][j]); + gmx_fatal(FARGS, + "Range checking i = %d, j = %d, c = %d, bot = %d, top = %d " + "matrix[i,j] = %f", + i, j, c, nlevel_bot, nlevel_top, mat[i][j]); } } else @@ -988,32 +995,29 @@ static void write_xpm_data_split(FILE *out, int n_x, int n_y, real **mat, } } -void write_xpm_m(FILE *out, t_matrix m) +void write_xpm_m(FILE* out, t_matrix m) { - gmx_bool bOneChar; - t_xpmelmt c; + gmx_bool bOneChar; + t_xpmelmt c; bOneChar = (m.map[0].code.c2 == 0); - write_xpm_header(out, m.title, m.legend, m.label_x, m.label_y, - m.bDiscrete); + write_xpm_header(out, m.title, m.legend, m.label_x, m.label_y, m.bDiscrete); fprintf(out, "static char *gromacs_xpm[] = {\n"); fprintf(out, "\"%d %d %zu %d\",\n", m.nx, m.ny, m.map.size(), bOneChar ? 1 : 2); - for (const auto &map : m.map) + for (const auto& map : m.map) { - fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n", - map.code.c1, - bOneChar ? ' ' : map.code.c2, - static_cast(round(map.rgb.r*255)), - static_cast(round(map.rgb.g*255)), - static_cast(round(map.rgb.b*255)), map.desc); + fprintf(out, "\"%c%c c #%02X%02X%02X \" /* \"%s\" */,\n", map.code.c1, + bOneChar ? ' ' : map.code.c2, static_cast(round(map.rgb.r * 255)), + static_cast(round(map.rgb.g * 255)), + static_cast(round(map.rgb.b * 255)), map.desc); } writeXpmAxis(out, "x", m.axis_x); writeXpmAxis(out, "y", m.axis_y); - for (int j = m.ny-1; (j >= 0); j--) + for (int j = m.ny - 1; (j >= 0); j--) { - if (j%(1+m.ny/100) == 0) + if (j % (1 + m.ny / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (100*(m.ny-j))/m.ny); + fprintf(stderr, "%3d%%\b\b\b\b", (100 * (m.ny - j)) / m.ny); } fprintf(out, "\""); if (bOneChar) @@ -1042,12 +1046,24 @@ void write_xpm_m(FILE *out, t_matrix m) } } -void write_xpm3(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real axis_x[], real axis_y[], - real *mat[], real lo, real mid, real hi, - t_rgb rlo, t_rgb rmid, t_rgb rhi, int *nlevels) +void write_xpm3(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real axis_x[], + real axis_y[], + real* mat[], + real lo, + real mid, + real hi, + t_rgb rlo, + t_rgb rmid, + t_rgb rhi, + int* nlevels) { /* See write_xpm. * Writes a colormap varying as rlo -> rmid -> rhi. @@ -1065,16 +1081,28 @@ void write_xpm3(FILE *out, unsigned int flags, write_xpm_data3(out, n_x, n_y, mat, lo, mid, hi, *nlevels); } -void write_xpm_split(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real axis_x[], real axis_y[], - real *mat[], - real lo_top, real hi_top, int *nlevel_top, - t_rgb rlo_top, t_rgb rhi_top, - real lo_bot, real hi_bot, int *nlevel_bot, - gmx_bool bDiscreteColor, - t_rgb rlo_bot, t_rgb rhi_bot) +void write_xpm_split(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real axis_x[], + real axis_y[], + real* mat[], + real lo_top, + real hi_top, + int* nlevel_top, + t_rgb rlo_top, + t_rgb rhi_top, + real lo_bot, + real hi_bot, + int* nlevel_bot, + gmx_bool bDiscreteColor, + t_rgb rlo_bot, + t_rgb rhi_bot) { /* See write_xpm. * Writes a colormap varying as rlo -> rmid -> rhi. @@ -1094,20 +1122,29 @@ void write_xpm_split(FILE *out, unsigned int flags, } write_xpm_header(out, title, legend, label_x, label_y, FALSE); - write_xpm_map_split(out, n_x, n_y, nlevel_top, lo_top, hi_top, rlo_top, rhi_top, - bDiscreteColor, nlevel_bot, lo_bot, hi_bot, rlo_bot, rhi_bot); + write_xpm_map_split(out, n_x, n_y, nlevel_top, lo_top, hi_top, rlo_top, rhi_top, bDiscreteColor, + nlevel_bot, lo_bot, hi_bot, rlo_bot, rhi_bot); writeXpmAxis(out, "x", ArrayRef(axis_x, axis_x + n_x + ((flags & MAT_SPATIAL_X) != 0U ? 1 : 0))); writeXpmAxis(out, "y", ArrayRef(axis_y, axis_y + n_y + ((flags & MAT_SPATIAL_Y) != 0U ? 1 : 0))); - write_xpm_data_split(out, n_x, n_y, mat, lo_top, hi_top, *nlevel_top, - lo_bot, hi_bot, *nlevel_bot); + write_xpm_data_split(out, n_x, n_y, mat, lo_top, hi_top, *nlevel_top, lo_bot, hi_bot, *nlevel_bot); } -void write_xpm(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real axis_x[], real axis_y[], - real *mat[], real lo, real hi, - t_rgb rlo, t_rgb rhi, int *nlevels) +void write_xpm(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real axis_x[], + real axis_y[], + real* mat[], + real lo, + real hi, + t_rgb rlo, + t_rgb rhi, + int* nlevels) { /* out xpm file * title matrix title diff --git a/src/gromacs/fileio/matio.h b/src/gromacs/fileio/matio.h index 5de0335b2f..5c094fedf3 100644 --- a/src/gromacs/fileio/matio.h +++ b/src/gromacs/fileio/matio.h @@ -69,23 +69,24 @@ typedef short t_matelmt; struct t_mapping { //! XPM element code - t_xpmelmt code; + t_xpmelmt code; //! Description - const char *desc = nullptr; + const char* desc = nullptr; //! RGB color - t_rgb rgb; + t_rgb rgb; }; -#define MAT_SPATIAL_X (1<<0) -#define MAT_SPATIAL_Y (1<<1) +#define MAT_SPATIAL_X (1 << 0) +#define MAT_SPATIAL_Y (1 << 1) /* Defines if x and y are spatial dimensions, * when not, there are n axis ticks at the middle of the elements, * when set, there are n+1 axis ticks at the edges of the elements. */ //! Convenience typedef -template -using DynamicMatrix2D = gmx::MultiDimArray < std::vector, gmx::extents < gmx::dynamic_extent, gmx::dynamic_extent>>; +template +using DynamicMatrix2D = + gmx::MultiDimArray, gmx::extents>; /*! \brief A matrix of integers, plus supporting values, such as used in XPM output * @@ -97,86 +98,120 @@ using DynamicMatrix2D = gmx::MultiDimArray < std::vector, gmx::extents < gmx: struct t_matrix { //! Defines if x and y are spatial dimensions. See comments on MAT_*. - unsigned int flags = 0; + unsigned int flags = 0; //! Size of the matrix in x - int nx = 0; + int nx = 0; //! Size of the matrix in y - int ny = 0; + int ny = 0; //! Matrix title - std::string title; + std::string title; //! Label for the continuous legend - std::string legend; + std::string legend; //! Label for the x-axis - std::string label_x; + std::string label_x; //! Label for the y-axis - std::string label_y; + std::string label_y; //! Whether the quantity described is discrete or continuous. - bool bDiscrete = false; + bool bDiscrete = false; //! The x-ticklabels - std::vector axis_x; + std::vector axis_x; //! The y-ticklabels - std::vector axis_y; + std::vector axis_y; //! Element x,y is matrix(x, y) DynamicMatrix2D matrix; //! Color levels for the output(?) - std::vector map; + std::vector map; }; //! Seach in the \c map for code \c c and return its entry, or -1 if not found. t_matelmt searchcmap(gmx::ArrayRef map, t_xpmelmt c); //! Read the mapping table from fn, return number of entries -std::vector readcmap(const char *fn); +std::vector readcmap(const char* fn); -void printcmap(FILE *out, int n, t_mapping map[]); +void printcmap(FILE* out, int n, t_mapping map[]); /* print mapping table to out */ -void writecmap(const char *fn, int n, t_mapping map[]); +void writecmap(const char* fn, int n, t_mapping map[]); /* print mapping table to fn */ //! Reads and returns a number of matrices from .xpm file \c fnm. -std::vector read_xpm_matrix(const char *fnm); +std::vector read_xpm_matrix(const char* fnm); -real **matrix2real(t_matrix *in, real **out); +real** matrix2real(t_matrix* in, real** out); /* Converts an matrix in a t_matrix struct to a matrix of reals * When mat==NULL memory will be allocated * Returns NULL when something went wrong */ -void write_xpm_m(FILE *out, t_matrix m); +void write_xpm_m(FILE* out, t_matrix m); /* Writes a t_matrix struct to .xpm file */ -void write_xpm3(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real axis_x[], real axis_y[], - real *mat[], real lo, real mid, real hi, - t_rgb rlo, t_rgb rmid, t_rgb rhi, int *nlevels); +void write_xpm3(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real axis_x[], + real axis_y[], + real* mat[], + real lo, + real mid, + real hi, + t_rgb rlo, + t_rgb rmid, + t_rgb rhi, + int* nlevels); /* See write_xpm. * Writes a colormap varying as rlo -> rmid -> rhi. */ -void write_xpm_split(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real axis_x[], real axis_y[], - real *mat[], - real lo_top, real hi_top, int *nlevel_top, - t_rgb rlo_top, t_rgb rhi_top, - real lo_bot, real hi_bot, int *nlevel_bot, - gmx_bool bDiscreteColor, - t_rgb rlo_bot, t_rgb rhi_bot); +void write_xpm_split(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real axis_x[], + real axis_y[], + real* mat[], + real lo_top, + real hi_top, + int* nlevel_top, + t_rgb rlo_top, + t_rgb rhi_top, + real lo_bot, + real hi_bot, + int* nlevel_bot, + gmx_bool bDiscreteColor, + t_rgb rlo_bot, + t_rgb rhi_bot); /* See write_xpm. * Writes a colormap with separate above and below diagonal colormaps. * If bDiscrete then a colormap with 16 fixed colors is used, first of * which is white. */ -void write_xpm(FILE *out, unsigned int flags, - const std::string &title, const std::string &legend, - const std::string &label_x, const std::string &label_y, - int n_x, int n_y, real t_x[], real t_y[], - real *mat[], real lo, real hi, - t_rgb rlo, t_rgb rhi, int *nlevels); +void write_xpm(FILE* out, + unsigned int flags, + const std::string& title, + const std::string& legend, + const std::string& label_x, + const std::string& label_y, + int n_x, + int n_y, + real t_x[], + real t_y[], + real* mat[], + real lo, + real hi, + t_rgb rlo, + t_rgb rhi, + int* nlevels); /* out xpm file * flags flags, defined types/matrix.h * MAT_SPATIAL_X @@ -199,8 +234,8 @@ void write_xpm(FILE *out, unsigned int flags, * nlevels number of color levels for the output */ -real **mk_matrix(int nx, int ny, gmx_bool b1D); +real** mk_matrix(int nx, int ny, gmx_bool b1D); -void done_matrix(int nx, real ***m); +void done_matrix(int nx, real*** m); -#endif /* GMX_FILEIO_MATIO_H */ +#endif /* GMX_FILEIO_MATIO_H */ diff --git a/src/gromacs/fileio/md5.cpp b/src/gromacs/fileio/md5.cpp index 5ea29bff63..e39ce730b8 100644 --- a/src/gromacs/fileio/md5.cpp +++ b/src/gromacs/fileio/md5.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,9 +43,9 @@ #include #if GMX_INTEGER_BIG_ENDIAN -#define ARCH_IS_BIG_ENDIAN 1 +# define ARCH_IS_BIG_ENDIAN 1 #else -#define ARCH_IS_BIG_ENDIAN 0 +# define ARCH_IS_BIG_ENDIAN 0 #endif /* @@ -102,86 +102,83 @@ #include "md5.h" -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else -# define BYTE_ORDER 0 +# define BYTE_ORDER 0 #endif #define T_MASK (static_cast(~0)) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db +#define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a +#define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 +#define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 +#define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 +#define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 +#define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 +#define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 +#define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed +#define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 +#define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 +#define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 +#define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 +#define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 +#define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 +#define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 +#define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 +#define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f +#define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 +#define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb +#define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/) { - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ @@ -189,7 +186,7 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; - const md5_word_t *X; + const md5_word_t* X; #endif { @@ -201,18 +198,18 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) */ static const int w = 1; - if (*(reinterpret_cast(&w))) /* dynamic little-endian */ + if (*(reinterpret_cast(&w))) /* dynamic little-endian */ #endif -#if BYTE_ORDER <= 0 /* little-endian */ +#if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ - if (!((data - reinterpret_cast(0)) & 3)) + if (!((data - reinterpret_cast(0)) & 3)) { /* data are properly aligned */ - X = reinterpret_cast(data); + X = reinterpret_cast(data); } else { @@ -223,7 +220,7 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) } #endif #if BYTE_ORDER == 0 - else /* dynamic big-endian */ + else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { @@ -231,14 +228,14 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) * On big-endian machines, we must arrange the bytes in the * right order. */ - const md5_byte_t *xp = data; + const md5_byte_t* xp = data; int i; -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif for (i = 0; i < 16; ++i, xp += 4) { xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); @@ -253,23 +250,23 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti) \ +#define SET(a, b, c, d, k, s, Ti) \ t = (a) + F(b, c, d) + X[k] + (Ti); \ (a) = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); + SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); @@ -279,25 +276,25 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti) \ +#define SET(a, b, c, d, k, s, Ti) \ t = (a) + G(b, c, d) + X[k] + (Ti); \ (a) = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET @@ -305,52 +302,52 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti) \ +#define SET(a, b, c, d, k, s, Ti) \ t = (a) + H(b, c, d) + X[k] + (Ti); \ (a) = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); + SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti) \ +#define SET(a, b, c, d, k, s, Ti) \ t = (a) + I(b, c, d) + X[k] + (Ti); \ (a) = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); + SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); + SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each @@ -362,23 +359,21 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) pms->abcd[3] += d; } -void -gmx_md5_init(md5_state_t *pms) +void gmx_md5_init(md5_state_t* pms) { pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; } -void -gmx_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +void gmx_md5_append(md5_state_t* pms, const md5_byte_t* data, int nbytes) { - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = static_cast(nbytes << 3); + const md5_byte_t* p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = static_cast(nbytes << 3); if (nbytes <= 0) { @@ -403,7 +398,7 @@ gmx_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { return; } - p += copy; + p += copy; left -= copy; md5_process(pms, pms->buf); } @@ -421,16 +416,14 @@ gmx_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) } } -std::array gmx_md5_finish(md5_state_t *pms) +std::array gmx_md5_finish(md5_state_t* pms) { - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; + static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + md5_byte_t data[8]; + int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) diff --git a/src/gromacs/fileio/md5.h b/src/gromacs/fileio/md5.h index 0f6a5a8b7a..c7e94e1205 100644 --- a/src/gromacs/fileio/md5.h +++ b/src/gromacs/fileio/md5.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -85,7 +85,7 @@ */ #ifndef GMX_md5_INCLUDED -# define GMX_md5_INCLUDED +#define GMX_md5_INCLUDED #include @@ -100,22 +100,23 @@ */ typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ +typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ +typedef struct md5_state_s +{ + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; /* Initialize the algorithm. */ -void gmx_md5_init(md5_state_t *pms); +void gmx_md5_init(md5_state_t* pms); /* Append a string to the message. */ -void gmx_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); +void gmx_md5_append(md5_state_t* pms, const md5_byte_t* data, int nbytes); /* Finish the message and return the digest. */ -std::array gmx_md5_finish(md5_state_t *pms); +std::array gmx_md5_finish(md5_state_t* pms); #endif diff --git a/src/gromacs/fileio/mrcdensitymap.cpp b/src/gromacs/fileio/mrcdensitymap.cpp index 0e251ee4e9..3104463806 100644 --- a/src/gromacs/fileio/mrcdensitymap.cpp +++ b/src/gromacs/fileio/mrcdensitymap.cpp @@ -70,13 +70,13 @@ namespace * \throws FileIOError if file not found * \throws FileIOError if reading was not successful */ -std::vector readCharBufferFromFile(const std::string &filename) +std::vector readCharBufferFromFile(const std::string& filename) { if (!gmx_fexist(filename)) { GMX_THROW(FileIOError("Error while reading '" + filename + "' - file not found.")); } - t_fileio *mrcFile = gmx_fio_open(filename.c_str(), "r"); + t_fileio* mrcFile = gmx_fio_open(filename.c_str(), "r"); // Determine file size gmx_fseek(gmx_fio_getfp(mrcFile), 0, SEEK_END); @@ -84,18 +84,20 @@ std::vector readCharBufferFromFile(const std::string &filename) gmx_fseek(gmx_fio_getfp(mrcFile), 0, SEEK_SET); // Read whole file into buffer the size of the file std::vector fileContentBuffer(fileSize); - size_t readSize = fread(fileContentBuffer.data(), sizeof(char), fileContentBuffer.size(), gmx_fio_getfp(mrcFile)); + size_t readSize = fread(fileContentBuffer.data(), sizeof(char), fileContentBuffer.size(), + gmx_fio_getfp(mrcFile)); gmx_fio_close(mrcFile); if (fileContentBuffer.size() != readSize) { - GMX_THROW(FileIOError("Error while reading '" + filename + "' - file size and read buffer size do not match.")); + GMX_THROW(FileIOError("Error while reading '" + filename + + "' - file size and read buffer size do not match.")); } return fileContentBuffer; } -} // namespace +} // namespace /******************************************************************** * MrcDensityMapOfFloatReader::Impl @@ -106,27 +108,27 @@ std::vector readCharBufferFromFile(const std::string &filename) */ class MrcDensityMapOfFloatReader::Impl { - public: - //! Build the map reader from a serializer. - explicit Impl(ISerializer *serializer); - ~Impl() {} - //! The header of the read mrc file - MrcDensityMapHeader header_; - //! The data of the mrc file - std::vector data_; +public: + //! Build the map reader from a serializer. + explicit Impl(ISerializer* serializer); + ~Impl() {} + //! The header of the read mrc file + MrcDensityMapHeader header_; + //! The data of the mrc file + std::vector data_; }; -MrcDensityMapOfFloatReader::Impl::Impl(ISerializer *serializer) +MrcDensityMapOfFloatReader::Impl::Impl(ISerializer* serializer) { if (!serializer->reading()) { GMX_THROW(InternalError("Cannot use writing serializer to read.")); } - header_ = deserializeMrcDensityMapHeader(serializer); + header_ = deserializeMrcDensityMapHeader(serializer); const auto dataSize = numberOfExpectedDataItems(header_); data_.resize(dataSize); - for (auto &value : data_) + for (auto& value : data_) { serializer->doFloat(&value); } @@ -136,7 +138,8 @@ MrcDensityMapOfFloatReader::Impl::Impl(ISerializer *serializer) * MrcDensityMapOfFloatReader */ -MrcDensityMapOfFloatReader::MrcDensityMapOfFloatReader(ISerializer *serializer) : impl_(new Impl(serializer)) +MrcDensityMapOfFloatReader::MrcDensityMapOfFloatReader(ISerializer* serializer) : + impl_(new Impl(serializer)) { } @@ -145,14 +148,12 @@ ArrayRef MrcDensityMapOfFloatReader::constView() const return impl_->data_; } -const MrcDensityMapHeader &MrcDensityMapOfFloatReader::header() const +const MrcDensityMapHeader& MrcDensityMapOfFloatReader::header() const { return impl_->header_; } -MrcDensityMapOfFloatReader::~MrcDensityMapOfFloatReader() -{ -} +MrcDensityMapOfFloatReader::~MrcDensityMapOfFloatReader() {} /******************************************************************** * MrcDensityMapOfFloatFromFileReader::Impl @@ -161,17 +162,18 @@ MrcDensityMapOfFloatReader::~MrcDensityMapOfFloatReader() class MrcDensityMapOfFloatFromFileReader::Impl { - public: - explicit Impl(const std::string &fileName); - ~Impl() = default; - const MrcDensityMapOfFloatReader &reader() const; - private: - std::vector buffer_; - InMemoryDeserializer serializer_; - const MrcDensityMapOfFloatReader reader_; +public: + explicit Impl(const std::string& fileName); + ~Impl() = default; + const MrcDensityMapOfFloatReader& reader() const; + +private: + std::vector buffer_; + InMemoryDeserializer serializer_; + const MrcDensityMapOfFloatReader reader_; }; -MrcDensityMapOfFloatFromFileReader::Impl::Impl(const std::string &filename) : +MrcDensityMapOfFloatFromFileReader::Impl::Impl(const std::string& filename) : buffer_(readCharBufferFromFile(filename)), serializer_(buffer_, false), reader_(&serializer_) @@ -179,12 +181,12 @@ MrcDensityMapOfFloatFromFileReader::Impl::Impl(const std::string &filename) : layout_right::mapping map(getDynamicExtents3D(reader_.header())); if (map.required_span_size() != reader_.constView().ssize()) { - GMX_THROW(FileIOError("File header density extent information of " - + filename + "' does not match density data size")); + GMX_THROW(FileIOError("File header density extent information of " + filename + + "' does not match density data size")); } } -const MrcDensityMapOfFloatReader &MrcDensityMapOfFloatFromFileReader::Impl::reader() const +const MrcDensityMapOfFloatReader& MrcDensityMapOfFloatFromFileReader::Impl::reader() const { return reader_; } @@ -193,23 +195,24 @@ const MrcDensityMapOfFloatReader &MrcDensityMapOfFloatFromFileReader::Impl::read * MrcDensityMapOfFloatFromFileReader */ -MrcDensityMapOfFloatFromFileReader::MrcDensityMapOfFloatFromFileReader(const std::string &filename) - : impl_(new Impl(filename)) -{} +MrcDensityMapOfFloatFromFileReader::MrcDensityMapOfFloatFromFileReader(const std::string& filename) : + impl_(new Impl(filename)) +{ +} MrcDensityMapOfFloatFromFileReader::~MrcDensityMapOfFloatFromFileReader() = default; -TranslateAndScale -MrcDensityMapOfFloatFromFileReader::transformationToDensityLattice() const +TranslateAndScale MrcDensityMapOfFloatFromFileReader::transformationToDensityLattice() const { return getCoordinateTransformationToLattice(impl_->reader().header()); } -MultiDimArray, dynamicExtents3D> -MrcDensityMapOfFloatFromFileReader::densityDataCopy() const +MultiDimArray, dynamicExtents3D> MrcDensityMapOfFloatFromFileReader::densityDataCopy() const { - MultiDimArray, dynamicExtents3D> result(getDynamicExtents3D(impl_->reader().header())); - std::copy(std::begin(impl_->reader().constView()), std::end(impl_->reader().constView()), begin(result.asView())); + MultiDimArray, dynamicExtents3D> result( + getDynamicExtents3D(impl_->reader().header())); + std::copy(std::begin(impl_->reader().constView()), std::end(impl_->reader().constView()), + begin(result.asView())); return result; } @@ -222,23 +225,25 @@ MrcDensityMapOfFloatFromFileReader::densityDataCopy() const */ class MrcDensityMapOfFloatWriter::Impl { - public: - //! Construct mrc file writer by providing header and data to be written. - Impl(const MrcDensityMapHeader &header, ArrayRef data); - ~Impl() {} - //! Write the header and data from the writer to a given serialier - void write(ISerializer *serializer) const; - //! The mrc density map header data - const MrcDensityMapHeader header_; - //! The density data - const ArrayRef data_; +public: + //! Construct mrc file writer by providing header and data to be written. + Impl(const MrcDensityMapHeader& header, ArrayRef data); + ~Impl() {} + //! Write the header and data from the writer to a given serialier + void write(ISerializer* serializer) const; + //! The mrc density map header data + const MrcDensityMapHeader header_; + //! The density data + const ArrayRef data_; }; -MrcDensityMapOfFloatWriter::Impl::Impl(const MrcDensityMapHeader &header, ArrayRef data) : header_(header), data_(data) +MrcDensityMapOfFloatWriter::Impl::Impl(const MrcDensityMapHeader& header, ArrayRef data) : + header_(header), + data_(data) { } -void MrcDensityMapOfFloatWriter::Impl::write(ISerializer *serializer) const +void MrcDensityMapOfFloatWriter::Impl::write(ISerializer* serializer) const { if (serializer->reading()) { @@ -262,17 +267,17 @@ void MrcDensityMapOfFloatWriter::Impl::write(ISerializer *serializer) const * MrcDensityMapOfFloatWriter */ -MrcDensityMapOfFloatWriter::MrcDensityMapOfFloatWriter(const MrcDensityMapHeader &header, ArrayRef data) : impl_(new Impl(header, data)) +MrcDensityMapOfFloatWriter::MrcDensityMapOfFloatWriter(const MrcDensityMapHeader& header, + ArrayRef data) : + impl_(new Impl(header, data)) { } -void MrcDensityMapOfFloatWriter::write(ISerializer *serializer) const +void MrcDensityMapOfFloatWriter::write(ISerializer* serializer) const { impl_->write(serializer); } -MrcDensityMapOfFloatWriter::~MrcDensityMapOfFloatWriter() -{ -} +MrcDensityMapOfFloatWriter::~MrcDensityMapOfFloatWriter() {} } // namespace gmx diff --git a/src/gromacs/fileio/mrcdensitymap.h b/src/gromacs/fileio/mrcdensitymap.h index 6b9d0ec004..85ef1e5510 100644 --- a/src/gromacs/fileio/mrcdensitymap.h +++ b/src/gromacs/fileio/mrcdensitymap.h @@ -60,26 +60,25 @@ class TranslateAndScale; */ class MrcDensityMapOfFloatReader { - public: - /*! \brief Construct from directly de-serializing data into the object. - * \throws InternalError if serializer is not reading - * \throws InternalError if header is inconsistent - * \throws if serializer throws error upon failed reading - * \param[in] serializer Serializer to read the object data from - */ - explicit MrcDensityMapOfFloatReader(ISerializer * serializer); - - ~MrcDensityMapOfFloatReader(); - - //! Return a view on the data of the density grid - ArrayRef constView() const; - //! Return the header - const MrcDensityMapHeader &header() const; - - private: - class Impl; - PrivateImplPointer impl_; - +public: + /*! \brief Construct from directly de-serializing data into the object. + * \throws InternalError if serializer is not reading + * \throws InternalError if header is inconsistent + * \throws if serializer throws error upon failed reading + * \param[in] serializer Serializer to read the object data from + */ + explicit MrcDensityMapOfFloatReader(ISerializer* serializer); + + ~MrcDensityMapOfFloatReader(); + + //! Return a view on the data of the density grid + ArrayRef constView() const; + //! Return the header + const MrcDensityMapHeader& header() const; + +private: + class Impl; + PrivateImplPointer impl_; }; /*! \libinternal \brief Read an mrc density map from a given file. @@ -94,53 +93,52 @@ class MrcDensityMapOfFloatReader */ class MrcDensityMapOfFloatFromFileReader { - public: - - MrcDensityMapOfFloatFromFileReader(); +public: + MrcDensityMapOfFloatFromFileReader(); - /*! \brief Read from filename. - * \throws FileIOError if file does not exist - * \throws FileIOError if read in buffer size does not match file size - * \throws FileIOError if header information does not match density - * data size - */ - explicit MrcDensityMapOfFloatFromFileReader(const std::string &filename); + /*! \brief Read from filename. + * \throws FileIOError if file does not exist + * \throws FileIOError if read in buffer size does not match file size + * \throws FileIOError if header information does not match density + * data size + */ + explicit MrcDensityMapOfFloatFromFileReader(const std::string& filename); - ~MrcDensityMapOfFloatFromFileReader(); + ~MrcDensityMapOfFloatFromFileReader(); - //! Return the coordinate transformation into the density - TranslateAndScale transformationToDensityLattice() const; + //! Return the coordinate transformation into the density + TranslateAndScale transformationToDensityLattice() const; - //! Return a copy of the density data - MultiDimArray, dynamicExtents3D> densityDataCopy() const; + //! Return a copy of the density data + MultiDimArray, dynamicExtents3D> densityDataCopy() const; - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; /*! \libinternal \brief Write an mrc/ccp4 file that contains float values. */ class MrcDensityMapOfFloatWriter { - public: - /*! \brief Construct by setting the data and the header. - * - * \throws if the header data description does not match the provided data - * - * \param[in] header mrc density map header - * \param[in] data the density map data - */ - MrcDensityMapOfFloatWriter(const MrcDensityMapHeader &header, ArrayRef data); - - ~MrcDensityMapOfFloatWriter(); - - //! Serialize the mrc density data. - void write(ISerializer *serializer) const; - - private: - class Impl; - PrivateImplPointer impl_; +public: + /*! \brief Construct by setting the data and the header. + * + * \throws if the header data description does not match the provided data + * + * \param[in] header mrc density map header + * \param[in] data the density map data + */ + MrcDensityMapOfFloatWriter(const MrcDensityMapHeader& header, ArrayRef data); + + ~MrcDensityMapOfFloatWriter(); + + //! Serialize the mrc density data. + void write(ISerializer* serializer) const; + +private: + class Impl; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/fileio/mrcdensitymapheader.cpp b/src/gromacs/fileio/mrcdensitymapheader.cpp index 86d554022a..28842078ba 100644 --- a/src/gromacs/fileio/mrcdensitymapheader.cpp +++ b/src/gromacs/fileio/mrcdensitymapheader.cpp @@ -50,55 +50,49 @@ namespace gmx { -size_t numberOfExpectedDataItems(const MrcDensityMapHeader &header) +size_t numberOfExpectedDataItems(const MrcDensityMapHeader& header) { - if (std::any_of( - std::begin(header.numColumnRowSection_), std::end(header.numColumnRowSection_), - [](auto i) { return i < 0; })) + if (std::any_of(std::begin(header.numColumnRowSection_), std::end(header.numColumnRowSection_), + [](auto i) { return i < 0; })) { - GMX_THROW(InternalError("Cannot determine data size, because the mrc " - "density map header is invalid (Negative number " - "describing data extent in at least one dimension).")); + GMX_THROW( + InternalError("Cannot determine data size, because the mrc " + "density map header is invalid (Negative number " + "describing data extent in at least one dimension).")); } - return header.numColumnRowSection_[XX] * header.numColumnRowSection_[YY] * header.numColumnRowSection_[ZZ]; + return header.numColumnRowSection_[XX] * header.numColumnRowSection_[YY] + * header.numColumnRowSection_[ZZ]; } -TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader &header) +TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader& header) { constexpr real c_AAtoNmConversion = 0.1; - RVec scale = { - header.extent_[XX] / (header.cellLength_[XX] * c_AAtoNmConversion), - header.extent_[YY] / (header.cellLength_[YY] * c_AAtoNmConversion), - header.extent_[ZZ] / (header.cellLength_[ZZ] * c_AAtoNmConversion) - }; - const RVec emdbOrigin { - header.userDefinedFloat_[12], header.userDefinedFloat_[13], header.userDefinedFloat_[14] - }; - RVec translation; + RVec scale = { header.extent_[XX] / (header.cellLength_[XX] * c_AAtoNmConversion), + header.extent_[YY] / (header.cellLength_[YY] * c_AAtoNmConversion), + header.extent_[ZZ] / (header.cellLength_[ZZ] * c_AAtoNmConversion) }; + const RVec emdbOrigin{ header.userDefinedFloat_[12], header.userDefinedFloat_[13], + header.userDefinedFloat_[14] }; + RVec translation; if (emdbOrigin[XX] == 0. && emdbOrigin[YY] == 0. && emdbOrigin[ZZ] == 0.) { - translation = RVec { - -header.columnRowSectionStart_[XX] / scale[XX], - -header.columnRowSectionStart_[YY] / scale[YY], - -header.columnRowSectionStart_[ZZ] / scale[ZZ] - }; + translation = RVec{ -header.columnRowSectionStart_[XX] / scale[XX], + -header.columnRowSectionStart_[YY] / scale[YY], + -header.columnRowSectionStart_[ZZ] / scale[ZZ] }; } else { - translation = { - -emdbOrigin[XX] * c_AAtoNmConversion, - -emdbOrigin[YY] * c_AAtoNmConversion, - -emdbOrigin[ZZ] * c_AAtoNmConversion - }; + translation = { -emdbOrigin[XX] * c_AAtoNmConversion, -emdbOrigin[YY] * c_AAtoNmConversion, + -emdbOrigin[ZZ] * c_AAtoNmConversion }; } - return {scale, translation}; + return { scale, translation }; } -dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader &header) +dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader& header) { - return {header.numColumnRowSection_[ZZ], header.numColumnRowSection_[YY], header.numColumnRowSection_[XX]}; + return { header.numColumnRowSection_[ZZ], header.numColumnRowSection_[YY], + header.numColumnRowSection_[XX] }; }; } // namespace gmx diff --git a/src/gromacs/fileio/mrcdensitymapheader.h b/src/gromacs/fileio/mrcdensitymapheader.h index 6f4fb06c11..f358efbaa2 100644 --- a/src/gromacs/fileio/mrcdensitymapheader.h +++ b/src/gromacs/fileio/mrcdensitymapheader.h @@ -75,9 +75,9 @@ enum class SpaceGroup : int32_t */ enum class MrcDataMode : int32_t { - uInt8 = 0, //!< compressed data mode, 8 bits, signed byte (range -128 to 127, ISO/IEC 10967) - int16 = 1, //!< 16 bits, signed integer (range -32768 to 32767, ISO/IEC 10967) - float32 = 2, //!< 32 bits, floating point number (IEEE 754) + uInt8 = 0, //!< compressed data mode, 8 bits, signed byte (range -128 to 127, ISO/IEC 10967) + int16 = 1, //!< 16 bits, signed integer (range -32768 to 32767, ISO/IEC 10967) + float32 = 2, //!< 32 bits, floating point number (IEEE 754) complexInt32 = 3, //!< 32 bits, complex signed integers (ISO/IEC 10967) complexFloat64 = 4, //!< 64 bits, complex floating point numbers (IEEE 754) }; @@ -100,9 +100,9 @@ struct MrcDataStatistics */ struct MrcDensitySkewData { - bool valid_ = false; //!< True if skew matrix is stored. - std::array matrix_ = {}; //!< Skew matrix for crystallographic unit cell in Ångström - std::array translation_ = {}; //!< Translation of crystallographic unit cell in Ångström + bool valid_ = false; //!< True if skew matrix is stored. + std::array matrix_ = {}; //!< Skew matrix for crystallographic unit cell in Ångström + std::array translation_ = {}; //!< Translation of crystallographic unit cell in Ångström }; /*! \libinternal @@ -112,7 +112,7 @@ struct CrystallographicLabels { static constexpr int c_labelSize = 80; //!< Length of crystallographic labels is eighty. //! Number of used crystallographic labels, 0 for imagestacks, 1 for emdb data - int32_t numUsedLabels_ = 0; + int32_t numUsedLabels_ = 0; //! Crystallographic labels or "::::EMDataBank.org::::EMD-1234::::" for EMDB entries std::array, 10> labels_ = {}; @@ -127,38 +127,39 @@ struct CrystallographicLabels * For a detailed description see * "EMDB Map Distribution Format Description Version 1.01 (c) emdatabank.org 2014" */ -struct MrcDensityMapHeader{ +struct MrcDensityMapHeader +{ //! Space group of stored data. - SpaceGroup spaceGroup_ = SpaceGroup::P1; + SpaceGroup spaceGroup_ = SpaceGroup::P1; //! Data mode, currently only mode 2 is supported - MrcDataMode dataMode_ = MrcDataMode::float32; + MrcDataMode dataMode_ = MrcDataMode::float32; //! Identifies file format, expected to be "MAP " - std::array formatIdentifier_ = {{'M', 'A', 'P', ' ' }}; + std::array formatIdentifier_ = { { 'M', 'A', 'P', ' ' } }; //! 15 unspecified float numbers - std::array userDefinedFloat_ = {}; + std::array userDefinedFloat_ = {}; - //!Labels for crystallographic data - CrystallographicLabels labels_ = {}; + //! Labels for crystallographic data + CrystallographicLabels labels_ = {}; //! Length of the crystallographic unit cell in Ångström - std::array cellLength_ = {{1., 1., 1. }}; + std::array cellLength_ = { { 1., 1., 1. } }; //! crystallographic unit cell angles - std::array cellAngles_ = {{90., 90., 90. }}; + std::array cellAngles_ = { { 90., 90., 90. } }; //! Data axis order with columns varying the fastest, and sections the slowest. - std::array columnRowSectionToXyz_ = {{0, 1, 2 }}; + std::array columnRowSectionToXyz_ = { { 0, 1, 2 } }; - std::array numColumnRowSection_ = {}; //!< Column, row and section count - std::array columnRowSectionStart_ = {}; //!< Start of values in grid - std::array extent_ = {}; //!< The number of grid points in the crystall cell + std::array numColumnRowSection_ = {}; //!< Column, row and section count + std::array columnRowSectionStart_ = {}; //!< Start of values in grid + std::array extent_ = {}; //!< The number of grid points in the crystall cell //! Statistics about the data stored in the file. - MrcDataStatistics dataStatistics_ = {}; + MrcDataStatistics dataStatistics_ = {}; //! Data to perform crystallographic unit cell skewing - MrcDensitySkewData skewData_ = {}; + MrcDensitySkewData skewData_ = {}; //! Extended header with symmetry tables - std::vector extendedHeader_ = {}; + std::vector extendedHeader_ = {}; }; /*! \brief Return the number of density data items that are expected @@ -166,7 +167,7 @@ struct MrcDensityMapHeader{ * \throws InternalError if the number of data items cannot be determined * \returns the number of voxels */ -size_t numberOfExpectedDataItems(const MrcDensityMapHeader &header); +size_t numberOfExpectedDataItems(const MrcDensityMapHeader& header); /*! \brief Extract the transformation into lattice coordinates. * \note Transformation into lattice coordinates is not treated uniformly @@ -182,12 +183,12 @@ size_t numberOfExpectedDataItems(const MrcDensityMapHeader &header); * \param[in] header from which the coordinate transformation is to be extracted * \returns a functor that transforms real space coordinates into the lattice */ -TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader &header); +TranslateAndScale getCoordinateTransformationToLattice(const MrcDensityMapHeader& header); /*! \brief Extract the extents of the density data * \param[in] header from which the extents are to be extracted * \returns density data extents in three dimensions. */ -dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader &header); -} // namespace gmx +dynamicExtents3D getDynamicExtents3D(const MrcDensityMapHeader& header); +} // namespace gmx #endif /* end of include guard: GMX_FILEIO_MRCDENSITYMAPHEADER_H */ diff --git a/src/gromacs/fileio/mrcserializer.cpp b/src/gromacs/fileio/mrcserializer.cpp index db3f61ed84..ac4968cdf2 100644 --- a/src/gromacs/fileio/mrcserializer.cpp +++ b/src/gromacs/fileio/mrcserializer.cpp @@ -76,11 +76,11 @@ enum class MachineStamp : int32_t * \param[in,out] serializer the serializer * \param[in,out] valueContainer the array to be serialized */ -template +template std::enable_if_t::value, void> -serialize(ISerializer *serializer, ContainerType *valueContainer) +serialize(ISerializer* serializer, ContainerType* valueContainer) { - for (auto &value : *valueContainer) + for (auto& value : *valueContainer) { serializer->doInt32(&value); } @@ -94,23 +94,23 @@ serialize(ISerializer *serializer, ContainerType *valueContainer) * \param[in,out] serializer the serializer * \param[in,out] valueContainer the array to be serialized */ -template +template std::enable_if_t::value, void> -serialize(ISerializer *serializer, ContainerType *valueContainer) +serialize(ISerializer* serializer, ContainerType* valueContainer) { - for (auto &value : *valueContainer) + for (auto& value : *valueContainer) { serializer->doFloat(&value); } } //! Serialize and convert from FORTRAN 1-based to C 0-based indices when reading and vice versa when writing -void serializeIndex(ISerializer *serializer, int32_t *index) +void serializeIndex(ISerializer* serializer, int32_t* index) { int32_t fortranIndex; if (!serializer->reading()) { - fortranIndex = *index+1; + fortranIndex = *index + 1; } serializer->doInt32(&fortranIndex); if (serializer->reading()) @@ -122,9 +122,9 @@ void serializeIndex(ISerializer *serializer, int32_t *index) /*! \brief * Serializes an integer array and add unity when writing, substracting unity when reading. */ -void serializeIndices(ISerializer * serializer, std::array * valueArray) +void serializeIndices(ISerializer* serializer, std::array* valueArray) { - for (auto &value : *valueArray) + for (auto& value : *valueArray) { serializeIndex(serializer, &value); } @@ -133,10 +133,9 @@ void serializeIndices(ISerializer * serializer, std::array * valueAr /*! \brief Serialize input as int32_t via static casting. * \tparam IntegralType type to be serialized as int32_t */ -template -std::enable_if_t<(std::is_integral::value || - std::is_enum::value), void > -serializeAsInt32(ISerializer *serializer, IntegralType *value) +template +std::enable_if_t<(std::is_integral::value || std::is_enum::value), void> +serializeAsInt32(ISerializer* serializer, IntegralType* value) { int32_t serializedValue; if (!serializer->reading()) @@ -166,7 +165,7 @@ float nmToMrcUnits(float nmValue) } //! Serialize and convert between MRC and GROMACS distance units -void serializeDistance(ISerializer *serializer, float *distance) +void serializeDistance(ISerializer* serializer, float* distance) { float convertedDistance; if (!serializer->reading()) @@ -181,7 +180,7 @@ void serializeDistance(ISerializer *serializer, float *distance) } //! Serialize the skew data, words 25-37 in an mrc file. -void serializeCrystallographicSkewData(ISerializer * serializer, MrcDensitySkewData * skewData) +void serializeCrystallographicSkewData(ISerializer* serializer, MrcDensitySkewData* skewData) { /* 25 | LSKFLG | signed int | emdb: 0 or 1 * flag for skew matrix @@ -192,11 +191,11 @@ void serializeCrystallographicSkewData(ISerializer * serializer, MrcDensitySkewD * 35-37 | SKWTRN | floating pt | emdb: not set * skew translation-T1, T2, T3 */ - for (auto &matrixEntry : skewData->matrix_) + for (auto& matrixEntry : skewData->matrix_) { serializeDistance(serializer, &matrixEntry); } - for (auto &translationEntry : skewData->translation_) + for (auto& translationEntry : skewData->translation_) { serializeDistance(serializer, &translationEntry); } @@ -208,7 +207,7 @@ void serializeCrystallographicSkewData(ISerializer * serializer, MrcDensitySkewD * ftp://ftp.wwpdb.org/pub/emdb/doc/Map-format/current/EMDB_map_format.pdf * \note format has small differences to http://www.ccpem.ac.uk/mrc_format/mrc2014.php */ -void doMrcDensityMapHeader(ISerializer * serializer, MrcDensityMapHeader * mrcFile) +void doMrcDensityMapHeader(ISerializer* serializer, MrcDensityMapHeader* mrcFile) { // 1-3 | NC, NR, NS | signed int >0 | emdb: NC=NR=NS // # of columns (fastest changing),rows, sections (slowest changing) @@ -223,8 +222,8 @@ void doMrcDensityMapHeader(ISerializer * serializer, MrcDensityMapHeader * mrcFi // 8-10 | NX, NY, NZ | signed int >0 | emdb: same as NC, NR, NS | intervals per unit cell repeat along X,Y Z serialize(serializer, &(mrcFile->extent_)); - // 11-13 | X_LENGTH, Y_LENGTH, Z_LENGTH | floating pt >0 | emdb Map lengths along X,Y,Z in Ångström - // Length in Ångström for a single voxel is unit_cell_length/n_voxel + // 11-13 | X_LENGTH, Y_LENGTH, Z_LENGTH | floating pt >0 | emdb Map lengths along X,Y,Z in + // Ångström Length in Ångström for a single voxel is unit_cell_length/n_voxel serialize(serializer, &(mrcFile->cellLength_)); // 14-16 | ALPHA,BETA,GAMMA | floating pt >0, <180 | emdb: 90, 90, 90 @@ -263,14 +262,14 @@ void doMrcDensityMapHeader(ISerializer * serializer, MrcDensityMapHeader * mrcFi // 38-52 | EXTRA | 32 bit binary // 15 floats of user-defined metadata // EMDB might use fields 50,51 and 52 for setting the coordinate system origin - for (auto &userFloat : mrcFile->userDefinedFloat_) + for (auto& userFloat : mrcFile->userDefinedFloat_) { serializer->doFloat(&userFloat); } // 53 | MAP | ASCII char | emdb: "MAP " // MRC/CCP4 MAP format identifier - for (auto &formatIdentifierCharacter : mrcFile->formatIdentifier_) + for (auto& formatIdentifierCharacter : mrcFile->formatIdentifier_) { serializer->doUChar(&formatIdentifierCharacter); } @@ -287,31 +286,30 @@ void doMrcDensityMapHeader(ISerializer * serializer, MrcDensityMapHeader * mrcFi // 57-256 | LABEL_N | ASCII char | emdb : “::::EMDataBank.org::::EMD-1234::::”. // 10 user-defined labels each 80 characters - for (auto && label : mrcFile->labels_.labels_) + for (auto&& label : mrcFile->labels_.labels_) { - for (auto && labelCharacter : label) + for (auto&& labelCharacter : label) { serializer->doUChar(&labelCharacter); } } // 257-257+NSYMBT | user defined extended header information | emdb : none - for (auto &extendedHeaderCharacter : mrcFile->extendedHeader_) + for (auto& extendedHeaderCharacter : mrcFile->extendedHeader_) { serializer->doUChar(&extendedHeaderCharacter); } } -} // namespace +} // namespace -void serializeMrcDensityMapHeader(ISerializer * serializer, - const MrcDensityMapHeader &mrcFile) +void serializeMrcDensityMapHeader(ISerializer* serializer, const MrcDensityMapHeader& mrcFile) { MrcDensityMapHeader mrcHeaderCopy = mrcFile; doMrcDensityMapHeader(serializer, &mrcHeaderCopy); } -MrcDensityMapHeader deserializeMrcDensityMapHeader(ISerializer * serializer) +MrcDensityMapHeader deserializeMrcDensityMapHeader(ISerializer* serializer) { MrcDensityMapHeader mrcHeader; doMrcDensityMapHeader(serializer, &mrcHeader); diff --git a/src/gromacs/fileio/mrcserializer.h b/src/gromacs/fileio/mrcserializer.h index 156262575d..e62a3d75cf 100644 --- a/src/gromacs/fileio/mrcserializer.h +++ b/src/gromacs/fileio/mrcserializer.h @@ -51,12 +51,11 @@ struct MrcDensityMapHeader; * \param[in] serializer the serializer * \param[in] mrcHeader file header to be serialized */ -void serializeMrcDensityMapHeader(ISerializer *serializer, - const MrcDensityMapHeader &mrcHeader); +void serializeMrcDensityMapHeader(ISerializer* serializer, const MrcDensityMapHeader& mrcHeader); /*! \brief Deserializes an MrcDensityMapHeader from a given serializer. * \param[in] serializer the serializer * \returns mrc density map header */ -MrcDensityMapHeader deserializeMrcDensityMapHeader(ISerializer *serializer); -} // namespace gmx +MrcDensityMapHeader deserializeMrcDensityMapHeader(ISerializer* serializer); +} // namespace gmx #endif /* end of include guard: GMX_FILEIO_MRCSERIALIZER_H */ diff --git a/src/gromacs/fileio/mtxio.cpp b/src/gromacs/fileio/mtxio.cpp index 542a6ae082..3bbe18303d 100644 --- a/src/gromacs/fileio/mtxio.cpp +++ b/src/gromacs/fileio/mtxio.cpp @@ -51,11 +51,10 @@ #include "gromacs/utility/smalloc.h" /* Just a number to identify our file type */ -#define GMX_MTXIO_MAGIC_NUMBER 0x34ce8fd2 - -#define GMX_MTXIO_FULL_MATRIX 0 -#define GMX_MTXIO_SPARSE_MATRIX 1 +#define GMX_MTXIO_MAGIC_NUMBER 0x34ce8fd2 +#define GMX_MTXIO_FULL_MATRIX 0 +#define GMX_MTXIO_SPARSE_MATRIX 1 /* Matrix file format definition: @@ -79,15 +78,11 @@ * Each entry consists of an integer column index and floating-point data value. */ -void gmx_mtxio_write(const char * filename, - int nrow, - int ncol, - real * full_matrix, - gmx_sparsematrix_t * sparse_matrix) +void gmx_mtxio_write(const char* filename, int nrow, int ncol, real* full_matrix, gmx_sparsematrix_t* sparse_matrix) { - t_fileio *fio; - int i, j, prec; - size_t sz; + t_fileio* fio; + int i, j, prec; + size_t sz; if (full_matrix != nullptr && sparse_matrix != nullptr) { @@ -122,7 +117,7 @@ void gmx_mtxio_write(const char * filename, /* Full matrix storage format */ i = GMX_MTXIO_FULL_MATRIX; gmx_fio_do_int(fio, i); - sz = nrow*ncol; + sz = nrow * ncol; gmx_fio_ndo_real(fio, full_matrix, sz); } else @@ -151,17 +146,12 @@ void gmx_mtxio_write(const char * filename, } -void -gmx_mtxio_read (const char * filename, - int * nrow, - int * ncol, - real ** full_matrix, - gmx_sparsematrix_t ** sparse_matrix) +void gmx_mtxio_read(const char* filename, int* nrow, int* ncol, real** full_matrix, gmx_sparsematrix_t** sparse_matrix) { - t_fileio *fio; - int i, j, prec; - char gmxver[256]; - size_t sz; + t_fileio* fio; + int i, j, prec; + char gmxver[256]; + size_t sz; fio = gmx_fio_open(filename, "r"); @@ -223,8 +213,7 @@ gmx_mtxio_read (const char * filename, snew((*sparse_matrix)->ndata, (*sparse_matrix)->nrow); snew((*sparse_matrix)->nalloc, (*sparse_matrix)->nrow); snew((*sparse_matrix)->data, (*sparse_matrix)->nrow); - gmx_fio_ndo_int(fio, (*sparse_matrix)->ndata, - (*sparse_matrix)->nrow); + gmx_fio_ndo_int(fio, (*sparse_matrix)->ndata, (*sparse_matrix)->nrow); for (i = 0; i < (*sparse_matrix)->nrow; i++) { diff --git a/src/gromacs/fileio/mtxio.h b/src/gromacs/fileio/mtxio.h index 1d9a8bbef6..651972c503 100644 --- a/src/gromacs/fileio/mtxio.h +++ b/src/gromacs/fileio/mtxio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,12 +52,7 @@ * EITHER a pointer to a full storage matrix or a sparse storage * matrix. If both pointers are non-NULL a fatal error will occur. */ -void -gmx_mtxio_write(const char * filename, - int nrow, - int ncol, - real * full_matrix, - gmx_sparsematrix_t * sparse_matrix); +void gmx_mtxio_write(const char* filename, int nrow, int ncol, real* full_matrix, gmx_sparsematrix_t* sparse_matrix); /* Read a matrix from file. @@ -71,11 +66,6 @@ gmx_mtxio_write(const char * filename, * To determine the format you should set *full_matrix and *sparse_matrix to NULL * before calling this routine, and check which one is non-NULL on return. */ -void -gmx_mtxio_read (const char * filename, - int * nrow, - int * ncol, - real ** full_matrix, - gmx_sparsematrix_t ** sparse_matrix); +void gmx_mtxio_read(const char* filename, int* nrow, int* ncol, real** full_matrix, gmx_sparsematrix_t** sparse_matrix); #endif diff --git a/src/gromacs/fileio/oenv.cpp b/src/gromacs/fileio/oenv.cpp index 4a97f07abf..7bef55cd05 100644 --- a/src/gromacs/fileio/oenv.cpp +++ b/src/gromacs/fileio/oenv.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,27 +45,29 @@ struct gmx_output_env_t { - explicit gmx_output_env_t(const gmx::IProgramContext &context) - : programContext(context), - time_unit(time_ps), - view(FALSE), - xvg_format(exvgNONE), - verbosity(0), - trajectory_io_verbosity(0) {} + explicit gmx_output_env_t(const gmx::IProgramContext& context) : + programContext(context), + time_unit(time_ps), + view(FALSE), + xvg_format(exvgNONE), + verbosity(0), + trajectory_io_verbosity(0) + { + } - const gmx::IProgramContext &programContext; + const gmx::IProgramContext& programContext; /* the time unit, enum defined in oenv.h */ - time_unit_t time_unit; + time_unit_t time_unit; /* view of file requested */ - gmx_bool view; + gmx_bool view; /* xvg output format, enum defined in oenv.h */ - xvg_format_t xvg_format; + xvg_format_t xvg_format; /* The level of verbosity for this program */ - int verbosity; + int verbosity; /* The level of verbosity during trajectory I/O. Default=1, quiet=0. */ - int trajectory_io_verbosity; + int trajectory_io_verbosity; }; /* The source code in this file should be thread-safe. @@ -79,99 +81,96 @@ struct gmx_output_env_t /* read only time names */ /* These must correspond to the time units type time_unit_t in oenv.h */ -static const real timefactors[] = { real(0), real(1e3), real(1), real(1e-3), real(1e-6), real(1e-9), real(1e-12), real(0) }; -static const real timeinvfactors[] = { real(0), real(1e-3), real(1), real(1e3), real(1e6), real(1e9), real(1e12), real(0) }; -static const char *time_units_str[] = { - nullptr, "fs", "ps", "ns", "us", - "\\mus", "ms", "s" -}; -static const char *time_units_xvgr[] = { - nullptr, "fs", "ps", "ns", - "ms", "s", nullptr -}; +static const real timefactors[] = { real(0), real(1e3), real(1), real(1e-3), + real(1e-6), real(1e-9), real(1e-12), real(0) }; +static const real timeinvfactors[] = { real(0), real(1e-3), real(1), real(1e3), + real(1e6), real(1e9), real(1e12), real(0) }; +static const char* time_units_str[] = { nullptr, "fs", "ps", "ns", "us", "\\mus", "ms", "s" }; +static const char* time_units_xvgr[] = { nullptr, "fs", "ps", "ns", "ms", "s", nullptr }; /***** OUTPUT_ENV MEMBER FUNCTIONS ******/ -void output_env_init(gmx_output_env_t **oenvp, - const gmx::IProgramContext &context, - time_unit_t tmu, gmx_bool view, xvg_format_t xvg_format, - int verbosity) +void output_env_init(gmx_output_env_t** oenvp, + const gmx::IProgramContext& context, + time_unit_t tmu, + gmx_bool view, + xvg_format_t xvg_format, + int verbosity) { try { - gmx_output_env_t *oenv = new gmx_output_env_t(context); - *oenvp = oenv; - oenv->time_unit = tmu; - oenv->view = view; - oenv->xvg_format = xvg_format; - oenv->verbosity = verbosity; - const char *env = getenv("GMX_TRAJECTORY_IO_VERBOSITY"); + gmx_output_env_t* oenv = new gmx_output_env_t(context); + *oenvp = oenv; + oenv->time_unit = tmu; + oenv->view = view; + oenv->xvg_format = xvg_format; + oenv->verbosity = verbosity; + const char* env = getenv("GMX_TRAJECTORY_IO_VERBOSITY"); oenv->trajectory_io_verbosity = (env != nullptr ? strtol(env, nullptr, 10) : 1); - } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } -void output_env_init_default(gmx_output_env_t **oenvp) +void output_env_init_default(gmx_output_env_t** oenvp) { try { - gmx_output_env_t *oenv = new gmx_output_env_t(gmx::getProgramContext()); - *oenvp = oenv; + gmx_output_env_t* oenv = new gmx_output_env_t(gmx::getProgramContext()); + *oenvp = oenv; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } -void output_env_done(gmx_output_env_t *oenv) +void output_env_done(gmx_output_env_t* oenv) { delete oenv; } -int output_env_get_verbosity(const gmx_output_env_t *oenv) +int output_env_get_verbosity(const gmx_output_env_t* oenv) { return oenv->verbosity; } -int output_env_get_trajectory_io_verbosity(const gmx_output_env_t *oenv) +int output_env_get_trajectory_io_verbosity(const gmx_output_env_t* oenv) { return oenv->trajectory_io_verbosity; } -std::string output_env_get_time_unit(const gmx_output_env_t *oenv) +std::string output_env_get_time_unit(const gmx_output_env_t* oenv) { return time_units_str[oenv->time_unit]; } -std::string output_env_get_time_label(const gmx_output_env_t *oenv) +std::string output_env_get_time_label(const gmx_output_env_t* oenv) { - return gmx::formatString("Time (%s)", time_units_str[oenv->time_unit] ? - time_units_str[oenv->time_unit] : "ps"); + return gmx::formatString( + "Time (%s)", time_units_str[oenv->time_unit] ? time_units_str[oenv->time_unit] : "ps"); } -std::string output_env_get_xvgr_tlabel(const gmx_output_env_t *oenv) +std::string output_env_get_xvgr_tlabel(const gmx_output_env_t* oenv) { - return gmx::formatString("Time (%s)", time_units_xvgr[oenv->time_unit] ? - time_units_xvgr[oenv->time_unit] : "ps"); + return gmx::formatString( + "Time (%s)", time_units_xvgr[oenv->time_unit] ? time_units_xvgr[oenv->time_unit] : "ps"); } -real output_env_get_time_factor(const gmx_output_env_t *oenv) +real output_env_get_time_factor(const gmx_output_env_t* oenv) { return timefactors[oenv->time_unit]; } -real output_env_get_time_invfactor(const gmx_output_env_t *oenv) +real output_env_get_time_invfactor(const gmx_output_env_t* oenv) { return timeinvfactors[oenv->time_unit]; } -real output_env_conv_time(const gmx_output_env_t *oenv, real time) +real output_env_conv_time(const gmx_output_env_t* oenv, real time) { - return time*timefactors[oenv->time_unit]; + return time * timefactors[oenv->time_unit]; } -void output_env_conv_times(const gmx_output_env_t *oenv, int n, real *time) +void output_env_conv_times(const gmx_output_env_t* oenv, int n, real* time) { int i; double fact = timefactors[oenv->time_unit]; @@ -185,31 +184,30 @@ void output_env_conv_times(const gmx_output_env_t *oenv, int n, real *time) } } -gmx_bool output_env_get_view(const gmx_output_env_t *oenv) +gmx_bool output_env_get_view(const gmx_output_env_t* oenv) { return oenv->view; } -xvg_format_t output_env_get_xvg_format(const gmx_output_env_t *oenv) +xvg_format_t output_env_get_xvg_format(const gmx_output_env_t* oenv) { return oenv->xvg_format; } -const char *output_env_get_program_display_name(const gmx_output_env_t *oenv) +const char* output_env_get_program_display_name(const gmx_output_env_t* oenv) { - const char *displayName = nullptr; + const char* displayName = nullptr; try { displayName = oenv->programContext.displayName(); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR return displayName; } -const gmx::IProgramContext & -output_env_get_program_context(const gmx_output_env_t *oenv) +const gmx::IProgramContext& output_env_get_program_context(const gmx_output_env_t* oenv) { return oenv->programContext; } diff --git a/src/gromacs/fileio/oenv.h b/src/gromacs/fileio/oenv.h index 5718897606..0624e1d77b 100644 --- a/src/gromacs/fileio/oenv.h +++ b/src/gromacs/fileio/oenv.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,71 +55,83 @@ struct gmx_output_env_t; typedef enum { - timeNULL, time_fs, time_ps, time_ns, time_us, time_ms, time_s + timeNULL, + time_fs, + time_ps, + time_ns, + time_us, + time_ms, + time_s } time_unit_t; /* the time units. For the time being, ps means no conversion. */ -typedef enum { - exvgNULL, exvgXMGRACE, exvgXMGR, exvgNONE +typedef enum +{ + exvgNULL, + exvgXMGRACE, + exvgXMGR, + exvgNONE } xvg_format_t; /* the xvg output formattings */ -void output_env_init_default(gmx_output_env_t **oenvp); +void output_env_init_default(gmx_output_env_t** oenvp); /* initialize an output_env structure, with reasonable default settings. (the time unit is set to time_ps, which means no conversion). */ -void output_env_done(gmx_output_env_t *oenv); +void output_env_done(gmx_output_env_t* oenv); /* free memory allocated for an output_env structure. */ -int output_env_get_verbosity(const gmx_output_env_t *oenv); +int output_env_get_verbosity(const gmx_output_env_t* oenv); /* return the verbosity */ -int output_env_get_trajectory_io_verbosity(const gmx_output_env_t *oenv); +int output_env_get_trajectory_io_verbosity(const gmx_output_env_t* oenv); /* return the verbosity for trajectory IO handling */ -std::string output_env_get_time_unit(const gmx_output_env_t *oenv); +std::string output_env_get_time_unit(const gmx_output_env_t* oenv); /* return time unit (e.g. ps or ns) */ -std::string output_env_get_time_label(const gmx_output_env_t *oenv); +std::string output_env_get_time_label(const gmx_output_env_t* oenv); /* return time unit label (e.g. "Time (ps)") */ -std::string output_env_get_xvgr_tlabel(const gmx_output_env_t *oenv); +std::string output_env_get_xvgr_tlabel(const gmx_output_env_t* oenv); /* return x-axis time label for xmgr */ -real output_env_get_time_factor(const gmx_output_env_t *oenv); +real output_env_get_time_factor(const gmx_output_env_t* oenv); /* return time conversion factor from ps (i.e. 1e-3 for ps->ns) */ -real output_env_get_time_invfactor(const gmx_output_env_t *oenv); +real output_env_get_time_invfactor(const gmx_output_env_t* oenv); /* return inverse time conversion factor to ps (i.e. 1e3 for ns->ps) */ -real output_env_conv_time(const gmx_output_env_t *oenv, real time); +real output_env_conv_time(const gmx_output_env_t* oenv, real time); /* return converted time */ -void output_env_conv_times(const gmx_output_env_t *oenv, int n, real *time); +void output_env_conv_times(const gmx_output_env_t* oenv, int n, real* time); /* convert array of times */ -gmx_bool output_env_get_view(const gmx_output_env_t *oenv); +gmx_bool output_env_get_view(const gmx_output_env_t* oenv); /* Return TRUE when user requested viewing of the file */ -xvg_format_t output_env_get_xvg_format(const gmx_output_env_t *oenv); +xvg_format_t output_env_get_xvg_format(const gmx_output_env_t* oenv); /* Returns enum (see above) for xvg output formatting */ /*! \brief * Returns display name for the currently running program. */ -const char *output_env_get_program_display_name(const gmx_output_env_t *oenv); +const char* output_env_get_program_display_name(const gmx_output_env_t* oenv); namespace gmx { class IProgramContext; } // namespace gmx -void output_env_init(gmx_output_env_t **oenvp, - const gmx::IProgramContext &context, - time_unit_t tmu, gmx_bool view, xvg_format_t xvg_format, - int verbosity); +void output_env_init(gmx_output_env_t** oenvp, + const gmx::IProgramContext& context, + time_unit_t tmu, + gmx_bool view, + xvg_format_t xvg_format, + int verbosity); /* initialize an output_env structure, setting the command line, the default time value a gmx_boolean view that is set to TRUE when the user requests direct viewing of graphs, @@ -128,7 +140,6 @@ void output_env_init(gmx_output_env_t **oenvp, /*! \brief * Returns gmx::IProgramContext from an output_env structure. */ -const gmx::IProgramContext & -output_env_get_program_context(const gmx_output_env_t *oenv); +const gmx::IProgramContext& output_env_get_program_context(const gmx_output_env_t* oenv); #endif diff --git a/src/gromacs/fileio/pdbio.cpp b/src/gromacs/fileio/pdbio.cpp index 2ac27ffd02..fa4be6e34b 100644 --- a/src/gromacs/fileio/pdbio.cpp +++ b/src/gromacs/fileio/pdbio.cpp @@ -61,25 +61,24 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/snprintf.h" -typedef struct { +typedef struct +{ int ai, aj; } gmx_conection_t; -typedef struct gmx_conect_t { +typedef struct gmx_conect_t +{ int nconect; gmx_bool bSorted; - gmx_conection_t *conect; + gmx_conection_t* conect; } gmx_conect_t; -static const char *pdbtp[epdbNR] = { - "ATOM ", "HETATM", "ANISOU", "CRYST1", - "COMPND", "MODEL", "ENDMDL", "TER", "HEADER", "TITLE", "REMARK", - "CONECT" -}; +static const char* pdbtp[epdbNR] = { "ATOM ", "HETATM", "ANISOU", "CRYST1", "COMPND", "MODEL", + "ENDMDL", "TER", "HEADER", "TITLE", "REMARK", "CONECT" }; #define REMARK_SIM_BOX "REMARK THIS IS A SIMULATION BOX" -static void xlate_atomname_pdb2gmx(char *name) +static void xlate_atomname_pdb2gmx(char* name) { int i, length; char temp; @@ -90,9 +89,9 @@ static void xlate_atomname_pdb2gmx(char *name) temp = name[0]; for (i = 1; i < length; i++) { - name[i-1] = name[i]; + name[i - 1] = name[i]; } - name[length-1] = temp; + name[length - 1] = temp; } } @@ -100,12 +99,12 @@ static void xlate_atomname_pdb2gmx(char *name) static std::string xlate_atomname_gmx2pdb(std::string name) { size_t length = name.size(); - if (length > 3 && std::isdigit(name[length-1])) + if (length > 3 && std::isdigit(name[length - 1])) { - char temp = name[length-1]; - for (size_t i = length-1; i > 0; --i) + char temp = name[length - 1]; + for (size_t i = length - 1; i > 0; --i) { - name[i] = name[i-1]; + name[i] = name[i - 1]; } name[0] = temp; } @@ -113,7 +112,7 @@ static std::string xlate_atomname_gmx2pdb(std::string name) } -void gmx_write_pdb_box(FILE *out, int ePBC, const matrix box) +void gmx_write_pdb_box(FILE* out, int ePBC, const matrix box) { real alpha, beta, gamma; @@ -127,25 +126,25 @@ void gmx_write_pdb_box(FILE *out, int ePBC, const matrix box) return; } - if (norm2(box[YY])*norm2(box[ZZ]) != 0) + if (norm2(box[YY]) * norm2(box[ZZ]) != 0) { - alpha = RAD2DEG*gmx_angle(box[YY], box[ZZ]); + alpha = RAD2DEG * gmx_angle(box[YY], box[ZZ]); } else { alpha = 90; } - if (norm2(box[XX])*norm2(box[ZZ]) != 0) + if (norm2(box[XX]) * norm2(box[ZZ]) != 0) { - beta = RAD2DEG*gmx_angle(box[XX], box[ZZ]); + beta = RAD2DEG * gmx_angle(box[XX], box[ZZ]); } else { - beta = 90; + beta = 90; } - if (norm2(box[XX])*norm2(box[YY]) != 0) + if (norm2(box[XX]) * norm2(box[YY]) != 0) { - gamma = RAD2DEG*gmx_angle(box[XX], box[YY]); + gamma = RAD2DEG * gmx_angle(box[XX], box[YY]); } else { @@ -154,24 +153,21 @@ void gmx_write_pdb_box(FILE *out, int ePBC, const matrix box) fprintf(out, "REMARK THIS IS A SIMULATION BOX\n"); if (ePBC != epbcSCREW) { - fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", - 10*norm(box[XX]), 10*norm(box[YY]), 10*norm(box[ZZ]), - alpha, beta, gamma, "P 1", 1); + fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", 10 * norm(box[XX]), + 10 * norm(box[YY]), 10 * norm(box[ZZ]), alpha, beta, gamma, "P 1", 1); } else { /* Double the a-vector length and write the correct space group */ - fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", - 20*norm(box[XX]), 10*norm(box[YY]), 10*norm(box[ZZ]), - alpha, beta, gamma, "P 21 1 1", 1); - + fprintf(out, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d\n", 20 * norm(box[XX]), + 10 * norm(box[YY]), 10 * norm(box[ZZ]), alpha, beta, gamma, "P 21 1 1", 1); } } -static void read_cryst1(char *line, int *ePBC, matrix box) +static void read_cryst1(char* line, int* ePBC, matrix box) { #define SG_SIZE 11 - char sa[12], sb[12], sc[12], sg[SG_SIZE+1], ident; + char sa[12], sb[12], sc[12], sg[SG_SIZE + 1], ident; double fa, fb, fc, alpha, beta, gamma, cosa, cosb, cosg, sing; int syma, symb, symc; int ePBC_file; @@ -181,16 +177,16 @@ static void read_cryst1(char *line, int *ePBC, matrix box) ePBC_file = -1; if (strlen(line) >= 55) { - strncpy(sg, line+55, SG_SIZE); + strncpy(sg, line + 55, SG_SIZE); sg[SG_SIZE] = '\0'; ident = ' '; syma = 0; symb = 0; symc = 0; sscanf(sg, "%c %d %d %d", &ident, &syma, &symb, &symc); - if (ident == 'P' && syma == 1 && symb <= 1 && symc <= 1) + if (ident == 'P' && syma == 1 && symb <= 1 && symc <= 1) { - fc = strtod(sc, nullptr)*0.1; + fc = strtod(sc, nullptr) * 0.1; ePBC_file = (fc > 0 ? epbcXYZ : epbcXY); } if (ident == 'P' && syma == 21 && symb == 1 && symc == 1) @@ -205,9 +201,9 @@ static void read_cryst1(char *line, int *ePBC, matrix box) if (box) { - fa = strtod(sa, nullptr)*0.1; - fb = strtod(sb, nullptr)*0.1; - fc = strtod(sc, nullptr)*0.1; + fa = strtod(sa, nullptr) * 0.1; + fb = strtod(sb, nullptr) * 0.1; + fc = strtod(sc, nullptr) * 0.1; if (ePBC_file == epbcSCREW) { fa *= 0.5; @@ -218,7 +214,7 @@ static void read_cryst1(char *line, int *ePBC, matrix box) { if (alpha != 90.0) { - cosa = std::cos(alpha*DEG2RAD); + cosa = std::cos(alpha * DEG2RAD); } else { @@ -226,7 +222,7 @@ static void read_cryst1(char *line, int *ePBC, matrix box) } if (beta != 90.0) { - cosb = std::cos(beta*DEG2RAD); + cosb = std::cos(beta * DEG2RAD); } else { @@ -234,20 +230,19 @@ static void read_cryst1(char *line, int *ePBC, matrix box) } if (gamma != 90.0) { - cosg = std::cos(gamma*DEG2RAD); - sing = std::sin(gamma*DEG2RAD); + cosg = std::cos(gamma * DEG2RAD); + sing = std::sin(gamma * DEG2RAD); } else { cosg = 0; sing = 1; } - box[YY][XX] = fb*cosg; - box[YY][YY] = fb*sing; - box[ZZ][XX] = fc*cosb; - box[ZZ][YY] = fc*(cosa - cosb*cosg)/sing; - box[ZZ][ZZ] = std::sqrt(fc*fc - - box[ZZ][XX]*box[ZZ][XX] - box[ZZ][YY]*box[ZZ][YY]); + box[YY][XX] = fb * cosg; + box[YY][YY] = fb * sing; + box[ZZ][XX] = fc * cosb; + box[ZZ][YY] = fc * (cosa - cosb * cosg) / sing; + box[ZZ][ZZ] = std::sqrt(fc * fc - box[ZZ][XX] * box[ZZ][XX] - box[ZZ][YY] * box[ZZ][YY]); } else { @@ -257,58 +252,53 @@ static void read_cryst1(char *line, int *ePBC, matrix box) } } -static int -gmx_fprintf_pqr_atomline(FILE * fp, - enum PDB_record record, - int atom_seq_number, - const char * atom_name, - const char * res_name, - char chain_id, - int res_seq_number, - real x, - real y, - real z, - real occupancy, - real b_factor) +static int gmx_fprintf_pqr_atomline(FILE* fp, + enum PDB_record record, + int atom_seq_number, + const char* atom_name, + const char* res_name, + char chain_id, + int res_seq_number, + real x, + real y, + real z, + real occupancy, + real b_factor) { GMX_RELEASE_ASSERT(record == epdbATOM || record == epdbHETATM, "Can only print PQR atom lines as ATOM or HETATM records"); /* Check atom name */ - GMX_RELEASE_ASSERT(atom_name != nullptr, - "Need atom information to print pqr"); + GMX_RELEASE_ASSERT(atom_name != nullptr, "Need atom information to print pqr"); /* Check residue name */ - GMX_RELEASE_ASSERT(res_name != nullptr, - "Need residue information to print pqr"); + GMX_RELEASE_ASSERT(res_name != nullptr, "Need residue information to print pqr"); /* Truncate integers so they fit */ atom_seq_number = atom_seq_number % 100000; res_seq_number = res_seq_number % 10000; - int n = fprintf(fp, - "%-6s%5d %-4.4s%4.4s%c%4d %8.3f %8.3f %8.3f %6.2f %6.2f\n", - pdbtp[record], - atom_seq_number, - atom_name, - res_name, - chain_id, - res_seq_number, - x, y, z, - occupancy, - b_factor); + int n = fprintf(fp, "%-6s%5d %-4.4s%4.4s%c%4d %8.3f %8.3f %8.3f %6.2f %6.2f\n", pdbtp[record], + atom_seq_number, atom_name, res_name, chain_id, res_seq_number, x, y, z, + occupancy, b_factor); return n; } -void write_pdbfile_indexed(FILE *out, const char *title, - const t_atoms *atoms, const rvec x[], - int ePBC, const matrix box, char chainid, - int model_nr, int nindex, const int index[], - gmx_conect conect, - bool usePqrFormat) +void write_pdbfile_indexed(FILE* out, + const char* title, + const t_atoms* atoms, + const rvec x[], + int ePBC, + const matrix box, + char chainid, + int model_nr, + int nindex, + const int index[], + gmx_conect conect, + bool usePqrFormat) { - gmx_conect_t *gc = static_cast(conect); + gmx_conect_t* gc = static_cast(conect); enum PDB_record type; char altloc; real occup, bfac; @@ -316,7 +306,7 @@ void write_pdbfile_indexed(FILE *out, const char *title, fprintf(out, "TITLE %s\n", (title && title[0]) ? title : gmx::bromacs().c_str()); - if (box && ( (norm2(box[XX]) != 0.0F) || (norm2(box[YY]) != 0.0F) || (norm2(box[ZZ]) != 0.0F) ) ) + if (box && ((norm2(box[XX]) != 0.0F) || (norm2(box[YY]) != 0.0F) || (norm2(box[ZZ]) != 0.0F))) { gmx_write_pdb_box(out, ePBC, box); } @@ -328,7 +318,7 @@ void write_pdbfile_indexed(FILE *out, const char *title, bOccup = TRUE; for (int ii = 0; (ii < nindex) && bOccup; ii++) { - int i = index[ii]; + int i = index[ii]; bOccup = bOccup && (atoms->pdbinfo[i].occup == 0.0); } } @@ -342,13 +332,13 @@ void write_pdbfile_indexed(FILE *out, const char *title, ResidueType rt; for (int ii = 0; ii < nindex; ii++) { - int i = index[ii]; - int resind = atoms->atom[i].resind; - std::string resnm = *atoms->resinfo[resind].name; - std::string nm = *atoms->atomname[i]; + int i = index[ii]; + int resind = atoms->atom[i].resind; + std::string resnm = *atoms->resinfo[resind].name; + std::string nm = *atoms->atomname[i]; /* rename HG12 to 2HG1, etc. */ - nm = xlate_atomname_gmx2pdb(nm); + nm = xlate_atomname_gmx2pdb(nm); int resnr = atoms->resinfo[resind].nr; unsigned char resic = atoms->resinfo[resind].ic; unsigned char ch; @@ -388,42 +378,22 @@ void write_pdbfile_indexed(FILE *out, const char *title, bfac = pdbinfo.bfac; if (!usePqrFormat) { - gmx_fprintf_pdb_atomline(out, - type, - i+1, - nm.c_str(), - altloc, - resnm.c_str(), - ch, - resnr, - resic, - 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], - occup, - bfac, - atoms->atom[i].elem); + gmx_fprintf_pdb_atomline(out, type, i + 1, nm.c_str(), altloc, resnm.c_str(), ch, resnr, + resic, 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], occup, + bfac, atoms->atom[i].elem); if (atoms->pdbinfo && atoms->pdbinfo[i].bAnisotropic) { - fprintf(out, "ANISOU%5d %-4.4s%4.4s%c%4d%c %7d%7d%7d%7d%7d%7d\n", - (i+1)%100000, nm.c_str(), resnm.c_str(), ch, resnr, - (resic == '\0') ? ' ' : resic, - atoms->pdbinfo[i].uij[0], atoms->pdbinfo[i].uij[1], - atoms->pdbinfo[i].uij[2], atoms->pdbinfo[i].uij[3], - atoms->pdbinfo[i].uij[4], atoms->pdbinfo[i].uij[5]); + fprintf(out, "ANISOU%5d %-4.4s%4.4s%c%4d%c %7d%7d%7d%7d%7d%7d\n", (i + 1) % 100000, + nm.c_str(), resnm.c_str(), ch, resnr, (resic == '\0') ? ' ' : resic, + atoms->pdbinfo[i].uij[0], atoms->pdbinfo[i].uij[1], atoms->pdbinfo[i].uij[2], + atoms->pdbinfo[i].uij[3], atoms->pdbinfo[i].uij[4], atoms->pdbinfo[i].uij[5]); } } else { - gmx_fprintf_pqr_atomline(out, - type, - i+1, - nm.c_str(), - resnm.c_str(), - ch, - resnr, - 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], - occup, - bfac); + gmx_fprintf_pqr_atomline(out, type, i + 1, nm.c_str(), resnm.c_str(), ch, resnr, + 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], occup, bfac); } } @@ -435,13 +405,20 @@ void write_pdbfile_indexed(FILE *out, const char *title, /* Write conect records */ for (int i = 0; (i < gc->nconect); i++) { - fprintf(out, "CONECT%5d%5d\n", gc->conect[i].ai+1, gc->conect[i].aj+1); + fprintf(out, "CONECT%5d%5d\n", gc->conect[i].ai + 1, gc->conect[i].aj + 1); } } } -void write_pdbfile(FILE *out, const char *title, const t_atoms *atoms, const rvec x[], - int ePBC, const matrix box, char chainid, int model_nr, gmx_conect conect) +void write_pdbfile(FILE* out, + const char* title, + const t_atoms* atoms, + const rvec x[], + int ePBC, + const matrix box, + char chainid, + int model_nr, + gmx_conect conect) { int i, *index; @@ -450,12 +427,12 @@ void write_pdbfile(FILE *out, const char *title, const t_atoms *atoms, const rve { index[i] = i; } - write_pdbfile_indexed(out, title, atoms, x, ePBC, box, chainid, model_nr, - atoms->nr, index, conect, false); + write_pdbfile_indexed(out, title, atoms, x, ePBC, box, chainid, model_nr, atoms->nr, index, + conect, false); sfree(index); } -static int line2type(const char *line) +static int line2type(const char* line) { int k; char type[8]; @@ -477,7 +454,7 @@ static int line2type(const char *line) return k; } -static void read_anisou(char line[], int natom, t_atoms *atoms) +static void read_anisou(char line[], int natom, t_atoms* atoms) { int i, j, k, atomnr; char nc = '\0'; @@ -503,23 +480,20 @@ static void read_anisou(char line[], int natom, t_atoms *atoms) /* Search backwards for number and name only */ atomnr = std::strtol(anr, nullptr, 10); - for (i = natom-1; (i >= 0); i--) + for (i = natom - 1; (i >= 0); i--) { - if ((std::strcmp(anm, *(atoms->atomname[i])) == 0) && - (atomnr == atoms->pdbinfo[i].atomnr)) + if ((std::strcmp(anm, *(atoms->atomname[i])) == 0) && (atomnr == atoms->pdbinfo[i].atomnr)) { break; } } if (i < 0) { - fprintf(stderr, "Skipping ANISOU record (atom %s %d not found)\n", - anm, atomnr); + fprintf(stderr, "Skipping ANISOU record (atom %s %d not found)\n", anm, atomnr); } else { - if (sscanf(line+29, "%d%d%d%d%d%d", - &atoms->pdbinfo[i].uij[U11], &atoms->pdbinfo[i].uij[U22], + if (sscanf(line + 29, "%d%d%d%d%d%d", &atoms->pdbinfo[i].uij[U11], &atoms->pdbinfo[i].uij[U22], &atoms->pdbinfo[i].uij[U33], &atoms->pdbinfo[i].uij[U12], &atoms->pdbinfo[i].uij[U13], &atoms->pdbinfo[i].uij[U23]) == 6) @@ -534,7 +508,7 @@ static void read_anisou(char line[], int natom, t_atoms *atoms) } } -void get_pdb_atomnumber(const t_atoms *atoms, AtomProperties *aps) +void get_pdb_atomnumber(const t_atoms* atoms, AtomProperties* aps) { int i, atomnumber, len; size_t k; @@ -551,7 +525,7 @@ void get_pdb_atomnumber(const t_atoms *atoms, AtomProperties *aps) std::strcpy(anm, atoms->pdbinfo[i].atomnm); std::strcpy(anm_copy, atoms->pdbinfo[i].atomnm); bool atomNumberSet = false; - len = strlen(anm); + len = strlen(anm); if ((anm[0] != ' ') && ((len <= 2) || !std::isdigit(anm[2]))) { anm_copy[2] = nc; @@ -589,11 +563,10 @@ void get_pdb_atomnumber(const t_atoms *atoms, AtomProperties *aps) if (atomNumberSet) { atoms->atom[i].atomnumber = atomnumber; - buf = aps->elementFromAtomNumber(atomnumber); + buf = aps->elementFromAtomNumber(atomnumber); if (debug) { - fprintf(debug, "Atomnumber for atom '%s' is %d\n", - anm, atomnumber); + fprintf(debug, "Atomnumber for atom '%s' is %d\n", anm, atomnumber); } } buf.resize(3); @@ -601,11 +574,10 @@ void get_pdb_atomnumber(const t_atoms *atoms, AtomProperties *aps) } } -static int read_atom(t_symtab *symtab, - const char line[], int type, int natom, - t_atoms *atoms, rvec x[], int chainnum, gmx_bool bChange) +static int +read_atom(t_symtab* symtab, const char line[], int type, int natom, t_atoms* atoms, rvec x[], int chainnum, gmx_bool bChange) { - t_atom *atomn; + t_atom* atomn; int j, k; char nc = '\0'; char anr[12], anm[12], anm_copy[12], altloc, resnm[12], rnr[12], elem[3]; @@ -616,8 +588,7 @@ static int read_atom(t_symtab *symtab, if (natom >= atoms->nr) { - gmx_fatal(FARGS, "\nFound more atoms (%d) in pdb file than expected (%d)", - natom+1, atoms->nr); + gmx_fatal(FARGS, "\nFound more atoms (%d) in pdb file than expected (%d)", natom + 1, atoms->nr); } /* Skip over type */ @@ -658,7 +629,7 @@ static int read_atom(t_symtab *symtab, trim(rnr); resnr = std::strtol(rnr, nullptr, 10); resic = line[j]; - j += 4; + j += 4; /* X,Y,Z Coordinate */ for (k = 0; (k < 8); k++, j++) @@ -705,10 +676,9 @@ static int read_atom(t_symtab *symtab, if (atoms->atom) { atomn = &(atoms->atom[natom]); - if ((natom == 0) || - atoms->resinfo[atoms->atom[natom-1].resind].nr != resnr || - atoms->resinfo[atoms->atom[natom-1].resind].ic != resic || - (strcmp(*atoms->resinfo[atoms->atom[natom-1].resind].name, resnm) != 0)) + if ((natom == 0) || atoms->resinfo[atoms->atom[natom - 1].resind].nr != resnr + || atoms->resinfo[atoms->atom[natom - 1].resind].ic != resic + || (strcmp(*atoms->resinfo[atoms->atom[natom - 1].resind].name, resnm) != 0)) { if (natom == 0) { @@ -716,14 +686,14 @@ static int read_atom(t_symtab *symtab, } else { - atomn->resind = atoms->atom[natom-1].resind + 1; + atomn->resind = atoms->atom[natom - 1].resind + 1; } atoms->nres = atomn->resind + 1; t_atoms_set_resinfo(atoms, natom, symtab, resnm, resnr, resic, chainnum, chainid); } else { - atomn->resind = atoms->atom[natom-1].resind; + atomn->resind = atoms->atom[natom - 1].resind; } if (bChange) { @@ -735,9 +705,9 @@ static int read_atom(t_symtab *symtab, atomn->atomnumber = atomnumber; strncpy(atomn->elem, elem, 4); } - x[natom][XX] = strtod(xc, nullptr)*0.1; - x[natom][YY] = strtod(yc, nullptr)*0.1; - x[natom][ZZ] = strtod(zc, nullptr)*0.1; + x[natom][XX] = strtod(xc, nullptr) * 0.1; + x[natom][YY] = strtod(yc, nullptr) * 0.1; + x[natom][ZZ] = strtod(zc, nullptr) * 0.1; if (atoms->pdbinfo) { atoms->pdbinfo[natom].type = type; @@ -752,7 +722,7 @@ static int read_atom(t_symtab *symtab, return natom; } -gmx_bool is_hydrogen(const char *nm) +gmx_bool is_hydrogen(const char* nm) { char buf[30]; @@ -770,19 +740,19 @@ gmx_bool is_hydrogen(const char *nm) return FALSE; } -gmx_bool is_dummymass(const char *nm) +gmx_bool is_dummymass(const char* nm) { char buf[30]; std::strcpy(buf, nm); trim(buf); - return (buf[0] == 'M') && (std::isdigit(buf[strlen(buf)-1]) != 0); + return (buf[0] == 'M') && (std::isdigit(buf[strlen(buf) - 1]) != 0); } -static void gmx_conect_addline(gmx_conect_t *con, char *line) +static void gmx_conect_addline(gmx_conect_t* con, char* line) { - int n, ai, aj; + int n, ai, aj; std::string form2 = "%%*s"; std::string format = form2 + "%%d"; @@ -796,29 +766,27 @@ static void gmx_conect_addline(gmx_conect_t *con, char *line) if (n == 1) { srenew(con->conect, ++con->nconect); - con->conect[con->nconect-1].ai = ai-1; - con->conect[con->nconect-1].aj = aj-1; + con->conect[con->nconect - 1].ai = ai - 1; + con->conect[con->nconect - 1].aj = aj - 1; } - } - while (n == 1); + } while (n == 1); } } -void gmx_conect_dump(FILE *fp, gmx_conect conect) +void gmx_conect_dump(FILE* fp, gmx_conect conect) { - gmx_conect_t *gc = static_cast(conect); + gmx_conect_t* gc = static_cast(conect); int i; for (i = 0; (i < gc->nconect); i++) { - fprintf(fp, "%6s%5d%5d\n", "CONECT", - gc->conect[i].ai+1, gc->conect[i].aj+1); + fprintf(fp, "%6s%5d%5d\n", "CONECT", gc->conect[i].ai + 1, gc->conect[i].aj + 1); } } gmx_conect gmx_conect_init() { - gmx_conect_t *gc; + gmx_conect_t* gc; snew(gc, 1); @@ -827,14 +795,14 @@ gmx_conect gmx_conect_init() void gmx_conect_done(gmx_conect conect) { - gmx_conect_t *gc = conect; + gmx_conect_t* gc = conect; sfree(gc->conect); } gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj) { - gmx_conect_t *gc = conect; + gmx_conect_t* gc = conect; int i; /* if (!gc->bSorted) @@ -842,10 +810,8 @@ gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj) for (i = 0; (i < gc->nconect); i++) { - if (((gc->conect[i].ai == ai) && - (gc->conect[i].aj == aj)) || - ((gc->conect[i].aj == ai) && - (gc->conect[i].ai == aj))) + if (((gc->conect[i].ai == ai) && (gc->conect[i].aj == aj)) + || ((gc->conect[i].aj == ai) && (gc->conect[i].ai == aj))) { return TRUE; } @@ -855,7 +821,7 @@ gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj) void gmx_conect_add(gmx_conect conect, int ai, int aj) { - gmx_conect_t *gc = static_cast(conect); + gmx_conect_t* gc = static_cast(conect); /* if (!gc->bSorted) sort_conect(gc);*/ @@ -863,23 +829,30 @@ void gmx_conect_add(gmx_conect conect, int ai, int aj) if (!gmx_conect_exist(conect, ai, aj)) { srenew(gc->conect, ++gc->nconect); - gc->conect[gc->nconect-1].ai = ai; - gc->conect[gc->nconect-1].aj = aj; + gc->conect[gc->nconect - 1].ai = ai; + gc->conect[gc->nconect - 1].aj = aj; } } -int read_pdbfile(FILE *in, char *title, int *model_nr, - t_atoms *atoms, t_symtab *symtab, rvec x[], int *ePBC, - matrix box, gmx_bool bChange, gmx_conect conect) +int read_pdbfile(FILE* in, + char* title, + int* model_nr, + t_atoms* atoms, + t_symtab* symtab, + rvec x[], + int* ePBC, + matrix box, + gmx_bool bChange, + gmx_conect conect) { - gmx_conect_t *gc = conect; + gmx_conect_t* gc = conect; gmx_bool bCOMPND; gmx_bool bConnWarn = FALSE; - char line[STRLEN+1]; + char line[STRLEN + 1]; int line_type; - char *c, *d; + char * c, *d; int natom, chainnum; - gmx_bool bStop = FALSE; + gmx_bool bStop = FALSE; if (ePBC) { @@ -919,15 +892,13 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, } break; - case epdbCRYST1: - read_cryst1(line, ePBC, box); - break; + case epdbCRYST1: read_cryst1(line, ePBC, box); break; case epdbTITLE: case epdbHEADER: if (std::strlen(line) > 6) { - c = line+6; + c = line + 6; /* skip HEADER or TITLE and spaces */ while (c[0] != ' ') { @@ -951,9 +922,9 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, break; case epdbCOMPND: - if ((!std::strstr(line, ": ")) || (std::strstr(line+6, "MOLECULE:"))) + if ((!std::strstr(line, ": ")) || (std::strstr(line + 6, "MOLECULE:"))) { - if (!(c = std::strstr(line+6, "MOLECULE:")) ) + if (!(c = std::strstr(line + 6, "MOLECULE:"))) { c = line; } @@ -970,7 +941,7 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, d = strstr(c, " "); if (d) { - while ( (d[-1] == ';') && d > c) + while ((d[-1] == ';') && d > c) { d--; } @@ -992,9 +963,7 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, } break; - case epdbTER: - chainnum++; - break; + case epdbTER: chainnum++; break; case epdbMODEL: if (model_nr) @@ -1003,9 +972,7 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, } break; - case epdbENDMDL: - bStop = TRUE; - break; + case epdbENDMDL: bStop = TRUE; break; case epdbCONECT: if (gc) { @@ -1018,15 +985,14 @@ int read_pdbfile(FILE *in, char *title, int *model_nr, } break; - default: - break; + default: break; } } return natom; } -void get_pdb_coordnum(FILE *in, int *natoms) +void get_pdb_coordnum(FILE* in, int* natoms) { char line[STRLEN]; @@ -1044,11 +1010,9 @@ void get_pdb_coordnum(FILE *in, int *natoms) } } -void gmx_pdb_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], int *ePBC, matrix box) +void gmx_pdb_read_conf(const char* infile, t_symtab* symtab, char** name, t_atoms* atoms, rvec x[], int* ePBC, matrix box) { - FILE *in = gmx_fio_fopen(infile, "r"); + FILE* in = gmx_fio_fopen(infile, "r"); char title[STRLEN]; read_pdbfile(in, title, nullptr, atoms, symtab, x, ePBC, box, TRUE, nullptr); if (name != nullptr) @@ -1058,44 +1022,42 @@ void gmx_pdb_read_conf(const char *infile, gmx_fio_fclose(in); } -gmx_conect gmx_conect_generate(const t_topology *top) +gmx_conect gmx_conect_generate(const t_topology* top) { int f, i; gmx_conect gc; /* Fill the conect records */ - gc = gmx_conect_init(); + gc = gmx_conect_init(); for (f = 0; (f < F_NRE); f++) { if (IS_CHEMBOND(f)) { - for (i = 0; (i < top->idef.il[f].nr); i += interaction_function[f].nratoms+1) + for (i = 0; (i < top->idef.il[f].nr); i += interaction_function[f].nratoms + 1) { - gmx_conect_add(gc, top->idef.il[f].iatoms[i+1], - top->idef.il[f].iatoms[i+2]); + gmx_conect_add(gc, top->idef.il[f].iatoms[i + 1], top->idef.il[f].iatoms[i + 2]); } } } return gc; } -int -gmx_fprintf_pdb_atomline(FILE * fp, - enum PDB_record record, - int atom_seq_number, - const char * atom_name, - char alternate_location, - const char * res_name, - char chain_id, - int res_seq_number, - char res_insertion_code, - real x, - real y, - real z, - real occupancy, - real b_factor, - const char * element) +int gmx_fprintf_pdb_atomline(FILE* fp, + enum PDB_record record, + int atom_seq_number, + const char* atom_name, + char alternate_location, + const char* res_name, + char chain_id, + int res_seq_number, + char res_insertion_code, + real x, + real y, + real z, + real occupancy, + real b_factor, + const char* element) { char tmp_atomname[6], tmp_resname[6]; gmx_bool start_name_in_col13; @@ -1112,7 +1074,8 @@ gmx_fprintf_pdb_atomline(FILE * fp, /* If the atom name is an element name with two chars, it should start already in column 13. * Otherwise it should start in column 14, unless the name length is 4 chars. */ - if ( (element != nullptr) && (std::strlen(element) >= 2) && (gmx_strncasecmp(atom_name, element, 2) == 0) ) + if ((element != nullptr) && (std::strlen(element) >= 2) + && (gmx_strncasecmp(atom_name, element, 2) == 0)) { start_name_in_col13 = TRUE; } @@ -1143,19 +1106,9 @@ gmx_fprintf_pdb_atomline(FILE * fp, atom_seq_number = atom_seq_number % 100000; res_seq_number = res_seq_number % 10000; - n = fprintf(fp, - "%-6s%5d %-4.4s%c%4.4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %2s\n", - pdbtp[record], - atom_seq_number, - tmp_atomname, - alternate_location, - tmp_resname, - chain_id, - res_seq_number, - res_insertion_code, - x, y, z, - occupancy, - b_factor, + n = fprintf(fp, "%-6s%5d %-4.4s%c%4.4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %2s\n", + pdbtp[record], atom_seq_number, tmp_atomname, alternate_location, tmp_resname, + chain_id, res_seq_number, res_insertion_code, x, y, z, occupancy, b_factor, (element != nullptr) ? element : ""); return n; diff --git a/src/gromacs/fileio/pdbio.h b/src/gromacs/fileio/pdbio.h index 98badfc6a7..0d9ea634b6 100644 --- a/src/gromacs/fileio/pdbio.h +++ b/src/gromacs/fileio/pdbio.h @@ -50,54 +50,72 @@ struct t_atoms; struct t_symtab; struct t_topology; -typedef struct gmx_conect_t *gmx_conect; +typedef struct gmx_conect_t* gmx_conect; /* Write a PDB line with an ATOM or HETATM record directly to a file pointer. * * Returns the number of characters printed. */ -int -gmx_fprintf_pdb_atomline(FILE * fp, - enum PDB_record record, - int atom_seq_number, - const char * atom_name, - char alternate_location, - const char * res_name, - char chain_id, - int res_seq_number, - char res_insertion_code, - real x, - real y, - real z, - real occupancy, - real b_factor, - const char * element); +int gmx_fprintf_pdb_atomline(FILE* fp, + enum PDB_record record, + int atom_seq_number, + const char* atom_name, + char alternate_location, + const char* res_name, + char chain_id, + int res_seq_number, + char res_insertion_code, + real x, + real y, + real z, + real occupancy, + real b_factor, + const char* element); /* Enumerated value for indexing an uij entry (anisotropic temperature factors) */ -enum { - U11, U22, U33, U12, U13, U23 +enum +{ + U11, + U22, + U33, + U12, + U13, + U23 }; void pdb_use_ter(gmx_bool bSet); /* set read_pdbatoms to read upto 'TER' or 'ENDMDL' (default, bSet=FALSE). This function is fundamentally broken as far as thread-safety is concerned.*/ -void gmx_write_pdb_box(FILE *out, int ePBC, const matrix box); +void gmx_write_pdb_box(FILE* out, int ePBC, const matrix box); /* write the box in the CRYST1 record, * with ePBC=-1 the pbc is guessed from the box * This function is fundamentally broken as far as thread-safety is concerned. */ -void write_pdbfile_indexed(FILE *out, const char *title, const t_atoms *atoms, - const rvec x[], int ePBC, const matrix box, char chain, - int model_nr, int nindex, const int index[], - gmx_conect conect, - bool usePqrFormat); +void write_pdbfile_indexed(FILE* out, + const char* title, + const t_atoms* atoms, + const rvec x[], + int ePBC, + const matrix box, + char chain, + int model_nr, + int nindex, + const int index[], + gmx_conect conect, + bool usePqrFormat); /* REALLY low level */ -void write_pdbfile(FILE *out, const char *title, const t_atoms *atoms, - const rvec x[], int ePBC, const matrix box, char chain, - int model_nr, gmx_conect conect); +void write_pdbfile(FILE* out, + const char* title, + const t_atoms* atoms, + const rvec x[], + int ePBC, + const matrix box, + char chain, + int model_nr, + gmx_conect conect); /* Low level pdb file writing routine. * * ONLY FOR SPECIAL PURPOSES, @@ -111,37 +129,41 @@ void write_pdbfile(FILE *out, const char *title, const t_atoms *atoms, * which may be useful for visualization purposes. */ -void get_pdb_atomnumber(const t_atoms *atoms, AtomProperties *aps); +void get_pdb_atomnumber(const t_atoms* atoms, AtomProperties* aps); /* Routine to extract atomic numbers from the atom names */ -int read_pdbfile(FILE *in, char *title, int *model_nr, - struct t_atoms *atoms, struct t_symtab *symtab, - rvec x[], int *ePBC, matrix box, - gmx_bool bChange, gmx_conect conect); +int read_pdbfile(FILE* in, + char* title, + int* model_nr, + struct t_atoms* atoms, + struct t_symtab* symtab, + rvec x[], + int* ePBC, + matrix box, + gmx_bool bChange, + gmx_conect conect); /* Function returns number of atoms found. * ePBC and gmx_conect structure may be NULL. */ -void gmx_pdb_read_conf(const char *infile, - t_symtab *symtab, char **name, t_atoms *atoms, - rvec x[], int *ePBC, matrix box); +void gmx_pdb_read_conf(const char* infile, t_symtab* symtab, char** name, t_atoms* atoms, rvec x[], int* ePBC, matrix box); /* Read a pdb file and extract ATOM and HETATM fields. * Read a box from the CRYST1 line, return 0 box when no CRYST1 is found. * ePBC may be NULL. * * If name is not nullptr, gmx_strdup the title string into it. */ -void get_pdb_coordnum(FILE *in, int *natoms); +void get_pdb_coordnum(FILE* in, int* natoms); /* Read a pdb file and count the ATOM and HETATM fields. */ -gmx_bool is_hydrogen(const char *nm); +gmx_bool is_hydrogen(const char* nm); /* Return whether atom nm is a hydrogen */ -gmx_bool is_dummymass(const char *nm); +gmx_bool is_dummymass(const char* nm); /* Return whether atom nm is a dummy mass */ /* Routines to handle CONECT records if they have been read in */ -void gmx_conect_dump(FILE *fp, gmx_conect conect); +void gmx_conect_dump(FILE* fp, gmx_conect conect); gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj); /* Return TRUE if there is a conection between the atoms */ @@ -149,7 +171,7 @@ gmx_bool gmx_conect_exist(gmx_conect conect, int ai, int aj); void gmx_conect_add(gmx_conect conect, int ai, int aj); /* Add a connection between ai and aj (numbered from 0 to natom-1) */ -gmx_conect gmx_conect_generate(const t_topology *top); +gmx_conect gmx_conect_generate(const t_topology* top); /* Generate a conect structure from a topology */ gmx_conect gmx_conect_init(); @@ -158,4 +180,4 @@ gmx_conect gmx_conect_init(); void gmx_conect_done(gmx_conect gc); /* Free memory */ -#endif /* GMX_FILEIO_PDBIO_H */ +#endif /* GMX_FILEIO_PDBIO_H */ diff --git a/src/gromacs/fileio/readinp.cpp b/src/gromacs/fileio/readinp.cpp index 743fd32555..6c343b2143 100644 --- a/src/gromacs/fileio/readinp.cpp +++ b/src/gromacs/fileio/readinp.cpp @@ -56,9 +56,7 @@ #include "gromacs/utility/textreader.h" #include "gromacs/utility/textwriter.h" -std::vector -read_inpfile(gmx::TextInputStream *stream, const char *fn, - warninp_t wi) +std::vector read_inpfile(gmx::TextInputStream* stream, const char* fn, warninp_t wi) { std::vector inp; @@ -85,7 +83,9 @@ read_inpfile(gmx::TextInputStream *stream, const char *fn, auto tokens = gmx::splitAndTrimDelimitedString(line, '='); if (tokens.size() < 2) { - auto message = gmx::formatString("No '=' to separate .mdp parameter key and value was found on line:\n'%s'", line.c_str()); + auto message = gmx::formatString( + "No '=' to separate .mdp parameter key and value was found on line:\n'%s'", + line.c_str()); warning_error(wi, message); continue; } @@ -104,13 +104,16 @@ read_inpfile(gmx::TextInputStream *stream, const char *fn, GMX_RELEASE_ASSERT(tokens.size() == 2, "Must have tokens for key and value"); if (tokens[0].empty() && tokens[1].empty()) { - auto message = gmx::formatString("No .mdp parameter name or value was found on line:\n'%s'", line.c_str()); + auto message = gmx::formatString( + "No .mdp parameter name or value was found on line:\n'%s'", line.c_str()); warning_error(wi, message); continue; } if (tokens[0].empty()) { - auto message = gmx::formatString("No .mdp parameter name was found on the left-hand side of '=' on line:\n'%s'", line.c_str()); + auto message = gmx::formatString( + "No .mdp parameter name was found on the left-hand side of '=' on line:\n'%s'", + line.c_str()); warning_error(wi, message); continue; } @@ -129,13 +132,11 @@ read_inpfile(gmx::TextInputStream *stream, const char *fn, if (found_index == -1) { /* add a new item */ - inp.emplace_back(0, 1, false, false, false, - tokens[0], tokens[1]); + inp.emplace_back(0, 1, false, false, false, tokens[0], tokens[1]); } else { - auto message = gmx::formatString("Parameter \"%s\" doubly defined\n", - tokens[0].c_str()); + auto message = gmx::formatString("Parameter \"%s\" doubly defined\n", tokens[0].c_str()); warning_error(wi, message); } } @@ -147,8 +148,7 @@ read_inpfile(gmx::TextInputStream *stream, const char *fn, if (debug) { - fprintf(debug, "Done reading MDP file, there were %zu entries in there\n", - inp.size()); + fprintf(debug, "Done reading MDP file, there were %zu entries in there\n", inp.size()); } return inp; @@ -156,9 +156,9 @@ read_inpfile(gmx::TextInputStream *stream, const char *fn, gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(gmx::ArrayRef inp) { - gmx::KeyValueTreeBuilder builder; - auto root = builder.rootObject(); - for (auto &local : inp) + gmx::KeyValueTreeBuilder builder; + auto root = builder.rootObject(); + for (auto& local : inp) { root.addValue(local.name_, !local.value_.empty() ? local.value_ : ""); } @@ -168,23 +168,20 @@ gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(gmx::ArrayRef *inp) +static void sort_inp(std::vector* inp) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; int mm; mm = -1; - for (const auto &local : inpRef) + for (const auto& local : inpRef) { mm = std::max(mm, local.count_); } - for (auto &local : inpRef) + for (auto& local : inpRef) { if (local.count_ == 0) { @@ -194,10 +191,12 @@ static void sort_inp(std::vector *inp) std::sort(inpRef.begin(), inpRef.end(), inp_comp()); } -void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector *inp, - gmx_bool bHaltOnUnknown, - WriteMdpHeader writeHeader, - warninp_t wi) +void write_inpfile(gmx::TextOutputStream* stream, + const char* fn, + std::vector* inp, + gmx_bool bHaltOnUnknown, + WriteMdpHeader writeHeader, + warninp_t wi) { using gmx::formatString; @@ -213,11 +212,9 @@ void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector 2 && local.name_[1] == ';')) @@ -226,13 +223,14 @@ void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector inp, const char *old_entry, const char *new_entry) +void replace_inp_entry(gmx::ArrayRef inp, const char* old_entry, const char* new_entry) { - for (auto &local : inp) + for (auto& local : inp) { if (gmx_strcasecmp_min(old_entry, local.name_.c_str()) == 0) { if (new_entry) { - fprintf(stderr, "Replacing old mdp entry '%s' by '%s'\n", - local.name_.c_str(), new_entry); + fprintf(stderr, "Replacing old mdp entry '%s' by '%s'\n", local.name_.c_str(), new_entry); int foundIndex = search_einp(inp, new_entry); if (foundIndex >= 0) { - gmx_fatal(FARGS, "A parameter is present with both the old name '%s' and the new name '%s'.", local.name_.c_str(), inp[foundIndex].name_.c_str()); + gmx_fatal(FARGS, + "A parameter is present with both the old name '%s' and the new name " + "'%s'.", + local.name_.c_str(), inp[foundIndex].name_.c_str()); } local.name_.assign(new_entry); } else { - fprintf(stderr, "Ignoring obsolete mdp entry '%s'\n", - local.name_.c_str()); + fprintf(stderr, "Ignoring obsolete mdp entry '%s'\n", local.name_.c_str()); local.bObsolete_ = TRUE; } } } } -int search_einp(gmx::ArrayRef inp, const char *name) +int search_einp(gmx::ArrayRef inp, const char* name) { if (inp.empty()) { @@ -292,9 +291,9 @@ int search_einp(gmx::ArrayRef inp, const char *name) return -1; } -void mark_einp_set(gmx::ArrayRef inp, const char *name) +void mark_einp_set(gmx::ArrayRef inp, const char* name) { - int i = search_einp(inp, name); + int i = search_einp(inp, name); if (i != -1) { inp[i].count_ = inp.front().inp_count_++; @@ -305,20 +304,19 @@ void mark_einp_set(gmx::ArrayRef inp, const char *name) } } -static int get_einp(std::vector *inp, const char *name) +static int get_einp(std::vector* inp, const char* name) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; bool notfound = false; - int i = search_einp(inpRef, name); + int i = search_einp(inpRef, name); if (i == -1) { notfound = true; - inpRef.emplace_back(0, 0, false, true, false, - name, ""); + inpRef.emplace_back(0, 0, false, true, false, name, ""); i = inpRef.size() - 1; - if (inpRef.size() == 1) + if (inpRef.size() == 1) { inpRef.front().inp_count_ = 1; } @@ -341,13 +339,12 @@ static int get_einp(std::vector *inp, const char *name) } /* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */ -int get_eint(std::vector *inp, const char *name, int def, - warninp_t wi) +int get_eint(std::vector* inp, const char* name, int def, warninp_t wi) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; char buf[32], *ptr, warn_buf[STRLEN]; - int ii = get_einp(inp, name); + int ii = get_einp(inp, name); if (ii == -1) { @@ -361,7 +358,10 @@ int get_eint(std::vector *inp, const char *name, int def, int ret = std::strtol(inpRef[ii].value_.c_str(), &ptr, 10); if (*ptr != '\0') { - sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); + sprintf(warn_buf, + "Right hand side '%s' for parameter '%s' in parameter file is not an integer " + "value\n", + inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); warning_error(wi, warn_buf); } @@ -369,21 +369,18 @@ int get_eint(std::vector *inp, const char *name, int def, } } -int get_eint(std::vector *inp, const std::string &name, int def, - warninp_t wi) +int get_eint(std::vector* inp, const std::string& name, int def, warninp_t wi) { return get_eint(inp, name.c_str(), def, wi); } /* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */ -int64_t get_eint64(std::vector *inp, - const char *name, int64_t def, - warninp_t wi) +int64_t get_eint64(std::vector* inp, const char* name, int64_t def, warninp_t wi) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; char buf[32], *ptr, warn_buf[STRLEN]; - int ii = get_einp(inp, name); + int ii = get_einp(inp, name); if (ii == -1) { @@ -397,7 +394,10 @@ int64_t get_eint64(std::vector *inp, int64_t ret = str_to_int64_t(inpRef[ii].value_.c_str(), &ptr); if (*ptr != '\0') { - sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); + sprintf(warn_buf, + "Right hand side '%s' for parameter '%s' in parameter file is not an integer " + "value\n", + inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); warning_error(wi, warn_buf); } @@ -405,21 +405,18 @@ int64_t get_eint64(std::vector *inp, } } -int64_t get_eint64(std::vector *inp, - const std::string &name, int64_t def, - warninp_t wi) +int64_t get_eint64(std::vector* inp, const std::string& name, int64_t def, warninp_t wi) { return get_eint64(inp, name.c_str(), def, wi); } /* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */ -double get_ereal(std::vector *inp, const char *name, double def, - warninp_t wi) +double get_ereal(std::vector* inp, const char* name, double def, warninp_t wi) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; char buf[32], *ptr, warn_buf[STRLEN]; - int ii = get_einp(inp, name); + int ii = get_einp(inp, name); if (ii == -1) { @@ -433,7 +430,10 @@ double get_ereal(std::vector *inp, const char *name, double def, double ret = strtod(inpRef[ii].value_.c_str(), &ptr); if (*ptr != '\0') { - sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not a real value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); + sprintf(warn_buf, + "Right hand side '%s' for parameter '%s' in parameter file is not a real " + "value\n", + inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str()); warning_error(wi, warn_buf); } @@ -441,19 +441,18 @@ double get_ereal(std::vector *inp, const char *name, double def, } } -double get_ereal(std::vector *inp, const std::string &name, double def, - warninp_t wi) +double get_ereal(std::vector* inp, const std::string& name, double def, warninp_t wi) { return get_ereal(inp, name.c_str(), def, wi); } /* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */ -const char *get_estr(std::vector *inp, const char *name, const char *def) +const char* get_estr(std::vector* inp, const char* name, const char* def) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; char buf[32]; - int ii = get_einp(inp, name); + int ii = get_einp(inp, name); if (ii == -1) { @@ -475,20 +474,19 @@ const char *get_estr(std::vector *inp, const char *name, const char * } } -const char *get_estr(std::vector *inp, const std::string &name, const char *def) +const char* get_estr(std::vector* inp, const std::string& name, const char* def) { return get_estr(inp, name.c_str(), def); } /* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */ -int get_eeenum(std::vector *inp, const char *name, const char **defs, - warninp_t wi) +int get_eeenum(std::vector* inp, const char* name, const char** defs, warninp_t wi) { - std::vector &inpRef = *inp; + std::vector& inpRef = *inp; int n = 0; char buf[STRLEN]; - int ii = get_einp(inp, name); + int ii = get_einp(inp, name); if (ii == -1) { @@ -509,11 +507,11 @@ int get_eeenum(std::vector *inp, const char *name, const char **defs, { n += sprintf(buf, "Invalid enum '%s' for variable %s, using '%s'\n", inpRef[ii].value_.c_str(), name, defs[0]); - n += sprintf(buf+n, "Next time use one of:"); - int j = 0; + n += sprintf(buf + n, "Next time use one of:"); + int j = 0; while (defs[j]) { - n += sprintf(buf+n, " '%s'", defs[j]); + n += sprintf(buf + n, " '%s'", defs[j]); j++; } if (wi != nullptr) @@ -533,37 +531,33 @@ int get_eeenum(std::vector *inp, const char *name, const char **defs, return i; } -int get_eeenum(std::vector *inp, const std::string &name, const char **defs, - warninp_t wi) +int get_eeenum(std::vector* inp, const std::string& name, const char** defs, warninp_t wi) { return get_eeenum(inp, name.c_str(), defs, wi); } -int get_eenum(std::vector *inp, const char *name, const char **defs) +int get_eenum(std::vector* inp, const char* name, const char** defs) { return get_eeenum(inp, name, defs, nullptr); } -void -printStringNewline(std::vector *inp, const char *line) +void printStringNewline(std::vector* inp, const char* line) { std::string tmp("\n; "); tmp.append(line); get_estr(inp, tmp.c_str(), nullptr); } -void -printStringNoNewline(std::vector *inp, const char *line) +void printStringNoNewline(std::vector* inp, const char* line) { std::string tmp("; "); tmp.append(line); get_estr(inp, tmp.c_str(), nullptr); } -void -setStringEntry(std::vector *inp, const char *name, char *newName, const char *def) +void setStringEntry(std::vector* inp, const char* name, char* newName, const char* def) { - const char *found = nullptr; - found = get_estr(inp, name, def); + const char* found = nullptr; + found = get_estr(inp, name, def); if (found != nullptr) { std::strcpy(newName, found); diff --git a/src/gromacs/fileio/readinp.h b/src/gromacs/fileio/readinp.h index 6fb6d2111d..10d2952d94 100644 --- a/src/gromacs/fileio/readinp.h +++ b/src/gromacs/fileio/readinp.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,14 +47,14 @@ #include "gromacs/utility/basedefinitions.h" struct warninp; -typedef warninp *warninp_t; +typedef warninp* warninp_t; namespace gmx { class KeyValueTreeObject; class TextInputStream; class TextOutputStream; -} +} // namespace gmx /* !\brief Input file structure that is populated with entries read from a file. * @@ -66,8 +66,13 @@ class TextOutputStream; struct t_inpfile { /*!\brief Minimum allowed constructor sets all elements */ - t_inpfile (int count, int inp_count, bool bObsolete, bool bSet, bool bHandledAsKeyValueTree, - std::string name, std::string value) : + t_inpfile(int count, + int inp_count, + bool bObsolete, + bool bSet, + bool bHandledAsKeyValueTree, + std::string name, + std::string value) : count_(count), bObsolete_(bObsolete), bSet_(bSet), @@ -77,14 +82,14 @@ struct t_inpfile inp_count_(inp_count) { } - int count_; /* sort order for output */ - bool bObsolete_; /* whether it is an obsolete param value */ - bool bSet_; /* whether it it has been read out */ - bool bHandledAsKeyValueTree_; /* whether it it has been handled with key-value machinery */ - std::string name_; /* name of the parameter */ - std::string value_; /* parameter value string */ - int inp_count_; /* number of einps read. Only valid for the first item - in the inpfile list. */ + int count_; /* sort order for output */ + bool bObsolete_; /* whether it is an obsolete param value */ + bool bSet_; /* whether it it has been read out */ + bool bHandledAsKeyValueTree_; /* whether it it has been handled with key-value machinery */ + std::string name_; /* name of the parameter */ + std::string value_; /* parameter value string */ + int inp_count_; /* number of einps read. Only valid for the first item + in the inpfile list. */ }; /*! \brief Create and return a vector of t_inpfile structs @@ -95,15 +100,14 @@ struct t_inpfile * \param[out] wi Handler for context-sensitive warnings. * \throws std::bad_alloc If out of memory. * \throws Anything the stream underlying \c reader can throw. */ -std::vector -read_inpfile(gmx::TextInputStream *stream, const char *fn, - warninp_t wi); +std::vector read_inpfile(gmx::TextInputStream* stream, const char* fn, warninp_t wi); gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(gmx::ArrayRef inp); enum class WriteMdpHeader { - no, yes + no, + yes }; /*! \brief Write "key = value" lines from \c inp to \c stream. @@ -116,58 +120,49 @@ enum class WriteMdpHeader * \param[out] wi Handler for context-sensitive warnings. * \throws std::bad_alloc If out of memory. * \throws Anything the stream underlying \c writer can throw. */ -void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector *inp, - gmx_bool bHaltOnUnknown, - WriteMdpHeader writeHeader, - warninp_t wi); +void write_inpfile(gmx::TextOutputStream* stream, + const char* fn, + std::vector* inp, + gmx_bool bHaltOnUnknown, + WriteMdpHeader writeHeader, + warninp_t wi); /* Write inp to fn, warning (and perhaps halting) if any fields are * unknown. The helpful header contains irreproducible content, so * its writing can be suppressed to make testing more useful. */ -void replace_inp_entry(gmx::ArrayRef inp, - const char *old_entry, const char *new_entry); +void replace_inp_entry(gmx::ArrayRef inp, const char* old_entry, const char* new_entry); -int search_einp(gmx::ArrayRef inp, const char *name); +int search_einp(gmx::ArrayRef inp, const char* name); /* Return the index of an .mdp field with the given name within the * inp vector, if it exists. Return -1 if it does not exist. */ -void mark_einp_set(gmx::ArrayRef inp, const char *name); +void mark_einp_set(gmx::ArrayRef inp, const char* name); -int get_eint(std::vector *inp, const char *name, int def, - warninp_t wi); -int get_eint(std::vector *inp, const std::string &name, int def, - warninp_t wi); +int get_eint(std::vector* inp, const char* name, int def, warninp_t wi); +int get_eint(std::vector* inp, const std::string& name, int def, warninp_t wi); -int64_t get_eint64(std::vector *inp, - const char *name, int64_t def, - warninp_t wi); -int64_t get_eint64(std::vector *inp, - const std::string &name, int64_t def, - warninp_t wi); +int64_t get_eint64(std::vector* inp, const char* name, int64_t def, warninp_t wi); +int64_t get_eint64(std::vector* inp, const std::string& name, int64_t def, warninp_t wi); -double get_ereal(std::vector *inp, const char *name, double def, - warninp_t wi); -double get_ereal(std::vector *inp, const std::string &name, double def, - warninp_t wi); +double get_ereal(std::vector* inp, const char* name, double def, warninp_t wi); +double get_ereal(std::vector* inp, const std::string& name, double def, warninp_t wi); -const char *get_estr(std::vector *inp, const char *name, const char *def); -const char *get_estr(std::vector *inp, const std::string &name, const char *def); +const char* get_estr(std::vector* inp, const char* name, const char* def); +const char* get_estr(std::vector* inp, const std::string& name, const char* def); -int get_eeenum(std::vector *inp, const char *name, const char **defs, - warninp_t wi); +int get_eeenum(std::vector* inp, const char* name, const char** defs, warninp_t wi); /* defs must be NULL terminated */ -int get_eeenum(std::vector *inp, const std::string &name, const char **defs, - warninp_t wi); +int get_eeenum(std::vector* inp, const std::string& name, const char** defs, warninp_t wi); /* defs must be NULL terminated */ -int get_eenum(std::vector *inp, const char *name, const char **defs); +int get_eenum(std::vector* inp, const char* name, const char** defs); /* defs must be NULL terminated */ //! Replace for macro CCTYPE, prints comment string after newline -void printStringNewline(std::vector *inp, const char *line); +void printStringNewline(std::vector* inp, const char* line); //! Replace for macro CTYPE, prints comment string -void printStringNoNewline(std::vector *inp, const char *line); +void printStringNoNewline(std::vector* inp, const char* line); //! Replace for macro STYPE, checks for existing string entry and if possible replaces it -void setStringEntry(std::vector *inp, const char *name, char *newName, const char *def); +void setStringEntry(std::vector* inp, const char* name, char* newName, const char* def); #endif diff --git a/src/gromacs/fileio/tests/confio.cpp b/src/gromacs/fileio/tests/confio.cpp index 52ba9201cd..e0f6c7231f 100644 --- a/src/gromacs/fileio/tests/confio.cpp +++ b/src/gromacs/fileio/tests/confio.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,7 +65,7 @@ /*! \brief * Google Test formatter for GromacsFileType values. */ -static void PrintTo(const GromacsFileType &ftp, std::ostream *os) +static void PrintTo(const GromacsFileType& ftp, std::ostream* os) { *os << "'" << ftp2ext(ftp) << "'"; } @@ -73,127 +73,123 @@ static void PrintTo(const GromacsFileType &ftp, std::ostream *os) namespace { -class StructureIORoundtripTest : public gmx::test::StringTestBase, - public ::testing::WithParamInterface +class StructureIORoundtripTest : + public gmx::test::StringTestBase, + public ::testing::WithParamInterface { - public: - StructureIORoundtripTest() +public: + StructureIORoundtripTest() + { + generateReferenceTopology(); + generateReferenceCoordinates(); + testTop_ = nullptr; + testX_ = nullptr; + clear_mat(testBox_); + referenceFilename_ = fileManager_.getTemporaryFilePath(getFileSuffix("ref")); + testFilename_ = fileManager_.getTemporaryFilePath(getFileSuffix("test")); + } + ~StructureIORoundtripTest() override + { + if (testTop_ != nullptr) { - generateReferenceTopology(); - generateReferenceCoordinates(); - testTop_ = nullptr; - testX_ = nullptr; - clear_mat(testBox_); - referenceFilename_ = - fileManager_.getTemporaryFilePath(getFileSuffix("ref")); - testFilename_ = - fileManager_.getTemporaryFilePath(getFileSuffix("test")); + done_top(testTop_); + sfree(testTop_); } - ~StructureIORoundtripTest() override + sfree(testX_); + done_top(refTop_); + sfree(refTop_); + } + + void writeReferenceFile() + { + write_sto_conf(referenceFilename_.c_str(), *refTop_->name, &refTop_->atoms, + as_rvec_array(refX_.data()), nullptr, -1, refBox_); + } + + void readReferenceFileTps() + { + snew(testTop_, 1); + int ePBC = -2; + read_tps_conf(referenceFilename_.c_str(), testTop_, &ePBC, &testX_, nullptr, testBox_, FALSE); + } + + void testTopologies() + { + // TODO: Compare the topologies. + } + + void writeTestFileAndTest() + { + write_sto_conf(testFilename_.c_str(), *testTop_->name, &testTop_->atoms, testX_, nullptr, + -1, testBox_); + testFilesEqual(referenceFilename_, testFilename_); + } + +private: + std::string getFileSuffix(const char* type) + { + return std::string(type) + "." + ftp2ext(GetParam()); + } + + void generateReferenceTopology() + { + snew(refTop_, 1); + open_symtab(&refTop_->symtab); + if (GetParam() == efESP) { - if (testTop_ != nullptr) - { - done_top(testTop_); - sfree(testTop_); - } - sfree(testX_); - done_top(refTop_); - sfree(refTop_); - } - - void writeReferenceFile() - { - write_sto_conf(referenceFilename_.c_str(), *refTop_->name, - &refTop_->atoms, as_rvec_array(refX_.data()), nullptr, -1, - refBox_); - } - - void readReferenceFileTps() - { - snew(testTop_, 1); - int ePBC = -2; - read_tps_conf(referenceFilename_.c_str(), testTop_, - &ePBC, &testX_, nullptr, testBox_, FALSE); - } - - void testTopologies() - { - // TODO: Compare the topologies. - } - - void writeTestFileAndTest() - { - write_sto_conf(testFilename_.c_str(), *testTop_->name, - &testTop_->atoms, testX_, nullptr, -1, testBox_); - testFilesEqual(referenceFilename_, testFilename_); + // Titles cannot be read from an .esp file... + refTop_->name = put_symtab(&refTop_->symtab, ""); } - - private: - std::string getFileSuffix(const char *type) + else { - return std::string(type) + "." + ftp2ext(GetParam()); + refTop_->name = put_symtab(&refTop_->symtab, "Test title"); } - - void generateReferenceTopology() + const int atomCount = 10; + init_t_atoms(&refTop_->atoms, atomCount, FALSE); + for (int i = 0; i < atomCount; ++i) { - snew(refTop_, 1); - open_symtab(&refTop_->symtab); - if (GetParam() == efESP) - { - // Titles cannot be read from an .esp file... - refTop_->name = put_symtab(&refTop_->symtab, ""); - } - else + char name[3]; + name[0] = 'A'; + name[1] = 'A' + i % 3; + name[2] = '\0'; + refTop_->atoms.atomname[i] = put_symtab(&refTop_->symtab, name); + refTop_->atoms.atom[i].resind = i / 3; + if (i % 3 == 0) { - refTop_->name = put_symtab(&refTop_->symtab, "Test title"); + char resname[3]; + resname[0] = 'R'; + resname[1] = 'A' + i / 3; + resname[2] = '\0'; + t_atoms_set_resinfo(&refTop_->atoms, i, &refTop_->symtab, resname, i / 3 + 1, ' ', 0, ' '); } - const int atomCount = 10; - init_t_atoms(&refTop_->atoms, atomCount, FALSE); - for (int i = 0; i < atomCount; ++i) - { - char name[3]; - name[0] = 'A'; - name[1] = 'A' + i%3; - name[2] = '\0'; - refTop_->atoms.atomname[i] = put_symtab(&refTop_->symtab, name); - refTop_->atoms.atom[i].resind = i/3; - if (i%3 == 0) - { - char resname[3]; - resname[0] = 'R'; - resname[1] = 'A' + i/3; - resname[2] = '\0'; - t_atoms_set_resinfo(&refTop_->atoms, i, &refTop_->symtab, - resname, i/3 + 1, ' ', 0, ' '); - } - } - refTop_->atoms.nres = 4; - close_symtab(&refTop_->symtab); } - - void generateReferenceCoordinates() + refTop_->atoms.nres = 4; + close_symtab(&refTop_->symtab); + } + + void generateReferenceCoordinates() + { + clear_mat(refBox_); + refBox_[XX][XX] = 1; + refBox_[YY][YY] = 2; + refBox_[ZZ][ZZ] = 3; + const int atomCount = refTop_->atoms.nr; + refX_.reserve(atomCount); + for (int i = 0; i < atomCount; ++i) { - clear_mat(refBox_); - refBox_[XX][XX] = 1; - refBox_[YY][YY] = 2; - refBox_[ZZ][ZZ] = 3; - const int atomCount = refTop_->atoms.nr; - refX_.reserve(atomCount); - for (int i = 0; i < atomCount; ++i) - { - refX_.emplace_back(i%4, i/4, (i/2)%3); - } + refX_.emplace_back(i % 4, i / 4, (i / 2) % 3); } - - gmx::test::TestFileManager fileManager_; - std::string referenceFilename_; - std::string testFilename_; - t_topology *refTop_; - std::vector refX_; - matrix refBox_; - t_topology *testTop_; - rvec *testX_; - matrix testBox_; + } + + gmx::test::TestFileManager fileManager_; + std::string referenceFilename_; + std::string testFilename_; + t_topology* refTop_; + std::vector refX_; + matrix refBox_; + t_topology* testTop_; + rvec* testX_; + matrix testBox_; }; TEST_P(StructureIORoundtripTest, ReadWriteTpsConf) @@ -206,6 +202,6 @@ TEST_P(StructureIORoundtripTest, ReadWriteTpsConf) INSTANTIATE_TEST_CASE_P(WithDifferentFormats, StructureIORoundtripTest, - ::testing::Values(efGRO, efG96, efPDB, efESP)); + ::testing::Values(efGRO, efG96, efPDB, efESP)); } // namespace diff --git a/src/gromacs/fileio/tests/filemd5.cpp b/src/gromacs/fileio/tests/filemd5.cpp index e46600d0aa..8c6042eee2 100644 --- a/src/gromacs/fileio/tests/filemd5.cpp +++ b/src/gromacs/fileio/tests/filemd5.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,29 +66,29 @@ namespace class FileMD5Test : public ::testing::Test { - public: - void prepareFile(int lengthInBytes) +public: + void prepareFile(int lengthInBytes) + { + // Fill some memory with some arbitrary bits. + std::vector data(lengthInBytes); + std::iota(data.begin(), data.end(), 1); + // Binary mode ensures it works the same on all OS + FILE* fp = fopen(filename_.c_str(), "wb"); + fwrite(data.data(), sizeof(char), data.size(), fp); + fclose(fp); + } + ~FileMD5Test() override + { + if (file_) { - // Fill some memory with some arbitrary bits. - std::vector data(lengthInBytes); - std::iota(data.begin(), data.end(), 1); - // Binary mode ensures it works the same on all OS - FILE *fp = fopen(filename_.c_str(), "wb"); - fwrite(data.data(), sizeof(char), data.size(), fp); - fclose(fp); + gmx_fio_close(file_); } - ~FileMD5Test() override - { - if (file_) - { - gmx_fio_close(file_); - } - } - TestFileManager fileManager_; - // Make sure the file extension is one that gmx_fio_open will - // recognize to open as binary. - std::string filename_ = fileManager_.getTemporaryFilePath("data.edr"); - t_fileio *file_ = nullptr; + } + TestFileManager fileManager_; + // Make sure the file extension is one that gmx_fio_open will + // recognize to open as binary. + std::string filename_ = fileManager_.getTemporaryFilePath("data.edr"); + t_fileio* file_ = nullptr; }; TEST_F(FileMD5Test, CanComputeMD5) @@ -96,11 +96,11 @@ TEST_F(FileMD5Test, CanComputeMD5) prepareFile(1000); file_ = gmx_fio_open(filename_.c_str(), "r+"); - std::array digest = {0}; + std::array digest = { 0 }; // Chosen to be less than the full file length - gmx_off_t offset = 64; - gmx_off_t expectedLength = 64; - gmx_off_t lengthActuallyRead = gmx_fio_get_file_md5(file_, offset, &digest); + gmx_off_t offset = 64; + gmx_off_t expectedLength = 64; + gmx_off_t lengthActuallyRead = gmx_fio_get_file_md5(file_, offset, &digest); EXPECT_EQ(expectedLength, lengthActuallyRead); // Did we compute an actual reproducible checksum? diff --git a/src/gromacs/fileio/tests/mrcdensitymap.cpp b/src/gromacs/fileio/tests/mrcdensitymap.cpp index a7cc86c905..d142f0fb4b 100644 --- a/src/gromacs/fileio/tests/mrcdensitymap.cpp +++ b/src/gromacs/fileio/tests/mrcdensitymap.cpp @@ -66,10 +66,10 @@ TEST(MrcDensityMap, RoundTripIsIdempotent) { // write header and data to serializer, store the serialized data - MrcDensityMapHeader header {}; - header.numColumnRowSection_ = {1, 1, 1}; + MrcDensityMapHeader header{}; + header.numColumnRowSection_ = { 1, 1, 1 }; - std::vector data(numberOfExpectedDataItems(header)); + std::vector data(numberOfExpectedDataItems(header)); MrcDensityMapOfFloatWriter mrcDensityMapWriter(header, data); InMemorySerializer serializer; @@ -81,7 +81,8 @@ TEST(MrcDensityMap, RoundTripIsIdempotent) InMemoryDeserializer deserializer(serializedFile, false); MrcDensityMapOfFloatReader mrcDensityMapReader(&deserializer); - MrcDensityMapOfFloatWriter writerOfDeserializedOutput(mrcDensityMapReader.header(), mrcDensityMapReader.constView()); + MrcDensityMapOfFloatWriter writerOfDeserializedOutput(mrcDensityMapReader.header(), + mrcDensityMapReader.constView()); writerOfDeserializedOutput.write(&serializer); const auto roundTripResult = serializer.finishAndGetBuffer(); @@ -102,11 +103,12 @@ TEST(MrcDensityMap, ReadsCoordinateTransformationFromFile) RVec coordinate3(1, 0, 0); RVec coordinate4(0, 1, 0); - MrcDensityMapOfFloatFromFileReader mrcFileReader(TestFileManager::getInputFilePath("ellipsoid-density.mrc")); - TranslateAndScale coordinateTransformation(mrcFileReader.transformationToDensityLattice()); + MrcDensityMapOfFloatFromFileReader mrcFileReader( + TestFileManager::getInputFilePath("ellipsoid-density.mrc")); + TranslateAndScale coordinateTransformation(mrcFileReader.transformationToDensityLattice()); - coordinateTransformation({&coordinate1, &coordinate1+1}); - coordinateTransformation({&coordinate2, &coordinate2+1}); + coordinateTransformation({ &coordinate1, &coordinate1 + 1 }); + coordinateTransformation({ &coordinate2, &coordinate2 + 1 }); EXPECT_REAL_EQ(0, coordinate1[XX]); EXPECT_REAL_EQ(-2, coordinate1[YY]); @@ -129,10 +131,10 @@ TEST(MrcDensityMap, ReadsDensityDataFromFile) { MrcDensityMapOfFloatFromFileReader mrcFileReader( TestFileManager::getInputFilePath("ellipsoid-density.mrc")); - const auto densityData = mrcFileReader.densityDataCopy(); + const auto densityData = mrcFileReader.densityDataCopy(); - TestReferenceData refData; - TestReferenceChecker checker(refData.rootChecker()); + TestReferenceData refData; + TestReferenceChecker checker(refData.rootChecker()); checker.checkSequence(begin(densityData.asConstView()), end(densityData.asConstView()), "data ellipsoid density"); } diff --git a/src/gromacs/fileio/tests/mrcdensitymapheader.cpp b/src/gromacs/fileio/tests/mrcdensitymapheader.cpp index 6f65972f5c..ad303cad21 100644 --- a/src/gromacs/fileio/tests/mrcdensitymapheader.cpp +++ b/src/gromacs/fileio/tests/mrcdensitymapheader.cpp @@ -65,47 +65,49 @@ TEST(MrcDensityMapHeaderTest, DataSizeIsZeroForDefaultHeader) TEST(MrcDensityMapHeaderTest, DataSizeIsCorrect) { MrcDensityMapHeader header; - header.numColumnRowSection_ = {1, 2, 3}; + header.numColumnRowSection_ = { 1, 2, 3 }; EXPECT_EQ(6, numberOfExpectedDataItems(header)); } TEST(MrcDensityMapHeaderTest, DataSizeThrowsWhenInvalid) { MrcDensityMapHeader header; - header.numColumnRowSection_ = {-1, 2, 3}; + header.numColumnRowSection_ = { -1, 2, 3 }; EXPECT_THROW(numberOfExpectedDataItems(header), InternalError); } TEST(MrcDensityMapHeaderTest, GetsCorrectCoordinateTransformNoOriginGiven) { MrcDensityMapHeader header; - header.extent_ = {100, 200, 300}; - header.columnRowSectionStart_ = {50, 200, 0}; - header.cellLength_ = {10, 20, 15}; + header.extent_ = { 100, 200, 300 }; + header.columnRowSectionStart_ = { 50, 200, 0 }; + header.cellLength_ = { 10, 20, 15 }; - std::array testVectors = {RVec {0., 0., 0.}, RVec {1., 1., 1.}}; + std::array testVectors = { RVec{ 0., 0., 0. }, RVec{ 1., 1., 1. } }; getCoordinateTransformationToLattice(header)(testVectors); - std::vector expectedVectors = {{-50, -200, 0}, {50, -100, 200}}; - EXPECT_THAT(expectedVectors, testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); + std::vector expectedVectors = { { -50, -200, 0 }, { 50, -100, 200 } }; + EXPECT_THAT(expectedVectors, + testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); } TEST(MrcDensityMapHeaderTest, GetsCorrectCoordinateTransformWithOriginDefined) { MrcDensityMapHeader header; - header.userDefinedFloat_[12] = 1.; - header.userDefinedFloat_[13] = 2.; - header.userDefinedFloat_[14] = 3.; - header.extent_ = {100, 200, 300}; + header.userDefinedFloat_[12] = 1.; + header.userDefinedFloat_[13] = 2.; + header.userDefinedFloat_[14] = 3.; + header.extent_ = { 100, 200, 300 }; // setting the columnRowSectionStart values that are to be ignored if userDefinedFloat_ is not zero - header.columnRowSectionStart_ = {50, 200, 0}; - header.cellLength_ = {10, 20, 15}; + header.columnRowSectionStart_ = { 50, 200, 0 }; + header.cellLength_ = { 10, 20, 15 }; - std::array testVectors = {RVec {0., 0., 0.}, RVec {1., 1., 1.}}; + std::array testVectors = { RVec{ 0., 0., 0. }, RVec{ 1., 1., 1. } }; getCoordinateTransformationToLattice(header)(testVectors); - std::vector expectedVectors = {{-10, -20, -60}, {90, 80, 140}}; - EXPECT_THAT(expectedVectors, testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); + std::vector expectedVectors = { { -10, -20, -60 }, { 90, 80, 140 } }; + EXPECT_THAT(expectedVectors, + testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); } TEST(MrcDensityMapHeaderTest, GetsCorrectCoordinateTransformWithStartValues) @@ -114,24 +116,25 @@ TEST(MrcDensityMapHeaderTest, GetsCorrectCoordinateTransformWithStartValues) header.userDefinedFloat_[12] = 0; header.userDefinedFloat_[13] = 0; header.userDefinedFloat_[14] = 0; - header.extent_ = {100, 200, 300}; - header.columnRowSectionStart_ = {50, 200, 0}; - header.cellLength_ = {10, 20, 15}; + header.extent_ = { 100, 200, 300 }; + header.columnRowSectionStart_ = { 50, 200, 0 }; + header.cellLength_ = { 10, 20, 15 }; - std::array testVectors = {RVec {0., 0., 0.}, RVec {1., 1., 1.}}; + std::array testVectors = { RVec{ 0., 0., 0. }, RVec{ 1., 1., 1. } }; getCoordinateTransformationToLattice(header)(testVectors); - std::vector expectedVectors = {{-50, -200, 0}, {50, -100, 200}}; - EXPECT_THAT(expectedVectors, testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); + std::vector expectedVectors = { { -50, -200, 0 }, { 50, -100, 200 } }; + EXPECT_THAT(expectedVectors, + testing::Pointwise(test::RVecEq(test::defaultFloatTolerance()), testVectors)); } TEST(MrcDensityMapHeaderTest, GetsCorrectExtents) { MrcDensityMapHeader header; - header.numColumnRowSection_ = {100, 200, 300}; + header.numColumnRowSection_ = { 100, 200, 300 }; - const auto extents = getDynamicExtents3D(header); - std::array expectedExtents = {300, 200, 100}; + const auto extents = getDynamicExtents3D(header); + std::array expectedExtents = { 300, 200, 100 }; EXPECT_EQ(expectedExtents[XX], extents.extent(XX)); EXPECT_EQ(expectedExtents[YY], extents.extent(YY)); EXPECT_EQ(expectedExtents[ZZ], extents.extent(ZZ)); diff --git a/src/gromacs/fileio/tests/mrcserializer.cpp b/src/gromacs/fileio/tests/mrcserializer.cpp index 2d42178c4d..723dcd4eb3 100644 --- a/src/gromacs/fileio/tests/mrcserializer.cpp +++ b/src/gromacs/fileio/tests/mrcserializer.cpp @@ -74,9 +74,9 @@ TEST(MrcSerializer, DefaultHeaderHasRightSerialSize) const MrcDensityMapHeader inputHeader = {}; serializeMrcDensityMapHeader(&serializer, inputHeader); - const auto serializedHeader = serializer.finishAndGetBuffer(); + const auto serializedHeader = serializer.finishAndGetBuffer(); - constexpr size_t c_defaultMrcHeaderSize = 1024; + constexpr size_t c_defaultMrcHeaderSize = 1024; EXPECT_EQ(c_defaultMrcHeaderSize, serializedHeader.size()); } @@ -86,10 +86,10 @@ TEST(MrcSerializer, DefaultHeaderIdenticalAfterRoundTrip) const MrcDensityMapHeader inputHeader = {}; serializeMrcDensityMapHeader(&serializer, inputHeader); - const auto serializedHeader = serializer.finishAndGetBuffer(); + const auto serializedHeader = serializer.finishAndGetBuffer(); - InMemoryDeserializer deserializer(serializedHeader, false); - const auto deserializedHeader = deserializeMrcDensityMapHeader(&deserializer); + InMemoryDeserializer deserializer(serializedHeader, false); + const auto deserializedHeader = deserializeMrcDensityMapHeader(&deserializer); // comparing serialized results saves MrcDensityHeaders comparison implementation serializeMrcDensityMapHeader(&serializer, deserializedHeader); diff --git a/src/gromacs/fileio/tests/readinp.cpp b/src/gromacs/fileio/tests/readinp.cpp index 6d23b9b525..b1aa664182 100644 --- a/src/gromacs/fileio/tests/readinp.cpp +++ b/src/gromacs/fileio/tests/readinp.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,18 +55,17 @@ namespace testing class ReadTest : public ::testing::Test { - public: - ReadTest() : inputField_ {{(t_inpfile(0, 0, false, false, false, "test", ""))}}, - wi_() - - { - wi_ = init_warning(FALSE, 0); - wiGuard_.reset(wi_); - } - - std::vector inputField_; - warninp_t wi_; - gmx::unique_cptr wiGuard_; +public: + ReadTest() : inputField_{ { (t_inpfile(0, 0, false, false, false, "test", "")) } }, wi_() + + { + wi_ = init_warning(FALSE, 0); + wiGuard_.reset(wi_); + } + + std::vector inputField_; + warninp_t wi_; + gmx::unique_cptr wiGuard_; }; TEST_F(ReadTest, get_eint_ReadsInteger) @@ -132,5 +131,5 @@ TEST_F(ReadTest, get_ereal_WarnsAboutString) ASSERT_TRUE(warning_errors_exist(wi_)); } -} // namespace testing -} // namespace gmx +} // namespace testing +} // namespace gmx diff --git a/src/gromacs/fileio/tests/tngio.cpp b/src/gromacs/fileio/tests/tngio.cpp index 0ea66b1414..3a56def805 100644 --- a/src/gromacs/fileio/tests/tngio.cpp +++ b/src/gromacs/fileio/tests/tngio.cpp @@ -57,11 +57,9 @@ namespace class TngTest : public ::testing::Test { - public: - TngTest() - { - } - gmx::test::TestFileManager fileManager_; +public: + TngTest() {} + gmx::test::TestFileManager fileManager_; }; TEST_F(TngTest, CanOpenTngFile) diff --git a/src/gromacs/fileio/timecontrol.cpp b/src/gromacs/fileio/timecontrol.cpp index 1d31fb31f5..fae0dd6b8d 100644 --- a/src/gromacs/fileio/timecontrol.cpp +++ b/src/gromacs/fileio/timecontrol.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,16 +48,13 @@ Please keep it that way. */ /* Globals for trajectory input */ -typedef struct { +typedef struct +{ real t; gmx_bool bSet; } t_timecontrol; -static t_timecontrol timecontrol[TNR] = { - { 0, FALSE }, - { 0, FALSE }, - { 0, FALSE } -}; +static t_timecontrol timecontrol[TNR] = { { 0, FALSE }, { 0, FALSE }, { 0, FALSE } }; static tMPI_Thread_mutex_t tc_mutex = TMPI_THREAD_MUTEX_INITIALIZER; diff --git a/src/gromacs/fileio/timecontrol.h b/src/gromacs/fileio/timecontrol.h index 9e42637411..52f7b37cee 100644 --- a/src/gromacs/fileio/timecontrol.h +++ b/src/gromacs/fileio/timecontrol.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,8 +41,12 @@ /* The code below is to facilitate controlled begin and end of * trajectory reading. */ -enum { - TBEGIN, TEND, TDELTA, TNR +enum +{ + TBEGIN, + TEND, + TDELTA, + TNR }; gmx_bool bTimeSet(int tcontrol); diff --git a/src/gromacs/fileio/tngio.cpp b/src/gromacs/fileio/tngio.cpp index 13474a4fe1..f8a9ea661b 100644 --- a/src/gromacs/fileio/tngio.cpp +++ b/src/gromacs/fileio/tngio.cpp @@ -46,7 +46,7 @@ #include #if GMX_USE_TNG -#include "tng/tng_io.h" +# include "tng/tng_io.h" #endif #include "gromacs/math/units.h" @@ -66,7 +66,7 @@ #include "gromacs/utility/unique_cptr.h" #if !GMX_USE_TNG -using tng_trajectory_t = void *; +using tng_trajectory_t = void*; #endif /*! \brief Gromacs Wrapper around tng datatype @@ -97,30 +97,21 @@ struct gmx_tng_trajectory }; #if GMX_USE_TNG -static const char *modeToVerb(char mode) +static const char* modeToVerb(char mode) { - const char *p; + const char* p; switch (mode) { - case 'r': - p = "reading"; - break; - case 'w': - p = "writing"; - break; - case 'a': - p = "appending"; - break; - default: - gmx_fatal(FARGS, "Invalid file opening mode %c", mode); + case 'r': p = "reading"; break; + case 'w': p = "writing"; break; + case 'a': p = "appending"; break; + default: gmx_fatal(FARGS, "Invalid file opening mode %c", mode); } return p; } #endif -void gmx_tng_open(const char *filename, - char mode, - gmx_tng_trajectory_t *gmx_tng) +void gmx_tng_open(const char* filename, char mode, gmx_tng_trajectory_t* gmx_tng) { #if GMX_USE_TNG /* First check whether we have to make a backup, @@ -135,7 +126,7 @@ void gmx_tng_open(const char *filename, (*gmx_tng)->lastStepDataIsValid = false; (*gmx_tng)->lastTimeDataIsValid = false; (*gmx_tng)->timePerFrameIsSet = false; - tng_trajectory_t * tng = &(*gmx_tng)->tng; + tng_trajectory_t* tng = &(*gmx_tng)->tng; /* tng must not be pointing at already allocated memory. * Memory will be allocated by tng_util_trajectory_open() and must @@ -145,10 +136,7 @@ void gmx_tng_open(const char *filename, /* TNG does return more than one degree of error, but there is no use case for GROMACS handling the non-fatal errors gracefully. */ - gmx_fatal(FARGS, - "File I/O error while opening %s for %s", - filename, - modeToVerb(mode)); + gmx_fatal(FARGS, "File I/O error while opening %s for %s", filename, modeToVerb(mode)); } if (mode == 'w' || mode == 'a') @@ -165,12 +153,11 @@ void gmx_tng_open(const char *filename, } char programInfo[256]; - const char *precisionString = ""; -#if GMX_DOUBLE + const char* precisionString = ""; +# if GMX_DOUBLE precisionString = " (double precision)"; -#endif - sprintf(programInfo, "%.100s %.128s%.24s", - gmx::getProgramContext().displayName(), +# endif + sprintf(programInfo, "%.100s %.128s%.24s", gmx::getProgramContext().displayName(), gmx_version(), precisionString); if (mode == 'w') { @@ -203,7 +190,7 @@ void gmx_tng_open(const char *filename, #endif } -void gmx_tng_close(gmx_tng_trajectory_t *gmx_tng) +void gmx_tng_close(gmx_tng_trajectory_t* gmx_tng) { /* We have to check that tng is set because * tng_util_trajectory_close wants to return a NULL in it, and @@ -213,7 +200,7 @@ void gmx_tng_close(gmx_tng_trajectory_t *gmx_tng) { return; } - tng_trajectory_t * tng = &(*gmx_tng)->tng; + tng_trajectory_t* tng = &(*gmx_tng)->tng; if (tng) { @@ -229,10 +216,10 @@ void gmx_tng_close(gmx_tng_trajectory_t *gmx_tng) #if GMX_USE_TNG static void addTngMoleculeFromTopology(gmx_tng_trajectory_t gmx_tng, - const char *moleculeName, - const t_atoms *atoms, + const char* moleculeName, + const t_atoms* atoms, int64_t numMolecules, - tng_molecule_t *tngMol) + tng_molecule_t* tngMol) { tng_trajectory_t tng = gmx_tng->tng; tng_chain_t tngChain = nullptr; @@ -245,15 +232,15 @@ static void addTngMoleculeFromTopology(gmx_tng_trajectory_t gmx_tng, for (int atomIndex = 0; atomIndex < atoms->nr; atomIndex++) { - const t_atom *at = &atoms->atom[atomIndex]; + const t_atom* at = &atoms->atom[atomIndex]; /* FIXME: Currently the TNG API can only add atoms belonging to a * residue and chain. Wait for TNG 2.0*/ if (atoms->nres > 0) { - const t_resinfo *resInfo = &atoms->resinfo[at->resind]; - char chainName[2] = {resInfo->chainid, 0}; - tng_atom_t tngAtom = nullptr; - t_atom *prevAtom; + const t_resinfo* resInfo = &atoms->resinfo[at->resind]; + char chainName[2] = { resInfo->chainid, 0 }; + tng_atom_t tngAtom = nullptr; + t_atom* prevAtom; if (atomIndex > 0) { @@ -270,33 +257,31 @@ static void addTngMoleculeFromTopology(gmx_tng_trajectory_t gmx_tng, { /* If this is the first atom or if the chain changed add * the chain to the TNG molecular system. */ - if (!prevAtom || resInfo->chainid != - atoms->resinfo[prevAtom->resind].chainid) + if (!prevAtom || resInfo->chainid != atoms->resinfo[prevAtom->resind].chainid) { - tng_molecule_chain_add(tng, *tngMol, chainName, - &tngChain); + tng_molecule_chain_add(tng, *tngMol, chainName, &tngChain); } /* FIXME: When TNG supports both residue index and residue * number the latter should be used. Wait for TNG 2.0*/ tng_chain_residue_add(tng, tngChain, *resInfo->name, &tngRes); } - tng_residue_atom_add(tng, tngRes, *(atoms->atomname[atomIndex]), *(atoms->atomtype[atomIndex]), &tngAtom); + tng_residue_atom_add(tng, tngRes, *(atoms->atomname[atomIndex]), + *(atoms->atomtype[atomIndex]), &tngAtom); } } tng_molecule_cnt_set(tng, *tngMol, numMolecules); } -void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, - const gmx_mtop_t *mtop) +void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, const gmx_mtop_t* mtop) { - int i; - int j; - std::vector atomCharges; - std::vector atomMasses; - tng_bond_t tngBond; - char datatype; + int i; + int j; + std::vector atomCharges; + std::vector atomMasses; + tng_bond_t tngBond; + char datatype; - tng_trajectory_t tng = gmx_tng->tng; + tng_trajectory_t tng = gmx_tng->tng; if (!mtop) { @@ -304,27 +289,23 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, return; } -#if GMX_DOUBLE +# if GMX_DOUBLE datatype = TNG_DOUBLE_DATA; -#else - datatype = TNG_FLOAT_DATA; -#endif +# else + datatype = TNG_FLOAT_DATA; +# endif atomCharges.reserve(mtop->natoms); atomMasses.reserve(mtop->natoms); - for (const gmx_molblock_t &molBlock : mtop->molblock) + for (const gmx_molblock_t& molBlock : mtop->molblock) { tng_molecule_t tngMol = nullptr; - const gmx_moltype_t *molType = &mtop->moltype[molBlock.type]; + const gmx_moltype_t* molType = &mtop->moltype[molBlock.type]; /* Add a molecule to the TNG trajectory with the same name as the * current molecule. */ - addTngMoleculeFromTopology(gmx_tng, - *(molType->name), - &molType->atoms, - molBlock.nmol, - &tngMol); + addTngMoleculeFromTopology(gmx_tng, *(molType->name), &molType->atoms, molBlock.nmol, &tngMol); /* Bonds have to be deduced from interactions (constraints etc). Different * interactions have different sets of parameters. */ @@ -333,8 +314,8 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, { if (IS_CHEMBOND(i)) { - const InteractionList &ilist = molType->ilist[i]; - j = 1; + const InteractionList& ilist = molType->ilist[i]; + j = 1; while (j < ilist.size()) { tng_molecule_bond_add(tng, tngMol, ilist.iatoms[j], ilist.iatoms[j + 1], &tngBond); @@ -343,8 +324,8 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, } } /* Settle is described using three atoms */ - const InteractionList &ilist = molType->ilist[F_SETTLE]; - j = 1; + const InteractionList& ilist = molType->ilist[F_SETTLE]; + j = 1; while (j < ilist.size()) { tng_molecule_bond_add(tng, tngMol, ilist.iatoms[j], ilist.iatoms[j + 1], &tngBond); @@ -360,19 +341,18 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, } for (int molCounter = 1; molCounter < molBlock.nmol; molCounter++) { - std::copy_n(atomCharges.end() - molType->atoms.nr, molType->atoms.nr, std::back_inserter(atomCharges)); - std::copy_n(atomMasses.end() - molType->atoms.nr, molType->atoms.nr, std::back_inserter(atomMasses)); + std::copy_n(atomCharges.end() - molType->atoms.nr, molType->atoms.nr, + std::back_inserter(atomCharges)); + std::copy_n(atomMasses.end() - molType->atoms.nr, molType->atoms.nr, + std::back_inserter(atomMasses)); } } /* Write the TNG data blocks. */ - tng_particle_data_block_add(tng, TNG_TRAJ_PARTIAL_CHARGES, "PARTIAL CHARGES", - datatype, TNG_NON_TRAJECTORY_BLOCK, - 1, 1, 1, 0, mtop->natoms, + tng_particle_data_block_add(tng, TNG_TRAJ_PARTIAL_CHARGES, "PARTIAL CHARGES", datatype, + TNG_NON_TRAJECTORY_BLOCK, 1, 1, 1, 0, mtop->natoms, TNG_GZIP_COMPRESSION, atomCharges.data()); - tng_particle_data_block_add(tng, TNG_TRAJ_MASSES, "ATOM MASSES", - datatype, TNG_NON_TRAJECTORY_BLOCK, - 1, 1, 1, 0, mtop->natoms, - TNG_GZIP_COMPRESSION, atomMasses.data()); + tng_particle_data_block_add(tng, TNG_TRAJ_MASSES, "ATOM MASSES", datatype, TNG_NON_TRAJECTORY_BLOCK, + 1, 1, 1, 0, mtop->natoms, TNG_GZIP_COMPRESSION, atomMasses.data()); } /*! \libinternal \brief Compute greatest common divisor of n1 and n2 @@ -380,8 +360,7 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t gmx_tng, * * If only one of n1 and n2 is positive, then return it. * If neither n1 or n2 is positive, then return -1. */ -static int -greatest_common_divisor_if_positive(int n1, int n2) +static int greatest_common_divisor_if_positive(int n1, int n2) { if (0 >= n1) { @@ -408,9 +387,9 @@ const int defaultFramesPerFrameSet = 100; * set according to output intervals. * The default is that 100 frames are written of the data * that is written most often. */ -static void tng_set_frames_per_frame_set(gmx_tng_trajectory_t gmx_tng, - const gmx_bool bUseLossyCompression, - const t_inputrec *ir) +static void tng_set_frames_per_frame_set(gmx_tng_trajectory_t gmx_tng, + const gmx_bool bUseLossyCompression, + const t_inputrec* ir) { int gcd = -1; tng_trajectory_t tng = gmx_tng->tng; @@ -438,26 +417,22 @@ static void tng_set_frames_per_frame_set(gmx_tng_trajectory_t gmx_tng, /*! \libinternal \brief Set the data-writing intervals, and number of * frames per frame set */ -static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, - const gmx_bool bUseLossyCompression, - const t_inputrec *ir) +static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, + const gmx_bool bUseLossyCompression, + const t_inputrec* ir) { tng_trajectory_t tng = gmx_tng->tng; /* Define pointers to specific writing functions depending on if we * write float or double data */ - typedef tng_function_status (*set_writing_interval_func_pointer)(tng_trajectory_t, - const int64_t, - const int64_t, - const int64_t, - const char*, - const char, - const char); -#if GMX_DOUBLE + typedef tng_function_status (*set_writing_interval_func_pointer)( + tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char, + const char); +# if GMX_DOUBLE set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set; -#else +# else set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_set; -#endif +# endif int xout, vout, fout; int gcd = -1, lowest = -1; char compression; @@ -466,19 +441,19 @@ static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, if (bUseLossyCompression) { - xout = ir->nstxout_compressed; + xout = ir->nstxout_compressed; /* If there is no uncompressed coordinate output write forces and velocities to the compressed tng file. */ if (ir->nstxout) { - vout = 0; - fout = 0; + vout = 0; + fout = 0; } else { - vout = ir->nstvout; - fout = ir->nstfout; + vout = ir->nstvout; + fout = ir->nstfout; } compression = TNG_TNG_COMPRESSION; } @@ -491,8 +466,7 @@ static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, } if (xout) { - set_writing_interval(tng, xout, 3, TNG_TRAJ_POSITIONS, - "POSITIONS", TNG_PARTICLE_BLOCK_DATA, + set_writing_interval(tng, xout, 3, TNG_TRAJ_POSITIONS, "POSITIONS", TNG_PARTICLE_BLOCK_DATA, compression); /* TODO: if/when we write energies to TNG also, reconsider how * and when box information is written, because GROMACS @@ -508,9 +482,8 @@ static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, } if (vout) { - set_writing_interval(tng, vout, 3, TNG_TRAJ_VELOCITIES, - "VELOCITIES", TNG_PARTICLE_BLOCK_DATA, - compression); + set_writing_interval(tng, vout, 3, TNG_TRAJ_VELOCITIES, "VELOCITIES", + TNG_PARTICLE_BLOCK_DATA, compression); gcd = greatest_common_divisor_if_positive(gcd, vout); if (lowest < 0 || vout < lowest) @@ -520,8 +493,7 @@ static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, } if (fout) { - set_writing_interval(tng, fout, 3, TNG_TRAJ_FORCES, - "FORCES", TNG_PARTICLE_BLOCK_DATA, + set_writing_interval(tng, fout, 3, TNG_TRAJ_FORCES, "FORCES", TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); gcd = greatest_common_divisor_if_positive(gcd, fout); @@ -534,28 +506,26 @@ static void set_writing_intervals(gmx_tng_trajectory_t gmx_tng, { /* Lambdas and box shape written at an interval of the lowest common denominator of other output */ - set_writing_interval(tng, gcd, 1, TNG_GMX_LAMBDA, - "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA, + set_writing_interval(tng, gcd, 1, TNG_GMX_LAMBDA, "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); - set_writing_interval(tng, gcd, 9, TNG_TRAJ_BOX_SHAPE, - "BOX SHAPE", TNG_NON_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION); + set_writing_interval(tng, gcd, 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", + TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); gmx_tng->lambdaOutputInterval = gcd; gmx_tng->boxOutputInterval = gcd; if (gcd < lowest / 10) { - gmx_warning("The lowest common denominator of trajectory output is " - "every %d step(s), whereas the shortest output interval " - "is every %d steps.", gcd, lowest); + gmx_warning( + "The lowest common denominator of trajectory output is " + "every %d step(s), whereas the shortest output interval " + "is every %d steps.", + gcd, lowest); } } } #endif -void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t gmx_tng, - const gmx_mtop_t *mtop, - const t_inputrec *ir) +void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t gmx_tng, const gmx_mtop_t* mtop, const t_inputrec* ir) { #if GMX_USE_TNG gmx_tng_add_mtop(gmx_tng, mtop); @@ -572,17 +542,16 @@ void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t gmx_tng, #if GMX_USE_TNG /* Check if all atoms in the molecule system are selected * by a selection group of type specified by gtype. */ -static gmx_bool all_atoms_selected(const gmx_mtop_t *mtop, - const SimulationAtomGroupType gtype) +static gmx_bool all_atoms_selected(const gmx_mtop_t* mtop, const SimulationAtomGroupType gtype) { /* Iterate through all atoms in the molecule system and * check if they belong to a selection group of the * requested type. */ int i = 0; - for (const gmx_molblock_t &molBlock : mtop->molblock) + for (const gmx_molblock_t& molBlock : mtop->molblock) { - const gmx_moltype_t &molType = mtop->moltype[molBlock.type]; - const t_atoms &atoms = molType.atoms; + const gmx_moltype_t& molType = mtop->moltype[molBlock.type]; + const t_atoms& atoms = molType.atoms; for (int j = 0; j < molBlock.nmol; j++) { @@ -605,22 +574,21 @@ static gmx_bool all_atoms_selected(const gmx_mtop_t *mtop, * is egcCompressedX, but other selections should be added when * e.g. writing energies is implemented. */ -static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, - const gmx_mtop_t *mtop) +static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, const gmx_mtop_t* mtop) { - const t_atoms *atoms; - const t_atom *at; - const t_resinfo *resInfo; - int nameIndex; - int atom_offset = 0; - tng_molecule_t mol, iterMol; - tng_chain_t chain; - tng_residue_t res; - tng_atom_t atom; - tng_bond_t tngBond; - int64_t nMols; - char *groupName; - tng_trajectory_t tng = gmx_tng->tng; + const t_atoms* atoms; + const t_atom* at; + const t_resinfo* resInfo; + int nameIndex; + int atom_offset = 0; + tng_molecule_t mol, iterMol; + tng_chain_t chain; + tng_residue_t res; + tng_atom_t atom; + tng_bond_t tngBond; + int64_t nMols; + char* groupName; + tng_trajectory_t tng = gmx_tng->tng; /* TODO: When the TNG molecules block is more flexible TNG selection * groups should not need all atoms specified. It should be possible @@ -650,9 +618,9 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, tng_molecule_name_set(tng, mol, groupName); tng_molecule_chain_add(tng, mol, "", &chain); int i = 0; - for (const gmx_molblock_t &molBlock : mtop->molblock) + for (const gmx_molblock_t& molBlock : mtop->molblock) { - const gmx_moltype_t &molType = mtop->moltype[molBlock.type]; + const gmx_moltype_t& molType = mtop->moltype[molBlock.type]; atoms = &molType.atoms; @@ -661,7 +629,7 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, bool bAtomsAdded = FALSE; for (int atomIndex = 0; atomIndex < atoms->nr; atomIndex++, i++) { - char *res_name; + char* res_name; int res_id; if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, i) != 0) @@ -682,16 +650,14 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, res_name = const_cast(""); res_id = 0; } - if (tng_chain_residue_find(tng, chain, res_name, res_id, &res) - != TNG_SUCCESS) + if (tng_chain_residue_find(tng, chain, res_name, res_id, &res) != TNG_SUCCESS) { /* Since there is ONE chain for selection groups do not keep the * original residue IDs - otherwise there might be conflicts. */ tng_chain_residue_add(tng, chain, res_name, &res); } tng_residue_atom_w_id_add(tng, res, *(atoms->atomname[atomIndex]), - *(atoms->atomtype[atomIndex]), - atom_offset + atomIndex, &atom); + *(atoms->atomtype[atomIndex]), atom_offset + atomIndex, &atom); bAtomsAdded = TRUE; } /* Add bonds. */ @@ -701,14 +667,18 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, { if (IS_CHEMBOND(k)) { - const InteractionList &ilist = molType.ilist[k]; + const InteractionList& ilist = molType.ilist[k]; for (int l = 1; l < ilist.size(); l += 3) { int atom1, atom2; atom1 = ilist.iatoms[l] + atom_offset; atom2 = ilist.iatoms[l + 1] + atom_offset; - if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1) == 0 && - getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2) == 0) + if (getGroupType(mtop->groups, + SimulationAtomGroupType::CompressedPositionOutput, atom1) + == 0 + && getGroupType(mtop->groups, + SimulationAtomGroupType::CompressedPositionOutput, atom2) + == 0) { tng_molecule_bond_add(tng, mol, ilist.iatoms[l], ilist.iatoms[l + 1], &tngBond); @@ -717,24 +687,25 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, } } /* Settle is described using three atoms */ - const InteractionList &ilist = molType.ilist[F_SETTLE]; + const InteractionList& ilist = molType.ilist[F_SETTLE]; for (int l = 1; l < ilist.size(); l += 4) { int atom1, atom2, atom3; atom1 = ilist.iatoms[l] + atom_offset; atom2 = ilist.iatoms[l + 1] + atom_offset; atom3 = ilist.iatoms[l + 2] + atom_offset; - if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1) == 0) + if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom1) + == 0) { - if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2) == 0) + if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom2) + == 0) { - tng_molecule_bond_add(tng, mol, atom1, - atom2, &tngBond); + tng_molecule_bond_add(tng, mol, atom1, atom2, &tngBond); } - if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom3) == 0) + if (getGroupType(mtop->groups, SimulationAtomGroupType::CompressedPositionOutput, atom3) + == 0) { - tng_molecule_bond_add(tng, mol, atom1, - atom3, &tngBond); + tng_molecule_bond_add(tng, mol, atom1, atom3, &tngBond); } } } @@ -757,8 +728,7 @@ static void add_selection_groups(gmx_tng_trajectory_t gmx_tng, } #endif -void gmx_tng_set_compression_precision(gmx_tng_trajectory_t gmx_tng, - real prec) +void gmx_tng_set_compression_precision(gmx_tng_trajectory_t gmx_tng, real prec) { #if GMX_USE_TNG tng_compression_precision_set(gmx_tng->tng, prec); @@ -768,9 +738,7 @@ void gmx_tng_set_compression_precision(gmx_tng_trajectory_t gmx_tng, #endif } -void gmx_tng_prepare_low_prec_writing(gmx_tng_trajectory_t gmx_tng, - const gmx_mtop_t *mtop, - const t_inputrec *ir) +void gmx_tng_prepare_low_prec_writing(gmx_tng_trajectory_t gmx_tng, const gmx_mtop_t* mtop, const t_inputrec* ir) { #if GMX_USE_TNG gmx_tng_add_mtop(gmx_tng, mtop); @@ -791,30 +759,24 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, int64_t step, real elapsedPicoSeconds, real lambda, - const rvec *box, + const rvec* box, int nAtoms, - const rvec *x, - const rvec *v, - const rvec *f) + const rvec* x, + const rvec* v, + const rvec* f) { #if GMX_USE_TNG - typedef tng_function_status (*write_data_func_pointer)(tng_trajectory_t, - const int64_t, - const double, - const real*, - const int64_t, - const int64_t, - const char*, - const char, - const char); -#if GMX_DOUBLE - static write_data_func_pointer write_data = tng_util_generic_with_time_double_write; -#else - static write_data_func_pointer write_data = tng_util_generic_with_time_write; -#endif - double elapsedSeconds = elapsedPicoSeconds * PICO; - int64_t nParticles; - char compression; + typedef tng_function_status (*write_data_func_pointer)( + tng_trajectory_t, const int64_t, const double, const real*, const int64_t, + const int64_t, const char*, const char, const char); +# if GMX_DOUBLE + static write_data_func_pointer write_data = tng_util_generic_with_time_double_write; +# else + static write_data_func_pointer write_data = tng_util_generic_with_time_write; +# endif + double elapsedSeconds = elapsedPicoSeconds * PICO; + int64_t nParticles; + char compression; if (!gmx_tng) @@ -857,7 +819,7 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, { double deltaTime = elapsedSeconds - gmx_tng->lastTime; std::int64_t deltaStep = step - gmx_tng->lastStep; - tng_time_per_frame_set(tng, deltaTime / deltaStep ); + tng_time_per_frame_set(tng, deltaTime / deltaStep); gmx_tng->timePerFrameIsSet = true; } @@ -882,11 +844,9 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, { GMX_ASSERT(box, "Need a non-NULL box if positions are written"); - if (write_data(tng, step, elapsedSeconds, - reinterpret_cast(x), - 3, TNG_TRAJ_POSITIONS, "POSITIONS", - TNG_PARTICLE_BLOCK_DATA, - compression) != TNG_SUCCESS) + if (write_data(tng, step, elapsedSeconds, reinterpret_cast(x), 3, + TNG_TRAJ_POSITIONS, "POSITIONS", TNG_PARTICLE_BLOCK_DATA, compression) + != TNG_SUCCESS) { gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?"); } @@ -894,11 +854,9 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, if (v) { - if (write_data(tng, step, elapsedSeconds, - reinterpret_cast(v), - 3, TNG_TRAJ_VELOCITIES, "VELOCITIES", - TNG_PARTICLE_BLOCK_DATA, - compression) != TNG_SUCCESS) + if (write_data(tng, step, elapsedSeconds, reinterpret_cast(v), 3, + TNG_TRAJ_VELOCITIES, "VELOCITIES", TNG_PARTICLE_BLOCK_DATA, compression) + != TNG_SUCCESS) { gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?"); } @@ -908,11 +866,9 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, { /* TNG-MF1 compression only compresses positions and velocities. Use lossless * compression for forces regardless of output mode */ - if (write_data(tng, step, elapsedSeconds, - reinterpret_cast(f), - 3, TNG_TRAJ_FORCES, "FORCES", - TNG_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION) != TNG_SUCCESS) + if (write_data(tng, step, elapsedSeconds, reinterpret_cast(f), 3, + TNG_TRAJ_FORCES, "FORCES", TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION) + != TNG_SUCCESS) { gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?"); } @@ -922,11 +878,9 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, { /* TNG-MF1 compression only compresses positions and velocities. Use lossless * compression for box shape regardless of output mode */ - if (write_data(tng, step, elapsedSeconds, - reinterpret_cast(box), - 9, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", - TNG_NON_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION) != TNG_SUCCESS) + if (write_data(tng, step, elapsedSeconds, reinterpret_cast(box), 9, + TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION) + != TNG_SUCCESS) { gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?"); } @@ -936,11 +890,9 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t gmx_tng, { /* TNG-MF1 compression only compresses positions and velocities. Use lossless * compression for lambda regardless of output mode */ - if (write_data(tng, step, elapsedSeconds, - reinterpret_cast(&lambda), - 1, TNG_GMX_LAMBDA, "LAMBDAS", - TNG_NON_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION) != TNG_SUCCESS) + if (write_data(tng, step, elapsedSeconds, reinterpret_cast(&lambda), 1, + TNG_GMX_LAMBDA, "LAMBDAS", TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION) + != TNG_SUCCESS) { gmx_file("Cannot write TNG trajectory frame; maybe you are out of disk space?"); } @@ -998,46 +950,35 @@ float gmx_tng_get_time_of_final_frame(gmx_tng_trajectory_t gmx_tng) #endif } -void gmx_prepare_tng_writing(const char *filename, +void gmx_prepare_tng_writing(const char* filename, char mode, - gmx_tng_trajectory_t *gmx_tng_input, - gmx_tng_trajectory_t *gmx_tng_output, + gmx_tng_trajectory_t* gmx_tng_input, + gmx_tng_trajectory_t* gmx_tng_output, int nAtoms, - const gmx_mtop_t *mtop, + const gmx_mtop_t* mtop, gmx::ArrayRef index, - const char *indexGroupName) + const char* indexGroupName) { #if GMX_USE_TNG - tng_trajectory_t *input = (gmx_tng_input && *gmx_tng_input) ? &(*gmx_tng_input)->tng : nullptr; + tng_trajectory_t* input = (gmx_tng_input && *gmx_tng_input) ? &(*gmx_tng_input)->tng : nullptr; /* FIXME after 5.0: Currently only standard block types are read */ - const int defaultNumIds = 5; - static int64_t fallbackIds[defaultNumIds] = - { - TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, - TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, - TNG_GMX_LAMBDA - }; - static char fallbackNames[defaultNumIds][32] = - { - "BOX SHAPE", "POSITIONS", "VELOCITIES", - "FORCES", "LAMBDAS" - }; - - typedef tng_function_status (*set_writing_interval_func_pointer)(tng_trajectory_t, - const int64_t, - const int64_t, - const int64_t, - const char*, - const char, - const char); -#if GMX_DOUBLE + const int defaultNumIds = 5; + static int64_t fallbackIds[defaultNumIds] = { TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, + TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, TNG_GMX_LAMBDA }; + static char fallbackNames[defaultNumIds][32] = { "BOX SHAPE", "POSITIONS", "VELOCITIES", + "FORCES", "LAMBDAS" }; + + typedef tng_function_status (*set_writing_interval_func_pointer)( + tng_trajectory_t, const int64_t, const int64_t, const int64_t, const char*, const char, + const char); +# if GMX_DOUBLE set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set; -#else +# else set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_set; -#endif +# endif gmx_tng_open(filename, mode, gmx_tng_output); - tng_trajectory_t *output = &(*gmx_tng_output)->tng; + tng_trajectory_t* output = &(*gmx_tng_output)->tng; /* Do we have an input file in TNG format? If so, then there's more data we can copy over, rather than having to improvise. */ @@ -1048,8 +989,8 @@ void gmx_prepare_tng_writing(const char *filename, * intervals of positions, box shape and lambdas) of the * output tng container based on their respective values int * the input tng container */ - double time, compression_precision; - int64_t n_frames_per_frame_set, interval = -1; + double time, compression_precision; + int64_t n_frames_per_frame_set, interval = -1; tng_compression_precision_get(*input, &compression_precision); tng_compression_precision_set(*output, compression_precision); @@ -1068,40 +1009,33 @@ void gmx_prepare_tng_writing(const char *filename, for (int i = 0; i < defaultNumIds; i++) { - if (tng_data_get_stride_length(*input, fallbackIds[i], -1, &interval) - == TNG_SUCCESS) + if (tng_data_get_stride_length(*input, fallbackIds[i], -1, &interval) == TNG_SUCCESS) { switch (fallbackIds[i]) { case TNG_TRAJ_POSITIONS: case TNG_TRAJ_VELOCITIES: - set_writing_interval(*output, interval, 3, fallbackIds[i], - fallbackNames[i], TNG_PARTICLE_BLOCK_DATA, - compression_type); + set_writing_interval(*output, interval, 3, fallbackIds[i], fallbackNames[i], + TNG_PARTICLE_BLOCK_DATA, compression_type); break; case TNG_TRAJ_FORCES: - set_writing_interval(*output, interval, 3, fallbackIds[i], - fallbackNames[i], TNG_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION); + set_writing_interval(*output, interval, 3, fallbackIds[i], fallbackNames[i], + TNG_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); break; case TNG_TRAJ_BOX_SHAPE: - set_writing_interval(*output, interval, 9, fallbackIds[i], - fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION); + set_writing_interval(*output, interval, 9, fallbackIds[i], fallbackNames[i], + TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); (*gmx_tng_output)->boxOutputInterval = interval; break; case TNG_GMX_LAMBDA: - set_writing_interval(*output, interval, 1, fallbackIds[i], - fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA, - TNG_GZIP_COMPRESSION); + set_writing_interval(*output, interval, 1, fallbackIds[i], fallbackNames[i], + TNG_NON_PARTICLE_BLOCK_DATA, TNG_GZIP_COMPRESSION); (*gmx_tng_output)->lambdaOutputInterval = interval; break; - default: - continue; + default: continue; } } } - } else { @@ -1140,25 +1074,15 @@ void gmx_prepare_tng_writing(const char *filename, #endif } -void gmx_write_tng_from_trxframe(gmx_tng_trajectory_t gmx_tng_output, - const t_trxframe *frame, - int natoms) +void gmx_write_tng_from_trxframe(gmx_tng_trajectory_t gmx_tng_output, const t_trxframe* frame, int natoms) { #if GMX_USE_TNG if (natoms < 0) { natoms = frame->natoms; } - gmx_fwrite_tng(gmx_tng_output, - TRUE, - frame->step, - frame->time, - 0, - frame->box, - natoms, - frame->x, - frame->v, - frame->f); + gmx_fwrite_tng(gmx_tng_output, TRUE, frame->step, frame->time, 0, frame->box, natoms, frame->x, + frame->v, frame->f); #else GMX_UNUSED_VALUE(gmx_tng_output); GMX_UNUSED_VALUE(frame); @@ -1170,15 +1094,14 @@ namespace { #if GMX_USE_TNG -void -convert_array_to_real_array(void *from, - real *to, - const float fact, - const int nAtoms, - const int nValues, - const char datatype) +void convert_array_to_real_array(void* from, + real* to, + const float fact, + const int nAtoms, + const int nValues, + const char datatype) { - int i, j; + int i, j; const bool useDouble = GMX_DOUBLE; switch (datatype) @@ -1196,7 +1119,7 @@ convert_array_to_real_array(void *from, { for (j = 0; j < nValues; j++) { - to[i*nValues+j] = reinterpret_cast(from)[i*nValues+j] * fact; + to[i * nValues + j] = reinterpret_cast(from)[i * nValues + j] * fact; } } } @@ -1207,7 +1130,7 @@ convert_array_to_real_array(void *from, { for (j = 0; j < nValues; j++) { - to[i*nValues+j] = reinterpret_cast(from)[i*nValues+j] * fact; + to[i * nValues + j] = reinterpret_cast(from)[i * nValues + j] * fact; } } } @@ -1217,7 +1140,7 @@ convert_array_to_real_array(void *from, { for (j = 0; j < nValues; j++) { - to[i*nValues+j] = reinterpret_cast(from)[i*nValues+j] * fact; + to[i * nValues + j] = reinterpret_cast(from)[i * nValues + j] * fact; } } break; @@ -1234,7 +1157,7 @@ convert_array_to_real_array(void *from, { for (j = 0; j < nValues; j++) { - to[i*nValues+j] = reinterpret_cast(from)[i*nValues+j] * fact; + to[i * nValues + j] = reinterpret_cast(from)[i * nValues + j] * fact; } } } @@ -1245,20 +1168,19 @@ convert_array_to_real_array(void *from, { for (j = 0; j < nValues; j++) { - to[i*nValues+j] = reinterpret_cast(from)[i*nValues+j] * fact; + to[i * nValues + j] = reinterpret_cast(from)[i * nValues + j] * fact; } } } break; - default: - gmx_incons("Illegal datatype when converting values to a real array!"); + default: gmx_incons("Illegal datatype when converting values to a real array!"); } } real getDistanceScaleFactor(gmx_tng_trajectory_t in) { - int64_t exp = -1; - real distanceScaleFactor; + int64_t exp = -1; + real distanceScaleFactor; // TODO Hopefully, TNG 2.0 will do this kind of thing for us tng_distance_unit_exponential_get(in->tng, &exp); @@ -1266,14 +1188,9 @@ real getDistanceScaleFactor(gmx_tng_trajectory_t in) // GROMACS expects distances in nm switch (exp) { - case 9: - distanceScaleFactor = NANO/NANO; - break; - case 10: - distanceScaleFactor = NANO/ANGSTROM; - break; - default: - distanceScaleFactor = pow(10.0, exp + 9.0); + case 9: distanceScaleFactor = NANO / NANO; break; + case 10: distanceScaleFactor = NANO / ANGSTROM; break; + default: distanceScaleFactor = pow(10.0, exp + 9.0); } return distanceScaleFactor; @@ -1282,18 +1199,16 @@ real getDistanceScaleFactor(gmx_tng_trajectory_t in) } // namespace -void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t gmx_tng, - gmx::ArrayRef ind, - const char *name) +void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t gmx_tng, gmx::ArrayRef ind, const char* name) { #if GMX_USE_TNG - int64_t nAtoms, cnt, nMols; - tng_molecule_t mol, iterMol; - tng_chain_t chain; - tng_residue_t res; - tng_atom_t atom; - tng_function_status stat; - tng_trajectory_t tng = gmx_tng->tng; + int64_t nAtoms, cnt, nMols; + tng_molecule_t mol, iterMol; + tng_chain_t chain; + tng_residue_t res; + tng_atom_t atom; + tng_function_status stat; + tng_trajectory_t tng = gmx_tng->tng; tng_num_particles_get(tng, &nAtoms); @@ -1325,7 +1240,7 @@ void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t gmx_tng, for (gmx::index i = 0; i < ind.ssize(); i++) { - char temp_name[256], temp_type[256]; + char temp_name[256], temp_type[256]; /* Try to retrieve the residue name of the atom */ stat = tng_residue_name_of_particle_nr_get(tng, ind[i], temp_name, 256); @@ -1334,8 +1249,7 @@ void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t gmx_tng, temp_name[0] = '\0'; } /* Check if the molecule of the selection already contains this residue */ - if (tng_chain_residue_find(tng, chain, temp_name, -1, &res) - != TNG_SUCCESS) + if (tng_chain_residue_find(tng, chain, temp_name, -1, &res) != TNG_SUCCESS) { tng_chain_residue_add(tng, chain, temp_name, &res); } @@ -1378,40 +1292,37 @@ void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t gmx_tng, * uncompressing them, then this implemenation should be reconsidered. * Ideally, gmx trjconv -f a.tng -o b.tng -b 10 -e 20 would be fast * and lose no information. */ -gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, - t_trxframe *fr, - int64_t *requestedIds, - int numRequestedIds) +gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, + t_trxframe* fr, + int64_t* requestedIds, + int numRequestedIds) { #if GMX_USE_TNG - tng_trajectory_t input = gmx_tng_input->tng; - gmx_bool bOK = TRUE; - tng_function_status stat; - int64_t numberOfAtoms = -1, frameNumber = -1; - int64_t nBlocks, blockId, *blockIds = nullptr, codecId; - char datatype = -1; - void *values = nullptr; - double frameTime = -1.0; - int size, blockDependency; - double prec; - const int defaultNumIds = 5; - static int64_t fallbackRequestedIds[defaultNumIds] = - { - TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, - TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, - TNG_GMX_LAMBDA - }; - - - fr->bStep = FALSE; - fr->bTime = FALSE; - fr->bLambda = FALSE; - fr->bAtoms = FALSE; - fr->bPrec = FALSE; - fr->bX = FALSE; - fr->bV = FALSE; - fr->bF = FALSE; - fr->bBox = FALSE; + tng_trajectory_t input = gmx_tng_input->tng; + gmx_bool bOK = TRUE; + tng_function_status stat; + int64_t numberOfAtoms = -1, frameNumber = -1; + int64_t nBlocks, blockId, *blockIds = nullptr, codecId; + char datatype = -1; + void* values = nullptr; + double frameTime = -1.0; + int size, blockDependency; + double prec; + const int defaultNumIds = 5; + static int64_t fallbackRequestedIds[defaultNumIds] = { TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS, + TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES, + TNG_GMX_LAMBDA }; + + + fr->bStep = FALSE; + fr->bTime = FALSE; + fr->bLambda = FALSE; + fr->bAtoms = FALSE; + fr->bPrec = FALSE; + fr->bX = FALSE; + fr->bV = FALSE; + fr->bF = FALSE; + fr->bBox = FALSE; /* If no specific IDs were requested read all block types that can * currently be interpreted */ @@ -1428,13 +1339,8 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, } fr->natoms = numberOfAtoms; - bool nextFrameExists = gmx_get_tng_data_block_types_of_next_frame(gmx_tng_input, - fr->step, - numRequestedIds, - requestedIds, - &frameNumber, - &nBlocks, - &blockIds); + bool nextFrameExists = gmx_get_tng_data_block_types_of_next_frame( + gmx_tng_input, fr->step, numRequestedIds, requestedIds, &frameNumber, &nBlocks, &blockIds); gmx::unique_cptr blockIdsGuard(blockIds); if (!nextFrameExists) { @@ -1452,21 +1358,13 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, tng_data_block_dependency_get(input, blockId, &blockDependency); if (blockDependency & TNG_PARTICLE_DEPENDENT) { - stat = tng_util_particle_data_next_frame_read(input, - blockId, - &values, - &datatype, - &frameNumber, - &frameTime); + stat = tng_util_particle_data_next_frame_read(input, blockId, &values, &datatype, + &frameNumber, &frameTime); } else { - stat = tng_util_non_particle_data_next_frame_read(input, - blockId, - &values, - &datatype, - &frameNumber, - &frameTime); + stat = tng_util_non_particle_data_next_frame_read(input, blockId, &values, &datatype, + &frameNumber, &frameTime); } if (stat == TNG_CRITICAL) { @@ -1482,36 +1380,23 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, case TNG_TRAJ_BOX_SHAPE: switch (datatype) { - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - size = sizeof(double); - break; - default: - gmx_incons("Illegal datatype of box shape values!"); + case TNG_INT_DATA: size = sizeof(int64_t); break; + case TNG_FLOAT_DATA: size = sizeof(float); break; + case TNG_DOUBLE_DATA: size = sizeof(double); break; + default: gmx_incons("Illegal datatype of box shape values!"); } for (int i = 0; i < DIM; i++) { - convert_array_to_real_array(reinterpret_cast(values) + size * i * DIM, - reinterpret_cast(fr->box[i]), - getDistanceScaleFactor(gmx_tng_input), - 1, - DIM, - datatype); + convert_array_to_real_array(reinterpret_cast(values) + size * i * DIM, + reinterpret_cast(fr->box[i]), + getDistanceScaleFactor(gmx_tng_input), 1, DIM, datatype); } fr->bBox = TRUE; break; case TNG_TRAJ_POSITIONS: srenew(fr->x, fr->natoms); - convert_array_to_real_array(values, - reinterpret_cast(fr->x), - getDistanceScaleFactor(gmx_tng_input), - fr->natoms, - DIM, + convert_array_to_real_array(values, reinterpret_cast(fr->x), + getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM, datatype); fr->bX = TRUE; tng_util_frame_current_compression_get(input, blockId, &codecId, &prec); @@ -1524,11 +1409,8 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, break; case TNG_TRAJ_VELOCITIES: srenew(fr->v, fr->natoms); - convert_array_to_real_array(values, - reinterpret_cast(fr->v), - getDistanceScaleFactor(gmx_tng_input), - fr->natoms, - DIM, + convert_array_to_real_array(values, reinterpret_cast(fr->v), + getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM, datatype); fr->bV = TRUE; tng_util_frame_current_compression_get(input, blockId, &codecId, &prec); @@ -1541,30 +1423,24 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, break; case TNG_TRAJ_FORCES: srenew(fr->f, fr->natoms); - convert_array_to_real_array(values, - reinterpret_cast(fr->f), - getDistanceScaleFactor(gmx_tng_input), - fr->natoms, - DIM, + convert_array_to_real_array(values, reinterpret_cast(fr->f), + getDistanceScaleFactor(gmx_tng_input), fr->natoms, DIM, datatype); fr->bF = TRUE; break; case TNG_GMX_LAMBDA: switch (datatype) { - case TNG_FLOAT_DATA: - fr->lambda = *(reinterpret_cast(values)); - break; - case TNG_DOUBLE_DATA: - fr->lambda = *(reinterpret_cast(values)); - break; - default: - gmx_incons("Illegal datatype lambda value!"); + case TNG_FLOAT_DATA: fr->lambda = *(reinterpret_cast(values)); break; + case TNG_DOUBLE_DATA: fr->lambda = *(reinterpret_cast(values)); break; + default: gmx_incons("Illegal datatype lambda value!"); } fr->bLambda = TRUE; break; default: - gmx_warning("Illegal block type! Currently GROMACS tools can only handle certain data types. Skipping block."); + gmx_warning( + "Illegal block type! Currently GROMACS tools can only handle certain data " + "types. Skipping block."); } /* values does not have to be freed before reading next frame. It will * be reallocated if it is not NULL. */ @@ -1591,8 +1467,7 @@ gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t gmx_tng_input, #endif } -void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, - FILE *stream) +void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, FILE* stream) { #if GMX_USE_TNG int64_t nMolecules, nChains, nResidues, nAtoms, nFramesRead; @@ -1605,7 +1480,7 @@ void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, char str[256]; char varNAtoms; char datatype; - void *data = nullptr; + void* data = nullptr; std::vector atomCharges; std::vector atomMasses; tng_trajectory_t input = gmx_tng_input->tng; @@ -1698,17 +1573,11 @@ void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, tng_num_particles_get(input, &nAtoms); stat = tng_particle_data_vector_get(input, TNG_TRAJ_PARTIAL_CHARGES, &data, &nFramesRead, - &strideLength, &nParticlesRead, - &nValuesPerFrameRead, &datatype); + &strideLength, &nParticlesRead, &nValuesPerFrameRead, &datatype); if (stat == TNG_SUCCESS) { atomCharges.resize(nAtoms); - convert_array_to_real_array(data, - atomCharges.data(), - 1, - nAtoms, - 1, - datatype); + convert_array_to_real_array(data, atomCharges.data(), 1, nAtoms, 1, datatype); fprintf(stream, "Atom Charges (%d):\n", int(nAtoms)); for (int64_t i = 0; i < nAtoms; i += 10) @@ -1722,18 +1591,12 @@ void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, } } - stat = tng_particle_data_vector_get(input, TNG_TRAJ_MASSES, &data, &nFramesRead, - &strideLength, &nParticlesRead, - &nValuesPerFrameRead, &datatype); + stat = tng_particle_data_vector_get(input, TNG_TRAJ_MASSES, &data, &nFramesRead, &strideLength, + &nParticlesRead, &nValuesPerFrameRead, &datatype); if (stat == TNG_SUCCESS) { atomMasses.resize(nAtoms); - convert_array_to_real_array(data, - atomMasses.data(), - 1, - nAtoms, - 1, - datatype); + convert_array_to_real_array(data, atomMasses.data(), 1, nAtoms, 1, datatype); fprintf(stream, "Atom Masses (%d):\n", int(nAtoms)); for (int64_t i = 0; i < nAtoms; i += 10) @@ -1757,19 +1620,17 @@ void gmx_print_tng_molecule_system(gmx_tng_trajectory_t gmx_tng_input, gmx_bool gmx_get_tng_data_block_types_of_next_frame(gmx_tng_trajectory_t gmx_tng_input, int frame, int nRequestedIds, - int64_t *requestedIds, - int64_t *nextFrame, - int64_t *nBlocks, - int64_t **blockIds) + int64_t* requestedIds, + int64_t* nextFrame, + int64_t* nBlocks, + int64_t** blockIds) { #if GMX_USE_TNG tng_function_status stat; tng_trajectory_t input = gmx_tng_input->tng; - stat = tng_util_trajectory_next_frame_present_data_blocks_find(input, frame, - nRequestedIds, requestedIds, - nextFrame, - nBlocks, blockIds); + stat = tng_util_trajectory_next_frame_present_data_blocks_find( + input, frame, nRequestedIds, requestedIds, nextFrame, nBlocks, blockIds); if (stat == TNG_CRITICAL) { @@ -1794,22 +1655,22 @@ gmx_bool gmx_get_tng_data_block_types_of_next_frame(gmx_tng_trajectory_t gmx_tng gmx_bool gmx_get_tng_data_next_frame_of_block_type(gmx_tng_trajectory_t gmx_tng_input, int64_t blockId, - real **values, - int64_t *frameNumber, - double *frameTime, - int64_t *nValuesPerFrame, - int64_t *nAtoms, - real *prec, - char *name, + real** values, + int64_t* frameNumber, + double* frameTime, + int64_t* nValuesPerFrame, + int64_t* nAtoms, + real* prec, + char* name, int maxLen, - gmx_bool *bOK) + gmx_bool* bOK) { #if GMX_USE_TNG tng_function_status stat; char datatype = -1; int64_t codecId; int blockDependency; - void *data = nullptr; + void* data = nullptr; double localPrec; tng_trajectory_t input = gmx_tng_input->tng; @@ -1826,23 +1687,15 @@ gmx_bool gmx_get_tng_data_next_frame_of_block_type(gmx_tng_trajectory_t gmx_tng_ if (blockDependency & TNG_PARTICLE_DEPENDENT) { tng_num_particles_get(input, nAtoms); - stat = tng_util_particle_data_next_frame_read(input, - blockId, - &data, - &datatype, - frameNumber, + stat = tng_util_particle_data_next_frame_read(input, blockId, &data, &datatype, frameNumber, frameTime); } else { *nAtoms = 1; /* There are not actually any atoms, but it is used for allocating memory */ - stat = tng_util_non_particle_data_next_frame_read(input, - blockId, - &data, - &datatype, - frameNumber, - frameTime); + stat = tng_util_non_particle_data_next_frame_read(input, blockId, &data, &datatype, + frameNumber, frameTime); } if (stat == TNG_CRITICAL) { @@ -1860,12 +1713,8 @@ gmx_bool gmx_get_tng_data_next_frame_of_block_type(gmx_tng_trajectory_t gmx_tng_ gmx_file("Cannot read next frame of TNG file"); } srenew(*values, sizeof(real) * *nValuesPerFrame * *nAtoms); - convert_array_to_real_array(data, - *values, - getDistanceScaleFactor(gmx_tng_input), - *nAtoms, - *nValuesPerFrame, - datatype); + convert_array_to_real_array(data, *values, getDistanceScaleFactor(gmx_tng_input), *nAtoms, + *nValuesPerFrame, datatype); tng_util_frame_current_compression_get(input, blockId, &codecId, &localPrec); diff --git a/src/gromacs/fileio/tngio.h b/src/gromacs/fileio/tngio.h index d3595de9da..d3e2273f09 100644 --- a/src/gromacs/fileio/tngio.h +++ b/src/gromacs/fileio/tngio.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,7 +46,7 @@ struct gmx_mtop_t; struct t_inputrec; struct gmx_tng_trajectory; -typedef struct gmx_tng_trajectory *gmx_tng_trajectory_t; +typedef struct gmx_tng_trajectory* gmx_tng_trajectory_t; struct t_trxframe; /*! \brief Open a TNG trajectory file @@ -57,12 +57,10 @@ struct t_trxframe; * * Handles all I/O errors internally via fatal error */ -void gmx_tng_open(const char *filename, - char mode, - gmx_tng_trajectory_t *tng_data_p); +void gmx_tng_open(const char* filename, char mode, gmx_tng_trajectory_t* tng_data_p); /*! \brief Finish writing a TNG trajectory file */ -void gmx_tng_close(gmx_tng_trajectory_t *tng); +void gmx_tng_close(gmx_tng_trajectory_t* tng); /*!\brief Add molecular topology information to TNG output (if * available) @@ -70,8 +68,7 @@ void gmx_tng_close(gmx_tng_trajectory_t *tng); * \param tng Valid handle to a TNG trajectory * \param mtop Pointer to a topology (can be NULL) */ -void gmx_tng_add_mtop(gmx_tng_trajectory_t tng, - const gmx_mtop_t *mtop); +void gmx_tng_add_mtop(gmx_tng_trajectory_t tng, const gmx_mtop_t* mtop); /*! \brief Do all TNG preparation for full-precision whole-system * trajectory writing during MD simulations. @@ -80,16 +77,13 @@ void gmx_tng_add_mtop(gmx_tng_trajectory_t tng, * \param mtop Global topology * \param ir Input settings (for writing frequencies) */ -void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t tng, - const gmx_mtop_t *mtop, - const t_inputrec *ir); +void gmx_tng_prepare_md_writing(gmx_tng_trajectory_t tng, const gmx_mtop_t* mtop, const t_inputrec* ir); /*! \brief Set the default compression precision for TNG writing * * \param tng Valid handle to a TNG trajectory * \param prec GROMACS-style precision setting (i.e. 1000 for 3 digits of precision) */ -void gmx_tng_set_compression_precision(gmx_tng_trajectory_t tng, - real prec); +void gmx_tng_set_compression_precision(gmx_tng_trajectory_t tng, real prec); /*! \brief Do all TNG preparation for low-precision selection-based * trajectory writing during MD simulations. @@ -98,9 +92,7 @@ void gmx_tng_set_compression_precision(gmx_tng_trajectory_t tng, * \param mtop Global topology * \param ir Input settings (for writing frequencies) */ -void gmx_tng_prepare_low_prec_writing(gmx_tng_trajectory_t tng, - const gmx_mtop_t *mtop, - const t_inputrec *ir); +void gmx_tng_prepare_low_prec_writing(gmx_tng_trajectory_t tng, const gmx_mtop_t* mtop, const t_inputrec* ir); /*! \brief Write a frame to a TNG file * @@ -122,11 +114,11 @@ void gmx_fwrite_tng(gmx_tng_trajectory_t tng, int64_t step, real elapsedPicoSeconds, real lambda, - const rvec *box, + const rvec* box, int nAtoms, - const rvec *x, - const rvec *v, - const rvec *f); + const rvec* x, + const rvec* v, + const rvec* f); /*! \brief Write the current frame set to disk. Perform compression * etc. @@ -143,14 +135,14 @@ void fflush_tng(gmx_tng_trajectory_t tng); float gmx_tng_get_time_of_final_frame(gmx_tng_trajectory_t tng); /*! \brief Prepare to write TNG output from trajectory conversion tools */ -void gmx_prepare_tng_writing(const char *filename, +void gmx_prepare_tng_writing(const char* filename, char mode, - gmx_tng_trajectory_t *in, - gmx_tng_trajectory_t *out, + gmx_tng_trajectory_t* in, + gmx_tng_trajectory_t* out, int nAtoms, - const struct gmx_mtop_t *mtop, + const struct gmx_mtop_t* mtop, gmx::ArrayRef index, - const char *indexGroupName); + const char* indexGroupName); /*! \brief Write a trxframe to a TNG file * @@ -162,49 +154,44 @@ void gmx_prepare_tng_writing(const char *filename, * parameter natoms supports writing an index-group subset of the * atoms. */ -void gmx_write_tng_from_trxframe(gmx_tng_trajectory_t output, - const t_trxframe *frame, - int natoms); +void gmx_write_tng_from_trxframe(gmx_tng_trajectory_t output, const t_trxframe* frame, int natoms); /*! \brief Creates a molecule containing only the indexed atoms and sets * the number of all other molecules to 0. Works similar to a * selection group. */ -void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t tng, - gmx::ArrayRef ind, - const char *name); +void gmx_tng_setup_atom_subgroup(gmx_tng_trajectory_t tng, gmx::ArrayRef ind, const char* name); /*! \brief Read the first/next TNG frame. */ -gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t input, - struct t_trxframe *fr, - int64_t *requestedIds, - int numRequestedIds); +gmx_bool gmx_read_next_tng_frame(gmx_tng_trajectory_t input, + struct t_trxframe* fr, + int64_t* requestedIds, + int numRequestedIds); /*! \brief Print the molecule system to stream */ -void gmx_print_tng_molecule_system(gmx_tng_trajectory_t input, - FILE *stream); +void gmx_print_tng_molecule_system(gmx_tng_trajectory_t input, FILE* stream); /*! \brief Get a list of block IDs present in the next frame with data. */ gmx_bool gmx_get_tng_data_block_types_of_next_frame(gmx_tng_trajectory_t input, int frame, int nRequestedIds, - int64_t *requestedIds, - int64_t *nextFrame, - int64_t *nBlocks, - int64_t **blockIds); + int64_t* requestedIds, + int64_t* nextFrame, + int64_t* nBlocks, + int64_t** blockIds); /*! \brief Get data of the next frame with data from the data block * with the specified block ID. */ gmx_bool gmx_get_tng_data_next_frame_of_block_type(gmx_tng_trajectory_t input, int64_t blockId, - real **values, - int64_t *frameNumber, - double *frameTime, - int64_t *nValuesPerFrame, - int64_t *nAtoms, - real *prec, - char *name, + real** values, + int64_t* frameNumber, + double* frameTime, + int64_t* nValuesPerFrame, + int64_t* nAtoms, + real* prec, + char* name, int maxLen, - gmx_bool *bOK); + gmx_bool* bOK); /*! \brief Get the output interval of box size. * diff --git a/src/gromacs/fileio/tpxio.cpp b/src/gromacs/fileio/tpxio.cpp index 971ebab155..86698e5e82 100644 --- a/src/gromacs/fileio/tpxio.cpp +++ b/src/gromacs/fileio/tpxio.cpp @@ -79,7 +79,7 @@ #include "gromacs/utility/snprintf.h" #include "gromacs/utility/txtdump.h" -#define TPX_TAG_RELEASE "release" +#define TPX_TAG_RELEASE "release" /*! \brief Tag string for the file format written to run input files * written by this version of the code. @@ -91,7 +91,7 @@ * merging with mainstream GROMACS, set this tag string back to * TPX_TAG_RELEASE, and instead add an element to tpxv. */ -static const char *tpx_tag = TPX_TAG_RELEASE; +static const char* tpx_tag = TPX_TAG_RELEASE; /*! \brief Enum of values that describe the contents of a tpr file * whose format matches a version number @@ -104,31 +104,32 @@ static const char *tpx_tag = TPX_TAG_RELEASE; */ enum tpxv { - tpxv_ComputationalElectrophysiology = 96, /**< support for ion/water position swaps (computational electrophysiology) */ - tpxv_Use64BitRandomSeed, /**< change ld_seed from int to int64_t */ + tpxv_ComputationalElectrophysiology = + 96, /**< support for ion/water position swaps (computational electrophysiology) */ + tpxv_Use64BitRandomSeed, /**< change ld_seed from int to int64_t */ tpxv_RestrictedBendingAndCombinedAngleTorsionPotentials, /**< potentials for supporting coarse-grained force fields */ - tpxv_InteractiveMolecularDynamics, /**< interactive molecular dynamics (IMD) */ - tpxv_RemoveObsoleteParameters1, /**< remove optimize_fft, dihre_fc, nstcheckpoint */ - tpxv_PullCoordTypeGeom, /**< add pull type and geometry per group and flat-bottom */ - tpxv_PullGeomDirRel, /**< add pull geometry direction-relative */ - tpxv_IntermolecularBondeds, /**< permit inter-molecular bonded interactions in the topology */ - tpxv_CompElWithSwapLayerOffset, /**< added parameters for improved CompEl setups */ - tpxv_CompElPolyatomicIonsAndMultipleIonTypes, /**< CompEl now can handle polyatomic ions and more than two types of ions */ - tpxv_RemoveAdress, /**< removed support for AdResS */ - tpxv_PullCoordNGroup, /**< add ngroup to pull coord */ - tpxv_RemoveTwinRange, /**< removed support for twin-range interactions */ - tpxv_ReplacePullPrintCOM12, /**< Replaced print-com-1, 2 with pull-print-com */ - tpxv_PullExternalPotential, /**< Added pull type external potential */ - tpxv_GenericParamsForElectricField, /**< Introduced KeyValueTree and moved electric field parameters */ - tpxv_AcceleratedWeightHistogram, /**< sampling with accelerated weight histogram method (AWH) */ - tpxv_RemoveImplicitSolvation, /**< removed support for implicit solvation */ - tpxv_PullPrevStepCOMAsReference, /**< Enabled using the COM of the pull group of the last frame as reference for PBC */ - tpxv_MimicQMMM, /**< Introduced support for MiMiC QM/MM interface */ - tpxv_PullAverage, /**< Added possibility to output average pull force and position */ - tpxv_GenericInternalParameters, /**< Added internal parameters for mdrun modules*/ - tpxv_VSite2FD, /**< Added 2FD type virtual site */ - tpxv_AddSizeField, /**< Added field with information about the size of the serialized tpr file in bytes, excluding the header */ - tpxv_Count /**< the total number of tpxv versions */ + tpxv_InteractiveMolecularDynamics, /**< interactive molecular dynamics (IMD) */ + tpxv_RemoveObsoleteParameters1, /**< remove optimize_fft, dihre_fc, nstcheckpoint */ + tpxv_PullCoordTypeGeom, /**< add pull type and geometry per group and flat-bottom */ + tpxv_PullGeomDirRel, /**< add pull geometry direction-relative */ + tpxv_IntermolecularBondeds, /**< permit inter-molecular bonded interactions in the topology */ + tpxv_CompElWithSwapLayerOffset, /**< added parameters for improved CompEl setups */ + tpxv_CompElPolyatomicIonsAndMultipleIonTypes, /**< CompEl now can handle polyatomic ions and more than two types of ions */ + tpxv_RemoveAdress, /**< removed support for AdResS */ + tpxv_PullCoordNGroup, /**< add ngroup to pull coord */ + tpxv_RemoveTwinRange, /**< removed support for twin-range interactions */ + tpxv_ReplacePullPrintCOM12, /**< Replaced print-com-1, 2 with pull-print-com */ + tpxv_PullExternalPotential, /**< Added pull type external potential */ + tpxv_GenericParamsForElectricField, /**< Introduced KeyValueTree and moved electric field parameters */ + tpxv_AcceleratedWeightHistogram, /**< sampling with accelerated weight histogram method (AWH) */ + tpxv_RemoveImplicitSolvation, /**< removed support for implicit solvation */ + tpxv_PullPrevStepCOMAsReference, /**< Enabled using the COM of the pull group of the last frame as reference for PBC */ + tpxv_MimicQMMM, /**< Introduced support for MiMiC QM/MM interface */ + tpxv_PullAverage, /**< Added possibility to output average pull force and position */ + tpxv_GenericInternalParameters, /**< Added internal parameters for mdrun modules*/ + tpxv_VSite2FD, /**< Added 2FD type virtual site */ + tpxv_AddSizeField, /**< Added field with information about the size of the serialized tpr file in bytes, excluding the header */ + tpxv_Count /**< the total number of tpxv versions */ }; /*! \brief Version number of the file format written to run input @@ -168,9 +169,9 @@ static const int tpx_generation = 27; static const int tpx_incompatible_version = 57; // GMX4.0 has version 58 - /* Struct used to maintain tpx compatibility when function types are added */ -typedef struct { +typedef struct +{ int fvnr; /* file version number in which the function type first appeared */ int ftype; /* function type */ } t_ftupd; @@ -190,27 +191,33 @@ typedef struct { * them to make things clear. */ static const t_ftupd ftupd[] = { - { 70, F_RESTRBONDS }, + { 70, F_RESTRBONDS }, { tpxv_RestrictedBendingAndCombinedAngleTorsionPotentials, F_RESTRANGLES }, - { 76, F_LINEAR_ANGLES }, + { 76, F_LINEAR_ANGLES }, { tpxv_RestrictedBendingAndCombinedAngleTorsionPotentials, F_RESTRDIHS }, { tpxv_RestrictedBendingAndCombinedAngleTorsionPotentials, F_CBTDIHS }, - { 65, F_CMAP }, + { 65, F_CMAP }, { 60, F_GB12_NOLONGERUSED }, { 61, F_GB13_NOLONGERUSED }, { 61, F_GB14_NOLONGERUSED }, { 72, F_GBPOL_NOLONGERUSED }, { 72, F_NPSOLVATION_NOLONGERUSED }, - { 93, F_LJ_RECIP }, - { 90, F_FBPOSRES }, - { 69, F_VTEMP_NOLONGERUSED}, - { 66, F_PDISPCORR }, - { 76, F_ANHARM_POL }, - { 79, F_DVDL_COUL }, - { 79, F_DVDL_VDW, }, - { 79, F_DVDL_BONDED, }, - { 79, F_DVDL_RESTRAINT }, - { 79, F_DVDL_TEMPERATURE }, + { 93, F_LJ_RECIP }, + { 90, F_FBPOSRES }, + { 69, F_VTEMP_NOLONGERUSED }, + { 66, F_PDISPCORR }, + { 76, F_ANHARM_POL }, + { 79, F_DVDL_COUL }, + { + 79, + F_DVDL_VDW, + }, + { + 79, + F_DVDL_BONDED, + }, + { 79, F_DVDL_RESTRAINT }, + { 79, F_DVDL_TEMPERATURE }, { tpxv_GenericInternalParameters, F_DENSITYFITTING }, { tpxv_VSite2FD, F_VSITE2FD }, }; @@ -224,9 +231,7 @@ static const t_ftupd ftupd[] = { * Now the higer level routines that do io of the structures and arrays * **************************************************************/ -static void do_pullgrp_tpx_pre95(gmx::ISerializer *serializer, - t_pull_group *pgrp, - t_pull_coord *pcrd) +static void do_pullgrp_tpx_pre95(gmx::ISerializer* serializer, t_pull_group* pgrp, t_pull_coord* pcrd) { rvec tmp; @@ -252,7 +257,7 @@ static void do_pullgrp_tpx_pre95(gmx::ISerializer *serializer, serializer->doReal(&pcrd->kB); } -static void do_pull_group(gmx::ISerializer *serializer, t_pull_group *pgrp) +static void do_pull_group(gmx::ISerializer* serializer, t_pull_group* pgrp) { serializer->doInt(&pgrp->nat); if (serializer->reading()) @@ -269,10 +274,12 @@ static void do_pull_group(gmx::ISerializer *serializer, t_pull_group *pgrp) serializer->doInt(&pgrp->pbcatom); } -static void do_pull_coord(gmx::ISerializer *serializer, - t_pull_coord *pcrd, - int file_version, - int ePullOld, int eGeomOld, ivec dimOld) +static void do_pull_coord(gmx::ISerializer* serializer, + t_pull_coord* pcrd, + int file_version, + int ePullOld, + int eGeomOld, + ivec dimOld) { if (file_version >= tpxv_PullCoordNGroup) { @@ -322,7 +329,7 @@ static void do_pull_coord(gmx::ISerializer *serializer, * use the groups for this coord (checks in the pull and WHAM code * ensure this), we can ignore the groups and set ngroup=0. */ - int *dum; + int* dum; snew(dum, pcrd->ngroup); serializer->doIntArray(dum, pcrd->ngroup); sfree(dum); @@ -372,12 +379,9 @@ static void do_pull_coord(gmx::ISerializer *serializer, serializer->doReal(&pcrd->kB); } -static void do_expandedvals(gmx::ISerializer *serializer, - t_expanded *expand, - t_lambda *fepvals, - int file_version) +static void do_expandedvals(gmx::ISerializer* serializer, t_expanded* expand, t_lambda* fepvals, int file_version) { - int n_lambda = fepvals->n_lambda; + int n_lambda = fepvals->n_lambda; /* reset the lambda calculation window */ fepvals->lambda_start_n = 0; @@ -419,10 +423,7 @@ static void do_expandedvals(gmx::ISerializer *serializer, } } -static void do_simtempvals(gmx::ISerializer *serializer, - t_simtemp *simtemp, - int n_lambda, - int file_version) +static void do_simtempvals(gmx::ISerializer* serializer, t_simtemp* simtemp, int n_lambda, int file_version) { if (file_version >= 79) { @@ -440,7 +441,7 @@ static void do_simtempvals(gmx::ISerializer *serializer, } } -static void do_imd(gmx::ISerializer *serializer, t_IMD *imd) +static void do_imd(gmx::ISerializer* serializer, t_IMD* imd) { serializer->doInt(&imd->nat); if (serializer->reading()) @@ -450,13 +451,11 @@ static void do_imd(gmx::ISerializer *serializer, t_IMD *imd) serializer->doIntArray(imd->ind, imd->nat); } -static void do_fepvals(gmx::ISerializer *serializer, - t_lambda *fepvals, - int file_version) +static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file_version) { /* i is defined in the ndo_double macro; use g to iterate. */ - int g; - real rdum; + int g; + real rdum; /* free energy values */ @@ -536,8 +535,7 @@ static void do_fepvals(gmx::ISerializer *serializer, { if (g != efptFEP) { - fepvals->all_lambda[g][h] = - fepvals->all_lambda[efptFEP][h]; + fepvals->all_lambda[g][h] = fepvals->all_lambda[efptFEP][h]; } } } @@ -546,8 +544,8 @@ static void do_fepvals(gmx::ISerializer *serializer, } else { - fepvals->n_lambda = 0; - fepvals->all_lambda = nullptr; + fepvals->n_lambda = 0; + fepvals->all_lambda = nullptr; if (fepvals->init_lambda >= 0) { fepvals->separate_dvdl[efptFEP] = TRUE; @@ -625,13 +623,11 @@ static void do_fepvals(gmx::ISerializer *serializer, if ((file_version >= 83 && file_version < 90) || file_version >= 92) { serializer->doInt(&fepvals->lambda_neighbors); - if ( (fepvals->lambda_neighbors >= 0) && (fepvals->init_fep_state >= 0) && - (fepvals->init_lambda < 0) ) + if ((fepvals->lambda_neighbors >= 0) && (fepvals->init_fep_state >= 0) + && (fepvals->init_lambda < 0)) { - fepvals->lambda_start_n = (fepvals->init_fep_state - - fepvals->lambda_neighbors); - fepvals->lambda_stop_n = (fepvals->init_fep_state + - fepvals->lambda_neighbors + 1); + fepvals->lambda_start_n = (fepvals->init_fep_state - fepvals->lambda_neighbors); + fepvals->lambda_stop_n = (fepvals->init_fep_state + fepvals->lambda_neighbors + 1); if (fepvals->lambda_start_n < 0) { fepvals->lambda_start_n = 0; @@ -654,8 +650,7 @@ static void do_fepvals(gmx::ISerializer *serializer, } } -static void do_awhBias(gmx::ISerializer *serializer, gmx::AwhBiasParams *awhBiasParams, - int gmx_unused file_version) +static void do_awhBias(gmx::ISerializer* serializer, gmx::AwhBiasParams* awhBiasParams, int gmx_unused file_version) { serializer->doInt(&awhBiasParams->eTarget); serializer->doDouble(&awhBiasParams->targetBetaScaling); @@ -674,7 +669,7 @@ static void do_awhBias(gmx::ISerializer *serializer, gmx::AwhBiasParams *awhBias for (int d = 0; d < awhBiasParams->ndim; d++) { - gmx::AwhDimParams *dimParams = &awhBiasParams->dimParams[d]; + gmx::AwhDimParams* dimParams = &awhBiasParams->dimParams[d]; serializer->doInt(&dimParams->eCoordProvider); serializer->doInt(&dimParams->coordIndex); @@ -688,9 +683,7 @@ static void do_awhBias(gmx::ISerializer *serializer, gmx::AwhBiasParams *awhBias } } -static void do_awh(gmx::ISerializer *serializer, - gmx::AwhParams *awhParams, - int gmx_unused file_version) +static void do_awh(gmx::ISerializer* serializer, gmx::AwhParams* awhParams, int gmx_unused file_version) { serializer->doInt(&awhParams->numBias); serializer->doInt(&awhParams->nstOut); @@ -714,10 +707,7 @@ static void do_awh(gmx::ISerializer *serializer, } } -static void do_pull(gmx::ISerializer *serializer, - pull_params_t *pull, - int file_version, - int ePullOld) +static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_version, int ePullOld) { int eGeomOld = -1; ivec dimOld; @@ -795,11 +785,11 @@ static void do_pull(gmx::ISerializer *serializer, for (g = 0; g < pull->ngroup; g++) { /* We read and ignore a pull coordinate for group 0 */ - do_pullgrp_tpx_pre95(serializer, &pull->group[g], &pull->coord[std::max(g-1, 0)]); + do_pullgrp_tpx_pre95(serializer, &pull->group[g], &pull->coord[std::max(g - 1, 0)]); if (g > 0) { - pull->coord[g-1].group[0] = 0; - pull->coord[g-1].group[1] = g; + pull->coord[g - 1].group[0] = 0; + pull->coord[g - 1].group[1] = g; } } @@ -813,15 +803,14 @@ static void do_pull(gmx::ISerializer *serializer, } for (g = 0; g < pull->ncoord; g++) { - do_pull_coord(serializer, &pull->coord[g], - file_version, ePullOld, eGeomOld, dimOld); + do_pull_coord(serializer, &pull->coord[g], file_version, ePullOld, eGeomOld, dimOld); } } if (file_version >= tpxv_PullAverage) { gmx_bool v; - v = pull->bXOutAverage; + v = pull->bXOutAverage; serializer->doBool(&v); pull->bXOutAverage = v; v = pull->bFOutAverage; @@ -831,8 +820,7 @@ static void do_pull(gmx::ISerializer *serializer, } -static void do_rotgrp(gmx::ISerializer *serializer, - t_rotgrp *rotg) +static void do_rotgrp(gmx::ISerializer* serializer, t_rotgrp* rotg) { serializer->doInt(&rotg->eType); serializer->doInt(&rotg->bMassW); @@ -859,8 +847,7 @@ static void do_rotgrp(gmx::ISerializer *serializer, serializer->doReal(&rotg->PotAngle_step); } -static void do_rot(gmx::ISerializer *serializer, - t_rot *rot) +static void do_rot(gmx::ISerializer* serializer, t_rot* rot) { int g; @@ -878,8 +865,7 @@ static void do_rot(gmx::ISerializer *serializer, } -static void do_swapgroup(gmx::ISerializer *serializer, - t_swapGroup *g) +static void do_swapgroup(gmx::ISerializer* serializer, t_swapGroup* g) { /* Name of the group or molecule */ @@ -909,16 +895,18 @@ static void do_swapgroup(gmx::ISerializer *serializer, serializer->doIntArray(g->nmolReq, eCompNR); } -static void do_swapcoords_tpx(gmx::ISerializer *serializer, - t_swapcoords *swap, - int file_version) +static void do_swapcoords_tpx(gmx::ISerializer* serializer, t_swapcoords* swap, int file_version) { /* Enums for better readability of the code */ - enum { - eCompA = 0, eCompB + enum + { + eCompA = 0, + eCompB }; - enum { - eChannel0 = 0, eChannel1 + enum + { + eChannel0 = 0, + eChannel1 }; @@ -956,11 +944,11 @@ static void do_swapcoords_tpx(gmx::ISerializer *serializer, swap->ngrp = 5; snew(swap->grp, swap->ngrp); - swap->grp[eGrpSplit0 ].molname = gmx_strdup("split0" ); // group 0: split0 - swap->grp[eGrpSplit1 ].molname = gmx_strdup("split1" ); // group 1: split1 - swap->grp[eGrpSolvent].molname = gmx_strdup("solvent"); // group 2: solvent - swap->grp[3 ].molname = gmx_strdup("anions" ); // group 3: anions - swap->grp[4 ].molname = gmx_strdup("cations"); // group 4: cations + swap->grp[eGrpSplit0].molname = gmx_strdup("split0"); // group 0: split0 + swap->grp[eGrpSplit1].molname = gmx_strdup("split1"); // group 1: split1 + swap->grp[eGrpSolvent].molname = gmx_strdup("solvent"); // group 2: solvent + swap->grp[3].molname = gmx_strdup("anions"); // group 3: anions + swap->grp[4].molname = gmx_strdup("cations"); // group 4: cations serializer->doInt(&swap->grp[3].nat); serializer->doInt(&swap->grp[eGrpSolvent].nat); @@ -981,7 +969,7 @@ static void do_swapcoords_tpx(gmx::ISerializer *serializer, // The order[] array keeps compatibility with older .tpr files // by reading in the groups in the classic order { - const int order[4] = {3, eGrpSolvent, eGrpSplit0, eGrpSplit1 }; + const int order[4] = { 3, eGrpSolvent, eGrpSplit0, eGrpSplit1 }; for (int ig = 0; ig < 4; ig++) { @@ -996,22 +984,21 @@ static void do_swapcoords_tpx(gmx::ISerializer *serializer, serializer->doInt(&swap->grp[3].nmolReq[j]); // group 3 = anions serializer->doInt(&swap->grp[4].nmolReq[j]); // group 4 = cations } - } /* End support reading older CompEl .tpr files */ + } /* End support reading older CompEl .tpr files */ if (file_version >= tpxv_CompElWithSwapLayerOffset) { serializer->doReal(&swap->bulkOffset[eCompA]); serializer->doReal(&swap->bulkOffset[eCompB]); } - } -static void do_legacy_efield(gmx::ISerializer *serializer, gmx::KeyValueTreeObjectBuilder *root) +static void do_legacy_efield(gmx::ISerializer* serializer, gmx::KeyValueTreeObjectBuilder* root) { - const char *const dimName[] = { "x", "y", "z" }; + const char* const dimName[] = { "x", "y", "z" }; - auto appliedForcesObj = root->addObject("applied-forces"); - auto efieldObj = appliedForcesObj.addObject("electric-field"); + auto appliedForcesObj = root->addObject("applied-forces"); + auto efieldObj = appliedForcesObj.addObject("electric-field"); // The content of the tpr file for this feature has // been the same since gromacs 4.0 that was used for // developing. @@ -1020,16 +1007,18 @@ static void do_legacy_efield(gmx::ISerializer *serializer, gmx::KeyValueTreeObje int n, nt; serializer->doInt(&n); serializer->doInt(&nt); - std::vector aa(n+1), phi(nt+1), at(nt+1), phit(nt+1); - serializer->doRealArray(aa.data(), n); + std::vector aa(n + 1), phi(nt + 1), at(nt + 1), phit(nt + 1); + serializer->doRealArray(aa.data(), n); serializer->doRealArray(phi.data(), n); - serializer->doRealArray(at.data(), nt); + serializer->doRealArray(at.data(), nt); serializer->doRealArray(phit.data(), nt); if (n > 0) { if (n > 1 || nt > 1) { - gmx_fatal(FARGS, "Can not handle tpr files with more than one electric field term per direction."); + gmx_fatal(FARGS, + "Can not handle tpr files with more than one electric field term per " + "direction."); } auto dimObj = efieldObj.addObject(dimName[j]); dimObj.addValue("E0", aa[0]); @@ -1041,9 +1030,7 @@ static void do_legacy_efield(gmx::ISerializer *serializer, gmx::KeyValueTreeObje } -static void do_inputrec(gmx::ISerializer *serializer, - t_inputrec *ir, - int file_version) +static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_version) { int i, j, k, idum = 0; real rdum; @@ -1052,8 +1039,7 @@ static void do_inputrec(gmx::ISerializer *serializer, if (file_version != tpx_version) { /* Give a warning about features that are not accessible */ - fprintf(stderr, "Note: file tpx version %d, software tpx version %d\n", - file_version, tpx_version); + fprintf(stderr, "Note: file tpx version %d, software tpx version %d\n", file_version, tpx_version); } if (file_version == 0) @@ -1560,16 +1546,16 @@ static void do_inputrec(gmx::ISerializer *serializer, if (serializer->reading()) { - snew(ir->opts.nrdf, ir->opts.ngtc); - snew(ir->opts.ref_t, ir->opts.ngtc); + snew(ir->opts.nrdf, ir->opts.ngtc); + snew(ir->opts.ref_t, ir->opts.ngtc); snew(ir->opts.annealing, ir->opts.ngtc); snew(ir->opts.anneal_npoints, ir->opts.ngtc); snew(ir->opts.anneal_time, ir->opts.ngtc); snew(ir->opts.anneal_temp, ir->opts.ngtc); - snew(ir->opts.tau_t, ir->opts.ngtc); + snew(ir->opts.tau_t, ir->opts.ngtc); snew(ir->opts.nFreeze, ir->opts.ngfrz); - snew(ir->opts.acc, ir->opts.ngacc); - snew(ir->opts.egp_flags, ir->opts.ngener*ir->opts.ngener); + snew(ir->opts.acc, ir->opts.ngacc); + snew(ir->opts.egp_flags, ir->opts.ngener * ir->opts.ngener); } if (ir->opts.ngtc > 0) { @@ -1585,8 +1571,7 @@ static void do_inputrec(gmx::ISerializer *serializer, { serializer->doRvecArray(ir->opts.acc, ir->opts.ngacc); } - serializer->doIntArray(ir->opts.egp_flags, - ir->opts.ngener*ir->opts.ngener); + serializer->doIntArray(ir->opts.egp_flags, ir->opts.ngener * ir->opts.ngener); /* First read the lists with annealing and npoints for each group */ serializer->doIntArray(ir->opts.annealing, ir->opts.ngtc); @@ -1642,16 +1627,16 @@ static void do_inputrec(gmx::ISerializer *serializer, serializer->doInt(&ir->opts.ngQM); if (serializer->reading()) { - snew(ir->opts.QMmethod, ir->opts.ngQM); - snew(ir->opts.QMbasis, ir->opts.ngQM); - snew(ir->opts.QMcharge, ir->opts.ngQM); - snew(ir->opts.QMmult, ir->opts.ngQM); - snew(ir->opts.bSH, ir->opts.ngQM); + snew(ir->opts.QMmethod, ir->opts.ngQM); + snew(ir->opts.QMbasis, ir->opts.ngQM); + snew(ir->opts.QMcharge, ir->opts.ngQM); + snew(ir->opts.QMmult, ir->opts.ngQM); + snew(ir->opts.bSH, ir->opts.ngQM); snew(ir->opts.CASorbitals, ir->opts.ngQM); snew(ir->opts.CASelectrons, ir->opts.ngQM); - snew(ir->opts.SAon, ir->opts.ngQM); - snew(ir->opts.SAoff, ir->opts.ngQM); - snew(ir->opts.SAsteps, ir->opts.ngQM); + snew(ir->opts.SAon, ir->opts.ngQM); + snew(ir->opts.SAoff, ir->opts.ngQM); + snew(ir->opts.SAsteps, ir->opts.ngQM); } if (ir->opts.ngQM > 0 && ir->bQMMM) { @@ -1679,8 +1664,7 @@ static void do_inputrec(gmx::ISerializer *serializer, { if (serializer->reading()) { - paramsObj.mergeObject( - gmx::deserializeKeyValueTree(serializer)); + paramsObj.mergeObject(gmx::deserializeKeyValueTree(serializer)); } else { @@ -1700,7 +1684,8 @@ static void do_inputrec(gmx::ISerializer *serializer, { if (serializer->reading()) { - ir->internalParameters = std::make_unique(gmx::deserializeKeyValueTree(serializer)); + ir->internalParameters = + std::make_unique(gmx::deserializeKeyValueTree(serializer)); } else { @@ -1712,7 +1697,7 @@ static void do_inputrec(gmx::ISerializer *serializer, } -static void do_harm(gmx::ISerializer *serializer, t_iparams *iparams) +static void do_harm(gmx::ISerializer* serializer, t_iparams* iparams) { serializer->doReal(&iparams->harmonic.rA); serializer->doReal(&iparams->harmonic.krA); @@ -1720,13 +1705,10 @@ static void do_harm(gmx::ISerializer *serializer, t_iparams *iparams) serializer->doReal(&iparams->harmonic.krB); } -static void do_iparams(gmx::ISerializer *serializer, - t_functype ftype, - t_iparams *iparams, - int file_version) +static void do_iparams(gmx::ISerializer* serializer, t_functype ftype, t_iparams* iparams, int file_version) { - int idum; - real rdum; + int idum; + real rdum; switch (ftype) { @@ -1839,11 +1821,8 @@ static void do_iparams(gmx::ISerializer *serializer, serializer->doReal(&iparams->cubic.kb); serializer->doReal(&iparams->cubic.kcub); break; - case F_CONNBONDS: - break; - case F_POLARIZATION: - serializer->doReal(&iparams->polarize.alpha); - break; + case F_CONNBONDS: break; + case F_POLARIZATION: serializer->doReal(&iparams->polarize.alpha); break; case F_ANHARM_POL: serializer->doReal(&iparams->anharm_polarize.alpha); serializer->doReal(&iparams->anharm_polarize.drcut); @@ -1950,9 +1929,7 @@ static void do_iparams(gmx::ISerializer *serializer, serializer->doReal(&iparams->fbposres.r); serializer->doReal(&iparams->fbposres.k); break; - case F_CBTDIHS: - serializer->doRealArray(iparams->cbtdihs.cbtcA, NR_CBTDIHS); - break; + case F_CBTDIHS: serializer->doRealArray(iparams->cbtdihs.cbtcA, NR_CBTDIHS); break; case F_RBDIHS: serializer->doRealArray(iparams->rbdihs.rbcA, NR_RBDIHS); serializer->doRealArray(iparams->rbdihs.rbcB, NR_RBDIHS); @@ -1974,9 +1951,7 @@ static void do_iparams(gmx::ISerializer *serializer, serializer->doReal(&iparams->settle.dhh); break; case F_VSITE2: - case F_VSITE2FD: - serializer->doReal(&iparams->vsite.a); - break; + case F_VSITE2FD: serializer->doReal(&iparams->vsite.a); break; case F_VSITE3: case F_VSITE3FD: case F_VSITE3FAD: @@ -2022,12 +1997,12 @@ static void do_iparams(gmx::ISerializer *serializer, serializer->doInt(&iparams->cmap.cmapB); break; default: - gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", - ftype, interaction_function[ftype].name, __FILE__, __LINE__); + gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", ftype, + interaction_function[ftype].name, __FILE__, __LINE__); } } -static void do_ilist(gmx::ISerializer *serializer, InteractionList *ilist) +static void do_ilist(gmx::ISerializer* serializer, InteractionList* ilist) { int nr = ilist->size(); serializer->doInt(&nr); @@ -2038,9 +2013,7 @@ static void do_ilist(gmx::ISerializer *serializer, InteractionList *ilist) serializer->doIntArray(ilist->iatoms.data(), ilist->size()); } -static void do_ffparams(gmx::ISerializer *serializer, - gmx_ffparams_t *ffparams, - int file_version) +static void do_ffparams(gmx::ISerializer* serializer, gmx_ffparams_t* ffparams, int file_version) { serializer->doInt(&ffparams->atnr); int numTypes = ffparams->numTypes(); @@ -2076,44 +2049,41 @@ static void do_ffparams(gmx::ISerializer *serializer, for (int k = 0; k < NFTUPD; k++) { /* Compare the read file_version to the update table */ - if ((file_version < ftupd[k].fvnr) && - (ffparams->functype[i] >= ftupd[k].ftype)) + if ((file_version < ftupd[k].fvnr) && (ffparams->functype[i] >= ftupd[k].ftype)) { ffparams->functype[i] += 1; } } } - do_iparams(serializer, ffparams->functype[i], &ffparams->iparams[i], - file_version); + do_iparams(serializer, ffparams->functype[i], &ffparams->iparams[i], file_version); } } -static void add_settle_atoms(InteractionList *ilist) +static void add_settle_atoms(InteractionList* ilist) { int i; /* Settle used to only store the first atom: add the other two */ - ilist->iatoms.resize(2*ilist->size()); - for (i = ilist->size()/4 - 1; i >= 0; i--) + ilist->iatoms.resize(2 * ilist->size()); + for (i = ilist->size() / 4 - 1; i >= 0; i--) { - ilist->iatoms[4*i+0] = ilist->iatoms[2*i+0]; - ilist->iatoms[4*i+1] = ilist->iatoms[2*i+1]; - ilist->iatoms[4*i+2] = ilist->iatoms[2*i+1] + 1; - ilist->iatoms[4*i+3] = ilist->iatoms[2*i+1] + 2; + ilist->iatoms[4 * i + 0] = ilist->iatoms[2 * i + 0]; + ilist->iatoms[4 * i + 1] = ilist->iatoms[2 * i + 1]; + ilist->iatoms[4 * i + 2] = ilist->iatoms[2 * i + 1] + 1; + ilist->iatoms[4 * i + 3] = ilist->iatoms[2 * i + 1] + 2; } } -static void do_ilists(gmx::ISerializer *serializer, - InteractionLists *ilists, - int file_version) +static void do_ilists(gmx::ISerializer* serializer, InteractionLists* ilists, int file_version) { GMX_RELEASE_ASSERT(ilists, "Need a valid ilists object"); - GMX_RELEASE_ASSERT(ilists->size() == F_NRE, "The code needs to be in sync with InteractionLists"); + GMX_RELEASE_ASSERT(ilists->size() == F_NRE, + "The code needs to be in sync with InteractionLists"); for (int j = 0; j < F_NRE; j++) { - InteractionList &ilist = (*ilists)[j]; + InteractionList& ilist = (*ilists)[j]; gmx_bool bClear = FALSE; if (serializer->reading()) { @@ -2140,7 +2110,7 @@ static void do_ilists(gmx::ISerializer *serializer, } } -static void do_block(gmx::ISerializer *serializer, t_block *block) +static void do_block(gmx::ISerializer* serializer, t_block* block) { serializer->doInt(&block->nr); if (serializer->reading()) @@ -2149,24 +2119,24 @@ static void do_block(gmx::ISerializer *serializer, t_block *block) { sfree(block->index); } - block->nalloc_index = block->nr+1; + block->nalloc_index = block->nr + 1; snew(block->index, block->nalloc_index); } - serializer->doIntArray(block->index, block->nr+1); + serializer->doIntArray(block->index, block->nr + 1); } -static void do_blocka(gmx::ISerializer *serializer, t_blocka *block) +static void do_blocka(gmx::ISerializer* serializer, t_blocka* block) { serializer->doInt(&block->nr); serializer->doInt(&block->nra); if (serializer->reading()) { - block->nalloc_index = block->nr+1; + block->nalloc_index = block->nr + 1; snew(block->index, block->nalloc_index); block->nalloc_a = block->nra; snew(block->a, block->nalloc_a); } - serializer->doIntArray(block->index, block->nr+1); + serializer->doIntArray(block->index, block->nr + 1); serializer->doIntArray(block->a, block->nra); } @@ -2174,29 +2144,28 @@ static void do_blocka(gmx::ISerializer *serializer, t_blocka *block) * to element names when reading TPR files, without making the Gromacs library * directory a dependency on mdrun (which is the case if we need elements.dat). */ -static const char * -atomicnumber_to_element(int atomicnumber) +static const char* atomicnumber_to_element(int atomicnumber) { - const char * p; + const char* p; /* This does not have to be complete, so we only include elements likely * to occur in PDB files. */ switch (atomicnumber) { - case 1: p = "H"; break; - case 5: p = "B"; break; - case 6: p = "C"; break; - case 7: p = "N"; break; - case 8: p = "O"; break; - case 9: p = "F"; break; + case 1: p = "H"; break; + case 5: p = "B"; break; + case 6: p = "C"; break; + case 7: p = "N"; break; + case 8: p = "O"; break; + case 9: p = "F"; break; case 11: p = "Na"; break; case 12: p = "Mg"; break; - case 15: p = "P"; break; - case 16: p = "S"; break; + case 15: p = "P"; break; + case 16: p = "S"; break; case 17: p = "Cl"; break; case 18: p = "Ar"; break; - case 19: p = "K"; break; + case 19: p = "K"; break; case 20: p = "Ca"; break; case 25: p = "Mn"; break; case 26: p = "Fe"; break; @@ -2205,13 +2174,13 @@ atomicnumber_to_element(int atomicnumber) case 30: p = "Zn"; break; case 35: p = "Br"; break; case 47: p = "Ag"; break; - default: p = ""; break; + default: p = ""; break; } return p; } -static void do_atom(gmx::ISerializer *serializer, t_atom *atom) +static void do_atom(gmx::ISerializer* serializer, t_atom* atom) { serializer->doReal(&atom->m); serializer->doReal(&atom->q); @@ -2233,10 +2202,9 @@ static void do_atom(gmx::ISerializer *serializer, t_atom *atom) } } -static void do_grps(gmx::ISerializer *serializer, - gmx::ArrayRef grps) +static void do_grps(gmx::ISerializer* serializer, gmx::ArrayRef grps) { - for (auto &group : grps) + for (auto& group : grps) { int size = group.size(); serializer->doInt(&size); @@ -2248,7 +2216,7 @@ static void do_grps(gmx::ISerializer *serializer, } } -static void do_symstr(gmx::ISerializer *serializer, char ***nm, t_symtab *symtab) +static void do_symstr(gmx::ISerializer* serializer, char*** nm, t_symtab* symtab) { int ls; @@ -2264,12 +2232,9 @@ static void do_symstr(gmx::ISerializer *serializer, char ***nm, t_symtab *symtab } } -static void do_strstr(gmx::ISerializer *serializer, - int nstr, - char ***nm, - t_symtab *symtab) +static void do_strstr(gmx::ISerializer* serializer, int nstr, char*** nm, t_symtab* symtab) { - int j; + int j; for (j = 0; (j < nstr); j++) { @@ -2277,13 +2242,9 @@ static void do_strstr(gmx::ISerializer *serializer, } } -static void do_resinfo(gmx::ISerializer *serializer, - int n, - t_resinfo *ri, - t_symtab *symtab, - int file_version) +static void do_resinfo(gmx::ISerializer* serializer, int n, t_resinfo* ri, t_symtab* symtab, int file_version) { - int j; + int j; for (j = 0; (j < n); j++) { @@ -2301,10 +2262,7 @@ static void do_resinfo(gmx::ISerializer *serializer, } } -static void do_atoms(gmx::ISerializer *serializer, - t_atoms *atoms, - t_symtab *symtab, - int file_version) +static void do_atoms(gmx::ISerializer* serializer, t_atoms* atoms, t_symtab* symtab, int file_version) { int i; @@ -2331,7 +2289,9 @@ static void do_atoms(gmx::ISerializer *serializer, } else { - GMX_RELEASE_ASSERT(atoms->haveMass && atoms->haveCharge && atoms->haveType && atoms->haveBState, "Mass, charge, atomtype and B-state parameters should be present in t_atoms when writing a tpr file"); + GMX_RELEASE_ASSERT(atoms->haveMass && atoms->haveCharge && atoms->haveType && atoms->haveBState, + "Mass, charge, atomtype and B-state parameters should be present in " + "t_atoms when writing a tpr file"); } for (i = 0; (i < atoms->nr); i++) { @@ -2344,9 +2304,7 @@ static void do_atoms(gmx::ISerializer *serializer, do_resinfo(serializer, atoms->nres, atoms->resinfo, symtab, file_version); } -static void do_groups(gmx::ISerializer *serializer, - SimulationGroups *groups, - t_symtab *symtab) +static void do_groups(gmx::ISerializer* serializer, SimulationGroups* groups, t_symtab* symtab) { do_grps(serializer, groups->groups); int numberOfGroupNames = groups->groupNames.size(); @@ -2371,10 +2329,9 @@ static void do_groups(gmx::ISerializer *serializer, } } -static void do_atomtypes(gmx::ISerializer *serializer, t_atomtypes *atomtypes, - int file_version) +static void do_atomtypes(gmx::ISerializer* serializer, t_atomtypes* atomtypes, int file_version) { - int j; + int j; serializer->doInt(&atomtypes->nr); j = atomtypes->nr; @@ -2399,13 +2356,13 @@ static void do_atomtypes(gmx::ISerializer *serializer, t_atomtypes *atomtypes, } } -static void do_symtab(gmx::ISerializer *serializer, t_symtab *symtab) +static void do_symtab(gmx::ISerializer* serializer, t_symtab* symtab) { int i, nr; - t_symbuf *symbuf; + t_symbuf* symbuf; serializer->doInt(&symtab->nr); - nr = symtab->nr; + nr = symtab->nr; if (serializer->reading()) { snew(symtab->symbuf, 1); @@ -2429,7 +2386,7 @@ static void do_symtab(gmx::ISerializer *serializer, t_symtab *symtab) std::string buf = symbuf->buf[i]; serializer->doString(&buf); } - nr -= i; + nr -= i; symbuf = symbuf->next; } if (nr != 0) @@ -2439,7 +2396,7 @@ static void do_symtab(gmx::ISerializer *serializer, t_symtab *symtab) } } -static void do_cmap(gmx::ISerializer *serializer, gmx_cmap_t *cmap_grid) +static void do_cmap(gmx::ISerializer* serializer, gmx_cmap_t* cmap_grid) { int ngrid = cmap_grid->cmapdata.size(); @@ -2455,7 +2412,7 @@ static void do_cmap(gmx::ISerializer *serializer, gmx_cmap_t *cmap_grid) for (int i = 0; i < ngrid; i++) { - cmap_grid->cmapdata[i].cmap.resize(4*nelem); + cmap_grid->cmapdata[i].cmap.resize(4 * nelem); } } @@ -2463,19 +2420,16 @@ static void do_cmap(gmx::ISerializer *serializer, gmx_cmap_t *cmap_grid) { for (int j = 0; j < nelem; j++) { - serializer->doReal(&cmap_grid->cmapdata[i].cmap[j*4]); - serializer->doReal(&cmap_grid->cmapdata[i].cmap[j*4+1]); - serializer->doReal(&cmap_grid->cmapdata[i].cmap[j*4+2]); - serializer->doReal(&cmap_grid->cmapdata[i].cmap[j*4+3]); + serializer->doReal(&cmap_grid->cmapdata[i].cmap[j * 4]); + serializer->doReal(&cmap_grid->cmapdata[i].cmap[j * 4 + 1]); + serializer->doReal(&cmap_grid->cmapdata[i].cmap[j * 4 + 2]); + serializer->doReal(&cmap_grid->cmapdata[i].cmap[j * 4 + 3]); } } } -static void do_moltype(gmx::ISerializer *serializer, - gmx_moltype_t *molt, - t_symtab *symtab, - int file_version) +static void do_moltype(gmx::ISerializer* serializer, gmx_moltype_t* molt, t_symtab* symtab, int file_version) { do_symstr(serializer, &(molt->name), symtab); @@ -2499,9 +2453,7 @@ static void do_moltype(gmx::ISerializer *serializer, do_blocka(serializer, &molt->excls); } -static void do_molblock(gmx::ISerializer *serializer, - gmx_molblock_t *molb, - int numAtomsPerMolecule) +static void do_molblock(gmx::ISerializer* serializer, gmx_molblock_t* molb, int numAtomsPerMolecule) { serializer->doInt(&molb->type); serializer->doInt(&molb->nmol); @@ -2531,20 +2483,19 @@ static void do_molblock(gmx::ISerializer *serializer, } serializer->doRvecArray(as_rvec_array(molb->posres_xB.data()), numPosres_xB); } - } -static void set_disres_npair(gmx_mtop_t *mtop) +static void set_disres_npair(gmx_mtop_t* mtop) { - gmx_mtop_ilistloop_t iloop; - int nmol; + gmx_mtop_ilistloop_t iloop; + int nmol; gmx::ArrayRef ip = mtop->ffparams.iparams; - iloop = gmx_mtop_ilistloop_init(mtop); - while (const InteractionLists *ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) + iloop = gmx_mtop_ilistloop_init(mtop); + while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) { - const InteractionList &il = (*ilist)[F_DISRES]; + const InteractionList& il = (*ilist)[F_DISRES]; if (il.size() > 0) { @@ -2553,7 +2504,7 @@ static void set_disres_npair(gmx_mtop_t *mtop) for (int i = 0; i < il.size(); i += 3) { npair++; - if (i+3 == il.size() || ip[a[i]].disres.label != ip[a[i+3]].disres.label) + if (i + 3 == il.size() || ip[a[i]].disres.label != ip[a[i + 3]].disres.label) { ip[a[i]].disres.npair = npair; npair = 0; @@ -2563,9 +2514,7 @@ static void set_disres_npair(gmx_mtop_t *mtop) } } -static void do_mtop(gmx::ISerializer *serializer, - gmx_mtop_t *mtop, - int file_version) +static void do_mtop(gmx::ISerializer* serializer, gmx_mtop_t* mtop, int file_version) { do_symtab(serializer, &(mtop->symtab)); @@ -2579,7 +2528,7 @@ static void do_mtop(gmx::ISerializer *serializer, { mtop->moltype.resize(nmoltype); } - for (gmx_moltype_t &moltype : mtop->moltype) + for (gmx_moltype_t& moltype : mtop->moltype) { do_moltype(serializer, &moltype, &mtop->symtab, file_version); } @@ -2590,7 +2539,7 @@ static void do_mtop(gmx::ISerializer *serializer, { mtop->molblock.resize(nmolblock); } - for (gmx_molblock_t &molblock : mtop->molblock) + for (gmx_molblock_t& molblock : mtop->molblock) { int numAtomsPerMolecule = (serializer->reading() ? 0 : mtop->moltype[molblock.type].atoms.nr); do_molblock(serializer, &molblock, numAtomsPerMolecule); @@ -2614,7 +2563,7 @@ static void do_mtop(gmx::ISerializer *serializer, mtop->bIntermolecularInteractions = FALSE; } - do_atomtypes (serializer, &(mtop->atomtypes), file_version); + do_atomtypes(serializer, &(mtop->atomtypes), file_version); if (file_version >= 65) { @@ -2655,15 +2604,15 @@ static void do_mtop(gmx::ISerializer *serializer, * \param[in,out] fio File handle. * \param[in] TopOnlyOK If not reading \p ir is fine or not. */ -static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, - TpxFileHeader *tpx, - const char *filename, - t_fileio *fio, +static void do_tpxheader(gmx::FileIOXdrSerializer* serializer, + TpxFileHeader* tpx, + const char* filename, + t_fileio* fio, bool TopOnlyOK) { - int precision; - int idum = 0; - real rdum = 0; + int precision; + int idum = 0; + real rdum = 0; /* XDR binary topology file */ precision = sizeof(real); @@ -2674,10 +2623,12 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, serializer->doString(&buf); if (std::strncmp(buf.c_str(), "VERSION", 7) != 0) { - gmx_fatal(FARGS, "Can not read file %s,\n" - " this file is from a GROMACS version which is older than 2.0\n" - " Make a new one with grompp or use a gro or pdb file, if possible", - filename); + gmx_fatal( + FARGS, + "Can not read file %s,\n" + " this file is from a GROMACS version which is older than 2.0\n" + " Make a new one with grompp or use a gro or pdb file, if possible", + filename); } // We need to know the precision used to write the TPR file, to match it // to the precision of the currently running binary. If the precisions match @@ -2688,13 +2639,14 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, tpx->isDouble = (precision == sizeof(double)); if ((precision != sizeof(float)) && !tpx->isDouble) { - gmx_fatal(FARGS, "Unknown precision in file %s: real is %d bytes " + gmx_fatal(FARGS, + "Unknown precision in file %s: real is %d bytes " "instead of %zu or %zu", filename, precision, sizeof(float), sizeof(double)); } gmx_fio_setprecision(fio, tpx->isDouble); - fprintf(stderr, "Reading file %s, %s (%s precision)\n", - filename, buf.c_str(), tpx->isDouble ? "double" : "single"); + fprintf(stderr, "Reading file %s, %s (%s precision)\n", filename, buf.c_str(), + tpx->isDouble ? "double" : "single"); } else { @@ -2702,7 +2654,7 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, serializer->doString(&buf); gmx_fio_setprecision(fio, tpx->isDouble); serializer->doInt(&precision); - fileTag = gmx::formatString("%s", tpx_tag); + fileTag = gmx::formatString("%s", tpx_tag); } /* Check versions! */ @@ -2734,28 +2686,27 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, if (fileTag != tpx_tag) { - fprintf(stderr, "Note: file tpx tag '%s', software tpx tag '%s'\n", - fileTag.c_str(), tpx_tag); + fprintf(stderr, "Note: file tpx tag '%s', software tpx tag '%s'\n", fileTag.c_str(), tpx_tag); /* We only support reading tpx files with the same tag as the code * or tpx files with the release tag and with lower version number. */ if (fileTag != TPX_TAG_RELEASE && tpx->fileVersion < tpx_version) { - gmx_fatal(FARGS, "tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' with program for tpx version %d, tag '%s'", - filename, tpx->fileVersion, fileTag.c_str(), - tpx_version, tpx_tag); + gmx_fatal(FARGS, + "tpx tag/version mismatch: reading tpx file (%s) version %d, tag '%s' " + "with program for tpx version %d, tag '%s'", + filename, tpx->fileVersion, fileTag.c_str(), tpx_version, tpx_tag); } } } - if ((tpx->fileVersion <= tpx_incompatible_version) || - ((tpx->fileVersion > tpx_version) && !TopOnlyOK) || - (tpx->fileGeneration > tpx_generation) || - tpx_version == 80) /*80 was used by both 5.0-dev and 4.6-dev*/ + if ((tpx->fileVersion <= tpx_incompatible_version) + || ((tpx->fileVersion > tpx_version) && !TopOnlyOK) || (tpx->fileGeneration > tpx_generation) + || tpx_version == 80) /*80 was used by both 5.0-dev and 4.6-dev*/ { - gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", - filename, tpx->fileVersion, tpx_version); + gmx_fatal(FARGS, "reading tpx file (%s) version %d with version %d program", filename, + tpx->fileVersion, tpx_version); } serializer->doInt(&tpx->natoms); @@ -2782,7 +2733,8 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, { if (!serializer->reading()) { - GMX_RELEASE_ASSERT(tpx->sizeOfTprBody != 0, "Not possible to write new file with zero TPR body size"); + GMX_RELEASE_ASSERT(tpx->sizeOfTprBody != 0, + "Not possible to write new file with zero TPR body size"); } serializer->doInt64(&tpx->sizeOfTprBody); } @@ -2794,7 +2746,9 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, } } -#define do_test(serializer, b, p) if ((serializer)->reading() && ((p) != nullptr) && !(b)) gmx_fatal(FARGS, "No %s in input file",#p) +#define do_test(serializer, b, p) \ + if ((serializer)->reading() && ((p) != nullptr) && !(b)) \ + gmx_fatal(FARGS, "No %s in input file", #p) /*! \brief * Process the first part of the TPR into the state datastructure. @@ -2811,9 +2765,7 @@ static void do_tpxheader(gmx::FileIOXdrSerializer *serializer, * \param[in] tpx The file header data. * \param[in, out] state Global state data. */ -static void do_tpx_state_first(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - t_state *state) +static void do_tpx_state_first(gmx::ISerializer* serializer, TpxFileHeader* tpx, t_state* state) { if (serializer->reading()) { @@ -2843,7 +2795,7 @@ static void do_tpx_state_first(gmx::ISerializer *serializer, if (state->ngtc > 0) { - real *dumv; + real* dumv; snew(dumv, state->ngtc); if (tpx->fileVersion < 69) { @@ -2865,9 +2817,7 @@ static void do_tpx_state_first(gmx::ISerializer *serializer, * \param[in] tpx The file header data. * \param[in,out] mtop Global topology. */ -static void do_tpx_mtop(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - gmx_mtop_t *mtop) +static void do_tpx_mtop(gmx::ISerializer* serializer, TpxFileHeader* tpx, gmx_mtop_t* mtop) { do_test(serializer, tpx->bTop, mtop); if (tpx->bTop) @@ -2899,19 +2849,18 @@ static void do_tpx_mtop(gmx::ISerializer *serializer, * \param[in,out] x Individual coordinates for processing, deprecated. * \param[in,out] v Individual velocities for processing, deprecated. */ -static void do_tpx_state_second(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - t_state *state, - rvec *x, - rvec *v) +static void do_tpx_state_second(gmx::ISerializer* serializer, TpxFileHeader* tpx, t_state* state, rvec* x, rvec* v) { if (!serializer->reading()) { - GMX_RELEASE_ASSERT(x == nullptr && v == nullptr, "Passing separate x and v pointers to do_tpx() is not supported when writing"); + GMX_RELEASE_ASSERT( + x == nullptr && v == nullptr, + "Passing separate x and v pointers to do_tpx() is not supported when writing"); } else { - GMX_RELEASE_ASSERT(!(x == nullptr && v != nullptr), "Passing x==NULL and v!=NULL is not supported"); + GMX_RELEASE_ASSERT(!(x == nullptr && v != nullptr), + "Passing x==NULL and v!=NULL is not supported"); } if (serializer->reading()) @@ -2943,7 +2892,7 @@ static void do_tpx_state_second(gmx::ISerializer *serializer, { if (serializer->reading()) { - state->flags |= (1<flags |= (1 << estX); } serializer->doRvecArray(x, tpx->natoms); } @@ -2953,7 +2902,7 @@ static void do_tpx_state_second(gmx::ISerializer *serializer, { if (serializer->reading()) { - state->flags |= (1<flags |= (1 << estV); } if (!v) { @@ -2983,12 +2932,10 @@ static void do_tpx_state_second(gmx::ISerializer *serializer, * \param[in] tpx The file header data. * \param[in,out] ir Datastructure with simulation parameters. */ -static int do_tpx_ir(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - t_inputrec *ir) +static int do_tpx_ir(gmx::ISerializer* serializer, TpxFileHeader* tpx, t_inputrec* ir) { - int ePBC; - gmx_bool bPeriodicMols; + int ePBC; + gmx_bool bPeriodicMols; /* Starting with tpx version 26, we have the inputrec * at the end of the file, so we can ignore it @@ -3046,10 +2993,7 @@ static int do_tpx_ir(gmx::ISerializer *serializer, * \param[out] state State needing correction. * \param[out] mtop Topology to finalize. */ -static void do_tpx_finalize(TpxFileHeader *tpx, - t_inputrec *ir, - t_state *state, - gmx_mtop_t *mtop) +static void do_tpx_finalize(TpxFileHeader* tpx, t_inputrec* ir, t_state* state, gmx_mtop_t* mtop) { if (tpx->fileVersion < 51 && state) { @@ -3099,13 +3043,13 @@ static void do_tpx_finalize(TpxFileHeader *tpx, * \param[in,out] v Individual velocities for processing, deprecated. * \param[in,out] mtop Global topology. */ -static int do_tpx_body(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - t_inputrec *ir, - t_state *state, - rvec *x, - rvec *v, - gmx_mtop_t *mtop) +static int do_tpx_body(gmx::ISerializer* serializer, + TpxFileHeader* tpx, + t_inputrec* ir, + t_state* state, + rvec* x, + rvec* v, + gmx_mtop_t* mtop) { if (state) { @@ -3132,20 +3076,17 @@ static int do_tpx_body(gmx::ISerializer *serializer, * \param[in,out] ir Datastructures with simulation parameters. * \param[in,out] mtop Global topology. */ -static int do_tpx_body(gmx::ISerializer *serializer, - TpxFileHeader *tpx, - t_inputrec *ir, - gmx_mtop_t *mtop) +static int do_tpx_body(gmx::ISerializer* serializer, TpxFileHeader* tpx, t_inputrec* ir, gmx_mtop_t* mtop) { return do_tpx_body(serializer, tpx, ir, nullptr, nullptr, nullptr, mtop); } -static t_fileio *open_tpx(const char *fn, const char *mode) +static t_fileio* open_tpx(const char* fn, const char* mode) { return gmx_fio_open(fn, mode); } -static void close_tpx(t_fileio *fio) +static void close_tpx(t_fileio* fio) { gmx_fio_close(fio); } @@ -3161,17 +3102,15 @@ static void close_tpx(t_fileio *fio) * \param[in] mtop Global topology. * \returns Fully populated header. */ -static TpxFileHeader populateTpxHeader(const t_state &state, - const t_inputrec *ir, - const gmx_mtop_t *mtop) +static TpxFileHeader populateTpxHeader(const t_state& state, const t_inputrec* ir, const gmx_mtop_t* mtop) { TpxFileHeader header; header.natoms = state.natoms; header.ngtc = state.ngtc; header.fep_state = state.fep_state; header.lambda = state.lambda[efptFEP]; - header.bIr = ir != nullptr; - header.bTop = mtop != nullptr; + header.bIr = ir != nullptr; + header.bTop = mtop != nullptr; header.bX = (state.flags & (1 << estX)) != 0; header.bV = (state.flags & (1 << estV)) != 0; header.bF = false; @@ -3196,7 +3135,7 @@ static TpxFileHeader populateTpxHeader(const t_state &state, * the information in \p buffer. * \param[in,out] buffer Information from TPR file as char buffer. */ -static void doTpxBodyBuffer(gmx::ISerializer *serializer, gmx::ArrayRef buffer) +static void doTpxBodyBuffer(gmx::ISerializer* serializer, gmx::ArrayRef buffer) { serializer->doCharArray(buffer.data(), buffer.size()); } @@ -3227,12 +3166,13 @@ static void doTpxBodyBuffer(gmx::ISerializer *serializer, gmx::ArrayRef bu * * \returns Partial de-serialized TPR used for communication to nodes. */ -static PartialDeserializedTprFile readTpxBody(TpxFileHeader *tpx, - gmx::ISerializer *serializer, - t_inputrec *ir, - t_state *state, - rvec *x, rvec *v, - gmx_mtop_t *mtop) +static PartialDeserializedTprFile readTpxBody(TpxFileHeader* tpx, + gmx::ISerializer* serializer, + t_inputrec* ir, + t_state* state, + rvec* x, + rvec* v, + gmx_mtop_t* mtop) { PartialDeserializedTprFile partialDeserializedTpr; if (tpx->fileVersion >= tpxv_AddSizeField && tpx->fileGeneration >= 27) @@ -3242,22 +3182,11 @@ static PartialDeserializedTprFile readTpxBody(TpxFileHeader *tpx, doTpxBodyBuffer(serializer, partialDeserializedTpr.body); partialDeserializedTpr.ePBC = - completeTprDeserialization(&partialDeserializedTpr, - ir, - state, - x, v, - mtop); + completeTprDeserialization(&partialDeserializedTpr, ir, state, x, v, mtop); } else { - partialDeserializedTpr.ePBC = - do_tpx_body(serializer, - tpx, - ir, - state, - x, - v, - mtop); + partialDeserializedTpr.ePBC = do_tpx_body(serializer, tpx, ir, state, x, v, mtop); } // Update header to system info for communication to nodes. // As we only need to communicate the inputrec and mtop to other nodes, @@ -3265,10 +3194,7 @@ static PartialDeserializedTprFile readTpxBody(TpxFileHeader *tpx, // in on master. partialDeserializedTpr.header = populateTpxHeader(*state, ir, mtop); gmx::InMemorySerializer tprBodySerializer; - do_tpx_body(&tprBodySerializer, - &partialDeserializedTpr.header, - ir, - mtop); + do_tpx_body(&tprBodySerializer, &partialDeserializedTpr.header, ir, mtop); partialDeserializedTpr.body = tprBodySerializer.finishAndGetBuffer(); return partialDeserializedTpr; @@ -3280,21 +3206,20 @@ static PartialDeserializedTprFile readTpxBody(TpxFileHeader *tpx, * ************************************************************/ -TpxFileHeader readTpxHeader(const char *fileName, bool canReadTopologyOnly) +TpxFileHeader readTpxHeader(const char* fileName, bool canReadTopologyOnly) { - t_fileio *fio; + t_fileio* fio; fio = open_tpx(fileName, "r"); gmx::FileIOXdrSerializer serializer(fio); - TpxFileHeader tpx; + TpxFileHeader tpx; do_tpxheader(&serializer, &tpx, fileName, fio, canReadTopologyOnly); close_tpx(fio); return tpx; } -void write_tpx_state(const char *fn, - const t_inputrec *ir, const t_state *state, const gmx_mtop_t *mtop) +void write_tpx_state(const char* fn, const t_inputrec* ir, const t_state* state, const gmx_mtop_t* mtop) { /* To write a state, we first need to write the state information to a buffer before * we append the raw bytes to the file. For this, the header information needs to be @@ -3302,103 +3227,69 @@ void write_tpx_state(const char *fn, * otherwise not available. */ - t_fileio *fio; + t_fileio* fio; - TpxFileHeader tpx = populateTpxHeader(*state, - ir, - mtop); + TpxFileHeader tpx = populateTpxHeader(*state, ir, mtop); gmx::InMemorySerializer tprBodySerializer; - do_tpx_body(&tprBodySerializer, - &tpx, - const_cast(ir), - const_cast(state), nullptr, nullptr, - const_cast(mtop)); + do_tpx_body(&tprBodySerializer, &tpx, const_cast(ir), const_cast(state), + nullptr, nullptr, const_cast(mtop)); std::vector tprBody = tprBodySerializer.finishAndGetBuffer(); - tpx.sizeOfTprBody = tprBody.size(); + tpx.sizeOfTprBody = tprBody.size(); fio = open_tpx(fn, "w"); gmx::FileIOXdrSerializer serializer(fio); - do_tpxheader(&serializer, - &tpx, - fn, - fio, - ir == nullptr); + do_tpxheader(&serializer, &tpx, fn, fio, ir == nullptr); doTpxBodyBuffer(&serializer, tprBody); close_tpx(fio); } -int completeTprDeserialization(PartialDeserializedTprFile *partialDeserializedTpr, - t_inputrec *ir, - t_state *state, - rvec *x, - rvec *v, - gmx_mtop_t *mtop) +int completeTprDeserialization(PartialDeserializedTprFile* partialDeserializedTpr, + t_inputrec* ir, + t_state* state, + rvec* x, + rvec* v, + gmx_mtop_t* mtop) { gmx::InMemoryDeserializer tprBodyDeserializer(partialDeserializedTpr->body, partialDeserializedTpr->header.isDouble); - return do_tpx_body(&tprBodyDeserializer, - &partialDeserializedTpr->header, - ir, - state, - x, - v, - mtop); + return do_tpx_body(&tprBodyDeserializer, &partialDeserializedTpr->header, ir, state, x, v, mtop); } -int completeTprDeserialization(PartialDeserializedTprFile *partialDeserializedTpr, - t_inputrec *ir, - gmx_mtop_t *mtop) +int completeTprDeserialization(PartialDeserializedTprFile* partialDeserializedTpr, + t_inputrec* ir, + gmx_mtop_t* mtop) { return completeTprDeserialization(partialDeserializedTpr, ir, nullptr, nullptr, nullptr, mtop); } -PartialDeserializedTprFile read_tpx_state(const char *fn, - t_inputrec *ir, - t_state *state, - gmx_mtop_t *mtop) +PartialDeserializedTprFile read_tpx_state(const char* fn, t_inputrec* ir, t_state* state, gmx_mtop_t* mtop) { - t_fileio *fio; + t_fileio* fio; fio = open_tpx(fn, "r"); - gmx::FileIOXdrSerializer serializer(fio); - PartialDeserializedTprFile partialDeserializedTpr; - do_tpxheader(&serializer, - &partialDeserializedTpr.header, - fn, - fio, - ir == nullptr); - partialDeserializedTpr = readTpxBody(&partialDeserializedTpr.header, - &serializer, - ir, - state, - nullptr, - nullptr, - mtop); + gmx::FileIOXdrSerializer serializer(fio); + PartialDeserializedTprFile partialDeserializedTpr; + do_tpxheader(&serializer, &partialDeserializedTpr.header, fn, fio, ir == nullptr); + partialDeserializedTpr = + readTpxBody(&partialDeserializedTpr.header, &serializer, ir, state, nullptr, nullptr, mtop); close_tpx(fio); return partialDeserializedTpr; } -int read_tpx(const char *fn, - t_inputrec *ir, matrix box, int *natoms, - rvec *x, rvec *v, gmx_mtop_t *mtop) +int read_tpx(const char* fn, t_inputrec* ir, matrix box, int* natoms, rvec* x, rvec* v, gmx_mtop_t* mtop) { - t_fileio *fio; - t_state state; + t_fileio* fio; + t_state state; - TpxFileHeader tpx; - fio = open_tpx(fn, "r"); + TpxFileHeader tpx; + fio = open_tpx(fn, "r"); gmx::FileIOXdrSerializer serializer(fio); - do_tpxheader(&serializer, - &tpx, - fn, - fio, - ir == nullptr); - PartialDeserializedTprFile partialDeserializedTpr - = readTpxBody(&tpx, &serializer, - ir, &state, x, v, mtop); + do_tpxheader(&serializer, &tpx, fn, fio, ir == nullptr); + PartialDeserializedTprFile partialDeserializedTpr = + readTpxBody(&tpx, &serializer, ir, &state, x, v, mtop); close_tpx(fio); if (mtop != nullptr && natoms != nullptr) { @@ -3411,12 +3302,10 @@ int read_tpx(const char *fn, return partialDeserializedTpr.ePBC; } -int read_tpx_top(const char *fn, - t_inputrec *ir, matrix box, int *natoms, - rvec *x, rvec *v, t_topology *top) +int read_tpx_top(const char* fn, t_inputrec* ir, matrix box, int* natoms, rvec* x, rvec* v, t_topology* top) { - gmx_mtop_t mtop; - int ePBC; + gmx_mtop_t mtop; + int ePBC; ePBC = read_tpx(fn, ir, box, natoms, x, v, &mtop); @@ -3425,12 +3314,12 @@ int read_tpx_top(const char *fn, return ePBC; } -gmx_bool fn2bTPX(const char *file) +gmx_bool fn2bTPX(const char* file) { return (efTPR == fn2ftp(file)); } -void pr_tpxheader(FILE *fp, int indent, const char *title, const TpxFileHeader *sh) +void pr_tpxheader(FILE* fp, int indent, const char* title, const TpxFileHeader* sh) { if (available(fp, sh, indent, title)) { diff --git a/src/gromacs/fileio/tpxio.h b/src/gromacs/fileio/tpxio.h index 8d4b008fb0..2346f0e00c 100644 --- a/src/gromacs/fileio/tpxio.h +++ b/src/gromacs/fileio/tpxio.h @@ -61,25 +61,25 @@ struct t_topology; struct TpxFileHeader { //! Non zero if input_rec is present. - bool bIr = false; + bool bIr = false; //! Non zero if a box is present. - bool bBox = false; + bool bBox = false; //! Non zero if a topology is present. - bool bTop = false; + bool bTop = false; //! Non zero if coordinates are present. - bool bX = false; + bool bX = false; //! Non zero if velocities are present. - bool bV = false; + bool bV = false; //! Non zero if forces are present (no longer supported, but retained so old .tpr can be read) - bool bF = false; + bool bF = false; //! The total number of atoms. - int natoms = 0; + int natoms = 0; //! The number of temperature coupling groups. - int ngtc = 0; + int ngtc = 0; //! Current value of lambda. - real lambda = 0; + real lambda = 0; //! Current value of the alchemical state - not yet printed out. - int fep_state = 0; + int fep_state = 0; /*a better decision will eventually (5.0 or later) need to be made on how to treat the alchemical state of the system, which can now vary through a simulation, and cannot be completely described @@ -88,11 +88,11 @@ struct TpxFileHeader //! Size of the TPR body in chars (equal to number of bytes) during I/O. int64_t sizeOfTprBody = 0; //! File version. - int fileVersion = 0; + int fileVersion = 0; //! File generation. - int fileGeneration = 0; + int fileGeneration = 0; //! If the tpr file was written in double precision. - bool isDouble = false; + bool isDouble = false; }; /*! \brief @@ -105,11 +105,11 @@ struct TpxFileHeader struct PartialDeserializedTprFile { //! The file header. - TpxFileHeader header; + TpxFileHeader header; //! The file body. std::vector body; //! Flag for PBC needed by legacy implementation. - int ePBC = -1; + int ePBC = -1; }; /* @@ -133,10 +133,9 @@ struct PartialDeserializedTprFile * \param[in] canReadTopologyOnly If reading the inputrec can be skipped or not. * \returns An initialized and populated TPX File header object. */ -TpxFileHeader readTpxHeader(const char *fileName, bool canReadTopologyOnly); +TpxFileHeader readTpxHeader(const char* fileName, bool canReadTopologyOnly); -void write_tpx_state(const char *fn, - const t_inputrec *ir, const t_state *state, const gmx_mtop_t *mtop); +void write_tpx_state(const char* fn, const t_inputrec* ir, const t_state* state, const gmx_mtop_t* mtop); /* Write a file, and close it again. */ @@ -154,17 +153,17 @@ void write_tpx_state(const char *fn, * * \returns PBC flag. */ -int completeTprDeserialization(PartialDeserializedTprFile *partialDeserializedTpr, - t_inputrec *ir, - t_state *state, - rvec *x, - rvec *v, - gmx_mtop_t *mtop); +int completeTprDeserialization(PartialDeserializedTprFile* partialDeserializedTpr, + t_inputrec* ir, + t_state* state, + rvec* x, + rvec* v, + gmx_mtop_t* mtop); //! Overload for final TPR deserialization when not using state vectors. -int completeTprDeserialization(PartialDeserializedTprFile *partialDeserializedTpr, - t_inputrec *ir, - gmx_mtop_t *mtop); +int completeTprDeserialization(PartialDeserializedTprFile* partialDeserializedTpr, + t_inputrec* ir, + gmx_mtop_t* mtop); /*! \brief * Read a file to set up a simulation and close it after reading. @@ -181,10 +180,7 @@ int completeTprDeserialization(PartialDeserializedTprFile *partialDeserializedTp * \param[out] mtop Global simulation topolgy. * \returns Struct with header and body in char vector. */ -PartialDeserializedTprFile read_tpx_state(const char *fn, - t_inputrec *ir, - t_state *state, - gmx_mtop_t *mtop); +PartialDeserializedTprFile read_tpx_state(const char* fn, t_inputrec* ir, t_state* state, gmx_mtop_t* mtop); /*! \brief * Read a file and close it again. @@ -208,18 +204,14 @@ PartialDeserializedTprFile read_tpx_state(const char *fn, * \param[out] mtop Topology to be populated, or nullptr. * \returns ir->ePBC if it was read from the file. */ -int read_tpx(const char *fn, - t_inputrec *ir, matrix box, int *natoms, - rvec *x, rvec *v, gmx_mtop_t *mtop); +int read_tpx(const char* fn, t_inputrec* ir, matrix box, int* natoms, rvec* x, rvec* v, gmx_mtop_t* mtop); -int read_tpx_top(const char *fn, - t_inputrec *ir, matrix box, int *natoms, - rvec *x, rvec *v, t_topology *top); +int read_tpx_top(const char* fn, t_inputrec* ir, matrix box, int* natoms, rvec* x, rvec* v, t_topology* top); /* As read_tpx, but for the old t_topology struct */ -gmx_bool fn2bTPX(const char *file); +gmx_bool fn2bTPX(const char* file); /* return if *file is one of the TPX file types */ -void pr_tpxheader(FILE *fp, int indent, const char *title, const TpxFileHeader *sh); +void pr_tpxheader(FILE* fp, int indent, const char* title, const TpxFileHeader* sh); #endif diff --git a/src/gromacs/fileio/trrio.cpp b/src/gromacs/fileio/trrio.cpp index b69811cb86..fbad07788a 100644 --- a/src/gromacs/fileio/trrio.cpp +++ b/src/gromacs/fileio/trrio.cpp @@ -47,27 +47,27 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -#define BUFSIZE 128 +#define BUFSIZE 128 -static int nFloatSize(gmx_trr_header_t *sh) +static int nFloatSize(gmx_trr_header_t* sh) { int nflsize = 0; if (sh->box_size) { - nflsize = sh->box_size/(DIM*DIM); + nflsize = sh->box_size / (DIM * DIM); } else if (sh->x_size) { - nflsize = sh->x_size/(sh->natoms*DIM); + nflsize = sh->x_size / (sh->natoms * DIM); } else if (sh->v_size) { - nflsize = sh->v_size/(sh->natoms*DIM); + nflsize = sh->v_size / (sh->natoms * DIM); } else if (sh->f_size) { - nflsize = sh->f_size/(sh->natoms*DIM); + nflsize = sh->f_size / (sh->natoms * DIM); } else { @@ -90,8 +90,7 @@ static int nFloatSize(gmx_trr_header_t *sh) That does not exclude the possibility of a reading error between frames, but the trajectory-handling infrastructure needs an overhaul before we can handle that. */ -static gmx_bool -do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *bOK) +static gmx_bool do_trr_frame_header(t_fileio* fio, bool bRead, gmx_trr_header_t* sh, gmx_bool* bOK) { const int magicValue = 1993; int magic = magicValue; @@ -111,7 +110,9 @@ do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *b if (magic != magicValue) { *bOK = FALSE; - gmx_fatal(FARGS, "Failed to find GROMACS magic number in trr frame header, so this is not a trr file!\n"); + gmx_fatal(FARGS, + "Failed to find GROMACS magic number in trr frame header, so this is not a trr " + "file!\n"); } if (bRead) @@ -156,18 +157,16 @@ do_trr_frame_header(t_fileio *fio, bool bRead, gmx_trr_header_t *sh, gmx_bool *b * the fact that we used a default int for the step number, which * is typically defined to be signed and 32 bit. */ int intStep = sh->step; - *bOK = *bOK && gmx_fio_do_int(fio, intStep); - sh->step = intStep; - *bOK = *bOK && gmx_fio_do_int(fio, sh->nre); - *bOK = *bOK && gmx_fio_do_real(fio, sh->t); - *bOK = *bOK && gmx_fio_do_real(fio, sh->lambda); + *bOK = *bOK && gmx_fio_do_int(fio, intStep); + sh->step = intStep; + *bOK = *bOK && gmx_fio_do_int(fio, sh->nre); + *bOK = *bOK && gmx_fio_do_real(fio, sh->t); + *bOK = *bOK && gmx_fio_do_real(fio, sh->lambda); return *bOK; } -static gmx_bool -do_trr_frame_data(t_fileio *fio, gmx_trr_header_t *sh, - rvec *box, rvec *x, rvec *v, rvec *f) +static gmx_bool do_trr_frame_data(t_fileio* fio, gmx_trr_header_t* sh, rvec* box, rvec* x, rvec* v, rvec* f) { matrix pv; gmx_bool bOK; @@ -185,15 +184,15 @@ do_trr_frame_data(t_fileio *fio, gmx_trr_header_t *sh, { bOK = bOK && gmx_fio_ndo_rvec(fio, pv, DIM); } - if (sh->x_size != 0) + if (sh->x_size != 0) { bOK = bOK && gmx_fio_ndo_rvec(fio, x, sh->natoms); } - if (sh->v_size != 0) + if (sh->v_size != 0) { bOK = bOK && gmx_fio_ndo_rvec(fio, v, sh->natoms); } - if (sh->f_size != 0) + if (sh->f_size != 0) { bOK = bOK && gmx_fio_ndo_rvec(fio, f, sh->natoms); } @@ -201,20 +200,27 @@ do_trr_frame_data(t_fileio *fio, gmx_trr_header_t *sh, return bOK; } -static gmx_bool -do_trr_frame(t_fileio *fio, bool bRead, int64_t *step, real *t, real *lambda, - rvec *box, int *natoms, rvec *x, rvec *v, rvec *f) +static gmx_bool do_trr_frame(t_fileio* fio, + bool bRead, + int64_t* step, + real* t, + real* lambda, + rvec* box, + int* natoms, + rvec* x, + rvec* v, + rvec* f) { - gmx_trr_header_t *sh; + gmx_trr_header_t* sh; gmx_bool bOK; snew(sh, 1); if (!bRead) { sh->box_size = (box) ? sizeof(matrix) : 0; - sh->x_size = ((x) ? (*natoms*sizeof(x[0])) : 0); - sh->v_size = ((v) ? (*natoms*sizeof(v[0])) : 0); - sh->f_size = ((f) ? (*natoms*sizeof(f[0])) : 0); + sh->x_size = ((x) ? (*natoms * sizeof(x[0])) : 0); + sh->v_size = ((v) ? (*natoms * sizeof(v[0])) : 0); + sh->f_size = ((f) ? (*natoms * sizeof(f[0])) : 0); sh->natoms = *natoms; sh->step = *step; sh->nre = 0; @@ -261,9 +267,9 @@ do_trr_frame(t_fileio *fio, bool bRead, int64_t *step, real *t, real *lambda, * ************************************************************/ -void gmx_trr_read_single_header(const char *fn, gmx_trr_header_t *header) +void gmx_trr_read_single_header(const char* fn, gmx_trr_header_t* header) { - t_fileio *fio = gmx_trr_open(fn, "r"); + t_fileio* fio = gmx_trr_open(fn, "r"); gmx_bool bOK; if (!do_trr_frame_header(fio, true, header, &bOK)) { @@ -272,55 +278,84 @@ void gmx_trr_read_single_header(const char *fn, gmx_trr_header_t *header) gmx_trr_close(fio); } -gmx_bool gmx_trr_read_frame_header(t_fileio *fio, gmx_trr_header_t *header, gmx_bool *bOK) +gmx_bool gmx_trr_read_frame_header(t_fileio* fio, gmx_trr_header_t* header, gmx_bool* bOK) { return do_trr_frame_header(fio, true, header, bOK); } -void gmx_trr_write_single_frame(const char *fn, int64_t step, real t, real lambda, - const rvec *box, int natoms, const rvec *x, const rvec *v, const rvec *f) +void gmx_trr_write_single_frame(const char* fn, + int64_t step, + real t, + real lambda, + const rvec* box, + int natoms, + const rvec* x, + const rvec* v, + const rvec* f) { - t_fileio *fio = gmx_trr_open(fn, "w"); - do_trr_frame(fio, false, &step, &t, &lambda, const_cast(box), &natoms, const_cast(x), const_cast(v), const_cast(f)); + t_fileio* fio = gmx_trr_open(fn, "w"); + do_trr_frame(fio, false, &step, &t, &lambda, const_cast(box), &natoms, + const_cast(x), const_cast(v), const_cast(f)); gmx_trr_close(fio); } -void gmx_trr_read_single_frame(const char *fn, int64_t *step, real *t, real *lambda, - rvec *box, int *natoms, rvec *x, rvec *v, rvec *f) +void gmx_trr_read_single_frame(const char* fn, + int64_t* step, + real* t, + real* lambda, + rvec* box, + int* natoms, + rvec* x, + rvec* v, + rvec* f) { - t_fileio *fio = gmx_trr_open(fn, "r"); + t_fileio* fio = gmx_trr_open(fn, "r"); do_trr_frame(fio, true, step, t, lambda, box, natoms, x, v, f); gmx_trr_close(fio); } -void gmx_trr_write_frame(t_fileio *fio, int64_t step, real t, real lambda, - const rvec *box, int natoms, const rvec *x, const rvec *v, const rvec *f) +void gmx_trr_write_frame(t_fileio* fio, + int64_t step, + real t, + real lambda, + const rvec* box, + int natoms, + const rvec* x, + const rvec* v, + const rvec* f) { - if (!do_trr_frame(fio, false, &step, &t, &lambda, const_cast(box), &natoms, const_cast(x), const_cast(v), const_cast(f))) + if (!do_trr_frame(fio, false, &step, &t, &lambda, const_cast(box), &natoms, + const_cast(x), const_cast(v), const_cast(f))) { gmx_file("Cannot write trajectory frame; maybe you are out of disk space?"); } } -gmx_bool gmx_trr_read_frame(t_fileio *fio, int64_t *step, real *t, real *lambda, - rvec *box, int *natoms, rvec *x, rvec *v, rvec *f) +gmx_bool gmx_trr_read_frame(t_fileio* fio, + int64_t* step, + real* t, + real* lambda, + rvec* box, + int* natoms, + rvec* x, + rvec* v, + rvec* f) { return do_trr_frame(fio, true, step, t, lambda, box, natoms, x, v, f); } -gmx_bool gmx_trr_read_frame_data(t_fileio *fio, gmx_trr_header_t *header, - rvec *box, rvec *x, rvec *v, rvec *f) +gmx_bool gmx_trr_read_frame_data(t_fileio* fio, gmx_trr_header_t* header, rvec* box, rvec* x, rvec* v, rvec* f) { return do_trr_frame_data(fio, header, box, x, v, f); } -t_fileio *gmx_trr_open(const char *fn, const char *mode) +t_fileio* gmx_trr_open(const char* fn, const char* mode) { return gmx_fio_open(fn, mode); } -void gmx_trr_close(t_fileio *fio) +void gmx_trr_close(t_fileio* fio) { gmx_fio_close(fio); } diff --git a/src/gromacs/fileio/trrio.h b/src/gromacs/fileio/trrio.h index cb3e021ed8..945489eb5d 100644 --- a/src/gromacs/fileio/trrio.h +++ b/src/gromacs/fileio/trrio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,66 +73,93 @@ struct t_fileio; /* sizes of the structs in a trr file, sizes are given in bytes. */ typedef struct gmx_trr_header_t { - gmx_bool bDouble; /* Double precision? */ - int ir_size; /* Backward compatibility */ - int e_size; /* Backward compatibility */ - int box_size; /* Non zero if a box is present */ - int vir_size; /* Backward compatibility */ - int pres_size; /* Backward compatibility */ - int top_size; /* Backward compatibility */ - int sym_size; /* Backward compatibility */ - int x_size; /* Non zero if coordinates are present */ - int v_size; /* Non zero if velocities are present */ - int f_size; /* Non zero if forces are present */ - - int natoms; /* The total number of atoms */ - int64_t step; /* Current step number */ - int nre; /* Backward compatibility */ - real t; /* Current time */ - real lambda; /* Current value of lambda */ - int fep_state; /* Current value of alchemical state */ + gmx_bool bDouble; /* Double precision? */ + int ir_size; /* Backward compatibility */ + int e_size; /* Backward compatibility */ + int box_size; /* Non zero if a box is present */ + int vir_size; /* Backward compatibility */ + int pres_size; /* Backward compatibility */ + int top_size; /* Backward compatibility */ + int sym_size; /* Backward compatibility */ + int x_size; /* Non zero if coordinates are present */ + int v_size; /* Non zero if velocities are present */ + int f_size; /* Non zero if forces are present */ + + int natoms; /* The total number of atoms */ + int64_t step; /* Current step number */ + int nre; /* Backward compatibility */ + real t; /* Current time */ + real lambda; /* Current value of lambda */ + int fep_state; /* Current value of alchemical state */ } gmx_trr_header_t; -struct t_fileio *gmx_trr_open(const char *fn, const char *mode); +struct t_fileio* gmx_trr_open(const char* fn, const char* mode); /* Open a trr file */ -void gmx_trr_close(struct t_fileio *fio); +void gmx_trr_close(struct t_fileio* fio); /* Close it */ -gmx_bool gmx_trr_read_frame_header(struct t_fileio *fio, gmx_trr_header_t *header, gmx_bool *bOK); +gmx_bool gmx_trr_read_frame_header(struct t_fileio* fio, gmx_trr_header_t* header, gmx_bool* bOK); /* Read the header of a trr file. Return FALSE if there is no frame. * bOK will be FALSE when the header is incomplete. */ -gmx_bool gmx_trr_read_frame_data(struct t_fileio *fio, gmx_trr_header_t *sh, - rvec *box, rvec *x, rvec *v, rvec *f); +gmx_bool gmx_trr_read_frame_data(struct t_fileio* fio, gmx_trr_header_t* sh, rvec* box, rvec* x, rvec* v, rvec* f); /* Extern read a frame except the header (that should be pre-read, * using routine gmx_trr_read_frame_header(), see above) from a trr file. * Return FALSE on error */ -gmx_bool gmx_trr_read_frame(struct t_fileio *fio, int64_t *step, real *t, real *lambda, - rvec *box, int *natoms, rvec *x, rvec *v, rvec *f); +gmx_bool gmx_trr_read_frame(struct t_fileio* fio, + int64_t* step, + real* t, + real* lambda, + rvec* box, + int* natoms, + rvec* x, + rvec* v, + rvec* f); /* Read a trr frame, including the header from fp. box, x, v, f may * be NULL, in which case the data will be skipped over. * return FALSE on error */ -void gmx_trr_write_frame(struct t_fileio *fio, int64_t step, real t, real lambda, - const rvec *box, int natoms, const rvec *x, const rvec *v, const rvec *f); +void gmx_trr_write_frame(struct t_fileio* fio, + int64_t step, + real t, + real lambda, + const rvec* box, + int natoms, + const rvec* x, + const rvec* v, + const rvec* f); /* Write a trr frame to file fp, box, x, v, f may be NULL */ -void gmx_trr_read_single_header(const char *fn, gmx_trr_header_t *header); +void gmx_trr_read_single_header(const char* fn, gmx_trr_header_t* header); /* Read the header of a trr file from fn, and close the file afterwards. */ -void gmx_trr_read_single_frame(const char *fn, int64_t *step, real *t, real *lambda, - rvec *box, int *natoms, rvec *x, rvec *v, rvec *f); +void gmx_trr_read_single_frame(const char* fn, + int64_t* step, + real* t, + real* lambda, + rvec* box, + int* natoms, + rvec* x, + rvec* v, + rvec* f); /* Read a single trr frame from file fn, which is closed afterwards */ -void gmx_trr_write_single_frame(const char *fn, int64_t step, real t, real lambda, - const rvec *box, int natoms, const rvec *x, const rvec *v, const rvec *f); +void gmx_trr_write_single_frame(const char* fn, + int64_t step, + real t, + real lambda, + const rvec* box, + int natoms, + const rvec* x, + const rvec* v, + const rvec* f); /* Write a single trr frame to file fn, which is closed afterwards */ diff --git a/src/gromacs/fileio/trxio.cpp b/src/gromacs/fileio/trxio.cpp index 846bb2a0a1..34ee2995c9 100644 --- a/src/gromacs/fileio/trxio.cpp +++ b/src/gromacs/fileio/trxio.cpp @@ -71,30 +71,30 @@ #include "gromacs/utility/smalloc.h" #if GMX_USE_PLUGINS -#include "gromacs/fileio/vmdio.h" +# include "gromacs/fileio/vmdio.h" #endif /* defines for frame counter output */ -#define SKIP1 10 -#define SKIP2 100 +#define SKIP1 10 +#define SKIP2 100 #define SKIP3 1000 struct t_trxstatus { - int flags; /* flags for read_first/next_frame */ - int __frame; - real t0; /* time of the first frame, needed * - * for skipping frames with -dt */ - real tf; /* internal frame time */ - t_trxframe *xframe; - t_fileio *fio; - gmx_tng_trajectory_t tng; - int natoms; - double DT, BOX[3]; - gmx_bool bReadBox; - char *persistent_line; /* Persistent line for reading g96 trajectories */ + int flags; /* flags for read_first/next_frame */ + int __frame; + real t0; /* time of the first frame, needed * + * for skipping frames with -dt */ + real tf; /* internal frame time */ + t_trxframe* xframe; + t_fileio* fio; + gmx_tng_trajectory_t tng; + int natoms; + double DT, BOX[3]; + gmx_bool bReadBox; + char* persistent_line; /* Persistent line for reading g96 trajectories */ #if GMX_USE_PLUGINS - gmx_vmdplugin_t *vmdplugin; + gmx_vmdplugin_t* vmdplugin; #endif }; @@ -105,18 +105,17 @@ gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble) int iq; double tol; - tol = 2*(bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS); + tol = 2 * (bDouble ? GMX_DOUBLE_EPS : GMX_FLOAT_EPS); - iq = static_cast((a - b + tol*a)/c); + iq = static_cast((a - b + tol * a) / c); - return fabs(a - b - c*iq) <= tol*fabs(a); + return fabs(a - b - c * iq) <= tol * fabs(a); } - int check_times2(real t, real t0, gmx_bool bDouble) { - int r; + int r; #if !GMX_DOUBLE /* since t is float, we can not use double precision for bRmod */ @@ -124,8 +123,7 @@ int check_times2(real t, real t0, gmx_bool bDouble) #endif r = -1; - if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) && - (!bTimeSet(TEND) || (t <= rTimeValue(TEND)))) + if ((!bTimeSet(TBEGIN) || (t >= rTimeValue(TBEGIN))) && (!bTimeSet(TEND) || (t <= rTimeValue(TEND)))) { if (bTimeSet(TDELTA) && !bRmod_fd(t, t0, rTimeValue(TDELTA), bDouble)) { @@ -142,8 +140,8 @@ int check_times2(real t, real t0, gmx_bool bDouble) } if (debug) { - fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n", - t, t0, rTimeValue(TBEGIN), rTimeValue(TEND), rTimeValue(TDELTA), r); + fprintf(debug, "t=%g, t0=%g, b=%g, e=%g, dt=%g: r=%d\n", t, t0, rTimeValue(TBEGIN), + rTimeValue(TEND), rTimeValue(TDELTA), r); } return r; } @@ -153,12 +151,12 @@ int check_times(real t) return check_times2(t, t, FALSE); } -static void initcount(t_trxstatus *status) +static void initcount(t_trxstatus* status) { status->__frame = -1; } -static void status_init(t_trxstatus *status) +static void status_init(t_trxstatus* status) { status->flags = 0; status->xframe = nullptr; @@ -171,50 +169,45 @@ static void status_init(t_trxstatus *status) } -int nframes_read(t_trxstatus *status) +int nframes_read(t_trxstatus* status) { return status->__frame; } -static void printcount_(t_trxstatus *status, const gmx_output_env_t *oenv, - const char *l, real t) +static void printcount_(t_trxstatus* status, const gmx_output_env_t* oenv, const char* l, real t) { - if ((status->__frame < 2*SKIP1 || status->__frame % SKIP1 == 0) && - (status->__frame < 2*SKIP2 || status->__frame % SKIP2 == 0) && - (status->__frame < 2*SKIP3 || status->__frame % SKIP3 == 0) && - output_env_get_trajectory_io_verbosity(oenv) != 0) + if ((status->__frame < 2 * SKIP1 || status->__frame % SKIP1 == 0) + && (status->__frame < 2 * SKIP2 || status->__frame % SKIP2 == 0) + && (status->__frame < 2 * SKIP3 || status->__frame % SKIP3 == 0) + && output_env_get_trajectory_io_verbosity(oenv) != 0) { - fprintf(stderr, "\r%-14s %6d time %8.3f ", l, status->__frame, - output_env_conv_time(oenv, t)); + fprintf(stderr, "\r%-14s %6d time %8.3f ", l, status->__frame, output_env_conv_time(oenv, t)); fflush(stderr); } } -static void printcount(t_trxstatus *status, const gmx_output_env_t *oenv, real t, - gmx_bool bSkip) +static void printcount(t_trxstatus* status, const gmx_output_env_t* oenv, real t, gmx_bool bSkip) { status->__frame++; printcount_(status, oenv, bSkip ? "Skipping frame" : "Reading frame", t); } -static void printlast(t_trxstatus *status, const gmx_output_env_t *oenv, real t) +static void printlast(t_trxstatus* status, const gmx_output_env_t* oenv, real t) { printcount_(status, oenv, "Last frame", t); fprintf(stderr, "\n"); fflush(stderr); } -static void printincomp(t_trxstatus *status, t_trxframe *fr) +static void printincomp(t_trxstatus* status, t_trxframe* fr) { if (fr->not_ok & HEADER_NOT_OK) { - fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n", - status->__frame+1, fr->time); + fprintf(stderr, "WARNING: Incomplete header: nr %d time %g\n", status->__frame + 1, fr->time); } else if (fr->not_ok) { - fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n", - status->__frame+1, fr->time); + fprintf(stderr, "WARNING: Incomplete frame: nr %d time %g\n", status->__frame + 1, fr->time); } fflush(stderr); } @@ -226,7 +219,7 @@ int prec2ndec(real prec) gmx_fatal(FARGS, "DEATH HORROR prec (%g) <= 0 in prec2ndec", prec); } - return gmx::roundToInt(log(prec)/log(10.0)); + return gmx::roundToInt(log(prec) / log(10.0)); } real ndec2prec(int ndec) @@ -234,27 +227,25 @@ real ndec2prec(int ndec) return pow(10.0, ndec); } -t_fileio *trx_get_fileio(t_trxstatus *status) +t_fileio* trx_get_fileio(t_trxstatus* status) { return status->fio; } -float trx_get_time_of_final_frame(t_trxstatus *status) +float trx_get_time_of_final_frame(t_trxstatus* status) { - t_fileio *stfio = trx_get_fileio(status); + t_fileio* stfio = trx_get_fileio(status); int filetype = gmx_fio_getftp(stfio); gmx_bool bOK; float lasttime = -1; if (filetype == efXTC) { - lasttime = - xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio), - gmx_fio_getxdr(stfio), - status->natoms, &bOK); + lasttime = xdr_xtc_get_last_frame_time(gmx_fio_getfp(stfio), gmx_fio_getxdr(stfio), + status->natoms, &bOK); if (!bOK) { - gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported." ); + gmx_fatal(FARGS, "Error reading last frame. Maybe seek not supported."); } } else if (filetype == efTNG) @@ -273,7 +264,7 @@ float trx_get_time_of_final_frame(t_trxstatus *status) return lasttime; } -void clear_trxframe(t_trxframe *fr, gmx_bool bFirst) +void clear_trxframe(t_trxframe* fr, gmx_bool bFirst) { fr->not_ok = 0; fr->bStep = FALSE; @@ -300,19 +291,18 @@ void clear_trxframe(t_trxframe *fr, gmx_bool bFirst) fr->v = nullptr; fr->f = nullptr; clear_mat(fr->box); - fr->bPBC = FALSE; - fr->ePBC = -1; + fr->bPBC = FALSE; + fr->ePBC = -1; } } -void set_trxframe_ePBC(t_trxframe *fr, int ePBC) +void set_trxframe_ePBC(t_trxframe* fr, int ePBC) { fr->bPBC = (ePBC == -1); fr->ePBC = ePBC; } -int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, - const int *ind, gmx_conect gc) +int write_trxframe_indexed(t_trxstatus* status, const t_trxframe* fr, int nind, const int* ind, gmx_conect gc) { char title[STRLEN]; rvec *xout = nullptr, *vout = nullptr, *fout = nullptr; @@ -344,13 +334,11 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, switch (ftp) { case efTRR: - case efTNG: - break; + case efTNG: break; default: if (!fr->bX) { - gmx_fatal(FARGS, "Need coordinates to write a %s trajectory", - ftp2ext(ftp)); + gmx_fatal(FARGS, "Need coordinates to write a %s trajectory", ftp2ext(ftp)); } break; } @@ -394,21 +382,16 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, } } break; - default: - break; + default: break; } switch (ftp) { - case efTNG: - gmx_write_tng_from_trxframe(status->tng, fr, nind); - break; - case efXTC: - write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec); - break; + case efTNG: gmx_write_tng_from_trxframe(status->tng, fr, nind); break; + case efXTC: write_xtc(status->fio, nind, fr->step, fr->time, fr->box, xout, prec); break; case efTRR: - gmx_trr_write_frame(status->fio, nframes_read(status), - fr->time, fr->step, fr->box, nind, xout, vout, fout); + gmx_trr_write_frame(status->fio, nframes_read(status), fr->time, fr->step, fr->box, + nind, xout, vout, fout); break; case efGRO: case efPDB: @@ -416,8 +399,7 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, case efENT: if (!fr->bAtoms) { - gmx_fatal(FARGS, "Can not write a %s file without atom names", - ftp2ext(ftp)); + gmx_fatal(FARGS, "Can not write a %s file without atom names", ftp2ext(ftp)); } sprintf(title, "frame t= %.3f", fr->time); if (ftp == efGRO) @@ -427,17 +409,15 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, } else { - write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms, - fr->x, -1, fr->box, ' ', fr->step, nind, ind, gc, FALSE); + write_pdbfile_indexed(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, -1, + fr->box, ' ', fr->step, nind, ind, gc, FALSE); } break; case efG96: sprintf(title, "frame t= %.3f", fr->time); write_g96_conf(gmx_fio_getfp(status->fio), title, fr, nind, ind); break; - default: - gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s", - ftp2ext(ftp)); + default: gmx_fatal(FARGS, "Sorry, write_trxframe_indexed can not write %s", ftp2ext(ftp)); } switch (ftp) @@ -454,43 +434,33 @@ int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, } sfree(xout); break; - case efXTC: - sfree(xout); - break; - default: - break; + case efXTC: sfree(xout); break; + default: break; } return 0; } -t_trxstatus * -trjtools_gmx_prepare_tng_writing(const char *filename, - char filemode, - t_trxstatus *in, - const char *infile, - const int natoms, - const gmx_mtop_t *mtop, - gmx::ArrayRef index, - const char *index_group_name) +t_trxstatus* trjtools_gmx_prepare_tng_writing(const char* filename, + char filemode, + t_trxstatus* in, + const char* infile, + const int natoms, + const gmx_mtop_t* mtop, + gmx::ArrayRef index, + const char* index_group_name) { if (filemode != 'w' && filemode != 'a') { gmx_incons("Sorry, can only prepare for TNG output."); } - t_trxstatus *out; + t_trxstatus* out; snew(out, 1); status_init(out); if (in != nullptr) { - gmx_prepare_tng_writing(filename, - filemode, - &in->tng, - &out->tng, - natoms, - mtop, - index, + gmx_prepare_tng_writing(filename, filemode, &in->tng, &out->tng, natoms, mtop, index, index_group_name); } else if ((infile) && (efTNG == fn2ftp(infile))) @@ -498,38 +468,25 @@ trjtools_gmx_prepare_tng_writing(const char *filename, gmx_tng_trajectory_t tng_in; gmx_tng_open(infile, 'r', &tng_in); - gmx_prepare_tng_writing(filename, - filemode, - &tng_in, - &out->tng, - natoms, - mtop, - index, + gmx_prepare_tng_writing(filename, filemode, &tng_in, &out->tng, natoms, mtop, index, index_group_name); } else { // we start from a file that is not a tng file or have been unable to load the // input file, so we need to populate the fields independently of it - gmx_prepare_tng_writing(filename, - filemode, - nullptr, - &out->tng, - natoms, - mtop, - index, + gmx_prepare_tng_writing(filename, filemode, nullptr, &out->tng, natoms, mtop, index, index_group_name); } return out; } -void write_tng_frame(t_trxstatus *status, - t_trxframe *frame) +void write_tng_frame(t_trxstatus* status, t_trxframe* frame) { gmx_write_tng_from_trxframe(status->tng, frame, -1); } -int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) +int write_trxframe(t_trxstatus* status, t_trxframe* fr, gmx_conect gc) { char title[STRLEN]; title[0] = '\0'; @@ -554,8 +511,7 @@ int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) switch (gmx_fio_getftp(status->fio)) { - case efTRR: - break; + case efTRR: break; default: if (!fr->bX) { @@ -572,7 +528,8 @@ int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) break; case efTRR: gmx_trr_write_frame(status->fio, fr->step, fr->time, fr->lambda, fr->box, fr->natoms, - fr->bX ? fr->x : nullptr, fr->bV ? fr->v : nullptr, fr->bF ? fr->f : nullptr); + fr->bX ? fr->x : nullptr, fr->bV ? fr->v : nullptr, + fr->bF ? fr->f : nullptr); break; case efGRO: case efPDB: @@ -586,19 +543,16 @@ int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) sprintf(title, "frame t= %.3f", fr->time); if (gmx_fio_getftp(status->fio) == efGRO) { - write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms, - fr->x, fr->bV ? fr->v : nullptr, fr->box); + write_hconf_p(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, + fr->bV ? fr->v : nullptr, fr->box); } else { - write_pdbfile(gmx_fio_getfp(status->fio), title, - fr->atoms, fr->x, fr->bPBC ? fr->ePBC : -1, fr->box, - ' ', fr->step, gc); + write_pdbfile(gmx_fio_getfp(status->fio), title, fr->atoms, fr->x, + fr->bPBC ? fr->ePBC : -1, fr->box, ' ', fr->step, gc); } break; - case efG96: - write_g96_conf(gmx_fio_getfp(status->fio), title, fr, -1, nullptr); - break; + case efG96: write_g96_conf(gmx_fio_getfp(status->fio), title, fr, -1, nullptr); break; default: gmx_fatal(FARGS, "Sorry, write_trxframe can not write %s", ftp2ext(gmx_fio_getftp(status->fio))); @@ -607,9 +561,16 @@ int write_trxframe(t_trxstatus *status, t_trxframe *fr, gmx_conect gc) return 0; } -int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atoms, - int step, real time, matrix box, rvec x[], rvec *v, - gmx_conect gc) +int write_trx(t_trxstatus* status, + int nind, + const int* ind, + const t_atoms* atoms, + int step, + real time, + matrix box, + rvec x[], + rvec* v, + gmx_conect gc) { t_trxframe fr; @@ -619,7 +580,7 @@ int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atom fr.bTime = TRUE; fr.time = time; fr.bAtoms = atoms != nullptr; - fr.atoms = const_cast(atoms); + fr.atoms = const_cast(atoms); fr.bX = TRUE; fr.x = x; fr.bV = v != nullptr; @@ -630,7 +591,7 @@ int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atom return write_trxframe_indexed(status, &fr, nind, ind, gc); } -void close_trx(t_trxstatus *status) +void close_trx(t_trxstatus* status) { if (status == nullptr) { @@ -652,9 +613,9 @@ void close_trx(t_trxstatus *status) sfree(status); } -t_trxstatus *open_trx(const char *outfile, const char *filemode) +t_trxstatus* open_trx(const char* outfile, const char* filemode) { - t_trxstatus *stat; + t_trxstatus* stat; if (filemode[0] != 'w' && filemode[0] != 'a' && filemode[1] != '+') { gmx_fatal(FARGS, "Sorry, write_trx can only write"); @@ -667,7 +628,7 @@ t_trxstatus *open_trx(const char *outfile, const char *filemode) return stat; } -static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr) +static gmx_bool gmx_next_frame(t_trxstatus* status, t_trxframe* fr) { gmx_trr_header_t sh; gmx_bool bOK, bRet; @@ -727,17 +688,17 @@ static gmx_bool gmx_next_frame(t_trxstatus *status, t_trxframe *fr) return bRet; } -static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) +static gmx_bool pdb_next_x(t_trxstatus* status, FILE* fp, t_trxframe* fr) { t_atoms atoms; - t_symtab *symtab; + t_symtab* symtab; matrix boxpdb; // Initiate model_nr to -1 rather than NOTSET. // It is not worthwhile introducing extra variables in the // read_pdbfile call to verify that a model_nr was read. - int ePBC, model_nr = -1, na; - char title[STRLEN], *time, *step; - double dbl; + int ePBC, model_nr = -1, na; + char title[STRLEN], *time, *step; + double dbl; atoms.nr = fr->natoms; atoms.atom = nullptr; @@ -745,7 +706,7 @@ static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) /* the other pointers in atoms should not be accessed if these are NULL */ snew(symtab, 1); open_symtab(symtab); - na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, nullptr); + na = read_pdbfile(fp, title, &model_nr, &atoms, symtab, fr->x, &ePBC, boxpdb, TRUE, nullptr); free_symtab(symtab); sfree(symtab); set_trxframe_ePBC(fr, ePBC); @@ -764,11 +725,11 @@ static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) fr->step = 0; step = std::strstr(title, " step= "); - fr->bStep = ((step != nullptr) && sscanf(step+7, "%" SCNd64, &fr->step) == 1); + fr->bStep = ((step != nullptr) && sscanf(step + 7, "%" SCNd64, &fr->step) == 1); dbl = 0.0; time = std::strstr(title, " t= "); - fr->bTime = ((time != nullptr) && sscanf(time+4, "%lf", &dbl) == 1); + fr->bTime = ((time != nullptr) && sscanf(time + 4, "%lf", &dbl) == 1); fr->time = dbl; if (na == 0) @@ -786,7 +747,7 @@ static gmx_bool pdb_next_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) } } -static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) +static int pdb_first_x(t_trxstatus* status, FILE* fp, t_trxframe* fr) { initcount(status); @@ -804,7 +765,7 @@ static int pdb_first_x(t_trxstatus *status, FILE *fp, t_trxframe *fr) return fr->natoms; } -bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxframe *fr) +bool read_next_frame(const gmx_output_env_t* oenv, t_trxstatus* status, t_trxframe* fr) { real pt; int ct; @@ -812,7 +773,7 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra bool bRet = false; int ftp; - pt = status->tf; + pt = status->tf; do { @@ -829,17 +790,15 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra } switch (ftp) { - case efTRR: - bRet = gmx_next_frame(status, fr); - break; + case efTRR: bRet = gmx_next_frame(status, fr); break; case efCPT: /* Checkpoint files can not contain mulitple frames */ break; case efG96: { - t_symtab *symtab = nullptr; - read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr, - symtab, status->persistent_line); + t_symtab* symtab = nullptr; + read_g96_conf(gmx_fio_getfp(status->fio), nullptr, nullptr, fr, symtab, + status->persistent_line); bRet = (fr->natoms > 0); break; } @@ -848,13 +807,16 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra { if (xtc_seek_time(status->fio, rTimeValue(TBEGIN), fr->natoms, TRUE)) { - gmx_fatal(FARGS, "Specified frame (time %f) doesn't exist or file corrupt/inconsistent.", + gmx_fatal(FARGS, + "Specified frame (time %f) doesn't exist or file " + "corrupt/inconsistent.", rTimeValue(TBEGIN)); } initcount(status); } - bRet = (read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box, - fr->x, &fr->prec, &bOK) != 0); + bRet = (read_next_xtc(status->fio, fr->natoms, &fr->step, &fr->time, fr->box, fr->x, + &fr->prec, &bOK) + != 0); fr->bPrec = (bRet && fr->prec > 0); fr->bStep = bRet; fr->bTime = bRet; @@ -867,32 +829,25 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra fr->not_ok = DATA_NOT_OK; } break; - case efTNG: - bRet = gmx_read_next_tng_frame(status->tng, fr, nullptr, 0); - break; - case efPDB: - bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr); - break; - case efGRO: - bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr); - break; + case efTNG: bRet = gmx_read_next_tng_frame(status->tng, fr, nullptr, 0); break; + case efPDB: bRet = pdb_next_x(status, gmx_fio_getfp(status->fio), fr); break; + case efGRO: bRet = gro_next_x_or_v(gmx_fio_getfp(status->fio), fr); break; default: #if GMX_USE_PLUGINS bRet = read_next_vmd_frame(status->vmdplugin, fr); #else gmx_fatal(FARGS, "DEATH HORROR in read_next_frame ftp=%s,status=%s", - ftp2ext(gmx_fio_getftp(status->fio)), - gmx_fio_getname(status->fio)); + ftp2ext(gmx_fio_getftp(status->fio)), gmx_fio_getname(status->fio)); #endif } status->tf = fr->time; if (bRet) { - bMissingData = ((((status->flags & TRX_NEED_X) != 0) && !fr->bX) || - (((status->flags & TRX_NEED_V) != 0) && !fr->bV) || - (((status->flags & TRX_NEED_F) != 0) && !fr->bF)); - bSkip = FALSE; + bMissingData = ((((status->flags & TRX_NEED_X) != 0) && !fr->bX) + || (((status->flags & TRX_NEED_V) != 0) && !fr->bV) + || (((status->flags & TRX_NEED_F) != 0) && !fr->bF)); + bSkip = FALSE; if (!bMissingData) { ct = check_times2(fr->time, status->t0, fr->bDouble); @@ -912,8 +867,7 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra } } - } - while (bRet && (bMissingData || bSkip)); + } while (bRet && (bMissingData || bSkip)); if (!bRet) { @@ -927,12 +881,11 @@ bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, t_trxfra return bRet; } -bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, - const char *fn, t_trxframe *fr, int flags) +bool read_first_frame(const gmx_output_env_t* oenv, t_trxstatus** status, const char* fn, t_trxframe* fr, int flags) { - t_fileio *fio = nullptr; - gmx_bool bFirst, bOK; - int ftp = fn2ftp(fn); + t_fileio* fio = nullptr; + gmx_bool bFirst, bOK; + int ftp = fn2ftp(fn); clear_trxframe(fr, TRUE); @@ -940,7 +893,7 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, snew((*status), 1); - status_init( *status ); + status_init(*status); initcount(*status); (*status)->flags = flags; @@ -955,8 +908,7 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, } switch (ftp) { - case efTRR: - break; + case efTRR: break; case efCPT: read_checkpoint_trxframe(fio, fr); bFirst = FALSE; @@ -967,9 +919,9 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, if (!(*status)->persistent_line) { /* allocate the persistent line */ - snew((*status)->persistent_line, STRLEN+1); + snew((*status)->persistent_line, STRLEN + 1); } - t_symtab *symtab = nullptr; + t_symtab* symtab = nullptr; read_g96_conf(gmx_fio_getfp(fio), fn, nullptr, fr, symtab, (*status)->persistent_line); gmx_fio_close(fio); clear_trxframe(fr, FALSE); @@ -985,10 +937,11 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, break; } case efXTC: - if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x, - &fr->prec, &bOK) == 0) + if (read_first_xtc(fio, &fr->natoms, &fr->step, &fr->time, fr->box, &fr->x, &fr->prec, &bOK) == 0) { - GMX_RELEASE_ASSERT(!bOK, "Inconsistent results - OK status from read_first_xtc, but 0 atom coords read"); + GMX_RELEASE_ASSERT(!bOK, + "Inconsistent results - OK status from read_first_xtc, but 0 " + "atom coords read"); fr->not_ok = DATA_NOT_OK; } if (fr->not_ok) @@ -1038,19 +991,28 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, break; default: #if GMX_USE_PLUGINS - fprintf(stderr, "The file format of %s is not a known trajectory format to GROMACS.\n" + fprintf(stderr, + "The file format of %s is not a known trajectory format to GROMACS.\n" "Please make sure that the file is a trajectory!\n" - "GROMACS will now assume it to be a trajectory and will try to open it using the VMD plug-ins.\n" - "This will only work in case the VMD plugins are found and it is a trajectory format supported by VMD.\n", fn); + "GROMACS will now assume it to be a trajectory and will try to open it using " + "the VMD plug-ins.\n" + "This will only work in case the VMD plugins are found and it is a trajectory " + "format supported by VMD.\n", + fn); gmx_fio_fp_close(fio); /*only close the file without removing FIO entry*/ if (!read_first_vmd_frame(fn, &(*status)->vmdplugin, fr)) { gmx_fatal(FARGS, "Not supported in read_first_frame: %s", fn); } #else - gmx_fatal(FARGS, "Not supported in read_first_frame: %s. Please make sure that the file is a trajectory.\n" - "GROMACS is not compiled with plug-in support. Thus it cannot read non-GROMACS trajectory formats using the VMD plug-ins.\n" - "Please compile with plug-in support if you want to read non-GROMACS trajectory formats.\n", fn); + gmx_fatal(FARGS, + "Not supported in read_first_frame: %s. Please make sure that the file is a " + "trajectory.\n" + "GROMACS is not compiled with plug-in support. Thus it cannot read " + "non-GROMACS trajectory formats using the VMD plug-ins.\n" + "Please compile with plug-in support if you want to read non-GROMACS " + "trajectory formats.\n", + fn); #endif } (*status)->tf = fr->time; @@ -1062,8 +1024,7 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, return FALSE; } - if (bFirst || - (!(flags & TRX_DONT_SKIP) && check_times(fr->time) < 0)) + if (bFirst || (!(flags & TRX_DONT_SKIP) && check_times(fr->time) < 0)) { /* Read a frame when no frame was read or the first was skipped */ if (!read_next_frame(oenv, *status, fr)) @@ -1083,8 +1044,7 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, /***** C O O R D I N A T E S T U F F *****/ -int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, const char *fn, - real *t, rvec **x, matrix box) +int read_first_x(const gmx_output_env_t* oenv, t_trxstatus** status, const char* fn, real* t, rvec** x, matrix box) { t_trxframe fr; @@ -1099,8 +1059,7 @@ int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, const char return (*status)->xframe->natoms; } -gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t, - rvec x[], matrix box) +gmx_bool read_next_x(const gmx_output_env_t* oenv, t_trxstatus* status, real* t, rvec x[], matrix box) { gmx_bool bRet; @@ -1113,7 +1072,7 @@ gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t, return bRet; } -void rewind_trj(t_trxstatus *status) +void rewind_trj(t_trxstatus* status) { initcount(status); @@ -1122,10 +1081,10 @@ void rewind_trj(t_trxstatus *status) /***** T O P O L O G Y S T U F F ******/ -t_topology *read_top(const char *fn, int *ePBC) +t_topology* read_top(const char* fn, int* ePBC) { int epbc, natoms; - t_topology *top; + t_topology* top; snew(top, 1); epbc = read_tpx_top(fn, nullptr, nullptr, &natoms, nullptr, nullptr, top); diff --git a/src/gromacs/fileio/trxio.h b/src/gromacs/fileio/trxio.h index ff65d3e310..bc0ee04886 100644 --- a/src/gromacs/fileio/trxio.h +++ b/src/gromacs/fileio/trxio.h @@ -64,23 +64,22 @@ int prec2ndec(real prec); * 1/(nm) */ real ndec2prec(int ndec); -void clear_trxframe(struct t_trxframe *fr, gmx_bool bFirst); +void clear_trxframe(struct t_trxframe* fr, gmx_bool bFirst); /* Set all content gmx_booleans to FALSE. * When bFirst = TRUE, set natoms=-1, all pointers to NULL * and all data to zero. */ -void set_trxframe_ePBC(struct t_trxframe *fr, int ePBC); +void set_trxframe_ePBC(struct t_trxframe* fr, int ePBC); /* Set the type of periodic boundary conditions, ePBC=-1 is not set */ -int nframes_read(t_trxstatus *status); +int nframes_read(t_trxstatus* status); /* Returns the number of frames read from the trajectory */ -int write_trxframe_indexed(t_trxstatus *status, const t_trxframe *fr, int nind, - const int *ind, gmx_conect gc); +int write_trxframe_indexed(t_trxstatus* status, const t_trxframe* fr, int nind, const int* ind, gmx_conect gc); /* Write an indexed frame to a TRX file, see write_trxframe. gc may be NULL */ -int write_trxframe(t_trxstatus *status, struct t_trxframe *fr, gmx_conect gc); +int write_trxframe(t_trxstatus* status, struct t_trxframe* fr, gmx_conect gc); /* Write a frame to a TRX file. * Only entries for which the gmx_boolean is TRUE will be written, * except for step, time, lambda and/or box, which may not be @@ -90,9 +89,16 @@ int write_trxframe(t_trxstatus *status, struct t_trxframe *fr, gmx_conect gc); * gc is important for pdb file writing only and may be NULL. */ -int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atoms, - int step, real time, matrix box, rvec x[], rvec *v, - gmx_conect gc); +int write_trx(t_trxstatus* status, + int nind, + const int* ind, + const t_atoms* atoms, + int step, + real time, + matrix box, + rvec x[], + rvec* v, + gmx_conect gc); /* Write an indexed frame to a TRX file. * v can be NULL. * atoms can be NULL for file types which don't need atom names. @@ -122,15 +128,14 @@ int write_trx(t_trxstatus *status, int nind, const int *ind, const t_atoms *atom * \param[in] index_group_name Name of the group of atom indices. * \returns Pointer to output TNG file. */ -t_trxstatus * -trjtools_gmx_prepare_tng_writing(const char *filename, - char filemode, - t_trxstatus *in, - const char *infile, - int natoms, - const struct gmx_mtop_t *mtop, - gmx::ArrayRef index, - const char *index_group_name); +t_trxstatus* trjtools_gmx_prepare_tng_writing(const char* filename, + char filemode, + t_trxstatus* in, + const char* infile, + int natoms, + const struct gmx_mtop_t* mtop, + gmx::ArrayRef index, + const char* index_group_name); /*! \brief Write a trxframe to the TNG file in status. * @@ -138,22 +143,21 @@ trjtools_gmx_prepare_tng_writing(const char *filename, * gmx_tng_trajectory_t are encapsulated, so client trajectory-writing * code with a t_trxstatus can't just call the TNG writing * function. */ -void write_tng_frame(t_trxstatus *status, - struct t_trxframe *fr); +void write_tng_frame(t_trxstatus* status, struct t_trxframe* fr); -void close_trx(t_trxstatus *status); +void close_trx(t_trxstatus* status); /* Close trajectory file as opened with read_first_x, read_first_frame * or open_trx. * Also frees memory in the structure. */ -t_trxstatus *open_trx(const char *outfile, const char *filemode); +t_trxstatus* open_trx(const char* outfile, const char* filemode); /* Open a TRX file and return an allocated status pointer */ -struct t_fileio *trx_get_fileio(t_trxstatus *status); +struct t_fileio* trx_get_fileio(t_trxstatus* status); /* get a fileio from a trxstatus */ -float trx_get_time_of_final_frame(t_trxstatus *status); +float trx_get_time_of_final_frame(t_trxstatus* status); /* get time of final frame. Only supported for TNG and XTC */ gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble); @@ -162,9 +166,9 @@ gmx_bool bRmod_fd(double a, double b, double c, gmx_bool bDouble); */ #if GMX_DOUBLE -#define bRmod(a, b, c) bRmod_fd(a, b, c, TRUE) +# define bRmod(a, b, c) bRmod_fd(a, b, c, TRUE) #else -#define bRmod(a, b, c) bRmod_fd(a, b, c, FALSE) +# define bRmod(a, b, c) bRmod_fd(a, b, c, FALSE) #endif int check_times2(real t, real t0, gmx_bool bDouble); @@ -186,30 +190,30 @@ int check_times(real t); */ - - - /* For trxframe.flags, used in trxframe read routines. * When a READ flag is set, the field will be read when present, * but a frame might be returned which does not contain the field. * When a NEED flag is set, frames not containing the field will be skipped. */ -#define TRX_READ_X (1u<<0u) -#define TRX_NEED_X (1u<<1u) -#define TRX_READ_V (1u<<2u) -#define TRX_NEED_V (1u<<3u) -#define TRX_READ_F (1u<<4u) -#define TRX_NEED_F (1u<<5u) +#define TRX_READ_X (1u << 0u) +#define TRX_NEED_X (1u << 1u) +#define TRX_READ_V (1u << 2u) +#define TRX_NEED_V (1u << 3u) +#define TRX_READ_F (1u << 4u) +#define TRX_NEED_F (1u << 5u) /* Useful for reading natoms from a trajectory without skipping */ -#define TRX_DONT_SKIP (1u<<6u) +#define TRX_DONT_SKIP (1u << 6u) /* For trxframe.not_ok */ -#define HEADER_NOT_OK (1u<<0u) -#define DATA_NOT_OK (1u<<1u) -#define FRAME_NOT_OK (HEADER_NOT_OK | DATA_NOT_OK) - -bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, - const char *fn, struct t_trxframe *fr, int flags); +#define HEADER_NOT_OK (1u << 0u) +#define DATA_NOT_OK (1u << 1u) +#define FRAME_NOT_OK (HEADER_NOT_OK | DATA_NOT_OK) + +bool read_first_frame(const gmx_output_env_t* oenv, + t_trxstatus** status, + const char* fn, + struct t_trxframe* fr, + int flags); /* Read the first frame which is in accordance with flags, which are * defined further up in this file. * Memory will be allocated for flagged entries. @@ -217,30 +221,28 @@ bool read_first_frame(const gmx_output_env_t *oenv, t_trxstatus **status, * Returns true when succeeded, false otherwise. */ -bool read_next_frame(const gmx_output_env_t *oenv, t_trxstatus *status, - struct t_trxframe *fr); +bool read_next_frame(const gmx_output_env_t* oenv, t_trxstatus* status, struct t_trxframe* fr); /* Reads the next frame which is in accordance with fr->flags. * Returns true when succeeded, false otherwise. */ -int read_first_x(const gmx_output_env_t *oenv, t_trxstatus **status, - const char *fn, real *t, rvec **x, matrix box); +int read_first_x(const gmx_output_env_t* oenv, t_trxstatus** status, const char* fn, real* t, rvec** x, matrix box); /* These routines read first coordinates and box, and allocates * memory for the coordinates, for a trajectory file. * The routine returns the number of atoms, or 0 when something is wrong. * The integer in status should be passed to calls of read_next_x */ -gmx_bool read_next_x(const gmx_output_env_t *oenv, t_trxstatus *status, real *t, rvec x[], matrix box); +gmx_bool read_next_x(const gmx_output_env_t* oenv, t_trxstatus* status, real* t, rvec x[], matrix box); /* Read coordinates and box from a trajectory file. Return TRUE when all well, * or FALSE when end of file (or last frame requested by user). * status is the integer set in read_first_x. */ -void rewind_trj(t_trxstatus *status); +void rewind_trj(t_trxstatus* status); /* Rewind trajectory file as opened with read_first_x */ -struct t_topology *read_top(const char *fn, int *ePBC); +struct t_topology* read_top(const char* fn, int* ePBC); /* Extract a topology data structure from a topology file. * If ePBC!=NULL *ePBC gives the pbc type. */ diff --git a/src/gromacs/fileio/vmdio.cpp b/src/gromacs/fileio/vmdio.cpp index a604cae1b8..4e21ee5ace 100644 --- a/src/gromacs/fileio/vmdio.cpp +++ b/src/gromacs/fileio/vmdio.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -100,13 +101,13 @@ #include "external/vmd_molfile/molfile_plugin.h" #include "external/vmd_molfile/vmddlopen.h" #if !GMX_NATIVE_WINDOWS -#include +# include #else -#ifndef _WIN32_IE -#define _WIN32_IE 0x0500 /* SHGetFolderPath is available since WinXP/IE5 */ -#endif -#include -#include +# ifndef _WIN32_IE +# define _WIN32_IE 0x0500 /* SHGetFolderPath is available since WinXP/IE5 */ +# endif +# include +# include #endif #include "gromacs/fileio/gmxfio.h" @@ -120,24 +121,23 @@ typedef int (*initfunc)(); -typedef int (*regfunc)(void *, vmdplugin_register_cb); +typedef int (*regfunc)(void*, vmdplugin_register_cb); typedef int (*finifunc)(); - -static int register_cb(void *v, vmdplugin_t *p) +static int register_cb(void* v, vmdplugin_t* p) { - const char *key = p->name; - gmx_vmdplugin_t *vmdplugin = static_cast(v); + const char* key = p->name; + gmx_vmdplugin_t* vmdplugin = static_cast(v); if (strcmp(key, vmdplugin->filetype) == 0) { - vmdplugin->api = reinterpret_cast(p); + vmdplugin->api = reinterpret_cast(p); } return VMDPLUGIN_SUCCESS; } -static int load_sharedlibrary_plugins(const char *fullpath, gmx_vmdplugin_t *vmdplugin) +static int load_sharedlibrary_plugins(const char* fullpath, gmx_vmdplugin_t* vmdplugin) { /* Open the dll; try to execute the init function. */ void *handle, *ifunc, *registerfunc; @@ -146,7 +146,8 @@ static int load_sharedlibrary_plugins(const char *fullpath, gmx_vmdplugin_t *vmd { if (debug) { - fprintf(debug, "\nUnable to open dynamic library %s.\n%s\n", fullpath, vmddlerror()); /*only to debug because of stdc++ erros */ + fprintf(debug, "\nUnable to open dynamic library %s.\n%s\n", fullpath, + vmddlerror()); /*only to debug because of stdc++ erros */ } return 0; } @@ -182,7 +183,7 @@ static int load_sharedlibrary_plugins(const char *fullpath, gmx_vmdplugin_t *vmd } /*return: 1: success, 0: last frame, -1: error*/ -gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr) +gmx_bool read_next_vmd_frame(gmx_vmdplugin_t* vmdplugin, t_trxframe* fr) { int rc, i; rvec vec, angle; @@ -192,10 +193,10 @@ gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr) fr->bV = vmdplugin->bV; #if GMX_DOUBLE - snew(ts.coords, fr->natoms*3); + snew(ts.coords, fr->natoms * 3); if (fr->bV) { - snew(ts.velocities, fr->natoms*3); + snew(ts.velocities, fr->natoms * 3); } #else ts.coords = reinterpret_cast(fr->x); @@ -220,14 +221,14 @@ gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr) #if GMX_DOUBLE for (i = 0; i < fr->natoms; i++) { - fr->x[i][0] = .1*ts.coords[i*3]; - fr->x[i][1] = .1*ts.coords[i*3+1]; - fr->x[i][2] = .1*ts.coords[i*3+2]; + fr->x[i][0] = .1 * ts.coords[i * 3]; + fr->x[i][1] = .1 * ts.coords[i * 3 + 1]; + fr->x[i][2] = .1 * ts.coords[i * 3 + 2]; if (fr->bV) { - fr->v[i][0] = .1*ts.velocities[i*3]; - fr->v[i][1] = .1*ts.velocities[i*3+1]; - fr->v[i][2] = .1*ts.velocities[i*3+2]; + fr->v[i][0] = .1 * ts.velocities[i * 3]; + fr->v[i][1] = .1 * ts.velocities[i * 3 + 1]; + fr->v[i][2] = .1 * ts.velocities[i * 3 + 2]; } } sfree(ts.coords); @@ -248,8 +249,12 @@ gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr) fr->bX = true; fr->bBox = true; - vec[0] = .1*ts.A; vec[1] = .1*ts.B; vec[2] = .1*ts.C; - angle[0] = ts.alpha; angle[1] = ts.beta; angle[2] = ts.gamma; + vec[0] = .1 * ts.A; + vec[1] = .1 * ts.B; + vec[2] = .1 * ts.C; + angle[0] = ts.alpha; + angle[1] = ts.beta; + angle[2] = ts.gamma; matrix_convert(fr->box, vec, angle); if (vmdplugin->api->abiversion > 10) { @@ -265,21 +270,22 @@ gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr) return true; } -static int load_vmd_library(const char *fn, gmx_vmdplugin_t *vmdplugin) +static int load_vmd_library(const char* fn, gmx_vmdplugin_t* vmdplugin) { - const char *err; - int ret = 0; + const char* err; + int ret = 0; #if !GMX_NATIVE_WINDOWS glob_t globbuf; const std::string defpath_suffix = "/plugins/*/molfile"; const std::string defpathenv = GMX_VMD_PLUGIN_PATH; #else - WIN32_FIND_DATA ffd; - HANDLE hFind = INVALID_HANDLE_VALUE; - char progfolder[GMX_PATH_MAX]; - std::string defpath_suffix = "\\plugins\\WIN32\\molfile"; + WIN32_FIND_DATA ffd; + HANDLE hFind = INVALID_HANDLE_VALUE; + char progfolder[GMX_PATH_MAX]; + std::string defpath_suffix = "\\plugins\\WIN32\\molfile"; SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, progfolder); - std::string defpathenv = gmx::formatString("%s\\University of Illinois\\VMD\\plugins\\WIN32\\molfile", progfolder); + std::string defpathenv = + gmx::formatString("%s\\University of Illinois\\VMD\\plugins\\WIN32\\molfile", progfolder); #endif vmdplugin->api = nullptr; @@ -312,7 +318,7 @@ static int load_vmd_library(const char *fn, gmx_vmdplugin_t *vmdplugin) } } #if !GMX_NATIVE_WINDOWS - std::string pathname = gmx::Path::join (pathenv, "/*.so"); + std::string pathname = gmx::Path::join(pathenv, "/*.so"); glob(pathname.c_str(), 0, nullptr, &globbuf); if (globbuf.gl_pathc == 0) { @@ -334,7 +340,7 @@ static int load_vmd_library(const char *fn, gmx_vmdplugin_t *vmdplugin) globfree(&globbuf); #else std::string pathname = gmx::Path::join(pathenv, "\\*.so"); - hFind = FindFirstFile(pathname.c_str(), &ffd); + hFind = FindFirstFile(pathname.c_str(), &ffd); if (INVALID_HANDLE_VALUE == hFind) { printf("\nNo VMD Plugins found\n"); @@ -344,8 +350,7 @@ static int load_vmd_library(const char *fn, gmx_vmdplugin_t *vmdplugin) { std::string filename = gmx::Path::join(pathenv, ffd.cFileName); ret |= load_sharedlibrary_plugins(filename.c_str(), vmdplugin); - } - while (FindNextFile(hFind, &ffd ) != 0 && vmdplugin->api == NULL); + } while (FindNextFile(hFind, &ffd) != 0 && vmdplugin->api == NULL); FindClose(hFind); #endif @@ -379,13 +384,12 @@ static int load_vmd_library(const char *fn, gmx_vmdplugin_t *vmdplugin) printf("\nUsing VMD plugin: %s (%s)\n", vmdplugin->api->name, vmdplugin->api->prettyname); return 1; - } -int read_first_vmd_frame(const char *fn, gmx_vmdplugin_t **vmdpluginp, t_trxframe *fr) +int read_first_vmd_frame(const char* fn, gmx_vmdplugin_t** vmdpluginp, t_trxframe* fr) { - molfile_timestep_metadata_t *metadata = nullptr; - gmx_vmdplugin_t *vmdplugin; + molfile_timestep_metadata_t* metadata = nullptr; + gmx_vmdplugin_t* vmdplugin; snew(vmdplugin, 1); *vmdpluginp = vmdplugin; @@ -398,8 +402,7 @@ int read_first_vmd_frame(const char *fn, gmx_vmdplugin_t **vmdpluginp, t_trxfram if (!vmdplugin->handle) { - fprintf(stderr, "\nError: could not open file '%s' for reading.\n", - fn); + fprintf(stderr, "\nError: could not open file '%s' for reading.\n", fn); return 0; } @@ -410,13 +413,12 @@ int read_first_vmd_frame(const char *fn, gmx_vmdplugin_t **vmdpluginp, t_trxfram } else if (fr->natoms == MOLFILE_NUMATOMS_NONE) { - fprintf(stderr, "\nNo atoms found by VMD plugin in file %s.\n", fn ); + fprintf(stderr, "\nNo atoms found by VMD plugin in file %s.\n", fn); return 0; } - else if (fr->natoms < 1) /*should not be reached*/ + else if (fr->natoms < 1) /*should not be reached*/ { - fprintf(stderr, "\nUnknown number of atoms %d for VMD plugin opening file %s.\n", - fr->natoms, fn ); + fprintf(stderr, "\nUnknown number of atoms %d for VMD plugin opening file %s.\n", fr->natoms, fn); return 0; } @@ -441,5 +443,4 @@ int read_first_vmd_frame(const char *fn, gmx_vmdplugin_t **vmdpluginp, t_trxfram "\nEither way, GROMACS cannot tell whether the trajectory has velocities.\n"); } return 1; - } diff --git a/src/gromacs/fileio/vmdio.h b/src/gromacs/fileio/vmdio.h index 1e5c437ab6..2e40cfd2dc 100644 --- a/src/gromacs/fileio/vmdio.h +++ b/src/gromacs/fileio/vmdio.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2012,2013,2014,2016, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2012,2013,2014,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,13 +43,13 @@ struct t_trxframe; struct gmx_vmdplugin_t { - molfile_plugin_t *api; - const char *filetype; - void *handle; + molfile_plugin_t* api; + const char* filetype; + void* handle; gmx_bool bV; }; -int read_first_vmd_frame(const char *fn, gmx_vmdplugin_t **vmdpluginp, t_trxframe *fr); -gmx_bool read_next_vmd_frame(gmx_vmdplugin_t *vmdplugin, t_trxframe *fr); +int read_first_vmd_frame(const char* fn, gmx_vmdplugin_t** vmdpluginp, t_trxframe* fr); +gmx_bool read_next_vmd_frame(gmx_vmdplugin_t* vmdplugin, t_trxframe* fr); #endif diff --git a/src/gromacs/fileio/warninp.cpp b/src/gromacs/fileio/warninp.cpp index bcdfcd5f8b..d8665b247d 100644 --- a/src/gromacs/fileio/warninp.cpp +++ b/src/gromacs/fileio/warninp.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,7 +46,8 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -typedef struct warninp { +typedef struct warninp +{ gmx_bool bAllowWarnings; int nwarn_note; int nwarn_warn; @@ -63,20 +64,20 @@ warninp_t init_warning(gmx_bool bAllowWarnings, int maxwarning) wi->bAllowWarnings = bAllowWarnings; wi->maxwarn = maxwarning; warning_reset(wi); - wi->filenm = "unknown"; - wi->lineno = 0; + wi->filenm = "unknown"; + wi->lineno = 0; return wi; } void warning_reset(warninp_t wi) { - wi->nwarn_note = 0; - wi->nwarn_warn = 0; - wi->nwarn_error = 0; + wi->nwarn_note = 0; + wi->nwarn_warn = 0; + wi->nwarn_error = 0; } -void set_warning_line(warninp_t wi, const char *s, int line) +void set_warning_line(warninp_t wi, const char* s, int line) { if (s != nullptr) { @@ -90,12 +91,12 @@ int get_warning_line(warninp_t wi) return wi->lineno; } -const char *get_warning_file(warninp_t wi) +const char* get_warning_file(warninp_t wi) { return wi->filenm.c_str(); } -static void low_warning(warninp_t wi, const char *wtype, int n, const char *s) +static void low_warning(warninp_t wi, const char* wtype, int n, const char* s) { #define indent 2 char *temp, *temp2; @@ -105,25 +106,24 @@ static void low_warning(warninp_t wi, const char *wtype, int n, const char *s) { s = "Empty error message."; } - snew(temp, std::strlen(s)+indent+1); + snew(temp, std::strlen(s) + indent + 1); for (i = 0; i < indent; i++) { temp[i] = ' '; } temp[indent] = '\0'; std::strcat(temp, s); - temp2 = wrap_lines(temp, 78-indent, indent, FALSE); + temp2 = wrap_lines(temp, 78 - indent, indent, FALSE); if (!wi->filenm.empty()) { if (wi->lineno != -1) { - fprintf(stderr, "\n%s %d [file %s, line %d]:\n%s\n\n", - wtype, n, wi->filenm.c_str(), wi->lineno, temp2); + fprintf(stderr, "\n%s %d [file %s, line %d]:\n%s\n\n", wtype, n, wi->filenm.c_str(), + wi->lineno, temp2); } else { - fprintf(stderr, "\n%s %d [file %s]:\n%s\n\n", - wtype, n, wi->filenm.c_str(), temp2); + fprintf(stderr, "\n%s %d [file %s]:\n%s\n\n", wtype, n, wi->filenm.c_str(), temp2); } } else @@ -134,7 +134,7 @@ static void low_warning(warninp_t wi, const char *wtype, int n, const char *s) sfree(temp2); } -void warning(warninp_t wi, const char *s) +void warning(warninp_t wi, const char* s) { if (wi->bAllowWarnings) { @@ -147,54 +147,52 @@ void warning(warninp_t wi, const char *s) } } -void warning(warninp_t wi, const std::string &s) +void warning(warninp_t wi, const std::string& s) { warning(wi, s.c_str()); } -void warning_note(warninp_t wi, const char *s) +void warning_note(warninp_t wi, const char* s) { wi->nwarn_note++; low_warning(wi, "NOTE", wi->nwarn_note, s); } -void warning_note(warninp_t wi, const std::string &s) +void warning_note(warninp_t wi, const std::string& s) { warning_note(wi, s.c_str()); } -void warning_error(warninp_t wi, const char *s) +void warning_error(warninp_t wi, const char* s) { wi->nwarn_error++; low_warning(wi, "ERROR", wi->nwarn_error, s); } -void warning_error(warninp_t wi, const std::string &s) +void warning_error(warninp_t wi, const std::string& s) { warning_error(wi, s.c_str()); } -static void print_warn_count(const char *type, int n) +static void print_warn_count(const char* type, int n) { if (n > 0) { - fprintf(stderr, "\nThere %s %d %s%s\n", - (n == 1) ? "was" : "were", n, type, (n == 1) ? "" : "s"); + fprintf(stderr, "\nThere %s %d %s%s\n", (n == 1) ? "was" : "were", n, type, (n == 1) ? "" : "s"); } } // Note it is the caller's responsibility to ensure that exiting is correct behaviour -[[noreturn]] static void check_warning_error_impl(warninp_t wi, int f_errno, const char *file, int line) +[[noreturn]] static void check_warning_error_impl(warninp_t wi, int f_errno, const char* file, int line) { print_warn_count("note", wi->nwarn_note); print_warn_count("warning", wi->nwarn_warn); gmx_fatal(f_errno, file, line, "There %s %d error%s in input file(s)", - (wi->nwarn_error == 1) ? "was" : "were", wi->nwarn_error, - (wi->nwarn_error == 1) ? "" : "s"); + (wi->nwarn_error == 1) ? "was" : "were", wi->nwarn_error, (wi->nwarn_error == 1) ? "" : "s"); } -void check_warning_error(warninp_t wi, int f_errno, const char *file, int line) +void check_warning_error(warninp_t wi, int f_errno, const char* file, int line) { if (wi->nwarn_error > 0) { @@ -202,13 +200,13 @@ void check_warning_error(warninp_t wi, int f_errno, const char *file, int line) } } -void warning_error_and_exit(warninp_t wi, const char *s, int f_errno, const char *file, int line) +void warning_error_and_exit(warninp_t wi, const char* s, int f_errno, const char* file, int line) { warning_error(wi, s); check_warning_error_impl(wi, f_errno, file, line); } -void warning_error_and_exit(warninp_t wi, const std::string &s, int f_errno, const char *file, int line) +void warning_error_and_exit(warninp_t wi, const std::string& s, int f_errno, const char* file, int line) { warning_error_and_exit(wi, s.c_str(), f_errno, file, line); } @@ -218,7 +216,7 @@ gmx_bool warning_errors_exist(warninp_t wi) return (wi->nwarn_error > 0); } -void done_warning(warninp_t wi, int f_errno, const char *file, int line) +void done_warning(warninp_t wi, int f_errno, const char* file, int line) { // If we've had an error, then this will report the number of // notes and warnings, and then exit. @@ -244,22 +242,18 @@ void free_warning(warninp_t wi) delete wi; } -void _too_few(warninp_t wi, const char *fn, int line) +void _too_few(warninp_t wi, const char* fn, int line) { char buf[STRLEN]; - sprintf(buf, - "Too few parameters on line (source file %s, line %d)", - fn, line); + sprintf(buf, "Too few parameters on line (source file %s, line %d)", fn, line); warning(wi, buf); } -void _incorrect_n_param(warninp_t wi, const char *fn, int line) +void _incorrect_n_param(warninp_t wi, const char* fn, int line) { char buf[STRLEN]; - sprintf(buf, - "Incorrect number of parameters on line (source file %s, line %d)", - fn, line); + sprintf(buf, "Incorrect number of parameters on line (source file %s, line %d)", fn, line); warning(wi, buf); } diff --git a/src/gromacs/fileio/warninp.h b/src/gromacs/fileio/warninp.h index 57949b440a..c8ee1eedd4 100644 --- a/src/gromacs/fileio/warninp.h +++ b/src/gromacs/fileio/warninp.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,11 +42,10 @@ #include "gromacs/utility/basedefinitions.h" /* Abstract type for warning bookkeeping */ -typedef struct warninp *warninp_t; +typedef struct warninp* warninp_t; -warninp_t -init_warning(gmx_bool bAllowWarnings, int maxwarning); +warninp_t init_warning(gmx_bool bAllowWarnings, int maxwarning); /* Initialize the warning data structure. * If bAllowWarnings=FALSE, all warnings (calls to warning()) will be * transformed into errors, calls to warning_note still produce notes. @@ -57,21 +56,17 @@ init_warning(gmx_bool bAllowWarnings, int maxwarning); * a -maxwarn command line option. */ -void -set_warning_line(warninp_t wi, const char *fn, int line); +void set_warning_line(warninp_t wi, const char* fn, int line); /* Set filename and linenumber for the warning */ -int -get_warning_line(warninp_t wi); +int get_warning_line(warninp_t wi); /* Get linenumber for the warning */ -const char * -get_warning_file(warninp_t wi); +const char* get_warning_file(warninp_t wi); /* Get filename for the warning */ -void -warning(warninp_t wi, const char *s); +void warning(warninp_t wi, const char* s); /* Issue a warning, with the string s. If s == NULL, then warn_buf * will be printed instead. The file and line set by set_warning_line * are printed, nwarn_warn (local) is incremented. @@ -81,11 +76,9 @@ warning(warninp_t wi, const char *s); * otherwise warning_note should be called. */ //! Convenience wrapper. -void -warning(warninp_t wi, const std::string &s); +void warning(warninp_t wi, const std::string& s); -void -warning_note(warninp_t wi, const char *s); +void warning_note(warninp_t wi, const char* s); /* Issue a note, with the string s. If s == NULL, then warn_buf * will be printed instead. The file and line set by set_warning_line * are printed, nwarn_note (local) is incremented. @@ -94,28 +87,26 @@ warning_note(warninp_t wi, const char *s); */ //! Convenience wrapper. -void -warning_note(warninp_t wi, const std::string &s); +void warning_note(warninp_t wi, const std::string& s); -void -warning_error(warninp_t wi, const char *s); +void warning_error(warninp_t wi, const char* s); /* Issue an error, with the string s. If s == NULL, then warn_buf * will be printed instead. The file and line set by set_warning_line * are printed, nwarn_error (local) is incremented. */ //! Convenience wrapper. -void -warning_error(warninp_t wi, const std::string &s); +void warning_error(warninp_t wi, const std::string& s); /*! \brief Issue an error with warning_error() and prevent further * processing by calling check_warning_error(). * * This is intended for use where there is no way to produce a data * structure that would prevent execution from segfaulting. */ -[[noreturn]] void warning_error_and_exit(warninp_t wi, const char *s, int f_errno, const char *file, int line); +[[noreturn]] void warning_error_and_exit(warninp_t wi, const char* s, int f_errno, const char* file, int line); //! \copydoc warning_error_and_exit(warninp_t, const char *, int, const char *, int); -[[noreturn]] void warning_error_and_exit(warninp_t wi, const std::string &s, int f_errno, const char *file, int line); +[[noreturn]] void +warning_error_and_exit(warninp_t wi, const std::string& s, int f_errno, const char* file, int line); gmx_bool warning_errors_exist(warninp_t wi); /* Return whether any error-level warnings were issued to wi. */ @@ -123,14 +114,12 @@ gmx_bool warning_errors_exist(warninp_t wi); //! Resets the count for all kinds of warnings to zero. void warning_reset(warninp_t wi); -void -check_warning_error(warninp_t wi, int f_errno, const char *file, int line); +void check_warning_error(warninp_t wi, int f_errno, const char* file, int line); /* When warning_error has been called at least once gmx_fatal is called, * otherwise does nothing. */ -void -done_warning(warninp_t wi, int f_errno, const char *file, int line); +void done_warning(warninp_t wi, int f_errno, const char* file, int line); /* Should be called when finished processing the input file. * Prints the number of notes and warnings * and generates a fatal error when errors were found or too many @@ -138,17 +127,14 @@ done_warning(warninp_t wi, int f_errno, const char *file, int line); * Frees the data structure pointed to by wi. */ -void -free_warning(warninp_t wi); +void free_warning(warninp_t wi); /* Frees the data structure pointed to by wi. */ -void -_too_few(warninp_t wi, const char *fn, int line); +void _too_few(warninp_t wi, const char* fn, int line); #define too_few(wi) _too_few(wi, __FILE__, __LINE__) /* Issue a warning stating 'Too few parameters' */ -void -_incorrect_n_param(warninp_t wi, const char *fn, int line); +void _incorrect_n_param(warninp_t wi, const char* fn, int line); #define incorrect_n_param(wi) _incorrect_n_param(wi, __FILE__, __LINE__) /* Issue a warning stating 'Incorrect number of parameters' */ diff --git a/src/gromacs/fileio/writeps.cpp b/src/gromacs/fileio/writeps.cpp index 72bf72ba4e..716ae92603 100644 --- a/src/gromacs/fileio/writeps.cpp +++ b/src/gromacs/fileio/writeps.cpp @@ -44,13 +44,13 @@ using namespace gmx; -const char *fontnm[efontNR] = { - "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic", - "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique", - "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" +const char* fontnm[efontNR] = { + "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic", + "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique", + "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique" }; -t_psdata ps_open(const char *fn, real x1, real y1, real x2, real y2) +t_psdata ps_open(const char* fn, real x1, real y1, real x2, real y2) { t_psdata ps; @@ -70,22 +70,22 @@ t_psdata ps_open(const char *fn, real x1, real y1, real x2, real y2) return ps; } -void ps_linewidth(t_psdata *ps, int lw) +void ps_linewidth(t_psdata* ps, int lw) { fprintf(ps->fp, "%d setlinewidth\n", lw); } -static void ps_defcolor(t_psdata *ps, real r, real g, real b, char *cname) +static void ps_defcolor(t_psdata* ps, real r, real g, real b, char* cname) { fprintf(ps->fp, "/%s {%g %g %g setrgbcolor} bind def\n", cname, r, g, b); } -static void ps_selcolor(t_psdata *ps, char *cname) +static void ps_selcolor(t_psdata* ps, char* cname) { fprintf(ps->fp, "%s\n", cname); } -static gmx::index search_col(t_psdata *ps, real r, real g, real b) +static gmx::index search_col(t_psdata* ps, real r, real g, real b) { for (gmx::index i = 0; ssize(ps->rgb); ++i) { @@ -100,12 +100,12 @@ static gmx::index search_col(t_psdata *ps, real r, real g, real b) sprintf(buf, "C%d", indexToBackElement); ps_defcolor(ps, r, g, b, buf); fprintf(ps->fp, "/B%zu {%s b} bind def\n", ps->rgb.size(), buf); - ps->rgb.emplace_back(t_rgb {r, g, b}); + ps->rgb.emplace_back(t_rgb{ r, g, b }); return indexToBackElement; } -void ps_color(t_psdata *ps, real r, real g, real b) +void ps_color(t_psdata* ps, real r, real g, real b) { char buf[12]; int indexToElement = static_cast(search_col(ps, r, g, b)); @@ -114,29 +114,30 @@ void ps_color(t_psdata *ps, real r, real g, real b) ps_selcolor(ps, buf); } -void ps_rgb(t_psdata *ps, const t_rgb *rgb) +void ps_rgb(t_psdata* ps, const t_rgb* rgb) { ps_color(ps, rgb->r, rgb->g, rgb->b); } -void ps_init_rgb_nbox(t_psdata *ps, real xbox, real ybox) +void ps_init_rgb_nbox(t_psdata* ps, real xbox, real ybox) { ps->gen_ybox = ybox; - fprintf(ps->fp, "/by {def currentpoint " + fprintf(ps->fp, + "/by {def currentpoint " "%g y r %g %g r %g y neg r %g %g r f y add moveto} bind def\n", 0.0, xbox, 0.0, 0.0, -xbox, 0.0); /* macro bn is used in ps_rgb_nbox to draw rectangular boxes */ } -void ps_rgb_nbox(t_psdata *ps, t_rgb *rgb, real n) +void ps_rgb_nbox(t_psdata* ps, t_rgb* rgb, real n) { int i; if (n > 2) { ps_rgb(ps, rgb); - fprintf(ps->fp, "/y %g by\n", n*ps->gen_ybox); + fprintf(ps->fp, "/y %g by\n", n * ps->gen_ybox); /* macro by is defined in ps_init_rgb_nbox */ } else @@ -146,101 +147,99 @@ void ps_rgb_nbox(t_psdata *ps, t_rgb *rgb, real n) ps_rgb_box(ps, rgb); } } - } -void ps_init_rgb_box(t_psdata *ps, real xbox, real ybox) +void ps_init_rgb_box(t_psdata* ps, real xbox, real ybox) { - fprintf(ps->fp, "/b {currentpoint " + fprintf(ps->fp, + "/b {currentpoint " "%g %g r %g %g r %g %g r %g %g r f %g add moveto} bind def\n", 0.0, ybox, xbox, 0.0, 0.0, -ybox, -xbox, 0.0, ybox); /* macro b is used in search_col to define macro B */ } -void ps_rgb_box(t_psdata *ps, t_rgb *rgb) +void ps_rgb_box(t_psdata* ps, t_rgb* rgb) { fprintf(ps->fp, "B%zd\n", search_col(ps, rgb->r, rgb->g, rgb->b)); /* macro B is defined in search_col from macro b */ } -void ps_lineto(t_psdata *ps, real x, real y) +void ps_lineto(t_psdata* ps, real x, real y) { fprintf(ps->fp, "%g %g l\n", x, y); } -void ps_linerel(t_psdata *ps, real dx, real dy) +void ps_linerel(t_psdata* ps, real dx, real dy) { fprintf(ps->fp, "%g %g r\n", dx, dy); } -void ps_moveto(t_psdata *ps, real x, real y) +void ps_moveto(t_psdata* ps, real x, real y) { fprintf(ps->fp, "%g %g m\n", x, y); } -void ps_moverel(t_psdata *ps, real dx, real dy) +void ps_moverel(t_psdata* ps, real dx, real dy) { fprintf(ps->fp, "%g %g rm\n", dx, dy); } -void ps_line(t_psdata *ps, real x1, real y1, real x2, real y2) +void ps_line(t_psdata* ps, real x1, real y1, real x2, real y2) { ps_moveto(ps, x1, y1); ps_lineto(ps, x2, y2); fprintf(ps->fp, "s\n"); } -static void do_box(t_psdata *ps, real x1, real y1, real x2, real y2) +static void do_box(t_psdata* ps, real x1, real y1, real x2, real y2) { ps_moveto(ps, x1, y1); - ps_linerel(ps, 0, static_cast(y2-y1)); - ps_linerel(ps, static_cast(x2-x1), 0); - ps_linerel(ps, 0, static_cast(y1-y2)); - ps_linerel(ps, static_cast(x1-x2), 0); + ps_linerel(ps, 0, static_cast(y2 - y1)); + ps_linerel(ps, static_cast(x2 - x1), 0); + ps_linerel(ps, 0, static_cast(y1 - y2)); + ps_linerel(ps, static_cast(x1 - x2), 0); } -void ps_box(t_psdata *ps, real x1, real y1, real x2, real y2) +void ps_box(t_psdata* ps, real x1, real y1, real x2, real y2) { do_box(ps, x1, y1, x2, y2); fprintf(ps->fp, "s\n"); } -void ps_fillbox(t_psdata *ps, real x1, real y1, real x2, real y2) +void ps_fillbox(t_psdata* ps, real x1, real y1, real x2, real y2) { do_box(ps, x1, y1, x2, y2); fprintf(ps->fp, "f\n"); } -void ps_arc(t_psdata *ps, real x1, real y1, real rad, real a0, real a1) +void ps_arc(t_psdata* ps, real x1, real y1, real rad, real a0, real a1) { fprintf(ps->fp, "%g %g %g %g %g arc s\n", x1, y1, rad, a0, a1); } -void ps_fillarc(t_psdata *ps, real x1, real y1, real rad, real a0, real a1) +void ps_fillarc(t_psdata* ps, real x1, real y1, real rad, real a0, real a1) { fprintf(ps->fp, "%g %g %g %g %g arc f\n", x1, y1, rad, a0, a1); } -void ps_arcslice(t_psdata *ps, real xc, real yc, - real rad1, real rad2, real a0, real a1) +void ps_arcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1) { - fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath s\n", - xc, yc, rad1, a0, a1, xc, yc, rad2, a1, a0); + fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath s\n", xc, yc, rad1, + a0, a1, xc, yc, rad2, a1, a0); } -void ps_fillarcslice(t_psdata *ps, real xc, real yc, - real rad1, real rad2, real a0, real a1) +void ps_fillarcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1) { - fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath f\n", - xc, yc, rad1, a0, a1, xc, yc, rad2, a1, a0); + fprintf(ps->fp, "newpath %g %g %g %g %g arc %g %g %g %g %g arcn closepath f\n", xc, yc, rad1, + a0, a1, xc, yc, rad2, a1, a0); } -void ps_circle(t_psdata *ps, real x1, real y1, real rad) +void ps_circle(t_psdata* ps, real x1, real y1, real rad) { ps_arc(ps, x1, y1, rad, 0, 360); } -void ps_font(t_psdata *ps, int font, real size) +void ps_font(t_psdata* ps, int font, real size) { if ((font < 0) || (font > efontNR)) @@ -252,19 +251,19 @@ void ps_font(t_psdata *ps, int font, real size) fprintf(ps->fp, "%g scalefont setfont\n", size); } -void ps_strfont(t_psdata *ps, char *font, real size) +void ps_strfont(t_psdata* ps, char* font, real size) { fprintf(ps->fp, "/%s findfont\n", font); fprintf(ps->fp, "%g scalefont setfont\n", size); } -void ps_text(t_psdata *ps, real x1, real y1, const std::string &str) +void ps_text(t_psdata* ps, real x1, real y1, const std::string& str) { ps_moveto(ps, x1, y1); fprintf(ps->fp, "(%s) show\n", str.c_str()); } -void ps_flip(t_psdata *ps, gmx_bool bPlus) +void ps_flip(t_psdata* ps, gmx_bool bPlus) { if (bPlus) { @@ -276,12 +275,12 @@ void ps_flip(t_psdata *ps, gmx_bool bPlus) } } -void ps_rotate(t_psdata *ps, real angle) +void ps_rotate(t_psdata* ps, real angle) { fprintf(ps->fp, "%f rotate\n", angle); } -void ps_ctext(t_psdata *ps, real x1, real y1, const std::string &str, int expos) +void ps_ctext(t_psdata* ps, real x1, real y1, const std::string& str, int expos) { if (expos == eXLeft) { @@ -292,33 +291,26 @@ void ps_ctext(t_psdata *ps, real x1, real y1, const std::string &str, int expos) fprintf(ps->fp, "(%s) stringwidth\n", str.c_str()); switch (expos) { - case eXLeft: - fprintf(ps->fp, "exch 0 exch pop exch\n"); - break; - case eXCenter: - fprintf(ps->fp, "exch 2 div neg exch\n"); - break; - case eXRight: - fprintf(ps->fp, "exch neg exch\n"); - break; - default: - gmx_fatal(FARGS, "invalid position index (expos=%d)", expos); + case eXLeft: fprintf(ps->fp, "exch 0 exch pop exch\n"); break; + case eXCenter: fprintf(ps->fp, "exch 2 div neg exch\n"); break; + case eXRight: fprintf(ps->fp, "exch neg exch\n"); break; + default: gmx_fatal(FARGS, "invalid position index (expos=%d)", expos); } fprintf(ps->fp, "rmoveto (%s) show\n", str.c_str()); } -void ps_translate(t_psdata *ps, real x, real y) +void ps_translate(t_psdata* ps, real x, real y) { fprintf(ps->fp, "%g %g translate\n", x, y); } -void ps_setorigin(t_psdata *ps) +void ps_setorigin(t_psdata* ps) { fprintf(ps->fp, "currentpoint dup 3 -1 roll dup 4 1 roll exch translate\n"); ps->ostack++; } -void ps_unsetorigin(t_psdata *ps) +void ps_unsetorigin(t_psdata* ps) { if (ps->ostack <= 0) { @@ -328,14 +320,14 @@ void ps_unsetorigin(t_psdata *ps) ps->ostack--; } -void ps_close(t_psdata *ps) +void ps_close(t_psdata* ps) { fprintf(ps->fp, "%%showpage\n"); fprintf(ps->fp, "%%%%EOF\n"); gmx_fio_fclose(ps->fp); } -void ps_comment(t_psdata *ps, const char *s) +void ps_comment(t_psdata* ps, const char* s) { fprintf(ps->fp, "%%%% %s\n", s); } diff --git a/src/gromacs/fileio/writeps.h b/src/gromacs/fileio/writeps.h index 1d3dc02a97..d6449e9adc 100644 --- a/src/gromacs/fileio/writeps.h +++ b/src/gromacs/fileio/writeps.h @@ -49,25 +49,41 @@ /* TODO: These two enums are used also in xutil.h in src/programs/view/. * The Y position enum doesn't seem to be actually used in this header... */ -typedef enum { - eXCenter, eXLeft, eXRight +typedef enum +{ + eXCenter, + eXLeft, + eXRight } eXPos; -typedef enum { - eYCenter, eYTop, eYBottom +typedef enum +{ + eYCenter, + eYTop, + eYBottom } eYPos; -enum { - efontTIMES, efontTIMESITALIC, efontTIMESBOLD, efontTIMESBOLDITALIC, - efontHELV, efontHELVITALIC, efontHELVBOLD, efontHELVBOLDITALIC, - efontCOUR, efontCOURITALIC, efontCOURBOLD, efontCOURBOLDITALIC, +enum +{ + efontTIMES, + efontTIMESITALIC, + efontTIMESBOLD, + efontTIMESBOLDITALIC, + efontHELV, + efontHELVITALIC, + efontHELVBOLD, + efontHELVBOLDITALIC, + efontCOUR, + efontCOURITALIC, + efontCOURBOLD, + efontCOURBOLDITALIC, efontNR }; struct t_psdata { - FILE *fp = nullptr; + FILE* fp = nullptr; int maxrgb = 0; std::vector rgb; real gen_ybox = 0; @@ -75,57 +91,55 @@ struct t_psdata }; -extern const char *fontnm[efontNR]; +extern const char* fontnm[efontNR]; -t_psdata ps_open(const char *fn, real x1, real y1, real x2, real y2); +t_psdata ps_open(const char* fn, real x1, real y1, real x2, real y2); -void ps_linewidth(t_psdata *ps, int lw); -void ps_color(t_psdata *ps, real r, real g, real b); -void ps_rgb(t_psdata *ps, const t_rgb *rgb); +void ps_linewidth(t_psdata* ps, int lw); +void ps_color(t_psdata* ps, real r, real g, real b); +void ps_rgb(t_psdata* ps, const t_rgb* rgb); -void ps_rgb_box(t_psdata *ps, t_rgb *rgb); -void ps_rgb_nbox(t_psdata *ps, t_rgb *rgb, real n); -void ps_init_rgb_box(t_psdata *ps, real xbox, real ybox); -void ps_init_rgb_nbox(t_psdata *ps, real xbox, real ybox); +void ps_rgb_box(t_psdata* ps, t_rgb* rgb); +void ps_rgb_nbox(t_psdata* ps, t_rgb* rgb, real n); +void ps_init_rgb_box(t_psdata* ps, real xbox, real ybox); +void ps_init_rgb_nbox(t_psdata* ps, real xbox, real ybox); -void ps_lineto(t_psdata *ps, real x, real y); -void ps_linerel(t_psdata *ps, real dx, real dy); +void ps_lineto(t_psdata* ps, real x, real y); +void ps_linerel(t_psdata* ps, real dx, real dy); -void ps_moveto(t_psdata *ps, real x, real y); -void ps_moverel(t_psdata *ps, real dx, real dy); +void ps_moveto(t_psdata* ps, real x, real y); +void ps_moverel(t_psdata* ps, real dx, real dy); -void ps_line(t_psdata *ps, real x1, real y1, real x2, real y2); +void ps_line(t_psdata* ps, real x1, real y1, real x2, real y2); -void ps_box(t_psdata *ps, real x1, real y1, real x2, real y2); -void ps_fillbox(t_psdata *ps, real x1, real y1, real x2, real y2); +void ps_box(t_psdata* ps, real x1, real y1, real x2, real y2); +void ps_fillbox(t_psdata* ps, real x1, real y1, real x2, real y2); -void ps_arc(t_psdata *ps, real x1, real y1, real rad, real a0, real a1); -void ps_fillarc(t_psdata *ps, real x1, real y1, real rad, real a0, real a1); -void ps_arcslice(t_psdata *ps, real xc, real yc, - real rad1, real rad2, real a0, real a1); -void ps_fillarcslice(t_psdata *ps, real xc, real yc, - real rad1, real rad2, real a0, real a1); +void ps_arc(t_psdata* ps, real x1, real y1, real rad, real a0, real a1); +void ps_fillarc(t_psdata* ps, real x1, real y1, real rad, real a0, real a1); +void ps_arcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1); +void ps_fillarcslice(t_psdata* ps, real xc, real yc, real rad1, real rad2, real a0, real a1); -void ps_circle(t_psdata *ps, real x1, real y1, real rad); +void ps_circle(t_psdata* ps, real x1, real y1, real rad); -void ps_font(t_psdata *ps, int font, real size); -void ps_strfont(t_psdata *ps, char *font, real size); +void ps_font(t_psdata* ps, int font, real size); +void ps_strfont(t_psdata* ps, char* font, real size); -void ps_text(t_psdata *ps, real x1, real y1, const std::string &str); -void ps_ctext(t_psdata *ps, real x1, real y1, const std::string &str, int expos); +void ps_text(t_psdata* ps, real x1, real y1, const std::string& str); +void ps_ctext(t_psdata* ps, real x1, real y1, const std::string& str, int expos); -void ps_close(t_psdata *ps); +void ps_close(t_psdata* ps); -void ps_flip(t_psdata *ps, gmx_bool bPlus); +void ps_flip(t_psdata* ps, gmx_bool bPlus); /* Rotate over 90 (bPlus) or -90 (!bPlus) degrees */ -void ps_rotate(t_psdata *ps, real angle); +void ps_rotate(t_psdata* ps, real angle); -void ps_translate(t_psdata *ps, real x, real y); +void ps_translate(t_psdata* ps, real x, real y); -void ps_setorigin(t_psdata *ps); -void ps_unsetorigin(t_psdata *ps); +void ps_setorigin(t_psdata* ps); +void ps_unsetorigin(t_psdata* ps); -void ps_comment(t_psdata *ps, const char *s); +void ps_comment(t_psdata* ps, const char* s); #endif diff --git a/src/gromacs/fileio/xdr_datatype.h b/src/gromacs/fileio/xdr_datatype.h index 9011f16074..108bd92c58 100644 --- a/src/gromacs/fileio/xdr_datatype.h +++ b/src/gromacs/fileio/xdr_datatype.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,6 +50,6 @@ typedef enum } xdr_datatype; /* names corresponding to the xdr_datatype enum */ -extern const char *xdr_datatype_names[]; +extern const char* xdr_datatype_names[]; #endif diff --git a/src/gromacs/fileio/xdrd.cpp b/src/gromacs/fileio/xdrd.cpp index 912de023dd..45175a5d6a 100644 --- a/src/gromacs/fileio/xdrd.cpp +++ b/src/gromacs/fileio/xdrd.cpp @@ -41,7 +41,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -int xdr_real(XDR *xdrs, real *r) +int xdr_real(XDR* xdrs, real* r) { #if GMX_DOUBLE float f; @@ -53,18 +53,18 @@ int xdr_real(XDR *xdrs, real *r) return ret; #else - return xdr_float(xdrs, static_cast(r)); + return xdr_float(xdrs, static_cast(r)); #endif } -int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision) +int xdr3drcoord(XDR* xdrs, real* fp, int* size, real* precision) { #if GMX_DOUBLE - float *ffp; + float* ffp; float fprec; int i, ret, isize; - isize = *size*DIM; + isize = *size * DIM; if (isize <= 0) { gmx_fatal(FARGS, "Don't know what to malloc for ffp, isize = %d", isize); @@ -88,11 +88,11 @@ int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision) sfree(ffp); return ret; #else - return xdr3dfcoord(xdrs, reinterpret_cast(fp), size, reinterpret_cast(precision)); + return xdr3dfcoord(xdrs, reinterpret_cast(fp), size, reinterpret_cast(precision)); #endif } -int xdr_int32(XDR *xdrs, int32_t *i) +int xdr_int32(XDR* xdrs, int32_t* i) { // Note that this implementation assumes that an int is at least // 32 bits, which is not strictly required by the language, but @@ -101,30 +101,31 @@ int xdr_int32(XDR *xdrs, int32_t *i) static_assert(sizeof(int) >= 4, "XDR handling assumes that an int32_t can be stored in an int"); int temporary = static_cast(*i); int ret = xdr_int(xdrs, &temporary); - *i = static_cast(temporary); + *i = static_cast(temporary); return ret; } -int xdr_int64(XDR *xdrs, int64_t *i) +int xdr_int64(XDR* xdrs, int64_t* i) { // Note that this implementation assumes that an int is at least // 32 bits, which is not strictly required by the language, but // good enough in practice on 32- or 64-bit systems. GROMACS // requires 64-bit systems. - static_assert(2*sizeof(int) >= 8, "XDR handling assumes that an int64_t can be stored in two ints"); - int imaj, imin; - int ret; + static_assert(2 * sizeof(int) >= 8, + "XDR handling assumes that an int64_t can be stored in two ints"); + int imaj, imin; + int ret; static const int64_t two_p32_m1 = 0xFFFFFFFF; int64_t imaj64, imin64; - imaj64 = ((*i)>>32) & two_p32_m1; + imaj64 = ((*i) >> 32) & two_p32_m1; imin64 = (*i) & two_p32_m1; imaj = static_cast(imaj64); imin = static_cast(imin64); ret = xdr_int(xdrs, &imaj); - ret |= xdr_int(xdrs, &imin); + ret |= xdr_int(xdrs, &imin); *i = ((static_cast(imaj) << 32) | (static_cast(imin) & two_p32_m1)); diff --git a/src/gromacs/fileio/xdrf.h b/src/gromacs/fileio/xdrf.h index dab6069031..fd83e5e735 100644 --- a/src/gromacs/fileio/xdrf.h +++ b/src/gromacs/fileio/xdrf.h @@ -42,46 +42,46 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -#ifdef __PGI /*Portland group compiler*/ -#define int64_t long long +#ifdef __PGI /*Portland group compiler*/ +# define int64_t long long #endif #include "config.h" #if GMX_INTERNAL_XDR -#include "gromacs/fileio/gmx_internal_xdr.h" +# include "gromacs/fileio/gmx_internal_xdr.h" #else -#include -#include +# include +# include #endif /* Read or write reduced precision *float* coordinates */ -int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision); +int xdr3dfcoord(XDR* xdrs, float* fp, int* size, float* precision); /* Read or write a *real* value (stored as float) */ -int xdr_real(XDR *xdrs, real *r); +int xdr_real(XDR* xdrs, real* r); /* Read or write reduced precision *real* coordinates */ -int xdr3drcoord(XDR *xdrs, real *fp, int *size, real *precision); +int xdr3drcoord(XDR* xdrs, real* fp, int* size, real* precision); //! Read or write a int32_t value. -int xdr_int32(XDR *xdrs, int32_t *i); +int xdr_int32(XDR* xdrs, int32_t* i); //! Read or write a int64_t value. -int xdr_int64(XDR *xdrs, int64_t *i); +int xdr_int64(XDR* xdrs, int64_t* i); -int xdr_xtc_seek_time(real time, FILE *fp, XDR *xdrs, int natoms, gmx_bool bSeekForwardOnly); +int xdr_xtc_seek_time(real time, FILE* fp, XDR* xdrs, int natoms, gmx_bool bSeekForwardOnly); -int xdr_xtc_seek_frame(int frame, FILE *fp, XDR *xdrs, int natoms); +int xdr_xtc_seek_frame(int frame, FILE* fp, XDR* xdrs, int natoms); -float xdr_xtc_get_last_frame_time(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK); +float xdr_xtc_get_last_frame_time(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK); -int xdr_xtc_get_last_frame_number(FILE *fp, XDR *xdrs, int natoms, gmx_bool * bOK); +int xdr_xtc_get_last_frame_number(FILE* fp, XDR* xdrs, int natoms, gmx_bool* bOK); #endif diff --git a/src/gromacs/fileio/xtcio.cpp b/src/gromacs/fileio/xtcio.cpp index 09f0d8cab7..35c77deba6 100644 --- a/src/gromacs/fileio/xtcio.cpp +++ b/src/gromacs/fileio/xtcio.cpp @@ -51,7 +51,7 @@ #define XTC_MAGIC 1995 -static int xdr_r2f(XDR *xdrs, real *r, gmx_bool gmx_unused bRead) +static int xdr_r2f(XDR* xdrs, real* r, gmx_bool gmx_unused bRead) { #if GMX_DOUBLE float f; @@ -69,17 +69,17 @@ static int xdr_r2f(XDR *xdrs, real *r, gmx_bool gmx_unused bRead) return ret; #else - return xdr_float(xdrs, static_cast(r)); + return xdr_float(xdrs, static_cast(r)); #endif } -t_fileio *open_xtc(const char *fn, const char *mode) +t_fileio* open_xtc(const char* fn, const char* mode) { return gmx_fio_open(fn, mode); } -void close_xtc(t_fileio *fio) +void close_xtc(t_fileio* fio) { gmx_fio_close(fio); } @@ -88,19 +88,20 @@ static void check_xtc_magic(int magic) { if (magic != XTC_MAGIC) { - gmx_fatal(FARGS, "Magic Number Error in XTC file (read %d, should be %d)", - magic, XTC_MAGIC); + gmx_fatal(FARGS, "Magic Number Error in XTC file (read %d, should be %d)", magic, XTC_MAGIC); } } -static int xtc_check(const char *str, gmx_bool bResult, const char *file, int line) +static int xtc_check(const char* str, gmx_bool bResult, const char* file, int line) { if (!bResult) { if (debug) { - fprintf(debug, "\nXTC error: read/write of %s failed, " - "source file %s, line %d\n", str, file, line); + fprintf(debug, + "\nXTC error: read/write of %s failed, " + "source file %s, line %d\n", + str, file, line); } return 0; } @@ -109,8 +110,7 @@ static int xtc_check(const char *str, gmx_bool bResult, const char *file, int li #define XTC_CHECK(s, b) xtc_check(s, b, __FILE__, __LINE__) -static int xtc_header(XDR *xd, int *magic, int *natoms, int64_t *step, real *time, - gmx_bool bRead, gmx_bool *bOK) +static int xtc_header(XDR* xd, int* magic, int* natoms, int64_t* step, real* time, gmx_bool bRead, gmx_bool* bOK) { int result; @@ -125,23 +125,23 @@ static int xtc_header(XDR *xd, int *magic, int *natoms, int64_t *step, real *tim * fix the fact that we used xdr_int for the step number, * which is defined to be signed and 32 bit. */ int intStep = *step; - result = XTC_CHECK("step", xdr_int(xd, &intStep)); /* frame number */ - *step = intStep; + result = XTC_CHECK("step", xdr_int(xd, &intStep)); /* frame number */ + *step = intStep; } if (result) { - result = XTC_CHECK("time", xdr_r2f(xd, time, bRead)); /* time */ + result = XTC_CHECK("time", xdr_r2f(xd, time, bRead)); /* time */ } *bOK = (result != 0); return result; } -static int xtc_coord(XDR *xd, int *natoms, rvec *box, rvec *x, real *prec, gmx_bool bRead) +static int xtc_coord(XDR* xd, int* natoms, rvec* box, rvec* x, real* prec, gmx_bool bRead) { - int i, j, result; + int i, j, result; #if GMX_DOUBLE - float *ftmp; + float* ftmp; float fprec; #endif @@ -162,16 +162,16 @@ static int xtc_coord(XDR *xd, int *natoms, rvec *box, rvec *x, real *prec, gmx_b #if GMX_DOUBLE /* allocate temp. single-precision array */ - snew(ftmp, (*natoms)*DIM); + snew(ftmp, (*natoms) * DIM); /* Copy data to temp. array if writing */ if (!bRead) { for (i = 0; (i < *natoms); i++) { - ftmp[DIM*i+XX] = x[i][XX]; - ftmp[DIM*i+YY] = x[i][YY]; - ftmp[DIM*i+ZZ] = x[i][ZZ]; + ftmp[DIM * i + XX] = x[i][XX]; + ftmp[DIM * i + YY] = x[i][YY]; + ftmp[DIM * i + ZZ] = x[i][ZZ]; } fprec = *prec; } @@ -182,9 +182,9 @@ static int xtc_coord(XDR *xd, int *natoms, rvec *box, rvec *x, real *prec, gmx_b { for (i = 0; (i < *natoms); i++) { - x[i][XX] = ftmp[DIM*i+XX]; - x[i][YY] = ftmp[DIM*i+YY]; - x[i][ZZ] = ftmp[DIM*i+ZZ]; + x[i][XX] = ftmp[DIM * i + XX]; + x[i][YY] = ftmp[DIM * i + YY]; + x[i][ZZ] = ftmp[DIM * i + ZZ]; } *prec = fprec; } @@ -197,13 +197,10 @@ static int xtc_coord(XDR *xd, int *natoms, rvec *box, rvec *x, real *prec, gmx_b } - -int write_xtc(t_fileio *fio, - int natoms, int64_t step, real time, - const rvec *box, const rvec *x, real prec) +int write_xtc(t_fileio* fio, int natoms, int64_t step, real time, const rvec* box, const rvec* x, real prec) { int magic_number = XTC_MAGIC; - XDR *xd; + XDR* xd; gmx_bool bDum; int bOK; @@ -223,7 +220,8 @@ int write_xtc(t_fileio *fio, } /* write data */ - bOK = xtc_coord(xd, &natoms, const_cast(box), const_cast(x), &prec, FALSE); /* bOK will be 1 if writing went well */ + bOK = xtc_coord(xd, &natoms, const_cast(box), const_cast(x), &prec, + FALSE); /* bOK will be 1 if writing went well */ if (bOK) { @@ -235,11 +233,10 @@ int write_xtc(t_fileio *fio, return bOK; /* 0 if bad, 1 if writing went well */ } -int read_first_xtc(t_fileio *fio, int *natoms, int64_t *step, real *time, - matrix box, rvec **x, real *prec, gmx_bool *bOK) +int read_first_xtc(t_fileio* fio, int* natoms, int64_t* step, real* time, matrix box, rvec** x, real* prec, gmx_bool* bOK) { int magic; - XDR *xd; + XDR* xd; *bOK = TRUE; xd = gmx_fio_getxdr(fio); @@ -260,13 +257,11 @@ int read_first_xtc(t_fileio *fio, int *natoms, int64_t *step, real *time, return static_cast(*bOK); } -int read_next_xtc(t_fileio* fio, - int natoms, int64_t *step, real *time, - matrix box, rvec *x, real *prec, gmx_bool *bOK) +int read_next_xtc(t_fileio* fio, int natoms, int64_t* step, real* time, matrix box, rvec* x, real* prec, gmx_bool* bOK) { int magic; int n; - XDR *xd; + XDR* xd; *bOK = TRUE; xd = gmx_fio_getxdr(fio); @@ -282,8 +277,7 @@ int read_next_xtc(t_fileio* fio, if (n > natoms) { - gmx_fatal(FARGS, "Frame contains more atoms (%d) than expected (%d)", - n, natoms); + gmx_fatal(FARGS, "Frame contains more atoms (%d) than expected (%d)", n, natoms); } *bOK = (xtc_coord(xd, &natoms, box, x, prec, TRUE) != 0); diff --git a/src/gromacs/fileio/xtcio.h b/src/gromacs/fileio/xtcio.h index af10cf522b..db206a904a 100644 --- a/src/gromacs/fileio/xtcio.h +++ b/src/gromacs/fileio/xtcio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,25 +55,26 @@ struct t_fileio; * negative. Fortunately, this tends not to cause serious problems, * and we've fixed it in TNG. */ -struct t_fileio *open_xtc(const char *filename, const char *mode); +struct t_fileio* open_xtc(const char* filename, const char* mode); /* Open a file for xdr I/O */ -void close_xtc(struct t_fileio *fio); +void close_xtc(struct t_fileio* fio); /* Close the file for xdr I/O */ -int read_first_xtc(struct t_fileio *fio, - int *natoms, int64_t *step, real *time, - matrix box, rvec **x, real *prec, gmx_bool *bOK); +int read_first_xtc(struct t_fileio* fio, + int* natoms, + int64_t* step, + real* time, + matrix box, + rvec** x, + real* prec, + gmx_bool* bOK); /* Open xtc file, read xtc file first time, allocate memory for x */ -int read_next_xtc(struct t_fileio *fio, - int natoms, int64_t *step, real *time, - matrix box, rvec *x, real *prec, gmx_bool *bOK); +int read_next_xtc(struct t_fileio* fio, int natoms, int64_t* step, real* time, matrix box, rvec* x, real* prec, gmx_bool* bOK); /* Read subsequent frames */ -int write_xtc(struct t_fileio *fio, - int natoms, int64_t step, real time, - const rvec *box, const rvec *x, real prec); +int write_xtc(struct t_fileio* fio, int natoms, int64_t step, real time, const rvec* box, const rvec* x, real prec); /* Write a frame to xtc file */ #endif diff --git a/src/gromacs/fileio/xvgr.cpp b/src/gromacs/fileio/xvgr.cpp index 86deb57401..55764b0362 100644 --- a/src/gromacs/fileio/xvgr.cpp +++ b/src/gromacs/fileio/xvgr.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,7 +56,7 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/sysinfo.h" -gmx_bool output_env_get_print_xvgr_codes(const gmx_output_env_t *oenv) +gmx_bool output_env_get_print_xvgr_codes(const gmx_output_env_t* oenv) { int xvg_format; @@ -65,12 +65,12 @@ gmx_bool output_env_get_print_xvgr_codes(const gmx_output_env_t *oenv) return (xvg_format == exvgXMGRACE || xvg_format == exvgXMGR); } -static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, - char *buf, int buflen) +static char* xvgrstr(const std::string& gmx, const gmx_output_env_t* oenv, char* buf, int buflen) { /* Supported greek letter names and corresponding xmgrace/xmgr symbols */ - const char *sym[] = { "beta", "chi", "delta", "eta", "lambda", "mu", "omega", "phi", "psi", "rho", "theta", nullptr }; - const char symc[] = { 'b', 'c', 'd', 'h', 'l', 'm', 'w', 'f', 'y', 'r', 'q', '\0' }; + const char* sym[] = { "beta", "chi", "delta", "eta", "lambda", "mu", + "omega", "phi", "psi", "rho", "theta", nullptr }; + const char symc[] = { 'b', 'c', 'd', 'h', 'l', 'm', 'w', 'f', 'y', 'r', 'q', '\0' }; int xvgf; gmx_bool bXVGR; int g, b, i; @@ -86,7 +86,10 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, /* Check with the largest string we have ("lambda"), add one for \0 */ if (b + 6 + 1 >= buflen) { - gmx_fatal(FARGS, "Output buffer length in xvgstr (%d) too small to process xvg input string '%s'", buflen, gmx.c_str()); + gmx_fatal(FARGS, + "Output buffer length in xvgstr (%d) too small to process xvg input string " + "'%s'", + buflen, gmx.c_str()); } if (gmx[g] == '\\') { @@ -129,7 +132,7 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, } else { - if (gmx[g+1] != ' ') + if (gmx[g + 1] != ' ') { buf[b++] = ' '; } @@ -141,15 +144,9 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, /* Backward compatibility for xmgr normal font "\4" */ switch (xvgf) { - case exvgXMGRACE: - sprintf(buf+b, "%s", "\\f{}"); - break; - case exvgXMGR: - sprintf(buf+b, "%s", "\\4"); - break; - default: - buf[b] = '\0'; - break; + case exvgXMGRACE: sprintf(buf + b, "%s", "\\f{}"); break; + case exvgXMGR: sprintf(buf + b, "%s", "\\4"); break; + default: buf[b] = '\0'; break; } g++; b = strlen(buf); @@ -159,15 +156,9 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, /* Backward compatibility for xmgr symbol font "\8" */ switch (xvgf) { - case exvgXMGRACE: - sprintf(buf+b, "%s", "\\x"); - break; - case exvgXMGR: - sprintf(buf+b, "%s", "\\8"); - break; - default: - buf[b] = '\0'; - break; + case exvgXMGRACE: sprintf(buf + b, "%s", "\\x"); break; + case exvgXMGR: sprintf(buf + b, "%s", "\\8"); break; + default: buf[b] = '\0'; break; } g++; b = std::strlen(buf); @@ -176,8 +167,7 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, { /* Check for special symbol */ i = 0; - while (sym[i] != nullptr && - gmx_strncasecmp(sym[i], &gmx[g], std::strlen(sym[i])) != 0) + while (sym[i] != nullptr && gmx_strncasecmp(sym[i], &gmx[g], std::strlen(sym[i])) != 0) { i++; } @@ -190,16 +180,12 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, } switch (xvgf) { - case exvgXMGRACE: - sprintf(buf+b, "%s%c%s", "\\x", c, "\\f{}"); - break; - case exvgXMGR: - sprintf(buf+b, "%s%c%s", "\\8", c, "\\4"); - break; + case exvgXMGRACE: sprintf(buf + b, "%s%c%s", "\\x", c, "\\f{}"); break; + case exvgXMGR: sprintf(buf + b, "%s%c%s", "\\8", c, "\\4"); break; default: - std::strncat(buf+b, &gmx[g], std::strlen(sym[i])); + std::strncat(buf + b, &gmx[g], std::strlen(sym[i])); b += std::strlen(sym[i]); - if (gmx[g+std::strlen(sym[i])] != ' ') + if (gmx[g + std::strlen(sym[i])] != ' ') { buf[b++] = ' '; } @@ -207,7 +193,7 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, break; } g += std::strlen(sym[i]); - b = std::strlen(buf); + b = std::strlen(buf); } else { @@ -231,9 +217,12 @@ static char *xvgrstr(const std::string &gmx, const gmx_output_env_t *oenv, return buf; } -void xvgr_header(FILE *fp, const char *title, const std::string &xaxis, - const std::string &yaxis, int exvg_graph_type, - const gmx_output_env_t *oenv) +void xvgr_header(FILE* fp, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + int exvg_graph_type, + const gmx_output_env_t* oenv) { char buf[STRLEN]; @@ -245,18 +234,14 @@ void xvgr_header(FILE *fp, const char *title, const std::string &xaxis, gmx::BinaryInformationSettings settings; settings.generatedByHeader(true); settings.linePrefix("# "); - gmx::printBinaryInformation(fp, output_env_get_program_context(oenv), - settings); + gmx::printBinaryInformation(fp, output_env_get_program_context(oenv), settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; - fprintf(fp, "# %s is part of G R O M A C S:\n#\n", - output_env_get_program_display_name(oenv)); + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR + fprintf(fp, "# %s is part of G R O M A C S:\n#\n", output_env_get_program_display_name(oenv)); fprintf(fp, "# %s\n#\n", gmx::bromacs().c_str()); fprintf(fp, "@ title \"%s\"\n", xvgrstr(title, oenv, buf, STRLEN)); - fprintf(fp, "@ xaxis label \"%s\"\n", - xvgrstr(xaxis, oenv, buf, STRLEN)); - fprintf(fp, "@ yaxis label \"%s\"\n", - xvgrstr(yaxis, oenv, buf, STRLEN)); + fprintf(fp, "@ xaxis label \"%s\"\n", xvgrstr(xaxis, oenv, buf, STRLEN)); + fprintf(fp, "@ yaxis label \"%s\"\n", xvgrstr(yaxis, oenv, buf, STRLEN)); switch (exvg_graph_type) { case exvggtXNY: @@ -269,21 +254,20 @@ void xvgr_header(FILE *fp, const char *title, const std::string &xaxis, fprintf(fp, "@TYPE xy\n"); } break; - case exvggtXYDY: - fprintf(fp, "@TYPE xydy\n"); - break; - case exvggtXYDYDY: - fprintf(fp, "@TYPE xydydy\n"); - break; + case exvggtXYDY: fprintf(fp, "@TYPE xydy\n"); break; + case exvggtXYDYDY: fprintf(fp, "@TYPE xydydy\n"); break; } } } -FILE *xvgropen_type(const char *fn, const char *title, const std::string &xaxis, - const std::string &yaxis, int exvg_graph_type, - const gmx_output_env_t *oenv) +FILE* xvgropen_type(const char* fn, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + int exvg_graph_type, + const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; fp = gmx_fio_fopen(fn, "w"); @@ -292,19 +276,21 @@ FILE *xvgropen_type(const char *fn, const char *title, const std::string &xaxis, return fp; } -FILE *xvgropen(const char *fn, const char *title, const std::string &xaxis, - const std::string &yaxis, const gmx_output_env_t *oenv) +FILE* xvgropen(const char* fn, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + const gmx_output_env_t* oenv) { return xvgropen_type(fn, title, xaxis, yaxis, exvggtXNY, oenv); } -void -xvgrclose(FILE *fp) +void xvgrclose(FILE* fp) { gmx_fio_fclose(fp); } -void xvgr_subtitle(FILE *out, const char *subtitle, const gmx_output_env_t *oenv) +void xvgr_subtitle(FILE* out, const char* subtitle, const gmx_output_env_t* oenv) { char buf[STRLEN]; @@ -314,8 +300,7 @@ void xvgr_subtitle(FILE *out, const char *subtitle, const gmx_output_env_t *oenv } } -void xvgr_view(FILE *out, real xmin, real ymin, real xmax, real ymax, - const gmx_output_env_t *oenv) +void xvgr_view(FILE* out, real xmin, real ymin, real xmax, real ymax, const gmx_output_env_t* oenv) { if (output_env_get_print_xvgr_codes(oenv)) { @@ -323,31 +308,31 @@ void xvgr_view(FILE *out, real xmin, real ymin, real xmax, real ymax, } } -void xvgr_world(FILE *out, real xmin, real ymin, real xmax, real ymax, - const gmx_output_env_t *oenv) +void xvgr_world(FILE* out, real xmin, real ymin, real xmax, real ymax, const gmx_output_env_t* oenv) { if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(out, "@ world xmin %g\n" + fprintf(out, + "@ world xmin %g\n" "@ world ymin %g\n" "@ world xmax %g\n" - "@ world ymax %g\n", xmin, ymin, xmax, ymax); + "@ world ymax %g\n", + xmin, ymin, xmax, ymax); } } -static bool stringIsEmpty(const std::string &s) +static bool stringIsEmpty(const std::string& s) { return s.empty(); } -static bool stringIsEmpty(const char *s) +static bool stringIsEmpty(const char* s) { return (s == nullptr || s[0] == '\0'); } -template -static void xvgr_legend(FILE *out, int nsets, const T * setname, - const gmx_output_env_t *oenv) +template +static void xvgr_legend(FILE* out, int nsets, const T* setname, const gmx_output_env_t* oenv) { int i; char buf[STRLEN]; @@ -366,34 +351,27 @@ static void xvgr_legend(FILE *out, int nsets, const T * setname, { if (output_env_get_xvg_format(oenv) == exvgXMGR) { - fprintf(out, "@ legend string %d \"%s\"\n", - i, xvgrstr(setname[i], oenv, buf, STRLEN)); + fprintf(out, "@ legend string %d \"%s\"\n", i, xvgrstr(setname[i], oenv, buf, STRLEN)); } else { - fprintf(out, "@ s%d legend \"%s\"\n", - i, xvgrstr(setname[i], oenv, buf, STRLEN)); + fprintf(out, "@ s%d legend \"%s\"\n", i, xvgrstr(setname[i], oenv, buf, STRLEN)); } } } } } -void xvgrLegend(FILE *out, - const std::vector &setNames, - const struct gmx_output_env_t *oenv) +void xvgrLegend(FILE* out, const std::vector& setNames, const struct gmx_output_env_t* oenv) { xvgr_legend(out, setNames.size(), setNames.data(), oenv); } -void xvgr_legend(FILE *out, int nsets, const char*const* setnames, - const struct gmx_output_env_t *oenv) +void xvgr_legend(FILE* out, int nsets, const char* const* setnames, const struct gmx_output_env_t* oenv) { - xvgr_legend(out, nsets, setnames, oenv); + xvgr_legend(out, nsets, setnames, oenv); } -void xvgr_new_dataset(FILE *out, int nr_first, int nsets, - const char **setname, - const gmx_output_env_t *oenv) +void xvgr_new_dataset(FILE* out, int nr_first, int nsets, const char** setname, const gmx_output_env_t* oenv) { int i; char buf[STRLEN]; @@ -407,13 +385,13 @@ void xvgr_new_dataset(FILE *out, int nr_first, int nsets, { if (output_env_get_xvg_format(oenv) == exvgXMGR) { - fprintf(out, "@ legend string %d \"%s\"\n", - i+nr_first, xvgrstr(setname[i], oenv, buf, STRLEN)); + fprintf(out, "@ legend string %d \"%s\"\n", i + nr_first, + xvgrstr(setname[i], oenv, buf, STRLEN)); } else { - fprintf(out, "@ s%d legend \"%s\"\n", - i+nr_first, xvgrstr(setname[i], oenv, buf, STRLEN)); + fprintf(out, "@ s%d legend \"%s\"\n", i + nr_first, + xvgrstr(setname[i], oenv, buf, STRLEN)); } } } @@ -424,8 +402,7 @@ void xvgr_new_dataset(FILE *out, int nr_first, int nsets, } } -void xvgr_line_props(FILE *out, int NrSet, int LineStyle, int LineColor, - const gmx_output_env_t *oenv) +void xvgr_line_props(FILE* out, int NrSet, int LineStyle, int LineColor, const gmx_output_env_t* oenv) { if (output_env_get_print_xvgr_codes(oenv)) { @@ -435,14 +412,22 @@ void xvgr_line_props(FILE *out, int NrSet, int LineStyle, int LineColor, } } -static const char *LocTypeStr[] = { "view", "world" }; -static const char *BoxFillStr[] = { "none", "color", "pattern" }; - -void xvgr_box(FILE *out, - int LocType, - real xmin, real ymin, real xmax, real ymax, - int LineStyle, int LineWidth, int LineColor, - int BoxFill, int BoxColor, int BoxPattern, const gmx_output_env_t *oenv) +static const char* LocTypeStr[] = { "view", "world" }; +static const char* BoxFillStr[] = { "none", "color", "pattern" }; + +void xvgr_box(FILE* out, + int LocType, + real xmin, + real ymin, + real xmax, + real ymax, + int LineStyle, + int LineWidth, + int LineColor, + int BoxFill, + int BoxColor, + int BoxPattern, + const gmx_output_env_t* oenv) { if (output_env_get_print_xvgr_codes(oenv)) { @@ -461,10 +446,10 @@ void xvgr_box(FILE *out, } /* reads a line into ptr, adjusting len and renewing ptr if neccesary */ -static char *fgets3(FILE *fp, char **ptr, int *len, int maxlen) +static char* fgets3(FILE* fp, char** ptr, int* len, int maxlen) { - int len_remaining = *len; /* remaining amount of allocated bytes in buf */ - int curp = 0; /* current position in buf to read into */ + int len_remaining = *len; /* remaining amount of allocated bytes in buf */ + int curp = 0; /* current position in buf to read into */ do { @@ -473,7 +458,7 @@ static char *fgets3(FILE *fp, char **ptr, int *len, int maxlen) if (*len + STRLEN < maxlen) { /* This line is longer than len characters, let's increase len! */ - *len += STRLEN; + *len += STRLEN; len_remaining += STRLEN; srenew(*ptr, *len); } @@ -489,10 +474,9 @@ static char *fgets3(FILE *fp, char **ptr, int *len, int maxlen) /* if last line, skip */ return nullptr; } - curp += len_remaining-1; /* overwrite the nul char in next iteration */ + curp += len_remaining - 1; /* overwrite the nul char in next iteration */ len_remaining = 1; - } - while ((std::strchr(*ptr, '\n') == nullptr) && (feof(fp) == 0)); + } while ((std::strchr(*ptr, '\n') == nullptr) && (feof(fp) == 0)); if (*len + STRLEN >= maxlen) { @@ -507,20 +491,20 @@ static char *fgets3(FILE *fp, char **ptr, int *len, int maxlen) { /* now remove newline */ int slen = std::strlen(*ptr); - if ((*ptr)[slen-1] == '\n') + if ((*ptr)[slen - 1] == '\n') { - (*ptr)[slen-1] = '\0'; + (*ptr)[slen - 1] = '\0'; } } return *ptr; } -static int wordcount(char *ptr) +static int wordcount(char* ptr) { int i, n = 0, is[2]; int cur = 0; -#define prev (1-cur) +#define prev (1 - cur) if (nullptr != ptr) { @@ -531,7 +515,7 @@ static int wordcount(char *ptr) { n++; } - else if ((i > 0) && (!is[cur] && is[prev])) + else if ((i > 0) && (!is[cur] && is[prev])) { n++; } @@ -541,10 +525,10 @@ static int wordcount(char *ptr) return n; } -static char *read_xvgr_string(const char *line) +static char* read_xvgr_string(const char* line) { const char *ptr0, *ptr1; - char *str; + char* str; ptr0 = std::strchr(line, '"'); if (ptr0 != nullptr) @@ -553,8 +537,8 @@ static char *read_xvgr_string(const char *line) ptr1 = std::strchr(ptr0, '"'); if (ptr1 != nullptr) { - str = gmx_strdup(ptr0); - str[ptr1-ptr0] = '\0'; + str = gmx_strdup(ptr0); + str[ptr1 - ptr0] = '\0'; } else { @@ -569,23 +553,22 @@ static char *read_xvgr_string(const char *line) return str; } -int read_xvg_legend(const char *fn, double ***y, int *ny, - char **subtitle, char ***legend) +int read_xvg_legend(const char* fn, double*** y, int* ny, char** subtitle, char*** legend) { - FILE *fp; - char *ptr; - char *base = nullptr; - char *fmt = nullptr; + FILE* fp; + char* ptr; + char* base = nullptr; + char* fmt = nullptr; int k, line = 0, nny, nx, maxx, rval, legend_nalloc, set, nchar; double lf; - double **yy = nullptr; - char *tmpbuf; + double** yy = nullptr; + char* tmpbuf; int len = STRLEN; - *ny = 0; - nny = 0; - nx = 0; - maxx = 0; - fp = gmx_fio_fopen(fn, "r"); + *ny = 0; + nny = 0; + nx = 0; + maxx = 0; + fp = gmx_fio_fopen(fn, "r"); snew(tmpbuf, len); if (subtitle != nullptr) @@ -598,7 +581,7 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, *legend = nullptr; } - while ((ptr = fgets3(fp, &tmpbuf, &len, 10*STRLEN)) != nullptr && ptr[0] != '&') + while ((ptr = fgets3(fp, &tmpbuf, &len, 10 * STRLEN)) != nullptr && ptr[0] != '&') { line++; trim(ptr); @@ -660,8 +643,8 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, return 0; } snew(yy, nny); - snew(fmt, 3*nny+1); - snew(base, 3*nny+1); + snew(fmt, 3 * nny + 1); + snew(base, 3 * nny + 1); } /* Allocate column space */ if (nx >= maxx) @@ -688,14 +671,13 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, break; } yy[k][nx] = lf; - srenew(fmt, 3*(nny+1)+1); - srenew(base, 3*nny+1); + srenew(fmt, 3 * (nny + 1) + 1); + srenew(base, 3 * nny + 1); std::strcat(base, "%*s"); } if (k != nny) { - fprintf(stderr, "Only %d columns on line %d in file %s\n", - k, line, fn); + fprintf(stderr, "Only %d columns on line %d in file %s\n", k, line, fn); for (; (k < nny); k++) { yy[k][nx] = 0.0; @@ -716,8 +698,8 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, if (*ny - 1 > legend_nalloc) { assert(legend); - srenew(*legend, *ny-1); - for (set = legend_nalloc; set < *ny-1; set++) + srenew(*legend, *ny - 1); + for (set = legend_nalloc; set < *ny - 1; set++) { (*legend)[set] = nullptr; } @@ -727,21 +709,20 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, return nx; } -int read_xvg(const char *fn, double ***y, int *ny) +int read_xvg(const char* fn, double*** y, int* ny) { return read_xvg_legend(fn, y, ny, nullptr, nullptr); } -void write_xvg(const char *fn, const char *title, int nx, int ny, real **y, - const char **leg, const gmx_output_env_t *oenv) +void write_xvg(const char* fn, const char* title, int nx, int ny, real** y, const char** leg, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; int i, j; fp = xvgropen(fn, title, "X", "Y", oenv); if (leg) { - xvgr_legend(fp, ny-1, leg, oenv); + xvgr_legend(fp, ny - 1, leg, oenv); } for (i = 0; (i < nx); i++) { @@ -754,18 +735,26 @@ void write_xvg(const char *fn, const char *title, int nx, int ny, real **y, xvgrclose(fp); } -real **read_xvg_time(const char *fn, - gmx_bool bHaveT, gmx_bool bTB, real tb, gmx_bool bTE, real te, - int nsets_in, int *nset, int *nval, real *dt, real **t) +real** read_xvg_time(const char* fn, + gmx_bool bHaveT, + gmx_bool bTB, + real tb, + gmx_bool bTE, + real te, + int nsets_in, + int* nset, + int* nval, + real* dt, + real** t) { - FILE *fp; + FILE* fp; #define MAXLINELEN 16384 - char line0[MAXLINELEN]; - char *line; - int t_nalloc, *val_nalloc, a, narg, n, sin, set, nchar; - double dbl; - gmx_bool bEndOfSet, bTimeInRange, bFirstLine = TRUE; - real **val; + char line0[MAXLINELEN]; + char* line; + int t_nalloc, *val_nalloc, a, narg, n, sin, set, nchar; + double dbl; + gmx_bool bEndOfSet, bTimeInRange, bFirstLine = TRUE; + real** val; t_nalloc = 0; *t = nullptr; @@ -807,7 +796,8 @@ real **read_xvg_time(const char *fn, } else if (a == 1) { - fprintf(stderr, "Found only 1 number on line, " + fprintf(stderr, + "Found only 1 number on line, " "assuming no time is present.\n"); bHaveT = FALSE; if (nsets_in > 1) @@ -819,8 +809,8 @@ real **read_xvg_time(const char *fn, a = 0; bTimeInRange = TRUE; - while ((a < narg || (nsets_in == 1 && n == 0)) && - sscanf(line, "%lf%n", &dbl, &nchar) == 1 && bTimeInRange) + while ((a < narg || (nsets_in == 1 && n == 0)) + && sscanf(line, "%lf%n", &dbl, &nchar) == 1 && bTimeInRange) { /* Use set=-1 as the time "set" */ if (sin) @@ -842,7 +832,7 @@ real **read_xvg_time(const char *fn, } else { - set = a-1; + set = a - 1; } } if (set == -1 && ((bTB && dbl < tb) || (bTE && dbl > te))) @@ -860,7 +850,7 @@ real **read_xvg_time(const char *fn, } if (set >= 0) { - *nset = set+1; + *nset = set + 1; srenew(val, *nset); srenew(val_nalloc, *nset); val_nalloc[set] = 0; @@ -893,7 +883,7 @@ real **read_xvg_time(const char *fn, a++; line += nchar; } - if (line0[strlen(line0)-1] != '\n') + if (line0[strlen(line0) - 1] != '\n') { fprintf(stderr, "File %s does not end with a newline, ignoring the last line\n", fn); } @@ -907,9 +897,10 @@ real **read_xvg_time(const char *fn, { if (a != narg) { - fprintf(stderr, "Invalid line in %s:\n%s" + fprintf(stderr, + "Invalid line in %s:\n%s" "Using zeros for the last %d sets\n", - fn, line0, narg-a); + fn, line0, narg - a); } n++; } @@ -933,7 +924,7 @@ real **read_xvg_time(const char *fn, } if (n > 1) { - *dt = static_cast((*t)[n-1]-(*t)[0])/(n-1.0); + *dt = static_cast((*t)[n - 1] - (*t)[0]) / (n - 1.0); } else { @@ -944,11 +935,9 @@ real **read_xvg_time(const char *fn, { if (n < *nval) { - fprintf(stderr, "Set %d is shorter (%d) than the previous set (%d)\n", - sin+1, n, *nval); + fprintf(stderr, "Set %d is shorter (%d) than the previous set (%d)\n", sin + 1, n, *nval); *nval = n; - fprintf(stderr, "Will use only the first %d points of every set\n", - *nval); + fprintf(stderr, "Will use only the first %d points of every set\n", *nval); } } } diff --git a/src/gromacs/fileio/xvgr.h b/src/gromacs/fileio/xvgr.h index e95fc54342..f443ea14c0 100644 --- a/src/gromacs/fileio/xvgr.h +++ b/src/gromacs/fileio/xvgr.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,27 +50,55 @@ struct gmx_output_env_t; /*************************************************** * XVGR DEFINITIONS ***************************************************/ -enum { - elNone, elSolid, elDotted, elDashed, - elLongDashed, elDotDashed, elNR +enum +{ + elNone, + elSolid, + elDotted, + elDashed, + elLongDashed, + elDotDashed, + elNR }; /* xvgr line-styles */ -enum { - ecWhite, ecFrank, ecBlack = ecFrank, - ecRed, ecGreen, ecBlue, ecYellow, ecBrown, ecGray, - ecPurple, ecLightBlue, ecViolet, ecHolland, ecLila, ecDarkGray, - ecAquamarine, ecOlive, ecNR +enum +{ + ecWhite, + ecFrank, + ecBlack = ecFrank, + ecRed, + ecGreen, + ecBlue, + ecYellow, + ecBrown, + ecGray, + ecPurple, + ecLightBlue, + ecViolet, + ecHolland, + ecLila, + ecDarkGray, + ecAquamarine, + ecOlive, + ecNR }; /* xvgr line-colors */ -enum { - eppNone, eppColor, eppPattern, eppNR +enum +{ + eppNone, + eppColor, + eppPattern, + eppNR }; /* xvgr pattern type */ -enum { - evView, evWorld, evNR +enum +{ + evView, + evWorld, + evNR }; /* view type */ @@ -91,79 +119,90 @@ enum { * \4 : (deprecated) end symbol font */ -gmx_bool output_env_get_print_xvgr_codes(const struct gmx_output_env_t *oenv); +gmx_bool output_env_get_print_xvgr_codes(const struct gmx_output_env_t* oenv); /* Returns if we should print xmgrace or xmgr codes */ -enum { - exvggtNONE, exvggtXNY, exvggtXYDY, exvggtXYDYDY, exvggtNR +enum +{ + exvggtNONE, + exvggtXNY, + exvggtXYDY, + exvggtXYDYDY, + exvggtNR }; -void xvgr_header(FILE *fp, const char *title, const std::string &xaxis, - const std::string &yaxis, int exvg_graph_type, - const struct gmx_output_env_t *oenv); +void xvgr_header(FILE* fp, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + int exvg_graph_type, + const struct gmx_output_env_t* oenv); /* In most cases you want to use xvgropen_type, which does the same thing * but takes a filename and opens it. */ -FILE *xvgropen_type(const char *fn, const char *title, const std::string &xaxis, - const std::string &yaxis, int exvg_graph_type, - const struct gmx_output_env_t *oenv); +FILE* xvgropen_type(const char* fn, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + int exvg_graph_type, + const struct gmx_output_env_t* oenv); /* Open a file, and write a title, and axis-labels in Xvgr format * or write nothing when oenv specifies so. * The xvgr graph type enum is defined above. */ -FILE *xvgropen(const char *fn, const char *title, const std::string &xaxis, - const std::string &yaxis, const struct gmx_output_env_t *oenv); +FILE* xvgropen(const char* fn, + const char* title, + const std::string& xaxis, + const std::string& yaxis, + const struct gmx_output_env_t* oenv); /* Calls xvgropen_type with graph type xvggtXNY. */ /* Close xvgr file, and clean up internal file buffers correctly */ -void xvgrclose(FILE *fp); +void xvgrclose(FILE* fp); -void xvgr_subtitle(FILE *out, const char *subtitle, - const struct gmx_output_env_t *oenv); +void xvgr_subtitle(FILE* out, const char* subtitle, const struct gmx_output_env_t* oenv); /* Set the subtitle in xvgr */ -void xvgr_view(FILE *out, real xmin, real ymin, real xmax, real ymax, - const struct gmx_output_env_t *oenv); +void xvgr_view(FILE* out, real xmin, real ymin, real xmax, real ymax, const struct gmx_output_env_t* oenv); /* Set the view in xvgr */ -void xvgr_world(FILE *out, real xmin, real ymin, real xmax, real ymax, - const struct gmx_output_env_t *oenv); +void xvgr_world(FILE* out, real xmin, real ymin, real xmax, real ymax, const struct gmx_output_env_t* oenv); /* Set the world in xvgr */ -void xvgrLegend(FILE *out, - const std::vector &setNames, - const struct gmx_output_env_t *oenv); +void xvgrLegend(FILE* out, const std::vector& setNames, const struct gmx_output_env_t* oenv); /* Make a legend box, and also modifies the view to make room for the legend */ -void xvgr_legend(FILE *out, int nsets, const char*const* setnames, - const struct gmx_output_env_t *oenv); +void xvgr_legend(FILE* out, int nsets, const char* const* setnames, const struct gmx_output_env_t* oenv); /* Make a legend box, and also modifies the view to make room for the legend */ -void xvgr_new_dataset(FILE *out, - int nr_first, int nsets, const char **setnames, - const struct gmx_output_env_t *oenv); +void xvgr_new_dataset(FILE* out, int nr_first, int nsets, const char** setnames, const struct gmx_output_env_t* oenv); /* End the previous data set(s) and start new one(s). nr_first = the global set number of the first new set (or 0 if no legend) nsets = the number of sets (or 0 if no legends) setnames = the set names (or NULL if no legends) */ -void xvgr_line_props(FILE *out, int NrSet, int LineStyle, int LineColor, - const struct gmx_output_env_t *oenv); +void xvgr_line_props(FILE* out, int NrSet, int LineStyle, int LineColor, const struct gmx_output_env_t* oenv); /* Set xvgr line styles and colors */ -void xvgr_box(FILE *out, - int LocType, - real xmin, real ymin, real xmax, real ymax, - int LineStyle, int LineWidth, int LineColor, - int BoxFill, int BoxColor, int BoxPattern, - const struct gmx_output_env_t *oenv); +void xvgr_box(FILE* out, + int LocType, + real xmin, + real ymin, + real xmax, + real ymax, + int LineStyle, + int LineWidth, + int LineColor, + int BoxFill, + int BoxColor, + int BoxPattern, + const struct gmx_output_env_t* oenv); /* Make a box */ -int read_xvg_legend(const char *fn, double ***y, int *ny, - char **subtitle, char ***legend); +int read_xvg_legend(const char* fn, double*** y, int* ny, char** subtitle, char*** legend); /* Read an xvg file for post processing. The number of rows is returned * fn is the filename, y is a pointer to a 2D array (to be allocated by * the routine) ny is the number of columns (including X if appropriate). @@ -173,11 +212,16 @@ int read_xvg_legend(const char *fn, double ***y, int *ny, * 0 is the first y legend, the legend string will be NULL when not present. */ -int read_xvg(const char *fn, double ***y, int *ny); +int read_xvg(const char* fn, double*** y, int* ny); /* As read_xvg_legend, but does not read legends. */ -void write_xvg(const char *fn, const char *title, int nx, int ny, real **y, - const char** leg, const struct gmx_output_env_t *oenv); +void write_xvg(const char* fn, + const char* title, + int nx, + int ny, + real** y, + const char** leg, + const struct gmx_output_env_t* oenv); /* Write a two D array (y) of dimensions nx rows times * ny columns to a file. If leg != NULL it will be written too. */ @@ -186,10 +230,15 @@ void write_xvg(const char *fn, const char *title, int nx, int ny, real **y, /* This function reads ascii (xvg) files and extracts the data sets to a * two dimensional array which is returned. */ -real **read_xvg_time(const char *fn, - gmx_bool bHaveT, - gmx_bool bTB, real tb, - gmx_bool bTE, real te, - int nsets_in, int *nset, int *nval, - real *dt, real **t); +real** read_xvg_time(const char* fn, + gmx_bool bHaveT, + gmx_bool bTB, + real tb, + gmx_bool bTE, + real te, + int nsets_in, + int* nset, + int* nval, + real* dt, + real** t); #endif diff --git a/src/gromacs/gmxana/anadih.cpp b/src/gromacs/gmxana/anadih.cpp index 7b94925c0e..b76f99dc1a 100644 --- a/src/gromacs/gmxana/anadih.cpp +++ b/src/gromacs/gmxana/anadih.cpp @@ -55,11 +55,16 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -void print_one(const gmx_output_env_t *oenv, const char *base, const char *name, - const char *title, const char *ylabel, int nf, real time[], - real data[]) +void print_one(const gmx_output_env_t* oenv, + const char* base, + const char* name, + const char* title, + const char* ylabel, + int nf, + real time[], + real data[]) { - FILE *fp; + FILE* fp; char buf[256], t2[256]; int k; @@ -79,9 +84,9 @@ static int calc_RBbin(real phi, int gmx_unused multiplicity, real gmx_unused cor { /* multiplicity and core_frac NOT used, * just given to enable use of pt-to-fn in caller low_ana_dih_trans*/ - static const real r30 = M_PI/6.0; - static const real r90 = M_PI/2.0; - static const real r150 = M_PI*5.0/6.0; + static const real r30 = M_PI / 6.0; + static const real r90 = M_PI / 2.0; + static const real r150 = M_PI * 5.0 / 6.0; if ((phi < r30) && (phi > -r30)) { @@ -100,7 +105,7 @@ static int calc_RBbin(real phi, int gmx_unused multiplicity, real gmx_unused cor static int calc_Nbin(real phi, int multiplicity, real core_frac) { - static const real r360 = 360*DEG2RAD; + static const real r360 = 360 * DEG2RAD; real rot_width, core_width, core_offset, low, hi; int bin; /* with multiplicity 3 and core_frac 0.5 @@ -113,15 +118,15 @@ static int calc_Nbin(real phi, int multiplicity, real core_frac) phi += r360; } - rot_width = 360./multiplicity; + rot_width = 360. / multiplicity; core_width = core_frac * rot_width; - core_offset = (rot_width - core_width)/2.0; + core_offset = (rot_width - core_width) / 2.0; for (bin = 1; bin <= multiplicity; bin++) { - low = ((bin - 1) * rot_width ) + core_offset; - hi = ((bin - 1) * rot_width ) + core_offset + core_width; + low = ((bin - 1) * rot_width) + core_offset; + hi = ((bin - 1) * rot_width) + core_offset + core_width; low *= DEG2RAD; - hi *= DEG2RAD; + hi *= DEG2RAD; if ((phi > low) && (phi < hi)) { return bin; @@ -130,15 +135,20 @@ static int calc_Nbin(real phi, int multiplicity, real core_frac) return 0; } -void ana_dih_trans(const char *fn_trans, const char *fn_histo, - real **dih, int nframes, int nangles, - const char *grpname, real *time, gmx_bool bRb, - const gmx_output_env_t *oenv) +void ana_dih_trans(const char* fn_trans, + const char* fn_histo, + real** dih, + int nframes, + int nangles, + const char* grpname, + real* time, + gmx_bool bRb, + const gmx_output_env_t* oenv) { /* just a wrapper; declare extra args, then chuck away at end. */ int maxchi = 0; - t_dlist *dlist; - int *multiplicity; + t_dlist* dlist; + int* multiplicity; int nlist = nangles; int k; @@ -149,37 +159,45 @@ void ana_dih_trans(const char *fn_trans, const char *fn_histo, multiplicity[k] = 3; } - low_ana_dih_trans(TRUE, fn_trans, TRUE, fn_histo, maxchi, - dih, nlist, dlist, nframes, - nangles, grpname, multiplicity, time, bRb, 0.5, oenv); + low_ana_dih_trans(TRUE, fn_trans, TRUE, fn_histo, maxchi, dih, nlist, dlist, nframes, nangles, + grpname, multiplicity, time, bRb, 0.5, oenv); sfree(dlist); sfree(multiplicity); - } -void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, - gmx_bool bHisto, const char *fn_histo, int maxchi, - real **dih, int nlist, t_dlist dlist[], int nframes, - int nangles, const char *grpname, int multiplicity[], - real *time, gmx_bool bRb, real core_frac, - const gmx_output_env_t *oenv) +void low_ana_dih_trans(gmx_bool bTrans, + const char* fn_trans, + gmx_bool bHisto, + const char* fn_histo, + int maxchi, + real** dih, + int nlist, + t_dlist dlist[], + int nframes, + int nangles, + const char* grpname, + int multiplicity[], + real* time, + gmx_bool bRb, + real core_frac, + const gmx_output_env_t* oenv) { - FILE *fp; - int *tr_f, *tr_h; + FILE* fp; + int * tr_f, *tr_h; char title[256]; int i, j, k, Dih, ntrans; int cur_bin, new_bin; real ttime; - real *rot_occ[NROT]; - int (*calc_bin)(real, int, real); - real dt; + real* rot_occ[NROT]; + int (*calc_bin)(real, int, real); + real dt; if (1 <= nframes) { return; } /* Assumes the frames are equally spaced in time */ - dt = (time[nframes-1]-time[0])/(nframes-1); + dt = (time[nframes - 1] - time[0]) / (nframes - 1); /* Analysis of dihedral transitions */ fprintf(stderr, "Now calculating transitions...\n"); @@ -234,21 +252,21 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, } #else /* why is all this md rubbish periodic? Remove 360 degree periodicity */ - if ( (dih[i][j] - prev) > M_PI) + if ((dih[i][j] - prev) > M_PI) { - dih[i][j] -= 2*M_PI; + dih[i][j] -= 2 * M_PI; } - else if ( (dih[i][j] - prev) < -M_PI) + else if ((dih[i][j] - prev) < -M_PI) { - dih[i][j] += 2*M_PI; + dih[i][j] += 2 * M_PI; } prev = dih[i][j]; mind = std::min(mind, dih[i][j]); maxd = std::max(maxd, dih[i][j]); - if ( (maxd - mind) > 2*M_PI/3) /* or 120 degrees, assuming */ - { /* multiplicity 3. Not so general.*/ + if ((maxd - mind) > 2 * M_PI / 3) /* or 120 degrees, assuming */ + { /* multiplicity 3. Not so general.*/ tr_f[j]++; tr_h[i]++; maxd = mind = dih[i][j]; /* get ready for next transition */ @@ -264,7 +282,7 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, fprintf(stderr, "Total number of transitions: %10d\n", ntrans); if (ntrans > 0) { - ttime = (dt*nframes*nangles)/ntrans; + ttime = (dt * nframes * nangles) / ntrans; fprintf(stderr, "Time between transitions: %10.3f ps\n", ttime); } @@ -273,13 +291,12 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, * based on fn histogramming in g_chi. diff roles for i and j here */ j = 0; - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { for (i = 0; (i < nlist); i++) { - if (((Dih < edOmega) ) || - ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) || - ((Dih > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1))) + if (((Dih < edOmega)) || ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) + || ((Dih > edOmega) && (dlist[i].atm.Cn[Dih - NONCHI + 3] != -1))) { /* grs debug printf("Not OK? i %d j %d Dih %d \n", i, j, Dih) ; */ dlist[i].ntr[Dih] = tr_h[j]; @@ -315,21 +332,18 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, { tr_f[tr_h[i]]++; } - for (j = nframes; ((tr_f[j-1] == 0) && (j > 0)); j--) - { - ; - } + for (j = nframes; ((tr_f[j - 1] == 0) && (j > 0)); j--) {} - ttime = dt*nframes; + ttime = dt * nframes; if (bHisto) { sprintf(title, "Transition time: %s", grpname); fp = xvgropen(fn_histo, title, "Time (ps)", "#", oenv); - for (i = j-1; (i > 0); i--) + for (i = j - 1; (i > 0); i--) { if (tr_f[i] != 0) { - fprintf(fp, "%10.3f %10d\n", ttime/i, tr_f[i]); + fprintf(fp, "%10.3f %10d\n", ttime / i, tr_f[i]); } } xvgrclose(fp); @@ -341,11 +355,9 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, { sfree(rot_occ[k]); } - } -void mk_multiplicity_lookup (int *multiplicity, int maxchi, - int nlist, t_dlist dlist[], int nangles) +void mk_multiplicity_lookup(int* multiplicity, int maxchi, int nlist, t_dlist dlist[], int nangles) { /* new by grs - for dihedral j (as in dih[j]) get multiplicity from dlist * and store in multiplicity[j] @@ -355,15 +367,14 @@ void mk_multiplicity_lookup (int *multiplicity, int maxchi, char name[4]; j = 0; - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { for (i = 0; (i < nlist); i++) { std::strncpy(name, dlist[i].name, 3); name[3] = '\0'; - if (((Dih < edOmega) ) || - ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) || - ((Dih > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1))) + if (((Dih < edOmega)) || ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) + || ((Dih > edOmega) && (dlist[i].atm.Cn[Dih - NONCHI + 3] != -1))) { /* default - we will correct the rest below */ multiplicity[j] = 3; @@ -375,18 +386,18 @@ void mk_multiplicity_lookup (int *multiplicity, int maxchi, } /* dihedrals to aromatic rings, COO, CONH2 or guanidinium are 2fold*/ - if (Dih > edOmega && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1)) + if (Dih > edOmega && (dlist[i].atm.Cn[Dih - NONCHI + 3] != -1)) { - if ( ((std::strstr(name, "PHE") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "TYR") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "PTR") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "TRP") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "HIS") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "GLU") != nullptr) && (Dih == edChi3)) || - ((std::strstr(name, "ASP") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "GLN") != nullptr) && (Dih == edChi3)) || - ((std::strstr(name, "ASN") != nullptr) && (Dih == edChi2)) || - ((std::strstr(name, "ARG") != nullptr) && (Dih == edChi4)) ) + if (((std::strstr(name, "PHE") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "TYR") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "PTR") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "TRP") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "HIS") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "GLU") != nullptr) && (Dih == edChi3)) + || ((std::strstr(name, "ASP") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "GLN") != nullptr) && (Dih == edChi3)) + || ((std::strstr(name, "ASN") != nullptr) && (Dih == edChi2)) + || ((std::strstr(name, "ARG") != nullptr) && (Dih == edChi4))) { multiplicity[j] = 2; } @@ -397,19 +408,16 @@ void mk_multiplicity_lookup (int *multiplicity, int maxchi, } if (j < nangles) { - fprintf(stderr, "WARNING: not all dihedrals found in topology (only %d out of %d)!\n", - j, nangles); + fprintf(stderr, "WARNING: not all dihedrals found in topology (only %d out of %d)!\n", j, nangles); } /* Check for remaining dihedrals */ for (; (j < nangles); j++) { multiplicity[j] = 3; } - } -void mk_chi_lookup (int **lookup, int maxchi, - int nlist, t_dlist dlist[]) +void mk_chi_lookup(int** lookup, int maxchi, int nlist, t_dlist dlist[]) { /* by grs. should rewrite everything to use this. (but haven't, @@ -421,14 +429,13 @@ void mk_chi_lookup (int **lookup, int maxchi, j = 0; /* NONCHI points to chi1, therefore we have to start counting there. */ - for (Dih = NONCHI; (Dih < NONCHI+maxchi); Dih++) + for (Dih = NONCHI; (Dih < NONCHI + maxchi); Dih++) { for (i = 0; (i < nlist); i++) { Chi = Dih - NONCHI; - if (((Dih < edOmega) ) || - ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) || - ((Dih > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1))) + if (((Dih < edOmega)) || ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) + || ((Dih > edOmega) && (dlist[i].atm.Cn[Dih - NONCHI + 3] != -1))) { /* grs debug printf("Not OK? i %d j %d Dih %d \n", i, j, Dih) ; */ if (Dih > edOmega) @@ -443,26 +450,34 @@ void mk_chi_lookup (int **lookup, int maxchi, } } } - } -void get_chi_product_traj (real **dih, int nframes, int nlist, - int maxchi, t_dlist dlist[], real time[], - int **lookup, int *multiplicity, gmx_bool bRb, gmx_bool bNormalize, - real core_frac, gmx_bool bAll, const char *fnall, - const gmx_output_env_t *oenv) +void get_chi_product_traj(real** dih, + int nframes, + int nlist, + int maxchi, + t_dlist dlist[], + real time[], + int** lookup, + int* multiplicity, + gmx_bool bRb, + gmx_bool bNormalize, + real core_frac, + gmx_bool bAll, + const char* fnall, + const gmx_output_env_t* oenv) { gmx_bool bRotZero, bHaveChi = FALSE; int accum = 0, index, i, j, k, Xi, n, b; - real *chi_prtrj; - int *chi_prhist; + real* chi_prtrj; + int* chi_prhist; int nbin; - FILE *fp, *fpall; + FILE * fp, *fpall; char hisfile[256], histitle[256], *namept; - int (*calc_bin)(real, int, real); + int (*calc_bin)(real, int, real); /* Analysis of dihedral transitions */ fprintf(stderr, "Now calculating Chi product trajectories...\n"); @@ -499,7 +514,7 @@ void get_chi_product_traj (real **dih, int nframes, int nlist, if (index >= 0) { n = multiplicity[index]; - nbin = n*nbin; + nbin = n * nbin; } } nbin += 1; /* for the "zero rotamer", outside the core region */ @@ -546,9 +561,9 @@ void get_chi_product_traj (real **dih, int nframes, int nlist, else { chi_prtrj[j] = accum; - if (accum+1 > nbin) + if (accum + 1 > nbin) { - nbin = accum+1; + nbin = accum + 1; } } } @@ -581,7 +596,7 @@ void get_chi_product_traj (real **dih, int nframes, int nlist, { if (bNormalize) { - fprintf(fp, "%5d %10g\n", k, (1.0*chi_prhist[k])/nframes); + fprintf(fp, "%5d %10g\n", k, (1.0 * chi_prhist[k]) / nframes); } else { @@ -601,7 +616,7 @@ void get_chi_product_traj (real **dih, int nframes, int nlist, { if (bNormalize) { - fprintf(fpall, " %10g", (1.0*chi_prhist[k])/nframes); + fprintf(fpall, " %10g", (1.0 * chi_prhist[k]) / nframes); } else { @@ -618,12 +633,9 @@ void get_chi_product_traj (real **dih, int nframes, int nlist, sfree(chi_prtrj); xvgrclose(fpall); fprintf(stderr, "\n"); - } -void calc_distribution_props(int nh, const int histo[], real start, - int nkkk, t_karplus kkk[], - real *S2) +void calc_distribution_props(int nh, const int histo[], real start, int nkkk, t_karplus kkk[], real* S2) { real d, dc, ds, c1, c2, tdc, tds; real fac, ang, invth, Jc; @@ -633,7 +645,7 @@ void calc_distribution_props(int nh, const int histo[], real start, { gmx_fatal(FARGS, "No points in histogram (%s, %d)", __FILE__, __LINE__); } - fac = 2*M_PI/nh; + fac = 2 * M_PI / nh; /* Compute normalisation factor */ th = 0; @@ -641,42 +653,42 @@ void calc_distribution_props(int nh, const int histo[], real start, { th += histo[j]; } - invth = 1.0/th; + invth = 1.0 / th; for (i = 0; (i < nkkk); i++) { kkk[i].Jc = 0; kkk[i].Jcsig = 0; } - tdc = 0; tds = 0; + tdc = 0; + tds = 0; for (j = 0; (j < nh); j++) { - d = invth*histo[j]; - ang = j*fac-start; - c1 = std::cos(ang); - dc = d*c1; - ds = d*std::sin(ang); + d = invth * histo[j]; + ang = j * fac - start; + c1 = std::cos(ang); + dc = d * c1; + ds = d * std::sin(ang); tdc += dc; tds += ds; for (i = 0; (i < nkkk); i++) { - c1 = std::cos(ang+kkk[i].offset); - c2 = c1*c1; - Jc = (kkk[i].A*c2 + kkk[i].B*c1 + kkk[i].C); - kkk[i].Jc += histo[j]*Jc; - kkk[i].Jcsig += histo[j]*gmx::square(Jc); + c1 = std::cos(ang + kkk[i].offset); + c2 = c1 * c1; + Jc = (kkk[i].A * c2 + kkk[i].B * c1 + kkk[i].C); + kkk[i].Jc += histo[j] * Jc; + kkk[i].Jcsig += histo[j] * gmx::square(Jc); } } for (i = 0; (i < nkkk); i++) { - kkk[i].Jc /= th; - kkk[i].Jcsig = std::sqrt(kkk[i].Jcsig/th-gmx::square(kkk[i].Jc)); + kkk[i].Jc /= th; + kkk[i].Jcsig = std::sqrt(kkk[i].Jcsig / th - gmx::square(kkk[i].Jc)); } - *S2 = tdc*tdc+tds*tds; + *S2 = tdc * tdc + tds * tds; } -static void calc_angles(struct t_pbc *pbc, - int n3, int index[], real ang[], rvec x_s[]) +static void calc_angles(struct t_pbc* pbc, int n3, int index[], real ang[], rvec x_s[]) { int i, ix, t1, t2; rvec r_ij, r_kj; @@ -684,13 +696,13 @@ static void calc_angles(struct t_pbc *pbc, for (i = ix = 0; (ix < n3); i++, ix += 3) { - ang[i] = bond_angle(x_s[index[ix]], x_s[index[ix+1]], x_s[index[ix+2]], - pbc, r_ij, r_kj, &costh, &t1, &t2); + ang[i] = bond_angle(x_s[index[ix]], x_s[index[ix + 1]], x_s[index[ix + 2]], pbc, r_ij, r_kj, + &costh, &t1, &t2); } if (debug) { - fprintf(debug, "Angle[0]=%g, costh=%g, index0 = %d, %d, %d\n", - ang[0], costh, index[0], index[1], index[2]); + fprintf(debug, "Angle[0]=%g, costh=%g, index0 = %d, %d, %d\n", ang[0], costh, index[0], + index[1], index[2]); pr_rvec(debug, 0, "rij", r_ij, DIM, TRUE); pr_rvec(debug, 0, "rkj", r_kj, DIM, TRUE); } @@ -719,9 +731,9 @@ static real calc_fraction(const real angles[], int nangles) gauche += 1.0; } } - if (trans+gauche > 0) + if (trans + gauche > 0) { - return trans/(trans+gauche); + return trans / (trans + gauche); } else { @@ -729,8 +741,7 @@ static real calc_fraction(const real angles[], int nangles) } } -static void calc_dihs(struct t_pbc *pbc, - int n4, const int index[], real ang[], rvec x_s[]) +static void calc_dihs(struct t_pbc* pbc, int n4, const int index[], real ang[], rvec x_s[]) { int i, ix, t1, t2, t3; rvec r_ij, r_kj, r_kl, m, n; @@ -738,18 +749,14 @@ static void calc_dihs(struct t_pbc *pbc, for (i = ix = 0; (ix < n4); i++, ix += 4) { - aaa = dih_angle(x_s[index[ix]], x_s[index[ix+1]], x_s[index[ix+2]], - x_s[index[ix+3]], pbc, - r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); + aaa = dih_angle(x_s[index[ix]], x_s[index[ix + 1]], x_s[index[ix + 2]], x_s[index[ix + 3]], + pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); ang[i] = aaa; /* not taking into account ryckaert bellemans yet */ } } -void make_histo(FILE *log, - int ndata, real data[], int npoints, int histo[], - real minx, real maxx) +void make_histo(FILE* log, int ndata, real data[], int npoints, int histo[], real minx, real maxx) { double dx; int i, ind; @@ -764,16 +771,15 @@ void make_histo(FILE *log, } fprintf(log, "Min data: %10g Max data: %10g\n", minx, maxx); } - dx = npoints/(maxx-minx); + dx = npoints / (maxx - minx); if (debug) { - fprintf(debug, - "Histogramming: ndata=%d, nhisto=%d, minx=%g,maxx=%g,dx=%g\n", - ndata, npoints, minx, maxx, dx); + fprintf(debug, "Histogramming: ndata=%d, nhisto=%d, minx=%g,maxx=%g,dx=%g\n", ndata, + npoints, minx, maxx, dx); } for (i = 0; (i < ndata); i++) { - ind = static_cast((data[i]-minx)*dx); + ind = static_cast((data[i] - minx) * dx); if ((ind >= 0) && (ind < npoints)) { histo[ind]++; @@ -793,53 +799,59 @@ void normalize_histo(int npoints, const int histo[], real dx, real normhisto[]) d = 0; for (i = 0; (i < npoints); i++) { - d += dx*histo[i]; + d += dx * histo[i]; } if (d == 0) { fprintf(stderr, "Empty histogram!\n"); return; } - fac = 1.0/d; + fac = 1.0 / d; for (i = 0; (i < npoints); i++) { - normhisto[i] = fac*histo[i]; + normhisto[i] = fac * histo[i]; } } -void read_ang_dih(const char *trj_fn, - gmx_bool bAngles, gmx_bool bSaveAll, gmx_bool bRb, gmx_bool bPBC, - int maxangstat, int angstat[], - int *nframes, real **time, - int isize, int index[], - real **trans_frac, - real **aver_angle, - real *dih[], - const gmx_output_env_t *oenv) +void read_ang_dih(const char* trj_fn, + gmx_bool bAngles, + gmx_bool bSaveAll, + gmx_bool bRb, + gmx_bool bPBC, + int maxangstat, + int angstat[], + int* nframes, + real** time, + int isize, + int index[], + real** trans_frac, + real** aver_angle, + real* dih[], + const gmx_output_env_t* oenv) { - struct t_pbc *pbc; - t_trxstatus *status; + struct t_pbc* pbc; + t_trxstatus* status; int i, angind, total, teller; int nangles, n_alloc; real t, fraction, pifac, aa, angle; - real *angles[2]; + real* angles[2]; matrix box; - rvec *x; + rvec* x; int cur = 0; -#define prev (1-cur) +#define prev (1 - cur) snew(pbc, 1); read_first_x(oenv, &status, trj_fn, &t, &x, box); if (bAngles) { - nangles = isize/3; + nangles = isize / 3; pifac = M_PI; } else { - nangles = isize/4; - pifac = 2.0*M_PI; + nangles = isize / 4; + pifac = 2.0 * M_PI; } snew(angles[cur], nangles); snew(angles[prev], nangles); @@ -900,7 +912,7 @@ void read_ang_dih(const char *trj_fn, { if (angles[cur][i] <= 0.0) { - angles[cur][i] += 2*M_PI; + angles[cur][i] += 2 * M_PI; } } } @@ -910,7 +922,7 @@ void read_ang_dih(const char *trj_fn, { for (i = 0; (i < nangles); i++) { - real dd = angles[cur][i]; + real dd = angles[cur][i]; angles[cur][i] = std::atan2(std::sin(dd), std::cos(dd)); } } @@ -922,11 +934,11 @@ void read_ang_dih(const char *trj_fn, { while (angles[cur][i] <= angles[prev][i] - M_PI) { - angles[cur][i] += 2*M_PI; + angles[cur][i] += 2 * M_PI; } while (angles[cur][i] > angles[prev][i] + M_PI) { - angles[cur][i] -= 2*M_PI; + angles[cur][i] -= 2 * M_PI; } } } @@ -937,7 +949,7 @@ void read_ang_dih(const char *trj_fn, aa = 0; for (i = 0; (i < nangles); i++) { - aa = aa+angles[cur][i]; + aa = aa + angles[cur][i]; /* angle in rad / 2Pi * max determines bin. bins go from 0 to maxangstat, even though scale goes from -pi to pi (dihedral) or -pi/2 to pi/2 @@ -950,27 +962,26 @@ void read_ang_dih(const char *trj_fn, { while (angle < -M_PI) { - angle += 2*M_PI; + angle += 2 * M_PI; } while (angle >= M_PI) { - angle -= 2*M_PI; + angle -= 2 * M_PI; } angle += M_PI; } /* Update the distribution histogram */ - angind = gmx::roundToInt((angle*maxangstat)/pifac); + angind = gmx::roundToInt((angle * maxangstat) / pifac); if (angind == maxangstat) { angind = 0; } - if ( (angind < 0) || (angind >= maxangstat) ) + if ((angind < 0) || (angind >= maxangstat)) { /* this will never happen */ - gmx_fatal(FARGS, "angle (%f) index out of range (0..%d) : %d\n", - angle, maxangstat, angind); + gmx_fatal(FARGS, "angle (%f) index out of range (0..%d) : %d\n", angle, maxangstat, angind); } angstat[angind]++; @@ -983,7 +994,7 @@ void read_ang_dih(const char *trj_fn, } /* average over all angles */ - (*aver_angle)[teller] = (aa/nangles); + (*aver_angle)[teller] = (aa / nangles); /* this copies all current dih. angles to dih[i], teller is frame */ if (bSaveAll) @@ -999,8 +1010,7 @@ void read_ang_dih(const char *trj_fn, /* Increment loop counter */ teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); sfree(x); diff --git a/src/gromacs/gmxana/binsearch.cpp b/src/gromacs/gmxana/binsearch.cpp index b9b9b93a81..2e503a3677 100644 --- a/src/gromacs/gmxana/binsearch.cpp +++ b/src/gromacs/gmxana/binsearch.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,7 +43,7 @@ #include "gromacs/utility/real.h" /*Make range-array (Permutation identity) for sorting */ -void rangeArray(int *ar, int size) +void rangeArray(int* ar, int size) { int i; for (i = 0; i < size; i++) @@ -51,7 +52,7 @@ void rangeArray(int *ar, int size) } } -static void pswap(int *v1, int *v2) +static void pswap(int* v1, int* v2) { int temp; temp = *v1; @@ -60,7 +61,7 @@ static void pswap(int *v1, int *v2) } -static void Swap (real *v1, real *v2) +static void Swap(real* v1, real* v2) { real temp; temp = *v1; @@ -69,8 +70,7 @@ static void Swap (real *v1, real *v2) } - -void insertionSort(real *arr, int *perm, int startndx, int endndx, int direction) +void insertionSort(real* arr, int* perm, int startndx, int endndx, int direction) { int i, j; @@ -82,13 +82,11 @@ void insertionSort(real *arr, int *perm, int startndx, int endndx, int direction while (j > startndx && arr[j - 1] > arr[j]) { - Swap(&arr[j], &arr[j-1]); - pswap(&perm[j], &perm[j-1]); + Swap(&arr[j], &arr[j - 1]); + pswap(&perm[j], &perm[j - 1]); j--; } - } - } if (direction < 0) @@ -99,30 +97,29 @@ void insertionSort(real *arr, int *perm, int startndx, int endndx, int direction while (j > startndx && arr[j - 1] < arr[j]) { - Swap(&arr[j], &arr[j-1]); - pswap(&perm[j], &perm[j-1]); + Swap(&arr[j], &arr[j - 1]); + pswap(&perm[j], &perm[j - 1]); j--; } - } } } -int BinarySearch (const real *array, int low, int high, real key, int direction) +int BinarySearch(const real* array, int low, int high, real key, int direction) { int iMid, iMax, iMin; - iMax = high+2; - iMin = low+1; + iMax = high + 2; + iMin = low + 1; -/*Iterative implementation*/ + /*Iterative implementation*/ if (direction >= 0) { - while (iMax-iMin > 1) + while (iMax - iMin > 1) { - iMid = (iMin+iMax)>>1; - if (key < array[iMid-1]) + iMid = (iMin + iMax) >> 1; + if (key < array[iMid - 1]) { iMax = iMid; } @@ -135,10 +132,10 @@ int BinarySearch (const real *array, int low, int high, real key, int direction) } else { - while (iMax-iMin > 1) + while (iMax - iMin > 1) { - iMid = (iMin+iMax)>>1; - if (key > array[iMid-1]) + iMid = (iMin + iMax) >> 1; + if (key > array[iMid - 1]) { iMax = iMid; } @@ -147,20 +144,18 @@ int BinarySearch (const real *array, int low, int high, real key, int direction) iMin = iMid; } } - return iMin-1; + return iMin - 1; } } -int start_binsearch(real *array, int *perm, int low, int high, - real key, int direction) +int start_binsearch(real* array, int* perm, int low, int high, real key, int direction) { insertionSort(array, perm, low, high, direction); return BinarySearch(array, low, high, key, direction); } -int LinearSearch (const double *array, int startindx, int stopindx, - double key, int *count, int direction) +int LinearSearch(const double* array, int startindx, int stopindx, double key, int* count, int direction) { /*Iterative implementation - assume elements sorted*/ int i; @@ -173,7 +168,7 @@ int LinearSearch (const double *array, int startindx, int stopindx, (*count)++; if (array[i] > key) { - keyindex = i-1; + keyindex = i - 1; return keyindex; } } @@ -185,7 +180,7 @@ int LinearSearch (const double *array, int startindx, int stopindx, (*count)++; if (array[i] > key) { - keyindex = i+1; + keyindex = i + 1; return keyindex; } } diff --git a/src/gromacs/gmxana/binsearch.h b/src/gromacs/gmxana/binsearch.h index 2458a22ba3..1acdebe339 100644 --- a/src/gromacs/gmxana/binsearch.h +++ b/src/gromacs/gmxana/binsearch.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,16 +37,14 @@ #include "gromacs/utility/real.h" -void rangeArray(int *ar, int size); +void rangeArray(int* ar, int size); -void insertionSort(real *ar, int *perm, int start, int end, int direction); +void insertionSort(real* ar, int* perm, int start, int end, int direction); -int BinarySearch(const real *ar, int start, int end, real key, int direction); +int BinarySearch(const real* ar, int start, int end, real key, int direction); -int start_binsearch(real *array, int *perm, int low, int high, - real key, int direction); +int start_binsearch(real* array, int* perm, int low, int high, real key, int direction); -int LinearSearch(const double *array, int startindx, int stopindx, - double key, int *count, int direction); +int LinearSearch(const double* array, int startindx, int stopindx, double key, int* count, int direction); #endif diff --git a/src/gromacs/gmxana/cmat.cpp b/src/gromacs/gmxana/cmat.cpp index ec67259db6..cde327414c 100644 --- a/src/gromacs/gmxana/cmat.cpp +++ b/src/gromacs/gmxana/cmat.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,9 +47,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -t_mat *init_mat(int n1, gmx_bool b1D) +t_mat* init_mat(int n1, gmx_bool b1D) { - t_mat *m; + t_mat* m; snew(m, 1); m->n1 = n1; @@ -67,7 +67,7 @@ t_mat *init_mat(int n1, gmx_bool b1D) return m; } -void copy_t_mat(t_mat *dst, t_mat *src) +void copy_t_mat(t_mat* dst, t_mat* src) { int i, j; @@ -90,33 +90,33 @@ void copy_t_mat(t_mat *dst, t_mat *src) } } -void enlarge_mat(t_mat *m, int deltan) +void enlarge_mat(t_mat* m, int deltan) { int i, j; - srenew(m->erow, m->nn+deltan); - srenew(m->m_ind, m->nn+deltan); - srenew(m->mat, m->nn+deltan); + srenew(m->erow, m->nn + deltan); + srenew(m->m_ind, m->nn + deltan); + srenew(m->mat, m->nn + deltan); /* Reallocate existing rows in the matrix, and set them to zero */ for (i = 0; (i < m->nn); i++) { - srenew(m->mat[i], m->nn+deltan); - for (j = m->nn; (j < m->nn+deltan); j++) + srenew(m->mat[i], m->nn + deltan); + for (j = m->nn; (j < m->nn + deltan); j++) { m->mat[i][j] = 0; } } /* Allocate new rows of the matrix, set energies to zero */ - for (i = m->nn; (i < m->nn+deltan); i++) + for (i = m->nn; (i < m->nn + deltan); i++) { - m->erow[i] = 0; - snew(m->mat[i], m->nn+deltan); + m->erow[i] = 0; + snew(m->mat[i], m->nn + deltan); } m->nn += deltan; } -void reset_index(t_mat *m) +void reset_index(t_mat* m) { int i; @@ -126,19 +126,19 @@ void reset_index(t_mat *m) } } -void set_mat_entry(t_mat *m, int i, int j, real val) +void set_mat_entry(t_mat* m, int i, int j, real val) { m->mat[i][j] = m->mat[j][i] = val; - m->maxrms = std::max(m->maxrms, val); + m->maxrms = std::max(m->maxrms, val); if (j != i) { - m->minrms = std::min(m->minrms, val); + m->minrms = std::min(m->minrms, val); } - m->sumrms += val; - m->nn = std::max(m->nn, std::max(j+1, i+1)); + m->sumrms += val; + m->nn = std::max(m->nn, std::max(j + 1, i + 1)); } -void done_mat(t_mat **m) +void done_mat(t_mat** m) { done_matrix((*m)->n1, &((*m)->mat)); sfree((*m)->m_ind); @@ -147,19 +147,19 @@ void done_mat(t_mat **m) *m = nullptr; } -real mat_energy(t_mat *m) +real mat_energy(t_mat* m) { int j; real emat = 0; - for (j = 0; (j < m->nn-1); j++) + for (j = 0; (j < m->nn - 1); j++) { - emat += gmx::square(m->mat[j][j+1]); + emat += gmx::square(m->mat[j][j + 1]); } return emat; } -void swap_rows(t_mat *m, int iswap, int jswap) +void swap_rows(t_mat* m, int iswap, int jswap) { real *tmp, ttt; int i, itmp; @@ -183,9 +183,9 @@ void swap_rows(t_mat *m, int iswap, int jswap) } } -void swap_mat(t_mat *m) +void swap_mat(t_mat* m) { - t_mat *tmp; + t_mat* tmp; int i, j; tmp = init_mat(m->nn, FALSE); @@ -207,20 +207,19 @@ void swap_mat(t_mat *m) done_mat(&tmp); } -void low_rmsd_dist(const char *fn, real maxrms, int nn, real **mat, - const gmx_output_env_t *oenv) +void low_rmsd_dist(const char* fn, real maxrms, int nn, real** mat, const gmx_output_env_t* oenv) { - FILE *fp; - int i, j, *histo, x; - real fac; + FILE* fp; + int i, j, *histo, x; + real fac; - fac = 100/maxrms; + fac = 100 / maxrms; snew(histo, 101); for (i = 0; i < nn; i++) { - for (j = i+1; j < nn; j++) + for (j = i + 1; j < nn; j++) { - x = gmx::roundToInt(fac*mat[i][j]); + x = gmx::roundToInt(fac * mat[i][j]); if (x <= 100) { histo[x]++; @@ -231,20 +230,20 @@ void low_rmsd_dist(const char *fn, real maxrms, int nn, real **mat, fp = xvgropen(fn, "RMS Distribution", "RMS (nm)", "a.u.", oenv); for (i = 0; (i < 101); i++) { - fprintf(fp, "%10g %10d\n", i/fac, histo[i]); + fprintf(fp, "%10g %10d\n", i / fac, histo[i]); } xvgrclose(fp); sfree(histo); } -void rmsd_distribution(const char *fn, t_mat *rms, const gmx_output_env_t *oenv) +void rmsd_distribution(const char* fn, t_mat* rms, const gmx_output_env_t* oenv) { low_rmsd_dist(fn, rms->maxrms, rms->nn, rms->mat, oenv); } -t_clustid *new_clustid(int n1) +t_clustid* new_clustid(int n1) { - t_clustid *c; + t_clustid* c; int i; snew(c, n1); diff --git a/src/gromacs/gmxana/cmat.h b/src/gromacs/gmxana/cmat.h index 0f6b782d2b..304f48e986 100644 --- a/src/gromacs/gmxana/cmat.h +++ b/src/gromacs/gmxana/cmat.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,50 +43,52 @@ struct gmx_output_env_t; -typedef struct { +typedef struct +{ int i, j; real dist; } t_dist; -typedef struct { - int conf, clust; +typedef struct +{ + int conf, clust; } t_clustid; -typedef struct { +typedef struct +{ int n1, nn; - int *m_ind; + int* m_ind; gmx_bool b1D; real minrms, maxrms, sumrms; - real *erow; - real **mat; + real* erow; + real** mat; } t_mat; /* The matrix is indexed using the matrix index */ -#define EROW(m, i) m->erow[i] +#define EROW(m, i) m->erow[i] -extern t_mat *init_mat(int n1, gmx_bool b1D); +extern t_mat* init_mat(int n1, gmx_bool b1D); -extern void copy_t_mat(t_mat *dst, t_mat *src); +extern void copy_t_mat(t_mat* dst, t_mat* src); -extern void enlarge_mat(t_mat *m, int deltan); +extern void enlarge_mat(t_mat* m, int deltan); -extern void reset_index(t_mat *m); +extern void reset_index(t_mat* m); -extern void swap_rows(t_mat *m, int iswap, int jswap); +extern void swap_rows(t_mat* m, int iswap, int jswap); -extern void set_mat_entry(t_mat *m, int i, int j, real val); +extern void set_mat_entry(t_mat* m, int i, int j, real val); -extern void done_mat(t_mat **m); +extern void done_mat(t_mat** m); -extern real mat_energy(t_mat *mat); +extern real mat_energy(t_mat* mat); -extern void swap_mat(t_mat *m); +extern void swap_mat(t_mat* m); -extern void low_rmsd_dist(const char *fn, real maxrms, int nn, real **mat, - const gmx_output_env_t *oenv); +extern void low_rmsd_dist(const char* fn, real maxrms, int nn, real** mat, const gmx_output_env_t* oenv); -extern void rmsd_distribution(const char *fn, t_mat *m, const gmx_output_env_t *oenv); +extern void rmsd_distribution(const char* fn, t_mat* m, const gmx_output_env_t* oenv); -extern t_clustid *new_clustid(int n1); +extern t_clustid* new_clustid(int n1); #endif diff --git a/src/gromacs/gmxana/dens_filter.cpp b/src/gromacs/gmxana/dens_filter.cpp index 01e0a604eb..d1334ac1e9 100644 --- a/src/gromacs/gmxana/dens_filter.cpp +++ b/src/gromacs/gmxana/dens_filter.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,10 +46,10 @@ #include "gromacs/math/vec.h" #include "gromacs/utility/smalloc.h" -gmx_bool convolution(int dataSize, real *x, int kernelSize, const real* kernel) +gmx_bool convolution(int dataSize, real* x, int kernelSize, const real* kernel) { int i, j, k; - real *out; + real* out; snew(out, dataSize); /* check validity of params */ if (!x || !kernel) @@ -62,7 +62,7 @@ gmx_bool convolution(int dataSize, real *x, int kernelSize, const real* kernel) } /* start convolution from out[kernelSize-1] to out[dataSize-1] (last) */ - for (i = kernelSize-1; i < dataSize; ++i) + for (i = kernelSize - 1; i < dataSize; ++i) { for (j = i, k = 0; k < kernelSize; --j, ++k) { @@ -89,11 +89,10 @@ gmx_bool convolution(int dataSize, real *x, int kernelSize, const real* kernel) /* Assuming kernel is shorter than x */ -gmx_bool periodic_convolution(int datasize, real *x, int kernelsize, - const real *kernel) +gmx_bool periodic_convolution(int datasize, real* x, int kernelsize, const real* kernel) { int i, j, idx; - real *filtered; + real* filtered; if (!x || !kernel) { @@ -111,8 +110,8 @@ gmx_bool periodic_convolution(int datasize, real *x, int kernelsize, for (j = 0; (j < kernelsize); j++) { // add datasize in case i-j is <0 - idx = i-j + datasize; - filtered[i] += kernel[j]*x[idx % datasize]; + idx = i - j + datasize; + filtered[i] += kernel[j] * x[idx % datasize]; } } for (i = 0; i < datasize; i++) @@ -125,18 +124,18 @@ gmx_bool periodic_convolution(int datasize, real *x, int kernelsize, } -/* returns discrete gaussian kernel of size n in *out, where n=2k+1=3,5,7,9,11 and k=1,2,3 is the order - * NO checks are performed +/* returns discrete gaussian kernel of size n in *out, where n=2k+1=3,5,7,9,11 and k=1,2,3 is the + * order NO checks are performed */ -void gausskernel(real *out, int n, real var) +void gausskernel(real* out, int n, real var) { - int i, j = 0, k; + int i, j = 0, k; real arg, tot = 0; - k = n/2; + k = n / 2; for (i = -k; i <= k; i++) { - arg = (i*i)/(2*var); + arg = (i * i) / (2 * var); tot += out[j++] = std::exp(-arg); } for (i = 0; i < j; i++) diff --git a/src/gromacs/gmxana/dens_filter.h b/src/gromacs/gmxana/dens_filter.h index 5de74c32fd..aa6f1f7234 100644 --- a/src/gromacs/gmxana/dens_filter.h +++ b/src/gromacs/gmxana/dens_filter.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,10 +39,8 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -extern gmx_bool convolution(int dataSize, real* in, int kernelSize, - const real* kernel); -extern gmx_bool periodic_convolution(int dsize, real *in, int ksize, - const real* kernel); -extern void gausskernel(real *out, int size, real var); +extern gmx_bool convolution(int dataSize, real* in, int kernelSize, const real* kernel); +extern gmx_bool periodic_convolution(int dsize, real* in, int ksize, const real* kernel); +extern void gausskernel(real* out, int size, real var); #endif diff --git a/src/gromacs/gmxana/dlist.cpp b/src/gromacs/gmxana/dlist.cpp index 70ded72044..78b59aa7f0 100644 --- a/src/gromacs/gmxana/dlist.cpp +++ b/src/gromacs/gmxana/dlist.cpp @@ -45,31 +45,37 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -t_dlist *mk_dlist(FILE *log, - const t_atoms *atoms, int *nlist, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi, - int maxchi, int r0, ResidueType *rt) +t_dlist* mk_dlist(FILE* log, + const t_atoms* atoms, + int* nlist, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bHChi, + int maxchi, + int r0, + ResidueType* rt) { int i, j, ii; t_dihatms atm, prev; int nl = 0, nc[edMax]; - char *thisres; - t_dlist *dl; + char* thisres; + t_dlist* dl; - snew(dl, atoms->nres+1); + snew(dl, atoms->nres + 1); prev.C = prev.Cn[1] = -1; /* Keep the compiler quiet */ for (i = 0; (i < edMax); i++) { nc[i] = 0; } - i = 0; + i = 0; while (i < atoms->nr) { int ires = atoms->atom[i].resind; /* Initiate all atom numbers to -1 */ atm.minC = atm.H = atm.N = atm.C = atm.O = atm.minCalpha = -1; - for (j = 0; (j < MAXCHI+3); j++) + for (j = 0; (j < MAXCHI + 3); j++) { atm.Cn[j] = -1; } @@ -78,9 +84,9 @@ t_dlist *mk_dlist(FILE *log, /* maybe should allow for chis to hydrogens? */ while ((i < atoms->nr) && (atoms->atom[i].resind == ires)) { - if ((std::strcmp(*(atoms->atomname[i]), "H") == 0) || - (std::strcmp(*(atoms->atomname[i]), "H1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "HN") == 0) ) + if ((std::strcmp(*(atoms->atomname[i]), "H") == 0) + || (std::strcmp(*(atoms->atomname[i]), "H1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "HN") == 0)) { atm.H = i; } @@ -92,10 +98,10 @@ t_dlist *mk_dlist(FILE *log, { atm.C = i; } - else if ((std::strcmp(*(atoms->atomname[i]), "O") == 0) || - (std::strcmp(*(atoms->atomname[i]), "O1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OC1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OT1") == 0)) + else if ((std::strcmp(*(atoms->atomname[i]), "O") == 0) + || (std::strcmp(*(atoms->atomname[i]), "O1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OC1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OT1") == 0)) { atm.O = i; } @@ -107,37 +113,38 @@ t_dlist *mk_dlist(FILE *log, { atm.Cn[2] = i; } - else if ((std::strcmp(*(atoms->atomname[i]), "CG") == 0) || - (std::strcmp(*(atoms->atomname[i]), "CG1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OG") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OG1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "SG") == 0)) + else if ((std::strcmp(*(atoms->atomname[i]), "CG") == 0) + || (std::strcmp(*(atoms->atomname[i]), "CG1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OG") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OG1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "SG") == 0)) { atm.Cn[3] = i; } - else if ((std::strcmp(*(atoms->atomname[i]), "CD") == 0) || - (std::strcmp(*(atoms->atomname[i]), "CD1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "SD") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OD1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "ND1") == 0)) + else if ((std::strcmp(*(atoms->atomname[i]), "CD") == 0) + || (std::strcmp(*(atoms->atomname[i]), "CD1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "SD") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OD1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "ND1") == 0)) { atm.Cn[4] = i; } /* by grs - split the Cn[4] into 2 bits to check allowing dih to H */ - else if (bHChi && ((std::strcmp(*(atoms->atomname[i]), "HG") == 0) || - (std::strcmp(*(atoms->atomname[i]), "HG1") == 0)) ) + else if (bHChi + && ((std::strcmp(*(atoms->atomname[i]), "HG") == 0) + || (std::strcmp(*(atoms->atomname[i]), "HG1") == 0))) { atm.Cn[4] = i; } - else if ((std::strcmp(*(atoms->atomname[i]), "CE") == 0) || - (std::strcmp(*(atoms->atomname[i]), "CE1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "OE1") == 0) || - (std::strcmp(*(atoms->atomname[i]), "NE") == 0)) + else if ((std::strcmp(*(atoms->atomname[i]), "CE") == 0) + || (std::strcmp(*(atoms->atomname[i]), "CE1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "OE1") == 0) + || (std::strcmp(*(atoms->atomname[i]), "NE") == 0)) { atm.Cn[5] = i; } - else if ((std::strcmp(*(atoms->atomname[i]), "CZ") == 0) || - (std::strcmp(*(atoms->atomname[i]), "NZ") == 0)) + else if ((std::strcmp(*(atoms->atomname[i]), "CZ") == 0) + || (std::strcmp(*(atoms->atomname[i]), "NZ") == 0)) { atm.Cn[6] = i; } @@ -153,13 +160,10 @@ t_dlist *mk_dlist(FILE *log, /* added by grs - special case for aromatics, whose chis above 2 are not real and produce rubbish output - so set back to -1 */ - if (std::strcmp(thisres, "PHE") == 0 || - std::strcmp(thisres, "TYR") == 0 || - std::strcmp(thisres, "PTR") == 0 || - std::strcmp(thisres, "TRP") == 0 || - std::strcmp(thisres, "HIS") == 0 || - std::strcmp(thisres, "HISA") == 0 || - std::strcmp(thisres, "HISB") == 0) + if (std::strcmp(thisres, "PHE") == 0 || std::strcmp(thisres, "TYR") == 0 + || std::strcmp(thisres, "PTR") == 0 || std::strcmp(thisres, "TRP") == 0 + || std::strcmp(thisres, "HIS") == 0 || std::strcmp(thisres, "HISA") == 0 + || std::strcmp(thisres, "HISB") == 0) { for (ii = 5; ii <= 7; ii++) { @@ -186,10 +190,10 @@ t_dlist *mk_dlist(FILE *log, prev = atm; /* Check how many dihedrals we have */ - if ((atm.N != -1) && (atm.Cn[1] != -1) && (atm.C != -1) && - (atm.O != -1) && ((atm.H != -1) || (atm.minC != -1))) + if ((atm.N != -1) && (atm.Cn[1] != -1) && (atm.C != -1) && (atm.O != -1) + && ((atm.H != -1) || (atm.minC != -1))) { - dl[nl].resnr = ires+1; + dl[nl].resnr = ires + 1; dl[nl].atm = atm; dl[nl].atm.Cn[0] = atm.N; if ((atm.Cn[3] != -1) && (atm.Cn[2] != -1) && (atm.Cn[1] != -1)) @@ -227,18 +231,21 @@ t_dlist *mk_dlist(FILE *log, * another machine, the residue type will be unknown. */ if (dl[nl].index == -1) { - gmx_fatal(FARGS, "Unknown residue %s when searching for residue type.\n" + gmx_fatal(FARGS, + "Unknown residue %s when searching for residue type.\n" "Maybe you need to add a custom residue in residuetypes.dat.", thisres); } - sprintf(dl[nl].name, "%s%d", thisres, ires+r0); + sprintf(dl[nl].name, "%s%d", thisres, ires + r0); nl++; } else if (debug) { - fprintf(debug, "Could not find N atom but could find other atoms" - " in residue %s%d\n", thisres, ires+r0); + fprintf(debug, + "Could not find N atom but could find other atoms" + " in residue %s%d\n", + thisres, ires + r0); } } fprintf(stderr, "\n"); @@ -274,7 +281,7 @@ t_dlist *mk_dlist(FILE *log, { for (i = 0; (i < maxchi); i++) { - fprintf(log, "Chi%d ", i+1); + fprintf(log, "Chi%d ", i + 1); } } fprintf(log, "\nNumber: "); @@ -300,7 +307,7 @@ t_dlist *mk_dlist(FILE *log, return dl; } -gmx_bool has_dihedral(int Dih, t_dlist *dl) +gmx_bool has_dihedral(int Dih, t_dlist* dl) { gmx_bool b = FALSE; int ddd; @@ -314,7 +321,8 @@ gmx_bool has_dihedral(int Dih, t_dlist *dl) b = ((dl->atm.N != -1) && (dl->atm.Cn[1] != -1) && (dl->atm.C != -1) && (dl->atm.O != -1)); break; case edOmega: - b = ((dl->atm.minCalpha != -1) && (dl->atm.minC != -1) && (dl->atm.N != -1) && (dl->atm.Cn[1] != -1)); + b = ((dl->atm.minCalpha != -1) && (dl->atm.minC != -1) && (dl->atm.N != -1) + && (dl->atm.Cn[1] != -1)); break; case edChi1: case edChi2: @@ -323,18 +331,17 @@ gmx_bool has_dihedral(int Dih, t_dlist *dl) case edChi5: case edChi6: ddd = Dih - edChi1; - b = ((dl->atm.Cn[ddd] != -1) && (dl->atm.Cn[ddd+1] != -1) && - (dl->atm.Cn[ddd+2] != -1) && (dl->atm.Cn[ddd+3] != -1)); + b = ((dl->atm.Cn[ddd] != -1) && (dl->atm.Cn[ddd + 1] != -1) + && (dl->atm.Cn[ddd + 2] != -1) && (dl->atm.Cn[ddd + 3] != -1)); break; default: pr_dlist(stdout, 1, dl, 1, 0, TRUE, TRUE, TRUE, TRUE, MAXCHI); - gmx_fatal(FARGS, "Non existent dihedral %d in file %s, line %d", - Dih, __FILE__, __LINE__); + gmx_fatal(FARGS, "Non existent dihedral %d in file %s, line %d", Dih, __FILE__, __LINE__); } return b; } -static void pr_one_ro(FILE *fp, t_dlist *dl, int nDih, real gmx_unused dt) +static void pr_one_ro(FILE* fp, t_dlist* dl, int nDih, real gmx_unused dt) { int k; for (k = 0; k < NROT; k++) @@ -344,17 +351,25 @@ static void pr_one_ro(FILE *fp, t_dlist *dl, int nDih, real gmx_unused dt) fprintf(fp, "\n"); } -static void pr_ntr_s2(FILE *fp, t_dlist *dl, int nDih, real dt) +static void pr_ntr_s2(FILE* fp, t_dlist* dl, int nDih, real dt) { - fprintf(fp, " %6.2f %6.2f\n", (dt == 0) ? 0 : dl->ntr[nDih]/dt, dl->S2[nDih]); + fprintf(fp, " %6.2f %6.2f\n", (dt == 0) ? 0 : dl->ntr[nDih] / dt, dl->S2[nDih]); } -void pr_dlist(FILE *fp, int nl, t_dlist dl[], real dt, int printtype, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega, int maxchi) +void pr_dlist(FILE* fp, + int nl, + t_dlist dl[], + real dt, + int printtype, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bOmega, + int maxchi) { - int i, Xi; + int i, Xi; - void (*pr_props)(FILE *, t_dlist *, int, real); + void (*pr_props)(FILE*, t_dlist*, int, real); /* Analysis of dihedral transitions etc */ @@ -376,41 +391,42 @@ void pr_dlist(FILE *fp, int nl, t_dlist dl[], real dt, int printtype, fprintf(fp, "Residue %s\n", dl[i].name); if (printtype == edPrintST) { - fprintf(fp, " Angle [ AI, AJ, AK, AL] #tr/ns S^2D \n" + fprintf(fp, + " Angle [ AI, AJ, AK, AL] #tr/ns S^2D \n" "--------------------------------------------\n"); } else { - fprintf(fp, " Angle [ AI, AJ, AK, AL] rotamers 0 g(-) t g(+)\n" + fprintf(fp, + " Angle [ AI, AJ, AK, AL] rotamers 0 g(-) t g(+)\n" "--------------------------------------------\n"); } if (bPhi) { fprintf(fp, " Phi [%5d,%5d,%5d,%5d]", - (dl[i].atm.H == -1) ? 1+dl[i].atm.minC : 1+dl[i].atm.H, - 1+dl[i].atm.N, 1+dl[i].atm.Cn[1], 1+dl[i].atm.C); + (dl[i].atm.H == -1) ? 1 + dl[i].atm.minC : 1 + dl[i].atm.H, 1 + dl[i].atm.N, + 1 + dl[i].atm.Cn[1], 1 + dl[i].atm.C); pr_props(fp, &dl[i], edPhi, dt); } if (bPsi) { - fprintf(fp, " Psi [%5d,%5d,%5d,%5d]", 1+dl[i].atm.N, 1+dl[i].atm.Cn[1], - 1+dl[i].atm.C, 1+dl[i].atm.O); + fprintf(fp, " Psi [%5d,%5d,%5d,%5d]", 1 + dl[i].atm.N, 1 + dl[i].atm.Cn[1], + 1 + dl[i].atm.C, 1 + dl[i].atm.O); pr_props(fp, &dl[i], edPsi, dt); } if (bOmega && has_dihedral(edOmega, &(dl[i]))) { - fprintf(fp, " Omega [%5d,%5d,%5d,%5d]", 1+dl[i].atm.minCalpha, 1+dl[i].atm.minC, - 1+dl[i].atm.N, 1+dl[i].atm.Cn[1]); + fprintf(fp, " Omega [%5d,%5d,%5d,%5d]", 1 + dl[i].atm.minCalpha, 1 + dl[i].atm.minC, + 1 + dl[i].atm.N, 1 + dl[i].atm.Cn[1]); pr_props(fp, &dl[i], edOmega, dt); } for (Xi = 0; Xi < MAXCHI; Xi++) { - if (bChi && (Xi < maxchi) && (dl[i].atm.Cn[Xi+3] != -1) ) + if (bChi && (Xi < maxchi) && (dl[i].atm.Cn[Xi + 3] != -1)) { - fprintf(fp, " Chi%d[%5d,%5d,%5d,%5d]", Xi+1, 1+dl[i].atm.Cn[Xi], - 1+dl[i].atm.Cn[Xi+1], 1+dl[i].atm.Cn[Xi+2], - 1+dl[i].atm.Cn[Xi+3]); - pr_props(fp, &dl[i], Xi+edChi1, dt); /* Xi+2 was wrong here */ + fprintf(fp, " Chi%d[%5d,%5d,%5d,%5d]", Xi + 1, 1 + dl[i].atm.Cn[Xi], + 1 + dl[i].atm.Cn[Xi + 1], 1 + dl[i].atm.Cn[Xi + 2], 1 + dl[i].atm.Cn[Xi + 3]); + pr_props(fp, &dl[i], Xi + edChi1, dt); /* Xi+2 was wrong here */ } } fprintf(fp, "\n"); @@ -418,22 +434,21 @@ void pr_dlist(FILE *fp, int nl, t_dlist dl[], real dt, int printtype, } - -int pr_trans(FILE *fp, int nl, t_dlist dl[], real dt, int Xi) +int pr_trans(FILE* fp, int nl, t_dlist dl[], real dt, int Xi) { /* never called at the moment */ - int i, nn, nz; + int i, nn, nz; nz = 0; fprintf(fp, "\\begin{table}[h]\n"); fprintf(fp, "\\caption{Number of dihedral transitions per nanosecond}\n"); fprintf(fp, "\\begin{tabular}{|l|l|}\n"); fprintf(fp, "\\hline\n"); - fprintf(fp, "Residue\t&$\\chi_%d$\t\\\\\n", Xi+1); + fprintf(fp, "Residue\t&$\\chi_%d$\t\\\\\n", Xi + 1); for (i = 0; (i < nl); i++) { - nn = static_cast(dl[i].ntr[Xi]/dt); + nn = static_cast(dl[i].ntr[Xi] / dt); if (nn == 0) { diff --git a/src/gromacs/gmxana/eigio.cpp b/src/gromacs/gmxana/eigio.cpp index 416b9b4ca2..3cea7e812a 100644 --- a/src/gromacs/gmxana/eigio.cpp +++ b/src/gromacs/gmxana/eigio.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,18 +44,24 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, - rvec **xref, gmx_bool *bDMR, - rvec **xav, gmx_bool *bDMA, - int *nvec, int **eignr, - rvec ***eigvec, real **eigval) +void read_eigenvectors(const char* file, + int* natoms, + gmx_bool* bFit, + rvec** xref, + gmx_bool* bDMR, + rvec** xav, + gmx_bool* bDMA, + int* nvec, + int** eignr, + rvec*** eigvec, + real** eigval) { - gmx_trr_header_t head; - int i, snew_size; - struct t_fileio *status; - rvec *x; - matrix box; - gmx_bool bOK; + gmx_trr_header_t head; + int i, snew_size; + struct t_fileio* status; + rvec* x; + matrix box; + gmx_bool bOK; *bDMR = FALSE; @@ -77,7 +83,8 @@ void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, *bFit = (head.lambda > -0.5); if (*bFit) { - fprintf(stderr, "Read %smass weighted reference structure with %d atoms from %s\n", *bDMR ? "" : "non ", *natoms, file); + fprintf(stderr, "Read %smass weighted reference structure with %d atoms from %s\n", + *bDMR ? "" : "non ", *natoms, file); } else { @@ -96,15 +103,15 @@ void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, *bDMA = (head.lambda > 0.5); if ((head.t <= -0.01) || (head.t >= 0.01)) { - fprintf(stderr, "WARNING: %s does not start with t=0, which should be the " + fprintf(stderr, + "WARNING: %s does not start with t=0, which should be the " "average structure. This might not be a eigenvector file. " "Some things might go wrong.\n", file); } else { - fprintf(stderr, - "Read %smass weighted average/minimum structure with %d atoms from %s\n", + fprintf(stderr, "Read %smass weighted average/minimum structure with %d atoms from %s\n", *bDMA ? "" : "non ", *natoms, file); } @@ -127,7 +134,7 @@ void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, } i = head.step; (*eigval)[*nvec] = head.t; - (*eignr)[*nvec] = i-1; + (*eignr)[*nvec] = i - 1; snew((*eigvec)[*nvec], *natoms); for (i = 0; i < *natoms; i++) { @@ -141,24 +148,30 @@ void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, } -void write_eigenvectors(const char *trrname, int natoms, const real mat[], - gmx_bool bReverse, int begin, int end, - int WriteXref, const rvec *xref, gmx_bool bDMR, - const rvec xav[], gmx_bool bDMA, const real eigval[]) +void write_eigenvectors(const char* trrname, + int natoms, + const real mat[], + gmx_bool bReverse, + int begin, + int end, + int WriteXref, + const rvec* xref, + gmx_bool bDMR, + const rvec xav[], + gmx_bool bDMA, + const real eigval[]) { - struct t_fileio *trrout; + struct t_fileio* trrout; int ndim, i, j, d, vec; matrix zerobox; - rvec *x; + rvec* x; - ndim = natoms*DIM; + ndim = natoms * DIM; clear_mat(zerobox); snew(x, natoms); - fprintf (stderr, - "\nWriting %saverage structure & eigenvectors %d--%d to %s\n", - (WriteXref == eWXR_YES) ? "reference, " : "", - begin, end, trrname); + fprintf(stderr, "\nWriting %saverage structure & eigenvectors %d--%d to %s\n", + (WriteXref == eWXR_YES) ? "reference, " : "", begin, end, trrname); trrout = gmx_trr_open(trrname, "w"); if (WriteXref == eWXR_YES) @@ -175,7 +188,7 @@ void write_eigenvectors(const char *trrname, int natoms, const real mat[], /* misuse lambda: 0/1 mass weighted analysis no/yes */ gmx_trr_write_frame(trrout, 0, 0, bDMA ? 1.0 : 0.0, zerobox, natoms, xav, nullptr, nullptr); - for (i = 0; i <= (end-begin); i++) + for (i = 0; i <= (end - begin); i++) { if (!bReverse) @@ -184,19 +197,19 @@ void write_eigenvectors(const char *trrname, int natoms, const real mat[], } else { - vec = ndim-i-1; + vec = ndim - i - 1; } for (j = 0; j < natoms; j++) { for (d = 0; d < DIM; d++) { - x[j][d] = mat[vec*ndim+DIM*j+d]; + x[j][d] = mat[vec * ndim + DIM * j + d]; } } /* Store the eigenvalue in the time field */ - gmx_trr_write_frame(trrout, begin+i, eigval[vec], 0, zerobox, natoms, x, nullptr, nullptr); + gmx_trr_write_frame(trrout, begin + i, eigval[vec], 0, zerobox, natoms, x, nullptr, nullptr); } gmx_trr_close(trrout); diff --git a/src/gromacs/gmxana/eigio.h b/src/gromacs/gmxana/eigio.h index 5358b3cff5..b6d0f71562 100644 --- a/src/gromacs/gmxana/eigio.h +++ b/src/gromacs/gmxana/eigio.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,14 +42,24 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -enum { - eWXR_NO, eWXR_YES, eWXR_NOFIT +enum +{ + eWXR_NO, + eWXR_YES, + eWXR_NOFIT }; -extern void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, - rvec **xref, gmx_bool *bDMR, - rvec **xav, gmx_bool *bDMA, - int *nvec, int **eignr, rvec ***eigvec, real **eigval); +extern void read_eigenvectors(const char* file, + int* natoms, + gmx_bool* bFit, + rvec** xref, + gmx_bool* bDMR, + rvec** xav, + gmx_bool* bDMA, + int* nvec, + int** eignr, + rvec*** eigvec, + real** eigval); /* Read eigenvectors from file into eigvec, the eigenvector numbers */ /* are stored in eignr. */ /* When bFit=FALSE no fitting was used in the covariance analysis. */ @@ -58,10 +68,18 @@ extern void read_eigenvectors(const char *file, int *natoms, gmx_bool *bFit, /* xav is the average/minimum structure is written (t=0). */ /* bDMA indicates mass weighted analysis/eigenvectors. */ -extern void write_eigenvectors(const char *trrname, int natoms, const real mat[], - gmx_bool bReverse, int begin, int end, - int WriteXref, const rvec *xref, gmx_bool bDMR, - const rvec xav[], gmx_bool bDMA, const real *eigval); +extern void write_eigenvectors(const char* trrname, + int natoms, + const real mat[], + gmx_bool bReverse, + int begin, + int end, + int WriteXref, + const rvec* xref, + gmx_bool bDMR, + const rvec xav[], + gmx_bool bDMA, + const real* eigval); /* Write eigenvectors in mat to a TRR file. */ /* The reference structure is written (t=-1) when WriteXref=eWXR_YES. */ /* When WriteXref==eWXR_NOFIT a zero frame is written (t=-1), */ @@ -78,9 +96,6 @@ extern void write_eigenvectors(const char *trrname, int natoms, const real mat[] * and the corresponding indices (start counting on 0) in eigvalnr[]. * Returns the number of values read. */ -int read_eigval (const char * fn, - int nmax, - int eigvalnr[], - real eigval[]); +int read_eigval(const char* fn, int nmax, int eigvalnr[], real eigval[]); #endif diff --git a/src/gromacs/gmxana/fitahx.cpp b/src/gromacs/gmxana/fitahx.cpp index 2d828082a3..98526305f7 100644 --- a/src/gromacs/gmxana/fitahx.cpp +++ b/src/gromacs/gmxana/fitahx.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,7 +47,7 @@ static void my_calc_xcm(int nbb, const int bbind[], rvec x[], rvec xcm) { - int i, m, ai; + int i, m, ai; clear_rvec(xcm); for (i = 0; (i < nbb); i++) @@ -72,15 +72,13 @@ static void my_sub_xcm(int nbb, const int bbind[], rvec x[], rvec xcm) } } -real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], - rvec x[], int nca, - int caindex[], gmx_bool bFit) +real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], rvec x[], int nca, int caindex[], gmx_bool bFit) { - static rvec *xref = nullptr; - static real *mass = nullptr; - const real d = 0.15; /* Rise per residue (nm) */ - const real tw = 1.745; /* Twist per residue (rad) */ - const real rad = 0.23; /* Radius of the helix (nm) */ + static rvec* xref = nullptr; + static real* mass = nullptr; + const real d = 0.15; /* Rise per residue (nm) */ + const real tw = 1.745; /* Twist per residue (rad) */ + const real rad = 0.23; /* Radius of the helix (nm) */ real phi0, trms, rms; rvec dx, xcm; int ai, i, nmass; @@ -99,17 +97,16 @@ real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], for (i = 0; (i < nca); i++) { ai = caindex[i]; - xref[ai][XX] = rad*std::cos(phi0); - xref[ai][YY] = rad*std::sin(phi0); - xref[ai][ZZ] = d*i; + xref[ai][XX] = rad * std::cos(phi0); + xref[ai][YY] = rad * std::sin(phi0); + xref[ai][ZZ] = d * i; /* Set the mass to select that this Calpha contributes to fitting */ mass[ai] = 10.0; /*#define DEBUG*/ #ifdef DEBUG - fprintf(stderr, "%5d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", ai, - x[ai][XX], x[ai][YY], x[ai][ZZ], - xref[ai][XX], xref[ai][YY], xref[ai][ZZ]); + fprintf(stderr, "%5d %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", ai, x[ai][XX], x[ai][YY], + x[ai][ZZ], xref[ai][XX], xref[ai][YY], xref[ai][ZZ]); #endif phi0 += tw; } @@ -156,12 +153,12 @@ real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], if (mass[ai] > 0.0) { rvec_sub(x[ai], xref[ai], dx); - rms = iprod(dx, dx); + rms = iprod(dx, dx); bb[i].rmsa += std::sqrt(rms); bb[i].nrms++; - trms += rms; + trms += rms; mass[ai] = 0.0; } } - return std::sqrt(trms/nca); + return std::sqrt(trms / nca); } diff --git a/src/gromacs/gmxana/fitahx.h b/src/gromacs/gmxana/fitahx.h index 6a1383c49b..f3ffaf5155 100644 --- a/src/gromacs/gmxana/fitahx.h +++ b/src/gromacs/gmxana/fitahx.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,7 +41,6 @@ #include "gromacs/gmxana/hxprops.h" -real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], - rvec x[], int nca, int caindex[], gmx_bool bFit); +real fit_ahx(int nres, t_bb bb[], int natoms, int nall, int allindex[], rvec x[], int nca, int caindex[], gmx_bool bFit); #endif diff --git a/src/gromacs/gmxana/gmx_ana.h b/src/gromacs/gmxana/gmx_ana.h index 3e62f32d54..f40e33e2db 100644 --- a/src/gromacs/gmxana/gmx_ana.h +++ b/src/gromacs/gmxana/gmx_ana.h @@ -36,205 +36,139 @@ */ #ifndef _gmx_ana_h -#define _gmx_ana_h +# define _gmx_ana_h -int -gmx_analyze(int argc, char *argv[]); +int gmx_analyze(int argc, char* argv[]); -int -gmx_anaeig(int argc, char *argv[]); +int gmx_anaeig(int argc, char* argv[]); -int -gmx_awh(int argc, char *argv[]); +int gmx_awh(int argc, char* argv[]); -int -gmx_g_angle(int argc, char *argv[]); +int gmx_g_angle(int argc, char* argv[]); -int -gmx_bar(int argc, char *argv[]); +int gmx_bar(int argc, char* argv[]); -int -gmx_bundle(int argc, char *argv[]); +int gmx_bundle(int argc, char* argv[]); -int -gmx_chi(int argc, char *argv[]); +int gmx_chi(int argc, char* argv[]); -int -gmx_cluster(int argc, char *argv[]); +int gmx_cluster(int argc, char* argv[]); -int -gmx_confrms(int argc, char *argv[]); +int gmx_confrms(int argc, char* argv[]); -int -gmx_covar(int argc, char *argv[]); +int gmx_covar(int argc, char* argv[]); -int -gmx_current(int argc, char *argv[]); +int gmx_current(int argc, char* argv[]); -int -gmx_density(int argc, char *argv[]); +int gmx_density(int argc, char* argv[]); -int -gmx_densmap(int argc, char *argv[]); +int gmx_densmap(int argc, char* argv[]); -int -gmx_densorder(int argc, char *argv[]); +int gmx_densorder(int argc, char* argv[]); -int -gmx_dielectric(int argc, char *argv[]); +int gmx_dielectric(int argc, char* argv[]); -int -gmx_dipoles(int argc, char *argv[]); +int gmx_dipoles(int argc, char* argv[]); -int -gmx_disre(int argc, char *argv[]); +int gmx_disre(int argc, char* argv[]); -int -gmx_do_dssp(int argc, char *argv[]); +int gmx_do_dssp(int argc, char* argv[]); -int -gmx_dos(int argc, char *argv[]); +int gmx_dos(int argc, char* argv[]); -int -gmx_dyecoupl(int argc, char *argv[]); +int gmx_dyecoupl(int argc, char* argv[]); -int -gmx_enemat(int argc, char *argv[]); +int gmx_enemat(int argc, char* argv[]); -int -gmx_energy(int argc, char *argv[]); +int gmx_energy(int argc, char* argv[]); -int -gmx_lie(int argc, char *argv[]); +int gmx_lie(int argc, char* argv[]); -int -gmx_filter(int argc, char *argv[]); +int gmx_filter(int argc, char* argv[]); -int -gmx_gyrate(int argc, char *argv[]); +int gmx_gyrate(int argc, char* argv[]); -int -gmx_h2order(int argc, char *argv[]); +int gmx_h2order(int argc, char* argv[]); -int -gmx_hbond(int argc, char *argv[]); +int gmx_hbond(int argc, char* argv[]); -int -gmx_helix(int argc, char *argv[]); +int gmx_helix(int argc, char* argv[]); -int -gmx_helixorient(int argc, char *argv[]); +int gmx_helixorient(int argc, char* argv[]); -int -gmx_hydorder(int argc, char *argv[]); +int gmx_hydorder(int argc, char* argv[]); -int -gmx_make_edi(int argc, char *argv[]); +int gmx_make_edi(int argc, char* argv[]); -int -gmx_mindist(int argc, char *argv[]); +int gmx_mindist(int argc, char* argv[]); -int -gmx_msd(int argc, char *argv[]); +int gmx_msd(int argc, char* argv[]); -int -gmx_nmeig(int argc, char *argv[]); +int gmx_nmeig(int argc, char* argv[]); -int -gmx_nmens(int argc, char *argv[]); +int gmx_nmens(int argc, char* argv[]); -int -gmx_nmr(int argc, char *argv[]); +int gmx_nmr(int argc, char* argv[]); -int -gmx_nmtraj(int argc, char *argv[]); +int gmx_nmtraj(int argc, char* argv[]); -int -gmx_order(int argc, char *argv[]); +int gmx_order(int argc, char* argv[]); -int -gmx_polystat(int argc, char *argv[]); +int gmx_polystat(int argc, char* argv[]); -int -gmx_potential(int argc, char *argv[]); +int gmx_potential(int argc, char* argv[]); -int -gmx_principal(int argc, char *argv[]); +int gmx_principal(int argc, char* argv[]); -int -gmx_rama(int argc, char *argv[]); +int gmx_rama(int argc, char* argv[]); -int -gmx_rotmat(int argc, char *argv[]); +int gmx_rotmat(int argc, char* argv[]); -int -gmx_rms(int argc, char *argv[]); +int gmx_rms(int argc, char* argv[]); -int -gmx_rmsdist(int argc, char *argv[]); +int gmx_rmsdist(int argc, char* argv[]); -int -gmx_rmsf(int argc, char *argv[]); +int gmx_rmsf(int argc, char* argv[]); -int -gmx_rotacf(int argc, char *argv[]); +int gmx_rotacf(int argc, char* argv[]); -int -gmx_saltbr(int argc, char *argv[]); +int gmx_saltbr(int argc, char* argv[]); -int -gmx_sham(int argc, char *argv[]); +int gmx_sham(int argc, char* argv[]); -int -gmx_sigeps(int argc, char *argv[]); +int gmx_sigeps(int argc, char* argv[]); -int -gmx_sorient(int argc, char *argv[]); +int gmx_sorient(int argc, char* argv[]); -int -gmx_spol(int argc, char *argv[]); +int gmx_spol(int argc, char* argv[]); -int -gmx_spatial(int argc, char *argv[]); +int gmx_spatial(int argc, char* argv[]); -int -gmx_tcaf(int argc, char *argv[]); +int gmx_tcaf(int argc, char* argv[]); -int -gmx_traj(int argc, char *argv[]); +int gmx_traj(int argc, char* argv[]); -int -gmx_trjorder(int argc, char *argv[]); +int gmx_trjorder(int argc, char* argv[]); -int -gmx_velacc(int argc, char *argv[]); +int gmx_velacc(int argc, char* argv[]); -int -gmx_clustsize(int argc, char *argv[]); +int gmx_clustsize(int argc, char* argv[]); -int -gmx_mdmat(int argc, char *argv[]); +int gmx_mdmat(int argc, char* argv[]); -int -gmx_vanhove(int argc, char *argv[]); +int gmx_vanhove(int argc, char* argv[]); -int -gmx_wham(int argc, char *argv[]); +int gmx_wham(int argc, char* argv[]); -int -gmx_wheel(int argc, char *argv[]); +int gmx_wheel(int argc, char* argv[]); -int -gmx_xpm2ps(int argc, char *argv[]); +int gmx_xpm2ps(int argc, char* argv[]); -int -gmx_membed(int argc, char *argv[]); +int gmx_membed(int argc, char* argv[]); -int -gmx_sans(int argc, char *argv[]); +int gmx_sans(int argc, char* argv[]); -int -gmx_saxs(int argc, char *argv[]); +int gmx_saxs(int argc, char* argv[]); #endif /* _gmx_ana_h */ diff --git a/src/gromacs/gmxana/gmx_anaeig.cpp b/src/gromacs/gmxana/gmx_anaeig.cpp index 0609301b50..319d069673 100644 --- a/src/gromacs/gmxana/gmx_anaeig.cpp +++ b/src/gromacs/gmxana/gmx_anaeig.cpp @@ -69,7 +69,7 @@ #include "thermochemistry.h" -static const char *proj_unit; +static const char* proj_unit; static real tick_spacing(real range, int minticks) { @@ -80,23 +80,32 @@ static real tick_spacing(real range, int minticks) return 1.0; } - sp = 0.2*std::exp(std::log(10.0)*std::ceil(std::log(range)/std::log(10.0))); - while (range/sp < minticks-1) + sp = 0.2 * std::exp(std::log(10.0) * std::ceil(std::log(range) / std::log(10.0))); + while (range / sp < minticks - 1) { - sp = sp/2; + sp = sp / 2; } return sp; } -static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, - const char *title, const char *subtitle, - const std::string &xlabel, const char **ylabel, - int n, real *x, real **y, real ***sy, - real scale_x, gmx_bool bZero, gmx_bool bSplit, - const gmx_output_env_t *oenv) +static void write_xvgr_graphs(const char* file, + int ngraphs, + int nsetspergraph, + const char* title, + const char* subtitle, + const std::string& xlabel, + const char** ylabel, + int n, + real* x, + real** y, + real*** sy, + real scale_x, + gmx_bool bZero, + gmx_bool bSplit, + const gmx_output_env_t* oenv) { - FILE *out; + FILE* out; int g, s, i; real ymin, ymax, xsp, ysp; @@ -149,11 +158,11 @@ static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, } else { - ymin = ymin-0.1*(ymax-ymin); + ymin = ymin - 0.1 * (ymax - ymin); } - ymax = ymax+0.1*(ymax-ymin); - xsp = tick_spacing((x[n-1]-x[0])*scale_x, 4); - ysp = tick_spacing(ymax-ymin, 3); + ymax = ymax + 0.1 * (ymax - ymin); + xsp = tick_spacing((x[n - 1] - x[0]) * scale_x, 4); + ysp = tick_spacing(ymax - ymin, 3); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(out, "@ with g%d\n@ g%d on\n", g, g); @@ -165,7 +174,7 @@ static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, fprintf(out, "@ subtitle \"%s\"\n", subtitle); } } - if (g == ngraphs-1) + if (g == ngraphs - 1) { fprintf(out, "@ xaxis label \"%s\"\n", xlabel.c_str()); } @@ -175,24 +184,24 @@ static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, } if (n > 1) { - fprintf(out, "@ world xmin %g\n", x[0]*scale_x); - fprintf(out, "@ world xmax %g\n", x[n-1]*scale_x); + fprintf(out, "@ world xmin %g\n", x[0] * scale_x); + fprintf(out, "@ world xmax %g\n", x[n - 1] * scale_x); fprintf(out, "@ world ymin %g\n", ymin); fprintf(out, "@ world ymax %g\n", ymax); } fprintf(out, "@ view xmin 0.15\n"); fprintf(out, "@ view xmax 0.85\n"); - fprintf(out, "@ view ymin %g\n", 0.15+(ngraphs-1-g)*0.7/ngraphs); - fprintf(out, "@ view ymax %g\n", 0.15+(ngraphs-g)*0.7/ngraphs); + fprintf(out, "@ view ymin %g\n", 0.15 + (ngraphs - 1 - g) * 0.7 / ngraphs); + fprintf(out, "@ view ymax %g\n", 0.15 + (ngraphs - g) * 0.7 / ngraphs); fprintf(out, "@ yaxis label \"%s\"\n", ylabel[g]); fprintf(out, "@ xaxis tick major %g\n", xsp); - fprintf(out, "@ xaxis tick minor %g\n", xsp/2); + fprintf(out, "@ xaxis tick minor %g\n", xsp / 2); fprintf(out, "@ xaxis ticklabel start type spec\n"); - fprintf(out, "@ xaxis ticklabel start %g\n", std::ceil(ymin/xsp)*xsp); + fprintf(out, "@ xaxis ticklabel start %g\n", std::ceil(ymin / xsp) * xsp); fprintf(out, "@ yaxis tick major %g\n", ysp); - fprintf(out, "@ yaxis tick minor %g\n", ysp/2); + fprintf(out, "@ yaxis tick minor %g\n", ysp / 2); fprintf(out, "@ yaxis ticklabel start type spec\n"); - fprintf(out, "@ yaxis ticklabel start %g\n", std::ceil(ymin/ysp)*ysp); + fprintf(out, "@ yaxis ticklabel start %g\n", std::ceil(ymin / ysp) * ysp); if ((ymin < 0) && (ymax > 0)) { fprintf(out, "@ zeroxaxis bar on\n"); @@ -207,8 +216,7 @@ static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, { fprintf(out, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } - fprintf(out, "%10.4f %10.5f\n", - x[i]*scale_x, y ? y[g][i] : sy[g][s][i]); + fprintf(out, "%10.4f %10.5f\n", x[i] * scale_x, y ? y[g][i] : sy[g][s][i]); } fprintf(out, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } @@ -217,8 +225,7 @@ static void write_xvgr_graphs(const char *file, int ngraphs, int nsetspergraph, } static void -compare(int natoms, int n1, rvec **eigvec1, int n2, rvec **eigvec2, - real *eigval1, int neig1, real *eigval2, int neig2) +compare(int natoms, int n1, rvec** eigvec1, int n2, rvec** eigvec2, real* eigval1, int neig1, real* eigval2, int neig2) { int n; int i, j, k; @@ -236,7 +243,7 @@ compare(int natoms, int n1, rvec **eigvec1, int n2, rvec **eigvec2, { eigval1[i] = 0; } - sum1 += eigval1[i]; + sum1 += eigval1[i]; eigval1[i] = std::sqrt(eigval1[i]); } trace1 = sum1; @@ -251,7 +258,7 @@ compare(int natoms, int n1, rvec **eigvec1, int n2, rvec **eigvec2, { eigval2[i] = 0; } - sum2 += eigval2[i]; + sum2 += eigval2[i]; eigval2[i] = std::sqrt(eigval2[i]); } trace2 = sum2; @@ -273,10 +280,9 @@ compare(int natoms, int n1, rvec **eigvec1, int n2, rvec **eigvec2, if (neig1 != n || neig2 != n) { fprintf(stdout, "this is %d%% and %d%% of the total trace\n", - gmx::roundToInt(100*sum1/trace1), gmx::roundToInt(100*sum2/trace2)); + gmx::roundToInt(100 * sum1 / trace1), gmx::roundToInt(100 * sum2 / trace2)); } - fprintf(stdout, "Square root of the traces: %g and %g\n", - std::sqrt(sum1), std::sqrt(sum2)); + fprintf(stdout, "Square root of the traces: %g and %g\n", std::sqrt(sum1), std::sqrt(sum2)); sab = 0; for (i = 0; i < n; i++) @@ -289,39 +295,46 @@ compare(int natoms, int n1, rvec **eigvec1, int n2, rvec **eigvec2, { ip += iprod(eigvec1[i][k], eigvec2[j][k]); } - tmp += eigval2[j]*ip*ip; + tmp += eigval2[j] * ip * ip; } - sab += eigval1[i]*tmp; + sab += eigval1[i] * tmp; } - samsb2 = sum1+sum2-2*sab; + samsb2 = sum1 + sum2 - 2 * sab; if (samsb2 < 0) { samsb2 = 0; } fprintf(stdout, "The overlap of the covariance matrices:\n"); - fprintf(stdout, " normalized: %.3f\n", 1-std::sqrt(samsb2/(sum1+sum2))); - tmp = 1-sab/std::sqrt(sum1*sum2); + fprintf(stdout, " normalized: %.3f\n", 1 - std::sqrt(samsb2 / (sum1 + sum2))); + tmp = 1 - sab / std::sqrt(sum1 * sum2); if (tmp < 0) { tmp = 0; } - fprintf(stdout, " shape: %.3f\n", 1-std::sqrt(tmp)); + fprintf(stdout, " shape: %.3f\n", 1 - std::sqrt(tmp)); } -static void inprod_matrix(const char *matfile, int natoms, - int nvec1, int *eignr1, rvec **eigvec1, - int nvec2, const int *eignr2, rvec **eigvec2, - gmx_bool bSelect, int noutvec, const int *outvec) +static void inprod_matrix(const char* matfile, + int natoms, + int nvec1, + int* eignr1, + rvec** eigvec1, + int nvec2, + const int* eignr2, + rvec** eigvec2, + gmx_bool bSelect, + int noutvec, + const int* outvec) { - FILE *out; - real **mat; - int i, x1, y1, x, y, nlevels; - int nx, ny; - real inp, *t_x, *t_y, maxval; - t_rgb rlo, rhi; + FILE* out; + real** mat; + int i, x1, y1, x, y, nlevels; + int nx, ny; + real inp, *t_x, *t_y, maxval; + t_rgb rlo, rhi; snew(t_y, nvec2); if (bSelect) @@ -332,7 +345,7 @@ static void inprod_matrix(const char *matfile, int natoms, { if (outvec[y1] < nvec2) { - t_y[ny] = eignr2[outvec[y1]]+1; + t_y[ny] = eignr2[outvec[y1]] + 1; ny++; } } @@ -343,12 +356,11 @@ static void inprod_matrix(const char *matfile, int natoms, ny = nvec2; for (y = 0; y < ny; y++) { - t_y[y] = eignr2[y]+1; + t_y[y] = eignr2[y] + 1; } } - fprintf(stderr, "Calculating inner-product matrix of %dx%d eigenvectors\n", - nx, nvec2); + fprintf(stderr, "Calculating inner-product matrix of %dx%d eigenvectors\n", nx, nvec2); snew(mat, nx); snew(t_x, nx); @@ -364,8 +376,8 @@ static void inprod_matrix(const char *matfile, int natoms, { x = x1; } - t_x[x1] = eignr1[x]+1; - fprintf(stderr, " %d", eignr1[x]+1); + t_x[x1] = eignr1[x] + 1; + fprintf(stderr, " %d", eignr1[x] + 1); for (y1 = 0; y1 < ny; y1++) { inp = 0; @@ -393,34 +405,41 @@ static void inprod_matrix(const char *matfile, int natoms, } } fprintf(stderr, "\n"); - rlo.r = 1; rlo.g = 1; rlo.b = 1; - rhi.r = 0; rhi.g = 0; rhi.b = 0; + rlo.r = 1; + rlo.g = 1; + rlo.b = 1; + rhi.r = 0; + rhi.g = 0; + rhi.b = 0; nlevels = 41; out = gmx_ffopen(matfile, "w"); - write_xpm(out, 0, "Eigenvector inner-products", "in.prod.", "run 1", "run 2", - nx, ny, t_x, t_y, mat, 0.0, maxval, rlo, rhi, &nlevels); + write_xpm(out, 0, "Eigenvector inner-products", "in.prod.", "run 1", "run 2", nx, ny, t_x, t_y, + mat, 0.0, maxval, rlo, rhi, &nlevels); gmx_ffclose(out); } -static void overlap(const char *outfile, int natoms, - rvec **eigvec1, - int nvec2, int *eignr2, rvec **eigvec2, - int noutvec, int *outvec, - const gmx_output_env_t *oenv) +static void overlap(const char* outfile, + int natoms, + rvec** eigvec1, + int nvec2, + int* eignr2, + rvec** eigvec2, + int noutvec, + int* outvec, + const gmx_output_env_t* oenv) { - FILE *out; + FILE* out; int i, v, vec, x; real overlap, inp; fprintf(stderr, "Calculating overlap between eigenvectors of set 2 with eigenvectors\n"); for (i = 0; i < noutvec; i++) { - fprintf(stderr, "%d ", outvec[i]+1); + fprintf(stderr, "%d ", outvec[i] + 1); } fprintf(stderr, "\n"); - out = xvgropen(outfile, "Subspace overlap", - "Eigenvectors of trajectory 2", "Overlap", oenv); + out = xvgropen(outfile, "Subspace overlap", "Eigenvectors of trajectory 2", "Overlap", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(out, "@ subtitle \"using %d eigenvectors of trajectory 1\"\n", noutvec); @@ -438,35 +457,54 @@ static void overlap(const char *outfile, int natoms, } overlap += gmx::square(inp); } - fprintf(out, "%5d %5.3f\n", eignr2[x]+1, overlap/noutvec); + fprintf(out, "%5d %5.3f\n", eignr2[x] + 1, overlap / noutvec); } xvgrclose(out); } -static void project(const char *trajfile, const t_topology *top, int ePBC, matrix topbox, - const char *projfile, const char *twodplotfile, - const char *threedplotfile, const char *filterfile, int skip, - const char *extremefile, gmx_bool bExtrAll, real extreme, - int nextr, const t_atoms *atoms, int natoms, int *index, - gmx_bool bFit, rvec *xref, int nfit, int *ifit, real *w_rls, - const real *sqrtm, rvec *xav, - int *eignr, rvec **eigvec, - int noutvec, int *outvec, gmx_bool bSplit, - const gmx_output_env_t *oenv) +static void project(const char* trajfile, + const t_topology* top, + int ePBC, + matrix topbox, + const char* projfile, + const char* twodplotfile, + const char* threedplotfile, + const char* filterfile, + int skip, + const char* extremefile, + gmx_bool bExtrAll, + real extreme, + int nextr, + const t_atoms* atoms, + int natoms, + int* index, + gmx_bool bFit, + rvec* xref, + int nfit, + int* ifit, + real* w_rls, + const real* sqrtm, + rvec* xav, + int* eignr, + rvec** eigvec, + int noutvec, + int* outvec, + gmx_bool bSplit, + const gmx_output_env_t* oenv) { - FILE *xvgrout = nullptr; + FILE* xvgrout = nullptr; int nat, i, j, d, v, vec, nfr, nframes = 0, snew_size, frame; - t_trxstatus *out = nullptr; - t_trxstatus *status; + t_trxstatus* out = nullptr; + t_trxstatus* status; int noutvec_extr, imin, imax; - real *pmin, *pmax; - int *all_at; + real * pmin, *pmax; + int* all_at; matrix box; - rvec *xread, *x; + rvec * xread, *x; real t, inp, **inprod = nullptr; char str[STRLEN], str2[STRLEN], *c; - const char **ylabel; + const char** ylabel; real fact; gmx_rmpbc_t gpbc = nullptr; @@ -484,15 +522,14 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri if (trajfile) { - snew(inprod, noutvec+1); + snew(inprod, noutvec + 1); if (filterfile) { - fprintf(stderr, "Writing a filtered trajectory to %s using eigenvectors\n", - filterfile); + fprintf(stderr, "Writing a filtered trajectory to %s using eigenvectors\n", filterfile); for (i = 0; i < noutvec; i++) { - fprintf(stderr, "%d ", outvec[i]+1); + fprintf(stderr, "%d ", outvec[i] + 1); } fprintf(stderr, "\n"); out = open_trx(filterfile, "w"); @@ -503,7 +540,10 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri nat = read_first_x(oenv, &status, trajfile, &t, &xread, box); if (nat > atoms->nr) { - gmx_fatal(FARGS, "the number of atoms in your trajectory (%d) is larger than the number of atoms in your structure file (%d)", nat, atoms->nr); + gmx_fatal(FARGS, + "the number of atoms in your trajectory (%d) is larger than the number of " + "atoms in your structure file (%d)", + nat, atoms->nr); } snew(all_at, nat); @@ -527,7 +567,7 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri if (nframes >= snew_size) { snew_size += 100; - for (i = 0; i < noutvec+1; i++) + for (i = 0; i < noutvec + 1; i++) { srenew(inprod[i], snew_size); } @@ -551,9 +591,10 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri inp = 0; for (i = 0; i < natoms; i++) { - inp += (eigvec[vec][i][0]*(x[i][0]-xav[i][0])+ - eigvec[vec][i][1]*(x[i][1]-xav[i][1])+ - eigvec[vec][i][2]*(x[i][2]-xav[i][2]))*sqrtm[i]; + inp += (eigvec[vec][i][0] * (x[i][0] - xav[i][0]) + + eigvec[vec][i][1] * (x[i][1] - xav[i][1]) + + eigvec[vec][i][2] * (x[i][2] - xav[i][2])) + * sqrtm[i]; } inprod[v][nframes] = inp; } @@ -568,7 +609,7 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri for (v = 0; v < noutvec; v++) { xread[index[i]][d] += - inprod[v][nframes]*eigvec[outvec[v]][i][d]/sqrtm[i]; + inprod[v][nframes] * eigvec[outvec[v]][i][d] / sqrtm[i]; } } } @@ -577,8 +618,7 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri nframes++; } nfr++; - } - while (read_next_x(oenv, status, &t, xread, box)); + } while (read_next_x(oenv, status, &t, xread, box)); close_trx(status); sfree(x); if (filterfile) @@ -603,44 +643,40 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri snew(ylabel, noutvec); for (v = 0; v < noutvec; v++) { - sprintf(str, "vec %d", eignr[outvec[v]]+1); + sprintf(str, "vec %d", eignr[outvec[v]] + 1); ylabel[v] = gmx_strdup(str); } sprintf(str, "projection on eigenvectors (%s)", proj_unit); write_xvgr_graphs(projfile, noutvec, 1, str, nullptr, output_env_get_xvgr_tlabel(oenv), - ylabel, - nframes, inprod[noutvec], inprod, nullptr, + ylabel, nframes, inprod[noutvec], inprod, nullptr, output_env_get_time_factor(oenv), FALSE, bSplit, oenv); } if (twodplotfile) { - sprintf(str, "projection on eigenvector %d (%s)", - eignr[outvec[0]]+1, proj_unit); - sprintf(str2, "projection on eigenvector %d (%s)", - eignr[outvec[noutvec-1]]+1, proj_unit); - xvgrout = xvgropen(twodplotfile, "2D projection of trajectory", str, str2, - oenv); + sprintf(str, "projection on eigenvector %d (%s)", eignr[outvec[0]] + 1, proj_unit); + sprintf(str2, "projection on eigenvector %d (%s)", eignr[outvec[noutvec - 1]] + 1, proj_unit); + xvgrout = xvgropen(twodplotfile, "2D projection of trajectory", str, str2, oenv); for (i = 0; i < nframes; i++) { if (bSplit && i > 0 && std::abs(inprod[noutvec][i]) < 1e-5) { fprintf(xvgrout, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } - fprintf(xvgrout, "%10.5f %10.5f\n", inprod[0][i], inprod[noutvec-1][i]); + fprintf(xvgrout, "%10.5f %10.5f\n", inprod[0][i], inprod[noutvec - 1][i]); } xvgrclose(xvgrout); } if (threedplotfile) { - t_atoms atoms; - rvec *x; - real *b = nullptr; - matrix box; - char *resnm, *atnm; - gmx_bool bPDB, b4D; - FILE *out; + t_atoms atoms; + rvec* x; + real* b = nullptr; + matrix box; + char * resnm, *atnm; + gmx_bool bPDB, b4D; + FILE* out; if (noutvec < 3) { @@ -655,17 +691,17 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri b4D = bPDB && (noutvec >= 4); if (b4D) { - fprintf(stderr, "You have selected four or more eigenvectors:\n" + fprintf(stderr, + "You have selected four or more eigenvectors:\n" "fourth eigenvector will be plotted " "in bfactor field of pdb file\n"); - sprintf(str, "4D proj. of traj. on eigenv. %d, %d, %d and %d", - eignr[outvec[0]]+1, eignr[outvec[1]]+1, - eignr[outvec[2]]+1, eignr[outvec[3]]+1); + sprintf(str, "4D proj. of traj. on eigenv. %d, %d, %d and %d", eignr[outvec[0]] + 1, + eignr[outvec[1]] + 1, eignr[outvec[2]] + 1, eignr[outvec[3]] + 1); } else { - sprintf(str, "3D proj. of traj. on eigenv. %d, %d and %d", - eignr[outvec[0]]+1, eignr[outvec[1]]+1, eignr[outvec[2]]+1); + sprintf(str, "3D proj. of traj. on eigenv. %d, %d and %d", eignr[outvec[0]] + 1, + eignr[outvec[1]] + 1, eignr[outvec[2]] + 1); } init_t_atoms(&atoms, nframes, FALSE); snew(x, nframes); @@ -675,7 +711,7 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri if (nframes > 10000) { - fact = 10000.0/nframes; + fact = 10000.0 / nframes; } else { @@ -687,19 +723,20 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri atoms.atomname[i] = &atnm; atoms.atom[i].resind = i; atoms.resinfo[i].name = &resnm; - atoms.resinfo[i].nr = static_cast(std::ceil(i*fact)); + atoms.resinfo[i].nr = static_cast(std::ceil(i * fact)); atoms.resinfo[i].ic = ' '; x[i][XX] = inprod[0][i]; x[i][YY] = inprod[1][i]; x[i][ZZ] = inprod[2][i]; if (b4D) { - b[i] = inprod[3][i]; + b[i] = inprod[3][i]; } } - if ( ( b4D || bSplit ) && bPDB) + if ((b4D || bSplit) && bPDB) { - GMX_RELEASE_ASSERT(inprod != nullptr, "inprod must be non-NULL with 4D or split PDB output options"); + GMX_RELEASE_ASSERT(inprod != nullptr, + "inprod must be non-NULL with 4D or split PDB output options"); out = gmx_ffopen(threedplotfile, "w"); fprintf(out, "HEADER %s\n", str); @@ -715,11 +752,12 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri fprintf(out, "TER\n"); j = 0; } - gmx_fprintf_pdb_atomline(out, epdbATOM, i+1, "C", ' ', "PRJ", ' ', j+1, ' ', - 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, 10*b[i], ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, i + 1, "C", ' ', "PRJ", ' ', j + 1, ' ', + 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, + 10 * b[i], ""); if (j > 0) { - fprintf(out, "CONECT%5d%5d\n", i, i+1); + fprintf(out, "CONECT%5d%5d\n", i, i + 1); } j++; } @@ -741,8 +779,7 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri { GMX_RELEASE_ASSERT(inprod != nullptr, "inprod must be non-NULL"); fprintf(stderr, "%11s %17s %17s\n", "eigenvector", "Minimum", "Maximum"); - fprintf(stderr, - "%11s %10s %10s %10s %10s\n", "", "value", "frame", "value", "frame"); + fprintf(stderr, "%11s %10s %10s %10s %10s\n", "", "value", "frame", "value", "frame"); imin = 0; imax = 0; for (v = 0; v < noutvec_extr; v++) @@ -760,15 +797,14 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri } pmin[v] = inprod[v][imin]; pmax[v] = inprod[v][imax]; - fprintf(stderr, "%7d %10.6f %10d %10.6f %10d\n", - eignr[outvec[v]]+1, - pmin[v], imin, pmax[v], imax); + fprintf(stderr, "%7d %10.6f %10d %10.6f %10d\n", eignr[outvec[v]] + 1, pmin[v], + imin, pmax[v], imax); } } else { pmin[0] = -extreme; - pmax[0] = extreme; + pmax[0] = extreme; } /* build format string for filename: */ std::strcpy(str, extremefile); /* copy filename */ @@ -784,10 +820,9 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri } else { - sprintf(str2, str, eignr[outvec[v]]+1); + sprintf(str2, str, eignr[outvec[v]] + 1); } - fprintf(stderr, "Writing %d frames along eigenvector %d to %s\n", - nextr, outvec[v]+1, str2); + fprintf(stderr, "Writing %d frames along eigenvector %d to %s\n", nextr, outvec[v] + 1, str2); out = open_trx(str2, "w"); for (frame = 0; frame < nextr; frame++) { @@ -803,8 +838,9 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri for (d = 0; d < DIM; d++) { xread[index[i]][d] = - (xav[i][d] + (pmin[v]*(nextr-frame-1)+pmax[v]*frame)/(nextr-1) - *eigvec[outvec[v]][i][d]/sqrtm[i]); + (xav[i][d] + + (pmin[v] * (nextr - frame - 1) + pmax[v] * frame) / (nextr - 1) + * eigvec[outvec[v]][i][d] / sqrtm[i]); } } write_trx(out, natoms, index, atoms, 0, frame, topbox, xread, nullptr, nullptr); @@ -817,15 +853,18 @@ static void project(const char *trajfile, const t_topology *top, int ePBC, matri fprintf(stderr, "\n"); } -static void components(const char *outfile, int natoms, - int *eignr, rvec **eigvec, - int noutvec, const int *outvec, - const gmx_output_env_t *oenv) +static void components(const char* outfile, + int natoms, + int* eignr, + rvec** eigvec, + int noutvec, + const int* outvec, + const gmx_output_env_t* oenv) { - int g, s, v, i; - real *x, ***y; - char str[STRLEN]; - const char**ylabel; + int g, s, v, i; + real * x, ***y; + char str[STRLEN]; + const char** ylabel; fprintf(stderr, "Writing eigenvector components to %s\n", outfile); @@ -834,12 +873,12 @@ static void components(const char *outfile, int natoms, snew(x, natoms); for (i = 0; i < natoms; i++) { - x[i] = i+1; + x[i] = i + 1; } for (g = 0; g < noutvec; g++) { v = outvec[g]; - sprintf(str, "vec %d", eignr[v]+1); + sprintf(str, "vec %d", eignr[v] + 1); ylabel[g] = gmx_strdup(str); snew(y[g], 4); for (s = 0; s < 4; s++) @@ -851,27 +890,31 @@ static void components(const char *outfile, int natoms, y[g][0][i] = norm(eigvec[v][i]); for (s = 0; s < 3; s++) { - y[g][s+1][i] = eigvec[v][i][s]; + y[g][s + 1][i] = eigvec[v][i][s]; } } } write_xvgr_graphs(outfile, noutvec, 4, "Eigenvector components", - "black: total, red: x, green: y, blue: z", - "Atom number", ylabel, - natoms, x, nullptr, y, 1, FALSE, FALSE, oenv); + "black: total, red: x, green: y, blue: z", "Atom number", ylabel, natoms, x, + nullptr, y, 1, FALSE, FALSE, oenv); fprintf(stderr, "\n"); } -static void rmsf(const char *outfile, int natoms, const real *sqrtm, - int *eignr, rvec **eigvec, - int noutvec, const int *outvec, - real *eigval, int neig, - const gmx_output_env_t *oenv) +static void rmsf(const char* outfile, + int natoms, + const real* sqrtm, + int* eignr, + rvec** eigvec, + int noutvec, + const int* outvec, + real* eigval, + int neig, + const gmx_output_env_t* oenv) { int g, v, i; - real *x, **y; + real * x, **y; char str[STRLEN]; - const char **ylabel; + const char** ylabel; for (i = 0; i < neig; i++) { @@ -888,32 +931,32 @@ static void rmsf(const char *outfile, int natoms, const real *sqrtm, snew(x, natoms); for (i = 0; i < natoms; i++) { - x[i] = i+1; + x[i] = i + 1; } for (g = 0; g < noutvec; g++) { v = outvec[g]; if (eignr[v] >= neig) { - gmx_fatal(FARGS, "Selected vector %d is larger than the number of eigenvalues (%d)", eignr[v]+1, neig); + gmx_fatal(FARGS, "Selected vector %d is larger than the number of eigenvalues (%d)", + eignr[v] + 1, neig); } - sprintf(str, "vec %d", eignr[v]+1); + sprintf(str, "vec %d", eignr[v] + 1); ylabel[g] = gmx_strdup(str); snew(y[g], natoms); for (i = 0; i < natoms; i++) { - y[g][i] = std::sqrt(eigval[eignr[v]]*norm2(eigvec[v][i]))/sqrtm[i]; + y[g][i] = std::sqrt(eigval[eignr[v]] * norm2(eigvec[v][i])) / sqrtm[i]; } } - write_xvgr_graphs(outfile, noutvec, 1, "RMS fluctuation (nm) ", nullptr, - "Atom number", ylabel, + write_xvgr_graphs(outfile, noutvec, 1, "RMS fluctuation (nm) ", nullptr, "Atom number", ylabel, natoms, x, y, nullptr, 1, TRUE, FALSE, oenv); fprintf(stderr, "\n"); } -int gmx_anaeig(int argc, char *argv[]) +int gmx_anaeig(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] analyzes eigenvectors. The eigenvectors can be of a", "covariance matrix ([gmx-covar]) or of a Normal Modes analysis", "([gmx-nmeig]).[PAR]", @@ -992,128 +1035,126 @@ int gmx_anaeig(int argc, char *argv[]) "computed based on the Quasiharmonic approach and based on", "Schlitter's formula." }; - static int first = 1, last = -1, skip = 1, nextr = 2, nskip = 6; - static real max = 0.0, temp = 298.15; - static gmx_bool bSplit = FALSE, bEntropy = FALSE; - t_pargs pa[] = { - { "-first", FALSE, etINT, {&first}, - "First eigenvector for analysis (-1 is select)" }, - { "-last", FALSE, etINT, {&last}, - "Last eigenvector for analysis (-1 is till the last)" }, - { "-skip", FALSE, etINT, {&skip}, - "Only analyse every nr-th frame" }, - { "-max", FALSE, etREAL, {&max}, + static int first = 1, last = -1, skip = 1, nextr = 2, nskip = 6; + static real max = 0.0, temp = 298.15; + static gmx_bool bSplit = FALSE, bEntropy = FALSE; + t_pargs pa[] = { + { "-first", FALSE, etINT, { &first }, "First eigenvector for analysis (-1 is select)" }, + { "-last", FALSE, etINT, { &last }, "Last eigenvector for analysis (-1 is till the last)" }, + { "-skip", FALSE, etINT, { &skip }, "Only analyse every nr-th frame" }, + { "-max", + FALSE, + etREAL, + { &max }, "Maximum for projection of the eigenvector on the average structure, " "max=0 gives the extremes" }, - { "-nframes", FALSE, etINT, {&nextr}, - "Number of frames for the extremes output" }, - { "-split", FALSE, etBOOL, {&bSplit}, - "Split eigenvector projections where time is zero" }, - { "-entropy", FALSE, etBOOL, {&bEntropy}, + { "-nframes", FALSE, etINT, { &nextr }, "Number of frames for the extremes output" }, + { "-split", FALSE, etBOOL, { &bSplit }, "Split eigenvector projections where time is zero" }, + { "-entropy", + FALSE, + etBOOL, + { &bEntropy }, "Compute entropy according to the Quasiharmonic formula or Schlitter's method." }, - { "-temp", FALSE, etREAL, {&temp}, - "Temperature for entropy calculations" }, - { "-nevskip", FALSE, etINT, {&nskip}, - "Number of eigenvalues to skip when computing the entropy due to the quasi harmonic approximation. When you do a rotational and/or translational fit prior to the covariance analysis, you get 3 or 6 eigenvalues that are very close to zero, and which should not be taken into account when computing the entropy." } + { "-temp", FALSE, etREAL, { &temp }, "Temperature for entropy calculations" }, + { "-nevskip", + FALSE, + etINT, + { &nskip }, + "Number of eigenvalues to skip when computing the entropy due to the quasi harmonic " + "approximation. When you do a rotational and/or translational fit prior to the " + "covariance analysis, you get 3 or 6 eigenvalues that are very close to zero, and which " + "should not be taken into account when computing the entropy." } }; #define NPA asize(pa) t_topology top; int ePBC = -1; - const t_atoms *atoms = nullptr; - rvec *xtop, *xref1, *xref2, *xrefp = nullptr; + const t_atoms* atoms = nullptr; + rvec * xtop, *xref1, *xref2, *xrefp = nullptr; gmx_bool bDMR1, bDMA1, bDMR2, bDMA2; int nvec1, nvec2, *eignr1 = nullptr, *eignr2 = nullptr; - rvec *xav1, *xav2, **eigvec1 = nullptr, **eigvec2 = nullptr; + rvec * xav1, *xav2, **eigvec1 = nullptr, **eigvec2 = nullptr; matrix topbox; real totmass, *sqrtm, *w_rls, t; int natoms; - char *grpname; - const char *indexfile; + char* grpname; + const char* indexfile; int i, j, d; int nout, *iout, noutvec, *outvec, nfit; - int *index = nullptr, *ifit = nullptr; - const char *VecFile, *Vec2File, *topfile; - const char *EigFile, *Eig2File; - const char *CompFile, *RmsfFile, *ProjOnVecFile; - const char *TwoDPlotFile, *ThreeDPlotFile; - const char *FilterFile, *ExtremeFile; - const char *OverlapFile, *InpMatFile; + int * index = nullptr, *ifit = nullptr; + const char * VecFile, *Vec2File, *topfile; + const char * EigFile, *Eig2File; + const char * CompFile, *RmsfFile, *ProjOnVecFile; + const char * TwoDPlotFile, *ThreeDPlotFile; + const char * FilterFile, *ExtremeFile; + const char * OverlapFile, *InpMatFile; gmx_bool bFit1, bFit2, bM, bIndex, bTPS, bTop, bVec2, bProj; gmx_bool bFirstToLast, bFirstLastSet, bTraj, bCompare, bPDB3D; - real *eigval1 = nullptr, *eigval2 = nullptr; + real * eigval1 = nullptr, *eigval2 = nullptr; int neig1, neig2; - double **xvgdata; - gmx_output_env_t *oenv; + double** xvgdata; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc; - t_filenm fnm[] = { - { efTRN, "-v", "eigenvec", ffREAD }, - { efTRN, "-v2", "eigenvec2", ffOPTRD }, - { efTRX, "-f", nullptr, ffOPTRD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-eig", "eigenval", ffOPTRD }, - { efXVG, "-eig2", "eigenval2", ffOPTRD }, - { efXVG, "-comp", "eigcomp", ffOPTWR }, - { efXVG, "-rmsf", "eigrmsf", ffOPTWR }, - { efXVG, "-proj", "proj", ffOPTWR }, - { efXVG, "-2d", "2dproj", ffOPTWR }, - { efSTO, "-3d", "3dproj.pdb", ffOPTWR }, - { efTRX, "-filt", "filtered", ffOPTWR }, - { efTRX, "-extr", "extreme.pdb", ffOPTWR }, - { efXVG, "-over", "overlap", ffOPTWR }, - { efXPM, "-inpr", "inprod", ffOPTWR } + t_filenm fnm[] = { + { efTRN, "-v", "eigenvec", ffREAD }, { efTRN, "-v2", "eigenvec2", ffOPTRD }, + { efTRX, "-f", nullptr, ffOPTRD }, { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-eig", "eigenval", ffOPTRD }, + { efXVG, "-eig2", "eigenval2", ffOPTRD }, { efXVG, "-comp", "eigcomp", ffOPTWR }, + { efXVG, "-rmsf", "eigrmsf", ffOPTWR }, { efXVG, "-proj", "proj", ffOPTWR }, + { efXVG, "-2d", "2dproj", ffOPTWR }, { efSTO, "-3d", "3dproj.pdb", ffOPTWR }, + { efTRX, "-filt", "filtered", ffOPTWR }, { efTRX, "-extr", "extreme.pdb", ffOPTWR }, + { efXVG, "-over", "overlap", ffOPTWR }, { efXPM, "-inpr", "inprod", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, + NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } indexfile = ftp2fn_null(efNDX, NFILE, fnm); - VecFile = opt2fn("-v", NFILE, fnm); - Vec2File = opt2fn_null("-v2", NFILE, fnm); - topfile = ftp2fn(efTPS, NFILE, fnm); - EigFile = opt2fn_null("-eig", NFILE, fnm); - Eig2File = opt2fn_null("-eig2", NFILE, fnm); - CompFile = opt2fn_null("-comp", NFILE, fnm); - RmsfFile = opt2fn_null("-rmsf", NFILE, fnm); - ProjOnVecFile = opt2fn_null("-proj", NFILE, fnm); - TwoDPlotFile = opt2fn_null("-2d", NFILE, fnm); - ThreeDPlotFile = opt2fn_null("-3d", NFILE, fnm); - FilterFile = opt2fn_null("-filt", NFILE, fnm); - ExtremeFile = opt2fn_null("-extr", NFILE, fnm); - OverlapFile = opt2fn_null("-over", NFILE, fnm); - InpMatFile = ftp2fn_null(efXPM, NFILE, fnm); - - bProj = (ProjOnVecFile != nullptr) || (TwoDPlotFile != nullptr) || (ThreeDPlotFile != nullptr) - || (FilterFile != nullptr) || (ExtremeFile != nullptr); - bFirstLastSet = - opt2parg_bSet("-first", NPA, pa) && opt2parg_bSet("-last", NPA, pa); - bFirstToLast = (CompFile != nullptr) || (RmsfFile != nullptr) || (ProjOnVecFile != nullptr) || (FilterFile != nullptr) || - (OverlapFile != nullptr) || (((ExtremeFile != nullptr) || (InpMatFile != nullptr)) && bFirstLastSet); - bVec2 = (Vec2File != nullptr) || (OverlapFile != nullptr) || (InpMatFile != nullptr); - bM = (RmsfFile != nullptr) || bProj; - bTraj = (ProjOnVecFile != nullptr) || (FilterFile != nullptr) || ((ExtremeFile != nullptr) && (max == 0)) - || (TwoDPlotFile != nullptr) || (ThreeDPlotFile != nullptr); + VecFile = opt2fn("-v", NFILE, fnm); + Vec2File = opt2fn_null("-v2", NFILE, fnm); + topfile = ftp2fn(efTPS, NFILE, fnm); + EigFile = opt2fn_null("-eig", NFILE, fnm); + Eig2File = opt2fn_null("-eig2", NFILE, fnm); + CompFile = opt2fn_null("-comp", NFILE, fnm); + RmsfFile = opt2fn_null("-rmsf", NFILE, fnm); + ProjOnVecFile = opt2fn_null("-proj", NFILE, fnm); + TwoDPlotFile = opt2fn_null("-2d", NFILE, fnm); + ThreeDPlotFile = opt2fn_null("-3d", NFILE, fnm); + FilterFile = opt2fn_null("-filt", NFILE, fnm); + ExtremeFile = opt2fn_null("-extr", NFILE, fnm); + OverlapFile = opt2fn_null("-over", NFILE, fnm); + InpMatFile = ftp2fn_null(efXPM, NFILE, fnm); + + bProj = (ProjOnVecFile != nullptr) || (TwoDPlotFile != nullptr) || (ThreeDPlotFile != nullptr) + || (FilterFile != nullptr) || (ExtremeFile != nullptr); + bFirstLastSet = opt2parg_bSet("-first", NPA, pa) && opt2parg_bSet("-last", NPA, pa); + bFirstToLast = (CompFile != nullptr) || (RmsfFile != nullptr) || (ProjOnVecFile != nullptr) + || (FilterFile != nullptr) || (OverlapFile != nullptr) + || (((ExtremeFile != nullptr) || (InpMatFile != nullptr)) && bFirstLastSet); + bVec2 = (Vec2File != nullptr) || (OverlapFile != nullptr) || (InpMatFile != nullptr); + bM = (RmsfFile != nullptr) || bProj; + bTraj = (ProjOnVecFile != nullptr) || (FilterFile != nullptr) + || ((ExtremeFile != nullptr) && (max == 0)) || (TwoDPlotFile != nullptr) + || (ThreeDPlotFile != nullptr); bIndex = bM || bProj; - bTPS = ftp2bSet(efTPS, NFILE, fnm) || bM || bTraj || - (FilterFile != nullptr) || (bIndex && (indexfile != nullptr)); + bTPS = ftp2bSet(efTPS, NFILE, fnm) || bM || bTraj || (FilterFile != nullptr) + || (bIndex && (indexfile != nullptr)); bCompare = (Vec2File != nullptr) || (Eig2File != nullptr); bPDB3D = fn2ftp(ThreeDPlotFile) == efPDB; - read_eigenvectors(VecFile, &natoms, &bFit1, - &xref1, &bDMR1, &xav1, &bDMA1, - &nvec1, &eignr1, &eigvec1, &eigval1); - neig1 = std::min(nvec1, DIM*natoms); - if (nvec1 != DIM*natoms) + read_eigenvectors(VecFile, &natoms, &bFit1, &xref1, &bDMR1, &xav1, &bDMA1, &nvec1, &eignr1, + &eigvec1, &eigval1); + neig1 = std::min(nvec1, DIM * natoms); + if (nvec1 != DIM * natoms) { - fprintf(stderr, "Warning: number of eigenvectors %d does not match three times\n" + fprintf(stderr, + "Warning: number of eigenvectors %d does not match three times\n" "the number of atoms %d in %s. Using %d eigenvectors.\n\n", nvec1, natoms, VecFile, neig1); } @@ -1124,18 +1165,20 @@ int gmx_anaeig(int argc, char *argv[]) int neig_tmp = read_xvg(EigFile, &xvgdata, &i); if (neig_tmp != neig1) { - fprintf(stderr, "Warning: number of eigenvalues in xvg file (%d) does not mtch trr file (%d)\n", neig1, natoms); + fprintf(stderr, + "Warning: number of eigenvalues in xvg file (%d) does not mtch trr file (%d)\n", + neig1, natoms); } neig1 = neig_tmp; srenew(eigval1, neig1); for (j = 0; j < neig1; j++) { - real tmp = eigval1[j]; + real tmp = eigval1[j]; eigval1[j] = xvgdata[1][j]; if (debug && (eigval1[j] != tmp)) { - fprintf(debug, "Replacing eigenvalue %d. From trr: %10g, from xvg: %10g\n", - j, tmp, eigval1[j]); + fprintf(debug, "Replacing eigenvalue %d. From trr: %10g, from xvg: %10g\n", j, tmp, + eigval1[j]); } } for (j = 0; j < i; j++) @@ -1150,14 +1193,14 @@ int gmx_anaeig(int argc, char *argv[]) { if (bDMA1) { - gmx_fatal(FARGS, "Can not calculate entropies from mass-weighted eigenvalues, redo the analysis without mass-weighting"); + gmx_fatal(FARGS, + "Can not calculate entropies from mass-weighted eigenvalues, redo the " + "analysis without mass-weighting"); } printf("The Entropy due to the Schlitter formula is %g J/mol K\n", - calcSchlitterEntropy(gmx::arrayRefFromArray(eigval1, neig1), - temp, FALSE)); + calcSchlitterEntropy(gmx::arrayRefFromArray(eigval1, neig1), temp, FALSE)); printf("The Entropy due to the Quasiharmonic analysis is %g J/mol K\n", - calcQuasiHarmonicEntropy(gmx::arrayRefFromArray(eigval1, neig1), - temp, FALSE, 1.0)); + calcQuasiHarmonicEntropy(gmx::arrayRefFromArray(eigval1, neig1), temp, FALSE, 1.0)); } if (bVec2) @@ -1167,10 +1210,10 @@ int gmx_anaeig(int argc, char *argv[]) gmx_fatal(FARGS, "Need a second eigenvector file to do this analysis."); } int natoms2; - read_eigenvectors(Vec2File, &natoms2, &bFit2, - &xref2, &bDMR2, &xav2, &bDMA2, &nvec2, &eignr2, &eigvec2, &eigval2); + read_eigenvectors(Vec2File, &natoms2, &bFit2, &xref2, &bDMR2, &xav2, &bDMA2, &nvec2, + &eignr2, &eigvec2, &eigval2); - neig2 = std::min(nvec2, DIM*natoms2); + neig2 = std::min(nvec2, DIM * natoms2); if (neig2 != neig1) { gmx_fatal(FARGS, "Dimensions in the eigenvector files don't match"); @@ -1219,8 +1262,7 @@ int gmx_anaeig(int argc, char *argv[]) } else { - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), - &top, &ePBC, &xtop, nullptr, topbox, bM); + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, topbox, bM); atoms = &top.atoms; gpbc = gmx_rmpbc_init(&top.idef, ePBC, atoms->nr); gmx_rmpbc(gpbc, atoms->nr, topbox, xtop); @@ -1230,7 +1272,8 @@ int gmx_anaeig(int argc, char *argv[]) if (xref1 == nullptr) { printf("\nNote: the structure in %s should be the same\n" - " as the one used for the fit in g_covar\n", topfile); + " as the one used for the fit in g_covar\n", + topfile); } printf("\nSelect the index group that was used for the least squares fit in g_covar\n"); get_index(atoms, indexfile, 1, &nfit, &ifit, &grpname); @@ -1254,7 +1297,10 @@ int gmx_anaeig(int argc, char *argv[]) /* Safety check between selected fit-group and reference structure read from the eigenvector file */ if (natoms != nfit) { - gmx_fatal(FARGS, "you selected a group with %d elements instead of %d, your selection does not fit the reference structure in the eigenvector file.", nfit, natoms); + gmx_fatal(FARGS, + "you selected a group with %d elements instead of %d, your selection " + "does not fit the reference structure in the eigenvector file.", + nfit, natoms); } for (i = 0; (i < nfit); i++) { @@ -1311,51 +1357,53 @@ int gmx_anaeig(int argc, char *argv[]) { for (d = 0; (d < DIM); d++) { - t += gmx::square((xav1[i][d]-xav2[i][d])*sqrtm[i]); + t += gmx::square((xav1[i][d] - xav2[i][d]) * sqrtm[i]); totmass += gmx::square(sqrtm[i]); } } - fprintf(stdout, "RMSD (without fit) between the two average structures:" - " %.3f (nm)\n\n", std::sqrt(t/totmass)); + fprintf(stdout, + "RMSD (without fit) between the two average structures:" + " %.3f (nm)\n\n", + std::sqrt(t / totmass)); } if (last == -1) { - last = natoms*DIM; + last = natoms * DIM; } if (first > -1) { if (bFirstToLast) { /* make an index from first to last */ - nout = last-first+1; + nout = last - first + 1; snew(iout, nout); for (i = 0; i < nout; i++) { - iout[i] = first-1+i; + iout[i] = first - 1 + i; } } else if (ThreeDPlotFile) { /* make an index of first+(0,1,2) and last */ nout = bPDB3D ? 4 : 3; - nout = std::min(last-first+1, nout); + nout = std::min(last - first + 1, nout); snew(iout, nout); - iout[0] = first-1; + iout[0] = first - 1; iout[1] = first; if (nout > 3) { - iout[2] = first+1; + iout[2] = first + 1; } - iout[nout-1] = last-1; + iout[nout - 1] = last - 1; } else { /* make an index of first and last */ nout = 2; snew(iout, nout); - iout[0] = first-1; - iout[1] = last-1; + iout[0] = first - 1; + iout[1] = last - 1; } } else @@ -1367,14 +1415,13 @@ int gmx_anaeig(int argc, char *argv[]) do { nout++; - srenew(iout, nout+1); + srenew(iout, nout + 1); if (1 != scanf("%d", &iout[nout])) { gmx_fatal(FARGS, "Error reading user input"); } iout[nout]--; - } - while (iout[nout] >= 0); + } while (iout[nout] >= 0); printf("\n"); } @@ -1400,7 +1447,7 @@ int gmx_anaeig(int argc, char *argv[]) fprintf(stderr, ":"); for (j = 0; j < noutvec; j++) { - fprintf(stderr, " %d", eignr1[outvec[j]]+1); + fprintf(stderr, " %d", eignr1[outvec[j]] + 1); } } fprintf(stderr, "\n"); @@ -1412,31 +1459,25 @@ int gmx_anaeig(int argc, char *argv[]) if (RmsfFile) { - rmsf(RmsfFile, natoms, sqrtm, eignr1, eigvec1, noutvec, outvec, eigval1, - neig1, oenv); + rmsf(RmsfFile, natoms, sqrtm, eignr1, eigvec1, noutvec, outvec, eigval1, neig1, oenv); } if (bProj) { - project(bTraj ? opt2fn("-f", NFILE, fnm) : nullptr, - bTop ? &top : nullptr, ePBC, topbox, - ProjOnVecFile, TwoDPlotFile, ThreeDPlotFile, FilterFile, skip, - ExtremeFile, bFirstLastSet, max, nextr, atoms, natoms, index, - bFit1, xrefp, nfit, ifit, w_rls, - sqrtm, xav1, eignr1, eigvec1, noutvec, outvec, bSplit, - oenv); + project(bTraj ? opt2fn("-f", NFILE, fnm) : nullptr, bTop ? &top : nullptr, ePBC, topbox, + ProjOnVecFile, TwoDPlotFile, ThreeDPlotFile, FilterFile, skip, ExtremeFile, + bFirstLastSet, max, nextr, atoms, natoms, index, bFit1, xrefp, nfit, ifit, w_rls, + sqrtm, xav1, eignr1, eigvec1, noutvec, outvec, bSplit, oenv); } if (OverlapFile) { - overlap(OverlapFile, natoms, - eigvec1, nvec2, eignr2, eigvec2, noutvec, outvec, oenv); + overlap(OverlapFile, natoms, eigvec1, nvec2, eignr2, eigvec2, noutvec, outvec, oenv); } if (InpMatFile) { - inprod_matrix(InpMatFile, natoms, - nvec1, eignr1, eigvec1, nvec2, eignr2, eigvec2, + inprod_matrix(InpMatFile, natoms, nvec1, eignr1, eigvec1, nvec2, eignr2, eigvec2, bFirstLastSet, noutvec, outvec); } @@ -1446,10 +1487,10 @@ int gmx_anaeig(int argc, char *argv[]) } - if (!CompFile && !bProj && !OverlapFile && !InpMatFile && - !bCompare && !bEntropy) + if (!CompFile && !bProj && !OverlapFile && !InpMatFile && !bCompare && !bEntropy) { - fprintf(stderr, "\nIf you want some output," + fprintf(stderr, + "\nIf you want some output," " set one (or two or ...) of the output file options\n"); } diff --git a/src/gromacs/gmxana/gmx_analyze.cpp b/src/gromacs/gmxana/gmx_analyze.cpp index 66ea69f083..267a3b0a50 100644 --- a/src/gromacs/gmxana/gmx_analyze.cpp +++ b/src/gromacs/gmxana/gmx_analyze.cpp @@ -61,11 +61,17 @@ #include "gromacs/utility/snprintf.h" /* must correspond to char *avbar_opt[] declared in main() */ -enum { - avbarSEL, avbarNONE, avbarSTDDEV, avbarERROR, avbar90, avbarNR +enum +{ + avbarSEL, + avbarNONE, + avbarSTDDEV, + avbarERROR, + avbar90, + avbarNR }; -static void power_fit(int n, int nset, real **val, real *t) +static void power_fit(int n, int nset, real** val, real* t) { real *x, *y, quality, a, b, r; int s, i; @@ -85,7 +91,8 @@ static void power_fit(int n, int nset, real **val, real *t) } else { - fprintf(stdout, "First time is not larger than 0, using index number as time for power fit\n"); + fprintf(stdout, + "First time is not larger than 0, using index number as time for power fit\n"); for (i = 0; i < n; i++) { x[i] = std::log1p(static_cast(i)); @@ -103,15 +110,14 @@ static void power_fit(int n, int nset, real **val, real *t) fprintf(stdout, "Will power fit up to point %d, since it is not larger than 0\n", i); } lsq_y_ax_b(i, x, y, &a, &b, &r, &quality); - fprintf(stdout, "Power fit set %3d: error %.3f a %g b %g\n", - s+1, quality, a, std::exp(b)); + fprintf(stdout, "Power fit set %3d: error %.3f a %g b %g\n", s + 1, quality, a, std::exp(b)); } sfree(y); sfree(x); } -static real cosine_content(int nhp, int n, const real *y) +static real cosine_content(int nhp, int n, const real* y) /* Assumes n equidistant points */ { double fac, cosyint, yyint; @@ -122,43 +128,39 @@ static real cosine_content(int nhp, int n, const real *y) return 0; } - fac = M_PI*nhp/(n-1); + fac = M_PI * nhp / (n - 1); cosyint = 0; yyint = 0; for (i = 0; i < n; i++) { - cosyint += std::cos(fac*i)*y[i]; - yyint += y[i]*y[i]; + cosyint += std::cos(fac * i) * y[i]; + yyint += y[i] * y[i]; } - return 2*cosyint*cosyint/(n*yyint); + return 2 * cosyint * cosyint / (n * yyint); } -static void plot_coscont(const char *ccfile, int n, int nset, real **val, - const gmx_output_env_t *oenv) +static void plot_coscont(const char* ccfile, int n, int nset, real** val, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; int s; real cc; - fp = xvgropen(ccfile, "Cosine content", "set / half periods", "cosine content", - oenv); + fp = xvgropen(ccfile, "Cosine content", "set / half periods", "cosine content", oenv); for (s = 0; s < nset; s++) { - cc = cosine_content(s+1, n, val[s]); - fprintf(fp, " %d %g\n", s+1, cc); - fprintf(stdout, "Cosine content of set %d with %.1f periods: %g\n", - s+1, 0.5*(s+1), cc); + cc = cosine_content(s + 1, n, val[s]); + fprintf(fp, " %d %g\n", s + 1, cc); + fprintf(stdout, "Cosine content of set %d with %.1f periods: %g\n", s + 1, 0.5 * (s + 1), cc); } fprintf(stdout, "\n"); xvgrclose(fp); } -static void regression_analysis(int n, gmx_bool bXYdy, - real *x, int nset, real **val) +static void regression_analysis(int n, gmx_bool bXYdy, real* x, int nset, real** val) { real S, chi2, a, b, da, db, r = 0; int ok; @@ -173,22 +175,20 @@ static void regression_analysis(int n, gmx_bool bXYdy, { if ((ok = lsq_y_ax_b_error(n, x, val[0], val[1], &a, &b, &da, &db, &r, &S)) != estatsOK) { - gmx_fatal(FARGS, "Error fitting the data: %s", - gmx_stats_message(ok)); + gmx_fatal(FARGS, "Error fitting the data: %s", gmx_stats_message(ok)); } } else { if ((ok = lsq_y_ax_b(n, x, val[0], &a, &b, &r, &S)) != estatsOK) { - gmx_fatal(FARGS, "Error fitting the data: %s", - gmx_stats_message(ok)); + gmx_fatal(FARGS, "Error fitting the data: %s", gmx_stats_message(ok)); } } - chi2 = gmx::square((n-2)*S); + chi2 = gmx::square((n - 2) * S); printf("Chi2 = %g\n", chi2); printf("S (Sqrt(Chi2/(n-2)) = %g\n", S); - printf("Correlation coefficient = %.1f%%\n", 100*r); + printf("Correlation coefficient = %.1f%%\n", 100 * r); printf("\n"); if (bXYdy) { @@ -207,8 +207,8 @@ static void regression_analysis(int n, gmx_bool bXYdy, int i, j; snew(y, n); - snew(xx, nset-1); - for (j = 0; (j < nset-1); j++) + snew(xx, nset - 1); + for (j = 0; (j < nset - 1); j++) { snew(xx[j], n); } @@ -217,15 +217,15 @@ static void regression_analysis(int n, gmx_bool bXYdy, y[i] = val[0][i]; for (j = 1; (j < nset); j++) { - xx[j-1][i] = val[j][i]; + xx[j - 1][i] = val[j][i]; } } - snew(a, nset-1); - chi2 = multi_regression(nullptr, n, y, nset-1, xx, a); - printf("Fitting %d data points in %d sets\n", n, nset-1); + snew(a, nset - 1); + chi2 = multi_regression(nullptr, n, y, nset - 1, xx, a); + printf("Fitting %d data points in %d sets\n", n, nset - 1); printf("chi2 = %g\n", chi2); printf("A ="); - for (i = 0; (i < nset-1); i++) + for (i = 0; (i < nset - 1); i++) { printf(" %g", a[i]); sfree(xx[i]); @@ -237,14 +237,13 @@ static void regression_analysis(int n, gmx_bool bXYdy, } } -static void histogram(const char *distfile, real binwidth, int n, int nset, real **val, - const gmx_output_env_t *oenv) +static void histogram(const char* distfile, real binwidth, int n, int nset, real** val, const gmx_output_env_t* oenv) { - FILE *fp; - int i, s; - double minval, maxval; - int nbin; - int64_t *histo; + FILE* fp; + int i, s; + double minval, maxval; + int nbin; + int64_t* histo; minval = val[0][0]; maxval = val[0][0]; @@ -263,15 +262,15 @@ static void histogram(const char *distfile, real binwidth, int n, int nset, real } } - minval = binwidth*std::floor(minval/binwidth); - maxval = binwidth*std::ceil(maxval/binwidth); + minval = binwidth * std::floor(minval / binwidth); + maxval = binwidth * std::ceil(maxval / binwidth); if (minval != 0) { minval -= binwidth; } maxval += binwidth; - nbin = gmx::roundToInt(((maxval - minval)/binwidth) + 1); + nbin = gmx::roundToInt(((maxval - minval) / binwidth) + 1); fprintf(stderr, "Making distributions with %d bins\n", nbin); snew(histo, nbin); fp = xvgropen(distfile, "Distribution", "", "", oenv); @@ -283,13 +282,13 @@ static void histogram(const char *distfile, real binwidth, int n, int nset, real } for (i = 0; i < n; i++) { - histo[gmx::roundToInt((val[s][i] - minval)/binwidth)]++; + histo[gmx::roundToInt((val[s][i] - minval) / binwidth)]++; } for (i = 0; i < nbin; i++) { - fprintf(fp, " %g %g\n", minval+i*binwidth, static_cast(histo[i])/(n*binwidth)); + fprintf(fp, " %g %g\n", minval + i * binwidth, static_cast(histo[i]) / (n * binwidth)); } - if (s < nset-1) + if (s < nset - 1) { fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } @@ -297,7 +296,7 @@ static void histogram(const char *distfile, real binwidth, int n, int nset, real xvgrclose(fp); } -static int real_comp(const void *a, const void *b) +static int real_comp(const void* a, const void* b) { real dif = *reinterpret_cast(a) - *reinterpret_cast(b); @@ -315,13 +314,12 @@ static int real_comp(const void *a, const void *b) } } -static void average(const char *avfile, int avbar_opt, - int n, int nset, real **val, real *t) +static void average(const char* avfile, int avbar_opt, int n, int nset, real** val, real* t) { - FILE *fp; - int i, s, edge = 0; - double av, var, err; - real *tmp = nullptr; + FILE* fp; + int i, s, edge = 0; + double av, var, err; + real* tmp = nullptr; fp = gmx_ffopen(avfile, "w"); if ((avbar_opt == avbarERROR) && (nset == 1)) @@ -334,9 +332,11 @@ static void average(const char *avfile, int avbar_opt, { snew(tmp, nset); fprintf(fp, "@TYPE xydydy\n"); - edge = gmx::roundToInt(nset*0.05); - fprintf(stdout, "Errorbars: discarding %d points on both sides: %d%%" - " interval\n", edge, gmx::roundToInt(100.*(nset-2*edge)/nset)); + edge = gmx::roundToInt(nset * 0.05); + fprintf(stdout, + "Errorbars: discarding %d points on both sides: %d%%" + " interval\n", + edge, gmx::roundToInt(100. * (nset - 2 * edge) / nset)); } else { @@ -363,21 +363,21 @@ static void average(const char *avfile, int avbar_opt, tmp[s] = val[s][i]; } qsort(tmp, nset, sizeof(tmp[0]), real_comp); - fprintf(fp, " %g %g", tmp[nset-1-edge]-av, av-tmp[edge]); + fprintf(fp, " %g %g", tmp[nset - 1 - edge] - av, av - tmp[edge]); } else { for (s = 0; s < nset; s++) { - var += gmx::square(val[s][i]-av); + var += gmx::square(val[s][i] - av); } if (avbar_opt == avbarSTDDEV) { - err = std::sqrt(var/nset); + err = std::sqrt(var / nset); } else { - err = std::sqrt(var/(nset*(nset-1))); + err = std::sqrt(var / (nset * (nset - 1))); } fprintf(fp, " %g", err); } @@ -403,31 +403,39 @@ static real optimal_error_estimate(double sigma, const double fitparm[], real tT { return 0; } - double ss = fitparm[1]*fitparm[0]+(1-fitparm[1])*fitparm[2]; + double ss = fitparm[1] * fitparm[0] + (1 - fitparm[1]) * fitparm[2]; if ((tTotal <= 0) || (ss <= 0)) { - fprintf(stderr, "Problem in error estimate: T = %g, ss = %g\n", - tTotal, ss); + fprintf(stderr, "Problem in error estimate: T = %g, ss = %g\n", tTotal, ss); return 0; } - return sigma*std::sqrt(2*ss/tTotal); + return sigma * std::sqrt(2 * ss / tTotal); } -static void estimate_error(const char *eefile, int nb_min, int resol, int n, - int nset, double *av, double *sig, real **val, real dt, - gmx_bool bFitAc, gmx_bool bSingleExpFit, gmx_bool bAllowNegLTCorr, - const gmx_output_env_t *oenv) +static void estimate_error(const char* eefile, + int nb_min, + int resol, + int n, + int nset, + double* av, + double* sig, + real** val, + real dt, + gmx_bool bFitAc, + gmx_bool bSingleExpFit, + gmx_bool bAllowNegLTCorr, + const gmx_output_env_t* oenv) { - FILE *fp; - int bs, prev_bs, nbs, nb; - real spacing, nbr; - int s, i, j; - double blav, var; - char **leg; - real *tbs, *ybs, rtmp, dens, *fitsig, twooe, tau1_est, tau_sig; - double fitparm[3]; - real ee, a, tau1, tau2; + FILE* fp; + int bs, prev_bs, nbs, nb; + real spacing, nbr; + int s, i, j; + double blav, var; + char** leg; + real * tbs, *ybs, rtmp, dens, *fitsig, twooe, tau1_est, tau_sig; + double fitparm[3]; + real ee, a, tau1, tau2; if (n < 4) { @@ -436,19 +444,16 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, return; } - fp = xvgropen(eefile, "Error estimates", - "Block size (time)", "Error estimate", oenv); + fp = xvgropen(eefile, "Error estimates", "Block size (time)", "Error estimate", oenv); if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(fp, - "@ subtitle \"using block averaging, total time %g (%d points)\"\n", - (n-1)*dt, n); + fprintf(fp, "@ subtitle \"using block averaging, total time %g (%d points)\"\n", (n - 1) * dt, n); } - snew(leg, 2*nset); - xvgr_legend(fp, 2*nset, leg, oenv); + snew(leg, 2 * nset); + xvgr_legend(fp, 2 * nset, leg, oenv); sfree(leg); - spacing = std::pow(2.0, 1.0/resol); + spacing = std::pow(2.0, 1.0 / resol); snew(tbs, n); snew(ybs, n); snew(fitsig, n); @@ -459,32 +464,32 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, nbr = nb_min; while (nbr <= n) { - bs = n/static_cast(nbr); + bs = n / static_cast(nbr); if (bs != prev_bs) { - nb = n/bs; + nb = n / bs; var = 0; for (i = 0; i < nb; i++) { blav = 0; for (j = 0; j < bs; j++) { - blav += val[s][bs*i+j]; + blav += val[s][bs * i + j]; } - var += gmx::square(av[s] - blav/bs); + var += gmx::square(av[s] - blav / bs); } - tbs[nbs] = bs*dt; + tbs[nbs] = bs * dt; if (sig[s] == 0) { ybs[nbs] = 0; } else { - ybs[nbs] = var/(nb*(nb-1.0))*(n*dt)/(sig[s]*sig[s]); + ybs[nbs] = var / (nb * (nb - 1.0)) * (n * dt) / (sig[s] * sig[s]); } nbs++; } - nbr *= spacing; + nbr *= spacing; prev_bs = bs; } if (sig[s] == 0) @@ -499,37 +504,37 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, } else { - for (i = 0; i < nbs/2; i++) + for (i = 0; i < nbs / 2; i++) { - rtmp = tbs[i]; - tbs[i] = tbs[nbs-1-i]; - tbs[nbs-1-i] = rtmp; - rtmp = ybs[i]; - ybs[i] = ybs[nbs-1-i]; - ybs[nbs-1-i] = rtmp; + rtmp = tbs[i]; + tbs[i] = tbs[nbs - 1 - i]; + tbs[nbs - 1 - i] = rtmp; + rtmp = ybs[i]; + ybs[i] = ybs[nbs - 1 - i]; + ybs[nbs - 1 - i] = rtmp; } /* The initial slope of the normalized ybs^2 is 1. * For a single exponential autocorrelation: ybs(tau1) = 2/e tau1 * From this we take our initial guess for tau1. */ - twooe = 2.0/std::exp(1.0); + twooe = 2.0 / std::exp(1.0); i = -1; do { i++; tau1_est = tbs[i]; - } - while (i < nbs - 1 && - (ybs[i] > ybs[i+1] || ybs[i] > twooe*tau1_est)); + } while (i < nbs - 1 && (ybs[i] > ybs[i + 1] || ybs[i] > twooe * tau1_est)); if (ybs[0] > ybs[1]) { - fprintf(stdout, "Data set %d has strange time correlations:\n" - "the std. error using single points is larger than that of blocks of 2 points\n" + fprintf(stdout, + "Data set %d has strange time correlations:\n" + "the std. error using single points is larger than that of blocks of 2 " + "points\n" "The error estimate might be inaccurate, check the fit\n", - s+1); + s + 1); /* Use the total time as tau for the fitting weights */ - tau_sig = (n - 1)*dt; + tau_sig = (n - 1) * dt; } else { @@ -538,7 +543,7 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, if (debug) { - fprintf(debug, "set %d tau1 estimate %f\n", s+1, tau1_est); + fprintf(debug, "set %d tau1 estimate %f\n", s + 1, tau1_est); } /* Generate more or less appropriate sigma's, @@ -548,17 +553,17 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, { if (i == 0) { - dens = tbs[1]/tbs[0] - 1; + dens = tbs[1] / tbs[0] - 1; } - else if (i == nbs-1) + else if (i == nbs - 1) { - dens = tbs[nbs-1]/tbs[nbs-2] - 1; + dens = tbs[nbs - 1] / tbs[nbs - 2] - 1; } else { - dens = 0.5*(tbs[i+1]/tbs[i-1] - 1); + dens = 0.5 * (tbs[i + 1] / tbs[i - 1] - 1); } - fitsig[i] = std::sqrt((tau_sig + tbs[i])/dens); + fitsig[i] = std::sqrt((tau_sig + tbs[i]) / dens); } if (!bSingleExpFit) @@ -568,88 +573,85 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, /* We set the initial guess for tau2 * to halfway between tau1_est and the total time (on log scale). */ - fitparm[2] = std::sqrt(tau1_est*(n-1)*dt); - do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt*n, oenv, - bDebugMode(), effnERREST, fitparm, 0, - nullptr); + fitparm[2] = std::sqrt(tau1_est * (n - 1) * dt); + do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, + fitparm, 0, nullptr); } if (bSingleExpFit || fitparm[0] < 0 || fitparm[2] < 0 || fitparm[1] < 0 - || (fitparm[1] > 1 && !bAllowNegLTCorr) || fitparm[2] > (n-1)*dt) + || (fitparm[1] > 1 && !bAllowNegLTCorr) || fitparm[2] > (n - 1) * dt) { if (!bSingleExpFit) { - if (fitparm[2] > (n-1)*dt) + if (fitparm[2] > (n - 1) * dt) { fprintf(stdout, "Warning: tau2 is longer than the length of the data (%g)\n" " the statistics might be bad\n", - (n-1)*dt); + (n - 1) * dt); } else { fprintf(stdout, "a fitted parameter is negative\n"); } fprintf(stdout, "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n", - optimal_error_estimate(sig[s], fitparm, n*dt), - fitparm[1], fitparm[0], fitparm[2]); + optimal_error_estimate(sig[s], fitparm, n * dt), fitparm[1], fitparm[0], + fitparm[2]); /* Do a fit with tau2 fixed at the total time. * One could also choose any other large value for tau2. */ fitparm[0] = tau1_est; fitparm[1] = 0.95; - fitparm[2] = (n-1)*dt; + fitparm[2] = (n - 1) * dt; fprintf(stdout, "Will fix tau2 at the total time: %g\n", fitparm[2]); - do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt*n, oenv, bDebugMode(), - effnERREST, fitparm, 4, nullptr); + do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, + fitparm, 4, nullptr); } - if (bSingleExpFit || fitparm[0] < 0 || fitparm[1] < 0 - || (fitparm[1] > 1 && !bAllowNegLTCorr)) + if (bSingleExpFit || fitparm[0] < 0 || fitparm[1] < 0 || (fitparm[1] > 1 && !bAllowNegLTCorr)) { if (!bSingleExpFit) { fprintf(stdout, "a fitted parameter is negative\n"); fprintf(stdout, "invalid fit: e.e. %g a %g tau1 %g tau2 %g\n", - optimal_error_estimate(sig[s], fitparm, n*dt), - fitparm[1], fitparm[0], fitparm[2]); + optimal_error_estimate(sig[s], fitparm, n * dt), fitparm[1], + fitparm[0], fitparm[2]); } /* Do a single exponential fit */ - fprintf(stderr, "Will use a single exponential fit for set %d\n", s+1); + fprintf(stderr, "Will use a single exponential fit for set %d\n", s + 1); fitparm[0] = tau1_est; fitparm[1] = 1.0; fitparm[2] = 0.0; - do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt*n, oenv, bDebugMode(), - effnERREST, fitparm, 6, nullptr); + do_lmfit(nbs, ybs, fitsig, 0, tbs, 0, dt * n, oenv, bDebugMode(), effnERREST, + fitparm, 6, nullptr); } } - ee = optimal_error_estimate(sig[s], fitparm, n*dt); + ee = optimal_error_estimate(sig[s], fitparm, n * dt); a = fitparm[1]; tau1 = fitparm[0]; tau2 = fitparm[2]; } - fprintf(stdout, "Set %3d: err.est. %g a %g tau1 %g tau2 %g\n", - s+1, ee, a, tau1, tau2); + fprintf(stdout, "Set %3d: err.est. %g a %g tau1 %g tau2 %g\n", s + 1, ee, a, tau1, tau2); if (output_env_get_xvg_format(oenv) == exvgXMGR) { - fprintf(fp, "@ legend string %d \"av %f\"\n", 2*s, av[s]); - fprintf(fp, "@ legend string %d \"ee %6g\"\n", 2*s+1, - optimal_error_estimate(sig[s], fitparm, n*dt)); + fprintf(fp, "@ legend string %d \"av %f\"\n", 2 * s, av[s]); + fprintf(fp, "@ legend string %d \"ee %6g\"\n", 2 * s + 1, + optimal_error_estimate(sig[s], fitparm, n * dt)); } else if (output_env_get_xvg_format(oenv) == exvgXMGRACE) { - fprintf(fp, "@ s%d legend \"av %f\"\n", 2*s, av[s]); - fprintf(fp, "@ s%d legend \"ee %6g\"\n", 2*s+1, - optimal_error_estimate(sig[s], fitparm, n*dt)); + fprintf(fp, "@ s%d legend \"av %f\"\n", 2 * s, av[s]); + fprintf(fp, "@ s%d legend \"ee %6g\"\n", 2 * s + 1, + optimal_error_estimate(sig[s], fitparm, n * dt)); } for (i = 0; i < nbs; i++) { - fprintf(fp, "%g %g %g\n", tbs[i], sig[s]*std::sqrt(ybs[i]/(n*dt)), - sig[s]*std::sqrt(fit_function(effnERREST, fitparm, tbs[i])/(n*dt))); + fprintf(fp, "%g %g %g\n", tbs[i], sig[s] * std::sqrt(ybs[i] / (n * dt)), + sig[s] * std::sqrt(fit_function(effnERREST, fitparm, tbs[i]) / (n * dt))); } if (bFitAc) { int fitlen; - real *ac, acint; + real * ac, acint; double ac_fit[4]; snew(ac, n); @@ -665,15 +667,14 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, fitsig[i] = 1; } } - low_do_autocorr(nullptr, oenv, nullptr, n, 1, -1, &ac, - dt, eacNormal, 1, FALSE, TRUE, + low_do_autocorr(nullptr, oenv, nullptr, n, 1, -1, &ac, dt, eacNormal, 1, FALSE, TRUE, FALSE, 0, 0, effnNONE); - fitlen = n/nb_min; + fitlen = n / nb_min; /* Integrate ACF only up to fitlen/2 to avoid integrating noise */ - acint = 0.5*ac[0]; - for (i = 1; i <= fitlen/2; i++) + acint = 0.5 * ac[0]; + for (i = 1; i <= fitlen / 2; i++) { acint += ac[i]; } @@ -682,30 +683,29 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, /* Generate more or less appropriate sigma's */ for (i = 0; i <= fitlen; i++) { - fitsig[i] = std::sqrt(acint + dt*i); + fitsig[i] = std::sqrt(acint + dt * i); } - ac_fit[0] = 0.5*acint; + ac_fit[0] = 0.5 * acint; ac_fit[1] = 0.95; - ac_fit[2] = 10*acint; - do_lmfit(n/nb_min, ac, fitsig, dt, nullptr, 0, fitlen*dt, oenv, - bDebugMode(), effnEXPEXP, ac_fit, 0, nullptr); + ac_fit[2] = 10 * acint; + do_lmfit(n / nb_min, ac, fitsig, dt, nullptr, 0, fitlen * dt, oenv, bDebugMode(), + effnEXPEXP, ac_fit, 0, nullptr); ac_fit[3] = 1 - ac_fit[1]; - fprintf(stdout, "Set %3d: ac erest %g a %g tau1 %g tau2 %g\n", - s+1, optimal_error_estimate(sig[s], ac_fit, n*dt), - ac_fit[1], ac_fit[0], ac_fit[2]); + fprintf(stdout, "Set %3d: ac erest %g a %g tau1 %g tau2 %g\n", s + 1, + optimal_error_estimate(sig[s], ac_fit, n * dt), ac_fit[1], ac_fit[0], ac_fit[2]); fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); for (i = 0; i < nbs; i++) { fprintf(fp, "%g %g\n", tbs[i], - sig[s]*std::sqrt(fit_function(effnERREST, ac_fit, tbs[i]))/(n*dt)); + sig[s] * std::sqrt(fit_function(effnERREST, ac_fit, tbs[i])) / (n * dt)); } sfree(ac); } - if (s < nset-1) + if (s < nset - 1) { fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } @@ -716,12 +716,11 @@ static void estimate_error(const char *eefile, int nb_min, int resol, int n, xvgrclose(fp); } -static void luzar_correl(int nn, real *time, int nset, real **val, real temp, - gmx_bool bError, real fit_start) +static void luzar_correl(int nn, real* time, int nset, real** val, real temp, gmx_bool bError, real fit_start) { - real *kt; - real d2; - int j; + real* kt; + real d2; + int j; please_cite(stdout, "Spoel2006b"); @@ -741,16 +740,14 @@ static void luzar_correl(int nn, real *time, int nset, real **val, real temp, { d2 += gmx::square(kt[j] - val[3][j]); } - fprintf(debug, "RMS difference in derivatives is %g\n", std::sqrt(d2/nn)); + fprintf(debug, "RMS difference in derivatives is %g\n", std::sqrt(d2 / nn)); } - analyse_corr(nn, time, val[0], val[2], kt, nullptr, nullptr, nullptr, fit_start, - temp); + analyse_corr(nn, time, val[0], val[2], kt, nullptr, nullptr, nullptr, fit_start, temp); sfree(kt); } else if (nset == 6) { - analyse_corr(nn, time, val[0], val[2], val[4], - val[1], val[3], val[5], fit_start, temp); + analyse_corr(nn, time, val[0], val[2], val[4], val[1], val[3], val[5], fit_start, temp); } else { @@ -759,56 +756,62 @@ static void luzar_correl(int nn, real *time, int nset, real **val, real temp, } } -static void filter(real flen, int n, int nset, real **val, real dt) +static void filter(real flen, int n, int nset, real** val, real dt) { int f, s, i, j; double *filt, sum, vf, fluc, fluctot; - f = static_cast(flen/(2*dt)); - snew(filt, f+1); + f = static_cast(flen / (2 * dt)); + snew(filt, f + 1); filt[0] = 1; sum = 1; for (i = 1; i <= f; i++) { - filt[i] = std::cos(M_PI*dt*i/flen); - sum += 2*filt[i]; + filt[i] = std::cos(M_PI * dt * i / flen); + sum += 2 * filt[i]; } for (i = 0; i <= f; i++) { filt[i] /= sum; } - fprintf(stdout, "Will calculate the fluctuation over %d points\n", n-2*f); - fprintf(stdout, " using a filter of length %g of %d points\n", flen, 2*f+1); + fprintf(stdout, "Will calculate the fluctuation over %d points\n", n - 2 * f); + fprintf(stdout, " using a filter of length %g of %d points\n", flen, 2 * f + 1); fluctot = 0; for (s = 0; s < nset; s++) { fluc = 0; - for (i = f; i < n-f; i++) + for (i = f; i < n - f; i++) { - vf = filt[0]*val[s][i]; + vf = filt[0] * val[s][i]; for (j = 1; j <= f; j++) { - vf += filt[j]*(val[s][i-f]+val[s][i+f]); + vf += filt[j] * (val[s][i - f] + val[s][i + f]); } fluc += gmx::square(val[s][i] - vf); } - fluc /= n - 2*f; + fluc /= n - 2 * f; fluctot += fluc; - fprintf(stdout, "Set %3d filtered fluctuation: %12.6e\n", s+1, std::sqrt(fluc)); + fprintf(stdout, "Set %3d filtered fluctuation: %12.6e\n", s + 1, std::sqrt(fluc)); } - fprintf(stdout, "Overall filtered fluctuation: %12.6e\n", std::sqrt(fluctot/nset)); + fprintf(stdout, "Overall filtered fluctuation: %12.6e\n", std::sqrt(fluctot / nset)); fprintf(stdout, "\n"); sfree(filt); } -static void do_fit(FILE *out, int n, gmx_bool bYdy, - int ny, real *x0, real **val, - int npargs, t_pargs *ppa, const gmx_output_env_t *oenv, - const char *fn_fitted) +static void do_fit(FILE* out, + int n, + gmx_bool bYdy, + int ny, + real* x0, + real** val, + int npargs, + t_pargs* ppa, + const gmx_output_env_t* oenv, + const char* fn_fitted) { - real *c1 = nullptr, *sig = nullptr; - double *fitparm; + real * c1 = nullptr, *sig = nullptr; + double* fitparm; real tendfit, tbeginfit; int i, efitfn, nparm; @@ -820,7 +823,7 @@ static void do_fit(FILE *out, int n, gmx_bool bYdy, if (bYdy) { c1 = val[n]; - sig = val[n+1]; + sig = val[n + 1]; fprintf(out, "Using two columns as y and sigma values\n"); } else @@ -837,48 +840,46 @@ static void do_fit(FILE *out, int n, gmx_bool bYdy, } if (opt2parg_bSet("-endfit", npargs, ppa)) { - tendfit = opt2parg_real("-endfit", npargs, ppa); + tendfit = opt2parg_real("-endfit", npargs, ppa); } else { - tendfit = x0[ny-1]; + tendfit = x0[ny - 1]; } snew(fitparm, nparm); switch (efitfn) { - case effnEXP1: - fitparm[0] = 0.5; - break; + case effnEXP1: fitparm[0] = 0.5; break; case effnEXP2: fitparm[0] = 0.5; fitparm[1] = c1[0]; break; case effnEXPEXP: fitparm[0] = 1.0; - fitparm[1] = 0.5*c1[0]; + fitparm[1] = 0.5 * c1[0]; fitparm[2] = 10.0; break; case effnEXP5: - fitparm[0] = fitparm[2] = 0.5*c1[0]; - fitparm[1] = 10; - fitparm[3] = 40; - fitparm[4] = 0; + fitparm[0] = fitparm[2] = 0.5 * c1[0]; + fitparm[1] = 10; + fitparm[3] = 40; + fitparm[4] = 0; break; case effnEXP7: - fitparm[0] = fitparm[2] = fitparm[4] = 0.33*c1[0]; - fitparm[1] = 1; - fitparm[3] = 10; - fitparm[5] = 100; - fitparm[6] = 0; + fitparm[0] = fitparm[2] = fitparm[4] = 0.33 * c1[0]; + fitparm[1] = 1; + fitparm[3] = 10; + fitparm[5] = 100; + fitparm[6] = 0; break; case effnEXP9: - fitparm[0] = fitparm[2] = fitparm[4] = fitparm[6] = 0.25*c1[0]; - fitparm[1] = 0.1; - fitparm[3] = 1; - fitparm[5] = 10; - fitparm[7] = 100; - fitparm[8] = 0; + fitparm[0] = fitparm[2] = fitparm[4] = fitparm[6] = 0.25 * c1[0]; + fitparm[1] = 0.1; + fitparm[3] = 1; + fitparm[5] = 10; + fitparm[7] = 100; + fitparm[8] = 0; break; default: fprintf(out, "Warning: don't know how to initialize the parameters\n"); @@ -890,15 +891,13 @@ static void do_fit(FILE *out, int n, gmx_bool bYdy, fprintf(out, "Starting parameters:\n"); for (i = 0; (i < nparm); i++) { - fprintf(out, "a%-2d = %12.5e\n", i+1, fitparm[i]); + fprintf(out, "a%-2d = %12.5e\n", i + 1, fitparm[i]); } - if (do_lmfit(ny, c1, sig, 0, x0, tbeginfit, tendfit, - oenv, bDebugMode(), efitfn, fitparm, 0, - fn_fitted) > 0) + if (do_lmfit(ny, c1, sig, 0, x0, tbeginfit, tendfit, oenv, bDebugMode(), efitfn, fitparm, 0, fn_fitted) > 0) { for (i = 0; (i < nparm); i++) { - fprintf(out, "a%-2d = %12.5e\n", i+1, fitparm[i]); + fprintf(out, "a%-2d = %12.5e\n", i + 1, fitparm[i]); } } else @@ -907,37 +906,36 @@ static void do_fit(FILE *out, int n, gmx_bool bYdy, } } -static void print_fitted_function(const char *fitfile, - const char *fn_fitted, +static void print_fitted_function(const char* fitfile, + const char* fn_fitted, gmx_bool bXYdy, int nset, int n, - real *t, - real **val, + real* t, + real** val, int npargs, - t_pargs *ppa, - gmx_output_env_t *oenv) + t_pargs* ppa, + gmx_output_env_t* oenv) { - FILE *out_fit = gmx_ffopen(fitfile, "w"); + FILE* out_fit = gmx_ffopen(fitfile, "w"); if (bXYdy && nset >= 2) { - do_fit(out_fit, 0, TRUE, n, t, val, npargs, ppa, oenv, - fn_fitted); + do_fit(out_fit, 0, TRUE, n, t, val, npargs, ppa, oenv, fn_fitted); } else { - char *buf2 = nullptr; + char* buf2 = nullptr; int s, buflen = 0; if (nullptr != fn_fitted) { - buflen = std::strlen(fn_fitted)+32; + buflen = std::strlen(fn_fitted) + 32; snew(buf2, buflen); std::strncpy(buf2, fn_fitted, buflen); - buf2[std::strlen(buf2)-4] = '\0'; + buf2[std::strlen(buf2) - 4] = '\0'; } for (s = 0; s < nset; s++) { - char *buf = nullptr; + char* buf = nullptr; if (nullptr != fn_fitted) { snew(buf, buflen); @@ -951,9 +949,9 @@ static void print_fitted_function(const char *fitfile, gmx_ffclose(out_fit); } -int gmx_analyze(int argc, char *argv[]) +int gmx_analyze(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] reads an ASCII file and analyzes data sets.", "A line in the input file may start with a time", "(see option [TT]-time[tt]) and any number of [IT]y[it]-values may follow.", @@ -979,7 +977,8 @@ int gmx_analyze(int argc, char *argv[]) "Option [TT]-cc[tt] plots the resemblance of set i with a cosine of", "i/2 periods. The formula is::", "", - " [MATH]2 ([INT][FROM]0[from][TO]T[to][int] y(t) [COS]i [GRK]pi[grk] t[cos] dt)^2 / [INT][FROM]0[from][TO]T[to][int] y^2(t) dt[math]", + " [MATH]2 ([INT][FROM]0[from][TO]T[to][int] y(t) [COS]i [GRK]pi[grk] t[cos] dt)^2 ", + " / [INT][FROM]0[from][TO]T[to][int] y^2(t) dt[math]", "", "This is useful for principal components obtained from covariance", "analysis, since the principal components of random diffusion are", @@ -1006,13 +1005,19 @@ int gmx_analyze(int argc, char *argv[]) "that the autocorrelation is a sum of two exponentials.", "The analytical curve for the block average is::", "", - " [MATH]f(t) = [GRK]sigma[grk][TT]*[tt][SQRT]2/T ( [GRK]alpha[grk] ([GRK]tau[grk][SUB]1[sub] (([EXP]-t/[GRK]tau[grk][SUB]1[sub][exp] - 1) [GRK]tau[grk][SUB]1[sub]/t + 1)) +", - " (1-[GRK]alpha[grk]) ([GRK]tau[grk][SUB]2[sub] (([EXP]-t/[GRK]tau[grk][SUB]2[sub][exp] - 1) [GRK]tau[grk][SUB]2[sub]/t + 1)))[sqrt][math],", + " [MATH]f(t) = [GRK]sigma[grk][TT]*[tt][SQRT]2/T ( [GRK]alpha[grk] ", + " ([GRK]tau[grk][SUB]1[sub] (([EXP]-t/[GRK]tau[grk][SUB]1[sub][exp] - 1) ", + " [GRK]tau[grk][SUB]1[sub]/t + 1)) +", + " (1-[GRK]alpha[grk]) ([GRK]tau[grk][SUB]2[sub] ", + " (([EXP]-t/[GRK]tau[grk][SUB]2[sub][exp] - 1) [GRK]tau[grk][SUB]2[sub]/t + ", + " 1)))[sqrt][math],", "", "where T is the total time.", - "[GRK]alpha[grk], [GRK]tau[grk][SUB]1[sub] and [GRK]tau[grk][SUB]2[sub] are obtained by fitting f^2(t) to error^2.", + "[GRK]alpha[grk], [GRK]tau[grk][SUB]1[sub] and [GRK]tau[grk][SUB]2[sub] are ", + "obtained by fitting f^2(t) to error^2.", "When the actual block average is very close to the analytical curve,", - "the error is [MATH][GRK]sigma[grk][TT]*[tt][SQRT]2/T (a [GRK]tau[grk][SUB]1[sub] + (1-a) [GRK]tau[grk][SUB]2[sub])[sqrt][math].", + "the error is [MATH][GRK]sigma[grk][TT]*[tt][SQRT]2/T (a [GRK]tau[grk][SUB]1[sub] ", + "+ (1-a) [GRK]tau[grk][SUB]2[sub])[sqrt][math].", "The complete derivation is given in", "B. Hess, J. Chem. Phys. 116:209-217, 2002.[PAR]", @@ -1040,104 +1045,135 @@ int gmx_analyze(int argc, char *argv[]) "original data and the fitted function to a new data file. The fitting", "parameters are stored as comment in the output file." }; - static real tb = -1, te = -1, frac = 0.5, filtlen = 0, binwidth = 0.1, aver_start = 0; - static gmx_bool bHaveT = TRUE, bDer = FALSE, bSubAv = TRUE, bAverCorr = FALSE, bXYdy = FALSE; - static gmx_bool bEESEF = FALSE, bEENLC = FALSE, bEeFitAc = FALSE, bPower = FALSE; - static gmx_bool bIntegrate = FALSE, bRegression = FALSE, bLuzar = FALSE; - static int nsets_in = 1, d = 1, nb_min = 4, resol = 10; - static real temp = 298.15, fit_start = 1, fit_end = 60; + static real tb = -1, te = -1, frac = 0.5, filtlen = 0, binwidth = 0.1, aver_start = 0; + static gmx_bool bHaveT = TRUE, bDer = FALSE, bSubAv = TRUE, bAverCorr = FALSE, bXYdy = FALSE; + static gmx_bool bEESEF = FALSE, bEENLC = FALSE, bEeFitAc = FALSE, bPower = FALSE; + static gmx_bool bIntegrate = FALSE, bRegression = FALSE, bLuzar = FALSE; + static int nsets_in = 1, d = 1, nb_min = 4, resol = 10; + static real temp = 298.15, fit_start = 1, fit_end = 60; /* must correspond to enum avbar* declared at beginning of file */ - static const char *avbar_opt[avbarNR+1] = { - nullptr, "none", "stddev", "error", "90", nullptr - }; - - t_pargs pa[] = { - { "-time", FALSE, etBOOL, {&bHaveT}, - "Expect a time in the input" }, - { "-b", FALSE, etREAL, {&tb}, - "First time to read from set" }, - { "-e", FALSE, etREAL, {&te}, - "Last time to read from set" }, - { "-n", FALSE, etINT, {&nsets_in}, - "Read this number of sets separated by &" }, - { "-d", FALSE, etBOOL, {&bDer}, - "Use the derivative" }, - { "-dp", FALSE, etINT, {&d}, + static const char* avbar_opt[avbarNR + 1] = { nullptr, "none", "stddev", "error", "90", nullptr }; + + t_pargs pa[] = { + { "-time", FALSE, etBOOL, { &bHaveT }, "Expect a time in the input" }, + { "-b", FALSE, etREAL, { &tb }, "First time to read from set" }, + { "-e", FALSE, etREAL, { &te }, "Last time to read from set" }, + { "-n", FALSE, etINT, { &nsets_in }, "Read this number of sets separated by &" }, + { "-d", FALSE, etBOOL, { &bDer }, "Use the derivative" }, + { "-dp", + FALSE, + etINT, + { &d }, "HIDDENThe derivative is the difference over this number of points" }, - { "-bw", FALSE, etREAL, {&binwidth}, - "Binwidth for the distribution" }, - { "-errbar", FALSE, etENUM, {avbar_opt}, - "Error bars for [TT]-av[tt]" }, - { "-integrate", FALSE, etBOOL, {&bIntegrate}, + { "-bw", FALSE, etREAL, { &binwidth }, "Binwidth for the distribution" }, + { "-errbar", FALSE, etENUM, { avbar_opt }, "Error bars for [TT]-av[tt]" }, + { "-integrate", + FALSE, + etBOOL, + { &bIntegrate }, "Integrate data function(s) numerically using trapezium rule" }, - { "-aver_start", FALSE, etREAL, {&aver_start}, - "Start averaging the integral from here" }, - { "-xydy", FALSE, etBOOL, {&bXYdy}, + { "-aver_start", FALSE, etREAL, { &aver_start }, "Start averaging the integral from here" }, + { "-xydy", + FALSE, + etBOOL, + { &bXYdy }, "Interpret second data set as error in the y values for integrating" }, - { "-regression", FALSE, etBOOL, {&bRegression}, - "Perform a linear regression analysis on the data. If [TT]-xydy[tt] is set a second set will be interpreted as the error bar in the Y value. Otherwise, if multiple data sets are present a multilinear regression will be performed yielding the constant A that minimize [MATH][GRK]chi[grk]^2 = (y - A[SUB]0[sub] x[SUB]0[sub] - A[SUB]1[sub] x[SUB]1[sub] - ... - A[SUB]N[sub] x[SUB]N[sub])^2[math] where now Y is the first data set in the input file and x[SUB]i[sub] the others. Do read the information at the option [TT]-time[tt]." }, - { "-luzar", FALSE, etBOOL, {&bLuzar}, + { "-regression", + FALSE, + etBOOL, + { &bRegression }, + "Perform a linear regression analysis on the data. If [TT]-xydy[tt] is set a second set " + "will be interpreted as the error bar in the Y value. Otherwise, if multiple data sets " + "are present a multilinear regression will be performed yielding the constant A that " + "minimize [MATH][GRK]chi[grk]^2 = (y - A[SUB]0[sub] x[SUB]0[sub] - A[SUB]1[sub] " + "x[SUB]1[sub] - ... - A[SUB]N[sub] x[SUB]N[sub])^2[math] where now Y is the first data " + "set in the input file and x[SUB]i[sub] the others. Do read the information at the " + "option [TT]-time[tt]." }, + { "-luzar", + FALSE, + etBOOL, + { &bLuzar }, "Do a Luzar and Chandler analysis on a correlation function and " "related as produced by [gmx-hbond]. When in addition the " "[TT]-xydy[tt] flag is given the second and fourth column will be " "interpreted as errors in c(t) and n(t)." }, - { "-temp", FALSE, etREAL, {&temp}, + { "-temp", + FALSE, + etREAL, + { &temp }, "Temperature for the Luzar hydrogen bonding kinetics analysis (K)" }, - { "-fitstart", FALSE, etREAL, {&fit_start}, - "Time (ps) from which to start fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation" }, - { "-fitend", FALSE, etREAL, {&fit_end}, - "Time (ps) where to stop fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation. Only with [TT]-gem[tt]" }, - { "-nbmin", FALSE, etINT, {&nb_min}, + { "-fitstart", + FALSE, + etREAL, + { &fit_start }, + "Time (ps) from which to start fitting the correlation functions in order to obtain the " + "forward and backward rate constants for HB breaking and formation" }, + { "-fitend", + FALSE, + etREAL, + { &fit_end }, + "Time (ps) where to stop fitting the correlation functions in order to obtain the " + "forward and backward rate constants for HB breaking and formation. Only with " + "[TT]-gem[tt]" }, + { "-nbmin", + FALSE, + etINT, + { &nb_min }, "HIDDENMinimum number of blocks for block averaging" }, - { "-resol", FALSE, etINT, {&resol}, + { "-resol", + FALSE, + etINT, + { &resol }, "HIDDENResolution for the block averaging, block size increases with" " a factor 2^(1/resol)" }, - { "-eeexpfit", FALSE, etBOOL, {&bEESEF}, + { "-eeexpfit", + FALSE, + etBOOL, + { &bEESEF }, "HIDDENAlways use a single exponential fit for the error estimate" }, - { "-eenlc", FALSE, etBOOL, {&bEENLC}, - "HIDDENAllow a negative long-time correlation" }, - { "-eefitac", FALSE, etBOOL, {&bEeFitAc}, + { "-eenlc", FALSE, etBOOL, { &bEENLC }, "HIDDENAllow a negative long-time correlation" }, + { "-eefitac", + FALSE, + etBOOL, + { &bEeFitAc }, "HIDDENAlso plot analytical block average using a autocorrelation fit" }, - { "-filter", FALSE, etREAL, {&filtlen}, - "Print the high-frequency fluctuation after filtering with a cosine filter of this length" }, - { "-power", FALSE, etBOOL, {&bPower}, - "Fit data to: b t^a" }, - { "-subav", FALSE, etBOOL, {&bSubAv}, - "Subtract the average before autocorrelating" }, - { "-oneacf", FALSE, etBOOL, {&bAverCorr}, - "Calculate one ACF over all sets" }, + { "-filter", + FALSE, + etREAL, + { &filtlen }, + "Print the high-frequency fluctuation after filtering with a cosine filter of this " + "length" }, + { "-power", FALSE, etBOOL, { &bPower }, "Fit data to: b t^a" }, + { "-subav", FALSE, etBOOL, { &bSubAv }, "Subtract the average before autocorrelating" }, + { "-oneacf", FALSE, etBOOL, { &bAverCorr }, "Calculate one ACF over all sets" }, }; #define NPA asize(pa) - FILE *out; + FILE* out; int n, nlast, s, nset, i, j = 0; - real **val, *t, dt, tot, error; - double *av, *sig, cum1, cum2, cum3, cum4, db; - const char *acfile, *msdfile, *ccfile, *distfile, *avfile, *eefile, *fitfile; - gmx_output_env_t *oenv; - - t_filenm fnm[] = { - { efXVG, "-f", "graph", ffREAD }, - { efXVG, "-ac", "autocorr", ffOPTWR }, - { efXVG, "-msd", "msd", ffOPTWR }, - { efXVG, "-cc", "coscont", ffOPTWR }, - { efXVG, "-dist", "distr", ffOPTWR }, - { efXVG, "-av", "average", ffOPTWR }, - { efXVG, "-ee", "errest", ffOPTWR }, - { efXVG, "-fitted", "fitted", ffOPTWR }, - { efLOG, "-g", "fitlog", ffOPTWR } + real ** val, *t, dt, tot, error; + double * av, *sig, cum1, cum2, cum3, cum4, db; + const char * acfile, *msdfile, *ccfile, *distfile, *avfile, *eefile, *fitfile; + gmx_output_env_t* oenv; + + t_filenm fnm[] = { + { efXVG, "-f", "graph", ffREAD }, { efXVG, "-ac", "autocorr", ffOPTWR }, + { efXVG, "-msd", "msd", ffOPTWR }, { efXVG, "-cc", "coscont", ffOPTWR }, + { efXVG, "-dist", "distr", ffOPTWR }, { efXVG, "-av", "average", ffOPTWR }, + { efXVG, "-ee", "errest", ffOPTWR }, { efXVG, "-fitted", "fitted", ffOPTWR }, + { efLOG, "-g", "fitlog", ffOPTWR } }; #define NFILE asize(fnm) int npargs; - t_pargs *ppa; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, asize(desc), desc, 0, + nullptr, &oenv)) { sfree(ppa); return 0; @@ -1151,29 +1187,26 @@ int gmx_analyze(int argc, char *argv[]) eefile = opt2fn_null("-ee", NFILE, fnm); if (opt2parg_bSet("-fitfn", npargs, ppa) && acfile == nullptr) { - fitfile = opt2fn("-g", NFILE, fnm); + fitfile = opt2fn("-g", NFILE, fnm); } else { - fitfile = opt2fn_null("-g", NFILE, fnm); + fitfile = opt2fn_null("-g", NFILE, fnm); } - val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, - opt2parg_bSet("-b", npargs, ppa), tb, - opt2parg_bSet("-e", npargs, ppa), te, - nsets_in, &nset, &n, &dt, &t); + val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, opt2parg_bSet("-b", npargs, ppa), tb, + opt2parg_bSet("-e", npargs, ppa), te, nsets_in, &nset, &n, &dt, &t); printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt); if (bDer) { - printf("Calculating the derivative as (f[i+%d]-f[i])/(%d*dt)\n\n", - d, d); + printf("Calculating the derivative as (f[i+%d]-f[i])/(%d*dt)\n\n", d, d); n -= d; for (s = 0; s < nset; s++) { for (i = 0; (i < n); i++) { - val[s][i] = (val[s][i+d]-val[s][i])/(d*dt); + val[s][i] = (val[s][i + d] - val[s][i]) / (d * dt); } } } @@ -1194,19 +1227,15 @@ int gmx_analyze(int argc, char *argv[]) for (s = 0; s < nset; s++) { sum = evaluate_integral(n, t, val[s], nullptr, aver_start, &stddev); - printf("Integral %d %10.5f +/- %10.5f\n", s+1, sum, stddev); + printf("Integral %d %10.5f +/- %10.5f\n", s + 1, sum, stddev); } } } if (fitfile != nullptr) { - print_fitted_function(fitfile, - opt2fn_null("-fitted", NFILE, fnm), - bXYdy, nset, - n, t, val, - npargs, ppa, - oenv); + print_fitted_function(fitfile, opt2fn_null("-fitted", NFILE, fnm), bXYdy, nset, n, t, val, + npargs, ppa, oenv); } printf(" std. dev. relative deviation of\n"); @@ -1228,28 +1257,27 @@ int gmx_analyze(int argc, char *argv[]) cum1 /= n; for (i = 0; (i < n); i++) { - db = val[s][i]-cum1; - cum2 += db*db; - cum3 += db*db*db; - cum4 += db*db*db*db; + db = val[s][i] - cum1; + cum2 += db * db; + cum3 += db * db * db; + cum4 += db * db * db * db; } - cum2 /= n; - cum3 /= n; - cum4 /= n; + cum2 /= n; + cum3 /= n; + cum4 /= n; av[s] = cum1; sig[s] = std::sqrt(cum2); if (n > 1) { - error = std::sqrt(cum2/(n-1)); + error = std::sqrt(cum2 / (n - 1)); } else { error = 0; } - printf("SS%d %13.6e %12.6e %12.6e %6.3f %6.3f\n", - s+1, av[s], sig[s], error, - sig[s] != 0.0 ? cum3/(sig[s]*sig[s]*sig[s]*std::sqrt(8/M_PI)) : 0, - sig[s] != 0.0 ? cum4/(sig[s]*sig[s]*sig[s]*sig[s]*3)-1 : 0); + printf("SS%d %13.6e %12.6e %12.6e %6.3f %6.3f\n", s + 1, av[s], sig[s], error, + sig[s] != 0.0 ? cum3 / (sig[s] * sig[s] * sig[s] * std::sqrt(8 / M_PI)) : 0, + sig[s] != 0.0 ? cum4 / (sig[s] * sig[s] * sig[s] * sig[s] * 3) - 1 : 0); } printf("\n"); @@ -1260,9 +1288,8 @@ int gmx_analyze(int argc, char *argv[]) if (msdfile) { - out = xvgropen(msdfile, "Mean square displacement", - "time", "MSD (nm\\S2\\N)", oenv); - nlast = static_cast(n*frac); + out = xvgropen(msdfile, "Mean square displacement", "time", "MSD (nm\\S2\\N)", oenv); + nlast = static_cast(n * frac); for (s = 0; s < nset; s++) { for (j = 0; j <= nlast; j++) @@ -1273,20 +1300,20 @@ int gmx_analyze(int argc, char *argv[]) fflush(stderr); } tot = 0; - for (i = 0; i < n-j; i++) + for (i = 0; i < n - j; i++) { - tot += gmx::square(val[s][i]-val[s][i+j]); + tot += gmx::square(val[s][i] - val[s][i + j]); } - tot /= (n-j); - fprintf(out, " %g %8g\n", dt*j, tot); + tot /= (n - j); + fprintf(out, " %g %8g\n", dt * j, tot); } - if (s < nset-1) + if (s < nset - 1) { fprintf(out, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } } xvgrclose(out); - fprintf(stderr, "\r%d, time=%g\n", j-1, (j-1)*dt); + fprintf(stderr, "\r%d, time=%g\n", j - 1, (j - 1) * dt); fflush(stderr); } if (ccfile) @@ -1304,8 +1331,7 @@ int gmx_analyze(int argc, char *argv[]) } if (eefile) { - estimate_error(eefile, nb_min, resol, n, nset, av, sig, val, dt, - bEeFitAc, bEESEF, bEENLC, oenv); + estimate_error(eefile, nb_min, resol, n, nset, av, sig, val, dt, bEeFitAc, bEESEF, bEENLC, oenv); } if (bPower) { @@ -1324,8 +1350,7 @@ int gmx_analyze(int argc, char *argv[]) } } } - do_autocorr(acfile, oenv, "Autocorrelation", n, nset, val, dt, - eacNormal, bAverCorr); + do_autocorr(acfile, oenv, "Autocorrelation", n, nset, val, dt, eacNormal, bAverCorr); } if (bRegression) diff --git a/src/gromacs/gmxana/gmx_angle.cpp b/src/gromacs/gmxana/gmx_angle.cpp index 1b56598e0f..0a92c634d8 100644 --- a/src/gromacs/gmxana/gmx_angle.cpp +++ b/src/gromacs/gmxana/gmx_angle.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,25 +59,23 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -static void dump_dih_trr(int nframes, int nangles, real **dih, const char *fn, - real *time) +static void dump_dih_trr(int nframes, int nangles, real** dih, const char* fn, real* time) { int i, j, k, l, m, na; - struct t_fileio *fio; - rvec *x; - matrix box = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}}; + struct t_fileio* fio; + rvec* x; + matrix box = { { 2, 0, 0 }, { 0, 2, 0 }, { 0, 0, 2 } }; - na = (nangles*2); + na = (nangles * 2); if ((na % 3) != 0) { - na = 1+na/3; + na = 1 + na / 3; } else { - na = na/3; + na = na / 3; } - printf("There are %d dihedrals. Will fill %d atom positions with cos/sin\n", - nangles, na); + printf("There are %d dihedrals. Will fill %d atom positions with cos/sin\n", nangles, na); snew(x, na); fio = gmx_trr_open(fn, "w"); for (i = 0; (i < nframes); i++) @@ -107,9 +105,9 @@ static void dump_dih_trr(int nframes, int nangles, real **dih, const char *fn, sfree(x); } -int gmx_g_angle(int argc, char *argv[]) +int gmx_g_angle(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] computes the angle distribution for a number of angles", "or dihedrals.[PAR]", "With option [TT]-ov[tt], you can plot the average angle of", @@ -130,66 +128,71 @@ int gmx_g_angle(int argc, char *argv[]) "records a histogram of the times between such transitions,", "assuming the input trajectory frames are equally spaced in time." }; - static const char *opt[] = { nullptr, "angle", "dihedral", "improper", "ryckaert-bellemans", nullptr }; - static gmx_bool bALL = FALSE, bChandler = FALSE, bAverCorr = FALSE, bPBC = TRUE; + static const char* opt[] = { nullptr, "angle", "dihedral", "improper", "ryckaert-bellemans", + nullptr }; + static gmx_bool bALL = FALSE, bChandler = FALSE, bAverCorr = FALSE, bPBC = TRUE; static real binwidth = 1; t_pargs pa[] = { - { "-type", FALSE, etENUM, {opt}, - "Type of angle to analyse" }, - { "-all", FALSE, etBOOL, {&bALL}, - "Plot all angles separately in the averages file, in the order of appearance in the index file." }, - { "-binwidth", FALSE, etREAL, {&binwidth}, + { "-type", FALSE, etENUM, { opt }, "Type of angle to analyse" }, + { "-all", + FALSE, + etBOOL, + { &bALL }, + "Plot all angles separately in the averages file, in the order of appearance in the " + "index file." }, + { "-binwidth", + FALSE, + etREAL, + { &binwidth }, "binwidth (degrees) for calculating the distribution" }, - { "-periodic", FALSE, etBOOL, {&bPBC}, - "Print dihedral angles modulo 360 degrees" }, - { "-chandler", FALSE, etBOOL, {&bChandler}, - "Use Chandler correlation function (N[trans] = 1, N[gauche] = 0) rather than cosine correlation function. Trans is defined as phi < -60 or phi > 60." }, - { "-avercorr", FALSE, etBOOL, {&bAverCorr}, + { "-periodic", FALSE, etBOOL, { &bPBC }, "Print dihedral angles modulo 360 degrees" }, + { "-chandler", + FALSE, + etBOOL, + { &bChandler }, + "Use Chandler correlation function (N[trans] = 1, N[gauche] = 0) rather than cosine " + "correlation function. Trans is defined as phi < -60 or phi > 60." }, + { "-avercorr", + FALSE, + etBOOL, + { &bAverCorr }, "Average the correlation functions for the individual angles/dihedrals" } }; - static const char *bugs[] = { + static const char* bugs[] = { "Counting transitions only works for dihedrals with multiplicity 3" }; - FILE *out; - real dt; - int isize; - int *index; - char *grpname; - real maxang, S2, norm_fac, maxstat; - unsigned long mode; - int nframes, maxangstat, mult, *angstat; - int i, j, nangles, first, last; - gmx_bool bAver, bRb, bPeriodic, - bFrac, /* calculate fraction too? */ - bTrans, /* worry about transtions too? */ - bCorr; /* correlation function ? */ - real aver, aver2, aversig; /* fraction trans dihedrals */ - double tfrac = 0; - char title[256]; - real **dih = nullptr; /* mega array with all dih. angles at all times*/ - real *time, *trans_frac, *aver_angle; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, "angle", ffREAD }, - { efXVG, "-od", "angdist", ffWRITE }, - { efXVG, "-ov", "angaver", ffOPTWR }, - { efXVG, "-of", "dihfrac", ffOPTWR }, - { efXVG, "-ot", "dihtrans", ffOPTWR }, - { efXVG, "-oh", "trhisto", ffOPTWR }, - { efXVG, "-oc", "dihcorr", ffOPTWR }, - { efTRR, "-or", nullptr, ffOPTWR } - }; + FILE* out; + real dt; + int isize; + int* index; + char* grpname; + real maxang, S2, norm_fac, maxstat; + unsigned long mode; + int nframes, maxangstat, mult, *angstat; + int i, j, nangles, first, last; + gmx_bool bAver, bRb, bPeriodic, bFrac, /* calculate fraction too? */ + bTrans, /* worry about transtions too? */ + bCorr; /* correlation function ? */ + real aver, aver2, aversig; /* fraction trans dihedrals */ + double tfrac = 0; + char title[256]; + real** dih = nullptr; /* mega array with all dih. angles at all times*/ + real * time, *trans_frac, *aver_angle; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efNDX, nullptr, "angle", ffREAD }, + { efXVG, "-od", "angdist", ffWRITE }, { efXVG, "-ov", "angaver", ffOPTWR }, + { efXVG, "-of", "dihfrac", ffOPTWR }, { efXVG, "-ot", "dihtrans", ffOPTWR }, + { efXVG, "-oh", "trhisto", ffOPTWR }, { efXVG, "-oc", "dihcorr", ffOPTWR }, + { efTRR, "-or", nullptr, ffOPTWR } }; #define NFILE asize(fnm) int npargs; - t_pargs *ppa; - gmx_output_env_t *oenv; + t_pargs* ppa; + gmx_output_env_t* oenv; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { sfree(ppa); return 0; @@ -199,7 +202,8 @@ int gmx_g_angle(int argc, char *argv[]) maxang = 360.0; bRb = FALSE; - GMX_RELEASE_ASSERT(opt[0] != nullptr, "Internal option inconsistency; opt[0]==NULL after processing"); + GMX_RELEASE_ASSERT(opt[0] != nullptr, + "Internal option inconsistency; opt[0]==NULL after processing"); switch (opt[0][0]) { @@ -207,13 +211,9 @@ int gmx_g_angle(int argc, char *argv[]) mult = 3; maxang = 180.0; break; - case 'd': - break; - case 'i': - break; - case 'r': - bRb = TRUE; - break; + case 'd': break; + case 'i': break; + case 'r': bRb = TRUE; break; } if (opt2bSet("-or", NFILE, fnm)) @@ -229,14 +229,15 @@ int gmx_g_angle(int argc, char *argv[]) } /* Calculate bin size */ - maxangstat = gmx::roundToInt(maxang/binwidth); - binwidth = maxang/maxangstat; + maxangstat = gmx::roundToInt(maxang / binwidth); + binwidth = maxang / maxangstat; rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); - nangles = isize/mult; + nangles = isize / mult; if ((isize % mult) != 0) { - gmx_fatal(FARGS, "number of index elements not multiple of %d, " + gmx_fatal(FARGS, + "number of index elements not multiple of %d, " "these can not be %s\n", mult, (mult == 3) ? "angle triplets" : "dihedral quadruplets"); } @@ -260,15 +261,17 @@ int gmx_g_angle(int argc, char *argv[]) if (bFrac && !bRb) { - fprintf(stderr, "Warning:" + fprintf(stderr, + "Warning:" " calculating fractions as defined in this program\n" "makes sense for Ryckaert Bellemans dihs. only. Ignoring -of\n\n"); bFrac = FALSE; } - if ( (bTrans || bFrac || bCorr) && mult == 3) + if ((bTrans || bFrac || bCorr) && mult == 3) { - gmx_fatal(FARGS, "Can only do transition, fraction or correlation\n" + gmx_fatal(FARGS, + "Can only do transition, fraction or correlation\n" "on dihedrals. Select -d\n"); } @@ -276,7 +279,7 @@ int gmx_g_angle(int argc, char *argv[]) * We need to know the nr of frames so we can allocate memory for an array * with all dihedral angles at all timesteps. Works for me. */ - if (bTrans || bCorr || bALL || opt2bSet("-or", NFILE, fnm)) + if (bTrans || bCorr || bALL || opt2bSet("-or", NFILE, fnm)) { snew(dih, nangles); } @@ -284,21 +287,18 @@ int gmx_g_angle(int argc, char *argv[]) snew(angstat, maxangstat); read_ang_dih(ftp2fn(efTRX, NFILE, fnm), (mult == 3), - bALL || bCorr || bTrans || opt2bSet("-or", NFILE, fnm), - bRb, bPBC, maxangstat, angstat, - &nframes, &time, isize, index, &trans_frac, &aver_angle, dih, - oenv); + bALL || bCorr || bTrans || opt2bSet("-or", NFILE, fnm), bRb, bPBC, maxangstat, + angstat, &nframes, &time, isize, index, &trans_frac, &aver_angle, dih, oenv); - dt = (time[nframes-1]-time[0])/(nframes-1); + dt = (time[nframes - 1] - time[0]) / (nframes - 1); if (bAver) { sprintf(title, "Average Angle: %s", grpname); - out = xvgropen(opt2fn("-ov", NFILE, fnm), - title, "Time (ps)", "Angle (degrees)", oenv); + out = xvgropen(opt2fn("-ov", NFILE, fnm), title, "Time (ps)", "Angle (degrees)", oenv); for (i = 0; (i < nframes); i++) { - fprintf(out, "%10.5f %8.3f", time[i], aver_angle[i]*RAD2DEG); + fprintf(out, "%10.5f %8.3f", time[i], aver_angle[i] * RAD2DEG); if (bALL) { for (j = 0; (j < nangles); j++) @@ -306,11 +306,11 @@ int gmx_g_angle(int argc, char *argv[]) if (bPBC) { real dd = dih[j][i]; - fprintf(out, " %8.3f", std::atan2(std::sin(dd), std::cos(dd))*RAD2DEG); + fprintf(out, " %8.3f", std::atan2(std::sin(dd), std::cos(dd)) * RAD2DEG); } else { - fprintf(out, " %8.3f", dih[j][i]*RAD2DEG); + fprintf(out, " %8.3f", dih[j][i] * RAD2DEG); } } } @@ -326,8 +326,7 @@ int gmx_g_angle(int argc, char *argv[]) if (bFrac) { sprintf(title, "Trans fraction: %s", grpname); - out = xvgropen(opt2fn("-of", NFILE, fnm), - title, "Time (ps)", "Fraction", oenv); + out = xvgropen(opt2fn("-of", NFILE, fnm), title, "Time (ps)", "Fraction", oenv); tfrac = 0.0; for (i = 0; (i < nframes); i++) { @@ -343,8 +342,8 @@ int gmx_g_angle(int argc, char *argv[]) if (bTrans) { - ana_dih_trans(opt2fn("-ot", NFILE, fnm), opt2fn("-oh", NFILE, fnm), - dih, nframes, nangles, grpname, time, bRb, oenv); + ana_dih_trans(opt2fn("-ot", NFILE, fnm), opt2fn("-oh", NFILE, fnm), dih, nframes, nangles, + grpname, time, bRb, oenv); } if (bCorr) @@ -359,7 +358,7 @@ int gmx_g_angle(int argc, char *argv[]) if (bChandler) { - real dval, sixty = DEG2RAD*60; + real dval, sixty = DEG2RAD * 60; gmx_bool bTest; for (i = 0; (i < nangles); i++) @@ -377,7 +376,7 @@ int gmx_g_angle(int argc, char *argv[]) } if (bTest) { - dih[i][j] = dval-tfrac; + dih[i][j] = dval - tfrac; } else { @@ -394,34 +393,26 @@ int gmx_g_angle(int argc, char *argv[]) { mode = eacCos; } - do_autocorr(opt2fn("-oc", NFILE, fnm), oenv, - "Dihedral Autocorrelation Function", + do_autocorr(opt2fn("-oc", NFILE, fnm), oenv, "Dihedral Autocorrelation Function", nframes, nangles, dih, dt, mode, bAverCorr); } } /* Determine the non-zero part of the distribution */ - for (first = 0; (first < maxangstat-1) && (angstat[first+1] == 0); first++) - { - ; - } - for (last = maxangstat-1; (last > 0) && (angstat[last-1] == 0); last--) - { - ; - } + for (first = 0; (first < maxangstat - 1) && (angstat[first + 1] == 0); first++) {} + for (last = maxangstat - 1; (last > 0) && (angstat[last - 1] == 0); last--) {} aver = aver2 = 0; for (i = 0; (i < nframes); i++) { - aver += RAD2DEG*aver_angle[i]; - aver2 += gmx::square(RAD2DEG*aver_angle[i]); + aver += RAD2DEG * aver_angle[i]; + aver2 += gmx::square(RAD2DEG * aver_angle[i]); } - aver /= nframes; - aver2 /= nframes; - aversig = std::sqrt(aver2-gmx::square(aver)); - printf("Found points in the range from %d to %d (max %d)\n", - first, last, maxangstat); + aver /= nframes; + aver2 /= nframes; + aversig = std::sqrt(aver2 - gmx::square(aver)); + printf("Found points in the range from %d to %d (max %d)\n", first, last, maxangstat); printf(" < angle > = %g\n", aver); printf("< angle^2 > = %g\n", aver2); printf("Std. Dev. = %g\n", aversig); @@ -438,20 +429,20 @@ int gmx_g_angle(int argc, char *argv[]) fprintf(stderr, "Order parameter S^2 = %g\n", S2); } - bPeriodic = (mult == 4) && (first == 0) && (last == maxangstat-1); + bPeriodic = (mult == 4) && (first == 0) && (last == maxangstat - 1); out = xvgropen(opt2fn("-od", NFILE, fnm), title, "Degrees", "", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(out, "@ subtitle \"average angle: %g\\So\\N\"\n", aver); } - norm_fac = 1.0/(nangles*nframes*binwidth); + norm_fac = 1.0 / (nangles * nframes * binwidth); if (bPeriodic) { maxstat = 0; for (i = first; (i <= last); i++) { - maxstat = std::max(maxstat, angstat[i]*norm_fac); + maxstat = std::max(maxstat, angstat[i] * norm_fac); } if (output_env_get_print_xvgr_codes(oenv)) { @@ -459,7 +450,7 @@ int gmx_g_angle(int argc, char *argv[]) fprintf(out, "@ world xmin -180\n"); fprintf(out, "@ world xmax 180\n"); fprintf(out, "@ world ymin 0\n"); - fprintf(out, "@ world ymax %g\n", maxstat*1.05); + fprintf(out, "@ world ymax %g\n", maxstat * 1.05); fprintf(out, "@ xaxis tick major 60\n"); fprintf(out, "@ xaxis tick minor 30\n"); fprintf(out, "@ yaxis tick major 0.005\n"); @@ -468,12 +459,12 @@ int gmx_g_angle(int argc, char *argv[]) } for (i = first; (i <= last); i++) { - fprintf(out, "%10g %10f\n", i*binwidth+180.0-maxang, angstat[i]*norm_fac); + fprintf(out, "%10g %10f\n", i * binwidth + 180.0 - maxang, angstat[i] * norm_fac); } if (bPeriodic) { /* print first bin again as last one */ - fprintf(out, "%10g %10f\n", 180.0, angstat[0]*norm_fac); + fprintf(out, "%10g %10f\n", 180.0, angstat[0] * norm_fac); } xvgrclose(out); diff --git a/src/gromacs/gmxana/gmx_awh.cpp b/src/gromacs/gmxana/gmx_awh.cpp index 1d7463bdaa..e0d8d94893 100644 --- a/src/gromacs/gmxana/gmx_awh.cpp +++ b/src/gromacs/gmxana/gmx_awh.cpp @@ -73,8 +73,8 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -using gmx::AwhParams; using gmx::AwhBiasParams; +using gmx::AwhParams; namespace { @@ -98,82 +98,76 @@ enum class EnergyUnit /*! \brief All meta-data that is shared for one output file type for one bias */ class OutputFile { - public: - /*! \brief Constructor, Set the output base file name and title. - * - * Result is a valid object, but will produce empty output files. - * - * \param[in] filename The name for output files, frame time, and possibly bias number, will be added per file/frame. - * \param[in] baseTitle The base title of the plot, the bias number might be added. - * \param[in] numBias The total number of AWH biases in the system. - * \param[in] biasIndex The index of this bias. - */ - OutputFile(const std::string &filename, - const std::string &baseTitle, - int numBias, - int biasIndex); - - /*! \brief Initializes the output file setup for the AWH output. - * - * \param[in] subBlockStart Index of the first sub-block to write in the energy frame. - * \param[in] numSubBlocks The total number of sub-blocks in the framw. - * \param[in] awhBiasParams The AWH bias parameters. - * \param[in] graphSelection Selects which graphs to plot. - * \param[in] energyUnit Requested energy unit in output. - * \param[in] kTValue kB*T in kJ/mol. - */ - void initializeAwhOutputFile(int subBlockStart, - int numSubBlocks, - const AwhBiasParams *awhBiasParams, - AwhGraphSelection graphSelection, - EnergyUnit energyUnit, - real kTValue); - - /*! \brief Initializes the output file setup for the fricion output. - * - * \param[in] subBlockStart Index of the first sub-block to write in the energy frame. - * \param[in] numSubBlocks The total number of sub-blocks in the framw. - * \param[in] awhBiasParams The AWH bias parameters. - * \param[in] energyUnit Requested energy unit in output. - * \param[in] kTValue kB*T in kJ/mol. - */ - void initializeFrictionOutputFile(int subBlockStart, - int numSubBlocks, - const AwhBiasParams *awhBiasParams, - EnergyUnit energyUnit, - real kTValue); - - /*! \brief Opens a single output file for a bias, prints title and legends. - * - * \param[in] time The time for of frame to be written. - * \param[in] oenv The output environment. - * \returns the file pointer. - */ - FILE * openBiasOutputFile(double time, - const gmx_output_env_t *oenv) const; - - /*! \brief Writes data selected from \p block to file. - * - * \param[in] block The energy block with the data to write. - * \param[in] subBlockStart The sub-block start index. - * \param[in] fp The file pointer. - */ - void writeData(const t_enxblock &block, - int subBlockStart, - FILE *fp) const; - - private: - std::string baseFilename_; /**< Base of the output file name. */ - std::string title_; /**< Title for the graph. */ - int numDim_; /**< Number of dimensions. */ - int firstGraphSubBlock_; /**< Index in the energy sub-blocks for the first graph. */ - int numGraph_; /**< Number of actual graphs. */ - bool useKTForEnergy_; /**< Whether to use kT instead of kJ/mol for energy. */ - std::vector scaleFactor_; /**< Scale factors from energy file data to output for each of the numGraph quantities. */ - - std::vector legend_; /**< Legends for the output */ - std::string xLabel_; /**< Label for the x-axis. */ - std::string yLabel_; /**< Label for the y-axis. */ +public: + /*! \brief Constructor, Set the output base file name and title. + * + * Result is a valid object, but will produce empty output files. + * + * \param[in] filename The name for output files, frame time, and possibly bias number, will be added per file/frame. + * \param[in] baseTitle The base title of the plot, the bias number might be added. + * \param[in] numBias The total number of AWH biases in the system. + * \param[in] biasIndex The index of this bias. + */ + OutputFile(const std::string& filename, const std::string& baseTitle, int numBias, int biasIndex); + + /*! \brief Initializes the output file setup for the AWH output. + * + * \param[in] subBlockStart Index of the first sub-block to write in the energy frame. + * \param[in] numSubBlocks The total number of sub-blocks in the framw. + * \param[in] awhBiasParams The AWH bias parameters. + * \param[in] graphSelection Selects which graphs to plot. + * \param[in] energyUnit Requested energy unit in output. + * \param[in] kTValue kB*T in kJ/mol. + */ + void initializeAwhOutputFile(int subBlockStart, + int numSubBlocks, + const AwhBiasParams* awhBiasParams, + AwhGraphSelection graphSelection, + EnergyUnit energyUnit, + real kTValue); + + /*! \brief Initializes the output file setup for the fricion output. + * + * \param[in] subBlockStart Index of the first sub-block to write in the energy frame. + * \param[in] numSubBlocks The total number of sub-blocks in the framw. + * \param[in] awhBiasParams The AWH bias parameters. + * \param[in] energyUnit Requested energy unit in output. + * \param[in] kTValue kB*T in kJ/mol. + */ + void initializeFrictionOutputFile(int subBlockStart, + int numSubBlocks, + const AwhBiasParams* awhBiasParams, + EnergyUnit energyUnit, + real kTValue); + + /*! \brief Opens a single output file for a bias, prints title and legends. + * + * \param[in] time The time for of frame to be written. + * \param[in] oenv The output environment. + * \returns the file pointer. + */ + FILE* openBiasOutputFile(double time, const gmx_output_env_t* oenv) const; + + /*! \brief Writes data selected from \p block to file. + * + * \param[in] block The energy block with the data to write. + * \param[in] subBlockStart The sub-block start index. + * \param[in] fp The file pointer. + */ + void writeData(const t_enxblock& block, int subBlockStart, FILE* fp) const; + +private: + std::string baseFilename_; /**< Base of the output file name. */ + std::string title_; /**< Title for the graph. */ + int numDim_; /**< Number of dimensions. */ + int firstGraphSubBlock_; /**< Index in the energy sub-blocks for the first graph. */ + int numGraph_; /**< Number of actual graphs. */ + bool useKTForEnergy_; /**< Whether to use kT instead of kJ/mol for energy. */ + std::vector scaleFactor_; /**< Scale factors from energy file data to output for each of the numGraph quantities. */ + + std::vector legend_; /**< Legends for the output */ + std::string xLabel_; /**< Label for the x-axis. */ + std::string yLabel_; /**< Label for the y-axis. */ }; /*! \brief All meta-data that is shared for all output files for one bias */ @@ -190,53 +184,46 @@ struct BiasOutputSetup } //! Return the AWH output file data. - const OutputFile &awhOutputFile() const + const OutputFile& awhOutputFile() const { - GMX_RELEASE_ASSERT(awhOutputFile_ != nullptr, "awhOutputFile() called without initialized AWH output file"); + GMX_RELEASE_ASSERT(awhOutputFile_ != nullptr, + "awhOutputFile() called without initialized AWH output file"); return *awhOutputFile_; } //! Return the a pointer to the friction output file data, can return nullptr - const OutputFile *frictionOutputFile() const - { - return frictionOutputFile_.get(); - } + const OutputFile* frictionOutputFile() const { return frictionOutputFile_.get(); } //! Return the starting subblock. - int subblockStart() const - { - return subblockStart_; - } + int subblockStart() const { return subblockStart_; } - private: - const int subblockStart_; /**< The start index of the subblocks to read. */ - std::unique_ptr awhOutputFile_; /**< The standard AWH output file data. */ - std::unique_ptr frictionOutputFile_; /**< The friction/metric tensor output file data */ +private: + const int subblockStart_; /**< The start index of the subblocks to read. */ + std::unique_ptr awhOutputFile_; /**< The standard AWH output file data. */ + std::unique_ptr frictionOutputFile_; /**< The friction/metric tensor output file data */ }; /*! \brief All options and meta-data needed for the AWH output */ class AwhReader { - public: - //! Constructor - AwhReader(const AwhParams *awhParams, - int numFileOptions, - const t_filenm *filenames, - AwhGraphSelection awhGraphSelection, - EnergyUnit energyUnit, - real kT, - const t_enxblock *block); - - //! Extract and print AWH data for an AWH block of one energy frame - void processAwhFrame(const t_enxblock &block, - double time, - const gmx_output_env_t *oenv) const; - - private: - std::vector biasOutputSetups_; /**< The output setups, one for each AWH bias. */ - public: - const real kT_; /**< kB*T in kJ/mol. */ +public: + //! Constructor + AwhReader(const AwhParams* awhParams, + int numFileOptions, + const t_filenm* filenames, + AwhGraphSelection awhGraphSelection, + EnergyUnit energyUnit, + real kT, + const t_enxblock* block); + + //! Extract and print AWH data for an AWH block of one energy frame + void processAwhFrame(const t_enxblock& block, double time, const gmx_output_env_t* oenv) const; + +private: + std::vector biasOutputSetups_; /**< The output setups, one for each AWH bias. */ +public: + const real kT_; /**< kB*T in kJ/mol. */ }; namespace @@ -245,8 +232,8 @@ namespace //! Enum for selecting output file type. enum class OutputFileType { - Awh, //!< AWH, all data except friction tensor. - Friction //!< The full friction tensor. + Awh, //!< AWH, all data except friction tensor. + Friction //!< The full friction tensor. }; /*! \brief The maximum number of observables per subblock, not including the full friction tensor. @@ -258,21 +245,16 @@ enum class OutputFileType constexpr int maxAwhGraphs = 6; /*! \brief Constructs a legend for a standard awh output file */ -std::vectormakeLegend(const AwhBiasParams *awhBiasParams, - OutputFileType outputFileType, - size_t numLegend) +std::vector makeLegend(const AwhBiasParams* awhBiasParams, + OutputFileType outputFileType, + size_t numLegend) { - const std::array legendBase = - { - { "PMF", - "Coord bias", - "Coord distr", - "Ref value distr", - "Target ref value distr", + const std::array legendBase = { + { "PMF", "Coord bias", "Coord distr", "Ref value distr", "Target ref value distr", "Friction metric" } }; - std::vector legend; + std::vector legend; /* Give legends to dimensions higher than the first */ for (int d = 1; d < awhBiasParams->ndim; d++) { @@ -303,17 +285,16 @@ std::vectormakeLegend(const AwhBiasParams *awhBiasParams, break; } - GMX_RELEASE_ASSERT(legend.size() == numLegend, "The number of legends requested for printing and the number generated should be the same"); + GMX_RELEASE_ASSERT(legend.size() == numLegend, + "The number of legends requested for printing and the number generated " + "should be the same"); return legend; } } // namespace -OutputFile::OutputFile(const std::string &filename, - const std::string &baseTitle, - int numBias, - int biasIndex) : +OutputFile::OutputFile(const std::string& filename, const std::string& baseTitle, int numBias, int biasIndex) : numDim_(0), firstGraphSubBlock_(0), numGraph_(0), @@ -325,13 +306,13 @@ OutputFile::OutputFile(const std::string &filename, if (numBias > 1) { baseFilename_ += gmx::formatString("%d", biasIndex + 1); - title_ += gmx::formatString(" %d", biasIndex + 1); + title_ += gmx::formatString(" %d", biasIndex + 1); } } void OutputFile::initializeAwhOutputFile(int subblockStart, int numSubBlocks, - const AwhBiasParams *awhBiasParams, + const AwhBiasParams* awhBiasParams, AwhGraphSelection graphSelection, EnergyUnit energyUnit, real kTValue) @@ -342,14 +323,13 @@ void OutputFile::initializeAwhOutputFile(int subblockStart, if (graphSelection == AwhGraphSelection::All) { /* There are one metadata and ndim coordinate blocks */ - numGraph_ = std::min(numSubBlocks - 1 - numDim_, - maxAwhGraphs); + numGraph_ = std::min(numSubBlocks - 1 - numDim_, maxAwhGraphs); } else { - numGraph_ = 1; + numGraph_ = 1; } - useKTForEnergy_ = (energyUnit == EnergyUnit::KT); + useKTForEnergy_ = (energyUnit == EnergyUnit::KT); scaleFactor_.resize(numGraph_, 1); if (!useKTForEnergy_) { @@ -359,57 +339,61 @@ void OutputFile::initializeAwhOutputFile(int subblockStart, int numLegend = numDim_ - 1 + numGraph_; legend_ = makeLegend(awhBiasParams, OutputFileType::Awh, numLegend); /* We could have both length and angle coordinates in a single bias */ - xLabel_ = "(nm or deg)"; - yLabel_ = useKTForEnergy_ ? "(k\\sB\\NT)" : "(kJ/mol)"; + xLabel_ = "(nm or deg)"; + yLabel_ = useKTForEnergy_ ? "(k\\sB\\NT)" : "(kJ/mol)"; if (graphSelection == AwhGraphSelection::All) { - yLabel_ += gmx::formatString(", (nm\\S-%d\\N or rad\\S-%d\\N), (-)", - awhBiasParams->ndim, awhBiasParams->ndim); + yLabel_ += gmx::formatString(", (nm\\S-%d\\N or rad\\S-%d\\N), (-)", awhBiasParams->ndim, + awhBiasParams->ndim); } } /*! \brief Initializes the output file setup for the fricion output (note that the filename is not set here). */ void OutputFile::initializeFrictionOutputFile(int subBlockStart, int numSubBlocks, - const AwhBiasParams *awhBiasParams, + const AwhBiasParams* awhBiasParams, EnergyUnit energyUnit, real kTValue) { /* The first subblock with actual graph y-values is index 1 + ndim */ numDim_ = awhBiasParams->ndim; - int numTensorElements = (numDim_*(numDim_ + 1))/2; + int numTensorElements = (numDim_ * (numDim_ + 1)) / 2; /* The friction tensor elements are always the last subblocks */ if (numSubBlocks < 1 + numDim_ + maxAwhGraphs + numTensorElements) { - gmx_fatal(FARGS, "You requested friction tensor output, but the AWH data in the energy file does not contain the friction tensor"); + gmx_fatal(FARGS, + "You requested friction tensor output, but the AWH data in the energy file does " + "not contain the friction tensor"); } - GMX_ASSERT(numSubBlocks == 1 + numDim_ + maxAwhGraphs + numTensorElements, "The number of sub-blocks per bias should be 1 + ndim + maxAwhGraphs + (ndim*(ndim + 1))/2"); + GMX_ASSERT(numSubBlocks == 1 + numDim_ + maxAwhGraphs + numTensorElements, + "The number of sub-blocks per bias should be 1 + ndim + maxAwhGraphs + (ndim*(ndim " + "+ 1))/2"); firstGraphSubBlock_ = subBlockStart + numSubBlocks - numTensorElements; numGraph_ = numTensorElements; useKTForEnergy_ = (energyUnit == EnergyUnit::KT); scaleFactor_.resize(numGraph_, useKTForEnergy_ ? 1 : kTValue); - int numLegend = numDim_ - 1 + numGraph_; - legend_ = makeLegend(awhBiasParams, OutputFileType::Friction, numLegend); - xLabel_ = "(nm or deg)"; + int numLegend = numDim_ - 1 + numGraph_; + legend_ = makeLegend(awhBiasParams, OutputFileType::Friction, numLegend); + xLabel_ = "(nm or deg)"; if (useKTForEnergy_) { - yLabel_ = "friction/k\\sB\\NT (nm\\S-2\\Nps or rad\\S-2\\Nps)"; + yLabel_ = "friction/k\\sB\\NT (nm\\S-2\\Nps or rad\\S-2\\Nps)"; } else { - yLabel_ = "friction (kJ mol\\S-1\\Nnm\\S-2\\Nps or kJ mol\\S-1\\Nrad\\S-2\\Nps)"; + yLabel_ = "friction (kJ mol\\S-1\\Nnm\\S-2\\Nps or kJ mol\\S-1\\Nrad\\S-2\\Nps)"; } } -AwhReader::AwhReader(const AwhParams *awhParams, +AwhReader::AwhReader(const AwhParams* awhParams, int numFileOptions, - const t_filenm *filenames, + const t_filenm* filenames, AwhGraphSelection awhGraphSelection, EnergyUnit energyUnit, real kT, - const t_enxblock *block) : + const t_enxblock* block) : kT_(kT) { GMX_RELEASE_ASSERT(block != nullptr, "NULL pointer passed to initAwhReader"); @@ -426,47 +410,45 @@ AwhReader::AwhReader(const AwhParams *awhParams, int subblockStart = 0; for (int k = 0; k < awhParams->numBias; k++) { - AwhBiasParams *awhBiasParams = &awhParams->awhBiasParams[k]; + AwhBiasParams* awhBiasParams = &awhParams->awhBiasParams[k]; - int numSubBlocks = static_cast(block->sub[subblockStart].fval[0]); + int numSubBlocks = static_cast(block->sub[subblockStart].fval[0]); - std::unique_ptr awhOutputFile(new OutputFile(opt2fn("-o", numFileOptions, filenames), "AWH", awhParams->numBias, k)); + std::unique_ptr awhOutputFile(new OutputFile( + opt2fn("-o", numFileOptions, filenames), "AWH", awhParams->numBias, k)); - awhOutputFile->initializeAwhOutputFile(subblockStart, numSubBlocks, - awhBiasParams, awhGraphSelection, - energyUnit, kT); + awhOutputFile->initializeAwhOutputFile(subblockStart, numSubBlocks, awhBiasParams, + awhGraphSelection, energyUnit, kT); std::unique_ptr frictionOutputFile; if (outputFriction) { - frictionOutputFile = std::make_unique(opt2fn("-fric", numFileOptions, filenames), "Friction tensor", awhParams->numBias, k); + frictionOutputFile = std::make_unique( + opt2fn("-fric", numFileOptions, filenames), "Friction tensor", awhParams->numBias, k); - frictionOutputFile->initializeFrictionOutputFile(subblockStart, numSubBlocks, awhBiasParams, energyUnit, kT); + frictionOutputFile->initializeFrictionOutputFile(subblockStart, numSubBlocks, + awhBiasParams, energyUnit, kT); } - biasOutputSetups_.emplace_back(BiasOutputSetup(subblockStart, - std::move(awhOutputFile), + biasOutputSetups_.emplace_back(BiasOutputSetup(subblockStart, std::move(awhOutputFile), std::move(frictionOutputFile))); subblockStart += numSubBlocks; } } -FILE * OutputFile::openBiasOutputFile(double time, - const gmx_output_env_t *oenv) const +FILE* OutputFile::openBiasOutputFile(double time, const gmx_output_env_t* oenv) const { std::string filename = baseFilename_ + gmx::formatString("_t%g.xvg", time); - FILE *fp = xvgropen(filename.c_str(), title_.c_str(), xLabel_, yLabel_, oenv); + FILE* fp = xvgropen(filename.c_str(), title_.c_str(), xLabel_, yLabel_, oenv); xvgrLegend(fp, legend_, oenv); return fp; } /*! \brief Prints data selected by \p outputFile from \p block to \p fp */ -void OutputFile::writeData(const t_enxblock &block, - int subBlockStart, - FILE *fp) const +void OutputFile::writeData(const t_enxblock& block, int subBlockStart, FILE* fp) const { int numPoints = block.sub[subBlockStart + 1].nr; for (int j = 0; j < numPoints; j++) @@ -480,46 +462,42 @@ void OutputFile::writeData(const t_enxblock &block, /* Print numGraph observables */ for (int i = 0; i < numGraph_; i++) { - fprintf(fp, " %g", block.sub[firstGraphSubBlock_ + i].fval[j]*scaleFactor_[i]); + fprintf(fp, " %g", block.sub[firstGraphSubBlock_ + i].fval[j] * scaleFactor_[i]); } fprintf(fp, "\n"); } } -void AwhReader::processAwhFrame(const t_enxblock &block, - double time, - const gmx_output_env_t *oenv) const +void AwhReader::processAwhFrame(const t_enxblock& block, double time, const gmx_output_env_t* oenv) const { /* We look for AWH data every energy frame and count the no of AWH frames found. We only extract every 'skip' AWH frame. */ - for (const auto &setup : biasOutputSetups_) + for (const auto& setup : biasOutputSetups_) { const int subStart = setup.subblockStart(); /* Each frame and AWH instance extracted generates one xvg file. */ { - const OutputFile &awhOutputFile = setup.awhOutputFile(); + const OutputFile& awhOutputFile = setup.awhOutputFile(); - FILE *fpAwh = awhOutputFile.openBiasOutputFile(time, oenv); + FILE* fpAwh = awhOutputFile.openBiasOutputFile(time, oenv); /* Now do the actual printing. Metadata in first subblock is treated separately. */ fprintf(fpAwh, "# AWH metadata: target error = %.2f kT = %.2f kJ/mol\n", - block.sub[subStart].fval[1], - block.sub[subStart].fval[1]*kT_); + block.sub[subStart].fval[1], block.sub[subStart].fval[1] * kT_); - fprintf(fpAwh, "# AWH metadata: log sample weight = %4.2f\n", - block.sub[subStart].fval[2]); + fprintf(fpAwh, "# AWH metadata: log sample weight = %4.2f\n", block.sub[subStart].fval[2]); awhOutputFile.writeData(block, subStart, fpAwh); gmx_ffclose(fpAwh); } - const OutputFile *frictionOutputFile = setup.frictionOutputFile(); + const OutputFile* frictionOutputFile = setup.frictionOutputFile(); if (frictionOutputFile != nullptr) { - FILE *fpFriction = frictionOutputFile->openBiasOutputFile(time, oenv); + FILE* fpFriction = frictionOutputFile->openBiasOutputFile(time, oenv); frictionOutputFile->writeData(block, subStart, fpFriction); @@ -529,50 +507,46 @@ void AwhReader::processAwhFrame(const t_enxblock &block, } /*! \brief The main function for the AWH tool */ -int gmx_awh(int argc, char *argv[]) +int gmx_awh(int argc, char* argv[]) { - const char *desc[] = { - "[THISMODULE] extracts AWH data from an energy file.", - "One or two files are written per AWH bias per time frame.", - "The bias index, if more than one, is appended to the file, as well as", - "the time of the frame. By default only the PMF is printed.", - "With [TT]-more[tt] the bias, target and coordinate distributions", - "are also printed.", - "With [TT]-more[tt] the bias, target and coordinate distributions", - "are also printed, as well as the metric sqrt(det(friction_tensor))", - "normalized such that the average is 1.", - "Option [TT]-fric[tt] prints all components of the friction tensor", - "to an additional set of files." - }; - static gmx_bool moreGraphs = FALSE; - static int skip = 0; - static gmx_bool kTUnit = FALSE; - t_pargs pa[] = { - { "-skip", FALSE, etINT, {&skip}, - "Skip number of frames between data points" }, - { "-more", FALSE, etBOOL, {&moreGraphs}, - "Print more output" }, - { "-kt", FALSE, etBOOL, {&kTUnit}, + const char* desc[] = { "[THISMODULE] extracts AWH data from an energy file.", + "One or two files are written per AWH bias per time frame.", + "The bias index, if more than one, is appended to the file, as well as", + "the time of the frame. By default only the PMF is printed.", + "With [TT]-more[tt] the bias, target and coordinate distributions", + "are also printed.", + "With [TT]-more[tt] the bias, target and coordinate distributions", + "are also printed, as well as the metric sqrt(det(friction_tensor))", + "normalized such that the average is 1.", + "Option [TT]-fric[tt] prints all components of the friction tensor", + "to an additional set of files." }; + static gmx_bool moreGraphs = FALSE; + static int skip = 0; + static gmx_bool kTUnit = FALSE; + t_pargs pa[] = { + { "-skip", FALSE, etINT, { &skip }, "Skip number of frames between data points" }, + { "-more", FALSE, etBOOL, { &moreGraphs }, "Print more output" }, + { "-kt", + FALSE, + etBOOL, + { &kTUnit }, "Print free energy output in units of kT instead of kJ/mol" } }; - ener_file_t fp; - t_inputrec ir; - gmx_enxnm_t *enm = nullptr; - t_enxframe *frame; - int nre; - gmx_output_env_t *oenv; - - t_filenm fnm[] = { - { efEDR, "-f", nullptr, ffREAD }, - { efTPR, "-s", nullptr, ffREAD }, - { efXVG, "-o", "awh", ffWRITE }, - { efXVG, "-fric", "friction", ffOPTWR } - }; - const int nfile = asize(fnm); - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, - nfile, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + ener_file_t fp; + t_inputrec ir; + gmx_enxnm_t* enm = nullptr; + t_enxframe* frame; + int nre; + gmx_output_env_t* oenv; + + t_filenm fnm[] = { { efEDR, "-f", nullptr, ffREAD }, + { efTPR, "-s", nullptr, ffREAD }, + { efXVG, "-o", "awh", ffWRITE }, + { efXVG, "-fric", "friction", ffOPTWR } }; + const int nfile = asize(fnm); + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, nfile, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -596,16 +570,16 @@ int gmx_awh(int argc, char *argv[]) std::unique_ptr awhReader; /* Initiate counters */ - gmx_bool haveFrame; - int awhFrameCounter = 0; - int timeCheck = 0; + gmx_bool haveFrame; + int awhFrameCounter = 0; + int timeCheck = 0; do { haveFrame = do_enx(fp, frame); - bool useFrame = false; + bool useFrame = false; - t_enxblock *block = nullptr; + t_enxblock* block = nullptr; if (haveFrame) { @@ -636,20 +610,16 @@ int gmx_awh(int argc, char *argv[]) */ if (awhReader == nullptr) { - AwhGraphSelection awhGraphSelection = (moreGraphs ? AwhGraphSelection::All : AwhGraphSelection::Pmf); - EnergyUnit energyUnit = (kTUnit ? EnergyUnit::KT : EnergyUnit::KJPerMol); - awhReader = - std::make_unique(ir.awhParams, - nfile, fnm, - awhGraphSelection, - energyUnit, BOLTZ*ir.opts.ref_t[0], - block); + AwhGraphSelection awhGraphSelection = + (moreGraphs ? AwhGraphSelection::All : AwhGraphSelection::Pmf); + EnergyUnit energyUnit = (kTUnit ? EnergyUnit::KT : EnergyUnit::KJPerMol); + awhReader = std::make_unique(ir.awhParams, nfile, fnm, awhGraphSelection, + energyUnit, BOLTZ * ir.opts.ref_t[0], block); } awhReader->processAwhFrame(*block, frame->t, oenv); } - } - while (haveFrame && (timeCheck <= 0)); + } while (haveFrame && (timeCheck <= 0)); fprintf(stderr, "\n"); diff --git a/src/gromacs/gmxana/gmx_bar.cpp b/src/gromacs/gmxana/gmx_bar.cpp index 16d70d70c5..062a3594e8 100644 --- a/src/gromacs/gmxana/gmx_bar.cpp +++ b/src/gromacs/gmxana/gmx_bar.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,96 +65,96 @@ /* Structure for the names of lambda vector components */ typedef struct lambda_components_t { - char **names; /* Array of strings with names for the lambda vector - components */ - int N; /* The number of components */ - int Nalloc; /* The number of allocated components */ + char** names; /* Array of strings with names for the lambda vector + components */ + int N; /* The number of components */ + int Nalloc; /* The number of allocated components */ } lambda_components_t; /* Structure for a lambda vector or a dhdl derivative direction */ typedef struct lambda_vec_t { - double *val; /* The lambda vector component values. Only valid if - dhdl == -1 */ - int dhdl; /* The coordinate index for the derivative described by this - structure, or -1 */ - const lambda_components_t *lc; /* the associated lambda_components - structure */ - int index; /* The state number (init-lambda-state) of this lambda - vector, if known. If not, it is set to -1 */ + double* val; /* The lambda vector component values. Only valid if + dhdl == -1 */ + int dhdl; /* The coordinate index for the derivative described by this + structure, or -1 */ + const lambda_components_t* lc; /* the associated lambda_components + structure */ + int index; /* The state number (init-lambda-state) of this lambda + vector, if known. If not, it is set to -1 */ } lambda_vec_t; /* the dhdl.xvg data from a simulation */ typedef struct xvg_t { - const char *filename; - int ftp; /* file type */ - int nset; /* number of lambdas, including dhdl */ - int *np; /* number of data points (du or hists) per lambda */ - int np_alloc; /* number of points (du or hists) allocated */ - double temp; /* temperature */ - lambda_vec_t *lambda; /* the lambdas (of first index for y). */ - double *t; /* the times (of second index for y) */ - double **y; /* the dU values. y[0] holds the derivative, while - further ones contain the energy differences between - the native lambda and the 'foreign' lambdas. */ - lambda_vec_t native_lambda; /* the native lambda */ - - struct xvg_t *next, *prev; /*location in the global linked list of xvg_ts*/ + const char* filename; + int ftp; /* file type */ + int nset; /* number of lambdas, including dhdl */ + int* np; /* number of data points (du or hists) per lambda */ + int np_alloc; /* number of points (du or hists) allocated */ + double temp; /* temperature */ + lambda_vec_t* lambda; /* the lambdas (of first index for y). */ + double* t; /* the times (of second index for y) */ + double** y; /* the dU values. y[0] holds the derivative, while + further ones contain the energy differences between + the native lambda and the 'foreign' lambdas. */ + lambda_vec_t native_lambda; /* the native lambda */ + + struct xvg_t *next, *prev; /*location in the global linked list of xvg_ts*/ } xvg_t; typedef struct hist_t { - unsigned int *bin[2]; /* the (forward + reverse) histogram values */ - double dx[2]; /* the histogram spacing. The reverse - dx is the negative of the forward dx.*/ - int64_t x0[2]; /* the (forward + reverse) histogram start - point(s) as int */ + unsigned int* bin[2]; /* the (forward + reverse) histogram values */ + double dx[2]; /* the histogram spacing. The reverse + dx is the negative of the forward dx.*/ + int64_t x0[2]; /* the (forward + reverse) histogram start + point(s) as int */ - int nbin[2]; /* the (forward+reverse) number of bins */ - int64_t sum; /* the total number of counts. Must be - the same for forward + reverse. */ - int nhist; /* number of hist datas (forward or reverse) */ + int nbin[2]; /* the (forward+reverse) number of bins */ + int64_t sum; /* the total number of counts. Must be + the same for forward + reverse. */ + int nhist; /* number of hist datas (forward or reverse) */ - double start_time, delta_time; /* start time, end time of histogram */ + double start_time, delta_time; /* start time, end time of histogram */ } hist_t; /* an aggregate of samples for partial free energy calculation */ typedef struct samples_t { - lambda_vec_t *native_lambda; /* pointer to native lambda vector */ - lambda_vec_t *foreign_lambda; /* pointer to foreign lambda vector */ + lambda_vec_t* native_lambda; /* pointer to native lambda vector */ + lambda_vec_t* foreign_lambda; /* pointer to foreign lambda vector */ double temp; /* the temperature */ gmx_bool derivative; /* whether this sample is a derivative */ /* The samples come either as either delta U lists: */ int ndu; /* the number of delta U samples */ - double *du; /* the delta u's */ - double *t; /* the times associated with those samples, or: */ + double* du; /* the delta u's */ + double* t; /* the times associated with those samples, or: */ double start_time, delta_time; /*start time and delta time for linear time*/ /* or as histograms: */ - hist_t *hist; /* a histogram */ + hist_t* hist; /* a histogram */ /* allocation data: (not NULL for data 'owned' by this struct) */ - double *du_alloc, *t_alloc; /* allocated delta u arrays */ - size_t ndu_alloc, nt_alloc; /* pre-allocated sizes */ - hist_t *hist_alloc; /* allocated hist */ + double *du_alloc, *t_alloc; /* allocated delta u arrays */ + size_t ndu_alloc, nt_alloc; /* pre-allocated sizes */ + hist_t* hist_alloc; /* allocated hist */ - int64_t ntot; /* total number of samples */ - const char *filename; /* the file name this sample comes from */ + int64_t ntot; /* total number of samples */ + const char* filename; /* the file name this sample comes from */ } samples_t; /* a sample range (start to end for du-style data, or boolean for both du-style data and histograms */ typedef struct sample_range_t { - int start, end; /* start and end index for du style data */ - gmx_bool use; /* whether to use this sample */ + int start, end; /* start and end index for du style data */ + gmx_bool use; /* whether to use this sample */ - samples_t *s; /* the samples this range belongs to */ + samples_t* s; /* the samples this range belongs to */ } sample_range_t; @@ -162,18 +163,18 @@ typedef struct sample_range_t foreign lambda) */ typedef struct sample_coll_t { - lambda_vec_t *native_lambda; /* these should be the same for all samples - in the histogram */ - lambda_vec_t *foreign_lambda; /* collection */ - double temp; /* the temperature */ + lambda_vec_t* native_lambda; /* these should be the same for all samples + in the histogram */ + lambda_vec_t* foreign_lambda; /* collection */ + double temp; /* the temperature */ - int nsamples; /* the number of samples */ - samples_t **s; /* the samples themselves */ - sample_range_t *r; /* the sample ranges */ - int nsamples_alloc; /* number of allocated samples */ + int nsamples; /* the number of samples */ + samples_t** s; /* the samples themselves */ + sample_range_t* r; /* the sample ranges */ + int nsamples_alloc; /* number of allocated samples */ - int64_t ntot; /* total number of samples in the ranges of - this collection */ + int64_t ntot; /* total number of samples in the ranges of + this collection */ struct sample_coll_t *next, *prev; /* next and previous in the list */ } sample_coll_t; @@ -181,12 +182,12 @@ typedef struct sample_coll_t /* all the samples associated with a lambda point */ typedef struct lambda_data_t { - lambda_vec_t *lambda; /* the native lambda (at start time if dynamic) */ - double temp; /* temperature */ + lambda_vec_t* lambda; /* the native lambda (at start time if dynamic) */ + double temp; /* temperature */ - sample_coll_t *sc; /* the samples */ + sample_coll_t* sc; /* the samples */ - sample_coll_t sc_head; /*the pre-allocated list head for the linked list.*/ + sample_coll_t sc_head; /*the pre-allocated list head for the linked list.*/ struct lambda_data_t *next, *prev; /* the next and prev in the list */ } lambda_data_t; @@ -194,35 +195,36 @@ typedef struct lambda_data_t /* Top-level data structure of simulation data */ typedef struct sim_data_t { - lambda_data_t *lb; /* a lambda data linked list */ - lambda_data_t lb_head; /* The head element of the linked list */ + lambda_data_t* lb; /* a lambda data linked list */ + lambda_data_t lb_head; /* The head element of the linked list */ - lambda_components_t lc; /* the allowed components of the lambda - vectors */ + lambda_components_t lc; /* the allowed components of the lambda + vectors */ } sim_data_t; /* Top-level data structure with calculated values. */ -typedef struct { - sample_coll_t *a, *b; /* the simulation data */ +typedef struct +{ + sample_coll_t *a, *b; /* the simulation data */ - double dg; /* the free energy difference */ - double dg_err; /* the free energy difference */ + double dg; /* the free energy difference */ + double dg_err; /* the free energy difference */ - double dg_disc_err; /* discretization error */ - double dg_histrange_err; /* histogram range error */ + double dg_disc_err; /* discretization error */ + double dg_histrange_err; /* histogram range error */ - double sa; /* relative entropy of b in state a */ - double sa_err; /* error in sa */ - double sb; /* relative entropy of a in state b */ - double sb_err; /* error in sb */ + double sa; /* relative entropy of b in state a */ + double sa_err; /* error in sa */ + double sb; /* relative entropy of a in state b */ + double sb_err; /* error in sb */ - double dg_stddev; /* expected dg stddev per sample */ - double dg_stddev_err; /* error in dg_stddev */ + double dg_stddev; /* expected dg stddev per sample */ + double dg_stddev_err; /* error in dg_stddev */ } barres_t; /* Initialize a lambda_components structure */ -static void lambda_components_init(lambda_components_t *lc) +static void lambda_components_init(lambda_components_t* lc) { lc->N = 0; lc->Nalloc = 2; @@ -230,15 +232,14 @@ static void lambda_components_init(lambda_components_t *lc) } /* Add a component to a lambda_components structure */ -static void lambda_components_add(lambda_components_t *lc, - const char *name, size_t name_length) +static void lambda_components_add(lambda_components_t* lc, const char* name, size_t name_length) { while (lc->N + 1 > lc->Nalloc) { - lc->Nalloc = (lc->Nalloc == 0) ? 2 : 2*lc->Nalloc; + lc->Nalloc = (lc->Nalloc == 0) ? 2 : 2 * lc->Nalloc; srenew(lc->names, lc->Nalloc); } - snew(lc->names[lc->N], name_length+1); + snew(lc->names[lc->N], name_length + 1); std::strncpy(lc->names[lc->N], name, name_length); lc->N++; } @@ -246,10 +247,7 @@ static void lambda_components_add(lambda_components_t *lc, /* check whether a component with index 'index' matches the given name, or is also NULL. Returns TRUE if this is the case. the string name does not need to end */ -static gmx_bool lambda_components_check(const lambda_components_t *lc, - int index, - const char *name, - size_t name_length) +static gmx_bool lambda_components_check(const lambda_components_t* lc, int index, const char* name, size_t name_length) { size_t len; if (!lc || index >= lc->N) @@ -260,13 +258,14 @@ static gmx_bool lambda_components_check(const lambda_components_t *lc, { return TRUE; } - if (((name != nullptr) && (lc->names[index] == nullptr)) || - ((name == nullptr) && (lc->names[index] != nullptr))) + if (((name != nullptr) && (lc->names[index] == nullptr)) + || ((name == nullptr) && (lc->names[index] != nullptr))) { return FALSE; } - GMX_RELEASE_ASSERT((name != nullptr) || (name_length == 0), - "If name is empty, the length of the substring to examine within it must be zero"); + GMX_RELEASE_ASSERT( + (name != nullptr) || (name_length == 0), + "If name is empty, the length of the substring to examine within it must be zero"); len = std::strlen(lc->names[index]); if (len != name_length) { @@ -282,9 +281,7 @@ static gmx_bool lambda_components_check(const lambda_components_t *lc, } /* Find the index of a given lambda component name, or -1 if not found */ -static int lambda_components_find(const lambda_components_t *lc, - const char *name, - size_t name_length) +static int lambda_components_find(const lambda_components_t* lc, const char* name, size_t name_length) { int i; @@ -299,9 +296,8 @@ static int lambda_components_find(const lambda_components_t *lc, } - /* initialize a lambda vector */ -static void lambda_vec_init(lambda_vec_t *lv, const lambda_components_t *lc) +static void lambda_vec_init(lambda_vec_t* lv, const lambda_components_t* lc) { snew(lv->val, lc->N); lv->index = -1; @@ -309,7 +305,7 @@ static void lambda_vec_init(lambda_vec_t *lv, const lambda_components_t *lc) lv->lc = lc; } -static void lambda_vec_copy(lambda_vec_t *lv, const lambda_vec_t *orig) +static void lambda_vec_copy(lambda_vec_t* lv, const lambda_vec_t* orig) { int i; @@ -323,9 +319,9 @@ static void lambda_vec_copy(lambda_vec_t *lv, const lambda_vec_t *orig) } /* write a lambda vec to a preallocated string */ -static void lambda_vec_print(const lambda_vec_t *lv, char *str, gmx_bool named) +static void lambda_vec_print(const lambda_vec_t* lv, char* str, gmx_bool named) { - int i; + int i; str[0] = 0; /* reset the string */ if (lv->dhdl < 0) @@ -341,7 +337,7 @@ static void lambda_vec_print(const lambda_vec_t *lv, char *str, gmx_bool named) for (i = 0; i < lv->lc->N; i++) { str += sprintf(str, "%g", lv->val[i]); - if (i < lv->lc->N-1) + if (i < lv->lc->N - 1) { str += sprintf(str, ", "); } @@ -363,7 +359,7 @@ static void lambda_vec_print(const lambda_vec_t *lv, char *str, gmx_bool named) } /* write a shortened version of the lambda vec to a preallocated string */ -static void lambda_vec_print_short(const lambda_vec_t *lv, char *str) +static void lambda_vec_print_short(const lambda_vec_t* lv, char* str) { if (lv->index >= 0) { @@ -383,19 +379,18 @@ static void lambda_vec_print_short(const lambda_vec_t *lv, char *str) } /* write an intermediate version of two lambda vecs to a preallocated string */ -static void lambda_vec_print_intermediate(const lambda_vec_t *a, - const lambda_vec_t *b, char *str) +static void lambda_vec_print_intermediate(const lambda_vec_t* a, const lambda_vec_t* b, char* str) { str[0] = 0; - if ( (a->index >= 0) && (b->index >= 0) ) + if ((a->index >= 0) && (b->index >= 0)) { - sprintf(str, "%6.3f", (a->index+b->index)/2.0); + sprintf(str, "%6.3f", (a->index + b->index) / 2.0); } else { - if ( (a->dhdl < 0) && (b->dhdl < 0) ) + if ((a->dhdl < 0) && (b->dhdl < 0)) { - sprintf(str, "%6.3f", (a->val[0]+b->val[0])/2.0); + sprintf(str, "%6.3f", (a->val[0] + b->val[0]) / 2.0); } } } @@ -403,32 +398,32 @@ static void lambda_vec_print_intermediate(const lambda_vec_t *a, /* calculate and return the absolute difference in lambda vectors: c = |a-b|. a and b must describe non-derivative lambda points */ -static double lambda_vec_abs_diff(const lambda_vec_t *a, const lambda_vec_t *b) +static double lambda_vec_abs_diff(const lambda_vec_t* a, const lambda_vec_t* b) { int i; double ret = 0.; - if ( (a->dhdl > 0) || (b->dhdl > 0) ) + if ((a->dhdl > 0) || (b->dhdl > 0)) { - gmx_fatal(FARGS, - "Trying to calculate the difference between derivatives instead of lambda points"); + gmx_fatal( + FARGS, + "Trying to calculate the difference between derivatives instead of lambda points"); } if (a->lc != b->lc) { - gmx_fatal(FARGS, - "Trying to calculate the difference lambdas with differing basis set"); + gmx_fatal(FARGS, "Trying to calculate the difference lambdas with differing basis set"); } for (i = 0; i < a->lc->N; i++) { double df = a->val[i] - b->val[i]; - ret += df*df; + ret += df * df; } return std::sqrt(ret); } /* check whether two lambda vectors are the same */ -static gmx_bool lambda_vec_same(const lambda_vec_t *a, const lambda_vec_t *b) +static gmx_bool lambda_vec_same(const lambda_vec_t* a, const lambda_vec_t* b) { int i; @@ -440,7 +435,7 @@ static gmx_bool lambda_vec_same(const lambda_vec_t *a, const lambda_vec_t *b) { for (i = 0; i < a->lc->N; i++) { - if (!gmx_within_tol(a->val[i], b->val[i], 10*GMX_REAL_EPS)) + if (!gmx_within_tol(a->val[i], b->val[i], 10 * GMX_REAL_EPS)) { return FALSE; } @@ -459,11 +454,10 @@ static gmx_bool lambda_vec_same(const lambda_vec_t *a, const lambda_vec_t *b) returns 1 if a is 'bigger' than b, returns 0 if they're the same, returns -1 if a is 'smaller' than b.*/ -static int lambda_vec_cmp_foreign(const lambda_vec_t *a, - const lambda_vec_t *b) +static int lambda_vec_cmp_foreign(const lambda_vec_t* a, const lambda_vec_t* b) { int i; - double norm_a = 0, norm_b = 0; + double norm_a = 0, norm_b = 0; gmx_bool different = FALSE; if (a->lc != b->lc) @@ -483,7 +477,7 @@ static int lambda_vec_cmp_foreign(const lambda_vec_t *a, { /* lambda vectors that are derivatives always sort higher than those without derivatives */ - if ((a->dhdl >= 0) != (b->dhdl >= 0) ) + if ((a->dhdl >= 0) != (b->dhdl >= 0)) { return (a->dhdl >= 0) ? 1 : -1; } @@ -494,12 +488,12 @@ static int lambda_vec_cmp_foreign(const lambda_vec_t *a, which is only valid if there is one component */ for (i = 0; i < a->lc->N; i++) { - if (!gmx_within_tol(a->val[i], b->val[i], 10*GMX_REAL_EPS)) + if (!gmx_within_tol(a->val[i], b->val[i], 10 * GMX_REAL_EPS)) { different = TRUE; } - norm_a += a->val[i]*a->val[i]; - norm_b += b->val[i]*b->val[i]; + norm_a += a->val[i] * a->val[i]; + norm_b += b->val[i] * b->val[i]; } if (!different) { @@ -513,8 +507,7 @@ static int lambda_vec_cmp_foreign(const lambda_vec_t *a, returns 1 if a is 'bigger' than b, returns 0 if they're the same, returns -1 if a is 'smaller' than b.*/ -static int lambda_vec_cmp_native(const lambda_vec_t *a, - const lambda_vec_t *b) +static int lambda_vec_cmp_native(const lambda_vec_t* a, const lambda_vec_t* b) { if (a->lc != b->lc) { @@ -533,15 +526,13 @@ static int lambda_vec_cmp_native(const lambda_vec_t *a, which is only valid if there is one component */ if (a->lc->N > 1) { - gmx_fatal(FARGS, - "Can't compare lambdas with no index and > 1 component"); + gmx_fatal(FARGS, "Can't compare lambdas with no index and > 1 component"); } if (a->dhdl >= 0 || b->dhdl >= 0) { - gmx_fatal(FARGS, - "Can't compare native lambdas that are derivatives"); + gmx_fatal(FARGS, "Can't compare native lambdas that are derivatives"); } - if (gmx_within_tol(a->val[0], b->val[0], 10*GMX_REAL_EPS)) + if (gmx_within_tol(a->val[0], b->val[0], 10 * GMX_REAL_EPS)) { return 0; } @@ -549,9 +540,7 @@ static int lambda_vec_cmp_native(const lambda_vec_t *a, } - - -static void hist_init(hist_t *h, int nhist, int *nbin) +static void hist_init(hist_t* h, int nhist, int* nbin) { int i; if (nhist > 2) @@ -564,13 +553,13 @@ static void hist_init(hist_t *h, int nhist, int *nbin) h->x0[i] = 0; h->nbin[i] = nbin[i]; h->start_time = h->delta_time = 0; - h->dx[i] = 0; + h->dx[i] = 0; } h->sum = 0; h->nhist = nhist; } -static void xvg_init(xvg_t *ba) +static void xvg_init(xvg_t* ba) { ba->filename = nullptr; ba->nset = 0; @@ -579,9 +568,12 @@ static void xvg_init(xvg_t *ba) ba->y = nullptr; } -static void samples_init(samples_t *s, lambda_vec_t *native_lambda, - lambda_vec_t *foreign_lambda, double temp, - gmx_bool derivative, const char *filename) +static void samples_init(samples_t* s, + lambda_vec_t* native_lambda, + lambda_vec_t* foreign_lambda, + double temp, + gmx_bool derivative, + const char* filename) { s->native_lambda = native_lambda; s->foreign_lambda = foreign_lambda; @@ -592,18 +584,18 @@ static void samples_init(samples_t *s, lambda_vec_t *native_lambda, s->du = nullptr; s->t = nullptr; s->start_time = s->delta_time = 0; - s->hist = nullptr; - s->du_alloc = nullptr; - s->t_alloc = nullptr; - s->hist_alloc = nullptr; - s->ndu_alloc = 0; - s->nt_alloc = 0; + s->hist = nullptr; + s->du_alloc = nullptr; + s->t_alloc = nullptr; + s->hist_alloc = nullptr; + s->ndu_alloc = 0; + s->nt_alloc = 0; s->ntot = 0; s->filename = filename; } -static void sample_range_init(sample_range_t *r, samples_t *s) +static void sample_range_init(sample_range_t* r, samples_t* s) { r->start = 0; r->end = s->ndu; @@ -611,8 +603,7 @@ static void sample_range_init(sample_range_t *r, samples_t *s) r->s = nullptr; } -static void sample_coll_init(sample_coll_t *sc, lambda_vec_t *native_lambda, - lambda_vec_t *foreign_lambda, double temp) +static void sample_coll_init(sample_coll_t* sc, lambda_vec_t* native_lambda, lambda_vec_t* foreign_lambda, double temp) { sc->native_lambda = native_lambda; sc->foreign_lambda = foreign_lambda; @@ -627,7 +618,7 @@ static void sample_coll_init(sample_coll_t *sc, lambda_vec_t *native_lambda, sc->next = sc->prev = nullptr; } -static void sample_coll_destroy(sample_coll_t *sc) +static void sample_coll_destroy(sample_coll_t* sc) { /* don't free the samples themselves */ sfree(sc->r); @@ -635,8 +626,7 @@ static void sample_coll_destroy(sample_coll_t *sc) } -static void lambda_data_init(lambda_data_t *l, lambda_vec_t *native_lambda, - double temp) +static void lambda_data_init(lambda_data_t* l, lambda_vec_t* native_lambda, double temp) { l->lambda = native_lambda; l->temp = temp; @@ -651,7 +641,7 @@ static void lambda_data_init(lambda_data_t *l, lambda_vec_t *native_lambda, l->sc->prev = l->sc; } -static void barres_init(barres_t *br) +static void barres_init(barres_t* br) { br->dg = 0; br->dg_err = 0; @@ -668,7 +658,7 @@ static void barres_init(barres_t *br) /* calculate the total number of samples in a sample collection */ -static void sample_coll_calc_ntot(sample_coll_t *sc) +static void sample_coll_calc_ntot(sample_coll_t* sc) { int i; @@ -692,10 +682,9 @@ static void sample_coll_calc_ntot(sample_coll_t *sc) /* find the barsamples_t associated with a lambda that corresponds to a specific foreign lambda */ -static sample_coll_t *lambda_data_find_sample_coll(lambda_data_t *l, - lambda_vec_t *foreign_lambda) +static sample_coll_t* lambda_data_find_sample_coll(lambda_data_t* l, lambda_vec_t* foreign_lambda) { - sample_coll_t *sc = l->sc->next; + sample_coll_t* sc = l->sc->next; while (sc != l->sc) { @@ -710,10 +699,10 @@ static sample_coll_t *lambda_data_find_sample_coll(lambda_data_t *l, } /* insert li into an ordered list of lambda_colls */ -static void lambda_data_insert_sample_coll(lambda_data_t *l, sample_coll_t *sc) +static void lambda_data_insert_sample_coll(lambda_data_t* l, sample_coll_t* sc) { - sample_coll_t *scn = l->sc->next; - while ( (scn != l->sc) ) + sample_coll_t* scn = l->sc->next; + while ((scn != l->sc)) { if (lambda_vec_cmp_foreign(scn->foreign_lambda, sc->foreign_lambda) > 0) { @@ -729,9 +718,9 @@ static void lambda_data_insert_sample_coll(lambda_data_t *l, sample_coll_t *sc) } /* insert li into an ordered list of lambdas */ -static void lambda_data_insert_lambda(lambda_data_t *head, lambda_data_t *li) +static void lambda_data_insert_lambda(lambda_data_t* head, lambda_data_t* li) { - lambda_data_t *lc = head->next; + lambda_data_t* lc = head->next; while (lc != head) { if (lambda_vec_cmp_native(lc->lambda, li->lambda) > 0) @@ -749,15 +738,14 @@ static void lambda_data_insert_lambda(lambda_data_t *head, lambda_data_t *li) /* insert a sample and a sample_range into a sample_coll. The samples are stored as a pointer, the range is copied. */ -static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s, - sample_range_t *r) +static void sample_coll_insert_sample(sample_coll_t* sc, samples_t* s, sample_range_t* r) { /* first check if it belongs here */ GMX_ASSERT(sc->next->s, "Next not properly initialized!"); if (sc->temp != s->temp) { - gmx_fatal(FARGS, "Temperatures in files %s and %s are not the same!", - s->filename, sc->next->s[0]->filename); + gmx_fatal(FARGS, "Temperatures in files %s and %s are not the same!", s->filename, + sc->next->s[0]->filename); } if (!lambda_vec_same(sc->native_lambda, s->native_lambda)) { @@ -771,9 +759,9 @@ static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s, } /* check if there's room */ - if ( (sc->nsamples + 1) > sc->nsamples_alloc) + if ((sc->nsamples + 1) > sc->nsamples_alloc) { - sc->nsamples_alloc = std::max(2*sc->nsamples_alloc, 2); + sc->nsamples_alloc = std::max(2 * sc->nsamples_alloc, 2); srenew(sc->s, sc->nsamples_alloc); srenew(sc->r, sc->nsamples_alloc); } @@ -786,18 +774,18 @@ static void sample_coll_insert_sample(sample_coll_t *sc, samples_t *s, /* insert a sample into a lambda_list, creating the right sample_coll if neccesary */ -static void lambda_data_list_insert_sample(lambda_data_t *head, samples_t *s) +static void lambda_data_list_insert_sample(lambda_data_t* head, samples_t* s) { gmx_bool found = FALSE; - sample_coll_t *sc; + sample_coll_t* sc; sample_range_t r; - lambda_data_t *l = head->next; + lambda_data_t* l = head->next; /* first search for the right lambda_data_t */ while (l != head) { - if (lambda_vec_same(l->lambda, s->native_lambda) ) + if (lambda_vec_same(l->lambda, s->native_lambda)) { found = TRUE; break; @@ -828,9 +816,8 @@ static void lambda_data_list_insert_sample(lambda_data_t *head, samples_t *s) /* make a histogram out of a sample collection */ -static void sample_coll_make_hist(sample_coll_t *sc, int **bin, - int *nbin_alloc, int *nbin, - double *dx, double *xmin, int nbin_default) +static void +sample_coll_make_hist(sample_coll_t* sc, int** bin, int* nbin_alloc, int* nbin, double* dx, double* xmin, int nbin_default) { int i, j, k; gmx_bool dx_set = FALSE; @@ -839,41 +826,41 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, gmx_bool xmax_set = FALSE; gmx_bool xmax_set_hard = FALSE; /* whether the xmax is bounded by the limits of a histogram */ - double xmax = -1; + double xmax = -1; /* first determine dx and xmin; try the histograms */ for (i = 0; i < sc->nsamples; i++) { if (sc->s[i]->hist) { - hist_t *hist = sc->s[i]->hist; + hist_t* hist = sc->s[i]->hist; for (k = 0; k < hist->nhist; k++) { double hdx = hist->dx[k]; - double xmax_now = (hist->x0[k]+hist->nbin[k])*hdx; + double xmax_now = (hist->x0[k] + hist->nbin[k]) * hdx; /* we use the biggest dx*/ - if ( (!dx_set) || hist->dx[0] > *dx) + if ((!dx_set) || hist->dx[0] > *dx) { dx_set = TRUE; *dx = hist->dx[0]; } - if ( (!xmin_set) || (hist->x0[k]*hdx) < *xmin) + if ((!xmin_set) || (hist->x0[k] * hdx) < *xmin) { xmin_set = TRUE; - *xmin = (hist->x0[k]*hdx); + *xmin = (hist->x0[k] * hdx); } - if ( (!xmax_set) || (xmax_now > xmax && !xmax_set_hard) ) + if ((!xmax_set) || (xmax_now > xmax && !xmax_set_hard)) { xmax_set = TRUE; xmax = xmax_now; - if (hist->bin[k][hist->nbin[k]-1] != 0) + if (hist->bin[k][hist->nbin[k] - 1] != 0) { xmax_set_hard = TRUE; } } - if (hist->bin[k][hist->nbin[k]-1] != 0 && (xmax_now < xmax) ) + if (hist->bin[k][hist->nbin[k] - 1] != 0 && (xmax_now < xmax)) { xmax_set_hard = TRUE; xmax = xmax_now; @@ -891,7 +878,7 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, int endi = sc->r[i].end; double du_xmin = sc->s[i]->du[starti]; double du_xmax = sc->s[i]->du[starti]; - for (j = starti+1; j < endi; j++) + for (j = starti + 1; j < endi; j++) { if (sc->s[i]->du[j] < du_xmin) { @@ -904,12 +891,12 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, } /* and now change the limits */ - if ( (!xmin_set) || (du_xmin < *xmin) ) + if ((!xmin_set) || (du_xmin < *xmin)) { xmin_set = TRUE; *xmin = du_xmin; } - if ( (!xmax_set) || ((du_xmax > xmax) && !xmax_set_hard) ) + if ((!xmax_set) || ((du_xmax > xmax) && !xmax_set_hard)) { xmax_set = TRUE; xmax = du_xmax; @@ -927,12 +914,12 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, if (!dx_set) { *nbin = nbin_default; - *dx = (xmax-(*xmin))/((*nbin)-2); /* -2 because we want the last bin to - be 0, and we count from 0 */ + *dx = (xmax - (*xmin)) / ((*nbin) - 2); /* -2 because we want the last bin to + be 0, and we count from 0 */ } else { - *nbin = static_cast((xmax-(*xmin))/(*dx)); + *nbin = static_cast((xmax - (*xmin)) / (*dx)); } if (*nbin > *nbin_alloc) @@ -952,21 +939,21 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, { if (sc->s[i]->hist) { - hist_t *hist = sc->s[i]->hist; + hist_t* hist = sc->s[i]->hist; for (k = 0; k < hist->nhist; k++) { double hdx = hist->dx[k]; - double xmin_hist = hist->x0[k]*hdx; + double xmin_hist = hist->x0[k] * hdx; for (j = 0; j < hist->nbin[k]; j++) { /* calculate the bin corresponding to the middle of the original bin */ - double x = hdx*(j+0.5) + xmin_hist; - int binnr = static_cast((x-(*xmin))/(*dx)); + double x = hdx * (j + 0.5) + xmin_hist; + int binnr = static_cast((x - (*xmin)) / (*dx)); if (binnr >= *nbin || binnr < 0) { - binnr = (*nbin)-1; + binnr = (*nbin) - 1; } (*bin)[binnr] += hist->bin[k][j]; @@ -979,10 +966,10 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, int endi = sc->r[i].end; for (j = starti; j < endi; j++) { - int binnr = static_cast((sc->s[i]->du[j]-(*xmin))/(*dx)); + int binnr = static_cast((sc->s[i]->du[j] - (*xmin)) / (*dx)); if (binnr >= *nbin || binnr < 0) { - binnr = (*nbin)-1; + binnr = (*nbin) - 1; } (*bin)[binnr]++; @@ -992,26 +979,25 @@ static void sample_coll_make_hist(sample_coll_t *sc, int **bin, } /* write a collection of histograms to a file */ -static void sim_data_histogram(sim_data_t *sd, const char *filename, - int nbin_default, const gmx_output_env_t *oenv) +static void sim_data_histogram(sim_data_t* sd, const char* filename, int nbin_default, const gmx_output_env_t* oenv) { char label_x[STRLEN]; - const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda"; - const char *title = "N(\\DeltaH)"; - const char *label_y = "Samples"; - FILE *fp; - lambda_data_t *bl; + const char * dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda"; + const char* title = "N(\\DeltaH)"; + const char* label_y = "Samples"; + FILE* fp; + lambda_data_t* bl; int nsets = 0; - char **setnames = nullptr; + char** setnames = nullptr; gmx_bool first_set = FALSE; /* histogram data: */ - int *hist = nullptr; + int* hist = nullptr; int nbin = 0; int nbin_alloc = 0; double dx = 0; double minval = 0; int i; - lambda_data_t *bl_head = sd->lb; + lambda_data_t* bl_head = sd->lb; printf("\nWriting histogram to %s\n", filename); sprintf(label_x, "\\DeltaH (%s)", unit_energy); @@ -1023,7 +1009,7 @@ static void sim_data_histogram(sim_data_t *sd, const char *filename, /* iterate over all lambdas */ while (bl != bl_head) { - sample_coll_t *sc = bl->sc->next; + sample_coll_t* sc = bl->sc->next; /* iterate over all samples */ while (sc != bl->sc) @@ -1032,19 +1018,17 @@ static void sim_data_histogram(sim_data_t *sd, const char *filename, nsets++; srenew(setnames, nsets); - snew(setnames[nsets-1], STRLEN); + snew(setnames[nsets - 1], STRLEN); if (sc->foreign_lambda->dhdl < 0) { lambda_vec_print(sc->native_lambda, buf, FALSE); lambda_vec_print(sc->foreign_lambda, buf2, FALSE); - sprintf(setnames[nsets-1], "N(%s(%s=%s) | %s=%s)", - deltag, lambda, buf2, lambda, buf); + sprintf(setnames[nsets - 1], "N(%s(%s=%s) | %s=%s)", deltag, lambda, buf2, lambda, buf); } else { lambda_vec_print(sc->native_lambda, buf, FALSE); - sprintf(setnames[nsets-1], "N(%s | %s=%s)", - dhdl, lambda, buf); + sprintf(setnames[nsets - 1], "N(%s | %s=%s)", dhdl, lambda, buf); } sc = sc->next; } @@ -1059,7 +1043,7 @@ static void sim_data_histogram(sim_data_t *sd, const char *filename, /* iterate over all lambdas */ while (bl != bl_head) { - sample_coll_t *sc = bl->sc->next; + sample_coll_t* sc = bl->sc->next; /* iterate over all samples */ while (sc != bl->sc) @@ -1069,13 +1053,12 @@ static void sim_data_histogram(sim_data_t *sd, const char *filename, xvgr_new_dataset(fp, 0, 0, nullptr, oenv); } - sample_coll_make_hist(sc, &hist, &nbin_alloc, &nbin, &dx, &minval, - nbin_default); + sample_coll_make_hist(sc, &hist, &nbin_alloc, &nbin, &dx, &minval, nbin_default); for (i = 0; i < nbin; i++) { - double xmin = i*dx + minval; - double xmax = (i+1)*dx + minval; + double xmin = i * dx + minval; + double xmax = (i + 1) * dx + minval; fprintf(fp, "%g %d\n%g %d\n", xmin, hist[i], xmax, hist[i]); } @@ -1095,26 +1078,25 @@ static void sim_data_histogram(sim_data_t *sd, const char *filename, xvgrclose(fp); } -static int -snprint_lambda_vec(char *str, int sz, const char *label, lambda_vec_t *lambda) +static int snprint_lambda_vec(char* str, int sz, const char* label, lambda_vec_t* lambda) { int n = 0; - n += snprintf(str+n, sz-n, "lambda vector [%s]: ", label); + n += snprintf(str + n, sz - n, "lambda vector [%s]: ", label); if (lambda->index >= 0) { - n += snprintf(str+n, sz-n, " init-lambda-state=%d", lambda->index); + n += snprintf(str + n, sz - n, " init-lambda-state=%d", lambda->index); } if (lambda->dhdl >= 0) { - n += snprintf(str+n, sz-n, " dhdl index=%d", lambda->dhdl); + n += snprintf(str + n, sz - n, " dhdl index=%d", lambda->dhdl); } else { int i; for (i = 0; i < lambda->lc->N; i++) { - n += snprintf(str+n, sz-n, " (%s) l=%g", lambda->lc->names[i], lambda->val[i]); + n += snprintf(str + n, sz - n, " (%s) l=%g", lambda->lc->names[i], lambda->val[i]); } } return n; @@ -1122,15 +1104,14 @@ snprint_lambda_vec(char *str, int sz, const char *label, lambda_vec_t *lambda) /* create a collection (array) of barres_t object given a ordered linked list of barlamda_t sample collections */ -static barres_t *barres_list_create(sim_data_t *sd, int *nres, - gmx_bool use_dhdl) +static barres_t* barres_list_create(sim_data_t* sd, int* nres, gmx_bool use_dhdl) { - lambda_data_t *bl; + lambda_data_t* bl; int nlambda = 0; - barres_t *res; + barres_t* res; gmx_bool dhdl = FALSE; gmx_bool first = TRUE; - lambda_data_t *bl_head = sd->lb; + lambda_data_t* bl_head = sd->lb; /* first count the lambdas */ bl = bl_head->next; @@ -1139,7 +1120,7 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, nlambda++; bl = bl->next; } - snew(res, nlambda-1); + snew(res, nlambda - 1); /* next put the right samples in the res */ *nres = 0; @@ -1147,7 +1128,7 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, while (bl != bl_head) { sample_coll_t *sc, *scprev; - barres_t *br = &(res[*nres]); + barres_t* br = &(res[*nres]); /* there is always a previous one. we search for that as a foreign lambda: */ scprev = lambda_data_find_sample_coll(bl->prev, bl->lambda); @@ -1164,12 +1145,16 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, if (first) { - printf("\nWARNING: Using the derivative data (dH/dlambda) to extrapolate delta H values.\nThis will only work if the Hamiltonian is linear in lambda.\n"); + printf("\nWARNING: Using the derivative data (dH/dlambda) to extrapolate delta H " + "values.\nThis will only work if the Hamiltonian is linear in lambda.\n"); dhdl = TRUE; } if (!dhdl) { - gmx_fatal(FARGS, "Some dhdl files contain only one value (dH/dl), while others \ncontain multiple values (dH/dl and/or Delta H), will not proceed \nbecause of possible inconsistencies.\n"); + gmx_fatal(FARGS, + "Some dhdl files contain only one value (dH/dl), while others \ncontain " + "multiple values (dH/dl and/or Delta H), will not proceed \nbecause of " + "possible inconsistencies.\n"); } } else if (!scprev && !sc) @@ -1178,7 +1163,14 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, snprint_lambda_vec(descX, STRLEN, "X", bl->prev->lambda); snprint_lambda_vec(descY, STRLEN, "Y", bl->lambda); - gmx_fatal(FARGS, "There is no path between the states X & Y below that is covered by foreign lambdas:\ncannot proceed with BAR.\nUse thermodynamic integration of dH/dl by calculating the averages of dH/dl\nwith g_analyze and integrating them.\nAlternatively, use the -extp option if (and only if) the Hamiltonian\ndepends linearly on lambda, which is NOT normally the case.\n\n%s\n%s\n", descX, descY); + gmx_fatal(FARGS, + "There is no path between the states X & Y below that is covered by foreign " + "lambdas:\ncannot proceed with BAR.\nUse thermodynamic integration of dH/dl " + "by calculating the averages of dH/dl\nwith g_analyze and integrating " + "them.\nAlternatively, use the -extp option if (and only if) the " + "Hamiltonian\ndepends linearly on lambda, which is NOT normally the " + "case.\n\n%s\n%s\n", + descX, descY); } /* normal delta H */ @@ -1187,14 +1179,20 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, char descX[STRLEN], descY[STRLEN]; snprint_lambda_vec(descX, STRLEN, "X", bl->lambda); snprint_lambda_vec(descY, STRLEN, "Y", bl->prev->lambda); - gmx_fatal(FARGS, "Could not find a set for foreign lambda (state X below)\nin the files for main lambda (state Y below)\n\n%s\n%s\n", descX, descY); + gmx_fatal(FARGS, + "Could not find a set for foreign lambda (state X below)\nin the files for " + "main lambda (state Y below)\n\n%s\n%s\n", + descX, descY); } if (!sc) { char descX[STRLEN], descY[STRLEN]; snprint_lambda_vec(descX, STRLEN, "X", bl->prev->lambda); snprint_lambda_vec(descY, STRLEN, "Y", bl->lambda); - gmx_fatal(FARGS, "Could not find a set for foreign lambda (state X below)\nin the files for main lambda (state Y below)\n\n%s\n%s\n", descX, descY); + gmx_fatal(FARGS, + "Could not find a set for foreign lambda (state X below)\nin the files for " + "main lambda (state Y below)\n\n%s\n%s\n", + descX, descY); } br->a = scprev; br->b = sc; @@ -1207,7 +1205,7 @@ static barres_t *barres_list_create(sim_data_t *sd, int *nres, } /* estimate the maximum discretization error */ -static double barres_list_max_disc_err(barres_t *res, int nres) +static double barres_list_max_disc_err(barres_t* res, int nres) { int i, j; double disc_err = 0.; @@ -1215,10 +1213,9 @@ static double barres_list_max_disc_err(barres_t *res, int nres) for (i = 0; i < nres; i++) { - barres_t *br = &(res[i]); + barres_t* br = &(res[i]); - delta_lambda = lambda_vec_abs_diff(br->b->native_lambda, - br->a->native_lambda); + delta_lambda = lambda_vec_abs_diff(br->b->native_lambda, br->a->native_lambda); for (j = 0; j < br->a->nsamples; j++) { @@ -1227,10 +1224,10 @@ static double barres_list_max_disc_err(barres_t *res, int nres) double Wfac = 1.; if (br->a->s[j]->derivative) { - Wfac = delta_lambda; + Wfac = delta_lambda; } - disc_err = std::max(disc_err, Wfac*br->a->s[j]->hist->dx[0]); + disc_err = std::max(disc_err, Wfac * br->a->s[j]->hist->dx[0]); } } for (j = 0; j < br->b->nsamples; j++) @@ -1240,9 +1237,9 @@ static double barres_list_max_disc_err(barres_t *res, int nres) double Wfac = 1.; if (br->b->s[j]->derivative) { - Wfac = delta_lambda; + Wfac = delta_lambda; } - disc_err = std::max(disc_err, Wfac*br->b->s[j]->hist->dx[0]); + disc_err = std::max(disc_err, Wfac * br->b->s[j]->hist->dx[0]); } } } @@ -1251,18 +1248,16 @@ static double barres_list_max_disc_err(barres_t *res, int nres) /* impose start and end times on a sample collection, updating sample_ranges */ -static void sample_coll_impose_times(sample_coll_t *sc, double begin_t, - double end_t) +static void sample_coll_impose_times(sample_coll_t* sc, double begin_t, double end_t) { int i; for (i = 0; i < sc->nsamples; i++) { - samples_t *s = sc->s[i]; - sample_range_t *r = &(sc->r[i]); + samples_t* s = sc->s[i]; + sample_range_t* r = &(sc->r[i]); if (s->hist) { - double end_time = s->hist->delta_time*s->hist->sum + - s->hist->start_time; + double end_time = s->hist->delta_time * s->hist->sum + s->hist->start_time; if (s->hist->start_time < begin_t || end_time > end_t) { r->use = FALSE; @@ -1275,12 +1270,12 @@ static void sample_coll_impose_times(sample_coll_t *sc, double begin_t, double end_time; if (s->start_time < begin_t) { - r->start = static_cast((begin_t - s->start_time)/s->delta_time); + r->start = static_cast((begin_t - s->start_time) / s->delta_time); } - end_time = s->delta_time*s->ndu + s->start_time; + end_time = s->delta_time * s->ndu + s->start_time; if (end_time > end_t) { - r->end = static_cast((end_t - s->start_time)/s->delta_time); + r->end = static_cast((end_t - s->start_time) / s->delta_time); } } else @@ -1309,12 +1304,12 @@ static void sample_coll_impose_times(sample_coll_t *sc, double begin_t, sample_coll_calc_ntot(sc); } -static void sim_data_impose_times(sim_data_t *sd, double begin, double end) +static void sim_data_impose_times(sim_data_t* sd, double begin, double end) { double first_t, last_t; double begin_t, end_t; - lambda_data_t *lc; - lambda_data_t *head = sd->lb; + lambda_data_t* lc; + lambda_data_t* head = sd->lb; int j; if (begin <= 0 && end < 0) @@ -1328,7 +1323,7 @@ static void sim_data_impose_times(sim_data_t *sd, double begin, double end) lc = head->next; while (lc != head) { - sample_coll_t *sc = lc->sc->next; + sample_coll_t* sc = lc->sc->next; while (sc != lc->sc) { for (j = 0; j < sc->nsamples; j++) @@ -1336,20 +1331,20 @@ static void sim_data_impose_times(sim_data_t *sd, double begin, double end) double start_t, end_t; start_t = sc->s[j]->start_time; - end_t = sc->s[j]->start_time; + end_t = sc->s[j]->start_time; if (sc->s[j]->hist) { - end_t += sc->s[j]->delta_time*sc->s[j]->hist->sum; + end_t += sc->s[j]->delta_time * sc->s[j]->hist->sum; } else { if (sc->s[j]->t) { - end_t = sc->s[j]->t[sc->s[j]->ndu-1]; + end_t = sc->s[j]->t[sc->s[j]->ndu - 1]; } else { - end_t += sc->s[j]->delta_time*sc->s[j]->ndu; + end_t += sc->s[j]->delta_time * sc->s[j]->ndu; } } @@ -1397,7 +1392,7 @@ static void sim_data_impose_times(sim_data_t *sd, double begin, double end) lc = head->next; while (lc != head) { - sample_coll_t *sc = lc->sc->next; + sample_coll_t* sc = lc->sc->next; while (sc != lc->sc) { sample_coll_impose_times(sc, begin_t, end_t); @@ -1409,15 +1404,13 @@ static void sim_data_impose_times(sim_data_t *sd, double begin, double end) /* create subsample i out of ni from an existing sample_coll */ -static gmx_bool sample_coll_create_subsample(sample_coll_t *sc, - sample_coll_t *sc_orig, - int i, int ni) +static gmx_bool sample_coll_create_subsample(sample_coll_t* sc, sample_coll_t* sc_orig, int i, int ni) { - int j; + int j; - int64_t ntot_start; - int64_t ntot_end; - int64_t ntot_so_far; + int64_t ntot_start; + int64_t ntot_end; + int64_t ntot_so_far; *sc = *sc_orig; /* just copy all fields */ @@ -1434,8 +1427,8 @@ static gmx_bool sample_coll_create_subsample(sample_coll_t *sc, /* now fix start and end fields */ /* the casts avoid possible overflows */ - ntot_start = static_cast(sc_orig->ntot*static_cast(i)/static_cast(ni)); - ntot_end = static_cast(sc_orig->ntot*static_cast(i+1)/static_cast(ni)); + ntot_start = static_cast(sc_orig->ntot * static_cast(i) / static_cast(ni)); + ntot_end = static_cast(sc_orig->ntot * static_cast(i + 1) / static_cast(ni)); ntot_so_far = 0; for (j = 0; j < sc->nsamples; j++) { @@ -1477,14 +1470,16 @@ static gmx_bool sample_coll_create_subsample(sample_coll_t *sc, } /* check if we're in range at all */ - if ( (new_end < new_start) || (new_start > sc->r[j].end) ) + if ((new_end < new_start) || (new_start > sc->r[j].end)) { new_start = 0; new_end = 0; } /* and write the new range */ - GMX_RELEASE_ASSERT(new_start <= std::numeric_limits::max(), "Value of 'new_start' too large for int converstion"); - GMX_RELEASE_ASSERT(new_end <= std::numeric_limits::max(), "Value of 'new_end' too large for int converstion"); + GMX_RELEASE_ASSERT(new_start <= std::numeric_limits::max(), + "Value of 'new_start' too large for int converstion"); + GMX_RELEASE_ASSERT(new_end <= std::numeric_limits::max(), + "Value of 'new_end' too large for int converstion"); sc->r[j].start = static_cast(new_start); sc->r[j].end = static_cast(new_end); } @@ -1500,8 +1495,8 @@ static gmx_bool sample_coll_create_subsample(sample_coll_t *sc, /* first calculate normalized bounds (where 0 is the start of the hist range, and 1 the end) */ - ntot_start_norm = (ntot_start-ntot_so_far)/static_cast(ntot_add); - ntot_end_norm = (ntot_end-ntot_so_far)/static_cast(ntot_add); + ntot_start_norm = (ntot_start - ntot_so_far) / static_cast(ntot_add); + ntot_end_norm = (ntot_end - ntot_so_far) / static_cast(ntot_add); /* now fix the boundaries */ ntot_start_norm = std::min(1.0, std::max(0.0, ntot_start_norm)); @@ -1532,47 +1527,46 @@ static gmx_bool sample_coll_create_subsample(sample_coll_t *sc, } /* calculate minimum and maximum work values in sample collection */ -static void sample_coll_min_max(sample_coll_t *sc, double Wfac, - double *Wmin, double *Wmax) +static void sample_coll_min_max(sample_coll_t* sc, double Wfac, double* Wmin, double* Wmax) { int i, j; - *Wmin = std::numeric_limits::max(); + *Wmin = std::numeric_limits::max(); *Wmax = -std::numeric_limits::max(); for (i = 0; i < sc->nsamples; i++) { - samples_t *s = sc->s[i]; - sample_range_t *r = &(sc->r[i]); + samples_t* s = sc->s[i]; + sample_range_t* r = &(sc->r[i]); if (r->use) { if (!s->hist) { for (j = r->start; j < r->end; j++) { - *Wmin = std::min(*Wmin, s->du[j]*Wfac); - *Wmax = std::max(*Wmax, s->du[j]*Wfac); + *Wmin = std::min(*Wmin, s->du[j] * Wfac); + *Wmax = std::max(*Wmax, s->du[j] * Wfac); } } else { int hd = 0; /* determine the histogram direction: */ double dx; - if ( (s->hist->nhist > 1) && (Wfac < 0) ) + if ((s->hist->nhist > 1) && (Wfac < 0)) { hd = 1; } dx = s->hist->dx[hd]; - for (j = s->hist->nbin[hd]-1; j >= 0; j--) + for (j = s->hist->nbin[hd] - 1; j >= 0; j--) { - *Wmin = std::min(*Wmin, Wfac*(s->hist->x0[hd])*dx); - *Wmax = std::max(*Wmax, Wfac*(s->hist->x0[hd])*dx); + *Wmin = std::min(*Wmin, Wfac * (s->hist->x0[hd]) * dx); + *Wmax = std::max(*Wmax, Wfac * (s->hist->x0[hd]) * dx); /* look for the highest value bin with values */ if (s->hist->bin[hd][j] > 0) { - *Wmin = std::min(*Wmin, Wfac*(j+s->hist->x0[hd]+1)*dx); - *Wmax = std::max(*Wmax, Wfac*(j+s->hist->x0[hd]+1)*dx); + *Wmin = std::min(*Wmin, Wfac * (j + s->hist->x0[hd] + 1) * dx); + *Wmax = std::max(*Wmax, Wfac * (j + s->hist->x0[hd] + 1) * dx); break; } } @@ -1582,7 +1576,7 @@ static void sample_coll_min_max(sample_coll_t *sc, double Wfac, } /* Initialize a sim_data structure */ -static void sim_data_init(sim_data_t *sd) +static void sim_data_init(sim_data_t* sd) { /* make linked list */ sd->lb = &(sd->lb_head); @@ -1593,7 +1587,7 @@ static void sim_data_init(sim_data_t *sd) } -static double calc_bar_sum(int n, const double *W, double Wfac, double sbMmDG) +static double calc_bar_sum(int n, const double* W, double Wfac, double sbMmDG) { int i; double sum; @@ -1602,7 +1596,7 @@ static double calc_bar_sum(int n, const double *W, double Wfac, double sbMmDG) for (i = 0; i < n; i++) { - sum += 1./(1. + std::exp(Wfac*W[i] + sbMmDG)); + sum += 1. / (1. + std::exp(Wfac * W[i] + sbMmDG)); } return sum; @@ -1613,8 +1607,7 @@ static double calc_bar_sum(int n, const double *W, double Wfac, double sbMmDG) if type== 0, calculate the best estimate for the average, if type==-1, calculate the minimum possible value given the histogram if type== 1, calculate the maximum possible value given the histogram */ -static double calc_bar_sum_hist(const hist_t *hist, double Wfac, double sbMmDG, - int type) +static double calc_bar_sum_hist(const hist_t* hist, double Wfac, double sbMmDG, int type) { double sum = 0.; int i; @@ -1625,12 +1618,12 @@ static double calc_bar_sum_hist(const hist_t *hist, double Wfac, double sbMmDG, int hd = 0; /* determine the histogram direction: */ double dx; - if ( (hist->nhist > 1) && (Wfac < 0) ) + if ((hist->nhist > 1) && (Wfac < 0)) { hd = 1; } dx = hist->dx[hd]; - maxbin = hist->nbin[hd]-1; + maxbin = hist->nbin[hd] - 1; if (type == 1) { maxbin = hist->nbin[hd]; /* we also add whatever was out of range */ @@ -1638,17 +1631,16 @@ static double calc_bar_sum_hist(const hist_t *hist, double Wfac, double sbMmDG, for (i = 0; i < maxbin; i++) { - double x = Wfac*((i+hist->x0[hd])+0.5)*dx; /* bin middle */ - double pxdx = hist->bin[0][i]*normdx; /* p(x)dx */ + double x = Wfac * ((i + hist->x0[hd]) + 0.5) * dx; /* bin middle */ + double pxdx = hist->bin[0][i] * normdx; /* p(x)dx */ - sum += pxdx/(1. + std::exp(x + sbMmDG)); + sum += pxdx / (1. + std::exp(x + sbMmDG)); } return sum; } -static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb, - double temp, double tol, int type) +static double calc_bar_lowlevel(sample_coll_t* ca, sample_coll_t* cb, double temp, double tol, int type) { double kT, beta, M; int i; @@ -1656,14 +1648,14 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb, double DG0, DG1, DG2, dDG1; double n1, n2; /* numbers of samples as doubles */ - kT = BOLTZ*temp; - beta = 1/kT; + kT = BOLTZ * temp; + beta = 1 / kT; /* count the numbers of samples */ n1 = ca->ntot; n2 = cb->ntot; - M = std::log(n1/n2); + M = std::log(n1 / n2); /*if (!lambda_vec_same(ca->native_lambda, ca->foreign_lambda))*/ if (ca->foreign_lambda->dhdl < 0) @@ -1678,16 +1670,14 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb, /* we're using dhdl, so delta_lambda needs to be a multiplication factor. */ /*double delta_lambda=cb->native_lambda-ca->native_lambda;*/ - double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, - ca->native_lambda); + double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, ca->native_lambda); if (cb->native_lambda->lc->N > 1) { - gmx_fatal(FARGS, - "Can't (yet) do multi-component dhdl interpolation"); + gmx_fatal(FARGS, "Can't (yet) do multi-component dhdl interpolation"); } - Wfac1 = beta*delta_lambda; - Wfac2 = -beta*delta_lambda; + Wfac1 = beta * delta_lambda; + Wfac2 = -beta * delta_lambda; } if (beta < 1) @@ -1723,44 +1713,42 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb, smaller than what we get out of the BAR averages. For the comparison we can use twice the tolerance. */ - while (DG2 - DG0 > 2*tol) + while (DG2 - DG0 > 2 * tol) { - DG1 = 0.5*(DG0 + DG2); + DG1 = 0.5 * (DG0 + DG2); /* calculate the BAR averages */ dDG1 = 0.; for (i = 0; i < ca->nsamples; i++) { - samples_t *s = ca->s[i]; - sample_range_t *r = &(ca->r[i]); + samples_t* s = ca->s[i]; + sample_range_t* r = &(ca->r[i]); if (r->use) { if (s->hist) { - dDG1 += calc_bar_sum_hist(s->hist, Wfac1, (M-DG1), type); + dDG1 += calc_bar_sum_hist(s->hist, Wfac1, (M - DG1), type); } else { - dDG1 += calc_bar_sum(r->end - r->start, s->du + r->start, - Wfac1, (M-DG1)); + dDG1 += calc_bar_sum(r->end - r->start, s->du + r->start, Wfac1, (M - DG1)); } } } for (i = 0; i < cb->nsamples; i++) { - samples_t *s = cb->s[i]; - sample_range_t *r = &(cb->r[i]); + samples_t* s = cb->s[i]; + sample_range_t* r = &(cb->r[i]); if (r->use) { if (s->hist) { - dDG1 -= calc_bar_sum_hist(s->hist, Wfac2, -(M-DG1), type); + dDG1 -= calc_bar_sum_hist(s->hist, Wfac2, -(M - DG1), type); } else { - dDG1 -= calc_bar_sum(r->end - r->start, s->du + r->start, - Wfac2, -(M-DG1)); + dDG1 -= calc_bar_sum(r->end - r->start, s->du + r->start, Wfac2, -(M - DG1)); } } } @@ -1779,11 +1767,10 @@ static double calc_bar_lowlevel(sample_coll_t *ca, sample_coll_t *cb, } } - return 0.5*(DG0 + DG2); + return 0.5 * (DG0 + DG2); } -static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, - double temp, double dg, double *sa, double *sb) +static void calc_rel_entropy(sample_coll_t* ca, sample_coll_t* cb, double temp, double dg, double* sa, double* sb) { int i, j; double W_ab = 0.; @@ -1792,8 +1779,8 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, double Wfac1, Wfac2; double n1, n2; - kT = BOLTZ*temp; - beta = 1/kT; + kT = BOLTZ * temp; + beta = 1 / kT; /* count the numbers of samples */ n1 = ca->ntot; @@ -1812,24 +1799,23 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, { /* we're using dhdl, so delta_lambda needs to be a multiplication factor. */ - double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, - ca->native_lambda); - Wfac1 = beta*delta_lambda; - Wfac2 = -beta*delta_lambda; + double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, ca->native_lambda); + Wfac1 = beta * delta_lambda; + Wfac2 = -beta * delta_lambda; } /* first calculate the average work in both directions */ for (i = 0; i < ca->nsamples; i++) { - samples_t *s = ca->s[i]; - sample_range_t *r = &(ca->r[i]); + samples_t* s = ca->s[i]; + sample_range_t* r = &(ca->r[i]); if (r->use) { if (!s->hist) { for (j = r->start; j < r->end; j++) { - W_ab += Wfac1*s->du[j]; + W_ab += Wfac1 * s->du[j]; } } else @@ -1839,7 +1825,7 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, double normdx = 1.; double dx; int hd = 0; /* histogram direction */ - if ( (s->hist->nhist > 1) && (Wfac1 < 0) ) + if ((s->hist->nhist > 1) && (Wfac1 < 0)) { hd = 1; } @@ -1847,9 +1833,9 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, for (j = 0; j < s->hist->nbin[0]; j++) { - double x = Wfac1*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/ - double pxdx = s->hist->bin[0][j]*normdx; /* p(x)dx */ - W_ab += pxdx*x; + double x = Wfac1 * ((j + s->hist->x0[0]) + 0.5) * dx; /*bin ctr*/ + double pxdx = s->hist->bin[0][j] * normdx; /* p(x)dx */ + W_ab += pxdx * x; } } } @@ -1858,15 +1844,15 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, for (i = 0; i < cb->nsamples; i++) { - samples_t *s = cb->s[i]; - sample_range_t *r = &(cb->r[i]); + samples_t* s = cb->s[i]; + sample_range_t* r = &(cb->r[i]); if (r->use) { if (!s->hist) { for (j = r->start; j < r->end; j++) { - W_ba += Wfac1*s->du[j]; + W_ba += Wfac1 * s->du[j]; } } else @@ -1876,7 +1862,7 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, double normdx = 1.; double dx; int hd = 0; /* histogram direction */ - if ( (s->hist->nhist > 1) && (Wfac2 < 0) ) + if ((s->hist->nhist > 1) && (Wfac2 < 0)) { hd = 1; } @@ -1884,9 +1870,9 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, for (j = 0; j < s->hist->nbin[0]; j++) { - double x = Wfac1*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/ - double pxdx = s->hist->bin[0][j]*normdx; /* p(x)dx */ - W_ba += pxdx*x; + double x = Wfac1 * ((j + s->hist->x0[0]) + 0.5) * dx; /*bin ctr*/ + double pxdx = s->hist->bin[0][j] * normdx; /* p(x)dx */ + W_ba += pxdx * x; } } } @@ -1898,8 +1884,7 @@ static void calc_rel_entropy(sample_coll_t *ca, sample_coll_t *cb, *sb = (W_ba + dg); } -static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, - double temp, double dg, double *stddev) +static void calc_dg_stddev(sample_coll_t* ca, sample_coll_t* cb, double temp, double dg, double* stddev) { int i, j; double M; @@ -1908,8 +1893,8 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, double Wfac1, Wfac2; double n1, n2; - kT = BOLTZ*temp; - beta = 1/kT; + kT = BOLTZ * temp; + beta = 1 / kT; /* count the numbers of samples */ n1 = ca->ntot; @@ -1928,27 +1913,26 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, { /* we're using dhdl, so delta_lambda needs to be a multiplication factor. */ - double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, - ca->native_lambda); - Wfac1 = beta*delta_lambda; - Wfac2 = -beta*delta_lambda; + double delta_lambda = lambda_vec_abs_diff(cb->native_lambda, ca->native_lambda); + Wfac1 = beta * delta_lambda; + Wfac2 = -beta * delta_lambda; } - M = std::log(n1/n2); + M = std::log(n1 / n2); /* calculate average in both directions */ for (i = 0; i < ca->nsamples; i++) { - samples_t *s = ca->s[i]; - sample_range_t *r = &(ca->r[i]); + samples_t* s = ca->s[i]; + sample_range_t* r = &(ca->r[i]); if (r->use) { if (!s->hist) { for (j = r->start; j < r->end; j++) { - sigmafact += 1./(2. + 2.*std::cosh((M + Wfac1*s->du[j] - dg))); + sigmafact += 1. / (2. + 2. * std::cosh((M + Wfac1 * s->du[j] - dg))); } } else @@ -1958,7 +1942,7 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, double normdx = 1.; double dx; int hd = 0; /* histogram direction */ - if ( (s->hist->nhist > 1) && (Wfac1 < 0) ) + if ((s->hist->nhist > 1) && (Wfac1 < 0)) { hd = 1; } @@ -1966,25 +1950,25 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, for (j = 0; j < s->hist->nbin[0]; j++) { - double x = Wfac1*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/ - double pxdx = s->hist->bin[0][j]*normdx; /* p(x)dx */ + double x = Wfac1 * ((j + s->hist->x0[0]) + 0.5) * dx; /*bin ctr*/ + double pxdx = s->hist->bin[0][j] * normdx; /* p(x)dx */ - sigmafact += pxdx/(2. + 2.*std::cosh((M + x - dg))); + sigmafact += pxdx / (2. + 2. * std::cosh((M + x - dg))); } } } } for (i = 0; i < cb->nsamples; i++) { - samples_t *s = cb->s[i]; - sample_range_t *r = &(cb->r[i]); + samples_t* s = cb->s[i]; + sample_range_t* r = &(cb->r[i]); if (r->use) { if (!s->hist) { for (j = r->start; j < r->end; j++) { - sigmafact += 1./(2. + 2.*std::cosh((M - Wfac2*s->du[j] - dg))); + sigmafact += 1. / (2. + 2. * std::cosh((M - Wfac2 * s->du[j] - dg))); } } else @@ -1994,7 +1978,7 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, double normdx = 1.; double dx; int hd = 0; /* histogram direction */ - if ( (s->hist->nhist > 1) && (Wfac2 < 0) ) + if ((s->hist->nhist > 1) && (Wfac2 < 0)) { hd = 1; } @@ -2002,10 +1986,10 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, for (j = 0; j < s->hist->nbin[0]; j++) { - double x = Wfac2*((j+s->hist->x0[0])+0.5)*dx; /*bin ctr*/ - double pxdx = s->hist->bin[0][j]*normdx; /* p(x)dx */ + double x = Wfac2 * ((j + s->hist->x0[0]) + 0.5) * dx; /*bin ctr*/ + double pxdx = s->hist->bin[0][j] * normdx; /* p(x)dx */ - sigmafact += pxdx/(2. + 2.*std::cosh((M - x - dg))); + sigmafact += pxdx / (2. + 2. * std::cosh((M - x - dg))); } } } @@ -2016,18 +2000,15 @@ static void calc_dg_stddev(sample_coll_t *ca, sample_coll_t *cb, /* Eq. 10 from Shirts, Bair, Hooker & Pande, Phys. Rev. Lett 91, 140601 (2003): */ - *stddev = std::sqrt(((1.0/sigmafact) - ( (n1+n2)/n1 + (n1+n2)/n2 ))); + *stddev = std::sqrt(((1.0 / sigmafact) - ((n1 + n2) / n1 + (n1 + n2) / n2))); } - -static void calc_bar(barres_t *br, double tol, - int npee_min, int npee_max, gmx_bool *bEE, - double *partsum) +static void calc_bar(barres_t* br, double tol, int npee_min, int npee_max, gmx_bool* bEE, double* partsum) { - int npee, p; - double dg_sig2, sa_sig2, sb_sig2, stddev_sig2; /* intermediate variance values - for calculated quantities */ + int npee, p; + double dg_sig2, sa_sig2, sb_sig2, stddev_sig2; /* intermediate variance values + for calculated quantities */ double temp = br->a->temp; int i; double dg_min, dg_max; @@ -2065,7 +2046,7 @@ static void calc_bar(barres_t *br, double tol, dg_min = calc_bar_lowlevel(br->a, br->b, temp, tol, -1); dg_max = calc_bar_lowlevel(br->a, br->b, temp, tol, 1); - if (std::abs(dg_max - dg_min) > GMX_REAL_EPS*10) + if (std::abs(dg_max - dg_min) > GMX_REAL_EPS * 10) { /* the histogram range error is the biggest of the differences between the best estimate and the extremes */ @@ -2089,7 +2070,7 @@ static void calc_bar(barres_t *br, double tol, } calc_rel_entropy(br->a, br->b, temp, br->dg, &(br->sa), &(br->sb)); - calc_dg_stddev(br->a, br->b, temp, br->dg, &(br->dg_stddev) ); + calc_dg_stddev(br->a, br->b, temp, br->dg, &(br->dg_stddev)); dg_sig2 = 0; sa_sig2 = 0; @@ -2101,10 +2082,8 @@ static void calc_bar(barres_t *br, double tol, sample_coll_t ca, cb; /* initialize the samples */ - sample_coll_init(&ca, br->a->native_lambda, br->a->foreign_lambda, - br->a->temp); - sample_coll_init(&cb, br->b->native_lambda, br->b->foreign_lambda, - br->b->temp); + sample_coll_init(&ca, br->a->native_lambda, br->a->foreign_lambda, br->a->temp); + sample_coll_init(&cb, br->b->native_lambda, br->b->foreign_lambda, br->b->temp); for (npee = npee_min; npee <= npee_max; npee++) { @@ -2130,7 +2109,8 @@ static void calc_bar(barres_t *br, double tol, if (!cac || !cbc) { - printf("WARNING: histogram number incompatible with block number for averaging: can't do error estimate\n"); + printf("WARNING: histogram number incompatible with block number for " + "averaging: can't do error estimate\n"); *bEE = FALSE; if (cac) { @@ -2143,49 +2123,49 @@ static void calc_bar(barres_t *br, double tol, return; } - dgp = calc_bar_lowlevel(&ca, &cb, temp, tol, 0); - dgs += dgp; - dgs2 += dgp*dgp; + dgp = calc_bar_lowlevel(&ca, &cb, temp, tol, 0); + dgs += dgp; + dgs2 += dgp * dgp; - partsum[npee*(npee_max+1)+p] += dgp; + partsum[npee * (npee_max + 1) + p] += dgp; calc_rel_entropy(&ca, &cb, temp, dgp, &sac, &sbc); - dsa += sac; - dsa2 += sac*sac; - dsb += sbc; - dsb2 += sbc*sbc; - calc_dg_stddev(&ca, &cb, temp, dgp, &stddevc ); + dsa += sac; + dsa2 += sac * sac; + dsb += sbc; + dsb2 += sbc * sbc; + calc_dg_stddev(&ca, &cb, temp, dgp, &stddevc); - dstddev += stddevc; - dstddev2 += stddevc*stddevc; + dstddev += stddevc; + dstddev2 += stddevc * stddevc; sample_coll_destroy(&ca); sample_coll_destroy(&cb); } - dgs /= npee; - dgs2 /= npee; - dg_sig2 += (dgs2-dgs*dgs)/(npee-1); + dgs /= npee; + dgs2 /= npee; + dg_sig2 += (dgs2 - dgs * dgs) / (npee - 1); - dsa /= npee; - dsa2 /= npee; - dsb /= npee; - dsb2 /= npee; - sa_sig2 += (dsa2-dsa*dsa)/(npee-1); - sb_sig2 += (dsb2-dsb*dsb)/(npee-1); + dsa /= npee; + dsa2 /= npee; + dsb /= npee; + dsb2 /= npee; + sa_sig2 += (dsa2 - dsa * dsa) / (npee - 1); + sb_sig2 += (dsb2 - dsb * dsb) / (npee - 1); - dstddev /= npee; - dstddev2 /= npee; - stddev_sig2 += (dstddev2-dstddev*dstddev)/(npee-1); + dstddev /= npee; + dstddev2 /= npee; + stddev_sig2 += (dstddev2 - dstddev * dstddev) / (npee - 1); } - br->dg_err = std::sqrt(dg_sig2/(npee_max - npee_min + 1)); - br->sa_err = std::sqrt(sa_sig2/(npee_max - npee_min + 1)); - br->sb_err = std::sqrt(sb_sig2/(npee_max - npee_min + 1)); - br->dg_stddev_err = std::sqrt(stddev_sig2/(npee_max - npee_min + 1)); + br->dg_err = std::sqrt(dg_sig2 / (npee_max - npee_min + 1)); + br->sa_err = std::sqrt(sa_sig2 / (npee_max - npee_min + 1)); + br->sb_err = std::sqrt(sb_sig2 / (npee_max - npee_min + 1)); + br->dg_stddev_err = std::sqrt(stddev_sig2 / (npee_max - npee_min + 1)); } } -static double bar_err(int nbmin, int nbmax, const double *partsum) +static double bar_err(int nbmin, int nbmax, const double* partsum) { int nb, b; double svar, s, s2, dg; @@ -2197,16 +2177,16 @@ static double bar_err(int nbmin, int nbmax, const double *partsum) s2 = 0; for (b = 0; b < nb; b++) { - dg = partsum[nb*(nbmax+1)+b]; - s += dg; - s2 += dg*dg; + dg = partsum[nb * (nbmax + 1) + b]; + s += dg; + s2 += dg * dg; } - s /= nb; - s2 /= nb; - svar += (s2 - s*s)/(nb - 1); + s /= nb; + s2 /= nb; + svar += (s2 - s * s) / (nb - 1); } - return std::sqrt(svar/(nbmax + 1 - nbmin)); + return std::sqrt(svar / (nbmax + 1 - nbmin)); } @@ -2215,7 +2195,7 @@ static double bar_err(int nbmin, int nbmax, const double *partsum) first non-space value found after that. Returns NULL if the string ends before that. */ -static const char *find_value(const char *str) +static const char* find_value(const char* str) { gmx_bool name_end_found = FALSE; @@ -2229,14 +2209,14 @@ static const char *find_value(const char *str) /* first find the end of the name */ if (!name_end_found) { - if (std::isspace(*str) || (*str == '=') ) + if (std::isspace(*str) || (*str == '=')) { name_end_found = TRUE; } } else { - if (!( std::isspace(*str) || (*str == '=') )) + if (!(std::isspace(*str) || (*str == '='))) { return str; } @@ -2248,23 +2228,23 @@ static const char *find_value(const char *str) /* read a vector-notation description of a lambda vector */ -static gmx_bool read_lambda_compvec(const char *str, - lambda_vec_t *lv, - const lambda_components_t *lc_in, - lambda_components_t *lc_out, - const char **end, - const char *fn) -{ - gmx_bool initialize_lc = FALSE; /* whether to initialize the lambda - components, or to check them */ - gmx_bool start_reached = FALSE; /* whether the start of component names - has been reached */ - gmx_bool vector = FALSE; /* whether there are multiple components */ - int n = 0; /* current component number */ - const char *val_start = nullptr; /* start of the component name, or NULL - if not in a value */ - char *strtod_end; - gmx_bool OK = TRUE; +static gmx_bool read_lambda_compvec(const char* str, + lambda_vec_t* lv, + const lambda_components_t* lc_in, + lambda_components_t* lc_out, + const char** end, + const char* fn) +{ + gmx_bool initialize_lc = FALSE; /* whether to initialize the lambda + components, or to check them */ + gmx_bool start_reached = FALSE; /* whether the start of component names + has been reached */ + gmx_bool vector = FALSE; /* whether there are multiple components */ + int n = 0; /* current component number */ + const char* val_start = nullptr; /* start of the component name, or NULL + if not in a value */ + char* strtod_end; + gmx_bool OK = TRUE; if (end) { @@ -2313,13 +2293,11 @@ static gmx_bool read_lambda_compvec(const char *str, { if (initialize_lc) { - lambda_components_add(lc_out, val_start, - (str-val_start)); + lambda_components_add(lc_out, val_start, (str - val_start)); } else { - if (!lambda_components_check(lc_out, n, val_start, - (str-val_start))) + if (!lambda_components_check(lc_out, n, val_start, (str - val_start))) { return FALSE; } @@ -2331,8 +2309,7 @@ static gmx_bool read_lambda_compvec(const char *str, lv->val[n] = strtod(val_start, &strtod_end); if (val_start == strtod_end) { - gmx_fatal(FARGS, - "Error reading lambda vector in %s", fn); + gmx_fatal(FARGS, "Error reading lambda vector in %s", fn); } } /* reset for the next identifier */ @@ -2372,11 +2349,9 @@ static gmx_bool read_lambda_compvec(const char *str, } else { - gmx_fatal(FARGS, "Incomplete lambda vector data in %s", - fn); + gmx_fatal(FARGS, "Incomplete lambda vector data in %s", fn); return FALSE; } - } } } @@ -2399,25 +2374,18 @@ static gmx_bool read_lambda_compvec(const char *str, } /* read and check the component names from a string */ -static gmx_bool read_lambda_components(const char *str, - lambda_components_t *lc, - const char **end, - const char *fn) +static gmx_bool read_lambda_components(const char* str, lambda_components_t* lc, const char** end, const char* fn) { return read_lambda_compvec(str, nullptr, nullptr, lc, end, fn); } /* read an initialized lambda vector from a string */ -static gmx_bool read_lambda_vector(const char *str, - lambda_vec_t *lv, - const char **end, - const char *fn) +static gmx_bool read_lambda_vector(const char* str, lambda_vec_t* lv, const char** end, const char* fn) { return read_lambda_compvec(str, lv, lv->lc, nullptr, end, fn); } - /* deduce lambda value from legend. fn = the file name legend = the legend string @@ -2425,14 +2393,12 @@ static gmx_bool read_lambda_vector(const char *str, lam = the initialized lambda vector returns whether to use the data in this set. */ -static gmx_bool legend2lambda(const char *fn, - const char *legend, - lambda_vec_t *lam) +static gmx_bool legend2lambda(const char* fn, const char* legend, lambda_vec_t* lam) { - const char *ptr = nullptr, *ptr2 = nullptr; - gmx_bool ok = FALSE; - gmx_bool bdhdl = FALSE; - const char *tostr = " to "; + const char *ptr = nullptr, *ptr2 = nullptr; + gmx_bool ok = FALSE; + gmx_bool bdhdl = FALSE; + const char* tostr = " to "; if (legend == nullptr) { @@ -2449,12 +2415,11 @@ static gmx_bool legend2lambda(const char *fn, ptr = ptr2; ptr2++; } - } - while (ptr2 != nullptr && *ptr2 != '\0'); + } while (ptr2 != nullptr && *ptr2 != '\0'); if (ptr) { - ptr += std::strlen(tostr)-1; /* and advance past that 'to' */ + ptr += std::strlen(tostr) - 1; /* and advance past that 'to' */ } else { @@ -2501,7 +2466,7 @@ static gmx_bool legend2lambda(const char *fn, else { int dhdl_index; - const char *end; + const char* end; ptr = std::strrchr(legend, '='); end = ptr; @@ -2532,24 +2497,20 @@ static gmx_bool legend2lambda(const char *fn, } } ptr++; - dhdl_index = lambda_components_find(lam->lc, ptr, (end-ptr)); + dhdl_index = lambda_components_find(lam->lc, ptr, (end - ptr)); if (dhdl_index < 0) { char buf[STRLEN]; - std::strncpy(buf, ptr, (end-ptr)); - buf[(end-ptr)] = '\0'; - gmx_fatal(FARGS, - "Did not find lambda component for '%s' in %s", - buf, fn); + std::strncpy(buf, ptr, (end - ptr)); + buf[(end - ptr)] = '\0'; + gmx_fatal(FARGS, "Did not find lambda component for '%s' in %s", buf, fn); } } else { if (lam->lc->N > 1) { - gmx_fatal(FARGS, - "dhdl without component name with >1 lambda component in %s", - fn); + gmx_fatal(FARGS, "dhdl without component name with >1 lambda component in %s", fn); } dhdl_index = 0; } @@ -2558,12 +2519,11 @@ static gmx_bool legend2lambda(const char *fn, return TRUE; } -static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn, - lambda_components_t *lc) +static gmx_bool subtitle2lambda(const char* subtitle, xvg_t* ba, const char* fn, lambda_components_t* lc) { gmx_bool bFound; - const char *ptr; - char *end; + const char* ptr; + char* end; double native_lambda; bFound = FALSE; @@ -2573,7 +2533,7 @@ static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn, if (ptr) { int index = -1; - const char *val_end; + const char* val_end; /* the new 4.6 style lambda vectors */ ptr = find_value(ptr); @@ -2598,17 +2558,14 @@ static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn, ptr++; if (*ptr == '\0') { - gmx_fatal(FARGS, - "Incomplete lambda vector component data in %s", fn); + gmx_fatal(FARGS, "Incomplete lambda vector component data in %s", fn); return FALSE; } } val_end = ptr; if (!read_lambda_components(ptr, lc, &val_end, fn)) { - gmx_fatal(FARGS, - "lambda vector components in %s don't match those previously read", - fn); + gmx_fatal(FARGS, "lambda vector components in %s don't match those previously read", fn); } ptr = find_value(val_end); if (!ptr) @@ -2645,15 +2602,14 @@ static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn, } if (ptr != nullptr) { - bFound = (sscanf(ptr+1, "%lf", &(native_lambda)) == 1); + bFound = (sscanf(ptr + 1, "%lf", &(native_lambda)) == 1); /* add the lambda component name as an empty string */ if (lc->N > 0) { if (!lambda_components_check(lc, 0, "", 0)) { gmx_fatal(FARGS, - "lambda vector components in %s don't match those previously read", - fn); + "lambda vector components in %s don't match those previously read", fn); } } else @@ -2668,14 +2624,13 @@ static gmx_bool subtitle2lambda(const char *subtitle, xvg_t *ba, const char *fn, return bFound; } -static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, - lambda_components_t *lc) +static void read_bar_xvg_lowlevel(const char* fn, const real* temp, xvg_t* ba, lambda_components_t* lc) { - int i; - char *subtitle, **legend, *ptr; - int np; - gmx_bool native_lambda_read = FALSE; - char buf[STRLEN]; + int i; + char * subtitle, **legend, *ptr; + int np; + gmx_bool native_lambda_read = FALSE; + char buf[STRLEN]; xvg_init(ba); @@ -2687,10 +2642,10 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, gmx_fatal(FARGS, "File %s contains no usable data.", fn); } /* Reorder the data */ - ba->t = ba->y[0]; + ba->t = ba->y[0]; for (i = 1; i < ba->nset; i++) { - ba->y[i-1] = ba->y[i]; + ba->y[i - 1] = ba->y[i]; } ba->nset--; @@ -2712,8 +2667,7 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, { if (ba->temp <= 0) { - gmx_fatal(FARGS, "Found temperature of %f in file '%s'", - ba->temp, fn); + gmx_fatal(FARGS, "Found temperature of %f in file '%s'", ba->temp, fn); } } } @@ -2722,7 +2676,10 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, { if (*temp <= 0) { - gmx_fatal(FARGS, "Did not find a temperature in the subtitle in file '%s', use the -temp option of [TT]gmx bar[tt]", fn); + gmx_fatal(FARGS, + "Did not find a temperature in the subtitle in file '%s', use the -temp " + "option of [TT]gmx bar[tt]", + fn); } ba->temp = *temp; } @@ -2745,16 +2702,19 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, } else { - gmx_fatal(FARGS, "File %s contains multiple sets but no legends, can not determine the lambda values", fn); + gmx_fatal(FARGS, + "File %s contains multiple sets but no legends, can not determine the lambda " + "values", + fn); } } else { - for (i = 0; i < ba->nset; ) + for (i = 0; i < ba->nset;) { /* Read lambda from the legend */ - lambda_vec_init( &(ba->lambda[i]), lc ); - lambda_vec_copy( &(ba->lambda[i]), &(ba->native_lambda)); + lambda_vec_init(&(ba->lambda[i]), lc); + lambda_vec_copy(&(ba->lambda[i]), &(ba->native_lambda)); gmx_bool use = legend2lambda(fn, legend[i], &(ba->lambda[i])); if (use) { @@ -2765,10 +2725,10 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, { int j; printf("%s: Ignoring set '%s'.\n", fn, legend[i]); - for (j = i+1; j < ba->nset; j++) + for (j = i + 1; j < ba->nset; j++) { - ba->y[j-1] = ba->y[j]; - legend[j-1] = legend[j]; + ba->y[j - 1] = ba->y[j]; + legend[j - 1] = legend[j]; } ba->nset--; } @@ -2782,7 +2742,7 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, if (legend != nullptr) { - for (i = 0; i < ba->nset-1; i++) + for (i = 0; i < ba->nset - 1; i++) { sfree(legend[i]); } @@ -2790,10 +2750,10 @@ static void read_bar_xvg_lowlevel(const char *fn, const real *temp, xvg_t *ba, } } -static void read_bar_xvg(const char *fn, real *temp, sim_data_t *sd) +static void read_bar_xvg(const char* fn, real* temp, sim_data_t* sd) { - xvg_t *barsim; - samples_t *s; + xvg_t* barsim; + samples_t* s; int i; snew(barsim, 1); @@ -2805,7 +2765,7 @@ static void read_bar_xvg(const char *fn, real *temp, sim_data_t *sd) gmx_fatal(FARGS, "File '%s' contains fewer than two columns", fn); } - if (!gmx_within_tol(*temp, barsim->temp, GMX_FLOAT_EPS) && (*temp > 0) ) + if (!gmx_within_tol(*temp, barsim->temp, GMX_FLOAT_EPS) && (*temp > 0)) { gmx_fatal(FARGS, "Temperature in file %s different from earlier files or setting\n", fn); } @@ -2815,22 +2775,20 @@ static void read_bar_xvg(const char *fn, real *temp, sim_data_t *sd) snew(s, barsim->nset); for (i = 0; i < barsim->nset; i++) { - samples_init(s+i, &(barsim->native_lambda), &(barsim->lambda[i]), - barsim->temp, lambda_vec_same(&(barsim->native_lambda), - &(barsim->lambda[i])), - fn); + samples_init(s + i, &(barsim->native_lambda), &(barsim->lambda[i]), barsim->temp, + lambda_vec_same(&(barsim->native_lambda), &(barsim->lambda[i])), fn); s[i].du = barsim->y[i]; s[i].ndu = barsim->np[i]; s[i].t = barsim->t; - lambda_data_list_insert_sample(sd->lb, s+i); + lambda_data_list_insert_sample(sd->lb, s + i); } { char buf[STRLEN]; lambda_vec_print(s[0].native_lambda, buf, FALSE); - printf("%s: %.1f - %.1f; lambda = %s\n dH/dl & foreign lambdas:\n", - fn, s[0].t[0], s[0].t[s[0].ndu-1], buf); + printf("%s: %.1f - %.1f; lambda = %s\n dH/dl & foreign lambdas:\n", fn, s[0].t[0], + s[0].t[s[0].ndu - 1], buf); for (i = 0; i < barsim->nset; i++) { lambda_vec_print(s[i].foreign_lambda, buf, TRUE); @@ -2840,31 +2798,28 @@ static void read_bar_xvg(const char *fn, real *temp, sim_data_t *sd) printf("\n\n"); } -static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk, - double start_time, double delta_time, - lambda_vec_t *native_lambda, double temp, - double *last_t, const char *filename) +static void read_edr_rawdh_block(samples_t** smp, + int* ndu, + t_enxblock* blk, + double start_time, + double delta_time, + lambda_vec_t* native_lambda, + double temp, + double* last_t, + const char* filename) { int i, j; - lambda_vec_t *foreign_lambda; + lambda_vec_t* foreign_lambda; int type; - samples_t *s; /* convenience pointer */ + samples_t* s; /* convenience pointer */ int startj; /* check the block types etc. */ - if ( (blk->nsub < 3) || - (blk->sub[0].type != xdr_datatype_int) || - (blk->sub[1].type != xdr_datatype_double) || - ( - (blk->sub[2].type != xdr_datatype_float) && - (blk->sub[2].type != xdr_datatype_double) - ) || - (blk->sub[0].nr < 1) || - (blk->sub[1].nr < 1) ) + if ((blk->nsub < 3) || (blk->sub[0].type != xdr_datatype_int) || (blk->sub[1].type != xdr_datatype_double) + || ((blk->sub[2].type != xdr_datatype_float) && (blk->sub[2].type != xdr_datatype_double)) + || (blk->sub[0].nr < 1) || (blk->sub[1].nr < 1)) { - gmx_fatal(FARGS, - "Unexpected/corrupted block data in file %s around time %f.", - filename, start_time); + gmx_fatal(FARGS, "Unexpected/corrupted block data in file %s around time %f.", filename, start_time); } snew(foreign_lambda, 1); @@ -2894,8 +2849,7 @@ static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk, { /* initialize the samples structure if it's empty. */ snew(*smp, 1); - samples_init(*smp, native_lambda, foreign_lambda, temp, - type == dhbtDHDL, filename); + samples_init(*smp, native_lambda, foreign_lambda, temp, type == dhbtDHDL, filename); (*smp)->start_time = start_time; (*smp)->delta_time = delta_time; } @@ -2904,81 +2858,77 @@ static void read_edr_rawdh_block(samples_t **smp, int *ndu, t_enxblock *blk, s = *smp; /* now double check */ - if (!lambda_vec_same(s->foreign_lambda, foreign_lambda) ) + if (!lambda_vec_same(s->foreign_lambda, foreign_lambda)) { char buf[STRLEN], buf2[STRLEN]; lambda_vec_print(foreign_lambda, buf, FALSE); lambda_vec_print(s->foreign_lambda, buf2, FALSE); fprintf(stderr, "Got foreign lambda=%s, expected: %s\n", buf, buf2); - gmx_fatal(FARGS, "Corrupted data in file %s around t=%f.", - filename, start_time); + gmx_fatal(FARGS, "Corrupted data in file %s around t=%f.", filename, start_time); } /* make room for the data */ if (gmx::index(s->ndu_alloc) < s->ndu + blk->sub[2].nr) { - s->ndu_alloc += (s->ndu_alloc < static_cast(blk->sub[2].nr)) ? - blk->sub[2].nr*2 : s->ndu_alloc; + s->ndu_alloc += (s->ndu_alloc < static_cast(blk->sub[2].nr)) ? blk->sub[2].nr * 2 + : s->ndu_alloc; srenew(s->du_alloc, s->ndu_alloc); s->du = s->du_alloc; } - startj = s->ndu; - s->ndu += blk->sub[2].nr; + startj = s->ndu; + s->ndu += blk->sub[2].nr; s->ntot += blk->sub[2].nr; - *ndu = blk->sub[2].nr; + *ndu = blk->sub[2].nr; /* and copy the data*/ for (j = 0; j < blk->sub[2].nr; j++) { if (blk->sub[2].type == xdr_datatype_float) { - s->du[startj+j] = blk->sub[2].fval[j]; + s->du[startj + j] = blk->sub[2].fval[j]; } else { - s->du[startj+j] = blk->sub[2].dval[j]; + s->du[startj + j] = blk->sub[2].dval[j]; } } - if (start_time + blk->sub[2].nr*delta_time > *last_t) + if (start_time + blk->sub[2].nr * delta_time > *last_t) { - *last_t = start_time + blk->sub[2].nr*delta_time; + *last_t = start_time + blk->sub[2].nr * delta_time; } } -static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, - double start_time, double delta_time, - lambda_vec_t *native_lambda, double temp, - double *last_t, const char *filename) +static samples_t* read_edr_hist_block(int* nsamples, + t_enxblock* blk, + double start_time, + double delta_time, + lambda_vec_t* native_lambda, + double temp, + double* last_t, + const char* filename) { int i, j; - samples_t *s; + samples_t* s; int nhist; - lambda_vec_t *foreign_lambda; + lambda_vec_t* foreign_lambda; int type; int nbins[2]; /* check the block types etc. */ - if ( (blk->nsub < 2) || - (blk->sub[0].type != xdr_datatype_double) || - (blk->sub[1].type != xdr_datatype_int64) || - (blk->sub[0].nr < 2) || - (blk->sub[1].nr < 2) ) + if ((blk->nsub < 2) || (blk->sub[0].type != xdr_datatype_double) + || (blk->sub[1].type != xdr_datatype_int64) || (blk->sub[0].nr < 2) || (blk->sub[1].nr < 2)) { - gmx_fatal(FARGS, - "Unexpected/corrupted block data in file %s around time %f", - filename, start_time); + gmx_fatal(FARGS, "Unexpected/corrupted block data in file %s around time %f", filename, start_time); } - nhist = blk->nsub-2; + nhist = blk->nsub - 2; if (nhist == 0) { return nullptr; } if (nhist > 2) { - gmx_fatal(FARGS, - "Unexpected/corrupted block data in file %s around time %f", - filename, start_time); + gmx_fatal(FARGS, "Unexpected/corrupted block data in file %s around time %f", filename, start_time); } snew(s, 1); @@ -2998,16 +2948,14 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, foreign_lambda->val[0] = old_foreign_lambda; if (foreign_lambda->lc->N > 1) { - gmx_fatal(FARGS, - "Single-component lambda in multi-component file %s", - filename); + gmx_fatal(FARGS, "Single-component lambda in multi-component file %s", filename); } } else { for (i = 0; i < native_lambda->lc->N; i++) { - foreign_lambda->val[i] = blk->sub[0].dval[i+2]; + foreign_lambda->val[i] = blk->sub[0].dval[i + 2]; } } } @@ -3017,9 +2965,7 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, { if (blk->sub[1].nr < 3 + nhist) { - gmx_fatal(FARGS, - "Missing derivative coord in multi-component file %s", - filename); + gmx_fatal(FARGS, "Missing derivative coord in multi-component file %s", filename); } foreign_lambda->dhdl = blk->sub[1].lval[2 + nhist]; } @@ -3029,20 +2975,19 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, } } - samples_init(s, native_lambda, foreign_lambda, temp, type == dhbtDHDL, - filename); + samples_init(s, native_lambda, foreign_lambda, temp, type == dhbtDHDL, filename); snew(s->hist, 1); for (i = 0; i < nhist; i++) { - nbins[i] = blk->sub[i+2].nr; + nbins[i] = blk->sub[i + 2].nr; } hist_init(s->hist, nhist, nbins); for (i = 0; i < nhist; i++) { - s->hist->x0[i] = blk->sub[1].lval[2+i]; + s->hist->x0[i] = blk->sub[1].lval[2 + i]; s->hist->dx[i] = blk->sub[0].dval[1]; if (i == 1) { @@ -3057,15 +3002,14 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, for (i = 0; i < nhist; i++) { - int64_t sum = 0; + int64_t sum = 0; for (j = 0; j < s->hist->nbin[i]; j++) { - int binv = static_cast(blk->sub[i+2].ival[j]); + int binv = static_cast(blk->sub[i + 2].ival[j]); s->hist->bin[i][j] = binv; - sum += binv; - + sum += binv; } if (i == 0) { @@ -3076,34 +3020,33 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk, { if (s->ntot != sum) { - gmx_fatal(FARGS, "Histogram counts don't match in %s", - filename); + gmx_fatal(FARGS, "Histogram counts don't match in %s", filename); } } } - if (start_time + s->hist->sum*delta_time > *last_t) + if (start_time + s->hist->sum * delta_time > *last_t) { - *last_t = start_time + s->hist->sum*delta_time; + *last_t = start_time + s->hist->sum * delta_time; } return s; } -static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) +static void read_barsim_edr(const char* fn, real* temp, sim_data_t* sd) { int i, j; ener_file_t fp; - t_enxframe *fr; + t_enxframe* fr; int nre; - gmx_enxnm_t *enm = nullptr; + gmx_enxnm_t* enm = nullptr; double first_t = -1; double last_t = -1; - samples_t **samples_rawdh = nullptr; /* contains samples for raw delta_h */ - int *nhists = nullptr; /* array to keep count & print at end */ - int *npts = nullptr; /* array to keep count & print at end */ - lambda_vec_t **lambdas = nullptr; /* array to keep count & print at end */ - lambda_vec_t *native_lambda; + samples_t** samples_rawdh = nullptr; /* contains samples for raw delta_h */ + int* nhists = nullptr; /* array to keep count & print at end */ + int* npts = nullptr; /* array to keep count & print at end */ + lambda_vec_t** lambdas = nullptr; /* array to keep count & print at end */ + lambda_vec_t* native_lambda; int nsamples = 0; lambda_vec_t start_lambda; @@ -3118,13 +3061,13 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) while (do_enx(fp, fr)) { /* count the data blocks */ - int nblocks_raw = 0; - int nblocks_hist = 0; - int nlam = 0; - int k; + int nblocks_raw = 0; + int nblocks_hist = 0; + int nlam = 0; + int k; /* DHCOLL block information: */ double start_time = 0, delta_time = 0, old_start_lambda = 0, delta_lambda = 0; - double rtemp = 0; + double rtemp = 0; /* count the blocks and handle collection information: */ for (i = 0; i < fr->nblock; i++) @@ -3140,9 +3083,8 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) if (fr->block[i].id == enxDHCOLL) { nlam++; - if ( (fr->block[i].nsub < 1) || - (fr->block[i].sub[0].type != xdr_datatype_double) || - (fr->block[i].sub[0].nr < 5)) + if ((fr->block[i].nsub < 1) || (fr->block[i].sub[0].type != xdr_datatype_double) + || (fr->block[i].sub[0].nr < 5)) { gmx_fatal(FARGS, "Unexpected block data in file %s", fn); } @@ -3158,9 +3100,10 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) { gmx_fatal(FARGS, "Lambda values not constant in %s: can't apply BAR method", fn); } - if ( ( *temp != rtemp) && (*temp > 0) ) + if ((*temp != rtemp) && (*temp > 0)) { - gmx_fatal(FARGS, "Temperature in file %s different from earlier files or setting\n", fn); + gmx_fatal(FARGS, + "Temperature in file %s different from earlier files or setting\n", fn); } *temp = rtemp; @@ -3171,7 +3114,8 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) if (!lambda_components_check(&(sd->lc), 0, "", 0)) { gmx_fatal(FARGS, - "lambda vector components in %s don't match those previously read", + "lambda vector components in %s don't match those previously " + "read", fn); } } @@ -3192,32 +3136,27 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) gmx_bool check = (sd->lc.N > 0); if (fr->block[i].nsub < 2) { - gmx_fatal(FARGS, - "No lambda vector, but start_lambda=%f\n", - old_start_lambda); + gmx_fatal(FARGS, "No lambda vector, but start_lambda=%f\n", old_start_lambda); } n_lambda_vec = fr->block[i].sub[1].ival[1]; for (j = 0; j < n_lambda_vec; j++) { - const char *name = - efpt_singular_names[fr->block[i].sub[1].ival[1+j]]; + const char* name = efpt_singular_names[fr->block[i].sub[1].ival[1 + j]]; if (check) { /* check the components */ - lambda_components_check(&(sd->lc), j, name, - std::strlen(name)); + lambda_components_check(&(sd->lc), j, name, std::strlen(name)); } else { - lambda_components_add(&(sd->lc), name, - std::strlen(name)); + lambda_components_add(&(sd->lc), name, std::strlen(name)); } } lambda_vec_init(&start_lambda, &(sd->lc)); start_lambda.index = fr->block[i].sub[1].ival[0]; for (j = 0; j < n_lambda_vec; j++) { - start_lambda.val[j] = fr->block[i].sub[0].dval[5+j]; + start_lambda.val[j] = fr->block[i].sub[0].dval[5 + j]; } } if (first_t < 0) @@ -3243,7 +3182,7 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) /*native_lambda=start_lambda;*/ lambda_vec_init(native_lambda, &(sd->lc)); lambda_vec_copy(native_lambda, &start_lambda); - nsamples = nblocks_raw+nblocks_hist; + nsamples = nblocks_raw + nblocks_hist; snew(nhists, nsamples); snew(npts, nsamples); snew(lambdas, nsamples); @@ -3262,20 +3201,22 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) // nsamples > 0 means this is NOT the first iteration /* check the native lambda */ - if (!lambda_vec_same(&start_lambda, native_lambda) ) + if (!lambda_vec_same(&start_lambda, native_lambda)) { - gmx_fatal(FARGS, "Native lambda not constant in file %s: started at %f, and becomes %f at time %f", + gmx_fatal(FARGS, + "Native lambda not constant in file %s: started at %f, and becomes %f at " + "time %f", fn, native_lambda->val[0], start_lambda.val[0], start_time); } /* check the number of samples against the previous number */ - if ( ((nblocks_raw+nblocks_hist) != nsamples) || (nlam != 1 ) ) + if (((nblocks_raw + nblocks_hist) != nsamples) || (nlam != 1)) { - gmx_fatal(FARGS, "Unexpected block count in %s: was %d, now %d\n", - fn, nsamples+1, nblocks_raw+nblocks_hist+nlam); + gmx_fatal(FARGS, "Unexpected block count in %s: was %d, now %d\n", fn, nsamples + 1, + nblocks_raw + nblocks_hist + nlam); } /* check whether last iterations's end time matches with the currrent start time */ - if ( (std::abs(last_t - start_time) > 2*delta_time) && last_t >= 0) + if ((std::abs(last_t - start_time) > 2 * delta_time) && last_t >= 0) { /* it didn't. We need to store our samples and reallocate */ for (i = 0; i < nsamples; i++) @@ -3283,8 +3224,7 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) if (samples_rawdh[i]) { /* insert it into the existing list */ - lambda_data_list_insert_sample(sd->lb, - samples_rawdh[i]); + lambda_data_list_insert_sample(sd->lb, samples_rawdh[i]); /* and make sure we'll allocate a new one this time around */ samples_rawdh[i] = nullptr; @@ -3303,12 +3243,8 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) if (type == dhbtDH || type == dhbtDHDL) { int ndu; - read_edr_rawdh_block(&(samples_rawdh[k]), - &ndu, - &(fr->block[i]), - start_time, delta_time, - native_lambda, rtemp, - &last_t, fn); + read_edr_rawdh_block(&(samples_rawdh[k]), &ndu, &(fr->block[i]), start_time, + delta_time, native_lambda, rtemp, &last_t, fn); npts[k] += ndu; if (samples_rawdh[k]) { @@ -3324,11 +3260,9 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) { int j; int nb = 0; - samples_t *s; /* this is where the data will go */ - s = read_edr_hist_block(&nb, &(fr->block[i]), - start_time, delta_time, - native_lambda, rtemp, - &last_t, fn); + samples_t* s; /* this is where the data will go */ + s = read_edr_hist_block(&nb, &(fr->block[i]), start_time, delta_time, + native_lambda, rtemp, &last_t, fn); nhists[k] += nb; if (nb > 0) { @@ -3338,7 +3272,7 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) /* and insert the new sample immediately */ for (j = 0; j < nb; j++) { - lambda_data_list_insert_sample(sd->lb, s+j); + lambda_data_list_insert_sample(sd->lb, s + j); } } } @@ -3359,8 +3293,7 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) char buf[STRLEN]; printf("\n"); lambda_vec_print(native_lambda, buf, FALSE); - printf("%s: %.1f - %.1f; lambda = %s\n foreign lambdas:\n", - fn, first_t, last_t, buf); + printf("%s: %.1f - %.1f; lambda = %s\n foreign lambdas:\n", fn, first_t, last_t, buf); for (i = 0; i < nsamples; i++) { if (lambdas[i]) @@ -3384,9 +3317,9 @@ static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd) } -int gmx_bar(int argc, char *argv[]) +int gmx_bar(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] calculates free energy difference estimates through ", "Bennett's acceptance ratio method (BAR). It also automatically", "adds series of individual free energies obtained with BAR into", @@ -3431,7 +3364,8 @@ int gmx_bar(int argc, char *argv[]) "These can contain either lists of energy differences (see the ", "[REF].mdp[ref] option [TT]separate_dhdl_file[tt]), or a series of ", "histograms (see the [REF].mdp[ref] options [TT]dh_hist_size[tt] and ", - "[TT]dh_hist_spacing[tt]).", "The temperature and [GRK]lambda[grk] ", + "[TT]dh_hist_spacing[tt]).", + "The temperature and [GRK]lambda[grk] ", "values are automatically deduced from the [TT]ener.edr[tt] file.[PAR]", "In addition to the [REF].mdp[ref] option [TT]foreign_lambda[tt], ", @@ -3490,57 +3424,58 @@ int gmx_bar(int argc, char *argv[]) "[TT]-oh[tt] option to write series of histograms, together with the ", "[TT]-nbin[tt] option.[PAR]" }; - static real begin = 0, end = -1, temp = -1; - int nd = 2, nbmin = 5, nbmax = 5; - int nbin = 100; - gmx_bool use_dhdl = FALSE; - t_pargs pa[] = { - { "-b", FALSE, etREAL, {&begin}, "Begin time for BAR" }, - { "-e", FALSE, etREAL, {&end}, "End time for BAR" }, - { "-temp", FALSE, etREAL, {&temp}, "Temperature (K)" }, - { "-prec", FALSE, etINT, {&nd}, "The number of digits after the decimal point" }, - { "-nbmin", FALSE, etINT, {&nbmin}, "Minimum number of blocks for error estimation" }, - { "-nbmax", FALSE, etINT, {&nbmax}, "Maximum number of blocks for error estimation" }, - { "-nbin", FALSE, etINT, {&nbin}, "Number of bins for histogram output"}, - { "-extp", FALSE, etBOOL, {&use_dhdl}, "Whether to linearly extrapolate dH/dl values to use as energies"} + static real begin = 0, end = -1, temp = -1; + int nd = 2, nbmin = 5, nbmax = 5; + int nbin = 100; + gmx_bool use_dhdl = FALSE; + t_pargs pa[] = { + { "-b", FALSE, etREAL, { &begin }, "Begin time for BAR" }, + { "-e", FALSE, etREAL, { &end }, "End time for BAR" }, + { "-temp", FALSE, etREAL, { &temp }, "Temperature (K)" }, + { "-prec", FALSE, etINT, { &nd }, "The number of digits after the decimal point" }, + { "-nbmin", FALSE, etINT, { &nbmin }, "Minimum number of blocks for error estimation" }, + { "-nbmax", FALSE, etINT, { &nbmax }, "Maximum number of blocks for error estimation" }, + { "-nbin", FALSE, etINT, { &nbin }, "Number of bins for histogram output" }, + { "-extp", + FALSE, + etBOOL, + { &use_dhdl }, + "Whether to linearly extrapolate dH/dl values to use as energies" } }; - t_filenm fnm[] = { - { efXVG, "-f", "dhdl", ffOPTRDMULT }, - { efEDR, "-g", "ener", ffOPTRDMULT }, - { efXVG, "-o", "bar", ffOPTWR }, - { efXVG, "-oi", "barint", ffOPTWR }, - { efXVG, "-oh", "histogram", ffOPTWR } - }; + t_filenm fnm[] = { { efXVG, "-f", "dhdl", ffOPTRDMULT }, + { efEDR, "-g", "ener", ffOPTRDMULT }, + { efXVG, "-o", "bar", ffOPTWR }, + { efXVG, "-oi", "barint", ffOPTWR }, + { efXVG, "-oh", "histogram", ffOPTWR } }; #define NFILE asize(fnm) - int f; - int nf = 0; /* file counter */ - int nfile_tot; /* total number of input files */ - sim_data_t sim_data; /* the simulation data */ - barres_t *results; /* the results */ - int nresults; /* number of results in results array */ + int f; + int nf = 0; /* file counter */ + int nfile_tot; /* total number of input files */ + sim_data_t sim_data; /* the simulation data */ + barres_t* results; /* the results */ + int nresults; /* number of results in results array */ - double *partsum; + double* partsum; double prec, dg_tot; - FILE *fpb, *fpi; + FILE * fpb, *fpi; char dgformat[20], xvg2format[STRLEN], xvg3format[STRLEN]; char buf[STRLEN], buf2[STRLEN]; char ktformat[STRLEN], sktformat[STRLEN]; char kteformat[STRLEN], skteformat[STRLEN]; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; double kT; gmx_bool result_OK = TRUE, bEE = TRUE; - gmx_bool disc_err = FALSE; - double sum_disc_err = 0.; /* discretization error */ - gmx_bool histrange_err = FALSE; - double sum_histrange_err = 0.; /* histogram range error */ - double stat_err = 0.; /* statistical error */ + gmx_bool disc_err = FALSE; + double sum_disc_err = 0.; /* discretization error */ + gmx_bool histrange_err = FALSE; + double sum_histrange_err = 0.; /* histogram range error */ + double stat_err = 0.; /* statistical error */ - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } @@ -3571,19 +3506,20 @@ int gmx_bar(int argc, char *argv[]) } prec = std::pow(10.0, static_cast(-nd)); - snew(partsum, (nbmax+1)*(nbmax+1)); + snew(partsum, (nbmax + 1) * (nbmax + 1)); nf = 0; /* read in all files. First xvg files */ - for (const std::string &filenm : xvgFiles) + for (const std::string& filenm : xvgFiles) { read_bar_xvg(filenm.c_str(), &temp, &sim_data); nf++; } /* then .edr files */ - for (const std::string &filenm : edrFiles) + for (const std::string& filenm : edrFiles) { - read_barsim_edr(filenm.c_str(), &temp, &sim_data);; + read_barsim_edr(filenm.c_str(), &temp, &sim_data); + nf++; } @@ -3610,41 +3546,40 @@ int gmx_bar(int argc, char *argv[]) { prec = sum_disc_err; nd = static_cast(std::ceil(-std::log10(prec))); - printf("WARNING: setting the precision to %g because that is the minimum\n reasonable number, given the expected discretization error.\n", prec); + printf("WARNING: setting the precision to %g because that is the minimum\n " + "reasonable number, given the expected discretization error.\n", + prec); } /*sprintf(lamformat,"%%6.3f");*/ - sprintf( dgformat, "%%%d.%df", 3+nd, nd); + sprintf(dgformat, "%%%d.%df", 3 + nd, nd); /* the format strings of the results in kT */ - sprintf( ktformat, "%%%d.%df", 5+nd, nd); - sprintf( sktformat, "%%%ds", 6+nd); + sprintf(ktformat, "%%%d.%df", 5 + nd, nd); + sprintf(sktformat, "%%%ds", 6 + nd); /* the format strings of the errors in kT */ - sprintf( kteformat, "%%%d.%df", 3+nd, nd); - sprintf( skteformat, "%%%ds", 4+nd); + sprintf(kteformat, "%%%d.%df", 3 + nd, nd); + sprintf(skteformat, "%%%ds", 4 + nd); sprintf(xvg2format, "%s %s\n", "%s", dgformat); sprintf(xvg3format, "%s %s %s\n", "%s", dgformat, dgformat); - fpb = nullptr; if (opt2bSet("-o", NFILE, fnm)) { sprintf(buf, "%s (%s)", "\\DeltaG", "kT"); - fpb = xvgropen_type(opt2fn("-o", NFILE, fnm), "Free energy differences", - "\\lambda", buf, exvggtXYDY, oenv); + fpb = xvgropen_type(opt2fn("-o", NFILE, fnm), "Free energy differences", "\\lambda", buf, + exvggtXYDY, oenv); } fpi = nullptr; if (opt2bSet("-oi", NFILE, fnm)) { sprintf(buf, "%s (%s)", "\\DeltaG", "kT"); - fpi = xvgropen(opt2fn("-oi", NFILE, fnm), "Free energy integral", - "\\lambda", buf, oenv); + fpi = xvgropen(opt2fn("-oi", NFILE, fnm), "Free energy integral", "\\lambda", buf, oenv); } - if (nbmin > nbmax) { nbmin = nbmax; @@ -3658,28 +3593,27 @@ int gmx_bar(int argc, char *argv[]) /* Determine the free energy difference with a factor of 10 * more accuracy than requested for printing. */ - calc_bar(&(results[f]), 0.1*prec, nbmin, nbmax, - &bEE, partsum); + calc_bar(&(results[f]), 0.1 * prec, nbmin, nbmax, &bEE, partsum); - if (results[f].dg_disc_err > prec/10.) + if (results[f].dg_disc_err > prec / 10.) { disc_err = TRUE; } - if (results[f].dg_histrange_err > prec/10.) + if (results[f].dg_histrange_err > prec / 10.) { histrange_err = TRUE; } } /* print results in kT */ - kT = BOLTZ*temp; + kT = BOLTZ * temp; printf("\nTemperature: %g K\n", temp); printf("\nDetailed results in kT (see help for explanation):\n\n"); printf("%6s ", " lam_A"); printf("%6s ", " lam_B"); - printf(sktformat, "DG "); + printf(sktformat, "DG "); if (bEE) { printf(skteformat, "+/- "); @@ -3692,17 +3626,17 @@ int gmx_bar(int argc, char *argv[]) { printf(skteformat, "range "); } - printf(sktformat, "s_A "); + printf(sktformat, "s_A "); if (bEE) { - printf(skteformat, "+/- " ); + printf(skteformat, "+/- "); } - printf(sktformat, "s_B "); + printf(sktformat, "s_B "); if (bEE) { - printf(skteformat, "+/- " ); + printf(skteformat, "+/- "); } - printf(sktformat, "stdev "); + printf(sktformat, "stdev "); if (bEE) { printf(skteformat, "+/- "); @@ -3714,7 +3648,7 @@ int gmx_bar(int argc, char *argv[]) printf("%s ", buf); lambda_vec_print_short(results[f].b->native_lambda, buf); printf("%s ", buf); - printf(ktformat, results[f].dg); + printf(ktformat, results[f].dg); printf(" "); if (bEE) { @@ -3731,21 +3665,21 @@ int gmx_bar(int argc, char *argv[]) printf(kteformat, results[f].dg_histrange_err); printf(" "); } - printf(ktformat, results[f].sa); + printf(ktformat, results[f].sa); printf(" "); if (bEE) { printf(kteformat, results[f].sa_err); printf(" "); } - printf(ktformat, results[f].sb); + printf(ktformat, results[f].sb); printf(" "); if (bEE) { printf(kteformat, results[f].sb_err); printf(" "); } - printf(ktformat, results[f].dg_stddev); + printf(ktformat, results[f].dg_stddev); printf(" "); if (bEE) { @@ -3754,8 +3688,7 @@ int gmx_bar(int argc, char *argv[]) printf("\n"); /* Check for negative relative entropy with a 95% certainty. */ - if (results[f].sa < -2*results[f].sa_err || - results[f].sb < -2*results[f].sb_err) + if (results[f].sa < -2 * results[f].sa_err || results[f].sb < -2 * results[f].sb_err) { result_OK = FALSE; } @@ -3773,7 +3706,7 @@ int gmx_bar(int argc, char *argv[]) /* final results in kJ/mol */ printf("\n\nFinal results in kJ/mol:\n\n"); - dg_tot = 0; + dg_tot = 0; for (f = 0; f < nresults; f++) { @@ -3786,9 +3719,7 @@ int gmx_bar(int argc, char *argv[]) if (fpb != nullptr) { - lambda_vec_print_intermediate(results[f].a->native_lambda, - results[f].b->native_lambda, - buf); + lambda_vec_print_intermediate(results[f].a->native_lambda, results[f].b->native_lambda, buf); fprintf(fpb, xvg3format, buf, results[f].dg, results[f].dg_err); } @@ -3799,18 +3730,18 @@ int gmx_bar(int argc, char *argv[]) printf("%s - %s", buf, buf2); printf(", DG "); - printf(dgformat, results[f].dg*kT); + printf(dgformat, results[f].dg * kT); if (bEE) { printf(" +/- "); - printf(dgformat, results[f].dg_err*kT); + printf(dgformat, results[f].dg_err * kT); } if (histrange_err) { printf(" (max. range err. = "); - printf(dgformat, results[f].dg_histrange_err*kT); + printf(dgformat, results[f].dg_histrange_err * kT); printf(")"); - sum_histrange_err += results[f].dg_histrange_err*kT; + sum_histrange_err += results[f].dg_histrange_err * kT; } printf("\n"); @@ -3819,14 +3750,14 @@ int gmx_bar(int argc, char *argv[]) printf("\n"); printf("total "); lambda_vec_print_short(results[0].a->native_lambda, buf); - lambda_vec_print_short(results[nresults-1].b->native_lambda, buf2); + lambda_vec_print_short(results[nresults - 1].b->native_lambda, buf2); printf("%s - %s", buf, buf2); printf(", DG "); - printf(dgformat, dg_tot*kT); + printf(dgformat, dg_tot * kT); if (bEE) { - stat_err = bar_err(nbmin, nbmax, partsum)*kT; + stat_err = bar_err(nbmin, nbmax, partsum) * kT; printf(" +/- "); printf(dgformat, std::max(std::max(stat_err, sum_disc_err), sum_histrange_err)); } @@ -3837,7 +3768,9 @@ int gmx_bar(int argc, char *argv[]) printf(dgformat, sum_disc_err); if (bEE && stat_err < sum_disc_err) { - printf("WARNING: discretization error (%g) is larger than statistical error.\n Decrease histogram spacing for more accurate results\n", stat_err); + printf("WARNING: discretization error (%g) is larger than statistical error.\n " + "Decrease histogram spacing for more accurate results\n", + stat_err); } } if (histrange_err) @@ -3846,16 +3779,17 @@ int gmx_bar(int argc, char *argv[]) printf(dgformat, sum_histrange_err); if (bEE && stat_err < sum_histrange_err) { - printf("WARNING: histogram range error (%g) is larger than statistical error.\n Increase histogram range for more accurate results\n", stat_err); + printf("WARNING: histogram range error (%g) is larger than statistical error.\n " + "Increase histogram range for more accurate results\n", + stat_err); } - } printf("\n"); if (fpi != nullptr) { - lambda_vec_print_short(results[nresults-1].b->native_lambda, buf); + lambda_vec_print_short(results[nresults - 1].b->native_lambda, buf); fprintf(fpi, xvg2format, buf, dg_tot); xvgrclose(fpi); } diff --git a/src/gromacs/gmxana/gmx_bundle.cpp b/src/gromacs/gmxana/gmx_bundle.cpp index 3ce667d7b6..df5a6c4d3f 100644 --- a/src/gromacs/gmxana/gmx_bundle.cpp +++ b/src/gromacs/gmxana/gmx_bundle.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,16 +58,17 @@ #define MAX_ENDS 3 -typedef struct { +typedef struct +{ int n; int nend; - rvec *end[MAX_ENDS]; - rvec *mid; - rvec *dir; - real *len; + rvec* end[MAX_ENDS]; + rvec* mid; + rvec* dir; + real* len; } t_bundle; -static void rotate_ends(t_bundle *bun, rvec axis, int c0, int c1) +static void rotate_ends(t_bundle* bun, rvec axis, int c0, int c1) { int end, i; rvec ax, tmp; @@ -78,17 +79,16 @@ static void rotate_ends(t_bundle *bun, rvec axis, int c0, int c1) for (i = 0; i < bun->n; i++) { copy_rvec(bun->end[end][i], tmp); - bun->end[end][i][c0] = ax[c1]*tmp[c0] - ax[c0]*tmp[c1]; - bun->end[end][i][c1] = ax[c0]*tmp[c0] + ax[c1]*tmp[c1]; + bun->end[end][i][c0] = ax[c1] * tmp[c0] - ax[c0] * tmp[c1]; + bun->end[end][i][c1] = ax[c0] * tmp[c0] + ax[c1] * tmp[c1]; } } copy_rvec(axis, tmp); - axis[c0] = ax[c1]*tmp[c0] - ax[c0]*tmp[c1]; - axis[c1] = ax[c0]*tmp[c0] + ax[c1]*tmp[c1]; + axis[c0] = ax[c1] * tmp[c0] - ax[c0] * tmp[c1]; + axis[c1] = ax[c0] * tmp[c0] + ax[c1] * tmp[c1]; } -static void calc_axes(rvec x[], t_atom atom[], const int gnx[], int *index[], - gmx_bool bRot, t_bundle *bun) +static void calc_axes(rvec x[], t_atom atom[], const int gnx[], int* index[], gmx_bool bRot, t_bundle* bun) { int end, i, div, d; real *mtot, m; @@ -106,23 +106,23 @@ static void calc_axes(rvec x[], t_atom atom[], const int gnx[], int *index[], clear_rvec(bun->end[end][i]); mtot[i] = 0; } - div = gnx[end]/bun->n; + div = gnx[end] / bun->n; for (i = 0; i < gnx[end]; i++) { m = atom[index[end][i]].m; for (d = 0; d < DIM; d++) { - bun->end[end][i/div][d] += m*x[index[end][i]][d]; + bun->end[end][i / div][d] += m * x[index[end][i]][d]; } - mtot[i/div] += m; + mtot[i / div] += m; } clear_rvec(axis[end]); for (i = 0; i < bun->n; i++) { - svmul(1.0/mtot[i], bun->end[end][i], bun->end[end][i]); + svmul(1.0 / mtot[i], bun->end[end][i], bun->end[end][i]); rvec_inc(axis[end], bun->end[end][i]); } - svmul(1.0/bun->n, axis[end], axis[end]); + svmul(1.0 / bun->n, axis[end], axis[end]); } sfree(mtot); @@ -153,11 +153,10 @@ static void calc_axes(rvec x[], t_atom atom[], const int gnx[], int *index[], } } -static void dump_axes(t_trxstatus *status, t_trxframe *fr, t_atoms *outat, - t_bundle *bun) +static void dump_axes(t_trxstatus* status, t_trxframe* fr, t_atoms* outat, t_bundle* bun) { t_trxframe frout; - static rvec *xout = nullptr; + static rvec* xout = nullptr; int i; GMX_ASSERT(outat->nr >= bun->n, ""); @@ -168,16 +167,16 @@ static void dump_axes(t_trxstatus *status, t_trxframe *fr, t_atoms *outat, for (i = 0; i < bun->n; i++) { - copy_rvec(bun->end[0][i], xout[3*i]); + copy_rvec(bun->end[0][i], xout[3 * i]); if (bun->nend >= 3) { - copy_rvec(bun->end[2][i], xout[3*i+1]); + copy_rvec(bun->end[2][i], xout[3 * i + 1]); } else { - copy_rvec(bun->mid[i], xout[3*i+1]); + copy_rvec(bun->mid[i], xout[3 * i + 1]); } - copy_rvec(bun->end[1][i], xout[3*i+2]); + copy_rvec(bun->end[1][i], xout[3 * i + 2]); } frout = *fr; frout.bV = FALSE; @@ -190,9 +189,9 @@ static void dump_axes(t_trxstatus *status, t_trxframe *fr, t_atoms *outat, write_trxframe(status, &frout, nullptr); } -int gmx_bundle(int argc, char *argv[]) +int gmx_bundle(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] analyzes bundles of axes. The axes can be for instance", "helix axes. The program reads two index groups and divides both", "of them in [TT]-na[tt] parts. The centers of mass of these parts", @@ -215,64 +214,57 @@ int gmx_bundle(int argc, char *argv[]) "command line option [TT]-nmrpdb[tt], and type [TT]set axis true[tt] to", "display the reference axis." }; - static int n = 0; - static gmx_bool bZ = FALSE; - t_pargs pa[] = { - { "-na", FALSE, etINT, {&n}, - "Number of axes" }, - { "-z", FALSE, etBOOL, {&bZ}, - "Use the [IT]z[it]-axis as reference instead of the average axis" } - }; - FILE *flen, *fdist, *fz, *ftilt, *ftiltr, *ftiltl; - FILE *fkink = nullptr, *fkinkr = nullptr, *fkinkl = nullptr; - t_trxstatus *status; - t_trxstatus *fpdb; - t_topology top; - int ePBC; - rvec *xtop; - matrix box; - t_trxframe fr; - t_atoms outatoms; - real t, comp; - char *grpname[MAX_ENDS]; + static int n = 0; + static gmx_bool bZ = FALSE; + t_pargs pa[] = { { "-na", FALSE, etINT, { &n }, "Number of axes" }, + { "-z", + FALSE, + etBOOL, + { &bZ }, + "Use the [IT]z[it]-axis as reference instead of the average axis" } }; + FILE * flen, *fdist, *fz, *ftilt, *ftiltr, *ftiltl; + FILE * fkink = nullptr, *fkinkr = nullptr, *fkinkl = nullptr; + t_trxstatus* status; + t_trxstatus* fpdb; + t_topology top; + int ePBC; + rvec* xtop; + matrix box; + t_trxframe fr; + t_atoms outatoms; + real t, comp; + char* grpname[MAX_ENDS]; /* FIXME: The constness should not be cast away */ - char *anm = const_cast("CA"), *rnm = const_cast("GLY"); + char * anm = const_cast("CA"), *rnm = const_cast("GLY"); int i, gnx[MAX_ENDS]; - int *index[MAX_ENDS]; + int* index[MAX_ENDS]; t_bundle bun; gmx_bool bKink; rvec va, vb, vc, vr, vl; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; #define NLEG asize(leg) t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-ol", "bun_len", ffWRITE }, - { efXVG, "-od", "bun_dist", ffWRITE }, - { efXVG, "-oz", "bun_z", ffWRITE }, - { efXVG, "-ot", "bun_tilt", ffWRITE }, - { efXVG, "-otr", "bun_tiltr", ffWRITE }, - { efXVG, "-otl", "bun_tiltl", ffWRITE }, - { efXVG, "-ok", "bun_kink", ffOPTWR }, - { efXVG, "-okr", "bun_kinkr", ffOPTWR }, - { efXVG, "-okl", "bun_kinkl", ffOPTWR }, + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-ol", "bun_len", ffWRITE }, + { efXVG, "-od", "bun_dist", ffWRITE }, { efXVG, "-oz", "bun_z", ffWRITE }, + { efXVG, "-ot", "bun_tilt", ffWRITE }, { efXVG, "-otr", "bun_tiltr", ffWRITE }, + { efXVG, "-otl", "bun_tiltl", ffWRITE }, { efXVG, "-ok", "bun_kink", ffOPTWR }, + { efXVG, "-okr", "bun_kinkr", ffOPTWR }, { efXVG, "-okl", "bun_kinkl", ffOPTWR }, { efPDB, "-oa", "axes", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, box, TRUE); - bKink = opt2bSet("-ok", NFILE, fnm) || opt2bSet("-okr", NFILE, fnm) - || opt2bSet("-okl", NFILE, fnm); + bKink = opt2bSet("-ok", NFILE, fnm) || opt2bSet("-okr", NFILE, fnm) || opt2bSet("-okl", NFILE, fnm); if (bKink) { bun.nend = 3; @@ -288,13 +280,11 @@ int gmx_bundle(int argc, char *argv[]) fprintf(stderr, "and a group of kink "); } fprintf(stderr, "atoms\n"); - get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bun.nend, - gnx, index, grpname); + get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bun.nend, gnx, index, grpname); if (n <= 0 || gnx[0] % n || gnx[1] % n || (bKink && gnx[2] % n)) { - gmx_fatal(FARGS, - "The size of one of your index groups is not a multiple of n"); + gmx_fatal(FARGS, "The size of one of your index groups is not a multiple of n"); } bun.n = n; snew(bun.end[0], n); @@ -307,14 +297,14 @@ int gmx_bundle(int argc, char *argv[]) snew(bun.dir, n); snew(bun.len, n); - flen = xvgropen(opt2fn("-ol", NFILE, fnm), "Axis lengths", - output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); + flen = xvgropen(opt2fn("-ol", NFILE, fnm), "Axis lengths", output_env_get_xvgr_tlabel(oenv), + "(nm)", oenv); fdist = xvgropen(opt2fn("-od", NFILE, fnm), "Distance of axis centers", - output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); + output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); fz = xvgropen(opt2fn("-oz", NFILE, fnm), "Z-shift of axis centers", - output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); - ftilt = xvgropen(opt2fn("-ot", NFILE, fnm), "Axis tilts", - output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv); + output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); + ftilt = xvgropen(opt2fn("-ot", NFILE, fnm), "Axis tilts", output_env_get_xvgr_tlabel(oenv), + "(degrees)", oenv); ftiltr = xvgropen(opt2fn("-otr", NFILE, fnm), "Radial axis tilts", output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv); ftiltl = xvgropen(opt2fn("-otl", NFILE, fnm), "Lateral axis tilts", @@ -322,8 +312,8 @@ int gmx_bundle(int argc, char *argv[]) if (bKink) { - fkink = xvgropen(opt2fn("-ok", NFILE, fnm), "Kink angles", - output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv); + fkink = xvgropen(opt2fn("-ok", NFILE, fnm), "Kink angles", output_env_get_xvgr_tlabel(oenv), + "(degrees)", oenv); fkinkr = xvgropen(opt2fn("-okr", NFILE, fnm), "Radial kink angles", output_env_get_xvgr_tlabel(oenv), "(degrees)", oenv); if (output_env_get_print_xvgr_codes(oenv)) @@ -336,15 +326,15 @@ int gmx_bundle(int argc, char *argv[]) if (opt2bSet("-oa", NFILE, fnm)) { - init_t_atoms(&outatoms, 3*n, FALSE); - outatoms.nr = 3*n; - for (i = 0; i < 3*n; i++) + init_t_atoms(&outatoms, 3 * n, FALSE); + outatoms.nr = 3 * n; + for (i = 0; i < 3 * n; i++) { - outatoms.atomname[i] = &anm; - outatoms.atom[i].resind = i/3; - outatoms.resinfo[i/3].name = &rnm; - outatoms.resinfo[i/3].nr = i/3 + 1; - outatoms.resinfo[i/3].ic = ' '; + outatoms.atomname[i] = &anm; + outatoms.atom[i].resind = i / 3; + outatoms.resinfo[i / 3].name = &rnm; + outatoms.resinfo[i / 3].nr = i / 3 + 1; + outatoms.resinfo[i / 3].ic = ' '; } fpdb = open_trx(opt2fn("-oa", NFILE, fnm), "w"); } @@ -379,29 +369,27 @@ int gmx_bundle(int argc, char *argv[]) fprintf(flen, " %6g", bun.len[i]); fprintf(fdist, " %6g", norm(bun.mid[i])); fprintf(fz, " %6g", bun.mid[i][ZZ]); - fprintf(ftilt, " %6g", RAD2DEG*acos(bun.dir[i][ZZ])); - comp = bun.mid[i][XX]*bun.dir[i][XX]+bun.mid[i][YY]*bun.dir[i][YY]; - fprintf(ftiltr, " %6g", RAD2DEG* - std::asin(comp/std::hypot(comp, bun.dir[i][ZZ]))); - comp = bun.mid[i][YY]*bun.dir[i][XX]-bun.mid[i][XX]*bun.dir[i][YY]; - fprintf(ftiltl, " %6g", RAD2DEG* - std::asin(comp/std::hypot(comp, bun.dir[i][ZZ]))); + fprintf(ftilt, " %6g", RAD2DEG * acos(bun.dir[i][ZZ])); + comp = bun.mid[i][XX] * bun.dir[i][XX] + bun.mid[i][YY] * bun.dir[i][YY]; + fprintf(ftiltr, " %6g", RAD2DEG * std::asin(comp / std::hypot(comp, bun.dir[i][ZZ]))); + comp = bun.mid[i][YY] * bun.dir[i][XX] - bun.mid[i][XX] * bun.dir[i][YY]; + fprintf(ftiltl, " %6g", RAD2DEG * std::asin(comp / std::hypot(comp, bun.dir[i][ZZ]))); if (bKink) { rvec_sub(bun.end[0][i], bun.end[2][i], va); rvec_sub(bun.end[2][i], bun.end[1][i], vb); unitv(va, va); unitv(vb, vb); - fprintf(fkink, " %6g", RAD2DEG*acos(iprod(va, vb))); + fprintf(fkink, " %6g", RAD2DEG * acos(iprod(va, vb))); cprod(va, vb, vc); copy_rvec(bun.mid[i], vr); vr[ZZ] = 0; unitv(vr, vr); - fprintf(fkinkr, " %6g", RAD2DEG*std::asin(iprod(vc, vr))); + fprintf(fkinkr, " %6g", RAD2DEG * std::asin(iprod(vc, vr))); vl[XX] = vr[YY]; vl[YY] = -vr[XX]; vl[ZZ] = 0; - fprintf(fkinkl, " %6g", RAD2DEG*std::asin(iprod(vc, vl))); + fprintf(fkinkl, " %6g", RAD2DEG * std::asin(iprod(vc, vl))); } } fprintf(flen, "\n"); @@ -420,8 +408,7 @@ int gmx_bundle(int argc, char *argv[]) { dump_axes(fpdb, &fr, &outatoms, &bun); } - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); gmx_rmpbc_done(gpbc); close_trx(status); diff --git a/src/gromacs/gmxana/gmx_chi.cpp b/src/gromacs/gmxana/gmx_chi.cpp index bda1e768f9..f14961a2b8 100644 --- a/src/gromacs/gmxana/gmx_chi.cpp +++ b/src/gromacs/gmxana/gmx_chi.cpp @@ -65,73 +65,71 @@ static gmx_bool bAllowed(real phi, real psi) { - static const char *map[] = { - "1100000000000000001111111000000000001111111111111111111111111", - "1100000000000000001111110000000000011111111111111111111111111", - "1100000000000000001111110000000000011111111111111111111111111", - "1100000000000000001111100000000000111111111111111111111111111", - "1100000000000000001111100000000000111111111111111111111111111", - "1100000000000000001111100000000001111111111111111111111111111", - "1100000000000000001111100000000001111111111111111111111111111", - "1100000000000000001111100000000011111111111111111111111111111", - "1110000000000000001111110000000111111111111111111111111111111", - "1110000000000000001111110000001111111111111111111111111111111", - "1110000000000000001111111000011111111111111111111111111111111", - "1110000000000000001111111100111111111111111111111111111111111", - "1110000000000000001111111111111111111111111111111111111111111", - "1110000000000000001111111111111111111111111111111111111111111", - "1110000000000000001111111111111111111111111111111111111111111", - "1110000000000000001111111111111111111111111111111111111111111", - "1110000000000000001111111111111110011111111111111111111111111", - "1110000000000000001111111111111100000111111111111111111111111", - "1110000000000000001111111111111000000000001111111111111111111", - "1100000000000000001111111111110000000000000011111111111111111", - "1100000000000000001111111111100000000000000011111111111111111", - "1000000000000000001111111111000000000000000001111111111111110", - "0000000000000000001111111110000000000000000000111111111111100", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000111111111111000000000000000", - "1100000000000000000000000000000001111111111111100000000000111", - "1100000000000000000000000000000001111111111111110000000000111", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000" - }; + static const char* map[] = { "1100000000000000001111111000000000001111111111111111111111111", + "1100000000000000001111110000000000011111111111111111111111111", + "1100000000000000001111110000000000011111111111111111111111111", + "1100000000000000001111100000000000111111111111111111111111111", + "1100000000000000001111100000000000111111111111111111111111111", + "1100000000000000001111100000000001111111111111111111111111111", + "1100000000000000001111100000000001111111111111111111111111111", + "1100000000000000001111100000000011111111111111111111111111111", + "1110000000000000001111110000000111111111111111111111111111111", + "1110000000000000001111110000001111111111111111111111111111111", + "1110000000000000001111111000011111111111111111111111111111111", + "1110000000000000001111111100111111111111111111111111111111111", + "1110000000000000001111111111111111111111111111111111111111111", + "1110000000000000001111111111111111111111111111111111111111111", + "1110000000000000001111111111111111111111111111111111111111111", + "1110000000000000001111111111111111111111111111111111111111111", + "1110000000000000001111111111111110011111111111111111111111111", + "1110000000000000001111111111111100000111111111111111111111111", + "1110000000000000001111111111111000000000001111111111111111111", + "1100000000000000001111111111110000000000000011111111111111111", + "1100000000000000001111111111100000000000000011111111111111111", + "1000000000000000001111111111000000000000000001111111111111110", + "0000000000000000001111111110000000000000000000111111111111100", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000111111111111000000000000000", + "1100000000000000000000000000000001111111111111100000000000111", + "1100000000000000000000000000000001111111111111110000000000111", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000" }; #define NPP asize(map) - int x, y; + int x, y; -#define INDEX(ppp) (((static_cast (360+(ppp)*RAD2DEG)) % 360)/6) +#define INDEX(ppp) (((static_cast(360 + (ppp)*RAD2DEG)) % 360) / 6) x = INDEX(phi); y = INDEX(psi); #undef INDEX @@ -139,19 +137,19 @@ static gmx_bool bAllowed(real phi, real psi) return map[x][y] == '1'; } -static int *make_chi_ind(int nl, t_dlist dl[], int *ndih) +static int* make_chi_ind(int nl, t_dlist dl[], int* ndih) { - int *id; - int i, Xi, n; + int* id; + int i, Xi, n; /* There are nl residues with max edMax dihedrals with 4 atoms each */ - snew(id, nl*edMax*4); + snew(id, nl * edMax * 4); n = 0; for (i = 0; (i < nl); i++) { /* Phi, fake the first one */ - dl[i].j0[edPhi] = n/4; + dl[i].j0[edPhi] = n / 4; if (dl[i].atm.minC >= 0) { id[n++] = dl[i].atm.minC; @@ -167,13 +165,13 @@ static int *make_chi_ind(int nl, t_dlist dl[], int *ndih) for (i = 0; (i < nl); i++) { /* Psi, fake the last one */ - dl[i].j0[edPsi] = n/4; + dl[i].j0[edPsi] = n / 4; id[n++] = dl[i].atm.N; id[n++] = dl[i].atm.Cn[1]; id[n++] = dl[i].atm.C; - if (i < (nl-1) ) + if (i < (nl - 1)) { - id[n++] = dl[i+1].atm.N; + id[n++] = dl[i + 1].atm.N; } else { @@ -185,7 +183,7 @@ static int *make_chi_ind(int nl, t_dlist dl[], int *ndih) /* Omega */ if (has_dihedral(edOmega, &(dl[i]))) { - dl[i].j0[edOmega] = n/4; + dl[i].j0[edOmega] = n / 4; id[n++] = dl[i].atm.minCalpha; id[n++] = dl[i].atm.minC; id[n++] = dl[i].atm.N; @@ -197,39 +195,47 @@ static int *make_chi_ind(int nl, t_dlist dl[], int *ndih) /* Chi# */ for (i = 0; (i < nl); i++) { - if (dl[i].atm.Cn[Xi+3] != -1) + if (dl[i].atm.Cn[Xi + 3] != -1) { - dl[i].j0[edChi1+Xi] = n/4; - id[n++] = dl[i].atm.Cn[Xi]; - id[n++] = dl[i].atm.Cn[Xi+1]; - id[n++] = dl[i].atm.Cn[Xi+2]; - id[n++] = dl[i].atm.Cn[Xi+3]; + dl[i].j0[edChi1 + Xi] = n / 4; + id[n++] = dl[i].atm.Cn[Xi]; + id[n++] = dl[i].atm.Cn[Xi + 1]; + id[n++] = dl[i].atm.Cn[Xi + 2]; + id[n++] = dl[i].atm.Cn[Xi + 3]; } } } - *ndih = n/4; + *ndih = n / 4; return id; } -static void do_dihcorr(const char *fn, int nf, int ndih, real **dih, real dt, - int nlist, t_dlist dlist[], real time[], int maxchi, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega, - const gmx_output_env_t *oenv) +static void do_dihcorr(const char* fn, + int nf, + int ndih, + real** dih, + real dt, + int nlist, + t_dlist dlist[], + real time[], + int maxchi, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bOmega, + const gmx_output_env_t* oenv) { char name1[256], name2[256]; int i, j, Xi; - do_autocorr(fn, oenv, "Dihedral Autocorrelation Function", - nf, ndih, dih, dt, eacCos, FALSE); + do_autocorr(fn, oenv, "Dihedral Autocorrelation Function", nf, ndih, dih, dt, eacCos, FALSE); /* Dump em all */ j = 0; for (i = 0; (i < nlist); i++) { if (bPhi) { - print_one(oenv, "corrphi", dlist[i].name, "Phi ACF for", "C(t)", nf/2, time, - dih[j]); + print_one(oenv, "corrphi", dlist[i].name, "Phi ACF for", "C(t)", nf / 2, time, dih[j]); } j++; } @@ -237,8 +243,7 @@ static void do_dihcorr(const char *fn, int nf, int ndih, real **dih, real dt, { if (bPsi) { - print_one(oenv, "corrpsi", dlist[i].name, "Psi ACF for", "C(t)", nf/2, time, - dih[j]); + print_one(oenv, "corrpsi", dlist[i].name, "Psi ACF for", "C(t)", nf / 2, time, dih[j]); } j++; } @@ -248,23 +253,22 @@ static void do_dihcorr(const char *fn, int nf, int ndih, real **dih, real dt, { if (bOmega) { - print_one(oenv, "corromega", dlist[i].name, "Omega ACF for", "C(t)", - nf/2, time, dih[j]); + print_one(oenv, "corromega", dlist[i].name, "Omega ACF for", "C(t)", nf / 2, time, dih[j]); } j++; } } for (Xi = 0; (Xi < maxchi); Xi++) { - sprintf(name1, "corrchi%d", Xi+1); - sprintf(name2, "Chi%d ACF for", Xi+1); + sprintf(name1, "corrchi%d", Xi + 1); + sprintf(name2, "Chi%d ACF for", Xi + 1); for (i = 0; (i < nlist); i++) { - if (dlist[i].atm.Cn[Xi+3] != -1) + if (dlist[i].atm.Cn[Xi + 3] != -1) { if (bChi) { - print_one(oenv, name1, dlist[i].name, name2, "C(t)", nf/2, time, dih[j]); + print_one(oenv, name1, dlist[i].name, name2, "C(t)", nf / 2, time, dih[j]); } j++; } @@ -285,21 +289,29 @@ static void copy_dih_data(const real in[], real out[], int nf, gmx_bool bLEAVE) } else { - mult = (180.0/M_PI); + mult = (180.0 / M_PI); } for (i = 0; (i < nf); i++) { - out[i] = in[i]*mult; + out[i] = in[i] * mult; } } -static void dump_em_all(int nlist, t_dlist dlist[], int nf, real time[], - real **dih, int maxchi, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega, gmx_bool bRAD, - const gmx_output_env_t *oenv) +static void dump_em_all(int nlist, + t_dlist dlist[], + int nf, + real time[], + real** dih, + int maxchi, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bOmega, + gmx_bool bRAD, + const gmx_output_env_t* oenv) { char name[256], titlestr[256], ystr[256]; - real *data; + real* data; int i, j, Xi; snew(data, nf); @@ -350,12 +362,12 @@ static void dump_em_all(int nlist, t_dlist dlist[], int nf, real time[], { for (i = 0; (i < nlist); i++) { - if (dlist[i].atm.Cn[Xi+3] != -1) + if (dlist[i].atm.Cn[Xi + 3] != -1) { if (bChi) { - sprintf(name, "chi%d", Xi+1); - sprintf(titlestr, "\\xc\\f{}\\s%d\\N", Xi+1); + sprintf(name, "chi%d", Xi + 1); + sprintf(titlestr, "\\xc\\f{}\\s%d\\N", Xi + 1); copy_dih_data(dih[j], data, nf, bRAD); print_one(oenv, name, dlist[i].name, titlestr, ystr, nf, time, data); } @@ -375,19 +387,18 @@ static void reset_one(real dih[], int nf, real phase) dih[j] += phase; while (dih[j] < -M_PI) { - dih[j] += 2*M_PI; + dih[j] += 2 * M_PI; } while (dih[j] >= M_PI) { - dih[j] -= 2*M_PI; + dih[j] -= 2 * M_PI; } } } -static int reset_em_all(int nlist, t_dlist dlist[], int nf, - real **dih, int maxchi) +static int reset_em_all(int nlist, t_dlist dlist[], int nf, real** dih, int maxchi) { - int i, j, Xi; + int i, j, Xi; /* Reset em all */ j = 0; @@ -404,7 +415,7 @@ static int reset_em_all(int nlist, t_dlist dlist[], int nf, } } /* Psi */ - for (i = 0; (i < nlist-1); i++) + for (i = 0; (i < nlist - 1); i++) { reset_one(dih[j++], nf, 0); } @@ -424,7 +435,7 @@ static int reset_em_all(int nlist, t_dlist dlist[], int nf, { for (i = 0; (i < nlist); i++) { - if (dlist[i].atm.Cn[Xi+3] != -1) + if (dlist[i].atm.Cn[Xi + 3] != -1) { reset_one(dih[j], nf, 0); j++; @@ -435,55 +446,61 @@ static int reset_em_all(int nlist, t_dlist dlist[], int nf, return j; } -static void histogramming(FILE *log, int nbin, ResidueType *rt, - int nf, int maxchi, real **dih, - int nlist, t_dlist dlist[], - const int index[], - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bOmega, gmx_bool bChi, - gmx_bool bNormalize, gmx_bool bSSHisto, const char *ssdump, - real bfac_max, const t_atoms *atoms, - gmx_bool bDo_jc, const char *fn, - const gmx_output_env_t *oenv) +static void histogramming(FILE* log, + int nbin, + ResidueType* rt, + int nf, + int maxchi, + real** dih, + int nlist, + t_dlist dlist[], + const int index[], + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bOmega, + gmx_bool bChi, + gmx_bool bNormalize, + gmx_bool bSSHisto, + const char* ssdump, + real bfac_max, + const t_atoms* atoms, + gmx_bool bDo_jc, + const char* fn, + const gmx_output_env_t* oenv) { /* also gets 3J couplings and order parameters S2 */ // Avoid warnings about narrowing conversions from double to real #ifdef _MSC_VER -#pragma warning(disable: 4838) +# pragma warning(disable : 4838) #endif - t_karplus kkkphi[] = { - { "J_NHa1", 6.51, -1.76, 1.6, -M_PI/3, 0.0, 0.0 }, - { "J_NHa2", 6.51, -1.76, 1.6, M_PI/3, 0.0, 0.0 }, - { "J_HaC'", 4.0, 1.1, 0.1, 0.0, 0.0, 0.0 }, - { "J_NHCb", 4.7, -1.5, -0.2, M_PI/3, 0.0, 0.0 }, - { "J_Ci-1Hai", 4.5, -1.3, -1.2, 2*M_PI/3, 0.0, 0.0 } - }; - t_karplus kkkpsi[] = { - { "J_HaN", -0.88, -0.61, -0.27, M_PI/3, 0.0, 0.0 } - }; - t_karplus kkkchi1[] = { - { "JHaHb2", 9.5, -1.6, 1.8, -M_PI/3, 0, 0.0 }, - { "JHaHb3", 9.5, -1.6, 1.8, 0, 0, 0.0 } - }; + t_karplus kkkphi[] = { { "J_NHa1", 6.51, -1.76, 1.6, -M_PI / 3, 0.0, 0.0 }, + { "J_NHa2", 6.51, -1.76, 1.6, M_PI / 3, 0.0, 0.0 }, + { "J_HaC'", 4.0, 1.1, 0.1, 0.0, 0.0, 0.0 }, + { "J_NHCb", 4.7, -1.5, -0.2, M_PI / 3, 0.0, 0.0 }, + { "J_Ci-1Hai", 4.5, -1.3, -1.2, 2 * M_PI / 3, 0.0, 0.0 } }; + t_karplus kkkpsi[] = { { "J_HaN", -0.88, -0.61, -0.27, M_PI / 3, 0.0, 0.0 } }; + t_karplus kkkchi1[] = { { "JHaHb2", 9.5, -1.6, 1.8, -M_PI / 3, 0, 0.0 }, + { "JHaHb3", 9.5, -1.6, 1.8, 0, 0, 0.0 } }; #ifdef _MSC_VER -#pragma warning(default: 4838) +# pragma warning(default : 4838) #endif #define NKKKPHI asize(kkkphi) #define NKKKPSI asize(kkkpsi) #define NKKKCHI asize(kkkchi1) -#define NJC (NKKKPHI+NKKKPSI+NKKKCHI) +#define NJC (NKKKPHI + NKKKPSI + NKKKCHI) - FILE *fp, *ssfp[3] = {nullptr, nullptr, nullptr}; - const char *sss[3] = { "sheet", "helix", "coil" }; + FILE * fp, *ssfp[3] = { nullptr, nullptr, nullptr }; + const char* sss[3] = { "sheet", "helix", "coil" }; real S2; - real *normhisto; - real **Jc, **Jcsig; - int ****his_aa_ss = nullptr; - int ***his_aa, *histmp; + real* normhisto; + real ** Jc, **Jcsig; + int**** his_aa_ss = nullptr; + int *** his_aa, *histmp; int i, j, k, m, n, nn, Dih, nres, hindex, angle; gmx_bool bBfac, bOccup; char hisfile[256], hhisfile[256], title[256], *ss_str = nullptr; - char **leg; - const char *residue_name; + char** leg; + const char* residue_name; int rt_size; rt_size = rt->numberOfEntries(); @@ -495,7 +512,7 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, gmx_fatal(FARGS, "Error reading from file %s", ssdump); } - snew(ss_str, nres+1); + snew(ss_str, nres + 1); if (1 != fscanf(fp, "%s", ss_str)) { gmx_fatal(FARGS, "Error reading from file %s", ssdump); @@ -506,13 +523,13 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, snew(his_aa_ss, 3); for (i = 0; (i < 3); i++) { - snew(his_aa_ss[i], rt_size+1); + snew(his_aa_ss[i], rt_size + 1); for (j = 0; (j <= rt_size); j++) { snew(his_aa_ss[i][j], edMax); for (Dih = 0; (Dih < edMax); Dih++) { - snew(his_aa_ss[i][j][Dih], nbin+1); + snew(his_aa_ss[i][j][Dih], nbin + 1); } } } @@ -520,10 +537,10 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, snew(his_aa, edMax); for (Dih = 0; (Dih < edMax); Dih++) { - snew(his_aa[Dih], rt_size+1); + snew(his_aa[Dih], rt_size + 1); for (i = 0; (i <= rt_size); i++) { - snew(his_aa[Dih][i], nbin+1); + snew(his_aa[Dih][i], nbin + 1); } } snew(histmp, nbin); @@ -538,13 +555,12 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, j = 0; n = 0; - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { for (i = 0; (i < nlist); i++) { - if (((Dih < edOmega) ) || - ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) || - ((Dih > edOmega) && (dlist[i].atm.Cn[Dih-NONCHI+3] != -1))) + if (((Dih < edOmega)) || ((Dih == edOmega) && (has_dihedral(edOmega, &(dlist[i])))) + || ((Dih > edOmega) && (dlist[i].atm.Cn[Dih - NONCHI + 3] != -1))) { make_histo(log, nf, dih[j], nbin, histmp, -M_PI, M_PI); @@ -559,12 +575,12 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, bBfac = bOccup = TRUE; for (nn = 0; (nn < 4); nn++, n++) { - bBfac = bBfac && (atoms->pdbinfo[index[n]].bfac <= bfac_max); + bBfac = bBfac && (atoms->pdbinfo[index[n]].bfac <= bfac_max); bOccup = bOccup && (atoms->pdbinfo[index[n]].occup == 1); } if (bOccup && ((bfac_max <= 0) || bBfac)) { - hindex = static_cast(((dih[j][0]+M_PI)*nbin)/(2*M_PI)); + hindex = static_cast(((dih[j][0] + M_PI) * nbin) / (2 * M_PI)); range_check(hindex, 0, nbin); /* Assign dihedral to either of the structure determined @@ -572,15 +588,9 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, */ switch (ss_str[dlist[i].resnr]) { - case 'E': - his_aa_ss[0][dlist[i].index][Dih][hindex]++; - break; - case 'H': - his_aa_ss[1][dlist[i].index][Dih][hindex]++; - break; - default: - his_aa_ss[2][dlist[i].index][Dih][hindex]++; - break; + case 'E': his_aa_ss[0][dlist[i].index][Dih][hindex]++; break; + case 'H': his_aa_ss[1][dlist[i].index][Dih][hindex]++; break; + default: his_aa_ss[2][dlist[i].index][Dih][hindex]++; break; } } else if (debug) @@ -610,23 +620,23 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, for (m = 0; (m < NKKKPSI); m++) { - Jc[i][NKKKPHI+m] = kkkpsi[m].Jc; - Jcsig[i][NKKKPHI+m] = kkkpsi[m].Jcsig; + Jc[i][NKKKPHI + m] = kkkpsi[m].Jc; + Jcsig[i][NKKKPHI + m] = kkkpsi[m].Jcsig; } break; case edChi1: calc_distribution_props(nbin, histmp, -M_PI, NKKKCHI, kkkchi1, &S2); for (m = 0; (m < NKKKCHI); m++) { - Jc[i][NKKKPHI+NKKKPSI+m] = kkkchi1[m].Jc; - Jcsig[i][NKKKPHI+NKKKPSI+m] = kkkchi1[m].Jcsig; + Jc[i][NKKKPHI + NKKKPSI + m] = kkkchi1[m].Jc; + Jcsig[i][NKKKPHI + NKKKPSI + m] = kkkchi1[m].Jcsig; } break; default: /* covers edOmega and higher Chis than Chi1 */ calc_distribution_props(nbin, histmp, -M_PI, 0, nullptr, &S2); break; } - dlist[i].S2[Dih] = S2; + dlist[i].S2[Dih] = S2; /* Sum distribution per amino acid type as well */ for (k = 0; (k < nbin); k++) @@ -660,7 +670,7 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, fprintf(log, "%7s SD", kkkchi1[i].name); } fprintf(log, "\n"); - for (i = 0; (i < NJC+1); i++) + for (i = 0; (i < NJC + 1); i++) { fprintf(log, "------------"); } @@ -679,8 +689,7 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, /* and to -jc file... */ if (bDo_jc) { - fp = xvgropen(fn, "\\S3\\NJ-Couplings from Karplus Equation", "Residue", - "Coupling", oenv); + fp = xvgropen(fn, "\\S3\\NJ-Couplings from Karplus Equation", "Residue", "Coupling", oenv); snew(leg, NJC); for (i = 0; (i < NKKKPHI); i++) { @@ -688,11 +697,11 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, } for (i = 0; (i < NKKKPSI); i++) { - leg[i+NKKKPHI] = gmx_strdup(kkkpsi[i].name); + leg[i + NKKKPHI] = gmx_strdup(kkkpsi[i].name); } for (i = 0; (i < NKKKCHI); i++) { - leg[i+NKKKPHI+NKKKPSI] = gmx_strdup(kkkchi1[i].name); + leg[i + NKKKPHI + NKKKPSI] = gmx_strdup(kkkchi1[i].name); } xvgr_legend(fp, NJC, leg, oenv); fprintf(fp, "%5s ", "#Res."); @@ -731,15 +740,13 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, break; } } - if ((j < nbin) && - ((bPhi && (Dih == edPhi)) || - (bPsi && (Dih == edPsi)) || - (bOmega && (Dih == edOmega)) || - (bChi && (Dih >= edChi1)))) + if ((j < nbin) + && ((bPhi && (Dih == edPhi)) || (bPsi && (Dih == edPsi)) + || (bOmega && (Dih == edOmega)) || (bChi && (Dih >= edChi1)))) { if (bNormalize) { - normalize_histo(nbin, his_aa[Dih][i], (360.0/nbin), normhisto); + normalize_histo(nbin, his_aa[Dih][i], (360.0 / nbin), normhisto); } residue_name = rt->nameFromResidueIndex(i).c_str(); @@ -758,9 +765,9 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, sprintf(title, "\\xw\\f{} Distribution for %s", residue_name); break; default: - sprintf(hisfile, "histo-chi%d%s", Dih-NONCHI+1, residue_name); - sprintf(title, "\\xc\\f{}\\s%d\\N Distribution for %s", - Dih-NONCHI+1, residue_name); + sprintf(hisfile, "histo-chi%d%s", Dih - NONCHI + 1, residue_name); + sprintf(title, "\\xc\\f{}\\s%d\\N Distribution for %s", Dih - NONCHI + 1, + residue_name); } std::strcpy(hhisfile, hisfile); std::strcat(hhisfile, ".xvg"); @@ -772,7 +779,9 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, xvgr_world(fp, -180, 0, 180, 0.1, oenv); if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(fp, "# this effort to set graph size fails unless you run with -autoscale none or -autoscale y flags\n"); + fprintf(fp, + "# this effort to set graph size fails unless you run with -autoscale " + "none or -autoscale y flags\n"); fprintf(fp, "@ xaxis tick on\n"); fprintf(fp, "@ xaxis tick major 90\n"); fprintf(fp, "@ xaxis tick minor 30\n"); @@ -786,12 +795,12 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, for (k = 0; (k < 3); k++) { std::string sshisfile = gmx::formatString("%s-%s.xvg", hisfile, sss[k]); - ssfp[k] = gmx_ffopen(sshisfile, "w"); + ssfp[k] = gmx_ffopen(sshisfile, "w"); } } for (j = 0; (j < nbin); j++) { - angle = -180 + (360/nbin)*j; + angle = -180 + (360 / nbin) * j; if (bNormalize) { fprintf(fp, "%5d %10g\n", angle, normhisto[j]); @@ -804,8 +813,7 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, { for (k = 0; (k < 3); k++) { - fprintf(ssfp[k], "%5d %10d\n", angle, - his_aa_ss[k][i][Dih][j]); + fprintf(ssfp[k], "%5d %10d\n", angle, his_aa_ss[k][i][Dih][j]); } } } @@ -844,10 +852,9 @@ static void histogramming(FILE *log, int nbin, ResidueType *rt, } } -static FILE *rama_file(const char *fn, const char *title, const char *xaxis, - const char *yaxis, const gmx_output_env_t *oenv) +static FILE* rama_file(const char* fn, const char* title, const char* xaxis, const char* yaxis, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; fp = xvgropen(fn, title, xaxis, yaxis, oenv); if (output_env_get_print_xvgr_codes(oenv)) @@ -882,27 +889,30 @@ static FILE *rama_file(const char *fn, const char *title, const char *xaxis, return fp; } -static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, - gmx_bool bViol, gmx_bool bRamOmega, const gmx_output_env_t *oenv) +static void do_rama(int nf, + int nlist, + t_dlist dlist[], + real** dih, + gmx_bool bViol, + gmx_bool bRamOmega, + const gmx_output_env_t* oenv) { - FILE *fp, *gp = nullptr; + FILE * fp, *gp = nullptr; gmx_bool bOm; char fn[256]; int i, j, k, Xi1, Xi2, Phi, Psi, Om = 0, nlevels; constexpr int NMAT = 120; - real **mat = nullptr, phi, psi, omega, axis[NMAT], lo, hi; + real ** mat = nullptr, phi, psi, omega, axis[NMAT], lo, hi; t_rgb rlo = { 1.0, 0.0, 0.0 }; t_rgb rmid = { 1.0, 1.0, 1.0 }; t_rgb rhi = { 0.0, 0.0, 1.0 }; for (i = 0; (i < nlist); i++) { - if ((has_dihedral(edPhi, &(dlist[i]))) && - (has_dihedral(edPsi, &(dlist[i])))) + if ((has_dihedral(edPhi, &(dlist[i]))) && (has_dihedral(edPsi, &(dlist[i])))) { sprintf(fn, "ramaPhiPsi%s.xvg", dlist[i].name); - fp = rama_file(fn, "Ramachandran Plot", - "\\8f\\4 (deg)", "\\8y\\4 (deg)", oenv); + fp = rama_file(fn, "Ramachandran Plot", "\\8f\\4 (deg)", "\\8y\\4 (deg)", oenv); bOm = bRamOmega && has_dihedral(edOmega, &(dlist[i])); if (bOm) { @@ -911,7 +921,7 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, for (j = 0; (j < NMAT); j++) { snew(mat[j], NMAT); - axis[j] = -180+gmx::exactDiv(360*j, NMAT); + axis[j] = -180 + gmx::exactDiv(360 * j, NMAT); } } if (bViol) @@ -923,18 +933,18 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, Psi = dlist[i].j0[edPsi]; for (j = 0; (j < nf); j++) { - phi = RAD2DEG*dih[Phi][j]; - psi = RAD2DEG*dih[Psi][j]; + phi = RAD2DEG * dih[Phi][j]; + psi = RAD2DEG * dih[Psi][j]; fprintf(fp, "%10g %10g\n", phi, psi); if (bViol) { - fprintf(gp, "%d\n", static_cast(!bAllowed(dih[Phi][j], RAD2DEG*dih[Psi][j])) ); + fprintf(gp, "%d\n", static_cast(!bAllowed(dih[Phi][j], RAD2DEG * dih[Psi][j]))); } if (bOm) { - omega = RAD2DEG*dih[Om][j]; - mat[static_cast(((phi*NMAT)/360)+gmx::exactDiv(NMAT, 2))][static_cast(((psi*NMAT)/360)+gmx::exactDiv(NMAT, 2))] - += omega; + omega = RAD2DEG * dih[Om][j]; + mat[static_cast(((phi * NMAT) / 360) + gmx::exactDiv(NMAT, 2))] + [static_cast(((psi * NMAT) / 360) + gmx::exactDiv(NMAT, 2))] += omega; } } if (bViol) @@ -952,8 +962,8 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, for (k = 0; (k < NMAT); k++) { mat[j][k] /= nf; - lo = std::min(mat[j][k], lo); - hi = std::max(mat[j][k], hi); + lo = std::min(mat[j][k], lo); + hi = std::max(mat[j][k], hi); } } /* Symmetrise */ @@ -973,11 +983,11 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, mat[j][k] += 180; } } - lo += 180; - hi += 180; + lo += 180; + hi += 180; nlevels = 20; - write_xpm3(fp, 0, "Omega/Ramachandran Plot", "Deg", "Phi", "Psi", - NMAT, NMAT, axis, axis, mat, lo, 180.0, hi, rlo, rmid, rhi, &nlevels); + write_xpm3(fp, 0, "Omega/Ramachandran Plot", "Deg", "Phi", "Psi", NMAT, NMAT, axis, + axis, mat, lo, 180.0, hi, rlo, rmid, rhi, &nlevels); gmx_ffclose(fp); for (j = 0; (j < NMAT); j++) { @@ -986,17 +996,16 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, sfree(mat); } } - if ((has_dihedral(edChi1, &(dlist[i]))) && - (has_dihedral(edChi2, &(dlist[i])))) + if ((has_dihedral(edChi1, &(dlist[i]))) && (has_dihedral(edChi2, &(dlist[i])))) { sprintf(fn, "ramaX1X2%s.xvg", dlist[i].name); - fp = rama_file(fn, "\\8c\\4\\s1\\N-\\8c\\4\\s2\\N Ramachandran Plot", + fp = rama_file(fn, "\\8c\\4\\s1\\N-\\8c\\4\\s2\\N Ramachandran Plot", "\\8c\\4\\s1\\N (deg)", "\\8c\\4\\s2\\N (deg)", oenv); Xi1 = dlist[i].j0[edChi1]; Xi2 = dlist[i].j0[edChi2]; for (j = 0; (j < nf); j++) { - fprintf(fp, "%10g %10g\n", RAD2DEG*dih[Xi1][j], RAD2DEG*dih[Xi2][j]); + fprintf(fp, "%10g %10g\n", RAD2DEG * dih[Xi1][j], RAD2DEG * dih[Xi2][j]); } xvgrclose(fp); } @@ -1008,16 +1017,14 @@ static void do_rama(int nf, int nlist, t_dlist dlist[], real **dih, } -static void print_transitions(const char *fn, int maxchi, int nlist, - t_dlist dlist[], real dt, - const gmx_output_env_t *oenv) +static void print_transitions(const char* fn, int maxchi, int nlist, t_dlist dlist[], real dt, const gmx_output_env_t* oenv) { /* based on order_params below */ - FILE *fp; + FILE* fp; int i, Dih, Xi; /* must correspond with enum in pp2shift.h:38 */ - char *leg[edMax]; + char* leg[edMax]; #define NLEG asize(leg) leg[0] = gmx_strdup("Phi"); @@ -1031,24 +1038,23 @@ static void print_transitions(const char *fn, int maxchi, int nlist, leg[8] = gmx_strdup("Chi6"); /* Print order parameters */ - fp = xvgropen(fn, "Dihedral Rotamer Transitions", "Residue", "Transitions/ns", - oenv); - xvgr_legend(fp, NONCHI+maxchi, leg, oenv); + fp = xvgropen(fn, "Dihedral Rotamer Transitions", "Residue", "Transitions/ns", oenv); + xvgr_legend(fp, NONCHI + maxchi, leg, oenv); fprintf(fp, "%5s ", "#Res."); fprintf(fp, "%10s %10s %10s ", leg[edPhi], leg[edPsi], leg[edOmega]); for (Xi = 0; Xi < maxchi; Xi++) { - fprintf(fp, "%10s ", leg[NONCHI+Xi]); + fprintf(fp, "%10s ", leg[NONCHI + Xi]); } fprintf(fp, "\n"); for (i = 0; (i < nlist); i++) { fprintf(fp, "%5d ", dlist[i].resnr); - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { - fprintf(fp, "%10.3f ", dlist[i].ntr[Dih]/dt); + fprintf(fp, "%10.3f ", dlist[i].ntr[Dih] / dt); } /* fprintf(fp,"%12s\n",dlist[i].name); this confuses xmgrace */ fprintf(fp, "\n"); @@ -1056,26 +1062,33 @@ static void print_transitions(const char *fn, int maxchi, int nlist, xvgrclose(fp); } -static void order_params(FILE *log, - const char *fn, int maxchi, int nlist, t_dlist dlist[], - const char *pdbfn, real bfac_init, - t_atoms *atoms, const rvec x[], int ePBC, matrix box, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, const gmx_output_env_t *oenv) +static void order_params(FILE* log, + const char* fn, + int maxchi, + int nlist, + t_dlist dlist[], + const char* pdbfn, + real bfac_init, + t_atoms* atoms, + const rvec x[], + int ePBC, + matrix box, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; int nh[edMax]; int i, Dih, Xi; real S2Max, S2Min; /* except for S2Min/Max, must correspond with enum in pp2shift.h:38 */ - const char *const_leg[2+edMax] = { - "S2Min", "S2Max", "Phi", "Psi", "Omega", - "Chi1", "Chi2", "Chi3", "Chi4", "Chi5", - "Chi6" - }; + const char* const_leg[2 + edMax] = { "S2Min", "S2Max", "Phi", "Psi", "Omega", "Chi1", + "Chi2", "Chi3", "Chi4", "Chi5", "Chi6" }; #define NLEG asize(leg) - char *leg[2+edMax]; + char* leg[2 + edMax]; for (i = 0; i < NLEG; i++) { @@ -1084,7 +1097,7 @@ static void order_params(FILE *log, /* Print order parameters */ fp = xvgropen(fn, "Dihedral Order Parameters", "Residue", "S2", oenv); - xvgr_legend(fp, 2+NONCHI+maxchi, const_leg, oenv); + xvgr_legend(fp, 2 + NONCHI + maxchi, const_leg, oenv); for (Dih = 0; (Dih < edMax); Dih++) { @@ -1093,10 +1106,10 @@ static void order_params(FILE *log, fprintf(fp, "%5s ", "#Res."); fprintf(fp, "%10s %10s ", leg[0], leg[1]); - fprintf(fp, "%10s %10s %10s ", leg[2+edPhi], leg[2+edPsi], leg[2+edOmega]); + fprintf(fp, "%10s %10s %10s ", leg[2 + edPhi], leg[2 + edPsi], leg[2 + edOmega]); for (Xi = 0; Xi < maxchi; Xi++) { - fprintf(fp, "%10s ", leg[2+NONCHI+Xi]); + fprintf(fp, "%10s ", leg[2 + NONCHI + Xi]); } fprintf(fp, "\n"); @@ -1104,7 +1117,7 @@ static void order_params(FILE *log, { S2Max = -10; S2Min = 10; - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { if (dlist[i].S2[Dih] != 0) { @@ -1124,7 +1137,7 @@ static void order_params(FILE *log, } fprintf(fp, "%5d ", dlist[i].resnr); fprintf(fp, "%10.3f %10.3f ", S2Min, S2Max); - for (Dih = 0; (Dih < NONCHI+maxchi); Dih++) + for (Dih = 0; (Dih < NONCHI + maxchi); Dih++) { fprintf(fp, "%10.3f ", dlist[i].S2[Dih]); } @@ -1156,16 +1169,17 @@ static void order_params(FILE *log, atoms->pdbinfo[dlist[i].atm.O].bfac = -dlist[i].S2[1]; /* Psi */ for (Xi = 0; (Xi < maxchi); Xi++) /* Chi's */ { - if (dlist[i].atm.Cn[Xi+3] != -1) + if (dlist[i].atm.Cn[Xi + 3] != -1) { - atoms->pdbinfo[dlist[i].atm.Cn[Xi+1]].bfac = -dlist[i].S2[NONCHI+Xi]; + atoms->pdbinfo[dlist[i].atm.Cn[Xi + 1]].bfac = -dlist[i].S2[NONCHI + Xi]; } } } fp = gmx_ffopen(pdbfn, "w"); fprintf(fp, "REMARK generated by g_chi\n"); - fprintf(fp, "REMARK " + fprintf(fp, + "REMARK " "B-factor field contains negative of dihedral order parameters\n"); write_pdbfile(fp, nullptr, atoms, x, ePBC, box, ' ', 0, nullptr); x0 = y0 = z0 = 1000.0; @@ -1180,8 +1194,9 @@ static void order_params(FILE *log, z0 *= 10.0; /* nm -> angstrom */ for (i = 0; (i < 10); i++) { - gmx_fprintf_pdb_atomline(fp, epdbATOM, atoms->nr+1+i, "CA", ' ', "LEG", ' ', atoms->nres+1, ' ', - x0, y0, z0+(1.2*i), 0.0, -0.1*i, ""); + gmx_fprintf_pdb_atomline(fp, epdbATOM, atoms->nr + 1 + i, "CA", ' ', "LEG", ' ', + atoms->nres + 1, ' ', x0, y0, z0 + (1.2 * i), 0.0, -0.1 * i, + ""); } gmx_ffclose(fp); } @@ -1200,7 +1215,7 @@ static void order_params(FILE *log, { for (Xi = 0; (Xi < maxchi); Xi++) { - fprintf(log, " %s ", leg[2+NONCHI+Xi]); + fprintf(log, " %s ", leg[2 + NONCHI + Xi]); } } fprintf(log, "\nNumber: "); @@ -1216,7 +1231,7 @@ static void order_params(FILE *log, { for (Xi = 0; (Xi < maxchi); Xi++) { - fprintf(log, "%4d ", nh[NONCHI+Xi]); + fprintf(log, "%4d ", nh[NONCHI + Xi]); } } fprintf(log, "\n"); @@ -1225,21 +1240,22 @@ static void order_params(FILE *log, { sfree(leg[i]); } - } -int gmx_chi(int argc, char *argv[]) +int gmx_chi(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes [GRK]phi[grk], [GRK]psi[grk], [GRK]omega[grk],", "and [GRK]chi[grk] dihedrals for all your", "amino acid backbone and sidechains.", "It can compute dihedral angle as a function of time, and as", "histogram distributions.", - "The distributions [TT](histo-(dihedral)(RESIDUE).xvg[tt]) are cumulative over all residues of each type.[PAR]", + "The distributions [TT](histo-(dihedral)(RESIDUE).xvg[tt]) are cumulative over all ", + "residues of each type.[PAR]", "If option [TT]-corr[tt] is given, the program will", "calculate dihedral autocorrelation functions. The function used", - "is C(t) = [CHEVRON][COS][GRK]chi[grk]([GRK]tau[grk])[cos] [COS][GRK]chi[grk]([GRK]tau[grk]+t)[cos][chevron]. The use of cosines", + "is C(t) = [CHEVRON][COS][GRK]chi[grk]([GRK]tau[grk])[cos] ", + "[COS][GRK]chi[grk]([GRK]tau[grk]+t)[cos][chevron]. The use of cosines", "rather than angles themselves, resolves the problem of periodicity.", "(Van der Spoel & Berendsen (1997), Biophys. J. 72, 2032-2041).", "Separate files for each dihedral of each residue", @@ -1257,7 +1273,8 @@ int gmx_chi(int argc, char *argv[]) " * a table for each residue of the rotamer occupancy.", "", "All rotamers are taken as 3-fold, except for [GRK]omega[grk] and [GRK]chi[grk] dihedrals", - "to planar groups (i.e. [GRK]chi[grk][SUB]2[sub] of aromatics, Asp and Asn; [GRK]chi[grk][SUB]3[sub] of Glu", + "to planar groups (i.e. [GRK]chi[grk][SUB]2[sub] of aromatics, Asp and Asn; ", + "[GRK]chi[grk][SUB]3[sub] of Glu", "and Gln; and [GRK]chi[grk][SUB]4[sub] of Arg), which are 2-fold. \"rotamer 0\" means ", "that the dihedral was not in the core region of each rotamer. ", "The width of the core region can be set with [TT]-core_rotamer[tt][PAR]", @@ -1273,7 +1290,8 @@ int gmx_chi(int argc, char *argv[]) "are equally spaced in time.[PAR]", "If [TT]-chi_prod[tt] is set (and [TT]-maxchi[tt] > 0), cumulative rotamers, e.g.", - "1+9([GRK]chi[grk][SUB]1[sub]-1)+3([GRK]chi[grk][SUB]2[sub]-1)+([GRK]chi[grk][SUB]3[sub]-1) (if the residue has three 3-fold ", + "1+9([GRK]chi[grk][SUB]1[sub]-1)+3([GRK]chi[grk][SUB]2[sub]-1)+", + "([GRK]chi[grk][SUB]3[sub]-1) (if the residue has three 3-fold ", "dihedrals and [TT]-maxchi[tt] >= 3)", "are calculated. As before, if any dihedral is not in the core region,", "the rotamer is taken to be 0. The occupancies of these cumulative ", @@ -1284,113 +1302,140 @@ int gmx_chi(int argc, char *argv[]) "and their occupancies to [TT]histo-chiproduct(RESIDUE)(nresnr).xvg[tt].[PAR]", "The option [TT]-r[tt] generates a contour plot of the average [GRK]omega[grk] angle", - "as a function of the [GRK]phi[grk] and [GRK]psi[grk] angles, that is, in a Ramachandran plot", - "the average [GRK]omega[grk] angle is plotted using color coding.", + "as a function of the [GRK]phi[grk] and [GRK]psi[grk] angles, that is, in a Ramachandran ", + "plot the average [GRK]omega[grk] angle is plotted using color coding.", }; - const char *bugs[] = { - "Produces MANY output files (up to about 4 times the number of residues in the protein, twice that if autocorrelation functions are calculated). Typically several hundred files are output.", + const char* bugs[] = { + "Produces MANY output files (up to about 4 times the number of residues in the " + "protein, twice that if autocorrelation functions are calculated). Typically " + "several hundred files are output.", "[GRK]phi[grk] and [GRK]psi[grk] dihedrals are calculated in a " "non-standard way, using H-N-CA-C for [GRK]phi[grk] instead of " "C(-)-N-CA-C, and N-CA-C-O for [GRK]psi[grk] instead of N-CA-C-N(+). " "This causes (usually small) discrepancies with the output of other " "tools like [gmx-rama].", "[TT]-r0[tt] option does not work properly", - "Rotamers with multiplicity 2 are printed in [TT]chi.log[tt] as if they had multiplicity 3, with the 3rd (g(+)) always having probability 0" + "Rotamers with multiplicity 2 are printed in [TT]chi.log[tt] as if they had " + "multiplicity 3, with the 3rd (g(+)) always having probability 0" }; /* defaults */ - static int r0 = 1, ndeg = 1, maxchi = 2; - static gmx_bool bAll = FALSE; - static gmx_bool bPhi = FALSE, bPsi = FALSE, bOmega = FALSE; - static real bfac_init = -1.0, bfac_max = 0; - static const char *maxchistr[] = { nullptr, "0", "1", "2", "3", "4", "5", "6", nullptr }; - static gmx_bool bRama = FALSE, bShift = FALSE, bViol = FALSE, bRamOmega = FALSE; - static gmx_bool bNormHisto = TRUE, bChiProduct = FALSE, bHChi = FALSE, bRAD = FALSE, bPBC = TRUE; - static real core_frac = 0.5; - t_pargs pa[] = { - { "-r0", FALSE, etINT, {&r0}, - "starting residue" }, - { "-phi", FALSE, etBOOL, {&bPhi}, - "Output for [GRK]phi[grk] dihedral angles" }, - { "-psi", FALSE, etBOOL, {&bPsi}, - "Output for [GRK]psi[grk] dihedral angles" }, - { "-omega", FALSE, etBOOL, {&bOmega}, + static int r0 = 1, ndeg = 1, maxchi = 2; + static gmx_bool bAll = FALSE; + static gmx_bool bPhi = FALSE, bPsi = FALSE, bOmega = FALSE; + static real bfac_init = -1.0, bfac_max = 0; + static const char* maxchistr[] = { nullptr, "0", "1", "2", "3", "4", "5", "6", nullptr }; + static gmx_bool bRama = FALSE, bShift = FALSE, bViol = FALSE, bRamOmega = FALSE; + static gmx_bool bNormHisto = TRUE, bChiProduct = FALSE, bHChi = FALSE, bRAD = FALSE, bPBC = TRUE; + static real core_frac = 0.5; + t_pargs pa[] = { + { "-r0", FALSE, etINT, { &r0 }, "starting residue" }, + { "-phi", FALSE, etBOOL, { &bPhi }, "Output for [GRK]phi[grk] dihedral angles" }, + { "-psi", FALSE, etBOOL, { &bPsi }, "Output for [GRK]psi[grk] dihedral angles" }, + { "-omega", + FALSE, + etBOOL, + { &bOmega }, "Output for [GRK]omega[grk] dihedrals (peptide bonds)" }, - { "-rama", FALSE, etBOOL, {&bRama}, - "Generate [GRK]phi[grk]/[GRK]psi[grk] and [GRK]chi[grk][SUB]1[sub]/[GRK]chi[grk][SUB]2[sub] Ramachandran plots" }, - { "-viol", FALSE, etBOOL, {&bViol}, + { "-rama", + FALSE, + etBOOL, + { &bRama }, + "Generate [GRK]phi[grk]/[GRK]psi[grk] and " + "[GRK]chi[grk][SUB]1[sub]/[GRK]chi[grk][SUB]2[sub] Ramachandran plots" }, + { "-viol", + FALSE, + etBOOL, + { &bViol }, "Write a file that gives 0 or 1 for violated Ramachandran angles" }, - { "-periodic", FALSE, etBOOL, {&bPBC}, - "Print dihedral angles modulo 360 degrees" }, - { "-all", FALSE, etBOOL, {&bAll}, - "Output separate files for every dihedral." }, - { "-rad", FALSE, etBOOL, {&bRAD}, - "in angle vs time files, use radians rather than degrees."}, - { "-shift", FALSE, etBOOL, {&bShift}, + { "-periodic", FALSE, etBOOL, { &bPBC }, "Print dihedral angles modulo 360 degrees" }, + { "-all", FALSE, etBOOL, { &bAll }, "Output separate files for every dihedral." }, + { "-rad", + FALSE, + etBOOL, + { &bRAD }, + "in angle vs time files, use radians rather than degrees." }, + { "-shift", + FALSE, + etBOOL, + { &bShift }, "Compute chemical shifts from [GRK]phi[grk]/[GRK]psi[grk] angles" }, - { "-binwidth", FALSE, etINT, {&ndeg}, - "bin width for histograms (degrees)" }, - { "-core_rotamer", FALSE, etREAL, {&core_frac}, - "only the central [TT]-core_rotamer[tt]\\*(360/multiplicity) belongs to each rotamer (the rest is assigned to rotamer 0)" }, - { "-maxchi", FALSE, etENUM, {maxchistr}, - "calculate first ndih [GRK]chi[grk] dihedrals" }, - { "-normhisto", FALSE, etBOOL, {&bNormHisto}, - "Normalize histograms" }, - { "-ramomega", FALSE, etBOOL, {&bRamOmega}, - "compute average omega as a function of [GRK]phi[grk]/[GRK]psi[grk] and plot it in an [REF].xpm[ref] plot" }, - { "-bfact", FALSE, etREAL, {&bfac_init}, - "B-factor value for [REF].pdb[ref] file for atoms with no calculated dihedral order parameter"}, - { "-chi_prod", FALSE, etBOOL, {&bChiProduct}, - "compute a single cumulative rotamer for each residue"}, - { "-HChi", FALSE, etBOOL, {&bHChi}, - "Include dihedrals to sidechain hydrogens"}, - { "-bmax", FALSE, etREAL, {&bfac_max}, - "Maximum B-factor on any of the atoms that make up a dihedral, for the dihedral angle to be considere in the statistics. Applies to database work where a number of X-Ray structures is analyzed. [TT]-bmax[tt] <= 0 means no limit." } + { "-binwidth", FALSE, etINT, { &ndeg }, "bin width for histograms (degrees)" }, + { "-core_rotamer", + FALSE, + etREAL, + { &core_frac }, + "only the central [TT]-core_rotamer[tt]\\*(360/multiplicity) belongs to each rotamer " + "(the rest is assigned to rotamer 0)" }, + { "-maxchi", FALSE, etENUM, { maxchistr }, "calculate first ndih [GRK]chi[grk] dihedrals" }, + { "-normhisto", FALSE, etBOOL, { &bNormHisto }, "Normalize histograms" }, + { "-ramomega", + FALSE, + etBOOL, + { &bRamOmega }, + "compute average omega as a function of [GRK]phi[grk]/[GRK]psi[grk] and plot it in an " + "[REF].xpm[ref] plot" }, + { "-bfact", + FALSE, + etREAL, + { &bfac_init }, + "B-factor value for [REF].pdb[ref] file for atoms with no calculated dihedral order " + "parameter" }, + { "-chi_prod", + FALSE, + etBOOL, + { &bChiProduct }, + "compute a single cumulative rotamer for each residue" }, + { "-HChi", FALSE, etBOOL, { &bHChi }, "Include dihedrals to sidechain hydrogens" }, + { "-bmax", + FALSE, + etREAL, + { &bfac_max }, + "Maximum B-factor on any of the atoms that make up a dihedral, for the dihedral angle to " + "be considere in the statistics. Applies to database work where a number of X-Ray " + "structures is analyzed. [TT]-bmax[tt] <= 0 means no limit." } }; - FILE *log; - int nlist, idum, nbin; - rvec *x; - int ePBC; - matrix box; - char grpname[256]; - t_dlist *dlist; - gmx_bool bChi, bCorr, bSSHisto; - gmx_bool bDo_rt, bDo_oh, bDo_ot, bDo_jc; - real dt = 0, traj_t_ns; - gmx_output_env_t *oenv; - - int isize, *index; - int ndih, nactdih, nf; - real **dih, *trans_frac, *aver_angle, *time; - int i, **chi_lookup, *multiplicity; - - t_filenm fnm[] = { - { efSTX, "-s", nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efXVG, "-o", "order", ffWRITE }, - { efPDB, "-p", "order", ffOPTWR }, - { efDAT, "-ss", "ssdump", ffOPTRD }, - { efXVG, "-jc", "Jcoupling", ffWRITE }, - { efXVG, "-corr", "dihcorr", ffOPTWR }, - { efLOG, "-g", "chi", ffWRITE }, - /* add two more arguments copying from g_angle */ - { efXVG, "-ot", "dihtrans", ffOPTWR }, - { efXVG, "-oh", "trhisto", ffOPTWR }, - { efXVG, "-rt", "restrans", ffOPTWR }, - { efXVG, "-cp", "chiprodhisto", ffOPTWR } - }; + FILE* log; + int nlist, idum, nbin; + rvec* x; + int ePBC; + matrix box; + char grpname[256]; + t_dlist* dlist; + gmx_bool bChi, bCorr, bSSHisto; + gmx_bool bDo_rt, bDo_oh, bDo_ot, bDo_jc; + real dt = 0, traj_t_ns; + gmx_output_env_t* oenv; + + int isize, *index; + int ndih, nactdih, nf; + real **dih, *trans_frac, *aver_angle, *time; + int i, **chi_lookup, *multiplicity; + + t_filenm fnm[] = { { efSTX, "-s", nullptr, ffREAD }, + { efTRX, "-f", nullptr, ffREAD }, + { efXVG, "-o", "order", ffWRITE }, + { efPDB, "-p", "order", ffOPTWR }, + { efDAT, "-ss", "ssdump", ffOPTRD }, + { efXVG, "-jc", "Jcoupling", ffWRITE }, + { efXVG, "-corr", "dihcorr", ffOPTWR }, + { efLOG, "-g", "chi", ffWRITE }, + /* add two more arguments copying from g_angle */ + { efXVG, "-ot", "dihtrans", ffOPTWR }, + { efXVG, "-oh", "trhisto", ffOPTWR }, + { efXVG, "-rt", "restrans", ffOPTWR }, + { efXVG, "-cp", "chiprodhisto", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, asize(bugs), bugs, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { sfree(ppa); return 0; @@ -1433,19 +1478,17 @@ int gmx_chi(int argc, char *argv[]) if (maxchi > MAXCHI) { - fprintf(stderr, - "Will only calculate first %d Chi dihedrals instead of %d.\n", - MAXCHI, maxchi); + fprintf(stderr, "Will only calculate first %d Chi dihedrals instead of %d.\n", MAXCHI, maxchi); maxchi = MAXCHI; } bSSHisto = ftp2bSet(efDAT, NFILE, fnm); - nbin = 360/ndeg; + nbin = 360 / ndeg; /* Find the chi angles using atoms struct and a list of amino acids */ - t_topology *top; + t_topology* top; snew(top, 1); read_tps_conf(ftp2fn(efSTX, NFILE, fnm), top, &ePBC, &x, nullptr, box, FALSE); - t_atoms &atoms = top->atoms; + t_atoms& atoms = top->atoms; if (atoms.pdbinfo == nullptr) { snew(atoms.pdbinfo, atoms.nr); @@ -1463,16 +1506,16 @@ int gmx_chi(int argc, char *argv[]) /* Make a linear index for reading all. */ index = make_chi_ind(nlist, dlist, &ndih); - isize = 4*ndih; + isize = 4 * ndih; fprintf(stderr, "%d dihedrals found\n", ndih); snew(dih, ndih); /* COMPUTE ALL DIHEDRALS! */ - read_ang_dih(ftp2fn(efTRX, NFILE, fnm), FALSE, TRUE, FALSE, bPBC, 1, &idum, - &nf, &time, isize, index, &trans_frac, &aver_angle, dih, oenv); + read_ang_dih(ftp2fn(efTRX, NFILE, fnm), FALSE, TRUE, FALSE, bPBC, 1, &idum, &nf, &time, isize, + index, &trans_frac, &aver_angle, dih, oenv); - dt = (time[nf-1]-time[0])/(nf-1); /* might want this for corr or n. transit*/ + dt = (time[nf - 1] - time[0]) / (nf - 1); /* might want this for corr or n. transit*/ if (bCorr) { if (nf < 2) @@ -1492,10 +1535,9 @@ int gmx_chi(int argc, char *argv[]) } /* Histogramming & J coupling constants & calc of S2 order params */ - histogramming(log, nbin, &rt, nf, maxchi, dih, nlist, dlist, index, - bPhi, bPsi, bOmega, bChi, - bNormHisto, bSSHisto, ftp2fn(efDAT, NFILE, fnm), bfac_max, &atoms, - bDo_jc, opt2fn("-jc", NFILE, fnm), oenv); + histogramming(log, nbin, &rt, nf, maxchi, dih, nlist, dlist, index, bPhi, bPsi, bOmega, bChi, + bNormHisto, bSSHisto, ftp2fn(efDAT, NFILE, fnm), bfac_max, &atoms, bDo_jc, + opt2fn("-jc", NFILE, fnm), oenv); /* transitions * @@ -1524,15 +1566,12 @@ int gmx_chi(int argc, char *argv[]) } - low_ana_dih_trans(bDo_ot, opt2fn("-ot", NFILE, fnm), - bDo_oh, opt2fn("-oh", NFILE, fnm), maxchi, - dih, nlist, dlist, nf, nactdih, grpname, multiplicity, - time, FALSE, core_frac, oenv); + low_ana_dih_trans(bDo_ot, opt2fn("-ot", NFILE, fnm), bDo_oh, opt2fn("-oh", NFILE, fnm), maxchi, dih, + nlist, dlist, nf, nactdih, grpname, multiplicity, time, FALSE, core_frac, oenv); /* Order parameters */ - order_params(log, opt2fn("-o", NFILE, fnm), maxchi, nlist, dlist, - ftp2fn_null(efPDB, NFILE, fnm), bfac_init, - &atoms, x, ePBC, box, bPhi, bPsi, bChi, oenv); + order_params(log, opt2fn("-o", NFILE, fnm), maxchi, nlist, dlist, ftp2fn_null(efPDB, NFILE, fnm), + bfac_init, &atoms, x, ePBC, box, bPhi, bPsi, bChi, oenv); /* Print ramachandran maps! */ if (bRama) @@ -1546,7 +1585,7 @@ int gmx_chi(int argc, char *argv[]) } /* rprint S^2, transitions, and rotamer occupancies to log */ - traj_t_ns = 0.001 * (time[nf-1]-time[0]); + traj_t_ns = 0.001 * (time[nf - 1] - time[0]); pr_dlist(log, nlist, dlist, traj_t_ns, edPrintST, bPhi, bPsi, bChi, bOmega, maxchi); pr_dlist(log, nlist, dlist, traj_t_ns, edPrintRO, bPhi, bPsi, bChi, bOmega, maxchi); gmx_ffclose(log); @@ -1566,10 +1605,8 @@ int gmx_chi(int argc, char *argv[]) } mk_chi_lookup(chi_lookup, maxchi, nlist, dlist); - get_chi_product_traj(dih, nf, nactdih, - maxchi, dlist, time, chi_lookup, multiplicity, - FALSE, bNormHisto, core_frac, bAll, - opt2fn("-cp", NFILE, fnm), oenv); + get_chi_product_traj(dih, nf, nactdih, maxchi, dlist, time, chi_lookup, multiplicity, FALSE, + bNormHisto, core_frac, bAll, opt2fn("-cp", NFILE, fnm), oenv); for (i = 0; i < nlist; i++) { @@ -1580,8 +1617,8 @@ int gmx_chi(int argc, char *argv[]) /* Correlation comes last because it messes up the angles */ if (bCorr) { - do_dihcorr(opt2fn("-corr", NFILE, fnm), nf, ndih, dih, dt, nlist, dlist, time, - maxchi, bPhi, bPsi, bChi, bOmega, oenv); + do_dihcorr(opt2fn("-corr", NFILE, fnm), nf, ndih, dih, dt, nlist, dlist, time, maxchi, bPhi, + bPsi, bChi, bOmega, oenv); } diff --git a/src/gromacs/gmxana/gmx_cluster.cpp b/src/gromacs/gmxana/gmx_cluster.cpp index a442db4263..3b4d8f0245 100644 --- a/src/gromacs/gmxana/gmx_cluster.cpp +++ b/src/gromacs/gmxana/gmx_cluster.cpp @@ -68,87 +68,86 @@ #include "gromacs/utility/stringutil.h" /* print to two file pointers at once (i.e. stderr and log) */ -static inline -void lo_ffprintf(FILE *fp1, FILE *fp2, const char *buf) +static inline void lo_ffprintf(FILE* fp1, FILE* fp2, const char* buf) { fprintf(fp1, "%s", buf); fprintf(fp2, "%s", buf); } /* just print a prepared buffer to fp1 and fp2 */ -static inline -void ffprintf(FILE *fp1, FILE *fp2, const char *buf) +static inline void ffprintf(FILE* fp1, FILE* fp2, const char* buf) { lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with one argument, then print to fp1 and fp2 */ -static inline -void ffprintf_d(FILE *fp1, FILE *fp2, char *buf, const char *fmt, int arg) +static inline void ffprintf_d(FILE* fp1, FILE* fp2, char* buf, const char* fmt, int arg) { sprintf(buf, fmt, arg); lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with one argument, then print to fp1 and fp2 */ -static inline -void ffprintf_g(FILE *fp1, FILE *fp2, char *buf, const char *fmt, real arg) +static inline void ffprintf_g(FILE* fp1, FILE* fp2, char* buf, const char* fmt, real arg) { sprintf(buf, fmt, arg); lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with one argument, then print to fp1 and fp2 */ -static inline -void ffprintf_s(FILE *fp1, FILE *fp2, char *buf, const char *fmt, const char *arg) +static inline void ffprintf_s(FILE* fp1, FILE* fp2, char* buf, const char* fmt, const char* arg) { sprintf(buf, fmt, arg); lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with two arguments, then print to fp1 and fp2 */ -static inline -void ffprintf_dd(FILE *fp1, FILE *fp2, char *buf, const char *fmt, int arg1, int arg2) +static inline void ffprintf_dd(FILE* fp1, FILE* fp2, char* buf, const char* fmt, int arg1, int arg2) { sprintf(buf, fmt, arg1, arg2); lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with two arguments, then print to fp1 and fp2 */ -static inline -void ffprintf_gg(FILE *fp1, FILE *fp2, char *buf, const char *fmt, real arg1, real arg2) +static inline void ffprintf_gg(FILE* fp1, FILE* fp2, char* buf, const char* fmt, real arg1, real arg2) { sprintf(buf, fmt, arg1, arg2); lo_ffprintf(fp1, fp2, buf); } /* prepare buffer with two arguments, then print to fp1 and fp2 */ -static inline -void ffprintf_ss(FILE *fp1, FILE *fp2, char *buf, const char *fmt, const char *arg1, const char *arg2) +static inline void ffprintf_ss(FILE* fp1, FILE* fp2, char* buf, const char* fmt, const char* arg1, const char* arg2) { sprintf(buf, fmt, arg1, arg2); lo_ffprintf(fp1, fp2, buf); } -typedef struct { +typedef struct +{ int ncl; - int *cl; + int* cl; } t_clusters; -typedef struct { +typedef struct +{ int nr; - int *nb; + int* nb; } t_nnb; -static void mc_optimize(FILE *log, t_mat *m, real *time, - int maxiter, int nrandom, - int seed, real kT, - const char *conv, gmx_output_env_t *oenv) +static void mc_optimize(FILE* log, + t_mat* m, + real* time, + int maxiter, + int nrandom, + int seed, + real kT, + const char* conv, + gmx_output_env_t* oenv) { - FILE *fp = nullptr; - real ecur, enext, emin, prob, enorm; - int i, j, iswap, jswap, nn, nuphill = 0; - t_mat *minimum; + FILE* fp = nullptr; + real ecur, enext, emin, prob, enorm; + int i, j, iswap, jswap, nn, nuphill = 0; + t_mat* minimum; if (seed == 0) { @@ -167,16 +166,16 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, printf("Using random seed %d.\n", seed); iswap = jswap = -1; - enorm = m->mat[0][0]; + enorm = m->mat[0][0]; for (i = 0; (i < m->n1); i++) { for (j = 0; (j < m->nn); j++) { if (m->mat[i][j] > enorm) { - enorm = m->mat[i][j]; - iswap = i; - jswap = j; + enorm = m->mat[i][j]; + iswap = i; + jswap = j; } } } @@ -186,12 +185,11 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, return; } swap_rows(m, 0, iswap); - swap_rows(m, m->n1-1, jswap); + swap_rows(m, m->n1 - 1, jswap); emin = ecur = mat_energy(m); - printf("Largest distance %g between %d and %d. Energy: %g.\n", - enorm, iswap, jswap, emin); + printf("Largest distance %g between %d and %d. Energy: %g.\n", enorm, iswap, jswap, emin); - nn = m->nn; + nn = m->nn; /* Initiate and store global minimum */ minimum = init_mat(nn, m->b1D); @@ -200,12 +198,11 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, if (nullptr != conv) { - fp = xvgropen(conv, "Convergence of the MC optimization", - "Energy", "Step", oenv); + fp = xvgropen(conv, "Convergence of the MC optimization", "Energy", "Step", oenv); } - gmx::UniformIntDistribution intDistNN(1, nn-2); // [1,nn-2] - gmx::UniformRealDistribution realDistOne; // [0,1) + gmx::UniformIntDistribution intDistNN(1, nn - 2); // [1,nn-2] + gmx::UniformRealDistribution realDistOne; // [0,1) for (i = 0; (i < maxiter); i++) { @@ -214,8 +211,7 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, { iswap = intDistNN(rng); jswap = intDistNN(rng); - } - while ((iswap == jswap) || (iswap >= nn-1) || (jswap >= nn-1)); + } while ((iswap == jswap) || (iswap >= nn - 1) || (jswap >= nn - 1)); /* Apply swap and compute energy */ swap_rows(m, iswap, jswap); @@ -236,7 +232,7 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, else if (kT > 0) { /* Try Monte Carlo step */ - prob = std::exp(-(enext-ecur)/(enorm*kT)); + prob = std::exp(-(enext - ecur) / (enorm * kT)); } if (prob == 1 || realDistOne(rng) < prob) @@ -246,8 +242,8 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, nuphill++; } - fprintf(log, "Iter: %d Swapped %4d and %4d (energy: %g prob: %g)\n", - i, iswap, jswap, enext, prob); + fprintf(log, "Iter: %d Swapped %4d and %4d (energy: %g prob: %g)\n", i, iswap, jswap, + enext, prob); if (nullptr != fp) { fprintf(fp, "%6d %10g\n", i, enext); @@ -259,8 +255,7 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, swap_rows(m, jswap, iswap); } } - fprintf(log, "%d uphill steps were taken during optimization\n", - nuphill); + fprintf(log, "%d uphill steps were taken during optimization\n", nuphill); /* Now swap the matrix to get it into global minimum mode */ copy_t_mat(m, minimum); @@ -270,10 +265,8 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, fprintf(log, "Swapped time and frame indices and RMSD to next neighbor:\n"); for (i = 0; (i < m->nn); i++) { - fprintf(log, "%10g %5d %10g\n", - time[m->m_ind[i]], - m->m_ind[i], - (i < m->nn-1) ? m->mat[m->m_ind[i]][m->m_ind[i+1]] : 0); + fprintf(log, "%10g %5d %10g\n", time[m->m_ind[i]], m->m_ind[i], + (i < m->nn - 1) ? m->mat[m->m_ind[i]][m->m_ind[i + 1]] : 0); } if (nullptr != fp) @@ -282,16 +275,16 @@ static void mc_optimize(FILE *log, t_mat *m, real *time, } } -static void calc_dist(int nind, rvec x[], real **d) +static void calc_dist(int nind, rvec x[], real** d) { - int i, j; - real *xi; - rvec dx; + int i, j; + real* xi; + rvec dx; - for (i = 0; (i < nind-1); i++) + for (i = 0; (i < nind - 1); i++) { xi = x[i]; - for (j = i+1; (j < nind); j++) + for (j = i + 1; (j < nind); j++) { /* Should use pbc_dx when analysing multiple molecueles, * but the box is not stored for every frame. @@ -302,55 +295,55 @@ static void calc_dist(int nind, rvec x[], real **d) } } -static real rms_dist(int isize, real **d, real **d_r) +static real rms_dist(int isize, real** d, real** d_r) { int i, j; real r, r2; r2 = 0.0; - for (i = 0; (i < isize-1); i++) + for (i = 0; (i < isize - 1); i++) { - for (j = i+1; (j < isize); j++) + for (j = i + 1; (j < isize); j++) { - r = d[i][j]-d_r[i][j]; - r2 += r*r; + r = d[i][j] - d_r[i][j]; + r2 += r * r; } } - r2 /= gmx::exactDiv(isize*(isize-1), 2); + r2 /= gmx::exactDiv(isize * (isize - 1), 2); return std::sqrt(r2); } -static bool rms_dist_comp(const t_dist &a, const t_dist &b) +static bool rms_dist_comp(const t_dist& a, const t_dist& b) { return a.dist < b.dist; } -static bool clust_id_comp(const t_clustid &a, const t_clustid &b) +static bool clust_id_comp(const t_clustid& a, const t_clustid& b) { return a.clust < b.clust; } -static bool nrnb_comp(const t_nnb &a, const t_nnb &b) +static bool nrnb_comp(const t_nnb& a, const t_nnb& b) { /* return bnn; - nn = ((n1-1)*n1)/2; + nn = ((n1 - 1) * n1) / 2; snew(d, nn); for (i = k = 0; (i < n1); i++) { - for (j = i+1; (j < n1); j++, k++) + for (j = i + 1; (j < n1); j++, k++) { d[k].i = i; d[k].j = j; @@ -361,7 +354,7 @@ static void gather(t_mat *m, real cutoff, t_clusters *clust) { gmx_incons("gather algortihm"); } - std::sort(d, d+nn, rms_dist_comp); + std::sort(d, d + nn, rms_dist_comp); /* Now we make a cluster index for all of the conformations */ c = new_clustid(n1); @@ -388,33 +381,31 @@ static void gather(t_mat *m, real cutoff, t_clusters *clust) } } } - } - while (bChange); + } while (bChange); fprintf(stderr, "\nSorting and renumbering clusters\n"); /* Sort on cluster number */ - std::sort(c, c+n1, clust_id_comp); + std::sort(c, c + n1, clust_id_comp); /* Renumber clusters */ cid = 1; for (k = 1; k < n1; k++) { - if (c[k].clust != c[k-1].clust) + if (c[k].clust != c[k - 1].clust) { - c[k-1].clust = cid; + c[k - 1].clust = cid; cid++; } else { - c[k-1].clust = cid; + c[k - 1].clust = cid; } } - c[k-1].clust = cid; + c[k - 1].clust = cid; if (debug) { for (k = 0; (k < n1); k++) { - fprintf(debug, "Cluster index for conformation %d: %d\n", - c[k].conf, c[k].clust); + fprintf(debug, "Cluster index for conformation %d: %d\n", c[k].conf, c[k].clust); } } clust->ncl = cid; @@ -427,7 +418,7 @@ static void gather(t_mat *m, real cutoff, t_clusters *clust) sfree(d); } -static gmx_bool jp_same(int **nnb, int i, int j, int P) +static gmx_bool jp_same(int** nnb, int i, int j, int P) { gmx_bool bIn; int k, ii, jj, pp; @@ -467,15 +458,14 @@ static gmx_bool jp_same(int **nnb, int i, int j, int P) return (pp >= P); } -static void jarvis_patrick(int n1, real **mat, int M, int P, - real rmsdcut, t_clusters *clust) +static void jarvis_patrick(int n1, real** mat, int M, int P, real rmsdcut, t_clusters* clust) { - t_dist *row; - t_clustid *c; - int **nnb; - int i, j, k, cid, diff, maxval; - gmx_bool bChange; - real **mcpy = nullptr; + t_dist* row; + t_clustid* c; + int** nnb; + int i, j, k, cid, diff, maxval; + gmx_bool bChange; + real** mcpy = nullptr; if (rmsdcut < 0) { @@ -494,16 +484,16 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, row[j].j = j; row[j].dist = mat[i][j]; } - std::sort(row, row+n1, rms_dist_comp); + std::sort(row, row + n1, rms_dist_comp); if (M > 0) { /* Put the M nearest neighbors in the list */ - snew(nnb[i], M+1); + snew(nnb[i], M + 1); for (j = k = 0; (k < M) && (j < n1) && (mat[i][row[j].j] < rmsdcut); j++) { - if (row[j].j != i) + if (row[j].j != i) { - nnb[i][k] = row[j].j; + nnb[i][k] = row[j].j; k++; } } @@ -529,7 +519,7 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, } if (k == maxval) { - srenew(nnb[i], maxval+1); + srenew(nnb[i], maxval + 1); } nnb[i][k] = -1; } @@ -555,7 +545,7 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, mcpy = mk_matrix(n1, n1, FALSE); for (i = 0; i < n1; i++) { - for (j = i+1; j < n1; j++) + for (j = i + 1; j < n1; j++) { mcpy[i][j] = static_cast(jp_same(nnb, i, j, P)); } @@ -566,7 +556,7 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, bChange = FALSE; for (i = 0; i < n1; i++) { - for (j = i+1; j < n1; j++) + for (j = i + 1; j < n1; j++) { if (mcpy[i][j] != 0.0F) { @@ -586,29 +576,28 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, } } } - } - while (bChange); + } while (bChange); fprintf(stderr, "\nSorting and renumbering clusters\n"); /* Sort on cluster number */ - std::sort(c, c+n1, clust_id_comp); + std::sort(c, c + n1, clust_id_comp); /* Renumber clusters */ cid = 1; for (k = 1; k < n1; k++) { - if (c[k].clust != c[k-1].clust) + if (c[k].clust != c[k - 1].clust) { - c[k-1].clust = cid; + c[k - 1].clust = cid; cid++; } else { - c[k-1].clust = cid; + c[k - 1].clust = cid; } } - c[k-1].clust = cid; - clust->ncl = cid; + c[k - 1].clust = cid; + clust->ncl = cid; for (k = 0; k < n1; k++) { clust->cl[c[k].conf] = c[k].clust; @@ -617,8 +606,7 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, { for (k = 0; (k < n1); k++) { - fprintf(debug, "Cluster index for conformation %d: %d\n", - c[k].conf, c[k].clust); + fprintf(debug, "Cluster index for conformation %d: %d\n", c[k].conf, c[k].clust); } } @@ -632,7 +620,7 @@ static void jarvis_patrick(int n1, real **mat, int M, int P, sfree(nnb); } -static void dump_nnb (FILE *fp, const char *title, int n1, t_nnb *nnb) +static void dump_nnb(FILE* fp, const char* title, int n1, t_nnb* nnb) { int i, j; @@ -649,10 +637,10 @@ static void dump_nnb (FILE *fp, const char *title, int n1, t_nnb *nnb) } } -static void gromos(int n1, real **mat, real rmsdcut, t_clusters *clust) +static void gromos(int n1, real** mat, real rmsdcut, t_clusters* clust) { - t_nnb *nnb; - int i, j, k, j1, maxval; + t_nnb* nnb; + int i, j, k, j1, maxval; /* Put all neighbors nearer than rmsdcut in the list */ fprintf(stderr, "Making list of neighbors within cutoff "); @@ -677,15 +665,15 @@ static void gromos(int n1, real **mat, real rmsdcut, t_clusters *clust) } /* store nr of neighbors, we'll need that */ nnb[i].nr = k; - if (i%(1+n1/100) == 0) + if (i % (1 + n1 / 100) == 0) { - fprintf(stderr, "%3d%%\b\b\b\b", (i*100+1)/n1); + fprintf(stderr, "%3d%%\b\b\b\b", (i * 100 + 1) / n1); } } fprintf(stderr, "%3d%%\n", 100); /* sort neighbor list on number of neighbors, largest first */ - std::sort(nnb, nnb+n1, nrnb_comp); + std::sort(nnb, nnb + n1, nrnb_comp); if (debug) { @@ -728,7 +716,7 @@ static void gromos(int n1, real **mat, real rmsdcut, t_clusters *clust) } /* sort again on nnb[].nr, because we have new # neighbors: */ /* but we only need to sort upto i, i.e. when nnb[].nr>0 */ - std::sort(nnb, nnb+i, nrnb_comp); + std::sort(nnb, nnb + i, nrnb_comp); fprintf(stderr, "\b\b\b\b%4d", k); /* new cluster id */ @@ -746,25 +734,34 @@ static void gromos(int n1, real **mat, real rmsdcut, t_clusters *clust) fprintf(debug, "\n"); } - clust->ncl = k-1; + clust->ncl = k - 1; } -static rvec **read_whole_trj(const char *fn, int isize, const int index[], int skip, - int *nframe, real **time, matrix **boxes, int **frameindices, const gmx_output_env_t *oenv, gmx_bool bPBC, gmx_rmpbc_t gpbc) +static rvec** read_whole_trj(const char* fn, + int isize, + const int index[], + int skip, + int* nframe, + real** time, + matrix** boxes, + int** frameindices, + const gmx_output_env_t* oenv, + gmx_bool bPBC, + gmx_rmpbc_t gpbc) { - rvec **xx, *x; + rvec ** xx, *x; matrix box; real t; int i, j, max_nf; int natom; - t_trxstatus *status; + t_trxstatus* status; - max_nf = 0; - xx = nullptr; - *time = nullptr; - natom = read_first_x(oenv, &status, fn, &t, &x, box); - i = 0; + max_nf = 0; + xx = nullptr; + *time = nullptr; + natom = read_first_x(oenv, &status, fn, &t, &x, box); + i = 0; int clusterIndex = 0; do { @@ -794,10 +791,8 @@ static rvec **read_whole_trj(const char *fn, int isize, const int index[], int s clusterIndex++; } i++; - } - while (read_next_x(oenv, status, &t, x, box)); - fprintf(stderr, "Allocated %zu bytes for frames\n", - (max_nf*isize*sizeof(**xx))); + } while (read_next_x(oenv, status, &t, x, box)); + fprintf(stderr, "Allocated %zu bytes for frames\n", (max_nf * isize * sizeof(**xx))); fprintf(stderr, "Read %d frames from trajectory %s\n", clusterIndex, fn); *nframe = clusterIndex; sfree(x); @@ -805,8 +800,7 @@ static rvec **read_whole_trj(const char *fn, int isize, const int index[], int s return xx; } -static int plot_clusters(int nf, real **mat, t_clusters *clust, - int minstruct) +static int plot_clusters(int nf, real** mat, t_clusters* clust, int minstruct) { int i, j, ncluster, ci; int *cl_id, *nstruct, *strind; @@ -836,8 +830,7 @@ static int plot_clusters(int nf, real **mat, t_clusters *clust, } } ncluster++; - fprintf(stderr, "There are %d clusters with at least %d conformations\n", - ncluster, minstruct); + fprintf(stderr, "There are %d clusters with at least %d conformations\n", ncluster, minstruct); for (i = 0; (i < nf); i++) { @@ -863,7 +856,7 @@ static int plot_clusters(int nf, real **mat, t_clusters *clust, return ncluster; } -static void mark_clusters(int nf, real **mat, real val, t_clusters *clust) +static void mark_clusters(int nf, real** mat, real val, t_clusters* clust) { int i, j; @@ -883,11 +876,11 @@ static void mark_clusters(int nf, real **mat, real val, t_clusters *clust) } } -static char *parse_filename(const char *fn, int maxnr) +static char* parse_filename(const char* fn, int maxnr) { int i; - char *fnout; - const char *ext; + char* fnout; + const char* ext; char buf[STRLEN]; if (std::strchr(fn, '%')) @@ -895,7 +888,7 @@ static char *parse_filename(const char *fn, int maxnr) gmx_fatal(FARGS, "will not number filename %s containing '%c'", fn, '%'); } /* number of digits needed in numbering */ - i = static_cast((std::log(static_cast(maxnr))/std::log(10.0)) + 1); + i = static_cast((std::log(static_cast(maxnr)) / std::log(10.0)) + 1); /* split fn and ext */ ext = std::strrchr(fn, '.'); if (!ext) @@ -905,19 +898,24 @@ static char *parse_filename(const char *fn, int maxnr) ext++; /* insert e.g. '%03d' between fn and ext */ sprintf(buf, "%s%%0%dd.%s", fn, i, ext); - snew(fnout, std::strlen(buf)+1); + snew(fnout, std::strlen(buf) + 1); std::strcpy(fnout, buf); return fnout; } -static void ana_trans(t_clusters *clust, int nf, - const char *transfn, const char *ntransfn, FILE *log, - t_rgb rlo, t_rgb rhi, const gmx_output_env_t *oenv) +static void ana_trans(t_clusters* clust, + int nf, + const char* transfn, + const char* ntransfn, + FILE* log, + t_rgb rlo, + t_rgb rhi, + const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; real **trans, *axis; - int *ntrans; + int* ntrans; int i, ntranst, maxtrans; char buf[STRLEN]; @@ -926,41 +924,41 @@ static void ana_trans(t_clusters *clust, int nf, snew(axis, clust->ncl); for (i = 0; i < clust->ncl; i++) { - axis[i] = i+1; + axis[i] = i + 1; snew(trans[i], clust->ncl); } ntranst = 0; maxtrans = 0; for (i = 1; i < nf; i++) { - if (clust->cl[i] != clust->cl[i-1]) + if (clust->cl[i] != clust->cl[i - 1]) { ntranst++; - ntrans[clust->cl[i-1]-1]++; - ntrans[clust->cl[i]-1]++; - trans[clust->cl[i-1]-1][clust->cl[i]-1]++; - maxtrans = static_cast(std::max(static_cast(maxtrans), trans[clust->cl[i]-1][clust->cl[i-1]-1])); + ntrans[clust->cl[i - 1] - 1]++; + ntrans[clust->cl[i] - 1]++; + trans[clust->cl[i - 1] - 1][clust->cl[i] - 1]++; + maxtrans = static_cast(std::max(static_cast(maxtrans), + trans[clust->cl[i] - 1][clust->cl[i - 1] - 1])); } } - ffprintf_dd(stderr, log, buf, "Counted %d transitions in total, " - "max %d between two specific clusters\n", ntranst, maxtrans); + ffprintf_dd(stderr, log, buf, + "Counted %d transitions in total, " + "max %d between two specific clusters\n", + ntranst, maxtrans); if (transfn) { fp = gmx_ffopen(transfn, "w"); - i = std::min(maxtrans+1, 80); - write_xpm(fp, 0, "Cluster Transitions", "# transitions", - "from cluster", "to cluster", - clust->ncl, clust->ncl, axis, axis, trans, - 0, maxtrans, rlo, rhi, &i); + i = std::min(maxtrans + 1, 80); + write_xpm(fp, 0, "Cluster Transitions", "# transitions", "from cluster", "to cluster", + clust->ncl, clust->ncl, axis, axis, trans, 0, maxtrans, rlo, rhi, &i); gmx_ffclose(fp); } if (ntransfn) { - fp = xvgropen(ntransfn, "Cluster Transitions", "Cluster #", "# transitions", - oenv); + fp = xvgropen(ntransfn, "Cluster Transitions", "Cluster #", "# transitions", oenv); for (i = 0; i < clust->ncl; i++) { - fprintf(fp, "%5d %5d\n", i+1, ntrans[i]); + fprintf(fp, "%5d %5d\n", i + 1, ntrans[i]); } xvgrclose(fp); } @@ -973,28 +971,46 @@ static void ana_trans(t_clusters *clust, int nf, sfree(axis); } -static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, - int natom, t_atoms *atoms, rvec *xtps, - real *mass, rvec **xx, real *time, - matrix *boxes, int *frameindices, - int ifsize, int *fitidx, - int iosize, int *outidx, - const char *trxfn, const char *sizefn, - const char *transfn, const char *ntransfn, - const char *clustidfn, const char *clustndxfn, gmx_bool bAverage, - int write_ncl, int write_nst, real rmsmin, - gmx_bool bFit, FILE *log, t_rgb rlo, t_rgb rhi, - const gmx_output_env_t *oenv) +static void analyze_clusters(int nf, + t_clusters* clust, + real** rmsd, + int natom, + t_atoms* atoms, + rvec* xtps, + real* mass, + rvec** xx, + real* time, + matrix* boxes, + int* frameindices, + int ifsize, + int* fitidx, + int iosize, + int* outidx, + const char* trxfn, + const char* sizefn, + const char* transfn, + const char* ntransfn, + const char* clustidfn, + const char* clustndxfn, + gmx_bool bAverage, + int write_ncl, + int write_nst, + real rmsmin, + gmx_bool bFit, + FILE* log, + t_rgb rlo, + t_rgb rhi, + const gmx_output_env_t* oenv) { - FILE *size_fp = nullptr; - FILE *ndxfn = nullptr; + FILE* size_fp = nullptr; + FILE* ndxfn = nullptr; char buf[STRLEN], buf1[40], buf2[40], buf3[40], *trxsfn; - t_trxstatus *trxout = nullptr; - t_trxstatus *trxsout = nullptr; + t_trxstatus* trxout = nullptr; + t_trxstatus* trxsout = nullptr; int i, i1, cl, nstr, *structure, first = 0, midstr; - gmx_bool *bWrite = nullptr; + gmx_bool* bWrite = nullptr; real r, clrmsd, midrmsd; - rvec *xav = nullptr; + rvec* xav = nullptr; matrix zerobox; clear_mat(zerobox); @@ -1063,7 +1079,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, if (clustidfn) { - FILE *fp = xvgropen(clustidfn, "Clusters", output_env_get_xvgr_tlabel(oenv), "Cluster #", oenv); + FILE* fp = xvgropen(clustidfn, "Clusters", output_env_get_xvgr_tlabel(oenv), "Cluster #", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ s0 symbol 2\n"); @@ -1090,8 +1106,8 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, } snew(structure, nf); - fprintf(log, "\n%3s | %3s %4s | %6s %4s | cluster members\n", - "cl.", "#st", "rmsd", "middle", "rmsd"); + fprintf(log, "\n%3s | %3s %4s | %6s %4s | cluster members\n", "cl.", "#st", "rmsd", "middle", + "rmsd"); for (cl = 1; cl <= clust->ncl; cl++) { /* prepare structures (fit, middle, average) */ @@ -1109,7 +1125,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, { structure[nstr] = i1; nstr++; - if (trxfn && (bAverage || write_ncl) ) + if (trxfn && (bAverage || write_ncl)) { if (bFit) { @@ -1228,7 +1244,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, bWrite[i] = FALSE; } } - if (cl < write_ncl+1 && nstr > write_nst) + if (cl < write_ncl + 1 && nstr > write_nst) { /* Dump all structures for this cluster */ /* generate numbered filename (there is a %d in trxfn!) */ @@ -1249,8 +1265,8 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, } if (bWrite[i]) { - write_trx(trxsout, iosize, outidx, atoms, i, time[structure[i]], boxes[structure[i]], - xx[structure[i]], nullptr, nullptr); + write_trx(trxsout, iosize, outidx, atoms, i, time[structure[i]], + boxes[structure[i]], xx[structure[i]], nullptr, nullptr); } } close_trx(trxsout); @@ -1260,7 +1276,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, { for (i = 0; i < natom; i++) { - svmul(1.0/nstr, xav[i], xav[i]); + svmul(1.0 / nstr, xav[i], xav[i]); } } else @@ -1307,7 +1323,7 @@ static void analyze_clusters(int nf, t_clusters *clust, real **rmsd, } } -static void convert_mat(t_matrix *mat, t_mat *rms) +static void convert_mat(t_matrix* mat, t_mat* rms) { int i, j; @@ -1319,7 +1335,7 @@ static void convert_mat(t_matrix *mat, t_mat *rms) for (j = i; j < mat->nx; j++) { rms->sumrms += rms->mat[i][j]; - rms->maxrms = std::max(rms->maxrms, rms->mat[i][j]); + rms->maxrms = std::max(rms->maxrms, rms->mat[i][j]); if (j != i) { rms->minrms = std::min(rms->minrms, rms->mat[i][j]); @@ -1329,9 +1345,9 @@ static void convert_mat(t_matrix *mat, t_mat *rms) rms->nn = mat->nx; } -int gmx_cluster(int argc, char *argv[]) +int gmx_cluster(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] can cluster structures using several different methods.", "Distances between structures can be determined from a trajectory", "or read from an [REF].xpm[ref] matrix file with the [TT]-dm[tt] option.", @@ -1408,133 +1424,158 @@ int gmx_cluster(int argc, char *argv[]) " of the cluster.", }; - FILE *fp, *log; - int nf = 0, i, i1, i2, j; - int64_t nrms = 0; - - matrix box; - matrix *boxes = nullptr; - rvec *xtps, *usextps, *x1, **xx = nullptr; - const char *fn, *trx_out_fn; - t_clusters clust; - t_mat *rms, *orig = nullptr; - real *eigenvalues; - t_topology top; - int ePBC; - t_atoms useatoms; - real *eigenvectors; - - int isize = 0, ifsize = 0, iosize = 0; - int *index = nullptr, *fitidx = nullptr, *outidx = nullptr, *frameindices = nullptr; - char *grpname; - real rmsd, **d1, **d2, *time = nullptr, time_invfac, *mass = nullptr; - char buf[STRLEN], buf1[80]; - gmx_bool bAnalyze, bUseRmsdCut, bJP_RMSD = FALSE, bReadMat, bReadTraj, bPBC = TRUE; + FILE * fp, *log; + int nf = 0, i, i1, i2, j; + int64_t nrms = 0; + + matrix box; + matrix* boxes = nullptr; + rvec * xtps, *usextps, *x1, **xx = nullptr; + const char *fn, *trx_out_fn; + t_clusters clust; + t_mat * rms, *orig = nullptr; + real* eigenvalues; + t_topology top; + int ePBC; + t_atoms useatoms; + real* eigenvectors; + + int isize = 0, ifsize = 0, iosize = 0; + int * index = nullptr, *fitidx = nullptr, *outidx = nullptr, *frameindices = nullptr; + char* grpname; + real rmsd, **d1, **d2, *time = nullptr, time_invfac, *mass = nullptr; + char buf[STRLEN], buf1[80]; + gmx_bool bAnalyze, bUseRmsdCut, bJP_RMSD = FALSE, bReadMat, bReadTraj, bPBC = TRUE; int method, ncluster = 0; - static const char *methodname[] = { - nullptr, "linkage", "jarvis-patrick", "monte-carlo", - "diagonalization", "gromos", nullptr - }; - enum { - m_null, m_linkage, m_jarvis_patrick, - m_monte_carlo, m_diagonalize, m_gromos, m_nr + static const char* methodname[] = { nullptr, "linkage", "jarvis-patrick", + "monte-carlo", "diagonalization", "gromos", + nullptr }; + enum + { + m_null, + m_linkage, + m_jarvis_patrick, + m_monte_carlo, + m_diagonalize, + m_gromos, + m_nr }; /* Set colors for plotting: white = zero RMS, black = maximum */ - static t_rgb rlo_top = { 1.0, 1.0, 1.0 }; - static t_rgb rhi_top = { 0.0, 0.0, 0.0 }; - static t_rgb rlo_bot = { 1.0, 1.0, 1.0 }; - static t_rgb rhi_bot = { 0.0, 0.0, 1.0 }; - static int nlevels = 40, skip = 1; - static real scalemax = -1.0, rmsdcut = 0.1, rmsmin = 0.0; - gmx_bool bRMSdist = FALSE, bBinary = FALSE, bAverage = FALSE, bFit = TRUE; - static int niter = 10000, nrandom = 0, seed = 0, write_ncl = 0, write_nst = 1, minstruct = 1; - static real kT = 1e-3; - static int M = 10, P = 3; - gmx_output_env_t *oenv; + static t_rgb rlo_top = { 1.0, 1.0, 1.0 }; + static t_rgb rhi_top = { 0.0, 0.0, 0.0 }; + static t_rgb rlo_bot = { 1.0, 1.0, 1.0 }; + static t_rgb rhi_bot = { 0.0, 0.0, 1.0 }; + static int nlevels = 40, skip = 1; + static real scalemax = -1.0, rmsdcut = 0.1, rmsmin = 0.0; + gmx_bool bRMSdist = FALSE, bBinary = FALSE, bAverage = FALSE, bFit = TRUE; + static int niter = 10000, nrandom = 0, seed = 0, write_ncl = 0, write_nst = 1, minstruct = 1; + static real kT = 1e-3; + static int M = 10, P = 3; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - t_pargs pa[] = { - { "-dista", FALSE, etBOOL, {&bRMSdist}, - "Use RMSD of distances instead of RMS deviation" }, - { "-nlevels", FALSE, etINT, {&nlevels}, + t_pargs pa[] = { + { "-dista", FALSE, etBOOL, { &bRMSdist }, "Use RMSD of distances instead of RMS deviation" }, + { "-nlevels", + FALSE, + etINT, + { &nlevels }, "Discretize RMSD matrix in this number of levels" }, - { "-cutoff", FALSE, etREAL, {&rmsdcut}, + { "-cutoff", + FALSE, + etREAL, + { &rmsdcut }, "RMSD cut-off (nm) for two structures to be neighbor" }, - { "-fit", FALSE, etBOOL, {&bFit}, - "Use least squares fitting before RMSD calculation" }, - { "-max", FALSE, etREAL, {&scalemax}, - "Maximum level in RMSD matrix" }, - { "-skip", FALSE, etINT, {&skip}, - "Only analyze every nr-th frame" }, - { "-av", FALSE, etBOOL, {&bAverage}, + { "-fit", FALSE, etBOOL, { &bFit }, "Use least squares fitting before RMSD calculation" }, + { "-max", FALSE, etREAL, { &scalemax }, "Maximum level in RMSD matrix" }, + { "-skip", FALSE, etINT, { &skip }, "Only analyze every nr-th frame" }, + { "-av", + FALSE, + etBOOL, + { &bAverage }, "Write average instead of middle structure for each cluster" }, - { "-wcl", FALSE, etINT, {&write_ncl}, + { "-wcl", + FALSE, + etINT, + { &write_ncl }, "Write the structures for this number of clusters to numbered files" }, - { "-nst", FALSE, etINT, {&write_nst}, + { "-nst", + FALSE, + etINT, + { &write_nst }, "Only write all structures if more than this number of structures per cluster" }, - { "-rmsmin", FALSE, etREAL, {&rmsmin}, + { "-rmsmin", + FALSE, + etREAL, + { &rmsmin }, "minimum rms difference with rest of cluster for writing structures" }, - { "-method", FALSE, etENUM, {methodname}, - "Method for cluster determination" }, - { "-minstruct", FALSE, etINT, {&minstruct}, + { "-method", FALSE, etENUM, { methodname }, "Method for cluster determination" }, + { "-minstruct", + FALSE, + etINT, + { &minstruct }, "Minimum number of structures in cluster for coloring in the [REF].xpm[ref] file" }, - { "-binary", FALSE, etBOOL, {&bBinary}, + { "-binary", + FALSE, + etBOOL, + { &bBinary }, "Treat the RMSD matrix as consisting of 0 and 1, where the cut-off " "is given by [TT]-cutoff[tt]" }, - { "-M", FALSE, etINT, {&M}, + { "-M", + FALSE, + etINT, + { &M }, "Number of nearest neighbors considered for Jarvis-Patrick algorithm, " "0 is use cutoff" }, - { "-P", FALSE, etINT, {&P}, + { "-P", + FALSE, + etINT, + { &P }, "Number of identical nearest neighbors required to form a cluster" }, - { "-seed", FALSE, etINT, {&seed}, + { "-seed", + FALSE, + etINT, + { &seed }, "Random number seed for Monte Carlo clustering algorithm (0 means generate)" }, - { "-niter", FALSE, etINT, {&niter}, - "Number of iterations for MC" }, - { "-nrandom", FALSE, etINT, {&nrandom}, + { "-niter", FALSE, etINT, { &niter }, "Number of iterations for MC" }, + { "-nrandom", + FALSE, + etINT, + { &nrandom }, "The first iterations for MC may be done complete random, to shuffle the frames" }, - { "-kT", FALSE, etREAL, {&kT}, + { "-kT", + FALSE, + etREAL, + { &kT }, "Boltzmann weighting factor for Monte Carlo optimization " "(zero turns off uphill steps)" }, - { "-pbc", FALSE, etBOOL, - { &bPBC }, "PBC check" } + { "-pbc", FALSE, etBOOL, { &bPBC }, "PBC check" } }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffOPTRD }, - { efTPS, "-s", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXPM, "-dm", "rmsd", ffOPTRD }, - { efXPM, "-om", "rmsd-raw", ffWRITE }, - { efXPM, "-o", "rmsd-clust", ffWRITE }, - { efLOG, "-g", "cluster", ffWRITE }, - { efXVG, "-dist", "rmsd-dist", ffOPTWR }, - { efXVG, "-ev", "rmsd-eig", ffOPTWR }, - { efXVG, "-conv", "mc-conv", ffOPTWR }, - { efXVG, "-sz", "clust-size", ffOPTWR}, - { efXPM, "-tr", "clust-trans", ffOPTWR}, - { efXVG, "-ntr", "clust-trans", ffOPTWR}, - { efXVG, "-clid", "clust-id", ffOPTWR}, - { efTRX, "-cl", "clusters.pdb", ffOPTWR }, - { efNDX, "-clndx", "clusters.ndx", ffOPTWR } + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffOPTRD }, { efTPS, "-s", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXPM, "-dm", "rmsd", ffOPTRD }, + { efXPM, "-om", "rmsd-raw", ffWRITE }, { efXPM, "-o", "rmsd-clust", ffWRITE }, + { efLOG, "-g", "cluster", ffWRITE }, { efXVG, "-dist", "rmsd-dist", ffOPTWR }, + { efXVG, "-ev", "rmsd-eig", ffOPTWR }, { efXVG, "-conv", "mc-conv", ffOPTWR }, + { efXVG, "-sz", "clust-size", ffOPTWR }, { efXPM, "-tr", "clust-trans", ffOPTWR }, + { efXVG, "-ntr", "clust-trans", ffOPTWR }, { efXVG, "-clid", "clust-id", ffOPTWR }, + { efTRX, "-cl", "clusters.pdb", ffOPTWR }, { efNDX, "-clndx", "clusters.ndx", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } /* parse options */ - bReadMat = opt2bSet("-dm", NFILE, fnm); - bReadTraj = opt2bSet("-f", NFILE, fnm) || !bReadMat; - if (opt2parg_bSet("-av", asize(pa), pa) || - opt2parg_bSet("-wcl", asize(pa), pa) || - opt2parg_bSet("-nst", asize(pa), pa) || - opt2parg_bSet("-rmsmin", asize(pa), pa) || - opt2bSet("-cl", NFILE, fnm) ) + bReadMat = opt2bSet("-dm", NFILE, fnm); + bReadTraj = opt2bSet("-f", NFILE, fnm) || !bReadMat; + if (opt2parg_bSet("-av", asize(pa), pa) || opt2parg_bSet("-wcl", asize(pa), pa) + || opt2parg_bSet("-nst", asize(pa), pa) || opt2parg_bSet("-rmsmin", asize(pa), pa) + || opt2bSet("-cl", NFILE, fnm)) { trx_out_fn = opt2fn("-cl", NFILE, fnm); } @@ -1544,15 +1585,16 @@ int gmx_cluster(int argc, char *argv[]) } if (bReadMat && output_env_get_time_factor(oenv) != 1) { - fprintf(stderr, - "\nWarning: assuming the time unit in %s is %s\n", + fprintf(stderr, "\nWarning: assuming the time unit in %s is %s\n", opt2fn("-dm", NFILE, fnm), output_env_get_time_unit(oenv).c_str()); } if (trx_out_fn && !bReadTraj) { - fprintf(stderr, "\nWarning: " + fprintf(stderr, + "\nWarning: " "cannot write cluster structures without reading trajectory\n" - " ignoring option -cl %s\n", trx_out_fn); + " ignoring option -cl %s\n", + trx_out_fn); } method = 1; @@ -1565,8 +1607,7 @@ int gmx_cluster(int argc, char *argv[]) gmx_fatal(FARGS, "Invalid method"); } - bAnalyze = (method == m_linkage || method == m_jarvis_patrick || - method == m_gromos ); + bAnalyze = (method == m_linkage || method == m_jarvis_patrick || method == m_gromos); /* Open log file */ log = ftp2FILE(efLOG, NFILE, fnm, "w"); @@ -1608,7 +1649,7 @@ int gmx_cluster(int argc, char *argv[]) } else /* method != m_jarvis */ { - bUseRmsdCut = ( bBinary || method == m_linkage || method == m_gromos ); + bUseRmsdCut = (bBinary || method == m_linkage || method == m_gromos); } if (bUseRmsdCut && method != m_jarvis_patrick) { @@ -1628,22 +1669,18 @@ int gmx_cluster(int argc, char *argv[]) if (bReadTraj) { /* don't read mass-database as masses (and top) are not used */ - read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtps, nullptr, box, - TRUE); + read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtps, nullptr, box, TRUE); if (bPBC) { gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr); } - fprintf(stderr, "\nSelect group for least squares fit%s:\n", - bReadMat ? "" : " and RMSD calculation"); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), - 1, &ifsize, &fitidx, &grpname); + fprintf(stderr, "\nSelect group for least squares fit%s:\n", bReadMat ? "" : " and RMSD calculation"); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifsize, &fitidx, &grpname); if (trx_out_fn) { fprintf(stderr, "\nSelect group for output:\n"); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), - 1, &iosize, &outidx, &grpname); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &iosize, &outidx, &grpname); /* merge and convert both index groups: */ /* first copy outidx to index. let outidx refer to elements in index */ snew(index, iosize); @@ -1721,13 +1758,14 @@ int gmx_cluster(int argc, char *argv[]) fprintf(stderr, "\n"); if (readmat[0].nx != readmat[0].ny) { - gmx_fatal(FARGS, "Matrix (%dx%d) is not square", - readmat[0].nx, readmat[0].ny); + gmx_fatal(FARGS, "Matrix (%dx%d) is not square", readmat[0].nx, readmat[0].ny); } if (bReadTraj && bAnalyze && (readmat[0].nx != nf)) { - gmx_fatal(FARGS, "Matrix size (%dx%d) does not match the number of " - "frames (%d)", readmat[0].nx, readmat[0].ny, nf); + gmx_fatal(FARGS, + "Matrix size (%dx%d) does not match the number of " + "frames (%d)", + readmat[0].nx, readmat[0].ny, nf); } nf = readmat[0].nx; @@ -1744,10 +1782,10 @@ int gmx_cluster(int argc, char *argv[]) nlevels = gmx::ssize(readmat[0].map); } - else /* !bReadMat */ + else /* !bReadMat */ { rms = init_mat(nf, method == m_diagonalize); - nrms = (static_cast(nf)*static_cast(nf-1))/2; + nrms = (static_cast(nf) * static_cast(nf - 1)) / 2; if (!bRMSdist) { fprintf(stderr, "Computing %dx%d RMS deviation matrix\n", nf, nf); @@ -1755,7 +1793,7 @@ int gmx_cluster(int argc, char *argv[]) snew(x1, isize); for (i1 = 0; i1 < nf; i1++) { - for (i2 = i1+1; i2 < nf; i2++) + for (i2 = i1 + 1; i2 < nf; i2++) { for (i = 0; i < isize; i++) { @@ -1768,8 +1806,11 @@ int gmx_cluster(int argc, char *argv[]) rmsd = rmsdev(isize, mass, xx[i2], x1); set_mat_entry(rms, i1, i2, rmsd); } - nrms -= nf-i1-1; - fprintf(stderr, "\r# RMSD calculations left: " "%" PRId64 " ", nrms); + nrms -= nf - i1 - 1; + fprintf(stderr, + "\r# RMSD calculations left: " + "%" PRId64 " ", + nrms); fflush(stderr); } sfree(x1); @@ -1789,13 +1830,16 @@ int gmx_cluster(int argc, char *argv[]) for (i1 = 0; i1 < nf; i1++) { calc_dist(isize, xx[i1], d1); - for (i2 = i1+1; (i2 < nf); i2++) + for (i2 = i1 + 1; (i2 < nf); i2++) { calc_dist(isize, xx[i2], d2); set_mat_entry(rms, i1, i2, rms_dist(isize, d1, d2)); } - nrms -= nf-i1-1; - fprintf(stderr, "\r# RMSD calculations left: " "%" PRId64 " ", nrms); + nrms -= nf - i1 - 1; + fprintf(stderr, + "\r# RMSD calculations left: " + "%" PRId64 " ", + nrms); fflush(stderr); } /* Clean up work arrays */ @@ -1809,25 +1853,24 @@ int gmx_cluster(int argc, char *argv[]) } fprintf(stderr, "\n\n"); } - ffprintf_gg(stderr, log, buf, "The RMSD ranges from %g to %g nm\n", - rms->minrms, rms->maxrms); - ffprintf_g(stderr, log, buf, "Average RMSD is %g\n", 2*rms->sumrms/(nf*(nf-1))); + ffprintf_gg(stderr, log, buf, "The RMSD ranges from %g to %g nm\n", rms->minrms, rms->maxrms); + ffprintf_g(stderr, log, buf, "Average RMSD is %g\n", 2 * rms->sumrms / (nf * (nf - 1))); ffprintf_d(stderr, log, buf, "Number of structures for matrix %d\n", nf); ffprintf_g(stderr, log, buf, "Energy of the matrix is %g.\n", mat_energy(rms)); - if (bUseRmsdCut && (rmsdcut < rms->minrms || rmsdcut > rms->maxrms) ) + if (bUseRmsdCut && (rmsdcut < rms->minrms || rmsdcut > rms->maxrms)) { - fprintf(stderr, "WARNING: rmsd cutoff %g is outside range of rmsd values " - "%g to %g\n", rmsdcut, rms->minrms, rms->maxrms); + fprintf(stderr, + "WARNING: rmsd cutoff %g is outside range of rmsd values " + "%g to %g\n", + rmsdcut, rms->minrms, rms->maxrms); } - if (bAnalyze && (rmsmin < rms->minrms) ) + if (bAnalyze && (rmsmin < rms->minrms)) { - fprintf(stderr, "WARNING: rmsd minimum %g is below lowest rmsd value %g\n", - rmsmin, rms->minrms); + fprintf(stderr, "WARNING: rmsd minimum %g is below lowest rmsd value %g\n", rmsmin, rms->minrms); } - if (bAnalyze && (rmsmin > rmsdcut) ) + if (bAnalyze && (rmsmin > rmsdcut)) { - fprintf(stderr, "WARNING: rmsd minimum %g is above rmsd cutoff %g\n", - rmsmin, rmsdcut); + fprintf(stderr, "WARNING: rmsd minimum %g is above rmsd cutoff %g\n", rmsmin, rmsdcut); } /* Plot the rmsd distribution */ @@ -1861,13 +1904,13 @@ int gmx_cluster(int argc, char *argv[]) case m_diagonalize: /* Do a diagonalization */ snew(eigenvalues, nf); - snew(eigenvectors, nf*nf); - std::memcpy(eigenvectors, rms->mat[0], nf*nf*sizeof(real)); + snew(eigenvectors, nf * nf); + std::memcpy(eigenvectors, rms->mat[0], nf * nf * sizeof(real)); eigensolver(eigenvectors, nf, 0, nf, eigenvalues, rms->mat[0]); sfree(eigenvectors); - fp = xvgropen(opt2fn("-ev", NFILE, fnm), "RMSD matrix Eigenvalues", - "Eigenvector index", "Eigenvalues (nm\\S2\\N)", oenv); + fp = xvgropen(opt2fn("-ev", NFILE, fnm), "RMSD matrix Eigenvalues", "Eigenvector index", + "Eigenvalues (nm\\S2\\N)", oenv); for (i = 0; (i < nf); i++) { fprintf(fp, "%10d %10g\n", i, eigenvalues[i]); @@ -1878,23 +1921,18 @@ int gmx_cluster(int argc, char *argv[]) orig = init_mat(rms->nn, FALSE); orig->nn = rms->nn; copy_t_mat(orig, rms); - mc_optimize(log, rms, time, niter, nrandom, seed, kT, - opt2fn_null("-conv", NFILE, fnm), oenv); + mc_optimize(log, rms, time, niter, nrandom, seed, kT, opt2fn_null("-conv", NFILE, fnm), oenv); break; case m_jarvis_patrick: jarvis_patrick(rms->nn, rms->mat, M, P, bJP_RMSD ? rmsdcut : -1, &clust); break; - case m_gromos: - gromos(rms->nn, rms->mat, rmsdcut, &clust); - break; - default: - gmx_fatal(FARGS, "DEATH HORROR unknown method \"%s\"", methodname[0]); + case m_gromos: gromos(rms->nn, rms->mat, rmsdcut, &clust); break; + default: gmx_fatal(FARGS, "DEATH HORROR unknown method \"%s\"", methodname[0]); } if (method == m_monte_carlo || method == m_diagonalize) { - fprintf(stderr, "Energy of the matrix after clustering is %g.\n", - mat_energy(rms)); + fprintf(stderr, "Energy of the matrix after clustering is %g.\n", mat_energy(rms)); } if (bAnalyze) @@ -1914,20 +1952,16 @@ int gmx_cluster(int argc, char *argv[]) { useatoms.atomname[i] = top.atoms.atomname[index[i]]; useatoms.atom[i].resind = top.atoms.atom[index[i]].resind; - useatoms.nres = std::max(useatoms.nres, useatoms.atom[i].resind+1); + useatoms.nres = std::max(useatoms.nres, useatoms.atom[i].resind + 1); copy_rvec(xtps[index[i]], usextps[i]); } useatoms.nr = isize; - analyze_clusters(nf, &clust, rms->mat, isize, &useatoms, usextps, mass, xx, time, boxes, frameindices, - ifsize, fitidx, iosize, outidx, - bReadTraj ? trx_out_fn : nullptr, - opt2fn_null("-sz", NFILE, fnm), - opt2fn_null("-tr", NFILE, fnm), - opt2fn_null("-ntr", NFILE, fnm), - opt2fn_null("-clid", NFILE, fnm), - opt2fn_null("-clndx", NFILE, fnm), - bAverage, write_ncl, write_nst, rmsmin, bFit, log, - rlo_bot, rhi_bot, oenv); + analyze_clusters(nf, &clust, rms->mat, isize, &useatoms, usextps, mass, xx, time, boxes, + frameindices, ifsize, fitidx, iosize, outidx, + bReadTraj ? trx_out_fn : nullptr, opt2fn_null("-sz", NFILE, fnm), + opt2fn_null("-tr", NFILE, fnm), opt2fn_null("-ntr", NFILE, fnm), + opt2fn_null("-clid", NFILE, fnm), opt2fn_null("-clndx", NFILE, fnm), + bAverage, write_ncl, write_nst, rmsmin, bFit, log, rlo_bot, rhi_bot, oenv); sfree(boxes); sfree(frameindices); } @@ -1938,7 +1972,7 @@ int gmx_cluster(int argc, char *argv[]) /* Make the clustering visible */ for (i2 = 0; (i2 < nf); i2++) { - for (i1 = i2+1; (i1 < nf); i1++) + for (i1 = i2 + 1; (i1 < nf); i1++) { if (rms->mat[i1][i2] != 0.0F) { @@ -1959,32 +1993,28 @@ int gmx_cluster(int argc, char *argv[]) else { auto timeLabel = output_env_get_time_label(oenv); - auto title = gmx::formatString("RMS%sDeviation / Cluster Index", - bRMSdist ? " Distance " : " "); + auto title = gmx::formatString("RMS%sDeviation / Cluster Index", bRMSdist ? " Distance " : " "); if (minstruct > 1) { - write_xpm_split(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, - nf, nf, time, time, rms->mat, 0.0, rms->maxrms, &nlevels, - rlo_top, rhi_top, 0.0, ncluster, + write_xpm_split(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time, + rms->mat, 0.0, rms->maxrms, &nlevels, rlo_top, rhi_top, 0.0, ncluster, &ncluster, TRUE, rlo_bot, rhi_bot); } else { - write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, - nf, nf, time, time, rms->mat, 0.0, rms->maxrms, - rlo_top, rhi_top, &nlevels); + write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time, rms->mat, + 0.0, rms->maxrms, rlo_top, rhi_top, &nlevels); } } fprintf(stderr, "\n"); gmx_ffclose(fp); if (nullptr != orig) { - fp = opt2FILE("-om", NFILE, fnm, "w"); + fp = opt2FILE("-om", NFILE, fnm, "w"); auto timeLabel = output_env_get_time_label(oenv); auto title = gmx::formatString("RMS%sDeviation", bRMSdist ? " Distance " : " "); - write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, - nf, nf, time, time, orig->mat, 0.0, orig->maxrms, - rlo_top, rhi_top, &nlevels); + write_xpm(fp, 0, title, "RMSD (nm)", timeLabel, timeLabel, nf, nf, time, time, orig->mat, + 0.0, orig->maxrms, rlo_top, rhi_top, &nlevels); gmx_ffclose(fp); done_mat(&orig); sfree(orig); diff --git a/src/gromacs/gmxana/gmx_clustsize.cpp b/src/gromacs/gmxana/gmx_clustsize.cpp index 7dbf95759f..28cc178ca7 100644 --- a/src/gromacs/gmxana/gmx_clustsize.cpp +++ b/src/gromacs/gmxana/gmx_clustsize.cpp @@ -64,45 +64,57 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -static void clust_size(const char *ndx, const char *trx, const char *xpm, - const char *xpmw, const char *ncl, const char *acl, - const char *mcl, const char *histo, const char *tempf, - const char *mcn, gmx_bool bMol, gmx_bool bPBC, const char *tpr, - real cut, int nskip, int nlevels, - t_rgb rmid, t_rgb rhi, int ndf, - const gmx_output_env_t *oenv) +static void clust_size(const char* ndx, + const char* trx, + const char* xpm, + const char* xpmw, + const char* ncl, + const char* acl, + const char* mcl, + const char* histo, + const char* tempf, + const char* mcn, + gmx_bool bMol, + gmx_bool bPBC, + const char* tpr, + real cut, + int nskip, + int nlevels, + t_rgb rmid, + t_rgb rhi, + int ndf, + const gmx_output_env_t* oenv) { - FILE *fp, *gp, *hp, *tp; - int *index = nullptr; - int nindex, natoms; - t_trxstatus *status; - rvec *x = nullptr, *v = nullptr, dx; - t_pbc pbc; - gmx_bool bSame, bTPRwarn = TRUE; + FILE * fp, *gp, *hp, *tp; + int* index = nullptr; + int nindex, natoms; + t_trxstatus* status; + rvec * x = nullptr, *v = nullptr, dx; + t_pbc pbc; + gmx_bool bSame, bTPRwarn = TRUE; /* Topology stuff */ - t_trxframe fr; - TpxFileHeader tpxh; - gmx_mtop_t *mtop = nullptr; - int ePBC = -1; - int ii, jj; - real temp, tfac; + t_trxframe fr; + TpxFileHeader tpxh; + gmx_mtop_t* mtop = nullptr; + int ePBC = -1; + int ii, jj; + real temp, tfac; /* Cluster size distribution (matrix) */ - real **cs_dist = nullptr; - real tf, dx2, cut2, *t_x = nullptr, *t_y, cmid, cmax, cav, ekin; - int i, j, k, ai, aj, ci, cj, nframe, nclust, n_x, max_size = 0; - int *clust_index, *clust_size, max_clust_size, max_clust_ind, nav, nhisto; - t_rgb rlo = { 1.0, 1.0, 1.0 }; - int frameCounter = 0; - real frameTime; + real** cs_dist = nullptr; + real tf, dx2, cut2, *t_x = nullptr, *t_y, cmid, cmax, cav, ekin; + int i, j, k, ai, aj, ci, cj, nframe, nclust, n_x, max_size = 0; + int * clust_index, *clust_size, max_clust_size, max_clust_ind, nav, nhisto; + t_rgb rlo = { 1.0, 1.0, 1.0 }; + int frameCounter = 0; + real frameTime; clear_trxframe(&fr, TRUE); auto timeLabel = output_env_get_time_label(oenv); - tf = output_env_get_time_factor(oenv); - fp = xvgropen(ncl, "Number of clusters", timeLabel, "N", oenv); - gp = xvgropen(acl, "Average cluster size", timeLabel, "#molecules", oenv); - hp = xvgropen(mcl, "Max cluster size", timeLabel, "#molecules", oenv); - tp = xvgropen(tempf, "Temperature of largest cluster", timeLabel, "T (K)", - oenv); + tf = output_env_get_time_factor(oenv); + fp = xvgropen(ncl, "Number of clusters", timeLabel, "N", oenv); + gp = xvgropen(acl, "Average cluster size", timeLabel, "#molecules", oenv); + hp = xvgropen(mcl, "Max cluster size", timeLabel, "#molecules", oenv); + tp = xvgropen(tempf, "Temperature of largest cluster", timeLabel, "T (K)", oenv); if (!read_first_frame(oenv, &status, trx, &fr, TRX_NEED_X | TRX_READ_V)) { @@ -118,8 +130,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, tpxh = readTpxHeader(tpr, true); if (tpxh.natoms != natoms) { - gmx_fatal(FARGS, "tpr (%d atoms) and trajectory (%d atoms) do not match!", - tpxh.natoms, natoms); + gmx_fatal(FARGS, "tpr (%d atoms) and trajectory (%d atoms) do not match!", tpxh.natoms, natoms); } ePBC = read_tpx(tpr, nullptr, nullptr, &natoms, nullptr, nullptr, mtop); } @@ -129,7 +140,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, } else { - tfac = ndf/(3.0*natoms); + tfac = ndf / (3.0 * natoms); } gmx::RangePartitioning mols; @@ -137,8 +148,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { if (ndx) { - printf("Using molecules rather than atoms. Not reading index file %s\n", - ndx); + printf("Using molecules rather than atoms. Not reading index file %s\n", ndx); } GMX_RELEASE_ASSERT(mtop != nullptr, "Trying to access mtop->mols from NULL mtop pointer"); mols = gmx_mtop_molecules(*mtop); @@ -153,20 +163,20 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, } else { - char *gname; + char* gname; rd_index(ndx, 1, &nindex, &index, &gname); sfree(gname); } snew(clust_index, nindex); snew(clust_size, nindex); - cut2 = cut*cut; + cut2 = cut * cut; nframe = 0; n_x = 0; snew(t_y, nindex); for (i = 0; (i < nindex); i++) { - t_y[i] = i+1; + t_y[i] = i + 1; } max_clust_size = 1; max_clust_ind = -1; @@ -188,7 +198,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, /* Cluster index is indexed with atom index number */ clust_index[i] = i; /* Cluster size is indexed with cluster number */ - clust_size[i] = 1; + clust_size[i] = 1; } /* Loop over atoms */ @@ -198,7 +208,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, ci = clust_index[i]; /* Loop over atoms (only half a matrix) */ - for (j = i+1; (j < nindex); j++) + for (j = i + 1; (j < nindex); j++) { cj = clust_index[j]; @@ -210,7 +220,8 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, /* Compute distance */ if (bMol) { - GMX_RELEASE_ASSERT(mols.numBlocks() > 0, "Cannot access index[] from empty mols"); + GMX_RELEASE_ASSERT(mols.numBlocks() > 0, + "Cannot access index[] from empty mols"); bSame = FALSE; for (ii = mols.block(ai).begin(); !bSame && ii < mols.block(ai).end(); ii++) { @@ -280,9 +291,9 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { frameTime = ++frameCounter; } - t_x[n_x-1] = frameTime*tf; + t_x[n_x - 1] = frameTime * tf; srenew(cs_dist, n_x); - snew(cs_dist[n_x-1], nindex); + snew(cs_dist[n_x - 1], nindex); nclust = 0; cav = 0; nav = 0; @@ -297,8 +308,8 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, if (ci > 0) { nclust++; - cs_dist[n_x-1][ci-1] += 1.0; - max_size = std::max(max_size, ci); + cs_dist[n_x - 1][ci - 1] += 1.0; + max_size = std::max(max_size, ci); if (ci > 1) { cav += ci; @@ -309,7 +320,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, fprintf(fp, "%14.6e %10d\n", frameTime, nclust); if (nav > 0) { - fprintf(gp, "%14.6e %10.3f\n", frameTime, cav/nav); + fprintf(gp, "%14.6e %10.3f\n", frameTime, cav / nav); } fprintf(hp, "%14.6e %10d\n", frameTime, max_clust_size); } @@ -335,19 +346,18 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { if (clust_index[i] == max_clust_ind) { - ai = index[i]; - real m = mtopGetAtomMass(mtop, ai, &molb); - ekin += 0.5*m*iprod(v[ai], v[ai]); + ai = index[i]; + real m = mtopGetAtomMass(mtop, ai, &molb); + ekin += 0.5 * m * iprod(v[ai], v[ai]); } } - temp = (ekin*2.0)/(3.0*tfac*max_clust_size*BOLTZ); + temp = (ekin * 2.0) / (3.0 * tfac * max_clust_size * BOLTZ); fprintf(tp, "%10.3f %10.3f\n", frameTime, temp); } } } nframe++; - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); close_trx(status); done_frame(&fr); xvgrclose(fp); @@ -365,15 +375,16 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { if (bMol) { - GMX_RELEASE_ASSERT(mols.numBlocks() > 0, "Cannot access index[] from empty mols"); + GMX_RELEASE_ASSERT(mols.numBlocks() > 0, + "Cannot access index[] from empty mols"); for (int j : mols.block(i)) { - fprintf(fp, "%d\n", j+1); + fprintf(fp, "%d\n", j + 1); } } else { - fprintf(fp, "%d\n", index[i]+1); + fprintf(fp, "%d\n", index[i] + 1); } } } @@ -391,10 +402,10 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { nelem += cs_dist[i][j]; } - fprintf(fp, "%5d %8.3f\n", j+1, nelem/n_x); - nhisto += static_cast((j+1)*nelem/n_x); + fprintf(fp, "%5d %8.3f\n", j + 1, nelem / n_x); + nhisto += static_cast((j + 1) * nelem / n_x); } - fprintf(fp, "%5d %8.3f\n", j+1, 0.0); + fprintf(fp, "%5d %8.3f\n", j + 1, 0.0); xvgrclose(fp); fprintf(stderr, "Total number of atoms in clusters = %d\n", nhisto); @@ -418,9 +429,8 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size); cmid = 1; fp = gmx_ffopen(xpm, "w"); - write_xpm3(fp, 0, "Cluster size distribution", "# clusters", timeLabel, "Size", - n_x, max_size, t_x, t_y, cs_dist, 0, cmid, cmax, - rlo, rmid, rhi, &nlevels); + write_xpm3(fp, 0, "Cluster size distribution", "# clusters", timeLabel, "Size", n_x, max_size, + t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels); gmx_ffclose(fp); cmid = 100.0; cmax = 0.0; @@ -428,7 +438,7 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, { for (j = 0; (j < max_size); j++) { - cs_dist[i][j] *= (j+1); + cs_dist[i][j] *= (j + 1); if ((cs_dist[i][j] > 0) && (cs_dist[i][j] < cmid)) { cmid = cs_dist[i][j]; @@ -438,9 +448,8 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, } fprintf(stderr, "cmid: %g, cmax: %g, max_size: %d\n", cmid, cmax, max_size); fp = gmx_ffopen(xpmw, "w"); - write_xpm3(fp, 0, "Weighted cluster size distribution", "Fraction", timeLabel, - "Size", n_x, max_size, t_x, t_y, cs_dist, 0, cmid, cmax, - rlo, rmid, rhi, &nlevels); + write_xpm3(fp, 0, "Weighted cluster size distribution", "Fraction", timeLabel, "Size", n_x, + max_size, t_x, t_y, cs_dist, 0, cmid, cmax, rlo, rmid, rhi, &nlevels); gmx_ffclose(fp); delete mtop; sfree(t_x); @@ -455,9 +464,9 @@ static void clust_size(const char *ndx, const char *trx, const char *xpm, sfree(index); } -int gmx_clustsize(int argc, char *argv[]) +int gmx_clustsize(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the size distributions of molecular/atomic clusters in", "the gas phase. The output is given in the form of an [REF].xpm[ref] file.", "The total number of clusters is written to an [REF].xvg[ref] file.[PAR]", @@ -476,64 +485,79 @@ int gmx_clustsize(int argc, char *argv[]) "atom numbers of the largest cluster." }; - real cutoff = 0.35; - int nskip = 0; - int nlevels = 20; - int ndf = -1; - gmx_bool bMol = FALSE; - gmx_bool bPBC = TRUE; - rvec rlo = { 1.0, 1.0, 0.0 }; - rvec rhi = { 0.0, 0.0, 1.0 }; + real cutoff = 0.35; + int nskip = 0; + int nlevels = 20; + int ndf = -1; + gmx_bool bMol = FALSE; + gmx_bool bPBC = TRUE; + rvec rlo = { 1.0, 1.0, 0.0 }; + rvec rhi = { 0.0, 0.0, 1.0 }; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; - t_pargs pa[] = { - { "-cut", FALSE, etREAL, {&cutoff}, + t_pargs pa[] = { + { "-cut", + FALSE, + etREAL, + { &cutoff }, "Largest distance (nm) to be considered in a cluster" }, - { "-mol", FALSE, etBOOL, {&bMol}, + { "-mol", + FALSE, + etBOOL, + { &bMol }, "Cluster molecules rather than atoms (needs [REF].tpr[ref] file)" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Use periodic boundary conditions" }, - { "-nskip", FALSE, etINT, {&nskip}, - "Number of frames to skip between writing" }, - { "-nlevels", FALSE, etINT, {&nlevels}, + { "-pbc", FALSE, etBOOL, { &bPBC }, "Use periodic boundary conditions" }, + { "-nskip", FALSE, etINT, { &nskip }, "Number of frames to skip between writing" }, + { "-nlevels", + FALSE, + etINT, + { &nlevels }, "Number of levels of grey in [REF].xpm[ref] output" }, - { "-ndf", FALSE, etINT, {&ndf}, - "Number of degrees of freedom of the entire system for temperature calculation. If not set, the number of atoms times three is used." }, - { "-rgblo", FALSE, etRVEC, {rlo}, + { "-ndf", + FALSE, + etINT, + { &ndf }, + "Number of degrees of freedom of the entire system for temperature calculation. " + "If not set, the number of atoms times three is used." }, + { "-rgblo", + FALSE, + etRVEC, + { rlo }, "RGB values for the color of the lowest occupied cluster size" }, - { "-rgbhi", FALSE, etRVEC, {rhi}, + { "-rgbhi", + FALSE, + etRVEC, + { rhi }, "RGB values for the color of the highest occupied cluster size" } }; #define NPA asize(pa) - const char *fnNDX, *fnTPR; - t_rgb rgblo, rgbhi; + const char *fnNDX, *fnTPR; + t_rgb rgblo, rgbhi; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXPM, "-o", "csize", ffWRITE }, - { efXPM, "-ow", "csizew", ffWRITE }, - { efXVG, "-nc", "nclust", ffWRITE }, - { efXVG, "-mc", "maxclust", ffWRITE }, - { efXVG, "-ac", "avclust", ffWRITE }, - { efXVG, "-hc", "histo-clust", ffWRITE }, - { efXVG, "-temp", "temp", ffOPTWR }, + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPR, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXPM, "-o", "csize", ffWRITE }, + { efXPM, "-ow", "csizew", ffWRITE }, { efXVG, "-nc", "nclust", ffWRITE }, + { efXVG, "-mc", "maxclust", ffWRITE }, { efXVG, "-ac", "avclust", ffWRITE }, + { efXVG, "-hc", "histo-clust", ffWRITE }, { efXVG, "-temp", "temp", ffOPTWR }, { efNDX, "-mcn", "maxclust", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, + NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } fnNDX = ftp2fn_null(efNDX, NFILE, fnm); - rgblo.r = rlo[XX]; rgblo.g = rlo[YY]; rgblo.b = rlo[ZZ]; - rgbhi.r = rhi[XX]; rgbhi.g = rhi[YY]; rgbhi.b = rhi[ZZ]; + rgblo.r = rlo[XX]; + rgblo.g = rlo[YY]; + rgblo.b = rlo[ZZ]; + rgbhi.r = rhi[XX]; + rgbhi.g = rhi[YY]; + rgbhi.b = rhi[ZZ]; fnTPR = ftp2fn_null(efTPR, NFILE, fnm); if (bMol && !fnTPR) @@ -541,13 +565,10 @@ int gmx_clustsize(int argc, char *argv[]) gmx_fatal(FARGS, "You need a tpr file for the -mol option"); } - clust_size(fnNDX, ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm), - opt2fn("-ow", NFILE, fnm), - opt2fn("-nc", NFILE, fnm), opt2fn("-ac", NFILE, fnm), - opt2fn("-mc", NFILE, fnm), opt2fn("-hc", NFILE, fnm), - opt2fn("-temp", NFILE, fnm), opt2fn("-mcn", NFILE, fnm), - bMol, bPBC, fnTPR, - cutoff, nskip, nlevels, rgblo, rgbhi, ndf, oenv); + clust_size(fnNDX, ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm), opt2fn("-ow", NFILE, fnm), + opt2fn("-nc", NFILE, fnm), opt2fn("-ac", NFILE, fnm), opt2fn("-mc", NFILE, fnm), + opt2fn("-hc", NFILE, fnm), opt2fn("-temp", NFILE, fnm), opt2fn("-mcn", NFILE, fnm), + bMol, bPBC, fnTPR, cutoff, nskip, nlevels, rgblo, rgbhi, ndf, oenv); output_env_done(oenv); diff --git a/src/gromacs/gmxana/gmx_confrms.cpp b/src/gromacs/gmxana/gmx_confrms.cpp index 0ad9d7c3fa..73d2678989 100644 --- a/src/gromacs/gmxana/gmx_confrms.cpp +++ b/src/gromacs/gmxana/gmx_confrms.cpp @@ -63,7 +63,7 @@ static const int NOTSET = -9368163; -static void calc_rm_cm(int isize, const int index[], const t_atoms *atoms, rvec x[], rvec xcm) +static void calc_rm_cm(int isize, const int index[], const t_atoms* atoms, rvec x[], rvec xcm) { int i, d; real tm, m; @@ -76,11 +76,11 @@ static void calc_rm_cm(int isize, const int index[], const t_atoms *atoms, rvec m = atoms->atom[index[i]].m; for (d = 0; d < DIM; d++) { - xcm[d] += m*x[index[i]][d]; + xcm[d] += m * x[index[i]][d]; } tm += m; } - svmul(1/tm, xcm, xcm); + svmul(1 / tm, xcm, xcm); for (i = 0; i < atoms->nr; i++) { rvec_dec(x[i], xcm); @@ -96,7 +96,7 @@ static int build_res_index(int isize, const int index[], t_atom atom[], int rind r++; for (i = 1; i < isize; i++) { - if (atom[index[i]].resind != rindex[r-1]) + if (atom[index[i]].resind != rindex[r - 1]) { rindex[r] = atom[index[i]].resind; r++; @@ -106,7 +106,7 @@ static int build_res_index(int isize, const int index[], t_atom atom[], int rind return r; } -static int find_res_end(int i, int isize, const int index[], const t_atoms *atoms) +static int find_res_end(int i, int isize, const int index[], const t_atoms* atoms) { int rnr; @@ -127,16 +127,20 @@ static int debug_strcmp(char s1[], char s2[]) return std::strcmp(s1, s2); } -static int find_next_match_atoms_in_res(int *i1, const int index1[], - int m1, char **atnms1[], - int *i2, const int index2[], - int m2, char **atnms2[]) +static int find_next_match_atoms_in_res(int* i1, + const int index1[], + int m1, + char** atnms1[], + int* i2, + const int index2[], + int m2, + char** atnms2[]) { int dx, dy, dmax, cmp; gmx_bool bFW = FALSE; cmp = NOTSET; - dmax = std::max(m1-*i1, m2-*i2); + dmax = std::max(m1 - *i1, m2 - *i2); for (dx = 0, dy = 0; dx < dmax && cmp != 0; dx++) { for (dy = dx; dy < dmax && cmp != 0; dy++) @@ -148,22 +152,22 @@ static int find_next_match_atoms_in_res(int *i1, const int index1[], fprintf(debug, "."); } cmp = NOTSET; - if (*i1+dx < m1 && *i2+dy < m2) + if (*i1 + dx < m1 && *i2 + dy < m2) { bFW = TRUE; - cmp = debug_strcmp(*atnms1[index1[*i1+dx]], *atnms2[index2[*i2+dy]]); + cmp = debug_strcmp(*atnms1[index1[*i1 + dx]], *atnms2[index2[*i2 + dy]]); if (debug) { - fprintf(debug, "(%d %d)", *i1+dx, *i2+dy); + fprintf(debug, "(%d %d)", *i1 + dx, *i2 + dy); } } - if (cmp != 0 && *i1+dy < m1 && *i2+dx < m2) + if (cmp != 0 && *i1 + dy < m1 && *i2 + dx < m2) { bFW = FALSE; - cmp = debug_strcmp(*atnms1[index1[*i1+dy]], *atnms2[index2[*i2+dx]]); + cmp = debug_strcmp(*atnms1[index1[*i1 + dy]], *atnms2[index2[*i2 + dx]]); if (debug) { - fprintf(debug, "(%d %d)", *i1+dy, *i2+dx); + fprintf(debug, "(%d %d)", *i1 + dy, *i2 + dx); } } } @@ -177,7 +181,7 @@ static int find_next_match_atoms_in_res(int *i1, const int index1[], { if (debug) { - fprintf(debug, "{%d %d}", *i1 + (bFW ? dx : dy), *i2 + (bFW ? dy : dx) ); + fprintf(debug, "{%d %d}", *i1 + (bFW ? dx : dy), *i2 + (bFW ? dy : dx)); } if (bFW) { @@ -194,10 +198,14 @@ static int find_next_match_atoms_in_res(int *i1, const int index1[], return cmp; } -static int find_next_match_res(int *rnr1, int isize1, - const int index1[], t_resinfo *resinfo1, - int *rnr2, int isize2, - const int index2[], t_resinfo *resinfo2) +static int find_next_match_res(int* rnr1, + int isize1, + const int index1[], + t_resinfo* resinfo1, + int* rnr2, + int isize2, + const int index2[], + t_resinfo* resinfo2) { int dmax, cmp, rr1, rr2; gmx_bool bFW = FALSE, bFF = FALSE; @@ -214,11 +222,10 @@ static int find_next_match_res(int *rnr1, int isize1, } cmp = NOTSET; - dmax = std::max(isize1-rr1, isize2-rr2); + dmax = std::max(isize1 - rr1, isize2 - rr2); if (debug) { - fprintf(debug, " R:%d-%d:%d-%d:%d ", - rr1, isize1, rr2, isize2, dmax); + fprintf(debug, " R:%d-%d:%d-%d:%d ", rr1, isize1, rr2, isize2, dmax); } int dx = 0, dy = 0; for (; dx < dmax && cmp != 0; dx++) @@ -228,34 +235,31 @@ static int find_next_match_res(int *rnr1, int isize1, if (dx != dy) { cmp = NOTSET; - if (rr1+dx < isize1 && rr2+dy < isize2) + if (rr1 + dx < isize1 && rr2 + dy < isize2) { bFW = TRUE; - cmp = debug_strcmp(*resinfo1[index1[rr1+dx]].name, - *resinfo2[index2[rr2+dy]].name); + cmp = debug_strcmp(*resinfo1[index1[rr1 + dx]].name, *resinfo2[index2[rr2 + dy]].name); if (debug) { - fprintf(debug, "(%d %d)", rr1+dx, rr2+dy); + fprintf(debug, "(%d %d)", rr1 + dx, rr2 + dy); } } - if (cmp != 0 && rr1+dy < isize1 && rr2+dx < isize2) + if (cmp != 0 && rr1 + dy < isize1 && rr2 + dx < isize2) { bFW = FALSE; - cmp = debug_strcmp(*resinfo1[index1[rr1+dy]].name, - *resinfo2[index2[rr2+dx]].name); + cmp = debug_strcmp(*resinfo1[index1[rr1 + dy]].name, *resinfo2[index2[rr2 + dx]].name); if (debug) { - fprintf(debug, "(%d %d)", rr1+dy, rr2+dx); + fprintf(debug, "(%d %d)", rr1 + dy, rr2 + dx); } } - if (dx != 0 && cmp != 0 && rr1+dx < isize1 && rr2+dx < isize2) + if (dx != 0 && cmp != 0 && rr1 + dx < isize1 && rr2 + dx < isize2) { bFF = TRUE; - cmp = debug_strcmp(*resinfo1[index1[rr1+dx]].name, - *resinfo2[index2[rr2+dx]].name); + cmp = debug_strcmp(*resinfo1[index1[rr1 + dx]].name, *resinfo2[index2[rr2 + dx]].name); if (debug) { - fprintf(debug, "(%d %d)", rr1+dx, rr2+dx); + fprintf(debug, "(%d %d)", rr1 + dx, rr2 + dx); } } else @@ -275,9 +279,8 @@ static int find_next_match_res(int *rnr1, int isize1, { if (debug) { - fprintf(debug, "%d.%d.%dX%sX%s", dx, rr1, rr2, - *resinfo1[index1[rr1+1]].name, - *resinfo2[index2[rr2+1]].name); + fprintf(debug, "%d.%d.%dX%sX%s", dx, rr1, rr2, *resinfo1[index1[rr1 + 1]].name, + *resinfo2[index2[rr2 + 1]].name); } dx = 1; } @@ -329,15 +332,19 @@ static int find_first_atom_in_res(int rnr, int isize, const int index[], t_atom } } -static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1, - int *isize2, int index2[], const t_atoms *atoms2) +static void find_matching_names(int* isize1, + int index1[], + const t_atoms* atoms1, + int* isize2, + int index2[], + const t_atoms* atoms2) { int i1, i2, ii1, ii2, m1, m2; int atcmp, rescmp; int rnr1, rnr2, prnr1, prnr2; int rsize1, rsize2; - int *rindex1, *rindex2; - char ***atnms1, ***atnms2; + int * rindex1, *rindex2; + char *** atnms1, ***atnms2; t_resinfo *resinfo1, *resinfo2; /* set some handy shortcuts */ @@ -352,8 +359,8 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 snew(rindex2, atoms2->nres); rsize2 = build_res_index(*isize2, index2, atoms2->atom, rindex2); - i1 = i2 = 0; - ii1 = ii2 = 0; + i1 = i2 = 0; + ii1 = ii2 = 0; atcmp = rescmp = 0; prnr1 = prnr2 = NOTSET; if (debug) @@ -369,8 +376,7 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 { if (debug) { - fprintf(debug, "R: %s%d %s%d\n", - *resinfo1[rnr1].name, rnr1, *resinfo2[rnr2].name, rnr2); + fprintf(debug, "R: %s%d %s%d\n", *resinfo1[rnr1].name, rnr1, *resinfo2[rnr2].name, rnr2); } rescmp = std::strcmp(*resinfo1[rnr1].name, *resinfo2[rnr2].name); } @@ -389,21 +395,17 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 { fprintf(debug, " [%d<%d %d<%d]", i1, m1, i2, m2); } - atcmp = find_next_match_atoms_in_res(&i1, index1, m1, atnms1, - &i2, index2, m2, atnms2); + atcmp = find_next_match_atoms_in_res(&i1, index1, m1, atnms1, &i2, index2, m2, atnms2); if (debug) { - fprintf(debug, " -> %d %d %s-%s", i1, i2, - *atnms1[index1[i1]], *atnms2[index2[i2]]); + fprintf(debug, " -> %d %d %s-%s", i1, i2, *atnms1[index1[i1]], *atnms2[index2[i2]]); } - } if (atcmp != 0) /* still no match -> next residue(s) */ { - prnr1 = rnr1; - prnr2 = rnr2; - rescmp = find_next_match_res(&rnr1, rsize1, rindex1, resinfo1, - &rnr2, rsize2, rindex2, resinfo2); + prnr1 = rnr1; + prnr2 = rnr2; + rescmp = find_next_match_res(&rnr1, rsize1, rindex1, resinfo1, &rnr2, rsize2, rindex2, resinfo2); if (rnr1 != prnr1) { i1 = find_first_atom_in_res(rnr1, *isize1, index1, atoms1->atom); @@ -414,11 +416,8 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 } if (debug) { - fprintf(debug, " -> %s%d-%s%d %s%d-%s%d", - *resinfo1[rnr1].name, rnr1, - *atnms1[index1[i1]], index1[i1], - *resinfo2[rnr2].name, rnr2, - *atnms2[index2[i2]], index2[i2]); + fprintf(debug, " -> %s%d-%s%d %s%d-%s%d", *resinfo1[rnr1].name, rnr1, *atnms1[index1[i1]], + index1[i1], *resinfo2[rnr2].name, rnr2, *atnms2[index2[i2]], index2[i2]); } m1 = find_res_end(i1, *isize1, index1, atoms1); m2 = find_res_end(i2, *isize2, index2, atoms2); @@ -426,12 +425,10 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 { fprintf(debug, " [%d<%d %d<%d]", i1, m1, i2, m2); } - atcmp = find_next_match_atoms_in_res(&i1, index1, m1, atnms1, - &i2, index2, m2, atnms2); + atcmp = find_next_match_atoms_in_res(&i1, index1, m1, atnms1, &i2, index2, m2, atnms2); if (debug) { - fprintf(debug, " -> %d %d %s-%s", i1, i2, - *atnms1[index1[i1]], *atnms2[index2[i2]]); + fprintf(debug, " -> %d %d %s-%s", i1, i2, *atnms1[index1[i1]], *atnms2[index2[i2]]); } } if (debug) @@ -482,9 +479,9 @@ static void find_matching_names(int *isize1, int index1[], const t_atoms *atoms1 } /* 1 */ -int gmx_confrms(int argc, char *argv[]) +int gmx_confrms(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the root mean square deviation (RMSD) of two", "structures after least-squares fitting the second structure on the first one.", "The two structures do NOT need to have the same number of atoms,", @@ -498,63 +495,62 @@ int gmx_confrms(int argc, char *argv[]) "(use [TT]rasmol -nmrpdb[tt]). Also in a [REF].pdb[ref] file, B-factors", "calculated from the atomic MSD values can be written with [TT]-bfac[tt].", }; - static gmx_bool bOne = FALSE, bRmpbc = FALSE, bMW = TRUE, bName = FALSE, - bBfac = FALSE, bFit = TRUE, bLabel = FALSE; - - t_pargs pa[] = { - { "-one", FALSE, etBOOL, {&bOne}, "Only write the fitted structure to file" }, - { "-mw", FALSE, etBOOL, {&bMW}, "Mass-weighted fitting and RMSD" }, - { "-pbc", FALSE, etBOOL, {&bRmpbc}, "Try to make molecules whole again" }, - { "-fit", FALSE, etBOOL, {&bFit}, + static gmx_bool bOne = FALSE, bRmpbc = FALSE, bMW = TRUE, bName = FALSE, bBfac = FALSE, + bFit = TRUE, bLabel = FALSE; + + t_pargs pa[] = { + { "-one", FALSE, etBOOL, { &bOne }, "Only write the fitted structure to file" }, + { "-mw", FALSE, etBOOL, { &bMW }, "Mass-weighted fitting and RMSD" }, + { "-pbc", FALSE, etBOOL, { &bRmpbc }, "Try to make molecules whole again" }, + { "-fit", + FALSE, + etBOOL, + { &bFit }, "Do least squares superposition of the target structure to the reference" }, - { "-name", FALSE, etBOOL, {&bName}, - "Only compare matching atom names" }, - { "-label", FALSE, etBOOL, {&bLabel}, - "Added chain labels A for first and B for second structure"}, - { "-bfac", FALSE, etBOOL, {&bBfac}, - "Output B-factors from atomic MSD values" } - }; - t_filenm fnm[] = { - { efTPS, "-f1", "conf1.gro", ffREAD }, - { efSTX, "-f2", "conf2", ffREAD }, - { efSTO, "-o", "fit.pdb", ffWRITE }, - { efNDX, "-n1", "fit1", ffOPTRD }, - { efNDX, "-n2", "fit2", ffOPTRD }, - { efNDX, "-no", "match", ffOPTWR } + { "-name", FALSE, etBOOL, { &bName }, "Only compare matching atom names" }, + { "-label", + FALSE, + etBOOL, + { &bLabel }, + "Added chain labels A for first and B for second structure" }, + { "-bfac", FALSE, etBOOL, { &bBfac }, "Output B-factors from atomic MSD values" } }; + t_filenm fnm[] = { { efTPS, "-f1", "conf1.gro", ffREAD }, { efSTX, "-f2", "conf2", ffREAD }, + { efSTO, "-o", "fit.pdb", ffWRITE }, { efNDX, "-n1", "fit1", ffOPTRD }, + { efNDX, "-n2", "fit2", ffOPTRD }, { efNDX, "-no", "match", ffOPTWR } }; #define NFILE asize(fnm) /* the two structure files */ - const char *conf1file, *conf2file, *matchndxfile, *outfile; - FILE *fp; - char *name1, *name2; - t_topology *top1, *top2; - int ePBC1, ePBC2; - t_atoms *atoms1, *atoms2; - int warn = 0; - int at; - real *w_rls, mass, totmass; - rvec *x1, *v1, *x2, *v2, *fit_x; - matrix box1, box2; - - gmx_output_env_t *oenv; + const char *conf1file, *conf2file, *matchndxfile, *outfile; + FILE* fp; + char * name1, *name2; + t_topology *top1, *top2; + int ePBC1, ePBC2; + t_atoms * atoms1, *atoms2; + int warn = 0; + int at; + real * w_rls, mass, totmass; + rvec * x1, *v1, *x2, *v2, *fit_x; + matrix box1, box2; + + gmx_output_env_t* oenv; /* counters */ - int i, m; + int i, m; /* center of mass calculation */ - rvec xcm1, xcm2; + rvec xcm1, xcm2; /* variables for fit */ - char *groupnames1, *groupnames2; - int isize1, isize2; - int *index1, *index2; - real rms, msd, minmsd, maxmsd; - real *msds; + char *groupnames1, *groupnames2; + int isize1, isize2; + int * index1, *index2; + real rms, msd, minmsd, maxmsd; + real* msds; - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } @@ -567,8 +563,7 @@ int gmx_confrms(int argc, char *argv[]) snew(top1, 1); read_tps_conf(conf1file, top1, &ePBC1, &x1, &v1, box1, TRUE); atoms1 = &(top1->atoms); - fprintf(stderr, "%s\nContaining %d atoms in %d residues\n", - *top1->name, atoms1->nr, atoms1->nres); + fprintf(stderr, "%s\nContaining %d atoms in %d residues\n", *top1->name, atoms1->nr, atoms1->nres); if (bRmpbc) { @@ -576,8 +571,7 @@ int gmx_confrms(int argc, char *argv[]) } fprintf(stderr, "Select group from first structure\n"); - get_index(atoms1, opt2fn_null("-n1", NFILE, fnm), - 1, &isize1, &index1, &groupnames1); + get_index(atoms1, opt2fn_null("-n1", NFILE, fnm), 1, &isize1, &index1, &groupnames1); printf("\n"); if (bFit && (isize1 < 3)) @@ -590,8 +584,7 @@ int gmx_confrms(int argc, char *argv[]) snew(top2, 1); read_tps_conf(conf2file, top2, &ePBC2, &x2, &v2, box2, TRUE); atoms2 = &(top2->atoms); - fprintf(stderr, "%s\nContaining %d atoms in %d residues\n", - *top2->name, atoms2->nr, atoms2->nres); + fprintf(stderr, "%s\nContaining %d atoms in %d residues\n", *top2->name, atoms2->nr, atoms2->nres); if (bRmpbc) { @@ -599,8 +592,7 @@ int gmx_confrms(int argc, char *argv[]) } fprintf(stderr, "Select group from second structure\n"); - get_index(atoms2, opt2fn_null("-n2", NFILE, fnm), - 1, &isize2, &index2, &groupnames2); + get_index(atoms2, opt2fn_null("-n2", NFILE, fnm), 1, &isize2, &index2, &groupnames2); if (bName) { @@ -608,17 +600,17 @@ int gmx_confrms(int argc, char *argv[]) if (matchndxfile) { fp = gmx_ffopen(matchndxfile, "w"); - fprintf(fp, "; Matching atoms between %s from %s and %s from %s\n", - groupnames1, conf1file, groupnames2, conf2file); + fprintf(fp, "; Matching atoms between %s from %s and %s from %s\n", groupnames1, + conf1file, groupnames2, conf2file); fprintf(fp, "[ Match_%s_%s ]\n", conf1file, groupnames1); for (i = 0; i < isize1; i++) { - fprintf(fp, "%4d%s", index1[i]+1, (i%15 == 14 || i == isize1-1) ? "\n" : " "); + fprintf(fp, "%4d%s", index1[i] + 1, (i % 15 == 14 || i == isize1 - 1) ? "\n" : " "); } fprintf(fp, "[ Match_%s_%s ]\n", conf2file, groupnames2); for (i = 0; i < isize2; i++) { - fprintf(fp, "%4d%s", index2[i]+1, (i%15 == 14 || i == isize2-1) ? "\n" : " "); + fprintf(fp, "%4d%s", index2[i] + 1, (i % 15 == 14 || i == isize2 - 1) ? "\n" : " "); } } } @@ -637,9 +629,8 @@ int gmx_confrms(int argc, char *argv[]) { if (warn < 20) { - fprintf(stderr, - "Warning: atomnames at index %d don't match: %d %s, %d %s\n", - i+1, index1[i]+1, name1, index2[i]+1, name2); + fprintf(stderr, "Warning: atomnames at index %d don't match: %d %s, %d %s\n", i + 1, + index1[i] + 1, name1, index2[i] + 1, name2); } warn++; } @@ -686,22 +677,22 @@ int gmx_confrms(int argc, char *argv[]) rms = 0; totmass = 0; maxmsd = -1e18; - minmsd = 1e18; + minmsd = 1e18; snew(msds, isize1); for (at = 0; at < isize1; at++) { mass = atoms1->atom[index1[at]].m; for (m = 0; m < DIM; m++) { - msd = gmx::square(x1[index1[at]][m] - x2[index2[at]][m]); - rms += msd*mass; + msd = gmx::square(x1[index1[at]][m] - x2[index2[at]][m]); + rms += msd * mass; msds[at] += msd; } - maxmsd = std::max(maxmsd, msds[at]); - minmsd = std::min(minmsd, msds[at]); + maxmsd = std::max(maxmsd, msds[at]); + minmsd = std::min(minmsd, msds[at]); totmass += mass; } - rms = std::sqrt(rms/totmass); + rms = std::sqrt(rms / totmass); printf("Root mean square deviation after lsq fit = %g nm\n", rms); if (bBfac) @@ -760,13 +751,13 @@ int gmx_confrms(int argc, char *argv[]) for (i = 0; i < isize1; i++) { /* atoms1->pdbinfo[index1[i]].type = eptAtom; */ -/* atoms1->pdbinfo[index1[i]].bAnisotropic = FALSE; */ + /* atoms1->pdbinfo[index1[i]].bAnisotropic = FALSE; */ if (bBfac) { - atoms1->pdbinfo[index1[i]].bfac = (800*M_PI*M_PI/3.0)*msds[i]; + atoms1->pdbinfo[index1[i]].bfac = (800 * M_PI * M_PI / 3.0) * msds[i]; } -/* if (bLabel) */ -/* atoms1->resinfo[atoms1->atom[index1[i]].resind].chain = 'A'; */ + /* if (bLabel) */ + /* atoms1->resinfo[atoms1->atom[index1[i]].resind].chain = 'A'; */ } srenew(atoms2->pdbinfo, atoms2->nr); srenew(atoms2->atom, atoms2->nr); /* Why renew atom? */ @@ -789,13 +780,13 @@ int gmx_confrms(int argc, char *argv[]) for (i = 0; i < isize2; i++) { /* atoms2->pdbinfo[index2[i]].type = eptAtom; */ -/* atoms2->pdbinfo[index2[i]].bAnisotropic = FALSE; */ + /* atoms2->pdbinfo[index2[i]].bAnisotropic = FALSE; */ if (bBfac) { - atoms2->pdbinfo[index2[i]].bfac = (800*M_PI*M_PI/3.0)*msds[i]; + atoms2->pdbinfo[index2[i]].bfac = (800 * M_PI * M_PI / 3.0) * msds[i]; } -/* if (bLabel) */ -/* atoms2->resinfo[atoms2->atom[index2[i]].resind].chain = 'B'; */ + /* if (bLabel) */ + /* atoms2->resinfo[atoms2->atom[index2[i]].resind].chain = 'B'; */ } } fp = gmx_ffopen(outfile, "w"); @@ -827,8 +818,7 @@ int gmx_confrms(int argc, char *argv[]) } if (!bOne) { - fprintf(stderr, - "WARNING: cannot write the reference structure to %s file\n", + fprintf(stderr, "WARNING: cannot write the reference structure to %s file\n", ftp2ext(fn2ftp(outfile))); } write_sto_conf(outfile, *top2->name, atoms2, x2, v2, ePBC2, box2); diff --git a/src/gromacs/gmxana/gmx_covar.cpp b/src/gromacs/gmxana/gmx_covar.cpp index 6b4ee55e3e..4d8bce1d0a 100644 --- a/src/gromacs/gmxana/gmx_covar.cpp +++ b/src/gromacs/gmxana/gmx_covar.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,9 +60,9 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/sysinfo.h" -int gmx_covar(int argc, char *argv[]) +int gmx_covar(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates and diagonalizes the (mass-weighted)", "covariance matrix.", "All structures are fitted to the structure in the structure file.", @@ -96,62 +96,57 @@ int gmx_covar(int argc, char *argv[]) "should consider carefully whether a reduced set of atoms will meet", "your needs for lower costs." }; - static gmx_bool bFit = TRUE, bRef = FALSE, bM = FALSE, bPBC = TRUE; - static int end = -1; - t_pargs pa[] = { - { "-fit", FALSE, etBOOL, {&bFit}, - "Fit to a reference structure"}, - { "-ref", FALSE, etBOOL, {&bRef}, - "Use the deviation from the conformation in the structure file instead of from the average" }, - { "-mwa", FALSE, etBOOL, {&bM}, - "Mass-weighted covariance analysis"}, - { "-last", FALSE, etINT, {&end}, - "Last eigenvector to write away (-1 is till the last)" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Apply corrections for periodic boundary conditions" } + static gmx_bool bFit = TRUE, bRef = FALSE, bM = FALSE, bPBC = TRUE; + static int end = -1; + t_pargs pa[] = { + { "-fit", FALSE, etBOOL, { &bFit }, "Fit to a reference structure" }, + { "-ref", + FALSE, + etBOOL, + { &bRef }, + "Use the deviation from the conformation in the structure file instead of from the " + "average" }, + { "-mwa", FALSE, etBOOL, { &bM }, "Mass-weighted covariance analysis" }, + { "-last", FALSE, etINT, { &end }, "Last eigenvector to write away (-1 is till the last)" }, + { "-pbc", FALSE, etBOOL, { &bPBC }, "Apply corrections for periodic boundary conditions" } }; - FILE *out = nullptr; /* initialization makes all compilers happy */ - t_trxstatus *status; + FILE* out = nullptr; /* initialization makes all compilers happy */ + t_trxstatus* status; t_topology top; int ePBC; - t_atoms *atoms; - rvec *x, *xread, *xref, *xav, *xproj; + t_atoms* atoms; + rvec * x, *xread, *xref, *xav, *xproj; matrix box, zerobox; - real *sqrtm, *mat, *eigenvalues, sum, trace, inv_nframes; + real * sqrtm, *mat, *eigenvalues, sum, trace, inv_nframes; real t, tstart, tend, **mat2; real xj, *w_rls = nullptr; real min, max, *axis; int natoms, nat, nframes0, nframes, nlevels; int64_t ndim, i, j, k, l; int WriteXref; - const char *fitfile, *trxfile, *ndxfile; - const char *eigvalfile, *eigvecfile, *averfile, *logfile; - const char *asciifile, *xpmfile, *xpmafile; + const char * fitfile, *trxfile, *ndxfile; + const char * eigvalfile, *eigvecfile, *averfile, *logfile; + const char * asciifile, *xpmfile, *xpmafile; char str[STRLEN], *fitname, *ananame; int d, dj, nfit; - int *index, *ifit; + int * index, *ifit; gmx_bool bDiffMass1, bDiffMass2; t_rgb rlo, rmi, rhi; - real *eigenvectors; - gmx_output_env_t *oenv; + real* eigenvectors; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "eigenval", ffWRITE }, - { efTRN, "-v", "eigenvec", ffWRITE }, - { efSTO, "-av", "average.pdb", ffWRITE }, - { efLOG, nullptr, "covar", ffWRITE }, - { efDAT, "-ascii", "covar", ffOPTWR }, - { efXPM, "-xpm", "covar", ffOPTWR }, - { efXPM, "-xpma", "covara", ffOPTWR } + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, nullptr, "eigenval", ffWRITE }, + { efTRN, "-v", "eigenvec", ffWRITE }, { efSTO, "-av", "average.pdb", ffWRITE }, + { efLOG, nullptr, "covar", ffWRITE }, { efDAT, "-ascii", "covar", ffOPTWR }, + { efXPM, "-xpm", "covar", ffOPTWR }, { efXPM, "-xpma", "covara", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -197,7 +192,7 @@ int gmx_covar(int argc, char *argv[]) w_rls[ifit[i]] = atoms->atom[ifit[i]].m; if (i) { - bDiffMass1 = bDiffMass1 || (w_rls[ifit[i]] != w_rls[ifit[i-1]]); + bDiffMass1 = bDiffMass1 || (w_rls[ifit[i]] != w_rls[ifit[i - 1]]); } } } @@ -210,7 +205,7 @@ int gmx_covar(int argc, char *argv[]) sqrtm[i] = std::sqrt(atoms->atom[index[i]].m); if (i) { - bDiffMass2 = bDiffMass2 || (sqrtm[i] != sqrtm[i-1]); + bDiffMass2 = bDiffMass2 || (sqrtm[i] != sqrtm[i - 1]); } } else @@ -228,7 +223,8 @@ int gmx_covar(int argc, char *argv[]) } if (!bDiffMass1) { - fprintf(stderr, "\n" + fprintf(stderr, + "\n" "Note: the fit and analysis group are identical,\n" " while the fit is mass weighted and the analysis is not.\n" " Making the fit non mass weighted.\n\n"); @@ -252,19 +248,20 @@ int gmx_covar(int argc, char *argv[]) snew(x, natoms); snew(xav, natoms); - ndim = natoms*DIM; + ndim = natoms * DIM; if (std::sqrt(static_cast(INT64_MAX)) < static_cast(ndim)) { gmx_fatal(FARGS, "Number of degrees of freedoms to large for matrix.\n"); } - snew(mat, ndim*ndim); + snew(mat, ndim * ndim); fprintf(stderr, "Calculating the average structure ...\n"); nframes0 = 0; nat = read_first_x(oenv, &status, trxfile, &t, &xread, box); if (nat != atoms->nr) { - fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", natoms, nat); + fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", + natoms, nat); } do { @@ -283,24 +280,24 @@ int gmx_covar(int argc, char *argv[]) { rvec_inc(xav[i], xread[index[i]]); } - } - while (read_next_x(oenv, status, &t, xread, box)); + } while (read_next_x(oenv, status, &t, xread, box)); close_trx(status); - inv_nframes = 1.0/nframes0; + inv_nframes = 1.0 / nframes0; for (i = 0; i < natoms; i++) { for (d = 0; d < DIM; d++) { - xav[i][d] *= inv_nframes; + xav[i][d] *= inv_nframes; xread[index[i]][d] = xav[i][d]; } } - write_sto_conf_indexed(opt2fn("-av", NFILE, fnm), "Average structure", - atoms, xread, nullptr, epbcNONE, zerobox, natoms, index); + write_sto_conf_indexed(opt2fn("-av", NFILE, fnm), "Average structure", atoms, xread, nullptr, + epbcNONE, zerobox, natoms, index); sfree(xread); - fprintf(stderr, "Constructing covariance matrix (%dx%d) ...\n", static_cast(ndim), static_cast(ndim)); + fprintf(stderr, "Constructing covariance matrix (%dx%d) ...\n", static_cast(ndim), + static_cast(ndim)); nframes = 0; nat = read_first_x(oenv, &status, trxfile, &t, &xread, box); tstart = t; @@ -337,21 +334,19 @@ int gmx_covar(int argc, char *argv[]) { for (dj = 0; dj < DIM; dj++) { - k = ndim*(DIM*j+dj); + k = ndim * (DIM * j + dj); xj = x[j][dj]; for (i = j; i < natoms; i++) { - l = k+DIM*i; + l = k + DIM * i; for (d = 0; d < DIM; d++) { - mat[l+d] += x[i][d]*xj; + mat[l + d] += x[i][d] * xj; } } } } - } - while (read_next_x(oenv, status, &t, xread, box) && - (bRef || nframes < nframes0)); + } while (read_next_x(oenv, status, &t, xread, box) && (bRef || nframes < nframes0)); close_trx(status); gmx_rmpbc_done(gpbc); @@ -372,17 +367,17 @@ int gmx_covar(int argc, char *argv[]) } /* correct the covariance matrix for the mass */ - inv_nframes = 1.0/nframes; + inv_nframes = 1.0 / nframes; for (j = 0; j < natoms; j++) { for (dj = 0; dj < DIM; dj++) { for (i = j; i < natoms; i++) { - k = ndim*(DIM*j+dj)+DIM*i; + k = ndim * (DIM * j + dj) + DIM * i; for (d = 0; d < DIM; d++) { - mat[k+d] = mat[k+d]*inv_nframes*sqrtm[i]*sqrtm[j]; + mat[k + d] = mat[k + d] * inv_nframes * sqrtm[i] * sqrtm[j]; } } } @@ -393,17 +388,16 @@ int gmx_covar(int argc, char *argv[]) { for (i = j; i < ndim; i++) { - mat[ndim*i+j] = mat[ndim*j+i]; + mat[ndim * i + j] = mat[ndim * j + i]; } } trace = 0; for (i = 0; i < ndim; i++) { - trace += mat[i*ndim+i]; + trace += mat[i * ndim + i]; } - fprintf(stderr, "\nTrace of the covariance matrix: %g (%snm^2)\n", - trace, bM ? "u " : ""); + fprintf(stderr, "\nTrace of the covariance matrix: %g (%snm^2)\n", trace, bM ? "u " : ""); if (asciifile) { @@ -412,8 +406,8 @@ int gmx_covar(int argc, char *argv[]) { for (i = 0; i < ndim; i += 3) { - fprintf(out, "%g %g %g\n", - mat[ndim*j+i], mat[ndim*j+i+1], mat[ndim*j+i+2]); + fprintf(out, "%g %g %g\n", mat[ndim * j + i], mat[ndim * j + i + 1], + mat[ndim * j + i + 2]); } } gmx_ffclose(out); @@ -426,7 +420,7 @@ int gmx_covar(int argc, char *argv[]) snew(mat2, ndim); for (j = 0; j < ndim; j++) { - mat2[j] = &(mat[ndim*j]); + mat2[j] = &(mat[ndim * j]); for (i = 0; i <= j; i++) { if (mat2[j][i] < min) @@ -442,16 +436,21 @@ int gmx_covar(int argc, char *argv[]) snew(axis, ndim); for (i = 0; i < ndim; i++) { - axis[i] = i+1; + axis[i] = i + 1; } - rlo.r = 0; rlo.g = 0; rlo.b = 1; - rmi.r = 1; rmi.g = 1; rmi.b = 1; - rhi.r = 1; rhi.g = 0; rhi.b = 0; + rlo.r = 0; + rlo.g = 0; + rlo.b = 1; + rmi.r = 1; + rmi.g = 1; + rmi.b = 1; + rhi.r = 1; + rhi.g = 0; + rhi.b = 0; out = gmx_ffopen(xpmfile, "w"); nlevels = 80; - write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", - "dim", "dim", ndim, ndim, axis, axis, - mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels); + write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", "dim", "dim", ndim, ndim, axis, + axis, mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels); gmx_ffclose(out); sfree(axis); sfree(mat2); @@ -461,19 +460,19 @@ int gmx_covar(int argc, char *argv[]) { min = 0; max = 0; - snew(mat2, ndim/DIM); - for (i = 0; i < ndim/DIM; i++) + snew(mat2, ndim / DIM); + for (i = 0; i < ndim / DIM; i++) { - snew(mat2[i], ndim/DIM); + snew(mat2[i], ndim / DIM); } - for (j = 0; j < ndim/DIM; j++) + for (j = 0; j < ndim / DIM; j++) { for (i = 0; i <= j; i++) { mat2[j][i] = 0; for (d = 0; d < DIM; d++) { - mat2[j][i] += mat[ndim*(DIM*j+d)+DIM*i+d]; + mat2[j][i] += mat[ndim * (DIM * j + d) + DIM * i + d]; } if (mat2[j][i] < min) { @@ -486,22 +485,27 @@ int gmx_covar(int argc, char *argv[]) mat2[i][j] = mat2[j][i]; } } - snew(axis, ndim/DIM); - for (i = 0; i < ndim/DIM; i++) + snew(axis, ndim / DIM); + for (i = 0; i < ndim / DIM; i++) { - axis[i] = i+1; + axis[i] = i + 1; } - rlo.r = 0; rlo.g = 0; rlo.b = 1; - rmi.r = 1; rmi.g = 1; rmi.b = 1; - rhi.r = 1; rhi.g = 0; rhi.b = 0; + rlo.r = 0; + rlo.g = 0; + rlo.b = 1; + rmi.r = 1; + rmi.g = 1; + rmi.b = 1; + rhi.r = 1; + rhi.g = 0; + rhi.b = 0; out = gmx_ffopen(xpmafile, "w"); nlevels = 80; - write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", - "atom", "atom", ndim/DIM, ndim/DIM, axis, axis, - mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels); + write_xpm3(out, 0, "Covariance", bM ? "u nm^2" : "nm^2", "atom", "atom", ndim / DIM, + ndim / DIM, axis, axis, mat2, min, 0.0, max, rlo, rmi, rhi, &nlevels); gmx_ffclose(out); sfree(axis); - for (i = 0; i < ndim/DIM; i++) + for (i = 0; i < ndim / DIM; i++) { sfree(mat2[i]); } @@ -512,9 +516,9 @@ int gmx_covar(int argc, char *argv[]) /* call diagonalization routine */ snew(eigenvalues, ndim); - snew(eigenvectors, ndim*ndim); + snew(eigenvectors, ndim * ndim); - std::memcpy(eigenvectors, mat, ndim*ndim*sizeof(real)); + std::memcpy(eigenvectors, mat, ndim * ndim * sizeof(real)); fprintf(stderr, "\nDiagonalizing ...\n"); fflush(stderr); eigensolver(eigenvectors, ndim, 0, ndim, eigenvalues, mat); @@ -527,20 +531,21 @@ int gmx_covar(int argc, char *argv[]) { sum += eigenvalues[i]; } - fprintf(stderr, "\nSum of the eigenvalues: %g (%snm^2)\n", - sum, bM ? "u " : ""); - if (std::abs(trace-sum) > 0.01*trace) + fprintf(stderr, "\nSum of the eigenvalues: %g (%snm^2)\n", sum, bM ? "u " : ""); + if (std::abs(trace - sum) > 0.01 * trace) { - fprintf(stderr, "\nWARNING: eigenvalue sum deviates from the trace of the covariance matrix\n"); + fprintf(stderr, + "\nWARNING: eigenvalue sum deviates from the trace of the covariance matrix\n"); } /* Set 'end', the maximum eigenvector and -value index used for output */ if (end == -1) { - if (nframes-1 < ndim) + if (nframes - 1 < ndim) { - end = nframes-1; - fprintf(stderr, "\nWARNING: there are fewer frames in your trajectory than there are\n"); + end = nframes - 1; + fprintf(stderr, + "\nWARNING: there are fewer frames in your trajectory than there are\n"); fprintf(stderr, "degrees of freedom in your system. Only generating the first\n"); fprintf(stderr, "%d out of %d eigenvectors and eigenvalues.\n", end, static_cast(ndim)); } @@ -553,12 +558,10 @@ int gmx_covar(int argc, char *argv[]) fprintf(stderr, "\nWriting eigenvalues to %s\n", eigvalfile); sprintf(str, "(%snm\\S2\\N)", bM ? "u " : ""); - out = xvgropen(eigvalfile, - "Eigenvalues of the covariance matrix", - "Eigenvector index", str, oenv); + out = xvgropen(eigvalfile, "Eigenvalues of the covariance matrix", "Eigenvector index", str, oenv); for (i = 0; (i < end); i++) { - fprintf (out, "%10d %g\n", static_cast(i+1), eigenvalues[ndim-1-i]); + fprintf(out, "%10d %g\n", static_cast(i + 1), eigenvalues[ndim - 1 - i]); } xvgrclose(out); @@ -584,8 +587,8 @@ int gmx_covar(int argc, char *argv[]) WriteXref = eWXR_NOFIT; } - write_eigenvectors(eigvecfile, natoms, mat, TRUE, 1, end, - WriteXref, x, bDiffMass1, xproj, bM, eigenvalues); + write_eigenvectors(eigvecfile, natoms, mat, TRUE, 1, end, WriteXref, x, bDiffMass1, xproj, bM, + eigenvalues); out = gmx_ffopen(logfile, "w"); @@ -597,7 +600,8 @@ int gmx_covar(int argc, char *argv[]) fprintf(out, "Working directory: %s\n\n", str); fprintf(out, "Read %d frames from %s (time %g to %g %s)\n", nframes, trxfile, - output_env_conv_time(oenv, tstart), output_env_conv_time(oenv, tend), output_env_get_time_unit(oenv).c_str()); + output_env_conv_time(oenv, tstart), output_env_conv_time(oenv, tend), + output_env_get_time_unit(oenv).c_str()); if (bFit) { fprintf(out, "Read reference structure for fit from %s\n", fitfile); @@ -622,11 +626,10 @@ int gmx_covar(int argc, char *argv[]) { fprintf(out, "Fit is %smass weighted\n", bDiffMass1 ? "" : "non-"); } - fprintf(out, "Diagonalized the %dx%d covariance matrix\n", static_cast(ndim), static_cast(ndim)); - fprintf(out, "Trace of the covariance matrix before diagonalizing: %g\n", - trace); - fprintf(out, "Trace of the covariance matrix after diagonalizing: %g\n\n", - sum); + fprintf(out, "Diagonalized the %dx%d covariance matrix\n", static_cast(ndim), + static_cast(ndim)); + fprintf(out, "Trace of the covariance matrix before diagonalizing: %g\n", trace); + fprintf(out, "Trace of the covariance matrix after diagonalizing: %g\n\n", sum); fprintf(out, "Wrote %d eigenvalues to %s\n", static_cast(end), eigvalfile); if (WriteXref == eWXR_YES) diff --git a/src/gromacs/gmxana/gmx_current.cpp b/src/gromacs/gmxana/gmx_current.cpp index fd6c082ae8..3e9c1b350a 100644 --- a/src/gromacs/gmxana/gmx_current.cpp +++ b/src/gromacs/gmxana/gmx_current.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,9 +56,9 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -#define EPSI0 (EPSILON0*E_CHARGE*E_CHARGE*AVOGADRO/(KILO*NANO)) /* EPSILON0 in SI units */ +#define EPSI0 (EPSILON0 * E_CHARGE * E_CHARGE * AVOGADRO / (KILO * NANO)) /* EPSILON0 in SI units */ -static void index_atom2mol(int *n, int *index, t_block *mols) +static void index_atom2mol(int* n, int* index, t_block* mols) { int nat, i, nmol, mol, j; @@ -73,10 +73,10 @@ static void index_atom2mol(int *n, int *index, t_block *mols) mol++; if (mol >= mols->nr) { - gmx_fatal(FARGS, "Atom index out of range: %d", index[i]+1); + gmx_fatal(FARGS, "Atom index out of range: %d", index[i] + 1); } } - for (j = mols->index[mol]; j < mols->index[mol+1]; j++) + for (j = mols->index[mol]; j < mols->index[mol + 1]; j++) { if (i >= nat || index[i] != j) { @@ -106,11 +106,10 @@ static gmx_bool precalc(t_topology top, real mass2[], real qmol[]) qall = 0.0; - for (i = 0; i < top.mols.nr; i++) { k = top.mols.index[i]; - l = top.mols.index[i+1]; + l = top.mols.index[i + 1]; mtot = 0.0; qtot = 0.0; @@ -122,9 +121,9 @@ static gmx_bool precalc(t_topology top, real mass2[], real qmol[]) for (j = k; j < l; j++) { - top.atoms.atom[j].q -= top.atoms.atom[j].m*qtot/mtot; - mass2[j] = top.atoms.atom[j].m/mtot; - qmol[j] = qtot; + top.atoms.atom[j].q -= top.atoms.atom[j].m * qtot / mtot; + mass2[j] = top.atoms.atom[j].m / mtot; + qmol[j] = qtot; } @@ -142,7 +141,9 @@ static gmx_bool precalc(t_topology top, real mass2[], real qmol[]) if (std::abs(qall) > 0.01) { - printf("\n\nSystem not neutral (q=%f) will not calculate translational part of the dipole moment.\n", qall); + printf("\n\nSystem not neutral (q=%f) will not calculate translational part of the dipole " + "moment.\n", + qall); bNEU = FALSE; } else @@ -151,7 +152,6 @@ static gmx_bool precalc(t_topology top, real mass2[], real qmol[]) } return bNEU; - } static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) @@ -162,20 +162,20 @@ static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) for (d = 0; d < DIM; d++) { - hbox[d] = 0.5*box[d][d]; + hbox[d] = 0.5 * box[d][d]; } for (i = 0; i < natoms; i++) { - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { - while (x[i][m]-xp[i][m] <= -hbox[m]) + while (x[i][m] - xp[i][m] <= -hbox[m]) { for (d = 0; d <= m; d++) { x[i][d] += box[m][d]; } } - while (x[i][m]-xp[i][m] > hbox[m]) + while (x[i][m] - xp[i][m] > hbox[m]) { for (d = 0; d <= m; d++) { @@ -186,8 +186,16 @@ static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) } } -static void calc_mj(t_topology top, int ePBC, matrix box, gmx_bool bNoJump, int isize, const int index0[], \ - rvec fr[], rvec mj, real mass2[], real qmol[]) +static void calc_mj(t_topology top, + int ePBC, + matrix box, + gmx_bool bNoJump, + int isize, + const int index0[], + rvec fr[], + rvec mj, + real mass2[], + real qmol[]) { int i, j, k, l; @@ -212,7 +220,7 @@ static void calc_mj(t_topology top, int ePBC, matrix box, gmx_bool bNoJump, int clear_rvec(mt1); clear_rvec(mt2); k = top.mols.index[index0[i]]; - l = top.mols.index[index0[i+1]]; + l = top.mols.index[index0[i + 1]]; for (j = k; j < l; j++) { svmul(mass2[j], fr[j], tmp); @@ -230,9 +238,7 @@ static void calc_mj(t_topology top, int ePBC, matrix box, gmx_bool bNoJump, int } rvec_inc(mj, mt1); - } - } @@ -248,31 +254,29 @@ static real calceps(real prefactor, real md2, real mj2, real cor, real eps_rf, g if (bCOR) { - epsilon = md2-2.0*cor+mj2; + epsilon = md2 - 2.0 * cor + mj2; } else { - epsilon = md2+mj2+2.0*cor; + epsilon = md2 + mj2 + 2.0 * cor; } if (eps_rf == 0.0) { - epsilon = 1.0+prefactor*epsilon; - + epsilon = 1.0 + prefactor * epsilon; } else { - epsilon = 2.0*eps_rf+1.0+2.0*eps_rf*prefactor*epsilon; - epsilon /= 2.0*eps_rf+1.0-prefactor*epsilon; + epsilon = 2.0 * eps_rf + 1.0 + 2.0 * eps_rf * prefactor * epsilon; + epsilon /= 2.0 * eps_rf + 1.0 - prefactor * epsilon; } return epsilon; - } -static real calc_cacf(FILE *fcacf, real prefactor, real cacf[], real time[], int nfr, const int vfr[], int ei, int nshift) +static real calc_cacf(FILE* fcacf, real prefactor, real cacf[], real time[], int nfr, const int vfr[], int ei, int nshift) { int i; @@ -289,7 +293,7 @@ static real calc_cacf(FILE *fcacf, real prefactor, real cacf[], real time[], int { real corint; - rfr = static_cast(nfr+i)/nshift; + rfr = static_cast(nfr + i) / nshift; cacf[i] /= rfr; if (time[vfr[i]] <= time[vfr[ei]]) @@ -299,12 +303,12 @@ static real calc_cacf(FILE *fcacf, real prefactor, real cacf[], real time[], int fprintf(fcacf, "%.3f\t%10.6g\t%10.6g\n", time[vfr[i]], cacf[i], sigma); - if ((i+1) < nfr) + if ((i + 1) < nfr) { - deltat = (time[vfr[i+1]]-time[vfr[i]]); + deltat = (time[vfr[i + 1]] - time[vfr[i]]); } - corint = 2.0*deltat*cacf[i]*prefactor; - if (i == 0 || (i+1) == nfr) + corint = 2.0 * deltat * cacf[i] * prefactor; + if (i == 0 || (i + 1) == nfr) { corint *= 0.5; } @@ -312,7 +316,6 @@ static real calc_cacf(FILE *fcacf, real prefactor, real cacf[], real time[], int i++; } - } else { @@ -320,13 +323,12 @@ static real calc_cacf(FILE *fcacf, real prefactor, real cacf[], real time[], int } return sigma_ret; - } -static void calc_mjdsp(FILE *fmjdsp, real prefactor, real dsp2[], real time[], int nfr, const real refr[]) +static void calc_mjdsp(FILE* fmjdsp, real prefactor, real dsp2[], real time[], int nfr, const real refr[]) { - int i; + int i; fprintf(fmjdsp, "#Prefactor fit E-H: 1 / 6.0*V*k_B*T: %g\n", prefactor); @@ -335,72 +337,89 @@ static void calc_mjdsp(FILE *fmjdsp, real prefactor, real dsp2[], real time[], i if (refr[i] != 0.0) { - dsp2[i] *= prefactor/refr[i]; + dsp2[i] *= prefactor / refr[i]; fprintf(fmjdsp, "%.3f\t%10.6g\n", time[i], dsp2[i]); } - - } - } -static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, - FILE *fmjdsp, gmx_bool bNoJump, gmx_bool bACF, gmx_bool bINT, - int ePBC, t_topology top, t_trxframe fr, real temp, - real bfit, real efit, real bvit, real evit, - t_trxstatus *status, int isize, int nmols, int nshift, - const int *index0, int indexm[], real mass2[], - real qmol[], real eps_rf, const gmx_output_env_t *oenv) +static void dielectric(FILE* fmj, + FILE* fmd, + FILE* outf, + FILE* fcur, + FILE* mcor, + FILE* fmjdsp, + gmx_bool bNoJump, + gmx_bool bACF, + gmx_bool bINT, + int ePBC, + t_topology top, + t_trxframe fr, + real temp, + real bfit, + real efit, + real bvit, + real evit, + t_trxstatus* status, + int isize, + int nmols, + int nshift, + const int* index0, + int indexm[], + real mass2[], + real qmol[], + real eps_rf, + const gmx_output_env_t* oenv) { - int i, j; - int valloc, nalloc, nfr, nvfr; - int vshfr; - real *xshfr = nullptr; - int *vfr = nullptr; - real refr = 0.0; - real *cacf = nullptr; - real *time = nullptr; - real *djc = nullptr; - real corint = 0.0; - real prefactorav = 0.0; - real prefactor = 0.0; - real volume; - real volume_av = 0.0; - real dk_s, dk_d, dk_f; - real mj = 0.0; - real mj2 = 0.0; - real mjd = 0.0; - real mjdav = 0.0; - real md2 = 0.0; - real mdav2 = 0.0; - real sgk; - rvec mja_tmp; - rvec mjd_tmp; - rvec mdvec; - rvec *mu = nullptr; - rvec *xp = nullptr; - rvec *v0 = nullptr; - rvec *mjdsp = nullptr; - real *dsp2 = nullptr; - real t0; - real rtmp; - - rvec tmp; - rvec *mtrans = nullptr; + int i, j; + int valloc, nalloc, nfr, nvfr; + int vshfr; + real* xshfr = nullptr; + int* vfr = nullptr; + real refr = 0.0; + real* cacf = nullptr; + real* time = nullptr; + real* djc = nullptr; + real corint = 0.0; + real prefactorav = 0.0; + real prefactor = 0.0; + real volume; + real volume_av = 0.0; + real dk_s, dk_d, dk_f; + real mj = 0.0; + real mj2 = 0.0; + real mjd = 0.0; + real mjdav = 0.0; + real md2 = 0.0; + real mdav2 = 0.0; + real sgk; + rvec mja_tmp; + rvec mjd_tmp; + rvec mdvec; + rvec* mu = nullptr; + rvec* xp = nullptr; + rvec* v0 = nullptr; + rvec* mjdsp = nullptr; + real* dsp2 = nullptr; + real t0; + real rtmp; + + rvec tmp; + rvec* mtrans = nullptr; /* * Variables for the least-squares fit for Einstein-Helfand and Green-Kubo */ - int bi, ei, ie, ii; - real rest = 0.0; - real sigma = 0.0; - real malt = 0.0; - real err = 0.0; - real *xfit; - real *yfit; - gmx_rmpbc_t gpbc = nullptr; + int bi, ei, ie, ii; + real rest = 0.0; + real sigma = 0.0; + real malt = 0.0; + real err = 0.0; + real* xfit; + real* yfit; + gmx_rmpbc_t gpbc = nullptr; /* * indices for EH @@ -439,7 +458,7 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, do { - refr = (nfr+1); + refr = (nfr + 1); if (nfr >= nalloc) { @@ -465,10 +484,9 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, if (nfr == 0) { t0 = fr.time; - } - time[nfr] = fr.time-t0; + time[nfr] = fr.time - t0; if (time[nfr] <= bfit) { @@ -495,7 +513,6 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, { copy_rvec(fr.x[i], xp[i]); } - } gmx_rmpbc_trxfr(gpbc, &fr); @@ -510,13 +527,13 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, } /*if(mod(nfr,nshift)==0){*/ - if (nfr%nshift == 0) + if (nfr % nshift == 0) { for (j = nfr; j >= 0; j--) { rvec_sub(mtrans[nfr], mtrans[j], tmp); - dsp2[nfr-j] += norm2(tmp); - xshfr[nfr-j] += 1.0; + dsp2[nfr - j] += norm2(tmp); + xshfr[nfr - j] += 1.0; } } @@ -566,17 +583,17 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, if (bACF || bINT) { /*if(mod(nvfr,nshift)==0){*/ - if (nvfr%nshift == 0) + if (nvfr % nshift == 0) { for (j = nvfr; j >= 0; j--) { if (bACF) { - cacf[nvfr-j] += iprod(v0[nvfr], v0[j]); + cacf[nvfr - j] += iprod(v0[nvfr], v0[j]); } if (bINT) { - djc[nvfr-j] += iprod(mu[vfr[j]], v0[nvfr]); + djc[nvfr - j] += iprod(mu[vfr[j]], v0[nvfr]); } } vshfr++; @@ -585,7 +602,7 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, nvfr++; } - volume = det(fr.box); + volume = det(fr.box); volume_av += volume; rvec_inc(mja_tmp, mtrans[nfr]); @@ -595,25 +612,25 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, mj2 += iprod(mtrans[nfr], mtrans[nfr]); md2 += iprod(mu[nfr], mu[nfr]); - fprintf(fmj, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mtrans[nfr][XX], mtrans[nfr][YY], mtrans[nfr][ZZ], mj2/refr, norm(mja_tmp)/refr); - fprintf(fmd, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", \ - time[nfr], mu[nfr][XX], mu[nfr][YY], mu[nfr][ZZ], md2/refr, norm(mdvec)/refr); + fprintf(fmj, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mtrans[nfr][XX], + mtrans[nfr][YY], mtrans[nfr][ZZ], mj2 / refr, norm(mja_tmp) / refr); + fprintf(fmd, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mu[nfr][XX], + mu[nfr][YY], mu[nfr][ZZ], md2 / refr, norm(mdvec) / refr); nfr++; - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); gmx_rmpbc_done(gpbc); volume_av /= refr; - prefactor = 1.0; - prefactor /= 3.0*EPSILON0*volume_av*BOLTZ*temp; + prefactor = 1.0; + prefactor /= 3.0 * EPSILON0 * volume_av * BOLTZ * temp; - prefactorav = E_CHARGE*E_CHARGE; - prefactorav /= volume_av*BOLTZMANN*temp*NANO*6.0; + prefactorav = E_CHARGE * E_CHARGE; + prefactorav /= volume_av * BOLTZMANN * temp * NANO * 6.0; fprintf(stderr, "Prefactor fit E-H: 1 / 6.0*V*k_B*T: %g\n", prefactorav); @@ -628,16 +645,19 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, mjd /= refr; md2 /= refr; - svmul(1.0/refr, mdvec, mdvec); - svmul(1.0/refr, mja_tmp, mja_tmp); + svmul(1.0 / refr, mdvec, mdvec); + svmul(1.0 / refr, mja_tmp, mja_tmp); mdav2 = norm2(mdvec); mj = norm2(mja_tmp); mjdav = iprod(mdvec, mja_tmp); - printf("\n\nAverage translational dipole moment M_J [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mja_tmp[XX], mja_tmp[YY], mja_tmp[ZZ], mj2); - printf("\n\nAverage molecular dipole moment M_D [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mdvec[XX], mdvec[YY], mdvec[ZZ], md2); + printf("\n\nAverage translational dipole moment M_J [enm] after %d frames (|M|^2): %f %f %f " + "(%f)\n", + nfr, mja_tmp[XX], mja_tmp[YY], mja_tmp[ZZ], mj2); + printf("\n\nAverage molecular dipole moment M_D [enm] after %d frames (|M|^2): %f %f %f (%f)\n", + nfr, mdvec[XX], mdvec[YY], mdvec[ZZ], md2); if (v0 != nullptr) { @@ -645,42 +665,39 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, { printf("\nCalculating M_D - current correlation integral ... \n"); - corint = calc_cacf(mcor, prefactorav/EPSI0, djc, time, nvfr, vfr, ie, nshift); - + corint = calc_cacf(mcor, prefactorav / EPSI0, djc, time, nvfr, vfr, ie, nshift); } if (bACF) { printf("\nCalculating current autocorrelation ... \n"); - sgk = calc_cacf(outf, prefactorav/PICO, cacf, time, nvfr, vfr, ie, nshift); + sgk = calc_cacf(outf, prefactorav / PICO, cacf, time, nvfr, vfr, ie, nshift); if (ie > ii) { - snew(xfit, ie-ii+1); - snew(yfit, ie-ii+1); + snew(xfit, ie - ii + 1); + snew(yfit, ie - ii + 1); for (i = ii; i <= ie; i++) { - xfit[i-ii] = std::log(time[vfr[i]]); - rtmp = std::abs(cacf[i]); - yfit[i-ii] = std::log(rtmp); - + xfit[i - ii] = std::log(time[vfr[i]]); + rtmp = std::abs(cacf[i]); + yfit[i - ii] = std::log(rtmp); } - lsq_y_ax_b(ie-ii, xfit, yfit, &sigma, &malt, &err, &rest); + lsq_y_ax_b(ie - ii, xfit, yfit, &sigma, &malt, &err, &rest); malt = std::exp(malt); sigma += 1.0; - malt *= prefactorav*2.0e12/sigma; + malt *= prefactorav * 2.0e12 / sigma; sfree(xfit); sfree(yfit); - } } } @@ -695,15 +712,16 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, fprintf(stderr, "********************************************\n"); - dk_f = calceps(prefactor, md2-mdav2, mj2-mj, mjd-mjdav, eps_rf, FALSE); + dk_f = calceps(prefactor, md2 - mdav2, mj2 - mj, mjd - mjdav, eps_rf, FALSE); fprintf(stderr, "\n\nFluctuations:\n epsilon=%f\n\n", dk_f); - fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD: (%f, %f, %f)\n", md2-mdav2, mj2-mj, mjd-mjdav); + fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD: (%f, %f, %f)\n", md2 - mdav2, mj2 - mj, + mjd - mjdav); fprintf(stderr, "\n********************************************\n"); if (bINT) { - dk_d = calceps(prefactor, md2-mdav2, mj2-mj, corint, eps_rf, TRUE); + dk_d = calceps(prefactor, md2 - mdav2, mj2 - mj, corint, eps_rf, TRUE); fprintf(stderr, "\nStatic dielectric constant using integral and fluctuations: %f\n", dk_d); - fprintf(stderr, "\n < M_JM_D > via integral: %.3f\n", -1.0*corint); + fprintf(stderr, "\n < M_JM_D > via integral: %.3f\n", -1.0 * corint); } fprintf(stderr, "\n***************************************************"); @@ -711,11 +729,11 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, fprintf(stderr, "and corresponding refactor 1.0 / 3.0*V*k_B*T*EPSILON_0: %f \n", prefactor); - if (bACF && (ii < nvfr)) { fprintf(stderr, "Integral and integrated fit to the current acf yields at t=%f:\n", time[vfr[ii]]); - fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n", sgk-malt*std::pow(time[vfr[ii]], sigma), sgk); + fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n", + sgk - malt * std::pow(time[vfr[ii]], sigma), sgk); } if (ei > bi) @@ -723,23 +741,24 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, fprintf(stderr, "\nStart fit at %f ps (%f).\n", time[bi], bfit); fprintf(stderr, "End fit at %f ps (%f).\n\n", time[ei], efit); - snew(xfit, ei-bi+1); - snew(yfit, ei-bi+1); + snew(xfit, ei - bi + 1); + snew(yfit, ei - bi + 1); for (i = bi; i <= ei; i++) { - xfit[i-bi] = time[i]; - yfit[i-bi] = dsp2[i]; + xfit[i - bi] = time[i]; + yfit[i - bi] = dsp2[i]; } - lsq_y_ax_b(ei-bi, xfit, yfit, &sigma, &malt, &err, &rest); + lsq_y_ax_b(ei - bi, xfit, yfit, &sigma, &malt, &err, &rest); sigma *= 1e12; - dk_d = calceps(prefactor, md2, 0.5*malt/prefactorav, corint, eps_rf, TRUE); + dk_d = calceps(prefactor, md2, 0.5 * malt / prefactorav, corint, eps_rf, TRUE); - fprintf(stderr, "Einstein-Helfand fit to the MSD of the translational dipole moment yields:\n\n"); + fprintf(stderr, + "Einstein-Helfand fit to the MSD of the translational dipole moment yields:\n\n"); fprintf(stderr, "sigma=%.4f\n", sigma); - fprintf(stderr, "translational fraction of M^2: %.4f\n", 0.5*malt/prefactorav); + fprintf(stderr, "translational fraction of M^2: %.4f\n", 0.5 * malt / prefactorav); fprintf(stderr, "Dielectric constant using EH: %.4f\n", dk_d); sfree(xfit); @@ -772,115 +791,149 @@ static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, } - -int gmx_current(int argc, char *argv[]) +int gmx_current(int argc, char* argv[]) { - static int nshift = 1000; - static real temp = 300.0; - static real eps_rf = 0.0; - static gmx_bool bNoJump = TRUE; - static real bfit = 100.0; - static real bvit = 0.5; - static real efit = 400.0; - static real evit = 5.0; - t_pargs pa[] = { - { "-sh", FALSE, etINT, {&nshift}, - "Shift of the frames for averaging the correlation functions and the mean-square displacement."}, - { "-nojump", FALSE, etBOOL, {&bNoJump}, - "Removes jumps of atoms across the box."}, - { "-eps", FALSE, etREAL, {&eps_rf}, - "Dielectric constant of the surrounding medium. The value zero corresponds to infinity (tin-foil boundary conditions)."}, - { "-bfit", FALSE, etREAL, {&bfit}, - "Begin of the fit of the straight line to the MSD of the translational fraction of the dipole moment."}, - { "-efit", FALSE, etREAL, {&efit}, - "End of the fit of the straight line to the MSD of the translational fraction of the dipole moment."}, - { "-bvit", FALSE, etREAL, {&bvit}, - "Begin of the fit of the current autocorrelation function to a*t^b."}, - { "-evit", FALSE, etREAL, {&evit}, - "End of the fit of the current autocorrelation function to a*t^b."}, - { "-temp", FALSE, etREAL, {&temp}, - "Temperature for calculating epsilon."} + static int nshift = 1000; + static real temp = 300.0; + static real eps_rf = 0.0; + static gmx_bool bNoJump = TRUE; + static real bfit = 100.0; + static real bvit = 0.5; + static real efit = 400.0; + static real evit = 5.0; + t_pargs pa[] = { + { "-sh", + FALSE, + etINT, + { &nshift }, + "Shift of the frames for averaging the correlation functions and the mean-square " + "displacement." }, + { "-nojump", FALSE, etBOOL, { &bNoJump }, "Removes jumps of atoms across the box." }, + { "-eps", + FALSE, + etREAL, + { &eps_rf }, + "Dielectric constant of the surrounding medium. The value zero corresponds to " + "infinity (tin-foil boundary conditions)." }, + { "-bfit", + FALSE, + etREAL, + { &bfit }, + "Begin of the fit of the straight line to the MSD of the translational fraction " + "of the dipole moment." }, + { "-efit", + FALSE, + etREAL, + { &efit }, + "End of the fit of the straight line to the MSD of the translational fraction of " + "the dipole moment." }, + { "-bvit", + FALSE, + etREAL, + { &bvit }, + "Begin of the fit of the current autocorrelation function to a*t^b." }, + { "-evit", + FALSE, + etREAL, + { &evit }, + "End of the fit of the current autocorrelation function to a*t^b." }, + { "-temp", FALSE, etREAL, { &temp }, "Temperature for calculating epsilon." } }; - gmx_output_env_t *oenv; - t_topology top; - char **grpname = nullptr; - const char *indexfn; - t_trxframe fr; - real *mass2 = nullptr; - matrix box; - int *index0; - int *indexm = nullptr; - int isize; - t_trxstatus *status; - int flags = 0; - gmx_bool bACF; - gmx_bool bINT; - int ePBC = -1; - int nmols; - int i; - real *qmol; - FILE *outf = nullptr; - FILE *mcor = nullptr; - FILE *fmj = nullptr; - FILE *fmd = nullptr; - FILE *fmjdsp = nullptr; - FILE *fcur = nullptr; - t_filenm fnm[] = { - { efTPS, nullptr, nullptr, ffREAD }, /* this is for the topology */ - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ - { efXVG, "-o", "current", ffWRITE }, - { efXVG, "-caf", "caf", ffOPTWR }, - { efXVG, "-dsp", "dsp", ffWRITE }, - { efXVG, "-md", "md", ffWRITE }, - { efXVG, "-mj", "mj", ffWRITE }, - { efXVG, "-mc", "mc", ffOPTWR } - }; + gmx_output_env_t* oenv; + t_topology top; + char** grpname = nullptr; + const char* indexfn; + t_trxframe fr; + real* mass2 = nullptr; + matrix box; + int* index0; + int* indexm = nullptr; + int isize; + t_trxstatus* status; + int flags = 0; + gmx_bool bACF; + gmx_bool bINT; + int ePBC = -1; + int nmols; + int i; + real* qmol; + FILE* outf = nullptr; + FILE* mcor = nullptr; + FILE* fmj = nullptr; + FILE* fmd = nullptr; + FILE* fmjdsp = nullptr; + FILE* fcur = nullptr; + t_filenm fnm[] = { { efTPS, nullptr, nullptr, ffREAD }, /* this is for the topology */ + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ + { efXVG, "-o", "current", ffWRITE }, + { efXVG, "-caf", "caf", ffOPTWR }, + { efXVG, "-dsp", "dsp", ffWRITE }, + { efXVG, "-md", "md", ffWRITE }, + { efXVG, "-mj", "mj", ffWRITE }, + { efXVG, "-mc", "mc", ffOPTWR } }; #define NFILE asize(fnm) - const char *desc[] = { - "[THISMODULE] is a tool for calculating the current autocorrelation function, the correlation", + const char* desc[] = { + "[THISMODULE] is a tool for calculating the current autocorrelation function, the " + "correlation", "of the rotational and translational dipole moment of the system, and the resulting static", "dielectric constant. To obtain a reasonable result, the index group has to be neutral.", - "Furthermore, the routine is capable of extracting the static conductivity from the current ", + "Furthermore, the routine is capable of extracting the static conductivity from the " + "current ", "autocorrelation function, if velocities are given. Additionally, an Einstein-Helfand fit ", "can be used to obtain the static conductivity.", "[PAR]", - "The flag [TT]-caf[tt] is for the output of the current autocorrelation function and [TT]-mc[tt] writes the", - "correlation of the rotational and translational part of the dipole moment in the corresponding", + "The flag [TT]-caf[tt] is for the output of the current autocorrelation function and " + "[TT]-mc[tt] writes the", + "correlation of the rotational and translational part of the dipole moment in the " + "corresponding", "file. However, this option is only available for trajectories containing velocities.", - "Options [TT]-sh[tt] and [TT]-tr[tt] are responsible for the averaging and integration of the", + "Options [TT]-sh[tt] and [TT]-tr[tt] are responsible for the averaging and integration of " + "the", "autocorrelation functions. Since averaging proceeds by shifting the starting point", - "through the trajectory, the shift can be modified with [TT]-sh[tt] to enable the choice of uncorrelated", + "through the trajectory, the shift can be modified with [TT]-sh[tt] to enable the choice " + "of uncorrelated", "starting points. Towards the end, statistical inaccuracy grows and integrating the", "correlation function only yields reliable values until a certain point, depending on", - "the number of frames. The option [TT]-tr[tt] controls the region of the integral taken into account", + "the number of frames. The option [TT]-tr[tt] controls the region of the integral taken " + "into account", "for calculating the static dielectric constant.", "[PAR]", - "Option [TT]-temp[tt] sets the temperature required for the computation of the static dielectric constant.", + "Option [TT]-temp[tt] sets the temperature required for the computation of the static " + "dielectric constant.", "[PAR]", - "Option [TT]-eps[tt] controls the dielectric constant of the surrounding medium for simulations using", - "a Reaction Field or dipole corrections of the Ewald summation ([TT]-eps[tt]\\=0 corresponds to", + "Option [TT]-eps[tt] controls the dielectric constant of the surrounding medium for " + "simulations using", + "a Reaction Field or dipole corrections of the Ewald summation ([TT]-eps[tt]\\=0 " + "corresponds to", "tin-foil boundary conditions).", "[PAR]", - "[TT]-[no]nojump[tt] unfolds the coordinates to allow free diffusion. This is required to get a continuous", - "translational dipole moment, required for the Einstein-Helfand fit. The results from the fit allow", - "the determination of the dielectric constant for system of charged molecules. However, it is also possible to extract", - "the dielectric constant from the fluctuations of the total dipole moment in folded coordinates. But this", - "option has to be used with care, since only very short time spans fulfill the approximation that the density", - "of the molecules is approximately constant and the averages are already converged. To be on the safe side,", - "the dielectric constant should be calculated with the help of the Einstein-Helfand method for", + "[TT]-[no]nojump[tt] unfolds the coordinates to allow free diffusion. This is required to " + "get a continuous", + "translational dipole moment, required for the Einstein-Helfand fit. The results from the " + "fit allow", + "the determination of the dielectric constant for system of charged molecules. However, it " + "is also possible to extract", + "the dielectric constant from the fluctuations of the total dipole moment in folded " + "coordinates. But this", + "option has to be used with care, since only very short time spans fulfill the " + "approximation that the density", + "of the molecules is approximately constant and the averages are already converged. To be " + "on the safe side,", + "the dielectric constant should be calculated with the help of the Einstein-Helfand method " + "for", "the translational part of the dielectric constant." }; /* At first the arguments will be parsed and the system information processed */ - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -921,13 +974,12 @@ int gmx_current(int argc, char *argv[]) { if (bACF) { - outf = xvgropen(opt2fn("-caf", NFILE, fnm), - "Current autocorrelation function", output_env_get_xvgr_tlabel(oenv), - "ACF (e nm/ps)\\S2", oenv); + outf = xvgropen(opt2fn("-caf", NFILE, fnm), "Current autocorrelation function", + output_env_get_xvgr_tlabel(oenv), "ACF (e nm/ps)\\S2", oenv); fprintf(outf, "# time\t acf\t average \t std.dev\n"); } - fcur = xvgropen(opt2fn("-o", NFILE, fnm), - "Current", output_env_get_xvgr_tlabel(oenv), "J(t) (e nm/ps)", oenv); + fcur = xvgropen(opt2fn("-o", NFILE, fnm), "Current", output_env_get_xvgr_tlabel(oenv), + "J(t) (e nm/ps)", oenv); fprintf(fcur, "# time\t Jx\t Jy \t J_z \n"); if (bINT) { @@ -939,28 +991,24 @@ int gmx_current(int argc, char *argv[]) } } - fmj = xvgropen(opt2fn("-mj", NFILE, fnm), - "Averaged translational part of M", output_env_get_xvgr_tlabel(oenv), - "< M\\sJ\\N > (enm)", oenv); + fmj = xvgropen(opt2fn("-mj", NFILE, fnm), "Averaged translational part of M", + output_env_get_xvgr_tlabel(oenv), "< M\\sJ\\N > (enm)", oenv); fprintf(fmj, "# time\t x\t y \t z \t average of M_J^2 \t std.dev\n"); - fmd = xvgropen(opt2fn("-md", NFILE, fnm), - "Averaged rotational part of M", output_env_get_xvgr_tlabel(oenv), - "< M\\sD\\N > (enm)", oenv); + fmd = xvgropen(opt2fn("-md", NFILE, fnm), "Averaged rotational part of M", + output_env_get_xvgr_tlabel(oenv), "< M\\sD\\N > (enm)", oenv); fprintf(fmd, "# time\t x\t y \t z \t average of M_D^2 \t std.dev\n"); - fmjdsp = xvgropen(opt2fn("-dsp", NFILE, fnm), - "MSD of the squared translational dipole moment M", - output_env_get_xvgr_tlabel(oenv), - "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N", - oenv); + fmjdsp = xvgropen( + opt2fn("-dsp", NFILE, fnm), "MSD of the squared translational dipole moment M", + output_env_get_xvgr_tlabel(oenv), + "<|M\\sJ\\N(t)-M\\sJ\\N(0)|\\S2\\N > / 6.0*V*k\\sB\\N*T / Sm\\S-1\\Nps\\S-1\\N", oenv); /* System information is read and prepared, dielectric() processes the frames * and calculates the requested quantities */ - dielectric(fmj, fmd, outf, fcur, mcor, fmjdsp, bNoJump, bACF, bINT, ePBC, top, fr, - temp, bfit, efit, bvit, evit, status, isize, nmols, nshift, - index0, indexm, mass2, qmol, eps_rf, oenv); + dielectric(fmj, fmd, outf, fcur, mcor, fmjdsp, bNoJump, bACF, bINT, ePBC, top, fr, temp, bfit, efit, + bvit, evit, status, isize, nmols, nshift, index0, indexm, mass2, qmol, eps_rf, oenv); xvgrclose(fmj); xvgrclose(fmd); diff --git a/src/gromacs/gmxana/gmx_density.cpp b/src/gromacs/gmxana/gmx_density.cpp index a50fece7de..9525795f2a 100644 --- a/src/gromacs/gmxana/gmx_density.cpp +++ b/src/gromacs/gmxana/gmx_density.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,8 +60,9 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -typedef struct { - char *atomname; +typedef struct +{ + char* atomname; int nr_el; } t_electron; @@ -71,22 +72,23 @@ typedef struct { /****************************************************************************/ /* used for sorting the list */ -static int compare(void *a, void *b) +static int compare(void* a, void* b) { t_electron *tmp1, *tmp2; - tmp1 = static_cast(a); tmp2 = static_cast(b); + tmp1 = static_cast(a); + tmp2 = static_cast(b); return std::strcmp(tmp1->atomname, tmp2->atomname); } -static int get_electrons(t_electron **eltab, const char *fn) +static int get_electrons(t_electron** eltab, const char* fn) { - char buffer[256]; /* to read in a line */ - char tempname[80]; /* buffer to hold name */ - int tempnr; + char buffer[256]; /* to read in a line */ + char tempname[80]; /* buffer to hold name */ + int tempnr; - FILE *in; - int nr; /* number of atomstypes to read */ + FILE* in; + int nr; /* number of atomstypes to read */ int i; if ((in = gmx_ffopen(fn, "r")) == nullptr) @@ -114,7 +116,7 @@ static int get_electrons(t_electron **eltab, const char *fn) } if (sscanf(buffer, "%s = %d", tempname, &tempnr) != 2) { - gmx_fatal(FARGS, "Invalid line in datafile at line %d\n", i+1); + gmx_fatal(FARGS, "Invalid line in datafile at line %d\n", i + 1); } (*eltab)[i].nr_el = tempnr; (*eltab)[i].atomname = gmx_strdup(tempname); @@ -123,14 +125,12 @@ static int get_electrons(t_electron **eltab, const char *fn) /* sort the list */ fprintf(stderr, "Sorting list..\n"); - qsort (*eltab, nr, sizeof(t_electron), - reinterpret_cast(compare)); + qsort(*eltab, nr, sizeof(t_electron), reinterpret_cast(compare)); return nr; } -static void center_coords(t_atoms *atoms, const int *index_center, int ncenter, - matrix box, rvec x0[]) +static void center_coords(t_atoms* atoms, const int* index_center, int ncenter, matrix box, rvec x0[]) { int i, k, m; real tmass, mm; @@ -143,14 +143,14 @@ static void center_coords(t_atoms *atoms, const int *index_center, int ncenter, i = index_center[k]; if (i >= atoms->nr) { - gmx_fatal(FARGS, "Index %d refers to atom %d, which is larger than natoms (%d).", - k+1, i+1, atoms->nr); + gmx_fatal(FARGS, "Index %d refers to atom %d, which is larger than natoms (%d).", k + 1, + i + 1, atoms->nr); } - mm = atoms->atom[i].m; + mm = atoms->atom[i].m; tmass += mm; for (m = 0; (m < DIM); m++) { - com[m] += mm*x0[i][m]; + com[m] += mm * x0[i][m]; } } for (m = 0; (m < DIM); m++) @@ -167,29 +167,38 @@ static void center_coords(t_atoms *atoms, const int *index_center, int ncenter, } } -static void calc_electron_density(const char *fn, int **index, const int gnx[], - double ***slDensity, int *nslices, t_topology *top, - int ePBC, - int axis, int nr_grps, real *slWidth, - t_electron eltab[], int nr, gmx_bool bCenter, - int *index_center, int ncenter, - gmx_bool bRelative, const gmx_output_env_t *oenv) +static void calc_electron_density(const char* fn, + int** index, + const int gnx[], + double*** slDensity, + int* nslices, + t_topology* top, + int ePBC, + int axis, + int nr_grps, + real* slWidth, + t_electron eltab[], + int nr, + gmx_bool bCenter, + int* index_center, + int ncenter, + gmx_bool bRelative, + const gmx_output_env_t* oenv) { - rvec *x0; /* coordinates without pbc */ - matrix box; /* box (3x3) */ + rvec* x0; /* coordinates without pbc */ + matrix box; /* box (3x3) */ double invvol; - int natoms; /* nr. atoms in trj */ - t_trxstatus *status; - int i, n, /* loop indices */ - nr_frames = 0, /* number of frames */ - slice; /* current slice */ - t_electron *found; /* found by bsearch */ - t_electron sought; /* thingie thought by bsearch */ - real boxSz, aveBox; - gmx_rmpbc_t gpbc = nullptr; - - real t, - z; + int natoms; /* nr. atoms in trj */ + t_trxstatus* status; + int i, n, /* loop indices */ + nr_frames = 0, /* number of frames */ + slice; /* current slice */ + t_electron* found; /* found by bsearch */ + t_electron sought; /* thingie thought by bsearch */ + real boxSz, aveBox; + gmx_rmpbc_t gpbc = nullptr; + + real t, z; if (axis < 0 || axis >= DIM) { @@ -229,16 +238,16 @@ static void calc_electron_density(const char *fn, int **index, const int gnx[], center_coords(&top->atoms, index_center, ncenter, box, x0); } - invvol = *nslices/(box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]); + invvol = *nslices / (box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]); if (bRelative) { - *slWidth = 1.0/(*nslices); + *slWidth = 1.0 / (*nslices); boxSz = 1.0; } else { - *slWidth = box[axis][axis]/(*nslices); + *slWidth = box[axis][axis] / (*nslices); boxSz = box[axis][axis]; } @@ -260,13 +269,13 @@ static void calc_electron_density(const char *fn, int **index, const int gnx[], if (bRelative) { - z = z/box[axis][axis]; + z = z / box[axis][axis]; } /* determine which slice atom is in */ if (bCenter) { - slice = static_cast(std::floor( (z-(boxSz/2.0)) / (*slWidth) ) + *nslices/2.); + slice = static_cast(std::floor((z - (boxSz / 2.0)) / (*slWidth)) + *nslices / 2.); } else { @@ -276,9 +285,9 @@ static void calc_electron_density(const char *fn, int **index, const int gnx[], sought.atomname = gmx_strdup(*(top->atoms.atomname[index[n][i]])); /* now find the number of electrons. This is not efficient. */ - found = static_cast(bsearch(&sought, - eltab, nr, sizeof(t_electron), - reinterpret_cast(compare))); + found = static_cast( + bsearch(&sought, eltab, nr, sizeof(t_electron), + reinterpret_cast(compare))); if (found == nullptr) { @@ -287,31 +296,28 @@ static void calc_electron_density(const char *fn, int **index, const int gnx[], } else { - (*slDensity)[n][slice] += (found->nr_el - - top->atoms.atom[index[n][i]].q)*invvol; + (*slDensity)[n][slice] += (found->nr_el - top->atoms.atom[index[n][i]].q) * invvol; } free(sought.atomname); } } nr_frames++; - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); gmx_rmpbc_done(gpbc); /*********** done with status file **********/ close_trx(status); -/* slDensity now contains the total number of electrons per slice, summed - over all frames. Now divide by nr_frames and volume of slice - */ + /* slDensity now contains the total number of electrons per slice, summed + over all frames. Now divide by nr_frames and volume of slice + */ - fprintf(stderr, "\nRead %d frames from trajectory. Counting electrons\n", - nr_frames); + fprintf(stderr, "\nRead %d frames from trajectory. Counting electrons\n", nr_frames); if (bRelative) { - aveBox /= nr_frames; - *slWidth = aveBox/(*nslices); + aveBox /= nr_frames; + *slWidth = aveBox / (*nslices); } for (n = 0; n < nr_grps; n++) @@ -325,25 +331,35 @@ static void calc_electron_density(const char *fn, int **index, const int gnx[], sfree(x0); /* free memory used by coordinate array */ } -static void calc_density(const char *fn, int **index, const int gnx[], - double ***slDensity, int *nslices, t_topology *top, int ePBC, - int axis, int nr_grps, real *slWidth, gmx_bool bCenter, - int *index_center, int ncenter, - gmx_bool bRelative, const gmx_output_env_t *oenv, const char **dens_opt) +static void calc_density(const char* fn, + int** index, + const int gnx[], + double*** slDensity, + int* nslices, + t_topology* top, + int ePBC, + int axis, + int nr_grps, + real* slWidth, + gmx_bool bCenter, + int* index_center, + int ncenter, + gmx_bool bRelative, + const gmx_output_env_t* oenv, + const char** dens_opt) { - rvec *x0; /* coordinates without pbc */ - matrix box; /* box (3x3) */ + rvec* x0; /* coordinates without pbc */ + matrix box; /* box (3x3) */ double invvol; - int natoms; /* nr. atoms in trj */ - t_trxstatus *status; - int i, n, /* loop indices */ - nr_frames = 0, /* number of frames */ - slice; /* current slice */ - real t, - z; - real boxSz, aveBox; - real *den_val; /* values from which the density is calculated */ - gmx_rmpbc_t gpbc = nullptr; + int natoms; /* nr. atoms in trj */ + t_trxstatus* status; + int i, n, /* loop indices */ + nr_frames = 0, /* number of frames */ + slice; /* current slice */ + real t, z; + real boxSz, aveBox; + real* den_val; /* values from which the density is calculated */ + gmx_rmpbc_t gpbc = nullptr; if (axis < 0 || axis >= DIM) { @@ -407,16 +423,16 @@ static void calc_density(const char *fn, int **index, const int gnx[], center_coords(&top->atoms, index_center, ncenter, box, x0); } - invvol = *nslices/(box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]); + invvol = *nslices / (box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]); if (bRelative) { - *slWidth = 1.0/(*nslices); + *slWidth = 1.0 / (*nslices); boxSz = 1.0; } else { - *slWidth = box[axis][axis]/(*nslices); + *slWidth = box[axis][axis] / (*nslices); boxSz = box[axis][axis]; } @@ -438,13 +454,13 @@ static void calc_density(const char *fn, int **index, const int gnx[], if (bRelative) { - z = z/box[axis][axis]; + z = z / box[axis][axis]; } /* determine which slice atom is in */ if (bCenter) { - slice = static_cast(std::floor( (z-(boxSz/2.0)) / (*slWidth) ) + *nslices/2.); + slice = static_cast(std::floor((z - (boxSz / 2.0)) / (*slWidth)) + *nslices / 2.); } else { @@ -464,12 +480,11 @@ static void calc_density(const char *fn, int **index, const int gnx[], slice -= *nslices; } - (*slDensity)[n][slice] += den_val[index[n][i]]*invvol; + (*slDensity)[n][slice] += den_val[index[n][i]] * invvol; } } nr_frames++; - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); gmx_rmpbc_done(gpbc); /*********** done with status file **********/ @@ -479,13 +494,12 @@ static void calc_density(const char *fn, int **index, const int gnx[], frames. Now divide by nr_frames and volume of slice */ - fprintf(stderr, "\nRead %d frames from trajectory. Calculating density\n", - nr_frames); + fprintf(stderr, "\nRead %d frames from trajectory. Calculating density\n", nr_frames); if (bRelative) { - aveBox /= nr_frames; - *slWidth = aveBox/(*nslices); + aveBox /= nr_frames; + *slWidth = aveBox / (*nslices); } for (n = 0; n < nr_grps; n++) @@ -500,16 +514,22 @@ static void calc_density(const char *fn, int **index, const int gnx[], sfree(den_val); } -static void plot_density(double *slDensity[], const char *afile, int nslices, - int nr_grps, char *grpname[], real slWidth, - const char **dens_opt, - gmx_bool bCenter, gmx_bool bRelative, gmx_bool bSymmetrize, - const gmx_output_env_t *oenv) +static void plot_density(double* slDensity[], + const char* afile, + int nslices, + int nr_grps, + char* grpname[], + real slWidth, + const char** dens_opt, + gmx_bool bCenter, + gmx_bool bRelative, + gmx_bool bSymmetrize, + const gmx_output_env_t* oenv) { - FILE *den; - const char *title = nullptr; - const char *xlabel = nullptr; - const char *ylabel = nullptr; + FILE* den; + const char* title = nullptr; + const char* xlabel = nullptr; + const char* ylabel = nullptr; int slice, n; real ddd; real axispos; @@ -518,9 +538,8 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, if (bCenter) { - xlabel = bRelative ? - "Average relative position from center (nm)" : - "Relative position from center (nm)"; + xlabel = bRelative ? "Average relative position from center (nm)" + : "Relative position from center (nm)"; } else { @@ -535,8 +554,7 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, case 'e': ylabel = "Electron density (e nm\\S-3\\N)"; break; } - den = xvgropen(afile, - title, xlabel, ylabel, oenv); + den = xvgropen(afile, title, xlabel, ylabel, oenv); xvgr_legend(den, nr_grps, grpname, oenv); @@ -544,7 +562,7 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, { if (bCenter) { - axispos = (slice - nslices/2.0 + 0.5) * slWidth; + axispos = (slice - nslices / 2.0 + 0.5) * slWidth; } else { @@ -555,7 +573,7 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, { if (bSymmetrize) { - ddd = (slDensity[n][slice]+slDensity[n][nslices-slice-1])*0.5; + ddd = (slDensity[n][slice] + slDensity[n][nslices - slice - 1]) * 0.5; } else { @@ -563,7 +581,7 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, } if (dens_opt[0][0] == 'm') { - fprintf(den, " %12g", ddd*AMU/(NANO*NANO*NANO)); + fprintf(den, " %12g", ddd * AMU / (NANO * NANO * NANO)); } else { @@ -576,9 +594,9 @@ static void plot_density(double *slDensity[], const char *afile, int nslices, xvgrclose(den); } -int gmx_density(int argc, char *argv[]) +int gmx_density(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes partial densities across the box, using an index file.[PAR]", "For the total density of NPT simulations, use [gmx-energy] instead.", "[PAR]", @@ -644,64 +662,74 @@ int gmx_density(int argc, char *argv[]) "", }; - gmx_output_env_t *oenv; - static const char *dens_opt[] = - { nullptr, "mass", "number", "charge", "electron", nullptr }; - static int axis = 2; /* normal to memb. default z */ - static const char *axtitle = "Z"; + gmx_output_env_t* oenv; + static const char* dens_opt[] = { nullptr, "mass", "number", "charge", "electron", nullptr }; + static int axis = 2; /* normal to memb. default z */ + static const char* axtitle = "Z"; static int nslices = 50; /* nr of slices defined */ static int ngrps = 1; /* nr. of groups */ static gmx_bool bSymmetrize = FALSE; static gmx_bool bCenter = FALSE; static gmx_bool bRelative = FALSE; - t_pargs pa[] = { - { "-d", FALSE, etSTR, {&axtitle}, + t_pargs pa[] = { + { "-d", + FALSE, + etSTR, + { &axtitle }, "Take the normal on the membrane in direction X, Y or Z." }, - { "-sl", FALSE, etINT, {&nslices}, - "Divide the box in this number of slices." }, - { "-dens", FALSE, etENUM, {dens_opt}, - "Density"}, - { "-ng", FALSE, etINT, {&ngrps}, - "Number of groups of which to compute densities." }, - { "-center", FALSE, etBOOL, {&bCenter}, - "Perform the binning relative to the center of the (changing) box. Useful for bilayers." }, - { "-symm", FALSE, etBOOL, {&bSymmetrize}, - "Symmetrize the density along the axis, with respect to the center. Useful for bilayers." }, - { "-relative", FALSE, etBOOL, {&bRelative}, + { "-sl", FALSE, etINT, { &nslices }, "Divide the box in this number of slices." }, + { "-dens", FALSE, etENUM, { dens_opt }, "Density" }, + { "-ng", FALSE, etINT, { &ngrps }, "Number of groups of which to compute densities." }, + { "-center", + FALSE, + etBOOL, + { &bCenter }, + "Perform the binning relative to the center of the (changing) box. Useful for " + "bilayers." }, + { "-symm", + FALSE, + etBOOL, + { &bSymmetrize }, + "Symmetrize the density along the axis, with respect to the center. Useful for " + "bilayers." }, + { "-relative", + FALSE, + etBOOL, + { &bRelative }, "Use relative coordinates for changing boxes and scale output by average dimensions." } }; - const char *bugs[] = { + const char* bugs[] = { "When calculating electron densities, atomnames are used instead of types. This is bad.", }; - double **density; /* density per slice */ - real slWidth; /* width of one slice */ - char *grpname_center; /* centering group name */ - char **grpname; /* groupnames */ - int nr_electrons; /* nr. electrons */ - int ncenter; /* size of centering group */ - int *ngx; /* sizes of groups */ - t_electron *el_tab; /* tabel with nr. of electrons*/ - t_topology *top; /* topology */ - int ePBC; - int *index_center; /* index for centering group */ - int **index; /* indices for all groups */ - - t_filenm fnm[] = { /* files for g_density */ - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTPR, nullptr, nullptr, ffREAD }, + double** density; /* density per slice */ + real slWidth; /* width of one slice */ + char* grpname_center; /* centering group name */ + char** grpname; /* groupnames */ + int nr_electrons; /* nr. electrons */ + int ncenter; /* size of centering group */ + int* ngx; /* sizes of groups */ + t_electron* el_tab; /* tabel with nr. of electrons*/ + t_topology* top; /* topology */ + int ePBC; + int* index_center; /* index for centering group */ + int** index; /* indices for all groups */ + + t_filenm fnm[] = { + /* files for g_density */ + { efTRX, "-f", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTPR, nullptr, nullptr, ffREAD }, { efDAT, "-ei", "electrons", ffOPTRD }, /* file with nr. of electrons */ { efXVG, "-o", "density", ffWRITE }, }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } @@ -729,8 +757,7 @@ int gmx_density(int argc, char *argv[]) "any special periodicity. If necessary, it is your responsibility to first use\n" "trjconv to make sure atoms in this group are placed in the right periodicity.\n\n" "Select the group to center density profiles around:\n"); - get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ncenter, - &index_center, &grpname_center); + get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ncenter, &index_center, &grpname_center); } else { @@ -743,25 +770,22 @@ int gmx_density(int argc, char *argv[]) if (dens_opt[0][0] == 'e') { - nr_electrons = get_electrons(&el_tab, ftp2fn(efDAT, NFILE, fnm)); + nr_electrons = get_electrons(&el_tab, ftp2fn(efDAT, NFILE, fnm)); fprintf(stderr, "Read %d atomtypes from datafile\n", nr_electrons); - calc_electron_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, - &nslices, top, ePBC, axis, ngrps, &slWidth, el_tab, - nr_electrons, bCenter, index_center, ncenter, - bRelative, oenv); + calc_electron_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top, ePBC, + axis, ngrps, &slWidth, el_tab, nr_electrons, bCenter, index_center, + ncenter, bRelative, oenv); } else { - calc_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top, - ePBC, axis, ngrps, &slWidth, bCenter, index_center, ncenter, - bRelative, oenv, dens_opt); + calc_density(ftp2fn(efTRX, NFILE, fnm), index, ngx, &density, &nslices, top, ePBC, axis, + ngrps, &slWidth, bCenter, index_center, ncenter, bRelative, oenv, dens_opt); } - plot_density(density, opt2fn("-o", NFILE, fnm), - nslices, ngrps, grpname, slWidth, dens_opt, + plot_density(density, opt2fn("-o", NFILE, fnm), nslices, ngrps, grpname, slWidth, dens_opt, bCenter, bRelative, bSymmetrize, oenv); - do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); /* view xvgr file */ + do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); /* view xvgr file */ return 0; } diff --git a/src/gromacs/gmxana/gmx_densmap.cpp b/src/gromacs/gmxana/gmx_densmap.cpp index 8ba3593944..1e98fb8f7c 100644 --- a/src/gromacs/gmxana/gmx_densmap.cpp +++ b/src/gromacs/gmxana/gmx_densmap.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,14 +58,15 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -int gmx_densmap(int argc, char *argv[]) +int gmx_densmap(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes 2D number-density maps.", "It can make planar and axial-radial density maps.", "The output [REF].xpm[ref] file can be visualized with for instance xv", "and can be converted to postscript with [TT]xpm2ps[tt].", - "Optionally, output can be in text form to a [REF].dat[ref] file with [TT]-od[tt], instead of the usual [REF].xpm[ref] file with [TT]-o[tt].", + "Optionally, output can be in text form to a [REF].dat[ref] file with [TT]-od[tt], ", + "instead of the usual [REF].xpm[ref] file with [TT]-o[tt].", "[PAR]", "The default analysis is a 2-D number-density map for a selected", "group of atoms in the x-y plane.", @@ -94,74 +95,59 @@ int gmx_densmap(int argc, char *argv[]) "from zero to the maximum density, you can set the maximum", "with the option [TT]-dmax[tt]." }; - static int n1 = 0, n2 = 0; - static real xmin = -1, xmax = -1, bin = 0.02, dmin = 0, dmax = 0, amax = 0, rmax = 0; + static int n1 = 0, n2 = 0; + static real xmin = -1, xmax = -1, bin = 0.02, dmin = 0, dmax = 0, amax = 0, rmax = 0; static gmx_bool bMirror = FALSE, bSums = FALSE; - static const char *eaver[] = { nullptr, "z", "y", "x", nullptr }; - static const char *eunit[] = { nullptr, "nm-3", "nm-2", "count", nullptr }; + static const char* eaver[] = { nullptr, "z", "y", "x", nullptr }; + static const char* eunit[] = { nullptr, "nm-3", "nm-2", "count", nullptr }; - t_pargs pa[] = { - { "-bin", FALSE, etREAL, {&bin}, - "Grid size (nm)" }, - { "-aver", FALSE, etENUM, {eaver}, - "The direction to average over" }, - { "-xmin", FALSE, etREAL, {&xmin}, - "Minimum coordinate for averaging" }, - { "-xmax", FALSE, etREAL, {&xmax}, - "Maximum coordinate for averaging" }, - { "-n1", FALSE, etINT, {&n1}, - "Number of grid cells in the first direction" }, - { "-n2", FALSE, etINT, {&n2}, - "Number of grid cells in the second direction" }, - { "-amax", FALSE, etREAL, {&amax}, - "Maximum axial distance from the center"}, - { "-rmax", FALSE, etREAL, {&rmax}, - "Maximum radial distance" }, - { "-mirror", FALSE, etBOOL, {&bMirror}, - "Add the mirror image below the axial axis" }, - { "-sums", FALSE, etBOOL, {&bSums}, - "Print density sums (1D map) to stdout" }, - { "-unit", FALSE, etENUM, {eunit}, - "Unit for the output" }, - { "-dmin", FALSE, etREAL, {&dmin}, - "Minimum density in output"}, - { "-dmax", FALSE, etREAL, {&dmax}, - "Maximum density in output (0 means calculate it)"}, - }; - gmx_bool bXmin, bXmax, bRadial; - FILE *fp; - t_trxstatus *status; - t_topology top; - int ePBC = -1; - rvec *x, xcom[2], direction, center, dx; - matrix box; - real t, m, mtot; - t_pbc pbc; - int cav = 0, c1 = 0, c2 = 0; - char **grpname, buf[STRLEN]; - const char *unit; - int i, j, k, l, ngrps, anagrp, *gnx = nullptr, nindex, nradial = 0, nfr, nmpower; - int **ind = nullptr, *index; - real **grid, maxgrid, m1, m2, box1, box2, *tickx, *tickz, invcellvol; - real invspa = 0, invspz = 0, axial, r, vol_old, vol, rowsum; - int nlev = 51; - t_rgb rlo = {1, 1, 1}, rhi = {0, 0, 0}; - gmx_output_env_t *oenv; - const char *label[] = { "x (nm)", "y (nm)", "z (nm)" }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-od", "densmap", ffOPTWR }, - { efXPM, "-o", "densmap", ffWRITE } + t_pargs pa[] = { + { "-bin", FALSE, etREAL, { &bin }, "Grid size (nm)" }, + { "-aver", FALSE, etENUM, { eaver }, "The direction to average over" }, + { "-xmin", FALSE, etREAL, { &xmin }, "Minimum coordinate for averaging" }, + { "-xmax", FALSE, etREAL, { &xmax }, "Maximum coordinate for averaging" }, + { "-n1", FALSE, etINT, { &n1 }, "Number of grid cells in the first direction" }, + { "-n2", FALSE, etINT, { &n2 }, "Number of grid cells in the second direction" }, + { "-amax", FALSE, etREAL, { &amax }, "Maximum axial distance from the center" }, + { "-rmax", FALSE, etREAL, { &rmax }, "Maximum radial distance" }, + { "-mirror", FALSE, etBOOL, { &bMirror }, "Add the mirror image below the axial axis" }, + { "-sums", FALSE, etBOOL, { &bSums }, "Print density sums (1D map) to stdout" }, + { "-unit", FALSE, etENUM, { eunit }, "Unit for the output" }, + { "-dmin", FALSE, etREAL, { &dmin }, "Minimum density in output" }, + { "-dmax", FALSE, etREAL, { &dmax }, "Maximum density in output (0 means calculate it)" }, }; + gmx_bool bXmin, bXmax, bRadial; + FILE* fp; + t_trxstatus* status; + t_topology top; + int ePBC = -1; + rvec * x, xcom[2], direction, center, dx; + matrix box; + real t, m, mtot; + t_pbc pbc; + int cav = 0, c1 = 0, c2 = 0; + char ** grpname, buf[STRLEN]; + const char* unit; + int i, j, k, l, ngrps, anagrp, *gnx = nullptr, nindex, nradial = 0, nfr, nmpower; + int ** ind = nullptr, *index; + real ** grid, maxgrid, m1, m2, box1, box2, *tickx, *tickz, invcellvol; + real invspa = 0, invspz = 0, axial, r, vol_old, vol, rowsum; + int nlev = 51; + t_rgb rlo = { 1, 1, 1 }, rhi = { 0, 0, 0 }; + gmx_output_env_t* oenv; + const char* label[] = { "x (nm)", "y (nm)", "z (nm)" }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efDAT, "-od", "densmap", ffOPTWR }, + { efXPM, "-o", "densmap", ffWRITE } }; #define NFILE asize(fnm) - int npargs; + int npargs; npargs = asize(pa); - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -197,8 +183,7 @@ int gmx_densmap(int argc, char *argv[]) if (ftp2bSet(efTPS, NFILE, fnm) || !ftp2bSet(efNDX, NFILE, fnm)) { - read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, nullptr, box, - bRadial); + read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &x, nullptr, box, bRadial); } if (!bRadial) { @@ -208,8 +193,7 @@ int gmx_densmap(int argc, char *argv[]) else { ngrps = 3; - fprintf(stderr, - "\nSelect two groups to define the axis and an analysis group\n"); + fprintf(stderr, "\nSelect two groups to define the axis and an analysis group\n"); } snew(gnx, ngrps); snew(grpname, ngrps); @@ -222,7 +206,9 @@ int gmx_densmap(int argc, char *argv[]) { if ((gnx[0] > 1 || gnx[1] > 1) && !ftp2bSet(efTPS, NFILE, fnm)) { - gmx_fatal(FARGS, "No run input file was supplied (option -s), this is required for the center of mass calculation"); + gmx_fatal(FARGS, + "No run input file was supplied (option -s), this is required for the center " + "of mass calculation"); } } @@ -230,9 +216,21 @@ int gmx_densmap(int argc, char *argv[]) switch (eaver[0][0]) { - case 'x': cav = XX; c1 = YY; c2 = ZZ; break; - case 'y': cav = YY; c1 = XX; c2 = ZZ; break; - case 'z': cav = ZZ; c1 = XX; c2 = YY; break; + case 'x': + cav = XX; + c1 = YY; + c2 = ZZ; + break; + case 'y': + cav = YY; + c1 = XX; + c2 = ZZ; + break; + case 'z': + cav = ZZ; + c1 = XX; + c2 = YY; + break; } read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); @@ -241,22 +239,22 @@ int gmx_densmap(int argc, char *argv[]) { if (n1 == 0) { - n1 = gmx::roundToInt(box[c1][c1]/bin); + n1 = gmx::roundToInt(box[c1][c1] / bin); } if (n2 == 0) { - n2 = gmx::roundToInt(box[c2][c2]/bin); + n2 = gmx::roundToInt(box[c2][c2] / bin); } } else { - n1 = gmx::roundToInt(2*amax/bin); - nradial = gmx::roundToInt(rmax/bin); - invspa = n1/(2*amax); - invspz = nradial/rmax; + n1 = gmx::roundToInt(2 * amax / bin); + nradial = gmx::roundToInt(rmax / bin); + invspa = n1 / (2 * amax); + invspz = nradial / rmax; if (bMirror) { - n2 = 2*nradial; + n2 = 2 * nradial; } else { @@ -277,24 +275,23 @@ int gmx_densmap(int argc, char *argv[]) { if (!bRadial) { - box1 += box[c1][c1]; - box2 += box[c2][c2]; - invcellvol = n1*n2; + box1 += box[c1][c1]; + box2 += box[c2][c2]; + invcellvol = n1 * n2; if (nmpower == -3) { invcellvol /= det(box); } else if (nmpower == -2) { - invcellvol /= box[c1][c1]*box[c2][c2]; + invcellvol /= box[c1][c1] * box[c2][c2]; } for (i = 0; i < nindex; i++) { j = index[i]; - if ((!bXmin || x[j][cav] >= xmin) && - (!bXmax || x[j][cav] <= xmax)) + if ((!bXmin || x[j][cav] >= xmin) && (!bXmax || x[j][cav] <= xmax)) { - m1 = x[j][c1]/box[c1][c1]; + m1 = x[j][c1] / box[c1][c1]; if (m1 >= 1) { m1 -= 1; @@ -303,7 +300,7 @@ int gmx_densmap(int argc, char *argv[]) { m1 += 1; } - m2 = x[j][c2]/box[c2][c2]; + m2 = x[j][c2] / box[c2][c2]; if (m2 >= 1) { m2 -= 1; @@ -312,7 +309,7 @@ int gmx_densmap(int argc, char *argv[]) { m2 += 1; } - grid[static_cast(m1*n1)][static_cast(m2*n2)] += invcellvol; + grid[static_cast(m1 * n1)][static_cast(m2 * n2)] += invcellvol; } } } @@ -337,17 +334,17 @@ int gmx_densmap(int argc, char *argv[]) m = top.atoms.atom[k].m; for (l = 0; l < DIM; l++) { - xcom[i][l] += m*x[k][l]; + xcom[i][l] += m * x[k][l]; } mtot += m; } - svmul(1/mtot, xcom[i], xcom[i]); + svmul(1 / mtot, xcom[i], xcom[i]); } } pbc_dx(&pbc, xcom[1], xcom[0], direction); for (i = 0; i < DIM; i++) { - center[i] = xcom[0][i] + 0.5*direction[i]; + center[i] = xcom[0][i] + 0.5 * direction[i]; } unitv(direction, direction); for (i = 0; i < nindex; i++) @@ -355,20 +352,19 @@ int gmx_densmap(int argc, char *argv[]) j = index[i]; pbc_dx(&pbc, x[j], center, dx); axial = iprod(dx, direction); - r = std::sqrt(norm2(dx) - axial*axial); + r = std::sqrt(norm2(dx) - axial * axial); if (axial >= -amax && axial < amax && r < rmax) { if (bMirror) { r += rmax; } - grid[static_cast((axial + amax)*invspa)][static_cast(r*invspz)] += 1; + grid[static_cast((axial + amax) * invspa)][static_cast(r * invspz)] += 1; } } } nfr++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); /* normalize gridpoints */ @@ -396,9 +392,9 @@ int gmx_densmap(int argc, char *argv[]) { switch (nmpower) { - case -3: vol = M_PI*(j+1)*(j+1)/(invspz*invspz*invspa); break; - case -2: vol = (j+1)/(invspz*invspa); break; - default: vol = j+1; break; + case -3: vol = M_PI * (j + 1) * (j + 1) / (invspz * invspz * invspa); break; + case -2: vol = (j + 1) / (invspz * invspa); break; + default: vol = j + 1; break; } if (bMirror) { @@ -408,10 +404,10 @@ int gmx_densmap(int argc, char *argv[]) { k = j; } - grid[i][k] /= nfr*(vol - vol_old); + grid[i][k] /= nfr * (vol - vol_old); if (bMirror) { - grid[i][nradial-1-j] = grid[i][k]; + grid[i][nradial - 1 - j] = grid[i][k]; } vol_old = vol; if (grid[i][k] > maxgrid) @@ -427,8 +423,8 @@ int gmx_densmap(int argc, char *argv[]) maxgrid = dmax; } - snew(tickx, n1+1); - snew(tickz, n2+1); + snew(tickx, n1 + 1); + snew(tickz, n2 + 1); if (!bRadial) { /* normalize box-axes */ @@ -436,31 +432,31 @@ int gmx_densmap(int argc, char *argv[]) box2 /= nfr; for (i = 0; i <= n1; i++) { - tickx[i] = i*box1/n1; + tickx[i] = i * box1 / n1; } for (i = 0; i <= n2; i++) { - tickz[i] = i*box2/n2; + tickz[i] = i * box2 / n2; } } else { for (i = 0; i <= n1; i++) { - tickx[i] = i/invspa - amax; + tickx[i] = i / invspa - amax; } if (bMirror) { for (i = 0; i <= n2; i++) { - tickz[i] = i/invspz - rmax; + tickz[i] = i / invspz - rmax; } } else { for (i = 0; i <= n2; i++) { - tickz[i] = i/invspz; + tickz[i] = i / invspz; } } } @@ -485,15 +481,15 @@ int gmx_densmap(int argc, char *argv[]) { if (!bXmax) { - sprintf(buf+std::strlen(buf), ", %c > %g nm", eaver[0][0], xmin); + sprintf(buf + std::strlen(buf), ", %c > %g nm", eaver[0][0], xmin); } else if (!bXmin) { - sprintf(buf+std::strlen(buf), ", %c < %g nm", eaver[0][0], xmax); + sprintf(buf + std::strlen(buf), ", %c < %g nm", eaver[0][0], xmax); } else { - sprintf(buf+std::strlen(buf), ", %c: %g - %g nm", eaver[0][0], xmin, xmax); + sprintf(buf + std::strlen(buf), ", %c: %g - %g nm", eaver[0][0], xmin, xmax); } } if (ftp2bSet(efDAT, NFILE, fnm)) @@ -521,9 +517,9 @@ int gmx_densmap(int argc, char *argv[]) else { fp = gmx_ffopen(ftp2fn(efXPM, NFILE, fnm), "w"); - write_xpm(fp, MAT_SPATIAL_X | MAT_SPATIAL_Y, buf, unit, - bRadial ? "axial (nm)" : label[c1], bRadial ? "r (nm)" : label[c2], - n1, n2, tickx, tickz, grid, dmin, maxgrid, rlo, rhi, &nlev); + write_xpm(fp, MAT_SPATIAL_X | MAT_SPATIAL_Y, buf, unit, bRadial ? "axial (nm)" : label[c1], + bRadial ? "r (nm)" : label[c2], n1, n2, tickx, tickz, grid, dmin, maxgrid, rlo, + rhi, &nlev); gmx_ffclose(fp); } diff --git a/src/gromacs/gmxana/gmx_densorder.cpp b/src/gromacs/gmxana/gmx_densorder.cpp index 6180386555..194a3b4a35 100644 --- a/src/gromacs/gmxana/gmx_densorder.cpp +++ b/src/gromacs/gmxana/gmx_densorder.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,11 +66,15 @@ #include "gromacs/utility/smalloc.h" -enum { - methSEL, methBISECT, methFUNCFIT, methNR +enum +{ + methSEL, + methBISECT, + methFUNCFIT, + methNR }; -static void center_coords(const t_atoms *atoms, matrix box, rvec x0[], int axis) +static void center_coords(const t_atoms* atoms, matrix box, rvec x0[], int axis) { int i, m; real tmass, mm; @@ -79,11 +84,11 @@ static void center_coords(const t_atoms *atoms, matrix box, rvec x0[], int axis) clear_rvec(com); for (i = 0; (i < atoms->nr); i++) { - mm = atoms->atom[i].m; + mm = atoms->atom[i].m; tmass += mm; for (m = 0; (m < DIM); m++) { - com[m] += mm*x0[i][m]; + com[m] += mm * x0[i][m]; } } for (m = 0; (m < DIM); m++) @@ -101,30 +106,45 @@ static void center_coords(const t_atoms *atoms, matrix box, rvec x0[], int axis) } -static void density_in_time (const char *fn, int **index, const int gnx[], real bw, real bwz, int nsttblock, real *****Densdevel, int *xslices, int *yslices, int *zslices, int *tblock, const t_topology *top, int ePBC, int axis, gmx_bool bCenter, gmx_bool bps1d, const gmx_output_env_t *oenv) +static void density_in_time(const char* fn, + int** index, + const int gnx[], + real bw, + real bwz, + int nsttblock, + real***** Densdevel, + int* xslices, + int* yslices, + int* zslices, + int* tblock, + const t_topology* top, + int ePBC, + int axis, + gmx_bool bCenter, + gmx_bool bps1d, + const gmx_output_env_t* oenv) { -/* - * *****Densdevel pointer to array of density values in slices and frame-blocks Densdevel[*nsttblock][*xslices][*yslices][*zslices] - * Densslice[x][y][z] - * nsttblock - nr of frames in each time-block - * bw widths of normal slices - * - * axis - axis direction (normal to slices) - * nndx - number ot atoms in **index - * grpn - group number in index - */ - t_trxstatus *status; + /* + * *****Densdevel pointer to array of density values in slices and frame-blocks + * Densdevel[*nsttblock][*xslices][*yslices][*zslices] Densslice[x][y][z] nsttblock - nr of + * frames in each time-block bw widths of normal slices + * + * axis - axis direction (normal to slices) + * nndx - number ot atoms in **index + * grpn - group number in index + */ + t_trxstatus* status; gmx_rmpbc_t gpbc = nullptr; - matrix box; /* Box - 3x3 -each step*/ - rvec *x0; /* List of Coord without PBC*/ - int i, j, /* loop indices, checks etc*/ - ax1 = 0, ax2 = 0, /* tangent directions */ - framenr = 0, /* frame number in trajectory*/ - slicex, slicey, slicez; /*slice # of x y z position */ - real ***Densslice = nullptr; /* Density-slice in one frame*/ - real dscale; /*physical scaling factor*/ - real t, x, y, z; /* time and coordinates*/ + matrix box; /* Box - 3x3 -each step*/ + rvec* x0; /* List of Coord without PBC*/ + int i, j, /* loop indices, checks etc*/ + ax1 = 0, ax2 = 0, /* tangent directions */ + framenr = 0, /* frame number in trajectory*/ + slicex, slicey, slicez; /*slice # of x y z position */ + real*** Densslice = nullptr; /* Density-slice in one frame*/ + real dscale; /*physical scaling factor*/ + real t, x, y, z; /* time and coordinates*/ rvec bbww; *tblock = 0; /* blocknr in block average - initialise to 0*/ @@ -132,27 +152,27 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real switch (axis) { case 0: - ax1 = YY; ax2 = ZZ; /*Surface: YZ*/ + ax1 = YY; + ax2 = ZZ; /*Surface: YZ*/ break; case 1: - ax1 = ZZ; ax2 = XX; /* Surface : XZ*/ + ax1 = ZZ; + ax2 = XX; /* Surface : XZ*/ break; case 2: - ax1 = XX; ax2 = YY; /* Surface XY*/ + ax1 = XX; + ax2 = YY; /* Surface XY*/ break; - default: - gmx_fatal(FARGS, "Invalid axes. Terminating\n"); + default: gmx_fatal(FARGS, "Invalid axes. Terminating\n"); } if (read_first_x(oenv, &status, fn, &t, &x0, box) == 0) { gmx_fatal(FARGS, "Could not read coordinates from file"); /* Open trajectory for read*/ - - } - *zslices = 1+static_cast(std::floor(box[axis][axis]/bwz)); - *yslices = 1+static_cast(std::floor(box[ax2][ax2]/bw)); - *xslices = 1+static_cast(std::floor(box[ax1][ax1]/bw)); + *zslices = 1 + static_cast(std::floor(box[axis][axis] / bwz)); + *yslices = 1 + static_cast(std::floor(box[ax2][ax2] / bw)); + *xslices = 1 + static_cast(std::floor(box[ax1][ax1] / bw)); if (bps1d) { if (*xslices < *yslices) @@ -164,8 +184,8 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real *yslices = 1; } } - fprintf(stderr, - "\nDividing the box in %5d x %5d x %5d slices with binw %f along axis %d\n", *xslices, *yslices, *zslices, bw, axis ); + fprintf(stderr, "\nDividing the box in %5d x %5d x %5d slices with binw %f along axis %d\n", + *xslices, *yslices, *zslices, bw, axis); /****Start trajectory processing***/ @@ -177,9 +197,9 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real do { - bbww[XX] = box[ax1][ax1]/ *xslices; - bbww[YY] = box[ax2][ax2]/ *yslices; - bbww[ZZ] = box[axis][axis]/ *zslices; + bbww[XX] = box[ax1][ax1] / *xslices; + bbww[YY] = box[ax2][ax2] / *yslices; + bbww[ZZ] = box[axis][axis] / *zslices; gmx_rmpbc(gpbc, top->atoms.nr, box, x0); /*Reset Densslice every nsttblock steps*/ /* The first conditional is for clang to understand that this branch is @@ -199,11 +219,12 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real /* Allocate Memory to extra frame in Densdevel - rather stupid approach: * A single frame each time, although only every nsttblock steps. */ - srenew(*Densdevel, *tblock+1); + srenew(*Densdevel, *tblock + 1); (*Densdevel)[*tblock] = Densslice; } - dscale = (*xslices)*(*yslices)*(*zslices)*AMU/ (box[ax1][ax1]*box[ax2][ax2]*box[axis][axis]*nsttblock*(NANO*NANO*NANO)); + dscale = (*xslices) * (*yslices) * (*zslices) * AMU + / (box[ax1][ax1] * box[ax2][ax2] * box[axis][axis] * nsttblock * (NANO * NANO * NANO)); if (bCenter) { @@ -212,7 +233,7 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real for (j = 0; j < gnx[0]; j++) - { /*Loop over all atoms in selected index*/ + { /*Loop over all atoms in selected index*/ x = x0[index[0][j]][ax1]; y = x0[index[0][j]][ax2]; z = x0[index[0][j]][axis]; @@ -243,10 +264,10 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real z -= box[axis][axis]; } - slicex = static_cast(x/bbww[XX]) % *xslices; - slicey = static_cast(y/bbww[YY]) % *yslices; - slicez = static_cast(z/bbww[ZZ]) % *zslices; - Densslice[slicex][slicey][slicez] += (top->atoms.atom[index[0][j]].m*dscale); + slicex = static_cast(x / bbww[XX]) % *xslices; + slicey = static_cast(y / bbww[YY]) % *yslices; + slicez = static_cast(z / bbww[ZZ]) % *zslices; + Densslice[slicex][slicey][slicez] += (top->atoms.atom[index[0][j]].m * dscale); } framenr++; @@ -258,8 +279,7 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real (*tblock)++; } - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); /*Free memory we no longer need and exit.*/ @@ -268,7 +288,7 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real if (/* DISABLES CODE */ (false)) { - FILE *fp; + FILE* fp; fp = fopen("koko.xvg", "w"); for (j = 0; (j < *zslices); j++) { @@ -281,14 +301,12 @@ static void density_in_time (const char *fn, int **index, const int gnx[], real } fclose(fp); } - } -static void outputfield(const char *fldfn, real ****Densmap, - int xslices, int yslices, int zslices, int tdim) +static void outputfield(const char* fldfn, real**** Densmap, int xslices, int yslices, int zslices, int tdim) { -/*Debug-filename and filehandle*/ - FILE *fldH; + /*Debug-filename and filehandle*/ + FILE* fldH; int n, i, j, k; int dim[4]; real totdens = 0; @@ -314,19 +332,19 @@ static void outputfield(const char *fldfn, real ****Densmap, } } } - totdens /= (xslices*yslices*zslices*tdim); + totdens /= (xslices * yslices * zslices * tdim); fprintf(stderr, "Total density [kg/m^3] %8f", totdens); gmx_ffclose(fldH); } -static void filterdensmap(real ****Densmap, int xslices, int yslices, int zslices, int tblocks, int ftsize) +static void filterdensmap(real**** Densmap, int xslices, int yslices, int zslices, int tblocks, int ftsize) { - real *kernel; + real* kernel; real std, var; int i, j, n, order; - order = ftsize/2; - std = order/2.0; - var = std*std; + order = ftsize / 2; + std = order / 2.0; + var = std * std; snew(kernel, ftsize); gausskernel(kernel, ftsize, var); for (n = 0; n < tblocks; n++) @@ -342,31 +360,38 @@ static void filterdensmap(real ****Densmap, int xslices, int yslices, int zslice } - - -static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zslices, - int tblocks, real binwidth, int method, - real dens1, real dens2, t_interf ****intf1, - t_interf ****intf2, const gmx_output_env_t *oenv) +static void interfaces_txy(real**** Densmap, + int xslices, + int yslices, + int zslices, + int tblocks, + real binwidth, + int method, + real dens1, + real dens2, + t_interf**** intf1, + t_interf**** intf2, + const gmx_output_env_t* oenv) { /*Returns two pointers to 3D arrays of t_interf structs containing (position,thickness) of the interface(s)*/ - FILE *xvg; - real *zDensavg; /* zDensavg[z]*/ + FILE* xvg; + real* zDensavg; /* zDensavg[z]*/ int i, j, k, n; int xysize; int ndx1, ndx2, *zperm; real densmid; real splitpoint, startpoint, endpoint; - real *sigma1, *sigma2; + real * sigma1, *sigma2; double beginfit1[4]; double beginfit2[4]; - double *fit1 = nullptr, *fit2 = nullptr; - const double *avgfit1; - const double *avgfit2; - const real onehalf = 1.00/2.00; - t_interf ***int1 = nullptr, ***int2 = nullptr; /*Interface matrices [t][x,y] - last index in row-major order*/ + double * fit1 = nullptr, *fit2 = nullptr; + const double* avgfit1; + const double* avgfit2; + const real onehalf = 1.00 / 2.00; + t_interf *** int1 = nullptr, + ***int2 = nullptr; /*Interface matrices [t][x,y] - last index in row-major order*/ /*Create int1(t,xy) and int2(t,xy) arrays with correct number of interf_t elements*/ - xysize = xslices*yslices; + xysize = xslices * yslices; snew(int1, tblocks); snew(int2, tblocks); for (i = 0; i < tblocks; i++) @@ -384,7 +409,7 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli if (method == methBISECT) { - densmid = onehalf*(dens1+dens2); + densmid = onehalf * (dens1 + dens2); snew(zperm, zslices); for (n = 0; n < tblocks; n++) { @@ -394,8 +419,8 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli { rangeArray(zperm, zslices); /*reset permutation array to identity*/ /*Binsearch returns slice-nr where the order param is <= setpoint sgmid*/ - ndx1 = start_binsearch(Densmap[n][i][j], zperm, 0, zslices/2-1, densmid, 1); - ndx2 = start_binsearch(Densmap[n][i][j], zperm, zslices/2, zslices-1, densmid, -1); + ndx1 = start_binsearch(Densmap[n][i][j], zperm, 0, zslices / 2 - 1, densmid, 1); + ndx2 = start_binsearch(Densmap[n][i][j], zperm, zslices / 2, zslices - 1, densmid, -1); /* Linear interpolation (for use later if time allows) * rho_1s= Densmap[n][i][j][zperm[ndx1]] @@ -425,10 +450,10 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli * pos=zperm[ndx2]+alpha*deltandx; */ /*After filtering we use the direct approach */ - int1[n][j+(i*yslices)]->Z = (zperm[ndx1]+onehalf)*binwidth; - int1[n][j+(i*yslices)]->t = binwidth; - int2[n][j+(i*yslices)]->Z = (zperm[ndx2]+onehalf)*binwidth; - int2[n][j+(i*yslices)]->t = binwidth; + int1[n][j + (i * yslices)]->Z = (zperm[ndx1] + onehalf) * binwidth; + int1[n][j + (i * yslices)]->t = binwidth; + int2[n][j + (i * yslices)]->Z = (zperm[ndx2] + onehalf) * binwidth; + int2[n][j + (i * yslices)]->t = binwidth; } } } @@ -438,17 +463,17 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli { /*Assume a box divided in 2 along midpoint of z for starters*/ startpoint = 0.0; - endpoint = binwidth*zslices; - splitpoint = (startpoint+endpoint)/2.0; + endpoint = binwidth * zslices; + splitpoint = (startpoint + endpoint) / 2.0; /*Initial fit proposals*/ beginfit1[0] = dens1; beginfit1[1] = dens2; - beginfit1[2] = (splitpoint/2); + beginfit1[2] = (splitpoint / 2); beginfit1[3] = 0.5; beginfit2[0] = dens2; beginfit2[1] = dens1; - beginfit2[2] = (3*splitpoint/2); + beginfit2[2] = (3 * splitpoint / 2); beginfit2[3] = 0.5; snew(zDensavg, zslices); @@ -468,7 +493,7 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli { for (j = 0; j < yslices; j++) { - zDensavg[k] += (Densmap[n][i][j][k]/(xslices*yslices*tblocks)); + zDensavg[k] += (Densmap[n][i][j][k] / (xslices * yslices * tblocks)); } } } @@ -476,10 +501,11 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli if (debug) { - xvg = xvgropen("DensprofileonZ.xvg", "Averaged Densityprofile on Z", "z[nm]", "Density[kg/m^3]", oenv); + xvg = xvgropen("DensprofileonZ.xvg", "Averaged Densityprofile on Z", "z[nm]", + "Density[kg/m^3]", oenv); for (k = 0; k < zslices; k++) { - fprintf(xvg, "%4f.3 %8f.4\n", k*binwidth, zDensavg[k]); + fprintf(xvg, "%4f.3 %8f.4\n", k * binwidth, zDensavg[k]); } xvgrclose(xvg); } @@ -487,16 +513,17 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli /*Fit average density in z over whole trajectory to obtain tentative fit-parameters in fit1 and fit2*/ /*Fit 1st half of box*/ - do_lmfit(zslices, zDensavg, sigma1, binwidth, nullptr, startpoint, splitpoint, oenv, FALSE, effnERF, beginfit1, 8, nullptr); + do_lmfit(zslices, zDensavg, sigma1, binwidth, nullptr, startpoint, splitpoint, oenv, FALSE, + effnERF, beginfit1, 8, nullptr); /*Fit 2nd half of box*/ - do_lmfit(zslices, zDensavg, sigma2, binwidth, nullptr, splitpoint, endpoint, oenv, FALSE, effnERF, beginfit2, 8, nullptr); + do_lmfit(zslices, zDensavg, sigma2, binwidth, nullptr, splitpoint, endpoint, oenv, FALSE, + effnERF, beginfit2, 8, nullptr); /*Initialise the const arrays for storing the average fit parameters*/ avgfit1 = beginfit1; avgfit2 = beginfit2; - /*Now do fit over each x y and t slice to get Zint(x,y,t) - loop is very large, we potentially should average over time directly*/ for (n = 0; n < tblocks; n++) { @@ -513,12 +540,14 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli fit2[k] = avgfit2[k]; } /*Now fit and store in structures in row-major order int[n][i][j]*/ - do_lmfit(zslices, Densmap[n][i][j], sigma1, binwidth, nullptr, startpoint, splitpoint, oenv, FALSE, effnERF, fit1, 0, nullptr); - int1[n][j+(yslices*i)]->Z = fit1[2]; - int1[n][j+(yslices*i)]->t = fit1[3]; - do_lmfit(zslices, Densmap[n][i][j], sigma2, binwidth, nullptr, splitpoint, endpoint, oenv, FALSE, effnERF, fit2, 0, nullptr); - int2[n][j+(yslices*i)]->Z = fit2[2]; - int2[n][j+(yslices*i)]->t = fit2[3]; + do_lmfit(zslices, Densmap[n][i][j], sigma1, binwidth, nullptr, startpoint, + splitpoint, oenv, FALSE, effnERF, fit1, 0, nullptr); + int1[n][j + (yslices * i)]->Z = fit1[2]; + int1[n][j + (yslices * i)]->t = fit1[3]; + do_lmfit(zslices, Densmap[n][i][j], sigma2, binwidth, nullptr, splitpoint, + endpoint, oenv, FALSE, effnERF, fit2, 0, nullptr); + int2[n][j + (yslices * i)]->Z = fit2[2]; + int2[n][j + (yslices * i)]->t = fit2[3]; } } } @@ -527,33 +556,41 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli *intf1 = int1; *intf2 = int2; - } -static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, int xbins, int ybins, int zbins, real bw, real bwz, gmx::ArrayRef outfiles, int maplevels ) +static void writesurftoxpms(t_interf*** surf1, + t_interf*** surf2, + int tblocks, + int xbins, + int ybins, + int zbins, + real bw, + real bwz, + gmx::ArrayRef outfiles, + int maplevels) { char numbuf[STRLEN]; int n, i, j; real **profile1, **profile2; real max1, max2, min1, min2, *xticks, *yticks; - t_rgb lo = {0, 0, 0}; - t_rgb hi = {1, 1, 1}; - FILE *xpmfile1, *xpmfile2; + t_rgb lo = { 0, 0, 0 }; + t_rgb hi = { 1, 1, 1 }; + FILE * xpmfile1, *xpmfile2; -/*Prepare xpm structures for output*/ + /*Prepare xpm structures for output*/ -/*Allocate memory to tick's and matrices*/ - snew (xticks, xbins+1); - snew (yticks, ybins+1); + /*Allocate memory to tick's and matrices*/ + snew(xticks, xbins + 1); + snew(yticks, ybins + 1); profile1 = mk_matrix(xbins, ybins, FALSE); profile2 = mk_matrix(xbins, ybins, FALSE); - for (i = 0; i < xbins+1; i++) + for (i = 0; i < xbins + 1; i++) { xticks[i] += bw; } - for (j = 0; j < ybins+1; j++) + for (j = 0; j < ybins + 1; j++) { yticks[j] += bw; } @@ -562,18 +599,18 @@ static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, i xpmfile2 = gmx_ffopen(outfiles[1], "w"); max1 = max2 = 0.0; - min1 = min2 = zbins*bwz; + min1 = min2 = zbins * bwz; for (n = 0; n < tblocks; n++) { sprintf(numbuf, "tblock: %4i", n); -/*Filling matrices for inclusion in xpm-files*/ + /*Filling matrices for inclusion in xpm-files*/ for (i = 0; i < xbins; i++) { for (j = 0; j < ybins; j++) { - profile1[i][j] = (surf1[n][j+ybins*i])->Z; - profile2[i][j] = (surf2[n][j+ybins*i])->Z; + profile1[i][j] = (surf1[n][j + ybins * i])->Z; + profile2[i][j] = (surf2[n][j + ybins * i])->Z; /*Finding max and min values*/ if (profile1[i][j] > max1) { @@ -594,8 +631,10 @@ static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, i } } - write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile1, min1, max1, lo, hi, &maplevels); - write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile2, min2, max2, lo, hi, &maplevels); + write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, + profile1, min1, max1, lo, hi, &maplevels); + write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, + profile2, min2, max2, lo, hi, &maplevels); } gmx_ffclose(xpmfile1); @@ -608,9 +647,13 @@ static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, i sfree(yticks); } -static void writeraw(t_interf ***int1, t_interf ***int2, int tblocks, - int xbins, int ybins, gmx::ArrayRef fnms, - const gmx_output_env_t *oenv) +static void writeraw(t_interf*** int1, + t_interf*** int2, + int tblocks, + int xbins, + int ybins, + gmx::ArrayRef fnms, + const gmx_output_env_t* oenv) { FILE *raw1, *raw2; int i, j, n; @@ -622,12 +665,10 @@ static void writeraw(t_interf ***int1, t_interf ***int2, int tblocks, gmx::BinaryInformationSettings settings; settings.generatedByHeader(true); settings.linePrefix("# "); - gmx::printBinaryInformation(raw1, output_env_get_program_context(oenv), - settings); - gmx::printBinaryInformation(raw2, output_env_get_program_context(oenv), - settings); + gmx::printBinaryInformation(raw1, output_env_get_program_context(oenv), settings); + gmx::printBinaryInformation(raw2, output_env_get_program_context(oenv), settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR fprintf(raw1, "# Legend: nt nx ny\n# Xbin Ybin Z t\n"); fprintf(raw2, "# Legend: nt nx ny\n# Xbin Ybin Z t\n"); fprintf(raw1, "%i %i %i\n", tblocks, xbins, ybins); @@ -638,8 +679,10 @@ static void writeraw(t_interf ***int1, t_interf ***int2, int tblocks, { for (j = 0; j < ybins; j++) { - fprintf(raw1, "%i %i %8.5f %6.4f\n", i, j, (int1[n][j+ybins*i])->Z, (int1[n][j+ybins*i])->t); - fprintf(raw2, "%i %i %8.5f %6.4f\n", i, j, (int2[n][j+ybins*i])->Z, (int2[n][j+ybins*i])->t); + fprintf(raw1, "%i %i %8.5f %6.4f\n", i, j, (int1[n][j + ybins * i])->Z, + (int1[n][j + ybins * i])->t); + fprintf(raw2, "%i %i %8.5f %6.4f\n", i, j, (int2[n][j + ybins * i])->Z, + (int2[n][j + ybins * i])->t); } } } @@ -649,25 +692,22 @@ static void writeraw(t_interf ***int1, t_interf ***int2, int tblocks, } - -int gmx_densorder(int argc, char *argv[]) +int gmx_densorder(int argc, char* argv[]) { - static const char *desc[] = { - "[THISMODULE] reduces a two-phase density distribution", - "along an axis, computed over a MD trajectory,", - "to 2D surfaces fluctuating in time, by a fit to", - "a functional profile for interfacial densities.", - "A time-averaged spatial representation of the", - "interfaces can be output with the option [TT]-tavg[tt]." - }; + static const char* desc[] = { "[THISMODULE] reduces a two-phase density distribution", + "along an axis, computed over a MD trajectory,", + "to 2D surfaces fluctuating in time, by a fit to", + "a functional profile for interfacial densities.", + "A time-averaged spatial representation of the", + "interfaces can be output with the option [TT]-tavg[tt]." }; /* Extra arguments - but note how you always get the begin/end * options when running the program, without mentioning them here! */ - gmx_output_env_t *oenv; - t_topology *top; - char **grpname; + gmx_output_env_t* oenv; + t_topology* top; + char** grpname; int ePBC, *ngx; static real binw = 0.2; static real binwz = 0.05; @@ -676,8 +716,8 @@ int gmx_densorder(int argc, char *argv[]) static int ftorder = 0; static int nsttblock = 100; static int axis = 2; - static const char *axtitle = "Z"; - int **index; /* Index list for single group*/ + static const char* axtitle = "Z"; + int** index; /* Index list for single group*/ int xslices, yslices, zslices, tblock; static gmx_bool bGraph = FALSE; static gmx_bool bCenter = FALSE; @@ -687,53 +727,58 @@ int gmx_densorder(int argc, char *argv[]) static gmx_bool b1d = FALSE; static int nlevels = 100; /*Densitymap - Densmap[t][x][y][z]*/ - real ****Densmap = nullptr; + real**** Densmap = nullptr; /* Surfaces surf[t][surf_x,surf_y]*/ - t_interf ***surf1, ***surf2; + t_interf ***surf1, ***surf2; - static const char *meth[] = {nullptr, "bisect", "functional", nullptr}; + static const char* meth[] = { nullptr, "bisect", "functional", nullptr }; int eMeth; - t_pargs pa[] = { - { "-1d", FALSE, etBOOL, {&b1d}, - "Pseudo-1d interface geometry"}, - { "-bw", FALSE, etREAL, {&binw}, - "Binwidth of density distribution tangential to interface"}, - { "-bwn", FALSE, etREAL, {&binwz}, - "Binwidth of density distribution normal to interface"}, - { "-order", FALSE, etINT, {&ftorder}, - "Order of Gaussian filter, order 0 equates to NO filtering"}, - {"-axis", FALSE, etSTR, {&axtitle}, - "Axis Direction - X, Y or Z"}, - {"-method", FALSE, etENUM, {meth}, - "Interface location method"}, - {"-d1", FALSE, etREAL, {&dens1}, - "Bulk density phase 1 (at small z)"}, - {"-d2", FALSE, etREAL, {&dens2}, - "Bulk density phase 2 (at large z)"}, - { "-tblock", FALSE, etINT, {&nsttblock}, - "Number of frames in one time-block average"}, - { "-nlevel", FALSE, etINT, {&nlevels}, - "Number of Height levels in 2D - XPixMaps"} + t_pargs pa[] = { + { "-1d", FALSE, etBOOL, { &b1d }, "Pseudo-1d interface geometry" }, + { "-bw", + FALSE, + etREAL, + { &binw }, + "Binwidth of density distribution tangential to interface" }, + { "-bwn", + FALSE, + etREAL, + { &binwz }, + "Binwidth of density distribution normal to interface" }, + { "-order", + FALSE, + etINT, + { &ftorder }, + "Order of Gaussian filter, order 0 equates to NO filtering" }, + { "-axis", FALSE, etSTR, { &axtitle }, "Axis Direction - X, Y or Z" }, + { "-method", FALSE, etENUM, { meth }, "Interface location method" }, + { "-d1", FALSE, etREAL, { &dens1 }, "Bulk density phase 1 (at small z)" }, + { "-d2", FALSE, etREAL, { &dens2 }, "Bulk density phase 2 (at large z)" }, + { "-tblock", FALSE, etINT, { &nsttblock }, "Number of frames in one time-block average" }, + { "-nlevel", FALSE, etINT, { &nlevels }, "Number of Height levels in 2D - XPixMaps" } }; t_filenm fnm[] = { - { efTPR, "-s", nullptr, ffREAD }, /* this is for the topology */ - { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ - { efNDX, "-n", nullptr, ffREAD}, /* this is to select groups */ - { efDAT, "-o", "Density4D", ffOPTWR}, /* This is for outputting the entire 4D densityfield in binary format */ - { efOUT, "-or", nullptr, ffOPTWRMULT}, /* This is for writing out the entire information in the t_interf arrays */ - { efXPM, "-og", "interface", ffOPTWRMULT}, /* This is for writing out the interface meshes - one xpm-file per tblock*/ - { efOUT, "-Spect", "intfspect", ffOPTWRMULT}, /* This is for the trajectory averaged Fourier-spectra*/ + { efTPR, "-s", nullptr, ffREAD }, /* this is for the topology */ + { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ + { efNDX, "-n", nullptr, ffREAD }, /* this is to select groups */ + { efDAT, "-o", "Density4D", + ffOPTWR }, /* This is for outputting the entire 4D densityfield in binary format */ + { efOUT, "-or", nullptr, + ffOPTWRMULT }, /* This is for writing out the entire information in the t_interf arrays */ + { efXPM, "-og", "interface", + ffOPTWRMULT }, /* This is for writing out the interface meshes - one xpm-file per tblock*/ + { efOUT, "-Spect", "intfspect", ffOPTWRMULT }, /* This is for the trajectory averaged Fourier-spectra*/ }; #define NFILE asize(fnm) /* This is the routine responsible for adding default options, * calling the X/motif interface, etc. */ - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -749,16 +794,17 @@ int gmx_densorder(int argc, char *argv[]) snew(index, 1); snew(ngx, 1); -/* Calculate axis */ + /* Calculate axis */ axis = toupper(axtitle[0]) - 'X'; get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, ngx, index, grpname); - density_in_time(ftp2fn(efTRX, NFILE, fnm), index, ngx, binw, binwz, nsttblock, &Densmap, &xslices, &yslices, &zslices, &tblock, top, ePBC, axis, bCenter, b1d, oenv); + density_in_time(ftp2fn(efTRX, NFILE, fnm), index, ngx, binw, binwz, nsttblock, &Densmap, + &xslices, &yslices, &zslices, &tblock, top, ePBC, axis, bCenter, b1d, oenv); if (ftorder > 0) { - filterdensmap(Densmap, xslices, yslices, zslices, tblock, 2*ftorder+1); + filterdensmap(Densmap, xslices, yslices, zslices, tblock, 2 * ftorder + 1); } if (bOut) @@ -766,7 +812,8 @@ int gmx_densorder(int argc, char *argv[]) outputfield(opt2fn("-o", NFILE, fnm), Densmap, xslices, yslices, zslices, tblock); } - interfaces_txy(Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1, &surf2, oenv); + interfaces_txy(Densmap, xslices, yslices, zslices, tblock, binwz, eMeth, dens1, dens2, &surf1, + &surf2, oenv); if (bGraph) { @@ -781,10 +828,7 @@ int gmx_densorder(int argc, char *argv[]) } - - - -/*Output raw-data*/ + /*Output raw-data*/ if (bRawOut) { gmx::ArrayRef rawFiles = opt2fns("-or", NFILE, fnm); @@ -796,14 +840,12 @@ int gmx_densorder(int argc, char *argv[]) } - if (bFourier) { gmx::ArrayRef spectra = opt2fns("-Spect", NFILE, fnm); if (spectra.size() != 2) { - gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %td", - spectra.ssize()); + gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %td", spectra.ssize()); } powerspectavg_intf(surf1, surf2, tblock, xslices, yslices, spectra); } diff --git a/src/gromacs/gmxana/gmx_dielectric.cpp b/src/gromacs/gmxana/gmx_dielectric.cpp index e7d350e7bc..5f5e719c24 100644 --- a/src/gromacs/gmxana/gmx_dielectric.cpp +++ b/src/gromacs/gmxana/gmx_dielectric.cpp @@ -61,7 +61,7 @@ /* Determines at which point in the array the fit should start */ static int calc_nbegin(int nx, real x[], real tbegin) { - int nbegin; + int nbegin; /* Assume input x is sorted */ for (nbegin = 0; (nbegin < nx) && (x[nbegin] <= tbegin); nbegin++) @@ -70,26 +70,24 @@ static int calc_nbegin(int nx, real x[], real tbegin) } if ((nbegin == nx) || (nbegin == 0)) { - gmx_fatal(FARGS, "Begin time %f not in x-domain [%f through %f]\n", - tbegin, x[0], x[nx-1]); + gmx_fatal(FARGS, "Begin time %f not in x-domain [%f through %f]\n", tbegin, x[0], x[nx - 1]); } /* Take the one closest to tbegin */ - if (std::abs(x[nbegin]-tbegin) > std::abs(x[nbegin-1]-tbegin)) + if (std::abs(x[nbegin] - tbegin) > std::abs(x[nbegin - 1] - tbegin)) { nbegin--; } - printf("nbegin = %d, x[nbegin] = %g, tbegin = %g\n", - nbegin, x[nbegin], tbegin); + printf("nbegin = %d, x[nbegin] = %g, tbegin = %g\n", nbegin, x[nbegin], tbegin); return nbegin; } -static real numerical_deriv(int nx, real x[], const real y[], const real fity[], real combined[], real dy[], - real tendInt, int nsmooth) +static real +numerical_deriv(int nx, real x[], const real y[], const real fity[], real combined[], real dy[], real tendInt, int nsmooth) { - FILE *tmpfp; + FILE* tmpfp; int i, nbegin, i0, i1; real fac, fx, fy, integralSmth; @@ -100,17 +98,17 @@ static real numerical_deriv(int nx, real x[], const real y[], const real fity[], { combined[i] = y[i]; } - fac = y[nbegin]/fity[nbegin]; + fac = y[nbegin] / fity[nbegin]; printf("scaling fitted curve by %g\n", fac); for (i = nbegin; (i < nx); i++) { - combined[i] = fity[i]*fac; + combined[i] = fity[i] * fac; } } else { i0 = std::max(0, nbegin); - i1 = std::min(nx-1, nbegin+nsmooth); + i1 = std::min(nx - 1, nbegin + nsmooth); printf("Making smooth transition from %d through %d\n", i0, i1); for (i = 0; (i < i0); i++) { @@ -118,30 +116,30 @@ static real numerical_deriv(int nx, real x[], const real y[], const real fity[], } for (i = i0; (i <= i1); i++) { - fx = static_cast(i1-i)/(i1-i0); - fy = static_cast(i-i0)/(i1-i0); + fx = static_cast(i1 - i) / (i1 - i0); + fy = static_cast(i - i0) / (i1 - i0); if (debug) { fprintf(debug, "x: %g factors for smoothing: %10g %10g\n", x[i], fx, fy); } - combined[i] = fx*y[i] + fy*fity[i]; + combined[i] = fx * y[i] + fy * fity[i]; } - for (i = i1+1; (i < nx); i++) + for (i = i1 + 1; (i < nx); i++) { combined[i] = fity[i]; } } tmpfp = gmx_ffopen("integral_smth.xvg", "w"); - integralSmth = print_and_integrate(tmpfp, nx, x[1]-x[0], combined, nullptr, 1); + integralSmth = print_and_integrate(tmpfp, nx, x[1] - x[0], combined, nullptr, 1); printf("SMOOTH integral = %10.5e\n", integralSmth); - dy[0] = (combined[1]-combined[0])/(x[1]-x[0]); - for (i = 1; (i < nx-1); i++) + dy[0] = (combined[1] - combined[0]) / (x[1] - x[0]); + for (i = 1; (i < nx - 1); i++) { - dy[i] = (combined[i+1]-combined[i-1])/(x[i+1]-x[i-1]); + dy[i] = (combined[i + 1] - combined[i - 1]) / (x[i + 1] - x[i - 1]); } - dy[nx-1] = (combined[nx-1]-combined[nx-2])/(x[nx-1]-x[nx-2]); + dy[nx - 1] = (combined[nx - 1] - combined[nx - 2]) / (x[nx - 1] - x[nx - 2]); for (i = 0; (i < nx); i++) { @@ -151,10 +149,16 @@ static real numerical_deriv(int nx, real x[], const real y[], const real fity[], return integralSmth; } -static void do_four(const char *fn, const char *cn, int nx, const real x[], const real dy[], - real eps0, real epsRF, const gmx_output_env_t *oenv) +static void do_four(const char* fn, + const char* cn, + int nx, + const real x[], + const real dy[], + real eps0, + real epsRF, + const gmx_output_env_t* oenv) { - FILE *fp, *cp; + FILE * fp, *cp; t_complex *tmp, gw, hw, kw; int i, nnx, nxsav; real fac, nu, dt, maxeps, numax; @@ -170,36 +174,34 @@ static void do_four(const char *fn, const char *cn, int nx, const real x[], cons } nnx = 1; - while (nnx < 2*nx) + while (nnx < 2 * nx) { nnx *= 2; } - snew(tmp, 2*nnx); + snew(tmp, 2 * nnx); printf("Doing FFT of %d points\n", nnx); for (i = 0; (i < nx); i++) { tmp[i].re = dy[i]; } - if ((fftcode = gmx_fft_init_1d_real(&fft, nnx, - GMX_FFT_FLAG_NONE)) != 0) + if ((fftcode = gmx_fft_init_1d_real(&fft, nnx, GMX_FFT_FLAG_NONE)) != 0) { gmx_fatal(FARGS, "gmx_fft_init_1d_real returned %d", fftcode); } - if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_COMPLEX_TO_REAL, - tmp, tmp)) != 0) + if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_COMPLEX_TO_REAL, tmp, tmp)) != 0) { gmx_fatal(FARGS, "gmx_fft_1d_real returned %d", fftcode); } gmx_fft_destroy(fft); - dt = x[1]-x[0]; + dt = x[1] - x[0]; if (epsRF == 0) { - fac = (eps0-1)/tmp[0].re; + fac = (eps0 - 1) / tmp[0].re; } else { - fac = ((eps0-1)/(2*epsRF+eps0))/tmp[0].re; + fac = ((eps0 - 1) / (2 * epsRF + eps0)) / tmp[0].re; } fp = xvgropen(fn, "Epsilon(\\8w\\4)", "Freq. (GHz)", "eps", oenv); cp = xvgropen(cn, "Cole-Cole plot", "Eps'", "Eps''", oenv); @@ -209,21 +211,21 @@ static void do_four(const char *fn, const char *cn, int nx, const real x[], cons { if (epsRF == 0) { - kw.re = 1+fac*tmp[i].re; - kw.im = 1+fac*tmp[i].im; + kw.re = 1 + fac * tmp[i].re; + kw.im = 1 + fac * tmp[i].im; } else { - gw = rcmul(fac, tmp[i]); - hw = rcmul(2*epsRF, gw); + gw = rcmul(fac, tmp[i]); + hw = rcmul(2 * epsRF, gw); hw.re += 1.0; - gw.re = 1.0 - gw.re; - gw.im = -gw.im; - kw = cdiv(hw, gw); + gw.re = 1.0 - gw.re; + gw.im = -gw.im; + kw = cdiv(hw, gw); } kw.im *= -1; - nu = (i+1)*1000.0/(nnx*dt); + nu = (i + 1) * 1000.0 / (nnx * dt); if (kw.im > maxeps) { maxeps = kw.im; @@ -233,16 +235,16 @@ static void do_four(const char *fn, const char *cn, int nx, const real x[], cons fprintf(fp, "%10.5e %10.5e %10.5e\n", nu, kw.re, kw.im); fprintf(cp, "%10.5e %10.5e\n", kw.re, kw.im); } - printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n", - maxeps, numax, 1000/(2*M_PI*numax)); + printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n", maxeps, numax, + 1000 / (2 * M_PI * numax)); xvgrclose(fp); xvgrclose(cp); sfree(tmp); } -int gmx_dielectric(int argc, char *argv[]) +int gmx_dielectric(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates frequency dependent dielectric constants", "from the autocorrelation function of the total dipole moment in", "your simulation. This ACF can be generated by [gmx-dipoles].", @@ -250,7 +252,8 @@ int gmx_dielectric(int argc, char *argv[]) "", " * One parameter: y = [EXP]-a[SUB]1[sub] x[exp],", " * Two parameters: y = a[SUB]2[sub] [EXP]-a[SUB]1[sub] x[exp],", - " * Three parameters: y = a[SUB]2[sub] [EXP]-a[SUB]1[sub] x[exp] + (1 - a[SUB]2[sub]) [EXP]-a[SUB]3[sub] x[exp].", + " * Three parameters: y = a[SUB]2[sub] [EXP]-a[SUB]1[sub] x[exp] + (1 - ", + " a[SUB]2[sub]) [EXP]-a[SUB]3[sub] x[exp].", "", "Start values for the fit procedure can be given on the command line.", "It is also possible to fix parameters at their start value, use [TT]-fix[tt]", @@ -266,55 +269,57 @@ int gmx_dielectric(int argc, char *argv[]) "For a pure exponential relaxation (Debye relaxation) the latter", "plot should be one half of a circle." }; - t_filenm fnm[] = { - { efXVG, "-f", "dipcorr", ffREAD }, - { efXVG, "-d", "deriv", ffWRITE }, - { efXVG, "-o", "epsw", ffWRITE }, - { efXVG, "-c", "cole", ffWRITE } - }; + t_filenm fnm[] = { { efXVG, "-f", "dipcorr", ffREAD }, + { efXVG, "-d", "deriv", ffWRITE }, + { efXVG, "-o", "epsw", ffWRITE }, + { efXVG, "-c", "cole", ffWRITE } }; #define NFILE asize(fnm) - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; int i, j, nx, ny, nxtail, eFitFn, nfitparm; real dt, integral, fitintegral, fac, rffac; - double *fitparms; - double **yd; - real **y; - const char *legend[] = { "Correlation", "Std. Dev.", "Fit", "Combined", "Derivative" }; - static int fix = 0, bX = 1, nsmooth = 3; - static real tendInt = 5.0, tbegin = 5.0, tend = 500.0; - static real A = 0.5, tau1 = 10.0, tau2 = 1.0, eps0 = 80, epsRF = 78.5, tail = 500.0; + double* fitparms; + double** yd; + real** y; + const char* legend[] = { "Correlation", "Std. Dev.", "Fit", "Combined", "Derivative" }; + static int fix = 0, bX = 1, nsmooth = 3; + static real tendInt = 5.0, tbegin = 5.0, tend = 500.0; + static real A = 0.5, tau1 = 10.0, tau2 = 1.0, eps0 = 80, epsRF = 78.5, tail = 500.0; real lambda; t_pargs pa[] = { - { "-x1", FALSE, etBOOL, {&bX}, + { "-x1", + FALSE, + etBOOL, + { &bX }, "use first column as [IT]x[it]-axis rather than first data set" }, - { "-eint", FALSE, etREAL, {&tendInt}, - "Time to end the integration of the data and start to use the fit"}, - { "-bfit", FALSE, etREAL, {&tbegin}, - "Begin time of fit" }, - { "-efit", FALSE, etREAL, {&tend}, - "End time of fit" }, - { "-tail", FALSE, etREAL, {&tail}, - "Length of function including data and tail from fit" }, - { "-A", FALSE, etREAL, {&A}, - "Start value for fit parameter A" }, - { "-tau1", FALSE, etREAL, {&tau1}, - "Start value for fit parameter [GRK]tau[grk]1" }, - { "-tau2", FALSE, etREAL, {&tau2}, - "Start value for fit parameter [GRK]tau[grk]2" }, - { "-eps0", FALSE, etREAL, {&eps0}, - "[GRK]epsilon[grk]0 of your liquid" }, - { "-epsRF", FALSE, etREAL, {&epsRF}, - "[GRK]epsilon[grk] of the reaction field used in your simulation. A value of 0 means infinity." }, - { "-fix", FALSE, etINT, {&fix}, + { "-eint", + FALSE, + etREAL, + { &tendInt }, + "Time to end the integration of the data and start to use the fit" }, + { "-bfit", FALSE, etREAL, { &tbegin }, "Begin time of fit" }, + { "-efit", FALSE, etREAL, { &tend }, "End time of fit" }, + { "-tail", FALSE, etREAL, { &tail }, "Length of function including data and tail from fit" }, + { "-A", FALSE, etREAL, { &A }, "Start value for fit parameter A" }, + { "-tau1", FALSE, etREAL, { &tau1 }, "Start value for fit parameter [GRK]tau[grk]1" }, + { "-tau2", FALSE, etREAL, { &tau2 }, "Start value for fit parameter [GRK]tau[grk]2" }, + { "-eps0", FALSE, etREAL, { &eps0 }, "[GRK]epsilon[grk]0 of your liquid" }, + { "-epsRF", + FALSE, + etREAL, + { &epsRF }, + "[GRK]epsilon[grk] of the reaction field used in your simulation. A value of 0 means " + "infinity." }, + { "-fix", + FALSE, + etINT, + { &fix }, "Fix parameters at their start values, A (2), tau1 (1), or tau2 (4)" }, - { "-ffn", FALSE, etENUM, {s_ffn}, - "Fit function" }, - { "-nsmooth", FALSE, etINT, {&nsmooth}, - "Number of points for smoothing" } + { "-ffn", FALSE, etENUM, { s_ffn }, "Fit function" }, + { "-nsmooth", FALSE, etINT, { &nsmooth }, "Number of points for smoothing" } }; - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -326,11 +331,10 @@ int gmx_dielectric(int argc, char *argv[]) nx = read_xvg(opt2fn("-f", NFILE, fnm), &yd, &ny); dt = yd[0][1] - yd[0][0]; - nxtail = std::min(static_cast(tail/dt), nx); + nxtail = std::min(static_cast(tail / dt), nx); printf("Read data set containing %d colums and %d rows\n", ny, nx); - printf("Assuming (from data) that timestep is %g, nxtail = %d\n", - dt, nxtail); + printf("Assuming (from data) that timestep is %g, nxtail = %d\n", dt, nxtail); snew(y, 6); for (i = 0; (i < ny); i++) { @@ -348,7 +352,7 @@ int gmx_dielectric(int argc, char *argv[]) { for (i = nx; (i < nxtail); i++) { - y[0][i] = dt*i+y[0][0]; + y[0][i] = dt * i + y[0][0]; for (j = 1; (j < ny); j++) { y[j][i] = 0.0; @@ -364,7 +368,7 @@ int gmx_dielectric(int argc, char *argv[]) printf("Creating standard deviation numbers ...\n"); snew(y[2], nx); - fac = 1.0/nx; + fac = 1.0 / nx; for (i = 0; (i < nx); i++) { y[2][i] = fac; @@ -389,10 +393,8 @@ int gmx_dielectric(int argc, char *argv[]) snew(y[4], nx); snew(y[5], nx); - integral = print_and_integrate(nullptr, calc_nbegin(nx, y[0], tbegin), - dt, y[1], nullptr, 1); - integral += do_lmfit(nx, y[1], y[2], dt, y[0], tbegin, tend, - oenv, TRUE, eFitFn, fitparms, fix, nullptr); + integral = print_and_integrate(nullptr, calc_nbegin(nx, y[0], tbegin), dt, y[1], nullptr, 1); + integral += do_lmfit(nx, y[1], y[2], dt, y[0], tbegin, tend, oenv, TRUE, eFitFn, fitparms, fix, nullptr); for (i = 0; i < nx; i++) { y[3][i] = fit_function(eFitFn, fitparms, y[0][i]); @@ -406,27 +408,24 @@ int gmx_dielectric(int argc, char *argv[]) } else { - lambda = (eps0 - 1.0)/(2*epsRF - 1.0); - rffac = (2*epsRF+eps0)/(2*epsRF+1); + lambda = (eps0 - 1.0) / (2 * epsRF - 1.0); + rffac = (2 * epsRF + eps0) / (2 * epsRF + 1); } printf("DATA INTEGRAL: %5.1f, tauD(old) = %5.1f ps, " "tau_slope = %5.1f, tau_slope,D = %5.1f ps\n", - integral, integral*rffac, fitparms[0], fitparms[0]*rffac); + integral, integral * rffac, fitparms[0], fitparms[0] * rffac); - printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n", - fitparms[0]*(1 + fitparms[1]*lambda), - 1 + ((1 - fitparms[1])*(eps0 - 1))/(1 + fitparms[1]*lambda)); + printf("tau_D from tau1 = %8.3g , eps(Infty) = %8.3f\n", fitparms[0] * (1 + fitparms[1] * lambda), + 1 + ((1 - fitparms[1]) * (eps0 - 1)) / (1 + fitparms[1] * lambda)); fitintegral = numerical_deriv(nx, y[0], y[1], y[3], y[4], y[5], tendInt, nsmooth); - printf("FIT INTEGRAL (tau_M): %5.1f, tau_D = %5.1f\n", - fitintegral, fitintegral*rffac); + printf("FIT INTEGRAL (tau_M): %5.1f, tau_D = %5.1f\n", fitintegral, fitintegral * rffac); /* Now we have the negative gradient of */ - write_xvg(opt2fn("-d", NFILE, fnm), "Data", nx-1, 6, y, legend, oenv); + write_xvg(opt2fn("-d", NFILE, fnm), "Data", nx - 1, 6, y, legend, oenv); /* Do FFT and analysis */ - do_four(opt2fn("-o", NFILE, fnm), opt2fn("-c", NFILE, fnm), - nx-1, y[0], y[5], eps0, epsRF, oenv); + do_four(opt2fn("-o", NFILE, fnm), opt2fn("-c", NFILE, fnm), nx - 1, y[0], y[5], eps0, epsRF, oenv); do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); do_view(oenv, opt2fn("-c", NFILE, fnm), nullptr); diff --git a/src/gromacs/gmxana/gmx_dipoles.cpp b/src/gromacs/gmxana/gmx_dipoles.cpp index 6601111115..d7ca1c3c13 100644 --- a/src/gromacs/gmxana/gmx_dipoles.cpp +++ b/src/gromacs/gmxana/gmx_dipoles.cpp @@ -74,46 +74,47 @@ #include "gromacs/utility/smalloc.h" #define e2d(x) ENM2DEBYE*(x) -#define EANG2CM (E_CHARGE*1.0e-10) /* e Angstrom to Coulomb meter */ -#define CM2D (SPEED_OF_LIGHT*1.0e+24) /* Coulomb meter to Debye */ +#define EANG2CM (E_CHARGE * 1.0e-10) /* e Angstrom to Coulomb meter */ +#define CM2D (SPEED_OF_LIGHT * 1.0e+24) /* Coulomb meter to Debye */ -typedef struct { +typedef struct +{ int nelem; real spacing, radius; - real *elem; - int *count; + real* elem; + int* count; gmx_bool bPhi; int nx, ny; - real **cmap; + real** cmap; } t_gkrbin; -static t_gkrbin *mk_gkrbin(real radius, real rcmax, gmx_bool bPhi, int ndegrees) +static t_gkrbin* mk_gkrbin(real radius, real rcmax, gmx_bool bPhi, int ndegrees) { - t_gkrbin *gb; - char *ptr; + t_gkrbin* gb; + char* ptr; int i; snew(gb, 1); if ((ptr = getenv("GMX_DIPOLE_SPACING")) != nullptr) { - double bw = strtod(ptr, nullptr); + double bw = strtod(ptr, nullptr); gb->spacing = bw; } else { gb->spacing = 0.01; /* nm */ } - gb->nelem = 1 + static_cast(radius/gb->spacing); + gb->nelem = 1 + static_cast(radius / gb->spacing); if (rcmax == 0) { gb->nx = gb->nelem; } else { - gb->nx = 1 + static_cast(rcmax/gb->spacing); + gb->nx = 1 + static_cast(rcmax / gb->spacing); } - gb->radius = radius; + gb->radius = radius; snew(gb->elem, gb->nelem); snew(gb->count, gb->nelem); @@ -128,7 +129,7 @@ static t_gkrbin *mk_gkrbin(real radius, real rcmax, gmx_bool bPhi, int ndegrees) return gb; } -static void done_gkrbin(t_gkrbin **gb) +static void done_gkrbin(t_gkrbin** gb) { sfree((*gb)->elem); sfree((*gb)->count); @@ -136,14 +137,14 @@ static void done_gkrbin(t_gkrbin **gb) *gb = nullptr; } -static void add2gkr(t_gkrbin *gb, real r, real cosa, real phi) +static void add2gkr(t_gkrbin* gb, real r, real cosa, real phi) { - int cy, index = gmx::roundToInt(r/gb->spacing); + int cy, index = gmx::roundToInt(r / gb->spacing); real alpha; if (index < gb->nelem) { - gb->elem[index] += cosa; + gb->elem[index] += cosa; gb->count[index]++; } if (index < gb->nx) @@ -151,13 +152,13 @@ static void add2gkr(t_gkrbin *gb, real r, real cosa, real phi) alpha = std::acos(cosa); if (gb->bPhi) { - cy = static_cast((M_PI+phi)*gb->ny/(2*M_PI)); + cy = static_cast((M_PI + phi) * gb->ny / (2 * M_PI)); } else { - cy = static_cast((alpha*gb->ny)/M_PI); /*((1+cosa)*0.5*(gb->ny));*/ + cy = static_cast((alpha * gb->ny) / M_PI); /*((1+cosa)*0.5*(gb->ny));*/ } - cy = std::min(gb->ny-1, std::max(0, cy)); + cy = std::min(gb->ny - 1, std::max(0, cy)); if (debug) { fprintf(debug, "CY: %10f %5d\n", alpha, cy); @@ -169,18 +170,27 @@ static void add2gkr(t_gkrbin *gb, real r, real cosa, real phi) static void rvec2sprvec(rvec dipcart, rvec dipsp) { clear_rvec(dipsp); - dipsp[0] = std::sqrt(dipcart[XX]*dipcart[XX]+dipcart[YY]*dipcart[YY]+dipcart[ZZ]*dipcart[ZZ]); /* R */ - dipsp[1] = std::atan2(dipcart[YY], dipcart[XX]); /* Theta */ - dipsp[2] = std::atan2(std::sqrt(dipcart[XX]*dipcart[XX]+dipcart[YY]*dipcart[YY]), dipcart[ZZ]); /* Phi */ + dipsp[0] = std::sqrt(dipcart[XX] * dipcart[XX] + dipcart[YY] * dipcart[YY] + + dipcart[ZZ] * dipcart[ZZ]); /* R */ + dipsp[1] = std::atan2(dipcart[YY], dipcart[XX]); /* Theta */ + dipsp[2] = std::atan2(std::sqrt(dipcart[XX] * dipcart[XX] + dipcart[YY] * dipcart[YY]), + dipcart[ZZ]); /* Phi */ } - -static void do_gkr(t_gkrbin *gb, int ncos, int *ngrp, int *molindex[], - const int mindex[], rvec x[], rvec mu[], - int ePBC, const matrix box, const t_atom *atom, const int *nAtom) +static void do_gkr(t_gkrbin* gb, + int ncos, + int* ngrp, + int* molindex[], + const int mindex[], + rvec x[], + rvec mu[], + int ePBC, + const matrix box, + const t_atom* atom, + const int* nAtom) { - static rvec *xcm[2] = { nullptr, nullptr}; + static rvec* xcm[2] = { nullptr, nullptr }; int gi, gj, j0, j1, i, j, k, n, grp0, grp1; real qtot, q, cosa, rr, phi; rvec dx; @@ -200,36 +210,36 @@ static void do_gkr(t_gkrbin *gb, int ncos, int *ngrp, int *molindex[], if (nAtom[n] > 0) { - copy_rvec(x[j0+nAtom[n]-1], xcm[n][i]); + copy_rvec(x[j0 + nAtom[n] - 1], xcm[n][i]); } else { - j1 = mindex[gi+1]; + j1 = mindex[gi + 1]; clear_rvec(xcm[n][i]); qtot = 0; for (j = j0; j < j1; j++) { - q = std::abs(atom[j].q); + q = std::abs(atom[j].q); qtot += q; for (k = 0; k < DIM; k++) { - xcm[n][i][k] += q*x[j][k]; + xcm[n][i][k] += q * x[j][k]; } } - svmul(1/qtot, xcm[n][i], xcm[n][i]); + svmul(1 / qtot, xcm[n][i], xcm[n][i]); } } } set_pbc(&pbc, ePBC, box); grp0 = 0; - grp1 = ncos-1; + grp1 = ncos - 1; for (i = 0; i < ngrp[grp0]; i++) { gi = molindex[grp0][i]; - j0 = (ncos == 2) ? 0 : i+1; + j0 = (ncos == 2) ? 0 : i + 1; for (j = j0; j < ngrp[grp1]; j++) { - gj = molindex[grp1][j]; + gj = molindex[grp1][j]; if ((iprod(mu[gi], mu[gi]) > 0) && (iprod(mu[gj], mu[gj]) > 0)) { /* Compute distance between molecules including PBC */ @@ -246,8 +256,7 @@ static void do_gkr(t_gkrbin *gb, int ncos, int *ngrp, int *molindex[], copy_rvec(xcm[grp1][j], xk); rvec_add(xj, mu[gi], xi); rvec_add(xk, mu[gj], xl); - phi = dih_angle(xi, xj, xk, xl, &pbc, - r_ij, r_kj, r_kl, mm, nn, /* out */ + phi = dih_angle(xi, xj, xk, xl, &pbc, r_ij, r_kj, r_kl, mm, nn, /* out */ &t1, &t2, &t3); cosa = std::cos(phi); } @@ -259,10 +268,10 @@ static void do_gkr(t_gkrbin *gb, int ncos, int *ngrp, int *molindex[], if (debug || std::isnan(cosa)) { fprintf(debug ? debug : stderr, - "mu[%d] = %5.2f %5.2f %5.2f |mi| = %5.2f, mu[%d] = %5.2f %5.2f %5.2f |mj| = %5.2f rr = %5.2f cosa = %5.2f\n", - gi, mu[gi][XX], mu[gi][YY], mu[gi][ZZ], norm(mu[gi]), - gj, mu[gj][XX], mu[gj][YY], mu[gj][ZZ], norm(mu[gj]), - rr, cosa); + "mu[%d] = %5.2f %5.2f %5.2f |mi| = %5.2f, mu[%d] = %5.2f %5.2f %5.2f " + "|mj| = %5.2f rr = %5.2f cosa = %5.2f\n", + gi, mu[gi][XX], mu[gi][YY], mu[gi][ZZ], norm(mu[gi]), gj, mu[gj][XX], + mu[gj][YY], mu[gj][ZZ], norm(mu[gj]), rr, cosa); } add2gkr(gb, rr, cosa, phi); @@ -271,7 +280,7 @@ static void do_gkr(t_gkrbin *gb, int ncos, int *ngrp, int *molindex[], } } -static real normalize_cmap(t_gkrbin *gb) +static real normalize_cmap(t_gkrbin* gb) { int i, j; real hi; @@ -280,11 +289,11 @@ static real normalize_cmap(t_gkrbin *gb) hi = 0; for (i = 0; (i < gb->nx); i++) { - vol = 4*M_PI*gmx::square(gb->spacing*i)*gb->spacing; + vol = 4 * M_PI * gmx::square(gb->spacing * i) * gb->spacing; for (j = 0; (j < gb->ny); j++) { gb->cmap[i][j] /= vol; - hi = std::max(hi, gb->cmap[i][j]); + hi = std::max(hi, gb->cmap[i][j]); } } if (hi <= 0) @@ -294,49 +303,44 @@ static real normalize_cmap(t_gkrbin *gb) return hi; } -static void print_cmap(const char *cmap, t_gkrbin *gb, int *nlevels) +static void print_cmap(const char* cmap, t_gkrbin* gb, int* nlevels) { - FILE *out; - int i, j; - real hi; + FILE* out; + int i, j; + real hi; - real *xaxis, *yaxis; - t_rgb rlo = { 1, 1, 1 }; - t_rgb rhi = { 0, 0, 0 }; + real *xaxis, *yaxis; + t_rgb rlo = { 1, 1, 1 }; + t_rgb rhi = { 0, 0, 0 }; hi = normalize_cmap(gb); - snew(xaxis, gb->nx+1); - for (i = 0; (i < gb->nx+1); i++) + snew(xaxis, gb->nx + 1); + for (i = 0; (i < gb->nx + 1); i++) { - xaxis[i] = i*gb->spacing; + xaxis[i] = i * gb->spacing; } snew(yaxis, gb->ny); for (j = 0; (j < gb->ny); j++) { if (gb->bPhi) { - yaxis[j] = (360.0*j)/(gb->ny-1.0)-180; + yaxis[j] = (360.0 * j) / (gb->ny - 1.0) - 180; } else { - yaxis[j] = (180.0*j)/(gb->ny-1.0); + yaxis[j] = (180.0 * j) / (gb->ny - 1.0); } /*2.0*j/(gb->ny-1.0)-1.0;*/ } out = gmx_ffopen(cmap, "w"); - write_xpm(out, 0, - "Dipole Orientation Distribution", "Fraction", "r (nm)", - gb->bPhi ? "Phi" : "Alpha", - gb->nx, gb->ny, xaxis, yaxis, - gb->cmap, 0, hi, rlo, rhi, nlevels); + write_xpm(out, 0, "Dipole Orientation Distribution", "Fraction", "r (nm)", gb->bPhi ? "Phi" : "Alpha", + gb->nx, gb->ny, xaxis, yaxis, gb->cmap, 0, hi, rlo, rhi, nlevels); gmx_ffclose(out); sfree(xaxis); sfree(yaxis); } -static void print_gkrbin(const char *fn, t_gkrbin *gb, - int ngrp, int nframes, real volume, - const gmx_output_env_t *oenv) +static void print_gkrbin(const char* fn, t_gkrbin* gb, int ngrp, int nframes, real volume, const gmx_output_env_t* oenv) { /* We compute Gk(r), gOO and hOO according to * Nymand & Linse, JCP 112 (2000) pp 6386-6395. @@ -344,8 +348,8 @@ static void print_gkrbin(const char *fn, t_gkrbin *gb, * rather than their inner product. This allows to take polarizible * models into account. The RDF is calculated as well, almost for free! */ - FILE *fp; - const char *leg[] = { "G\\sk\\N(r)", "< cos >", "h\\sOO\\N", "g\\sOO\\N", "Energy" }; + FILE* fp; + const char* leg[] = { "G\\sk\\N(r)", "< cos >", "h\\sOO\\N", "g\\sOO\\N", "Energy" }; int i, last; real x0, x1, ggg, Gkr, vol_s, rho, gOO, hOO, cosav, ener; double fac; @@ -353,8 +357,8 @@ static void print_gkrbin(const char *fn, t_gkrbin *gb, fp = xvgropen(fn, "Distance dependent Gk", "r (nm)", "G\\sk\\N(r)", oenv); xvgr_legend(fp, asize(leg), leg, oenv); - Gkr = 1; /* Self-dipole inproduct = 1 */ - rho = ngrp/volume; + Gkr = 1; /* Self-dipole inproduct = 1 */ + rho = ngrp / volume; if (debug) { @@ -362,8 +366,8 @@ static void print_gkrbin(const char *fn, t_gkrbin *gb, fprintf(debug, "ngrp = %d, nframes = %d\n", ngrp, nframes); } - last = gb->nelem-1; - while (last > 1 && gb->elem[last-1] == 0) + last = gb->nelem - 1; + while (last > 1 && gb->elem[last - 1] == 0) { last--; } @@ -372,38 +376,37 @@ static void print_gkrbin(const char *fn, t_gkrbin *gb, * Multiply by 2 because we only take half the matrix of interactions * into account. */ - fac = 2.0/(ngrp * nframes); + fac = 2.0 / (ngrp * nframes); x0 = 0; for (i = 0; i < last; i++) { /* Centre of the coordinate in the spherical layer */ - x1 = x0+gb->spacing; + x1 = x0 + gb->spacing; /* Volume of the layer */ - vol_s = (4.0/3.0)*M_PI*(x1*x1*x1-x0*x0*x0); + vol_s = (4.0 / 3.0) * M_PI * (x1 * x1 * x1 - x0 * x0 * x0); /* gOO */ - gOO = gb->count[i]*fac/(rho*vol_s); + gOO = gb->count[i] * fac / (rho * vol_s); /* Dipole correlation hOO, normalized by the relative number density, like * in a Radial distribution function. */ - ggg = gb->elem[i]*fac; - hOO = 3.0*ggg/(rho*vol_s); + ggg = gb->elem[i] * fac; + hOO = 3.0 * ggg / (rho * vol_s); Gkr += ggg; if (gb->count[i]) { - cosav = gb->elem[i]/gb->count[i]; + cosav = gb->elem[i] / gb->count[i]; } else { cosav = 0; } - ener = -0.5*cosav*ONE_4PI_EPS0/(x1*x1*x1); + ener = -0.5 * cosav * ONE_4PI_EPS0 / (x1 * x1 * x1); - fprintf(fp, "%10.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n", - x1, Gkr, cosav, hOO, gOO, ener); + fprintf(fp, "%10.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n", x1, Gkr, cosav, hOO, gOO, ener); /* Swap x0 and x1 */ x0 = x1; @@ -411,23 +414,25 @@ static void print_gkrbin(const char *fn, t_gkrbin *gb, xvgrclose(fp); } -static gmx_bool read_mu_from_enx(ener_file_t fmu, int Vol, const ivec iMu, rvec mu, real *vol, - real *t, int nre, t_enxframe *fr) +static gmx_bool +read_mu_from_enx(ener_file_t fmu, int Vol, const ivec iMu, rvec mu, real* vol, real* t, int nre, t_enxframe* fr) { - int i; - gmx_bool bCont; - char buf[22]; + int i; + gmx_bool bCont; + char buf[22]; bCont = do_enx(fmu, fr); if (fr->nre != nre) { - fprintf(stderr, "Something strange: expected %d entries in energy file at step %s\n(time %g) but found %d entries\n", + fprintf(stderr, + "Something strange: expected %d entries in energy file at step %s\n(time %g) but " + "found %d entries\n", nre, gmx_step_str(fr->step, buf), fr->t, fr->nre); } if (bCont) { - if (Vol != -1) /* we've got Volume in the energy file */ + if (Vol != -1) /* we've got Volume in the energy file */ { *vol = fr->ener[Vol].e; } @@ -441,7 +446,7 @@ static gmx_bool read_mu_from_enx(ener_file_t fmu, int Vol, const ivec iMu, rvec return bCont; } -static void neutralize_mols(int n, const int *index, const t_block *mols, t_atom *atom) +static void neutralize_mols(int n, const int* index, const t_block* mols, t_atom* atom) { double mtot, qtot; int ncharged, m, a0, a1, a; @@ -450,7 +455,7 @@ static void neutralize_mols(int n, const int *index, const t_block *mols, t_atom for (m = 0; m < n; m++) { a0 = mols->index[index[m]]; - a1 = mols->index[index[m]+1]; + a1 = mols->index[index[m] + 1]; mtot = 0; qtot = 0; for (a = a0; a < a1; a++) @@ -468,7 +473,7 @@ static void neutralize_mols(int n, const int *index, const t_block *mols, t_atom /* Remove the net charge at the center of mass */ for (a = a0; a < a1; a++) { - atom[a].q -= qtot*atom[a].m/mtot; + atom[a].q -= qtot * atom[a].m / mtot; } } } @@ -476,7 +481,8 @@ static void neutralize_mols(int n, const int *index, const t_block *mols, t_atom if (ncharged) { printf("There are %d charged molecules in the selection,\n" - "will subtract their charge at their center of mass\n", ncharged); + "will subtract their charge at their center of mass\n", + ncharged); } } @@ -488,10 +494,10 @@ static void mol_dip(int k0, int k1, rvec x[], const t_atom atom[], rvec mu) clear_rvec(mu); for (k = k0; (k < k1); k++) { - q = e2d(atom[k].q); + q = e2d(atom[k].q); for (m = 0; (m < DIM); m++) { - mu[m] += q*x[k][m]; + mu[m] += q * x[k][m]; } } } @@ -500,9 +506,9 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) { int i, k, m, n, niter; real q, r2, mass, masstot; - rvec com; /* center of mass */ - rvec r; /* distance of atoms to center of mass */ - double **inten; + rvec com; /* center of mass */ + rvec r; /* distance of atoms to center of mass */ + double** inten; double dd[DIM], **ev; snew(inten, DIM); @@ -519,21 +525,21 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) masstot = 0.0; for (k = k0; (k < k1); k++) { - mass = atom[k].m; + mass = atom[k].m; masstot += mass; for (i = 0; (i < DIM); i++) { - com[i] += mass*x[k][i]; + com[i] += mass * x[k][i]; } } - svmul((1.0/masstot), com, com); + svmul((1.0 / masstot), com, com); /* We want traceless quadrupole moments, so let us calculate the complete * quadrupole moment tensor and diagonalize this tensor to get * the individual components on the diagonal. */ -#define delta(a, b) (( (a) == (b) ) ? 1.0 : 0.0) +#define delta(a, b) (((a) == (b)) ? 1.0 : 0.0) for (m = 0; (m < DIM); m++) { @@ -542,16 +548,16 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) inten[m][n] = 0; } } - for (k = k0; (k < k1); k++) /* loop over atoms in a molecule */ + for (k = k0; (k < k1); k++) /* loop over atoms in a molecule */ { - q = (atom[k].q)*100.0; + q = (atom[k].q) * 100.0; rvec_sub(x[k], com, r); r2 = iprod(r, r); for (m = 0; (m < DIM); m++) { for (n = 0; (n < DIM); n++) { - inten[m][n] += 0.5*q*(3.0*r[m]*r[n] - r2*delta(m, n))*EANG2CM*CM2D; + inten[m][n] += 0.5 * q * (3.0 * r[m] * r[n] - r2 * delta(m, n)) * EANG2CM * CM2D; } } } @@ -559,8 +565,7 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) { for (i = 0; (i < DIM); i++) { - fprintf(debug, "Q[%d] = %8.3f %8.3f %8.3f\n", - i, inten[i][XX], inten[i][YY], inten[i][ZZ]); + fprintf(debug, "Q[%d] = %8.3f %8.3f %8.3f\n", i, inten[i][XX], inten[i][YY], inten[i][ZZ]); } } @@ -571,13 +576,11 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) { for (i = 0; (i < DIM); i++) { - fprintf(debug, "ev[%d] = %8.3f %8.3f %8.3f\n", - i, ev[i][XX], ev[i][YY], ev[i][ZZ]); + fprintf(debug, "ev[%d] = %8.3f %8.3f %8.3f\n", i, ev[i][XX], ev[i][YY], ev[i][ZZ]); } for (i = 0; (i < DIM); i++) { - fprintf(debug, "Q'[%d] = %8.3f %8.3f %8.3f\n", - i, inten[i][XX], inten[i][YY], inten[i][ZZ]); + fprintf(debug, "Q'[%d] = %8.3f %8.3f %8.3f\n", i, inten[i][XX], inten[i][YY], inten[i][ZZ]); } } /* Sort the eigenvalues, for water we know that the order is as follows: @@ -602,9 +605,9 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) for (m = 0; (m < DIM); m++) { - quad[0] = dd[2]; /* yy */ - quad[1] = dd[0]; /* zz */ - quad[2] = dd[1]; /* xx */ + quad[0] = dd[2]; /* yy */ + quad[1] = dd[0]; /* zz */ + quad[2] = dd[1]; /* xx */ } if (debug) @@ -628,10 +631,10 @@ static void mol_quad(int k0, int k1, rvec x[], const t_atom atom[], rvec quad) static real calc_eps(double M_diff, double volume, double epsRF, double temp) { double eps, A, teller, noemer; - double eps_0 = 8.854187817e-12; /* epsilon_0 in C^2 J^-1 m^-1 */ - double fac = 1.112650021e-59; /* converts Debye^2 to C^2 m^2 */ + double eps_0 = 8.854187817e-12; /* epsilon_0 in C^2 J^-1 m^-1 */ + double fac = 1.112650021e-59; /* converts Debye^2 to C^2 m^2 */ - A = M_diff*fac/(3*eps_0*volume*NANO*NANO*NANO*BOLTZMANN*temp); + A = M_diff * fac / (3 * eps_0 * volume * NANO * NANO * NANO * BOLTZMANN * temp); if (epsRF == 0.0) { @@ -640,17 +643,15 @@ static real calc_eps(double M_diff, double volume, double epsRF, double temp) } else { - teller = 1 + (A*2*epsRF/(2*epsRF+1)); - noemer = 1 - (A/(2*epsRF+1)); + teller = 1 + (A * 2 * epsRF / (2 * epsRF + 1)); + noemer = 1 - (A / (2 * epsRF + 1)); } eps = teller / noemer; return eps; } -static void update_slab_dipoles(int k0, int k1, rvec x[], rvec mu, - int idim, int nslice, rvec slab_dipole[], - matrix box) +static void update_slab_dipoles(int k0, int k1, rvec x[], rvec mu, int idim, int nslice, rvec slab_dipole[], matrix box) { int k; real xdim = 0; @@ -659,45 +660,41 @@ static void update_slab_dipoles(int k0, int k1, rvec x[], rvec mu, { xdim += x[k][idim]; } - xdim /= (k1-k0); - k = (static_cast(xdim*nslice/box[idim][idim] + nslice)) % nslice; + xdim /= (k1 - k0); + k = (static_cast(xdim * nslice / box[idim][idim] + nslice)) % nslice; rvec_inc(slab_dipole[k], mu); } -static void dump_slab_dipoles(const char *fn, int idim, int nslice, - rvec slab_dipole[], matrix box, int nframes, - const gmx_output_env_t *oenv) +static void dump_slab_dipoles(const char* fn, + int idim, + int nslice, + rvec slab_dipole[], + matrix box, + int nframes, + const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; char buf[STRLEN]; int i; real mutot; - const char *leg_dim[4] = { - "\\f{12}m\\f{4}\\sX\\N", - "\\f{12}m\\f{4}\\sY\\N", - "\\f{12}m\\f{4}\\sZ\\N", - "\\f{12}m\\f{4}\\stot\\N" - }; + const char* leg_dim[4] = { "\\f{12}m\\f{4}\\sX\\N", "\\f{12}m\\f{4}\\sY\\N", + "\\f{12}m\\f{4}\\sZ\\N", "\\f{12}m\\f{4}\\stot\\N" }; - sprintf(buf, "Box-%c (nm)", 'X'+idim); - fp = xvgropen(fn, "Average dipole moment per slab", buf, "\\f{12}m\\f{4} (D)", - oenv); + sprintf(buf, "Box-%c (nm)", 'X' + idim); + fp = xvgropen(fn, "Average dipole moment per slab", buf, "\\f{12}m\\f{4} (D)", oenv); xvgr_legend(fp, DIM, leg_dim, oenv); for (i = 0; (i < nslice); i++) { - mutot = norm(slab_dipole[i])/nframes; + mutot = norm(slab_dipole[i]) / nframes; fprintf(fp, "%10.3f %10.3f %10.3f %10.3f %10.3f\n", - ((i+0.5)*box[idim][idim])/nslice, - slab_dipole[i][XX]/nframes, - slab_dipole[i][YY]/nframes, - slab_dipole[i][ZZ]/nframes, - mutot); + ((i + 0.5) * box[idim][idim]) / nslice, slab_dipole[i][XX] / nframes, + slab_dipole[i][YY] / nframes, slab_dipole[i][ZZ] / nframes, mutot); } xvgrclose(fp); do_view(oenv, fn, "-autoscale xy -nxy"); } -static void compute_avercos(int n, rvec dip[], real *dd, rvec axis, gmx_bool bPairs) +static void compute_avercos(int n, rvec dip[], real* dd, rvec axis, gmx_bool bPairs) { int i, j, k; double dc, d, ddc1, ddc2, ddc3; @@ -714,86 +711,84 @@ static void compute_avercos(int n, rvec dip[], real *dd, rvec axis, gmx_bool bPa ddc3 += std::abs(cos_angle(dip[i], zzz)); if (bPairs) { - for (j = i+1; (j < n); j++, k++) + for (j = i + 1; (j < n); j++, k++) { - dc = cos_angle(dip[i], dip[j]); - d += std::abs(dc); + dc = cos_angle(dip[i], dip[j]); + d += std::abs(dc); } } } - *dd = d/k; - axis[XX] = ddc1/n; - axis[YY] = ddc2/n; - axis[ZZ] = ddc3/n; + *dd = d / k; + axis[XX] = ddc1 / n; + axis[YY] = ddc2 / n; + axis[ZZ] = ddc3 / n; } -static void do_dip(const t_topology *top, int ePBC, real volume, - const char *fn, - const char *out_mtot, const char *out_eps, - const char *out_aver, const char *dipdist, - const char *cosaver, const char *fndip3d, - const char *fnadip, gmx_bool bPairs, - const char *corrtype, const char *corf, - gmx_bool bGkr, const char *gkrfn, - gmx_bool bPhi, int *nlevels, int ndegrees, - int ncos, - const char *cmap, real rcmax, - gmx_bool bQuad, - gmx_bool bMU, const char *mufn, - int *gnx, int *molindex[], - real mu_max, real mu_aver, - real epsilonRF, real temp, - int *gkatom, int skip, - gmx_bool bSlab, int nslices, - const char *axtitle, const char *slabfn, - const gmx_output_env_t *oenv) +static void do_dip(const t_topology* top, + int ePBC, + real volume, + const char* fn, + const char* out_mtot, + const char* out_eps, + const char* out_aver, + const char* dipdist, + const char* cosaver, + const char* fndip3d, + const char* fnadip, + gmx_bool bPairs, + const char* corrtype, + const char* corf, + gmx_bool bGkr, + const char* gkrfn, + gmx_bool bPhi, + int* nlevels, + int ndegrees, + int ncos, + const char* cmap, + real rcmax, + gmx_bool bQuad, + gmx_bool bMU, + const char* mufn, + int* gnx, + int* molindex[], + real mu_max, + real mu_aver, + real epsilonRF, + real temp, + int* gkatom, + int skip, + gmx_bool bSlab, + int nslices, + const char* axtitle, + const char* slabfn, + const gmx_output_env_t* oenv) { - const char *leg_mtot[] = { - "M\\sx \\N", - "M\\sy \\N", - "M\\sz \\N", - "|M\\stot \\N|" - }; + const char* leg_mtot[] = { "M\\sx \\N", "M\\sy \\N", "M\\sz \\N", "|M\\stot \\N|" }; #define NLEGMTOT asize(leg_mtot) - const char *leg_eps[] = { - "epsilon", - "G\\sk", - "g\\sk" - }; + const char* leg_eps[] = { "epsilon", "G\\sk", "g\\sk" }; #define NLEGEPS asize(leg_eps) - const char *leg_aver[] = { - "< |M|\\S2\\N >", - "< |M| >\\S2\\N", - "< |M|\\S2\\N > - < |M| >\\S2\\N", - "< |M| >\\S2\\N / < |M|\\S2\\N >" - }; + const char* leg_aver[] = { "< |M|\\S2\\N >", "< |M| >\\S2\\N", "< |M|\\S2\\N > - < |M| >\\S2\\N", + "< |M| >\\S2\\N / < |M|\\S2\\N >" }; #define NLEGAVER asize(leg_aver) - const char *leg_cosaver[] = { - "\\f{4}<|cos\\f{12}q\\f{4}\\sij\\N|>", - "RMSD cos", - "\\f{4}<|cos\\f{12}q\\f{4}\\siX\\N|>", - "\\f{4}<|cos\\f{12}q\\f{4}\\siY\\N|>", - "\\f{4}<|cos\\f{12}q\\f{4}\\siZ\\N|>" - }; + const char* leg_cosaver[] = { "\\f{4}<|cos\\f{12}q\\f{4}\\sij\\N|>", "RMSD cos", + "\\f{4}<|cos\\f{12}q\\f{4}\\siX\\N|>", + "\\f{4}<|cos\\f{12}q\\f{4}\\siY\\N|>", + "\\f{4}<|cos\\f{12}q\\f{4}\\siZ\\N|>" }; #define NLEGCOSAVER asize(leg_cosaver) - const char *leg_adip[] = { - "", - "Std. Dev.", - "Error" - }; + const char* leg_adip[] = { "", "Std. Dev.", "Error" }; #define NLEGADIP asize(leg_adip) - FILE *outdd, *outmtot, *outaver, *outeps, *caver = nullptr; - FILE *dip3d = nullptr, *adip = nullptr; - rvec *x, *dipole = nullptr, mu_t, quad, *dipsp = nullptr; - t_gkrbin *gkrbin = nullptr; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; + FILE * outdd, *outmtot, *outaver, *outeps, *caver = nullptr; + FILE * dip3d = nullptr, *adip = nullptr; + rvec * x, *dipole = nullptr, mu_t, quad, *dipsp = nullptr; + t_gkrbin* gkrbin = nullptr; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; int nframes = 1000, nre, timecheck = 0, ncolour = 0; - ener_file_t fmu = nullptr; + ener_file_t fmu = nullptr; int i, n, m, natom = 0, gnx_tot, teller, tel3; - t_trxstatus *status; - int *dipole_bin, ndipbin, ibin, iVol, idim = -1; + t_trxstatus* status; + int * dipole_bin, ndipbin, ibin, iVol, idim = -1; unsigned long mode; real rcut = 0, t, t0, t1, dt, dd, rms_cos; rvec dipaxis; @@ -802,12 +797,12 @@ static void do_dip(const t_topology *top, int ePBC, real volume, double M_diff = 0, epsilon, invtel, vol_aver; double mu_ave, mu_mol, M2_ave = 0, M_ave2 = 0, M_av[DIM], M_av2[DIM]; double M[3], M2[3], M4[3], Gk = 0, g_k = 0; - gmx_stats_t *Qlsq, mulsq, muframelsq = nullptr; + gmx_stats_t * Qlsq, mulsq, muframelsq = nullptr; ivec iMu; - real **muall = nullptr; - rvec *slab_dipoles = nullptr; - const t_atom *atom = nullptr; - const t_block *mols = nullptr; + real** muall = nullptr; + rvec* slab_dipoles = nullptr; + const t_atom* atom = nullptr; + const t_block* mols = nullptr; gmx_rmpbc_t gpbc = nullptr; gnx_tot = gnx[0]; @@ -871,14 +866,14 @@ static void do_dip(const t_topology *top, int ePBC, real volume, if (bTotal) { snew(muall, 1); - snew(muall[0], nframes*DIM); + snew(muall[0], nframes * DIM); } else { snew(muall, gnx[0]); for (i = 0; (i < gnx[0]); i++) { - snew(muall[i], nframes*DIM); + snew(muall[i], nframes * DIM); } } } @@ -900,13 +895,10 @@ static void do_dip(const t_topology *top, int ePBC, real volume, mulsq = gmx_stats_init(); /* Open all the files */ - outmtot = xvgropen(out_mtot, - "Total dipole moment of the simulation box vs. time", - "Time (ps)", "Total Dipole Moment (Debye)", oenv); - outeps = xvgropen(out_eps, "Epsilon and Kirkwood factors", - "Time (ps)", "", oenv); - outaver = xvgropen(out_aver, "Total dipole moment", - "Time (ps)", "D", oenv); + outmtot = xvgropen(out_mtot, "Total dipole moment of the simulation box vs. time", "Time (ps)", + "Total Dipole Moment (Debye)", oenv); + outeps = xvgropen(out_eps, "Epsilon and Kirkwood factors", "Time (ps)", "", oenv); + outaver = xvgropen(out_aver, "Total dipole moment", "Time (ps)", "D", oenv); if (bSlab) { idim = axtitle[0] - 'X'; @@ -922,8 +914,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, { bSlab = FALSE; } - fprintf(stderr, "axtitle = %s, nslices = %d, idim = %d\n", - axtitle, nslices, idim); + fprintf(stderr, "axtitle = %s, nslices = %d, idim = %d\n", axtitle, nslices, idim); if (bSlab) { snew(slab_dipoles, nslices); @@ -935,14 +926,12 @@ static void do_dip(const t_topology *top, int ePBC, real volume, { adip = xvgropen(fnadip, "Average molecular dipole", "Dipole (D)", "", oenv); xvgr_legend(adip, NLEGADIP, leg_adip, oenv); - } if (cosaver) { - caver = xvgropen(cosaver, bPairs ? "Average pair orientation" : - "Average absolute dipole orientation", "Time (ps)", "", oenv); - xvgr_legend(caver, NLEGCOSAVER, bPairs ? leg_cosaver : &(leg_cosaver[1]), - oenv); + caver = xvgropen(cosaver, bPairs ? "Average pair orientation" : "Average absolute dipole orientation", + "Time (ps)", "", oenv); + xvgr_legend(caver, NLEGCOSAVER, bPairs ? leg_cosaver : &(leg_cosaver[1]), oenv); } if (fndip3d) @@ -960,10 +949,9 @@ static void do_dip(const t_topology *top, int ePBC, real volume, gmx::BinaryInformationSettings settings; settings.generatedByHeader(true); settings.linePrefix("# "); - gmx::printBinaryInformation(dip3d, output_env_get_program_context(oenv), - settings); + gmx::printBinaryInformation(dip3d, output_env_get_program_context(oenv), settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Write legends to all the files */ @@ -972,7 +960,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, if (bMU && (mu_aver == -1)) { - xvgr_legend(outeps, NLEGEPS-2, leg_eps, oenv); + xvgr_legend(outeps, NLEGEPS - 2, leg_eps, oenv); } else { @@ -1006,18 +994,17 @@ static void do_dip(const t_topology *top, int ePBC, real volume, printf("End of %s reached\n", mufn); break; } - } - while (bCont && (timecheck < 0)); + } while (bCont && (timecheck < 0)); } else { - natom = read_first_x(oenv, &status, fn, &t, &x, box); + natom = read_first_x(oenv, &status, fn, &t, &x, box); } /* Calculate spacing for dipole bin (simple histogram) */ - ndipbin = 1 + static_cast(mu_max/0.01); + ndipbin = 1 + static_cast(mu_max / 0.01); snew(dipole_bin, ndipbin); - mu_ave = 0.0; + mu_ave = 0.0; for (m = 0; (m < DIM); m++) { M[m] = M2[m] = M4[m] = 0.0; @@ -1027,7 +1014,8 @@ static void do_dip(const t_topology *top, int ePBC, real volume, { /* Use 0.7 iso 0.5 to account for pressure scaling */ /* rcut = 0.7*sqrt(max_cutoff2(box)); */ - rcut = 0.7*std::sqrt(gmx::square(box[XX][XX])+gmx::square(box[YY][YY])+gmx::square(box[ZZ][ZZ])); + rcut = 0.7 + * std::sqrt(gmx::square(box[XX][XX]) + gmx::square(box[YY][YY]) + gmx::square(box[ZZ][ZZ])); gkrbin = mk_gkrbin(rcut, rcmax, bPhi, ndegrees); } @@ -1043,13 +1031,13 @@ static void do_dip(const t_topology *top, int ePBC, real volume, nframes += 1000; if (bTotal) { - srenew(muall[0], nframes*DIM); + srenew(muall[0], nframes * DIM); } else { for (i = 0; (i < gnx_tot); i++) { - srenew(muall[i], nframes*DIM); + srenew(muall[i], nframes * DIM); } } } @@ -1068,7 +1056,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, /* Copy rvec into double precision local variable */ for (m = 0; (m < DIM); m++) { - M_av[m] = mu_t[m]; + M_av[m] = mu_t[m]; } } else @@ -1088,16 +1076,15 @@ static void do_dip(const t_topology *top, int ePBC, real volume, { int ind0, ind1; - ind0 = mols->index[molindex[n][i]]; - ind1 = mols->index[molindex[n][i]+1]; + ind0 = mols->index[molindex[n][i]]; + ind1 = mols->index[molindex[n][i] + 1]; mol_dip(ind0, ind1, x, atom, dipole[i]); gmx_stats_add_point(mulsq, 0, norm(dipole[i]), 0, 0); gmx_stats_add_point(muframelsq, 0, norm(dipole[i]), 0, 0); if (bSlab) { - update_slab_dipoles(ind0, ind1, x, - dipole[i], idim, nslices, slab_dipoles, box); + update_slab_dipoles(ind0, ind1, x, dipole[i], idim, nslices, slab_dipoles, box); } if (bQuad) { @@ -1109,23 +1096,23 @@ static void do_dip(const t_topology *top, int ePBC, real volume, } if (bCorr && !bTotal) { - tel3 = DIM*teller; - muall[i][tel3+XX] = dipole[i][XX]; - muall[i][tel3+YY] = dipole[i][YY]; - muall[i][tel3+ZZ] = dipole[i][ZZ]; + tel3 = DIM * teller; + muall[i][tel3 + XX] = dipole[i][XX]; + muall[i][tel3 + YY] = dipole[i][YY]; + muall[i][tel3 + ZZ] = dipole[i][ZZ]; } mu_mol = 0.0; for (m = 0; (m < DIM); m++) { - M_av[m] += dipole[i][m]; /* M per frame */ - mu_mol += dipole[i][m]*dipole[i][m]; /* calc. mu for distribution */ + M_av[m] += dipole[i][m]; /* M per frame */ + mu_mol += dipole[i][m] * dipole[i][m]; /* calc. mu for distribution */ } mu_mol = std::sqrt(mu_mol); - mu_ave += mu_mol; /* calc. the average mu */ + mu_ave += mu_mol; /* calc. the average mu */ /* Update the dipole distribution */ - ibin = gmx::roundToInt(ndipbin*mu_mol/mu_max); + ibin = gmx::roundToInt(ndipbin * mu_mol / mu_max); if (ibin < ndipbin) { dipole_bin[ibin]++; @@ -1135,7 +1122,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, { rvec2sprvec(dipole[i], dipsp[i]); - if (dipsp[i][YY] > -M_PI && dipsp[i][YY] < -0.5*M_PI) + if (dipsp[i][YY] > -M_PI && dipsp[i][YY] < -0.5 * M_PI) { if (dipsp[i][ZZ] < 0.5 * M_PI) { @@ -1146,7 +1133,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, ncolour = 2; } } - else if (dipsp[i][YY] > -0.5*M_PI && dipsp[i][YY] < 0.0*M_PI) + else if (dipsp[i][YY] > -0.5 * M_PI && dipsp[i][YY] < 0.0 * M_PI) { if (dipsp[i][ZZ] < 0.5 * M_PI) { @@ -1157,7 +1144,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, ncolour = 4; } } - else if (dipsp[i][YY] > 0.0 && dipsp[i][YY] < 0.5*M_PI) + else if (dipsp[i][YY] > 0.0 && dipsp[i][YY] < 0.5 * M_PI) { if (dipsp[i][ZZ] < 0.5 * M_PI) { @@ -1168,7 +1155,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, ncolour = 6; } } - else if (dipsp[i][YY] > 0.5*M_PI && dipsp[i][YY] < M_PI) + else if (dipsp[i][YY] > 0.5 * M_PI && dipsp[i][YY] < M_PI) { if (dipsp[i][ZZ] < 0.5 * M_PI) { @@ -1181,15 +1168,11 @@ static void do_dip(const t_topology *top, int ePBC, real volume, } if (dip3d) { - fprintf(dip3d, "set arrow %d from %f, %f, %f to %f, %f, %f lt %d # %d %d\n", - i+1, - x[ind0][XX], - x[ind0][YY], - x[ind0][ZZ], - x[ind0][XX]+dipole[i][XX]/25, - x[ind0][YY]+dipole[i][YY]/25, - x[ind0][ZZ]+dipole[i][ZZ]/25, - ncolour, ind0, i); + fprintf(dip3d, + "set arrow %d from %f, %f, %f to %f, %f, %f lt %d # %d %d\n", + i + 1, x[ind0][XX], x[ind0][YY], x[ind0][ZZ], + x[ind0][XX] + dipole[i][XX] / 25, x[ind0][YY] + dipole[i][YY] / 25, + x[ind0][ZZ] + dipole[i][ZZ] / 25, ncolour, ind0, i); } } } /* End loop of all molecules in frame */ @@ -1208,39 +1191,37 @@ static void do_dip(const t_topology *top, int ePBC, real volume, /* Compute square of total dipole */ for (m = 0; (m < DIM); m++) { - M_av2[m] = M_av[m]*M_av[m]; + M_av2[m] = M_av[m] * M_av[m]; } if (cosaver) { compute_avercos(gnx_tot, dipole, &dd, dipaxis, bPairs); - rms_cos = std::sqrt(gmx::square(dipaxis[XX]-0.5)+ - gmx::square(dipaxis[YY]-0.5)+ - gmx::square(dipaxis[ZZ]-0.5)); + rms_cos = std::sqrt(gmx::square(dipaxis[XX] - 0.5) + gmx::square(dipaxis[YY] - 0.5) + + gmx::square(dipaxis[ZZ] - 0.5)); if (bPairs) { - fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n", - t, dd, rms_cos, dipaxis[XX], dipaxis[YY], dipaxis[ZZ]); + fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n", t, dd, rms_cos, + dipaxis[XX], dipaxis[YY], dipaxis[ZZ]); } else { - fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e\n", - t, rms_cos, dipaxis[XX], dipaxis[YY], dipaxis[ZZ]); + fprintf(caver, "%10.3e %10.3e %10.3e %10.3e %10.3e\n", t, rms_cos, dipaxis[XX], + dipaxis[YY], dipaxis[ZZ]); } } if (bGkr) { - do_gkr(gkrbin, ncos, gnx, molindex, mols->index, x, dipole, ePBC, box, - atom, gkatom); + do_gkr(gkrbin, ncos, gnx, molindex, mols->index, x, dipole, ePBC, box, atom, gkatom); } if (bTotal) { - tel3 = DIM*teller; - muall[0][tel3+XX] = M_av[XX]; - muall[0][tel3+YY] = M_av[YY]; - muall[0][tel3+ZZ] = M_av[ZZ]; + tel3 = DIM * teller; + muall[0][tel3 + XX] = M_av[XX]; + muall[0][tel3 + YY] = M_av[YY]; + muall[0][tel3 + ZZ] = M_av[ZZ]; } /* Write to file the total dipole moment of the box, and its components @@ -1248,14 +1229,13 @@ static void do_dip(const t_topology *top, int ePBC, real volume, */ if ((skip == 0) || ((teller % skip) == 0)) { - fprintf(outmtot, "%10g %12.8e %12.8e %12.8e %12.8e\n", - t, M_av[XX], M_av[YY], M_av[ZZ], - std::sqrt(M_av2[XX]+M_av2[YY]+M_av2[ZZ])); + fprintf(outmtot, "%10g %12.8e %12.8e %12.8e %12.8e\n", t, M_av[XX], M_av[YY], M_av[ZZ], + std::sqrt(M_av2[XX] + M_av2[YY] + M_av2[ZZ])); } for (m = 0; (m < DIM); m++) { - M[m] += M_av[m]; + M[m] += M_av[m]; M2[m] += M_av2[m]; M4[m] += gmx::square(M_av2[m]); } @@ -1263,24 +1243,24 @@ static void do_dip(const t_topology *top, int ePBC, real volume, teller++; /* Calculate for output the running averages */ - invtel = 1.0/teller; - M2_ave = (M2[XX]+M2[YY]+M2[ZZ])*invtel; - M_ave2 = invtel*(invtel*(M[XX]*M[XX] + M[YY]*M[YY] + M[ZZ]*M[ZZ])); - M_diff = M2_ave - M_ave2; + invtel = 1.0 / teller; + M2_ave = (M2[XX] + M2[YY] + M2[ZZ]) * invtel; + M_ave2 = invtel * (invtel * (M[XX] * M[XX] + M[YY] * M[YY] + M[ZZ] * M[ZZ])); + M_diff = M2_ave - M_ave2; /* Compute volume from box in traj, else we use the one from above */ if (!bMU) { - volume = det(box); + volume = det(box); } vol_aver += volume; - epsilon = calc_eps(M_diff, (vol_aver/teller), epsilonRF, temp); + epsilon = calc_eps(M_diff, (vol_aver / teller), epsilonRF, temp); /* Calculate running average for dipole */ if (mu_ave != 0) { - mu_aver = (mu_ave/gnx_tot)*invtel; + mu_aver = (mu_ave / gnx_tot) * invtel; } if ((skip == 0) || ((teller % skip) == 0)) @@ -1289,8 +1269,8 @@ static void do_dip(const t_topology *top, int ePBC, real volume, * the two. Here M is sum mu_i. Further write the finite system * Kirkwood G factor and epsilon. */ - fprintf(outaver, "%10g %10.3e %10.3e %10.3e %10.3e\n", - t, M2_ave, M_ave2, M_diff, M_ave2/M2_ave); + fprintf(outaver, "%10g %10.3e %10.3e %10.3e %10.3e\n", t, M2_ave, M_ave2, M_diff, + M_ave2 / M2_ave); if (fnadip) { @@ -1304,20 +1284,19 @@ static void do_dip(const t_topology *top, int ePBC, real volume, if (!bMU || (mu_aver != -1)) { /* Finite system Kirkwood G-factor */ - Gk = M_diff/(gnx_tot*mu_aver*mu_aver); + Gk = M_diff / (gnx_tot * mu_aver * mu_aver); /* Infinite system Kirkwood G-factor */ if (epsilonRF == 0.0) { - g_k = ((2*epsilon+1)*Gk/(3*epsilon)); + g_k = ((2 * epsilon + 1) * Gk / (3 * epsilon)); } else { - g_k = ((2*epsilonRF+epsilon)*(2*epsilon+1)* - Gk/(3*epsilon*(2*epsilonRF+1))); + g_k = ((2 * epsilonRF + epsilon) * (2 * epsilon + 1) * Gk + / (3 * epsilon * (2 * epsilonRF + 1))); } fprintf(outeps, "%10g %10.3e %10.3e %10.3e\n", t, epsilon, Gk, g_k); - } else { @@ -1335,8 +1314,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, bCont = read_next_x(oenv, status, &t, x, box); } timecheck = check_times(t); - } - while (bCont && (timecheck == 0) ); + } while (bCont && (timecheck == 0)); gmx_rmpbc_done(gpbc); @@ -1391,21 +1369,20 @@ static void do_dip(const t_topology *top, int ePBC, real volume, } else { - dt = (t1 - t0)/(teller-1); + dt = (t1 - t0) / (teller - 1); printf("t0 %g, t %g, teller %d\n", t0, t, teller); mode = eacVector; if (bTotal) { - do_autocorr(corf, oenv, "Autocorrelation Function of Total Dipole", - teller, 1, muall, dt, mode, TRUE); + do_autocorr(corf, oenv, "Autocorrelation Function of Total Dipole", teller, 1, + muall, dt, mode, TRUE); } else { - do_autocorr(corf, oenv, "Dipole Autocorrelation Function", - teller, gnx_tot, muall, dt, - mode, std::strcmp(corrtype, "molsep") != 0); + do_autocorr(corf, oenv, "Dipole Autocorrelation Function", teller, gnx_tot, muall, + dt, mode, std::strcmp(corrtype, "molsep") != 0); } } } @@ -1416,8 +1393,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, gmx_stats_get_ase(mulsq, &aver, &sigma, &error); printf("\nDipole moment (Debye)\n"); printf("---------------------\n"); - printf("Average = %8.4f Std. Dev. = %8.4f Error = %8.4f\n", - aver, sigma, error); + printf("Average = %8.4f Std. Dev. = %8.4f Error = %8.4f\n", aver, sigma, error); if (bQuad) { rvec a, s, e; @@ -1435,13 +1411,13 @@ static void do_dip(const t_topology *top, int ePBC, real volume, printf("\n"); } printf("The following averages for the complete trajectory have been calculated:\n\n"); - printf(" Total < M_x > = %g Debye\n", M[XX]/teller); - printf(" Total < M_y > = %g Debye\n", M[YY]/teller); - printf(" Total < M_z > = %g Debye\n\n", M[ZZ]/teller); + printf(" Total < M_x > = %g Debye\n", M[XX] / teller); + printf(" Total < M_y > = %g Debye\n", M[YY] / teller); + printf(" Total < M_z > = %g Debye\n\n", M[ZZ] / teller); - printf(" Total < M_x^2 > = %g Debye^2\n", M2[XX]/teller); - printf(" Total < M_y^2 > = %g Debye^2\n", M2[YY]/teller); - printf(" Total < M_z^2 > = %g Debye^2\n\n", M2[ZZ]/teller); + printf(" Total < M_x^2 > = %g Debye^2\n", M2[XX] / teller); + printf(" Total < M_y^2 > = %g Debye^2\n", M2[YY] / teller); + printf(" Total < M_z^2 > = %g Debye^2\n\n", M2[ZZ] / teller); printf(" Total < |M|^2 > = %g Debye^2\n", M2_ave); printf(" Total |< M >|^2 = %g Debye^2\n\n", M_ave2); @@ -1462,8 +1438,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, outdd = xvgropen(dipdist, "Dipole Moment Distribution", "mu (Debye)", "", oenv); for (i = 0; (i < ndipbin); i++) { - fprintf(outdd, "%10g %10f\n", - (i*mu_max)/ndipbin, static_cast(dipole_bin[i])/teller); + fprintf(outdd, "%10g %10f\n", (i * mu_max) / ndipbin, static_cast(dipole_bin[i]) / teller); } xvgrclose(outdd); sfree(dipole_bin); @@ -1474,7 +1449,7 @@ static void do_dip(const t_topology *top, int ePBC, real volume, } } -static void dipole_atom2molindex(int *n, int *index, const t_block *mols) +static void dipole_atom2molindex(int* n, int* index, const t_block* mols) { int nmol, i, j, m; @@ -1489,9 +1464,10 @@ static void dipole_atom2molindex(int *n, int *index, const t_block *mols) } if (m == mols->nr) { - gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule", i+1, index[i]+1); + gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule", + i + 1, index[i] + 1); } - for (j = mols->index[m]; j < mols->index[m+1]; j++) + for (j = mols->index[m]; j < mols->index[m + 1]; j++) { if (i >= *n || index[i] != j) { @@ -1506,9 +1482,9 @@ static void dipole_atom2molindex(int *n, int *index, const t_block *mols) *n = nmol; } -int gmx_dipoles(int argc, char *argv[]) +int gmx_dipoles(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the total dipole plus fluctuations of a simulation", "system. From this you can compute e.g. the dielectric constant for", "low-dielectric media.", @@ -1516,7 +1492,8 @@ int gmx_dipoles(int argc, char *argv[]) "center of mass of the molecule.[PAR]", "The file [TT]Mtot.xvg[tt] contains the total dipole moment of a frame, the", "components as well as the norm of the vector.", - "The file [TT]aver.xvg[tt] contains [CHEVRON][MAG][GRK]mu[grk][mag]^2[chevron] and [MAG][CHEVRON][GRK]mu[grk][chevron][mag]^2 during the", + "The file [TT]aver.xvg[tt] contains [CHEVRON][MAG][GRK]mu[grk][mag]^2[chevron] and ", + "[MAG][CHEVRON][GRK]mu[grk][chevron][mag]^2 during the", "simulation.", "The file [TT]dipdist.xvg[tt] contains the distribution of dipole moments during", "the simulation", @@ -1545,103 +1522,134 @@ int gmx_dipoles(int argc, char *argv[]) "an average dipole moment of the molecule of 2.273 (SPC). For the", "distribution function a maximum of 5.0 will be used." }; - real mu_max = 5, mu_aver = -1, rcmax = 0; - real epsilonRF = 0.0, temp = 300; - gmx_bool bPairs = TRUE, bPhi = FALSE, bQuad = FALSE; - const char *corrtype[] = {nullptr, "none", "mol", "molsep", "total", nullptr}; - const char *axtitle = "Z"; + real mu_max = 5, mu_aver = -1, rcmax = 0; + real epsilonRF = 0.0, temp = 300; + gmx_bool bPairs = TRUE, bPhi = FALSE, bQuad = FALSE; + const char* corrtype[] = { nullptr, "none", "mol", "molsep", "total", nullptr }; + const char* axtitle = "Z"; int nslices = 10; /* nr of slices defined */ - int skip = 0, nFA = 0, nFB = 0, ncos = 1; - int nlevels = 20, ndegrees = 90; - gmx_output_env_t *oenv; + int skip = 0, nFA = 0, nFB = 0, ncos = 1; + int nlevels = 20, ndegrees = 90; + gmx_output_env_t* oenv; t_pargs pa[] = { - { "-mu", FALSE, etREAL, {&mu_aver}, - "dipole of a single molecule (in Debye)" }, - { "-mumax", FALSE, etREAL, {&mu_max}, - "max dipole in Debye (for histogram)" }, - { "-epsilonRF", FALSE, etREAL, {&epsilonRF}, - "[GRK]epsilon[grk] of the reaction field used during the simulation, needed for dielectric constant calculation. WARNING: 0.0 means infinity (default)" }, - { "-skip", FALSE, etINT, {&skip}, + { "-mu", FALSE, etREAL, { &mu_aver }, "dipole of a single molecule (in Debye)" }, + { "-mumax", FALSE, etREAL, { &mu_max }, "max dipole in Debye (for histogram)" }, + { "-epsilonRF", + FALSE, + etREAL, + { &epsilonRF }, + "[GRK]epsilon[grk] of the reaction field used during the simulation, needed for " + "dielectric constant calculation. WARNING: 0.0 means infinity (default)" }, + { "-skip", + FALSE, + etINT, + { &skip }, "Skip steps in the output (but not in the computations)" }, - { "-temp", FALSE, etREAL, {&temp}, + { "-temp", + FALSE, + etREAL, + { &temp }, "Average temperature of the simulation (needed for dielectric constant calculation)" }, - { "-corr", FALSE, etENUM, {corrtype}, - "Correlation function to calculate" }, - { "-pairs", FALSE, etBOOL, {&bPairs}, - "Calculate [MAG][COS][GRK]theta[grk][cos][mag] between all pairs of molecules. May be slow" }, - { "-quad", FALSE, etBOOL, {&bQuad}, - "Take quadrupole into account"}, - { "-ncos", FALSE, etINT, {&ncos}, - "Must be 1 or 2. Determines whether the [CHEVRON][COS][GRK]theta[grk][cos][chevron] is computed between all molecules in one group, or between molecules in two different groups. This turns on the [TT]-g[tt] flag." }, - { "-axis", FALSE, etSTR, {&axtitle}, + { "-corr", FALSE, etENUM, { corrtype }, "Correlation function to calculate" }, + { "-pairs", + FALSE, + etBOOL, + { &bPairs }, + "Calculate [MAG][COS][GRK]theta[grk][cos][mag] between all pairs of molecules. May be " + "slow" }, + { "-quad", FALSE, etBOOL, { &bQuad }, "Take quadrupole into account" }, + { "-ncos", + FALSE, + etINT, + { &ncos }, + "Must be 1 or 2. Determines whether the [CHEVRON][COS][GRK]theta[grk][cos][chevron] is " + "computed between all molecules in one group, or between molecules in two different " + "groups. This turns on the [TT]-g[tt] flag." }, + { "-axis", + FALSE, + etSTR, + { &axtitle }, "Take the normal on the computational box in direction X, Y or Z." }, - { "-sl", FALSE, etINT, {&nslices}, - "Divide the box into this number of slices." }, - { "-gkratom", FALSE, etINT, {&nFA}, - "Use the n-th atom of a molecule (starting from 1) to calculate the distance between molecules rather than the center of charge (when 0) in the calculation of distance dependent Kirkwood factors" }, - { "-gkratom2", FALSE, etINT, {&nFB}, - "Same as previous option in case ncos = 2, i.e. dipole interaction between two groups of molecules" }, - { "-rcmax", FALSE, etREAL, {&rcmax}, - "Maximum distance to use in the dipole orientation distribution (with ncos == 2). If zero, a criterion based on the box length will be used." }, - { "-phi", FALSE, etBOOL, {&bPhi}, - "Plot the 'torsion angle' defined as the rotation of the two dipole vectors around the distance vector between the two molecules in the [REF].xpm[ref] file from the [TT]-cmap[tt] option. By default the cosine of the angle between the dipoles is plotted." }, - { "-nlevels", FALSE, etINT, {&nlevels}, - "Number of colors in the cmap output" }, - { "-ndegrees", FALSE, etINT, {&ndegrees}, + { "-sl", FALSE, etINT, { &nslices }, "Divide the box into this number of slices." }, + { "-gkratom", + FALSE, + etINT, + { &nFA }, + "Use the n-th atom of a molecule (starting from 1) to calculate the distance between " + "molecules rather than the center of charge (when 0) in the calculation of distance " + "dependent Kirkwood factors" }, + { "-gkratom2", + FALSE, + etINT, + { &nFB }, + "Same as previous option in case ncos = 2, i.e. dipole interaction between two groups of " + "molecules" }, + { "-rcmax", + FALSE, + etREAL, + { &rcmax }, + "Maximum distance to use in the dipole orientation distribution (with ncos == 2). If " + "zero, a criterion based on the box length will be used." }, + { "-phi", + FALSE, + etBOOL, + { &bPhi }, + "Plot the 'torsion angle' defined as the rotation of the two dipole vectors around the " + "distance vector between the two molecules in the [REF].xpm[ref] file from the " + "[TT]-cmap[tt] option. By default the cosine of the angle between the dipoles is " + "plotted." }, + { "-nlevels", FALSE, etINT, { &nlevels }, "Number of colors in the cmap output" }, + { "-ndegrees", + FALSE, + etINT, + { &ndegrees }, "Number of divisions on the [IT]y[it]-axis in the cmap output (for 180 degrees)" } }; - int *gnx; - int nFF[2]; - int **grpindex; - char **grpname = nullptr; - gmx_bool bGkr, bMU, bSlab; - t_filenm fnm[] = { - { efEDR, "-en", nullptr, ffOPTRD }, - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-o", "Mtot", ffWRITE }, - { efXVG, "-eps", "epsilon", ffWRITE }, - { efXVG, "-a", "aver", ffWRITE }, - { efXVG, "-d", "dipdist", ffWRITE }, - { efXVG, "-c", "dipcorr", ffOPTWR }, - { efXVG, "-g", "gkr", ffOPTWR }, - { efXVG, "-adip", "adip", ffOPTWR }, - { efXVG, "-dip3d", "dip3d", ffOPTWR }, - { efXVG, "-cos", "cosaver", ffOPTWR }, - { efXPM, "-cmap", "cmap", ffOPTWR }, - { efXVG, "-slab", "slab", ffOPTWR } - }; + int* gnx; + int nFF[2]; + int** grpindex; + char** grpname = nullptr; + gmx_bool bGkr, bMU, bSlab; + t_filenm fnm[] = { { efEDR, "-en", nullptr, ffOPTRD }, { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffOPTRD }, + { efXVG, "-o", "Mtot", ffWRITE }, { efXVG, "-eps", "epsilon", ffWRITE }, + { efXVG, "-a", "aver", ffWRITE }, { efXVG, "-d", "dipdist", ffWRITE }, + { efXVG, "-c", "dipcorr", ffOPTWR }, { efXVG, "-g", "gkr", ffOPTWR }, + { efXVG, "-adip", "adip", ffOPTWR }, { efXVG, "-dip3d", "dip3d", ffOPTWR }, + { efXVG, "-cos", "cosaver", ffOPTWR }, { efXPM, "-cmap", "cmap", ffOPTWR }, + { efXVG, "-slab", "slab", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; - t_topology *top; - int ePBC; - int k, natoms; - matrix box; + int npargs; + t_pargs* ppa; + t_topology* top; + int ePBC; + int k, natoms; + matrix box; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, + asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; } - printf("Using %g as mu_max and %g as the dipole moment.\n", - mu_max, mu_aver); + printf("Using %g as mu_max and %g as the dipole moment.\n", mu_max, mu_aver); if (epsilonRF == 0.0) { printf("WARNING: EpsilonRF = 0.0, this really means EpsilonRF = infinity\n"); } - bMU = opt2bSet("-en", NFILE, fnm); + bMU = opt2bSet("-en", NFILE, fnm); if (bMU) { - gmx_fatal(FARGS, "Due to new ways of treating molecules in GROMACS the total dipole in the energy file may be incorrect, because molecules can be split over periodic boundary conditions before computing the dipole. Please use your trajectory file."); + gmx_fatal(FARGS, + "Due to new ways of treating molecules in GROMACS the total dipole in the energy " + "file may be incorrect, because molecules can be split over periodic boundary " + "conditions before computing the dipole. Please use your trajectory file."); } - bGkr = opt2bSet("-g", NFILE, fnm); + bGkr = opt2bSet("-g", NFILE, fnm); if (opt2parg_bSet("-ncos", asize(pa), pa)) { if ((ncos != 1) && (ncos != 2)) @@ -1650,8 +1658,8 @@ int gmx_dipoles(int argc, char *argv[]) } bGkr = TRUE; } - bSlab = (opt2bSet("-slab", NFILE, fnm) || opt2parg_bSet("-sl", asize(pa), pa) || - opt2parg_bSet("-axis", asize(pa), pa)); + bSlab = (opt2bSet("-slab", NFILE, fnm) || opt2parg_bSet("-sl", asize(pa), pa) + || opt2parg_bSet("-axis", asize(pa), pa)); if (bMU) { if (bQuad) @@ -1662,8 +1670,8 @@ int gmx_dipoles(int argc, char *argv[]) if (bGkr) { printf("WARNING: Can not determine Gk(r) from energy file\n"); - bGkr = FALSE; - ncos = 1; + bGkr = FALSE; + ncos = 1; } if (mu_aver == -1) { @@ -1673,14 +1681,12 @@ int gmx_dipoles(int argc, char *argv[]) } snew(top, 1); - ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), nullptr, box, - &natoms, nullptr, nullptr, top); + ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms, nullptr, nullptr, top); snew(gnx, ncos); snew(grpname, ncos); snew(grpindex, ncos); - get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), - ncos, gnx, grpindex, grpname); + get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), ncos, gnx, grpindex, grpname); for (k = 0; (k < ncos); k++) { dipole_atom2molindex(&gnx[k], grpindex[k], &(top->mols)); @@ -1688,20 +1694,13 @@ int gmx_dipoles(int argc, char *argv[]) } nFF[0] = nFA; nFF[1] = nFB; - do_dip(top, ePBC, det(box), ftp2fn(efTRX, NFILE, fnm), - opt2fn("-o", NFILE, fnm), opt2fn("-eps", NFILE, fnm), - opt2fn("-a", NFILE, fnm), opt2fn("-d", NFILE, fnm), - opt2fn_null("-cos", NFILE, fnm), - opt2fn_null("-dip3d", NFILE, fnm), opt2fn_null("-adip", NFILE, fnm), - bPairs, corrtype[0], - opt2fn("-c", NFILE, fnm), - bGkr, opt2fn("-g", NFILE, fnm), - bPhi, &nlevels, ndegrees, - ncos, - opt2fn("-cmap", NFILE, fnm), rcmax, - bQuad, bMU, opt2fn("-en", NFILE, fnm), - gnx, grpindex, mu_max, mu_aver, epsilonRF, temp, nFF, skip, - bSlab, nslices, axtitle, opt2fn("-slab", NFILE, fnm), oenv); + do_dip(top, ePBC, det(box), ftp2fn(efTRX, NFILE, fnm), opt2fn("-o", NFILE, fnm), + opt2fn("-eps", NFILE, fnm), opt2fn("-a", NFILE, fnm), opt2fn("-d", NFILE, fnm), + opt2fn_null("-cos", NFILE, fnm), opt2fn_null("-dip3d", NFILE, fnm), + opt2fn_null("-adip", NFILE, fnm), bPairs, corrtype[0], opt2fn("-c", NFILE, fnm), bGkr, + opt2fn("-g", NFILE, fnm), bPhi, &nlevels, ndegrees, ncos, opt2fn("-cmap", NFILE, fnm), + rcmax, bQuad, bMU, opt2fn("-en", NFILE, fnm), gnx, grpindex, mu_max, mu_aver, epsilonRF, + temp, nFF, skip, bSlab, nslices, axtitle, opt2fn("-slab", NFILE, fnm), oenv); do_view(oenv, opt2fn("-o", NFILE, fnm), "-autoscale xy -nxy"); do_view(oenv, opt2fn("-eps", NFILE, fnm), "-autoscale xy -nxy"); diff --git a/src/gromacs/gmxana/gmx_disre.cpp b/src/gromacs/gmxana/gmx_disre.cpp index 2bed1d997f..66a79e7276 100644 --- a/src/gromacs/gmxana/gmx_disre.cpp +++ b/src/gromacs/gmxana/gmx_disre.cpp @@ -75,15 +75,17 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int n; real v; } t_toppop; -static t_toppop *top = nullptr; +static t_toppop* top = nullptr; static int ntop = 0; -typedef struct { +typedef struct +{ int nv, nframes; real sumv, averv, maxv; real *aver1, *aver2, *aver_3, *aver_6; @@ -125,11 +127,11 @@ static void add5(int ndr, real viol) } } -static void print5(FILE *fp) +static void print5(FILE* fp) { int i; - std::sort(top, top+ntop, [](const t_toppop &a, const t_toppop &b) {return a.v > b.v; }); //reverse sort + std::sort(top, top + ntop, [](const t_toppop& a, const t_toppop& b) { return a.v > b.v; }); // reverse sort fprintf(fp, "Index:"); for (i = 0; (i < ntop); i++) { @@ -143,18 +145,25 @@ static void print5(FILE *fp) fprintf(fp, "\n"); } -static void check_viol(FILE *log, - t_ilist *disres, t_iparams forceparams[], - rvec x[], rvec4 f[], - t_pbc *pbc, t_graph *g, t_dr_result dr[], - int clust_id, int isize, const int index[], real vvindex[], - t_fcdata *fcd) +static void check_viol(FILE* log, + t_ilist* disres, + t_iparams forceparams[], + rvec x[], + rvec4 f[], + t_pbc* pbc, + t_graph* g, + t_dr_result dr[], + int clust_id, + int isize, + const int index[], + real vvindex[], + t_fcdata* fcd) { - t_iatom *forceatoms; - int i, j, nat, n, type, nviol, ndr, label; - real rt, mviol, tviol, viol, lam, dvdl, drt; - rvec *fshift; - static gmx_bool bFirst = TRUE; + t_iatom* forceatoms; + int i, j, nat, n, type, nviol, ndr, label; + real rt, mviol, tviol, viol, lam, dvdl, drt; + rvec* fshift; + static gmx_bool bFirst = TRUE; lam = 0; dvdl = 0; @@ -171,26 +180,22 @@ static void check_viol(FILE *log, { vvindex[j] = 0; } - nat = interaction_function[F_DISRES].nratoms+1; - for (i = 0; (i < disres->nr); ) + nat = interaction_function[F_DISRES].nratoms + 1; + for (i = 0; (i < disres->nr);) { type = forceatoms[i]; n = 0; label = forceparams[type].disres.label; if (debug) { - fprintf(debug, "DISRE: ndr = %d, label = %d i=%d, n =%d\n", - ndr, label, i, n); + fprintf(debug, "DISRE: ndr = %d, label = %d i=%d, n =%d\n", ndr, label, i, n); } do { n += nat; - } - while (((i+n) < disres->nr) && - (forceparams[forceatoms[i+n]].disres.label == label)); + } while (((i + n) < disres->nr) && (forceparams[forceatoms[i + n]].disres.label == label)); - calc_disres_R_6(nullptr, nullptr, n, &forceatoms[i], - x, pbc, fcd, nullptr); + calc_disres_R_6(nullptr, nullptr, n, &forceatoms[i], x, pbc, fcd, nullptr); if (fcd->disres.Rt_6[label] <= 0) { @@ -198,16 +203,14 @@ static void check_viol(FILE *log, } rt = gmx::invsixthroot(fcd->disres.Rt_6[label]); - dr[clust_id].aver1[ndr] += rt; - dr[clust_id].aver2[ndr] += gmx::square(rt); - drt = 1.0/gmx::power3(rt); + dr[clust_id].aver1[ndr] += rt; + dr[clust_id].aver2[ndr] += gmx::square(rt); + drt = 1.0 / gmx::power3(rt); dr[clust_id].aver_3[ndr] += drt; dr[clust_id].aver_6[ndr] += fcd->disres.Rt_6[label]; snew(fshift, SHIFTS); - ta_disres(n, &forceatoms[i], forceparams, - x, f, fshift, - pbc, g, lam, &dvdl, nullptr, fcd, nullptr); + ta_disres(n, &forceatoms[i], forceparams, x, f, fshift, pbc, g, lam, &dvdl, nullptr, fcd, nullptr); sfree(fshift); viol = fcd->disres.sumviol; @@ -232,18 +235,17 @@ static void check_viol(FILE *log, } } ndr++; - i += n; + i += n; } dr[clust_id].nv = nviol; dr[clust_id].maxv = mviol; dr[clust_id].sumv = tviol; - dr[clust_id].averv = tviol/ndr; + dr[clust_id].averv = tviol / ndr; dr[clust_id].nframes++; if (bFirst) { - fprintf(stderr, "\nThere are %d restraints and %d pairs\n", - ndr, disres->nr/nat); + fprintf(stderr, "\nThere are %d restraints and %d pairs\n", ndr, disres->nr / nat); bFirst = FALSE; } if (ntop) @@ -252,16 +254,17 @@ static void check_viol(FILE *log, } } -typedef struct { +typedef struct +{ int label; gmx_bool bCore; real up1, r, rT3, rT6, viol, violT3, violT6; } t_dr_stats; -static void dump_dump(FILE *log, int ndr, t_dr_stats drs[]) +static void dump_dump(FILE* log, int ndr, t_dr_stats drs[]) { - static const char *core[] = { "All restraints", "Core restraints" }; - static const char *tp[] = { "linear", "third power", "sixth power" }; + static const char* core[] = { "All restraints", "Core restraints" }; + static const char* tp[] = { "linear", "third power", "sixth power" }; real viol_tot, viol_max, viol = 0; gmx_bool bCore; int nviol, nrestr; @@ -272,34 +275,27 @@ static void dump_dump(FILE *log, int ndr, t_dr_stats drs[]) bCore = (iCore == 1); for (kkk = 0; (kkk < 3); kkk++) { - viol_tot = 0; - viol_max = 0; - nviol = 0; - nrestr = 0; + viol_tot = 0; + viol_max = 0; + nviol = 0; + nrestr = 0; for (i = 0; (i < ndr); i++) { if (!bCore || drs[i].bCore) { switch (kkk) { - case 0: - viol = drs[i].viol; - break; - case 1: - viol = drs[i].violT3; - break; - case 2: - viol = drs[i].violT6; - break; - default: - gmx_incons("Dumping violations"); + case 0: viol = drs[i].viol; break; + case 1: viol = drs[i].violT3; break; + case 2: viol = drs[i].violT6; break; + default: gmx_incons("Dumping violations"); } - viol_max = std::max(viol_max, viol); + viol_max = std::max(viol_max, viol); if (viol > 0) { nviol++; } - viol_tot += viol; + viol_tot += viol; nrestr++; } } @@ -311,7 +307,7 @@ static void dump_dump(FILE *log, int ndr, t_dr_stats drs[]) fprintf(log, "Sum of violations: %8.3f nm\n", viol_tot); if (nrestr > 0) { - fprintf(log, "Average violation: %8.3f nm\n", viol_tot/nrestr); + fprintf(log, "Average violation: %8.3f nm\n", viol_tot / nrestr); } fprintf(log, "Largest violation: %8.3f nm\n", viol_max); fprintf(log, "Number of violated restraints: %d/%d\n", nviol, nrestr); @@ -320,20 +316,19 @@ static void dump_dump(FILE *log, int ndr, t_dr_stats drs[]) } } -static void dump_viol(FILE *log, int ndr, t_dr_stats *drs, gmx_bool bLinear) +static void dump_viol(FILE* log, int ndr, t_dr_stats* drs, gmx_bool bLinear) { int i; fprintf(log, "Restr. Core Up1 \n"); for (i = 0; (i < ndr); i++) { - if (bLinear && (drs[i].viol == 0)) + if (bLinear && (drs[i].viol == 0)) { break; } - fprintf(log, "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n", - drs[i].label, yesno_names[drs[i].bCore], - drs[i].up1, drs[i].r, drs[i].rT3, drs[i].rT6, + fprintf(log, "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n", drs[i].label, + yesno_names[drs[i].bCore], drs[i].up1, drs[i].r, drs[i].rT3, drs[i].rT6, drs[i].viol, drs[i].violT3, drs[i].violT6); } } @@ -351,13 +346,17 @@ static gmx_bool is_core(int i, int isize, const int index[]) return bIC; } -static void dump_stats(FILE *log, int nsteps, - const t_disresdata &dd, - const t_ilist *disres, - t_iparams ip[], t_dr_result *dr, - int isize, int index[], t_atoms *atoms) +static void dump_stats(FILE* log, + int nsteps, + const t_disresdata& dd, + const t_ilist* disres, + t_iparams ip[], + t_dr_result* dr, + int isize, + int index[], + t_atoms* atoms) { - t_dr_stats *drs; + t_dr_stats* drs; fprintf(log, "\n"); fprintf(log, "++++++++++++++ STATISTICS ++++++++++++++++++++++++\n"); @@ -366,31 +365,31 @@ static void dump_stats(FILE *log, int nsteps, for (int j = 0; j < disres->nr; j += nra) { // Note that the restraint i can be used by multiple pairs - const int i = disres->iatoms[j] - dd.type_min; + const int i = disres->iatoms[j] - dd.type_min; GMX_RELEASE_ASSERT(i >= 0 && i < dd.nres, "The restraint index should be in range"); drs[i].label = ip[disres->iatoms[j]].disres.label; drs[i].bCore = is_core(drs[i].label, isize, index); drs[i].up1 = ip[disres->iatoms[j]].disres.up1; - drs[i].r = dr->aver1[i]/nsteps; - drs[i].rT3 = gmx::invcbrt(dr->aver_3[i]/nsteps); - drs[i].rT6 = gmx::invsixthroot(dr->aver_6[i]/nsteps); - drs[i].viol = std::max(0.0, static_cast(drs[i].r-drs[i].up1)); - drs[i].violT3 = std::max(0.0, static_cast(drs[i].rT3-drs[i].up1)); - drs[i].violT6 = std::max(0.0, static_cast(drs[i].rT6-drs[i].up1)); + drs[i].r = dr->aver1[i] / nsteps; + drs[i].rT3 = gmx::invcbrt(dr->aver_3[i] / nsteps); + drs[i].rT6 = gmx::invsixthroot(dr->aver_6[i] / nsteps); + drs[i].viol = std::max(0.0, static_cast(drs[i].r - drs[i].up1)); + drs[i].violT3 = std::max(0.0, static_cast(drs[i].rT3 - drs[i].up1)); + drs[i].violT6 = std::max(0.0, static_cast(drs[i].rT6 - drs[i].up1)); if (atoms) { - int j1 = disres->iatoms[j+1]; - int j2 = disres->iatoms[j+2]; - atoms->pdbinfo[j1].bfac += drs[i].violT3*5; - atoms->pdbinfo[j2].bfac += drs[i].violT3*5; + int j1 = disres->iatoms[j + 1]; + int j2 = disres->iatoms[j + 2]; + atoms->pdbinfo[j1].bfac += drs[i].violT3 * 5; + atoms->pdbinfo[j2].bfac += drs[i].violT3 * 5; } } dump_viol(log, dd.nres, drs, FALSE); fprintf(log, "+++ Sorted by linear averaged violations: +++\n"); - std::sort(drs, drs + dd.nres, [](const t_dr_stats &a, const t_dr_stats &b) - {return a.viol > b.viol; }); //Reverse sort + std::sort(drs, drs + dd.nres, + [](const t_dr_stats& a, const t_dr_stats& b) { return a.viol > b.viol; }); // Reverse sort dump_viol(log, dd.nres, drs, TRUE); dump_dump(log, dd.nres, drs); @@ -398,15 +397,19 @@ static void dump_stats(FILE *log, int nsteps, sfree(drs); } -static void dump_clust_stats(FILE *fp, - const t_disresdata &dd, - const t_ilist *disres, - t_iparams ip[], t_blocka *clust, t_dr_result dr[], - char *clust_name[], int isize, int index[]) +static void dump_clust_stats(FILE* fp, + const t_disresdata& dd, + const t_ilist* disres, + t_iparams ip[], + t_blocka* clust, + t_dr_result dr[], + char* clust_name[], + int isize, + int index[]) { int k, nra, mmm = 0; double sumV, maxV, sumVT3, sumVT6, maxVT3, maxVT6; - t_dr_stats *drs; + t_dr_stats* drs; fprintf(fp, "\n"); fprintf(fp, "++++++++++++++ STATISTICS ++++++++++++++++++++++\n"); @@ -420,51 +423,51 @@ static void dump_clust_stats(FILE *fp, { continue; } - if (dr[k].nframes != (clust->index[k+1]-clust->index[k])) + if (dr[k].nframes != (clust->index[k + 1] - clust->index[k])) { - gmx_fatal(FARGS, "Inconsistency in cluster %s.\n" + gmx_fatal(FARGS, + "Inconsistency in cluster %s.\n" "Found %d frames in trajectory rather than the expected %d\n", - clust_name[k], dr[k].nframes, - clust->index[k+1]-clust->index[k]); + clust_name[k], dr[k].nframes, clust->index[k + 1] - clust->index[k]); } if (!clust_name[k]) { gmx_fatal(FARGS, "Inconsistency with cluster %d. Invalid name", k); } - nra = interaction_function[F_DISRES].nratoms+1; - sumV = sumVT3 = sumVT6 = maxV = maxVT3 = maxVT6 = 0; + nra = interaction_function[F_DISRES].nratoms + 1; + sumV = sumVT3 = sumVT6 = maxV = maxVT3 = maxVT6 = 0; // Use a map to process each restraint only once while looping over all pairs std::unordered_map restraintHasBeenProcessed; for (int j = 0; j < dd.nres; j += nra) { // Note that the restraint i can be used by multiple pairs - const int i = disres->iatoms[j] - dd.type_min; + const int i = disres->iatoms[j] - dd.type_min; if (restraintHasBeenProcessed[i]) { continue; } - drs[i].label = ip[disres->iatoms[j]].disres.label; - drs[i].bCore = is_core(drs[i].label, isize, index); - drs[i].up1 = ip[disres->iatoms[j]].disres.up1; - drs[i].r = dr[k].aver1[i]/dr[k].nframes; + drs[i].label = ip[disres->iatoms[j]].disres.label; + drs[i].bCore = is_core(drs[i].label, isize, index); + drs[i].up1 = ip[disres->iatoms[j]].disres.up1; + drs[i].r = dr[k].aver1[i] / dr[k].nframes; if ((dr[k].aver_3[i] <= 0) || !std::isfinite(dr[k].aver_3[i])) { gmx_fatal(FARGS, "dr[%d].aver_3[%d] = %f", k, i, dr[k].aver_3[i]); } - drs[i].rT3 = gmx::invcbrt(dr[k].aver_3[i]/dr[k].nframes); - drs[i].rT6 = gmx::invsixthroot(dr[k].aver_6[i]/dr[k].nframes); - drs[i].viol = std::max(0.0, static_cast(drs[i].r-drs[i].up1)); - drs[i].violT3 = std::max(0.0, static_cast(drs[i].rT3-drs[i].up1)); - drs[i].violT6 = std::max(0.0, static_cast(drs[i].rT6-drs[i].up1)); - sumV += drs[i].viol; - sumVT3 += drs[i].violT3; - sumVT6 += drs[i].violT6; - maxV = std::max(maxV, static_cast(drs[i].viol)); - maxVT3 = std::max(maxVT3, static_cast(drs[i].violT3)); - maxVT6 = std::max(maxVT6, static_cast(drs[i].violT6)); + drs[i].rT3 = gmx::invcbrt(dr[k].aver_3[i] / dr[k].nframes); + drs[i].rT6 = gmx::invsixthroot(dr[k].aver_6[i] / dr[k].nframes); + drs[i].viol = std::max(0.0, static_cast(drs[i].r - drs[i].up1)); + drs[i].violT3 = std::max(0.0, static_cast(drs[i].rT3 - drs[i].up1)); + drs[i].violT6 = std::max(0.0, static_cast(drs[i].rT6 - drs[i].up1)); + sumV += drs[i].viol; + sumVT3 += drs[i].violT3; + sumVT6 += drs[i].violT6; + maxV = std::max(maxV, static_cast(drs[i].viol)); + maxVT3 = std::max(maxVT3, static_cast(drs[i].violT3)); + maxVT6 = std::max(maxVT6, static_cast(drs[i].violT6)); // We have processed restraint i, mark it as such restraintHasBeenProcessed[i] = true; @@ -473,21 +476,19 @@ static void dump_clust_stats(FILE *fp, { mmm++; } - fprintf(fp, "%-10s%6d%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", - clust_name[k], + fprintf(fp, "%-10s%6d%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", clust_name[k], dr[k].nframes, sumV, maxV, sumVT3, maxVT3, sumVT6, maxVT6); - } fflush(fp); sfree(drs); } -static void init_dr_res(t_dr_result *dr, int ndr) +static void init_dr_res(t_dr_result* dr, int ndr) { - snew(dr->aver1, ndr+1); - snew(dr->aver2, ndr+1); - snew(dr->aver_3, ndr+1); - snew(dr->aver_6, ndr+1); + snew(dr->aver1, ndr + 1); + snew(dr->aver2, ndr + 1); + snew(dr->aver_3, ndr + 1); + snew(dr->aver_6, ndr + 1); dr->nv = 0; dr->nframes = 0; dr->sumv = 0; @@ -495,18 +496,24 @@ static void init_dr_res(t_dr_result *dr, int ndr) dr->averv = 0; } -static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, - int nsteps, t_idef *idef, const gmx_mtop_t *mtop, - real max_dr, int nlevels, gmx_bool bThird) +static void dump_disre_matrix(const char* fn, + t_dr_result* dr, + int ndr, + int nsteps, + t_idef* idef, + const gmx_mtop_t* mtop, + real max_dr, + int nlevels, + gmx_bool bThird) { - FILE *fp; - int *resnr; - int n_res, a_offset, mol, a; - int i, j, nra, nratoms, tp, ri, rj, index, nlabel, label; - int ai, aj, *ptr; - real **matrix, *t_res, hi, *w_dr, rav, rviol; - t_rgb rlo = { 1, 1, 1 }; - t_rgb rhi = { 0, 0, 0 }; + FILE* fp; + int* resnr; + int n_res, a_offset, mol, a; + int i, j, nra, nratoms, tp, ri, rj, index, nlabel, label; + int ai, aj, *ptr; + real **matrix, *t_res, hi, *w_dr, rav, rviol; + t_rgb rlo = { 1, 1, 1 }; + t_rgb rhi = { 0, 0, 0 }; if (fn == nullptr) { return; @@ -515,16 +522,16 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, snew(resnr, mtop->natoms); n_res = 0; a_offset = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const t_atoms &atoms = mtop->moltype[molb.type].atoms; + const t_atoms& atoms = mtop->moltype[molb.type].atoms; for (mol = 0; mol < molb.nmol; mol++) { for (a = 0; a < atoms.nr; a++) { resnr[a_offset + a] = n_res + atoms.atom[a].resind; } - n_res += atoms.nres; + n_res += atoms.nres; a_offset += atoms.nr; } } @@ -532,7 +539,7 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, snew(t_res, n_res); for (i = 0; (i < n_res); i++) { - t_res[i] = i+1; + t_res[i] = i + 1; } snew(matrix, n_res); for (i = 0; (i < n_res); i++) @@ -540,21 +547,21 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, snew(matrix[i], n_res); } nratoms = interaction_function[F_DISRES].nratoms; - nra = (idef->il[F_DISRES].nr/(nratoms+1)); - snew(ptr, nra+1); - index = 0; - nlabel = 0; - ptr[0] = 0; + nra = (idef->il[F_DISRES].nr / (nratoms + 1)); + snew(ptr, nra + 1); + index = 0; + nlabel = 0; + ptr[0] = 0; snew(w_dr, ndr); - for (i = 0; (i < idef->il[F_DISRES].nr); i += nratoms+1) + for (i = 0; (i < idef->il[F_DISRES].nr); i += nratoms + 1) { - tp = idef->il[F_DISRES].iatoms[i]; - label = idef->iparams[tp].disres.label; + tp = idef->il[F_DISRES].iatoms[i]; + label = idef->iparams[tp].disres.label; if (label != index) { /* Set index pointer */ - ptr[index+1] = i; + ptr[index + 1] = i; if (nlabel <= 0) { gmx_fatal(FARGS, "nlabel is %d, label = %d", nlabel, label); @@ -564,7 +571,7 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, gmx_fatal(FARGS, "ndr = %d, index = %d", ndr, index); } /* Update the weight */ - w_dr[index] = 1.0/nlabel; + w_dr[index] = 1.0 / nlabel; index = label; nlabel = 1; } @@ -577,31 +584,31 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, hi = 0; for (i = 0; (i < ndr); i++) { - for (j = ptr[i]; (j < ptr[i+1]); j += nratoms+1) + for (j = ptr[i]; (j < ptr[i + 1]); j += nratoms + 1) { - tp = idef->il[F_DISRES].iatoms[j]; - ai = idef->il[F_DISRES].iatoms[j+1]; - aj = idef->il[F_DISRES].iatoms[j+2]; + tp = idef->il[F_DISRES].iatoms[j]; + ai = idef->il[F_DISRES].iatoms[j + 1]; + aj = idef->il[F_DISRES].iatoms[j + 2]; ri = resnr[ai]; rj = resnr[aj]; if (bThird) { - rav = gmx::invcbrt(dr->aver_3[i]/nsteps); + rav = gmx::invcbrt(dr->aver_3[i] / nsteps); } else { - rav = dr->aver1[i]/nsteps; + rav = dr->aver1[i] / nsteps; } if (debug) { fprintf(debug, "DR %d, atoms %d, %d, distance %g\n", i, ai, aj, rav); } - rviol = std::max(0.0_real, rav-idef->iparams[tp].disres.up1); - matrix[ri][rj] += w_dr[i]*rviol; - matrix[rj][ri] += w_dr[i]*rviol; - hi = std::max(hi, matrix[ri][rj]); - hi = std::max(hi, matrix[rj][ri]); + rviol = std::max(0.0_real, rav - idef->iparams[tp].disres.up1); + matrix[ri][rj] += w_dr[i] * rviol; + matrix[rj][ri] += w_dr[i] * rviol; + hi = std::max(hi, matrix[ri][rj]); + hi = std::max(hi, matrix[rj][ri]); } } @@ -611,20 +618,22 @@ static void dump_disre_matrix(const char *fn, t_dr_result *dr, int ndr, { if (hi > max_dr) { - printf("Warning: the maxdr that you have specified (%g) is smaller than\nthe largest value in your simulation (%g)\n", max_dr, hi); + printf("Warning: the maxdr that you have specified (%g) is smaller than\nthe largest " + "value in your simulation (%g)\n", + max_dr, hi); } hi = max_dr; } printf("Highest level in the matrix will be %g\n", hi); fp = gmx_ffopen(fn, "w"); - write_xpm(fp, 0, "Distance Violations", " (nm)", "Residue", "Residue", - n_res, n_res, t_res, t_res, matrix, 0, hi, rlo, rhi, &nlevels); + write_xpm(fp, 0, "Distance Violations", " (nm)", "Residue", "Residue", n_res, n_res, t_res, + t_res, matrix, 0, hi, rlo, rhi, &nlevels); gmx_ffclose(fp); } -int gmx_disre(int argc, char *argv[]) +int gmx_disre(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes violations of distance restraints.", "The program always", "computes the instantaneous violations rather than time-averaged,", @@ -641,63 +650,64 @@ int gmx_disre(int argc, char *argv[]) "the program will compute average violations using the third power", "averaging algorithm and print them in the log file." }; - static int ntop = 0; - static int nlevels = 20; - static real max_dr = 0; - static gmx_bool bThird = TRUE; - t_pargs pa[] = { - { "-ntop", FALSE, etINT, {&ntop}, + static int ntop = 0; + static int nlevels = 20; + static real max_dr = 0; + static gmx_bool bThird = TRUE; + t_pargs pa[] = { + { "-ntop", + FALSE, + etINT, + { &ntop }, "Number of large violations that are stored in the log file every step" }, - { "-maxdr", FALSE, etREAL, {&max_dr}, - "Maximum distance violation in matrix output. If less than or equal to 0 the maximum will be determined by the data." }, - { "-nlevels", FALSE, etINT, {&nlevels}, - "Number of levels in the matrix output" }, - { "-third", FALSE, etBOOL, {&bThird}, + { "-maxdr", + FALSE, + etREAL, + { &max_dr }, + "Maximum distance violation in matrix output. If less than or equal to 0 the " + "maximum will be determined by the data." }, + { "-nlevels", FALSE, etINT, { &nlevels }, "Number of levels in the matrix output" }, + { "-third", + FALSE, + etBOOL, + { &bThird }, "Use inverse third power averaging or linear for matrix output" } }; - FILE *out = nullptr, *aver = nullptr, *numv = nullptr, *maxxv = nullptr, *xvg = nullptr; + FILE *out = nullptr, *aver = nullptr, *numv = nullptr, *maxxv = nullptr, *xvg = nullptr; gmx_localtop_t top; t_fcdata fcd; - t_graph *g; + t_graph* g; int i, j, kkk; - t_trxstatus *status; + t_trxstatus* status; real t; - rvec *x, *xav = nullptr; - rvec4 *f; + rvec * x, *xav = nullptr; + rvec4* f; matrix box; gmx_bool bPDB; int isize; - int *index = nullptr, *ind_fit = nullptr; - char *grpname; - t_cluster_ndx *clust = nullptr; + int * index = nullptr, *ind_fit = nullptr; + char* grpname; + t_cluster_ndx* clust = nullptr; t_dr_result dr, *dr_clust = nullptr; - char **leg; - real *vvindex = nullptr, *w_rls = nullptr; + char** leg; + real * vvindex = nullptr, *w_rls = nullptr; t_pbc pbc, *pbc_null; int my_clust; - FILE *fplog; - gmx_output_env_t *oenv; + FILE* fplog; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efXVG, "-ds", "drsum", ffWRITE }, - { efXVG, "-da", "draver", ffWRITE }, - { efXVG, "-dn", "drnum", ffWRITE }, - { efXVG, "-dm", "drmax", ffWRITE }, - { efXVG, "-dr", "restr", ffWRITE }, - { efLOG, "-l", "disres", ffWRITE }, - { efNDX, nullptr, "viol", ffOPTRD }, - { efPDB, "-q", "viol", ffOPTWR }, - { efNDX, "-c", "clust", ffOPTRD }, - { efXPM, "-x", "matrix", ffOPTWR } - }; + t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, + { efXVG, "-ds", "drsum", ffWRITE }, { efXVG, "-da", "draver", ffWRITE }, + { efXVG, "-dn", "drnum", ffWRITE }, { efXVG, "-dm", "drmax", ffWRITE }, + { efXVG, "-dr", "restr", ffWRITE }, { efLOG, "-l", "disres", ffWRITE }, + { efNDX, nullptr, "viol", ffOPTRD }, { efPDB, "-q", "viol", ffOPTWR }, + { efNDX, "-c", "clust", ffOPTRD }, { efXPM, "-x", "matrix", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -709,13 +719,13 @@ int gmx_disre(int argc, char *argv[]) init5(ntop); } - t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec irInstance; + t_inputrec* ir = &irInstance; gmx::TopologyInformation topInfo; topInfo.fillFromInputFile(ftp2fn(efTPR, NFILE, fnm)); - int ntopatoms = topInfo.mtop()->natoms; - AtomsDataPtr atoms; + int ntopatoms = topInfo.mtop()->natoms; + AtomsDataPtr atoms; bPDB = opt2bSet("-q", NFILE, fnm); if (bPDB) { @@ -758,8 +768,7 @@ int gmx_disre(int argc, char *argv[]) /* TODO: Nothing is written to this file if -c is provided, but it is * still opened... */ rd_index(ftp2fn(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); - xvg = xvgropen(opt2fn("-dr", NFILE, fnm), "Individual Restraints", "Time (ps)", - "nm", oenv); + xvg = xvgropen(opt2fn("-dr", NFILE, fnm), "Individual Restraints", "Time (ps)", "nm", oenv); snew(vvindex, isize); snew(leg, isize); for (i = 0; (i < isize); i++) @@ -779,13 +788,13 @@ int gmx_disre(int argc, char *argv[]) init_disres(fplog, topInfo.mtop(), ir, nullptr, nullptr, &fcd, nullptr, FALSE); int natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); - snew(f, 5*natoms); + snew(f, 5 * natoms); init_dr_res(&dr, fcd.disres.nres); if (opt2bSet("-c", NFILE, fnm)) { clust = cluster_index(fplog, opt2fn("-c", NFILE, fnm)); - snew(dr_clust, clust->clust->nr+1); + snew(dr_clust, clust->clust->nr + 1); for (i = 0; (i <= clust->clust->nr); i++) { init_dr_res(&dr_clust[i], fcd.disres.nres); @@ -793,14 +802,10 @@ int gmx_disre(int argc, char *argv[]) } else { - out = xvgropen(opt2fn("-ds", NFILE, fnm), - "Sum of Violations", "Time (ps)", "nm", oenv); - aver = xvgropen(opt2fn("-da", NFILE, fnm), - "Average Violation", "Time (ps)", "nm", oenv); - numv = xvgropen(opt2fn("-dn", NFILE, fnm), - "# Violations", "Time (ps)", "#", oenv); - maxxv = xvgropen(opt2fn("-dm", NFILE, fnm), - "Largest Violation", "Time (ps)", "nm", oenv); + out = xvgropen(opt2fn("-ds", NFILE, fnm), "Sum of Violations", "Time (ps)", "nm", oenv); + aver = xvgropen(opt2fn("-da", NFILE, fnm), "Average Violation", "Time (ps)", "nm", oenv); + numv = xvgropen(opt2fn("-dn", NFILE, fnm), "# Violations", "Time (ps)", "#", oenv); + maxxv = xvgropen(opt2fn("-dm", NFILE, fnm), "Largest Violation", "Time (ps)", "nm", oenv); } auto mdAtoms = gmx::makeMDAtoms(fplog, *topInfo.mtop(), *ir, false); @@ -830,19 +835,20 @@ int gmx_disre(int argc, char *argv[]) { if (j > clust->maxframe) { - gmx_fatal(FARGS, "There are more frames in the trajectory than in the cluster index file. t = %8f\n", t); + gmx_fatal(FARGS, + "There are more frames in the trajectory than in the cluster index file. " + "t = %8f\n", + t); } my_clust = clust->inv_clust[j]; range_check(my_clust, 0, clust->clust->nr); - check_viol(fplog, &(top.idef.il[F_DISRES]), - top.idef.iparams, - x, f, pbc_null, g, dr_clust, my_clust, isize, index, vvindex, &fcd); + check_viol(fplog, &(top.idef.il[F_DISRES]), top.idef.iparams, x, f, pbc_null, g, + dr_clust, my_clust, isize, index, vvindex, &fcd); } else { - check_viol(fplog, &(top.idef.il[F_DISRES]), - top.idef.iparams, - x, f, pbc_null, g, &dr, 0, isize, index, vvindex, &fcd); + check_viol(fplog, &(top.idef.il[F_DISRES]), top.idef.iparams, x, f, pbc_null, g, &dr, 0, + isize, index, vvindex, &fcd); } if (bPDB) { @@ -870,14 +876,13 @@ int gmx_disre(int argc, char *argv[]) } fprintf(xvg, "\n"); } - fprintf(out, "%10g %10g\n", t, dr.sumv); + fprintf(out, "%10g %10g\n", t, dr.sumv); fprintf(aver, "%10g %10g\n", t, dr.averv); fprintf(maxxv, "%10g %10g\n", t, dr.maxv); fprintf(numv, "%10g %10d\n", t, dr.nv); } j++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); if (ir->ePBC != epbcNONE) { @@ -886,23 +891,20 @@ int gmx_disre(int argc, char *argv[]) if (clust) { - dump_clust_stats(fplog, fcd.disres, &(top.idef.il[F_DISRES]), - top.idef.iparams, clust->clust, dr_clust, - clust->grpname, isize, index); + dump_clust_stats(fplog, fcd.disres, &(top.idef.il[F_DISRES]), top.idef.iparams, + clust->clust, dr_clust, clust->grpname, isize, index); } else { - dump_stats(fplog, j, fcd.disres, &(top.idef.il[F_DISRES]), - top.idef.iparams, &dr, isize, index, - bPDB ? atoms.get() : nullptr); + dump_stats(fplog, j, fcd.disres, &(top.idef.il[F_DISRES]), top.idef.iparams, &dr, isize, + index, bPDB ? atoms.get() : nullptr); if (bPDB) { - write_sto_conf(opt2fn("-q", NFILE, fnm), - "Coloured by average violation in Angstrom", + write_sto_conf(opt2fn("-q", NFILE, fnm), "Coloured by average violation in Angstrom", atoms.get(), xav, nullptr, ir->ePBC, box); } - dump_disre_matrix(opt2fn_null("-x", NFILE, fnm), &dr, fcd.disres.nres, - j, &top.idef, topInfo.mtop(), max_dr, nlevels, bThird); + dump_disre_matrix(opt2fn_null("-x", NFILE, fnm), &dr, fcd.disres.nres, j, &top.idef, + topInfo.mtop(), max_dr, nlevels, bThird); xvgrclose(out); xvgrclose(aver); xvgrclose(numv); diff --git a/src/gromacs/gmxana/gmx_do_dssp.cpp b/src/gromacs/gmxana/gmx_do_dssp.cpp index e0ab634dc4..1935ae1c15 100644 --- a/src/gromacs/gmxana/gmx_do_dssp.cpp +++ b/src/gromacs/gmxana/gmx_do_dssp.cpp @@ -65,11 +65,11 @@ #include "gromacs/utility/strdb.h" #if GMX_NATIVE_WINDOWS - #define NULL_DEVICE "nul" - #define popen _popen - #define pclose _pclose +# define NULL_DEVICE "nul" +# define popen _popen +# define pclose _pclose #else - #define NULL_DEVICE "/dev/null" +# define NULL_DEVICE "/dev/null" #endif struct DsspInputStrings @@ -84,28 +84,30 @@ static const char* prepareToRedirectStdout(bool bVerbose) return bVerbose ? "" : "2>" NULL_DEVICE; } -static void printDsspResult(char *dssp, const DsspInputStrings &strings, - const std::string &redirectionString) +static void printDsspResult(char* dssp, const DsspInputStrings& strings, const std::string& redirectionString) { #if HAVE_PIPES || GMX_NATIVE_WINDOWS - sprintf(dssp, "%s -i %s %s", - strings.dptr.c_str(), strings.pdbfile.c_str(), redirectionString.c_str()); + sprintf(dssp, "%s -i %s %s", strings.dptr.c_str(), strings.pdbfile.c_str(), redirectionString.c_str()); #else - sprintf(dssp, "%s -i %s -o %s > %s %s", - strings.dptr.c_str(), strings.pdbfile.c_str(), strings.tmpfile.c_str(), NULL_DEVICE, redirectionString.c_str()); + sprintf(dssp, "%s -i %s -o %s > %s %s", strings.dptr.c_str(), strings.pdbfile.c_str(), + strings.tmpfile.c_str(), NULL_DEVICE, redirectionString.c_str()); #endif } -static int strip_dssp(FILE *tapeout, int nres, - const gmx_bool bPhobres[], real t, - real *acc, FILE *fTArea, - t_matrix *mat, int average_area[], - const gmx_output_env_t *oenv) +static int strip_dssp(FILE* tapeout, + int nres, + const gmx_bool bPhobres[], + real t, + real* acc, + FILE* fTArea, + t_matrix* mat, + int average_area[], + const gmx_output_env_t* oenv) { static gmx_bool bFirst = TRUE; - static char *ssbuf; - char buf[STRLEN+1]; + static char* ssbuf; + char buf[STRLEN + 1]; char SSTP; int nr, iacc, nresidues; int naccf, naccb; /* Count hydrophobic and hydrophilic residues */ @@ -116,8 +118,7 @@ static int strip_dssp(FILE *tapeout, int nres, do { fgets2(buf, STRLEN, tapeout); - } - while (std::strstr(buf, "KAPPA") == nullptr); + } while (std::strstr(buf, "KAPPA") == nullptr); if (bFirst) { /* Since we also have empty lines in the dssp output (temp) file, @@ -126,18 +127,18 @@ static int strip_dssp(FILE *tapeout, int nres, * we allocate 2*nres-1, since for each chain there is a * separating line in the temp file. (At most each residue * could have been defined as a separate chain.) */ - snew(ssbuf, 2*nres-1); + snew(ssbuf, 2 * nres - 1); } - iaccb = iaccf = 0; - nresidues = 0; - naccf = 0; - naccb = 0; + iaccb = iaccf = 0; + nresidues = 0; + naccf = 0; + naccb = 0; for (nr = 0; (fgets2(buf, STRLEN, tapeout) != nullptr); nr++) { if (buf[13] == '!') /* Chain separator line has '!' at pos. 13 */ { - SSTP = '='; /* Chain separator sign '=' */ + SSTP = '='; /* Chain separator sign '=' */ } else { @@ -174,7 +175,8 @@ static int strip_dssp(FILE *tapeout, int nres, { if (nullptr != acc) { - fprintf(stderr, "%d residues were classified as hydrophobic and %d as hydrophilic.\n", naccb, naccf); + fprintf(stderr, "%d residues were classified as hydrophobic and %d as hydrophilic.\n", + naccb, naccf); } mat->title = "Secondary structure"; @@ -187,21 +189,21 @@ static int strip_dssp(FILE *tapeout, int nres, std::iota(mat->axis_y.begin(), mat->axis_y.end(), 1); mat->axis_x.resize(0); mat->matrix.resize(0, 0); - bFirst = false; + bFirst = false; } mat->axis_x.push_back(t); mat->matrix.resize(mat->matrix.extent(0), nr); - mat->nx = mat->matrix.extent(0); + mat->nx = mat->matrix.extent(0); auto columnIndex = mat->nx - 1; for (int i = 0; i < nr; i++) { - t_xpmelmt c = {ssbuf[i], 0}; + t_xpmelmt c = { ssbuf[i], 0 }; mat->matrix(columnIndex, i) = std::max(static_cast(0), searchcmap(mat->map, c)); } if (fTArea) { - fprintf(fTArea, "%10g %10g %10g\n", t, 0.01*iaccb, 0.01*iaccf); + fprintf(fTArea, "%10g %10g %10g\n", t, 0.01 * iaccb, 0.01 * iaccf); } /* Return the number of lines found in the dssp file (i.e. number @@ -210,14 +212,14 @@ static int strip_dssp(FILE *tapeout, int nres, return nr; } -static gmx_bool *bPhobics(t_atoms *atoms) +static gmx_bool* bPhobics(t_atoms* atoms) { - int j, i, nb; - char **cb; - gmx_bool *bb; - int n_surf; - char surffn[] = "surface.dat"; - char **surf_res, **surf_lines; + int j, i, nb; + char** cb; + gmx_bool* bb; + int n_surf; + char surffn[] = "surface.dat"; + char ** surf_res, **surf_lines; nb = get_lines("phbres.dat", &cb); @@ -234,7 +236,7 @@ static gmx_bool *bPhobics(t_atoms *atoms) for (i = 0, j = 0; (i < atoms->nres); i++) { - if (-1 != search_str(n_surf, surf_res, *atoms->resinfo[i].name) ) + if (-1 != search_str(n_surf, surf_res, *atoms->resinfo[i].name)) { bb[j++] = (-1 != search_str(nb, cb, *atoms->resinfo[i].name)); } @@ -242,7 +244,8 @@ static gmx_bool *bPhobics(t_atoms *atoms) if (i != j) { - fprintf(stderr, "Not all residues were recognized (%d from %d), the result may be inaccurate!\n", j, i); + fprintf(stderr, + "Not all residues were recognized (%d from %d), the result may be inaccurate!\n", j, i); } for (i = 0; (i < n_surf); i++) @@ -254,11 +257,11 @@ static gmx_bool *bPhobics(t_atoms *atoms) return bb; } -static void check_oo(t_atoms *atoms) +static void check_oo(t_atoms* atoms) { - char *OOO; + char* OOO; - int i; + int i; OOO = gmx_strdup("O"); @@ -279,14 +282,13 @@ static void check_oo(t_atoms *atoms) } } -static void norm_acc(t_atoms *atoms, int nres, - const real av_area[], real norm_av_area[]) +static void norm_acc(t_atoms* atoms, int nres, const real av_area[], real norm_av_area[]) { - int i, n, n_surf; + int i, n, n_surf; char surffn[] = "surface.dat"; - char **surf_res, **surf_lines; - double *surf; + char ** surf_res, **surf_lines; + double* surf; n_surf = get_lines(surffn, &surf_lines); snew(surf, n_surf); @@ -312,7 +314,7 @@ static void norm_acc(t_atoms *atoms, int nres, } } -static void prune_ss_legend(t_matrix *mat) +static void prune_ss_legend(t_matrix* mat) { std::vector isPresent(mat->map.size()); std::vector newnum(mat->map.size()); @@ -348,12 +350,12 @@ static void prune_ss_legend(t_matrix *mat) } } -static void write_sas_mat(const char *fn, real **accr, int nframe, int nres, t_matrix *mat) +static void write_sas_mat(const char* fn, real** accr, int nframe, int nres, t_matrix* mat) { real lo, hi; int i, j, nlev; - t_rgb rlo = {1, 1, 1}, rhi = {0, 0, 0}; - FILE *fp; + t_rgb rlo = { 1, 1, 1 }, rhi = { 0, 0, 0 }; + FILE* fp; if (fn) { @@ -367,19 +369,17 @@ static void write_sas_mat(const char *fn, real **accr, int nframe, int nres, t_m } } fp = gmx_ffopen(fn, "w"); - nlev = static_cast(hi-lo+1); - write_xpm(fp, 0, "Solvent Accessible Surface", "Surface (A^2)", - "Time", "Residue Index", nframe, nres, - mat->axis_x.data(), mat->axis_y.data(), accr, lo, hi, rlo, rhi, &nlev); + nlev = static_cast(hi - lo + 1); + write_xpm(fp, 0, "Solvent Accessible Surface", "Surface (A^2)", "Time", "Residue Index", + nframe, nres, mat->axis_x.data(), mat->axis_y.data(), accr, lo, hi, rlo, rhi, &nlev); gmx_ffclose(fp); } } -static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string, - const gmx_output_env_t *oenv) +static void analyse_ss(const char* outfile, t_matrix* mat, const char* ss_string, const gmx_output_env_t* oenv) { - FILE *fp; - int ss_count, total_count; + FILE* fp; + int ss_count, total_count; gmx::ArrayRef map = mat->map; std::vector count(map.size()); @@ -387,15 +387,15 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string // This copying would not be necessary if xvgr_legend could take a // view of string views std::vector leg; - leg.reserve(map.size()+1); + leg.reserve(map.size() + 1); leg.emplace_back("Structure"); - for (const auto &m : map) + for (const auto& m : map) { leg.emplace_back(m.desc); } - fp = xvgropen(outfile, "Secondary Structure", - output_env_get_xvgr_tlabel(oenv), "Number of Residues", oenv); + fp = xvgropen(outfile, "Secondary Structure", output_env_get_xvgr_tlabel(oenv), + "Number of Residues", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"Structure = "); @@ -406,7 +406,7 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string { fprintf(fp, " + "); } - for (const auto &m : map) + for (const auto& m : map) { if (ss_string[s] == m.code.c1) { @@ -421,7 +421,7 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string for (int f = 0; f < mat->nx; f++) { ss_count = 0; - for (auto &c : count) + for (auto& c : count) { c = 0; } @@ -434,12 +434,12 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string { if (std::strchr(ss_string, map[s].code.c1)) { - ss_count += count[s]; + ss_count += count[s]; total_count += count[s]; } } fprintf(fp, "%8g %5d", mat->axis_x[f], ss_count); - for (const auto &c : count) + for (const auto& c : count) { fprintf(fp, " %5d", c); } @@ -447,7 +447,7 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string } /* now print column totals */ fprintf(fp, "%-8s %5d", "# Totals", total_count); - for (const auto &t : total) + for (const auto& t : total) { fprintf(fp, " %5d", t); } @@ -455,7 +455,7 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string /* now print probabilities */ fprintf(fp, "%-8s %5.2f", "# SS pr.", total_count / static_cast(mat->nx * mat->ny)); - for (const auto &t : total) + for (const auto& t : total) { fprintf(fp, " %5.2f", t / static_cast(mat->nx * mat->ny)); } @@ -464,9 +464,9 @@ static void analyse_ss(const char *outfile, t_matrix *mat, const char *ss_string xvgrclose(fp); } -int gmx_do_dssp(int argc, char *argv[]) +int gmx_do_dssp(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] ", "reads a trajectory file and computes the secondary structure for", "each time frame ", @@ -503,60 +503,55 @@ int gmx_do_dssp(int argc, char *argv[]) "function of secondary structure type." }; static gmx_bool bVerbose; - static const char *ss_string = "HEBT"; + static const char* ss_string = "HEBT"; static int dsspVersion = 2; t_pargs pa[] = { - { "-v", FALSE, etBOOL, {&bVerbose}, - "HIDDENGenerate miles of useless information" }, - { "-sss", FALSE, etSTR, {&ss_string}, - "Secondary structures for structure count"}, - { "-ver", FALSE, etINT, {&dsspVersion}, - "DSSP major version. Syntax changed with version 2"} + { "-v", FALSE, etBOOL, { &bVerbose }, "HIDDENGenerate miles of useless information" }, + { "-sss", FALSE, etSTR, { &ss_string }, "Secondary structures for structure count" }, + { "-ver", + FALSE, + etINT, + { &dsspVersion }, + "DSSP major version. Syntax changed with version 2" } }; - t_trxstatus *status; - FILE *tapein, *tapeout; - FILE *ss, *acc, *fTArea, *tmpf; - const char *fnSCount, *fnArea, *fnTArea, *fnAArea; - const char *leg[] = { "Phobic", "Phylic" }; - t_topology top; - int ePBC; - t_atoms *atoms; - t_matrix mat; - int nres, nr0, naccr, nres_plus_separators; - gmx_bool *bPhbres, bDoAccSurf; - real t; - int natoms, nframe = 0; - matrix box = {{0}}; - int gnx; - char *grpnm; - int *index; - rvec *xp, *x; - int *average_area; - real **accr, *accr_ptr = nullptr, *av_area, *norm_av_area; - char pdbfile[32], tmpfile[32]; - char dssp[256]; - const char *dptr; - gmx_output_env_t *oenv; - gmx_rmpbc_t gpbc = nullptr; - - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-ssdump", "ssdump", ffOPTWR }, - { efMAP, "-map", "ss", ffLIBRD }, - { efXPM, "-o", "ss", ffWRITE }, - { efXVG, "-sc", "scount", ffWRITE }, - { efXPM, "-a", "area", ffOPTWR }, - { efXVG, "-ta", "totarea", ffOPTWR }, - { efXVG, "-aa", "averarea", ffOPTWR } + t_trxstatus* status; + FILE * tapein, *tapeout; + FILE * ss, *acc, *fTArea, *tmpf; + const char * fnSCount, *fnArea, *fnTArea, *fnAArea; + const char* leg[] = { "Phobic", "Phylic" }; + t_topology top; + int ePBC; + t_atoms* atoms; + t_matrix mat; + int nres, nr0, naccr, nres_plus_separators; + gmx_bool * bPhbres, bDoAccSurf; + real t; + int natoms, nframe = 0; + matrix box = { { 0 } }; + int gnx; + char* grpnm; + int* index; + rvec * xp, *x; + int* average_area; + real ** accr, *accr_ptr = nullptr, *av_area, *norm_av_area; + char pdbfile[32], tmpfile[32]; + char dssp[256]; + const char* dptr; + gmx_output_env_t* oenv; + gmx_rmpbc_t gpbc = nullptr; + + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efDAT, "-ssdump", "ssdump", ffOPTWR }, + { efMAP, "-map", "ss", ffLIBRD }, { efXPM, "-o", "ss", ffWRITE }, + { efXVG, "-sc", "scount", ffWRITE }, { efXPM, "-a", "area", ffOPTWR }, + { efXVG, "-ta", "totarea", ffOPTWR }, { efXVG, "-aa", "averarea", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW | PCA_TIME_UNIT, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -616,10 +611,9 @@ int gmx_do_dssp(int argc, char *argv[]) } if (!gmx_fexist(dptr)) { - gmx_fatal(FARGS, "DSSP executable (%s) does not exist (use setenv DSSP)", - dptr); + gmx_fatal(FARGS, "DSSP executable (%s) does not exist (use setenv DSSP)", dptr); } - std::string redirectionString; + std::string redirectionString; redirectionString = prepareToRedirectStdout(bVerbose); DsspInputStrings dsspStrings; dsspStrings.dptr = dptr; @@ -629,7 +623,9 @@ int gmx_do_dssp(int argc, char *argv[]) { if (dsspVersion > 2) { - printf("\nWARNING: You use DSSP version %d, which is not explicitly\nsupported by do_dssp. Assuming version 2 syntax.\n\n", dsspVersion); + printf("\nWARNING: You use DSSP version %d, which is not explicitly\nsupported by " + "do_dssp. Assuming version 2 syntax.\n\n", + dsspVersion); } printDsspResult(dssp, dsspStrings, redirectionString); @@ -685,9 +681,9 @@ int gmx_do_dssp(int argc, char *argv[]) { naccr += 10; srenew(accr, naccr); - for (int i = naccr-10; i < naccr; i++) + for (int i = naccr - 10; i < naccr; i++) { - snew(accr[i], 2*atoms->nres-1); + snew(accr[i], 2 * atoms->nres - 1); } } gmx_rmpbc(gpbc, natoms, box, x); @@ -705,8 +701,10 @@ int gmx_do_dssp(int argc, char *argv[]) { remove(pdbfile); remove(tmpfile); - gmx_fatal(FARGS, "Failed to execute command: %s\n" - "Try specifying your dssp version with the -ver option.", dssp); + gmx_fatal(FARGS, + "Failed to execute command: %s\n" + "Try specifying your dssp version with the -ver option.", + dssp); } if (bDoAccSurf) { @@ -714,8 +712,8 @@ int gmx_do_dssp(int argc, char *argv[]) } /* strip_dssp returns the number of lines found in the dssp file, i.e. * the number of residues plus the separator lines */ - nres_plus_separators = strip_dssp(tapeout, nres, bPhbres, t, - accr_ptr, fTArea, &mat, average_area, oenv); + nres_plus_separators = + strip_dssp(tapeout, nres, bPhbres, t, accr_ptr, fTArea, &mat, average_area, oenv); #if HAVE_PIPES || GMX_NATIVE_WINDOWS pclose(tapeout); #else @@ -724,8 +722,7 @@ int gmx_do_dssp(int argc, char *argv[]) remove(tmpfile); remove(pdbfile); nframe++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); close_trx(status); if (fTArea) @@ -771,11 +768,10 @@ int gmx_do_dssp(int argc, char *argv[]) if (fnAArea) { - acc = xvgropen(fnAArea, "Average Accessible Area", - "Residue", "A\\S2", oenv); + acc = xvgropen(fnAArea, "Average Accessible Area", "Residue", "A\\S2", oenv); for (int i = 0; (i < nres); i++) { - fprintf(acc, "%5d %10g %10g\n", i+1, av_area[i], norm_av_area[i]); + fprintf(acc, "%5d %10g %10g\n", i + 1, av_area[i], norm_av_area[i]); } xvgrclose(acc); } diff --git a/src/gromacs/gmxana/gmx_dos.cpp b/src/gromacs/gmxana/gmx_dos.cpp index 602e11db34..344ad272ea 100644 --- a/src/gromacs/gmxana/gmx_dos.cpp +++ b/src/gromacs/gmxana/gmx_dos.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,16 +63,26 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -enum { - VACF, MVACF, DOS, DOS_SOLID, DOS_DIFF, DOS_CP, DOS_S, DOS_A, DOS_E, DOS_NR +enum +{ + VACF, + MVACF, + DOS, + DOS_SOLID, + DOS_DIFF, + DOS_CP, + DOS_S, + DOS_A, + DOS_E, + DOS_NR }; -static int calcMoleculesInIndexGroup(const t_block *mols, int natoms, const int *index, int nindex) +static int calcMoleculesInIndexGroup(const t_block* mols, int natoms, const int* index, int nindex) { - int i = 0; - int mol = 0; - int nMol = 0; - int j; + int i = 0; + int mol = 0; + int nMol = 0; + int j; while (i < nindex) { @@ -80,10 +91,10 @@ static int calcMoleculesInIndexGroup(const t_block *mols, int natoms, const int mol++; if (mol >= mols->nr) { - gmx_fatal(FARGS, "Atom index out of range: %d", index[i]+1); + gmx_fatal(FARGS, "Atom index out of range: %d", index[i] + 1); } } - for (j = mols->index[mol]; j < mols->index[mol+1]; j++) + for (j = mols->index[mol]; j < mols->index[mol + 1]; j++) { if (index[i] != j) { @@ -102,17 +113,14 @@ static int calcMoleculesInIndexGroup(const t_block *mols, int natoms, const int static double FD(double Delta, double f) { - return (2*std::pow(Delta, -4.5)*std::pow(f, 7.5) - - 6*std::pow(Delta, -3.0)*std::pow(f, 5.0) - - std::pow(Delta, -1.5)*std::pow(f, 3.5) + - 6*std::pow(Delta, -1.5)*std::pow(f, 2.5) + - 2*f - 2); + return (2 * std::pow(Delta, -4.5) * std::pow(f, 7.5) + - 6 * std::pow(Delta, -3.0) * std::pow(f, 5.0) - std::pow(Delta, -1.5) * std::pow(f, 3.5) + + 6 * std::pow(Delta, -1.5) * std::pow(f, 2.5) + 2 * f - 2); } static double YYY(double f, double y) { - return (2*gmx::power3(y*f) - gmx::square(f)*y*(1+6*y) + - (2+6*y)*f - 2); + return (2 * gmx::power3(y * f) - gmx::square(f) * y * (1 + 6 * y) + (2 + 6 * y) * f - 2); } static double calc_compress(double y) @@ -121,12 +129,10 @@ static double calc_compress(double y) { return 0; } - return ((1+y+gmx::square(y)-gmx::power3(y))/(gmx::power3(1-y))); + return ((1 + y + gmx::square(y) - gmx::power3(y)) / (gmx::power3(1 - y))); } -static double bisector(double Delta, double tol, - double ff0, double ff1, - double ff(double, double)) +static double bisector(double Delta, double tol, double ff0, double ff1, double ff(double, double)) { double fd, f, f0, f1; double tolmin = 1e-8; @@ -141,8 +147,8 @@ static double bisector(double Delta, double tol, do { - f = (f0+f1)*0.5; - fd = ff(Delta, f); + f = (f0 + f1) * 0.5; + fd = ff(Delta, f); if (fd < 0) { f0 = f; @@ -155,8 +161,7 @@ static double bisector(double Delta, double tol, { return f; } - } - while ((f1-f0) > tol); + } while ((f1 - f0) > tol); return f; } @@ -170,12 +175,11 @@ static double calc_y(double f, double Delta, double toler) { double y1, y2; - y1 = std::pow(f/Delta, 1.5); + y1 = std::pow(f / Delta, 1.5); y2 = bisector(f, toler, 0, 10000, YYY); - if (std::abs((y1-y2)/(y1+y2)) > 100*toler) + if (std::abs((y1 - y2) / (y1 + y2)) > 100 * toler) { - fprintf(stderr, "Inconsistency computing y: y1 = %f, y2 = %f, using y1.\n", - y1, y2); + fprintf(stderr, "Inconsistency computing y: y1 = %f, y2 = %f, using y1.\n", y1, y2); } return y1; @@ -183,14 +187,14 @@ static double calc_y(double f, double Delta, double toler) static double calc_Shs(double f, double y) { - double fy = f*y; + double fy = f * y; - return BOLTZ*(std::log(calc_compress(fy)) + fy*(3*fy-4)/gmx::square(1-fy)); + return BOLTZ * (std::log(calc_compress(fy)) + fy * (3 * fy - 4) / gmx::square(1 - fy)); } static real wCsolid(real nu, real beta) { - real bhn = beta*PLANCK*nu; + real bhn = beta * PLANCK * nu; real ebn, koko; if (bhn == 0) @@ -200,14 +204,14 @@ static real wCsolid(real nu, real beta) else { ebn = std::exp(bhn); - koko = gmx::square(1-ebn); - return gmx::square(bhn)*ebn/koko; + koko = gmx::square(1 - ebn); + return gmx::square(bhn) * ebn / koko; } } static real wSsolid(real nu, real beta) { - real bhn = beta*PLANCK*nu; + real bhn = beta * PLANCK * nu; if (bhn == 0) { @@ -215,13 +219,13 @@ static real wSsolid(real nu, real beta) } else { - return bhn/std::expm1(bhn) - std::log1p(-std::exp(-bhn)); + return bhn / std::expm1(bhn) - std::log1p(-std::exp(-bhn)); } } static real wAsolid(real nu, real beta) { - real bhn = beta*PLANCK*nu; + real bhn = beta * PLANCK * nu; if (bhn == 0) { @@ -229,13 +233,13 @@ static real wAsolid(real nu, real beta) } else { - return std::log((1-std::exp(-bhn))/(std::exp(-bhn/2))) - std::log(bhn); + return std::log((1 - std::exp(-bhn)) / (std::exp(-bhn / 2))) - std::log(bhn); } } static real wEsolid(real nu, real beta) { - real bhn = beta*PLANCK*nu; + real bhn = beta * PLANCK * nu; if (bhn == 0) { @@ -243,96 +247,100 @@ static real wEsolid(real nu, real beta) } else { - return bhn/2 + bhn/std::expm1(bhn)-1; + return bhn / 2 + bhn / std::expm1(bhn) - 1; } } -int gmx_dos(int argc, char *argv[]) +int gmx_dos(int argc, char* argv[]) { - const char *desc[] = { - "[THISMODULE] computes the Density of States from a simulations.", - "In order for this to be meaningful the velocities must be saved", - "in the trajecotry with sufficiently high frequency such as to cover", - "all vibrations. For flexible systems that would be around a few fs", - "between saving. Properties based on the DoS are printed on the", - "standard output.", - "Note that the density of states is calculated from the mass-weighted", - "autocorrelation, and by default only from the square of the real", - "component rather than absolute value. This means the shape can differ", - "substantially from the plain vibrational power spectrum you can", - "calculate with gmx velacc." + const char* desc[] = { "[THISMODULE] computes the Density of States from a simulations.", + "In order for this to be meaningful the velocities must be saved", + "in the trajecotry with sufficiently high frequency such as to cover", + "all vibrations. For flexible systems that would be around a few fs", + "between saving. Properties based on the DoS are printed on the", + "standard output.", + "Note that the density of states is calculated from the mass-weighted", + "autocorrelation, and by default only from the square of the real", + "component rather than absolute value. This means the shape can differ", + "substantially from the plain vibrational power spectrum you can", + "calculate with gmx velacc." }; + const char* bugs[] = { + "This program needs a lot of memory: total usage equals the number of atoms times " + "3 times number of frames times 4 (or 8 when run in double precision)." }; - const char *bugs[] = { - "This program needs a lot of memory: total usage equals the number of atoms times 3 times number of frames times 4 (or 8 when run in double precision)." - }; - FILE *fp, *fplog; - t_topology top; - int ePBC = -1; - t_trxframe fr; - matrix box; - int gnx; - real t0, t1; - t_trxstatus *status; - int nV, nframes, n_alloc, i, j, fftcode, Nmol, Natom; - double rho, dt, Vsum, V, tmass, dostot, dos2; - real **c1, **dos, mi, beta, bfac, *nu, *tt, stddev, c1j; - gmx_output_env_t *oenv; - gmx_fft_t fft; - double cP, DiffCoeff, Delta, f, y, z, sigHS, Shs, Sig, DoS0, recip_fac; - double wCdiff, wSdiff, wAdiff, wEdiff; - int grpNatoms; - int *index; - char *grpname; - double invNormalize; - gmx_bool normalizeAutocorrelation; - - static gmx_bool bVerbose = TRUE, bAbsolute = FALSE, bNormalizeDos = FALSE; - static gmx_bool bRecip = FALSE; - static real Temp = 298.15, toler = 1e-6; - int min_frames = 100; - - t_pargs pa[] = { - { "-v", FALSE, etBOOL, {&bVerbose}, - "Be loud and noisy." }, - { "-recip", FALSE, etBOOL, {&bRecip}, + FILE * fp, *fplog; + t_topology top; + int ePBC = -1; + t_trxframe fr; + matrix box; + int gnx; + real t0, t1; + t_trxstatus* status; + int nV, nframes, n_alloc, i, j, fftcode, Nmol, Natom; + double rho, dt, Vsum, V, tmass, dostot, dos2; + real ** c1, **dos, mi, beta, bfac, *nu, *tt, stddev, c1j; + gmx_output_env_t* oenv; + gmx_fft_t fft; + double cP, DiffCoeff, Delta, f, y, z, sigHS, Shs, Sig, DoS0, recip_fac; + double wCdiff, wSdiff, wAdiff, wEdiff; + int grpNatoms; + int* index; + char* grpname; + double invNormalize; + gmx_bool normalizeAutocorrelation; + + static gmx_bool bVerbose = TRUE, bAbsolute = FALSE, bNormalizeDos = FALSE; + static gmx_bool bRecip = FALSE; + static real Temp = 298.15, toler = 1e-6; + int min_frames = 100; + + t_pargs pa[] = { + { "-v", FALSE, etBOOL, { &bVerbose }, "Be loud and noisy." }, + { "-recip", + FALSE, + etBOOL, + { &bRecip }, "Use cm^-1 on X-axis instead of 1/ps for DoS plots." }, - { "-abs", FALSE, etBOOL, {&bAbsolute}, - "Use the absolute value of the Fourier transform of the VACF as the Density of States. Default is to use the real component only" }, - { "-normdos", FALSE, etBOOL, {&bNormalizeDos}, + { "-abs", + FALSE, + etBOOL, + { &bAbsolute }, + "Use the absolute value of the Fourier transform of the VACF as the Density of States. " + "Default is to use the real component only" }, + { "-normdos", + FALSE, + etBOOL, + { &bNormalizeDos }, "Normalize the DoS such that it adds up to 3N. This should usually not be necessary." }, - { "-T", FALSE, etREAL, {&Temp}, - "Temperature in the simulation" }, - { "-toler", FALSE, etREAL, {&toler}, + { "-T", FALSE, etREAL, { &Temp }, "Temperature in the simulation" }, + { "-toler", + FALSE, + etREAL, + { &toler }, "[HIDDEN]Tolerance when computing the fluidicity using bisection algorithm" } }; - t_filenm fnm[] = { - { efTRN, "-f", nullptr, ffREAD }, - { efTPR, "-s", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-vacf", "vacf", ffWRITE }, - { efXVG, "-mvacf", "mvacf", ffWRITE }, - { efXVG, "-dos", "dos", ffWRITE }, - { efLOG, "-g", "dos", ffWRITE }, + t_filenm fnm[] = { + { efTRN, "-f", nullptr, ffREAD }, { efTPR, "-s", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-vacf", "vacf", ffWRITE }, + { efXVG, "-mvacf", "mvacf", ffWRITE }, { efXVG, "-dos", "dos", ffWRITE }, + { efLOG, "-g", "dos", ffWRITE }, }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; - const char *DoSlegend[] = { - "DoS(v)", "DoS(v)[Solid]", "DoS(v)[Diff]" - }; + int npargs; + t_pargs* ppa; + const char* DoSlegend[] = { "DoS(v)", "DoS(v)[Solid]", "DoS(v)[Diff]" }; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, - asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { sfree(ppa); return 0; } - beta = 1/(Temp*BOLTZ); + beta = 1 / (Temp * BOLTZ); fplog = gmx_fio_fopen(ftp2fn(efLOG, NFILE, fnm), "w"); fprintf(fplog, "Doing density of states analysis based on trajectory.\n"); @@ -353,7 +361,7 @@ int gmx_dos(int argc, char *argv[]) Natom = grpNatoms; Nmol = calcMoleculesInIndexGroup(&top.mols, top.atoms.nr, index, grpNatoms); - gnx = Natom*DIM; + gnx = Natom * DIM; /* Correlation stuff */ snew(c1, gnx); @@ -373,8 +381,8 @@ int gmx_dos(int argc, char *argv[]) { if (fr.bBox) { - V = det(fr.box); - Vsum += V; + V = det(fr.box); + Vsum += V; nV++; } if (nframes >= n_alloc) @@ -387,32 +395,31 @@ int gmx_dos(int argc, char *argv[]) } for (i = 0; i < gnx; i += DIM) { - c1[i+XX][nframes] = fr.v[index[i/DIM]][XX]; - c1[i+YY][nframes] = fr.v[index[i/DIM]][YY]; - c1[i+ZZ][nframes] = fr.v[index[i/DIM]][ZZ]; + c1[i + XX][nframes] = fr.v[index[i / DIM]][XX]; + c1[i + YY][nframes] = fr.v[index[i / DIM]][YY]; + c1[i + ZZ][nframes] = fr.v[index[i / DIM]][ZZ]; } t1 = fr.time; nframes++; - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); close_trx(status); if (nframes < min_frames) { - gmx_fatal(FARGS, "You need at least %d frames in the trajectory and you only have %d.", min_frames, nframes); + gmx_fatal(FARGS, "You need at least %d frames in the trajectory and you only have %d.", + min_frames, nframes); } - dt = (t1-t0)/(nframes-1); + dt = (t1 - t0) / (nframes - 1); if (nV > 0) { - V = Vsum/nV; + V = Vsum / nV; } if (bVerbose) { - printf("Going to do %d fourier transforms of length %d. Hang on.\n", - gnx, nframes); + printf("Going to do %d fourier transforms of length %d. Hang on.\n", gnx, nframes); } /* Unfortunately the -normalize program option for the autocorrelation * function calculation is added as a hack with a static variable in the @@ -434,7 +441,7 @@ int gmx_dos(int argc, char *argv[]) snew(dos, DOS_NR); for (j = 0; (j < DOS_NR); j++) { - snew(dos[j], nframes+4); + snew(dos[j], nframes + 4); } if (bVerbose) @@ -443,24 +450,24 @@ int gmx_dos(int argc, char *argv[]) } for (i = 0; (i < gnx); i += DIM) { - mi = top.atoms.atom[index[i/DIM]].m; - for (j = 0; (j < nframes/2); j++) + mi = top.atoms.atom[index[i / DIM]].m; + for (j = 0; (j < nframes / 2); j++) { - c1j = (c1[i+XX][j] + c1[i+YY][j] + c1[i+ZZ][j]); - dos[VACF][j] += c1j/Natom; - dos[MVACF][j] += mi*c1j; + c1j = (c1[i + XX][j] + c1[i + YY][j] + c1[i + ZZ][j]); + dos[VACF][j] += c1j / Natom; + dos[MVACF][j] += mi * c1j; } } - fp = xvgropen(opt2fn("-vacf", NFILE, fnm), "Velocity autocorrelation function", - "Time (ps)", "C(t)", oenv); - snew(tt, nframes/2); + fp = xvgropen(opt2fn("-vacf", NFILE, fnm), "Velocity autocorrelation function", "Time (ps)", + "C(t)", oenv); + snew(tt, nframes / 2); - invNormalize = normalizeAutocorrelation ? 1.0/dos[VACF][0] : 1.0; + invNormalize = normalizeAutocorrelation ? 1.0 / dos[VACF][0] : 1.0; - for (j = 0; (j < nframes/2); j++) + for (j = 0; (j < nframes / 2); j++) { - tt[j] = j*dt; + tt[j] = j * dt; fprintf(fp, "%10g %10g\n", tt[j], dos[VACF][j] * invNormalize); } xvgrclose(fp); @@ -468,50 +475,48 @@ int gmx_dos(int argc, char *argv[]) fp = xvgropen(opt2fn("-mvacf", NFILE, fnm), "Mass-weighted velocity autocorrelation function", "Time (ps)", "C(t)", oenv); - invNormalize = normalizeAutocorrelation ? 1.0/dos[VACF][0] : 1.0; + invNormalize = normalizeAutocorrelation ? 1.0 / dos[VACF][0] : 1.0; - for (j = 0; (j < nframes/2); j++) + for (j = 0; (j < nframes / 2); j++) { fprintf(fp, "%10g %10g\n", tt[j], dos[MVACF][j] * invNormalize); } xvgrclose(fp); - if ((fftcode = gmx_fft_init_1d_real(&fft, nframes/2, - GMX_FFT_FLAG_NONE)) != 0) + if ((fftcode = gmx_fft_init_1d_real(&fft, nframes / 2, GMX_FFT_FLAG_NONE)) != 0) { gmx_fatal(FARGS, "gmx_fft_init_1d_real returned %d", fftcode); } - if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_REAL_TO_COMPLEX, - dos[MVACF], dos[DOS])) != 0) + if ((fftcode = gmx_fft_1d_real(fft, GMX_FFT_REAL_TO_COMPLEX, dos[MVACF], dos[DOS])) != 0) { gmx_fatal(FARGS, "gmx_fft_1d_real returned %d", fftcode); } /* First compute the DoS */ /* Magic factor of 8 included now. */ - bfac = 8*dt*beta/2; + bfac = 8 * dt * beta / 2; dos2 = 0; - snew(nu, nframes/4); - for (j = 0; (j < nframes/4); j++) + snew(nu, nframes / 4); + for (j = 0; (j < nframes / 4); j++) { - nu[j] = 2*j/(t1-t0); - dos2 += gmx::square(dos[DOS][2*j]) + gmx::square(dos[DOS][2*j+1]); + nu[j] = 2 * j / (t1 - t0); + dos2 += gmx::square(dos[DOS][2 * j]) + gmx::square(dos[DOS][2 * j + 1]); if (bAbsolute) { - dos[DOS][j] = bfac*std::hypot(dos[DOS][2*j], dos[DOS][2*j+1]); + dos[DOS][j] = bfac * std::hypot(dos[DOS][2 * j], dos[DOS][2 * j + 1]); } else { - dos[DOS][j] = bfac*dos[DOS][2*j]; + dos[DOS][j] = bfac * dos[DOS][2 * j]; } } /* Normalize it */ - dostot = evaluate_integral(nframes/4, nu, dos[DOS], nullptr, int{nframes/4}, &stddev); + dostot = evaluate_integral(nframes / 4, nu, dos[DOS], nullptr, int{ nframes / 4 }, &stddev); if (bNormalizeDos) { - for (j = 0; (j < nframes/4); j++) + for (j = 0; (j < nframes / 4); j++) { - dos[DOS][j] *= 3*Natom/dostot; + dos[DOS][j] *= 3 * Natom / dostot; } } @@ -519,15 +524,16 @@ int gmx_dos(int argc, char *argv[]) DoS0 = dos[DOS][0]; /* Note this eqn. is incorrect in Pascal2011a! */ - Delta = ((2*DoS0/(9*Natom))*std::sqrt(M_PI*BOLTZ*Temp*Natom/tmass)* - std::pow((Natom/V), 1.0/3.0)*std::pow(6.0/M_PI, 2.0/3.0)); + Delta = ((2 * DoS0 / (9 * Natom)) * std::sqrt(M_PI * BOLTZ * Temp * Natom / tmass) + * std::pow((Natom / V), 1.0 / 3.0) * std::pow(6.0 / M_PI, 2.0 / 3.0)); f = calc_fluidicity(Delta, toler); y = calc_y(f, Delta, toler); z = calc_compress(y); - Sig = BOLTZ*(5.0/2.0+std::log(2*M_PI*BOLTZ*Temp/(gmx::square(PLANCK))*V/(f*Natom))); - Shs = Sig+calc_Shs(f, y); - rho = (tmass*AMU)/(V*NANO*NANO*NANO); - sigHS = std::cbrt(6*y*V/(M_PI*Natom)); + Sig = BOLTZ + * (5.0 / 2.0 + std::log(2 * M_PI * BOLTZ * Temp / (gmx::square(PLANCK)) * V / (f * Natom))); + Shs = Sig + calc_Shs(f, y); + rho = (tmass * AMU) / (V * NANO * NANO * NANO); + sigHS = std::cbrt(6 * y * V / (M_PI * Natom)); fprintf(fplog, "System = \"%s\"\n", *top.name); fprintf(fplog, "Nmol = %d\n", Nmol); @@ -553,48 +559,37 @@ int gmx_dos(int argc, char *argv[]) /* Now compute solid (2) and diffusive (3) components */ fp = xvgropen(opt2fn("-dos", NFILE, fnm), "Density of states", - bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)", - "\\f{4}S(\\f{12}n\\f{4})", oenv); + bRecip ? "E (cm\\S-1\\N)" : "\\f{12}n\\f{4} (1/ps)", "\\f{4}S(\\f{12}n\\f{4})", oenv); xvgr_legend(fp, asize(DoSlegend), DoSlegend, oenv); - recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0; - for (j = 0; (j < nframes/4); j++) + recip_fac = bRecip ? (1e7 / SPEED_OF_LIGHT) : 1.0; + for (j = 0; (j < nframes / 4); j++) { - dos[DOS_DIFF][j] = DoS0/(1+gmx::square(DoS0*M_PI*nu[j]/(6*f*Natom))); - dos[DOS_SOLID][j] = dos[DOS][j]-dos[DOS_DIFF][j]; - fprintf(fp, "%10g %10g %10g %10g\n", - recip_fac*nu[j], - dos[DOS][j]/recip_fac, - dos[DOS_SOLID][j]/recip_fac, - dos[DOS_DIFF][j]/recip_fac); + dos[DOS_DIFF][j] = DoS0 / (1 + gmx::square(DoS0 * M_PI * nu[j] / (6 * f * Natom))); + dos[DOS_SOLID][j] = dos[DOS][j] - dos[DOS_DIFF][j]; + fprintf(fp, "%10g %10g %10g %10g\n", recip_fac * nu[j], dos[DOS][j] / recip_fac, + dos[DOS_SOLID][j] / recip_fac, dos[DOS_DIFF][j] / recip_fac); } xvgrclose(fp); /* Finally analyze the results! */ wCdiff = 0.5; - wSdiff = Shs/(3*BOLTZ); /* Is this correct? */ + wSdiff = Shs / (3 * BOLTZ); /* Is this correct? */ wEdiff = 0.5; - wAdiff = wEdiff-wSdiff; - for (j = 0; (j < nframes/4); j++) + wAdiff = wEdiff - wSdiff; + for (j = 0; (j < nframes / 4); j++) { - dos[DOS_CP][j] = (dos[DOS_DIFF][j]*wCdiff + - dos[DOS_SOLID][j]*wCsolid(nu[j], beta)); - dos[DOS_S][j] = (dos[DOS_DIFF][j]*wSdiff + - dos[DOS_SOLID][j]*wSsolid(nu[j], beta)); - dos[DOS_A][j] = (dos[DOS_DIFF][j]*wAdiff + - dos[DOS_SOLID][j]*wAsolid(nu[j], beta)); - dos[DOS_E][j] = (dos[DOS_DIFF][j]*wEdiff + - dos[DOS_SOLID][j]*wEsolid(nu[j], beta)); + dos[DOS_CP][j] = (dos[DOS_DIFF][j] * wCdiff + dos[DOS_SOLID][j] * wCsolid(nu[j], beta)); + dos[DOS_S][j] = (dos[DOS_DIFF][j] * wSdiff + dos[DOS_SOLID][j] * wSsolid(nu[j], beta)); + dos[DOS_A][j] = (dos[DOS_DIFF][j] * wAdiff + dos[DOS_SOLID][j] * wAsolid(nu[j], beta)); + dos[DOS_E][j] = (dos[DOS_DIFF][j] * wEdiff + dos[DOS_SOLID][j] * wEsolid(nu[j], beta)); } - DiffCoeff = evaluate_integral(nframes/2, tt, dos[VACF], nullptr, nframes/2., &stddev); - DiffCoeff = 1000*DiffCoeff/3.0; - fprintf(fplog, "Diffusion coefficient from VACF %g 10^-5 cm^2/s\n", - DiffCoeff); - fprintf(fplog, "Diffusion coefficient from DoS %g 10^-5 cm^2/s\n", - 1000*DoS0/(12*tmass*beta)); - - cP = BOLTZ * evaluate_integral(nframes/4, nu, dos[DOS_CP], nullptr, - int{nframes/4}, &stddev); - fprintf(fplog, "Heat capacity %g J/mol K\n", 1000*cP/Nmol); + DiffCoeff = evaluate_integral(nframes / 2, tt, dos[VACF], nullptr, nframes / 2., &stddev); + DiffCoeff = 1000 * DiffCoeff / 3.0; + fprintf(fplog, "Diffusion coefficient from VACF %g 10^-5 cm^2/s\n", DiffCoeff); + fprintf(fplog, "Diffusion coefficient from DoS %g 10^-5 cm^2/s\n", 1000 * DoS0 / (12 * tmass * beta)); + + cP = BOLTZ * evaluate_integral(nframes / 4, nu, dos[DOS_CP], nullptr, int{ nframes / 4 }, &stddev); + fprintf(fplog, "Heat capacity %g J/mol K\n", 1000 * cP / Nmol); fprintf(fplog, "\nArrivederci!\n"); gmx_fio_fclose(fplog); diff --git a/src/gromacs/gmxana/gmx_dyecoupl.cpp b/src/gromacs/gmxana/gmx_dyecoupl.cpp index 09f12d6843..d77819d564 100644 --- a/src/gromacs/gmxana/gmx_dyecoupl.cpp +++ b/src/gromacs/gmxana/gmx_dyecoupl.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,10 +49,9 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -int gmx_dyecoupl(int argc, char *argv[]) +int gmx_dyecoupl(int argc, char* argv[]) { - const char *desc[] = - { + const char* desc[] = { "[THISMODULE] extracts dye dynamics from trajectory files.", "Currently, R and kappa^2 between dyes is extracted for (F)RET", "simulations with assumed dipolar coupling as in the Foerster equation.", @@ -73,62 +72,57 @@ int gmx_dyecoupl(int argc, char *argv[]) static gmx_bool bPBCdist = FALSE, bNormHist = FALSE; int histbins = 50; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; real R0 = -1; - t_pargs pa[] = - { + t_pargs pa[] = { { "-pbcdist", FALSE, etBOOL, { &bPBCdist }, "Distance R based on PBC" }, { "-norm", FALSE, etBOOL, { &bNormHist }, "Normalize histograms" }, - { "-bins", FALSE, etINT, {&histbins}, "# of histogram bins" }, - { "-R0", FALSE, etREAL, {&R0}, "Foerster radius including kappa^2=2/3 in nm" } + { "-bins", FALSE, etINT, { &histbins }, "# of histogram bins" }, + { "-R0", FALSE, etREAL, { &R0 }, "Foerster radius including kappa^2=2/3 in nm" } }; #define NPA asize(pa) - t_filenm fnm[] = - { - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffREAD }, - { efXVG, "-ot", "rkappa", ffOPTWR }, - { efXVG, "-oe", "insteff", ffOPTWR }, - { efDAT, "-o", "rkappa", ffOPTWR }, - { efXVG, "-rhist", "rhist", ffOPTWR }, - { efXVG, "-khist", "khist", ffOPTWR } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffREAD }, + { efXVG, "-ot", "rkappa", ffOPTWR }, { efXVG, "-oe", "insteff", ffOPTWR }, + { efDAT, "-o", "rkappa", ffOPTWR }, { efXVG, "-rhist", "rhist", ffOPTWR }, + { efXVG, "-khist", "khist", ffOPTWR } }; #define NFILE asize(fnm) - const char *in_trajfile, *out_xvgrkfile = nullptr, *out_xvginstefffile = nullptr, *out_xvgrhistfile = nullptr, *out_xvgkhistfile = nullptr, *out_datfile = nullptr; + const char *in_trajfile, *out_xvgrkfile = nullptr, *out_xvginstefffile = nullptr, + *out_xvgrhistfile = nullptr, *out_xvgkhistfile = nullptr, + *out_datfile = nullptr; gmx_bool bHaveFirstFrame, bHaveNextFrame, indexOK = TRUE; int ndon, nacc; - int *donindex, *accindex; - char *grpnm; - t_trxstatus *status; + int * donindex, *accindex; + char* grpnm; + t_trxstatus* status; t_trxframe fr; - int flags; - int allocblock = 1000; - real histexpand = 1e-6; - rvec donvec, accvec, donpos, accpos, dist, distnorm; - int natoms; + int flags; + int allocblock = 1000; + real histexpand = 1e-6; + rvec donvec, accvec, donpos, accpos, dist, distnorm; + int natoms; /*we rely on PBC autodetection (...currently)*/ - int ePBC = -1; + int ePBC = -1; - real *rvalues = nullptr, *kappa2values = nullptr, *rhist = nullptr, *khist = nullptr; - t_pbc *pbc = nullptr; - int i, bin; - FILE *rkfp = nullptr, *rhfp = nullptr, *khfp = nullptr, *datfp = nullptr, *iefp = nullptr; - gmx_bool bRKout, bRhistout, bKhistout, bDatout, bInstEffout, grident; + real * rvalues = nullptr, *kappa2values = nullptr, *rhist = nullptr, *khist = nullptr; + t_pbc* pbc = nullptr; + int i, bin; + FILE * rkfp = nullptr, *rhfp = nullptr, *khfp = nullptr, *datfp = nullptr, *iefp = nullptr; + gmx_bool bRKout, bRhistout, bKhistout, bDatout, bInstEffout, grident; - const char *rkleg[2] = { "R", "\\f{Symbol}k\\f{}\\S2\\N" }; - const char *rhleg[1] = { "p(R)" }; - const char *khleg[1] = { "p(\\f{Symbol}k\\f{}\\S2\\N)" }; - const char *ieleg[1] = { "E\\sRET\\N(t)" }; + const char* rkleg[2] = { "R", "\\f{Symbol}k\\f{}\\S2\\N" }; + const char* rhleg[1] = { "p(R)" }; + const char* khleg[1] = { "p(\\f{Symbol}k\\f{}\\S2\\N)" }; + const char* ieleg[1] = { "E\\sRET\\N(t)" }; - real R, kappa2, insteff, Rs = 0., kappa2s = 0., insteffs = 0., rmax, rmin, kmin = 0., kmax = 4., - rrange, krange, rincr, kincr, Rfrac; - int rkcount = 0, rblocksallocated = 0, kblocksallocated = 0; + real R, kappa2, insteff, Rs = 0., kappa2s = 0., insteffs = 0., rmax, rmin, kmin = 0., kmax = 4., + rrange, krange, rincr, kincr, Rfrac; + int rkcount = 0, rblocksallocated = 0, kblocksallocated = 0; if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) @@ -233,19 +227,15 @@ int gmx_dyecoupl(int argc, char *argv[]) if (bRKout) { - rkfp = xvgropen(out_xvgrkfile, - "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory", - "Time (ps)", "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N", - oenv); + rkfp = xvgropen(out_xvgrkfile, "Distance and \\f{Symbol}k\\f{}\\S2\\N trajectory", + "Time (ps)", "Distance (nm) / \\f{Symbol}k\\f{}\\S2\\N", oenv); xvgr_legend(rkfp, 2, rkleg, oenv); } if (bInstEffout) { - iefp = xvgropen(out_xvginstefffile, - "Instantaneous RET Efficiency", - "Time (ps)", "RET Efficiency", - oenv); + iefp = xvgropen(out_xvginstefffile, "Instantaneous RET Efficiency", "Time (ps)", + "RET Efficiency", oenv); xvgr_legend(iefp, 1, ieleg, oenv); } @@ -303,13 +293,13 @@ int gmx_dyecoupl(int argc, char *argv[]) } unitv(dist, distnorm); - R = norm(dist); - kappa2 = iprod(donvec, accvec)- 3.* (iprod(donvec, distnorm) * iprod(distnorm, accvec)); + R = norm(dist); + kappa2 = iprod(donvec, accvec) - 3. * (iprod(donvec, distnorm) * iprod(distnorm, accvec)); kappa2 *= kappa2; if (R0 > 0) { - Rfrac = R/R0; - insteff = 1/(1+(Rfrac*Rfrac*Rfrac*Rfrac*Rfrac*Rfrac)*2/3/kappa2); + Rfrac = R / R0; + insteff = 1 / (1 + (Rfrac * Rfrac * Rfrac * Rfrac * Rfrac * Rfrac) * 2 / 3 / kappa2); insteffs += insteff; if (bInstEffout) @@ -319,7 +309,7 @@ int gmx_dyecoupl(int argc, char *argv[]) } - Rs += R; + Rs += R; kappa2s += kappa2; rkcount++; @@ -335,27 +325,26 @@ int gmx_dyecoupl(int argc, char *argv[]) if (bRhistout) { - rvalues[rkcount-1] = R; + rvalues[rkcount - 1] = R; if (rkcount % allocblock == 0) { - srenew(rvalues, allocblock*(rblocksallocated+1)); + srenew(rvalues, allocblock * (rblocksallocated + 1)); rblocksallocated += 1; } } if (bKhistout) { - kappa2values[rkcount-1] = kappa2; + kappa2values[rkcount - 1] = kappa2; if (rkcount % allocblock == 0) { - srenew(kappa2values, allocblock*(kblocksallocated+1)); + srenew(kappa2values, allocblock * (kblocksallocated + 1)); kblocksallocated += 1; } } bHaveNextFrame = read_next_frame(oenv, status, &fr); - } - while (bHaveNextFrame); + } while (bHaveNextFrame); if (bRKout) { @@ -397,28 +386,27 @@ int gmx_dyecoupl(int argc, char *argv[]) for (i = 1; i < rkcount; i++) { - bin = static_cast((rvalues[i] - rmin) / rincr); + bin = static_cast((rvalues[i] - rmin) / rincr); rhist[bin] += 1; } if (bNormHist) { for (i = 0; i < histbins; i++) { - rhist[i] /= rkcount * rrange/histbins; + rhist[i] /= rkcount * rrange / histbins; } - rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", - "R (nm)", "Normalized Probability", oenv); + rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)", + "Normalized Probability", oenv); } else { - rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", - "R (nm)", "Probability", oenv); + rhfp = xvgropen(out_xvgrhistfile, "Distance Distribution", "R (nm)", + "Probability", oenv); } xvgr_legend(rhfp, 1, rhleg, oenv); for (i = 0; i < histbins; i++) { - fprintf(rhfp, "%12.7f %12.7f\n", (i + 0.5) * rincr + rmin, - rhist[i]); + fprintf(rhfp, "%12.7f %12.7f\n", (i + 0.5) * rincr + rmin, rhist[i]); } xvgrclose(rhfp); } @@ -431,38 +419,33 @@ int gmx_dyecoupl(int argc, char *argv[]) for (i = 1; i < rkcount; i++) { - bin = static_cast((kappa2values[i] - kmin) / kincr); + bin = static_cast((kappa2values[i] - kmin) / kincr); khist[bin] += 1; } if (bNormHist) { for (i = 0; i < histbins; i++) { - khist[i] /= rkcount * krange/histbins; + khist[i] /= rkcount * krange / histbins; } - khfp = xvgropen(out_xvgkhistfile, - "\\f{Symbol}k\\f{}\\S2\\N Distribution", - "\\f{Symbol}k\\f{}\\S2\\N", - "Normalized Probability", oenv); + khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution", + "\\f{Symbol}k\\f{}\\S2\\N", "Normalized Probability", oenv); } else { - khfp = xvgropen(out_xvgkhistfile, - "\\f{Symbol}k\\f{}\\S2\\N Distribution", + khfp = xvgropen(out_xvgkhistfile, "\\f{Symbol}k\\f{}\\S2\\N Distribution", "\\f{Symbol}k\\f{}\\S2\\N", "Probability", oenv); } xvgr_legend(khfp, 1, khleg, oenv); for (i = 0; i < histbins; i++) { - fprintf(khfp, "%12.7f %12.7f\n", (i + 0.5) * kincr + kmin, - khist[i]); + fprintf(khfp, "%12.7f %12.7f\n", (i + 0.5) * kincr + kmin, khist[i]); } xvgrclose(khfp); } printf("\nAverages:\n"); - printf("R_avg = %8.4f nm\nKappa^2 = %8.4f\n", Rs / rkcount, - kappa2s / rkcount); + printf("R_avg = %8.4f nm\nKappa^2 = %8.4f\n", Rs / rkcount, kappa2s / rkcount); if (R0 > 0) { printf("E_RETavg = %8.4f\n", insteffs / rkcount); diff --git a/src/gromacs/gmxana/gmx_enemat.cpp b/src/gromacs/gmxana/gmx_enemat.cpp index cbf6f9d04d..6491e164e2 100644 --- a/src/gromacs/gmxana/gmx_enemat.cpp +++ b/src/gromacs/gmxana/gmx_enemat.cpp @@ -61,13 +61,13 @@ #include "gromacs/utility/strdb.h" -static int search_str2(int nstr, char **str, char *key) +static int search_str2(int nstr, char** str, char* key) { - int i, n; - int keylen = std::strlen(key); + int i, n; + int keylen = std::strlen(key); /* Linear search */ n = 0; - while ( (n < keylen) && ((key[n] < '0') || (key[n] > '9')) ) + while ((n < keylen) && ((key[n] < '0') || (key[n] > '9'))) { n++; } @@ -82,9 +82,9 @@ static int search_str2(int nstr, char **str, char *key) return -1; } -int gmx_enemat(int argc, char *argv[]) +int gmx_enemat(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] extracts an energy matrix from the energy file ([TT]-f[tt]).", "With [TT]-groups[tt] a file must be supplied with on each", "line a group of atoms to be used. For these groups matrix of", @@ -108,7 +108,9 @@ int gmx_enemat(int argc, char *argv[]) "calculated ([TT]-etot[tt]).[PAR]", "An approximation of the free energy can be calculated using:", - "[MATH]E[SUB]free[sub] = E[SUB]0[sub] + kT [LOG][CHEVRON][EXP](E-E[SUB]0[sub])/kT[exp][chevron][log][math], where '[MATH][CHEVRON][chevron][math]'", + "[MATH]E[SUB]free[sub] = E[SUB]0[sub] + kT ", + "[LOG][CHEVRON][EXP](E-E[SUB]0[sub])/kT[exp][chevron][log][math], where ", + "'[MATH][CHEVRON][chevron][math]'", "stands for time-average. A file with reference free energies", "can be supplied to calculate the free energy difference", "with some reference state. Group names (e.g. residue names)", @@ -119,76 +121,81 @@ int gmx_enemat(int argc, char *argv[]) }; static gmx_bool bSum = FALSE; static gmx_bool bMeanEmtx = TRUE; - static int skip = 0, nlevels = 20; - static real cutmax = 1e20, cutmin = -1e20, reftemp = 300.0; - static gmx_bool bCoulSR = TRUE, bCoul14 = FALSE; - static gmx_bool bLJSR = TRUE, bLJ14 = FALSE, bBhamSR = FALSE, - bFree = TRUE; - t_pargs pa[] = { - { "-sum", FALSE, etBOOL, {&bSum}, + static int skip = 0, nlevels = 20; + static real cutmax = 1e20, cutmin = -1e20, reftemp = 300.0; + static gmx_bool bCoulSR = TRUE, bCoul14 = FALSE; + static gmx_bool bLJSR = TRUE, bLJ14 = FALSE, bBhamSR = FALSE, bFree = TRUE; + t_pargs pa[] = { + { "-sum", + FALSE, + etBOOL, + { &bSum }, "Sum the energy terms selected rather than display them all" }, - { "-skip", FALSE, etINT, {&skip}, - "Skip number of frames between data points" }, - { "-mean", FALSE, etBOOL, {&bMeanEmtx}, + { "-skip", FALSE, etINT, { &skip }, "Skip number of frames between data points" }, + { "-mean", + FALSE, + etBOOL, + { &bMeanEmtx }, "with [TT]-groups[tt] extracts matrix of mean energies instead of " "matrix for each timestep" }, - { "-nlevels", FALSE, etINT, {&nlevels}, "number of levels for matrix colors"}, - { "-max", FALSE, etREAL, {&cutmax}, "max value for energies"}, - { "-min", FALSE, etREAL, {&cutmin}, "min value for energies"}, - { "-coulsr", FALSE, etBOOL, {&bCoulSR}, "extract Coulomb SR energies"}, - { "-coul14", FALSE, etBOOL, {&bCoul14}, "extract Coulomb 1-4 energies"}, - { "-ljsr", FALSE, etBOOL, {&bLJSR}, "extract Lennard-Jones SR energies"}, - { "-lj14", FALSE, etBOOL, {&bLJ14}, "extract Lennard-Jones 1-4 energies"}, - { "-bhamsr", FALSE, etBOOL, {&bBhamSR}, "extract Buckingham SR energies"}, - { "-free", FALSE, etBOOL, {&bFree}, "calculate free energy"}, - { "-temp", FALSE, etREAL, {&reftemp}, - "reference temperature for free energy calculation"} + { "-nlevels", FALSE, etINT, { &nlevels }, "number of levels for matrix colors" }, + { "-max", FALSE, etREAL, { &cutmax }, "max value for energies" }, + { "-min", FALSE, etREAL, { &cutmin }, "min value for energies" }, + { "-coulsr", FALSE, etBOOL, { &bCoulSR }, "extract Coulomb SR energies" }, + { "-coul14", FALSE, etBOOL, { &bCoul14 }, "extract Coulomb 1-4 energies" }, + { "-ljsr", FALSE, etBOOL, { &bLJSR }, "extract Lennard-Jones SR energies" }, + { "-lj14", FALSE, etBOOL, { &bLJ14 }, "extract Lennard-Jones 1-4 energies" }, + { "-bhamsr", FALSE, etBOOL, { &bBhamSR }, "extract Buckingham SR energies" }, + { "-free", FALSE, etBOOL, { &bFree }, "calculate free energy" }, + { "-temp", + FALSE, + etREAL, + { &reftemp }, + "reference temperature for free energy calculation" } }; /* We will define egSP more energy-groups: egTotal (total energy) */ #define egTotal egNR #define egSP 1 - gmx_bool egrp_use[egNR+egSP]; + gmx_bool egrp_use[egNR + egSP]; ener_file_t in; - FILE *out; + FILE* out; int timecheck = 0; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; int teller = 0; real sum; gmx_bool bCont, bRef; gmx_bool bCutmax, bCutmin; - real **eneset, *time = nullptr; - int *set, i, j, prevk, k, m = 0, n, nre, nset, nenergy; - char **groups = nullptr; + real ** eneset, *time = nullptr; + int * set, i, j, prevk, k, m = 0, n, nre, nset, nenergy; + char** groups = nullptr; char groupname[255], fn[255]; int ngroups; t_rgb rlo, rhi, rmid; real emax, emid, emin; - real ***emat, **etot, *groupnr; + real *** emat, **etot, *groupnr; double beta, expE, **e, *eaver, *efree = nullptr, edum; char label[234]; - char **ereflines, **erefres = nullptr; - real *eref = nullptr, *edif = nullptr; + char ** ereflines, **erefres = nullptr; + real * eref = nullptr, *edif = nullptr; int neref = 0; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; - t_filenm fnm[] = { - { efEDR, "-f", nullptr, ffOPTRD }, - { efDAT, "-groups", "groups", ffREAD }, - { efDAT, "-eref", "eref", ffOPTRD }, - { efXPM, "-emat", "emat", ffWRITE }, - { efXVG, "-etot", "energy", ffWRITE } - }; + t_filenm fnm[] = { { efEDR, "-f", nullptr, ffOPTRD }, + { efDAT, "-groups", "groups", ffREAD }, + { efDAT, "-eref", "eref", ffOPTRD }, + { efXPM, "-emat", "emat", ffWRITE }, + { efXVG, "-etot", "energy", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - for (i = 0; (i < egNR+egSP); i++) + for (i = 0; (i < egNR + egSP); i++) { egrp_use[i] = FALSE; } @@ -219,7 +226,7 @@ int gmx_enemat(int argc, char *argv[]) fprintf(stderr, "Will read groupnames from inputfile\n"); ngroups = get_lines(opt2fn("-groups", NFILE, fnm), &groups); fprintf(stderr, "Read %d groups\n", ngroups); - snew(set, static_cast(gmx::square(ngroups)*egNR/2)); + snew(set, static_cast(gmx::square(ngroups) * egNR / 2)); n = 0; prevk = 0; for (i = 0; (i < ngroups); i++) @@ -232,7 +239,7 @@ int gmx_enemat(int argc, char *argv[]) { sprintf(groupname, "%s:%s-%s", egrp_nm[m], groups[i], groups[j]); bool foundMatch = false; - for (k = prevk; (k < prevk+nre); k++) + for (k = prevk; (k < prevk + nre); k++) { if (std::strcmp(enm[k % nre].name, groupname) == 0) { @@ -243,8 +250,10 @@ int gmx_enemat(int argc, char *argv[]) } if (!foundMatch) { - fprintf(stderr, "WARNING! could not find group %s (%d,%d) " - "in energy file\n", groupname, i, j); + fprintf(stderr, + "WARNING! could not find group %s (%d,%d) " + "in energy file\n", + groupname, i, j); } else { @@ -265,7 +274,7 @@ int gmx_enemat(int argc, char *argv[]) return 1; } nset = n; - snew(eneset, nset+1); + snew(eneset, nset + 1); fprintf(stderr, "Will select half-matrix of energies with %d elements\n", n); /* Start reading energy frames */ @@ -279,8 +288,7 @@ int gmx_enemat(int argc, char *argv[]) { timecheck = check_times(fr->t); } - } - while (bCont && (timecheck < 0)); + } while (bCont && (timecheck < 0)); if (timecheck == 0) { @@ -293,10 +301,10 @@ int gmx_enemat(int argc, char *argv[]) if ((nenergy % 1000) == 0) { - srenew(time, nenergy+1000); + srenew(time, nenergy + 1000); for (i = 0; (i <= nset); i++) { - srenew(eneset[i], nenergy+1000); + srenew(eneset[i], nenergy + 1000); } } time[nenergy] = fr->t; @@ -304,7 +312,7 @@ int gmx_enemat(int argc, char *argv[]) for (i = 0; (i < nset); i++) { eneset[i][nenergy] = fr->ener[set[i]].e; - sum += fr->ener[set[i]].e; + sum += fr->ener[set[i]].e; } if (bSum) { @@ -314,16 +322,17 @@ int gmx_enemat(int argc, char *argv[]) } teller++; } - } - while (bCont && (timecheck == 0)); + } while (bCont && (timecheck == 0)); fprintf(stderr, "\n"); - fprintf(stderr, "Will build energy half-matrix of %d groups, %d elements, " - "over %d frames\n", ngroups, nset, nenergy); + fprintf(stderr, + "Will build energy half-matrix of %d groups, %d elements, " + "over %d frames\n", + ngroups, nset, nenergy); - snew(emat, egNR+egSP); - for (j = 0; (j < egNR+egSP); j++) + snew(emat, egNR + egSP); + for (j = 0; (j < egNR + egSP); j++) { if (egrp_use[m]) { @@ -337,11 +346,17 @@ int gmx_enemat(int argc, char *argv[]) snew(groupnr, ngroups); for (i = 0; (i < ngroups); i++) { - groupnr[i] = i+1; + groupnr[i] = i + 1; } - rlo.r = 1.0; rlo.g = 0.0; rlo.b = 0.0; - rmid.r = 1.0; rmid.g = 1.0; rmid.b = 1.0; - rhi.r = 0.0; rhi.g = 0.0; rhi.b = 1.0; + rlo.r = 1.0; + rlo.g = 0.0; + rlo.b = 0.0; + rmid.r = 1.0; + rmid.g = 1.0; + rmid.b = 1.0; + rhi.r = 0.0; + rhi.g = 0.0; + rhi.b = 1.0; if (bMeanEmtx) { snew(e, ngroups); @@ -361,17 +376,17 @@ int gmx_enemat(int argc, char *argv[]) for (k = 0; (k < nenergy); k++) { emat[m][i][j] += eneset[n][k]; - e[i][k] += eneset[n][k]; /* *0.5; */ - e[j][k] += eneset[n][k]; /* *0.5; */ + e[i][k] += eneset[n][k]; /* *0.5; */ + e[j][k] += eneset[n][k]; /* *0.5; */ } n++; emat[egTotal][i][j] += emat[m][i][j]; - emat[m][i][j] /= nenergy; - emat[m][j][i] = emat[m][i][j]; + emat[m][i][j] /= nenergy; + emat[m][j][i] = emat[m][i][j]; } } emat[egTotal][i][j] /= nenergy; - emat[egTotal][j][i] = emat[egTotal][i][j]; + emat[egTotal][j][i] = emat[egTotal][i][j]; } } if (bFree) @@ -399,7 +414,7 @@ int gmx_enemat(int argc, char *argv[]) } eaver[i] /= nenergy; } - beta = 1.0/(BOLTZ*reftemp); + beta = 1.0 / (BOLTZ * reftemp); snew(efree, ngroups); snew(edif, ngroups); for (i = 0; (i < ngroups); i++) @@ -407,21 +422,23 @@ int gmx_enemat(int argc, char *argv[]) expE = 0; for (k = 0; (k < nenergy); k++) { - expE += std::exp(beta*(e[i][k]-eaver[i])); + expE += std::exp(beta * (e[i][k] - eaver[i])); } - efree[i] = std::log(expE/nenergy)/beta + eaver[i]; + efree[i] = std::log(expE / nenergy) / beta + eaver[i]; if (bRef) { n = search_str2(neref, erefres, groups[i]); if (n != -1) { - edif[i] = efree[i]-eref[n]; + edif[i] = efree[i] - eref[n]; } else { edif[i] = efree[i]; - fprintf(stderr, "WARNING: group %s not found " - "in reference energies.\n", groups[i]); + fprintf(stderr, + "WARNING: group %s not found " + "in reference energies.\n", + groups[i]); } } else @@ -433,7 +450,7 @@ int gmx_enemat(int argc, char *argv[]) emid = 0.0; /*(emin+emax)*0.5;*/ egrp_nm[egTotal] = "total"; - for (m = 0; (m < egNR+egSP); m++) + for (m = 0; (m < egNR + egSP); m++) { if (egrp_use[m]) { @@ -455,13 +472,14 @@ int gmx_enemat(int argc, char *argv[]) } if (emax == emin) { - fprintf(stderr, "Matrix of %s energy is uniform at %f " - "(will not produce output).\n", egrp_nm[m], emax); + fprintf(stderr, + "Matrix of %s energy is uniform at %f " + "(will not produce output).\n", + egrp_nm[m], emax); } else { - fprintf(stderr, "Matrix of %s energy ranges from %f to %f\n", - egrp_nm[m], emin, emax); + fprintf(stderr, "Matrix of %s energy ranges from %f to %f\n", egrp_nm[m], emin, emax); if ((bCutmax) || (emax > cutmax)) { emax = cutmax; @@ -480,31 +498,28 @@ int gmx_enemat(int argc, char *argv[]) out = gmx_ffopen(fn, "w"); if (emin >= emid) { - write_xpm(out, 0, label, "Energy (kJ/mol)", - "Residue Index", "Residue Index", - ngroups, ngroups, groupnr, groupnr, emat[m], + write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index", + "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emid, emax, rmid, rhi, &nlevels); } else if (emax <= emid) { - write_xpm(out, 0, label, "Energy (kJ/mol)", - "Residue Index", "Residue Index", - ngroups, ngroups, groupnr, groupnr, emat[m], + write_xpm(out, 0, label, "Energy (kJ/mol)", "Residue Index", + "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emin, emid, rlo, rmid, &nlevels); } else { - write_xpm3(out, 0, label, "Energy (kJ/mol)", - "Residue Index", "Residue Index", - ngroups, ngroups, groupnr, groupnr, emat[m], + write_xpm3(out, 0, label, "Energy (kJ/mol)", "Residue Index", + "Residue Index", ngroups, ngroups, groupnr, groupnr, emat[m], emin, emid, emax, rlo, rmid, rhi, &nlevels); } gmx_ffclose(out); } } } - snew(etot, egNR+egSP); - for (m = 0; (m < egNR+egSP); m++) + snew(etot, egNR + egSP); + for (m = 0; (m < egNR + egSP); m++) { snew(etot[m], ngroups); for (i = 0; (i < ngroups); i++) @@ -516,8 +531,7 @@ int gmx_enemat(int argc, char *argv[]) } } - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Mean Energy", "Residue", "kJ/mol", - oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Mean Energy", "Residue", "kJ/mol", oenv); xvgr_legend(out, 0, nullptr, oenv); j = 0; if (output_env_get_print_xvgr_codes(oenv)) @@ -534,7 +548,7 @@ int gmx_enemat(int argc, char *argv[]) sprintf(str2, " legend "); } - for (m = 0; (m < egNR+egSP); m++) + for (m = 0; (m < egNR + egSP); m++) { if (egrp_use[m]) { @@ -552,7 +566,7 @@ int gmx_enemat(int argc, char *argv[]) fprintf(out, "@TYPE xy\n"); fprintf(out, "#%3s", "grp"); - for (m = 0; (m < egNR+egSP); m++) + for (m = 0; (m < egNR + egSP); m++) { if (egrp_use[m]) { @@ -572,7 +586,7 @@ int gmx_enemat(int argc, char *argv[]) for (i = 0; (i < ngroups); i++) { fprintf(out, "%3.0f", groupnr[i]); - for (m = 0; (m < egNR+egSP); m++) + for (m = 0; (m < egNR + egSP); m++) { if (egrp_use[m]) { @@ -593,22 +607,23 @@ int gmx_enemat(int argc, char *argv[]) } else { - fprintf(stderr, "While typing at your keyboard, suddenly...\n" + fprintf(stderr, + "While typing at your keyboard, suddenly...\n" "...nothing happens.\nWARNING: Not Implemented Yet\n"); -/* - out=ftp2FILE(efMAT,NFILE,fnm,"w"); - n=0; - emin=emax=0.0; - for (k=0; (kstep); sfree(edat->steps); @@ -112,27 +115,27 @@ static void done_enerdata_t(int nset, enerdata_t *edat) sfree(edat->s); } -static void chomp(char *buf) +static void chomp(char* buf) { int len = std::strlen(buf); - while ((len > 0) && (buf[len-1] == '\n')) + while ((len > 0) && (buf[len - 1] == '\n')) { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; len--; } } -static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) +static int* select_by_name(int nre, gmx_enxnm_t* nm, int* nset) { - gmx_bool *bE; + gmx_bool* bE; int k, kk, j, i, nmatch, nind, nss; - int *set; + int* set; gmx_bool bEOF, bVerbose = TRUE, bLong = FALSE; - char *ptr, buf[STRLEN]; - const char *fm4 = "%3d %-14s"; - const char *fm2 = "%3d %-34s"; - char **newnm = nullptr; + char * ptr, buf[STRLEN]; + const char* fm4 = "%3d %-14s"; + const char* fm2 = "%3d %-34s"; + char** newnm = nullptr; if ((getenv("GMX_ENER_VERBOSE")) != nullptr) { @@ -164,7 +167,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) fprintf(stderr, "\n"); } bLong = FALSE; - for (kk = k; kk < k+4; kk++) + for (kk = k; kk < k + 4; kk++) { if (kk < nre && std::strlen(nm[kk].name) > 14) { @@ -178,7 +181,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) } if (!bLong) { - fprintf(stderr, fm4, k+1, newnm[k]); + fprintf(stderr, fm4, k + 1, newnm[k]); j++; if (j == 4) { @@ -187,7 +190,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) } else { - fprintf(stderr, fm2, k+1, newnm[k]); + fprintf(stderr, fm2, k + 1, newnm[k]); j++; if (j == 2) { @@ -204,7 +207,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) snew(bE, nre); bEOF = FALSE; - while (!bEOF && (fgets2(buf, STRLEN-1, stdin))) + while (!bEOF && (fgets2(buf, STRLEN - 1, stdin))) { /* Remove newlines */ chomp(buf); @@ -222,7 +225,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) if (!bEOF) { /* First try to read an integer */ - nss = sscanf(ptr, "%d", &nind); + nss = sscanf(ptr, "%d", &nind); if (nss == 1) { /* Zero means end of input */ @@ -232,7 +235,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) } else if ((1 <= nind) && (nind <= nre)) { - bE[nind-1] = TRUE; + bE[nind - 1] = TRUE; } else { @@ -275,8 +278,7 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) { trim(ptr); } - } - while (!bEOF && ((ptr != nullptr) && (std::strlen(ptr) > 0))); + } while (!bEOF && ((ptr != nullptr) && (std::strlen(ptr) > 0))); } } @@ -305,36 +307,40 @@ static int *select_by_name(int nre, gmx_enxnm_t *nm, int *nset) return set; } -static void get_dhdl_parms(const char *topnm, t_inputrec *ir) +static void get_dhdl_parms(const char* topnm, t_inputrec* ir) { - gmx_mtop_t mtop; - int natoms; - matrix box; + gmx_mtop_t mtop; + int natoms; + matrix box; /* all we need is the ir to be able to write the label */ read_tpx(topnm, ir, box, &natoms, nullptr, nullptr, &mtop); } -static void einstein_visco(const char *fn, const char *fni, int nsets, - int nint, real **eneint, - real V, real T, double dt, - const gmx_output_env_t *oenv) +static void einstein_visco(const char* fn, + const char* fni, + int nsets, + int nint, + real** eneint, + real V, + real T, + double dt, + const gmx_output_env_t* oenv) { - FILE *fp0, *fp1; + FILE * fp0, *fp1; double av[4], avold[4]; double fac, di; int i, j, m, nf4; - nf4 = nint/4 + 1; + nf4 = nint / 4 + 1; for (i = 0; i <= nsets; i++) { avold[i] = 0; } - fp0 = xvgropen(fni, "Shear viscosity integral", - "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N ps)", oenv); - fp1 = xvgropen(fn, "Shear viscosity using Einstein relation", - "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N)", oenv); + fp0 = xvgropen(fni, "Shear viscosity integral", "Time (ps)", "(kg m\\S-1\\N s\\S-1\\N ps)", oenv); + fp1 = xvgropen(fn, "Shear viscosity using Einstein relation", "Time (ps)", + "(kg m\\S-1\\N s\\S-1\\N)", oenv); for (i = 0; i < nf4; i++) { for (m = 0; m <= nsets; m++) @@ -345,25 +351,25 @@ static void einstein_visco(const char *fn, const char *fni, int nsets, { for (m = 0; m < nsets; m++) { - di = gmx::square(eneint[m][j+i] - eneint[m][j]); + di = gmx::square(eneint[m][j + i] - eneint[m][j]); - av[m] += di; - av[nsets] += di/nsets; + av[m] += di; + av[nsets] += di / nsets; } } /* Convert to SI for the viscosity */ - fac = (V*NANO*NANO*NANO*PICO*1e10)/(2*BOLTZMANN*T)/(nint - i); - fprintf(fp0, "%10g", i*dt); + fac = (V * NANO * NANO * NANO * PICO * 1e10) / (2 * BOLTZMANN * T) / (nint - i); + fprintf(fp0, "%10g", i * dt); for (m = 0; (m <= nsets); m++) { - av[m] = fac*av[m]; + av[m] = fac * av[m]; fprintf(fp0, " %10g", av[m]); } fprintf(fp0, "\n"); - fprintf(fp1, "%10g", (i + 0.5)*dt); + fprintf(fp1, "%10g", (i + 0.5) * dt); for (m = 0; (m <= nsets); m++) { - fprintf(fp1, " %10g", (av[m]-avold[m])/dt); + fprintf(fp1, " %10g", (av[m] - avold[m]) / dt); avold[m] = av[m]; } fprintf(fp1, "\n"); @@ -372,21 +378,23 @@ static void einstein_visco(const char *fn, const char *fni, int nsets, xvgrclose(fp1); } -typedef struct { - int64_t np; - double sum; - double sav; - double sav2; +typedef struct +{ + int64_t np; + double sum; + double sav; + double sav2; } ee_sum_t; -typedef struct { - int b; - ee_sum_t sum; - int64_t nst; - int64_t nst_min; +typedef struct +{ + int b; + ee_sum_t sum; + int64_t nst; + int64_t nst_min; } ener_ee_t; -static void clear_ee_sum(ee_sum_t *ees) +static void clear_ee_sum(ee_sum_t* ees) { ees->sav = 0; ees->sav2 = 0; @@ -394,35 +402,34 @@ static void clear_ee_sum(ee_sum_t *ees) ees->sum = 0; } -static void add_ee_sum(ee_sum_t *ees, double sum, int np) +static void add_ee_sum(ee_sum_t* ees, double sum, int np) { - ees->np += np; + ees->np += np; ees->sum += sum; } -static void add_ee_av(ee_sum_t *ees) +static void add_ee_av(ee_sum_t* ees) { double av; - av = ees->sum/ees->np; - ees->sav += av; - ees->sav2 += av*av; - ees->np = 0; - ees->sum = 0; + av = ees->sum / ees->np; + ees->sav += av; + ees->sav2 += av * av; + ees->np = 0; + ees->sum = 0; } -static double calc_ee2(int nb, ee_sum_t *ees) +static double calc_ee2(int nb, ee_sum_t* ees) { - return (ees->sav2/nb - gmx::square(ees->sav/nb))/(nb - 1); + return (ees->sav2 / nb - gmx::square(ees->sav / nb)) / (nb - 1); } -static void set_ee_av(ener_ee_t *eee) +static void set_ee_av(ener_ee_t* eee) { if (debug) { char buf[STEPSTRSIZE]; - fprintf(debug, "Storing average for err.est.: %s steps\n", - gmx_step_str(eee->nst, buf)); + fprintf(debug, "Storing average for err.est.: %s steps\n", gmx_step_str(eee->nst, buf)); } add_ee_av(&eee->sum); eee->b++; @@ -433,16 +440,16 @@ static void set_ee_av(ener_ee_t *eee) eee->nst = 0; } -static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) +static void calc_averages(int nset, enerdata_t* edat, int nbmin, int nbmax) { - int nb, i, f, nee; - double sum, sum2, sump, see2; - int64_t np, p, bound_nb; - enerdat_t *ed; - exactsum_t *es; - gmx_bool bAllZero; - double x, sx, sy, sxx, sxy; - ener_ee_t *eee; + int nb, i, f, nee; + double sum, sum2, sump, see2; + int64_t np, p, bound_nb; + enerdat_t* ed; + exactsum_t* es; + gmx_bool bAllZero; + double x, sx, sy, sxx, sxy; + ener_ee_t* eee; /* Check if we have exact statistics over all points */ for (i = 0; i < nset; i++) @@ -470,7 +477,7 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) } } - snew(eee, nbmax+1); + snew(eee, nbmax + 1); for (i = 0; i < nset; i++) { ed = &edat->s[i]; @@ -484,7 +491,7 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) sxy = 0; for (nb = nbmin; nb <= nbmax; nb++) { - eee[nb].b = 0; + eee[nb].b = 0; clear_ee_sum(&eee[nb].sum); eee[nb].nst = 0; eee[nb].nst_min = 0; @@ -496,44 +503,42 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) if (ed->bExactStat) { /* Add the sum and the sum of variances to the totals. */ - p = edat->points[f]; - sump = es->sum; + p = edat->points[f]; + sump = es->sum; sum2 += es->sum2; if (np > 0) { - sum2 += gmx::square(sum/np - (sum + es->sum)/(np + p)) - *np*(np + p)/p; + sum2 += gmx::square(sum / np - (sum + es->sum) / (np + p)) * np * (np + p) / p; } } else { /* Add a single value to the sum and sum of squares. */ - p = 1; - sump = ed->ener[f]; + p = 1; + sump = ed->ener[f]; sum2 += gmx::square(sump); } /* sum has to be increased after sum2 */ - np += p; + np += p; sum += sump; /* For the linear regression use variance 1/p. * Note that sump is the sum, not the average, so we don't need p*. */ - x = edat->step[f] - 0.5*(edat->steps[f] - 1); - sx += p*x; - sy += sump; - sxx += p*x*x; - sxy += x*sump; + x = edat->step[f] - 0.5 * (edat->steps[f] - 1); + sx += p * x; + sy += sump; + sxx += p * x * x; + sxy += x * sump; for (nb = nbmin; nb <= nbmax; nb++) { /* Check if the current end step is closer to the desired * block boundary than the next end step. */ - bound_nb = (edat->step[0]-1)*nb + edat->nsteps*(eee[nb].b+1); - if (eee[nb].nst > 0 && - bound_nb - edat->step[f-1]*nb < edat->step[f]*nb - bound_nb) + bound_nb = (edat->step[0] - 1) * nb + edat->nsteps * (eee[nb].b + 1); + if (eee[nb].nst > 0 && bound_nb - edat->step[f - 1] * nb < edat->step[f] * nb - bound_nb) { set_ee_av(&eee[nb]); } @@ -543,7 +548,7 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) } else { - eee[nb].nst += edat->step[f] - edat->step[f-1]; + eee[nb].nst += edat->step[f] - edat->step[f - 1]; } if (ed->bExactStat) { @@ -553,27 +558,27 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) { add_ee_sum(&eee[nb].sum, edat->s[i].ener[f], 1); } - bound_nb = (edat->step[0]-1)*nb + edat->nsteps*(eee[nb].b+1); - if (edat->step[f]*nb >= bound_nb) + bound_nb = (edat->step[0] - 1) * nb + edat->nsteps * (eee[nb].b + 1); + if (edat->step[f] * nb >= bound_nb) { set_ee_av(&eee[nb]); } } } - edat->s[i].av = sum/np; + edat->s[i].av = sum / np; if (ed->bExactStat) { - edat->s[i].rmsd = std::sqrt(sum2/np); + edat->s[i].rmsd = std::sqrt(sum2 / np); } else { - edat->s[i].rmsd = std::sqrt(sum2/np - gmx::square(edat->s[i].av)); + edat->s[i].rmsd = std::sqrt(sum2 / np - gmx::square(edat->s[i].av)); } if (edat->nframes > 1) { - edat->s[i].slope = (np*sxy - sx*sy)/(np*sxx - sx*sx); + edat->s[i].slope = (np * sxy - sx * sy) / (np * sxx - sx * sx); } else { @@ -590,12 +595,10 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) if (debug) { char buf1[STEPSTRSIZE], buf2[STEPSTRSIZE]; - fprintf(debug, "Requested %d blocks, we have %d blocks, min %s nsteps %s\n", - nb, eee[nb].b, - gmx_step_str(eee[nb].nst_min, buf1), - gmx_step_str(edat->nsteps, buf2)); + fprintf(debug, "Requested %d blocks, we have %d blocks, min %s nsteps %s\n", nb, + eee[nb].b, gmx_step_str(eee[nb].nst_min, buf1), gmx_step_str(edat->nsteps, buf2)); } - if (eee[nb].b == nb && 5*nb*eee[nb].nst_min >= 4*edat->nsteps) + if (eee[nb].b == nb && 5 * nb * eee[nb].nst_min >= 4 * edat->nsteps) { see2 += calc_ee2(nb, &eee[nb].sum); nee++; @@ -603,7 +606,7 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) } if (nee > 0) { - edat->s[i].ee = std::sqrt(see2/nee); + edat->s[i].ee = std::sqrt(see2 / nee); } else { @@ -613,10 +616,10 @@ static void calc_averages(int nset, enerdata_t *edat, int nbmin, int nbmax) sfree(eee); } -static enerdata_t *calc_sum(int nset, enerdata_t *edat, int nbmin, int nbmax) +static enerdata_t* calc_sum(int nset, enerdata_t* edat, int nbmin, int nbmax) { - enerdata_t *esum; - enerdat_t *s; + enerdata_t* esum; + enerdat_t* s; int f, i; double sum; @@ -660,23 +663,23 @@ static enerdata_t *calc_sum(int nset, enerdata_t *edat, int nbmin, int nbmax) return esum; } -static void ee_pr(double ee, int buflen, char *buf) +static void ee_pr(double ee, int buflen, char* buf) { snprintf(buf, buflen, "%s", "--"); if (ee >= 0) { /* Round to two decimals by printing. */ - char tmp[100]; + char tmp[100]; snprintf(tmp, sizeof(tmp), "%.1e", ee); double rnd = gmx::doubleFromString(tmp); snprintf(buf, buflen, "%g", rnd); } } -static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t *edat) +static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t* edat) { -/* Remove the drift by performing a fit to y = ax+b. - Uses 5 iterations. */ + /* Remove the drift by performing a fit to y = ax+b. + Uses 5 iterations. */ int i, j, k; double delta; @@ -687,7 +690,7 @@ static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t *ed { for (i = 0; (i < nset); i++) { - delta = edat->s[i].slope*dt; + delta = edat->s[i].slope * dt; if (nullptr != debug) { @@ -696,7 +699,7 @@ static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t *ed for (j = 0; (j < edat->nframes); j++) { - edat->s[i].ener[j] -= j*delta; + edat->s[i].ener[j] -= j * delta; edat->s[i].es[j].sum = 0; edat->s[i].es[j].sum2 = 0; } @@ -705,25 +708,35 @@ static void remove_drift(int nset, int nbmin, int nbmax, real dt, enerdata_t *ed } } -static void calc_fluctuation_props(FILE *fp, - gmx_bool bDriftCorr, real dt, - int nset, int nmol, - char **leg, enerdata_t *edat, - int nbmin, int nbmax) +static void calc_fluctuation_props(FILE* fp, + gmx_bool bDriftCorr, + real dt, + int nset, + int nmol, + char** leg, + enerdata_t* edat, + int nbmin, + int nbmax) { int i, j; double vv, v, h, varv, hh, varh, tt, cv, cp, alpha, kappa, dcp, varet; double NANO3; - enum { - eVol, eEnth, eTemp, eEtot, eNR + enum + { + eVol, + eEnth, + eTemp, + eEtot, + eNR }; - const char *my_ener[] = { "Volume", "Enthalpy", "Temperature", "Total Energy" }; + const char* my_ener[] = { "Volume", "Enthalpy", "Temperature", "Total Energy" }; int ii[eNR]; - NANO3 = NANO*NANO*NANO; + NANO3 = NANO * NANO * NANO; if (!bDriftCorr) { - fprintf(fp, "\nYou may want to use the -driftcorr flag in order to correct\n" + fprintf(fp, + "\nYou may want to use the -driftcorr flag in order to correct\n" "for spurious drift in the graphs. Note that this is not\n" "a substitute for proper equilibration and sampling!\n"); } @@ -733,165 +746,166 @@ static void calc_fluctuation_props(FILE *fp, } for (i = 0; (i < eNR); i++) { - for (ii[i] = 0; (ii[i] < nset && - (gmx_strcasecmp(leg[ii[i]], my_ener[i]) != 0)); ii[i]++) - { - ; - } + for (ii[i] = 0; (ii[i] < nset && (gmx_strcasecmp(leg[ii[i]], my_ener[i]) != 0)); ii[i]++) {} /* if (ii[i] < nset) fprintf(fp,"Found %s data.\n",my_ener[i]); */ } - /* Compute it all! */ - alpha = kappa = cp = dcp = cv = NOTSET; +/* Compute it all! */ +alpha = kappa = cp = dcp = cv = NOTSET; - /* Temperature */ - tt = NOTSET; - if (ii[eTemp] < nset) +/* Temperature */ +tt = NOTSET; +if (ii[eTemp] < nset) +{ + tt = edat->s[ii[eTemp]].av; +} +/* Volume */ +vv = varv = NOTSET; +if ((ii[eVol] < nset) && (ii[eTemp] < nset)) +{ + vv = edat->s[ii[eVol]].av * NANO3; + varv = gmx::square(edat->s[ii[eVol]].rmsd * NANO3); + kappa = (varv / vv) / (BOLTZMANN * tt); +} +/* Enthalpy */ +hh = varh = NOTSET; +if ((ii[eEnth] < nset) && (ii[eTemp] < nset)) +{ + hh = KILO * edat->s[ii[eEnth]].av / AVOGADRO; + varh = gmx::square(KILO * edat->s[ii[eEnth]].rmsd / AVOGADRO); + cp = AVOGADRO * ((varh / nmol) / (BOLTZMANN * tt * tt)); +} +/* Total energy */ +if ((ii[eEtot] < nset) && (hh == NOTSET) && (tt != NOTSET)) +{ + /* Only compute cv in constant volume runs, which we can test + by checking whether the enthalpy was computed. + */ + varet = gmx::square(edat->s[ii[eEtot]].rmsd); + cv = KILO * ((varet / nmol) / (BOLTZ * tt * tt)); +} +/* Alpha, dcp */ +if ((ii[eVol] < nset) && (ii[eEnth] < nset) && (ii[eTemp] < nset)) +{ + double v_sum, h_sum, vh_sum, v_aver, h_aver, vh_aver; + vh_sum = v_sum = h_sum = 0; + for (j = 0; (j < edat->nframes); j++) { - tt = edat->s[ii[eTemp]].av; + v = edat->s[ii[eVol]].ener[j] * NANO3; + h = KILO * edat->s[ii[eEnth]].ener[j] / AVOGADRO; + v_sum += v; + h_sum += h; + vh_sum += (v * h); } - /* Volume */ - vv = varv = NOTSET; - if ((ii[eVol] < nset) && (ii[eTemp] < nset)) + vh_aver = vh_sum / edat->nframes; + v_aver = v_sum / edat->nframes; + h_aver = h_sum / edat->nframes; + alpha = (vh_aver - v_aver * h_aver) / (v_aver * BOLTZMANN * tt * tt); + dcp = (v_aver * AVOGADRO / nmol) * tt * gmx::square(alpha) / (kappa); +} + +if (tt != NOTSET) +{ + if (nmol < 2) { - vv = edat->s[ii[eVol]].av*NANO3; - varv = gmx::square(edat->s[ii[eVol]].rmsd*NANO3); - kappa = (varv/vv)/(BOLTZMANN*tt); + fprintf(fp, "\nWARNING: nmol = %d, this may not be what you want.\n", nmol); } - /* Enthalpy */ - hh = varh = NOTSET; - if ((ii[eEnth] < nset) && (ii[eTemp] < nset)) + fprintf(fp, "\nTemperature dependent fluctuation properties at T = %g.\n", tt); + fprintf(fp, "\nHeat capacities obtained from fluctuations do *not* include\n"); + fprintf(fp, "quantum corrections. If you want to get a more accurate estimate\n"); + fprintf(fp, "please use the g_dos program.\n\n"); + fprintf(fp, + "WARNING: Please verify that your simulations are converged and perform\n" + "a block-averaging error analysis (not implemented in g_energy yet)\n"); + + if (debug != nullptr) { - hh = KILO*edat->s[ii[eEnth]].av/AVOGADRO; - varh = gmx::square(KILO*edat->s[ii[eEnth]].rmsd/AVOGADRO); - cp = AVOGADRO*((varh/nmol)/(BOLTZMANN*tt*tt)); + if (varv != NOTSET) + { + fprintf(fp, "varv = %10g (m^6)\n", varv * AVOGADRO / nmol); + } } - /* Total energy */ - if ((ii[eEtot] < nset) && (hh == NOTSET) && (tt != NOTSET)) + if (vv != NOTSET) { - /* Only compute cv in constant volume runs, which we can test - by checking whether the enthalpy was computed. - */ - varet = gmx::square(edat->s[ii[eEtot]].rmsd); - cv = KILO*((varet/nmol)/(BOLTZ*tt*tt)); + fprintf(fp, "Volume = %10g m^3/mol\n", vv * AVOGADRO / nmol); } - /* Alpha, dcp */ - if ((ii[eVol] < nset) && (ii[eEnth] < nset) && (ii[eTemp] < nset)) + if (varh != NOTSET) { - double v_sum, h_sum, vh_sum, v_aver, h_aver, vh_aver; - vh_sum = v_sum = h_sum = 0; - for (j = 0; (j < edat->nframes); j++) - { - v = edat->s[ii[eVol]].ener[j]*NANO3; - h = KILO*edat->s[ii[eEnth]].ener[j]/AVOGADRO; - v_sum += v; - h_sum += h; - vh_sum += (v*h); - } - vh_aver = vh_sum / edat->nframes; - v_aver = v_sum / edat->nframes; - h_aver = h_sum / edat->nframes; - alpha = (vh_aver-v_aver*h_aver)/(v_aver*BOLTZMANN*tt*tt); - dcp = (v_aver*AVOGADRO/nmol)*tt*gmx::square(alpha)/(kappa); + fprintf(fp, "Enthalpy = %10g kJ/mol\n", + hh * AVOGADRO / (KILO * nmol)); } - - if (tt != NOTSET) + if (alpha != NOTSET) { - if (nmol < 2) - { - fprintf(fp, "\nWARNING: nmol = %d, this may not be what you want.\n", - nmol); - } - fprintf(fp, "\nTemperature dependent fluctuation properties at T = %g.\n", tt); - fprintf(fp, "\nHeat capacities obtained from fluctuations do *not* include\n"); - fprintf(fp, "quantum corrections. If you want to get a more accurate estimate\n"); - fprintf(fp, "please use the g_dos program.\n\n"); - fprintf(fp, "WARNING: Please verify that your simulations are converged and perform\n" - "a block-averaging error analysis (not implemented in g_energy yet)\n"); - - if (debug != nullptr) - { - if (varv != NOTSET) - { - fprintf(fp, "varv = %10g (m^6)\n", varv*AVOGADRO/nmol); - } - } - if (vv != NOTSET) - { - fprintf(fp, "Volume = %10g m^3/mol\n", - vv*AVOGADRO/nmol); - } - if (varh != NOTSET) - { - fprintf(fp, "Enthalpy = %10g kJ/mol\n", - hh*AVOGADRO/(KILO*nmol)); - } - if (alpha != NOTSET) - { - fprintf(fp, "Coefficient of Thermal Expansion Alpha_P = %10g (1/K)\n", - alpha); - } - if (kappa != NOTSET) - { - fprintf(fp, "Isothermal Compressibility Kappa = %10g (m^3/J)\n", - kappa); - fprintf(fp, "Adiabatic bulk modulus = %10g (J/m^3)\n", - 1.0/kappa); - } - if (cp != NOTSET) - { - fprintf(fp, "Heat capacity at constant pressure Cp = %10g J/(mol K)\n", - cp); - } - if (cv != NOTSET) - { - fprintf(fp, "Heat capacity at constant volume Cv = %10g J/(mol K)\n", - cv); - } - if (dcp != NOTSET) - { - fprintf(fp, "Cp-Cv = %10g J/(mol K)\n", - dcp); - } - please_cite(fp, "Allen1987a"); + fprintf(fp, "Coefficient of Thermal Expansion Alpha_P = %10g (1/K)\n", alpha); } - else + if (kappa != NOTSET) + { + fprintf(fp, "Isothermal Compressibility Kappa = %10g (m^3/J)\n", kappa); + fprintf(fp, "Adiabatic bulk modulus = %10g (J/m^3)\n", 1.0 / kappa); + } + if (cp != NOTSET) { - fprintf(fp, "You should select the temperature in order to obtain fluctuation properties.\n"); + fprintf(fp, "Heat capacity at constant pressure Cp = %10g J/(mol K)\n", cp); } + if (cv != NOTSET) + { + fprintf(fp, "Heat capacity at constant volume Cv = %10g J/(mol K)\n", cv); + } + if (dcp != NOTSET) + { + fprintf(fp, "Cp-Cv = %10g J/(mol K)\n", dcp); + } + please_cite(fp, "Allen1987a"); +} +else +{ + fprintf(fp, "You should select the temperature in order to obtain fluctuation properties.\n"); +} } -static void analyse_ener(gmx_bool bCorr, const char *corrfn, - const char *eviscofn, const char *eviscoifn, - gmx_bool bFee, gmx_bool bSum, gmx_bool bFluct, - gmx_bool bVisco, const char *visfn, int nmol, - int64_t start_step, double start_t, - int64_t step, double t, - real reftemp, - enerdata_t *edat, - int nset, const int set[], const gmx_bool *bIsEner, - char **leg, gmx_enxnm_t *enm, - real Vaver, real ezero, - int nbmin, int nbmax, - const gmx_output_env_t *oenv) +static void analyse_ener(gmx_bool bCorr, + const char* corrfn, + const char* eviscofn, + const char* eviscoifn, + gmx_bool bFee, + gmx_bool bSum, + gmx_bool bFluct, + gmx_bool bVisco, + const char* visfn, + int nmol, + int64_t start_step, + double start_t, + int64_t step, + double t, + real reftemp, + enerdata_t* edat, + int nset, + const int set[], + const gmx_bool* bIsEner, + char** leg, + gmx_enxnm_t* enm, + real Vaver, + real ezero, + int nbmin, + int nbmax, + const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; /* Check out the printed manual for equations! */ - double Dt, aver, stddev, errest, delta_t, totaldrift; - enerdata_t *esum = nullptr; - real integral, intBulk, Temp = 0, Pres = 0; - real pr_aver, pr_stddev, pr_errest; - double beta = 0, expE, expEtot, *fee = nullptr; - int64_t nsteps; - int nexact, nnotexact; - int i, j, nout; - char buf[256], eebuf[100]; - - nsteps = step - start_step + 1; + double Dt, aver, stddev, errest, delta_t, totaldrift; + enerdata_t* esum = nullptr; + real integral, intBulk, Temp = 0, Pres = 0; + real pr_aver, pr_stddev, pr_errest; + double beta = 0, expE, expEtot, *fee = nullptr; + int64_t nsteps; + int nexact, nnotexact; + int i, j, nout; + char buf[256], eebuf[100]; + + nsteps = step - start_step + 1; if (nsteps < 1) { - fprintf(stdout, "Not enough steps (%s) for statistics\n", - gmx_step_str(nsteps, buf)); + fprintf(stdout, "Not enough steps (%s) for statistics\n", gmx_step_str(nsteps, buf)); } else { @@ -932,13 +946,11 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, if (nnotexact == 0) { - fprintf(stdout, "All statistics are over %s points\n", - gmx_step_str(edat->npoints, buf)); + fprintf(stdout, "All statistics are over %s points\n", gmx_step_str(edat->npoints, buf)); } else if (nexact == 0 || edat->npoints == edat->nframes) { - fprintf(stdout, "All statistics are over %d points (frames)\n", - edat->nframes); + fprintf(stdout, "All statistics are over %d points (frames)\n", edat->nframes); } else { @@ -952,13 +964,12 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } fprintf(stdout, " %s has statistics over %d points (frames)\n", nnotexact == 1 ? "is" : "are", edat->nframes); - fprintf(stdout, "All other statistics are over %s points\n", - gmx_step_str(edat->npoints, buf)); + fprintf(stdout, "All other statistics are over %s points\n", gmx_step_str(edat->npoints, buf)); } fprintf(stdout, "\n"); - fprintf(stdout, "%-24s %10s %10s %10s %10s", - "Energy", "Average", "Err.Est.", "RMSD", "Tot-Drift"); + fprintf(stdout, "%-24s %10s %10s %10s %10s", "Energy", "Average", "Err.Est.", "RMSD", + "Tot-Drift"); if (bFee) { fprintf(stdout, " %10s\n", "-kT ln"); @@ -967,13 +978,15 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, { fprintf(stdout, "\n"); } - fprintf(stdout, "-------------------------------------------------------------------------------\n"); + fprintf(stdout, + "-------------------------------------------------------------------------------" + "\n"); /* Initiate locals, only used with -sum */ expEtot = 0; if (bFee) { - beta = 1.0/(BOLTZ*reftemp); + beta = 1.0 / (BOLTZ * reftemp); snew(fee, nset); } for (i = 0; (i < nset); i++) @@ -987,14 +1000,14 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, expE = 0; for (j = 0; (j < edat->nframes); j++) { - expE += std::exp(beta*(edat->s[i].ener[j] - aver)/nmol); + expE += std::exp(beta * (edat->s[i].ener[j] - aver) / nmol); } if (bSum) { - expEtot += expE/edat->nframes; + expEtot += expE / edat->nframes; } - fee[i] = std::log(expE/edat->nframes)/beta + aver/nmol; + fee[i] = std::log(expE / edat->nframes) / beta + aver / nmol; } if (std::strstr(leg[i], "empera") != nullptr) { @@ -1010,9 +1023,9 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } if (bIsEner[i]) { - pr_aver = aver/nmol-ezero; - pr_stddev = stddev/nmol; - pr_errest = errest/nmol; + pr_aver = aver / nmol - ezero; + pr_stddev = stddev / nmol; + pr_errest = errest / nmol; } else { @@ -1022,15 +1035,14 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } /* Multiply the slope in steps with the number of steps taken */ - totaldrift = (edat->nsteps - 1)*edat->s[i].slope; + totaldrift = (edat->nsteps - 1) * edat->s[i].slope; if (bIsEner[i]) { totaldrift /= nmol; } ee_pr(pr_errest, sizeof(eebuf), eebuf); - fprintf(stdout, "%-24s %10g %10s %10g %10g", - leg[i], pr_aver, eebuf, pr_stddev, totaldrift); + fprintf(stdout, "%-24s %10g %10s %10g %10g", leg[i], pr_aver, eebuf, pr_stddev, totaldrift); if (bFee) { fprintf(stdout, " %10g", fee[i]); @@ -1048,16 +1060,15 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } if (bSum) { - totaldrift = (edat->nsteps - 1)*esum->s[0].slope; - ee_pr(esum->s[0].ee/nmol, sizeof(eebuf), eebuf); - fprintf(stdout, "%-24s %10g %10s %10s %10g (%s)", - "Total", esum->s[0].av/nmol, eebuf, - "--", totaldrift/nmol, enm[set[0]].unit); + totaldrift = (edat->nsteps - 1) * esum->s[0].slope; + ee_pr(esum->s[0].ee / nmol, sizeof(eebuf), eebuf); + fprintf(stdout, "%-24s %10g %10s %10s %10g (%s)", "Total", esum->s[0].av / nmol, eebuf, + "--", totaldrift / nmol, enm[set[0]].unit); /* pr_aver,pr_stddev,a,totaldrift */ if (bFee) { - fprintf(stdout, " %10g %10g\n", - std::log(expEtot)/beta + esum->s[0].av/nmol, std::log(expEtot)/beta); + fprintf(stdout, " %10g %10g\n", std::log(expEtot) / beta + esum->s[0].av / nmol, + std::log(expEtot) / beta); } else { @@ -1068,7 +1079,7 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, /* Do correlation function */ if (edat->nframes > 1) { - Dt = delta_t/(edat->nframes - 1); + Dt = delta_t / (edat->nframes - 1); } else { @@ -1078,8 +1089,8 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, { const char* leg[] = { "Shear", "Bulk" }; real factor; - real **eneset; - real **eneint; + real** eneset; + real** eneint; /* Assume pressure tensor is in Pxx Pxy Pxz Pyx Pyy Pyz Pzx Pzy Pzz */ @@ -1093,9 +1104,9 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } for (i = 0; (i < edat->nframes); i++) { - eneset[0][i] = 0.5*(edat->s[1].ener[i]+edat->s[3].ener[i]); - eneset[1][i] = 0.5*(edat->s[2].ener[i]+edat->s[6].ener[i]); - eneset[2][i] = 0.5*(edat->s[5].ener[i]+edat->s[7].ener[i]); + eneset[0][i] = 0.5 * (edat->s[1].ener[i] + edat->s[3].ener[i]); + eneset[1][i] = 0.5 * (edat->s[2].ener[i] + edat->s[6].ener[i]); + eneset[2][i] = 0.5 * (edat->s[5].ener[i] + edat->s[7].ener[i]); for (j = 3; j <= 11; j++) { eneset[j][i] = edat->s[j].ener[i]; @@ -1114,13 +1125,18 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, eneint[2][0] = 0; for (i = 0; i < edat->nframes; i++) { - eneint[0][i+1] = eneint[0][i] + 0.5*(edat->s[1].es[i].sum + edat->s[3].es[i].sum)*Dt/edat->points[i]; - eneint[1][i+1] = eneint[1][i] + 0.5*(edat->s[2].es[i].sum + edat->s[6].es[i].sum)*Dt/edat->points[i]; - eneint[2][i+1] = eneint[2][i] + 0.5*(edat->s[5].es[i].sum + edat->s[7].es[i].sum)*Dt/edat->points[i]; + eneint[0][i + 1] = + eneint[0][i] + + 0.5 * (edat->s[1].es[i].sum + edat->s[3].es[i].sum) * Dt / edat->points[i]; + eneint[1][i + 1] = + eneint[1][i] + + 0.5 * (edat->s[2].es[i].sum + edat->s[6].es[i].sum) * Dt / edat->points[i]; + eneint[2][i + 1] = + eneint[2][i] + + 0.5 * (edat->s[5].es[i].sum + edat->s[7].es[i].sum) * Dt / edat->points[i]; } - einstein_visco(eviscofn, eviscoifn, - 3, edat->nframes+1, eneint, Vaver, Temp, Dt, oenv); + einstein_visco(eviscofn, eviscoifn, 3, edat->nframes + 1, eneint, Vaver, Temp, Dt, oenv); for (i = 0; i < 3; i++) { @@ -1131,17 +1147,15 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, /*do_autocorr(corrfn,buf,nenergy,3,eneset,Dt,eacNormal,TRUE);*/ /* Do it for shear viscosity */ std::strcpy(buf, "Shear Viscosity"); - low_do_autocorr(corrfn, oenv, buf, edat->nframes, 3, - (edat->nframes+1)/2, eneset, Dt, - eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0); + low_do_autocorr(corrfn, oenv, buf, edat->nframes, 3, (edat->nframes + 1) / 2, eneset, + Dt, eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0); /* Now for bulk viscosity */ std::strcpy(buf, "Bulk Viscosity"); - low_do_autocorr(corrfn, oenv, buf, edat->nframes, 1, - (edat->nframes+1)/2, &(eneset[11]), Dt, - eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0); + low_do_autocorr(corrfn, oenv, buf, edat->nframes, 1, (edat->nframes + 1) / 2, + &(eneset[11]), Dt, eacNormal, 1, TRUE, FALSE, FALSE, 0.0, 0.0, 0); - factor = (Vaver*1e-26/(BOLTZMANN*Temp))*Dt; + factor = (Vaver * 1e-26 / (BOLTZMANN * Temp)) * Dt; fp = xvgropen(visfn, buf, "Time (ps)", "\\8h\\4 (cp)", oenv); xvgr_legend(fp, asize(leg), leg, oenv); @@ -1149,15 +1163,15 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, integral = 0; intBulk = 0; nout = get_acfnout(); - if ((nout < 2) || (nout >= edat->nframes/2)) + if ((nout < 2) || (nout >= edat->nframes / 2)) { - nout = edat->nframes/2; + nout = edat->nframes / 2; } for (i = 1; (i < nout); i++) { - integral += 0.5*(eneset[0][i-1] + eneset[0][i])*factor; - intBulk += 0.5*(eneset[11][i-1] + eneset[11][i])*factor; - fprintf(fp, "%10g %10g %10g\n", (i*Dt), integral, intBulk); + integral += 0.5 * (eneset[0][i - 1] + eneset[0][i]) * factor; + intBulk += 0.5 * (eneset[11][i - 1] + eneset[11][i]) * factor; + fprintf(fp, "%10g %10g %10g\n", (i * Dt), integral, intBulk); } xvgrclose(fp); @@ -1187,12 +1201,12 @@ static void analyse_ener(gmx_bool bCorr, const char *corrfn, } } -static void print_time(FILE *fp, double t) +static void print_time(FILE* fp, double t) { fprintf(fp, "%12.6f", t); } -static void print1(FILE *fp, gmx_bool bDp, real e) +static void print1(FILE* fp, gmx_bool bDp, real e) { if (bDp) { @@ -1204,25 +1218,27 @@ static void print1(FILE *fp, gmx_bool bDp, real e) } } -static void fec(const char *ene2fn, const char *runavgfn, - real reftemp, int nset, const int set[], char *leg[], - enerdata_t *edat, double time[], - const gmx_output_env_t *oenv) +static void fec(const char* ene2fn, + const char* runavgfn, + real reftemp, + int nset, + const int set[], + char* leg[], + enerdata_t* edat, + double time[], + const gmx_output_env_t* oenv) { - const char * ravgleg[] = { - "\\8D\\4E = E\\sB\\N-E\\sA\\N", - "\\s0..t\\N" - }; - FILE *fp; + const char* ravgleg[] = { "\\8D\\4E = E\\sB\\N-E\\sA\\N", "\\s0..t\\N" }; + FILE* fp; ener_file_t enx; int timecheck, nenergy, nenergy2, maxenergy; int i, j; gmx_bool bCont; real aver, beta; - real **eneset2; + real** eneset2; double dE, sum; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; char buf[22]; /* read second energy file */ @@ -1231,7 +1247,7 @@ static void fec(const char *ene2fn, const char *runavgfn, enx = open_enx(ene2fn, "r"); do_enxnms(enx, &(fr->nre), &enm); - snew(eneset2, nset+1); + snew(eneset2, nset + 1); nenergy2 = 0; maxenergy = 0; timecheck = 0; @@ -1249,8 +1265,7 @@ static void fec(const char *ene2fn, const char *runavgfn, timecheck = check_times(fr->t); } - } - while (bCont && (timecheck < 0)); + } while (bCont && (timecheck < 0)); /* Store energies for analysis afterwards... */ if ((timecheck == 0) && bCont) @@ -1269,8 +1284,8 @@ static void fec(const char *ene2fn, const char *runavgfn, if (fr->t != time[nenergy2]) { - fprintf(stderr, "\nWARNING time mismatch %g!=%g at frame %s\n", - fr->t, time[nenergy2], gmx_step_str(fr->step, buf)); + fprintf(stderr, "\nWARNING time mismatch %g!=%g at frame %s\n", fr->t, + time[nenergy2], gmx_step_str(fr->step, buf)); } for (i = 0; i < nset; i++) { @@ -1279,14 +1294,12 @@ static void fec(const char *ene2fn, const char *runavgfn, nenergy2++; } } - } - while (bCont && (timecheck == 0)); + } while (bCont && (timecheck == 0)); /* check */ if (edat->nframes != nenergy2) { - fprintf(stderr, "\nWARNING file length mismatch %d!=%d\n", - edat->nframes, nenergy2); + fprintf(stderr, "\nWARNING file length mismatch %d!=%d\n", edat->nframes, nenergy2); } nenergy = std::min(edat->nframes, nenergy2); @@ -1294,32 +1307,29 @@ static void fec(const char *ene2fn, const char *runavgfn, fp = nullptr; if (runavgfn) { - fp = xvgropen(runavgfn, "Running average free energy difference", - "Time (" unit_time ")", "\\8D\\4E (" unit_energy ")", oenv); + fp = xvgropen(runavgfn, "Running average free energy difference", "Time (" unit_time ")", + "\\8D\\4E (" unit_energy ")", oenv); xvgr_legend(fp, asize(ravgleg), ravgleg, oenv); } - fprintf(stdout, "\n%-24s %10s\n", - "Energy", "dF = -kT ln < exp(-(EB-EA)/kT) >A"); + fprintf(stdout, "\n%-24s %10s\n", "Energy", "dF = -kT ln < exp(-(EB-EA)/kT) >A"); sum = 0; - beta = 1.0/(BOLTZ*reftemp); + beta = 1.0 / (BOLTZ * reftemp); for (i = 0; i < nset; i++) { if (gmx_strcasecmp(leg[i], enm[set[i]].name) != 0) { - fprintf(stderr, "\nWARNING energy set name mismatch %s!=%s\n", - leg[i], enm[set[i]].name); + fprintf(stderr, "\nWARNING energy set name mismatch %s!=%s\n", leg[i], enm[set[i]].name); } for (j = 0; j < nenergy; j++) { - dE = eneset2[i][j] - edat->s[i].ener[j]; - sum += std::exp(-dE*beta); + dE = eneset2[i][j] - edat->s[i].ener[j]; + sum += std::exp(-dE * beta); if (fp) { - fprintf(fp, "%10g %10g %10g\n", - time[j], dE, -BOLTZ*reftemp*std::log(sum/(j+1)) ); + fprintf(fp, "%10g %10g %10g\n", time[j], dE, -BOLTZ * reftemp * std::log(sum / (j + 1))); } } - aver = -BOLTZ*reftemp*std::log(sum/nenergy); + aver = -BOLTZ * reftemp * std::log(sum / nenergy); fprintf(stdout, "%-24s %10g\n", leg[i], aver); } if (fp) @@ -1330,21 +1340,27 @@ static void fec(const char *ene2fn, const char *runavgfn, } -static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, - const char *filename, gmx_bool bDp, - int *blocks, int *hists, int *samples, int *nlambdas, - const gmx_output_env_t *oenv) +static void do_dhdl(t_enxframe* fr, + const t_inputrec* ir, + FILE** fp_dhdl, + const char* filename, + gmx_bool bDp, + int* blocks, + int* hists, + int* samples, + int* nlambdas, + const gmx_output_env_t* oenv) { - const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda"; - char title[STRLEN], label_x[STRLEN], label_y[STRLEN], legend[STRLEN]; - char buf[STRLEN]; - int nblock_hist = 0, nblock_dh = 0, nblock_dhcoll = 0; - int i, j, k; + const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda"; + char title[STRLEN], label_x[STRLEN], label_y[STRLEN], legend[STRLEN]; + char buf[STRLEN]; + int nblock_hist = 0, nblock_dh = 0, nblock_dhcoll = 0; + int i, j, k; /* coll data */ - double temp = 0, start_time = 0, delta_time = 0, start_lambda = 0; + double temp = 0, start_time = 0, delta_time = 0, start_lambda = 0; static int setnr = 0; - double *native_lambda_vec = nullptr; - const char **lambda_components = nullptr; + double* native_lambda_vec = nullptr; + const char** lambda_components = nullptr; int n_lambda_vec = 0; bool firstPass = true; @@ -1362,18 +1378,17 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, else if (fr->block[i].id == enxDHCOLL) { nblock_dhcoll++; - if ( (fr->block[i].nsub < 1) || - (fr->block[i].sub[0].type != xdr_datatype_double) || - (fr->block[i].sub[0].nr < 5)) + if ((fr->block[i].nsub < 1) || (fr->block[i].sub[0].type != xdr_datatype_double) + || (fr->block[i].sub[0].nr < 5)) { gmx_fatal(FARGS, "Unexpected block data"); } /* read the data from the DHCOLL block */ - temp = fr->block[i].sub[0].dval[0]; - start_time = fr->block[i].sub[0].dval[1]; - delta_time = fr->block[i].sub[0].dval[2]; - start_lambda = fr->block[i].sub[0].dval[3]; + temp = fr->block[i].sub[0].dval[0]; + start_time = fr->block[i].sub[0].dval[1]; + delta_time = fr->block[i].sub[0].dval[2]; + start_lambda = fr->block[i].sub[0].dval[3]; if (fr->block[i].nsub > 1) { if (firstPass) @@ -1387,15 +1402,13 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, { if (n_lambda_vec != fr->block[i].sub[1].ival[1]) { - gmx_fatal(FARGS, - "Unexpected change of basis set in lambda"); + gmx_fatal(FARGS, "Unexpected change of basis set in lambda"); } } for (j = 0; j < n_lambda_vec; j++) { - native_lambda_vec[j] = fr->block[i].sub[0].dval[5+j]; - lambda_components[j] = - efpt_singular_names[fr->block[i].sub[1].ival[2+j]]; + native_lambda_vec[j] = fr->block[i].sub[0].dval[5 + j]; + lambda_components[j] = efpt_singular_names[fr->block[i].sub[1].ival[2 + j]]; } } } @@ -1410,7 +1423,9 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, } if (nblock_hist > 0 && nblock_dh > 0) { - gmx_fatal(FARGS, "This energy file contains both histogram dhdl data and non-histogram dhdl data. Don't know what to do."); + gmx_fatal(FARGS, + "This energy file contains both histogram dhdl data and non-histogram dhdl data. " + "Don't know what to do."); } if (!*fp_dhdl) { @@ -1435,9 +1450,9 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, } } - (*hists) += nblock_hist; - (*blocks) += nblock_dh; - (*nlambdas) = nblock_hist+nblock_dh; + (*hists) += nblock_hist; + (*blocks) += nblock_dh; + (*nlambdas) = nblock_hist + nblock_dh; /* write the data */ if (nblock_hist > 0) @@ -1446,19 +1461,17 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, /* histograms */ for (i = 0; i < fr->nblock; i++) { - t_enxblock *blk = &(fr->block[i]); + t_enxblock* blk = &(fr->block[i]); if (blk->id == enxDHHIST) { - double foreign_lambda, dx; - int64_t x0; - int nhist, derivative; + double foreign_lambda, dx; + int64_t x0; + int nhist, derivative; /* check the block types etc. */ - if ( (blk->nsub < 2) || - (blk->sub[0].type != xdr_datatype_double) || - (blk->sub[1].type != xdr_datatype_int64) || - (blk->sub[0].nr < 2) || - (blk->sub[1].nr < 2) ) + if ((blk->nsub < 2) || (blk->sub[0].type != xdr_datatype_double) + || (blk->sub[1].type != xdr_datatype_int64) || (blk->sub[0].nr < 2) + || (blk->sub[1].nr < 2)) { gmx_fatal(FARGS, "Unexpected block data in file"); } @@ -1468,34 +1481,31 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, derivative = blk->sub[1].lval[1]; for (j = 0; j < nhist; j++) { - const char *lg[1]; - x0 = blk->sub[1].lval[2+j]; + const char* lg[1]; + x0 = blk->sub[1].lval[2 + j]; if (!derivative) { - sprintf(legend, "N(%s(%s=%g) | %s=%g)", - deltag, lambda, foreign_lambda, + sprintf(legend, "N(%s(%s=%g) | %s=%g)", deltag, lambda, foreign_lambda, lambda, start_lambda); } else { - sprintf(legend, "N(%s | %s=%g)", - dhdl, lambda, start_lambda); + sprintf(legend, "N(%s | %s=%g)", dhdl, lambda, start_lambda); } lg[0] = legend; xvgr_new_dataset(*fp_dhdl, setnr, 1, lg, oenv); setnr++; - for (k = 0; k < blk->sub[j+2].nr; k++) + for (k = 0; k < blk->sub[j + 2].nr; k++) { int hist; double xmin, xmax; - hist = blk->sub[j+2].ival[k]; - xmin = (x0+k)*dx; - xmax = (x0+k+1)*dx; - fprintf(*fp_dhdl, "%g %d\n%g %d\n", xmin, hist, - xmax, hist); + hist = blk->sub[j + 2].ival[k]; + xmin = (x0 + k) * dx; + xmax = (x0 + k + 1) * dx; + fprintf(*fp_dhdl, "%g %d\n%g %d\n", xmin, hist, xmax, hist); sum += hist; } /* multiple histogram data blocks in one histogram @@ -1506,16 +1516,16 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, } } } - (*samples) += static_cast(sum/nblock_hist); + (*samples) += static_cast(sum / nblock_hist); } else { /* raw dh */ - int len = 0; + int len = 0; for (i = 0; i < fr->nblock; i++) { - t_enxblock *blk = &(fr->block[i]); + t_enxblock* blk = &(fr->block[i]); if (blk->id == enxDH) { if (len == 0) @@ -1535,13 +1545,13 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, for (i = 0; i < len; i++) { - double time = start_time + delta_time*i; + double time = start_time + delta_time * i; fprintf(*fp_dhdl, "%.4f ", time); for (j = 0; j < fr->nblock; j++) { - t_enxblock *blk = &(fr->block[j]); + t_enxblock* blk = &(fr->block[j]); if (blk->id == enxDH) { double value; @@ -1557,17 +1567,18 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, if (j == 1 && ir->bExpanded) { - fprintf(*fp_dhdl, "%4d", static_cast(value)); /* if expanded ensembles and zero, this is a state value, it's an integer. We need a cleaner conditional than if j==1! */ + fprintf(*fp_dhdl, "%4d", + static_cast(value)); /* if expanded ensembles and zero, this is a state value, it's an integer. We need a cleaner conditional than if j==1! */ } else { if (bDp) { - fprintf(*fp_dhdl, " %#.12g", value); /* print normal precision */ + fprintf(*fp_dhdl, " %#.12g", value); /* print normal precision */ } else { - fprintf(*fp_dhdl, " %#.8g", value); /* print normal precision */ + fprintf(*fp_dhdl, " %#.8g", value); /* print normal precision */ } } } @@ -1578,9 +1589,9 @@ static void do_dhdl(t_enxframe *fr, const t_inputrec *ir, FILE **fp_dhdl, } -int gmx_energy(int argc, char *argv[]) +int gmx_energy(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] extracts energy components", "from an energy file. The user is prompted to interactively", "select the desired energy terms.[PAR]", @@ -1628,8 +1639,10 @@ int gmx_energy(int argc, char *argv[]) "With [TT]-fee[tt] an estimate is calculated for the free-energy", "difference with an ideal gas state::", "", - " [GRK]Delta[grk] A = A(N,V,T) - A[SUB]idealgas[sub](N,V,T) = kT [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln]", - " [GRK]Delta[grk] G = G(N,p,T) - G[SUB]idealgas[sub](N,p,T) = kT [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln]", + " [GRK]Delta[grk] A = A(N,V,T) - A[SUB]idealgas[sub](N,V,T) = kT ", + " [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln]", + " [GRK]Delta[grk] G = G(N,p,T) - G[SUB]idealgas[sub](N,p,T) = kT ", + " [LN][CHEVRON][EXP]U[SUB]pot[sub]/kT[exp][chevron][ln]", "", "where k is Boltzmann's constant, T is set by [TT]-fetemp[tt] and", "the average is over the ensemble (or time in a trajectory).", @@ -1638,14 +1651,18 @@ int gmx_energy(int argc, char *argv[]) "and using the potential energy. This also allows for an entropy", "estimate using::", "", - " [GRK]Delta[grk] S(N,V,T) = S(N,V,T) - S[SUB]idealgas[sub](N,V,T) = ([CHEVRON]U[SUB]pot[sub][chevron] - [GRK]Delta[grk] A)/T", - " [GRK]Delta[grk] S(N,p,T) = S(N,p,T) - S[SUB]idealgas[sub](N,p,T) = ([CHEVRON]U[SUB]pot[sub][chevron] + pV - [GRK]Delta[grk] G)/T", + " [GRK]Delta[grk] S(N,V,T) = S(N,V,T) - S[SUB]idealgas[sub](N,V,T) = ", + " ([CHEVRON]U[SUB]pot[sub][chevron] - [GRK]Delta[grk] A)/T", + " [GRK]Delta[grk] S(N,p,T) = S(N,p,T) - S[SUB]idealgas[sub](N,p,T) = ", + " ([CHEVRON]U[SUB]pot[sub][chevron] + pV - [GRK]Delta[grk] G)/T", "", "When a second energy file is specified ([TT]-f2[tt]), a free energy", "difference is calculated::", "", - " dF = -kT [LN][CHEVRON][EXP]-(E[SUB]B[sub]-E[SUB]A[sub])/kT[exp][chevron][SUB]A[sub][ln] ,", + " dF = -kT ", + " [LN][CHEVRON][EXP]-(E[SUB]B[sub]-E[SUB]A[sub]) / ", + " kT[exp][chevron][SUB]A[sub][ln],", "", "where E[SUB]A[sub] and E[SUB]B[sub] are the energies from the first and second energy", "files, and the average is over the ensemble A. The running average", @@ -1653,101 +1670,111 @@ int gmx_energy(int argc, char *argv[]) "[BB]Note[bb] that the energies must both be calculated from the same trajectory." }; - static gmx_bool bSum = FALSE, bFee = FALSE, bPrAll = FALSE, bFluct = FALSE, bDriftCorr = FALSE; - static gmx_bool bDp = FALSE, bMutot = FALSE, bOrinst = FALSE, bOvec = FALSE, bFluctProps = FALSE; - static int nmol = 1, nbmin = 5, nbmax = 5; - static real reftemp = 300.0, ezero = 0; - t_pargs pa[] = { - { "-fee", FALSE, etBOOL, {&bFee}, - "Do a free energy estimate" }, - { "-fetemp", FALSE, etREAL, {&reftemp}, + static gmx_bool bSum = FALSE, bFee = FALSE, bPrAll = FALSE, bFluct = FALSE, bDriftCorr = FALSE; + static gmx_bool bDp = FALSE, bMutot = FALSE, bOrinst = FALSE, bOvec = FALSE, bFluctProps = FALSE; + static int nmol = 1, nbmin = 5, nbmax = 5; + static real reftemp = 300.0, ezero = 0; + t_pargs pa[] = { + { "-fee", FALSE, etBOOL, { &bFee }, "Do a free energy estimate" }, + { "-fetemp", + FALSE, + etREAL, + { &reftemp }, "Reference temperature for free energy calculation" }, - { "-zero", FALSE, etREAL, {&ezero}, - "Subtract a zero-point energy" }, - { "-sum", FALSE, etBOOL, {&bSum}, + { "-zero", FALSE, etREAL, { &ezero }, "Subtract a zero-point energy" }, + { "-sum", + FALSE, + etBOOL, + { &bSum }, "Sum the energy terms selected rather than display them all" }, - { "-dp", FALSE, etBOOL, {&bDp}, - "Print energies in high precision" }, - { "-nbmin", FALSE, etINT, {&nbmin}, - "Minimum number of blocks for error estimate" }, - { "-nbmax", FALSE, etINT, {&nbmax}, - "Maximum number of blocks for error estimate" }, - { "-mutot", FALSE, etBOOL, {&bMutot}, + { "-dp", FALSE, etBOOL, { &bDp }, "Print energies in high precision" }, + { "-nbmin", FALSE, etINT, { &nbmin }, "Minimum number of blocks for error estimate" }, + { "-nbmax", FALSE, etINT, { &nbmax }, "Maximum number of blocks for error estimate" }, + { "-mutot", + FALSE, + etBOOL, + { &bMutot }, "Compute the total dipole moment from the components" }, - { "-aver", FALSE, etBOOL, {&bPrAll}, - "Also print the exact average and rmsd stored in the energy frames (only when 1 term is requested)" }, - { "-nmol", FALSE, etINT, {&nmol}, + { "-aver", + FALSE, + etBOOL, + { &bPrAll }, + "Also print the exact average and rmsd stored in the energy frames (only when 1 term is " + "requested)" }, + { "-nmol", + FALSE, + etINT, + { &nmol }, "Number of molecules in your sample: the energies are divided by this number" }, - { "-fluct_props", FALSE, etBOOL, {&bFluctProps}, + { "-fluct_props", + FALSE, + etBOOL, + { &bFluctProps }, "Compute properties based on energy fluctuations, like heat capacity" }, - { "-driftcorr", FALSE, etBOOL, {&bDriftCorr}, - "Useful only for calculations of fluctuation properties. The drift in the observables will be subtracted before computing the fluctuation properties."}, - { "-fluc", FALSE, etBOOL, {&bFluct}, + { "-driftcorr", + FALSE, + etBOOL, + { &bDriftCorr }, + "Useful only for calculations of fluctuation properties. The drift in the observables " + "will be subtracted before computing the fluctuation properties." }, + { "-fluc", + FALSE, + etBOOL, + { &bFluct }, "Calculate autocorrelation of energy fluctuations rather than energy itself" }, - { "-orinst", FALSE, etBOOL, {&bOrinst}, - "Analyse instantaneous orientation data" }, - { "-ovec", FALSE, etBOOL, {&bOvec}, - "Also plot the eigenvectors with [TT]-oten[tt]" } - }; - static const char *setnm[] = { - "Pres-XX", "Pres-XY", "Pres-XZ", "Pres-YX", "Pres-YY", - "Pres-YZ", "Pres-ZX", "Pres-ZY", "Pres-ZZ", "Temperature", - "Volume", "Pressure" + { "-orinst", FALSE, etBOOL, { &bOrinst }, "Analyse instantaneous orientation data" }, + { "-ovec", FALSE, etBOOL, { &bOvec }, "Also plot the eigenvectors with [TT]-oten[tt]" } }; - - FILE *out = nullptr; - FILE *fp_dhdl = nullptr; - ener_file_t fp; - int timecheck = 0; - enerdata_t edat; - gmx_enxnm_t *enm = nullptr; - t_enxframe *frame, *fr = nullptr; - int cur = 0; -#define NEXT (1-cur) - int nre, nfr; - int64_t start_step; - real start_t; - gmx_bool bDHDL; - gmx_bool bFoundStart, bCont, bVisco; - double sum, dbl; - double *time = nullptr; - real Vaver; - int *set = nullptr, i, j, nset, sss; - gmx_bool *bIsEner = nullptr; - char **leg = nullptr; - char buf[256]; - gmx_output_env_t *oenv; - int dh_blocks = 0, dh_hists = 0, dh_samples = 0, dh_lambdas = 0; - - t_filenm fnm[] = { - { efEDR, "-f", nullptr, ffREAD }, - { efEDR, "-f2", nullptr, ffOPTRD }, - { efTPR, "-s", nullptr, ffOPTRD }, - { efXVG, "-o", "energy", ffWRITE }, - { efXVG, "-viol", "violaver", ffOPTWR }, - { efXVG, "-pairs", "pairs", ffOPTWR }, - { efXVG, "-corr", "enecorr", ffOPTWR }, - { efXVG, "-vis", "visco", ffOPTWR }, - { efXVG, "-evisco", "evisco", ffOPTWR }, - { efXVG, "-eviscoi", "eviscoi", ffOPTWR }, - { efXVG, "-ravg", "runavgdf", ffOPTWR }, - { efXVG, "-odh", "dhdl", ffOPTWR } + static const char* setnm[] = { "Pres-XX", "Pres-XY", "Pres-XZ", "Pres-YX", + "Pres-YY", "Pres-YZ", "Pres-ZX", "Pres-ZY", + "Pres-ZZ", "Temperature", "Volume", "Pressure" }; + + FILE* out = nullptr; + FILE* fp_dhdl = nullptr; + ener_file_t fp; + int timecheck = 0; + enerdata_t edat; + gmx_enxnm_t* enm = nullptr; + t_enxframe * frame, *fr = nullptr; + int cur = 0; +#define NEXT (1 - cur) + int nre, nfr; + int64_t start_step; + real start_t; + gmx_bool bDHDL; + gmx_bool bFoundStart, bCont, bVisco; + double sum, dbl; + double* time = nullptr; + real Vaver; + int * set = nullptr, i, j, nset, sss; + gmx_bool* bIsEner = nullptr; + char** leg = nullptr; + char buf[256]; + gmx_output_env_t* oenv; + int dh_blocks = 0, dh_hists = 0, dh_samples = 0, dh_lambdas = 0; + + t_filenm fnm[] = { + { efEDR, "-f", nullptr, ffREAD }, { efEDR, "-f2", nullptr, ffOPTRD }, + { efTPR, "-s", nullptr, ffOPTRD }, { efXVG, "-o", "energy", ffWRITE }, + { efXVG, "-viol", "violaver", ffOPTWR }, { efXVG, "-pairs", "pairs", ffOPTWR }, + { efXVG, "-corr", "enecorr", ffOPTWR }, { efXVG, "-vis", "visco", ffOPTWR }, + { efXVG, "-evisco", "evisco", ffOPTWR }, { efXVG, "-eviscoi", "eviscoi", ffOPTWR }, + { efXVG, "-ravg", "runavgdf", ffOPTWR }, { efXVG, "-odh", "dhdl", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm, + npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; } - bDHDL = opt2bSet("-odh", NFILE, fnm); + bDHDL = opt2bSet("-odh", NFILE, fnm); nset = 0; @@ -1760,7 +1787,7 @@ int gmx_energy(int argc, char *argv[]) bVisco = opt2bSet("-vis", NFILE, fnm); t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec* ir = &irInstance; if (!bDHDL) { @@ -1792,8 +1819,7 @@ int gmx_energy(int argc, char *argv[]) } else { - gmx_fatal(FARGS, "Could not find term %s for viscosity calculation", - setnm[j]); + gmx_fatal(FARGS, "Could not find term %s for viscosity calculation", setnm[j]); } } } @@ -1820,10 +1846,9 @@ int gmx_energy(int argc, char *argv[]) std::strcat(buf, ")"); } } - out = xvgropen(opt2fn("-o", NFILE, fnm), "GROMACS Energies", "Time (ps)", buf, - oenv); + out = xvgropen(opt2fn("-o", NFILE, fnm), "GROMACS Energies", "Time (ps)", buf, oenv); - snew(leg, nset+1); + snew(leg, nset + 1); for (i = 0; (i < nset); i++) { leg[i] = enm[set[i]].name; @@ -1831,7 +1856,7 @@ int gmx_energy(int argc, char *argv[]) if (bSum) { leg[nset] = gmx_strdup("Sum"); - xvgr_legend(out, nset+1, leg, oenv); + xvgr_legend(out, nset + 1, leg, oenv); } else { @@ -1844,15 +1869,14 @@ int gmx_energy(int argc, char *argv[]) bIsEner[i] = FALSE; for (j = 0; (j <= F_ETOT); j++) { - bIsEner[i] = bIsEner[i] || - (gmx_strcasecmp(interaction_function[j].longname, leg[i]) == 0); + bIsEner[i] = bIsEner[i] + || (gmx_strcasecmp(interaction_function[j].longname, leg[i]) == 0); } } if (bPrAll && nset > 1) { gmx_fatal(FARGS, "Printing averages can only be done when a single set is selected"); } - } else if (bDHDL) { @@ -1870,9 +1894,9 @@ int gmx_energy(int argc, char *argv[]) snew(edat.s, nset); /* Initiate counters */ - bFoundStart = FALSE; - start_step = 0; - start_t = 0; + bFoundStart = FALSE; + start_step = 0; + start_t = 0; do { /* This loop searches for the first frame (when -b option is given), @@ -1885,8 +1909,7 @@ int gmx_energy(int argc, char *argv[]) { timecheck = check_times(frame[NEXT].t); } - } - while (bCont && (timecheck < 0)); + } while (bCont && (timecheck < 0)); if ((timecheck == 0) && bCont) { @@ -1896,25 +1919,23 @@ int gmx_energy(int argc, char *argv[]) if (fr->nre > 0) { /* The frame contains energies, so update cur */ - cur = NEXT; + cur = NEXT; if (edat.nframes % 1000 == 0) { - srenew(edat.step, edat.nframes+1000); - std::memset(&(edat.step[edat.nframes]), 0, 1000*sizeof(edat.step[0])); - srenew(edat.steps, edat.nframes+1000); - std::memset(&(edat.steps[edat.nframes]), 0, 1000*sizeof(edat.steps[0])); - srenew(edat.points, edat.nframes+1000); - std::memset(&(edat.points[edat.nframes]), 0, 1000*sizeof(edat.points[0])); + srenew(edat.step, edat.nframes + 1000); + std::memset(&(edat.step[edat.nframes]), 0, 1000 * sizeof(edat.step[0])); + srenew(edat.steps, edat.nframes + 1000); + std::memset(&(edat.steps[edat.nframes]), 0, 1000 * sizeof(edat.steps[0])); + srenew(edat.points, edat.nframes + 1000); + std::memset(&(edat.points[edat.nframes]), 0, 1000 * sizeof(edat.points[0])); for (i = 0; i < nset; i++) { - srenew(edat.s[i].ener, edat.nframes+1000); - std::memset(&(edat.s[i].ener[edat.nframes]), 0, - 1000*sizeof(edat.s[i].ener[0])); - srenew(edat.s[i].es, edat.nframes+1000); - std::memset(&(edat.s[i].es[edat.nframes]), 0, - 1000*sizeof(edat.s[i].es[0])); + srenew(edat.s[i].ener, edat.nframes + 1000); + std::memset(&(edat.s[i].ener[edat.nframes]), 0, 1000 * sizeof(edat.s[i].ener[0])); + srenew(edat.s[i].es, edat.nframes + 1000); + std::memset(&(edat.s[i].es[edat.nframes]), 0, 1000 * sizeof(edat.s[i].es[0])); } } @@ -1955,7 +1976,7 @@ int gmx_energy(int argc, char *argv[]) edat.s[i].es[nfr].sum = fr->ener[sss].e; edat.s[i].es[nfr].sum2 = 0; } - edat.npoints += 1; + edat.npoints += 1; edat.bHaveSums = FALSE; } else if (fr->step - start_step + 1 == edat.nsteps + fr->nsteps) @@ -1992,14 +2013,15 @@ int gmx_energy(int argc, char *argv[]) { if (edat.nframes % 1000 == 0) { - srenew(time, edat.nframes+1000); + srenew(time, edat.nframes + 1000); } time[edat.nframes] = fr->t; edat.nframes++; } if (bDHDL) { - do_dhdl(fr, ir, &fp_dhdl, opt2fn("-odh", NFILE, fnm), bDp, &dh_blocks, &dh_hists, &dh_samples, &dh_lambdas, oenv); + do_dhdl(fr, ir, &fp_dhdl, opt2fn("-odh", NFILE, fnm), bDp, &dh_blocks, &dh_hists, + &dh_samples, &dh_lambdas, oenv); } /******************************************* @@ -2018,8 +2040,8 @@ int gmx_energy(int argc, char *argv[]) { print_time(out, fr->t); print1(out, bDp, fr->ener[set[0]].e); - print1(out, bDp, fr->ener[set[0]].esum/fr->nsum); - print1(out, bDp, std::sqrt(fr->ener[set[0]].eav/fr->nsum)); + print1(out, bDp, fr->ener[set[0]].esum / fr->nsum); + print1(out, bDp, std::sqrt(fr->ener[set[0]].eav / fr->nsum)); fprintf(out, "\n"); } } @@ -2033,7 +2055,7 @@ int gmx_energy(int argc, char *argv[]) { sum += fr->ener[set[i]].e; } - print1(out, bDp, sum/nmol-ezero); + print1(out, bDp, sum / nmol - ezero); } else { @@ -2041,7 +2063,7 @@ int gmx_energy(int argc, char *argv[]) { if (bIsEner[i]) { - print1(out, bDp, (fr->ener[set[i]].e)/nmol-ezero); + print1(out, bDp, (fr->ener[set[i]].e) / nmol - ezero); } else { @@ -2054,8 +2076,7 @@ int gmx_energy(int argc, char *argv[]) } } } - } - while (bCont && (timecheck == 0)); + } while (bCont && (timecheck == 0)); fprintf(stderr, "\n"); done_ener_file(fp); @@ -2069,8 +2090,7 @@ int gmx_energy(int argc, char *argv[]) if (fp_dhdl) { gmx_fio_fclose(fp_dhdl); - printf("\n\nWrote %d lambda values with %d samples as ", - dh_lambdas, dh_samples); + printf("\n\nWrote %d lambda values with %d samples as ", dh_lambdas, dh_samples); if (dh_hists > 0) { printf("%d dH histograms ", dh_hists); @@ -2080,36 +2100,29 @@ int gmx_energy(int argc, char *argv[]) printf("%d dH data blocks ", dh_blocks); } printf("to %s\n", opt2fn("-odh", NFILE, fnm)); - } else { gmx_fatal(FARGS, "No dH data in %s\n", opt2fn("-f", NFILE, fnm)); } - } else { - double dt = (frame[cur].t-start_t)/(edat.nframes-1); + double dt = (frame[cur].t - start_t) / (edat.nframes - 1); analyse_ener(opt2bSet("-corr", NFILE, fnm), opt2fn("-corr", NFILE, fnm), - opt2fn("-evisco", NFILE, fnm), opt2fn("-eviscoi", NFILE, fnm), - bFee, bSum, bFluct, - bVisco, opt2fn("-vis", NFILE, fnm), - nmol, - start_step, start_t, frame[cur].step, frame[cur].t, - reftemp, &edat, - nset, set, bIsEner, leg, enm, Vaver, ezero, nbmin, nbmax, - oenv); + opt2fn("-evisco", NFILE, fnm), opt2fn("-eviscoi", NFILE, fnm), bFee, bSum, + bFluct, bVisco, opt2fn("-vis", NFILE, fnm), nmol, start_step, start_t, + frame[cur].step, frame[cur].t, reftemp, &edat, nset, set, bIsEner, leg, enm, + Vaver, ezero, nbmin, nbmax, oenv); if (bFluctProps) { - calc_fluctuation_props(stdout, bDriftCorr, dt, nset, nmol, leg, &edat, - nbmin, nbmax); + calc_fluctuation_props(stdout, bDriftCorr, dt, nset, nmol, leg, &edat, nbmin, nbmax); } } if (opt2bSet("-f2", NFILE, fnm)) { - fec(opt2fn("-f2", NFILE, fnm), opt2fn("-ravg", NFILE, fnm), - reftemp, nset, set, leg, &edat, time, oenv); + fec(opt2fn("-f2", NFILE, fnm), opt2fn("-ravg", NFILE, fnm), reftemp, nset, set, leg, &edat, + time, oenv); } // Clean up! done_enerdata_t(nset, &edat); @@ -2123,7 +2136,7 @@ int gmx_energy(int argc, char *argv[]) sfree(leg); sfree(bIsEner); { - const char *nxy = "-nxy"; + const char* nxy = "-nxy"; do_view(oenv, opt2fn("-o", NFILE, fnm), nxy); do_view(oenv, opt2fn_null("-ravg", NFILE, fnm), nxy); diff --git a/src/gromacs/gmxana/gmx_filter.cpp b/src/gromacs/gmxana/gmx_filter.cpp index ca7d7c41fd..45505439f4 100644 --- a/src/gromacs/gmxana/gmx_filter.cpp +++ b/src/gromacs/gmxana/gmx_filter.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,9 +53,9 @@ #include "gromacs/utility/arraysize.h" #include "gromacs/utility/smalloc.h" -int gmx_filter(int argc, char *argv[]) +int gmx_filter(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] performs frequency filtering on a trajectory.", "The filter shape is cos([GRK]pi[grk] t/A) + 1 from -A to +A, where A is given", "by the option [TT]-nf[tt] times the time step in the input trajectory.", @@ -79,49 +79,47 @@ int gmx_filter(int argc, char *argv[]) "the coordinates in the structure file." }; - static int nf = 10; - static gmx_bool bNoJump = TRUE, bFit = FALSE, bLowAll = FALSE; - t_pargs pa[] = { - { "-nf", FALSE, etINT, {&nf}, + static int nf = 10; + static gmx_bool bNoJump = TRUE, bFit = FALSE, bLowAll = FALSE; + t_pargs pa[] = { + { "-nf", + FALSE, + etINT, + { &nf }, "Sets the filter length as well as the output interval for low-pass filtering" }, - { "-all", FALSE, etBOOL, {&bLowAll}, - "Write all low-pass filtered frames" }, - { "-nojump", FALSE, etBOOL, {&bNoJump}, - "Remove jumps of atoms across the box" }, - { "-fit", FALSE, etBOOL, {&bFit}, - "Fit all frames to a reference structure" } + { "-all", FALSE, etBOOL, { &bLowAll }, "Write all low-pass filtered frames" }, + { "-nojump", FALSE, etBOOL, { &bNoJump }, "Remove jumps of atoms across the box" }, + { "-fit", FALSE, etBOOL, { &bFit }, "Fit all frames to a reference structure" } }; - const char *topfile, *lowfile, *highfile; + const char * topfile, *lowfile, *highfile; gmx_bool bTop = FALSE; t_topology top; int ePBC = -1; - rvec *xtop; + rvec* xtop; matrix topbox, *box, boxf; - char *grpname; + char* grpname; int isize; - int *index; - real *w_rls = nullptr; - t_trxstatus *in; - t_trxstatus *outl, *outh; + int* index; + real* w_rls = nullptr; + t_trxstatus* in; + t_trxstatus * outl, *outh; int nffr, i, fr, nat, j, d, m; - int *ind; + int* ind; real flen, *filt, sum, *t; rvec xcmtop, xcm, **x, *ptr, *xf, *xn, *xp, hbox; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; #define NLEG asize(leg) - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTRO, "-ol", "lowpass", ffOPTWR }, - { efTRO, "-oh", "highpass", ffOPTWR } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTRO, "-ol", "lowpass", ffOPTWR }, + { efTRO, "-oh", "highpass", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -139,8 +137,7 @@ int gmx_filter(int argc, char *argv[]) } if (topfile) { - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, - &xtop, nullptr, topbox, TRUE); + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, topbox, TRUE); if (bTop) { gpbc = gmx_rmpbc_init(&top.idef, ePBC, top.atoms.nr); @@ -167,15 +164,15 @@ int gmx_filter(int argc, char *argv[]) } /* The actual filter length flen can actually be any real number */ - flen = 2*nf; + flen = 2 * nf; /* nffr is the number of frames that we filter over */ - nffr = 2*nf - 1; + nffr = 2 * nf - 1; snew(filt, nffr); sum = 0; for (i = 0; i < nffr; i++) { - filt[i] = std::cos(2*M_PI*(i - nf + 1)/static_cast(flen)) + 1; - sum += filt[i]; + filt[i] = std::cos(2 * M_PI * (i - nf + 1) / static_cast(flen)) + 1; + sum += filt[i]; } fprintf(stdout, "filter weights:"); for (i = 0; i < nffr; i++) @@ -189,15 +186,14 @@ int gmx_filter(int argc, char *argv[]) snew(x, nffr); snew(box, nffr); - nat = read_first_x(oenv, &in, opt2fn("-f", NFILE, fnm), - &(t[nffr - 1]), &(x[nffr - 1]), box[nffr - 1]); + nat = read_first_x(oenv, &in, opt2fn("-f", NFILE, fnm), &(t[nffr - 1]), &(x[nffr - 1]), box[nffr - 1]); snew(ind, nat); for (i = 0; i < nat; i++) { ind[i] = i; } /* x[nffr - 1] was already allocated by read_first_x */ - for (i = 0; i < nffr-1; i++) + for (i = 0; i < nffr - 1; i++) { snew(x[i], nat); } @@ -230,12 +226,12 @@ int gmx_filter(int argc, char *argv[]) { for (d = 0; d < DIM; d++) { - hbox[d] = 0.5*box[nffr - 1][d][d]; + hbox[d] = 0.5 * box[nffr - 1][d][d]; } } for (i = 0; i < nat; i++) { - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { if (hbox[m] > 0) { @@ -288,21 +284,21 @@ int gmx_filter(int argc, char *argv[]) { for (d = 0; d < DIM; d++) { - xf[j][d] += filt[i]*x[i][j][d]; + xf[j][d] += filt[i] * x[i][j][d]; } } for (j = 0; j < DIM; j++) { for (d = 0; d < DIM; d++) { - boxf[j][d] += filt[i]*box[i][j][d]; + boxf[j][d] += filt[i] * box[i][j][d]; } } } if (outl && (bLowAll || fr % nf == nf - 1)) { - write_trx(outl, nat, ind, topfile ? &(top.atoms) : nullptr, - 0, t[nf - 1], bFit ? topbox : boxf, xf, nullptr, nullptr); + write_trx(outl, nat, ind, topfile ? &(top.atoms) : nullptr, 0, t[nf - 1], + bFit ? topbox : boxf, xf, nullptr, nullptr); } if (outh) { @@ -328,22 +324,21 @@ int gmx_filter(int argc, char *argv[]) boxf[j][d] = topbox[j][d] + box[nf - 1][j][d] - boxf[j][d]; } } - write_trx(outh, nat, ind, topfile ? &(top.atoms) : nullptr, - 0, t[nf - 1], bFit ? topbox : boxf, xf, nullptr, nullptr); + write_trx(outh, nat, ind, topfile ? &(top.atoms) : nullptr, 0, t[nf - 1], + bFit ? topbox : boxf, xf, nullptr, nullptr); } } /* Cycle all the pointer and the box by one */ ptr = x[0]; - for (i = 0; i < nffr-1; i++) + for (i = 0; i < nffr - 1; i++) { - t[i] = t[i+1]; - x[i] = x[i+1]; - copy_mat(box[i+1], box[i]); + t[i] = t[i + 1]; + x[i] = x[i + 1]; + copy_mat(box[i + 1], box[i]); } x[nffr - 1] = ptr; fr++; - } - while (read_next_x(oenv, in, &(t[nffr - 1]), x[nffr - 1], box[nffr - 1])); + } while (read_next_x(oenv, in, &(t[nffr - 1]), x[nffr - 1], box[nffr - 1])); if (bTop) { diff --git a/src/gromacs/gmxana/gmx_gyrate.cpp b/src/gromacs/gmxana/gmx_gyrate.cpp index 567854e574..d6340a56b0 100644 --- a/src/gromacs/gmxana/gmx_gyrate.cpp +++ b/src/gromacs/gmxana/gmx_gyrate.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,12 +59,21 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static real calc_gyro(rvec x[], int gnx, int index[], t_atom atom[], real tm, - rvec gvec, rvec d, gmx_bool bQ, gmx_bool bRot, gmx_bool bMOI, matrix trans) +static real calc_gyro(rvec x[], + int gnx, + int index[], + t_atom atom[], + real tm, + rvec gvec, + rvec d, + gmx_bool bQ, + gmx_bool bRot, + gmx_bool bMOI, + matrix trans) { - int i, ii, m; - real gyro, dx2, m0, Itot; - rvec comp; + int i, ii, m; + real gyro, dx2, m0, Itot; + rvec comp; if (bRot) { @@ -76,7 +85,7 @@ static real calc_gyro(rvec x[], int gnx, int index[], t_atom atom[], real tm, } for (m = 0; (m < DIM); m++) { - d[m] = std::sqrt(d[m]/tm); + d[m] = std::sqrt(d[m] / tm); } /* rotate_atoms(gnx,index,x,trans); */ } @@ -94,26 +103,24 @@ static real calc_gyro(rvec x[], int gnx, int index[], t_atom atom[], real tm, } for (m = 0; (m < DIM); m++) { - dx2 = x[ii][m]*x[ii][m]; - comp[m] += dx2*m0; + dx2 = x[ii][m] * x[ii][m]; + comp[m] += dx2 * m0; } } - gyro = comp[XX]+comp[YY]+comp[ZZ]; + gyro = comp[XX] + comp[YY] + comp[ZZ]; for (m = 0; (m < DIM); m++) { - gvec[m] = std::sqrt((gyro-comp[m])/tm); + gvec[m] = std::sqrt((gyro - comp[m]) / tm); } - return std::sqrt(gyro/tm); + return std::sqrt(gyro / tm); } -static void calc_gyro_z(rvec x[], matrix box, - int gnx, const int index[], t_atom atom[], - int nz, real time, FILE *out) +static void calc_gyro_z(rvec x[], matrix box, int gnx, const int index[], t_atom atom[], int nz, real time, FILE* out) { - static dvec *inertia = nullptr; - static double *tm = nullptr; + static dvec* inertia = nullptr; + static double* tm = nullptr; int i, ii, j, zi; real zf, w, sdet, e1, e2; @@ -132,7 +139,7 @@ static void calc_gyro_z(rvec x[], matrix box, for (i = 0; (i < gnx); i++) { ii = index[i]; - zf = nz*x[ii][ZZ]/box[ZZ][ZZ]; + zf = nz * x[ii][ZZ] / box[ZZ][ZZ]; if (zf >= nz) { zf -= nz; @@ -148,11 +155,11 @@ static void calc_gyro_z(rvec x[], matrix box, { zi = 0; } - w = atom[ii].m*(1 + std::cos(M_PI*(zf - zi))); - inertia[zi][0] += w*gmx::square(x[ii][YY]); - inertia[zi][1] += w*gmx::square(x[ii][XX]); - inertia[zi][2] -= w*x[ii][XX]*x[ii][YY]; - tm[zi] += w; + w = atom[ii].m * (1 + std::cos(M_PI * (zf - zi))); + inertia[zi][0] += w * gmx::square(x[ii][YY]); + inertia[zi][1] += w * gmx::square(x[ii][XX]); + inertia[zi][2] -= w * x[ii][XX] * x[ii][YY]; + tm[zi] += w; } } fprintf(out, "%10g", time); @@ -162,18 +169,18 @@ static void calc_gyro_z(rvec x[], matrix box, { inertia[j][i] /= tm[j]; } - sdet = std::sqrt(gmx::square(inertia[j][0] - inertia[j][1]) + 4*gmx::square(inertia[j][2])); - e1 = std::sqrt(0.5*(inertia[j][0] + inertia[j][1] + sdet)); - e2 = std::sqrt(0.5*(inertia[j][0] + inertia[j][1] - sdet)); + sdet = std::sqrt(gmx::square(inertia[j][0] - inertia[j][1]) + 4 * gmx::square(inertia[j][2])); + e1 = std::sqrt(0.5 * (inertia[j][0] + inertia[j][1] + sdet)); + e2 = std::sqrt(0.5 * (inertia[j][0] + inertia[j][1] - sdet)); fprintf(out, " %5.3f %5.3f", e1, e2); } fprintf(out, "\n"); } -int gmx_gyrate(int argc, char *argv[]) +int gmx_gyrate(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the radius of gyration of a molecule", "and the radii of gyration about the [IT]x[it]-, [IT]y[it]- and [IT]z[it]-axes,", "as a function of time. The atoms are explicitly mass weighted.[PAR]", @@ -186,57 +193,66 @@ int gmx_gyrate(int argc, char *argv[]) "With the option [TT]-nz[tt] 2D radii of gyration in the [IT]x-y[it] plane", "of slices along the [IT]z[it]-axis are calculated." }; - static int nmol = 1, nz = 0; - static gmx_bool bQ = FALSE, bRot = FALSE, bMOI = FALSE; - t_pargs pa[] = { - { "-nmol", FALSE, etINT, {&nmol}, - "The number of molecules to analyze" }, - { "-q", FALSE, etBOOL, {&bQ}, + static int nmol = 1, nz = 0; + static gmx_bool bQ = FALSE, bRot = FALSE, bMOI = FALSE; + t_pargs pa[] = { + { "-nmol", FALSE, etINT, { &nmol }, "The number of molecules to analyze" }, + { "-q", + FALSE, + etBOOL, + { &bQ }, "Use absolute value of the charge of an atom as weighting factor instead of mass" }, - { "-p", FALSE, etBOOL, {&bRot}, + { "-p", + FALSE, + etBOOL, + { &bRot }, "Calculate the radii of gyration about the principal axes." }, - { "-moi", FALSE, etBOOL, {&bMOI}, + { "-moi", + FALSE, + etBOOL, + { &bMOI }, "Calculate the moments of inertia (defined by the principal axes)." }, - { "-nz", FALSE, etINT, {&nz}, + { "-nz", + FALSE, + etINT, + { &nz }, "Calculate the 2D radii of gyration of this number of slices along the z-axis" }, }; - FILE *out; - t_trxstatus *status; + FILE* out; + t_trxstatus* status; t_topology top; int ePBC; - rvec *x, *x_s; + rvec * x, *x_s; rvec xcm, gvec, gvec1; matrix box, trans; gmx_bool bACF; - real **moi_trans = nullptr; - int max_moi = 0, delta_moi = 100; + real** moi_trans = nullptr; + int max_moi = 0, delta_moi = 100; rvec d, d1; /* eigenvalues of inertia tensor */ real t, t0, tm, gyro; int natoms; - char *grpname; + char* grpname; int j, m, gnx, nam, mol; - int *index; - gmx_output_env_t *oenv; + int* index; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - const char *leg[] = { "Rg", "Rg\\sX\\N", "Rg\\sY\\N", "Rg\\sZ\\N" }; - const char *legI[] = { "Itot", "I1", "I2", "I3" }; + const char* leg[] = { "Rg", "Rg\\sX\\N", "Rg\\sY\\N", "Rg\\sZ\\N" }; + const char* legI[] = { "Itot", "I1", "I2", "I3" }; #define NLEG asize(leg) - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "gyrate", ffWRITE }, - { efXVG, "-acf", "moi-acf", ffOPTWR }, + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, nullptr, "gyrate", ffWRITE }, + { efXVG, "-acf", "moi-acf", ffOPTWR }, }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, npargs, ppa, + asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; @@ -273,7 +289,7 @@ int gmx_gyrate(int argc, char *argv[]) { gmx_fatal(FARGS, "The number of atoms in the group (%d) is not a multiple of nmol (%d)", gnx, nmol); } - nam = gnx/nmol; + nam = gnx / nmol; natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); snew(x_s, natoms); @@ -282,18 +298,18 @@ int gmx_gyrate(int argc, char *argv[]) t0 = t; if (bQ) { - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), - "Radius of Charge (total and around axes)", "Time (ps)", "Rg (nm)", oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Radius of Charge (total and around axes)", + "Time (ps)", "Rg (nm)", oenv); } else if (bMOI) { - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), - "Moments of inertia (total and around axes)", "Time (ps)", "I (a.m.u. nm\\S2\\N)", oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Moments of inertia (total and around axes)", + "Time (ps)", "I (a.m.u. nm\\S2\\N)", oenv); } else { - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), - "Radius of gyration (total and around axes)", "Time (ps)", "Rg (nm)", oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Radius of gyration (total and around axes)", + "Time (ps)", "Rg (nm)", oenv); } if (bMOI) { @@ -327,15 +343,15 @@ int gmx_gyrate(int argc, char *argv[]) clear_rvec(d1); for (mol = 0; mol < nmol; mol++) { - tm = sub_xcm(nz == 0 ? x_s : x, nam, index+mol*nam, top.atoms.atom, xcm, bQ); + tm = sub_xcm(nz == 0 ? x_s : x, nam, index + mol * nam, top.atoms.atom, xcm, bQ); if (nz == 0) { - gyro += calc_gyro(x_s, nam, index+mol*nam, top.atoms.atom, - tm, gvec1, d1, bQ, bRot, bMOI, trans); + gyro += calc_gyro(x_s, nam, index + mol * nam, top.atoms.atom, tm, gvec1, d1, bQ, + bRot, bMOI, trans); } else { - calc_gyro_z(x, box, nam, index+mol*nam, top.atoms.atom, nz, t, out); + calc_gyro_z(x, box, nam, index + mol * nam, top.atoms.atom, nz, t, out); } rvec_inc(gvec, gvec1); rvec_inc(d, d1); @@ -343,8 +359,8 @@ int gmx_gyrate(int argc, char *argv[]) if (nmol > 0) { gyro /= nmol; - svmul(1.0/nmol, gvec, gvec); - svmul(1.0/nmol, d, d); + svmul(1.0 / nmol, gvec, gvec); + svmul(1.0 / nmol, d, d); } if (nz == 0) @@ -356,25 +372,22 @@ int gmx_gyrate(int argc, char *argv[]) max_moi += delta_moi; for (m = 0; (m < DIM); m++) { - srenew(moi_trans[m], max_moi*DIM); + srenew(moi_trans[m], max_moi * DIM); } } for (m = 0; (m < DIM); m++) { - copy_rvec(trans[m], moi_trans[m]+DIM*j); + copy_rvec(trans[m], moi_trans[m] + DIM * j); } - fprintf(out, "%10g %10g %10g %10g %10g\n", - t, gyro, d[XX], d[YY], d[ZZ]); + fprintf(out, "%10g %10g %10g %10g %10g\n", t, gyro, d[XX], d[YY], d[ZZ]); } else { - fprintf(out, "%10g %10g %10g %10g %10g\n", - t, gyro, gvec[XX], gvec[YY], gvec[ZZ]); + fprintf(out, "%10g %10g %10g %10g %10g\n", t, gyro, gvec[XX], gvec[YY], gvec[ZZ]); } } j++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); if (nz == 0) { @@ -387,9 +400,8 @@ int gmx_gyrate(int argc, char *argv[]) { int mode = eacVector; - do_autocorr(opt2fn("-acf", NFILE, fnm), oenv, - "Moment of inertia vector ACF", - j, 3, moi_trans, (t-t0)/j, mode, FALSE); + do_autocorr(opt2fn("-acf", NFILE, fnm), oenv, "Moment of inertia vector ACF", j, 3, + moi_trans, (t - t0) / j, mode, FALSE); do_view(oenv, opt2fn("-acf", NFILE, fnm), "-nxy"); } diff --git a/src/gromacs/gmxana/gmx_h2order.cpp b/src/gromacs/gmxana/gmx_h2order.cpp index c5edc450a6..790aa6f72b 100644 --- a/src/gromacs/gmxana/gmx_h2order.cpp +++ b/src/gromacs/gmxana/gmx_h2order.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,27 +63,34 @@ /* directions. */ /****************************************************************************/ -static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDipole, - real **slOrder, real *slWidth, int *nslices, - const t_topology *top, int ePBC, - int axis, gmx_bool bMicel, int micel[], int nmic, - const gmx_output_env_t *oenv) +static void calc_h2order(const char* fn, + const int index[], + int ngx, + rvec** slDipole, + real** slOrder, + real* slWidth, + int* nslices, + const t_topology* top, + int ePBC, + int axis, + gmx_bool bMicel, + int micel[], + int nmic, + const gmx_output_env_t* oenv) { rvec *x0, /* coordinates with pbc */ - dipole, /* dipole moment due to one molecules */ - normal, - com; /* center of mass of micel, with bMicel */ - rvec *dip; /* sum of dipoles, unnormalized */ + dipole, /* dipole moment due to one molecules */ + normal, com; /* center of mass of micel, with bMicel */ + rvec* dip; /* sum of dipoles, unnormalized */ matrix box; /* box (3x3) */ - t_trxstatus *status; - real t, /* time from trajectory */ - *sum, /* sum of all cosines of dipoles, per slice */ - *frame; /* order over one frame */ - int natoms, /* nr. atoms in trj */ - i, j, teller = 0, - slice = 0, /* current slice number */ - *count; /* nr. of atoms in one slice */ - gmx_rmpbc_t gpbc = nullptr; + t_trxstatus* status; + real t, /* time from trajectory */ + *sum, /* sum of all cosines of dipoles, per slice */ + *frame; /* order over one frame */ + int natoms, /* nr. atoms in trj */ + i, j, teller = 0, slice = 0, /* current slice number */ + *count; /* nr. of atoms in one slice */ + gmx_rmpbc_t gpbc = nullptr; if ((natoms = read_first_x(oenv, &status, fn, &t, &x0, box)) == 0) { @@ -93,22 +100,25 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi if (!*nslices) { *nslices = static_cast(box[axis][axis] * 10); /* default value */ - - } switch (axis) { case 0: - normal[0] = 1; normal[1] = 0; normal[2] = 0; + normal[0] = 1; + normal[1] = 0; + normal[2] = 0; break; case 1: - normal[0] = 0; normal[1] = 1; normal[2] = 0; + normal[0] = 0; + normal[1] = 1; + normal[2] = 0; break; case 2: - normal[0] = 0; normal[1] = 0; normal[2] = 1; + normal[0] = 0; + normal[1] = 0; + normal[2] = 1; break; - default: - gmx_fatal(FARGS, "No valid value for -axis-. Exiting.\n"); + default: gmx_fatal(FARGS, "No valid value for -axis-. Exiting.\n"); } clear_rvec(dipole); @@ -117,9 +127,8 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi snew(dip, *nslices); snew(frame, *nslices); - *slWidth = box[axis][axis]/(*nslices); - fprintf(stderr, "Box divided in %d slices. Initial width of slice: %f\n", - *nslices, *slWidth); + *slWidth = box[axis][axis] / (*nslices); + fprintf(stderr, "Box divided in %d slices. Initial width of slice: %f\n", *nslices, *slWidth); teller = 0; @@ -127,7 +136,7 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi /*********** Start processing trajectory ***********/ do { - *slWidth = box[axis][axis]/(*nslices); + *slWidth = box[axis][axis] / (*nslices); teller++; gmx_rmpbc(gpbc, natoms, box, x0); @@ -137,31 +146,30 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi calc_xcm(x0, nmic, micel, top->atoms.atom, com, FALSE); } - for (i = 0; i < ngx/3; i++) + for (i = 0; i < ngx / 3; i++) { /* put all waters in box */ for (j = 0; j < DIM; j++) { - if (x0[index[3*i]][j] < 0) + if (x0[index[3 * i]][j] < 0) { - x0[index[3*i]][j] += box[j][j]; - x0[index[3*i+1]][j] += box[j][j]; - x0[index[3*i+2]][j] += box[j][j]; + x0[index[3 * i]][j] += box[j][j]; + x0[index[3 * i + 1]][j] += box[j][j]; + x0[index[3 * i + 2]][j] += box[j][j]; } - if (x0[index[3*i]][j] > box[j][j]) + if (x0[index[3 * i]][j] > box[j][j]) { - x0[index[3*i]][j] -= box[j][j]; - x0[index[3*i+1]][j] -= box[j][j]; - x0[index[3*i+2]][j] -= box[j][j]; + x0[index[3 * i]][j] -= box[j][j]; + x0[index[3 * i + 1]][j] -= box[j][j]; + x0[index[3 * i + 2]][j] -= box[j][j]; } } for (j = 0; j < DIM; j++) { - dipole[j] = - x0[index[3*i]][j] * top->atoms.atom[index[3*i]].q + - x0[index[3*i+1]][j] * top->atoms.atom[index[3*i+1]].q + - x0[index[3*i+2]][j] * top->atoms.atom[index[3*i+2]].q; + dipole[j] = x0[index[3 * i]][j] * top->atoms.atom[index[3 * i]].q + + x0[index[3 * i + 1]][j] * top->atoms.atom[index[3 * i + 1]].q + + x0[index[3 * i + 2]][j] * top->atoms.atom[index[3 * i + 2]].q; } /* now we have a dipole vector. Might as well safe it. Then the @@ -170,40 +178,38 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi */ if (bMicel) - { /* this is for spherical interfaces */ - rvec_sub(com, x0[index[3*i]], normal); /* vector from Oxygen to COM */ - slice = static_cast(norm(normal)/(*slWidth)); /* spherical slice */ + { /* this is for spherical interfaces */ + rvec_sub(com, x0[index[3 * i]], normal); /* vector from Oxygen to COM */ + slice = static_cast(norm(normal) / (*slWidth)); /* spherical slice */ - sum[slice] += iprod(dipole, normal) / (norm(dipole) * norm(normal)); + sum[slice] += iprod(dipole, normal) / (norm(dipole) * norm(normal)); frame[slice] += iprod(dipole, normal) / (norm(dipole) * norm(normal)); count[slice]++; - } else { /* this is for flat interfaces */ /* determine which slice atom is in */ - slice = static_cast(x0[index[3*i]][axis] / (*slWidth)); + slice = static_cast(x0[index[3 * i]][axis] / (*slWidth)); if (slice < 0 || slice >= *nslices) { - fprintf(stderr, "Coordinate: %f ", x0[index[3*i]][axis]); + fprintf(stderr, "Coordinate: %f ", x0[index[3 * i]][axis]); fprintf(stderr, "HELP PANIC! slice = %d, OUT OF RANGE!\n", slice); } else { rvec_add(dipole, dip[slice], dip[slice]); /* Add dipole to total. mag[slice] is total dipole in axis direction */ - sum[slice] += iprod(dipole, normal)/norm(dipole); - frame[slice] += iprod(dipole, normal)/norm(dipole); + sum[slice] += iprod(dipole, normal) / norm(dipole); + frame[slice] += iprod(dipole, normal) / norm(dipole); /* increase count for that slice */ count[slice]++; } } } - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); /*********** done with status file **********/ fprintf(stderr, "\nRead trajectory. Printing parameters to file\n"); @@ -227,37 +233,34 @@ static void calc_h2order(const char *fn, const int index[], int ngx, rvec **slDi *slOrder = sum; /* copy a pointer, I hope */ *slDipole = dip; - sfree(x0); /* free memory used by coordinate arrays */ + sfree(x0); /* free memory used by coordinate arrays */ } -static void h2order_plot(rvec dipole[], real order[], const char *afile, - int nslices, real slWidth, const gmx_output_env_t *oenv) +static void h2order_plot(rvec dipole[], real order[], const char* afile, int nslices, real slWidth, const gmx_output_env_t* oenv) { - FILE *ord; /* xvgr files with order parameters */ - int slice; /* loop index */ - char buf[256]; /* for xvgr title */ - real factor; /* conversion to Debye from electron*nm */ + FILE* ord; /* xvgr files with order parameters */ + int slice; /* loop index */ + char buf[256]; /* for xvgr title */ + real factor; /* conversion to Debye from electron*nm */ /* factor = 1e-9*1.60217733e-19/3.336e-30 */ - factor = 1.60217733/3.336e-2; + factor = 1.60217733 / 3.336e-2; fprintf(stderr, "%d slices\n", nslices); sprintf(buf, "Water orientation with respect to normal"); - ord = xvgropen(afile, buf, - "box (nm)", "mu_x, mu_y, mu_z (D), cosine with normal", oenv); + ord = xvgropen(afile, buf, "box (nm)", "mu_x, mu_y, mu_z (D), cosine with normal", oenv); for (slice = 0; slice < nslices; slice++) { - fprintf(ord, "%8.3f %8.3f %8.3f %8.3f %e\n", slWidth*slice, - factor*dipole[slice][XX], factor*dipole[slice][YY], - factor*dipole[slice][ZZ], order[slice]); + fprintf(ord, "%8.3f %8.3f %8.3f %8.3f %e\n", slWidth * slice, factor * dipole[slice][XX], + factor * dipole[slice][YY], factor * dipole[slice][ZZ], order[slice]); } xvgrclose(ord); } -int gmx_h2order(int argc, char *argv[]) +int gmx_h2order(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the orientation of water molecules with respect to the normal", "of the box. The program determines the average cosine of the angle", "between the dipole moment of water and an axis of the box. The box is", @@ -267,49 +270,53 @@ int gmx_h2order(int argc, char *argv[]) "dipole and the axis from the center of mass to the oxygen is calculated", "instead of the angle between the dipole and a box axis." }; - static int axis = 2; /* normal to memb. default z */ - static const char *axtitle = "Z"; - static int nslices = 0; /* nr of slices defined */ - t_pargs pa[] = { - { "-d", FALSE, etSTR, {&axtitle}, - "Take the normal on the membrane in direction X, Y or Z." }, - { "-sl", FALSE, etINT, {&nslices}, - "Calculate order parameter as function of boxlength, dividing the box" - " in this number of slices."} - }; - const char *bugs[] = { + static int axis = 2; /* normal to memb. default z */ + static const char* axtitle = "Z"; + static int nslices = 0; /* nr of slices defined */ + t_pargs pa[] = { { "-d", + FALSE, + etSTR, + { &axtitle }, + "Take the normal on the membrane in direction X, Y or Z." }, + { "-sl", + FALSE, + etINT, + { &nslices }, + "Calculate order parameter as function of boxlength, dividing the box" + " in this number of slices." } }; + const char* bugs[] = { "The program assigns whole water molecules to a slice, based on the first " "atom of three in the index file group. It assumes an order O,H,H. " "Name is not important, but the order is. If this demand is not met, " "assigning molecules to slices is different." }; - gmx_output_env_t *oenv; - real *slOrder, /* av. cosine, per slice */ - slWidth = 0.0; /* width of a slice */ - rvec *slDipole; - char *grpname, /* groupnames */ - *micname; - int ngx, /* nr. of atomsin sol group */ - nmic = 0; /* nr. of atoms in micelle */ - t_topology *top; /* topology */ - int ePBC; - int *index, /* indices for solvent group */ - *micelle = nullptr; - gmx_bool bMicel = FALSE; /* think we're a micel */ - t_filenm fnm[] = { /* files for g_order */ - { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ - { efNDX, nullptr, nullptr, ffREAD }, /* index file */ - { efNDX, "-nm", nullptr, ffOPTRD }, /* index with micelle atoms */ - { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ - { efXVG, "-o", "order", ffWRITE }, /* xvgr output file */ + gmx_output_env_t* oenv; + real * slOrder, /* av. cosine, per slice */ + slWidth = 0.0; /* width of a slice */ + rvec* slDipole; + char *grpname, /* groupnames */ + *micname; + int ngx, /* nr. of atomsin sol group */ + nmic = 0; /* nr. of atoms in micelle */ + t_topology* top; /* topology */ + int ePBC; + int * index, /* indices for solvent group */ + *micelle = nullptr; + gmx_bool bMicel = FALSE; /* think we're a micel */ + t_filenm fnm[] = { + /* files for g_order */ + { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ + { efNDX, nullptr, nullptr, ffREAD }, /* index file */ + { efNDX, "-nm", nullptr, ffOPTRD }, /* index with micelle atoms */ + { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ + { efXVG, "-o", "order", ffWRITE }, /* xvgr output file */ }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, - fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } @@ -324,12 +331,10 @@ int gmx_h2order(int argc, char *argv[]) rd_index(opt2fn("-nm", NFILE, fnm), 1, &nmic, &micelle, &micname); } - calc_h2order(ftp2fn(efTRX, NFILE, fnm), index, ngx, &slDipole, &slOrder, - &slWidth, &nslices, top, ePBC, axis, bMicel, micelle, nmic, - oenv); + calc_h2order(ftp2fn(efTRX, NFILE, fnm), index, ngx, &slDipole, &slOrder, &slWidth, &nslices, + top, ePBC, axis, bMicel, micelle, nmic, oenv); - h2order_plot(slDipole, slOrder, opt2fn("-o", NFILE, fnm), nslices, - slWidth, oenv); + h2order_plot(slDipole, slOrder, opt2fn("-o", NFILE, fnm), nslices, slWidth, oenv); do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); /* view xvgr file */ diff --git a/src/gromacs/gmxana/gmx_hbond.cpp b/src/gromacs/gmxana/gmx_hbond.cpp index f4dc3d3701..260fae262c 100644 --- a/src/gromacs/gmxana/gmx_hbond.cpp +++ b/src/gromacs/gmxana/gmx_hbond.cpp @@ -79,59 +79,71 @@ #define max_hx 7 typedef int t_hx[max_hx]; #define NRHXTYPES max_hx -static const char *hxtypenames[NRHXTYPES] = -{"n-n", "n-n+1", "n-n+2", "n-n+3", "n-n+4", "n-n+5", "n-n>6"}; +static const char* hxtypenames[NRHXTYPES] = { "n-n", "n-n+1", "n-n+2", "n-n+3", + "n-n+4", "n-n+5", "n-n>6" }; #define MAXHH 4 static const int NOTSET = -49297; /* -----------------------------------------*/ -enum { - gr0, gr1, grI, grNR +enum +{ + gr0, + gr1, + grI, + grNR }; -enum { - hbNo, hbDist, hbHB, hbNR, hbR2 +enum +{ + hbNo, + hbDist, + hbHB, + hbNR, + hbR2 }; static const unsigned char c_acceptorMask = (1 << 0); static const unsigned char c_donorMask = (1 << 1); static const unsigned char c_inGroupMask = (1 << 2); -static const char *grpnames[grNR] = {"0", "1", "I" }; +static const char* grpnames[grNR] = { "0", "1", "I" }; -static gmx_bool bDebug = FALSE; +static gmx_bool bDebug = FALSE; #define HB_NO 0 -#define HB_YES 1<<0 -#define HB_INS 1<<1 -#define HB_YESINS (HB_YES|HB_INS) -#define HB_NR (1<<2) +#define HB_YES 1 << 0 +#define HB_INS 1 << 1 +#define HB_YESINS (HB_YES | HB_INS) +#define HB_NR (1 << 2) #define MAXHYDRO 4 -#define ISHB(h) ((h) & 2) -#define ISDIST(h) ((h) & 1) -#define ISDIST2(h) ((h) & 4) -#define ISACC(h) ((h) & c_acceptorMask) -#define ISDON(h) ((h) & c_donorMask) -#define ISINGRP(h) ((h) & c_inGroupMask) - -typedef struct { - int nr; - int maxnr; - int *atoms; +#define ISHB(h) ((h)&2) +#define ISDIST(h) ((h)&1) +#define ISDIST2(h) ((h)&4) +#define ISACC(h) ((h)&c_acceptorMask) +#define ISDON(h) ((h)&c_donorMask) +#define ISINGRP(h) ((h)&c_inGroupMask) + +typedef struct +{ + int nr; + int maxnr; + int* atoms; } t_ncell; -typedef struct { +typedef struct +{ t_ncell d[grNR]; t_ncell a[grNR]; } t_gridcell; -typedef int t_icell[grNR]; +typedef int t_icell[grNR]; typedef int h_id[MAXHYDRO]; -typedef struct { - int history[MAXHYDRO]; +typedef struct +{ + int history[MAXHYDRO]; /* Has this hbond existed ever? If so as hbDist or hbHB or both. * Result is stored as a bitmap (1 = hbDist) || (2 = hbHB) */ @@ -140,8 +152,8 @@ typedef struct { */ int n0; /* First frame a HB was found */ int nframes, maxframes; /* Amount of frames in this hbond */ - unsigned int **h; - unsigned int **g; + unsigned int** h; + unsigned int** g; /* See Xu and Berne, JPCB 105 (2001), p. 11929. We define the * function g(t) = [1-h(t)] H(t) where H(t) is one when the donor- * acceptor distance is less than the user-specified distance (typically @@ -149,39 +161,42 @@ typedef struct { */ } t_hbond; -typedef struct { - int nra, max_nra; - int *acc; /* Atom numbers of the acceptors */ - int *grp; /* Group index */ - int *aptr; /* Map atom number to acceptor index */ +typedef struct +{ + int nra, max_nra; + int* acc; /* Atom numbers of the acceptors */ + int* grp; /* Group index */ + int* aptr; /* Map atom number to acceptor index */ } t_acceptors; -typedef struct { - int nrd, max_nrd; - int *don; /* Atom numbers of the donors */ - int *grp; /* Group index */ - int *dptr; /* Map atom number to donor index */ - int *nhydro; /* Number of hydrogens for each donor */ - h_id *hydro; /* The atom numbers of the hydrogens */ - h_id *nhbonds; /* The number of HBs per H at current */ +typedef struct +{ + int nrd, max_nrd; + int* don; /* Atom numbers of the donors */ + int* grp; /* Group index */ + int* dptr; /* Map atom number to donor index */ + int* nhydro; /* Number of hydrogens for each donor */ + h_id* hydro; /* The atom numbers of the hydrogens */ + h_id* nhbonds; /* The number of HBs per H at current */ } t_donors; -typedef struct { - gmx_bool bHBmap, bDAnr; - int wordlen; +typedef struct +{ + gmx_bool bHBmap, bDAnr; + int wordlen; /* The following arrays are nframes long */ - int nframes, max_frames, maxhydro; - int *nhb, *ndist; - h_id *n_bound; - real *time; - t_icell *danr; - t_hx *nhx; + int nframes, max_frames, maxhydro; + int * nhb, *ndist; + h_id* n_bound; + real* time; + t_icell* danr; + t_hx* nhx; /* These structures are initialized from the topology at start up */ - t_donors d; - t_acceptors a; + t_donors d; + t_acceptors a; /* This holds a matrix with all possible hydrogen bonds */ - int nrhb, nrdist; - t_hbond ***hbmap; + int nrhb, nrdist; + t_hbond*** hbmap; } t_hbdata; /* Changed argument 'bMerge' into 'oneHB' below, @@ -190,12 +205,12 @@ typedef struct { * - Erik Marklund May 29, 2006 */ -static t_hbdata *mk_hbdata(gmx_bool bHBmap, gmx_bool bDAnr, gmx_bool oneHB) +static t_hbdata* mk_hbdata(gmx_bool bHBmap, gmx_bool bDAnr, gmx_bool oneHB) { - t_hbdata *hb; + t_hbdata* hb; snew(hb, 1); - hb->wordlen = 8*sizeof(unsigned int); + hb->wordlen = 8 * sizeof(unsigned int); hb->bHBmap = bHBmap; hb->bDAnr = bDAnr; if (oneHB) @@ -209,9 +224,9 @@ static t_hbdata *mk_hbdata(gmx_bool bHBmap, gmx_bool bDAnr, gmx_bool oneHB) return hb; } -static void mk_hbmap(t_hbdata *hb) +static void mk_hbmap(t_hbdata* hb) { - int i, j; + int i, j; snew(hb->hbmap, hb->d.nrd); for (i = 0; (i < hb->d.nrd); i++) @@ -228,7 +243,7 @@ static void mk_hbmap(t_hbdata *hb) } } -static void add_frames(t_hbdata *hb, int nframes) +static void add_frames(t_hbdata* hb, int nframes) { if (nframes >= hb->max_frames) { @@ -247,7 +262,7 @@ static void add_frames(t_hbdata *hb, int nframes) } #define OFFSET(frame) ((frame) / 32) -#define MASK(frame) (1 << ((frame) % 32)) +#define MASK(frame) (1 << ((frame) % 32)) static void _set_hb(unsigned int hbexist[], unsigned int frame, gmx_bool bValue) { @@ -266,9 +281,9 @@ static gmx_bool is_hb(const unsigned int hbexist[], int frame) return (hbexist[OFFSET(frame)] & MASK(frame)) != 0; } -static void set_hb(t_hbdata *hb, int id, int ih, int ia, int frame, int ihb) +static void set_hb(t_hbdata* hb, int id, int ih, int ia, int frame, int ihb) { - unsigned int *ghptr = nullptr; + unsigned int* ghptr = nullptr; if (ihb == hbHB) { @@ -283,16 +298,16 @@ static void set_hb(t_hbdata *hb, int id, int ih, int ia, int frame, int ihb) gmx_fatal(FARGS, "Incomprehensible iValue %d in set_hb", ihb); } - _set_hb(ghptr, frame-hb->hbmap[id][ia]->n0, TRUE); + _set_hb(ghptr, frame - hb->hbmap[id][ia]->n0, TRUE); } -static void add_ff(t_hbdata *hbd, int id, int h, int ia, int frame, int ihb) +static void add_ff(t_hbdata* hbd, int id, int h, int ia, int frame, int ihb) { - int i, j, n; - t_hbond *hb = hbd->hbmap[id][ia]; - int maxhydro = std::min(hbd->maxhydro, hbd->d.nhydro[id]); - int wlen = hbd->wordlen; - int delta = 32*wlen; + int i, j, n; + t_hbond* hb = hbd->hbmap[id][ia]; + int maxhydro = std::min(hbd->maxhydro, hbd->d.nhydro[id]); + int wlen = hbd->wordlen; + int delta = 32 * wlen; if (!hb->h[0]) { @@ -300,13 +315,13 @@ static void add_ff(t_hbdata *hbd, int id, int h, int ia, int frame, int ihb) hb->maxframes = delta; for (i = 0; (i < maxhydro); i++) { - snew(hb->h[i], hb->maxframes/wlen); - snew(hb->g[i], hb->maxframes/wlen); + snew(hb->h[i], hb->maxframes / wlen); + snew(hb->g[i], hb->maxframes / wlen); } } else { - hb->nframes = frame-hb->n0; + hb->nframes = frame - hb->n0; /* We need a while loop here because hbonds may be returning * after a long time. */ @@ -315,9 +330,9 @@ static void add_ff(t_hbdata *hbd, int id, int h, int ia, int frame, int ihb) n = hb->maxframes + delta; for (i = 0; (i < maxhydro); i++) { - srenew(hb->h[i], n/wlen); - srenew(hb->g[i], n/wlen); - for (j = hb->maxframes/wlen; (j < n/wlen); j++) + srenew(hb->h[i], n / wlen); + srenew(hb->g[i], n / wlen); + for (j = hb->maxframes / wlen; (j < n / wlen); j++) { hb->h[i][j] = 0; hb->g[i][j] = 0; @@ -331,10 +346,9 @@ static void add_ff(t_hbdata *hbd, int id, int h, int ia, int frame, int ihb) { set_hb(hbd, id, h, ia, frame, ihb); } - } -static void inc_nhbonds(t_donors *ddd, int d, int h) +static void inc_nhbonds(t_donors* ddd, int d, int h) { int j; int dptr = ddd->dptr[d]; @@ -349,12 +363,11 @@ static void inc_nhbonds(t_donors *ddd, int d, int h) } if (j == ddd->nhydro[dptr]) { - gmx_fatal(FARGS, "No such hydrogen %d on donor %d\n", h+1, d+1); + gmx_fatal(FARGS, "No such hydrogen %d on donor %d\n", h + 1, d + 1); } } -static int _acceptor_index(t_acceptors *a, int grp, int i, - const char *file, int line) +static int _acceptor_index(t_acceptors* a, int grp, int i, const char* file, int line) { int ai = a->aptr[i]; @@ -362,8 +375,8 @@ static int _acceptor_index(t_acceptors *a, int grp, int i, { if (debug && bDebug) { - fprintf(debug, "Acc. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", - ai, a->grp[ai], grp, file, line); + fprintf(debug, "Acc. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", ai, + a->grp[ai], grp, file, line); } return NOTSET; } @@ -374,7 +387,7 @@ static int _acceptor_index(t_acceptors *a, int grp, int i, } #define acceptor_index(a, grp, i) _acceptor_index(a, grp, i, __FILE__, __LINE__) -static int _donor_index(t_donors *d, int grp, int i, const char *file, int line) +static int _donor_index(t_donors* d, int grp, int i, const char* file, int line) { int di = d->dptr[i]; @@ -387,8 +400,8 @@ static int _donor_index(t_donors *d, int grp, int i, const char *file, int line) { if (debug && bDebug) { - fprintf(debug, "Don. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", - di, d->grp[di], grp, file, line); + fprintf(debug, "Don. group inconsist.. grp[%d] = %d, grp = %d (%s, %d)\n", di, + d->grp[di], grp, file, line); } return NOTSET; } @@ -399,42 +412,40 @@ static int _donor_index(t_donors *d, int grp, int i, const char *file, int line) } #define donor_index(d, grp, i) _donor_index(d, grp, i, __FILE__, __LINE__) -static gmx_bool isInterchangable(t_hbdata *hb, int d, int a, int grpa, int grpd) +static gmx_bool isInterchangable(t_hbdata* hb, int d, int a, int grpa, int grpd) { /* g_hbond doesn't allow overlapping groups */ if (grpa != grpd) { return FALSE; } - return - donor_index(&hb->d, grpd, a) != NOTSET - && acceptor_index(&hb->a, grpa, d) != NOTSET; + return donor_index(&hb->d, grpd, a) != NOTSET && acceptor_index(&hb->a, grpa, d) != NOTSET; } -static void add_hbond(t_hbdata *hb, int d, int a, int h, int grpd, int grpa, - int frame, gmx_bool bMerge, int ihb, gmx_bool bContact) +static void +add_hbond(t_hbdata* hb, int d, int a, int h, int grpd, int grpa, int frame, gmx_bool bMerge, int ihb, gmx_bool bContact) { int k, id, ia, hh; gmx_bool daSwap = FALSE; if ((id = hb->d.dptr[d]) == NOTSET) { - gmx_fatal(FARGS, "No donor atom %d", d+1); + gmx_fatal(FARGS, "No donor atom %d", d + 1); } else if (grpd != hb->d.grp[id]) { - gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", - grpd, hb->d.grp[id], d+1); + gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", grpd, + hb->d.grp[id], d + 1); } if ((ia = hb->a.aptr[a]) == NOTSET) { - gmx_fatal(FARGS, "No acceptor atom %d", a+1); + gmx_fatal(FARGS, "No acceptor atom %d", a + 1); } else if (grpa != hb->a.grp[ia]) { - gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", - grpa, hb->a.grp[ia], a+1); + gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", grpa, + hb->a.grp[ia], a + 1); } if (bMerge) @@ -454,21 +465,21 @@ static void add_hbond(t_hbdata *hb, int d, int a, int h, int grpd, int grpa, /* Now repeat donor/acc check. */ if ((id = hb->d.dptr[d]) == NOTSET) { - gmx_fatal(FARGS, "No donor atom %d", d+1); + gmx_fatal(FARGS, "No donor atom %d", d + 1); } else if (grpd != hb->d.grp[id]) { - gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", - grpd, hb->d.grp[id], d+1); + gmx_fatal(FARGS, "Inconsistent donor groups, %d instead of %d, atom %d", grpd, + hb->d.grp[id], d + 1); } if ((ia = hb->a.aptr[a]) == NOTSET) { - gmx_fatal(FARGS, "No acceptor atom %d", a+1); + gmx_fatal(FARGS, "No acceptor atom %d", a + 1); } else if (grpa != hb->a.grp[ia]) { - gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", - grpa, hb->a.grp[ia], a+1); + gmx_fatal(FARGS, "Inconsistent acceptor groups, %d instead of %d, atom %d", grpa, + hb->a.grp[ia], a + 1); } } } @@ -487,8 +498,7 @@ static void add_hbond(t_hbdata *hb, int d, int a, int h, int grpd, int grpa, } if (k == hb->d.nhydro[id]) { - gmx_fatal(FARGS, "Donor %d does not have hydrogen %d (a = %d)", - d+1, h+1, a+1); + gmx_fatal(FARGS, "Donor %d does not have hydrogen %d (a = %d)", d + 1, h + 1, a + 1); } } else @@ -511,7 +521,7 @@ static void add_hbond(t_hbdata *hb, int d, int a, int h, int grpd, int grpa, } add_ff(hb, id, k, ia, frame, ihb); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } @@ -573,19 +583,18 @@ static void add_hbond(t_hbdata *hb, int d, int a, int h, int grpd, int grpa, } } -static char *mkatomname(const t_atoms *atoms, int i) +static char* mkatomname(const t_atoms* atoms, int i) { static char buf[32]; int rnr; rnr = atoms->atom[i].resind; - sprintf(buf, "%4s%d%-4s", - *atoms->resinfo[rnr].name, atoms->resinfo[rnr].nr, *atoms->atomname[i]); + sprintf(buf, "%4s%d%-4s", *atoms->resinfo[rnr].name, atoms->resinfo[rnr].nr, *atoms->atomname[i]); return buf; } -static void gen_datable(int *index, int isize, unsigned char *datable, int natoms) +static void gen_datable(int* index, int isize, unsigned char* datable, int natoms) { /* Generates table of all atoms and sets the ingroup bit for atoms in index[] */ int i; @@ -600,10 +609,10 @@ static void gen_datable(int *index, int isize, unsigned char *datable, int natom } } -static void clear_datable_grp(unsigned char *datable, int size) +static void clear_datable_grp(unsigned char* datable, int size) { /* Clears group information from the table */ - int i; + int i; if (size > 0) { for (i = 0; i < size; i++) @@ -613,7 +622,7 @@ static void clear_datable_grp(unsigned char *datable, int size) } } -static void add_acc(t_acceptors *a, int ia, int grp) +static void add_acc(t_acceptors* a, int ia, int grp) { if (a->nra >= a->max_nra) { @@ -625,10 +634,15 @@ static void add_acc(t_acceptors *a, int ia, int grp) a->acc[a->nra++] = ia; } -static void search_acceptors(const t_topology *top, int isize, - const int *index, t_acceptors *a, int grp, - gmx_bool bNitAcc, - gmx_bool bContact, gmx_bool bDoIt, unsigned char *datable) +static void search_acceptors(const t_topology* top, + int isize, + const int* index, + t_acceptors* a, + int grp, + gmx_bool bNitAcc, + gmx_bool bContact, + gmx_bool bDoIt, + unsigned char* datable) { int i, n; @@ -637,10 +651,10 @@ static void search_acceptors(const t_topology *top, int isize, for (i = 0; (i < isize); i++) { n = index[i]; - if ((bContact || - (((*top->atoms.atomname[n])[0] == 'O') || - (bNitAcc && ((*top->atoms.atomname[n])[0] == 'N')))) && - ISINGRP(datable[n])) + if ((bContact + || (((*top->atoms.atomname[n])[0] == 'O') + || (bNitAcc && ((*top->atoms.atomname[n])[0] == 'N')))) + && ISINGRP(datable[n])) { datable[n] |= c_acceptorMask; add_acc(a, n, grp); @@ -658,7 +672,7 @@ static void search_acceptors(const t_topology *top, int isize, } } -static void add_h2d(int id, int ih, t_donors *ddd) +static void add_h2d(int id, int ih, t_donors* ddd) { int i; @@ -666,8 +680,7 @@ static void add_h2d(int id, int ih, t_donors *ddd) { if (ddd->hydro[id][i] == ih) { - printf("Hm. This isn't the first time I found this donor (%d,%d)\n", - ddd->don[id], ih); + printf("Hm. This isn't the first time I found this donor (%d,%d)\n", ddd->don[id], ih); break; } } @@ -675,21 +688,20 @@ static void add_h2d(int id, int ih, t_donors *ddd) { if (ddd->nhydro[id] >= MAXHYDRO) { - gmx_fatal(FARGS, "Donor %d has more than %d hydrogens!", - ddd->don[id], MAXHYDRO); + gmx_fatal(FARGS, "Donor %d has more than %d hydrogens!", ddd->don[id], MAXHYDRO); } ddd->hydro[id][i] = ih; ddd->nhydro[id]++; } } -static void add_dh(t_donors *ddd, int id, int ih, int grp, const unsigned char *datable) +static void add_dh(t_donors* ddd, int id, int ih, int grp, const unsigned char* datable) { int i; if (!datable || ISDON(datable[id])) { - if (ddd->dptr[id] == NOTSET) /* New donor */ + if (ddd->dptr[id] == NOTSET) /* New donor */ { i = ddd->nrd; ddd->dptr[id] = i; @@ -721,20 +733,24 @@ static void add_dh(t_donors *ddd, int id, int ih, int grp, const unsigned char * } add_h2d(i, ih, ddd); } - else - if (datable) + else if (datable) { printf("Warning: Atom %d is not in the d/a-table!\n", id); } } -static void search_donors(const t_topology *top, int isize, const int *index, - t_donors *ddd, int grp, gmx_bool bContact, gmx_bool bDoIt, - unsigned char *datable) +static void search_donors(const t_topology* top, + int isize, + const int* index, + t_donors* ddd, + int grp, + gmx_bool bContact, + gmx_bool bDoIt, + unsigned char* datable) { - int i, j; - t_functype func_type; - int nr1, nr2, nr3; + int i, j; + t_functype func_type; + int nr1, nr2, nr3; if (!ddd->dptr) { @@ -760,7 +776,7 @@ static void search_donors(const t_topology *top, int isize, const int *index, { for (func_type = 0; (func_type < F_NRE); func_type++) { - const t_ilist *interaction = &(top->idef.il[func_type]); + const t_ilist* interaction = &(top->idef.il[func_type]); if (func_type == F_POSRES || func_type == F_FBPOSRES) { /* The ilist looks strange for posre. Bug in grompp? @@ -768,34 +784,33 @@ static void search_donors(const t_topology *top, int isize, const int *index, continue; } for (i = 0; i < interaction->nr; - i += interaction_function[top->idef.functype[interaction->iatoms[i]]].nratoms+1) + i += interaction_function[top->idef.functype[interaction->iatoms[i]]].nratoms + 1) { /* next function */ if (func_type != top->idef.functype[interaction->iatoms[i]]) { - fprintf(stderr, "Error in func_type %s", - interaction_function[func_type].longname); + fprintf(stderr, "Error in func_type %s", interaction_function[func_type].longname); continue; } /* check out this functype */ if (func_type == F_SETTLE) { - nr1 = interaction->iatoms[i+1]; - nr2 = interaction->iatoms[i+2]; - nr3 = interaction->iatoms[i+3]; + nr1 = interaction->iatoms[i + 1]; + nr2 = interaction->iatoms[i + 2]; + nr3 = interaction->iatoms[i + 3]; if (ISINGRP(datable[nr1])) { if (ISINGRP(datable[nr2])) { datable[nr1] |= c_donorMask; - add_dh(ddd, nr1, nr1+1, grp, datable); + add_dh(ddd, nr1, nr1 + 1, grp, datable); } if (ISINGRP(datable[nr3])) { datable[nr1] |= c_donorMask; - add_dh(ddd, nr1, nr1+2, grp, datable); + add_dh(ddd, nr1, nr1 + 2, grp, datable); } } } @@ -803,12 +818,11 @@ static void search_donors(const t_topology *top, int isize, const int *index, { for (j = 0; j < 2; j++) { - nr1 = interaction->iatoms[i+1+j]; - nr2 = interaction->iatoms[i+2-j]; - if ((*top->atoms.atomname[nr1][0] == 'H') && - ((*top->atoms.atomname[nr2][0] == 'O') || - (*top->atoms.atomname[nr2][0] == 'N')) && - ISINGRP(datable[nr1]) && ISINGRP(datable[nr2])) + nr1 = interaction->iatoms[i + 1 + j]; + nr2 = interaction->iatoms[i + 2 - j]; + if ((*top->atoms.atomname[nr1][0] == 'H') + && ((*top->atoms.atomname[nr2][0] == 'O') || (*top->atoms.atomname[nr2][0] == 'N')) + && ISINGRP(datable[nr1]) && ISINGRP(datable[nr2])) { datable[nr2] |= c_donorMask; add_dh(ddd, nr2, nr1, grp, datable); @@ -822,7 +836,7 @@ static void search_donors(const t_topology *top, int isize, const int *index, { interaction = &top->idef.il[func_type]; for (i = 0; i < interaction->nr; - i += interaction_function[top->idef.functype[interaction->iatoms[i]]].nratoms+1) + i += interaction_function[top->idef.functype[interaction->iatoms[i]]].nratoms + 1) { /* next function */ if (func_type != top->idef.functype[interaction->iatoms[i]]) @@ -832,12 +846,12 @@ static void search_donors(const t_topology *top, int isize, const int *index, if (interaction_function[func_type].flags & IF_VSITE) { - nr1 = interaction->iatoms[i+1]; - if (*top->atoms.atomname[nr1][0] == 'H') + nr1 = interaction->iatoms[i + 1]; + if (*top->atoms.atomname[nr1][0] == 'H') { - nr2 = nr1-1; + nr2 = nr1 - 1; stop = FALSE; - while (!stop && ( *top->atoms.atomname[nr2][0] == 'H')) + while (!stop && (*top->atoms.atomname[nr2][0] == 'H')) { if (nr2) { @@ -848,9 +862,9 @@ static void search_donors(const t_topology *top, int isize, const int *index, stop = TRUE; } } - if (!stop && ( ( *top->atoms.atomname[nr2][0] == 'O') || - ( *top->atoms.atomname[nr2][0] == 'N') ) && - ISINGRP(datable[nr1]) && ISINGRP(datable[nr2])) + if (!stop + && ((*top->atoms.atomname[nr2][0] == 'O') || (*top->atoms.atomname[nr2][0] == 'N')) + && ISINGRP(datable[nr1]) && ISINGRP(datable[nr2])) { datable[nr2] |= c_donorMask; add_dh(ddd, nr2, nr1, grp, datable); @@ -863,20 +877,20 @@ static void search_donors(const t_topology *top, int isize, const int *index, } } -static t_gridcell ***init_grid(gmx_bool bBox, rvec box[], real rcut, ivec ngrid) +static t_gridcell*** init_grid(gmx_bool bBox, rvec box[], real rcut, ivec ngrid) { - t_gridcell ***grid; + t_gridcell*** grid; int i, y, z; if (bBox) { for (i = 0; i < DIM; i++) { - ngrid[i] = static_cast(box[i][i]/(1.2*rcut)); + ngrid[i] = static_cast(box[i][i] / (1.2 * rcut)); } } - if (!bBox || (ngrid[XX] < 3) || (ngrid[YY] < 3) || (ngrid[ZZ] < 3) ) + if (!bBox || (ngrid[XX] < 3) || (ngrid[YY] < 3) || (ngrid[ZZ] < 3)) { for (i = 0; i < DIM; i++) { @@ -885,14 +899,18 @@ static t_gridcell ***init_grid(gmx_bool bBox, rvec box[], real rcut, ivec ngrid) } else { - printf("\nWill do grid-search on %dx%dx%d grid, rcut=%3.8f\n", - ngrid[XX], ngrid[YY], ngrid[ZZ], rcut); + printf("\nWill do grid-search on %dx%dx%d grid, rcut=%3.8f\n", ngrid[XX], ngrid[YY], + ngrid[ZZ], rcut); } - if (((ngrid[XX]*ngrid[YY]*ngrid[ZZ]) * sizeof(grid)) > INT_MAX) + if (((ngrid[XX] * ngrid[YY] * ngrid[ZZ]) * sizeof(grid)) > INT_MAX) { - gmx_fatal(FARGS, "Failed to allocate memory for %d x %d x %d grid points, which is larger than the maximum of %zu. " - "You are likely either using a box that is too large (box dimensions are %3.8f nm x%3.8f nm x%3.8f nm) or a cutoff (%3.8f nm) that is too small.", - ngrid[XX], ngrid[YY], ngrid[ZZ], INT_MAX/sizeof(grid), box[XX][XX], box[YY][YY], box[ZZ][ZZ], rcut); + gmx_fatal(FARGS, + "Failed to allocate memory for %d x %d x %d grid points, which is larger than " + "the maximum of %zu. " + "You are likely either using a box that is too large (box dimensions are %3.8f " + "nm x%3.8f nm x%3.8f nm) or a cutoff (%3.8f nm) that is too small.", + ngrid[XX], ngrid[YY], ngrid[ZZ], INT_MAX / sizeof(grid), box[XX][XX], box[YY][YY], + box[ZZ][ZZ], rcut); } snew(grid, ngrid[ZZ]); for (z = 0; z < ngrid[ZZ]; z++) @@ -906,7 +924,7 @@ static t_gridcell ***init_grid(gmx_bool bBox, rvec box[], real rcut, ivec ngrid) return grid; } -static void reset_nhbonds(t_donors *ddd) +static void reset_nhbonds(t_donors* ddd) { int i, j; @@ -922,36 +940,45 @@ static void reset_nhbonds(t_donors *ddd) static void pbc_correct_gem(rvec dx, matrix box, const rvec hbox); static void pbc_in_gridbox(rvec dx, matrix box); -static void build_grid(t_hbdata *hb, rvec x[], rvec xshell, - gmx_bool bBox, matrix box, rvec hbox, - real rcut, real rshell, - ivec ngrid, t_gridcell ***grid) +static void build_grid(t_hbdata* hb, + rvec x[], + rvec xshell, + gmx_bool bBox, + matrix box, + rvec hbox, + real rcut, + real rshell, + ivec ngrid, + t_gridcell*** grid) { - int i, m, gr, xi, yi, zi, nr; - int *ad; - ivec grididx; - rvec invdelta, dshell; - t_ncell *newgrid; - gmx_bool bDoRshell, bInShell; - real rshell2 = 0; - int gx, gy, gz; - int dum = -1; + int i, m, gr, xi, yi, zi, nr; + int* ad; + ivec grididx; + rvec invdelta, dshell; + t_ncell* newgrid; + gmx_bool bDoRshell, bInShell; + real rshell2 = 0; + int gx, gy, gz; + int dum = -1; bDoRshell = (rshell > 0); rshell2 = gmx::square(rshell); bInShell = TRUE; -#define DBB(x) if (debug && bDebug) fprintf(debug, "build_grid, line %d, %s = %d\n", __LINE__,#x, x) +#define DBB(x) \ + if (debug && bDebug) \ + fprintf(debug, "build_grid, line %d, %s = %d\n", __LINE__, #x, x) DBB(dum); for (m = 0; m < DIM; m++) { - hbox[m] = box[m][m]*0.5; + hbox[m] = box[m][m] * 0.5; if (bBox) { - invdelta[m] = ngrid[m]/box[m][m]; - if (1/invdelta[m] < rcut) + invdelta[m] = ngrid[m] / box[m][m]; + if (1 / invdelta[m] < rcut) { - gmx_fatal(FARGS, "Your computational box has shrunk too much.\n" + gmx_fatal(FARGS, + "Your computational box has shrunk too much.\n" "%s can not handle this situation, sorry.\n", gmx::getProgramContext().displayName()); } @@ -1010,7 +1037,7 @@ static void build_grid(t_hbdata *hb, rvec x[], rvec xshell, while (!bDone) { bDone = TRUE; - for (m = DIM-1; m >= 0 && bInShell; m--) + for (m = DIM - 1; m >= 0 && bInShell; m--) { if (dshell[m] < -hbox[m]) { @@ -1019,15 +1046,15 @@ static void build_grid(t_hbdata *hb, rvec x[], rvec xshell, } if (dshell[m] >= hbox[m]) { - bDone = FALSE; - dshell[m] -= 2*hbox[m]; + bDone = FALSE; + dshell[m] -= 2 * hbox[m]; } } } - for (m = DIM-1; m >= 0 && bInShell; m--) + for (m = DIM - 1; m >= 0 && bInShell; m--) { /* if we're outside the cube, we're outside the sphere also! */ - if ( (dshell[m] > rshell) || (-dshell[m] > rshell) ) + if ((dshell[m] > rshell) || (-dshell[m] > rshell)) { bInShell = FALSE; } @@ -1046,10 +1073,10 @@ static void build_grid(t_hbdata *hb, rvec x[], rvec xshell, { pbc_in_gridbox(x[ad[i]], box); - for (m = DIM-1; m >= 0; m--) - { /* determine grid index of atom */ - grididx[m] = static_cast(x[ad[i]][m]*invdelta[m]); - grididx[m] = (grididx[m]+ngrid[m]) % ngrid[m]; + for (m = DIM - 1; m >= 0; m--) + { /* determine grid index of atom */ + grididx[m] = static_cast(x[ad[i]][m] * invdelta[m]); + grididx[m] = (grididx[m] + ngrid[m]) % ngrid[m]; } } @@ -1086,7 +1113,7 @@ static void build_grid(t_hbdata *hb, rvec x[], rvec xshell, } } -static void count_da_grid(const ivec ngrid, t_gridcell ***grid, t_icell danr) +static void count_da_grid(const ivec ngrid, t_gridcell*** grid, t_icell danr) { int gr, xi, yi, zi; @@ -1117,18 +1144,18 @@ static void count_da_grid(const ivec ngrid, t_gridcell ***grid, t_icell danr) */ static inline int grid_loop_begin(int n, int x, gmx_bool bTric, gmx_bool bEdge) { - return ((n == 1) ? x : bTric && bEdge ? 0 : (x-1)); + return ((n == 1) ? x : bTric && bEdge ? 0 : (x - 1)); } static inline int grid_loop_end(int n, int x, gmx_bool bTric, gmx_bool bEdge) { - return ((n == 1) ? x : bTric && bEdge ? (n-1) : (x+1)); + return ((n == 1) ? x : bTric && bEdge ? (n - 1) : (x + 1)); } static inline int grid_mod(int j, int n) { - return (j+n) % (n); + return (j + n) % (n); } -static void dump_grid(FILE *fp, ivec ngrid, t_gridcell ***grid) +static void dump_grid(FILE* fp, ivec ngrid, t_gridcell*** grid) { int gr, x, y, z, sum[grNR]; @@ -1139,7 +1166,7 @@ static void dump_grid(FILE *fp, ivec ngrid, t_gridcell ***grid) fprintf(fp, "GROUP %d (%s)\n", gr, grpnames[gr]); for (z = 0; z < ngrid[ZZ]; z += 2) { - fprintf(fp, "Z=%d,%d\n", z, z+1); + fprintf(fp, "Z=%d,%d\n", z, z + 1); for (y = 0; y < ngrid[YY]; y++) { for (x = 0; x < ngrid[XX]; x++) @@ -1148,17 +1175,16 @@ static void dump_grid(FILE *fp, ivec ngrid, t_gridcell ***grid) sum[gr] += grid[z][y][x].d[gr].nr; fprintf(fp, "%3d", grid[x][y][z].a[gr].nr); sum[gr] += grid[z][y][x].a[gr].nr; - } fprintf(fp, " | "); - if ( (z+1) < ngrid[ZZ]) + if ((z + 1) < ngrid[ZZ]) { for (x = 0; x < ngrid[XX]; x++) { - fprintf(fp, "%3d", grid[z+1][y][x].d[gr].nr); - sum[gr] += grid[z+1][y][x].d[gr].nr; - fprintf(fp, "%3d", grid[z+1][y][x].a[gr].nr); - sum[gr] += grid[z+1][y][x].a[gr].nr; + fprintf(fp, "%3d", grid[z + 1][y][x].d[gr].nr); + sum[gr] += grid[z + 1][y][x].d[gr].nr; + fprintf(fp, "%3d", grid[z + 1][y][x].a[gr].nr); + sum[gr] += grid[z + 1][y][x].a[gr].nr; } } fprintf(fp, "\n"); @@ -1176,10 +1202,10 @@ static void dump_grid(FILE *fp, ivec ngrid, t_gridcell ***grid) /* New GMX record! 5 * in a row. Congratulations! * Sorry, only four left. */ -static void free_grid(const ivec ngrid, t_gridcell ****grid) +static void free_grid(const ivec ngrid, t_gridcell**** grid) { int y, z; - t_gridcell ***g = *grid; + t_gridcell*** g = *grid; for (z = 0; z < ngrid[ZZ]; z++) { @@ -1200,7 +1226,7 @@ static void pbc_correct_gem(rvec dx, matrix box, const rvec hbox) while (!bDone) { bDone = TRUE; - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { if (dx[m] < -hbox[m]) { @@ -1223,7 +1249,7 @@ static void pbc_in_gridbox(rvec dx, matrix box) while (!bDone) { bDone = TRUE; - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { if (dx[m] < 0) { @@ -1243,11 +1269,24 @@ static void pbc_in_gridbox(rvec dx, matrix box) * use of second cut-off. * - Erik Marklund, June 29, 2006 */ -static int is_hbond(t_hbdata *hb, int grpd, int grpa, int d, int a, - real rcut, real r2cut, real ccut, - rvec x[], gmx_bool bBox, matrix box, rvec hbox, - real *d_ha, real *ang, gmx_bool bDA, int *hhh, - gmx_bool bContact, gmx_bool bMerge) +static int is_hbond(t_hbdata* hb, + int grpd, + int grpa, + int d, + int a, + real rcut, + real r2cut, + real ccut, + rvec x[], + gmx_bool bBox, + matrix box, + rvec hbox, + real* d_ha, + real* ang, + gmx_bool bDA, + int* hhh, + gmx_bool bContact, + gmx_bool bMerge) { int h, hh, id; rvec r_da, r_ha, r_dh; @@ -1260,14 +1299,13 @@ static int is_hbond(t_hbdata *hb, int grpd, int grpa, int d, int a, return hbNo; } - if (((id = donor_index(&hb->d, grpd, d)) == NOTSET) || - (acceptor_index(&hb->a, grpa, a) == NOTSET)) + if (((id = donor_index(&hb->d, grpd, d)) == NOTSET) || (acceptor_index(&hb->a, grpa, a) == NOTSET)) { return hbNo; } - rc2 = rcut*rcut; - r2c2 = r2cut*r2cut; + rc2 = rcut * rcut; + r2c2 = r2cut * r2cut; rvec_sub(x[d], x[a], r_da); /* Insert projection code here */ @@ -1279,9 +1317,10 @@ static int is_hbond(t_hbdata *hb, int grpd, int grpa, int d, int a, } if (bBox) { - if (d > a && bMerge && isInterchangable(hb, d, a, grpd, grpa)) /* acceptor is also a donor and vice versa? */ - { /* return hbNo; */ - daSwap = TRUE; /* If so, then their history should be filed with donor and acceptor swapped. */ + if (d > a && bMerge + && isInterchangable(hb, d, a, grpd, grpa)) /* acceptor is also a donor and vice versa? */ + { /* return hbNo; */ + daSwap = TRUE; /* If so, then their history should be filed with donor and acceptor swapped. */ } pbc_correct_gem(r_da, box, hbox); } @@ -1316,7 +1355,7 @@ static int is_hbond(t_hbdata *hb, int grpd, int grpa, int d, int a, for (h = 0; (h < hb->d.nhydro[id]); h++) { hh = hb->d.hydro[id][h]; - rha2 = rc2+1; + rha2 = rc2 + 1; if (!bDA) { rvec_sub(x[hh], x[a], r_ha); @@ -1363,14 +1402,12 @@ static int is_hbond(t_hbdata *hb, int grpd, int grpa, int d, int a, /* Merging is now done on the fly, so do_merge is most likely obsolete now. * Will do some more testing before removing the function entirely. * - Erik Marklund, MAY 10 2010 */ -static void do_merge(t_hbdata *hb, int ntmp, - bool htmp[], bool gtmp[], - t_hbond *hb0, t_hbond *hb1) +static void do_merge(t_hbdata* hb, int ntmp, bool htmp[], bool gtmp[], t_hbond* hb0, t_hbond* hb1) { /* Here we need to make sure we're treating periodicity in * the right way for the geminate recombination kinetics. */ - int m, mm, n00, n01, nn0, nnframes; + int m, mm, n00, n01, nn0, nnframes; /* Decide where to start from when merging */ n00 = hb0->n0; @@ -1390,26 +1427,26 @@ static void do_merge(t_hbdata *hb, int ntmp, - Erik Marklund, June 1, 2006 */ for (m = 0; (m <= hb0->nframes); m++) { - mm = m+n00-nn0; + mm = m + n00 - nn0; htmp[mm] = is_hb(hb0->h[0], m); } for (m = 0; (m <= hb0->nframes); m++) { - mm = m+n00-nn0; + mm = m + n00 - nn0; gtmp[mm] = is_hb(hb0->g[0], m); } /* Next HB */ for (m = 0; (m <= hb1->nframes); m++) { - mm = m+n01-nn0; + mm = m + n01 - nn0; htmp[mm] = htmp[mm] || is_hb(hb1->h[0], m); gtmp[mm] = gtmp[mm] || is_hb(hb1->g[0], m); } /* Reallocate target array */ if (nnframes > hb0->maxframes) { - srenew(hb0->h[0], 4+nnframes/hb->wordlen); - srenew(hb0->g[0], 4+nnframes/hb->wordlen); + srenew(hb0->h[0], 4 + nnframes / hb->wordlen); + srenew(hb0->g[0], 4 + nnframes / hb->wordlen); } /* Copy temp array to target array */ @@ -1424,11 +1461,11 @@ static void do_merge(t_hbdata *hb, int ntmp, hb0->maxframes = nnframes; } -static void merge_hb(t_hbdata *hb, gmx_bool bTwo, gmx_bool bContact) +static void merge_hb(t_hbdata* hb, gmx_bool bTwo, gmx_bool bContact) { - int i, inrnew, indnew, j, ii, jj, id, ia, ntmp; - bool *htmp, *gtmp; - t_hbond *hb0, *hb1; + int i, inrnew, indnew, j, ii, jj, id, ia, ntmp; + bool * htmp, *gtmp; + t_hbond *hb0, *hb1; inrnew = hb->nrhb; indnew = hb->nrdist; @@ -1436,12 +1473,12 @@ static void merge_hb(t_hbdata *hb, gmx_bool bTwo, gmx_bool bContact) /* Check whether donors are also acceptors */ printf("Merging hbonds with Acceptor and Donor swapped\n"); - ntmp = 2*hb->max_frames; + ntmp = 2 * hb->max_frames; snew(gtmp, ntmp); snew(htmp, ntmp); for (i = 0; (i < hb->d.nrd); i++) { - fprintf(stderr, "\r%d/%d", i+1, hb->d.nrd); + fprintf(stderr, "\r%d/%d", i + 1, hb->d.nrd); fflush(stderr); id = hb->d.don[i]; ii = hb->a.aptr[id]; @@ -1449,8 +1486,8 @@ static void merge_hb(t_hbdata *hb, gmx_bool bTwo, gmx_bool bContact) { ia = hb->a.acc[j]; jj = hb->d.dptr[ia]; - if ((id != ia) && (ii != NOTSET) && (jj != NOTSET) && - (!bTwo || (hb->d.grp[i] != hb->a.grp[j]))) + if ((id != ia) && (ii != NOTSET) && (jj != NOTSET) + && (!bTwo || (hb->d.grp[i] != hb->a.grp[j]))) { hb0 = hb->hbmap[i][j]; hb1 = hb->hbmap[jj][ii]; @@ -1465,8 +1502,7 @@ static void merge_hb(t_hbdata *hb, gmx_bool bTwo, gmx_bool bContact) { indnew--; } - else - if (bContact) + else if (bContact) { gmx_incons("No contact history"); } @@ -1492,9 +1528,9 @@ static void merge_hb(t_hbdata *hb, gmx_bool bTwo, gmx_bool bContact) sfree(htmp); } -static void do_nhb_dist(FILE *fp, t_hbdata *hb, real t) +static void do_nhb_dist(FILE* fp, t_hbdata* hb, real t) { - int i, j, k, n_bound[MAXHH], nbtot; + int i, j, k, n_bound[MAXHH], nbtot; /* Set array to 0 */ for (k = 0; (k < MAXHH); k++) @@ -1514,26 +1550,25 @@ static void do_nhb_dist(FILE *fp, t_hbdata *hb, real t) for (k = 0; (k < MAXHH); k++) { fprintf(fp, " %8d", n_bound[k]); - nbtot += n_bound[k]*k; + nbtot += n_bound[k] * k; } fprintf(fp, " %8d\n", nbtot); } -static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bContact, - const gmx_output_env_t *oenv) +static void do_hblife(const char* fn, t_hbdata* hb, gmx_bool bMerge, gmx_bool bContact, const gmx_output_env_t* oenv) { - FILE *fp; - const char *leg[] = { "p(t)", "t p(t)" }; - int *histo; + FILE* fp; + const char* leg[] = { "p(t)", "t p(t)" }; + int* histo; int i, j, j0, k, m, nh, ihb, ohb, nhydro, ndump = 0; int nframes = hb->nframes; - unsigned int **h; + unsigned int** h; real t, x1, dt; double sum, integral; - t_hbond *hbh; + t_hbond* hbh; snew(h, hb->maxhydro); - snew(histo, nframes+1); + snew(histo, nframes + 1); /* Total number of hbonds analyzed here */ for (i = 0; (i < hb->d.nrd); i++) { @@ -1572,7 +1607,7 @@ static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bC for (j = 0; (j <= hbh->nframes); j++) { - ihb = static_cast(is_hb(h[nh], j)); + ihb = static_cast(is_hb(h[nh], j)); if (debug && (ndump < 10)) { fprintf(debug, "%5d %5d\n", j, ihb); @@ -1585,7 +1620,7 @@ static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bC } else { - histo[j-j0]++; + histo[j - j0]++; } ohb = ihb; } @@ -1602,12 +1637,12 @@ static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bC } else { - fp = xvgropen(fn, "Uninterrupted hydrogen bond lifetime", output_env_get_xvgr_tlabel(oenv), "()", - oenv); + fp = xvgropen(fn, "Uninterrupted hydrogen bond lifetime", output_env_get_xvgr_tlabel(oenv), + "()", oenv); } xvgr_legend(fp, asize(leg), leg, oenv); - j0 = nframes-1; + j0 = nframes - 1; while ((j0 > 0) && (histo[j0] == 0)) { j0--; @@ -1617,14 +1652,14 @@ static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bC { sum += histo[i]; } - dt = hb->time[1]-hb->time[0]; - sum = dt*sum; + dt = hb->time[1] - hb->time[0]; + sum = dt * sum; integral = 0; for (i = 1; (i <= j0); i++) { - t = hb->time[i] - hb->time[0] - 0.5*dt; - x1 = t*histo[i]/sum; - fprintf(fp, "%8.3f %10.3e %10.3e\n", t, histo[i]/sum, x1); + t = hb->time[i] - hb->time[0] - 0.5 * dt; + x1 = t * histo[i] / sum; + fprintf(fp, "%8.3f %10.3e %10.3e\n", t, histo[i] / sum, x1); integral += x1; } integral *= dt; @@ -1637,13 +1672,13 @@ static void do_hblife(const char *fn, t_hbdata *hb, gmx_bool bMerge, gmx_bool bC sfree(histo); } -static void dump_ac(t_hbdata *hb, gmx_bool oneHB, int nDump) +static void dump_ac(t_hbdata* hb, gmx_bool oneHB, int nDump) { - FILE *fp; - int i, j, k, m, nd, ihb, idist; - int nframes = hb->nframes; - gmx_bool bPrint; - t_hbond *hbh; + FILE* fp; + int i, j, k, m, nd, ihb, idist; + int nframes = hb->nframes; + gmx_bool bPrint; + t_hbond* hbh; if (nDump <= 0) { @@ -1658,8 +1693,8 @@ static void dump_ac(t_hbdata *hb, gmx_bool oneHB, int nDump) for (k = 0; (k < hb->a.nra) && (nd < nDump); k++) { bPrint = FALSE; - ihb = idist = 0; - hbh = hb->hbmap[i][k]; + ihb = idist = 0; + hbh = hb->hbmap[i][k]; if (oneHB) { if (hbh->h[0]) @@ -1673,8 +1708,10 @@ static void dump_ac(t_hbdata *hb, gmx_bool oneHB, int nDump) { for (m = 0; (m < hb->maxhydro) && !ihb; m++) { - ihb = static_cast((ihb != 0) || (((hbh->h[m]) != nullptr) && is_hb(hbh->h[m], j))); - idist = static_cast((idist != 0) || (((hbh->g[m]) != nullptr) && is_hb(hbh->g[m], j))); + ihb = static_cast((ihb != 0) + || (((hbh->h[m]) != nullptr) && is_hb(hbh->h[m], j))); + idist = static_cast((idist != 0) + || (((hbh->g[m]) != nullptr) && is_hb(hbh->g[m], j))); } /* This is not correct! */ /* What isn't correct? -Erik M */ @@ -1696,33 +1733,42 @@ static real calc_dg(real tau, real temp) { real kbt; - kbt = BOLTZ*temp; + kbt = BOLTZ * temp; if (tau <= 0) { return -666; } else { - return kbt*std::log(kbt*tau/PLANCK); + return kbt * std::log(kbt * tau / PLANCK); } } -typedef struct { +typedef struct +{ int n0, n1, nparams, ndelta; real kkk[2]; real *t, *ct, *nt, *kt, *sigma_ct, *sigma_nt, *sigma_kt; } t_luzar; -static real compute_weighted_rates(int n, real t[], real ct[], real nt[], - real kt[], real sigma_ct[], real sigma_nt[], - real sigma_kt[], real *k, real *kp, - real *sigma_k, real *sigma_kp, - real fit_start) +static real compute_weighted_rates(int n, + real t[], + real ct[], + real nt[], + real kt[], + real sigma_ct[], + real sigma_nt[], + real sigma_kt[], + real* k, + real* kp, + real* sigma_k, + real* sigma_kp, + real fit_start) { #define NK 10 - int i, j; - t_luzar tl; - real kkk = 0, kkp = 0, kk2 = 0, kp2 = 0, chi2; + int i, j; + t_luzar tl; + real kkk = 0, kkp = 0, kk2 = 0, kp2 = 0, chi2; *sigma_k = 0; *sigma_kp = 0; @@ -1748,10 +1794,10 @@ static real compute_weighted_rates(int n, real t[], real ct[], real nt[], tl.kkk[0] = *k; tl.kkk[1] = *kp; - chi2 = 0; /*optimize_luzar_parameters(debug, &tl, 1000, 1e-3); */ - *k = tl.kkk[0]; - *kp = tl.kkk[1] = *kp; - tl.ndelta = NK; + chi2 = 0; /*optimize_luzar_parameters(debug, &tl, 1000, 1e-3); */ + *k = tl.kkk[0]; + *kp = tl.kkk[1] = *kp; + tl.ndelta = NK; for (j = 0; (j < NK); j++) { kkk += tl.kkk[0]; @@ -1760,88 +1806,87 @@ static real compute_weighted_rates(int n, real t[], real ct[], real nt[], kp2 += gmx::square(tl.kkk[1]); tl.n0++; } - *sigma_k = std::sqrt(kk2/NK - gmx::square(kkk/NK)); - *sigma_kp = std::sqrt(kp2/NK - gmx::square(kkp/NK)); + *sigma_k = std::sqrt(kk2 / NK - gmx::square(kkk / NK)); + *sigma_kp = std::sqrt(kp2 / NK - gmx::square(kkp / NK)); return chi2; } -void analyse_corr(int n, real t[], real ct[], real nt[], real kt[], - real sigma_ct[], real sigma_nt[], real sigma_kt[], - real fit_start, real temp) +void analyse_corr(int n, + real t[], + real ct[], + real nt[], + real kt[], + real sigma_ct[], + real sigma_nt[], + real sigma_kt[], + real fit_start, + real temp) { - int i0, i; - real k = 1, kp = 1, kow = 1; - real Q = 0, chi2, tau_hb, dtau, tau_rlx, e_1, sigma_k, sigma_kp, ddg; - double tmp, sn2 = 0, sc2 = 0, sk2 = 0, scn = 0, sck = 0, snk = 0; - gmx_bool bError = (sigma_ct != nullptr) && (sigma_nt != nullptr) && (sigma_kt != nullptr); + int i0, i; + real k = 1, kp = 1, kow = 1; + real Q = 0, chi2, tau_hb, dtau, tau_rlx, e_1, sigma_k, sigma_kp, ddg; + double tmp, sn2 = 0, sc2 = 0, sk2 = 0, scn = 0, sck = 0, snk = 0; + gmx_bool bError = (sigma_ct != nullptr) && (sigma_nt != nullptr) && (sigma_kt != nullptr); - for (i0 = 0; (i0 < n-2) && ((t[i0]-t[0]) < fit_start); i0++) - { - ; - } - if (i0 < n-2) + for (i0 = 0; (i0 < n - 2) && ((t[i0] - t[0]) < fit_start); i0++) {} + if (i0 < n - 2) { for (i = i0; (i < n); i++) { sc2 += gmx::square(ct[i]); sn2 += gmx::square(nt[i]); sk2 += gmx::square(kt[i]); - sck += ct[i]*kt[i]; - snk += nt[i]*kt[i]; - scn += ct[i]*nt[i]; + sck += ct[i] * kt[i]; + snk += nt[i] * kt[i]; + scn += ct[i] * nt[i]; } printf("Hydrogen bond thermodynamics at T = %g K\n", temp); - tmp = (sn2*sc2-gmx::square(scn)); + tmp = (sn2 * sc2 - gmx::square(scn)); if ((tmp > 0) && (sn2 > 0)) { - k = (sn2*sck-scn*snk)/tmp; - kp = (k*scn-snk)/sn2; + k = (sn2 * sck - scn * snk) / tmp; + kp = (k * scn - snk) / sn2; if (bError) { chi2 = 0; for (i = i0; (i < n); i++) { - chi2 += gmx::square(k*ct[i]-kp*nt[i]-kt[i]); + chi2 += gmx::square(k * ct[i] - kp * nt[i] - kt[i]); } - compute_weighted_rates(n, t, ct, nt, kt, sigma_ct, sigma_nt, - sigma_kt, &k, &kp, + compute_weighted_rates(n, t, ct, nt, kt, sigma_ct, sigma_nt, sigma_kt, &k, &kp, &sigma_k, &sigma_kp, fit_start); Q = 0; /* quality_of_fit(chi2, 2);*/ - ddg = BOLTZ*temp*sigma_k/k; - printf("Fitting paramaters chi^2 = %10g, Quality of fit = %10g\n", - chi2, Q); + ddg = BOLTZ * temp * sigma_k / k; + printf("Fitting paramaters chi^2 = %10g, Quality of fit = %10g\n", chi2, Q); printf("The Rate and Delta G are followed by an error estimate\n"); printf("----------------------------------------------------------\n" "Type Rate (1/ps) Sigma Time (ps) DG (kJ/mol) Sigma\n"); - printf("Forward %10.3f %6.2f %8.3f %10.3f %6.2f\n", - k, sigma_k, 1/k, calc_dg(1/k, temp), ddg); - ddg = BOLTZ*temp*sigma_kp/kp; - printf("Backward %10.3f %6.2f %8.3f %10.3f %6.2f\n", - kp, sigma_kp, 1/kp, calc_dg(1/kp, temp), ddg); + printf("Forward %10.3f %6.2f %8.3f %10.3f %6.2f\n", k, sigma_k, 1 / k, + calc_dg(1 / k, temp), ddg); + ddg = BOLTZ * temp * sigma_kp / kp; + printf("Backward %10.3f %6.2f %8.3f %10.3f %6.2f\n", kp, sigma_kp, 1 / kp, + calc_dg(1 / kp, temp), ddg); } else { chi2 = 0; for (i = i0; (i < n); i++) { - chi2 += gmx::square(k*ct[i]-kp*nt[i]-kt[i]); + chi2 += gmx::square(k * ct[i] - kp * nt[i] - kt[i]); } - printf("Fitting parameters chi^2 = %10g\nQ = %10g\n", - chi2, Q); + printf("Fitting parameters chi^2 = %10g\nQ = %10g\n", chi2, Q); printf("--------------------------------------------------\n" "Type Rate (1/ps) Time (ps) DG (kJ/mol) Chi^2\n"); - printf("Forward %10.3f %8.3f %10.3f %10g\n", - k, 1/k, calc_dg(1/k, temp), chi2); - printf("Backward %10.3f %8.3f %10.3f\n", - kp, 1/kp, calc_dg(1/kp, temp)); + printf("Forward %10.3f %8.3f %10.3f %10g\n", k, 1 / k, calc_dg(1 / k, temp), chi2); + printf("Backward %10.3f %8.3f %10.3f\n", kp, 1 / kp, calc_dg(1 / kp, temp)); } } if (sc2 > 0) { - kow = 2*sck/sc2; - printf("One-way %10.3f %s%8.3f %10.3f\n", - kow, bError ? " " : "", 1/kow, calc_dg(1/kow, temp)); + kow = 2 * sck / sc2; + printf("One-way %10.3f %s%8.3f %10.3f\n", kow, bError ? " " : "", 1 / kow, + calc_dg(1 / kow, temp)); } else { @@ -1850,24 +1895,23 @@ void analyse_corr(int n, real t[], real ct[], real nt[], real kt[], sc2, sn2, sk2, sck, snk, scn); } /* Determine integral of the correlation function */ - tau_hb = evaluate_integral(n, t, ct, nullptr, (t[n-1]-t[0])/2, &dtau); - printf("Integral %10.3f %s%8.3f %10.3f\n", 1/tau_hb, - bError ? " " : "", tau_hb, calc_dg(tau_hb, temp)); + tau_hb = evaluate_integral(n, t, ct, nullptr, (t[n - 1] - t[0]) / 2, &dtau); + printf("Integral %10.3f %s%8.3f %10.3f\n", 1 / tau_hb, bError ? " " : "", tau_hb, + calc_dg(tau_hb, temp)); e_1 = std::exp(-1.0); - for (i = 0; (i < n-2); i++) + for (i = 0; (i < n - 2); i++) { - if ((ct[i] > e_1) && (ct[i+1] <= e_1)) + if ((ct[i] > e_1) && (ct[i + 1] <= e_1)) { break; } } - if (i < n-2) + if (i < n - 2) { /* Determine tau_relax from linear interpolation */ - tau_rlx = t[i]-t[0] + (e_1-ct[i])*(t[i+1]-t[i])/(ct[i+1]-ct[i]); - printf("Relaxation %10.3f %8.3f %s%10.3f\n", 1/tau_rlx, - tau_rlx, bError ? " " : "", - calc_dg(tau_rlx, temp)); + tau_rlx = t[i] - t[0] + (e_1 - ct[i]) * (t[i + 1] - t[i]) / (ct[i + 1] - ct[i]); + printf("Relaxation %10.3f %8.3f %s%10.3f\n", 1 / tau_rlx, tau_rlx, + bError ? " " : "", calc_dg(tau_rlx, temp)); } } else @@ -1881,26 +1925,26 @@ void compute_derivative(int nn, const real x[], const real y[], real dydx[]) int j; /* Compute k(t) = dc(t)/dt */ - for (j = 1; (j < nn-1); j++) + for (j = 1; (j < nn - 1); j++) { - dydx[j] = (y[j+1]-y[j-1])/(x[j+1]-x[j-1]); + dydx[j] = (y[j + 1] - y[j - 1]) / (x[j + 1] - x[j - 1]); } /* Extrapolate endpoints */ - dydx[0] = 2*dydx[1] - dydx[2]; - dydx[nn-1] = 2*dydx[nn-2] - dydx[nn-3]; + dydx[0] = 2 * dydx[1] - dydx[2]; + dydx[nn - 1] = 2 * dydx[nn - 2] - dydx[nn - 3]; } -static void normalizeACF(real *ct, real *gt, int nhb, int len) +static void normalizeACF(real* ct, real* gt, int nhb, int len) { real ct_fac, gt_fac = 0; int i; /* Xu and Berne use the same normalization constant */ - ct_fac = 1.0/ct[0]; + ct_fac = 1.0 / ct[0]; if (nhb != 0) { - gt_fac = 1.0/nhb; + gt_fac = 1.0 / nhb; } printf("Normalization for c(t) = %g for gh(t) = %g\n", ct_fac, gt_fac); @@ -1914,34 +1958,40 @@ static void normalizeACF(real *ct, real *gt, int nhb, int len) } } -static void do_hbac(const char *fn, t_hbdata *hb, - int nDump, gmx_bool bMerge, gmx_bool bContact, real fit_start, - real temp, gmx_bool R2, const gmx_output_env_t *oenv, - int nThreads) +static void do_hbac(const char* fn, + t_hbdata* hb, + int nDump, + gmx_bool bMerge, + gmx_bool bContact, + real fit_start, + real temp, + gmx_bool R2, + const gmx_output_env_t* oenv, + int nThreads) { - FILE *fp; - int i, j, k, m, ihb, idist, n2, nn; - - const char *legLuzar[] = { - "Ac\\sfin sys\\v{}\\z{}(t)", - "Ac(t)", - "Cc\\scontact,hb\\v{}\\z{}(t)", - "-dAc\\sfs\\v{}\\z{}/dt" - }; - gmx_bool bNorm = FALSE; - double nhb = 0; - real *rhbex = nullptr, *ht, *gt, *ght, *dght, *kt; - real *ct, tail, tail2, dtail, *cct; - const real tol = 1e-3; - int nframes = hb->nframes; - unsigned int **h = nullptr, **g = nullptr; + FILE* fp; + int i, j, k, m, ihb, idist, n2, nn; + + const char* legLuzar[] = { "Ac\\sfin sys\\v{}\\z{}(t)", "Ac(t)", "Cc\\scontact,hb\\v{}\\z{}(t)", + "-dAc\\sfs\\v{}\\z{}/dt" }; + gmx_bool bNorm = FALSE; + double nhb = 0; + real * rhbex = nullptr, *ht, *gt, *ght, *dght, *kt; + real * ct, tail, tail2, dtail, *cct; + const real tol = 1e-3; + int nframes = hb->nframes; + unsigned int **h = nullptr, **g = nullptr; int nh, nhbonds, nhydro; - t_hbond *hbh; + t_hbond* hbh; int acType; - int *dondata = nullptr; + int* dondata = nullptr; - enum { - AC_NONE, AC_NN, AC_GEM, AC_LUZAR + enum + { + AC_NONE, + AC_NN, + AC_GEM, + AC_LUZAR }; const bool bOMP = GMX_OPENMP; @@ -1960,7 +2010,7 @@ static void do_hbac(const char *fn, t_hbdata *hb, n2 *= 2; } - nn = nframes/2; + nn = nframes / 2; if (acType != AC_NN || bOMP) { @@ -1985,7 +2035,8 @@ static void do_hbac(const char *fn, t_hbdata *hb, dondata[i] = -1; } printf("ACF calculations parallelized with OpenMP using %i threads.\n" - "Expect close to linear scaling over this donor-loop.\n", nThreads); + "Expect close to linear scaling over this donor-loop.\n", + nThreads); fflush(stdout); fprintf(stderr, "Donors: [thread no]\n"); { @@ -2001,12 +2052,12 @@ static void do_hbac(const char *fn, t_hbdata *hb, /* Build the ACF */ - snew(rhbex, 2*n2); - snew(ct, 2*n2); - snew(gt, 2*n2); - snew(ht, 2*n2); - snew(ght, 2*n2); - snew(dght, 2*n2); + snew(rhbex, 2 * n2); + snew(ct, 2 * n2); + snew(gt, 2 * n2); + snew(ht, 2 * n2); + snew(ght, 2 * n2); + snew(dght, 2 * n2); snew(kt, nn); snew(cct, nn); @@ -2046,9 +2097,9 @@ static void do_hbac(const char *fn, t_hbdata *hb, for (nh = 0; (nh < nhydro); nh++) { int nrint = bContact ? hb->nrdist : hb->nrhb; - if ((((nhbonds+1) % 10) == 0) || (nhbonds+1 == nrint)) + if ((((nhbonds + 1) % 10) == 0) || (nhbonds + 1 == nrint)) { - fprintf(stderr, "\rACF %d/%d", nhbonds+1, nrint); + fprintf(stderr, "\rACF %d/%d", nhbonds + 1, nrint); fflush(stderr); } nhbonds++; @@ -2068,19 +2119,20 @@ static void do_hbac(const char *fn, t_hbdata *hb, * otherwise use g(t) = 1-h(t) */ if (!R2 && bContact) { - gt[j] = 1-ihb; + gt[j] = 1 - ihb; } else { - gt[j] = idist*(1-ihb); + gt[j] = idist * (1 - ihb); } - ht[j] = rhbex[j]; - nhb += ihb; + ht[j] = rhbex[j]; + nhb += ihb; } /* The autocorrelation function is normalized after summation only */ - low_do_autocorr(nullptr, oenv, nullptr, nframes, 1, -1, &rhbex, hb->time[1]-hb->time[0], - eacNormal, 1, FALSE, bNorm, FALSE, 0, -1, 0); + low_do_autocorr(nullptr, oenv, nullptr, nframes, 1, -1, &rhbex, + hb->time[1] - hb->time[0], eacNormal, 1, FALSE, bNorm, FALSE, 0, + -1, 0); /* Cross correlation analysis for thermodynamics */ for (j = nframes; (j < n2); j++) @@ -2093,7 +2145,7 @@ static void do_hbac(const char *fn, t_hbdata *hb, for (j = 0; (j < nn); j++) { - ct[j] += rhbex[j]; + ct[j] += rhbex[j]; ght[j] += dght[j]; } } @@ -2108,14 +2160,14 @@ static void do_hbac(const char *fn, t_hbdata *hb, /* Determine tail value for statistics */ tail = 0; tail2 = 0; - for (j = nn/2; (j < nn); j++) + for (j = nn / 2; (j < nn); j++) { - tail += ct[j]; - tail2 += ct[j]*ct[j]; + tail += ct[j]; + tail2 += ct[j] * ct[j]; } - tail /= (nn - int{nn/2}); - tail2 /= (nn - int{nn/2}); - dtail = std::sqrt(tail2-tail*tail); + tail /= (nn - int{ nn / 2 }); + tail2 /= (nn - int{ nn / 2 }); + dtail = std::sqrt(tail2 - tail * tail); /* Check whether the ACF is long enough */ if (dtail > tol) @@ -2128,7 +2180,7 @@ static void do_hbac(const char *fn, t_hbdata *hb, for (j = 0; (j < nn); j++) { cct[j] = ct[j]; - ct[j] = (cct[j]-tail)/(1-tail); + ct[j] = (cct[j] - tail) / (1 - tail); } /* Compute negative derivative k(t) = -dc(t)/dt */ compute_derivative(nn, hb->time, ct, kt); @@ -2151,13 +2203,12 @@ static void do_hbac(const char *fn, t_hbdata *hb, for (j = 0; (j < nn); j++) { - fprintf(fp, "%10g %10g %10g %10g %10g\n", - hb->time[j]-hb->time[0], ct[j], cct[j], ght[j], kt[j]); + fprintf(fp, "%10g %10g %10g %10g %10g\n", hb->time[j] - hb->time[0], ct[j], cct[j], + ght[j], kt[j]); } xvgrclose(fp); - analyse_corr(nn, hb->time, ct, ght, kt, nullptr, nullptr, nullptr, - fit_start, temp); + analyse_corr(nn, hb->time, ct, ght, kt, nullptr, nullptr, nullptr, fit_start, temp); do_view(oenv, fn, nullptr); sfree(rhbex); @@ -2170,25 +2221,23 @@ static void do_hbac(const char *fn, t_hbdata *hb, sfree(kt); } -static void init_hbframe(t_hbdata *hb, int nframes, real t) +static void init_hbframe(t_hbdata* hb, int nframes, real t) { int i; - hb->time[nframes] = t; - hb->nhb[nframes] = 0; - hb->ndist[nframes] = 0; + hb->time[nframes] = t; + hb->nhb[nframes] = 0; + hb->ndist[nframes] = 0; for (i = 0; (i < max_hx); i++) { hb->nhx[nframes][i] = 0; } } -static FILE *open_donor_properties_file(const char *fn, - t_hbdata *hb, - const gmx_output_env_t *oenv) +static FILE* open_donor_properties_file(const char* fn, t_hbdata* hb, const gmx_output_env_t* oenv) { - FILE *fp = nullptr; - const char *leg[] = { "Nbound", "Nfree" }; + FILE* fp = nullptr; + const char* leg[] = { "Nbound", "Nfree" }; if (!fn || !hb) { @@ -2201,7 +2250,7 @@ static FILE *open_donor_properties_file(const char *fn, return fp; } -static void analyse_donor_properties(FILE *fp, t_hbdata *hb, int nframes, real t) +static void analyse_donor_properties(FILE* fp, t_hbdata* hb, int nframes, real t) { int i, j, k, nbound, nb, nhtot; @@ -2219,8 +2268,7 @@ static void analyse_donor_properties(FILE *fp, t_hbdata *hb, int nframes, real t nhtot++; for (j = 0; (j < hb->a.nra) && (nb == 0); j++) { - if (hb->hbmap[i][j] && hb->hbmap[i][j]->h[k] && - is_hb(hb->hbmap[i][j]->h[k], nframes)) + if (hb->hbmap[i][j] && hb->hbmap[i][j]->h[k] && is_hb(hb->hbmap[i][j]->h[k], nframes)) { nb = 1; } @@ -2228,15 +2276,20 @@ static void analyse_donor_properties(FILE *fp, t_hbdata *hb, int nframes, real t nbound += nb; } } - fprintf(fp, "%10.3e %6d %6d\n", t, nbound, nhtot-nbound); + fprintf(fp, "%10.3e %6d %6d\n", t, nbound, nhtot - nbound); } -static void dump_hbmap(t_hbdata *hb, - int nfile, t_filenm fnm[], gmx_bool bTwo, - gmx_bool bContact, const int isize[], int *index[], char *grpnames[], - const t_atoms *atoms) +static void dump_hbmap(t_hbdata* hb, + int nfile, + t_filenm fnm[], + gmx_bool bTwo, + gmx_bool bContact, + const int isize[], + int* index[], + char* grpnames[], + const t_atoms* atoms) { - FILE *fp, *fplog; + FILE * fp, *fplog; int ddd, hhh, aaa, i, j, k, m, grp; char ds[32], hs[32], as[32]; gmx_bool first; @@ -2256,8 +2309,8 @@ static void dump_hbmap(t_hbdata *hb, fprintf(fp, "[ %s ]", grpnames[grp]); for (i = 0; i < isize[grp]; i++) { - fprintf(fp, (i%15) ? " " : "\n"); - fprintf(fp, " %4d", index[grp][i]+1); + fprintf(fp, (i % 15) ? " " : "\n"); + fprintf(fp, " %4d", index[grp][i] + 1); } fprintf(fp, "\n"); @@ -2270,8 +2323,7 @@ static void dump_hbmap(t_hbdata *hb, { for (j = 0; (j < hb->d.nhydro[i]); j++) { - fprintf(fp, " %4d %4d", hb->d.don[i]+1, - hb->d.hydro[i][j]+1); + fprintf(fp, " %4d %4d", hb->d.don[i] + 1, hb->d.hydro[i][j] + 1); } fprintf(fp, "\n"); } @@ -2282,8 +2334,8 @@ static void dump_hbmap(t_hbdata *hb, { if (hb->a.grp[i] == grp) { - fprintf(fp, (i%15 && !first) ? " " : "\n"); - fprintf(fp, " %4d", hb->a.acc[i]+1); + fprintf(fp, (i % 15 && !first) ? " " : "\n"); + fprintf(fp, " %4d", hb->a.acc[i] + 1); first = FALSE; } } @@ -2292,8 +2344,7 @@ static void dump_hbmap(t_hbdata *hb, } if (bTwo) { - fprintf(fp, bContact ? "[ contacts_%s-%s ]\n" : - "[ hbonds_%s-%s ]\n", grpnames[0], grpnames[1]); + fprintf(fp, bContact ? "[ contacts_%s-%s ]\n" : "[ hbonds_%s-%s ]\n", grpnames[0], grpnames[1]); } else { @@ -2314,7 +2365,7 @@ static void dump_hbmap(t_hbdata *hb, sprintf(as, "%s", mkatomname(atoms, aaa)); if (bContact) { - fprintf(fp, " %6d %6d\n", ddd+1, aaa+1); + fprintf(fp, " %6d %6d\n", ddd + 1, aaa + 1); if (fplog) { fprintf(fplog, "%12s %12s\n", ds, as); @@ -2324,7 +2375,7 @@ static void dump_hbmap(t_hbdata *hb, { hhh = hb->d.hydro[i][m]; sprintf(hs, "%s", mkatomname(atoms, hhh)); - fprintf(fp, " %6d %6d %6d\n", ddd+1, hhh+1, aaa+1); + fprintf(fp, " %6d %6d %6d\n", ddd + 1, hhh + 1, aaa + 1); if (fplog) { fprintf(fplog, "%12s %12s %12s\n", ds, hs, as); @@ -2343,12 +2394,12 @@ static void dump_hbmap(t_hbdata *hb, /* sync_hbdata() updates the parallel t_hbdata p_hb using hb as template. * It mimics add_frames() and init_frame() to some extent. */ -static void sync_hbdata(t_hbdata *p_hb, int nframes) +static void sync_hbdata(t_hbdata* p_hb, int nframes) { if (nframes >= p_hb->max_frames) { p_hb->max_frames += 4096; - srenew(p_hb->nhb, p_hb->max_frames); + srenew(p_hb->nhb, p_hb->max_frames); srenew(p_hb->ndist, p_hb->max_frames); srenew(p_hb->n_bound, p_hb->max_frames); srenew(p_hb->nhx, p_hb->max_frames); @@ -2356,20 +2407,19 @@ static void sync_hbdata(t_hbdata *p_hb, int nframes) { srenew(p_hb->danr, p_hb->max_frames); } - std::memset(&(p_hb->nhb[nframes]), 0, sizeof(int) * (p_hb->max_frames-nframes)); - std::memset(&(p_hb->ndist[nframes]), 0, sizeof(int) * (p_hb->max_frames-nframes)); + std::memset(&(p_hb->nhb[nframes]), 0, sizeof(int) * (p_hb->max_frames - nframes)); + std::memset(&(p_hb->ndist[nframes]), 0, sizeof(int) * (p_hb->max_frames - nframes)); p_hb->nhb[nframes] = 0; p_hb->ndist[nframes] = 0; - } p_hb->nframes = nframes; - std::memset(&(p_hb->nhx[nframes]), 0, sizeof(int)*max_hx); /* zero the helix count for this frame */ + std::memset(&(p_hb->nhx[nframes]), 0, sizeof(int) * max_hx); /* zero the helix count for this frame */ } -int gmx_hbond(int argc, char *argv[]) +int gmx_hbond(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes and analyzes hydrogen bonds. Hydrogen bonds are", "determined based on cutoffs for the angle Hydrogen - Donor - Acceptor", "(zero is extended) and the distance Donor - Acceptor", @@ -2385,8 +2435,7 @@ int gmx_hbond(int argc, char *argv[]) "If you set [TT]-shell[tt], you will be asked for an additional index group", "which should contain exactly one atom. In this case, only hydrogen", - "bonds between atoms within the shell distance from the one atom are", - "considered.[PAR]", + "bonds between atoms within the shell distance from the one atom are", "considered.[PAR]", "With option -ac, rate constants for hydrogen bonding can be derived with the", "model of Luzar and Chandler (Nature 379:55, 1996; J. Chem. Phys. 113:23, 2000).", @@ -2394,8 +2443,7 @@ int gmx_hbond(int argc, char *argv[]) "n(t) can be defined as either all pairs that are not within contact distance r at time t", "(corresponding to leaving the -r2 option at the default value 0) or all pairs that", "are within distance r2 (corresponding to setting a second cut-off value with option -r2).", - "See mentioned literature for more details and definitions.", - "[PAR]", + "See mentioned literature for more details and definitions.", "[PAR]", /* "It is also possible to analyse specific hydrogen bonds with", "[TT]-sel[tt]. This index file must contain a group of atom triplets", @@ -2411,9 +2459,7 @@ int gmx_hbond(int argc, char *argv[]) "note also that no check is made for the types of atoms.[PAR]", */ - "[BB]Output:[bb]", - "", - " * [TT]-num[tt]: number of hydrogen bonds as a function of time.", + "[BB]Output:[bb]", "", " * [TT]-num[tt]: number of hydrogen bonds as a function of time.", " * [TT]-ac[tt]: average over all autocorrelations of the existence", " functions (either 0 or 1) of all hydrogen bonds.", " * [TT]-dist[tt]: distance distribution of all hydrogen bonds.", @@ -2427,133 +2473,169 @@ int gmx_hbond(int argc, char *argv[]) " all solvent atoms involved in insertion.", " * [TT]-hbm[tt]: existence matrix for all hydrogen bonds over all", " frames, this also contains information on solvent insertion", - " into hydrogen bonds. Ordering is identical to that in [TT]-hbn[tt]", - " index file.", + " into hydrogen bonds. Ordering is identical to that in [TT]-hbn[tt]", " index file.", " * [TT]-dan[tt]: write out the number of donors and acceptors analyzed for", " each timeframe. This is especially useful when using [TT]-shell[tt].", " * [TT]-nhbdist[tt]: compute the number of HBonds per hydrogen in order to", - " compare results to Raman Spectroscopy.", - "", + " compare results to Raman Spectroscopy.", "", "Note: options [TT]-ac[tt], [TT]-life[tt], [TT]-hbn[tt] and [TT]-hbm[tt]", "require an amount of memory proportional to the total numbers of donors", "times the total number of acceptors in the selected group(s)." }; - static real acut = 30, abin = 1, rcut = 0.35, r2cut = 0, rbin = 0.005, rshell = -1; - static real maxnhb = 0, fit_start = 1, fit_end = 60, temp = 298.15; - static gmx_bool bNitAcc = TRUE, bDA = TRUE, bMerge = TRUE; - static int nDump = 0; - static int nThreads = 0; + static real acut = 30, abin = 1, rcut = 0.35, r2cut = 0, rbin = 0.005, rshell = -1; + static real maxnhb = 0, fit_start = 1, fit_end = 60, temp = 298.15; + static gmx_bool bNitAcc = TRUE, bDA = TRUE, bMerge = TRUE; + static int nDump = 0; + static int nThreads = 0; - static gmx_bool bContact = FALSE; + static gmx_bool bContact = FALSE; /* options */ - t_pargs pa [] = { - { "-a", FALSE, etREAL, {&acut}, - "Cutoff angle (degrees, Hydrogen - Donor - Acceptor)" }, - { "-r", FALSE, etREAL, {&rcut}, - "Cutoff radius (nm, X - Acceptor, see next option)" }, - { "-da", FALSE, etBOOL, {&bDA}, + t_pargs pa[] = { + { "-a", FALSE, etREAL, { &acut }, "Cutoff angle (degrees, Hydrogen - Donor - Acceptor)" }, + { "-r", FALSE, etREAL, { &rcut }, "Cutoff radius (nm, X - Acceptor, see next option)" }, + { "-da", + FALSE, + etBOOL, + { &bDA }, "Use distance Donor-Acceptor (if TRUE) or Hydrogen-Acceptor (FALSE)" }, - { "-r2", FALSE, etREAL, {&r2cut}, - "Second cutoff radius. Mainly useful with [TT]-contact[tt] and [TT]-ac[tt]"}, - { "-abin", FALSE, etREAL, {&abin}, - "Binwidth angle distribution (degrees)" }, - { "-rbin", FALSE, etREAL, {&rbin}, - "Binwidth distance distribution (nm)" }, - { "-nitacc", FALSE, etBOOL, {&bNitAcc}, - "Regard nitrogen atoms as acceptors" }, - { "-contact", FALSE, etBOOL, {&bContact}, + { "-r2", + FALSE, + etREAL, + { &r2cut }, + "Second cutoff radius. Mainly useful with [TT]-contact[tt] and [TT]-ac[tt]" }, + { "-abin", FALSE, etREAL, { &abin }, "Binwidth angle distribution (degrees)" }, + { "-rbin", FALSE, etREAL, { &rbin }, "Binwidth distance distribution (nm)" }, + { "-nitacc", FALSE, etBOOL, { &bNitAcc }, "Regard nitrogen atoms as acceptors" }, + { "-contact", + FALSE, + etBOOL, + { &bContact }, "Do not look for hydrogen bonds, but merely for contacts within the cut-off distance" }, - { "-shell", FALSE, etREAL, {&rshell}, + { "-shell", + FALSE, + etREAL, + { &rshell }, "when > 0, only calculate hydrogen bonds within # nm shell around " "one particle" }, - { "-fitstart", FALSE, etREAL, {&fit_start}, - "Time (ps) from which to start fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation. With [TT]-gemfit[tt] we suggest [TT]-fitstart 0[tt]" }, - { "-fitend", FALSE, etREAL, {&fit_end}, - "Time (ps) to which to stop fitting the correlation functions in order to obtain the forward and backward rate constants for HB breaking and formation (only with [TT]-gemfit[tt])" }, - { "-temp", FALSE, etREAL, {&temp}, - "Temperature (K) for computing the Gibbs energy corresponding to HB breaking and reforming" }, - { "-dump", FALSE, etINT, {&nDump}, + { "-fitstart", + FALSE, + etREAL, + { &fit_start }, + "Time (ps) from which to start fitting the correlation functions in order to obtain the " + "forward and backward rate constants for HB breaking and formation. With [TT]-gemfit[tt] " + "we suggest [TT]-fitstart 0[tt]" }, + { "-fitend", + FALSE, + etREAL, + { &fit_end }, + "Time (ps) to which to stop fitting the correlation functions in order to obtain the " + "forward and backward rate constants for HB breaking and formation (only with " + "[TT]-gemfit[tt])" }, + { "-temp", + FALSE, + etREAL, + { &temp }, + "Temperature (K) for computing the Gibbs energy corresponding to HB breaking and " + "reforming" }, + { "-dump", + FALSE, + etINT, + { &nDump }, "Dump the first N hydrogen bond ACFs in a single [REF].xvg[ref] file for debugging" }, - { "-max_hb", FALSE, etREAL, {&maxnhb}, - "Theoretical maximum number of hydrogen bonds used for normalizing HB autocorrelation function. Can be useful in case the program estimates it wrongly" }, - { "-merge", FALSE, etBOOL, {&bMerge}, - "H-bonds between the same donor and acceptor, but with different hydrogen are treated as a single H-bond. Mainly important for the ACF." }, + { "-max_hb", + FALSE, + etREAL, + { &maxnhb }, + "Theoretical maximum number of hydrogen bonds used for normalizing HB autocorrelation " + "function. Can be useful in case the program estimates it wrongly" }, + { "-merge", + FALSE, + etBOOL, + { &bMerge }, + "H-bonds between the same donor and acceptor, but with different hydrogen are treated as " + "a single H-bond. Mainly important for the ACF." }, #if GMX_OPENMP - { "-nthreads", FALSE, etINT, {&nThreads}, - "Number of threads used for the parallel loop over autocorrelations. nThreads <= 0 means maximum number of threads. Requires linking with OpenMP. The number of threads is limited by the number of cores (before OpenMP v.3 ) or environment variable OMP_THREAD_LIMIT (OpenMP v.3)"}, + { "-nthreads", + FALSE, + etINT, + { &nThreads }, + "Number of threads used for the parallel loop over autocorrelations. nThreads <= 0 means " + "maximum number of threads. Requires linking with OpenMP. The number of threads is " + "limited by the number of cores (before OpenMP v.3 ) or environment variable " + "OMP_THREAD_LIMIT (OpenMP v.3)" }, #endif }; - const char *bugs[] = { - "The option [TT]-sel[tt] that used to work on selected hbonds is out of order, and therefore not available for the time being." + const char* bugs[] = { + "The option [TT]-sel[tt] that used to work on selected hbonds is out of order, and " + "therefore not available for the time being." }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - /* { efNDX, "-sel", "select", ffOPTRD },*/ - { efXVG, "-num", "hbnum", ffWRITE }, - { efLOG, "-g", "hbond", ffOPTWR }, - { efXVG, "-ac", "hbac", ffOPTWR }, - { efXVG, "-dist", "hbdist", ffOPTWR }, - { efXVG, "-ang", "hbang", ffOPTWR }, - { efXVG, "-hx", "hbhelix", ffOPTWR }, - { efNDX, "-hbn", "hbond", ffOPTWR }, - { efXPM, "-hbm", "hbmap", ffOPTWR }, - { efXVG, "-don", "donor", ffOPTWR }, - { efXVG, "-dan", "danum", ffOPTWR }, - { efXVG, "-life", "hblife", ffOPTWR }, - { efXVG, "-nhbdist", "nhbdist", ffOPTWR } + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + /* { efNDX, "-sel", "select", ffOPTRD },*/ + { efXVG, "-num", "hbnum", ffWRITE }, + { efLOG, "-g", "hbond", ffOPTWR }, + { efXVG, "-ac", "hbac", ffOPTWR }, + { efXVG, "-dist", "hbdist", ffOPTWR }, + { efXVG, "-ang", "hbang", ffOPTWR }, + { efXVG, "-hx", "hbhelix", ffOPTWR }, + { efNDX, "-hbn", "hbond", ffOPTWR }, + { efXPM, "-hbm", "hbmap", ffOPTWR }, + { efXVG, "-don", "donor", ffOPTWR }, + { efXVG, "-dan", "danum", ffOPTWR }, + { efXVG, "-life", "hblife", ffOPTWR }, + { efXVG, "-nhbdist", "nhbdist", ffOPTWR } }; #define NFILE asize(fnm) - char hbmap [HB_NR] = { ' ', 'o', '-', '*' }; - const char *hbdesc[HB_NR] = { "None", "Present", "Inserted", "Present & Inserted" }; - t_rgb hbrgb [HB_NR] = { {1, 1, 1}, {1, 0, 0}, {0, 0, 1}, {1, 0, 1} }; - - t_trxstatus *status; - bool trrStatus = true; - t_topology top; - t_pargs *ppa; - int npargs, natoms, nframes = 0, shatom; - int *isize; - char **grpnames; - int **index; - rvec *x, hbox; - matrix box; - real t, ccut, dist = 0.0, ang = 0.0; - double max_nhb, aver_nhb, aver_dist; - int h = 0, i = 0, j, k = 0, ogrp, nsel; - int xi = 0, yi, zi, ai; - int xj, yj, zj, aj, xjj, yjj, zjj; - gmx_bool bSelected, bHBmap, bStop, bTwo, bBox, bTric; - int *adist, *rdist; - int grp, nabin, nrbin, resdist, ihb; - char **leg; - t_hbdata *hb; - FILE *fp, *fpnhb = nullptr, *donor_properties = nullptr; - t_gridcell ***grid; - t_ncell *icell, *jcell; - ivec ngrid; - unsigned char *datable; - gmx_output_env_t *oenv; - int ii, hh, actual_nThreads; - int threadNr = 0; - gmx_bool bParallel; - gmx_bool bEdge_yjj, bEdge_xjj; - - t_hbdata **p_hb = nullptr; /* one per thread, then merge after the frame loop */ - int **p_adist = nullptr, **p_rdist = nullptr; /* a histogram for each thread. */ - - const bool bOMP = GMX_OPENMP; + char hbmap[HB_NR] = { ' ', 'o', '-', '*' }; + const char* hbdesc[HB_NR] = { "None", "Present", "Inserted", "Present & Inserted" }; + t_rgb hbrgb[HB_NR] = { { 1, 1, 1 }, { 1, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 } }; + + t_trxstatus* status; + bool trrStatus = true; + t_topology top; + t_pargs* ppa; + int npargs, natoms, nframes = 0, shatom; + int* isize; + char** grpnames; + int** index; + rvec * x, hbox; + matrix box; + real t, ccut, dist = 0.0, ang = 0.0; + double max_nhb, aver_nhb, aver_dist; + int h = 0, i = 0, j, k = 0, ogrp, nsel; + int xi = 0, yi, zi, ai; + int xj, yj, zj, aj, xjj, yjj, zjj; + gmx_bool bSelected, bHBmap, bStop, bTwo, bBox, bTric; + int * adist, *rdist; + int grp, nabin, nrbin, resdist, ihb; + char** leg; + t_hbdata* hb; + FILE * fp, *fpnhb = nullptr, *donor_properties = nullptr; + t_gridcell*** grid; + t_ncell * icell, *jcell; + ivec ngrid; + unsigned char* datable; + gmx_output_env_t* oenv; + int ii, hh, actual_nThreads; + int threadNr = 0; + gmx_bool bParallel; + gmx_bool bEdge_yjj, bEdge_xjj; + + t_hbdata** p_hb = nullptr; /* one per thread, then merge after the frame loop */ + int ** p_adist = nullptr, **p_rdist = nullptr; /* a histogram for each thread. */ + + const bool bOMP = GMX_OPENMP; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, npargs, - ppa, asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, npargs, ppa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { sfree(ppa); return 0; @@ -2561,7 +2643,7 @@ int gmx_hbond(int argc, char *argv[]) /* process input */ bSelected = FALSE; - ccut = std::cos(acut*DEG2RAD); + ccut = std::cos(acut * DEG2RAD); if (bContact) { @@ -2576,24 +2658,22 @@ int gmx_hbond(int argc, char *argv[]) } /* Initiate main data structure! */ - bHBmap = (opt2bSet("-ac", NFILE, fnm) || - opt2bSet("-life", NFILE, fnm) || - opt2bSet("-hbn", NFILE, fnm) || - opt2bSet("-hbm", NFILE, fnm)); + bHBmap = (opt2bSet("-ac", NFILE, fnm) || opt2bSet("-life", NFILE, fnm) + || opt2bSet("-hbn", NFILE, fnm) || opt2bSet("-hbm", NFILE, fnm)); if (opt2bSet("-nhbdist", NFILE, fnm)) { - const char *leg[MAXHH+1] = { "0 HBs", "1 HB", "2 HBs", "3 HBs", "Total" }; - fpnhb = xvgropen(opt2fn("-nhbdist", NFILE, fnm), - "Number of donor-H with N HBs", output_env_get_xvgr_tlabel(oenv), "N", oenv); + const char* leg[MAXHH + 1] = { "0 HBs", "1 HB", "2 HBs", "3 HBs", "Total" }; + fpnhb = xvgropen(opt2fn("-nhbdist", NFILE, fnm), "Number of donor-H with N HBs", + output_env_get_xvgr_tlabel(oenv), "N", oenv); xvgr_legend(fpnhb, asize(leg), leg, oenv); } hb = mk_hbdata(bHBmap, opt2bSet("-dan", NFILE, fnm), bMerge || bContact); /* get topology */ - t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec irInstance; + t_inputrec* ir = &irInstance; read_tpx_top(ftp2fn(efTPR, NFILE, fnm), ir, box, &natoms, nullptr, nullptr, &top); snew(grpnames, grNR); @@ -2606,37 +2686,36 @@ int gmx_hbond(int argc, char *argv[]) { /* analyze selected hydrogen bonds */ printf("Select group with selected atoms:\n"); - get_index(&(top.atoms), opt2fn("-sel", NFILE, fnm), - 1, &nsel, index, grpnames); + get_index(&(top.atoms), opt2fn("-sel", NFILE, fnm), 1, &nsel, index, grpnames); if (nsel % 3) { - gmx_fatal(FARGS, "Number of atoms in group '%s' not a multiple of 3\n" + gmx_fatal(FARGS, + "Number of atoms in group '%s' not a multiple of 3\n" "and therefore cannot contain triplets of " - "Donor-Hydrogen-Acceptor", grpnames[0]); + "Donor-Hydrogen-Acceptor", + grpnames[0]); } bTwo = FALSE; for (i = 0; (i < nsel); i += 3) { - int dd = index[0][i]; - int aa = index[0][i+2]; - /* int */ hh = index[0][i+1]; - add_dh (&hb->d, dd, hh, i, datable); + int dd = index[0][i]; + int aa = index[0][i + 2]; + /* int */ hh = index[0][i + 1]; + add_dh(&hb->d, dd, hh, i, datable); add_acc(&hb->a, aa, i); /* Should this be here ? */ snew(hb->d.dptr, top.atoms.nr); snew(hb->a.aptr, top.atoms.nr); add_hbond(hb, dd, aa, hh, gr0, gr0, 0, bMerge, 0, bContact); } - printf("Analyzing %d selected hydrogen bonds from '%s'\n", - isize[0], grpnames[0]); + printf("Analyzing %d selected hydrogen bonds from '%s'\n", isize[0], grpnames[0]); } else { /* analyze all hydrogen bonds: get group(s) */ printf("Specify 2 groups to analyze:\n"); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), - 2, isize, index, grpnames); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 2, isize, index, grpnames); /* check if we have two identical or two non-overlapping groups */ bTwo = isize[0] != isize[1]; @@ -2646,8 +2725,7 @@ int gmx_hbond(int argc, char *argv[]) } if (bTwo) { - printf("Checking for overlap in atoms between %s and %s\n", - grpnames[0], grpnames[1]); + printf("Checking for overlap in atoms between %s and %s\n", grpnames[0], grpnames[1]); gen_datable(index[0], isize[0], datable, top.atoms.nr); @@ -2655,8 +2733,8 @@ int gmx_hbond(int argc, char *argv[]) { if (ISINGRP(datable[index[1][i]])) { - gmx_fatal(FARGS, "Partial overlap between groups '%s' and '%s'", - grpnames[0], grpnames[1]); + gmx_fatal(FARGS, "Partial overlap between groups '%s' and '%s'", grpnames[0], + grpnames[1]); } } } @@ -2664,8 +2742,8 @@ int gmx_hbond(int argc, char *argv[]) { printf("Calculating %s " "between %s (%d atoms) and %s (%d atoms)\n", - bContact ? "contacts" : "hydrogen bonds", - grpnames[0], isize[0], grpnames[1], isize[1]); + bContact ? "contacts" : "hydrogen bonds", grpnames[0], isize[0], grpnames[1], + isize[1]); } else { @@ -2679,21 +2757,20 @@ int gmx_hbond(int argc, char *argv[]) snew(datable, top.atoms.nr); for (i = 0; (i < grNR); i++) { - if ( ((i == gr0) && !bSelected ) || - ((i == gr1) && bTwo )) + if (((i == gr0) && !bSelected) || ((i == gr1) && bTwo)) { gen_datable(index[i], isize[i], datable, top.atoms.nr); if (bContact) { - search_acceptors(&top, isize[i], index[i], &hb->a, i, - bNitAcc, TRUE, (bTwo && (i == gr0)) || !bTwo, datable); - search_donors (&top, isize[i], index[i], &hb->d, i, - TRUE, (bTwo && (i == gr1)) || !bTwo, datable); + search_acceptors(&top, isize[i], index[i], &hb->a, i, bNitAcc, TRUE, + (bTwo && (i == gr0)) || !bTwo, datable); + search_donors(&top, isize[i], index[i], &hb->d, i, TRUE, + (bTwo && (i == gr1)) || !bTwo, datable); } else { search_acceptors(&top, isize[i], index[i], &hb->a, i, bNitAcc, FALSE, TRUE, datable); - search_donors (&top, isize[i], index[i], &hb->d, i, FALSE, TRUE, datable); + search_donors(&top, isize[i], index[i], &hb->d, i, FALSE, TRUE, datable); } if (bTwo) { @@ -2744,53 +2821,51 @@ int gmx_hbond(int argc, char *argv[]) shatom = 0; if (rshell > 0) { - int shisz; - int *shidx; - char *shgrpnm; + int shisz; + int* shidx; + char* shgrpnm; /* get index group with atom for shell */ do { printf("Select atom for shell (1 atom):\n"); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), - 1, &shisz, &shidx, &shgrpnm); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &shisz, &shidx, &shgrpnm); if (shisz != 1) { printf("group contains %d atoms, should be 1 (one)\n", shisz); } - } - while (shisz != 1); + } while (shisz != 1); shatom = shidx[0]; printf("Will calculate hydrogen bonds within a shell " - "of %g nm around atom %i\n", rshell, shatom+1); + "of %g nm around atom %i\n", + rshell, shatom + 1); } /* Analyze trajectory */ natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); if (natoms > top.atoms.nr) { - gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", - top.atoms.nr, natoms); + gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", top.atoms.nr, natoms); } bBox = (ir->ePBC != epbcNONE); grid = init_grid(bBox, box, (rcut > r2cut) ? rcut : r2cut, ngrid); - nabin = static_cast(acut/abin); - nrbin = static_cast(rcut/rbin); - snew(adist, nabin+1); - snew(rdist, nrbin+1); + nabin = static_cast(acut / abin); + nrbin = static_cast(rcut / rbin); + snew(adist, nabin + 1); + snew(rdist, nrbin + 1); #if !GMX_OPENMP -#define __ADIST adist -#define __RDIST rdist -#define __HBDATA hb -#else /* GMX_OPENMP ================================================== \ - * Set up the OpenMP stuff, | - * like the number of threads and such | - * Also start the parallel loop. | +# define __ADIST adist +# define __RDIST rdist +# define __HBDATA hb +#else /* GMX_OPENMP ================================================== \ + * Set up the OpenMP stuff, | \ + * like the number of threads and such | \ + * Also start the parallel loop. | \ */ -#define __ADIST p_adist[threadNr] -#define __RDIST p_rdist[threadNr] -#define __HBDATA p_hb[threadNr] +# define __ADIST p_adist[threadNr] +# define __RDIST p_rdist[threadNr] +# define __HBDATA p_hb[threadNr] #endif if (bOMP) { @@ -2809,14 +2884,14 @@ int gmx_hbond(int argc, char *argv[]) actual_nThreads = 1; } - snew(p_hb, actual_nThreads); + snew(p_hb, actual_nThreads); snew(p_adist, actual_nThreads); snew(p_rdist, actual_nThreads); for (i = 0; i < actual_nThreads; i++) { snew(p_hb[i], 1); - snew(p_adist[i], nabin+1); - snew(p_rdist[i], nrbin+1); + snew(p_adist[i], nabin + 1); + snew(p_rdist[i], nrbin + 1); p_hb[i]->max_frames = 0; p_hb[i]->nhb = nullptr; @@ -2825,16 +2900,16 @@ int gmx_hbond(int argc, char *argv[]) p_hb[i]->time = nullptr; p_hb[i]->nhx = nullptr; - p_hb[i]->bHBmap = hb->bHBmap; - p_hb[i]->bDAnr = hb->bDAnr; - p_hb[i]->wordlen = hb->wordlen; - p_hb[i]->nframes = hb->nframes; - p_hb[i]->maxhydro = hb->maxhydro; - p_hb[i]->danr = hb->danr; - p_hb[i]->d = hb->d; - p_hb[i]->a = hb->a; - p_hb[i]->hbmap = hb->hbmap; - p_hb[i]->time = hb->time; /* This may need re-syncing at every frame. */ + p_hb[i]->bHBmap = hb->bHBmap; + p_hb[i]->bDAnr = hb->bDAnr; + p_hb[i]->wordlen = hb->wordlen; + p_hb[i]->nframes = hb->nframes; + p_hb[i]->maxhydro = hb->maxhydro; + p_hb[i]->danr = hb->danr; + p_hb[i]->d = hb->d; + p_hb[i]->a = hb->a; + p_hb[i]->hbmap = hb->hbmap; + p_hb[i]->time = hb->time; /* This may need re-syncing at every frame. */ p_hb[i]->nrhb = 0; p_hb[i]->nrdist = 0; @@ -2844,17 +2919,10 @@ int gmx_hbond(int argc, char *argv[]) /* Make a thread pool here, * instead of forking anew at every frame. */ -#pragma omp parallel \ - firstprivate(i) \ - private(j, h, ii, hh, \ - xi, yi, zi, xj, yj, zj, threadNr, \ - dist, ang, icell, jcell, \ - grp, ogrp, ai, aj, xjj, yjj, zjj, \ - ihb, resdist, \ - k, bTric, \ - bEdge_xjj, bEdge_yjj) \ - default(shared) - { /* Start of parallel region */ +#pragma omp parallel firstprivate(i) private( \ + j, h, ii, hh, xi, yi, zi, xj, yj, zj, threadNr, dist, ang, icell, jcell, grp, ogrp, ai, \ + aj, xjj, yjj, zjj, ihb, resdist, k, bTric, bEdge_xjj, bEdge_yjj) default(shared) + { /* Start of parallel region */ if (bOMP) { threadNr = gmx_omp_get_thread_num(); @@ -2870,7 +2938,7 @@ int gmx_hbond(int argc, char *argv[]) { sync_hbdata(p_hb[threadNr], nframes); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #pragma omp single { @@ -2893,7 +2961,7 @@ int gmx_hbond(int argc, char *argv[]) count_da_grid(ngrid, grid, hb->danr[nframes]); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* omp single */ if (bOMP) @@ -2912,11 +2980,11 @@ int gmx_hbond(int argc, char *argv[]) /* int ii; */ for (ii = 0; (ii < nsel); ii++) { - int dd = index[0][i]; - int aa = index[0][i+2]; - /* int */ hh = index[0][i+1]; - ihb = is_hbond(hb, ii, ii, dd, aa, rcut, r2cut, ccut, x, bBox, box, - hbox, &dist, &ang, bDA, &h, bContact, bMerge); + int dd = index[0][i]; + int aa = index[0][i + 2]; + /* int */ hh = index[0][i + 1]; + ihb = is_hbond(hb, ii, ii, dd, aa, rcut, r2cut, ccut, x, bBox, box, + hbox, &dist, &ang, bDA, &h, bContact, bMerge); if (ihb) { @@ -2926,7 +2994,7 @@ int gmx_hbond(int argc, char *argv[]) } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* omp single */ } /* if (bSelected) */ else @@ -2949,7 +3017,7 @@ int gmx_hbond(int argc, char *argv[]) if (bTwo) { - ogrp = 1-grp; + ogrp = 1 - grp; } else { @@ -2961,12 +3029,11 @@ int gmx_hbond(int argc, char *argv[]) */ for (ai = 0; (ai < icell->nr); ai++) { - i = icell->atoms[ai]; + i = icell->atoms[ai]; /* loop over all adjacent gridcells (xj,yj,zj) */ for (zjj = grid_loop_begin(ngrid[ZZ], zi, bTric, FALSE); - zjj <= grid_loop_end(ngrid[ZZ], zi, bTric, FALSE); - zjj++) + zjj <= grid_loop_end(ngrid[ZZ], zi, bTric, FALSE); zjj++) { zj = grid_mod(zjj, ngrid[ZZ]); bEdge_yjj = (zj == 0) || (zj == ngrid[ZZ] - 1); @@ -2975,61 +3042,75 @@ int gmx_hbond(int argc, char *argv[]) yjj++) { yj = grid_mod(yjj, ngrid[YY]); - bEdge_xjj = - (yj == 0) || (yj == ngrid[YY] - 1) || - (zj == 0) || (zj == ngrid[ZZ] - 1); + bEdge_xjj = (yj == 0) || (yj == ngrid[YY] - 1) + || (zj == 0) || (zj == ngrid[ZZ] - 1); for (xjj = grid_loop_begin(ngrid[XX], xi, bTric, bEdge_xjj); xjj <= grid_loop_end(ngrid[XX], xi, bTric, bEdge_xjj); xjj++) { xj = grid_mod(xjj, ngrid[XX]); jcell = &(grid[zj][yj][xj].a[ogrp]); - /* loop over acceptor atoms from other group (ogrp) - * in this adjacent gridcell (jcell) + /* loop over acceptor atoms from other group + * (ogrp) in this adjacent gridcell (jcell) */ for (aj = 0; (aj < jcell->nr); aj++) { j = jcell->atoms[aj]; /* check if this once was a h-bond */ - ihb = is_hbond(__HBDATA, grp, ogrp, i, j, rcut, r2cut, ccut, x, bBox, box, - hbox, &dist, &ang, bDA, &h, bContact, bMerge); + ihb = is_hbond(__HBDATA, grp, ogrp, i, j, + rcut, r2cut, ccut, x, bBox, + box, hbox, &dist, &ang, bDA, + &h, bContact, bMerge); if (ihb) { /* add to index if not already there */ /* Add a hbond */ - add_hbond(__HBDATA, i, j, h, grp, ogrp, nframes, bMerge, ihb, bContact); + add_hbond(__HBDATA, i, j, h, grp, ogrp, + nframes, bMerge, ihb, bContact); /* make angle and distance distributions */ if (ihb == hbHB && !bContact) { if (dist > rcut) { - gmx_fatal(FARGS, "distance is higher than what is allowed for an hbond: %f", dist); + gmx_fatal( + FARGS, + "distance is higher " + "than what is allowed " + "for an hbond: %f", + dist); } ang *= RAD2DEG; - __ADIST[static_cast( ang/abin)]++; - __RDIST[static_cast(dist/rbin)]++; + __ADIST[static_cast(ang / abin)]++; + __RDIST[static_cast(dist / rbin)]++; if (!bTwo) { if (donor_index(&hb->d, grp, i) == NOTSET) { - gmx_fatal(FARGS, "Invalid donor %d", i); + gmx_fatal( + FARGS, + "Invalid donor %d", i); } - if (acceptor_index(&hb->a, ogrp, j) == NOTSET) + if (acceptor_index(&hb->a, ogrp, j) + == NOTSET) { - gmx_fatal(FARGS, "Invalid acceptor %d", j); + gmx_fatal(FARGS, + "Invalid " + "acceptor %d", + j); } - resdist = std::abs(top.atoms.atom[i].resind-top.atoms.atom[j].resind); + resdist = std::abs( + top.atoms.atom[i].resind + - top.atoms.atom[j].resind); if (resdist >= max_hx) { - resdist = max_hx-1; + resdist = max_hx - 1; } __HBDATA->nhx[nframes][resdist]++; } } - } } /* for aj */ } /* for xjj */ @@ -3040,7 +3121,7 @@ int gmx_hbond(int argc, char *argv[]) } /* for xi,yi,zi */ } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* if (bSelected) {...} else */ @@ -3055,15 +3136,15 @@ int gmx_hbond(int argc, char *argv[]) /* Sum up histograms and counts from p_hb[] into hb */ if (bOMP) { - hb->nhb[k] += p_hb[threadNr]->nhb[k]; + hb->nhb[k] += p_hb[threadNr]->nhb[k]; hb->ndist[k] += p_hb[threadNr]->ndist[k]; for (j = 0; j < max_hx; j++) { - hb->nhx[k][j] += p_hb[threadNr]->nhx[k][j]; + hb->nhx[k][j] += p_hb[threadNr]->nhx[k][j]; } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Here are a handful of single constructs @@ -3078,7 +3159,7 @@ int gmx_hbond(int argc, char *argv[]) { analyse_donor_properties(donor_properties, hb, k, t); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #pragma omp single @@ -3090,7 +3171,7 @@ int gmx_hbond(int argc, char *argv[]) do_nhb_dist(fpnhb, hb, t); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #pragma omp single @@ -3100,18 +3181,17 @@ int gmx_hbond(int argc, char *argv[]) trrStatus = (read_next_x(oenv, status, &t, x, box)); nframes++; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #pragma omp barrier - } - while (trrStatus); + } while (trrStatus); if (bOMP) { #pragma omp critical { - hb->nrhb += p_hb[threadNr]->nrhb; + hb->nrhb += p_hb[threadNr]->nrhb; hb->nrdist += p_hb[threadNr]->nrdist; } @@ -3131,7 +3211,7 @@ int gmx_hbond(int argc, char *argv[]) adist[i] += p_adist[j][i]; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } #pragma omp for for (i = 0; i <= nrbin; i++) @@ -3143,7 +3223,7 @@ int gmx_hbond(int argc, char *argv[]) rdist[i] += p_rdist[j][i]; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } sfree(p_adist[threadNr]); @@ -3158,7 +3238,8 @@ int gmx_hbond(int argc, char *argv[]) if (nframes < 2 && (opt2bSet("-ac", NFILE, fnm) || opt2bSet("-life", NFILE, fnm))) { - gmx_fatal(FARGS, "Cannot calculate autocorrelation of life times with less than two frames"); + gmx_fatal(FARGS, + "Cannot calculate autocorrelation of life times with less than two frames"); } free_grid(ngrid, &grid); @@ -3182,7 +3263,7 @@ int gmx_hbond(int argc, char *argv[]) } else { - max_nhb = 0.5*(hb->d.nrd*hb->a.nra); + max_nhb = 0.5 * (hb->d.nrd * hb->a.nra); } if (bHBmap) @@ -3195,8 +3276,8 @@ int gmx_hbond(int argc, char *argv[]) { printf("Found %d different %s in trajectory\n" "Found %d different atom-pairs within %s distance\n", - hb->nrhb, bContact ? "contacts" : "hydrogen bonds", - hb->nrdist, (r2cut > 0) ? "second cut-off" : "hydrogen bonding"); + hb->nrhb, bContact ? "contacts" : "hydrogen bonds", hb->nrdist, + (r2cut > 0) ? "second cut-off" : "hydrogen bonding"); if (bMerge) { @@ -3216,8 +3297,8 @@ int gmx_hbond(int argc, char *argv[]) /* Print out number of hbonds and distances */ aver_nhb = 0; aver_dist = 0; - fp = xvgropen(opt2fn("-num", NFILE, fnm), bContact ? "Contacts" : - "Hydrogen Bonds", output_env_get_xvgr_tlabel(oenv), "Number", oenv); + fp = xvgropen(opt2fn("-num", NFILE, fnm), bContact ? "Contacts" : "Hydrogen Bonds", + output_env_get_xvgr_tlabel(oenv), "Number", oenv); snew(leg, 2); snew(leg[0], STRLEN); snew(leg[1], STRLEN); @@ -3230,11 +3311,11 @@ int gmx_hbond(int argc, char *argv[]) for (i = 0; (i < nframes); i++) { fprintf(fp, "%10g %10d %10d\n", hb->time[i], hb->nhb[i], hb->ndist[i]); - aver_nhb += hb->nhb[i]; + aver_nhb += hb->nhb[i]; aver_dist += hb->ndist[i]; } xvgrclose(fp); - aver_nhb /= nframes; + aver_nhb /= nframes; aver_dist /= nframes; /* Print HB distance distribution */ if (opt2bSet("-dist", NFILE, fnm)) @@ -3247,14 +3328,12 @@ int gmx_hbond(int argc, char *argv[]) sum += rdist[i]; } - fp = xvgropen(opt2fn("-dist", NFILE, fnm), - "Hydrogen Bond Distribution", - bDA ? - "Donor - Acceptor Distance (nm)" : - "Hydrogen - Acceptor Distance (nm)", "", oenv); + fp = xvgropen(opt2fn("-dist", NFILE, fnm), "Hydrogen Bond Distribution", + bDA ? "Donor - Acceptor Distance (nm)" : "Hydrogen - Acceptor Distance (nm)", + "", oenv); for (i = 0; i < nrbin; i++) { - fprintf(fp, "%10g %10g\n", (i+0.5)*rbin, rdist[i]/(rbin*sum)); + fprintf(fp, "%10g %10g\n", (i + 0.5) * rbin, rdist[i] / (rbin * sum)); } xvgrclose(fp); } @@ -3270,12 +3349,11 @@ int gmx_hbond(int argc, char *argv[]) sum += adist[i]; } - fp = xvgropen(opt2fn("-ang", NFILE, fnm), - "Hydrogen Bond Distribution", + fp = xvgropen(opt2fn("-ang", NFILE, fnm), "Hydrogen Bond Distribution", "Hydrogen - Donor - Acceptor Angle (\\SO\\N)", "", oenv); for (i = 0; i < nabin; i++) { - fprintf(fp, "%10g %10g\n", (i+0.5)*abin, adist[i]/(abin*sum)); + fprintf(fp, "%10g %10g\n", (i + 0.5) * abin, adist[i] / (abin * sum)); } xvgrclose(fp); } @@ -3283,8 +3361,8 @@ int gmx_hbond(int argc, char *argv[]) /* Print HB in alpha-helix */ if (opt2bSet("-hx", NFILE, fnm)) { - fp = xvgropen(opt2fn("-hx", NFILE, fnm), - "Hydrogen Bonds", output_env_get_xvgr_tlabel(oenv), "Count", oenv); + fp = xvgropen(opt2fn("-hx", NFILE, fnm), "Hydrogen Bonds", output_env_get_xvgr_tlabel(oenv), + "Count", oenv); xvgr_legend(fp, NRHXTYPES, hxtypenames, oenv); for (i = 0; i < nframes; i++) { @@ -3299,8 +3377,7 @@ int gmx_hbond(int argc, char *argv[]) } printf("Average number of %s per timeframe %.3f out of %g possible\n", - bContact ? "contacts" : "hbonds", - bContact ? aver_dist : aver_nhb, max_nhb); + bContact ? "contacts" : "hbonds", bContact ? aver_dist : aver_nhb, max_nhb); /* Do Autocorrelation etc. */ if (hb->bHBmap) @@ -3315,9 +3392,8 @@ int gmx_hbond(int argc, char *argv[]) } if (opt2bSet("-ac", NFILE, fnm)) { - do_hbac(opt2fn("-ac", NFILE, fnm), hb, nDump, - bMerge, bContact, fit_start, temp, r2cut > 0, oenv, - nThreads); + do_hbac(opt2fn("-ac", NFILE, fnm), hb, nDump, bMerge, bContact, fit_start, temp, + r2cut > 0, oenv, nThreads); } if (opt2bSet("-life", NFILE, fnm)) { @@ -3335,7 +3411,7 @@ int gmx_hbond(int argc, char *argv[]) mat.ny = hb->nrhb; mat.matrix.resize(mat.nx, mat.ny); - for (auto &value : mat.matrix.toArrayRef()) + for (auto& value : mat.matrix.toArrayRef()) { value = 0; } @@ -3354,7 +3430,8 @@ int gmx_hbond(int argc, char *argv[]) { int nn0 = hb->hbmap[id][ia]->n0; range_check(y, 0, mat.ny); - mat.matrix(x+nn0, y) = static_cast(is_hb(hb->hbmap[id][ia]->h[hh], x)); + mat.matrix(x + nn0, y) = static_cast( + is_hb(hb->hbmap[id][ia]->h[hh], x)); } y++; } @@ -3365,14 +3442,13 @@ int gmx_hbond(int argc, char *argv[]) std::copy(hb->time, hb->time + mat.nx, mat.axis_x.begin()); mat.axis_y.resize(mat.ny); std::iota(mat.axis_y.begin(), mat.axis_y.end(), 0); - mat.title = (bContact ? "Contact Existence Map" : - "Hydrogen Bond Existence Map"); - mat.legend = bContact ? "Contacts" : "Hydrogen Bonds"; - mat.label_x = output_env_get_xvgr_tlabel(oenv); - mat.label_y = bContact ? "Contact Index" : "Hydrogen Bond Index"; + mat.title = (bContact ? "Contact Existence Map" : "Hydrogen Bond Existence Map"); + mat.legend = bContact ? "Contacts" : "Hydrogen Bonds"; + mat.label_x = output_env_get_xvgr_tlabel(oenv); + mat.label_y = bContact ? "Contact Index" : "Hydrogen Bond Index"; mat.bDiscrete = true; mat.map.resize(2); - for (auto &m : mat.map) + for (auto& m : mat.map) { m.code.c1 = hbmap[i]; m.desc = hbdesc[i]; @@ -3384,7 +3460,9 @@ int gmx_hbond(int argc, char *argv[]) } else { - fprintf(stderr, "No hydrogen bonds/contacts found. No hydrogen bond map will be printed.\n"); + fprintf(stderr, + "No hydrogen bonds/contacts found. No hydrogen bond map will be " + "printed.\n"); } } } @@ -3392,19 +3470,19 @@ int gmx_hbond(int argc, char *argv[]) if (hb->bDAnr) { int i, j, nleg; - char **legnames; + char** legnames; char buf[STRLEN]; -#define USE_THIS_GROUP(j) ( ((j) == gr0) || (bTwo && ((j) == gr1)) ) +#define USE_THIS_GROUP(j) (((j) == gr0) || (bTwo && ((j) == gr1))) - fp = xvgropen(opt2fn("-dan", NFILE, fnm), - "Donors and Acceptors", output_env_get_xvgr_tlabel(oenv), "Count", oenv); - nleg = (bTwo ? 2 : 1)*2; + fp = xvgropen(opt2fn("-dan", NFILE, fnm), "Donors and Acceptors", + output_env_get_xvgr_tlabel(oenv), "Count", oenv); + nleg = (bTwo ? 2 : 1) * 2; snew(legnames, nleg); i = 0; for (j = 0; j < grNR; j++) { - if (USE_THIS_GROUP(j) ) + if (USE_THIS_GROUP(j)) { sprintf(buf, "Donors %s", grpnames[j]); legnames[i++] = gmx_strdup(buf); @@ -3422,7 +3500,7 @@ int gmx_hbond(int argc, char *argv[]) fprintf(fp, "%10g", hb->time[i]); for (j = 0; (j < grNR); j++) { - if (USE_THIS_GROUP(j) ) + if (USE_THIS_GROUP(j)) { fprintf(fp, " %6d", hb->danr[i][j]); } diff --git a/src/gromacs/gmxana/gmx_helix.cpp b/src/gromacs/gmxana/gmx_helix.cpp index 7f659c1e15..13f5d04874 100644 --- a/src/gromacs/gmxana/gmx_helix.cpp +++ b/src/gromacs/gmxana/gmx_helix.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,9 +58,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -int gmx_helix(int argc, char *argv[]) +int gmx_helix(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes all kinds of helix properties. First, the peptide", "is checked to find the longest helical part, as determined by", "hydrogen bonds and [GRK]phi[grk]/[GRK]psi[grk] angles.", @@ -70,8 +70,8 @@ int gmx_helix(int argc, char *argv[]) "", " * Helix radius (file [TT]radius.xvg[tt]). This is merely the", " RMS deviation in two dimensions for all C[GRK]alpha[grk] atoms.", - " it is calculated as [SQRT]([SUM][sum][SUB]i[sub] (x^2(i)+y^2(i)))/N[sqrt] where N is the number", - " of backbone atoms. For an ideal helix the radius is 0.23 nm.", + " it is calculated as [SQRT]([SUM][sum][SUB]i[sub] (x^2(i)+y^2(i)))/N[sqrt] where N is ", + " the number of backbone atoms. For an ideal helix the radius is 0.23 nm.", " * Twist (file [TT]twist.xvg[tt]). The average helical angle per", " residue is calculated. For an [GRK]alpha[grk]-helix it is 100 degrees,", " for 3-10 helices it will be smaller, and ", @@ -90,86 +90,81 @@ int gmx_helix(int argc, char *argv[]) " * Average [GRK]phi[grk] and [GRK]psi[grk] angles (file [TT]phipsi.xvg[tt]).", " * Ellipticity at 222 nm according to Hirst and Brooks." }; - static gmx_bool bCheck = FALSE, bFit = TRUE, bDBG = FALSE, bEV = FALSE; - static int rStart = 0, rEnd = 0, r0 = 1; - t_pargs pa [] = { - { "-r0", FALSE, etINT, {&r0}, - "The first residue number in the sequence" }, - { "-q", FALSE, etBOOL, {&bCheck}, - "Check at every step which part of the sequence is helical" }, - { "-F", FALSE, etBOOL, {&bFit}, - "Toggle fit to a perfect helix" }, - { "-db", FALSE, etBOOL, {&bDBG}, - "Print debug info" }, - { "-ev", FALSE, etBOOL, {&bEV}, - "Write a new 'trajectory' file for ED" }, - { "-ahxstart", FALSE, etINT, {&rStart}, - "First residue in helix" }, - { "-ahxend", FALSE, etINT, {&rEnd}, - "Last residue in helix" } - }; + static gmx_bool bCheck = FALSE, bFit = TRUE, bDBG = FALSE, bEV = FALSE; + static int rStart = 0, rEnd = 0, r0 = 1; + t_pargs pa[] = { { "-r0", FALSE, etINT, { &r0 }, "The first residue number in the sequence" }, + { "-q", + FALSE, + etBOOL, + { &bCheck }, + "Check at every step which part of the sequence is helical" }, + { "-F", FALSE, etBOOL, { &bFit }, "Toggle fit to a perfect helix" }, + { "-db", FALSE, etBOOL, { &bDBG }, "Print debug info" }, + { "-ev", FALSE, etBOOL, { &bEV }, "Write a new 'trajectory' file for ED" }, + { "-ahxstart", FALSE, etINT, { &rStart }, "First residue in helix" }, + { "-ahxend", FALSE, etINT, { &rEnd }, "Last residue in helix" } }; - typedef struct { //NOLINT(clang-analyzer-optin.performance.Padding) - FILE *fp, *fp2; + typedef struct + { //NOLINT(clang-analyzer-optin.performance.Padding) + FILE * fp, *fp2; gmx_bool bfp2; - const char *filenm; - const char *title; - const char *xaxis; - const char *yaxis; + const char* filenm; + const char* title; + const char* xaxis; + const char* yaxis; real val; } t_xvgrfile; - t_xvgrfile xf[efhNR] = { - { nullptr, nullptr, TRUE, "radius", "Helix radius", nullptr, "r (nm)", 0.0 }, - { nullptr, nullptr, TRUE, "twist", "Twist per residue", nullptr, "Angle (deg)", 0.0 }, - { nullptr, nullptr, TRUE, "rise", "Rise per residue", nullptr, "Rise (nm)", 0.0 }, - { nullptr, nullptr, FALSE, "len-ahx", "Length of the Helix", nullptr, "Length (nm)", 0.0 }, - { nullptr, nullptr, FALSE, "dip-ahx", "Helix Backbone Dipole", nullptr, "rq (nm e)", 0.0 }, - { nullptr, nullptr, TRUE, "rms-ahx", "RMS Deviation from Ideal Helix", nullptr, "RMS (nm)", 0.0 }, - { nullptr, nullptr, FALSE, "rmsa-ahx", "Average RMSD per Residue", "Residue", "RMS (nm)", 0.0 }, - { nullptr, nullptr, FALSE, "cd222", "Ellipticity at 222 nm", nullptr, "nm", 0.0 }, - { nullptr, nullptr, TRUE, "pprms", "RMS Distance from \\8a\\4-helix", nullptr, "deg", 0.0 }, - { nullptr, nullptr, TRUE, "caphi", "Average Ca-Ca Dihedral", nullptr, "\\8F\\4(deg)", 0.0 }, - { nullptr, nullptr, TRUE, "phi", "Average \\8F\\4 angles", nullptr, "deg", 0.0 }, - { nullptr, nullptr, TRUE, "psi", "Average \\8Y\\4 angles", nullptr, "deg", 0.0 }, - { nullptr, nullptr, TRUE, "hb3", "Average n-n+3 hbond length", nullptr, "nm", 0.0 }, - { nullptr, nullptr, TRUE, "hb4", "Average n-n+4 hbond length", nullptr, "nm", 0.0 }, - { nullptr, nullptr, TRUE, "hb5", "Average n-n+5 hbond length", nullptr, "nm", 0.0 }, - { nullptr, nullptr, FALSE, "JCaHa", "J-Coupling Values", "Residue", "Hz", 0.0 }, - { nullptr, nullptr, FALSE, "helicity", "Helicity per Residue", "Residue", "% of time", 0.0 } + t_xvgrfile xf[efhNR] = { + { nullptr, nullptr, TRUE, "radius", "Helix radius", nullptr, "r (nm)", 0.0 }, + { nullptr, nullptr, TRUE, "twist", "Twist per residue", nullptr, "Angle (deg)", 0.0 }, + { nullptr, nullptr, TRUE, "rise", "Rise per residue", nullptr, "Rise (nm)", 0.0 }, + { nullptr, nullptr, FALSE, "len-ahx", "Length of the Helix", nullptr, "Length (nm)", 0.0 }, + { nullptr, nullptr, FALSE, "dip-ahx", "Helix Backbone Dipole", nullptr, "rq (nm e)", 0.0 }, + { nullptr, nullptr, TRUE, "rms-ahx", "RMS Deviation from Ideal Helix", nullptr, "RMS (nm)", 0.0 }, + { nullptr, nullptr, FALSE, "rmsa-ahx", "Average RMSD per Residue", "Residue", "RMS (nm)", 0.0 }, + { nullptr, nullptr, FALSE, "cd222", "Ellipticity at 222 nm", nullptr, "nm", 0.0 }, + { nullptr, nullptr, TRUE, "pprms", "RMS Distance from \\8a\\4-helix", nullptr, "deg", 0.0 }, + { nullptr, nullptr, TRUE, "caphi", "Average Ca-Ca Dihedral", nullptr, "\\8F\\4(deg)", 0.0 }, + { nullptr, nullptr, TRUE, "phi", "Average \\8F\\4 angles", nullptr, "deg", 0.0 }, + { nullptr, nullptr, TRUE, "psi", "Average \\8Y\\4 angles", nullptr, "deg", 0.0 }, + { nullptr, nullptr, TRUE, "hb3", "Average n-n+3 hbond length", nullptr, "nm", 0.0 }, + { nullptr, nullptr, TRUE, "hb4", "Average n-n+4 hbond length", nullptr, "nm", 0.0 }, + { nullptr, nullptr, TRUE, "hb5", "Average n-n+5 hbond length", nullptr, "nm", 0.0 }, + { nullptr, nullptr, FALSE, "JCaHa", "J-Coupling Values", "Residue", "Hz", 0.0 }, + { nullptr, nullptr, FALSE, "helicity", "Helicity per Residue", "Residue", "% of time", 0.0 } }; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; char buf[54]; - t_trxstatus *status; + t_trxstatus* status; int natoms, nres; - t_bb *bb; + t_bb* bb; int i, j, nall, nbb, nca, teller; - int *bbindex, *caindex, *allindex; - t_topology *top; + int * bbindex, *caindex, *allindex; + t_topology* top; int ePBC; - rvec *x, *xref; + rvec * x, *xref; real t; real rms; matrix box; gmx_rmpbc_t gpbc = nullptr; gmx_bool bRange; t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffREAD }, + { efTRX, "-f", nullptr, ffREAD }, { efSTO, "-cz", "zconf", ffWRITE }, }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - bRange = (opt2parg_bSet("-ahxstart", asize(pa), pa) && - opt2parg_bSet("-ahxend", asize(pa), pa)); + bRange = (opt2parg_bSet("-ahxstart", asize(pa), pa) && opt2parg_bSet("-ahxend", asize(pa), pa)); top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC); @@ -177,12 +172,14 @@ int gmx_helix(int argc, char *argv[]) if (natoms != top->atoms.nr) { - gmx_fatal(FARGS, "Sorry can only run when the number of atoms in the run input file (%d) is equal to the number in the trajectory (%d)", + gmx_fatal(FARGS, + "Sorry can only run when the number of atoms in the run input file (%d) is equal " + "to the number in the trajectory (%d)", top->atoms.nr, natoms); } - bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex, - top->atoms.atomname, top->atoms.atom, top->atoms.resinfo); + bb = mkbbind(ftp2fn(efNDX, NFILE, fnm), &nres, &nbb, r0, &nall, &allindex, top->atoms.atomname, + top->atoms.atom, top->atoms.resinfo); snew(bbindex, natoms); snew(caindex, nres); @@ -193,9 +190,7 @@ int gmx_helix(int argc, char *argv[]) { sprintf(buf, "%s.xvg", xf[i].filenm); remove(buf); - xf[i].fp = xvgropen(buf, xf[i].title, - xf[i].xaxis ? xf[i].xaxis : "Time (ps)", - xf[i].yaxis, oenv); + xf[i].fp = xvgropen(buf, xf[i].title, xf[i].xaxis ? xf[i].xaxis : "Time (ps)", xf[i].yaxis, oenv); if (xf[i].bfp2) { sprintf(buf, "%s.out", xf[i].filenm); @@ -206,8 +201,7 @@ int gmx_helix(int argc, char *argv[]) /* Read reference frame from tpx file to compute helix length */ snew(xref, top->atoms.nr); - read_tpx(ftp2fn(efTPR, NFILE, fnm), - nullptr, nullptr, nullptr, xref, nullptr, nullptr); + read_tpx(ftp2fn(efTPR, NFILE, fnm), nullptr, nullptr, nullptr, xref, nullptr, nullptr); calc_hxprops(nres, bb, xref); do_start_end(nres, bb, &nbb, bbindex, &nca, caindex, bRange, rStart, rEnd); sfree(xref); @@ -242,8 +236,8 @@ int gmx_helix(int argc, char *argv[]) if (teller == 1) { - write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", - &(top->atoms), x, nullptr, ePBC, box); + write_sto_conf(opt2fn("-cz", NFILE, fnm), "Helix fitted to Z-Axis", &(top->atoms), + x, nullptr, ePBC, box); } xf[efhRAD].val = radius(xf[efhRAD].fp2, nca, caindex, x); @@ -258,18 +252,14 @@ int gmx_helix(int argc, char *argv[]) for (j = 0; (j <= efhCPHI); j++) { - fprintf(xf[j].fp, "%10g %10g\n", t, xf[j].val); + fprintf(xf[j].fp, "%10g %10g\n", t, xf[j].val); } - av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2, - t, nres, bb); - av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2, - xf[efhHB4].fp, xf[efhHB4].fp2, - xf[efhHB5].fp, xf[efhHB5].fp2, - t, nres, bb); + av_phipsi(xf[efhPHI].fp, xf[efhPSI].fp, xf[efhPHI].fp2, xf[efhPSI].fp2, t, nres, bb); + av_hblen(xf[efhHB3].fp, xf[efhHB3].fp2, xf[efhHB4].fp, xf[efhHB4].fp2, xf[efhHB5].fp, + xf[efhHB5].fp2, t, nres, bb); } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); gmx_rmpbc_done(gpbc); @@ -280,11 +270,11 @@ int gmx_helix(int argc, char *argv[]) { if (bb[i].nrms > 0) { - fprintf(xf[efhRMSA].fp, "%10d %10g\n", r0+i, bb[i].rmsa/bb[i].nrms); + fprintf(xf[efhRMSA].fp, "%10d %10g\n", r0 + i, bb[i].rmsa / bb[i].nrms); } - fprintf(xf[efhAHX].fp, "%10d %10g\n", r0+i, (bb[i].nhx*100.0)/static_cast(teller)); - fprintf(xf[efhJCA].fp, "%10d %10g\n", - r0+i, 140.3+(bb[i].jcaha/static_cast(teller))); + fprintf(xf[efhAHX].fp, "%10d %10g\n", r0 + i, (bb[i].nhx * 100.0) / static_cast(teller)); + fprintf(xf[efhJCA].fp, "%10d %10g\n", r0 + i, + 140.3 + (bb[i].jcaha / static_cast(teller))); } for (i = 0; (i < efhNR); i++) diff --git a/src/gromacs/gmxana/gmx_helixorient.cpp b/src/gromacs/gmxana/gmx_helixorient.cpp index 8b5a3c9bcf..fef5d10ae4 100644 --- a/src/gromacs/gmxana/gmx_helixorient.cpp +++ b/src/gromacs/gmxana/gmx_helixorient.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,9 +55,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -int gmx_helixorient(int argc, char *argv[]) +int gmx_helixorient(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates the coordinates and direction of the average", "axis inside an alpha helix, and the direction/vectors of both the", "C[GRK]alpha[grk] and (optionally) a sidechain atom relative to the axis.[PAR]", @@ -69,99 +69,101 @@ int gmx_helixorient(int argc, char *argv[]) "We need four C[GRK]alpha[grk] coordinates to define the local direction of the helix", "axis.[PAR]", "The tilt/rotation is calculated from Euler rotations, where we define", - "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as [IT]y[it], and the", + "the helix axis as the local [IT]x[it]-axis, the residues/C[GRK]alpha[grk] vector as ", + "[IT]y[it], and the", "[IT]z[it]-axis from their cross product. We use the Euler Y-Z-X rotation, meaning", "we first tilt the helix axis (1) around and (2) orthogonal to the residues", "vector, and finally apply the (3) rotation around it. For debugging or other", "purposes, we also write out the actual Euler rotation angles as [TT]theta[1-3].xvg[tt]" }; - t_topology *top = nullptr; - real t; - rvec *x = nullptr; - matrix box; - t_trxstatus *status; - int natoms; - real theta1, theta2, theta3; - - int i, j, teller = 0; - int iCA, iSC; - int *ind_CA; - int *ind_SC; - char *gn_CA; - char *gn_SC; - rvec v1, v2; - rvec *x_CA, *x_SC; - rvec *r12; - rvec *r23; - rvec *r34; - rvec *diff13; - rvec *diff24; - rvec *helixaxis; - rvec *residuehelixaxis; - rvec *residueorigin; - rvec *residuevector; - rvec *sidechainvector; - - rvec *residuehelixaxis_t0; - rvec *residuevector_t0; - rvec *axis3_t0; - rvec *residuehelixaxis_tlast; - rvec *residuevector_tlast; - rvec *axis3_tlast; - rvec refaxes[3], newaxes[3]; - rvec unitaxes[3]; - rvec rot_refaxes[3], rot_newaxes[3]; - - real tilt, rotation; - rvec *axis3; - real *twist, *residuetwist; - real *radius, *residueradius; - real *rise, *residuerise; - real *residuebending; - - real tmp; - real weight[3]; - t_pbc pbc; - matrix A; - - FILE *fpaxis, *fpcenter, *fptilt, *fprotation; - FILE *fpradius, *fprise, *fptwist; - FILE *fptheta1, *fptheta2, *fptheta3; - FILE *fpbending; - int ePBC; - - gmx_output_env_t *oenv; + t_topology* top = nullptr; + real t; + rvec* x = nullptr; + matrix box; + t_trxstatus* status; + int natoms; + real theta1, theta2, theta3; + + int i, j, teller = 0; + int iCA, iSC; + int* ind_CA; + int* ind_SC; + char* gn_CA; + char* gn_SC; + rvec v1, v2; + rvec *x_CA, *x_SC; + rvec* r12; + rvec* r23; + rvec* r34; + rvec* diff13; + rvec* diff24; + rvec* helixaxis; + rvec* residuehelixaxis; + rvec* residueorigin; + rvec* residuevector; + rvec* sidechainvector; + + rvec* residuehelixaxis_t0; + rvec* residuevector_t0; + rvec* axis3_t0; + rvec* residuehelixaxis_tlast; + rvec* residuevector_tlast; + rvec* axis3_tlast; + rvec refaxes[3], newaxes[3]; + rvec unitaxes[3]; + rvec rot_refaxes[3], rot_newaxes[3]; + + real tilt, rotation; + rvec* axis3; + real *twist, *residuetwist; + real *radius, *residueradius; + real *rise, *residuerise; + real* residuebending; + + real tmp; + real weight[3]; + t_pbc pbc; + matrix A; + + FILE *fpaxis, *fpcenter, *fptilt, *fprotation; + FILE *fpradius, *fprise, *fptwist; + FILE *fptheta1, *fptheta2, *fptheta3; + FILE* fpbending; + int ePBC; + + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - static gmx_bool bSC = FALSE; - static gmx_bool bIncremental = FALSE; + static gmx_bool bSC = FALSE; + static gmx_bool bIncremental = FALSE; - static t_pargs pa[] = { - { "-sidechain", FALSE, etBOOL, {&bSC}, + static t_pargs pa[] = { + { "-sidechain", + FALSE, + etBOOL, + { &bSC }, "Calculate sidechain directions relative to helix axis too." }, - { "-incremental", FALSE, etBOOL, {&bIncremental}, + { "-incremental", + FALSE, + etBOOL, + { &bIncremental }, "Calculate incremental rather than total rotation/tilt." }, }; #define NPA asize(pa) t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-oaxis", "helixaxis", ffWRITE }, - { efDAT, "-ocenter", "center", ffWRITE }, - { efXVG, "-orise", "rise", ffWRITE }, - { efXVG, "-oradius", "radius", ffWRITE }, - { efXVG, "-otwist", "twist", ffWRITE }, - { efXVG, "-obending", "bending", ffWRITE }, - { efXVG, "-otilt", "tilt", ffWRITE }, - { efXVG, "-orot", "rotation", ffWRITE } + { efTPR, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efDAT, "-oaxis", "helixaxis", ffWRITE }, + { efDAT, "-ocenter", "center", ffWRITE }, { efXVG, "-orise", "rise", ffWRITE }, + { efXVG, "-oradius", "radius", ffWRITE }, { efXVG, "-otwist", "twist", ffWRITE }, + { efXVG, "-obending", "bending", ffWRITE }, { efXVG, "-otilt", "tilt", ffWRITE }, + { efXVG, "-orot", "rotation", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0, + nullptr, &oenv)) { return 0; } @@ -179,12 +181,12 @@ int gmx_helixorient(int argc, char *argv[]) snew(x_CA, iCA); snew(x_SC, iCA); /* sic! */ - snew(r12, iCA-3); - snew(r23, iCA-3); - snew(r34, iCA-3); - snew(diff13, iCA-3); - snew(diff24, iCA-3); - snew(helixaxis, iCA-3); + snew(r12, iCA - 3); + snew(r23, iCA - 3); + snew(r34, iCA - 3); + snew(diff13, iCA - 3); + snew(diff24, iCA - 3); + snew(helixaxis, iCA - 3); snew(twist, iCA); snew(residuetwist, iCA); snew(radius, iCA); @@ -212,7 +214,6 @@ int gmx_helixorient(int argc, char *argv[]) { gmx_fatal(FARGS, "Number of sidechain atoms (%d) != number of CA atoms (%d)", iSC, iCA); } - } natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); @@ -230,20 +231,17 @@ int gmx_helixorient(int argc, char *argv[]) if (bIncremental) { - fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), - "Incremental local helix tilt", "Time(ps)", "Tilt (degrees)", - oenv); - fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), - "Incremental local helix rotation", "Time(ps)", - "Rotation (degrees)", oenv); + fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), "Incremental local helix tilt", "Time(ps)", + "Tilt (degrees)", oenv); + fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), "Incremental local helix rotation", + "Time(ps)", "Rotation (degrees)", oenv); } else { - fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), - "Cumulative local helix tilt", "Time(ps)", "Tilt (degrees)", oenv); - fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), - "Cumulative local helix rotation", "Time(ps)", - "Rotation (degrees)", oenv); + fptilt = xvgropen(opt2fn("-otilt", NFILE, fnm), "Cumulative local helix tilt", "Time(ps)", + "Tilt (degrees)", oenv); + fprotation = xvgropen(opt2fn("-orot", NFILE, fnm), "Cumulative local helix rotation", + "Time(ps)", "Rotation (degrees)", oenv); } clear_rvecs(3, unitaxes); @@ -270,27 +268,27 @@ int gmx_helixorient(int argc, char *argv[]) } } - for (i = 0; i < iCA-3; i++) + for (i = 0; i < iCA - 3; i++) { - rvec_sub(x_CA[i+1], x_CA[i], r12[i]); - rvec_sub(x_CA[i+2], x_CA[i+1], r23[i]); - rvec_sub(x_CA[i+3], x_CA[i+2], r34[i]); + rvec_sub(x_CA[i + 1], x_CA[i], r12[i]); + rvec_sub(x_CA[i + 2], x_CA[i + 1], r23[i]); + rvec_sub(x_CA[i + 3], x_CA[i + 2], r34[i]); rvec_sub(r12[i], r23[i], diff13[i]); rvec_sub(r23[i], r34[i], diff24[i]); /* calculate helix axis */ cprod(diff13[i], diff24[i], helixaxis[i]); - svmul(1.0/norm(helixaxis[i]), helixaxis[i], helixaxis[i]); + svmul(1.0 / norm(helixaxis[i]), helixaxis[i], helixaxis[i]); tmp = cos_angle(diff13[i], diff24[i]); - twist[i] = 180.0/M_PI * std::acos( tmp ); - radius[i] = std::sqrt( norm(diff13[i])*norm(diff24[i]) ) / (2.0* (1.0-tmp) ); + twist[i] = 180.0 / M_PI * std::acos(tmp); + radius[i] = std::sqrt(norm(diff13[i]) * norm(diff24[i])) / (2.0 * (1.0 - tmp)); rise[i] = std::abs(iprod(r23[i], helixaxis[i])); - svmul(radius[i]/norm(diff13[i]), diff13[i], v1); - svmul(radius[i]/norm(diff24[i]), diff24[i], v2); + svmul(radius[i] / norm(diff13[i]), diff13[i], v1); + svmul(radius[i] / norm(diff24[i]), diff24[i], v2); - rvec_sub(x_CA[i+1], v1, residueorigin[i+1]); - rvec_sub(x_CA[i+2], v2, residueorigin[i+2]); + rvec_sub(x_CA[i + 1], v1, residueorigin[i + 1]); + rvec_sub(x_CA[i + 2], v2, residueorigin[i + 2]); } residueradius[0] = residuetwist[0] = residuerise[0] = 0; @@ -299,21 +297,21 @@ int gmx_helixorient(int argc, char *argv[]) residuerise[1] = rise[0]; residuebending[0] = residuebending[1] = 0; - for (i = 2; i < iCA-2; i++) + for (i = 2; i < iCA - 2; i++) { - residueradius[i] = 0.5*(radius[i-2]+radius[i-1]); - residuetwist[i] = 0.5*(twist[i-2]+twist[i-1]); - residuerise[i] = 0.5*(rise[i-2]+rise[i-1]); - residuebending[i] = 180.0/M_PI*std::acos( cos_angle(helixaxis[i-2], helixaxis[i-1]) ); + residueradius[i] = 0.5 * (radius[i - 2] + radius[i - 1]); + residuetwist[i] = 0.5 * (twist[i - 2] + twist[i - 1]); + residuerise[i] = 0.5 * (rise[i - 2] + rise[i - 1]); + residuebending[i] = 180.0 / M_PI * std::acos(cos_angle(helixaxis[i - 2], helixaxis[i - 1])); } - residueradius[iCA-2] = radius[iCA-4]; - residuetwist[iCA-2] = twist[iCA-4]; - residuerise[iCA-2] = rise[iCA-4]; - residueradius[iCA-1] = residuetwist[iCA-1] = residuerise[iCA-1] = 0; - residuebending[iCA-2] = residuebending[iCA-1] = 0; + residueradius[iCA - 2] = radius[iCA - 4]; + residuetwist[iCA - 2] = twist[iCA - 4]; + residuerise[iCA - 2] = rise[iCA - 4]; + residueradius[iCA - 1] = residuetwist[iCA - 1] = residuerise[iCA - 1] = 0; + residuebending[iCA - 2] = residuebending[iCA - 1] = 0; clear_rvec(residueorigin[0]); - clear_rvec(residueorigin[iCA-1]); + clear_rvec(residueorigin[iCA - 1]); /* average helix axes to define them on the residues. * Just extrapolate second first/list atom. @@ -321,18 +319,18 @@ int gmx_helixorient(int argc, char *argv[]) copy_rvec(helixaxis[0], residuehelixaxis[0]); copy_rvec(helixaxis[0], residuehelixaxis[1]); - for (i = 2; i < iCA-2; i++) + for (i = 2; i < iCA - 2; i++) { - rvec_add(helixaxis[i-2], helixaxis[i-1], residuehelixaxis[i]); + rvec_add(helixaxis[i - 2], helixaxis[i - 1], residuehelixaxis[i]); svmul(0.5, residuehelixaxis[i], residuehelixaxis[i]); } - copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-2]); - copy_rvec(helixaxis[iCA-4], residuehelixaxis[iCA-1]); + copy_rvec(helixaxis[iCA - 4], residuehelixaxis[iCA - 2]); + copy_rvec(helixaxis[iCA - 4], residuehelixaxis[iCA - 1]); /* Normalize the axis */ for (i = 0; i < iCA; i++) { - svmul(1.0/norm(residuehelixaxis[i]), residuehelixaxis[i], residuehelixaxis[i]); + svmul(1.0 / norm(residuehelixaxis[i]), residuehelixaxis[i], residuehelixaxis[i]); } /* calculate vector from origin to residue CA */ @@ -345,7 +343,7 @@ int gmx_helixorient(int argc, char *argv[]) for (i = 0; i < iCA; i++) { - if (i == 0 || i == iCA-1) + if (i == 0 || i == iCA - 1) { fprintf(fpaxis, "%15.12g %15.12g %15.12g ", 0.0, 0.0, 0.0); fprintf(fpcenter, "%15.12g %15.12g %15.12g ", 0.0, 0.0, 0.0); @@ -356,11 +354,13 @@ int gmx_helixorient(int argc, char *argv[]) } else { - rvec_sub( bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]); - svmul(1.0/norm(residuevector[i]), residuevector[i], residuevector[i]); + rvec_sub(bSC ? x_SC[i] : x_CA[i], residueorigin[i], residuevector[i]); + svmul(1.0 / norm(residuevector[i]), residuevector[i], residuevector[i]); cprod(residuehelixaxis[i], residuevector[i], axis3[i]); - fprintf(fpaxis, "%15.12g %15.12g %15.12g ", residuehelixaxis[i][0], residuehelixaxis[i][1], residuehelixaxis[i][2]); - fprintf(fpcenter, "%15.12g %15.12g %15.12g ", residueorigin[i][0], residueorigin[i][1], residueorigin[i][2]); + fprintf(fpaxis, "%15.12g %15.12g %15.12g ", residuehelixaxis[i][0], + residuehelixaxis[i][1], residuehelixaxis[i][2]); + fprintf(fpcenter, "%15.12g %15.12g %15.12g ", residueorigin[i][0], + residueorigin[i][1], residueorigin[i][2]); fprintf(fprise, "%15.12g ", residuerise[i]); fprintf(fpradius, "%15.12g ", residueradius[i]); @@ -394,7 +394,7 @@ int gmx_helixorient(int argc, char *argv[]) for (i = 0; i < iCA; i++) { - if (i == 0 || i == iCA-1) + if (i == 0 || i == iCA - 1) { tilt = rotation = 0; } @@ -434,16 +434,15 @@ int gmx_helixorient(int argc, char *argv[]) * A contains rotation column vectors. */ - theta1 = 180.0/M_PI*std::atan2(A[0][2], A[0][0]); - theta2 = 180.0/M_PI*std::asin(-A[0][1]); - theta3 = 180.0/M_PI*std::atan2(A[2][1], A[1][1]); + theta1 = 180.0 / M_PI * std::atan2(A[0][2], A[0][0]); + theta2 = 180.0 / M_PI * std::asin(-A[0][1]); + theta3 = 180.0 / M_PI * std::atan2(A[2][1], A[1][1]); - tilt = std::sqrt(theta1*theta1+theta2*theta2); + tilt = std::sqrt(theta1 * theta1 + theta2 * theta2); rotation = theta3; fprintf(fptheta1, "%15.12g ", theta1); fprintf(fptheta2, "%15.12g ", theta2); fprintf(fptheta3, "%15.12g ", theta3); - } fprintf(fptilt, "%15.12g ", tilt); fprintf(fprotation, "%15.12g ", rotation); @@ -463,8 +462,7 @@ int gmx_helixorient(int argc, char *argv[]) } teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_hydorder.cpp b/src/gromacs/gmxana/gmx_hydorder.cpp index 2b2ce9572c..c7f81a1ee4 100644 --- a/src/gromacs/gmxana/gmx_hydorder.cpp +++ b/src/gromacs/gmxana/gmx_hydorder.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,20 +60,28 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -static void find_tetra_order_grid(t_topology top, int ePBC, - int natoms, matrix box, - rvec x[], int maxidx, const int index[], - real *sgmean, real *skmean, - int nslicex, int nslicey, int nslicez, - real ***sggrid, real ***skgrid) +static void find_tetra_order_grid(t_topology top, + int ePBC, + int natoms, + matrix box, + rvec x[], + int maxidx, + const int index[], + real* sgmean, + real* skmean, + int nslicex, + int nslicey, + int nslicez, + real*** sggrid, + real*** skgrid) { int ix, jx, i, j, k, l, n, *nn[4]; rvec dx, rj, rk, urk, urj; real cost, cost2, *sgmol, *skmol, rmean, rmean2, r2, box2, *r_nn[4]; t_pbc pbc; int slindex_x, slindex_y, slindex_z; - int ***sl_count; - real onethird = 1.0/3.0; + int*** sl_count; + real onethird = 1.0 / 3.0; gmx_rmpbc_t gpbc; /* dmat = init_mat(maxidx, FALSE); */ @@ -114,7 +123,7 @@ static void find_tetra_order_grid(t_topology top, int ePBC, *skmean = 0.0; l = 0; for (i = 0; (i < maxidx); i++) - { /* loop over index file */ + { /* loop over index file */ ix = index[i]; for (j = 0; (j < maxidx); j++) { @@ -134,25 +143,35 @@ static void find_tetra_order_grid(t_topology top, int ePBC, /* determine the nearest neighbours */ if (r2 < r_nn[0][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i]; - r_nn[1][i] = r_nn[0][i]; nn[1][i] = nn[0][i]; - r_nn[0][i] = r2; nn[0][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r_nn[1][i]; + nn[2][i] = nn[1][i]; + r_nn[1][i] = r_nn[0][i]; + nn[1][i] = nn[0][i]; + r_nn[0][i] = r2; + nn[0][i] = j; } else if (r2 < r_nn[1][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i]; - r_nn[1][i] = r2; nn[1][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r_nn[1][i]; + nn[2][i] = nn[1][i]; + r_nn[1][i] = r2; + nn[1][i] = j; } else if (r2 < r_nn[2][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r2; nn[2][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r2; + nn[2][i] = j; } else if (r2 < r_nn[3][i]) { - r_nn[3][i] = r2; nn[3][i] = j; + r_nn[3][i] = r2; + nn[3][i] = j; } } @@ -162,7 +181,7 @@ static void find_tetra_order_grid(t_topology top, int ePBC, for (j = 0; (j < 4); j++) { r_nn[j][i] = std::sqrt(r_nn[j][i]); - rmean += r_nn[j][i]; + rmean += r_nn[j][i]; } rmean /= 4; @@ -174,7 +193,7 @@ static void find_tetra_order_grid(t_topology top, int ePBC, /* angular part tetrahedrality order parameter per atom */ for (j = 0; (j < 3); j++) { - for (k = j+1; (k < 4); k++) + for (k = j + 1; (k < 4); k++) { pbc_dx(&pbc, x[ix], x[index[nn[k][i]]], rk); pbc_dx(&pbc, x[ix], x[index[nn[j][i]]], rj); @@ -191,7 +210,7 @@ static void find_tetra_order_grid(t_topology top, int ePBC, } } /* normalize sgmol between 0.0 and 1.0 */ - sgmol[i] = 3*sgmol[i]/32; + sgmol[i] = 3 * sgmol[i] / 32; *sgmean += sgmol[i]; /* distance part tetrahedrality order parameter per atom */ @@ -207,9 +226,9 @@ static void find_tetra_order_grid(t_topology top, int ePBC, *skmean += skmol[i]; /* Compute sliced stuff in x y z*/ - slindex_x = static_cast(std::round((1+x[i][XX]/box[XX][XX])*nslicex)) % nslicex; - slindex_y = static_cast(std::round((1+x[i][YY]/box[YY][YY])*nslicey)) % nslicey; - slindex_z = static_cast(std::round((1+x[i][ZZ]/box[ZZ][ZZ])*nslicez)) % nslicez; + slindex_x = static_cast(std::round((1 + x[i][XX] / box[XX][XX]) * nslicex)) % nslicex; + slindex_y = static_cast(std::round((1 + x[i][YY] / box[YY][YY]) * nslicey)) % nslicey; + slindex_z = static_cast(std::round((1 + x[i][ZZ] / box[ZZ][ZZ]) * nslicez)) % nslicez; sggrid[slindex_x][slindex_y][slindex_z] += sgmol[i]; skgrid[slindex_x][slindex_y][slindex_z] += skmol[i]; (sl_count[slindex_x][slindex_y][slindex_z])++; @@ -246,43 +265,52 @@ static void find_tetra_order_grid(t_topology top, int ePBC, /*Determines interface from tetrahedral order parameter in box with specified binwidth. */ /*Outputs interface positions(bins), the number of timeframes, and the number of surface-mesh points in xy*/ -static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, const char *fnTRX, real binw, int tblock, - int *nframes, int *nslicex, int *nslicey, - real sgang1, real sgang2, real ****intfpos, - gmx_output_env_t *oenv) +static void calc_tetra_order_interface(const char* fnNDX, + const char* fnTPS, + const char* fnTRX, + real binw, + int tblock, + int* nframes, + int* nslicex, + int* nslicey, + real sgang1, + real sgang2, + real**** intfpos, + gmx_output_env_t* oenv) { - FILE *fpsg = nullptr, *fpsk = nullptr; - t_topology top; - int ePBC; - t_trxstatus *status; - int natoms; - real t; - rvec *xtop, *x; - matrix box; - real sg, sk, sgintf; - int **index = nullptr; - char **grpname = nullptr; - int i, j, k, n, *isize, ng, nslicez, framenr; - real ***sg_grid = nullptr, ***sk_grid = nullptr, ***sg_fravg = nullptr, ***sk_fravg = nullptr, ****sk_4d = nullptr, ****sg_4d = nullptr; - int *perm; - int ndx1, ndx2; - int bins; - const real onehalf = 1.0/2.0; + FILE * fpsg = nullptr, *fpsk = nullptr; + t_topology top; + int ePBC; + t_trxstatus* status; + int natoms; + real t; + rvec * xtop, *x; + matrix box; + real sg, sk, sgintf; + int** index = nullptr; + char** grpname = nullptr; + int i, j, k, n, *isize, ng, nslicez, framenr; + real ***sg_grid = nullptr, ***sk_grid = nullptr, ***sg_fravg = nullptr, ***sk_fravg = nullptr, + ****sk_4d = nullptr, ****sg_4d = nullptr; + int* perm; + int ndx1, ndx2; + int bins; + const real onehalf = 1.0 / 2.0; /* real ***intfpos[2]; pointers to arrays of two interface positions zcoord(framenr,xbin,ybin): intfpos[interface_index][t][nslicey*x+y] * i.e 1D Row-major order in (t,x,y) */ read_tps_conf(fnTPS, &top, &ePBC, &xtop, nullptr, box, FALSE); - *nslicex = static_cast(box[XX][XX]/binw + onehalf); /*Calculate slicenr from binwidth*/ - *nslicey = static_cast(box[YY][YY]/binw + onehalf); - nslicez = static_cast(box[ZZ][ZZ]/binw + onehalf); - + *nslicex = static_cast(box[XX][XX] / binw + onehalf); /*Calculate slicenr from binwidth*/ + *nslicey = static_cast(box[YY][YY] / binw + onehalf); + nslicez = static_cast(box[ZZ][ZZ] / binw + onehalf); ng = 1; /* get index groups */ - printf("Select the group that contains the atoms you want to use for the tetrahedrality order parameter calculation:\n"); + printf("Select the group that contains the atoms you want to use for the tetrahedrality order " + "parameter calculation:\n"); snew(grpname, ng); snew(index, ng); snew(isize, ng); @@ -292,8 +320,7 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box); if (natoms > top.atoms.nr) { - gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", - top.atoms.nr, natoms); + gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", top.atoms.nr, natoms); } check_index(nullptr, ng, index[0], nullptr, natoms); @@ -317,14 +344,14 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con *nframes = 0; framenr = 0; -/* Loop over frames*/ + /* Loop over frames*/ do { /*Initialize box meshes (temporary storage for each tblock frame -reinitialise every tblock steps */ - if (framenr%tblock == 0) + if (framenr % tblock == 0) { - srenew(sk_4d, *nframes+1); - srenew(sg_4d, *nframes+1); + srenew(sk_4d, *nframes + 1); + srenew(sg_4d, *nframes + 1); snew(sg_fravg, *nslicex); snew(sk_fravg, *nslicex); for (i = 0; i < *nslicex; i++) @@ -339,8 +366,8 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con } } - find_tetra_order_grid(top, ePBC, natoms, box, x, isize[0], index[0], - &sg, &sk, *nslicex, *nslicey, nslicez, sg_grid, sk_grid); + find_tetra_order_grid(top, ePBC, natoms, box, x, isize[0], index[0], &sg, &sk, *nslicex, + *nslicey, nslicez, sg_grid, sk_grid); GMX_RELEASE_ASSERT(sk_fravg != nullptr, "Trying to dereference NULL sk_fravg pointer"); for (i = 0; i < *nslicex; i++) { @@ -348,15 +375,15 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con { for (k = 0; k < nslicez; k++) { - sk_fravg[i][j][k] += sk_grid[i][j][k]/tblock; - sg_fravg[i][j][k] += sg_grid[i][j][k]/tblock; + sk_fravg[i][j][k] += sk_grid[i][j][k] / tblock; + sg_fravg[i][j][k] += sg_grid[i][j][k] / tblock; } } } framenr++; - if (framenr%tblock == 0) + if (framenr % tblock == 0) { GMX_RELEASE_ASSERT(sk_4d != nullptr, "Trying to dereference NULL sk_4d pointer"); sk_4d[*nframes] = sk_fravg; @@ -364,8 +391,7 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con (*nframes)++; } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); sfree(grpname); @@ -375,8 +401,10 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con /*Debugging for printing out the entire order parameter meshes.*/ if (debug) { - fpsg = xvgropen("sg_ang_mesh", "S\\sg\\N Angle Order Parameter / Meshpoint", "(nm)", "S\\sg\\N", oenv); - fpsk = xvgropen("sk_dist_mesh", "S\\sk\\N Distance Order Parameter / Meshpoint", "(nm)", "S\\sk\\N", oenv); + fpsg = xvgropen("sg_ang_mesh", "S\\sg\\N Angle Order Parameter / Meshpoint", "(nm)", + "S\\sg\\N", oenv); + fpsk = xvgropen("sk_dist_mesh", "S\\sk\\N Distance Order Parameter / Meshpoint", "(nm)", + "S\\sk\\N", oenv); for (n = 0; n < (*nframes); n++) { fprintf(fpsg, "%i\n", n); @@ -387,8 +415,12 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con { for (k = 0; k < nslicez; k++) { - fprintf(fpsg, "%4f %4f %4f %8f\n", (i+0.5)*box[XX][XX]/(*nslicex), (j+0.5)*box[YY][YY]/(*nslicey), (k+0.5)*box[ZZ][ZZ]/nslicez, sg_4d[n][i][j][k]); - fprintf(fpsk, "%4f %4f %4f %8f\n", (i+0.5)*box[XX][XX]/(*nslicex), (j+0.5)*box[YY][YY]/(*nslicey), (k+0.5)*box[ZZ][ZZ]/nslicez, sk_4d[n][i][j][k]); + fprintf(fpsg, "%4f %4f %4f %8f\n", (i + 0.5) * box[XX][XX] / (*nslicex), + (j + 0.5) * box[YY][YY] / (*nslicey), + (k + 0.5) * box[ZZ][ZZ] / nslicez, sg_4d[n][i][j][k]); + fprintf(fpsk, "%4f %4f %4f %8f\n", (i + 0.5) * box[XX][XX] / (*nslicex), + (j + 0.5) * box[YY][YY] / (*nslicey), + (k + 0.5) * box[ZZ][ZZ] / nslicez, sk_4d[n][i][j][k]); } } } @@ -401,7 +433,7 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con /* Find positions of interface z by scanning orderparam for each frame and for each xy-mesh cylinder along z*/ /*Simple trial: assume interface is in the middle of -sgang1 and sgang2*/ - sgintf = 0.5*(sgang1+sgang2); + sgintf = 0.5 * (sgang1 + sgang2); /*Allocate memory for interface arrays; */ @@ -409,10 +441,10 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con snew((*intfpos)[0], *nframes); snew((*intfpos)[1], *nframes); - bins = (*nslicex)*(*nslicey); + bins = (*nslicex) * (*nslicey); - snew(perm, nslicez); /*permutation array for sorting along normal coordinate*/ + snew(perm, nslicez); /*permutation array for sorting along normal coordinate*/ for (n = 0; n < *nframes; n++) @@ -425,18 +457,18 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con { rangeArray(perm, nslicez); /*reset permutation array to identity*/ /*Binsearch returns 2 bin-numbers where the order param is <= setpoint sgintf*/ - ndx1 = start_binsearch(sg_4d[n][i][j], perm, 0, nslicez/2-1, sgintf, 1); - ndx2 = start_binsearch(sg_4d[n][i][j], perm, nslicez/2, nslicez-1, sgintf, -1); + ndx1 = start_binsearch(sg_4d[n][i][j], perm, 0, nslicez / 2 - 1, sgintf, 1); + ndx2 = start_binsearch(sg_4d[n][i][j], perm, nslicez / 2, nslicez - 1, sgintf, -1); /*Use linear interpolation to smooth out the interface position*/ /*left interface (0)*/ /*if((sg_4d[n][i][j][perm[ndx1+1]]-sg_4d[n][i][j][perm[ndx1]])/sg_4d[n][i][j][perm[ndx1]] > 0.01){ pos=( (sgintf-sg_4d[n][i][j][perm[ndx1]])*perm[ndx1+1]+(sg_4d[n][i][j][perm[ndx1+1]]-sgintf)*perm[ndx1 ])*/ - (*intfpos)[0][n][j+*nslicey*i] = (perm[ndx1]+onehalf)*binw; + (*intfpos)[0][n][j + *nslicey * i] = (perm[ndx1] + onehalf) * binw; /*right interface (1)*/ /*alpha=(sgintf-sg_4d[n][i][j][perm[ndx2]])/(sg_4d[n][i][j][perm[ndx2]+1]-sg_4d[n][i][j][perm[ndx2]]);*/ /*(*intfpos)[1][n][j+*nslicey*i]=((1-alpha)*perm[ndx2]+alpha*(perm[ndx2]+1)+onehalf)*box[ZZ][ZZ]/nslicez;*/ - (*intfpos)[1][n][j+*nslicey*i] = (perm[ndx2]+onehalf)*binw; + (*intfpos)[1][n][j + *nslicey * i] = (perm[ndx2] + onehalf) * binw; } } } @@ -446,31 +478,37 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con sfree(sg_4d); } -static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, real bw, gmx::ArrayRef outfiles, int maplevels ) +static void writesurftoxpms(real*** surf, + int tblocks, + int xbins, + int ybins, + real bw, + gmx::ArrayRef outfiles, + int maplevels) { char numbuf[STRLEN]; int n, i, j; real **profile1, **profile2; real max1, max2, min1, min2, *xticks, *yticks; - t_rgb lo = {1, 1, 1}; - t_rgb hi = {0, 0, 0}; - FILE *xpmfile1, *xpmfile2; + t_rgb lo = { 1, 1, 1 }; + t_rgb hi = { 0, 0, 0 }; + FILE * xpmfile1, *xpmfile2; -/*Prepare xpm structures for output*/ + /*Prepare xpm structures for output*/ -/*Allocate memory to tick's and matrices*/ - snew (xticks, xbins+1); - snew (yticks, ybins+1); + /*Allocate memory to tick's and matrices*/ + snew(xticks, xbins + 1); + snew(yticks, ybins + 1); profile1 = mk_matrix(xbins, ybins, FALSE); profile2 = mk_matrix(xbins, ybins, FALSE); - for (i = 0; i < xbins+1; i++) + for (i = 0; i < xbins + 1; i++) { xticks[i] += bw; } - for (j = 0; j < ybins+1; j++) + for (j = 0; j < ybins + 1; j++) { yticks[j] += bw; } @@ -489,8 +527,8 @@ static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, rea { for (j = 0; j < ybins; j++) { - profile1[i][j] = (surf[0][n][j+ybins*i]); - profile2[i][j] = (surf[1][n][j+ybins*i]); + profile1[i][j] = (surf[0][n][j + ybins * i]); + profile2[i][j] = (surf[1][n][j + ybins * i]); /*Finding max and min values*/ if (profile1[i][j] > max1) { @@ -511,15 +549,16 @@ static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, rea } } - write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile1, min1, max1, lo, hi, &maplevels); - write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, profile2, min2, max2, lo, hi, &maplevels); + write_xpm(xpmfile1, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, + profile1, min1, max1, lo, hi, &maplevels); + write_xpm(xpmfile2, 3, numbuf, "Height", "x[nm]", "y[nm]", xbins, ybins, xticks, yticks, + profile2, min2, max2, lo, hi, &maplevels); } gmx_ffclose(xpmfile1); gmx_ffclose(xpmfile2); - sfree(profile1); sfree(profile2); sfree(xticks); @@ -527,8 +566,7 @@ static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, rea } -static void writeraw(real ***surf, int tblocks, int xbins, int ybins, - gmx::ArrayRef fnms) +static void writeraw(real*** surf, int tblocks, int xbins, int ybins, gmx::ArrayRef fnms) { FILE *raw1, *raw2; int i, j, n; @@ -545,8 +583,8 @@ static void writeraw(real ***surf, int tblocks, int xbins, int ybins, { for (j = 0; j < ybins; j++) { - fprintf(raw1, "%i %i %8.5f\n", i, j, (surf[0][n][j+ybins*i])); - fprintf(raw2, "%i %i %8.5f\n", i, j, (surf[1][n][j+ybins*i])); + fprintf(raw1, "%i %i %8.5f\n", i, j, (surf[0][n][j + ybins * i])); + fprintf(raw2, "%i %i %8.5f\n", i, j, (surf[1][n][j + ybins * i])); } } } @@ -556,10 +594,9 @@ static void writeraw(real ***surf, int tblocks, int xbins, int ybins, } - -int gmx_hydorder(int argc, char *argv[]) +int gmx_hydorder(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] computes the tetrahedrality order parameters around a ", "given atom. Both angle an distance order parameters are calculated. See", "P.-L. Chau and A.J. Hardwick, Mol. Phys., 93, (1998), 511-518.", @@ -575,44 +612,39 @@ int gmx_hydorder(int argc, char *argv[]) static int nlevels = 100; static real binwidth = 1.0; /* binwidth in mesh */ static real sg1 = 1; - static real sg2 = 1; /* order parameters for bulk phases */ + static real sg2 = 1; /* order parameters for bulk phases */ static gmx_bool bFourier = FALSE; static gmx_bool bRawOut = FALSE; int frames, xslices, yslices; /* Dimensions of interface arrays*/ - real ***intfpos; /* Interface arrays (intfnr,t,xy) -potentially large */ - static const char *normal_axis[] = { nullptr, "z", "x", "y", nullptr }; - - t_pargs pa[] = { - { "-d", FALSE, etENUM, {normal_axis}, - "Direction of the normal on the membrane" }, - { "-bw", FALSE, etREAL, {&binwidth}, - "Binwidth of box mesh" }, - { "-sgang1", FALSE, etREAL, {&sg1}, - "tetrahedral angle parameter in Phase 1 (bulk)" }, - { "-sgang2", FALSE, etREAL, {&sg2}, - "tetrahedral angle parameter in Phase 2 (bulk)" }, - { "-tblock", FALSE, etINT, {&nsttblock}, - "Number of frames in one time-block average"}, - { "-nlevel", FALSE, etINT, {&nlevels}, - "Number of Height levels in 2D - XPixMaps"} + real*** intfpos; /* Interface arrays (intfnr,t,xy) -potentially large */ + static const char* normal_axis[] = { nullptr, "z", "x", "y", nullptr }; + + t_pargs pa[] = { + { "-d", FALSE, etENUM, { normal_axis }, "Direction of the normal on the membrane" }, + { "-bw", FALSE, etREAL, { &binwidth }, "Binwidth of box mesh" }, + { "-sgang1", FALSE, etREAL, { &sg1 }, "tetrahedral angle parameter in Phase 1 (bulk)" }, + { "-sgang2", FALSE, etREAL, { &sg2 }, "tetrahedral angle parameter in Phase 2 (bulk)" }, + { "-tblock", FALSE, etINT, { &nsttblock }, "Number of frames in one time-block average" }, + { "-nlevel", FALSE, etINT, { &nlevels }, "Number of Height levels in 2D - XPixMaps" } }; - t_filenm fnm[] = { /* files for g_order */ - { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ - { efNDX, "-n", nullptr, ffREAD }, /* index file */ - { efTPR, "-s", nullptr, ffREAD }, /* topology file */ - { efXPM, "-o", "intf", ffWRMULT}, /* XPM- surface maps */ - { efOUT, "-or", "raw", ffOPTWRMULT }, /* xvgr output file */ - { efOUT, "-Spect", "intfspect", ffOPTWRMULT}, /* Fourier spectrum interfaces */ + t_filenm fnm[] = { + /* files for g_order */ + { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ + { efNDX, "-n", nullptr, ffREAD }, /* index file */ + { efTPR, "-s", nullptr, ffREAD }, /* topology file */ + { efXPM, "-o", "intf", ffWRMULT }, /* XPM- surface maps */ + { efOUT, "-or", "raw", ffOPTWRMULT }, /* xvgr output file */ + { efOUT, "-Spect", "intfspect", ffOPTWRMULT }, /* Fourier spectrum interfaces */ }; #define NFILE asize(fnm) /*Filenames*/ - const char *ndxfnm, *tpsfnm, *trxfnm; - gmx_output_env_t *oenv; + const char * ndxfnm, *tpsfnm, *trxfnm; + gmx_output_env_t* oenv; - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -629,7 +661,8 @@ int gmx_hydorder(int argc, char *argv[]) trxfnm = ftp2fn(efTRX, NFILE, fnm); /* Calculate axis */ - GMX_RELEASE_ASSERT(normal_axis[0] != nullptr, "Option setting inconsistency; normal_axis[0] is NULL"); + GMX_RELEASE_ASSERT(normal_axis[0] != nullptr, + "Option setting inconsistency; normal_axis[0] is NULL"); if (std::strcmp(normal_axis[0], "x") == 0) { axis = XX; @@ -649,15 +682,9 @@ int gmx_hydorder(int argc, char *argv[]) switch (axis) { - case 0: - fprintf(stderr, "Taking x axis as normal to the membrane\n"); - break; - case 1: - fprintf(stderr, "Taking y axis as normal to the membrane\n"); - break; - case 2: - fprintf(stderr, "Taking z axis as normal to the membrane\n"); - break; + case 0: fprintf(stderr, "Taking x axis as normal to the membrane\n"); break; + case 1: fprintf(stderr, "Taking y axis as normal to the membrane\n"); break; + case 2: fprintf(stderr, "Taking z axis as normal to the membrane\n"); break; } /* tetraheder order parameter */ @@ -667,7 +694,8 @@ int gmx_hydorder(int argc, char *argv[]) { gmx_fatal(FARGS, "No or not correct number (2) of output-files: %td", intfn.ssize()); } - calc_tetra_order_interface(ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices, &yslices, sg1, sg2, &intfpos, oenv); + calc_tetra_order_interface(ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices, + &yslices, sg1, sg2, &intfpos, oenv); writesurftoxpms(intfpos, frames, xslices, yslices, binwidth, intfn, nlevels); if (bFourier) diff --git a/src/gromacs/gmxana/gmx_lie.cpp b/src/gromacs/gmxana/gmx_lie.cpp index 17dba3971f..d19ee95a30 100644 --- a/src/gromacs/gmxana/gmx_lie.cpp +++ b/src/gromacs/gmxana/gmx_lie.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,16 +56,17 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int nlj, nqq; - int *lj; - int *qq; + int* lj; + int* qq; } t_liedata; -static t_liedata *analyze_names(int nre, gmx_enxnm_t *names, const char *ligand) +static t_liedata* analyze_names(int nre, gmx_enxnm_t* names, const char* ligand) { int i; - t_liedata *ld; + t_liedata* ld; char self[256]; /* Skip until we come to pressure */ @@ -82,20 +83,19 @@ static t_liedata *analyze_names(int nre, gmx_enxnm_t *names, const char *ligand) snew(ld, 1); for (; (i < nre); i++) { - if ((std::strstr(names[i].name, ligand) != nullptr) && - (std::strstr(names[i].name, self) == nullptr)) + if ((std::strstr(names[i].name, ligand) != nullptr) && (std::strstr(names[i].name, self) == nullptr)) { if (std::strstr(names[i].name, "LJ") != nullptr) { ld->nlj++; srenew(ld->lj, ld->nlj); - ld->lj[ld->nlj-1] = i; + ld->lj[ld->nlj - 1] = i; } else if (std::strstr(names[i].name, "Coul") != nullptr) { ld->nqq++; srenew(ld->qq, ld->nqq); - ld->qq[ld->nqq-1] = i; + ld->qq[ld->nqq - 1] = i; } } } @@ -115,8 +115,7 @@ static t_liedata *analyze_names(int nre, gmx_enxnm_t *names, const char *ligand) return ld; } -static real calc_lie(t_liedata *ld, t_energy ee[], real lie_lj, real lie_qq, - real fac_lj, real fac_qq) +static real calc_lie(t_liedata* ld, t_energy ee[], real lie_lj, real lie_qq, real fac_lj, real fac_qq) { int i; real lj_tot, qq_tot; @@ -133,12 +132,12 @@ static real calc_lie(t_liedata *ld, t_energy ee[], real lie_lj, real lie_qq, } /* And now the great LIE formula: */ - return fac_lj*(lj_tot-lie_lj)+fac_qq*(qq_tot-lie_qq); + return fac_lj * (lj_tot - lie_lj) + fac_qq * (qq_tot - lie_qq); } -int gmx_lie(int argc, char *argv[]) +int gmx_lie(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes a free energy estimate based on an energy analysis", "from nonbonded energies. One needs an energy file with the following components:", "Coul-(A-B) LJ-SR (A-B) etc.[PAR]", @@ -149,39 +148,43 @@ int gmx_lie(int argc, char *argv[]) "are necessary for supplying suitable values for -Elj and -Eqq." }; static real lie_lj = 0, lie_qq = 0, fac_lj = 0.181, fac_qq = 0.5; - static const char *ligand = "none"; + static const char* ligand = "none"; t_pargs pa[] = { - { "-Elj", FALSE, etREAL, {&lie_lj}, + { "-Elj", + FALSE, + etREAL, + { &lie_lj }, "Lennard-Jones interaction between ligand and solvent" }, - { "-Eqq", FALSE, etREAL, {&lie_qq}, - "Coulomb interaction between ligand and solvent" }, - { "-Clj", FALSE, etREAL, {&fac_lj}, + { "-Eqq", FALSE, etREAL, { &lie_qq }, "Coulomb interaction between ligand and solvent" }, + { "-Clj", + FALSE, + etREAL, + { &fac_lj }, "Factor in the LIE equation for Lennard-Jones component of energy" }, - { "-Cqq", FALSE, etREAL, {&fac_qq}, + { "-Cqq", + FALSE, + etREAL, + { &fac_qq }, "Factor in the LIE equation for Coulomb component of energy" }, - { "-ligand", FALSE, etSTR, {&ligand}, - "Name of the ligand in the energy file" } + { "-ligand", FALSE, etSTR, { &ligand }, "Name of the ligand in the energy file" } }; #define NPA asize(pa) - FILE *out; + FILE* out; int nre, nframes = 0, ct = 0; ener_file_t fp; - t_liedata *ld; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; + t_liedata* ld; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; real lie; double lieaver = 0, lieav2 = 0; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; - t_filenm fnm[] = { - { efEDR, "-f", "ener", ffREAD }, - { efXVG, "-o", "lie", ffWRITE } - }; + t_filenm fnm[] = { { efEDR, "-f", "ener", ffREAD }, { efXVG, "-o", "lie", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, NPA, pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -192,16 +195,16 @@ int gmx_lie(int argc, char *argv[]) ld = analyze_names(nre, enm, ligand); snew(fr, 1); - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "LIE free energy estimate", - "Time (ps)", "DGbind (kJ/mol)", oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "LIE free energy estimate", "Time (ps)", + "DGbind (kJ/mol)", oenv); while (do_enx(fp, fr)) { ct = check_times(fr->t); if (ct == 0) { - lie = calc_lie(ld, fr->ener, lie_lj, lie_qq, fac_lj, fac_qq); + lie = calc_lie(ld, fr->ener, lie_lj, lie_qq, fac_lj, fac_qq); lieaver += lie; - lieav2 += lie*lie; + lieav2 += lie * lie; nframes++; fprintf(out, "%10g %10g\n", fr->t, lie); } @@ -212,8 +215,8 @@ int gmx_lie(int argc, char *argv[]) if (nframes > 0) { - printf("DGbind = %.3f (%.3f)\n", lieaver/nframes, - std::sqrt(lieav2/nframes-gmx::square(lieaver/nframes))); + printf("DGbind = %.3f (%.3f)\n", lieaver / nframes, + std::sqrt(lieav2 / nframes - gmx::square(lieaver / nframes))); } do_view(oenv, ftp2fn(efXVG, NFILE, fnm), "-nxy"); diff --git a/src/gromacs/gmxana/gmx_make_edi.cpp b/src/gromacs/gmxana/gmx_make_edi.cpp index 1e9608e3ec..b22d063d2a 100644 --- a/src/gromacs/gmxana/gmx_make_edi.cpp +++ b/src/gromacs/gmxana/gmx_make_edi.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,58 +61,57 @@ typedef struct { - real deltaF0; - gmx_bool bHarmonic; - gmx_bool bConstForce; /* Do constant force flooding instead of - evaluating a flooding potential */ - real tau; - real deltaF; - real kT; - real constEfl; - real alpha2; + real deltaF0; + gmx_bool bHarmonic; + gmx_bool bConstForce; /* Do constant force flooding instead of + evaluating a flooding potential */ + real tau; + real deltaF; + real kT; + real constEfl; + real alpha2; } t_edflood; /* This type is for the average, reference, target, and origin structure */ typedef struct edix { - int nr; /* number of atoms this structure contains */ - int *anrs; /* atom index numbers */ - rvec *x; /* positions */ - real *sqrtm; /* sqrt of the masses used for mass- - * weighting of analysis */ + int nr; /* number of atoms this structure contains */ + int* anrs; /* atom index numbers */ + rvec* x; /* positions */ + real* sqrtm; /* sqrt of the masses used for mass- + * weighting of analysis */ } t_edix; typedef struct edipar { - int nini; /* total Nr of atoms */ - gmx_bool fitmas; /* true if trans fit with cm */ - gmx_bool pcamas; /* true if mass-weighted PCA */ - int presteps; /* number of steps to run without any - * perturbations ... just monitoring */ - int outfrq; /* freq (in steps) of writing to edo */ - int maxedsteps; /* max nr of steps per cycle */ - struct edix sref; /* reference positions, to these fitting - * will be done */ - struct edix sav; /* average positions */ - struct edix star; /* target positions */ - struct edix sori; /* origin positions */ - real slope; /* minimal slope in acceptance radexp */ - int ned; /* Nr of atoms in essdyn buffer */ - t_edflood flood; /* parameters especially for flooding */ + int nini; /* total Nr of atoms */ + gmx_bool fitmas; /* true if trans fit with cm */ + gmx_bool pcamas; /* true if mass-weighted PCA */ + int presteps; /* number of steps to run without any + * perturbations ... just monitoring */ + int outfrq; /* freq (in steps) of writing to edo */ + int maxedsteps; /* max nr of steps per cycle */ + struct edix sref; /* reference positions, to these fitting + * will be done */ + struct edix sav; /* average positions */ + struct edix star; /* target positions */ + struct edix sori; /* origin positions */ + real slope; /* minimal slope in acceptance radexp */ + int ned; /* Nr of atoms in essdyn buffer */ + t_edflood flood; /* parameters especially for flooding */ } t_edipar; - -static void make_t_edx(struct edix *edx, int natoms, rvec *pos, int index[]) +static void make_t_edx(struct edix* edx, int natoms, rvec* pos, int index[]) { edx->nr = natoms; edx->anrs = index; edx->x = pos; } -static void write_t_edx(FILE *fp, struct edix edx, const char *comment) +static void write_t_edx(FILE* fp, struct edix edx, const char* comment) { /*here we copy only the pointers into the t_edx struct no data is copied and edx.box is ignored */ @@ -120,11 +119,11 @@ static void write_t_edx(FILE *fp, struct edix edx, const char *comment) fprintf(fp, "#%s \n %d \n", comment, edx.nr); for (i = 0; i < edx.nr; i++) { - fprintf(fp, "%d %f %f %f\n", (edx.anrs)[i]+1, (edx.x)[i][XX], (edx.x)[i][YY], (edx.x)[i][ZZ]); + fprintf(fp, "%d %f %f %f\n", (edx.anrs)[i] + 1, (edx.x)[i][XX], (edx.x)[i][YY], (edx.x)[i][ZZ]); } } -static int sscan_list(int *list[], const char *str, const char *listname) +static int sscan_list(int* list[], const char* str, const char* listname) { /*this routine scans a string of the form 1,3-6,9 and returns the selected numbers (in this case 1 3 4 5 6 9) in NULL-terminated array of integers. @@ -140,26 +139,34 @@ static int sscan_list(int *list[], const char *str, const char *listname) int n = std::strlen(str); /*enums to define the different lexical stati */ - enum { - sBefore, sNumber, sMinus, sRange, sZero, sSmaller, sError, sSteppedRange + enum + { + sBefore, + sNumber, + sMinus, + sRange, + sZero, + sSmaller, + sError, + sSteppedRange }; - int status = sBefore; /*status of the deterministic automat to scan str */ - int number = 0; - int end_number = 0; + int status = sBefore; /*status of the deterministic automat to scan str */ + int number = 0; + int end_number = 0; - char *start = nullptr; /*holds the string of the number behind a ','*/ - char *end = nullptr; /*holds the string of the number behind a '-' */ + char* start = nullptr; /*holds the string of the number behind a ','*/ + char* end = nullptr; /*holds the string of the number behind a '-' */ - int nvecs = 0; /* counts the number of vectors in the list*/ + int nvecs = 0; /* counts the number of vectors in the list*/ step = nullptr; - snew(pos, n+4); + snew(pos, n + 4); startpos = pos; std::strcpy(pos, str); - pos[n] = ','; - pos[n+1] = '1'; - pos[n+2] = '\0'; + pos[n] = ','; + pos[n + 1] = '1'; + pos[n + 2] = '\0'; *list = nullptr; @@ -186,9 +193,9 @@ static int sscan_list(int *list[], const char *str, const char *listname) if (c == ',') { /*store number*/ - srenew(*list, nvecs+1); + srenew(*list, nvecs + 1); (*list)[nvecs++] = number = std::strtol(start, nullptr, 10); - status = sBefore; + status = sBefore; if (number == 0) { status = sZero; @@ -197,7 +204,8 @@ static int sscan_list(int *list[], const char *str, const char *listname) } else if (c == '-') { - status = sMinus; break; + status = sMinus; + break; } else if (std::isdigit(c)) { @@ -214,7 +222,8 @@ static int sscan_list(int *list[], const char *str, const char *listname) if (std::isdigit(c)) { end = pos; - status = sRange; break; + status = sRange; + break; } else { @@ -227,7 +236,8 @@ static int sscan_list(int *list[], const char *str, const char *listname) { if (step) { - status = sError; break; + status = sError; + break; } else { @@ -252,13 +262,15 @@ static int sscan_list(int *list[], const char *str, const char *listname) status = sBefore; if (number == 0) { - status = sZero; break; + status = sZero; + break; } if (end_number <= number) { - status = sSmaller; break; + status = sSmaller; + break; } - srenew(*list, nvecs+end_number-number+1); + srenew(*list, nvecs + end_number - number + 1); if (step) { istep = strtol(step, nullptr, 10); @@ -291,38 +303,46 @@ static int sscan_list(int *list[], const char *str, const char *listname) /* format error occured */ case sError: - gmx_fatal(FARGS, "Error in the list of eigenvectors for %s at pos %td with char %c", listname, pos-startpos, *(pos-1)); + gmx_fatal(FARGS, "Error in the list of eigenvectors for %s at pos %td with char %c", + listname, pos - startpos, *(pos - 1)); /* logical error occured */ case sZero: - gmx_fatal(FARGS, "Error in the list of eigenvectors for %s at pos %td: eigenvector 0 is not valid", listname, pos-startpos); + gmx_fatal(FARGS, + "Error in the list of eigenvectors for %s at pos %td: eigenvector 0 is " + "not valid", + listname, pos - startpos); case sSmaller: - gmx_fatal(FARGS, "Error in the list of eigenvectors for %s at pos %td: second index %d is not bigger than %d", listname, pos-startpos, end_number, number); + gmx_fatal(FARGS, + "Error in the list of eigenvectors for %s at pos %td: second index %d is " + "not bigger than %d", + listname, pos - startpos, end_number, number); } ++pos; /* read next character */ } /*scanner has finished */ /* append zero to list of eigenvectors */ - srenew(*list, nvecs+1); + srenew(*list, nvecs + 1); (*list)[nvecs] = 0; sfree(startpos); return nvecs; } /*sscan_list*/ -static void write_eigvec(FILE* fp, int natoms, int eig_list[], rvec** eigvecs, int nvec, const char *grouptitle, real steps[]) +static void +write_eigvec(FILE* fp, int natoms, int eig_list[], rvec** eigvecs, int nvec, const char* grouptitle, real steps[]) { -/* eig_list is a zero-terminated list of indices into the eigvecs array. - eigvecs are coordinates of eigenvectors - grouptitle to write in the comment line - steps -- array with stepsizes for evLINFIX, evLINACC and evRADACC - */ + /* eig_list is a zero-terminated list of indices into the eigvecs array. + eigvecs are coordinates of eigenvectors + grouptitle to write in the comment line + steps -- array with stepsizes for evLINFIX, evLINACC and evRADACC + */ - int n = 0, i; rvec x; + int n = 0, i; + rvec x; while (eig_list[n++]) { - ; /*count selected eigenvecs*/ - + /*count selected eigenvecs*/ } - fprintf(fp, "# NUMBER OF EIGENVECTORS + %s\n %d\n", grouptitle, n-1); + fprintf(fp, "# NUMBER OF EIGENVECTORS + %s\n %d\n", grouptitle, n - 1); /* write list of eigenvector indicess */ for (n = 0; eig_list[n]; n++) @@ -345,9 +365,12 @@ static void write_eigvec(FILE* fp, int natoms, int eig_list[], rvec** eigvecs, i { if (eig_list[n] > nvec) { - gmx_fatal(FARGS, "Selected eigenvector %d is higher than maximum number %d of available eigenvectors", eig_list[n], nvec); + gmx_fatal(FARGS, + "Selected eigenvector %d is higher than maximum number %d of available " + "eigenvectors", + eig_list[n], nvec); } - copy_rvec(eigvecs[eig_list[n]-1][i], x); + copy_rvec(eigvecs[eig_list[n] - 1][i], x); fprintf(fp, "%8.5f %8.5f %8.5f\n", x[XX], x[YY], x[ZZ]); } n++; @@ -356,26 +379,41 @@ static void write_eigvec(FILE* fp, int natoms, int eig_list[], rvec** eigvecs, i /*enum referring to the different lists of eigenvectors*/ -enum { - evLINFIX, evLINACC, evFLOOD, evRADFIX, evRADACC, evRADCON, evMON, evNr +enum +{ + evLINFIX, + evLINACC, + evFLOOD, + evRADFIX, + evRADACC, + evRADCON, + evMON, + evNr }; #define oldMAGIC 666 #define MAGIC 670 -static void write_the_whole_thing(FILE* fp, t_edipar *edpars, rvec** eigvecs, - int nvec, int *eig_listen[], real* evStepList[]) +static void write_the_whole_thing(FILE* fp, + t_edipar* edpars, + rvec** eigvecs, + int nvec, + int* eig_listen[], + real* evStepList[]) { -/* write edi-file */ + /* write edi-file */ /*Header*/ - fprintf(fp, "#MAGIC\n %d \n#NINI\n %d\n#FITMAS\n %d\n#ANALYSIS_MAS\n %d\n", - MAGIC, edpars->nini, int(edpars->fitmas), int(edpars->pcamas)); - fprintf(fp, "#OUTFRQ\n %d\n#MAXLEN\n %d\n#SLOPECRIT\n %f\n", - edpars->outfrq, edpars->maxedsteps, edpars->slope); - fprintf(fp, "#PRESTEPS\n %d\n#DELTA_F0\n %f\n#INIT_DELTA_F\n %f\n#TAU\n %f\n#EFL_NULL\n %f\n#ALPHA2\n %f\n#KT\n %f\n#HARMONIC\n %d\n#CONST_FORCE_FLOODING\n %d\n", - edpars->presteps, edpars->flood.deltaF0, edpars->flood.deltaF, edpars->flood.tau, edpars->flood.constEfl, - edpars->flood.alpha2, edpars->flood.kT, int(edpars->flood.bHarmonic), int(edpars->flood.bConstForce)); + fprintf(fp, "#MAGIC\n %d \n#NINI\n %d\n#FITMAS\n %d\n#ANALYSIS_MAS\n %d\n", MAGIC, edpars->nini, + int(edpars->fitmas), int(edpars->pcamas)); + fprintf(fp, "#OUTFRQ\n %d\n#MAXLEN\n %d\n#SLOPECRIT\n %f\n", edpars->outfrq, edpars->maxedsteps, + edpars->slope); + fprintf(fp, + "#PRESTEPS\n %d\n#DELTA_F0\n %f\n#INIT_DELTA_F\n %f\n#TAU\n %f\n#EFL_NULL\n " + "%f\n#ALPHA2\n %f\n#KT\n %f\n#HARMONIC\n %d\n#CONST_FORCE_FLOODING\n %d\n", + edpars->presteps, edpars->flood.deltaF0, edpars->flood.deltaF, edpars->flood.tau, + edpars->flood.constEfl, edpars->flood.alpha2, edpars->flood.kT, + int(edpars->flood.bHarmonic), int(edpars->flood.bConstForce)); /* Average and reference positions */ write_t_edx(fp, edpars->sref, "NREF, XREF"); @@ -384,12 +422,16 @@ static void write_the_whole_thing(FILE* fp, t_edipar *edpars, rvec** eigvecs, /*Eigenvectors */ write_eigvec(fp, edpars->ned, eig_listen[evMON], eigvecs, nvec, "COMPONENTS GROUP 1", nullptr); - write_eigvec(fp, edpars->ned, eig_listen[evLINFIX], eigvecs, nvec, "COMPONENTS GROUP 2", evStepList[evLINFIX]); - write_eigvec(fp, edpars->ned, eig_listen[evLINACC], eigvecs, nvec, "COMPONENTS GROUP 3", evStepList[evLINACC]); - write_eigvec(fp, edpars->ned, eig_listen[evRADFIX], eigvecs, nvec, "COMPONENTS GROUP 4", evStepList[evRADFIX]); + write_eigvec(fp, edpars->ned, eig_listen[evLINFIX], eigvecs, nvec, "COMPONENTS GROUP 2", + evStepList[evLINFIX]); + write_eigvec(fp, edpars->ned, eig_listen[evLINACC], eigvecs, nvec, "COMPONENTS GROUP 3", + evStepList[evLINACC]); + write_eigvec(fp, edpars->ned, eig_listen[evRADFIX], eigvecs, nvec, "COMPONENTS GROUP 4", + evStepList[evRADFIX]); write_eigvec(fp, edpars->ned, eig_listen[evRADACC], eigvecs, nvec, "COMPONENTS GROUP 5", nullptr); write_eigvec(fp, edpars->ned, eig_listen[evRADCON], eigvecs, nvec, "COMPONENTS GROUP 6", nullptr); - write_eigvec(fp, edpars->ned, eig_listen[evFLOOD], eigvecs, nvec, "COMPONENTS GROUP 7", evStepList[evFLOOD]); + write_eigvec(fp, edpars->ned, eig_listen[evFLOOD], eigvecs, nvec, "COMPONENTS GROUP 7", + evStepList[evFLOOD]); /*Target and Origin positions */ @@ -397,10 +439,10 @@ static void write_the_whole_thing(FILE* fp, t_edipar *edpars, rvec** eigvecs, write_t_edx(fp, edpars->sori, "NORIGIN, XORIGIN"); } -static int read_conffile(const char *confin, rvec **x) +static int read_conffile(const char* confin, rvec** x) { - t_topology top; - matrix box; + t_topology top; + matrix box; printf("read coordnumber from file %s\n", confin); read_tps_conf(confin, &top, nullptr, x, nullptr, box, FALSE); printf("number of coordinates in file %d\n", top.atoms.nr); @@ -408,11 +450,10 @@ static int read_conffile(const char *confin, rvec **x) } -static void read_eigenvalues(const int vecs[], const char *eigfile, real values[], - gmx_bool bHesse, real kT, int natoms_average_struct) +static void read_eigenvalues(const int vecs[], const char* eigfile, real values[], gmx_bool bHesse, real kT, int natoms_average_struct) { int neig, nrow, i; - double **eigval; + double** eigval; neig = read_xvg(eigfile, &eigval, &nrow); @@ -422,7 +463,9 @@ static void read_eigenvalues(const int vecs[], const char *eigfile, real values[ if (eigval[1][i] < -0.001 && bHesse) { fprintf(stderr, - "WARNING: The Hessian Matrix has negative eigenvalue %f, we set it to zero (no flooding in this direction)\n\n", eigval[1][i]); + "WARNING: The Hessian Matrix has negative eigenvalue %f, we set it to zero (no " + "flooding in this direction)\n\n", + eigval[1][i]); } if (eigval[1][i] < 0) @@ -436,9 +479,12 @@ static void read_eigenvalues(const int vecs[], const char *eigfile, real values[ { if (vecs[i] < 7) { - gmx_fatal(FARGS, "ERROR: You have chosen one of the first 6 eigenvectors of the HESSE Matrix. That does not make sense, since they correspond to the 6 rotational and translational degrees of freedom.\n\n"); + gmx_fatal(FARGS, + "ERROR: You have chosen one of the first 6 eigenvectors of the HESSE " + "Matrix. That does not make sense, since they correspond to the 6 " + "rotational and translational degrees of freedom.\n\n"); } - values[i] = eigval[1][vecs[i]-1]/kT; + values[i] = eigval[1][vecs[i] - 1] / kT; } } else @@ -458,11 +504,14 @@ static void read_eigenvalues(const int vecs[], const char *eigfile, real values[ * of possible eigenvalues is just S - 1. Since in make_edi we only know N but not S, we can * only warn the user if he picked one of the last 6 of 3N. */ - if (vecs[i] > ( 3 * natoms_average_struct - 6 )) + if (vecs[i] > (3 * natoms_average_struct - 6)) { - gmx_fatal(FARGS, "ERROR: You have chosen one of the last 6 eigenvectors of the COVARIANCE Matrix. That does not make sense, since they correspond to the 6 rotational and translational degrees of freedom.\n\n"); + gmx_fatal(FARGS, + "ERROR: You have chosen one of the last 6 eigenvectors of the COVARIANCE " + "Matrix. That does not make sense, since they correspond to the 6 " + "rotational and translational degrees of freedom.\n\n"); } - values[i] = 1/eigval[1][vecs[i]-1]; + values[i] = 1 / eigval[1][vecs[i] - 1]; } } /* free memory */ @@ -474,12 +523,12 @@ static void read_eigenvalues(const int vecs[], const char *eigfile, real values[ } -static real *scan_vecparams(const char *str, const char * par, int nvecs) +static real* scan_vecparams(const char* str, const char* par, int nvecs) { - char f0[256], f1[256]; /*format strings adapted every pass of the loop*/ - double d; - int i; - real *vec_params; + char f0[256], f1[256]; /*format strings adapted every pass of the loop*/ + double d; + int i; + real* vec_params; snew(vec_params, nvecs); if (str) @@ -501,18 +550,18 @@ static real *scan_vecparams(const char *str, const char * par, int nvecs) } -static void init_edx(struct edix *edx) +static void init_edx(struct edix* edx) { edx->nr = 0; snew(edx->x, 1); snew(edx->anrs, 1); } -static void filter2edx(struct edix *edx, int nindex, int index[], int ngro, - const int igro[], const rvec *x, const char* structure) +static void +filter2edx(struct edix* edx, int nindex, int index[], int ngro, const int igro[], const rvec* x, const char* structure) { -/* filter2edx copies coordinates from x to edx which are given in index - */ + /* filter2edx copies coordinates from x to edx which are given in index + */ int pos, i; int ix = edx->nr; @@ -521,10 +570,7 @@ static void filter2edx(struct edix *edx, int nindex, int index[], int ngro, srenew(edx->anrs, edx->nr); for (i = 0; i < nindex; i++, ix++) { - for (pos = 0; pos < ngro-1 && igro[pos] != index[i]; ++pos) - { - } - ; /*search element in igro*/ + for (pos = 0; pos < ngro - 1 && igro[pos] != index[i]; ++pos) {} /*search element in igro*/ if (igro[pos] != index[i]) { gmx_fatal(FARGS, "Couldn't find atom with index %d in structure %s", index[i], structure); @@ -534,19 +580,25 @@ static void filter2edx(struct edix *edx, int nindex, int index[], int ngro, } } -static void get_structure(const t_atoms *atoms, const char *IndexFile, - const char *StructureFile, struct edix *edx, int nfit, - int ifit[], int nav, int index[]) +static void get_structure(const t_atoms* atoms, + const char* IndexFile, + const char* StructureFile, + struct edix* edx, + int nfit, + int ifit[], + int nav, + int index[]) { - int *igro; /*index corresponding to target or origin structure*/ - int ngro; - int ntar; - rvec *xtar; - char * grpname; + int* igro; /*index corresponding to target or origin structure*/ + int ngro; + int ntar; + rvec* xtar; + char* grpname; ntar = read_conffile(StructureFile, &xtar); - printf("Select an index group of %d elements that corresponds to the atoms in the structure file %s\n", + printf("Select an index group of %d elements that corresponds to the atoms in the structure " + "file %s\n", ntar, StructureFile); get_index(atoms, IndexFile, 1, &ngro, &igro, &grpname); if (ngro != ntar) @@ -563,12 +615,12 @@ static void get_structure(const t_atoms *atoms, const char *IndexFile, } } -int gmx_make_edi(int argc, char *argv[]) +int gmx_make_edi(int argc, char* argv[]) { - static const char *desc[] = { - "[THISMODULE] generates an essential dynamics (ED) sampling input file to be used with [TT]mdrun[tt]", - "based on eigenvectors of a covariance matrix ([gmx-covar]) or from a", + static const char* desc[] = { + "[THISMODULE] generates an essential dynamics (ED) sampling input file to be used with ", + "[TT]mdrun[tt] based on eigenvectors of a covariance matrix ([gmx-covar]) or from a", "normal modes analysis ([gmx-nmeig]).", "ED sampling can be used to manipulate the position along collective coordinates", "(eigenvectors) of (biological) macromolecules during a simulation. Particularly,", @@ -590,7 +642,8 @@ int gmx_make_edi(int argc, char *argv[]) "B.L. de Groot, A.Amadei, R.M. Scheek, N.A.J. van Nuland and H.J.C. Berendsen; ", "An extended sampling of the configurational space of HPr from E. coli", "Proteins: Struct. Funct. Gen. 26: 314-322 (1996)", - "[PAR]You will be prompted for one or more index groups that correspond to the eigenvectors,", + "[PAR]You will be prompted for one or more index groups that correspond to the ", + "eigenvectors,", "reference structure, target positions, etc.[PAR]", "[TT]-mon[tt]: monitor projections of the coordinates onto selected eigenvectors.[PAR]", @@ -606,7 +659,9 @@ int gmx_make_edi(int argc, char *argv[]) "[TT]-radcon[tt]: perform acceptance radius contraction along selected eigenvectors", "towards a target structure specified with [TT]-tar[tt].[PAR]", "NOTE: each eigenvector can be selected only once. [PAR]", - "[TT]-outfrq[tt]: frequency (in steps) of writing out projections etc. to [REF].xvg[ref] file[PAR]", + "[TT]-outfrq[tt]: frequency (in steps) of writing out projections etc. to [REF].xvg[ref] ", + "file", + "[PAR]", "[TT]-slope[tt]: minimal slope in acceptance radius expansion. A new expansion", "cycle will be started if the spontaneous increase of the radius (in nm/step)", "is less than the value specified.[PAR]", @@ -623,39 +678,48 @@ int gmx_make_edi(int argc, char *argv[]) "Take a look on the initial RMSD from the reference structure, which is printed", "out at the start of the simulation; if this is much higher than expected, one", "of the ED molecules might be shifted by a box vector. [PAR]", - "All ED-related output of [TT]mdrun[tt] (specify with [TT]-eo[tt]) is written to a [REF].xvg[ref] file", - "as a function of time in intervals of OUTFRQ steps.[PAR]", + "All ED-related output of [TT]mdrun[tt] (specify with [TT]-eo[tt]) is written to a ", + "[REF].xvg[ref] file as a function of time in intervals of OUTFRQ steps.[PAR]", "[BB]Note[bb] that you can impose multiple ED constraints and flooding potentials in", - "a single simulation (on different molecules) if several [REF].edi[ref] files were concatenated", - "first. The constraints are applied in the order they appear in the [REF].edi[ref] file. ", - "Depending on what was specified in the [REF].edi[ref] input file, the output file contains for each ED dataset", + "a single simulation (on different molecules) if several [REF].edi[ref] files were ", + "concatenated first. The constraints are applied in the order they appear in ", + "the [REF].edi[ref] file. Depending on what was specified in the [REF].edi[ref] ", + "input file, the output file contains for each ED dataset", "", - " * the RMSD of the fitted molecule to the reference structure (for atoms involved in fitting prior to calculating the ED constraints)", + " * the RMSD of the fitted molecule to the reference structure (for atoms involved in ", + " fitting prior to calculating the ED constraints)", " * projections of the positions onto selected eigenvectors", "", "FLOODING:[PAR]", - "with [TT]-flood[tt], you can specify which eigenvectors are used to compute a flooding potential,", + "with [TT]-flood[tt], you can specify which eigenvectors are used to compute a flooding ", + "potential,", "which will lead to extra forces expelling the structure out of the region described", - "by the covariance matrix. If you switch -restrain the potential is inverted and the structure", - "is kept in that region.", + "by the covariance matrix. If you switch -restrain the potential is inverted and the ", + "structure is kept in that region.", "[PAR]", "The origin is normally the average structure stored in the [TT]eigvec.trr[tt] file.", "It can be changed with [TT]-ori[tt] to an arbitrary position in configuration space.", - "With [TT]-tau[tt], [TT]-deltaF0[tt], and [TT]-Eflnull[tt] you control the flooding behaviour.", - "Efl is the flooding strength, it is updated according to the rule of adaptive flooding.", - "Tau is the time constant of adaptive flooding, high [GRK]tau[grk] means slow adaption (i.e. growth). ", + "With [TT]-tau[tt], [TT]-deltaF0[tt], and [TT]-Eflnull[tt] you control the flooding ", + "behaviour. Efl is the flooding strength, it is updated according to the rule of ", + "adaptive flooding. Tau is the time constant of adaptive flooding, high ", + "[GRK]tau[grk] means slow adaption (i.e. growth). ", "DeltaF0 is the flooding strength you want to reach after tau ps of simulation.", "To use constant Efl set [TT]-tau[tt] to zero.", "[PAR]", - "[TT]-alpha[tt] is a fudge parameter to control the width of the flooding potential. A value of 2 has been found", + "[TT]-alpha[tt] is a fudge parameter to control the width of the flooding potential. A ", + "value of 2 has been found", "to give good results for most standard cases in flooding of proteins.", - "[GRK]alpha[grk] basically accounts for incomplete sampling, if you sampled further the width of the ensemble would", + "[GRK]alpha[grk] basically accounts for incomplete sampling, if you sampled further the ", + "width of the ensemble would", "increase, this is mimicked by [GRK]alpha[grk] > 1.", - "For restraining, [GRK]alpha[grk] < 1 can give you smaller width in the restraining potential.", + "For restraining, [GRK]alpha[grk] < 1 can give you smaller width in the restraining ", + "potential.", "[PAR]", "RESTART and FLOODING:", - "If you want to restart a crashed flooding simulation please find the values deltaF and Efl in", - "the output file and manually put them into the [REF].edi[ref] file under DELTA_F0 and EFL_NULL." + "If you want to restart a crashed flooding simulation please find the values deltaF and ", + "Efl in", + "the output file and manually put them into the [REF].edi[ref] file under DELTA_F0 and ", + "EFL_NULL." }; /* Save all the params in this struct and then save it in an edi file. @@ -663,15 +727,17 @@ int gmx_make_edi(int argc, char *argv[]) */ static t_edipar edi_params; - enum { + enum + { evStepNr = evRADFIX + 1 }; - static const char* evSelections[evNr] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - static const char* evOptions[evNr] = {"-linfix", "-linacc", "-flood", "-radfix", "-radacc", "-radcon", "-mon"}; - static const char* evParams[evStepNr] = {nullptr, nullptr}; - static const char* evStepOptions[evStepNr] = {"-linstep", "-accdir", "-not_used", "-radstep"}; + static const char* evSelections[evNr] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; + static const char* evOptions[evNr] = { "-linfix", "-linacc", "-flood", "-radfix", + "-radacc", "-radcon", "-mon" }; + static const char* evParams[evStepNr] = { nullptr, nullptr }; + static const char* evStepOptions[evStepNr] = { "-linstep", "-accdir", "-not_used", "-radstep" }; static const char* ConstForceStr; - static real * evStepList[evStepNr]; + static real* evStepList[evStepNr]; static real radstep = 0.0; static real deltaF0 = 150; static real deltaF = 0; @@ -679,115 +745,183 @@ int gmx_make_edi(int argc, char *argv[]) static real constEfl = 0.0; static real alpha = 1; static int eqSteps = 0; - static int * listen[evNr]; + static int* listen[evNr]; static real T = 300.0; const real kB = 2.5 / 300.0; /* k_boltzmann in MD units */ static gmx_bool bRestrain = FALSE; static gmx_bool bHesse = FALSE; static gmx_bool bHarmonic = FALSE; t_pargs pa[] = { - { "-mon", FALSE, etSTR, {&evSelections[evMON]}, - "Indices of eigenvectors for projections of x (e.g. 1,2-5,9) or 1-100:10 means 1 11 21 31 ... 91" }, - { "-linfix", FALSE, etSTR, {&evSelections[0]}, + { "-mon", + FALSE, + etSTR, + { &evSelections[evMON] }, + "Indices of eigenvectors for projections of x (e.g. 1,2-5,9) or 1-100:10 means 1 11 21 " + "31 ... 91" }, + { "-linfix", + FALSE, + etSTR, + { &evSelections[0] }, "Indices of eigenvectors for fixed increment linear sampling" }, - { "-linacc", FALSE, etSTR, {&evSelections[1]}, + { "-linacc", + FALSE, + etSTR, + { &evSelections[1] }, "Indices of eigenvectors for acceptance linear sampling" }, - { "-radfix", FALSE, etSTR, {&evSelections[3]}, + { "-radfix", + FALSE, + etSTR, + { &evSelections[3] }, "Indices of eigenvectors for fixed increment radius expansion" }, - { "-radacc", FALSE, etSTR, {&evSelections[4]}, + { "-radacc", + FALSE, + etSTR, + { &evSelections[4] }, "Indices of eigenvectors for acceptance radius expansion" }, - { "-radcon", FALSE, etSTR, {&evSelections[5]}, + { "-radcon", + FALSE, + etSTR, + { &evSelections[5] }, "Indices of eigenvectors for acceptance radius contraction" }, - { "-flood", FALSE, etSTR, {&evSelections[2]}, - "Indices of eigenvectors for flooding"}, - { "-outfrq", FALSE, etINT, {&edi_params.outfrq}, + { "-flood", FALSE, etSTR, { &evSelections[2] }, "Indices of eigenvectors for flooding" }, + { "-outfrq", + FALSE, + etINT, + { &edi_params.outfrq }, "Frequency (in steps) of writing output in [REF].xvg[ref] file" }, - { "-slope", FALSE, etREAL, { &edi_params.slope}, - "Minimal slope in acceptance radius expansion"}, - { "-linstep", FALSE, etSTR, {&evParams[0]}, - "Stepsizes (nm/step) for fixed increment linear sampling (put in quotes! \"1.0 2.3 5.1 -3.1\")"}, - { "-accdir", FALSE, etSTR, {&evParams[1]}, - "Directions for acceptance linear sampling - only sign counts! (put in quotes! \"-1 +1 -1.1\")"}, - { "-radstep", FALSE, etREAL, {&radstep}, - "Stepsize (nm/step) for fixed increment radius expansion"}, - { "-maxedsteps", FALSE, etINT, {&edi_params.maxedsteps}, + { "-slope", + FALSE, + etREAL, + { &edi_params.slope }, + "Minimal slope in acceptance radius expansion" }, + { "-linstep", + FALSE, + etSTR, + { &evParams[0] }, + "Stepsizes (nm/step) for fixed increment linear sampling (put in quotes! \"1.0 2.3 5.1 " + "-3.1\")" }, + { "-accdir", + FALSE, + etSTR, + { &evParams[1] }, + "Directions for acceptance linear sampling - only sign counts! (put in quotes! \"-1 +1 " + "-1.1\")" }, + { "-radstep", + FALSE, + etREAL, + { &radstep }, + "Stepsize (nm/step) for fixed increment radius expansion" }, + { "-maxedsteps", + FALSE, + etINT, + { &edi_params.maxedsteps }, "Maximum number of steps per cycle" }, - { "-eqsteps", FALSE, etINT, {&eqSteps}, - "Number of steps to run without any perturbations "}, - { "-deltaF0", FALSE, etREAL, {&deltaF0}, - "Target destabilization energy for flooding"}, - { "-deltaF", FALSE, etREAL, {&deltaF}, - "Start deltaF with this parameter - default 0, nonzero values only needed for restart"}, - { "-tau", FALSE, etREAL, {&tau}, - "Coupling constant for adaption of flooding strength according to deltaF0, 0 = infinity i.e. constant flooding strength"}, - { "-Eflnull", FALSE, etREAL, {&constEfl}, + { "-eqsteps", + FALSE, + etINT, + { &eqSteps }, + "Number of steps to run without any perturbations " }, + { "-deltaF0", FALSE, etREAL, { &deltaF0 }, "Target destabilization energy for flooding" }, + { "-deltaF", + FALSE, + etREAL, + { &deltaF }, + "Start deltaF with this parameter - default 0, nonzero values only needed for restart" }, + { "-tau", + FALSE, + etREAL, + { &tau }, + "Coupling constant for adaption of flooding strength according to deltaF0, 0 = infinity " + "i.e. constant flooding strength" }, + { "-Eflnull", + FALSE, + etREAL, + { &constEfl }, "The starting value of the flooding strength. The flooding strength is updated " - "according to the adaptive flooding scheme. For a constant flooding strength use [TT]-tau[tt] 0. "}, - { "-T", FALSE, etREAL, {&T}, - "T is temperature, the value is needed if you want to do flooding "}, - { "-alpha", FALSE, etREAL, {&alpha}, - "Scale width of gaussian flooding potential with alpha^2 "}, - { "-restrain", FALSE, etBOOL, {&bRestrain}, - "Use the flooding potential with inverted sign -> effects as quasiharmonic restraining potential"}, - { "-hessian", FALSE, etBOOL, {&bHesse}, - "The eigenvectors and eigenvalues are from a Hessian matrix"}, - { "-harmonic", FALSE, etBOOL, {&bHarmonic}, - "The eigenvalues are interpreted as spring constant"}, - { "-constF", FALSE, etSTR, {&ConstForceStr}, - "Constant force flooding: manually set the forces for the eigenvectors selected with -flood " - "(put in quotes! \"1.0 2.3 5.1 -3.1\"). No other flooding parameters are needed when specifying the forces directly."} + "according to the adaptive flooding scheme. For a constant flooding strength use " + "[TT]-tau[tt] 0. " }, + { "-T", + FALSE, + etREAL, + { &T }, + "T is temperature, the value is needed if you want to do flooding " }, + { "-alpha", + FALSE, + etREAL, + { &alpha }, + "Scale width of gaussian flooding potential with alpha^2 " }, + { "-restrain", + FALSE, + etBOOL, + { &bRestrain }, + "Use the flooding potential with inverted sign -> effects as quasiharmonic restraining " + "potential" }, + { "-hessian", + FALSE, + etBOOL, + { &bHesse }, + "The eigenvectors and eigenvalues are from a Hessian matrix" }, + { "-harmonic", + FALSE, + etBOOL, + { &bHarmonic }, + "The eigenvalues are interpreted as spring constant" }, + { "-constF", + FALSE, + etSTR, + { &ConstForceStr }, + "Constant force flooding: manually set the forces for the eigenvectors selected with " + "-flood " + "(put in quotes! \"1.0 2.3 5.1 -3.1\"). No other flooding parameters are needed when " + "specifying the forces directly." } }; #define NPA asize(pa) - rvec *xref1; - int nvec1, *eignr1 = nullptr; - rvec *xav1, **eigvec1 = nullptr; - t_atoms *atoms = nullptr; - int nav; /* Number of atoms in the average structure */ - char *grpname; - const char *indexfile; - int i; - int *index, *ifit; - int nfit; /* Number of atoms in the reference/fit structure */ - int ev_class; /* parameter _class i.e. evMON, evRADFIX etc. */ - int nvecs; - real *eigval1 = nullptr; /* in V3.3 this is parameter of read_eigenvectors */ - - const char *EdiFile; - const char *TargetFile; - const char *OriginFile; - const char *EigvecFile; - - gmx_output_env_t *oenv; + rvec* xref1; + int nvec1, *eignr1 = nullptr; + rvec * xav1, **eigvec1 = nullptr; + t_atoms* atoms = nullptr; + int nav; /* Number of atoms in the average structure */ + char* grpname; + const char* indexfile; + int i; + int * index, *ifit; + int nfit; /* Number of atoms in the reference/fit structure */ + int ev_class; /* parameter _class i.e. evMON, evRADFIX etc. */ + int nvecs; + real* eigval1 = nullptr; /* in V3.3 this is parameter of read_eigenvectors */ + + const char* EdiFile; + const char* TargetFile; + const char* OriginFile; + const char* EigvecFile; + + gmx_output_env_t* oenv; /*to read topology file*/ - t_topology top; - int ePBC; - matrix topbox; - rvec *xtop; - gmx_bool bFit1; - - t_filenm fnm[] = { - { efTRN, "-f", "eigenvec", ffREAD }, - { efXVG, "-eig", "eigenval", ffOPTRD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efSTX, "-tar", "target", ffOPTRD}, - { efSTX, "-ori", "origin", ffOPTRD}, - { efEDI, "-o", "sam", ffWRITE } - }; + t_topology top; + int ePBC; + matrix topbox; + rvec* xtop; + gmx_bool bFit1; + + t_filenm fnm[] = { { efTRN, "-f", "eigenvec", ffREAD }, { efXVG, "-eig", "eigenval", ffOPTRD }, + { efTPS, nullptr, nullptr, ffREAD }, { efNDX, nullptr, nullptr, ffOPTRD }, + { efSTX, "-tar", "target", ffOPTRD }, { efSTX, "-ori", "origin", ffOPTRD }, + { efEDI, "-o", "sam", ffWRITE } }; #define NFILE asize(fnm) - edi_params.outfrq = 100; edi_params.slope = 0.0; edi_params.maxedsteps = 0; - if (!parse_common_args(&argc, argv, 0, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + edi_params.outfrq = 100; + edi_params.slope = 0.0; + edi_params.maxedsteps = 0; + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - indexfile = ftp2fn_null(efNDX, NFILE, fnm); - EdiFile = ftp2fn(efEDI, NFILE, fnm); - TargetFile = opt2fn_null("-tar", NFILE, fnm); - OriginFile = opt2fn_null("-ori", NFILE, fnm); + indexfile = ftp2fn_null(efNDX, NFILE, fnm); + EdiFile = ftp2fn(efEDI, NFILE, fnm); + TargetFile = opt2fn_null("-tar", NFILE, fnm); + OriginFile = opt2fn_null("-ori", NFILE, fnm); for (ev_class = 0; ev_class < evNr; ++ev_class) @@ -795,16 +929,17 @@ int gmx_make_edi(int argc, char *argv[]) if (opt2parg_bSet(evOptions[ev_class], NPA, pa)) { /*get list of eigenvectors*/ - nvecs = sscan_list(&(listen[ev_class]), opt2parg_str(evOptions[ev_class], NPA, pa), evOptions[ev_class]); - if (ev_class < evStepNr-2) + nvecs = sscan_list(&(listen[ev_class]), opt2parg_str(evOptions[ev_class], NPA, pa), + evOptions[ev_class]); + if (ev_class < evStepNr - 2) { /*if apropriate get list of stepsizes for these eigenvectors*/ if (opt2parg_bSet(evStepOptions[ev_class], NPA, pa)) { - evStepList[ev_class] = - scan_vecparams(opt2parg_str(evStepOptions[ev_class], NPA, pa), evStepOptions[ev_class], nvecs); + evStepList[ev_class] = scan_vecparams(opt2parg_str(evStepOptions[ev_class], NPA, pa), + evStepOptions[ev_class], nvecs); } - else /*if list is not given fill with zeros */ + else /*if list is not given fill with zeros */ { snew(evStepList[ev_class], nvecs); for (i = 0; i < nvecs; i++) @@ -829,14 +964,15 @@ int gmx_make_edi(int argc, char *argv[]) * the fproj values from the command line */ if (opt2parg_bSet("-constF", NPA, pa)) { - evStepList[ev_class] = scan_vecparams(opt2parg_str("-constF", NPA, pa), "-constF", nvecs); + evStepList[ev_class] = + scan_vecparams(opt2parg_str("-constF", NPA, pa), "-constF", nvecs); } } else { - }; /*to avoid ambiguity */ + } /*to avoid ambiguity */ } - else /* if there are no eigenvectors for this option set list to zero */ + else /* if there are no eigenvectors for this option set list to zero */ { listen[ev_class] = nullptr; snew(listen[ev_class], 1); @@ -859,11 +995,10 @@ int gmx_make_edi(int argc, char *argv[]) EigvecFile = opt2fn("-f", NFILE, fnm); /*read eigenvectors from eigvec.trr*/ - read_eigenvectors(EigvecFile, &nav, &bFit1, - &xref1, &edi_params.fitmas, &xav1, &edi_params.pcamas, &nvec1, &eignr1, &eigvec1, &eigval1); + read_eigenvectors(EigvecFile, &nav, &bFit1, &xref1, &edi_params.fitmas, &xav1, + &edi_params.pcamas, &nvec1, &eignr1, &eigvec1, &eigval1); - read_tps_conf(ftp2fn(efTPS, NFILE, fnm), - &top, &ePBC, &xtop, nullptr, topbox, false); + read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, topbox, false); atoms = &top.atoms; @@ -871,8 +1006,7 @@ int gmx_make_edi(int argc, char *argv[]) get_index(atoms, indexfile, 1, &i, &index, &grpname); /*if indexfile != NULL parameter 'atoms' is ignored */ if (i != nav) { - gmx_fatal(FARGS, "you selected a group with %d elements instead of %d", - i, nav); + gmx_fatal(FARGS, "you selected a group with %d elements instead of %d", i, nav); } printf("\n"); @@ -883,7 +1017,8 @@ int gmx_make_edi(int argc, char *argv[]) { /* if g_covar used different coordinate groups to fit and to do the PCA */ printf("\nNote: the structure in %s should be the same\n" - " as the one used for the fit in g_covar\n", ftp2fn(efTPS, NFILE, fnm)); + " as the one used for the fit in g_covar\n", + ftp2fn(efTPS, NFILE, fnm)); printf("\nSelect the index group that was used for the least squares fit in g_covar\n"); } else @@ -916,14 +1051,15 @@ int gmx_make_edi(int argc, char *argv[]) if (listen[evFLOOD][0] != 0) { - read_eigenvalues(listen[evFLOOD], opt2fn("-eig", NFILE, fnm), evStepList[evFLOOD], bHesse, kB*T, nav); + read_eigenvalues(listen[evFLOOD], opt2fn("-eig", NFILE, fnm), evStepList[evFLOOD], + bHesse, kB * T, nav); } edi_params.flood.tau = tau; edi_params.flood.deltaF0 = deltaF0; edi_params.flood.deltaF = deltaF; edi_params.presteps = eqSteps; - edi_params.flood.kT = kB*T; + edi_params.flood.kT = kB * T; edi_params.flood.bHarmonic = bHarmonic; if (bRestrain) { @@ -945,7 +1081,7 @@ int gmx_make_edi(int argc, char *argv[]) /*store reference and average structure in edi_params*/ - make_t_edx(&edi_params.sref, nfit, xref1, ifit ); + make_t_edx(&edi_params.sref, nfit, xref1, ifit); make_t_edx(&edi_params.sav, nav, xav1, index); @@ -954,7 +1090,8 @@ int gmx_make_edi(int argc, char *argv[]) { if (0 != listen[evFLOOD][0]) { - fprintf(stderr, "\nNote: Providing a TARGET structure has no effect when using flooding.\n" + fprintf(stderr, + "\nNote: Providing a TARGET structure has no effect when using flooding.\n" " You may want to use -ori to define the flooding potential center.\n\n"); } get_structure(atoms, indexfile, TargetFile, &edi_params.star, nfit, ifit, nav, index); diff --git a/src/gromacs/gmxana/gmx_mdmat.cpp b/src/gromacs/gmxana/gmx_mdmat.cpp index 8e63f022f9..e3799edfff 100644 --- a/src/gromacs/gmxana/gmx_mdmat.cpp +++ b/src/gromacs/gmxana/gmx_mdmat.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,9 +63,9 @@ #define FARAWAY 10000 -static int *res_ndx(t_atoms *atoms) +static int* res_ndx(t_atoms* atoms) { - int *rndx; + int* rndx; int i, r0; if (atoms->nr <= 0) @@ -76,15 +76,15 @@ static int *res_ndx(t_atoms *atoms) r0 = atoms->atom[0].resind; for (i = 0; (i < atoms->nr); i++) { - rndx[i] = atoms->atom[i].resind-r0; + rndx[i] = atoms->atom[i].resind - r0; } return rndx; } -static int *res_natm(t_atoms *atoms) +static int* res_natm(t_atoms* atoms) { - int *natm; + int* natm; int i, j, r0; if (atoms->nr <= 0) @@ -96,7 +96,7 @@ static int *res_natm(t_atoms *atoms) j = 0; for (i = 0; (i < atoms->nres); i++) { - while ((atoms->atom[j].resind)-r0 == i) + while ((atoms->atom[j].resind) - r0 == i) { natm[i]++; j++; @@ -106,9 +106,16 @@ static int *res_natm(t_atoms *atoms) return natm; } -static void calc_mat(int nres, int natoms, const int rndx[], - rvec x[], const int *index, - real trunc, real **mdmat, int **nmat, int ePBC, matrix box) +static void calc_mat(int nres, + int natoms, + const int rndx[], + rvec x[], + const int* index, + real trunc, + real** mdmat, + int** nmat, + int ePBC, + matrix box) { int i, j, resi, resj; real trunc2, r, r2; @@ -127,7 +134,7 @@ static void calc_mat(int nres, int natoms, const int rndx[], for (i = 0; (i < natoms); i++) { resi = rndx[i]; - for (j = i+1; (j < natoms); j++) + for (j = i + 1; (j < natoms); j++) { resj = rndx[j]; pbc_dx(&pbc, x[index[i]], x[index[j]], ddx); @@ -144,7 +151,7 @@ static void calc_mat(int nres, int natoms, const int rndx[], for (resi = 0; (resi < nres); resi++) { mdmat[resi][resi] = 0; - for (resj = resi+1; (resj < nres); resj++) + for (resj = resi + 1; (resj < nres); resj++) { r = std::sqrt(mdmat[resi][resj]); mdmat[resi][resj] = r; @@ -153,8 +160,7 @@ static void calc_mat(int nres, int natoms, const int rndx[], } } -static void tot_nmat(int nres, int natoms, int nframes, int **nmat, - int *tot_n, real *mean_n) +static void tot_nmat(int nres, int natoms, int nframes, int** nmat, int* tot_n, real* mean_n) { int i, j; @@ -172,9 +178,9 @@ static void tot_nmat(int nres, int natoms, int nframes, int **nmat, } } -int gmx_mdmat(int argc, char *argv[]) +int gmx_mdmat(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] makes distance matrices consisting of the smallest distance", "between residue pairs. With [TT]-frames[tt], these distance matrices can be", "stored in order to see differences in tertiary structure as a", @@ -185,50 +191,45 @@ int gmx_mdmat(int argc, char *argv[]) "residues over the whole trajectory can be made.", "The output can be processed with [gmx-xpm2ps] to make a PostScript (tm) plot." }; - static real truncate = 1.5; - static int nlevels = 40; - t_pargs pa[] = { - { "-t", FALSE, etREAL, {&truncate}, - "trunc distance" }, - { "-nlevels", FALSE, etINT, {&nlevels}, - "Discretize distance in this number of levels" } + static real truncate = 1.5; + static int nlevels = 40; + t_pargs pa[] = { + { "-t", FALSE, etREAL, { &truncate }, "trunc distance" }, + { "-nlevels", FALSE, etINT, { &nlevels }, "Discretize distance in this number of levels" } }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXPM, "-mean", "dm", ffWRITE }, - { efXPM, "-frames", "dmf", ffOPTWR }, - { efXVG, "-no", "num", ffOPTWR }, + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXPM, "-mean", "dm", ffWRITE }, + { efXPM, "-frames", "dmf", ffOPTWR }, { efXVG, "-no", "num", ffOPTWR }, }; #define NFILE asize(fnm) - FILE *out = nullptr, *fp; - t_topology top; - int ePBC; - t_atoms useatoms; - int isize; - int *index; - char *grpname; - int *rndx, *natm, prevres, newres; + FILE * out = nullptr, *fp; + t_topology top; + int ePBC; + t_atoms useatoms; + int isize; + int* index; + char* grpname; + int * rndx, *natm, prevres, newres; int i, j, nres, natoms, nframes, trxnat; - t_trxstatus *status; + t_trxstatus* status; gmx_bool bCalcN, bFrames; real t, ratio; char label[234]; t_rgb rlo, rhi; - rvec *x; - real **mdmat, *resnr, **totmdmat; - int **nmat, **totnmat; - real *mean_n; - int *tot_n; - matrix box = {{0}}; - gmx_output_env_t *oenv; + rvec* x; + real ** mdmat, *resnr, **totmdmat; + int ** nmat, **totnmat; + real* mean_n; + int* tot_n; + matrix box = { { 0 } }; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, - asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } @@ -257,7 +258,7 @@ int gmx_mdmat(int argc, char *argv[]) newres = 0; for (i = 0; (i < isize); i++) { - int ii = index[i]; + int ii = index[i]; useatoms.atomname[i] = top.atoms.atomname[ii]; if (top.atoms.atom[ii].resind != prevres) { @@ -268,13 +269,12 @@ int gmx_mdmat(int argc, char *argv[]) { fprintf(debug, "New residue: atom %5s %5s %6d, index entry %5d, newres %5d\n", *(top.atoms.resinfo[top.atoms.atom[ii].resind].name), - *(top.atoms.atomname[ii]), - ii, i, newres); + *(top.atoms.atomname[ii]), ii, i, newres); } } useatoms.atom[i].resind = newres; } - useatoms.nres = newres+1; + useatoms.nres = newres + 1; useatoms.nr = isize; rndx = res_ndx(&(useatoms)); @@ -293,7 +293,7 @@ int gmx_mdmat(int argc, char *argv[]) snew(mdmat[i], nres); snew(nmat[i], natoms); snew(totnmat[i], natoms); - resnr[i] = i+1; + resnr[i] = i + 1; } snew(totmdmat, nres); for (i = 0; (i < nres); i++) @@ -305,8 +305,12 @@ int gmx_mdmat(int argc, char *argv[]) nframes = 0; - rlo.r = 1.0; rlo.g = 1.0; rlo.b = 1.0; - rhi.r = 0.0; rhi.g = 0.0; rhi.b = 0.0; + rlo.r = 1.0; + rlo.g = 1.0; + rlo.b = 1.0; + rhi.r = 0.0; + rhi.g = 0.0; + rhi.b = 0.0; gpbc = gmx_rmpbc_init(&top.idef, ePBC, trxnat); @@ -339,11 +343,10 @@ int gmx_mdmat(int argc, char *argv[]) if (bFrames) { sprintf(label, "t=%.0f ps", t); - write_xpm(out, 0, label, "Distance (nm)", "Residue Index", "Residue Index", - nres, nres, resnr, resnr, mdmat, 0, truncate, rlo, rhi, &nlevels); + write_xpm(out, 0, label, "Distance (nm)", "Residue Index", "Residue Index", nres, nres, + resnr, resnr, mdmat, 0, truncate, rlo, rhi, &nlevels); } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); close_trx(status); gmx_rmpbc_done(gpbc); @@ -361,13 +364,13 @@ int gmx_mdmat(int argc, char *argv[]) totmdmat[i][j] /= nframes; } } - write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean smallest distance", - "Distance (nm)", "Residue Index", "Residue Index", - nres, nres, resnr, resnr, totmdmat, 0, truncate, rlo, rhi, &nlevels); + write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean smallest distance", "Distance (nm)", + "Residue Index", "Residue Index", nres, nres, resnr, resnr, totmdmat, 0, truncate, + rlo, rhi, &nlevels); if (bCalcN) { - char **legend; + char** legend; snew(legend, 5); for (i = 0; i < 5; i++) @@ -375,8 +378,8 @@ int gmx_mdmat(int argc, char *argv[]) snew(legend[i], STRLEN); } tot_nmat(nres, natoms, nframes, totnmat, tot_n, mean_n); - fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), - "Increase in number of contacts", "Residue", "Ratio", oenv); + fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Increase in number of contacts", "Residue", + "Ratio", oenv); sprintf(legend[0], "Total/mean"); sprintf(legend[1], "Total"); sprintf(legend[2], "Mean"); @@ -391,10 +394,10 @@ int gmx_mdmat(int argc, char *argv[]) } else { - ratio = tot_n[i]/mean_n[i]; + ratio = tot_n[i] / mean_n[i]; } - fprintf(fp, "%3d %8.3f %3d %8.3f %3d %8.3f\n", - i+1, ratio, tot_n[i], mean_n[i], natm[i], mean_n[i]/natm[i]); + fprintf(fp, "%3d %8.3f %3d %8.3f %3d %8.3f\n", i + 1, ratio, tot_n[i], mean_n[i], + natm[i], mean_n[i] / natm[i]); } xvgrclose(fp); } diff --git a/src/gromacs/gmxana/gmx_mindist.cpp b/src/gromacs/gmxana/gmx_mindist.cpp index 1c4752e8a0..fff6505628 100644 --- a/src/gromacs/gmxana/gmx_mindist.cpp +++ b/src/gromacs/gmxana/gmx_mindist.cpp @@ -63,9 +63,7 @@ #include "gromacs/utility/smalloc.h" -static void periodic_dist(int ePBC, - matrix box, rvec x[], int n, const int index[], - real *rmin, real *rmax, int *min_ind) +static void periodic_dist(int ePBC, matrix box, rvec x[], int n, const int index[], real* rmin, real* rmax, int* min_ind) { #define NSHIFT_MAX 26 int nsz, nshift, sx, sy, sz, i, j, s; @@ -84,8 +82,7 @@ static void periodic_dist(int ePBC, } else { - gmx_fatal(FARGS, "pbc = %s is not supported by g_mindist", - epbc_names[ePBC]); + gmx_fatal(FARGS, "pbc = %s is not supported by g_mindist", epbc_names[ePBC]); } nshift = 0; @@ -99,8 +96,7 @@ static void periodic_dist(int ePBC, { for (i = 0; i < DIM; i++) { - shift[nshift][i] = - sx*box[XX][i] + sy*box[YY][i] + sz*box[ZZ][i]; + shift[nshift][i] = sx * box[XX][i] + sy * box[YY][i] + sz * box[ZZ][i]; } nshift++; } @@ -113,7 +109,7 @@ static void periodic_dist(int ePBC, for (i = 0; i < n; i++) { - for (j = i+1; j < n; j++) + for (j = i + 1; j < n; j++) { rvec_sub(x[index[i]], x[index[j]], d0); r2 = norm2(d0); @@ -139,18 +135,22 @@ static void periodic_dist(int ePBC, *rmax = std::sqrt(r2max); } -static void periodic_mindist_plot(const char *trxfn, const char *outfn, - const t_topology *top, int ePBC, - int n, int index[], gmx_bool bSplit, - const gmx_output_env_t *oenv) +static void periodic_mindist_plot(const char* trxfn, + const char* outfn, + const t_topology* top, + int ePBC, + int n, + int index[], + gmx_bool bSplit, + const gmx_output_env_t* oenv) { - FILE *out; - const char *leg[5] = { "min per.", "max int.", "box1", "box2", "box3" }; - t_trxstatus *status; + FILE* out; + const char* leg[5] = { "min per.", "max int.", "box1", "box2", "box3" }; + t_trxstatus* status; real t; - rvec *x; + rvec* x; matrix box; - int natoms, ind_min[2] = {0, 0}, ind_mini = 0, ind_minj = 0; + int natoms, ind_min[2] = { 0, 0 }, ind_mini = 0, ind_minj = 0; real rmin, rmax, rmint, tmint; gmx_bool bFirst; gmx_rmpbc_t gpbc = nullptr; @@ -159,8 +159,8 @@ static void periodic_mindist_plot(const char *trxfn, const char *outfn, check_index(nullptr, n, index, nullptr, natoms); - out = xvgropen(outfn, "Minimum distance to periodic image", - output_env_get_time_label(oenv), "Distance (nm)", oenv); + out = xvgropen(outfn, "Minimum distance to periodic image", output_env_get_time_label(oenv), + "Distance (nm)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(out, "@ subtitle \"and maximum internal distance\"\n"); @@ -191,15 +191,14 @@ static void periodic_mindist_plot(const char *trxfn, const char *outfn, ind_mini = ind_min[0]; ind_minj = ind_min[1]; } - if (bSplit && !bFirst && std::abs(t/output_env_get_time_factor(oenv)) < 1e-5) + if (bSplit && !bFirst && std::abs(t / output_env_get_time_factor(oenv)) < 1e-5) { fprintf(out, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } - fprintf(out, "\t%g\t%6.3f %6.3f %6.3f %6.3f %6.3f\n", - output_env_conv_time(oenv, t), rmin, rmax, norm(box[0]), norm(box[1]), norm(box[2])); + fprintf(out, "\t%g\t%6.3f %6.3f %6.3f %6.3f %6.3f\n", output_env_conv_time(oenv, t), rmin, + rmax, norm(box[0]), norm(box[1]), norm(box[2])); bFirst = FALSE; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); if (nullptr != top) { @@ -212,22 +211,35 @@ static void periodic_mindist_plot(const char *trxfn, const char *outfn, "\nThe shortest periodic distance is %g (nm) at time %g (%s),\n" "between atoms %d and %d\n", rmint, output_env_conv_time(oenv, tmint), output_env_get_time_unit(oenv).c_str(), - index[ind_mini]+1, index[ind_minj]+1); + index[ind_mini] + 1, index[ind_minj] + 1); } -static void calc_dist(real rcut, gmx_bool bPBC, int ePBC, matrix box, rvec x[], - int nx1, int nx2, int index1[], int index2[], +static void calc_dist(real rcut, + gmx_bool bPBC, + int ePBC, + matrix box, + rvec x[], + int nx1, + int nx2, + int index1[], + int index2[], gmx_bool bGroup, - real *rmin, real *rmax, int *nmin, int *nmax, - int *ixmin, int *jxmin, int *ixmax, int *jxmax) + real* rmin, + real* rmax, + int* nmin, + int* nmax, + int* ixmin, + int* jxmin, + int* ixmax, + int* jxmax) { - int i, j, i0 = 0, j1; - int ix, jx; - int *index3; - rvec dx; - real r2, rmin2, rmax2, rcut2; - t_pbc pbc; - int nmin_j, nmax_j; + int i, j, i0 = 0, j1; + int ix, jx; + int* index3; + rvec dx; + real r2, rmin2, rmax2, rcut2; + t_pbc pbc; + int nmin_j, nmax_j; *ixmin = -1; *jxmin = -1; @@ -325,30 +337,46 @@ static void calc_dist(real rcut, gmx_bool bPBC, int ePBC, matrix box, rvec x[], *rmax = std::sqrt(rmax2); } -static void dist_plot(const char *fn, const char *afile, const char *dfile, - const char *nfile, const char *rfile, const char *xfile, - real rcut, gmx_bool bMat, const t_atoms *atoms, - int ng, int *index[], int gnx[], char *grpn[], gmx_bool bSplit, - gmx_bool bMin, int nres, int *residue, gmx_bool bPBC, int ePBC, - gmx_bool bGroup, gmx_bool bEachResEachTime, gmx_bool bPrintResName, - const gmx_output_env_t *oenv) +static void dist_plot(const char* fn, + const char* afile, + const char* dfile, + const char* nfile, + const char* rfile, + const char* xfile, + real rcut, + gmx_bool bMat, + const t_atoms* atoms, + int ng, + int* index[], + int gnx[], + char* grpn[], + gmx_bool bSplit, + gmx_bool bMin, + int nres, + int* residue, + gmx_bool bPBC, + int ePBC, + gmx_bool bGroup, + gmx_bool bEachResEachTime, + gmx_bool bPrintResName, + const gmx_output_env_t* oenv) { - FILE *atm, *dist, *num; - t_trxstatus *trxout; - char buf[256]; - char **leg; - real t, dmin, dmax, **mindres = nullptr, **maxdres = nullptr; - int nmin, nmax; - t_trxstatus *status; - int i = -1, j, k; - int min2, max2, min1r, min2r, max1r, max2r; - int min1 = 0; - int max1 = 0; - int oindex[2]; - rvec *x0; - matrix box; - gmx_bool bFirst; - FILE *respertime = nullptr; + FILE * atm, *dist, *num; + t_trxstatus* trxout; + char buf[256]; + char** leg; + real t, dmin, dmax, **mindres = nullptr, **maxdres = nullptr; + int nmin, nmax; + t_trxstatus* status; + int i = -1, j, k; + int min2, max2, min1r, min2r, max1r, max2r; + int min1 = 0; + int max1 = 0; + int oindex[2]; + rvec* x0; + matrix box; + gmx_bool bFirst; + FILE* respertime = nullptr; if (read_first_x(oenv, &status, fn, &t, &x0, box) == 0) { @@ -358,8 +386,8 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, sprintf(buf, "%simum Distance", bMin ? "Min" : "Max"); dist = xvgropen(dfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv); sprintf(buf, "Number of Contacts %s %g nm", bMin ? "<" : ">", rcut); - num = nfile ? xvgropen(nfile, buf, output_env_get_time_label(oenv), "Number", oenv) : nullptr; - atm = afile ? gmx_ffopen(afile, "w") : nullptr; + num = nfile ? xvgropen(nfile, buf, output_env_get_time_label(oenv), "Number", oenv) : nullptr; + atm = afile ? gmx_ffopen(afile, "w") : nullptr; trxout = xfile ? open_trx(xfile, "w") : nullptr; if (bMat) @@ -378,10 +406,10 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, else { GMX_RELEASE_ASSERT(ng > 1, "Must have more than one group with bMat"); - snew(leg, (ng*(ng-1))/2); - for (i = j = 0; (i < ng-1); i++) + snew(leg, (ng * (ng - 1)) / 2); + for (i = j = 0; (i < ng - 1); i++) { - for (k = i+1; (k < ng); k++, j++) + for (k = i + 1; (k < ng); k++, j++) { sprintf(buf, "%s-%s", grpn[i], grpn[k]); leg[j] = gmx_strdup(buf); @@ -396,16 +424,16 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, } else { - snew(leg, ng-1); - for (i = 0; (i < ng-1); i++) + snew(leg, ng - 1); + for (i = 0; (i < ng - 1); i++) { - sprintf(buf, "%s-%s", grpn[0], grpn[i+1]); + sprintf(buf, "%s-%s", grpn[0], grpn[i + 1]); leg[i] = gmx_strdup(buf); } - xvgr_legend(dist, ng-1, leg, oenv); + xvgr_legend(dist, ng - 1, leg, oenv); if (num) { - xvgr_legend(num, ng-1, leg, oenv); + xvgr_legend(num, ng - 1, leg, oenv); } } @@ -413,31 +441,32 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, { sprintf(buf, "%simum Distance", bMin ? "Min" : "Max"); respertime = xvgropen(rfile, buf, output_env_get_time_label(oenv), "Distance (nm)", oenv); - xvgr_legend(respertime, ng-1, leg, oenv); - if (bPrintResName && output_env_get_print_xvgr_codes(oenv) ) + xvgr_legend(respertime, ng - 1, leg, oenv); + if (bPrintResName && output_env_get_print_xvgr_codes(oenv)) { fprintf(respertime, "# "); for (j = 0; j < nres; j++) { - fprintf(respertime, "%s%d ", *(atoms->resinfo[atoms->atom[index[0][residue[j]]].resind].name), atoms->atom[index[0][residue[j]]].resind); + fprintf(respertime, "%s%d ", + *(atoms->resinfo[atoms->atom[index[0][residue[j]]].resind].name), + atoms->atom[index[0][residue[j]]].resind); } fprintf(respertime, "\n"); } - } if (nres) { - snew(mindres, ng-1); - snew(maxdres, ng-1); + snew(mindres, ng - 1); + snew(maxdres, ng - 1); for (i = 1; i < ng; i++) { - snew(mindres[i-1], nres); - snew(maxdres[i-1], nres); + snew(mindres[i - 1], nres); + snew(maxdres[i - 1], nres); for (j = 0; j < nres; j++) { - mindres[i-1][j] = 1e6; + mindres[i - 1][j] = 1e6; } /* maxdres[*][*] is already 0 */ } @@ -445,7 +474,7 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, bFirst = TRUE; do { - if (bSplit && !bFirst && std::abs(t/output_env_get_time_factor(oenv)) < 1e-5) + if (bSplit && !bFirst && std::abs(t / output_env_get_time_factor(oenv)) < 1e-5) { fprintf(dist, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); if (num) @@ -477,9 +506,9 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, } else { - for (i = 0; (i < ng-1); i++) + for (i = 0; (i < ng - 1); i++) { - for (k = i+1; (k < ng); k++) + for (k = i + 1; (k < ng); k++) { calc_dist(rcut, bPBC, ePBC, box, x0, gnx[i], gnx[k], index[i], index[k], bGroup, &dmin, &dmax, &nmin, &nmax, &min1, &min2, &max1, &max2); @@ -508,11 +537,11 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, { for (j = 0; j < nres; j++) { - calc_dist(rcut, bPBC, ePBC, box, x0, residue[j+1]-residue[j], gnx[i], - &(index[0][residue[j]]), index[i], bGroup, - &dmin, &dmax, &nmin, &nmax, &min1r, &min2r, &max1r, &max2r); - mindres[i-1][j] = std::min(mindres[i-1][j], dmin); - maxdres[i-1][j] = std::max(maxdres[i-1][j], dmax); + calc_dist(rcut, bPBC, ePBC, box, x0, residue[j + 1] - residue[j], gnx[i], + &(index[0][residue[j]]), index[i], bGroup, &dmin, &dmax, &nmin, + &nmax, &min1r, &min2r, &max1r, &max2r); + mindres[i - 1][j] = std::min(mindres[i - 1][j], dmin); + maxdres[i - 1][j] = std::max(maxdres[i - 1][j], dmax); } } } @@ -522,13 +551,12 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, { fprintf(num, "\n"); } - if ( (bMin ? min1 : max1) != -1) + if ((bMin ? min1 : max1) != -1) { if (atm) { - fprintf(atm, "%12e %12d %12d\n", - output_env_conv_time(oenv, t), 1+(bMin ? min1 : max1), - 1+(bMin ? min2 : max2)); + fprintf(atm, "%12e %12d %12d\n", output_env_conv_time(oenv, t), + 1 + (bMin ? min1 : max1), 1 + (bMin ? min2 : max2)); } } @@ -547,16 +575,15 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, { for (j = 0; j < nres; j++) { - fprintf(respertime, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]); + fprintf(respertime, " %7g", bMin ? mindres[i - 1][j] : maxdres[i - 1][j]); /*reset distances for next time point*/ - mindres[i-1][j] = 1e6; - maxdres[i-1][j] = 0; + mindres[i - 1][j] = 1e6; + maxdres[i - 1][j] = 0; } } fprintf(respertime, "\n"); } - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); close_trx(status); xvgrclose(dist); @@ -579,17 +606,17 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, if (nres && !bEachResEachTime) { - FILE *res; + FILE* res; sprintf(buf, "%simum Distance", bMin ? "Min" : "Max"); res = xvgropen(rfile, buf, "Residue (#)", "Distance (nm)", oenv); - xvgr_legend(res, ng-1, leg, oenv); + xvgr_legend(res, ng - 1, leg, oenv); for (j = 0; j < nres; j++) { - fprintf(res, "%4d", j+1); + fprintf(res, "%4d", j + 1); for (i = 1; i < ng; i++) { - fprintf(res, " %7g", bMin ? mindres[i-1][j] : maxdres[i-1][j]); + fprintf(res, " %7g", bMin ? mindres[i - 1][j] : maxdres[i - 1][j]); } fprintf(res, "\n"); } @@ -601,7 +628,7 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, sfree(x0); } - int freeLeg = bMat ? (ng == 1 ? 1 : (ng*(ng-1))/2) : ng - 1; + int freeLeg = bMat ? (ng == 1 ? 1 : (ng * (ng - 1)) / 2) : ng - 1; for (int i = 0; i < freeLeg; i++) { sfree(leg[i]); @@ -609,15 +636,15 @@ static void dist_plot(const char *fn, const char *afile, const char *dfile, sfree(leg); } -static int find_residues(const t_atoms *atoms, int n, const int index[], int **resindex) +static int find_residues(const t_atoms* atoms, int n, const int index[], int** resindex) { int i; - int nres = 0, resnr, presnr = 0; + int nres = 0, resnr, presnr = 0; bool presFound = false; - int *residx; + int* residx; /* build index of first atom numbers for each residue */ - snew(residx, atoms->nres+1); + snew(residx, atoms->nres + 1); for (i = 0; i < n; i++) { resnr = atoms->atom[index[i]].resind; @@ -631,24 +658,23 @@ static int find_residues(const t_atoms *atoms, int n, const int index[], int **r } if (debug) { - printf("Found %d residues out of %d (%d/%d atoms)\n", - nres, atoms->nres, atoms->nr, n); + printf("Found %d residues out of %d (%d/%d atoms)\n", nres, atoms->nres, atoms->nr, n); } - srenew(residx, nres+1); + srenew(residx, nres + 1); /* mark end of last residue */ residx[nres] = n; *resindex = residx; return nres; } -static void dump_res(FILE *out, int nres, int *resindex, int index[]) +static void dump_res(FILE* out, int nres, int* resindex, int index[]) { int i, j; - for (i = 0; i < nres-1; i++) + for (i = 0; i < nres - 1; i++) { - fprintf(out, "Res %d (%d):", i, resindex[i+1]-resindex[i]); - for (j = resindex[i]; j < resindex[i+1]; j++) + fprintf(out, "Res %d (%d):", i, resindex[i + 1] - resindex[i]); + for (j = resindex[i]; j < resindex[i + 1]; j++) { fprintf(out, " %d(%d)", j, index[j]); } @@ -656,9 +682,9 @@ static void dump_res(FILE *out, int nres, int *resindex, int index[]) } } -int gmx_mindist(int argc, char *argv[]) +int gmx_mindist(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the distance between one group and a number of", "other groups. Both the minimum distance", "(between any pair of atoms from the respective groups)", @@ -680,60 +706,55 @@ int gmx_mindist(int argc, char *argv[]) "Also [gmx-distance] and [gmx-pairdist] calculate distances." }; - gmx_bool bMat = FALSE, bPI = FALSE, bSplit = FALSE, bMax = FALSE, bPBC = TRUE; - gmx_bool bGroup = FALSE; - real rcutoff = 0.6; - int ng = 1; - gmx_bool bEachResEachTime = FALSE, bPrintResName = FALSE; - t_pargs pa[] = { - { "-matrix", FALSE, etBOOL, {&bMat}, - "Calculate half a matrix of group-group distances" }, - { "-max", FALSE, etBOOL, {&bMax}, - "Calculate *maximum* distance instead of minimum" }, - { "-d", FALSE, etREAL, {&rcutoff}, - "Distance for contacts" }, - { "-group", FALSE, etBOOL, {&bGroup}, + gmx_bool bMat = FALSE, bPI = FALSE, bSplit = FALSE, bMax = FALSE, bPBC = TRUE; + gmx_bool bGroup = FALSE; + real rcutoff = 0.6; + int ng = 1; + gmx_bool bEachResEachTime = FALSE, bPrintResName = FALSE; + t_pargs pa[] = { + { "-matrix", FALSE, etBOOL, { &bMat }, "Calculate half a matrix of group-group distances" }, + { "-max", FALSE, etBOOL, { &bMax }, "Calculate *maximum* distance instead of minimum" }, + { "-d", FALSE, etREAL, { &rcutoff }, "Distance for contacts" }, + { "-group", + FALSE, + etBOOL, + { &bGroup }, "Count contacts with multiple atoms in the first group as one" }, - { "-pi", FALSE, etBOOL, {&bPI}, - "Calculate minimum distance with periodic images" }, - { "-split", FALSE, etBOOL, {&bSplit}, - "Split graph where time is zero" }, - { "-ng", FALSE, etINT, {&ng}, + { "-pi", FALSE, etBOOL, { &bPI }, "Calculate minimum distance with periodic images" }, + { "-split", FALSE, etBOOL, { &bSplit }, "Split graph where time is zero" }, + { "-ng", + FALSE, + etINT, + { &ng }, "Number of secondary groups to compute distance to a central group" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Take periodic boundary conditions into account" }, - { "-respertime", FALSE, etBOOL, {&bEachResEachTime}, + { "-pbc", FALSE, etBOOL, { &bPBC }, "Take periodic boundary conditions into account" }, + { "-respertime", + FALSE, + etBOOL, + { &bEachResEachTime }, "When writing per-residue distances, write distance for each time point" }, - { "-printresname", FALSE, etBOOL, {&bPrintResName}, - "Write residue names" } + { "-printresname", FALSE, etBOOL, { &bPrintResName }, "Write residue names" } }; - gmx_output_env_t *oenv; - t_topology *top = nullptr; + gmx_output_env_t* oenv; + t_topology* top = nullptr; int ePBC = -1; - rvec *x = nullptr; + rvec* x = nullptr; matrix box; gmx_bool bTop = FALSE; - int i, nres = 0; - const char *trxfnm, *tpsfnm, *ndxfnm, *distfnm, *numfnm, *atmfnm, *oxfnm, *resfnm; - char **grpname; - int *gnx; - int **index, *residues = nullptr; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-od", "mindist", ffWRITE }, - { efXVG, "-on", "numcont", ffOPTWR }, - { efOUT, "-o", "atm-pair", ffOPTWR }, - { efTRO, "-ox", "mindist", ffOPTWR }, - { efXVG, "-or", "mindistres", ffOPTWR } - }; + int i, nres = 0; + const char *trxfnm, *tpsfnm, *ndxfnm, *distfnm, *numfnm, *atmfnm, *oxfnm, *resfnm; + char** grpname; + int* gnx; + int ** index, *residues = nullptr; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-od", "mindist", ffWRITE }, + { efXVG, "-on", "numcont", ffOPTWR }, { efOUT, "-o", "atm-pair", ffOPTWR }, + { efTRO, "-ox", "mindist", ffOPTWR }, { efXVG, "-or", "mindistres", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -780,7 +801,8 @@ int gmx_mindist(int argc, char *argv[]) bTop = read_tps_conf(tpsfnm, top, &ePBC, &x, nullptr, box, FALSE); if (bPI && !bTop) { - printf("\nWARNING: Without a run input file a trajectory with broken molecules will not give the correct periodic image distance\n\n"); + printf("\nWARNING: Without a run input file a trajectory with broken molecules will " + "not give the correct periodic image distance\n\n"); } } get_index(top ? &(top->atoms) : nullptr, ndxfnm, ng, gnx, index, grpname); @@ -788,15 +810,14 @@ int gmx_mindist(int argc, char *argv[]) if (bMat && (ng == 1)) { ng = gnx[0]; - printf("Special case: making distance matrix between all atoms in group %s\n", - grpname[0]); + printf("Special case: making distance matrix between all atoms in group %s\n", grpname[0]); srenew(gnx, ng); srenew(index, ng); srenew(grpname, ng); for (i = 1; (i < ng); i++) { - gnx[i] = 1; - grpname[i] = grpname[0]; + gnx[i] = 1; + grpname[i] = grpname[0]; snew(index[i], 1); index[i][0] = index[0][i]; } @@ -825,10 +846,9 @@ int gmx_mindist(int argc, char *argv[]) } else { - dist_plot(trxfnm, atmfnm, distfnm, numfnm, resfnm, oxfnm, - rcutoff, bMat, top ? &(top->atoms) : nullptr, - ng, index, gnx, grpname, bSplit, !bMax, nres, residues, bPBC, ePBC, - bGroup, bEachResEachTime, bPrintResName, oenv); + dist_plot(trxfnm, atmfnm, distfnm, numfnm, resfnm, oxfnm, rcutoff, bMat, + top ? &(top->atoms) : nullptr, ng, index, gnx, grpname, bSplit, !bMax, nres, + residues, bPBC, ePBC, bGroup, bEachResEachTime, bPrintResName, oenv); } do_view(oenv, distfnm, "-nxy"); diff --git a/src/gromacs/gmxana/gmx_msd.cpp b/src/gromacs/gmxana/gmx_msd.cpp index 5e6c1d4a64..39882709e8 100644 --- a/src/gromacs/gmxana/gmx_msd.cpp +++ b/src/gromacs/gmxana/gmx_msd.cpp @@ -62,49 +62,64 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -static constexpr double diffusionConversionFactor = 1000.0; /* Convert nm^2/ps to 10e-5 cm^2/s */ +static constexpr double diffusionConversionFactor = 1000.0; /* Convert nm^2/ps to 10e-5 cm^2/s */ /* NORMAL = total diffusion coefficient (default). X,Y,Z is diffusion coefficient in X,Y,Z direction. LATERAL is diffusion coefficient in plane perpendicular to axis */ -typedef enum { - NOT_USED, NORMAL, X, Y, Z, LATERAL +typedef enum +{ + NOT_USED, + NORMAL, + X, + Y, + Z, + LATERAL } msd_type; // TODO : Group related fields into a struct -struct t_corr { - real t0; /* start time and time increment between */ - real delta_t; /* time between restart points */ - real beginfit, /* the begin/end time for fits as reals between */ - endfit; /* 0 and 1 */ - real dim_factor; /* the dimensionality factor for the diffusion - constant */ - std::vector< std::vector > data; /* the displacement data. First index is the group - number, second is frame number */ - std::vector time; /* frame time */ - std::vector mass; /* masses for mass-weighted msd */ - matrix **datam; - std::vector< std::vector > x0; /* original positions */ - std::vector com; /* center of mass correction for each frame */ - gmx_stats_t **lsq; /* fitting stats for individual molecule msds */ - msd_type type; /* the type of msd to calculate (lateral, etc.)*/ - int axis; /* the axis along which to calculate */ - int ncoords; - int nrestart; /* number of restart points */ - int nmol; /* number of molecules (for bMol) */ - int nframes; /* number of frames */ - int nlast; - int ngrp; /* number of groups to use for msd calculation */ - std::vector n_offs; - std::vector< std::vector > ndata; /* the number of msds (particles/mols) per data - point. */ - t_corr(int nrgrp, int type, int axis, real dim_factor, int nrmol, - gmx_bool bTen, gmx_bool bMass, real dt, const t_topology *top, - real beginfit, real endfit) : +struct t_corr +{ + real t0; /* start time and time increment between */ + real delta_t; /* time between restart points */ + real beginfit, /* the begin/end time for fits as reals between */ + endfit; /* 0 and 1 */ + real dim_factor; /* the dimensionality factor for the diffusion + constant */ + std::vector> data; /* the displacement data. First index is the group + number, second is frame number */ + std::vector time; /* frame time */ + std::vector mass; /* masses for mass-weighted msd */ + matrix** datam; + std::vector> x0; /* original positions */ + std::vector com; /* center of mass correction for each frame */ + gmx_stats_t** lsq; /* fitting stats for individual molecule msds */ + msd_type type; /* the type of msd to calculate (lateral, etc.)*/ + int axis; /* the axis along which to calculate */ + int ncoords; + int nrestart; /* number of restart points */ + int nmol; /* number of molecules (for bMol) */ + int nframes; /* number of frames */ + int nlast; + int ngrp; /* number of groups to use for msd calculation */ + std::vector n_offs; + std::vector> ndata; /* the number of msds (particles/mols) per data + point. */ + t_corr(int nrgrp, + int type, + int axis, + real dim_factor, + int nrmol, + gmx_bool bTen, + gmx_bool bMass, + real dt, + const t_topology* top, + real beginfit, + real endfit) : t0(0), delta_t(dt), - beginfit((1 - 2*GMX_REAL_EPS)*beginfit), - endfit((1 + 2*GMX_REAL_EPS)*endfit), + beginfit((1 - 2 * GMX_REAL_EPS) * beginfit), + endfit((1 + 2 * GMX_REAL_EPS) * endfit), dim_factor(dim_factor), data(nrgrp, std::vector()), datam(nullptr), @@ -137,7 +152,7 @@ struct t_corr { { if (bMass) { - const t_atoms *atoms = &top->atoms; + const t_atoms* atoms = &top->atoms; mass.resize(atoms->nr); for (int i = 0; (i < atoms->nr); i++) { @@ -159,39 +174,45 @@ struct t_corr { } }; -typedef real t_calc_func (t_corr *curr, int nx, const int index[], int nx0, rvec xc[], - const rvec dcom, gmx_bool bTen, matrix mat); +typedef real +t_calc_func(t_corr* curr, int nx, const int index[], int nx0, rvec xc[], const rvec dcom, gmx_bool bTen, matrix mat); -static real thistime(t_corr *curr) +static real thistime(t_corr* curr) { return curr->time[curr->nframes]; } -static int in_data(t_corr *curr, int nx00) +static int in_data(t_corr* curr, int nx00) { - return curr->nframes-curr->n_offs[nx00]; + return curr->nframes - curr->n_offs[nx00]; } -static void corr_print(t_corr *curr, gmx_bool bTen, const char *fn, const char *title, - const char *yaxis, - real msdtime, real beginfit, real endfit, - real *DD, real *SigmaD, char *grpname[], - const gmx_output_env_t *oenv) +static void corr_print(t_corr* curr, + gmx_bool bTen, + const char* fn, + const char* title, + const char* yaxis, + real msdtime, + real beginfit, + real endfit, + real* DD, + real* SigmaD, + char* grpname[], + const gmx_output_env_t* oenv) { - FILE *out; + FILE* out; int i, j; out = xvgropen(fn, title, output_env_get_xvgr_tlabel(oenv), yaxis, oenv); if (DD) { - fprintf(out, "# MSD gathered over %g %s with %d restarts\n", - msdtime, output_env_get_time_unit(oenv).c_str(), curr->nrestart); - fprintf(out, "# Diffusion constants fitted from time %g to %g %s\n", - beginfit, endfit, output_env_get_time_unit(oenv).c_str()); + fprintf(out, "# MSD gathered over %g %s with %d restarts\n", msdtime, + output_env_get_time_unit(oenv).c_str(), curr->nrestart); + fprintf(out, "# Diffusion constants fitted from time %g to %g %s\n", beginfit, endfit, + output_env_get_time_unit(oenv).c_str()); for (i = 0; i < curr->ngrp; i++) { - fprintf(out, "# D[%10s] = %.4f (+/- %.4f) (1e-5 cm^2/s)\n", - grpname[i], DD[i], SigmaD[i]); + fprintf(out, "# D[%10s] = %.4f (+/- %.4f) (1e-5 cm^2/s)\n", grpname[i], DD[i], SigmaD[i]); } } for (i = 0; i < curr->nframes; i++) @@ -202,13 +223,9 @@ static void corr_print(t_corr *curr, gmx_bool bTen, const char *fn, const char * fprintf(out, " %10g", curr->data[j][i]); if (bTen) { - fprintf(out, " %10g %10g %10g %10g %10g %10g", - curr->datam[j][i][XX][XX], - curr->datam[j][i][YY][YY], - curr->datam[j][i][ZZ][ZZ], - curr->datam[j][i][YY][XX], - curr->datam[j][i][ZZ][XX], - curr->datam[j][i][ZZ][YY]); + fprintf(out, " %10g %10g %10g %10g %10g %10g", curr->datam[j][i][XX][XX], + curr->datam[j][i][YY][YY], curr->datam[j][i][ZZ][ZZ], curr->datam[j][i][YY][XX], + curr->datam[j][i][ZZ][XX], curr->datam[j][i][ZZ][YY]); } } fprintf(out, "\n"); @@ -217,8 +234,8 @@ static void corr_print(t_corr *curr, gmx_bool bTen, const char *fn, const char * } /* called from corr_loop, to do the main calculations */ -static void calc_corr(t_corr *curr, int nr, int nx, int index[], rvec xc[], - gmx_bool bRmCOMM, rvec com, t_calc_func *calc1, gmx_bool bTen) +static void +calc_corr(t_corr* curr, int nr, int nx, int index[], rvec xc[], gmx_bool bRmCOMM, rvec com, t_calc_func* calc1, gmx_bool bTen) { int nx0; real g; @@ -228,9 +245,9 @@ static void calc_corr(t_corr *curr, int nr, int nx, int index[], rvec xc[], /* Check for new starting point */ if (curr->nlast < curr->nrestart) { - if ((thistime(curr) >= (curr->nlast*curr->delta_t)) && (nr == 0)) + if ((thistime(curr) >= (curr->nlast * curr->delta_t)) && (nr == 0)) { - std::memcpy(curr->x0[curr->nlast].data()->as_vec(), xc, curr->ncoords*sizeof(xc[0])); + std::memcpy(curr->x0[curr->nlast].data()->as_vec(), xc, curr->ncoords * sizeof(xc[0])); curr->n_offs[curr->nlast] = curr->nframes; copy_rvec(com, curr->com[curr->nlast]); curr->nlast++; @@ -257,16 +274,15 @@ static void calc_corr(t_corr *curr, int nr, int nx, int index[], rvec xc[], curr->data[nr][in_data(curr, nx0)] += g; if (bTen) { - m_add(curr->datam[nr][in_data(curr, nx0)], mat, - curr->datam[nr][in_data(curr, nx0)]); + m_add(curr->datam[nr][in_data(curr, nx0)], mat, curr->datam[nr][in_data(curr, nx0)]); } curr->ndata[nr][in_data(curr, nx0)]++; } } /* the non-mass-weighted mean-squared displacement calculation */ -static real calc1_norm(t_corr *curr, int nx, const int index[], int nx0, rvec xc[], - const rvec dcom, gmx_bool bTen, matrix mat) +static real +calc1_norm(t_corr* curr, int nx, const int index[], int nx0, rvec xc[], const rvec dcom, gmx_bool bTen, matrix mat) { int i, ix, m, m2; real g, r, r2; @@ -285,12 +301,12 @@ static real calc1_norm(t_corr *curr, int nx, const int index[], int nx0, rvec xc for (m = 0; (m < DIM); m++) { rv[m] = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; - r2 += rv[m]*rv[m]; + r2 += rv[m] * rv[m]; if (bTen) { for (m2 = 0; m2 <= m; m2++) { - mat[m][m2] += rv[m]*rv[m2]; + mat[m][m2] += rv[m] * rv[m2]; } } } @@ -298,34 +314,32 @@ static real calc1_norm(t_corr *curr, int nx, const int index[], int nx0, rvec xc case X: case Y: case Z: - r = xc[ix][curr->type-X] - curr->x0[nx0][ix][curr->type-X] - - dcom[curr->type-X]; - r2 += r*r; + r = xc[ix][curr->type - X] - curr->x0[nx0][ix][curr->type - X] - dcom[curr->type - X]; + r2 += r * r; break; case LATERAL: for (m = 0; (m < DIM); m++) { if (m != curr->axis) { - r = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; - r2 += r*r; + r = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; + r2 += r * r; } } break; - default: - gmx_fatal(FARGS, "Error: did not expect option value %d", curr->type); + default: gmx_fatal(FARGS, "Error: did not expect option value %d", curr->type); } g += r2; } g /= nx; - msmul(mat, 1.0/nx, mat); + msmul(mat, 1.0 / nx, mat); return g; } /* calculate the com of molecules in x and put it into xa */ -static void calc_mol_com(int nmol, const int *molindex, const t_block *mols, const t_atoms *atoms, - rvec *x, rvec *xa) +static void +calc_mol_com(int nmol, const int* molindex, const t_block* mols, const t_atoms* atoms, rvec* x, rvec* xa) { int m, mol, i, d; rvec xm; @@ -336,21 +350,20 @@ static void calc_mol_com(int nmol, const int *molindex, const t_block *mols, con mol = molindex[m]; clear_rvec(xm); mtot = 0; - for (i = mols->index[mol]; i < mols->index[mol+1]; i++) + for (i = mols->index[mol]; i < mols->index[mol + 1]; i++) { mass = atoms->atom[i].m; for (d = 0; d < DIM; d++) { - xm[d] += mass*x[i][d]; + xm[d] += mass * x[i][d]; } mtot += mass; } - svmul(1/mtot, xm, xa[m]); + svmul(1 / mtot, xm, xa[m]); } } -static real calc_one_mw(t_corr *curr, int ix, int nx0, rvec xc[], real *tm, - const rvec dcom, gmx_bool bTen, matrix mat) +static real calc_one_mw(t_corr* curr, int ix, int nx0, rvec xc[], real* tm, const rvec dcom, gmx_bool bTen, matrix mat) { real r2, r, mm; rvec rv; @@ -362,19 +375,19 @@ static real calc_one_mw(t_corr *curr, int ix, int nx0, rvec xc[], real *tm, return 0; } (*tm) += mm; - r2 = 0.0; + r2 = 0.0; switch (curr->type) { case NORMAL: for (m = 0; (m < DIM); m++) { rv[m] = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; - r2 += mm*rv[m]*rv[m]; + r2 += mm * rv[m] * rv[m]; if (bTen) { for (m2 = 0; m2 <= m; m2++) { - mat[m][m2] += mm*rv[m]*rv[m2]; + mat[m][m2] += mm * rv[m] * rv[m2]; } } } @@ -382,29 +395,26 @@ static real calc_one_mw(t_corr *curr, int ix, int nx0, rvec xc[], real *tm, case X: case Y: case Z: - r = xc[ix][curr->type-X] - curr->x0[nx0][ix][curr->type-X] - - dcom[curr->type-X]; - r2 = mm*r*r; + r = xc[ix][curr->type - X] - curr->x0[nx0][ix][curr->type - X] - dcom[curr->type - X]; + r2 = mm * r * r; break; case LATERAL: for (m = 0; (m < DIM); m++) { if (m != curr->axis) { - r = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; - r2 += mm*r*r; + r = xc[ix][m] - curr->x0[nx0][ix][m] - dcom[m]; + r2 += mm * r * r; } } break; - default: - gmx_fatal(FARGS, "Options got screwed. Did not expect value %d\n", curr->type); + default: gmx_fatal(FARGS, "Options got screwed. Did not expect value %d\n", curr->type); } /* end switch */ return r2; } /* the normal, mass-weighted mean-squared displacement calcuation */ -static real calc1_mw(t_corr *curr, int nx, const int index[], int nx0, rvec xc[], - const rvec dcom, gmx_bool bTen, matrix mat) +static real calc1_mw(t_corr* curr, int nx, const int index[], int nx0, rvec xc[], const rvec dcom, gmx_bool bTen, matrix mat) { int i; real g, tm; @@ -419,7 +429,7 @@ static real calc1_mw(t_corr *curr, int nx, const int index[], int nx0, rvec xc[] g /= tm; if (bTen) { - msmul(mat, 1/tm, mat); + msmul(mat, 1 / tm, mat); } return g; @@ -431,8 +441,7 @@ static real calc1_mw(t_corr *curr, int nx, const int index[], int nx0, rvec xc[] xcur = the current coordinates xprev = the previous coordinates box = the box matrix */ -static void prep_data(gmx_bool bMol, int gnx, const int index[], - rvec xcur[], rvec xprev[], matrix box) +static void prep_data(gmx_bool bMol, int gnx, const int index[], rvec xcur[], rvec xprev[], matrix box) { int i, m, ind; rvec hbox; @@ -440,7 +449,7 @@ static void prep_data(gmx_bool bMol, int gnx, const int index[], /* Remove periodicity */ for (m = 0; (m < DIM); m++) { - hbox[m] = 0.5*box[m][m]; + hbox[m] = 0.5 * box[m][m]; } for (i = 0; (i < gnx); i++) @@ -454,17 +463,17 @@ static void prep_data(gmx_bool bMol, int gnx, const int index[], ind = index[i]; } - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { if (hbox[m] == 0) { continue; } - while (xcur[ind][m]-xprev[ind][m] <= -hbox[m]) + while (xcur[ind][m] - xprev[ind][m] <= -hbox[m]) { rvec_inc(xcur[ind], box[m]); } - while (xcur[ind][m]-xprev[ind][m] > hbox[m]) + while (xcur[ind][m] - xprev[ind][m] > hbox[m]) { rvec_dec(xcur[ind], box[m]); } @@ -480,9 +489,8 @@ static void prep_data(gmx_bool bMol, int gnx, const int index[], box = the box matrix atoms = atom data (for mass) com(output) = center of mass */ -static void calc_com(gmx_bool bMol, int gnx, int index[], - rvec xcur[], rvec xprev[], matrix box, const t_atoms *atoms, - rvec com) +static void +calc_com(gmx_bool bMol, int gnx, int index[], rvec xcur[], rvec xprev[], matrix box, const t_atoms* atoms, rvec com) { int i, m, ind; real mass; @@ -508,19 +516,25 @@ static void calc_com(gmx_bool bMol, int gnx, int index[], mass = atoms->atom[ind].m; for (m = 0; m < DIM; m++) { - sx[m] += mass*xcur[ind][m]; + sx[m] += mass * xcur[ind][m]; } tmass += mass; } for (m = 0; m < DIM; m++) { - com[m] = sx[m]/tmass; + com[m] = sx[m] / tmass; } } -static real calc1_mol(t_corr *curr, int nx, const int gmx_unused index[], int nx0, rvec xc[], - const rvec dcom, gmx_bool bTen, matrix mat) +static real calc1_mol(t_corr* curr, + int nx, + const int gmx_unused index[], + int nx0, + rvec xc[], + const rvec dcom, + gmx_bool bTen, + matrix mat) { int i; real g, tm, gtot, tt; @@ -539,21 +553,27 @@ static real calc1_mol(t_corr *curr, int nx, const int gmx_unused index[], int nx gmx_stats_add_point(curr->lsq[nx0][i], tt, g, 0, 0); } } - msmul(mat, 1.0/nx, mat); + msmul(mat, 1.0 / nx, mat); - return gtot/nx; + return gtot / nx; } -static void printmol(t_corr *curr, const char *fn, - const char *fn_pdb, const int *molindex, const t_topology *top, - rvec *x, int ePBC, matrix box, const gmx_output_env_t *oenv) +static void printmol(t_corr* curr, + const char* fn, + const char* fn_pdb, + const int* molindex, + const t_topology* top, + rvec* x, + int ePBC, + matrix box, + const gmx_output_env_t* oenv) { - FILE *out; + FILE* out; gmx_stats_t lsq1; int i, j; real a, b, D, Dav, D2av, VarD, sqrtD, sqrtD_max, scale; - t_pdbinfo *pdbinfo = nullptr; - const int *mol2a = nullptr; + t_pdbinfo* pdbinfo = nullptr; + const int* mol2a = nullptr; out = xvgropen(fn, "Diffusion Coefficients / Molecule", "Molecule", "D (1e-5 cm^2/s)", oenv); @@ -563,8 +583,8 @@ static void printmol(t_corr *curr, const char *fn, mol2a = top->mols.index; } - Dav = D2av = 0; - sqrtD_max = 0; + Dav = D2av = 0; + sqrtD_max = 0; for (i = 0; (i < curr->nmol); i++) { lsq1 = gmx_stats_init(); @@ -579,12 +599,12 @@ static void printmol(t_corr *curr, const char *fn, } gmx_stats_get_ab(lsq1, elsqWEIGHT_NONE, &a, &b, nullptr, nullptr, nullptr, nullptr); gmx_stats_free(lsq1); - D = a*diffusionConversionFactor/curr->dim_factor; + D = a * diffusionConversionFactor / curr->dim_factor; if (D < 0) { - D = 0; + D = 0; } - Dav += D; + Dav += D; D2av += gmx::square(D); fprintf(out, "%10d %10g\n", i, D); if (pdbinfo) @@ -594,7 +614,7 @@ static void printmol(t_corr *curr, const char *fn, { sqrtD_max = sqrtD; } - for (j = mol2a[molindex[i]]; j < mol2a[molindex[i]+1]; j++) + for (j = mol2a[molindex[i]]; j < mol2a[molindex[i] + 1]; j++) { pdbinfo[j].bfac = sqrtD; } @@ -604,20 +624,20 @@ static void printmol(t_corr *curr, const char *fn, do_view(oenv, fn, "-graphtype bar"); /* Compute variance, stddev and error */ - Dav /= curr->nmol; + Dav /= curr->nmol; D2av /= curr->nmol; - VarD = D2av - gmx::square(Dav); - printf(" = %.4f Std. Dev. = %.4f Error = %.4f\n", - Dav, std::sqrt(VarD), std::sqrt(VarD/curr->nmol)); + VarD = D2av - gmx::square(Dav); + printf(" = %.4f Std. Dev. = %.4f Error = %.4f\n", Dav, std::sqrt(VarD), + std::sqrt(VarD / curr->nmol)); if (fn_pdb && x) { scale = 1; - while (scale*sqrtD_max > 10) + while (scale * sqrtD_max > 10) { scale *= 0.1; } - while (scale*sqrtD_max < 0.1) + while (scale * sqrtD_max < 0.1) { scale *= 10; } @@ -634,22 +654,33 @@ static void printmol(t_corr *curr, const char *fn, * fx and nx are file pointers to things like read_first_x and * read_next_x */ -static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int ePBC, - gmx_bool bMol, int gnx[], int *index[], - t_calc_func *calc1, gmx_bool bTen, gmx::ArrayRef gnx_com, int *index_com[], - real dt, real t_pdb, rvec **x_pdb, matrix box_pdb, - const gmx_output_env_t *oenv) +static int corr_loop(t_corr* curr, + const char* fn, + const t_topology* top, + int ePBC, + gmx_bool bMol, + int gnx[], + int* index[], + t_calc_func* calc1, + gmx_bool bTen, + gmx::ArrayRef gnx_com, + int* index_com[], + real dt, + real t_pdb, + rvec** x_pdb, + matrix box_pdb, + const gmx_output_env_t* oenv) { - rvec *x[2]; /* the coordinates to read */ - rvec *xa[2]; /* the coordinates to calculate displacements for */ - rvec com = {0}; - real t, t_prev = 0; - int natoms, i, j, cur = 0, maxframes = 0; - t_trxstatus *status; -#define prev (1-cur) - matrix box; - gmx_bool bFirst; - gmx_rmpbc_t gpbc = nullptr; + rvec* x[2]; /* the coordinates to read */ + rvec* xa[2]; /* the coordinates to calculate displacements for */ + rvec com = { 0 }; + real t, t_prev = 0; + int natoms, i, j, cur = 0, maxframes = 0; + t_trxstatus* status; +#define prev (1 - cur) + matrix box; + gmx_bool bFirst; + gmx_rmpbc_t gpbc = nullptr; natoms = read_first_x(oenv, &status, fn, &curr->t0, &(x[cur]), box); #ifdef DEBUG @@ -657,7 +688,10 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP #endif if ((!gnx_com.empty()) && natoms < top->atoms.nr) { - fprintf(stderr, "WARNING: The trajectory only contains part of the system (%d of %d atoms) and therefore the COM motion of only this part of the system will be removed\n", natoms, top->atoms.nr); + fprintf(stderr, + "WARNING: The trajectory only contains part of the system (%d of %d atoms) and " + "therefore the COM motion of only this part of the system will be removed\n", + natoms, top->atoms.nr); } snew(x[prev], natoms); @@ -692,10 +726,9 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP /* the loop over all frames */ do { - if (x_pdb && ((bFirst && t_pdb < t) || - (!bFirst && - t_pdb > t - 0.5*(t - t_prev) && - t_pdb < t + 0.5*(t - t_prev)))) + if (x_pdb + && ((bFirst && t_pdb < t) + || (!bFirst && t_pdb > t - 0.5 * (t - t_prev) && t_pdb < t + 0.5 * (t - t_prev)))) { if (*x_pdb == nullptr) { @@ -715,24 +748,23 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP curr->nrestart++; curr->x0.resize(curr->nrestart); - curr->x0[curr->nrestart-1].resize(curr->ncoords); + curr->x0[curr->nrestart - 1].resize(curr->ncoords); curr->com.resize(curr->nrestart); curr->n_offs.resize(curr->nrestart); srenew(curr->lsq, curr->nrestart); - snew(curr->lsq[curr->nrestart-1], curr->nmol); + snew(curr->lsq[curr->nrestart - 1], curr->nmol); for (i = 0; i < curr->nmol; i++) { - curr->lsq[curr->nrestart-1][i] = gmx_stats_init(); + curr->lsq[curr->nrestart - 1][i] = gmx_stats_init(); } if (debug) { - fprintf(debug, "Extended data structures because of new restart %d\n", - curr->nrestart); + fprintf(debug, "Extended data structures because of new restart %d\n", curr->nrestart); } } /* create or extend the frame-based arrays */ - if (curr->nframes >= maxframes-1) + if (curr->nframes >= maxframes - 1) { if (maxframes == 0) { @@ -753,7 +785,7 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP { srenew(curr->datam[i], maxframes); } - for (j = maxframes-10; j < maxframes; j++) + for (j = maxframes - 10; j < maxframes; j++) { curr->ndata[i][j] = 0; curr->data[i][j] = 0; @@ -787,7 +819,7 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP /* for the first frame, the previous frame is a copy of the first frame */ if (bFirst) { - std::memcpy(xa[prev], xa[cur], curr->ncoords*sizeof(xa[prev][0])); + std::memcpy(xa[prev], xa[cur], curr->ncoords * sizeof(xa[prev][0])); bFirst = FALSE; } @@ -800,29 +832,26 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP /* calculate the center of mass */ if (!gnx_com.empty()) { - GMX_RELEASE_ASSERT(index_com != nullptr, "Center-of-mass removal must have valid index group"); - calc_com(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box, - &top->atoms, com); + GMX_RELEASE_ASSERT(index_com != nullptr, + "Center-of-mass removal must have valid index group"); + calc_com(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box, &top->atoms, com); } /* loop over all groups in index file */ for (i = 0; (i < curr->ngrp); i++) { /* calculate something useful, like mean square displacements */ - calc_corr(curr, i, gnx[i], index[i], xa[cur], (!gnx_com.empty()), com, - calc1, bTen); + calc_corr(curr, i, gnx[i], index[i], xa[cur], (!gnx_com.empty()), com, calc1, bTen); } cur = prev; t_prev = t; curr->nframes++; - } - while (read_next_x(oenv, status, &t, x[cur], box)); - fprintf(stderr, "\nUsed %d restart points spaced %g %s over %g %s\n\n", - curr->nrestart, + } while (read_next_x(oenv, status, &t, x[cur], box)); + fprintf(stderr, "\nUsed %d restart points spaced %g %s over %g %s\n\n", curr->nrestart, output_env_conv_time(oenv, dt), output_env_get_time_unit(oenv).c_str(), - output_env_conv_time(oenv, curr->time[curr->nframes-1]), - output_env_get_time_unit(oenv).c_str() ); + output_env_conv_time(oenv, curr->time[curr->nframes - 1]), + output_env_get_time_unit(oenv).c_str()); if (bMol) { @@ -834,7 +863,7 @@ static int corr_loop(t_corr *curr, const char *fn, const t_topology *top, int eP return natoms; } -static void index_atom2mol(int *n, int *index, const t_block *mols) +static void index_atom2mol(int* n, int* index, const t_block* mols) { int nat, i, nmol, mol, j; @@ -849,10 +878,10 @@ static void index_atom2mol(int *n, int *index, const t_block *mols) mol++; if (mol >= mols->nr) { - gmx_fatal(FARGS, "Atom index out of range: %d", index[i]+1); + gmx_fatal(FARGS, "Atom index out of range: %d", index[i] + 1); } } - for (j = mols->index[mol]; j < mols->index[mol+1]; j++) + for (j = mols->index[mol]; j < mols->index[mol + 1]; j++) { if (i >= nat || index[i] != j) { @@ -868,24 +897,37 @@ static void index_atom2mol(int *n, int *index, const t_block *mols) *n = nmol; } -static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_file, - const char *mol_file, const char *pdb_file, real t_pdb, - int nrgrp, t_topology *top, int ePBC, - gmx_bool bTen, gmx_bool bMW, gmx_bool bRmCOMM, - int type, real dim_factor, int axis, - real dt, real beginfit, real endfit, const gmx_output_env_t *oenv) +static void do_corr(const char* trx_file, + const char* ndx_file, + const char* msd_file, + const char* mol_file, + const char* pdb_file, + real t_pdb, + int nrgrp, + t_topology* top, + int ePBC, + gmx_bool bTen, + gmx_bool bMW, + gmx_bool bRmCOMM, + int type, + real dim_factor, + int axis, + real dt, + real beginfit, + real endfit, + const gmx_output_env_t* oenv) { std::unique_ptr msd; std::vector gnx, gnx_com; /* the selected groups' sizes */ - int **index; /* selected groups' indices */ - char **grpname; + int** index; /* selected groups' indices */ + char** grpname; int i, i0, i1, j, N, nat_trx; std::vector SigmaD, DD; real a, a2, b, r, chi2; - rvec *x = nullptr; + rvec* x = nullptr; matrix box; - int **index_com = nullptr; /* the COM removal group atom indices */ - char **grpname_com = nullptr; /* the COM removal group name */ + int** index_com = nullptr; /* the COM removal group atom indices */ + char** grpname_com = nullptr; /* the COM removal group name */ gnx.resize(nrgrp); snew(index, nrgrp); @@ -909,15 +951,12 @@ static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_ index_atom2mol(&gnx[0], index[0], &top->mols); } - msd = std::make_unique(nrgrp, type, axis, dim_factor, - mol_file == nullptr ? 0 : gnx[0], + msd = std::make_unique(nrgrp, type, axis, dim_factor, mol_file == nullptr ? 0 : gnx[0], bTen, bMW, dt, top, beginfit, endfit); - nat_trx = - corr_loop(msd.get(), trx_file, top, ePBC, mol_file ? gnx[0] != 0 : false, gnx.data(), index, - (mol_file != nullptr) ? calc1_mol : (bMW ? calc1_mw : calc1_norm), - bTen, gnx_com, index_com, dt, t_pdb, - pdb_file ? &x : nullptr, box, oenv); + nat_trx = corr_loop(msd.get(), trx_file, top, ePBC, mol_file ? gnx[0] != 0 : false, gnx.data(), + index, (mol_file != nullptr) ? calc1_mol : (bMW ? calc1_mw : calc1_norm), + bTen, gnx_com, index_com, dt, t_pdb, pdb_file ? &x : nullptr, box, oenv); /* Correct for the number of points */ for (j = 0; (j < msd->ngrp); j++) @@ -927,7 +966,7 @@ static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_ msd->data[j][i] /= msd->ndata[j][i]; if (bTen) { - msmul(msd->datam[j][i], 1.0/msd->ndata[j][i], msd->datam[j][i]); + msmul(msd->datam[j][i], 1.0 / msd->ndata[j][i], msd->datam[j][i]); } } } @@ -936,8 +975,10 @@ static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_ { if (pdb_file && x == nullptr) { - fprintf(stderr, "\nNo frame found need time tpdb = %g ps\n" - "Can not write %s\n\n", t_pdb, pdb_file); + fprintf(stderr, + "\nNo frame found need time tpdb = %g ps\n" + "Can not write %s\n\n", + t_pdb, pdb_file); } i = top->atoms.nr; top->atoms.nr = nat_trx; @@ -951,37 +992,33 @@ static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_ if (beginfit == -1) { - i0 = gmx::roundToInt(0.1*(msd->nframes - 1)); + i0 = gmx::roundToInt(0.1 * (msd->nframes - 1)); beginfit = msd->time[i0]; } else { - for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++) - { - ; - } + for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++) {} } if (endfit == -1) { - i1 = gmx::roundToInt(0.9*(msd->nframes - 1)) + 1; - endfit = msd->time[i1-1]; + i1 = gmx::roundToInt(0.9 * (msd->nframes - 1)) + 1; + endfit = msd->time[i1 - 1]; } else { - for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++) - { - ; - } + for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++) {} } fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit, output_env_get_time_unit(oenv).c_str()); - N = i1-i0; + N = i1 - i0; if (N <= 2) { - fprintf(stdout, "Not enough points for fitting (%d).\n" - "Can not determine the diffusion constant.\n", N); + fprintf(stdout, + "Not enough points for fitting (%d).\n" + "Can not determine the diffusion constant.\n", + N); } else { @@ -991,39 +1028,35 @@ static void do_corr(const char *trx_file, const char *ndx_file, const char *msd_ { if (N >= 4) { - lsq_y_ax_b(N/2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2); - lsq_y_ax_b(N/2, &(msd->time[i0+N/2]), &(msd->data[j][i0+N/2]), &a2, &b, &r, &chi2); - SigmaD[j] = std::abs(a-a2); + lsq_y_ax_b(N / 2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2); + lsq_y_ax_b(N / 2, &(msd->time[i0 + N / 2]), &(msd->data[j][i0 + N / 2]), &a2, &b, &r, &chi2); + SigmaD[j] = std::abs(a - a2); } else { SigmaD[j] = 0; } lsq_y_ax_b(N, &(msd->time[i0]), &(msd->data[j][i0]), &(DD[j]), &b, &r, &chi2); - DD[j] *= diffusionConversionFactor/msd->dim_factor; - SigmaD[j] *= diffusionConversionFactor/msd->dim_factor; + DD[j] *= diffusionConversionFactor / msd->dim_factor; + SigmaD[j] *= diffusionConversionFactor / msd->dim_factor; if (DD[j] > 0.01 && DD[j] < 1e4) { - fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n", - grpname[j], DD[j], SigmaD[j]); + fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n", grpname[j], DD[j], SigmaD[j]); } else { - fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n", - grpname[j], DD[j], SigmaD[j]); + fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n", grpname[j], DD[j], SigmaD[j]); } } } /* Print mean square displacement */ - corr_print(msd.get(), bTen, msd_file, - "Mean Square Displacement", - "MSD (nm\\S2\\N)", - msd->time[msd->nframes-1], beginfit, endfit, DD.data(), SigmaD.data(), grpname, oenv); + corr_print(msd.get(), bTen, msd_file, "Mean Square Displacement", "MSD (nm\\S2\\N)", + msd->time[msd->nframes - 1], beginfit, endfit, DD.data(), SigmaD.data(), grpname, oenv); } -int gmx_msd(int argc, char *argv[]) +int gmx_msd(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the mean square displacement (MSD) of atoms from", "a set of initial positions. This provides an easy way to compute", "the diffusion constant using the Einstein relation.", @@ -1067,8 +1100,8 @@ int gmx_msd(int argc, char *argv[]) "the diffusion coefficient of the molecule.", "This option implies option [TT]-mol[tt]." }; - static const char *normtype[] = { nullptr, "no", "x", "y", "z", nullptr }; - static const char *axtitle[] = { nullptr, "no", "x", "y", "z", nullptr }; + static const char* normtype[] = { nullptr, "no", "x", "y", "z", nullptr }; + static const char* axtitle[] = { nullptr, "no", "x", "y", "z", nullptr }; static int ngroup = 1; static real dt = 10; static real t_pdb = 0; @@ -1078,50 +1111,44 @@ int gmx_msd(int argc, char *argv[]) static gmx_bool bMW = TRUE; static gmx_bool bRmCOMM = FALSE; t_pargs pa[] = { - { "-type", FALSE, etENUM, {normtype}, - "Compute diffusion coefficient in one direction" }, - { "-lateral", FALSE, etENUM, {axtitle}, + { "-type", FALSE, etENUM, { normtype }, "Compute diffusion coefficient in one direction" }, + { "-lateral", + FALSE, + etENUM, + { axtitle }, "Calculate the lateral diffusion in a plane perpendicular to" }, - { "-ten", FALSE, etBOOL, {&bTen}, - "Calculate the full tensor" }, - { "-ngroup", FALSE, etINT, {&ngroup}, - "Number of groups to calculate MSD for" }, - { "-mw", FALSE, etBOOL, {&bMW}, - "Mass weighted MSD" }, - { "-rmcomm", FALSE, etBOOL, {&bRmCOMM}, - "Remove center of mass motion" }, - { "-tpdb", FALSE, etTIME, {&t_pdb}, - "The frame to use for option [TT]-pdb[tt] (%t)" }, - { "-trestart", FALSE, etTIME, {&dt}, - "Time between restarting points in trajectory (%t)" }, - { "-beginfit", FALSE, etTIME, {&beginfit}, + { "-ten", FALSE, etBOOL, { &bTen }, "Calculate the full tensor" }, + { "-ngroup", FALSE, etINT, { &ngroup }, "Number of groups to calculate MSD for" }, + { "-mw", FALSE, etBOOL, { &bMW }, "Mass weighted MSD" }, + { "-rmcomm", FALSE, etBOOL, { &bRmCOMM }, "Remove center of mass motion" }, + { "-tpdb", FALSE, etTIME, { &t_pdb }, "The frame to use for option [TT]-pdb[tt] (%t)" }, + { "-trestart", FALSE, etTIME, { &dt }, "Time between restarting points in trajectory (%t)" }, + { "-beginfit", + FALSE, + etTIME, + { &beginfit }, "Start time for fitting the MSD (%t), -1 is 10%" }, - { "-endfit", FALSE, etTIME, {&endfit}, - "End time for fitting the MSD (%t), -1 is 90%" } + { "-endfit", FALSE, etTIME, { &endfit }, "End time for fitting the MSD (%t), -1 is 90%" } }; - t_filenm fnm[] = { - { efTRX, nullptr, nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "msd", ffWRITE }, - { efXVG, "-mol", "diff_mol", ffOPTWR }, - { efPDB, "-pdb", "diff_mol", ffOPTWR } + t_filenm fnm[] = { + { efTRX, nullptr, nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, nullptr, "msd", ffWRITE }, + { efXVG, "-mol", "diff_mol", ffOPTWR }, { efPDB, "-pdb", "diff_mol", ffOPTWR } }; #define NFILE asize(fnm) t_topology top; int ePBC; matrix box; - const char *trx_file, *tps_file, *ndx_file, *msd_file, *mol_file, *pdb_file; - rvec *xdum; + const char * trx_file, *tps_file, *ndx_file, *msd_file, *mol_file, *pdb_file; + rvec* xdum; gmx_bool bTop; int axis, type; real dim_factor; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END | PCA_TIME_UNIT, + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; @@ -1146,14 +1173,13 @@ int gmx_msd(int argc, char *argv[]) } if (mol_file && ngroup > 1) { - gmx_fatal(FARGS, "With molecular msd can only have 1 group (now %d)", - ngroup); + gmx_fatal(FARGS, "With molecular msd can only have 1 group (now %d)", ngroup); } if (mol_file) { - bMW = TRUE; + bMW = TRUE; fprintf(stderr, "Calculating diffusion coefficients for molecules.\n"); } @@ -1189,14 +1215,11 @@ int gmx_msd(int argc, char *argv[]) bTop = read_tps_conf(tps_file, &top, &ePBC, &xdum, nullptr, box, bMW || bRmCOMM); if (mol_file && !bTop) { - gmx_fatal(FARGS, - "Could not read a topology from %s. Try a tpr file instead.", - tps_file); + gmx_fatal(FARGS, "Could not read a topology from %s. Try a tpr file instead.", tps_file); } - do_corr(trx_file, ndx_file, msd_file, mol_file, pdb_file, t_pdb, ngroup, - &top, ePBC, bTen, bMW, bRmCOMM, type, dim_factor, axis, dt, beginfit, endfit, - oenv); + do_corr(trx_file, ndx_file, msd_file, mol_file, pdb_file, t_pdb, ngroup, &top, ePBC, bTen, bMW, + bRmCOMM, type, dim_factor, axis, dt, beginfit, endfit, oenv); done_top(&top); view_all(oenv, NFILE, fnm); diff --git a/src/gromacs/gmxana/gmx_nmeig.cpp b/src/gromacs/gmxana/gmx_nmeig.cpp index 3a040fe57d..24d4f70aa9 100644 --- a/src/gromacs/gmxana/gmx_nmeig.cpp +++ b/src/gromacs/gmxana/gmx_nmeig.cpp @@ -70,69 +70,68 @@ static double cv_corr(double nu, double T) { - double x = PLANCK*nu/(BOLTZ*T); + double x = PLANCK * nu / (BOLTZ * T); double ex = std::exp(x); if (nu <= 0) { - return BOLTZ*KILO; + return BOLTZ * KILO; } else { - return BOLTZ*KILO*(ex*gmx::square(x)/gmx::square(ex-1) - 1); + return BOLTZ * KILO * (ex * gmx::square(x) / gmx::square(ex - 1) - 1); } } static double u_corr(double nu, double T) { - double x = PLANCK*nu/(BOLTZ*T); + double x = PLANCK * nu / (BOLTZ * T); double ex = std::exp(x); if (nu <= 0) { - return BOLTZ*T; + return BOLTZ * T; } else { - return BOLTZ*T*(0.5*x - 1 + x/(ex-1)); + return BOLTZ * T * (0.5 * x - 1 + x / (ex - 1)); } } -static size_t get_nharm_mt(const gmx_moltype_t *mt) +static size_t get_nharm_mt(const gmx_moltype_t* mt) { - static int harm_func[] = { F_BONDS }; - int i, ft; - size_t nh = 0; + static int harm_func[] = { F_BONDS }; + int i, ft; + size_t nh = 0; for (i = 0; (i < asize(harm_func)); i++) { - ft = harm_func[i]; - nh += mt->ilist[ft].size()/(interaction_function[ft].nratoms+1); + ft = harm_func[i]; + nh += mt->ilist[ft].size() / (interaction_function[ft].nratoms + 1); } return nh; } -static int get_nharm(const gmx_mtop_t *mtop) +static int get_nharm(const gmx_mtop_t* mtop) { int nh = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { nh += molb.nmol * get_nharm_mt(&(mtop->moltype[molb.type])); } return nh; } -static void -nma_full_hessian(real *hess, - int ndim, - gmx_bool bM, - const t_topology *top, - gmx::ArrayRef atom_index, - int begin, - int end, - real *eigenvalues, - real *eigenvectors) +static void nma_full_hessian(real* hess, + int ndim, + gmx_bool bM, + const t_topology* top, + gmx::ArrayRef atom_index, + int begin, + int end, + real* eigenvalues, + real* eigenvectors) { real mass_fac; @@ -148,10 +147,10 @@ nma_full_hessian(real *hess, for (int k = 0; (k < atom_index.ssize()); k++) { size_t ak = atom_index[k]; - mass_fac = gmx::invsqrt(top->atoms.atom[ai].m*top->atoms.atom[ak].m); + mass_fac = gmx::invsqrt(top->atoms.atom[ai].m * top->atoms.atom[ak].m); for (size_t l = 0; (l < DIM); l++) { - hess[(i*DIM+j)*ndim+k*DIM+l] *= mass_fac; + hess[(i * DIM + j) * ndim + k * DIM + l] *= mass_fac; } } } @@ -163,20 +162,20 @@ nma_full_hessian(real *hess, fprintf(stderr, "\nDiagonalizing to find vectors %d through %d...\n", begin, end); fflush(stderr); - eigensolver(hess, ndim, begin-1, end-1, eigenvalues, eigenvectors); + eigensolver(hess, ndim, begin - 1, end - 1, eigenvalues, eigenvectors); /* And scale the output eigenvectors */ if (bM && eigenvectors != nullptr) { - for (int i = 0; i < (end-begin+1); i++) + for (int i = 0; i < (end - begin + 1); i++) { for (gmx::index j = 0; j < atom_index.ssize(); j++) { size_t aj = atom_index[j]; - mass_fac = gmx::invsqrt(top->atoms.atom[aj].m); + mass_fac = gmx::invsqrt(top->atoms.atom[aj].m); for (size_t k = 0; (k < DIM); k++) { - eigenvectors[i*ndim+j*DIM+k] *= mass_fac; + eigenvectors[i * ndim + j * DIM + k] *= mass_fac; } } } @@ -184,15 +183,13 @@ nma_full_hessian(real *hess, } - -static void -nma_sparse_hessian(gmx_sparsematrix_t *sparse_hessian, - gmx_bool bM, - const t_topology *top, - gmx::ArrayRef atom_index, - int neig, - real *eigenvalues, - real *eigenvectors) +static void nma_sparse_hessian(gmx_sparsematrix_t* sparse_hessian, + gmx_bool bM, + const t_topology* top, + gmx::ArrayRef atom_index, + int neig, + real* eigenvalues, + real* eigenvectors) { int i, k; int row, col; @@ -200,12 +197,13 @@ nma_sparse_hessian(gmx_sparsematrix_t *sparse_hessian, int katom; size_t ndim; - ndim = DIM*atom_index.size(); + ndim = DIM * atom_index.size(); /* Cannot check symmetry since we only store half matrix */ /* divide elements hess[i][j] by sqrt(mas[i])*sqrt(mas[j]) when required */ - GMX_RELEASE_ASSERT(sparse_hessian != nullptr, "NULL matrix pointer provided to nma_sparse_hessian"); + GMX_RELEASE_ASSERT(sparse_hessian != nullptr, + "NULL matrix pointer provided to nma_sparse_hessian"); if (bM) { @@ -214,13 +212,13 @@ nma_sparse_hessian(gmx_sparsematrix_t *sparse_hessian, size_t ai = atom_index[iatom]; for (size_t j = 0; (j < DIM); j++) { - row = DIM*iatom+j; + row = DIM * iatom + j; for (k = 0; k < sparse_hessian->ndata[row]; k++) { col = sparse_hessian->data[row][k].col; - katom = col/3; + katom = col / 3; size_t ak = atom_index[katom]; - mass_fac = gmx::invsqrt(top->atoms.atom[ai].m*top->atoms.atom[ak].m); + mass_fac = gmx::invsqrt(top->atoms.atom[ai].m * top->atoms.atom[ak].m); sparse_hessian->data[row][k].value *= mass_fac; } } @@ -239,10 +237,10 @@ nma_sparse_hessian(gmx_sparsematrix_t *sparse_hessian, for (gmx::index j = 0; j < atom_index.ssize(); j++) { size_t aj = atom_index[j]; - mass_fac = gmx::invsqrt(top->atoms.atom[aj].m); + mass_fac = gmx::invsqrt(top->atoms.atom[aj].m); for (k = 0; (k < DIM); k++) { - eigenvectors[i*ndim+j*DIM+k] *= mass_fac; + eigenvectors[i * ndim + j * DIM + k] *= mass_fac; } } } @@ -251,8 +249,7 @@ nma_sparse_hessian(gmx_sparsematrix_t *sparse_hessian, /* Returns a pointer for eigenvector storage */ -static real *allocateEigenvectors(int nrow, int first, int last, - bool ignoreBegin) +static real* allocateEigenvectors(int nrow, int first, int last, bool ignoreBegin) { int numVector; if (ignoreBegin) @@ -263,19 +260,20 @@ static real *allocateEigenvectors(int nrow, int first, int last, { numVector = last - first + 1; } - size_t vectorsSize = static_cast(nrow)*static_cast(numVector); + size_t vectorsSize = static_cast(nrow) * static_cast(numVector); /* We can't have more than INT_MAX elements. * Relaxing this restriction probably requires changing lots of loop * variable types in the linear algebra code. */ if (vectorsSize > INT_MAX) { - gmx_fatal(FARGS, "You asked to store %d eigenvectors of size %d, which requires more than the supported %d elements; %sdecrease -last", - numVector, nrow, INT_MAX, - ignoreBegin ? "" : "increase -first and/or "); + gmx_fatal(FARGS, + "You asked to store %d eigenvectors of size %d, which requires more than the " + "supported %d elements; %sdecrease -last", + numVector, nrow, INT_MAX, ignoreBegin ? "" : "increase -first and/or "); } - real *eigenvectors; + real* eigenvectors; snew(eigenvectors, vectorsSize); return eigenvectors; @@ -285,14 +283,14 @@ static real *allocateEigenvectors(int nrow, int first, int last, */ static double calcTranslationalHeatCapacity() { - return RGAS*1.5; + return RGAS * 1.5; } /*! \brief Compute internal energy due to translational motion */ static double calcTranslationalInternalEnergy(double T) { - return BOLTZ*T*1.5; + return BOLTZ * T * 1.5; } /*! \brief Compute heat capacity due to rotational motion @@ -305,11 +303,11 @@ static double calcRotationalInternalEnergy(gmx_bool linear, double T) { if (linear) { - return BOLTZ*T; + return BOLTZ * T; } else { - return BOLTZ*T*1.5; + return BOLTZ * T * 1.5; } } @@ -326,12 +324,12 @@ static double calcRotationalHeatCapacity(gmx_bool linear) } else { - return RGAS*1.5; + return RGAS * 1.5; } } -static void analyzeThermochemistry(FILE *fp, - const t_topology &top, +static void analyzeThermochemistry(FILE* fp, + const t_topology& top, rvec top_x[], gmx::ArrayRef atom_index, real eigfreq[], @@ -341,44 +339,40 @@ static void analyzeThermochemistry(FILE *fp, real scale_factor, real linear_toler) { - std::vector index(atom_index.begin(), atom_index.end()); + std::vector index(atom_index.begin(), atom_index.end()); - rvec xcm; - double tmass = calc_xcm(top_x, index.size(), - index.data(), top.atoms.atom, xcm, FALSE); - double Strans = calcTranslationalEntropy(tmass, T, P); + rvec xcm; + double tmass = calc_xcm(top_x, index.size(), index.data(), top.atoms.atom, xcm, FALSE); + double Strans = calcTranslationalEntropy(tmass, T, P); std::vector x_com; x_com.resize(top.atoms.nr); for (int i = 0; i < top.atoms.nr; i++) { copy_rvec(top_x[i], x_com[i]); } - (void) sub_xcm(as_rvec_array(x_com.data()), index.size(), index.data(), - top.atoms.atom, xcm, FALSE); + (void)sub_xcm(as_rvec_array(x_com.data()), index.size(), index.data(), top.atoms.atom, xcm, FALSE); rvec inertia; matrix trans; - principal_comp(index.size(), index.data(), top.atoms.atom, - as_rvec_array(x_com.data()), trans, inertia); - bool linear = (inertia[XX]/inertia[YY] < linear_toler && - inertia[XX]/inertia[ZZ] < linear_toler); + principal_comp(index.size(), index.data(), top.atoms.atom, as_rvec_array(x_com.data()), trans, inertia); + bool linear = (inertia[XX] / inertia[YY] < linear_toler && inertia[XX] / inertia[ZZ] < linear_toler); // (kJ/mol ps)^2/(Dalton nm^2 kJ/mol K) = // KILO kg m^2 ps^2/(s^2 mol g/mol nm^2 K) = // KILO^2 10^18 / 10^24 K = 1/K - double rot_const = gmx::square(PLANCK)/(8*gmx::square(M_PI)*BOLTZ); + double rot_const = gmx::square(PLANCK) / (8 * gmx::square(M_PI) * BOLTZ); // Rotational temperature (1/K) - rvec theta = { 0, 0, 0 }; + rvec theta = { 0, 0, 0 }; if (linear) { // For linear molecules the first element of the inertia // vector is zero. - theta[0] = rot_const/inertia[1]; + theta[0] = rot_const / inertia[1]; } else { for (int m = 0; m < DIM; m++) { - theta[m] = rot_const/inertia[m]; + theta[m] = rot_const / inertia[m]; } } if (debug) @@ -388,32 +382,29 @@ static void analyzeThermochemistry(FILE *fp, pr_rvecs(debug, 0, "trans", trans, DIM); fprintf(debug, "linear molecule = %s\n", linear ? "true" : "no"); } - size_t nFreq = index.size()*DIM; - auto eFreq = gmx::arrayRefFromArray(eigfreq, nFreq); - double Svib = calcQuasiHarmonicEntropy(eFreq, T, linear, scale_factor); + size_t nFreq = index.size() * DIM; + auto eFreq = gmx::arrayRefFromArray(eigfreq, nFreq); + double Svib = calcQuasiHarmonicEntropy(eFreq, T, linear, scale_factor); - double Srot = calcRotationalEntropy(T, top.atoms.nr, - linear, theta, sigma_r); + double Srot = calcRotationalEntropy(T, top.atoms.nr, linear, theta, sigma_r); fprintf(fp, "Translational entropy %g J/mol K\n", Strans); fprintf(fp, "Rotational entropy %g J/mol K\n", Srot); fprintf(fp, "Vibrational entropy %g J/mol K\n", Svib); - fprintf(fp, "Total entropy %g J/mol K\n", Svib+Strans+Srot); - double HeatCapacity = (calcTranslationalHeatCapacity() + - calcRotationalHeatCapacity(linear) + - calcVibrationalHeatCapacity(eFreq, T, linear, scale_factor)); + fprintf(fp, "Total entropy %g J/mol K\n", Svib + Strans + Srot); + double HeatCapacity = (calcTranslationalHeatCapacity() + calcRotationalHeatCapacity(linear) + + calcVibrationalHeatCapacity(eFreq, T, linear, scale_factor)); fprintf(fp, "Heat capacity %g J/mol K\n", HeatCapacity); - double Evib = (calcTranslationalInternalEnergy(T) + - calcRotationalInternalEnergy(linear, T) + - calcVibrationalInternalEnergy(eFreq, T, linear, scale_factor)); + double Evib = (calcTranslationalInternalEnergy(T) + calcRotationalInternalEnergy(linear, T) + + calcVibrationalInternalEnergy(eFreq, T, linear, scale_factor)); fprintf(fp, "Internal energy %g kJ/mol\n", Evib); - double ZPE = calcZeroPointEnergy(eFreq, scale_factor); + double ZPE = calcZeroPointEnergy(eFreq, scale_factor); fprintf(fp, "Zero-point energy %g kJ/mol\n", ZPE); } -int gmx_nmeig(int argc, char *argv[]) +int gmx_nmeig(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates the eigenvectors/values of a (Hessian) matrix,", "which can be calculated with [gmx-mdrun].", "The eigenvectors are written to a trajectory file ([TT]-v[tt]).", @@ -438,7 +429,8 @@ int gmx_nmeig(int argc, char *argv[]) "you need to analyze the [TT]quant_corr.xvg[tt] file yourself.[PAR]", "To make things more flexible, the program can also take virtual sites into account", "when computing quantum corrections. When selecting [TT]-constr[tt] and", - "[TT]-qc[tt], the [TT]-begin[tt] and [TT]-end[tt] options will be set automatically as well.[PAR]", + "[TT]-qc[tt], the [TT]-begin[tt] and [TT]-end[tt] options will be set automatically as ", + "well.[PAR]", "Based on a harmonic analysis of the normal mode frequencies,", "thermochemical properties S0 (Standard Entropy),", "Cv (Heat capacity at constant volume), Zero-point energy and the internal energy are", @@ -446,73 +438,94 @@ int gmx_nmeig(int argc, char *argv[]) "programs." }; - static gmx_bool bM = TRUE, bCons = FALSE; - static int begin = 1, end = 50, maxspec = 4000, sigma_r = 1; - static real T = 298.15, width = 1, P = 1, scale_factor = 1; - static real linear_toler = 1e-5; + static gmx_bool bM = TRUE, bCons = FALSE; + static int begin = 1, end = 50, maxspec = 4000, sigma_r = 1; + static real T = 298.15, width = 1, P = 1, scale_factor = 1; + static real linear_toler = 1e-5; - t_pargs pa[] = - { - { "-m", FALSE, etBOOL, {&bM}, + t_pargs pa[] = { + { "-m", + FALSE, + etBOOL, + { &bM }, "Divide elements of Hessian by product of sqrt(mass) of involved " "atoms prior to diagonalization. This should be used for 'Normal Modes' " "analysis" }, - { "-first", FALSE, etINT, {&begin}, - "First eigenvector to write away" }, - { "-last", FALSE, etINT, {&end}, + { "-first", FALSE, etINT, { &begin }, "First eigenvector to write away" }, + { "-last", + FALSE, + etINT, + { &end }, "Last eigenvector to write away. -1 is use all dimensions." }, - { "-maxspec", FALSE, etINT, {&maxspec}, + { "-maxspec", + FALSE, + etINT, + { &maxspec }, "Highest frequency (1/cm) to consider in the spectrum" }, - { "-T", FALSE, etREAL, {&T}, - "Temperature for computing entropy, quantum heat capacity and enthalpy when using normal mode calculations to correct classical simulations" }, - { "-P", FALSE, etREAL, {&P}, - "Pressure (bar) when computing entropy" }, - { "-sigma", FALSE, etINT, {&sigma_r}, - "Number of symmetric copies used when computing entropy. E.g. for water the number is 2, for NH3 it is 3 and for methane it is 12." }, - { "-scale", FALSE, etREAL, {&scale_factor}, + { "-T", + FALSE, + etREAL, + { &T }, + "Temperature for computing entropy, quantum heat capacity and enthalpy when " + "using normal mode calculations to correct classical simulations" }, + { "-P", FALSE, etREAL, { &P }, "Pressure (bar) when computing entropy" }, + { "-sigma", + FALSE, + etINT, + { &sigma_r }, + "Number of symmetric copies used when computing entropy. E.g. for water the " + "number is 2, for NH3 it is 3 and for methane it is 12." }, + { "-scale", + FALSE, + etREAL, + { &scale_factor }, "Factor to scale frequencies before computing thermochemistry values" }, - { "-linear_toler", FALSE, etREAL, {&linear_toler}, - "Tolerance for determining whether a compound is linear as determined from the ration of the moments inertion Ix/Iy and Ix/Iz." }, - { "-constr", FALSE, etBOOL, {&bCons}, - "If constraints were used in the simulation but not in the normal mode analysis you will need to set this for computing the quantum corrections." }, - { "-width", FALSE, etREAL, {&width}, + { "-linear_toler", + FALSE, + etREAL, + { &linear_toler }, + "Tolerance for determining whether a compound is linear as determined from the " + "ration of the moments inertion Ix/Iy and Ix/Iz." }, + { "-constr", + FALSE, + etBOOL, + { &bCons }, + "If constraints were used in the simulation but not in the normal mode analysis " + "you will need to set this for computing the quantum corrections." }, + { "-width", + FALSE, + etREAL, + { &width }, "Width (sigma) of the gaussian peaks (1/cm) when generating a spectrum" } }; - FILE *out, *qc, *spec; - t_topology top; - gmx_mtop_t mtop; - rvec *top_x; - matrix box; - real *eigenvalues; - real *eigenvectors; - real qcvtot, qutot, qcv, qu; - int i, j, k; - real value, omega, nu; - real factor_gmx_to_omega2; - real factor_omega_to_wavenumber; - real *spectrum = nullptr; - real wfac; - gmx_output_env_t *oenv; - const char *qcleg[] = { - "Heat Capacity cV (J/mol K)", - "Enthalpy H (kJ/mol)" - }; - real * full_hessian = nullptr; - gmx_sparsematrix_t * sparse_hessian = nullptr; - - t_filenm fnm[] = { - { efMTX, "-f", "hessian", ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efXVG, "-of", "eigenfreq", ffWRITE }, - { efXVG, "-ol", "eigenval", ffWRITE }, - { efXVG, "-os", "spectrum", ffOPTWR }, - { efXVG, "-qc", "quant_corr", ffOPTWR }, - { efTRN, "-v", "eigenvec", ffWRITE } + FILE * out, *qc, *spec; + t_topology top; + gmx_mtop_t mtop; + rvec* top_x; + matrix box; + real* eigenvalues; + real* eigenvectors; + real qcvtot, qutot, qcv, qu; + int i, j, k; + real value, omega, nu; + real factor_gmx_to_omega2; + real factor_omega_to_wavenumber; + real* spectrum = nullptr; + real wfac; + gmx_output_env_t* oenv; + const char* qcleg[] = { "Heat Capacity cV (J/mol K)", "Enthalpy H (kJ/mol)" }; + real* full_hessian = nullptr; + gmx_sparsematrix_t* sparse_hessian = nullptr; + + t_filenm fnm[] = { + { efMTX, "-f", "hessian", ffREAD }, { efTPR, nullptr, nullptr, ffREAD }, + { efXVG, "-of", "eigenfreq", ffWRITE }, { efXVG, "-ol", "eigenval", ffWRITE }, + { efXVG, "-os", "spectrum", ffOPTWR }, { efXVG, "-qc", "quant_corr", ffOPTWR }, + { efTRN, "-v", "eigenvec", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -522,8 +535,7 @@ int gmx_nmeig(int argc, char *argv[]) snew(top_x, tpx.natoms); int natoms_tpx; - read_tpx(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms_tpx, - top_x, nullptr, &mtop); + read_tpx(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms_tpx, top_x, nullptr, &mtop); int nharm = 0; if (bCons) { @@ -534,7 +546,7 @@ int gmx_nmeig(int argc, char *argv[]) top = gmx_mtop_t_to_t_topology(&mtop, true); bM = TRUE; - int ndim = DIM*atom_index.size(); + int ndim = DIM * atom_index.size(); if (opt2bSet("-qc", NFILE, fnm)) { @@ -563,20 +575,23 @@ int gmx_nmeig(int argc, char *argv[]) { fprintf(stderr, "Cannot use sparse Hessian to calculate all eigenvectors.\n"); - fprintf(stderr, "Will try to allocate memory and convert to full matrix representation...\n"); + fprintf(stderr, + "Will try to allocate memory and convert to full matrix representation...\n"); - size_t hessianSize = static_cast(nrow)*static_cast(ncol); + size_t hessianSize = static_cast(nrow) * static_cast(ncol); /* Allowing Hessians larger than INT_MAX probably only makes sense * with (OpenMP) parallel diagonalization routines, since with a single * thread it will takes months. */ if (hessianSize > INT_MAX) { - gmx_fatal(FARGS, "Hessian size is %d x %d, which is larger than the maximum allowed %d elements.", + gmx_fatal(FARGS, + "Hessian size is %d x %d, which is larger than the maximum allowed %d " + "elements.", nrow, ncol, INT_MAX); } snew(full_hessian, hessianSize); - for (i = 0; i < nrow*ncol; i++) + for (i = 0; i < nrow * ncol; i++) { full_hessian[i] = 0; } @@ -585,10 +600,10 @@ int gmx_nmeig(int argc, char *argv[]) { for (j = 0; j < sparse_hessian->ndata[i]; j++) { - k = sparse_hessian->data[i][j].col; - value = sparse_hessian->data[i][j].value; - full_hessian[i*ndim+k] = value; - full_hessian[k*ndim+i] = value; + k = sparse_hessian->data[i][j].col; + value = sparse_hessian->data[i][j].value; + full_hessian[i * ndim + k] = value; + full_hessian[k * ndim + i] = value; } } gmx_sparsematrix_destroy(sparse_hessian); @@ -603,8 +618,7 @@ int gmx_nmeig(int argc, char *argv[]) /* Using full matrix storage */ eigenvectors = allocateEigenvectors(nrow, begin, end, false); - nma_full_hessian(full_hessian, nrow, bM, &top, atom_index, begin, end, - eigenvalues, eigenvectors); + nma_full_hessian(full_hessian, nrow, bM, &top, atom_index, begin, end, eigenvalues, eigenvectors); } else { @@ -617,7 +631,7 @@ int gmx_nmeig(int argc, char *argv[]) /* check the output, first 6 eigenvalues should be reasonably small */ gmx_bool bSuck = FALSE; - for (i = begin-1; (i < 6); i++) + for (i = begin - 1; (i < 6); i++) { if (std::abs(eigenvalues[i]) > 1.0e-3) { @@ -632,10 +646,9 @@ int gmx_nmeig(int argc, char *argv[]) } /* now write the output */ - fprintf (stderr, "Writing eigenvalues...\n"); - out = xvgropen(opt2fn("-ol", NFILE, fnm), - "Eigenvalues", "Eigenvalue index", "Eigenvalue [Gromacs units]", - oenv); + fprintf(stderr, "Writing eigenvalues...\n"); + out = xvgropen(opt2fn("-ol", NFILE, fnm), "Eigenvalues", "Eigenvalue index", + "Eigenvalue [Gromacs units]", oenv); if (output_env_get_print_xvgr_codes(oenv)) { if (bM) @@ -648,9 +661,9 @@ int gmx_nmeig(int argc, char *argv[]) } } - for (i = 0; i <= (end-begin); i++) + for (i = 0; i <= (end - begin); i++) { - fprintf (out, "%6d %15g\n", begin+i, eigenvalues[i]); + fprintf(out, "%6d %15g\n", begin + i, eigenvalues[i]); } xvgrclose(out); @@ -667,9 +680,8 @@ int gmx_nmeig(int argc, char *argv[]) } printf("Writing eigenfrequencies - negative eigenvalues will be set to zero.\n"); - out = xvgropen(opt2fn("-of", NFILE, fnm), - "Eigenfrequencies", "Eigenvector index", "Wavenumber [cm\\S-1\\N]", - oenv); + out = xvgropen(opt2fn("-of", NFILE, fnm), "Eigenfrequencies", "Eigenvector index", + "Wavenumber [cm\\S-1\\N]", oenv); if (output_env_get_print_xvgr_codes(oenv)) { if (bM) @@ -688,9 +700,7 @@ int gmx_nmeig(int argc, char *argv[]) snew(spectrum, maxspec); spec = xvgropen(opt2fn("-os", NFILE, fnm), "Vibrational spectrum based on harmonic approximation", - "\\f{12}w\\f{4} (cm\\S-1\\N)", - "Intensity [Gromacs units]", - oenv); + "\\f{12}w\\f{4} (cm\\S-1\\N)", "Intensity [Gromacs units]", oenv); for (i = 0; (i < maxspec); i++) { spectrum[i] = 0; @@ -705,41 +715,41 @@ int gmx_nmeig(int argc, char *argv[]) * light. Do this by first converting to omega^2 (units 1/s), take the square * root, and finally divide by the speed of light (nm/ps in gromacs). */ - factor_gmx_to_omega2 = 1.0E21/(AVOGADRO*AMU); - factor_omega_to_wavenumber = 1.0E-5/(2.0*M_PI*SPEED_OF_LIGHT); + factor_gmx_to_omega2 = 1.0E21 / (AVOGADRO * AMU); + factor_omega_to_wavenumber = 1.0E-5 / (2.0 * M_PI * SPEED_OF_LIGHT); value = 0; for (i = begin; (i <= end); i++) { - value = eigenvalues[i-begin]; + value = eigenvalues[i - begin]; if (value < 0) { value = 0; } - omega = std::sqrt(value*factor_gmx_to_omega2); - nu = 1e-12*omega/(2*M_PI); - value = omega*factor_omega_to_wavenumber; - fprintf (out, "%6d %15g\n", i, value); + omega = std::sqrt(value * factor_gmx_to_omega2); + nu = 1e-12 * omega / (2 * M_PI); + value = omega * factor_omega_to_wavenumber; + fprintf(out, "%6d %15g\n", i, value); if (nullptr != spec) { - wfac = eigenvalues[i-begin]/(width*std::sqrt(2*M_PI)); + wfac = eigenvalues[i - begin] / (width * std::sqrt(2 * M_PI)); for (j = 0; (j < maxspec); j++) { - spectrum[j] += wfac*std::exp(-gmx::square(j-value)/(2*gmx::square(width))); + spectrum[j] += wfac * std::exp(-gmx::square(j - value) / (2 * gmx::square(width))); } } if (nullptr != qc) { qcv = cv_corr(nu, T); qu = u_corr(nu, T); - if (i > end-nharm) + if (i > end - nharm) { - qcv += BOLTZ*KILO; - qu += BOLTZ*T; + qcv += BOLTZ * KILO; + qu += BOLTZ * T; } - fprintf (qc, "%6d %15g %15g\n", i, qcv, qu); + fprintf(qc, "%6d %15g %15g\n", i, qcv, qu); qcvtot += qcv; - qutot += qu; + qutot += qu; } } xvgrclose(out); @@ -753,7 +763,7 @@ int gmx_nmeig(int argc, char *argv[]) { for (j = 0; (j < maxspec); j++) { - fprintf(spec, "%10g %10g\n", 1.0*j, spectrum[j]); + fprintf(spec, "%10g %10g\n", 1.0 * j, spectrum[j]); } xvgrclose(spec); } @@ -772,7 +782,7 @@ int gmx_nmeig(int argc, char *argv[]) * nma_full_hessian() or nma_sparse_hessian() routines. Mass scaled vectors * will not be strictly orthogonal in plain cartesian scalar products. */ - const real *eigenvectorPtr; + const real* eigenvectorPtr; if (full_hessian != nullptr) { eigenvectorPtr = eigenvectors; @@ -780,15 +790,15 @@ int gmx_nmeig(int argc, char *argv[]) else { /* The sparse matrix diagonalization store all eigenvectors up to end */ - eigenvectorPtr = eigenvectors + (begin - 1)*atom_index.size(); + eigenvectorPtr = eigenvectors + (begin - 1) * atom_index.size(); } - write_eigenvectors(opt2fn("-v", NFILE, fnm), atom_index.size(), eigenvectorPtr, FALSE, begin, end, - eWXR_NO, nullptr, FALSE, top_x, bM, eigenvalues); + write_eigenvectors(opt2fn("-v", NFILE, fnm), atom_index.size(), eigenvectorPtr, FALSE, begin, + end, eWXR_NO, nullptr, FALSE, top_x, bM, eigenvalues); if (begin == 1) { - analyzeThermochemistry(stdout, top, top_x, atom_index, eigenvalues, - T, P, sigma_r, scale_factor, linear_toler); + analyzeThermochemistry(stdout, top, top_x, atom_index, eigenvalues, T, P, sigma_r, + scale_factor, linear_toler); please_cite(stdout, "Spoel2018a"); } else diff --git a/src/gromacs/gmxana/gmx_nmens.cpp b/src/gromacs/gmxana/gmx_nmens.cpp index 0157f7d132..ea3d6f47d3 100644 --- a/src/gromacs/gmxana/gmx_nmens.cpp +++ b/src/gromacs/gmxana/gmx_nmens.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,9 +59,9 @@ #include "gromacs/utility/smalloc.h" -int gmx_nmens(int argc, char *argv[]) +int gmx_nmens(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] generates an ensemble around an average structure", "in a subspace that is defined by a set of normal modes (eigenvectors).", "The eigenvectors are assumed to be mass-weighted.", @@ -71,64 +71,56 @@ int gmx_nmens(int argc, char *argv[]) "normal modes are the translational and rotational degrees of freedom." }; static int nstruct = 100, first = 7, last = -1, seed = 0; - static real temp = 300.0; - t_pargs pa[] = { - { "-temp", FALSE, etREAL, {&temp}, - "Temperature in Kelvin" }, - { "-seed", FALSE, etINT, {&seed}, - "Random seed (0 means generate)" }, - { "-num", FALSE, etINT, {&nstruct}, - "Number of structures to generate" }, - { "-first", FALSE, etINT, {&first}, - "First eigenvector to use (-1 is select)" }, - { "-last", FALSE, etINT, {&last}, - "Last eigenvector to use (-1 is till the last)" } + static real temp = 300.0; + t_pargs pa[] = { + { "-temp", FALSE, etREAL, { &temp }, "Temperature in Kelvin" }, + { "-seed", FALSE, etINT, { &seed }, "Random seed (0 means generate)" }, + { "-num", FALSE, etINT, { &nstruct }, "Number of structures to generate" }, + { "-first", FALSE, etINT, { &first }, "First eigenvector to use (-1 is select)" }, + { "-last", FALSE, etINT, { &last }, "Last eigenvector to use (-1 is till the last)" } }; #define NPA asize(pa) - t_trxstatus *out; + t_trxstatus* out; t_topology top; int ePBC; - t_atoms *atoms; - rvec *xtop, *xref, *xav, *xout1, *xout2; + t_atoms* atoms; + rvec * xtop, *xref, *xav, *xout1, *xout2; gmx_bool bDMR, bDMA, bFit; int nvec, *eignr = nullptr; - rvec **eigvec = nullptr; + rvec** eigvec = nullptr; matrix box; - real *eigval, *invsqrtm, t, disp; + real * eigval, *invsqrtm, t, disp; int natoms; - char *grpname; - const char *indexfile; + char* grpname; + const char* indexfile; int i, j, d, s, v; int nout, *iout, noutvec, *outvec; - int *index; + int* index; real rfac, rhalf, jr; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; int jran; const unsigned long im = 0xffff; const unsigned long ia = 1093; const unsigned long ic = 18257; - t_filenm fnm[] = { - { efTRN, "-v", "eigenvec", ffREAD }, - { efXVG, "-e", "eigenval", ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTRO, "-o", "ensemble", ffWRITE } - }; + t_filenm fnm[] = { { efTRN, "-v", "eigenvec", ffREAD }, + { efXVG, "-e", "eigenval", ffREAD }, + { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTRO, "-o", "ensemble", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } indexfile = ftp2fn_null(efNDX, NFILE, fnm); - read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, - &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval); + read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec, + &eignr, &eigvec, &eigval); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, box, bDMA); atoms = &top.atoms; @@ -137,8 +129,7 @@ int gmx_nmens(int argc, char *argv[]) get_index(atoms, indexfile, 1, &i, &index, &grpname); if (i != natoms) { - gmx_fatal(FARGS, "you selected a group with %d elements instead of %d", - i, natoms); + gmx_fatal(FARGS, "you selected a group with %d elements instead of %d", i, natoms); } printf("\n"); @@ -160,16 +151,16 @@ int gmx_nmens(int argc, char *argv[]) if (last == -1) { - last = natoms*DIM; + last = natoms * DIM; } if (first > -1) { /* make an index from first to last */ - nout = last-first+1; + nout = last - first + 1; snew(iout, nout); for (i = 0; i < nout; i++) { - iout[i] = first-1+i; + iout[i] = first - 1 + i; } } else @@ -180,14 +171,13 @@ int gmx_nmens(int argc, char *argv[]) do { nout++; - srenew(iout, nout+1); + srenew(iout, nout + 1); if (1 != scanf("%d", &iout[nout])) { gmx_fatal(FARGS, "Error reading user input"); } iout[nout]--; - } - while (iout[nout] >= 0); + } while (iout[nout] >= 0); printf("\n"); } @@ -222,12 +212,12 @@ int gmx_nmens(int argc, char *argv[]) fprintf(stderr, "Using random seed %d and a temperature of %g K.\n", seed, temp); - gmx::UniformIntDistribution dist(0, im-1); + gmx::UniformIntDistribution dist(0, im - 1); jran = dist(rng); snew(xout1, natoms); snew(xout2, atoms->nr); - out = open_trx(ftp2fn(efTRO, NFILE, fnm), "w"); + out = open_trx(ftp2fn(efTRO, NFILE, fnm), "w"); for (s = 0; s < nstruct; s++) { @@ -241,25 +231,25 @@ int gmx_nmens(int argc, char *argv[]) /* (r-0.5) n times: var_n = n * var_1 = n/12 n=4: var_n = 1/3, so multiply with 3 */ - rfac = std::sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]); - rhalf = 2.0*rfac; - rfac = rfac/im; + rfac = std::sqrt(3.0 * BOLTZ * temp / eigval[iout[j]]); + rhalf = 2.0 * rfac; + rfac = rfac / im; - jran = (jran*ia+ic) & im; + jran = (jran * ia + ic) & im; jr = jran; - jran = (jran*ia+ic) & im; - jr += jran; - jran = (jran*ia+ic) & im; - jr += jran; - jran = (jran*ia+ic) & im; - jr += jran; + jran = (jran * ia + ic) & im; + jr += jran; + jran = (jran * ia + ic) & im; + jr += jran; + jran = (jran * ia + ic) & im; + jr += jran; disp = rfac * jr - rhalf; for (i = 0; i < natoms; i++) { for (d = 0; d < DIM; d++) { - xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i]; + xout1[i][d] += disp * eigvec[v][i][d] * invsqrtm[i]; } } } @@ -267,9 +257,9 @@ int gmx_nmens(int argc, char *argv[]) { copy_rvec(xout1[i], xout2[index[i]]); } - t = s+1; + t = s + 1; write_trx(out, natoms, index, atoms, 0, t, box, xout2, nullptr, nullptr); - fprintf(stderr, "\rGenerated %d structures", s+1); + fprintf(stderr, "\rGenerated %d structures", s + 1); fflush(stderr); } fprintf(stderr, "\n"); diff --git a/src/gromacs/gmxana/gmx_nmr.cpp b/src/gromacs/gmxana/gmx_nmr.cpp index a8eff5ea27..37284b225d 100644 --- a/src/gromacs/gmxana/gmx_nmr.cpp +++ b/src/gromacs/gmxana/gmx_nmr.cpp @@ -72,7 +72,7 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/strconvert.h" -static real minthird = -1.0/3.0, minsixth = -1.0/6.0; +static real minthird = -1.0 / 3.0, minsixth = -1.0 / 6.0; static double mypow(double x, double y) { @@ -86,7 +86,7 @@ static double mypow(double x, double y) } } -static real blk_value(t_enxblock *blk, int sub, int index) +static real blk_value(t_enxblock* blk, int sub, int index) { range_check(index, 0, blk->sub[sub].nr); if (blk->sub[sub].type == xdr_datatype_float) @@ -103,11 +103,11 @@ static real blk_value(t_enxblock *blk, int sub, int index) } } -static int *select_it(int nre, char *nm[], int *nset) +static int* select_it(int nre, char* nm[], int* nset) { - gmx_bool *bE; + gmx_bool* bE; int n, k, j, i; - int *set; + int* set; gmx_bool bVerbose = TRUE; if ((getenv("GMX_ENER_VERBOSE")) != nullptr) @@ -120,11 +120,11 @@ static int *select_it(int nre, char *nm[], int *nset) if (bVerbose) { - for (k = 0; (k < nre); ) + for (k = 0; (k < nre);) { for (j = 0; (j < 4) && (k < nre); j++, k++) { - fprintf(stderr, " %3d=%14s", k+1, nm[k]); + fprintf(stderr, " %3d=%14s", k + 1, nm[k]); } fprintf(stderr, "\n"); } @@ -139,10 +139,9 @@ static int *select_it(int nre, char *nm[], int *nset) } if ((n > 0) && (n <= nre)) { - bE[n-1] = TRUE; + bE[n - 1] = TRUE; } - } - while (n != 0); + } while (n != 0); snew(set, nre); for (i = (*nset) = 0; (i < nre); i++) @@ -158,22 +157,21 @@ static int *select_it(int nre, char *nm[], int *nset) return set; } -static void get_orires_parms(const char *topnm, t_inputrec *ir, - int *nor, int *nex, int **label, real **obs) +static void get_orires_parms(const char* topnm, t_inputrec* ir, int* nor, int* nex, int** label, real** obs) { - gmx_mtop_t mtop; - t_topology top; - t_iparams *ip; - int natoms, i; - t_iatom *iatom; - int nb; - matrix box; + gmx_mtop_t mtop; + t_topology top; + t_iparams* ip; + int natoms, i; + t_iatom* iatom; + int nb; + matrix box; read_tpx(topnm, ir, box, &natoms, nullptr, nullptr, &mtop); top = gmx_mtop_t_to_t_topology(&mtop, FALSE); - ip = top.idef.iparams; - iatom = top.idef.il[F_ORIRES].iatoms; + ip = top.idef.iparams; + iatom = top.idef.il[F_ORIRES].iatoms; /* Count how many distance restraint there are... */ nb = top.idef.il[F_ORIRES].nr; @@ -182,35 +180,33 @@ static void get_orires_parms(const char *topnm, t_inputrec *ir, gmx_fatal(FARGS, "No orientation restraints in topology!\n"); } - *nor = nb/3; + *nor = nb / 3; *nex = 0; snew(*label, *nor); snew(*obs, *nor); for (i = 0; i < nb; i += 3) { - (*label)[i/3] = ip[iatom[i]].orires.label; - (*obs)[i/3] = ip[iatom[i]].orires.obs; + (*label)[i / 3] = ip[iatom[i]].orires.label; + (*obs)[i / 3] = ip[iatom[i]].orires.obs; if (ip[iatom[i]].orires.ex >= *nex) { - *nex = ip[iatom[i]].orires.ex+1; + *nex = ip[iatom[i]].orires.ex + 1; } } - fprintf(stderr, "Found %d orientation restraints with %d experiments", - *nor, *nex); + fprintf(stderr, "Found %d orientation restraints with %d experiments", *nor, *nex); done_top_mtop(&top, &mtop); } -static int get_bounds(real **bounds, int **index, int **dr_pair, int *npairs, - gmx_localtop_t *top) +static int get_bounds(real** bounds, int** index, int** dr_pair, int* npairs, gmx_localtop_t* top) { - t_functype *functype; - t_iparams *ip; - int i, j, k, type, ftype, natom; - t_ilist *disres; - t_iatom *iatom; - real *b; - int *ind, *pair; - int nb, label1; + t_functype* functype; + t_iparams* ip; + int i, j, k, type, ftype, natom; + t_ilist* disres; + t_iatom* iatom; + real* b; + int * ind, *pair; + int nb, label1; functype = top->idef.functype; ip = top->idef.iparams; @@ -225,7 +221,7 @@ static int get_bounds(real **bounds, int **index, int **dr_pair, int *npairs, /* Allocate memory */ snew(b, nb); snew(ind, nb); - snew(pair, nb+1); + snew(pair, nb + 1); /* Fill the bound array */ nb = 0; @@ -244,14 +240,14 @@ static int get_bounds(real **bounds, int **index, int **dr_pair, int *npairs, *bounds = b; /* Fill the index array */ - label1 = -1; - disres = &(top->idef.il[F_DISRES]); - iatom = disres->iatoms; - for (i = j = k = 0; (i < disres->nr); ) + label1 = -1; + disres = &(top->idef.il[F_DISRES]); + iatom = disres->iatoms; + for (i = j = k = 0; (i < disres->nr);) { type = iatom[i]; ftype = top->idef.functype[type]; - natom = interaction_function[ftype].nratoms+1; + natom = interaction_function[ftype].nratoms + 1; if (label1 != top->idef.iparams[type].disres.label) { pair[j] = k; @@ -261,8 +257,8 @@ static int get_bounds(real **bounds, int **index, int **dr_pair, int *npairs, k++; i += natom; } - pair[j] = k; - *npairs = k; + pair[j] = k; + *npairs = k; if (j != nb) { gmx_incons("get_bounds for distance restraints"); @@ -274,12 +270,12 @@ static int get_bounds(real **bounds, int **index, int **dr_pair, int *npairs, return nb; } -static void calc_violations(real rt[], real rav3[], int nb, const int index[], - real bounds[], real *viol, double *st, double *sa) +static void +calc_violations(real rt[], real rav3[], int nb, const int index[], real bounds[], real* viol, double* st, double* sa) { - const real sixth = 1.0/6.0; - int i, j; - double rsum, rav, sumaver, sumt; + const real sixth = 1.0 / 6.0; + int i, j; + double rsum, rav, sumaver, sumt; sumaver = 0; sumt = 0; @@ -287,85 +283,84 @@ static void calc_violations(real rt[], real rav3[], int nb, const int index[], { rsum = 0.0; rav = 0.0; - for (j = index[i]; (j < index[i+1]); j++) + for (j = index[i]; (j < index[i + 1]); j++) { if (viol) { viol[j] += mypow(rt[j], -3.0); } - rav += gmx::square(rav3[j]); - rsum += mypow(rt[j], -6); + rav += gmx::square(rav3[j]); + rsum += mypow(rt[j], -6); } - rsum = std::max(0.0, mypow(rsum, -sixth)-bounds[i]); - rav = std::max(0.0, mypow(rav, -sixth)-bounds[i]); + rsum = std::max(0.0, mypow(rsum, -sixth) - bounds[i]); + rav = std::max(0.0, mypow(rav, -sixth) - bounds[i]); - sumt += rsum; + sumt += rsum; sumaver += rav; } *st = sumt; *sa = sumaver; } -static void analyse_disre(const char *voutfn, int nframes, - real violaver[], real bounds[], int index[], - int pair[], int nbounds, - const gmx_output_env_t *oenv) +static void analyse_disre(const char* voutfn, + int nframes, + real violaver[], + real bounds[], + int index[], + int pair[], + int nbounds, + const gmx_output_env_t* oenv) { - FILE *vout; - double sum, sumt, sumaver; - int i, j; + FILE* vout; + double sum, sumt, sumaver; + int i, j; /* Subtract bounds from distances, to calculate violations */ - calc_violations(violaver, violaver, - nbounds, pair, bounds, nullptr, &sumt, &sumaver); + calc_violations(violaver, violaver, nbounds, pair, bounds, nullptr, &sumt, &sumaver); #ifdef DEBUG - fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n", - sumaver); - fprintf(stdout, "Largest violation averaged over simulation: %g nm\n\n", - sumt); + fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n", sumaver); + fprintf(stdout, "Largest violation averaged over simulation: %g nm\n\n", sumt); #endif - vout = xvgropen(voutfn, "r\\S-3\\N average violations", "DR Index", "nm", - oenv); + vout = xvgropen(voutfn, "r\\S-3\\N average violations", "DR Index", "nm", oenv); sum = 0.0; sumt = 0.0; for (i = 0; (i < nbounds); i++) { /* Do ensemble averaging */ sumaver = 0; - for (j = pair[i]; (j < pair[i+1]); j++) + for (j = pair[i]; (j < pair[i + 1]); j++) { - sumaver += gmx::square(violaver[j]/real(nframes)); + sumaver += gmx::square(violaver[j] / real(nframes)); } - sumaver = std::max(0.0, mypow(sumaver, minsixth)-bounds[i]); + sumaver = std::max(0.0, mypow(sumaver, minsixth) - bounds[i]); - sumt += sumaver; - sum = std::max(sum, sumaver); + sumt += sumaver; + sum = std::max(sum, sumaver); fprintf(vout, "%10d %10.5e\n", index[i], sumaver); } #ifdef DEBUG for (j = 0; (j < dr.ndr); j++) { - fprintf(vout, "%10d %10.5e\n", j, mypow(violaver[j]/real(nframes), minthird)); + fprintf(vout, "%10d %10.5e\n", j, mypow(violaver[j] / real(nframes), minthird)); } #endif xvgrclose(vout); - fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n", - sumt); + fprintf(stdout, "\nSum of violations averaged over simulation: %g nm\n", sumt); fprintf(stdout, "Largest violation averaged over simulation: %g nm\n\n", sum); do_view(oenv, voutfn, "-graphtype bar"); } -static void print_time(FILE *fp, double t) +static void print_time(FILE* fp, double t) { fprintf(fp, "%12.6f", t); } -int gmx_nmr(int argc, char *argv[]) +int gmx_nmr(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] extracts distance or orientation restraint", "data from an energy file. The user is prompted to interactively", "select the desired terms.[PAR]", @@ -396,72 +391,67 @@ int gmx_nmr(int argc, char *argv[]) }; - static gmx_bool bPrAll = FALSE; - static gmx_bool bDp = FALSE, bOrinst = FALSE, bOvec = FALSE; - static int skip = 0; - t_pargs pa[] = { - { "-dp", FALSE, etBOOL, {&bDp}, - "Print energies in high precision" }, - { "-skip", FALSE, etINT, {&skip}, - "Skip number of frames between data points" }, - { "-aver", FALSE, etBOOL, {&bPrAll}, - "Also print the exact average and rmsd stored in the energy frames (only when 1 term is requested)" }, - { "-orinst", FALSE, etBOOL, {&bOrinst}, - "Analyse instantaneous orientation data" }, - { "-ovec", FALSE, etBOOL, {&bOvec}, - "Also plot the eigenvectors with [TT]-oten[tt]" } - }; - const char * drleg[] = { - "Running average", - "Instantaneous" + static gmx_bool bPrAll = FALSE; + static gmx_bool bDp = FALSE, bOrinst = FALSE, bOvec = FALSE; + static int skip = 0; + t_pargs pa[] = { + { "-dp", FALSE, etBOOL, { &bDp }, "Print energies in high precision" }, + { "-skip", FALSE, etINT, { &skip }, "Skip number of frames between data points" }, + { "-aver", + FALSE, + etBOOL, + { &bPrAll }, + "Also print the exact average and rmsd stored in the energy frames (only when 1 term is " + "requested)" }, + { "-orinst", FALSE, etBOOL, { &bOrinst }, "Analyse instantaneous orientation data" }, + { "-ovec", FALSE, etBOOL, { &bOvec }, "Also plot the eigenvectors with [TT]-oten[tt]" } }; - - FILE /* *out = NULL,*/ *out_disre = nullptr, *fp_pairs = nullptr, *fort = nullptr, *fodt = nullptr, *foten = nullptr; - ener_file_t fp; - int timecheck = 0; - gmx_localtop_t top; - gmx_enxnm_t *enm = nullptr; - t_enxframe fr; - int nre, teller, teller_disre; - int nor = 0, nex = 0, norfr = 0, enx_i = 0; - real *bounds = nullptr, *violaver = nullptr, *oobs = nullptr, *orient = nullptr, *odrms = nullptr; - int *index = nullptr, *pair = nullptr, norsel = 0, *orsel = nullptr, *or_label = nullptr; - int nbounds = 0, npairs; - gmx_bool bDisRe, bDRAll, bORA, bORT, bODA, bODR, bODT, bORIRE, bOTEN; - gmx_bool bCont; - double sumaver, sumt; - int *set = nullptr, i, j, k, nset, sss; - char **pairleg, **odtleg, **otenleg; - char **leg = nullptr; - const char *anm_j, *anm_k, *resnm_j, *resnm_k; - int resnr_j, resnr_k; - const char *orinst_sub = "@ subtitle \"instantaneous\"\n"; - char buf[256]; - gmx_output_env_t *oenv; - t_enxblock *blk_disre = nullptr; + const char* drleg[] = { "Running average", "Instantaneous" }; + + FILE /* *out = NULL,*/ *out_disre = nullptr, *fp_pairs = nullptr, *fort = nullptr, + *fodt = nullptr, *foten = nullptr; + ener_file_t fp; + int timecheck = 0; + gmx_localtop_t top; + gmx_enxnm_t* enm = nullptr; + t_enxframe fr; + int nre, teller, teller_disre; + int nor = 0, nex = 0, norfr = 0, enx_i = 0; + real *bounds = nullptr, *violaver = nullptr, *oobs = nullptr, *orient = nullptr, *odrms = nullptr; + int * index = nullptr, *pair = nullptr, norsel = 0, *orsel = nullptr, *or_label = nullptr; + int nbounds = 0, npairs; + gmx_bool bDisRe, bDRAll, bORA, bORT, bODA, bODR, bODT, bORIRE, bOTEN; + gmx_bool bCont; + double sumaver, sumt; + int * set = nullptr, i, j, k, nset, sss; + char ** pairleg, **odtleg, **otenleg; + char** leg = nullptr; + const char *anm_j, *anm_k, *resnm_j, *resnm_k; + int resnr_j, resnr_k; + const char* orinst_sub = "@ subtitle \"instantaneous\"\n"; + char buf[256]; + gmx_output_env_t* oenv; + t_enxblock* blk_disre = nullptr; int ndisre = 0; - t_filenm fnm[] = { - { efEDR, "-f", nullptr, ffREAD }, - { efEDR, "-f2", nullptr, ffOPTRD }, - { efTPR, "-s", nullptr, ffOPTRD }, - // { efXVG, "-o", "energy", ffWRITE }, - { efXVG, "-viol", "violaver", ffOPTWR }, - { efXVG, "-pairs", "pairs", ffOPTWR }, - { efXVG, "-ora", "orienta", ffOPTWR }, - { efXVG, "-ort", "orientt", ffOPTWR }, - { efXVG, "-oda", "orideva", ffOPTWR }, - { efXVG, "-odr", "oridevr", ffOPTWR }, - { efXVG, "-odt", "oridevt", ffOPTWR }, - { efXVG, "-oten", "oriten", ffOPTWR } - }; + t_filenm fnm[] = { { efEDR, "-f", nullptr, ffREAD }, + { efEDR, "-f2", nullptr, ffOPTRD }, + { efTPR, "-s", nullptr, ffOPTRD }, + // { efXVG, "-o", "energy", ffWRITE }, + { efXVG, "-viol", "violaver", ffOPTWR }, + { efXVG, "-pairs", "pairs", ffOPTWR }, + { efXVG, "-ora", "orienta", ffOPTWR }, + { efXVG, "-ort", "orientt", ffOPTWR }, + { efXVG, "-oda", "orideva", ffOPTWR }, + { efXVG, "-odr", "oridevr", ffOPTWR }, + { efXVG, "-odt", "oridevt", ffOPTWR }, + { efXVG, "-oten", "oriten", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; + int npargs; npargs = asize(pa); - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, - NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_BEGIN | PCA_CAN_END, NFILE, fnm, + npargs, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -486,16 +476,15 @@ int gmx_nmr(int argc, char *argv[]) do_enxnms(fp, &nre, &enm); free_enxnms(nre, enm); - t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec irInstance; + t_inputrec* ir = &irInstance; init_enxframe(&fr); gmx::TopologyInformation topInfo; if (!bDisRe) { if (bORIRE || bOTEN) { - get_orires_parms(ftp2fn(efTPR, NFILE, fnm), ir, - &nor, &nex, &or_label, &oobs); + get_orires_parms(ftp2fn(efTPR, NFILE, fnm), ir, &nor, &nex, &or_label, &oobs); } if (bORIRE) @@ -526,13 +515,12 @@ int gmx_nmr(int argc, char *argv[]) do { j++; - srenew(orsel, j+1); + srenew(orsel, j + 1); if (1 != scanf("%d", &(orsel[j]))) { gmx_fatal(FARGS, "Error reading user input"); } - } - while (orsel[j] > 0); + } while (orsel[j] > 0); if (orsel[0] == -1) { fprintf(stderr, "Selecting all %d orientation restraints\n", nor); @@ -560,8 +548,7 @@ int gmx_nmr(int argc, char *argv[]) } if (k == nor) { - fprintf(stderr, "Orientation restraint label %d not found\n", - orsel[i]); + fprintf(stderr, "Orientation restraint label %d not found\n", orsel[i]); } } } @@ -583,8 +570,7 @@ int gmx_nmr(int argc, char *argv[]) } if (bODT) { - fodt = xvgropen(opt2fn("-odt", NFILE, fnm), - "Orientation restraint deviation", + fodt = xvgropen(opt2fn("-odt", NFILE, fnm), "Orientation restraint deviation", "Time (ps)", "", oenv); if (bOrinst && output_env_get_print_xvgr_codes(oenv)) { @@ -601,26 +587,25 @@ int gmx_nmr(int argc, char *argv[]) } if (bOTEN) { - foten = xvgropen(opt2fn("-oten", NFILE, fnm), - "Order tensor", "Time (ps)", "", oenv); - snew(otenleg, bOvec ? nex*12 : nex*3); + foten = xvgropen(opt2fn("-oten", NFILE, fnm), "Order tensor", "Time (ps)", "", oenv); + snew(otenleg, bOvec ? nex * 12 : nex * 3); for (i = 0; i < nex; i++) { for (j = 0; j < 3; j++) { - sprintf(buf, "eig%d", j+1); - otenleg[(bOvec ? 12 : 3)*i+j] = gmx_strdup(buf); + sprintf(buf, "eig%d", j + 1); + otenleg[(bOvec ? 12 : 3) * i + j] = gmx_strdup(buf); } if (bOvec) { for (j = 0; j < 9; j++) { - sprintf(buf, "vec%d%s", j/3+1, j%3 == 0 ? "x" : (j%3 == 1 ? "y" : "z")); - otenleg[12*i+3+j] = gmx_strdup(buf); + sprintf(buf, "vec%d%s", j / 3 + 1, j % 3 == 0 ? "x" : (j % 3 == 1 ? "y" : "z")); + otenleg[12 * i + 3 + j] = gmx_strdup(buf); } } } - xvgr_legend(foten, bOvec ? nex*12 : nex*3, otenleg, oenv); + xvgr_legend(foten, bOvec ? nex * 12 : nex * 3, otenleg, oenv); for (j = 0; j < 3; j++) { sfree(otenleg[j]); @@ -634,20 +619,17 @@ int gmx_nmr(int argc, char *argv[]) topInfo.fillFromInputFile(ftp2fn(efTPR, NFILE, fnm)); gmx_mtop_generate_local_top(*topInfo.mtop(), &top, ir->efep != efepNO); } - nbounds = get_bounds(&bounds, &index, &pair, &npairs, - &top); + nbounds = get_bounds(&bounds, &index, &pair, &npairs, &top); snew(violaver, npairs); - out_disre = xvgropen(opt2fn("-o", NFILE, fnm), "Sum of Violations", - "Time (ps)", "nm", oenv); + out_disre = xvgropen(opt2fn("-o", NFILE, fnm), "Sum of Violations", "Time (ps)", "nm", oenv); xvgr_legend(out_disre, 2, drleg, oenv); if (bDRAll) { - fp_pairs = xvgropen(opt2fn("-pairs", NFILE, fnm), "Pair Distances", - "Time (ps)", "Distance (nm)", oenv); + fp_pairs = xvgropen(opt2fn("-pairs", NFILE, fnm), "Pair Distances", "Time (ps)", + "Distance (nm)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(fp_pairs, "@ subtitle \"averaged (tau=%g) and instantaneous\"\n", - ir->dr_tau); + fprintf(fp_pairs, "@ subtitle \"averaged (tau=%g) and instantaneous\"\n", ir->dr_tau); } } } @@ -667,8 +649,7 @@ int gmx_nmr(int argc, char *argv[]) { timecheck = check_times(fr.t); } - } - while (bCont && (timecheck < 0)); + } while (bCont && (timecheck < 0)); if ((timecheck == 0) && bCont) { @@ -679,46 +660,46 @@ int gmx_nmr(int argc, char *argv[]) blk_disre = find_block_id_enxframe(&fr, enxDISRE, nullptr); if (bDisRe && bDRAll && !leg && blk_disre) { - t_iatom *fa; - t_iparams *ip; + t_iatom* fa; + t_iparams* ip; fa = top.idef.il[F_DISRES].iatoms; ip = top.idef.iparams; - if (blk_disre->nsub != 2 || - (blk_disre->sub[0].nr != blk_disre->sub[1].nr) ) + if (blk_disre->nsub != 2 || (blk_disre->sub[0].nr != blk_disre->sub[1].nr)) { gmx_incons("Number of disre sub-blocks not equal to 2"); } ndisre = blk_disre->sub[0].nr; - if (ndisre != top.idef.il[F_DISRES].nr/3) + if (ndisre != top.idef.il[F_DISRES].nr / 3) { - gmx_fatal(FARGS, "Number of disre pairs in the energy file (%d) does not match the number in the run input file (%d)\n", - ndisre, top.idef.il[F_DISRES].nr/3); + gmx_fatal(FARGS, + "Number of disre pairs in the energy file (%d) does not match the " + "number in the run input file (%d)\n", + ndisre, top.idef.il[F_DISRES].nr / 3); } snew(pairleg, ndisre); int molb = 0; for (i = 0; i < ndisre; i++) { snew(pairleg[i], 30); - j = fa[3*i+1]; - k = fa[3*i+2]; + j = fa[3 * i + 1]; + k = fa[3 * i + 2]; mtopGetAtomAndResidueName(topInfo.mtop(), j, &molb, &anm_j, &resnr_j, &resnm_j, nullptr); mtopGetAtomAndResidueName(topInfo.mtop(), k, &molb, &anm_k, &resnr_k, &resnm_k, nullptr); - sprintf(pairleg[i], "%d %s %d %s (%d)", - resnr_j, anm_j, resnr_k, anm_k, - ip[fa[3*i]].disres.label); + sprintf(pairleg[i], "%d %s %d %s (%d)", resnr_j, anm_j, resnr_k, anm_k, + ip[fa[3 * i]].disres.label); } set = select_it(ndisre, pairleg, &nset); - snew(leg, 2*nset); + snew(leg, 2 * nset); for (i = 0; (i < nset); i++) { - snew(leg[2*i], 32); - sprintf(leg[2*i], "a %s", pairleg[set[i]]); - snew(leg[2*i+1], 32); - sprintf(leg[2*i+1], "i %s", pairleg[set[i]]); + snew(leg[2 * i], 32); + sprintf(leg[2 * i], "a %s", pairleg[set[i]]); + snew(leg[2 * i + 1], 32); + sprintf(leg[2 * i + 1], "i %s", pairleg[set[i]]); } - xvgr_legend(fp_pairs, 2*nset, leg, oenv); + xvgr_legend(fp_pairs, 2 * nset, leg, oenv); } /* @@ -733,14 +714,15 @@ int gmx_nmr(int argc, char *argv[]) *******************************************/ if (ndisre > 0) { - GMX_RELEASE_ASSERT(blk_disre != nullptr, "Trying to dereference NULL blk_disre pointer"); - #if !GMX_DOUBLE - float *disre_rt = blk_disre->sub[0].fval; - float *disre_rm3tav = blk_disre->sub[1].fval; - #else - double *disre_rt = blk_disre->sub[0].dval; - double *disre_rm3tav = blk_disre->sub[1].dval; - #endif + GMX_RELEASE_ASSERT(blk_disre != nullptr, + "Trying to dereference NULL blk_disre pointer"); +#if !GMX_DOUBLE + float* disre_rt = blk_disre->sub[0].fval; + float* disre_rm3tav = blk_disre->sub[1].fval; +#else + double* disre_rt = blk_disre->sub[0].dval; + double* disre_rm3tav = blk_disre->sub[1].dval; +#endif print_time(out_disre, fr.t); if (violaver == nullptr) @@ -749,8 +731,8 @@ int gmx_nmr(int argc, char *argv[]) } /* Subtract bounds from distances, to calculate violations */ - calc_violations(disre_rt, disre_rm3tav, - nbounds, pair, bounds, violaver, &sumt, &sumaver); + calc_violations(disre_rt, disre_rm3tav, nbounds, pair, bounds, violaver, + &sumt, &sumaver); fprintf(out_disre, " %8.4f %8.4f\n", sumaver, sumt); if (bDRAll) @@ -773,7 +755,7 @@ int gmx_nmr(int argc, char *argv[]) *******************************************/ else { - t_enxblock *blk = find_block_id_enxframe(&fr, enx_i, nullptr); + t_enxblock* blk = find_block_id_enxframe(&fr, enx_i, nullptr); if (bORIRE && blk) { if (blk->nsub != 1) @@ -783,7 +765,10 @@ int gmx_nmr(int argc, char *argv[]) if (blk->sub[0].nr != nor) { - gmx_fatal(FARGS, "Number of orientation restraints in energy file (%d) does not match with the topology (%d)", blk->sub[0].nr, nor); + gmx_fatal(FARGS, + "Number of orientation restraints in energy file (%d) does " + "not match with the topology (%d)", + blk->sub[0].nr, nor); } if (bORA || bODA) { @@ -814,7 +799,7 @@ int gmx_nmr(int argc, char *argv[]) fprintf(fodt, " %10f", fr.t); for (i = 0; i < norsel; i++) { - fprintf(fodt, " %g", blk_value(blk, 0, orsel[i])-oobs[orsel[i]]); + fprintf(fodt, " %g", blk_value(blk, 0, orsel[i]) - oobs[orsel[i]]); } fprintf(fodt, "\n"); } @@ -828,17 +813,19 @@ int gmx_nmr(int argc, char *argv[]) gmx_fatal(FARGS, "Orientational restraints read in incorrectly"); } - if (blk->sub[0].nr != nex*12) + if (blk->sub[0].nr != nex * 12) { - gmx_fatal(FARGS, "Number of orientation experiments in energy file (%d) does not match with the topology (%d)", - blk->sub[0].nr/12, nex); + gmx_fatal(FARGS, + "Number of orientation experiments in energy file (%d) does " + "not match with the topology (%d)", + blk->sub[0].nr / 12, nex); } fprintf(foten, " %10f", fr.t); for (i = 0; i < nex; i++) { for (j = 0; j < (bOvec ? 12 : 3); j++) { - fprintf(foten, " %g", blk_value(blk, 0, i*12+j)); + fprintf(foten, " %g", blk_value(blk, 0, i * 12 + j)); } } fprintf(foten, "\n"); @@ -847,8 +834,7 @@ int gmx_nmr(int argc, char *argv[]) } teller++; } - } - while (bCont && (timecheck == 0)); + } while (bCont && (timecheck == 0)); free_enxframe(&fr); fprintf(stderr, "\n"); @@ -873,8 +859,7 @@ int gmx_nmr(int argc, char *argv[]) } if (bORA) { - FILE *out = xvgropen(opt2fn("-ora", NFILE, fnm), - "Average calculated orientations", + FILE* out = xvgropen(opt2fn("-ora", NFILE, fnm), "Average calculated orientations", "Restraint label", "", oenv); if (bOrinst && output_env_get_print_xvgr_codes(oenv)) { @@ -882,14 +867,13 @@ int gmx_nmr(int argc, char *argv[]) } for (i = 0; i < nor; i++) { - fprintf(out, "%5d %g\n", or_label[i], orient[i]/real(norfr)); + fprintf(out, "%5d %g\n", or_label[i], orient[i] / real(norfr)); } xvgrclose(out); } if (bODA) { - FILE *out = xvgropen(opt2fn("-oda", NFILE, fnm), - "Average restraint deviation", + FILE* out = xvgropen(opt2fn("-oda", NFILE, fnm), "Average restraint deviation", "Restraint label", "", oenv); if (bOrinst && output_env_get_print_xvgr_codes(oenv)) { @@ -897,14 +881,13 @@ int gmx_nmr(int argc, char *argv[]) } for (i = 0; i < nor; i++) { - fprintf(out, "%5d %g\n", or_label[i], orient[i]/real(norfr)-oobs[i]); + fprintf(out, "%5d %g\n", or_label[i], orient[i] / real(norfr) - oobs[i]); } xvgrclose(out); } if (bODR) { - FILE *out = xvgropen(opt2fn("-odr", NFILE, fnm), - "RMS orientation restraint deviations", + FILE* out = xvgropen(opt2fn("-odr", NFILE, fnm), "RMS orientation restraint deviations", "Restraint label", "", oenv); if (bOrinst && output_env_get_print_xvgr_codes(oenv)) { @@ -912,7 +895,7 @@ int gmx_nmr(int argc, char *argv[]) } for (i = 0; i < nor; i++) { - fprintf(out, "%5d %g\n", or_label[i], std::sqrt(odrms[i]/real(norfr))); + fprintf(out, "%5d %g\n", or_label[i], std::sqrt(odrms[i] / real(norfr))); } xvgrclose(out); } @@ -929,11 +912,11 @@ int gmx_nmr(int argc, char *argv[]) if (bDisRe) { - analyse_disre(opt2fn("-viol", NFILE, fnm), - teller_disre, violaver, bounds, index, pair, nbounds, oenv); + analyse_disre(opt2fn("-viol", NFILE, fnm), teller_disre, violaver, bounds, index, pair, + nbounds, oenv); } { - const char *nxy = "-nxy"; + const char* nxy = "-nxy"; do_view(oenv, opt2fn_null("-ora", NFILE, fnm), nxy); do_view(oenv, opt2fn_null("-ort", NFILE, fnm), nxy); diff --git a/src/gromacs/gmxana/gmx_nmtraj.cpp b/src/gromacs/gmxana/gmx_nmtraj.cpp index b7777611e8..7c4557cec0 100644 --- a/src/gromacs/gmxana/gmx_nmtraj.cpp +++ b/src/gromacs/gmxana/gmx_nmtraj.cpp @@ -59,10 +59,9 @@ #include "gromacs/utility/strconvert.h" #include "gromacs/utility/stringutil.h" -int gmx_nmtraj(int argc, char *argv[]) +int gmx_nmtraj(int argc, char* argv[]) { - const char *desc[] = - { + const char* desc[] = { "[THISMODULE] generates an virtual trajectory from an eigenvector, ", "corresponding to a harmonic Cartesian oscillation around the average ", "structure. The eigenvectors should normally be mass-weighted, but you can ", @@ -74,81 +73,77 @@ int gmx_nmtraj(int argc, char *argv[]) "assuming equipartition of the energy over all modes. To make the motion clearly visible ", "in PyMol you might want to amplify it by setting an unrealistically high temperature. ", "However, be aware that both the linear Cartesian displacements and mass weighting will ", - "lead to serious structure deformation for high amplitudes - this is is simply a limitation ", - "of the Cartesian normal mode model. By default the selected eigenvector is set to 7, since ", + "lead to serious structure deformation for high amplitudes - this is is simply a ", + "limitation of the Cartesian normal mode model. By default the selected eigenvector ", + "is set to 7, since ", "the first six normal modes are the translational and rotational degrees of freedom." }; static real refamplitude = 0.25; static int nframes = 30; static real temp = 300.0; - static const char *eignrvec = "7"; - static const char *phasevec = "0.0"; - - t_pargs pa[] = - { - { "-eignr", FALSE, etSTR, {&eignrvec}, "String of eigenvectors to use (first is 1)" }, - { "-phases", FALSE, etSTR, {&phasevec}, "String of phases (default is 0.0)" }, - { "-temp", FALSE, etREAL, {&temp}, "Temperature (K)" }, - { "-amplitude", FALSE, etREAL, {&refamplitude}, "Amplitude for modes with eigenvalue<=0" }, - { "-nframes", FALSE, etINT, {&nframes}, "Number of frames to generate" } + static const char* eignrvec = "7"; + static const char* phasevec = "0.0"; + + t_pargs pa[] = { + { "-eignr", FALSE, etSTR, { &eignrvec }, "String of eigenvectors to use (first is 1)" }, + { "-phases", FALSE, etSTR, { &phasevec }, "String of phases (default is 0.0)" }, + { "-temp", FALSE, etREAL, { &temp }, "Temperature (K)" }, + { "-amplitude", FALSE, etREAL, { &refamplitude }, "Amplitude for modes with eigenvalue<=0" }, + { "-nframes", FALSE, etINT, { &nframes }, "Number of frames to generate" } }; #define NPA asize(pa) - t_trxstatus *out; - t_topology top; - int ePBC; - t_atoms *atoms; - rvec *xtop, *xref, *xav, *xout; - int nvec, *eignr = nullptr; - rvec **eigvec = nullptr; - matrix box; - int natoms; - int i, j, k, kmode, d; - gmx_bool bDMR, bDMA, bFit; - - real * eigval; - int * dummy; - real * invsqrtm; - int *out_eigidx; - rvec * this_eigvec; + t_trxstatus* out; + t_topology top; + int ePBC; + t_atoms* atoms; + rvec * xtop, *xref, *xav, *xout; + int nvec, *eignr = nullptr; + rvec** eigvec = nullptr; + matrix box; + int natoms; + int i, j, k, kmode, d; + gmx_bool bDMR, bDMA, bFit; + + real* eigval; + int* dummy; + real* invsqrtm; + int* out_eigidx; + rvec* this_eigvec; real omega, Ekin, m, vel; - real *amplitude; - gmx_output_env_t *oenv; + real* amplitude; + gmx_output_env_t* oenv; - t_filenm fnm[] = - { - { efTPS, nullptr, nullptr, ffREAD }, - { efTRN, "-v", "eigenvec", ffREAD }, - { efTRO, "-o", "nmtraj", ffWRITE } - }; + t_filenm fnm[] = { { efTPS, nullptr, nullptr, ffREAD }, + { efTRN, "-v", "eigenvec", ffREAD }, + { efTRO, "-o", "nmtraj", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, - &xref, &bDMR, &xav, &bDMA, &nvec, &eignr, &eigvec, &eigval); + read_eigenvectors(opt2fn("-v", NFILE, fnm), &natoms, &bFit, &xref, &bDMR, &xav, &bDMA, &nvec, + &eignr, &eigvec, &eigval); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, box, bDMA); /* Find vectors and phases */ std::vector imodes; - for (const auto &imodeString : gmx::splitString(eignrvec)) + for (const auto& imodeString : gmx::splitString(eignrvec)) { imodes.emplace_back(gmx::fromStdString(imodeString)); } - int nmodes = gmx::ssize(imodes); + int nmodes = gmx::ssize(imodes); std::vector phases; phases.reserve(nmodes); - for (const auto &phaseString : gmx::splitString(phasevec)) + for (const auto& phaseString : gmx::splitString(phasevec)) { phases.emplace_back(gmx::fromStdString(phaseString)); } @@ -161,7 +156,7 @@ int gmx_nmtraj(int argc, char *argv[]) if (nmodes > nphases) { - printf("Warning: Setting phase of last %d modes to zero...\n", nmodes-nphases); + printf("Warning: Setting phase of last %d modes to zero...\n", nmodes - nphases); phases.resize(nmodes, 0); } @@ -231,12 +226,12 @@ int gmx_nmtraj(int argc, char *argv[]) kmode = out_eigidx[i]; this_eigvec = eigvec[kmode]; - if ( (kmode >= 6) && (eigval[kmode] > 0)) + if ((kmode >= 6) && (eigval[kmode] > 0)) { /* Derive amplitude from temperature and eigenvalue if we can */ /* Convert eigenvalue to angular frequency, in units s^(-1) */ - omega = std::sqrt(eigval[kmode]*1.0E21/(AVOGADRO*AMU)); + omega = std::sqrt(eigval[kmode] * 1.0E21 / (AVOGADRO * AMU)); /* Harmonic motion will be x=x0 + A*sin(omega*t)*eigenvec. * The velocity is thus: * @@ -258,18 +253,18 @@ int gmx_nmtraj(int argc, char *argv[]) m = atoms->atom[k].m; for (d = 0; d < DIM; d++) { - vel = omega*this_eigvec[k][d]; - Ekin += 0.5*0.5*m*vel*vel; + vel = omega * this_eigvec[k][d]; + Ekin += 0.5 * 0.5 * m * vel * vel; } } /* Convert Ekin from amu*(nm/s)^2 to J, i.e., kg*(m/s)^2 * This will also be proportional to A^2 */ - Ekin *= AMU*1E-18; + Ekin *= AMU * 1E-18; /* Set the amplitude so the energy is kT/2 */ - amplitude[i] = std::sqrt(0.5*BOLTZMANN*temp/Ekin); + amplitude[i] = std::sqrt(0.5 * BOLTZMANN * temp / Ekin); } else { @@ -285,7 +280,7 @@ int gmx_nmtraj(int argc, char *argv[]) for (i = 0; i < nframes; i++) { - real fraction = static_cast(i)/static_cast(nframes); + real fraction = static_cast(i) / static_cast(nframes); for (j = 0; j < natoms; j++) { copy_rvec(xav[j], xout[j]); @@ -300,7 +295,8 @@ int gmx_nmtraj(int argc, char *argv[]) { for (d = 0; d < DIM; d++) { - xout[j][d] += amplitude[k]*std::sin(2*M_PI*(fraction+phases[k]/360.0))*this_eigvec[j][d]; + xout[j][d] += amplitude[k] * std::sin(2 * M_PI * (fraction + phases[k] / 360.0)) + * this_eigvec[j][d]; } } } diff --git a/src/gromacs/gmxana/gmx_order.cpp b/src/gromacs/gmxana/gmx_order.cpp index 0073ec72d2..b608e85b83 100644 --- a/src/gromacs/gmxana/gmx_order.cpp +++ b/src/gromacs/gmxana/gmx_order.cpp @@ -75,22 +75,28 @@ /* P.J. van Maaren, November 2005 Added tetrahedral stuff */ /****************************************************************************/ -static void find_nearest_neighbours(int ePBC, - int natoms, matrix box, - rvec x[], int maxidx, const int index[], - real *sgmean, real *skmean, - int nslice, int slice_dim, - real sgslice[], real skslice[], +static void find_nearest_neighbours(int ePBC, + int natoms, + matrix box, + rvec x[], + int maxidx, + const int index[], + real* sgmean, + real* skmean, + int nslice, + int slice_dim, + real sgslice[], + real skslice[], gmx_rmpbc_t gpbc) { - int ix, jx, nsgbin, *sgbin; - int i, ibin, j, k, l, n, *nn[4]; - rvec dx, rj, rk, urk, urj; - real cost, cost2, *sgmol, *skmol, rmean, rmean2, r2, box2, *r_nn[4]; - t_pbc pbc; - int sl_index; - real *sl_count; - real onethird = 1.0/3.0; + int ix, jx, nsgbin, *sgbin; + int i, ibin, j, k, l, n, *nn[4]; + rvec dx, rj, rk, urk, urj; + real cost, cost2, *sgmol, *skmol, rmean, rmean2, r2, box2, *r_nn[4]; + t_pbc pbc; + int sl_index; + real* sl_count; + real onethird = 1.0 / 3.0; /* dmat = init_mat(maxidx, FALSE); */ box2 = box[XX][XX] * box[XX][XX]; snew(sl_count, nslice); @@ -139,25 +145,35 @@ static void find_nearest_neighbours(int ePBC, /* determine the nearest neighbours */ if (r2 < r_nn[0][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i]; - r_nn[1][i] = r_nn[0][i]; nn[1][i] = nn[0][i]; - r_nn[0][i] = r2; nn[0][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r_nn[1][i]; + nn[2][i] = nn[1][i]; + r_nn[1][i] = r_nn[0][i]; + nn[1][i] = nn[0][i]; + r_nn[0][i] = r2; + nn[0][i] = j; } else if (r2 < r_nn[1][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r_nn[1][i]; nn[2][i] = nn[1][i]; - r_nn[1][i] = r2; nn[1][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r_nn[1][i]; + nn[2][i] = nn[1][i]; + r_nn[1][i] = r2; + nn[1][i] = j; } else if (r2 < r_nn[2][i]) { - r_nn[3][i] = r_nn[2][i]; nn[3][i] = nn[2][i]; - r_nn[2][i] = r2; nn[2][i] = j; + r_nn[3][i] = r_nn[2][i]; + nn[3][i] = nn[2][i]; + r_nn[2][i] = r2; + nn[2][i] = j; } else if (r2 < r_nn[3][i]) { - r_nn[3][i] = r2; nn[3][i] = j; + r_nn[3][i] = r2; + nn[3][i] = j; } } @@ -167,7 +183,7 @@ static void find_nearest_neighbours(int ePBC, for (j = 0; (j < 4); j++) { r_nn[j][i] = std::sqrt(r_nn[j][i]); - rmean += r_nn[j][i]; + rmean += r_nn[j][i]; } rmean /= 4; @@ -179,7 +195,7 @@ static void find_nearest_neighbours(int ePBC, /* angular part tetrahedrality order parameter per atom */ for (j = 0; (j < 3); j++) { - for (k = j+1; (k < 4); k++) + for (k = j + 1; (k < 4); k++) { pbc_dx(&pbc, x[ix], x[index[nn[k][i]]], rk); pbc_dx(&pbc, x[ix], x[index[nn[j][i]]], rj); @@ -206,7 +222,7 @@ static void find_nearest_neighbours(int ePBC, } /* normalize sgmol between 0.0 and 1.0 */ - sgmol[i] = 3*sgmol[i]/32; + sgmol[i] = 3 * sgmol[i] / 32; *sgmean += sgmol[i]; /* distance part tetrahedrality order parameter per atom */ @@ -222,7 +238,9 @@ static void find_nearest_neighbours(int ePBC, *skmean += skmol[i]; /* Compute sliced stuff */ - sl_index = static_cast(std::round((1+x[i][slice_dim]/box[slice_dim][slice_dim])*static_cast(nslice))) % nslice; + sl_index = static_cast(std::round((1 + x[i][slice_dim] / box[slice_dim][slice_dim]) + * static_cast(nslice))) + % nslice; sgslice[sl_index] += sgmol[i]; skslice[sl_index] += skmol[i]; sl_count[sl_index]++; @@ -251,26 +269,30 @@ static void find_nearest_neighbours(int ePBC, } -static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, - const char *fnTRX, const char *sgfn, - const char *skfn, - int nslice, int slice_dim, - const char *sgslfn, const char *skslfn, - const gmx_output_env_t *oenv) +static void calc_tetra_order_parm(const char* fnNDX, + const char* fnTPS, + const char* fnTRX, + const char* sgfn, + const char* skfn, + int nslice, + int slice_dim, + const char* sgslfn, + const char* skslfn, + const gmx_output_env_t* oenv) { - FILE *fpsg = nullptr, *fpsk = nullptr; + FILE * fpsg = nullptr, *fpsk = nullptr; t_topology top; int ePBC; - t_trxstatus *status; + t_trxstatus* status; int natoms; real t; - rvec *xtop, *x; + rvec * xtop, *x; matrix box; real sg, sk; - int **index; - char **grpname; + int** index; + char** grpname; int i, *isize, ng, nframes; - real *sg_slice, *sg_slice_tot, *sk_slice, *sk_slice_tot; + real * sg_slice, *sg_slice_tot, *sk_slice, *sk_slice_tot; gmx_rmpbc_t gpbc = nullptr; @@ -282,7 +304,8 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, snew(sk_slice_tot, nslice); ng = 1; /* get index groups */ - printf("Select the group that contains the atoms you want to use for the tetrahedrality order parameter calculation:\n"); + printf("Select the group that contains the atoms you want to use for the tetrahedrality order " + "parameter calculation:\n"); snew(grpname, ng); snew(index, ng); snew(isize, ng); @@ -292,23 +315,20 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box); if (natoms > top.atoms.nr) { - gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", - top.atoms.nr, natoms); + gmx_fatal(FARGS, "Topology (%d atoms) does not match trajectory (%d atoms)", top.atoms.nr, natoms); } check_index(nullptr, ng, index[0], nullptr, natoms); - fpsg = xvgropen(sgfn, "S\\sg\\N Angle Order Parameter", "Time (ps)", "S\\sg\\N", - oenv); - fpsk = xvgropen(skfn, "S\\sk\\N Distance Order Parameter", "Time (ps)", "S\\sk\\N", - oenv); + fpsg = xvgropen(sgfn, "S\\sg\\N Angle Order Parameter", "Time (ps)", "S\\sg\\N", oenv); + fpsk = xvgropen(skfn, "S\\sk\\N Distance Order Parameter", "Time (ps)", "S\\sk\\N", oenv); /* loop over frames */ gpbc = gmx_rmpbc_init(&top.idef, ePBC, natoms); nframes = 0; do { - find_nearest_neighbours(ePBC, natoms, box, x, isize[0], index[0], - &sg, &sk, nslice, slice_dim, sg_slice, sk_slice, gpbc); + find_nearest_neighbours(ePBC, natoms, box, x, isize[0], index[0], &sg, &sk, nslice, + slice_dim, sg_slice, sk_slice, gpbc); for (i = 0; (i < nslice); i++) { sg_slice_tot[i] += sg_slice[i]; @@ -317,8 +337,7 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, fprintf(fpsg, "%f %f\n", t, sg); fprintf(fpsk, "%f %f\n", t, sk); nframes++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); gmx_rmpbc_done(gpbc); @@ -329,18 +348,14 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, xvgrclose(fpsg); xvgrclose(fpsk); - fpsg = xvgropen(sgslfn, - "S\\sg\\N Angle Order Parameter / Slab", "(nm)", "S\\sg\\N", - oenv); - fpsk = xvgropen(skslfn, - "S\\sk\\N Distance Order Parameter / Slab", "(nm)", "S\\sk\\N", - oenv); + fpsg = xvgropen(sgslfn, "S\\sg\\N Angle Order Parameter / Slab", "(nm)", "S\\sg\\N", oenv); + fpsk = xvgropen(skslfn, "S\\sk\\N Distance Order Parameter / Slab", "(nm)", "S\\sk\\N", oenv); for (i = 0; (i < nslice); i++) { - fprintf(fpsg, "%10g %10g\n", (i+0.5)*box[slice_dim][slice_dim]/nslice, - sg_slice_tot[i]/static_cast(nframes)); - fprintf(fpsk, "%10g %10g\n", (i+0.5)*box[slice_dim][slice_dim]/nslice, - sk_slice_tot[i]/static_cast(nframes)); + fprintf(fpsg, "%10g %10g\n", (i + 0.5) * box[slice_dim][slice_dim] / nslice, + sg_slice_tot[i] / static_cast(nframes)); + fprintf(fpsk, "%10g %10g\n", (i + 0.5) * box[slice_dim][slice_dim] / nslice, + sk_slice_tot[i] / static_cast(nframes)); } xvgrclose(fpsg); xvgrclose(fpsk); @@ -348,16 +363,15 @@ static void calc_tetra_order_parm(const char *fnNDX, const char *fnTPS, /* Print name of first atom in all groups in index file */ -static void print_types(const int index[], int a[], int ngrps, - char *groups[], const t_topology *top) +static void print_types(const int index[], int a[], int ngrps, char* groups[], const t_topology* top) { int i; fprintf(stderr, "Using following groups: \n"); for (i = 0; i < ngrps; i++) { - fprintf(stderr, "Groupname: %s First atomname: %s First atomnr %d\n", - groups[i], *(top->atoms.atomname[a[index[i]]]), a[index[i]]); + fprintf(stderr, "Groupname: %s First atomname: %s First atomnr %d\n", groups[i], + *(top->atoms.atomname[a[index[i]]]), a[index[i]]); } fprintf(stderr, "\n"); } @@ -366,49 +380,62 @@ static void check_length(real length, int a, int b) { if (length > 0.3) { - fprintf(stderr, "WARNING: distance between atoms %d and " + fprintf(stderr, + "WARNING: distance between atoms %d and " "%d > 0.3 nm (%f). Index file might be corrupt.\n", a, b, length); } } -static void calc_order(const char *fn, const int *index, int *a, rvec **order, - real ***slOrder, real *slWidth, int nslices, gmx_bool bSliced, - gmx_bool bUnsat, const t_topology *top, int ePBC, int ngrps, int axis, - gmx_bool permolecule, gmx_bool radial, gmx_bool distcalc, const char *radfn, - real ***distvals, - const gmx_output_env_t *oenv) +static void calc_order(const char* fn, + const int* index, + int* a, + rvec** order, + real*** slOrder, + real* slWidth, + int nslices, + gmx_bool bSliced, + gmx_bool bUnsat, + const t_topology* top, + int ePBC, + int ngrps, + int axis, + gmx_bool permolecule, + gmx_bool radial, + gmx_bool distcalc, + const char* radfn, + real*** distvals, + const gmx_output_env_t* oenv) { /* if permolecule = TRUE, order parameters will be calculed per molecule * and stored in slOrder with #slices = # molecules */ - rvec *x0, /* coordinates with pbc */ - *x1; /* coordinates without pbc */ - matrix box; /* box (3x3) */ - t_trxstatus *status; - rvec cossum, /* sum of vector angles for three axes */ - Sx, Sy, Sz, /* the three molecular axes */ - tmp1, tmp2, /* temp. rvecs for calculating dot products */ - frameorder; /* order parameters for one frame */ - real *slFrameorder; /* order parameter for one frame, per slice */ - real length, /* total distance between two atoms */ - t, /* time from trajectory */ - z_ave, z1, z2; /* average z, used to det. which slice atom is in */ - int natoms, /* nr. atoms in trj */ - nr_tails, /* nr tails, to check if index file is correct */ - size = 0, /* nr. of atoms in group. same as nr_tails */ - i, j, m, k, teller = 0, - slice; /* current slice number */ - real nr_frames = 0; - int *slCount; /* nr. of atoms in one slice */ - real sdbangle = 0; /* sum of these angles */ - gmx_bool use_unitvector = FALSE; /* use a specified unit vector instead of axis to specify unit normal*/ - rvec direction, com; - int comsize, distsize; - int *comidx = nullptr, *distidx = nullptr; - char *grpname = nullptr; - t_pbc pbc; - real arcdist, tmpdist; - gmx_rmpbc_t gpbc = nullptr; + rvec *x0, /* coordinates with pbc */ + *x1; /* coordinates without pbc */ + matrix box; /* box (3x3) */ + t_trxstatus* status; + rvec cossum, /* sum of vector angles for three axes */ + Sx, Sy, Sz, /* the three molecular axes */ + tmp1, tmp2, /* temp. rvecs for calculating dot products */ + frameorder; /* order parameters for one frame */ + real* slFrameorder; /* order parameter for one frame, per slice */ + real length, /* total distance between two atoms */ + t, /* time from trajectory */ + z_ave, z1, z2; /* average z, used to det. which slice atom is in */ + int natoms, /* nr. atoms in trj */ + nr_tails, /* nr tails, to check if index file is correct */ + size = 0, /* nr. of atoms in group. same as nr_tails */ + i, j, m, k, teller = 0, slice; /* current slice number */ + real nr_frames = 0; + int* slCount; /* nr. of atoms in one slice */ + real sdbangle = 0; /* sum of these angles */ + gmx_bool use_unitvector = FALSE; /* use a specified unit vector instead of axis to specify unit normal*/ + rvec direction, com; + int comsize, distsize; + int * comidx = nullptr, *distidx = nullptr; + char* grpname = nullptr; + t_pbc pbc; + real arcdist, tmpdist; + gmx_rmpbc_t gpbc = nullptr; /* PBC added for center-of-mass vector*/ /* Initiate the pbc structure */ @@ -427,8 +454,7 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, { nslices = nr_tails; bSliced = FALSE; /*force slices off */ - fprintf(stderr, "Calculating order parameters for each of %d molecules\n", - nslices); + fprintf(stderr, "Calculating order parameters for each of %d molecules\n", nslices); } if (radial) @@ -450,7 +476,8 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, if (use_unitvector && bSliced) { - fprintf(stderr, "Warning: slicing and specified unit vectors are not currently compatible\n"); + fprintf(stderr, + "Warning: slicing and specified unit vectors are not currently compatible\n"); } snew(slCount, nslices); @@ -473,9 +500,8 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, if (bSliced) { - *slWidth = box[axis][axis]/static_cast(nslices); - fprintf(stderr, "Box divided in %d slices. Initial width of slice: %f\n", - nslices, *slWidth); + *slWidth = box[axis][axis] / static_cast(nslices); + fprintf(stderr, "Box divided in %d slices. Initial width of slice: %f\n", nslices, *slWidth); } @@ -494,7 +520,7 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, { if (bSliced) { - *slWidth = box[axis][axis]/static_cast(nslices); + *slWidth = box[axis][axis] / static_cast(nslices); } teller++; @@ -513,12 +539,14 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, if (radial) { /*center-of-mass determination*/ - com[XX] = 0.0; com[YY] = 0.0; com[ZZ] = 0.0; + com[XX] = 0.0; + com[YY] = 0.0; + com[ZZ] = 0.0; for (j = 0; j < comsize; j++) { rvec_inc(com, x1[comidx[j]]); } - svmul(1.0/comsize, com, com); + svmul(1.0 / comsize, com, com); } rvec displacementFromReference; if (distcalc) @@ -528,7 +556,7 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, { rvec_inc(dref, x1[distidx[j]]); } - svmul(1.0/distsize, dref, dref); + svmul(1.0 / distsize, dref, dref); if (radial) { pbc_dx(&pbc, dref, com, displacementFromReference); @@ -540,11 +568,13 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, { clear_rvec(frameorder); - size = index[i+1] - index[i]; + size = index[i + 1] - index[i]; if (size != nr_tails) { - gmx_fatal(FARGS, "grp %d does not have same number of" - " elements as grp 1\n", i); + gmx_fatal(FARGS, + "grp %d does not have same number of" + " elements as grp 1\n", + i); } for (j = 0; j < size; j++) @@ -552,7 +582,7 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, if (radial) /*create unit vector*/ { - pbc_dx(&pbc, x1[a[index[i]+j]], com, direction); + pbc_dx(&pbc, x1[a[index[i] + j]], com, direction); unitv(direction, direction); /*DEBUG*/ /*if (j==0) @@ -565,10 +595,10 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, rvec dist; /* Using convention for unsaturated carbons */ /* first get Sz, the vector from Cn to Cn+1 */ - rvec_sub(x1[a[index[i+1]+j]], x1[a[index[i]+j]], dist); + rvec_sub(x1[a[index[i + 1] + j]], x1[a[index[i] + j]], dist); length = norm(dist); - check_length(length, a[index[i]+j], a[index[i+1]+j]); - svmul(1.0/length, dist, Sz); + check_length(length, a[index[i] + j], a[index[i + 1] + j]); + svmul(1.0 / length, dist, Sz); /* this is actually the cosine of the angle between the double bond and axis, because Sz is normalized and the two other components of @@ -586,24 +616,24 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, { rvec dist; /* get vector dist(Cn-1,Cn+1) for tail atoms */ - rvec_sub(x1[a[index[i+1]+j]], x1[a[index[i-1]+j]], dist); + rvec_sub(x1[a[index[i + 1] + j]], x1[a[index[i - 1] + j]], dist); length = norm(dist); /* determine distance between two atoms */ - check_length(length, a[index[i-1]+j], a[index[i+1]+j]); + check_length(length, a[index[i - 1] + j], a[index[i + 1] + j]); - svmul(1.0/length, dist, Sz); + svmul(1.0 / length, dist, Sz); /* Sz is now the molecular axis Sz, normalized and all that */ } /* now get Sx. Sx is normal to the plane of Cn-1, Cn and Cn+1 so we can use the outer product of Cn-1->Cn and Cn+1->Cn, I hope */ - rvec_sub(x1[a[index[i+1]+j]], x1[a[index[i]+j]], tmp1); - rvec_sub(x1[a[index[i-1]+j]], x1[a[index[i]+j]], tmp2); + rvec_sub(x1[a[index[i + 1] + j]], x1[a[index[i] + j]], tmp1); + rvec_sub(x1[a[index[i - 1] + j]], x1[a[index[i] + j]], tmp2); cprod(tmp1, tmp2, Sx); - svmul(1.0/norm(Sx), Sx, Sx); + svmul(1.0 / norm(Sx), Sx, Sx); /* now we can get Sy from the outer product of Sx and Sz */ cprod(Sz, Sx, Sy); - svmul(1.0/norm(Sy), Sy, Sy); + svmul(1.0 / norm(Sy), Sy, Sy); /* the square of cosine of the angle between dist and the axis. Using the innerproduct, but two of the three elements are zero @@ -636,48 +666,50 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, kept, until I find it necessary to know the others too */ - z1 = x1[a[index[i-1]+j]][axis]; - z2 = x1[a[index[i+1]+j]][axis]; + z1 = x1[a[index[i - 1] + j]][axis]; + z2 = x1[a[index[i + 1] + j]][axis]; z_ave = 0.5 * (z1 + z2); - slice = static_cast((static_cast(nslices)*z_ave)/box[axis][axis]); + slice = static_cast((static_cast(nslices) * z_ave) / box[axis][axis]); while (slice < 0) { slice += static_cast(nslices); } - slice = slice % nslices; + slice = slice % nslices; - slCount[slice]++; /* determine slice, increase count */ + slCount[slice]++; /* determine slice, increase count */ slFrameorder[slice] += 0.5 * (3 * cossum[axis] - 1); } else if (permolecule) { /* store per-molecule order parameter - * To just track single-axis order: (*slOrder)[j][i] += 0.5 * (3 * iprod(cossum,direction) - 1); - * following is for Scd order: */ - (*slOrder)[j][i] += -1* (1.0/3.0 * (3 * cossum[XX] - 1) + 1.0/3.0 * 0.5 * (3.0 * cossum[YY] - 1)); + * To just track single-axis order: (*slOrder)[j][i] += 0.5 * (3 * + * iprod(cossum,direction) - 1); following is for Scd order: */ + (*slOrder)[j][i] += -1 + * (1.0 / 3.0 * (3 * cossum[XX] - 1) + + 1.0 / 3.0 * 0.5 * (3.0 * cossum[YY] - 1)); } if (distcalc) { if (radial) { /* bin order parameter by arc distance from reference group*/ - arcdist = gmx_angle(displacementFromReference, direction); + arcdist = gmx_angle(displacementFromReference, direction); (*distvals)[j][i] += arcdist; } else if (i == 1) { /* Want minimum lateral distance to first group calculated */ - tmpdist = trace(box); /* should be max value */ + tmpdist = trace(box); /* should be max value */ for (k = 0; k < distsize; k++) { rvec displacement; - pbc_dx(&pbc, x1[distidx[k]], x1[a[index[i]+j]], displacement); + pbc_dx(&pbc, x1[distidx[k]], x1[a[index[i] + j]], displacement); /* at the moment, just remove displacement[axis] */ displacement[axis] = 0; tmpdist = std::min(tmpdist, norm2(displacement)); } - //fprintf(stderr, "Min dist %f; trace %f\n", tmpdist, trace(box)); + // fprintf(stderr, "Min dist %f; trace %f\n", tmpdist, trace(box)); (*distvals)[j][i] += std::sqrt(tmpdist); } } @@ -685,25 +717,25 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, for (m = 0; m < DIM; m++) { - (*order)[i][m] += (frameorder[m]/static_cast(size)); + (*order)[i][m] += (frameorder[m] / static_cast(size)); } if (!permolecule) - { /*Skip following if doing per-molecule*/ + { /*Skip following if doing per-molecule*/ for (k = 0; k < nslices; k++) { if (slCount[k]) /* if no elements, nothing has to be added */ { - (*slOrder)[k][i] += slFrameorder[k]/static_cast(slCount[k]); - slFrameorder[k] = 0; slCount[k] = 0; + (*slOrder)[k][i] += slFrameorder[k] / static_cast(slCount[k]); + slFrameorder[k] = 0; + slCount[k] = 0; } } } /* end loop i, over all groups in indexfile */ } nr_frames++; - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); /*********** done with status file **********/ fprintf(stderr, "\nRead trajectory. Printing parameters to file\n"); @@ -712,9 +744,9 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, /* average over frames */ for (i = 1; i < ngrps - 1; i++) { - svmul(1.0/nr_frames, (*order)[i], (*order)[i]); - fprintf(stderr, "Atom %d Tensor: x=%g , y=%g, z=%g\n", i, (*order)[i][XX], - (*order)[i][YY], (*order)[i][ZZ]); + svmul(1.0 / nr_frames, (*order)[i], (*order)[i]); + fprintf(stderr, "Atom %d Tensor: x=%g , y=%g, z=%g\n", i, (*order)[i][XX], (*order)[i][YY], + (*order)[i][ZZ]); if (bSliced || permolecule) { for (k = 0; k < nslices; k++) @@ -734,7 +766,7 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, if (bUnsat) { fprintf(stderr, "Average angle between double bond and normal: %f\n", - 180*sdbangle/(nr_frames * static_cast(size)*M_PI)); + 180 * sdbangle / (nr_frames * static_cast(size) * M_PI)); } sfree(x0); /* free memory used by coordinate arrays */ @@ -754,14 +786,23 @@ static void calc_order(const char *fn, const int *index, int *a, rvec **order, } -static void order_plot(rvec order[], real *slOrder[], const char *afile, const char *bfile, - const char *cfile, int ngrps, int nslices, real slWidth, gmx_bool bSzonly, - gmx_bool permolecule, real **distvals, const gmx_output_env_t *oenv) +static void order_plot(rvec order[], + real* slOrder[], + const char* afile, + const char* bfile, + const char* cfile, + int ngrps, + int nslices, + real slWidth, + gmx_bool bSzonly, + gmx_bool permolecule, + real** distvals, + const gmx_output_env_t* oenv) { - FILE *ord, *slOrd; /* xvgr files with order parameters */ - int atom, slice; /* atom corresponding to order para.*/ - char buf[256]; /* for xvgr title */ - real S; /* order parameter averaged over all atoms */ + FILE *ord, *slOrd; /* xvgr files with order parameters */ + int atom, slice; /* atom corresponding to order para.*/ + char buf[256]; /* for xvgr title */ + real S; /* order parameter averaged over all atoms */ if (permolecule) { @@ -771,8 +812,8 @@ static void order_plot(rvec order[], real *slOrder[], const char *afile, const c slOrd = xvgropen(bfile, buf, "Molecule", "S", oenv); for (atom = 1; atom < ngrps - 1; atom++) { - fprintf(ord, "%12d %12g\n", atom, -1.0 * (2.0/3.0 * order[atom][XX] + - 1.0/3.0 * order[atom][YY])); + fprintf(ord, "%12d %12g\n", atom, + -1.0 * (2.0 / 3.0 * order[atom][XX] + 1.0 / 3.0 * order[atom][YY])); } for (slice = 0; slice < nslices; slice++) @@ -788,7 +829,6 @@ static void order_plot(rvec order[], real *slOrder[], const char *afile, const c } fprintf(slOrd, "\n"); } - } else if (bSzonly) { @@ -811,9 +851,9 @@ static void order_plot(rvec order[], real *slOrder[], const char *afile, const c { S += slOrder[slice][atom]; } - fprintf(slOrd, "%12g %12g\n", static_cast(slice)*slWidth, S/static_cast(atom)); + fprintf(slOrd, "%12g %12g\n", static_cast(slice) * slWidth, + S / static_cast(atom)); } - } else { @@ -824,29 +864,37 @@ static void order_plot(rvec order[], real *slOrder[], const char *afile, const c for (atom = 1; atom < ngrps - 1; atom++) { - fprintf(ord, "%12d %12g %12g %12g\n", atom, order[atom][XX], - order[atom][YY], order[atom][ZZ]); - fprintf(slOrd, "%12d %12g\n", atom, -1.0 * (2.0/3.0 * order[atom][XX] + - 1.0/3.0 * order[atom][YY])); + fprintf(ord, "%12d %12g %12g %12g\n", atom, order[atom][XX], order[atom][YY], + order[atom][ZZ]); + fprintf(slOrd, "%12d %12g\n", atom, + -1.0 * (2.0 / 3.0 * order[atom][XX] + 1.0 / 3.0 * order[atom][YY])); } - } xvgrclose(ord); xvgrclose(slOrd); } -static void write_bfactors(t_filenm *fnm, int nfile, const int *index, const int *a, int nslices, int ngrps, real **order, const t_topology *top, real **distvals, gmx_output_env_t *oenv) +static void write_bfactors(t_filenm* fnm, + int nfile, + const int* index, + const int* a, + int nslices, + int ngrps, + real** order, + const t_topology* top, + real** distvals, + gmx_output_env_t* oenv) { /*function to write order parameters as B factors in PDB file using first frame of trajectory*/ - t_trxstatus *status; + t_trxstatus* status; t_trxframe fr, frout; t_atoms useatoms; int i, j, ctr, nout; - ngrps -= 2; /*we don't have an order parameter for the first or - last atom in each chain*/ - nout = nslices*ngrps; + ngrps -= 2; /*we don't have an order parameter for the first or + last atom in each chain*/ + nout = nslices * ngrps; read_first_frame(oenv, &status, ftp2fn(efTRX, nfile, fnm), &fr, TRX_NEED_X); close_trx(status); @@ -874,28 +922,30 @@ static void write_bfactors(t_filenm *fnm, int nfile, const int *index, const in for (i = 0; i < ngrps; i++, ctr++) { /*iterate along each chain*/ - useatoms.pdbinfo[ctr].bfac = order[j][i+1]; + useatoms.pdbinfo[ctr].bfac = order[j][i + 1]; if (distvals) { - useatoms.pdbinfo[ctr].occup = distvals[j][i+1]; + useatoms.pdbinfo[ctr].occup = distvals[j][i + 1]; } - copy_rvec(fr.x[a[index[i+1]+j]], frout.x[ctr]); - useatoms.atomname[ctr] = top->atoms.atomname[a[index[i+1]+j]]; - useatoms.atom[ctr] = top->atoms.atom[a[index[i+1]+j]]; - useatoms.nres = std::max(useatoms.nres, useatoms.atom[ctr].resind+1); - useatoms.resinfo[useatoms.atom[ctr].resind] = top->atoms.resinfo[useatoms.atom[ctr].resind]; /*copy resinfo*/ + copy_rvec(fr.x[a[index[i + 1] + j]], frout.x[ctr]); + useatoms.atomname[ctr] = top->atoms.atomname[a[index[i + 1] + j]]; + useatoms.atom[ctr] = top->atoms.atom[a[index[i + 1] + j]]; + useatoms.nres = std::max(useatoms.nres, useatoms.atom[ctr].resind + 1); + useatoms.resinfo[useatoms.atom[ctr].resind] = + top->atoms.resinfo[useatoms.atom[ctr].resind]; /*copy resinfo*/ } } - write_sto_conf(opt2fn("-ob", nfile, fnm), "Order parameters", &useatoms, frout.x, nullptr, frout.ePBC, frout.box); + write_sto_conf(opt2fn("-ob", nfile, fnm), "Order parameters", &useatoms, frout.x, nullptr, + frout.ePBC, frout.box); sfree(frout.x); done_atom(&useatoms); } -int gmx_order(int argc, char *argv[]) +int gmx_order(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the order parameter per atom for carbon tails. For atom i the", "vector i-1, i+1 is used together with an axis. ", "The index file should contain only the groups to be used for calculations,", @@ -919,63 +969,72 @@ int gmx_order(int argc, char *argv[]) static int nslices = 1; /* nr of slices defined */ static gmx_bool bSzonly = FALSE; /* True if only Sz is wanted */ static gmx_bool bUnsat = FALSE; /* True if carbons are unsat. */ - static const char *normal_axis[] = { nullptr, "z", "x", "y", nullptr }; + static const char* normal_axis[] = { nullptr, "z", "x", "y", nullptr }; static gmx_bool permolecule = FALSE; /*compute on a per-molecule basis */ static gmx_bool radial = FALSE; /*compute a radial membrane normal */ static gmx_bool distcalc = FALSE; /*calculate distance from a reference group */ t_pargs pa[] = { - { "-d", FALSE, etENUM, {normal_axis}, - "Direction of the normal on the membrane" }, - { "-sl", FALSE, etINT, {&nslices}, + { "-d", FALSE, etENUM, { normal_axis }, "Direction of the normal on the membrane" }, + { "-sl", + FALSE, + etINT, + { &nslices }, "Calculate order parameter as function of box length, dividing the box" " into this number of slices." }, - { "-szonly", FALSE, etBOOL, {&bSzonly}, + { "-szonly", + FALSE, + etBOOL, + { &bSzonly }, "Only give Sz element of order tensor. (axis can be specified with [TT]-d[tt])" }, - { "-unsat", FALSE, etBOOL, {&bUnsat}, + { "-unsat", + FALSE, + etBOOL, + { &bUnsat }, "Calculate order parameters for unsaturated carbons. Note that this can" "not be mixed with normal order parameters." }, - { "-permolecule", FALSE, etBOOL, {&permolecule}, + { "-permolecule", + FALSE, + etBOOL, + { &permolecule }, "Compute per-molecule Scd order parameters" }, - { "-radial", FALSE, etBOOL, {&radial}, - "Compute a radial membrane normal" }, - { "-calcdist", FALSE, etBOOL, {&distcalc}, - "Compute distance from a reference" }, + { "-radial", FALSE, etBOOL, { &radial }, "Compute a radial membrane normal" }, + { "-calcdist", FALSE, etBOOL, { &distcalc }, "Compute distance from a reference" }, }; - rvec *order; /* order par. for each atom */ - real **slOrder; /* same, per slice */ - real slWidth = 0.0; /* width of a slice */ - char **grpname; /* groupnames */ - int ngrps, /* nr. of groups */ - i, - axis = 0; /* normal axis */ - t_topology *top; /* topology */ - int ePBC; - int *index, /* indices for a */ - *a; /* atom numbers in each group */ - t_blocka *block; /* data from index file */ - t_filenm fnm[] = { /* files for g_order */ - { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ - { efNDX, "-n", nullptr, ffREAD }, /* index file */ - { efNDX, "-nr", nullptr, ffOPTRD }, /* index for radial axis calculation */ - { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ - { efXVG, "-o", "order", ffWRITE }, /* xvgr output file */ - { efXVG, "-od", "deuter", ffWRITE }, /* xvgr output file */ - { efPDB, "-ob", nullptr, ffOPTWR }, /* write Scd as B factors to PDB if permolecule */ - { efXVG, "-os", "sliced", ffWRITE }, /* xvgr output file */ - { efXVG, "-Sg", "sg-ang", ffOPTWR }, /* xvgr output file */ - { efXVG, "-Sk", "sk-dist", ffOPTWR }, /* xvgr output file */ + rvec* order; /* order par. for each atom */ + real** slOrder; /* same, per slice */ + real slWidth = 0.0; /* width of a slice */ + char** grpname; /* groupnames */ + int ngrps, /* nr. of groups */ + i, axis = 0; /* normal axis */ + t_topology* top; /* topology */ + int ePBC; + int * index, /* indices for a */ + *a; /* atom numbers in each group */ + t_blocka* block; /* data from index file */ + t_filenm fnm[] = { + /* files for g_order */ + { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ + { efNDX, "-n", nullptr, ffREAD }, /* index file */ + { efNDX, "-nr", nullptr, ffOPTRD }, /* index for radial axis calculation */ + { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ + { efXVG, "-o", "order", ffWRITE }, /* xvgr output file */ + { efXVG, "-od", "deuter", ffWRITE }, /* xvgr output file */ + { efPDB, "-ob", nullptr, ffOPTWR }, /* write Scd as B factors to PDB if permolecule */ + { efXVG, "-os", "sliced", ffWRITE }, /* xvgr output file */ + { efXVG, "-Sg", "sg-ang", ffOPTWR }, /* xvgr output file */ + { efXVG, "-Sk", "sk-dist", ffOPTWR }, /* xvgr output file */ { efXVG, "-Sgsl", "sg-ang-slice", ffOPTWR }, /* xvgr output file */ { efXVG, "-Sksl", "sk-dist-slice", ffOPTWR }, /* xvgr output file */ }; - gmx_bool bSliced = FALSE; /* True if box is sliced */ + gmx_bool bSliced = FALSE; /* True if box is sliced */ #define NFILE asize(fnm) - real **distvals = nullptr; - const char *sgfnm, *skfnm, *ndxfnm, *tpsfnm, *trxfnm; - gmx_output_env_t *oenv; + real** distvals = nullptr; + const char * sgfnm, *skfnm, *ndxfnm, *tpsfnm, *trxfnm; + gmx_output_env_t* oenv; - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -1010,15 +1069,9 @@ int gmx_order(int argc, char *argv[]) switch (axis) { - case 0: - fprintf(stderr, "Taking x axis as normal to the membrane\n"); - break; - case 1: - fprintf(stderr, "Taking y axis as normal to the membrane\n"); - break; - case 2: - fprintf(stderr, "Taking z axis as normal to the membrane\n"); - break; + case 0: fprintf(stderr, "Taking x axis as normal to the membrane\n"); break; + case 1: fprintf(stderr, "Taking y axis as normal to the membrane\n"); break; + case 2: fprintf(stderr, "Taking z axis as normal to the membrane\n"); break; } /* tetraheder order parameter */ @@ -1028,8 +1081,7 @@ int gmx_order(int argc, char *argv[]) sgfnm = opt2fn("-Sg", NFILE, fnm); skfnm = opt2fn("-Sk", NFILE, fnm); calc_tetra_order_parm(ndxfnm, tpsfnm, trxfnm, sgfnm, skfnm, nslices, axis, - opt2fn("-Sgsl", NFILE, fnm), opt2fn("-Sksl", NFILE, fnm), - oenv); + opt2fn("-Sgsl", NFILE, fnm), opt2fn("-Sksl", NFILE, fnm), oenv); /* view xvgr files */ do_view(oenv, opt2fn("-Sg", NFILE, fnm), nullptr); do_view(oenv, opt2fn("-Sk", NFILE, fnm), nullptr); @@ -1061,8 +1113,8 @@ int gmx_order(int argc, char *argv[]) top = read_top(ftp2fn(efTPR, NFILE, fnm), &ePBC); /* read topology file */ block = init_index(ftp2fn(efNDX, NFILE, fnm), &grpname); - index = block->index; /* get indices from t_block block */ - a = block->a; /* see block.h */ + index = block->index; /* get indices from t_block block */ + a = block->a; /* see block.h */ ngrps = block->nr; if (permolecule) @@ -1083,18 +1135,18 @@ int gmx_order(int argc, char *argv[]) /* show atomtypes, to check if index file is correct */ print_types(index, a, ngrps, grpname, top); - calc_order(ftp2fn(efTRX, NFILE, fnm), index, a, &order, - &slOrder, &slWidth, nslices, bSliced, bUnsat, - top, ePBC, ngrps, axis, permolecule, radial, distcalc, opt2fn_null("-nr", NFILE, fnm), &distvals, oenv); + calc_order(ftp2fn(efTRX, NFILE, fnm), index, a, &order, &slOrder, &slWidth, nslices, + bSliced, bUnsat, top, ePBC, ngrps, axis, permolecule, radial, distcalc, + opt2fn_null("-nr", NFILE, fnm), &distvals, oenv); if (radial) { ngrps--; /*don't print the last group--was used for center-of-mass determination*/ - } order_plot(order, slOrder, opt2fn("-o", NFILE, fnm), opt2fn("-os", NFILE, fnm), - opt2fn("-od", NFILE, fnm), ngrps, nslices, slWidth, bSzonly, permolecule, distvals, oenv); + opt2fn("-od", NFILE, fnm), ngrps, nslices, slWidth, bSzonly, permolecule, + distvals, oenv); if (opt2bSet("-ob", NFILE, fnm)) { diff --git a/src/gromacs/gmxana/gmx_polystat.cpp b/src/gromacs/gmxana/gmx_polystat.cpp index 2c5f05bec3..00108b5468 100644 --- a/src/gromacs/gmxana/gmx_polystat.cpp +++ b/src/gromacs/gmxana/gmx_polystat.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,7 +57,7 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void gyro_eigen(double **gyr, double *eig, double **eigv, int *ord) +static void gyro_eigen(double** gyr, double* eig, double** eigv, int* ord) { int nrot, d; @@ -86,7 +86,7 @@ static void gyro_eigen(double **gyr, double *eig, double **eigv, int *ord) } /* Calculate mean square internal distances (Auhl et al., JCP 119, 12718) */ -static void calc_int_dist(double *intd, rvec *x, int i0, int i1) +static void calc_int_dist(double* intd, rvec* x, int i0, int i1) { int ii; const int ml = i1 - i0 + 1; /* Number of beads in molecule. */ @@ -98,16 +98,16 @@ static void calc_int_dist(double *intd, rvec *x, int i0, int i1) d = 0.; for (ii = i0; ii <= i1 - bd; ii++) { - d += distance2(x[ii], x[ii+bd]); + d += distance2(x[ii], x[ii + bd]); } - d /= ml - bd; + d /= ml - bd; intd[bd - 1] += d; } } -int gmx_polystat(int argc, char *argv[]) +int gmx_polystat(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] plots static properties of polymers as a function of time", "and prints the average.[PAR]", "By default it determines the average end-to-end distance and radii", @@ -132,80 +132,67 @@ int gmx_polystat(int argc, char *argv[]) "the average cos reaches a value of 1/e. This point is determined", "by a linear interpolation of [LOG][log]." }; - static gmx_bool bMW = TRUE, bPC = FALSE; + static gmx_bool bMW = TRUE, bPC = FALSE; t_pargs pa[] = { - { "-mw", FALSE, etBOOL, {&bMW}, - "Use the mass weighting for radii of gyration" }, - { "-pc", FALSE, etBOOL, {&bPC}, - "Plot average eigenvalues" } + { "-mw", FALSE, etBOOL, { &bMW }, "Use the mass weighting for radii of gyration" }, + { "-pc", FALSE, etBOOL, { &bPC }, "Plot average eigenvalues" } }; - t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-o", "polystat", ffWRITE }, - { efXVG, "-v", "polyvec", ffOPTWR }, - { efXVG, "-p", "persist", ffOPTWR }, - { efXVG, "-i", "intdist", ffOPTWR } - }; + t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-o", "polystat", ffWRITE }, + { efXVG, "-v", "polyvec", ffOPTWR }, { efXVG, "-p", "persist", ffOPTWR }, + { efXVG, "-i", "intdist", ffOPTWR } }; #define NFILE asize(fnm) - t_topology *top; - gmx_output_env_t *oenv; + t_topology* top; + gmx_output_env_t* oenv; int ePBC; int isize, *index, nmol, *molind, mol, nat_min = 0, nat_max = 0; - char *grpname; - t_trxstatus *status; + char* grpname; + t_trxstatus* status; real t; - rvec *x, *bond = nullptr; + rvec * x, *bond = nullptr; matrix box; - int natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = {0}; - dvec cm, sum_eig = {0, 0, 0}; - double **gyr, **gyr_all, eig[DIM], **eigv; + int natoms, i, j, frame, ind0, ind1, a, d, d2, ord[DIM] = { 0 }; + dvec cm, sum_eig = { 0, 0, 0 }; + double ** gyr, **gyr_all, eig[DIM], **eigv; double sum_eed2, sum_eed2_tot, sum_gyro, sum_gyro_tot, sum_pers_tot; - int *ninp = nullptr; - double *sum_inp = nullptr, pers; - double *intd, ymax, ymin; + int* ninp = nullptr; + double * sum_inp = nullptr, pers; + double * intd, ymax, ymin; double mmol, m; char title[STRLEN]; - FILE *out, *outv, *outp, *outi; - const char *leg[8] = { - "end to end", "", - " eig1", " eig2", " eig3", - "", "", "" - }; - char **legp, buf[STRLEN]; + FILE * out, *outv, *outp, *outi; + const char* leg[8] = { "end to end", "", " eig1", + " eig2", " eig3", "", + "", "" }; + char ** legp, buf[STRLEN]; gmx_rmpbc_t gpbc = nullptr; - if (!parse_common_args(&argc, argv, - PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } snew(top, 1); - ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), - nullptr, box, &natoms, nullptr, nullptr, top); + ePBC = read_tpx_top(ftp2fn(efTPR, NFILE, fnm), nullptr, box, &natoms, nullptr, nullptr, top); fprintf(stderr, "Select a group of polymer mainchain atoms:\n"); - get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &isize, &index, &grpname); + get_index(&top->atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); - snew(molind, top->mols.nr+1); + snew(molind, top->mols.nr + 1); nmol = 0; mol = -1; for (i = 0; i < isize; i++) { - if (i == 0 || index[i] >= top->mols.index[mol+1]) + if (i == 0 || index[i] >= top->mols.index[mol + 1]) { molind[nmol++] = i; do { mol++; - } - while (index[i] >= top->mols.index[mol+1]); + } while (index[i] >= top->mols.index[mol + 1]); } } molind[nmol] = i; @@ -213,32 +200,30 @@ int gmx_polystat(int argc, char *argv[]) nat_max = 0; for (mol = 0; mol < nmol; mol++) { - nat_min = std::min(nat_min, molind[mol+1]-molind[mol]); - nat_max = std::max(nat_max, molind[mol+1]-molind[mol]); + nat_min = std::min(nat_min, molind[mol + 1] - molind[mol]); + nat_max = std::max(nat_max, molind[mol + 1] - molind[mol]); } fprintf(stderr, "Group %s consists of %d molecules\n", grpname, nmol); - fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n", - nat_min, nat_max); + fprintf(stderr, "Group size per molecule, min: %d atoms, max %d atoms\n", nat_min, nat_max); sprintf(title, "Size of %d polymers", nmol); - out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)", - oenv); + out = xvgropen(opt2fn("-o", NFILE, fnm), title, output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); xvgr_legend(out, bPC ? 8 : 5, leg, oenv); if (opt2bSet("-v", NFILE, fnm)) { outv = xvgropen(opt2fn("-v", NFILE, fnm), "Principal components", output_env_get_xvgr_tlabel(oenv), "(nm)", oenv); - snew(legp, DIM*DIM); + snew(legp, DIM * DIM); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { - sprintf(buf, "eig%d %c", d+1, 'x'+d2); - legp[d*DIM+d2] = gmx_strdup(buf); + sprintf(buf, "eig%d %c", d + 1, 'x' + d2); + legp[d * DIM + d2] = gmx_strdup(buf); } } - xvgr_legend(outv, DIM*DIM, legp, oenv); + xvgr_legend(outv, DIM * DIM, legp, oenv); } else { @@ -249,9 +234,9 @@ int gmx_polystat(int argc, char *argv[]) { outp = xvgropen(opt2fn("-p", NFILE, fnm), "Persistence length", output_env_get_xvgr_tlabel(oenv), "bonds", oenv); - snew(bond, nat_max-1); - snew(sum_inp, nat_min/2); - snew(ninp, nat_min/2); + snew(bond, nat_max - 1); + snew(sum_inp, nat_min / 2); + snew(ninp, nat_min / 2); } else { @@ -260,9 +245,9 @@ int gmx_polystat(int argc, char *argv[]) if (opt2bSet("-i", NFILE, fnm)) { - outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances", - "n", "/n (nm\\S2\\N)", oenv); - i = index[molind[1]-1] - index[molind[0]]; /* Length of polymer -1 */ + outi = xvgropen(opt2fn("-i", NFILE, fnm), "Internal distances", "n", + "/n (nm\\S2\\N)", oenv); + i = index[molind[1] - 1] - index[molind[0]]; /* Length of polymer -1 */ snew(intd, i); } else @@ -307,7 +292,7 @@ int gmx_polystat(int argc, char *argv[]) if (outp) { - for (i = 0; i < nat_min/2; i++) + for (i = 0; i < nat_min / 2; i++) { sum_inp[i] = 0; ninp[i] = 0; @@ -317,15 +302,15 @@ int gmx_polystat(int argc, char *argv[]) for (mol = 0; mol < nmol; mol++) { ind0 = molind[mol]; - ind1 = molind[mol+1]; + ind1 = molind[mol + 1]; /* Determine end to end distance */ - sum_eed2 += distance2(x[index[ind0]], x[index[ind1-1]]); + sum_eed2 += distance2(x[index[ind0]], x[index[ind1 - 1]]); /* Determine internal distances */ if (outi) { - calc_int_dist(intd, x, index[ind0], index[ind1-1]); + calc_int_dist(intd, x, index[ind0], index[ind1 - 1]); } /* Determine the radius of gyration */ @@ -350,19 +335,19 @@ int gmx_polystat(int argc, char *argv[]) mmol += m; for (d = 0; d < DIM; d++) { - cm[d] += m*x[a][d]; + cm[d] += m * x[a][d]; for (d2 = 0; d2 < DIM; d2++) { - gyr[d][d2] += m*x[a][d]*x[a][d2]; + gyr[d][d2] += m * x[a][d] * x[a][d2]; } } } - dsvmul(1/mmol, cm, cm); + dsvmul(1 / mmol, cm, cm); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) { - gyr[d][d2] = gyr[d][d2]/mmol - cm[d]*cm[d2]; + gyr[d][d2] = gyr[d][d2] / mmol - cm[d] * cm[d2]; gyr_all[d][d2] += gyr[d][d2]; } } @@ -376,16 +361,16 @@ int gmx_polystat(int argc, char *argv[]) } if (outp) { - for (i = ind0; i < ind1-1; i++) + for (i = ind0; i < ind1 - 1; i++) { - rvec_sub(x[index[i+1]], x[index[i]], bond[i-ind0]); - unitv(bond[i-ind0], bond[i-ind0]); + rvec_sub(x[index[i + 1]], x[index[i]], bond[i - ind0]); + unitv(bond[i - ind0], bond[i - ind0]); } - for (i = ind0; i < ind1-1; i++) + for (i = ind0; i < ind1 - 1; i++) { - for (j = 0; (i+j < ind1-1 && j < nat_min/2); j += 2) + for (j = 0; (i + j < ind1 - 1 && j < nat_min / 2); j += 2) { - sum_inp[j] += iprod(bond[i-ind0], bond[i-ind0+j]); + sum_inp[j] += iprod(bond[i - ind0], bond[i - ind0 + j]); ninp[j]++; } } @@ -405,22 +390,21 @@ int gmx_polystat(int argc, char *argv[]) gyro_eigen(gyr_all, eig, eigv, ord); - fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f", - t*output_env_get_time_factor(oenv), - std::sqrt(sum_eed2), sqrt(sum_gyro), - std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), std::sqrt(eig[ord[2]])); + fprintf(out, "%10.3f %8.4f %8.4f %8.4f %8.4f %8.4f", t * output_env_get_time_factor(oenv), + std::sqrt(sum_eed2), sqrt(sum_gyro), std::sqrt(eig[ord[0]]), std::sqrt(eig[ord[1]]), + std::sqrt(eig[ord[2]])); if (bPC) { for (d = 0; d < DIM; d++) { - fprintf(out, " %8.4f", std::sqrt(sum_eig[d]/nmol)); + fprintf(out, " %8.4f", std::sqrt(sum_eig[d] / nmol)); } } fprintf(out, "\n"); if (outv) { - fprintf(outv, "%10.3f", t*output_env_get_time_factor(oenv)); + fprintf(outv, "%10.3f", t * output_env_get_time_factor(oenv)); for (d = 0; d < DIM; d++) { for (d2 = 0; d2 < DIM; d2++) @@ -437,7 +421,7 @@ int gmx_polystat(int argc, char *argv[]) if (outp) { i = -1; - for (j = 0; j < nat_min/2; j += 2) + for (j = 0; j < nat_min / 2; j += 2) { sum_inp[j] /= ninp[j]; if (i == -1 && sum_inp[j] <= std::exp(-1.0)) @@ -453,15 +437,15 @@ int gmx_polystat(int argc, char *argv[]) { /* Do linear interpolation on a log scale */ pers = i - 2.0 - + 2.0*(std::log(sum_inp[i-2]) + 1.0)/(std::log(sum_inp[i-2]) - std::log(sum_inp[i])); + + 2.0 * (std::log(sum_inp[i - 2]) + 1.0) + / (std::log(sum_inp[i - 2]) - std::log(sum_inp[i])); } - fprintf(outp, "%10.3f %8.4f\n", t*output_env_get_time_factor(oenv), pers); + fprintf(outp, "%10.3f %8.4f\n", t * output_env_get_time_factor(oenv), pers); sum_pers_tot += pers; } frame++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); @@ -480,14 +464,11 @@ int gmx_polystat(int argc, char *argv[]) sum_eed2_tot /= frame; sum_gyro_tot /= frame; sum_pers_tot /= frame; - fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n", - std::sqrt(sum_eed2_tot)); - fprintf(stdout, "\nAverage radius of gyration: %.3f (nm)\n", - std::sqrt(sum_gyro_tot)); + fprintf(stdout, "\nAverage end to end distance: %.3f (nm)\n", std::sqrt(sum_eed2_tot)); + fprintf(stdout, "\nAverage radius of gyration: %.3f (nm)\n", std::sqrt(sum_gyro_tot)); if (opt2bSet("-p", NFILE, fnm)) { - fprintf(stdout, "\nAverage persistence length: %.2f bonds\n", - sum_pers_tot); + fprintf(stdout, "\nAverage persistence length: %.2f bonds\n", sum_pers_tot); } /* Handle printing of internal distances. */ @@ -499,7 +480,7 @@ int gmx_polystat(int argc, char *argv[]) } ymax = -1; ymin = 1e300; - j = index[molind[1]-1] - index[molind[0]]; /* Polymer length -1. */ + j = index[molind[1] - 1] - index[molind[0]]; /* Polymer length -1. */ for (i = 0; i < j; i++) { intd[i] /= (i + 1) * frame * nmol; @@ -515,7 +496,7 @@ int gmx_polystat(int argc, char *argv[]) xvgr_world(outi, 1, ymin, j, ymax, oenv); for (i = 0; i < j; i++) { - fprintf(outi, "%d %8.4f\n", i+1, intd[i]); + fprintf(outi, "%d %8.4f\n", i + 1, intd[i]); } xvgrclose(outi); } diff --git a/src/gromacs/gmxana/gmx_potential.cpp b/src/gromacs/gmxana/gmx_potential.cpp index fef1987053..459f99ca5d 100644 --- a/src/gromacs/gmxana/gmx_potential.cpp +++ b/src/gromacs/gmxana/gmx_potential.cpp @@ -75,67 +75,77 @@ static int ce = 0, cb = 0; /* this routine integrates the array data and returns the resulting array */ /* routine uses simple trapezoid rule */ -static void p_integrate(double *result, const double data[], int ndata, double slWidth) +static void p_integrate(double* result, const double data[], int ndata, double slWidth) { int i, slice; double sum; if (ndata <= 2) { - fprintf(stderr, "Warning: nr of slices very small. This will result" + fprintf(stderr, + "Warning: nr of slices very small. This will result" "in nonsense.\n"); } - fprintf(stderr, "Integrating from slice %d to slice %d\n", cb, ndata-ce); + fprintf(stderr, "Integrating from slice %d to slice %d\n", cb, ndata - ce); - for (slice = cb; slice < (ndata-ce); slice++) + for (slice = cb; slice < (ndata - ce); slice++) { sum = 0; for (i = cb; i < slice; i++) { - sum += slWidth * (data[i] + 0.5 * (data[i+1] - data[i])); + sum += slWidth * (data[i] + 0.5 * (data[i + 1] - data[i])); } result[slice] = sum; } } -static void calc_potential(const char *fn, int **index, int gnx[], - double ***slPotential, double ***slCharge, - double ***slField, int *nslices, - const t_topology *top, int ePBC, - int axis, int nr_grps, double *slWidth, - double fudge_z, gmx_bool bSpherical, gmx_bool bCorrect, - const gmx_output_env_t *oenv) +static void calc_potential(const char* fn, + int** index, + int gnx[], + double*** slPotential, + double*** slCharge, + double*** slField, + int* nslices, + const t_topology* top, + int ePBC, + int axis, + int nr_grps, + double* slWidth, + double fudge_z, + gmx_bool bSpherical, + gmx_bool bCorrect, + const gmx_output_env_t* oenv) { - rvec *x0; /* coordinates without pbc */ + rvec* x0; /* coordinates without pbc */ matrix box; /* box (3x3) */ int natoms; /* nr. atoms in trj */ - t_trxstatus *status; - int i, n, /* loop indices */ - teller = 0, - ax1 = 0, ax2 = 0, - nr_frames = 0, /* number of frames */ - slice; /* current slice */ - double slVolume; /* volume of slice for spherical averaging */ - double qsum, nn; - real t; - double z; - rvec xcm; - gmx_rmpbc_t gpbc = nullptr; + t_trxstatus* status; + int i, n, /* loop indices */ + teller = 0, ax1 = 0, ax2 = 0, nr_frames = 0, /* number of frames */ + slice; /* current slice */ + double slVolume; /* volume of slice for spherical averaging */ + double qsum, nn; + real t; + double z; + rvec xcm; + gmx_rmpbc_t gpbc = nullptr; switch (axis) { case 0: - ax1 = 1; ax2 = 2; + ax1 = 1; + ax2 = 2; break; case 1: - ax1 = 0; ax2 = 2; + ax1 = 0; + ax2 = 2; break; case 2: - ax1 = 0; ax2 = 1; + ax1 = 0; + ax2 = 1; break; - default: - gmx_fatal(FARGS, "Invalid axes. Terminating\n"); + default: gmx_fatal(FARGS, "Invalid axes. Terminating\n"); } if ((natoms = read_first_x(oenv, &status, fn, &t, &x0, box)) == 0) @@ -146,7 +156,6 @@ static void calc_potential(const char *fn, int **index, int gnx[], if (!*nslices) { *nslices = static_cast(box[axis][axis] * 10.0); /* default value */ - } fprintf(stderr, "\nDividing the box in %d slices\n", *nslices); @@ -167,7 +176,7 @@ static void calc_potential(const char *fn, int **index, int gnx[], /*********** Start processing trajectory ***********/ do { - *slWidth = box[axis][axis]/static_cast((*nslices)); + *slWidth = box[axis][axis] / static_cast((*nslices)); teller++; gmx_rmpbc(gpbc, natoms, box, x0); @@ -181,8 +190,10 @@ static void calc_potential(const char *fn, int **index, int gnx[], * group in the trajectory file */ if (gnx[n] > natoms) { - gmx_fatal(FARGS, "You selected a group with %d atoms, but only %d atoms\n" - "were found in the trajectory.\n", gnx[n], natoms); + gmx_fatal(FARGS, + "You selected a group with %d atoms, but only %d atoms\n" + "were found in the trajectory.\n", + gnx[n], natoms); } for (i = 0; i < gnx[n]; i++) /* loop over all atoms in index file */ { @@ -190,7 +201,7 @@ static void calc_potential(const char *fn, int **index, int gnx[], { rvec_add(x0[index[n][i]], xcm, x0[index[n][i]]); /* only distance from origin counts, not sign */ - slice = static_cast(norm(x0[index[n][i]])/(*slWidth)); + slice = static_cast(norm(x0[index[n][i]]) / (*slWidth)); /* this is a nice check for spherical groups but not for all water in a cubic box since a lot will fall outside @@ -215,14 +226,13 @@ static void calc_potential(const char *fn, int **index, int gnx[], z -= box[axis][axis]; } /* determine which slice atom is in */ - slice = static_cast((z / (*slWidth))); + slice = static_cast((z / (*slWidth))); (*slCharge)[n][slice] += top->atoms.atom[index[n][i]].q; } } } nr_frames++; - } - while (read_next_x(oenv, status, &t, x0, box)); + } while (read_next_x(oenv, status, &t, x0, box)); gmx_rmpbc_done(gpbc); @@ -236,13 +246,14 @@ static void calc_potential(const char *fn, int **index, int gnx[], if (bSpherical) { - fprintf(stderr, "\n\nRead %d frames from trajectory. Calculating potential" - "in spherical coordinates\n", nr_frames); + fprintf(stderr, + "\n\nRead %d frames from trajectory. Calculating potential" + "in spherical coordinates\n", + nr_frames); } else { - fprintf(stderr, "\n\nRead %d frames from trajectory. Calculating potential\n", - nr_frames); + fprintf(stderr, "\n\nRead %d frames from trajectory. Calculating potential\n", nr_frames); } for (n = 0; n < nr_grps; n++) @@ -254,7 +265,7 @@ static void calc_potential(const char *fn, int **index, int gnx[], /* charge per volume is now the summed charge, divided by the nr of frames and by the volume of the slice it's in, 4pi r^2 dr */ - slVolume = 4*M_PI * gmx::square(i) * gmx::square(*slWidth) * *slWidth; + slVolume = 4 * M_PI * gmx::square(i) * gmx::square(*slWidth) * *slWidth; if (slVolume == 0) { (*slCharge)[n][i] = 0; @@ -267,8 +278,9 @@ static void calc_potential(const char *fn, int **index, int gnx[], else { /* get charge per volume */ - (*slCharge)[n][i] = (*slCharge)[n][i] * (*nslices) / - (static_cast(nr_frames) * box[axis][axis] * box[ax1][ax1] * box[ax2][ax2]); + (*slCharge)[n][i] = (*slCharge)[n][i] * (*nslices) + / (static_cast(nr_frames) * box[axis][axis] + * box[ax1][ax1] * box[ax2][ax2]); } } /* Now we have charge densities */ @@ -343,10 +355,8 @@ static void calc_potential(const char *fn, int **index, int gnx[], { if (bSpherical) { - (*slPotential)[n][i] = ELC * (*slPotential)[n][i] * -1.0E9 / - (EPS0 * i * (*slWidth)); - (*slField)[n][i] = ELC * (*slField)[n][i] * 1E18 / - (EPS0 * i * (*slWidth)); + (*slPotential)[n][i] = ELC * (*slPotential)[n][i] * -1.0E9 / (EPS0 * i * (*slWidth)); + (*slField)[n][i] = ELC * (*slField)[n][i] * 1E18 / (EPS0 * i * (*slWidth)); } else { @@ -359,16 +369,23 @@ static void calc_potential(const char *fn, int **index, int gnx[], sfree(x0); /* free memory used by coordinate array */ } -static void plot_potential(double *potential[], double *charge[], double *field[], - const char *afile, const char *bfile, const char *cfile, - int nslices, int nr_grps, const char *const grpname[], double slWidth, - const gmx_output_env_t *oenv) +static void plot_potential(double* potential[], + double* charge[], + double* field[], + const char* afile, + const char* bfile, + const char* cfile, + int nslices, + int nr_grps, + const char* const grpname[], + double slWidth, + const gmx_output_env_t* oenv) { - FILE *pot, /* xvgr file with potential */ - *cha, /* xvgr file with charges */ - *fie; /* xvgr files with fields */ - char buf[256]; /* for xvgr title */ - int slice, n; + FILE *pot, /* xvgr file with potential */ + *cha, /* xvgr file with charges */ + *fie; /* xvgr files with fields */ + char buf[256]; /* for xvgr title */ + int slice, n; sprintf(buf, "Electrostatic Potential"); pot = xvgropen(afile, buf, "Box (nm)", "Potential (V)", oenv); @@ -390,7 +407,7 @@ static void plot_potential(double *potential[], double *charge[], double *field[ for (n = 0; n < nr_grps; n++) { fprintf(pot, " %20.16g", potential[n][slice]); - fprintf(fie, " %20.16g", field[n][slice]/1e9); /* convert to V/nm */ + fprintf(fie, " %20.16g", field[n][slice] / 1e9); /* convert to V/nm */ fprintf(cha, " %20.16g", charge[n][slice]); } fprintf(pot, "\n"); @@ -403,9 +420,9 @@ static void plot_potential(double *potential[], double *charge[], double *field[ xvgrclose(fie); } -int gmx_potential(int argc, char *argv[]) +int gmx_potential(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the electrostatical potential across the box. The potential is", "calculated by first summing the charges per slice and then integrating", "twice of this charge distribution. Periodic boundaries are not taken", @@ -415,50 +432,65 @@ int gmx_potential(int argc, char *argv[]) "spherical slices and twice integrating them. epsilon_r is taken as 1,", "but 2 is more appropriate in many cases." }; - gmx_output_env_t *oenv; - static int axis = 2; /* normal to memb. default z */ - static const char *axtitle = "Z"; - static int nslices = 10; /* nr of slices defined */ + gmx_output_env_t* oenv; + static int axis = 2; /* normal to memb. default z */ + static const char* axtitle = "Z"; + static int nslices = 10; /* nr of slices defined */ static int ngrps = 1; - static gmx_bool bSpherical = FALSE; /* default is bilayer types */ - static real fudge_z = 0; /* translate coordinates */ + static gmx_bool bSpherical = FALSE; /* default is bilayer types */ + static real fudge_z = 0; /* translate coordinates */ static gmx_bool bCorrect = false; - t_pargs pa [] = { - { "-d", FALSE, etSTR, {&axtitle}, + t_pargs pa[] = { + { "-d", + FALSE, + etSTR, + { &axtitle }, "Take the normal on the membrane in direction X, Y or Z." }, - { "-sl", FALSE, etINT, {&nslices}, + { "-sl", + FALSE, + etINT, + { &nslices }, "Calculate potential as function of boxlength, dividing the box" " in this number of slices." }, - { "-cb", FALSE, etINT, {&cb}, + { "-cb", + FALSE, + etINT, + { &cb }, "Discard this number of first slices of box for integration" }, - { "-ce", FALSE, etINT, {&ce}, + { "-ce", + FALSE, + etINT, + { &ce }, "Discard this number of last slices of box for integration" }, - { "-tz", FALSE, etREAL, {&fudge_z}, + { "-tz", + FALSE, + etREAL, + { &fudge_z }, "Translate all coordinates by this distance in the direction of the box" }, - { "-spherical", FALSE, etBOOL, {&bSpherical}, - "Calculate in spherical coordinates" }, - { "-ng", FALSE, etINT, {&ngrps}, - "Number of groups to consider" }, - { "-correct", FALSE, etBOOL, {&bCorrect}, + { "-spherical", FALSE, etBOOL, { &bSpherical }, "Calculate in spherical coordinates" }, + { "-ng", FALSE, etINT, { &ngrps }, "Number of groups to consider" }, + { "-correct", + FALSE, + etBOOL, + { &bCorrect }, "Assume net zero charge of groups to improve accuracy" } }; - const char *bugs[] = { - "Discarding slices for integration should not be necessary." - }; - - double **potential, /* potential per slice */ - **charge, /* total charge per slice */ - **field, /* field per slice */ - slWidth; /* width of one slice */ - char **grpname; /* groupnames */ - int *ngx; /* sizes of groups */ - t_topology *top; /* topology */ + const char* bugs[] = { "Discarding slices for integration should not be necessary." }; + + double **potential, /* potential per slice */ + **charge, /* total charge per slice */ + **field, /* field per slice */ + slWidth; /* width of one slice */ + char** grpname; /* groupnames */ + int* ngx; /* sizes of groups */ + t_topology* top; /* topology */ int ePBC; - int **index; /* indices for all groups */ - t_filenm fnm[] = { /* files for g_order */ - { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ - { efNDX, nullptr, nullptr, ffREAD }, /* index file */ - { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ + int** index; /* indices for all groups */ + t_filenm fnm[] = { + /* files for g_order */ + { efTRX, "-f", nullptr, ffREAD }, /* trajectory file */ + { efNDX, nullptr, nullptr, ffREAD }, /* index file */ + { efTPR, nullptr, nullptr, ffREAD }, /* topology file */ { efXVG, "-o", "potential", ffWRITE }, /* xvgr output file */ { efXVG, "-oc", "charge", ffWRITE }, /* xvgr output file */ { efXVG, "-of", "field", ffWRITE }, /* xvgr output file */ @@ -466,9 +498,8 @@ int gmx_potential(int argc, char *argv[]) #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } @@ -485,14 +516,11 @@ int gmx_potential(int argc, char *argv[]) rd_index(ftp2fn(efNDX, NFILE, fnm), ngrps, ngx, index, grpname); - calc_potential(ftp2fn(efTRX, NFILE, fnm), index, ngx, - &potential, &charge, &field, - &nslices, top, ePBC, axis, ngrps, &slWidth, fudge_z, - bSpherical, bCorrect, oenv); + calc_potential(ftp2fn(efTRX, NFILE, fnm), index, ngx, &potential, &charge, &field, &nslices, + top, ePBC, axis, ngrps, &slWidth, fudge_z, bSpherical, bCorrect, oenv); - plot_potential(potential, charge, field, opt2fn("-o", NFILE, fnm), - opt2fn("-oc", NFILE, fnm), opt2fn("-of", NFILE, fnm), - nslices, ngrps, grpname, slWidth, oenv); + plot_potential(potential, charge, field, opt2fn("-o", NFILE, fnm), opt2fn("-oc", NFILE, fnm), + opt2fn("-of", NFILE, fnm), nslices, ngrps, grpname, slWidth, oenv); do_view(oenv, opt2fn("-o", NFILE, fnm), nullptr); /* view xvgr file */ do_view(oenv, opt2fn("-oc", NFILE, fnm), nullptr); /* view xvgr file */ diff --git a/src/gromacs/gmxana/gmx_principal.cpp b/src/gromacs/gmxana/gmx_principal.cpp index 65bfa3a202..53286210ff 100644 --- a/src/gromacs/gmxana/gmx_principal.cpp +++ b/src/gromacs/gmxana/gmx_principal.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,23 +56,17 @@ #include "gromacs/utility/smalloc.h" -static void -calc_principal_axes(const t_topology *top, - rvec *x, - int *index, - int n, - matrix axes, - rvec inertia) +static void calc_principal_axes(const t_topology* top, rvec* x, int* index, int n, matrix axes, rvec inertia) { - rvec xcm; + rvec xcm; sub_xcm(x, n, index, top->atoms.atom, xcm, FALSE); principal_comp(n, index, top->atoms.atom, x, axes, inertia); } -int gmx_principal(int argc, char *argv[]) +int gmx_principal(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates the three principal axes of inertia for a group", "of atoms. NOTE: Old versions of GROMACS wrote the output data in a", "strange transposed way. As of GROMACS 5.0, the output file paxis1.dat", @@ -80,45 +74,37 @@ int gmx_principal(int argc, char *argv[]) "each frame, and similarly for the middle and minor axes in paxis2.dat", "and paxis3.dat." }; - static gmx_bool foo = FALSE; + static gmx_bool foo = FALSE; - t_pargs pa[] = { - { "-foo", FALSE, etBOOL, {&foo}, "Dummy option to avoid empty array" } - }; - t_trxstatus *status; - t_topology top; - int ePBC; - real t; - rvec * x; + t_pargs pa[] = { { "-foo", FALSE, etBOOL, { &foo }, "Dummy option to avoid empty array" } }; + t_trxstatus* status; + t_topology top; + int ePBC; + real t; + rvec* x; int natoms; - char *grpname; + char* grpname; int i, gnx; - int *index; + int* index; rvec moi; - FILE * axis1; - FILE * axis2; - FILE * axis3; - FILE * fmoi; + FILE* axis1; + FILE* axis2; + FILE* axis3; + FILE* fmoi; matrix axes, box; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - char ** legend; - - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-a1", "paxis1", ffWRITE }, - { efXVG, "-a2", "paxis2", ffWRITE }, - { efXVG, "-a3", "paxis3", ffWRITE }, - { efXVG, "-om", "moi", ffWRITE } - }; + char** legend; + + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-a1", "paxis1", ffWRITE }, + { efXVG, "-a2", "paxis2", ffWRITE }, { efXVG, "-a3", "paxis3", ffWRITE }, + { efXVG, "-om", "moi", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -127,7 +113,7 @@ int gmx_principal(int argc, char *argv[]) for (i = 0; i < DIM; i++) { snew(legend[i], STRLEN); - sprintf(legend[i], "%c component", 'X'+i); + sprintf(legend[i], "%c component", 'X' + i); } axis1 = xvgropen(opt2fn("-a1", NFILE, fnm), "Principal axis 1 (major axis)", @@ -146,8 +132,8 @@ int gmx_principal(int argc, char *argv[]) sprintf(legend[YY], "Axis 2 (middle)"); sprintf(legend[ZZ], "Axis 3 (minor)"); - fmoi = xvgropen(opt2fn("-om", NFILE, fnm), "Moments of inertia around inertial axes", - output_env_get_xvgr_tlabel(oenv), "I (au nm\\S2\\N)", oenv); + fmoi = xvgropen(opt2fn("-om", NFILE, fnm), "Moments of inertia around inertial axes", + output_env_get_xvgr_tlabel(oenv), "I (au nm\\S2\\N)", oenv); xvgr_legend(fmoi, DIM, legend, oenv); for (i = 0; i < DIM; i++) @@ -170,12 +156,14 @@ int gmx_principal(int argc, char *argv[]) calc_principal_axes(&top, x, index, gnx, axes, moi); - fprintf(axis1, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[XX][XX], axes[XX][YY], axes[XX][ZZ]); - fprintf(axis2, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[YY][XX], axes[YY][YY], axes[YY][ZZ]); - fprintf(axis3, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY], axes[ZZ][ZZ]); - fprintf(fmoi, "%15.10f %15.10f %15.10f %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]); - } - while (read_next_x(oenv, status, &t, x, box)); + fprintf(axis1, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[XX][XX], axes[XX][YY], + axes[XX][ZZ]); + fprintf(axis2, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[YY][XX], axes[YY][YY], + axes[YY][ZZ]); + fprintf(axis3, "%15.10f %15.10f %15.10f %15.10f\n", t, axes[ZZ][XX], axes[ZZ][YY], + axes[ZZ][ZZ]); + fprintf(fmoi, "%15.10f %15.10f %15.10f %15.10f\n", t, moi[XX], moi[YY], moi[ZZ]); + } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_rama.cpp b/src/gromacs/gmxana/gmx_rama.cpp index 7aa63cbddd..e73381376d 100644 --- a/src/gromacs/gmxana/gmx_rama.cpp +++ b/src/gromacs/gmxana/gmx_rama.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,41 +51,39 @@ #include "gromacs/utility/smalloc.h" -static void plot_rama(FILE *out, t_xrama *xr) +static void plot_rama(FILE* out, t_xrama* xr) { int i; real phi, psi; for (i = 0; (i < xr->npp); i++) { - phi = xr->dih[xr->pp[i].iphi].ang*RAD2DEG; - psi = xr->dih[xr->pp[i].ipsi].ang*RAD2DEG; + phi = xr->dih[xr->pp[i].iphi].ang * RAD2DEG; + psi = xr->dih[xr->pp[i].ipsi].ang * RAD2DEG; fprintf(out, "%g %g %s\n", phi, psi, xr->pp[i].label); } } -int gmx_rama(int argc, char *argv[]) +int gmx_rama(int argc, char* argv[]) { - const char *desc[] = { - "[THISMODULE] selects the [GRK]phi[grk]/[GRK]psi[grk] dihedral combinations from your topology file", + const char* desc[] = { + "[THISMODULE] selects the [GRK]phi[grk]/[GRK]psi[grk] dihedral combinations from " + "your topology file", "and computes these as a function of time.", - "Using simple Unix tools such as [IT]grep[it] you can select out", - "specific residues." + "Using simple Unix tools such as [IT]grep[it] you can select out", "specific residues." }; - FILE *out; - t_xrama *xr; + FILE* out; + t_xrama* xr; int j; - gmx_output_env_t *oenv; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efXVG, nullptr, "rama", ffWRITE } - }; + gmx_output_env_t* oenv; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efXVG, nullptr, "rama", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, 0, nullptr, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, 0, nullptr, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -109,8 +107,7 @@ int gmx_rama(int argc, char *argv[]) { plot_rama(out, xr); j++; - } - while (new_data(xr)); + } while (new_data(xr)); fprintf(stderr, "\n"); xvgrclose(out); diff --git a/src/gromacs/gmxana/gmx_rms.cpp b/src/gromacs/gmxana/gmx_rms.cpp index ed445c3aaf..ccc24ff467 100644 --- a/src/gromacs/gmxana/gmx_rms.cpp +++ b/src/gromacs/gmxana/gmx_rms.cpp @@ -64,8 +64,7 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -static void norm_princ(const t_atoms *atoms, int isize, int *index, int natoms, - rvec *x) +static void norm_princ(const t_atoms* atoms, int isize, int* index, int natoms, rvec* x) { int i, m; rvec princ, vec; @@ -97,10 +96,9 @@ static void norm_princ(const t_atoms *atoms, int isize, int *index, int natoms, } } -int gmx_rms(int argc, char *argv[]) +int gmx_rms(int argc, char* argv[]) { - const char *desc[] = - { + const char* desc[] = { "[THISMODULE] compares two structures by computing the root mean square", "deviation (RMSD), the size-independent [GRK]rho[grk] similarity parameter", "([TT]rho[tt]) or the scaled [GRK]rho[grk] ([TT]rhosc[tt]), ", @@ -147,134 +145,103 @@ int gmx_rms(int argc, char *argv[]) "analogously to the [TT]-m[tt] option. Only bonds between atoms in the", "comparison group are considered." }; - static gmx_bool bPBC = TRUE, bFitAll = TRUE, bSplit = FALSE; - static gmx_bool bDeltaLog = FALSE; - static int prev = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0; - static real rmsd_user_max = -1, rmsd_user_min = -1, bond_user_max = -1, - bond_user_min = -1, delta_maxy = 0.0; + static gmx_bool bPBC = TRUE, bFitAll = TRUE, bSplit = FALSE; + static gmx_bool bDeltaLog = FALSE; + static int prev = 0, freq = 1, freq2 = 1, nlevels = 80, avl = 0; + static real rmsd_user_max = -1, rmsd_user_min = -1, bond_user_max = -1, bond_user_min = -1, + delta_maxy = 0.0; /* strings and things for selecting difference method */ enum { - ewSel, ewRMSD, ewRho, ewRhoSc, ewNR + ewSel, + ewRMSD, + ewRho, + ewRhoSc, + ewNR }; int ewhat; - const char *what[ewNR + 1] = - { nullptr, "rmsd", "rho", "rhosc", nullptr }; - const char *whatname[ewNR] = - { nullptr, "RMSD", "Rho", "Rho sc" }; - const char *whatlabel[ewNR] = - { nullptr, "RMSD (nm)", "Rho", "Rho sc" }; - const char *whatxvgname[ewNR] = - { nullptr, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" }; - const char *whatxvglabel[ewNR] = - { nullptr, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" }; + const char* what[ewNR + 1] = { nullptr, "rmsd", "rho", "rhosc", nullptr }; + const char* whatname[ewNR] = { nullptr, "RMSD", "Rho", "Rho sc" }; + const char* whatlabel[ewNR] = { nullptr, "RMSD (nm)", "Rho", "Rho sc" }; + const char* whatxvgname[ewNR] = { nullptr, "RMSD", "\\8r\\4", "\\8r\\4\\ssc\\N" }; + const char* whatxvglabel[ewNR] = { nullptr, "RMSD (nm)", "\\8r\\4", "\\8r\\4\\ssc\\N" }; /* strings and things for fitting methods */ enum { - efSel, efFit, efReset, efNone, efNR + efSel, + efFit, + efReset, + efNone, + efNR }; int efit; - const char *fit[efNR + 1] = - { nullptr, "rot+trans", "translation", "none", nullptr }; - const char *fitgraphlabel[efNR + 1] = - { nullptr, "lsq fit", "translational fit", "no fit" }; - static int nrms = 1; - static gmx_bool bMassWeighted = TRUE; - t_pargs pa[] = - { - { "-what", FALSE, etENUM, - { what }, "Structural difference measure" }, - { "-pbc", FALSE, etBOOL, - { &bPBC }, "PBC check" }, - { "-fit", FALSE, etENUM, - { fit }, "Fit to reference structure" }, - { "-prev", FALSE, etINT, - { &prev }, "Compare with previous frame" }, - { "-split", FALSE, etBOOL, - { &bSplit }, "Split graph where time is zero" }, - { "-fitall", FALSE, etBOOL, - { &bFitAll }, "HIDDENFit all pairs of structures in matrix" }, - { "-skip", FALSE, etINT, - { &freq }, "Only write every nr-th frame to matrix" }, - { "-skip2", FALSE, etINT, - { &freq2 }, "Only write every nr-th frame to matrix" }, - { "-max", FALSE, etREAL, - { &rmsd_user_max }, "Maximum level in comparison matrix" }, - { "-min", FALSE, etREAL, - { &rmsd_user_min }, "Minimum level in comparison matrix" }, - { "-bmax", FALSE, etREAL, - { &bond_user_max }, "Maximum level in bond angle matrix" }, - { "-bmin", FALSE, etREAL, - { &bond_user_min }, "Minimum level in bond angle matrix" }, - { "-mw", FALSE, etBOOL, - { &bMassWeighted }, "Use mass weighting for superposition" }, - { "-nlevels", FALSE, etINT, - { &nlevels }, "Number of levels in the matrices" }, - { "-ng", FALSE, etINT, - { &nrms }, "Number of groups to compute RMS between" }, - { "-dlog", FALSE, etBOOL, - { &bDeltaLog }, - "HIDDENUse a log x-axis in the delta t matrix" }, - { "-dmax", FALSE, etREAL, - { &delta_maxy }, "HIDDENMaximum level in delta matrix" }, - { "-aver", FALSE, etINT, - { &avl }, - "HIDDENAverage over this distance in the RMSD matrix" } + const char* fit[efNR + 1] = { nullptr, "rot+trans", "translation", "none", nullptr }; + const char* fitgraphlabel[efNR + 1] = { nullptr, "lsq fit", "translational fit", "no fit" }; + static int nrms = 1; + static gmx_bool bMassWeighted = TRUE; + t_pargs pa[] = { + { "-what", FALSE, etENUM, { what }, "Structural difference measure" }, + { "-pbc", FALSE, etBOOL, { &bPBC }, "PBC check" }, + { "-fit", FALSE, etENUM, { fit }, "Fit to reference structure" }, + { "-prev", FALSE, etINT, { &prev }, "Compare with previous frame" }, + { "-split", FALSE, etBOOL, { &bSplit }, "Split graph where time is zero" }, + { "-fitall", FALSE, etBOOL, { &bFitAll }, "HIDDENFit all pairs of structures in matrix" }, + { "-skip", FALSE, etINT, { &freq }, "Only write every nr-th frame to matrix" }, + { "-skip2", FALSE, etINT, { &freq2 }, "Only write every nr-th frame to matrix" }, + { "-max", FALSE, etREAL, { &rmsd_user_max }, "Maximum level in comparison matrix" }, + { "-min", FALSE, etREAL, { &rmsd_user_min }, "Minimum level in comparison matrix" }, + { "-bmax", FALSE, etREAL, { &bond_user_max }, "Maximum level in bond angle matrix" }, + { "-bmin", FALSE, etREAL, { &bond_user_min }, "Minimum level in bond angle matrix" }, + { "-mw", FALSE, etBOOL, { &bMassWeighted }, "Use mass weighting for superposition" }, + { "-nlevels", FALSE, etINT, { &nlevels }, "Number of levels in the matrices" }, + { "-ng", FALSE, etINT, { &nrms }, "Number of groups to compute RMS between" }, + { "-dlog", FALSE, etBOOL, { &bDeltaLog }, "HIDDENUse a log x-axis in the delta t matrix" }, + { "-dmax", FALSE, etREAL, { &delta_maxy }, "HIDDENMaximum level in delta matrix" }, + { "-aver", FALSE, etINT, { &avl }, "HIDDENAverage over this distance in the RMSD matrix" } }; - int natoms_trx, natoms_trx2, natoms; - int i, j, k, m; + int natoms_trx, natoms_trx2, natoms; + int i, j, k, m; #define NFRAME 5000 - int maxframe = NFRAME, maxframe2 = NFRAME; - real t, *w_rls, *w_rms, *w_rls_m = nullptr, *w_rms_m = nullptr; - gmx_bool bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass; - gmx_bool bFit, bReset; - t_topology top; - int ePBC; - t_iatom *iatom = nullptr; + int maxframe = NFRAME, maxframe2 = NFRAME; + real t, *w_rls, *w_rms, *w_rls_m = nullptr, *w_rms_m = nullptr; + gmx_bool bNorm, bAv, bFreq2, bFile2, bMat, bBond, bDelta, bMirror, bMass; + gmx_bool bFit, bReset; + t_topology top; + int ePBC; + t_iatom* iatom = nullptr; - matrix box = {{0}}; - rvec *x, *xp, *xm = nullptr, **mat_x = nullptr, **mat_x2, *mat_x2_j = nullptr, vec1, - vec2; - t_trxstatus *status; - char buf[256], buf2[256]; - int ncons = 0; - FILE *fp; - real rlstot = 0, **rls, **rlsm = nullptr, *time, *time2, *rlsnorm = nullptr, - **rmsd_mat = nullptr, **bond_mat = nullptr, *axis, *axis2, *del_xaxis, - *del_yaxis, rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang; - real **rmsdav_mat = nullptr, av_tot, weight, weight_tot; - real **delta = nullptr, delta_max, delta_scalex = 0, delta_scaley = 0, - *delta_tot; - int delta_xsize = 0, del_lev = 100, mx, my, abs_my; - gmx_bool bA1, bA2, bPrev, bTop, *bInMat = nullptr; - int ifit, *irms, ibond = 0, *ind_bond1 = nullptr, *ind_bond2 = nullptr, n_ind_m = - 0; - int *ind_fit, **ind_rms, *ind_m = nullptr, *rev_ind_m = nullptr, *ind_rms_m = - nullptr; - char *gn_fit, **gn_rms; - t_rgb rlo, rhi; - gmx_output_env_t *oenv; + matrix box = { { 0 } }; + rvec * x, *xp, *xm = nullptr, **mat_x = nullptr, **mat_x2, *mat_x2_j = nullptr, vec1, vec2; + t_trxstatus* status; + char buf[256], buf2[256]; + int ncons = 0; + FILE* fp; + real rlstot = 0, **rls, **rlsm = nullptr, *time, *time2, *rlsnorm = nullptr, + **rmsd_mat = nullptr, **bond_mat = nullptr, *axis, *axis2, *del_xaxis, *del_yaxis, + rmsd_max, rmsd_min, rmsd_avg, bond_max, bond_min, ang; + real ** rmsdav_mat = nullptr, av_tot, weight, weight_tot; + real ** delta = nullptr, delta_max, delta_scalex = 0, delta_scaley = 0, *delta_tot; + int delta_xsize = 0, del_lev = 100, mx, my, abs_my; + gmx_bool bA1, bA2, bPrev, bTop, *bInMat = nullptr; + int ifit, *irms, ibond = 0, *ind_bond1 = nullptr, *ind_bond2 = nullptr, n_ind_m = 0; + int * ind_fit, **ind_rms, *ind_m = nullptr, *rev_ind_m = nullptr, *ind_rms_m = nullptr; + char * gn_fit, **gn_rms; + t_rgb rlo, rhi; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - t_filenm fnm[] = - { - { efTPS, nullptr, nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efTRX, "-f2", nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "rmsd", ffWRITE }, - { efXVG, "-mir", "rmsdmir", ffOPTWR }, - { efXVG, "-a", "avgrp", ffOPTWR }, - { efXVG, "-dist", "rmsd-dist", ffOPTWR }, - { efXPM, "-m", "rmsd", ffOPTWR }, - { efDAT, "-bin", "rmsd", ffOPTWR }, + t_filenm fnm[] = { + { efTPS, nullptr, nullptr, ffREAD }, { efTRX, "-f", nullptr, ffREAD }, + { efTRX, "-f2", nullptr, ffOPTRD }, { efNDX, nullptr, nullptr, ffOPTRD }, + { efXVG, nullptr, "rmsd", ffWRITE }, { efXVG, "-mir", "rmsdmir", ffOPTWR }, + { efXVG, "-a", "avgrp", ffOPTWR }, { efXVG, "-dist", "rmsd-dist", ffOPTWR }, + { efXPM, "-m", "rmsd", ffOPTWR }, { efDAT, "-bin", "rmsd", ffOPTWR }, { efXPM, "-bm", "bond", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -303,11 +270,12 @@ int gmx_rms(int argc, char *argv[]) bBond = opt2bSet("-bm", NFILE, fnm); bDelta = (delta_maxy > 0); /* calculate rmsd vs delta t matrix from * * your RMSD matrix (hidden option */ - bNorm = opt2bSet("-a", NFILE, fnm); - bFreq2 = opt2parg_bSet("-skip2", asize(pa), pa); + bNorm = opt2bSet("-a", NFILE, fnm); + bFreq2 = opt2parg_bSet("-skip2", asize(pa), pa); if (freq <= 0) { - fprintf(stderr, "The number of frames to skip is <= 0. " + fprintf(stderr, + "The number of frames to skip is <= 0. " "Writing out all frames.\n\n"); freq = 1; } @@ -326,7 +294,8 @@ int gmx_rms(int argc, char *argv[]) bPrev = (prev > 0); if (bPrev) { - fprintf(stderr, "WARNING: using option -prev with large trajectories will\n" + fprintf(stderr, + "WARNING: using option -prev with large trajectories will\n" " require a lot of memory and could lead to crashes\n"); prev = abs(prev); if (freq != 1) @@ -337,11 +306,10 @@ int gmx_rms(int argc, char *argv[]) if (bFile2 && !bMat && !bBond) { - fprintf( - stderr, + fprintf(stderr, "WARNING: second trajectory (-f2) useless when not calculating matrix (-m/-bm),\n" - " will not read from %s\n", opt2fn("-f2", NFILE, - fnm)); + " will not read from %s\n", + opt2fn("-f2", NFILE, fnm)); bFile2 = FALSE; } @@ -352,14 +320,13 @@ int gmx_rms(int argc, char *argv[]) { fprintf(stderr, "WARNING: second trajectory (-f2) useless when making delta matrix,\n" - " will not read from %s\n", opt2fn("-f2", - NFILE, fnm)); + " will not read from %s\n", + opt2fn("-f2", NFILE, fnm)); bFile2 = FALSE; } } - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xp, - nullptr, box, TRUE); + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xp, nullptr, box, TRUE); snew(w_rls, top.atoms.nr); snew(w_rms, top.atoms.nr); @@ -373,10 +340,8 @@ int gmx_rms(int argc, char *argv[]) if (bReset) { - fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares" - : "translational"); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit, - &ind_fit, &gn_fit); + fprintf(stderr, "Select group for %s fit\n", bFit ? "least squares" : "translational"); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit, &ind_fit, &gn_fit); } else { @@ -387,7 +352,7 @@ int gmx_rms(int argc, char *argv[]) { if (bFit && ifit < 3) { - gmx_fatal(FARGS, "Need >= 3 points to fit!\n" ); + gmx_fatal(FARGS, "Need >= 3 points to fit!\n"); } bMass = FALSE; @@ -422,10 +387,8 @@ int gmx_rms(int argc, char *argv[]) snew(ind_rms, nrms); snew(irms, nrms); - fprintf(stderr, "Select group%s for %s calculation\n", - (nrms > 1) ? "s" : "", whatname[ewhat]); - get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), - nrms, irms, ind_rms, gn_rms); + fprintf(stderr, "Select group%s for %s calculation\n", (nrms > 1) ? "s" : "", whatname[ewhat]); + get_index(&(top.atoms), ftp2fn_null(efNDX, NFILE, fnm), nrms, irms, ind_rms, gn_rms); if (bNorm) { @@ -498,8 +461,7 @@ int gmx_rms(int argc, char *argv[]) natoms_trx = read_first_x(oenv, &status, opt2fn("-f", NFILE, fnm), &t, &x, box); if (natoms_trx != top.atoms.nr) { - fprintf(stderr, - "\nWARNING: topology has %d atoms, whereas trajectory has %d\n", + fprintf(stderr, "\nWARNING: topology has %d atoms, whereas trajectory has %d\n", top.atoms.nr, natoms_trx); } natoms = std::min(top.atoms.nr, natoms_trx); @@ -565,7 +527,7 @@ int gmx_rms(int argc, char *argv[]) { if (IS_CHEMBOND(k)) { - ncons += top.idef.il[k].nr/3; + ncons += top.idef.il[k].nr / 3; } } fprintf(stderr, "Found %d bonds in topology\n", ncons); @@ -577,26 +539,26 @@ int gmx_rms(int argc, char *argv[]) if (IS_CHEMBOND(k)) { iatom = top.idef.il[k].iatoms; - ncons = top.idef.il[k].nr/3; + ncons = top.idef.il[k].nr / 3; for (i = 0; i < ncons; i++) { bA1 = FALSE; bA2 = FALSE; for (j = 0; j < irms[0]; j++) { - if (iatom[3*i+1] == ind_rms[0][j]) + if (iatom[3 * i + 1] == ind_rms[0][j]) { bA1 = TRUE; } - if (iatom[3*i+2] == ind_rms[0][j]) + if (iatom[3 * i + 2] == ind_rms[0][j]) { bA2 = TRUE; } } if (bA1 && bA2) { - ind_bond1[ibond] = rev_ind_m[iatom[3*i+1]]; - ind_bond2[ibond] = rev_ind_m[iatom[3*i+2]]; + ind_bond1[ibond] = rev_ind_m[iatom[3 * i + 1]]; + ind_bond2[ibond] = rev_ind_m[iatom[3 * i + 2]]; ibond++; } } @@ -642,7 +604,7 @@ int gmx_rms(int argc, char *argv[]) { if (tel_mat >= NFRAME) { - srenew(mat_x, tel_mat+1); + srenew(mat_x, tel_mat + 1); } snew(mat_x[tel_mat], n_ind_m); for (i = 0; i < n_ind_m; i++) @@ -655,7 +617,7 @@ int gmx_rms(int argc, char *argv[]) /*calculate energy of root_least_squares*/ if (bPrev) { - j = tel_mat-prev-1; + j = tel_mat - prev - 1; if (j < 0) { j = 0; @@ -675,15 +637,13 @@ int gmx_rms(int argc, char *argv[]) } for (j = 0; (j < nrms); j++) { - rls[j][teller] = - calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp); + rls[j][teller] = calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xp); } if (bNorm) { for (j = 0; (j < irms[0]); j++) { - rlsnorm[j] += - calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp); + rlsnorm[j] += calc_similar_ind(ewhat != ewRMSD, 1, &(ind_rms[0][j]), w_rms, x, xp); } } @@ -698,7 +658,7 @@ int gmx_rms(int argc, char *argv[]) for (j = 0; j < nrms; j++) { rlsm[j][teller] = - calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm); + calc_similar_ind(ewhat != ewRMSD, irms[j], ind_rms[j], w_rms, x, xm); } } time[teller] = output_env_conv_time(oenv, t); @@ -722,8 +682,7 @@ int gmx_rms(int argc, char *argv[]) } } } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); int tel_mat2 = 0; @@ -735,13 +694,13 @@ int gmx_rms(int argc, char *argv[]) fprintf(stderr, "\nWill read second trajectory file\n"); snew(mat_x2, NFRAME); - natoms_trx2 = - read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box); + natoms_trx2 = read_first_x(oenv, &status, opt2fn("-f2", NFILE, fnm), &t, &x, box); if (natoms_trx2 != natoms_trx) { gmx_fatal(FARGS, "Second trajectory (%d atoms) does not match the first one" - " (%d atoms)", natoms_trx2, natoms_trx); + " (%d atoms)", + natoms_trx2, natoms_trx); } frame2 = 0; do @@ -773,7 +732,7 @@ int gmx_rms(int argc, char *argv[]) { if (tel_mat2 >= NFRAME) { - srenew(mat_x2, tel_mat2+1); + srenew(mat_x2, tel_mat2 + 1); } snew(mat_x2[tel_mat2], n_ind_m); for (i = 0; i < n_ind_m; i++) @@ -793,8 +752,7 @@ int gmx_rms(int argc, char *argv[]) maxframe2 += NFRAME; srenew(time2, maxframe2); } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); } else @@ -812,14 +770,12 @@ int gmx_rms(int argc, char *argv[]) fprintf(stderr, "\n"); if (bMat) { - fprintf(stderr, "Building %s matrix, %dx%d elements\n", - whatname[ewhat], tel_mat, tel_mat2); + fprintf(stderr, "Building %s matrix, %dx%d elements\n", whatname[ewhat], tel_mat, tel_mat2); snew(rmsd_mat, tel_mat); } if (bBond) { - fprintf(stderr, "Building bond angle matrix, %dx%d elements\n", - tel_mat, tel_mat2); + fprintf(stderr, "Building bond angle matrix, %dx%d elements\n", tel_mat, tel_mat2); snew(bond_mat, tel_mat); } snew(axis, tel_mat); @@ -838,24 +794,24 @@ int gmx_rms(int argc, char *argv[]) bond_min = 1e10; for (j = 0; j < tel_mat2; j++) { - axis2[j] = time2[freq2*j]; + axis2[j] = time2[freq2 * j]; } if (bDelta) { if (bDeltaLog) { - delta_scalex = 8.0/std::log(2.0); - delta_xsize = gmx::roundToInt(std::log(tel_mat/2.)*delta_scalex)+1; + delta_scalex = 8.0 / std::log(2.0); + delta_xsize = gmx::roundToInt(std::log(tel_mat / 2.) * delta_scalex) + 1; } else { - delta_xsize = tel_mat/2; + delta_xsize = tel_mat / 2; } - delta_scaley = 1.0/delta_maxy; + delta_scaley = 1.0 / delta_maxy; snew(delta, delta_xsize); for (j = 0; j < delta_xsize; j++) { - snew(delta[j], del_lev+1); + snew(delta[j], del_lev + 1); } if (avl > 0) { @@ -873,7 +829,7 @@ int gmx_rms(int argc, char *argv[]) } for (i = 0; i < tel_mat; i++) { - axis[i] = time[freq*i]; + axis[i] = time[freq * i]; fprintf(stderr, "\r element %5d; time %5.2f ", i, axis[i]); fflush(stderr); if (bMat) @@ -902,9 +858,8 @@ int gmx_rms(int argc, char *argv[]) { if (bFile2 || (i < j)) { - rmsd_mat[i][j] = - calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m, - w_rms_m, mat_x[i], mat_x2_j); + rmsd_mat[i][j] = calc_similar_ind(ewhat != ewRMSD, irms[0], ind_rms_m, + w_rms_m, mat_x[i], mat_x2_j); if (rmsd_mat[i][j] > rmsd_max) { rmsd_max = rmsd_mat[i][j]; @@ -931,7 +886,7 @@ int gmx_rms(int argc, char *argv[]) rvec_sub(mat_x2_j[ind_bond1[m]], mat_x2_j[ind_bond2[m]], vec2); ang += std::acos(cos_angle(vec1, vec2)); } - bond_mat[i][j] = ang*180.0/(M_PI*ibond); + bond_mat[i][j] = ang * 180.0 / (M_PI * ibond); if (bond_mat[i][j] > bond_max) { bond_max = bond_mat[i][j]; @@ -950,40 +905,40 @@ int gmx_rms(int argc, char *argv[]) } if (bFile2) { - rmsd_avg /= static_cast(tel_mat)*static_cast(tel_mat2); + rmsd_avg /= static_cast(tel_mat) * static_cast(tel_mat2); } else { - rmsd_avg /= tel_mat*(tel_mat - 1)/2.; + rmsd_avg /= tel_mat * (tel_mat - 1) / 2.; } if (bMat && (avl > 0)) { rmsd_max = 0.0; rmsd_min = 0.0; rmsd_avg = 0.0; - for (j = 0; j < tel_mat-1; j++) + for (j = 0; j < tel_mat - 1; j++) { - for (i = j+1; i < tel_mat; i++) + for (i = j + 1; i < tel_mat; i++) { av_tot = 0; weight_tot = 0; for (my = -avl; my <= avl; my++) { - if ((j+my >= 0) && (j+my < tel_mat)) + if ((j + my >= 0) && (j + my < tel_mat)) { abs_my = std::abs(my); for (mx = -avl; mx <= avl; mx++) { - if ((i+mx >= 0) && (i+mx < tel_mat)) + if ((i + mx >= 0) && (i + mx < tel_mat)) { - weight = avl+1.0-std::max(std::abs(mx), abs_my); - av_tot += weight*rmsd_mat[i+mx][j+my]; + weight = avl + 1.0 - std::max(std::abs(mx), abs_my); + av_tot += weight * rmsd_mat[i + mx][j + my]; weight_tot += weight; } } } } - rmsdav_mat[i][j] = av_tot/weight_tot; + rmsdav_mat[i][j] = av_tot / weight_tot; rmsdav_mat[j][i] = rmsdav_mat[i][j]; if (rmsdav_mat[i][j] > rmsd_max) { @@ -996,10 +951,13 @@ int gmx_rms(int argc, char *argv[]) if (bMat) { - fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n", - whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg); - rlo.r = 1; rlo.g = 1; rlo.b = 1; - rhi.r = 0; rhi.g = 0; rhi.b = 0; + fprintf(stderr, "\n%s: Min %f, Max %f, Avg %f\n", whatname[ewhat], rmsd_min, rmsd_max, rmsd_avg); + rlo.r = 1; + rlo.g = 1; + rlo.b = 1; + rhi.r = 0; + rhi.g = 0; + rhi.b = 0; if (rmsd_user_max != -1) { rmsd_max = rmsd_user_max; @@ -1008,15 +966,14 @@ int gmx_rms(int argc, char *argv[]) { rmsd_min = rmsd_user_min; } - if ((rmsd_user_max != -1) || (rmsd_user_min != -1)) + if ((rmsd_user_max != -1) || (rmsd_user_min != -1)) { - fprintf(stderr, "Min and Max value set to resp. %f and %f\n", - rmsd_min, rmsd_max); + fprintf(stderr, "Min and Max value set to resp. %f and %f\n", rmsd_min, rmsd_max); } sprintf(buf, "%s %s matrix", gn_rms[0], whatname[ewhat]); write_xpm(opt2FILE("-m", NFILE, fnm, "w"), 0, buf, whatlabel[ewhat], - output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2, - axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels); + output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, + tel_mat2, axis, axis2, rmsd_mat, rmsd_min, rmsd_max, rlo, rhi, &nlevels); /* Print the distribution of RMSD values */ if (opt2bSet("-dist", NFILE, fnm)) { @@ -1026,18 +983,18 @@ int gmx_rms(int argc, char *argv[]) if (bDelta) { snew(delta_tot, delta_xsize); - for (j = 0; j < tel_mat-1; j++) + for (j = 0; j < tel_mat - 1; j++) { - for (i = j+1; i < tel_mat; i++) + for (i = j + 1; i < tel_mat; i++) { - mx = i-j; - if (mx < tel_mat/2) + mx = i - j; + if (mx < tel_mat / 2) { if (bDeltaLog) { - mx = gmx::roundToInt(std::log(static_cast(mx))*delta_scalex); + mx = gmx::roundToInt(std::log(static_cast(mx)) * delta_scalex); } - my = gmx::roundToInt(rmsd_mat[i][j]*delta_scaley*static_cast(del_lev)); + my = gmx::roundToInt(rmsd_mat[i][j] * delta_scaley * static_cast(del_lev)); delta_tot[mx] += 1.0; if ((rmsd_mat[i][j] >= 0) && (rmsd_mat[i][j] <= delta_maxy)) { @@ -1051,7 +1008,7 @@ int gmx_rms(int argc, char *argv[]) { if (delta_tot[i] > 0.0) { - delta_tot[i] = 1.0/delta_tot[i]; + delta_tot[i] = 1.0 / delta_tot[i]; for (j = 0; j <= del_lev; j++) { delta[i][j] *= delta_tot[i]; @@ -1064,20 +1021,20 @@ int gmx_rms(int argc, char *argv[]) } fprintf(stderr, "Maximum in delta matrix: %f\n", delta_max); snew(del_xaxis, delta_xsize); - snew(del_yaxis, del_lev+1); + snew(del_yaxis, del_lev + 1); for (i = 0; i < delta_xsize; i++) { - del_xaxis[i] = axis[i]-axis[0]; + del_xaxis[i] = axis[i] - axis[0]; } - for (i = 0; i < del_lev+1; i++) + for (i = 0; i < del_lev + 1; i++) { - del_yaxis[i] = delta_maxy*static_cast(i)/static_cast(del_lev); + del_yaxis[i] = delta_maxy * static_cast(i) / static_cast(del_lev); } sprintf(buf, "%s %s vs. delta t", gn_rms[0], whatname[ewhat]); fp = gmx_ffopen("delta.xpm", "w"); write_xpm(fp, 0, buf, "density", output_env_get_time_label(oenv), whatlabel[ewhat], - delta_xsize, del_lev+1, del_xaxis, del_yaxis, - delta, 0.0, delta_max, rlo, rhi, &nlevels); + delta_xsize, del_lev + 1, del_xaxis, del_yaxis, delta, 0.0, delta_max, + rlo, rhi, &nlevels); gmx_ffclose(fp); } if (opt2bSet("-bin", NFILE, fnm)) @@ -1105,17 +1062,23 @@ int gmx_rms(int argc, char *argv[]) { bond_min = bond_user_min; } - if ((bond_user_max != -1) || (bond_user_min != -1)) + if ((bond_user_max != -1) || (bond_user_min != -1)) { - fprintf(stderr, "Bond angle Min and Max set to:\n" - "Min. angle: %f, Max. angle: %f\n", bond_min, bond_max); + fprintf(stderr, + "Bond angle Min and Max set to:\n" + "Min. angle: %f, Max. angle: %f\n", + bond_min, bond_max); } - rlo.r = 1; rlo.g = 1; rlo.b = 1; - rhi.r = 0; rhi.g = 0; rhi.b = 0; + rlo.r = 1; + rlo.g = 1; + rlo.b = 1; + rhi.r = 0; + rhi.g = 0; + rhi.b = 0; sprintf(buf, "%s av. bond angle deviation", gn_rms[0]); write_xpm(opt2FILE("-bm", NFILE, fnm, "w"), 0, buf, "degrees", - output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, tel_mat2, - axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels); + output_env_get_time_label(oenv), output_env_get_time_label(oenv), tel_mat, + tel_mat2, axis, axis2, bond_mat, bond_min, bond_max, rlo, rhi, &nlevels); } } @@ -1128,16 +1091,15 @@ int gmx_rms(int argc, char *argv[]) } else { - sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat], - time[prev*freq]-time[0], output_env_get_time_label(oenv).c_str()); + sprintf(buf, "%s with frame %g %s ago", whatxvgname[ewhat], time[prev * freq] - time[0], + output_env_get_time_label(oenv).c_str()); } fp = xvgropen(opt2fn("-o", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), whatxvglabel[ewhat], oenv); if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n", - (nrms == 1) ? "" : "of ", gn_rms[0], fitgraphlabel[efit], - bFit ? " to " : "", bFit ? gn_fit : ""); + fprintf(fp, "@ subtitle \"%s%s after %s%s%s\"\n", (nrms == 1) ? "" : "of ", gn_rms[0], + fitgraphlabel[efit], bFit ? " to " : "", bFit ? gn_fit : ""); } if (nrms != 1) { @@ -1145,12 +1107,11 @@ int gmx_rms(int argc, char *argv[]) } for (i = 0; (i < teller); i++) { - if (bSplit && i > 0 && - std::abs(time[bPrev ? freq*i : i]/output_env_get_time_factor(oenv)) < 1e-5) + if (bSplit && i > 0 && std::abs(time[bPrev ? freq * i : i] / output_env_get_time_factor(oenv)) < 1e-5) { fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } - fprintf(fp, "%12.7f", time[bPrev ? freq*i : i]); + fprintf(fp, "%12.7f", time[bPrev ? freq * i : i]); for (j = 0; (j < nrms); j++) { fprintf(fp, " %12.7f", rls[j][i]); @@ -1168,14 +1129,13 @@ int gmx_rms(int argc, char *argv[]) /* Write the mirror RMSD's to file */ sprintf(buf, "%s with Mirror", whatxvgname[ewhat]); sprintf(buf2, "Mirror %s", whatxvglabel[ewhat]); - fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), - buf2, oenv); + fp = xvgropen(opt2fn("-mir", NFILE, fnm), buf, output_env_get_xvgr_tlabel(oenv), buf2, oenv); if (nrms == 1) { if (output_env_get_print_xvgr_codes(oenv)) { - fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n", - gn_rms[0], bFit ? gn_fit : ""); + fprintf(fp, "@ subtitle \"of %s after lsq fit to mirror of %s\"\n", gn_rms[0], + bFit ? gn_fit : ""); } } else @@ -1209,7 +1169,7 @@ int gmx_rms(int argc, char *argv[]) fp = xvgropen(opt2fn("-a", NFILE, fnm), buf, "Residue", buf2, oenv); for (j = 0; (j < nrms); j++) { - fprintf(fp, "%10d %10g\n", j, rlstot/static_cast(teller)); + fprintf(fp, "%10d %10g\n", j, rlstot / static_cast(teller)); } xvgrclose(fp); } @@ -1219,7 +1179,7 @@ int gmx_rms(int argc, char *argv[]) fp = xvgropen("aver.xvg", gn_rms[0], "Residue", whatxvglabel[ewhat], oenv); for (j = 0; (j < irms[0]); j++) { - fprintf(fp, "%10d %10g\n", j, rlsnorm[j]/static_cast(teller)); + fprintf(fp, "%10d %10g\n", j, rlsnorm[j] / static_cast(teller)); } xvgrclose(fp); } diff --git a/src/gromacs/gmxana/gmx_rmsdist.cpp b/src/gromacs/gmxana/gmx_rmsdist.cpp index e001103edc..48eb4e8ffd 100644 --- a/src/gromacs/gmxana/gmx_rmsdist.cpp +++ b/src/gromacs/gmxana/gmx_rmsdist.cpp @@ -62,19 +62,18 @@ #include "gromacs/utility/strdb.h" -static void calc_dist(int nind, const int index[], const rvec x[], int ePBC, matrix box, - real **d) +static void calc_dist(int nind, const int index[], const rvec x[], int ePBC, matrix box, real** d) { - int i, j; - rvec dx; - real temp2; - t_pbc pbc; + int i, j; + rvec dx; + real temp2; + t_pbc pbc; set_pbc(&pbc, ePBC, box); - for (i = 0; (i < nind-1); i++) + for (i = 0; (i < nind - 1); i++) { - const real *xi = x[index[i]]; - for (j = i+1; (j < nind); j++) + const real* xi = x[index[i]]; + for (j = i + 1; (j < nind); j++) { pbc_dx(&pbc, xi, x[index[j]], dx); temp2 = norm2(dx); @@ -83,51 +82,57 @@ static void calc_dist(int nind, const int index[], const rvec x[], int ePBC, mat } } -static void calc_dist_tot(int nind, const int index[], rvec x[], - int ePBC, matrix box, - real **d, real **dtot, real **dtot2, - gmx_bool bNMR, real **dtot1_3, real **dtot1_6) +static void calc_dist_tot(int nind, + const int index[], + rvec x[], + int ePBC, + matrix box, + real** d, + real** dtot, + real** dtot2, + gmx_bool bNMR, + real** dtot1_3, + real** dtot1_6) { - int i, j; - real *xi; - real temp, temp2, temp1_3; - rvec dx; - t_pbc pbc; + int i, j; + real* xi; + real temp, temp2, temp1_3; + rvec dx; + t_pbc pbc; set_pbc(&pbc, ePBC, box); - for (i = 0; (i < nind-1); i++) + for (i = 0; (i < nind - 1); i++) { xi = x[index[i]]; - for (j = i+1; (j < nind); j++) + for (j = i + 1; (j < nind); j++) { pbc_dx(&pbc, xi, x[index[j]], dx); - temp2 = norm2(dx); - temp = std::sqrt(temp2); - d[i][j] = temp; - dtot[i][j] += temp; + temp2 = norm2(dx); + temp = std::sqrt(temp2); + d[i][j] = temp; + dtot[i][j] += temp; dtot2[i][j] += temp2; if (bNMR) { - temp1_3 = 1.0/(temp*temp2); + temp1_3 = 1.0 / (temp * temp2); dtot1_3[i][j] += temp1_3; - dtot1_6[i][j] += temp1_3*temp1_3; + dtot1_6[i][j] += temp1_3 * temp1_3; } } } } -static void calc_nmr(int nind, int nframes, real **dtot1_3, real **dtot1_6, - real *max1_3, real *max1_6) +static void calc_nmr(int nind, int nframes, real** dtot1_3, real** dtot1_6, real* max1_3, real* max1_6) { - int i, j; - real temp1_3, temp1_6; + int i, j; + real temp1_3, temp1_6; - for (i = 0; (i < nind-1); i++) + for (i = 0; (i < nind - 1); i++) { - for (j = i+1; (j < nind); j++) + for (j = i + 1; (j < nind); j++) { - temp1_3 = gmx::invcbrt(dtot1_3[i][j]/static_cast(nframes)); - temp1_6 = gmx::invsixthroot(dtot1_6[i][j]/static_cast(nframes)); + temp1_3 = gmx::invcbrt(dtot1_3[i][j] / static_cast(nframes)); + temp1_6 = gmx::invsixthroot(dtot1_6[i][j] / static_cast(nframes)); if (temp1_3 > *max1_3) { *max1_3 = temp1_3; @@ -146,7 +151,8 @@ static void calc_nmr(int nind, int nframes, real **dtot1_3, real **dtot1_6, static char Hnum[] = "123"; -typedef struct { +typedef struct +{ int nr; real r_3; real r_6; @@ -154,28 +160,30 @@ typedef struct { real i_6; } t_noe; -typedef struct { +typedef struct +{ int anr; int ianr; int rnr; - char *aname; - char *rname; + char* aname; + char* rname; } t_noe_gr; -typedef struct { +typedef struct +{ bool set; int rnr; - char *nname; - char *rname; - char *aname; + char* nname; + char* rname; + char* aname; } t_equiv; -static int read_equiv(const char *eq_fn, t_equiv ***equivptr) +static int read_equiv(const char* eq_fn, t_equiv*** equivptr) { - FILE *fp; + FILE* fp; char line[STRLEN], resname[10], atomname[10], *lp; int neq, na, n, resnr; - t_equiv **equiv; + t_equiv** equiv; fp = gmx_ffopen(eq_fn, "r"); neq = 0; @@ -184,7 +192,7 @@ static int read_equiv(const char *eq_fn, t_equiv ***equivptr) { lp = line; /* this is not efficient, but I'm lazy */ - srenew(equiv, neq+1); + srenew(equiv, neq + 1); equiv[neq] = nullptr; na = 0; if (sscanf(lp, "%s %n", atomname, &n) == 1) @@ -195,9 +203,9 @@ static int read_equiv(const char *eq_fn, t_equiv ***equivptr) while (sscanf(lp, "%d %s %s %n", &resnr, resname, atomname, &n) == 3) { /* this is not efficient, but I'm lazy (again) */ - srenew(equiv[neq], na+1); + srenew(equiv[neq], na + 1); equiv[neq][na].set = true; - equiv[neq][na].rnr = resnr-1; + equiv[neq][na].rnr = resnr - 1; equiv[neq][na].rname = gmx_strdup(resname); equiv[neq][na].aname = gmx_strdup(atomname); if (na > 0) @@ -209,7 +217,7 @@ static int read_equiv(const char *eq_fn, t_equiv ***equivptr) } } /* make empty element as flag for end of array */ - srenew(equiv[neq], na+1); + srenew(equiv[neq], na + 1); equiv[neq][na].set = false; equiv[neq][na].rnr = 0; equiv[neq][na].rname = nullptr; @@ -225,7 +233,7 @@ static int read_equiv(const char *eq_fn, t_equiv ***equivptr) return neq; } -static void dump_equiv(FILE *out, int neq, t_equiv **equiv) +static void dump_equiv(FILE* out, int neq, t_equiv** equiv) { int i, j; @@ -235,16 +243,14 @@ static void dump_equiv(FILE *out, int neq, t_equiv **equiv) fprintf(out, "%s", equiv[i][0].nname); for (j = 0; equiv[i][j].set; j++) { - fprintf(out, " %d %s %s", - equiv[i][j].rnr, equiv[i][j].rname, equiv[i][j].aname); + fprintf(out, " %d %s %s", equiv[i][j].rnr, equiv[i][j].rname, equiv[i][j].aname); } fprintf(out, "\n"); } } -static gmx_bool is_equiv(int neq, t_equiv **equiv, char **nname, - int rnr1, char *rname1, char *aname1, - int rnr2, char *rname2, char *aname2) +static gmx_bool +is_equiv(int neq, t_equiv** equiv, char** nname, int rnr1, char* rname1, char* aname1, int rnr2, char* rname2, char* aname2) { int i, j; gmx_bool bFound; @@ -256,9 +262,8 @@ static gmx_bool is_equiv(int neq, t_equiv **equiv, char **nname, /* find first atom */ for (j = 0; equiv[i][j].set && !bFound; j++) { - bFound = ( equiv[i][j].rnr == rnr1 && - std::strcmp(equiv[i][j].rname, rname1) == 0 && - std::strcmp(equiv[i][j].aname, aname1) == 0 ); + bFound = (equiv[i][j].rnr == rnr1 && std::strcmp(equiv[i][j].rname, rname1) == 0 + && std::strcmp(equiv[i][j].aname, aname1) == 0); } if (bFound) { @@ -266,29 +271,31 @@ static gmx_bool is_equiv(int neq, t_equiv **equiv, char **nname, bFound = FALSE; for (j = 0; equiv[i][j].set && !bFound; j++) { - bFound = ( equiv[i][j].rnr == rnr2 && - std::strcmp(equiv[i][j].rname, rname2) == 0 && - std::strcmp(equiv[i][j].aname, aname2) == 0 ); + bFound = (equiv[i][j].rnr == rnr2 && std::strcmp(equiv[i][j].rname, rname2) == 0 + && std::strcmp(equiv[i][j].aname, aname2) == 0); } } } if (bFound) { - *nname = gmx_strdup(equiv[i-1][0].nname); + *nname = gmx_strdup(equiv[i - 1][0].nname); } return bFound; } -static int analyze_noe_equivalent(const char *eq_fn, - const t_atoms *atoms, int isize, const int *index, - gmx_bool bSumH, - int *noe_index, t_noe_gr *noe_gr) +static int analyze_noe_equivalent(const char* eq_fn, + const t_atoms* atoms, + int isize, + const int* index, + gmx_bool bSumH, + int* noe_index, + t_noe_gr* noe_gr) { int i, j, anmil, anmjl, rnri, rnrj, gi, groupnr, neq; - char *anmi, *anmj, **nnm; + char * anmi, *anmj, **nnm; gmx_bool bMatch, bEquiv; - t_equiv **equiv; + t_equiv** equiv; snew(nnm, isize); if (bSumH) @@ -310,18 +317,17 @@ static int analyze_noe_equivalent(const char *eq_fn, groupnr = 0; for (i = 0; i < isize; i++) { - if (equiv && i < isize-1) + if (equiv && i < isize - 1) { /* check explicit list of equivalent atoms */ do { - j = i+1; + j = i + 1; rnri = atoms->atom[index[i]].resind; rnrj = atoms->atom[index[j]].resind; - bEquiv = - is_equiv(neq, equiv, &nnm[i], - rnri, *atoms->resinfo[rnri].name, *atoms->atomname[index[i]], - rnrj, *atoms->resinfo[rnrj].name, *atoms->atomname[index[j]]); + bEquiv = is_equiv(neq, equiv, &nnm[i], rnri, *atoms->resinfo[rnri].name, + *atoms->atomname[index[i]], rnrj, *atoms->resinfo[rnrj].name, + *atoms->atomname[index[j]]); if (nnm[i] && bEquiv) { nnm[j] = gmx_strdup(nnm[i]); @@ -333,8 +339,7 @@ static int analyze_noe_equivalent(const char *eq_fn, /* skip matching atom */ i = j; } - } - while (bEquiv && i < isize-1); + } while (bEquiv && i < isize - 1); } else { @@ -347,15 +352,16 @@ static int analyze_noe_equivalent(const char *eq_fn, This is supposed to cover all CH3 groups and the like */ anmi = *atoms->atomname[index[i]]; anmil = std::strlen(anmi); - bMatch = i <= isize-3 && anmi[anmil-1] == '1'; + bMatch = i <= isize - 3 && anmi[anmil - 1] == '1'; if (bMatch) { for (j = 1; j < 3; j++) { - anmj = *atoms->atomname[index[i+j]]; + anmj = *atoms->atomname[index[i + j]]; anmjl = std::strlen(anmj); - bMatch = bMatch && ( anmil == anmjl && anmj[anmjl-1] == Hnum[j] && - std::strncmp(anmi, anmj, anmil-1) == 0 ); + bMatch = bMatch + && (anmil == anmjl && anmj[anmjl - 1] == Hnum[j] + && std::strncmp(anmi, anmj, anmil - 1) == 0); } } /* set index for this atom */ @@ -365,7 +371,7 @@ static int analyze_noe_equivalent(const char *eq_fn, /* set index for next two matching atoms */ for (j = 1; j < 3; j++) { - noe_index[i+j] = groupnr; + noe_index[i + j] = groupnr; } /* skip matching atoms */ i += 2; @@ -410,9 +416,9 @@ static int analyze_noe_equivalent(const char *eq_fn, else { noe_gr[gi].aname = gmx_strdup(*atoms->atomname[index[i]]); - if (noe_index[i] == noe_index[i+1]) + if (noe_index[i] == noe_index[i + 1]) { - noe_gr[gi].aname[std::strlen(noe_gr[gi].aname)-1] = '*'; + noe_gr[gi].aname[std::strlen(noe_gr[gi].aname) - 1] = '*'; } } noe_gr[gi].rnr = atoms->atom[index[i]].resind; @@ -420,9 +426,8 @@ static int analyze_noe_equivalent(const char *eq_fn, /* dump group definitions */ if (debug) { - fprintf(debug, "%d %d %d %d %s %s %d\n", i, gi, - noe_gr[gi].ianr, noe_gr[gi].anr, noe_gr[gi].aname, - noe_gr[gi].rname, noe_gr[gi].rnr); + fprintf(debug, "%d %d %d %d %s %s %d\n", i, gi, noe_gr[gi].ianr, noe_gr[gi].anr, + noe_gr[gi].aname, noe_gr[gi].rname, noe_gr[gi].rnr); } } } @@ -441,16 +446,16 @@ static int analyze_noe_equivalent(const char *eq_fn, /* }; */ #define NSCALE 6 -static char *noe2scale(real r3, real r6, real rmax) +static char* noe2scale(real r3, real r6, real rmax) { int i, s3, s6; - static char buf[NSCALE+1]; + static char buf[NSCALE + 1]; /* r goes from 0 to rmax NSCALE*r/rmax goes from 0 to NSCALE NSCALE - NSCALE*r/rmax goes from NSCALE to 0 */ - s3 = NSCALE - std::min(NSCALE, static_cast(NSCALE*r3/rmax)); - s6 = NSCALE - std::min(NSCALE, static_cast(NSCALE*r6/rmax)); + s3 = NSCALE - std::min(NSCALE, static_cast(NSCALE * r3 / rmax)); + s6 = NSCALE - std::min(NSCALE, static_cast(NSCALE * r6 / rmax)); for (i = 0; i < s3; i++) { @@ -465,8 +470,7 @@ static char *noe2scale(real r3, real r6, real rmax) return buf; } -static void calc_noe(int isize, const int *noe_index, - real **dtot1_3, real **dtot1_6, int gnr, t_noe **noe) +static void calc_noe(int isize, const int* noe_index, real** dtot1_3, real** dtot1_6, int gnr, t_noe** noe) { int i, j, gi, gj; @@ -478,24 +482,24 @@ static void calc_noe(int isize, const int *noe_index, { gj = noe_index[j]; noe[gi][gj].nr++; - noe[gi][gj].i_3 += 1.0/gmx::power3(dtot1_3[i][j]); - noe[gi][gj].i_6 += 1.0/gmx::power6(dtot1_6[i][j]); + noe[gi][gj].i_3 += 1.0 / gmx::power3(dtot1_3[i][j]); + noe[gi][gj].i_6 += 1.0 / gmx::power6(dtot1_6[i][j]); } } /* make averages */ for (i = 0; i < gnr; i++) { - for (j = i+1; j < gnr; j++) + for (j = i + 1; j < gnr; j++) { - noe[i][j].r_3 = gmx::invcbrt(noe[i][j].i_3/static_cast(noe[i][j].nr)); - noe[i][j].r_6 = gmx::invsixthroot(noe[i][j].i_6/static_cast(noe[i][j].nr)); + noe[i][j].r_3 = gmx::invcbrt(noe[i][j].i_3 / static_cast(noe[i][j].nr)); + noe[i][j].r_6 = gmx::invsixthroot(noe[i][j].i_6 / static_cast(noe[i][j].nr)); noe[j][i] = noe[i][j]; } } } -static void write_noe(FILE *fp, int gnr, t_noe **noe, t_noe_gr *noe_gr, real rmax) +static void write_noe(FILE* fp, int gnr, t_noe** noe, t_noe_gr* noe_gr, real rmax) { int i, j; real r3, r6, min3, min6; @@ -503,14 +507,13 @@ static void write_noe(FILE *fp, int gnr, t_noe **noe, t_noe_gr *noe_gr, real rma t_noe_gr gri, grj; min3 = min6 = 1e6; - fprintf(fp, - ";%4s %3s %4s %4s%3s %4s %4s %4s %4s%3s %5s %5s %8s %2s %2s %s\n", - "ianr", "anr", "anm", "rnm", "rnr", "ianr", "anr", "anm", "rnm", "rnr", - "1/r^3", "1/r^6", "intnsty", "Dr", "Da", "scale"); + fprintf(fp, ";%4s %3s %4s %4s%3s %4s %4s %4s %4s%3s %5s %5s %8s %2s %2s %s\n", "ianr", "anr", + "anm", "rnm", "rnr", "ianr", "anr", "anm", "rnm", "rnr", "1/r^3", "1/r^6", "intnsty", + "Dr", "Da", "scale"); for (i = 0; i < gnr; i++) { gri = noe_gr[i]; - for (j = i+1; j < gnr; j++) + for (j = i + 1; j < gnr; j++) { grj = noe_gr[j]; r3 = noe[i][j].r_3; @@ -521,7 +524,7 @@ static void write_noe(FILE *fp, int gnr, t_noe **noe, t_noe_gr *noe_gr, real rma { if (grj.rnr == gri.rnr) { - sprintf(buf, "%2d", grj.anr-gri.anr); + sprintf(buf, "%2d", grj.anr - gri.anr); } else { @@ -543,12 +546,10 @@ static void write_noe(FILE *fp, int gnr, t_noe **noe, t_noe_gr *noe_gr, real rma { std::strcpy(b6, "-"); } - fprintf(fp, - "%4d %4d %4s %4s%3d %4d %4d %4s %4s%3d %5s %5s %8d %2d %2s %s\n", - gri.ianr+1, gri.anr+1, gri.aname, gri.rname, gri.rnr+1, - grj.ianr+1, grj.anr+1, grj.aname, grj.rname, grj.rnr+1, - b3, b6, gmx::roundToInt(noe[i][j].i_6), grj.rnr-gri.rnr, buf, - noe2scale(r3, r6, rmax)); + fprintf(fp, "%4d %4d %4s %4s%3d %4d %4d %4s %4s%3d %5s %5s %8d %2d %2s %s\n", + gri.ianr + 1, gri.anr + 1, gri.aname, gri.rname, gri.rnr + 1, grj.ianr + 1, + grj.anr + 1, grj.aname, grj.rname, grj.rnr + 1, b3, b6, + gmx::roundToInt(noe[i][j].i_6), grj.rnr - gri.rnr, buf, noe2scale(r3, r6, rmax)); } } } @@ -557,46 +558,53 @@ static void write_noe(FILE *fp, int gnr, t_noe **noe, t_noe_gr *noe_gr, real rma { if (MINI > rmax) { - fprintf(stdout, "NOTE: no 1/r^%d averaged distances found below %g, " - "smallest was %g\n", i, rmax, MINI ); + fprintf(stdout, + "NOTE: no 1/r^%d averaged distances found below %g, " + "smallest was %g\n", + i, rmax, MINI); } else { - fprintf(stdout, "Smallest 1/r^%d averaged distance was %g\n", i, MINI ); + fprintf(stdout, "Smallest 1/r^%d averaged distance was %g\n", i, MINI); } } #undef MINI } -static void calc_rms(int nind, int nframes, - real **dtot, real **dtot2, - real **rmsmat, real *rmsmax, - real **rmscmat, real *rmscmax, - real **meanmat, real *meanmax) +static void calc_rms(int nind, + int nframes, + real** dtot, + real** dtot2, + real** rmsmat, + real* rmsmax, + real** rmscmat, + real* rmscmax, + real** meanmat, + real* meanmax) { - int i, j; - real mean, mean2, rms, rmsc; -/* N.B. dtot and dtot2 contain the total distance and the total squared - * distance respectively, BUT they return RMS and the scaled RMS resp. - */ + int i, j; + real mean, mean2, rms, rmsc; + /* N.B. dtot and dtot2 contain the total distance and the total squared + * distance respectively, BUT they return RMS and the scaled RMS resp. + */ *rmsmax = -1000; *rmscmax = -1000; *meanmax = -1000; - for (i = 0; (i < nind-1); i++) + for (i = 0; (i < nind - 1); i++) { - for (j = i+1; (j < nind); j++) + for (j = i + 1; (j < nind); j++) { - mean = dtot[i][j]/static_cast(nframes); - mean2 = dtot2[i][j]/static_cast(nframes); - rms = std::sqrt(std::max(0.0_real, mean2-mean*mean)); - rmsc = rms/mean; + mean = dtot[i][j] / static_cast(nframes); + mean2 = dtot2[i][j] / static_cast(nframes); + rms = std::sqrt(std::max(0.0_real, mean2 - mean * mean)); + rmsc = rms / mean; if (mean > *meanmax) { *meanmax = mean; } - if (rms > *rmsmax) + if (rms > *rmsmax) { *rmsmax = rms; } @@ -605,34 +613,34 @@ static void calc_rms(int nind, int nframes, *rmscmax = rmsc; } meanmat[i][j] = meanmat[j][i] = mean; - rmsmat[i][j] = rmsmat[j][i] = rms; + rmsmat[i][j] = rmsmat[j][i] = rms; rmscmat[i][j] = rmscmat[j][i] = rmsc; } } } -static real rms_diff(int natom, real **d, real **d_r) +static real rms_diff(int natom, real** d, real** d_r) { int i, j; real r, r2; r2 = 0.0; - for (i = 0; (i < natom-1); i++) + for (i = 0; (i < natom - 1); i++) { - for (j = i+1; (j < natom); j++) + for (j = i + 1; (j < natom); j++) { - r = d[i][j]-d_r[i][j]; - r2 += r*r; + r = d[i][j] - d_r[i][j]; + r2 += r * r; } } - r2 /= gmx::exactDiv(natom*(natom-1), 2); + r2 /= gmx::exactDiv(natom * (natom - 1), 2); return std::sqrt(r2); } -int gmx_rmsdist(int argc, char *argv[]) +int gmx_rmsdist(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the root mean square deviation of atom distances,", "which has the advantage that no fit is needed like in standard RMS", "deviation as computed by [gmx-rms].", @@ -656,62 +664,57 @@ int gmx_rmsdist(int argc, char *argv[]) }; - int i, teller; - real t; - - t_topology top; - int ePBC; - t_atoms *atoms; - matrix box; - rvec *x; - FILE *fp; - - t_trxstatus *status; - int isize, gnr = 0; - int *index, *noe_index; - char *grpname; - real **d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr; - real **dtot1_3 = nullptr, **dtot1_6 = nullptr; - real rmsnow, meanmax, rmsmax, rmscmax; - real max1_3, max1_6; - t_noe_gr *noe_gr = nullptr; - t_noe **noe = nullptr; - t_rgb rlo, rhi; - gmx_bool bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR; + int i, teller; + real t; + + t_topology top; + int ePBC; + t_atoms* atoms; + matrix box; + rvec* x; + FILE* fp; + + t_trxstatus* status; + int isize, gnr = 0; + int * index, *noe_index; + char* grpname; + real ** d_r, **d, **dtot, **dtot2, **mean, **rms, **rmsc, *resnr; + real ** dtot1_3 = nullptr, **dtot1_6 = nullptr; + real rmsnow, meanmax, rmsmax, rmscmax; + real max1_3, max1_6; + t_noe_gr* noe_gr = nullptr; + t_noe** noe = nullptr; + t_rgb rlo, rhi; + gmx_bool bRMS, bScale, bMean, bNOE, bNMR3, bNMR6, bNMR; static int nlevels = 40; static real scalemax = -1.0; static gmx_bool bSumH = TRUE; static gmx_bool bPBC = TRUE; - gmx_output_env_t *oenv; - - t_pargs pa[] = { - { "-nlevels", FALSE, etINT, {&nlevels}, - "Discretize RMS in this number of levels" }, - { "-max", FALSE, etREAL, {&scalemax}, - "Maximum level in matrices" }, - { "-sumh", FALSE, etBOOL, {&bSumH}, - "Average distance over equivalent hydrogens" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, + gmx_output_env_t* oenv; + + t_pargs pa[] = { + { "-nlevels", FALSE, etINT, { &nlevels }, "Discretize RMS in this number of levels" }, + { "-max", FALSE, etREAL, { &scalemax }, "Maximum level in matrices" }, + { "-sumh", FALSE, etBOOL, { &bSumH }, "Average distance over equivalent hydrogens" }, + { "-pbc", + FALSE, + etBOOL, + { &bPBC }, "Use periodic boundary conditions when computing distances" } }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-equiv", "equiv", ffOPTRD }, - { efXVG, nullptr, "distrmsd", ffWRITE }, - { efXPM, "-rms", "rmsdist", ffOPTWR }, - { efXPM, "-scl", "rmsscale", ffOPTWR }, - { efXPM, "-mean", "rmsmean", ffOPTWR }, - { efXPM, "-nmr3", "nmr3", ffOPTWR }, - { efXPM, "-nmr6", "nmr6", ffOPTWR }, - { efDAT, "-noe", "noe", ffOPTWR }, + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efDAT, "-equiv", "equiv", ffOPTRD }, + { efXVG, nullptr, "distrmsd", ffWRITE }, { efXPM, "-rms", "rmsdist", ffOPTWR }, + { efXPM, "-scl", "rmsscale", ffOPTWR }, { efXPM, "-mean", "rmsmean", ffOPTWR }, + { efXPM, "-nmr3", "nmr3", ffOPTWR }, { efXPM, "-nmr6", "nmr6", ffOPTWR }, + { efDAT, "-noe", "noe", ffOPTWR }, }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -731,8 +734,10 @@ int gmx_rmsdist(int argc, char *argv[]) if (bNOE && scalemax < 0) { scalemax = 0.6; - fprintf(stderr, "WARNING: using -noe without -max " - "makes no sense, setting -max to %g\n\n", scalemax); + fprintf(stderr, + "WARNING: using -noe without -max " + "makes no sense, setting -max to %g\n\n", + scalemax); } /* get topology and index */ @@ -774,7 +779,7 @@ int gmx_rmsdist(int argc, char *argv[]) snew(rms[i], isize); snew(rmsc[i], isize); snew(d_r[i], isize); - resnr[i] = i+1; + resnr[i] = i + 1; } /*set box type*/ @@ -782,8 +787,7 @@ int gmx_rmsdist(int argc, char *argv[]) sfree(x); /*open output files*/ - fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)", - oenv); + fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS Deviation", "Time (ps)", "RMSD (nm)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp, "@ subtitle \"of distances between %s atoms\"\n", grpname); @@ -800,8 +804,7 @@ int gmx_rmsdist(int argc, char *argv[]) rmsnow = rms_diff(isize, d, d_r); fprintf(fp, "%g %g\n", t, rmsnow); teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); xvgrclose(fp); @@ -828,12 +831,11 @@ int gmx_rmsdist(int argc, char *argv[]) if (bNOE) { /* make list of noe atom groups */ - snew(noe_index, isize+1); + snew(noe_index, isize + 1); snew(noe_gr, isize); - gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm), - atoms, isize, index, bSumH, noe_index, noe_gr); - fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n", - gnr, isize); + gnr = analyze_noe_equivalent(opt2fn_null("-equiv", NFILE, fnm), atoms, isize, index, bSumH, + noe_index, noe_gr); + fprintf(stdout, "Found %d non-equivalent atom-groups in %d atoms\n", gnr, isize); /* make half matrix of of noe-group distances from atom distances */ snew(noe, gnr); for (i = 0; i < gnr; i++) @@ -843,41 +845,43 @@ int gmx_rmsdist(int argc, char *argv[]) calc_noe(isize, noe_index, dtot1_3, dtot1_6, gnr, noe); } - rlo.r = 1.0; rlo.g = 1.0; rlo.b = 1.0; - rhi.r = 0.0; rhi.g = 0.0; rhi.b = 0.0; + rlo.r = 1.0; + rlo.g = 1.0; + rlo.b = 1.0; + rhi.r = 0.0; + rhi.g = 0.0; + rhi.b = 0.0; if (bRMS) { - write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0, - "RMS of distance", "RMS (nm)", "Atom Index", "Atom Index", - isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels); + write_xpm(opt2FILE("-rms", NFILE, fnm, "w"), 0, "RMS of distance", "RMS (nm)", "Atom Index", + "Atom Index", isize, isize, resnr, resnr, rms, 0.0, rmsmax, rlo, rhi, &nlevels); } if (bScale) { - write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0, - "Relative RMS", "RMS", "Atom Index", "Atom Index", - isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels); + write_xpm(opt2FILE("-scl", NFILE, fnm, "w"), 0, "Relative RMS", "RMS", "Atom Index", + "Atom Index", isize, isize, resnr, resnr, rmsc, 0.0, rmscmax, rlo, rhi, &nlevels); } if (bMean) { - write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, - "Mean Distance", "Distance (nm)", "Atom Index", "Atom Index", - isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, rhi, &nlevels); + write_xpm(opt2FILE("-mean", NFILE, fnm, "w"), 0, "Mean Distance", "Distance (nm)", + "Atom Index", "Atom Index", isize, isize, resnr, resnr, mean, 0.0, meanmax, rlo, + rhi, &nlevels); } if (bNMR3) { write_xpm(opt2FILE("-nmr3", NFILE, fnm, "w"), 0, "1/r^3 averaged distances", - "Distance (nm)", "Atom Index", "Atom Index", - isize, isize, resnr, resnr, dtot1_3, 0.0, max1_3, rlo, rhi, &nlevels); + "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_3, + 0.0, max1_3, rlo, rhi, &nlevels); } if (bNMR6) { write_xpm(opt2FILE("-nmr6", NFILE, fnm, "w"), 0, "1/r^6 averaged distances", - "Distance (nm)", "Atom Index", "Atom Index", - isize, isize, resnr, resnr, dtot1_6, 0.0, max1_6, rlo, rhi, &nlevels); + "Distance (nm)", "Atom Index", "Atom Index", isize, isize, resnr, resnr, dtot1_6, + 0.0, max1_6, rlo, rhi, &nlevels); } if (bNOE) diff --git a/src/gromacs/gmxana/gmx_rmsf.cpp b/src/gromacs/gmxana/gmx_rmsf.cpp index 87af428628..e2fe3c133a 100644 --- a/src/gromacs/gmxana/gmx_rmsf.cpp +++ b/src/gromacs/gmxana/gmx_rmsf.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static real find_pdb_bfac(const t_atoms *atoms, t_resinfo *ri, char *atomnm) +static real find_pdb_bfac(const t_atoms* atoms, t_resinfo* ri, char* atomnm) { char rresnm[8]; int i; @@ -70,18 +70,17 @@ static real find_pdb_bfac(const t_atoms *atoms, t_resinfo *ri, char *atomnm) rresnm[3] = '\0'; for (i = 0; (i < atoms->nr); i++) { - if ((ri->nr == atoms->resinfo[atoms->atom[i].resind].nr) && - (ri->ic == atoms->resinfo[atoms->atom[i].resind].ic) && - (std::strcmp(*atoms->resinfo[atoms->atom[i].resind].name, rresnm) == 0) && - (std::strstr(*atoms->atomname[i], atomnm) != nullptr)) + if ((ri->nr == atoms->resinfo[atoms->atom[i].resind].nr) + && (ri->ic == atoms->resinfo[atoms->atom[i].resind].ic) + && (std::strcmp(*atoms->resinfo[atoms->atom[i].resind].name, rresnm) == 0) + && (std::strstr(*atoms->atomname[i], atomnm) != nullptr)) { break; } } if (i == atoms->nr) { - fprintf(stderr, "\rCan not find %s%d-%s in pdbfile\n", - rresnm, ri->nr, atomnm); + fprintf(stderr, "\rCan not find %s%d-%s in pdbfile\n", rresnm, ri->nr, atomnm); fflush(stderr); return 0.0; } @@ -89,14 +88,12 @@ static real find_pdb_bfac(const t_atoms *atoms, t_resinfo *ri, char *atomnm) return atoms->pdbinfo[i].bfac; } -static void correlate_aniso(const char *fn, t_atoms *ref, t_atoms *calc, - const gmx_output_env_t *oenv) +static void correlate_aniso(const char* fn, t_atoms* ref, t_atoms* calc, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; int i, j; - fp = xvgropen(fn, "Correlation between X-Ray and Computed Uij", "X-Ray", - "Computed", oenv); + fp = xvgropen(fn, "Correlation between X-Ray and Computed Uij", "X-Ray", "Computed", oenv); for (i = 0; (i < ref->nr); i++) { if (ref->pdbinfo[i].bAnisotropic) @@ -110,9 +107,13 @@ static void correlate_aniso(const char *fn, t_atoms *ref, t_atoms *calc, xvgrclose(fp); } -static void average_residues(double f[], double **U, int uind, - int isize, const int index[], const real w_rls[], - const t_atoms *atoms) +static void average_residues(double f[], + double** U, + int uind, + int isize, + const int index[], + const real w_rls[], + const t_atoms* atoms) { int i, j, start; double av, m; @@ -126,10 +127,9 @@ static void average_residues(double f[], double **U, int uind, } for (i = 0; i < isize; i++) { - av += w_rls[index[i]]*(f != nullptr ? f[i] : U[i][uind]); - m += w_rls[index[i]]; - if (i+1 == isize || - atoms->atom[index[i]].resind != atoms->atom[index[i+1]].resind) + av += w_rls[index[i]] * (f != nullptr ? f[i] : U[i][uind]); + m += w_rls[index[i]]; + if (i + 1 == isize || atoms->atom[index[i]].resind != atoms->atom[index[i + 1]].resind) { av /= m; if (f != nullptr) @@ -146,32 +146,32 @@ static void average_residues(double f[], double **U, int uind, U[j][uind] = av; } } - start = i+1; + start = i + 1; av = 0; m = 0; } } } -static void print_dir(FILE *fp, real *Uaver) +static void print_dir(FILE* fp, real* Uaver) { - real eigvec[DIM*DIM]; - real tmp[DIM*DIM]; + real eigvec[DIM * DIM]; + real tmp[DIM * DIM]; rvec eigval; int d, m; fprintf(fp, "MSF X Y Z\n"); for (d = 0; d < DIM; d++) { - fprintf(fp, " %c ", 'X'+d-XX); + fprintf(fp, " %c ", 'X' + d - XX); for (m = 0; m < DIM; m++) { - fprintf(fp, " %9.2e", Uaver[3*m+d]); + fprintf(fp, " %9.2e", Uaver[3 * m + d]); } fprintf(fp, "%s\n", m == DIM ? " (nm^2)" : ""); } - for (m = 0; m < DIM*DIM; m++) + for (m = 0; m < DIM * DIM; m++) { tmp[m] = Uaver[m]; } @@ -180,22 +180,21 @@ static void print_dir(FILE *fp, real *Uaver) eigensolver(tmp, DIM, 0, DIM, eigval, eigvec); fprintf(fp, "\n Eigenvectors\n\n"); - fprintf(fp, "Eigv %-8.2e %-8.2e %-8.2e (nm^2)\n\n", - eigval[2], eigval[1], eigval[0]); + fprintf(fp, "Eigv %-8.2e %-8.2e %-8.2e (nm^2)\n\n", eigval[2], eigval[1], eigval[0]); for (d = 0; d < DIM; d++) { - fprintf(fp, " %c ", 'X'+d-XX); - for (m = DIM-1; m >= 0; m--) + fprintf(fp, " %c ", 'X' + d - XX); + for (m = DIM - 1; m >= 0; m--) { - fprintf(fp, "%7.4f ", eigvec[3*m+d]); + fprintf(fp, "%7.4f ", eigvec[3 * m + d]); } fprintf(fp, "\n"); } } -int gmx_rmsf(int argc, char *argv[]) +int gmx_rmsf(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the root mean square fluctuation (RMSF, i.e. standard ", "deviation) of atomic positions in the trajectory (supplied with [TT]-f[tt])", "after (optionally) fitting to a reference frame (supplied with [TT]-s[tt]).[PAR]", @@ -224,68 +223,62 @@ int gmx_rmsf(int argc, char *argv[]) "This shows the directions in which the atoms fluctuate the most and", "the least." }; - static gmx_bool bRes = FALSE, bAniso = FALSE, bFit = TRUE; - t_pargs pargs[] = { - { "-res", FALSE, etBOOL, {&bRes}, - "Calculate averages for each residue" }, - { "-aniso", FALSE, etBOOL, {&bAniso}, - "Compute anisotropic termperature factors" }, - { "-fit", FALSE, etBOOL, {&bFit}, - "Do a least squares superposition before computing RMSF. Without this you must make sure that the reference structure and the trajectory match." } - }; - int natom; - int i, m, teller = 0; - real t, *w_rls; - - t_topology top; - int ePBC; - t_atoms *pdbatoms, *refatoms; - - matrix box, pdbbox; - rvec *x, *pdbx, *xref; - t_trxstatus *status; - const char *label; - - FILE *fp; /* the graphics file */ - const char *devfn, *dirfn; - int resind; - - gmx_bool bReadPDB; - int *index; - int isize; - char *grpnames; - - real bfac, pdb_bfac, *Uaver; - double **U, *xav; - int aid; - rvec *rmsd_x = nullptr; - double *rmsf, invcount, totmass; - int d; - real count = 0; - rvec xcm; - gmx_rmpbc_t gpbc = nullptr; - - gmx_output_env_t *oenv; - - const char *leg[2] = { "MD", "X-Ray" }; - - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efPDB, "-q", nullptr, ffOPTRD }, - { efPDB, "-oq", "bfac", ffOPTWR }, - { efPDB, "-ox", "xaver", ffOPTWR }, - { efXVG, "-o", "rmsf", ffWRITE }, - { efXVG, "-od", "rmsdev", ffOPTWR }, - { efXVG, "-oc", "correl", ffOPTWR }, - { efLOG, "-dir", "rmsf", ffOPTWR } + static gmx_bool bRes = FALSE, bAniso = FALSE, bFit = TRUE; + t_pargs pargs[] = { + { "-res", FALSE, etBOOL, { &bRes }, "Calculate averages for each residue" }, + { "-aniso", FALSE, etBOOL, { &bAniso }, "Compute anisotropic termperature factors" }, + { "-fit", + FALSE, + etBOOL, + { &bFit }, + "Do a least squares superposition before computing RMSF. Without this you must " + "make sure that the reference structure and the trajectory match." } }; + int natom; + int i, m, teller = 0; + real t, *w_rls; + + t_topology top; + int ePBC; + t_atoms * pdbatoms, *refatoms; + + matrix box, pdbbox; + rvec * x, *pdbx, *xref; + t_trxstatus* status; + const char* label; + + FILE* fp; /* the graphics file */ + const char *devfn, *dirfn; + int resind; + + gmx_bool bReadPDB; + int* index; + int isize; + char* grpnames; + + real bfac, pdb_bfac, *Uaver; + double ** U, *xav; + int aid; + rvec* rmsd_x = nullptr; + double * rmsf, invcount, totmass; + int d; + real count = 0; + rvec xcm; + gmx_rmpbc_t gpbc = nullptr; + + gmx_output_env_t* oenv; + + const char* leg[2] = { "MD", "X-Ray" }; + + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efPDB, "-q", nullptr, ffOPTRD }, + { efPDB, "-oq", "bfac", ffOPTWR }, { efPDB, "-ox", "xaver", ffOPTWR }, + { efXVG, "-o", "rmsf", ffWRITE }, { efXVG, "-od", "rmsdev", ffOPTWR }, + { efXVG, "-oc", "correl", ffOPTWR }, { efLOG, "-dir", "rmsf", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pargs), pargs, asize(desc), desc, 0, nullptr, - &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pargs), + pargs, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -295,7 +288,7 @@ int gmx_rmsf(int argc, char *argv[]) dirfn = opt2fn_null("-dir", NFILE, fnm); read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xref, nullptr, box, TRUE); - const char *title = *top.name; + const char* title = *top.name; snew(w_rls, top.atoms.nr); fprintf(stderr, "Select group(s) for root mean square calculation\n"); @@ -308,11 +301,11 @@ int gmx_rmsf(int argc, char *argv[]) } /* Malloc the rmsf arrays */ - snew(xav, isize*DIM); + snew(xav, isize * DIM); snew(U, isize); for (i = 0; i < isize; i++) { - snew(U[i], DIM*DIM); + snew(U[i], DIM * DIM); } snew(rmsf, isize); if (devfn) @@ -322,7 +315,7 @@ int gmx_rmsf(int argc, char *argv[]) if (bReadPDB) { - t_topology *top_pdb; + t_topology* top_pdb; snew(top_pdb, 1); /* Read coordinates twice */ read_tps_conf(opt2fn("-q", NFILE, fnm), top_pdb, nullptr, nullptr, nullptr, pdbbox, FALSE); @@ -338,9 +331,9 @@ int gmx_rmsf(int argc, char *argv[]) } else { - pdbatoms = &top.atoms; - refatoms = &top.atoms; - pdbx = xref; + pdbatoms = &top.atoms; + refatoms = &top.atoms; + pdbx = xref; snew(pdbatoms->pdbinfo, pdbatoms->nr); pdbatoms->havePdbInfo = TRUE; copy_mat(box, pdbbox); @@ -380,10 +373,10 @@ int gmx_rmsf(int argc, char *argv[]) aid = index[i]; for (d = 0; d < DIM; d++) { - xav[i*DIM + d] += x[aid][d]; + xav[i * DIM + d] += x[aid][d]; for (m = 0; m < DIM; m++) { - U[i][d*DIM + m] += x[aid][d]*x[aid][m]; + U[i][d * DIM + m] += x[aid][d] * x[aid][m]; } } } @@ -396,14 +389,13 @@ int gmx_rmsf(int argc, char *argv[]) aid = index[i]; for (d = 0; (d < DIM); d++) { - rmsd_x[i][d] += gmx::square(x[aid][d]-xref[aid][d]); + rmsd_x[i][d] += gmx::square(x[aid][d] - xref[aid][d]); } } } count += 1.0; teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); if (bFit) @@ -412,34 +404,33 @@ int gmx_rmsf(int argc, char *argv[]) } - invcount = 1.0/count; - snew(Uaver, DIM*DIM); + invcount = 1.0 / count; + snew(Uaver, DIM * DIM); totmass = 0; for (i = 0; i < isize; i++) { for (d = 0; d < DIM; d++) { - xav[i*DIM + d] *= invcount; + xav[i * DIM + d] *= invcount; } for (d = 0; d < DIM; d++) { for (m = 0; m < DIM; m++) { - U[i][d*DIM + m] = U[i][d*DIM + m]*invcount - - xav[i*DIM + d]*xav[i*DIM + m]; - Uaver[3*d+m] += top.atoms.atom[index[i]].m*U[i][d*DIM + m]; + U[i][d * DIM + m] = U[i][d * DIM + m] * invcount - xav[i * DIM + d] * xav[i * DIM + m]; + Uaver[3 * d + m] += top.atoms.atom[index[i]].m * U[i][d * DIM + m]; } } totmass += top.atoms.atom[index[i]].m; } - for (d = 0; d < DIM*DIM; d++) + for (d = 0; d < DIM * DIM; d++) { Uaver[d] /= totmass; } if (bRes) { - for (d = 0; d < DIM*DIM; d++) + for (d = 0; d < DIM * DIM; d++) { average_residues(nullptr, U, d, isize, index, w_rls, &top.atoms); } @@ -449,14 +440,14 @@ int gmx_rmsf(int argc, char *argv[]) { for (i = 0; i < isize; i++) { - aid = index[i]; + aid = index[i]; pdbatoms->pdbinfo[aid].bAnisotropic = TRUE; - pdbatoms->pdbinfo[aid].uij[U11] = static_cast(1e6*U[i][XX*DIM + XX]); - pdbatoms->pdbinfo[aid].uij[U22] = static_cast(1e6*U[i][YY*DIM + YY]); - pdbatoms->pdbinfo[aid].uij[U33] = static_cast(1e6*U[i][ZZ*DIM + ZZ]); - pdbatoms->pdbinfo[aid].uij[U12] = static_cast(1e6*U[i][XX*DIM + YY]); - pdbatoms->pdbinfo[aid].uij[U13] = static_cast(1e6*U[i][XX*DIM + ZZ]); - pdbatoms->pdbinfo[aid].uij[U23] = static_cast(1e6*U[i][YY*DIM + ZZ]); + pdbatoms->pdbinfo[aid].uij[U11] = static_cast(1e6 * U[i][XX * DIM + XX]); + pdbatoms->pdbinfo[aid].uij[U22] = static_cast(1e6 * U[i][YY * DIM + YY]); + pdbatoms->pdbinfo[aid].uij[U33] = static_cast(1e6 * U[i][ZZ * DIM + ZZ]); + pdbatoms->pdbinfo[aid].uij[U12] = static_cast(1e6 * U[i][XX * DIM + YY]); + pdbatoms->pdbinfo[aid].uij[U13] = static_cast(1e6 * U[i][XX * DIM + ZZ]); + pdbatoms->pdbinfo[aid].uij[U23] = static_cast(1e6 * U[i][YY * DIM + ZZ]); } } if (bRes) @@ -470,7 +461,7 @@ int gmx_rmsf(int argc, char *argv[]) for (i = 0; i < isize; i++) { - rmsf[i] = U[i][XX*DIM + XX] + U[i][YY*DIM + YY] + U[i][ZZ*DIM + ZZ]; + rmsf[i] = U[i][XX * DIM + XX] + U[i][YY * DIM + YY] + U[i][ZZ * DIM + ZZ]; } if (dirfn) @@ -491,22 +482,21 @@ int gmx_rmsf(int argc, char *argv[]) /* Write RMSF output */ if (bReadPDB) { - bfac = 8.0*M_PI*M_PI/3.0*100; - fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "B-Factors", - label, "(A\\b\\S\\So\\N\\S2\\N)", oenv); + bfac = 8.0 * M_PI * M_PI / 3.0 * 100; + fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "B-Factors", label, "(A\\b\\S\\So\\N\\S2\\N)", oenv); xvgr_legend(fp, 2, leg, oenv); for (i = 0; (i < isize); i++) { - if (!bRes || i+1 == isize || - top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) + if (!bRes || i + 1 == isize + || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind) { - resind = top.atoms.atom[index[i]].resind; - pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind], - *(top.atoms.atomname[index[i]])); + resind = top.atoms.atom[index[i]].resind; + pdb_bfac = find_pdb_bfac(pdbatoms, &top.atoms.resinfo[resind], + *(top.atoms.atomname[index[i]])); fprintf(fp, "%5d %10.5f %10.5f\n", - bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, rmsf[i]*bfac, - pdb_bfac); + bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1, + rmsf[i] * bfac, pdb_bfac); } } xvgrclose(fp); @@ -516,11 +506,12 @@ int gmx_rmsf(int argc, char *argv[]) fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "RMS fluctuation", label, "(nm)", oenv); for (i = 0; i < isize; i++) { - if (!bRes || i+1 == isize || - top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) + if (!bRes || i + 1 == isize + || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind) { fprintf(fp, "%5d %8.4f\n", - bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i])); + bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1, + std::sqrt(rmsf[i])); } } xvgrclose(fp); @@ -528,14 +519,14 @@ int gmx_rmsf(int argc, char *argv[]) for (i = 0; i < isize; i++) { - pdbatoms->pdbinfo[index[i]].bfac = 800*M_PI*M_PI/3.0*rmsf[i]; + pdbatoms->pdbinfo[index[i]].bfac = 800 * M_PI * M_PI / 3.0 * rmsf[i]; } if (devfn) { for (i = 0; i < isize; i++) { - rmsf[i] = (rmsd_x[i][XX]+rmsd_x[i][YY]+rmsd_x[i][ZZ])/count; + rmsf[i] = (rmsd_x[i][XX] + rmsd_x[i][YY] + rmsd_x[i][ZZ]) / count; } if (bRes) { @@ -545,11 +536,12 @@ int gmx_rmsf(int argc, char *argv[]) fp = xvgropen(devfn, "RMS Deviation", label, "(nm)", oenv); for (i = 0; i < isize; i++) { - if (!bRes || i+1 == isize || - top.atoms.atom[index[i]].resind != top.atoms.atom[index[i+1]].resind) + if (!bRes || i + 1 == isize + || top.atoms.atom[index[i]].resind != top.atoms.atom[index[i + 1]].resind) { fprintf(fp, "%5d %8.4f\n", - bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i]+1, std::sqrt(rmsf[i])); + bRes ? top.atoms.resinfo[top.atoms.atom[index[i]].resind].nr : index[i] + 1, + std::sqrt(rmsf[i])); } } xvgrclose(fp); @@ -562,23 +554,23 @@ int gmx_rmsf(int argc, char *argv[]) { rvec_inc(pdbx[index[i]], xcm); } - write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, - nullptr, ePBC, pdbbox, isize, index); + write_sto_conf_indexed(opt2fn("-oq", NFILE, fnm), title, pdbatoms, pdbx, nullptr, ePBC, + pdbbox, isize, index); } if (opt2bSet("-ox", NFILE, fnm)) { - rvec *bFactorX; + rvec* bFactorX; snew(bFactorX, top.atoms.nr); for (i = 0; i < isize; i++) { for (d = 0; d < DIM; d++) { - bFactorX[index[i]][d] = xcm[d] + xav[i*DIM + d]; + bFactorX[index[i]][d] = xcm[d] + xav[i * DIM + d]; } } /* Write a .pdb file with B-factors and optionally anisou records */ - write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr, - ePBC, pdbbox, isize, index); + write_sto_conf_indexed(opt2fn("-ox", NFILE, fnm), title, pdbatoms, bFactorX, nullptr, ePBC, + pdbbox, isize, index); sfree(bFactorX); } if (bAniso) diff --git a/src/gromacs/gmxana/gmx_rotacf.cpp b/src/gromacs/gmxana/gmx_rotacf.cpp index 809f6c051c..63d21d22c7 100644 --- a/src/gromacs/gmxana/gmx_rotacf.cpp +++ b/src/gromacs/gmxana/gmx_rotacf.cpp @@ -53,9 +53,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -int gmx_rotacf(int argc, char *argv[]) +int gmx_rotacf(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates the rotational correlation function", "for molecules. Atom triplets (i,j,k) must be given in the index", "file, defining two vectors ij and jk. The rotational ACF", @@ -74,46 +74,46 @@ int gmx_rotacf(int argc, char *argv[]) "file. The correlation function will be fitted from 2.5 ps until 20.0 ps", "to a two-parameter exponential." }; - static gmx_bool bVec = FALSE, bAver = TRUE; + static gmx_bool bVec = FALSE, bAver = TRUE; - t_pargs pa[] = { - { "-d", FALSE, etBOOL, {&bVec}, + t_pargs pa[] = { + { "-d", + FALSE, + etBOOL, + { &bVec }, "Use index doublets (vectors) for correlation function instead of triplets (planes)" }, - { "-aver", FALSE, etBOOL, {&bAver}, - "Average over molecules" } + { "-aver", FALSE, etBOOL, { &bAver }, "Average over molecules" } }; - t_trxstatus *status; - int isize; - int *index; - char *grpname; - rvec *x, *x_s; - matrix box; - real **c1; - rvec xij, xjk, n; - int i, m, teller, n_alloc, natoms, nvec, ai, aj, ak; - unsigned long mode; - real t, t0, t1, dt; - gmx_rmpbc_t gpbc = nullptr; - t_topology *top; - int ePBC; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffREAD }, - { efXVG, "-o", "rotacf", ffWRITE } - }; + t_trxstatus* status; + int isize; + int* index; + char* grpname; + rvec * x, *x_s; + matrix box; + real** c1; + rvec xij, xjk, n; + int i, m, teller, n_alloc, natoms, nvec, ai, aj, ak; + unsigned long mode; + real t, t0, t1, dt; + gmx_rmpbc_t gpbc = nullptr; + t_topology* top; + int ePBC; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffREAD }, + { efXVG, "-o", "rotacf", ffWRITE } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; @@ -123,21 +123,23 @@ int gmx_rotacf(int argc, char *argv[]) if (bVec) { - nvec = isize/2; + nvec = isize / 2; } else { - nvec = isize/3; + nvec = isize / 3; } if (((isize % 3) != 0) && !bVec) { - gmx_fatal(FARGS, "number of index elements not multiple of 3, " + gmx_fatal(FARGS, + "number of index elements not multiple of 3, " "these can not be atom triplets\n"); } if (((isize % 2) != 0) && bVec) { - gmx_fatal(FARGS, "number of index elements not multiple of 2, " + gmx_fatal(FARGS, + "number of index elements not multiple of 2, " "these can not be atom doublets\n"); } @@ -156,8 +158,8 @@ int gmx_rotacf(int argc, char *argv[]) gpbc = gmx_rmpbc_init(&(top->idef), ePBC, natoms); /* Start the loop over frames */ - t0 = t; - teller = 0; + t0 = t; + teller = 0; do { if (teller >= n_alloc) @@ -165,7 +167,7 @@ int gmx_rotacf(int argc, char *argv[]) n_alloc += 100; for (i = 0; (i < nvec); i++) { - srenew(c1[i], DIM*n_alloc); + srenew(c1[i], DIM * n_alloc); } } t1 = t; @@ -180,15 +182,15 @@ int gmx_rotacf(int argc, char *argv[]) { for (i = 0; (i < nvec); i++) { - ai = index[3*i]; - aj = index[3*i+1]; - ak = index[3*i+2]; + ai = index[3 * i]; + aj = index[3 * i + 1]; + ak = index[3 * i + 2]; rvec_sub(x_s[ai], x_s[aj], xij); rvec_sub(x_s[aj], x_s[ak], xjk); cprod(xij, xjk, n); for (m = 0; (m < DIM); m++) { - c1[i][DIM*teller+m] = n[m]; + c1[i][DIM * teller + m] = n[m]; } } } @@ -196,19 +198,18 @@ int gmx_rotacf(int argc, char *argv[]) { for (i = 0; (i < nvec); i++) { - ai = index[2*i]; - aj = index[2*i+1]; + ai = index[2 * i]; + aj = index[2 * i + 1]; rvec_sub(x_s[ai], x_s[aj], n); for (m = 0; (m < DIM); m++) { - c1[i][DIM*teller+m] = n[m]; + c1[i][DIM * teller + m] = n[m]; } } } /* Increment loop counter */ teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); fprintf(stderr, "\nDone with trajectory\n"); @@ -222,12 +223,12 @@ int gmx_rotacf(int argc, char *argv[]) } else { - dt = (t1 - t0)/(static_cast(teller-1)); + dt = (t1 - t0) / (static_cast(teller - 1)); mode = eacVector; - do_autocorr(ftp2fn(efXVG, NFILE, fnm), oenv, "Rotational Correlation Function", - teller, nvec, c1, dt, mode, bAver); + do_autocorr(ftp2fn(efXVG, NFILE, fnm), oenv, "Rotational Correlation Function", teller, + nvec, c1, dt, mode, bAver); } do_view(oenv, ftp2fn(efXVG, NFILE, fnm), nullptr); diff --git a/src/gromacs/gmxana/gmx_rotmat.cpp b/src/gromacs/gmxana/gmx_rotmat.cpp index ea5c2f4222..9aa0fd82ca 100644 --- a/src/gromacs/gmxana/gmx_rotmat.cpp +++ b/src/gromacs/gmxana/gmx_rotmat.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2009-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,18 +56,25 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int skip, - int gnx, int *index, - gmx_bool bMW, const t_topology *top, int ePBC, rvec *x_ref) +static void get_refx(gmx_output_env_t* oenv, + const char* trxfn, + int nfitdim, + int skip, + int gnx, + int* index, + gmx_bool bMW, + const t_topology* top, + int ePBC, + rvec* x_ref) { int natoms, nfr_all, nfr, i, j, a, r, c, min_fr; - t_trxstatus *status; - real *ti, min_t; + t_trxstatus* status; + real * ti, min_t; double tot_mass, msd, *srmsd, min_srmsd, srmsd_tot; - rvec *x, **xi; + rvec * x, **xi; real xf; matrix box, R; - real *w_rls; + real* w_rls; gmx_rmpbc_t gpbc = nullptr; @@ -82,9 +90,11 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int { if (index[a] >= natoms) { - gmx_fatal(FARGS, "Atom index (%d) is larger than the number of atoms in the trajecory (%d)", index[a]+1, natoms); + gmx_fatal(FARGS, + "Atom index (%d) is larger than the number of atoms in the trajecory (%d)", + index[a] + 1, natoms); } - w_rls[a] = (bMW ? top->atoms.atom[index[a]].m : 1.0); + w_rls[a] = (bMW ? top->atoms.atom[index[a]].m : 1.0); tot_mass += w_rls[a]; } gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); @@ -103,13 +113,12 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int nfr++; if (nfr % 100 == 0) { - srenew(ti, nfr+100); - srenew(xi, nfr+100); + srenew(ti, nfr + 100); + srenew(xi, nfr + 100); } } nfr_all++; - } - while (read_next_x(oenv, status, &ti[nfr], x, box)); + } while (read_next_x(oenv, status, &ti[nfr], x, box)); close_trx(status); sfree(x); @@ -120,7 +129,7 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int { fprintf(stdout, "\rProcessing frame %d of %d", i, nfr); fflush(stdout); - for (j = i+1; j < nfr; j++) + for (j = i + 1; j < nfr; j++) { calc_fit_R(nfitdim, gnx, w_rls, xi[i], xi[j], R); @@ -132,12 +141,12 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int xf = 0; for (c = 0; c < DIM; c++) { - xf += R[r][c]*xi[j][a][c]; + xf += R[r][c] * xi[j][a][c]; } - msd += w_rls[a]*gmx::square(xi[i][a][r] - xf); + msd += w_rls[a] * gmx::square(xi[i][a][r] - xf); } } - msd /= tot_mass; + msd /= tot_mass; srmsd[i] += std::sqrt(msd); srmsd[j] += std::sqrt(msd); } @@ -163,9 +172,8 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int } sfree(srmsd); - printf("Average RMSD between all structures: %.3f\n", srmsd_tot/nfr); - printf("Structure with lowest RMSD to all others: time %g, av. RMSD %.3f\n", - min_t, min_srmsd); + printf("Average RMSD between all structures: %.3f\n", srmsd_tot / nfr); + printf("Structure with lowest RMSD to all others: time %g, av. RMSD %.3f\n", min_t, min_srmsd); for (a = 0; a < gnx; a++) { @@ -175,9 +183,9 @@ static void get_refx(gmx_output_env_t *oenv, const char *trxfn, int nfitdim, int sfree(xi); } -int gmx_rotmat(int argc, char *argv[]) +int gmx_rotmat(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] plots the rotation matrix required for least squares fitting", "a conformation onto the reference conformation provided with", "[TT]-s[tt]. Translation is removed before fitting.", @@ -203,46 +211,43 @@ int gmx_rotmat(int argc, char *argv[]) "Option [TT]-fitxy[tt] fits in the [IT]x-y[it] plane before determining", "the rotation matrix." }; - const char *reffit[] = - { nullptr, "none", "xyz", "xy", nullptr }; - static int skip = 1; - static gmx_bool bFitXY = FALSE, bMW = TRUE; - t_pargs pa[] = { - { "-ref", FALSE, etENUM, {reffit}, - "Determine the optimal reference structure" }, - { "-skip", FALSE, etINT, {&skip}, - "Use every nr-th frame for [TT]-ref[tt]" }, - { "-fitxy", FALSE, etBOOL, {&bFitXY}, + const char* reffit[] = { nullptr, "none", "xyz", "xy", nullptr }; + static int skip = 1; + static gmx_bool bFitXY = FALSE, bMW = TRUE; + t_pargs pa[] = { + { "-ref", FALSE, etENUM, { reffit }, "Determine the optimal reference structure" }, + { "-skip", FALSE, etINT, { &skip }, "Use every nr-th frame for [TT]-ref[tt]" }, + { "-fitxy", + FALSE, + etBOOL, + { &bFitXY }, "Fit the x/y rotation before determining the rotation" }, - { "-mw", FALSE, etBOOL, {&bMW}, - "Use mass weighted fitting" } + { "-mw", FALSE, etBOOL, { &bMW }, "Use mass weighted fitting" } }; - FILE *out; - t_trxstatus *status; + FILE* out; + t_trxstatus* status; t_topology top; int ePBC; - rvec *x_ref, *x; + rvec * x_ref, *x; matrix box, R; real t; int natoms, i; - char *grpname; + char* grpname; int gnx; gmx_rmpbc_t gpbc = nullptr; - int *index; - gmx_output_env_t *oenv; - real *w_rls; - const char *leg[] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" }; + int* index; + gmx_output_env_t* oenv; + real* w_rls; + const char* leg[] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" }; #define NLEG asize(leg) - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "rotmat", ffWRITE } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efXVG, nullptr, "rotmat", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -258,8 +263,8 @@ int gmx_rotmat(int argc, char *argv[]) GMX_RELEASE_ASSERT(reffit[0] != nullptr, "Options inconsistency; reffit[0] is NULL"); if (reffit[0][0] != 'n') { - get_refx(oenv, ftp2fn(efTRX, NFILE, fnm), reffit[0][2] == 'z' ? 3 : 2, skip, - gnx, index, bMW, &top, ePBC, x_ref); + get_refx(oenv, ftp2fn(efTRX, NFILE, fnm), reffit[0][2] == 'z' ? 3 : 2, skip, gnx, index, + bMW, &top, ePBC, x_ref); } natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); @@ -269,7 +274,9 @@ int gmx_rotmat(int argc, char *argv[]) { if (index[i] >= natoms) { - gmx_fatal(FARGS, "Atom index (%d) is larger than the number of atoms in the trajecory (%d)", index[i]+1, natoms); + gmx_fatal(FARGS, + "Atom index (%d) is larger than the number of atoms in the trajecory (%d)", + index[i] + 1, natoms); } w_rls[index[i]] = (bMW ? top.atoms.atom[index[i]].m : 1.0); } @@ -279,8 +286,7 @@ int gmx_rotmat(int argc, char *argv[]) reset_x(gnx, index, natoms, nullptr, x_ref, w_rls); } - out = xvgropen(ftp2fn(efXVG, NFILE, fnm), - "Fit matrix", "Time (ps)", "", oenv); + out = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Fit matrix", "Time (ps)", "", oenv); xvgr_legend(out, NLEG, leg, oenv); do @@ -296,14 +302,9 @@ int gmx_rotmat(int argc, char *argv[]) calc_fit_R(DIM, natoms, w_rls, x_ref, x, R); - fprintf(out, - "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n", - t, - R[XX][XX], R[XX][YY], R[XX][ZZ], - R[YY][XX], R[YY][YY], R[YY][ZZ], - R[ZZ][XX], R[ZZ][YY], R[ZZ][ZZ]); - } - while (read_next_x(oenv, status, &t, x, box)); + fprintf(out, "%7g %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f %7.4f\n", t, R[XX][XX], + R[XX][YY], R[XX][ZZ], R[YY][XX], R[YY][YY], R[YY][ZZ], R[ZZ][XX], R[ZZ][YY], R[ZZ][ZZ]); + } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); diff --git a/src/gromacs/gmxana/gmx_saltbr.cpp b/src/gromacs/gmxana/gmx_saltbr.cpp index b44d98d539..225004499a 100644 --- a/src/gromacs/gmxana/gmx_saltbr.cpp +++ b/src/gromacs/gmxana/gmx_saltbr.cpp @@ -53,15 +53,16 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { - char *label; +typedef struct +{ + char* label; int cg; real q; } t_charge; -static t_charge *mk_charge(const t_atoms *atoms, int *nncg) +static t_charge* mk_charge(const t_atoms* atoms, int* nncg) { - t_charge *cg = nullptr; + t_charge* cg = nullptr; char buf[32]; int i, ncg, resnr, anr; real qq; @@ -73,15 +74,12 @@ static t_charge *mk_charge(const t_atoms *atoms, int *nncg) qq = atoms->atom[i].q; if (std::abs(qq) > 1.0e-5) { - srenew(cg, ncg+1); + srenew(cg, ncg + 1); cg[ncg].q = qq; cg[ncg].cg = i; anr = i; resnr = atoms->atom[anr].resind; - sprintf(buf, "%s%d-%d", - *(atoms->resinfo[resnr].name), - atoms->resinfo[resnr].nr, - anr+1); + sprintf(buf, "%s%d-%d", *(atoms->resinfo[resnr].name), atoms->resinfo[resnr].nr, anr + 1); cg[ncg].label = gmx_strdup(buf); ncg++; } @@ -90,8 +88,7 @@ static t_charge *mk_charge(const t_atoms *atoms, int *nncg) for (i = 0; (i < ncg); i++) { - printf("CG: %10s Q: %6g Atoms:", - cg[i].label, cg[i].q); + printf("CG: %10s Q: %6g Atoms:", cg[i].label, cg[i].q); printf(" %4d", cg[i].cg); printf("\n"); } @@ -99,62 +96,61 @@ static t_charge *mk_charge(const t_atoms *atoms, int *nncg) return cg; } -int gmx_saltbr(int argc, char *argv[]) +int gmx_saltbr(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] plots the distance between all combination of charged groups", "as a function of time. The groups are combined in different ways.", "A minimum distance can be given (i.e. a cut-off), such that groups", "that are never closer than that distance will not be plotted.[PAR]", "Output will be in a number of fixed filenames, [TT]min-min.xvg[tt], [TT]plus-min.xvg[tt]", "and [TT]plus-plus.xvg[tt], or files for every individual ion pair if the [TT]-sep[tt]", - "option is selected. In this case, files are named as [TT]sb-(Resname)(Resnr)-(Atomnr)[tt].", + "option is selected. In this case, files are named as ", + "[TT]sb-(Resname)(Resnr)-(Atomnr)[tt].", "There may be [BB]many[bb] such files." }; static gmx_bool bSep = FALSE; static real truncate = 1000.0; - t_pargs pa[] = { - { "-t", FALSE, etREAL, {&truncate}, - "Groups that are never closer than this distance are not plotted" }, - { "-sep", FALSE, etBOOL, {&bSep}, - "Use separate files for each interaction (may be MANY)" } - }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, + t_pargs pa[] = { { "-t", + FALSE, + etREAL, + { &truncate }, + "Groups that are never closer than this distance are not plotted" }, + { "-sep", + FALSE, + etBOOL, + { &bSep }, + "Use separate files for each interaction (may be MANY)" } }; + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, }; #define NFILE asize(fnm) - FILE *out[3], *fp; - static const char *title[3] = { - "Distance between positively charged groups", - "Distance between negatively charged groups", - "Distance between oppositely charged groups" - }; - static const char *fn[3] = { - "plus-plus.xvg", - "min-min.xvg", - "plus-min.xvg" - }; - int nset[3] = {0, 0, 0}; + FILE * out[3], *fp; + static const char* title[3] = { "Distance between positively charged groups", + "Distance between negatively charged groups", + "Distance between oppositely charged groups" }; + static const char* fn[3] = { "plus-plus.xvg", "min-min.xvg", "plus-min.xvg" }; + int nset[3] = { 0, 0, 0 }; - t_topology *top; - int ePBC; - char *buf; - t_trxstatus *status; - int i, j, k, m, nnn, teller, ncg; - real t, *time, qi, qj; - t_charge *cg; - real ***cgdist; - int **nWithin; + t_topology* top; + int ePBC; + char* buf; + t_trxstatus* status; + int i, j, k, m, nnn, teller, ncg; + real t, *time, qi, qj; + t_charge* cg; + real*** cgdist; + int** nWithin; - t_pbc pbc; - rvec *x; - matrix box; - gmx_output_env_t *oenv; + t_pbc pbc; + rvec* x; + matrix box; + gmx_output_env_t* oenv; - if (!parse_common_args(&argc, argv, PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } @@ -175,16 +171,16 @@ int gmx_saltbr(int argc, char *argv[]) time = nullptr; do { - srenew(time, teller+1); + srenew(time, teller + 1); time[teller] = t; set_pbc(&pbc, ePBC, box); for (i = 0; (i < ncg); i++) { - for (j = i+1; (j < ncg); j++) + for (j = i + 1; (j < ncg); j++) { - srenew(cgdist[i][j], teller+1); + srenew(cgdist[i][j], teller + 1); rvec dx; pbc_dx(&pbc, x[cg[i].cg], x[cg[j].cg], dx); cgdist[i][j][teller] = norm(dx); @@ -196,8 +192,7 @@ int gmx_saltbr(int argc, char *argv[]) } teller++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); fprintf(stderr, "\n"); close_trx(status); @@ -206,7 +201,7 @@ int gmx_saltbr(int argc, char *argv[]) snew(buf, 256); for (i = 0; (i < ncg); i++) { - for (j = i+1; (j < ncg); j++) + for (j = i + 1; (j < ncg); j++) { if (nWithin[i][j]) { @@ -234,17 +229,17 @@ int gmx_saltbr(int argc, char *argv[]) for (i = 0; (i < ncg); i++) { qi = cg[i].q; - for (j = i+1; (j < ncg); j++) + for (j = i + 1; (j < ncg); j++) { qj = cg[j].q; if (nWithin[i][j]) { sprintf(buf, "%s:%s", cg[i].label, cg[j].label); - if (qi*qj < 0) + if (qi * qj < 0) { nnn = 2; } - else if (qi+qj > 0) + else if (qi + qj > 0) { nnn = 0; } @@ -269,7 +264,7 @@ int gmx_saltbr(int argc, char *argv[]) } } nset[nnn]++; - nWithin[i][j] = nnn+1; + nWithin[i][j] = nnn + 1; } } } @@ -282,12 +277,12 @@ int gmx_saltbr(int argc, char *argv[]) for (i = 0; (i < ncg); i++) { - for (j = i+1; (j < ncg); j++) + for (j = i + 1; (j < ncg); j++) { nnn = nWithin[i][j]; if (nnn > 0) { - fprintf(out[nnn-1], " %10g", cgdist[i][j][k]); + fprintf(out[nnn - 1], " %10g", cgdist[i][j][k]); } } } diff --git a/src/gromacs/gmxana/gmx_sans.cpp b/src/gromacs/gmxana/gmx_sans.cpp index b08c5dc36f..797ab499ef 100644 --- a/src/gromacs/gmxana/gmx_sans.cpp +++ b/src/gromacs/gmxana/gmx_sans.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,9 +59,9 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -int gmx_sans(int argc, char *argv[]) +int gmx_sans(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes SANS spectra using Debye formula.", "It currently uses topology file (since it need to assigne element for each atom).", "[PAR]", @@ -76,89 +76,87 @@ int gmx_sans(int argc, char *argv[]) "Note: When using Debye direct method computational cost increases as", "1/2 * N * (N - 1) where N is atom number in group of interest.", "[PAR]", - "WARNING: If sq or pr specified this tool can produce large number of files! Up to two times larger than number of frames!" + "WARNING: If sq or pr specified this tool can produce large number of files! Up to ", + "two times larger than number of frames!" }; - static gmx_bool bPBC = TRUE; - static gmx_bool bNORM = FALSE; - static real binwidth = 0.2, grid = 0.05; /* bins shouldn't be smaller then smallest bond (~0.1nm) length */ - static real start_q = 0.0, end_q = 2.0, q_step = 0.01; - static real mcover = -1; - static unsigned int seed = 0; - static int nthreads = -1; + static gmx_bool bPBC = TRUE; + static gmx_bool bNORM = FALSE; + static real binwidth = 0.2, + grid = 0.05; /* bins shouldn't be smaller then smallest bond (~0.1nm) length */ + static real start_q = 0.0, end_q = 2.0, q_step = 0.01; + static real mcover = -1; + static unsigned int seed = 0; + static int nthreads = -1; - static const char *emode[] = { nullptr, "direct", "mc", nullptr }; - static const char *emethod[] = { nullptr, "debye", "fft", nullptr }; + static const char* emode[] = { nullptr, "direct", "mc", nullptr }; + static const char* emethod[] = { nullptr, "debye", "fft", nullptr }; - gmx_neutron_atomic_structurefactors_t *gnsf; - gmx_sans_t *gsans; + gmx_neutron_atomic_structurefactors_t* gnsf; + gmx_sans_t* gsans; #define NPA asize(pa) - t_pargs pa[] = { - { "-bin", FALSE, etREAL, {&binwidth}, - "[HIDDEN]Binwidth (nm)" }, - { "-mode", FALSE, etENUM, {emode}, - "Mode for sans spectra calculation" }, - { "-mcover", FALSE, etREAL, {&mcover}, - "Monte-Carlo coverage should be -1(default) or (0,1]"}, - { "-method", FALSE, etENUM, {emethod}, - "[HIDDEN]Method for sans spectra calculation" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, + t_pargs pa[] = { + { "-bin", FALSE, etREAL, { &binwidth }, "[HIDDEN]Binwidth (nm)" }, + { "-mode", FALSE, etENUM, { emode }, "Mode for sans spectra calculation" }, + { "-mcover", + FALSE, + etREAL, + { &mcover }, + "Monte-Carlo coverage should be -1(default) or (0,1]" }, + { "-method", FALSE, etENUM, { emethod }, "[HIDDEN]Method for sans spectra calculation" }, + { "-pbc", + FALSE, + etBOOL, + { &bPBC }, "Use periodic boundary conditions for computing distances" }, - { "-grid", FALSE, etREAL, {&grid}, - "[HIDDEN]Grid spacing (in nm) for FFTs" }, - {"-startq", FALSE, etREAL, {&start_q}, - "Starting q (1/nm) "}, - {"-endq", FALSE, etREAL, {&end_q}, - "Ending q (1/nm)"}, - { "-qstep", FALSE, etREAL, {&q_step}, - "Stepping in q (1/nm)"}, - { "-seed", FALSE, etINT, {&seed}, - "Random seed for Monte-Carlo"}, + { "-grid", FALSE, etREAL, { &grid }, "[HIDDEN]Grid spacing (in nm) for FFTs" }, + { "-startq", FALSE, etREAL, { &start_q }, "Starting q (1/nm) " }, + { "-endq", FALSE, etREAL, { &end_q }, "Ending q (1/nm)" }, + { "-qstep", FALSE, etREAL, { &q_step }, "Stepping in q (1/nm)" }, + { "-seed", FALSE, etINT, { &seed }, "Random seed for Monte-Carlo" }, #if GMX_OPENMP - { "-nt", FALSE, etINT, {&nthreads}, - "Number of threads to start"}, + { "-nt", FALSE, etINT, { &nthreads }, "Number of threads to start" }, #endif }; - FILE *fp; - const char *fnTPX, *fnTRX, *fnDAT = nullptr; - t_trxstatus *status; - t_topology *top = nullptr; - gmx_rmpbc_t gpbc = nullptr; - gmx_bool bFFT = FALSE, bDEBYE = FALSE; - gmx_bool bMC = FALSE; - int ePBC = -1; - matrix box; - rvec *x; - int natoms; - real t; - char **grpname = nullptr; - int *index = nullptr; - int isize; - int i; - char *hdr = nullptr; - char *suffix = nullptr; - gmx_radial_distribution_histogram_t *prframecurrent = nullptr, *pr = nullptr; - gmx_static_structurefactor_t *sqframecurrent = nullptr, *sq = nullptr; - gmx_output_env_t *oenv; + FILE* fp; + const char * fnTPX, *fnTRX, *fnDAT = nullptr; + t_trxstatus* status; + t_topology* top = nullptr; + gmx_rmpbc_t gpbc = nullptr; + gmx_bool bFFT = FALSE, bDEBYE = FALSE; + gmx_bool bMC = FALSE; + int ePBC = -1; + matrix box; + rvec* x; + int natoms; + real t; + char** grpname = nullptr; + int* index = nullptr; + int isize; + int i; + char* hdr = nullptr; + char* suffix = nullptr; + gmx_radial_distribution_histogram_t *prframecurrent = nullptr, *pr = nullptr; + gmx_static_structurefactor_t * sqframecurrent = nullptr, *sq = nullptr; + gmx_output_env_t* oenv; - std::array filenames = - { { { efTPR, "-s", nullptr, ffREAD }, - { efTRX, "-f", nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-d", "nsfactor", ffOPTRD }, - { efXVG, "-pr", "pr", ffWRITE }, - { efXVG, "-sq", "sq", ffWRITE }, - { efXVG, "-prframe", "prframe", ffOPTWR }, - { efXVG, "-sqframe", "sqframe", ffOPTWR } } }; - t_filenm *fnm = filenames.data(); + std::array filenames = { { { efTPR, "-s", nullptr, ffREAD }, + { efTRX, "-f", nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efDAT, "-d", "nsfactor", ffOPTRD }, + { efXVG, "-pr", "pr", ffWRITE }, + { efXVG, "-sq", "sq", ffWRITE }, + { efXVG, "-prframe", "prframe", ffOPTWR }, + { efXVG, "-sqframe", "sqframe", ffOPTWR } } }; + t_filenm* fnm = filenames.data(); const auto NFILE = filenames.size(); nthreads = gmx_omp_get_max_threads(); - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -178,21 +176,13 @@ int gmx_sans(int argc, char *argv[]) bDEBYE = TRUE; switch (emode[0][0]) { - case 'd': - bMC = FALSE; - break; - case 'm': - bMC = TRUE; - break; - default: - break; + case 'd': bMC = FALSE; break; + case 'm': bMC = TRUE; break; + default: break; } break; - case 'f': - bFFT = TRUE; - break; - default: - break; + case 'f': bFFT = TRUE; break; + default: break; } if (bDEBYE) @@ -221,7 +211,8 @@ int gmx_sans(int argc, char *argv[]) fnTRX = ftp2fn(efTRX, NFILE, fnm); gnsf = gmx_neutronstructurefactors_init(fnDAT); - fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n", gnsf->nratoms, fnDAT); + fprintf(stderr, "Read %d atom names from %s with neutron scattering parameters\n\n", + gnsf->nratoms, fnDAT); snew(top, 1); snew(grpname, 1); @@ -244,7 +235,8 @@ int gmx_sans(int argc, char *argv[]) natoms = read_first_x(oenv, &status, fnTRX, &t, &x, box); if (natoms != top->atoms.nr) { - fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", natoms, top->atoms.nr); + fprintf(stderr, "\nWARNING: number of atoms in tpx (%d) and trajectory (%d) do not match\n", + natoms, top->atoms.nr); } do @@ -260,7 +252,8 @@ int gmx_sans(int argc, char *argv[]) snew(pr, 1); } /* realy calc p(r) */ - prframecurrent = calc_radial_distribution_histogram(gsans, x, box, index, isize, binwidth, bMC, bNORM, mcover, seed); + prframecurrent = calc_radial_distribution_histogram(gsans, x, box, index, isize, binwidth, + bMC, bNORM, mcover, seed); /* copy prframecurrent -> pr and summ up pr->gr[i] */ /* allocate and/or resize memory for pr->gr[i] and pr->r[i] */ if (pr->gr == nullptr) @@ -284,7 +277,7 @@ int gmx_sans(int argc, char *argv[]) for (i = 0; i < prframecurrent->grn; i++) { pr->gr[i] += prframecurrent->gr[i]; - pr->r[i] = prframecurrent->r[i]; + pr->r[i] = prframecurrent->r[i]; } /* normalize histo */ normalize_probability(prframecurrent->grn, prframecurrent->gr); @@ -301,7 +294,8 @@ int gmx_sans(int argc, char *argv[]) auto fnmdup = filenames; sprintf(suffix, "-t%.2f", t); add_suffix_to_output_names(fnmdup.data(), NFILE, suffix); - fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup.data()), hdr, "Distance (nm)", "Probability", oenv); + fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup.data()), hdr, "Distance (nm)", + "Probability", oenv); for (i = 0; i < prframecurrent->grn; i++) { fprintf(fp, "%10.6f%10.6f\n", prframecurrent->r[i], prframecurrent->gr[i]); @@ -320,7 +314,8 @@ int gmx_sans(int argc, char *argv[]) auto fnmdup = filenames; sprintf(suffix, "-t%.2f", t); add_suffix_to_output_names(fnmdup.data(), NFILE, suffix); - fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup.data()), hdr, "q (nm^-1)", "s(q)/s(0)", oenv); + fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup.data()), hdr, "q (nm^-1)", + "s(q)/s(0)", oenv); for (i = 0; i < sqframecurrent->qn; i++) { fprintf(fp, "%10.6f%10.6f\n", sqframecurrent->q[i], sqframecurrent->s[i]); @@ -337,8 +332,7 @@ int gmx_sans(int argc, char *argv[]) sfree(sqframecurrent->q); sfree(sqframecurrent->s); sfree(sqframecurrent); - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); /* normalize histo */ diff --git a/src/gromacs/gmxana/gmx_saxs.cpp b/src/gromacs/gmxana/gmx_saxs.cpp index 6a7000bf45..afe2bc0f92 100644 --- a/src/gromacs/gmxana/gmx_saxs.cpp +++ b/src/gromacs/gmxana/gmx_saxs.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,41 +46,33 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -int gmx_saxs(int argc, char *argv[]) +int gmx_saxs(int argc, char* argv[]) { - const char *desc[] = { - "[THISMODULE] calculates SAXS structure factors for given index", - "groups based on Cromer's method.", - "Both topology and trajectory files are required." - }; + const char* desc[] = { "[THISMODULE] calculates SAXS structure factors for given index", + "groups based on Cromer's method.", + "Both topology and trajectory files are required." }; - static real start_q = 0.0, end_q = 60.0, energy = 12.0; - static int ngroups = 1; + static real start_q = 0.0, end_q = 60.0, energy = 12.0; + static int ngroups = 1; - t_pargs pa[] = { - { "-ng", FALSE, etINT, {&ngroups}, - "Number of groups to compute SAXS" }, - {"-startq", FALSE, etREAL, {&start_q}, - "Starting q (1/nm) "}, - {"-endq", FALSE, etREAL, {&end_q}, - "Ending q (1/nm)"}, - {"-energy", FALSE, etREAL, {&energy}, - "Energy of the incoming X-ray (keV) "} + t_pargs pa[] = { + { "-ng", FALSE, etINT, { &ngroups }, "Number of groups to compute SAXS" }, + { "-startq", FALSE, etREAL, { &start_q }, "Starting q (1/nm) " }, + { "-endq", FALSE, etREAL, { &end_q }, "Ending q (1/nm)" }, + { "-energy", FALSE, etREAL, { &energy }, "Energy of the incoming X-ray (keV) " } }; #define NPA asize(pa) - const char *fnTPS, *fnTRX, *fnNDX, *fnDAT = nullptr; - gmx_output_env_t *oenv; + const char * fnTPS, *fnTRX, *fnNDX, *fnDAT = nullptr; + gmx_output_env_t* oenv; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efDAT, "-d", "sfactor", ffOPTRD }, - { efXVG, "-sq", "sq", ffWRITE }, + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efDAT, "-d", "sfactor", ffOPTRD }, + { efXVG, "-sq", "sq", ffWRITE }, }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME, - NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, NPA, pa, asize(desc), desc, 0, + nullptr, &oenv)) { return 0; } @@ -90,9 +82,8 @@ int gmx_saxs(int argc, char *argv[]) fnDAT = ftp2fn(efDAT, NFILE, fnm); fnNDX = ftp2fn_null(efNDX, NFILE, fnm); - do_scattering_intensity(fnTPS, fnNDX, opt2fn("-sq", NFILE, fnm), - fnTRX, fnDAT, - start_q, end_q, energy, ngroups, oenv); + do_scattering_intensity(fnTPS, fnNDX, opt2fn("-sq", NFILE, fnm), fnTRX, fnDAT, start_q, end_q, + energy, ngroups, oenv); please_cite(stdout, "Cromer1968a"); diff --git a/src/gromacs/gmxana/gmx_sham.cpp b/src/gromacs/gmxana/gmx_sham.cpp index b8550687a2..f367d121e6 100644 --- a/src/gromacs/gmxana/gmx_sham.cpp +++ b/src/gromacs/gmxana/gmx_sham.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,49 +59,50 @@ #include "gromacs/utility/smalloc.h" -static int index2(const int *ibox, int x, int y) +static int index2(const int* ibox, int x, int y) { - return (ibox[1]*x+y); + return (ibox[1] * x + y); } -static int index3(const int *ibox, int x, int y, int z) +static int index3(const int* ibox, int x, int y, int z) { - return (ibox[2]*(ibox[1]*x+y)+z); + return (ibox[2] * (ibox[1] * x + y) + z); } -static int64_t indexn(int ndim, const int *ibox, const int *nxyz) +static int64_t indexn(int ndim, const int* ibox, const int* nxyz) { - int64_t d, dd; - int k, kk; + int64_t d, dd; + int k, kk; /* Compute index in 1-D array */ d = 0; for (k = 0; (k < ndim); k++) { dd = nxyz[k]; - for (kk = k+1; (kk < ndim); kk++) + for (kk = k + 1; (kk < ndim); kk++) { - dd = dd*ibox[kk]; + dd = dd * ibox[kk]; } d += dd; } return d; } -typedef struct { - int Nx; /* x grid points in unit cell */ - int Ny; /* y grid points in unit cell */ - int Nz; /* z grid points in unit cell */ - int dmin[3]; /* starting point x,y,z*/ - int dmax[3]; /* ending point x,y,z */ - real cell[6]; /* usual cell parameters */ - real * ed; /* data */ +typedef struct +{ + int Nx; /* x grid points in unit cell */ + int Ny; /* y grid points in unit cell */ + int Nz; /* z grid points in unit cell */ + int dmin[3]; /* starting point x,y,z*/ + int dmax[3]; /* ending point x,y,z */ + real cell[6]; /* usual cell parameters */ + real* ed; /* data */ } XplorMap; -static void lo_write_xplor(XplorMap * map, const char * file) +static void lo_write_xplor(XplorMap* map, const char* file) { - FILE * fp; - int z, i, j, n; + FILE* fp; + int z, i, j, n; fp = gmx_ffopen(file, "w"); /* The REMARKS part is the worst part of the XPLOR format @@ -110,12 +111,9 @@ static void lo_write_xplor(XplorMap * map, const char * file) fprintf(fp, "\n 2 !NTITLE\n"); fprintf(fp, " REMARKS Energy Landscape from GROMACS\n"); fprintf(fp, " REMARKS DATE: 2004-12-21 \n"); - fprintf(fp, " %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", - map->Nx, map->dmin[0], map->dmax[0], - map->Ny, map->dmin[1], map->dmax[1], - map->Nz, map->dmin[2], map->dmax[2]); - fprintf(fp, "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n", - map->cell[0], map->cell[1], map->cell[2], + fprintf(fp, " %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", map->Nx, map->dmin[0], map->dmax[0], + map->Ny, map->dmin[1], map->dmax[1], map->Nz, map->dmin[2], map->dmax[2]); + fprintf(fp, "%12.5E%12.5E%12.5E%12.5E%12.5E%12.5E\n", map->cell[0], map->cell[1], map->cell[2], map->cell[3], map->cell[4], map->cell[5]); fprintf(fp, "ZYX\n"); @@ -123,13 +121,13 @@ static void lo_write_xplor(XplorMap * map, const char * file) for (n = 0; n < map->Nz; n++, z++) { fprintf(fp, "%8d\n", z); - for (i = 0; i < map->Nx*map->Ny; i += 6) + for (i = 0; i < map->Nx * map->Ny; i += 6) { for (j = 0; j < 6; j++) { - if (i+j < map->Nx*map->Ny) + if (i + j < map->Nx * map->Ny) { - fprintf(fp, "%12.5E", map->ed[n*map->Nx*map->Ny+i+j]); + fprintf(fp, "%12.5E", map->ed[n * map->Nx * map->Ny + i + j]); } } fprintf(fp, "\n"); @@ -139,16 +137,16 @@ static void lo_write_xplor(XplorMap * map, const char * file) gmx_ffclose(fp); } -static void write_xplor(const char *file, const real *data, int *ibox, const real dmin[], const real dmax[]) +static void write_xplor(const char* file, const real* data, int* ibox, const real dmin[], const real dmax[]) { - XplorMap *xm; + XplorMap* xm; int i, j, k, n; snew(xm, 1); xm->Nx = ibox[XX]; xm->Ny = ibox[YY]; xm->Nz = ibox[ZZ]; - snew(xm->ed, xm->Nx*xm->Ny*xm->Nz); + snew(xm->ed, xm->Nx * xm->Ny * xm->Nz); n = 0; for (k = 0; (k < xm->Nz); k++) { @@ -160,15 +158,15 @@ static void write_xplor(const char *file, const real *data, int *ibox, const rea } } } - xm->cell[0] = dmax[XX]-dmin[XX]; - xm->cell[1] = dmax[YY]-dmin[YY]; - xm->cell[2] = dmax[ZZ]-dmin[ZZ]; + xm->cell[0] = dmax[XX] - dmin[XX]; + xm->cell[1] = dmax[YY] - dmin[YY]; + xm->cell[2] = dmax[ZZ] - dmin[ZZ]; xm->cell[3] = xm->cell[4] = xm->cell[5] = 90; clear_ivec(xm->dmin); - xm->dmax[XX] = ibox[XX]-1; - xm->dmax[YY] = ibox[YY]-1; - xm->dmax[ZZ] = ibox[ZZ]-1; + xm->dmax[XX] = ibox[XX] - 1; + xm->dmax[YY] = ibox[YY] - 1; + xm->dmax[ZZ] = ibox[ZZ] - 1; lo_write_xplor(xm, file); @@ -176,7 +174,7 @@ static void write_xplor(const char *file, const real *data, int *ibox, const rea sfree(xm); } -static void normalize_p_e(int len, double *P, const int *nbin, real *E, real pmin) +static void normalize_p_e(int len, double* P, const int* nbin, real* E, real pmin) { int i; double Ptot = 0; @@ -186,13 +184,13 @@ static void normalize_p_e(int len, double *P, const int *nbin, real *E, real pmi Ptot += P[i]; if (nbin[i] > 0) { - E[i] = E[i]/nbin[i]; + E[i] = E[i] / nbin[i]; } } printf("Ptot = %g\n", Ptot); for (i = 0; (i < len); i++) { - P[i] = P[i]/Ptot; + P[i] = P[i] / Ptot; /* Have to check for pmin after normalizing to prevent "stretching" * the energies. */ @@ -203,15 +201,17 @@ static void normalize_p_e(int len, double *P, const int *nbin, real *E, real pmi } } -typedef struct { - int64_t index; - real ener; +typedef struct +{ + int64_t index; + real ener; } t_minimum; -static int comp_minima(const void *a, const void *b) +static int comp_minima(const void* a, const void* b) { - const t_minimum *ma = reinterpret_cast(a); - const t_minimum *mb = reinterpret_cast(b);; + const t_minimum* ma = reinterpret_cast(a); + const t_minimum* mb = reinterpret_cast(b); + if (ma->ener < mb->ener) { @@ -227,54 +227,49 @@ static int comp_minima(const void *a, const void *b) } } -static inline -void print_minimum(FILE *fp, int num, const t_minimum *min) +static inline void print_minimum(FILE* fp, int num, const t_minimum* min) { fprintf(fp, - "Minimum %d at index " "%" PRId64 " energy %10.3f\n", + "Minimum %d at index " + "%" PRId64 " energy %10.3f\n", num, min->index, min->ener); } -static inline -void add_minimum(FILE *fp, int num, const t_minimum *min, t_minimum *mm) +static inline void add_minimum(FILE* fp, int num, const t_minimum* min, t_minimum* mm) { print_minimum(fp, num, min); mm[num].index = min->index; mm[num].ener = min->ener; } -static inline -gmx_bool is_local_minimum_from_below(const t_minimum *this_min, - int dimension_index, - int dimension_min, - int neighbour_index, - const real *W) +static inline gmx_bool is_local_minimum_from_below(const t_minimum* this_min, + int dimension_index, + int dimension_min, + int neighbour_index, + const real* W) { - return ((dimension_index == dimension_min) || - ((dimension_index > dimension_min) && - (this_min->ener < W[neighbour_index]))); + return ((dimension_index == dimension_min) + || ((dimension_index > dimension_min) && (this_min->ener < W[neighbour_index]))); /* Note over/underflow within W cannot occur. */ } -static inline -gmx_bool is_local_minimum_from_above(const t_minimum *this_min, - int dimension_index, - int dimension_max, - int neighbour_index, - const real *W) +static inline gmx_bool is_local_minimum_from_above(const t_minimum* this_min, + int dimension_index, + int dimension_max, + int neighbour_index, + const real* W) { - return ((dimension_index == dimension_max) || - ((dimension_index < dimension_max) && - (this_min->ener < W[neighbour_index]))); + return ((dimension_index == dimension_max) + || ((dimension_index < dimension_max) && (this_min->ener < W[neighbour_index]))); /* Note over/underflow within W cannot occur. */ } -static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real W[]) +static void pick_minima(const char* logfile, int* ibox, int ndim, int len, real W[]) { - FILE *fp; + FILE* fp; int i, j, k, nmin; t_minimum *mm, this_min; - int *this_point; + int* this_point; int loopmax, loopcounter; snew(mm, len); @@ -296,10 +291,10 @@ static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real /* Get the index of this point in the flat array */ this_min.index = index2(ibox, i, j); this_min.ener = W[this_min.index]; - if (is_local_minimum_from_below(&this_min, i, 0, index2(ibox, i-1, j ), W) && - is_local_minimum_from_above(&this_min, i, ibox[0]-1, index2(ibox, i+1, j ), W) && - is_local_minimum_from_below(&this_min, j, 0, index2(ibox, i, j-1), W) && - is_local_minimum_from_above(&this_min, j, ibox[1]-1, index2(ibox, i, j+1), W)) + if (is_local_minimum_from_below(&this_min, i, 0, index2(ibox, i - 1, j), W) + && is_local_minimum_from_above(&this_min, i, ibox[0] - 1, index2(ibox, i + 1, j), W) + && is_local_minimum_from_below(&this_min, j, 0, index2(ibox, i, j - 1), W) + && is_local_minimum_from_above(&this_min, j, ibox[1] - 1, index2(ibox, i, j + 1), W)) { add_minimum(fp, nmin, &this_min, mm); nmin++; @@ -317,12 +312,15 @@ static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real /* Get the index of this point in the flat array */ this_min.index = index3(ibox, i, j, k); this_min.ener = W[this_min.index]; - if (is_local_minimum_from_below(&this_min, i, 0, index3(ibox, i-1, j, k ), W) && - is_local_minimum_from_above(&this_min, i, ibox[0]-1, index3(ibox, i+1, j, k ), W) && - is_local_minimum_from_below(&this_min, j, 0, index3(ibox, i, j-1, k ), W) && - is_local_minimum_from_above(&this_min, j, ibox[1]-1, index3(ibox, i, j+1, k ), W) && - is_local_minimum_from_below(&this_min, k, 0, index3(ibox, i, j, k-1), W) && - is_local_minimum_from_above(&this_min, k, ibox[2]-1, index3(ibox, i, j, k+1), W)) + if (is_local_minimum_from_below(&this_min, i, 0, index3(ibox, i - 1, j, k), W) + && is_local_minimum_from_above(&this_min, i, ibox[0] - 1, + index3(ibox, i + 1, j, k), W) + && is_local_minimum_from_below(&this_min, j, 0, index3(ibox, i, j - 1, k), W) + && is_local_minimum_from_above(&this_min, j, ibox[1] - 1, + index3(ibox, i, j + 1, k), W) + && is_local_minimum_from_below(&this_min, k, 0, index3(ibox, i, j, k - 1), W) + && is_local_minimum_from_above(&this_min, k, ibox[2] - 1, + index3(ibox, i, j, k + 1), W)) { add_minimum(fp, nmin, &this_min, mm); nmin++; @@ -365,11 +363,13 @@ static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real * this_point array for use with indexn(). */ int index = this_point[i]; this_point[i]--; - bMin = bMin && - is_local_minimum_from_below(&this_min, index, 0, indexn(ndim, ibox, this_point), W); + bMin = bMin + && is_local_minimum_from_below(&this_min, index, 0, + indexn(ndim, ibox, this_point), W); this_point[i] += 2; - bMin = bMin && - is_local_minimum_from_above(&this_min, index, ibox[i]-1, indexn(ndim, ibox, this_point), W); + bMin = bMin + && is_local_minimum_from_above(&this_min, index, ibox[i] - 1, + indexn(ndim, ibox, this_point), W); this_point[i]--; } if (bMin) @@ -385,7 +385,7 @@ static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real if (loopmax > loopcounter) { /* update this_point non-recursively */ - i = ndim-1; + i = ndim - 1; this_point[i]++; while (ibox[i] == this_point[i]) { @@ -411,34 +411,50 @@ static void pick_minima(const char *logfile, int *ibox, int ndim, int len, real sfree(mm); } -static void do_sham(const char *fn, const char *ndx, - const char *xpmP, const char *xpm, const char *xpm2, - const char *xpm3, const char *pdb, - const char *logf, - int n, int neig, real **eig, - gmx_bool bGE, int nenerT, real **enerT, - real Tref, - real pmax, real gmax, - const real *emin, const real *emax, int nlevels, real pmin, - const int *idim, int *ibox, - gmx_bool bXmin, real *xmin, gmx_bool bXmax, real *xmax) +static void do_sham(const char* fn, + const char* ndx, + const char* xpmP, + const char* xpm, + const char* xpm2, + const char* xpm3, + const char* pdb, + const char* logf, + int n, + int neig, + real** eig, + gmx_bool bGE, + int nenerT, + real** enerT, + real Tref, + real pmax, + real gmax, + const real* emin, + const real* emax, + int nlevels, + real pmin, + const int* idim, + int* ibox, + gmx_bool bXmin, + real* xmin, + gmx_bool bXmax, + real* xmax) { - FILE *fp; - real *min_eig, *max_eig; - real *axis_x, *axis_y, *axis_z, *axis = nullptr; - double *P; - real **PP, *W, *E, **WW, **EE, *S, **SS, *M, *bE; + FILE* fp; + real * min_eig, *max_eig; + real * axis_x, *axis_y, *axis_z, *axis = nullptr; + double* P; + real ** PP, *W, *E, **WW, **EE, *S, **SS, *M, *bE; rvec xxx; - char *buf; - double *bfac, efac, bref, Pmax, Wmin, Wmax, Winf, Emin, Emax, Einf, Smin, Smax, Sinf; - real *delta; + char* buf; + double * bfac, efac, bref, Pmax, Wmin, Wmax, Winf, Emin, Emax, Einf, Smin, Smax, Sinf; + real* delta; int i, j, k, imin, len, index, *nbin, *bindex, bi; - int *nxyz, maxbox; - t_blocka *b; + int * nxyz, maxbox; + t_blocka* b; gmx_bool bOutside; unsigned int flags; - t_rgb rlo = { 0, 0, 0 }; - t_rgb rhi = { 1, 1, 1 }; + t_rgb rlo = { 0, 0, 0 }; + t_rgb rhi = { 1, 1, 1 }; /* Determine extremes for the eigenvectors */ snew(min_eig, neig); @@ -455,7 +471,7 @@ static void do_sham(const char *fn, const char *ndx, { min_eig[i] = std::min(min_eig[i], eig[i][j]); max_eig[i] = std::max(max_eig[i], eig[i][j]); - delta[i] = (max_eig[i]-min_eig[i])/(2.0*ibox[i]); + delta[i] = (max_eig[i] - min_eig[i]) / (2.0 * ibox[i]); } /* Add some extra space, half a bin on each side, unless the * user has set the limits. @@ -464,7 +480,8 @@ static void do_sham(const char *fn, const char *ndx, { if (max_eig[i] > xmax[i]) { - gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i, xmax[i], max_eig[i]); + gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i, + xmax[i], max_eig[i]); } max_eig[i] = xmax[i]; } @@ -477,7 +494,8 @@ static void do_sham(const char *fn, const char *ndx, { if (min_eig[i] < xmin[i]) { - gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i, xmin[i], min_eig[i]); + gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i, + xmin[i], min_eig[i]); } min_eig[i] = xmin[i]; } @@ -485,10 +503,10 @@ static void do_sham(const char *fn, const char *ndx, { min_eig[i] -= delta[i]; } - bfac[i] = ibox[i]/(max_eig[i]-min_eig[i]); + bfac[i] = ibox[i] / (max_eig[i] - min_eig[i]); } /* Do the binning */ - bref = 1/(BOLTZ*Tref); + bref = 1 / (BOLTZ * Tref); snew(bE, n); if (bGE || nenerT == 2) { @@ -498,13 +516,13 @@ static void do_sham(const char *fn, const char *ndx, { if (bGE) { - bE[j] = bref*enerT[0][j]; + bE[j] = bref * enerT[0][j]; } else { - bE[j] = (bref - 1/(BOLTZ*enerT[1][j]))*enerT[0][j]; + bE[j] = (bref - 1 / (BOLTZ * enerT[1][j])) * enerT[0][j]; } - Emin = std::min(Emin, static_cast(bE[j])); + Emin = std::min(Emin, static_cast(bE[j])); } } else @@ -514,10 +532,9 @@ static void do_sham(const char *fn, const char *ndx, len = 1; for (i = 0; (i < neig); i++) { - len = len*ibox[i]; + len = len * ibox[i]; } - printf("There are %d bins in the %d-dimensional histogram. Beta-Emin = %g\n", - len, neig, Emin); + printf("There are %d bins in the %d-dimensional histogram. Beta-Emin = %g\n", len, neig, Emin); snew(P, len); snew(W, len); snew(E, len); @@ -534,7 +551,7 @@ static void do_sham(const char *fn, const char *ndx, bOutside = FALSE; for (i = 0; (i < neig); i++) { - nxyz[i] = static_cast(bfac[i]*(eig[i][j]-min_eig[i])); + nxyz[i] = static_cast(bfac[i] * (eig[i][j] - min_eig[i])); if (nxyz[i] < 0 || nxyz[i] >= ibox[i]) { bOutside = TRUE; @@ -547,7 +564,7 @@ static void do_sham(const char *fn, const char *ndx, /* Compute the exponential factor */ if (enerT) { - efac = std::exp(-bE[j]+Emin); + efac = std::exp(-bE[j] + Emin); } else { @@ -566,7 +583,7 @@ static void do_sham(const char *fn, const char *ndx, } else if (idim[i] == -1) { - efac /= std::sin(DEG2RAD*eig[i][j]); + efac /= std::sin(DEG2RAD * eig[i][j]); } } /* Update the probability */ @@ -596,7 +613,7 @@ static void do_sham(const char *fn, const char *ndx, if (P[i] != 0) { Pmax = std::max(P[i], Pmax); - W[i] = -BOLTZ*Tref*std::log(P[i]); + W[i] = -BOLTZ * Tref * std::log(P[i]); if (W[i] < Wmin) { Wmin = W[i]; @@ -619,11 +636,11 @@ static void do_sham(const char *fn, const char *ndx, { Wmax -= Wmin; } - Winf = Wmax+1; - Einf = Emax+1; - Smin = Emin-Wmax; - Smax = Emax-Smin; - Sinf = Smax+1; + Winf = Wmax + 1; + Einf = Emax + 1; + Smin = Emin - Wmax; + Smax = Emax - Smin; + Sinf = Smax + 1; /* Write out the free energy as a function of bin index */ fp = gmx_ffopen(fn, "w"); for (i = 0; (i < len); i++) @@ -631,7 +648,7 @@ static void do_sham(const char *fn, const char *ndx, if (P[i] != 0) { W[i] -= Wmin; - S[i] = E[i]-W[i]-Smin; + S[i] = E[i] - W[i] - Smin; fprintf(fp, "%5d %10.5e %10.5e %10.5e\n", i, W[i], E[i], S[i]); } else @@ -644,18 +661,18 @@ static void do_sham(const char *fn, const char *ndx, gmx_ffclose(fp); /* Organize the structures in the bins */ snew(b, 1); - snew(b->index, len+1); + snew(b->index, len + 1); snew(b->a, n); b->index[0] = 0; for (i = 0; (i < len); i++) { - b->index[i+1] = b->index[i]+nbin[i]; - nbin[i] = 0; + b->index[i + 1] = b->index[i] + nbin[i]; + nbin[i] = 0; } for (i = 0; (i < n); i++) { - bi = bindex[i]; - b->a[b->index[bi]+nbin[bi]] = i; + bi = bindex[i]; + b->a[b->index[bi] + nbin[bi]] = i; nbin[bi]++; } /* Consistency check */ @@ -674,21 +691,21 @@ static void do_sham(const char *fn, const char *ndx, if (nbin[i] > 0) { fprintf(fp, "[ %d ]\n", i); - for (j = b->index[i]; (j < b->index[i+1]); j++) + for (j = b->index[i]; (j < b->index[i + 1]); j++) { - fprintf(fp, "%d\n", b->a[j]+1); + fprintf(fp, "%d\n", b->a[j] + 1); } } } gmx_ffclose(fp); - snew(axis_x, ibox[0]+1); - snew(axis_y, ibox[1]+1); - snew(axis_z, ibox[2]+1); + snew(axis_x, ibox[0] + 1); + snew(axis_y, ibox[1] + 1); + snew(axis_z, ibox[2] + 1); maxbox = std::max(ibox[0], std::max(ibox[1], ibox[2])); - snew(PP, maxbox*maxbox); - snew(WW, maxbox*maxbox); - snew(EE, maxbox*maxbox); - snew(SS, maxbox*maxbox); + snew(PP, maxbox * maxbox); + snew(WW, maxbox * maxbox); + snew(EE, maxbox * maxbox); + snew(SS, maxbox * maxbox); for (i = 0; (i < std::min(neig, 3)); i++) { switch (i) @@ -700,7 +717,7 @@ static void do_sham(const char *fn, const char *ndx, } for (j = 0; j <= ibox[i]; j++) { - axis[j] = min_eig[i] + j/bfac[i]; + axis[j] = min_eig[i] + j / bfac[i]; } } @@ -719,28 +736,27 @@ static void do_sham(const char *fn, const char *ndx, snew(PP[i], ibox[1]); for (j = 0; j < ibox[1]; j++) { - PP[i][j] = P[i*ibox[1]+j]; + PP[i][j] = P[i * ibox[1] + j]; } - WW[i] = &(W[i*ibox[1]]); - EE[i] = &(E[i*ibox[1]]); - SS[i] = &(S[i*ibox[1]]); + WW[i] = &(W[i * ibox[1]]); + EE[i] = &(E[i * ibox[1]]); + SS[i] = &(S[i * ibox[1]]); } fp = gmx_ffopen(xpmP, "w"); - write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2", - ibox[0], ibox[1], axis_x, axis_y, PP, 0, Pmax, rlo, rhi, &nlevels); + write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2", ibox[0], ibox[1], axis_x, + axis_y, PP, 0, Pmax, rlo, rhi, &nlevels); gmx_ffclose(fp); fp = gmx_ffopen(xpm, "w"); - write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2", - ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels); + write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1], + axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels); gmx_ffclose(fp); fp = gmx_ffopen(xpm2, "w"); - write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2", - ibox[0], ibox[1], axis_x, axis_y, EE, - emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels); + write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1], + axis_x, axis_y, EE, emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels); gmx_ffclose(fp); fp = gmx_ffopen(xpm3, "w"); - write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2", - ibox[0], ibox[1], axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels); + write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1], + axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels); gmx_ffclose(fp); } else if (neig == 3) @@ -749,27 +765,27 @@ static void do_sham(const char *fn, const char *ndx, fp = gmx_ffopen(pdb, "w"); for (i = 0; (i < ibox[0]); i++) { - xxx[XX] = 3*i+1.5*(1-ibox[0]); + xxx[XX] = 3 * i + 1.5 * (1 - ibox[0]); for (j = 0; (j < ibox[1]); j++) { - xxx[YY] = 3*j+1.5*(1-ibox[1]); + xxx[YY] = 3 * j + 1.5 * (1 - ibox[1]); for (k = 0; (k < ibox[2]); k++) { - xxx[ZZ] = 3*k+1.5*(1-ibox[2]); + xxx[ZZ] = 3 * k + 1.5 * (1 - ibox[2]); index = index3(ibox, i, j, k); if (P[index] > 0) { fprintf(fp, "%-6s%5d %-4.4s%3.3s %4d %8.3f%8.3f%8.3f%6.2f%6.2f\n", - "ATOM", (index+1) %10000, "H", "H", (index+1)%10000, - xxx[XX], xxx[YY], xxx[ZZ], 1.0, W[index]); + "ATOM", (index + 1) % 10000, "H", "H", (index + 1) % 10000, xxx[XX], + xxx[YY], xxx[ZZ], 1.0, W[index]); } } } } gmx_ffclose(fp); write_xplor("out.xplor", W, ibox, min_eig, max_eig); - nxyz[XX] = imin/(ibox[1]*ibox[2]); - nxyz[YY] = (imin-nxyz[XX]*ibox[1]*ibox[2])/ibox[2]; + nxyz[XX] = imin / (ibox[1] * ibox[2]); + nxyz[YY] = (imin - nxyz[XX] * ibox[1] * ibox[2]) / ibox[2]; nxyz[ZZ] = imin % ibox[2]; for (i = 0; (i < ibox[0]); i++) { @@ -779,12 +795,12 @@ static void do_sham(const char *fn, const char *ndx, WW[i][j] = W[index3(ibox, i, j, nxyz[ZZ])]; } } - snew(buf, std::strlen(xpm)+4); + snew(buf, std::strlen(xpm) + 4); sprintf(buf, "%s", xpm); - sprintf(&buf[std::strlen(xpm)-4], "12.xpm"); + sprintf(&buf[std::strlen(xpm) - 4], "12.xpm"); fp = gmx_ffopen(buf, "w"); - write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2", - ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels); + write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2", ibox[0], ibox[1], + axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels); gmx_ffclose(fp); for (i = 0; (i < ibox[0]); i++) { @@ -793,10 +809,10 @@ static void do_sham(const char *fn, const char *ndx, WW[i][j] = W[index3(ibox, i, nxyz[YY], j)]; } } - sprintf(&buf[std::strlen(xpm)-4], "13.xpm"); + sprintf(&buf[std::strlen(xpm) - 4], "13.xpm"); fp = gmx_ffopen(buf, "w"); - write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3", - ibox[0], ibox[2], axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels); + write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3", ibox[0], ibox[2], + axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels); gmx_ffclose(fp); for (i = 0; (i < ibox[1]); i++) { @@ -805,24 +821,24 @@ static void do_sham(const char *fn, const char *ndx, WW[i][j] = W[index3(ibox, nxyz[XX], i, j)]; } } - sprintf(&buf[std::strlen(xpm)-4], "23.xpm"); + sprintf(&buf[std::strlen(xpm) - 4], "23.xpm"); fp = gmx_ffopen(buf, "w"); - write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3", - ibox[1], ibox[2], axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels); + write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3", ibox[1], ibox[2], + axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels); gmx_ffclose(fp); sfree(buf); } } -static void ehisto(const char *fh, int n, real **enerT, const gmx_output_env_t *oenv) +static void ehisto(const char* fh, int n, real** enerT, const gmx_output_env_t* oenv) { - FILE *fp; - int i, j, k, nbin, blength; - int *bindex; - real *T, bmin, bmax, bwidth; - int **histo; + FILE* fp; + int i, j, k, nbin, blength; + int* bindex; + real *T, bmin, bmax, bwidth; + int** histo; - bmin = 1e8; + bmin = 1e8; bmax = -1e8; snew(bindex, n); snew(T, n); @@ -847,7 +863,7 @@ static void ehisto(const char *fh, int n, real **enerT, const gmx_output_env_t * bmax = std::max(enerT[0][j], bmax); } bwidth = 1.0; - blength = static_cast((bmax - bmin)/bwidth + 2); + blength = static_cast((bmax - bmin) / bwidth + 2); snew(histo, nbin); for (i = 0; (i < nbin); i++) { @@ -855,13 +871,13 @@ static void ehisto(const char *fh, int n, real **enerT, const gmx_output_env_t * } for (j = 0; (j < n); j++) { - k = static_cast((enerT[0][j]-bmin)/bwidth); + k = static_cast((enerT[0][j] - bmin) / bwidth); histo[bindex[j]][k]++; } fp = xvgropen(fh, "Energy distribution", "E (kJ/mol)", "", oenv); for (j = 0; (j < blength); j++) { - fprintf(fp, "%8.3f", bmin+j*bwidth); + fprintf(fp, "%8.3f", bmin + j * bwidth); for (k = 0; (k < nbin); k++) { fprintf(fp, " %6d", histo[k][j]); @@ -871,9 +887,9 @@ static void ehisto(const char *fh, int n, real **enerT, const gmx_output_env_t * xvgrclose(fp); } -int gmx_sham(int argc, char *argv[]) +int gmx_sham(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] makes multi-dimensional free-energy, enthalpy and entropy plots.", "[THISMODULE] reads one or more [REF].xvg[ref] files and analyzes data sets.", "The basic purpose of [THISMODULE] is to plot Gibbs free energy landscapes", @@ -914,90 +930,94 @@ int gmx_sham(int argc, char *argv[]) "is the natural quantity to use, as it will produce bins of the same", "volume." }; - static real tb = -1, te = -1; - static gmx_bool bHaveT = TRUE, bDer = FALSE; - static gmx_bool bSham = TRUE; - static real Tref = 298.15, pmin = 0, ttol = 0, pmax = 0, gmax = 0, emin = 0, emax = 0; - static rvec nrdim = {1, 1, 1}; - static rvec nrbox = {32, 32, 32}; - static rvec xmin = {0, 0, 0}, xmax = {1, 1, 1}; - static int nsets_in = 1, nlevels = 25; - t_pargs pa[] = { - { "-time", FALSE, etBOOL, {&bHaveT}, - "Expect a time in the input" }, - { "-b", FALSE, etREAL, {&tb}, - "First time to read from set" }, - { "-e", FALSE, etREAL, {&te}, - "Last time to read from set" }, - { "-ttol", FALSE, etREAL, {&ttol}, - "Tolerance on time in appropriate units (usually ps)" }, - { "-n", FALSE, etINT, {&nsets_in}, + static real tb = -1, te = -1; + static gmx_bool bHaveT = TRUE, bDer = FALSE; + static gmx_bool bSham = TRUE; + static real Tref = 298.15, pmin = 0, ttol = 0, pmax = 0, gmax = 0, emin = 0, emax = 0; + static rvec nrdim = { 1, 1, 1 }; + static rvec nrbox = { 32, 32, 32 }; + static rvec xmin = { 0, 0, 0 }, xmax = { 1, 1, 1 }; + static int nsets_in = 1, nlevels = 25; + t_pargs pa[] = { + { "-time", FALSE, etBOOL, { &bHaveT }, "Expect a time in the input" }, + { "-b", FALSE, etREAL, { &tb }, "First time to read from set" }, + { "-e", FALSE, etREAL, { &te }, "Last time to read from set" }, + { "-ttol", FALSE, etREAL, { &ttol }, "Tolerance on time in appropriate units (usually ps)" }, + { "-n", + FALSE, + etINT, + { &nsets_in }, "Read this number of sets separated by lines containing only an ampersand" }, - { "-d", FALSE, etBOOL, {&bDer}, - "Use the derivative" }, - { "-sham", FALSE, etBOOL, {&bSham}, + { "-d", FALSE, etBOOL, { &bDer }, "Use the derivative" }, + { "-sham", + FALSE, + etBOOL, + { &bSham }, "Turn off energy weighting even if energies are given" }, - { "-tsham", FALSE, etREAL, {&Tref}, - "Temperature for single histogram analysis" }, - { "-pmin", FALSE, etREAL, {&pmin}, + { "-tsham", FALSE, etREAL, { &Tref }, "Temperature for single histogram analysis" }, + { "-pmin", + FALSE, + etREAL, + { &pmin }, "Minimum probability. Anything lower than this will be set to zero" }, - { "-dim", FALSE, etRVEC, {nrdim}, - "Dimensions for distances, used for volume correction (max 3 values, dimensions > 3 will get the same value as the last)" }, - { "-ngrid", FALSE, etRVEC, {nrbox}, - "Number of bins for energy landscapes (max 3 values, dimensions > 3 will get the same value as the last)" }, - { "-xmin", FALSE, etRVEC, {xmin}, + { "-dim", + FALSE, + etRVEC, + { nrdim }, + "Dimensions for distances, used for volume correction (max 3 values, dimensions > 3 will " + "get the same value as the last)" }, + { "-ngrid", + FALSE, + etRVEC, + { nrbox }, + "Number of bins for energy landscapes (max 3 values, dimensions > 3 will get the same " + "value as the last)" }, + { "-xmin", + FALSE, + etRVEC, + { xmin }, "Minimum for the axes in energy landscape (see above for > 3 dimensions)" }, - { "-xmax", FALSE, etRVEC, {xmax}, + { "-xmax", + FALSE, + etRVEC, + { xmax }, "Maximum for the axes in energy landscape (see above for > 3 dimensions)" }, - { "-pmax", FALSE, etREAL, {&pmax}, - "Maximum probability in output, default is calculate" }, - { "-gmax", FALSE, etREAL, {&gmax}, - "Maximum free energy in output, default is calculate" }, - { "-emin", FALSE, etREAL, {&emin}, - "Minimum enthalpy in output, default is calculate" }, - { "-emax", FALSE, etREAL, {&emax}, - "Maximum enthalpy in output, default is calculate" }, - { "-nlevels", FALSE, etINT, {&nlevels}, - "Number of levels for energy landscape" }, + { "-pmax", FALSE, etREAL, { &pmax }, "Maximum probability in output, default is calculate" }, + { "-gmax", FALSE, etREAL, { &gmax }, "Maximum free energy in output, default is calculate" }, + { "-emin", FALSE, etREAL, { &emin }, "Minimum enthalpy in output, default is calculate" }, + { "-emax", FALSE, etREAL, { &emax }, "Maximum enthalpy in output, default is calculate" }, + { "-nlevels", FALSE, etINT, { &nlevels }, "Number of levels for energy landscape" }, }; #define NPA asize(pa) int n, e_n, nset, e_nset = 0, i, *idim, *ibox; - real **val, **et_val, *t, *e_t, e_dt, dt; - real *rmin, *rmax; - const char *fn_ge, *fn_ene; - gmx_output_env_t *oenv; + real ** val, **et_val, *t, *e_t, e_dt, dt; + real * rmin, *rmax; + const char * fn_ge, *fn_ene; + gmx_output_env_t* oenv; int64_t num_grid_points; - t_filenm fnm[] = { - { efXVG, "-f", "graph", ffREAD }, - { efXVG, "-ge", "gibbs", ffOPTRD }, - { efXVG, "-ene", "esham", ffOPTRD }, - { efXVG, "-dist", "ener", ffOPTWR }, - { efXVG, "-histo", "edist", ffOPTWR }, - { efNDX, "-bin", "bindex", ffOPTWR }, - { efXPM, "-lp", "prob", ffOPTWR }, - { efXPM, "-ls", "gibbs", ffOPTWR }, - { efXPM, "-lsh", "enthalpy", ffOPTWR }, - { efXPM, "-lss", "entropy", ffOPTWR }, - { efPDB, "-ls3", "gibbs3", ffOPTWR }, - { efLOG, "-g", "shamlog", ffOPTWR } + t_filenm fnm[] = { + { efXVG, "-f", "graph", ffREAD }, { efXVG, "-ge", "gibbs", ffOPTRD }, + { efXVG, "-ene", "esham", ffOPTRD }, { efXVG, "-dist", "ener", ffOPTWR }, + { efXVG, "-histo", "edist", ffOPTWR }, { efNDX, "-bin", "bindex", ffOPTWR }, + { efXPM, "-lp", "prob", ffOPTWR }, { efXPM, "-ls", "gibbs", ffOPTWR }, + { efXPM, "-lsh", "enthalpy", ffOPTWR }, { efXPM, "-lss", "entropy", ffOPTWR }, + { efPDB, "-ls3", "gibbs3", ffOPTWR }, { efLOG, "-g", "shamlog", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; + int npargs; npargs = asize(pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, - NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, npargs, pa, asize(desc), desc, 0, + nullptr, &oenv)) { return 0; } - val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, - opt2parg_bSet("-b", npargs, pa), tb-ttol, - opt2parg_bSet("-e", npargs, pa), te+ttol, - nsets_in, &nset, &n, &dt, &t); + val = read_xvg_time(opt2fn("-f", NFILE, fnm), bHaveT, opt2parg_bSet("-b", npargs, pa), tb - ttol, + opt2parg_bSet("-e", npargs, pa), te + ttol, nsets_in, &nset, &n, &dt, &t); printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt); fn_ge = opt2fn_null("-ge", NFILE, fnm); @@ -1010,29 +1030,28 @@ int gmx_sham(int argc, char *argv[]) if (fn_ge || fn_ene) { - et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene, bHaveT, - opt2parg_bSet("-b", npargs, pa), tb-ttol, - opt2parg_bSet("-e", npargs, pa), te+ttol, - 1, &e_nset, &e_n, &e_dt, &e_t); + et_val = read_xvg_time(fn_ge ? fn_ge : fn_ene, bHaveT, opt2parg_bSet("-b", npargs, pa), + tb - ttol, opt2parg_bSet("-e", npargs, pa), te + ttol, 1, &e_nset, + &e_n, &e_dt, &e_t); if (fn_ge) { if (e_nset != 1) { - gmx_fatal(FARGS, "Can only handle one free energy component in %s", - fn_ge); + gmx_fatal(FARGS, "Can only handle one free energy component in %s", fn_ge); } } else { if (e_nset != 1 && e_nset != 2) { - gmx_fatal(FARGS, "Can only handle one energy component or one energy and one T in %s", - fn_ene); + gmx_fatal(FARGS, + "Can only handle one energy component or one energy and one T in %s", fn_ene); } } if (e_n != n) { - gmx_fatal(FARGS, "Number of energies (%d) does not match number of entries (%d) in %s", e_n, n, opt2fn("-f", NFILE, fnm)); + gmx_fatal(FARGS, "Number of energies (%d) does not match number of entries (%d) in %s", + e_n, n, opt2fn("-f", NFILE, fnm)); } } else @@ -1078,19 +1097,12 @@ int gmx_sham(int argc, char *argv[]) } /* The number of grid points fits in a int64_t. */ - do_sham(opt2fn("-dist", NFILE, fnm), opt2fn("-bin", NFILE, fnm), - opt2fn("-lp", NFILE, fnm), - opt2fn("-ls", NFILE, fnm), opt2fn("-lsh", NFILE, fnm), - opt2fn("-lss", NFILE, fnm), - opt2fn("-ls3", NFILE, fnm), opt2fn("-g", NFILE, fnm), - n, nset, val, fn_ge != nullptr, e_nset, et_val, Tref, - pmax, gmax, - opt2parg_bSet("-emin", NPA, pa) ? &emin : nullptr, - opt2parg_bSet("-emax", NPA, pa) ? &emax : nullptr, - nlevels, pmin, - idim, ibox, - opt2parg_bSet("-xmin", NPA, pa), rmin, - opt2parg_bSet("-xmax", NPA, pa), rmax); + do_sham(opt2fn("-dist", NFILE, fnm), opt2fn("-bin", NFILE, fnm), opt2fn("-lp", NFILE, fnm), + opt2fn("-ls", NFILE, fnm), opt2fn("-lsh", NFILE, fnm), opt2fn("-lss", NFILE, fnm), + opt2fn("-ls3", NFILE, fnm), opt2fn("-g", NFILE, fnm), n, nset, val, fn_ge != nullptr, + e_nset, et_val, Tref, pmax, gmax, opt2parg_bSet("-emin", NPA, pa) ? &emin : nullptr, + opt2parg_bSet("-emax", NPA, pa) ? &emax : nullptr, nlevels, pmin, idim, ibox, + opt2parg_bSet("-xmin", NPA, pa), rmin, opt2parg_bSet("-xmax", NPA, pa), rmax); return 0; } diff --git a/src/gromacs/gmxana/gmx_sigeps.cpp b/src/gromacs/gmxana/gmx_sigeps.cpp index 02da8ac8ae..12d7a461a7 100644 --- a/src/gromacs/gmxana/gmx_sigeps.cpp +++ b/src/gromacs/gmxana/gmx_sigeps.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,88 +52,85 @@ static real pot(real x, real qq, real c6, real cn, int npow) { - return cn*pow(x, -npow)-c6/gmx::power6(x)+qq*ONE_4PI_EPS0/x; + return cn * pow(x, -npow) - c6 / gmx::power6(x) + qq * ONE_4PI_EPS0 / x; } static real bhpot(real x, real A, real B, real C) { - return A*std::exp(-B*x) - C/gmx::power6(x); + return A * std::exp(-B * x) - C / gmx::power6(x); } static real dpot(real x, real qq, real c6, real cn, int npow) { - return -(npow*cn*std::pow(x, -npow-1)-6*c6/(x*gmx::power6(x))+qq*ONE_4PI_EPS0/gmx::square(x)); + return -(npow * cn * std::pow(x, -npow - 1) - 6 * c6 / (x * gmx::power6(x)) + + qq * ONE_4PI_EPS0 / gmx::square(x)); } -int gmx_sigeps(int argc, char *argv[]) +int gmx_sigeps(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] is a simple utility that converts C6/C12 or C6/Cn combinations", "to [GRK]sigma[grk] and [GRK]epsilon[grk], or vice versa. It can also plot the potential", "in file. In addition, it makes an approximation of a Buckingham potential", "to a Lennard-Jones potential." }; - static real c6 = 1.0e-3, cn = 1.0e-6, qi = 0, qj = 0, sig = 0.3, eps = 1, sigfac = 0.7; - static real Abh = 1e5, Bbh = 32, Cbh = 1e-3; - static int npow = 12; - t_pargs pa[] = { - { "-c6", FALSE, etREAL, {&c6}, "C6" }, - { "-cn", FALSE, etREAL, {&cn}, "Constant for repulsion" }, - { "-pow", FALSE, etINT, {&npow}, "Power of the repulsion term" }, - { "-sig", FALSE, etREAL, {&sig}, "[GRK]sigma[grk]" }, - { "-eps", FALSE, etREAL, {&eps}, "[GRK]epsilon[grk]" }, - { "-A", FALSE, etREAL, {&Abh}, "Buckingham A" }, - { "-B", FALSE, etREAL, {&Bbh}, "Buckingham B" }, - { "-C", FALSE, etREAL, {&Cbh}, "Buckingham C" }, - { "-qi", FALSE, etREAL, {&qi}, "qi" }, - { "-qj", FALSE, etREAL, {&qj}, "qj" }, - { "-sigfac", FALSE, etREAL, {&sigfac}, "Factor in front of [GRK]sigma[grk] for starting the plot" } - }; - t_filenm fnm[] = { - { efXVG, "-o", "potje", ffWRITE } - }; - gmx_output_env_t *oenv; + static real c6 = 1.0e-3, cn = 1.0e-6, qi = 0, qj = 0, sig = 0.3, eps = 1, sigfac = 0.7; + static real Abh = 1e5, Bbh = 32, Cbh = 1e-3; + static int npow = 12; + t_pargs pa[] = { { "-c6", FALSE, etREAL, { &c6 }, "C6" }, + { "-cn", FALSE, etREAL, { &cn }, "Constant for repulsion" }, + { "-pow", FALSE, etINT, { &npow }, "Power of the repulsion term" }, + { "-sig", FALSE, etREAL, { &sig }, "[GRK]sigma[grk]" }, + { "-eps", FALSE, etREAL, { &eps }, "[GRK]epsilon[grk]" }, + { "-A", FALSE, etREAL, { &Abh }, "Buckingham A" }, + { "-B", FALSE, etREAL, { &Bbh }, "Buckingham B" }, + { "-C", FALSE, etREAL, { &Cbh }, "Buckingham C" }, + { "-qi", FALSE, etREAL, { &qi }, "qi" }, + { "-qj", FALSE, etREAL, { &qj }, "qj" }, + { "-sigfac", + FALSE, + etREAL, + { &sigfac }, + "Factor in front of [GRK]sigma[grk] for starting the plot" } }; + t_filenm fnm[] = { { efXVG, "-o", "potje", ffWRITE } }; + gmx_output_env_t* oenv; #define NFILE asize(fnm) - const char *legend[] = { "Lennard-Jones", "Buckingham" }; - FILE *fp; - int i; - gmx_bool bBham; - real qq, x, oldx, minimum, mval, dp[2]; - int cur = 0; -#define next (1-cur) + const char* legend[] = { "Lennard-Jones", "Buckingham" }; + FILE* fp; + int i; + gmx_bool bBham; + real qq, x, oldx, minimum, mval, dp[2]; + int cur = 0; +#define next (1 - cur) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), - desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } - bBham = (opt2parg_bSet("-A", asize(pa), pa) || - opt2parg_bSet("-B", asize(pa), pa) || - opt2parg_bSet("-C", asize(pa), pa)); + bBham = (opt2parg_bSet("-A", asize(pa), pa) || opt2parg_bSet("-B", asize(pa), pa) + || opt2parg_bSet("-C", asize(pa), pa)); if (bBham) { c6 = Cbh; - sig = std::pow((6.0/npow)*std::pow(npow/Bbh, npow-6), 1.0/(npow-6)); - eps = c6/(4*gmx::power6(sig)); - cn = 4*eps*std::pow(sig, npow); + sig = std::pow((6.0 / npow) * std::pow(npow / Bbh, npow - 6), 1.0 / (npow - 6)); + eps = c6 / (4 * gmx::power6(sig)); + cn = 4 * eps * std::pow(sig, npow); } else { - if (opt2parg_bSet("-sig", asize(pa), pa) || - opt2parg_bSet("-eps", asize(pa), pa)) + if (opt2parg_bSet("-sig", asize(pa), pa) || opt2parg_bSet("-eps", asize(pa), pa)) { - c6 = 4*eps*gmx::power6(sig); - cn = 4*eps*std::pow(sig, npow); + c6 = 4 * eps * gmx::power6(sig); + cn = 4 * eps * std::pow(sig, npow); } - else if (opt2parg_bSet("-c6", asize(pa), pa) || - opt2parg_bSet("-cn", asize(pa), pa) || - opt2parg_bSet("-pow", asize(pa), pa)) + else if (opt2parg_bSet("-c6", asize(pa), pa) || opt2parg_bSet("-cn", asize(pa), pa) + || opt2parg_bSet("-pow", asize(pa), pa)) { - sig = std::pow(cn/c6, static_cast(1.0/(npow-6))); - eps = 0.25*c6/gmx::power6(sig); + sig = std::pow(cn / c6, static_cast(1.0 / (npow - 6))); + eps = 0.25 * c6 / gmx::power6(sig); } else { @@ -142,37 +139,34 @@ int gmx_sigeps(int argc, char *argv[]) printf("c6 = %12.5e, c%d = %12.5e\n", c6, npow, cn); printf("sigma = %12.5f, epsilon = %12.5f\n", sig, eps); - minimum = std::pow(npow/6.0*std::pow(sig, npow-6), 1.0/(npow-6)); - printf("Van der Waals minimum at %g, V = %g\n\n", - minimum, pot(minimum, 0, c6, cn, npow)); + minimum = std::pow(npow / 6.0 * std::pow(sig, npow - 6), 1.0 / (npow - 6)); + printf("Van der Waals minimum at %g, V = %g\n\n", minimum, pot(minimum, 0, c6, cn, npow)); printf("Fit of Lennard Jones (%d-6) to Buckingham:\n", npow); - Bbh = npow/minimum; + Bbh = npow / minimum; Cbh = c6; - Abh = 4*eps*std::pow(sig/minimum, static_cast(npow))*std::exp(static_cast(npow)); + Abh = 4 * eps * std::pow(sig / minimum, static_cast(npow)) + * std::exp(static_cast(npow)); printf("A = %g, B = %g, C = %g\n", Abh, Bbh, Cbh); } - qq = qi*qj; + qq = qi * qj; - fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Potential", "r (nm)", "E (kJ/mol)", - oenv); - xvgr_legend(fp, asize(legend), legend, - oenv); + fp = xvgropen(ftp2fn(efXVG, NFILE, fnm), "Potential", "r (nm)", "E (kJ/mol)", oenv); + xvgr_legend(fp, asize(legend), legend, oenv); if (sig == 0) { sig = 0.25; } - oldx = 0; + oldx = 0; for (i = 0; (i < 100); i++) { - x = sigfac*sig+sig*i*0.02; + x = sigfac * sig + sig * i * 0.02; dp[next] = dpot(x, qq, c6, cn, npow); - fprintf(fp, "%10g %10g %10g\n", x, pot(x, qq, c6, cn, npow), - bhpot(x, Abh, Bbh, Cbh)); + fprintf(fp, "%10g %10g %10g\n", x, pot(x, qq, c6, cn, npow), bhpot(x, Abh, Bbh, Cbh)); if (qq != 0) { - if ((i > 0) && (dp[cur]*dp[next] < 0)) + if ((i > 0) && (dp[cur] * dp[next] < 0)) { - minimum = oldx + dp[cur]*(x-oldx)/(dp[cur]-dp[next]); + minimum = oldx + dp[cur] * (x - oldx) / (dp[cur] - dp[next]); mval = pot(minimum, qq, c6, cn, npow); printf("Van der Waals + Coulomb minimum at r = %g (nm). Value = %g (kJ/mol)\n", minimum, mval); @@ -180,7 +174,6 @@ int gmx_sigeps(int argc, char *argv[]) } cur = next; oldx = x; - } xvgrclose(fp); diff --git a/src/gromacs/gmxana/gmx_sorient.cpp b/src/gromacs/gmxana/gmx_sorient.cpp index 837c234828..4d661534cd 100644 --- a/src/gromacs/gmxana/gmx_sorient.cpp +++ b/src/gromacs/gmxana/gmx_sorient.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,8 +56,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void calc_com_pbc(int nrefat, t_topology *top, rvec x[], t_pbc *pbc, - const int index[], rvec xref, gmx_bool bPBC) +static void calc_com_pbc(int nrefat, t_topology* top, rvec x[], t_pbc* pbc, const int index[], rvec xref, gmx_bool bPBC) { const real tol = 1e-4; gmx_bool bChanged; @@ -74,11 +73,11 @@ static void calc_com_pbc(int nrefat, t_topology *top, rvec x[], t_pbc *pbc, mass = top->atoms.atom[ai].m; for (j = 0; (j < DIM); j++) { - xref[j] += mass*x[ai][j]; + xref[j] += mass * x[ai][j]; } mtot += mass; } - svmul(1/mtot, xref, xref); + svmul(1 / mtot, xref, xref); /* Now check if any atom is more than half the box from the COM */ if (bPBC) { @@ -89,15 +88,15 @@ static void calc_com_pbc(int nrefat, t_topology *top, rvec x[], t_pbc *pbc, for (m = 0; (m < nrefat); m++) { ai = index[m]; - mass = top->atoms.atom[ai].m/mtot; + mass = top->atoms.atom[ai].m / mtot; pbc_dx(pbc, x[ai], xref, dx); rvec_add(xref, dx, xtest); for (j = 0; (j < DIM); j++) { - if (std::abs(xtest[j]-x[ai][j]) > tol) + if (std::abs(xtest[j] - x[ai][j]) > tol) { /* Here we have used the wrong image for contributing to the COM */ - xref[j] += mass*(xtest[j]-x[ai][j]); + xref[j] += mass * (xtest[j] - x[ai][j]); x[ai][j] = xtest[j]; bChanged = TRUE; } @@ -108,52 +107,47 @@ static void calc_com_pbc(int nrefat, t_topology *top, rvec x[], t_pbc *pbc, printf("COM: %8.3f %8.3f %8.3f iter = %d\n", xref[XX], xref[YY], xref[ZZ], iter); } iter++; - } - while (bChanged); + } while (bChanged); } } -int gmx_sorient(int argc, char *argv[]) +int gmx_sorient(int argc, char* argv[]) { - t_topology top; - int ePBC = -1; - t_trxstatus *status; - int natoms; - real t; - rvec *xtop, *x; - matrix box; - - FILE *fp; - int i, p, sa0, sa1, sa2, n, ntot, nf, m, *hist1, *hist2, *histn, nbin1, nbin2, nrbin; - real *histi1, *histi2, invbw, invrbw; - double sum1, sum2; - int *isize, nrefgrp, nrefat; - int **index; - char **grpname; - real inp, outp, nav, normfac, rmin2, rmax2, rcut, rcut2, r2, r; - real c1, c2; - char str[STRLEN]; - gmx_bool bTPS; - rvec xref, dx, dxh1, dxh2, outer; - gmx_rmpbc_t gpbc = nullptr; - t_pbc pbc; - const char *legr[] = { - "", - "<3cos\\S2\\N(\\8q\\4\\s2\\N)-1>" - }; - const char *legc[] = { - "cos(\\8q\\4\\s1\\N)", - "3cos\\S2\\N(\\8q\\4\\s2\\N)-1" - }; - - const char *desc[] = { + t_topology top; + int ePBC = -1; + t_trxstatus* status; + int natoms; + real t; + rvec * xtop, *x; + matrix box; + + FILE* fp; + int i, p, sa0, sa1, sa2, n, ntot, nf, m, *hist1, *hist2, *histn, nbin1, nbin2, nrbin; + real * histi1, *histi2, invbw, invrbw; + double sum1, sum2; + int * isize, nrefgrp, nrefat; + int** index; + char** grpname; + real inp, outp, nav, normfac, rmin2, rmax2, rcut, rcut2, r2, r; + real c1, c2; + char str[STRLEN]; + gmx_bool bTPS; + rvec xref, dx, dxh1, dxh2, outer; + gmx_rmpbc_t gpbc = nullptr; + t_pbc pbc; + const char* legr[] = { "", "<3cos\\S2\\N(\\8q\\4\\s2\\N)-1>" }; + const char* legc[] = { "cos(\\8q\\4\\s1\\N)", "3cos\\S2\\N(\\8q\\4\\s2\\N)-1" }; + + const char* desc[] = { "[THISMODULE] analyzes solvent orientation around solutes.", "It calculates two angles between the vector from one or more", "reference positions to the first atom of each solvent molecule:", "", - " * [GRK]theta[grk][SUB]1[sub]: the angle with the vector from the first atom of the solvent", + " * [GRK]theta[grk][SUB]1[sub]: the angle with the vector from the first atom of " + "the solvent", " molecule to the midpoint between atoms 2 and 3.", - " * [GRK]theta[grk][SUB]2[sub]: the angle with the normal of the solvent plane, defined by the", + " * [GRK]theta[grk][SUB]2[sub]: the angle with the normal of the solvent plane, " + "defined by the", " same three atoms, or, when the option [TT]-v23[tt] is set, ", " the angle with the vector between atoms 2 and 3.", "", @@ -162,44 +156,46 @@ int gmx_sorient(int argc, char *argv[]) "consist of 3 atoms per solvent molecule.", "Only solvent molecules between [TT]-rmin[tt] and [TT]-rmax[tt] are", "considered for [TT]-o[tt] and [TT]-no[tt] each frame.[PAR]", - "[TT]-o[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] for rmin<=r<=rmax.[PAR]", - "[TT]-no[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]2[sub][cos][math] for rmin<=r<=rmax.[PAR]", - "[TT]-ro[tt]: [MATH][CHEVRON][COS][GRK]theta[grk][SUB]1[sub][cos][chevron][math] and [MATH][CHEVRON]3[COS]^2[GRK]theta[grk][SUB]2[sub][cos]-1[chevron][math] as a function of the", + "[TT]-o[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] for " + "rmin<=r<=rmax.[PAR]", + "[TT]-no[tt]: distribution of [MATH][COS][GRK]theta[grk][SUB]2[sub][cos][math] for " + "rmin<=r<=rmax.[PAR]", + "[TT]-ro[tt]: [MATH][CHEVRON][COS][GRK]theta[grk][SUB]1[sub][cos][chevron][math] " + "and [MATH][CHEVRON]3[COS]^2[GRK]theta[grk][SUB]2[sub][cos]-1[chevron][math] as a " + "function of the", "distance.[PAR]", "[TT]-co[tt]: the sum over all solvent molecules within distance r", - "of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] and [MATH]3[COS]^2([GRK]theta[grk][SUB]2[sub])-1[cos][math] as a function of r.[PAR]", + "of [MATH][COS][GRK]theta[grk][SUB]1[sub][cos][math] and " + "[MATH]3[COS]^2([GRK]theta[grk][SUB]2[sub])-1[cos][math] as a function of r.[PAR]", "[TT]-rc[tt]: the distribution of the solvent molecules as a function of r" }; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; static gmx_bool bCom = FALSE, bVec23 = FALSE, bPBC = FALSE; static real rmin = 0.0, rmax = 0.5, binwidth = 0.02, rbinw = 0.02; t_pargs pa[] = { - { "-com", FALSE, etBOOL, {&bCom}, - "Use the center of mass as the reference position" }, - { "-v23", FALSE, etBOOL, {&bVec23}, - "Use the vector between atoms 2 and 3" }, - { "-rmin", FALSE, etREAL, {&rmin}, "Minimum distance (nm)" }, - { "-rmax", FALSE, etREAL, {&rmax}, "Maximum distance (nm)" }, - { "-cbin", FALSE, etREAL, {&binwidth}, "Binwidth for the cosine" }, - { "-rbin", FALSE, etREAL, {&rbinw}, "Binwidth for r (nm)" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, "Check PBC for the center of mass calculation. Only necessary when your reference group consists of several molecules." } + { "-com", FALSE, etBOOL, { &bCom }, "Use the center of mass as the reference position" }, + { "-v23", FALSE, etBOOL, { &bVec23 }, "Use the vector between atoms 2 and 3" }, + { "-rmin", FALSE, etREAL, { &rmin }, "Minimum distance (nm)" }, + { "-rmax", FALSE, etREAL, { &rmax }, "Maximum distance (nm)" }, + { "-cbin", FALSE, etREAL, { &binwidth }, "Binwidth for the cosine" }, + { "-rbin", FALSE, etREAL, { &rbinw }, "Binwidth for r (nm)" }, + { "-pbc", + FALSE, + etBOOL, + { &bPBC }, + "Check PBC for the center of mass calculation. Only necessary when your reference group " + "consists of several molecules." } }; - t_filenm fnm[] = { - { efTRX, nullptr, nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "sori", ffWRITE }, - { efXVG, "-no", "snor", ffWRITE }, - { efXVG, "-ro", "sord", ffWRITE }, - { efXVG, "-co", "scum", ffWRITE }, - { efXVG, "-rc", "scount", ffWRITE } - }; + t_filenm fnm[] = { { efTRX, nullptr, nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, nullptr, "sori", ffWRITE }, + { efXVG, "-no", "snor", ffWRITE }, { efXVG, "-ro", "sord", ffWRITE }, + { efXVG, "-co", "scum", ffWRITE }, { efXVG, "-rc", "scount", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -207,8 +203,7 @@ int gmx_sorient(int argc, char *argv[]) bTPS = (opt2bSet("-s", NFILE, fnm) || !opt2bSet("-n", NFILE, fnm) || bCom); if (bTPS) { - read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, box, - bCom); + read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, box, bCom); } /* get index groups */ @@ -238,8 +233,7 @@ int gmx_sorient(int argc, char *argv[]) if (isize[1] % 3) { - gmx_fatal(FARGS, "The number of solvent atoms (%d) is not a multiple of 3", - isize[1]); + gmx_fatal(FARGS, "The number of solvent atoms (%d) is not a multiple of 3", isize[1]); } /* initialize reading trajectory: */ @@ -247,22 +241,22 @@ int gmx_sorient(int argc, char *argv[]) rmin2 = gmx::square(rmin); rmax2 = gmx::square(rmax); - rcut = 0.99*std::sqrt(max_cutoff2(guess_ePBC(box), box)); + rcut = 0.99 * std::sqrt(max_cutoff2(guess_ePBC(box), box)); if (rcut == 0) { - rcut = 10*rmax; + rcut = 10 * rmax; } rcut2 = gmx::square(rcut); - invbw = 1/binwidth; - nbin1 = 1+gmx::roundToInt(2*invbw); - nbin2 = 1+gmx::roundToInt(invbw); + invbw = 1 / binwidth; + nbin1 = 1 + gmx::roundToInt(2 * invbw); + nbin2 = 1 + gmx::roundToInt(invbw); - invrbw = 1/rbinw; + invrbw = 1 / rbinw; snew(hist1, nbin1); snew(hist2, nbin2); - nrbin = 1+static_cast(rcut/rbinw); + nrbin = 1 + static_cast(rcut / rbinw); if (nrbin == 0) { nrbin = 1; @@ -291,8 +285,8 @@ int gmx_sorient(int argc, char *argv[]) } set_pbc(&pbc, ePBC, box); - n = 0; - inp = 0; + n = 0; + inp = 0; for (p = 0; (p < nrefgrp); p++) { if (bCom) @@ -307,13 +301,13 @@ int gmx_sorient(int argc, char *argv[]) for (m = 0; m < isize[1]; m += 3) { sa0 = index[1][m]; - sa1 = index[1][m+1]; - sa2 = index[1][m+2]; + sa1 = index[1][m + 1]; + sa2 = index[1][m + 2]; range_check(sa0, 0, natoms); range_check(sa1, 0, natoms); range_check(sa2, 0, natoms); pbc_dx(&pbc, x[sa0], xref, dx); - r2 = norm2(dx); + r2 = norm2(dx); if (r2 < rcut2) { r = std::sqrt(r2); @@ -323,7 +317,7 @@ int gmx_sorient(int argc, char *argv[]) rvec_sub(x[sa1], x[sa0], dxh1); rvec_sub(x[sa2], x[sa0], dxh2); rvec_inc(dxh1, dxh2); - svmul(1/r, dx, dx); + svmul(1 / r, dx, dx); unitv(dxh1, dxh1); inp = iprod(dx, dxh1); cprod(dxh1, dxh2, outer); @@ -335,19 +329,19 @@ int gmx_sorient(int argc, char *argv[]) /* Use the vector between the 2nd and 3rd atom */ rvec_sub(x[sa2], x[sa1], dxh2); unitv(dxh2, dxh2); - outp = iprod(dx, dxh2)/r; + outp = iprod(dx, dxh2) / r; } { - int ii = static_cast(invrbw*r); + int ii = static_cast(invrbw * r); range_check(ii, 0, nrbin); histi1[ii] += inp; - histi2[ii] += 3*gmx::square(outp) - 1; + histi2[ii] += 3 * gmx::square(outp) - 1; histn[ii]++; } if ((r2 >= rmin2) && (r2 < rmax2)) { - int ii1 = static_cast(invbw*(inp + 1)); - int ii2 = static_cast(invbw*std::abs(outp)); + int ii1 = static_cast(invbw * (inp + 1)); + int ii2 = static_cast(invbw * std::abs(outp)); range_check(ii1, 0, nbin1); range_check(ii2, 0, nbin2); @@ -363,8 +357,7 @@ int gmx_sorient(int argc, char *argv[]) ntot += n; nf++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); /* clean up */ sfree(x); @@ -372,22 +365,19 @@ int gmx_sorient(int argc, char *argv[]) gmx_rmpbc_done(gpbc); /* Add the bin for the exact maximum to the previous bin */ - hist1[nbin1-1] += hist1[nbin1]; - hist2[nbin2-1] += hist2[nbin2]; + hist1[nbin1 - 1] += hist1[nbin1]; + hist2[nbin2 - 1] += hist2[nbin2]; - nav = static_cast(ntot)/(nrefgrp*nf); - normfac = invbw/ntot; + nav = static_cast(ntot) / (nrefgrp * nf); + normfac = invbw / ntot; - fprintf(stderr, "Average nr of molecules between %g and %g nm: %.1f\n", - rmin, rmax, nav); + fprintf(stderr, "Average nr of molecules between %g and %g nm: %.1f\n", rmin, rmax, nav); if (ntot > 0) { sum1 /= ntot; sum2 /= ntot; - fprintf(stderr, "Average cos(theta1) between %g and %g nm: %6.3f\n", - rmin, rmax, sum1); - fprintf(stderr, "Average 3cos2(theta2)-1 between %g and %g nm: %6.3f\n", - rmin, rmax, sum2); + fprintf(stderr, "Average cos(theta1) between %g and %g nm: %6.3f\n", rmin, rmax, sum1); + fprintf(stderr, "Average 3cos2(theta2)-1 between %g and %g nm: %6.3f\n", rmin, rmax, sum2); } sprintf(str, "Solvent orientation between %g and %g nm", rmin, rmax); @@ -398,7 +388,7 @@ int gmx_sorient(int argc, char *argv[]) } for (i = 0; i < nbin1; i++) { - fprintf(fp, "%g %g\n", (i+0.5)*binwidth-1, 2*normfac*hist1[i]); + fprintf(fp, "%g %g\n", (i + 0.5) * binwidth - 1, 2 * normfac * hist1[i]); } xvgrclose(fp); @@ -410,7 +400,7 @@ int gmx_sorient(int argc, char *argv[]) } for (i = 0; i < nbin2; i++) { - fprintf(fp, "%g %g\n", (i+0.5)*binwidth, normfac*hist2[i]); + fprintf(fp, "%g %g\n", (i + 0.5) * binwidth, normfac * hist2[i]); } xvgrclose(fp); @@ -424,9 +414,8 @@ int gmx_sorient(int argc, char *argv[]) xvgr_legend(fp, 2, legr, oenv); for (i = 0; i < nrbin; i++) { - fprintf(fp, "%g %g %g\n", (i+0.5)*rbinw, - histn[i] ? histi1[i]/histn[i] : 0, - histn[i] ? histi2[i]/histn[i] : 0); + fprintf(fp, "%g %g %g\n", (i + 0.5) * rbinw, histn[i] ? histi1[i] / histn[i] : 0, + histn[i] ? histi2[i] / histn[i] : 0); } xvgrclose(fp); @@ -437,15 +426,15 @@ int gmx_sorient(int argc, char *argv[]) fprintf(fp, "@ subtitle \"as a function of distance\"\n"); } xvgr_legend(fp, 2, legc, oenv); - normfac = 1.0/(nrefgrp*nf); + normfac = 1.0 / (nrefgrp * nf); c1 = 0; c2 = 0; fprintf(fp, "%g %g %g\n", 0.0, c1, c2); for (i = 0; i < nrbin; i++) { - c1 += histi1[i]*normfac; - c2 += histi2[i]*normfac; - fprintf(fp, "%g %g %g\n", (i+1)*rbinw, c1, c2); + c1 += histi1[i] * normfac; + c2 += histi2[i] * normfac; + fprintf(fp, "%g %g %g\n", (i + 1) * rbinw, c1, c2); } xvgrclose(fp); @@ -455,10 +444,10 @@ int gmx_sorient(int argc, char *argv[]) { fprintf(fp, "@ subtitle \"as a function of distance\"\n"); } - normfac = 1.0/(rbinw*nf); + normfac = 1.0 / (rbinw * nf); for (i = 0; i < nrbin; i++) { - fprintf(fp, "%g %g\n", (i+0.5)*rbinw, histn[i]*normfac); + fprintf(fp, "%g %g\n", (i + 0.5) * rbinw, histn[i] * normfac); } xvgrclose(fp); diff --git a/src/gromacs/gmxana/gmx_spatial.cpp b/src/gromacs/gmxana/gmx_spatial.cpp index bdcb6b2020..000517b6da 100644 --- a/src/gromacs/gmxana/gmx_spatial.cpp +++ b/src/gromacs/gmxana/gmx_spatial.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,18 +52,21 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static const double bohr = 0.529177249; /* conversion factor to compensate for VMD plugin conversion... */ +static const double bohr = + 0.529177249; /* conversion factor to compensate for VMD plugin conversion... */ -int gmx_spatial(int argc, char *argv[]) +int gmx_spatial(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] calculates the spatial distribution function and", "outputs it in a form that can be read by VMD as Gaussian98 cube format.", "For a system of 32,000 atoms and a 50 ns trajectory, the SDF can be generated", "in about 30 minutes, with most of the time dedicated to the two runs through", "[TT]trjconv[tt] that are required to center everything properly.", "This also takes a whole bunch of space (3 copies of the trajectory file).", - "Still, the pictures are pretty and very informative when the fitted selection is properly made.", + "Still, the pictures are pretty and very informative when the fitted selection is ", + "properly ", + "made.", "3-4 atoms in a widely mobile group (like a free amino acid in solution) works", "well, or select the protein backbone in a stable folded structure to get the SDF", "of solvent and look at the time-averaged solvation shell.", @@ -72,22 +75,29 @@ int gmx_spatial(int argc, char *argv[]) "", "Usage:", "", - "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the SDF", + "1. Use [gmx-make_ndx] to create a group containing the atoms around which you want the ", + "SDF", "2. [TT]gmx trjconv -s a.tpr -f a.tng -o b.tng -boxcenter tric -ur compact -pbc none[tt]", "3. [TT]gmx trjconv -s a.tpr -f b.tng -o c.tng -fit rot+trans[tt]", "4. run [THISMODULE] on the [TT]c.tng[tt] output of step #3.", "5. Load [TT]grid.cube[tt] into VMD and view as an isosurface.", "", - "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] between steps 1 and 2.", + "[BB]Note[bb] that systems such as micelles will require [TT]gmx trjconv -pbc cluster[tt] ", + "between steps 1 and 2.", "", "Warnings", "^^^^^^^^", "", - "The SDF will be generated for a cube that contains all bins that have some non-zero occupancy.", - "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that your system will be rotating", - "and translating in space (in order that the selected group does not). Therefore the values that are", - "returned will only be valid for some region around your central group/coordinate that has full overlap", - "with system volume throughout the entire translated/rotated system over the course of the trajectory.", + "The SDF will be generated for a cube that contains all bins that have some non-zero ", + "occupancy.", + "However, the preparatory [TT]-fit rot+trans[tt] option to [gmx-trjconv] implies that ", + "your system will be rotating", + "and translating in space (in order that the selected group does not). Therefore the ", + "values that are", + "returned will only be valid for some region around your central group/coordinate that ", + "has full overlap", + "with system volume throughout the entire translated/rotated system over the course of ", + "the trajectory.", "It is up to the user to ensure that this is the case.", "", "Risky options", @@ -99,74 +109,87 @@ int gmx_spatial(int argc, char *argv[]) "memory is allocated for cube bins based on the initial coordinates and the [TT]-nab[tt]", "option value." }; - const char *bugs[] = { - "When the allocated memory is not large enough, a segmentation fault may occur. This is usually detected " - "and the program is halted prior to the fault while displaying a warning message suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) " - "option. However, the program does not detect all such events. If you encounter a segmentation fault, run it again " + const char* bugs[] = { + "When the allocated memory is not large enough, a segmentation fault may occur. ", + "This is usually detected ", + "and the program is halted prior to the fault while displaying a warning message ", + "suggesting the use of the [TT]-nab[tt] (Number of Additional Bins) ", + "option. However, the program does not detect all such events. If you encounter a ", + "segmentation fault, run it again ", "with an increased [TT]-nab[tt] value." }; - static gmx_bool bPBC = FALSE; - static int iIGNOREOUTER = -1; /*Positive values may help if the surface is spikey */ - static gmx_bool bCUTDOWN = TRUE; - static real rBINWIDTH = 0.05; /* nm */ - static gmx_bool bCALCDIV = TRUE; - static int iNAB = 4; + static gmx_bool bPBC = FALSE; + static int iIGNOREOUTER = -1; /*Positive values may help if the surface is spikey */ + static gmx_bool bCUTDOWN = TRUE; + static real rBINWIDTH = 0.05; /* nm */ + static gmx_bool bCALCDIV = TRUE; + static int iNAB = 4; - t_pargs pa[] = { - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Use periodic boundary conditions for computing distances" }, - { "-div", FALSE, etBOOL, {&bCALCDIV}, - "Calculate and apply the divisor for bin occupancies based on atoms/minimal cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to get accurate counts per frame" }, - { "-ign", FALSE, etINT, {&iIGNOREOUTER}, - "Do not display this number of outer cubes (positive values may reduce boundary speckles; -1 ensures outer surface is visible)" }, - /* { "-cut", bCUTDOWN, etBOOL, {&bCUTDOWN},*/ - /* "Display a total cube that is of minimal size" }, */ - { "-bin", FALSE, etREAL, {&rBINWIDTH}, - "Width of the bins (nm)" }, - { "-nab", FALSE, etINT, {&iNAB}, - "Number of additional bins to ensure proper memory allocation" } - }; + t_pargs pa[] = { { "-pbc", + FALSE, + etBOOL, + { &bPBC }, + "Use periodic boundary conditions for computing distances" }, + { "-div", + FALSE, + etBOOL, + { &bCALCDIV }, + "Calculate and apply the divisor for bin occupancies based on atoms/minimal " + "cube size. Set as TRUE for visualization and as FALSE ([TT]-nodiv[tt]) to " + "get accurate counts per frame" }, + { "-ign", + FALSE, + etINT, + { &iIGNOREOUTER }, + "Do not display this number of outer cubes (positive values may reduce " + "boundary speckles; -1 ensures outer surface is visible)" }, + /* { "-cut", bCUTDOWN, etBOOL, {&bCUTDOWN},*/ + /* "Display a total cube that is of minimal size" }, */ + { "-bin", FALSE, etREAL, { &rBINWIDTH }, "Width of the bins (nm)" }, + { "-nab", + FALSE, + etINT, + { &iNAB }, + "Number of additional bins to ensure proper memory allocation" } }; double MINBIN[3]; double MAXBIN[3]; t_topology top; int ePBC; t_trxframe fr; - rvec *xtop; + rvec* xtop; matrix box, box_pbc; - t_trxstatus *status; + t_trxstatus* status; int flags = TRX_READ_X; t_pbc pbc; - t_atoms *atoms; + t_atoms* atoms; int natoms; - char *grpnm, *grpnmp; - int *index, *indexp; + char * grpnm, *grpnmp; + int * index, *indexp; int i, nidx, nidxp; int v; int j, k; - int ***bin = nullptr; + int*** bin = nullptr; int nbin[3]; - FILE *flp; + FILE* flp; int x, y, z, minx, miny, minz, maxx, maxy, maxz; int numfr, numcu; int tot, maxval, minval; double norm; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_rmpbc_t gpbc = nullptr; - t_filenm fnm[] = { - { efTPS, nullptr, nullptr, ffREAD }, /* this is for the topology */ - { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ - { efNDX, nullptr, nullptr, ffOPTRD } - }; + t_filenm fnm[] = { { efTPS, nullptr, nullptr, ffREAD }, /* this is for the topology */ + { efTRX, "-f", nullptr, ffREAD }, /* and this for the trajectory */ + { efNDX, nullptr, nullptr, ffOPTRD } }; #define NFILE asize(fnm) /* This is the routine responsible for adding default options, * calling the X/motif interface, etc. */ - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, asize(bugs), bugs, &oenv)) { return 0; } @@ -217,9 +240,9 @@ int gmx_spatial(int argc, char *argv[]) } for (i = ZZ; i >= XX; --i) { - MAXBIN[i] = (std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)+iNAB)*rBINWIDTH+MINBIN[i]; - MINBIN[i] -= iNAB*rBINWIDTH; - nbin[i] = static_cast(std::ceil((MAXBIN[i]-MINBIN[i])/rBINWIDTH)); + MAXBIN[i] = (std::ceil((MAXBIN[i] - MINBIN[i]) / rBINWIDTH) + iNAB) * rBINWIDTH + MINBIN[i]; + MINBIN[i] -= iNAB * rBINWIDTH; + nbin[i] = static_cast(std::ceil((MAXBIN[i] - MINBIN[i]) / rBINWIDTH)); } snew(bin, nbin[XX]); for (i = 0; i < nbin[XX]; ++i) @@ -232,8 +255,8 @@ int gmx_spatial(int argc, char *argv[]) } copy_mat(box, box_pbc); numfr = 0; - minx = miny = minz = 999; - maxx = maxy = maxz = 0; + minx = miny = minz = 999; + maxx = maxy = maxz = 0; if (bPBC) { @@ -253,18 +276,21 @@ int gmx_spatial(int argc, char *argv[]) for (i = 0; i < nidx; i++) { - if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX] || - fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY] || - fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ]) + if (fr.x[index[i]][XX] < MINBIN[XX] || fr.x[index[i]][XX] > MAXBIN[XX] + || fr.x[index[i]][YY] < MINBIN[YY] || fr.x[index[i]][YY] > MAXBIN[YY] + || fr.x[index[i]][ZZ] < MINBIN[ZZ] || fr.x[index[i]][ZZ] > MAXBIN[ZZ]) { - printf("There was an item outside of the allocated memory. Increase the value given with the -nab option.\n"); - printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX], MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]); - printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX], fr.x[index[i]][YY], fr.x[index[i]][ZZ]); + printf("There was an item outside of the allocated memory. Increase the value " + "given with the -nab option.\n"); + printf("Memory was allocated for [%f,%f,%f]\tto\t[%f,%f,%f]\n", MINBIN[XX], + MINBIN[YY], MINBIN[ZZ], MAXBIN[XX], MAXBIN[YY], MAXBIN[ZZ]); + printf("Memory was required for [%f,%f,%f]\n", fr.x[index[i]][XX], + fr.x[index[i]][YY], fr.x[index[i]][ZZ]); exit(1); } - x = static_cast(std::ceil((fr.x[index[i]][XX]-MINBIN[XX])/rBINWIDTH)); - y = static_cast(std::ceil((fr.x[index[i]][YY]-MINBIN[YY])/rBINWIDTH)); - z = static_cast(std::ceil((fr.x[index[i]][ZZ]-MINBIN[ZZ])/rBINWIDTH)); + x = static_cast(std::ceil((fr.x[index[i]][XX] - MINBIN[XX]) / rBINWIDTH)); + y = static_cast(std::ceil((fr.x[index[i]][YY] - MINBIN[YY]) / rBINWIDTH)); + z = static_cast(std::ceil((fr.x[index[i]][ZZ] - MINBIN[ZZ]) / rBINWIDTH)); ++bin[x][y][z]; if (x < minx) { @@ -294,8 +320,7 @@ int gmx_spatial(int argc, char *argv[]) numfr++; /* printf("%f\t%f\t%f\n",box[XX][XX],box[YY][YY],box[ZZ][ZZ]); */ - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); if (bPBC) { @@ -305,19 +330,25 @@ int gmx_spatial(int argc, char *argv[]) if (!bCUTDOWN) { minx = miny = minz = 0; - maxx = nbin[XX]; - maxy = nbin[YY]; - maxz = nbin[ZZ]; + maxx = nbin[XX]; + maxy = nbin[YY]; + maxz = nbin[ZZ]; } /* OUTPUT */ flp = gmx_ffopen("grid.cube", "w"); fprintf(flp, "Spatial Distribution Function\n"); fprintf(flp, "test\n"); - fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp, (MINBIN[XX]+(minx+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[YY]+(miny+iIGNOREOUTER)*rBINWIDTH)*10./bohr, (MINBIN[ZZ]+(minz+iIGNOREOUTER)*rBINWIDTH)*10./bohr); - fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx-minx+1-(2*iIGNOREOUTER), rBINWIDTH*10./bohr, 0., 0.); - fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy-miny+1-(2*iIGNOREOUTER), 0., rBINWIDTH*10./bohr, 0.); - fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz-minz+1-(2*iIGNOREOUTER), 0., 0., rBINWIDTH*10./bohr); + fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", nidxp, + (MINBIN[XX] + (minx + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr, + (MINBIN[YY] + (miny + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr, + (MINBIN[ZZ] + (minz + iIGNOREOUTER) * rBINWIDTH) * 10. / bohr); + fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxx - minx + 1 - (2 * iIGNOREOUTER), + rBINWIDTH * 10. / bohr, 0., 0.); + fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxy - miny + 1 - (2 * iIGNOREOUTER), 0., + rBINWIDTH * 10. / bohr, 0.); + fprintf(flp, "%5d%12.6f%12.6f%12.6f\n", maxz - minz + 1 - (2 * iIGNOREOUTER), 0., 0., + rBINWIDTH * 10. / bohr); for (i = 0; i < nidxp; i++) { v = 2; @@ -341,7 +372,8 @@ int gmx_spatial(int argc, char *argv[]) { v = 16; } - fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX]*10.0/bohr, fr.x[indexp[i]][YY]*10.0/bohr, fr.x[indexp[i]][ZZ]*10.0/bohr); + fprintf(flp, "%5d%12.6f%12.6f%12.6f%12.6f\n", v, 0., fr.x[indexp[i]][XX] * 10.0 / bohr, + fr.x[indexp[i]][YY] * 10.0 / bohr, fr.x[indexp[i]][ZZ] * 10.0 / bohr); } tot = 0; @@ -365,7 +397,8 @@ int gmx_spatial(int argc, char *argv[]) } if (bin[k][j][i] != 0) { - printf("A bin was not empty when it should have been empty. Programming error.\n"); + printf("A bin was not empty when it should have been empty. Programming " + "error.\n"); printf("bin[%d][%d][%d] was = %d\n", k, j, i, bin[k][j][i]); exit(1); } @@ -377,19 +410,19 @@ int gmx_spatial(int argc, char *argv[]) maxval = 0; for (k = 0; k < nbin[XX]; k++) { - if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER) + if (k < minx + iIGNOREOUTER || k > maxx - iIGNOREOUTER) { continue; } for (j = 0; j < nbin[YY]; j++) { - if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER) + if (j < miny + iIGNOREOUTER || j > maxy - iIGNOREOUTER) { continue; } for (i = 0; i < nbin[ZZ]; i++) { - if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER) + if (i < minz + iIGNOREOUTER || i > maxz - iIGNOREOUTER) { continue; } @@ -406,10 +439,11 @@ int gmx_spatial(int argc, char *argv[]) } } - numcu = (maxx-minx+1-(2*iIGNOREOUTER))*(maxy-miny+1-(2*iIGNOREOUTER))*(maxz-minz+1-(2*iIGNOREOUTER)); + numcu = (maxx - minx + 1 - (2 * iIGNOREOUTER)) * (maxy - miny + 1 - (2 * iIGNOREOUTER)) + * (maxz - minz + 1 - (2 * iIGNOREOUTER)); if (bCALCDIV) { - norm = static_cast(numcu*numfr)/tot; + norm = static_cast(numcu * numfr) / tot; } else { @@ -418,23 +452,23 @@ int gmx_spatial(int argc, char *argv[]) for (k = 0; k < nbin[XX]; k++) { - if (k < minx+iIGNOREOUTER || k > maxx-iIGNOREOUTER) + if (k < minx + iIGNOREOUTER || k > maxx - iIGNOREOUTER) { continue; } for (j = 0; j < nbin[YY]; j++) { - if (j < miny+iIGNOREOUTER || j > maxy-iIGNOREOUTER) + if (j < miny + iIGNOREOUTER || j > maxy - iIGNOREOUTER) { continue; } for (i = 0; i < nbin[ZZ]; i++) { - if (i < minz+iIGNOREOUTER || i > maxz-iIGNOREOUTER) + if (i < minz + iIGNOREOUTER || i > maxz - iIGNOREOUTER) { continue; } - fprintf(flp, "%12.6f ", static_cast(norm*bin[k][j][i])/numfr); + fprintf(flp, "%12.6f ", static_cast(norm * bin[k][j][i]) / numfr); } fprintf(flp, "\n"); } @@ -444,13 +478,15 @@ int gmx_spatial(int argc, char *argv[]) if (bCALCDIV) { - printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0/norm); - printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval*norm/numfr, maxval*norm/numfr); + printf("Counts per frame in all %d cubes divided by %le\n", numcu, 1.0 / norm); + printf("Normalized data: average %le, min %le, max %le\n", 1.0, minval * norm / numfr, + maxval * norm / numfr); } else { printf("grid.cube contains counts per frame in all %d cubes\n", numcu); - printf("Raw data: average %le, min %le, max %le\n", 1.0/norm, static_cast(minval)/numfr, static_cast(maxval)/numfr); + printf("Raw data: average %le, min %le, max %le\n", 1.0 / norm, + static_cast(minval) / numfr, static_cast(maxval) / numfr); } return 0; diff --git a/src/gromacs/gmxana/gmx_spol.cpp b/src/gromacs/gmxana/gmx_spol.cpp index 8894887353..74cc5b6654 100644 --- a/src/gromacs/gmxana/gmx_spol.cpp +++ b/src/gromacs/gmxana/gmx_spol.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,8 +58,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void calc_com_pbc(int nrefat, const t_topology *top, rvec x[], t_pbc *pbc, - const int index[], rvec xref, int ePBC) +static void calc_com_pbc(int nrefat, const t_topology* top, rvec x[], t_pbc* pbc, const int index[], rvec xref, int ePBC) { const real tol = 1e-4; gmx_bool bChanged; @@ -76,11 +75,11 @@ static void calc_com_pbc(int nrefat, const t_topology *top, rvec x[], t_pbc *pbc mass = top->atoms.atom[ai].m; for (j = 0; (j < DIM); j++) { - xref[j] += mass*x[ai][j]; + xref[j] += mass * x[ai][j]; } mtot += mass; } - svmul(1/mtot, xref, xref); + svmul(1 / mtot, xref, xref); /* Now check if any atom is more than half the box from the COM */ if (ePBC != epbcNONE) { @@ -91,15 +90,15 @@ static void calc_com_pbc(int nrefat, const t_topology *top, rvec x[], t_pbc *pbc for (m = 0; (m < nrefat); m++) { ai = index[m]; - mass = top->atoms.atom[ai].m/mtot; + mass = top->atoms.atom[ai].m / mtot; pbc_dx(pbc, x[ai], xref, dx); rvec_add(xref, dx, xtest); for (j = 0; (j < DIM); j++) { - if (std::abs(xtest[j]-x[ai][j]) > tol) + if (std::abs(xtest[j] - x[ai][j]) > tol) { /* Here we have used the wrong image for contributing to the COM */ - xref[j] += mass*(xtest[j]-x[ai][j]); + xref[j] += mass * (xtest[j] - x[ai][j]); x[ai][j] = xtest[j]; bChanged = TRUE; } @@ -110,12 +109,11 @@ static void calc_com_pbc(int nrefat, const t_topology *top, rvec x[], t_pbc *pbc printf("COM: %8.3f %8.3f %8.3f iter = %d\n", xref[XX], xref[YY], xref[ZZ], iter); } iter++; - } - while (bChanged); + } while (bChanged); } } -static void spol_atom2molindex(int *n, int *index, const t_block *mols) +static void spol_atom2molindex(int* n, int* index, const t_block* mols) { int nmol, i, j, m; @@ -130,9 +128,10 @@ static void spol_atom2molindex(int *n, int *index, const t_block *mols) } if (m == mols->nr) { - gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule", i+1, index[i]+1); + gmx_fatal(FARGS, "index[%d]=%d does not correspond to the first atom of a molecule", + i + 1, index[i] + 1); } - for (j = mols->index[m]; j < mols->index[m+1]; j++) + for (j = mols->index[m]; j < mols->index[m + 1]; j++) { if (i >= *n || index[i] != j) { @@ -148,29 +147,29 @@ static void spol_atom2molindex(int *n, int *index, const t_block *mols) *n = nmol; } -int gmx_spol(int argc, char *argv[]) +int gmx_spol(int argc, char* argv[]) { - t_topology *top; - t_atom *atom; - t_trxstatus *status; + t_topology* top; + t_atom* atom; + t_trxstatus* status; int nrefat, natoms, nf, ntot; real t; - rvec *x, xref, trial, dx = {0}, dip, dir; + rvec * x, xref, trial, dx = { 0 }, dip, dir; matrix box; - FILE *fp; - int *isize, nrefgrp; - int **index, *molindex; - char **grpname; - real rmin2, rmax2, rcut, rcut2, rdx2 = 0, rtry2, qav, q, dip2, invbw; - int nbin, i, m, mol, a0, a1, a, d; - double sdip, sdip2, sinp, sdinp, nmol; - int *hist; - t_pbc pbc; - gmx_rmpbc_t gpbc = nullptr; + FILE* fp; + int * isize, nrefgrp; + int ** index, *molindex; + char** grpname; + real rmin2, rmax2, rcut, rcut2, rdx2 = 0, rtry2, qav, q, dip2, invbw; + int nbin, i, m, mol, a0, a1, a, d; + double sdip, sdip2, sinp, sdinp, nmol; + int* hist; + t_pbc pbc; + gmx_rmpbc_t gpbc = nullptr; - const char *desc[] = { + const char* desc[] = { "[THISMODULE] analyzes dipoles around a solute; it is especially useful", "for polarizable water. A group of reference atoms, or a center", "of mass reference (option [TT]-com[tt]) and a group of solvent", @@ -191,31 +190,27 @@ int gmx_spol(int argc, char *argv[]) "to the midpoint between the second and the third atom." }; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; static gmx_bool bCom = FALSE; static int srefat = 1; - static real rmin = 0.0, rmax = 0.32, refdip = 0, bw = 0.01; - t_pargs pa[] = { - { "-com", FALSE, etBOOL, {&bCom}, - "Use the center of mass as the reference position" }, - { "-refat", FALSE, etINT, {&srefat}, - "The reference atom of the solvent molecule" }, - { "-rmin", FALSE, etREAL, {&rmin}, "Maximum distance (nm)" }, - { "-rmax", FALSE, etREAL, {&rmax}, "Maximum distance (nm)" }, - { "-dip", FALSE, etREAL, {&refdip}, "The average dipole (D)" }, - { "-bw", FALSE, etREAL, {&bw}, "The bin width" } + static real rmin = 0.0, rmax = 0.32, refdip = 0, bw = 0.01; + t_pargs pa[] = { + { "-com", FALSE, etBOOL, { &bCom }, "Use the center of mass as the reference position" }, + { "-refat", FALSE, etINT, { &srefat }, "The reference atom of the solvent molecule" }, + { "-rmin", FALSE, etREAL, { &rmin }, "Maximum distance (nm)" }, + { "-rmax", FALSE, etREAL, { &rmax }, "Maximum distance (nm)" }, + { "-dip", FALSE, etREAL, { &refdip }, "The average dipole (D)" }, + { "-bw", FALSE, etREAL, { &bw }, "The bin width" } }; - t_filenm fnm[] = { - { efTRX, nullptr, nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, nullptr, "scdist", ffWRITE } - }; + t_filenm fnm[] = { { efTRX, nullptr, nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efXVG, nullptr, "scdist", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_CAN_VIEW, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -223,9 +218,8 @@ int gmx_spol(int argc, char *argv[]) snew(top, 1); // TODO: Only ePBC is used, not the full inputrec. t_inputrec irInstance; - t_inputrec *ir = &irInstance; - read_tpx_top(ftp2fn(efTPR, NFILE, fnm), - ir, box, &natoms, nullptr, nullptr, top); + t_inputrec* ir = &irInstance; + read_tpx_top(ftp2fn(efTPR, NFILE, fnm), ir, box, &natoms, nullptr, nullptr, top); /* get index groups */ printf("Select a group of reference particles and a solvent group:\n"); @@ -251,14 +245,14 @@ int gmx_spol(int argc, char *argv[]) /* initialize reading trajectory: */ natoms = read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); - rcut = 0.99*std::sqrt(max_cutoff2(ir->ePBC, box)); + rcut = 0.99 * std::sqrt(max_cutoff2(ir->ePBC, box)); if (rcut == 0) { - rcut = 10*rmax; + rcut = 10 * rmax; } rcut2 = gmx::square(rcut); - invbw = 1/bw; - nbin = static_cast(rcut*invbw)+2; + invbw = 1 / bw; + nbin = static_cast(rcut * invbw) + 2; snew(hist, nbin); rmin2 = gmx::square(rmin); @@ -292,10 +286,10 @@ int gmx_spol(int argc, char *argv[]) { mol = index[1][m]; a0 = molindex[mol]; - a1 = molindex[mol+1]; + a1 = molindex[mol + 1]; for (i = 0; i < nrefgrp; i++) { - pbc_dx(&pbc, x[a0+srefat], bCom ? xref : x[index[0][i]], trial); + pbc_dx(&pbc, x[a0 + srefat], bCom ? xref : x[index[0][i]], trial); rtry2 = norm2(trial); if (i == 0 || rtry2 < rdx2) { @@ -305,7 +299,7 @@ int gmx_spol(int argc, char *argv[]) } if (rdx2 < rcut2) { - hist[static_cast(std::sqrt(rdx2)*invbw)+1]++; + hist[static_cast(std::sqrt(rdx2) * invbw) + 1]++; } if (rdx2 >= rmin2 && rdx2 < rmax2) { @@ -322,30 +316,30 @@ int gmx_spol(int argc, char *argv[]) q = atom[a].q - qav; for (d = 0; d < DIM; d++) { - dip[d] += q*x[a][d]; + dip[d] += q * x[a][d]; } } for (d = 0; d < DIM; d++) { dir[d] = -x[a0][d]; } - for (a = a0+1; a < a0+3; a++) + for (a = a0 + 1; a < a0 + 3; a++) { for (d = 0; d < DIM; d++) { - dir[d] += 0.5*x[a][d]; + dir[d] += 0.5 * x[a][d]; } } unitv(dir, dir); svmul(ENM2DEBYE, dip, dip); - dip2 = norm2(dip); - sdip += std::sqrt(dip2); + dip2 = norm2(dip); + sdip += std::sqrt(dip2); sdip2 += dip2; for (d = 0; d < DIM; d++) { - sinp += dx[d]*dip[d]; - sdinp += dx[d]*(dip[d] - refdip*dir[d]); + sinp += dx[d] * dip[d]; + sdinp += dx[d] * (dip[d] - refdip * dir[d]); } ntot++; @@ -353,8 +347,7 @@ int gmx_spol(int argc, char *argv[]) } nf++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); gmx_rmpbc_done(gpbc); @@ -362,29 +355,26 @@ int gmx_spol(int argc, char *argv[]) sfree(x); close_trx(status); - fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", - rmax, static_cast(ntot)/nf); + fprintf(stderr, "Average number of molecules within %g nm is %.1f\n", rmax, + static_cast(ntot) / nf); if (ntot > 0) { - sdip /= ntot; + sdip /= ntot; sdip2 /= ntot; - sinp /= ntot; + sinp /= ntot; sdinp /= ntot; - fprintf(stderr, "Average dipole: %f (D), std.dev. %f\n", - sdip, std::sqrt(sdip2-gmx::square(sdip))); - fprintf(stderr, "Average radial component of the dipole: %f (D)\n", - sinp); - fprintf(stderr, "Average radial component of the polarization: %f (D)\n", - sdinp); + fprintf(stderr, "Average dipole: %f (D), std.dev. %f\n", sdip, + std::sqrt(sdip2 - gmx::square(sdip))); + fprintf(stderr, "Average radial component of the dipole: %f (D)\n", sinp); + fprintf(stderr, "Average radial component of the polarization: %f (D)\n", sdinp); } - fp = xvgropen(opt2fn("-o", NFILE, fnm), - "Cumulative solvent distribution", "r (nm)", "molecules", oenv); + fp = xvgropen(opt2fn("-o", NFILE, fnm), "Cumulative solvent distribution", "r (nm)", "molecules", oenv); nmol = 0; for (i = 0; i <= nbin; i++) { nmol += hist[i]; - fprintf(fp, "%g %g\n", i*bw, nmol/nf); + fprintf(fp, "%g %g\n", i * bw, nmol / nf); } xvgrclose(fp); diff --git a/src/gromacs/gmxana/gmx_tcaf.cpp b/src/gromacs/gmxana/gmx_tcaf.cpp index 7e1553e18e..b4c8e1952f 100644 --- a/src/gromacs/gmxana/gmx_tcaf.cpp +++ b/src/gromacs/gmxana/gmx_tcaf.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,24 +62,45 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -#define NK 24 +#define NK 24 #define NPK 4 -#define NKC 6 +#define NKC 6 #define NKC0 4 -static const int kset_c[NKC+1] = { 0, 3, 9, 13, 16, 19, NK }; - -static rvec v0[NK] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 1, 0}, {1, -1, 0}, {1, 0, 1}, {1, 0, -1}, {0, 1, 1}, {0, 1, -1}, {1, 1, 1}, {1, 1, -1}, {1, -1, 1}, {-1, 1, 1}, {2, 0, 0}, {0, 2, 0}, {0, 0, 2}, {3, 0, 0}, {0, 3, 0}, {0, 0, 3}, {4, 0, 0}, {0, 4, 0}, {0, 0, 4}}; -static rvec v1[NK] = {{0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 1, 0}, {0, 1, 0}, {1, 0, 0}, {1, 0, 0}, {1, -1, 0}, {1, -1, 0}, {1, 0, -1}, { 0, 1, -1}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}}; -static rvec v2[NK] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {1, -1, 0}, {1, 1, 0}, {1, 0, -1}, {1, 0, 1}, {0, 1, -1}, {0, 1, 1}, {1, 1, -2}, {1, 1, 2}, {1, 2, 1}, { 2, 1, 1}, {0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; - -static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, - real rho, real wt, const char *fn_trans, - const char *fn_tca, const char *fn_tc, - const char *fn_tcf, const char *fn_cub, - const char *fn_vk, const gmx_output_env_t *oenv) +static const int kset_c[NKC + 1] = { 0, 3, 9, 13, 16, 19, NK }; + +static rvec v0[NK] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 1, 0 }, { 1, -1, 0 }, + { 1, 0, 1 }, { 1, 0, -1 }, { 0, 1, 1 }, { 0, 1, -1 }, { 1, 1, 1 }, + { 1, 1, -1 }, { 1, -1, 1 }, { -1, 1, 1 }, { 2, 0, 0 }, { 0, 2, 0 }, + { 0, 0, 2 }, { 3, 0, 0 }, { 0, 3, 0 }, { 0, 0, 3 }, { 4, 0, 0 }, + { 0, 4, 0 }, { 0, 0, 4 } }; +static rvec v1[NK] = { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 0 }, { 0, 0, 1 }, { 0, 0, 1 }, + { 0, 1, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 0, 0 }, { 1, -1, 0 }, + { 1, -1, 0 }, { 1, 0, -1 }, { 0, 1, -1 }, { 0, 1, 0 }, { 0, 0, 1 }, + { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 }, + { 0, 0, 1 }, { 1, 0, 0 } }; +static rvec v2[NK] = { { 0, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 }, { 1, -1, 0 }, { 1, 1, 0 }, + { 1, 0, -1 }, { 1, 0, 1 }, { 0, 1, -1 }, { 0, 1, 1 }, { 1, 1, -2 }, + { 1, 1, 2 }, { 1, 2, 1 }, { 2, 1, 1 }, { 0, 0, 1 }, { 1, 0, 0 }, + { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, + { 1, 0, 0 }, { 0, 1, 0 } }; + +static void process_tcaf(int nframes, + real dt, + int nkc, + real** tc, + rvec* kfac, + real rho, + real wt, + const char* fn_trans, + const char* fn_tca, + const char* fn_tc, + const char* fn_tcf, + const char* fn_cub, + const char* fn_vk, + const gmx_output_env_t* oenv) { - FILE *fp, *fp_vk, *fp_cub = nullptr; + FILE * fp, *fp_vk, *fp_cub = nullptr; int nk, ntc; real **tcaf, **tcafc = nullptr, eta, *sig; int i, j, k, kc; @@ -87,15 +108,14 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, double fitparms[3]; nk = kset_c[nkc]; - ntc = nk*NPK; + ntc = nk * NPK; if (fn_trans) { - fp = xvgropen(fn_trans, "Transverse Current", "Time (ps)", "TC (nm/ps)", - oenv); + fp = xvgropen(fn_trans, "Transverse Current", "Time (ps)", "TC (nm/ps)", oenv); for (i = 0; i < nframes; i++) { - fprintf(fp, "%g", i*dt); + fprintf(fp, "%g", i * dt); for (j = 0; j < ntc; j++) { fprintf(fp, " %g", tc[j][i]); @@ -106,10 +126,10 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, do_view(oenv, fn_trans, "-nxy"); } - ncorr = (nframes+1)/2; - if (ncorr > gmx::roundToInt(5*wt/dt)) + ncorr = (nframes + 1) / 2; + if (ncorr > gmx::roundToInt(5 * wt / dt)) { - ncorr = gmx::roundToInt(5*wt/dt)+1; + ncorr = gmx::roundToInt(5 * wt / dt) + 1; } snew(tcaf, nk); for (k = 0; k < nk; k++) @@ -127,31 +147,29 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, snew(sig, ncorr); for (i = 0; i < ncorr; i++) { - sig[i] = std::exp(0.5*i*dt/wt); + sig[i] = std::exp(0.5 * i * dt / wt); } - low_do_autocorr(fn_tca, oenv, "Transverse Current Autocorrelation Functions", - nframes, ntc, ncorr, tc, dt, eacNormal, - 1, FALSE, FALSE, FALSE, 0, 0, 0); + low_do_autocorr(fn_tca, oenv, "Transverse Current Autocorrelation Functions", nframes, ntc, + ncorr, tc, dt, eacNormal, 1, FALSE, FALSE, FALSE, 0, 0, 0); do_view(oenv, fn_tca, "-nxy"); - fp = xvgropen(fn_tc, "Transverse Current Autocorrelation Functions", - "Time (ps)", "TCAF", oenv); + fp = xvgropen(fn_tc, "Transverse Current Autocorrelation Functions", "Time (ps)", "TCAF", oenv); for (i = 0; i < ncorr; i++) { kc = 0; - fprintf(fp, "%g", i*dt); + fprintf(fp, "%g", i * dt); for (k = 0; k < nk; k++) { for (j = 0; j < NPK; j++) { - tcaf[k][i] += tc[NPK*k+j][i]; + tcaf[k][i] += tc[NPK * k + j][i]; } if (fn_cub) { for (j = 0; j < NPK; j++) { - tcafc[kc][i] += tc[NPK*k+j][i]; + tcafc[kc][i] += tc[NPK * k + j][i]; } } if (i == 0) @@ -163,7 +181,7 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, tcaf[k][i] /= tcaf[k][0]; fprintf(fp, " %g", tcaf[k][i]); } - if (k+1 == kset_c[kc+1]) + if (k + 1 == kset_c[kc + 1]) { kc++; } @@ -182,15 +200,14 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, for (i = 1; i < ncorr; i++) { tcafc[kc][i] /= tcafc[kc][0]; - fprintf(fp_cub, "%g %g\n", i*dt, tcafc[kc][i]); + fprintf(fp_cub, "%g %g\n", i * dt, tcafc[kc][i]); } fprintf(fp_cub, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); tcafc[kc][0] = 1.0; } } - fp_vk = xvgropen(fn_vk, "Fits", "k (nm\\S-1\\N)", - "\\8h\\4 (10\\S-3\\N kg m\\S-1\\N s\\S-1\\N)", oenv); + fp_vk = xvgropen(fn_vk, "Fits", "k (nm\\S-1\\N)", "\\8h\\4 (10\\S-3\\N kg m\\S-1\\N s\\S-1\\N)", oenv); if (output_env_get_print_xvgr_codes(oenv)) { fprintf(fp_vk, "@ s0 symbol 2\n"); @@ -205,19 +222,17 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, fp = xvgropen(fn_tcf, "TCAF Fits", "Time (ps)", "", oenv); for (k = 0; k < nk; k++) { - tcaf[k][0] = 1.0; - fitparms[0] = 1; - fitparms[1] = 1; - do_lmfit(ncorr, tcaf[k], sig, dt, nullptr, 0, ncorr*dt, - oenv, bDebugMode(), effnVAC, fitparms, 0, nullptr); - eta = 1000*fitparms[1]*rho/ - (4*fitparms[0]*PICO*norm2(kfac[k])/(NANO*NANO)); - fprintf(stdout, "k %6.3f tau %6.3f eta %8.5f 10^-3 kg/(m s)\n", - norm(kfac[k]), fitparms[0], eta); + tcaf[k][0] = 1.0; + fitparms[0] = 1; + fitparms[1] = 1; + do_lmfit(ncorr, tcaf[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC, + fitparms, 0, nullptr); + eta = 1000 * fitparms[1] * rho / (4 * fitparms[0] * PICO * norm2(kfac[k]) / (NANO * NANO)); + fprintf(stdout, "k %6.3f tau %6.3f eta %8.5f 10^-3 kg/(m s)\n", norm(kfac[k]), fitparms[0], eta); fprintf(fp_vk, "%6.3f %g\n", norm(kfac[k]), eta); for (i = 0; i < ncorr; i++) { - fprintf(fp, "%g %g\n", i*dt, fit_function(effnVAC, fitparms, i*dt)); + fprintf(fp, "%g %g\n", i * dt, fit_function(effnVAC, fitparms, i * dt)); } fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } @@ -230,20 +245,19 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, fprintf(fp_vk, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); for (k = 0; k < nkc; k++) { - tcafc[k][0] = 1.0; - fitparms[0] = 1; - fitparms[1] = 1; - do_lmfit(ncorr, tcafc[k], sig, dt, nullptr, 0, ncorr*dt, - oenv, bDebugMode(), effnVAC, fitparms, 0, nullptr); - eta = 1000*fitparms[1]*rho/ - (4*fitparms[0]*PICO*norm2(kfac[kset_c[k]])/(NANO*NANO)); - fprintf(stdout, - "k %6.3f tau %6.3f Omega %6.3f eta %8.5f 10^-3 kg/(m s)\n", + tcafc[k][0] = 1.0; + fitparms[0] = 1; + fitparms[1] = 1; + do_lmfit(ncorr, tcafc[k], sig, dt, nullptr, 0, ncorr * dt, oenv, bDebugMode(), effnVAC, + fitparms, 0, nullptr); + eta = 1000 * fitparms[1] * rho + / (4 * fitparms[0] * PICO * norm2(kfac[kset_c[k]]) / (NANO * NANO)); + fprintf(stdout, "k %6.3f tau %6.3f Omega %6.3f eta %8.5f 10^-3 kg/(m s)\n", norm(kfac[kset_c[k]]), fitparms[0], fitparms[1], eta); fprintf(fp_vk, "%6.3f %g\n", norm(kfac[kset_c[k]]), eta); for (i = 0; i < ncorr; i++) { - fprintf(fp_cub, "%g %g\n", i*dt, fit_function(effnVAC, fitparms, i*dt)); + fprintf(fp_cub, "%g %g\n", i * dt, fit_function(effnVAC, fitparms, i * dt)); } fprintf(fp_cub, "%s\n", output_env_get_print_xvgr_codes(oenv) ? "&" : ""); } @@ -256,9 +270,9 @@ static void process_tcaf(int nframes, real dt, int nkc, real **tc, rvec *kfac, } -int gmx_tcaf(int argc, char *argv[]) +int gmx_tcaf(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes tranverse current autocorrelations.", "These are used to estimate the shear viscosity, [GRK]eta[grk].", "For details see: Palmer, Phys. Rev. E 49 (1994) pp 359-366.[PAR]", @@ -270,12 +284,15 @@ int gmx_tcaf(int argc, char *argv[]) "combination with the velocity in 2 perpendicular directions. This gives", "a total of 16*2*2=64 transverse currents. One autocorrelation is", "calculated fitted for each k-vector, which gives 16 TCAFs. Each of", - "these TCAFs is fitted to [MATH]f(t) = [EXP]-v[exp]([COSH]Wv[cosh] + 1/W [SINH]Wv[sinh])[math],", - "[MATH]v = -t/(2 [GRK]tau[grk])[math], [MATH]W = [SQRT]1 - 4 [GRK]tau[grk] [GRK]eta[grk]/[GRK]rho[grk] k^2[sqrt][math], which gives 16 values of [GRK]tau[grk]", - "and [GRK]eta[grk]. The fit weights decay exponentially with time constant [MATH]w[math] (given with [TT]-wt[tt]) as [MATH][EXP]-t/w[exp][math], and the TCAF and", + "these TCAFs is fitted to [MATH]f(t) = [EXP]-v[exp]([COSH]Wv[cosh] + 1/W ", + "[SINH]Wv[sinh])[math],", + "[MATH]v = -t/(2 [GRK]tau[grk])[math], [MATH]W = [SQRT]1 - 4 [GRK]tau[grk] ", + "[GRK]eta[grk]/[GRK]rho[grk] k^2[sqrt][math], which gives 16 values of [GRK]tau[grk]", + "and [GRK]eta[grk]. The fit weights decay exponentially with time constant [MATH]w[math] ", + "(given with [TT]-wt[tt]) as [MATH][EXP]-t/w[exp][math], and the TCAF and", "fit are calculated up to time [MATH]5*w[math].", - "The [GRK]eta[grk] values should be fitted to [MATH]1 - a [GRK]eta[grk](k) k^2[math], from which", - "one can estimate the shear viscosity at k=0.[PAR]", + "The [GRK]eta[grk] values should be fitted to [MATH]1 - a [GRK]eta[grk](k) k^2[math], ", + "from which one can estimate the shear viscosity at k=0.[PAR]", "When the box is cubic, one can use the option [TT]-oc[tt], which", "averages the TCAFs over all k-vectors with the same length.", "This results in more accurate TCAFs.", @@ -285,22 +302,20 @@ int gmx_tcaf(int argc, char *argv[]) "molecules instead of atoms. In this case, the index group should", "consist of molecule numbers instead of atom numbers.[PAR]", "The k-dependent viscosities in the [TT]-ov[tt] file should be", - "fitted to [MATH][GRK]eta[grk](k) = [GRK]eta[grk][SUB]0[sub] (1 - a k^2)[math] to obtain the viscosity at", + "fitted to [MATH][GRK]eta[grk](k) = [GRK]eta[grk][SUB]0[sub] (1 - a k^2)[math] to obtain ", + "the viscosity at", "infinite wavelength.[PAR]", "[BB]Note:[bb] make sure you write coordinates and velocities often enough.", "The initial, non-exponential, part of the autocorrelation function", "is very important for obtaining a good fit." }; - static gmx_bool bMol = FALSE, bK34 = FALSE; - static real wt = 5; - t_pargs pa[] = { - { "-mol", FALSE, etBOOL, {&bMol}, - "Calculate TCAF of molecules" }, - { "-k34", FALSE, etBOOL, {&bK34}, - "Also use k=(3,0,0) and k=(4,0,0)" }, - { "-wt", FALSE, etREAL, {&wt}, - "Exponential decay time for the TCAF fit weights" } + static gmx_bool bMol = FALSE, bK34 = FALSE; + static real wt = 5; + t_pargs pa[] = { + { "-mol", FALSE, etBOOL, { &bMol }, "Calculate TCAF of molecules" }, + { "-k34", FALSE, etBOOL, { &bK34 }, "Also use k=(3,0,0) and k=(4,0,0)" }, + { "-wt", FALSE, etREAL, { &wt }, "Exponential decay time for the TCAF fit weights" } }; t_topology top; @@ -309,46 +324,39 @@ int gmx_tcaf(int argc, char *argv[]) matrix box; gmx_bool bTop; int gnx; - int *index, *atndx = nullptr, at; - char *grpname; + int * index, *atndx = nullptr, at; + char* grpname; char title[256]; real t0, t1, dt, m, mtot, sysmass, rho, sx, cx; - t_trxstatus *status; + t_trxstatus* status; int nframes, n_alloc, i, j, k, d; rvec mv_mol, cm_mol, kfac[NK]; int nkc, nk, ntc; - real **tc; - gmx_output_env_t *oenv; + real** tc; + gmx_output_env_t* oenv; #define NHISTO 360 - t_filenm fnm[] = { - { efTRN, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-ot", "transcur", ffOPTWR }, - { efXVG, "-oa", "tcaf_all", ffWRITE }, - { efXVG, "-o", "tcaf", ffWRITE }, - { efXVG, "-of", "tcaf_fit", ffWRITE }, - { efXVG, "-oc", "tcaf_cub", ffOPTWR }, - { efXVG, "-ov", "visc_k", ffWRITE } - }; + t_filenm fnm[] = { { efTRN, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-ot", "transcur", ffOPTWR }, + { efXVG, "-oa", "tcaf_all", ffWRITE }, { efXVG, "-o", "tcaf", ffWRITE }, + { efXVG, "-of", "tcaf_fit", ffWRITE }, { efXVG, "-oc", "tcaf_cub", ffOPTWR }, + { efXVG, "-ov", "visc_k", ffWRITE } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; } - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, nullptr, nullptr, box, - TRUE); + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, nullptr, nullptr, box, TRUE); get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname); if (bMol) @@ -368,9 +376,9 @@ int gmx_tcaf(int argc, char *argv[]) { nkc = NKC0; } - nk = kset_c[nkc]; + nk = kset_c[nkc]; GMX_ASSERT(nk >= 16, "Has to be over 16 because nkc is either NKC or NKC0."); - ntc = nk*NPK; + ntc = nk * NPK; sprintf(title, "Velocity Autocorrelation Function for %s", grpname); @@ -398,8 +406,7 @@ int gmx_tcaf(int argc, char *argv[]) sysmass += top.atoms.atom[i].m; } - read_first_frame(oenv, &status, ftp2fn(efTRN, NFILE, fnm), &fr, - TRX_NEED_X | TRX_NEED_V); + read_first_frame(oenv, &status, ftp2fn(efTRN, NFILE, fnm), &fr, TRX_NEED_X | TRX_NEED_V); t0 = fr.time; n_alloc = 0; @@ -418,12 +425,12 @@ int gmx_tcaf(int argc, char *argv[]) } } - rho += 1/det(fr.box); + rho += 1 / det(fr.box); for (k = 0; k < nk; k++) { for (d = 0; d < DIM; d++) { - kfac[k][d] = 2*M_PI*v0[k][d]/fr.box[d][d]; + kfac[k][d] = 2 * M_PI * v0[k][d] / fr.box[d][d]; } } for (i = 0; i < ntc; i++) @@ -438,19 +445,19 @@ int gmx_tcaf(int argc, char *argv[]) clear_rvec(mv_mol); clear_rvec(cm_mol); mtot = 0; - for (j = 0; j < atndx[index[i]+1] - atndx[index[i]]; j++) + for (j = 0; j < atndx[index[i] + 1] - atndx[index[i]]; j++) { - at = atndx[index[i]] + j; - m = top.atoms.atom[at].m; - mv_mol[XX] += m*fr.v[at][XX]; - mv_mol[YY] += m*fr.v[at][YY]; - mv_mol[ZZ] += m*fr.v[at][ZZ]; - cm_mol[XX] += m*fr.x[at][XX]; - cm_mol[YY] += m*fr.x[at][YY]; - cm_mol[ZZ] += m*fr.x[at][ZZ]; - mtot += m; + at = atndx[index[i]] + j; + m = top.atoms.atom[at].m; + mv_mol[XX] += m * fr.v[at][XX]; + mv_mol[YY] += m * fr.v[at][YY]; + mv_mol[ZZ] += m * fr.v[at][ZZ]; + cm_mol[XX] += m * fr.x[at][XX]; + cm_mol[YY] += m * fr.x[at][YY]; + cm_mol[ZZ] += m * fr.x[at][ZZ]; + mtot += m; } - svmul(1.0/mtot, cm_mol, cm_mol); + svmul(1.0 / mtot, cm_mol, cm_mol); } else { @@ -464,34 +471,31 @@ int gmx_tcaf(int argc, char *argv[]) j = 0; for (k = 0; k < nk; k++) { - sx = std::sin(iprod(kfac[k], cm_mol)); - cx = std::cos(iprod(kfac[k], cm_mol)); - tc[j][nframes] += sx*iprod(v1[k], mv_mol); + sx = std::sin(iprod(kfac[k], cm_mol)); + cx = std::cos(iprod(kfac[k], cm_mol)); + tc[j][nframes] += sx * iprod(v1[k], mv_mol); j++; - tc[j][nframes] += cx*iprod(v1[k], mv_mol); + tc[j][nframes] += cx * iprod(v1[k], mv_mol); j++; - tc[j][nframes] += sx*iprod(v2[k], mv_mol); + tc[j][nframes] += sx * iprod(v2[k], mv_mol); j++; - tc[j][nframes] += cx*iprod(v2[k], mv_mol); + tc[j][nframes] += cx * iprod(v2[k], mv_mol); j++; } } t1 = fr.time; nframes++; - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); close_trx(status); - dt = (t1-t0)/(nframes-1); + dt = (t1 - t0) / (nframes - 1); - rho *= sysmass/nframes*AMU/(NANO*NANO*NANO); + rho *= sysmass / nframes * AMU / (NANO * NANO * NANO); fprintf(stdout, "Density = %g (kg/m^3)\n", rho); - process_tcaf(nframes, dt, nkc, tc, kfac, rho, wt, - opt2fn_null("-ot", NFILE, fnm), - opt2fn("-oa", NFILE, fnm), opt2fn("-o", NFILE, fnm), - opt2fn("-of", NFILE, fnm), opt2fn_null("-oc", NFILE, fnm), - opt2fn("-ov", NFILE, fnm), oenv); + process_tcaf(nframes, dt, nkc, tc, kfac, rho, wt, opt2fn_null("-ot", NFILE, fnm), + opt2fn("-oa", NFILE, fnm), opt2fn("-o", NFILE, fnm), opt2fn("-of", NFILE, fnm), + opt2fn_null("-oc", NFILE, fnm), opt2fn("-ov", NFILE, fnm), oenv); return 0; } diff --git a/src/gromacs/gmxana/gmx_traj.cpp b/src/gromacs/gmxana/gmx_traj.cpp index 606abcadff..059081a9d8 100644 --- a/src/gromacs/gmxana/gmx_traj.cpp +++ b/src/gromacs/gmxana/gmx_traj.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,8 +66,8 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -static void low_print_data(FILE *fp, real time, rvec x[], int n, const int *index, - const gmx_bool bDim[], const char *sffmt) +static void +low_print_data(FILE* fp, real time, rvec x[], int n, const int* index, const gmx_bool bDim[], const char* sffmt) { int i, ii, d; @@ -97,8 +97,7 @@ static void low_print_data(FILE *fp, real time, rvec x[], int n, const int *inde fprintf(fp, "\n"); } -static void average_data(rvec x[], rvec xav[], const real *mass, - int ngrps, const int isize[], int **index) +static void average_data(rvec x[], rvec xav[], const real* mass, int ngrps, const int isize[], int** index) { int g, i, ind, d; real m; @@ -135,7 +134,7 @@ static void average_data(rvec x[], rvec xav[], const real *mass, { for (d = 0; d < DIM; d++) { - xav[g][d] = sum[d]/mtot; + xav[g][d] = sum[d] / mtot; } } else @@ -149,11 +148,18 @@ static void average_data(rvec x[], rvec xav[], const real *mass, } } -static void print_data(FILE *fp, real time, rvec x[], real *mass, gmx_bool bCom, - int ngrps, int isize[], int **index, gmx_bool bDim[], - const char *sffmt) +static void print_data(FILE* fp, + real time, + rvec x[], + real* mass, + gmx_bool bCom, + int ngrps, + int isize[], + int** index, + gmx_bool bDim[], + const char* sffmt) { - static rvec *xav = nullptr; + static rvec* xav = nullptr; if (bCom) { @@ -170,11 +176,16 @@ static void print_data(FILE *fp, real time, rvec x[], real *mass, gmx_bool bCom, } } -static void write_trx_x(t_trxstatus *status, const t_trxframe *fr, real *mass, gmx_bool bCom, - int ngrps, int isize[], int **index) +static void write_trx_x(t_trxstatus* status, + const t_trxframe* fr, + real* mass, + gmx_bool bCom, + int ngrps, + int isize[], + int** index) { - static rvec *xav = nullptr; - static t_atoms *atoms = nullptr; + static rvec* xav = nullptr; + static t_atoms* atoms = nullptr; t_trxframe fr_av; int i; @@ -209,12 +220,18 @@ static void write_trx_x(t_trxstatus *status, const t_trxframe *fr, real *mass, g } } -static void make_legend(FILE *fp, int ngrps, int isize, int index[], - char **name, gmx_bool bCom, gmx_bool bMol, const gmx_bool bDim[], - const gmx_output_env_t *oenv) +static void make_legend(FILE* fp, + int ngrps, + int isize, + int index[], + char** name, + gmx_bool bCom, + gmx_bool bMol, + const gmx_bool bDim[], + const gmx_output_env_t* oenv) { - char **leg; - const char *dimtxt[] = { " X", " Y", " Z", "" }; + char** leg; + const char* dimtxt[] = { " X", " Y", " Z", "" }; int n, i, j, d; if (bCom) @@ -226,7 +243,7 @@ static void make_legend(FILE *fp, int ngrps, int isize, int index[], n = isize; } - snew(leg, 4*n); + snew(leg, 4 * n); j = 0; for (i = 0; i < n; i++) { @@ -237,7 +254,7 @@ static void make_legend(FILE *fp, int ngrps, int isize, int index[], snew(leg[j], STRLEN); if (bMol) { - sprintf(leg[j], "mol %d%s", index[i]+1, dimtxt[d]); + sprintf(leg[j], "mol %d%s", index[i] + 1, dimtxt[d]); } else if (bCom) { @@ -245,7 +262,7 @@ static void make_legend(FILE *fp, int ngrps, int isize, int index[], } else { - sprintf(leg[j], "atom %d%s", index[i]+1, dimtxt[d]); + sprintf(leg[j], "atom %d%s", index[i] + 1, dimtxt[d]); } j++; } @@ -262,12 +279,12 @@ static void make_legend(FILE *fp, int ngrps, int isize, int index[], static real ekrot(rvec x[], rvec v[], const real mass[], int isize, const int index[]) { - real TCM[5][5], L[5][5]; - double tm, m0, lxx, lxy, lxz, lyy, lyz, lzz, ekrot; - rvec a0, ocm; - dvec dx, b0; - dvec xcm, vcm, acm; - int i, j, m, n; + real TCM[5][5], L[5][5]; + double tm, m0, lxx, lxy, lxz, lyy, lyz, lzz, ekrot; + rvec a0, ocm; + dvec dx, b0; + dvec xcm, vcm, acm; + int i, j, m, n; clear_dvec(xcm); clear_dvec(vcm); @@ -275,15 +292,15 @@ static real ekrot(rvec x[], rvec v[], const real mass[], int isize, const int in tm = 0.0; for (i = 0; i < isize; i++) { - j = index[i]; - m0 = mass[j]; + j = index[i]; + m0 = mass[j]; tm += m0; cprod(x[j], v[j], a0); for (m = 0; (m < DIM); m++) { - xcm[m] += m0*x[j][m]; /* c.o.m. position */ - vcm[m] += m0*v[j][m]; /* c.o.m. velocity */ - acm[m] += m0*a0[m]; /* rotational velocity around c.o.m. */ + xcm[m] += m0 * x[j][m]; /* c.o.m. position */ + vcm[m] += m0 * v[j][m]; /* c.o.m. velocity */ + acm[m] += m0 * a0[m]; /* rotational velocity around c.o.m. */ } } dcprod(xcm, vcm, b0); @@ -291,7 +308,7 @@ static real ekrot(rvec x[], rvec v[], const real mass[], int isize, const int in { xcm[m] /= tm; vcm[m] /= tm; - acm[m] -= b0[m]/tm; + acm[m] -= b0[m] / tm; } lxx = lxy = lxz = lyy = lyz = lzz = 0.0; @@ -303,23 +320,23 @@ static real ekrot(rvec x[], rvec v[], const real mass[], int isize, const int in { dx[m] = x[j][m] - xcm[m]; } - lxx += dx[XX]*dx[XX]*m0; - lxy += dx[XX]*dx[YY]*m0; - lxz += dx[XX]*dx[ZZ]*m0; - lyy += dx[YY]*dx[YY]*m0; - lyz += dx[YY]*dx[ZZ]*m0; - lzz += dx[ZZ]*dx[ZZ]*m0; + lxx += dx[XX] * dx[XX] * m0; + lxy += dx[XX] * dx[YY] * m0; + lxz += dx[XX] * dx[ZZ] * m0; + lyy += dx[YY] * dx[YY] * m0; + lyz += dx[YY] * dx[ZZ] * m0; + lzz += dx[ZZ] * dx[ZZ] * m0; } - L[XX][XX] = lyy + lzz; + L[XX][XX] = lyy + lzz; L[YY][XX] = -lxy; L[ZZ][XX] = -lxz; L[XX][YY] = -lxy; - L[YY][YY] = lxx + lzz; + L[YY][YY] = lxx + lzz; L[ZZ][YY] = -lyz; L[XX][ZZ] = -lxz; L[YY][ZZ] = -lyz; - L[ZZ][ZZ] = lxx + lyy; + L[ZZ][ZZ] = lxx + lyy; m_inv_gen(&L[0][0], DIM, &TCM[0][0]); @@ -330,9 +347,9 @@ static real ekrot(rvec x[], rvec v[], const real mass[], int isize, const int in { for (n = 0; n < DIM; n++) { - ocm[m] += TCM[m][n]*acm[n]; + ocm[m] += TCM[m][n] * acm[n]; } - ekrot += 0.5*ocm[m]*acm[m]; + ekrot += 0.5 * ocm[m] * acm[m]; } return ekrot; @@ -351,12 +368,12 @@ static real ektrans(rvec v[], const real mass[], int isize, const int index[]) j = index[i]; for (d = 0; d < DIM; d++) { - mvcom[d] += mass[j]*v[j][d]; + mvcom[d] += mass[j] * v[j][d]; } mtot += mass[j]; } - return dnorm2(mvcom)/(mtot*2); + return dnorm2(mvcom) / (mtot * 2); } static real temp(rvec v[], const real mass[], int isize, const int index[]) @@ -367,11 +384,11 @@ static real temp(rvec v[], const real mass[], int isize, const int index[]) ekin2 = 0; for (i = 0; i < isize; i++) { - j = index[i]; - ekin2 += mass[j]*norm2(v[j]); + j = index[i]; + ekin2 += mass[j] * norm2(v[j]); } - return ekin2/(3*isize*BOLTZ); + return ekin2 / (3 * isize * BOLTZ); } static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) @@ -381,20 +398,20 @@ static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) for (d = 0; d < DIM; d++) { - hbox[d] = 0.5*box[d][d]; + hbox[d] = 0.5 * box[d][d]; } for (i = 0; i < natoms; i++) { - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { - while (x[i][m]-xp[i][m] <= -hbox[m]) + while (x[i][m] - xp[i][m] <= -hbox[m]) { for (d = 0; d <= m; d++) { x[i][d] += box[m][d]; } } - while (x[i][m]-xp[i][m] > hbox[m]) + while (x[i][m] - xp[i][m] > hbox[m]) { for (d = 0; d <= m; d++) { @@ -405,22 +422,30 @@ static void remove_jump(matrix box, int natoms, rvec xp[], rvec x[]) } } -static void write_pdb_bfac(const char *fname, const char *xname, - const char *title, t_atoms *atoms, int ePBC, matrix box, - int isize, int *index, int nfr_x, rvec *x, - int nfr_v, rvec *sum, - const gmx_bool bDim[], real scale_factor, - const gmx_output_env_t *oenv) +static void write_pdb_bfac(const char* fname, + const char* xname, + const char* title, + t_atoms* atoms, + int ePBC, + matrix box, + int isize, + int* index, + int nfr_x, + rvec* x, + int nfr_v, + rvec* sum, + const gmx_bool bDim[], + real scale_factor, + const gmx_output_env_t* oenv) { - FILE *fp; - real max, len2, scale; - int maxi; - int i, m, onedim; + FILE* fp; + real max, len2, scale; + int maxi; + int i, m, onedim; if ((nfr_x == 0) || (nfr_v == 0)) { - fprintf(stderr, "No frames found for %s, will not write %s\n", - title, fname); + fprintf(stderr, "No frames found for %s, will not write %s\n", title, fname); } else { @@ -443,7 +468,7 @@ static void write_pdb_bfac(const char *fname, const char *xname, onedim = -1; } } - scale = 1.0/nfr_v; + scale = 1.0 / nfr_v; for (i = 0; i < isize; i++) { svmul(scale, sum[index[i]], sum[index[i]]); @@ -452,8 +477,8 @@ static void write_pdb_bfac(const char *fname, const char *xname, fp = xvgropen(xname, title, "Atom", "Spatial component", oenv); for (i = 0; i < isize; i++) { - fprintf(fp, "%-5d %10.3f %10.3f %10.3f\n", 1+i, - sum[index[i]][XX], sum[index[i]][YY], sum[index[i]][ZZ]); + fprintf(fp, "%-5d %10.3f %10.3f %10.3f\n", 1 + i, sum[index[i]][XX], + sum[index[i]][YY], sum[index[i]][ZZ]); } xvgrclose(fp); max = 0; @@ -486,13 +511,12 @@ static void write_pdb_bfac(const char *fname, const char *xname, } else { - scale = 10.0/std::sqrt(max); + scale = 10.0 / std::sqrt(max); } } - printf("Maximum %s is %g on atom %d %s, res. %s %d\n", - title, std::sqrt(max), maxi+1, *(atoms->atomname[maxi]), - *(atoms->resinfo[atoms->atom[maxi].resind].name), + printf("Maximum %s is %g on atom %d %s, res. %s %d\n", title, std::sqrt(max), maxi + 1, + *(atoms->atomname[maxi]), *(atoms->resinfo[atoms->atom[maxi].resind].name), atoms->resinfo[atoms->atom[maxi].resind].nr); if (atoms->pdbinfo == nullptr) @@ -513,22 +537,21 @@ static void write_pdb_bfac(const char *fname, const char *xname, len2 += gmx::square(sum[index[i]][m]); } } - atoms->pdbinfo[index[i]].bfac = std::sqrt(len2)*scale; + atoms->pdbinfo[index[i]].bfac = std::sqrt(len2) * scale; } } else { for (i = 0; i < isize; i++) { - atoms->pdbinfo[index[i]].bfac = sum[index[i]][onedim]*scale; + atoms->pdbinfo[index[i]].bfac = sum[index[i]][onedim] * scale; } } write_sto_conf_indexed(fname, title, atoms, x, nullptr, ePBC, box, isize, index); } } -static void update_histo(int gnx, const int index[], rvec v[], - int *nhisto, int **histo, real binwidth) +static void update_histo(int gnx, const int index[], rvec v[], int* nhisto, int** histo, real binwidth) { int i, m, in, nnn; real vn, vnmax; @@ -541,17 +564,17 @@ static void update_histo(int gnx, const int index[], rvec v[], vn = norm(v[index[i]]); vnmax = std::max(vn, vnmax); } - vnmax *= 2; - *nhisto = static_cast(1+(vnmax/binwidth)); + vnmax *= 2; + *nhisto = static_cast(1 + (vnmax / binwidth)); snew(*histo, *nhisto); } for (i = 0; (i < gnx); i++) { vn = norm(v[index[i]]); - in = static_cast(vn/binwidth); + in = static_cast(vn / binwidth); if (in >= *nhisto) { - nnn = in+100; + nnn = in + 100; fprintf(stderr, "Extending histogram from %d to %d\n", *nhisto, nnn); srenew(*histo, nnn); @@ -565,24 +588,22 @@ static void update_histo(int gnx, const int index[], rvec v[], } } -static void print_histo(const char *fn, int nhisto, int histo[], real binwidth, - const gmx_output_env_t *oenv) +static void print_histo(const char* fn, int nhisto, int histo[], real binwidth, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; int i; - fp = xvgropen(fn, "Velocity distribution", "V (nm/ps)", "arbitrary units", - oenv); + fp = xvgropen(fn, "Velocity distribution", "V (nm/ps)", "arbitrary units", oenv); for (i = 0; (i < nhisto); i++) { - fprintf(fp, "%10.3e %10d\n", i*binwidth, histo[i]); + fprintf(fp, "%10.3e %10d\n", i * binwidth, histo[i]); } xvgrclose(fp); } -int gmx_traj(int argc, char *argv[]) +int gmx_traj(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] plots coordinates, velocities, forces and/or the box.", "With [TT]-com[tt] the coordinates, velocities and forces are", "calculated for the center of mass of each group.", @@ -615,95 +636,86 @@ int gmx_traj(int argc, char *argv[]) "", "See [gmx-trajectory] for plotting similar data for selections." }; - static gmx_bool bMol = FALSE, bCom = FALSE, bPBC = TRUE, bNoJump = FALSE; - static gmx_bool bX = TRUE, bY = TRUE, bZ = TRUE, bNorm = FALSE, bFP = FALSE; - static int ngroups = 1; - static real ctime = -1, scale = 0, binwidth = 1; - t_pargs pa[] = { - { "-com", FALSE, etBOOL, {&bCom}, - "Plot data for the com of each group" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Make molecules whole for COM" }, - { "-mol", FALSE, etBOOL, {&bMol}, + static gmx_bool bMol = FALSE, bCom = FALSE, bPBC = TRUE, bNoJump = FALSE; + static gmx_bool bX = TRUE, bY = TRUE, bZ = TRUE, bNorm = FALSE, bFP = FALSE; + static int ngroups = 1; + static real ctime = -1, scale = 0, binwidth = 1; + t_pargs pa[] = { + { "-com", FALSE, etBOOL, { &bCom }, "Plot data for the com of each group" }, + { "-pbc", FALSE, etBOOL, { &bPBC }, "Make molecules whole for COM" }, + { "-mol", + FALSE, + etBOOL, + { &bMol }, "Index contains molecule numbers instead of atom numbers" }, - { "-nojump", FALSE, etBOOL, {&bNoJump}, - "Remove jumps of atoms across the box" }, - { "-x", FALSE, etBOOL, {&bX}, - "Plot X-component" }, - { "-y", FALSE, etBOOL, {&bY}, - "Plot Y-component" }, - { "-z", FALSE, etBOOL, {&bZ}, - "Plot Z-component" }, - { "-ng", FALSE, etINT, {&ngroups}, - "Number of groups to consider" }, - { "-len", FALSE, etBOOL, {&bNorm}, - "Plot vector length" }, - { "-fp", FALSE, etBOOL, {&bFP}, - "Full precision output" }, - { "-bin", FALSE, etREAL, {&binwidth}, - "Binwidth for velocity histogram (nm/ps)" }, - { "-ctime", FALSE, etREAL, {&ctime}, + { "-nojump", FALSE, etBOOL, { &bNoJump }, "Remove jumps of atoms across the box" }, + { "-x", FALSE, etBOOL, { &bX }, "Plot X-component" }, + { "-y", FALSE, etBOOL, { &bY }, "Plot Y-component" }, + { "-z", FALSE, etBOOL, { &bZ }, "Plot Z-component" }, + { "-ng", FALSE, etINT, { &ngroups }, "Number of groups to consider" }, + { "-len", FALSE, etBOOL, { &bNorm }, "Plot vector length" }, + { "-fp", FALSE, etBOOL, { &bFP }, "Full precision output" }, + { "-bin", FALSE, etREAL, { &binwidth }, "Binwidth for velocity histogram (nm/ps)" }, + { "-ctime", + FALSE, + etREAL, + { &ctime }, "Use frame at this time for x in [TT]-cv[tt] and [TT]-cf[tt] instead of the average x" }, - { "-scale", FALSE, etREAL, {&scale}, + { "-scale", + FALSE, + etREAL, + { &scale }, "Scale factor for [REF].pdb[ref] output, 0 is autoscale" } }; - FILE *outx = nullptr, *outv = nullptr, *outf = nullptr, *outb = nullptr, *outt = nullptr; - FILE *outekt = nullptr, *outekr = nullptr; - t_topology top; - int ePBC; - real *mass, time; - const char *indexfn; - t_trxframe fr; - int flags, nvhisto = 0, *vhisto = nullptr; - rvec *xtop, *xp = nullptr; - rvec *sumx = nullptr, *sumv = nullptr, *sumf = nullptr; - matrix topbox; - t_trxstatus *status; - t_trxstatus *status_out = nullptr; - gmx_rmpbc_t gpbc = nullptr; - int i, j; - int nr_xfr, nr_vfr, nr_ffr; - char **grpname; - int *isize0, *isize; - int **index0, **index; - int *atndx; - t_block *mols; - gmx_bool bTop, bOX, bOXT, bOV, bOF, bOB, bOT, bEKT, bEKR, bCV, bCF; - gmx_bool bDim[4], bDum[4], bVD; - char sffmt[STRLEN]; - const char *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" }; - gmx_output_env_t *oenv; - - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-ox", "coord", ffOPTWR }, - { efTRX, "-oxt", "coord", ffOPTWR }, - { efXVG, "-ov", "veloc", ffOPTWR }, - { efXVG, "-of", "force", ffOPTWR }, - { efXVG, "-ob", "box", ffOPTWR }, - { efXVG, "-ot", "temp", ffOPTWR }, - { efXVG, "-ekt", "ektrans", ffOPTWR }, - { efXVG, "-ekr", "ekrot", ffOPTWR }, - { efXVG, "-vd", "veldist", ffOPTWR }, - { efPDB, "-cv", "veloc", ffOPTWR }, - { efPDB, "-cf", "force", ffOPTWR }, - { efXVG, "-av", "all_veloc", ffOPTWR }, - { efXVG, "-af", "all_force", ffOPTWR } + FILE * outx = nullptr, *outv = nullptr, *outf = nullptr, *outb = nullptr, *outt = nullptr; + FILE * outekt = nullptr, *outekr = nullptr; + t_topology top; + int ePBC; + real * mass, time; + const char* indexfn; + t_trxframe fr; + int flags, nvhisto = 0, *vhisto = nullptr; + rvec * xtop, *xp = nullptr; + rvec * sumx = nullptr, *sumv = nullptr, *sumf = nullptr; + matrix topbox; + t_trxstatus* status; + t_trxstatus* status_out = nullptr; + gmx_rmpbc_t gpbc = nullptr; + int i, j; + int nr_xfr, nr_vfr, nr_ffr; + char** grpname; + int * isize0, *isize; + int ** index0, **index; + int* atndx; + t_block* mols; + gmx_bool bTop, bOX, bOXT, bOV, bOF, bOB, bOT, bEKT, bEKR, bCV, bCF; + gmx_bool bDim[4], bDum[4], bVD; + char sffmt[STRLEN]; + const char* box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" }; + gmx_output_env_t* oenv; + + t_filenm fnm[] = { + { efTRX, "-f", nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXVG, "-ox", "coord", ffOPTWR }, + { efTRX, "-oxt", "coord", ffOPTWR }, { efXVG, "-ov", "veloc", ffOPTWR }, + { efXVG, "-of", "force", ffOPTWR }, { efXVG, "-ob", "box", ffOPTWR }, + { efXVG, "-ot", "temp", ffOPTWR }, { efXVG, "-ekt", "ektrans", ffOPTWR }, + { efXVG, "-ekr", "ekrot", ffOPTWR }, { efXVG, "-vd", "veldist", ffOPTWR }, + { efPDB, "-cv", "veloc", ffOPTWR }, { efPDB, "-cf", "force", ffOPTWR }, + { efXVG, "-av", "all_veloc", ffOPTWR }, { efXVG, "-af", "all_force", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME | PCA_TIME_UNIT | PCA_CAN_VIEW, NFILE, fnm, + asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } if (bMol) { - fprintf(stderr, "Interpreting indexfile entries as molecules.\n" + fprintf(stderr, + "Interpreting indexfile entries as molecules.\n" "Using center of mass.\n"); } @@ -738,8 +750,7 @@ int gmx_traj(int argc, char *argv[]) } std::string sffmt6 = gmx::formatString("%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt); - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, - &xtop, nullptr, topbox, + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, topbox, bCom && (bOX || bOXT || bOV || bOT || bEKT || bEKR)); sfree(xtop); if ((bMol || bCV || bCF) && !bTop) @@ -776,10 +787,10 @@ int gmx_traj(int argc, char *argv[]) { if (index0[0][i] < 0 || index0[0][i] >= mols->nr) { - gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)", - index0[0][i]+1, 1, mols->nr); + gmx_fatal(FARGS, "Molecule index (%d) is out of range (%d-%d)", index0[0][i] + 1, 1, + mols->nr); } - isize[i] = atndx[index0[0][i]+1] - atndx[index0[0][i]]; + isize[i] = atndx[index0[0][i] + 1] - atndx[index0[0][i]]; snew(index[i], isize[i]); for (j = 0; j < isize[i]; j++) { @@ -810,9 +821,8 @@ int gmx_traj(int argc, char *argv[]) if (bOX) { flags = flags | TRX_READ_X; - outx = xvgropen(opt2fn("-ox", NFILE, fnm), - bCom ? "Center of mass" : "Coordinate", - label, "Coordinate (nm)", oenv); + outx = xvgropen(opt2fn("-ox", NFILE, fnm), bCom ? "Center of mass" : "Coordinate", label, + "Coordinate (nm)", oenv); make_legend(outx, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOXT) @@ -823,23 +833,20 @@ int gmx_traj(int argc, char *argv[]) if (bOV) { flags = flags | TRX_READ_V; - outv = xvgropen(opt2fn("-ov", NFILE, fnm), - bCom ? "Center of mass velocity" : "Velocity", - label, "Velocity (nm/ps)", oenv); + outv = xvgropen(opt2fn("-ov", NFILE, fnm), bCom ? "Center of mass velocity" : "Velocity", + label, "Velocity (nm/ps)", oenv); make_legend(outv, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOF) { flags = flags | TRX_READ_F; - outf = xvgropen(opt2fn("-of", NFILE, fnm), "Force", - label, "Force (kJ mol\\S-1\\N nm\\S-1\\N)", - oenv); + outf = xvgropen(opt2fn("-of", NFILE, fnm), "Force", label, + "Force (kJ mol\\S-1\\N nm\\S-1\\N)", oenv); make_legend(outf, ngroups, isize0[0], index0[0], grpname, bCom, bMol, bDim, oenv); } if (bOB) { - outb = xvgropen(opt2fn("-ob", NFILE, fnm), "Box vector elements", - label, "(nm)", oenv); + outb = xvgropen(opt2fn("-ob", NFILE, fnm), "Box vector elements", label, "(nm)", oenv); xvgr_legend(outb, 6, box_leg, oenv); } @@ -850,8 +857,7 @@ int gmx_traj(int argc, char *argv[]) bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; - outt = xvgropen(opt2fn("-ot", NFILE, fnm), "Temperature", - label, "(K)", oenv); + outt = xvgropen(opt2fn("-ot", NFILE, fnm), "Temperature", label, "(K)", oenv); make_legend(outt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKT) @@ -861,8 +867,8 @@ int gmx_traj(int argc, char *argv[]) bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_V; - outekt = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation", - label, "Energy (kJ mol\\S-1\\N)", oenv); + outekt = xvgropen(opt2fn("-ekt", NFILE, fnm), "Center of mass translation", label, + "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekt, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bEKR) @@ -872,8 +878,8 @@ int gmx_traj(int argc, char *argv[]) bDum[ZZ] = FALSE; bDum[DIM] = TRUE; flags = flags | TRX_READ_X | TRX_READ_V; - outekr = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation", - label, "Energy (kJ mol\\S-1\\N)", oenv); + outekr = xvgropen(opt2fn("-ekr", NFILE, fnm), "Center of mass rotation", label, + "Energy (kJ mol\\S-1\\N)", oenv); make_legend(outekr, ngroups, isize[0], index[0], grpname, bCom, bMol, bDum, oenv); } if (bVD) @@ -899,7 +905,9 @@ int gmx_traj(int argc, char *argv[]) if ((bOV || bOF) && fn2ftp(ftp2fn(efTRX, NFILE, fnm)) == efXTC) { - gmx_fatal(FARGS, "Cannot extract velocities or forces since your input XTC file does not contain them."); + gmx_fatal(FARGS, + "Cannot extract velocities or forces since your input XTC file does not contain " + "them."); } if (bCV || bCF) @@ -980,8 +988,7 @@ int gmx_traj(int argc, char *argv[]) if (bOB && fr.bBox) { fprintf(outb, "\t%g", fr.time); - fprintf(outb, sffmt6.c_str(), - fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ], + fprintf(outb, sffmt6.c_str(), fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ], fr.box[YY][XX], fr.box[ZZ][XX], fr.box[ZZ][YY]); fprintf(outb, "\n"); } @@ -1012,9 +1019,8 @@ int gmx_traj(int argc, char *argv[]) } fprintf(outekr, "\n"); } - if ((bCV || bCF) && fr.bX && - (ctime < 0 || (fr.time >= ctime*0.999999 && - fr.time <= ctime*1.000001))) + if ((bCV || bCF) && fr.bX + && (ctime < 0 || (fr.time >= ctime * 0.999999 && fr.time <= ctime * 1.000001))) { for (i = 0; i < fr.natoms; i++) { @@ -1039,8 +1045,7 @@ int gmx_traj(int argc, char *argv[]) nr_ffr++; } - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); if (gpbc != nullptr) { @@ -1094,12 +1099,14 @@ int gmx_traj(int argc, char *argv[]) { if (ePBC != epbcNONE && !bNoJump) { - fprintf(stderr, "\nWARNING: More than one frame was used for option -cv or -cf\n" - "If atoms jump across the box you should use the -nojump or -ctime option\n\n"); + fprintf(stderr, + "\nWARNING: More than one frame was used for option -cv or -cf\n" + "If atoms jump across the box you should use the -nojump or -ctime " + "option\n\n"); } for (i = 0; i < isize[0]; i++) { - svmul(1.0/nr_xfr, sumx[index[0][i]], sumx[index[0][i]]); + svmul(1.0 / nr_xfr, sumx[index[0][i]], sumx[index[0][i]]); } } else if (nr_xfr == 0) @@ -1109,17 +1116,15 @@ int gmx_traj(int argc, char *argv[]) } if (bCV) { - write_pdb_bfac(opt2fn("-cv", NFILE, fnm), - opt2fn("-av", NFILE, fnm), "average velocity", &(top.atoms), - ePBC, topbox, isize[0], index[0], nr_xfr, sumx, - nr_vfr, sumv, bDim, scale, oenv); + write_pdb_bfac(opt2fn("-cv", NFILE, fnm), opt2fn("-av", NFILE, fnm), "average velocity", + &(top.atoms), ePBC, topbox, isize[0], index[0], nr_xfr, sumx, nr_vfr, sumv, + bDim, scale, oenv); } if (bCF) { - write_pdb_bfac(opt2fn("-cf", NFILE, fnm), - opt2fn("-af", NFILE, fnm), "average force", &(top.atoms), - ePBC, topbox, isize[0], index[0], nr_xfr, sumx, - nr_ffr, sumf, bDim, scale, oenv); + write_pdb_bfac(opt2fn("-cf", NFILE, fnm), opt2fn("-af", NFILE, fnm), "average force", + &(top.atoms), ePBC, topbox, isize[0], index[0], nr_xfr, sumx, nr_ffr, sumf, + bDim, scale, oenv); } /* view it */ diff --git a/src/gromacs/gmxana/gmx_trjorder.cpp b/src/gromacs/gmxana/gmx_trjorder.cpp index 698107ca12..75cf93dc39 100644 --- a/src/gromacs/gmxana/gmx_trjorder.cpp +++ b/src/gromacs/gmxana/gmx_trjorder.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,14 +56,15 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { - int i; - real d2; +typedef struct +{ + int i; + real d2; } t_order; -static t_order *order; +static t_order* order; -static int ocomp(const void *a, const void *b) +static int ocomp(const void* a, const void* b) { const t_order *oa, *ob; @@ -80,9 +81,9 @@ static int ocomp(const void *a, const void *b) } } -int gmx_trjorder(int argc, char *argv[]) +int gmx_trjorder(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] orders molecules according to the smallest distance", "to atoms in a reference group", "or on z-coordinate (with option [TT]-z[tt]).", @@ -107,48 +108,50 @@ int gmx_trjorder(int argc, char *argv[]) "With option [TT]-nshell[tt] the number of molecules within a shell", "of radius [TT]-r[tt] around the reference group are printed." }; - static int na = 3, ref_a = 1; - static real rcut = 0; - static gmx_bool bCOM = FALSE, bZ = FALSE; - t_pargs pa[] = { - { "-na", FALSE, etINT, {&na}, - "Number of atoms in a molecule" }, - { "-da", FALSE, etINT, {&ref_a}, - "Atom used for the distance calculation, 0 is COM" }, - { "-com", FALSE, etBOOL, {&bCOM}, + static int na = 3, ref_a = 1; + static real rcut = 0; + static gmx_bool bCOM = FALSE, bZ = FALSE; + t_pargs pa[] = { + { "-na", FALSE, etINT, { &na }, "Number of atoms in a molecule" }, + { "-da", FALSE, etINT, { &ref_a }, "Atom used for the distance calculation, 0 is COM" }, + { "-com", + FALSE, + etBOOL, + { &bCOM }, "Use the distance to the center of mass of the reference group" }, - { "-r", FALSE, etREAL, {&rcut}, - "Cutoff used for the distance calculation when computing the number of molecules in a shell around e.g. a protein" }, - { "-z", FALSE, etBOOL, {&bZ}, - "Order molecules on z-coordinate" } + { "-r", + FALSE, + etREAL, + { &rcut }, + "Cutoff used for the distance calculation when computing the number of molecules in a " + "shell around e.g. a protein" }, + { "-z", FALSE, etBOOL, { &bZ }, "Order molecules on z-coordinate" } }; - FILE *fp; - t_trxstatus *out; - t_trxstatus *status; + FILE* fp; + t_trxstatus* out; + t_trxstatus* status; gmx_bool bNShell, bPDBout; t_topology top; int ePBC; - rvec *x, *xsol, xcom, dx; + rvec * x, *xsol, xcom, dx; matrix box; t_pbc pbc; gmx_rmpbc_t gpbc; real t, totmass, mass, rcut2 = 0, n2; int natoms, nwat, ncut; - char **grpname; - int i, j, d, *isize, isize_ref = 0, isize_sol; + char** grpname; + int i, j, d, *isize, isize_ref = 0, isize_sol; int sa, sr, *swi, **index, *ind_ref = nullptr, *ind_sol; - gmx_output_env_t *oenv; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTRO, "-o", "ordered", ffOPTWR }, - { efXVG, "-nshell", "nshell", ffOPTWR } - }; + gmx_output_env_t* oenv; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTRO, "-o", "ordered", ffOPTWR }, + { efXVG, "-nshell", "nshell", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } @@ -157,13 +160,11 @@ int gmx_trjorder(int argc, char *argv[]) sfree(x); /* get index groups */ - printf("Select %sa group of molecules to be ordered:\n", - bZ ? "" : "a group of reference atoms and "); + printf("Select %sa group of molecules to be ordered:\n", bZ ? "" : "a group of reference atoms and "); snew(grpname, 2); snew(index, 2); snew(isize, 2); - get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bZ ? 1 : 2, - isize, index, grpname); + get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), bZ ? 1 : 2, isize, index, grpname); if (!bZ) { @@ -189,7 +190,10 @@ int gmx_trjorder(int argc, char *argv[]) { if (index[i][j] > natoms) { - gmx_fatal(FARGS, "An atom number in group %s is larger than the number of atoms in the trajectory", grpname[i]); + gmx_fatal(FARGS, + "An atom number in group %s is larger than the number of atoms in the " + "trajectory", + grpname[i]); } } } @@ -200,10 +204,11 @@ int gmx_trjorder(int argc, char *argv[]) isize[1], na); } - nwat = isize_sol/na; + nwat = isize_sol / na; if (ref_a > na) { - gmx_fatal(FARGS, "The reference atom can not be larger than the number of atoms in a molecule"); + gmx_fatal(FARGS, + "The reference atom can not be larger than the number of atoms in a molecule"); } ref_a--; snew(xsol, nwat); @@ -216,16 +221,13 @@ int gmx_trjorder(int argc, char *argv[]) out = nullptr; fp = nullptr; - bNShell = ((opt2bSet("-nshell", NFILE, fnm)) || - (opt2parg_bSet("-r", asize(pa), pa))); + bNShell = ((opt2bSet("-nshell", NFILE, fnm)) || (opt2parg_bSet("-r", asize(pa), pa))); bPDBout = FALSE; if (bNShell) { - rcut2 = rcut*rcut; - fp = xvgropen(opt2fn("-nshell", NFILE, fnm), "Number of molecules", - "Time (ps)", "N", oenv); - printf("Will compute the number of molecules within a radius of %g\n", - rcut); + rcut2 = rcut * rcut; + fp = xvgropen(opt2fn("-nshell", NFILE, fnm), "Number of molecules", "Time (ps)", "N", oenv); + printf("Will compute the number of molecules within a radius of %g\n", rcut); } if (!bNShell || opt2bSet("-o", NFILE, fnm)) { @@ -252,15 +254,15 @@ int gmx_trjorder(int argc, char *argv[]) clear_rvec(xsol[i]); for (j = 0; j < na; j++) { - sa = ind_sol[i*na+j]; - mass = top.atoms.atom[sa].m; + sa = ind_sol[i * na + j]; + mass = top.atoms.atom[sa].m; totmass += mass; for (d = 0; d < DIM; d++) { - xsol[i][d] += mass*x[sa][d]; + xsol[i][d] += mass * x[sa][d]; } } - svmul(1.0/totmass, xsol[i], xsol[i]); + svmul(1.0 / totmass, xsol[i], xsol[i]); } } else @@ -268,7 +270,7 @@ int gmx_trjorder(int argc, char *argv[]) /* Copy the reference atom of all solvent molecules */ for (i = 0; i < nwat; i++) { - copy_rvec(x[ind_sol[i*na+ref_a]], xsol[i]); + copy_rvec(x[ind_sol[i * na + ref_a]], xsol[i]); } } @@ -276,9 +278,9 @@ int gmx_trjorder(int argc, char *argv[]) { for (i = 0; (i < nwat); i++) { - sa = ind_sol[na*i]; - order[i].i = sa; - order[i].d2 = xsol[i][ZZ]; + sa = ind_sol[na * i]; + order[i].i = sa; + order[i].d2 = xsol[i][ZZ]; } } else if (bCOM) @@ -287,20 +289,20 @@ int gmx_trjorder(int argc, char *argv[]) clear_rvec(xcom); for (i = 0; i < isize_ref; i++) { - mass = top.atoms.atom[ind_ref[i]].m; + mass = top.atoms.atom[ind_ref[i]].m; totmass += mass; for (j = 0; j < DIM; j++) { - xcom[j] += mass*x[ind_ref[i]][j]; + xcom[j] += mass * x[ind_ref[i]][j]; } } - svmul(1/totmass, xcom, xcom); + svmul(1 / totmass, xcom, xcom); for (i = 0; (i < nwat); i++) { - sa = ind_sol[na*i]; + sa = ind_sol[na * i]; pbc_dx(&pbc, xcom, xsol[i], dx); - order[i].i = sa; - order[i].d2 = norm2(dx); + order[i].i = sa; + order[i].d2 = norm2(dx); } } else @@ -308,10 +310,10 @@ int gmx_trjorder(int argc, char *argv[]) /* Set distance to first atom */ for (i = 0; (i < nwat); i++) { - sa = ind_sol[na*i]; + sa = ind_sol[na * i]; pbc_dx(&pbc, x[ind_ref[0]], xsol[i], dx); - order[i].i = sa; - order[i].d2 = norm2(dx); + order[i].i = sa; + order[i].d2 = norm2(dx); } for (j = 1; (j < isize_ref); j++) { @@ -322,7 +324,7 @@ int gmx_trjorder(int argc, char *argv[]) n2 = norm2(dx); if (n2 < order[i].d2) { - order[i].d2 = n2; + order[i].d2 = n2; } } } @@ -347,7 +349,7 @@ int gmx_trjorder(int argc, char *argv[]) { for (j = 0; (j < na); j++) { - swi[ind_sol[na*i]+j] = order[i].i+j; + swi[ind_sol[na * i] + j] = order[i].i + j; } } @@ -358,14 +360,13 @@ int gmx_trjorder(int argc, char *argv[]) { for (j = 0; (j < na); j++) { - top.atoms.pdbinfo[order[i].i+j].bfac = std::sqrt(order[i].d2); + top.atoms.pdbinfo[order[i].i + j].bfac = std::sqrt(order[i].d2); } } } write_trx(out, natoms, swi, &top.atoms, 0, t, box, x, nullptr, nullptr); } - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); close_trx(status); if (out) { diff --git a/src/gromacs/gmxana/gmx_vanhove.cpp b/src/gromacs/gmxana/gmx_vanhove.cpp index e72a5f53a0..7dae7ea80b 100644 --- a/src/gromacs/gmxana/gmx_vanhove.cpp +++ b/src/gromacs/gmxana/gmx_vanhove.cpp @@ -62,9 +62,9 @@ #include "gromacs/utility/smalloc.h" -int gmx_vanhove(int argc, char *argv[]) +int gmx_vanhove(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] computes the Van Hove correlation function.", "The Van Hove G(r,t) is the probability that a particle that is at r[SUB]0[sub]", "at time zero can be found at position r[SUB]0[sub]+r at time t.", @@ -96,62 +96,61 @@ int gmx_vanhove(int argc, char *argv[]) "time can be reduced." }; static int fmmax = 0, ftmax = 0, nlev = 81, nr = 1, fshift = 0; - static real sbin = 0, rmax = 2, rbin = 0.01, mmax = 0, rint = 0; - t_pargs pa[] = { - { "-sqrt", FALSE, etREAL, {&sbin}, + static real sbin = 0, rmax = 2, rbin = 0.01, mmax = 0, rint = 0; + t_pargs pa[] = { + { "-sqrt", + FALSE, + etREAL, + { &sbin }, "Use [SQRT]t[sqrt] on the matrix axis which binspacing # in [SQRT]ps[sqrt]" }, - { "-fm", FALSE, etINT, {&fmmax}, - "Number of frames in the matrix, 0 is plot all" }, - { "-rmax", FALSE, etREAL, {&rmax}, - "Maximum r in the matrix (nm)" }, - { "-rbin", FALSE, etREAL, {&rbin}, - "Binwidth in the matrix and for [TT]-or[tt] (nm)" }, - { "-mmax", FALSE, etREAL, {&mmax}, + { "-fm", FALSE, etINT, { &fmmax }, "Number of frames in the matrix, 0 is plot all" }, + { "-rmax", FALSE, etREAL, { &rmax }, "Maximum r in the matrix (nm)" }, + { "-rbin", FALSE, etREAL, { &rbin }, "Binwidth in the matrix and for [TT]-or[tt] (nm)" }, + { "-mmax", + FALSE, + etREAL, + { &mmax }, "Maximum density in the matrix, 0 is calculate (1/nm)" }, - { "-nlevels", FALSE, etINT, {&nlev}, - "Number of levels in the matrix" }, - { "-nr", FALSE, etINT, {&nr}, - "Number of curves for the [TT]-or[tt] output" }, - { "-fr", FALSE, etINT, {&fshift}, - "Frame spacing for the [TT]-or[tt] output" }, - { "-rt", FALSE, etREAL, {&rint}, - "Integration limit for the [TT]-ot[tt] output (nm)" }, - { "-ft", FALSE, etINT, {&ftmax}, + { "-nlevels", FALSE, etINT, { &nlev }, "Number of levels in the matrix" }, + { "-nr", FALSE, etINT, { &nr }, "Number of curves for the [TT]-or[tt] output" }, + { "-fr", FALSE, etINT, { &fshift }, "Frame spacing for the [TT]-or[tt] output" }, + { "-rt", FALSE, etREAL, { &rint }, "Integration limit for the [TT]-ot[tt] output (nm)" }, + { "-ft", + FALSE, + etINT, + { &ftmax }, "Number of frames in the [TT]-ot[tt] output, 0 is plot all" } }; #define NPA asize(pa) t_filenm fnm[] = { - { efTRX, nullptr, nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXPM, "-om", "vanhove", ffOPTWR }, - { efXVG, "-or", "vanhove_r", ffOPTWR }, - { efXVG, "-ot", "vanhove_t", ffOPTWR } + { efTRX, nullptr, nullptr, ffREAD }, { efTPS, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, { efXPM, "-om", "vanhove", ffOPTWR }, + { efXVG, "-or", "vanhove_r", ffOPTWR }, { efXVG, "-ot", "vanhove_t", ffOPTWR } }; #define NFILE asize(fnm) - gmx_output_env_t *oenv; - const char *matfile, *otfile, *orfile; + gmx_output_env_t* oenv; + const char * matfile, *otfile, *orfile; t_topology top; int ePBC; matrix boxtop, box, *sbox, avbox, corr; - rvec *xtop, *x, **sx; + rvec * xtop, *x, **sx; int isize, nalloc, nallocn; - t_trxstatus *status; - int *index; - char *grpname; + t_trxstatus* status; + int* index; + char* grpname; int nfr, f, ff, i, m, mat_nx = 0, nbin = 0, bin, mbin, fbin; - real *time, t, invbin = 0, rmax2 = 0, rint2 = 0, d2; + real * time, t, invbin = 0, rmax2 = 0, rint2 = 0, d2; real invsbin = 0, matmax, normfac, dt, *tickx, *ticky; char buf[STRLEN], **legend; - real **mat = nullptr; - int *pt = nullptr, **pr = nullptr, *mcount = nullptr, *tcount = nullptr, *rcount = nullptr; - FILE *fp; - t_rgb rlo = {1, 1, 1}, rhi = {0, 0, 0}; + real** mat = nullptr; + int * pt = nullptr, **pr = nullptr, *mcount = nullptr, *tcount = nullptr, *rcount = nullptr; + FILE* fp; + t_rgb rlo = { 1, 1, 1 }, rhi = { 0, 0, 0 }; - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, asize(pa), pa, + asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -159,30 +158,28 @@ int gmx_vanhove(int argc, char *argv[]) matfile = opt2fn_null("-om", NFILE, fnm); if (opt2parg_bSet("-fr", NPA, pa)) { - orfile = opt2fn("-or", NFILE, fnm); + orfile = opt2fn("-or", NFILE, fnm); } else { - orfile = opt2fn_null("-or", NFILE, fnm); + orfile = opt2fn_null("-or", NFILE, fnm); } if (opt2parg_bSet("-rt", NPA, pa)) { - otfile = opt2fn("-ot", NFILE, fnm); + otfile = opt2fn("-ot", NFILE, fnm); } else { - otfile = opt2fn_null("-ot", NFILE, fnm); + otfile = opt2fn_null("-ot", NFILE, fnm); } if (!matfile && !otfile && !orfile) { - fprintf(stderr, - "For output set one (or more) of the output file options\n"); + fprintf(stderr, "For output set one (or more) of the output file options\n"); exit(0); } - read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, boxtop, - FALSE); + read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, &xtop, nullptr, boxtop, FALSE); get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &isize, &index, &grpname); nalloc = 0; @@ -192,7 +189,7 @@ int gmx_vanhove(int argc, char *argv[]) clear_mat(avbox); read_first_x(oenv, &status, ftp2fn(efTRX, NFILE, fnm), &t, &x, box); - nfr = 0; + nfr = 0; do { if (nfr >= nalloc) @@ -218,8 +215,7 @@ int gmx_vanhove(int argc, char *argv[]) } nfr++; - } - while (read_next_x(oenv, status, &t, x, box)); + } while (read_next_x(oenv, status, &t, x, box)); /* clean up */ sfree(x); @@ -227,11 +223,11 @@ int gmx_vanhove(int argc, char *argv[]) fprintf(stderr, "Read %d frames\n", nfr); - dt = (time[nfr-1] - time[0])/(nfr - 1); + dt = (time[nfr - 1] - time[0]) / (nfr - 1); /* Some ugly rounding to get nice nice times in the output */ - dt = std::round(10000.0*dt)/10000.0; + dt = std::round(10000.0 * dt) / 10000.0; - invbin = 1.0/rbin; + invbin = 1.0 / rbin; if (matfile) { @@ -240,24 +236,24 @@ int gmx_vanhove(int argc, char *argv[]) fmmax = nfr - 1; } snew(mcount, fmmax); - nbin = gmx::roundToInt(rmax*invbin); + nbin = gmx::roundToInt(rmax * invbin); if (sbin == 0) { mat_nx = fmmax + 1; } else { - invsbin = 1.0/sbin; - mat_nx = static_cast(std::sqrt(fmmax*dt)*invsbin + 1); + invsbin = 1.0 / sbin; + mat_nx = static_cast(std::sqrt(fmmax * dt) * invsbin + 1); } snew(mat, mat_nx); for (f = 0; f < mat_nx; f++) { snew(mat[f], nbin); } - rmax2 = gmx::square(nbin*rbin); + rmax2 = gmx::square(nbin * rbin); /* Initialize time zero */ - mat[0][0] = nfr*isize; + mat[0][0] = nfr * isize; mcount[0] += nfr; } else @@ -280,9 +276,9 @@ int gmx_vanhove(int argc, char *argv[]) } snew(tcount, ftmax); snew(pt, nfr); - rint2 = rint*rint; + rint2 = rint * rint; /* Initialize time zero */ - pt[0] = nfr*isize; + pt[0] = nfr * isize; tcount[0] += nfr; } else @@ -290,7 +286,7 @@ int gmx_vanhove(int argc, char *argv[]) ftmax = 0; } - msmul(avbox, 1.0/nfr, avbox); + msmul(avbox, 1.0 / nfr, avbox); for (f = 0; f < nfr; f++) { if (f % 100 == 0) @@ -309,13 +305,13 @@ int gmx_vanhove(int argc, char *argv[]) if (f > 0) { /* Correct for periodic jumps */ - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { - while (sx[f][i][m] - sx[f-1][i][m] > 0.5*avbox[m][m]) + while (sx[f][i][m] - sx[f - 1][i][m] > 0.5 * avbox[m][m]) { rvec_dec(sx[f][i], avbox[m]); } - while (sx[f][i][m] - sx[f-1][i][m] <= -0.5*avbox[m][m]) + while (sx[f][i][m] - sx[f - 1][i][m] <= -0.5 * avbox[m][m]) { rvec_inc(sx[f][i], avbox[m]); } @@ -334,14 +330,14 @@ int gmx_vanhove(int argc, char *argv[]) } else { - mbin = gmx::roundToInt(std::sqrt(fbin*dt)*invsbin); + mbin = gmx::roundToInt(std::sqrt(fbin * dt) * invsbin); } for (i = 0; i < isize; i++) { d2 = distance2(sx[f][i], sx[ff][i]); if (mbin < mat_nx && d2 < rmax2) { - bin = gmx::roundToInt(std::sqrt(d2)*invbin); + bin = gmx::roundToInt(std::sqrt(d2) * invbin); if (bin < nbin) { mat[mbin][bin] += 1; @@ -366,16 +362,16 @@ int gmx_vanhove(int argc, char *argv[]) { for (fbin = 0; fbin < nr; fbin++) { - ff = f - (fbin + 1)*fshift; + ff = f - (fbin + 1) * fshift; if (ff >= 0) { for (i = 0; i < isize; i++) { d2 = distance2(sx[f][i], sx[ff][i]); - bin = gmx::roundToInt(std::sqrt(d2)*invbin); + bin = gmx::roundToInt(std::sqrt(d2) * invbin); if (bin >= nalloc) { - nallocn = 10*(bin/10) + 11; + nallocn = 10 * (bin / 10) + 11; for (m = 0; m < nr; m++) { srenew(pr[m], nallocn); @@ -400,7 +396,7 @@ int gmx_vanhove(int argc, char *argv[]) matmax = 0; for (f = 0; f < mat_nx; f++) { - normfac = 1.0/(mcount[f]*isize*rbin); + normfac = 1.0 / (mcount[f] * isize * rbin); for (i = 0; i < nbin; i++) { mat[f][i] *= normfac; @@ -410,8 +406,7 @@ int gmx_vanhove(int argc, char *argv[]) } } } - fprintf(stdout, "Value at (0,0): %.3f, maximum of the rest %.3f\n", - mat[0][0], matmax); + fprintf(stdout, "Value at (0,0): %.3f, maximum of the rest %.3f\n", mat[0][0], matmax); if (mmax > 0) { matmax = mmax; @@ -421,22 +416,22 @@ int gmx_vanhove(int argc, char *argv[]) { if (sbin == 0) { - tickx[f] = f*dt; + tickx[f] = f * dt; } else { - tickx[f] = f*sbin; + tickx[f] = f * sbin; } } - snew(ticky, nbin+1); + snew(ticky, nbin + 1); for (i = 0; i <= nbin; i++) { - ticky[i] = i*rbin; + ticky[i] = i * rbin; } fp = gmx_ffopen(matfile, "w"); write_xpm(fp, MAT_SPATIAL_Y, "Van Hove function", "G (1/nm)", - sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)", "r (nm)", - mat_nx, nbin, tickx, ticky, mat, 0, matmax, rlo, rhi, &nlev); + sbin == 0 ? "time (ps)" : "sqrt(time) (ps^1/2)", "r (nm)", mat_nx, nbin, tickx, + ticky, mat, 0, matmax, rlo, rhi, &nlev); gmx_ffclose(fp); } @@ -450,16 +445,18 @@ int gmx_vanhove(int argc, char *argv[]) snew(legend, nr); for (fbin = 0; fbin < nr; fbin++) { - sprintf(buf, "%g ps", (fbin + 1)*fshift*dt); + sprintf(buf, "%g ps", (fbin + 1) * fshift * dt); legend[fbin] = gmx_strdup(buf); } xvgr_legend(fp, nr, legend, oenv); for (i = 0; i < nalloc; i++) { - fprintf(fp, "%g", i*rbin); + fprintf(fp, "%g", i * rbin); for (fbin = 0; fbin < nr; fbin++) { - fprintf(fp, " %g", static_cast(pr[fbin][i]/(rcount[fbin]*isize*rbin*(i == 0 ? 0.5 : 1.0)))); + fprintf(fp, " %g", + static_cast(pr[fbin][i] + / (rcount[fbin] * isize * rbin * (i == 0 ? 0.5 : 1.0)))); } fprintf(fp, "\n"); } @@ -476,7 +473,7 @@ int gmx_vanhove(int argc, char *argv[]) } for (f = 0; f <= ftmax; f++) { - fprintf(fp, "%g %g\n", f*dt, static_cast(pt[f])/(tcount[f]*isize)); + fprintf(fp, "%g %g\n", f * dt, static_cast(pt[f]) / (tcount[f] * isize)); } xvgrclose(fp); } diff --git a/src/gromacs/gmxana/gmx_velacc.cpp b/src/gromacs/gmxana/gmx_velacc.cpp index c4e33254e5..d75f95b501 100644 --- a/src/gromacs/gmxana/gmx_velacc.cpp +++ b/src/gromacs/gmxana/gmx_velacc.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void index_atom2mol(int *n, int *index, const t_block *mols) +static void index_atom2mol(int* n, int* index, const t_block* mols) { int nat, i, nmol, mol, j; @@ -76,10 +76,10 @@ static void index_atom2mol(int *n, int *index, const t_block *mols) mol++; if (mol >= mols->nr) { - gmx_fatal(FARGS, "Atom index out of range: %d", index[i]+1); + gmx_fatal(FARGS, "Atom index out of range: %d", index[i] + 1); } } - for (j = mols->index[mol]; j < mols->index[mol+1]; j++) + for (j = mols->index[mol]; j < mols->index[mol + 1]; j++) { if (i >= nat || index[i] != j) { @@ -95,7 +95,7 @@ static void index_atom2mol(int *n, int *index, const t_block *mols) *n = nmol; } -static void precalc(const t_topology &top, real normm[]) +static void precalc(const t_topology& top, real normm[]) { real mtot; @@ -104,7 +104,7 @@ static void precalc(const t_topology &top, real normm[]) for (i = 0; i < top.mols.nr; i++) { k = top.mols.index[i]; - l = top.mols.index[i+1]; + l = top.mols.index[i + 1]; mtot = 0.0; for (j = k; j < l; j++) @@ -114,23 +114,20 @@ static void precalc(const t_topology &top, real normm[]) for (j = k; j < l; j++) { - normm[j] = top.atoms.atom[j].m/mtot; + normm[j] = top.atoms.atom[j].m / mtot; } - } - } -static void calc_spectrum(int n, const real c[], real dt, const char *fn, - gmx_output_env_t *oenv, gmx_bool bRecip) +static void calc_spectrum(int n, const real c[], real dt, const char* fn, gmx_output_env_t* oenv, gmx_bool bRecip) { - FILE *fp; + FILE* fp; gmx_fft_t fft; int i, status; - real *data; + real* data; real nu, omega, recip_fac; - snew(data, n*2); + snew(data, n * 2); for (i = 0; (i < n); i++) { data[i] = c[i]; @@ -145,9 +142,7 @@ static void calc_spectrum(int n, const real c[], real dt, const char *fn, gmx_fatal(FARGS, "Invalid fft return status %d", status); } fp = xvgropen(fn, "Vibrational Power Spectrum", - bRecip ? "\\f{12}w\\f{4} (cm\\S-1\\N)" : - "\\f{12}n\\f{4} (ps\\S-1\\N)", - "a.u.", oenv); + bRecip ? "\\f{12}w\\f{4} (cm\\S-1\\N)" : "\\f{12}n\\f{4} (ps\\S-1\\N)", "a.u.", oenv); /* This is difficult. * The length of the ACF is dt (as passed to this routine). * We pass the vacf with N time steps from 0 to dt. @@ -161,86 +156,79 @@ static void calc_spectrum(int n, const real c[], real dt, const char *fn, * The timestep between saving the trajectory is * 1e7 is to convert nanometer to cm */ - recip_fac = bRecip ? (1e7/SPEED_OF_LIGHT) : 1.0; + recip_fac = bRecip ? (1e7 / SPEED_OF_LIGHT) : 1.0; for (i = 0; (i < n); i += 2) { - nu = i/(2*dt); - omega = nu*recip_fac; + nu = i / (2 * dt); + omega = nu * recip_fac; /* Computing the square magnitude of a complex number, since this is a power * spectrum. */ - fprintf(fp, "%10g %10g\n", omega, gmx::square(data[i])+gmx::square(data[i+1])); + fprintf(fp, "%10g %10g\n", omega, gmx::square(data[i]) + gmx::square(data[i + 1])); } xvgrclose(fp); gmx_fft_destroy(fft); sfree(data); } -int gmx_velacc(int argc, char *argv[]) +int gmx_velacc(int argc, char* argv[]) { - const char *desc[] = { - "[THISMODULE] computes the velocity autocorrelation function.", - "When the [TT]-m[tt] option is used, the momentum autocorrelation", - "function is calculated.[PAR]", - "With option [TT]-mol[tt] the velocity autocorrelation function of", - "molecules is calculated. In this case the index group should consist", - "of molecule numbers instead of atom numbers.[PAR]", - "By using option [TT]-os[tt] you can also extract the estimated", - "(vibrational) power spectrum, which is the Fourier transform of the", - "velocity autocorrelation function.", - "Be sure that your trajectory contains frames with velocity information", - "(i.e. [TT]nstvout[tt] was set in your original [REF].mdp[ref] file),", - "and that the time interval between data collection points is", - "much shorter than the time scale of the autocorrelation." - }; + const char* desc[] = { "[THISMODULE] computes the velocity autocorrelation function.", + "When the [TT]-m[tt] option is used, the momentum autocorrelation", + "function is calculated.[PAR]", + "With option [TT]-mol[tt] the velocity autocorrelation function of", + "molecules is calculated. In this case the index group should consist", + "of molecule numbers instead of atom numbers.[PAR]", + "By using option [TT]-os[tt] you can also extract the estimated", + "(vibrational) power spectrum, which is the Fourier transform of the", + "velocity autocorrelation function.", + "Be sure that your trajectory contains frames with velocity information", + "(i.e. [TT]nstvout[tt] was set in your original [REF].mdp[ref] file),", + "and that the time interval between data collection points is", + "much shorter than the time scale of the autocorrelation." }; static gmx_bool bMass = FALSE, bMol = FALSE, bRecip = TRUE; - t_pargs pa[] = { - { "-m", FALSE, etBOOL, {&bMass}, - "Calculate the momentum autocorrelation function" }, - { "-recip", FALSE, etBOOL, {&bRecip}, - "Use cm^-1 on X-axis instead of 1/ps for spectra." }, - { "-mol", FALSE, etBOOL, {&bMol}, - "Calculate the velocity acf of molecules" } + t_pargs pa[] = { + { "-m", FALSE, etBOOL, { &bMass }, "Calculate the momentum autocorrelation function" }, + { "-recip", FALSE, etBOOL, { &bRecip }, "Use cm^-1 on X-axis instead of 1/ps for spectra." }, + { "-mol", FALSE, etBOOL, { &bMol }, "Calculate the velocity acf of molecules" } }; - t_topology top; - int ePBC = -1; - t_trxframe fr; - matrix box; - gmx_bool bTPS = FALSE, bTop = FALSE; - int gnx; - int *index; - char *grpname; + t_topology top; + int ePBC = -1; + t_trxframe fr; + matrix box; + gmx_bool bTPS = FALSE, bTop = FALSE; + int gnx; + int* index; + char* grpname; /* t0, t1 are the beginning and end time respectively. * dt is the time step, mass is temp variable for atomic mass. */ - real t0, t1, dt, mass; - t_trxstatus *status; - int counter, n_alloc, i, j, counter_dim, k, l; - rvec mv_mol; + real t0, t1, dt, mass; + t_trxstatus* status; + int counter, n_alloc, i, j, counter_dim, k, l; + rvec mv_mol; /* Array for the correlation function */ - real **c1; - real *normm = nullptr; - gmx_output_env_t *oenv; + real** c1; + real* normm = nullptr; + gmx_output_env_t* oenv; #define NHISTO 360 - t_filenm fnm[] = { - { efTRN, "-f", nullptr, ffREAD }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efXVG, "-o", "vac", ffWRITE }, - { efXVG, "-os", "spectrum", ffOPTWR } - }; + t_filenm fnm[] = { { efTRN, "-f", nullptr, ffREAD }, + { efTPS, nullptr, nullptr, ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efXVG, "-o", "vac", ffWRITE }, + { efXVG, "-os", "spectrum", ffOPTWR } }; #define NFILE asize(fnm) - int npargs; - t_pargs *ppa; + int npargs; + t_pargs* ppa; npargs = asize(pa); ppa = add_acf_pargs(&npargs, pa); - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, - NFILE, fnm, npargs, ppa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME, NFILE, fnm, npargs, ppa, + asize(desc), desc, 0, nullptr, &oenv)) { sfree(ppa); return 0; @@ -253,8 +241,7 @@ int gmx_velacc(int argc, char *argv[]) if (bTPS) { - bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, nullptr, nullptr, box, - TRUE); + bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC, nullptr, nullptr, box, TRUE); get_index(&top.atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname); } else @@ -292,17 +279,17 @@ int gmx_velacc(int argc, char *argv[]) n_alloc += 100; for (i = 0; i < gnx; i++) { - srenew(c1[i], DIM*n_alloc); + srenew(c1[i], DIM * n_alloc); } } - counter_dim = DIM*counter; + counter_dim = DIM * counter; if (bMol) { for (i = 0; i < gnx; i++) { clear_rvec(mv_mol); k = top.mols.index[index[i]]; - l = top.mols.index[index[i]+1]; + l = top.mols.index[index[i] + 1]; for (j = k; j < l; j++) { if (bMass) @@ -313,13 +300,13 @@ int gmx_velacc(int argc, char *argv[]) { mass = normm[j]; } - mv_mol[XX] += mass*fr.v[j][XX]; - mv_mol[YY] += mass*fr.v[j][YY]; - mv_mol[ZZ] += mass*fr.v[j][ZZ]; + mv_mol[XX] += mass * fr.v[j][XX]; + mv_mol[YY] += mass * fr.v[j][YY]; + mv_mol[ZZ] += mass * fr.v[j][ZZ]; } - c1[i][counter_dim+XX] = mv_mol[XX]; - c1[i][counter_dim+YY] = mv_mol[YY]; - c1[i][counter_dim+ZZ] = mv_mol[ZZ]; + c1[i][counter_dim + XX] = mv_mol[XX]; + c1[i][counter_dim + YY] = mv_mol[YY]; + c1[i][counter_dim + ZZ] = mv_mol[ZZ]; } } else @@ -334,36 +321,32 @@ int gmx_velacc(int argc, char *argv[]) { mass = 1; } - c1[i][counter_dim+XX] = mass*fr.v[index[i]][XX]; - c1[i][counter_dim+YY] = mass*fr.v[index[i]][YY]; - c1[i][counter_dim+ZZ] = mass*fr.v[index[i]][ZZ]; + c1[i][counter_dim + XX] = mass * fr.v[index[i]][XX]; + c1[i][counter_dim + YY] = mass * fr.v[index[i]][YY]; + c1[i][counter_dim + ZZ] = mass * fr.v[index[i]][ZZ]; } } t1 = fr.time; counter++; - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); close_trx(status); if (counter >= 4) { /* Compute time step between frames */ - dt = (t1-t0)/(counter-1); + dt = (t1 - t0) / (counter - 1); do_autocorr(opt2fn("-o", NFILE, fnm), oenv, - bMass ? - "Momentum Autocorrelation Function" : - "Velocity Autocorrelation Function", + bMass ? "Momentum Autocorrelation Function" : "Velocity Autocorrelation Function", counter, gnx, c1, dt, eacVector, TRUE); do_view(oenv, opt2fn("-o", NFILE, fnm), "-nxy"); if (opt2bSet("-os", NFILE, fnm)) { - calc_spectrum(counter/2, (c1[0]), (t1-t0)/2, opt2fn("-os", NFILE, fnm), - oenv, bRecip); + calc_spectrum(counter / 2, (c1[0]), (t1 - t0) / 2, opt2fn("-os", NFILE, fnm), oenv, bRecip); do_view(oenv, opt2fn("-os", NFILE, fnm), "-nxy"); } } diff --git a/src/gromacs/gmxana/gmx_wham.cpp b/src/gromacs/gmxana/gmx_wham.cpp index 69e0fc7943..c865262e1d 100644 --- a/src/gromacs/gmxana/gmx_wham.cpp +++ b/src/gromacs/gmxana/gmx_wham.cpp @@ -86,14 +86,23 @@ /*! \brief * enum for energy units */ -enum { - enSel, en_kJ, en_kCal, en_kT, enNr +enum +{ + enSel, + en_kJ, + en_kCal, + en_kT, + enNr }; /*! \brief * enum for type of input files (pdos, tpr, or pullf) */ -enum { - whamin_unknown, whamin_tpr, whamin_pullxf, whamin_pdo +enum +{ + whamin_unknown, + whamin_tpr, + whamin_pullxf, + whamin_pdo }; /*! \brief enum for bootstrapping method @@ -116,22 +125,26 @@ enum { * J Chem Theory Comput, 6(12), 3713-3720 (2010) * ******************************************************************** */ -enum { - bsMethod_unknown, bsMethod_BayesianHist, bsMethod_hist, - bsMethod_traj, bsMethod_trajGauss +enum +{ + bsMethod_unknown, + bsMethod_BayesianHist, + bsMethod_hist, + bsMethod_traj, + bsMethod_trajGauss }; //! Parameters of one pull coodinate typedef struct { - int pull_type; //!< such as constraint, umbrella, ... - int geometry; //!< such as distance, direction, cylinder - int ngroup; //!< the number of pull groups involved - ivec dim; //!< pull dimension with geometry distance - int ndim; //!< nr of pull_dim != 0 - real k; //!< force constants in tpr file - real init_dist; //!< reference displacement - char coord_unit[256]; //!< unit of the displacement + int pull_type; //!< such as constraint, umbrella, ... + int geometry; //!< such as distance, direction, cylinder + int ngroup; //!< the number of pull groups involved + ivec dim; //!< pull dimension with geometry distance + int ndim; //!< nr of pull_dim != 0 + real k; //!< force constants in tpr file + real init_dist; //!< reference displacement + char coord_unit[256]; //!< unit of the displacement } t_pullcoord; //! Parameters of the umbrella potentials @@ -142,7 +155,7 @@ typedef struct */ /*!\{*/ int npullcrds; //!< nr of umbrella pull coordinates for reading - t_pullcoord *pcrd; //!< the pull coordinates + t_pullcoord* pcrd; //!< the pull coordinates gmx_bool bPrintCOM; //!< COMs of pull groups writtn in pullx.xvg gmx_bool bPrintRefValue; //!< Reference value for the coordinate written in pullx.xvg gmx_bool bPrintComp; //!< Components of pull distance written to pullx.xvg ? @@ -166,47 +179,47 @@ typedef struct //! Data in the umbrella histograms typedef struct { - int nPull; //!< nr of pull groups in this pdo or pullf/x file - double **Histo; //!< nPull histograms - double **cum; //!< nPull cumulative distribution functions - int nBin; //!< nr of bins. identical to opt->bins - double *k; //!< force constants for the nPull coords - double *pos; //!< umbrella positions for the nPull coords - double *z; //!< z=(-Fi/kT) for the nPull coords. These values are iteratively computed during wham - int *N; //!< nr of data points in nPull histograms. - int *Ntot; //!< also nr of data points. N and Ntot only differ if bHistEq==TRUE + int nPull; //!< nr of pull groups in this pdo or pullf/x file + double** Histo; //!< nPull histograms + double** cum; //!< nPull cumulative distribution functions + int nBin; //!< nr of bins. identical to opt->bins + double* k; //!< force constants for the nPull coords + double* pos; //!< umbrella positions for the nPull coords + double* z; //!< z=(-Fi/kT) for the nPull coords. These values are iteratively computed during wham + int* N; //!< nr of data points in nPull histograms. + int* Ntot; //!< also nr of data points. N and Ntot only differ if bHistEq==TRUE /*! \brief g = 1 + 2*tau[int]/dt where tau is the integrated autocorrelation time. * * Compare, e.g. Ferrenberg/Swendsen, PRL 63:1195 (1989), * Kumar et al, J Comp Chem 13, 1011-1021 (1992), eq. 28 */ - double *g; - double *tau; //!< intetrated autocorrelation time (IACT) - double *tausmooth; //!< smoothed IACT + double* g; + double* tau; //!< intetrated autocorrelation time (IACT) + double* tausmooth; //!< smoothed IACT - double dt; //!< timestep in the input data. Can be adapted with gmx wham option -dt + double dt; //!< timestep in the input data. Can be adapted with gmx wham option -dt /*! \brief TRUE, if any data point of the histogram is within min and max, otherwise FALSE */ - gmx_bool **bContrib; - real **ztime; //!< input data z(t) as a function of time. Required to compute ACTs + gmx_bool** bContrib; + real** ztime; //!< input data z(t) as a function of time. Required to compute ACTs /*! \brief average force estimated from average displacement, fAv=dzAv*k * * Used for integration to guess the potential. */ - real *forceAv; - real *aver; //!< average of histograms - real *sigma; //!< stddev of histograms - double *bsWeight; //!< for bootstrapping complete histograms with continuous weights + real* forceAv; + real* aver; //!< average of histograms + real* sigma; //!< stddev of histograms + double* bsWeight; //!< for bootstrapping complete histograms with continuous weights } t_UmbrellaWindow; //! Selection of pull coordinates to be used in WHAM (one structure for each tpr file) typedef struct { - int n; //!< total nr of pull coords in this tpr file - int nUse; //!< nr of pull coords used - gmx_bool *bUse; //!< boolean array of size n. =1 if used, =0 if not + int n; //!< total nr of pull coords in this tpr file + int nUse; //!< nr of pull coords used + gmx_bool* bUse; //!< boolean array of size n. =1 if used, =0 if not } t_coordselection; //! Parameters of WHAM @@ -216,21 +229,21 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) * \name Input stuff */ /*!\{*/ - const char *fnTpr, *fnPullf, *fnCoordSel; - const char *fnPdo, *fnPullx; //!< file names of input - gmx_bool bTpr, bPullf, bPdo, bPullx; //!< input file types given? - real tmin, tmax, dt; //!< only read input within tmin and tmax with dt - - gmx_bool bInitPotByIntegration; //!< before WHAM, guess potential by force integration. Yields 1.5 to 2 times faster convergence - int stepUpdateContrib; //!< update contribution table every ... iterations. Accelerates WHAM. - int nCoordsel; //!< if >0: use only certain group in WHAM, if ==0: use all groups - t_coordselection *coordsel; //!< for each tpr file: which pull coordinates to use in WHAM? + const char *fnTpr, *fnPullf, *fnCoordSel; + const char *fnPdo, *fnPullx; //!< file names of input + gmx_bool bTpr, bPullf, bPdo, bPullx; //!< input file types given? + real tmin, tmax, dt; //!< only read input within tmin and tmax with dt + + gmx_bool bInitPotByIntegration; //!< before WHAM, guess potential by force integration. Yields 1.5 to 2 times faster convergence + int stepUpdateContrib; //!< update contribution table every ... iterations. Accelerates WHAM. + int nCoordsel; //!< if >0: use only certain group in WHAM, if ==0: use all groups + t_coordselection* coordsel; //!< for each tpr file: which pull coordinates to use in WHAM? /*!\}*/ /*! * \name Basic WHAM options */ /*!\{*/ - int bins; //!< nr of bins, min, max, and dz of profile + int bins; //!< nr of bins, min, max, and dz of profile real min, max, dz; real Temperature, Tolerance; //!< temperature, converged when probability changes less than Tolerance gmx_bool bCycl; //!< generate cyclic (periodic) PMF @@ -239,21 +252,21 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) * \name Output control */ /*!\{*/ - gmx_bool bLog; //!< energy output (instead of probability) for profile - int unit; //!< unit for PMF output kJ/mol or kT or kCal/mol - gmx_bool bSym; //!< symmetrize PMF around z=0 after WHAM, useful for membranes etc. + gmx_bool bLog; //!< energy output (instead of probability) for profile + int unit; //!< unit for PMF output kJ/mol or kT or kCal/mol + gmx_bool bSym; //!< symmetrize PMF around z=0 after WHAM, useful for membranes etc. /*! \brief after wham, set prof to zero at this z-position. * When bootstrapping, set zProf0 to a "stable" reference position. */ - real zProf0; - gmx_bool bProf0Set; //!< setting profile to 0 at zProf0? + real zProf0; + gmx_bool bProf0Set; //!< setting profile to 0 at zProf0? - gmx_bool bBoundsOnly, bHistOnly; //!< determine min and max, or write histograms and exit - gmx_bool bAuto; //!< determine min and max automatically but do not exit + gmx_bool bBoundsOnly, bHistOnly; //!< determine min and max, or write histograms and exit + gmx_bool bAuto; //!< determine min and max automatically but do not exit - gmx_bool verbose; //!< more noisy wham mode - int stepchange; //!< print maximum change in prof after how many interations - gmx_output_env_t *oenv; //!< xvgr options + gmx_bool verbose; //!< more noisy wham mode + int stepchange; //!< print maximum change in prof after how many interations + gmx_output_env_t* oenv; //!< xvgr options /*!\}*/ /*! * \name Autocorrelation stuff @@ -261,8 +274,8 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) /*!\{*/ gmx_bool bTauIntGiven, bCalcTauInt; //!< IACT given or should be calculated? real sigSmoothIact; //!< sigma of Gaussian to smooth ACTs - gmx_bool bAllowReduceIact; //!< Allow to reduce ACTs during smoothing. Otherwise ACT are only increased during smoothing - real acTrestart; //!< when computing ACT, time between restarting points + gmx_bool bAllowReduceIact; //!< Allow to reduce ACTs during smoothing. Otherwise ACT are only increased during smoothing + real acTrestart; //!< when computing ACT, time between restarting points /* \brief Enforce the same weight for each umbella window, that is * calculate with the same number of data points for @@ -277,7 +290,7 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) * \name Bootstrapping stuff */ /*!\{*/ - int nBootStrap; //!< nr of bootstraps (50 is usually enough) + int nBootStrap; //!< nr of bootstraps (50 is usually enough) /* \brief bootstrap method * @@ -305,7 +318,7 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) long the reaction coordinate xi. Avoids gaps along xi. */ int histBootStrapBlockLength; - int bsSeed; //!< random seed for bootstrapping + int bsSeed; //!< random seed for bootstrapping /* \brief Write cumulative distribution functions (CDFs) of histograms and write the generated histograms for each bootstrap */ @@ -315,37 +328,37 @@ typedef struct // NOLINT(clang-analyzer-optin.performance.Padding) * \name tabulated umbrella potential stuff */ /*!\{*/ - gmx_bool bTab; - double *tabX, *tabY, tabMin, tabMax, tabDz; - int tabNbins; + gmx_bool bTab; + double * tabX, *tabY, tabMin, tabMax, tabDz; + int tabNbins; /*!\}*/ - gmx::DefaultRandomEngine rng; //!< gromacs random number generator - gmx::TabulatedNormalDistribution<> normalDistribution; //!< Uses default: real output, 14-bit table + gmx::DefaultRandomEngine rng; //!< gromacs random number generator + gmx::TabulatedNormalDistribution<> normalDistribution; //!< Uses default: real output, 14-bit table } t_UmbrellaOptions; //! Make an umbrella window (may contain several histograms) -static t_UmbrellaWindow * initUmbrellaWindows(int nwin) +static t_UmbrellaWindow* initUmbrellaWindows(int nwin) { - t_UmbrellaWindow *win; + t_UmbrellaWindow* win; int i; snew(win, nwin); for (i = 0; i < nwin; i++) { - win[i].Histo = win[i].cum = nullptr; - win[i].k = win[i].pos = win[i].z = nullptr; - win[i].N = win[i].Ntot = nullptr; - win[i].g = win[i].tau = win[i].tausmooth = nullptr; - win[i].bContrib = nullptr; - win[i].ztime = nullptr; - win[i].forceAv = nullptr; - win[i].aver = win[i].sigma = nullptr; - win[i].bsWeight = nullptr; + win[i].Histo = win[i].cum = nullptr; + win[i].k = win[i].pos = win[i].z = nullptr; + win[i].N = win[i].Ntot = nullptr; + win[i].g = win[i].tau = win[i].tausmooth = nullptr; + win[i].bContrib = nullptr; + win[i].ztime = nullptr; + win[i].forceAv = nullptr; + win[i].aver = win[i].sigma = nullptr; + win[i].bsWeight = nullptr; } return win; } //! Delete an umbrella window (may contain several histograms) -static void freeUmbrellaWindows(t_UmbrellaWindow *win, int nwin) +static void freeUmbrellaWindows(t_UmbrellaWindow* win, int nwin) { int i, j; for (i = 0; i < nwin; i++) @@ -394,10 +407,10 @@ static void freeUmbrellaWindows(t_UmbrellaWindow *win, int nwin) /*! \brief * Read and setup tabulated umbrella potential */ -static void setup_tab(const char *fn, t_UmbrellaOptions *opt) +static void setup_tab(const char* fn, t_UmbrellaOptions* opt) { int i, ny, nl; - double **y; + double** y; printf("Setting up tabulated potential from file %s\n", fn); nl = read_xvg(fn, &y, &ny); @@ -407,16 +420,18 @@ static void setup_tab(const char *fn, t_UmbrellaOptions *opt) gmx_fatal(FARGS, "Found %d columns in %s. Expected 2.\n", ny, fn); } opt->tabMin = y[0][0]; - opt->tabMax = y[0][nl-1]; - opt->tabDz = (opt->tabMax-opt->tabMin)/(nl-1); + opt->tabMax = y[0][nl - 1]; + opt->tabDz = (opt->tabMax - opt->tabMin) / (nl - 1); if (opt->tabDz <= 0) { - gmx_fatal(FARGS, "The tabulated potential in %s must be provided in \n" - "ascending z-direction", fn); + gmx_fatal(FARGS, + "The tabulated potential in %s must be provided in \n" + "ascending z-direction", + fn); } - for (i = 0; i < nl-1; i++) + for (i = 0; i < nl - 1; i++) { - if (std::abs(y[0][i+1]-y[0][i]-opt->tabDz) > opt->tabDz/1e6) + if (std::abs(y[0][i + 1] - y[0][i] - opt->tabDz) > opt->tabDz / 1e6) { gmx_fatal(FARGS, "z-values in %s are not equally spaced.\n", fn); } @@ -428,12 +443,12 @@ static void setup_tab(const char *fn, t_UmbrellaOptions *opt) opt->tabX[i] = y[0][i]; opt->tabY[i] = y[1][i]; } - printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n", - opt->tabMin, opt->tabMax, opt->tabDz); + printf("Found equally spaced tabulated potential from %g to %g, spacing %g\n", opt->tabMin, + opt->tabMax, opt->tabDz); } //! Read the header of an PDO file (position, force const, nr of groups) -static void read_pdo_header(FILE * file, t_UmbrellaHeader * header, t_UmbrellaOptions *opt) +static void read_pdo_header(FILE* file, t_UmbrellaHeader* header, t_UmbrellaOptions* opt) { char line[2048]; char Buffer0[256], Buffer1[256], Buffer2[256], Buffer3[256], Buffer4[256]; @@ -449,7 +464,8 @@ static void read_pdo_header(FILE * file, t_UmbrellaHeader * header, t_UmbrellaOp ist >> Buffer0 >> Buffer1 >> Buffer2; if (std::strcmp(Buffer1, "UMBRELLA") != 0) { - gmx_fatal(FARGS, "This does not appear to be a valid pdo file. Found %s, expected %s\n" + gmx_fatal(FARGS, + "This does not appear to be a valid pdo file. Found %s, expected %s\n" "(Found in first line: `%s')\n", Buffer1, "UMBRELLA", line); } @@ -499,8 +515,7 @@ static void read_pdo_header(FILE * file, t_UmbrellaHeader * header, t_UmbrellaOp if (opt->verbose) { - printf("\tFound nPull=%d , nSkip=%d, ref=%s\n", header->nPull, header->nSkip, - header->Reference); + printf("\tFound nPull=%d , nSkip=%d, ref=%s\n", header->nPull, header->nSkip, header->Reference); } for (i = 0; i < header->nPull; ++i) @@ -516,8 +531,8 @@ static void read_pdo_header(FILE * file, t_UmbrellaHeader * header, t_UmbrellaOp if (opt->verbose) { - printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n", - i, header->PullName[i], header->UmbPos[i][0], header->UmbCons[i][0]); + printf("\tpullgroup %d, pullname = %s, UmbPos = %g, UmbConst = %g\n", i, + header->PullName[i], header->UmbPos[i][0], header->UmbCons[i][0]); } } @@ -534,12 +549,12 @@ static void read_pdo_header(FILE * file, t_UmbrellaHeader * header, t_UmbrellaOp } //! smarter fgets -static char *fgets3(FILE *fp, char ptr[], int *len) +static char* fgets3(FILE* fp, char ptr[], int* len) { - char *p; + char* p; int slen; - if (fgets(ptr, *len-1, fp) == nullptr) + if (fgets(ptr, *len - 1, fp) == nullptr) { return nullptr; } @@ -548,17 +563,17 @@ static char *fgets3(FILE *fp, char ptr[], int *len) { /* This line is longer than len characters, let's increase len! */ *len += STRLEN; - p += STRLEN; + p += STRLEN; srenew(ptr, *len); - if (fgets(p-1, STRLEN, fp) == nullptr) + if (fgets(p - 1, STRLEN, fp) == nullptr) { break; } } slen = std::strlen(ptr); - if (ptr[slen-1] == '\n') + if (ptr[slen - 1] == '\n') { - ptr[slen-1] = '\0'; + ptr[slen - 1] = '\0'; } return ptr; @@ -570,29 +585,33 @@ static char *fgets3(FILE *fp, char ptr[], int *len) * At the moment, this warning is avoided by hiding the format string * the variable fmtlf. */ -static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, - int fileno, t_UmbrellaWindow * win, - t_UmbrellaOptions *opt, - gmx_bool bGetMinMax, real *mintmp, real *maxtmp) +static void read_pdo_data(FILE* file, + t_UmbrellaHeader* header, + int fileno, + t_UmbrellaWindow* win, + t_UmbrellaOptions* opt, + gmx_bool bGetMinMax, + real* mintmp, + real* maxtmp) { - int i, inttemp, bins, count, ntot; - real minval, maxval, minfound = 1e20, maxfound = -1e20; - double temp, time, time0 = 0, dt; - char *ptr = nullptr; - t_UmbrellaWindow * window = nullptr; - gmx_bool timeok, dt_ok = true; - char *tmpbuf = nullptr, fmt[256], fmtign[256], fmtlf[5] = "%lf"; - int len = STRLEN, dstep = 1; - const int blocklen = 4096; - int *lennow = nullptr; + int i, inttemp, bins, count, ntot; + real minval, maxval, minfound = 1e20, maxfound = -1e20; + double temp, time, time0 = 0, dt; + char* ptr = nullptr; + t_UmbrellaWindow* window = nullptr; + gmx_bool timeok, dt_ok = true; + char * tmpbuf = nullptr, fmt[256], fmtign[256], fmtlf[5] = "%lf"; + int len = STRLEN, dstep = 1; + const int blocklen = 4096; + int* lennow = nullptr; if (!bGetMinMax) { - bins = opt->bins; - minval = opt->min; - maxval = opt->max; + bins = opt->bins; + minval = opt->min; + maxval = opt->max; - window = win+fileno; + window = win + fileno; /* Need to alocate memory and set up structure */ window->nPull = header->nPull; window->nBin = bins; @@ -640,12 +659,12 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, { minfound = 1e20; maxfound = -1e20; - minval = maxval = bins = 0; /* Get rid of warnings */ + minval = maxval = bins = 0; /* Get rid of warnings */ } count = 0; snew(tmpbuf, len); - while ( (ptr = fgets3(file, tmpbuf, &len)) != nullptr) + while ((ptr = fgets3(file, tmpbuf, &len)) != nullptr) { trim(ptr); @@ -660,7 +679,7 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, sscanf(ptr, fmtlf, &time); /* printf("Time %f\n",time); */ /* Round time to fs */ - time = 1.0/1000*( gmx::roundToInt64(time*1000) ); + time = 1.0 / 1000 * (gmx::roundToInt64(time * 1000)); /* get time step of pdo file */ if (count == 0) @@ -669,10 +688,10 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, } else if (count == 1) { - dt = time-time0; + dt = time - time0; if (opt->dt > 0.0) { - dstep = gmx::roundToInt(opt->dt/dt); + dstep = gmx::roundToInt(opt->dt / dt); if (dstep == 0) { dstep = 1; @@ -680,12 +699,12 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, } if (!bGetMinMax) { - window->dt = dt*dstep; + window->dt = dt * dstep; } } count++; - dt_ok = ((count-1)%dstep == 0); + dt_ok = ((count - 1) % dstep == 0); timeok = (dt_ok && time >= opt->tmin && time <= opt->tmax); /* if (opt->verbose) printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n", @@ -696,8 +715,8 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, for (i = 0; i < header->nPull; ++i) { std::strcpy(fmt, fmtign); - std::strcat(fmt, "%lf"); /* Creating a format stings such as "%*s...%*s%lf" */ - std::strcat(fmtign, "%*s"); /* ignoring one more entry in the next loop */ + std::strcat(fmt, "%lf"); /* Creating a format stings such as "%*s...%*s%lf" */ + std::strcat(fmtign, "%*s"); /* ignoring one more entry in the next loop */ if (sscanf(ptr, fmt, &temp)) { temp += header->UmbPos[i][0]; @@ -727,11 +746,11 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, } temp -= minval; - temp /= (maxval-minval); + temp /= (maxval - minval); temp *= bins; - temp = std::floor(temp); + temp = std::floor(temp); - inttemp = static_cast (temp); + inttemp = static_cast(temp); if (opt->bCycl) { if (inttemp < 0) @@ -781,49 +800,52 @@ static void read_pdo_data(FILE * file, t_UmbrellaHeader * header, * by this routine (not recommended). Since we now support autocorrelations, it is better to set * an appropriate autocorrelation times instead of using this function. */ -static void enforceEqualWeights(t_UmbrellaWindow * window, int nWindows) +static void enforceEqualWeights(t_UmbrellaWindow* window, int nWindows) { int i, k, j, NEnforced; double ratio; NEnforced = window[0].Ntot[0]; printf("\nFound -hist-eq. Enforcing equal weights for all histograms, \ni.e. doing a " - "non-weighted histogram analysis method. Ndata = %d\n", NEnforced); + "non-weighted histogram analysis method. Ndata = %d\n", + NEnforced); /* enforce all histograms to have the same weight as the very first histogram */ for (j = 0; j < nWindows; ++j) { for (k = 0; k < window[j].nPull; ++k) { - ratio = 1.0*NEnforced/window[j].Ntot[k]; + ratio = 1.0 * NEnforced / window[j].Ntot[k]; for (i = 0; i < window[0].nBin; ++i) { window[j].Histo[k][i] *= ratio; } - window[j].N[k] = gmx::roundToInt(ratio*window[j].N[k]); + window[j].N[k] = gmx::roundToInt(ratio * window[j].N[k]); } } } /*! \brief Simple linear interpolation between two given tabulated points */ -static double tabulated_pot(double dist, t_UmbrellaOptions *opt) +static double tabulated_pot(double dist, t_UmbrellaOptions* opt) { int jl, ju; double pl, pu, dz, dp; - jl = static_cast (std::floor((dist-opt->tabMin)/opt->tabDz)); - ju = jl+1; + jl = static_cast(std::floor((dist - opt->tabMin) / opt->tabDz)); + ju = jl + 1; if (jl < 0 || ju >= opt->tabNbins) { - gmx_fatal(FARGS, "Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n" - "Provide an extended table.", dist, jl, ju); + gmx_fatal(FARGS, + "Distance %f out of bounds of tabulated potential (jl=%d, ju=%d).\n" + "Provide an extended table.", + dist, jl, ju); } pl = opt->tabY[jl]; pu = opt->tabY[ju]; - dz = dist-opt->tabX[jl]; - dp = (pu-pl)*dz/opt->tabDz; - return pl+dp; + dz = dist - opt->tabX[jl]; + dp = (pu - pl) * dz / opt->tabDz; + return pl + dp; } @@ -834,13 +856,12 @@ static double tabulated_pot(double dist, t_UmbrellaOptions *opt) * After rapid convergence (using only substiantal contributions), we always switch to * full precision. */ -static void setup_acc_wham(const double *profile, t_UmbrellaWindow * window, int nWindows, - t_UmbrellaOptions *opt) +static void setup_acc_wham(const double* profile, t_UmbrellaWindow* window, int nWindows, t_UmbrellaOptions* opt) { - int i, j, k, nGrptot = 0, nContrib = 0, nTot = 0; - double U, min = opt->min, dz = opt->dz, temp, ztot_half, distance, ztot, contrib1, contrib2; - gmx_bool bAnyContrib; - static int bFirst = 1; + int i, j, k, nGrptot = 0, nContrib = 0, nTot = 0; + double U, min = opt->min, dz = opt->dz, temp, ztot_half, distance, ztot, contrib1, contrib2; + gmx_bool bAnyContrib; + static int bFirst = 1; static double wham_contrib_lim; if (bFirst) @@ -849,11 +870,11 @@ static void setup_acc_wham(const double *profile, t_UmbrellaWindow * window, int { nGrptot += window[i].nPull; } - wham_contrib_lim = opt->Tolerance/nGrptot; + wham_contrib_lim = opt->Tolerance / nGrptot; } - ztot = opt->max-opt->min; - ztot_half = ztot/2; + ztot = opt->max - opt->min; + ztot_half = ztot / 2; for (i = 0; i < nWindows; ++i) { @@ -870,11 +891,11 @@ static void setup_acc_wham(const double *profile, t_UmbrellaWindow * window, int bAnyContrib = FALSE; for (k = 0; k < opt->bins; ++k) { - temp = (1.0*k+0.5)*dz+min; - distance = temp - window[i].pos[j]; /* distance to umbrella center */ + temp = (1.0 * k + 0.5) * dz + min; + distance = temp - window[i].pos[j]; /* distance to umbrella center */ if (opt->bCycl) - { /* in cyclic wham: */ - if (distance > ztot_half) /* |distance| < ztot_half */ + { /* in cyclic wham: */ + if (distance > ztot_half) /* |distance| < ztot_half */ { distance -= ztot; } @@ -892,14 +913,14 @@ static void setup_acc_wham(const double *profile, t_UmbrellaWindow * window, int if (!opt->bTab) { - U = 0.5*window[i].k[j]*gmx::square(distance); /* harmonic potential assumed. */ + U = 0.5 * window[i].k[j] * gmx::square(distance); /* harmonic potential assumed. */ } else { - U = tabulated_pot(distance, opt); /* Use tabulated potential */ + U = tabulated_pot(distance, opt); /* Use tabulated potential */ } - contrib1 = profile[k]*std::exp(-U/(BOLTZ*opt->Temperature)); - contrib2 = window[i].N[j]*std::exp(-U/(BOLTZ*opt->Temperature) + window[i].z[j]); + contrib1 = profile[k] * std::exp(-U / (BOLTZ * opt->Temperature)); + contrib2 = window[i].N[j] * std::exp(-U / (BOLTZ * opt->Temperature) + window[i].z[j]); window[i].bContrib[j][k] = (contrib1 > wham_contrib_lim || contrib2 > wham_contrib_lim); bAnyContrib = bAnyContrib || window[i].bContrib[j][k]; if (window[i].bContrib[j][k]) @@ -923,25 +944,24 @@ static void setup_acc_wham(const double *profile, t_UmbrellaWindow * window, int if (bFirst) { printf("Initialized rapid wham stuff (contrib tolerance %g)\n" - "Evaluating only %d of %d expressions.\n\n", wham_contrib_lim, nContrib, nTot); + "Evaluating only %d of %d expressions.\n\n", + wham_contrib_lim, nContrib, nTot); } if (opt->verbose) { - printf("Updated rapid wham stuff. (evaluating only %d of %d contributions)\n", - nContrib, nTot); + printf("Updated rapid wham stuff. (evaluating only %d of %d contributions)\n", nContrib, nTot); } bFirst = 0; } //! Compute the PMF (one of the two main WHAM routines) -static void calc_profile(double *profile, t_UmbrellaWindow * window, int nWindows, - t_UmbrellaOptions *opt, gmx_bool bExact) +static void calc_profile(double* profile, t_UmbrellaWindow* window, int nWindows, t_UmbrellaOptions* opt, gmx_bool bExact) { double ztot_half, ztot, min = opt->min, dz = opt->dz; - ztot = opt->max-opt->min; - ztot_half = ztot/2; + ztot = opt->max - opt->min; + ztot_half = ztot / 2; #pragma omp parallel { @@ -950,8 +970,8 @@ static void calc_profile(double *profile, t_UmbrellaWindow * window, int nWindow int nthreads = gmx_omp_get_max_threads(); int thread_id = gmx_omp_get_thread_num(); int i; - int i0 = thread_id*opt->bins/nthreads; - int i1 = std::min(opt->bins, ((thread_id+1)*opt->bins)/nthreads); + int i0 = thread_id * opt->bins / nthreads; + int i1 = std::min(opt->bins, ((thread_id + 1) * opt->bins) / nthreads); for (i = i0; i < i1; ++i) { @@ -962,18 +982,18 @@ static void calc_profile(double *profile, t_UmbrellaWindow * window, int nWindow { for (k = 0; k < window[j].nPull; ++k) { - invg = 1.0/window[j].g[k] * window[j].bsWeight[k]; - temp = (1.0*i+0.5)*dz+min; - num += invg*window[j].Histo[k][i]; + invg = 1.0 / window[j].g[k] * window[j].bsWeight[k]; + temp = (1.0 * i + 0.5) * dz + min; + num += invg * window[j].Histo[k][i]; if (!(bExact || window[j].bContrib[k][i])) { continue; } - distance = temp - window[j].pos[k]; /* distance to umbrella center */ + distance = temp - window[j].pos[k]; /* distance to umbrella center */ if (opt->bCycl) - { /* in cyclic wham: */ - if (distance > ztot_half) /* |distance| < ztot_half */ + { /* in cyclic wham: */ + if (distance > ztot_half) /* |distance| < ztot_half */ { distance -= ztot; } @@ -985,31 +1005,31 @@ static void calc_profile(double *profile, t_UmbrellaWindow * window, int nWindow if (!opt->bTab) { - U = 0.5*window[j].k[k]*gmx::square(distance); /* harmonic potential assumed. */ + U = 0.5 * window[j].k[k] * gmx::square(distance); /* harmonic potential assumed. */ } else { - U = tabulated_pot(distance, opt); /* Use tabulated potential */ + U = tabulated_pot(distance, opt); /* Use tabulated potential */ } - denom += invg*window[j].N[k]*std::exp(-U/(BOLTZ*opt->Temperature) + window[j].z[k]); + denom += invg * window[j].N[k] + * std::exp(-U / (BOLTZ * opt->Temperature) + window[j].z[k]); } } - profile[i] = num/denom; + profile[i] = num / denom; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } //! Compute the free energy offsets z (one of the two main WHAM routines) -static double calc_z(const double * profile, t_UmbrellaWindow * window, int nWindows, - t_UmbrellaOptions *opt, gmx_bool bExact) +static double calc_z(const double* profile, t_UmbrellaWindow* window, int nWindows, t_UmbrellaOptions* opt, gmx_bool bExact) { - double min = opt->min, dz = opt->dz, ztot_half, ztot; + double min = opt->min, dz = opt->dz, ztot_half, ztot; double maxglob = -1e20; - ztot = opt->max-opt->min; - ztot_half = ztot/2; + ztot = opt->max - opt->min; + ztot_half = ztot / 2; #pragma omp parallel { @@ -1018,13 +1038,13 @@ static double calc_z(const double * profile, t_UmbrellaWindow * window, int nWin int nthreads = gmx_omp_get_max_threads(); int thread_id = gmx_omp_get_thread_num(); int i; - int i0 = thread_id*nWindows/nthreads; - int i1 = std::min(nWindows, ((thread_id+1)*nWindows)/nthreads); - double maxloc = -1e20; + int i0 = thread_id * nWindows / nthreads; + int i1 = std::min(nWindows, ((thread_id + 1) * nWindows) / nthreads); + double maxloc = -1e20; for (i = i0; i < i1; ++i) { - double total = 0, temp, distance, U = 0; + double total = 0, temp, distance, U = 0; int j, k; for (j = 0; j < window[i].nPull; ++j) @@ -1036,11 +1056,11 @@ static double calc_z(const double * profile, t_UmbrellaWindow * window, int nWin { continue; } - temp = (1.0*k+0.5)*dz+min; - distance = temp - window[i].pos[j]; /* distance to umbrella center */ + temp = (1.0 * k + 0.5) * dz + min; + distance = temp - window[i].pos[j]; /* distance to umbrella center */ if (opt->bCycl) - { /* in cyclic wham: */ - if (distance > ztot_half) /* |distance| < ztot_half */ + { /* in cyclic wham: */ + if (distance > ztot_half) /* |distance| < ztot_half */ { distance -= ztot; } @@ -1052,13 +1072,13 @@ static double calc_z(const double * profile, t_UmbrellaWindow * window, int nWin if (!opt->bTab) { - U = 0.5*window[i].k[j]*gmx::square(distance); /* harmonic potential assumed. */ + U = 0.5 * window[i].k[j] * gmx::square(distance); /* harmonic potential assumed. */ } else { - U = tabulated_pot(distance, opt); /* Use tabulated potential */ + U = tabulated_pot(distance, opt); /* Use tabulated potential */ } - total += profile[k]*std::exp(-U/(BOLTZ*opt->Temperature)); + total += profile[k] * std::exp(-U / (BOLTZ * opt->Temperature)); } /* Avoid floating point exception if window is far outside min and max */ if (total != 0.0) @@ -1089,14 +1109,14 @@ static double calc_z(const double * profile, t_UmbrellaWindow * window, int nWin } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } return maxglob; } //! Make PMF symmetric around 0 (useful e.g. for membranes) -static void symmetrizeProfile(double* profile, t_UmbrellaOptions *opt) +static void symmetrizeProfile(double* profile, t_UmbrellaOptions* opt) { int i, j, bins = opt->bins; double *prof2, min = opt->min, max = opt->max, dz = opt->dz, zsym, deltaz, profsym; @@ -1104,26 +1124,26 @@ static void symmetrizeProfile(double* profile, t_UmbrellaOptions *opt) if (min > 0. || max < 0.) { - gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", - opt->min, opt->max); + gmx_fatal(FARGS, "Cannot symmetrize profile around z=0 with min=%f and max=%f\n", opt->min, + opt->max); } snew(prof2, bins); for (i = 0; i < bins; i++) { - z = min+(i+0.5)*dz; + z = min + (i + 0.5) * dz; zsym = -z; /* bin left of zsym */ - j = gmx::roundToInt((zsym-min)/dz)-1; - if (j >= 0 && (j+1) < bins) + j = gmx::roundToInt((zsym - min) / dz) - 1; + if (j >= 0 && (j + 1) < bins) { /* interpolate profile linearly between bins j and j+1 */ - z1 = min+(j+0.5)*dz; - deltaz = zsym-z1; - profsym = profile[j] + (profile[j+1]-profile[j])/dz*deltaz; + z1 = min + (j + 0.5) * dz; + deltaz = zsym - z1; + profsym = profile[j] + (profile[j + 1] - profile[j]) / dz * deltaz; /* average between left and right */ - prof2[i] = 0.5*(profsym+profile[i]); + prof2[i] = 0.5 * (profsym + profile[i]); } else { @@ -1131,17 +1151,17 @@ static void symmetrizeProfile(double* profile, t_UmbrellaOptions *opt) } } - std::memcpy(profile, prof2, bins*sizeof(double)); + std::memcpy(profile, prof2, bins * sizeof(double)); sfree(prof2); } //! Set energy unit (kJ/mol,kT,kCal/mol) and set it to zero at opt->zProf0 -static void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt) +static void prof_normalization_and_unit(double* profile, t_UmbrellaOptions* opt) { int i, bins, imin; double unit_factor = 1., diff; - bins = opt->bins; + bins = opt->bins; /* Not log? Nothing to do! */ if (!opt->bLog) @@ -1156,11 +1176,11 @@ static void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt } else if (opt->unit == en_kJ) { - unit_factor = BOLTZ*opt->Temperature; + unit_factor = BOLTZ * opt->Temperature; } else if (opt->unit == en_kCal) { - unit_factor = (BOLTZ/CAL2JOULE)*opt->Temperature; + unit_factor = (BOLTZ / CAL2JOULE) * opt->Temperature; } else { @@ -1171,7 +1191,7 @@ static void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt { if (profile[i] > 0.0) { - profile[i] = -std::log(profile[i])*unit_factor; + profile[i] = -std::log(profile[i]) * unit_factor; } } @@ -1184,14 +1204,14 @@ static void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt { /* Get bin with shortest distance to opt->zProf0 (-0.5 from bin position and +0.5 from rounding cancel) */ - imin = static_cast((opt->zProf0-opt->min)/opt->dz); + imin = static_cast((opt->zProf0 - opt->min) / opt->dz); if (imin < 0) { imin = 0; } else if (imin >= bins) { - imin = bins-1; + imin = bins - 1; } diff = profile[imin]; } @@ -1204,9 +1224,9 @@ static void prof_normalization_and_unit(double * profile, t_UmbrellaOptions *opt } //! Make an array of random integers (used for bootstrapping) -static void getRandomIntArray(int nPull, int blockLength, int* randomArray, gmx::DefaultRandomEngine * rng) +static void getRandomIntArray(int nPull, int blockLength, int* randomArray, gmx::DefaultRandomEngine* rng) { - gmx::UniformIntDistribution dist(0, blockLength-1); + gmx::UniformIntDistribution dist(0, blockLength - 1); int ipull, blockBase, nr, ipullRandom; @@ -1217,16 +1237,16 @@ static void getRandomIntArray(int nPull, int blockLength, int* randomArray, gmx: for (ipull = 0; ipull < nPull; ipull++) { - blockBase = (ipull/blockLength)*blockLength; + blockBase = (ipull / blockLength) * blockLength; do { /* make sure nothing bad happens in the last block */ nr = dist(*rng); // [0,blockLength-1] ipullRandom = blockBase + nr; - } - while (ipullRandom >= nPull); + } while (ipullRandom >= nPull); if (ipullRandom < 0 || ipullRandom >= nPull) { - gmx_fatal(FARGS, "Ups, random iWin = %d, nPull = %d, nr = %d, " + gmx_fatal(FARGS, + "Ups, random iWin = %d, nPull = %d, nr = %d, " "blockLength = %d, blockBase = %d\n", ipullRandom, nPull, nr, blockLength, blockBase); } @@ -1239,17 +1259,16 @@ static void getRandomIntArray(int nPull, int blockLength, int* randomArray, gmx: * This is used when bootstapping new trajectories and thereby create new histogtrams, * but it is not required if we bootstrap complete histograms. */ -static void copy_pullgrp_to_synthwindow(t_UmbrellaWindow *synthWindow, - t_UmbrellaWindow *thisWindow, int pullid) +static void copy_pullgrp_to_synthwindow(t_UmbrellaWindow* synthWindow, t_UmbrellaWindow* thisWindow, int pullid) { - synthWindow->N [0] = thisWindow->N [pullid]; - synthWindow->Histo [0] = thisWindow->Histo [pullid]; - synthWindow->pos [0] = thisWindow->pos [pullid]; - synthWindow->z [0] = thisWindow->z [pullid]; - synthWindow->k [0] = thisWindow->k [pullid]; - synthWindow->bContrib[0] = thisWindow->bContrib [pullid]; - synthWindow->g [0] = thisWindow->g [pullid]; - synthWindow->bsWeight[0] = thisWindow->bsWeight [pullid]; + synthWindow->N[0] = thisWindow->N[pullid]; + synthWindow->Histo[0] = thisWindow->Histo[pullid]; + synthWindow->pos[0] = thisWindow->pos[pullid]; + synthWindow->z[0] = thisWindow->z[pullid]; + synthWindow->k[0] = thisWindow->k[pullid]; + synthWindow->bContrib[0] = thisWindow->bContrib[pullid]; + synthWindow->g[0] = thisWindow->g[pullid]; + synthWindow->bsWeight[0] = thisWindow->bsWeight[pullid]; } /*! \brief Calculate cumulative distribution function of of all histograms. @@ -1258,13 +1277,16 @@ static void copy_pullgrp_to_synthwindow(t_UmbrellaWindow *synthWindow, * which are distributed according to the histograms. Required to generate * the "synthetic" histograms for the Bootstrap method */ -static void calc_cumulatives(t_UmbrellaWindow *window, int nWindows, - t_UmbrellaOptions *opt, const char *fnhist, const char *xlabel) +static void calc_cumulatives(t_UmbrellaWindow* window, + int nWindows, + t_UmbrellaOptions* opt, + const char* fnhist, + const char* xlabel) { int i, j, k, nbin; double last; std::string fn; - FILE *fp = nullptr; + FILE* fp = nullptr; if (opt->bs_verbose) { @@ -1278,11 +1300,11 @@ static void calc_cumulatives(t_UmbrellaWindow *window, int nWindows, snew(window[i].cum, window[i].nPull); for (j = 0; j < window[i].nPull; j++) { - snew(window[i].cum[j], nbin+1); + snew(window[i].cum[j], nbin + 1); window[i].cum[j][0] = 0.; for (k = 1; k <= nbin; k++) { - window[i].cum[j][k] = window[i].cum[j][k-1]+window[i].Histo[j][k-1]; + window[i].cum[j][k] = window[i].cum[j][k - 1] + window[i].Histo[j][k - 1]; } /* normalize CDFs. Ensure cum[nbin]==1 */ @@ -1299,7 +1321,7 @@ static void calc_cumulatives(t_UmbrellaWindow *window, int nWindows, { for (k = 0; k <= nbin; k++) { - fprintf(fp, "%g\t", opt->min+k*opt->dz); + fprintf(fp, "%g\t", opt->min + k * opt->dz); for (i = 0; i < nWindows; i++) { for (j = 0; j < window[i].nPull; j++) @@ -1319,15 +1341,15 @@ static void calc_cumulatives(t_UmbrellaWindow *window, int nWindows, * * This is used to generate a random sequence distributed according to a histogram */ -static void searchCumulative(const double xx[], int n, double x, int *j) +static void searchCumulative(const double xx[], int n, double x, int* j) { int ju, jm, jl; jl = -1; ju = n; - while (ju-jl > 1) + while (ju - jl > 1) { - jm = (ju+jl) >> 1; + jm = (ju + jl) >> 1; if (x >= xx[jm]) { jl = jm; @@ -1341,9 +1363,9 @@ static void searchCumulative(const double xx[], int n, double x, int *j) { *j = 0; } - else if (x == xx[n-1]) + else if (x == xx[n - 1]) { - *j = n-2; + *j = n - 2; } else { @@ -1352,8 +1374,10 @@ static void searchCumulative(const double xx[], int n, double x, int *j) } //! Bootstrap new trajectories and thereby generate new (bootstrapped) histograms -static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWindow *thisWindow, - int pullid, t_UmbrellaOptions *opt) +static void create_synthetic_histo(t_UmbrellaWindow* synthWindow, + t_UmbrellaWindow* thisWindow, + int pullid, + t_UmbrellaOptions* opt) { int N, i, nbins, r_index, ibin; double r, tausteps = 0.0, a, ap, dt, x, invsqrt2, g, y, sig = 0., z, mu = 0.; @@ -1366,13 +1390,13 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind /* tau = autocorrelation time */ if (opt->tauBootStrap > 0.0) { - tausteps = opt->tauBootStrap/dt; + tausteps = opt->tauBootStrap / dt; } else if (opt->bTauIntGiven || opt->bCalcTauInt) { /* calc tausteps from g=1+2tausteps */ g = thisWindow->g[pullid]; - tausteps = (g-1)/2; + tausteps = (g - 1) / 2; } else { @@ -1390,12 +1414,12 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind gmx_fatal(FARGS, "%s", errstr); } - synthWindow->N [0] = N; - synthWindow->pos [0] = thisWindow->pos[pullid]; - synthWindow->z [0] = thisWindow->z[pullid]; - synthWindow->k [0] = thisWindow->k[pullid]; + synthWindow->N[0] = N; + synthWindow->pos[0] = thisWindow->pos[pullid]; + synthWindow->z[0] = thisWindow->z[pullid]; + synthWindow->k[0] = thisWindow->k[pullid]; synthWindow->bContrib[0] = thisWindow->bContrib[pullid]; - synthWindow->g [0] = thisWindow->g [pullid]; + synthWindow->g[0] = thisWindow->g[pullid]; synthWindow->bsWeight[0] = thisWindow->bsWeight[pullid]; for (i = 0; i < nbins; i++) @@ -1405,8 +1429,8 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind if (opt->bsMethod == bsMethod_trajGauss) { - sig = thisWindow->sigma [pullid]; - mu = thisWindow->aver [pullid]; + sig = thisWindow->sigma[pullid]; + mu = thisWindow->aver[pullid]; } /* Genrate autocorrelated Gaussian random variable with autocorrelation time tau @@ -1425,9 +1449,9 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind Note: The ACT of the flat distribution and of the generated histogram is not 100% exactly tau, but near tau (my test was 3.8 instead of 4). */ - a = std::exp(-1.0/tausteps); - ap = std::sqrt(1.0-a*a); - invsqrt2 = 1.0/std::sqrt(2.0); + a = std::exp(-1.0 / tausteps); + ap = std::sqrt(1.0 - a * a); + invsqrt2 = 1.0 / std::sqrt(2.0); /* init random sequence */ x = opt->normalDistribution(opt->rng); @@ -1438,12 +1462,12 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind for (i = 0; i < N; i++) { y = opt->normalDistribution(opt->rng); - x = a*x+ap*y; + x = a * x + ap * y; /* get flat distribution in [0,1] using cumulative distribution function of Gauusian Note: CDF(Gaussian) = 0.5*{1+erf[x/sqrt(2)]} */ - r = 0.5*(1+std::erf(x*invsqrt2)); - searchCumulative(thisWindow->cum[pullid], nbins+1, r, &r_index); + r = 0.5 * (1 + std::erf(x * invsqrt2)); + searchCumulative(thisWindow->cum[pullid], nbins + 1, r, &r_index); synthWindow->Histo[0][r_index] += 1.; } } @@ -1458,24 +1482,18 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind while (i < N) { y = opt->normalDistribution(opt->rng); - x = a*x+ap*y; - z = x*sig+mu; - ibin = static_cast (std::floor((z-opt->min)/opt->dz)); + x = a * x + ap * y; + z = x * sig + mu; + ibin = static_cast(std::floor((z - opt->min) / opt->dz)); if (opt->bCycl) { if (ibin < 0) { - while ( (ibin += nbins) < 0) - { - ; - } + while ((ibin += nbins) < 0) {} } else if (ibin >= nbins) { - while ( (ibin -= nbins) >= nbins) - { - ; - } + while ((ibin -= nbins) >= nbins) {} } } @@ -1497,11 +1515,15 @@ static void create_synthetic_histo(t_UmbrellaWindow *synthWindow, t_UmbrellaWind * If bs_index>=0, a number is added to the output file name to allow the ouput of all * sets of bootstrapped histograms. */ -static void print_histograms(const char *fnhist, t_UmbrellaWindow * window, int nWindows, - int bs_index, t_UmbrellaOptions *opt, const char *xlabel) +static void print_histograms(const char* fnhist, + t_UmbrellaWindow* window, + int nWindows, + int bs_index, + t_UmbrellaOptions* opt, + const char* xlabel) { std::string fn, title; - FILE *fp; + FILE* fp; int bins, l, i, j; if (bs_index >= 0) @@ -1521,7 +1543,7 @@ static void print_histograms(const char *fnhist, t_UmbrellaWindow * window, int /* Write histograms */ for (l = 0; l < bins; ++l) { - fprintf(fp, "%e\t", (l+0.5)*opt->dz+opt->min); + fprintf(fp, "%e\t", (l + 0.5) * opt->dz + opt->min); for (i = 0; i < nWindows; ++i) { for (j = 0; j < window[i].nPull; ++j) @@ -1537,26 +1559,26 @@ static void print_histograms(const char *fnhist, t_UmbrellaWindow * window, int } //! Make random weights for histograms for the Bayesian bootstrap of complete histograms) -static void setRandomBsWeights(t_UmbrellaWindow *synthwin, int nAllPull, t_UmbrellaOptions *opt) +static void setRandomBsWeights(t_UmbrellaWindow* synthwin, int nAllPull, t_UmbrellaOptions* opt) { - int i; - double *r; + int i; + double* r; gmx::UniformRealDistribution dist(0, nAllPull); snew(r, nAllPull); /* generate ordered random numbers between 0 and nAllPull */ - for (i = 0; i < nAllPull-1; i++) + for (i = 0; i < nAllPull - 1; i++) { r[i] = dist(opt->rng); } - std::sort(r, r+nAllPull-1); - r[nAllPull-1] = 1.0*nAllPull; + std::sort(r, r + nAllPull - 1); + r[nAllPull - 1] = 1.0 * nAllPull; synthwin[0].bsWeight[0] = r[0]; for (i = 1; i < nAllPull; i++) { - synthwin[i].bsWeight[0] = r[i]-r[i-1]; + synthwin[i].bsWeight[0] = r[i] - r[i - 1]; } /* avoid to have zero weight by adding a tiny value */ @@ -1572,16 +1594,22 @@ static void setRandomBsWeights(t_UmbrellaWindow *synthwin, int nAllPull, t_Umbre } //! The main bootstrapping routine -static void do_bootstrapping(const char *fnres, const char* fnprof, const char *fnhist, - const char *xlabel, char* ylabel, double *profile, - t_UmbrellaWindow * window, int nWindows, t_UmbrellaOptions *opt) +static void do_bootstrapping(const char* fnres, + const char* fnprof, + const char* fnhist, + const char* xlabel, + char* ylabel, + double* profile, + t_UmbrellaWindow* window, + int nWindows, + t_UmbrellaOptions* opt) { - t_UmbrellaWindow * synthWindow; - double *bsProfile, *bsProfiles_av, *bsProfiles_av2, maxchange = 1e20, tmp, stddev; - int i, j, *randomArray = nullptr, winid, pullid, ib; - int iAllPull, nAllPull, *allPull_winId, *allPull_pullId; - FILE *fp; - gmx_bool bExact = FALSE; + t_UmbrellaWindow* synthWindow; + double * bsProfile, *bsProfiles_av, *bsProfiles_av2, maxchange = 1e20, tmp, stddev; + int i, j, *randomArray = nullptr, winid, pullid, ib; + int iAllPull, nAllPull, *allPull_winId, *allPull_pullId; + FILE* fp; + gmx_bool bExact = FALSE; /* init random generator */ if (opt->bsSeed == 0) @@ -1590,7 +1618,7 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * } opt->rng.seed(opt->bsSeed); - snew(bsProfile, opt->bins); + snew(bsProfile, opt->bins); snew(bsProfiles_av, opt->bins); snew(bsProfiles_av2, opt->bins); @@ -1646,17 +1674,14 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * /* just copy all histogams into synthWindow array */ for (i = 0; i < nAllPull; i++) { - winid = allPull_winId [i]; + winid = allPull_winId[i]; pullid = allPull_pullId[i]; - copy_pullgrp_to_synthwindow(synthWindow+i, window+winid, pullid); + copy_pullgrp_to_synthwindow(synthWindow + i, window + winid, pullid); } break; case bsMethod_traj: - case bsMethod_trajGauss: - calc_cumulatives(window, nWindows, opt, fnhist, xlabel); - break; - default: - gmx_fatal(FARGS, "Unknown bootstrap method. That should not have happened.\n"); + case bsMethod_trajGauss: calc_cumulatives(window, nWindows, opt, fnhist, xlabel); break; + default: gmx_fatal(FARGS, "Unknown bootstrap method. That should not have happened.\n"); } /* do bootstrapping */ @@ -1665,7 +1690,8 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * { printf(" *******************************************\n" " ******** Start bootstrap nr %d ************\n" - " *******************************************\n", ib+1); + " *******************************************\n", + ib + 1); switch (opt->bsMethod) { @@ -1675,9 +1701,9 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * getRandomIntArray(nAllPull, opt->histBootStrapBlockLength, randomArray, &opt->rng); for (i = 0; i < nAllPull; i++) { - winid = allPull_winId [randomArray[i]]; + winid = allPull_winId[randomArray[i]]; pullid = allPull_pullId[randomArray[i]]; - copy_pullgrp_to_synthwindow(synthWindow+i, window+winid, pullid); + copy_pullgrp_to_synthwindow(synthWindow + i, window + winid, pullid); } break; case bsMethod_BayesianHist: @@ -1692,7 +1718,7 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * { winid = allPull_winId[i]; pullid = allPull_pullId[i]; - create_synthetic_histo(synthWindow+i, window+winid, pullid, opt); + create_synthetic_histo(synthWindow + i, window + winid, pullid, opt); } break; } @@ -1707,10 +1733,10 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * i = 0; bExact = FALSE; maxchange = 1e20; - std::memcpy(bsProfile, profile, opt->bins*sizeof(double)); /* use profile as guess */ + std::memcpy(bsProfile, profile, opt->bins * sizeof(double)); /* use profile as guess */ do { - if ( (i%opt->stepUpdateContrib) == 0) + if ((i % opt->stepUpdateContrib) == 0) { setup_acc_wham(bsProfile, synthWindow, nAllPull, opt); } @@ -1718,14 +1744,14 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * { bExact = TRUE; } - if (((i%opt->stepchange) == 0 || i == 1) && i != 0) + if (((i % opt->stepchange) == 0 || i == 1) && i != 0) { printf("\t%4d) Maximum change %e\n", i, maxchange); } calc_profile(bsProfile, synthWindow, nAllPull, opt, bExact); i++; - } - while ( (maxchange = calc_z(bsProfile, synthWindow, nAllPull, opt, bExact)) > opt->Tolerance || !bExact); + } while ((maxchange = calc_z(bsProfile, synthWindow, nAllPull, opt, bExact)) > opt->Tolerance + || !bExact); printf("\tConverged in %d iterations. Final maximum change %g\n", i, maxchange); if (opt->bLog) @@ -1742,10 +1768,10 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * /* save stuff to get average and stddev */ for (i = 0; i < opt->bins; i++) { - tmp = bsProfile[i]; - bsProfiles_av[i] += tmp; - bsProfiles_av2[i] += tmp*tmp; - fprintf(fp, "%e\t%e\n", (i+0.5)*opt->dz+opt->min, tmp); + tmp = bsProfile[i]; + bsProfiles_av[i] += tmp; + bsProfiles_av2[i] += tmp * tmp; + fprintf(fp, "%e\t%e\n", (i + 0.5) * opt->dz + opt->min, tmp); } fprintf(fp, "%s\n", output_env_get_print_xvgr_codes(opt->oenv) ? "&" : ""); } @@ -1759,30 +1785,30 @@ static void do_bootstrapping(const char *fnres, const char* fnprof, const char * } for (i = 0; i < opt->bins; i++) { - bsProfiles_av [i] /= opt->nBootStrap; + bsProfiles_av[i] /= opt->nBootStrap; bsProfiles_av2[i] /= opt->nBootStrap; - tmp = bsProfiles_av2[i]-gmx::square(bsProfiles_av[i]); - stddev = (tmp >= 0.) ? std::sqrt(tmp) : 0.; /* Catch rouding errors */ - fprintf(fp, "%e\t%e\t%e\n", (i+0.5)*opt->dz+opt->min, bsProfiles_av [i], stddev); + tmp = bsProfiles_av2[i] - gmx::square(bsProfiles_av[i]); + stddev = (tmp >= 0.) ? std::sqrt(tmp) : 0.; /* Catch rouding errors */ + fprintf(fp, "%e\t%e\t%e\n", (i + 0.5) * opt->dz + opt->min, bsProfiles_av[i], stddev); } xvgrclose(fp); printf("Wrote boot strap result to %s\n", fnres); } //! Return type of input file based on file extension (xvg, pdo, or tpr) -static int whaminFileType(char *fn) +static int whaminFileType(char* fn) { int len; len = std::strlen(fn); - if (std::strcmp(fn+len-3, "tpr") == 0) + if (std::strcmp(fn + len - 3, "tpr") == 0) { return whamin_tpr; } - else if (std::strcmp(fn+len-3, "xvg") == 0 || std::strcmp(fn+len-6, "xvg.gz") == 0) + else if (std::strcmp(fn + len - 3, "xvg") == 0 || std::strcmp(fn + len - 6, "xvg.gz") == 0) { return whamin_pullxf; } - else if (std::strcmp(fn+len-3, "pdo") == 0 || std::strcmp(fn+len-6, "pdo.gz") == 0) + else if (std::strcmp(fn + len - 3, "pdo") == 0 || std::strcmp(fn + len - 6, "pdo.gz") == 0) { return whamin_pdo; } @@ -1793,12 +1819,11 @@ static int whaminFileType(char *fn) } //! Read the files names in pdo-files.dat, pullf/x-files.dat, tpr-files.dat -static void read_wham_in(const char *fn, char ***filenamesRet, int *nfilesRet, - t_UmbrellaOptions *opt) +static void read_wham_in(const char* fn, char*** filenamesRet, int* nfilesRet, t_UmbrellaOptions* opt) { - char **filename = nullptr, tmp[WHAM_MAXFILELEN+2]; + char **filename = nullptr, tmp[WHAM_MAXFILELEN + 2]; int nread, sizenow, i, block = 1; - FILE *fp; + FILE* fp; fp = gmx_ffopen(fn, "r"); nread = 0; @@ -1813,15 +1838,15 @@ static void read_wham_in(const char *fn, char ***filenamesRet, int *nfilesRet, { sizenow += block; srenew(filename, sizenow); - for (i = sizenow-block; i < sizenow; i++) + for (i = sizenow - block; i < sizenow; i++) { snew(filename[i], WHAM_MAXFILELEN); } } /* remove newline if there is one */ - if (tmp[std::strlen(tmp)-1] == '\n') + if (tmp[std::strlen(tmp) - 1] == '\n') { - tmp[std::strlen(tmp)-1] = '\0'; + tmp[std::strlen(tmp) - 1] = '\0'; } std::strcpy(filename[nread], tmp); if (opt->verbose) @@ -1835,14 +1860,14 @@ static void read_wham_in(const char *fn, char ***filenamesRet, int *nfilesRet, } //! Open a file or a pipe to a gzipped file -static FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt, gmx_bool *bPipeOpen) +static FILE* open_pdo_pipe(const char* fn, t_UmbrellaOptions* opt, gmx_bool* bPipeOpen) { char Buffer[2048], gunzip[1024], *Path = nullptr; - FILE *pipe = nullptr; + FILE* pipe = nullptr; static gmx_bool bFirst = true; /* gzipped pdo file? */ - if ((std::strcmp(fn+std::strlen(fn)-3, ".gz") == 0)) + if ((std::strcmp(fn + std::strlen(fn) - 3, ".gz") == 0)) { /* search gunzip executable */ if (!(Path = getenv("GMX_PATH_GZIP"))) @@ -1857,7 +1882,8 @@ static FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt, gmx_bool *bPi } else { - gmx_fatal(FARGS, "Cannot find executable gunzip in /bin or /usr/bin.\n" + gmx_fatal(FARGS, + "Cannot find executable gunzip in /bin or /usr/bin.\n" "You may want to define the path to gunzip " "with the environment variable GMX_PATH_GZIP."); } @@ -1867,8 +1893,10 @@ static FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt, gmx_bool *bPi sprintf(gunzip, "%s/gunzip", Path); if (!gmx_fexist(gunzip)) { - gmx_fatal(FARGS, "Cannot find executable %s. Please define the path to gunzip" - " in the environmental varialbe GMX_PATH_GZIP.", gunzip); + gmx_fatal(FARGS, + "Cannot find executable %s. Please define the path to gunzip" + " in the environmental varialbe GMX_PATH_GZIP.", + gunzip); } } if (bFirst) @@ -1905,7 +1933,7 @@ static FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt, gmx_bool *bPi } //! Close file or pipe -static void pdo_close_file(FILE *fp) +static void pdo_close_file(FILE* fp) { #if HAVE_PIPES pclose(fp); @@ -1915,10 +1943,9 @@ static void pdo_close_file(FILE *fp) } //! Reading all pdo files -static void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header, - t_UmbrellaWindow *window, t_UmbrellaOptions *opt) +static void read_pdo_files(char** fn, int nfiles, t_UmbrellaHeader* header, t_UmbrellaWindow* window, t_UmbrellaOptions* opt) { - FILE *file; + FILE* file; real mintmp, maxtmp, done = 0.; int i; gmx_bool bPipeOpen; @@ -1940,8 +1967,9 @@ static void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header, file = open_pdo_pipe(fn[i], opt, &bPipeOpen); /*fgets(Buffer0,999,file); fprintf(stderr,"First line '%s'\n",Buffer0); */ - done = 100.0*(i+1)/nfiles; - fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done); fflush(stdout); + done = 100.0 * (i + 1) / nfiles; + fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done); + fflush(stdout); if (opt->verbose) { printf("\n"); @@ -1971,18 +1999,19 @@ static void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header, if (opt->bBoundsOnly) { printf("Found option -boundsonly, now exiting.\n"); - exit (0); + exit(0); } } /* store stepsize in profile */ - opt->dz = (opt->max-opt->min)/opt->bins; + opt->dz = (opt->max - opt->min) / opt->bins; /* Having min and max, we read in all files */ /* Loop over all files */ for (i = 0; i < nfiles; ++i) { - done = 100.0*(i+1)/nfiles; - fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done); fflush(stdout); + done = 100.0 * (i + 1) / nfiles; + fprintf(stdout, "\rOpening %s ... [%2.0f%%]", fn[i], done); + fflush(stdout); if (opt->verbose) { printf("\n"); @@ -1991,7 +2020,7 @@ static void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header, read_pdo_header(file, header, opt); /* load data into window */ read_pdo_data(file, header, i, window, opt, FALSE, nullptr, nullptr); - if ((window+i)->Ntot[0] == 0) + if ((window + i)->Ntot[0] == 0) { fprintf(stderr, "\nWARNING, no data points read from file %s (check -b option)\n", fn[i]); } @@ -2016,12 +2045,12 @@ static void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header, #define int2YN(a) (((a) == 0) ? ("N") : ("Y")) //! Read pull groups from a tpr file (including position, force const, geometry, number of groups) -static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_UmbrellaOptions *opt, t_coordselection *coordsel) +static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_UmbrellaOptions* opt, t_coordselection* coordsel) { - t_inputrec irInstance; - t_inputrec *ir = &irInstance; - t_state state; - static int first = 1; + t_inputrec irInstance; + t_inputrec* ir = &irInstance; + t_state state; + static int first = 1; /* printf("Reading %s \n",fn); */ read_tpx_state(fn, ir, &state, nullptr); @@ -2045,32 +2074,38 @@ static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_Umbrella snew(header->pcrd, header->npullcrds); for (int i = 0; i < ir->pull->ncoord; i++) { - header->pcrd[i].pull_type = ir->pull->coord[i].eType; - header->pcrd[i].geometry = ir->pull->coord[i].eGeom; - header->pcrd[i].ngroup = ir->pull->coord[i].ngroup; + header->pcrd[i].pull_type = ir->pull->coord[i].eType; + header->pcrd[i].geometry = ir->pull->coord[i].eGeom; + header->pcrd[i].ngroup = ir->pull->coord[i].ngroup; /* Angle type coordinates are handled fully in degrees in gmx wham. * The pull "distance" appears with a power of -2 in the force constant, * so we need to multiply with the internal units (radians for angle) * to user units (degrees for an angle) with the same power. */ - header->pcrd[i].k = ir->pull->coord[i].k/gmx::square(pull_conversion_factor_internal2userinput(&ir->pull->coord[i])); - header->pcrd[i].init_dist = ir->pull->coord[i].init; + header->pcrd[i].k = + ir->pull->coord[i].k + / gmx::square(pull_conversion_factor_internal2userinput(&ir->pull->coord[i])); + header->pcrd[i].init_dist = ir->pull->coord[i].init; copy_ivec(ir->pull->coord[i].dim, header->pcrd[i].dim); - header->pcrd[i].ndim = header->pcrd[i].dim[XX] + header->pcrd[i].dim[YY] + header->pcrd[i].dim[ZZ]; + header->pcrd[i].ndim = + header->pcrd[i].dim[XX] + header->pcrd[i].dim[YY] + header->pcrd[i].dim[ZZ]; - std::strcpy(header->pcrd[i].coord_unit, - pull_coordinate_units(&ir->pull->coord[i])); + std::strcpy(header->pcrd[i].coord_unit, pull_coordinate_units(&ir->pull->coord[i])); if (ir->efep != efepNO && ir->pull->coord[i].k != ir->pull->coord[i].kB) { - gmx_fatal(FARGS, "Seems like you did free-energy perturbation, and you perturbed the force constant." + gmx_fatal(FARGS, + "Seems like you did free-energy perturbation, and you perturbed the force " + "constant." " This is not supported.\n"); } if (coordsel && (coordsel->n != ir->pull->ncoord)) { - gmx_fatal(FARGS, "Found %d pull coordinates in %s, but %d columns in the respective line\n" - "coordinate selection file (option -is)\n", ir->pull->ncoord, fn, coordsel->n); + gmx_fatal(FARGS, + "Found %d pull coordinates in %s, but %d columns in the respective line\n" + "coordinate selection file (option -is)\n", + ir->pull->ncoord, fn, coordsel->n); } } @@ -2084,9 +2119,12 @@ static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_Umbrella { if (header->pcrd[i].pull_type != epullUMBRELLA) { - gmx_fatal(FARGS, "%s: Pull coordinate %d is of type \"%s\", expected \"umbrella\". Only umbrella coodinates can enter WHAM.\n" - "If you have umrella and non-umbrella coordinates, you can select the umbrella coordinates with gmx wham -is\n", - fn, i+1, epull_names[header->pcrd[i].pull_type]); + gmx_fatal(FARGS, + "%s: Pull coordinate %d is of type \"%s\", expected \"umbrella\". Only " + "umbrella coodinates can enter WHAM.\n" + "If you have umrella and non-umbrella coordinates, you can select the " + "umbrella coordinates with gmx wham -is\n", + fn, i + 1, epull_names[header->pcrd[i].pull_type]); } if (!geometryIsSet) { @@ -2096,32 +2134,43 @@ static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_Umbrella } if (geom != header->pcrd[i].geometry) { - gmx_fatal(FARGS, "%s: Your pull coordinates have different pull geometry (coordinate 1: %s, coordinate %d: %s)\n" - "If you want to use only some pull coordinates in WHAM, please select them with option gmx wham -is\n", - fn, epullg_names[geom], i+1, epullg_names[header->pcrd[i].geometry]); - } - if (thedim[XX] != header->pcrd[i].dim[XX] || thedim[YY] != header->pcrd[i].dim[YY] || thedim[ZZ] != header->pcrd[i].dim[ZZ]) - { - gmx_fatal(FARGS, "%s: Your pull coordinates have different pull dimensions (coordinate 1: %s %s %s, coordinate %d: %s %s %s)\n" - "If you want to use only some pull coordinates in WHAM, please select them with option gmx wham -is\n", - fn, int2YN(thedim[XX]), int2YN(thedim[YY]), int2YN(thedim[ZZ]), i+1, - int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), int2YN(header->pcrd[i].dim[ZZ])); + gmx_fatal(FARGS, + "%s: Your pull coordinates have different pull geometry (coordinate 1: " + "%s, coordinate %d: %s)\n" + "If you want to use only some pull coordinates in WHAM, please select " + "them with option gmx wham -is\n", + fn, epullg_names[geom], i + 1, epullg_names[header->pcrd[i].geometry]); + } + if (thedim[XX] != header->pcrd[i].dim[XX] || thedim[YY] != header->pcrd[i].dim[YY] + || thedim[ZZ] != header->pcrd[i].dim[ZZ]) + { + gmx_fatal(FARGS, + "%s: Your pull coordinates have different pull dimensions (coordinate 1: " + "%s %s %s, coordinate %d: %s %s %s)\n" + "If you want to use only some pull coordinates in WHAM, please select " + "them with option gmx wham -is\n", + fn, int2YN(thedim[XX]), int2YN(thedim[YY]), int2YN(thedim[ZZ]), i + 1, + int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), + int2YN(header->pcrd[i].dim[ZZ])); } if (header->pcrd[i].geometry == epullgCYL) { if (header->pcrd[i].dim[XX] || header->pcrd[i].dim[YY] || (!header->pcrd[i].dim[ZZ])) { - gmx_fatal(FARGS, "With pull geometry 'cylinder', expected pulling in Z direction only.\n" - "However, found dimensions [%s %s %s]\n", - int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), - int2YN(header->pcrd[i].dim[ZZ])); + gmx_fatal( + FARGS, + "With pull geometry 'cylinder', expected pulling in Z direction only.\n" + "However, found dimensions [%s %s %s]\n", + int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), + int2YN(header->pcrd[i].dim[ZZ])); } } if (header->pcrd[i].k <= 0.0) { - gmx_fatal(FARGS, "%s: Pull coordinate %d has force constant of of %g.\n" + gmx_fatal(FARGS, + "%s: Pull coordinate %d has force constant of of %g.\n" "That doesn't seem to be an Umbrella tpr.\n", - fn, i+1, header->pcrd[i].k); + fn, i + 1, header->pcrd[i].k); } } } @@ -2136,16 +2185,18 @@ static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_Umbrella maxlen = (lentmp > maxlen) ? lentmp : maxlen; } char fmt[STRLEN]; - sprintf(fmt, "\tGeometry %%-%ds k = %%-8g position = %%-8g dimensions [%%s %%s %%s] (%%d dimensions). Used: %%s\n", - maxlen+1); + sprintf(fmt, + "\tGeometry %%-%ds k = %%-8g position = %%-8g dimensions [%%s %%s %%s] (%%d " + "dimensions). Used: %%s\n", + maxlen + 1); for (int i = 0; i < ir->pull->ncoord; i++) { bool use = (coordsel == nullptr || coordsel->bUse[i]); - printf(fmt, - epullg_names[header->pcrd[i].geometry], header->pcrd[i].k, header->pcrd[i].init_dist, - int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), int2YN(header->pcrd[i].dim[ZZ]), - header->pcrd[i].ndim, use ? "Yes" : "No"); - printf("\tPull group coordinates of %d groups expected in pullx files.\n", ir->pull->bPrintCOM ? header->pcrd[i].ngroup : 0); + printf(fmt, epullg_names[header->pcrd[i].geometry], header->pcrd[i].k, header->pcrd[i].init_dist, + int2YN(header->pcrd[i].dim[XX]), int2YN(header->pcrd[i].dim[YY]), + int2YN(header->pcrd[i].dim[ZZ]), header->pcrd[i].ndim, use ? "Yes" : "No"); + printf("\tPull group coordinates of %d groups expected in pullx files.\n", + ir->pull->bPrintCOM ? header->pcrd[i].ngroup : 0); } printf("\tReference value of the coordinate%s expected in pullx files.\n", header->bPrintRefValue ? "" : " not"); @@ -2159,20 +2210,23 @@ static void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_Umbrella } //! Read pullx.xvg or pullf.xvg -static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, - t_UmbrellaWindow * window, - t_UmbrellaOptions *opt, - gmx_bool bGetMinMax, real *mintmp, real *maxtmp, - t_coordselection *coordsel) +static void read_pull_xf(const char* fn, + t_UmbrellaHeader* header, + t_UmbrellaWindow* window, + t_UmbrellaOptions* opt, + gmx_bool bGetMinMax, + real* mintmp, + real* maxtmp, + t_coordselection* coordsel) { - double **y = nullptr, pos = 0., t, force, time0 = 0., dt; + double ** y = nullptr, pos = 0., t, force, time0 = 0., dt; int ny, nt, bins, ibin, i, g, gUsed, dstep = 1; int nColExpect, ntot, column; real min, max, minfound = 1e20, maxfound = -1e20; gmx_bool dt_ok, timeok; - const char *quantity; + const char* quantity; const int blocklen = 4096; - int *lennow = nullptr; + int* lennow = nullptr; static gmx_bool bFirst = TRUE; /* @@ -2189,14 +2243,17 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, if (header->bPrintComp && opt->bPullx) { - gmx_fatal(FARGS, "gmx wham cannot read pullx files if the components of the coordinate was written\n" - "(mdp option pull-print-components). Provide the pull force files instead (with option -if).\n"); + gmx_fatal( + FARGS, + "gmx wham cannot read pullx files if the components of the coordinate was written\n" + "(mdp option pull-print-components). Provide the pull force files instead (with " + "option -if).\n"); } int *nColThisCrd, *nColCOMCrd, *nColRefCrd; snew(nColThisCrd, header->npullcrds); - snew(nColCOMCrd, header->npullcrds); - snew(nColRefCrd, header->npullcrds); + snew(nColCOMCrd, header->npullcrds); + snew(nColRefCrd, header->npullcrds); if (!opt->bPullx) { @@ -2213,9 +2270,9 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, /* pullx reading. Note explanation above. */ for (g = 0; g < header->npullcrds; g++) { - nColRefCrd[g] = (header->bPrintRefValue ? 1 : 0); - nColCOMCrd[g] = (header->bPrintCOM ? header->pcrd[g].ndim*header->pcrd[g].ngroup : 0); - nColThisCrd[g] = 1 + nColCOMCrd[g] + nColRefCrd[g]; + nColRefCrd[g] = (header->bPrintRefValue ? 1 : 0); + nColCOMCrd[g] = (header->bPrintCOM ? header->pcrd[g].ndim * header->pcrd[g].ngroup : 0); + nColThisCrd[g] = 1 + nColCOMCrd[g] + nColRefCrd[g]; } } @@ -2229,7 +2286,7 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, nt = read_xvg(fn, &y, &ny); /* Check consistency */ - quantity = opt->bPullx ? "position" : "force"; + quantity = opt->bPullx ? "position" : "force"; if (nt < 1) { gmx_fatal(FARGS, "Empty pull %s file %s\n", quantity, fn); @@ -2239,7 +2296,7 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, printf("\nReading pull %s file %s, expecting %d columns:\n", quantity, fn, nColExpect); for (i = 0; i < header->npullcrds; i++) { - printf("\tColumns for pull coordinate %d\n", i+1); + printf("\tColumns for pull coordinate %d\n", i + 1); printf("\t\treaction coordinate: %d\n" "\t\tcenter-of-mass of groups: %d\n" "\t\treference position column: %s\n", @@ -2250,8 +2307,10 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, } if (nColExpect != ny) { - gmx_fatal(FARGS, "Expected %d columns (including time column) in %s, but found %d." - " Maybe you confused options -if and -ix ?", nColExpect, fn, ny); + gmx_fatal(FARGS, + "Expected %d columns (including time column) in %s, but found %d." + " Maybe you confused options -if and -ix ?", + nColExpect, fn, ny); } if (!bGetMinMax) @@ -2262,7 +2321,7 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, max = opt->max; if (nt > 1) { - window->dt = y[0][1]-y[0][0]; + window->dt = y[0][1] - y[0][0]; } else if (opt->nBootStrap && opt->tauBootStrap != 0.0) { @@ -2275,7 +2334,9 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, /* Use only groups selected with option -is file */ if (header->npullcrds != coordsel->n) { - gmx_fatal(FARGS, "tpr file contains %d pull groups, but expected %d from group selection file\n", + gmx_fatal(FARGS, + "tpr file contains %d pull groups, but expected %d from group selection " + "file\n", header->npullcrds, coordsel->n); } window->nPull = coordsel->nUse; @@ -2286,13 +2347,13 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, } window->nBin = bins; - snew(window->Histo, window->nPull); - snew(window->z, window->nPull); - snew(window->k, window->nPull); - snew(window->pos, window->nPull); - snew(window->N, window->nPull); - snew(window->Ntot, window->nPull); - snew(window->g, window->nPull); + snew(window->Histo, window->nPull); + snew(window->z, window->nPull); + snew(window->k, window->nPull); + snew(window->pos, window->nPull); + snew(window->N, window->nPull); + snew(window->Ntot, window->nPull); + snew(window->g, window->nPull); snew(window->bsWeight, window->nPull); window->bContrib = nullptr; @@ -2308,11 +2369,11 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, for (g = 0; g < window->nPull; ++g) { - window->z [g] = 1; - window->bsWeight [g] = 1.; - window->N [g] = 0; - window->Ntot [g] = 0; - window->g [g] = 1.; + window->z[g] = 1; + window->bsWeight[g] = 1.; + window->N[g] = 0; + window->Ntot[g] = 0; + window->g[g] = 1.; snew(window->Histo[g], bins); if (opt->bCalcTauInt) @@ -2329,23 +2390,23 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, { continue; } - window->k [gUsed] = header->pcrd[g].k; + window->k[gUsed] = header->pcrd[g].k; window->pos[gUsed] = header->pcrd[g].init_dist; gUsed++; } } else - { /* only determine min and max */ + { /* only determine min and max */ minfound = 1e20; maxfound = -1e20; - min = max = bins = 0; /* Get rid of warnings */ + min = max = bins = 0; /* Get rid of warnings */ } for (i = 0; i < nt; i++) { /* Do you want that time frame? */ - t = 1.0/1000*( gmx::roundToInt64((y[0][i]*1000))); /* round time to fs */ + t = 1.0 / 1000 * (gmx::roundToInt64((y[0][i] * 1000))); /* round time to fs */ /* get time step of pdo file and get dstep from opt->dt */ if (i == 0) @@ -2354,10 +2415,10 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, } else if (i == 1) { - dt = t-time0; + dt = t - time0; if (opt->dt > 0.0) { - dstep = gmx::roundToInt(opt->dt/dt); + dstep = gmx::roundToInt(opt->dt / dt); if (dstep == 0) { dstep = 1; @@ -2365,11 +2426,11 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, } if (!bGetMinMax) { - window->dt = dt*dstep; + window->dt = dt * dstep; } } - dt_ok = (i%dstep == 0); + dt_ok = (i % dstep == 0); timeok = (dt_ok && t >= opt->tmin && t <= opt->tmax); /*if (opt->verbose) printf(" time = %f, (tmin,tmax)=(%e,%e), dt_ok=%d timeok=%d\n", @@ -2381,7 +2442,7 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, * if coordsel != NULL: * only groups with coordsel.bUse[g]==TRUE are stored. gUsed is not always equal g */ - gUsed = -1; + gUsed = -1; for (g = 0; g < header->npullcrds; ++g) { /* was this group selected for application in WHAM? */ @@ -2394,8 +2455,8 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, if (opt->bPullf) { /* y has 1 time column y[0] and one column per force y[1],...,y[nCrds] */ - force = y[g+1][i]; - pos = -force/header->pcrd[g].k + header->pcrd[g].init_dist; + force = y[g + 1][i]; + pos = -force / header->pcrd[g].k + header->pcrd[g].init_dist; } else { @@ -2407,7 +2468,7 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, { column += nColThisCrd[j]; } - pos = y[column][i]; + pos = y[column][i]; } /* printf("crd %d dpos %f poseq %f pos %f \n",g,dpos,poseq,pos); */ @@ -2426,7 +2487,9 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, { if (gUsed >= window->nPull) { - gmx_fatal(FARGS, "gUsed too large (%d, nPull=%d). This error should have been caught before.\n", + gmx_fatal(FARGS, + "gUsed too large (%d, nPull=%d). This error should have been " + "caught before.\n", gUsed, window->nPull); } @@ -2443,22 +2506,16 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, window->ztime[gUsed][ntot] = pos; } - ibin = static_cast (std::floor((pos-min)/(max-min)*bins)); + ibin = static_cast(std::floor((pos - min) / (max - min) * bins)); if (opt->bCycl) { if (ibin < 0) { - while ( (ibin += bins) < 0) - { - ; - } + while ((ibin += bins) < 0) {} } else if (ibin >= bins) { - while ( (ibin -= bins) >= bins) - { - ; - } + while ((ibin -= bins) >= bins) {} } } if (ibin >= 0 && ibin < bins) @@ -2493,9 +2550,12 @@ static void read_pull_xf(const char *fn, t_UmbrellaHeader * header, } //! read pullf-files.dat or pullx-files.dat and tpr-files.dat -static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, - t_UmbrellaHeader* header, - t_UmbrellaWindow *window, t_UmbrellaOptions *opt) +static void read_tpr_pullxf_files(char** fnTprs, + char** fnPull, + int nfiles, + t_UmbrellaHeader* header, + t_UmbrellaWindow* window, + t_UmbrellaOptions* opt) { int i; real mintmp, maxtmp; @@ -2517,7 +2577,8 @@ static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, read_tpr_header(fnTprs[i], header, opt, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr); if (whaminFileType(fnPull[i]) != whamin_pullxf) { - gmx_fatal(FARGS, "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i); + gmx_fatal(FARGS, + "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i); } read_pull_xf(fnPull[i], header, nullptr, opt, TRUE, &mintmp, &maxtmp, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr); @@ -2534,11 +2595,11 @@ static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, if (opt->bBoundsOnly) { printf("Found option -boundsonly, now exiting.\n"); - exit (0); + exit(0); } } /* store stepsize in profile */ - opt->dz = (opt->max-opt->min)/opt->bins; + opt->dz = (opt->max - opt->min) / opt->bins; bool foundData = false; for (i = 0; i < nfiles; i++) @@ -2550,9 +2611,10 @@ static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, read_tpr_header(fnTprs[i], header, opt, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr); if (whaminFileType(fnPull[i]) != whamin_pullxf) { - gmx_fatal(FARGS, "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i); + gmx_fatal(FARGS, + "Expected the %d'th file in input file to be a xvg (pullx/pullf) file\n", i); } - read_pull_xf(fnPull[i], header, window+i, opt, FALSE, nullptr, nullptr, + read_pull_xf(fnPull[i], header, window + i, opt, FALSE, nullptr, nullptr, (opt->nCoordsel > 0) ? &opt->coordsel[i] : nullptr); if (window[i].Ntot[0] == 0) { @@ -2565,7 +2627,9 @@ static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, } if (!foundData) { - gmx_fatal(FARGS, "No data points were found in pullf/pullx files. Maybe you need to specify the -b option?\n"); + gmx_fatal(FARGS, + "No data points were found in pullf/pullx files. Maybe you need to specify the " + "-b option?\n"); } for (i = 0; i < nfiles; i++) @@ -2582,10 +2646,10 @@ static void read_tpr_pullxf_files(char **fnTprs, char **fnPull, int nfiles, * Note: Here we consider tau[int] := int_0^inf ACF(t) as the integrated autocorrelation times. * The factor `g := 1 + 2*tau[int]` subsequently enters the uncertainty. */ -static void readIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwins, const char* fn) +static void readIntegratedAutocorrelationTimes(t_UmbrellaWindow* window, int nwins, const char* fn) { int nlines, ny, i, ig; - double **iact; + double** iact; printf("Readging Integrated autocorrelation times from %s ...\n", fn); nlines = read_xvg(fn, &iact, &ny); @@ -2598,14 +2662,15 @@ static void readIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi { if (window[i].nPull != ny) { - gmx_fatal(FARGS, "You are providing autocorrelation times with option -iiact and the\n" + gmx_fatal(FARGS, + "You are providing autocorrelation times with option -iiact and the\n" "number of pull groups is different in different simulations. That is not\n" "supported yet. Sorry.\n"); } for (ig = 0; ig < window[i].nPull; ig++) { /* compare Kumar et al, J Comp Chem 13, 1011-1021 (1992) */ - window[i].g[ig] = 1+2*iact[ig][i]/window[i].dt; + window[i].g[ig] = 1 + 2 * iact[ig][i] / window[i].dt; if (iact[ig][i] <= 0.0) { @@ -2625,17 +2690,17 @@ static void readIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi * If opt->bAllowReduceIact==FALSE, the ACTs are never reduced, only increased * by the smoothing */ -static void smoothIact(t_UmbrellaWindow *window, int nwins, t_UmbrellaOptions *opt) +static void smoothIact(t_UmbrellaWindow* window, int nwins, t_UmbrellaOptions* opt) { int i, ig, j, jg; double pos, dpos2, siglim, siglim2, gaufact, invtwosig2, w, weight, tausm; /* only evaluate within +- 3sigma of the Gausian */ - siglim = 3.0*opt->sigSmoothIact; + siglim = 3.0 * opt->sigSmoothIact; siglim2 = gmx::square(siglim); /* pre-factor of Gaussian */ - gaufact = 1.0/(std::sqrt(2*M_PI)*opt->sigSmoothIact); - invtwosig2 = 0.5/gmx::square(opt->sigSmoothIact); + gaufact = 1.0 / (std::sqrt(2 * M_PI) * opt->sigSmoothIact); + invtwosig2 = 0.5 / gmx::square(opt->sigSmoothIact); for (i = 0; i < nwins; i++) { @@ -2649,12 +2714,12 @@ static void smoothIact(t_UmbrellaWindow *window, int nwins, t_UmbrellaOptions *o { for (jg = 0; jg < window[j].nPull; jg++) { - dpos2 = gmx::square(window[j].pos[jg]-pos); + dpos2 = gmx::square(window[j].pos[jg] - pos); if (dpos2 < siglim2) { - w = gaufact*std::exp(-dpos2*invtwosig2); + w = gaufact * std::exp(-dpos2 * invtwosig2); weight += w; - tausm += w*window[j].tau[jg]; + tausm += w * window[j].tau[jg]; /*printf("Weight %g dpos2=%g pos=%g gaufact=%g invtwosig2=%g\n", w,dpos2,pos,gaufact,invtwosig2); */ } @@ -2669,7 +2734,7 @@ static void smoothIact(t_UmbrellaWindow *window, int nwins, t_UmbrellaOptions *o { window[i].tausmooth[ig] = window[i].tau[ig]; } - window[i].g[ig] = 1+2*tausm/window[i].dt; + window[i].g[ig] = 1 + 2 * tausm / window[i].dt; } } } @@ -2679,8 +2744,11 @@ static void smoothIact(t_UmbrellaWindow *window, int nwins, t_UmbrellaOptions *o /*! \brief Try to compute the autocorrelation time for each umbrealla window */ -static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwins, - t_UmbrellaOptions *opt, const char *fn, const char *xlabel) +static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow* window, + int nwins, + t_UmbrellaOptions* opt, + const char* fn, + const char* xlabel) { int i, ig, ncorr, ntot, j, k, *count, restart; real *corr, c0, dt, tmp; @@ -2696,23 +2764,26 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi printf("\n"); for (i = 0; i < nwins; i++) { - fprintf(stdout, "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...", 100.*(i+1)/nwins); + fprintf(stdout, "\rEstimating integrated autocorrelation times ... [%2.0f%%] ...", + 100. * (i + 1) / nwins); fflush(stdout); ntot = window[i].Ntot[0]; /* using half the maximum time as length of autocorrelation function */ - ncorr = ntot/2; + ncorr = ntot / 2; if (ntot < 10) { - gmx_fatal(FARGS, "Tryig to estimtate autocorrelation time from only %d" - " points. Provide more pull data!", ntot); + gmx_fatal(FARGS, + "Tryig to estimtate autocorrelation time from only %d" + " points. Provide more pull data!", + ntot); } snew(corr, ncorr); /* snew(corrSq,ncorr); */ snew(count, ncorr); dt = window[i].dt; snew(window[i].tau, window[i].nPull); - restart = gmx::roundToInt(opt->acTrestart/dt); + restart = gmx::roundToInt(opt->acTrestart / dt); if (restart == 0) { restart = 1; @@ -2722,8 +2793,10 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi { if (ntot != window[i].Ntot[ig]) { - gmx_fatal(FARGS, "Encountered different nr of frames in different pull groups.\n" - "That should not happen. (%d and %d)\n", ntot, window[i].Ntot[ig]); + gmx_fatal(FARGS, + "Encountered different nr of frames in different pull groups.\n" + "That should not happen. (%d and %d)\n", + ntot, window[i].Ntot[ig]); } ztime = window[i].ztime[ig]; @@ -2740,10 +2813,10 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi } for (j = 0; (j < ntot); j += restart) { - for (k = 0; (k < ncorr) && (j+k < ntot); k++) + for (k = 0; (k < ncorr) && (j + k < ntot); k++) { - tmp = (ztime[j]-av)*(ztime[j+k]-av); - corr [k] += tmp; + tmp = (ztime[j] - av) * (ztime[j + k] - av); + corr[k] += tmp; /* corrSq[k] += tmp*tmp; */ count[k]++; } @@ -2752,12 +2825,12 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi for (k = 0; (k < ncorr); k++) { /* count probably = (ncorr-k+(restart-1))/restart; */ - corr[k] = corr[k]/count[k]; + corr[k] = corr[k] / count[k]; /* variance of autocorrelation function */ /* corrSq[k]=corrSq[k]/count[k]; */ } /* normalize such that corr[0] == 0 */ - c0 = 1./corr[0]; + c0 = 1. / corr[0]; for (k = 0; (k < ncorr); k++) { corr[k] *= c0; @@ -2769,13 +2842,13 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi { for (k = 0; (k < ncorr); k++) { - fprintf(fpcorr, "%g %g\n", k*dt, corr[k]); + fprintf(fpcorr, "%g %g\n", k * dt, corr[k]); } fprintf(fpcorr, "%s\n", output_env_get_print_xvgr_codes(opt->oenv) ? "&" : ""); } /* esimate integrated correlation time, fitting is too unstable */ - tausteps = 0.5*corr[0]; + tausteps = 0.5 * corr[0]; /* consider corr below WHAM_AC_ZERO_LIMIT as noise */ for (j = 1; (j < ncorr) && (corr[j] > WHAM_AC_ZERO_LIMIT); j++) { @@ -2784,8 +2857,8 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi /* g = 1+2*tau, see. Ferrenberg/Swendsen, PRL 63:1195 (1989) or Kumar et al, eq. 28 ff. */ - window[i].tau[ig] = tausteps*dt; - window[i].g[ig] = 1+2*tausteps; + window[i].tau[ig] = tausteps * dt; + window[i].g[ig] = 1 + 2 * tausteps; /* printf("win %d, group %d, estimated correlation time = %g ps\n",i,ig,window[i].tau[ig]); */ } /* ig loop */ sfree(corr); @@ -2822,7 +2895,8 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi } if (opt->sigSmoothIact > 0.0) { - printf("Smoothing autocorrelation times along reaction coordinate with Gaussian of sig = %g\n", + printf("Smoothing autocorrelation times along reaction coordinate with Gaussian of sig = " + "%g\n", opt->sigSmoothIact); /* smooth IACT along reaction coordinate and overwrite g=1+2tau */ smoothIact(window, nwins, opt); @@ -2847,7 +2921,7 @@ static void calcIntegratedAutocorrelationTimes(t_UmbrellaWindow *window, int nwi /*! \brief * compute average and sigma of each umbrella histogram */ -static void averageSigma(t_UmbrellaWindow *window, int nwins) +static void averageSigma(t_UmbrellaWindow* window, int nwins) { int i, ig, ntot, k; real av, sum2, sig, diff, *ztime, nSamplesIndep; @@ -2868,10 +2942,10 @@ static void averageSigma(t_UmbrellaWindow *window, int nwins) av /= ntot; for (k = 0, sum2 = 0.; k < ntot; k++) { - diff = ztime[k]-av; - sum2 += diff*diff; + diff = ztime[k] - av; + sum2 += diff * diff; } - sig = std::sqrt(sum2/ntot); + sig = std::sqrt(sum2 / ntot); window[i].aver[ig] = av; /* Note: This estimate for sigma is biased from the limited sampling. @@ -2880,8 +2954,8 @@ static void averageSigma(t_UmbrellaWindow *window, int nwins) */ if (window[i].tau) { - nSamplesIndep = window[i].N[ig]/(window[i].tau[ig]/window[i].dt); - window[i].sigma[ig] = sig * nSamplesIndep/(nSamplesIndep-1); + nSamplesIndep = window[i].N[ig] / (window[i].tau[ig] / window[i].dt); + window[i].sigma[ig] = sig * nSamplesIndep / (nSamplesIndep - 1); } else { @@ -2896,15 +2970,15 @@ static void averageSigma(t_UmbrellaWindow *window, int nwins) /*! \brief * Use histograms to compute average force on pull group. */ -static void computeAverageForce(t_UmbrellaWindow *window, int nWindows, t_UmbrellaOptions *opt) +static void computeAverageForce(t_UmbrellaWindow* window, int nWindows, t_UmbrellaOptions* opt) { int i, j, bins = opt->bins, k; double dz, min = opt->min, max = opt->max, displAv, temp, distance, ztot, ztot_half, w, weight; double posmirrored; - dz = (max-min)/bins; - ztot = opt->max-min; - ztot_half = ztot/2; + dz = (max - min) / bins; + ztot = opt->max - min; + ztot_half = ztot / 2; /* Compute average displacement from histograms */ for (j = 0; j < nWindows; ++j) @@ -2916,11 +2990,11 @@ static void computeAverageForce(t_UmbrellaWindow *window, int nWindows, t_Umbrel weight = 0.0; for (i = 0; i < opt->bins; ++i) { - temp = (1.0*i+0.5)*dz+min; + temp = (1.0 * i + 0.5) * dz + min; distance = temp - window[j].pos[k]; if (opt->bCycl) - { /* in cyclic wham: */ - if (distance > ztot_half) /* |distance| < ztot_half */ + { /* in cyclic wham: */ + if (distance > ztot_half) /* |distance| < ztot_half */ { distance -= ztot; } @@ -2929,26 +3003,26 @@ static void computeAverageForce(t_UmbrellaWindow *window, int nWindows, t_Umbrel distance += ztot; } } - w = window[j].Histo[k][i]/window[j].g[k]; - displAv += w*distance; - weight += w; + w = window[j].Histo[k][i] / window[j].g[k]; + displAv += w * distance; + weight += w; /* Are we near min or max? We are getting wrong forces from the histgrams since the histograms are zero outside [min,max). Therefore, assume that the position on the other side of the histomgram center is equally likely. */ if (!opt->bCycl) { - posmirrored = window[j].pos[k]-distance; + posmirrored = window[j].pos[k] - distance; if (posmirrored >= max || posmirrored < min) { - displAv += -w*distance; - weight += w; + displAv += -w * distance; + weight += w; } } } - displAv /= weight; + displAv /= weight; /* average force from average displacement */ - window[j].forceAv[k] = displAv*window[j].k[k]; + window[j].forceAv[k] = displAv * window[j].k[k]; /* sigma from average square displacement */ /* window[j].sigma [k] = sqrt(displAv2); */ /* printf("Win %d, sigma = %f\n",j,sqrt(displAv2)); */ @@ -2959,8 +3033,7 @@ static void computeAverageForce(t_UmbrellaWindow *window, int nWindows, t_Umbrel /*! \brief * Check if the complete reaction coordinate is covered by the histograms */ -static void checkReactionCoordinateCovered(t_UmbrellaWindow *window, int nwins, - t_UmbrellaOptions *opt) +static void checkReactionCoordinateCovered(t_UmbrellaWindow* window, int nwins, t_UmbrellaOptions* opt) { int i, ig, j, bins = opt->bins; bool bBoundary; @@ -2976,19 +3049,21 @@ static void checkReactionCoordinateCovered(t_UmbrellaWindow *window, int nwins, count[j] += window[i].Histo[ig][j]; } } - avcount += 1.0*count[j]; + avcount += 1.0 * count[j]; } avcount /= bins; for (j = 0; j < bins; ++j) { - relcount = count[j]/avcount; - z = (j+0.5)*opt->dz+opt->min; - bBoundary = jbins/20; + relcount = count[j] / avcount; + z = (j + 0.5) * opt->dz + opt->min; + bBoundary = j < bins / 20 || (bins - j) > bins / 20; /* check for bins with no data */ if (count[j] == 0) { - fprintf(stderr, "\nWARNING, no data point in bin %d (z=%g) !\n" - "You may not get a reasonable profile. Check your histograms!\n", j, z); + fprintf(stderr, + "\nWARNING, no data point in bin %d (z=%g) !\n" + "You may not get a reasonable profile. Check your histograms!\n", + j, z); } /* and check for poor sampling */ else if (relcount < 0.005 && !bBoundary) @@ -3003,13 +3078,13 @@ static void checkReactionCoordinateCovered(t_UmbrellaWindow *window, int nwins, * * This speeds up the convergence by roughly a factor of 2 */ -static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_UmbrellaOptions *opt, const char *xlabel) +static void guessPotByIntegration(t_UmbrellaWindow* window, int nWindows, t_UmbrellaOptions* opt, const char* xlabel) { int i, j, ig, bins = opt->bins, nHist, winmin, groupmin; double dz, min = opt->min, *pot, pos, hispos, dist, diff, fAv, distmin, *f; - FILE *fp; + FILE* fp; - dz = (opt->max-min)/bins; + dz = (opt->max - min) / bins; printf("Getting initial potential by integration.\n"); @@ -3022,7 +3097,7 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr snew(f, bins); for (j = 0; j < opt->bins; ++j) { - pos = (1.0*j+0.5)*dz+min; + pos = (1.0 * j + 0.5) * dz + min; nHist = 0; fAv = 0.; distmin = 1e20; @@ -3032,9 +3107,9 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr for (ig = 0; ig < window[i].nPull; ig++) { hispos = window[i].pos[ig]; - dist = std::abs(hispos-pos); + dist = std::abs(hispos - pos); /* average force within bin */ - if (dist < dz/2) + if (dist < dz / 2) { nHist++; fAv += window[i].forceAv[ig]; @@ -3051,7 +3126,7 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr /* if no histogram found in this bin, use closest histogram */ if (nHist > 0) { - fAv = fAv/nHist; + fAv = fAv / nHist; } else { @@ -3061,16 +3136,16 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr } for (j = 1; j < opt->bins; ++j) { - pot[j] = pot[j-1] - 0.5*dz*(f[j-1]+f[j]); + pot[j] = pot[j - 1] - 0.5 * dz * (f[j - 1] + f[j]); } /* cyclic wham: linearly correct possible offset */ if (opt->bCycl) { - diff = (pot[bins-1]-pot[0])/(bins-1); + diff = (pot[bins - 1] - pot[0]) / (bins - 1); for (j = 1; j < opt->bins; ++j) { - pot[j] -= j*diff; + pot[j] -= j * diff; } } if (opt->verbose) @@ -3078,7 +3153,7 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr fp = xvgropen("pmfintegrated.xvg", "PMF from force integration", xlabel, "PMF (kJ/mol)", opt->oenv); for (j = 0; j < opt->bins; ++j) { - fprintf(fp, "%g %g\n", (j+0.5)*dz+opt->min, pot[j]); + fprintf(fp, "%g %g\n", (j + 0.5) * dz + opt->min, pot[j]); } xvgrclose(fp); printf("verbose mode: wrote %s with PMF from interated forces\n", "pmfintegrated.xvg"); @@ -3090,7 +3165,7 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr */ for (j = 0; j < opt->bins; ++j) { - pot[j] = std::exp(-pot[j]/(BOLTZ*opt->Temperature)); + pot[j] = std::exp(-pot[j] / (BOLTZ * opt->Temperature)); } calc_z(pot, window, nWindows, opt, TRUE); @@ -3099,7 +3174,7 @@ static void guessPotByIntegration(t_UmbrellaWindow *window, int nWindows, t_Umbr } //! Count number of words in an line -static int wordcount(char *ptr) +static int wordcount(char* ptr) { int i, n, is[2]; int cur = 0; @@ -3113,11 +3188,11 @@ static int wordcount(char *ptr) for (i = 0; (ptr[i] != '\0'); i++) { is[cur] = isspace(ptr[i]); - if ((i > 0) && (is[cur] && !is[1-cur])) + if ((i > 0) && (is[cur] && !is[1 - cur])) { n++; } - cur = 1-cur; + cur = 1 - cur; } return n; } @@ -3126,9 +3201,9 @@ static int wordcount(char *ptr) * * TO DO: ptr=fgets(...) is never freed (small memory leak) */ -static void readPullCoordSelection(t_UmbrellaOptions *opt, char **fnTpr, int nTpr) +static void readPullCoordSelection(t_UmbrellaOptions* opt, char** fnTpr, int nTpr) { - FILE *fp; + FILE* fp; int i, iline, n, len = STRLEN, temp; char *ptr = nullptr, *tmpbuf = nullptr; char fmt[1024], fmtign[1024]; @@ -3140,7 +3215,7 @@ static void readPullCoordSelection(t_UmbrellaOptions *opt, char **fnTpr, int nTp snew(tmpbuf, len); sizenow = 0; iline = 0; - while ( (ptr = fgets3(fp, tmpbuf, &len)) != nullptr) + while ((ptr = fgets3(fp, tmpbuf, &len)) != nullptr) { trim(ptr); n = wordcount(ptr); @@ -3174,19 +3249,19 @@ static void readPullCoordSelection(t_UmbrellaOptions *opt, char **fnTpr, int nTp opt->nCoordsel = iline; if (nTpr != opt->nCoordsel) { - gmx_fatal(FARGS, "Found %d tpr files but %d lines in %s\n", nTpr, opt->nCoordsel, - opt->fnCoordSel); + gmx_fatal(FARGS, "Found %d tpr files but %d lines in %s\n", nTpr, opt->nCoordsel, opt->fnCoordSel); } printf("\nUse only these pull coordinates:\n"); for (iline = 0; iline < nTpr; iline++) { - printf("%s (%d of %d coordinates):", fnTpr[iline], opt->coordsel[iline].nUse, opt->coordsel[iline].n); + printf("%s (%d of %d coordinates):", fnTpr[iline], opt->coordsel[iline].nUse, + opt->coordsel[iline].n); for (i = 0; i < opt->coordsel[iline].n; i++) { if (opt->coordsel[iline].bUse[i]) { - printf(" %d", i+1); + printf(" %d", i + 1); } } printf("\n"); @@ -3197,15 +3272,15 @@ static void readPullCoordSelection(t_UmbrellaOptions *opt, char **fnTpr, int nTp } //! Boolean XOR -#define WHAMBOOLXOR(a, b) ( ((!(a)) && (b)) || ((a) && (!(b)))) +#define WHAMBOOLXOR(a, b) (((!(a)) && (b)) || ((a) && (!(b)))) //! Number of elements in fnm (used for command line parsing) #define NFILE asize(fnm) //! The main gmx wham routine -int gmx_wham(int argc, char *argv[]) +int gmx_wham(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] is an analysis program that implements the Weighted", "Histogram Analysis Method (WHAM). It is intended to analyze", "output files generated by umbrella sampling simulations to ", @@ -3227,11 +3302,12 @@ int gmx_wham(int argc, char *argv[]) " provides the pull force output file names ([TT]pullf.xvg[tt]) with option [TT]-if[tt].", " From the pull force the position in the umbrella potential is", " computed. This does not work with tabulated umbrella potentials.", - "* With option [TT]-ip[tt], the user provides file names of (gzipped) [REF].pdo[ref] files, i.e.", + "* With option [TT]-ip[tt], the user provides file names of (gzipped) [REF].pdo[ref] ", + " files, i.e.", " the GROMACS 3.3 umbrella output files. If you have some unusual", " reaction coordinate you may also generate your own [REF].pdo[ref] files and", - " feed them with the [TT]-ip[tt] option into to [THISMODULE]. The [REF].pdo[ref] file header", - " must be similar to the following::", + " feed them with the [TT]-ip[tt] option into to [THISMODULE]. The [REF].pdo[ref] file ", + " header must be similar to the following::", "", " # UMBRELLA 3.0", " # Component selection: 0 0 1", @@ -3247,12 +3323,17 @@ int gmx_wham(int argc, char *argv[]) " a data column for each pull group follows (i.e. the displacement", " with respect to the umbrella center). Up to four pull groups are possible ", " per [REF].pdo[ref] file at present.[PAR]", - "By default, all pull coordinates found in all pullx/pullf files are used in WHAM. If only ", - "some of the pull coordinates should be used, a pull coordinate selection file (option [TT]-is[tt]) can ", + "By default, all pull coordinates found in all pullx/pullf files are used in WHAM. If ", + "only ", + "some of the pull coordinates should be used, a pull coordinate selection file (option ", + "[TT]-is[tt]) can ", "be provided. The selection file must contain one line for each tpr file in tpr-files.dat.", - "Each of these lines must contain one digit (0 or 1) for each pull coordinate in the tpr file. ", - "Here, 1 indicates that the pull coordinate is used in WHAM, and 0 means it is omitted. Example:", - "If you have three tpr files, each containing 4 pull coordinates, but only pull coordinates 1 and 2 should be ", + "Each of these lines must contain one digit (0 or 1) for each pull coordinate in the tpr ", + "file. ", + "Here, 1 indicates that the pull coordinate is used in WHAM, and 0 means it is omitted. ", + "Example:", + "If you have three tpr files, each containing 4 pull coordinates, but only pull ", + "coordinates 1 and 2 should be ", "used, coordsel.dat looks like this::", "", " 1 1 0 0", @@ -3266,7 +3347,8 @@ int gmx_wham(int argc, char *argv[]) "", "Always check whether the histograms sufficiently overlap.[PAR]", "The umbrella potential is assumed to be harmonic and the force constants are ", - "read from the [REF].tpr[ref] or [REF].pdo[ref] files. If a non-harmonic umbrella force was applied ", + "read from the [REF].tpr[ref] or [REF].pdo[ref] files. If a non-harmonic umbrella force ", + "was applied ", "a tabulated potential can be provided with [TT]-tab[tt].", "", "WHAM options", @@ -3318,7 +3400,8 @@ int gmx_wham(int argc, char *argv[]) "less robust) method such as fitting to a double exponential, you can ", "compute the IACTs with [gmx-analyze] and provide them to [THISMODULE] with the file ", "[TT]iact-in.dat[tt] (option [TT]-iiact[tt]), which should contain one line per ", - "input file ([REF].pdo[ref] or pullx/f file) and one column per pull coordinate in the respective file.", + "input file ([REF].pdo[ref] or pullx/f file) and one column per pull coordinate in the ", + "respective file.", "", "Error analysis", "^^^^^^^^^^^^^^", @@ -3349,7 +3432,8 @@ int gmx_wham(int argc, char *argv[]) " and properly autocorrelated. The autocorrelation time (ACT) for each window must be ", " known, so use [TT]-ac[tt] or provide the ACT with [TT]-iiact[tt]. If the ACT of all ", " windows are identical (and known), you can also provide them with [TT]-bs-tau[tt]. ", - " Note that this method may severely underestimate the error in case of limited sampling, ", + " Note that this method may severely underestimate the error in case of limited ", + " sampling, ", " that is if individual histograms do not represent the complete phase space at ", " the respective positions.", "* [TT]traj-gauss[tt] The same as method [TT]traj[tt], but the trajectories are ", @@ -3367,99 +3451,127 @@ int gmx_wham(int argc, char *argv[]) "the histograms." }; - const char *en_unit[] = {nullptr, "kJ", "kCal", "kT", nullptr}; - const char *en_unit_label[] = {"", "E (kJ mol\\S-1\\N)", "E (kcal mol\\S-1\\N)", "E (kT)", nullptr}; - const char *en_bsMethod[] = { nullptr, "b-hist", "hist", "traj", "traj-gauss", nullptr }; + const char* en_unit[] = { nullptr, "kJ", "kCal", "kT", nullptr }; + const char* en_unit_label[] = { "", "E (kJ mol\\S-1\\N)", "E (kcal mol\\S-1\\N)", "E (kT)", nullptr }; + const char* en_bsMethod[] = { nullptr, "b-hist", "hist", "traj", "traj-gauss", nullptr }; static t_UmbrellaOptions opt; - t_pargs pa[] = { - { "-min", FALSE, etREAL, {&opt.min}, - "Minimum coordinate in profile"}, - { "-max", FALSE, etREAL, {&opt.max}, - "Maximum coordinate in profile"}, - { "-auto", FALSE, etBOOL, {&opt.bAuto}, - "Determine min and max automatically"}, - { "-bins", FALSE, etINT, {&opt.bins}, - "Number of bins in profile"}, - { "-temp", FALSE, etREAL, {&opt.Temperature}, - "Temperature"}, - { "-tol", FALSE, etREAL, {&opt.Tolerance}, - "Tolerance"}, - { "-v", FALSE, etBOOL, {&opt.verbose}, - "Verbose mode"}, - { "-b", FALSE, etREAL, {&opt.tmin}, - "First time to analyse (ps)"}, - { "-e", FALSE, etREAL, {&opt.tmax}, - "Last time to analyse (ps)"}, - { "-dt", FALSE, etREAL, {&opt.dt}, - "Analyse only every dt ps"}, - { "-histonly", FALSE, etBOOL, {&opt.bHistOnly}, - "Write histograms and exit"}, - { "-boundsonly", FALSE, etBOOL, {&opt.bBoundsOnly}, - "Determine min and max and exit (with [TT]-auto[tt])"}, - { "-log", FALSE, etBOOL, {&opt.bLog}, - "Calculate the log of the profile before printing"}, - { "-unit", FALSE, etENUM, {en_unit}, - "Energy unit in case of log output" }, - { "-zprof0", FALSE, etREAL, {&opt.zProf0}, - "Define profile to 0.0 at this position (with [TT]-log[tt])"}, - { "-cycl", FALSE, etBOOL, {&opt.bCycl}, - "Create cyclic/periodic profile. Assumes min and max are the same point."}, - { "-sym", FALSE, etBOOL, {&opt.bSym}, - "Symmetrize profile around z=0"}, - { "-hist-eq", FALSE, etBOOL, {&opt.bHistEq}, - "HIDDENEnforce equal weight for all histograms. (Non-Weighed-HAM)"}, - { "-ac", FALSE, etBOOL, {&opt.bCalcTauInt}, - "Calculate integrated autocorrelation times and use in wham"}, - { "-acsig", FALSE, etREAL, {&opt.sigSmoothIact}, - "Smooth autocorrelation times along reaction coordinate with Gaussian of this [GRK]sigma[grk]"}, - { "-ac-trestart", FALSE, etREAL, {&opt.acTrestart}, - "When computing autocorrelation functions, restart computing every .. (ps)"}, - { "-acred", FALSE, etBOOL, {&opt.bAllowReduceIact}, + t_pargs pa[] = { + { "-min", FALSE, etREAL, { &opt.min }, "Minimum coordinate in profile" }, + { "-max", FALSE, etREAL, { &opt.max }, "Maximum coordinate in profile" }, + { "-auto", FALSE, etBOOL, { &opt.bAuto }, "Determine min and max automatically" }, + { "-bins", FALSE, etINT, { &opt.bins }, "Number of bins in profile" }, + { "-temp", FALSE, etREAL, { &opt.Temperature }, "Temperature" }, + { "-tol", FALSE, etREAL, { &opt.Tolerance }, "Tolerance" }, + { "-v", FALSE, etBOOL, { &opt.verbose }, "Verbose mode" }, + { "-b", FALSE, etREAL, { &opt.tmin }, "First time to analyse (ps)" }, + { "-e", FALSE, etREAL, { &opt.tmax }, "Last time to analyse (ps)" }, + { "-dt", FALSE, etREAL, { &opt.dt }, "Analyse only every dt ps" }, + { "-histonly", FALSE, etBOOL, { &opt.bHistOnly }, "Write histograms and exit" }, + { "-boundsonly", + FALSE, + etBOOL, + { &opt.bBoundsOnly }, + "Determine min and max and exit (with [TT]-auto[tt])" }, + { "-log", FALSE, etBOOL, { &opt.bLog }, "Calculate the log of the profile before printing" }, + { "-unit", FALSE, etENUM, { en_unit }, "Energy unit in case of log output" }, + { "-zprof0", + FALSE, + etREAL, + { &opt.zProf0 }, + "Define profile to 0.0 at this position (with [TT]-log[tt])" }, + { "-cycl", + FALSE, + etBOOL, + { &opt.bCycl }, + "Create cyclic/periodic profile. Assumes min and max are the same point." }, + { "-sym", FALSE, etBOOL, { &opt.bSym }, "Symmetrize profile around z=0" }, + { "-hist-eq", + FALSE, + etBOOL, + { &opt.bHistEq }, + "HIDDENEnforce equal weight for all histograms. (Non-Weighed-HAM)" }, + { "-ac", + FALSE, + etBOOL, + { &opt.bCalcTauInt }, + "Calculate integrated autocorrelation times and use in wham" }, + { "-acsig", + FALSE, + etREAL, + { &opt.sigSmoothIact }, + "Smooth autocorrelation times along reaction coordinate with Gaussian of this " + "[GRK]sigma[grk]" }, + { "-ac-trestart", + FALSE, + etREAL, + { &opt.acTrestart }, + "When computing autocorrelation functions, restart computing every .. (ps)" }, + { "-acred", + FALSE, + etBOOL, + { &opt.bAllowReduceIact }, "HIDDENWhen smoothing the ACTs, allows one to reduce ACTs. Otherwise, only increase ACTs " - "during smoothing"}, - { "-nBootstrap", FALSE, etINT, {&opt.nBootStrap}, + "during smoothing" }, + { "-nBootstrap", + FALSE, + etINT, + { &opt.nBootStrap }, "nr of bootstraps to estimate statistical uncertainty (e.g., 200)" }, - { "-bs-method", FALSE, etENUM, {en_bsMethod}, - "Bootstrap method" }, - { "-bs-tau", FALSE, etREAL, {&opt.tauBootStrap}, - "Autocorrelation time (ACT) assumed for all histograms. Use option [TT]-ac[tt] if ACT is unknown."}, - { "-bs-seed", FALSE, etINT, {&opt.bsSeed}, - "Seed for bootstrapping. (-1 = use time)"}, - { "-histbs-block", FALSE, etINT, {&opt.histBootStrapBlockLength}, - "When mixing histograms only mix within blocks of [TT]-histbs-block[tt]."}, - { "-vbs", FALSE, etBOOL, {&opt.bs_verbose}, - "Verbose bootstrapping. Print the CDFs and a histogram file for each bootstrap."}, - { "-stepout", FALSE, etINT, {&opt.stepchange}, - "HIDDENWrite maximum change every ... (set to 1 with [TT]-v[tt])"}, - { "-updateContr", FALSE, etINT, {&opt.stepUpdateContrib}, - "HIDDENUpdate table with significan contributions to WHAM every ... iterations"}, + { "-bs-method", FALSE, etENUM, { en_bsMethod }, "Bootstrap method" }, + { "-bs-tau", + FALSE, + etREAL, + { &opt.tauBootStrap }, + "Autocorrelation time (ACT) assumed for all histograms. Use option [TT]-ac[tt] if ACT is " + "unknown." }, + { "-bs-seed", FALSE, etINT, { &opt.bsSeed }, "Seed for bootstrapping. (-1 = use time)" }, + { "-histbs-block", + FALSE, + etINT, + { &opt.histBootStrapBlockLength }, + "When mixing histograms only mix within blocks of [TT]-histbs-block[tt]." }, + { "-vbs", + FALSE, + etBOOL, + { &opt.bs_verbose }, + "Verbose bootstrapping. Print the CDFs and a histogram file for each bootstrap." }, + { "-stepout", + FALSE, + etINT, + { &opt.stepchange }, + "HIDDENWrite maximum change every ... (set to 1 with [TT]-v[tt])" }, + { "-updateContr", + FALSE, + etINT, + { &opt.stepUpdateContrib }, + "HIDDENUpdate table with significan contributions to WHAM every ... iterations" }, }; - t_filenm fnm[] = { - { efDAT, "-ix", "pullx-files", ffOPTRD}, /* wham input: pullf.xvg's and tprs */ - { efDAT, "-if", "pullf-files", ffOPTRD}, /* wham input: pullf.xvg's and tprs */ - { efDAT, "-it", "tpr-files", ffOPTRD}, /* wham input: tprs */ - { efDAT, "-ip", "pdo-files", ffOPTRD}, /* wham input: pdo files (gmx3 style) */ - { efDAT, "-is", "coordsel", ffOPTRD}, /* input: select pull coords to use */ - { efXVG, "-o", "profile", ffWRITE }, /* output file for profile */ - { efXVG, "-hist", "histo", ffWRITE}, /* output file for histograms */ - { efXVG, "-oiact", "iact", ffOPTWR}, /* writing integrated autocorrelation times */ - { efDAT, "-iiact", "iact-in", ffOPTRD}, /* reading integrated autocorrelation times */ - { efXVG, "-bsres", "bsResult", ffOPTWR}, /* average and errors of bootstrap analysis */ - { efXVG, "-bsprof", "bsProfs", ffOPTWR}, /* output file for bootstrap profiles */ - { efDAT, "-tab", "umb-pot", ffOPTRD}, /* Tabulated umbrella potential (if not harmonic) */ + t_filenm fnm[] = { + { efDAT, "-ix", "pullx-files", ffOPTRD }, /* wham input: pullf.xvg's and tprs */ + { efDAT, "-if", "pullf-files", ffOPTRD }, /* wham input: pullf.xvg's and tprs */ + { efDAT, "-it", "tpr-files", ffOPTRD }, /* wham input: tprs */ + { efDAT, "-ip", "pdo-files", ffOPTRD }, /* wham input: pdo files (gmx3 style) */ + { efDAT, "-is", "coordsel", ffOPTRD }, /* input: select pull coords to use */ + { efXVG, "-o", "profile", ffWRITE }, /* output file for profile */ + { efXVG, "-hist", "histo", ffWRITE }, /* output file for histograms */ + { efXVG, "-oiact", "iact", ffOPTWR }, /* writing integrated autocorrelation times */ + { efDAT, "-iiact", "iact-in", ffOPTRD }, /* reading integrated autocorrelation times */ + { efXVG, "-bsres", "bsResult", ffOPTWR }, /* average and errors of bootstrap analysis */ + { efXVG, "-bsprof", "bsProfs", ffOPTWR }, /* output file for bootstrap profiles */ + { efDAT, "-tab", "umb-pot", ffOPTRD }, /* Tabulated umbrella potential (if not harmonic) */ }; - int i, j, l, nfiles, nwins, nfiles2; - t_UmbrellaHeader header; - t_UmbrellaWindow * window = nullptr; - double *profile, maxchange = 1e20; - gmx_bool bMinSet, bMaxSet, bAutoSet, bExact = FALSE; - char **fninTpr, **fninPull, **fninPdo; - const char *fnPull; - FILE *histout, *profout; - char xlabel[STRLEN], ylabel[256], title[256]; + int i, j, l, nfiles, nwins, nfiles2; + t_UmbrellaHeader header; + t_UmbrellaWindow* window = nullptr; + double * profile, maxchange = 1e20; + gmx_bool bMinSet, bMaxSet, bAutoSet, bExact = FALSE; + char ** fninTpr, **fninPull, **fninPdo; + const char* fnPull; + FILE * histout, *profout; + char xlabel[STRLEN], ylabel[256], title[256]; opt.bins = 200; opt.verbose = FALSE; @@ -3497,8 +3609,8 @@ int gmx_wham(int argc, char *argv[]) opt.stepchange = 100; opt.stepUpdateContrib = 100; - if (!parse_common_args(&argc, argv, 0, - NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &opt.oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, + &opt.oenv)) { return 0; } @@ -3506,7 +3618,7 @@ int gmx_wham(int argc, char *argv[]) opt.unit = nenum(en_unit); opt.bsMethod = nenum(en_bsMethod); - opt.bProf0Set = opt2parg_bSet("-zprof0", asize(pa), pa); + opt.bProf0Set = opt2parg_bSet("-zprof0", asize(pa), pa); opt.bTab = opt2bSet("-tab", NFILE, fnm); opt.bPdo = opt2bSet("-ip", NFILE, fnm); @@ -3514,9 +3626,10 @@ int gmx_wham(int argc, char *argv[]) opt.bPullx = opt2bSet("-ix", NFILE, fnm); opt.bPullf = opt2bSet("-if", NFILE, fnm); opt.bTauIntGiven = opt2bSet("-iiact", NFILE, fnm); - if (opt.bTab && opt.bPullf) + if (opt.bTab && opt.bPullf) { - gmx_fatal(FARGS, "Force input does not work with tabulated potentials. " + gmx_fatal(FARGS, + "Force input does not work with tabulated potentials. " "Provide pullx.xvg or pdo files!"); } @@ -3526,7 +3639,8 @@ int gmx_wham(int argc, char *argv[]) } if (!opt.bPdo && !(opt.bTpr || opt.bPullf || opt.bPullx)) { - gmx_fatal(FARGS, "gmx wham supports three input modes, pullx, pullf, or pdo file input." + gmx_fatal(FARGS, + "gmx wham supports three input modes, pullx, pullf, or pdo file input." "\n\n Check gmx wham -h !"); } @@ -3536,15 +3650,15 @@ int gmx_wham(int argc, char *argv[]) opt.fnPullx = opt2fn("-ix", NFILE, fnm); opt.fnCoordSel = opt2fn_null("-is", NFILE, fnm); - bMinSet = opt2parg_bSet("-min", asize(pa), pa); - bMaxSet = opt2parg_bSet("-max", asize(pa), pa); - bAutoSet = opt2parg_bSet("-auto", asize(pa), pa); - if ( (bMinSet || bMaxSet) && bAutoSet) + bMinSet = opt2parg_bSet("-min", asize(pa), pa); + bMaxSet = opt2parg_bSet("-max", asize(pa), pa); + bAutoSet = opt2parg_bSet("-auto", asize(pa), pa); + if ((bMinSet || bMaxSet) && bAutoSet) { gmx_fatal(FARGS, "With -auto, do not give -min or -max\n"); } - if ( (bMinSet && !bMaxSet) || (!bMinSet && bMaxSet)) + if ((bMinSet && !bMaxSet) || (!bMinSet && bMaxSet)) { gmx_fatal(FARGS, "When giving -min, you must give -max (and vice versa), too\n"); } @@ -3557,18 +3671,21 @@ int gmx_wham(int argc, char *argv[]) if (opt.bTauIntGiven && opt.bCalcTauInt) { - gmx_fatal(FARGS, "Either read (option -iiact) or calculate (option -ac) the\n" + gmx_fatal(FARGS, + "Either read (option -iiact) or calculate (option -ac) the\n" "the autocorrelation times. Not both."); } if (opt.tauBootStrap > 0.0 && opt2parg_bSet("-ac", asize(pa), pa)) { - gmx_fatal(FARGS, "Either compute autocorrelation times (ACTs) (option -ac) or " + gmx_fatal(FARGS, + "Either compute autocorrelation times (ACTs) (option -ac) or " "provide it with -bs-tau for bootstrapping. Not Both.\n"); } if (opt.tauBootStrap > 0.0 && opt2bSet("-iiact", NFILE, fnm)) { - gmx_fatal(FARGS, "Either provide autocorrelation times (ACTs) with file iact-in.dat " + gmx_fatal(FARGS, + "Either provide autocorrelation times (ACTs) with file iact-in.dat " "(option -iiact) or define all ACTs with -bs-tau for bootstrapping\n. Not Both."); } @@ -3579,12 +3696,11 @@ int gmx_wham(int argc, char *argv[]) fnPull = opt.bPullf ? opt.fnPullf : opt.fnPullx; read_wham_in(fnPull, &fninPull, &nfiles2, &opt); - printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n", - nfiles, nfiles2, opt.bPullf ? "force" : "position", opt.fnTpr, fnPull); + printf("Found %d tpr and %d pull %s files in %s and %s, respectively\n", nfiles, nfiles2, + opt.bPullf ? "force" : "position", opt.fnTpr, fnPull); if (nfiles != nfiles2) { - gmx_fatal(FARGS, "Found %d file names in %s, but %d in %s\n", nfiles, - opt.fnTpr, nfiles2, fnPull); + gmx_fatal(FARGS, "Found %d file names in %s, but %d in %s\n", nfiles, opt.fnTpr, nfiles2, fnPull); } /* Read file that selects the pull group to be used */ @@ -3597,11 +3713,13 @@ int gmx_wham(int argc, char *argv[]) read_tpr_pullxf_files(fninTpr, fninPull, nfiles, &header, window, &opt); } else - { /* reading pdo files */ - if (opt.fnCoordSel != nullptr) + { /* reading pdo files */ + if (opt.fnCoordSel != nullptr) { - gmx_fatal(FARGS, "Reading a -is file is not supported with PDO input files.\n" - "Use awk or a similar tool to pick the required pull groups from your PDO files\n"); + gmx_fatal(FARGS, + "Reading a -is file is not supported with PDO input files.\n" + "Use awk or a similar tool to pick the required pull groups from your PDO " + "files\n"); } read_wham_in(opt.fnPdo, &fninPdo, &nfiles, &opt); printf("Found %d pdo files in %s\n", nfiles, opt.fnPdo); @@ -3622,11 +3740,10 @@ int gmx_wham(int argc, char *argv[]) } /* write histograms */ - histout = xvgropen(opt2fn("-hist", NFILE, fnm), "Umbrella histograms", - xlabel, "count", opt.oenv); + histout = xvgropen(opt2fn("-hist", NFILE, fnm), "Umbrella histograms", xlabel, "count", opt.oenv); for (l = 0; l < opt.bins; ++l) { - fprintf(histout, "%e\t", (l+0.5)/opt.bins*(opt.max-opt.min)+opt.min); + fprintf(histout, "%e\t", (l + 0.5) / opt.bins * (opt.max - opt.min) + opt.min); for (i = 0; i < nwins; ++i) { for (j = 0; j < window[i].nPull; ++j) @@ -3687,7 +3804,7 @@ int gmx_wham(int argc, char *argv[]) i = 0; do { - if ( (i%opt.stepUpdateContrib) == 0) + if ((i % opt.stepUpdateContrib) == 0) { setup_acc_wham(profile, window, nwins, &opt); } @@ -3698,13 +3815,12 @@ int gmx_wham(int argc, char *argv[]) printf("Switched to exact iteration in iteration %d\n", i); } calc_profile(profile, window, nwins, &opt, bExact); - if (((i%opt.stepchange) == 0 || i == 1) && i != 0) + if (((i % opt.stepchange) == 0 || i == 1) && i != 0) { printf("\t%4d) Maximum change %e\n", i, maxchange); } i++; - } - while ( (maxchange = calc_z(profile, window, nwins, &opt, bExact)) > opt.Tolerance || !bExact); + } while ((maxchange = calc_z(profile, window, nwins, &opt, bExact)) > opt.Tolerance || !bExact); printf("Converged in %d iterations. Final maximum change %g\n", i, maxchange); /* calc error from Kumar's formula */ @@ -3735,7 +3851,7 @@ int gmx_wham(int argc, char *argv[]) profout = xvgropen(opt2fn("-o", NFILE, fnm), title, xlabel, ylabel, opt.oenv); for (i = 0; i < opt.bins; ++i) { - fprintf(profout, "%e\t%e\n", (i+0.5)/opt.bins*(opt.max-opt.min)+opt.min, profile[i]); + fprintf(profout, "%e\t%e\n", (i + 0.5) / opt.bins * (opt.max - opt.min) + opt.min, profile[i]); } xvgrclose(profout); printf("Wrote %s\n", opt2fn("-o", NFILE, fnm)); @@ -3744,8 +3860,7 @@ int gmx_wham(int argc, char *argv[]) if (opt.nBootStrap) { do_bootstrapping(opt2fn("-bsres", NFILE, fnm), opt2fn("-bsprof", NFILE, fnm), - opt2fn("-hist", NFILE, fnm), - xlabel, ylabel, profile, window, nwins, &opt); + opt2fn("-hist", NFILE, fnm), xlabel, ylabel, profile, window, nwins, &opt); } sfree(profile); diff --git a/src/gromacs/gmxana/gmx_wheel.cpp b/src/gromacs/gmxana/gmx_wheel.cpp index 35716a650e..924eda09b1 100644 --- a/src/gromacs/gmxana/gmx_wheel.cpp +++ b/src/gromacs/gmxana/gmx_wheel.cpp @@ -55,11 +55,11 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/strdb.h" -static gmx_bool *bPhobics(int nres, char *resnm[]) +static gmx_bool* bPhobics(int nres, char* resnm[]) { int i, nb; - char **cb; - gmx_bool *bb; + char** cb; + gmx_bool* bb; nb = get_lines("phbres.dat", &cb); snew(bb, nres); @@ -74,19 +74,19 @@ static gmx_bool *bPhobics(int nres, char *resnm[]) return bb; } -static void wheel(const char *fn, int nres, char *resnm[], int r0, real rot0, char *title) +static void wheel(const char* fn, int nres, char* resnm[], int r0, real rot0, char* title) { const real fontsize = 16; const real gray = 0.9; const real fontasp = 0.6; - const real fontwidth = fontsize*fontasp; + const real fontwidth = fontsize * fontasp; - int i, sl, slen; - real ring, inner, outer; - real xc, yc, box; - gmx_bool *bPh; - char **rnms; - char sign; + int i, sl, slen; + real ring, inner, outer; + real xc, yc, box; + gmx_bool* bPh; + char** rnms; + char sign; inner = 75.0; slen = 0; @@ -95,40 +95,40 @@ static void wheel(const char *fn, int nres, char *resnm[], int r0, real rot0, ch { snew(rnms[i], 256); sl = std::strlen(resnm[i]); - sign = resnm[i][sl-1]; + sign = resnm[i][sl - 1]; if ((sign == '+') || (sign == '-')) { - resnm[i][sl-1] = '\0'; + resnm[i][sl - 1] = '\0'; } - sprintf(rnms[i], "%s-%d", resnm[i], i+r0); + sprintf(rnms[i], "%s-%d", resnm[i], i + r0); if ((sign == '+') || (sign == '-')) { - sl = std::strlen(rnms[i]); - rnms[i][sl] = sign; - rnms[i][sl+1] = '\0'; + sl = std::strlen(rnms[i]); + rnms[i][sl] = sign; + rnms[i][sl + 1] = '\0'; } slen = std::max(slen, static_cast(std::strlen(rnms[i]))); } - ring = (2+slen)*fontwidth; - outer = inner+ring; - box = inner*1.5+(1+int{nres/18})*ring; + ring = (2 + slen) * fontwidth; + outer = inner + ring; + box = inner * 1.5 + (1 + int{ nres / 18 }) * ring; bPh = bPhobics(nres, resnm); - t_psdata out = ps_open(fn, 0, 0, 2.0*box, 2.0*box); - xc = box; - yc = box; + t_psdata out = ps_open(fn, 0, 0, 2.0 * box, 2.0 * box); + xc = box; + yc = box; - ps_font(&out, efontHELV, 1.5*fontsize); + ps_font(&out, efontHELV, 1.5 * fontsize); ps_translate(&out, xc, yc); if (title) { - ps_ctext(&out, 0, -fontsize*1.5/2.0, title, eXCenter); + ps_ctext(&out, 0, -fontsize * 1.5 / 2.0, title, eXCenter); } ps_font(&out, efontHELV, fontsize); ps_rotate(&out, rot0); - for (i = 0; (i < nres); ) + for (i = 0; (i < nres);) { if (bPh[i]) { @@ -138,30 +138,30 @@ static void wheel(const char *fn, int nres, char *resnm[], int r0, real rot0, ch } ps_arcslice(&out, 0, 0, inner, outer, -10, 10); - ps_ctext(&out, inner+fontwidth, -fontsize/2.0, rnms[i], eXLeft); + ps_ctext(&out, inner + fontwidth, -fontsize / 2.0, rnms[i], eXLeft); ps_rotate(&out, -100); i++; if ((i % 18) == 0) { - inner = outer; + inner = outer; outer += ring; } } ps_close(&out); } -static void wheel2(const char *fn, int nres, char *resnm[], real rot0, char *title) +static void wheel2(const char* fn, int nres, char* resnm[], real rot0, char* title) { const real fontsize = 14; const real gray = 0.9; const real fontasp = 0.45; const int angle = 9; - const real fontwidth = fontsize*fontasp; + const real fontwidth = fontsize * fontasp; - int i, slen; - real ring, inner, outer; - real xc, yc, box; + int i, slen; + real ring, inner, outer; + real xc, yc, box; inner = 60.0; slen = 0; @@ -170,25 +170,25 @@ static void wheel2(const char *fn, int nres, char *resnm[], real rot0, char *tit slen = std::max(slen, static_cast(strlen(resnm[i]))); } fprintf(stderr, "slen = %d\n", slen); - ring = slen*fontwidth; - outer = inner+ring; - box = (1+gmx::exactDiv(nres, 2*angle))*outer; + ring = slen * fontwidth; + outer = inner + ring; + box = (1 + gmx::exactDiv(nres, 2 * angle)) * outer; - t_psdata out = ps_open(fn, 0, 0, 2.0*box, 2.0*box); - xc = box; - yc = box; + t_psdata out = ps_open(fn, 0, 0, 2.0 * box, 2.0 * box); + xc = box; + yc = box; - ps_font(&out, efontHELV, 1.5*fontsize); + ps_font(&out, efontHELV, 1.5 * fontsize); ps_translate(&out, xc, yc); ps_color(&out, 0, 0, 0); if (title) { - ps_ctext(&out, 0, -fontsize*1.5/2.0, title, eXCenter); + ps_ctext(&out, 0, -fontsize * 1.5 / 2.0, title, eXCenter); } ps_font(&out, efontHELV, fontsize); ps_rotate(&out, rot0); - for (i = 0; (i < nres); ) + for (i = 0; (i < nres);) { if ((i % 5) == 4) { @@ -198,53 +198,52 @@ static void wheel2(const char *fn, int nres, char *resnm[], real rot0, char *tit } ps_arcslice(&out, 0, 0, inner, outer, -angle, angle); - ps_ctext(&out, inner+fontwidth, -fontsize/2.0, resnm[i], eXLeft); - ps_rotate(&out, -2*angle); + ps_ctext(&out, inner + fontwidth, -fontsize / 2.0, resnm[i], eXLeft); + ps_rotate(&out, -2 * angle); i++; - if ((i % (2*angle)) == 0) + if ((i % (2 * angle)) == 0) { - inner = outer; + inner = outer; outer += ring; } } ps_close(&out); } -int gmx_wheel(int argc, char *argv[]) +int gmx_wheel(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] plots a helical wheel representation of your sequence.", "The input sequence is in the [REF].dat[ref] file where the first line contains", "the number of residues and each consecutive line contains a residue " "name." }; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; static real rot0 = 0; static gmx_bool bNum = TRUE; - static char *title = nullptr; + static char* title = nullptr; static int r0 = 1; - t_pargs pa [] = { - { "-r0", FALSE, etINT, {&r0}, - "The first residue number in the sequence" }, - { "-rot0", FALSE, etREAL, {&rot0}, - "Rotate around an angle initially (90 degrees makes sense)" }, - { "-T", FALSE, etSTR, {&title}, - "Plot a title in the center of the wheel (must be shorter than 10 characters, or it will overwrite the wheel)" }, - { "-nn", FALSE, etBOOL, {&bNum}, - "Toggle numbers" } - }; - t_filenm fnm[] = { - { efDAT, "-f", nullptr, ffREAD }, - { efEPS, "-o", nullptr, ffWRITE } - }; + t_pargs pa[] = { { "-r0", FALSE, etINT, { &r0 }, "The first residue number in the sequence" }, + { "-rot0", + FALSE, + etREAL, + { &rot0 }, + "Rotate around an angle initially (90 degrees makes sense)" }, + { "-T", + FALSE, + etSTR, + { &title }, + "Plot a title in the center of the wheel (must be shorter than 10 " + "characters, or it will overwrite the wheel)" }, + { "-nn", FALSE, etBOOL, { &bNum }, "Toggle numbers" } }; + t_filenm fnm[] = { { efDAT, "-f", nullptr, ffREAD }, { efEPS, "-o", nullptr, ffWRITE } }; #define NFILE asize(fnm) int i, nres; - char **resnm; + char** resnm; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } diff --git a/src/gromacs/gmxana/gmx_xpm2ps.cpp b/src/gromacs/gmxana/gmx_xpm2ps.cpp index 7aca5d4bf4..0e2ed8c687 100644 --- a/src/gromacs/gmxana/gmx_xpm2ps.cpp +++ b/src/gromacs/gmxana/gmx_xpm2ps.cpp @@ -66,9 +66,10 @@ #include "gromacs/utility/stringutil.h" #define FUDGE 1.2 -#define DDD 2 +#define DDD 2 -typedef struct { +typedef struct +{ real major; real minor; real offset; @@ -83,7 +84,8 @@ typedef struct { char tickfont[STRLEN]; } t_axisdef; -typedef struct { +typedef struct +{ int bw; real linewidth; real xoffs, yoffs; @@ -107,20 +109,33 @@ typedef struct { } t_psrec; /* MUST correspond to char *legend[] in main() */ -enum { - elSel, elBoth, elFirst, elSecond, elNone, elNR +enum +{ + elSel, + elBoth, + elFirst, + elSecond, + elNone, + elNR }; /* MUST correspond to char *combine[] in main() */ -enum { - ecSel, ecHalves, ecAdd, ecSub, ecMult, ecDiv, ecNR +enum +{ + ecSel, + ecHalves, + ecAdd, + ecSub, + ecMult, + ecDiv, + ecNR }; -static void get_params(const char *mpin, const char *mpout, t_psrec *psr) +static void get_params(const char* mpin, const char* mpout, t_psrec* psr) { - static const char *gmx_bools[BOOL_NR+1] = { "no", "yes", nullptr }; + static const char* gmx_bools[BOOL_NR + 1] = { "no", "yes", nullptr }; /* this must correspond to t_rgb *linecolors[] below */ - static const char *colors[] = { "none", "black", "white", nullptr }; + static const char* colors[] = { "none", "black", "white", nullptr }; warninp_t wi; std::vector inp; @@ -137,47 +152,47 @@ static void get_params(const char *mpin, const char *mpout, t_psrec *psr) inp.clear(); } - psr->bw = get_eenum(&inp, "black&white", gmx_bools); - psr->linewidth = get_ereal(&inp, "linewidth", 1.0, wi); - setStringEntry(&inp, "titlefont", psr->titfont, "Helvetica"); - psr->titfontsize = get_ereal(&inp, "titlefontsize", 20.0, wi); - psr->legend = (get_eenum(&inp, "legend", gmx_bools) != 0); - setStringEntry(&inp, "legendfont", psr->legfont, psr->titfont); - setStringEntry(&inp, "legendlabel", psr->leglabel, ""); - setStringEntry(&inp, "legend2label", psr->leg2label, psr->leglabel); - psr->legfontsize = get_ereal(&inp, "legendfontsize", 14.0, wi); - psr->xboxsize = get_ereal(&inp, "xbox", 0.0, wi); - psr->yboxsize = get_ereal(&inp, "ybox", 0.0, wi); - psr->boxspacing = get_ereal(&inp, "matrixspacing", 20.0, wi); - psr->xoffs = get_ereal(&inp, "xoffset", 0.0, wi); - psr->yoffs = get_ereal(&inp, "yoffset", psr->xoffs, wi); - psr->boxlinewidth = get_ereal(&inp, "boxlinewidth", psr->linewidth, wi); - psr->ticklinewidth = get_ereal(&inp, "ticklinewidth", psr->linewidth, wi); - psr->zerolinewidth = get_ereal(&inp, "zerolinewidth", psr->ticklinewidth, wi); - psr->X.lineatzero = get_eenum(&inp, "x-lineat0value", colors); - psr->X.major = get_ereal(&inp, "x-major", 1, wi); - psr->X.minor = get_ereal(&inp, "x-minor", 1, wi); - psr->X.offset = get_ereal(&inp, "x-firstmajor", 0.0, wi); - psr->X.first = (get_eenum(&inp, "x-majorat0", gmx_bools) != 0); + psr->bw = get_eenum(&inp, "black&white", gmx_bools); + psr->linewidth = get_ereal(&inp, "linewidth", 1.0, wi); + setStringEntry(&inp, "titlefont", psr->titfont, "Helvetica"); + psr->titfontsize = get_ereal(&inp, "titlefontsize", 20.0, wi); + psr->legend = (get_eenum(&inp, "legend", gmx_bools) != 0); + setStringEntry(&inp, "legendfont", psr->legfont, psr->titfont); + setStringEntry(&inp, "legendlabel", psr->leglabel, ""); + setStringEntry(&inp, "legend2label", psr->leg2label, psr->leglabel); + psr->legfontsize = get_ereal(&inp, "legendfontsize", 14.0, wi); + psr->xboxsize = get_ereal(&inp, "xbox", 0.0, wi); + psr->yboxsize = get_ereal(&inp, "ybox", 0.0, wi); + psr->boxspacing = get_ereal(&inp, "matrixspacing", 20.0, wi); + psr->xoffs = get_ereal(&inp, "xoffset", 0.0, wi); + psr->yoffs = get_ereal(&inp, "yoffset", psr->xoffs, wi); + psr->boxlinewidth = get_ereal(&inp, "boxlinewidth", psr->linewidth, wi); + psr->ticklinewidth = get_ereal(&inp, "ticklinewidth", psr->linewidth, wi); + psr->zerolinewidth = get_ereal(&inp, "zerolinewidth", psr->ticklinewidth, wi); + psr->X.lineatzero = get_eenum(&inp, "x-lineat0value", colors); + psr->X.major = get_ereal(&inp, "x-major", 1, wi); + psr->X.minor = get_ereal(&inp, "x-minor", 1, wi); + psr->X.offset = get_ereal(&inp, "x-firstmajor", 0.0, wi); + psr->X.first = (get_eenum(&inp, "x-majorat0", gmx_bools) != 0); psr->X.majorticklen = get_ereal(&inp, "x-majorticklen", 8.0, wi); psr->X.minorticklen = get_ereal(&inp, "x-minorticklen", 4.0, wi); - setStringEntry(&inp, "x-label", psr->X.label, ""); - psr->X.fontsize = get_ereal(&inp, "x-fontsize", 16.0, wi); - setStringEntry(&inp, "x-font", psr->X.font, psr->titfont); + setStringEntry(&inp, "x-label", psr->X.label, ""); + psr->X.fontsize = get_ereal(&inp, "x-fontsize", 16.0, wi); + setStringEntry(&inp, "x-font", psr->X.font, psr->titfont); psr->X.tickfontsize = get_ereal(&inp, "x-tickfontsize", 10.0, wi); - setStringEntry(&inp, "x-tickfont", psr->X.tickfont, psr->X.font); - psr->Y.lineatzero = get_eenum(&inp, "y-lineat0value", colors); - psr->Y.major = get_ereal(&inp, "y-major", psr->X.major, wi); - psr->Y.minor = get_ereal(&inp, "y-minor", psr->X.minor, wi); - psr->Y.offset = get_ereal(&inp, "y-firstmajor", psr->X.offset, wi); - psr->Y.first = (get_eenum(&inp, "y-majorat0", gmx_bools) != 0); + setStringEntry(&inp, "x-tickfont", psr->X.tickfont, psr->X.font); + psr->Y.lineatzero = get_eenum(&inp, "y-lineat0value", colors); + psr->Y.major = get_ereal(&inp, "y-major", psr->X.major, wi); + psr->Y.minor = get_ereal(&inp, "y-minor", psr->X.minor, wi); + psr->Y.offset = get_ereal(&inp, "y-firstmajor", psr->X.offset, wi); + psr->Y.first = (get_eenum(&inp, "y-majorat0", gmx_bools) != 0); psr->Y.majorticklen = get_ereal(&inp, "y-majorticklen", psr->X.majorticklen, wi); psr->Y.minorticklen = get_ereal(&inp, "y-minorticklen", psr->X.minorticklen, wi); - setStringEntry(&inp, "y-label", psr->Y.label, psr->X.label); - psr->Y.fontsize = get_ereal(&inp, "y-fontsize", psr->X.fontsize, wi); - setStringEntry(&inp, "y-font", psr->Y.font, psr->X.font); + setStringEntry(&inp, "y-label", psr->Y.label, psr->X.label); + psr->Y.fontsize = get_ereal(&inp, "y-fontsize", psr->X.fontsize, wi); + setStringEntry(&inp, "y-font", psr->Y.font, psr->X.font); psr->Y.tickfontsize = get_ereal(&inp, "y-tickfontsize", psr->X.tickfontsize, wi); - setStringEntry(&inp, "y-tickfont", psr->Y.tickfont, psr->Y.font); + setStringEntry(&inp, "y-tickfont", psr->Y.tickfont, psr->Y.font); check_warning_error(wi, FARGS); @@ -195,53 +210,62 @@ static t_rgb black = { 0, 0, 0 }; static t_rgb white = { 1, 1, 1 }; #define BLACK (&black) /* this must correspond to *colors[] in get_params */ -static t_rgb *linecolors[] = { nullptr, &black, &white, nullptr }; - -static void leg_discrete(t_psdata *ps, real x0, real y0, const std::string &label, - real fontsize, char *font, +static t_rgb* linecolors[] = { nullptr, &black, &white, nullptr }; + +static void leg_discrete(t_psdata* ps, + real x0, + real y0, + const std::string& label, + real fontsize, + char* font, gmx::ArrayRef map) { - real yhh; - real boxhh; + real yhh; + real boxhh; - boxhh = fontsize+DDD; + boxhh = fontsize + DDD; /* LANDSCAPE */ ps_rgb(ps, BLACK); ps_strfont(ps, font, fontsize); - yhh = y0+fontsize+3*DDD; + yhh = y0 + fontsize + 3 * DDD; if (!label.empty()) { ps_ctext(ps, x0, yhh, label, eXLeft); } ps_moveto(ps, x0, y0); - for (const auto &m : map) + for (const auto& m : map) { ps_setorigin(ps); ps_rgb(ps, &m.rgb); - ps_fillbox(ps, DDD, DDD, DDD+fontsize, boxhh-DDD); + ps_fillbox(ps, DDD, DDD, DDD + fontsize, boxhh - DDD); ps_rgb(ps, BLACK); - ps_box(ps, DDD, DDD, DDD+fontsize, boxhh-DDD); - ps_ctext(ps, boxhh+2*DDD, fontsize/3, m.desc, eXLeft); + ps_box(ps, DDD, DDD, DDD + fontsize, boxhh - DDD); + ps_ctext(ps, boxhh + 2 * DDD, fontsize / 3, m.desc, eXLeft); ps_unsetorigin(ps); - ps_moverel(ps, DDD, -fontsize/3); + ps_moverel(ps, DDD, -fontsize / 3); } } -static void leg_continuous(t_psdata *ps, real x0, real x, real y0, const std::string &label, - real fontsize, char *font, +static void leg_continuous(t_psdata* ps, + real x0, + real x, + real y0, + const std::string& label, + real fontsize, + char* font, gmx::ArrayRef map, - int mapoffset) + int mapoffset) { real xx0; real yhh, boxxh, boxyh; gmx::index mapIndex = gmx::ssize(map) - mapoffset; boxyh = fontsize; - if (x < 8*fontsize) + if (x < 8 * fontsize) { - x = 8*fontsize; + x = 8 * fontsize; } - boxxh = x/mapIndex; + boxxh = x / mapIndex; if (boxxh > fontsize) { boxxh = fontsize; @@ -250,61 +274,66 @@ static void leg_continuous(t_psdata *ps, real x0, real x, real y0, const std::st GMX_RELEASE_ASSERT(!map.empty(), "NULL map array provided to leg_continuous()"); /* LANDSCAPE */ - xx0 = x0-(mapIndex*boxxh)/2.0; + xx0 = x0 - (mapIndex * boxxh) / 2.0; for (gmx::index i = 0; (i < mapIndex); i++) { - ps_rgb(ps, &(map[i+mapoffset].rgb)); - ps_fillbox(ps, xx0+i*boxxh, y0, xx0+(i+1)*boxxh, y0+boxyh); + ps_rgb(ps, &(map[i + mapoffset].rgb)); + ps_fillbox(ps, xx0 + i * boxxh, y0, xx0 + (i + 1) * boxxh, y0 + boxyh); } ps_strfont(ps, font, fontsize); ps_rgb(ps, BLACK); - ps_box(ps, xx0, y0, xx0+mapIndex*boxxh, y0+boxyh); + ps_box(ps, xx0, y0, xx0 + mapIndex * boxxh, y0 + boxyh); - yhh = y0+boxyh+3*DDD; - ps_ctext(ps, xx0+boxxh/2, yhh, map[0].desc, eXCenter); + yhh = y0 + boxyh + 3 * DDD; + ps_ctext(ps, xx0 + boxxh / 2, yhh, map[0].desc, eXCenter); if (!label.empty()) { ps_ctext(ps, x0, yhh, label, eXCenter); } - ps_ctext(ps, xx0+(mapIndex*boxxh) - - boxxh/2, yhh, map[map.size()-1].desc, eXCenter); + ps_ctext(ps, xx0 + (mapIndex * boxxh) - boxxh / 2, yhh, map[map.size() - 1].desc, eXCenter); } -static void leg_bicontinuous(t_psdata *ps, real x0, real x, real y0, const std::string &label1, - const std::string &label2, real fontsize, char *font, +static void leg_bicontinuous(t_psdata* ps, + real x0, + real x, + real y0, + const std::string& label1, + const std::string& label2, + real fontsize, + char* font, gmx::ArrayRef map1, gmx::ArrayRef map2) { real xx1, xx2, x1, x2; - x1 = x/(map1.size()+map2.size())*map1.size(); /* width of legend 1 */ - x2 = x/(map1.size()+map2.size())*map2.size(); /* width of legend 2 */ - xx1 = x0-(x2/2.0)-fontsize; /* center of legend 1 */ - xx2 = x0+(x1/2.0)+fontsize; /* center of legend 2 */ - x1 -= fontsize/2; /* adjust width */ - x2 -= fontsize/2; /* adjust width */ + x1 = x / (map1.size() + map2.size()) * map1.size(); /* width of legend 1 */ + x2 = x / (map1.size() + map2.size()) * map2.size(); /* width of legend 2 */ + xx1 = x0 - (x2 / 2.0) - fontsize; /* center of legend 1 */ + xx2 = x0 + (x1 / 2.0) + fontsize; /* center of legend 2 */ + x1 -= fontsize / 2; /* adjust width */ + x2 -= fontsize / 2; /* adjust width */ leg_continuous(ps, xx1, x1, y0, label1, fontsize, font, map1, 0); leg_continuous(ps, xx2, x2, y0, label2, fontsize, font, map2, 0); } -static real box_height(const t_matrix &mat, t_psrec *psr) +static real box_height(const t_matrix& mat, t_psrec* psr) { - return mat.ny*psr->yboxsize; + return mat.ny * psr->yboxsize; } -static real box_dh(t_psrec *psr) +static real box_dh(t_psrec* psr) { return psr->boxspacing; } -static real box_dh_top(gmx_bool bOnce, t_psrec *psr) +static real box_dh_top(gmx_bool bOnce, t_psrec* psr) { real dh; - if (psr->bTitle || (psr->bTitleOnce && bOnce) ) + if (psr->bTitle || (psr->bTitleOnce && bOnce)) { - dh = 2*psr->titfontsize; + dh = 2 * psr->titfontsize; } else { @@ -314,25 +343,24 @@ static real box_dh_top(gmx_bool bOnce, t_psrec *psr) return dh; } -static gmx_bool box_do_all_x_maj_ticks(t_psrec *psr) +static gmx_bool box_do_all_x_maj_ticks(t_psrec* psr) { - return (psr->boxspacing > (1.5*psr->X.majorticklen)); + return (psr->boxspacing > (1.5 * psr->X.majorticklen)); } -static gmx_bool box_do_all_x_min_ticks(t_psrec *psr) +static gmx_bool box_do_all_x_min_ticks(t_psrec* psr) { - return (psr->boxspacing > (1.5*psr->X.minorticklen)); + return (psr->boxspacing > (1.5 * psr->X.minorticklen)); } -static void draw_boxes(t_psdata *ps, real x0, real y0, real w, - gmx::ArrayRef mat, t_psrec *psr) +static void draw_boxes(t_psdata* ps, real x0, real y0, real w, gmx::ArrayRef mat, t_psrec* psr) { - char buf[128]; - real xxx; - char **xtick, **ytick; - real xx, yy, dy, xx00, yy00, offset_x, offset_y; - int x, ntx, nty; - size_t strlength; + char buf[128]; + real xxx; + char **xtick, **ytick; + real xx, yy, dy, xx00, yy00, offset_x, offset_y; + int x, ntx, nty; + size_t strlength; /* Only necessary when there will be no y-labels */ strlength = 0; @@ -344,15 +372,15 @@ static void draw_boxes(t_psdata *ps, real x0, real y0, real w, for (auto m = mat.begin(); m != mat.end(); ++m) { dy = box_height(*m, psr); - ps_box(ps, x0-1, yy00-1, x0+w+1, yy00+dy+1); - yy00 += dy+box_dh(psr)+box_dh_top(m+1 == mat.end(), psr); + ps_box(ps, x0 - 1, yy00 - 1, x0 + w + 1, yy00 + dy + 1); + yy00 += dy + box_dh(psr) + box_dh_top(m + 1 == mat.end(), psr); } /* Draw the ticks on the axes */ ps_linewidth(ps, static_cast(psr->ticklinewidth)); - xx00 = x0-1; - yy00 = y0-1; - auto halfway = mat.begin() + (mat.size()/2); + xx00 = x0 - 1; + yy00 = y0 - 1; + auto halfway = mat.begin() + (mat.size() / 2); for (auto m = mat.begin(); m != mat.end(); ++m) { if (m->flags & MAT_SPATIAL_X) @@ -384,31 +412,29 @@ static void draw_boxes(t_psdata *ps, real x0, real y0, real w, ps_strfont(ps, psr->X.tickfont, psr->X.tickfontsize); for (x = 0; (x < ntx); x++) { - xx = xx00 + (x + offset_x)*psr->xboxsize; - if ( ( bRmod(m->axis_x[x], psr->X.offset, psr->X.major) || - (psr->X.first && (x == 0))) && - ( m == mat.begin() || box_do_all_x_maj_ticks(psr) ) ) + xx = xx00 + (x + offset_x) * psr->xboxsize; + if ((bRmod(m->axis_x[x], psr->X.offset, psr->X.major) || (psr->X.first && (x == 0))) + && (m == mat.begin() || box_do_all_x_maj_ticks(psr))) { /* Longer tick marks */ - ps_line (ps, xx, yy00, xx, yy00-psr->X.majorticklen); + ps_line(ps, xx, yy00, xx, yy00 - psr->X.majorticklen); /* Plot label on lowest graph only */ if (m == mat.begin()) { - ps_ctext(ps, xx, - yy00-DDD-psr->X.majorticklen-psr->X.tickfontsize*0.8, + ps_ctext(ps, xx, yy00 - DDD - psr->X.majorticklen - psr->X.tickfontsize * 0.8, xtick[x], eXCenter); } } - else if (bRmod(m->axis_x[x], psr->X.offset, psr->X.minor) && - ( (m == mat.begin()) || box_do_all_x_min_ticks(psr) ) ) + else if (bRmod(m->axis_x[x], psr->X.offset, psr->X.minor) + && ((m == mat.begin()) || box_do_all_x_min_ticks(psr))) { /* Shorter tick marks */ - ps_line(ps, xx, yy00, xx, yy00-psr->X.minorticklen); + ps_line(ps, xx, yy00, xx, yy00 - psr->X.minorticklen); } - else if (bRmod(m->axis_x[x], psr->X.offset, psr->X.major) ) + else if (bRmod(m->axis_x[x], psr->X.offset, psr->X.major)) { /* Even shorter marks, only each X.major */ - ps_line(ps, xx, yy00, xx, yy00-(psr->boxspacing/2)); + ps_line(ps, xx, yy00, xx, yy00 - (psr->boxspacing / 2)); } } ps_strfont(ps, psr->Y.tickfont, psr->Y.tickfontsize); @@ -421,20 +447,19 @@ static void draw_boxes(t_psdata *ps, real x0, real y0, real w, for (int y = 0; (y < nty); y++) { - yy = yy00 + (y + offset_y)*psr->yboxsize; - if (bRmod(m->axis_y[y], psr->Y.offset, psr->Y.major) || - (psr->Y.first && (y == 0))) + yy = yy00 + (y + offset_y) * psr->yboxsize; + if (bRmod(m->axis_y[y], psr->Y.offset, psr->Y.major) || (psr->Y.first && (y == 0))) { /* Major ticks */ strlength = std::max(strlength, std::strlen(ytick[y])); - ps_line (ps, xx00, yy, xx00-psr->Y.majorticklen, yy); - ps_ctext(ps, xx00-psr->Y.majorticklen-DDD, - yy-psr->Y.tickfontsize/3.0, ytick[y], eXRight); + ps_line(ps, xx00, yy, xx00 - psr->Y.majorticklen, yy); + ps_ctext(ps, xx00 - psr->Y.majorticklen - DDD, yy - psr->Y.tickfontsize / 3.0, + ytick[y], eXRight); } - else if (bRmod(m->axis_y[y], psr->Y.offset, psr->Y.minor) ) + else if (bRmod(m->axis_y[y], psr->Y.offset, psr->Y.minor)) { /* Minor ticks */ - ps_line(ps, xx00, yy, xx00-psr->Y.minorticklen, yy); + ps_line(ps, xx00, yy, xx00 - psr->Y.minorticklen, yy); } } sfree(xtick); @@ -456,14 +481,13 @@ static void draw_boxes(t_psdata *ps, real x0, real y0, real w, { ps_strfont(ps, psr->Y.font, psr->Y.fontsize); ps_flip(ps, TRUE); - xxx = x0-psr->X.majorticklen-psr->X.tickfontsize*strlength-DDD; - ps_ctext(ps, yy00+box_height(*m, psr)/2.0, 612.5-xxx, - mylab, eXCenter); + xxx = x0 - psr->X.majorticklen - psr->X.tickfontsize * strlength - DDD; + ps_ctext(ps, yy00 + box_height(*m, psr) / 2.0, 612.5 - xxx, mylab, eXCenter); ps_flip(ps, FALSE); } } - yy00 += box_height(*m, psr)+box_dh(psr)+box_dh_top(m+1 == mat.end(), psr); + yy00 += box_height(*m, psr) + box_dh(psr) + box_dh_top(m + 1 == mat.end(), psr); } /* Label on X-axis */ std::string mylab; @@ -478,19 +502,19 @@ static void draw_boxes(t_psdata *ps, real x0, real y0, real w, if (!mylab.empty()) { ps_strfont(ps, psr->X.font, psr->X.fontsize); - ps_ctext(ps, x0+w/2, y0-DDD-psr->X.majorticklen-psr->X.tickfontsize*FUDGE- - psr->X.fontsize, mylab, eXCenter); + ps_ctext(ps, x0 + w / 2, + y0 - DDD - psr->X.majorticklen - psr->X.tickfontsize * FUDGE - psr->X.fontsize, + mylab, eXCenter); } } -static void draw_zerolines(t_psdata *out, real x0, real y0, real w, - gmx::ArrayRef mat, t_psrec *psr) +static void draw_zerolines(t_psdata* out, real x0, real y0, real w, gmx::ArrayRef mat, t_psrec* psr) { - real xx, yy, dy, xx00, yy00; - int x, y; + real xx, yy, dy, xx00, yy00; + int x, y; - xx00 = x0-1.5; - yy00 = y0-1.5; + xx00 = x0 - 1.5; + yy00 = y0 - 1.5; ps_linewidth(out, static_cast(psr->zerolinewidth)); for (auto m = mat.begin(); m != mat.end(); ++m) { @@ -501,13 +525,12 @@ static void draw_zerolines(t_psdata *out, real x0, real y0, real w, ps_rgb(out, linecolors[psr->X.lineatzero]); for (x = 0; (x < m->nx); x++) { - xx = xx00+(x+0.7)*psr->xboxsize; + xx = xx00 + (x + 0.7) * psr->xboxsize; /* draw lines whenever tick label almost zero (e.g. next trajectory) */ - if (x != 0 && x < m->nx-1 && - std::abs(m->axis_x[x]) < - 0.1*std::abs(m->axis_x[x+1]-m->axis_x[x]) ) + if (x != 0 && x < m->nx - 1 + && std::abs(m->axis_x[x]) < 0.1 * std::abs(m->axis_x[x + 1] - m->axis_x[x])) { - ps_line (out, xx, yy00, xx, yy00+dy+2); + ps_line(out, xx, yy00, xx, yy00 + dy + 2); } } } @@ -516,48 +539,52 @@ static void draw_zerolines(t_psdata *out, real x0, real y0, real w, ps_rgb(out, linecolors[psr->Y.lineatzero]); for (y = 0; (y < m->ny); y++) { - yy = yy00+(y+0.7)*psr->yboxsize; + yy = yy00 + (y + 0.7) * psr->yboxsize; /* draw lines whenever tick label almost zero (e.g. next trajectory) */ - if (y != 0 && y < m->ny-1 && - std::abs(m->axis_y[y]) < - 0.1*std::abs(m->axis_y[y+1]-m->axis_y[y]) ) + if (y != 0 && y < m->ny - 1 + && std::abs(m->axis_y[y]) < 0.1 * std::abs(m->axis_y[y + 1] - m->axis_y[y])) { - ps_line (out, xx00, yy, xx00+w+2, yy); + ps_line(out, xx00, yy, xx00 + w + 2, yy); } } } - yy00 += box_height(*m, psr)+box_dh(psr)+box_dh_top(m+1 == mat.end(), psr); + yy00 += box_height(*m, psr) + box_dh(psr) + box_dh_top(m + 1 == mat.end(), psr); } } static void box_dim(gmx::ArrayRef mat, - gmx::ArrayRef mat2, t_psrec *psr, - int elegend, gmx_bool bFrame, - real *w, real *h, real *dw, real *dh) + gmx::ArrayRef mat2, + t_psrec* psr, + int elegend, + gmx_bool bFrame, + real* w, + real* h, + real* dw, + real* dh) { int maxytick; real ww, hh, dww, dhh; - hh = dww = dhh = 0; - maxytick = 0; + hh = dww = dhh = 0; + maxytick = 0; ww = 0; - for (const auto &m : mat) + for (const auto& m : mat) { - ww = std::max(ww, m.nx*psr->xboxsize); - hh += box_height(m, psr); + ww = std::max(ww, m.nx * psr->xboxsize); + hh += box_height(m, psr); maxytick = std::max(maxytick, m.nx); } if (bFrame) { if (mat[0].label_y[0]) { - dww += 2.0*(psr->Y.fontsize+DDD); + dww += 2.0 * (psr->Y.fontsize + DDD); } if (psr->Y.major > 0) { - dww += psr->Y.majorticklen + DDD + - psr->Y.tickfontsize*(std::log(static_cast(maxytick))/std::log(10.0)); + dww += psr->Y.majorticklen + DDD + + psr->Y.tickfontsize * (std::log(static_cast(maxytick)) / std::log(10.0)); } else if (psr->Y.minor > 0) { @@ -566,33 +593,33 @@ static void box_dim(gmx::ArrayRef mat, if (mat[0].label_x[0]) { - dhh += psr->X.fontsize+2*DDD; + dhh += psr->X.fontsize + 2 * DDD; } - if ( /* fool emacs auto-indent */ - (elegend == elBoth && (mat[0].legend[0] || (!mat2.empty() && mat2[0].legend[0]))) || - (elegend == elFirst && mat[0].legend[0]) || - (elegend == elSecond && (!mat2.empty() && mat2[0].legend[0])) ) + if (/* fool emacs auto-indent */ + (elegend == elBoth && (mat[0].legend[0] || (!mat2.empty() && mat2[0].legend[0]))) + || (elegend == elFirst && mat[0].legend[0]) + || (elegend == elSecond && (!mat2.empty() && mat2[0].legend[0]))) { - dhh += 2*(psr->legfontsize*FUDGE+2*DDD); + dhh += 2 * (psr->legfontsize * FUDGE + 2 * DDD); } else { - dhh += psr->legfontsize*FUDGE+2*DDD; + dhh += psr->legfontsize * FUDGE + 2 * DDD; } if (psr->X.major > 0) { - dhh += psr->X.tickfontsize*FUDGE+2*DDD+psr->X.majorticklen; + dhh += psr->X.tickfontsize * FUDGE + 2 * DDD + psr->X.majorticklen; } else if (psr->X.minor > 0) { dhh += psr->X.minorticklen; } - hh += (mat.size()-1)*box_dh(psr); + hh += (mat.size() - 1) * box_dh(psr); hh += box_dh_top(TRUE, psr); if (mat.size() > 1) { - hh += (mat.size()-1)*box_dh_top(FALSE, psr); + hh += (mat.size() - 1) * box_dh_top(FALSE, psr); } } *w = ww; @@ -601,26 +628,27 @@ static void box_dim(gmx::ArrayRef mat, *dh = dhh; } -static std::vector add_maps(gmx::ArrayRef map1, - gmx::ArrayRef map2) +static std::vector add_maps(gmx::ArrayRef map1, gmx::ArrayRef map2) { - static char mapper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<.>/?"; + static char mapper[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+{}|;:',<" + ".>/?"; std::vector map(map1.size() + map2.size()); - size_t nsymbols = std::strlen(mapper); - if (map.size() > nsymbols*nsymbols) + size_t nsymbols = std::strlen(mapper); + if (map.size() > nsymbols * nsymbols) { gmx_fatal(FARGS, "Not enough symbols to merge the two colormaps\n"); } - printf("Combining colormaps of %zu and %zu elements into one of %zu elements\n", - map1.size(), map2.size(), map.size()); + printf("Combining colormaps of %zu and %zu elements into one of %zu elements\n", map1.size(), + map2.size(), map.size()); gmx::index k = 0; for (gmx::index j = 0; j < gmx::ssize(map1) && k < gmx::ssize(map); ++j, ++k) { map[k].code.c1 = mapper[k % nsymbols]; if (map.size() > nsymbols) { - map[k].code.c2 = mapper[k/nsymbols]; + map[k].code.c2 = mapper[k / nsymbols]; } map[k].rgb.r = map1[j].rgb.r; map[k].rgb.g = map1[j].rgb.g; @@ -632,7 +660,7 @@ static std::vector add_maps(gmx::ArrayRef map1, map[k].code.c1 = mapper[k % nsymbols]; if (map.size() > nsymbols) { - map[k].code.c2 = mapper[k/nsymbols]; + map[k].code.c2 = mapper[k / nsymbols]; } map[k].rgb.r = map2[j].rgb.r; map[k].rgb.g = map2[j].rgb.g; @@ -643,22 +671,24 @@ static std::vector add_maps(gmx::ArrayRef map1, return map; } -static bool operator==(const t_mapping &lhs, const t_mapping &rhs) +static bool operator==(const t_mapping& lhs, const t_mapping& rhs) { return (lhs.rgb.r == rhs.rgb.r && lhs.rgb.g == rhs.rgb.g && lhs.rgb.b == rhs.rgb.b); } -static void xpm_mat(const char *outf, +static void xpm_mat(const char* outf, gmx::ArrayRef mat, gmx::ArrayRef mat2, - gmx_bool bDiag, gmx_bool bFirstDiag) + gmx_bool bDiag, + gmx_bool bFirstDiag) { - FILE *out; - int x, y, col; + FILE* out; + int x, y, col; out = gmx_ffopen(outf, "w"); - GMX_RELEASE_ASSERT(mat.size() == mat2.size(), "Combined matrix write requires matrices of the same size"); + GMX_RELEASE_ASSERT(mat.size() == mat2.size(), + "Combined matrix write requires matrices of the same size"); for (gmx::index i = 0; i != gmx::ssize(mat); ++i) { // Color maps that differ only in RGB value are considered different @@ -691,7 +721,7 @@ static void xpm_mat(const char *outf, } } } - mat[i].map = map; + mat[i].map = map; if (mat[i].title != mat2[i].title) { mat[i].title += " / " + mat2[i].title; @@ -706,22 +736,21 @@ static void xpm_mat(const char *outf, gmx_ffclose(out); } -static void tick_spacing(int n, real axis[], real offset, char axisnm, - real *major, real *minor) +static void tick_spacing(int n, real axis[], real offset, char axisnm, real* major, real* minor) { real space; gmx_bool bTryAgain; int i, j, t, f = 0, ten; #define NFACT 4 - real major_fact[NFACT] = {5, 4, 2, 1}; - real minor_fact[NFACT] = {5, 4, 4, 5}; + real major_fact[NFACT] = { 5, 4, 2, 1 }; + real minor_fact[NFACT] = { 5, 4, 4, 5 }; /* start with interval between 10 matrix points: */ - space = std::max(10*axis[1]-axis[0], axis[std::min(10, n-1)]-axis[0]); + space = std::max(10 * axis[1] - axis[0], axis[std::min(10, n - 1)] - axis[0]); /* get power of 10 */ - ten = static_cast(std::ceil(std::log(space)/std::log(10.0))-1); + ten = static_cast(std::ceil(std::log(space) / std::log(10.0)) - 1); bTryAgain = TRUE; - for (t = ten+2; t > ten-3 && bTryAgain; t--) + for (t = ten + 2; t > ten - 3 && bTryAgain; t--) { for (f = 0; f < NFACT && bTryAgain; f++) { @@ -730,55 +759,61 @@ static void tick_spacing(int n, real axis[], real offset, char axisnm, i = 0; for (j = 0; j < n; j++) { - if (bRmod(axis[j], offset, space) ) + if (bRmod(axis[j], offset, space)) { i++; } } /* do we have a reasonable number of ticks ? */ - bTryAgain = (i > std::min(10, n-1)) || (i < 5); + bTryAgain = (i > std::min(10, n - 1)) || (i < 5); } } if (bTryAgain) { - space = std::max(10*axis[1]-axis[0], axis[std::min(10, n-1)]-axis[0]); - fprintf(stderr, "Auto tick spacing failed for %c-axis, guessing %g\n", - axisnm, space); + space = std::max(10 * axis[1] - axis[0], axis[std::min(10, n - 1)] - axis[0]); + fprintf(stderr, "Auto tick spacing failed for %c-axis, guessing %g\n", axisnm, space); } *major = space; - *minor = space / minor_fact[(f > 0) ? f-1 : 0]; - fprintf(stderr, "Auto tick spacing for %c-axis: major %g, minor %g\n", - axisnm, *major, *minor); + *minor = space / minor_fact[(f > 0) ? f - 1 : 0]; + fprintf(stderr, "Auto tick spacing for %c-axis: major %g, minor %g\n", axisnm, *major, *minor); } -static void ps_mat(const char *outf, +static void ps_mat(const char* outf, gmx::ArrayRef mat, gmx::ArrayRef mat2, - gmx_bool bFrame, gmx_bool bDiag, gmx_bool bFirstDiag, - gmx_bool bTitle, gmx_bool bTitleOnce, gmx_bool bYonce, int elegend, - real size, real boxx, real boxy, const char *m2p, const char *m2pout, - int mapoffset) + gmx_bool bFrame, + gmx_bool bDiag, + gmx_bool bFirstDiag, + gmx_bool bTitle, + gmx_bool bTitleOnce, + gmx_bool bYonce, + int elegend, + real size, + real boxx, + real boxy, + const char* m2p, + const char* m2pout, + int mapoffset) { - t_psrec psrec, *psr; - int W, H; - int x, y, col; - real x0, y0, xx; - real w, h, dw, dh; - gmx_bool bMap1, bNextMap1, bDiscrete; + t_psrec psrec, *psr; + int W, H; + int x, y, col; + real x0, y0, xx; + real w, h, dw, dh; + gmx_bool bMap1, bNextMap1, bDiscrete; try { get_params(m2p, m2pout, &psrec); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR psr = &psrec; if (psr->X.major <= 0) { tick_spacing((mat[0].flags & MAT_SPATIAL_X) ? mat[0].nx + 1 : mat[0].nx, - mat[0].axis_x.data(), psr->X.offset, 'X', - &(psr->X.major), &(psr->X.minor) ); + mat[0].axis_x.data(), psr->X.offset, 'X', &(psr->X.major), &(psr->X.minor)); } if (psr->X.minor <= 0) { @@ -787,8 +822,7 @@ static void ps_mat(const char *outf, if (psr->Y.major <= 0) { tick_spacing((mat[0].flags & MAT_SPATIAL_Y) ? mat[0].ny + 1 : mat[0].ny, - mat[0].axis_y.data(), psr->Y.offset, 'Y', - &(psr->Y.major), &(psr->Y.minor) ); + mat[0].axis_y.data(), psr->Y.offset, 'Y', &(psr->Y.major), &(psr->Y.minor)); } if (psr->Y.minor <= 0) { @@ -807,18 +841,18 @@ static void ps_mat(const char *outf, if (psr->xboxsize == 0) { - psr->xboxsize = size/mat[0].nx; + psr->xboxsize = size / mat[0].nx; printf("Set the x-size of the box to %.3f\n", psr->xboxsize); } if (psr->yboxsize == 0) { - psr->yboxsize = size/mat[0].nx; + psr->yboxsize = size / mat[0].nx; printf("Set the y-size of the box to %.3f\n", psr->yboxsize); } gmx::ArrayRef map1; - int legendIndex = 0; - for (const auto &m : mat) + int legendIndex = 0; + for (const auto& m : mat) { if (m.map.size() > map1.size()) { @@ -833,7 +867,7 @@ static void ps_mat(const char *outf, gmx::ArrayRef map2; if (!mat2.empty()) { - for (const auto &m : mat2) + for (const auto& m : mat2) { if (m.map.size() > map2.size()) { @@ -851,7 +885,7 @@ static void ps_mat(const char *outf, mat[0].legend = psr->leglabel; } - bTitle = bTitle && !mat.back().title.empty(); + bTitle = bTitle && !mat.back().title.empty(); bTitleOnce = bTitleOnce && !mat.back().title.empty(); psr->bTitle = bTitle; psr->bTitleOnce = bTitleOnce; @@ -861,18 +895,18 @@ static void ps_mat(const char *outf, box_dim(mat, mat2, psr, elegend, bFrame, &w, &h, &dw, &dh); /* Set up bounding box */ - W = static_cast(w+dw); - H = static_cast(h+dh); + W = static_cast(w + dw); + H = static_cast(h + dh); /* Start box at */ x0 = dw; y0 = dh; - x = static_cast(W+psr->xoffs); - y = static_cast(H+psr->yoffs); + x = static_cast(W + psr->xoffs); + y = static_cast(H + psr->yoffs); if (bFrame) { - x += 5*DDD; - y += 4*DDD; + x += 5 * DDD; + y += 4 * DDD; } t_psdata out = ps_open(outf, 0, 0, x, y); ps_linewidth(&out, static_cast(psr->linewidth)); @@ -888,7 +922,7 @@ static void ps_mat(const char *outf, for (gmx::index i = 0; i != gmx::ssize(mat); ++i) { - if (bTitle || (bTitleOnce && i == gmx::ssize(mat)-1) ) + if (bTitle || (bTitleOnce && i == gmx::ssize(mat) - 1)) { /* Print title, if any */ ps_rgb(&out, BLACK); @@ -902,8 +936,7 @@ static void ps_mat(const char *outf, { buf = mat[i].title + " / " + mat2[i].title; } - ps_ctext(&out, x0+w/2, y0+box_height(mat[i], psr)+psr->titfontsize, - buf, eXCenter); + ps_ctext(&out, x0 + w / 2, y0 + box_height(mat[i], psr) + psr->titfontsize, buf, eXCenter); } ps_comment(&out, gmx::formatString("Here starts the filling of box #%zd", i).c_str()); for (x = 0; (x < mat[i].nx); x++) @@ -911,7 +944,7 @@ static void ps_mat(const char *outf, int nexty; int nextcol; - xx = x0+x*psr->xboxsize; + xx = x0 + x * psr->xboxsize; ps_moveto(&out, xx, y0); y = 0; bMap1 = (mat2.empty() || (x < y || (x == y && bFirstDiag))); @@ -936,18 +969,18 @@ static void ps_mat(const char *outf, { nextcol = mat[i].matrix(x, nexty); } - if ( (nexty == mat[i].ny) || (col != nextcol) || (bMap1 != bNextMap1) ) + if ((nexty == mat[i].ny) || (col != nextcol) || (bMap1 != bNextMap1)) { if (col >= 0) { if (bMap1) { - ps_rgb_nbox(&out, &(mat[i].map[col].rgb), nexty-y); + ps_rgb_nbox(&out, &(mat[i].map[col].rgb), nexty - y); } else { assert(!mat2.empty()); - ps_rgb_nbox(&out, &(mat2[i].map[col].rgb), nexty-y); + ps_rgb_nbox(&out, &(mat2[i].map[col].rgb), nexty - y); } } else @@ -960,7 +993,7 @@ static void ps_mat(const char *outf, } } } - y0 += box_height(mat[i], psr)+box_dh(psr)+box_dh_top(i+1 == gmx::ssize(mat), psr); + y0 += box_height(mat[i], psr) + box_dh(psr) + box_dh_top(i + 1 == gmx::ssize(mat), psr); } if (psr->X.lineatzero || psr->Y.lineatzero) @@ -991,21 +1024,19 @@ static void ps_mat(const char *outf, } if (bDiscrete) { - leg_discrete(&out, psr->legfontsize, DDD, legend, - psr->legfontsize, psr->legfont, leg_map); + leg_discrete(&out, psr->legfontsize, DDD, legend, psr->legfontsize, psr->legfont, leg_map); } else { if (elegend != elBoth) { - leg_continuous(&out, x0+w/2, w/2, DDD, legend, - psr->legfontsize, psr->legfont, leg_map, - mapoffset); + leg_continuous(&out, x0 + w / 2, w / 2, DDD, legend, psr->legfontsize, psr->legfont, + leg_map, mapoffset); } else { assert(!mat2.empty()); - leg_bicontinuous(&out, x0+w/2, w, DDD, mat[0].legend, mat2[0].legend, + leg_bicontinuous(&out, x0 + w / 2, w, DDD, mat[0].legend, mat2[0].legend, psr->legfontsize, psr->legfont, map1, map2); } } @@ -1017,7 +1048,7 @@ static void ps_mat(const char *outf, static void make_axis_labels(gmx::ArrayRef mat1) { - for (auto &m : mat1) + for (auto& m : mat1) { /* Make labels for x axis */ if (m.axis_x.empty()) @@ -1034,16 +1065,14 @@ static void make_axis_labels(gmx::ArrayRef mat1) } } -static void prune_mat(gmx::ArrayRef mat, - gmx::ArrayRef mat2, - int skip) +static void prune_mat(gmx::ArrayRef mat, gmx::ArrayRef mat2, int skip) { - GMX_RELEASE_ASSERT(mat.size() == mat2.size(), "Matrix pruning requires matrices of the same size"); + GMX_RELEASE_ASSERT(mat.size() == mat2.size(), + "Matrix pruning requires matrices of the same size"); for (gmx::index i = 0; i != gmx::ssize(mat); ++i) { - fprintf(stderr, "converting %dx%d matrix to %dx%d\n", - mat[i].nx, mat[i].ny, - (mat[i].nx+skip-1)/skip, (mat[i].ny+skip-1)/skip); + fprintf(stderr, "converting %dx%d matrix to %dx%d\n", mat[i].nx, mat[i].ny, + (mat[i].nx + skip - 1) / skip, (mat[i].ny + skip - 1) / skip); /* walk through matrix */ int xs = 0; for (int x = 0; (x < mat[i].nx); x++) @@ -1080,18 +1109,17 @@ static void prune_mat(gmx::ArrayRef mat, } } /* adjust parameters */ - mat[i].nx = (mat[i].nx+skip-1)/skip; - mat[i].ny = (mat[i].ny+skip-1)/skip; + mat[i].nx = (mat[i].nx + skip - 1) / skip; + mat[i].ny = (mat[i].ny + skip - 1) / skip; if (!mat2.empty()) { - mat2[i].nx = (mat2[i].nx+skip-1)/skip; - mat2[i].ny = (mat2[i].ny+skip-1)/skip; + mat2[i].nx = (mat2[i].nx + skip - 1) / skip; + mat2[i].ny = (mat2[i].ny + skip - 1) / skip; } } } -static void zero_lines(gmx::ArrayRef mat, - gmx::ArrayRef mat2) +static void zero_lines(gmx::ArrayRef mat, gmx::ArrayRef mat2) { GMX_RELEASE_ASSERT(mat.size() == mat2.size(), "zero_lines requires matrices of the same size"); for (gmx::index i = 0; i != gmx::ssize(mat); ++i) @@ -1107,9 +1135,9 @@ static void zero_lines(gmx::ArrayRef mat, { mats = mat2; } - for (int x = 0; x < mats[i].nx-1; x++) + for (int x = 0; x < mats[i].nx - 1; x++) { - if (std::abs(mats[i].axis_x[x+1]) < 1e-5) + if (std::abs(mats[i].axis_x[x + 1]) < 1e-5) { for (int y = 0; y < mats[i].ny; y++) { @@ -1117,9 +1145,9 @@ static void zero_lines(gmx::ArrayRef mat, } } } - for (int y = 0; y < mats[i].ny-1; y++) + for (int y = 0; y < mats[i].ny - 1; y++) { - if (std::abs(mats[i].axis_y[y+1]) < 1e-5) + if (std::abs(mats[i].axis_y[y + 1]) < 1e-5) { for (int x = 0; x < mats[i].nx; x++) { @@ -1131,32 +1159,38 @@ static void zero_lines(gmx::ArrayRef mat, } } -static void write_combined_matrix(int ecombine, const char *fn, +static void write_combined_matrix(int ecombine, + const char* fn, gmx::ArrayRef mat1, gmx::ArrayRef mat2, - const real *cmin, const real *cmax) + const real* cmin, + const real* cmax) { - FILE *out; - real **rmat1, **rmat2; - real rhi, rlo; + FILE* out; + real **rmat1, **rmat2; + real rhi, rlo; out = gmx_ffopen(fn, "w"); - GMX_RELEASE_ASSERT(mat1.size() == mat2.size(), "Combined matrix write requires matrices of the same size"); + GMX_RELEASE_ASSERT(mat1.size() == mat2.size(), + "Combined matrix write requires matrices of the same size"); for (gmx::index k = 0; k != gmx::ssize(mat1); k++) { if (mat2[k].nx != mat1[k].nx || mat2[k].ny != mat1[k].ny) { - gmx_fatal(FARGS, "Size of frame %zd in 1st (%dx%d) and 2nd matrix (%dx%d) do" - " not match.\n", k, mat1[k].nx, mat1[k].ny, mat2[k].nx, mat2[k].ny); + gmx_fatal(FARGS, + "Size of frame %zd in 1st (%dx%d) and 2nd matrix (%dx%d) do" + " not match.\n", + k, mat1[k].nx, mat1[k].ny, mat2[k].nx, mat2[k].ny); } printf("Combining two %dx%d matrices\n", mat1[k].nx, mat1[k].ny); rmat1 = matrix2real(&mat1[k], nullptr); rmat2 = matrix2real(&mat2[k], nullptr); if (nullptr == rmat1 || nullptr == rmat2) { - gmx_fatal(FARGS, "Could not extract real data from %s xpm matrices. Note that, e.g.,\n" + gmx_fatal(FARGS, + "Could not extract real data from %s xpm matrices. Note that, e.g.,\n" "g_rms and g_mdmat provide such data, but not do_dssp.\n", - (nullptr == rmat1 && nullptr == rmat2) ? "both" : "one of the" ); + (nullptr == rmat1 && nullptr == rmat2) ? "both" : "one of the"); } rlo = 1e38; rhi = -1e38; @@ -1166,12 +1200,11 @@ static void write_combined_matrix(int ecombine, const char *fn, { switch (ecombine) { - case ecAdd: rmat1[i][j] += rmat2[i][j]; break; - case ecSub: rmat1[i][j] -= rmat2[i][j]; break; + case ecAdd: rmat1[i][j] += rmat2[i][j]; break; + case ecSub: rmat1[i][j] -= rmat2[i][j]; break; case ecMult: rmat1[i][j] *= rmat2[i][j]; break; - case ecDiv: rmat1[i][j] /= rmat2[i][j]; break; - default: - gmx_fatal(FARGS, "No such combination rule %d for matrices", ecombine); + case ecDiv: rmat1[i][j] /= rmat2[i][j]; break; + default: gmx_fatal(FARGS, "No such combination rule %d for matrices", ecombine); } rlo = std::min(rlo, rmat1[i][j]); rhi = std::max(rhi, rmat1[i][j]); @@ -1188,15 +1221,13 @@ static void write_combined_matrix(int ecombine, const char *fn, int nlevels = static_cast(std::max(mat1[k].map.size(), mat2[k].map.size())); if (rhi == rlo) { - fprintf(stderr, - "combination results in uniform matrix (%g), no output\n", rhi); + fprintf(stderr, "combination results in uniform matrix (%g), no output\n", rhi); } else { - write_xpm(out, mat1[k].flags, mat1[k].title, mat1[k].legend, - mat1[k].label_x, mat1[k].label_y, - mat1[k].nx, mat1[k].ny, mat1[k].axis_x.data(), mat1[k].axis_y.data(), - rmat1, rlo, rhi, white, black, &nlevels); + write_xpm(out, mat1[k].flags, mat1[k].title, mat1[k].legend, mat1[k].label_x, + mat1[k].label_y, mat1[k].nx, mat1[k].ny, mat1[k].axis_x.data(), + mat1[k].axis_y.data(), rmat1, rlo, rhi, white, black, &nlevels); } } gmx_ffclose(out); @@ -1204,25 +1235,40 @@ static void write_combined_matrix(int ecombine, const char *fn, static void do_mat(gmx::ArrayRef mat, gmx::ArrayRef mat2, - gmx_bool bFrame, gmx_bool bZeroLine, gmx_bool bDiag, gmx_bool bFirstDiag, gmx_bool bTitle, - gmx_bool bTitleOnce, gmx_bool bYonce, int elegend, - real size, real boxx, real boxy, - const char *epsfile, const char *xpmfile, const char *m2p, - const char *m2pout, int skip, int mapoffset) + gmx_bool bFrame, + gmx_bool bZeroLine, + gmx_bool bDiag, + gmx_bool bFirstDiag, + gmx_bool bTitle, + gmx_bool bTitleOnce, + gmx_bool bYonce, + int elegend, + real size, + real boxx, + real boxy, + const char* epsfile, + const char* xpmfile, + const char* m2p, + const char* m2pout, + int skip, + int mapoffset) { - GMX_RELEASE_ASSERT(mat.size() == mat2.size(), "Combined matrix write requires matrices of the same size"); + GMX_RELEASE_ASSERT(mat.size() == mat2.size(), + "Combined matrix write requires matrices of the same size"); if (!mat2.empty()) { for (gmx::index k = 0; k != gmx::ssize(mat); k++) { if ((mat2[k].nx != mat[k].nx) || (mat2[k].ny != mat[k].ny)) { - gmx_fatal(FARGS, "WAKE UP!! Size of frame %zd in 2nd matrix file (%dx%d) does not match size of 1st matrix (%dx%d) or the other way around.\n", + gmx_fatal(FARGS, + "WAKE UP!! Size of frame %zd in 2nd matrix file (%dx%d) does not match " + "size of 1st matrix (%dx%d) or the other way around.\n", k, mat2[k].nx, mat2[k].ny, mat[k].nx, mat[k].ny); } for (int j = 0; (j < mat[k].ny); j++) { - for (int i = bFirstDiag ? j+1 : j; (i < mat[k].nx); i++) + for (int i = bFirstDiag ? j + 1 : j; (i < mat[k].nx); i++) { mat[k].matrix(i, j) = mat2[k].matrix(i, j); } @@ -1248,8 +1294,7 @@ static void do_mat(gmx::ArrayRef mat, if (epsfile != nullptr) { - ps_mat(epsfile, mat, mat2, bFrame, bDiag, bFirstDiag, - bTitle, bTitleOnce, bYonce, elegend, + ps_mat(epsfile, mat, mat2, bFrame, bDiag, bFirstDiag, bTitle, bTitleOnce, bYonce, elegend, size, boxx, boxy, m2p, m2pout, mapoffset); } if (xpmfile != nullptr) @@ -1262,19 +1307,19 @@ static void gradient_map(const rvec grad, gmx::ArrayRef map) { int i = 0; real fraction = 1.0 / (map.size() - 1.0); - for (auto &m : map) + for (auto& m : map) { - real c = i*fraction; - m.rgb.r = 1-c*(1-grad[XX]); - m.rgb.g = 1-c*(1-grad[YY]); - m.rgb.b = 1-c*(1-grad[ZZ]); + real c = i * fraction; + m.rgb.r = 1 - c * (1 - grad[XX]); + m.rgb.g = 1 - c * (1 - grad[YY]); + m.rgb.b = 1 - c * (1 - grad[ZZ]); ++i; } } static void gradient_mat(rvec grad, gmx::ArrayRef mat) { - for (auto &m : mat) + for (auto& m : mat) { gradient_map(grad, m.map); } @@ -1282,9 +1327,9 @@ static void gradient_mat(rvec grad, gmx::ArrayRef mat) static void rainbow_map(gmx_bool bBlue, gmx::ArrayRef map) { - for (auto &m : map) + for (auto& m : map) { - real c = (m.rgb.r + m.rgb.g + m.rgb.b)/3; + real c = (m.rgb.r + m.rgb.g + m.rgb.b) / 3; real r, g, b; if (c > 1) { @@ -1297,25 +1342,25 @@ static void rainbow_map(gmx_bool bBlue, gmx::ArrayRef map) if (c <= 0.25) /* 0-0.25 */ { r = 0; - g = std::pow(4.0*c, 2.0/3.0); + g = std::pow(4.0 * c, 2.0 / 3.0); b = 1; } else if (c <= 0.5) /* 0.25-0.5 */ { r = 0; g = 1; - b = std::pow(2.0-4.0*c, 2.0/3.0); + b = std::pow(2.0 - 4.0 * c, 2.0 / 3.0); } else if (c <= 0.75) /* 0.5-0.75 */ { - r = std::pow(4.0*c-2.0, 2.0/3.0); + r = std::pow(4.0 * c - 2.0, 2.0 / 3.0); g = 1; b = 0; } else /* 0.75-1 */ { r = 1; - g = std::pow(4.0-4.0*c, 2.0/3.0); + g = std::pow(4.0 - 4.0 * c, 2.0 / 3.0); b = 0; } m.rgb.r = r; @@ -1326,15 +1371,15 @@ static void rainbow_map(gmx_bool bBlue, gmx::ArrayRef map) static void rainbow_mat(gmx_bool bBlue, gmx::ArrayRef mat) { - for (auto &m : mat) + for (auto& m : mat) { rainbow_map(bBlue, m.map); } } -int gmx_xpm2ps(int argc, char *argv[]) +int gmx_xpm2ps(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] makes a beautiful color plot of an XPixelMap file.", "Labels and axis can be displayed, when they are supplied", "in the correct matrix format.", @@ -1377,72 +1422,88 @@ int gmx_xpm2ps(int argc, char *argv[]) "the [TT]-xpm[tt] option." }; - gmx_output_env_t *oenv; - const char *fn, *epsfile = nullptr, *xpmfile = nullptr; + gmx_output_env_t* oenv; + const char * fn, *epsfile = nullptr, *xpmfile = nullptr; int i, etitle, elegend, ediag, erainbow, ecombine; gmx_bool bTitle, bTitleOnce, bDiag, bFirstDiag, bGrad; static gmx_bool bFrame = TRUE, bZeroLine = FALSE, bYonce = FALSE; - static real size = 400, boxx = 0, boxy = 0, cmin = 0, cmax = 0; - static rvec grad = {0, 0, 0}; - enum { - etSel, etTop, etOnce, etYlabel, etNone, etNR + static real size = 400, boxx = 0, boxy = 0, cmin = 0, cmax = 0; + static rvec grad = { 0, 0, 0 }; + enum + { + etSel, + etTop, + etOnce, + etYlabel, + etNone, + etNR }; - const char *title[] = { nullptr, "top", "once", "ylabel", "none", nullptr }; + const char* title[] = { nullptr, "top", "once", "ylabel", "none", nullptr }; /* MUST correspond to enum elXxx as defined at top of file */ - const char *legend[] = { nullptr, "both", "first", "second", "none", nullptr }; - enum { - edSel, edFirst, edSecond, edNone, edNR + const char* legend[] = { nullptr, "both", "first", "second", "none", nullptr }; + enum + { + edSel, + edFirst, + edSecond, + edNone, + edNR }; - const char *diag[] = { nullptr, "first", "second", "none", nullptr }; - enum { - erSel, erNo, erBlue, erRed, erNR + const char* diag[] = { nullptr, "first", "second", "none", nullptr }; + enum + { + erSel, + erNo, + erBlue, + erRed, + erNR }; - const char *rainbow[] = { nullptr, "no", "blue", "red", nullptr }; + const char* rainbow[] = { nullptr, "no", "blue", "red", nullptr }; /* MUST correspond to enum ecXxx as defined at top of file */ - const char *combine[] = { - nullptr, "halves", "add", "sub", "mult", "div", nullptr - }; + const char* combine[] = { nullptr, "halves", "add", "sub", "mult", "div", nullptr }; static int skip = 1, mapoffset = 0; t_pargs pa[] = { - { "-frame", FALSE, etBOOL, {&bFrame}, - "Display frame, ticks, labels, title and legend" }, - { "-title", FALSE, etENUM, {title}, "Show title at" }, - { "-yonce", FALSE, etBOOL, {&bYonce}, "Show y-label only once" }, - { "-legend", FALSE, etENUM, {legend}, "Show legend" }, - { "-diag", FALSE, etENUM, {diag}, "Diagonal" }, - { "-size", FALSE, etREAL, {&size}, - "Horizontal size of the matrix in ps units" }, - { "-bx", FALSE, etREAL, {&boxx}, + { "-frame", FALSE, etBOOL, { &bFrame }, "Display frame, ticks, labels, title and legend" }, + { "-title", FALSE, etENUM, { title }, "Show title at" }, + { "-yonce", FALSE, etBOOL, { &bYonce }, "Show y-label only once" }, + { "-legend", FALSE, etENUM, { legend }, "Show legend" }, + { "-diag", FALSE, etENUM, { diag }, "Diagonal" }, + { "-size", FALSE, etREAL, { &size }, "Horizontal size of the matrix in ps units" }, + { "-bx", + FALSE, + etREAL, + { &boxx }, "Element x-size, overrides [TT]-size[tt] (also y-size when [TT]-by[tt] is not set)" }, - { "-by", FALSE, etREAL, {&boxy}, "Element y-size" }, - { "-rainbow", FALSE, etENUM, {rainbow}, - "Rainbow colors, convert white to" }, - { "-gradient", FALSE, etRVEC, {grad}, + { "-by", FALSE, etREAL, { &boxy }, "Element y-size" }, + { "-rainbow", FALSE, etENUM, { rainbow }, "Rainbow colors, convert white to" }, + { "-gradient", + FALSE, + etRVEC, + { grad }, "Re-scale colormap to a smooth gradient from white {1,1,1} to {r,g,b}" }, - { "-skip", FALSE, etINT, {&skip}, - "only write out every nr-th row and column" }, - { "-zeroline", FALSE, etBOOL, {&bZeroLine}, - "insert line in [REF].xpm[ref] matrix where axis label is zero"}, - { "-legoffset", FALSE, etINT, {&mapoffset}, + { "-skip", FALSE, etINT, { &skip }, "only write out every nr-th row and column" }, + { "-zeroline", + FALSE, + etBOOL, + { &bZeroLine }, + "insert line in [REF].xpm[ref] matrix where axis label is zero" }, + { "-legoffset", + FALSE, + etINT, + { &mapoffset }, "Skip first N colors from [REF].xpm[ref] file for the legend" }, - { "-combine", FALSE, etENUM, {combine}, "Combine two matrices" }, - { "-cmin", FALSE, etREAL, {&cmin}, "Minimum for combination output" }, - { "-cmax", FALSE, etREAL, {&cmax}, "Maximum for combination output" } + { "-combine", FALSE, etENUM, { combine }, "Combine two matrices" }, + { "-cmin", FALSE, etREAL, { &cmin }, "Minimum for combination output" }, + { "-cmax", FALSE, etREAL, { &cmax }, "Maximum for combination output" } }; #define NPA asize(pa) - t_filenm fnm[] = { - { efXPM, "-f", nullptr, ffREAD }, - { efXPM, "-f2", "root2", ffOPTRD }, - { efM2P, "-di", nullptr, ffLIBOPTRD }, - { efM2P, "-do", "out", ffOPTWR }, - { efEPS, "-o", nullptr, ffOPTWR }, - { efXPM, "-xpm", nullptr, ffOPTWR } - }; + t_filenm fnm[] = { { efXPM, "-f", nullptr, ffREAD }, { efXPM, "-f2", "root2", ffOPTRD }, + { efM2P, "-di", nullptr, ffLIBOPTRD }, { efM2P, "-do", "out", ffOPTWR }, + { efEPS, "-o", nullptr, ffOPTWR }, { efXPM, "-xpm", nullptr, ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, - NFILE, fnm, NPA, pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_VIEW, NFILE, fnm, NPA, pa, asize(desc), desc, 0, + nullptr, &oenv)) { return 0; } @@ -1484,22 +1545,25 @@ int gmx_xpm2ps(int argc, char *argv[]) fprintf(stderr, "WARNING: can only write result of arithmetic combination " "of two matrices to .xpm file\n" - " file %s will not be written\n", epsfile); + " file %s will not be written\n", + epsfile); epsfile = nullptr; } bDiag = ediag != edNone; bFirstDiag = ediag != edSecond; - fn = opt2fn("-f", NFILE, fnm); + fn = opt2fn("-f", NFILE, fnm); std::vector mat, mat2; mat = read_xpm_matrix(fn); - fprintf(stderr, "There %s %zu matri%s in %s\n", (mat.size() > 1) ? "are" : "is", mat.size(), (mat.size() > 1) ? "ces" : "x", fn); + fprintf(stderr, "There %s %zu matri%s in %s\n", (mat.size() > 1) ? "are" : "is", mat.size(), + (mat.size() > 1) ? "ces" : "x", fn); fn = opt2fn_null("-f2", NFILE, fnm); if (fn) { mat2 = read_xpm_matrix(fn); - fprintf(stderr, "There %s %zu matri%s in %s\n", (mat2.size() > 1) ? "are" : "is", mat2.size(), (mat2.size() > 1) ? "ces" : "x", fn); + fprintf(stderr, "There %s %zu matri%s in %s\n", (mat2.size() > 1) ? "are" : "is", + mat2.size(), (mat2.size() > 1) ? "ces" : "x", fn); if (mat.size() != mat2.size()) { fprintf(stderr, "Different number of matrices, using the smallest number.\n"); @@ -1528,11 +1592,11 @@ int gmx_xpm2ps(int argc, char *argv[]) bTitleOnce = etitle == etOnce; if (etitle == etYlabel) { - for (auto &m : mat) + for (auto& m : mat) { m.label_y = m.title; } - for (auto &m : mat2) + for (auto& m : mat2) { m.label_y = m.title; } @@ -1561,17 +1625,14 @@ int gmx_xpm2ps(int argc, char *argv[]) if (ecombine && ecombine != ecHalves) { - write_combined_matrix(ecombine, xpmfile, mat, mat2, - opt2parg_bSet("-cmin", NPA, pa) ? &cmin : nullptr, + write_combined_matrix(ecombine, xpmfile, mat, mat2, opt2parg_bSet("-cmin", NPA, pa) ? &cmin : nullptr, opt2parg_bSet("-cmax", NPA, pa) ? &cmax : nullptr); } else { - do_mat(mat, mat2, bFrame, bZeroLine, bDiag, bFirstDiag, - bTitle, bTitleOnce, bYonce, - elegend, size, boxx, boxy, epsfile, xpmfile, - opt2fn_null("-di", NFILE, fnm), opt2fn_null("-do", NFILE, fnm), skip, - mapoffset); + do_mat(mat, mat2, bFrame, bZeroLine, bDiag, bFirstDiag, bTitle, bTitleOnce, bYonce, elegend, + size, boxx, boxy, epsfile, xpmfile, opt2fn_null("-di", NFILE, fnm), + opt2fn_null("-do", NFILE, fnm), skip, mapoffset); } view_all(oenv, NFILE, fnm); diff --git a/src/gromacs/gmxana/gstat.h b/src/gromacs/gmxana/gstat.h index 7abb9717bc..405228ef80 100644 --- a/src/gromacs/gmxana/gstat.h +++ b/src/gromacs/gmxana/gstat.h @@ -44,47 +44,60 @@ struct gmx_output_env_t; class ResidueType; /* must correspond with 'leg' g_chi.c:727 */ -enum { - edPhi = 0, edPsi, edOmega, edChi1, edChi2, edChi3, edChi4, edChi5, edChi6, edMax +enum +{ + edPhi = 0, + edPsi, + edOmega, + edChi1, + edChi2, + edChi3, + edChi4, + edChi5, + edChi6, + edMax }; -enum { - edPrintST = 0, edPrintRO +enum +{ + edPrintST = 0, + edPrintRO }; #define NHISTO 360 #define NONCHI 3 -#define MAXCHI (edMax-NONCHI) -#define NROT 4 /* number of rotamers: 1=g(-), 2=t, 3=g(+), 0=other */ +#define MAXCHI (edMax - NONCHI) +#define NROT 4 /* number of rotamers: 1=g(-), 2=t, 3=g(+), 0=other */ -typedef struct { - int minCalpha, minC, H, N, C, O, Cn[MAXCHI+3]; +typedef struct +{ + int minCalpha, minC, H, N, C, O, Cn[MAXCHI + 3]; } t_dihatms; /* Cn[0]=N, Cn[1]=Ca, Cn[2]=Cb etc. */ -typedef struct { - char name[12]; - int resnr; - int index; /* Index for amino acids (histograms) */ - int j0[edMax]; /* Index in dih array (phi angle is first...) */ - t_dihatms atm; - int b[edMax]; - int ntr[edMax]; - real S2[edMax]; - real rot_occ[edMax][NROT]; +typedef struct +{ + char name[12]; + int resnr; + int index; /* Index for amino acids (histograms) */ + int j0[edMax]; /* Index in dih array (phi angle is first...) */ + t_dihatms atm; + int b[edMax]; + int ntr[edMax]; + real S2[edMax]; + real rot_occ[edMax][NROT]; } t_dlist; -typedef struct { - const char *name; /* Description of the J coupling constant */ +typedef struct +{ + const char* name; /* Description of the J coupling constant */ real A, B, C; /* Karplus coefficients */ real offset; /* Offset for dihedral angle in histogram (e.g. -M_PI/3) */ real Jc; /* Resulting Jcoupling */ real Jcsig; /* Standard deviation in Jc */ } t_karplus; -void calc_distribution_props(int nh, const int histo[], - real start, int nkkk, t_karplus kkk[], - real *S2); +void calc_distribution_props(int nh, const int histo[], real start, int nkkk, t_karplus kkk[], real* S2); /* This routine takes a dihedral distribution and calculates * coupling constants and dihedral order parameters of it. * @@ -108,10 +121,15 @@ void calc_distribution_props(int nh, const int histo[], * */ -void ana_dih_trans(const char *fn_trans, const char *fn_histo, - real **dih, int nframes, int nangles, - const char *grpname, real *time, gmx_bool bRb, - const gmx_output_env_t *oenv); +void ana_dih_trans(const char* fn_trans, + const char* fn_histo, + real** dih, + int nframes, + int nangles, + const char* grpname, + real* time, + gmx_bool bRb, + const gmx_output_env_t* oenv); /* * Analyse dihedral transitions, by counting transitions per dihedral * and per frame. The total number of transitions is printed to @@ -135,12 +153,22 @@ void ana_dih_trans(const char *fn_trans, const char *fn_histo, * (trans = 0) */ -void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, - gmx_bool bHisto, const char *fn_histo, int maxchi, - real **dih, int nlist, t_dlist dlist[], - int nframes, int nangles, const char *grpname, - int multiplicity[], real *time, gmx_bool bRb, - real core_frac, const gmx_output_env_t *oenv); +void low_ana_dih_trans(gmx_bool bTrans, + const char* fn_trans, + gmx_bool bHisto, + const char* fn_histo, + int maxchi, + real** dih, + int nlist, + t_dlist dlist[], + int nframes, + int nangles, + const char* grpname, + int multiplicity[], + real* time, + gmx_bool bRb, + real core_frac, + const gmx_output_env_t* oenv); /* as above but passes dlist so can copy occupancies into it, and multiplicity[] * (1..nangles, corresp to dih[this][], so can have non-3 multiplicity of * rotamers. Also production of xvg output files is conditional @@ -149,16 +177,21 @@ void low_ana_dih_trans(gmx_bool bTrans, const char *fn_trans, * to each rotamer, the rest goes to rotamer zero */ - -void read_ang_dih(const char *trj_fn, - gmx_bool bAngles, gmx_bool bSaveAll, gmx_bool bRb, gmx_bool bPBC, - int maxangstat, int angstat[], - int *nframes, real **time, - int isize, int index[], - real **trans_frac, - real **aver_angle, - real *dih[], - const gmx_output_env_t *oenv); +void read_ang_dih(const char* trj_fn, + gmx_bool bAngles, + gmx_bool bSaveAll, + gmx_bool bRb, + gmx_bool bPBC, + int maxangstat, + int angstat[], + int* nframes, + real** time, + int isize, + int index[], + real** trans_frac, + real** aver_angle, + real* dih[], + const gmx_output_env_t* oenv); /* * Read a trajectory and calculate angles and dihedrals. * @@ -180,9 +213,7 @@ void read_ang_dih(const char *trj_fn, * dih all angles at each time frame */ -void make_histo(FILE *log, - int ndata, real data[], int npoints, int histo[], - real minx, real maxx); +void make_histo(FILE* log, int ndata, real data[], int npoints, int histo[], real minx, real maxx); /* * Make a histogram from data. The min and max of the data array can * be determined (if minx == 0 and maxx == 0) @@ -212,43 +243,73 @@ void normalize_histo(int npoints, const int histo[], real dx, real normhisto[]); /* Routines from pp2shift (anadih.c etc.) */ -void do_pp2shifts(FILE *fp, int nframes, - int nlist, t_dlist dlist[], real **dih); +void do_pp2shifts(FILE* fp, int nframes, int nlist, t_dlist dlist[], real** dih); -gmx_bool has_dihedral(int Dih, t_dlist *dl); +gmx_bool has_dihedral(int Dih, t_dlist* dl); -t_dlist *mk_dlist(FILE *log, - const t_atoms *atoms, int *nlist, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bHChi, - int maxchi, int r0, ResidueType *rt); +t_dlist* mk_dlist(FILE* log, + const t_atoms* atoms, + int* nlist, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bHChi, + int maxchi, + int r0, + ResidueType* rt); -void pr_dlist(FILE *fp, int nl, t_dlist dl[], real dt, int printtype, - gmx_bool bPhi, gmx_bool bPsi, gmx_bool bChi, gmx_bool bOmega, int maxchi); +void pr_dlist(FILE* fp, + int nl, + t_dlist dl[], + real dt, + int printtype, + gmx_bool bPhi, + gmx_bool bPsi, + gmx_bool bChi, + gmx_bool bOmega, + int maxchi); -int pr_trans(FILE *fp, int nl, t_dlist dl[], real dt, int Xi); +int pr_trans(FILE* fp, int nl, t_dlist dl[], real dt, int Xi); -void mk_chi_lookup (int **lookup, int maxchi, - int nlist, t_dlist dlist[]); +void mk_chi_lookup(int** lookup, int maxchi, int nlist, t_dlist dlist[]); -void mk_multiplicity_lookup (int *multiplicity, int maxchi, - int nlist, t_dlist dlist[], int nangle); +void mk_multiplicity_lookup(int* multiplicity, int maxchi, int nlist, t_dlist dlist[], int nangle); -void get_chi_product_traj (real **dih, int nframes, - int nlist, int maxchi, t_dlist dlist[], - real time[], int **lookup, int *multiplicity, - gmx_bool bRb, gmx_bool bNormalize, - real core_frac, gmx_bool bAll, const char *fnall, - const gmx_output_env_t *oenv); +void get_chi_product_traj(real** dih, + int nframes, + int nlist, + int maxchi, + t_dlist dlist[], + real time[], + int** lookup, + int* multiplicity, + gmx_bool bRb, + gmx_bool bNormalize, + real core_frac, + gmx_bool bAll, + const char* fnall, + const gmx_output_env_t* oenv); -void print_one (const gmx_output_env_t *oenv, const char *base, - const char *name, - const char *title, const char *ylabel, int nf, - real time[], real data[]); +void print_one(const gmx_output_env_t* oenv, + const char* base, + const char* name, + const char* title, + const char* ylabel, + int nf, + real time[], + real data[]); /* Routines from g_hbond */ -void analyse_corr(int n, real t[], real ct[], real nt[], real kt[], - real sigma_ct[], real sigma_nt[], real sigma_kt[], - real fit_start, real temp); +void analyse_corr(int n, + real t[], + real ct[], + real nt[], + real kt[], + real sigma_ct[], + real sigma_nt[], + real sigma_kt[], + real fit_start, + real temp); void compute_derivative(int nn, const real x[], const real y[], real dydx[]); diff --git a/src/gromacs/gmxana/hxprops.cpp b/src/gromacs/gmxana/hxprops.cpp index 94a6671d87..102141b006 100644 --- a/src/gromacs/gmxana/hxprops.cpp +++ b/src/gromacs/gmxana/hxprops.cpp @@ -55,34 +55,25 @@ real ellipticity(int nres, t_bb bb[]) { - typedef struct { + typedef struct + { real phi, psi, w; } t_ppwstr; // Avoid warnings about narrowing conversions from double to real #ifdef _MSC_VER -#pragma warning(disable: 4838) +# pragma warning(disable : 4838) #endif - static const t_ppwstr ppw[] = { - { -67, -44, 0.31 }, - { -66, -41, 0.31 }, - { -59, -44, 0.44 }, - { -57, -47, 0.56 }, - { -53, -52, 0.78 }, - { -48, -57, 1.00 }, - { -70.5, -35.8, 0.15 }, - { -57, -79, 0.23 }, - { -38, -78, 1.20 }, - { -60, -30, 0.24 }, - { -54, -28, 0.46 }, - { -44, -33, 0.68 } - }; + static const t_ppwstr ppw[] = { { -67, -44, 0.31 }, { -66, -41, 0.31 }, { -59, -44, 0.44 }, + { -57, -47, 0.56 }, { -53, -52, 0.78 }, { -48, -57, 1.00 }, + { -70.5, -35.8, 0.15 }, { -57, -79, 0.23 }, { -38, -78, 1.20 }, + { -60, -30, 0.24 }, { -54, -28, 0.46 }, { -44, -33, 0.68 } }; #ifdef _MSC_VER -#pragma warning(default: 4838) +# pragma warning(default : 4838) #endif #define NPPW asize(ppw) - int i, j; - real ell, pp2, phi, psi; + int i, j; + real ell, pp2, phi, psi; ell = 0; for (i = 0; (i < nres); i++) @@ -91,7 +82,7 @@ real ellipticity(int nres, t_bb bb[]) psi = bb[i].psi; for (j = 0; (j < NPPW); j++) { - pp2 = gmx::square(phi-ppw[j].phi)+gmx::square(psi-ppw[j].psi); + pp2 = gmx::square(phi - ppw[j].phi) + gmx::square(psi - ppw[j].psi); if (pp2 < 64) { bb[i].nhx++; @@ -108,12 +99,12 @@ real ahx_len(int gnx, const int index[], rvec x[]) { rvec dx; - rvec_sub(x[index[0]], x[index[gnx-1]], dx); + rvec_sub(x[index[0]], x[index[gnx - 1]], dx); return norm(dx); } -real radius(FILE *fp, int nca, const int ca_index[], rvec x[]) +real radius(FILE* fp, int nca, const int ca_index[], rvec x[]) /* Assume we have all the backbone */ { real dl2, dlt; @@ -123,7 +114,7 @@ real radius(FILE *fp, int nca, const int ca_index[], rvec x[]) for (i = 0; (i < nca); i++) { ai = ca_index[i]; - dl2 = gmx::square(x[ai][XX])+gmx::square(x[ai][YY]); + dl2 = gmx::square(x[ai][XX]) + gmx::square(x[ai][YY]); if (fp) { @@ -137,7 +128,7 @@ real radius(FILE *fp, int nca, const int ca_index[], rvec x[]) fprintf(fp, "\n"); } - return std::sqrt(dlt/nca); + return std::sqrt(dlt / nca); } static real rot(rvec x1, const rvec x2) @@ -148,10 +139,10 @@ static real rot(rvec x1, const rvec x2) phi1 = std::atan2(x1[YY], x1[XX]); cp = std::cos(phi1); sp = std::sin(phi1); - xx = cp*x2[XX]+sp*x2[YY]; - yy = -sp*x2[XX]+cp*x2[YY]; + xx = cp * x2[XX] + sp * x2[YY]; + yy = -sp * x2[XX] + cp * x2[YY]; - dphi = RAD2DEG*std::atan2(yy, xx); + dphi = RAD2DEG * std::atan2(yy, xx); return dphi; } @@ -173,10 +164,10 @@ real twist(int nca, const int caindex[], rvec x[]) dphi += 360; } pt += dphi; - a0 = a1; + a0 = a1; } - return (pt/(nca-1)); + return (pt / (nca - 1)); } real ca_phi(int gnx, const int index[], rvec x[]) @@ -192,20 +183,18 @@ real ca_phi(int gnx, const int index[], rvec x[]) } phitot = 0; - for (i = 0; (i < gnx-4); i++) + for (i = 0; (i < gnx - 4); i++) { - ai = index[i+0]; - aj = index[i+1]; - ak = index[i+2]; - al = index[i+3]; - phi = RAD2DEG* - dih_angle(x[ai], x[aj], x[ak], x[al], nullptr, - r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); + ai = index[i + 0]; + aj = index[i + 1]; + ak = index[i + 2]; + al = index[i + 3]; + phi = RAD2DEG + * dih_angle(x[ai], x[aj], x[ak], x[al], nullptr, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); phitot += phi; } - return (phitot/(gnx-4.0)); + return (phitot / (gnx - 4.0)); } real dip(int nbb, int const bbind[], const rvec x[], const t_atom atom[]) @@ -221,7 +210,7 @@ real dip(int nbb, int const bbind[], const rvec x[], const t_atom atom[]) q = atom[ai].q; for (m = 0; (m < DIM); m++) { - dipje[m] += x[ai][m]*q; + dipje[m] += x[ai][m] * q; } } return norm(dipje); @@ -238,37 +227,34 @@ real rise(int gnx, const int index[], rvec x[]) ztot = 0; for (i = 1; (i < gnx); i++) { - ai = index[i]; - z = x[ai][ZZ]; - ztot += (z-z0); - z0 = z; + ai = index[i]; + z = x[ai][ZZ]; + ztot += (z - z0); + z0 = z; } - return (ztot/(gnx-1.0)); + return (ztot / (gnx - 1.0)); } -void av_hblen(FILE *fp3, FILE *fp3a, - FILE *fp4, FILE *fp4a, - FILE *fp5, FILE *fp5a, - real t, int nres, t_bb bb[]) +void av_hblen(FILE* fp3, FILE* fp3a, FILE* fp4, FILE* fp4a, FILE* fp5, FILE* fp5a, real t, int nres, t_bb bb[]) { int i, n3 = 0, n4 = 0, n5 = 0; real d3 = 0, d4 = 0, d5 = 0; - for (i = 0; (i < nres-3); i++) + for (i = 0; (i < nres - 3); i++) { if (bb[i].bHelix) { - fprintf(fp3a, "%10g", bb[i].d3); + fprintf(fp3a, "%10g", bb[i].d3); n3++; d3 += bb[i].d3; - if (i < nres-4) + if (i < nres - 4) { fprintf(fp4a, "%10g", bb[i].d4); n4++; d4 += bb[i].d4; } - if (i < nres-5) + if (i < nres - 5) { fprintf(fp5a, "%10g", bb[i].d5); n5++; @@ -276,17 +262,15 @@ void av_hblen(FILE *fp3, FILE *fp3a, } } } - fprintf(fp3, "%10g %10g\n", t, d3/n3); - fprintf(fp4, "%10g %10g\n", t, d4/n4); - fprintf(fp5, "%10g %10g\n", t, d5/n5); + fprintf(fp3, "%10g %10g\n", t, d3 / n3); + fprintf(fp4, "%10g %10g\n", t, d4 / n4); + fprintf(fp5, "%10g %10g\n", t, d5 / n5); fprintf(fp3a, "\n"); fprintf(fp4a, "\n"); fprintf(fp5a, "\n"); - } -void av_phipsi(FILE *fphi, FILE *fpsi, FILE *fphi2, FILE *fpsi2, - real t, int nres, t_bb bb[]) +void av_phipsi(FILE* fphi, FILE* fpsi, FILE* fphi2, FILE* fpsi2, real t, int nres, t_bb bb[]) { int i, n = 0; real phi = 0, psi = 0; @@ -304,8 +288,8 @@ void av_phipsi(FILE *fphi, FILE *fpsi, FILE *fphi2, FILE *fpsi2, n++; } } - fprintf(fphi, "%10g %10g\n", t, (phi/n)); - fprintf(fpsi, "%10g %10g\n", t, (psi/n)); + fprintf(fphi, "%10g %10g\n", t, (phi / n)); + fprintf(fpsi, "%10g %10g\n", t, (psi / n)); fprintf(fphi2, "\n"); fprintf(fpsi2, "\n"); } @@ -317,12 +301,12 @@ static void set_ahcity(int nbb, t_bb bb[]) for (n = 0; (n < nbb); n++) { - pp2 = gmx::square(bb[n].phi-PHI_AHX)+gmx::square(bb[n].psi-PSI_AHX); + pp2 = gmx::square(bb[n].phi - PHI_AHX) + gmx::square(bb[n].psi - PSI_AHX); bb[n].bHelix = FALSE; if (pp2 < 2500) { - if ((bb[n].d4 < 0.36) || ((n > 0) && bb[n-1].bHelix)) + if ((bb[n].d4 < 0.36) || ((n > 0) && bb[n - 1].bHelix)) { bb[n].bHelix = TRUE; } @@ -330,16 +314,21 @@ static void set_ahcity(int nbb, t_bb bb[]) } } -t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, - int *nall, int **index, - char ***atomname, t_atom atom[], - t_resinfo *resinfo) +t_bb* mkbbind(const char* fn, + int* nres, + int* nbb, + int res0, + int* nall, + int** index, + char*** atomname, + t_atom atom[], + t_resinfo* resinfo) { - static const char * bb_nm[] = { "N", "H", "CA", "C", "O", "HN" }; + static const char* bb_nm[] = { "N", "H", "CA", "C", "O", "HN" }; #define NBB asize(bb_nm) - t_bb *bb; - char *grpname; - int ai, i, i0, i1, j, k, rnr, gnx, r0, r1; + t_bb* bb; + char* grpname; + int ai, i, i0, i1, j, k, rnr, gnx, r0, r1; fprintf(stderr, "Please select a group containing the entire backbone\n"); rd_index(fn, 1, &gnx, index, &grpname); @@ -351,12 +340,13 @@ t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, r0 = std::min(r0, atom[(*index)[i]].resind); r1 = std::max(r1, atom[(*index)[i]].resind); } - rnr = r1-r0+1; + rnr = r1 - r0 + 1; fprintf(stderr, "There are %d residues\n", rnr); snew(bb, rnr); for (i = 0; (i < rnr); i++) { - bb[i].N = bb[i].H = bb[i].CA = bb[i].C = bb[i].O = -1; bb[i].resno = res0+i; + bb[i].N = bb[i].H = bb[i].CA = bb[i].C = bb[i].O = -1; + bb[i].resno = res0 + i; } for (i = j = 0; (i < gnx); i++) @@ -366,7 +356,7 @@ t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, int resindex = atom[ai].resind; // Create an index into the residues present in the selected // index group. - int bbindex = resindex -r0; + int bbindex = resindex - r0; if (std::strcmp(*(resinfo[resindex].name), "PRO") == 0) { // For PRO in a peptide, there is no H bound to backbone @@ -385,42 +375,31 @@ t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, } switch (k) { - case 0: - bb[bbindex].N = ai; - break; + case 0: bb[bbindex].N = ai; break; case 1: case 5: /* No attempt to address the case where some weird input has both H and HN atoms in the group */ bb[bbindex].H = ai; break; - case 2: - bb[bbindex].CA = ai; - break; - case 3: - bb[bbindex].C = ai; - break; - case 4: - bb[bbindex].O = ai; - break; - default: - break; + case 2: bb[bbindex].CA = ai; break; + case 3: bb[bbindex].C = ai; break; + case 4: bb[bbindex].O = ai; break; + default: break; } } for (i0 = 0; (i0 < rnr); i0++) { - if ((bb[i0].N != -1) && (bb[i0].H != -1) && - (bb[i0].CA != -1) && - (bb[i0].C != -1) && (bb[i0].O != -1)) + if ((bb[i0].N != -1) && (bb[i0].H != -1) && (bb[i0].CA != -1) && (bb[i0].C != -1) + && (bb[i0].O != -1)) { break; } } - for (i1 = rnr-1; (i1 >= 0); i1--) + for (i1 = rnr - 1; (i1 >= 0); i1--) { - if ((bb[i1].N != -1) && (bb[i1].H != -1) && - (bb[i1].CA != -1) && - (bb[i1].C != -1) && (bb[i1].O != -1)) + if ((bb[i1].N != -1) && (bb[i1].H != -1) && (bb[i1].CA != -1) && (bb[i1].C != -1) + && (bb[i1].O != -1)) { break; } @@ -429,19 +408,19 @@ t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, { i0++; } - if (i1 == rnr-1) + if (i1 == rnr - 1) { i1--; } for (i = i0; (i < i1); i++) { - bb[i].Cprev = bb[i-1].C; - bb[i].Nnext = bb[i+1].N; + bb[i].Cprev = bb[i - 1].C; + bb[i].Nnext = bb[i + 1].N; } - rnr = std::max(0, i1-i0+1); - fprintf(stderr, "There are %d complete backbone residues (from %d to %d)\n", - rnr, bb[i0].resno, bb[i1].resno); + rnr = std::max(0, i1 - i0 + 1); + fprintf(stderr, "There are %d complete backbone residues (from %d to %d)\n", rnr, bb[i0].resno, + bb[i1].resno); if (rnr == 0) { gmx_fatal(FARGS, "Zero complete backbone residues were found, cannot proceed"); @@ -459,12 +438,12 @@ t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, } *nres = rnr; - *nbb = rnr*asize(bb_nm); + *nbb = rnr * asize(bb_nm); return bb; } -real pprms(FILE *fp, int nbb, t_bb bb[]) +real pprms(FILE* fp, int nbb, t_bb bb[]) { int i, n; real rms, rmst, rms2; @@ -474,7 +453,7 @@ real pprms(FILE *fp, int nbb, t_bb bb[]) { if (bb[i].bHelix) { - rms = std::sqrt(bb[i].pprms2); + rms = std::sqrt(bb[i].pprms2); rmst += rms; rms2 += bb[i].pprms2; fprintf(fp, "%10g ", rms); @@ -482,7 +461,7 @@ real pprms(FILE *fp, int nbb, t_bb bb[]) } } fprintf(fp, "\n"); - rms = std::sqrt(rms2/n-gmx::square(rmst/n)); + rms = std::sqrt(rms2 / n - gmx::square(rmst / n)); return rms; } @@ -496,80 +475,67 @@ void calc_hxprops(int nres, t_bb bb[], const rvec x[]) { ao = bb[i].O; bb[i].d4 = bb[i].d3 = bb[i].d5 = 0; - if (i < nres-3) + if (i < nres - 3) { - an = bb[i+3].N; + an = bb[i + 3].N; rvec_sub(x[ao], x[an], dx); bb[i].d3 = norm(dx); } - if (i < nres-4) + if (i < nres - 4) { - an = bb[i+4].N; + an = bb[i + 4].N; rvec_sub(x[ao], x[an], dx); bb[i].d4 = norm(dx); } - if (i < nres-5) + if (i < nres - 5) { - an = bb[i+5].N; + an = bb[i + 5].N; rvec_sub(x[ao], x[an], dx); bb[i].d5 = norm(dx); } - bb[i].phi = RAD2DEG* - dih_angle(x[bb[i].Cprev], x[bb[i].N], x[bb[i].CA], x[bb[i].C], nullptr, - r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); - bb[i].psi = RAD2DEG* - dih_angle(x[bb[i].N], x[bb[i].CA], x[bb[i].C], x[bb[i].Nnext], nullptr, - r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); - bb[i].pprms2 = gmx::square(bb[i].phi-PHI_AHX)+gmx::square(bb[i].psi-PSI_AHX); - - bb[i].jcaha += - 1.4*std::sin((bb[i].psi+138.0)*DEG2RAD) - - 4.1*std::cos(2.0*DEG2RAD*(bb[i].psi+138.0)) + - 2.0*std::cos(2.0*DEG2RAD*(bb[i].phi+30.0)); + bb[i].phi = RAD2DEG + * dih_angle(x[bb[i].Cprev], x[bb[i].N], x[bb[i].CA], x[bb[i].C], nullptr, r_ij, + r_kj, r_kl, m, n, &t1, &t2, &t3); + bb[i].psi = RAD2DEG + * dih_angle(x[bb[i].N], x[bb[i].CA], x[bb[i].C], x[bb[i].Nnext], nullptr, r_ij, + r_kj, r_kl, m, n, &t1, &t2, &t3); + bb[i].pprms2 = gmx::square(bb[i].phi - PHI_AHX) + gmx::square(bb[i].psi - PSI_AHX); + + bb[i].jcaha += 1.4 * std::sin((bb[i].psi + 138.0) * DEG2RAD) + - 4.1 * std::cos(2.0 * DEG2RAD * (bb[i].psi + 138.0)) + + 2.0 * std::cos(2.0 * DEG2RAD * (bb[i].phi + 30.0)); } } -static void check_ahx(int nres, t_bb bb[], - int *hstart, int *hend) +static void check_ahx(int nres, t_bb bb[], int* hstart, int* hend) { - int h0, h1, h0sav, h1sav; + int h0, h1, h0sav, h1sav; set_ahcity(nres, bb); h0 = h0sav = h1sav = 0; do { - for (; (!bb[h0].bHelix) && (h0 < nres-4); h0++) - { - ; - } - for (h1 = h0; bb[h1+1].bHelix && (h1 < nres-1); h1++) - { - ; - } + for (; (!bb[h0].bHelix) && (h0 < nres - 4); h0++) {} + for (h1 = h0; bb[h1 + 1].bHelix && (h1 < nres - 1); h1++) {} if (h1 > h0) { /*fprintf(stderr,"Helix from %d to %d\n",h0,h1);*/ - if (h1-h0 > h1sav-h0sav) + if (h1 - h0 > h1sav - h0sav) { h0sav = h0; h1sav = h1; } } - h0 = h1+1; - } - while (h1 < nres-1); + h0 = h1 + 1; + } while (h1 < nres - 1); *hstart = h0sav; *hend = h1sav; } -void do_start_end(int nres, t_bb bb[], int *nbb, int bbindex[], - int *nca, int caindex[], - gmx_bool bRange, int rStart, int rEnd) +void do_start_end(int nres, t_bb bb[], int* nbb, int bbindex[], int* nca, int caindex[], gmx_bool bRange, int rStart, int rEnd) { - int i, j, hstart = 0, hend = 0; + int i, j, hstart = 0, hend = 0; if (bRange) { @@ -594,34 +560,32 @@ void do_start_end(int nres, t_bb bb[], int *nbb, int bbindex[], /* Find start and end of longest helix fragment */ check_ahx(nres, bb, &hstart, &hend); } - fprintf(stderr, "helix from: %d through %d\n", - bb[hstart].resno, bb[hend].resno); + fprintf(stderr, "helix from: %d through %d\n", bb[hstart].resno, bb[hend].resno); for (j = 0, i = hstart; (i <= hend); i++) { - bbindex[j++] = bb[i].N; - bbindex[j++] = bb[i].H; - bbindex[j++] = bb[i].CA; - bbindex[j++] = bb[i].C; - bbindex[j++] = bb[i].O; - caindex[i-hstart] = bb[i].CA; + bbindex[j++] = bb[i].N; + bbindex[j++] = bb[i].H; + bbindex[j++] = bb[i].CA; + bbindex[j++] = bb[i].C; + bbindex[j++] = bb[i].O; + caindex[i - hstart] = bb[i].CA; } *nbb = j; - *nca = (hend-hstart+1); + *nca = (hend - hstart + 1); } -void pr_bb(FILE *fp, int nres, t_bb bb[]) +void pr_bb(FILE* fp, int nres, t_bb bb[]) { int i; fprintf(fp, "\n"); - fprintf(fp, "%3s %3s %3s %3s %3s %7s %7s %7s %7s %7s %3s\n", - "AA", "N", "Ca", "C", "O", "Phi", "Psi", "D3", "D4", "D5", "Hx?"); + fprintf(fp, "%3s %3s %3s %3s %3s %7s %7s %7s %7s %7s %3s\n", "AA", "N", "Ca", "C", "O", "Phi", + "Psi", "D3", "D4", "D5", "Hx?"); for (i = 0; (i < nres); i++) { - fprintf(fp, "%3d %3d %3d %3d %3d %7.2f %7.2f %7.3f %7.3f %7.3f %3s\n", - bb[i].resno, bb[i].N, bb[i].CA, bb[i].C, bb[i].O, - bb[i].phi, bb[i].psi, bb[i].d3, bb[i].d4, bb[i].d5, + fprintf(fp, "%3d %3d %3d %3d %3d %7.2f %7.2f %7.3f %7.3f %7.3f %3s\n", bb[i].resno, bb[i].N, + bb[i].CA, bb[i].C, bb[i].O, bb[i].phi, bb[i].psi, bb[i].d3, bb[i].d4, bb[i].d5, bb[i].bHelix ? "Yes" : "No"); } fprintf(fp, "\n"); diff --git a/src/gromacs/gmxana/hxprops.h b/src/gromacs/gmxana/hxprops.h index 8ceb5d06e4..6799aa9552 100644 --- a/src/gromacs/gmxana/hxprops.h +++ b/src/gromacs/gmxana/hxprops.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,55 +54,70 @@ struct t_resinfo; /*! \internal \brief Struct containing properties of a residue in a protein backbone. */ -struct t_bb { +struct t_bb +{ //! Protein backbone phi angle. - real phi; + real phi; //! Protein backbone psi angle. - real psi; + real psi; //! RMS distance of phi and psi angles from ideal helix - real pprms2; + real pprms2; //! Estimated J-coupling value - real jcaha; + real jcaha; //! Value of 3 turn helix? - real d3; + real d3; //! Value of 4 turn helix? - real d4; + real d4; //! Value of 5 turn? - real d5; + real d5; //! Average of RMS for analysis. - real rmsa; + real rmsa; //! If the structure is helical. gmx_bool bHelix; //! Number of elliptical elements - int nhx; + int nhx; //! Average RMS Deviation when atoms of this residue are fitted to ideal helix - int nrms; + int nrms; //! Residue index for output, relative to gmx_helix -r0 value - int resno; + int resno; //! Index for previous carbon. - int Cprev; + int Cprev; //! Index for backbone nitrogen. - int N; + int N; //! Index for backbone NH hydrogen. - int H; + int H; //! Index for alpha carbon. - int CA; + int CA; //! Index for carbonyl carbon. - int C; + int C; //! Index for carbonyl oxygen. - int O; + int O; //! Index for next backbone nitrogen. - int Nnext; + int Nnext; //! Name for this residue. - char label[32]; + char label[32]; }; -enum { - efhRAD, efhTWIST, efhRISE, efhLEN, - efhDIP, efhRMS, efhRMSA, efhCD222, - efhPPRMS, efhCPHI, efhPHI, efhPSI, - efhHB3, efhHB4, efhHB5, efhJCA, - efhAHX, efhNR +enum +{ + efhRAD, + efhTWIST, + efhRISE, + efhLEN, + efhDIP, + efhRMS, + efhRMSA, + efhCD222, + efhPPRMS, + efhCPHI, + efhPHI, + efhPSI, + efhHB3, + efhHB4, + efhHB5, + efhJCA, + efhAHX, + efhNR }; extern real ahx_len(int gnx, const int index[], rvec x[]); @@ -110,13 +125,13 @@ extern real ahx_len(int gnx, const int index[], rvec x[]); extern real ellipticity(int nres, t_bb bb[]); -extern real radius(FILE *fp, int nca, const int ca_index[], rvec x[]); +extern real radius(FILE* fp, int nca, const int ca_index[], rvec x[]); /* Assume we have calphas */ extern real twist(int nca, const int caindex[], rvec x[]); /* Calculate the twist of the helix */ -extern real pprms(FILE *fp, int nbb, t_bb bb[]); +extern real pprms(FILE* fp, int nbb, t_bb bb[]); /* Calculate the average RMS from canonical phi/psi values * and the distance per residue */ @@ -129,13 +144,10 @@ extern real dip(int nbb, const int bbind[], const rvec x[], const t_atom atom[]) extern real rise(int gnx, const int index[], rvec x[]); /* Assume we have a list of Calpha atoms only! */ -extern void av_hblen(FILE *fp3, FILE *fp3a, - FILE *fp4, FILE *fp4a, - FILE *fp5, FILE *fp5a, - real t, int nres, t_bb bb[]); +extern void +av_hblen(FILE* fp3, FILE* fp3a, FILE* fp4, FILE* fp4a, FILE* fp5, FILE* fp5a, real t, int nres, t_bb bb[]); -extern void av_phipsi(FILE *fphi, FILE *fpsi, FILE *fphi2, FILE *fpsi2, - real t, int nres, t_bb bb[]); +extern void av_phipsi(FILE* fphi, FILE* fpsi, FILE* fphi2, FILE* fpsi2, real t, int nres, t_bb bb[]); /*! \brief Allocate and fill an array of information about residues in a protein backbone. * @@ -148,17 +160,28 @@ extern void av_phipsi(FILE *fphi, FILE *fpsi, FILE *fphi2, FILE *fpsi2, * * In the output array, the first residue will be numbered starting * from res0. */ -extern t_bb *mkbbind(const char *fn, int *nres, int *nbb, int res0, - int *nall, int **index, - char ***atomname, t_atom atom[], - t_resinfo *resinfo); - -extern void do_start_end(int nres, t_bb bb[], int *nbb, - int bbindex[], int *nca, int caindex[], - gmx_bool bRange, int rStart, int rEnd); +extern t_bb* mkbbind(const char* fn, + int* nres, + int* nbb, + int res0, + int* nall, + int** index, + char*** atomname, + t_atom atom[], + t_resinfo* resinfo); + +extern void do_start_end(int nres, + t_bb bb[], + int* nbb, + int bbindex[], + int* nca, + int caindex[], + gmx_bool bRange, + int rStart, + int rEnd); extern void calc_hxprops(int nres, t_bb bb[], const rvec x[]); -extern void pr_bb(FILE *fp, int nres, t_bb bb[]); +extern void pr_bb(FILE* fp, int nres, t_bb bb[]); #endif diff --git a/src/gromacs/gmxana/interf.h b/src/gromacs/gmxana/interf.h index 435604be74..bcd8b5e5f5 100644 --- a/src/gromacs/gmxana/interf.h +++ b/src/gromacs/gmxana/interf.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,12 +38,13 @@ #include "gromacs/utility/real.h" -typedef struct { +typedef struct +{ real Z; /* Interface height-coordinate */ real t; /* Interface thickness */ } t_interf; -static inline void init_interf(t_interf *surf) +static inline void init_interf(t_interf* surf) { surf->Z = 0; surf->t = 0; diff --git a/src/gromacs/gmxana/nrama.cpp b/src/gromacs/gmxana/nrama.cpp index 689f6c17ee..1efd2f57bf 100644 --- a/src/gromacs/gmxana/nrama.cpp +++ b/src/gromacs/gmxana/nrama.cpp @@ -50,10 +50,10 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static const char *pp_pat[] = { "C", "N", "CA", "C", "N" }; -#define NPP (sizeof(pp_pat)/sizeof(pp_pat[0])) +static const char* pp_pat[] = { "C", "N", "CA", "C", "N" }; +#define NPP (sizeof(pp_pat) / sizeof(pp_pat[0])) -static bool d_comp(const t_dih &a, const t_dih &b) +static bool d_comp(const t_dih& a, const t_dih& b) { if (a.ai[1] < b.ai[1]) { @@ -70,12 +70,12 @@ static bool d_comp(const t_dih &a, const t_dih &b) } -static void calc_dihs(t_xrama *xr) +static void calc_dihs(t_xrama* xr) { - int i, t1, t2, t3; - rvec r_ij, r_kj, r_kl, m, n; - t_dih *dd; - gmx_rmpbc_t gpbc = nullptr; + int i, t1, t2, t3; + rvec r_ij, r_kj, r_kl, m, n; + t_dih* dd; + gmx_rmpbc_t gpbc = nullptr; gpbc = gmx_rmpbc_init(xr->idef, xr->ePBC, xr->natoms); gmx_rmpbc(gpbc, xr->natoms, xr->box, xr->x); @@ -84,14 +84,12 @@ static void calc_dihs(t_xrama *xr) for (i = 0; (i < xr->ndih); i++) { dd = &(xr->dih[i]); - dd->ang = dih_angle(xr->x[dd->ai[0]], xr->x[dd->ai[1]], - xr->x[dd->ai[2]], xr->x[dd->ai[3]], - nullptr, - r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); + dd->ang = dih_angle(xr->x[dd->ai[0]], xr->x[dd->ai[1]], xr->x[dd->ai[2]], xr->x[dd->ai[3]], + nullptr, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); } } -gmx_bool new_data(t_xrama *xr) +gmx_bool new_data(t_xrama* xr) { if (!read_next_x(xr->oenv, xr->traj, &xr->t, xr->x, xr->box)) { @@ -103,7 +101,7 @@ gmx_bool new_data(t_xrama *xr) return TRUE; } -static int find_atom(const char *find, char ***names, int start, int nr) +static int find_atom(const char* find, char*** names, int start, int nr) { int i; @@ -117,25 +115,25 @@ static int find_atom(const char *find, char ***names, int start, int nr) return -1; } -static void add_xr(t_xrama *xr, const int ff[5], const t_atoms *atoms) +static void add_xr(t_xrama* xr, const int ff[5], const t_atoms* atoms) { char buf[12]; int i; - srenew(xr->dih, xr->ndih+2); + srenew(xr->dih, xr->ndih + 2); for (i = 0; (i < 4); i++) { xr->dih[xr->ndih].ai[i] = ff[i]; } for (i = 0; (i < 4); i++) { - xr->dih[xr->ndih+1].ai[i] = ff[i+1]; + xr->dih[xr->ndih + 1].ai[i] = ff[i + 1]; } xr->ndih += 2; - srenew(xr->pp, xr->npp+1); - xr->pp[xr->npp].iphi = xr->ndih-2; - xr->pp[xr->npp].ipsi = xr->ndih-1; + srenew(xr->pp, xr->npp + 1); + xr->pp[xr->npp].iphi = xr->ndih - 2; + xr->pp[xr->npp].ipsi = xr->ndih - 1; xr->pp[xr->npp].bShow = FALSE; sprintf(buf, "%s-%d", *atoms->resinfo[atoms->atom[ff[1]].resind].name, atoms->resinfo[atoms->atom[ff[1]].resind].nr); @@ -143,13 +141,13 @@ static void add_xr(t_xrama *xr, const int ff[5], const t_atoms *atoms) xr->npp++; } -static void get_dih(t_xrama *xr, const t_atoms *atoms) +static void get_dih(t_xrama* xr, const t_atoms* atoms) { int found, ff[NPP]; int i; size_t j; - for (i = 0; (i < atoms->nr); ) + for (i = 0; (i < atoms->nr);) { found = i; for (j = 0; (j < NPP); j++) @@ -158,19 +156,19 @@ static void get_dih(t_xrama *xr, const t_atoms *atoms) { break; } - found = ff[j]+1; + found = ff[j] + 1; } if (j != NPP) { break; } add_xr(xr, ff, atoms); - i = ff[0]+1; + i = ff[0] + 1; } fprintf(stderr, "Found %d phi-psi combinations\n", xr->npp); } -static void min_max(t_xrama *xr) +static void min_max(t_xrama* xr) { int ai, i, j; @@ -193,14 +191,14 @@ static void min_max(t_xrama *xr) } } -static void get_dih_props(t_xrama *xr, const t_idef *idef, int mult) +static void get_dih_props(t_xrama* xr, const t_idef* idef, int mult) { int i, ft, ftype, nra; - t_iatom *ia; - t_dih *dd, key; + t_iatom* ia; + t_dih * dd, key; ia = idef->il[F_PDIHS].iatoms; - for (i = 0; (i < idef->il[F_PDIHS].nr); ) + for (i = 0; (i < idef->il[F_PDIHS].nr);) { ft = ia[0]; ftype = idef->functype[ft]; @@ -213,23 +211,22 @@ static void get_dih_props(t_xrama *xr, const t_idef *idef, int mult) key.ai[1] = ia[2]; key.ai[2] = ia[3]; - dd = std::lower_bound(xr->dih, xr->dih+xr->ndih, key, d_comp); - if (dd < xr->dih+xr->ndih && !d_comp(key, *dd)) + dd = std::lower_bound(xr->dih, xr->dih + xr->ndih, key, d_comp); + if (dd < xr->dih + xr->ndih && !d_comp(key, *dd)) { dd->mult = idef->iparams[ft].pdihs.mult; dd->phi0 = idef->iparams[ft].pdihs.phiA; } - i += nra+1; - ia += nra+1; + i += nra + 1; + ia += nra + 1; } /* Fill in defaults for values not in the topology */ for (i = 0; (i < xr->ndih); i++) { if (xr->dih[i].mult == 0) { - fprintf(stderr, - "Dihedral around %d,%d not found in topology. Using mult=%d\n", + fprintf(stderr, "Dihedral around %d,%d not found in topology. Using mult=%d\n", xr->dih[i].ai[1], xr->dih[i].ai[2], mult); xr->dih[i].mult = mult; xr->dih[i].phi0 = 180; @@ -238,11 +235,9 @@ static void get_dih_props(t_xrama *xr, const t_idef *idef, int mult) } - -t_topology *init_rama(gmx_output_env_t *oenv, const char *infile, - const char *topfile, t_xrama *xr, int mult) +t_topology* init_rama(gmx_output_env_t* oenv, const char* infile, const char* topfile, t_xrama* xr, int mult) { - t_topology *top; + t_topology* top; real t; top = read_top(topfile, &xr->ePBC); diff --git a/src/gromacs/gmxana/nrama.h b/src/gromacs/gmxana/nrama.h index 8b3c54a4ac..6aee0a3e94 100644 --- a/src/gromacs/gmxana/nrama.h +++ b/src/gromacs/gmxana/nrama.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,38 +44,40 @@ struct gmx_output_env_t; -typedef struct { +typedef struct +{ gmx_bool bShow; - char *label; + char* label; int iphi, ipsi; /* point in the dih array of xr... */ } t_phipsi; -typedef struct { - int ai[4]; - int mult; - real phi0; - real ang; +typedef struct +{ + int ai[4]; + int mult; + real phi0; + real ang; } t_dih; -typedef struct { +typedef struct +{ int ndih; - t_dih *dih; + t_dih* dih; int npp; - t_phipsi *pp; - t_trxstatus *traj; + t_phipsi* pp; + t_trxstatus* traj; int natoms; int amin, amax; real t; - rvec *x; + rvec* x; matrix box; - t_idef *idef; + t_idef* idef; int ePBC; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; } t_xrama; -t_topology *init_rama(gmx_output_env_t *oenv, const char *infile, - const char *topfile, t_xrama *xr, int mult); +t_topology* init_rama(gmx_output_env_t* oenv, const char* infile, const char* topfile, t_xrama* xr, int mult); -gmx_bool new_data(t_xrama *xr); +gmx_bool new_data(t_xrama* xr); -#endif /* GMX_GMXANA_NRAMA_H */ +#endif /* GMX_GMXANA_NRAMA_H */ diff --git a/src/gromacs/gmxana/nsfactor.cpp b/src/gromacs/gmxana/nsfactor.cpp index ae3f658096..3c53901f13 100644 --- a/src/gromacs/gmxana/nsfactor.cpp +++ b/src/gromacs/gmxana/nsfactor.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,7 +58,9 @@ void check_binwidth(real binwidth) real smallest_bin = 0.1; if (binwidth < smallest_bin) { - gmx_fatal(FARGS, "Binwidth shouldn't be smaller then smallest bond length (H-H bond ~0.1nm) in a box"); + gmx_fatal(FARGS, + "Binwidth shouldn't be smaller then smallest bond length (H-H bond ~0.1nm) in a " + "box"); } } @@ -78,7 +80,7 @@ void check_mcover(real mcover) } } -void normalize_probability(int n, double *a) +void normalize_probability(int n, double* a) { int i; double norm = 0.0; @@ -92,19 +94,19 @@ void normalize_probability(int n, double *a) } } -gmx_neutron_atomic_structurefactors_t *gmx_neutronstructurefactors_init(const char *datfn) +gmx_neutron_atomic_structurefactors_t* gmx_neutronstructurefactors_init(const char* datfn) { /* read nsfactor.dat */ - char line[STRLEN]; - int nralloc = 10; - int n, p; - int i, line_no; - char atomnm[8]; - double slength; - gmx_neutron_atomic_structurefactors_t *gnsf; + char line[STRLEN]; + int nralloc = 10; + int n, p; + int i, line_no; + char atomnm[8]; + double slength; + gmx_neutron_atomic_structurefactors_t* gnsf; gmx::FilePtr fp = gmx::openLibraryFile(datfn); - line_no = 0; + line_no = 0; /* allocate memory for structure */ snew(gnsf, nralloc); snew(gnsf->atomnm, nralloc); @@ -136,8 +138,7 @@ gmx_neutron_atomic_structurefactors_t *gmx_neutronstructurefactors_init(const ch } else { - fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", - datfn, line_no); + fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", datfn, line_no); } } srenew(gnsf->atomnm, gnsf->nratoms); @@ -148,10 +149,10 @@ gmx_neutron_atomic_structurefactors_t *gmx_neutronstructurefactors_init(const ch return gnsf; } -gmx_sans_t *gmx_sans_init (const t_topology *top, gmx_neutron_atomic_structurefactors_t *gnsf) +gmx_sans_t* gmx_sans_init(const t_topology* top, gmx_neutron_atomic_structurefactors_t* gnsf) { - gmx_sans_t *gsans = nullptr; - int i, j; + gmx_sans_t* gsans = nullptr; + int i, j; /* Try to assing scattering length from nsfactor.dat */ snew(gsans, 1); snew(gsans->slength, top->atoms.nr); @@ -186,30 +187,29 @@ gmx_sans_t *gmx_sans_init (const t_topology *top, gmx_neutron_atomic_structurefa return gsans; } -gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( - gmx_sans_t *gsans, - rvec *x, - matrix box, - const int *index, - int isize, - double binwidth, - gmx_bool bMC, - gmx_bool bNORM, - real mcover, - unsigned int seed) +gmx_radial_distribution_histogram_t* calc_radial_distribution_histogram(gmx_sans_t* gsans, + rvec* x, + matrix box, + const int* index, + int isize, + double binwidth, + gmx_bool bMC, + gmx_bool bNORM, + real mcover, + unsigned int seed) { - gmx_radial_distribution_histogram_t *pr = nullptr; - rvec dist; - double rmax; - int i, j; + gmx_radial_distribution_histogram_t* pr = nullptr; + rvec dist; + double rmax; + int i, j; #if GMX_OPENMP - double **tgr; - int tid; - int nthreads; - gmx::DefaultRandomEngine *trng = nullptr; + double** tgr; + int tid; + int nthreads; + gmx::DefaultRandomEngine* trng = nullptr; #endif - int64_t mc = 0, mc_max; - gmx::DefaultRandomEngine rng(seed); + int64_t mc = 0, mc_max; + gmx::DefaultRandomEngine rng(seed); /* allocate memory for pr */ snew(pr, 1); @@ -225,7 +225,7 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( rmax = norm(dist); - pr->grn = static_cast(std::floor(rmax/pr->binwidth)+1); + pr->grn = static_cast(std::floor(rmax / pr->binwidth) + 1); snew(pr->gr, pr->grn); @@ -234,11 +234,11 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( /* Special case for setting automaticaly number of mc iterations to 1% of total number of direct iterations */ if (mcover == -1) { - mc_max = static_cast(std::floor(0.5*0.01*isize*(isize-1))); + mc_max = static_cast(std::floor(0.5 * 0.01 * isize * (isize - 1))); } else { - mc_max = static_cast(std::floor(0.5*mcover*isize*(isize-1))); + mc_max = static_cast(std::floor(0.5 * mcover * isize * (isize - 1))); } #if GMX_OPENMP nthreads = gmx_omp_get_max_threads(); @@ -249,12 +249,12 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( snew(tgr[i], pr->grn); trng[i].seed(rng()); } - #pragma omp parallel shared(tgr,trng,mc) private(tid,i,j) +# pragma omp parallel shared(tgr, trng, mc) private(tid, i, j) { - gmx::UniformIntDistribution tdist(0, isize-1); + gmx::UniformIntDistribution tdist(0, isize - 1); tid = gmx_omp_get_thread_num(); - /* now starting parallel threads */ - #pragma omp for +/* now starting parallel threads */ +# pragma omp for for (mc = 0; mc < mc_max; mc++) { try @@ -263,10 +263,11 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( j = tdist(trng[tid]); // [0,isize-1] if (i != j) { - tgr[tid][static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]]))/binwidth))] += gsans->slength[index[i]]*gsans->slength[index[j]]; + tgr[tid][static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]])) / binwidth))] += + gsans->slength[index[i]] * gsans->slength[index[j]]; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* collecting data from threads */ @@ -285,14 +286,15 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( sfree(tgr); delete[] trng; #else - gmx::UniformIntDistribution dist(0, isize-1); + gmx::UniformIntDistribution dist(0, isize - 1); for (mc = 0; mc < mc_max; mc++) { i = dist(rng); // [0,isize-1] j = dist(rng); // [0,isize-1] if (i != j) { - pr->gr[static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]]))/binwidth))] += gsans->slength[index[i]]*gsans->slength[index[j]]; + pr->gr[static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]])) / binwidth))] += + gsans->slength[index[i]] * gsans->slength[index[j]]; } } #endif @@ -307,21 +309,22 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( { snew(tgr[i], pr->grn); } - #pragma omp parallel shared(tgr) private(tid,i,j) +# pragma omp parallel shared(tgr) private(tid, i, j) { tid = gmx_omp_get_thread_num(); - /* starting parallel threads */ - #pragma omp for +/* starting parallel threads */ +# pragma omp for for (i = 0; i < isize; i++) { try { for (j = 0; j < i; j++) { - tgr[tid][static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]]))/binwidth))] += gsans->slength[index[i]]*gsans->slength[index[j]]; + tgr[tid][static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]])) / binwidth))] += + gsans->slength[index[i]] * gsans->slength[index[j]]; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* collecating data for pr->gr */ @@ -343,7 +346,8 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( { for (j = 0; j < i; j++) { - pr->gr[static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]]))/binwidth))] += gsans->slength[index[i]]*gsans->slength[index[j]]; + pr->gr[static_cast(std::floor(std::sqrt(distance2(x[index[i]], x[index[j]])) / binwidth))] += + gsans->slength[index[i]] * gsans->slength[index[j]]; } } #endif @@ -358,24 +362,27 @@ gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram ( snew(pr->r, pr->grn); for (i = 0; i < pr->grn; i++) { - pr->r[i] = (pr->binwidth*i+pr->binwidth*0.5); + pr->r[i] = (pr->binwidth * i + pr->binwidth * 0.5); } return pr; } -gmx_static_structurefactor_t *convert_histogram_to_intensity_curve (gmx_radial_distribution_histogram_t *pr, double start_q, double end_q, double q_step) +gmx_static_structurefactor_t* convert_histogram_to_intensity_curve(gmx_radial_distribution_histogram_t* pr, + double start_q, + double end_q, + double q_step) { - gmx_static_structurefactor_t *sq = nullptr; - int i, j; + gmx_static_structurefactor_t* sq = nullptr; + int i, j; /* init data */ snew(sq, 1); - sq->qn = static_cast(std::floor((end_q-start_q)/q_step)); + sq->qn = static_cast(std::floor((end_q - start_q) / q_step)); snew(sq->q, sq->qn); snew(sq->s, sq->qn); for (i = 0; i < sq->qn; i++) { - sq->q[i] = start_q+i*q_step; + sq->q[i] = start_q + i * q_step; } if (start_q == 0.0) @@ -385,7 +392,7 @@ gmx_static_structurefactor_t *convert_histogram_to_intensity_curve (gmx_radial_d { for (j = 0; j < pr->grn; j++) { - sq->s[i] += (pr->gr[j]/pr->r[j])*std::sin(sq->q[i]*pr->r[j]); + sq->s[i] += (pr->gr[j] / pr->r[j]) * std::sin(sq->q[i] * pr->r[j]); } sq->s[i] /= sq->q[i]; } @@ -396,7 +403,7 @@ gmx_static_structurefactor_t *convert_histogram_to_intensity_curve (gmx_radial_d { for (j = 0; j < pr->grn; j++) { - sq->s[i] += (pr->gr[j]/pr->r[j])*std::sin(sq->q[i]*pr->r[j]); + sq->s[i] += (pr->gr[j] / pr->r[j]) * std::sin(sq->q[i] * pr->r[j]); } sq->s[i] /= sq->q[i]; } diff --git a/src/gromacs/gmxana/nsfactor.h b/src/gromacs/gmxana/nsfactor.h index d8550cdd11..df87a98998 100644 --- a/src/gromacs/gmxana/nsfactor.h +++ b/src/gromacs/gmxana/nsfactor.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,55 +41,62 @@ struct t_topology; -typedef struct gmx_neutron_atomic_structurefactors_t { - int nratoms; - int *p; /* proton number */ - int *n; /* neuton number */ - double *slength; /* scattering length in fm */ - char **atomnm; /* atom symbol */ +typedef struct gmx_neutron_atomic_structurefactors_t +{ + int nratoms; + int* p; /* proton number */ + int* n; /* neuton number */ + double* slength; /* scattering length in fm */ + char** atomnm; /* atom symbol */ } gmx_neutron_atomic_structurefactors_t; -typedef struct gmx_sans_t { - const t_topology *top; /* topology */ - double *slength; /* scattering length for this topology */ +typedef struct gmx_sans_t +{ + const t_topology* top; /* topology */ + double* slength; /* scattering length for this topology */ } gmx_sans_t; -typedef struct gmx_radial_distribution_histogram_t { +typedef struct gmx_radial_distribution_histogram_t +{ int grn; /* number of bins */ double binwidth; /* bin size */ - double *r; /* Distances */ - double *gr; /* Probability */ + double* r; /* Distances */ + double* gr; /* Probability */ } gmx_radial_distribution_histogram_t; -typedef struct gmx_static_structurefactor_t { - int qn; /* number of items */ - double *s; /* scattering */ - double *q; /* q vectors */ - double qstep; /* q increment */ +typedef struct gmx_static_structurefactor_t +{ + int qn; /* number of items */ + double* s; /* scattering */ + double* q; /* q vectors */ + double qstep; /* q increment */ } gmx_static_structurefactor_t; void check_binwidth(real binwidth); void check_mcover(real mcover); -void normalize_probability(int n, double *a); +void normalize_probability(int n, double* a); -gmx_neutron_atomic_structurefactors_t *gmx_neutronstructurefactors_init(const char *datfn); +gmx_neutron_atomic_structurefactors_t* gmx_neutronstructurefactors_init(const char* datfn); -gmx_sans_t *gmx_sans_init(const t_topology *top, gmx_neutron_atomic_structurefactors_t *gnsf); +gmx_sans_t* gmx_sans_init(const t_topology* top, gmx_neutron_atomic_structurefactors_t* gnsf); -gmx_radial_distribution_histogram_t *calc_radial_distribution_histogram (gmx_sans_t *gsans, - rvec *x, - matrix box, - const int *index, - int isize, - double binwidth, - gmx_bool bMC, - gmx_bool bNORM, - real mcover, - unsigned int seed); +gmx_radial_distribution_histogram_t* calc_radial_distribution_histogram(gmx_sans_t* gsans, + rvec* x, + matrix box, + const int* index, + int isize, + double binwidth, + gmx_bool bMC, + gmx_bool bNORM, + real mcover, + unsigned int seed); -gmx_static_structurefactor_t *convert_histogram_to_intensity_curve (gmx_radial_distribution_histogram_t *pr, double start_q, double end_q, double q_step); +gmx_static_structurefactor_t* convert_histogram_to_intensity_curve(gmx_radial_distribution_histogram_t* pr, + double start_q, + double end_q, + double q_step); #endif diff --git a/src/gromacs/gmxana/powerspect.cpp b/src/gromacs/gmxana/powerspect.cpp index bf9b4a3349..7a7da61e95 100644 --- a/src/gromacs/gmxana/powerspect.cpp +++ b/src/gromacs/gmxana/powerspect.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,47 +44,45 @@ #include "gromacs/utility/real.h" #include "gromacs/utility/smalloc.h" -static void addtoavgenergy(t_complex *list, real *result, int size, int tsteps) +static void addtoavgenergy(t_complex* list, real* result, int size, int tsteps) { int i; for (i = 0; i < size; i++) { - result[i] += cabs2(list[i])/tsteps; + result[i] += cabs2(list[i]) / tsteps; } - } -void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins, - gmx::ArrayRef outfiles) +void powerspectavg(real*** intftab, int tsteps, int xbins, int ybins, gmx::ArrayRef outfiles) { /*Fourier plans and output;*/ gmx_fft_t fftp; - t_complex *ftspect1; /* Spatial FFT of interface for each time frame and interface ftint[time,xycoord][0], ftintf[time,xycoord][1] for interface 1 and 2 respectively */ - t_complex *ftspect2; - real *pspectavg1; /*power -spectrum 1st interface*/ - real *pspectavg2; /* -------------- 2nd interface*/ - real *temp; - FILE *datfile1, *datfile2; /*data-files with interface data*/ + t_complex* ftspect1; /* Spatial FFT of interface for each time frame and interface ftint[time,xycoord][0], ftintf[time,xycoord][1] for interface 1 and 2 respectively */ + t_complex* ftspect2; + real* pspectavg1; /*power -spectrum 1st interface*/ + real* pspectavg2; /* -------------- 2nd interface*/ + real* temp; + FILE * datfile1, *datfile2; /*data-files with interface data*/ int n; /*time index*/ - int fy = ybins/2+1; /* number of (symmetric) fourier y elements; */ - int rfl = xbins*fy; /*length of real - DFT == Symmetric 2D matrix*/ + int fy = ybins / 2 + 1; /* number of (symmetric) fourier y elements; */ + int rfl = xbins * fy; /*length of real - DFT == Symmetric 2D matrix*/ -/*Prepare data structures for FFT, with time averaging of power spectrum*/ + /*Prepare data structures for FFT, with time averaging of power spectrum*/ if (gmx_fft_init_2d_real(&fftp, xbins, ybins, GMX_FFT_FLAG_NONE) != 0) { gmx_fatal(FARGS, "Error allocating FFT"); } -/*Initialize arrays*/ + /*Initialize arrays*/ snew(ftspect1, rfl); snew(ftspect2, rfl); snew(temp, rfl); snew(pspectavg1, rfl); snew(pspectavg2, rfl); -/*Fouriertransform directly (no normalization or anything)*/ -/*NB! Check carefully indexes here*/ + /*Fouriertransform directly (no normalization or anything)*/ + /*NB! Check carefully indexes here*/ for (n = 0; n < tsteps; n++) { @@ -101,29 +99,27 @@ void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins, datfile1 = gmx_ffopen(outfiles[0], "w"); datfile2 = gmx_ffopen(outfiles[1], "w"); -/*Filling dat files with spectral data*/ + /*Filling dat files with spectral data*/ fprintf(datfile1, "%s\n", "kx\t ky\t\tPower(kx,ky)"); fprintf(datfile2, "%s\n", "kx\t ky\t\tPower(kx,ky)"); for (n = 0; n < rfl; n++) { fprintf(datfile1, "%d\t%d\t %8.6f\n", (n / fy), (n % fy), pspectavg1[n]); - fprintf(datfile2, "%d\t%d\t %8.6f\n", (n /fy), (n % fy), pspectavg2[n]); + fprintf(datfile2, "%d\t%d\t %8.6f\n", (n / fy), (n % fy), pspectavg2[n]); } gmx_ffclose(datfile1); gmx_ffclose(datfile2); sfree(ftspect1); sfree(ftspect2); - } -void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t, int xb, int yb, - gmx::ArrayRef outfiles) +void powerspectavg_intf(t_interf*** if1, t_interf*** if2, int t, int xb, int yb, gmx::ArrayRef outfiles) { - real ***surf; + real*** surf; - int xy = xb*yb; - int i, n; + int xy = xb * yb; + int i, n; snew(surf, 2); snew(surf[0], t); diff --git a/src/gromacs/gmxana/powerspect.h b/src/gromacs/gmxana/powerspect.h index f0eb2ec310..79f4962079 100644 --- a/src/gromacs/gmxana/powerspect.h +++ b/src/gromacs/gmxana/powerspect.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,11 +43,13 @@ #include "gromacs/utility/arrayref.h" #include "gromacs/utility/real.h" -extern void powerspectavg(real ***interface, int t, int xbins, int ybins, - gmx::ArrayRef outfiles); +extern void powerspectavg(real*** interface, int t, int xbins, int ybins, gmx::ArrayRef outfiles); -extern void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t, - int xbins, int ybins, +extern void powerspectavg_intf(t_interf*** if1, + t_interf*** if2, + int t, + int xbins, + int ybins, gmx::ArrayRef outfiles); #endif diff --git a/src/gromacs/gmxana/pp2shift.cpp b/src/gromacs/gmxana/pp2shift.cpp index b05ff8c2d1..d27fe4ea3f 100644 --- a/src/gromacs/gmxana/pp2shift.cpp +++ b/src/gromacs/gmxana/pp2shift.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,13 +49,14 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int nx, ny; real dx, dy; - real **data; + real** data; } t_shiftdata; -static real interpolate(real phi, real psi, t_shiftdata *sd) +static real interpolate(real phi, real psi, t_shiftdata* sd) { int iphi, ipsi, iphi1, ipsi1; real fphi, fpsi, wx0, wx1, wy0, wy1; @@ -67,65 +68,63 @@ static real interpolate(real phi, real psi, t_shiftdata *sd) */ while (phi < 0) { - phi += 2*M_PI; + phi += 2 * M_PI; } while (psi < 0) { - psi += 2*M_PI; + psi += 2 * M_PI; } - phi = 2*M_PI-phi; + phi = 2 * M_PI - phi; - fphi = phi*sd->dx; - fpsi = psi*sd->dy; + fphi = phi * sd->dx; + fpsi = psi * sd->dy; - iphi = static_cast(fphi); - ipsi = static_cast(fpsi); + iphi = static_cast(fphi); + ipsi = static_cast(fpsi); fphi -= iphi; /* Fraction (offset from gridpoint) */ fpsi -= ipsi; - wx0 = 1.0-fphi; + wx0 = 1.0 - fphi; wx1 = fphi; - wy0 = 1.0-fpsi; + wy0 = 1.0 - fpsi; wy1 = fpsi; iphi = iphi % sd->nx; ipsi = ipsi % sd->ny; - iphi1 = (iphi+1) % sd->nx; - ipsi1 = (ipsi+1) % sd->ny; + iphi1 = (iphi + 1) % sd->nx; + ipsi1 = (ipsi + 1) % sd->ny; - return (sd->data[iphi] [ipsi] * wx0*wy0 + - sd->data[iphi1] [ipsi] * wx1*wy0 + - sd->data[iphi] [ipsi1] * wx0*wy1 + - sd->data[iphi1] [ipsi1] * wx1*wy1); + return (sd->data[iphi][ipsi] * wx0 * wy0 + sd->data[iphi1][ipsi] * wx1 * wy0 + + sd->data[iphi][ipsi1] * wx0 * wy1 + sd->data[iphi1][ipsi1] * wx1 * wy1); } -static void dump_sd(const char *fn, t_shiftdata *sd) +static void dump_sd(const char* fn, t_shiftdata* sd) { - FILE *fp; - int i, j; - char buf[256]; - int nnx, nny, nfac = 4, nlevels = 20; - real phi, psi, *x_phi, *y_psi, **newdata; - real lo, hi; - t_rgb rlo = { 1, 0, 0 }, rhi = { 0, 0, 1 }; - - nnx = sd->nx*nfac+1; - nny = sd->ny*nfac+1; + FILE* fp; + int i, j; + char buf[256]; + int nnx, nny, nfac = 4, nlevels = 20; + real phi, psi, *x_phi, *y_psi, **newdata; + real lo, hi; + t_rgb rlo = { 1, 0, 0 }, rhi = { 0, 0, 1 }; + + nnx = sd->nx * nfac + 1; + nny = sd->ny * nfac + 1; snew(x_phi, nnx); snew(y_psi, nny); snew(newdata, nnx); - lo = 100000; + lo = 100000; hi = -100000; for (i = 0; (i < nnx); i++) { snew(newdata[i], nny); - phi = i*2*M_PI/(nnx-1); - x_phi[i] = phi*RAD2DEG-180; + phi = i * 2 * M_PI / (nnx - 1); + x_phi[i] = phi * RAD2DEG - 180; for (j = 0; (j < nny); j++) { - psi = j*2*M_PI/(nny-1); + psi = j * 2 * M_PI / (nny - 1); if (i == 0) { - y_psi[j] = psi*RAD2DEG-180; + y_psi[j] = psi * RAD2DEG - 180; } /*if (((i % nfac) == 0) && ((j % nfac) == 0)) newdata[i][j] = sd->data[i/nfac][j/nfac]; @@ -137,8 +136,7 @@ static void dump_sd(const char *fn, t_shiftdata *sd) } sprintf(buf, "%s.xpm", fn); fp = gmx_ffopen(buf, "w"); - write_xpm(fp, 0, fn, fn, "Phi", "Psi", nnx, nny, - x_phi, y_psi, newdata, lo, hi, rlo, rhi, &nlevels); + write_xpm(fp, 0, fn, fn, "Phi", "Psi", nnx, nny, x_phi, y_psi, newdata, lo, hi, rlo, rhi, &nlevels); for (i = 0; (i < nnx); i++) { sfree(newdata[i]); @@ -148,11 +146,11 @@ static void dump_sd(const char *fn, t_shiftdata *sd) sfree(y_psi); } -static t_shiftdata *read_shifts(const char *fn) +static t_shiftdata* read_shifts(const char* fn) { double xx; int i, j, nx, ny; - t_shiftdata *sd; + t_shiftdata* sd; snew(sd, 1); gmx::FilePtr fp = gmx::openLibraryFile(fn); @@ -163,12 +161,12 @@ static t_shiftdata *read_shifts(const char *fn) GMX_ASSERT(nx > 0, ""); sd->nx = nx; sd->ny = ny; - sd->dx = nx/(2*M_PI); - sd->dy = ny/(2*M_PI); - snew(sd->data, nx+1); + sd->dx = nx / (2 * M_PI); + sd->dy = ny / (2 * M_PI); + snew(sd->data, nx + 1); for (i = 0; (i <= nx); i++) { - snew(sd->data[i], ny+1); + snew(sd->data[i], ny + 1); for (j = 0; (j < ny); j++) { if (i == nx) @@ -196,7 +194,7 @@ static t_shiftdata *read_shifts(const char *fn) } -static void done_shifts(t_shiftdata *sd) +static void done_shifts(t_shiftdata* sd) { int i; @@ -208,7 +206,7 @@ static void done_shifts(t_shiftdata *sd) sfree(sd); } -void do_pp2shifts(FILE *fp, int nf, int nlist, t_dlist dlist[], real **dih) +void do_pp2shifts(FILE* fp, int nf, int nlist, t_dlist dlist[], real** dih) { t_shiftdata *ca_sd, *co_sd, *ha_sd, *cb_sd; int i, j, Phi, Psi; @@ -223,16 +221,15 @@ void do_pp2shifts(FILE *fp, int nf, int nlist, t_dlist dlist[], real **dih) fprintf(fp, "\n *** Chemical shifts from the chemical shift index ***\n"); please_cite(fp, "Wishart98a"); - fprintf(fp, "%12s %10s %10s %10s %10s\n", - "Residue", "delta Ca", "delta Ha", "delta CO", "delta Cb"); + fprintf(fp, "%12s %10s %10s %10s %10s\n", "Residue", "delta Ca", "delta Ha", "delta CO", + "delta Cb"); for (i = 0; (i < nlist); i++) { - if ((has_dihedral(edPhi, &(dlist[i]))) && - (has_dihedral(edPsi, &(dlist[i])))) + if ((has_dihedral(edPhi, &(dlist[i]))) && (has_dihedral(edPsi, &(dlist[i])))) { Phi = dlist[i].j0[edPhi]; Psi = dlist[i].j0[edPsi]; - ca = cb = co = ha = 0; + ca = cb = co = ha = 0; for (j = 0; (j < nf); j++) { phi = dih[Phi][j]; @@ -243,8 +240,8 @@ void do_pp2shifts(FILE *fp, int nf, int nlist, t_dlist dlist[], real **dih) co += interpolate(phi, psi, co_sd); ha += interpolate(phi, psi, ha_sd); } - fprintf(fp, "%12s %10g %10g %10g %10g\n", - dlist[i].name, ca/nf, ha/nf, co/nf, cb/nf); + fprintf(fp, "%12s %10g %10g %10g %10g\n", dlist[i].name, ca / nf, ha / nf, co / nf, + cb / nf); } } fprintf(fp, "\n"); diff --git a/src/gromacs/gmxana/princ.cpp b/src/gromacs/gmxana/princ.cpp index 65987d9d40..330a518fca 100644 --- a/src/gromacs/gmxana/princ.cpp +++ b/src/gromacs/gmxana/princ.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,15 +57,14 @@ static void m_op(matrix mat, rvec x) for (m = 0; (m < DIM); m++) { - xp[m] = mat[m][XX]*x[XX]+mat[m][YY]*x[YY]+mat[m][ZZ]*x[ZZ]; + xp[m] = mat[m][XX] * x[XX] + mat[m][YY] * x[YY] + mat[m][ZZ] * x[ZZ]; } fprintf(stderr, "x %8.3f %8.3f %8.3f\n", x[XX], x[YY], x[ZZ]); fprintf(stderr, "xp %8.3f %8.3f %8.3f\n", xp[XX], xp[YY], xp[ZZ]); - fprintf(stderr, "fac %8.3f %8.3f %8.3f\n", xp[XX]/x[XX], xp[YY]/x[YY], - xp[ZZ]/x[ZZ]); + fprintf(stderr, "fac %8.3f %8.3f %8.3f\n", xp[XX] / x[XX], xp[YY] / x[YY], xp[ZZ] / x[ZZ]); } -static void ptrans(char *s, real **inten, real d[], real e[]) +static void ptrans(char* s, real** inten, real d[], real e[]) { int m; real n, x, y, z; @@ -74,38 +73,37 @@ static void ptrans(char *s, real **inten, real d[], real e[]) x = inten[m][1]; y = inten[m][2]; z = inten[m][3]; - n = x*x+y*y+z*z; - fprintf(stderr, "%8s %8.3f %8.3f %8.3f, norm:%8.3f, d:%8.3f, e:%8.3f\n", - s, x, y, z, std::sqrt(n), d[m], e[m]); + n = x * x + y * y + z * z; + fprintf(stderr, "%8s %8.3f %8.3f %8.3f, norm:%8.3f, d:%8.3f, e:%8.3f\n", s, x, y, z, + std::sqrt(n), d[m], e[m]); } fprintf(stderr, "\n"); } -void t_trans(matrix trans, real d[], real **ev) +void t_trans(matrix trans, real d[], real** ev) { rvec x; int j; for (j = 0; (j < DIM); j++) { - x[XX] = ev[1][j+1]; - x[YY] = ev[2][j+1]; - x[ZZ] = ev[3][j+1]; + x[XX] = ev[1][j + 1]; + x[YY] = ev[2][j + 1]; + x[ZZ] = ev[3][j + 1]; m_op(trans, x); - fprintf(stderr, "d[%d]=%g\n", j, d[j+1]); + fprintf(stderr, "d[%d]=%g\n", j, d[j + 1]); } } #endif -void principal_comp(int n, const int index[], t_atom atom[], rvec x[], - matrix trans, rvec d) +void principal_comp(int n, const int index[], t_atom atom[], rvec x[], matrix trans, rvec d) { int i, j, ai, m, nrot; real mm, rx, ry, rz; double **inten, dd[NDIM], tvec[NDIM], **ev; #ifdef DEBUG - real e[NDIM]; + real e[NDIM]; #endif - real temp; + real temp; snew(inten, NDIM); snew(ev, NDIM); @@ -128,17 +126,17 @@ void principal_comp(int n, const int index[], t_atom atom[], rvec x[], } for (i = 0; (i < n); i++) { - ai = index[i]; - mm = atom[ai].m; - rx = x[ai][XX]; - ry = x[ai][YY]; - rz = x[ai][ZZ]; - inten[0][0] += mm*(gmx::square(ry)+gmx::square(rz)); - inten[1][1] += mm*(gmx::square(rx)+gmx::square(rz)); - inten[2][2] += mm*(gmx::square(rx)+gmx::square(ry)); - inten[1][0] -= mm*(ry*rx); - inten[2][0] -= mm*(rx*rz); - inten[2][1] -= mm*(rz*ry); + ai = index[i]; + mm = atom[ai].m; + rx = x[ai][XX]; + ry = x[ai][YY]; + rz = x[ai][ZZ]; + inten[0][0] += mm * (gmx::square(ry) + gmx::square(rz)); + inten[1][1] += mm * (gmx::square(rx) + gmx::square(rz)); + inten[2][2] += mm * (gmx::square(rx) + gmx::square(ry)); + inten[1][0] -= mm * (ry * rx); + inten[2][0] -= mm * (rx * rz); + inten[2][1] -= mm * (rz * ry); } inten[0][1] = inten[1][0]; inten[0][2] = inten[2][0]; @@ -162,14 +160,24 @@ void principal_comp(int n, const int index[], t_atom atom[], rvec x[], #endif /* Sort eigenvalues in ascending order */ -#define SWAPPER(i) \ - if (std::abs(dd[(i)+1]) < std::abs(dd[i])) { \ - temp = dd[i]; \ - for (j = 0; (j < NDIM); j++) { tvec[j] = ev[j][i]; } \ - dd[i] = dd[(i)+1]; \ - for (j = 0; (j < NDIM); j++) { ev[j][i] = ev[j][(i)+1]; } \ - dd[(i)+1] = temp; \ - for (j = 0; (j < NDIM); j++) { ev[j][(i)+1] = tvec[j]; } \ +#define SWAPPER(i) \ + if (std::abs(dd[(i) + 1]) < std::abs(dd[i])) \ + { \ + temp = dd[i]; \ + for (j = 0; (j < NDIM); j++) \ + { \ + tvec[j] = ev[j][i]; \ + } \ + dd[i] = dd[(i) + 1]; \ + for (j = 0; (j < NDIM); j++) \ + { \ + ev[j][i] = ev[j][(i) + 1]; \ + } \ + dd[(i) + 1] = temp; \ + for (j = 0; (j < NDIM); j++) \ + { \ + ev[j][(i) + 1] = tvec[j]; \ + } \ } SWAPPER(0) SWAPPER(1) @@ -197,10 +205,10 @@ void principal_comp(int n, const int index[], t_atom atom[], rvec x[], sfree(ev); } -void rotate_atoms(int gnx, const int *index, rvec x[], matrix trans) +void rotate_atoms(int gnx, const int* index, rvec x[], matrix trans) { - real xt, yt, zt; - int i, ii; + real xt, yt, zt; + int i, ii; for (i = 0; (i < gnx); i++) { @@ -208,14 +216,13 @@ void rotate_atoms(int gnx, const int *index, rvec x[], matrix trans) xt = x[ii][XX]; yt = x[ii][YY]; zt = x[ii][ZZ]; - x[ii][XX] = trans[XX][XX]*xt+trans[XX][YY]*yt+trans[XX][ZZ]*zt; - x[ii][YY] = trans[YY][XX]*xt+trans[YY][YY]*yt+trans[YY][ZZ]*zt; - x[ii][ZZ] = trans[ZZ][XX]*xt+trans[ZZ][YY]*yt+trans[ZZ][ZZ]*zt; + x[ii][XX] = trans[XX][XX] * xt + trans[XX][YY] * yt + trans[XX][ZZ] * zt; + x[ii][YY] = trans[YY][XX] * xt + trans[YY][YY] * yt + trans[YY][ZZ] * zt; + x[ii][ZZ] = trans[ZZ][XX] * xt + trans[ZZ][YY] * yt + trans[ZZ][ZZ] * zt; } } -real calc_xcm(const rvec x[], int gnx, const int *index, const t_atom *atom, rvec xcm, - gmx_bool bQ) +real calc_xcm(const rvec x[], int gnx, const int* index, const t_atom* atom, rvec xcm, gmx_bool bQ) { int i, ii, m; real m0, tm; @@ -243,7 +250,7 @@ real calc_xcm(const rvec x[], int gnx, const int *index, const t_atom *atom, rve tm += m0; for (m = 0; (m < DIM); m++) { - xcm[m] += m0*x[ii][m]; + xcm[m] += m0 * x[ii][m]; } } for (m = 0; (m < DIM); m++) @@ -254,8 +261,7 @@ real calc_xcm(const rvec x[], int gnx, const int *index, const t_atom *atom, rve return tm; } -real sub_xcm(rvec x[], int gnx, const int *index, const t_atom atom[], rvec xcm, - gmx_bool bQ) +real sub_xcm(rvec x[], int gnx, const int* index, const t_atom atom[], rvec xcm, gmx_bool bQ) { int i, ii; real tm; @@ -269,9 +275,9 @@ real sub_xcm(rvec x[], int gnx, const int *index, const t_atom atom[], rvec xcm, return tm; } -void add_xcm(rvec x[], int gnx, const int *index, rvec xcm) +void add_xcm(rvec x[], int gnx, const int* index, rvec xcm) { - int i, ii; + int i, ii; for (i = 0; (i < gnx); i++) { @@ -280,12 +286,11 @@ void add_xcm(rvec x[], int gnx, const int *index, rvec xcm) } } -void orient_princ(const t_atoms *atoms, int isize, const int *index, - int natoms, rvec x[], rvec *v, rvec d) +void orient_princ(const t_atoms* atoms, int isize, const int* index, int natoms, rvec x[], rvec* v, rvec d) { - int i, m; - rvec xcm, prcomp; - matrix trans; + int i, m; + rvec xcm, prcomp; + matrix trans; calc_xcm(x, isize, index, atoms->atom, xcm, FALSE); for (i = 0; i < natoms; i++) diff --git a/src/gromacs/gmxana/princ.h b/src/gromacs/gmxana/princ.h index 36ec41f3d2..021b341c77 100644 --- a/src/gromacs/gmxana/princ.h +++ b/src/gromacs/gmxana/princ.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,31 +47,27 @@ struct t_atoms; void rotate_atoms(int gnx, const int index[], rvec x[], matrix trans); /* Rotate all atoms in index using matrix trans */ -void principal_comp(int n, const int index[], t_atom atom[], rvec x[], - matrix trans, rvec d); +void principal_comp(int n, const int index[], t_atom atom[], rvec x[], matrix trans, rvec d); /* Calculate the principal components of atoms in index. Atoms are * mass weighted. It is assumed that the center of mass is in the origin! */ -void orient_princ(const t_atoms *atoms, int isize, const int *index, - int natoms, rvec x[], rvec *v, rvec d); +void orient_princ(const t_atoms* atoms, int isize, const int* index, int natoms, rvec x[], rvec* v, rvec d); /* rotates molecule to align principal axes with coordinate axes */ -real calc_xcm(const rvec x[], int gnx, const int *index, const t_atom *atom, rvec xcm, - gmx_bool bQ); +real calc_xcm(const rvec x[], int gnx, const int* index, const t_atom* atom, rvec xcm, gmx_bool bQ); /* Calculate the center of mass of the atoms in index. if bQ then the atoms * will be charge weighted rather than mass weighted. * Returns the total mass/charge. */ -real sub_xcm(rvec x[], int gnx, const int *index, const t_atom atom[], rvec xcm, - gmx_bool bQ); +real sub_xcm(rvec x[], int gnx, const int* index, const t_atom atom[], rvec xcm, gmx_bool bQ); /* Calc. the center of mass and subtract it from all coordinates. * Returns the original center of mass in xcm * Returns the total mass */ -void add_xcm(rvec x[], int gnx, const int *index, rvec xcm); +void add_xcm(rvec x[], int gnx, const int* index, rvec xcm); /* Increment all atoms in index with xcm */ #endif diff --git a/src/gromacs/gmxana/sfactor.cpp b/src/gromacs/gmxana/sfactor.cpp index caeca37850..0f9035a670 100644 --- a/src/gromacs/gmxana/sfactor.cpp +++ b/src/gromacs/gmxana/sfactor.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,19 +61,21 @@ #include "gromacs/utility/strdb.h" -typedef struct gmx_structurefactors { - int nratoms; - int *p; /* proton number */ - int *n; /* neutron number */ +typedef struct gmx_structurefactors +{ + int nratoms; + int* p; /* proton number */ + int* n; /* neutron number */ /* Parameters for the Cromer Mann fit */ - real **a; /* parameter a */ - real **b; /* parameter b */ - real *c; /* parameter c */ - char **atomnm; /* atomname */ + real** a; /* parameter a */ + real** b; /* parameter b */ + real* c; /* parameter c */ + char** atomnm; /* atomname */ } gmx_structurefactors; -typedef struct reduced_atom{ +typedef struct reduced_atom +{ rvec x; int t; } reduced_atom; @@ -81,32 +83,32 @@ typedef struct reduced_atom{ typedef struct structure_factor { - int n_angles; - int n_groups; - double lambda; - double energy; - double momentum; - double ref_k; - double **F; - int nSteps; - int total_n_atoms; + int n_angles; + int n_groups; + double lambda; + double energy; + double momentum; + double ref_k; + double** F; + int nSteps; + int total_n_atoms; } structure_factor; -extern int * create_indexed_atom_type (reduced_atom_t * atm, int size) +extern int* create_indexed_atom_type(reduced_atom_t* atm, int size) { -/* - * create an index of the atom types found in a group - * i.e.: for water index_atp[0]=type_number_of_O and - * index_atp[1]=type_number_of_H - * - * the last element is set to 0 - */ - int *index_atp, i, i_tmp, j; + /* + * create an index of the atom types found in a group + * i.e.: for water index_atp[0]=type_number_of_O and + * index_atp[1]=type_number_of_H + * + * the last element is set to 0 + */ + int *index_atp, i, i_tmp, j; - reduced_atom *att = static_cast(atm); + reduced_atom* att = static_cast(atm); - snew (index_atp, 1); + snew(index_atp, 1); i_tmp = 1; index_atp[0] = att[0].t; for (i = 1; i < size; i++) @@ -121,55 +123,59 @@ extern int * create_indexed_atom_type (reduced_atom_t * atm, int size) if (j == i_tmp) /* i.e. no indexed atom type is == to atm[i].t */ { i_tmp++; - srenew (index_atp, i_tmp * sizeof (int)); + srenew(index_atp, i_tmp * sizeof(int)); index_atp[i_tmp - 1] = att[i].t; } } i_tmp++; - srenew (index_atp, i_tmp * sizeof (int)); + srenew(index_atp, i_tmp * sizeof(int)); index_atp[i_tmp - 1] = 0; return index_atp; } - -extern t_complex *** rc_tensor_allocation(int x, int y, int z) +extern t_complex*** rc_tensor_allocation(int x, int y, int z) { - t_complex ***t; + t_complex*** t; int i, j; snew(t, x); - snew(t[0], x*y); - snew(t[0][0], x*y*z); + snew(t[0], x * y); + snew(t[0][0], x * y * z); for (j = 1; j < y; j++) { - t[0][j] = t[0][j-1] + z; + t[0][j] = t[0][j - 1] + z; } for (i = 1; i < x; i++) { - t[i] = t[i-1] + y; - t[i][0] = t[i-1][0] + y*z; + t[i] = t[i - 1] + y; + t[i][0] = t[i - 1][0] + y * z; for (j = 1; j < y; j++) { - t[i][j] = t[i][j-1] + z; + t[i][j] = t[i][j - 1] + z; } } return t; } -extern void compute_structure_factor (structure_factor_t * sft, matrix box, - reduced_atom_t * red, int isize, real start_q, - real end_q, int group, real **sf_table) +extern void compute_structure_factor(structure_factor_t* sft, + matrix box, + reduced_atom_t* red, + int isize, + real start_q, + real end_q, + int group, + real** sf_table) { - structure_factor *sf = static_cast(sft); - reduced_atom *redt = static_cast(red); + structure_factor* sf = static_cast(sft); + reduced_atom* redt = static_cast(red); - t_complex ***tmpSF; - rvec k_factor; - real kdotx, asf, kx, ky, kz, krr; - int kr, maxkx, maxky, maxkz, i, j, k, p, *counter; + t_complex*** tmpSF; + rvec k_factor; + real kdotx, asf, kx, ky, kz, krr; + int kr, maxkx, maxky, maxkz, i, j, k, p, *counter; k_factor[XX] = 2 * M_PI / box[XX][XX]; @@ -180,18 +186,18 @@ extern void compute_structure_factor (structure_factor_t * sft, matrix box, maxky = gmx::roundToInt(end_q / k_factor[YY]); maxkz = gmx::roundToInt(end_q / k_factor[ZZ]); - snew (counter, sf->n_angles); + snew(counter, sf->n_angles); tmpSF = rc_tensor_allocation(maxkx, maxky, maxkz); -/* - * The big loop... - * compute real and imaginary part of the structure factor for every - * (kx,ky,kz)) - */ + /* + * The big loop... + * compute real and imaginary part of the structure factor for every + * (kx,ky,kz)) + */ fprintf(stderr, "\n"); for (i = 0; i < maxkx; i++) { - fprintf (stderr, "\rdone %3.1f%% ", (100.0*(i+1))/maxkx); + fprintf(stderr, "\rdone %3.1f%% ", (100.0 * (i + 1)) / maxkx); fflush(stderr); kx = i * k_factor[XX]; for (j = 0; j < maxky; j++) @@ -202,10 +208,10 @@ extern void compute_structure_factor (structure_factor_t * sft, matrix box, if (i != 0 || j != 0 || k != 0) { kz = k * k_factor[ZZ]; - krr = std::sqrt (gmx::square(kx) + gmx::square(ky) + gmx::square(kz)); + krr = std::sqrt(gmx::square(kx) + gmx::square(ky) + gmx::square(kz)); if (krr >= start_q && krr <= end_q) { - kr = gmx::roundToInt(krr/sf->ref_k); + kr = gmx::roundToInt(krr / sf->ref_k); if (kr < sf->n_angles) { counter[kr]++; /* will be used for the copmutation @@ -214,8 +220,7 @@ extern void compute_structure_factor (structure_factor_t * sft, matrix box, { asf = sf_table[redt[p].t][kr]; - kdotx = kx * redt[p].x[XX] + - ky * redt[p].x[YY] + kz * redt[p].x[ZZ]; + kdotx = kx * redt[p].x[XX] + ky * redt[p].x[YY] + kz * redt[p].x[ZZ]; tmpSF[i][j][k].re += std::cos(kdotx) * asf; tmpSF[i][j][k].im += std::sin(kdotx) * asf; @@ -225,28 +230,31 @@ extern void compute_structure_factor (structure_factor_t * sft, matrix box, } } } - } /* end loop on i */ -/* - * compute the square modulus of the structure factor, averaging on the surface - * kx*kx + ky*ky + kz*kz = krr*krr - * note that this is correct only for a (on the macroscopic scale) - * isotropic system. - */ + } /* end loop on i */ + /* + * compute the square modulus of the structure factor, averaging on the surface + * kx*kx + ky*ky + kz*kz = krr*krr + * note that this is correct only for a (on the macroscopic scale) + * isotropic system. + */ for (i = 0; i < maxkx; i++) { - kx = i * k_factor[XX]; for (j = 0; j < maxky; j++) + kx = i * k_factor[XX]; + for (j = 0; j < maxky; j++) { - ky = j * k_factor[YY]; for (k = 0; k < maxkz; k++) + ky = j * k_factor[YY]; + for (k = 0; k < maxkz; k++) { - kz = k * k_factor[ZZ]; krr = std::sqrt (gmx::square(kx) + gmx::square(ky) - + gmx::square(kz)); if (krr >= start_q && krr <= end_q) + kz = k * k_factor[ZZ]; + krr = std::sqrt(gmx::square(kx) + gmx::square(ky) + gmx::square(kz)); + if (krr >= start_q && krr <= end_q) { kr = gmx::roundToInt(krr / sf->ref_k); if (kr < sf->n_angles && counter[kr] != 0) { sf->F[group][kr] += - (gmx::square(tmpSF[i][j][k].re) + - gmx::square(tmpSF[i][j][k].im))/ counter[kr]; + (gmx::square(tmpSF[i][j][k].re) + gmx::square(tmpSF[i][j][k].im)) + / counter[kr]; } } } @@ -259,13 +267,13 @@ extern void compute_structure_factor (structure_factor_t * sft, matrix box, } -extern gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn) +extern gmx_structurefactors_t* gmx_structurefactors_init(const char* datfn) { /* Read the database for the structure factor of the different atoms */ char line[STRLEN]; - gmx_structurefactors *gsf; + gmx_structurefactors* gsf; double a1, a2, a3, a4, b1, b2, b3, b4, c; int p; int i; @@ -273,7 +281,7 @@ extern gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn) int line_no; char atomn[32]; gmx::FilePtr fp = gmx::openLibraryFile(datfn); - line_no = 0; + line_no = 0; snew(gsf, 1); snew(gsf->atomnm, nralloc); @@ -286,8 +294,9 @@ extern gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn) while (get_a_line(fp.get(), line, STRLEN)) { i = line_no; - if (sscanf(line, "%s %d %lf %lf %lf %lf %lf %lf %lf %lf %lf", - atomn, &p, &a1, &a2, &a3, &a4, &b1, &b2, &b3, &b4, &c) == 11) + if (sscanf(line, "%s %d %lf %lf %lf %lf %lf %lf %lf %lf %lf", atomn, &p, &a1, &a2, &a3, &a4, + &b1, &b2, &b3, &b4, &c) + == 11) { gsf->atomnm[i] = gmx_strdup(atomn); gsf->p[i] = p; @@ -316,8 +325,7 @@ extern gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn) } else { - fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", - datfn, line_no); + fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", datfn, line_no); } } @@ -327,52 +335,53 @@ extern gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn) srenew(gsf->c, gsf->nratoms); srenew(gsf->p, gsf->nratoms); - return static_cast(gsf); - + return static_cast(gsf); } -extern void rearrange_atoms (reduced_atom_t * positions, t_trxframe *fr, const int * index, - int isize, const t_topology * top, gmx_bool flag, gmx_structurefactors_t *gsf) +extern void rearrange_atoms(reduced_atom_t* positions, + t_trxframe* fr, + const int* index, + int isize, + const t_topology* top, + gmx_bool flag, + gmx_structurefactors_t* gsf) /* given the group's index, return the (continuous) array of atoms */ { - int i; + int i; - reduced_atom *pos = static_cast(positions); + reduced_atom* pos = static_cast(positions); if (flag) { for (i = 0; i < isize; i++) { - pos[i].t = - return_atom_type (*(top->atoms.atomname[index[i]]), gsf); + pos[i].t = return_atom_type(*(top->atoms.atomname[index[i]]), gsf); } } for (i = 0; i < isize; i++) { - copy_rvec (fr->x[index[i]], pos[i].x); + copy_rvec(fr->x[index[i]], pos[i].x); } } -extern int return_atom_type (const char *name, gmx_structurefactors_t *gsf) +extern int return_atom_type(const char* name, gmx_structurefactors_t* gsf) { - typedef struct { - const char *name; + typedef struct + { + const char* name; int nh; } t_united_h; - t_united_h uh[] = { - { "CH1", 1 }, { "CH2", 2 }, { "CH3", 3 }, - { "CS1", 1 }, { "CS2", 2 }, { "CS3", 3 }, - { "CP1", 1 }, { "CP2", 2 }, { "CP3", 3 } - }; - int i, cnt = 0; - int *tndx; - int nrc; - int fndx = 0; - int NCMT; + t_united_h uh[] = { { "CH1", 1 }, { "CH2", 2 }, { "CH3", 3 }, { "CS1", 1 }, { "CS2", 2 }, + { "CS3", 3 }, { "CP1", 1 }, { "CP2", 2 }, { "CP3", 3 } }; + int i, cnt = 0; + int* tndx; + int nrc; + int fndx = 0; + int NCMT; - gmx_structurefactors *gsft = static_cast(gsf); + gmx_structurefactors* gsft = static_cast(gsf); NCMT = gsft->nratoms; @@ -382,13 +391,13 @@ extern int return_atom_type (const char *name, gmx_structurefactors_t *gsf) { if (std::strcmp(name, uh[i].name) == 0) { - return NCMT-1+uh[i].nh; + return NCMT - 1 + uh[i].nh; } } for (i = 0; (i < NCMT); i++) { - if (std::strncmp (name, gsft->atomnm[i], std::strlen(gsft->atomnm[i])) == 0) + if (std::strncmp(name, gsft->atomnm[i], std::strlen(gsft->atomnm[i])) == 0) { tndx[cnt] = i; cnt++; @@ -397,8 +406,7 @@ extern int return_atom_type (const char *name, gmx_structurefactors_t *gsf) if (cnt == 0) { - gmx_fatal(FARGS, "\nError: atom (%s) not in list (%d types checked)!\n", - name, i); + gmx_fatal(FARGS, "\nError: atom (%s) not in list (%d types checked)!\n", name, i); } else { @@ -416,13 +424,13 @@ extern int return_atom_type (const char *name, gmx_structurefactors_t *gsf) } } -extern int gmx_structurefactors_get_sf(gmx_structurefactors_t *gsf, int elem, real a[4], real b[4], real *c) +extern int gmx_structurefactors_get_sf(gmx_structurefactors_t* gsf, int elem, real a[4], real b[4], real* c) { int success; int i; - gmx_structurefactors *gsft = static_cast(gsf); - success = 0; + gmx_structurefactors* gsft = static_cast(gsf); + success = 0; for (i = 0; i < 4; i++) { @@ -435,28 +443,33 @@ extern int gmx_structurefactors_get_sf(gmx_structurefactors_t *gsf, int elem, re return success; } -extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX, - const char* fnXVG, const char *fnTRX, - const char* fnDAT, - real start_q, real end_q, - real energy, int ng, const gmx_output_env_t *oenv) +extern int do_scattering_intensity(const char* fnTPS, + const char* fnNDX, + const char* fnXVG, + const char* fnTRX, + const char* fnDAT, + real start_q, + real end_q, + real energy, + int ng, + const gmx_output_env_t* oenv) { - int i, *isize, flags = TRX_READ_X, **index_atp; - t_trxstatus *status; - char **grpname; - int **index; - t_topology top; - int ePBC; - t_trxframe fr; - reduced_atom_t **red; - structure_factor *sf; - rvec *xtop; - real **sf_table; - matrix box; - real r_tmp; - - gmx_structurefactors_t *gmx_sf; - real *a, *b, c; + int i, *isize, flags = TRX_READ_X, **index_atp; + t_trxstatus* status; + char** grpname; + int** index; + t_topology top; + int ePBC; + t_trxframe fr; + reduced_atom_t** red; + structure_factor* sf; + rvec* xtop; + real** sf_table; + matrix box; + real r_tmp; + + gmx_structurefactors_t* gmx_sf; + real * a, *b, c; snew(a, 4); snew(b, 4); @@ -466,36 +479,35 @@ extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX, gmx_structurefactors_get_sf(gmx_sf, 0, a, b, &c); - snew (sf, 1); + snew(sf, 1); sf->energy = energy; /* Read the topology informations */ - read_tps_conf (fnTPS, &top, &ePBC, &xtop, nullptr, box, TRUE); - sfree (xtop); + read_tps_conf(fnTPS, &top, &ePBC, &xtop, nullptr, box, TRUE); + sfree(xtop); /* groups stuff... */ - snew (isize, ng); - snew (index, ng); - snew (grpname, ng); + snew(isize, ng); + snew(index, ng); + snew(grpname, ng); - fprintf (stderr, "\nSelect %d group%s\n", ng, - ng == 1 ? "" : "s"); + fprintf(stderr, "\nSelect %d group%s\n", ng, ng == 1 ? "" : "s"); if (fnTPS) { - get_index (&top.atoms, fnNDX, ng, isize, index, grpname); + get_index(&top.atoms, fnNDX, ng, isize, index, grpname); } else { - rd_index (fnNDX, ng, isize, index, grpname); + rd_index(fnNDX, ng, isize, index, grpname); } /* The first time we read data is a little special */ - read_first_frame (oenv, &status, fnTRX, &fr, flags); + read_first_frame(oenv, &status, fnTRX, &fr, flags); sf->total_n_atoms = fr.natoms; - snew (red, ng); - snew (index_atp, ng); + snew(red, ng); + snew(index_atp, ng); r_tmp = std::max(box[XX][XX], box[YY][YY]); r_tmp = std::max(box[ZZ][ZZ], r_tmp); @@ -504,19 +516,19 @@ extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX, /* ref_k will be the reference momentum unit */ sf->n_angles = gmx::roundToInt(end_q / sf->ref_k); - snew (sf->F, ng); + snew(sf->F, ng); for (i = 0; i < ng; i++) { - snew (sf->F[i], sf->n_angles); + snew(sf->F[i], sf->n_angles); } for (i = 0; i < ng; i++) { - snew (red[i], isize[i]); - rearrange_atoms (red[i], &fr, index[i], isize[i], &top, TRUE, gmx_sf); - index_atp[i] = create_indexed_atom_type (red[i], isize[i]); + snew(red[i], isize[i]); + rearrange_atoms(red[i], &fr, index[i], isize[i], &top, TRUE, gmx_sf); + index_atp[i] = create_indexed_atom_type(red[i], isize[i]); } - sf_table = compute_scattering_factor_table (gmx_sf, static_cast(sf)); + sf_table = compute_scattering_factor_table(gmx_sf, static_cast(sf)); /* This is the main loop over frames */ @@ -526,16 +538,16 @@ extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX, sf->nSteps++; for (i = 0; i < ng; i++) { - rearrange_atoms (red[i], &fr, index[i], isize[i], &top, FALSE, gmx_sf); + rearrange_atoms(red[i], &fr, index[i], isize[i], &top, FALSE, gmx_sf); - compute_structure_factor (static_cast(sf), box, red[i], isize[i], - start_q, end_q, i, sf_table); + compute_structure_factor(static_cast(sf), box, red[i], isize[i], + start_q, end_q, i, sf_table); } } - while (read_next_frame (oenv, status, &fr)); + while (read_next_frame(oenv, status, &fr)); - save_data (static_cast(sf), fnXVG, ng, start_q, end_q, oenv); + save_data(static_cast(sf), fnXVG, ng, start_q, end_q, oenv); sfree(a); @@ -547,58 +559,60 @@ extern int do_scattering_intensity (const char* fnTPS, const char* fnNDX, } -extern void save_data (structure_factor_t *sft, const char *file, int ngrps, - real start_q, real end_q, const gmx_output_env_t *oenv) +extern void save_data(structure_factor_t* sft, + const char* file, + int ngrps, + real start_q, + real end_q, + const gmx_output_env_t* oenv) { - FILE *fp; - int i, g = 0; - double *tmp, polarization_factor, A; + FILE* fp; + int i, g = 0; + double *tmp, polarization_factor, A; - structure_factor *sf = static_cast(sft); + structure_factor* sf = static_cast(sft); - fp = xvgropen (file, "Scattering Intensity", "q (1/nm)", - "Intensity (a.u.)", oenv); + fp = xvgropen(file, "Scattering Intensity", "q (1/nm)", "Intensity (a.u.)", oenv); - snew (tmp, ngrps); + snew(tmp, ngrps); for (g = 0; g < ngrps; g++) { for (i = 0; i < sf->n_angles; i++) { -/* - * theta is half the angle between incoming and scattered vectors. - * - * polar. fact. = 0.5*(1+cos^2(2*theta)) = 1 - 0.5 * sin^2(2*theta) - * - * sin(theta) = q/(2k) := A -> sin^2(theta) = 4*A^2 (1-A^2) -> - * -> 0.5*(1+cos^2(2*theta)) = 1 - 2 A^2 (1-A^2) - */ + /* + * theta is half the angle between incoming and scattered vectors. + * + * polar. fact. = 0.5*(1+cos^2(2*theta)) = 1 - 0.5 * sin^2(2*theta) + * + * sin(theta) = q/(2k) := A -> sin^2(theta) = 4*A^2 (1-A^2) -> + * -> 0.5*(1+cos^2(2*theta)) = 1 - 2 A^2 (1-A^2) + */ A = static_cast(i * sf->ref_k) / (2.0 * sf->momentum); polarization_factor = 1 - 2.0 * gmx::square(A) * (1 - gmx::square(A)); - sf->F[g][i] *= polarization_factor; + sf->F[g][i] *= polarization_factor; } } for (i = 0; i < sf->n_angles; i++) { if (i * sf->ref_k >= start_q && i * sf->ref_k <= end_q) { - fprintf (fp, "%10.5f ", i * sf->ref_k); + fprintf(fp, "%10.5f ", i * sf->ref_k); for (g = 0; g < ngrps; g++) { - fprintf (fp, " %10.5f ", (sf->F[g][i]) /( sf->total_n_atoms* - sf->nSteps)); + fprintf(fp, " %10.5f ", (sf->F[g][i]) / (sf->total_n_atoms * sf->nSteps)); } - fprintf (fp, "\n"); + fprintf(fp, "\n"); } } - xvgrclose (fp); + xvgrclose(fp); } -extern double CMSF (gmx_structurefactors_t *gsf, int type, int nh, double lambda, double sin_theta) +extern double CMSF(gmx_structurefactors_t* gsf, int type, int nh, double lambda, double sin_theta) /* * return Cromer-Mann fit for the atomic scattering factor: * sin_theta is the sine of half the angle between incoming and scattered @@ -607,7 +621,7 @@ extern double CMSF (gmx_structurefactors_t *gsf, int type, int nh, double lambda { int i; double tmp = 0.0, k2; - real *a, *b; + real * a, *b; real c; snew(a, 4); @@ -625,42 +639,41 @@ extern double CMSF (gmx_structurefactors_t *gsf, int type, int nh, double lambda */ if (nh > 0) { - tmp = (CMSF (gsf, return_atom_type ("C", gsf), 0, lambda, sin_theta) + - nh*CMSF (gsf, return_atom_type ("H", gsf), 0, lambda, sin_theta)); + tmp = (CMSF(gsf, return_atom_type("C", gsf), 0, lambda, sin_theta) + + nh * CMSF(gsf, return_atom_type("H", gsf), 0, lambda, sin_theta)); } /* all atom case */ else { - k2 = (gmx::square(sin_theta) / gmx::square(10.0 * lambda)); + k2 = (gmx::square(sin_theta) / gmx::square(10.0 * lambda)); gmx_structurefactors_get_sf(gsf, type, a, b, &c); - tmp = c; + tmp = c; for (i = 0; (i < 4); i++) { - tmp += a[i] * exp (-b[i] * k2); + tmp += a[i] * exp(-b[i] * k2); } } return tmp; } - -extern real **gmx_structurefactors_table(gmx_structurefactors_t *gsf, real momentum, real ref_k, real lambda, int n_angles) +extern real** gmx_structurefactors_table(gmx_structurefactors_t* gsf, real momentum, real ref_k, real lambda, int n_angles) { int NCMT; int nsftable; int i, j; double q, sin_theta; - real **sf_table; - gmx_structurefactors *gsft = static_cast(gsf); + real** sf_table; + gmx_structurefactors* gsft = static_cast(gsf); NCMT = gsft->nratoms; - nsftable = NCMT+3; + nsftable = NCMT + 3; - snew (sf_table, nsftable); + snew(sf_table, nsftable); for (i = 0; (i < nsftable); i++) { - snew (sf_table[i], n_angles); + snew(sf_table[i], n_angles); for (j = 0; j < n_angles; j++) { q = static_cast(j * ref_k); @@ -669,23 +682,23 @@ extern real **gmx_structurefactors_table(gmx_structurefactors_t *gsf, real momen sin_theta = q / (2.0 * momentum); if (i < NCMT) { - sf_table[i][j] = CMSF (gsf, i, 0, lambda, sin_theta); + sf_table[i][j] = CMSF(gsf, i, 0, lambda, sin_theta); } else { - sf_table[i][j] = CMSF (gsf, i, i-NCMT+1, lambda, sin_theta); + sf_table[i][j] = CMSF(gsf, i, i - NCMT + 1, lambda, sin_theta); } } } return sf_table; } -extern void gmx_structurefactors_done(gmx_structurefactors_t *gsf) +extern void gmx_structurefactors_done(gmx_structurefactors_t* gsf) { int i; - gmx_structurefactors *sf; - sf = static_cast(gsf); + gmx_structurefactors* sf; + sf = static_cast(gsf); for (i = 0; i < sf->nratoms; i++) { @@ -701,26 +714,25 @@ extern void gmx_structurefactors_done(gmx_structurefactors_t *gsf) sfree(sf->c); sfree(sf); - } -extern real **compute_scattering_factor_table (gmx_structurefactors_t *gsf, structure_factor_t *sft) +extern real** compute_scattering_factor_table(gmx_structurefactors_t* gsf, structure_factor_t* sft) { -/* - * this function build up a table of scattering factors for every atom - * type and for every scattering angle. - */ + /* + * this function build up a table of scattering factors for every atom + * type and for every scattering angle. + */ - double hc = 1239.842; - real ** sf_table; + double hc = 1239.842; + real** sf_table; - structure_factor *sf = static_cast(sft); + structure_factor* sf = static_cast(sft); /* \hbar \omega \lambda = hc = 1239.842 eV * nm */ sf->momentum = (static_cast(2. * 1000.0 * M_PI * sf->energy) / hc); sf->lambda = hc / (1000.0 * sf->energy); - fprintf (stderr, "\nwavelenght = %f nm\n", sf->lambda); + fprintf(stderr, "\nwavelenght = %f nm\n", sf->lambda); sf_table = gmx_structurefactors_table(gsf, sf->momentum, sf->ref_k, sf->lambda, sf->n_angles); diff --git a/src/gromacs/gmxana/sfactor.h b/src/gromacs/gmxana/sfactor.h index e1ad760415..1010accf21 100644 --- a/src/gromacs/gmxana/sfactor.h +++ b/src/gromacs/gmxana/sfactor.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,39 +51,52 @@ typedef struct structure_factor structure_factor_t; typedef struct reduced_atom reduced_atom_t; -int * create_indexed_atom_type (reduced_atom_t * atm, int size); +int* create_indexed_atom_type(reduced_atom_t* atm, int size); -void compute_structure_factor (structure_factor_t * sft, matrix box, - reduced_atom_t * red, int isize, real start_q, - real end_q, int group, real **sf_table); +void compute_structure_factor(structure_factor_t* sft, + matrix box, + reduced_atom_t* red, + int isize, + real start_q, + real end_q, + int group, + real** sf_table); -gmx_structurefactors_t *gmx_structurefactors_init(const char *datfn); +gmx_structurefactors_t* gmx_structurefactors_init(const char* datfn); -void gmx_structurefactors_done(gmx_structurefactors_t *gsf); +void gmx_structurefactors_done(gmx_structurefactors_t* gsf); -int gmx_structurefactors_get_sf(gmx_structurefactors_t *gsf, int elem, real a[4], real b[4], real *c); +int gmx_structurefactors_get_sf(gmx_structurefactors_t* gsf, int elem, real a[4], real b[4], real* c); -real **gmx_structurefactors_table(gmx_structurefactors_t *gsf, real momentum, real ref_k, - real lambda, int n_angles); +real** gmx_structurefactors_table(gmx_structurefactors_t* gsf, real momentum, real ref_k, real lambda, int n_angles); -void save_data (structure_factor_t * sft, const char *file, int ngrps, - real start_q, real end_q, const gmx_output_env_t *oenv); +void save_data(structure_factor_t* sft, const char* file, int ngrps, real start_q, real end_q, const gmx_output_env_t* oenv); -double CMSF (gmx_structurefactors_t *gsf, int type, int nh, double lambda, double sin_theta); +double CMSF(gmx_structurefactors_t* gsf, int type, int nh, double lambda, double sin_theta); -int return_atom_type (const char *name, gmx_structurefactors_t *gsf); +int return_atom_type(const char* name, gmx_structurefactors_t* gsf); -void rearrange_atoms (reduced_atom_t * positions, struct t_trxframe *fr, const int * index, - int isize, const t_topology * top, gmx_bool flag, gmx_structurefactors_t *gsf); +void rearrange_atoms(reduced_atom_t* positions, + struct t_trxframe* fr, + const int* index, + int isize, + const t_topology* top, + gmx_bool flag, + gmx_structurefactors_t* gsf); -int do_scattering_intensity (const char* fnTPS, const char* fnNDX, - const char* fnXVG, const char *fnTRX, - const char* fnDAT, - real start_q, real end_q, - real energy, int ng, const gmx_output_env_t *oenv); +int do_scattering_intensity(const char* fnTPS, + const char* fnNDX, + const char* fnXVG, + const char* fnTRX, + const char* fnDAT, + real start_q, + real end_q, + real energy, + int ng, + const gmx_output_env_t* oenv); -t_complex *** rc_tensor_allocation(int x, int y, int z); +t_complex*** rc_tensor_allocation(int x, int y, int z); -real **compute_scattering_factor_table (gmx_structurefactors_t *gsf, structure_factor_t * sft); +real** compute_scattering_factor_table(gmx_structurefactors_t* gsf, structure_factor_t* sft); #endif diff --git a/src/gromacs/gmxana/tests/entropy.cpp b/src/gromacs/gmxana/tests/entropy.cpp index 0c730f4ceb..ff2ec4de0c 100644 --- a/src/gromacs/gmxana/tests/entropy.cpp +++ b/src/gromacs/gmxana/tests/entropy.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,50 +53,41 @@ namespace class Entropy : public ::testing::Test { - protected: - test::TestReferenceData refData_; - test::TestReferenceChecker checker_; - Entropy( ) : checker_(refData_.rootChecker()) - { - } - public: - void runSchlitter(real temperature, gmx_bool bLinear) - { - std::vector ev = { - 0.00197861, 0.000389439, 0.000316043, - 0.000150392, 0.000110254, 8.99659e-05, - 8.06572e-05, 5.14339e-05, 4.34268e-05, - 2.16063e-05, 1.65182e-05, 1.3965e-05, - 1.01937e-05, 5.83113e-06, 4.59067e-06, - 3.39577e-06, 2.14837e-06, 1.20468e-06, - 9.60817e-18, 1.48941e-19, 1.13939e-19, - 5.02332e-20, -6.90708e-21, -1.91354e-18 - }; - std::vector eigenvalue; - std::copy(ev.begin(), ev.end(), std::back_inserter(eigenvalue)); - - real S = calcSchlitterEntropy(eigenvalue, temperature, bLinear); - checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-7)); - checker_.checkReal(S, "entropy"); - } - - void runQuasiHarmonic(real temperature, gmx_bool bLinear) - { - std::vector ev = { - -31.403, -7.73169, -3.80315, -2.15659e-06, -1.70991e-07, - 236, 4609.83, 6718.07, 6966.27, 8587.85, - 10736.3, 13543.7, 17721.3, 22868, 35517.8, - 44118.1, 75827.9, 106277, 115132, 120782, - 445118, 451149, 481058, 484576 - }; - std::vector eigenvalue; - std::copy(ev.begin(), ev.end(), std::back_inserter(eigenvalue)); - - real S = calcQuasiHarmonicEntropy(eigenvalue, temperature, bLinear, 1.0); - - checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-7)); - checker_.checkReal(S, "entropy"); - } +protected: + test::TestReferenceData refData_; + test::TestReferenceChecker checker_; + Entropy() : checker_(refData_.rootChecker()) {} + +public: + void runSchlitter(real temperature, gmx_bool bLinear) + { + std::vector ev = { 0.00197861, 0.000389439, 0.000316043, 0.000150392, 0.000110254, + 8.99659e-05, 8.06572e-05, 5.14339e-05, 4.34268e-05, 2.16063e-05, + 1.65182e-05, 1.3965e-05, 1.01937e-05, 5.83113e-06, 4.59067e-06, + 3.39577e-06, 2.14837e-06, 1.20468e-06, 9.60817e-18, 1.48941e-19, + 1.13939e-19, 5.02332e-20, -6.90708e-21, -1.91354e-18 }; + std::vector eigenvalue; + std::copy(ev.begin(), ev.end(), std::back_inserter(eigenvalue)); + + real S = calcSchlitterEntropy(eigenvalue, temperature, bLinear); + checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-7)); + checker_.checkReal(S, "entropy"); + } + + void runQuasiHarmonic(real temperature, gmx_bool bLinear) + { + std::vector ev = { -31.403, -7.73169, -3.80315, -2.15659e-06, -1.70991e-07, 236, + 4609.83, 6718.07, 6966.27, 8587.85, 10736.3, 13543.7, + 17721.3, 22868, 35517.8, 44118.1, 75827.9, 106277, + 115132, 120782, 445118, 451149, 481058, 484576 }; + std::vector eigenvalue; + std::copy(ev.begin(), ev.end(), std::back_inserter(eigenvalue)); + + real S = calcQuasiHarmonicEntropy(eigenvalue, temperature, bLinear, 1.0); + + checker_.setDefaultTolerance(test::relativeToleranceAsFloatingPoint(1, 1e-7)); + checker_.checkReal(S, "entropy"); + } }; TEST_F(Entropy, Schlitter_300_NoLinear) diff --git a/src/gromacs/gmxana/tests/gmx_make_ndx.cpp b/src/gromacs/gmxana/tests/gmx_make_ndx.cpp index a8ec219b48..2f5437a8dc 100644 --- a/src/gromacs/gmxana/tests/gmx_make_ndx.cpp +++ b/src/gromacs/gmxana/tests/gmx_make_ndx.cpp @@ -52,24 +52,24 @@ namespace class GmxMakeNdx : public gmx::test::CommandLineTestBase { - public: - /*! \brief runs the test for the filename prefix \p sysName from the simulation data base - \param[in] sysName file name prefix sysName.g96 must be present in the simulation database - */ - void runTest(const std::string &sysName) - { - auto &cmdline = commandLine(); - auto groFileName = sysName + ".g96"; - std::string ndxFileName = sysName + ".ndx"; - setInputFile("-f", groFileName); - setOutputFile("-o", ndxFileName.c_str(), gmx::test::ExactTextMatch()); +public: + /*! \brief runs the test for the filename prefix \p sysName from the simulation data base + \param[in] sysName file name prefix sysName.g96 must be present in the simulation database + */ + void runTest(const std::string& sysName) + { + auto& cmdline = commandLine(); + auto groFileName = sysName + ".g96"; + std::string ndxFileName = sysName + ".ndx"; + setInputFile("-f", groFileName); + setOutputFile("-o", ndxFileName.c_str(), gmx::test::ExactTextMatch()); - gmx::test::StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin("q\n"); + gmx::test::StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin("q\n"); - ASSERT_EQ(0, gmx_make_ndx(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } + ASSERT_EQ(0, gmx_make_ndx(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); + } }; TEST_F(GmxMakeNdx, WritesDefaultProteinIndexGroups) diff --git a/src/gromacs/gmxana/tests/gmx_mindist.cpp b/src/gromacs/gmxana/tests/gmx_mindist.cpp index b2e5459366..4dc4c10523 100644 --- a/src/gromacs/gmxana/tests/gmx_mindist.cpp +++ b/src/gromacs/gmxana/tests/gmx_mindist.cpp @@ -60,29 +60,29 @@ namespace { using gmx::test::CommandLine; -using gmx::test::XvgMatch; using gmx::test::StdioTestHelper; +using gmx::test::XvgMatch; class MindistTest : public gmx::test::CommandLineTestBase { - public: - MindistTest() - { - setInputFile("-f", "mindist_coords.gro"); - setInputFile("-s", "mindist_coords.gro"); - setInputFile("-n", "mindist.ndx"); - } - - void runTest(const CommandLine &args, const char * stringForStdin) - { - StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin(stringForStdin); - - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - ASSERT_EQ(0, gmx_mindist(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } +public: + MindistTest() + { + setInputFile("-f", "mindist_coords.gro"); + setInputFile("-s", "mindist_coords.gro"); + setInputFile("-n", "mindist.ndx"); + } + + void runTest(const CommandLine& args, const char* stringForStdin) + { + StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin(stringForStdin); + + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + ASSERT_EQ(0, gmx_mindist(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); + } }; /* mindist_coords.pdb has 3 beads spaced out in a 5 nm box, with the same yz coordinates @@ -99,10 +99,8 @@ class MindistTest : public gmx::test::CommandLineTestBase TEST_F(MindistTest, mindistWorksWithSingleAtoms) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist" - }; - const char * const stdIn = "0 1"; + const char* const cmdline[] = { "mindist" }; + const char* const stdIn = "0 1"; runTest(CommandLine(cmdline), stdIn); } @@ -110,10 +108,8 @@ TEST_F(MindistTest, mindistWorksWithSingleAtoms) TEST_F(MindistTest, mindistWorksWithMultipleAtoms) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist" - }; - const char * const stdIn = "2 3"; + const char* const cmdline[] = { "mindist" }; + const char* const stdIn = "2 3"; runTest(CommandLine(cmdline), stdIn); } @@ -121,10 +117,8 @@ TEST_F(MindistTest, mindistWorksWithMultipleAtoms) TEST_F(MindistTest, mindistDoesNotPickUpContacts) { setOutputFile("-on", "ncontacts.xvg", XvgMatch()); - const char * const cmdline[] = { - "mindist" - }; - const char * const stdIn = "0 1"; + const char* const cmdline[] = { "mindist" }; + const char* const stdIn = "0 1"; runTest(CommandLine(cmdline), stdIn); } @@ -132,20 +126,24 @@ TEST_F(MindistTest, mindistDoesNotPickUpContacts) TEST_F(MindistTest, mindistPicksUpContacts) { setOutputFile("-on", "ncontacts.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-d", "2.5", + const char* const cmdline[] = { + "mindist", + "-d", + "2.5", }; - const char * const stdIn = "0 1"; + const char* const stdIn = "0 1"; runTest(CommandLine(cmdline), stdIn); } TEST_F(MindistTest, ngWorks) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-ng", "2", + const char* const cmdline[] = { + "mindist", + "-ng", + "2", }; - const char * const stdIn = "0 1 2"; + const char* const stdIn = "0 1 2"; runTest(CommandLine(cmdline), stdIn); } @@ -153,10 +151,8 @@ TEST_F(MindistTest, ngWorks) TEST_F(MindistTest, groupWorks) { setOutputFile("-on", "ncontacts.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-group", "-d", "3" - }; - const char * const stdIn = "3, 2"; + const char* const cmdline[] = { "mindist", "-group", "-d", "3" }; + const char* const stdIn = "3, 2"; runTest(CommandLine(cmdline), stdIn); } @@ -164,10 +160,8 @@ TEST_F(MindistTest, groupWorks) TEST_F(MindistTest, maxDistWorks) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-max" - }; - const char * const stdIn = "2 3"; + const char* const cmdline[] = { "mindist", "-max" }; + const char* const stdIn = "2 3"; runTest(CommandLine(cmdline), stdIn); } @@ -176,10 +170,8 @@ TEST_F(MindistTest, maxDistWorks) TEST_F(MindistTest, noPbcWorks) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-nopbc" - }; - const char * const stdIn = "0 1"; + const char* const cmdline[] = { "mindist", "-nopbc" }; + const char* const stdIn = "0 1"; runTest(CommandLine(cmdline), stdIn); } @@ -187,23 +179,19 @@ TEST_F(MindistTest, noPbcWorks) TEST_F(MindistTest, resPerTimeWorks) { setOutputFile("-or", "respertime.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-respertime" - }; - const char * const stdIn = "3 2"; + const char* const cmdline[] = { "mindist", "-respertime" }; + const char* const stdIn = "3 2"; runTest(CommandLine(cmdline), stdIn); } TEST_F(MindistTest, matrixWorks) { setOutputFile("-od", "mindist.xvg", XvgMatch()); - const char *const cmdline[] = { - "mindist", "-matrix" - }; - const char * const stdIn = "5"; + const char* const cmdline[] = { "mindist", "-matrix" }; + const char* const stdIn = "5"; runTest(CommandLine(cmdline), stdIn); } // TODO test periodic image - needs a tpr? -} //namespace +} // namespace diff --git a/src/gromacs/gmxana/tests/gmx_msd.cpp b/src/gromacs/gmxana/tests/gmx_msd.cpp index 6a21280fde..bca2bd8430 100644 --- a/src/gromacs/gmxana/tests/gmx_msd.cpp +++ b/src/gromacs/gmxana/tests/gmx_msd.cpp @@ -64,75 +64,74 @@ using gmx::test::XvgMatch; class MsdTest : public gmx::test::CommandLineTestBase { - public: - MsdTest() - { - setOutputFile("-o", "msd.xvg", XvgMatch()); - setInputFile("-f", "msd_traj.xtc"); - setInputFile("-s", "msd_coords.gro"); - setInputFile("-n", "msd.ndx"); - } - - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - ASSERT_EQ(0, gmx_msd(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } +public: + MsdTest() + { + setOutputFile("-o", "msd.xvg", XvgMatch()); + setInputFile("-f", "msd_traj.xtc"); + setInputFile("-s", "msd_coords.gro"); + setInputFile("-n", "msd.ndx"); + } + + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + ASSERT_EQ(0, gmx_msd(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); + } }; class MsdMolTest : public gmx::test::CommandLineTestBase { - public: - MsdMolTest() +public: + MsdMolTest() + { + double tolerance = 1e-5; + XvgMatch xvg; + XvgMatch& toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, tolerance)); + setOutputFile("-mol", "msdmol.xvg", toler); + } + + void runTest(const CommandLine& args, const char* ndxfile, const std::string& simulationName) + { + setInputFile("-f", simulationName + ".pdb"); + std::string tpr = fileManager().getTemporaryFilePath(".tpr"); + std::string mdp = fileManager().getTemporaryFilePath(".mdp"); + FILE* fp = fopen(mdp.c_str(), "w"); + fprintf(fp, "cutoff-scheme = verlet\n"); + fprintf(fp, "rcoulomb = 0.85\n"); + fprintf(fp, "rvdw = 0.85\n"); + fprintf(fp, "rlist = 0.85\n"); + fclose(fp); + + // Prepare a .tpr file { - double tolerance = 1e-5; - XvgMatch xvg; - XvgMatch &toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, tolerance)); - setOutputFile("-mol", "msdmol.xvg", toler); + CommandLine caller; + auto simDB = gmx::test::TestFileManager::getTestSimulationDatabaseDirectory(); + auto base = gmx::Path::join(simDB, simulationName); + caller.append("grompp"); + caller.addOption("-maxwarn", 0); + caller.addOption("-f", mdp.c_str()); + std::string gro = (base + ".pdb"); + caller.addOption("-c", gro.c_str()); + std::string top = (base + ".top"); + caller.addOption("-p", top.c_str()); + std::string ndx = (base + ".ndx"); + caller.addOption("-n", ndx.c_str()); + caller.addOption("-o", tpr.c_str()); + ASSERT_EQ(0, gmx_grompp(caller.argc(), caller.argv())); } - - void runTest(const CommandLine &args, const char *ndxfile, - const std::string &simulationName) + // Run the MSD analysis { - setInputFile("-f", simulationName + ".pdb"); - std::string tpr = fileManager().getTemporaryFilePath(".tpr"); - std::string mdp = fileManager().getTemporaryFilePath(".mdp"); - FILE *fp = fopen(mdp.c_str(), "w"); - fprintf(fp, "cutoff-scheme = verlet\n"); - fprintf(fp, "rcoulomb = 0.85\n"); - fprintf(fp, "rvdw = 0.85\n"); - fprintf(fp, "rlist = 0.85\n"); - fclose(fp); - - // Prepare a .tpr file - { - CommandLine caller; - auto simDB = gmx::test::TestFileManager::getTestSimulationDatabaseDirectory(); - auto base = gmx::Path::join(simDB, simulationName); - caller.append("grompp"); - caller.addOption("-maxwarn", 0); - caller.addOption("-f", mdp.c_str()); - std::string gro = (base + ".pdb"); - caller.addOption("-c", gro.c_str()); - std::string top = (base + ".top"); - caller.addOption("-p", top.c_str()); - std::string ndx = (base + ".ndx"); - caller.addOption("-n", ndx.c_str()); - caller.addOption("-o", tpr.c_str()); - ASSERT_EQ(0, gmx_grompp(caller.argc(), caller.argv())); - } - // Run the MSD analysis - { - setInputFile("-n", ndxfile); - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - cmdline.addOption("-s", tpr.c_str()); - ASSERT_EQ(0, gmx_msd(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } + setInputFile("-n", ndxfile); + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + cmdline.addOption("-s", tpr.c_str()); + ASSERT_EQ(0, gmx_msd(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); } + } }; /* msd_traj.xtc contains a 10 frame (1 ps per frame) simulation @@ -148,7 +147,7 @@ class MsdMolTest : public gmx::test::CommandLineTestBase // for 3D, (8 + 4 + 0) / 3 should yield 4 cm^2 / s TEST_F(MsdTest, threeDimensionalDiffusion) { - const char *const cmdline[] = { + const char* const cmdline[] = { "msd", "-mw", "no", "-trestart", "200", }; runTest(CommandLine(cmdline)); @@ -157,46 +156,36 @@ TEST_F(MsdTest, threeDimensionalDiffusion) // for lateral z, (8 + 4) / 2 should yield 6 cm^2 /s TEST_F(MsdTest, twoDimensionalDiffusion) { - const char *const cmdline[] = { - "msd", "-mw", "no", "-trestart", "200", "-lateral", "z" - }; + const char* const cmdline[] = { "msd", "-mw", "no", "-trestart", "200", "-lateral", "z" }; runTest(CommandLine(cmdline)); } // for type x, should yield 8 cm^2 / s TEST_F(MsdTest, oneDimensionalDiffusion) { - const char *const cmdline[] = { - "msd", "-mw", "no", "-trestart", "200", "-type", "x" - }; + const char* const cmdline[] = { "msd", "-mw", "no", "-trestart", "200", "-type", "x" }; runTest(CommandLine(cmdline)); } // Test the diffusion per molecule output, mass weighted TEST_F(MsdMolTest, diffMolMassWeighted) { - const char *const cmdline[] = { - "msd", "-trestart", "200" - }; + const char* const cmdline[] = { "msd", "-trestart", "200" }; runTest(CommandLine(cmdline), "spc5.ndx", "spc5"); } // Test the diffusion per molecule output, non-mass weighted TEST_F(MsdMolTest, diffMolNonMassWeighted) { - const char *const cmdline[] = { - "msd", "-trestart", "200", "-mw", "no" - }; + const char* const cmdline[] = { "msd", "-trestart", "200", "-mw", "no" }; runTest(CommandLine(cmdline), "spc5.ndx", "spc5"); } // Test the diffusion per molecule output, with selection TEST_F(MsdMolTest, diffMolSelected) { - const char *const cmdline[] = { - "msd", "-trestart", "200" - }; + const char* const cmdline[] = { "msd", "-trestart", "200" }; runTest(CommandLine(cmdline), "spc5_3.ndx", "spc5"); } -} //namespace +} // namespace diff --git a/src/gromacs/gmxana/tests/gmx_traj.cpp b/src/gromacs/gmxana/tests/gmx_traj.cpp index 9bf8b93a2a..eb43b61b85 100644 --- a/src/gromacs/gmxana/tests/gmx_traj.cpp +++ b/src/gromacs/gmxana/tests/gmx_traj.cpp @@ -52,22 +52,21 @@ namespace { -class GmxTraj : public gmx::test::CommandLineTestBase, - public ::testing::WithParamInterface +class GmxTraj : public gmx::test::CommandLineTestBase, public ::testing::WithParamInterface { - public: - void runTest(const char *fileName) - { - auto &cmdline = commandLine(); - setInputFile("-s", "spc2.gro"); - setInputFile("-f", fileName); - setOutputFile("-ox", "spc2.xvg", gmx::test::NoTextMatch()); +public: + void runTest(const char* fileName) + { + auto& cmdline = commandLine(); + setInputFile("-s", "spc2.gro"); + setInputFile("-f", fileName); + setOutputFile("-ox", "spc2.xvg", gmx::test::NoTextMatch()); - gmx::test::StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin("0\n"); + gmx::test::StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin("0\n"); - ASSERT_EQ(0, gmx_traj(cmdline.argc(), cmdline.argv())); - } + ASSERT_EQ(0, gmx_traj(cmdline.argc(), cmdline.argv())); + } }; /* TODO These tests are actually not very effective, because gmx-traj @@ -85,18 +84,13 @@ TEST_P(GmxTraj, WithDifferentInputFormats) * database. These all have two identical frames of two SPC water * molecules, which were generated via trjconv from the .gro * version. */ -const char *const trajectoryFileNames[] = { - "spc2-traj.trr", +const char* const trajectoryFileNames[] = { "spc2-traj.trr", #if GMX_USE_TNG - "spc2-traj.tng", + "spc2-traj.tng", #endif - "spc2-traj.xtc", - "spc2-traj.gro", - "spc2-traj.pdb", - "spc2-traj.g96" -}; + "spc2-traj.xtc", "spc2-traj.gro", + "spc2-traj.pdb", "spc2-traj.g96" }; -INSTANTIATE_TEST_CASE_P(NoFatalErrorWhenWritingFrom, - GmxTraj, ::testing::ValuesIn(trajectoryFileNames)); +INSTANTIATE_TEST_CASE_P(NoFatalErrorWhenWritingFrom, GmxTraj, ::testing::ValuesIn(trajectoryFileNames)); } // namespace diff --git a/src/gromacs/gmxana/thermochemistry.cpp b/src/gromacs/gmxana/thermochemistry.cpp index 9b7c84fee6..b9124abe5d 100644 --- a/src/gromacs/gmxana/thermochemistry.cpp +++ b/src/gromacs/gmxana/thermochemistry.cpp @@ -46,78 +46,69 @@ static double eigval_to_frequency(double eigval) { - double factor_gmx_to_omega2 = 1.0E21/(AVOGADRO*AMU); - return std::sqrt(std::max(0.0, eigval)*factor_gmx_to_omega2); + double factor_gmx_to_omega2 = 1.0E21 / (AVOGADRO * AMU); + return std::sqrt(std::max(0.0, eigval) * factor_gmx_to_omega2); } -double calcZeroPointEnergy(gmx::ArrayRef eigval, - real scale_factor) +double calcZeroPointEnergy(gmx::ArrayRef eigval, real scale_factor) { // Convert frequency (ps^-1) to energy (kJ/mol) - double factor = PLANCK*PICO/(2.0*M_PI); + double factor = PLANCK * PICO / (2.0 * M_PI); double zpe = 0; - for (auto &r : eigval) + for (auto& r : eigval) { double omega = eigval_to_frequency(r); - zpe += 0.5*factor*scale_factor*omega; + zpe += 0.5 * factor * scale_factor * omega; } return zpe; } -double calcVibrationalInternalEnergy(gmx::ArrayRef eigval, - real temperature, - gmx_bool linear, - real scale_factor) +double calcVibrationalInternalEnergy(gmx::ArrayRef eigval, real temperature, gmx_bool linear, real scale_factor) { size_t nskip = linear ? 5 : 6; double Evib = 0; - double hbar = PLANCK1/(2*M_PI); + double hbar = PLANCK1 / (2 * M_PI); for (gmx::index i = nskip; i < eigval.ssize(); i++) { if (eigval[i] > 0) { - double omega = scale_factor*eigval_to_frequency(eigval[i]); - double hwkT = (hbar*omega)/(BOLTZMANN*temperature); + double omega = scale_factor * eigval_to_frequency(eigval[i]); + double hwkT = (hbar * omega) / (BOLTZMANN * temperature); // Prevent overflow by checking for unreasonably large numbers. if (hwkT < 100) { - double dEvib = hwkT*(0.5 + 1.0/(std::expm1(hwkT))); + double dEvib = hwkT * (0.5 + 1.0 / (std::expm1(hwkT))); if (debug) { fprintf(debug, "i %d eigval %g omega %g hwkT %g dEvib %g\n", - static_cast(i+1), static_cast(eigval[i]), - omega, hwkT, dEvib); + static_cast(i + 1), static_cast(eigval[i]), omega, hwkT, dEvib); } Evib += dEvib; } } } - return temperature*BOLTZ*Evib; - + return temperature * BOLTZ * Evib; } -double calcVibrationalHeatCapacity(gmx::ArrayRef eigval, - real temperature, - gmx_bool linear, - real scale_factor) +double calcVibrationalHeatCapacity(gmx::ArrayRef eigval, real temperature, gmx_bool linear, real scale_factor) { size_t nskip = linear ? 5 : 6; double cv = 0; - double hbar = PLANCK1/(2*M_PI); + double hbar = PLANCK1 / (2 * M_PI); for (gmx::index i = nskip; i < eigval.ssize(); i++) { if (eigval[i] > 0) { - double omega = scale_factor*eigval_to_frequency(eigval[i]); - double hwkT = (hbar*omega)/(BOLTZMANN*temperature); + double omega = scale_factor * eigval_to_frequency(eigval[i]); + double hwkT = (hbar * omega) / (BOLTZMANN * temperature); // Prevent overflow by checking for unreasonably large numbers. if (hwkT < 100) { - double dcv = std::exp(hwkT)*gmx::square(hwkT/std::expm1(hwkT)); + double dcv = std::exp(hwkT) * gmx::square(hwkT / std::expm1(hwkT)); if (debug) { fprintf(debug, "i %d eigval %g omega %g hwkT %g dcv %g\n", - static_cast(i+1), static_cast(eigval[i]), omega, hwkT, dcv); + static_cast(i + 1), static_cast(eigval[i]), omega, hwkT, dcv); } cv += dcv; } @@ -126,27 +117,20 @@ double calcVibrationalHeatCapacity(gmx::ArrayRef eigval, return RGAS * cv; } -double calcTranslationalEntropy(real mass, - real temperature, - real pressure) +double calcTranslationalEntropy(real mass, real temperature, real pressure) { - double kT = BOLTZ*temperature; + double kT = BOLTZ * temperature; GMX_RELEASE_ASSERT(mass > 0, "Molecular mass should be larger than zero"); GMX_RELEASE_ASSERT(pressure > 0, "Pressure should be larger than zero"); GMX_RELEASE_ASSERT(temperature > 0, "Temperature should be larger than zero"); // Convert bar to Pascal - double P = pressure*1e5; - double qT = (std::pow(2*M_PI*mass*kT/gmx::square(PLANCK), 1.5) * - (kT/P) * (1e30/AVOGADRO)); - return RGAS*(std::log(qT) + 2.5); + double P = pressure * 1e5; + double qT = (std::pow(2 * M_PI * mass * kT / gmx::square(PLANCK), 1.5) * (kT / P) * (1e30 / AVOGADRO)); + return RGAS * (std::log(qT) + 2.5); } -double calcRotationalEntropy(real temperature, - int natom, - gmx_bool linear, - const rvec theta, - real sigma_r) +double calcRotationalEntropy(real temperature, int natom, gmx_bool linear, const rvec theta, real sigma_r) { GMX_RELEASE_ASSERT(sigma_r > 0, "Symmetry factor should be larger than zero"); GMX_RELEASE_ASSERT(temperature > 0, "Temperature should be larger than zero"); @@ -157,71 +141,63 @@ double calcRotationalEntropy(real temperature, if (linear) { GMX_RELEASE_ASSERT(theta[0] > 0, "Theta should be larger than zero"); - double qR = temperature/(sigma_r * theta[0]); + double qR = temperature / (sigma_r * theta[0]); sR = RGAS * (std::log(qR) + 1); } else { - double Q = theta[XX]*theta[YY]*theta[ZZ]; + double Q = theta[XX] * theta[YY] * theta[ZZ]; GMX_RELEASE_ASSERT(Q > 0, "Q should be larger than zero"); - double qR = std::sqrt(M_PI * std::pow(temperature, 3)/Q)/sigma_r; + double qR = std::sqrt(M_PI * std::pow(temperature, 3) / Q) / sigma_r; sR = RGAS * (std::log(qR) + 1.5); } } return sR; } -double calcQuasiHarmonicEntropy(gmx::ArrayRef eigval, - real temperature, - gmx_bool bLinear, - real scale_factor) +double calcQuasiHarmonicEntropy(gmx::ArrayRef eigval, real temperature, gmx_bool bLinear, real scale_factor) { size_t nskip = bLinear ? 5 : 6; double S = 0; - double hbar = PLANCK1/(2*M_PI); + double hbar = PLANCK1 / (2 * M_PI); for (gmx::index i = nskip; (i < eigval.ssize()); i++) { if (eigval[i] > 0) { - double omega = scale_factor*eigval_to_frequency(eigval[i]); - double hwkT = (hbar*omega)/(BOLTZMANN*temperature); - double dS = (hwkT/std::expm1(hwkT) - std::log1p(-std::exp(-hwkT))); - S += dS; + double omega = scale_factor * eigval_to_frequency(eigval[i]); + double hwkT = (hbar * omega) / (BOLTZMANN * temperature); + double dS = (hwkT / std::expm1(hwkT) - std::log1p(-std::exp(-hwkT))); + S += dS; if (debug) { fprintf(debug, "i = %5d eigval = %10g w = %10g hwkT = %10g dS = %10g\n", - static_cast(i+1), static_cast(eigval[i]), - omega, hwkT, dS); + static_cast(i + 1), static_cast(eigval[i]), omega, hwkT, dS); } } else if (debug) { - fprintf(debug, "eigval[%d] = %g\n", static_cast(i+1), - static_cast(eigval[i])); + fprintf(debug, "eigval[%d] = %g\n", static_cast(i + 1), static_cast(eigval[i])); } } - return S*RGAS; + return S * RGAS; } -double calcSchlitterEntropy(gmx::ArrayRef eigval, - real temperature, - gmx_bool bLinear) +double calcSchlitterEntropy(gmx::ArrayRef eigval, real temperature, gmx_bool bLinear) { size_t nskip = bLinear ? 5 : 6; - double hbar = PLANCK1/(2*M_PI); // J s - double kt = BOLTZMANN*temperature; // J - double kteh = kt*std::exp(2.0)/(hbar*hbar); // 1/(J s^2) = 1/(kg m^2) - double evcorr = NANO*NANO*AMU; + double hbar = PLANCK1 / (2 * M_PI); // J s + double kt = BOLTZMANN * temperature; // J + double kteh = kt * std::exp(2.0) / (hbar * hbar); // 1/(J s^2) = 1/(kg m^2) + double evcorr = NANO * NANO * AMU; if (debug) { - fprintf(debug, "n = %td, kteh = %g evcorr = %g\n", - ssize(eigval), kteh, evcorr); + fprintf(debug, "n = %td, kteh = %g evcorr = %g\n", ssize(eigval), kteh, evcorr); } double deter = 0; for (gmx::index i = nskip; i < eigval.ssize(); i++) { - double dd = 1+kteh*eigval[i]*evcorr; - deter += std::log(dd); + double dd = 1 + kteh * eigval[i] * evcorr; + deter += std::log(dd); } - return 0.5*RGAS*deter; + return 0.5 * RGAS * deter; } diff --git a/src/gromacs/gmxana/thermochemistry.h b/src/gromacs/gmxana/thermochemistry.h index 5d8010563c..b704d0e8d3 100644 --- a/src/gromacs/gmxana/thermochemistry.h +++ b/src/gromacs/gmxana/thermochemistry.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,8 +55,7 @@ * \param[in] scale_factor Factor to scale frequencies by before computing cv * \return The zero point energy (kJ/mol) */ -double calcZeroPointEnergy(gmx::ArrayRef eigval, - real scale_factor); +double calcZeroPointEnergy(gmx::ArrayRef eigval, real scale_factor); /*! \brief Compute heat capacity due to vibrational motion * @@ -82,9 +81,7 @@ double calcVibrationalHeatCapacity(gmx::ArrayRef eigval, * \param[in] pressure Pressure (bar) at which to compute * \returns The translational entropy (J/mol K) */ -double calcTranslationalEntropy(real mass, - real temperature, - real pressure); +double calcTranslationalEntropy(real mass, real temperature, real pressure); /*! \brief Compute entropy due to rotational motion * @@ -99,11 +96,7 @@ double calcTranslationalEntropy(real mass, * \param[in] sigma_r Symmetry factor, should be >= 1 * \returns The rotational entropy (J/mol K) */ -double calcRotationalEntropy(real temperature, - int natom, - gmx_bool linear, - const rvec theta, - real sigma_r); +double calcRotationalEntropy(real temperature, int natom, gmx_bool linear, const rvec theta, real sigma_r); /*! \brief Compute internal energy due to vibrational motion * @@ -131,9 +124,7 @@ double calcVibrationalInternalEnergy(gmx::ArrayRef eigval, * \param[in] linear True if this is a linear molecule (typically a diatomic molecule). * \return the entropy (J/mol K) */ -double calcSchlitterEntropy(gmx::ArrayRef eigval, - real temperature, - gmx_bool linear); +double calcSchlitterEntropy(gmx::ArrayRef eigval, real temperature, gmx_bool linear); /*! \brief Compute entropy using Quasi-Harmonic formula * @@ -148,9 +139,6 @@ double calcSchlitterEntropy(gmx::ArrayRef eigval, * \param[in] scale_factor Factor to scale frequencies by before computing S0 * \return the entropy (J/mol K) */ -double calcQuasiHarmonicEntropy(gmx::ArrayRef eigval, - real temperature, - gmx_bool linear, - real scale_factor); +double calcQuasiHarmonicEntropy(gmx::ArrayRef eigval, real temperature, gmx_bool linear, real scale_factor); #endif diff --git a/src/gromacs/gmxlib/conformation_utilities.cpp b/src/gromacs/gmxlib/conformation_utilities.cpp index c3d6dbd118..5af2587545 100644 --- a/src/gromacs/gmxlib/conformation_utilities.cpp +++ b/src/gromacs/gmxlib/conformation_utilities.cpp @@ -47,7 +47,7 @@ #include "gromacs/math/vec.h" #include "gromacs/pbcutil/pbc.h" -static void low_rotate_conf(int natom, rvec *x, real alfa, real beta, real gamma) +static void low_rotate_conf(int natom, rvec* x, real alfa, real beta, real gamma) { int i; rvec x_old; @@ -56,23 +56,23 @@ static void low_rotate_conf(int natom, rvec *x, real alfa, real beta, real gamma { copy_rvec(x[i], x_old); /*calculate new x[i] by rotation alfa around the x-axis*/ - x[i][XX] = x_old[XX]; - x[i][YY] = cos(alfa)*x_old[YY] - sin(alfa)*x_old[ZZ]; - x[i][ZZ] = sin(alfa)*x_old[YY] + cos(alfa)*x_old[ZZ]; + x[i][XX] = x_old[XX]; + x[i][YY] = cos(alfa) * x_old[YY] - sin(alfa) * x_old[ZZ]; + x[i][ZZ] = sin(alfa) * x_old[YY] + cos(alfa) * x_old[ZZ]; copy_rvec(x[i], x_old); /*calculate new x[i] by rotation beta around the y-axis*/ - x[i][XX] = cos(beta)*x_old[XX] + sin(beta)*x_old[ZZ]; - x[i][YY] = x_old[YY]; - x[i][ZZ] = -sin(beta)*x_old[XX] + cos(beta)*x_old[ZZ]; + x[i][XX] = cos(beta) * x_old[XX] + sin(beta) * x_old[ZZ]; + x[i][YY] = x_old[YY]; + x[i][ZZ] = -sin(beta) * x_old[XX] + cos(beta) * x_old[ZZ]; copy_rvec(x[i], x_old); /*calculate new x[i] by rotation gamma around the z-axis*/ - x[i][XX] = x_old[XX]*cos(gamma) - x_old[YY]*sin(gamma); - x[i][YY] = x_old[XX]*sin(gamma) + x_old[YY]*cos(gamma); - x[i][ZZ] = x_old[ZZ]; + x[i][XX] = x_old[XX] * cos(gamma) - x_old[YY] * sin(gamma); + x[i][YY] = x_old[XX] * sin(gamma) + x_old[YY] * cos(gamma); + x[i][ZZ] = x_old[ZZ]; } } -void rotate_conf(int natom, rvec *x, rvec *v, real alfa, real beta, real gamma) +void rotate_conf(int natom, rvec* x, rvec* v, real alfa, real beta, real gamma) { if (x) { @@ -85,8 +85,7 @@ void rotate_conf(int natom, rvec *x, rvec *v, real alfa, real beta, real gamma) } /* Make a new box around a configuration*/ -void make_new_box(int natoms, rvec *x, matrix box, const rvec box_space, - gmx_bool bCenter) +void make_new_box(int natoms, rvec* x, matrix box, const rvec box_space, gmx_bool bCenter) { int i, m; rvec xmin, xmax; @@ -108,7 +107,7 @@ void make_new_box(int natoms, rvec *x, matrix box, const rvec box_space, /*calculate the new box sizes for cubic and octahedral ...*/ for (m = 0; (m < DIM); m++) { - box[m][m] = xmax[m]-xmin[m]+2*box_space[m]; + box[m][m] = xmax[m] - xmin[m] + 2 * box_space[m]; } /*move the molecule to the center of the box*/ @@ -118,7 +117,7 @@ void make_new_box(int natoms, rvec *x, matrix box, const rvec box_space, { for (m = 0; (m < DIM); m++) { - x[i][m] += 0.5*(box[m][m]-xmin[m]-xmax[m]); + x[i][m] += 0.5 * (box[m][m] - xmin[m] - xmax[m]); } } } diff --git a/src/gromacs/gmxlib/conformation_utilities.h b/src/gromacs/gmxlib/conformation_utilities.h index b3dbc96f39..b8c0ec87ea 100644 --- a/src/gromacs/gmxlib/conformation_utilities.h +++ b/src/gromacs/gmxlib/conformation_utilities.h @@ -41,11 +41,10 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -void rotate_conf(int natom, rvec *x, rvec *v, real alfa, real beta, real gamma); +void rotate_conf(int natom, rvec* x, rvec* v, real alfa, real beta, real gamma); /*rotate() rotates a configuration alfa degrees around the x_axis and beta degrees around the y_axis, *v can be NULL */ -void make_new_box(int natoms, rvec *x, matrix box, const rvec box_space, - gmx_bool bCenter); +void make_new_box(int natoms, rvec* x, matrix box, const rvec box_space, gmx_bool bCenter); /* Generates a box around a configuration, box_space is optional extra * space around it. If bCenter then coordinates will be centered in * the generated box diff --git a/src/gromacs/gmxlib/network.cpp b/src/gromacs/gmxlib/network.cpp index cc5dbd573d..64c7c51d8c 100644 --- a/src/gromacs/gmxlib/network.cpp +++ b/src/gromacs/gmxlib/network.cpp @@ -60,20 +60,19 @@ /* The source code in this file should be thread-safe. Please keep it that way. */ -CommrecHandle init_commrec(MPI_Comm communicator, - const gmx_multisim_t *ms) +CommrecHandle init_commrec(MPI_Comm communicator, const gmx_multisim_t* ms) { CommrecHandle handle; - t_commrec *cr; + t_commrec* cr; snew(cr, 1); handle.reset(cr); int rankInCommunicator, sizeOfCommunicator; #if GMX_MPI -# if GMX_LIB_MPI +# if GMX_LIB_MPI GMX_RELEASE_ASSERT(gmx_mpi_initialized(), "Must have initialized MPI before building commrec"); -# endif +# endif MPI_Comm_rank(communicator, &rankInCommunicator); MPI_Comm_size(communicator, &sizeOfCommunicator); #else @@ -120,7 +119,7 @@ CommrecHandle init_commrec(MPI_Comm communicator, return handle; } -void done_commrec(t_commrec *cr) +void done_commrec(t_commrec* cr) { if (MASTER(cr)) { @@ -136,15 +135,12 @@ void done_commrec(t_commrec *cr) // structure of the commrec and domdec initialization code makes // it hard to avoid both leaks and double frees. bool mySimIsMyGroup = (cr->mpi_comm_mysim == cr->mpi_comm_mygroup); - if (cr->mpi_comm_mysim != MPI_COMM_NULL && - cr->mpi_comm_mysim != MPI_COMM_WORLD) + if (cr->mpi_comm_mysim != MPI_COMM_NULL && cr->mpi_comm_mysim != MPI_COMM_WORLD) { // TODO see above // MPI_Comm_free(&cr->mpi_comm_mysim); } - if (!mySimIsMyGroup && - cr->mpi_comm_mygroup != MPI_COMM_NULL && - cr->mpi_comm_mygroup != MPI_COMM_WORLD) + if (!mySimIsMyGroup && cr->mpi_comm_mygroup != MPI_COMM_NULL && cr->mpi_comm_mygroup != MPI_COMM_WORLD) { // TODO see above // MPI_Comm_free(&cr->mpi_comm_mygroup); @@ -153,9 +149,9 @@ void done_commrec(t_commrec *cr) sfree(cr); } -void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) +void gmx_setup_nodecomm(FILE gmx_unused* fplog, t_commrec* cr) { - gmx_nodecomm_t *nc; + gmx_nodecomm_t* nc; /* Many MPI implementations do not optimize MPI_Allreduce * (and probably also other global communication calls) @@ -172,7 +168,7 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) nc->bUse = FALSE; #if !GMX_THREAD_MPI -#if GMX_MPI +# if GMX_MPI int n, rank; // TODO PhysicalNodeCommunicator could be extended/used to handle @@ -193,8 +189,7 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) MPI_Comm_rank(nc->comm_intra, &nc->rank_intra); if (debug) { - fprintf(debug, "In gmx_setup_nodecomm: node ID %d rank within node %d\n", - rank, nc->rank_intra); + fprintf(debug, "In gmx_setup_nodecomm: node ID %d rank within node %d\n", rank, nc->rank_intra); } /* The inter-node communicator, split on rank_intra. * We actually only need the one for rank=0, @@ -208,18 +203,16 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) MPI_Comm_size(nc->comm_intra, &ni); if (debug) { - fprintf(debug, "In gmx_setup_nodecomm: groups %d, my group size %d\n", - ng, ni); + fprintf(debug, "In gmx_setup_nodecomm: groups %d, my group size %d\n", ng, ni); } - if (getenv("GMX_NO_NODECOMM") == nullptr && - ((ng > 1 && ng < n) || (ni > 1 && ni < n))) + if (getenv("GMX_NO_NODECOMM") == nullptr && ((ng > 1 && ng < n) || (ni > 1 && ni < n))) { nc->bUse = TRUE; if (fplog) { - fprintf(fplog, "Using two step summing over %d groups of on average %.1f ranks\n\n", - ng, (real)n/(real)ng); + fprintf(fplog, "Using two step summing over %d groups of on average %.1f ranks\n\n", ng, + (real)n / (real)ng); } if (nc->rank_intra > 0) { @@ -233,17 +226,19 @@ void gmx_setup_nodecomm(FILE gmx_unused *fplog, t_commrec *cr) MPI_Comm_free(&nc->comm_intra); if (debug) { - fprintf(debug, "In gmx_setup_nodecomm: not unsing separate inter- and intra-node communicators.\n"); + fprintf(debug, + "In gmx_setup_nodecomm: not unsing separate inter- and intra-node " + "communicators.\n"); } } -#endif +# endif #else /* tMPI runs only on a single node so just use the nodeid */ nc->rank_intra = cr->nodeid; #endif } -void gmx_barrier(const t_commrec gmx_unused *cr) +void gmx_barrier(const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_barrier"); @@ -252,7 +247,7 @@ void gmx_barrier(const t_commrec gmx_unused *cr) #endif } -void gmx_bcast(int gmx_unused nbytes, void gmx_unused *b, const t_commrec gmx_unused *cr) +void gmx_bcast(int gmx_unused nbytes, void gmx_unused* b, const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_bast"); @@ -261,7 +256,7 @@ void gmx_bcast(int gmx_unused nbytes, void gmx_unused *b, const t_commrec gmx_un #endif } -void gmx_bcast_sim(int gmx_unused nbytes, void gmx_unused *b, const t_commrec gmx_unused *cr) +void gmx_bcast_sim(int gmx_unused nbytes, void gmx_unused* b, const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_bast"); @@ -270,22 +265,20 @@ void gmx_bcast_sim(int gmx_unused nbytes, void gmx_unused *b, const t_commrec gm #endif } -void gmx_sumd(int gmx_unused nr, double gmx_unused r[], const t_commrec gmx_unused *cr) +void gmx_sumd(int gmx_unused nr, double gmx_unused r[], const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_sumd"); #else -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS if (cr->nc.bUse) { if (cr->nc.rank_intra == 0) { /* Use two step summing. */ - MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, 0, - cr->nc.comm_intra); + MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, 0, cr->nc.comm_intra); /* Sum the roots of the internal (intra) buffers. */ - MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, cr->nc.comm_inter); } else { @@ -297,10 +290,9 @@ void gmx_sumd(int gmx_unused nr, double gmx_unused r[], const t_commrec gmx_unus } else { - MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mygroup); + MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mygroup); } -#else +# else int i; if (nr > cr->mpb->dbuf_alloc) @@ -315,40 +307,36 @@ void gmx_sumd(int gmx_unused nr, double gmx_unused r[], const t_commrec gmx_unus if (cr->nc.rank_intra == 0) { /* Sum with the buffers reversed */ - MPI_Allreduce(cr->mpb->dbuf, r, nr, MPI_DOUBLE, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(cr->mpb->dbuf, r, nr, MPI_DOUBLE, MPI_SUM, cr->nc.comm_inter); } MPI_Bcast(r, nr, MPI_DOUBLE, 0, cr->nc.comm_intra); } else { - MPI_Allreduce(r, cr->mpb->dbuf, nr, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mygroup); + MPI_Allreduce(r, cr->mpb->dbuf, nr, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mygroup); for (i = 0; i < nr; i++) { r[i] = cr->mpb->dbuf[i]; } } -#endif +# endif #endif } -void gmx_sumf(int gmx_unused nr, float gmx_unused r[], const t_commrec gmx_unused *cr) +void gmx_sumf(int gmx_unused nr, float gmx_unused r[], const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_sumf"); #else -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS if (cr->nc.bUse) { /* Use two step summing. */ if (cr->nc.rank_intra == 0) { - MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, 0, - cr->nc.comm_intra); + MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, 0, cr->nc.comm_intra); /* Sum the roots of the internal (intra) buffers */ - MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, cr->nc.comm_inter); } else { @@ -362,7 +350,7 @@ void gmx_sumf(int gmx_unused nr, float gmx_unused r[], const t_commrec gmx_unuse { MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, cr->mpi_comm_mygroup); } -#else +# else int i; if (nr > cr->mpb->fbuf_alloc) @@ -377,30 +365,28 @@ void gmx_sumf(int gmx_unused nr, float gmx_unused r[], const t_commrec gmx_unuse if (cr->nc.rank_intra == 0) { /* Sum with the buffers reversed */ - MPI_Allreduce(cr->mpb->fbuf, r, nr, MPI_FLOAT, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(cr->mpb->fbuf, r, nr, MPI_FLOAT, MPI_SUM, cr->nc.comm_inter); } MPI_Bcast(r, nr, MPI_FLOAT, 0, cr->nc.comm_intra); } else { - MPI_Allreduce(r, cr->mpb->fbuf, nr, MPI_FLOAT, MPI_SUM, - cr->mpi_comm_mygroup); + MPI_Allreduce(r, cr->mpb->fbuf, nr, MPI_FLOAT, MPI_SUM, cr->mpi_comm_mygroup); for (i = 0; i < nr; i++) { r[i] = cr->mpb->fbuf[i]; } } -#endif +# endif #endif } -void gmx_sumi(int gmx_unused nr, int gmx_unused r[], const t_commrec gmx_unused *cr) +void gmx_sumi(int gmx_unused nr, int gmx_unused r[], const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_sumi"); #else -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS if (cr->nc.bUse) { /* Use two step summing */ @@ -422,7 +408,7 @@ void gmx_sumi(int gmx_unused nr, int gmx_unused r[], const t_commrec gmx_unused { MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT, MPI_SUM, cr->mpi_comm_mygroup); } -#else +# else int i; if (nr > cr->mpb->ibuf_alloc) @@ -449,26 +435,24 @@ void gmx_sumi(int gmx_unused nr, int gmx_unused r[], const t_commrec gmx_unused r[i] = cr->mpb->ibuf[i]; } } -#endif +# endif #endif } -void gmx_sumli(int gmx_unused nr, int64_t gmx_unused r[], const t_commrec gmx_unused *cr) +void gmx_sumli(int gmx_unused nr, int64_t gmx_unused r[], const t_commrec gmx_unused* cr) { #if !GMX_MPI gmx_call("gmx_sumli"); #else -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS if (cr->nc.bUse) { /* Use two step summing */ if (cr->nc.rank_intra == 0) { - MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, 0, - cr->nc.comm_intra); + MPI_Reduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, 0, cr->nc.comm_intra); /* Sum with the buffers reversed */ - MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, cr->nc.comm_inter); } else { @@ -482,7 +466,7 @@ void gmx_sumli(int gmx_unused nr, int64_t gmx_unused r[], const t_commrec gmx_un { MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, cr->mpi_comm_mygroup); } -#else +# else int i; if (nr > cr->mpb->libuf_alloc) @@ -493,43 +477,43 @@ void gmx_sumli(int gmx_unused nr, int64_t gmx_unused r[], const t_commrec gmx_un if (cr->nc.bUse) { /* Use two step summing */ - MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, - cr->nc.comm_intra); + MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, cr->nc.comm_intra); if (cr->nc.rank_intra == 0) { /* Sum with the buffers reversed */ - MPI_Allreduce(cr->mpb->libuf, r, nr, MPI_INT64_T, MPI_SUM, - cr->nc.comm_inter); + MPI_Allreduce(cr->mpb->libuf, r, nr, MPI_INT64_T, MPI_SUM, cr->nc.comm_inter); } MPI_Bcast(r, nr, MPI_INT64_T, 0, cr->nc.comm_intra); } else { - MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, - cr->mpi_comm_mygroup); + MPI_Allreduce(r, cr->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, cr->mpi_comm_mygroup); for (i = 0; i < nr; i++) { r[i] = cr->mpb->libuf[i]; } } -#endif +# endif #endif } -const char *opt2fn_master(const char *opt, int nfile, const t_filenm fnm[], - t_commrec *cr) +const char* opt2fn_master(const char* opt, int nfile, const t_filenm fnm[], t_commrec* cr) { return SIMMASTER(cr) ? opt2fn(opt, nfile, fnm) : nullptr; } -void gmx_fatal_collective(int f_errno, const char *file, int line, - MPI_Comm comm, gmx_bool bMaster, - gmx_fmtstr const char *fmt, ...) +void gmx_fatal_collective(int f_errno, + const char* file, + int line, + MPI_Comm comm, + gmx_bool bMaster, + gmx_fmtstr const char* fmt, + ...) { va_list ap; gmx_bool bFinalize; #if GMX_MPI - int result; + int result; /* Check if we are calling on all processes in MPI_COMM_WORLD */ MPI_Comm_compare(comm, MPI_COMM_WORLD, &result); /* Any result except MPI_UNEQUAL allows us to call MPI_Finalize */ @@ -544,7 +528,7 @@ void gmx_fatal_collective(int f_errno, const char *file, int line, va_end(ap); } -void simulationBarrier(const t_commrec *cr) +void simulationBarrier(const t_commrec* cr) { if (PAR(cr)) { diff --git a/src/gromacs/gmxlib/network.h b/src/gromacs/gmxlib/network.h index 6d931f60de..fd0196a295 100644 --- a/src/gromacs/gmxlib/network.h +++ b/src/gromacs/gmxlib/network.h @@ -53,16 +53,15 @@ struct t_commrec; struct t_filenm; //! Free memory associated with the commrec. -void done_commrec(t_commrec *cr); +void done_commrec(t_commrec* cr); //! Convenience alias. using CommrecHandle = gmx::unique_cptr; //! Allocate, initialize and return the commrec. -CommrecHandle init_commrec(MPI_Comm communicator, - const gmx_multisim_t *ms); +CommrecHandle init_commrec(MPI_Comm communicator, const gmx_multisim_t* ms); -struct t_commrec *reinitialize_commrec_for_this_thread(const t_commrec *cro); +struct t_commrec* reinitialize_commrec_for_this_thread(const t_commrec* cro); /* Initialize communication records for thread-parallel simulations. Must be called on all threads before any communication takes place by @@ -70,48 +69,50 @@ struct t_commrec *reinitialize_commrec_for_this_thread(const t_commrec *cro); thread-local versions (a small memory leak results because we don't deallocate the old shared version). */ -void gmx_fill_commrec_from_mpi(t_commrec *cr); +void gmx_fill_commrec_from_mpi(t_commrec* cr); /* Continues t_commrec construction */ -void gmx_setup_nodecomm(FILE *fplog, struct t_commrec *cr); +void gmx_setup_nodecomm(FILE* fplog, struct t_commrec* cr); /* Sets up fast global communication for clusters with multi-core nodes */ -void gmx_barrier(const struct t_commrec *cr); +void gmx_barrier(const struct t_commrec* cr); /* Wait till all processes in cr->mpi_comm_mygroup have reached the barrier */ -void gmx_bcast(int nbytes, void *b, const struct t_commrec *cr); +void gmx_bcast(int nbytes, void* b, const struct t_commrec* cr); /* Broadcast nbytes bytes from the master to cr->mpi_comm_mygroup */ -void gmx_bcast_sim(int nbytes, void *b, const struct t_commrec *cr); +void gmx_bcast_sim(int nbytes, void* b, const struct t_commrec* cr); /* Broadcast nbytes bytes from the sim master to cr->mpi_comm_mysim */ -void gmx_sumi(int nr, int r[], const struct t_commrec *cr); +void gmx_sumi(int nr, int r[], const struct t_commrec* cr); /* Calculate the global sum of an array of ints */ -void gmx_sumli(int nr, int64_t r[], const struct t_commrec *cr); +void gmx_sumli(int nr, int64_t r[], const struct t_commrec* cr); /* Calculate the global sum of an array of large ints */ -void gmx_sumf(int nr, float r[], const struct t_commrec *cr); +void gmx_sumf(int nr, float r[], const struct t_commrec* cr); /* Calculate the global sum of an array of floats */ -void gmx_sumd(int nr, double r[], const struct t_commrec *cr); +void gmx_sumd(int nr, double r[], const struct t_commrec* cr); /* Calculate the global sum of an array of doubles */ #if GMX_DOUBLE -#define gmx_sum gmx_sumd +# define gmx_sum gmx_sumd #else -#define gmx_sum gmx_sumf +# define gmx_sum gmx_sumf #endif -const char *opt2fn_master(const char *opt, int nfile, - const t_filenm fnm[], t_commrec *cr); +const char* opt2fn_master(const char* opt, int nfile, const t_filenm fnm[], t_commrec* cr); /* Return the filename belonging to cmd-line option opt, or NULL when * no such option or not running on master */ -[[ noreturn ]] void -gmx_fatal_collective(int f_errno, const char *file, int line, - MPI_Comm comm, gmx_bool bMaster, - gmx_fmtstr const char *fmt, ...) gmx_format(printf, 6, 7); +[[noreturn]] void gmx_fatal_collective(int f_errno, + const char* file, + int line, + MPI_Comm comm, + gmx_bool bMaster, + gmx_fmtstr const char* fmt, + ...) gmx_format(printf, 6, 7); /* As gmx_fatal declared in utility/fatalerror.h, * but only the master process prints the error message. * This should only be called one of the following two situations: @@ -123,6 +124,6 @@ gmx_fatal_collective(int f_errno, const char *file, int line, */ //! Make a barrier across all ranks of this simulation -void simulationBarrier(const t_commrec *cr); +void simulationBarrier(const t_commrec* cr); #endif diff --git a/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp b/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp index abe21c1a59..8395379dad 100644 --- a/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp +++ b/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp @@ -62,7 +62,7 @@ enum class SoftCoreTreatment }; //! Most treatments are fine with float in mixed-precision mode. -template +template struct SoftCoreReal { //! Real type for soft-core calculations @@ -70,7 +70,7 @@ struct SoftCoreReal }; //! This treatment requires double precision for some computations. -template <> +template<> struct SoftCoreReal { //! Real type for soft-core calculations @@ -78,36 +78,30 @@ struct SoftCoreReal }; //! Computes r^(1/p) and 1/r^(1/p) for the standard p=6 -template -static inline void pthRoot(const real r, - real *pthRoot, - real *invPthRoot) +template +static inline void pthRoot(const real r, real* pthRoot, real* invPthRoot) { *invPthRoot = gmx::invsqrt(std::cbrt(r)); - *pthRoot = 1/(*invPthRoot); + *pthRoot = 1 / (*invPthRoot); } // We need a double version to make the specialization below work #if !GMX_DOUBLE //! Computes r^(1/p) and 1/r^(1/p) for the standard p=6 -template -static inline void pthRoot(const double r, - real *pthRoot, - double *invPthRoot) +template +static inline void pthRoot(const double r, real* pthRoot, double* invPthRoot) { *invPthRoot = gmx::invsqrt(std::cbrt(r)); - *pthRoot = 1/(*invPthRoot); + *pthRoot = 1 / (*invPthRoot); } #endif //! Computes r^(1/p) and 1/r^(1/p) for p=48 -template <> -inline void pthRoot(const double r, - real *pthRoot, - double *invPthRoot) +template<> +inline void pthRoot(const double r, real* pthRoot, double* invPthRoot) { - *pthRoot = std::pow(r, 1.0/48.0); - *invPthRoot = 1/(*pthRoot); + *pthRoot = std::pow(r, 1.0 / 48.0); + *invPthRoot = 1 / (*pthRoot); } template @@ -153,55 +147,59 @@ static inline real calculateVdw12(const real c12, const real rinv6) /* reaction-field electrostatics */ template static inline SCReal -reactionFieldScalarForce(const real qq, const real rinv, const SCReal r, const real krf, - const real two) +reactionFieldScalarForce(const real qq, const real rinv, const SCReal r, const real krf, const real two) { - return (qq*(rinv - two*krf*r*r)); + return (qq * (rinv - two * krf * r * r)); } template static inline real -reactionFieldPotential(const real qq, const real rinv, const SCReal r, const real krf, - const real potentialShift) +reactionFieldPotential(const real qq, const real rinv, const SCReal r, const real krf, const real potentialShift) { - return (qq*(rinv + krf*r*r-potentialShift)); + return (qq * (rinv + krf * r * r - potentialShift)); } /* Ewald electrostatics */ -static inline real -ewaldScalarForce(const real coulomb, const real rinv) +static inline real ewaldScalarForce(const real coulomb, const real rinv) { - return (coulomb*rinv); + return (coulomb * rinv); } -static inline real -ewaldPotential(const real coulomb, const real rinv, const real potentialShift) +static inline real ewaldPotential(const real coulomb, const real rinv, const real potentialShift) { - return (coulomb*(rinv-potentialShift)); + return (coulomb * (rinv - potentialShift)); } /* cutoff LJ */ -static inline real -lennardJonesScalarForce(const real v6, const real v12) +static inline real lennardJonesScalarForce(const real v6, const real v12) { return (v12 - v6); } -static inline real -lennardJonesPotential(const real v6, const real v12, const real c6, const real c12, const real repulsionShift, - const real dispersionShift, const real onesixth, const real onetwelfth) +static inline real lennardJonesPotential(const real v6, + const real v12, + const real c6, + const real c12, + const real repulsionShift, + const real dispersionShift, + const real onesixth, + const real onetwelfth) { - return ((v12 + c12*repulsionShift)*onetwelfth - (v6 + c6*dispersionShift)*onesixth); + return ((v12 + c12 * repulsionShift) * onetwelfth - (v6 + c6 * dispersionShift) * onesixth); } /* Ewald LJ */ -static inline real -ewaldLennardJonesGridSubtract(const real c6grid, const real potentialShift, const real onesixth) +static inline real ewaldLennardJonesGridSubtract(const real c6grid, const real potentialShift, const real onesixth) { return (c6grid * potentialShift * onesixth); } /* LJ Potential switch */ template -static inline SCReal -potSwitchScalarForceMod(const SCReal fScalarInp, const real potential, const real sw, const SCReal r, const real rVdw, const real dsw, const real zero) +static inline SCReal potSwitchScalarForceMod(const SCReal fScalarInp, + const real potential, + const real sw, + const SCReal r, + const real rVdw, + const real dsw, + const real zero) { if (r < rVdw) { @@ -224,78 +222,73 @@ potSwitchPotentialMod(const real potentialInp, const real sw, const SCReal r, co //! Templated free-energy non-bonded kernel -template -static void -nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, - rvec * gmx_restrict xx, - gmx::ForceWithShiftForces * forceWithShiftForces, - const t_forcerec * gmx_restrict fr, - const t_mdatoms * gmx_restrict mdatoms, - nb_kernel_data_t * gmx_restrict kernel_data, - t_nrnb * gmx_restrict nrnb) +template +static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist, + rvec* gmx_restrict xx, + gmx::ForceWithShiftForces* forceWithShiftForces, + const t_forcerec* gmx_restrict fr, + const t_mdatoms* gmx_restrict mdatoms, + nb_kernel_data_t* gmx_restrict kernel_data, + t_nrnb* gmx_restrict nrnb) { using SCReal = typename SoftCoreReal::Real; constexpr bool useSoftCore = (softCoreTreatment != SoftCoreTreatment::None); -#define STATE_A 0 -#define STATE_B 1 -#define NSTATES 2 +#define STATE_A 0 +#define STATE_B 1 +#define NSTATES 2 - constexpr real onetwelfth = 1.0/12.0; - constexpr real onesixth = 1.0/6.0; - constexpr real zero = 0.0; - constexpr real half = 0.5; - constexpr real one = 1.0; - constexpr real two = 2.0; - constexpr real six = 6.0; + constexpr real onetwelfth = 1.0 / 12.0; + constexpr real onesixth = 1.0 / 6.0; + constexpr real zero = 0.0; + constexpr real half = 0.5; + constexpr real one = 1.0; + constexpr real two = 2.0; + constexpr real six = 6.0; /* Extract pointer to non-bonded interaction constants */ - const interaction_const_t *ic = fr->ic; + const interaction_const_t* ic = fr->ic; // Extract pair list data - const int nri = nlist->nri; - const int *iinr = nlist->iinr; - const int *jindex = nlist->jindex; - const int *jjnr = nlist->jjnr; - const int *shift = nlist->shift; - const int *gid = nlist->gid; - - const real *shiftvec = fr->shift_vec[0]; - const real *chargeA = mdatoms->chargeA; - const real *chargeB = mdatoms->chargeB; - real *Vc = kernel_data->energygrp_elec; - const int *typeA = mdatoms->typeA; - const int *typeB = mdatoms->typeB; - const int ntype = fr->ntype; - const real *nbfp = fr->nbfp; - const real *nbfp_grid = fr->ljpme_c6grid; - real *Vv = kernel_data->energygrp_vdw; - const real lambda_coul = kernel_data->lambda[efptCOUL]; - const real lambda_vdw = kernel_data->lambda[efptVDW]; - real *dvdl = kernel_data->dvdl; - const real alpha_coul = fr->sc_alphacoul; - const real alpha_vdw = fr->sc_alphavdw; - const real lam_power = fr->sc_power; - const real sigma6_def = fr->sc_sigma6_def; - const real sigma6_min = fr->sc_sigma6_min; - const bool doForces = ((kernel_data->flags & GMX_NONBONDED_DO_FORCE) != 0); - const bool doShiftForces = ((kernel_data->flags & GMX_NONBONDED_DO_SHIFTFORCE) != 0); - const bool doPotential = ((kernel_data->flags & GMX_NONBONDED_DO_POTENTIAL) != 0); + const int nri = nlist->nri; + const int* iinr = nlist->iinr; + const int* jindex = nlist->jindex; + const int* jjnr = nlist->jjnr; + const int* shift = nlist->shift; + const int* gid = nlist->gid; + + const real* shiftvec = fr->shift_vec[0]; + const real* chargeA = mdatoms->chargeA; + const real* chargeB = mdatoms->chargeB; + real* Vc = kernel_data->energygrp_elec; + const int* typeA = mdatoms->typeA; + const int* typeB = mdatoms->typeB; + const int ntype = fr->ntype; + const real* nbfp = fr->nbfp; + const real* nbfp_grid = fr->ljpme_c6grid; + real* Vv = kernel_data->energygrp_vdw; + const real lambda_coul = kernel_data->lambda[efptCOUL]; + const real lambda_vdw = kernel_data->lambda[efptVDW]; + real* dvdl = kernel_data->dvdl; + const real alpha_coul = fr->sc_alphacoul; + const real alpha_vdw = fr->sc_alphavdw; + const real lam_power = fr->sc_power; + const real sigma6_def = fr->sc_sigma6_def; + const real sigma6_min = fr->sc_sigma6_min; + const bool doForces = ((kernel_data->flags & GMX_NONBONDED_DO_FORCE) != 0); + const bool doShiftForces = ((kernel_data->flags & GMX_NONBONDED_DO_SHIFTFORCE) != 0); + const bool doPotential = ((kernel_data->flags & GMX_NONBONDED_DO_POTENTIAL) != 0); // Extract data from interaction_const_t - const real facel = ic->epsfac; - const real rcoulomb = ic->rcoulomb; - const real krf = ic->k_rf; - const real crf = ic->c_rf; - const real sh_lj_ewald = ic->sh_lj_ewald; - const real rvdw = ic->rvdw; - const real dispersionShift = ic->dispersion_shift.cpot; - const real repulsionShift = ic->repulsion_shift.cpot; + const real facel = ic->epsfac; + const real rcoulomb = ic->rcoulomb; + const real krf = ic->k_rf; + const real crf = ic->c_rf; + const real sh_lj_ewald = ic->sh_lj_ewald; + const real rvdw = ic->rvdw; + const real dispersionShift = ic->dispersion_shift.cpot; + const real repulsionShift = ic->repulsion_shift.cpot; // Note that the nbnxm kernels do not support Coulomb potential switching at all GMX_ASSERT(ic->coulomb_modifier != eintmodPOTSWITCH, @@ -305,12 +298,12 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, if (vdwModifierIsPotSwitch) { const real d = ic->rvdw - ic->rvdw_switch; - vdw_swV3 = -10.0/(d*d*d); - vdw_swV4 = 15.0/(d*d*d*d); - vdw_swV5 = -6.0/(d*d*d*d*d); - vdw_swF2 = -30.0/(d*d*d); - vdw_swF3 = 60.0/(d*d*d*d); - vdw_swF4 = -30.0/(d*d*d*d*d); + vdw_swV3 = -10.0 / (d * d * d); + vdw_swV4 = 15.0 / (d * d * d * d); + vdw_swV5 = -6.0 / (d * d * d * d * d); + vdw_swF2 = -30.0 / (d * d * d); + vdw_swF3 = 60.0 / (d * d * d * d); + vdw_swF4 = -30.0 / (d * d * d * d * d); } else { @@ -329,21 +322,21 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, } real rcutoff_max2 = std::max(ic->rcoulomb, ic->rvdw); - rcutoff_max2 = rcutoff_max2*rcutoff_max2; - - const real *tab_ewald_F_lj = nullptr; - const real *tab_ewald_V_lj = nullptr; - const real *ewtab = nullptr; - real ewtabscale = 0; - real ewtabhalfspace = 0; - real sh_ewald = 0; + rcutoff_max2 = rcutoff_max2 * rcutoff_max2; + + const real* tab_ewald_F_lj = nullptr; + const real* tab_ewald_V_lj = nullptr; + const real* ewtab = nullptr; + real ewtabscale = 0; + real ewtabhalfspace = 0; + real sh_ewald = 0; if (elecInteractionTypeIsEwald || vdwInteractionTypeIsEwald) { - const auto &tables = *ic->coulombEwaldTables; + const auto& tables = *ic->coulombEwaldTables; sh_ewald = ic->sh_ewald; ewtab = tables.tableFDV0.data(); ewtabscale = tables.scale; - ewtabhalfspace = half/ewtabscale; + ewtabhalfspace = half / ewtabscale; tab_ewald_F_lj = tables.tableF.data(); tab_ewald_V_lj = tables.tableV.data(); } @@ -360,11 +353,11 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * things (1/r rather than short-range Ewald). For these settings, we just * use the traditional short-range Ewald interaction in that case. */ - GMX_RELEASE_ASSERT(!(vdwInteractionTypeIsEwald && vdwModifierIsPotSwitch), + GMX_RELEASE_ASSERT(!(vdwInteractionTypeIsEwald && vdwModifierIsPotSwitch), "Can not apply soft-core to switched Ewald potentials"); - SCReal dvdl_coul = 0; /* Needs double for sc_power==48 */ - SCReal dvdl_vdw = 0; /* Needs double for sc_power==48 */ + SCReal dvdl_coul = 0; /* Needs double for sc_power==48 */ + SCReal dvdl_vdw = 0; /* Needs double for sc_power==48 */ /* Lambda factor for state A, 1-lambda*/ real LFC[NSTATES], LFV[NSTATES]; @@ -384,36 +377,36 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, constexpr real sc_r_power = (softCoreTreatment == SoftCoreTreatment::RPower48 ? 48.0_real : 6.0_real); for (int i = 0; i < NSTATES; i++) { - lfac_coul[i] = (lam_power == 2 ? (1-LFC[i])*(1-LFC[i]) : (1-LFC[i])); - dlfac_coul[i] = DLF[i]*lam_power/sc_r_power*(lam_power == 2 ? (1-LFC[i]) : 1); - lfac_vdw[i] = (lam_power == 2 ? (1-LFV[i])*(1-LFV[i]) : (1-LFV[i])); - dlfac_vdw[i] = DLF[i]*lam_power/sc_r_power*(lam_power == 2 ? (1-LFV[i]) : 1); + lfac_coul[i] = (lam_power == 2 ? (1 - LFC[i]) * (1 - LFC[i]) : (1 - LFC[i])); + dlfac_coul[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFC[i]) : 1); + lfac_vdw[i] = (lam_power == 2 ? (1 - LFV[i]) * (1 - LFV[i]) : (1 - LFV[i])); + dlfac_vdw[i] = DLF[i] * lam_power / sc_r_power * (lam_power == 2 ? (1 - LFV[i]) : 1); } // TODO: We should get rid of using pointers to real - const real *x = xx[0]; - real * gmx_restrict f = &(forceWithShiftForces->force()[0][0]); - real * gmx_restrict fshift = &(forceWithShiftForces->shiftForces()[0][0]); + const real* x = xx[0]; + real* gmx_restrict f = &(forceWithShiftForces->force()[0][0]); + real* gmx_restrict fshift = &(forceWithShiftForces->shiftForces()[0][0]); for (int n = 0; n < nri; n++) { - int npair_within_cutoff = 0; + int npair_within_cutoff = 0; - const int is3 = 3*shift[n]; + const int is3 = 3 * shift[n]; const real shX = shiftvec[is3]; - const real shY = shiftvec[is3+1]; - const real shZ = shiftvec[is3+2]; + const real shY = shiftvec[is3 + 1]; + const real shZ = shiftvec[is3 + 2]; const int nj0 = jindex[n]; - const int nj1 = jindex[n+1]; + const int nj1 = jindex[n + 1]; const int ii = iinr[n]; - const int ii3 = 3*ii; - const real ix = shX + x[ii3+0]; - const real iy = shY + x[ii3+1]; - const real iz = shZ + x[ii3+2]; - const real iqA = facel*chargeA[ii]; - const real iqB = facel*chargeB[ii]; - const int ntiA = 2*ntype*typeA[ii]; - const int ntiB = 2*ntype*typeB[ii]; + const int ii3 = 3 * ii; + const real ix = shX + x[ii3 + 0]; + const real iy = shY + x[ii3 + 1]; + const real iz = shZ + x[ii3 + 2]; + const real iqA = facel * chargeA[ii]; + const real iqB = facel * chargeB[ii]; + const int ntiA = 2 * ntype * typeA[ii]; + const int ntiB = 2 * ntype * typeB[ii]; real vctot = 0; real vvtot = 0; real fix = 0; @@ -423,16 +416,16 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, for (int k = nj0; k < nj1; k++) { int tj[NSTATES]; - const int jnr = jjnr[k]; - const int j3 = 3*jnr; + const int jnr = jjnr[k]; + const int j3 = 3 * jnr; real c6[NSTATES], c12[NSTATES], qq[NSTATES], Vcoul[NSTATES], Vvdw[NSTATES]; real r, rinv, rp, rpm2; real alpha_vdw_eff, alpha_coul_eff, sigma_pow[NSTATES]; - const real dx = ix - x[j3]; - const real dy = iy - x[j3+1]; - const real dz = iz - x[j3+2]; - const real rsq = dx*dx + dy*dy + dz*dz; - SCReal FscalC[NSTATES], FscalV[NSTATES]; /* Needs double for sc_power==48 */ + const real dx = ix - x[j3]; + const real dy = iy - x[j3 + 1]; + const real dz = iz - x[j3 + 2]; + const real rsq = dx * dx + dy * dy + dz * dz; + SCReal FscalC[NSTATES], FscalV[NSTATES]; /* Needs double for sc_power==48 */ if (rsq >= rcutoff_max2) { @@ -453,8 +446,8 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * not calculate LJ interactions when C6 and C12 are zero. */ - rinv = gmx::invsqrt(rsq); - r = rsq*rinv; + rinv = gmx::invsqrt(rsq); + r = rsq * rinv; } else { @@ -462,8 +455,8 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * But note that the potential is in general non-zero, * since the soft-cored r will be non-zero. */ - rinv = 0; - r = 0; + rinv = 0; + r = 0; } if (softCoreTreatment == SoftCoreTreatment::None) @@ -472,54 +465,54 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * with not using soft-core, so we use power of 0 which gives * the simplest math and cheapest code. */ - rpm2 = rinv*rinv; - rp = 1; + rpm2 = rinv * rinv; + rp = 1; } if (softCoreTreatment == SoftCoreTreatment::RPower6) { - rpm2 = rsq*rsq; /* r4 */ - rp = rpm2*rsq; /* r6 */ + rpm2 = rsq * rsq; /* r4 */ + rp = rpm2 * rsq; /* r6 */ } if (softCoreTreatment == SoftCoreTreatment::RPower48) { - rp = rsq*rsq*rsq; /* r6 */ - rp = rp*rp; /* r12 */ - rp = rp*rp; /* r24 */ - rp = rp*rp; /* r48 */ - rpm2 = rp/rsq; /* r46 */ + rp = rsq * rsq * rsq; /* r6 */ + rp = rp * rp; /* r12 */ + rp = rp * rp; /* r24 */ + rp = rp * rp; /* r48 */ + rpm2 = rp / rsq; /* r46 */ } real Fscal = 0; - qq[STATE_A] = iqA*chargeA[jnr]; - qq[STATE_B] = iqB*chargeB[jnr]; + qq[STATE_A] = iqA * chargeA[jnr]; + qq[STATE_B] = iqB * chargeB[jnr]; - tj[STATE_A] = ntiA+2*typeA[jnr]; - tj[STATE_B] = ntiB+2*typeB[jnr]; + tj[STATE_A] = ntiA + 2 * typeA[jnr]; + tj[STATE_B] = ntiB + 2 * typeB[jnr]; if (nlist->excl_fep == nullptr || nlist->excl_fep[k]) { - c6[STATE_A] = nbfp[tj[STATE_A]]; - c6[STATE_B] = nbfp[tj[STATE_B]]; + c6[STATE_A] = nbfp[tj[STATE_A]]; + c6[STATE_B] = nbfp[tj[STATE_B]]; for (int i = 0; i < NSTATES; i++) { - c12[i] = nbfp[tj[i]+1]; + c12[i] = nbfp[tj[i] + 1]; if (useSoftCore) { real sigma6[NSTATES]; if ((c6[i] > 0) && (c12[i] > 0)) { /* c12 is stored scaled with 12.0 and c6 is scaled with 6.0 - correct for this */ - sigma6[i] = half*c12[i]/c6[i]; - if (sigma6[i] < sigma6_min) /* for disappearing coul and vdw with soft core at the same time */ + sigma6[i] = half * c12[i] / c6[i]; + if (sigma6[i] < sigma6_min) /* for disappearing coul and vdw with soft core at the same time */ { sigma6[i] = sigma6_min; } } else { - sigma6[i] = sigma6_def; + sigma6[i] = sigma6_def; } sigma_pow[i] = calculateSigmaPow(sigma6[i]); } @@ -530,13 +523,13 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, /* only use softcore if one of the states has a zero endstate - softcore is for avoiding infinities!*/ if ((c12[STATE_A] > 0) && (c12[STATE_B] > 0)) { - alpha_vdw_eff = 0; - alpha_coul_eff = 0; + alpha_vdw_eff = 0; + alpha_coul_eff = 0; } else { - alpha_vdw_eff = alpha_vdw; - alpha_coul_eff = alpha_coul; + alpha_vdw_eff = alpha_vdw; + alpha_coul_eff = alpha_coul; } } @@ -551,16 +544,16 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, SCReal rC, rV, rpinvC, rpinvV; /* Needs double for sc_power==48 */ /* Only spend time on A or B state if it is non-zero */ - if ( (qq[i] != 0) || (c6[i] != 0) || (c12[i] != 0) ) + if ((qq[i] != 0) || (c6[i] != 0) || (c12[i] != 0)) { /* this section has to be inside the loop because of the dependence on sigma_pow */ if (useSoftCore) { - rpinvC = one/(alpha_coul_eff*lfac_coul[i]*sigma_pow[i]+rp); + rpinvC = one / (alpha_coul_eff * lfac_coul[i] * sigma_pow[i] + rp); pthRoot(rpinvC, &rinvC, &rC); if (scLambdasOrAlphasDiffer) { - rpinvV = one/(alpha_vdw_eff*lfac_vdw[i]*sigma_pow[i]+rp); + rpinvV = one / (alpha_vdw_eff * lfac_vdw[i] * sigma_pow[i] + rp); pthRoot(rpinvV, &rinvV, &rV); } else @@ -573,24 +566,23 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, } else { - rpinvC = 1; - rinvC = rinv; - rC = r; + rpinvC = 1; + rinvC = rinv; + rC = r; - rpinvV = 1; - rinvV = rinv; - rV = r; + rpinvV = 1; + rinvV = rinv; + rV = r; } /* Only process the coulomb interactions if we have charges, * and if we either include all entries in the list (no cutoff * used in the kernel), or if we are within the cutoff. */ - bool computeElecInteraction = - ( elecInteractionTypeIsEwald && r < rcoulomb) || - (!elecInteractionTypeIsEwald && rC < rcoulomb); + bool computeElecInteraction = (elecInteractionTypeIsEwald && r < rcoulomb) + || (!elecInteractionTypeIsEwald && rC < rcoulomb); - if ( (qq[i] != 0) && computeElecInteraction) + if ((qq[i] != 0) && computeElecInteraction) { if (elecInteractionTypeIsEwald) { @@ -609,41 +601,43 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * include all entries in the list (no cutoff used * in the kernel), or if we are within the cutoff. */ - bool computeVdwInteraction = - ( vdwInteractionTypeIsEwald && r < rvdw) || - (!vdwInteractionTypeIsEwald && rV < rvdw); + bool computeVdwInteraction = (vdwInteractionTypeIsEwald && r < rvdw) + || (!vdwInteractionTypeIsEwald && rV < rvdw); if ((c6[i] != 0 || c12[i] != 0) && computeVdwInteraction) { real rinv6; if (softCoreTreatment == SoftCoreTreatment::RPower6) { - rinv6 = calculateRinv6(rpinvV); + rinv6 = calculateRinv6(rpinvV); } else { - rinv6 = calculateRinv6(rinvV); + rinv6 = calculateRinv6(rinvV); } - real Vvdw6 = calculateVdw6(c6[i], rinv6); - real Vvdw12 = calculateVdw12(c12[i], rinv6); + real Vvdw6 = calculateVdw6(c6[i], rinv6); + real Vvdw12 = calculateVdw12(c12[i], rinv6); - Vvdw[i] = lennardJonesPotential(Vvdw6, Vvdw12, c6[i], c12[i], repulsionShift, dispersionShift, onesixth, onetwelfth); - FscalV[i] = lennardJonesScalarForce(Vvdw6, Vvdw12); + Vvdw[i] = lennardJonesPotential(Vvdw6, Vvdw12, c6[i], c12[i], repulsionShift, + dispersionShift, onesixth, onetwelfth); + FscalV[i] = lennardJonesScalarForce(Vvdw6, Vvdw12); if (vdwInteractionTypeIsEwald) { /* Subtract the grid potential at the cut-off */ - Vvdw[i] += ewaldLennardJonesGridSubtract(nbfp_grid[tj[i]], sh_lj_ewald, onesixth); + Vvdw[i] += ewaldLennardJonesGridSubtract(nbfp_grid[tj[i]], + sh_lj_ewald, onesixth); } if (vdwModifierIsPotSwitch) { - real d = rV - ic->rvdw_switch; - d = (d > zero) ? d : zero; - const real d2 = d*d; - const real sw = one+d2*d*(vdw_swV3+d*(vdw_swV4+d*vdw_swV5)); - const real dsw = d2*(vdw_swF2+d*(vdw_swF3+d*vdw_swF4)); - - FscalV[i] = potSwitchScalarForceMod(FscalV[i], Vvdw[i], sw, rV, rvdw, dsw, zero); + real d = rV - ic->rvdw_switch; + d = (d > zero) ? d : zero; + const real d2 = d * d; + const real sw = one + d2 * d * (vdw_swV3 + d * (vdw_swV4 + d * vdw_swV5)); + const real dsw = d2 * (vdw_swF2 + d * (vdw_swF3 + d * vdw_swF4)); + + FscalV[i] = potSwitchScalarForceMod(FscalV[i], Vvdw[i], sw, rV, + rvdw, dsw, zero); Vvdw[i] = potSwitchPotentialMod(Vvdw[i], sw, rV, rvdw, zero); } } @@ -661,21 +655,24 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, /* Assemble A and B states */ for (int i = 0; i < NSTATES; i++) { - vctot += LFC[i]*Vcoul[i]; - vvtot += LFV[i]*Vvdw[i]; + vctot += LFC[i] * Vcoul[i]; + vvtot += LFV[i] * Vvdw[i]; - Fscal += LFC[i]*FscalC[i]*rpm2; - Fscal += LFV[i]*FscalV[i]*rpm2; + Fscal += LFC[i] * FscalC[i] * rpm2; + Fscal += LFV[i] * FscalV[i] * rpm2; if (useSoftCore) { - dvdl_coul += Vcoul[i]*DLF[i] + LFC[i]*alpha_coul_eff*dlfac_coul[i]*FscalC[i]*sigma_pow[i]; - dvdl_vdw += Vvdw[i]*DLF[i] + LFV[i]*alpha_vdw_eff*dlfac_vdw[i]*FscalV[i]*sigma_pow[i]; + dvdl_coul += + Vcoul[i] * DLF[i] + + LFC[i] * alpha_coul_eff * dlfac_coul[i] * FscalC[i] * sigma_pow[i]; + dvdl_vdw += Vvdw[i] * DLF[i] + + LFV[i] * alpha_vdw_eff * dlfac_vdw[i] * FscalV[i] * sigma_pow[i]; } else { - dvdl_coul += Vcoul[i]*DLF[i]; - dvdl_vdw += Vvdw[i]*DLF[i]; + dvdl_coul += Vcoul[i] * DLF[i]; + dvdl_vdw += Vvdw[i] * DLF[i]; } } } @@ -685,8 +682,8 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * using the Verlet scheme, we don't use soft-core. * As there is no singularity, there is no need for soft-core. */ - const real FF = -two*krf; - real VV = krf*rsq - crf; + const real FF = -two * krf; + real VV = krf * rsq - crf; if (ii == jnr) { @@ -695,9 +692,9 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, for (int i = 0; i < NSTATES; i++) { - vctot += LFC[i]*qq[i]*VV; - Fscal += LFC[i]*qq[i]*FF; - dvdl_coul += DLF[i]*qq[i]*VV; + vctot += LFC[i] * qq[i] * VV; + Fscal += LFC[i] * qq[i] * FF; + dvdl_coul += DLF[i] * qq[i] * VV; } } @@ -711,15 +708,15 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * the softcore to the entire electrostatic interaction, * including the reciprocal-space component. */ - real v_lr, f_lr; + real v_lr, f_lr; - const real ewrt = r*ewtabscale; + const real ewrt = r * ewtabscale; int ewitab = static_cast(ewrt); const real eweps = ewrt - ewitab; - ewitab = 4*ewitab; - f_lr = ewtab[ewitab] + eweps*ewtab[ewitab+1]; - v_lr = (ewtab[ewitab + 2] - ewtabhalfspace*eweps*(ewtab[ewitab] + f_lr)); - f_lr *= rinv; + ewitab = 4 * ewitab; + f_lr = ewtab[ewitab] + eweps * ewtab[ewitab + 1]; + v_lr = (ewtab[ewitab + 2] - ewtabhalfspace * eweps * (ewtab[ewitab] + f_lr)); + f_lr *= rinv; /* Note that any possible Ewald shift has already been applied in * the normal interaction part above. @@ -737,9 +734,9 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, for (int i = 0; i < NSTATES; i++) { - vctot -= LFC[i]*qq[i]*v_lr; - Fscal -= LFC[i]*qq[i]*f_lr; - dvdl_coul -= (DLF[i]*qq[i])*v_lr; + vctot -= LFC[i] * qq[i] * v_lr; + Fscal -= LFC[i] * qq[i] * f_lr; + dvdl_coul -= (DLF[i] * qq[i]) * v_lr; } } @@ -758,15 +755,15 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * r close to 0 for non-interacting pairs. */ - const real rs = rsq*rinv*ewtabscale; + const real rs = rsq * rinv * ewtabscale; const int ri = static_cast(rs); const real frac = rs - ri; - const real f_lr = (1 - frac)*tab_ewald_F_lj[ri] + frac*tab_ewald_F_lj[ri+1]; + const real f_lr = (1 - frac) * tab_ewald_F_lj[ri] + frac * tab_ewald_F_lj[ri + 1]; /* TODO: Currently the Ewald LJ table does not contain * the factor 1/6, we should add this. */ - const real FF = f_lr*rinv/six; - real VV = (tab_ewald_V_lj[ri] - ewtabhalfspace*frac*(tab_ewald_F_lj[ri] + f_lr))/six; + const real FF = f_lr * rinv / six; + real VV = (tab_ewald_V_lj[ri] - ewtabhalfspace * frac * (tab_ewald_F_lj[ri] + f_lr)) / six; if (ii == jnr) { @@ -781,20 +778,20 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, for (int i = 0; i < NSTATES; i++) { const real c6grid = nbfp_grid[tj[i]]; - vvtot += LFV[i]*c6grid*VV; - Fscal += LFV[i]*c6grid*FF; - dvdl_vdw += (DLF[i]*c6grid)*VV; + vvtot += LFV[i] * c6grid * VV; + Fscal += LFV[i] * c6grid * FF; + dvdl_vdw += (DLF[i] * c6grid) * VV; } } if (doForces) { - const real tx = Fscal*dx; - const real ty = Fscal*dy; - const real tz = Fscal*dz; - fix = fix + tx; - fiy = fiy + ty; - fiz = fiz + tz; + const real tx = Fscal * dx; + const real ty = Fscal * dy; + const real tz = Fscal * dz; + fix = fix + tx; + fiy = fiy + ty; + fiz = fiz + tz; /* OpenMP atomics are expensive, but this kernels is also * expensive, so we can take this hit, instead of using * thread-local output buffers and extra reduction. @@ -803,11 +800,11 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, * not throw, so no need for try/catch. */ #pragma omp atomic - f[j3] -= tx; + f[j3] -= tx; #pragma omp atomic - f[j3+1] -= ty; + f[j3 + 1] -= ty; #pragma omp atomic - f[j3+2] -= tz; + f[j3 + 2] -= tz; } } @@ -821,24 +818,24 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, if (doForces) { #pragma omp atomic - f[ii3] += fix; + f[ii3] += fix; #pragma omp atomic - f[ii3+1] += fiy; + f[ii3 + 1] += fiy; #pragma omp atomic - f[ii3+2] += fiz; + f[ii3 + 2] += fiz; } if (doShiftForces) { #pragma omp atomic - fshift[is3] += fix; + fshift[is3] += fix; #pragma omp atomic - fshift[is3+1] += fiy; + fshift[is3 + 1] += fiy; #pragma omp atomic - fshift[is3+2] += fiz; + fshift[is3 + 2] += fiz; } if (doPotential) { - int ggid = gid[n]; + int ggid = gid[n]; #pragma omp atomic Vc[ggid] += vctot; #pragma omp atomic @@ -848,142 +845,128 @@ nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, } #pragma omp atomic - dvdl[efptCOUL] += dvdl_coul; - #pragma omp atomic - dvdl[efptVDW] += dvdl_vdw; + dvdl[efptCOUL] += dvdl_coul; +#pragma omp atomic + dvdl[efptVDW] += dvdl_vdw; /* Estimate flops, average for free energy stuff: * 12 flops per outer iteration * 150 flops per inner iteration */ #pragma omp atomic - inc_nrnb(nrnb, eNR_NBKERNEL_FREE_ENERGY, nlist->nri*12 + nlist->jindex[nri]*150); + inc_nrnb(nrnb, eNR_NBKERNEL_FREE_ENERGY, nlist->nri * 12 + nlist->jindex[nri] * 150); } -typedef void (* KernelFunction)(const t_nblist * gmx_restrict nlist, - rvec * gmx_restrict xx, - gmx::ForceWithShiftForces * forceWithShiftForces, - const t_forcerec * gmx_restrict fr, - const t_mdatoms * gmx_restrict mdatoms, - nb_kernel_data_t * gmx_restrict kernel_data, - t_nrnb * gmx_restrict nrnb); - -template -static KernelFunction -dispatchKernelOnVdwModifier(const bool vdwModifierIsPotSwitch) +typedef void (*KernelFunction)(const t_nblist* gmx_restrict nlist, + rvec* gmx_restrict xx, + gmx::ForceWithShiftForces* forceWithShiftForces, + const t_forcerec* gmx_restrict fr, + const t_mdatoms* gmx_restrict mdatoms, + nb_kernel_data_t* gmx_restrict kernel_data, + t_nrnb* gmx_restrict nrnb); + +template +static KernelFunction dispatchKernelOnVdwModifier(const bool vdwModifierIsPotSwitch) { if (vdwModifierIsPotSwitch) { - return(nb_free_energy_kernel); + return (nb_free_energy_kernel); } else { - return(nb_free_energy_kernel); + return (nb_free_energy_kernel); } } -template -static KernelFunction -dispatchKernelOnElecInteractionType(const bool elecInteractionTypeIsEwald, - const bool vdwModifierIsPotSwitch) +template +static KernelFunction dispatchKernelOnElecInteractionType(const bool elecInteractionTypeIsEwald, + const bool vdwModifierIsPotSwitch) { if (elecInteractionTypeIsEwald) { - return(dispatchKernelOnVdwModifier(vdwModifierIsPotSwitch)); + return (dispatchKernelOnVdwModifier( + vdwModifierIsPotSwitch)); } else { - return(dispatchKernelOnVdwModifier(vdwModifierIsPotSwitch)); + return (dispatchKernelOnVdwModifier( + vdwModifierIsPotSwitch)); } } -template -static KernelFunction -dispatchKernelOnVdwInteractionType(const bool vdwInteractionTypeIsEwald, - const bool elecInteractionTypeIsEwald, - const bool vdwModifierIsPotSwitch) +template +static KernelFunction dispatchKernelOnVdwInteractionType(const bool vdwInteractionTypeIsEwald, + const bool elecInteractionTypeIsEwald, + const bool vdwModifierIsPotSwitch) { if (vdwInteractionTypeIsEwald) { - return(dispatchKernelOnElecInteractionType(elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); + return (dispatchKernelOnElecInteractionType( + elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); } else { - return(dispatchKernelOnElecInteractionType(elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); + return (dispatchKernelOnElecInteractionType( + elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); } } template -static KernelFunction -dispatchKernelOnScLambdasOrAlphasDifference(const bool scLambdasOrAlphasDiffer, - const bool vdwInteractionTypeIsEwald, - const bool elecInteractionTypeIsEwald, - const bool vdwModifierIsPotSwitch) +static KernelFunction dispatchKernelOnScLambdasOrAlphasDifference(const bool scLambdasOrAlphasDiffer, + const bool vdwInteractionTypeIsEwald, + const bool elecInteractionTypeIsEwald, + const bool vdwModifierIsPotSwitch) { if (scLambdasOrAlphasDiffer) { - return(dispatchKernelOnVdwInteractionType(vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch)); + return (dispatchKernelOnVdwInteractionType( + vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); } else { - return(dispatchKernelOnVdwInteractionType(vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch)); + return (dispatchKernelOnVdwInteractionType( + vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, vdwModifierIsPotSwitch)); } } -static KernelFunction -dispatchKernel(const bool scLambdasOrAlphasDiffer, - const bool vdwInteractionTypeIsEwald, - const bool elecInteractionTypeIsEwald, - const bool vdwModifierIsPotSwitch, - const t_forcerec *fr) +static KernelFunction dispatchKernel(const bool scLambdasOrAlphasDiffer, + const bool vdwInteractionTypeIsEwald, + const bool elecInteractionTypeIsEwald, + const bool vdwModifierIsPotSwitch, + const t_forcerec* fr) { if (fr->sc_alphacoul == 0 && fr->sc_alphavdw == 0) { - return(dispatchKernelOnScLambdasOrAlphasDifference(scLambdasOrAlphasDiffer, - vdwInteractionTypeIsEwald, - elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch)); + return (dispatchKernelOnScLambdasOrAlphasDifference( + scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, + vdwModifierIsPotSwitch)); } else if (fr->sc_r_power == 6.0_real) { - return(dispatchKernelOnScLambdasOrAlphasDifference(scLambdasOrAlphasDiffer, - vdwInteractionTypeIsEwald, - elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch)); + return (dispatchKernelOnScLambdasOrAlphasDifference( + scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, + vdwModifierIsPotSwitch)); } else { - return(dispatchKernelOnScLambdasOrAlphasDifference(scLambdasOrAlphasDiffer, - vdwInteractionTypeIsEwald, - elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch)); + return (dispatchKernelOnScLambdasOrAlphasDifference( + scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, + vdwModifierIsPotSwitch)); } } -void gmx_nb_free_energy_kernel(const t_nblist *nlist, - rvec *xx, - gmx::ForceWithShiftForces *ff, - const t_forcerec *fr, - const t_mdatoms *mdatoms, - nb_kernel_data_t *kernel_data, - t_nrnb *nrnb) +void gmx_nb_free_energy_kernel(const t_nblist* nlist, + rvec* xx, + gmx::ForceWithShiftForces* ff, + const t_forcerec* fr, + const t_mdatoms* mdatoms, + nb_kernel_data_t* kernel_data, + t_nrnb* nrnb) { - GMX_ASSERT(EEL_PME_EWALD(fr->ic->eeltype) || fr->ic->eeltype == eelCUT || EEL_RF(fr->ic->eeltype), + GMX_ASSERT(EEL_PME_EWALD(fr->ic->eeltype) || fr->ic->eeltype == eelCUT || EEL_RF(fr->ic->eeltype), "Unsupported eeltype with free energy"); const bool vdwInteractionTypeIsEwald = (EVDW_PME(fr->ic->vdwtype)); @@ -997,8 +980,7 @@ void gmx_nb_free_energy_kernel(const t_nblist *nlist, } else if (fr->sc_r_power == 6.0_real || fr->sc_r_power == 48.0_real) { - if (kernel_data->lambda[efptCOUL] == kernel_data->lambda[efptVDW] && - fr->sc_alphacoul == fr->sc_alphavdw) + if (kernel_data->lambda[efptCOUL] == kernel_data->lambda[efptVDW] && fr->sc_alphacoul == fr->sc_alphavdw) { scLambdasOrAlphasDiffer = false; } @@ -1007,7 +989,7 @@ void gmx_nb_free_energy_kernel(const t_nblist *nlist, { GMX_RELEASE_ASSERT(false, "Unsupported soft-core r-power"); } - KernelFunction kernelFunc = dispatchKernel(scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, elecInteractionTypeIsEwald, - vdwModifierIsPotSwitch, fr); + KernelFunction kernelFunc = dispatchKernel(scLambdasOrAlphasDiffer, vdwInteractionTypeIsEwald, + elecInteractionTypeIsEwald, vdwModifierIsPotSwitch, fr); kernelFunc(nlist, xx, ff, fr, mdatoms, kernel_data, nrnb); } diff --git a/src/gromacs/gmxlib/nonbonded/nb_free_energy.h b/src/gromacs/gmxlib/nonbonded/nb_free_energy.h index cf4394fee4..75070022ee 100644 --- a/src/gromacs/gmxlib/nonbonded/nb_free_energy.h +++ b/src/gromacs/gmxlib/nonbonded/nb_free_energy.h @@ -50,13 +50,12 @@ namespace gmx class ForceWithShiftForces; } -void - gmx_nb_free_energy_kernel(const t_nblist * gmx_restrict nlist, - rvec * gmx_restrict xx, - gmx::ForceWithShiftForces * forceWithShiftForces, - const t_forcerec * gmx_restrict fr, - const t_mdatoms * gmx_restrict mdatoms, - nb_kernel_data_t * gmx_restrict kernel_data, - t_nrnb * gmx_restrict nrnb); +void gmx_nb_free_energy_kernel(const t_nblist* gmx_restrict nlist, + rvec* gmx_restrict xx, + gmx::ForceWithShiftForces* forceWithShiftForces, + const t_forcerec* gmx_restrict fr, + const t_mdatoms* gmx_restrict mdatoms, + nb_kernel_data_t* gmx_restrict kernel_data, + t_nrnb* gmx_restrict nrnb); #endif diff --git a/src/gromacs/gmxlib/nonbonded/nb_kernel.h b/src/gromacs/gmxlib/nonbonded/nb_kernel.h index a9dc4a94d9..b90f7404ae 100644 --- a/src/gromacs/gmxlib/nonbonded/nb_kernel.h +++ b/src/gromacs/gmxlib/nonbonded/nb_kernel.h @@ -52,29 +52,27 @@ struct t_blocka; typedef struct { int flags; - const struct t_blocka *exclusions; - real *lambda; - real *dvdl; + const struct t_blocka* exclusions; + real* lambda; + real* dvdl; /* pointers to tables */ - t_forcetable * table_elec; - t_forcetable * table_vdw; - t_forcetable * table_elec_vdw; + t_forcetable* table_elec; + t_forcetable* table_vdw; + t_forcetable* table_elec_vdw; /* potentials */ - real * energygrp_elec; - real * energygrp_vdw; -} -nb_kernel_data_t; + real* energygrp_elec; + real* energygrp_vdw; +} nb_kernel_data_t; -typedef void - nb_kernel_t (t_nblist * gmx_restrict nlist, - rvec * gmx_restrict x, - rvec * gmx_restrict f, - struct t_forcerec * gmx_restrict fr, - t_mdatoms * gmx_restrict mdatoms, - nb_kernel_data_t * gmx_restrict kernel_data, - t_nrnb * gmx_restrict nrnb); +typedef void nb_kernel_t(t_nblist* gmx_restrict nlist, + rvec* gmx_restrict x, + rvec* gmx_restrict f, + struct t_forcerec* gmx_restrict fr, + t_mdatoms* gmx_restrict mdatoms, + nb_kernel_data_t* gmx_restrict kernel_data, + t_nrnb* gmx_restrict nrnb); #endif /* _nb_kernel_h_ */ diff --git a/src/gromacs/gmxlib/nonbonded/nonbonded.h b/src/gromacs/gmxlib/nonbonded/nonbonded.h index 40a4bbd2cf..9ab0997104 100644 --- a/src/gromacs/gmxlib/nonbonded/nonbonded.h +++ b/src/gromacs/gmxlib/nonbonded/nonbonded.h @@ -37,10 +37,10 @@ #ifndef GMX_GMXLIB_NONBONDED_NONBONDED_H #define GMX_GMXLIB_NONBONDED_NONBONDED_H -#define GMX_NONBONDED_DO_FORCE (1<<1) -#define GMX_NONBONDED_DO_SHIFTFORCE (1<<2) -#define GMX_NONBONDED_DO_FOREIGNLAMBDA (1<<3) -#define GMX_NONBONDED_DO_POTENTIAL (1<<4) -#define GMX_NONBONDED_DO_SR (1<<5) +#define GMX_NONBONDED_DO_FORCE (1 << 1) +#define GMX_NONBONDED_DO_SHIFTFORCE (1 << 2) +#define GMX_NONBONDED_DO_FOREIGNLAMBDA (1 << 3) +#define GMX_NONBONDED_DO_POTENTIAL (1 << 4) +#define GMX_NONBONDED_DO_SR (1 << 5) #endif diff --git a/src/gromacs/gmxlib/nrnb.cpp b/src/gromacs/gmxlib/nrnb.cpp index 1eea461821..77598f0108 100644 --- a/src/gromacs/gmxlib/nrnb.cpp +++ b/src/gromacs/gmxlib/nrnb.cpp @@ -48,8 +48,9 @@ #include "gromacs/mdtypes/md_enums.h" #include "gromacs/utility/arraysize.h" -typedef struct { - const char *name; +typedef struct +{ + const char* name; int flop; } t_nrnb_data; @@ -58,34 +59,34 @@ static const t_nrnb_data nbdata[eNRNB] = { /* These are re-used for different NB kernels, since there are so many. * The actual number of flops is set dynamically. */ - { "NB VdW [V&F]", 1 }, - { "NB VdW [F]", 1 }, - { "NB Elec. [V&F]", 1 }, - { "NB Elec. [F]", 1 }, - { "NB Elec. [W3,V&F]", 1 }, - { "NB Elec. [W3,F]", 1 }, - { "NB Elec. [W3-W3,V&F]", 1 }, - { "NB Elec. [W3-W3,F]", 1 }, - { "NB Elec. [W4,V&F]", 1 }, - { "NB Elec. [W4,F]", 1 }, - { "NB Elec. [W4-W4,V&F]", 1 }, - { "NB Elec. [W4-W4,F]", 1 }, - { "NB VdW & Elec. [V&F]", 1 }, - { "NB VdW & Elec. [F]", 1 }, - { "NB VdW & Elec. [W3,V&F]", 1 }, - { "NB VdW & Elec. [W3,F]", 1 }, - { "NB VdW & Elec. [W3-W3,V&F]", 1 }, - { "NB VdW & Elec. [W3-W3,F]", 1 }, - { "NB VdW & Elec. [W4,V&F]", 1 }, - { "NB VdW & Elec. [W4,F]", 1 }, - { "NB VdW & Elec. [W4-W4,V&F]", 1 }, - { "NB VdW & Elec. [W4-W4,F]", 1 }, - - { "NB Generic kernel", 1 }, - { "NB Generic charge grp kernel", 1 }, - { "NB Free energy kernel", 1 }, - - { "Pair Search distance check", 9 }, /* nbnxn pair dist. check */ + { "NB VdW [V&F]", 1 }, + { "NB VdW [F]", 1 }, + { "NB Elec. [V&F]", 1 }, + { "NB Elec. [F]", 1 }, + { "NB Elec. [W3,V&F]", 1 }, + { "NB Elec. [W3,F]", 1 }, + { "NB Elec. [W3-W3,V&F]", 1 }, + { "NB Elec. [W3-W3,F]", 1 }, + { "NB Elec. [W4,V&F]", 1 }, + { "NB Elec. [W4,F]", 1 }, + { "NB Elec. [W4-W4,V&F]", 1 }, + { "NB Elec. [W4-W4,F]", 1 }, + { "NB VdW & Elec. [V&F]", 1 }, + { "NB VdW & Elec. [F]", 1 }, + { "NB VdW & Elec. [W3,V&F]", 1 }, + { "NB VdW & Elec. [W3,F]", 1 }, + { "NB VdW & Elec. [W3-W3,V&F]", 1 }, + { "NB VdW & Elec. [W3-W3,F]", 1 }, + { "NB VdW & Elec. [W4,V&F]", 1 }, + { "NB VdW & Elec. [W4,F]", 1 }, + { "NB VdW & Elec. [W4-W4,V&F]", 1 }, + { "NB VdW & Elec. [W4-W4,F]", 1 }, + + { "NB Generic kernel", 1 }, + { "NB Generic charge grp kernel", 1 }, + { "NB Free energy kernel", 1 }, + + { "Pair Search distance check", 9 }, /* nbnxn pair dist. check */ /* nbnxn kernel flops are based on inner-loops without exclusion checks. * Plain Coulomb runs through the RF kernels, except with GPUs. * invsqrt is counted as 6 flops: 1 for _mm_rsqt_ps + 5 for iteration. @@ -96,99 +97,99 @@ static const t_nrnb_data nbdata[eNRNB] = { * - GPU always does exclusions, which requires 2-4 flops, but as invsqrt * is always counted as 6 flops, this roughly compensates. */ - { "NxN RF Elec. + LJ [F]", 38 }, /* nbnxn kernel LJ+RF, no ener */ - { "NxN RF Elec. + LJ [V&F]", 54 }, - { "NxN QSTab Elec. + LJ [F]", 41 }, /* nbnxn kernel LJ+tab, no en */ - { "NxN QSTab Elec. + LJ [V&F]", 59 }, - { "NxN Ewald Elec. + LJ [F]", 66 }, /* nbnxn kernel LJ+Ewald, no en */ - { "NxN Ewald Elec. + LJ [V&F]", 107 }, - { "NxN LJ [F]", 33 }, /* nbnxn kernel LJ, no ener */ - { "NxN LJ [V&F]", 43 }, - { "NxN RF Electrostatics [F]", 31 }, /* nbnxn kernel RF, no ener */ - { "NxN RF Electrostatics [V&F]", 36 }, - { "NxN QSTab Elec. [F]", 34 }, /* nbnxn kernel tab, no ener */ - { "NxN QSTab Elec. [V&F]", 41 }, - { "NxN Ewald Elec. [F]", 61 }, /* nbnxn kernel Ewald, no ener */ - { "NxN Ewald Elec. [V&F]", 84 }, + { "NxN RF Elec. + LJ [F]", 38 }, /* nbnxn kernel LJ+RF, no ener */ + { "NxN RF Elec. + LJ [V&F]", 54 }, + { "NxN QSTab Elec. + LJ [F]", 41 }, /* nbnxn kernel LJ+tab, no en */ + { "NxN QSTab Elec. + LJ [V&F]", 59 }, + { "NxN Ewald Elec. + LJ [F]", 66 }, /* nbnxn kernel LJ+Ewald, no en */ + { "NxN Ewald Elec. + LJ [V&F]", 107 }, + { "NxN LJ [F]", 33 }, /* nbnxn kernel LJ, no ener */ + { "NxN LJ [V&F]", 43 }, + { "NxN RF Electrostatics [F]", 31 }, /* nbnxn kernel RF, no ener */ + { "NxN RF Electrostatics [V&F]", 36 }, + { "NxN QSTab Elec. [F]", 34 }, /* nbnxn kernel tab, no ener */ + { "NxN QSTab Elec. [V&F]", 41 }, + { "NxN Ewald Elec. [F]", 61 }, /* nbnxn kernel Ewald, no ener */ + { "NxN Ewald Elec. [V&F]", 84 }, /* The switch function flops should be added to the LJ kernels above */ - { "NxN LJ add F-switch [F]", 12 }, /* extra cost for LJ F-switch */ - { "NxN LJ add F-switch [V&F]", 22 }, - { "NxN LJ add P-switch [F]", 27 }, /* extra cost for LJ P-switch */ - { "NxN LJ add P-switch [V&F]", 20 }, - { "NxN LJ add LJ Ewald [F]", 36 }, /* extra cost for LJ Ewald */ - { "NxN LJ add LJ Ewald [V&F]", 33 }, - { "1,4 nonbonded interactions", 90 }, - { "Calc Weights", 36 }, - { "Spread Q", 6 }, - { "Spread Q Bspline", 2 }, - { "Gather F", 23 }, - { "Gather F Bspline", 6 }, - { "3D-FFT", 8 }, - { "Convolution", 4 }, - { "Solve PME", 64 }, - { "NS-Pairs", 21 }, - { "Reset In Box", 3 }, - { "Shift-X", 6 }, - { "CG-CoM", 3 }, - { "Sum Forces", 1 }, - { "Bonds", 59 }, - { "G96Bonds", 44 }, - { "FENE Bonds", 58 }, - { "Tab. Bonds", 62 }, - { "Restraint Potential", 86 }, - { "Linear Angles", 57 }, - { "Angles", 168 }, - { "G96Angles", 150 }, - { "Quartic Angles", 160 }, - { "Tab. Angles", 169 }, - { "Propers", 229 }, - { "Impropers", 208 }, - { "RB-Dihedrals", 247 }, - { "Four. Dihedrals", 247 }, - { "Tab. Dihedrals", 227 }, - { "Dist. Restr.", 200 }, - { "Orient. Restr.", 200 }, - { "Dihedral Restr.", 200 }, - { "Pos. Restr.", 50 }, - { "Flat-bottom posres", 50 }, - { "Angle Restr.", 191 }, - { "Angle Restr. Z", 164 }, - { "Morse Potent.", 83 }, - { "Cubic Bonds", 54 }, - { "Walls", 31 }, - { "Polarization", 59 }, - { "Anharmonic Polarization", 72 }, - { "Water Pol.", 62 }, - { "Thole Pol.", 296 }, - { "Virial", 18 }, - { "Update", 31 }, - { "Ext.ens. Update", 54 }, - { "Stop-CM", 10 }, - { "P-Coupling", 6 }, - { "Calc-Ekin", 27 }, - { "Lincs", 60 }, - { "Lincs-Mat", 4 }, - { "Shake", 30 }, - { "Constraint-V", 8 }, - { "Shake-Init", 10 }, - { "Constraint-Vir", 24 }, - { "Settle", 323 }, - { "Virtual Site 2", 23 }, - { "Virtual Site 2fd", 63 }, - { "Virtual Site 3", 37 }, - { "Virtual Site 3fd", 95 }, - { "Virtual Site 3fad", 176 }, - { "Virtual Site 3out", 87 }, - { "Virtual Site 4fd", 110 }, - { "Virtual Site 4fdn", 254 }, - { "Virtual Site N", 15 }, - { "CMAP", 1700 }, // Estimate! - { "Urey-Bradley", 183 }, - { "Cross-Bond-Bond", 163 }, - { "Cross-Bond-Angle", 163 } + { "NxN LJ add F-switch [F]", 12 }, /* extra cost for LJ F-switch */ + { "NxN LJ add F-switch [V&F]", 22 }, + { "NxN LJ add P-switch [F]", 27 }, /* extra cost for LJ P-switch */ + { "NxN LJ add P-switch [V&F]", 20 }, + { "NxN LJ add LJ Ewald [F]", 36 }, /* extra cost for LJ Ewald */ + { "NxN LJ add LJ Ewald [V&F]", 33 }, + { "1,4 nonbonded interactions", 90 }, + { "Calc Weights", 36 }, + { "Spread Q", 6 }, + { "Spread Q Bspline", 2 }, + { "Gather F", 23 }, + { "Gather F Bspline", 6 }, + { "3D-FFT", 8 }, + { "Convolution", 4 }, + { "Solve PME", 64 }, + { "NS-Pairs", 21 }, + { "Reset In Box", 3 }, + { "Shift-X", 6 }, + { "CG-CoM", 3 }, + { "Sum Forces", 1 }, + { "Bonds", 59 }, + { "G96Bonds", 44 }, + { "FENE Bonds", 58 }, + { "Tab. Bonds", 62 }, + { "Restraint Potential", 86 }, + { "Linear Angles", 57 }, + { "Angles", 168 }, + { "G96Angles", 150 }, + { "Quartic Angles", 160 }, + { "Tab. Angles", 169 }, + { "Propers", 229 }, + { "Impropers", 208 }, + { "RB-Dihedrals", 247 }, + { "Four. Dihedrals", 247 }, + { "Tab. Dihedrals", 227 }, + { "Dist. Restr.", 200 }, + { "Orient. Restr.", 200 }, + { "Dihedral Restr.", 200 }, + { "Pos. Restr.", 50 }, + { "Flat-bottom posres", 50 }, + { "Angle Restr.", 191 }, + { "Angle Restr. Z", 164 }, + { "Morse Potent.", 83 }, + { "Cubic Bonds", 54 }, + { "Walls", 31 }, + { "Polarization", 59 }, + { "Anharmonic Polarization", 72 }, + { "Water Pol.", 62 }, + { "Thole Pol.", 296 }, + { "Virial", 18 }, + { "Update", 31 }, + { "Ext.ens. Update", 54 }, + { "Stop-CM", 10 }, + { "P-Coupling", 6 }, + { "Calc-Ekin", 27 }, + { "Lincs", 60 }, + { "Lincs-Mat", 4 }, + { "Shake", 30 }, + { "Constraint-V", 8 }, + { "Shake-Init", 10 }, + { "Constraint-Vir", 24 }, + { "Settle", 323 }, + { "Virtual Site 2", 23 }, + { "Virtual Site 2fd", 63 }, + { "Virtual Site 3", 37 }, + { "Virtual Site 3fd", 95 }, + { "Virtual Site 3fad", 176 }, + { "Virtual Site 3out", 87 }, + { "Virtual Site 4fd", 110 }, + { "Virtual Site 4fdn", 254 }, + { "Virtual Site N", 15 }, + { "CMAP", 1700 }, // Estimate! + { "Urey-Bradley", 183 }, + { "Cross-Bond-Bond", 163 }, + { "Cross-Bond-Angle", 163 } }; -static void pr_two(FILE *out, int c, int i) +static void pr_two(FILE* out, int c, int i) { if (i < 10) { @@ -200,17 +201,17 @@ static void pr_two(FILE *out, int c, int i) } } -static void pr_difftime(FILE *out, double dt) +static void pr_difftime(FILE* out, double dt) { - int ndays, nhours, nmins, nsecs; - gmx_bool bPrint, bPrinted; - - ndays = static_cast(dt/(24*3600)); - dt = dt-24*3600*ndays; - nhours = static_cast(dt/3600); - dt = dt-3600*nhours; - nmins = static_cast(dt/60); - dt = dt-nmins*60; + int ndays, nhours, nmins, nsecs; + gmx_bool bPrint, bPrinted; + + ndays = static_cast(dt / (24 * 3600)); + dt = dt - 24 * 3600 * ndays; + nhours = static_cast(dt / 3600); + dt = dt - 3600 * nhours; + nmins = static_cast(dt / 60); + dt = dt - nmins * 60; nsecs = static_cast(dt); bPrint = (ndays > 0); bPrinted = bPrint; @@ -255,7 +256,7 @@ static void pr_difftime(FILE *out, double dt) fprintf(out, "\n"); } -void clear_nrnb(t_nrnb *nrnb) +void clear_nrnb(t_nrnb* nrnb) { int i; @@ -265,17 +266,17 @@ void clear_nrnb(t_nrnb *nrnb) } } -void add_nrnb(t_nrnb *dest, t_nrnb *s1, t_nrnb *s2) +void add_nrnb(t_nrnb* dest, t_nrnb* s1, t_nrnb* s2) { int i; for (i = 0; (i < eNRNB); i++) { - dest->n[i] = s1->n[i]+s2->n[i]; + dest->n[i] = s1->n[i] + s2->n[i]; } } -void print_nrnb(FILE *out, t_nrnb *nrnb) +void print_nrnb(FILE* out, t_nrnb* nrnb) { int i; @@ -288,12 +289,12 @@ void print_nrnb(FILE *out, t_nrnb *nrnb) } } -void _inc_nrnb(t_nrnb *nrnb, int enr, int inc, char gmx_unused *file, int gmx_unused line) +void _inc_nrnb(t_nrnb* nrnb, int enr, int inc, char gmx_unused* file, int gmx_unused line) { nrnb->n[enr] += inc; #ifdef DEBUG_NRNB - printf("nrnb %15s(%2d) incremented with %8d from file %s line %d\n", - nbdata[enr].name, enr, inc, file, line); + printf("nrnb %15s(%2d) incremented with %8d from file %s line %d\n", nbdata[enr].name, enr, inc, + file, line); #endif } @@ -309,40 +310,41 @@ static gmx_bool nrnb_is_nbnxn_kernel_addition(int enr) return (enr >= eNR_NBNXN_ADD_LJ_FSW && enr <= eNR_NBNXN_ADD_LJ_EWALD_E); } -void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop) +void print_flop(FILE* out, t_nrnb* nrnb, double* nbfs, double* mflop) { - int i, j; - double mni, frac, tfrac, tflop; - const char *myline = "-----------------------------------------------------------------------------"; + int i, j; + double mni, frac, tfrac, tflop; + const char* myline = + "-----------------------------------------------------------------------------"; *nbfs = 0.0; for (i = 0; (i < eNR_NBKERNEL_TOTAL_NR); i++) { if (std::strstr(nbdata[i].name, "W3-W3") != nullptr) { - *nbfs += 9e-6*nrnb->n[i]; + *nbfs += 9e-6 * nrnb->n[i]; } else if (std::strstr(nbdata[i].name, "W3") != nullptr) { - *nbfs += 3e-6*nrnb->n[i]; + *nbfs += 3e-6 * nrnb->n[i]; } else if (std::strstr(nbdata[i].name, "W4-W4") != nullptr) { - *nbfs += 10e-6*nrnb->n[i]; + *nbfs += 10e-6 * nrnb->n[i]; } else if (std::strstr(nbdata[i].name, "W4") != nullptr) { - *nbfs += 4e-6*nrnb->n[i]; + *nbfs += 4e-6 * nrnb->n[i]; } else { - *nbfs += 1e-6*nrnb->n[i]; + *nbfs += 1e-6 * nrnb->n[i]; } } tflop = 0; for (i = 0; (i < eNRNB); i++) { - tflop += 1e-6*nrnb->n[i]*nbdata[i].flop; + tflop += 1e-6 * nrnb->n[i] * nbdata[i].flop; } if (tflop == 0) @@ -362,15 +364,14 @@ void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop) fprintf(out, " W3=SPC/TIP3p W4=TIP4p (single or pairs)\n"); fprintf(out, " V&F=Potential and force V=Potential only F=Force only\n\n"); - fprintf(out, " %-32s %16s %15s %7s\n", - "Computing:", "M-Number", "M-Flops", "% Flops"); + fprintf(out, " %-32s %16s %15s %7s\n", "Computing:", "M-Number", "M-Flops", "% Flops"); fprintf(out, "%s\n", myline); } *mflop = 0.0; tfrac = 0.0; for (i = 0; (i < eNRNB); i++) { - mni = 1e-6*nrnb->n[i]; + mni = 1e-6 * nrnb->n[i]; /* Skip empty entries and nbnxn additional flops, * which have been added to the kernel entry. */ @@ -378,7 +379,7 @@ void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop) { int flop; - flop = nbdata[i].flop; + flop = nbdata[i].flop; if (nrnb_is_nbnxn_vdw_kernel(i)) { /* Possibly add the cost of an LJ switch/Ewald function */ @@ -395,21 +396,19 @@ void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop) } } } - *mflop += mni*flop; - frac = 100.0*mni*flop/tflop; - tfrac += frac; + *mflop += mni * flop; + frac = 100.0 * mni * flop / tflop; + tfrac += frac; if (out != nullptr) { - fprintf(out, " %-32s %16.6f %15.3f %6.1f\n", - nbdata[i].name, mni, mni*flop, frac); + fprintf(out, " %-32s %16.6f %15.3f %6.1f\n", nbdata[i].name, mni, mni * flop, frac); } } } if (out) { fprintf(out, "%s\n", myline); - fprintf(out, " %-32s %16s %15.3f %6.1f\n", - "Total", "", *mflop, tfrac); + fprintf(out, " %-32s %16s %15.3f %6.1f\n", "Total", "", *mflop, tfrac); fprintf(out, "%s\n\n", myline); if (nrnb->n[eNR_NBKERNEL_GENERIC] > 0) @@ -423,9 +422,13 @@ void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop) } } -void print_perf(FILE *out, double time_per_thread, double time_per_node, - int64_t nsteps, double delta_t, - double nbfs, double mflop) +void print_perf(FILE* out, + double time_per_thread, + double time_per_node, + int64_t nsteps, + double delta_t, + double nbfs, + double mflop) { double wallclocktime; @@ -434,53 +437,47 @@ void print_perf(FILE *out, double time_per_thread, double time_per_node, if (time_per_node > 0) { fprintf(out, "%12s %12s %12s %10s\n", "", "Core t (s)", "Wall t (s)", "(%)"); - fprintf(out, "%12s %12.3f %12.3f %10.1f\n", "Time:", - time_per_thread, time_per_node, 100.0*time_per_thread/time_per_node); + fprintf(out, "%12s %12.3f %12.3f %10.1f\n", "Time:", time_per_thread, time_per_node, + 100.0 * time_per_thread / time_per_node); /* only print day-hour-sec format if time_per_node is more than 30 min */ - if (time_per_node > 30*60) + if (time_per_node > 30 * 60) { fprintf(out, "%12s %12s", "", ""); pr_difftime(out, time_per_node); } if (delta_t > 0) { - mflop = mflop/time_per_node; - wallclocktime = nsteps*delta_t; + mflop = mflop / time_per_node; + wallclocktime = nsteps * delta_t; if (getenv("GMX_DETAILED_PERF_STATS") == nullptr) { - fprintf(out, "%12s %12s %12s\n", - "", "(ns/day)", "(hour/ns)"); - fprintf(out, "%12s %12.3f %12.3f\n", "Performance:", - wallclocktime*24*3.6/time_per_node, 1000*time_per_node/(3600*wallclocktime)); + fprintf(out, "%12s %12s %12s\n", "", "(ns/day)", "(hour/ns)"); + fprintf(out, "%12s %12.3f %12.3f\n", "Performance:", wallclocktime * 24 * 3.6 / time_per_node, + 1000 * time_per_node / (3600 * wallclocktime)); } else { - fprintf(out, "%12s %12s %12s %12s %12s\n", - "", "(Mnbf/s)", (mflop > 1000) ? "(GFlops)" : "(MFlops)", - "(ns/day)", "(hour/ns)"); - fprintf(out, "%12s %12.3f %12.3f %12.3f %12.3f\n", "Performance:", - nbfs/time_per_node, (mflop > 1000) ? (mflop/1000) : mflop, - wallclocktime*24*3.6/time_per_node, 1000*time_per_node/(3600*wallclocktime)); + fprintf(out, "%12s %12s %12s %12s %12s\n", "", "(Mnbf/s)", + (mflop > 1000) ? "(GFlops)" : "(MFlops)", "(ns/day)", "(hour/ns)"); + fprintf(out, "%12s %12.3f %12.3f %12.3f %12.3f\n", "Performance:", nbfs / time_per_node, + (mflop > 1000) ? (mflop / 1000) : mflop, wallclocktime * 24 * 3.6 / time_per_node, + 1000 * time_per_node / (3600 * wallclocktime)); } } else { if (getenv("GMX_DETAILED_PERF_STATS") == nullptr) { - fprintf(out, "%12s %14s\n", - "", "(steps/hour)"); - fprintf(out, "%12s %14.1f\n", "Performance:", - nsteps*3600.0/time_per_node); + fprintf(out, "%12s %14s\n", "", "(steps/hour)"); + fprintf(out, "%12s %14.1f\n", "Performance:", nsteps * 3600.0 / time_per_node); } else { - fprintf(out, "%12s %12s %12s %14s\n", - "", "(Mnbf/s)", (mflop > 1000) ? "(GFlops)" : "(MFlops)", - "(steps/hour)"); - fprintf(out, "%12s %12.3f %12.3f %14.1f\n", "Performance:", - nbfs/time_per_node, (mflop > 1000) ? (mflop/1000) : mflop, - nsteps*3600.0/time_per_node); + fprintf(out, "%12s %12s %12s %14s\n", "", "(Mnbf/s)", + (mflop > 1000) ? "(GFlops)" : "(MFlops)", "(steps/hour)"); + fprintf(out, "%12s %12.3f %12.3f %14.1f\n", "Performance:", nbfs / time_per_node, + (mflop > 1000) ? (mflop / 1000) : mflop, nsteps * 3600.0 / time_per_node); } } } @@ -491,26 +488,22 @@ int cost_nrnb(int enr) return nbdata[enr].flop; } -const char *nrnb_str(int enr) +const char* nrnb_str(int enr) { return nbdata[enr].name; } -static const int force_index[] = { - eNR_BONDS, eNR_ANGLES, eNR_PROPER, eNR_IMPROPER, - eNR_RB, eNR_DISRES, eNR_ORIRES, eNR_POSRES, - eNR_FBPOSRES, eNR_NS, +static const int force_index[] = { + eNR_BONDS, eNR_ANGLES, eNR_PROPER, eNR_IMPROPER, eNR_RB, + eNR_DISRES, eNR_ORIRES, eNR_POSRES, eNR_FBPOSRES, eNR_NS, }; #define NFORCE_INDEX asize(force_index) -static const int constr_index[] = { - eNR_SHAKE, eNR_SHAKE_RIJ, eNR_SETTLE, eNR_UPDATE, eNR_PCOUPL, - eNR_CONSTR_VIR, eNR_CONSTR_V -}; +static const int constr_index[] = { eNR_SHAKE, eNR_SHAKE_RIJ, eNR_SETTLE, eNR_UPDATE, + eNR_PCOUPL, eNR_CONSTR_VIR, eNR_CONSTR_V }; #define NCONSTR_INDEX asize(constr_index) -static double pr_av(FILE *log, t_commrec *cr, - double fav, const double ftot[], const char *title) +static double pr_av(FILE* log, t_commrec* cr, double fav, const double ftot[], const char* title) { int i, perc; double dperc, unb; @@ -522,14 +515,14 @@ static double pr_av(FILE *log, t_commrec *cr, fprintf(log, "\n %-26s", title); for (i = 0; (i < cr->nnodes); i++) { - dperc = (100.0*ftot[i])/fav; + dperc = (100.0 * ftot[i]) / fav; unb = std::max(unb, dperc); perc = static_cast(dperc); fprintf(log, "%3d ", perc); } if (unb > 0) { - perc = static_cast(10000.0/unb); + perc = static_cast(10000.0 / unb); fprintf(log, "%6d%%\n\n", perc); } else @@ -540,9 +533,9 @@ static double pr_av(FILE *log, t_commrec *cr, return unb; } -void pr_load(FILE *log, t_commrec *cr, t_nrnb nrnb[]) +void pr_load(FILE* log, t_commrec* cr, t_nrnb nrnb[]) { - t_nrnb av; + t_nrnb av; std::vector ftot(cr->nnodes); std::vector stot(cr->nnodes); @@ -552,21 +545,21 @@ void pr_load(FILE *log, t_commrec *cr, t_nrnb nrnb[]) /* Cost due to forces */ for (int j = 0; (j < eNR_NBKERNEL_TOTAL_NR); j++) { - ftot[i] += nrnb[i].n[j]*cost_nrnb(j); + ftot[i] += nrnb[i].n[j] * cost_nrnb(j); } for (int j = 0; (j < NFORCE_INDEX); j++) { - ftot[i] += nrnb[i].n[force_index[j]]*cost_nrnb(force_index[j]); + ftot[i] += nrnb[i].n[force_index[j]] * cost_nrnb(force_index[j]); } /* Due to shake */ for (int j = 0; (j < NCONSTR_INDEX); j++) { - stot[i] += nrnb[i].n[constr_index[j]]*cost_nrnb(constr_index[j]); + stot[i] += nrnb[i].n[constr_index[j]] * cost_nrnb(constr_index[j]); } } for (int j = 0; (j < eNRNB); j++) { - av.n[j] = av.n[j]/static_cast(cr->nnodes - cr->npmenodes); + av.n[j] = av.n[j] / static_cast(cr->nnodes - cr->npmenodes); } fprintf(log, "\nDetailed load balancing info in percentage of average\n"); @@ -594,14 +587,14 @@ void pr_load(FILE *log, t_commrec *cr, t_nrnb nrnb[]) fprintf(log, " %-26s", nrnb_str(j)); for (int i = 0; (i < cr->nnodes); i++) { - dperc = (100.0*nrnb[i].n[j])/av.n[j]; + dperc = (100.0 * nrnb[i].n[j]) / av.n[j]; unb = std::max(unb, dperc); perc = static_cast(dperc); fprintf(log, "%3d ", perc); } if (unb > 0) { - perc = static_cast(10000.0/unb); + perc = static_cast(10000.0 / unb); fprintf(log, "%6d%%\n", perc); } else @@ -620,10 +613,10 @@ void pr_load(FILE *log, t_commrec *cr, t_nrnb nrnb[]) double uf = pr_av(log, cr, fav, ftot.data(), "Total Force"); double us = pr_av(log, cr, sav, stot.data(), "Total Constr."); - double unb = (uf*fav+us*sav)/(fav+sav); + double unb = (uf * fav + us * sav) / (fav + sav); if (unb > 0) { - unb = 10000.0/unb; + unb = 10000.0 / unb; fprintf(log, "\nTotal Scaling: %.0f%% of max performance\n\n", unb); } } diff --git a/src/gromacs/gmxlib/nrnb.h b/src/gromacs/gmxlib/nrnb.h index bab0ac594e..85eff94880 100644 --- a/src/gromacs/gmxlib/nrnb.h +++ b/src/gromacs/gmxlib/nrnb.h @@ -69,50 +69,103 @@ enum eNR_NBKERNEL_ELEC_VDW_W4W4_VF, eNR_NBKERNEL_ELEC_VDW_W4W4_F, - eNR_NBKERNEL_NR, /* Total number of interaction-specific kernel entries */ + eNR_NBKERNEL_NR, /* Total number of interaction-specific kernel entries */ eNR_NBKERNEL_GENERIC = eNR_NBKERNEL_NR, /* Reuse number; KERNEL_NR is not an entry itself */ eNR_NBKERNEL_GENERIC_CG, - eNR_NBKERNEL_FREE_ENERGY, /* Add other generic kernels _before_ the free energy one */ + eNR_NBKERNEL_FREE_ENERGY, /* Add other generic kernels _before_ the free energy one */ eNR_NBKERNEL_TOTAL_NR, eNR_NBNXN_DIST2 = eNR_NBKERNEL_TOTAL_NR, // Reuse the symbolic constant that indicates the last kernel - eNR_NBNXN_LJ_RF, eNR_NBNXN_LJ_RF_E, - eNR_NBNXN_LJ_TAB, eNR_NBNXN_LJ_TAB_E, - eNR_NBNXN_LJ_EWALD, eNR_NBNXN_LJ_EWALD_E, - eNR_NBNXN_LJ, eNR_NBNXN_LJ_E, - eNR_NBNXN_RF, eNR_NBNXN_RF_E, - eNR_NBNXN_TAB, eNR_NBNXN_TAB_E, - eNR_NBNXN_EWALD, eNR_NBNXN_EWALD_E, - eNR_NBNXN_ADD_LJ_FSW, eNR_NBNXN_ADD_LJ_FSW_E, - eNR_NBNXN_ADD_LJ_PSW, eNR_NBNXN_ADD_LJ_PSW_E, - eNR_NBNXN_ADD_LJ_EWALD, eNR_NBNXN_ADD_LJ_EWALD_E, + eNR_NBNXN_LJ_RF, + eNR_NBNXN_LJ_RF_E, + eNR_NBNXN_LJ_TAB, + eNR_NBNXN_LJ_TAB_E, + eNR_NBNXN_LJ_EWALD, + eNR_NBNXN_LJ_EWALD_E, + eNR_NBNXN_LJ, + eNR_NBNXN_LJ_E, + eNR_NBNXN_RF, + eNR_NBNXN_RF_E, + eNR_NBNXN_TAB, + eNR_NBNXN_TAB_E, + eNR_NBNXN_EWALD, + eNR_NBNXN_EWALD_E, + eNR_NBNXN_ADD_LJ_FSW, + eNR_NBNXN_ADD_LJ_FSW_E, + eNR_NBNXN_ADD_LJ_PSW, + eNR_NBNXN_ADD_LJ_PSW_E, + eNR_NBNXN_ADD_LJ_EWALD, + eNR_NBNXN_ADD_LJ_EWALD_E, eNR_NB14, - eNR_WEIGHTS, eNR_SPREAD, eNR_SPREADBSP, - eNR_GATHERF, eNR_GATHERFBSP, eNR_FFT, - eNR_CONV, eNR_SOLVEPME, eNR_NS, eNR_RESETX, - eNR_SHIFTX, eNR_CGCM, eNR_FSUM, - eNR_BONDS, eNR_G96BONDS, eNR_FENEBONDS, - eNR_TABBONDS, eNR_RESTRBONDS, eNR_LINEAR_ANGLES, - eNR_ANGLES, eNR_G96ANGLES, eNR_QANGLES, - eNR_TABANGLES, eNR_PROPER, eNR_IMPROPER, - eNR_RB, eNR_FOURDIH, eNR_TABDIHS, - eNR_DISRES, eNR_ORIRES, eNR_DIHRES, - eNR_POSRES, eNR_FBPOSRES, - eNR_ANGRES, eNR_ANGRESZ, - eNR_MORSE, eNR_CUBICBONDS, eNR_WALLS, - eNR_POLARIZE, eNR_ANHARM_POL, - eNR_WPOL, eNR_THOLE, eNR_VIRIAL, - eNR_UPDATE, eNR_EXTUPDATE, eNR_STOPCM, - eNR_PCOUPL, eNR_EKIN, eNR_LINCS, - eNR_LINCSMAT, eNR_SHAKE, eNR_CONSTR_V, - eNR_SHAKE_RIJ, eNR_CONSTR_VIR, eNR_SETTLE, - eNR_VSITE2, eNR_VSITE2FD, - eNR_VSITE3, eNR_VSITE3FD, - eNR_VSITE3FAD, eNR_VSITE3OUT, eNR_VSITE4FD, - eNR_VSITE4FDN, eNR_VSITEN, - eNR_CMAP, eNR_UREY_BRADLEY, eNR_CROSS_BOND_BOND, + eNR_WEIGHTS, + eNR_SPREAD, + eNR_SPREADBSP, + eNR_GATHERF, + eNR_GATHERFBSP, + eNR_FFT, + eNR_CONV, + eNR_SOLVEPME, + eNR_NS, + eNR_RESETX, + eNR_SHIFTX, + eNR_CGCM, + eNR_FSUM, + eNR_BONDS, + eNR_G96BONDS, + eNR_FENEBONDS, + eNR_TABBONDS, + eNR_RESTRBONDS, + eNR_LINEAR_ANGLES, + eNR_ANGLES, + eNR_G96ANGLES, + eNR_QANGLES, + eNR_TABANGLES, + eNR_PROPER, + eNR_IMPROPER, + eNR_RB, + eNR_FOURDIH, + eNR_TABDIHS, + eNR_DISRES, + eNR_ORIRES, + eNR_DIHRES, + eNR_POSRES, + eNR_FBPOSRES, + eNR_ANGRES, + eNR_ANGRESZ, + eNR_MORSE, + eNR_CUBICBONDS, + eNR_WALLS, + eNR_POLARIZE, + eNR_ANHARM_POL, + eNR_WPOL, + eNR_THOLE, + eNR_VIRIAL, + eNR_UPDATE, + eNR_EXTUPDATE, + eNR_STOPCM, + eNR_PCOUPL, + eNR_EKIN, + eNR_LINCS, + eNR_LINCSMAT, + eNR_SHAKE, + eNR_CONSTR_V, + eNR_SHAKE_RIJ, + eNR_CONSTR_VIR, + eNR_SETTLE, + eNR_VSITE2, + eNR_VSITE2FD, + eNR_VSITE3, + eNR_VSITE3FD, + eNR_VSITE3FAD, + eNR_VSITE3OUT, + eNR_VSITE4FD, + eNR_VSITE4FDN, + eNR_VSITEN, + eNR_CMAP, + eNR_UREY_BRADLEY, + eNR_CROSS_BOND_BOND, eNR_CROSS_BOND_ANGLE, eNRNB }; @@ -125,38 +178,36 @@ struct t_nrnb struct t_commrec; -void clear_nrnb(t_nrnb *nrnb); +void clear_nrnb(t_nrnb* nrnb); -void add_nrnb(t_nrnb *dest, t_nrnb *s1, t_nrnb *s2); +void add_nrnb(t_nrnb* dest, t_nrnb* s1, t_nrnb* s2); -void print_nrnb(FILE *out, t_nrnb *nrnb); +void print_nrnb(FILE* out, t_nrnb* nrnb); -void _inc_nrnb(t_nrnb *nrnb, int enr, int inc, char *file, int line); +void _inc_nrnb(t_nrnb* nrnb, int enr, int inc, char* file, int line); #ifdef DEBUG_NRNB -#define inc_nrnb(nrnb, enr, inc) _inc_nrnb(nrnb, enr, inc, __FILE__, __LINE__) +# define inc_nrnb(nrnb, enr, inc) _inc_nrnb(nrnb, enr, inc, __FILE__, __LINE__) #else -#define inc_nrnb(nrnb, enr, inc) (nrnb)->n[enr] += inc +# define inc_nrnb(nrnb, enr, inc) (nrnb)->n[enr] += inc #endif -void print_flop(FILE *out, t_nrnb *nrnb, double *nbfs, double *mflop); +void print_flop(FILE* out, t_nrnb* nrnb, double* nbfs, double* mflop); /* Calculates the non-bonded forces and flop count. * When out!=NULL also prints the full count table. */ -void print_perf(FILE *out, double nodetime, double realtime, - int64_t nsteps, double delta_t, - double nbfs, double mflop); +void print_perf(FILE* out, double nodetime, double realtime, int64_t nsteps, double delta_t, double nbfs, double mflop); /* Prints the performance, nbfs and mflop come from print_flop */ -void pr_load(FILE *log, struct t_commrec *cr, t_nrnb nrnb[]); +void pr_load(FILE* log, struct t_commrec* cr, t_nrnb nrnb[]); /* Print detailed load balancing info */ int cost_nrnb(int enr); /* Cost in i860 cycles of this component of MD */ -const char *nrnb_str(int enr); +const char* nrnb_str(int enr); /* Name of this component */ -#endif /* GMX_GMXLIB_NRNB_H */ +#endif /* GMX_GMXLIB_NRNB_H */ diff --git a/src/gromacs/gmxpreprocess/add_par.cpp b/src/gromacs/gmxpreprocess/add_par.cpp index c87f31ab9e..bffcbdf875 100644 --- a/src/gromacs/gmxpreprocess/add_par.cpp +++ b/src/gromacs/gmxpreprocess/add_par.cpp @@ -52,46 +52,41 @@ #include "hackblock.h" -void add_param(InteractionsOfType *ps, - int ai, - int aj, - gmx::ArrayRef c, - const char *s) +void add_param(InteractionsOfType* ps, int ai, int aj, gmx::ArrayRef c, const char* s) { if ((ai < 0) || (aj < 0)) { gmx_fatal(FARGS, "Trying to add impossible atoms: ai=%d, aj=%d", ai, aj); } - std::vector atoms = {ai, aj}; + std::vector atoms = { ai, aj }; std::vector forceParm(c.begin(), c.end()); ps->interactionTypes.emplace_back(InteractionOfType(atoms, forceParm, s ? s : "")); } -void add_cmap_param(InteractionsOfType *ps, int ai, int aj, int ak, int al, int am, const char *s) +void add_cmap_param(InteractionsOfType* ps, int ai, int aj, int ak, int al, int am, const char* s) { - std::vector atoms = {ai, aj, ak, al, am}; + std::vector atoms = { ai, aj, ak, al, am }; ps->interactionTypes.emplace_back(InteractionOfType(atoms, {}, s ? s : "")); } -void add_vsite2_param(InteractionsOfType *ps, int ai, int aj, int ak, real c0) +void add_vsite2_param(InteractionsOfType* ps, int ai, int aj, int ak, real c0) { - std::vector atoms = {ai, aj, ak}; - std::vector forceParm = {c0}; + std::vector atoms = { ai, aj, ak }; + std::vector forceParm = { c0 }; ps->interactionTypes.emplace_back(InteractionOfType(atoms, forceParm)); } -void add_vsite3_param(InteractionsOfType *ps, int ai, int aj, int ak, int al, - real c0, real c1) +void add_vsite3_param(InteractionsOfType* ps, int ai, int aj, int ak, int al, real c0, real c1) { - std::vector atoms = {ai, aj, ak, al}; - std::vector forceParm = {c0, c1}; + std::vector atoms = { ai, aj, ak, al }; + std::vector forceParm = { c0, c1 }; ps->interactionTypes.emplace_back(InteractionOfType(atoms, forceParm)); } -void add_vsite3_atoms(InteractionsOfType *ps, int ai, int aj, int ak, int al, bool bSwapParity) +void add_vsite3_atoms(InteractionsOfType* ps, int ai, int aj, int ak, int al, bool bSwapParity) { - std::vector atoms = {ai, aj, ak, al}; + std::vector atoms = { ai, aj, ak, al }; ps->interactionTypes.emplace_back(InteractionOfType(atoms, {})); if (bSwapParity) @@ -100,25 +95,24 @@ void add_vsite3_atoms(InteractionsOfType *ps, int ai, int aj, int ak, int al, bo } } -void add_vsite4_atoms(InteractionsOfType *ps, int ai, int aj, int ak, int al, int am) +void add_vsite4_atoms(InteractionsOfType* ps, int ai, int aj, int ak, int al, int am) { - std::vector atoms = {ai, aj, ak, al, am}; + std::vector atoms = { ai, aj, ak, al, am }; ps->interactionTypes.emplace_back(InteractionOfType(atoms, {})); } -int search_jtype(const PreprocessResidue &localPpResidue, const char *name, bool bNterm) +int search_jtype(const PreprocessResidue& localPpResidue, const char* name, bool bNterm) { int niter, jmax; size_t k, kmax, minstrlen; - char *rtpname, searchname[12]; + char * rtpname, searchname[12]; strcpy(searchname, name); /* Do a best match comparison */ /* for protein N-terminus, allow renaming of H1, H2 and H3 to H */ - if (bNterm && (strlen(searchname) == 2) && (searchname[0] == 'H') && - ( (searchname[1] == '1') || (searchname[1] == '2') || - (searchname[1] == '3') ) ) + if (bNterm && (strlen(searchname) == 2) && (searchname[0] == 'H') + && ((searchname[1] == '1') || (searchname[1] == '2') || (searchname[1] == '3'))) { niter = 2; } @@ -164,12 +158,13 @@ int search_jtype(const PreprocessResidue &localPpResidue, const char *name, bool } if (jmax == -1) { - gmx_fatal(FARGS, "Atom %s not found in rtp database in residue %s", - searchname, localPpResidue.resname.c_str()); + gmx_fatal(FARGS, "Atom %s not found in rtp database in residue %s", searchname, + localPpResidue.resname.c_str()); } if (kmax != strlen(searchname)) { - gmx_fatal(FARGS, "Atom %s not found in rtp database in residue %s, " + gmx_fatal(FARGS, + "Atom %s not found in rtp database in residue %s, " "it looks a bit like %s", searchname, localPpResidue.resname.c_str(), *(localPpResidue.atomname[jmax])); } diff --git a/src/gromacs/gmxpreprocess/add_par.h b/src/gromacs/gmxpreprocess/add_par.h index 13ad55304c..048d42e799 100644 --- a/src/gromacs/gmxpreprocess/add_par.h +++ b/src/gromacs/gmxpreprocess/add_par.h @@ -44,26 +44,18 @@ struct InteractionsOfType; struct PreprocessResidue; -void add_param(InteractionsOfType *ps, - int ai, - int aj, - gmx::ArrayRef c, - const char *s); +void add_param(InteractionsOfType* ps, int ai, int aj, gmx::ArrayRef c, const char* s); -void add_cmap_param(InteractionsOfType *ps, int ai, int aj, int ak, int al, int am, - const char *s); +void add_cmap_param(InteractionsOfType* ps, int ai, int aj, int ak, int al, int am, const char* s); -void add_vsite3_atoms(InteractionsOfType *ps, int ai, int aj, int ak, int al, - bool bSwapParity); +void add_vsite3_atoms(InteractionsOfType* ps, int ai, int aj, int ak, int al, bool bSwapParity); -void add_vsite2_param(InteractionsOfType *ps, int ai, int aj, int ak, real c0); +void add_vsite2_param(InteractionsOfType* ps, int ai, int aj, int ak, real c0); -void add_vsite3_param(InteractionsOfType *ps, int ai, int aj, int ak, int al, - real c0, real c1); +void add_vsite3_param(InteractionsOfType* ps, int ai, int aj, int ak, int al, real c0, real c1); -void add_vsite4_atoms(InteractionsOfType *ps, int ai, int aj, int ak, int al, - int am); +void add_vsite4_atoms(InteractionsOfType* ps, int ai, int aj, int ak, int al, int am); -int search_jtype(const PreprocessResidue &localPpResidue, const char *name, bool bFirstRes); +int search_jtype(const PreprocessResidue& localPpResidue, const char* name, bool bFirstRes); #endif diff --git a/src/gromacs/gmxpreprocess/calch.cpp b/src/gromacs/gmxpreprocess/calch.cpp index 2b0f49f641..24572cd44b 100644 --- a/src/gromacs/gmxpreprocess/calch.cpp +++ b/src/gromacs/gmxpreprocess/calch.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,37 +59,25 @@ /* The source code in this file should be thread-safe. Please keep it that way. */ -static void gen_waterhydrogen(int nh, rvec xa[], rvec xh[], int *l) +static void gen_waterhydrogen(int nh, rvec xa[], rvec xh[], int* l) { #define AA 0.081649 #define BB 0.0 #define CC 0.0577350 - const dvec matrix1[6] = { - { AA, BB, CC }, - { AA, BB, CC }, - { AA, BB, CC }, - { -AA, BB, CC }, - { -AA, BB, CC }, - { BB, AA, -CC } - }; - const dvec matrix2[6] = { - { -AA, BB, CC }, - { BB, AA, -CC }, - { BB, -AA, -CC }, - { BB, AA, -CC }, - { BB, -AA, -CC }, - { BB, -AA, -CC } - }; + const dvec matrix1[6] = { { AA, BB, CC }, { AA, BB, CC }, { AA, BB, CC }, + { -AA, BB, CC }, { -AA, BB, CC }, { BB, AA, -CC } }; + const dvec matrix2[6] = { { -AA, BB, CC }, { BB, AA, -CC }, { BB, -AA, -CC }, + { BB, AA, -CC }, { BB, -AA, -CC }, { BB, -AA, -CC } }; #undef AA #undef BB #undef CC - int m; + int m; /* This was copied from Gromos */ for (m = 0; (m < DIM); m++) { - xH1[m] = xAI[m]+matrix1[*l][m]; - xH2[m] = xAI[m]+matrix2[*l][m]; + xH1[m] = xAI[m] + matrix1[*l][m]; + xH2[m] = xAI[m] + matrix2[*l][m]; } if (nh > 2) { @@ -100,28 +88,28 @@ static void gen_waterhydrogen(int nh, rvec xa[], rvec xh[], int *l) copy_rvec(xAI, xH4); } - *l = (*l+1) % 6; + *l = (*l + 1) % 6; } -void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) +void calc_h_pos(int nht, rvec xa[], rvec xh[], int* l) { -#define alfaH (acos(-1/3.0)) /* 109.47 degrees */ -#define alfaHpl (2*M_PI/3) /* 120 degrees */ -#define distH 0.1 +#define alfaH (acos(-1 / 3.0)) /* 109.47 degrees */ +#define alfaHpl (2 * M_PI / 3) /* 120 degrees */ +#define distH 0.1 -#define alfaCOM (DEG2RAD*117) -#define alfaCO (DEG2RAD*121) -#define alfaCOA (DEG2RAD*115) +#define alfaCOM (DEG2RAD * 117) +#define alfaCO (DEG2RAD * 121) +#define alfaCOA (DEG2RAD * 115) -#define distO 0.123 -#define distOA 0.125 -#define distOM 0.136 +#define distO 0.123 +#define distOA 0.125 +#define distOM 0.136 rvec sa, sb, sij; real s6, rij, ra, rb, xd; int d; - s6 = 0.5*std::sqrt(3.e0); + s6 = 0.5 * std::sqrt(3.e0); /* common work for constructing one, two or three dihedral hydrogens */ switch (nht) @@ -135,29 +123,29 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) for (d = 0; (d < DIM); d++) { xd = xAJ[d]; - sij[d] = xAI[d]-xd; - sb[d] = xd-xAK[d]; - rij += gmx::square(sij[d]); + sij[d] = xAI[d] - xd; + sb[d] = xd - xAK[d]; + rij += gmx::square(sij[d]); } rij = std::sqrt(rij); - sa[XX] = sij[YY]*sb[ZZ]-sij[ZZ]*sb[YY]; - sa[YY] = sij[ZZ]*sb[XX]-sij[XX]*sb[ZZ]; - sa[ZZ] = sij[XX]*sb[YY]-sij[YY]*sb[XX]; + sa[XX] = sij[YY] * sb[ZZ] - sij[ZZ] * sb[YY]; + sa[YY] = sij[ZZ] * sb[XX] - sij[XX] * sb[ZZ]; + sa[ZZ] = sij[XX] * sb[YY] - sij[YY] * sb[XX]; ra = 0.e0; for (d = 0; (d < DIM); d++) { - sij[d] = sij[d]/rij; - ra += gmx::square(sa[d]); + sij[d] = sij[d] / rij; + ra += gmx::square(sa[d]); } ra = std::sqrt(ra); for (d = 0; (d < DIM); d++) { - sa[d] = sa[d]/ra; + sa[d] = sa[d] / ra; } - sb[XX] = sa[YY]*sij[ZZ]-sa[ZZ]*sij[YY]; - sb[YY] = sa[ZZ]*sij[XX]-sa[XX]*sij[ZZ]; - sb[ZZ] = sa[XX]*sij[YY]-sa[YY]*sij[XX]; + sb[XX] = sa[YY] * sij[ZZ] - sa[ZZ] * sij[YY]; + sb[YY] = sa[ZZ] * sij[XX] - sa[XX] * sij[ZZ]; + sb[ZZ] = sa[XX] * sij[YY] - sa[YY] * sij[XX]; break; } /* end switch */ @@ -168,52 +156,48 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) rb = 0.e0; for (d = 0; (d < DIM); d++) { - sij[d] = xAI[d]-xAJ[d]; - sb[d] = xAI[d]-xAK[d]; - rij += gmx::square(sij[d]); - rb += gmx::square(sb[d]); + sij[d] = xAI[d] - xAJ[d]; + sb[d] = xAI[d] - xAK[d]; + rij += gmx::square(sij[d]); + rb += gmx::square(sb[d]); } rij = std::sqrt(rij); rb = std::sqrt(rb); ra = 0.e0; for (d = 0; (d < DIM); d++) { - sa[d] = sij[d]/rij+sb[d]/rb; - ra += gmx::square(sa[d]); + sa[d] = sij[d] / rij + sb[d] / rb; + ra += gmx::square(sa[d]); } ra = std::sqrt(ra); for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]+distH*sa[d]/ra; + xH1[d] = xAI[d] + distH * sa[d] / ra; } break; case 2: /* one single hydrogen, e.g. hydroxyl */ for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]+distH*sin(alfaH)*sb[d]-distH*cos(alfaH)*sij[d]; + xH1[d] = xAI[d] + distH * sin(alfaH) * sb[d] - distH * cos(alfaH) * sij[d]; } break; case 3: /* two planar hydrogens, e.g. -NH2 */ for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]-distH*sin(alfaHpl)*sb[d]-distH*cos(alfaHpl)*sij[d]; - xH2[d] = xAI[d]+distH*sin(alfaHpl)*sb[d]-distH*cos(alfaHpl)*sij[d]; + xH1[d] = xAI[d] - distH * sin(alfaHpl) * sb[d] - distH * cos(alfaHpl) * sij[d]; + xH2[d] = xAI[d] + distH * sin(alfaHpl) * sb[d] - distH * cos(alfaHpl) * sij[d]; } break; case 4: /* two or three tetrahedral hydrogens, e.g. -CH3 */ for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]+distH*sin(alfaH)*sb[d]-distH*cos(alfaH)*sij[d]; - xH2[d] = ( xAI[d] - - distH*sin(alfaH)*0.5*sb[d] - + distH*sin(alfaH)*s6*sa[d] - - distH*cos(alfaH)*sij[d] ); + xH1[d] = xAI[d] + distH * sin(alfaH) * sb[d] - distH * cos(alfaH) * sij[d]; + xH2[d] = (xAI[d] - distH * sin(alfaH) * 0.5 * sb[d] + + distH * sin(alfaH) * s6 * sa[d] - distH * cos(alfaH) * sij[d]); if (xH3[XX] != NOTSET && xH3[YY] != NOTSET && xH3[ZZ] != NOTSET) { - xH3[d] = ( xAI[d] - - distH*sin(alfaH)*0.5*sb[d] - - distH*sin(alfaH)*s6*sa[d] - - distH*cos(alfaH)*sij[d] ); + xH3[d] = (xAI[d] - distH * sin(alfaH) * 0.5 * sb[d] + - distH * sin(alfaH) * s6 * sa[d] - distH * cos(alfaH) * sij[d]); } } break; @@ -224,13 +208,13 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) for (d = 0; (d < DIM); d++) { - center = (xAJ[d]+xAK[d]+xAL[d])/3.0; - dxc[d] = xAI[d]-center; + center = (xAJ[d] + xAK[d] + xAL[d]) / 3.0; + dxc[d] = xAI[d] - center; } center = norm(dxc); for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]+dxc[d]*distH/center; + xH1[d] = xAI[d] + dxc[d] * distH / center; } break; } @@ -241,7 +225,7 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) for (d = 0; (d < DIM); d++) { - rBB[d] = xAI[d]-0.5*(xAJ[d]+xAK[d]); + rBB[d] = xAI[d] - 0.5 * (xAJ[d] + xAK[d]); } bb = norm(rBB); @@ -252,38 +236,30 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]+distH*(cos(alfaH/2.0)*rBB[d]/bb+ - sin(alfaH/2.0)*rNN[d]/nn); - xH2[d] = xAI[d]+distH*(cos(alfaH/2.0)*rBB[d]/bb- - sin(alfaH/2.0)*rNN[d]/nn); + xH1[d] = xAI[d] + distH * (cos(alfaH / 2.0) * rBB[d] / bb + sin(alfaH / 2.0) * rNN[d] / nn); + xH2[d] = xAI[d] + distH * (cos(alfaH / 2.0) * rBB[d] / bb - sin(alfaH / 2.0) * rNN[d] / nn); } break; } - case 7: /* two water hydrogens */ - gen_waterhydrogen(2, xa, xh, l); - break; - case 10: /* three water hydrogens */ - gen_waterhydrogen(3, xa, xh, l); - break; - case 11: /* four water hydrogens */ - gen_waterhydrogen(4, xa, xh, l); - break; + case 7: /* two water hydrogens */ gen_waterhydrogen(2, xa, xh, l); break; + case 10: /* three water hydrogens */ gen_waterhydrogen(3, xa, xh, l); break; + case 11: /* four water hydrogens */ gen_waterhydrogen(4, xa, xh, l); break; case 8: /* two carboxyl oxygens, -COO- */ for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]-distOM*sin(alfaCOM)*sb[d]-distOM*cos(alfaCOM)*sij[d]; - xH2[d] = xAI[d]+distOM*sin(alfaCOM)*sb[d]-distOM*cos(alfaCOM)*sij[d]; + xH1[d] = xAI[d] - distOM * sin(alfaCOM) * sb[d] - distOM * cos(alfaCOM) * sij[d]; + xH2[d] = xAI[d] + distOM * sin(alfaCOM) * sb[d] - distOM * cos(alfaCOM) * sij[d]; } break; - case 9: /* carboxyl oxygens and hydrogen, -COOH */ + case 9: /* carboxyl oxygens and hydrogen, -COOH */ { rvec xa2[4]; /* i,j,k,l */ /* first add two oxygens */ for (d = 0; (d < DIM); d++) { - xH1[d] = xAI[d]-distO *sin(alfaCO )*sb[d]-distO *cos(alfaCO )*sij[d]; - xH2[d] = xAI[d]+distOA*sin(alfaCOA)*sb[d]-distOA*cos(alfaCOA)*sij[d]; + xH1[d] = xAI[d] - distO * sin(alfaCO) * sb[d] - distO * cos(alfaCO) * sij[d]; + xH2[d] = xAI[d] + distOA * sin(alfaCOA) * sb[d] - distOA * cos(alfaCOA) * sij[d]; } /* now use rule 2 to add hydrogen to 2nd oxygen */ @@ -291,11 +267,10 @@ void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l) copy_rvec(xAI, xa2[1]); /* new j = i */ copy_rvec(xAJ, xa2[2]); /* new k = j */ copy_rvec(xAK, xa2[3]); /* new l = k, not used */ - calc_h_pos(2, xa2, (xh+2), l); + calc_h_pos(2, xa2, (xh + 2), l); break; } - default: - gmx_fatal(FARGS, "Invalid argument (%d) for nht in routine genh\n", nht); + default: gmx_fatal(FARGS, "Invalid argument (%d) for nht in routine genh\n", nht); } /* end switch */ } diff --git a/src/gromacs/gmxpreprocess/calch.h b/src/gromacs/gmxpreprocess/calch.h index dc86564c8c..20a3c14d5f 100644 --- a/src/gromacs/gmxpreprocess/calch.h +++ b/src/gromacs/gmxpreprocess/calch.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,7 +39,7 @@ #include "gromacs/math/vectypes.h" -void calc_h_pos(int nht, rvec xa[], rvec xh[], int *l); +void calc_h_pos(int nht, rvec xa[], rvec xh[], int* l); /* * w.f. van gunsteren, groningen, july 1981 * diff --git a/src/gromacs/gmxpreprocess/convparm.cpp b/src/gromacs/gmxpreprocess/convparm.cpp index 40cbc20ed1..b8c6c66359 100644 --- a/src/gromacs/gmxpreprocess/convparm.cpp +++ b/src/gromacs/gmxpreprocess/convparm.cpp @@ -59,40 +59,39 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static int round_check(real r, int limit, int ftype, const char *name) +static int round_check(real r, int limit, int ftype, const char* name) { const int i = gmx::roundToInt(r); - if (r-i > 0.01 || r-i < -0.01) + if (r - i > 0.01 || r - i < -0.01) { - gmx_fatal(FARGS, "A non-integer value (%f) was supplied for '%s' in %s", - r, name, interaction_function[ftype].longname); + gmx_fatal(FARGS, "A non-integer value (%f) was supplied for '%s' in %s", r, name, + interaction_function[ftype].longname); } if (i < limit) { - gmx_fatal(FARGS, "Value of '%s' in %s is %d, which is smaller than the minimum of %d", - name, interaction_function[ftype].longname, i, limit); + gmx_fatal(FARGS, "Value of '%s' in %s is %d, which is smaller than the minimum of %d", name, + interaction_function[ftype].longname, i, limit); } return i; } -static void set_ljparams(int comb, double reppow, double v, double w, - real *c6, real *c12) +static void set_ljparams(int comb, double reppow, double v, double w, real* c6, real* c12) { if (comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS) { if (v >= 0) { - *c6 = 4*w*gmx::power6(v); - *c12 = 4*w*std::pow(v, reppow); + *c6 = 4 * w * gmx::power6(v); + *c12 = 4 * w * std::pow(v, reppow); } else { /* Interpret negative sigma as c6=0 and c12 with -sigma */ *c6 = 0; - *c12 = 4*w*std::pow(-v, reppow); + *c12 = 4 * w * std::pow(-v, reppow); } } else @@ -105,11 +104,9 @@ static void set_ljparams(int comb, double reppow, double v, double w, /* A return value of 0 means parameters were assigned successfully, * returning -1 means this is an all-zero interaction that should not be added. */ -static int -assign_param(t_functype ftype, t_iparams *newparam, - gmx::ArrayRef old, int comb, double reppow) +static int assign_param(t_functype ftype, t_iparams* newparam, gmx::ArrayRef old, int comb, double reppow) { - bool all_param_zero = true; + bool all_param_zero = true; /* Set to zero */ for (int j = 0; (j < MAXFORCEPARAM); j++) @@ -125,8 +122,8 @@ assign_param(t_functype ftype, t_iparams *newparam, if (all_param_zero) { - if (IS_ANGLE(ftype) || IS_RESTRAINT_TYPE(ftype) || ftype == F_IDIHS || - ftype == F_PDIHS || ftype == F_PIDIHS || ftype == F_RBDIHS || ftype == F_FOURDIHS) + if (IS_ANGLE(ftype) || IS_RESTRAINT_TYPE(ftype) || ftype == F_IDIHS || ftype == F_PDIHS + || ftype == F_PIDIHS || ftype == F_RBDIHS || ftype == F_FOURDIHS) { return -1; } @@ -136,9 +133,9 @@ assign_param(t_functype ftype, t_iparams *newparam, { case F_G96ANGLES: /* Post processing of input data: store cosine iso angle itself */ - newparam->harmonic.rA = cos(old[0]*DEG2RAD); + newparam->harmonic.rA = cos(old[0] * DEG2RAD); newparam->harmonic.krA = old[1]; - newparam->harmonic.rB = cos(old[2]*DEG2RAD); + newparam->harmonic.rB = cos(old[2] * DEG2RAD); newparam->harmonic.krB = old[3]; break; case F_G96BONDS: @@ -195,7 +192,7 @@ assign_param(t_functype ftype, t_iparams *newparam, newparam->qangle.theta = old[0]; for (int i = 0; i < 5; i++) { - newparam->qangle.c[i] = old[i+1]; + newparam->qangle.c[i] = old[i + 1]; } break; case F_LINEAR_ANGLES: @@ -218,35 +215,32 @@ assign_param(t_functype ftype, t_iparams *newparam, newparam->harmonic.krA = old[1]; break; case F_MORSE: - newparam->morse.b0A = old[0]; - newparam->morse.cbA = old[1]; - newparam->morse.betaA = old[2]; - newparam->morse.b0B = old[3]; - newparam->morse.cbB = old[4]; - newparam->morse.betaB = old[5]; + newparam->morse.b0A = old[0]; + newparam->morse.cbA = old[1]; + newparam->morse.betaA = old[2]; + newparam->morse.b0B = old[3]; + newparam->morse.cbB = old[4]; + newparam->morse.betaB = old[5]; break; case F_CUBICBONDS: - newparam->cubic.b0 = old[0]; - newparam->cubic.kb = old[1]; - newparam->cubic.kcub = old[2]; - break; - case F_CONNBONDS: - break; - case F_POLARIZATION: - newparam->polarize.alpha = old[0]; + newparam->cubic.b0 = old[0]; + newparam->cubic.kb = old[1]; + newparam->cubic.kcub = old[2]; break; + case F_CONNBONDS: break; + case F_POLARIZATION: newparam->polarize.alpha = old[0]; break; case F_ANHARM_POL: newparam->anharm_polarize.alpha = old[0]; newparam->anharm_polarize.drcut = old[1]; newparam->anharm_polarize.khyp = old[2]; break; case F_WATER_POL: - newparam->wpol.al_x = old[0]; - newparam->wpol.al_y = old[1]; - newparam->wpol.al_z = old[2]; - newparam->wpol.rOH = old[3]; - newparam->wpol.rHH = old[4]; - newparam->wpol.rOD = old[5]; + newparam->wpol.al_x = old[0]; + newparam->wpol.al_y = old[1]; + newparam->wpol.al_z = old[2]; + newparam->wpol.rOH = old[3]; + newparam->wpol.rHH = old[4]; + newparam->wpol.rOD = old[5]; break; case F_THOLE_POL: newparam->thole.a = old[0]; @@ -254,7 +248,7 @@ assign_param(t_functype ftype, t_iparams *newparam, newparam->thole.alpha2 = old[2]; if ((old[1] > 0) && (old[2] > 0)) { - newparam->thole.rfac = old[0]*gmx::invsixthroot(old[1]*old[2]); + newparam->thole.rfac = old[0] * gmx::invsixthroot(old[1] * old[2]); } else { @@ -326,12 +320,13 @@ assign_param(t_functype ftype, t_iparams *newparam, newparam->posres.pos0B[ZZ] = old[11]; break; case F_FBPOSRES: - newparam->fbposres.geom = round_check(old[0], 0, ftype, "geometry"); + newparam->fbposres.geom = round_check(old[0], 0, ftype, "geometry"); if (!(newparam->fbposres.geom > efbposresZERO && newparam->fbposres.geom < efbposresNR)) { - gmx_fatal(FARGS, "Invalid geometry for flat-bottomed position restraint.\n" - "Expected number between 1 and %d. Found %d\n", efbposresNR-1, - newparam->fbposres.geom); + gmx_fatal(FARGS, + "Invalid geometry for flat-bottomed position restraint.\n" + "Expected number between 1 and %d. Found %d\n", + efbposresNR - 1, newparam->fbposres.geom); } newparam->fbposres.r = old[1]; newparam->fbposres.k = old[2]; @@ -356,18 +351,18 @@ assign_param(t_functype ftype, t_iparams *newparam, newparam->orires.kfac = old[5]; break; case F_DIHRES: - newparam->dihres.phiA = old[0]; - newparam->dihres.dphiA = old[1]; - newparam->dihres.kfacA = old[2]; - newparam->dihres.phiB = old[3]; - newparam->dihres.dphiB = old[4]; - newparam->dihres.kfacB = old[5]; + newparam->dihres.phiA = old[0]; + newparam->dihres.dphiA = old[1]; + newparam->dihres.kfacA = old[2]; + newparam->dihres.phiB = old[3]; + newparam->dihres.dphiB = old[4]; + newparam->dihres.kfacB = old[5]; break; case F_RBDIHS: for (int i = 0; (i < NR_RBDIHS); i++) { newparam->rbdihs.rbcA[i] = old[i]; - newparam->rbdihs.rbcB[i] = old[NR_RBDIHS+i]; + newparam->rbdihs.rbcB[i] = old[NR_RBDIHS + i]; } break; case F_CBTDIHS: @@ -382,18 +377,19 @@ assign_param(t_functype ftype, t_iparams *newparam, * Ryckaert-Bellemans form. */ /* Use conversion formula for OPLS to Ryckaert-Bellemans: */ - newparam->rbdihs.rbcA[0] = old[1]+0.5*(old[0]+old[2]); - newparam->rbdihs.rbcA[1] = 0.5*(3.0*old[2]-old[0]); - newparam->rbdihs.rbcA[2] = 4.0*old[3]-old[1]; - newparam->rbdihs.rbcA[3] = -2.0*old[2]; - newparam->rbdihs.rbcA[4] = -4.0*old[3]; + newparam->rbdihs.rbcA[0] = old[1] + 0.5 * (old[0] + old[2]); + newparam->rbdihs.rbcA[1] = 0.5 * (3.0 * old[2] - old[0]); + newparam->rbdihs.rbcA[2] = 4.0 * old[3] - old[1]; + newparam->rbdihs.rbcA[3] = -2.0 * old[2]; + newparam->rbdihs.rbcA[4] = -4.0 * old[3]; newparam->rbdihs.rbcA[5] = 0.0; - newparam->rbdihs.rbcB[0] = old[NR_FOURDIHS+1]+0.5*(old[NR_FOURDIHS+0]+old[NR_FOURDIHS+2]); - newparam->rbdihs.rbcB[1] = 0.5*(3.0*old[NR_FOURDIHS+2]-old[NR_FOURDIHS+0]); - newparam->rbdihs.rbcB[2] = 4.0*old[NR_FOURDIHS+3]-old[NR_FOURDIHS+1]; - newparam->rbdihs.rbcB[3] = -2.0*old[NR_FOURDIHS+2]; - newparam->rbdihs.rbcB[4] = -4.0*old[NR_FOURDIHS+3]; + newparam->rbdihs.rbcB[0] = + old[NR_FOURDIHS + 1] + 0.5 * (old[NR_FOURDIHS + 0] + old[NR_FOURDIHS + 2]); + newparam->rbdihs.rbcB[1] = 0.5 * (3.0 * old[NR_FOURDIHS + 2] - old[NR_FOURDIHS + 0]); + newparam->rbdihs.rbcB[2] = 4.0 * old[NR_FOURDIHS + 3] - old[NR_FOURDIHS + 1]; + newparam->rbdihs.rbcB[3] = -2.0 * old[NR_FOURDIHS + 2]; + newparam->rbdihs.rbcB[4] = -4.0 * old[NR_FOURDIHS + 3]; newparam->rbdihs.rbcB[5] = 0.0; break; case F_CONSTR: @@ -437,24 +433,26 @@ assign_param(t_functype ftype, t_iparams *newparam, break; case F_GB12_NOLONGERUSED: case F_GB13_NOLONGERUSED: - case F_GB14_NOLONGERUSED: - break; + case F_GB14_NOLONGERUSED: break; default: - gmx_fatal(FARGS, "unknown function type %d in %s line %d", - ftype, __FILE__, __LINE__); + gmx_fatal(FARGS, "unknown function type %d in %s line %d", ftype, __FILE__, __LINE__); } return 0; } -static int enter_params(gmx_ffparams_t *ffparams, t_functype ftype, - gmx::ArrayRef forceparams, int comb, real reppow, - int start, bool bAppend) +static int enter_params(gmx_ffparams_t* ffparams, + t_functype ftype, + gmx::ArrayRef forceparams, + int comb, + real reppow, + int start, + bool bAppend) { t_iparams newparam; int type; int rc; - if ( (rc = assign_param(ftype, &newparam, forceparams, comb, reppow)) < 0) + if ((rc = assign_param(ftype, &newparam, forceparams, comb, reppow)) < 0) { /* -1 means this interaction is all-zero and should not be added */ return rc; @@ -481,61 +479,67 @@ static int enter_params(gmx_ffparams_t *ffparams, t_functype ftype, ffparams->iparams.push_back(newparam); ffparams->functype.push_back(ftype); - GMX_ASSERT(ffparams->iparams.size() == ffparams->functype.size(), - "sizes should match"); + GMX_ASSERT(ffparams->iparams.size() == ffparams->functype.size(), "sizes should match"); return type; } -static void append_interaction(InteractionList *ilist, - int type, gmx::ArrayRef a) +static void append_interaction(InteractionList* ilist, int type, gmx::ArrayRef a) { ilist->iatoms.push_back(type); - for (const auto &atom : a) + for (const auto& atom : a) { ilist->iatoms.push_back(atom); } } -static void enter_function(const InteractionsOfType *p, t_functype ftype, int comb, real reppow, - gmx_ffparams_t *ffparams, InteractionList *il, - bool bNB, bool bAppend) +static void enter_function(const InteractionsOfType* p, + t_functype ftype, + int comb, + real reppow, + gmx_ffparams_t* ffparams, + InteractionList* il, + bool bNB, + bool bAppend) { int start = ffparams->numTypes(); - for (auto &parm : p->interactionTypes) + for (auto& parm : p->interactionTypes) { int type = enter_params(ffparams, ftype, parm.forceParam(), comb, reppow, start, bAppend); /* Type==-1 is used as a signal that this interaction is all-zero and should not be added. */ if (!bNB && type >= 0) { GMX_RELEASE_ASSERT(il, "Need valid interaction list"); - GMX_RELEASE_ASSERT(parm.atoms().ssize() == NRAL(ftype), "Need to have correct number of atoms for the parameter"); + GMX_RELEASE_ASSERT(parm.atoms().ssize() == NRAL(ftype), + "Need to have correct number of atoms for the parameter"); append_interaction(il, type, parm.atoms()); } } } -void convertInteractionsOfType(int atnr, gmx::ArrayRef nbtypes, +void convertInteractionsOfType(int atnr, + gmx::ArrayRef nbtypes, gmx::ArrayRef mi, - const MoleculeInformation *intermolecular_interactions, - int comb, double reppow, real fudgeQQ, - gmx_mtop_t *mtop) + const MoleculeInformation* intermolecular_interactions, + int comb, + double reppow, + real fudgeQQ, + gmx_mtop_t* mtop) { int i; unsigned long flags; - gmx_ffparams_t *ffp; - gmx_moltype_t *molt; + gmx_ffparams_t* ffp; + gmx_moltype_t* molt; - ffp = &mtop->ffparams; - ffp->atnr = atnr; + ffp = &mtop->ffparams; + ffp->atnr = atnr; ffp->functype.clear(); ffp->iparams.clear(); - ffp->reppow = reppow; + ffp->reppow = reppow; - enter_function(&(nbtypes[F_LJ]), static_cast(F_LJ), comb, reppow, ffp, nullptr, - TRUE, TRUE); - enter_function(&(nbtypes[F_BHAM]), static_cast(F_BHAM), comb, reppow, ffp, nullptr, + enter_function(&(nbtypes[F_LJ]), static_cast(F_LJ), comb, reppow, ffp, nullptr, TRUE, TRUE); + enter_function(&(nbtypes[F_BHAM]), static_cast(F_BHAM), comb, reppow, ffp, nullptr, TRUE, TRUE); for (size_t mt = 0; mt < mtop->moltype.size(); mt++) @@ -548,13 +552,11 @@ void convertInteractionsOfType(int atnr, gmx::ArrayRef gmx::ArrayRef interactions = mi[mt].interactions; flags = interaction_function[i].flags; - if ((i != F_LJ) && (i != F_BHAM) && ((flags & IF_BOND) || - (flags & IF_VSITE) || - (flags & IF_CONSTRAINT))) + if ((i != F_LJ) && (i != F_BHAM) + && ((flags & IF_BOND) || (flags & IF_VSITE) || (flags & IF_CONSTRAINT))) { - enter_function(&(interactions[i]), static_cast(i), comb, reppow, - ffp, &molt->ilist[i], - FALSE, (i == F_POSRES || i == F_FBPOSRES)); + enter_function(&(interactions[i]), static_cast(i), comb, reppow, ffp, + &molt->ilist[i], FALSE, (i == F_POSRES || i == F_FBPOSRES)); } } } @@ -581,21 +583,27 @@ void convertInteractionsOfType(int atnr, gmx::ArrayRef */ if (!(flags & IF_BOND)) { - gmx_fatal(FARGS, "The intermolecular_interaction section may only contain bonded potentials"); + gmx_fatal(FARGS, + "The intermolecular_interaction section may only contain bonded " + "potentials"); } else if (NRAL(i) == 1) /* e.g. position restraints */ { - gmx_fatal(FARGS, "Single atom interactions don't make sense in the intermolecular_interaction section, you can put them in the moleculetype section"); + gmx_fatal(FARGS, + "Single atom interactions don't make sense in the " + "intermolecular_interaction section, you can put them in the " + "moleculetype section"); } else if (flags & IF_CHEMBOND) { - gmx_fatal(FARGS, "The intermolecular_interaction can not contain chemically bonding interactions"); + gmx_fatal(FARGS, + "The intermolecular_interaction can not contain chemically bonding " + "interactions"); } else { enter_function(&(interactions[i]), static_cast(i), comb, reppow, - ffp, &(*mtop->intermolecular_ilist)[i], - FALSE, FALSE); + ffp, &(*mtop->intermolecular_ilist)[i], FALSE, FALSE); mtop->bIntermolecularInteractions = TRUE; } diff --git a/src/gromacs/gmxpreprocess/convparm.h b/src/gromacs/gmxpreprocess/convparm.h index a245f6f01b..5268cde9fc 100644 --- a/src/gromacs/gmxpreprocess/convparm.h +++ b/src/gromacs/gmxpreprocess/convparm.h @@ -45,10 +45,13 @@ struct gmx_mtop_t; struct MoleculeInformation; struct InteractionsOfType; -void convertInteractionsOfType(int atnr, gmx::ArrayRef nbtypes, +void convertInteractionsOfType(int atnr, + gmx::ArrayRef nbtypes, gmx::ArrayRef mi, - const MoleculeInformation *intermolecular_interactions, - int comb, double reppow, real fudgeQQ, - gmx_mtop_t *mtop); + const MoleculeInformation* intermolecular_interactions, + int comb, + double reppow, + real fudgeQQ, + gmx_mtop_t* mtop); #endif diff --git a/src/gromacs/gmxpreprocess/editconf.cpp b/src/gromacs/gmxpreprocess/editconf.cpp index b51a984a11..ee76e72bfe 100644 --- a/src/gromacs/gmxpreprocess/editconf.cpp +++ b/src/gromacs/gmxpreprocess/editconf.cpp @@ -68,7 +68,7 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/strdb.h" -static real calc_mass(t_atoms *atoms, gmx_bool bGetMass, AtomProperties *aps) +static real calc_mass(t_atoms* atoms, gmx_bool bGetMass, AtomProperties* aps) { real tmass; int i; @@ -78,8 +78,7 @@ static real calc_mass(t_atoms *atoms, gmx_bool bGetMass, AtomProperties *aps) { if (bGetMass) { - aps->setAtomProperty(epropMass, - std::string(*atoms->resinfo[atoms->atom[i].resind].name), + aps->setAtomProperty(epropMass, std::string(*atoms->resinfo[atoms->atom[i].resind].name), std::string(*atoms->atomname[i]), &(atoms->atom[i].m)); } tmass += atoms->atom[i].m; @@ -88,11 +87,10 @@ static real calc_mass(t_atoms *atoms, gmx_bool bGetMass, AtomProperties *aps) return tmass; } -static real calc_geom(int isize, const int *index, rvec *x, rvec geom_center, rvec minval, - rvec maxval, gmx_bool bDiam) +static real calc_geom(int isize, const int* index, rvec* x, rvec geom_center, rvec minval, rvec maxval, gmx_bool bDiam) { - real diam2, d; - int ii, i, j; + real diam2, d; + int ii, i, j; clear_rvec(geom_center); diam2 = 0; @@ -163,15 +161,14 @@ static real calc_geom(int isize, const int *index, rvec *x, rvec geom_center, rv return std::sqrt(diam2); } -static void center_conf(int natom, rvec *x, rvec center, rvec geom_cent) +static void center_conf(int natom, rvec* x, rvec center, rvec geom_cent) { int i; rvec shift; rvec_sub(center, geom_cent, shift); - printf(" shift :%7.3f%7.3f%7.3f (nm)\n", shift[XX], shift[YY], - shift[ZZ]); + printf(" shift :%7.3f%7.3f%7.3f (nm)\n", shift[XX], shift[YY], shift[ZZ]); for (i = 0; (i < natom); i++) { @@ -199,10 +196,10 @@ static void scale_conf(int natom, rvec x[], matrix box, const rvec scale) } } -static void read_bfac(const char *fn, int *n_bfac, double **bfac_val, int **bfac_nr) +static void read_bfac(const char* fn, int* n_bfac, double** bfac_val, int** bfac_nr) { int i; - char **bfac_lines; + char** bfac_lines; *n_bfac = get_lines(fn, &bfac_lines); snew(*bfac_val, *n_bfac); @@ -212,11 +209,9 @@ static void read_bfac(const char *fn, int *n_bfac, double **bfac_val, int **bfac { sscanf(bfac_lines[i], "%d %lf", &(*bfac_nr)[i], &(*bfac_val)[i]); } - } -static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, - double *bfac, int *bfac_nr, gmx_bool peratom) +static void set_pdb_conf_bfac(int natoms, int nres, t_atoms* atoms, int n_bfac, double* bfac, int* bfac_nr, gmx_bool peratom) { real bfac_min, bfac_max; int i, n; @@ -247,7 +242,8 @@ static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, { fprintf(stderr, "Range of values for B-factors too large (min %g, max %g) " - "will scale down a factor 10\n", bfac_min, bfac_max); + "will scale down a factor 10\n", + bfac_min, bfac_max); for (i = 0; (i < n_bfac); i++) { bfac[i] /= 10; @@ -259,7 +255,8 @@ static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, { fprintf(stderr, "Range of values for B-factors too small (min %g, max %g) " - "will scale up a factor 10\n", bfac_min, bfac_max); + "will scale up a factor 10\n", + bfac_min, bfac_max); for (i = 0; (i < n_bfac); i++) { bfac[i] *= 10; @@ -275,8 +272,7 @@ static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, if (!peratom) { - fprintf(stderr, "Will attach %d B-factors to %d residues\n", n_bfac, - nres); + fprintf(stderr, "Will attach %d B-factors to %d residues\n", n_bfac, nres); for (i = 0; (i < n_bfac); i++) { found = FALSE; @@ -296,8 +292,7 @@ static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, } else { - fprintf(stderr, "Will attach %d B-factors to %d atoms\n", n_bfac, - natoms); + fprintf(stderr, "Will attach %d B-factors to %d atoms\n", n_bfac, natoms); for (i = 0; (i < n_bfac); i++) { atoms->pdbinfo[bfac_nr[i] - 1].bfac = bfac[i]; @@ -305,7 +300,7 @@ static void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac, } } -static void pdb_legend(FILE *out, int natoms, int nres, t_atoms *atoms, rvec x[]) +static void pdb_legend(FILE* out, int natoms, int nres, t_atoms* atoms, rvec x[]) { real bfac_min, bfac_max, xmin, ymin, zmin; int i; @@ -327,19 +322,17 @@ static void pdb_legend(FILE *out, int natoms, int nres, t_atoms *atoms, rvec x[] fprintf(stderr, "B-factors range from %g to %g\n", bfac_min, bfac_max); for (i = 1; (i < 12); i++) { - fprintf(out, - "%-6s%5d %-4.4s%3.3s %c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f\n", - "ATOM ", natoms + 1 + i, "CA", "LEG", space, nres + 1, space, - (xmin + (i * 0.12)) * 10, ymin * 10, zmin * 10, 1.0, bfac_min - + ((i - 1.0) * (bfac_max - bfac_min) / 10)); + fprintf(out, "%-6s%5d %-4.4s%3.3s %c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f\n", "ATOM ", + natoms + 1 + i, "CA", "LEG", space, nres + 1, space, (xmin + (i * 0.12)) * 10, + ymin * 10, zmin * 10, 1.0, bfac_min + ((i - 1.0) * (bfac_max - bfac_min) / 10)); } } -static void visualize_images(const char *fn, int ePBC, matrix box) +static void visualize_images(const char* fn, int ePBC, matrix box) { t_atoms atoms; - rvec *img; - char *c, *ala; + rvec* img; + char * c, *ala; int nat, i; nat = NTRICIMG + 1; @@ -365,17 +358,13 @@ static void visualize_images(const char *fn, int ePBC, matrix box) sfree(img); } -static void visualize_box(FILE *out, int a0, int r0, matrix box, const rvec gridsize) +static void visualize_box(FILE* out, int a0, int r0, matrix box, const rvec gridsize) { - int *edge; + int* edge; rvec *vert, shift; int nx, ny, nz, nbox, nat; int i, j, x, y, z; - int rectedge[24] = - { - 0, 1, 1, 3, 3, 2, 0, 2, 0, 4, 1, 5, 3, 7, 2, 6, 4, 5, 5, 7, 7, 6, 6, - 4 - }; + int rectedge[24] = { 0, 1, 1, 3, 3, 2, 0, 2, 0, 4, 1, 5, 3, 7, 2, 6, 4, 5, 5, 7, 7, 6, 6, 4 }; a0++; r0++; @@ -398,8 +387,7 @@ static void visualize_box(FILE *out, int a0, int r0, matrix box, const rvec grid { for (i = 0; i < DIM; i++) { - shift[i] = x * box[0][i] + y * box[1][i] + z - * box[2][i]; + shift[i] = x * box[0][i] + y * box[1][i] + z * box[2][i]; } for (i = 0; i < NCUCVERT; i++) { @@ -412,8 +400,9 @@ static void visualize_box(FILE *out, int a0, int r0, matrix box, const rvec grid for (i = 0; i < nat; i++) { - gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i / NCUCVERT, r0 + i, ' ', - 10*vert[i][XX], 10*vert[i][YY], 10*vert[i][ZZ], 1.0, 0.0, ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i / NCUCVERT, + r0 + i, ' ', 10 * vert[i][XX], 10 * vert[i][YY], + 10 * vert[i][ZZ], 1.0, 0.0, ""); } edge = compact_unitcell_edges(); @@ -437,8 +426,9 @@ static void visualize_box(FILE *out, int a0, int r0, matrix box, const rvec grid { for (x = 0; x <= 1; x++) { - gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i/8, r0+i, ' ', - x * 10 * box[XX][XX], y * 10 * box[YY][YY], z * 10 * box[ZZ][ZZ], 1.0, 0.0, ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, a0 + i, "C", ' ', "BOX", 'K' + i / 8, + r0 + i, ' ', x * 10 * box[XX][XX], y * 10 * box[YY][YY], + z * 10 * box[ZZ][ZZ], 1.0, 0.0, ""); i++; } } @@ -456,36 +446,34 @@ static void calc_rotmatrix(rvec principal_axis, rvec targetvec, matrix rotmatrix real ux, uy, uz, costheta, sintheta; costheta = cos_angle(principal_axis, targetvec); - sintheta = std::sqrt(1.0-costheta*costheta); /* sign is always positive since 0(vol*4.5))); + printf("Volume: %g nm^3, corresponds to roughly %d electrons\n", vol, + 100 * (static_cast(vol * 4.5))); } if (bMead || bGrasp || bCONECT) @@ -841,8 +813,7 @@ int gmx_editconf(int argc, char *argv[]) /* Determine the Van der Waals radius from the force field */ if (bReadVDW) { - if (!aps.setAtomProperty(epropVDW, - *top->atoms.resinfo[top->atoms.atom[i].resind].name, + if (!aps.setAtomProperty(epropVDW, *top->atoms.resinfo[top->atoms.atom[i].resind].name, *top->atoms.atomname[i], &vdw)) { vdw = rvdw; @@ -851,20 +822,20 @@ int gmx_editconf(int argc, char *argv[]) else { itype = top->atoms.atom[i].type; - c12 = top->idef.iparams[itype*ntype+itype].lj.c12; - c6 = top->idef.iparams[itype*ntype+itype].lj.c6; + c12 = top->idef.iparams[itype * ntype + itype].lj.c12; + c6 = top->idef.iparams[itype * ntype + itype].lj.c6; if ((c6 != 0) && (c12 != 0)) { real sig6; if (bSig56) { - sig6 = 2*c12/c6; + sig6 = 2 * c12 / c6; } else { - sig6 = c12/c6; + sig6 = c12 / c6; } - vdw = 0.5*gmx::sixthroot(sig6); + vdw = 0.5 * gmx::sixthroot(sig6); } else { @@ -923,8 +894,7 @@ int gmx_editconf(int argc, char *argv[]) if (bIndex) { fprintf(stderr, "\nSelect a group for determining the system size:\n"); - get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &ssize, &sindex, &sgrpname); + get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ssize, &sindex, &sgrpname); } else { @@ -933,22 +903,17 @@ int gmx_editconf(int argc, char *argv[]) } diam = calc_geom(ssize, sindex, x, gc, rmin, rmax, bCalcDiam); rvec_sub(rmax, rmin, size); - printf(" system size :%7.3f%7.3f%7.3f (nm)\n", - size[XX], size[YY], size[ZZ]); + printf(" system size :%7.3f%7.3f%7.3f (nm)\n", size[XX], size[YY], size[ZZ]); if (bCalcDiam) { printf(" diameter :%7.3f (nm)\n", diam); } printf(" center :%7.3f%7.3f%7.3f (nm)\n", gc[XX], gc[YY], gc[ZZ]); - printf(" box vectors :%7.3f%7.3f%7.3f (nm)\n", - norm(box[XX]), norm(box[YY]), norm(box[ZZ])); + printf(" box vectors :%7.3f%7.3f%7.3f (nm)\n", norm(box[XX]), norm(box[YY]), norm(box[ZZ])); printf(" box angles :%7.2f%7.2f%7.2f (degrees)\n", - norm2(box[ZZ]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[YY], box[ZZ]), - norm2(box[ZZ]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[XX], box[ZZ]), - norm2(box[YY]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[XX], box[YY])); + norm2(box[ZZ]) == 0 ? 0 : RAD2DEG * gmx_angle(box[YY], box[ZZ]), + norm2(box[ZZ]) == 0 ? 0 : RAD2DEG * gmx_angle(box[XX], box[ZZ]), + norm2(box[YY]) == 0 ? 0 : RAD2DEG * gmx_angle(box[XX], box[YY])); printf(" box volume :%7.2f (nm^3)\n", det(box)); } @@ -959,8 +924,8 @@ int gmx_editconf(int argc, char *argv[]) if (bOrient) { - int *index; - char *grpnames; + int* index; + char* grpnames; /* Get a group for principal component analysis */ fprintf(stderr, "\nSelect group for the determining the orientation\n"); @@ -981,17 +946,19 @@ int gmx_editconf(int argc, char *argv[]) real vol, dens; vol = det(box); - dens = (mass*AMU)/(vol*NANO*NANO*NANO); + dens = (mass * AMU) / (vol * NANO * NANO * NANO); fprintf(stderr, "Volume of input %g (nm^3)\n", vol); fprintf(stderr, "Mass of input %g (a.m.u.)\n", mass); fprintf(stderr, "Density of input %g (g/l)\n", dens); if (vol == 0 || mass == 0) { - gmx_fatal(FARGS, "Cannot scale density with " - "zero mass (%g) or volume (%g)\n", mass, vol); + gmx_fatal(FARGS, + "Cannot scale density with " + "zero mass (%g) or volume (%g)\n", + mass, vol); } - scale[XX] = scale[YY] = scale[ZZ] = std::cbrt(dens/rho); + scale[XX] = scale[YY] = scale[ZZ] = std::cbrt(dens / rho); fprintf(stderr, "Scaling all box vectors by %g\n", scale[XX]); } scale_conf(atoms.nr, x, box, scale); @@ -1002,8 +969,7 @@ int gmx_editconf(int argc, char *argv[]) if (bIndex) { fprintf(stderr, "\nSelect a group that you want to align:\n"); - get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &numAlignmentAtoms, &aindex, &agrpname); + get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &numAlignmentAtoms, &aindex, &agrpname); } else { @@ -1014,8 +980,8 @@ int gmx_editconf(int argc, char *argv[]) aindex[i] = i; } } - printf("Aligning %d atoms (out of %d) to %g %g %g, center of rotation %g %g %g\n", numAlignmentAtoms, natom, - targetvec[XX], targetvec[YY], targetvec[ZZ], + printf("Aligning %d atoms (out of %d) to %g %g %g, center of rotation %g %g %g\n", + numAlignmentAtoms, natom, targetvec[XX], targetvec[YY], targetvec[ZZ], aligncenter[XX], aligncenter[YY], aligncenter[ZZ]); /*subtract out pivot point*/ for (i = 0; i < numAlignmentAtoms; i++) @@ -1028,7 +994,9 @@ int gmx_editconf(int argc, char *argv[]) unitv(targetvec, targetvec); printf("Using %g %g %g as principal axis\n", trans[0][2], trans[1][2], trans[2][2]); - tmpvec[XX] = trans[0][2]; tmpvec[YY] = trans[1][2]; tmpvec[ZZ] = trans[2][2]; + tmpvec[XX] = trans[0][2]; + tmpvec[YY] = trans[1][2]; + tmpvec[ZZ] = trans[2][2]; calc_rotmatrix(tmpvec, targetvec, rotmatrix); /* rotmatrix finished */ @@ -1054,16 +1022,15 @@ int gmx_editconf(int argc, char *argv[]) if (bIndex) { fprintf(stderr, "\nSelect a group that you want to translate:\n"); - get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &ssize, &sindex, &sgrpname); + get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ssize, &sindex, &sgrpname); } else { ssize = atoms.nr; sindex = nullptr; } - printf("Translating %d atoms (out of %d) by %g %g %g nm\n", ssize, natom, - translation[XX], translation[YY], translation[ZZ]); + printf("Translating %d atoms (out of %d) by %g %g %g nm\n", ssize, natom, translation[XX], + translation[YY], translation[ZZ]); if (sindex) { for (i = 0; i < ssize; i++) @@ -1082,7 +1049,8 @@ int gmx_editconf(int argc, char *argv[]) if (bRotate) { /* Rotate */ - printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n", rotangles[XX], rotangles[YY], rotangles[ZZ]); + printf("Rotating %g, %g, %g degrees around the X, Y and Z axis respectively\n", + rotangles[XX], rotangles[YY], rotangles[ZZ]); for (i = 0; i < DIM; i++) { rotangles[i] *= DEG2RAD; @@ -1097,8 +1065,7 @@ int gmx_editconf(int argc, char *argv[]) rvec_sub(rmax, rmin, size); if (bScale || bOrient || bRotate) { - printf("new system size : %6.3f %6.3f %6.3f\n", - size[XX], size[YY], size[ZZ]); + printf("new system size : %6.3f %6.3f %6.3f\n", size[XX], size[YY], size[ZZ]); } } @@ -1121,7 +1088,7 @@ int gmx_editconf(int argc, char *argv[]) { for (i = 0; i < DIM; i++) { - newbox[i] = size[i]+2*dist; + newbox[i] = size[i] + 2 * dist; } } if (!bSetAng) @@ -1144,7 +1111,7 @@ int gmx_editconf(int argc, char *argv[]) } else { - d = diam+2*dist; + d = diam + 2 * dist; } if (btype[0][0] == 'c') { @@ -1157,18 +1124,18 @@ int gmx_editconf(int argc, char *argv[]) { box[XX][XX] = d; box[YY][YY] = d; - box[ZZ][XX] = d/2; - box[ZZ][YY] = d/2; - box[ZZ][ZZ] = d*std::sqrt(2.0)/2.0; + box[ZZ][XX] = d / 2; + box[ZZ][YY] = d / 2; + box[ZZ][ZZ] = d * std::sqrt(2.0) / 2.0; } else { box[XX][XX] = d; - box[YY][XX] = d/3; - box[YY][YY] = d*std::sqrt(2.0)*2.0/3.0; - box[ZZ][XX] = -d/3; - box[ZZ][YY] = d*std::sqrt(2.0)/3.0; - box[ZZ][ZZ] = d*std::sqrt(6.0)/3.0; + box[YY][XX] = d / 3; + box[YY][YY] = d * std::sqrt(2.0) * 2.0 / 3.0; + box[ZZ][XX] = -d / 3; + box[ZZ][YY] = d * std::sqrt(2.0) / 3.0; + box[ZZ][ZZ] = d * std::sqrt(6.0) / 3.0; } break; } @@ -1194,15 +1161,11 @@ int gmx_editconf(int argc, char *argv[]) } if (bOrient || bScale || bDist || bSetSize) { - printf("new box vectors :%7.3f%7.3f%7.3f (nm)\n", - norm(box[XX]), norm(box[YY]), norm(box[ZZ])); + printf("new box vectors :%7.3f%7.3f%7.3f (nm)\n", norm(box[XX]), norm(box[YY]), norm(box[ZZ])); printf("new box angles :%7.2f%7.2f%7.2f (degrees)\n", - norm2(box[ZZ]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[YY], box[ZZ]), - norm2(box[ZZ]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[XX], box[ZZ]), - norm2(box[YY]) == 0 ? 0 : - RAD2DEG*gmx_angle(box[XX], box[YY])); + norm2(box[ZZ]) == 0 ? 0 : RAD2DEG * gmx_angle(box[YY], box[ZZ]), + norm2(box[ZZ]) == 0 ? 0 : RAD2DEG * gmx_angle(box[XX], box[ZZ]), + norm2(box[YY]) == 0 ? 0 : RAD2DEG * gmx_angle(box[XX], box[YY])); printf("new box volume :%7.2f (nm^3)\n", det(box)); } @@ -1221,11 +1184,13 @@ int gmx_editconf(int argc, char *argv[]) printf("\nWARNING: Your box is triclinic with non-orthogonal axes. In this case, the\n" "distance from the solute to a box surface along the corresponding normal\n" "vector might be somewhat smaller than your specified value %f.\n" - "You can check the actual value with g_mindist -pi\n", dist); + "You can check the actual value with g_mindist -pi\n", + dist); } else if (!opt2parg_bSet("-bt", NPA, pa)) { - printf("\nWARNING: No boxtype specified - distance condition applied in each dimension.\n" + printf("\nWARNING: No boxtype specified - distance condition applied in each " + "dimension.\n" "If the molecule rotates the actual distance will be smaller. You might want\n" "to use a cubic box instead, or why not try a dodecahedron today?\n"); } @@ -1242,8 +1207,7 @@ int gmx_editconf(int argc, char *argv[]) if (bIndex) { fprintf(stderr, "\nSelect a group for output:\n"); - get_index(&atoms, opt2fn_null("-n", NFILE, fnm), - 1, &isize, &index, &grpname); + get_index(&atoms, opt2fn_null("-n", NFILE, fnm), 1, &isize, &index, &grpname); if (resnr_start >= 0) { @@ -1288,24 +1252,27 @@ int gmx_editconf(int argc, char *argv[]) out = gmx_ffopen(outfile, "w"); if (bMead) { - fprintf(out, "REMARK " + fprintf(out, + "REMARK " "The B-factors in this file hold atomic radii\n"); - fprintf(out, "REMARK " + fprintf(out, + "REMARK " "The occupancy in this file hold atomic charges\n"); } else if (bGrasp) { fprintf(out, "GRASP PDB FILE\nFORMAT NUMBER=1\n"); - fprintf(out, "REMARK " + fprintf(out, + "REMARK " "The B-factors in this file hold atomic charges\n"); - fprintf(out, "REMARK " + fprintf(out, + "REMARK " "The occupancy in this file hold atomic radii\n"); } else if (opt2bSet("-bf", NFILE, fnm)) { read_bfac(opt2fn("-bf", NFILE, fnm), &n_bfac, &bfac, &bfac_nr); - set_pdb_conf_bfac(atoms.nr, atoms.nres, &atoms, - n_bfac, bfac, bfac_nr, peratom); + set_pdb_conf_bfac(atoms.nr, atoms.nres, &atoms, n_bfac, bfac, bfac_nr, peratom); } if (opt2parg_bSet("-label", NPA, pa)) { @@ -1317,7 +1284,7 @@ int gmx_editconf(int argc, char *argv[]) /* Need to bypass the regular write_pdbfile because I don't want to change * all instances to include the boolean flag for writing out PQR files. */ - int *index; + int* index; snew(index, atoms.nr); for (int i = 0; i < atoms.nr; i++) { @@ -1332,7 +1299,7 @@ int gmx_editconf(int argc, char *argv[]) } if (visbox[0] > 0) { - visualize_box(out, bLegend ? atoms.nr+12 : atoms.nr, + visualize_box(out, bLegend ? atoms.nr + 12 : atoms.nr, bLegend ? atoms.nres = 12 : atoms.nres, box, visbox); } gmx_ffclose(out); diff --git a/src/gromacs/gmxpreprocess/editconf.h b/src/gromacs/gmxpreprocess/editconf.h index c1122c8088..a7c4e1dbaf 100644 --- a/src/gromacs/gmxpreprocess/editconf.h +++ b/src/gromacs/gmxpreprocess/editconf.h @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_EDITCONF_H #define GMX_GMXPREPROCESS_EDITCONF_H -int gmx_editconf(int argc, char *argv[]); +int gmx_editconf(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/fflibutil.cpp b/src/gromacs/gmxpreprocess/fflibutil.cpp index 55d9afd0a2..89eb9d44a2 100644 --- a/src/gromacs/gmxpreprocess/fflibutil.cpp +++ b/src/gromacs/gmxpreprocess/fflibutil.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,25 +52,25 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -const char *fflib_forcefield_dir_ext() +const char* fflib_forcefield_dir_ext() { return ".ff"; } -const char *fflib_forcefield_itp() +const char* fflib_forcefield_itp() { return "forcefield.itp"; } -const char *fflib_forcefield_doc() +const char* fflib_forcefield_doc() { return "forcefield.doc"; } -void fflib_filename_base(const char *filename, char *filebase, int maxlen) +void fflib_filename_base(const char* filename, char* filebase, int maxlen) { - const char *cptr; - char *ptr; + const char* cptr; + char* ptr; cptr = strrchr(filename, DIR_SEPARATOR); if (cptr != nullptr) @@ -84,8 +84,7 @@ void fflib_filename_base(const char *filename, char *filebase, int maxlen) } if (strlen(filename) >= static_cast(maxlen)) { - gmx_fatal(FARGS, "filename is longer (%zu) than maxlen (%d)", - strlen(filename), maxlen); + gmx_fatal(FARGS, "filename is longer (%zu) than maxlen (%d)", strlen(filename), maxlen); } strcpy(filebase, cptr); /* Remove the extension */ @@ -96,47 +95,41 @@ void fflib_filename_base(const char *filename, char *filebase, int maxlen) } } -std::vector fflib_search_file_end(const char *ffdir, - const char *file_end, - bool bFatalError) +std::vector fflib_search_file_end(const char* ffdir, const char* file_end, bool bFatalError) { try { std::string ffdirFull(gmx::getLibraryFileFinder().findFile(ffdir)); - std::vector result - = gmx::DirectoryEnumerator::enumerateFilesWithExtension( - ffdirFull.c_str(), file_end, true); + std::vector result = gmx::DirectoryEnumerator::enumerateFilesWithExtension( + ffdirFull.c_str(), file_end, true); if (result.empty() && bFatalError) { - std::string message - = gmx::formatString("Could not find any files ending on '%s' " - "in the force field directory '%s'", - file_end, ffdir); + std::string message = gmx::formatString( + "Could not find any files ending on '%s' " + "in the force field directory '%s'", + file_end, ffdir); GMX_THROW(gmx::InvalidInputError(message)); } - for (std::string &filename : result) + for (std::string& filename : result) { filename = gmx::Path::join(ffdir, filename); } return result; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } std::vector fflib_enumerate_forcefields() { - const char *const dirend = fflib_forcefield_dir_ext(); - const char *const filename = fflib_forcefield_itp(); - std::vector candidates - = gmx::getLibraryFileFinder().enumerateFiles( - gmx::DataFileOptions(dirend) - .throwIfNotFound(false)); + const char* const dirend = fflib_forcefield_dir_ext(); + const char* const filename = fflib_forcefield_itp(); + std::vector candidates = gmx::getLibraryFileFinder().enumerateFiles( + gmx::DataFileOptions(dirend).throwIfNotFound(false)); std::vector result; for (size_t i = 0; i < candidates.size(); ++i) { - std::string testPath(gmx::Path::join( - candidates[i].dir, candidates[i].name, filename)); + std::string testPath(gmx::Path::join(candidates[i].dir, candidates[i].name, filename)); // TODO: Consider also checking that the directory can be listed. if (gmx::File::exists(testPath, gmx::File::returnFalseOnError)) { @@ -148,23 +141,23 @@ std::vector fflib_enumerate_forcefields() // could also list the directories searched. if (result.empty()) { - std::string message - = gmx::formatString("No force fields found (files with name '%s' " - "in subdirectories ending on '%s')", - filename, dirend); + std::string message = gmx::formatString( + "No force fields found (files with name '%s' " + "in subdirectories ending on '%s')", + filename, dirend); GMX_THROW(gmx::InvalidInputError(message)); } return result; } -bool fflib_fexist(const std::string &file) +bool fflib_fexist(const std::string& file) { return !gmx::findLibraryFile(file, true, false).empty(); } -FILE *fflib_open(const std::string &file) +FILE* fflib_open(const std::string& file) { std::string fileFullPath = gmx::findLibraryFile(file); fprintf(stderr, "Opening force field file %s\n", fileFullPath.c_str()); diff --git a/src/gromacs/gmxpreprocess/fflibutil.h b/src/gromacs/gmxpreprocess/fflibutil.h index c608183a40..386a10bc16 100644 --- a/src/gromacs/gmxpreprocess/fflibutil.h +++ b/src/gromacs/gmxpreprocess/fflibutil.h @@ -49,33 +49,31 @@ */ std::vector fflib_enumerate_forcefields(); -const char *fflib_forcefield_dir_ext(); +const char* fflib_forcefield_dir_ext(); /* Returns the name of the force field directory extension */ -const char *fflib_forcefield_itp(); +const char* fflib_forcefield_itp(); /* Returns the name of the main forcefield itp file */ -const char *fflib_forcefield_doc(); +const char* fflib_forcefield_doc(); /* Returns the name of the forcefield documentation file */ -void fflib_filename_base(const char *filename, char *filebase, int maxlen); +void fflib_filename_base(const char* filename, char* filebase, int maxlen); /* Return the base file name of filename in base, * i.e. remove path and extension, if present. * base should be at least of size maxlen. */ -std::vector fflib_search_file_end(const char *ffdir, - const char *file_end, - bool bFatalError); +std::vector fflib_search_file_end(const char* ffdir, const char* file_end, bool bFatalError); /* Search for files ending on file_end in the force field directory fflib. * fflib should be in the GROMACS lib.path. * Return the number of files and the file names in filenames. */ -bool fflib_fexist(const std::string &file); +bool fflib_fexist(const std::string& file); /* Check if a file exists in the force field library */ -FILE *fflib_open(const std::string &file); +FILE* fflib_open(const std::string& file); /* Open force field library file "file" for reading. * "file" should contain the whole path to the force field library, * either absolute or relative to the current dir. diff --git a/src/gromacs/gmxpreprocess/gen_ad.cpp b/src/gromacs/gmxpreprocess/gen_ad.cpp index 19bf2ab547..2ccc05234c 100644 --- a/src/gromacs/gmxpreprocess/gen_ad.cpp +++ b/src/gromacs/gmxpreprocess/gen_ad.cpp @@ -64,24 +64,24 @@ #include "resall.h" #define DIHEDRAL_WAS_SET_IN_RTP 0 -static bool was_dihedral_set_in_rtp(const InteractionOfType &dih) +static bool was_dihedral_set_in_rtp(const InteractionOfType& dih) { // This is a bad way to check this, but I don't know how to make this better now. gmx::ArrayRef forceParam = dih.forceParam(); - return forceParam[MAXFORCEPARAM-1] == DIHEDRAL_WAS_SET_IN_RTP; + return forceParam[MAXFORCEPARAM - 1] == DIHEDRAL_WAS_SET_IN_RTP; } -typedef bool (*peq)(const InteractionOfType &p1, const InteractionOfType &p2); +typedef bool (*peq)(const InteractionOfType& p1, const InteractionOfType& p2); -static bool acomp(const InteractionOfType &a1, const InteractionOfType &a2) +static bool acomp(const InteractionOfType& a1, const InteractionOfType& a2) { - int ac; + int ac; - if ((ac = (a1.aj()-a2.aj())) != 0) + if ((ac = (a1.aj() - a2.aj())) != 0) { return ac < 0; } - else if ((ac = (a1.ai()-a2.ai())) != 0) + else if ((ac = (a1.ai() - a2.ai())) != 0) { return ac < 0; } @@ -91,11 +91,11 @@ static bool acomp(const InteractionOfType &a1, const InteractionOfType &a2) } } -static bool pcomp(const InteractionOfType &a1, const InteractionOfType &a2) +static bool pcomp(const InteractionOfType& a1, const InteractionOfType& a2) { - int pc; + int pc; - if ((pc = (a1.ai()-a2.ai())) != 0) + if ((pc = (a1.ai() - a2.ai())) != 0) { return pc < 0; } @@ -105,36 +105,34 @@ static bool pcomp(const InteractionOfType &a1, const InteractionOfType &a2) } } -static bool dcomp(const InteractionOfType &d1, const InteractionOfType &d2) +static bool dcomp(const InteractionOfType& d1, const InteractionOfType& d2) { - int dc; + int dc; /* First sort by J & K (the two central) atoms */ - if ((dc = (d1.aj()-d2.aj())) != 0) + if ((dc = (d1.aj() - d2.aj())) != 0) { return dc < 0; } - else if ((dc = (d1.ak()-d2.ak())) != 0) + else if ((dc = (d1.ak() - d2.ak())) != 0) { return dc < 0; } /* Then make sure to put rtp dihedrals before generated ones */ - else if (was_dihedral_set_in_rtp(d1) && - !was_dihedral_set_in_rtp(d2)) + else if (was_dihedral_set_in_rtp(d1) && !was_dihedral_set_in_rtp(d2)) { return true; } - else if (!was_dihedral_set_in_rtp(d1) && - was_dihedral_set_in_rtp(d2)) + else if (!was_dihedral_set_in_rtp(d1) && was_dihedral_set_in_rtp(d2)) { return false; } /* Then sort by I and J (two outer) atoms */ - else if ((dc = (d1.ai()-d2.ai())) != 0) + else if ((dc = (d1.ai() - d2.ai())) != 0) { return dc < 0; } - else if ((dc = (d1.al()-d2.al())) != 0) + else if ((dc = (d1.al() - d2.al())) != 0) { return dc < 0; } @@ -142,34 +140,33 @@ static bool dcomp(const InteractionOfType &d1, const InteractionOfType &d2) { // AMBER force fields with type 9 dihedrals can reach here, where we sort on // the contents of the string that names the macro for the parameters. - return std::lexicographical_compare(d1.interactionTypeName().begin(), - d1.interactionTypeName().end(), - d2.interactionTypeName().begin(), - d2.interactionTypeName().end()); + return std::lexicographical_compare( + d1.interactionTypeName().begin(), d1.interactionTypeName().end(), + d2.interactionTypeName().begin(), d2.interactionTypeName().end()); } } -static bool is_dihedral_on_same_bond(const InteractionOfType &p1, const InteractionOfType &p2) +static bool is_dihedral_on_same_bond(const InteractionOfType& p1, const InteractionOfType& p2) { - return ((p1.aj() == p2.aj()) && (p1.ak() == p2.ak())) || - ((p1.aj() == p2.ak()) && (p1.ak() == p2.aj())); + return ((p1.aj() == p2.aj()) && (p1.ak() == p2.ak())) + || ((p1.aj() == p2.ak()) && (p1.ak() == p2.aj())); } -static bool preq(const InteractionOfType &p1, const InteractionOfType &p2) +static bool preq(const InteractionOfType& p1, const InteractionOfType& p2) { return (p1.ai() == p2.ai()) && (p1.aj() == p2.aj()); } -static void rm2par(std::vector *p, peq eq) +static void rm2par(std::vector* p, peq eq) { if (p->empty()) { return; } - for (auto param = p->begin() + 1; param != p->end(); ) + for (auto param = p->begin() + 1; param != p->end();) { auto prev = param - 1; if (eq(*param, *prev)) @@ -183,30 +180,28 @@ static void rm2par(std::vector *p, peq eq) } } -static void cppar(gmx::ArrayRef types, - gmx::ArrayRef plist, - int ftype) +static void cppar(gmx::ArrayRef types, gmx::ArrayRef plist, int ftype) { /* Keep old stuff */ - for (const auto &type : types) + for (const auto& type : types) { plist[ftype].interactionTypes.push_back(type); } } -static bool idcomp(const InteractionOfType &a, const InteractionOfType &b) +static bool idcomp(const InteractionOfType& a, const InteractionOfType& b) { - int d; + int d; - if ((d = (a.ai()-b.ai())) != 0) + if ((d = (a.ai() - b.ai())) != 0) { return d < 0; } - else if ((d = (a.al()-b.al())) != 0) + else if ((d = (a.al() - b.al())) != 0) { return d < 0; } - else if ((d = (a.aj()-b.aj())) != 0) + else if ((d = (a.aj() - b.aj())) != 0) { return d < 0; } @@ -220,7 +215,7 @@ static void sort_id(gmx::ArrayRef ps) { if (ps.size() > 1) { - for (auto &parm : ps) + for (auto& parm : ps) { parm.sortAtomIds(); } @@ -228,13 +223,13 @@ static void sort_id(gmx::ArrayRef ps) } } -static int n_hydro(gmx::ArrayRef a, char ***atomname) +static int n_hydro(gmx::ArrayRef a, char*** atomname) { - int nh = 0; + int nh = 0; for (auto atom = a.begin(); atom < a.end(); atom += 3) { - const char *aname = *atomname[*atom]; + const char* aname = *atomname[*atom]; char c0 = toupper(aname[0]); if (c0 == 'H') { @@ -256,17 +251,18 @@ static int n_hydro(gmx::ArrayRef a, char ***atomname) * file). */ static std::vector clean_dih(gmx::ArrayRef dih, gmx::ArrayRef improper, - t_atoms *atoms, bool bKeepAllGeneratedDihedrals, + t_atoms* atoms, + bool bKeepAllGeneratedDihedrals, bool bRemoveDihedralIfWithImproper) { /* Construct the list of the indices of the dihedrals * (i.e. generated or read) that might be kept. */ - std::vector < std::pair < InteractionOfType, int>> newDihedrals; + std::vector> newDihedrals; if (bKeepAllGeneratedDihedrals) { fprintf(stderr, "Keeping all generated dihedrals\n"); int i = 0; - for (const auto &dihedral : dih) + for (const auto& dihedral : dih) { newDihedrals.emplace_back(std::pair(dihedral, i++)); } @@ -284,16 +280,15 @@ static std::vector clean_dih(gmx::ArrayRef(*dihedral, i++)); } } } int k = 0; - for (auto dihedral = newDihedrals.begin(); dihedral != newDihedrals.end(); ) + for (auto dihedral = newDihedrals.begin(); dihedral != newDihedrals.end();) { bool bWasSetInRTP = was_dihedral_set_in_rtp(dihedral->first); bool bKeep = true; @@ -323,9 +318,7 @@ static std::vector clean_dih(gmx::ArrayRefsecond + 1; for (int l = dihedral->second; - (l < next && - is_dihedral_on_same_bond(dihedral->first, dih[l])); - l++) + (l < next && is_dihedral_on_same_bond(dihedral->first, dih[l])); l++) { int nh = n_hydro(dih[l].atoms(), atoms->atomname); if (nh < minh) @@ -353,34 +346,33 @@ static std::vector clean_dih(gmx::ArrayRef finalDihedrals; finalDihedrals.reserve(newDihedrals.size()); - for (const auto ¶m : newDihedrals) + for (const auto& param : newDihedrals) { finalDihedrals.emplace_back(param.first); } return finalDihedrals; } -static std::vector get_impropers(t_atoms *atoms, +static std::vector get_impropers(t_atoms* atoms, gmx::ArrayRef globalPatches, - bool bAllowMissing) + bool bAllowMissing) { std::vector improper; /* Add all the impropers from the residue database to the list. */ - int start = 0; + int start = 0; if (!globalPatches.empty()) { for (int i = 0; (i < atoms->nres); i++) { - BondedInteractionList *impropers = &globalPatches[i].rb[ebtsIDIHS]; - for (const auto &bondeds : impropers->b) + BondedInteractionList* impropers = &globalPatches[i].rb[ebtsIDIHS]; + for (const auto& bondeds : impropers->b) { - bool bStop = false; - std::vector ai; + bool bStop = false; + std::vector ai; for (int k = 0; (k < 4) && !bStop; k++) { - int entry = search_atom(bondeds.a[k].c_str(), start, - atoms, "improper", bAllowMissing); + int entry = search_atom(bondeds.a[k].c_str(), start, atoms, "improper", bAllowMissing); if (entry != -1) { @@ -407,11 +399,11 @@ static std::vector get_impropers(t_atoms return improper; } -static int nb_dist(t_nextnb *nnb, int ai, int aj) +static int nb_dist(t_nextnb* nnb, int ai, int aj) { int nre, nrx, NRE; - int *nrexcl; - int *a; + int* nrexcl; + int* a; if (ai == aj) { @@ -434,13 +426,16 @@ static int nb_dist(t_nextnb *nnb, int ai, int aj) return NRE; } -static bool is_hydro(t_atoms *atoms, int ai) +static bool is_hydro(t_atoms* atoms, int ai) { return ((*(atoms->atomname[ai]))[0] == 'H'); } -static void get_atomnames_min(int n, gmx::ArrayRef anm, - int resind, t_atoms *atoms, gmx::ArrayRef a) +static void get_atomnames_min(int n, + gmx::ArrayRef anm, + int resind, + t_atoms* atoms, + gmx::ArrayRef a) { /* Assume ascending residue numbering */ for (int m = 0; m < n; m++) @@ -461,42 +456,37 @@ static void get_atomnames_min(int n, gmx::ArrayRef anm, } } -static void gen_excls(t_atoms *atoms, - t_excls *excls, - gmx::ArrayRef globalPatches, - bool bAllowMissing) +static void gen_excls(t_atoms* atoms, t_excls* excls, gmx::ArrayRef globalPatches, bool bAllowMissing) { int astart = 0; for (int a = 0; a < atoms->nr; a++) { int r = atoms->atom[a].resind; - if (a == atoms->nr-1 || atoms->atom[a+1].resind != r) + if (a == atoms->nr - 1 || atoms->atom[a + 1].resind != r) { - BondedInteractionList *hbexcl = &globalPatches[r].rb[ebtsEXCLS]; + BondedInteractionList* hbexcl = &globalPatches[r].rb[ebtsEXCLS]; - for (const auto &bondeds : hbexcl->b) + for (const auto& bondeds : hbexcl->b) { - const char *anm = bondeds.a[0].c_str(); - int i1 = search_atom(anm, astart, atoms, - "exclusion", bAllowMissing); - anm = bondeds.a[1].c_str(); - int i2 = search_atom(anm, astart, atoms, - "exclusion", bAllowMissing); + const char* anm = bondeds.a[0].c_str(); + int i1 = search_atom(anm, astart, atoms, "exclusion", bAllowMissing); + anm = bondeds.a[1].c_str(); + int i2 = search_atom(anm, astart, atoms, "exclusion", bAllowMissing); if (i1 != -1 && i2 != -1) { if (i1 > i2) { int itmp = i1; - i1 = i2; - i2 = itmp; + i1 = i2; + i2 = itmp; } - srenew(excls[i1].e, excls[i1].nr+1); + srenew(excls[i1].e, excls[i1].nr + 1); excls[i1].e[excls[i1].nr] = i2; excls[i1].nr++; } } - astart = a+1; + astart = a + 1; } } @@ -504,27 +494,27 @@ static void gen_excls(t_atoms *atoms, { if (excls[a].nr > 1) { - std::sort(excls[a].e, excls[a].e+excls[a].nr); + std::sort(excls[a].e, excls[a].e + excls[a].nr); } } } -static void remove_excl(t_excls *excls, int remove) +static void remove_excl(t_excls* excls, int remove) { int i; - for (i = remove+1; i < excls->nr; i++) + for (i = remove + 1; i < excls->nr; i++) { - excls->e[i-1] = excls->e[i]; + excls->e[i - 1] = excls->e[i]; } excls->nr--; } -static void clean_excls(t_nextnb *nnb, int nrexcl, t_excls excls[]) +static void clean_excls(t_nextnb* nnb, int nrexcl, t_excls excls[]) { int i, j, j1, k, k1, l, l1, e; - t_excls *excl; + t_excls* excl; if (nrexcl >= 1) { @@ -586,9 +576,12 @@ static void clean_excls(t_nextnb *nnb, int nrexcl, t_excls excls[]) } /* Generate pairs, angles and dihedrals from .rtp settings */ -void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, - gmx::ArrayRef plist, t_excls excls[], gmx::ArrayRef globalPatches, - bool bAllowMissing) +void gen_pad(t_atoms* atoms, + gmx::ArrayRef rtpFFDB, + gmx::ArrayRef plist, + t_excls excls[], + gmx::ArrayRef globalPatches, + bool bAllowMissing) { t_nextnb nnb; init_nnb(&nnb, atoms->nr, 4); @@ -599,12 +592,12 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, * from the bonds. The ones that are already there from the rtp file * will be retained. */ - std::vector ang; - std::vector dih; - std::vector pai; - std::vector improper; + std::vector ang; + std::vector dih; + std::vector pai; + std::vector improper; - std::array anm; + std::array anm; if (!globalPatches.empty()) { @@ -614,7 +607,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, { for (int j = 0; j < ebtsNR; j++) { - for (auto &bondeds : globalPatches[i].rb[j].b) + for (auto& bondeds : globalPatches[i].rb[j].b) { bondeds.match = false; } @@ -640,7 +633,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, /* Generate every angle only once */ if (i < k1) { - std::vector atomNumbers = {i, j1, k1}; + std::vector atomNumbers = { i, j1, k1 }; std::string name; if (!globalPatches.empty()) { @@ -651,22 +644,22 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, minres = std::min(minres, atoms->atom[atomNumbers[m]].resind); maxres = std::max(maxres, atoms->atom[atomNumbers[m]].resind); } - int res = 2*minres-maxres; + int res = 2 * minres - maxres; do { - res += maxres-minres; + res += maxres - minres; get_atomnames_min(3, anm, res, atoms, atomNumbers); - BondedInteractionList *hbang = &globalPatches[res].rb[ebtsANGLES]; - for (auto &bondeds : hbang->b) + BondedInteractionList* hbang = &globalPatches[res].rb[ebtsANGLES]; + for (auto& bondeds : hbang->b) { if (anm[1] == bondeds.aj()) { bool bFound = false; for (int m = 0; m < 3; m += 2) { - bFound = (bFound || - ((anm[m] == bondeds.ai()) && - (anm[2-m] == bondeds.ak()))); + bFound = (bFound + || ((anm[m] == bondeds.ai()) + && (anm[2 - m] == bondeds.ak()))); } if (bFound) { @@ -676,8 +669,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, } } } - } - while (res < maxres); + } while (res < maxres); } ang.push_back(InteractionOfType(atomNumbers, {}, name)); } @@ -691,7 +683,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, int l1 = nnb.a[k1][1][l]; if ((l1 != i) && (l1 != j1)) { - std::vector atomNumbers = {i, j1, k1, l1}; + std::vector atomNumbers = { i, j1, k1, l1 }; std::string name; int nFound = 0; if (!globalPatches.empty()) @@ -700,29 +692,25 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, int maxres = minres; for (int m = 1; m < 4; m++) { - minres = std::min( - minres, - atoms->atom[atomNumbers[m]].resind); - maxres = std::max( - maxres, - atoms->atom[atomNumbers[m]].resind); + minres = std::min(minres, atoms->atom[atomNumbers[m]].resind); + maxres = std::max(maxres, atoms->atom[atomNumbers[m]].resind); } - int res = 2*minres-maxres; + int res = 2 * minres - maxres; do { - res += maxres-minres; + res += maxres - minres; get_atomnames_min(4, anm, res, atoms, atomNumbers); - BondedInteractionList *hbdih = &globalPatches[res].rb[ebtsPDIHS]; - for (auto &bondeds : hbdih->b) + BondedInteractionList* hbdih = &globalPatches[res].rb[ebtsPDIHS]; + for (auto& bondeds : hbdih->b) { bool bFound = false; for (int m = 0; m < 2; m++) { - bFound = (bFound || - ((anm[3*m] == bondeds.ai()) && - (anm[1+m] == bondeds.aj()) && - (anm[2-m] == bondeds.ak()) && - (anm[3-3*m] == bondeds.al()))); + bFound = (bFound + || ((anm[3 * m] == bondeds.ai()) + && (anm[1 + m] == bondeds.aj()) + && (anm[2 - m] == bondeds.ak()) + && (anm[3 - 3 * m] == bondeds.al()))); } if (bFound) { @@ -735,16 +723,16 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, */ nFound++; dih.push_back(InteractionOfType(atomNumbers, {}, name)); - dih.back().setForceParameter(MAXFORCEPARAM-1, DIHEDRAL_WAS_SET_IN_RTP); + dih.back().setForceParameter( + MAXFORCEPARAM - 1, DIHEDRAL_WAS_SET_IN_RTP); } } - } - while (res < maxres); + } while (res < maxres); } if (nFound == 0) { - std::vector atoms = {i, j1, k1, l1}; - dih.push_back(InteractionOfType(atoms, {}, "")); + std::vector atoms = { i, j1, k1, l1 }; + dih.push_back(InteractionOfType(atoms, {}, "")); } int nbd = nb_dist(&nnb, i, l1); @@ -759,10 +747,10 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, } if (!bExcl) { - if (rtpFFDB[0].bGenerateHH14Interactions || - !(is_hydro(atoms, i1) && is_hydro(atoms, i2))) + if (rtpFFDB[0].bGenerateHH14Interactions + || !(is_hydro(atoms, i1) && is_hydro(atoms, i2))) { - std::vector atoms = {i1, i2}; + std::vector atoms = { i1, i2 }; pai.push_back(InteractionOfType(atoms, {}, "")); } } @@ -785,8 +773,8 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, for (int i = 0; i < atoms->nres; i++) { /* Add remaining angles from hackblock */ - BondedInteractionList *hbang = &globalPatches[i].rb[ebtsANGLES]; - for (auto &bondeds : hbang->b) + BondedInteractionList* hbang = &globalPatches[i].rb[ebtsANGLES]; + for (auto& bondeds : hbang->b) { if (bondeds.match) { @@ -798,7 +786,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, bool bFound = true; for (int k = 0; k < 3 && bFound; k++) { - const char *p = bondeds.a[k].c_str(); + const char* p = bondeds.a[k].c_str(); int res = i; if (p[0] == '-') { @@ -811,7 +799,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, res++; } atomNumbers.emplace_back(search_res_atom(p, res, atoms, "angle", TRUE)); - bFound = (atomNumbers.back() != -1); + bFound = (atomNumbers.back() != -1); } if (bFound) @@ -823,8 +811,8 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, } /* Add remaining dihedrals from hackblock */ - BondedInteractionList *hbdih = &globalPatches[i].rb[ebtsPDIHS]; - for (auto &bondeds : hbdih->b) + BondedInteractionList* hbdih = &globalPatches[i].rb[ebtsPDIHS]; + for (auto& bondeds : hbdih->b) { if (bondeds.match) { @@ -836,7 +824,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, bool bFound = true; for (int k = 0; k < 4 && bFound; k++) { - const char *p = bondeds.a[k].c_str(); + const char* p = bondeds.a[k].c_str(); int res = i; if (p[0] == '-') { @@ -849,7 +837,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, res++; } atomNumbers.emplace_back(search_res_atom(p, res, atoms, "dihedral", TRUE)); - bFound = (atomNumbers.back() != -1); + bFound = (atomNumbers.back() != -1); } if (bFound) @@ -897,8 +885,7 @@ void gen_pad(t_atoms *atoms, gmx::ArrayRef rtpFFDB, if (!dih.empty()) { fprintf(stderr, "Before cleaning: %zu dihedrals\n", dih.size()); - dih = clean_dih(dih, improper, atoms, - rtpFFDB[0].bKeepAllGeneratedDihedrals, + dih = clean_dih(dih, improper, atoms, rtpFFDB[0].bKeepAllGeneratedDihedrals, rtpFFDB[0].bRemoveDihedralIfWithImproper); } diff --git a/src/gromacs/gmxpreprocess/gen_ad.h b/src/gromacs/gmxpreprocess/gen_ad.h index 489ee4ba06..f05ffdcf4d 100644 --- a/src/gromacs/gmxpreprocess/gen_ad.h +++ b/src/gromacs/gmxpreprocess/gen_ad.h @@ -46,11 +46,11 @@ struct MoleculePatchDatabase; struct InteractionsOfType; struct PreprocessResidue; -void gen_pad(t_atoms *atoms, - gmx::ArrayRef rtpFFDB, - gmx::ArrayRef plist, - t_excls excls[], - gmx::ArrayRef globalPatches, - bool bAllowMissing); +void gen_pad(t_atoms* atoms, + gmx::ArrayRef rtpFFDB, + gmx::ArrayRef plist, + t_excls excls[], + gmx::ArrayRef globalPatches, + bool bAllowMissing); #endif diff --git a/src/gromacs/gmxpreprocess/gen_maxwell_velocities.cpp b/src/gromacs/gmxpreprocess/gen_maxwell_velocities.cpp index dee74291c0..fbcd56eeb4 100644 --- a/src/gromacs/gmxpreprocess/gen_maxwell_velocities.cpp +++ b/src/gromacs/gmxpreprocess/gen_maxwell_velocities.cpp @@ -50,38 +50,37 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void low_mspeed(real tempi, - gmx_mtop_t *mtop, rvec v[], gmx::ThreeFry2x64<> * rng) +static void low_mspeed(real tempi, gmx_mtop_t* mtop, rvec v[], gmx::ThreeFry2x64<>* rng) { - int nrdf; - real boltz; - real ekin, temp; - gmx::TabulatedNormalDistribution normalDist; + int nrdf; + real boltz; + real ekin, temp; + gmx::TabulatedNormalDistribution normalDist; - boltz = BOLTZ*tempi; + boltz = BOLTZ * tempi; ekin = 0.0; nrdf = 0; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); real mass = local.m; if (mass > 0) { rng->restart(i, 0); - real sd = std::sqrt(boltz/mass); + real sd = std::sqrt(boltz / mass); for (int m = 0; (m < DIM); m++) { - v[i][m] = sd*normalDist(*rng); - ekin += 0.5*mass*v[i][m]*v[i][m]; + v[i][m] = sd * normalDist(*rng); + ekin += 0.5 * mass * v[i][m] * v[i][m]; } nrdf += DIM; } } - temp = (2.0*ekin)/(nrdf*BOLTZ); + temp = (2.0 * ekin) / (nrdf * BOLTZ); if (temp > 0) { - real scal = std::sqrt(tempi/temp); + real scal = std::sqrt(tempi / temp); for (int i = 0; (i < mtop->natoms); i++) { for (int m = 0; (m < DIM); m++) @@ -90,8 +89,7 @@ static void low_mspeed(real tempi, } } } - fprintf(stderr, "Velocities were taken from a Maxwell distribution at %g K\n", - tempi); + fprintf(stderr, "Velocities were taken from a Maxwell distribution at %g K\n", tempi); if (debug) { fprintf(debug, @@ -101,7 +99,7 @@ static void low_mspeed(real tempi, } } -void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t *mtop, rvec v[]) +void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t* mtop, rvec v[]) { if (seed == 0) @@ -109,13 +107,12 @@ void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t *mtop, rvec v[]) seed = static_cast(gmx::makeRandomSeed()); fprintf(stderr, "Using random seed %u for generating velocities\n", seed); } - gmx::ThreeFry2x64<> rng(seed, gmx::RandomDomain::MaxwellVelocities); + gmx::ThreeFry2x64<> rng(seed, gmx::RandomDomain::MaxwellVelocities); low_mspeed(tempi, mtop, v, &rng); } -static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], - rvec xcm, rvec vcm, rvec acm, matrix L) +static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], rvec xcm, rvec vcm, rvec acm, matrix L) { rvec dx, a0; real tm, m0; @@ -127,14 +124,14 @@ static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], tm = 0.0; for (i = 0; (i < natoms); i++) { - m0 = mass[i]; + m0 = mass[i]; tm += m0; cprod(x[i], v[i], a0); for (m = 0; (m < DIM); m++) { - xcm[m] += m0*x[i][m]; /* c.o.m. position */ - vcm[m] += m0*v[i][m]; /* c.o.m. velocity */ - acm[m] += m0*a0[m]; /* rotational velocity around c.o.m. */ + xcm[m] += m0 * x[i][m]; /* c.o.m. position */ + vcm[m] += m0 * v[i][m]; /* c.o.m. velocity */ + acm[m] += m0 * a0[m]; /* rotational velocity around c.o.m. */ } } cprod(xcm, vcm, a0); @@ -142,12 +139,11 @@ static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], { xcm[m] /= tm; vcm[m] /= tm; - acm[m] -= a0[m]/tm; + acm[m] -= a0[m] / tm; } -#define PVEC(str, v) fprintf(log, \ - "%s[X]: %10.5e %s[Y]: %10.5e %s[Z]: %10.5e\n", \ - str, (v)[0], str, (v)[1], str, (v)[2]) +#define PVEC(str, v) \ + fprintf(log, "%s[X]: %10.5e %s[Y]: %10.5e %s[Z]: %10.5e\n", str, (v)[0], str, (v)[1], str, (v)[2]) #ifdef DEBUG PVEC("xcm", xcm); PVEC("acm", acm); @@ -160,14 +156,14 @@ static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], m0 = mass[i]; for (m = 0; (m < DIM); m++) { - dx[m] = x[i][m]-xcm[m]; + dx[m] = x[i][m] - xcm[m]; } - L[XX][XX] += dx[XX]*dx[XX]*m0; - L[XX][YY] += dx[XX]*dx[YY]*m0; - L[XX][ZZ] += dx[XX]*dx[ZZ]*m0; - L[YY][YY] += dx[YY]*dx[YY]*m0; - L[YY][ZZ] += dx[YY]*dx[ZZ]*m0; - L[ZZ][ZZ] += dx[ZZ]*dx[ZZ]*m0; + L[XX][XX] += dx[XX] * dx[XX] * m0; + L[XX][YY] += dx[XX] * dx[YY] * m0; + L[XX][ZZ] += dx[XX] * dx[ZZ] * m0; + L[YY][YY] += dx[YY] * dx[YY] * m0; + L[YY][ZZ] += dx[YY] * dx[ZZ] * m0; + L[ZZ][ZZ] += dx[ZZ] * dx[ZZ] * m0; } #ifdef DEBUG PVEC("L-x", L[XX]); @@ -178,7 +174,7 @@ static real calc_cm(int natoms, const real mass[], rvec x[], rvec v[], return tm; } -void stop_cm(FILE gmx_unused *log, int natoms, real mass[], rvec x[], rvec v[]) +void stop_cm(FILE gmx_unused* log, int natoms, real mass[], rvec x[], rvec v[]) { rvec xcm, vcm, acm; tensor L; diff --git a/src/gromacs/gmxpreprocess/gen_maxwell_velocities.h b/src/gromacs/gmxpreprocess/gen_maxwell_velocities.h index 63d64d51c0..e339cd797d 100644 --- a/src/gromacs/gmxpreprocess/gen_maxwell_velocities.h +++ b/src/gromacs/gmxpreprocess/gen_maxwell_velocities.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,8 +53,7 @@ struct gmx_mtop_t; * \param[in] mtop Molecular Topology * \param[out] v Velocities */ -void maxwell_speed(real tempi, unsigned int seed, - gmx_mtop_t *mtop, rvec v[]); +void maxwell_speed(real tempi, unsigned int seed, gmx_mtop_t* mtop, rvec v[]); /*! \brief * Remove the center of mass motion in a set of coordinates. @@ -65,6 +64,6 @@ void maxwell_speed(real tempi, unsigned int seed, * \param[in] x Coordinates * \param[out] v Velocities */ -void stop_cm(FILE *log, int natoms, real mass[], rvec x[], rvec v[]); +void stop_cm(FILE* log, int natoms, real mass[], rvec x[], rvec v[]); #endif diff --git a/src/gromacs/gmxpreprocess/gen_vsite.cpp b/src/gromacs/gmxpreprocess/gen_vsite.cpp index 7255916acb..c72debf48a 100644 --- a/src/gromacs/gmxpreprocess/gen_vsite.cpp +++ b/src/gromacs/gmxpreprocess/gen_vsite.cpp @@ -73,8 +73,8 @@ #include "resall.h" #define MAXNAME 32 -#define OPENDIR '[' /* starting sign for directive */ -#define CLOSEDIR ']' /* ending sign for directive */ +#define OPENDIR '[' /* starting sign for directive */ +#define CLOSEDIR ']' /* ending sign for directive */ /*! \libinternal \brief * The configuration describing a virtual site. @@ -90,11 +90,18 @@ struct VirtualSiteConfiguration * \param[in] nextheavy Type of bonded heavy atom. * \param[in] dummy What kind of dummy is used in the vsite. */ - explicit VirtualSiteConfiguration(const std::string &type, bool planar, - int nhyd, const std::string &nextheavy, const std::string &dummy) - : atomtype(type), isplanar(planar), nHydrogens(nhyd), nextHeavyType(nextheavy), - dummyMass(dummy) - {} + explicit VirtualSiteConfiguration(const std::string& type, + bool planar, + int nhyd, + const std::string& nextheavy, + const std::string& dummy) : + atomtype(type), + isplanar(planar), + nHydrogens(nhyd), + nextHeavyType(nextheavy), + dummyMass(dummy) + { + } //! Type for the XH3/XH2 atom. std::string atomtype; /*! \brief Is the configuration planar? @@ -103,9 +110,9 @@ struct VirtualSiteConfiguration * ones are in a planar geometry. The two next entries * are undefined in that case. */ - bool isplanar = false; - //!cnumber of connected hydrogens. - int nHydrogens; + bool isplanar = false; + //! cnumber of connected hydrogens. + int nHydrogens; //! Type for the heavy atom bonded to XH2/XH3. std::string nextHeavyType; //! The type of MNH* or MCH3* dummy mass to use. @@ -128,8 +135,7 @@ struct VirtualSiteTopology * * \param[in] name Residue name. */ - explicit VirtualSiteTopology(const std::string &name) : resname(name) - {} + explicit VirtualSiteTopology(const std::string& name) : resname(name) {} //! Residue name. std::string resname; //! Helper struct for single bond in virtual site. @@ -142,15 +148,18 @@ struct VirtualSiteTopology * \param[in] a2 Second atom name. * \param[in] v Value for distance. */ - VirtualSiteBond(const std::string &a1, const std::string &a2, real v) : - atom1(a1), atom2(a2), value(v) - {} + VirtualSiteBond(const std::string& a1, const std::string& a2, real v) : + atom1(a1), + atom2(a2), + value(v) + { + } //! Atom 1 in bond. std::string atom1; //! Atom 2 in bond. std::string atom2; //! Distance value between atoms. - float value; + float value; }; //! Container of all bonds in virtual site. std::vector bond; @@ -165,9 +174,13 @@ struct VirtualSiteTopology * \param[in] a3 Third atom name. * \param[in] v Value for angle. */ - VirtualSiteAngle(const std::string &a1, const std::string &a2, const std::string &a3, real v) : - atom1(a1), atom2(a2), atom3(a3), value(v) - {} + VirtualSiteAngle(const std::string& a1, const std::string& a2, const std::string& a3, real v) : + atom1(a1), + atom2(a2), + atom3(a3), + value(v) + { + } //! Atom 1 in angle. std::string atom1; //! Atom 2 in angle. @@ -175,33 +188,33 @@ struct VirtualSiteTopology //! Atom 3 in angle. std::string atom3; //! Value for angle. - float value; + float value; }; //! Container for all angles in virtual site. std::vector angle; }; -enum { - DDB_CH3, DDB_NH3, DDB_NH2, DDB_PHE, DDB_TYR, - DDB_TRP, DDB_HISA, DDB_HISB, DDB_HISH, DDB_DIR_NR +enum +{ + DDB_CH3, + DDB_NH3, + DDB_NH2, + DDB_PHE, + DDB_TYR, + DDB_TRP, + DDB_HISA, + DDB_HISB, + DDB_HISH, + DDB_DIR_NR }; typedef char t_dirname[STRLEN]; -static const t_dirname ddb_dirnames[DDB_DIR_NR] = { - "CH3", - "NH3", - "NH2", - "PHE", - "TYR", - "TRP", - "HISA", - "HISB", - "HISH" -}; +static const t_dirname ddb_dirnames[DDB_DIR_NR] = { "CH3", "NH3", "NH2", "PHE", "TYR", + "TRP", "HISA", "HISB", "HISH" }; -static int ddb_name2dir(char *name) +static int ddb_name2dir(char* name) { /* Translate a directive name to the number of the directive. * HID/HIE/HIP names are translated to the ones we use in Gromacs. @@ -223,9 +236,9 @@ static int ddb_name2dir(char *name) } -static void read_vsite_database(const char *ddbname, - std::vector *vsiteconflist, - std::vector *vsitetoplist) +static void read_vsite_database(const char* ddbname, + std::vector* vsiteconflist, + std::vector* vsitetoplist) { /* This routine is a quick hack to fix the problem with hardcoded atomtypes * and aromatic vsite parameters by reading them from a ff???.vsd file. @@ -240,17 +253,17 @@ static void read_vsite_database(const char *ddbname, * case the second field should just be the word planar. */ - char dirstr[STRLEN]; - char pline[STRLEN]; - int curdir; - char *ch; - char s1[MAXNAME], s2[MAXNAME], s3[MAXNAME], s4[MAXNAME]; + char dirstr[STRLEN]; + char pline[STRLEN]; + int curdir; + char* ch; + char s1[MAXNAME], s2[MAXNAME], s3[MAXNAME], s4[MAXNAME]; gmx::FilePtr ddb = gmx::openLibraryFile(ddbname); curdir = -1; - while (fgets2(pline, STRLEN-2, ddb.get()) != nullptr) + while (fgets2(pline, STRLEN - 2, ddb.get()) != nullptr) { strip_comment(pline); trim(pline); @@ -258,20 +271,18 @@ static void read_vsite_database(const char *ddbname, { if (pline[0] == OPENDIR) { - strncpy(dirstr, pline+1, STRLEN-2); - if ((ch = strchr (dirstr, CLOSEDIR)) != nullptr) + strncpy(dirstr, pline + 1, STRLEN - 2); + if ((ch = strchr(dirstr, CLOSEDIR)) != nullptr) { (*ch) = 0; } - trim (dirstr); + trim(dirstr); - if (!gmx_strcasecmp(dirstr, "HID") || - !gmx_strcasecmp(dirstr, "HISD")) + if (!gmx_strcasecmp(dirstr, "HID") || !gmx_strcasecmp(dirstr, "HISD")) { sprintf(dirstr, "HISA"); } - else if (!gmx_strcasecmp(dirstr, "HIE") || - !gmx_strcasecmp(dirstr, "HISE")) + else if (!gmx_strcasecmp(dirstr, "HIE") || !gmx_strcasecmp(dirstr, "HISE")) { sprintf(dirstr, "HISB"); } @@ -283,8 +294,7 @@ static void read_vsite_database(const char *ddbname, curdir = ddb_name2dir(dirstr); if (curdir < 0) { - gmx_fatal(FARGS, "Invalid directive %s in vsite database %s", - dirstr, ddbname); + gmx_fatal(FARGS, "Invalid directive %s in vsite database %s", dirstr, ddbname); } } else @@ -332,9 +342,10 @@ static void read_vsite_database(const char *ddbname, case DDB_HISB: case DDB_HISH: { - const auto found = std::find_if(vsitetoplist->begin(), vsitetoplist->end(), - [&dirstr](const auto &entry) - { return gmx::equalCaseInsensitive(dirstr, entry.resname); }); + const auto found = std::find_if( + vsitetoplist->begin(), vsitetoplist->end(), [&dirstr](const auto& entry) { + return gmx::equalCaseInsensitive(dirstr, entry.resname); + }); /* Allocate a new topology entry if this is a new residue */ if (found == vsitetoplist->end()) { @@ -353,17 +364,21 @@ static void read_vsite_database(const char *ddbname, else if (numberOfSites == 4) { /* angle */ - vsitetoplist->back().angle.emplace_back(s1String, s2String, s3String, strtod(s4, nullptr)); + vsitetoplist->back().angle.emplace_back(s1String, s2String, s3String, + strtod(s4, nullptr)); /* angle */ } else { - gmx_fatal(FARGS, "Need 3 or 4 values to specify bond/angle values in %s: %s\n", ddbname, pline); + gmx_fatal(FARGS, + "Need 3 or 4 values to specify bond/angle values in %s: %s\n", + ddbname, pline); } } break; default: - gmx_fatal(FARGS, "Didnt find a case for directive %s in read_vsite_database\n", dirstr); + gmx_fatal(FARGS, + "Didnt find a case for directive %s in read_vsite_database\n", dirstr); } } } @@ -371,16 +386,16 @@ static void read_vsite_database(const char *ddbname, } static int nitrogen_is_planar(gmx::ArrayRef vsiteconflist, - const std::string &atomtype) + const std::string& atomtype) { /* Return 1 if atomtype exists in database list and is planar, 0 if not, * and -1 if not found. */ int res; - const auto found = std::find_if(vsiteconflist.begin(), vsiteconflist.end(), - [&atomtype](const auto &entry) - { return (gmx::equalCaseInsensitive(entry.atomtype, atomtype) && - entry.nHydrogens == 2); }); + const auto found = + std::find_if(vsiteconflist.begin(), vsiteconflist.end(), [&atomtype](const auto& entry) { + return (gmx::equalCaseInsensitive(entry.atomtype, atomtype) && entry.nHydrogens == 2); + }); if (found != vsiteconflist.end()) { res = static_cast(found->isplanar); @@ -394,13 +409,15 @@ static int nitrogen_is_planar(gmx::ArrayRef vsit } static std::string get_dummymass_name(gmx::ArrayRef vsiteconflist, - const std::string &atom, const std::string &nextheavy) + const std::string& atom, + const std::string& nextheavy) { /* Return the dummy mass name if found, or NULL if not set in ddb database */ - const auto found = std::find_if(vsiteconflist.begin(), vsiteconflist.end(), - [&atom, &nextheavy](const auto &entry) - { return (gmx::equalCaseInsensitive(atom, entry.atomtype) && - gmx::equalCaseInsensitive(nextheavy, entry.nextHeavyType)); }); + const auto found = std::find_if( + vsiteconflist.begin(), vsiteconflist.end(), [&atom, &nextheavy](const auto& entry) { + return (gmx::equalCaseInsensitive(atom, entry.atomtype) + && gmx::equalCaseInsensitive(nextheavy, entry.nextHeavyType)); + }); if (found != vsiteconflist.end()) { return found->dummyMass; @@ -412,27 +429,28 @@ static std::string get_dummymass_name(gmx::ArrayRef vsitetop, - const std::string &res, - const std::string &atom1, - const std::string &atom2) + const std::string& res, + const std::string& atom1, + const std::string& atom2) { - const auto found = std::find_if(vsitetop.begin(), vsitetop.end(), - [&res](const auto &entry) - { return gmx::equalCaseInsensitive(res, entry.resname); }); + const auto found = std::find_if(vsitetop.begin(), vsitetop.end(), [&res](const auto& entry) { + return gmx::equalCaseInsensitive(res, entry.resname); + }); if (found == vsitetop.end()) { gmx_fatal(FARGS, "No vsite information for residue %s found in vsite database.\n", res.c_str()); } - const auto foundBond = std::find_if(found->bond.begin(), found->bond.end(), - [&atom1, &atom2](const auto &entry) - { return ((atom1 == entry.atom1 && atom2 == entry.atom2) || - (atom1 == entry.atom2 && atom2 == entry.atom1)); }); + const auto foundBond = + std::find_if(found->bond.begin(), found->bond.end(), [&atom1, &atom2](const auto& entry) { + return ((atom1 == entry.atom1 && atom2 == entry.atom2) + || (atom1 == entry.atom2 && atom2 == entry.atom1)); + }); if (foundBond == found->bond.end()) { - gmx_fatal(FARGS, "Couldnt find bond %s-%s for residue %s in vsite database.\n", atom1.c_str(), atom2.c_str(), res.c_str()); + gmx_fatal(FARGS, "Couldnt find bond %s-%s for residue %s in vsite database.\n", + atom1.c_str(), atom2.c_str(), res.c_str()); } return foundBond->value; @@ -440,44 +458,53 @@ static real get_ddb_bond(gmx::ArrayRef vsitetop, static real get_ddb_angle(gmx::ArrayRef vsitetop, - const std::string &res, - const std::string &atom1, - const std::string &atom2, - const std::string &atom3) + const std::string& res, + const std::string& atom1, + const std::string& atom2, + const std::string& atom3) { - const auto found = std::find_if(vsitetop.begin(), vsitetop.end(), - [&res](const auto &entry) - { return gmx::equalCaseInsensitive(res, entry.resname); }); + const auto found = std::find_if(vsitetop.begin(), vsitetop.end(), [&res](const auto& entry) { + return gmx::equalCaseInsensitive(res, entry.resname); + }); if (found == vsitetop.end()) { gmx_fatal(FARGS, "No vsite information for residue %s found in vsite database.\n", res.c_str()); } - const auto foundAngle = std::find_if(found->angle.begin(), found->angle.end(), - [&atom1, &atom2, &atom3](const auto &entry) - { return ((atom1 == entry.atom1 && atom2 == entry.atom2 && atom3 == entry.atom3) || - (atom1 == entry.atom3 && atom2 == entry.atom2 && atom3 == entry.atom1) || - (atom1 == entry.atom2 && atom2 == entry.atom1 && atom3 == entry.atom3) || - (atom1 == entry.atom3 && atom2 == entry.atom1 && atom3 == entry.atom2)); }); + const auto foundAngle = std::find_if( + found->angle.begin(), found->angle.end(), [&atom1, &atom2, &atom3](const auto& entry) { + return ((atom1 == entry.atom1 && atom2 == entry.atom2 && atom3 == entry.atom3) + || (atom1 == entry.atom3 && atom2 == entry.atom2 && atom3 == entry.atom1) + || (atom1 == entry.atom2 && atom2 == entry.atom1 && atom3 == entry.atom3) + || (atom1 == entry.atom3 && atom2 == entry.atom1 && atom3 == entry.atom2)); + }); if (foundAngle == found->angle.end()) { - gmx_fatal(FARGS, "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n", atom1.c_str(), atom2.c_str(), atom3.c_str(), res.c_str()); + gmx_fatal(FARGS, "Couldnt find angle %s-%s-%s for residue %s in vsite database.\n", + atom1.c_str(), atom2.c_str(), atom3.c_str(), res.c_str()); } return foundAngle->value; } -static void count_bonds(int atom, InteractionsOfType *psb, char ***atomname, - int *nrbonds, int *nrHatoms, int Hatoms[], int *Heavy, - int *nrheavies, int heavies[]) +static void count_bonds(int atom, + InteractionsOfType* psb, + char*** atomname, + int* nrbonds, + int* nrHatoms, + int Hatoms[], + int* Heavy, + int* nrheavies, + int heavies[]) { int heavy, other, nrb, nrH, nrhv; /* find heavy atom bound to this hydrogen */ heavy = NOTSET; - for (auto parm = psb->interactionTypes.begin(); (parm != psb->interactionTypes.end()) && (heavy == NOTSET); parm++) + for (auto parm = psb->interactionTypes.begin(); + (parm != psb->interactionTypes.end()) && (heavy == NOTSET); parm++) { if (parm->ai() == atom) { @@ -490,14 +517,14 @@ static void count_bonds(int atom, InteractionsOfType *psb, char ***atomname, } if (heavy == NOTSET) { - gmx_fatal(FARGS, "unbound hydrogen atom %d", atom+1); + gmx_fatal(FARGS, "unbound hydrogen atom %d", atom + 1); } /* find all atoms bound to heavy atom */ other = NOTSET; nrb = 0; nrH = 0; nrhv = 0; - for (const auto &parm : psb->interactionTypes) + for (const auto& parm : psb->interactionTypes) { if (parm.ai() == heavy) { @@ -529,30 +556,28 @@ static void count_bonds(int atom, InteractionsOfType *psb, char ***atomname, *nrheavies = nrhv; } -static void print_bonds(FILE *fp, int o2n[], - int nrHatoms, const int Hatoms[], int Heavy, - int nrheavies, const int heavies[]) +static void +print_bonds(FILE* fp, int o2n[], int nrHatoms, const int Hatoms[], int Heavy, int nrheavies, const int heavies[]) { int i; fprintf(fp, "Found: %d Hatoms: ", nrHatoms); for (i = 0; i < nrHatoms; i++) { - fprintf(fp, " %d", o2n[Hatoms[i]]+1); + fprintf(fp, " %d", o2n[Hatoms[i]] + 1); } - fprintf(fp, "; %d Heavy atoms: %d", nrheavies+1, o2n[Heavy]+1); + fprintf(fp, "; %d Heavy atoms: %d", nrheavies + 1, o2n[Heavy] + 1); for (i = 0; i < nrheavies; i++) { - fprintf(fp, " %d", o2n[heavies[i]]+1); + fprintf(fp, " %d", o2n[heavies[i]] + 1); } fprintf(fp, "\n"); } -static int get_atype(int atom, t_atoms *at, gmx::ArrayRef rtpFFDB, - ResidueType *rt) +static int get_atype(int atom, t_atoms* at, gmx::ArrayRef rtpFFDB, ResidueType* rt) { - int type; - bool bNterm; + int type; + bool bNterm; if (at->atom[atom].m != 0.0F) { @@ -561,34 +586,32 @@ static int get_atype(int atom, t_atoms *at, gmx::ArrayRefresinfo[at->atom[atom].resind].name), rtpFFDB); - bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein") && - (at->atom[atom].resind == 0); - int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm); - type = localPpResidue->atom[j].type; + auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB); + bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein") + && (at->atom[atom].resind == 0); + int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm); + type = localPpResidue->atom[j].type; } return type; } -static int vsite_nm2type(const char *name, PreprocessingAtomTypes *atype) +static int vsite_nm2type(const char* name, PreprocessingAtomTypes* atype) { int tp; tp = atype->atomTypeFromName(name); if (tp == NOTSET) { - gmx_fatal(FARGS, "Dummy mass type (%s) not found in atom type database", - name); + gmx_fatal(FARGS, "Dummy mass type (%s) not found in atom type database", name); } return tp; } -static real get_amass(int atom, t_atoms *at, gmx::ArrayRef rtpFFDB, - ResidueType *rt) +static real get_amass(int atom, t_atoms* at, gmx::ArrayRef rtpFFDB, ResidueType* rt) { - real mass; - bool bNterm; + real mass; + bool bNterm; if (at->atom[atom].m != 0.0F) { @@ -597,29 +620,32 @@ static real get_amass(int atom, t_atoms *at, gmx::ArrayRefresinfo[at->atom[atom].resind].name), rtpFFDB); - bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein") && - (at->atom[atom].resind == 0); - int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm); - mass = localPpResidue->atom[j].m; + auto localPpResidue = getDatabaseEntry(*(at->resinfo[at->atom[atom].resind].name), rtpFFDB); + bNterm = rt->namedResidueHasType(*(at->resinfo[at->atom[atom].resind].name), "Protein") + && (at->atom[atom].resind == 0); + int j = search_jtype(*localPpResidue, *(at->atomname[atom]), bNterm); + mass = localPpResidue->atom[j].m; } return mass; } -static void my_add_param(InteractionsOfType *plist, int ai, int aj, real b) +static void my_add_param(InteractionsOfType* plist, int ai, int aj, real b) { - static real c[MAXFORCEPARAM] = - { NOTSET, NOTSET, NOTSET, NOTSET, NOTSET, NOTSET }; + static real c[MAXFORCEPARAM] = { NOTSET, NOTSET, NOTSET, NOTSET, NOTSET, NOTSET }; c[0] = b; add_param(plist, ai, aj, c, nullptr); } -static void add_vsites(gmx::ArrayRef plist, int vsite_type[], - int Heavy, int nrHatoms, int Hatoms[], - int nrheavies, int heavies[]) +static void add_vsites(gmx::ArrayRef plist, + int vsite_type[], + int Heavy, + int nrHatoms, + int Hatoms[], + int nrheavies, + int heavies[]) { - int other, moreheavy; + int other, moreheavy; for (int i = 0; i < nrHatoms; i++) { @@ -632,14 +658,16 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] { gmx_incons("Undetected error in setting up virtual sites"); } - bool bSwapParity = (ftype < 0); + bool bSwapParity = (ftype < 0); vsite_type[Hatoms[i]] = ftype = abs(ftype); if (ftype == F_BONDS) { - if ( (nrheavies != 1) && (nrHatoms != 1) ) + if ((nrheavies != 1) && (nrHatoms != 1)) { - gmx_fatal(FARGS, "cannot make constraint in add_vsites for %d heavy " - "atoms and %d hydrogen atoms", nrheavies, nrHatoms); + gmx_fatal(FARGS, + "cannot make constraint in add_vsites for %d heavy " + "atoms and %d hydrogen atoms", + nrheavies, nrHatoms); } my_add_param(&(plist[F_CONSTRNC]), Hatoms[i], heavies[0], NOTSET); } @@ -653,11 +681,9 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] if (nrheavies < 2) { gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 3)", - nrheavies+1, - interaction_function[vsite_type[Hatoms[i]]].name); + nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name); } - add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], heavies[1], - bSwapParity); + add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], heavies[1], bSwapParity); break; case F_VSITE3FAD: { @@ -670,7 +696,8 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] /* find more heavy atoms */ other = moreheavy = NOTSET; for (auto parm = plist[F_BONDS].interactionTypes.begin(); - (parm != plist[F_BONDS].interactionTypes.end()) && (moreheavy == NOTSET); parm++) + (parm != plist[F_BONDS].interactionTypes.end()) && (moreheavy == NOTSET); + parm++) { if (parm->ai() == heavies[0]) { @@ -680,18 +707,17 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] { other = parm->ai(); } - if ( (other != NOTSET) && (other != Heavy) ) + if ((other != NOTSET) && (other != Heavy)) { moreheavy = other; } } if (moreheavy == NOTSET) { - gmx_fatal(FARGS, "Unbound molecule part %d-%d", Heavy+1, Hatoms[0]+1); + gmx_fatal(FARGS, "Unbound molecule part %d-%d", Heavy + 1, Hatoms[0] + 1); } } - add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], moreheavy, - bSwapParity); + add_vsite3_atoms(&plist[ftype], Hatoms[i], Heavy, heavies[0], moreheavy, bSwapParity); break; } case F_VSITE4FD: @@ -699,11 +725,9 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] if (nrheavies < 3) { gmx_fatal(FARGS, "Not enough heavy atoms (%d) for %s (min 4)", - nrheavies+1, - interaction_function[vsite_type[Hatoms[i]]].name); + nrheavies + 1, interaction_function[vsite_type[Hatoms[i]]].name); } - add_vsite4_atoms(&plist[ftype], - Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]); + add_vsite4_atoms(&plist[ftype], Hatoms[0], Heavy, heavies[0], heavies[1], heavies[2]); break; default: @@ -714,22 +738,39 @@ static void add_vsites(gmx::ArrayRef plist, int vsite_type[] } /* for i */ } -#define ANGLE_6RING (DEG2RAD*120) +#define ANGLE_6RING (DEG2RAD * 120) /* cosine rule: a^2 = b^2 + c^2 - 2 b c cos(alpha) */ /* get a^2 when a, b and alpha are given: */ -#define cosrule(b, c, alpha) ( gmx::square(b) + gmx::square(c) - 2*(b)*(c)*std::cos(alpha) ) +#define cosrule(b, c, alpha) (gmx::square(b) + gmx::square(c) - 2 * (b) * (c)*std::cos(alpha)) /* get cos(alpha) when a, b and c are given: */ -#define acosrule(a, b, c) ( (gmx::square(b)+gmx::square(c)-gmx::square(a))/(2*(b)*(c)) ) - -static int gen_vsites_6ring(t_atoms *at, int *vsite_type[], gmx::ArrayRef plist, - int nrfound, int *ats, real bond_cc, real bond_ch, - real xcom, bool bDoZ) +#define acosrule(a, b, c) ((gmx::square(b) + gmx::square(c) - gmx::square(a)) / (2 * (b) * (c))) + +static int gen_vsites_6ring(t_atoms* at, + int* vsite_type[], + gmx::ArrayRef plist, + int nrfound, + int* ats, + real bond_cc, + real bond_ch, + real xcom, + bool bDoZ) { /* these MUST correspond to the atnms array in do_vsite_aromatics! */ - enum { - atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, - atCZ, atHZ, atNR + enum + { + atCG, + atCD1, + atHD1, + atCD2, + atHD2, + atCE1, + atHE1, + atCE2, + atHE2, + atCZ, + atHZ, + atNR }; int i, nvsite; @@ -748,7 +789,7 @@ static int gen_vsites_6ring(t_atoms *at, int *vsite_type[], gmx::ArrayRefatom[ats[i]].m; - if (i != atCG && i != atCE1 && i != atCE2 && (bDoZ || (i != atHZ && i != atCZ) ) ) + if (i != atCG && i != atCE1 && i != atCE2 && (bDoZ || (i != atHZ && i != atCZ))) { - at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; - (*vsite_type)[ats[i]] = F_VSITE3; + at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; + (*vsite_type)[ats[i]] = F_VSITE3; nvsite++; } } @@ -770,59 +811,66 @@ static int gen_vsites_6ring(t_atoms *at, int *vsite_type[], gmx::ArrayRefatom[ats[atCG]].m = at->atom[ats[atCG]].mB = xcom*mtot/xCG; - mrest = mtot-mG; - at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = - at->atom[ats[atCE2]].m = at->atom[ats[atCE2]].mB = mrest / 2; + mG = at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = xcom * mtot / xCG; + mrest = mtot - mG; + at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = at->atom[ats[atCE2]].m = + at->atom[ats[atCE2]].mB = mrest / 2; /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */ - tmp1 = dCGCE*std::sin(ANGLE_6RING*0.5); - tmp2 = bond_cc*std::cos(0.5*ANGLE_6RING) + tmp1; + tmp1 = dCGCE * std::sin(ANGLE_6RING * 0.5); + tmp2 = bond_cc * std::cos(0.5 * ANGLE_6RING) + tmp1; tmp1 *= 2; - a = b = -bond_ch / tmp1; + a = b = -bond_ch / tmp1; /* HE1 and HE2: */ - add_vsite3_param(&plist[F_VSITE3], - ats[atHE1], ats[atCE1], ats[atCE2], ats[atCG], a, b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHE2], ats[atCE2], ats[atCE1], ats[atCG], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atHE1], ats[atCE1], ats[atCE2], ats[atCG], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atHE2], ats[atCE2], ats[atCE1], ats[atCG], a, b); /* CD1, CD2 and CZ: */ a = b = tmp2 / tmp1; - add_vsite3_param(&plist[F_VSITE3], - ats[atCD1], ats[atCE2], ats[atCE1], ats[atCG], a, b); - add_vsite3_param(&plist[F_VSITE3], - ats[atCD2], ats[atCE1], ats[atCE2], ats[atCG], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atCD1], ats[atCE2], ats[atCE1], ats[atCG], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atCD2], ats[atCE1], ats[atCE2], ats[atCG], a, b); if (bDoZ) { - add_vsite3_param(&plist[F_VSITE3], - ats[atCZ], ats[atCG], ats[atCE1], ats[atCE2], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atCZ], ats[atCG], ats[atCE1], ats[atCE2], a, b); } /* HD1, HD2 and HZ: */ - a = b = ( bond_ch + tmp2 ) / tmp1; - add_vsite3_param(&plist[F_VSITE3], - ats[atHD1], ats[atCE2], ats[atCE1], ats[atCG], a, b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHD2], ats[atCE1], ats[atCE2], ats[atCG], a, b); + a = b = (bond_ch + tmp2) / tmp1; + add_vsite3_param(&plist[F_VSITE3], ats[atHD1], ats[atCE2], ats[atCE1], ats[atCG], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atHD2], ats[atCE1], ats[atCE2], ats[atCG], a, b); if (bDoZ) { - add_vsite3_param(&plist[F_VSITE3], - ats[atHZ], ats[atCG], ats[atCE1], ats[atCE2], a, b); + add_vsite3_param(&plist[F_VSITE3], ats[atHZ], ats[atCG], ats[atCE1], ats[atCE2], a, b); } return nvsite; } -static int gen_vsites_phe(t_atoms *at, int *vsite_type[], gmx::ArrayRef plist, - int nrfound, int *ats, gmx::ArrayRef vsitetop) +static int gen_vsites_phe(t_atoms* at, + int* vsite_type[], + gmx::ArrayRef plist, + int nrfound, + int* ats, + gmx::ArrayRef vsitetop) { real bond_cc, bond_ch; real xcom, mtot; int i; /* these MUST correspond to the atnms array in do_vsite_aromatics! */ - enum { - atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, - atCZ, atHZ, atNR + enum + { + atCG, + atCD1, + atHD1, + atCD2, + atHD2, + atCE1, + atHE1, + atCE2, + atHE2, + atCZ, + atHZ, + atNR }; real x[atNR]; /* Aromatic rings have 6-fold symmetry, so we only need one bond length. @@ -831,22 +879,22 @@ static int gen_vsites_phe(t_atoms *at, int *vsite_type[], gmx::ArrayRefatom[ats[i]].m; + xcom += x[i] * at->atom[ats[i]].m; mtot += at->atom[ats[i]].m; } xcom /= mtot; @@ -854,48 +902,68 @@ static int gen_vsites_phe(t_atoms *at, int *vsite_type[], gmx::ArrayRef *newx, - t_atom *newatom[], char ***newatomname[], - int *o2n[], int *newvsite_type[], int *newcgnr[], - t_symtab *symtab, int *nadd, - gmx::ArrayRef x, int *cgnr[], - t_atoms *at, int *vsite_type[], - gmx::ArrayRef plist, - int nrfound, int *ats, int add_shift, +static int gen_vsites_trp(PreprocessingAtomTypes* atype, + std::vector* newx, + t_atom* newatom[], + char*** newatomname[], + int* o2n[], + int* newvsite_type[], + int* newcgnr[], + t_symtab* symtab, + int* nadd, + gmx::ArrayRef x, + int* cgnr[], + t_atoms* at, + int* vsite_type[], + gmx::ArrayRef plist, + int nrfound, + int* ats, + int add_shift, gmx::ArrayRef vsitetop) { #define NMASS 2 /* these MUST correspond to the atnms array in do_vsite_aromatics! */ - enum { - atCB, atCG, atCD1, atHD1, atCD2, atNE1, atHE1, atCE2, atCE3, atHE3, - atCZ2, atHZ2, atCZ3, atHZ3, atCH2, atHH2, atNR + enum + { + atCB, + atCG, + atCD1, + atHD1, + atCD2, + atNE1, + atHE1, + atCE2, + atCE3, + atHE3, + atCZ2, + atHZ2, + atCZ3, + atHZ3, + atCH2, + atHH2, + atNR }; /* weights for determining the COM's of both rings (M1 and M2): */ - real mw[NMASS][atNR] = { - { 0, 1, 1, 1, 0.5, 1, 1, 0.5, 0, 0, - 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0.5, 0, 0, 0.5, 1, 1, - 1, 1, 1, 1, 1, 1 } - }; + real mw[NMASS][atNR] = { { 0, 1, 1, 1, 0.5, 1, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0.5, 0, 0, 0.5, 1, 1, 1, 1, 1, 1, 1, 1 } }; real xi[atNR], yi[atNR]; real xcom[NMASS], ycom[NMASS], alpha; @@ -935,21 +1003,21 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, b_CE3_HE3 = get_ddb_bond(vsitetop, "TRP", "CE3", "HE3"); b_CZ3_HZ3 = get_ddb_bond(vsitetop, "TRP", "CZ3", "HZ3"); - a_NE1_CE2_CD2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "NE1", "CE2", "CD2"); - a_CE2_CD2_CG = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CG"); - a_CB_CG_CD2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CB", "CG", "CD2"); - a_CD2_CG_CD1 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CD2", "CG", "CD1"); - - a_CE2_CD2_CE3 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CE3"); - a_CD2_CE2_CZ2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CD2", "CE2", "CZ2"); - a_CD2_CE3_CZ3 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "CZ3"); - a_CE3_CZ3_HZ3 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CE3", "CZ3", "HZ3"); - a_CZ2_CH2_HH2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CZ2", "CH2", "HH2"); - a_CE2_CZ2_HZ2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "HZ2"); - a_CE2_CZ2_CH2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "CH2"); - a_CG_CD1_HD1 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CG", "CD1", "HD1"); - a_HE1_NE1_CE2 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "HE1", "NE1", "CE2"); - a_CD2_CE3_HE3 = DEG2RAD*get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "HE3"); + a_NE1_CE2_CD2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "NE1", "CE2", "CD2"); + a_CE2_CD2_CG = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CG"); + a_CB_CG_CD2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CB", "CG", "CD2"); + a_CD2_CG_CD1 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CG", "CD1"); + + a_CE2_CD2_CE3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CD2", "CE3"); + a_CD2_CE2_CZ2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE2", "CZ2"); + a_CD2_CE3_CZ3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "CZ3"); + a_CE3_CZ3_HZ3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE3", "CZ3", "HZ3"); + a_CZ2_CH2_HH2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CZ2", "CH2", "HH2"); + a_CE2_CZ2_HZ2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "HZ2"); + a_CE2_CZ2_CH2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CE2", "CZ2", "CH2"); + a_CG_CD1_HD1 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CG", "CD1", "HD1"); + a_HE1_NE1_CE2 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "HE1", "NE1", "CE2"); + a_CD2_CE3_HE3 = DEG2RAD * get_ddb_angle(vsitetop, "TRP", "CD2", "CE3", "HE3"); /* Calculate local coordinates. * y-axis (x=0) is the bond CD2-CE2. @@ -957,63 +1025,63 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, * intersects the middle of the bond. */ xi[atCD2] = 0; - yi[atCD2] = -0.5*b_CD2_CE2; + yi[atCD2] = -0.5 * b_CD2_CE2; xi[atCE2] = 0; - yi[atCE2] = 0.5*b_CD2_CE2; + yi[atCE2] = 0.5 * b_CD2_CE2; - xi[atNE1] = -b_NE1_CE2*std::sin(a_NE1_CE2_CD2); - yi[atNE1] = yi[atCE2]-b_NE1_CE2*std::cos(a_NE1_CE2_CD2); + xi[atNE1] = -b_NE1_CE2 * std::sin(a_NE1_CE2_CD2); + yi[atNE1] = yi[atCE2] - b_NE1_CE2 * std::cos(a_NE1_CE2_CD2); - xi[atCG] = -b_CG_CD2*std::sin(a_CE2_CD2_CG); - yi[atCG] = yi[atCD2]+b_CG_CD2*std::cos(a_CE2_CD2_CG); + xi[atCG] = -b_CG_CD2 * std::sin(a_CE2_CD2_CG); + yi[atCG] = yi[atCD2] + b_CG_CD2 * std::cos(a_CE2_CD2_CG); alpha = a_CE2_CD2_CG + M_PI - a_CB_CG_CD2; - xi[atCB] = xi[atCG]-b_CB_CG*std::sin(alpha); - yi[atCB] = yi[atCG]+b_CB_CG*std::cos(alpha); + xi[atCB] = xi[atCG] - b_CB_CG * std::sin(alpha); + yi[atCB] = yi[atCG] + b_CB_CG * std::cos(alpha); alpha = a_CE2_CD2_CG + a_CD2_CG_CD1 - M_PI; - xi[atCD1] = xi[atCG]-b_CG_CD1*std::sin(alpha); - yi[atCD1] = yi[atCG]+b_CG_CD1*std::cos(alpha); + xi[atCD1] = xi[atCG] - b_CG_CD1 * std::sin(alpha); + yi[atCD1] = yi[atCG] + b_CG_CD1 * std::cos(alpha); - xi[atCE3] = b_CD2_CE3*std::sin(a_CE2_CD2_CE3); - yi[atCE3] = yi[atCD2]+b_CD2_CE3*std::cos(a_CE2_CD2_CE3); + xi[atCE3] = b_CD2_CE3 * std::sin(a_CE2_CD2_CE3); + yi[atCE3] = yi[atCD2] + b_CD2_CE3 * std::cos(a_CE2_CD2_CE3); - xi[atCZ2] = b_CE2_CZ2*std::sin(a_CD2_CE2_CZ2); - yi[atCZ2] = yi[atCE2]-b_CE2_CZ2*std::cos(a_CD2_CE2_CZ2); + xi[atCZ2] = b_CE2_CZ2 * std::sin(a_CD2_CE2_CZ2); + yi[atCZ2] = yi[atCE2] - b_CE2_CZ2 * std::cos(a_CD2_CE2_CZ2); alpha = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - M_PI; - xi[atCZ3] = xi[atCE3]+b_CE3_CZ3*std::sin(alpha); - yi[atCZ3] = yi[atCE3]+b_CE3_CZ3*std::cos(alpha); + xi[atCZ3] = xi[atCE3] + b_CE3_CZ3 * std::sin(alpha); + yi[atCZ3] = yi[atCE3] + b_CE3_CZ3 * std::cos(alpha); alpha = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - M_PI; - xi[atCH2] = xi[atCZ2]+b_CZ2_CH2*std::sin(alpha); - yi[atCH2] = yi[atCZ2]-b_CZ2_CH2*std::cos(alpha); + xi[atCH2] = xi[atCZ2] + b_CZ2_CH2 * std::sin(alpha); + yi[atCH2] = yi[atCZ2] - b_CZ2_CH2 * std::cos(alpha); /* hydrogens */ alpha = a_CE2_CD2_CG + a_CD2_CG_CD1 - a_CG_CD1_HD1; - xi[atHD1] = xi[atCD1]-b_CD1_HD1*std::sin(alpha); - yi[atHD1] = yi[atCD1]+b_CD1_HD1*std::cos(alpha); + xi[atHD1] = xi[atCD1] - b_CD1_HD1 * std::sin(alpha); + yi[atHD1] = yi[atCD1] + b_CD1_HD1 * std::cos(alpha); alpha = a_NE1_CE2_CD2 + M_PI - a_HE1_NE1_CE2; - xi[atHE1] = xi[atNE1]-b_NE1_HE1*std::sin(alpha); - yi[atHE1] = yi[atNE1]-b_NE1_HE1*std::cos(alpha); + xi[atHE1] = xi[atNE1] - b_NE1_HE1 * std::sin(alpha); + yi[atHE1] = yi[atNE1] - b_NE1_HE1 * std::cos(alpha); alpha = a_CE2_CD2_CE3 + M_PI - a_CD2_CE3_HE3; - xi[atHE3] = xi[atCE3]+b_CE3_HE3*std::sin(alpha); - yi[atHE3] = yi[atCE3]+b_CE3_HE3*std::cos(alpha); + xi[atHE3] = xi[atCE3] + b_CE3_HE3 * std::sin(alpha); + yi[atHE3] = yi[atCE3] + b_CE3_HE3 * std::cos(alpha); alpha = a_CD2_CE2_CZ2 + M_PI - a_CE2_CZ2_HZ2; - xi[atHZ2] = xi[atCZ2]+b_CZ2_HZ2*std::sin(alpha); - yi[atHZ2] = yi[atCZ2]-b_CZ2_HZ2*std::cos(alpha); + xi[atHZ2] = xi[atCZ2] + b_CZ2_HZ2 * std::sin(alpha); + yi[atHZ2] = yi[atCZ2] - b_CZ2_HZ2 * std::cos(alpha); alpha = a_CD2_CE2_CZ2 + a_CE2_CZ2_CH2 - a_CZ2_CH2_HH2; - xi[atHZ3] = xi[atCZ3]+b_CZ3_HZ3*std::sin(alpha); - yi[atHZ3] = yi[atCZ3]+b_CZ3_HZ3*std::cos(alpha); + xi[atHZ3] = xi[atCZ3] + b_CZ3_HZ3 * std::sin(alpha); + yi[atHZ3] = yi[atCZ3] + b_CZ3_HZ3 * std::cos(alpha); alpha = a_CE2_CD2_CE3 + a_CD2_CE3_CZ3 - a_CE3_CZ3_HZ3; - xi[atHH2] = xi[atCH2]+b_CH2_HH2*std::sin(alpha); - yi[atHH2] = yi[atCH2]-b_CH2_HH2*std::cos(alpha); + xi[atHH2] = xi[atCH2] + b_CH2_HH2 * std::sin(alpha); + yi[atHH2] = yi[atCH2] - b_CH2_HH2 * std::cos(alpha); /* Calculate masses for each ring and put it on the dummy masses */ for (j = 0; j < NMASS; j++) @@ -1026,7 +1094,7 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, { for (j = 0; j < NMASS; j++) { - mM[j] += mw[j][i] * at->atom[ats[i]].m; + mM[j] += mw[j][i] * at->atom[ats[i]].m; xcom[j] += xi[i] * mw[j][i] * at->atom[ats[i]].m; ycom[j] += yi[i] * mw[j][i] * at->atom[ats[i]].m; } @@ -1044,25 +1112,25 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, i0 = ats[atCB]; for (j = 0; j < NMASS; j++) { - atM[j] = i0+*nadd+j; + atM[j] = i0 + *nadd + j; } if (debug) { - fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, (*o2n)[i0]+1); + fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, (*o2n)[i0] + 1); } *nadd += NMASS; for (j = i0; j < at->nr; j++) { - (*o2n)[j] = j+*nadd; + (*o2n)[j] = j + *nadd; } - newx->resize(at->nr+*nadd); - srenew(*newatom, at->nr+*nadd); - srenew(*newatomname, at->nr+*nadd); - srenew(*newvsite_type, at->nr+*nadd); - srenew(*newcgnr, at->nr+*nadd); + newx->resize(at->nr + *nadd); + srenew(*newatom, at->nr + *nadd); + srenew(*newatomname, at->nr + *nadd); + srenew(*newvsite_type, at->nr + *nadd); + srenew(*newcgnr, at->nr + *nadd); for (j = 0; j < NMASS; j++) { - (*newatomname)[at->nr+*nadd-1-j] = nullptr; + (*newatomname)[at->nr + *nadd - 1 - j] = nullptr; } /* Dummy masses will be placed at the center-of-mass in each ring. */ @@ -1074,15 +1142,15 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, */ rvec_sub(x[ats[atCB]], x[ats[atCG]], r_ij); rvec_sub(x[ats[atCD2]], x[ats[atCG]], r_ik); - calc_vsite3_param(xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], - xi[atCD2], yi[atCD2], &a, &b); + calc_vsite3_param(xcom[0], ycom[0], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], + yi[atCD2], &a, &b); svmul(a, r_ij, t1); svmul(b, r_ik, t2); rvec_add(t1, t2, t1); rvec_add(t1, x[ats[atCG]], (*newx)[atM[0]]); - calc_vsite3_param(xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], - xi[atCD2], yi[atCD2], &a, &b); + calc_vsite3_param(xcom[1], ycom[1], xi[atCG], yi[atCG], xi[atCB], yi[atCB], xi[atCD2], + yi[atCD2], &a, &b); svmul(a, r_ij, t1); svmul(b, r_ik, t2); rvec_add(t1, t2, t1); @@ -1091,17 +1159,17 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, /* set parameters for the masses */ for (j = 0; j < NMASS; j++) { - sprintf(name, "MW%d", j+1); - (*newatomname) [atM[j]] = put_symtab(symtab, name); - (*newatom) [atM[j]].m = (*newatom)[atM[j]].mB = mM[j]; - (*newatom) [atM[j]].q = (*newatom)[atM[j]].qB = 0.0; - (*newatom) [atM[j]].type = (*newatom)[atM[j]].typeB = tpM; - (*newatom) [atM[j]].ptype = eptAtom; - (*newatom) [atM[j]].resind = at->atom[i0].resind; - (*newatom) [atM[j]].elem[0] = 'M'; - (*newatom) [atM[j]].elem[1] = '\0'; - (*newvsite_type)[atM[j]] = NOTSET; - (*newcgnr) [atM[j]] = (*cgnr)[i0]; + sprintf(name, "MW%d", j + 1); + (*newatomname)[atM[j]] = put_symtab(symtab, name); + (*newatom)[atM[j]].m = (*newatom)[atM[j]].mB = mM[j]; + (*newatom)[atM[j]].q = (*newatom)[atM[j]].qB = 0.0; + (*newatom)[atM[j]].type = (*newatom)[atM[j]].typeB = tpM; + (*newatom)[atM[j]].ptype = eptAtom; + (*newatom)[atM[j]].resind = at->atom[i0].resind; + (*newatom)[atM[j]].elem[0] = 'M'; + (*newatom)[atM[j]].elem[1] = '\0'; + (*newvsite_type)[atM[j]] = NOTSET; + (*newcgnr)[atM[j]] = (*cgnr)[i0]; } /* renumber cgnr: */ for (i = i0; i < at->nr; i++) @@ -1111,12 +1179,12 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, /* constraints between CB, M1 and M2 */ /* 'add_shift' says which atoms won't be renumbered afterwards */ - dCBM1 = std::hypot( xcom[0]-xi[atCB], ycom[0]-yi[atCB] ); - dM1M2 = std::hypot( xcom[0]-xcom[1], ycom[0]-ycom[1] ); - dCBM2 = std::hypot( xcom[1]-xi[atCB], ycom[1]-yi[atCB] ); - my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift+atM[0], dCBM1); - my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift+atM[1], dCBM2); - my_add_param(&(plist[F_CONSTRNC]), add_shift+atM[0], add_shift+atM[1], dM1M2); + dCBM1 = std::hypot(xcom[0] - xi[atCB], ycom[0] - yi[atCB]); + dM1M2 = std::hypot(xcom[0] - xcom[1], ycom[0] - ycom[1]); + dCBM2 = std::hypot(xcom[1] - xi[atCB], ycom[1] - yi[atCB]); + my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift + atM[0], dCBM1); + my_add_param(&(plist[F_CONSTRNC]), ats[atCB], add_shift + atM[1], dCBM2); + my_add_param(&(plist[F_CONSTRNC]), add_shift + atM[0], add_shift + atM[1], dM1M2); /* rest will be vsite3 */ nvsite = 0; @@ -1124,8 +1192,8 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, { if (i != atCB) { - at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; - (*vsite_type)[ats[i]] = F_VSITE3; + at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; + (*vsite_type)[ats[i]] = F_VSITE3; nvsite++; } } @@ -1134,11 +1202,12 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, r_d = r_M1 + a r_M1_M2 + b r_M1_CB */ for (i = 0; i < atNR; i++) { - if ( (*vsite_type)[ats[i]] == F_VSITE3) + if ((*vsite_type)[ats[i]] == F_VSITE3) { - calc_vsite3_param(xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[i], add_shift+atM[0], add_shift+atM[1], ats[atCB], a, b); + calc_vsite3_param(xi[i], yi[i], xcom[0], ycom[0], xcom[1], ycom[1], xi[atCB], yi[atCB], + &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[i], add_shift + atM[0], add_shift + atM[1], + ats[atCB], a, b); } } return nvsite; @@ -1146,15 +1215,23 @@ static int gen_vsites_trp(PreprocessingAtomTypes *atype, } -static int gen_vsites_tyr(PreprocessingAtomTypes *atype, - std::vector *newx, - t_atom *newatom[], char ***newatomname[], - int *o2n[], int *newvsite_type[], int *newcgnr[], - t_symtab *symtab, int *nadd, - gmx::ArrayRef x, int *cgnr[], - t_atoms *at, int *vsite_type[], - gmx::ArrayRef plist, - int nrfound, int *ats, int add_shift, +static int gen_vsites_tyr(PreprocessingAtomTypes* atype, + std::vector* newx, + t_atom* newatom[], + char*** newatomname[], + int* o2n[], + int* newvsite_type[], + int* newcgnr[], + t_symtab* symtab, + int* nadd, + gmx::ArrayRef x, + int* cgnr[], + t_atoms* at, + int* vsite_type[], + gmx::ArrayRef plist, + int nrfound, + int* ats, + int add_shift, gmx::ArrayRef vsitetop) { int nvsite, i, i0, j, atM, tpM; @@ -1166,9 +1243,21 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, char name[10]; /* these MUST correspond to the atnms array in do_vsite_aromatics! */ - enum { - atCG, atCD1, atHD1, atCD2, atHD2, atCE1, atHE1, atCE2, atHE2, - atCZ, atOH, atHH, atNR + enum + { + atCG, + atCD1, + atHD1, + atCD2, + atHD2, + atCE1, + atHE1, + atCE2, + atHE2, + atCZ, + atOH, + atHH, + atNR }; real xi[atNR]; /* CG, CE1, CE2 (as in general 6-ring) and OH and HH stay, @@ -1186,24 +1275,24 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, bond_ch = get_ddb_bond(vsitetop, "TYR", "CD1", "HD1"); bond_co = get_ddb_bond(vsitetop, "TYR", "CZ", "OH"); bond_oh = get_ddb_bond(vsitetop, "TYR", "OH", "HH"); - angle_coh = DEG2RAD*get_ddb_angle(vsitetop, "TYR", "CZ", "OH", "HH"); + angle_coh = DEG2RAD * get_ddb_angle(vsitetop, "TYR", "CZ", "OH", "HH"); - xi[atCG] = -bond_cc+bond_cc*std::cos(ANGLE_6RING); + xi[atCG] = -bond_cc + bond_cc * std::cos(ANGLE_6RING); xi[atCD1] = -bond_cc; - xi[atHD1] = xi[atCD1]+bond_ch*std::cos(ANGLE_6RING); + xi[atHD1] = xi[atCD1] + bond_ch * std::cos(ANGLE_6RING); xi[atCE1] = 0; - xi[atHE1] = xi[atCE1]-bond_ch*std::cos(ANGLE_6RING); + xi[atHE1] = xi[atCE1] - bond_ch * std::cos(ANGLE_6RING); xi[atCD2] = xi[atCD1]; xi[atHD2] = xi[atHD1]; xi[atCE2] = xi[atCE1]; xi[atHE2] = xi[atHE1]; - xi[atCZ] = bond_cc*std::cos(0.5*ANGLE_6RING); - xi[atOH] = xi[atCZ]+bond_co; + xi[atCZ] = bond_cc * std::cos(0.5 * ANGLE_6RING); + xi[atOH] = xi[atCZ] + bond_co; xcom = mtot = 0; for (i = 0; i < atOH; i++) { - xcom += xi[i]*at->atom[ats[i]].m; + xcom += xi[i] * at->atom[ats[i]].m; mtot += at->atom[ats[i]].m; } xcom /= mtot; @@ -1214,14 +1303,13 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, /* then construct CZ from the 2nd triangle */ /* vsite3 construction: r_d = r_i + a r_ij + b r_ik */ - a = b = 0.5 * bond_co / ( bond_co - bond_cc*std::cos(ANGLE_6RING) ); - add_vsite3_param(&plist[F_VSITE3], - ats[atCZ], ats[atOH], ats[atCE1], ats[atCE2], a, b); + a = b = 0.5 * bond_co / (bond_co - bond_cc * std::cos(ANGLE_6RING)); + add_vsite3_param(&plist[F_VSITE3], ats[atCZ], ats[atOH], ats[atCE1], ats[atCE2], a, b); at->atom[ats[atCZ]].m = at->atom[ats[atCZ]].mB = 0; /* constraints between CE1, CE2 and OH */ - dCGCE = std::sqrt( cosrule(bond_cc, bond_cc, ANGLE_6RING) ); - dCEOH = std::sqrt( cosrule(bond_cc, bond_co, ANGLE_6RING) ); + dCGCE = std::sqrt(cosrule(bond_cc, bond_cc, ANGLE_6RING)); + dCEOH = std::sqrt(cosrule(bond_cc, bond_co, ANGLE_6RING)); my_add_param(&(plist[F_CONSTRNC]), ats[atCE1], ats[atOH], dCEOH); my_add_param(&(plist[F_CONSTRNC]), ats[atCE2], ats[atOH], dCEOH); @@ -1235,32 +1323,32 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, * apply to the HH constructed atom and not directly on the virtual mass. */ - vdist = 2.0*bond_oh; - mM = at->atom[ats[atHH]].m/2.0; - at->atom[ats[atOH]].m += mM; /* add 1/2 of original H mass */ + vdist = 2.0 * bond_oh; + mM = at->atom[ats[atHH]].m / 2.0; + at->atom[ats[atOH]].m += mM; /* add 1/2 of original H mass */ at->atom[ats[atOH]].mB += mM; /* add 1/2 of original H mass */ - at->atom[ats[atHH]].m = at->atom[ats[atHH]].mB = 0; + at->atom[ats[atHH]].m = at->atom[ats[atHH]].mB = 0; /* get dummy mass type */ tpM = vsite_nm2type("MW", atype); /* make space for 1 mass: shift HH only */ i0 = ats[atHH]; - atM = i0+*nadd; + atM = i0 + *nadd; if (debug) { - fprintf(stderr, "Inserting 1 dummy mass at %d\n", (*o2n)[i0]+1); + fprintf(stderr, "Inserting 1 dummy mass at %d\n", (*o2n)[i0] + 1); } (*nadd)++; for (j = i0; j < at->nr; j++) { - (*o2n)[j] = j+*nadd; + (*o2n)[j] = j + *nadd; } - newx->resize(at->nr+*nadd); - srenew(*newatom, at->nr+*nadd); - srenew(*newatomname, at->nr+*nadd); - srenew(*newvsite_type, at->nr+*nadd); - srenew(*newcgnr, at->nr+*nadd); - (*newatomname)[at->nr+*nadd-1] = nullptr; + newx->resize(at->nr + *nadd); + srenew(*newatom, at->nr + *nadd); + srenew(*newatomname, at->nr + *nadd); + srenew(*newvsite_type, at->nr + *nadd); + srenew(*newcgnr, at->nr + *nadd); + (*newatomname)[at->nr + *nadd - 1] = nullptr; /* Calc the dummy mass initial position */ rvec_sub(x[ats[atHH]], x[ats[atOH]], r1); @@ -1268,16 +1356,16 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, rvec_add(r1, x[ats[atHH]], (*newx)[atM]); strcpy(name, "MW1"); - (*newatomname) [atM] = put_symtab(symtab, name); - (*newatom) [atM].m = (*newatom)[atM].mB = mM; - (*newatom) [atM].q = (*newatom)[atM].qB = 0.0; - (*newatom) [atM].type = (*newatom)[atM].typeB = tpM; - (*newatom) [atM].ptype = eptAtom; - (*newatom) [atM].resind = at->atom[i0].resind; - (*newatom) [atM].elem[0] = 'M'; - (*newatom) [atM].elem[1] = '\0'; - (*newvsite_type)[atM] = NOTSET; - (*newcgnr) [atM] = (*cgnr)[i0]; + (*newatomname)[atM] = put_symtab(symtab, name); + (*newatom)[atM].m = (*newatom)[atM].mB = mM; + (*newatom)[atM].q = (*newatom)[atM].qB = 0.0; + (*newatom)[atM].type = (*newatom)[atM].typeB = tpM; + (*newatom)[atM].ptype = eptAtom; + (*newatom)[atM].resind = at->atom[i0].resind; + (*newatom)[atM].elem[0] = 'M'; + (*newatom)[atM].elem[1] = '\0'; + (*newvsite_type)[atM] = NOTSET; + (*newcgnr)[atM] = (*cgnr)[i0]; /* renumber cgnr: */ for (i = i0; i < at->nr; i++) { @@ -1287,19 +1375,21 @@ static int gen_vsites_tyr(PreprocessingAtomTypes *atype, (*vsite_type)[ats[atHH]] = F_VSITE2; nvsite++; /* assume we also want the COH angle constrained: */ - tmp1 = bond_cc*std::cos(0.5*ANGLE_6RING) + dCGCE*std::sin(ANGLE_6RING*0.5) + bond_co; - dCGM = std::sqrt( cosrule(tmp1, vdist, angle_coh) ); - my_add_param(&(plist[F_CONSTRNC]), ats[atCG], add_shift+atM, dCGM); - my_add_param(&(plist[F_CONSTRNC]), ats[atOH], add_shift+atM, vdist); + tmp1 = bond_cc * std::cos(0.5 * ANGLE_6RING) + dCGCE * std::sin(ANGLE_6RING * 0.5) + bond_co; + dCGM = std::sqrt(cosrule(tmp1, vdist, angle_coh)); + my_add_param(&(plist[F_CONSTRNC]), ats[atCG], add_shift + atM, dCGM); + my_add_param(&(plist[F_CONSTRNC]), ats[atOH], add_shift + atM, vdist); - add_vsite2_param(&plist[F_VSITE2], - ats[atHH], ats[atOH], add_shift+atM, 1.0/2.0); + add_vsite2_param(&plist[F_VSITE2], ats[atHH], ats[atOH], add_shift + atM, 1.0 / 2.0); return nvsite; } -static int gen_vsites_his(t_atoms *at, int *vsite_type[], - gmx::ArrayRef plist, - int nrfound, int *ats, gmx::ArrayRef vsitetop) +static int gen_vsites_his(t_atoms* at, + int* vsite_type[], + gmx::ArrayRef plist, + int nrfound, + int* ats, + gmx::ArrayRef vsitetop) { int nvsite, i; real a, b, alpha, dCGCE1, dCGNE2; @@ -1313,8 +1403,18 @@ static int gen_vsites_his(t_atoms *at, int *vsite_type[], char resname[10]; /* these MUST correspond to the atnms array in do_vsite_aromatics! */ - enum { - atCG, atND1, atHD1, atCD2, atHD2, atCE1, atHE1, atNE2, atHE2, atNR + enum + { + atCG, + atND1, + atHD1, + atCD2, + atHD2, + atCE1, + atHE1, + atNE2, + atHE2, + atNR }; real x[atNR], y[atNR]; @@ -1324,14 +1424,14 @@ static int gen_vsites_his(t_atoms *at, int *vsite_type[], /* assert( nrfound >= atNR-3 || nrfound <= atNR ); * Don't understand the above logic. Shouldn't it be && rather than || ??? */ - if ((nrfound < atNR-3) || (nrfound > atNR)) + if ((nrfound < atNR - 3) || (nrfound > atNR)) { gmx_incons("Generating vsites for HIS"); } /* avoid warnings about uninitialized variables */ - b_ND1_HD1 = b_NE2_HE2 = b_CE1_HE1 = b_CD2_HD2 = a_NE2_CE1_HE1 = - a_NE2_CD2_HD2 = a_CE1_ND1_HD1 = a_CE1_NE2_HE2 = 0; + b_ND1_HD1 = b_NE2_HE2 = b_CE1_HE1 = b_CD2_HD2 = a_NE2_CE1_HE1 = a_NE2_CD2_HD2 = a_CE1_ND1_HD1 = + a_CE1_NE2_HE2 = 0; if (ats[atHD1] != NOTSET) { @@ -1355,35 +1455,35 @@ static int gen_vsites_his(t_atoms *at, int *vsite_type[], b_CE1_NE2 = get_ddb_bond(vsitetop, resname, "CE1", "NE2"); b_CG_CD2 = get_ddb_bond(vsitetop, resname, "CG", "CD2"); b_CD2_NE2 = get_ddb_bond(vsitetop, resname, "CD2", "NE2"); - a_CG_ND1_CE1 = DEG2RAD*get_ddb_angle(vsitetop, resname, "CG", "ND1", "CE1"); - a_CG_CD2_NE2 = DEG2RAD*get_ddb_angle(vsitetop, resname, "CG", "CD2", "NE2"); - a_ND1_CE1_NE2 = DEG2RAD*get_ddb_angle(vsitetop, resname, "ND1", "CE1", "NE2"); - a_CE1_NE2_CD2 = DEG2RAD*get_ddb_angle(vsitetop, resname, "CE1", "NE2", "CD2"); + a_CG_ND1_CE1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CG", "ND1", "CE1"); + a_CG_CD2_NE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CG", "CD2", "NE2"); + a_ND1_CE1_NE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "ND1", "CE1", "NE2"); + a_CE1_NE2_CD2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "CD2"); if (ats[atHD1] != NOTSET) { b_ND1_HD1 = get_ddb_bond(vsitetop, resname, "ND1", "HD1"); - a_CE1_ND1_HD1 = DEG2RAD*get_ddb_angle(vsitetop, resname, "CE1", "ND1", "HD1"); + a_CE1_ND1_HD1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "ND1", "HD1"); } if (ats[atHE2] != NOTSET) { b_NE2_HE2 = get_ddb_bond(vsitetop, resname, "NE2", "HE2"); - a_CE1_NE2_HE2 = DEG2RAD*get_ddb_angle(vsitetop, resname, "CE1", "NE2", "HE2"); + a_CE1_NE2_HE2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "CE1", "NE2", "HE2"); } if (ats[atHD2] != NOTSET) { b_CD2_HD2 = get_ddb_bond(vsitetop, resname, "CD2", "HD2"); - a_NE2_CD2_HD2 = DEG2RAD*get_ddb_angle(vsitetop, resname, "NE2", "CD2", "HD2"); + a_NE2_CD2_HD2 = DEG2RAD * get_ddb_angle(vsitetop, resname, "NE2", "CD2", "HD2"); } if (ats[atHE1] != NOTSET) { b_CE1_HE1 = get_ddb_bond(vsitetop, resname, "CE1", "HE1"); - a_NE2_CE1_HE1 = DEG2RAD*get_ddb_angle(vsitetop, resname, "NE2", "CE1", "HE1"); + a_NE2_CE1_HE1 = DEG2RAD * get_ddb_angle(vsitetop, resname, "NE2", "CE1", "HE1"); } /* constraints between CG, CE1 and NE1 */ - dCGCE1 = std::sqrt( cosrule(b_CG_ND1, b_ND1_CE1, a_CG_ND1_CE1) ); - dCGNE2 = std::sqrt( cosrule(b_CG_CD2, b_CD2_NE2, a_CG_CD2_NE2) ); + dCGCE1 = std::sqrt(cosrule(b_CG_ND1, b_ND1_CE1, a_CG_ND1_CE1)); + dCGNE2 = std::sqrt(cosrule(b_CG_CD2, b_CD2_NE2, a_CG_CD2_NE2)); my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atCE1], dCGCE1); my_add_param(&(plist[F_CONSTRNC]), ats[atCG], ats[atNE2], dCGNE2); @@ -1398,71 +1498,71 @@ static int gen_vsites_his(t_atoms *at, int *vsite_type[], */ cosalpha = acosrule(dCGNE2, dCGCE1, b_CE1_NE2); x[atCE1] = 0; - y[atCE1] = cosalpha*dCGCE1; + y[atCE1] = cosalpha * dCGCE1; x[atNE2] = 0; - y[atNE2] = y[atCE1]-b_CE1_NE2; - sinalpha = std::sqrt(1-cosalpha*cosalpha); - x[atCG] = -sinalpha*dCGCE1; + y[atNE2] = y[atCE1] - b_CE1_NE2; + sinalpha = std::sqrt(1 - cosalpha * cosalpha); + x[atCG] = -sinalpha * dCGCE1; y[atCG] = 0; x[atHE1] = x[atHE2] = x[atHD1] = x[atHD2] = 0; y[atHE1] = y[atHE2] = y[atHD1] = y[atHD2] = 0; /* calculate ND1 and CD2 positions from CE1 and NE2 */ - x[atND1] = -b_ND1_CE1*std::sin(a_ND1_CE1_NE2); - y[atND1] = y[atCE1]-b_ND1_CE1*std::cos(a_ND1_CE1_NE2); + x[atND1] = -b_ND1_CE1 * std::sin(a_ND1_CE1_NE2); + y[atND1] = y[atCE1] - b_ND1_CE1 * std::cos(a_ND1_CE1_NE2); - x[atCD2] = -b_CD2_NE2*std::sin(a_CE1_NE2_CD2); - y[atCD2] = y[atNE2]+b_CD2_NE2*std::cos(a_CE1_NE2_CD2); + x[atCD2] = -b_CD2_NE2 * std::sin(a_CE1_NE2_CD2); + y[atCD2] = y[atNE2] + b_CD2_NE2 * std::cos(a_CE1_NE2_CD2); /* And finally the hydrogen positions */ if (ats[atHE1] != NOTSET) { - x[atHE1] = x[atCE1] + b_CE1_HE1*std::sin(a_NE2_CE1_HE1); - y[atHE1] = y[atCE1] - b_CE1_HE1*std::cos(a_NE2_CE1_HE1); + x[atHE1] = x[atCE1] + b_CE1_HE1 * std::sin(a_NE2_CE1_HE1); + y[atHE1] = y[atCE1] - b_CE1_HE1 * std::cos(a_NE2_CE1_HE1); } /* HD2 - first get (ccw) angle from (positive) y-axis */ if (ats[atHD2] != NOTSET) { alpha = a_CE1_NE2_CD2 + M_PI - a_NE2_CD2_HD2; - x[atHD2] = x[atCD2] - b_CD2_HD2*std::sin(alpha); - y[atHD2] = y[atCD2] + b_CD2_HD2*std::cos(alpha); + x[atHD2] = x[atCD2] - b_CD2_HD2 * std::sin(alpha); + y[atHD2] = y[atCD2] + b_CD2_HD2 * std::cos(alpha); } if (ats[atHD1] != NOTSET) { /* HD1 - first get (cw) angle from (positive) y-axis */ alpha = a_ND1_CE1_NE2 + M_PI - a_CE1_ND1_HD1; - x[atHD1] = x[atND1] - b_ND1_HD1*std::sin(alpha); - y[atHD1] = y[atND1] - b_ND1_HD1*std::cos(alpha); + x[atHD1] = x[atND1] - b_ND1_HD1 * std::sin(alpha); + y[atHD1] = y[atND1] - b_ND1_HD1 * std::cos(alpha); } if (ats[atHE2] != NOTSET) { - x[atHE2] = x[atNE2] + b_NE2_HE2*std::sin(a_CE1_NE2_HE2); - y[atHE2] = y[atNE2] + b_NE2_HE2*std::cos(a_CE1_NE2_HE2); + x[atHE2] = x[atNE2] + b_NE2_HE2 * std::sin(a_CE1_NE2_HE2); + y[atHE2] = y[atNE2] + b_NE2_HE2 * std::cos(a_CE1_NE2_HE2); } /* Have all coordinates now */ /* calc center-of-mass; keep atoms CG, CE1, NE2 and * set the rest to vsite3 */ - mtot = xcom = ycom = 0; - nvsite = 0; + mtot = xcom = ycom = 0; + nvsite = 0; for (i = 0; i < atNR; i++) { if (ats[i] != NOTSET) { mtot += at->atom[ats[i]].m; - xcom += x[i]*at->atom[ats[i]].m; - ycom += y[i]*at->atom[ats[i]].m; + xcom += x[i] * at->atom[ats[i]].m; + ycom += y[i] * at->atom[ats[i]].m; if (i != atCG && i != atCE1 && i != atNE2) { - at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; - (*vsite_type)[ats[i]] = F_VSITE3; + at->atom[ats[i]].m = at->atom[ats[i]].mB = 0; + (*vsite_type)[ats[i]] = F_VSITE3; nvsite++; } } } - if (nvsite+3 != nrfound) + if (nvsite + 3 != nrfound) { gmx_incons("Generating vsites for HIS"); } @@ -1471,59 +1571,53 @@ static int gen_vsites_his(t_atoms *at, int *vsite_type[], ycom /= mtot; /* distribute mass so that com stays the same */ - mG = xcom*mtot/x[atCG]; - mrest = mtot-mG; - mCE1 = (ycom-y[atNE2])*mrest/(y[atCE1]-y[atNE2]); - mNE2 = mrest-mCE1; + mG = xcom * mtot / x[atCG]; + mrest = mtot - mG; + mCE1 = (ycom - y[atNE2]) * mrest / (y[atCE1] - y[atNE2]); + mNE2 = mrest - mCE1; - at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = mG; + at->atom[ats[atCG]].m = at->atom[ats[atCG]].mB = mG; at->atom[ats[atCE1]].m = at->atom[ats[atCE1]].mB = mCE1; at->atom[ats[atNE2]].m = at->atom[ats[atNE2]].mB = mNE2; /* HE1 */ if (ats[atHE1] != NOTSET) { - calc_vsite3_param(x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHE1], ats[atCE1], ats[atNE2], ats[atCG], a, b); + calc_vsite3_param(x[atHE1], y[atHE1], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], + y[atCG], &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atHE1], ats[atCE1], ats[atNE2], ats[atCG], a, b); } /* HE2 */ if (ats[atHE2] != NOTSET) { - calc_vsite3_param(x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHE2], ats[atNE2], ats[atCE1], ats[atCG], a, b); + calc_vsite3_param(x[atHE2], y[atHE2], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], + y[atCG], &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atHE2], ats[atNE2], ats[atCE1], ats[atCG], a, b); } /* ND1 */ - calc_vsite3_param(x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atND1], ats[atNE2], ats[atCE1], ats[atCG], a, b); + calc_vsite3_param(x[atND1], y[atND1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], y[atCG], + &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atND1], ats[atNE2], ats[atCE1], ats[atCG], a, b); /* CD2 */ - calc_vsite3_param(x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atCD2], ats[atCE1], ats[atNE2], ats[atCG], a, b); + calc_vsite3_param(x[atCD2], y[atCD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], y[atCG], + &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atCD2], ats[atCE1], ats[atNE2], ats[atCG], a, b); /* HD1 */ if (ats[atHD1] != NOTSET) { - calc_vsite3_param(x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHD1], ats[atNE2], ats[atCE1], ats[atCG], a, b); + calc_vsite3_param(x[atHD1], y[atHD1], x[atNE2], y[atNE2], x[atCE1], y[atCE1], x[atCG], + y[atCG], &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atHD1], ats[atNE2], ats[atCE1], ats[atCG], a, b); } /* HD2 */ if (ats[atHD2] != NOTSET) { - calc_vsite3_param(x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], - x[atCG], y[atCG], &a, &b); - add_vsite3_param(&plist[F_VSITE3], - ats[atHD2], ats[atCE1], ats[atNE2], ats[atCG], a, b); + calc_vsite3_param(x[atHD2], y[atHD2], x[atCE1], y[atCE1], x[atNE2], y[atNE2], x[atCG], + y[atCG], &a, &b); + add_vsite3_param(&plist[F_VSITE3], ats[atHD2], ats[atCE1], ats[atNE2], ats[atCG], a, b); } return nvsite; } @@ -1534,77 +1628,77 @@ static bool is_vsite(int vsite_type) { return FALSE; } - switch (abs(vsite_type) ) + switch (abs(vsite_type)) { case F_VSITE3: case F_VSITE3FD: case F_VSITE3OUT: case F_VSITE3FAD: case F_VSITE4FD: - case F_VSITE4FDN: - return TRUE; - default: - return FALSE; + case F_VSITE4FDN: return TRUE; + default: return FALSE; } } static char atomnamesuffix[] = "1234"; -void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtomTypes *atype, - t_atoms *at, t_symtab *symtab, - std::vector *x, - gmx::ArrayRef plist, int *vsite_type[], int *cgnr[], - real mHmult, bool bVsiteAromatics, - const char *ffdir) +void do_vsites(gmx::ArrayRef rtpFFDB, + PreprocessingAtomTypes* atype, + t_atoms* at, + t_symtab* symtab, + std::vector* x, + gmx::ArrayRef plist, + int* vsite_type[], + int* cgnr[], + real mHmult, + bool bVsiteAromatics, + const char* ffdir) { #define MAXATOMSPERRESIDUE 16 - int k, m, i0, ni0, whatres, add_shift, nvsite, nadd; - int ai, aj, ak, al; - int nrfound = 0, needed, nrbonds, nrHatoms, Heavy, nrheavies, tpM, tpHeavy; - int Hatoms[4], heavies[4]; - bool bWARNING, bAddVsiteParam, bFirstWater; - matrix tmpmat; - real mHtot, mtot, fact, fact2; - rvec rpar, rperp, temp; - char tpname[32], nexttpname[32]; - int *o2n, *newvsite_type, *newcgnr, ats[MAXATOMSPERRESIDUE]; - t_atom *newatom; - char ***newatomname; - int cmplength; - bool isN, planarN, bFound; + int k, m, i0, ni0, whatres, add_shift, nvsite, nadd; + int ai, aj, ak, al; + int nrfound = 0, needed, nrbonds, nrHatoms, Heavy, nrheavies, tpM, tpHeavy; + int Hatoms[4], heavies[4]; + bool bWARNING, bAddVsiteParam, bFirstWater; + matrix tmpmat; + real mHtot, mtot, fact, fact2; + rvec rpar, rperp, temp; + char tpname[32], nexttpname[32]; + int * o2n, *newvsite_type, *newcgnr, ats[MAXATOMSPERRESIDUE]; + t_atom* newatom; + char*** newatomname; + int cmplength; + bool isN, planarN, bFound; /* if bVsiteAromatics=TRUE do_vsites will specifically convert atoms in PHE, TRP, TYR and HIS to a construction of virtual sites */ - enum { - resPHE, resTRP, resTYR, resHIS, resNR + enum + { + resPHE, + resTRP, + resTYR, + resHIS, + resNR }; - const char *resnms[resNR] = { "PHE", "TRP", "TYR", "HIS" }; + const char* resnms[resNR] = { "PHE", "TRP", "TYR", "HIS" }; /* Amber03 alternative names for termini */ - const char *resnmsN[resNR] = { "NPHE", "NTRP", "NTYR", "NHIS" }; - const char *resnmsC[resNR] = { "CPHE", "CTRP", "CTYR", "CHIS" }; + const char* resnmsN[resNR] = { "NPHE", "NTRP", "NTYR", "NHIS" }; + const char* resnmsC[resNR] = { "CPHE", "CTRP", "CTYR", "CHIS" }; /* HIS can be known as HISH, HIS1, HISA, HID, HIE, HIP, etc. too */ - bool bPartial[resNR] = { FALSE, FALSE, FALSE, TRUE }; + bool bPartial[resNR] = { FALSE, FALSE, FALSE, TRUE }; /* the atnms for every residue MUST correspond to the enums in the gen_vsites_* (one for each residue) routines! */ /* also the atom names in atnms MUST be in the same order as in the .rtp! */ - const char *atnms[resNR][MAXATOMSPERRESIDUE+1] = { + const char* atnms[resNR][MAXATOMSPERRESIDUE + 1] = { { "CG", /* PHE */ - "CD1", "HD1", "CD2", "HD2", - "CE1", "HE1", "CE2", "HE2", - "CZ", "HZ", nullptr }, + "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "HZ", nullptr }, { "CB", /* TRP */ - "CG", - "CD1", "HD1", "CD2", - "NE1", "HE1", "CE2", "CE3", "HE3", - "CZ2", "HZ2", "CZ3", "HZ3", + "CG", "CD1", "HD1", "CD2", "NE1", "HE1", "CE2", "CE3", "HE3", "CZ2", "HZ2", "CZ3", "HZ3", "CH2", "HH2", nullptr }, { "CG", /* TYR */ - "CD1", "HD1", "CD2", "HD2", - "CE1", "HE1", "CE2", "HE2", - "CZ", "OH", "HH", nullptr }, + "CD1", "HD1", "CD2", "HD2", "CE1", "HE1", "CE2", "HE2", "CZ", "OH", "HH", nullptr }, { "CG", /* HIS */ - "ND1", "HD1", "CD2", "HD2", - "CE1", "HE1", "NE2", "HE2", nullptr } + "ND1", "HD1", "CD2", "HD2", "CE1", "HE1", "NE2", "HE2", nullptr } }; if (debug) @@ -1631,7 +1725,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom * force field (rings can be strained). */ std::vector vsitetop; - for (const auto &filename : db) + for (const auto& filename : db) { read_vsite_database(filename.c_str(), &vsiteconflist, &vsitetop); } @@ -1640,7 +1734,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom nvsite = 0; nadd = 0; /* we need a marker for which atoms should *not* be renumbered afterwards */ - add_shift = 10*at->nr; + add_shift = 10 * at->nr; /* make arrays where masses can be inserted into */ std::vector newx(at->nr); snew(newatom, at->nr); @@ -1656,7 +1750,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* make index to tell which residues were already processed */ std::vector bResProcessed(at->nres); - ResidueType rt; + ResidueType rt; /* generate vsite constructions */ /* loop over all atoms */ @@ -1667,17 +1761,15 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom { resind = at->atom[i].resind; } - const char *resnm = *(at->resinfo[resind].name); + const char* resnm = *(at->resinfo[resind].name); /* first check for aromatics to virtualize */ /* don't waste our effort on DNA, water etc. */ /* Only do the vsite aromatic stuff when we reach the * CA atom, since there might be an X2/X3 group on the * N-terminus that must be treated first. */ - if (bVsiteAromatics && - (strcmp(*(at->atomname[i]), "CA") == 0) && - !bResProcessed[resind] && - rt.namedResidueHasType(*(at->resinfo[resind].name), "Protein") ) + if (bVsiteAromatics && (strcmp(*(at->atomname[i]), "CA") == 0) && !bResProcessed[resind] + && rt.namedResidueHasType(*(at->resinfo[resind].name), "Protein")) { /* mark this residue */ bResProcessed[resind] = TRUE; @@ -1686,11 +1778,11 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom for (int j = 0; j < resNR && whatres == NOTSET; j++) { - cmplength = bPartial[j] ? strlen(resnm)-1 : strlen(resnm); + cmplength = bPartial[j] ? strlen(resnm) - 1 : strlen(resnm); - bFound = ((gmx::equalCaseInsensitive(resnm, resnms[j], cmplength)) || - (gmx::equalCaseInsensitive(resnm, resnmsN[j], cmplength)) || - (gmx::equalCaseInsensitive(resnm, resnmsC[j], cmplength))); + bFound = ((gmx::equalCaseInsensitive(resnm, resnms[j], cmplength)) + || (gmx::equalCaseInsensitive(resnm, resnmsN[j], cmplength)) + || (gmx::equalCaseInsensitive(resnm, resnmsC[j], cmplength))); if (bFound) { @@ -1713,7 +1805,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* now k is number of atom names in atnms[j] */ if (j == resHIS) { - needed = k-3; + needed = k - 3; } else { @@ -1721,7 +1813,8 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom } if (nrfound < needed) { - gmx_fatal(FARGS, "not enough atoms found (%d, need %d) in " + gmx_fatal(FARGS, + "not enough atoms found (%d, need %d) in " "residue %s %d while\n " "generating aromatics virtual site construction", nrfound, needed, resnm, at->resinfo[resind].nr); @@ -1736,44 +1829,42 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom case resPHE: if (debug) { - fprintf(stderr, "PHE at %d\n", o2n[ats[0]]+1); + fprintf(stderr, "PHE at %d\n", o2n[ats[0]] + 1); } nvsite += gen_vsites_phe(at, vsite_type, plist, nrfound, ats, vsitetop); break; case resTRP: if (debug) { - fprintf(stderr, "TRP at %d\n", o2n[ats[0]]+1); + fprintf(stderr, "TRP at %d\n", o2n[ats[0]] + 1); } nvsite += gen_vsites_trp(atype, &newx, &newatom, &newatomname, &o2n, - &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, - at, vsite_type, plist, nrfound, ats, add_shift, vsitetop); + &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at, + vsite_type, plist, nrfound, ats, add_shift, vsitetop); break; case resTYR: if (debug) { - fprintf(stderr, "TYR at %d\n", o2n[ats[0]]+1); + fprintf(stderr, "TYR at %d\n", o2n[ats[0]] + 1); } nvsite += gen_vsites_tyr(atype, &newx, &newatom, &newatomname, &o2n, - &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, - at, vsite_type, plist, nrfound, ats, add_shift, vsitetop); + &newvsite_type, &newcgnr, symtab, &nadd, *x, cgnr, at, + vsite_type, plist, nrfound, ats, add_shift, vsitetop); break; case resHIS: if (debug) { - fprintf(stderr, "HIS at %d\n", o2n[ats[0]]+1); + fprintf(stderr, "HIS at %d\n", o2n[ats[0]] + 1); } nvsite += gen_vsites_his(at, vsite_type, plist, nrfound, ats, vsitetop); break; case NOTSET: /* this means this residue won't be processed */ break; - default: - gmx_fatal(FARGS, "DEATH HORROR in do_vsites (%s:%d)", - __FILE__, __LINE__); + default: gmx_fatal(FARGS, "DEATH HORROR in do_vsites (%s:%d)", __FILE__, __LINE__); } /* switch whatres */ /* skip back to beginning of residue */ - while (i > 0 && at->atom[i-1].resind == resind) + while (i > 0 && at->atom[i - 1].resind == resind) { i--; } @@ -1781,12 +1872,12 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* now process the rest of the hydrogens */ /* only process hydrogen atoms which are not already set */ - if ( ((*vsite_type)[i] == NOTSET) && is_hydrogen(*(at->atomname[i]))) + if (((*vsite_type)[i] == NOTSET) && is_hydrogen(*(at->atomname[i]))) { /* find heavy atom, count #bonds from it and #H atoms bound to it and return H atom numbers (Hatoms) and heavy atom numbers (heavies) */ - count_bonds(i, &plist[F_BONDS], at->atomname, - &nrbonds, &nrHatoms, Hatoms, &Heavy, &nrheavies, heavies); + count_bonds(i, &plist[F_BONDS], at->atomname, &nrbonds, &nrHatoms, Hatoms, &Heavy, + &nrheavies, heavies); /* get Heavy atom type */ tpHeavy = get_atype(Heavy, at, rtpFFDB, &rt); strcpy(tpname, atype->atomNameFromAtomType(tpHeavy)); @@ -1798,12 +1889,8 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom { switch (nrbonds) { - case 2: /* -O-H */ - (*vsite_type)[i] = F_BONDS; - break; - case 3: /* =CH-, -NH- or =NH+- */ - (*vsite_type)[i] = F_VSITE3FD; - break; + case 2: /* -O-H */ (*vsite_type)[i] = F_BONDS; break; + case 3: /* =CH-, -NH- or =NH+- */ (*vsite_type)[i] = F_VSITE3FD; break; case 4: /* --CH- (tert) */ /* The old type 4FD had stability issues, so * all new constructs should use 4FDN @@ -1827,13 +1914,10 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom } break; - default: /* nrbonds != 2, 3 or 4 */ - bWARNING = TRUE; + default: /* nrbonds != 2, 3 or 4 */ bWARNING = TRUE; } - } - else if ( (nrHatoms == 2) && (nrbonds == 2) && - (at->atom[Heavy].atomnumber == 8) ) + else if ((nrHatoms == 2) && (nrbonds == 2) && (at->atom[Heavy].atomnumber == 8)) { bAddVsiteParam = FALSE; /* this is water: skip these hydrogens */ if (bFirstWater) @@ -1841,12 +1925,11 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom bFirstWater = FALSE; if (debug) { - fprintf(debug, - "Not converting hydrogens in water to virtual sites\n"); + fprintf(debug, "Not converting hydrogens in water to virtual sites\n"); } } } - else if ( (nrHatoms == 2) && (nrbonds == 4) ) + else if ((nrHatoms == 2) && (nrbonds == 4)) { /* -CH2- , -NH2+- */ (*vsite_type)[Hatoms[0]] = F_VSITE3OUT; @@ -1860,53 +1943,60 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom isN = planarN = FALSE; if ((nrHatoms == 2) && ((*at->atomname[Heavy])[0] == 'N')) { - isN = TRUE; - int j = nitrogen_is_planar(vsiteconflist, tpname); + isN = TRUE; + int j = nitrogen_is_planar(vsiteconflist, tpname); if (j < 0) { gmx_fatal(FARGS, "No vsite database NH2 entry for type %s\n", tpname); } planarN = (j == 1); } - if ( (nrHatoms == 2) && (nrbonds == 3) && ( !isN || planarN ) ) + if ((nrHatoms == 2) && (nrbonds == 3) && (!isN || planarN)) { /* =CH2 or, if it is a nitrogen NH2, it is a planar one */ (*vsite_type)[Hatoms[0]] = F_VSITE3FAD; (*vsite_type)[Hatoms[1]] = -F_VSITE3FAD; } - else if ( ( (nrHatoms == 2) && (nrbonds == 3) && - ( isN && !planarN ) ) || - ( (nrHatoms == 3) && (nrbonds == 4) ) ) + else if (((nrHatoms == 2) && (nrbonds == 3) && (isN && !planarN)) + || ((nrHatoms == 3) && (nrbonds == 4))) { /* CH3, NH3 or non-planar NH2 group */ - int Hat_vsite_type[3] = { F_VSITE3, F_VSITE3OUT, F_VSITE3OUT }; - bool Hat_SwapParity[3] = { FALSE, TRUE, FALSE }; + int Hat_vsite_type[3] = { F_VSITE3, F_VSITE3OUT, F_VSITE3OUT }; + bool Hat_SwapParity[3] = { FALSE, TRUE, FALSE }; if (debug) { - fprintf(stderr, "-XH3 or nonplanar NH2 group at %d\n", i+1); + fprintf(stderr, "-XH3 or nonplanar NH2 group at %d\n", i + 1); } bAddVsiteParam = FALSE; /* we'll do this ourselves! */ /* -NH2 (umbrella), -NH3+ or -CH3 */ - (*vsite_type)[Heavy] = F_VSITE3; + (*vsite_type)[Heavy] = F_VSITE3; for (int j = 0; j < nrHatoms; j++) { (*vsite_type)[Hatoms[j]] = Hat_vsite_type[j]; } /* get dummy mass type from first char of heavy atom type (N or C) */ - strcpy(nexttpname, atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, &rt))); + strcpy(nexttpname, + atype->atomNameFromAtomType(get_atype(heavies[0], at, rtpFFDB, &rt))); std::string ch = get_dummymass_name(vsiteconflist, tpname, nexttpname); std::string name; if (ch.empty()) { if (!db.empty()) { - gmx_fatal(FARGS, "Can't find dummy mass for type %s bonded to type %s in the virtual site database (.vsd files). Add it to the database!\n", tpname, nexttpname); + gmx_fatal( + FARGS, + "Can't find dummy mass for type %s bonded to type %s in the " + "virtual site database (.vsd files). Add it to the database!\n", + tpname, nexttpname); } else { - gmx_fatal(FARGS, "A dummy mass for type %s bonded to type %s is required, but no virtual site database (.vsd) files where found.\n", tpname, nexttpname); + gmx_fatal(FARGS, + "A dummy mass for type %s bonded to type %s is required, but " + "no virtual site database (.vsd) files where found.\n", + tpname, nexttpname); } } else @@ -1918,26 +2008,26 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* make space for 2 masses: shift all atoms starting with 'Heavy' */ #define NMASS 2 i0 = Heavy; - ni0 = i0+nadd; + ni0 = i0 + nadd; if (debug) { - fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, o2n[i0]+1); + fprintf(stderr, "Inserting %d dummy masses at %d\n", NMASS, o2n[i0] + 1); } nadd += NMASS; for (int j = i0; j < at->nr; j++) { - o2n[j] = j+nadd; + o2n[j] = j + nadd; } - newx.resize(at->nr+nadd); - srenew(newatom, at->nr+nadd); - srenew(newatomname, at->nr+nadd); - srenew(newvsite_type, at->nr+nadd); - srenew(newcgnr, at->nr+nadd); + newx.resize(at->nr + nadd); + srenew(newatom, at->nr + nadd); + srenew(newatomname, at->nr + nadd); + srenew(newvsite_type, at->nr + nadd); + srenew(newcgnr, at->nr + nadd); for (int j = 0; j < NMASS; j++) { - newatomname[at->nr+nadd-1-j] = nullptr; + newatomname[at->nr + nadd - 1 - j] = nullptr; } /* calculate starting position for the masses */ @@ -1945,7 +2035,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* get atom masses, and set Heavy and Hatoms mass to zero */ for (int j = 0; j < nrHatoms; j++) { - mHtot += get_amass(Hatoms[j], at, rtpFFDB, &rt); + mHtot += get_amass(Hatoms[j], at, rtpFFDB, &rt); at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0; } mtot = mHtot + get_amass(Heavy, at, rtpFFDB, &rt); @@ -1954,7 +2044,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom { mHtot *= mHmult; } - fact2 = mHtot/mtot; + fact2 = mHtot / mtot; fact = std::sqrt(fact2); /* generate vectors parallel and perpendicular to rotational axis: * rpar = Heavy -> Hcom @@ -1964,58 +2054,56 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom { rvec_inc(rpar, (*x)[Hatoms[j]]); } - svmul(1.0/nrHatoms, rpar, rpar); /* rpar = ( H1+H2+H3 ) / 3 */ - rvec_dec(rpar, (*x)[Heavy]); /* - Heavy */ + svmul(1.0 / nrHatoms, rpar, rpar); /* rpar = ( H1+H2+H3 ) / 3 */ + rvec_dec(rpar, (*x)[Heavy]); /* - Heavy */ rvec_sub((*x)[Hatoms[0]], (*x)[Heavy], rperp); - rvec_dec(rperp, rpar); /* rperp = H1 - Heavy - rpar */ + rvec_dec(rperp, rpar); /* rperp = H1 - Heavy - rpar */ /* calc mass positions */ svmul(fact2, rpar, temp); for (int j = 0; (j < NMASS); j++) /* xM = xN + fact2 * rpar +/- fact * rperp */ { - rvec_add((*x)[Heavy], temp, newx[ni0+j]); + rvec_add((*x)[Heavy], temp, newx[ni0 + j]); } svmul(fact, rperp, temp); - rvec_inc(newx[ni0 ], temp); - rvec_dec(newx[ni0+1], temp); + rvec_inc(newx[ni0], temp); + rvec_dec(newx[ni0 + 1], temp); /* set atom parameters for the masses */ for (int j = 0; (j < NMASS); j++) { /* make name: "M??#" or "M?#" (? is atomname, # is number) */ name[0] = 'M'; int k; - for (k = 0; (*at->atomname[Heavy])[k] && ( k < NMASS ); k++) + for (k = 0; (*at->atomname[Heavy])[k] && (k < NMASS); k++) { - name[k+1] = (*at->atomname[Heavy])[k]; + name[k + 1] = (*at->atomname[Heavy])[k]; } - name[k+1] = atomnamesuffix[j]; - name[k+2] = '\0'; - newatomname[ni0+j] = put_symtab(symtab, name.c_str()); - newatom[ni0+j].m = newatom[ni0+j].mB = mtot/NMASS; - newatom[ni0+j].q = newatom[ni0+j].qB = 0.0; - newatom[ni0+j].type = newatom[ni0+j].typeB = tpM; - newatom[ni0+j].ptype = eptAtom; - newatom[ni0+j].resind = at->atom[i0].resind; - newatom[ni0+j].elem[0] = 'M'; - newatom[ni0+j].elem[1] = '\0'; - newvsite_type[ni0+j] = NOTSET; - newcgnr[ni0+j] = (*cgnr)[i0]; + name[k + 1] = atomnamesuffix[j]; + name[k + 2] = '\0'; + newatomname[ni0 + j] = put_symtab(symtab, name.c_str()); + newatom[ni0 + j].m = newatom[ni0 + j].mB = mtot / NMASS; + newatom[ni0 + j].q = newatom[ni0 + j].qB = 0.0; + newatom[ni0 + j].type = newatom[ni0 + j].typeB = tpM; + newatom[ni0 + j].ptype = eptAtom; + newatom[ni0 + j].resind = at->atom[i0].resind; + newatom[ni0 + j].elem[0] = 'M'; + newatom[ni0 + j].elem[1] = '\0'; + newvsite_type[ni0 + j] = NOTSET; + newcgnr[ni0 + j] = (*cgnr)[i0]; } /* add constraints between dummy masses and to heavies[0] */ /* 'add_shift' says which atoms won't be renumbered afterwards */ - my_add_param(&(plist[F_CONSTRNC]), heavies[0], add_shift+ni0, NOTSET); - my_add_param(&(plist[F_CONSTRNC]), heavies[0], add_shift+ni0+1, NOTSET); - my_add_param(&(plist[F_CONSTRNC]), add_shift+ni0, add_shift+ni0+1, NOTSET); + my_add_param(&(plist[F_CONSTRNC]), heavies[0], add_shift + ni0, NOTSET); + my_add_param(&(plist[F_CONSTRNC]), heavies[0], add_shift + ni0 + 1, NOTSET); + my_add_param(&(plist[F_CONSTRNC]), add_shift + ni0, add_shift + ni0 + 1, NOTSET); /* generate Heavy, H1, H2 and H3 from M1, M2 and heavies[0] */ /* note that vsite_type cannot be NOTSET, because we just set it */ - add_vsite3_atoms (&plist[(*vsite_type)[Heavy]], - Heavy, heavies[0], add_shift+ni0, add_shift+ni0+1, - FALSE); + add_vsite3_atoms(&plist[(*vsite_type)[Heavy]], Heavy, heavies[0], + add_shift + ni0, add_shift + ni0 + 1, FALSE); for (int j = 0; j < nrHatoms; j++) { - add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]], - Hatoms[j], heavies[0], add_shift+ni0, add_shift+ni0+1, - Hat_SwapParity[j]); + add_vsite3_atoms(&plist[(*vsite_type)[Hatoms[j]]], Hatoms[j], heavies[0], + add_shift + ni0, add_shift + ni0 + 1, Hat_SwapParity[j]); } #undef NMASS } @@ -2023,27 +2111,26 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom { bWARNING = TRUE; } - } if (bWARNING) { - gmx_fatal(FARGS, "Cannot convert atom %d %s (bound to a heavy atom " + gmx_fatal(FARGS, + "Cannot convert atom %d %s (bound to a heavy atom " "%s with \n" " %d bonds and %d bound hydrogens atoms) to virtual site\n", - i+1, *(at->atomname[i]), tpname, nrbonds, nrHatoms); + i + 1, *(at->atomname[i]), tpname, nrbonds, nrHatoms); } if (bAddVsiteParam) { /* add vsite parameters to topology, also get rid of negative vsite_types */ - add_vsites(plist, (*vsite_type), Heavy, nrHatoms, Hatoms, - nrheavies, heavies); + add_vsites(plist, (*vsite_type), Heavy, nrHatoms, Hatoms, nrheavies, heavies); /* transfer mass of virtual site to Heavy atom */ for (int j = 0; j < nrHatoms; j++) { if (is_vsite((*vsite_type)[Hatoms[j]])) { - at->atom[Heavy].m += at->atom[Hatoms[j]].m; + at->atom[Heavy].m += at->atom[Hatoms[j]].m; at->atom[Heavy].mB = at->atom[Heavy].m; at->atom[Hatoms[j]].m = at->atom[Hatoms[j]].mB = 0; } @@ -2052,37 +2139,33 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom nvsite += nrHatoms; if (debug) { - fprintf(debug, "atom %d: ", o2n[i]+1); + fprintf(debug, "atom %d: ", o2n[i] + 1); print_bonds(debug, o2n, nrHatoms, Hatoms, Heavy, nrheavies, heavies); } } /* if vsite NOTSET & is hydrogen */ - } /* for i < at->nr */ + } /* for i < at->nr */ if (debug) { fprintf(debug, "Before inserting new atoms:\n"); for (int i = 0; i < at->nr; i++) { - fprintf(debug, "%4d %4d %4s %4d %4s %6d %-10s\n", i+1, o2n[i]+1, - at->atomname[i] ? *(at->atomname[i]) : "(NULL)", - at->resinfo[at->atom[i].resind].nr, - at->resinfo[at->atom[i].resind].name ? - *(at->resinfo[at->atom[i].resind].name) : "(NULL)", + fprintf(debug, "%4d %4d %4s %4d %4s %6d %-10s\n", i + 1, o2n[i] + 1, + at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr, + at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)", (*cgnr)[i], - ((*vsite_type)[i] == NOTSET) ? - "NOTSET" : interaction_function[(*vsite_type)[i]].name); + ((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name); } fprintf(debug, "new atoms to be inserted:\n"); - for (int i = 0; i < at->nr+nadd; i++) + for (int i = 0; i < at->nr + nadd; i++) { if (newatomname[i]) { - fprintf(debug, "%4d %4s %4d %6d %-10s\n", i+1, - newatomname[i] ? *(newatomname[i]) : "(NULL)", - newatom[i].resind, newcgnr[i], - (newvsite_type[i] == NOTSET) ? - "NOTSET" : interaction_function[newvsite_type[i]].name); + fprintf(debug, "%4d %4s %4d %6d %-10s\n", i + 1, + newatomname[i] ? *(newatomname[i]) : "(NULL)", newatom[i].resind, newcgnr[i], + (newvsite_type[i] == NOTSET) ? "NOTSET" + : interaction_function[newvsite_type[i]].name); } } } @@ -2090,10 +2173,10 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom /* add all original atoms to the new arrays, using o2n index array */ for (int i = 0; i < at->nr; i++) { - newatomname [o2n[i]] = at->atomname [i]; - newatom [o2n[i]] = at->atom [i]; + newatomname[o2n[i]] = at->atomname[i]; + newatom[o2n[i]] = at->atom[i]; newvsite_type[o2n[i]] = (*vsite_type)[i]; - newcgnr [o2n[i]] = (*cgnr) [i]; + newcgnr[o2n[i]] = (*cgnr)[i]; copy_rvec((*x)[i], newx[o2n[i]]); } /* throw away old atoms */ @@ -2102,7 +2185,7 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom sfree(*vsite_type); sfree(*cgnr); /* put in the new ones */ - at->nr += nadd; + at->nr += nadd; at->atom = newatom; at->atomname = newatomname; *vsite_type = newvsite_type; @@ -2110,8 +2193,10 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom *x = newx; if (at->nr > add_shift) { - gmx_fatal(FARGS, "Added impossible amount of dummy masses " - "(%d on a total of %d atoms)\n", nadd, at->nr-nadd); + gmx_fatal(FARGS, + "Added impossible amount of dummy masses " + "(%d on a total of %d atoms)\n", + nadd, at->nr - nadd); } if (debug) @@ -2119,48 +2204,42 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom fprintf(debug, "After inserting new atoms:\n"); for (int i = 0; i < at->nr; i++) { - fprintf(debug, "%4d %4s %4d %4s %6d %-10s\n", i+1, - at->atomname[i] ? *(at->atomname[i]) : "(NULL)", - at->resinfo[at->atom[i].resind].nr, - at->resinfo[at->atom[i].resind].name ? - *(at->resinfo[at->atom[i].resind].name) : "(NULL)", + fprintf(debug, "%4d %4s %4d %4s %6d %-10s\n", i + 1, + at->atomname[i] ? *(at->atomname[i]) : "(NULL)", at->resinfo[at->atom[i].resind].nr, + at->resinfo[at->atom[i].resind].name ? *(at->resinfo[at->atom[i].resind].name) : "(NULL)", (*cgnr)[i], - ((*vsite_type)[i] == NOTSET) ? - "NOTSET" : interaction_function[(*vsite_type)[i]].name); + ((*vsite_type)[i] == NOTSET) ? "NOTSET" : interaction_function[(*vsite_type)[i]].name); } } /* now renumber all the interactions because of the added atoms */ for (int ftype = 0; ftype < F_NRE; ftype++) { - InteractionsOfType *params = &(plist[ftype]); + InteractionsOfType* params = &(plist[ftype]); if (debug) { - fprintf(debug, "Renumbering %zu %s\n", params->size(), - interaction_function[ftype].longname); + fprintf(debug, "Renumbering %zu %s\n", params->size(), interaction_function[ftype].longname); } /* Horrible hacks needed here to get this to work */ for (auto parm = params->interactionTypes.begin(); parm != params->interactionTypes.end(); parm++) { gmx::ArrayRef atomNumbers(parm->atoms()); - std::vector newAtomNumber; + std::vector newAtomNumber; for (int j = 0; j < NRAL(ftype); j++) { if (atomNumbers[j] >= add_shift) { if (debug) { - fprintf(debug, " [%d -> %d]", atomNumbers[j], - atomNumbers[j]-add_shift); + fprintf(debug, " [%d -> %d]", atomNumbers[j], atomNumbers[j] - add_shift); } - newAtomNumber.emplace_back(atomNumbers[j]-add_shift); + newAtomNumber.emplace_back(atomNumbers[j] - add_shift); } else { if (debug) { - fprintf(debug, " [%d -> %d]", atomNumbers[j], - o2n[atomNumbers[j]]); + fprintf(debug, " [%d -> %d]", atomNumbers[j], o2n[atomNumbers[j]]); } newAtomNumber.emplace_back(o2n[atomNumbers[j]]); } @@ -2173,8 +2252,8 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom } } /* sort constraint parameters */ - InteractionsOfType *params = &(plist[F_CONSTRNC]); - for (auto &type : params->interactionTypes) + InteractionsOfType* params = &(plist[F_CONSTRNC]); + for (auto& type : params->interactionTypes) { type.sortAtomIds(); } @@ -2188,45 +2267,42 @@ void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtom fprintf(stderr, "Added %zu new constraints\n", plist[F_CONSTRNC].size()); } -void do_h_mass(InteractionsOfType *psb, int vsite_type[], t_atoms *at, real mHmult, - bool bDeuterate) +void do_h_mass(InteractionsOfType* psb, int vsite_type[], t_atoms* at, real mHmult, bool bDeuterate) { /* loop over all atoms */ for (int i = 0; i < at->nr; i++) { /* adjust masses if i is hydrogen and not a virtual site */ - if (!is_vsite(vsite_type[i]) && is_hydrogen(*(at->atomname[i])) ) + if (!is_vsite(vsite_type[i]) && is_hydrogen(*(at->atomname[i]))) { /* find bonded heavy atom */ int a = NOTSET; - for (auto parm = psb->interactionTypes.begin(); (parm != psb->interactionTypes.end()) && (a == NOTSET); parm++) + for (auto parm = psb->interactionTypes.begin(); + (parm != psb->interactionTypes.end()) && (a == NOTSET); parm++) { /* if other atom is not a virtual site, it is the one we want */ - if ( (parm->ai() == i) && - !is_vsite(vsite_type[parm->aj()]) ) + if ((parm->ai() == i) && !is_vsite(vsite_type[parm->aj()])) { a = parm->aj(); } - else if ( (parm->aj() == i) && - !is_vsite(vsite_type[parm->ai()]) ) + else if ((parm->aj() == i) && !is_vsite(vsite_type[parm->ai()])) { a = parm->ai(); } } if (a == NOTSET) { - gmx_fatal(FARGS, "Unbound hydrogen atom (%d) found while adjusting mass", - i+1); + gmx_fatal(FARGS, "Unbound hydrogen atom (%d) found while adjusting mass", i + 1); } /* adjust mass of i (hydrogen) with mHmult and correct mass of a (bonded atom) with same amount */ if (!bDeuterate) { - at->atom[a].m -= (mHmult-1.0)*at->atom[i].m; - at->atom[a].mB -= (mHmult-1.0)*at->atom[i].m; + at->atom[a].m -= (mHmult - 1.0) * at->atom[i].m; + at->atom[a].mB -= (mHmult - 1.0) * at->atom[i].m; } - at->atom[i].m *= mHmult; + at->atom[i].m *= mHmult; at->atom[i].mB *= mHmult; } } diff --git a/src/gromacs/gmxpreprocess/gen_vsite.h b/src/gromacs/gmxpreprocess/gen_vsite.h index 580d1dbe5c..a86f4f4926 100644 --- a/src/gromacs/gmxpreprocess/gen_vsite.h +++ b/src/gromacs/gmxpreprocess/gen_vsite.h @@ -50,13 +50,18 @@ struct t_symtab; /* stuff for pdb2gmx */ -void do_vsites(gmx::ArrayRef rtpFFDB, PreprocessingAtomTypes *atype, - t_atoms *at, t_symtab *symtab, std::vector *x, - gmx::ArrayRef plist, int *dummy_type[], int *cgnr[], - real mHmult, bool bVSiteAromatics, - const char *ffdir); +void do_vsites(gmx::ArrayRef rtpFFDB, + PreprocessingAtomTypes* atype, + t_atoms* at, + t_symtab* symtab, + std::vector* x, + gmx::ArrayRef plist, + int* dummy_type[], + int* cgnr[], + real mHmult, + bool bVSiteAromatics, + const char* ffdir); -void do_h_mass(InteractionsOfType *psb, int vsite_type[], t_atoms *at, real mHmult, - bool bDeuterate); +void do_h_mass(InteractionsOfType* psb, int vsite_type[], t_atoms* at, real mHmult, bool bDeuterate); #endif diff --git a/src/gromacs/gmxpreprocess/genconf.cpp b/src/gromacs/gmxpreprocess/genconf.cpp index 4f13a69b57..a2630b7b88 100644 --- a/src/gromacs/gmxpreprocess/genconf.cpp +++ b/src/gromacs/gmxpreprocess/genconf.cpp @@ -55,13 +55,13 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[], - gmx::DefaultRandomEngine * rng, const rvec max_rot) +static void +rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[], gmx::DefaultRandomEngine* rng, const rvec max_rot) { - mat4 mt1, mt2, mr[DIM], mtemp1, mtemp2, mtemp3, mxtot, mvtot; - rvec xcm; - real phi; - int i, m; + mat4 mt1, mt2, mr[DIM], mtemp1, mtemp2, mtemp3, mxtot, mvtot; + rvec xcm; + real phi; + int i, m; gmx::UniformRealDistribution dist(-1.0, 1.0); clear_rvec(xcm); @@ -69,7 +69,7 @@ static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[], { for (m = 0; (m < DIM); m++) { - xcm[m] += x[i][m]/natoms; /* get center of mass of one molecule */ + xcm[m] += x[i][m] / natoms; /* get center of mass of one molecule */ } } fprintf(stderr, "center of geometry: %f, %f, %f\n", xcm[0], xcm[1], xcm[2]); @@ -78,7 +78,7 @@ static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[], gmx_mat4_init_translation(-xcm[XX], -xcm[YY], -xcm[ZZ], mt1); for (m = 0; (m < DIM); m++) { - phi = M_PI*max_rot[m]*dist(*rng)/180; + phi = M_PI * max_rot[m] * dist(*rng) / 180; gmx_mat4_init_rotation(m, phi, mr[m]); } gmx_mat4_init_translation(xcm[XX], xcm[YY], xcm[ZZ], mt2); @@ -99,9 +99,9 @@ static void rand_rot(int natoms, rvec x[], rvec v[], vec4 xrot[], vec4 vrot[], } } -int gmx_genconf(int argc, char *argv[]) +int gmx_genconf(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] multiplies a given coordinate file by simply stacking them", "on top of each other, like a small child playing with wooden blocks.", "The program makes a grid of [IT]user-defined[it]", @@ -116,48 +116,43 @@ int gmx_genconf(int argc, char *argv[]) "build the grid." }; - const char *bugs[] = { - "The program should allow for random displacement of lattice points." - }; + const char* bugs[] = { "The program should allow for random displacement of lattice points." }; int vol; - rvec *x, *xx, *v; /* coordinates? */ + rvec * x, *xx, *v; /* coordinates? */ real t; - vec4 *xrot, *vrot; + vec4 * xrot, *vrot; int ePBC; matrix box, boxx; /* box length matrix */ rvec shift; - int natoms; /* number of atoms in one molecule */ - int nres; /* number of molecules? */ + int natoms; /* number of atoms in one molecule */ + int nres; /* number of molecules? */ int i, j, k, l, m, ndx, nrdx, nx, ny, nz; - t_trxstatus *status; + t_trxstatus* status; bool bTRX; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; - t_filenm fnm[] = { - { efSTX, "-f", "conf", ffREAD }, - { efSTO, "-o", "out", ffWRITE }, - { efTRX, "-trj", nullptr, ffOPTRD } - }; + t_filenm fnm[] = { { efSTX, "-f", "conf", ffREAD }, + { efSTO, "-o", "out", ffWRITE }, + { efTRX, "-trj", nullptr, ffOPTRD } }; #define NFILE asize(fnm) - rvec nrbox = {1, 1, 1}; - int seed = 0; /* seed for random number generator */ - gmx_bool bRandom = FALSE; /* False: no random rotations */ - gmx_bool bRenum = TRUE; /* renumber residues */ - rvec dist = {0, 0, 0}; /* space added between molecules ? */ - rvec max_rot = {180, 180, 180}; /* maximum rotation */ - t_pargs pa[] = { - { "-nbox", FALSE, etRVEC, {nrbox}, "Number of boxes" }, - { "-dist", FALSE, etRVEC, {dist}, "Distance between boxes" }, - { "-seed", FALSE, etINT, {&seed}, - "Random generator seed (0 means generate)" }, - { "-rot", FALSE, etBOOL, {&bRandom}, "Randomly rotate conformations" }, - { "-maxrot", FALSE, etRVEC, {max_rot}, "Maximum random rotation" }, - { "-renumber", FALSE, etBOOL, {&bRenum}, "Renumber residues" } + rvec nrbox = { 1, 1, 1 }; + int seed = 0; /* seed for random number generator */ + gmx_bool bRandom = FALSE; /* False: no random rotations */ + gmx_bool bRenum = TRUE; /* renumber residues */ + rvec dist = { 0, 0, 0 }; /* space added between molecules ? */ + rvec max_rot = { 180, 180, 180 }; /* maximum rotation */ + t_pargs pa[] = { + { "-nbox", FALSE, etRVEC, { nrbox }, "Number of boxes" }, + { "-dist", FALSE, etRVEC, { dist }, "Distance between boxes" }, + { "-seed", FALSE, etINT, { &seed }, "Random generator seed (0 means generate)" }, + { "-rot", FALSE, etBOOL, { &bRandom }, "Randomly rotate conformations" }, + { "-maxrot", FALSE, etRVEC, { max_rot }, "Maximum random rotation" }, + { "-renumber", FALSE, etBOOL, { &bRenum }, "Renumber residues" } }; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, + asize(bugs), bugs, &oenv)) { return 0; } @@ -178,19 +173,19 @@ int gmx_genconf(int argc, char *argv[]) gmx_fatal(FARGS, "Number of boxes (-nbox) should be larger than zero"); } - vol = nx*ny*nz; /* calculate volume in grid points (= nr. molecules) */ + vol = nx * ny * nz; /* calculate volume in grid points (= nr. molecules) */ gmx_mtop_t mtop; bool haveTop = false; readConfAndTopology(opt2fn("-f", NFILE, fnm), &haveTop, &mtop, &ePBC, &x, &v, box); - t_atoms atoms = gmx_mtop_global_atoms(&mtop); - natoms = atoms.nr; - nres = atoms.nres; /* nr of residues in one element? */ + t_atoms atoms = gmx_mtop_global_atoms(&mtop); + natoms = atoms.nr; + nres = atoms.nres; /* nr of residues in one element? */ /* make space for all the atoms */ - add_t_atoms(&atoms, natoms*(vol-1), nres*(vol-1)); - srenew(x, natoms*vol); /* get space for coordinates of all atoms */ - srenew(v, natoms*vol); /* velocities. not really needed? */ - snew(xrot, natoms); /* get space for rotation matrix? */ + add_t_atoms(&atoms, natoms * (vol - 1), nres * (vol - 1)); + srenew(x, natoms * vol); /* get space for coordinates of all atoms */ + srenew(v, natoms * vol); /* velocities. not really needed? */ + snew(xrot, natoms); /* get space for rotation matrix? */ snew(vrot, natoms); if (bTRX) @@ -210,20 +205,20 @@ int gmx_genconf(int argc, char *argv[]) } - for (k = 0; (k < nz); k++) /* loop over all gridpositions */ + for (k = 0; (k < nz); k++) /* loop over all gridpositions */ { - shift[ZZ] = k*(dist[ZZ]+box[ZZ][ZZ]); + shift[ZZ] = k * (dist[ZZ] + box[ZZ][ZZ]); for (j = 0; (j < ny); j++) { - shift[YY] = j*(dist[YY]+box[YY][YY])+k*box[ZZ][YY]; + shift[YY] = j * (dist[YY] + box[YY][YY]) + k * box[ZZ][YY]; for (i = 0; (i < nx); i++) { - shift[XX] = i*(dist[XX]+box[XX][XX])+j*box[YY][XX]+k*box[ZZ][XX]; + shift[XX] = i * (dist[XX] + box[XX][XX]) + j * box[YY][XX] + k * box[ZZ][XX]; - ndx = (i*ny*nz+j*nz+k)*natoms; - nrdx = (i*ny*nz+j*nz+k)*nres; + ndx = (i * ny * nz + j * nz + k) * natoms; + nrdx = (i * ny * nz + j * nz + k) * nres; /* Random rotation on input coords */ if (bRandom) @@ -237,13 +232,13 @@ int gmx_genconf(int argc, char *argv[]) { if (bRandom) { - x[ndx+l][m] = xrot[l][m]; - v[ndx+l][m] = vrot[l][m]; + x[ndx + l][m] = xrot[l][m]; + v[ndx + l][m] = vrot[l][m]; } else { - x[ndx+l][m] = xx[l][m]; - v[ndx+l][m] = v[l][m]; + x[ndx + l][m] = xx[l][m]; + v[ndx + l][m] = v[l][m]; } } if (ePBC == epbcSCREW && i % 2 == 1) @@ -251,30 +246,29 @@ int gmx_genconf(int argc, char *argv[]) /* Rotate around x axis */ for (m = YY; m <= ZZ; m++) { - x[ndx+l][m] = box[YY][m] + box[ZZ][m] - x[ndx+l][m]; - v[ndx+l][m] = -v[ndx+l][m]; + x[ndx + l][m] = box[YY][m] + box[ZZ][m] - x[ndx + l][m]; + v[ndx + l][m] = -v[ndx + l][m]; } } for (m = 0; (m < DIM); m++) { - x[ndx+l][m] += shift[m]; + x[ndx + l][m] += shift[m]; } - atoms.atom[ndx+l].resind = nrdx + atoms.atom[l].resind; - atoms.atomname[ndx+l] = atoms.atomname[l]; + atoms.atom[ndx + l].resind = nrdx + atoms.atom[l].resind; + atoms.atomname[ndx + l] = atoms.atomname[l]; } for (l = 0; (l < nres); l++) { - atoms.resinfo[nrdx+l] = atoms.resinfo[l]; + atoms.resinfo[nrdx + l] = atoms.resinfo[l]; if (bRenum) { - atoms.resinfo[nrdx+l].nr += nrdx; + atoms.resinfo[nrdx + l].nr += nrdx; } } if (bTRX) { - if (!read_next_x(oenv, status, &t, xx, boxx) && - ((i+1)*(j+1)*(k+1) < vol)) + if (!read_next_x(oenv, status, &t, xx, boxx) && ((i + 1) * (j + 1) * (k + 1) < vol)) { gmx_fatal(FARGS, "Not enough frames in trajectory"); } @@ -306,7 +300,7 @@ int gmx_genconf(int argc, char *argv[]) { for (i = 0; i < atoms.nres; i++) { - atoms.resinfo[i].nr = i+1; + atoms.resinfo[i].nr = i + 1; } } diff --git a/src/gromacs/gmxpreprocess/genconf.h b/src/gromacs/gmxpreprocess/genconf.h index e10b6139a8..395c6ca6a8 100644 --- a/src/gromacs/gmxpreprocess/genconf.h +++ b/src/gromacs/gmxpreprocess/genconf.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_GENCONF_H #define GMX_GMXPREPROCESS_GENCONF_H -int gmx_genconf(int argc, char *argv[]); +int gmx_genconf(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/genhydro.cpp b/src/gromacs/gmxpreprocess/genhydro.cpp index 8589a928de..262f320762 100644 --- a/src/gromacs/gmxpreprocess/genhydro.cpp +++ b/src/gromacs/gmxpreprocess/genhydro.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,31 +60,29 @@ #include "hackblock.h" #include "resall.h" -static void copy_atom(const t_atoms *atoms1, int a1, t_atoms *atoms2, int a2, t_symtab *symtab) +static void copy_atom(const t_atoms* atoms1, int a1, t_atoms* atoms2, int a2, t_symtab* symtab) { atoms2->atom[a2] = atoms1->atom[a1]; atoms2->atomname[a2] = put_symtab(symtab, *atoms1->atomname[a1]); } -static int pdbasearch_atom(const char *name, int resind, const t_atoms *pdba, - const char *searchtype, bool bAllowMissing) +static int pdbasearch_atom(const char* name, int resind, const t_atoms* pdba, const char* searchtype, bool bAllowMissing) { - int i; + int i; - for (i = 0; (i < pdba->nr) && (pdba->atom[i].resind != resind); i++) - { - ; - } + for (i = 0; (i < pdba->nr) && (pdba->atom[i].resind != resind); i++) {} - return search_atom(name, i, pdba, - searchtype, bAllowMissing); + return search_atom(name, i, pdba, searchtype, bAllowMissing); } -static void hacksearch_atom(int *ii, int *jj, const char *name, - gmx::ArrayRef < const std::vector < MoleculePatch>> patches, - int resind, const t_atoms *pdba) +static void hacksearch_atom(int* ii, + int* jj, + const char* name, + gmx::ArrayRef> patches, + int resind, + const t_atoms* pdba) { - int i; + int i; *ii = -1; if (name[0] == '-') @@ -92,14 +90,11 @@ static void hacksearch_atom(int *ii, int *jj, const char *name, name++; resind--; } - for (i = 0; (i < pdba->nr) && (pdba->atom[i].resind != resind); i++) - { - ; - } + for (i = 0; (i < pdba->nr) && (pdba->atom[i].resind != resind); i++) {} for (; (i < pdba->nr) && (pdba->atom[i].resind == resind) && (*ii < 0); i++) { int j = 0; - for (const auto &patch : patches[i]) + for (const auto& patch : patches[i]) { if (patch.nname == name) { @@ -109,11 +104,10 @@ static void hacksearch_atom(int *ii, int *jj, const char *name, j++; } } - } static std::vector -getMoleculePatchDatabases(const t_atoms *pdba, +getMoleculePatchDatabases(const t_atoms* pdba, gmx::ArrayRef globalPatches, int nterpairs, gmx::ArrayRef ntdb, @@ -151,14 +145,15 @@ getMoleculePatchDatabases(const t_atoms *pdba, return modBlock; } -static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, +static void expand_hackblocks_one(const MoleculePatchDatabase& newPatch, const std::string localAtomName, //NOLINT(performance-unnecessary-value-param) - std::vector *globalPatches, - bool bN, bool bC) + std::vector* globalPatches, + bool bN, + bool bC) { /* we'll recursively add atoms to atoms */ - int pos = 0; - for (auto &singlePatch : newPatch.hack) + int pos = 0; + for (auto& singlePatch : newPatch.hack) { /* first check if we're in the N- or C-terminus, then we should ignore all hacks involving atoms from resp. previous or next residue @@ -182,17 +177,16 @@ static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, and first control aton (AI) matches this atom or delete/replace from tdb (oname!=NULL) and oname matches this atom */ - if (!bIgnore && - ( ( ( singlePatch.tp > 0 || singlePatch.oname.empty() ) && - singlePatch.a[0] == localAtomName ) || - ( singlePatch.oname == localAtomName) ) ) + if (!bIgnore + && (((singlePatch.tp > 0 || singlePatch.oname.empty()) && singlePatch.a[0] == localAtomName) + || (singlePatch.oname == localAtomName))) { /* now expand all hacks for this atom */ for (int k = 0; k < singlePatch.nr; k++) { globalPatches->push_back(singlePatch); - MoleculePatch *patch = &globalPatches->back(); - patch->bXSet = false; + MoleculePatch* patch = &globalPatches->back(); + patch->bXSet = false; /* if we're adding (oname==NULL) and don't have a new name (nname) yet, build it from localAtomName */ if (patch->nname.empty()) @@ -207,9 +201,10 @@ static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, { if (gmx_debug_at) { - fprintf(debug, "Hack '%s' %d, replacing nname '%s' with '%s' (old name '%s')\n", - localAtomName.c_str(), pos, - patch->nname.c_str(), singlePatch.nname.c_str(), + fprintf(debug, + "Hack '%s' %d, replacing nname '%s' with '%s' (old name '%s')\n", + localAtomName.c_str(), pos, patch->nname.c_str(), + singlePatch.nname.c_str(), patch->oname.empty() ? "" : patch->oname.c_str()); } patch->nname = singlePatch.nname; @@ -225,12 +220,12 @@ static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, { /* This is a water lone pair, not a hydrogen */ /* Ugly hardcoded name hack */ - patch->nname.assign(gmx::formatString("LP%d", 1+k-2)); + patch->nname.assign(gmx::formatString("LP%d", 1 + k - 2)); } else if (singlePatch.nr > 1) { /* adding more than one atom, number them */ - patch->nname.append(gmx::formatString("%d", 1+k)); + patch->nname.append(gmx::formatString("%d", 1 + k)); } } @@ -239,12 +234,9 @@ static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, { for (int k = 0; k < singlePatch.nr; k++) { - expand_hackblocks_one(newPatch, - globalPatches->at( - globalPatches->size() - - singlePatch.nr + - k).nname, - globalPatches, bN, bC); + expand_hackblocks_one( + newPatch, globalPatches->at(globalPatches->size() - singlePatch.nr + k).nname, + globalPatches, bN, bC); } } } @@ -252,12 +244,12 @@ static void expand_hackblocks_one(const MoleculePatchDatabase &newPatch, } } -static void expand_hackblocks(const t_atoms *pdba, - gmx::ArrayRef hb, - gmx::ArrayRef < std::vector < MoleculePatch>> patches, - int nterpairs, - gmx::ArrayRef rN, - gmx::ArrayRef rC) +static void expand_hackblocks(const t_atoms* pdba, + gmx::ArrayRef hb, + gmx::ArrayRef> patches, + int nterpairs, + gmx::ArrayRef rN, + gmx::ArrayRef rC) { for (int i = 0; i < pdba->nr; i++) { @@ -273,21 +265,17 @@ static void expand_hackblocks(const t_atoms *pdba } /* add hacks to this atom */ - expand_hackblocks_one(hb[pdba->atom[i].resind], *pdba->atomname[i], - &patches[i], bN, bC); + expand_hackblocks_one(hb[pdba->atom[i].resind], *pdba->atomname[i], &patches[i], bN, bC); } } -static int check_atoms_present(const t_atoms *pdba, - gmx::ArrayRef < std::vector < MoleculePatch>> patches) +static int check_atoms_present(const t_atoms* pdba, gmx::ArrayRef> patches) { int nadd = 0; for (int i = 0; i < pdba->nr; i++) { int rnr = pdba->atom[i].resind; - for (auto patch = patches[i].begin(); - patch != patches[i].end(); - patch++) + for (auto patch = patches[i].begin(); patch != patches[i].end(); patch++) { switch (patch->type()) { @@ -315,13 +303,9 @@ static int check_atoms_present(const t_atoms *pdb nadd--; break; } - case MoleculePatchType::Replace: - { - break; + case MoleculePatchType::Replace: { break; } - default: - { - GMX_THROW(gmx::InternalError("Case not handled")); + default: { GMX_THROW(gmx::InternalError("Case not handled")); } } } @@ -329,26 +313,26 @@ static int check_atoms_present(const t_atoms *pdb return nadd; } -static void calc_all_pos(const t_atoms *pdba, - gmx::ArrayRef x, - gmx::ArrayRef < std::vector < MoleculePatch>> patches, - bool bCheckMissing) +static void calc_all_pos(const t_atoms* pdba, + gmx::ArrayRef x, + gmx::ArrayRef> patches, + bool bCheckMissing) { - int ii, l = 0; + int ii, l = 0; #define MAXH 4 - rvec xa[4]; /* control atoms for calc_h_pos */ - rvec xh[MAXH]; /* hydrogen positions from calc_h_pos */ + rvec xa[4]; /* control atoms for calc_h_pos */ + rvec xh[MAXH]; /* hydrogen positions from calc_h_pos */ - int jj = 0; + int jj = 0; for (int i = 0; i < pdba->nr; i++) { - int rnr = pdba->atom[i].resind; - for (auto patch = patches[i].begin(); patch != patches[i].end(); - patch += patch->nr) + int rnr = pdba->atom[i].resind; + for (auto patch = patches[i].begin(); patch != patches[i].end(); patch += patch->nr) { GMX_RELEASE_ASSERT(patch < patches[i].end(), - "The number of patches in the last patch can not exceed the total number of patches"); + "The number of patches in the last patch can not exceed the total " + "number of patches"); /* check if we're adding: */ if (patch->type() == MoleculePatchType::Add && patch->tp > 0) { @@ -356,8 +340,7 @@ static void calc_all_pos(const t_atoms *pdba, for (int m = 0; (m < patch->nctl && bFoundAll); m++) { int ia = pdbasearch_atom(patch->a[m].c_str(), rnr, pdba, - bCheckMissing ? "atom" : "check", - !bCheckMissing); + bCheckMissing ? "atom" : "check", !bCheckMissing); if (ia < 0) { /* not found in original atoms, might still be in @@ -372,13 +355,12 @@ static void calc_all_pos(const t_atoms *pdba, bFoundAll = false; if (bCheckMissing) { - gmx_fatal(FARGS, "Atom %s not found in residue %s %d" + gmx_fatal(FARGS, + "Atom %s not found in residue %s %d" ", rtp entry %s" " while adding hydrogens", - patch->a[m].c_str(), - *pdba->resinfo[rnr].name, - pdba->resinfo[rnr].nr, - *pdba->resinfo[rnr].rtp); + patch->a[m].c_str(), *pdba->resinfo[rnr].name, + pdba->resinfo[rnr].nr, *pdba->resinfo[rnr].rtp); } } } @@ -416,11 +398,11 @@ static void calc_all_pos(const t_atoms *pdba, } } -static int add_h_low(t_atoms **initialAtoms, - t_atoms **modifiedAtoms, - std::vector *xptr, +static int add_h_low(t_atoms** initialAtoms, + t_atoms** modifiedAtoms, + std::vector* xptr, gmx::ArrayRef globalPatches, - t_symtab *symtab, + t_symtab* symtab, const int nterpairs, gmx::ArrayRef ntdb, gmx::ArrayRef ctdb, @@ -428,12 +410,12 @@ static int add_h_low(t_atoms **initialAtoms, gmx::ArrayRef rC, const bool bCheckMissing) { - int nadd; - int newi, natoms, nalreadypresent; - std::vector < std::vector < MoleculePatch>> patches; - std::vector xn; + int nadd; + int newi, natoms, nalreadypresent; + std::vector> patches; + std::vector xn; - t_atoms *pdba = *initialAtoms; + t_atoms* pdba = *initialAtoms; /* set flags for adding hydrogens (according to hdb) */ natoms = pdba->nr; @@ -442,7 +424,7 @@ static int add_h_low(t_atoms **initialAtoms, /* We'll have to do all the hard work */ /* first get all the hackblocks for each residue: */ std::vector hb = - getMoleculePatchDatabases(pdba, globalPatches, nterpairs, ntdb, ctdb, rN, rC); + getMoleculePatchDatabases(pdba, globalPatches, nterpairs, ntdb, ctdb, rN, rC); /* expand the hackblocks to atom level */ patches.resize(natoms); @@ -460,8 +442,8 @@ static int add_h_low(t_atoms **initialAtoms, if (nadd > 0) { srenew(*modifiedAtoms, 1); - init_t_atoms(*modifiedAtoms, natoms+nadd, FALSE); - (*modifiedAtoms)->nres = pdba->nres; + init_t_atoms(*modifiedAtoms, natoms + nadd, FALSE); + (*modifiedAtoms)->nres = pdba->nres; srenew((*modifiedAtoms)->resinfo, pdba->nres); std::copy(pdba->resinfo, pdba->resinfo + pdba->nres, (*modifiedAtoms)->resinfo); } @@ -470,63 +452,59 @@ static int add_h_low(t_atoms **initialAtoms, return natoms; } - xn.resize(natoms+nadd); + xn.resize(natoms + nadd); newi = 0; for (int i = 0; (i < natoms); i++) { /* check if this atom wasn't scheduled for deletion */ - if (patches[i].empty() || (!patches[i][0].nname.empty()) ) + if (patches[i].empty() || (!patches[i][0].nname.empty())) { - if (newi >= natoms+nadd) + if (newi >= natoms + nadd) { /*gmx_fatal(FARGS,"Not enough space for adding atoms");*/ nadd += 10; - xn.resize(natoms+nadd); - srenew((*modifiedAtoms)->atom, natoms+nadd); - srenew((*modifiedAtoms)->atomname, natoms+nadd); + xn.resize(natoms + nadd); + srenew((*modifiedAtoms)->atom, natoms + nadd); + srenew((*modifiedAtoms)->atomname, natoms + nadd); } copy_atom(pdba, i, (*modifiedAtoms), newi, symtab); copy_rvec((*xptr)[i], xn[newi]); /* process the hacks for this atom */ nalreadypresent = 0; - for (auto patch = patches[i].begin(); - patch != patches[i].end(); - patch++) + for (auto patch = patches[i].begin(); patch != patches[i].end(); patch++) { if (patch->type() == MoleculePatchType::Add) /* add */ { newi++; - if (newi >= natoms+nadd) + if (newi >= natoms + nadd) { /* gmx_fatal(FARGS,"Not enough space for adding atoms");*/ nadd += 10; - xn.resize(natoms+nadd); - srenew((*modifiedAtoms)->atom, natoms+nadd); - srenew((*modifiedAtoms)->atomname, natoms+nadd); + xn.resize(natoms + nadd); + srenew((*modifiedAtoms)->atom, natoms + nadd); + srenew((*modifiedAtoms)->atomname, natoms + nadd); } (*modifiedAtoms)->atom[newi].resind = pdba->atom[i].resind; } - if (!patch->nname.empty() && - (patch->oname.empty() || - patch->oname == *(*modifiedAtoms)->atomname[newi])) + if (!patch->nname.empty() + && (patch->oname.empty() || patch->oname == *(*modifiedAtoms)->atomname[newi])) { /* add or replace */ if (patch->type() == MoleculePatchType::Add && patch->bAlreadyPresent) { /* This atom is already present, copy it from the input. */ nalreadypresent++; - copy_atom(pdba, i+nalreadypresent, (*modifiedAtoms), newi, symtab); - copy_rvec((*xptr)[i+nalreadypresent], xn[newi]); + copy_atom(pdba, i + nalreadypresent, (*modifiedAtoms), newi, symtab); + copy_rvec((*xptr)[i + nalreadypresent], xn[newi]); } else { if (gmx_debug_at) { - fprintf(debug, "Replacing %d '%s' with (old name '%s') %s\n", - newi, - ((*modifiedAtoms)->atomname[newi] && - *(*modifiedAtoms)->atomname[newi]) ? - *(*modifiedAtoms)->atomname[newi] : "", + fprintf(debug, "Replacing %d '%s' with (old name '%s') %s\n", newi, + ((*modifiedAtoms)->atomname[newi] && *(*modifiedAtoms)->atomname[newi]) + ? *(*modifiedAtoms)->atomname[newi] + : "", patch->oname.empty() ? "" : patch->oname.c_str(), patch->nname.c_str()); } @@ -557,11 +535,11 @@ static int add_h_low(t_atoms **initialAtoms, return newi; } -int add_h(t_atoms **initialAtoms, - t_atoms **localAtoms, - std::vector *xptr, +int add_h(t_atoms** initialAtoms, + t_atoms** localAtoms, + std::vector* xptr, gmx::ArrayRef globalPatches, - t_symtab *symtab, + t_symtab* symtab, const int nterpairs, gmx::ArrayRef ntdb, gmx::ArrayRef ctdb, @@ -579,19 +557,22 @@ int add_h(t_atoms **initialAtoms, do { nold = nnew; - nnew = add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN, rC, FALSE); + nnew = add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, + ctdb, rN, rC, FALSE); niter++; if (niter > 100) { - gmx_fatal(FARGS, "More than 100 iterations of add_h. Maybe you are trying to replace an added atom (this is not supported)?"); + gmx_fatal(FARGS, + "More than 100 iterations of add_h. Maybe you are trying to replace an added " + "atom (this is not supported)?"); } - } - while (nnew > nold); + } while (nnew > nold); if (!bAllowMissing) { /* Call add_h_low once more, now only for the missing atoms check */ - add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN, rC, TRUE); + add_h_low(initialAtoms, localAtoms, xptr, globalPatches, symtab, nterpairs, ntdb, ctdb, rN, + rC, TRUE); } return nnew; diff --git a/src/gromacs/gmxpreprocess/genhydro.h b/src/gromacs/gmxpreprocess/genhydro.h index 8159c800e5..a7c451fb29 100644 --- a/src/gromacs/gmxpreprocess/genhydro.h +++ b/src/gromacs/gmxpreprocess/genhydro.h @@ -61,11 +61,11 @@ struct MoleculePatchDatabase; * \param[in] bMissing If routine should continue if atoms are not found. * \returns New total number of atoms. */ -int add_h(t_atoms **initialAtoms, - t_atoms **localAtoms, - std::vector *xptr, +int add_h(t_atoms** initialAtoms, + t_atoms** localAtoms, + std::vector* xptr, gmx::ArrayRef globalPatches, - t_symtab *symtab, + t_symtab* symtab, int nterpairs, gmx::ArrayRef ntdb, gmx::ArrayRef ctdb, diff --git a/src/gromacs/gmxpreprocess/genion.cpp b/src/gromacs/gmxpreprocess/genion.cpp index aab6f86c5e..bb472e7dc0 100644 --- a/src/gromacs/gmxpreprocess/genion.cpp +++ b/src/gromacs/gmxpreprocess/genion.cpp @@ -77,7 +77,7 @@ * \returns true if any distance between an atom from group A and group B is * smaller than a minimum distance. */ -static bool groupsCloserThanCutoffWithPbc(t_pbc *pbc, +static bool groupsCloserThanCutoffWithPbc(t_pbc* pbc, rvec x[], gmx::ArrayRef smallerGroupIndices, gmx::ArrayRef largerGroupIndices, @@ -109,32 +109,34 @@ static bool groupsCloserThanCutoffWithPbc(t_pbc *pbc, * * \returns atom indices of the specified solvent molecule */ -static std::vector -solventMoleculeIndices(int solventMoleculeNumber, int numberAtomsPerSolventMolecule, gmx::ArrayRef solventGroupIndex) +static std::vector solventMoleculeIndices(int solventMoleculeNumber, + int numberAtomsPerSolventMolecule, + gmx::ArrayRef solventGroupIndex) { std::vector indices(numberAtomsPerSolventMolecule); for (int solventAtomNumber = 0; solventAtomNumber < numberAtomsPerSolventMolecule; ++solventAtomNumber) { - indices[solventAtomNumber] = solventGroupIndex[numberAtomsPerSolventMolecule * solventMoleculeNumber + solventAtomNumber]; + indices[solventAtomNumber] = + solventGroupIndex[numberAtomsPerSolventMolecule * solventMoleculeNumber + solventAtomNumber]; } return indices; } static void insert_ion(int nsa, - std::vector *solventMoleculesForReplacement, + std::vector* solventMoleculesForReplacement, int repl[], gmx::ArrayRef index, rvec x[], - t_pbc *pbc, + t_pbc* pbc, int sign, int q, - const char *ionname, - t_atoms *atoms, + const char* ionname, + t_atoms* atoms, real rmin, - std::vector *notSolventGroup) + std::vector* notSolventGroup) { - std::vector solventMoleculeAtomsToBeReplaced - = solventMoleculeIndices(solventMoleculesForReplacement->back(), nsa, index); + std::vector solventMoleculeAtomsToBeReplaced = + solventMoleculeIndices(solventMoleculesForReplacement->back(), nsa, index); if (rmin > 0.0) { @@ -143,7 +145,8 @@ static void insert_ion(int nsa, && !solventMoleculesForReplacement->empty()) { solventMoleculesForReplacement->pop_back(); - solventMoleculeAtomsToBeReplaced = solventMoleculeIndices(solventMoleculesForReplacement->back(), nsa, index); + solventMoleculeAtomsToBeReplaced = + solventMoleculeIndices(solventMoleculesForReplacement->back(), nsa, index); } } @@ -162,9 +165,8 @@ static void insert_ion(int nsa, // The first solvent molecule atom is replaced with an ion and the respective // charge while the rest of the solvent molecule atoms is set to 0 charge. atoms->atom[solventMoleculeAtomsToBeReplaced.front()].q = q; - for (auto replacedMoleculeAtom = solventMoleculeAtomsToBeReplaced.begin()+1; - replacedMoleculeAtom != solventMoleculeAtomsToBeReplaced.end(); - ++replacedMoleculeAtom) + for (auto replacedMoleculeAtom = solventMoleculeAtomsToBeReplaced.begin() + 1; + replacedMoleculeAtom != solventMoleculeAtomsToBeReplaced.end(); ++replacedMoleculeAtom) { atoms->atom[*replacedMoleculeAtom].q = 0; } @@ -172,13 +174,13 @@ static void insert_ion(int nsa, } -static char *aname(const char *mname) +static char* aname(const char* mname) { - char *str; + char* str; int i; str = gmx_strdup(mname); - i = std::strlen(str)-1; + i = std::strlen(str) - 1; while (i > 1 && (std::isdigit(str[i]) || (str[i] == '+') || (str[i] == '-'))) { str[i] = '\0'; @@ -188,12 +190,19 @@ static char *aname(const char *mname) return str; } -static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRef index, - t_atoms *atoms, rvec x[], - char **pptr, char **nptr, char **paptr, char **naptr) +static void sort_ions(int nsa, + int nw, + const int repl[], + gmx::ArrayRef index, + t_atoms* atoms, + rvec x[], + char** pptr, + char** nptr, + char** paptr, + char** naptr) { - int i, j, k, r, np, nn, starta, startr, npi, nni; - rvec *xt; + int i, j, k, r, np, nn, starta, startr, npi, nni; + rvec* xt; snew(xt, atoms->nr); @@ -208,7 +217,7 @@ static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRef 0) @@ -221,10 +230,10 @@ static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRef 0) + if (np + nn > 0) { /* Put the positive and negative ions at the end */ - starta = index[nsa*(nw - np - nn)]; + starta = index[nsa * (nw - np - nn)]; startr = atoms->atom[starta].resind; npi = 0; @@ -234,9 +243,9 @@ static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRef 0) { - j = starta+npi; - k = startr+npi; - copy_rvec(x[index[nsa*i]], xt[j]); + j = starta + npi; + k = startr + npi; + copy_rvec(x[index[nsa * i]], xt[j]); atoms->atomname[j] = paptr; atoms->atom[j].resind = k; atoms->resinfo[k].name = pptr; @@ -244,23 +253,23 @@ static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRefatomname[j] = naptr; atoms->atom[j].resind = k; atoms->resinfo[k].name = nptr; nni++; } } - for (i = index[nsa*nw-1]+1; i < atoms->nr; i++) + for (i = index[nsa * nw - 1] + 1; i < atoms->nr; i++) { - j = i-(nsa-1)*(np+nn); + j = i - (nsa - 1) * (np + nn); atoms->atomname[j] = atoms->atomname[i]; atoms->atom[j] = atoms->atom[i]; copy_rvec(x[i], xt[j]); } - atoms->nr -= (nsa-1)*(np+nn); + atoms->nr -= (nsa - 1) * (np + nn); /* Copy the new positions back */ for (i = index[0]; i < atoms->nr; i++) @@ -271,17 +280,16 @@ static void sort_ions(int nsa, int nw, const int repl[], gmx::ArrayRef 0) { @@ -397,23 +410,24 @@ static std::vector invertIndexGroup(int nrAtoms, std::vector indexGrou // construct the inverted index group by adding all indicies between two // indices of indexGroup std::vector invertedGroup; - for (auto indexGroupIt = std::begin(indexGroup); indexGroupIt != std::end(indexGroup)-1; ++indexGroupIt) + for (auto indexGroupIt = std::begin(indexGroup); indexGroupIt != std::end(indexGroup) - 1; ++indexGroupIt) { const int firstToAddToInvertedGroup = *indexGroupIt + 1; const int numIndicesToAdd = *(indexGroupIt + 1) - firstToAddToInvertedGroup; if (numIndicesToAdd > 0) { invertedGroup.resize(invertedGroup.size() + numIndicesToAdd); - std::iota(std::end(invertedGroup) - numIndicesToAdd, std::end(invertedGroup), firstToAddToInvertedGroup); + std::iota(std::end(invertedGroup) - numIndicesToAdd, std::end(invertedGroup), + firstToAddToInvertedGroup); } } return invertedGroup; } -int gmx_genion(int argc, char *argv[]) +int gmx_genion(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] randomly replaces solvent molecules with monoatomic ions.", "The group of solvent molecules should be continuous and all molecules", "should have the same number of atoms.", @@ -428,47 +442,55 @@ int gmx_genion(int argc, char *argv[]) "added, without sign, for the uncommon states only.[PAR]", "For larger ions, e.g. sulfate we recommended using [gmx-insert-molecules]." }; - const char *bugs[] = { + const char* bugs[] = { "If you specify a salt concentration existing ions are not taken into " "account. In effect you therefore specify the amount of salt to be added.", }; - int p_num = 0, n_num = 0, p_q = 1, n_q = -1; - const char *p_name = "NA", *n_name = "CL"; - real rmin = 0.6, conc = 0; - int seed = 0; - gmx_bool bNeutral = FALSE; - t_pargs pa[] = { - { "-np", FALSE, etINT, {&p_num}, "Number of positive ions" }, - { "-pname", FALSE, etSTR, {&p_name}, "Name of the positive ion" }, - { "-pq", FALSE, etINT, {&p_q}, "Charge of the positive ion" }, - { "-nn", FALSE, etINT, {&n_num}, "Number of negative ions" }, - { "-nname", FALSE, etSTR, {&n_name}, "Name of the negative ion" }, - { "-nq", FALSE, etINT, {&n_q}, "Charge of the negative ion" }, - { "-rmin", FALSE, etREAL, {&rmin}, "Minimum distance between ions and non-solvent" }, - { "-seed", FALSE, etINT, {&seed}, "Seed for random number generator (0 means generate)" }, - { "-conc", FALSE, etREAL, {&conc}, - "Specify salt concentration (mol/liter). This will add sufficient ions to reach up to the specified concentration as computed from the volume of the cell in the input [REF].tpr[ref] file. Overrides the [TT]-np[tt] and [TT]-nn[tt] options." }, - { "-neutral", FALSE, etBOOL, {&bNeutral}, "This option will add enough ions to neutralize the system. These ions are added on top of those specified with [TT]-np[tt]/[TT]-nn[tt] or [TT]-conc[tt]. "} - }; - t_topology top; - rvec *x; - real vol; - matrix box; - t_atoms atoms; - t_pbc pbc; - int *repl, ePBC; - int nw, nsa, nsalt, iqtot; - gmx_output_env_t *oenv = nullptr; - t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efSTO, "-o", nullptr, ffWRITE }, - { efTOP, "-p", "topol", ffOPTRW } + int p_num = 0, n_num = 0, p_q = 1, n_q = -1; + const char *p_name = "NA", *n_name = "CL"; + real rmin = 0.6, conc = 0; + int seed = 0; + gmx_bool bNeutral = FALSE; + t_pargs pa[] = { + { "-np", FALSE, etINT, { &p_num }, "Number of positive ions" }, + { "-pname", FALSE, etSTR, { &p_name }, "Name of the positive ion" }, + { "-pq", FALSE, etINT, { &p_q }, "Charge of the positive ion" }, + { "-nn", FALSE, etINT, { &n_num }, "Number of negative ions" }, + { "-nname", FALSE, etSTR, { &n_name }, "Name of the negative ion" }, + { "-nq", FALSE, etINT, { &n_q }, "Charge of the negative ion" }, + { "-rmin", FALSE, etREAL, { &rmin }, "Minimum distance between ions and non-solvent" }, + { "-seed", FALSE, etINT, { &seed }, "Seed for random number generator (0 means generate)" }, + { "-conc", + FALSE, + etREAL, + { &conc }, + "Specify salt concentration (mol/liter). This will add sufficient ions to reach up to " + "the specified concentration as computed from the volume of the cell in the input " + "[REF].tpr[ref] file. Overrides the [TT]-np[tt] and [TT]-nn[tt] options." }, + { "-neutral", + FALSE, + etBOOL, + { &bNeutral }, + "This option will add enough ions to neutralize the system. These ions are added on top " + "of those specified with [TT]-np[tt]/[TT]-nn[tt] or [TT]-conc[tt]. " } }; + t_topology top; + rvec* x; + real vol; + matrix box; + t_atoms atoms; + t_pbc pbc; + int * repl, ePBC; + int nw, nsa, nsalt, iqtot; + gmx_output_env_t* oenv = nullptr; + t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efSTO, "-o", nullptr, ffWRITE }, + { efTOP, "-p", "topol", ffOPTRW } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, + asize(bugs), bugs, &oenv)) { if (oenv != nullptr) { @@ -505,21 +527,23 @@ int gmx_genion(int argc, char *argv[]) { /* Compute number of ions to be added */ vol = det(box); - nsalt = gmx::roundToInt(conc*vol*AVOGADRO/1e24); - p_num = abs(nsalt*n_q); - n_num = abs(nsalt*p_q); + nsalt = gmx::roundToInt(conc * vol * AVOGADRO / 1e24); + p_num = abs(nsalt * n_q); + n_num = abs(nsalt * p_q); } if (bNeutral) { - int qdelta = p_num*p_q + n_num*n_q + iqtot; + int qdelta = p_num * p_q + n_num * n_q + iqtot; /* Check if the system is neutralizable * is (qdelta == p_q*p_num + n_q*n_num) solvable for p_num and n_num? */ int gcd = gmx_greatest_common_divisor(n_q, p_q); if ((qdelta % gcd) != 0) { - gmx_fatal(FARGS, "Can't neutralize this system using -nq %d and" - " -pq %d.\n", n_q, p_q); + gmx_fatal(FARGS, + "Can't neutralize this system using -nq %d and" + " -pq %d.\n", + n_q, p_q); } while (qdelta != 0) @@ -537,10 +561,10 @@ int gmx_genion(int argc, char *argv[]) } } - char * pptr = gmx_strdup(p_name); - char * paptr = aname(p_name); - char * nptr = gmx_strdup(n_name); - char * naptr = aname(n_name); + char* pptr = gmx_strdup(p_name); + char* paptr = aname(p_name); + char* nptr = gmx_strdup(n_name); + char* naptr = aname(n_name); if ((p_num == 0) && (n_num == 0)) { @@ -548,18 +572,17 @@ int gmx_genion(int argc, char *argv[]) } else { - char *grpname = nullptr; + char* grpname = nullptr; - printf("Will try to add %d %s ions and %d %s ions.\n", - p_num, p_name, n_num, n_name); + printf("Will try to add %d %s ions and %d %s ions.\n", p_num, p_name, n_num, n_name); printf("Select a continuous group of solvent molecules\n"); std::vector solventGroup; { - int *index = nullptr; - int nwa; + int* index = nullptr; + int nwa; get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nwa, &index, &grpname); - solventGroup.assign(index, index+nwa); + solventGroup.assign(index, index + nwa); sfree(index); } @@ -567,15 +590,15 @@ int gmx_genion(int argc, char *argv[]) { if (solventGroup[i] != solventGroup[i - 1] + 1) { - gmx_fatal(FARGS, "The solvent group %s is not continuous: " + gmx_fatal(FARGS, + "The solvent group %s is not continuous: " "index[%d]=%d, index[%d]=%d", - grpname, int(i), solventGroup[i-1]+1, int(i+1), solventGroup[i]+1); + grpname, int(i), solventGroup[i - 1] + 1, int(i + 1), solventGroup[i] + 1); } } nsa = 1; - while ((nsa < gmx::ssize(solventGroup)) && - (atoms.atom[solventGroup[nsa]].resind == - atoms.atom[solventGroup[nsa-1]].resind)) + while ((nsa < gmx::ssize(solventGroup)) + && (atoms.atom[solventGroup[nsa]].resind == atoms.atom[solventGroup[nsa - 1]].resind)) { nsa++; } @@ -584,9 +607,9 @@ int gmx_genion(int argc, char *argv[]) gmx_fatal(FARGS, "Your solvent group size (%td) is not a multiple of %d", gmx::ssize(solventGroup), nsa); } - nw = solventGroup.size()/nsa; + nw = solventGroup.size() / nsa; fprintf(stderr, "Number of (%d-atomic) solvent molecules: %d\n", nsa, nw); - if (p_num+n_num > nw) + if (p_num + n_num > nw) { gmx_fatal(FARGS, "Not enough solvent for adding ions"); } @@ -616,18 +639,19 @@ int gmx_genion(int argc, char *argv[]) // Randomly shuffle the solvent molecules that shall be replaced by ions // then pick molecules from the back of the list as replacement candidates gmx::DefaultRandomEngine rng(seed); - std::shuffle(std::begin(solventMoleculesForReplacement), std::end(solventMoleculesForReplacement), rng); + std::shuffle(std::begin(solventMoleculesForReplacement), + std::end(solventMoleculesForReplacement), rng); /* Now loop over the ions that have to be placed */ while (p_num-- > 0) { - insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, - 1, p_q, p_name, &atoms, rmin, ¬SolventGroup); + insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, 1, p_q, + p_name, &atoms, rmin, ¬SolventGroup); } while (n_num-- > 0) { - insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, - -1, n_q, n_name, &atoms, rmin, ¬SolventGroup); + insert_ion(nsa, &solventMoleculesForReplacement, repl, solventGroup, x, &pbc, -1, n_q, + n_name, &atoms, rmin, ¬SolventGroup); } fprintf(stderr, "\n"); diff --git a/src/gromacs/gmxpreprocess/genion.h b/src/gromacs/gmxpreprocess/genion.h index 1ce7f9bf66..bde3085ccc 100644 --- a/src/gromacs/gmxpreprocess/genion.h +++ b/src/gromacs/gmxpreprocess/genion.h @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_GENION_H #define GMX_GMXPREPROCESS_GENION_H -int gmx_genion(int argc, char *argv[]); +int gmx_genion(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/genrestr.cpp b/src/gromacs/gmxpreprocess/genrestr.cpp index 3d462299cf..137bef2ab2 100644 --- a/src/gromacs/gmxpreprocess/genrestr.cpp +++ b/src/gromacs/gmxpreprocess/genrestr.cpp @@ -55,9 +55,9 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -int gmx_genrestr(int argc, char *argv[]) +int gmx_genrestr(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] produces an #include file for a topology containing", "a list of atom numbers and three force constants for the", "[IT]x[it]-, [IT]y[it]-, and [IT]z[it]-direction based on", @@ -82,58 +82,80 @@ int gmx_genrestr(int argc, char *argv[]) "maintain the overall conformation of a protein without tieing it to", "a specific position (as with position restraints)." }; - static rvec fc = {1000.0, 1000.0, 1000.0}; - static real freeze_level = 0.0; - static real disre_dist = 0.1; - static real disre_frac = 0.0; - static real disre_up2 = 1.0; - static gmx_bool bDisre = FALSE; - static gmx_bool bConstr = FALSE; - static real cutoff = -1.0; + static rvec fc = { 1000.0, 1000.0, 1000.0 }; + static real freeze_level = 0.0; + static real disre_dist = 0.1; + static real disre_frac = 0.0; + static real disre_up2 = 1.0; + static gmx_bool bDisre = FALSE; + static gmx_bool bConstr = FALSE; + static real cutoff = -1.0; - t_pargs pa[] = { - { "-fc", FALSE, etRVEC, {fc}, - "Force constants (kJ/mol nm^2)" }, - { "-freeze", FALSE, etREAL, {&freeze_level}, - "If the [TT]-of[tt] option or this one is given an index file will be written containing atom numbers of all atoms that have a B-factor less than the level given here" }, - { "-disre", FALSE, etBOOL, {&bDisre}, + t_pargs pa[] = { + { "-fc", FALSE, etRVEC, { fc }, "Force constants (kJ/mol nm^2)" }, + { "-freeze", + FALSE, + etREAL, + { &freeze_level }, + "If the [TT]-of[tt] option or this one is given an index file will be written containing " + "atom numbers of all atoms that have a B-factor less than the level given here" }, + { "-disre", + FALSE, + etBOOL, + { &bDisre }, "Generate a distance restraint matrix for all the atoms in index" }, - { "-disre_dist", FALSE, etREAL, {&disre_dist}, + { "-disre_dist", + FALSE, + etREAL, + { &disre_dist }, "Distance range around the actual distance for generating distance restraints" }, - { "-disre_frac", FALSE, etREAL, {&disre_frac}, - "Fraction of distance to be used as interval rather than a fixed distance. If the fraction of the distance that you specify here is less than the distance given in the previous option, that one is used instead." }, - { "-disre_up2", FALSE, etREAL, {&disre_up2}, - "Distance between upper bound for distance restraints, and the distance at which the force becomes constant (see manual)" }, - { "-cutoff", FALSE, etREAL, {&cutoff}, + { "-disre_frac", + FALSE, + etREAL, + { &disre_frac }, + "Fraction of distance to be used as interval rather than a fixed distance. If the " + "fraction of the distance that you specify here is less than the distance given in the " + "previous option, that one is used instead." }, + { "-disre_up2", + FALSE, + etREAL, + { &disre_up2 }, + "Distance between upper bound for distance restraints, and the distance at which the " + "force becomes constant (see manual)" }, + { "-cutoff", + FALSE, + etREAL, + { &cutoff }, "Only generate distance restraints for atoms pairs within cutoff (nm)" }, - { "-constr", FALSE, etBOOL, {&bConstr}, - "Generate a constraint matrix rather than distance restraints. Constraints of type 2 will be generated that do generate exclusions." } + { "-constr", + FALSE, + etBOOL, + { &bConstr }, + "Generate a constraint matrix rather than distance restraints. Constraints of type 2 " + "will be generated that do generate exclusions." } }; #define npargs asize(pa) - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; t_atoms atoms; int i, j, k; - FILE *out; + FILE* out; int igrp; real d, dd, lo, hi; - int *ind_grp; - const char *xfn, *nfn; - char *gn_grp; + int* ind_grp; + const char * xfn, *nfn; + char* gn_grp; matrix box; gmx_bool bFreeze; rvec dx, *x = nullptr, *v = nullptr; - t_filenm fnm[] = { - { efSTX, "-f", nullptr, ffREAD }, - { efNDX, "-n", nullptr, ffOPTRD }, - { efITP, "-o", "posre", ffWRITE }, - { efNDX, "-of", "freeze", ffOPTWR } - }; + t_filenm fnm[] = { { efSTX, "-f", nullptr, ffREAD }, + { efNDX, "-n", nullptr, ffOPTRD }, + { efITP, "-o", "posre", ffWRITE }, + { efNDX, "-of", "freeze", ffOPTWR } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, npargs, pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, npargs, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -143,7 +165,7 @@ int gmx_genrestr(int argc, char *argv[]) xfn = opt2fn_null("-f", NFILE, fnm); nfn = opt2fn_null("-n", NFILE, fnm); - if (( nfn == nullptr ) && ( xfn == nullptr)) + if ((nfn == nullptr) && (xfn == nullptr)) { gmx_fatal(FARGS, "no index file and no structure file supplied"); } @@ -157,7 +179,7 @@ int gmx_genrestr(int argc, char *argv[]) gmx_fatal(FARGS, "disre_dist should be >= 0"); } - const char *title = ""; + const char* title = ""; bool haveTopology = false; if (xfn != nullptr) { @@ -177,8 +199,7 @@ int gmx_genrestr(int argc, char *argv[]) { if (!haveTopology || !atoms.pdbinfo) { - gmx_fatal(FARGS, "No B-factors in input file %s, use a pdb file next time.", - xfn); + gmx_fatal(FARGS, "No B-factors in input file %s, use a pdb file next time.", xfn); } out = opt2FILE("-of", NFILE, fnm, "w"); @@ -187,15 +208,14 @@ int gmx_genrestr(int argc, char *argv[]) { if (atoms.pdbinfo[i].bfac <= freeze_level) { - fprintf(out, "%d\n", i+1); + fprintf(out, "%d\n", i + 1); } } gmx_ffclose(out); } else if ((bDisre || bConstr) && x) { - printf("Select group to generate %s matrix from\n", - bConstr ? "constraint" : "distance restraint"); + printf("Select group to generate %s matrix from\n", bConstr ? "constraint" : "distance restraint"); get_index(&atoms, nfn, 1, &igrp, &ind_grp, &gn_grp); out = ftp2FILE(efITP, NFILE, fnm, "w"); @@ -209,18 +229,18 @@ int gmx_genrestr(int argc, char *argv[]) { fprintf(out, "; distance restraints for %s of %s\n\n", gn_grp, title); fprintf(out, "[ distance_restraints ]\n"); - fprintf(out, ";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n", "i", "j", "?", - "label", "funct", "lo", "up1", "up2", "weight"); + fprintf(out, ";%4s %5s %1s %5s %10s %10s %10s %10s %10s\n", "i", "j", "?", "label", + "funct", "lo", "up1", "up2", "weight"); } for (i = k = 0; i < igrp; i++) { - for (j = i+1; j < igrp; j++, k++) + for (j = i + 1; j < igrp; j++, k++) { rvec_sub(x[ind_grp[i]], x[ind_grp[j]], dx); d = norm(dx); if (bConstr) { - fprintf(out, "%5d %5d %1d %10g\n", ind_grp[i]+1, ind_grp[j]+1, 2, d); + fprintf(out, "%5d %5d %1d %10g\n", ind_grp[i] + 1, ind_grp[j] + 1, 2, d); } else { @@ -228,17 +248,16 @@ int gmx_genrestr(int argc, char *argv[]) { if (disre_frac > 0) { - dd = std::min(disre_dist, disre_frac*d); + dd = std::min(disre_dist, disre_frac * d); } else { dd = disre_dist; } - lo = std::max(0.0_real, d-dd); - hi = d+dd; - fprintf(out, "%5d %5d %1d %5d %10d %10g %10g %10g %10g\n", - ind_grp[i]+1, ind_grp[j]+1, 1, k, 1, - lo, hi, hi+disre_up2, 1.0); + lo = std::max(0.0_real, d - dd); + hi = d + dd; + fprintf(out, "%5d %5d %1d %5d %10d %10g %10g %10g %10g\n", ind_grp[i] + 1, + ind_grp[j] + 1, 1, k, 1, lo, hi, hi + disre_up2, 1.0); } } } @@ -256,8 +275,7 @@ int gmx_genrestr(int argc, char *argv[]) fprintf(out, ";%3s %5s %9s %10s %10s\n", "i", "funct", "fcx", "fcy", "fcz"); for (i = 0; i < igrp; i++) { - fprintf(out, "%4d %4d %10g %10g %10g\n", - ind_grp[i]+1, 1, fc[XX], fc[YY], fc[ZZ]); + fprintf(out, "%4d %4d %10g %10g %10g\n", ind_grp[i] + 1, 1, fc[XX], fc[YY], fc[ZZ]); } gmx_ffclose(out); } diff --git a/src/gromacs/gmxpreprocess/genrestr.h b/src/gromacs/gmxpreprocess/genrestr.h index d7264fe656..9281f96ad3 100644 --- a/src/gromacs/gmxpreprocess/genrestr.h +++ b/src/gromacs/gmxpreprocess/genrestr.h @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_GENPR_H #define GMX_GMXPREPROCESS_GENPR_H -int gmx_genrestr(int argc, char *argv[]); +int gmx_genrestr(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/gmxcpp.cpp b/src/gromacs/gmxpreprocess/gmxcpp.cpp index d232b55dbf..eaebc356dd 100644 --- a/src/gromacs/gmxpreprocess/gmxcpp.cpp +++ b/src/gromacs/gmxpreprocess/gmxcpp.cpp @@ -66,24 +66,28 @@ struct t_define }; /* enum used for handling ifdefs */ -enum { - eifTRUE, eifFALSE, eifIGNORE, eifNR +enum +{ + eifTRUE, + eifFALSE, + eifIGNORE, + eifNR }; struct gmx_cpp { - std::shared_ptr < std::vector < t_define>> defines; - std::shared_ptr < std::vector < std::string>> includes; - std::unordered_set unmatched_defines; - FILE *fp = nullptr; - std::string path; - std::string cwd; - std::string fn; - std::string line; - int line_nr; - std::vector ifdefs; - struct gmx_cpp *child = nullptr; - struct gmx_cpp *parent = nullptr; + std::shared_ptr> defines; + std::shared_ptr> includes; + std::unordered_set unmatched_defines; + FILE* fp = nullptr; + std::string path; + std::string cwd; + std::string fn; + std::string line; + int line_nr; + std::vector ifdefs; + struct gmx_cpp* child = nullptr; + struct gmx_cpp* parent = nullptr; }; static bool is_word_end(char c) @@ -91,16 +95,15 @@ static bool is_word_end(char c) return !((isalnum(c) != 0) || c == '_'); } -static const char *strstrw(const char *buf, const char *word) +static const char* strstrw(const char* buf, const char* word) { - const char *ptr; + const char* ptr; while ((ptr = strstr(buf, word)) != nullptr) { /* Check if we did not find part of a longer word */ - if (ptr && - is_word_end(ptr[strlen(word)]) && - (((ptr > buf) && is_word_end(ptr[-1])) || (ptr == buf))) + if (ptr && is_word_end(ptr[strlen(word)]) + && (((ptr > buf) && is_word_end(ptr[-1])) || (ptr == buf))) { return ptr; } @@ -114,9 +117,7 @@ static const char *strstrw(const char *buf, const char *word) * returned in *name, and the remainder of the line after leading * whitespace, without trailing whitespace, is returned in *val */ -static bool find_directive(const char *buf, - std::string *name, - std::string *val) +static bool find_directive(const char* buf, std::string* name, std::string* val) { /* Skip initial whitespace */ while (isspace(*buf)) @@ -173,13 +174,12 @@ static bool is_ifdeffed_out(gmx::ArrayRef ifdefs) return (!ifdefs.empty() && ifdefs.back() != eifTRUE); } -static void add_include(std::vector *includes, - const char *includePath) +static void add_include(std::vector* includes, const char* includePath) { GMX_RELEASE_ASSERT(includes, "Need valid includes"); GMX_RELEASE_ASSERT(includePath, "Need a valid include path"); - for (const std::string &include : *includes) + for (const std::string& include : *includes) { if (strcmp(include.c_str(), includePath) == 0) { @@ -190,14 +190,12 @@ static void add_include(std::vector *includes, includes->push_back(includePath); } -static void add_define(std::vector *defines, - const std::string &name, - const char *value) +static void add_define(std::vector* defines, const std::string& name, const char* value) { GMX_RELEASE_ASSERT(defines, "Need defines"); GMX_RELEASE_ASSERT(value, "Need a value"); - for (t_define &define : *defines) + for (t_define& define : *defines) { if (define.name == name) { @@ -211,15 +209,14 @@ static void add_define(std::vector *defines, /* Open the file to be processed. The handle variable holds internal info for the cpp emulator. Return integer status */ -static int -cpp_open_file(const char *filenm, - gmx_cpp_t *handle, - char **cppopts, - std::shared_ptr < std::vector < t_define>> *definesFromParent, - std::shared_ptr < std::vector < std::string>> *includesFromParent) +static int cpp_open_file(const char* filenm, + gmx_cpp_t* handle, + char** cppopts, + std::shared_ptr>* definesFromParent, + std::shared_ptr>* includesFromParent) { // TODO: We should avoid new/delete, we should use Pimpl instead - gmx_cpp *cpp = new gmx_cpp; + gmx_cpp* cpp = new gmx_cpp; *handle = cpp; if (definesFromParent) @@ -228,7 +225,7 @@ cpp_open_file(const char *filenm, } else { - cpp->defines = std::make_shared < std::vector < t_define>>(); + cpp->defines = std::make_shared>(); } if (includesFromParent) @@ -237,7 +234,7 @@ cpp_open_file(const char *filenm, } else { - cpp->includes = std::make_shared < std::vector < std::string>>(); + cpp->includes = std::make_shared>(); } /* First process options, they might be necessary for opening files @@ -254,14 +251,13 @@ cpp_open_file(const char *filenm, if (strstr(cppopts[i], "-D") == cppopts[i]) { /* If the option contains a =, split it into name and value. */ - char *ptr = strchr(cppopts[i], '='); + char* ptr = strchr(cppopts[i], '='); if (ptr) { std::string buf = cppopts[i] + 2; buf.resize(ptr - cppopts[i] - 2); add_define(cpp->defines.get(), buf, ptr + 1); cpp->unmatched_defines.insert(buf); - } else { @@ -281,7 +277,7 @@ cpp_open_file(const char *filenm, else { /* If not, check all the paths given with -I. */ - for (const std::string &include : *cpp->includes) + for (const std::string& include : *cpp->includes) { std::string buf = include + "/" + filenm; if (gmx_fexist(buf)) @@ -324,10 +320,10 @@ cpp_open_file(const char *filenm, gmx_chdir(cpp->path.c_str()); } cpp->line.clear(); - cpp->line_nr = 0; + cpp->line_nr = 0; cpp->ifdefs.clear(); - cpp->child = nullptr; - cpp->parent = nullptr; + cpp->child = nullptr; + cpp->parent = nullptr; if (cpp->fp == nullptr) { cpp->fp = fopen(cpp->fn.c_str(), "r"); @@ -337,8 +333,7 @@ cpp_open_file(const char *filenm, switch (errno) { case EINVAL: - default: - return eCPP_UNKNOWN; + default: return eCPP_UNKNOWN; } } return eCPP_OK; @@ -346,20 +341,17 @@ cpp_open_file(const char *filenm, /* Open the file to be processed. The handle variable holds internal info for the cpp emulator. Return integer status */ -int cpp_open_file(const char *filenm, gmx_cpp_t *handle, char **cppopts) +int cpp_open_file(const char* filenm, gmx_cpp_t* handle, char** cppopts) { return cpp_open_file(filenm, handle, cppopts, nullptr, nullptr); } /* Note that dval might be null, e.g. when handling a line like '#define */ -static int -process_directive(gmx_cpp_t *handlep, - const std::string &dname, - const std::string &dval) +static int process_directive(gmx_cpp_t* handlep, const std::string& dname, const std::string& dval) { - gmx_cpp_t handle = *handlep; + gmx_cpp_t handle = *handlep; - std::vector &ifdefs = handle->ifdefs; + std::vector& ifdefs = handle->ifdefs; /* #ifdef or ifndef statement */ bool bIfdef = (dname == "ifdef"); @@ -378,7 +370,7 @@ process_directive(gmx_cpp_t *handlep, return eCPP_SYNTAX; } bool found = false; - for (const t_define &define : *handle->defines) + for (const t_define& define : *handle->defines) { if (define.name == dval) { @@ -425,7 +417,7 @@ process_directive(gmx_cpp_t *handlep, } /* #endif statement */ - if (dname == "endif") + if (dname == "endif") { if (ifdefs.empty()) { @@ -464,7 +456,7 @@ process_directive(gmx_cpp_t *handlep, { if (len == -1) { - i0 = i1+1; + i0 = i1 + 1; len = 0; } else @@ -484,8 +476,8 @@ process_directive(gmx_cpp_t *handlep, std::string inc_fn = dval.substr(i0, len); /* Open include file and store it as a child in the handle structure */ - int status = cpp_open_file(inc_fn.c_str(), &(handle->child), nullptr, - &handle->defines, &handle->includes); + int status = cpp_open_file(inc_fn.c_str(), &(handle->child), nullptr, &handle->defines, + &handle->includes); if (status != eCPP_OK) { handle->child = nullptr; @@ -506,7 +498,7 @@ process_directive(gmx_cpp_t *handlep, return eCPP_SYNTAX; } /* Split it into name and value. */ - const char *ptr = dval.c_str(); + const char* ptr = dval.c_str(); while ((*ptr != '\0') && !isspace(*ptr)) { ptr++; @@ -523,14 +515,14 @@ process_directive(gmx_cpp_t *handlep, } /* #undef statement */ - if (dname == "undef") + if (dname == "undef") { // A bare '#undef' is an invalid line if (dval.empty()) { return eCPP_SYNTAX; } - std::vector &defines = *handle->defines; + std::vector& defines = *handle->defines; for (size_t i = 0; i < defines.size(); i++) { if (defines[i].name == dval) @@ -552,11 +544,11 @@ process_directive(gmx_cpp_t *handlep, routine also does all the "intelligent" work like processing cpp directives and so on. Note that often the routine is called recursively and no cpp directives are printed. */ -int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) +int cpp_read_line(gmx_cpp_t* handlep, int n, char buf[]) { - gmx_cpp_t handle = *handlep; - int status; - bool bEOF; + gmx_cpp_t handle = *handlep; + int status; + bool bEOF; if (!handle) { @@ -571,7 +563,7 @@ int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) if (!bEOF) { /* Read the actual line now. */ - if (fgets2(buf, n-1, handle->fp) == nullptr) + if (fgets2(buf, n - 1, handle->fp) == nullptr) { /* Recheck EOF, since we could have been at the end before * the fgets2 call, but we need to read past the end to know. @@ -594,7 +586,7 @@ int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) return eCPP_EOF; } cpp_close_file(handlep); - *handlep = handle->parent; + *handlep = handle->parent; delete handle; return cpp_read_line(handlep, n, buf); } @@ -630,12 +622,12 @@ int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) that we have to use a best fit algorithm, rather than first come first go. We do this by sorting the defines on length first, and then on alphabetical order. */ - for (t_define &define : *handle->defines) + for (t_define& define : *handle->defines) { if (!define.def.empty()) { int nn = 0; - const char *ptr = buf; + const char* ptr = buf; while ((ptr = strstrw(ptr, define.name.c_str())) != nullptr) { nn++; @@ -651,14 +643,14 @@ int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) } root->unmatched_defines.erase(define.name); - std::string name; - const char *ptr = buf; - const char *ptr2; + std::string name; + const char* ptr = buf; + const char* ptr2; while ((ptr2 = strstrw(ptr, define.name.c_str())) != nullptr) { name.append(ptr, ptr2 - ptr); name += define.def; - ptr = ptr2 + define.name.size(); + ptr = ptr2 + define.name.size(); } name += ptr; GMX_RELEASE_ASSERT(name.size() < static_cast(n), @@ -671,18 +663,18 @@ int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]) return eCPP_OK; } -const char *cpp_cur_file(const gmx_cpp_t *handlep) +const char* cpp_cur_file(const gmx_cpp_t* handlep) { return (*handlep)->fn.c_str(); } -int cpp_cur_linenr(const gmx_cpp_t *handlep) +int cpp_cur_linenr(const gmx_cpp_t* handlep) { return (*handlep)->line_nr; } /* Close the file! Return integer status. */ -int cpp_close_file(gmx_cpp_t *handlep) +int cpp_close_file(gmx_cpp_t* handlep) { gmx_cpp_t handle = *handlep; @@ -708,10 +700,9 @@ int cpp_close_file(gmx_cpp_t *handlep) return eCPP_OK; } -const std::string *cpp_find_define(const gmx_cpp_t *handlep, - const std::string &defineName) +const std::string* cpp_find_define(const gmx_cpp_t* handlep, const std::string& defineName) { - for (const t_define &define : *(*handlep)->defines) + for (const t_define& define : *(*handlep)->defines) { if (define.name == defineName) { @@ -734,19 +725,24 @@ void cpp_done(gmx_cpp_t handle) /* Return a string containing the error message coresponding to status variable */ -char *cpp_error(gmx_cpp_t *handlep, int status) +char* cpp_error(gmx_cpp_t* handlep, int status) { char buf[256]; - const char *ecpp[] = { - "OK", "File not found", "End of file", "Syntax error", "Interrupted", - "Invalid file handle", "Invalid delimiter for filename in #include statement", - "File not open", "Unknown error, perhaps your text file uses wrong line endings?", "Error status out of range" - }; + const char* ecpp[] = { "OK", + "File not found", + "End of file", + "Syntax error", + "Interrupted", + "Invalid file handle", + "Invalid delimiter for filename in #include statement", + "File not open", + "Unknown error, perhaps your text file uses wrong line endings?", + "Error status out of range" }; gmx_cpp_t handle = *handlep; if (!handle) { - return const_cast(ecpp[eCPP_INVALID_HANDLE]); + return const_cast(ecpp[eCPP_INVALID_HANDLE]); } if ((status < 0) || (status >= eCPP_NR)) @@ -754,28 +750,29 @@ char *cpp_error(gmx_cpp_t *handlep, int status) status = eCPP_NR; } - sprintf(buf, "%s - File %s, line %d\nLast line read:\n'%s'", - ecpp[status], + sprintf(buf, "%s - File %s, line %d\nLast line read:\n'%s'", ecpp[status], (handle && !handle->fn.empty()) ? handle->fn.c_str() : "unknown", - (handle) ? handle->line_nr : -1, - !handle->line.empty() ? handle->line.c_str() : ""); + (handle) ? handle->line_nr : -1, !handle->line.empty() ? handle->line.c_str() : ""); return gmx_strdup(buf); } -std::string checkAndWarnForUnusedDefines(const gmx_cpp &handle) +std::string checkAndWarnForUnusedDefines(const gmx_cpp& handle) { std::string warning; if (!handle.unmatched_defines.empty()) { - warning = "The following macros were defined in the 'define' mdp field with the -D prefix, but " - "were not used in the topology:\n"; - for (auto &str : handle.unmatched_defines) + warning = + "The following macros were defined in the 'define' mdp field with the -D prefix, " + "but " + "were not used in the topology:\n"; + for (auto& str : handle.unmatched_defines) { warning += (" " + str + "\n"); } - warning += "If you haven't made a spelling error, either use the macro you defined, " - "or don't define the macro"; + warning += + "If you haven't made a spelling error, either use the macro you defined, " + "or don't define the macro"; } return warning; } diff --git a/src/gromacs/gmxpreprocess/gmxcpp.h b/src/gromacs/gmxpreprocess/gmxcpp.h index 988dd1a23a..a97a72b909 100644 --- a/src/gromacs/gmxpreprocess/gmxcpp.h +++ b/src/gromacs/gmxpreprocess/gmxcpp.h @@ -40,42 +40,49 @@ #include -typedef struct gmx_cpp *gmx_cpp_t; +typedef struct gmx_cpp* gmx_cpp_t; /* The possible return codes for these functions */ -enum { - eCPP_OK, eCPP_FILE_NOT_FOUND, eCPP_EOF, eCPP_SYNTAX, eCPP_INTERRUPT, - eCPP_INVALID_HANDLE, eCPP_INVALID_INCLUDE_DELIMITER, - eCPP_FILE_NOT_OPEN, eCPP_UNKNOWN, eCPP_NR +enum +{ + eCPP_OK, + eCPP_FILE_NOT_FOUND, + eCPP_EOF, + eCPP_SYNTAX, + eCPP_INTERRUPT, + eCPP_INVALID_HANDLE, + eCPP_INVALID_INCLUDE_DELIMITER, + eCPP_FILE_NOT_OPEN, + eCPP_UNKNOWN, + eCPP_NR }; /* Open the file to be processed. The handle variable holds internal info for the cpp emulator. The cppopt variable (null terminated) can hold cpp options like -IXXX and -DXXX. Return integer status. */ -int cpp_open_file(const char *filenm, gmx_cpp_t *handlep, char **cppopts); +int cpp_open_file(const char* filenm, gmx_cpp_t* handlep, char** cppopts); /* Return one whole line from the file into buf which holds at most n characters, for subsequent processing. Returns integer status. */ -int cpp_read_line(gmx_cpp_t *handlep, int n, char buf[]); +int cpp_read_line(gmx_cpp_t* handlep, int n, char buf[]); /* Return the file currently being read. */ -const char *cpp_cur_file(const gmx_cpp_t *handlep); +const char* cpp_cur_file(const gmx_cpp_t* handlep); /* Return the current line number. */ -int cpp_cur_linenr(const gmx_cpp_t *handlep); +int cpp_cur_linenr(const gmx_cpp_t* handlep); /* Close the file! Return integer status. */ -int cpp_close_file(gmx_cpp_t *handlep); +int cpp_close_file(gmx_cpp_t* handlep); /* Return a pointer to the value of defineName, when present, nullptr othwerwise. */ -const std::string *cpp_find_define(const gmx_cpp_t *handlep, - const std::string &defineName); +const std::string* cpp_find_define(const gmx_cpp_t* handlep, const std::string& defineName); /* Clean up normal and file static data structures */ @@ -84,10 +91,10 @@ void cpp_done(gmx_cpp_t handle); /* Return a string containing the error message coresponding to status variable. */ -char *cpp_error(gmx_cpp_t *handlep, int status); +char* cpp_error(gmx_cpp_t* handlep, int status); /* Returns warning message if strings defined in mdp define section (e.g. -DFLEXIBLE) * were not not found when processing the topology */ -std::string checkAndWarnForUnusedDefines(const gmx_cpp &handle); +std::string checkAndWarnForUnusedDefines(const gmx_cpp& handle); #endif diff --git a/src/gromacs/gmxpreprocess/gpp_atomtype.cpp b/src/gromacs/gmxpreprocess/gpp_atomtype.cpp index 1cf8bad2c4..d5b65c5c35 100644 --- a/src/gromacs/gmxpreprocess/gpp_atomtype.cpp +++ b/src/gromacs/gmxpreprocess/gpp_atomtype.cpp @@ -58,35 +58,33 @@ struct AtomTypeData { //! Explicit constructor. - AtomTypeData(const t_atom &a, - char **name, - const InteractionOfType &nb, - const int bondAtomType, - const int atomNumber) : - atom_(a), name_(name), nb_(nb), + AtomTypeData(const t_atom& a, char** name, const InteractionOfType& nb, const int bondAtomType, const int atomNumber) : + atom_(a), + name_(name), + nb_(nb), bondAtomType_(bondAtomType), atomNumber_(atomNumber) { } //! Actual atom data. - t_atom atom_; + t_atom atom_; //! Atom name. - char **name_; + char** name_; //! Nonbonded data. - InteractionOfType nb_; + InteractionOfType nb_; //! Bonded atomtype for the type. - int bondAtomType_; + int bondAtomType_; //! Atom number for the atom type. - int atomNumber_; + int atomNumber_; }; class PreprocessingAtomTypes::Impl { - public: - //! The number for currently loaded entries. - size_t size() const { return types.size(); } - //! The actual atom type data. - std::vector types; +public: + //! The number for currently loaded entries. + size_t size() const { return types.size(); } + //! The actual atom type data. + std::vector types; }; bool PreprocessingAtomTypes::isSet(int nt) const @@ -94,12 +92,11 @@ bool PreprocessingAtomTypes::isSet(int nt) const return ((nt >= 0) && (nt < gmx::ssize(*this))); } -int PreprocessingAtomTypes::atomTypeFromName(const std::string &str) const +int PreprocessingAtomTypes::atomTypeFromName(const std::string& str) const { /* Atom types are always case sensitive */ auto found = std::find_if(impl_->types.begin(), impl_->types.end(), - [&str](const auto &type) - { return str == *type.name_; }); + [&str](const auto& type) { return str == *type.name_; }); if (found == impl_->types.end()) { return NOTSET; @@ -115,7 +112,7 @@ size_t PreprocessingAtomTypes::size() const return impl_->size(); } -const char *PreprocessingAtomTypes::atomNameFromAtomType(int nt) const +const char* PreprocessingAtomTypes::atomNameFromAtomType(int nt) const { return isSet(nt) ? *(impl_->types[nt].name_) : nullptr; } @@ -159,38 +156,32 @@ real PreprocessingAtomTypes::atomNonBondedParamFromAtomType(int nt, int param) c return forceParam[param]; } -PreprocessingAtomTypes::PreprocessingAtomTypes() - : impl_(new Impl) -{} +PreprocessingAtomTypes::PreprocessingAtomTypes() : impl_(new Impl) {} -PreprocessingAtomTypes::PreprocessingAtomTypes(PreprocessingAtomTypes &&old) noexcept - : impl_(std::move(old.impl_)) -{} +PreprocessingAtomTypes::PreprocessingAtomTypes(PreprocessingAtomTypes&& old) noexcept : + impl_(std::move(old.impl_)) +{ +} -PreprocessingAtomTypes &PreprocessingAtomTypes::operator=(PreprocessingAtomTypes &&old) noexcept +PreprocessingAtomTypes& PreprocessingAtomTypes::operator=(PreprocessingAtomTypes&& old) noexcept { impl_ = std::move(old.impl_); return *this; } -PreprocessingAtomTypes::~PreprocessingAtomTypes() -{} +PreprocessingAtomTypes::~PreprocessingAtomTypes() {} -int PreprocessingAtomTypes::addType(t_symtab *tab, - const t_atom &a, - const std::string &name, - const InteractionOfType &nb, +int PreprocessingAtomTypes::addType(t_symtab* tab, + const t_atom& a, + const std::string& name, + const InteractionOfType& nb, int bondAtomType, int atomNumber) { int position = atomTypeFromName(name); if (position == NOTSET) { - impl_->types.emplace_back(a, - put_symtab(tab, name.c_str()), - nb, - bondAtomType, - atomNumber); + impl_->types.emplace_back(a, put_symtab(tab, name.c_str()), nb, bondAtomType, atomNumber); return atomTypeFromName(name); } else @@ -200,10 +191,10 @@ int PreprocessingAtomTypes::addType(t_symtab *tab, } int PreprocessingAtomTypes::setType(int nt, - t_symtab *tab, - const t_atom &a, - const std::string &name, - const InteractionOfType &nb, + t_symtab* tab, + const t_atom& a, + const std::string& name, + const InteractionOfType& nb, int bondAtomType, int atomNumber) { @@ -221,23 +212,22 @@ int PreprocessingAtomTypes::setType(int nt, return nt; } -void PreprocessingAtomTypes::printTypes(FILE * out) +void PreprocessingAtomTypes::printTypes(FILE* out) { - fprintf (out, "[ %s ]\n", dir2str(Directive::d_atomtypes)); - fprintf (out, "; %6s %8s %8s %8s %12s %12s\n", - "type", "mass", "charge", "particle", "c6", "c12"); - for (auto &entry : impl_->types) + fprintf(out, "[ %s ]\n", dir2str(Directive::d_atomtypes)); + fprintf(out, "; %6s %8s %8s %8s %12s %12s\n", "type", "mass", "charge", "particle", "c6", + "c12"); + for (auto& entry : impl_->types) { - fprintf(out, "%8s %8.3f %8.3f %8s %12e %12e\n", - *(entry.name_), entry.atom_.m, entry.atom_.q, "A", - entry.nb_.c0(), entry.nb_.c1()); + fprintf(out, "%8s %8.3f %8.3f %8s %12e %12e\n", *(entry.name_), entry.atom_.m, + entry.atom_.q, "A", entry.nb_.c0(), entry.nb_.c1()); } - fprintf (out, "\n"); + fprintf(out, "\n"); } -static int search_atomtypes(const PreprocessingAtomTypes *ga, - int *n, +static int search_atomtypes(const PreprocessingAtomTypes* ga, + int* n, gmx::ArrayRef typelist, int thistype, gmx::ArrayRef interactionTypes, @@ -262,17 +252,17 @@ static int search_atomtypes(const PreprocessingAtomTypes *ga, for (int j = 0; j < ntype && bFound; j++) { /* Check nonbonded parameters */ - gmx::ArrayRef forceParam1 = interactionTypes[ntype*typelist[i]+j].forceParam(); - gmx::ArrayRef forceParam2 = interactionTypes[ntype*thistype+j].forceParam(); + gmx::ArrayRef forceParam1 = + interactionTypes[ntype * typelist[i] + j].forceParam(); + gmx::ArrayRef forceParam2 = interactionTypes[ntype * thistype + j].forceParam(); for (int k = 0; (k < nrfp) && bFound; k++) { bFound = forceParam1[k] == forceParam2[k]; } /* Check atomnumber */ - int tli = typelist[i]; - bFound = bFound && - (ga->atomNumberFromAtomType(tli) == ga->atomNumberFromAtomType(thistype)); + int tli = typelist[i]; + bFound = bFound && (ga->atomNumberFromAtomType(tli) == ga->atomNumberFromAtomType(thistype)); } if (bFound) { @@ -294,12 +284,12 @@ static int search_atomtypes(const PreprocessingAtomTypes *ga, return i; } -void PreprocessingAtomTypes::renumberTypes(gmx::ArrayRef plist, - gmx_mtop_t *mtop, - int *wall_atomtype, - bool bVerbose) +void PreprocessingAtomTypes::renumberTypes(gmx::ArrayRef plist, + gmx_mtop_t* mtop, + int* wall_atomtype, + bool bVerbose) { - int nat, ftype, ntype; + int nat, ftype, ntype; ntype = size(); std::vector typelist(ntype); @@ -332,17 +322,15 @@ void PreprocessingAtomTypes::renumberTypes(gmx::ArrayRef * can determine if two types should be merged. */ nat = 0; - for (const gmx_moltype_t &moltype : mtop->moltype) + for (const gmx_moltype_t& moltype : mtop->moltype) { - const t_atoms *atoms = &moltype.atoms; + const t_atoms* atoms = &moltype.atoms; for (int i = 0; (i < atoms->nr); i++) { - atoms->atom[i].type = - search_atomtypes(this, &nat, typelist, atoms->atom[i].type, - plist[ftype].interactionTypes, ftype); - atoms->atom[i].typeB = - search_atomtypes(this, &nat, typelist, atoms->atom[i].typeB, - plist[ftype].interactionTypes, ftype); + atoms->atom[i].type = search_atomtypes(this, &nat, typelist, atoms->atom[i].type, + plist[ftype].interactionTypes, ftype); + atoms->atom[i].typeB = search_atomtypes(this, &nat, typelist, atoms->atom[i].typeB, + plist[ftype].interactionTypes, ftype); } } @@ -367,8 +355,9 @@ void PreprocessingAtomTypes::renumberTypes(gmx::ArrayRef for (int j = 0; (j < nat); j++) { int mj = typelist[j]; - const InteractionOfType &interactionType = plist[ftype].interactionTypes[ntype*mi+mj]; - nbsnew.emplace_back(interactionType.atoms(), interactionType.forceParam(), interactionType.interactionTypeName()); + const InteractionOfType& interactionType = plist[ftype].interactionTypes[ntype * mi + mj]; + nbsnew.emplace_back(interactionType.atoms(), interactionType.forceParam(), + interactionType.interactionTypeName()); } new_types.push_back(impl_->types[mi]); } @@ -379,10 +368,10 @@ void PreprocessingAtomTypes::renumberTypes(gmx::ArrayRef plist[ftype].interactionTypes = nbsnew; } -void PreprocessingAtomTypes::copyTot_atomtypes(t_atomtypes *atomtypes) const +void PreprocessingAtomTypes::copyTot_atomtypes(t_atomtypes* atomtypes) const { /* Copy the atomtype data to the topology atomtype list */ - int ntype = size(); + int ntype = size(); atomtypes->nr = ntype; snew(atomtypes->atomnumber, ntype); diff --git a/src/gromacs/gmxpreprocess/gpp_atomtype.h b/src/gromacs/gmxpreprocess/gpp_atomtype.h index 8869f72702..2ced59ad23 100644 --- a/src/gromacs/gmxpreprocess/gpp_atomtype.h +++ b/src/gromacs/gmxpreprocess/gpp_atomtype.h @@ -65,163 +65,161 @@ struct t_symtab; */ class PreprocessingAtomTypes { - public: - PreprocessingAtomTypes(); - //! Move constructor. - PreprocessingAtomTypes(PreprocessingAtomTypes &&old) noexcept; - //! Move assignment constructor. - PreprocessingAtomTypes &operator=(PreprocessingAtomTypes &&old) noexcept; - - ~PreprocessingAtomTypes(); - - /*! \brief - * Get atom type index for atom type name if present in the database, or NOTSET. - * - * \todo The code should be changed to instead use a gmx::compat version - * of std::optional to return an iterator to the element being searched, - * or an empty optional construct if the entry has not been found. - * - * \param[in] str Input string to search type for. - * \returns Atomtype as integer. - */ - int atomTypeFromName(const std::string &str) const; - - //! Get number of defined atom types. - size_t size() const; - - /*! \brief - * Get name of atom from internal atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The type name. - */ - const char *atomNameFromAtomType(int nt) const; - - /*! \brief - * Get normal mass of atom from internal atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The mass for the atom or NOTSET. - */ - real atomMassFromAtomType(int nt) const; - - /*! \brief - * Get normal charge of atom from internal atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The charge for the atom or NOTSET. - */ - real atomChargeFromAtomType(int nt) const; - - /*! \brief - * Get particle type for atom type \p nt - * - * \param[in] nt Internal number of atom type. - * \returns The particle type or NOTSET. - */ - int atomParticleTypeFromAtomType(int nt) const; - - /*! \brief - * Get bond atom parameter of atom from internal atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The bond atom parameter or NOTSET. - */ - int bondAtomTypeFromAtomType(int nt) const; - - /*! \brief - * Get atomic number of atom from internal atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The atomic number type or NOTSET. - */ - int atomNumberFromAtomType(int nt) const; - - /*! \brief - * Get the value of \p param of type \p nt. - * - * \param[in] param The parameter value to find. - * \param[in] nt The number of the type. - * \returns The value of the parameter or NOTSET. - */ - real atomNonBondedParamFromAtomType(int nt, int param) const; - - /*! \brief - * If a value is within the range of the current types or not. - * - * \param[in] nt Value to check. - * \returns True if value is in range. - */ - bool isSet(int nt) const; - - /*! \brief - * Print data to file. - * - * \param[in] out File pointer. - */ - void printTypes(FILE *out); - - /*! \brief - * Set the values of an existing atom type \p nt. - * - * \param[in] nt Type that should be set. - * \param[in] tab Symbol table. - * \param[in] a Atom information. - * \param[in] name Atom name. - * \param[in] nb Nonbonded parameters. - * \param[in] bondAtomType What kind of bonded interactions are there. - * \param[in] atomNumber Atomic number of the entry. - * \returns Number of the type set or NOTSET - */ - int setType(int nt, - t_symtab *tab, - const t_atom &a, - const std::string &name, - const InteractionOfType &nb, - int bondAtomType, - int atomNumber); - - /*! \brief - * Add new atom type to database. - * - * \param[in] tab Symbol table. - * \param[in] a Atom information. - * \param[in] name Atom name. - * \param[in] nb Nonbonded parameters. - * \param[in] bondAtomType What kind of bonded interactions are there. - * \param[in] atomNumber Atomic number of the entry. - * \returns Number of entries in database. - */ - int addType(t_symtab *tab, - const t_atom &a, - const std::string &name, - const InteractionOfType &nb, - int bondAtomType, - int atomNumber); - - /*! \brief - * Renumber existing atom type entries. - * - * \param[in] plist List of parameters. - * \param[in] mtop Global topology. - * \param[inout] wallAtomType Atom types of wall atoms, which may also be renumbered - * \param[in] verbose If we want to print additional info. - */ - void renumberTypes(gmx::ArrayRef plist, - gmx_mtop_t *mtop, - int *wallAtomType, - bool verbose); - - /*! \brief - * Copy information to other structure. - * - * \param[inout] atypes Other datastructure to copy to. - */ - void copyTot_atomtypes(t_atomtypes *atypes) const; - private: - class Impl; - //! Pimpl that holds the data. - gmx::PrivateImplPointer impl_; +public: + PreprocessingAtomTypes(); + //! Move constructor. + PreprocessingAtomTypes(PreprocessingAtomTypes&& old) noexcept; + //! Move assignment constructor. + PreprocessingAtomTypes& operator=(PreprocessingAtomTypes&& old) noexcept; + + ~PreprocessingAtomTypes(); + + /*! \brief + * Get atom type index for atom type name if present in the database, or NOTSET. + * + * \todo The code should be changed to instead use a gmx::compat version + * of std::optional to return an iterator to the element being searched, + * or an empty optional construct if the entry has not been found. + * + * \param[in] str Input string to search type for. + * \returns Atomtype as integer. + */ + int atomTypeFromName(const std::string& str) const; + + //! Get number of defined atom types. + size_t size() const; + + /*! \brief + * Get name of atom from internal atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The type name. + */ + const char* atomNameFromAtomType(int nt) const; + + /*! \brief + * Get normal mass of atom from internal atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The mass for the atom or NOTSET. + */ + real atomMassFromAtomType(int nt) const; + + /*! \brief + * Get normal charge of atom from internal atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The charge for the atom or NOTSET. + */ + real atomChargeFromAtomType(int nt) const; + + /*! \brief + * Get particle type for atom type \p nt + * + * \param[in] nt Internal number of atom type. + * \returns The particle type or NOTSET. + */ + int atomParticleTypeFromAtomType(int nt) const; + + /*! \brief + * Get bond atom parameter of atom from internal atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The bond atom parameter or NOTSET. + */ + int bondAtomTypeFromAtomType(int nt) const; + + /*! \brief + * Get atomic number of atom from internal atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The atomic number type or NOTSET. + */ + int atomNumberFromAtomType(int nt) const; + + /*! \brief + * Get the value of \p param of type \p nt. + * + * \param[in] param The parameter value to find. + * \param[in] nt The number of the type. + * \returns The value of the parameter or NOTSET. + */ + real atomNonBondedParamFromAtomType(int nt, int param) const; + + /*! \brief + * If a value is within the range of the current types or not. + * + * \param[in] nt Value to check. + * \returns True if value is in range. + */ + bool isSet(int nt) const; + + /*! \brief + * Print data to file. + * + * \param[in] out File pointer. + */ + void printTypes(FILE* out); + + /*! \brief + * Set the values of an existing atom type \p nt. + * + * \param[in] nt Type that should be set. + * \param[in] tab Symbol table. + * \param[in] a Atom information. + * \param[in] name Atom name. + * \param[in] nb Nonbonded parameters. + * \param[in] bondAtomType What kind of bonded interactions are there. + * \param[in] atomNumber Atomic number of the entry. + * \returns Number of the type set or NOTSET + */ + int setType(int nt, + t_symtab* tab, + const t_atom& a, + const std::string& name, + const InteractionOfType& nb, + int bondAtomType, + int atomNumber); + + /*! \brief + * Add new atom type to database. + * + * \param[in] tab Symbol table. + * \param[in] a Atom information. + * \param[in] name Atom name. + * \param[in] nb Nonbonded parameters. + * \param[in] bondAtomType What kind of bonded interactions are there. + * \param[in] atomNumber Atomic number of the entry. + * \returns Number of entries in database. + */ + int addType(t_symtab* tab, + const t_atom& a, + const std::string& name, + const InteractionOfType& nb, + int bondAtomType, + int atomNumber); + + /*! \brief + * Renumber existing atom type entries. + * + * \param[in] plist List of parameters. + * \param[in] mtop Global topology. + * \param[inout] wallAtomType Atom types of wall atoms, which may also be renumbered + * \param[in] verbose If we want to print additional info. + */ + void renumberTypes(gmx::ArrayRef plist, gmx_mtop_t* mtop, int* wallAtomType, bool verbose); + + /*! \brief + * Copy information to other structure. + * + * \param[inout] atypes Other datastructure to copy to. + */ + void copyTot_atomtypes(t_atomtypes* atypes) const; + +private: + class Impl; + //! Pimpl that holds the data. + gmx::PrivateImplPointer impl_; }; #endif diff --git a/src/gromacs/gmxpreprocess/gpp_bond_atomtype.cpp b/src/gromacs/gmxpreprocess/gpp_bond_atomtype.cpp index 8376d5890d..4d083506b7 100644 --- a/src/gromacs/gmxpreprocess/gpp_bond_atomtype.cpp +++ b/src/gromacs/gmxpreprocess/gpp_bond_atomtype.cpp @@ -50,17 +50,17 @@ class PreprocessingBondAtomType::Impl { - public: - //! The atom type names. - std::vector typeNames; +public: + //! The atom type names. + std::vector typeNames; }; -int PreprocessingBondAtomType::bondAtomTypeFromName(const std::string &str) const +int PreprocessingBondAtomType::bondAtomTypeFromName(const std::string& str) const { /* Atom types are always case sensitive */ - auto found = std::find_if(impl_->typeNames.begin(), impl_->typeNames.end(), - [&str](const auto &type) - { return str == const_cast(*type); }); + auto found = + std::find_if(impl_->typeNames.begin(), impl_->typeNames.end(), + [&str](const auto& type) { return str == const_cast(*type); }); if (found == impl_->typeNames.end()) { return NOTSET; @@ -71,20 +71,16 @@ int PreprocessingBondAtomType::bondAtomTypeFromName(const std::string &str) cons } } -const char *PreprocessingBondAtomType::atomNameFromBondAtomType(int nt) const +const char* PreprocessingBondAtomType::atomNameFromBondAtomType(int nt) const { return isSet(nt) ? *impl_->typeNames[nt] : nullptr; } -PreprocessingBondAtomType::PreprocessingBondAtomType() - : impl_(new Impl) -{} +PreprocessingBondAtomType::PreprocessingBondAtomType() : impl_(new Impl) {} -PreprocessingBondAtomType::~PreprocessingBondAtomType() -{} +PreprocessingBondAtomType::~PreprocessingBondAtomType() {} -int PreprocessingBondAtomType::addBondAtomType(t_symtab *tab, - const std::string &name) +int PreprocessingBondAtomType::addBondAtomType(t_symtab* tab, const std::string& name) { int position = bondAtomTypeFromName(name); if (position == NOTSET) diff --git a/src/gromacs/gmxpreprocess/gpp_bond_atomtype.h b/src/gromacs/gmxpreprocess/gpp_bond_atomtype.h index 6ac9b2c788..3c1220dc42 100644 --- a/src/gromacs/gmxpreprocess/gpp_bond_atomtype.h +++ b/src/gromacs/gmxpreprocess/gpp_bond_atomtype.h @@ -59,55 +59,54 @@ struct t_symtab; */ class PreprocessingBondAtomType { - public: - PreprocessingBondAtomType(); - ~PreprocessingBondAtomType(); +public: + PreprocessingBondAtomType(); + ~PreprocessingBondAtomType(); - //! Get number of defined bond atom types. - size_t size() const; + //! Get number of defined bond atom types. + size_t size() const; - /*! \brief - * Get name of atom from internal bond atom type number. - * - * \param[in] nt Internal number of atom type. - * \returns The type name. - */ - const char *atomNameFromBondAtomType(int nt) const; + /*! \brief + * Get name of atom from internal bond atom type number. + * + * \param[in] nt Internal number of atom type. + * \returns The type name. + */ + const char* atomNameFromBondAtomType(int nt) const; - /*! \brief - * Get bond atom type index for atom type name if present in the database, or NOTSET. - * - * \todo The code should be changed to instead use a gmx::compat version - * of std::optional to return a handle to the element being searched, - * or an empty optional construct if the entry has not been found. - * - * \param[in] str Input string to search type for. - * \returns Atomtype as integer. - */ - int bondAtomTypeFromName(const std::string &str) const; + /*! \brief + * Get bond atom type index for atom type name if present in the database, or NOTSET. + * + * \todo The code should be changed to instead use a gmx::compat version + * of std::optional to return a handle to the element being searched, + * or an empty optional construct if the entry has not been found. + * + * \param[in] str Input string to search type for. + * \returns Atomtype as integer. + */ + int bondAtomTypeFromName(const std::string& str) const; - /*! \brief - * Add a complete new bond atom type. - * - * \param[in] tab Symbol table. - * \param[in] name Atom name. - * \returns The number of entries in database or the type number of an already set type. - */ - int addBondAtomType(t_symtab *tab, - const std::string &name); + /*! \brief + * Add a complete new bond atom type. + * + * \param[in] tab Symbol table. + * \param[in] name Atom name. + * \returns The number of entries in database or the type number of an already set type. + */ + int addBondAtomType(t_symtab* tab, const std::string& name); - /*! \brief - * If a value is within the range of the current types or not. - * - * \param[in] nt Value to check. - * \returns True if value is in range. - */ - bool isSet(int nt) const; + /*! \brief + * If a value is within the range of the current types or not. + * + * \param[in] nt Value to check. + * \returns True if value is in range. + */ + bool isSet(int nt) const; - private: - class Impl; - //! Pimpl that holds the data. - gmx::PrivateImplPointer impl_; +private: + class Impl; + //! Pimpl that holds the data. + gmx::PrivateImplPointer impl_; }; #endif diff --git a/src/gromacs/gmxpreprocess/gpp_nextnb.cpp b/src/gromacs/gmxpreprocess/gpp_nextnb.cpp index 8154db2ab8..19aa460d27 100644 --- a/src/gromacs/gmxpreprocess/gpp_nextnb.cpp +++ b/src/gromacs/gmxpreprocess/gpp_nextnb.cpp @@ -50,12 +50,12 @@ /* #define DEBUG_NNB */ -typedef struct { +typedef struct +{ int ai, aj; } sortable; -static int -bond_sort (const void *a, const void *b) +static int bond_sort(const void* a, const void* b) { const sortable *sa, *sb; @@ -64,24 +64,23 @@ bond_sort (const void *a, const void *b) if (sa->ai == sb->ai) { - return (sa->aj-sb->aj); + return (sa->aj - sb->aj); } else { - return (sa->ai-sb->ai); + return (sa->ai - sb->ai); } } -static int -compare_int (const void * a, const void * b) +static int compare_int(const void* a, const void* b) { - return ( *reinterpret_cast(a) - *reinterpret_cast(b) ); + return (*reinterpret_cast(a) - *reinterpret_cast(b)); } #ifdef DEBUG -#define prints(str, n, s) __prints(str, n, s) -static void __prints(char *str, int n, sortable *s) +# define prints(str, n, s) __prints(str, n, s) +static void __prints(char* str, int n, sortable* s) { int i; @@ -98,10 +97,10 @@ static void __prints(char *str, int n, sortable *s) } } #else -#define prints(str, n, s) +# define prints(str, n, s) #endif -void init_nnb(t_nextnb *nnb, int nr, int nrex) +void init_nnb(t_nextnb* nnb, int nr, int nrex) { int i; @@ -113,19 +112,19 @@ void init_nnb(t_nextnb *nnb, int nr, int nrex) snew(nnb->nrexcl, nr); for (i = 0; (i < nr); i++) { - snew(nnb->a[i], nrex+1); - snew(nnb->nrexcl[i], nrex+1); + snew(nnb->a[i], nrex + 1); + snew(nnb->nrexcl[i], nrex + 1); } } -static void add_nnb (t_nextnb *nnb, int nre, int i, int j) +static void add_nnb(t_nextnb* nnb, int nre, int i, int j) { - srenew(nnb->a[i][nre], nnb->nrexcl[i][nre]+1); + srenew(nnb->a[i][nre], nnb->nrexcl[i][nre] + 1); nnb->a[i][nre][nnb->nrexcl[i][nre]] = j; nnb->nrexcl[i][nre]++; } -void done_nnb (t_nextnb *nnb) +void done_nnb(t_nextnb* nnb) { int i, nre; @@ -135,20 +134,20 @@ void done_nnb (t_nextnb *nnb) { if (nnb->nrexcl[i][nre] > 0) { - sfree (nnb->a[i][nre]); + sfree(nnb->a[i][nre]); } } - sfree (nnb->nrexcl[i]); - sfree (nnb->a[i]); + sfree(nnb->nrexcl[i]); + sfree(nnb->a[i]); } - sfree (nnb->a); - sfree (nnb->nrexcl); + sfree(nnb->a); + sfree(nnb->nrexcl); nnb->nr = 0; nnb->nrex = 0; } #ifdef DEBUG_NNB -void __print_nnb(t_nextnb *nnb, char *s) +void __print_nnb(t_nextnb* nnb, char* s) { int i, j, k; @@ -173,13 +172,13 @@ void __print_nnb(t_nextnb *nnb, char *s) } #endif -static void nnb2excl(t_nextnb *nnb, t_blocka *excl) +static void nnb2excl(t_nextnb* nnb, t_blocka* excl) { int i, j, j_index; int nre, nrx, nrs, nr_of_sortables; - sortable *s; + sortable* s; - srenew(excl->index, nnb->nr+1); + srenew(excl->index, nnb->nr + 1); excl->index[0] = 0; for (i = 0; (i < nnb->nr); i++) { @@ -211,7 +210,7 @@ static void nnb2excl(t_nextnb *nnb, t_blocka *excl) prints("nnb2excl before qsort", nr_of_sortables, s); if (nr_of_sortables > 1) { - qsort (s, nr_of_sortables, static_cast(sizeof(s[0])), bond_sort); + qsort(s, nr_of_sortables, static_cast(sizeof(s[0])), bond_sort); prints("nnb2excl after qsort", nr_of_sortables, s); } @@ -221,29 +220,29 @@ static void nnb2excl(t_nextnb *nnb, t_blocka *excl) { for (j = 1; (j < nr_of_sortables); j++) { - if ((s[j].ai != s[j-1].ai) || (s[j].aj != s[j-1].aj)) + if ((s[j].ai != s[j - 1].ai) || (s[j].aj != s[j - 1].aj)) { - s[j_index++] = s[j-1]; + s[j_index++] = s[j - 1]; } } - s[j_index++] = s[j-1]; + s[j_index++] = s[j - 1]; } nr_of_sortables = j_index; prints("after rm-double", j_index, s); /* make space for arrays */ - srenew(excl->a, excl->nra+nr_of_sortables); + srenew(excl->a, excl->nra + nr_of_sortables); /* put the sorted exclusions in the target list */ for (nrs = 0; (nrs < nr_of_sortables); nrs++) { - excl->a[excl->nra+nrs] = s[nrs].aj; + excl->a[excl->nra + nrs] = s[nrs].aj; } - excl->nra += nr_of_sortables; - excl->index[i+1] = excl->nra; + excl->nra += nr_of_sortables; + excl->index[i + 1] = excl->nra; /* cleanup temporary space */ - sfree (s); + sfree(s); } } @@ -264,11 +263,7 @@ static void nnb2excl(t_nextnb *nnb, t_blocka *excl) * the routine will return true if the query atom is already listed as * first or second neighbor (exclusion) in nnb. */ -static bool -atom_is_present_in_nnb(const t_nextnb * nnb, - int atom, - int highest_order, - int query) +static bool atom_is_present_in_nnb(const t_nextnb* nnb, int atom, int highest_order, int query) { GMX_RELEASE_ASSERT(highest_order < nnb->nrex, "Inconsistent nnb seach parameters"); @@ -286,8 +281,8 @@ atom_is_present_in_nnb(const t_nextnb * nnb, } static void do_gen(int nrbonds, /* total number of bonds in s */ - sortable *s, /* bidirectional list of bonds */ - t_nextnb *nnb) /* the tmp storage for excl */ + sortable* s, /* bidirectional list of bonds */ + t_nextnb* nnb) /* the tmp storage for excl */ /* Assume excl is initalised and s[] contains all bonds bidirectional */ { int i, j, k, n, nb; @@ -330,27 +325,25 @@ static void do_gen(int nrbonds, /* total number of bonds in s */ // with high exclusion order if (!atom_is_present_in_nnb(nnb, i, n, nnb->a[nb][n][k])) { - add_nnb(nnb, n+1, i, nnb->a[nb][n][k]); + add_nnb(nnb, n + 1, i, nnb->a[nb][n][k]); } } } } } print_nnb(nnb, "After exclude rest"); - } -static void add_b(InteractionsOfType *bonds, int *nrf, sortable *s) +static void add_b(InteractionsOfType* bonds, int* nrf, sortable* s) { int i = 0; - for (const auto &bond : bonds->interactionTypes) + for (const auto& bond : bonds->interactionTypes) { int ai = bond.ai(); int aj = bond.aj(); if ((ai < 0) || (aj < 0)) { - gmx_fatal(FARGS, "Impossible atom numbers in bond %d: ai=%d, aj=%d", - i, ai, aj); + gmx_fatal(FARGS, "Impossible atom numbers in bond %d: ai=%d, aj=%d", i, ai, aj); } /* Add every bond twice */ s[(*nrf)].ai = ai; @@ -361,9 +354,9 @@ static void add_b(InteractionsOfType *bonds, int *nrf, sortable *s) } } -void gen_nnb(t_nextnb *nnb, gmx::ArrayRef plist) +void gen_nnb(t_nextnb* nnb, gmx::ArrayRef plist) { - sortable *s; + sortable* s; int nrbonds, nrf; nrbonds = 0; @@ -372,7 +365,7 @@ void gen_nnb(t_nextnb *nnb, gmx::ArrayRef plist) if (IS_CHEMBOND(i)) { /* we need every bond twice (bidirectional) */ - nrbonds += 2*plist[i].size(); + nrbonds += 2 * plist[i].size(); } } @@ -399,8 +392,7 @@ void gen_nnb(t_nextnb *nnb, gmx::ArrayRef plist) sfree(s); } -static void -sort_and_purge_nnb(t_nextnb *nnb) +static void sort_and_purge_nnb(t_nextnb* nnb) { int i, j, k, m, n, cnt, prev, idx; bool found; @@ -440,10 +432,7 @@ sort_and_purge_nnb(t_nextnb *nnb) } -void generate_excl (int nrexcl, - int nratoms, - gmx::ArrayRef plist, - t_blocka *excl) +void generate_excl(int nrexcl, int nratoms, gmx::ArrayRef plist, t_blocka* excl) { t_nextnb nnb; if (nrexcl < 0) @@ -454,6 +443,6 @@ void generate_excl (int nrexcl, gen_nnb(&nnb, plist); excl->nr = nratoms; sort_and_purge_nnb(&nnb); - nnb2excl (&nnb, excl); + nnb2excl(&nnb, excl); done_nnb(&nnb); } diff --git a/src/gromacs/gmxpreprocess/gpp_nextnb.h b/src/gromacs/gmxpreprocess/gpp_nextnb.h index 80779f7687..4d014cdf97 100644 --- a/src/gromacs/gmxpreprocess/gpp_nextnb.h +++ b/src/gromacs/gmxpreprocess/gpp_nextnb.h @@ -45,39 +45,37 @@ struct InteractionsOfType; struct t_nextnb { - int nr; /* nr atoms (0 <= i < nr) (atoms->nr) */ - int nrex; /* with nrex lists of neighbours */ + int nr; /* nr atoms (0 <= i < nr) (atoms->nr) */ + int nrex; /* with nrex lists of neighbours */ /* respectively containing zeroth, first */ /* second etc. neigbours (0 <= nre < nrex) */ - int **nrexcl; /* with (0 <= nrx < nrexcl[i][nre]) neigbours */ + int** nrexcl; /* with (0 <= nrx < nrexcl[i][nre]) neigbours */ /* per list stored in one 2d array of lists */ - int ***a; /* like this: a[i][nre][nrx] */ + int*** a; /* like this: a[i][nre][nrx] */ }; -void init_nnb(t_nextnb *nnb, int nr, int nrex); +void init_nnb(t_nextnb* nnb, int nr, int nrex); /* Initiate the arrays for nnb (see above) */ -void done_nnb(t_nextnb *nnb); +void done_nnb(t_nextnb* nnb); /* Cleanup the nnb struct */ #ifdef DEBUG_NNB -#define print_nnb(nnb, s) __print_nnb(nnb, s) -void print_nnb(t_nextnb *nnb, char *s); +# define print_nnb(nnb, s) __print_nnb(nnb, s) +void print_nnb(t_nextnb* nnb, char* s); /* Print the nnb struct */ #else -#define print_nnb(nnb, s) +# define print_nnb(nnb, s) #endif -void gen_nnb(t_nextnb *nnb, gmx::ArrayRef plist); +void gen_nnb(t_nextnb* nnb, gmx::ArrayRef plist); /* Generate a t_nextnb structure from bond information. * With the structure you can either generate exclusions * or generate angles and dihedrals. The structure must be * initiated using init_nnb. */ -void generate_excl(int nrexcl, int nratoms, - gmx::ArrayRef plist, - t_blocka *excl); +void generate_excl(int nrexcl, int nratoms, gmx::ArrayRef plist, t_blocka* excl); /* Generate an exclusion block from bonds and constraints in * plist. */ diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index 11755e631f..3922eeb01c 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -109,12 +109,14 @@ /* TODO The implementation details should move to their own source file. */ InteractionOfType::InteractionOfType(gmx::ArrayRef atoms, gmx::ArrayRef params, - const std::string &name) - : atoms_(atoms.begin(), atoms.end()), - interactionTypeName_(name) + const std::string& name) : + atoms_(atoms.begin(), atoms.end()), + interactionTypeName_(name) { - GMX_RELEASE_ASSERT(params.size() <= forceParam_.size(), - gmx::formatString("Cannot have more parameters than the maximum number possible (%d)", MAXFORCEPARAM).c_str()); + GMX_RELEASE_ASSERT( + params.size() <= forceParam_.size(), + gmx::formatString("Cannot have more parameters than the maximum number possible (%d)", MAXFORCEPARAM) + .c_str()); auto forceParamIt = forceParam_.begin(); for (const auto param : params) { @@ -126,52 +128,52 @@ InteractionOfType::InteractionOfType(gmx::ArrayRef atoms, } } -const int &InteractionOfType::ai() const +const int& InteractionOfType::ai() const { GMX_RELEASE_ASSERT(!atoms_.empty(), "Need to have at least one atom set"); return atoms_[0]; } -const int &InteractionOfType::aj() const +const int& InteractionOfType::aj() const { GMX_RELEASE_ASSERT(atoms_.size() > 1, "Need to have at least two atoms set"); return atoms_[1]; } -const int &InteractionOfType::ak() const +const int& InteractionOfType::ak() const { GMX_RELEASE_ASSERT(atoms_.size() > 2, "Need to have at least three atoms set"); return atoms_[2]; } -const int &InteractionOfType::al() const +const int& InteractionOfType::al() const { GMX_RELEASE_ASSERT(atoms_.size() > 3, "Need to have at least four atoms set"); return atoms_[3]; } -const int &InteractionOfType::am() const +const int& InteractionOfType::am() const { GMX_RELEASE_ASSERT(atoms_.size() > 4, "Need to have at least five atoms set"); return atoms_[4]; } -const real &InteractionOfType::c0() const +const real& InteractionOfType::c0() const { return forceParam_[0]; } -const real &InteractionOfType::c1() const +const real& InteractionOfType::c1() const { return forceParam_[1]; } -const real &InteractionOfType::c2() const +const real& InteractionOfType::c2() const { return forceParam_[2]; } -const std::string &InteractionOfType::interactionTypeName() const +const std::string& InteractionOfType::interactionTypeName() const { return interactionTypeName_; } @@ -217,13 +219,15 @@ void InteractionOfType::sortAtomIds() } else { - GMX_THROW(gmx::InternalError("Can not sort parameters other than bonds, angles or dihedrals")); + GMX_THROW(gmx::InternalError( + "Can not sort parameters other than bonds, angles or dihedrals")); } }; void InteractionOfType::setForceParameter(int pos, real value) { - GMX_RELEASE_ASSERT(pos < MAXFORCEPARAM, "Can't set parameter beyond the maximum number of parameters"); + GMX_RELEASE_ASSERT(pos < MAXFORCEPARAM, + "Can't set parameter beyond the maximum number of parameters"); forceParam_[pos] = value; } @@ -241,7 +245,7 @@ void MoleculeInformation::partialCleanUp() void MoleculeInformation::fullCleanUp() { - done_atom (&atoms); + done_atom(&atoms); done_block(&mols); } @@ -249,19 +253,18 @@ static int rm_interactions(int ifunc, gmx::ArrayRef mols) { int n = 0; /* For all the molecule types */ - for (auto &mol : mols) + for (auto& mol : mols) { - n += mol.interactions[ifunc].size(); + n += mol.interactions[ifunc].size(); mol.interactions[ifunc].interactionTypes.clear(); } return n; } -static int check_atom_names(const char *fn1, const char *fn2, - gmx_mtop_t *mtop, const t_atoms *at) +static int check_atom_names(const char* fn1, const char* fn2, gmx_mtop_t* mtop, const t_atoms* at) { int m, i, j, nmismatch; - t_atoms *tat; + t_atoms* tat; #define MAXMISMATCH 20 if (mtop->natoms != at->nr) @@ -271,20 +274,20 @@ static int check_atom_names(const char *fn1, const char *fn2, nmismatch = 0; i = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { tat = &mtop->moltype[molb.type].atoms; for (m = 0; m < molb.nmol; m++) { for (j = 0; j < tat->nr; j++) { - if (strcmp( *(tat->atomname[j]), *(at->atomname[i]) ) != 0) + if (strcmp(*(tat->atomname[j]), *(at->atomname[i])) != 0) { if (nmismatch < MAXMISMATCH) { fprintf(stderr, "Warning: atom name %d in %s and %s does not match (%s - %s)\n", - i+1, fn1, fn2, *(tat->atomname[j]), *(at->atomname[i])); + i + 1, fn1, fn2, *(tat->atomname[j]), *(at->atomname[i])); } else if (nmismatch == MAXMISMATCH) { @@ -300,7 +303,7 @@ static int check_atom_names(const char *fn1, const char *fn2, return nmismatch; } -static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) +static void check_bonds_timestep(const gmx_mtop_t* mtop, double dt, warninp* wi) { /* This check is not intended to ensure accurate integration, * rather it is to signal mistakes in the mdp settings. @@ -320,31 +323,31 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) * of dt=1 fs without constraints and dt=2 fs with only H-bond constraints * we set the note limit to 10. */ - int min_steps_warn = 5; - int min_steps_note = 10; - int ftype; - int i, a1, a2, w_a1, w_a2, j; - real twopi2, limit2, fc, re, m1, m2, period2, w_period2; - bool bFound, bWater, bWarn; - char warn_buf[STRLEN]; + int min_steps_warn = 5; + int min_steps_note = 10; + int ftype; + int i, a1, a2, w_a1, w_a2, j; + real twopi2, limit2, fc, re, m1, m2, period2, w_period2; + bool bFound, bWater, bWarn; + char warn_buf[STRLEN]; /* Get the interaction parameters */ gmx::ArrayRef ip = mtop->ffparams.iparams; - twopi2 = gmx::square(2*M_PI); + twopi2 = gmx::square(2 * M_PI); - limit2 = gmx::square(min_steps_note*dt); + limit2 = gmx::square(min_steps_note * dt); - w_a1 = w_a2 = -1; - w_period2 = -1.0; + w_a1 = w_a2 = -1; + w_period2 = -1.0; - const gmx_moltype_t *w_moltype = nullptr; - for (const gmx_moltype_t &moltype : mtop->moltype) + const gmx_moltype_t* w_moltype = nullptr; + for (const gmx_moltype_t& moltype : mtop->moltype) { - const t_atom *atom = moltype.atoms.atom; - const InteractionLists &ilist = moltype.ilist; - const InteractionList &ilc = ilist[F_CONSTR]; - const InteractionList &ils = ilist[F_SETTLE]; + const t_atom* atom = moltype.atoms.atom; + const InteractionLists& ilist = moltype.ilist; + const InteractionList& ilc = ilist[F_CONSTR]; + const InteractionList& ils = ilist[F_SETTLE]; for (ftype = 0; ftype < F_NRE; ftype++) { if (!(ftype == F_BONDS || ftype == F_G96BONDS || ftype == F_HARMONIC)) @@ -352,7 +355,7 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) continue; } - const InteractionList &ilb = ilist[ftype]; + const InteractionList& ilb = ilist[ftype]; for (i = 0; i < ilb.size(); i += 3) { fc = ip[ilb.iatoms[i]].harmonic.krA; @@ -360,15 +363,15 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) if (ftype == F_G96BONDS) { /* Convert squared sqaure fc to harmonic fc */ - fc = 2*fc*re; + fc = 2 * fc * re; } - a1 = ilb.iatoms[i+1]; - a2 = ilb.iatoms[i+2]; + a1 = ilb.iatoms[i + 1]; + a2 = ilb.iatoms[i + 2]; m1 = atom[a1].m; m2 = atom[a2].m; if (fc > 0 && m1 > 0 && m2 > 0) { - period2 = twopi2*m1*m2/((m1 + m2)*fc); + period2 = twopi2 * m1 * m2 / ((m1 + m2) * fc); } else { @@ -376,30 +379,29 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) } if (debug) { - fprintf(debug, "fc %g m1 %g m2 %g period %g\n", - fc, m1, m2, std::sqrt(period2)); + fprintf(debug, "fc %g m1 %g m2 %g period %g\n", fc, m1, m2, std::sqrt(period2)); } if (period2 < limit2) { bFound = false; for (j = 0; j < ilc.size(); j += 3) { - if ((ilc.iatoms[j+1] == a1 && ilc.iatoms[j+2] == a2) || - (ilc.iatoms[j+1] == a2 && ilc.iatoms[j+2] == a1)) + if ((ilc.iatoms[j + 1] == a1 && ilc.iatoms[j + 2] == a2) + || (ilc.iatoms[j + 1] == a2 && ilc.iatoms[j + 2] == a1)) { bFound = true; } } for (j = 0; j < ils.size(); j += 4) { - if ((a1 == ils.iatoms[j+1] || a1 == ils.iatoms[j+2] || a1 == ils.iatoms[j+3]) && - (a2 == ils.iatoms[j+1] || a2 == ils.iatoms[j+2] || a2 == ils.iatoms[j+3])) + if ((a1 == ils.iatoms[j + 1] || a1 == ils.iatoms[j + 2] || a1 == ils.iatoms[j + 3]) + && (a2 == ils.iatoms[j + 1] || a2 == ils.iatoms[j + 2] + || a2 == ils.iatoms[j + 3])) { bFound = true; } } - if (!bFound && - (w_moltype == nullptr || period2 < w_period2)) + if (!bFound && (w_moltype == nullptr || period2 < w_period2)) { w_moltype = &moltype; w_a1 = a1; @@ -413,19 +415,19 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) if (w_moltype != nullptr) { - bWarn = (w_period2 < gmx::square(min_steps_warn*dt)); + bWarn = (w_period2 < gmx::square(min_steps_warn * dt)); /* A check that would recognize most water models */ - bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' && - w_moltype->atoms.nr <= 5); - sprintf(warn_buf, "The bond in molecule-type %s between atoms %d %s and %d %s has an estimated oscillational period of %.1e ps, which is less than %d times the time step of %.1e ps.\n" + bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' && w_moltype->atoms.nr <= 5); + sprintf(warn_buf, + "The bond in molecule-type %s between atoms %d %s and %d %s has an estimated " + "oscillational period of %.1e ps, which is less than %d times the time step of " + "%.1e ps.\n" "%s", - *w_moltype->name, - w_a1+1, *w_moltype->atoms.atomname[w_a1], - w_a2+1, *w_moltype->atoms.atomname[w_a2], - std::sqrt(w_period2), bWarn ? min_steps_warn : min_steps_note, dt, - bWater ? - "Maybe you asked for fexible water." : - "Maybe you forgot to change the constraints mdp option."); + *w_moltype->name, w_a1 + 1, *w_moltype->atoms.atomname[w_a1], w_a2 + 1, + *w_moltype->atoms.atomname[w_a2], std::sqrt(w_period2), + bWarn ? min_steps_warn : min_steps_note, dt, + bWater ? "Maybe you asked for fexible water." + : "Maybe you forgot to change the constraints mdp option."); if (bWarn) { warning(wi, warn_buf); @@ -437,33 +439,28 @@ static void check_bonds_timestep(const gmx_mtop_t *mtop, double dt, warninp *wi) } } -static void check_vel(gmx_mtop_t *mtop, rvec v[]) +static void check_vel(gmx_mtop_t* mtop, rvec v[]) { for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); - if (local.ptype == eptShell || - local.ptype == eptBond || - local.ptype == eptVSite) + if (local.ptype == eptShell || local.ptype == eptBond || local.ptype == eptVSite) { clear_rvec(v[i]); } } } -static void check_shells_inputrec(gmx_mtop_t *mtop, - t_inputrec *ir, - warninp *wi) +static void check_shells_inputrec(gmx_mtop_t* mtop, t_inputrec* ir, warninp* wi) { - int nshells = 0; - char warn_buf[STRLEN]; + int nshells = 0; + char warn_buf[STRLEN]; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); - if (local.ptype == eptShell || - local.ptype == eptBond) + const t_atom& local = atomP.atom(); + if (local.ptype == eptShell || local.ptype == eptBond) { nshells++; } @@ -471,8 +468,7 @@ static void check_shells_inputrec(gmx_mtop_t *mtop, if ((nshells > 0) && (ir->nstcalcenergy != 1)) { set_warning_line(wi, "unknown", -1); - snprintf(warn_buf, STRLEN, - "There are %d shells, changing nstcalcenergy from %d to 1", + snprintf(warn_buf, STRLEN, "There are %d shells, changing nstcalcenergy from %d to 1", nshells, ir->nstcalcenergy); ir->nstcalcenergy = 1; warning(wi, warn_buf); @@ -481,12 +477,12 @@ static void check_shells_inputrec(gmx_mtop_t *mtop, /* TODO Decide whether this function can be consolidated with * gmx_mtop_ftype_count */ -static int nint_ftype(gmx_mtop_t *mtop, gmx::ArrayRef mi, int ftype) +static int nint_ftype(gmx_mtop_t* mtop, gmx::ArrayRef mi, int ftype) { int nint = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - nint += molb.nmol*mi[molb.type].interactions[ftype].size(); + nint += molb.nmol * mi[molb.type].interactions[ftype].size(); } return nint; @@ -496,16 +492,15 @@ static int nint_ftype(gmx_mtop_t *mtop, gmx::ArrayRef * in the order of use in the molblocks, * unused molecule types are deleted. */ -static void renumber_moltypes(gmx_mtop_t *sys, - std::vector *molinfo) +static void renumber_moltypes(gmx_mtop_t* sys, std::vector* molinfo) { std::vector order; - for (gmx_molblock_t &molblock : sys->molblock) + for (gmx_molblock_t& molblock : sys->molblock) { - const auto found = std::find_if(order.begin(), order.end(), - [&molblock](const auto &entry) - { return molblock.type == entry; }); + const auto found = std::find_if(order.begin(), order.end(), [&molblock](const auto& entry) { + return molblock.type == entry; + }); if (found == order.end()) { /* This type did not occur yet, add it */ @@ -520,13 +515,13 @@ static void renumber_moltypes(gmx_mtop_t *sys, /* We still need to reorder the molinfo structs */ std::vector minew(order.size()); - int index = 0; - for (auto &mi : *molinfo) + int index = 0; + for (auto& mi : *molinfo) { const auto found = std::find(order.begin(), order.end(), index); if (found != order.end()) { - int pos = std::distance(order.begin(), found); + int pos = std::distance(order.begin(), found); minew[pos] = mi; } else @@ -537,58 +532,61 @@ static void renumber_moltypes(gmx_mtop_t *sys, index++; } - *molinfo = minew; + *molinfo = minew; } -static void molinfo2mtop(gmx::ArrayRef mi, gmx_mtop_t *mtop) +static void molinfo2mtop(gmx::ArrayRef mi, gmx_mtop_t* mtop) { mtop->moltype.resize(mi.size()); int pos = 0; - for (const auto &mol : mi) + for (const auto& mol : mi) { - gmx_moltype_t &molt = mtop->moltype[pos]; + gmx_moltype_t& molt = mtop->moltype[pos]; molt.name = mol.name; molt.atoms = mol.atoms; /* ilists are copied later */ - molt.excls = mol.excls; + molt.excls = mol.excls; pos++; } } -static void -new_status(const char *topfile, const char *topppfile, const char *confin, - t_gromppopts *opts, t_inputrec *ir, gmx_bool bZero, - bool bGenVel, bool bVerbose, t_state *state, - PreprocessingAtomTypes *atypes, gmx_mtop_t *sys, - std::vector *mi, - std::unique_ptr *intermolecular_interactions, - gmx::ArrayRef interactions, - int *comb, double *reppow, real *fudgeQQ, - gmx_bool bMorse, - warninp *wi) +static void new_status(const char* topfile, + const char* topppfile, + const char* confin, + t_gromppopts* opts, + t_inputrec* ir, + gmx_bool bZero, + bool bGenVel, + bool bVerbose, + t_state* state, + PreprocessingAtomTypes* atypes, + gmx_mtop_t* sys, + std::vector* mi, + std::unique_ptr* intermolecular_interactions, + gmx::ArrayRef interactions, + int* comb, + double* reppow, + real* fudgeQQ, + gmx_bool bMorse, + warninp* wi) { - std::vector molblock; - int i, nmismatch; - bool ffParametrizedWithHBondConstraints; - char buf[STRLEN]; - char warn_buf[STRLEN]; + std::vector molblock; + int i, nmismatch; + bool ffParametrizedWithHBondConstraints; + char buf[STRLEN]; + char warn_buf[STRLEN]; /* TOPOLOGY processing */ - sys->name = do_top(bVerbose, topfile, topppfile, opts, bZero, &(sys->symtab), - interactions, comb, reppow, fudgeQQ, - atypes, mi, intermolecular_interactions, - ir, - &molblock, - &ffParametrizedWithHBondConstraints, - wi); + sys->name = do_top(bVerbose, topfile, topppfile, opts, bZero, &(sys->symtab), interactions, + comb, reppow, fudgeQQ, atypes, mi, intermolecular_interactions, ir, + &molblock, &ffParametrizedWithHBondConstraints, wi); sys->molblock.clear(); sys->natoms = 0; - for (const gmx_molblock_t &molb : molblock) + for (const gmx_molblock_t& molb : molblock) { - if (!sys->molblock.empty() && - molb.type == sys->molblock.back().type) + if (!sys->molblock.empty() && molb.type == sys->molblock.back().type) { /* Merge consecutive blocks with the same molecule type */ sys->molblock.back().nmol += molb.nmol; @@ -598,7 +596,7 @@ new_status(const char *topfile, const char *topppfile, const char *confin, /* Add a new molblock to the topology */ sys->molblock.push_back(molb); } - sys->natoms += molb.nmol*(*mi)[sys->molblock.back().type].atoms.nr; + sys->natoms += molb.nmol * (*mi)[sys->molblock.back().type].atoms.nr; } if (sys->molblock.empty()) { @@ -642,15 +640,15 @@ new_status(const char *topfile, const char *topppfile, const char *confin, * to all bonds with force fields that have been parametrized with H-bond * constraints only. Do not print note with large timesteps or vsites. */ - if (opts->nshake == eshALLBONDS && - ffParametrizedWithHBondConstraints && - ir->delta_t < 0.0026 && - gmx_mtop_ftype_count(sys, F_VSITE3FD) == 0) + if (opts->nshake == eshALLBONDS && ffParametrizedWithHBondConstraints && ir->delta_t < 0.0026 + && gmx_mtop_ftype_count(sys, F_VSITE3FD) == 0) { set_warning_line(wi, "unknown", -1); - warning_note(wi, "You are using constraints on all bonds, whereas the forcefield " + warning_note(wi, + "You are using constraints on all bonds, whereas the forcefield " "has been parametrized only with constraints involving hydrogen atoms. " - "We suggest using constraints = h-bonds instead, this will also improve performance."); + "We suggest using constraints = h-bonds instead, this will also improve " + "performance."); } /* COORDINATE file processing */ @@ -659,15 +657,16 @@ new_status(const char *topfile, const char *topppfile, const char *confin, fprintf(stderr, "processing coordinates...\n"); } - t_topology *conftop; - rvec *x = nullptr; - rvec *v = nullptr; + t_topology* conftop; + rvec* x = nullptr; + rvec* v = nullptr; snew(conftop, 1); read_tps_conf(confin, conftop, nullptr, &x, &v, state->box, FALSE); state->natoms = conftop->atoms.nr; if (state->natoms != sys->natoms) { - gmx_fatal(FARGS, "number of coordinates in coordinate file (%s, %d)\n" + gmx_fatal(FARGS, + "number of coordinates in coordinate file (%s, %d)\n" " does not match topology (%s, %d)", confin, state->natoms, topfile, sys->natoms); } @@ -680,11 +679,11 @@ new_status(const char *topfile, const char *topppfile, const char *confin, state->flags |= (1 << estV); } state_change_natoms(state, state->natoms); - std::copy(x, x+state->natoms, state->x.data()); + std::copy(x, x + state->natoms, state->x.data()); sfree(x); if (v != nullptr) { - std::copy(v, v+state->natoms, state->v.data()); + std::copy(v, v + state->natoms, state->v.data()); sfree(v); } /* This call fixes the box shape for runs with pressure scaling */ @@ -696,7 +695,8 @@ new_status(const char *topfile, const char *topppfile, const char *confin, if (nmismatch) { - sprintf(buf, "%d non-matching atom name%s\n" + sprintf(buf, + "%d non-matching atom name%s\n" "atom names from %s will be used\n" "atom names from %s will be ignored\n", nmismatch, (nmismatch == 1) ? "" : "s", topfile, confin); @@ -709,25 +709,22 @@ new_status(const char *topfile, const char *topppfile, const char *confin, fprintf(stderr, "double-checking input for internal consistency...\n"); } { - bool bHasNormalConstraints = 0 < (nint_ftype(sys, *mi, F_CONSTR) + - nint_ftype(sys, *mi, F_CONSTRNC)); + bool bHasNormalConstraints = + 0 < (nint_ftype(sys, *mi, F_CONSTR) + nint_ftype(sys, *mi, F_CONSTRNC)); bool bHasAnyConstraints = bHasNormalConstraints || 0 < nint_ftype(sys, *mi, F_SETTLE); - double_check(ir, state->box, - bHasNormalConstraints, - bHasAnyConstraints, - wi); + double_check(ir, state->box, bHasNormalConstraints, bHasAnyConstraints, wi); } if (bGenVel) { - real *mass; + real* mass; snew(mass, state->natoms); for (const AtomProxy atomP : AtomRange(*sys)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); - mass[i] = local.m; + mass[i] = local.m; } if (opts->seed == -1) @@ -743,9 +740,7 @@ new_status(const char *topfile, const char *topppfile, const char *confin, } } -static void copy_state(const char *slog, t_trxframe *fr, - bool bReadVel, t_state *state, - double *use_time) +static void copy_state(const char* slog, t_trxframe* fr, bool bReadVel, t_state* state, double* use_time) { if (fr->not_ok & FRAME_NOT_OK) { @@ -753,18 +748,17 @@ static void copy_state(const char *slog, t_trxframe *fr, } if (!fr->bX) { - gmx_fatal(FARGS, "Did not find a frame with coordinates in file %s", - slog); + gmx_fatal(FARGS, "Did not find a frame with coordinates in file %s", slog); } - std::copy(fr->x, fr->x+state->natoms, state->x.data()); + std::copy(fr->x, fr->x + state->natoms, state->x.data()); if (bReadVel) { if (!fr->bV) { gmx_incons("Trajecory frame unexpectedly does not contain velocities"); } - std::copy(fr->v, fr->v+state->natoms, state->v.data()); + std::copy(fr->v, fr->v + state->natoms, state->v.data()); } if (fr->bBox) { @@ -774,22 +768,25 @@ static void copy_state(const char *slog, t_trxframe *fr, *use_time = fr->time; } -static void cont_status(const char *slog, const char *ener, - bool bNeedVel, bool bGenVel, real fr_time, - t_inputrec *ir, t_state *state, - gmx_mtop_t *sys, - const gmx_output_env_t *oenv) +static void cont_status(const char* slog, + const char* ener, + bool bNeedVel, + bool bGenVel, + real fr_time, + t_inputrec* ir, + t_state* state, + gmx_mtop_t* sys, + const gmx_output_env_t* oenv) /* If fr_time == -1 read the last frame available which is complete */ { bool bReadVel; t_trxframe fr; - t_trxstatus *fp; + t_trxstatus* fp; double use_time; bReadVel = (bNeedVel && !bGenVel); - fprintf(stderr, - "Reading Coordinates%s and Box size from old trajectory\n", + fprintf(stderr, "Reading Coordinates%s and Box size from old trajectory\n", bReadVel ? ", Velocities" : ""); if (fr_time == -1) { @@ -803,7 +800,8 @@ static void cont_status(const char *slog, const char *ener, { if (bGenVel) { - fprintf(stderr, "Velocities generated: " + fprintf(stderr, + "Velocities generated: " "ignoring velocities in input trajectory\n"); } read_first_frame(oenv, &fp, slog, &fr, TRX_NEED_X); @@ -817,10 +815,11 @@ static void cont_status(const char *slog, const char *ener, fprintf(stderr, "\n" "WARNING: Did not find a frame with velocities in file %s,\n" - " all velocities will be set to zero!\n\n", slog); - for (auto &vi : makeArrayRef(state->v)) + " all velocities will be set to zero!\n\n", + slog); + for (auto& vi : makeArrayRef(state->v)) { - vi = {0, 0, 0}; + vi = { 0, 0, 0 }; } close_trx(fp); /* Search for a frame without velocities */ @@ -833,14 +832,14 @@ static void cont_status(const char *slog, const char *ener, if (sys->natoms != state->natoms) { - gmx_fatal(FARGS, "Number of atoms in Topology " + gmx_fatal(FARGS, + "Number of atoms in Topology " "is not the same as in Trajectory"); } copy_state(slog, &fr, bReadVel, state, &use_time); /* Find the appropriate frame */ - while ((fr_time == -1 || fr.time < fr_time) && - read_next_frame(oenv, fp, &fr)) + while ((fr_time == -1 || fr.time < fr_time) && read_next_frame(oenv, fp, &fr)) { copy_state(slog, &fr, bReadVel, state, &use_time); } @@ -856,31 +855,32 @@ static void cont_status(const char *slog, const char *ener, fprintf(stderr, "Using frame at t = %g ps\n", use_time); fprintf(stderr, "Starting time for run is %g ps\n", ir->init_t); - if ((ir->epc != epcNO || ir->etc == etcNOSEHOOVER) && ener) + if ((ir->epc != epcNO || ir->etc == etcNOSEHOOVER) && ener) { get_enx_state(ener, use_time, sys->groups, ir, state); preserve_box_shape(ir, state->box_rel, state->boxv); } } -static void read_posres(gmx_mtop_t *mtop, +static void read_posres(gmx_mtop_t* mtop, gmx::ArrayRef molinfo, - gmx_bool bTopB, - const char *fn, - int rc_scaling, int ePBC, - rvec com, - warninp *wi) + gmx_bool bTopB, + const char* fn, + int rc_scaling, + int ePBC, + rvec com, + warninp* wi) { - gmx_bool *hadAtom; - rvec *x, *v; - dvec sum; - double totmass; - t_topology *top; - matrix box, invbox; - int natoms, npbcdim = 0; - char warn_buf[STRLEN]; - int a, nat_molb; - t_atom *atom; + gmx_bool* hadAtom; + rvec * x, *v; + dvec sum; + double totmass; + t_topology* top; + matrix box, invbox; + int natoms, npbcdim = 0; + char warn_buf[STRLEN]; + int a, nat_molb; + t_atom* atom; snew(top, 1); read_tps_conf(fn, top, nullptr, &x, &v, box, FALSE); @@ -889,7 +889,10 @@ static void read_posres(gmx_mtop_t *mtop, sfree(top); if (natoms != mtop->natoms) { - sprintf(warn_buf, "The number of atoms in %s (%d) does not match the number of atoms in the topology (%d). Will assume that the first %d atoms in the topology and %s match.", fn, natoms, mtop->natoms, std::min(mtop->natoms, natoms), fn); + sprintf(warn_buf, + "The number of atoms in %s (%d) does not match the number of atoms in the topology " + "(%d). Will assume that the first %d atoms in the topology and %s match.", + fn, natoms, mtop->natoms, std::min(mtop->natoms, natoms), fn); warning(wi, warn_buf); } @@ -912,21 +915,23 @@ static void read_posres(gmx_mtop_t *mtop, totmass = 0; a = 0; snew(hadAtom, natoms); - for (gmx_molblock_t &molb : mtop->molblock) + for (gmx_molblock_t& molb : mtop->molblock) { - nat_molb = molb.nmol*mtop->moltype[molb.type].atoms.nr; - const InteractionsOfType *pr = &(molinfo[molb.type].interactions[F_POSRES]); - const InteractionsOfType *prfb = &(molinfo[molb.type].interactions[F_FBPOSRES]); + nat_molb = molb.nmol * mtop->moltype[molb.type].atoms.nr; + const InteractionsOfType* pr = &(molinfo[molb.type].interactions[F_POSRES]); + const InteractionsOfType* prfb = &(molinfo[molb.type].interactions[F_FBPOSRES]); if (pr->size() > 0 || prfb->size() > 0) { atom = mtop->moltype[molb.type].atoms.atom; - for (const auto &restraint : pr->interactionTypes) + for (const auto& restraint : pr->interactionTypes) { int ai = restraint.ai(); if (ai >= natoms) { - gmx_fatal(FARGS, "Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n", - ai+1, *molinfo[molb.type].name, fn, natoms); + gmx_fatal(FARGS, + "Position restraint atom index (%d) in moltype '%s' is larger than " + "number of atoms in %s (%d).\n", + ai + 1, *molinfo[molb.type].name, fn, natoms); } hadAtom[ai] = TRUE; if (rc_scaling == erscCOM) @@ -934,28 +939,30 @@ static void read_posres(gmx_mtop_t *mtop, /* Determine the center of mass of the posres reference coordinates */ for (int j = 0; j < npbcdim; j++) { - sum[j] += atom[ai].m*x[a+ai][j]; + sum[j] += atom[ai].m * x[a + ai][j]; } - totmass += atom[ai].m; + totmass += atom[ai].m; } } /* Same for flat-bottomed posres, but do not count an atom twice for COM */ - for (const auto &restraint : prfb->interactionTypes) + for (const auto& restraint : prfb->interactionTypes) { int ai = restraint.ai(); if (ai >= natoms) { - gmx_fatal(FARGS, "Position restraint atom index (%d) in moltype '%s' is larger than number of atoms in %s (%d).\n", - ai+1, *molinfo[molb.type].name, fn, natoms); + gmx_fatal(FARGS, + "Position restraint atom index (%d) in moltype '%s' is larger than " + "number of atoms in %s (%d).\n", + ai + 1, *molinfo[molb.type].name, fn, natoms); } if (rc_scaling == erscCOM && !hadAtom[ai]) { /* Determine the center of mass of the posres reference coordinates */ for (int j = 0; j < npbcdim; j++) { - sum[j] += atom[ai].m*x[a+ai][j]; + sum[j] += atom[ai].m * x[a + ai][j]; } - totmass += atom[ai].m; + totmass += atom[ai].m; } } if (!bTopB) @@ -963,7 +970,7 @@ static void read_posres(gmx_mtop_t *mtop, molb.posres_xA.resize(nat_molb); for (int i = 0; i < nat_molb; i++) { - copy_rvec(x[a+i], molb.posres_xA[i]); + copy_rvec(x[a + i], molb.posres_xA[i]); } } else @@ -971,7 +978,7 @@ static void read_posres(gmx_mtop_t *mtop, molb.posres_xB.resize(nat_molb); for (int i = 0; i < nat_molb; i++) { - copy_rvec(x[a+i], molb.posres_xB[i]); + copy_rvec(x[a + i], molb.posres_xB[i]); } } } @@ -985,21 +992,23 @@ static void read_posres(gmx_mtop_t *mtop, } for (int j = 0; j < npbcdim; j++) { - com[j] = sum[j]/totmass; + com[j] = sum[j] / totmass; } - fprintf(stderr, "The center of mass of the position restraint coord's is %6.3f %6.3f %6.3f\n", com[XX], com[YY], com[ZZ]); + fprintf(stderr, + "The center of mass of the position restraint coord's is %6.3f %6.3f %6.3f\n", + com[XX], com[YY], com[ZZ]); } if (rc_scaling != erscNO) { GMX_ASSERT(npbcdim <= DIM, "Only DIM dimensions can have PBC"); - for (gmx_molblock_t &molb : mtop->molblock) + for (gmx_molblock_t& molb : mtop->molblock) { - nat_molb = molb.nmol*mtop->moltype[molb.type].atoms.nr; + nat_molb = molb.nmol * mtop->moltype[molb.type].atoms.nr; if (!molb.posres_xA.empty() || !molb.posres_xB.empty()) { - std::vector &xp = (!bTopB ? molb.posres_xA : molb.posres_xB); + std::vector& xp = (!bTopB ? molb.posres_xA : molb.posres_xB); for (int i = 0; i < nat_molb; i++) { for (int j = 0; j < npbcdim; j++) @@ -1008,9 +1017,9 @@ static void read_posres(gmx_mtop_t *mtop, { /* Convert from Cartesian to crystal coordinates */ xp[i][j] *= invbox[j][j]; - for (int k = j+1; k < npbcdim; k++) + for (int k = j + 1; k < npbcdim; k++) { - xp[i][j] += invbox[k][j]*xp[i][k]; + xp[i][j] += invbox[k][j] * xp[i][k]; } } else if (rc_scaling == erscCOM) @@ -1029,9 +1038,9 @@ static void read_posres(gmx_mtop_t *mtop, for (int j = 0; j < npbcdim; j++) { com[j] *= invbox[j][j]; - for (int k = j+1; k < npbcdim; k++) + for (int k = j + 1; k < npbcdim; k++) { - com[j] += invbox[k][j]*com[k]; + com[j] += invbox[k][j] * com[k]; } } } @@ -1042,12 +1051,15 @@ static void read_posres(gmx_mtop_t *mtop, sfree(hadAtom); } -static void gen_posres(gmx_mtop_t *mtop, +static void gen_posres(gmx_mtop_t* mtop, gmx::ArrayRef mi, - const char *fnA, const char *fnB, - int rc_scaling, int ePBC, - rvec com, rvec comB, - warninp *wi) + const char* fnA, + const char* fnB, + int rc_scaling, + int ePBC, + rvec com, + rvec comB, + warninp* wi) { read_posres(mtop, mi, FALSE, fnA, rc_scaling, ePBC, com, wi); /* It is safer to simply read the b-state posres rather than trying @@ -1056,8 +1068,7 @@ static void gen_posres(gmx_mtop_t *mtop, read_posres(mtop, mi, TRUE, fnB, rc_scaling, ePBC, comB, wi); } -static void set_wall_atomtype(PreprocessingAtomTypes *at, t_gromppopts *opts, - t_inputrec *ir, warninp *wi) +static void set_wall_atomtype(PreprocessingAtomTypes* at, t_gromppopts* opts, t_inputrec* ir, warninp* wi) { int i; char warn_buf[STRLEN]; @@ -1077,7 +1088,7 @@ static void set_wall_atomtype(PreprocessingAtomTypes *at, t_gromppopts *opts, } } -static int nrdf_internal(const t_atoms *atoms) +static int nrdf_internal(const t_atoms* atoms) { int i, nmass, nrdf; @@ -1085,30 +1096,23 @@ static int nrdf_internal(const t_atoms *atoms) for (i = 0; i < atoms->nr; i++) { /* Vsite ptype might not be set here yet, so also check the mass */ - if ((atoms->atom[i].ptype == eptAtom || - atoms->atom[i].ptype == eptNucleus) - && atoms->atom[i].m > 0) + if ((atoms->atom[i].ptype == eptAtom || atoms->atom[i].ptype == eptNucleus) && atoms->atom[i].m > 0) { nmass++; } } switch (nmass) { - case 0: nrdf = 0; break; - case 1: nrdf = 0; break; - case 2: nrdf = 1; break; - default: nrdf = nmass*3 - 6; break; + case 0: nrdf = 0; break; + case 1: nrdf = 0; break; + case 2: nrdf = 1; break; + default: nrdf = nmass * 3 - 6; break; } return nrdf; } -static void -spline1d( double dx, - const double * y, - int n, - double * u, - double * y2 ) +static void spline1d(double dx, const double* y, int n, double* u, double* y2) { int i; double p, q; @@ -1116,65 +1120,57 @@ spline1d( double dx, y2[0] = 0.0; u[0] = 0.0; - for (i = 1; i < n-1; i++) + for (i = 1; i < n - 1; i++) { - p = 0.5*y2[i-1]+2.0; - y2[i] = -0.5/p; - q = (y[i+1]-2.0*y[i]+y[i-1])/dx; - u[i] = (3.0*q/dx-0.5*u[i-1])/p; + p = 0.5 * y2[i - 1] + 2.0; + y2[i] = -0.5 / p; + q = (y[i + 1] - 2.0 * y[i] + y[i - 1]) / dx; + u[i] = (3.0 * q / dx - 0.5 * u[i - 1]) / p; } - y2[n-1] = 0.0; + y2[n - 1] = 0.0; - for (i = n-2; i >= 0; i--) + for (i = n - 2; i >= 0; i--) { - y2[i] = y2[i]*y2[i+1]+u[i]; + y2[i] = y2[i] * y2[i + 1] + u[i]; } } static void -interpolate1d( double xmin, - double dx, - const double * ya, - const double * y2a, - double x, - double * y, - double * y1) +interpolate1d(double xmin, double dx, const double* ya, const double* y2a, double x, double* y, double* y1) { int ix; double a, b; - ix = static_cast((x-xmin)/dx); + ix = static_cast((x - xmin) / dx); - a = (xmin+(ix+1)*dx-x)/dx; - b = (x-xmin-ix*dx)/dx; + a = (xmin + (ix + 1) * dx - x) / dx; + b = (x - xmin - ix * dx) / dx; - *y = a*ya[ix]+b*ya[ix+1]+((a*a*a-a)*y2a[ix]+(b*b*b-b)*y2a[ix+1])*(dx*dx)/6.0; - *y1 = (ya[ix+1]-ya[ix])/dx-(3.0*a*a-1.0)/6.0*dx*y2a[ix]+(3.0*b*b-1.0)/6.0*dx*y2a[ix+1]; + *y = a * ya[ix] + b * ya[ix + 1] + + ((a * a * a - a) * y2a[ix] + (b * b * b - b) * y2a[ix + 1]) * (dx * dx) / 6.0; + *y1 = (ya[ix + 1] - ya[ix]) / dx - (3.0 * a * a - 1.0) / 6.0 * dx * y2a[ix] + + (3.0 * b * b - 1.0) / 6.0 * dx * y2a[ix + 1]; } -static void -setup_cmap (int grid_spacing, - int nc, - gmx::ArrayRef grid, - gmx_cmap_t * cmap_grid) +static void setup_cmap(int grid_spacing, int nc, gmx::ArrayRef grid, gmx_cmap_t* cmap_grid) { - int i, j, k, ii, jj, kk, idx; - int offset; - double dx, xmin, v, v1, v2, v12; - double phi, psi; + int i, j, k, ii, jj, kk, idx; + int offset; + double dx, xmin, v, v1, v2, v12; + double phi, psi; - std::vector tmp_u(2*grid_spacing, 0.0); - std::vector tmp_u2(2*grid_spacing, 0.0); - std::vector tmp_yy(2*grid_spacing, 0.0); - std::vector tmp_y1(2*grid_spacing, 0.0); - std::vector tmp_t2(2*grid_spacing*2*grid_spacing, 0.0); - std::vector tmp_grid(2*grid_spacing*2*grid_spacing, 0.0); + std::vector tmp_u(2 * grid_spacing, 0.0); + std::vector tmp_u2(2 * grid_spacing, 0.0); + std::vector tmp_yy(2 * grid_spacing, 0.0); + std::vector tmp_y1(2 * grid_spacing, 0.0); + std::vector tmp_t2(2 * grid_spacing * 2 * grid_spacing, 0.0); + std::vector tmp_grid(2 * grid_spacing * 2 * grid_spacing, 0.0); - dx = 360.0/grid_spacing; - xmin = -180.0-dx*grid_spacing/2; + dx = 360.0 / grid_spacing; + xmin = -180.0 - dx * grid_spacing / 2; for (kk = 0; kk < nc; kk++) { @@ -1184,87 +1180,86 @@ setup_cmap (int grid_spacing, */ offset = kk * grid_spacing * grid_spacing * 2; - for (i = 0; i < 2*grid_spacing; i++) + for (i = 0; i < 2 * grid_spacing; i++) { - ii = (i+grid_spacing-grid_spacing/2)%grid_spacing; + ii = (i + grid_spacing - grid_spacing / 2) % grid_spacing; - for (j = 0; j < 2*grid_spacing; j++) + for (j = 0; j < 2 * grid_spacing; j++) { - jj = (j+grid_spacing-grid_spacing/2)%grid_spacing; - tmp_grid[i*grid_spacing*2+j] = grid[offset+ii*grid_spacing+jj]; + jj = (j + grid_spacing - grid_spacing / 2) % grid_spacing; + tmp_grid[i * grid_spacing * 2 + j] = grid[offset + ii * grid_spacing + jj]; } } - for (i = 0; i < 2*grid_spacing; i++) + for (i = 0; i < 2 * grid_spacing; i++) { - spline1d(dx, &(tmp_grid[2*grid_spacing*i]), 2*grid_spacing, tmp_u.data(), &(tmp_t2[2*grid_spacing*i])); + spline1d(dx, &(tmp_grid[2 * grid_spacing * i]), 2 * grid_spacing, tmp_u.data(), + &(tmp_t2[2 * grid_spacing * i])); } - for (i = grid_spacing/2; i < grid_spacing+grid_spacing/2; i++) + for (i = grid_spacing / 2; i < grid_spacing + grid_spacing / 2; i++) { - ii = i-grid_spacing/2; - phi = ii*dx-180.0; + ii = i - grid_spacing / 2; + phi = ii * dx - 180.0; - for (j = grid_spacing/2; j < grid_spacing+grid_spacing/2; j++) + for (j = grid_spacing / 2; j < grid_spacing + grid_spacing / 2; j++) { - jj = j-grid_spacing/2; - psi = jj*dx-180.0; + jj = j - grid_spacing / 2; + psi = jj * dx - 180.0; - for (k = 0; k < 2*grid_spacing; k++) + for (k = 0; k < 2 * grid_spacing; k++) { - interpolate1d(xmin, dx, &(tmp_grid[2*grid_spacing*k]), - &(tmp_t2[2*grid_spacing*k]), psi, &tmp_yy[k], &tmp_y1[k]); + interpolate1d(xmin, dx, &(tmp_grid[2 * grid_spacing * k]), + &(tmp_t2[2 * grid_spacing * k]), psi, &tmp_yy[k], &tmp_y1[k]); } - spline1d(dx, tmp_yy.data(), 2*grid_spacing, tmp_u.data(), tmp_u2.data()); + spline1d(dx, tmp_yy.data(), 2 * grid_spacing, tmp_u.data(), tmp_u2.data()); interpolate1d(xmin, dx, tmp_yy.data(), tmp_u2.data(), phi, &v, &v1); - spline1d(dx, tmp_y1.data(), 2*grid_spacing, tmp_u.data(), tmp_u2.data()); + spline1d(dx, tmp_y1.data(), 2 * grid_spacing, tmp_u.data(), tmp_u2.data()); interpolate1d(xmin, dx, tmp_y1.data(), tmp_u2.data(), phi, &v2, &v12); - idx = ii*grid_spacing+jj; - cmap_grid->cmapdata[kk].cmap[idx*4] = grid[offset+ii*grid_spacing+jj]; - cmap_grid->cmapdata[kk].cmap[idx*4+1] = v1; - cmap_grid->cmapdata[kk].cmap[idx*4+2] = v2; - cmap_grid->cmapdata[kk].cmap[idx*4+3] = v12; + idx = ii * grid_spacing + jj; + cmap_grid->cmapdata[kk].cmap[idx * 4] = grid[offset + ii * grid_spacing + jj]; + cmap_grid->cmapdata[kk].cmap[idx * 4 + 1] = v1; + cmap_grid->cmapdata[kk].cmap[idx * 4 + 2] = v2; + cmap_grid->cmapdata[kk].cmap[idx * 4 + 3] = v12; } } } } -static void init_cmap_grid(gmx_cmap_t *cmap_grid, int ngrid, int grid_spacing) +static void init_cmap_grid(gmx_cmap_t* cmap_grid, int ngrid, int grid_spacing) { int i, nelem; cmap_grid->grid_spacing = grid_spacing; - nelem = cmap_grid->grid_spacing*cmap_grid->grid_spacing; + nelem = cmap_grid->grid_spacing * cmap_grid->grid_spacing; cmap_grid->cmapdata.resize(ngrid); for (i = 0; i < ngrid; i++) { - cmap_grid->cmapdata[i].cmap.resize(4*nelem); + cmap_grid->cmapdata[i].cmap.resize(4 * nelem); } } -static int count_constraints(const gmx_mtop_t *mtop, - gmx::ArrayRef mi, - warninp *wi) +static int count_constraints(const gmx_mtop_t* mtop, gmx::ArrayRef mi, warninp* wi) { - int count, count_mol; - char buf[STRLEN]; + int count, count_mol; + char buf[STRLEN]; count = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - count_mol = 0; + count_mol = 0; gmx::ArrayRef interactions = mi[molb.type].interactions; for (int i = 0; i < F_NRE; i++) { if (i == F_SETTLE) { - count_mol += 3*interactions[i].size(); + count_mol += 3 * interactions[i].size(); } else if (interaction_function[i].flags & IF_CONSTRAINT) { @@ -1276,27 +1271,25 @@ static int count_constraints(const gmx_mtop_t *mtop, { sprintf(buf, "Molecule type '%s' has %d constraints.\n" - "For stability and efficiency there should not be more constraints than internal number of degrees of freedom: %d.\n", - *mi[molb.type].name, count_mol, - nrdf_internal(&mi[molb.type].atoms)); + "For stability and efficiency there should not be more constraints than " + "internal number of degrees of freedom: %d.\n", + *mi[molb.type].name, count_mol, nrdf_internal(&mi[molb.type].atoms)); warning(wi, buf); } - count += molb.nmol*count_mol; + count += molb.nmol * count_mol; } return count; } -static real calc_temp(const gmx_mtop_t *mtop, - const t_inputrec *ir, - rvec *v) +static real calc_temp(const gmx_mtop_t* mtop, const t_inputrec* ir, rvec* v) { - double sum_mv2 = 0; + double sum_mv2 = 0; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); - sum_mv2 += local.m*norm2(v[i]); + sum_mv2 += local.m * norm2(v[i]); } double nrdf = 0; @@ -1305,15 +1298,14 @@ static real calc_temp(const gmx_mtop_t *mtop, nrdf += ir->opts.nrdf[g]; } - return sum_mv2/(nrdf*BOLTZ); + return sum_mv2 / (nrdf * BOLTZ); } -static real get_max_reference_temp(const t_inputrec *ir, - warninp *wi) +static real get_max_reference_temp(const t_inputrec* ir, warninp* wi) { - real ref_t; - int i; - bool bNoCoupl; + real ref_t; + int i; + bool bNoCoupl; ref_t = 0; bNoCoupl = false; @@ -1333,7 +1325,10 @@ static real get_max_reference_temp(const t_inputrec *ir, { char buf[STRLEN]; - sprintf(buf, "Some temperature coupling groups do not use temperature coupling. We will assume their temperature is not more than %.3f K. If their temperature is higher, the energy error and the Verlet buffer might be underestimated.", + sprintf(buf, + "Some temperature coupling groups do not use temperature coupling. We will assume " + "their temperature is not more than %.3f K. If their temperature is higher, the " + "energy error and the Verlet buffer might be underestimated.", ref_t); warning(wi, buf); } @@ -1344,11 +1339,9 @@ static real get_max_reference_temp(const t_inputrec *ir, /* Checks if there are unbound atoms in moleculetype molt. * Prints a note for each unbound atoms and a warning if any is present. */ -static void checkForUnboundAtoms(const gmx_moltype_t *molt, - gmx_bool bVerbose, - warninp *wi) +static void checkForUnboundAtoms(const gmx_moltype_t* molt, gmx_bool bVerbose, warninp* wi) { - const t_atoms *atoms = &molt->atoms; + const t_atoms* atoms = &molt->atoms; if (atoms->nr == 1) { @@ -1360,11 +1353,10 @@ static void checkForUnboundAtoms(const gmx_moltype_t *molt, for (int ftype = 0; ftype < F_NRE; ftype++) { - if (((interaction_function[ftype].flags & IF_BOND) && ftype != F_CONNBONDS) || - (interaction_function[ftype].flags & IF_CONSTRAINT) || - ftype == F_SETTLE) + if (((interaction_function[ftype].flags & IF_BOND) && ftype != F_CONNBONDS) + || (interaction_function[ftype].flags & IF_CONSTRAINT) || ftype == F_SETTLE) { - const InteractionList &il = molt->ilist[ftype]; + const InteractionList& il = molt->ilist[ftype]; const int nral = NRAL(ftype); for (int i = 0; i < il.size(); i += 1 + nral) @@ -1380,12 +1372,13 @@ static void checkForUnboundAtoms(const gmx_moltype_t *molt, int numDanglingAtoms = 0; for (int a = 0; a < atoms->nr; a++) { - if (atoms->atom[a].ptype != eptVSite && - count[a] == 0) + if (atoms->atom[a].ptype != eptVSite && count[a] == 0) { if (bVerbose) { - fprintf(stderr, "\nAtom %d '%s' in moleculetype '%s' is not bound by a potential or constraint to any other atom in the same moleculetype.\n", + fprintf(stderr, + "\nAtom %d '%s' in moleculetype '%s' is not bound by a potential or " + "constraint to any other atom in the same moleculetype.\n", a + 1, *atoms->atomname[a], *molt->name); } numDanglingAtoms++; @@ -1395,18 +1388,21 @@ static void checkForUnboundAtoms(const gmx_moltype_t *molt, if (numDanglingAtoms > 0) { char buf[STRLEN]; - sprintf(buf, "In moleculetype '%s' %d atoms are not bound by a potential or constraint to any other atom in the same moleculetype. Although technically this might not cause issues in a simulation, this often means that the user forgot to add a bond/potential/constraint or put multiple molecules in the same moleculetype definition by mistake. Run with -v to get information for each atom.", + sprintf(buf, + "In moleculetype '%s' %d atoms are not bound by a potential or constraint to any " + "other atom in the same moleculetype. Although technically this might not cause " + "issues in a simulation, this often means that the user forgot to add a " + "bond/potential/constraint or put multiple molecules in the same moleculetype " + "definition by mistake. Run with -v to get information for each atom.", *molt->name, numDanglingAtoms); warning_note(wi, buf); } } /* Checks all moleculetypes for unbound atoms */ -static void checkForUnboundAtoms(const gmx_mtop_t *mtop, - gmx_bool bVerbose, - warninp *wi) +static void checkForUnboundAtoms(const gmx_mtop_t* mtop, gmx_bool bVerbose, warninp* wi) { - for (const gmx_moltype_t &molt : mtop->moltype) + for (const gmx_moltype_t& molt : mtop->moltype) { checkForUnboundAtoms(&molt, bVerbose, wi); } @@ -1419,29 +1415,27 @@ static void checkForUnboundAtoms(const gmx_mtop_t *mtop, * involved in a single constraint; the mass of the two atoms needs to * differ by more than \p massFactorThreshold. */ -static bool haveDecoupledModeInMol(const gmx_moltype_t &molt, - gmx::ArrayRef iparams, - real massFactorThreshold) +static bool haveDecoupledModeInMol(const gmx_moltype_t& molt, + gmx::ArrayRef iparams, + real massFactorThreshold) { - if (molt.ilist[F_CONSTR].size() == 0 && - molt.ilist[F_CONSTRNC].size() == 0) + if (molt.ilist[F_CONSTR].size() == 0 && molt.ilist[F_CONSTRNC].size() == 0) { return false; } - const t_atom * atom = molt.atoms.atom; + const t_atom* atom = molt.atoms.atom; - t_blocka atomToConstraints = - gmx::make_at2con(molt, iparams, - gmx::FlexibleConstraintTreatment::Exclude); + t_blocka atomToConstraints = + gmx::make_at2con(molt, iparams, gmx::FlexibleConstraintTreatment::Exclude); - bool haveDecoupledMode = false; + bool haveDecoupledMode = false; for (int ftype = 0; ftype < F_NRE; ftype++) { if (interaction_function[ftype].flags & IF_ATYPE) { const int nral = NRAL(ftype); - const InteractionList &il = molt.ilist[ftype]; + const InteractionList& il = molt.ilist[ftype]; for (int i = 0; i < il.size(); i += 1 + nral) { /* Here we check for the mass difference between the atoms @@ -1461,18 +1455,18 @@ static bool haveDecoupledModeInMol(const gmx_moltype_t &molt, int a0 = il.iatoms[1 + i]; int a1 = il.iatoms[1 + i + 1]; int a2 = il.iatoms[1 + i + 2]; - if ((atom[a0].m > atom[a2].m*massFactorThreshold || - atom[a2].m > atom[a0].m*massFactorThreshold) && - atomToConstraints.index[a0 + 1] - atomToConstraints.index[a0] == 1 && - atomToConstraints.index[a2 + 1] - atomToConstraints.index[a2] == 1 && - atomToConstraints.index[a1 + 1] - atomToConstraints.index[a1] >= 3) + if ((atom[a0].m > atom[a2].m * massFactorThreshold || atom[a2].m > atom[a0].m * massFactorThreshold) + && atomToConstraints.index[a0 + 1] - atomToConstraints.index[a0] == 1 + && atomToConstraints.index[a2 + 1] - atomToConstraints.index[a2] == 1 + && atomToConstraints.index[a1 + 1] - atomToConstraints.index[a1] >= 3) { - int constraint0 = atomToConstraints.a[atomToConstraints.index[a0]]; - int constraint2 = atomToConstraints.a[atomToConstraints.index[a2]]; + int constraint0 = atomToConstraints.a[atomToConstraints.index[a0]]; + int constraint2 = atomToConstraints.a[atomToConstraints.index[a2]]; - bool foundAtom0 = false; - bool foundAtom2 = false; - for (int conIndex = atomToConstraints.index[a1]; conIndex < atomToConstraints.index[a1 + 1]; conIndex++) + bool foundAtom0 = false; + bool foundAtom2 = false; + for (int conIndex = atomToConstraints.index[a1]; + conIndex < atomToConstraints.index[a1 + 1]; conIndex++) { if (atomToConstraints.a[conIndex] == constraint0) { @@ -1502,9 +1496,7 @@ static bool haveDecoupledModeInMol(const gmx_moltype_t &molt, * When decoupled modes are present and the accuray in insufficient, * this routine issues a warning if the accuracy is insufficient. */ -static void checkDecoupledModeAccuracy(const gmx_mtop_t *mtop, - const t_inputrec *ir, - warninp *wi) +static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec* ir, warninp* wi) { /* We only have issues with decoupled modes with normal MD. * With stochastic dynamics equipartitioning is enforced strongly. @@ -1529,26 +1521,26 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t *mtop, * energy/time, respectively, so they will "only" work correctly * for atomistic force fields using MD units. */ - const real massFactorThreshold = 13.0; - const real bufferToleranceThreshold = 1e-4; - const int lincsIterationThreshold = 2; - const int lincsOrderThreshold = 4; - const real shakeToleranceThreshold = 0.005*ir->delta_t; - - bool lincsWithSufficientTolerance = (ir->eConstrAlg == econtLINCS && ir->nLincsIter >= lincsIterationThreshold && ir->nProjOrder >= lincsOrderThreshold); - bool shakeWithSufficientTolerance = (ir->eConstrAlg == econtSHAKE && ir->shake_tol <= 1.1*shakeToleranceThreshold); - if (ir->cutoff_scheme == ecutsVERLET && - ir->verletbuf_tol <= 1.1*bufferToleranceThreshold && - (lincsWithSufficientTolerance || shakeWithSufficientTolerance)) + const real massFactorThreshold = 13.0; + const real bufferToleranceThreshold = 1e-4; + const int lincsIterationThreshold = 2; + const int lincsOrderThreshold = 4; + const real shakeToleranceThreshold = 0.005 * ir->delta_t; + + bool lincsWithSufficientTolerance = (ir->eConstrAlg == econtLINCS && ir->nLincsIter >= lincsIterationThreshold + && ir->nProjOrder >= lincsOrderThreshold); + bool shakeWithSufficientTolerance = + (ir->eConstrAlg == econtSHAKE && ir->shake_tol <= 1.1 * shakeToleranceThreshold); + if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol <= 1.1 * bufferToleranceThreshold + && (lincsWithSufficientTolerance || shakeWithSufficientTolerance)) { return; } bool haveDecoupledMode = false; - for (const gmx_moltype_t &molt : mtop->moltype) + for (const gmx_moltype_t& molt : mtop->moltype) { - if (haveDecoupledModeInMol(molt, mtop->ffparams.iparams, - massFactorThreshold)) + if (haveDecoupledModeInMol(molt, mtop->ffparams.iparams, massFactorThreshold)) { haveDecoupledMode = true; } @@ -1557,85 +1549,85 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t *mtop, if (haveDecoupledMode) { std::string message = gmx::formatString( - "There are atoms at both ends of an angle, connected by constraints " - "and with masses that differ by more than a factor of %g. This means " - "that there are likely dynamic modes that are only very weakly coupled.", - massFactorThreshold); + "There are atoms at both ends of an angle, connected by constraints " + "and with masses that differ by more than a factor of %g. This means " + "that there are likely dynamic modes that are only very weakly coupled.", + massFactorThreshold); if (ir->cutoff_scheme == ecutsVERLET) { message += gmx::formatString( - " To ensure good equipartitioning, you need to either not use " - "constraints on all bonds (but, if possible, only on bonds involving " - "hydrogens) or use integrator = %s or decrease one or more tolerances: " - "verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order " - ">= %d or SHAKE tolerance <= %g", - ei_names[eiSD1], - bufferToleranceThreshold, - lincsIterationThreshold, lincsOrderThreshold, - shakeToleranceThreshold); + " To ensure good equipartitioning, you need to either not use " + "constraints on all bonds (but, if possible, only on bonds involving " + "hydrogens) or use integrator = %s or decrease one or more tolerances: " + "verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order " + ">= %d or SHAKE tolerance <= %g", + ei_names[eiSD1], bufferToleranceThreshold, lincsIterationThreshold, + lincsOrderThreshold, shakeToleranceThreshold); } else { message += gmx::formatString( - " To ensure good equipartitioning, we suggest to switch to the %s " - "cutoff-scheme, since that allows for better control over the Verlet " - "buffer size and thus over the energy drift.", - ecutscheme_names[ecutsVERLET]); + " To ensure good equipartitioning, we suggest to switch to the %s " + "cutoff-scheme, since that allows for better control over the Verlet " + "buffer size and thus over the energy drift.", + ecutscheme_names[ecutsVERLET]); } warning(wi, message); } } -static void set_verlet_buffer(const gmx_mtop_t *mtop, - t_inputrec *ir, - real buffer_temp, - matrix box, - warninp *wi) +static void set_verlet_buffer(const gmx_mtop_t* mtop, t_inputrec* ir, real buffer_temp, matrix box, warninp* wi) { - char warn_buf[STRLEN]; + char warn_buf[STRLEN]; - printf("Determining Verlet buffer for a tolerance of %g kJ/mol/ps at %g K\n", ir->verletbuf_tol, buffer_temp); + printf("Determining Verlet buffer for a tolerance of %g kJ/mol/ps at %g K\n", ir->verletbuf_tol, + buffer_temp); /* Calculate the buffer size for simple atom vs atoms list */ VerletbufListSetup listSetup1x1; listSetup1x1.cluster_size_i = 1; listSetup1x1.cluster_size_j = 1; - const real rlist_1x1 = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, - buffer_temp, listSetup1x1); + const real rlist_1x1 = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, + buffer_temp, listSetup1x1); /* Set the pair-list buffer size in ir */ - VerletbufListSetup listSetup4x4 = - verletbufGetSafeListSetup(ListSetupType::CpuNoSimd); - ir->rlist = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, - buffer_temp, listSetup4x4); + VerletbufListSetup listSetup4x4 = verletbufGetSafeListSetup(ListSetupType::CpuNoSimd); + ir->rlist = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, + buffer_temp, listSetup4x4); const int n_nonlin_vsite = countNonlinearVsites(*mtop); if (n_nonlin_vsite > 0) { - sprintf(warn_buf, "There are %d non-linear virtual site constructions. Their contribution to the energy error is approximated. In most cases this does not affect the error significantly.", n_nonlin_vsite); + sprintf(warn_buf, + "There are %d non-linear virtual site constructions. Their contribution to the " + "energy error is approximated. In most cases this does not affect the error " + "significantly.", + n_nonlin_vsite); warning_note(wi, warn_buf); } - printf("Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm\n", - 1, 1, rlist_1x1, rlist_1x1-std::max(ir->rvdw, ir->rcoulomb)); + printf("Calculated rlist for %dx%d atom pair-list as %.3f nm, buffer size %.3f nm\n", 1, 1, + rlist_1x1, rlist_1x1 - std::max(ir->rvdw, ir->rcoulomb)); printf("Set rlist, assuming %dx%d atom pair-list, to %.3f nm, buffer size %.3f nm\n", - listSetup4x4.cluster_size_i, listSetup4x4.cluster_size_j, - ir->rlist, ir->rlist-std::max(ir->rvdw, ir->rcoulomb)); + listSetup4x4.cluster_size_i, listSetup4x4.cluster_size_j, ir->rlist, + ir->rlist - std::max(ir->rvdw, ir->rcoulomb)); printf("Note that mdrun will redetermine rlist based on the actual pair-list setup\n"); if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box)) { - gmx_fatal(FARGS, "The pair-list cut-off (%g nm) is longer than half the shortest box vector or longer than the smallest box diagonal element (%g nm). Increase the box size or decrease nstlist or increase verlet-buffer-tolerance.", ir->rlist, std::sqrt(max_cutoff2(ir->ePBC, box))); + gmx_fatal(FARGS, + "The pair-list cut-off (%g nm) is longer than half the shortest box vector or " + "longer than the smallest box diagonal element (%g nm). Increase the box size or " + "decrease nstlist or increase verlet-buffer-tolerance.", + ir->rlist, std::sqrt(max_cutoff2(ir->ePBC, box))); } } -int gmx_grompp(int argc, char *argv[]) +int gmx_grompp(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] (the gromacs preprocessor)", "reads a molecular topology file, checks the validity of the", "file, expands the topology from a molecular description to an atomic", @@ -1733,61 +1725,70 @@ int gmx_grompp(int argc, char *argv[]) "interpret the output messages before attempting to bypass them with", "this option." }; - t_gromppopts *opts; + t_gromppopts* opts; std::vector mi; std::unique_ptr intermolecular_interactions; int nvsite, comb; real fudgeQQ; double reppow; - const char *mdparin; + const char* mdparin; bool bNeedVel, bGenVel; gmx_bool have_atomnumber; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_bool bVerbose = FALSE; - warninp *wi; + warninp* wi; char warn_buf[STRLEN]; - t_filenm fnm[] = { - { efMDP, nullptr, nullptr, ffREAD }, - { efMDP, "-po", "mdout", ffWRITE }, - { efSTX, "-c", nullptr, ffREAD }, - { efSTX, "-r", "restraint", ffOPTRD }, - { efSTX, "-rb", "restraint", ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTOP, nullptr, nullptr, ffREAD }, - { efTOP, "-pp", "processed", ffOPTWR }, - { efTPR, "-o", nullptr, ffWRITE }, - { efTRN, "-t", nullptr, ffOPTRD }, - { efEDR, "-e", nullptr, ffOPTRD }, - /* This group is needed by the VMD viewer as the start configuration for IMD sessions: */ - { efGRO, "-imd", "imdgroup", ffOPTWR }, - { efTRN, "-ref", "rotref", ffOPTRW } - }; + t_filenm fnm[] = { { efMDP, nullptr, nullptr, ffREAD }, + { efMDP, "-po", "mdout", ffWRITE }, + { efSTX, "-c", nullptr, ffREAD }, + { efSTX, "-r", "restraint", ffOPTRD }, + { efSTX, "-rb", "restraint", ffOPTRD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTOP, nullptr, nullptr, ffREAD }, + { efTOP, "-pp", "processed", ffOPTWR }, + { efTPR, "-o", nullptr, ffWRITE }, + { efTRN, "-t", nullptr, ffOPTRD }, + { efEDR, "-e", nullptr, ffOPTRD }, + /* This group is needed by the VMD viewer as the start configuration for IMD sessions: */ + { efGRO, "-imd", "imdgroup", ffOPTWR }, + { efTRN, "-ref", "rotref", ffOPTRW } }; #define NFILE asize(fnm) /* Command line options */ - gmx_bool bRenum = TRUE; - gmx_bool bRmVSBds = TRUE, bZero = FALSE; - int i, maxwarn = 0; - real fr_time = -1; - t_pargs pa[] = { - { "-v", FALSE, etBOOL, {&bVerbose}, - "Be loud and noisy" }, - { "-time", FALSE, etREAL, {&fr_time}, - "Take frame at or first after this time." }, - { "-rmvsbds", FALSE, etBOOL, {&bRmVSBds}, + gmx_bool bRenum = TRUE; + gmx_bool bRmVSBds = TRUE, bZero = FALSE; + int i, maxwarn = 0; + real fr_time = -1; + t_pargs pa[] = { + { "-v", FALSE, etBOOL, { &bVerbose }, "Be loud and noisy" }, + { "-time", FALSE, etREAL, { &fr_time }, "Take frame at or first after this time." }, + { "-rmvsbds", + FALSE, + etBOOL, + { &bRmVSBds }, "Remove constant bonded interactions with virtual sites" }, - { "-maxwarn", FALSE, etINT, {&maxwarn}, - "Number of allowed warnings during input processing. Not for normal use and may generate unstable systems" }, - { "-zero", FALSE, etBOOL, {&bZero}, - "Set parameters for bonded interactions without defaults to zero instead of generating an error" }, - { "-renum", FALSE, etBOOL, {&bRenum}, + { "-maxwarn", + FALSE, + etINT, + { &maxwarn }, + "Number of allowed warnings during input processing. Not for normal use and may " + "generate unstable systems" }, + { "-zero", + FALSE, + etBOOL, + { &bZero }, + "Set parameters for bonded interactions without defaults to zero instead of " + "generating an error" }, + { "-renum", + FALSE, + etBOOL, + { &bRenum }, "Renumber atomtypes and minimize number of atomtypes" } }; /* Parse the command line */ - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -1795,7 +1796,7 @@ int gmx_grompp(int argc, char *argv[]) /* Initiate some variables */ gmx::MDModules mdModules; t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec* ir = &irInstance; snew(opts, 1); snew(opts->include, STRLEN); snew(opts->define, STRLEN); @@ -1809,7 +1810,7 @@ int gmx_grompp(int argc, char *argv[]) { get_ir(mdparin, opt2fn("-po", NFILE, fnm), &mdModules, ir, opts, WriteMdpHeader::yes, wi); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR if (bVerbose) { @@ -1848,19 +1849,16 @@ int gmx_grompp(int argc, char *argv[]) pr_symtab(debug, 0, "Just opened", &sys.symtab); } - const char *fn = ftp2fn(efTOP, NFILE, fnm); + const char* fn = ftp2fn(efTOP, NFILE, fnm); if (!gmx_fexist(fn)) { gmx_fatal(FARGS, "%s does not exist", fn); } t_state state; - new_status(fn, opt2fn_null("-pp", NFILE, fnm), opt2fn("-c", NFILE, fnm), - opts, ir, bZero, bGenVel, bVerbose, &state, - &atypes, &sys, &mi, &intermolecular_interactions, - interactions, &comb, &reppow, &fudgeQQ, - opts->bMorse, - wi); + new_status(fn, opt2fn_null("-pp", NFILE, fnm), opt2fn("-c", NFILE, fnm), opts, ir, bZero, + bGenVel, bVerbose, &state, &atypes, &sys, &mi, &intermolecular_interactions, + interactions, &comb, &reppow, &fudgeQQ, opts->bMorse, wi); if (debug) { @@ -1871,8 +1869,7 @@ int gmx_grompp(int argc, char *argv[]) /* set parameters for virtual site construction (not for vsiten) */ for (size_t mt = 0; mt < sys.moltype.size(); mt++) { - nvsite += - set_vsites(bVerbose, &sys.moltype[mt].atoms, &atypes, mi[mt].interactions); + nvsite += set_vsites(bVerbose, &sys.moltype[mt].atoms, &atypes, mi[mt].interactions); } /* now throw away all obsolete bonds, angles and dihedrals: */ /* note: constraints are ALWAYS removed */ @@ -1888,8 +1885,8 @@ int gmx_grompp(int argc, char *argv[]) { if (ir->eI == eiCG || ir->eI == eiLBFGS) { - sprintf(warn_buf, "Can not do %s with %s, use %s", - EI(ir->eI), econstr_names[econtSHAKE], econstr_names[econtLINCS]); + sprintf(warn_buf, "Can not do %s with %s, use %s", EI(ir->eI), + econstr_names[econtSHAKE], econstr_names[econtLINCS]); warning_error(wi, warn_buf); } if (ir->bPeriodicMols) @@ -1900,7 +1897,7 @@ int gmx_grompp(int argc, char *argv[]) } } - if (EI_SD (ir->eI) && ir->etc != etcNO) + if (EI_SD(ir->eI) && ir->etc != etcNO) { warning_note(wi, "Temperature coupling is ignored with SD integrators."); } @@ -1913,14 +1910,15 @@ int gmx_grompp(int argc, char *argv[]) } if (!have_atomnumber && ir->bQMMM) { - warning_error(wi, - "\n" - "It appears as if you are trying to run a QM/MM calculation, but the force\n" - "field you are using does not contain atom numbers fields. This is an\n" - "optional field (introduced in GROMACS 3.3) for general runs, but mandatory\n" - "for QM/MM. The good news is that it is easy to add - put the atom number as\n" - "an integer just before the mass column in ffXXXnb.itp.\n" - "NB: United atoms have the same atom numbers as normal ones.\n\n"); + warning_error( + wi, + "\n" + "It appears as if you are trying to run a QM/MM calculation, but the force\n" + "field you are using does not contain atom numbers fields. This is an\n" + "optional field (introduced in GROMACS 3.3) for general runs, but mandatory\n" + "for QM/MM. The good news is that it is easy to add - put the atom number as\n" + "an integer just before the mass column in ffXXXnb.itp.\n" + "NB: United atoms have the same atom numbers as normal ones.\n\n"); } /* Check for errors in the input now, since they might cause problems @@ -1928,18 +1926,20 @@ int gmx_grompp(int argc, char *argv[]) */ check_warning_error(wi, FARGS); - if (nint_ftype(&sys, mi, F_POSRES) > 0 || - nint_ftype(&sys, mi, F_FBPOSRES) > 0) + if (nint_ftype(&sys, mi, F_POSRES) > 0 || nint_ftype(&sys, mi, F_FBPOSRES) > 0) { if (ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK) { - sprintf(warn_buf, "You are combining position restraints with %s pressure coupling, which can lead to instabilities. If you really want to combine position restraints with pressure coupling, we suggest to use %s pressure coupling instead.", + sprintf(warn_buf, + "You are combining position restraints with %s pressure coupling, which can " + "lead to instabilities. If you really want to combine position restraints with " + "pressure coupling, we suggest to use %s pressure coupling instead.", EPCOUPLTYPE(ir->epc), EPCOUPLTYPE(epcBERENDSEN)); warning_note(wi, warn_buf); } - const char *fn = opt2fn("-r", NFILE, fnm); - const char *fnB; + const char* fn = opt2fn("-r", NFILE, fnm); + const char* fnB; if (!gmx_fexist(fn)) { @@ -1947,7 +1947,8 @@ int gmx_grompp(int argc, char *argv[]) "Cannot find position restraint file %s (option -r).\n" "From GROMACS-2018, you need to specify the position restraint " "coordinate files explicitly to avoid mistakes, although you can " - "still use the same file as you specify for the -c option.", fn); + "still use the same file as you specify for the -c option.", + fn); } if (opt2bSet("-rb", NFILE, fnm)) @@ -1959,7 +1960,8 @@ int gmx_grompp(int argc, char *argv[]) "Cannot find B-state position restraint file %s (option -rb).\n" "From GROMACS-2018, you need to specify the position restraint " "coordinate files explicitly to avoid mistakes, although you can " - "still use the same file as you specify for the -c option.", fn); + "still use the same file as you specify for the -c option.", + fn); } } else @@ -1979,17 +1981,16 @@ int gmx_grompp(int argc, char *argv[]) fprintf(stderr, " and %s\n", fnB); } } - gen_posres(&sys, mi, fn, fnB, - ir->refcoord_scaling, ir->ePBC, - ir->posres_com, ir->posres_comB, - wi); + gen_posres(&sys, mi, fn, fnB, ir->refcoord_scaling, ir->ePBC, ir->posres_com, ir->posres_comB, wi); } /* If we are using CMAP, setup the pre-interpolation grid */ if (interactions[F_CMAP].ncmap() > 0) { - init_cmap_grid(&sys.ffparams.cmap_grid, interactions[F_CMAP].cmapAngles, interactions[F_CMAP].cmakeGridSpacing); - setup_cmap(interactions[F_CMAP].cmakeGridSpacing, interactions[F_CMAP].cmapAngles, interactions[F_CMAP].cmap, &sys.ffparams.cmap_grid); + init_cmap_grid(&sys.ffparams.cmap_grid, interactions[F_CMAP].cmapAngles, + interactions[F_CMAP].cmakeGridSpacing); + setup_cmap(interactions[F_CMAP].cmakeGridSpacing, interactions[F_CMAP].cmapAngles, + interactions[F_CMAP].cmap, &sys.ffparams.cmap_grid); } set_wall_atomtype(&atypes, opts, ir, wi); @@ -2017,8 +2018,8 @@ int gmx_grompp(int argc, char *argv[]) } const int ntype = atypes.size(); - convertInteractionsOfType(ntype, interactions, mi, intermolecular_interactions.get(), - comb, reppow, fudgeQQ, &sys); + convertInteractionsOfType(ntype, interactions, mi, intermolecular_interactions.get(), comb, + reppow, fudgeQQ, &sys); if (debug) { @@ -2026,7 +2027,7 @@ int gmx_grompp(int argc, char *argv[]) } /* set ptype to VSite for virtual sites */ - for (gmx_moltype_t &moltype : sys.moltype) + for (gmx_moltype_t& moltype : sys.moltype) { set_vsites_ptype(FALSE, &moltype); } @@ -2057,7 +2058,12 @@ int gmx_grompp(int argc, char *argv[]) if (EI_ENERGY_MINIMIZATION(ir->eI) && 0 == ir->nsteps) { - warning_note(wi, "Zero-step energy minimization will alter the coordinates before calculating the energy. If you just want the energy of a single point, try zero-step MD (with unconstrained_start = yes). To do multiple single-point energy evaluations of different configurations of the same topology, use mdrun -rerun."); + warning_note( + wi, + "Zero-step energy minimization will alter the coordinates before calculating the " + "energy. If you just want the energy of a single point, try zero-step MD (with " + "unconstrained_start = yes). To do multiple single-point energy evaluations of " + "different configurations of the same topology, use mdrun -rerun."); } check_warning_error(wi, FARGS); @@ -2066,8 +2072,7 @@ int gmx_grompp(int argc, char *argv[]) { fprintf(stderr, "initialising group options...\n"); } - do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), - &sys, bVerbose, mdModules.notifier(), ir, wi); + do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifier(), ir, wi); if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0) { @@ -2087,13 +2092,18 @@ int gmx_grompp(int argc, char *argv[]) } if (buffer_temp > 0) { - sprintf(warn_buf, "NVE simulation: will use the initial temperature of %.3f K for determining the Verlet buffer size", buffer_temp); + sprintf(warn_buf, + "NVE simulation: will use the initial temperature of %.3f K for " + "determining the Verlet buffer size", + buffer_temp); warning_note(wi, warn_buf); } else { - sprintf(warn_buf, "NVE simulation with an initial temperature of zero: will use a Verlet buffer of %d%%. Check your energy drift!", - gmx::roundToInt(verlet_buffer_ratio_NVE_T0*100)); + sprintf(warn_buf, + "NVE simulation with an initial temperature of zero: will use a Verlet " + "buffer of %d%%. Check your energy drift!", + gmx::roundToInt(verlet_buffer_ratio_NVE_T0 * 100)); warning_note(wi, warn_buf); } } @@ -2108,8 +2118,8 @@ int gmx_grompp(int argc, char *argv[]) * Since we don't actually use verletbuf_tol, we set it to -1 * so it can't be misused later. */ - ir->rlist *= 1.0 + verlet_buffer_ratio_NVE_T0; - ir->verletbuf_tol = -1; + ir->rlist *= 1.0 + verlet_buffer_ratio_NVE_T0; + ir->verletbuf_tol = -1; } else { @@ -2118,22 +2128,26 @@ int gmx_grompp(int argc, char *argv[]) * Note that we can't warn when nsteps=0, since we don't * know how many steps the user intends to run. */ - if (EI_MD(ir->eI) && ir->etc == etcNO && ir->nstlist > 1 && - ir->nsteps > 0) + if (EI_MD(ir->eI) && ir->etc == etcNO && ir->nstlist > 1 && ir->nsteps > 0) { const real driftTolerance = 0.01; /* We use 2 DOF per atom = 2kT pot+kin energy, * to be on the safe side with constraints. */ - const real totalEnergyDriftPerAtomPerPicosecond = 2*BOLTZ*buffer_temp/(ir->nsteps*ir->delta_t); + const real totalEnergyDriftPerAtomPerPicosecond = + 2 * BOLTZ * buffer_temp / (ir->nsteps * ir->delta_t); - if (ir->verletbuf_tol > 1.1*driftTolerance*totalEnergyDriftPerAtomPerPicosecond) + if (ir->verletbuf_tol > 1.1 * driftTolerance * totalEnergyDriftPerAtomPerPicosecond) { - sprintf(warn_buf, "You are using a Verlet buffer tolerance of %g kJ/mol/ps for an NVE simulation of length %g ps, which can give a final drift of %d%%. For conserving energy to %d%% when using constraints, you might need to set verlet-buffer-tolerance to %.1e.", - ir->verletbuf_tol, ir->nsteps*ir->delta_t, - gmx::roundToInt(ir->verletbuf_tol/totalEnergyDriftPerAtomPerPicosecond*100), - gmx::roundToInt(100*driftTolerance), - driftTolerance*totalEnergyDriftPerAtomPerPicosecond); + sprintf(warn_buf, + "You are using a Verlet buffer tolerance of %g kJ/mol/ps for an " + "NVE simulation of length %g ps, which can give a final drift of " + "%d%%. For conserving energy to %d%% when using constraints, you " + "might need to set verlet-buffer-tolerance to %.1e.", + ir->verletbuf_tol, ir->nsteps * ir->delta_t, + gmx::roundToInt(ir->verletbuf_tol / totalEnergyDriftPerAtomPerPicosecond * 100), + gmx::roundToInt(100 * driftTolerance), + driftTolerance * totalEnergyDriftPerAtomPerPicosecond); warning_note(wi, warn_buf); } } @@ -2180,8 +2194,8 @@ int gmx_grompp(int argc, char *argv[]) { fprintf(stderr, "getting data from old trajectory ...\n"); } - cont_status(ftp2fn(efTRN, NFILE, fnm), ftp2fn_null(efEDR, NFILE, fnm), - bNeedVel, bGenVel, fr_time, ir, &state, &sys, oenv); + cont_status(ftp2fn(efTRN, NFILE, fnm), ftp2fn_null(efEDR, NFILE, fnm), bNeedVel, bGenVel, + fr_time, ir, &state, &sys, oenv); } if (ir->ePBC == epbcXY && ir->nwall != 2) @@ -2204,16 +2218,17 @@ int gmx_grompp(int argc, char *argv[]) else if (ir->nkx != 0 && ir->nky != 0 && ir->nkz != 0) { set_warning_line(wi, mdparin, -1); - warning_error(wi, "Some of the Fourier grid sizes are set, but all of them need to be set."); + warning_error( + wi, "Some of the Fourier grid sizes are set, but all of them need to be set."); } const int minGridSize = minimalPmeGridSize(ir->pme_order); - calcFftGrid(stdout, scaledBox, ir->fourier_spacing, minGridSize, - &(ir->nkx), &(ir->nky), &(ir->nkz)); - if (ir->nkx < minGridSize || - ir->nky < minGridSize || - ir->nkz < minGridSize) + calcFftGrid(stdout, scaledBox, ir->fourier_spacing, minGridSize, &(ir->nkx), &(ir->nky), + &(ir->nkz)); + if (ir->nkx < minGridSize || ir->nky < minGridSize || ir->nkz < minGridSize) { - warning_error(wi, "The PME grid size should be >= 2*(pme-order - 1); either manually increase the grid size or decrease pme-order"); + warning_error(wi, + "The PME grid size should be >= 2*(pme-order - 1); either manually " + "increase the grid size or decrease pme-order"); } } @@ -2244,7 +2259,7 @@ int gmx_grompp(int argc, char *argv[]) } } - pull_t *pull = nullptr; + pull_t* pull = nullptr; if (ir->bPull) { @@ -2263,9 +2278,8 @@ int gmx_grompp(int argc, char *argv[]) { copy_mat(ir->compress, compressibility); } - setStateDependentAwhParams(ir->awhParams, ir->pull, pull, - state.box, ir->ePBC, compressibility, - &ir->opts, wi); + setStateDependentAwhParams(ir->awhParams, ir->pull, pull, state.box, ir->ePBC, + compressibility, &ir->opts, wi); } if (ir->bPull) @@ -2276,8 +2290,7 @@ int gmx_grompp(int argc, char *argv[]) if (ir->bRot) { set_reference_positions(ir->rot, state.x.rvec_array(), state.box, - opt2fn("-ref", NFILE, fnm), opt2bSet("-ref", NFILE, fnm), - wi); + opt2fn("-ref", NFILE, fnm), opt2bSet("-ref", NFILE, fnm), wi); } /* reset_multinr(sys); */ @@ -2290,17 +2303,18 @@ int gmx_grompp(int argc, char *argv[]) * charges. This will double the cost, but the optimal performance will * then probably be at a slightly larger cut-off and grid spacing. */ - if ((ir->efep == efepNO && ratio > 1.0/2.0) || - (ir->efep != efepNO && ratio > 2.0/3.0)) + if ((ir->efep == efepNO && ratio > 1.0 / 2.0) || (ir->efep != efepNO && ratio > 2.0 / 3.0)) { - warning_note(wi, - "The optimal PME mesh load for parallel simulations is below 0.5\n" - "and for highly parallel simulations between 0.25 and 0.33,\n" - "for higher performance, increase the cut-off and the PME grid spacing.\n"); + warning_note( + wi, + "The optimal PME mesh load for parallel simulations is below 0.5\n" + "and for highly parallel simulations between 0.25 and 0.33,\n" + "for higher performance, increase the cut-off and the PME grid spacing.\n"); if (ir->efep != efepNO) { warning_note(wi, - "For free energy simulations, the optimal load limit increases from 0.5 to 0.667\n"); + "For free energy simulations, the optimal load limit increases from " + "0.5 to 0.667\n"); } } } @@ -2326,7 +2340,8 @@ int gmx_grompp(int argc, char *argv[]) { gmx::KeyValueTreeBuilder internalParameterBuilder; mdModules.notifier().notifier_.notify(internalParameterBuilder.rootObject()); - ir->internalParameters = std::make_unique(internalParameterBuilder.build()); + ir->internalParameters = + std::make_unique(internalParameterBuilder.build()); } if (bVerbose) @@ -2343,7 +2358,7 @@ int gmx_grompp(int argc, char *argv[]) sfree(opts->define); sfree(opts->include); sfree(opts); - for (auto &mol : mi) + for (auto& mol : mi) { // Some of the contents of molinfo have been stolen, so // fullCleanUp can't be called. diff --git a/src/gromacs/gmxpreprocess/grompp.h b/src/gromacs/gmxpreprocess/grompp.h index 9e6bcba686..29a783f339 100644 --- a/src/gromacs/gmxpreprocess/grompp.h +++ b/src/gromacs/gmxpreprocess/grompp.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_GROMPP_H #define GMX_GMXPREPROCESS_GROMPP_H -int gmx_grompp(int argc, char *argv[]); +int gmx_grompp(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/grompp_impl.h b/src/gromacs/gmxpreprocess/grompp_impl.h index 0e38d543e0..1e06a7d6da 100644 --- a/src/gromacs/gmxpreprocess/grompp_impl.h +++ b/src/gromacs/gmxpreprocess/grompp_impl.h @@ -54,71 +54,71 @@ */ class InteractionOfType { - public: - //! Constructor that initializes vectors. - InteractionOfType(gmx::ArrayRef atoms, - gmx::ArrayRef params, - const std::string &name = ""); - /*!@{*/ - //! Access the individual elements set for the parameter. - const int &ai() const; - const int &aj() const; - const int &ak() const; - const int &al() const; - const int &am() const; - - const real &c0() const; - const real &c1() const; - const real &c2() const; - - const std::string &interactionTypeName() const; - /*!@}*/ - - /*! \brief Renumbers atom Ids. - * - * Enforces that ai() is less than the opposite terminal atom index, - * with the number depending on the interaction type. - */ - void sortAtomIds(); - - //! Set single force field parameter. - void setForceParameter(int pos, real value); - - //! View on all atoms numbers that are actually set. - gmx::ArrayRef atoms() { return atoms_; } - //! Const view on all atoms numbers that are actually set. - gmx::ArrayRef atoms() const { return atoms_; } - //! View on all of the force field parameters - gmx::ArrayRef forceParam() const { return forceParam_; } - //! View on all of the force field parameters - gmx::ArrayRef forceParam() { return forceParam_; } - - private: - //! Return if we have a bond parameter, means two atoms right now. - bool isBond() const { return atoms_.size() == 2; } - //! Return if we have an angle parameter, means three atoms right now. - bool isAngle() const { return atoms_.size() == 3; } - //! Return if we have a dihedral parameter, means four atoms right now. - bool isDihedral() const { return atoms_.size() == 4; } - //! Return if we have a cmap parameter, means five atoms right now. - bool isCmap() const { return atoms_.size() == 5; } - //! Enforce that atom id ai() is less than aj(). - void sortBondAtomIds(); - //! Enforce that atom id ai() is less than ak(). Does not change aj(). - void sortAngleAtomIds(); - /*! \brief Enforce order of atoms in dihedral. - * - * Changes atom order if needed to enforce that ai() is less than al(). - * If ai() and al() are swapped, aj() and ak() are swapped as well, - * independent of their previous order. - */ - void sortDihedralAtomIds(); - //! The atom list (eg. bonds: particle, i = atoms[0] (ai), j = atoms[1] (aj)) - std::vector atoms_; - //! Force parameters (eg. b0 = forceParam[0]) - std::array forceParam_; - //! Used with forcefields whose .rtp files name the interaction types (e.g. GROMOS), rather than look them up from the atom names. - std::string interactionTypeName_; +public: + //! Constructor that initializes vectors. + InteractionOfType(gmx::ArrayRef atoms, + gmx::ArrayRef params, + const std::string& name = ""); + /*!@{*/ + //! Access the individual elements set for the parameter. + const int& ai() const; + const int& aj() const; + const int& ak() const; + const int& al() const; + const int& am() const; + + const real& c0() const; + const real& c1() const; + const real& c2() const; + + const std::string& interactionTypeName() const; + /*!@}*/ + + /*! \brief Renumbers atom Ids. + * + * Enforces that ai() is less than the opposite terminal atom index, + * with the number depending on the interaction type. + */ + void sortAtomIds(); + + //! Set single force field parameter. + void setForceParameter(int pos, real value); + + //! View on all atoms numbers that are actually set. + gmx::ArrayRef atoms() { return atoms_; } + //! Const view on all atoms numbers that are actually set. + gmx::ArrayRef atoms() const { return atoms_; } + //! View on all of the force field parameters + gmx::ArrayRef forceParam() const { return forceParam_; } + //! View on all of the force field parameters + gmx::ArrayRef forceParam() { return forceParam_; } + +private: + //! Return if we have a bond parameter, means two atoms right now. + bool isBond() const { return atoms_.size() == 2; } + //! Return if we have an angle parameter, means three atoms right now. + bool isAngle() const { return atoms_.size() == 3; } + //! Return if we have a dihedral parameter, means four atoms right now. + bool isDihedral() const { return atoms_.size() == 4; } + //! Return if we have a cmap parameter, means five atoms right now. + bool isCmap() const { return atoms_.size() == 5; } + //! Enforce that atom id ai() is less than aj(). + void sortBondAtomIds(); + //! Enforce that atom id ai() is less than ak(). Does not change aj(). + void sortAngleAtomIds(); + /*! \brief Enforce order of atoms in dihedral. + * + * Changes atom order if needed to enforce that ai() is less than al(). + * If ai() and al() are swapped, aj() and ak() are swapped as well, + * independent of their previous order. + */ + void sortDihedralAtomIds(); + //! The atom list (eg. bonds: particle, i = atoms[0] (ai), j = atoms[1] (aj)) + std::vector atoms_; + //! Force parameters (eg. b0 = forceParam[0]) + std::array forceParam_; + //! Used with forcefields whose .rtp files name the interaction types (e.g. GROMOS), rather than look them up from the atom names. + std::string interactionTypeName_; }; /*! \libinternal \brief @@ -131,30 +131,30 @@ class InteractionOfType * topology file definition. */ struct InteractionsOfType -{ // NOLINT (clang-analyzer-optin.performance.Padding) +{ // NOLINT (clang-analyzer-optin.performance.Padding) //! The different parameters in the system. std::vector interactionTypes; //! CMAP grid spacing. - int cmakeGridSpacing = -1; + int cmakeGridSpacing = -1; //! Number of cmap angles. - int cmapAngles = -1; + int cmapAngles = -1; //! CMAP grid data. - std::vector cmap; + std::vector cmap; //! The five atomtypes followed by a number that identifies the type. - std::vector cmapAtomTypes; + std::vector cmapAtomTypes; //! Number of parameters. size_t size() const { return interactionTypes.size(); } //! Elements in cmap grid data. - int ncmap() const { return cmap.size(); } + int ncmap() const { return cmap.size(); } //! Number of elements in cmapAtomTypes. - int nct() const { return cmapAtomTypes.size(); } + int nct() const { return cmapAtomTypes.size(); } }; struct t_excls { - int nr; /* The number of exclusions */ - int *e; /* The excluded atoms */ + int nr; /* The number of exclusions */ + int* e; /* The excluded atoms */ }; @@ -164,21 +164,21 @@ struct t_excls struct MoleculeInformation { //! Name of the molecule. - char **name = nullptr; - //!Number of exclusions per atom. - int nrexcl = 0; + char** name = nullptr; + //! Number of exclusions per atom. + int nrexcl = 0; //! Have exclusions been generated?. - bool excl_set = false; + bool excl_set = false; //! Has the mol been processed. - bool bProcessed = false; + bool bProcessed = false; //! Atoms in the moelcule. - t_atoms atoms; + t_atoms atoms; //! Molecules separated in datastructure. - t_block mols; + t_block mols; //! Exclusions in the molecule. - t_blocka excls; + t_blocka excls; //! Interactions of a defined type. - std::array interactions; + std::array interactions; /*! \brief * Initializer. diff --git a/src/gromacs/gmxpreprocess/h_db.cpp b/src/gromacs/gmxpreprocess/h_db.cpp index 8edb6ceb8e..1a3e257e2d 100644 --- a/src/gromacs/gmxpreprocess/h_db.cpp +++ b/src/gromacs/gmxpreprocess/h_db.cpp @@ -70,7 +70,7 @@ const int ncontrol[] = { -1, 3, 3, 3, 3, 4, 3, 1, 3, 3, 1, 1 }; #define maxcontrol asize(ncontrol) -void print_ab(FILE *out, const MoleculePatch &hack, const char *nname) +void print_ab(FILE* out, const MoleculePatch& hack, const char* nname) { fprintf(out, "%d\t%d\t%s", hack.nr, hack.tp, nname); for (int i = 0; (i < hack.nctl); i++) @@ -81,7 +81,7 @@ void print_ab(FILE *out, const MoleculePatch &hack, const char *nname) } -void read_ab(char *line, const char *fn, MoleculePatch *hack) +void read_ab(char* line, const char* fn, MoleculePatch* hack) { int nh, tp, ns; char a[4][12]; @@ -97,13 +97,17 @@ void read_ab(char *line, const char *fn, MoleculePatch *hack) hack->tp = tp; if ((tp < 1) || (tp >= maxcontrol)) { - gmx_fatal(FARGS, "Error in hdb file %s:\nH-type should be in 1-%d. Offending line:\n%s", fn, maxcontrol-1, line); + gmx_fatal(FARGS, "Error in hdb file %s:\nH-type should be in 1-%d. Offending line:\n%s", fn, + maxcontrol - 1, line); } hack->nctl = ns - 3; if ((hack->nctl != ncontrol[hack->tp]) && (ncontrol[hack->tp] != -1)) { - gmx_fatal(FARGS, "Error in hdb file %s:\nWrong number of control atoms (%d instead of %d) on line:\n%s\n", fn, hack->nctl, ncontrol[hack->tp], line); + gmx_fatal(FARGS, + "Error in hdb file %s:\nWrong number of control atoms (%d instead of %d) on " + "line:\n%s\n", + fn, hack->nctl, ncontrol[hack->tp], line); } for (int i = 0; (i < hack->nctl); i++) { @@ -120,9 +124,9 @@ void read_ab(char *line, const char *fn, MoleculePatch *hack) } } -static void read_h_db_file(const char *hfn, std::vector *globalPatches) +static void read_h_db_file(const char* hfn, std::vector* globalPatches) { - char filebase[STRLEN], line[STRLEN], buf[STRLEN]; + char filebase[STRLEN], line[STRLEN], buf[STRLEN]; fflib_filename_base(hfn, filebase, STRLEN); /* Currently filebase is read and set, but not used. @@ -130,9 +134,9 @@ static void read_h_db_file(const char *hfn, std::vector * * in any rtp file. */ - FILE *in = fflib_open(hfn); + FILE* in = fflib_open(hfn); - while (fgets2(line, STRLEN-1, in)) + while (fgets2(line, STRLEN - 1, in)) { // Skip lines that are only whitespace if (gmx::countWords(line) == 0) @@ -143,26 +147,26 @@ static void read_h_db_file(const char *hfn, std::vector * if (sscanf(line, "%s%n", buf, &n) != 1) { int size = globalPatches->size(); - fprintf(stderr, "Error in hdb file: nah = %d\nline = '%s'\n", - size, line); + fprintf(stderr, "Error in hdb file: nah = %d\nline = '%s'\n", size, line); break; } globalPatches->emplace_back(MoleculePatchDatabase()); - MoleculePatchDatabase *block = &globalPatches->back(); + MoleculePatchDatabase* block = &globalPatches->back(); clearModificationBlock(block); block->name = buf; block->filebase = filebase; int nab; - if (sscanf(line+n, "%d", &nab) == 1) + if (sscanf(line + n, "%d", &nab) == 1) { for (int i = 0; (i < nab); i++) { if (feof(in)) { - gmx_fatal(FARGS, "Expected %d lines of hydrogens, found only %d " + gmx_fatal(FARGS, + "Expected %d lines of hydrogens, found only %d " "while reading Hydrogen Database %s residue %s", - nab, i-1, block->name.c_str(), hfn); + nab, i - 1, block->name.c_str(), hfn); } if (nullptr == fgets(buf, STRLEN, in)) { @@ -179,15 +183,17 @@ static void read_h_db_file(const char *hfn, std::vector * { /* Sort the list for searching later */ std::sort(globalPatches->begin(), globalPatches->end(), - [](const MoleculePatchDatabase &a1, const MoleculePatchDatabase &a2) - { return std::lexicographical_compare(a1.name.begin(), a1.name.end(), - a2.name.begin(), a2.name.end(), - [](const char &c1, const char &c2) - { return std::toupper(c1) < std::toupper(c2); }); }); + [](const MoleculePatchDatabase& a1, const MoleculePatchDatabase& a2) { + return std::lexicographical_compare( + a1.name.begin(), a1.name.end(), a2.name.begin(), a2.name.end(), + [](const char& c1, const char& c2) { + return std::toupper(c1) < std::toupper(c2); + }); + }); } } -int read_h_db(const char *ffdir, std::vector *globalPatches) +int read_h_db(const char* ffdir, std::vector* globalPatches) { /* Read the hydrogen database file(s). * Do not generate an error when no files are found. @@ -195,7 +201,7 @@ int read_h_db(const char *ffdir, std::vector *globalPatch std::vector hdbf = fflib_search_file_end(ffdir, ".hdb", FALSE); globalPatches->clear(); - for (const auto &filename : hdbf) + for (const auto& filename : hdbf) { read_h_db_file(filename.c_str(), globalPatches); } @@ -203,9 +209,9 @@ int read_h_db(const char *ffdir, std::vector *globalPatch } gmx::ArrayRef::iterator -search_h_db(gmx::ArrayRef globalPatches, const char *key) +search_h_db(gmx::ArrayRef globalPatches, const char* key) { - return std::find_if(globalPatches.begin(), globalPatches.end(), - [&key](const MoleculePatchDatabase &a) - { return gmx::equalCaseInsensitive(key, a.name); }); + return std::find_if( + globalPatches.begin(), globalPatches.end(), + [&key](const MoleculePatchDatabase& a) { return gmx::equalCaseInsensitive(key, a.name); }); } diff --git a/src/gromacs/gmxpreprocess/h_db.h b/src/gromacs/gmxpreprocess/h_db.h index ac8409e8ec..6f68c7ed32 100644 --- a/src/gromacs/gmxpreprocess/h_db.h +++ b/src/gromacs/gmxpreprocess/h_db.h @@ -49,7 +49,7 @@ struct MoleculePatchDatabase; /* functions for the h-database */ -void read_ab(char *line, const char *fn, MoleculePatch *ab); +void read_ab(char* line, const char* fn, MoleculePatch* ab); /* Read one add block */ /*! \brief @@ -59,9 +59,9 @@ void read_ab(char *line, const char *fn, MoleculePatch *ab); * \param[inout] globalPatches The database for atom modifications to populate. * \returns The number of modifications stored. */ -int read_h_db(const char *ffdir, std::vector *globalPatches); +int read_h_db(const char* ffdir, std::vector* globalPatches); -void print_ab(FILE *out, const MoleculePatch &ab, const char *nname); +void print_ab(FILE* out, const MoleculePatch& ab, const char* nname); /* print one add block */ /*! \brief @@ -71,7 +71,7 @@ void print_ab(FILE *out, const MoleculePatch &ab, const char *nname); * \param[in] key Name to search for. */ gmx::ArrayRef::iterator -search_h_db(gmx::ArrayRef globalPatches, const char *key); +search_h_db(gmx::ArrayRef globalPatches, const char* key); /* Search for an entry in the database */ #endif diff --git a/src/gromacs/gmxpreprocess/hackblock.cpp b/src/gromacs/gmxpreprocess/hackblock.cpp index dc69417ca7..56422819e0 100644 --- a/src/gromacs/gmxpreprocess/hackblock.cpp +++ b/src/gromacs/gmxpreprocess/hackblock.cpp @@ -53,8 +53,8 @@ #include "gromacs/utility/smalloc.h" /* these MUST correspond to the enum in hackblock.h */ -const char *btsNames[ebtsNR] = { "bonds", "angles", "dihedrals", "impropers", "exclusions", "cmap" }; -const int btsNiatoms[ebtsNR] = { 2, 3, 4, 4, 2, 5 }; +const char* btsNames[ebtsNR] = { "bonds", "angles", "dihedrals", "impropers", "exclusions", "cmap" }; +const int btsNiatoms[ebtsNR] = { 2, 3, 4, 4, 2, 5 }; MoleculePatchType MoleculePatch::type() const { @@ -76,7 +76,7 @@ MoleculePatchType MoleculePatch::type() const } } -void clearModificationBlock(MoleculePatchDatabase *globalPatches) +void clearModificationBlock(MoleculePatchDatabase* globalPatches) { globalPatches->name.clear(); globalPatches->hack.clear(); @@ -88,7 +88,7 @@ void clearModificationBlock(MoleculePatchDatabase *globalPatches) #define safe_strdup(str) (((str) != NULL) ? gmx_strdup(str) : NULL) -static bool contains_char(const BondedInteraction &s, char c) +static bool contains_char(const BondedInteraction& s, char c) { bool bRet = false; @@ -103,12 +103,13 @@ static bool contains_char(const BondedInteraction &s, char c) return bRet; } -static int -rbonded_find_atoms_in_list(const BondedInteraction &b, gmx::ArrayRef blist, int natoms) +static int rbonded_find_atoms_in_list(const BondedInteraction& b, + gmx::ArrayRef blist, + int natoms) { - int foundPos = -1; + int foundPos = -1; - for (auto it = blist.begin(); (it != blist.end()) && ( foundPos < 0); it++) + for (auto it = blist.begin(); (it != blist.end()) && (foundPos < 0); it++) { bool atomsMatch = true; for (int k = 0; k < natoms && atomsMatch; k++) @@ -121,7 +122,7 @@ rbonded_find_atoms_in_list(const BondedInteraction &b, gmx::ArrayRefa[natoms-1-k]); + atomsMatch = atomsMatch && (b.a[k] == it->a[natoms - 1 - k]); } } if (atomsMatch) @@ -169,7 +170,7 @@ bool mergeBondedInteractionList(gmx::ArrayRef s, */ int nbHackblockStart = d[i].b.size(); - for (const auto &b : s[i].b) + for (const auto& b : s[i].b) { /* Check if this bonded string already exists before adding. * We are merging from the main RTP to the hackblocks, so this @@ -194,8 +195,7 @@ bool mergeBondedInteractionList(gmx::ArrayRef s, */ if (index < 0 || index >= nbHackblockStart) { - if (!(bMin && contains_char(b, '-')) - && !(bPlus && contains_char(b, '+'))) + if (!(bMin && contains_char(b, '-')) && !(bPlus && contains_char(b, '+'))) { d[i].b.push_back(b); } @@ -216,21 +216,21 @@ bool mergeBondedInteractionList(gmx::ArrayRef s, return bBondsRemoved; } -void copyPreprocessResidues(const PreprocessResidue &s, PreprocessResidue *d, t_symtab *symtab) +void copyPreprocessResidues(const PreprocessResidue& s, PreprocessResidue* d, t_symtab* symtab) { - *d = s; + *d = s; d->atom.clear(); - for (const auto &a : s.atom) + for (const auto& a : s.atom) { d->atom.push_back(a); } d->atomname.clear(); - for (const auto &a : s.atomname) + for (const auto& a : s.atomname) { d->atomname.push_back(put_symtab(symtab, *a)); } d->cgnr.clear(); - for (const auto &c : s.cgnr) + for (const auto& c : s.cgnr) { d->cgnr.push_back(c); } @@ -242,24 +242,24 @@ void copyPreprocessResidues(const PreprocessResidue &s, PreprocessResidue *d, t_ mergeBondedInteractionList(s.rb, d->rb, FALSE, FALSE); } -void mergeAtomModifications(const MoleculePatchDatabase &s, MoleculePatchDatabase *d) +void mergeAtomModifications(const MoleculePatchDatabase& s, MoleculePatchDatabase* d) { - for (const auto &h : s.hack) + for (const auto& h : s.hack) { d->hack.push_back(h); } } -void mergeAtomAndBondModifications(const MoleculePatchDatabase &s, MoleculePatchDatabase *d) +void mergeAtomAndBondModifications(const MoleculePatchDatabase& s, MoleculePatchDatabase* d) { mergeAtomModifications(s, d); mergeBondedInteractionList(s.rb, d->rb, FALSE, FALSE); } -void copyModificationBlocks(const MoleculePatchDatabase &s, MoleculePatchDatabase *d) +void copyModificationBlocks(const MoleculePatchDatabase& s, MoleculePatchDatabase* d) { - *d = s; - d->name = s.name; + *d = s; + d->name = s.name; d->hack.clear(); for (int i = 0; i < ebtsNR; i++) { diff --git a/src/gromacs/gmxpreprocess/hackblock.h b/src/gromacs/gmxpreprocess/hackblock.h index cfc1e57cb9..9fa36722eb 100644 --- a/src/gromacs/gmxpreprocess/hackblock.h +++ b/src/gromacs/gmxpreprocess/hackblock.h @@ -57,13 +57,20 @@ struct t_symtab; * ebtsBONDS must be the first, new types can be added to the end * these *MUST* correspond to the arrays in hackblock.cpp */ -enum { - ebtsBONDS, ebtsANGLES, ebtsPDIHS, ebtsIDIHS, ebtsEXCLS, ebtsCMAP, ebtsNR +enum +{ + ebtsBONDS, + ebtsANGLES, + ebtsPDIHS, + ebtsIDIHS, + ebtsEXCLS, + ebtsCMAP, + ebtsNR }; //! Names for interaction type entries -extern const char *btsNames[ebtsNR]; +extern const char* btsNames[ebtsNR]; //! Numbers for atoms in the interactions. -extern const int btsNiatoms[ebtsNR]; +extern const int btsNiatoms[ebtsNR]; /* if changing any of these structs, make sure that all of the free/clear/copy/merge_t_* functions stay updated */ @@ -80,19 +87,19 @@ struct BondedInteraction * .rtp/.tdb to .top and will be parsed by cpp * during grompp. */ - std::string s; + std::string s; //! Has the entry been found? - bool match = false; + bool match = false; //! Get name of first atom in bonded interaction. - const std::string &ai() const { return a[0]; } + const std::string& ai() const { return a[0]; } //! Get name of second atom in bonded interaction.. - const std::string &aj() const { return a[1]; } + const std::string& aj() const { return a[1]; } //! Get name of third atom in bonded interaction. - const std::string &ak() const { return a[2]; } + const std::string& ak() const { return a[2]; } //! Get name of fourth atom in bonded interaction. - const std::string &al() const { return a[3]; } + const std::string& al() const { return a[3]; } //! Get name of fifth atom in bonded interaction. - const std::string &am() const { return a[4]; } + const std::string& am() const { return a[4]; } }; /*! \libinternal \brief @@ -102,7 +109,7 @@ struct BondedInteraction struct BondedInteractionList { //! The type of bonded interaction. - int type = -1; + int type = -1; //! The actual bonded interactions. std::vector b; }; @@ -113,27 +120,27 @@ struct BondedInteractionList struct PreprocessResidue { //! Name of the residue. - std::string resname; + std::string resname; //! The base file name this rtp entry was read from. - std::string filebase; + std::string filebase; //! Atom data. - std::vector atom; + std::vector atom; //! Atom names. - std::vector atomname; + std::vector atomname; //! Charge group numbers. - std::vector cgnr; + std::vector cgnr; //! Delete autogenerated dihedrals or not. - bool bKeepAllGeneratedDihedrals = false; + bool bKeepAllGeneratedDihedrals = false; //! Number of bonded exclusions. - int nrexcl = -1; + int nrexcl = -1; //! If Hydrogen only 1-4 interactions should be generated. - bool bGenerateHH14Interactions = false; + bool bGenerateHH14Interactions = false; //! Delete dihedrals also defined by impropers. - bool bRemoveDihedralIfWithImproper = false; + bool bRemoveDihedralIfWithImproper = false; //! List of bonded interactions to potentially add. std::array rb; //! Get number of atoms in residue. - int natom() const { return atom.size(); } + int natom() const { return atom.size(); } }; //! Declare different types of hacks for later check. @@ -153,29 +160,29 @@ enum class MoleculePatchType struct MoleculePatch { //! Number of new are deleted atoms. NOT always equal to atom.size()! - int nr; + int nr; //! Old name for entry. - std::string oname; + std::string oname; //! New name for entry. - std::string nname; + std::string nname; //! New atom data. - std::vector atom; + std::vector atom; //! Chargegroup number. - int cgnr = NOTSET; + int cgnr = NOTSET; //! Type of attachement. - int tp = 0; + int tp = 0; //! Number of control atoms. - int nctl = 0; + int nctl = 0; //! Name of control atoms. std::array a; //! Is an atom to be hacked already present? - bool bAlreadyPresent = false; + bool bAlreadyPresent = false; //! Are coordinates for a new atom already set? - bool bXSet = false; + bool bXSet = false; //! New position for hacked atom. - rvec newx = {NOTSET}; + rvec newx = { NOTSET }; //! New atom index number after additions. - int newi = -1; + int newi = -1; /*! \brief * Get type of hack. @@ -189,13 +196,13 @@ struct MoleculePatch MoleculePatchType type() const; //! Control atom i name. - const std::string &ai() const { return a[0]; } + const std::string& ai() const { return a[0]; } //! Control atom j name. - const std::string &aj() const { return a[1]; } + const std::string& aj() const { return a[1]; } //! Control atom k name. - const std::string &ak() const { return a[2]; } + const std::string& ak() const { return a[2]; } //! Control atom l name. - const std::string &al() const { return a[3]; } + const std::string& al() const { return a[3]; } }; /*! \libinternal \brief * A set of modifications to apply to atoms. @@ -203,15 +210,15 @@ struct MoleculePatch struct MoleculePatchDatabase { //! Name of block - std::string name; + std::string name; //! File that entry was read from. - std::string filebase; + std::string filebase; //! List of changes to atoms. - std::vector hack; + std::vector hack; //! List of bonded interactions to potentially add. - std::array rb; + std::array rb; //! Number of atoms to modify - int nhack() const { return hack.size(); } + int nhack() const { return hack.size(); } }; /*!\brief @@ -220,7 +227,7 @@ struct MoleculePatchDatabase * \param[inout] globalPatches Block to reset. * \todo Remove once constructor/destructor takes care of all of this. */ -void clearModificationBlock(MoleculePatchDatabase *globalPatches); +void clearModificationBlock(MoleculePatchDatabase* globalPatches); /*!\brief * Copy residue information. @@ -230,7 +237,7 @@ void clearModificationBlock(MoleculePatchDatabase *globalPatches); * \param[inout] symtab Symbol table for names. * \todo Remove once copy can be done directly. */ -void copyPreprocessResidues(const PreprocessResidue &s, PreprocessResidue *d, t_symtab *symtab); +void copyPreprocessResidues(const PreprocessResidue& s, PreprocessResidue* d, t_symtab* symtab); /*! \brief * Add bond information in \p s to \p d. @@ -242,8 +249,9 @@ void copyPreprocessResidues(const PreprocessResidue &s, PreprocessResidue *d, t_ * \returns if bonds were removed at the termini. */ bool mergeBondedInteractionList(gmx::ArrayRef s, - gmx::ArrayRef d, - bool bMin, bool bPlus); + gmx::ArrayRef d, + bool bMin, + bool bPlus); /*! \brief * Copy all information from datastructure. @@ -251,7 +259,7 @@ bool mergeBondedInteractionList(gmx::ArrayRef s, * \param[in] s Source information. * \param[inout] d Destination to copy to. */ -void copyModificationBlocks(const MoleculePatchDatabase &s, MoleculePatchDatabase *d); +void copyModificationBlocks(const MoleculePatchDatabase& s, MoleculePatchDatabase* d); /*!\brief * Add the individual modifications in \p s to \p d. @@ -259,9 +267,9 @@ void copyModificationBlocks(const MoleculePatchDatabase &s, MoleculePatchDatabas * \param[in] s Source information. * \param[inout] d Destination to copy to. */ -void mergeAtomModifications(const MoleculePatchDatabase &s, MoleculePatchDatabase *d); +void mergeAtomModifications(const MoleculePatchDatabase& s, MoleculePatchDatabase* d); //! \copydoc mergeAtomModifications -void mergeAtomAndBondModifications(const MoleculePatchDatabase &s, MoleculePatchDatabase *d); +void mergeAtomAndBondModifications(const MoleculePatchDatabase& s, MoleculePatchDatabase* d); #endif diff --git a/src/gromacs/gmxpreprocess/hizzie.cpp b/src/gromacs/gmxpreprocess/hizzie.cpp index f8b39e0e8e..3244b51e2a 100644 --- a/src/gromacs/gmxpreprocess/hizzie.cpp +++ b/src/gromacs/gmxpreprocess/hizzie.cpp @@ -56,7 +56,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static int in_strings(char *key, int nstr, const char **str) +static int in_strings(char* key, int nstr, const char** str) { int j; @@ -73,32 +73,31 @@ static int in_strings(char *key, int nstr, const char **str) static bool hbond(rvec x[], int i, int j, real distance) { - real tol = distance*distance; - rvec tmp; + real tol = distance * distance; + rvec tmp; rvec_sub(x[i], x[j], tmp); return (iprod(tmp, tmp) < tol); } -static void chk_allhb(t_atoms *pdba, rvec x[], t_blocka *hb, - const bool donor[], const bool accept[], real dist) +static void chk_allhb(t_atoms* pdba, rvec x[], t_blocka* hb, const bool donor[], const bool accept[], real dist) { int i, j, k, ii, natom; natom = pdba->nr; - snew(hb->index, natom+1); - snew(hb->a, 6*natom); + snew(hb->index, natom + 1); + snew(hb->a, 6 * natom); hb->nr = natom; - hb->nra = 6*natom; + hb->nra = 6 * natom; - k = ii = 0; + k = ii = 0; hb->index[ii++] = 0; for (i = 0; (i < natom); i++) { if (donor[i]) { - for (j = i+1; (j < natom); j++) + for (j = i + 1; (j < natom); j++) { if ((accept[j]) && (hbond(x, i, j, dist))) { @@ -108,7 +107,7 @@ static void chk_allhb(t_atoms *pdba, rvec x[], t_blocka *hb, } else if (accept[i]) { - for (j = i+1; (j < natom); j++) + for (j = i + 1; (j < natom); j++) { if ((donor[j]) && (hbond(x, i, j, dist))) { @@ -121,14 +120,12 @@ static void chk_allhb(t_atoms *pdba, rvec x[], t_blocka *hb, hb->nra = k; } -static bool chk_hbonds(int i, t_atoms *pdba, rvec x[], - const bool ad[], bool hbond[], rvec xh, - real angle, real dist) +static bool chk_hbonds(int i, t_atoms* pdba, rvec x[], const bool ad[], bool hbond[], rvec xh, real angle, real dist) { - bool bHB; - int j, aj, ri, natom; - real d2, dist2, a; - rvec nh, oh; + bool bHB; + int j, aj, ri, natom; + real d2, dist2, a; + rvec nh, oh; natom = pdba->nr; bHB = FALSE; @@ -140,15 +137,14 @@ static bool chk_hbonds(int i, t_atoms *pdba, rvec x[], if ((ad[j]) && (j != i)) { /* Check whether the other atom is on the same ring as well */ - if ((pdba->atom[j].resind != ri) || - ((strcmp(*pdba->atomname[j], "ND1") != 0) && - (strcmp(*pdba->atomname[j], "NE2") != 0))) + if ((pdba->atom[j].resind != ri) + || ((strcmp(*pdba->atomname[j], "ND1") != 0) && (strcmp(*pdba->atomname[j], "NE2") != 0))) { - aj = j; - d2 = distance2(x[i], x[j]); + aj = j; + d2 = distance2(x[i], x[j]); rvec_sub(x[i], xh, nh); rvec_sub(x[aj], xh, oh); - a = RAD2DEG * acos(cos_angle(nh, oh)); + a = RAD2DEG * acos(cos_angle(nh, oh)); if ((d2 < dist2) && (a > angle)) { hbond[i] = TRUE; @@ -169,37 +165,33 @@ static void calc_ringh(rvec xattach, rvec xb, rvec xc, rvec xh) rvec_sub(xattach, xb, tab); rvec_sub(xattach, xc, tac); rvec_add(tab, tac, xh); - n = 0.1/norm(xh); + n = 0.1 / norm(xh); svmul(n, xh, xh); rvec_inc(xh, xattach); } -void set_histp(t_atoms *pdba, rvec *x, t_symtab *symtab, real angle, real dist) +void set_histp(t_atoms* pdba, rvec* x, t_symtab* symtab, real angle, real dist) { - static const char *prot_acc[] = { - "O", "OD1", "OD2", "OE1", "OE2", "OG", "OG1", "OH", "OW" - }; + static const char* prot_acc[] = { "O", "OD1", "OD2", "OE1", "OE2", "OG", "OG1", "OH", "OW" }; #define NPA asize(prot_acc) - static const char *prot_don[] = { - "N", "NH1", "NH2", "NE", "ND1", "ND2", "NE2", "NZ", "OG", "OG1", "OH", "NE1", "OW" - }; + static const char* prot_don[] = { "N", "NH1", "NH2", "NE", "ND1", "ND2", "NE2", + "NZ", "OG", "OG1", "OH", "NE1", "OW" }; #define NPD asize(prot_don) - bool *donor, *acceptor; - bool *hbond; + bool * donor, *acceptor; + bool* hbond; bool bHDd, bHEd; rvec xh1, xh2; int natom; int i, j, nd, na, hisind, type = -1; int nd1, ne2, cg, cd2, ce1; - t_blocka *hb; - char *atomnm; + t_blocka* hb; + char* atomnm; natom = pdba->nr; i = 0; - while (i < natom && - gmx_strcasecmp(*pdba->resinfo[pdba->atom[i].resind].name, "HIS") != 0) + while (i < natom && gmx_strcasecmp(*pdba->resinfo[pdba->atom[i].resind].name, "HIS") != 0) { i++; } @@ -262,7 +254,7 @@ void set_histp(t_atoms *pdba, rvec *x, t_symtab *symtab, real angle, real dist) } else if (strcmp(atomnm, "CG") == 0) { - cg = i; + cg = i; } else if (strcmp(atomnm, "CE1") == 0) { @@ -280,8 +272,7 @@ void set_histp(t_atoms *pdba, rvec *x, t_symtab *symtab, real angle, real dist) i++; } - if (!((cg == -1 ) || (cd2 == -1) || (ce1 == -1) || - (nd1 == -1) || (ne2 == -1))) + if (!((cg == -1) || (cd2 == -1) || (ce1 == -1) || (nd1 == -1) || (ne2 == -1))) { calc_ringh(x[nd1], x[cg], x[ce1], xh1); calc_ringh(x[ne2], x[ce1], x[cd2], xh2); @@ -306,13 +297,11 @@ void set_histp(t_atoms *pdba, rvec *x, t_symtab *symtab, real angle, real dist) { type = ehisB; } - fprintf(stderr, "Will use %s for residue %d\n", - hh[type], pdba->resinfo[hisind].nr); + fprintf(stderr, "Will use %s for residue %d\n", hh[type], pdba->resinfo[hisind].nr); } else { - gmx_fatal(FARGS, "Incomplete ring in HIS%d", - pdba->resinfo[hisind].nr); + gmx_fatal(FARGS, "Incomplete ring in HIS%d", pdba->resinfo[hisind].nr); } pdba->resinfo[hisind].rtp = put_symtab(symtab, hh[type]); diff --git a/src/gromacs/gmxpreprocess/hizzie.h b/src/gromacs/gmxpreprocess/hizzie.h index f453a499d3..2c7127917c 100644 --- a/src/gromacs/gmxpreprocess/hizzie.h +++ b/src/gromacs/gmxpreprocess/hizzie.h @@ -44,7 +44,7 @@ struct t_atoms; struct t_symtab; -void set_histp(t_atoms *pdba, rvec *x, t_symtab *symtab, real angle, real distance); +void set_histp(t_atoms* pdba, rvec* x, t_symtab* symtab, real angle, real distance); /* calculate HIStidine protonation state */ #endif diff --git a/src/gromacs/gmxpreprocess/insert_molecules.cpp b/src/gromacs/gmxpreprocess/insert_molecules.cpp index 8f7df5bbbc..b7684ba057 100644 --- a/src/gromacs/gmxpreprocess/insert_molecules.cpp +++ b/src/gromacs/gmxpreprocess/insert_molecules.cpp @@ -79,31 +79,35 @@ using gmx::RVec; /* enum for random rotations of inserted solutes */ -enum RotationType { - en_rotXYZ, en_rotZ, en_rotNone +enum RotationType +{ + en_rotXYZ, + en_rotZ, + en_rotNone }; -const char *const cRotationEnum[] = {"xyz", "z", "none"}; +const char* const cRotationEnum[] = { "xyz", "z", "none" }; static void center_molecule(gmx::ArrayRef x) { - rvec center = {0}; - for (auto &xi : x) + rvec center = { 0 }; + for (auto& xi : x) { rvec_inc(center, xi); } - svmul(1.0/x.size(), center, center); - for (auto &xi : x) + svmul(1.0 / x.size(), center, center); + for (auto& xi : x) { rvec_dec(xi, center); } } -static void generate_trial_conf(gmx::ArrayRef xin, - const rvec offset, RotationType enum_rot, - gmx::DefaultRandomEngine * rng, - std::vector *xout) +static void generate_trial_conf(gmx::ArrayRef xin, + const rvec offset, + RotationType enum_rot, + gmx::DefaultRandomEngine* rng, + std::vector* xout) { - gmx::UniformRealDistribution dist(0, 2.0*M_PI); + gmx::UniformRealDistribution dist(0, 2.0 * M_PI); xout->assign(xin.begin(), xin.end()); real alfa = 0.0, beta = 0.0, gamma = 0.0; @@ -115,12 +119,10 @@ static void generate_trial_conf(gmx::ArrayRef xin, gamma = dist(*rng); break; case en_rotZ: - alfa = beta = 0.; - gamma = dist(*rng); - break; - case en_rotNone: - alfa = beta = gamma = 0.; + alfa = beta = 0.; + gamma = dist(*rng); break; + case en_rotNone: alfa = beta = gamma = 0.; break; } if (enum_rot == en_rotXYZ || enum_rot == en_rotZ) { @@ -132,13 +134,13 @@ static void generate_trial_conf(gmx::ArrayRef xin, } } -static bool isInsertionAllowed(gmx::AnalysisNeighborhoodSearch *search, - const std::vector &exclusionDistances, - const std::vector &x, - const std::vector &exclusionDistances_insrt, - const t_atoms &atoms, - const std::set &removableAtoms, - gmx::AtomsRemover *remover) +static bool isInsertionAllowed(gmx::AnalysisNeighborhoodSearch* search, + const std::vector& exclusionDistances, + const std::vector& x, + const std::vector& exclusionDistances_insrt, + const t_atoms& atoms, + const std::set& removableAtoms, + gmx::AtomsRemover* remover) { gmx::AnalysisNeighborhoodPositions pos(x); gmx::AnalysisNeighborhoodPairSearch pairSearch = search->startPairSearch(pos); @@ -161,31 +163,36 @@ static bool isInsertionAllowed(gmx::AnalysisNeighborhoodSearch *search, return true; } -static void insert_mols(int nmol_insrt, int ntry, int seed, - real defaultDistance, real scaleFactor, - t_atoms *atoms, t_symtab *symtab, std::vector *x, - const std::set &removableAtoms, - const t_atoms &atoms_insrt, gmx::ArrayRef x_insrt, - int ePBC, matrix box, - const std::string &posfn, const rvec deltaR, - RotationType enum_rot) +static void insert_mols(int nmol_insrt, + int ntry, + int seed, + real defaultDistance, + real scaleFactor, + t_atoms* atoms, + t_symtab* symtab, + std::vector* x, + const std::set& removableAtoms, + const t_atoms& atoms_insrt, + gmx::ArrayRef x_insrt, + int ePBC, + matrix box, + const std::string& posfn, + const rvec deltaR, + RotationType enum_rot) { fprintf(stderr, "Initialising inter-atomic distances...\n"); - AtomProperties aps; - std::vector exclusionDistances( - makeExclusionDistances(atoms, &aps, defaultDistance, scaleFactor)); + AtomProperties aps; + std::vector exclusionDistances(makeExclusionDistances(atoms, &aps, defaultDistance, scaleFactor)); const std::vector exclusionDistances_insrt( makeExclusionDistances(&atoms_insrt, &aps, defaultDistance, scaleFactor)); - const real maxInsertRadius - = *std::max_element(exclusionDistances_insrt.begin(), - exclusionDistances_insrt.end()); - real maxRadius = maxInsertRadius; + const real maxInsertRadius = + *std::max_element(exclusionDistances_insrt.begin(), exclusionDistances_insrt.end()); + real maxRadius = maxInsertRadius; if (!exclusionDistances.empty()) { - const real maxExistingRadius - = *std::max_element(exclusionDistances.begin(), - exclusionDistances.end()); + const real maxExistingRadius = + *std::max_element(exclusionDistances.begin(), exclusionDistances.end()); maxRadius = std::max(maxInsertRadius, maxExistingRadius); } @@ -202,23 +209,21 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, gmx::DefaultRandomEngine rng(seed); - t_pbc pbc; + t_pbc pbc; set_pbc(&pbc, ePBC, box); /* With -ip, take nmol_insrt from file posfn */ - double **rpos = nullptr; - const bool insertAtPositions = !posfn.empty(); + double** rpos = nullptr; + const bool insertAtPositions = !posfn.empty(); if (insertAtPositions) { int ncol; nmol_insrt = read_xvg(posfn.c_str(), &rpos, &ncol); if (ncol != 3) { - gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n", - posfn.c_str()); + gmx_fatal(FARGS, "Expected 3 columns (x/y/z coordinates) in file %s\n", posfn.c_str()); } - fprintf(stderr, "Read %d positions from file %s\n\n", - nmol_insrt, posfn.c_str()); + fprintf(stderr, "Read %d positions from file %s\n\n", nmol_insrt, posfn.c_str()); } gmx::AtomsBuilder builder(atoms, symtab); @@ -231,15 +236,15 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, exclusionDistances.reserve(finalAtomCount); } - std::vector x_n(x_insrt.size()); + std::vector x_n(x_insrt.size()); - int mol = 0; - int trial = 0; - int firstTrial = 0; - int failed = 0; - gmx::UniformRealDistribution dist; + int mol = 0; + int trial = 0; + int firstTrial = 0; + int failed = 0; + gmx::UniformRealDistribution dist; - while (mol < nmol_insrt && trial < ntry*nmol_insrt) + while (mol < nmol_insrt && trial < ntry * nmol_insrt) { rvec offset_x; if (!insertAtPositions) @@ -254,17 +259,17 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, // Skip a position if ntry trials were not successful. if (trial >= firstTrial + ntry) { - fprintf(stderr, " skipped position (%.3f, %.3f, %.3f)\n", - rpos[XX][mol], rpos[YY][mol], rpos[ZZ][mol]); + fprintf(stderr, " skipped position (%.3f, %.3f, %.3f)\n", rpos[XX][mol], + rpos[YY][mol], rpos[ZZ][mol]); ++mol; ++failed; firstTrial = trial; continue; } // Insert at positions taken from option -ip file. - offset_x[XX] = rpos[XX][mol] + deltaR[XX]*(2 * dist(rng)-1); - offset_x[YY] = rpos[YY][mol] + deltaR[YY]*(2 * dist(rng)-1); - offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ]*(2 * dist(rng)-1); + offset_x[XX] = rpos[XX][mol] + deltaR[XX] * (2 * dist(rng) - 1); + offset_x[YY] = rpos[YY][mol] + deltaR[YY] * (2 * dist(rng) - 1); + offset_x[ZZ] = rpos[ZZ][mol] + deltaR[ZZ] * (2 * dist(rng) - 1); } fprintf(stderr, "\rTry %d", ++trial); fflush(stderr); @@ -272,12 +277,11 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, generate_trial_conf(x_insrt, offset_x, enum_rot, &rng, &x_n); gmx::AnalysisNeighborhoodPositions pos(*x); gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, pos); - if (isInsertionAllowed(&search, exclusionDistances, x_n, exclusionDistances_insrt, - *atoms, removableAtoms, &remover)) + if (isInsertionAllowed(&search, exclusionDistances, x_n, exclusionDistances_insrt, *atoms, + removableAtoms, &remover)) { x->insert(x->end(), x_n.begin(), x_n.end()); - exclusionDistances.insert(exclusionDistances.end(), - exclusionDistances_insrt.begin(), + exclusionDistances.insert(exclusionDistances.end(), exclusionDistances_insrt.begin(), exclusionDistances_insrt.end()); builder.mergeAtoms(atoms_insrt); ++mol; @@ -288,8 +292,7 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, fprintf(stderr, "\n"); /* print number of molecules added */ - fprintf(stderr, "Added %d molecules (out of %d requested)\n", - mol - failed, nmol_insrt); + fprintf(stderr, "Added %d molecules (out of %d requested)\n", mol - failed, nmol_insrt); const int originalAtomCount = atoms->nr; const int originalResidueCount = atoms->nres; @@ -298,8 +301,7 @@ static void insert_mols(int nmol_insrt, int ntry, int seed, remover.removeMarkedAtoms(atoms); if (atoms->nr < originalAtomCount) { - fprintf(stderr, "Replaced %d residues (%d atoms)\n", - originalResidueCount - atoms->nres, + fprintf(stderr, "Replaced %d residues (%d atoms)\n", originalResidueCount - atoms->nres, originalAtomCount - atoms->nr); } @@ -321,57 +323,58 @@ namespace class InsertMolecules : public ICommandLineOptionsModule, public ITopologyProvider { - public: - InsertMolecules() - : bBox_(false), nmolIns_(0), nmolTry_(10), seed_(0), - defaultDistance_(0.105), scaleFactor_(0.57), enumRot_(en_rotXYZ) - { - clear_rvec(newBox_); - clear_rvec(deltaR_); - clear_mat(box_); - } - - // From ITopologyProvider - gmx_mtop_t *getTopology(bool /*required*/) override { return &top_; } - int getAtomCount() override { return 0; } +public: + InsertMolecules() : + bBox_(false), + nmolIns_(0), + nmolTry_(10), + seed_(0), + defaultDistance_(0.105), + scaleFactor_(0.57), + enumRot_(en_rotXYZ) + { + clear_rvec(newBox_); + clear_rvec(deltaR_); + clear_mat(box_); + } - // From ICommandLineOptionsModule - void init(CommandLineModuleSettings * /*settings*/) override - { - } - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - void optionsFinished() override; - int run() override; - - private: - SelectionCollection selections_; - - std::string inputConfFile_; - std::string insertConfFile_; - std::string positionFile_; - std::string outputConfFile_; - rvec newBox_; - bool bBox_; - int nmolIns_; - int nmolTry_; - int seed_; - real defaultDistance_; - real scaleFactor_; - rvec deltaR_; - RotationType enumRot_; - Selection replaceSel_; - - gmx_mtop_t top_; - std::vector x_; - matrix box_; - int ePBC_; + // From ITopologyProvider + gmx_mtop_t* getTopology(bool /*required*/) override { return &top_; } + int getAtomCount() override { return 0; } + + // From ICommandLineOptionsModule + void init(CommandLineModuleSettings* /*settings*/) override {} + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + void optionsFinished() override; + int run() override; + +private: + SelectionCollection selections_; + + std::string inputConfFile_; + std::string insertConfFile_; + std::string positionFile_; + std::string outputConfFile_; + rvec newBox_; + bool bBox_; + int nmolIns_; + int nmolTry_; + int seed_; + real defaultDistance_; + real scaleFactor_; + rvec deltaR_; + RotationType enumRot_; + Selection replaceSel_; + + gmx_mtop_t top_; + std::vector x_; + matrix box_; + int ePBC_; }; -void InsertMolecules::initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) +void InsertMolecules::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - const char *const desc[] = { + const char* const desc[] = { "[THISMODULE] inserts [TT]-nmol[tt] copies of the system specified in", "the [TT]-ci[tt] input file. The insertions take place either into", "vacant space in the solute conformation given with [TT]-f[tt], or", @@ -424,82 +427,84 @@ void InsertMolecules::initOptions(IOptionsContainer *options, // TODO: Replace use of legacyType. options->addOption(FileNameOption("f") - .legacyType(efSTX).inputFile() - .store(&inputConfFile_) - .defaultBasename("protein") - .description("Existing configuration to insert into")); + .legacyType(efSTX) + .inputFile() + .store(&inputConfFile_) + .defaultBasename("protein") + .description("Existing configuration to insert into")); options->addOption(FileNameOption("ci") - .legacyType(efSTX).inputFile().required() - .store(&insertConfFile_) - .defaultBasename("insert") - .description("Configuration to insert")); + .legacyType(efSTX) + .inputFile() + .required() + .store(&insertConfFile_) + .defaultBasename("insert") + .description("Configuration to insert")); options->addOption(FileNameOption("ip") - .filetype(eftGenericData).inputFile() - .store(&positionFile_) - .defaultBasename("positions") - .description("Predefined insertion trial positions")); + .filetype(eftGenericData) + .inputFile() + .store(&positionFile_) + .defaultBasename("positions") + .description("Predefined insertion trial positions")); options->addOption(FileNameOption("o") - .legacyType(efSTO).outputFile().required() - .store(&outputConfFile_) - .defaultBasename("out") - .description("Output configuration after insertion")); - - options->addOption(SelectionOption("replace").onlyAtoms() - .store(&replaceSel_) - .description("Atoms that can be removed if overlapping")); + .legacyType(efSTO) + .outputFile() + .required() + .store(&outputConfFile_) + .defaultBasename("out") + .description("Output configuration after insertion")); + + options->addOption( + SelectionOption("replace").onlyAtoms().store(&replaceSel_).description("Atoms that can be removed if overlapping")); selectionOptionBehavior->initOptions(options); - options->addOption(RealOption("box").vector() - .store(newBox_).storeIsSet(&bBox_) - .description("Box size (in nm)")); - options->addOption(IntegerOption("nmol") - .store(&nmolIns_) - .description("Number of extra molecules to insert")); - options->addOption(IntegerOption("try") - .store(&nmolTry_) - .description("Try inserting [TT]-nmol[tt] times [TT]-try[tt] times")); - options->addOption(IntegerOption("seed") - .store(&seed_) - .description("Random generator seed (0 means generate)")); - options->addOption(RealOption("radius") - .store(&defaultDistance_) - .description("Default van der Waals distance")); - options->addOption(RealOption("scale") - .store(&scaleFactor_) - .description("Scale factor to multiply Van der Waals radii from the database in share/gromacs/top/vdwradii.dat. The default value of 0.57 yields density close to 1000 g/l for proteins in water.")); - options->addOption(RealOption("dr").vector() - .store(deltaR_) - .description("Allowed displacement in x/y/z from positions in [TT]-ip[tt] file")); - options->addOption(EnumOption("rot").enumValue(cRotationEnum) - .store(&enumRot_) - .description("Rotate inserted molecules randomly")); + options->addOption(RealOption("box").vector().store(newBox_).storeIsSet(&bBox_).description( + "Box size (in nm)")); + options->addOption(IntegerOption("nmol").store(&nmolIns_).description( + "Number of extra molecules to insert")); + options->addOption(IntegerOption("try").store(&nmolTry_).description( + "Try inserting [TT]-nmol[tt] times [TT]-try[tt] times")); + options->addOption(IntegerOption("seed").store(&seed_).description( + "Random generator seed (0 means generate)")); + options->addOption( + RealOption("radius").store(&defaultDistance_).description("Default van der Waals distance")); + options->addOption( + RealOption("scale").store(&scaleFactor_).description("Scale factor to multiply Van der Waals radii from the database in share/gromacs/top/vdwradii.dat. The default value of 0.57 yields density close to 1000 g/l for proteins in water.")); + options->addOption(RealOption("dr").vector().store(deltaR_).description( + "Allowed displacement in x/y/z from positions in [TT]-ip[tt] file")); + options->addOption(EnumOption("rot") + .enumValue(cRotationEnum) + .store(&enumRot_) + .description("Rotate inserted molecules randomly")); } void InsertMolecules::optionsFinished() { if (nmolIns_ <= 0 && positionFile_.empty()) { - GMX_THROW(InconsistentInputError("Either -nmol must be larger than 0, " - "or positions must be given with -ip.")); + GMX_THROW( + InconsistentInputError("Either -nmol must be larger than 0, " + "or positions must be given with -ip.")); } if (inputConfFile_.empty() && !bBox_) { - GMX_THROW(InconsistentInputError("When no solute (-f) is specified, " - "a box size (-box) must be specified.")); + GMX_THROW( + InconsistentInputError("When no solute (-f) is specified, " + "a box size (-box) must be specified.")); } if (replaceSel_.isValid() && inputConfFile_.empty()) { - GMX_THROW(InconsistentInputError("Replacement (-replace) only makes sense " - "together with an existing configuration (-f).")); + GMX_THROW( + InconsistentInputError("Replacement (-replace) only makes sense " + "together with an existing configuration (-f).")); } if (!inputConfFile_.empty()) { bool bTprFileWasRead; - rvec *temporaryX = nullptr; + rvec* temporaryX = nullptr; fprintf(stderr, "Reading solute configuration\n"); - readConfAndTopology(inputConfFile_.c_str(), &bTprFileWasRead, &top_, - &ePBC_, &temporaryX, nullptr, box_); + readConfAndTopology(inputConfFile_.c_str(), &bTprFileWasRead, &top_, &ePBC_, &temporaryX, + nullptr, box_); x_.assign(temporaryX, temporaryX + top_.natoms); sfree(temporaryX); if (top_.natoms == 0) @@ -514,17 +519,16 @@ int InsertMolecules::run() std::set removableAtoms; if (replaceSel_.isValid()) { - t_pbc pbc; + t_pbc pbc; set_pbc(&pbc, ePBC_, box_); - t_trxframe *fr; + t_trxframe* fr; snew(fr, 1); fr->natoms = x_.size(); fr->bX = TRUE; fr->x = as_rvec_array(x_.data()); selections_.evaluate(fr, &pbc); sfree(fr); - removableAtoms.insert(replaceSel_.atomIndices().begin(), - replaceSel_.atomIndices().end()); + removableAtoms.insert(replaceSel_.atomIndices().begin(), replaceSel_.atomIndices().end()); // TODO: It could be nice to check that removableAtoms contains full // residues, since we anyways remove whole residues instead of // individual atoms. @@ -541,27 +545,27 @@ int InsertMolecules::run() } if (det(box_) == 0) { - gmx_fatal(FARGS, "Undefined solute box.\nCreate one with gmx editconf " + gmx_fatal(FARGS, + "Undefined solute box.\nCreate one with gmx editconf " "or give explicit -box command line option"); } - gmx_mtop_t topInserted; - t_atoms atomsInserted; - std::vector xInserted; + gmx_mtop_t topInserted; + t_atoms atomsInserted; + std::vector xInserted; { - bool bTprFileWasRead; - int ePBC_dummy; - matrix box_dummy; - rvec *temporaryX; - readConfAndTopology(insertConfFile_.c_str(), &bTprFileWasRead, &topInserted, - &ePBC_dummy, &temporaryX, nullptr, box_dummy); + bool bTprFileWasRead; + int ePBC_dummy; + matrix box_dummy; + rvec* temporaryX; + readConfAndTopology(insertConfFile_.c_str(), &bTprFileWasRead, &topInserted, &ePBC_dummy, + &temporaryX, nullptr, box_dummy); xInserted.assign(temporaryX, temporaryX + topInserted.natoms); sfree(temporaryX); atomsInserted = gmx_mtop_global_atoms(&topInserted); if (atomsInserted.nr == 0) { - gmx_fatal(FARGS, "No molecule in %s, please check your input", - insertConfFile_.c_str()); + gmx_fatal(FARGS, "No molecule in %s, please check your input", insertConfFile_.c_str()); } if (top_.name == nullptr) { @@ -577,19 +581,17 @@ int InsertMolecules::run() /* add nmol_ins molecules of atoms_ins in random orientation at random place */ - insert_mols(nmolIns_, nmolTry_, seed_, defaultDistance_, scaleFactor_, - &atoms, &top_.symtab, &x_, removableAtoms, atomsInserted, xInserted, - ePBCForOutput, box_, positionFile_, deltaR_, enumRot_); + insert_mols(nmolIns_, nmolTry_, seed_, defaultDistance_, scaleFactor_, &atoms, &top_.symtab, + &x_, removableAtoms, atomsInserted, xInserted, ePBCForOutput, box_, positionFile_, + deltaR_, enumRot_); /* write new configuration to file confout */ - fprintf(stderr, "Writing generated configuration to %s\n", - outputConfFile_.c_str()); - write_sto_conf(outputConfFile_.c_str(), *top_.name, &atoms, - as_rvec_array(x_.data()), nullptr, ePBCForOutput, box_); + fprintf(stderr, "Writing generated configuration to %s\n", outputConfFile_.c_str()); + write_sto_conf(outputConfFile_.c_str(), *top_.name, &atoms, as_rvec_array(x_.data()), nullptr, + ePBCForOutput, box_); /* print size of generated configuration */ - fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", - atoms.nr, atoms.nres); + fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", atoms.nr, atoms.nres); done_atom(&atoms); done_atom(&atomsInserted); @@ -597,7 +599,7 @@ int InsertMolecules::run() return 0; } -} // namespace +} // namespace const char* InsertMoleculesInfo::name() @@ -608,8 +610,7 @@ const char* InsertMoleculesInfo::name() const char* InsertMoleculesInfo::shortDescription() { - static const char* shortDescription = - "Insert molecules into existing vacancies"; + static const char* shortDescription = "Insert molecules into existing vacancies"; return shortDescription; } diff --git a/src/gromacs/gmxpreprocess/insert_molecules.h b/src/gromacs/gmxpreprocess/insert_molecules.h index 37601f2748..24fd986d8b 100644 --- a/src/gromacs/gmxpreprocess/insert_molecules.h +++ b/src/gromacs/gmxpreprocess/insert_molecules.h @@ -42,10 +42,10 @@ namespace gmx class InsertMoleculesInfo { - public: - static const char* name(); - static const char* shortDescription(); - static ICommandLineOptionsModulePointer create(); +public: + static const char* name(); + static const char* shortDescription(); + static ICommandLineOptionsModulePointer create(); }; } // namespace gmx diff --git a/src/gromacs/gmxpreprocess/makeexclusiondistances.cpp b/src/gromacs/gmxpreprocess/makeexclusiondistances.cpp index ad524735d8..c290dd31af 100644 --- a/src/gromacs/gmxpreprocess/makeexclusiondistances.cpp +++ b/src/gromacs/gmxpreprocess/makeexclusiondistances.cpp @@ -42,9 +42,7 @@ #include "gromacs/topology/atomprop.h" #include "gromacs/topology/atoms.h" -std::vector -makeExclusionDistances(const t_atoms *a, AtomProperties *aps, - real defaultDistance, real scaleFactor) +std::vector makeExclusionDistances(const t_atoms* a, AtomProperties* aps, real defaultDistance, real scaleFactor) { std::vector exclusionDistances; @@ -53,9 +51,8 @@ makeExclusionDistances(const t_atoms *a, AtomProperties *aps, exclusionDistances.reserve(a->nr); for (int i = 0; i < a->nr; ++i) { - real value; - if (!aps->setAtomProperty(epropVDW, - std::string(*(a->resinfo[a->atom[i].resind].name)), + real value; + if (!aps->setAtomProperty(epropVDW, std::string(*(a->resinfo[a->atom[i].resind].name)), std::string(*(a->atomname[i])), &value)) { value = defaultDistance; diff --git a/src/gromacs/gmxpreprocess/makeexclusiondistances.h b/src/gromacs/gmxpreprocess/makeexclusiondistances.h index fd89e741f1..57be811be1 100644 --- a/src/gromacs/gmxpreprocess/makeexclusiondistances.h +++ b/src/gromacs/gmxpreprocess/makeexclusiondistances.h @@ -48,8 +48,6 @@ struct t_atoms; * default value. Used directly and indirectly by solvate and * insert-molecules for deciding whether molecules clash. The return * pointer should be freed by the caller. */ -std::vector -makeExclusionDistances(const t_atoms *a, AtomProperties *aps, - real defaultDistance, real scaleFactor); +std::vector makeExclusionDistances(const t_atoms* a, AtomProperties* aps, real defaultDistance, real scaleFactor); #endif diff --git a/src/gromacs/gmxpreprocess/nm2type.cpp b/src/gromacs/gmxpreprocess/nm2type.cpp index 3222fa2406..7c8a942371 100644 --- a/src/gromacs/gmxpreprocess/nm2type.cpp +++ b/src/gromacs/gmxpreprocess/nm2type.cpp @@ -60,16 +60,16 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void rd_nm2type_file(const std::string &filename, int *nnm, t_nm2type **nmp) +static void rd_nm2type_file(const std::string& filename, int* nnm, t_nm2type** nmp) { - FILE *fp; - bool bCont; - char libfilename[128]; - char format[128], f1[128]; - char buf[1024], elem[16], type[16], nbbuf[16], **newbuf; - int i, nb, nnnm, line = 1; - double qq, mm; - t_nm2type *nm2t = nullptr; + FILE* fp; + bool bCont; + char libfilename[128]; + char format[128], f1[128]; + char buf[1024], elem[16], type[16], nbbuf[16], **newbuf; + int i, nb, nnnm, line = 1; + double qq, mm; + t_nm2type* nm2t = nullptr; fp = fflib_open(filename); if (nullptr == fp) @@ -91,7 +91,7 @@ static void rd_nm2type_file(const std::string &filename, int *nnm, t_nm2type **n if (sscanf(buf, "%s%s%lf%lf%d", elem, type, &qq, &mm, &nb) == 5) { /* If we can read the first four, there probably is more */ - srenew(nm2t, nnnm+1); + srenew(nm2t, nnnm + 1); snew(nm2t[nnnm].blen, nb); if (nb > 0) { @@ -124,36 +124,34 @@ static void rd_nm2type_file(const std::string &filename, int *nnm, t_nm2type **n } line++; } - } - while (bCont); + } while (bCont); gmx_ffclose(fp); *nnm = nnnm; *nmp = nm2t; } -t_nm2type *rd_nm2type(const char *ffdir, int *nnm) +t_nm2type* rd_nm2type(const char* ffdir, int* nnm) { - std::vector ff = fflib_search_file_end(ffdir, ".n2t", FALSE); - *nnm = 0; - t_nm2type *nm = nullptr; - for (const auto &filename : ff) + std::vector ff = fflib_search_file_end(ffdir, ".n2t", FALSE); + *nnm = 0; + t_nm2type* nm = nullptr; + for (const auto& filename : ff) { rd_nm2type_file(filename, nnm, &nm); } return nm; } -void dump_nm2type(FILE *fp, int nnm, t_nm2type nm2t[]) +void dump_nm2type(FILE* fp, int nnm, t_nm2type nm2t[]) { int i, j; fprintf(fp, "; nm2type database\n"); for (i = 0; (i < nnm); i++) { - fprintf(fp, "%-8s %-8s %8.4f %8.4f %-4d", - nm2t[i].elem, nm2t[i].type, - nm2t[i].q, nm2t[i].m, nm2t[i].nbonds); + fprintf(fp, "%-8s %-8s %8.4f %8.4f %-4d", nm2t[i].elem, nm2t[i].type, nm2t[i].q, nm2t[i].m, + nm2t[i].nbonds); for (j = 0; (j < nm2t[i].nbonds); j++) { fprintf(fp, " %-5s %6.4f", nm2t[i].bond[j], nm2t[i].blen[j]); @@ -162,11 +160,16 @@ void dump_nm2type(FILE *fp, int nnm, t_nm2type nm2t[]) } } -enum { - ematchNone, ematchWild, ematchElem, ematchExact, ematchNR +enum +{ + ematchNone, + ematchWild, + ematchElem, + ematchExact, + ematchNR }; -static int match_str(const char *atom, const char *template_string) +static int match_str(const char* atom, const char* template_string) { if (!atom || !template_string) { @@ -190,14 +193,19 @@ static int match_str(const char *atom, const char *template_string) } } -int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, - PreprocessingAtomTypes *atype, int *nbonds, InteractionsOfType *bonds) +int nm2type(int nnm, + t_nm2type nm2t[], + t_symtab* tab, + t_atoms* atoms, + PreprocessingAtomTypes* atype, + int* nbonds, + InteractionsOfType* bonds) { - int cur = 0; -#define prev (1-cur) - int nresolved, nb, maxbond, nqual[2][ematchNR]; - int *bbb, *n_mask, *m_mask, **match; - char *aname_i, *aname_n; + int cur = 0; +#define prev (1 - cur) + int nresolved, nb, maxbond, nqual[2][ematchNR]; + int * bbb, *n_mask, *m_mask, **match; + char *aname_i, *aname_n; maxbond = 0; for (int i = 0; (i < atoms->nr); i++) @@ -222,7 +230,7 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, { aname_i = *atoms->atomname[i]; nb = 0; - for (const auto &bond : bonds->interactionTypes) + for (const auto& bond : bonds->interactionTypes) { int ai = bond.ai(); int aj = bond.aj(); @@ -237,8 +245,7 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, } if (nb != nbonds[i]) { - gmx_fatal(FARGS, "Counting number of bonds nb = %d, nbonds[%d] = %d", - nb, i, nbonds[i]); + gmx_fatal(FARGS, "Counting number of bonds nb = %d, nbonds[%d] = %d", nb, i, nbonds[i]); } if (debug) { @@ -271,7 +278,7 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, /* Fill a matrix with matching quality */ for (int m = 0; (m < nb); m++) { - const char *aname_m = *atoms->atomname[bbb[m]]; + const char* aname_m = *atoms->atomname[bbb[m]]; for (int n = 0; (n < nb); n++) { aname_n = nm2t[k].bond[n]; @@ -284,15 +291,13 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, n_mask[m] = 0; m_mask[m] = 0; } - for (int j = ematchNR-1; (j > 0); j--) + for (int j = ematchNR - 1; (j > 0); j--) { for (int m = 0; (m < nb); m++) { for (int n = 0; (n < nb); n++) { - if ((n_mask[n] == 0) && - (m_mask[m] == 0) && - (match[m][n] == j)) + if ((n_mask[n] == 0) && (m_mask[m] == 0) && (match[m][n] == j)) { n_mask[n] = 1; m_mask[m] = 1; @@ -301,18 +306,17 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, } } } - if ((nqual[cur][ematchExact]+ - nqual[cur][ematchElem]+ - nqual[cur][ematchWild]) == nb) + if ((nqual[cur][ematchExact] + nqual[cur][ematchElem] + nqual[cur][ematchWild]) == nb) { if ((nqual[cur][ematchExact] > nqual[prev][ematchExact]) || - ((nqual[cur][ematchExact] == nqual[prev][ematchExact]) && - (nqual[cur][ematchElem] > nqual[prev][ematchElem])) || + ((nqual[cur][ematchExact] == nqual[prev][ematchExact]) + && (nqual[cur][ematchElem] > nqual[prev][ematchElem])) + || - ((nqual[cur][ematchExact] == nqual[prev][ematchExact]) && - (nqual[cur][ematchElem] == nqual[prev][ematchElem]) && - (nqual[cur][ematchWild] > nqual[prev][ematchWild]))) + ((nqual[cur][ematchExact] == nqual[prev][ematchExact]) + && (nqual[cur][ematchElem] == nqual[prev][ematchElem]) + && (nqual[cur][ematchWild] > nqual[prev][ematchWild]))) { best = k; cur = prev; @@ -323,20 +327,20 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, } if (best != -1) { - int atomnr = 0; - real alpha = 0; + int atomnr = 0; + real alpha = 0; double qq = nm2t[best].q; double mm = nm2t[best].m; - const char *type = nm2t[best].type; + const char* type = nm2t[best].type; - int k; + int k; if ((k = atype->atomTypeFromName(type)) == NOTSET) { atoms->atom[i].qB = alpha; - atoms->atom[i].m = atoms->atom[i].mB = mm; - k = atype->addType(tab, atoms->atom[i], type, InteractionOfType({}, {}), - atoms->atom[i].type, atomnr); + atoms->atom[i].m = atoms->atom[i].mB = mm; + k = atype->addType(tab, atoms->atom[i], type, InteractionOfType({}, {}), + atoms->atom[i].type, atomnr); } atoms->atom[i].type = k; atoms->atom[i].typeB = k; @@ -349,7 +353,7 @@ int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, else { fprintf(stderr, "Can not find forcefield for atom %s-%d with %d bonds\n", - *atoms->atomname[i], i+1, nb); + *atoms->atomname[i], i + 1, nb); } } sfree(bbb); diff --git a/src/gromacs/gmxpreprocess/nm2type.h b/src/gromacs/gmxpreprocess/nm2type.h index 4107337c1a..720f46e373 100644 --- a/src/gromacs/gmxpreprocess/nm2type.h +++ b/src/gromacs/gmxpreprocess/nm2type.h @@ -46,23 +46,28 @@ struct t_symtab; struct t_nm2type { - char *elem, *type; - double q, m; - int nbonds; - char **bond; - double *blen; + char * elem, *type; + double q, m; + int nbonds; + char** bond; + double* blen; }; -t_nm2type *rd_nm2type(const char *ffdir, int *nnm); +t_nm2type* rd_nm2type(const char* ffdir, int* nnm); /* Read the name 2 type database. nnm is the number of entries * ff is the force field. */ -void dump_nm2type(FILE *fp, int nnm, t_nm2type nm2t[]); +void dump_nm2type(FILE* fp, int nnm, t_nm2type nm2t[]); /* Dump the database for debugging. Can be reread by the program */ -int nm2type(int nnm, t_nm2type nm2t[], t_symtab *tab, t_atoms *atoms, - PreprocessingAtomTypes *atype, int *nbonds, InteractionsOfType *bond); +int nm2type(int nnm, + t_nm2type nm2t[], + t_symtab* tab, + t_atoms* atoms, + PreprocessingAtomTypes* atype, + int* nbonds, + InteractionsOfType* bond); /* Try to determine the atomtype (force field dependent) for the atoms * with help of the bond list */ diff --git a/src/gromacs/gmxpreprocess/pdb2gmx.cpp b/src/gromacs/gmxpreprocess/pdb2gmx.cpp index 3c040aab0c..409472415b 100644 --- a/src/gromacs/gmxpreprocess/pdb2gmx.cpp +++ b/src/gromacs/gmxpreprocess/pdb2gmx.cpp @@ -87,12 +87,16 @@ #include "hackblock.h" #include "resall.h" -struct RtpRename{ - RtpRename(const char *newGmx, const char *newMain, - const char *newNter, const char *newCter, - const char *newBter) : - gmx(newGmx), main(newMain), nter(newNter), cter(newCter), bter(newBter) - {} +struct RtpRename +{ + RtpRename(const char* newGmx, const char* newMain, const char* newNter, const char* newCter, const char* newBter) : + gmx(newGmx), + main(newMain), + nter(newNter), + cter(newCter), + bter(newBter) + { + } std::string gmx; std::string main; std::string nter; @@ -100,127 +104,124 @@ struct RtpRename{ std::string bter; }; -static const char *res2bb_notermini(const std::string &name, - gmx::ArrayRef rr) +static const char* res2bb_notermini(const std::string& name, gmx::ArrayRef rr) { /* NOTE: This function returns the main building block name, * it does not take terminal renaming into account. */ - auto found = std::find_if(rr.begin(), rr.end(), [&name](const auto &rename) - { return gmx::equalCaseInsensitive(name, rename.gmx); }); + auto found = std::find_if(rr.begin(), rr.end(), [&name](const auto& rename) { + return gmx::equalCaseInsensitive(name, rename.gmx); + }); return found != rr.end() ? found->main.c_str() : name.c_str(); } -static const char *select_res(int nr, int resnr, - const char *name[], const char *expl[], - const char *title, +static const char* select_res(int nr, + int resnr, + const char* name[], + const char* expl[], + const char* title, gmx::ArrayRef rr) { - printf("Which %s type do you want for residue %d\n", title, resnr+1); + printf("Which %s type do you want for residue %d\n", title, resnr + 1); for (int sel = 0; (sel < nr); sel++) { - printf("%d. %s (%s)\n", - sel, expl[sel], res2bb_notermini(name[sel], rr)); + printf("%d. %s (%s)\n", sel, expl[sel], res2bb_notermini(name[sel], rr)); } - printf("\nType a number:"); fflush(stdout); + printf("\nType a number:"); + fflush(stdout); int userSelection; if (scanf("%d", &userSelection) != 1) { - gmx_fatal(FARGS, "Answer me for res %s %d!", title, resnr+1); + gmx_fatal(FARGS, "Answer me for res %s %d!", title, resnr + 1); } return name[userSelection]; } -static const char *get_asptp(int resnr, gmx::ArrayRef rr) +static const char* get_asptp(int resnr, gmx::ArrayRef rr) { - enum { - easp, easpH, easpNR - }; - const char *lh[easpNR] = { "ASP", "ASPH" }; - const char *expl[easpNR] = { - "Not protonated (charge -1)", - "Protonated (charge 0)" + enum + { + easp, + easpH, + easpNR }; + const char* lh[easpNR] = { "ASP", "ASPH" }; + const char* expl[easpNR] = { "Not protonated (charge -1)", "Protonated (charge 0)" }; return select_res(easpNR, resnr, lh, expl, "ASPARTIC ACID", rr); } -static const char *get_glutp(int resnr, gmx::ArrayRef rr) +static const char* get_glutp(int resnr, gmx::ArrayRef rr) { - enum { - eglu, egluH, egluNR - }; - const char *lh[egluNR] = { "GLU", "GLUH" }; - const char *expl[egluNR] = { - "Not protonated (charge -1)", - "Protonated (charge 0)" + enum + { + eglu, + egluH, + egluNR }; + const char* lh[egluNR] = { "GLU", "GLUH" }; + const char* expl[egluNR] = { "Not protonated (charge -1)", "Protonated (charge 0)" }; return select_res(egluNR, resnr, lh, expl, "GLUTAMIC ACID", rr); } -static const char *get_glntp(int resnr, gmx::ArrayRef rr) +static const char* get_glntp(int resnr, gmx::ArrayRef rr) { - enum { - egln, eglnH, eglnNR - }; - const char *lh[eglnNR] = { "GLN", "QLN" }; - const char *expl[eglnNR] = { - "Not protonated (charge 0)", - "Protonated (charge +1)" + enum + { + egln, + eglnH, + eglnNR }; + const char* lh[eglnNR] = { "GLN", "QLN" }; + const char* expl[eglnNR] = { "Not protonated (charge 0)", "Protonated (charge +1)" }; return select_res(eglnNR, resnr, lh, expl, "GLUTAMINE", rr); } -static const char *get_lystp(int resnr, gmx::ArrayRef rr) +static const char* get_lystp(int resnr, gmx::ArrayRef rr) { - enum { - elys, elysH, elysNR - }; - const char *lh[elysNR] = { "LYSN", "LYS" }; - const char *expl[elysNR] = { - "Not protonated (charge 0)", - "Protonated (charge +1)" + enum + { + elys, + elysH, + elysNR }; + const char* lh[elysNR] = { "LYSN", "LYS" }; + const char* expl[elysNR] = { "Not protonated (charge 0)", "Protonated (charge +1)" }; return select_res(elysNR, resnr, lh, expl, "LYSINE", rr); } -static const char *get_argtp(int resnr, gmx::ArrayRef rr) +static const char* get_argtp(int resnr, gmx::ArrayRef rr) { - enum { - earg, eargH, eargNR - }; - const char *lh[eargNR] = { "ARGN", "ARG" }; - const char *expl[eargNR] = { - "Not protonated (charge 0)", - "Protonated (charge +1)" + enum + { + earg, + eargH, + eargNR }; + const char* lh[eargNR] = { "ARGN", "ARG" }; + const char* expl[eargNR] = { "Not protonated (charge 0)", "Protonated (charge +1)" }; return select_res(eargNR, resnr, lh, expl, "ARGININE", rr); } -static const char *get_histp(int resnr, gmx::ArrayRef rr) +static const char* get_histp(int resnr, gmx::ArrayRef rr) { - const char *expl[ehisNR] = { - "H on ND1 only", - "H on NE2 only", - "H on ND1 and NE2", - "Coupled to Heme" - }; + const char* expl[ehisNR] = { "H on ND1 only", "H on NE2 only", "H on ND1 and NE2", + "Coupled to Heme" }; return select_res(ehisNR, resnr, hh, expl, "HISTIDINE", rr); } -static void read_rtprename(const char *fname, FILE *fp, - std::vector *rtprename) +static void read_rtprename(const char* fname, FILE* fp, std::vector* rtprename) { - char line[STRLEN], buf[STRLEN]; + char line[STRLEN], buf[STRLEN]; - int ncol = 0; + int ncol = 0; while (get_a_line(fp, line, STRLEN)) { /* line is NULL-terminated and length rr, - const char *name, - bool bStart, bool bEnd, - bool bCompareFFRTPname) + const char* name, + bool bStart, + bool bEnd, + bool bCompareFFRTPname) { - auto found = std::find_if(rr.begin(), rr.end(), [&name, &bCompareFFRTPname](const auto &rename) - { return ((!bCompareFFRTPname && (name == rename.gmx)) || - (bCompareFFRTPname && (name == rename.main))); }); + auto found = std::find_if(rr.begin(), rr.end(), [&name, &bCompareFFRTPname](const auto& rename) { + return ((!bCompareFFRTPname && (name == rename.gmx)) + || (bCompareFFRTPname && (name == rename.main))); + }); std::string newName; /* If found in the database, rename this residue's rtp building block, @@ -279,7 +288,7 @@ static std::string search_resrename(gmx::ArrayRef rr, { if (bStart && bEnd) { - newName = found->bter; + newName = found->bter; } else if (bStart) { @@ -296,19 +305,21 @@ static std::string search_resrename(gmx::ArrayRef rr, if (newName[0] == '-') { - gmx_fatal(FARGS, "In the chosen force field there is no residue type for '%s'%s", name, bStart ? ( bEnd ? " as a standalone (starting & ending) residue" : " as a starting terminus") : (bEnd ? " as an ending terminus" : "")); + gmx_fatal(FARGS, "In the chosen force field there is no residue type for '%s'%s", name, + bStart ? (bEnd ? " as a standalone (starting & ending) residue" : " as a starting terminus") + : (bEnd ? " as an ending terminus" : "")); } } return newName; } -static void rename_resrtp(t_atoms *pdba, +static void rename_resrtp(t_atoms* pdba, int nterpairs, gmx::ArrayRef r_start, gmx::ArrayRef r_end, gmx::ArrayRef rr, - t_symtab *symtab, + t_symtab* symtab, bool bVerbose) { bool bFFRTPTERRNM = (getenv("GMX_NO_FFRTP_TER_RENAME") == nullptr); @@ -341,23 +352,22 @@ static void rename_resrtp(t_atoms *pdba, * but probably a force field specific rtp name. * Check if we need to rename it because it is terminal. */ - newName = search_resrename(rr, - *pdba->resinfo[r].rtp, bStart, bEnd, true); + newName = search_resrename(rr, *pdba->resinfo[r].rtp, bStart, bEnd, true); } if (!newName.empty() && newName != *pdba->resinfo[r].rtp) { if (bVerbose) { - printf("Changing rtp entry of residue %d %s to '%s'\n", - pdba->resinfo[r].nr, *pdba->resinfo[r].name, newName.c_str()); + printf("Changing rtp entry of residue %d %s to '%s'\n", pdba->resinfo[r].nr, + *pdba->resinfo[r].name, newName.c_str()); } pdba->resinfo[r].rtp = put_symtab(symtab, newName.c_str()); } } } -static void pdbres_to_gmxrtp(t_atoms *pdba) +static void pdbres_to_gmxrtp(t_atoms* pdba) { int i; @@ -370,17 +380,16 @@ static void pdbres_to_gmxrtp(t_atoms *pdba) } } -static void rename_pdbres(t_atoms *pdba, const char *oldnm, const char *newnm, - bool bFullCompare, t_symtab *symtab) +static void rename_pdbres(t_atoms* pdba, const char* oldnm, const char* newnm, bool bFullCompare, t_symtab* symtab) { - char *resnm; + char* resnm; int i; for (i = 0; (i < pdba->nres); i++) { resnm = *pdba->resinfo[i].name; - if ((bFullCompare && (gmx::equalCaseInsensitive(resnm, oldnm))) || - (!bFullCompare && strstr(resnm, oldnm) != nullptr)) + if ((bFullCompare && (gmx::equalCaseInsensitive(resnm, oldnm))) + || (!bFullCompare && strstr(resnm, oldnm) != nullptr)) { /* Rename the residue name (not the rtp name) */ pdba->resinfo[i].name = put_symtab(symtab, newnm); @@ -388,18 +397,17 @@ static void rename_pdbres(t_atoms *pdba, const char *oldnm, const char *newnm, } } -static void rename_bb(t_atoms *pdba, const char *oldnm, const char *newnm, - bool bFullCompare, t_symtab *symtab) +static void rename_bb(t_atoms* pdba, const char* oldnm, const char* newnm, bool bFullCompare, t_symtab* symtab) { - char *bbnm; + char* bbnm; int i; for (i = 0; (i < pdba->nres); i++) { /* We have not set the rtp name yes, use the residue name */ bbnm = *pdba->resinfo[i].name; - if ((bFullCompare && (gmx::equalCaseInsensitive(bbnm, oldnm))) || - (!bFullCompare && strstr(bbnm, oldnm) != nullptr)) + if ((bFullCompare && (gmx::equalCaseInsensitive(bbnm, oldnm))) + || (!bFullCompare && strstr(bbnm, oldnm) != nullptr)) { /* Change the rtp builing block name */ pdba->resinfo[i].rtp = put_symtab(symtab, newnm); @@ -407,22 +415,22 @@ static void rename_bb(t_atoms *pdba, const char *oldnm, const char *newnm, } } -static void rename_bbint(t_atoms *pdba, const char *oldnm, - const char *gettp(int, gmx::ArrayRef), - bool bFullCompare, - t_symtab *symtab, +static void rename_bbint(t_atoms* pdba, + const char* oldnm, + const char* gettp(int, gmx::ArrayRef), + bool bFullCompare, + t_symtab* symtab, gmx::ArrayRef rr) { int i; - const char *ptr; - char *bbnm; + const char* ptr; + char* bbnm; for (i = 0; i < pdba->nres; i++) { /* We have not set the rtp name yet, use the residue name */ bbnm = *pdba->resinfo[i].name; - if ((bFullCompare && (strcmp(bbnm, oldnm) == 0)) || - (!bFullCompare && strstr(bbnm, oldnm) != nullptr)) + if ((bFullCompare && (strcmp(bbnm, oldnm) == 0)) || (!bFullCompare && strstr(bbnm, oldnm) != nullptr)) { ptr = gettp(i, rr); pdba->resinfo[i].rtp = put_symtab(symtab, ptr); @@ -430,7 +438,7 @@ static void rename_bbint(t_atoms *pdba, const char *oldnm, } } -static void check_occupancy(t_atoms *atoms, const char *filename, bool bVerbose) +static void check_occupancy(t_atoms* atoms, const char* filename, bool bVerbose) { int i, ftp; int nzero = 0; @@ -451,8 +459,7 @@ static void check_occupancy(t_atoms *atoms, const char *filename, bool bVerbose) { fprintf(stderr, "Occupancy for atom %s%d-%s is %f rather than 1\n", *atoms->resinfo[atoms->atom[i].resind].name, - atoms->resinfo[ atoms->atom[i].resind].nr, - *atoms->atomname[i], + atoms->resinfo[atoms->atom[i].resind].nr, *atoms->atomname[i], atoms->pdbinfo[i].occup); } if (atoms->pdbinfo[i].occup == 0) @@ -485,9 +492,9 @@ static void check_occupancy(t_atoms *atoms, const char *filename, bool bVerbose) } } -static void write_posres(const char *fn, t_atoms *pdba, real fc) +static void write_posres(const char* fn, t_atoms* pdba, real fc) { - FILE *fp; + FILE* fp; int i; fp = gmx_fio_fopen(fn, "w"); @@ -498,23 +505,32 @@ static void write_posres(const char *fn, t_atoms *pdba, real fc) "; not restrained.\n" "\n" "[ position_restraints ]\n" - "; %4s%6s%8s%8s%8s\n", "atom", "type", "fx", "fy", "fz" - ); + "; %4s%6s%8s%8s%8s\n", + "atom", "type", "fx", "fy", "fz"); for (i = 0; (i < pdba->nr); i++) { if (!is_hydrogen(*pdba->atomname[i]) && !is_dummymass(*pdba->atomname[i])) { - fprintf(fp, "%6d%6d %g %g %g\n", i+1, 1, fc, fc, fc); + fprintf(fp, "%6d%6d %g %g %g\n", i + 1, 1, fc, fc, fc); } } gmx_fio_fclose(fp); } -static int read_pdball(const char *inf, bool bOutput, const char *outf, char **title, - t_atoms *atoms, rvec **x, - int *ePBC, matrix box, bool bRemoveH, - t_symtab *symtab, ResidueType *rt, const char *watres, - AtomProperties *aps, bool bVerbose) +static int read_pdball(const char* inf, + bool bOutput, + const char* outf, + char** title, + t_atoms* atoms, + rvec** x, + int* ePBC, + matrix box, + bool bRemoveH, + t_symtab* symtab, + ResidueType* rt, + const char* watres, + AtomProperties* aps, + bool bVerbose) /* Read a pdb file. (containing proteins) */ { int natom, new_natom, i; @@ -522,7 +538,7 @@ static int read_pdball(const char *inf, bool bOutput, const char *outf, char **t /* READ IT */ printf("Reading %s...\n", inf); readConfAndAtoms(inf, symtab, title, atoms, ePBC, x, nullptr, box); - natom = atoms->nr; + natom = atoms->nr; if (atoms->pdbinfo == nullptr) { snew(atoms->pdbinfo, atoms->nr); @@ -561,9 +577,7 @@ static int read_pdball(const char *inf, bool bOutput, const char *outf, char **t rename_pdbres(atoms, "SOL", watres, false, symtab); rename_pdbres(atoms, "WAT", watres, false, symtab); - rename_atoms("xlateat.dat", nullptr, - atoms, symtab, {}, true, - rt, true, bVerbose); + rename_atoms("xlateat.dat", nullptr, atoms, symtab, {}, true, rt, true, bVerbose); if (natom == 0) { @@ -577,11 +591,20 @@ static int read_pdball(const char *inf, bool bOutput, const char *outf, char **t return natom; } -static void process_chain(t_atoms *pdba, gmx::ArrayRef x, - bool bTrpU, bool bPheU, bool bTyrU, - bool bLysMan, bool bAspMan, bool bGluMan, - bool bHisMan, bool bArgMan, bool bGlnMan, - real angle, real distance, t_symtab *symtab, +static void process_chain(t_atoms* pdba, + gmx::ArrayRef x, + bool bTrpU, + bool bPheU, + bool bTyrU, + bool bLysMan, + bool bAspMan, + bool bGluMan, + bool bHisMan, + bool bArgMan, + bool bGlnMan, + real angle, + real distance, + t_symtab* symtab, gmx::ArrayRef rr) { /* Rename aromatics, lys, asp and histidine */ @@ -648,7 +671,8 @@ static void process_chain(t_atoms *pdba, gmx::ArrayRef x, } /* struct for sorting the atoms from the pdb file */ -typedef struct { +typedef struct +{ int resnr; /* residue number */ int j; /* database order index */ int index; /* original atom number */ @@ -656,7 +680,7 @@ typedef struct { char altloc; /* alternate location indicator */ } t_pdbindex; -static bool pdbicomp(const t_pdbindex &a, const t_pdbindex &b) +static bool pdbicomp(const t_pdbindex& a, const t_pdbindex& b) { int d = (a.resnr - b.resnr); if (d == 0) @@ -675,44 +699,49 @@ static bool pdbicomp(const t_pdbindex &a, const t_pdbindex &b) } static void sort_pdbatoms(gmx::ArrayRef restp_chain, - int natoms, - t_atoms **pdbaptr, - t_atoms **newPdbAtoms, - std::vector *x, - t_blocka *block, char ***gnames) + int natoms, + t_atoms** pdbaptr, + t_atoms** newPdbAtoms, + std::vector* x, + t_blocka* block, + char*** gnames) { - t_atoms *pdba = *pdbaptr; + t_atoms* pdba = *pdbaptr; std::vector xnew; - t_pdbindex *pdbi; - char *atomnm; + t_pdbindex* pdbi; + char* atomnm; natoms = pdba->nr; snew(pdbi, natoms); for (int i = 0; i < natoms; i++) { - atomnm = *pdba->atomname[i]; - const PreprocessResidue *localPpResidue = &restp_chain[pdba->atom[i].resind]; - auto found = std::find_if(localPpResidue->atomname.begin(), localPpResidue->atomname.end(), - [&atomnm](char** it){return gmx::equalCaseInsensitive(atomnm, *it); }); + atomnm = *pdba->atomname[i]; + const PreprocessResidue* localPpResidue = &restp_chain[pdba->atom[i].resind]; + auto found = + std::find_if(localPpResidue->atomname.begin(), localPpResidue->atomname.end(), + [&atomnm](char** it) { return gmx::equalCaseInsensitive(atomnm, *it); }); if (found == localPpResidue->atomname.end()) { char buf[STRLEN]; sprintf(buf, "Atom %s in residue %s %d was not found in rtp entry %s with %d atoms\n" - "while sorting atoms.\n%s", atomnm, - *pdba->resinfo[pdba->atom[i].resind].name, - pdba->resinfo[pdba->atom[i].resind].nr, - localPpResidue->resname.c_str(), + "while sorting atoms.\n%s", + atomnm, *pdba->resinfo[pdba->atom[i].resind].name, + pdba->resinfo[pdba->atom[i].resind].nr, localPpResidue->resname.c_str(), localPpResidue->natom(), - is_hydrogen(atomnm) ? - "\nFor a hydrogen, this can be a different protonation state, or it\n" - "might have had a different number in the PDB file and was rebuilt\n" - "(it might for instance have been H3, and we only expected H1 & H2).\n" - "Note that hydrogens might have been added to the entry for the N-terminus.\n" - "Remove this hydrogen or choose a different protonation state to solve it.\n" - "Option -ignh will ignore all hydrogens in the input." : "."); + is_hydrogen(atomnm) + ? "\nFor a hydrogen, this can be a different protonation state, or it\n" + "might have had a different number in the PDB file and was rebuilt\n" + "(it might for instance have been H3, and we only expected H1 & " + "H2).\n" + "Note that hydrogens might have been added to the entry for the " + "N-terminus.\n" + "Remove this hydrogen or choose a different protonation state to " + "solve it.\n" + "Option -ignh will ignore all hydrogens in the input." + : "."); gmx_fatal(FARGS, "%s", buf); } /* make shadow array to be sorted into indexgroup */ @@ -722,7 +751,7 @@ static void sort_pdbatoms(gmx::ArrayRef restp_chain, pdbi[i].anm1 = atomnm[1]; pdbi[i].altloc = pdba->pdbinfo[i].altloc; } - std::sort(pdbi, pdbi+natoms, pdbicomp); + std::sort(pdbi, pdbi + natoms, pdbicomp); /* pdba is sorted in pdbnew using the pdbi index */ std::vector a(natoms); @@ -751,29 +780,28 @@ static void sort_pdbatoms(gmx::ArrayRef restp_chain, sfree(pdbi); } -static int remove_duplicate_atoms(t_atoms *pdba, gmx::ArrayRef x, bool bVerbose) +static int remove_duplicate_atoms(t_atoms* pdba, gmx::ArrayRef x, bool bVerbose) { int i, j, oldnatoms, ndel; - t_resinfo *ri; + t_resinfo* ri; printf("Checking for duplicate atoms....\n"); - oldnatoms = pdba->nr; - ndel = 0; + oldnatoms = pdba->nr; + ndel = 0; /* NOTE: pdba->nr is modified inside the loop */ for (i = 1; (i < pdba->nr); i++) { /* compare 'i' and 'i-1', throw away 'i' if they are identical this is a 'while' because multiple alternate locations can be present */ - while ( (i < pdba->nr) && - (pdba->atom[i-1].resind == pdba->atom[i].resind) && - (strcmp(*pdba->atomname[i-1], *pdba->atomname[i]) == 0) ) + while ((i < pdba->nr) && (pdba->atom[i - 1].resind == pdba->atom[i].resind) + && (strcmp(*pdba->atomname[i - 1], *pdba->atomname[i]) == 0)) { ndel++; if (bVerbose) { ri = &pdba->resinfo[pdba->atom[i].resind]; - printf("deleting duplicate atom %4s %s%4d%c", - *pdba->atomname[i], *ri->name, ri->nr, ri->ic); + printf("deleting duplicate atom %4s %s%4d%c", *pdba->atomname[i], *ri->name, + ri->nr, ri->ic); if (ri->chainid && (ri->chainid != ' ')) { printf(" ch %c", ri->chainid); @@ -796,17 +824,17 @@ static int remove_duplicate_atoms(t_atoms *pdba, gmx::ArrayRef x, boo /* sfree(pdba->atomname[i]); */ for (j = i; j < pdba->nr; j++) { - pdba->atom[j] = pdba->atom[j+1]; - pdba->atomname[j] = pdba->atomname[j+1]; + pdba->atom[j] = pdba->atom[j + 1]; + pdba->atomname[j] = pdba->atomname[j + 1]; if (pdba->pdbinfo) { - pdba->pdbinfo[j] = pdba->pdbinfo[j+1]; + pdba->pdbinfo[j] = pdba->pdbinfo[j + 1]; } - copy_rvec(x[j+1], x[j]); + copy_rvec(x[j + 1], x[j]); } - srenew(pdba->atom, pdba->nr); + srenew(pdba->atom, pdba->nr); /* srenew(pdba->atomname, pdba->nr); */ - srenew(pdba->pdbinfo, pdba->nr); + srenew(pdba->pdbinfo, pdba->nr); } } if (pdba->nr != oldnatoms) @@ -817,28 +845,26 @@ static int remove_duplicate_atoms(t_atoms *pdba, gmx::ArrayRef x, boo return pdba->nr; } -static void -checkResidueTypeSanity(t_atoms *pdba, - int r0, - int r1, - ResidueType *rt) +static void checkResidueTypeSanity(t_atoms* pdba, int r0, int r1, ResidueType* rt) { - std::string startResidueString = gmx::formatString("%s%d", *pdba->resinfo[r0].name, pdba->resinfo[r0].nr); - std::string endResidueString = gmx::formatString("%s%d", *pdba->resinfo[r1-1].name, pdba->resinfo[r1-1].nr); + std::string startResidueString = + gmx::formatString("%s%d", *pdba->resinfo[r0].name, pdba->resinfo[r0].nr); + std::string endResidueString = + gmx::formatString("%s%d", *pdba->resinfo[r1 - 1].name, pdba->resinfo[r1 - 1].nr); // Check whether all residues in chain have the same chain ID. - bool allResiduesHaveSameChainID = true; - char chainID0 = pdba->resinfo[r0].chainid; - char chainID; - std::string residueString; + bool allResiduesHaveSameChainID = true; + char chainID0 = pdba->resinfo[r0].chainid; + char chainID; + std::string residueString; for (int i = r0 + 1; i < r1; i++) { chainID = pdba->resinfo[i].chainid; if (chainID != chainID0) { - allResiduesHaveSameChainID = false; - residueString = gmx::formatString("%s%d", *pdba->resinfo[i].name, pdba->resinfo[i].nr); + allResiduesHaveSameChainID = false; + residueString = gmx::formatString("%s%d", *pdba->resinfo[i].name, pdba->resinfo[i].nr); break; } } @@ -848,8 +874,8 @@ checkResidueTypeSanity(t_atoms *pdba, gmx_fatal(FARGS, "The chain covering the range %s--%s does not have a consistent chain ID. " "The first residue has ID '%c', while residue %s has ID '%c'.", - startResidueString.c_str(), endResidueString.c_str(), - chainID0, residueString.c_str(), chainID); + startResidueString.c_str(), endResidueString.c_str(), chainID0, + residueString.c_str(), chainID); } // At this point all residues have the same ID. If they are also non-blank @@ -866,7 +892,7 @@ checkResidueTypeSanity(t_atoms *pdba, if (!gmx::equalCaseInsensitive(restype, restype0)) { allResiduesHaveSameType = false; - residueString = gmx::formatString("%s%d", *pdba->resinfo[i].name, pdba->resinfo[i].nr); + residueString = gmx::formatString("%s%d", *pdba->resinfo[i].name, pdba->resinfo[i].nr); break; } } @@ -881,16 +907,15 @@ checkResidueTypeSanity(t_atoms *pdba, "file in the GROMACS library directory. If there are other molecules " "such as ligands, they should not have the same chain ID as the " "adjacent protein chain since it's a separate molecule.", - startResidueString.c_str(), endResidueString.c_str(), - restype0.c_str(), residueString.c_str(), restype.c_str()); + startResidueString.c_str(), endResidueString.c_str(), restype0.c_str(), + residueString.c_str(), restype.c_str()); } } } -static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, - ResidueType *rt) +static void find_nc_ter(t_atoms* pdba, int r0, int r1, int* r_start, int* r_end, ResidueType* rt) { - int i; + int i; gmx::compat::optional startrestype; *r_start = -1; @@ -922,18 +947,20 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, { continue; } - if (gmx::equalCaseInsensitive(*startrestype, "Protein") || - gmx::equalCaseInsensitive(*startrestype, "DNA") || - gmx::equalCaseInsensitive(*startrestype, "RNA") ) + if (gmx::equalCaseInsensitive(*startrestype, "Protein") + || gmx::equalCaseInsensitive(*startrestype, "DNA") + || gmx::equalCaseInsensitive(*startrestype, "RNA")) { - printf("Identified residue %s%d as a starting terminus.\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr); + printf("Identified residue %s%d as a starting terminus.\n", *pdba->resinfo[i].name, + pdba->resinfo[i].nr); *r_start = i; } else if (gmx::equalCaseInsensitive(*startrestype, "Ion")) { if (ionNotes < 5) { - printf("Residue %s%d has type 'Ion', assuming it is not linked into a chain.\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr); + printf("Residue %s%d has type 'Ion', assuming it is not linked into a chain.\n", + *pdba->resinfo[i].name, pdba->resinfo[i].nr); } if (ionNotes == 4) { @@ -948,26 +975,35 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, { if (chainID == ' ') { - printf("\nWarning: Starting residue %s%d in chain not identified as Protein/RNA/DNA.\n" + printf("\nWarning: Starting residue %s%d in chain not identified as " + "Protein/RNA/DNA.\n" "This chain lacks identifiers, which makes it impossible to do strict\n" - "classification of the start/end residues. Here we need to guess this residue\n" - "should not be part of the chain and instead introduce a break, but that will\n" - "be catastrophic if they should in fact be linked. Please check your structure,\n" + "classification of the start/end residues. Here we need to guess this " + "residue\n" + "should not be part of the chain and instead introduce a break, but " + "that will\n" + "be catastrophic if they should in fact be linked. Please check your " + "structure,\n" "and add %s to residuetypes.dat if this was not correct.\n\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr, *pdba->resinfo[i].name); } else { - printf("\nWarning: No residues in chain starting at %s%d identified as Protein/RNA/DNA.\n" - "This makes it impossible to link them into a molecule, which could either be\n" - "correct or a catastrophic error. Please check your structure, and add all\n" - "necessary residue names to residuetypes.dat if this was not correct.\n\n", + printf("\nWarning: No residues in chain starting at %s%d identified as " + "Protein/RNA/DNA.\n" + "This makes it impossible to link them into a molecule, which could " + "either be\n" + "correct or a catastrophic error. Please check your structure, and add " + "all\n" + "necessary residue names to residuetypes.dat if this was not " + "correct.\n\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr); } } if (startWarnings == 4) { - printf("Disabling further warnings about unidentified residues at start of chain.\n"); + printf("Disabling further warnings about unidentified residues at start of " + "chain.\n"); } startWarnings++; } @@ -979,7 +1015,7 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, for (int i = *r_start; i < r1; i++) { gmx::compat::optional restype = - rt->optionalTypeOfNamedDatabaseResidue(*pdba->resinfo[i].name); + rt->optionalTypeOfNamedDatabaseResidue(*pdba->resinfo[i].name); if (!restype) { continue; @@ -992,7 +1028,8 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, { if (ionNotes < 5) { - printf("Residue %s%d has type 'Ion', assuming it is not linked into a chain.\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr); + printf("Residue %s%d has type 'Ion', assuming it is not linked into a chain.\n", + *pdba->resinfo[i].name, pdba->resinfo[i].nr); } if (ionNotes == 4) { @@ -1010,17 +1047,22 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, { printf("\nWarning: Residue %s%d in chain has different type ('%s') from\n" "residue %s%d ('%s'). This chain lacks identifiers, which makes\n" - "it impossible to do strict classification of the start/end residues. Here we\n" - "need to guess this residue should not be part of the chain and instead\n" - "introduce a break, but that will be catastrophic if they should in fact be\n" + "it impossible to do strict classification of the start/end residues. " + "Here we\n" + "need to guess this residue should not be part of the chain and " + "instead\n" + "introduce a break, but that will be catastrophic if they should in " + "fact be\n" "linked. Please check your structure, and add %s to residuetypes.dat\n" "if this was not correct.\n\n", *pdba->resinfo[i].name, pdba->resinfo[i].nr, restype->c_str(), - *pdba->resinfo[*r_start].name, pdba->resinfo[*r_start].nr, startrestype->c_str(), *pdba->resinfo[i].name); + *pdba->resinfo[*r_start].name, pdba->resinfo[*r_start].nr, + startrestype->c_str(), *pdba->resinfo[i].name); } if (endWarnings == 4) { - printf("Disabling further warnings about unidentified residues at end of chain.\n"); + printf("Disabling further warnings about unidentified residues at end of " + "chain.\n"); } endWarnings++; } @@ -1029,18 +1071,22 @@ static void find_nc_ter(t_atoms *pdba, int r0, int r1, int *r_start, int *r_end, if (*r_end >= 0) { - printf("Identified residue %s%d as a ending terminus.\n", *pdba->resinfo[*r_end].name, pdba->resinfo[*r_end].nr); + printf("Identified residue %s%d as a ending terminus.\n", *pdba->resinfo[*r_end].name, + pdba->resinfo[*r_end].nr); } } /* enum for chain separation */ -enum ChainSepType { - enChainSep_id_or_ter, enChainSep_id_and_ter, enChainSep_ter, - enChainSep_id, enChainSep_interactive -}; -static const char *ChainSepEnum[] = {"id_or_ter", "id_and_ter", "ter", "id", "interactive"}; -static const char *ChainSepInfoString[] = +enum ChainSepType { + enChainSep_id_or_ter, + enChainSep_id_and_ter, + enChainSep_ter, + enChainSep_id, + enChainSep_interactive +}; +static const char* ChainSepEnum[] = { "id_or_ter", "id_and_ter", "ter", "id", "interactive" }; +static const char* ChainSepInfoString[] = { "Splitting chemical chains based on TER records or chain id changing.\n", "Splitting chemical chains based on TER records and chain id changing.\n", "Splitting chemical chains based on TER records only (ignoring chain id).\n", @@ -1048,28 +1094,26 @@ static const char *ChainSepInfoString[] = "Splitting chemical chains interactively.\n" }; -static void -modify_chain_numbers(t_atoms * pdba, - ChainSepType enumChainSep) +static void modify_chain_numbers(t_atoms* pdba, ChainSepType enumChainSep) { - int i; - char old_prev_chainid; - char old_this_chainid; - int old_prev_chainnum; - int old_this_chainnum; - t_resinfo *ri; - char select[STRLEN]; - int new_chainnum; - int this_atomnum; - int prev_atomnum; - const char * prev_atomname; - const char * this_atomname; - const char * prev_resname; - const char * this_resname; - int prev_resnum; - int this_resnum; - char prev_chainid; - char this_chainid; + int i; + char old_prev_chainid; + char old_this_chainid; + int old_prev_chainnum; + int old_this_chainnum; + t_resinfo* ri; + char select[STRLEN]; + int new_chainnum; + int this_atomnum; + int prev_atomnum; + const char* prev_atomname; + const char* this_atomname; + const char* prev_resname; + const char* this_resname; + int prev_resnum; + int this_resnum; + char prev_chainid; + char this_chainid; /* The default chain enumeration is based on TER records only */ printf("%s", ChainSepInfoString[enumChainSep]); @@ -1078,29 +1122,29 @@ modify_chain_numbers(t_atoms * pdba, old_prev_chainnum = -1; new_chainnum = -1; - this_atomname = nullptr; - this_atomnum = -1; - this_resname = nullptr; - this_resnum = -1; - this_chainid = '?'; + this_atomname = nullptr; + this_atomnum = -1; + this_resname = nullptr; + this_resnum = -1; + this_chainid = '?'; for (i = 0; i < pdba->nres; i++) { - ri = &pdba->resinfo[i]; - old_this_chainid = ri->chainid; - old_this_chainnum = ri->chainnum; + ri = &pdba->resinfo[i]; + old_this_chainid = ri->chainid; + old_this_chainnum = ri->chainnum; - prev_atomname = this_atomname; - prev_atomnum = this_atomnum; - prev_resname = this_resname; - prev_resnum = this_resnum; - prev_chainid = this_chainid; + prev_atomname = this_atomname; + prev_atomnum = this_atomnum; + prev_resname = this_resname; + prev_resnum = this_resnum; + prev_chainid = this_chainid; - this_atomname = *(pdba->atomname[i]); - this_atomnum = (pdba->pdbinfo != nullptr) ? pdba->pdbinfo[i].atomnr : i+1; - this_resname = *ri->name; - this_resnum = ri->nr; - this_chainid = ri->chainid; + this_atomname = *(pdba->atomname[i]); + this_atomnum = (pdba->pdbinfo != nullptr) ? pdba->pdbinfo[i].atomnr : i + 1; + this_resname = *ri->name; + this_resnum = ri->nr; + this_chainid = ri->chainid; switch (enumChainSep) { @@ -1142,7 +1186,7 @@ modify_chain_numbers(t_atoms * pdba, prev_resname, prev_resnum, prev_chainid, prev_atomnum, prev_atomname, this_resname, this_resnum, this_chainid, this_atomnum, this_atomname); - if (nullptr == fgets(select, STRLEN-1, stdin)) + if (nullptr == fgets(select, STRLEN - 1, stdin)) { gmx_fatal(FARGS, "Error reading from stdin"); } @@ -1153,8 +1197,7 @@ modify_chain_numbers(t_atoms * pdba, } } break; - default: - gmx_fatal(FARGS, "Internal inconsistency - this shouldn't happen..."); + default: gmx_fatal(FARGS, "Internal inconsistency - this shouldn't happen..."); } old_prev_chainid = old_this_chainid; old_prev_chainnum = old_this_chainnum; @@ -1163,7 +1206,8 @@ modify_chain_numbers(t_atoms * pdba, } } -struct t_pdbchain { +struct t_pdbchain +{ char chainid = ' '; char chainnum = ' '; int start = -1; @@ -1173,42 +1217,54 @@ struct t_pdbchain { std::vector chainstart; }; -struct t_chain { - char chainid = ' '; - int chainnum = ' '; - bool bAllWat = false; - int nterpairs = -1; - std::vector chainstart; - std::vector ntdb; - std::vector ctdb; - std::vector r_start; - std::vector r_end; - t_atoms *pdba; - std::vector x; +struct t_chain +{ + char chainid = ' '; + int chainnum = ' '; + bool bAllWat = false; + int nterpairs = -1; + std::vector chainstart; + std::vector ntdb; + std::vector ctdb; + std::vector r_start; + std::vector r_end; + t_atoms* pdba; + std::vector x; }; // TODO make all enums into scoped enums /* enum for vsites */ -enum VSitesType { - enVSites_none, enVSites_hydrogens, enVSites_aromatics +enum VSitesType +{ + enVSites_none, + enVSites_hydrogens, + enVSites_aromatics }; -static const char *VSitesEnum[] = {"none", "hydrogens", "aromatics"}; +static const char* VSitesEnum[] = { "none", "hydrogens", "aromatics" }; /* enum for water model */ -enum WaterType { - enWater_select, enWater_none, enWater_spc, enWater_spce, - enWater_tip3p, enWater_tip4p, enWater_tip5p, enWater_tips3p -}; -static const char *WaterEnum[] = { - "select", "none", "spc", "spce", - "tip3p", "tip4p", "tip5p", "tips3p" +enum WaterType +{ + enWater_select, + enWater_none, + enWater_spc, + enWater_spce, + enWater_tip3p, + enWater_tip4p, + enWater_tip5p, + enWater_tips3p }; +static const char* WaterEnum[] = { "select", "none", "spc", "spce", + "tip3p", "tip4p", "tip5p", "tips3p" }; /* enum for merge */ -enum MergeType { - enMerge_no, enMerge_all, enMerge_interactive +enum MergeType +{ + enMerge_no, + enMerge_all, + enMerge_interactive }; -static const char *MergeEnum[] = {"no", "all", "interactive"}; +static const char* MergeEnum[] = { "no", "all", "interactive" }; namespace gmx { @@ -1218,93 +1274,91 @@ namespace class pdb2gmx : public ICommandLineOptionsModule { - public: - pdb2gmx() : - bVsites_(FALSE), bPrevWat_(FALSE), bVsiteAromatics_(FALSE), - enumChainSep_(enChainSep_id_or_ter), - enumVSites_(enVSites_none), - enumWater_(enWater_select), - enumMerge_(enMerge_no), - itp_file_(nullptr), - mHmult_(0) - { - } - - // From ICommandLineOptionsModule - void init(CommandLineModuleSettings * /*settings*/) override - { - } - - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - - void optionsFinished() override; - - int run() override; - - private: - bool bNewRTP_; - bool bInter_; - bool bCysMan_; - bool bLysMan_; - bool bAspMan_; - bool bGluMan_; - bool bHisMan_; - bool bGlnMan_; - bool bArgMan_; - bool bTerMan_; - bool bUnA_; - bool bHeavyH_; - bool bSort_; - bool bAllowMissing_; - bool bRemoveH_; - bool bDeuterate_; - bool bVerbose_; - bool bChargeGroups_; - bool bCmap_; - bool bRenumRes_; - bool bRTPresname_; - bool bIndexSet_; - bool bOutputSet_; - bool bVsites_; - bool bWat_; - bool bPrevWat_; - bool bITP_; - bool bVsiteAromatics_; - real angle_; - real distance_; - real posre_fc_; - real long_bond_dist_; - real short_bond_dist_; - - std::string indexOutputFile_; - std::string outputFile_; - std::string topologyFile_; - std::string includeTopologyFile_; - std::string outputConfFile_; - std::string inputConfFile_; - std::string outFile_; - std::string ff_; - - ChainSepType enumChainSep_; - VSitesType enumVSites_; - WaterType enumWater_; - MergeType enumMerge_; - - FILE *itp_file_; - char forcefield_[STRLEN]; - char ffdir_[STRLEN]; - char *ffname_; - char *watermodel_; - std::vector incls_; - std::vector mols_; - real mHmult_; +public: + pdb2gmx() : + bVsites_(FALSE), + bPrevWat_(FALSE), + bVsiteAromatics_(FALSE), + enumChainSep_(enChainSep_id_or_ter), + enumVSites_(enVSites_none), + enumWater_(enWater_select), + enumMerge_(enMerge_no), + itp_file_(nullptr), + mHmult_(0) + { + } + + // From ICommandLineOptionsModule + void init(CommandLineModuleSettings* /*settings*/) override {} + + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + + void optionsFinished() override; + + int run() override; + +private: + bool bNewRTP_; + bool bInter_; + bool bCysMan_; + bool bLysMan_; + bool bAspMan_; + bool bGluMan_; + bool bHisMan_; + bool bGlnMan_; + bool bArgMan_; + bool bTerMan_; + bool bUnA_; + bool bHeavyH_; + bool bSort_; + bool bAllowMissing_; + bool bRemoveH_; + bool bDeuterate_; + bool bVerbose_; + bool bChargeGroups_; + bool bCmap_; + bool bRenumRes_; + bool bRTPresname_; + bool bIndexSet_; + bool bOutputSet_; + bool bVsites_; + bool bWat_; + bool bPrevWat_; + bool bITP_; + bool bVsiteAromatics_; + real angle_; + real distance_; + real posre_fc_; + real long_bond_dist_; + real short_bond_dist_; + + std::string indexOutputFile_; + std::string outputFile_; + std::string topologyFile_; + std::string includeTopologyFile_; + std::string outputConfFile_; + std::string inputConfFile_; + std::string outFile_; + std::string ff_; + + ChainSepType enumChainSep_; + VSitesType enumVSites_; + WaterType enumWater_; + MergeType enumMerge_; + + FILE* itp_file_; + char forcefield_[STRLEN]; + char ffdir_[STRLEN]; + char* ffname_; + char* watermodel_; + std::vector incls_; + std::vector mols_; + real mHmult_; }; -void pdb2gmx::initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) +void pdb2gmx::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] reads a [REF].pdb[ref] (or [REF].gro[ref]) file, reads", "some database files, adds hydrogens to the molecules and generates", "coordinates in GROMACS (GROMOS), or optionally [REF].pdb[ref], format", @@ -1418,129 +1472,126 @@ void pdb2gmx::initOptions(IOptionsContainer *options, settings->setHelpText(desc); - options->addOption(BooleanOption("newrtp") - .store(&bNewRTP_).defaultValue(false).hidden() - .description("Write the residue database in new format to [TT]new.rtp[tt]")); - options->addOption(RealOption("lb") - .store(&long_bond_dist_).defaultValue(0.25).hidden() - .description("Long bond warning distance")); - options->addOption(RealOption("sb") - .store(&short_bond_dist_).defaultValue(0.05).hidden() - .description("Short bond warning distance")); - options->addOption(EnumOption("chainsep").enumValue(ChainSepEnum) - .store(&enumChainSep_) - .description("Condition in PDB files when a new chain should be started (adding termini)")); - options->addOption(EnumOption("merge").enumValue(MergeEnum) - .store(&enumMerge_) - .description("Merge multiple chains into a single [moleculetype]")); - options->addOption(StringOption("ff") - .store(&ff_).defaultValue("select") - .description("Force field, interactive by default. Use [TT]-h[tt] for information.")); - options->addOption(EnumOption("water") - .store(&enumWater_).enumValue(WaterEnum) - .description("Water model to use")); - options->addOption(BooleanOption("inter") - .store(&bInter_).defaultValue(false) - .description("Set the next 8 options to interactive")); - options->addOption(BooleanOption("ss") - .store(&bCysMan_).defaultValue(false) - .description("Interactive SS bridge selection")); - options->addOption(BooleanOption("ter") - .store(&bTerMan_).defaultValue(false) - .description("Interactive termini selection, instead of charged (default)")); - options->addOption(BooleanOption("lys") - .store(&bLysMan_).defaultValue(false) - .description("Interactive lysine selection, instead of charged")); - options->addOption(BooleanOption("arg") - .store(&bArgMan_).defaultValue(false) - .description("Interactive arginine selection, instead of charged")); - options->addOption(BooleanOption("asp") - .store(&bAspMan_).defaultValue(false) - .description("Interactive aspartic acid selection, instead of charged")); - options->addOption(BooleanOption("glu") - .store(&bGluMan_).defaultValue(false) - .description("Interactive glutamic acid selection, instead of charged")); - options->addOption(BooleanOption("gln") - .store(&bGlnMan_).defaultValue(false) - .description("Interactive glutamine selection, instead of charged")); - options->addOption(BooleanOption("his") - .store(&bHisMan_).defaultValue(false) - .description("Interactive histidine selection, instead of checking H-bonds")); - options->addOption(RealOption("angle") - .store(&angle_).defaultValue(135.0) - .description("Minimum hydrogen-donor-acceptor angle for a H-bond (degrees)")); - options->addOption(RealOption("dist") - .store(&distance_).defaultValue(0.3) - .description("Maximum donor-acceptor distance for a H-bond (nm)")); - options->addOption(BooleanOption("una") - .store(&bUnA_).defaultValue(false) - .description("Select aromatic rings with united CH atoms on phenylalanine, tryptophane and tyrosine")); - options->addOption(BooleanOption("sort") - .store(&bSort_).defaultValue(true).hidden() - .description("Sort the residues according to database, turning this off is dangerous as charge groups might be broken in parts")); - options->addOption(BooleanOption("ignh") - .store(&bRemoveH_).defaultValue(false) - .description("Ignore hydrogen atoms that are in the coordinate file")); - options->addOption(BooleanOption("missing") - .store(&bAllowMissing_).defaultValue(false) - .description("Continue when atoms are missing and bonds cannot be made, dangerous")); - options->addOption(BooleanOption("v") - .store(&bVerbose_).defaultValue(false) - .description("Be slightly more verbose in messages")); - options->addOption(RealOption("posrefc") - .store(&posre_fc_).defaultValue(1000) - .description("Force constant for position restraints")); - options->addOption(EnumOption("vsite") - .store(&enumVSites_).enumValue(VSitesEnum) - .description("Convert atoms to virtual sites")); - options->addOption(BooleanOption("heavyh") - .store(&bHeavyH_).defaultValue(false) - .description("Make hydrogen atoms heavy")); - options->addOption(BooleanOption("deuterate") - .store(&bDeuterate_).defaultValue(false) - .description("Change the mass of hydrogens to 2 amu")); + options->addOption(BooleanOption("newrtp").store(&bNewRTP_).defaultValue(false).hidden().description( + "Write the residue database in new format to [TT]new.rtp[tt]")); + options->addOption( + RealOption("lb").store(&long_bond_dist_).defaultValue(0.25).hidden().description("Long bond warning distance")); + options->addOption( + RealOption("sb").store(&short_bond_dist_).defaultValue(0.05).hidden().description("Short bond warning distance")); + options->addOption( + EnumOption("chainsep").enumValue(ChainSepEnum).store(&enumChainSep_).description("Condition in PDB files when a new chain should be started (adding termini)")); + options->addOption(EnumOption("merge") + .enumValue(MergeEnum) + .store(&enumMerge_) + .description("Merge multiple chains into a single [moleculetype]")); + options->addOption(StringOption("ff").store(&ff_).defaultValue("select").description( + "Force field, interactive by default. Use [TT]-h[tt] for information.")); + options->addOption( + EnumOption("water").store(&enumWater_).enumValue(WaterEnum).description("Water model to use")); + options->addOption(BooleanOption("inter").store(&bInter_).defaultValue(false).description( + "Set the next 8 options to interactive")); + options->addOption(BooleanOption("ss").store(&bCysMan_).defaultValue(false).description( + "Interactive SS bridge selection")); + options->addOption(BooleanOption("ter").store(&bTerMan_).defaultValue(false).description( + "Interactive termini selection, instead of charged (default)")); + options->addOption(BooleanOption("lys").store(&bLysMan_).defaultValue(false).description( + "Interactive lysine selection, instead of charged")); + options->addOption(BooleanOption("arg").store(&bArgMan_).defaultValue(false).description( + "Interactive arginine selection, instead of charged")); + options->addOption(BooleanOption("asp").store(&bAspMan_).defaultValue(false).description( + "Interactive aspartic acid selection, instead of charged")); + options->addOption(BooleanOption("glu").store(&bGluMan_).defaultValue(false).description( + "Interactive glutamic acid selection, instead of charged")); + options->addOption(BooleanOption("gln").store(&bGlnMan_).defaultValue(false).description( + "Interactive glutamine selection, instead of charged")); + options->addOption(BooleanOption("his").store(&bHisMan_).defaultValue(false).description( + "Interactive histidine selection, instead of checking H-bonds")); + options->addOption(RealOption("angle").store(&angle_).defaultValue(135.0).description( + "Minimum hydrogen-donor-acceptor angle for a H-bond (degrees)")); + options->addOption( + RealOption("dist").store(&distance_).defaultValue(0.3).description("Maximum donor-acceptor distance for a H-bond (nm)")); + options->addOption(BooleanOption("una").store(&bUnA_).defaultValue(false).description( + "Select aromatic rings with united CH atoms on phenylalanine, tryptophane and " + "tyrosine")); + options->addOption(BooleanOption("sort").store(&bSort_).defaultValue(true).hidden().description( + "Sort the residues according to database, turning this off is dangerous as charge " + "groups might be broken in parts")); + options->addOption( + BooleanOption("ignh").store(&bRemoveH_).defaultValue(false).description("Ignore hydrogen atoms that are in the coordinate file")); + options->addOption( + BooleanOption("missing") + .store(&bAllowMissing_) + .defaultValue(false) + .description( + "Continue when atoms are missing and bonds cannot be made, dangerous")); + options->addOption( + BooleanOption("v").store(&bVerbose_).defaultValue(false).description("Be slightly more verbose in messages")); + options->addOption( + RealOption("posrefc").store(&posre_fc_).defaultValue(1000).description("Force constant for position restraints")); + options->addOption( + EnumOption("vsite").store(&enumVSites_).enumValue(VSitesEnum).description("Convert atoms to virtual sites")); + options->addOption(BooleanOption("heavyh").store(&bHeavyH_).defaultValue(false).description( + "Make hydrogen atoms heavy")); + options->addOption( + BooleanOption("deuterate").store(&bDeuterate_).defaultValue(false).description("Change the mass of hydrogens to 2 amu")); options->addOption(BooleanOption("chargegrp") - .store(&bChargeGroups_).defaultValue(true) - .description("Use charge groups in the [REF].rtp[ref] file")); - options->addOption(BooleanOption("cmap") - .store(&bCmap_).defaultValue(true) - .description("Use cmap torsions (if enabled in the [REF].rtp[ref] file)")); + .store(&bChargeGroups_) + .defaultValue(true) + .description("Use charge groups in the [REF].rtp[ref] file")); + options->addOption(BooleanOption("cmap").store(&bCmap_).defaultValue(true).description( + "Use cmap torsions (if enabled in the [REF].rtp[ref] file)")); options->addOption(BooleanOption("renum") - .store(&bRenumRes_).defaultValue(false) - .description("Renumber the residues consecutively in the output")); + .store(&bRenumRes_) + .defaultValue(false) + .description("Renumber the residues consecutively in the output")); options->addOption(BooleanOption("rtpres") - .store(&bRTPresname_).defaultValue(false) - .description("Use [REF].rtp[ref] entry names as residue names")); + .store(&bRTPresname_) + .defaultValue(false) + .description("Use [REF].rtp[ref] entry names as residue names")); options->addOption(FileNameOption("f") - .legacyType(efSTX).inputFile() - .store(&inputConfFile_).required() - .defaultBasename("protein").defaultType(efPDB) - .description("Structure file")); + .legacyType(efSTX) + .inputFile() + .store(&inputConfFile_) + .required() + .defaultBasename("protein") + .defaultType(efPDB) + .description("Structure file")); options->addOption(FileNameOption("o") - .legacyType(efSTO).outputFile() - .store(&outputConfFile_).required() - .defaultBasename("conf") - .description("Structure file")); + .legacyType(efSTO) + .outputFile() + .store(&outputConfFile_) + .required() + .defaultBasename("conf") + .description("Structure file")); options->addOption(FileNameOption("p") - .legacyType(efTOP).outputFile() - .store(&topologyFile_).required() - .defaultBasename("topol") - .description("Topology file")); + .legacyType(efTOP) + .outputFile() + .store(&topologyFile_) + .required() + .defaultBasename("topol") + .description("Topology file")); options->addOption(FileNameOption("i") - .legacyType(efITP).outputFile() - .store(&includeTopologyFile_).required() - .defaultBasename("posre") - .description("Include file for topology")); + .legacyType(efITP) + .outputFile() + .store(&includeTopologyFile_) + .required() + .defaultBasename("posre") + .description("Include file for topology")); options->addOption(FileNameOption("n") - .legacyType(efNDX).outputFile() - .store(&indexOutputFile_).storeIsSet(&bIndexSet_) - .defaultBasename("index") - .description("Index file")); + .legacyType(efNDX) + .outputFile() + .store(&indexOutputFile_) + .storeIsSet(&bIndexSet_) + .defaultBasename("index") + .description("Index file")); options->addOption(FileNameOption("q") - .legacyType(efSTO).outputFile() - .store(&outFile_).storeIsSet(&bOutputSet_) - .defaultBasename("clean").defaultType(efPDB) - .description("Structure file")); + .legacyType(efSTO) + .outputFile() + .store(&outFile_) + .storeIsSet(&bOutputSet_) + .defaultBasename("clean") + .defaultType(efPDB) + .description("Structure file")); } void pdb2gmx::optionsFinished() @@ -1576,9 +1627,8 @@ void pdb2gmx::optionsFinished() } /* Force field selection, interactive or direct */ - choose_ff(strcmp(ff_.c_str(), "select") == 0 ? nullptr : ff_.c_str(), - forcefield_, sizeof(forcefield_), - ffdir_, sizeof(ffdir_)); + choose_ff(strcmp(ff_.c_str(), "select") == 0 ? nullptr : ff_.c_str(), forcefield_, + sizeof(forcefield_), ffdir_, sizeof(ffdir_)); if (strlen(forcefield_) > 0) { @@ -1596,23 +1646,22 @@ int pdb2gmx::run() char select[STRLEN]; std::vector ssbonds; - int this_atomnum; - int prev_atomnum; - const char *prev_atomname; - const char *this_atomname; - const char *prev_resname; - const char *this_resname; - int prev_resnum; - int this_resnum; - char prev_chainid; - char this_chainid; - int prev_chainnumber; - int this_chainnumber; - int this_chainstart; - int prev_chainstart; - - printf("\nUsing the %s force field in directory %s\n\n", - ffname_, ffdir_); + int this_atomnum; + int prev_atomnum; + const char* prev_atomname; + const char* this_atomname; + const char* prev_resname; + const char* this_resname; + int prev_resnum; + int this_resnum; + char prev_chainid; + char this_chainid; + int prev_chainnumber; + int this_chainnumber; + int this_chainstart; + int prev_chainstart; + + printf("\nUsing the %s force field in directory %s\n\n", ffname_, ffdir_); choose_watermodel(WaterEnum[enumWater_], ffdir_, &watermodel_); @@ -1632,7 +1681,7 @@ int pdb2gmx::run() break; default: gmx_fatal(FARGS, "Internal inconsistency: VSitesEnum='%s'", VSitesEnum[enumVSites_]); - } /* end switch */ + } /* end switch */ /* Open the symbol table */ t_symtab symtab; @@ -1644,18 +1693,18 @@ int pdb2gmx::run() /* Read residue renaming database(s), if present */ std::vector rrn = fflib_search_file_end(ffdir_, ".r2b", FALSE); - std::vector rtprename; - for (const auto &filename : rrn) + std::vector rtprename; + for (const auto& filename : rrn) { printf("going to rename %s\n", filename.c_str()); - FILE *fp = fflib_open(filename); + FILE* fp = fflib_open(filename); read_rtprename(filename.c_str(), fp, &rtprename); gmx_ffclose(fp); } /* Add all alternative names from the residue renaming database to the list of recognized amino/nucleic acids. */ - for (const auto &rename : rtprename) + for (const auto& rename : rtprename) { /* Only add names if the 'standard' gromacs/iupac base name was found */ if (auto restype = rt.optionalTypeOfNamedDatabaseResidue(rename.gmx)) @@ -1668,15 +1717,13 @@ int pdb2gmx::run() } matrix box; - const char *watres; + const char* watres; clear_mat(box); - if (watermodel_ != nullptr && (strstr(watermodel_, "4p") || - strstr(watermodel_, "4P"))) + if (watermodel_ != nullptr && (strstr(watermodel_, "4p") || strstr(watermodel_, "4P"))) { watres = "HO4"; } - else if (watermodel_ != nullptr && (strstr(watermodel_, "5p") || - strstr(watermodel_, "5P"))) + else if (watermodel_ != nullptr && (strstr(watermodel_, "5p") || strstr(watermodel_, "5P"))) { watres = "HO5"; } @@ -1686,13 +1733,12 @@ int pdb2gmx::run() } AtomProperties aps; - char *title = nullptr; + char* title = nullptr; int ePBC; t_atoms pdba_all; - rvec *pdbx; - int natom = read_pdball(inputConfFile_.c_str(), bOutputSet_, outFile_.c_str(), - &title, &pdba_all, &pdbx, &ePBC, box, bRemoveH_, - &symtab, &rt, watres, &aps, bVerbose_); + rvec* pdbx; + int natom = read_pdball(inputConfFile_.c_str(), bOutputSet_, outFile_.c_str(), &title, &pdba_all, + &pdbx, &ePBC, box, bRemoveH_, &symtab, &rt, watres, &aps, bVerbose_); if (natom == 0) { @@ -1705,64 +1751,68 @@ int pdb2gmx::run() modify_chain_numbers(&pdba_all, enumChainSep_); - int nchainmerges = 0; + int nchainmerges = 0; - this_atomname = nullptr; - this_atomnum = -1; - this_resname = nullptr; - this_resnum = -1; - this_chainid = '?'; - this_chainnumber = -1; - this_chainstart = 0; + this_atomname = nullptr; + this_atomnum = -1; + this_resname = nullptr; + this_resnum = -1; + this_chainid = '?'; + this_chainnumber = -1; + this_chainstart = 0; /* Keep the compiler happy */ - prev_chainstart = 0; + prev_chainstart = 0; int numChains = 0; std::vector pdb_ch; - t_resinfo *ri; - bool bMerged = false; + t_resinfo* ri; + bool bMerged = false; for (int i = 0; (i < natom); i++) { ri = &pdba_all.resinfo[pdba_all.atom[i].resind]; /* TODO this should live in a helper object, and consolidate that with code in modify_chain_numbers */ - prev_atomname = this_atomname; - prev_atomnum = this_atomnum; - prev_resname = this_resname; - prev_resnum = this_resnum; - prev_chainid = this_chainid; - prev_chainnumber = this_chainnumber; + prev_atomname = this_atomname; + prev_atomnum = this_atomnum; + prev_resname = this_resname; + prev_resnum = this_resnum; + prev_chainid = this_chainid; + prev_chainnumber = this_chainnumber; if (!bMerged) { - prev_chainstart = this_chainstart; + prev_chainstart = this_chainstart; } - this_atomname = *pdba_all.atomname[i]; - this_atomnum = (pdba_all.pdbinfo != nullptr) ? pdba_all.pdbinfo[i].atomnr : i+1; - this_resname = *ri->name; - this_resnum = ri->nr; - this_chainid = ri->chainid; - this_chainnumber = ri->chainnum; + this_atomname = *pdba_all.atomname[i]; + this_atomnum = (pdba_all.pdbinfo != nullptr) ? pdba_all.pdbinfo[i].atomnr : i + 1; + this_resname = *ri->name; + this_resnum = ri->nr; + this_chainid = ri->chainid; + this_chainnumber = ri->chainnum; bWat_ = gmx::equalCaseInsensitive(*ri->name, watres); if ((i == 0) || (this_chainnumber != prev_chainnumber) || (bWat_ != bPrevWat_)) { - GMX_RELEASE_ASSERT(pdba_all.pdbinfo, "Must have pdbinfo from reading a PDB file if chain number is changing"); + GMX_RELEASE_ASSERT( + pdba_all.pdbinfo, + "Must have pdbinfo from reading a PDB file if chain number is changing"); this_chainstart = pdba_all.atom[i].resind; bMerged = false; if (i > 0 && !bWat_) { if (!strncmp(MergeEnum[enumMerge_], "int", 3)) { - printf("Merge chain ending with residue %s%d (chain id '%c', atom %d %s) and chain starting with\n" - "residue %s%d (chain id '%c', atom %d %s) into a single moleculetype (keeping termini)? [n/y]\n", + printf("Merge chain ending with residue %s%d (chain id '%c', atom %d %s) and " + "chain starting with\n" + "residue %s%d (chain id '%c', atom %d %s) into a single moleculetype " + "(keeping termini)? [n/y]\n", prev_resname, prev_resnum, prev_chainid, prev_atomnum, prev_atomname, this_resname, this_resnum, this_chainid, this_atomnum, this_atomname); - if (nullptr == fgets(select, STRLEN-1, stdin)) + if (nullptr == fgets(select, STRLEN - 1, stdin)) { gmx_fatal(FARGS, "Error reading from stdin"); } @@ -1776,10 +1826,10 @@ int pdb2gmx::run() if (bMerged) { - pdb_ch[numChains-1].chainstart[pdb_ch[numChains-1].nterpairs] = - pdba_all.atom[i].resind - prev_chainstart; - pdb_ch[numChains-1].nterpairs++; - pdb_ch[numChains-1].chainstart.resize(pdb_ch[numChains-1].nterpairs+1); + pdb_ch[numChains - 1].chainstart[pdb_ch[numChains - 1].nterpairs] = + pdba_all.atom[i].resind - prev_chainstart; + pdb_ch[numChains - 1].nterpairs++; + pdb_ch[numChains - 1].chainstart.resize(pdb_ch[numChains - 1].nterpairs + 1); nchainmerges++; } else @@ -1787,7 +1837,7 @@ int pdb2gmx::run() /* set natom for previous chain */ if (numChains > 0) { - pdb_ch[numChains-1].natom = i-pdb_ch[numChains-1].start; + pdb_ch[numChains - 1].natom = i - pdb_ch[numChains - 1].start; } if (bWat_) { @@ -1799,8 +1849,10 @@ int pdb2gmx::run() { if (pdb_ch[j].chainid != ' ' && pdb_ch[j].chainid == ri->chainid) { - printf("WARNING: Chain identifier '%c' is used in two non-sequential blocks.\n" - "They will be treated as separate chains unless you reorder your file.\n", + printf("WARNING: Chain identifier '%c' is used in two non-sequential " + "blocks.\n" + "They will be treated as separate chains unless you reorder your " + "file.\n", ri->chainid); } } @@ -1817,7 +1869,7 @@ int pdb2gmx::run() { newChain.nterpairs = 1; } - newChain.chainstart.resize(newChain.nterpairs+1); + newChain.chainstart.resize(newChain.nterpairs + 1); /* modified [numChains] to [0] below */ newChain.chainstart[0] = 0; pdb_ch.push_back(newChain); @@ -1826,7 +1878,7 @@ int pdb2gmx::run() } bPrevWat_ = bWat_; } - pdb_ch.back().natom = natom-pdb_ch.back().start; + pdb_ch.back().natom = natom - pdb_ch.back().start; /* set all the water blocks at the end of the chain */ std::vector swap_index(numChains); @@ -1852,12 +1904,12 @@ int pdb2gmx::run() printf("Moved all the water blocks to the end\n"); } - t_atoms *pdba; + t_atoms* pdba; std::vector chains(numChains); /* copy pdb data and x for all chains */ for (int i = 0; (i < numChains); i++) { - int si = swap_index[i]; + int si = swap_index[i]; chains[i].chainid = pdb_ch[si].chainid; chains[i].chainnum = pdb_ch[si].chainnum; chains[i].bAllWat = pdb_ch[si].bAllWat; @@ -1872,15 +1924,14 @@ int pdb2gmx::run() init_t_atoms(chains[i].pdba, pdb_ch[si].natom, true); for (j = 0; j < chains[i].pdba->nr; j++) { - chains[i].pdba->atom[j] = pdba_all.atom[pdb_ch[si].start+j]; - chains[i].pdba->atomname[j] = - put_symtab(&symtab, *pdba_all.atomname[pdb_ch[si].start+j]); - chains[i].pdba->pdbinfo[j] = pdba_all.pdbinfo[pdb_ch[si].start+j]; - chains[i].x.emplace_back(pdbx[pdb_ch[si].start+j]); + chains[i].pdba->atom[j] = pdba_all.atom[pdb_ch[si].start + j]; + chains[i].pdba->atomname[j] = put_symtab(&symtab, *pdba_all.atomname[pdb_ch[si].start + j]); + chains[i].pdba->pdbinfo[j] = pdba_all.pdbinfo[pdb_ch[si].start + j]; + chains[i].x.emplace_back(pdbx[pdb_ch[si].start + j]); } /* Re-index the residues assuming that the indices are continuous */ int k = chains[i].pdba->atom[0].resind; - int nres = chains[i].pdba->atom[chains[i].pdba->nr-1].resind - k + 1; + int nres = chains[i].pdba->atom[chains[i].pdba->nr - 1].resind - k + 1; chains[i].pdba->nres = nres; for (int j = 0; j < chains[i].pdba->nr; j++) { @@ -1889,8 +1940,8 @@ int pdb2gmx::run() srenew(chains[i].pdba->resinfo, nres); for (int j = 0; j < nres; j++) { - chains[i].pdba->resinfo[j] = pdba_all.resinfo[k+j]; - chains[i].pdba->resinfo[j].name = put_symtab(&symtab, *pdba_all.resinfo[k+j].name); + chains[i].pdba->resinfo[j] = pdba_all.resinfo[k + j]; + chains[i].pdba->resinfo[j].name = put_symtab(&symtab, *pdba_all.resinfo[k + j].name); /* make all chain identifiers equal to that of the chain */ chains[i].pdba->resinfo[j].chainid = pdb_ch[si].chainid; } @@ -1898,22 +1949,18 @@ int pdb2gmx::run() if (nchainmerges > 0) { - printf("\nMerged chains into joint molecule definitions at %d places.\n\n", - nchainmerges); + printf("\nMerged chains into joint molecule definitions at %d places.\n\n", nchainmerges); } printf("There are %d chains and %d blocks of water and " "%d residues with %d atoms\n", - numChains-nwaterchain, nwaterchain, - pdba_all.nres, natom); + numChains - nwaterchain, nwaterchain, pdba_all.nres, natom); printf("\n %5s %4s %6s\n", "chain", "#res", "#atoms"); for (int i = 0; (i < numChains); i++) { - printf(" %d '%c' %5d %6d %s\n", - i+1, chains[i].chainid ? chains[i].chainid : '-', - chains[i].pdba->nres, chains[i].pdba->nr, - chains[i].bAllWat ? "(only water)" : ""); + printf(" %d '%c' %5d %6d %s\n", i + 1, chains[i].chainid ? chains[i].chainid : '-', + chains[i].pdba->nres, chains[i].pdba->nr, chains[i].bAllWat ? "(only water)" : ""); } printf("\n"); @@ -1924,16 +1971,16 @@ int pdb2gmx::run() /* read residue database */ printf("Reading residue database... (%s)\n", forcefield_); - std::vector rtpf = fflib_search_file_end(ffdir_, ".rtp", true); + std::vector rtpf = fflib_search_file_end(ffdir_, ".rtp", true); std::vector rtpFFDB; - for (const auto &filename : rtpf) + for (const auto& filename : rtpf) { readResidueDatabase(filename, &rtpFFDB, &atype, &symtab, false); } if (bNewRTP_) { /* Not correct with multiple rtp input files with different bonded types */ - FILE *fp = gmx_fio_fopen("new.rtp", "w"); + FILE* fp = gmx_fio_fopen("new.rtp", "w"); print_resall(fp, rtpFFDB, atype); gmx_fio_fclose(fp); } @@ -1943,21 +1990,21 @@ int pdb2gmx::run() read_h_db(ffdir_, &ah); /* Read Termini database... */ - std::vector ntdb; - std::vector ctdb; - std::vector tdblist; - int nNtdb = read_ter_db(ffdir_, 'n', &ntdb, &atype); - int nCtdb = read_ter_db(ffdir_, 'c', &ctdb, &atype); + std::vector ntdb; + std::vector ctdb; + std::vector tdblist; + int nNtdb = read_ter_db(ffdir_, 'n', &ntdb, &atype); + int nCtdb = read_ter_db(ffdir_, 'c', &ctdb, &atype); - FILE *top_file = gmx_fio_fopen(topologyFile_.c_str(), "w"); + FILE* top_file = gmx_fio_fopen(topologyFile_.c_str(), "w"); print_top_header(top_file, topologyFile_.c_str(), FALSE, ffdir_, mHmult_); - t_chain *cc; - std::vector x; + t_chain* cc; + std::vector x; /* new pdb datastructure for sorting. */ - t_atoms **sortAtoms = nullptr; - t_atoms **localAtoms = nullptr; + t_atoms** sortAtoms = nullptr; + t_atoms** localAtoms = nullptr; snew(sortAtoms, numChains); snew(localAtoms, numChains); for (int chain = 0; (chain < numChains); chain++) @@ -1970,27 +2017,25 @@ int pdb2gmx::run() natom = cc->pdba->nr; int nres = cc->pdba->nres; - if (cc->chainid && ( cc->chainid != ' ' ) ) + if (cc->chainid && (cc->chainid != ' ')) { - printf("Processing chain %d '%c' (%d atoms, %d residues)\n", - chain+1, cc->chainid, natom, nres); + printf("Processing chain %d '%c' (%d atoms, %d residues)\n", chain + 1, cc->chainid, + natom, nres); } else { - printf("Processing chain %d (%d atoms, %d residues)\n", - chain+1, natom, nres); + printf("Processing chain %d (%d atoms, %d residues)\n", chain + 1, natom, nres); } - process_chain(pdba, x, bUnA_, bUnA_, bUnA_, bLysMan_, bAspMan_, bGluMan_, - bHisMan_, bArgMan_, bGlnMan_, angle_, distance_, &symtab, - rtprename); + process_chain(pdba, x, bUnA_, bUnA_, bUnA_, bLysMan_, bAspMan_, bGluMan_, bHisMan_, + bArgMan_, bGlnMan_, angle_, distance_, &symtab, rtprename); cc->chainstart[cc->nterpairs] = pdba->nres; - j = 0; + j = 0; for (int i = 0; i < cc->nterpairs; i++) { - find_nc_ter(pdba, cc->chainstart[i], cc->chainstart[i+1], - &(cc->r_start[j]), &(cc->r_end[j]), &rt); + find_nc_ter(pdba, cc->chainstart[i], cc->chainstart[i + 1], &(cc->r_start[j]), + &(cc->r_end[j]), &rt); if (cc->r_start[j] >= 0 && cc->r_end[j] >= 0) { @@ -2010,8 +2055,7 @@ int pdb2gmx::run() if (!rtprename.empty()) { - rename_resrtp(pdba, cc->nterpairs, cc->r_start, cc->r_end, rtprename, - &symtab, bVerbose_); + rename_resrtp(pdba, cc->nterpairs, cc->r_start, cc->r_end, rtprename, &symtab, bVerbose_); } for (int i = 0; i < cc->nterpairs; i++) @@ -2024,12 +2068,13 @@ int pdb2gmx::run() /* First the N terminus */ if (nNtdb > 0) { - tdblist = filter_ter(ntdb, - *pdba->resinfo[cc->r_start[i]].name); + tdblist = filter_ter(ntdb, *pdba->resinfo[cc->r_start[i]].name); if (tdblist.empty()) { - printf("No suitable end (N or 5') terminus found in database - assuming this residue\n" - "is already in a terminus-specific form and skipping terminus selection.\n"); + printf("No suitable end (N or 5') terminus found in database - assuming this " + "residue\n" + "is already in a terminus-specific form and skipping terminus " + "selection.\n"); cc->ntdb.push_back(nullptr); } else @@ -2037,8 +2082,7 @@ int pdb2gmx::run() if (bTerMan_ && !tdblist.empty()) { sprintf(select, "Select start terminus type for %s-%d", - *pdba->resinfo[cc->r_start[i]].name, - pdba->resinfo[cc->r_start[i]].nr); + *pdba->resinfo[cc->r_start[i]].name, pdba->resinfo[cc->r_start[i]].nr); cc->ntdb.push_back(choose_ter(tdblist, select)); } else @@ -2046,10 +2090,8 @@ int pdb2gmx::run() cc->ntdb.push_back(tdblist[0]); } - printf("Start terminus %s-%d: %s\n", - *pdba->resinfo[cc->r_start[i]].name, - pdba->resinfo[cc->r_start[i]].nr, - (cc->ntdb[i])->name.c_str()); + printf("Start terminus %s-%d: %s\n", *pdba->resinfo[cc->r_start[i]].name, + pdba->resinfo[cc->r_start[i]].nr, (cc->ntdb[i])->name.c_str()); tdblist.clear(); } } @@ -2061,12 +2103,13 @@ int pdb2gmx::run() /* And the C terminus */ if (nCtdb > 0) { - tdblist = filter_ter(ctdb, - *pdba->resinfo[cc->r_end[i]].name); + tdblist = filter_ter(ctdb, *pdba->resinfo[cc->r_end[i]].name); if (tdblist.empty()) { - printf("No suitable end (C or 3') terminus found in database - assuming this residue\n" - "is already in a terminus-specific form and skipping terminus selection.\n"); + printf("No suitable end (C or 3') terminus found in database - assuming this " + "residue\n" + "is already in a terminus-specific form and skipping terminus " + "selection.\n"); cc->ctdb.push_back(nullptr); } else @@ -2074,18 +2117,15 @@ int pdb2gmx::run() if (bTerMan_ && !tdblist.empty()) { sprintf(select, "Select end terminus type for %s-%d", - *pdba->resinfo[cc->r_end[i]].name, - pdba->resinfo[cc->r_end[i]].nr); + *pdba->resinfo[cc->r_end[i]].name, pdba->resinfo[cc->r_end[i]].nr); cc->ctdb.push_back(choose_ter(tdblist, select)); } else { cc->ctdb.push_back(tdblist[0]); } - printf("End terminus %s-%d: %s\n", - *pdba->resinfo[cc->r_end[i]].name, - pdba->resinfo[cc->r_end[i]].nr, - (cc->ctdb[i])->name.c_str()); + printf("End terminus %s-%d: %s\n", *pdba->resinfo[cc->r_end[i]].name, + pdba->resinfo[cc->r_end[i]].nr, (cc->ctdb[i])->name.c_str()); tdblist.clear(); } } @@ -2096,25 +2136,22 @@ int pdb2gmx::run() } std::vector hb_chain; /* lookup hackblocks and rtp for all residues */ - std::vector restp_chain; - get_hackblocks_rtp(&hb_chain, &restp_chain, - rtpFFDB, pdba->nres, pdba->resinfo, - cc->nterpairs, &symtab, cc->ntdb, cc->ctdb, cc->r_start, cc->r_end, - bAllowMissing_); + std::vector restp_chain; + get_hackblocks_rtp(&hb_chain, &restp_chain, rtpFFDB, pdba->nres, pdba->resinfo, cc->nterpairs, + &symtab, cc->ntdb, cc->ctdb, cc->r_start, cc->r_end, bAllowMissing_); /* ideally, now we would not need the rtp itself anymore, but do everything using the hb and restp arrays. Unfortunately, that requires some re-thinking of code in gen_vsite.c, which I won't do now :( AF 26-7-99 */ - rename_atoms(nullptr, ffdir_, - pdba, &symtab, restp_chain, false, &rt, false, bVerbose_); + rename_atoms(nullptr, ffdir_, pdba, &symtab, restp_chain, false, &rt, false, bVerbose_); match_atomnames_with_rtp(restp_chain, hb_chain, pdba, &symtab, x, bVerbose_); if (bSort_) { - char **gnames; - t_blocka *block = new_blocka(); + char** gnames; + t_blocka* block = new_blocka(); snew(gnames, 1); sort_pdbatoms(restp_chain, natom, &pdba, &sortAtoms[chain], &x, block, &gnames); remove_duplicate_atoms(pdba, x, bVerbose_); @@ -2122,7 +2159,8 @@ int pdb2gmx::run() { if (bRemoveH_) { - fprintf(stderr, "WARNING: with the -remh option the generated " + fprintf(stderr, + "WARNING: with the -remh option the generated " "index file (%s) might be useless\n" "(the index file is generated before hydrogens are added)", indexOutputFile_.c_str()); @@ -2139,20 +2177,20 @@ int pdb2gmx::run() } else { - fprintf(stderr, "WARNING: " + fprintf(stderr, + "WARNING: " "without sorting no check for duplicate atoms can be done\n"); } /* Generate Hydrogen atoms (and termini) in the sequence */ printf("Generating any missing hydrogen atoms and/or adding termini.\n"); - add_h(&pdba, &localAtoms[chain], &x, ah, &symtab, - cc->nterpairs, cc->ntdb, cc->ctdb, cc->r_start, cc->r_end, bAllowMissing_); - printf("Now there are %d residues with %d atoms\n", - pdba->nres, pdba->nr); + add_h(&pdba, &localAtoms[chain], &x, ah, &symtab, cc->nterpairs, cc->ntdb, cc->ctdb, + cc->r_start, cc->r_end, bAllowMissing_); + printf("Now there are %d residues with %d atoms\n", pdba->nres, pdba->nr); /* make up molecule name(s) */ - int k = (cc->nterpairs > 0 && cc->r_start[0] >= 0) ? cc->r_start[0] : 0; + int k = (cc->nterpairs > 0 && cc->r_start[0] >= 0) ? cc->r_start[0] : 0; std::string restype = rt.typeOfNamedDatabaseResidue(*pdba->resinfo[k].name); @@ -2184,7 +2222,7 @@ int pdb2gmx::run() /* Add the number for this chain identifier if there are multiple copies */ if (nid_used > 0) { - suffix.append(formatString("%d", nid_used+1)); + suffix.append(formatString("%d", nid_used + 1)); } if (suffix.length() > 0) @@ -2197,18 +2235,19 @@ int pdb2gmx::run() molname = restype; } } - std::string itp_fn = topologyFile_;; + std::string itp_fn = topologyFile_; + std::string posre_fn = includeTopologyFile_; - if ((numChains-nwaterchain > 1) && !cc->bAllWat) + if ((numChains - nwaterchain > 1) && !cc->bAllWat) { - bITP_ = true; + bITP_ = true; printf("Chain time...\n"); - //construct the itp file name + // construct the itp file name itp_fn = stripSuffixIfPresent(itp_fn, ".top"); itp_fn.append("_"); itp_fn.append(molname); itp_fn.append(".itp"); - //now do the same for posre + // now do the same for posre posre_fn = stripSuffixIfPresent(posre_fn, ".itp"); posre_fn.append("_"); posre_fn.append(molname); @@ -2218,8 +2257,8 @@ int pdb2gmx::run() posre_fn = Path::concatenateBeforeExtension(posre_fn, "_pr"); } incls_.emplace_back(); - incls_.back() = itp_fn; - itp_file_ = gmx_fio_fopen(itp_fn.c_str(), "w"); + incls_.back() = itp_fn; + itp_file_ = gmx_fio_fopen(itp_fn.c_str(), "w"); } else { @@ -2243,7 +2282,7 @@ int pdb2gmx::run() print_top_comment(itp_file_, itp_fn.c_str(), ffdir_, true); } - FILE *top_file2; + FILE* top_file2; if (cc->bAllWat) { top_file2 = nullptr; @@ -2257,13 +2296,9 @@ int pdb2gmx::run() top_file2 = top_file; } - pdb2top(top_file2, posre_fn.c_str(), molname.c_str(), pdba, &x, &atype, &symtab, - rtpFFDB, - restp_chain, hb_chain, - bAllowMissing_, - bVsites_, bVsiteAromatics_, ffdir_, - mHmult_, ssbonds, - long_bond_dist_, short_bond_dist_, bDeuterate_, bChargeGroups_, bCmap_, + pdb2top(top_file2, posre_fn.c_str(), molname.c_str(), pdba, &x, &atype, &symtab, rtpFFDB, + restp_chain, hb_chain, bAllowMissing_, bVsites_, bVsiteAromatics_, ffdir_, mHmult_, + ssbonds, long_bond_dist_, short_bond_dist_, bDeuterate_, bChargeGroups_, bCmap_, bRenumRes_, bRTPresname_); if (!cc->bAllWat) @@ -2287,9 +2322,10 @@ int pdb2gmx::run() { if (chains[chain].bAllWat) { - auto message = formatString("You have chosen not to include a water model, " - "but there is water in the input file. Select a " - "water model or remove the water from your input file."); + auto message = formatString( + "You have chosen not to include a water model, " + "but there is water in the input file. Select a " + "water model or remove the water from your input file."); GMX_THROW(InconsistentInputError(message)); } } @@ -2299,10 +2335,11 @@ int pdb2gmx::run() std::string waterFile = formatString("%s%c%s.itp", ffdir_, DIR_SEPARATOR, watermodel_); if (!fflib_fexist(waterFile)) { - auto message = formatString("The topology file '%s' for the selected water " - "model '%s' can not be found in the force field " - "directory. Select a different water model.", - waterFile.c_str(), watermodel_); + auto message = formatString( + "The topology file '%s' for the selected water " + "model '%s' can not be found in the force field " + "directory. Select a different water model.", + waterFile.c_str(), watermodel_); GMX_THROW(InconsistentInputError(message)); } } @@ -2311,14 +2348,14 @@ int pdb2gmx::run() gmx_fio_fclose(top_file); /* now merge all chains back together */ - natom = 0; - int nres = 0; + natom = 0; + int nres = 0; for (int i = 0; (i < numChains); i++) { natom += chains[i].pdba->nr; - nres += chains[i].pdba->nres; + nres += chains[i].pdba->nres; } - t_atoms *atoms; + t_atoms* atoms; snew(atoms, 1); init_t_atoms(atoms, natom, false); for (int i = 0; i < atoms->nres; i++) @@ -2334,14 +2371,14 @@ int pdb2gmx::run() { if (numChains > 1) { - printf("Including chain %d in system: %d atoms %d residues\n", - i+1, chains[i].pdba->nr, chains[i].pdba->nres); + printf("Including chain %d in system: %d atoms %d residues\n", i + 1, + chains[i].pdba->nr, chains[i].pdba->nres); } for (int j = 0; (j < chains[i].pdba->nr); j++) { - atoms->atom[k] = chains[i].pdba->atom[j]; + atoms->atom[k] = chains[i].pdba->atom[j]; atoms->atom[k].resind += l; /* l is processed nr of residues */ - atoms->atomname[k] = chains[i].pdba->atomname[j]; + atoms->atomname[k] = chains[i].pdba->atomname[j]; atoms->resinfo[atoms->atom[k].resind].chainid = chains[i].chainid; x.push_back(chains[i].x[j]); k++; @@ -2387,29 +2424,26 @@ int pdb2gmx::run() sfree(title); sfree(pdbx); printf("\t\t--------- PLEASE NOTE ------------\n"); - printf("You have successfully generated a topology from: %s.\n", - inputConfFile_.c_str()); + printf("You have successfully generated a topology from: %s.\n", inputConfFile_.c_str()); if (watermodel_ != nullptr) { - printf("The %s force field and the %s water model are used.\n", - ffname_, watermodel_); + printf("The %s force field and the %s water model are used.\n", ffname_, watermodel_); sfree(watermodel_); } else { - printf("The %s force field is used.\n", - ffname_); + printf("The %s force field is used.\n", ffname_); } printf("\t\t--------- ETON ESAELP ------------\n"); return 0; } -} // namespace +} // namespace -const char pdb2gmxInfo::name[] = "pdb2gmx"; +const char pdb2gmxInfo::name[] = "pdb2gmx"; const char pdb2gmxInfo::shortDescription[] = - "Convert coordinate files to topology and FF-compliant coordinate files"; + "Convert coordinate files to topology and FF-compliant coordinate files"; ICommandLineOptionsModulePointer pdb2gmxInfo::create() { return std::make_unique(); diff --git a/src/gromacs/gmxpreprocess/pdb2gmx.h b/src/gromacs/gmxpreprocess/pdb2gmx.h index 53bd185536..60b72ad31c 100644 --- a/src/gromacs/gmxpreprocess/pdb2gmx.h +++ b/src/gromacs/gmxpreprocess/pdb2gmx.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,10 +43,10 @@ namespace gmx class pdb2gmxInfo { - public: - static const char name[]; - static const char shortDescription[]; - static ICommandLineOptionsModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static ICommandLineOptionsModulePointer create(); }; } // namespace gmx diff --git a/src/gromacs/gmxpreprocess/pdb2top.cpp b/src/gromacs/gmxpreprocess/pdb2top.cpp index a4f4b528ff..e333b6ea9f 100644 --- a/src/gromacs/gmxpreprocess/pdb2top.cpp +++ b/src/gromacs/gmxpreprocess/pdb2top.cpp @@ -83,14 +83,14 @@ #include "resall.h" /* this must correspond to enum in pdb2top.h */ -const char *hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" }; +const char* hh[ehisNR] = { "HISD", "HISE", "HISH", "HIS1" }; -static int missing_atoms(const PreprocessResidue *rp, int resind, t_atoms *at, int i0, int i) +static int missing_atoms(const PreprocessResidue* rp, int resind, t_atoms* at, int i0, int i) { int nmiss = 0; for (int j = 0; j < rp->natom(); j++) { - const char *name = *(rp->atomname[j]); + const char* name = *(rp->atomname[j]); bool bFound = false; for (int k = i0; k < i; k++) { @@ -99,12 +99,15 @@ static int missing_atoms(const PreprocessResidue *rp, int resind, t_atoms *at, i if (!bFound) { nmiss++; - fprintf(stderr, "\nWARNING: " + fprintf(stderr, + "\nWARNING: " "atom %s is missing in residue %s %d in the pdb file\n", name, *(at->resinfo[resind].name), at->resinfo[resind].nr); if (name[0] == 'H' || name[0] == 'h') { - fprintf(stderr, " You might need to add atom %s to the hydrogen database of building block %s\n" + fprintf(stderr, + " You might need to add atom %s to the hydrogen database of " + "building block %s\n" " in the file %s.hdb (see the manual)\n", name, *(at->resinfo[resind].rtp), rp->filebase.c_str()); } @@ -126,16 +129,13 @@ bool is_int(double x) } ix = gmx::roundToInt(x); - return (fabs(x-ix) < tol); + return (fabs(x - ix) < tol); } -static void -choose_ff_impl(const char *ffsel, - char *forcefield, int ff_maxlen, - char *ffdir, int ffdir_maxlen) +static void choose_ff_impl(const char* ffsel, char* forcefield, int ff_maxlen, char* ffdir, int ffdir_maxlen) { std::vector ffdirs = fflib_enumerate_forcefields(); - const int nff = ssize(ffdirs); + const int nff = ssize(ffdirs); /* Replace with unix path separators */ #if DIR_SEPARATOR != '/' @@ -150,16 +150,15 @@ choose_ff_impl(const char *ffsel, ffs.reserve(ffdirs.size()); for (int i = 0; i < nff; ++i) { - ffs.push_back(gmx::stripSuffixIfPresent(ffdirs[i].name, - fflib_forcefield_dir_ext())); + ffs.push_back(gmx::stripSuffixIfPresent(ffdirs[i].name, fflib_forcefield_dir_ext())); } int sel; if (ffsel != nullptr) { - sel = -1; - int cwdsel = -1; - int nfound = 0; + sel = -1; + int cwdsel = -1; + int nfound = 0; for (int i = 0; i < nff; ++i) { if (ffs[i] == ffsel) @@ -187,23 +186,26 @@ choose_ff_impl(const char *ffsel, fprintf(stderr, "Force field '%s' occurs in %d places. pdb2gmx is using the one in the\n" "current directory. Use interactive selection (not the -ff option) if\n" - "you would prefer a different one.\n", ffsel, nfound); + "you would prefer a different one.\n", + ffsel, nfound); } else { std::string message = gmx::formatString( - "Force field '%s' occurs in %d places, but not in " - "the current directory.\n" - "Run without the -ff switch and select the force " - "field interactively.", ffsel, nfound); + "Force field '%s' occurs in %d places, but not in " + "the current directory.\n" + "Run without the -ff switch and select the force " + "field interactively.", + ffsel, nfound); GMX_THROW(gmx::InconsistentInputError(message)); } } else if (nfound == 0) { std::string message = gmx::formatString( - "Could not find force field '%s' in current directory, " - "install tree or GMXLIB path.", ffsel); + "Could not find force field '%s' in current directory, " + "install tree or GMXLIB path.", + ffsel); GMX_THROW(gmx::InconsistentInputError(message)); } } @@ -213,17 +215,15 @@ choose_ff_impl(const char *ffsel, desc.reserve(ffdirs.size()); for (int i = 0; i < nff; ++i) { - std::string docFileName( - gmx::Path::join(ffdirs[i].dir, ffdirs[i].name, - fflib_forcefield_doc())); + std::string docFileName(gmx::Path::join(ffdirs[i].dir, ffdirs[i].name, fflib_forcefield_doc())); // TODO: Just try to open the file with a method that does not // throw/bail out with a fatal error instead of multiple checks. if (gmx::File::exists(docFileName, gmx::File::returnFalseOnError)) { // TODO: Use a C++ API without such an intermediate/fixed-length buffer. - char buf[STRLEN]; + char buf[STRLEN]; /* We don't use fflib_open, because we don't want printf's */ - FILE *fp = gmx_ffopen(docFileName, "r"); + FILE* fp = gmx_ffopen(docFileName, "r"); get_a_line(fp, buf, STRLEN); gmx_ffclose(fp); desc.emplace_back(buf); @@ -240,10 +240,10 @@ choose_ff_impl(const char *ffsel, { for (int j = i + 1; j < nff; ++j) { - if (ffdirs[i].dir == ffdirs[j].dir && - ((desc[i][0] == '[' && desc[j][0] != '[') || - ((desc[i][0] == '[' || desc[j][0] != '[') && - gmx_strcasecmp(desc[i].c_str(), desc[j].c_str()) > 0))) + if (ffdirs[i].dir == ffdirs[j].dir + && ((desc[i][0] == '[' && desc[j][0] != '[') + || ((desc[i][0] == '[' || desc[j][0] != '[') + && gmx_strcasecmp(desc[i].c_str(), desc[j].c_str()) > 0))) { std::swap(ffdirs[i].name, ffdirs[j].name); std::swap(ffs[i], ffs[j]); @@ -255,7 +255,7 @@ choose_ff_impl(const char *ffsel, printf("\nSelect the Force Field:\n"); for (int i = 0; i < nff; ++i) { - if (i == 0 || ffdirs[i-1].dir != ffdirs[i].dir) + if (i == 0 || ffdirs[i - 1].dir != ffdirs[i].dir) { if (ffdirs[i].dir == ".") { @@ -266,13 +266,13 @@ choose_ff_impl(const char *ffsel, printf("From '%s':\n", ffdirs[i].dir.c_str()); } } - printf("%2d: %s\n", i+1, desc[i].c_str()); + printf("%2d: %s\n", i + 1, desc[i].c_str()); } sel = -1; // TODO: Add a C++ API for this. - char buf[STRLEN]; - char *pret; + char buf[STRLEN]; + char* pret; do { pret = fgets(buf, STRLEN, stdin); @@ -282,8 +282,7 @@ choose_ff_impl(const char *ffsel, sel = strtol(buf, nullptr, 10); sel--; } - } - while (pret == nullptr || (sel < 0) || (sel >= nff)); + } while (pret == nullptr || (sel < 0) || (sel >= nff)); /* Check for a current limitation of the fflib code. * It will always read from the first ff directory in the list. @@ -295,14 +294,14 @@ choose_ff_impl(const char *ffsel, if (ffs[i] == ffs[sel]) { std::string message = gmx::formatString( - "Can only select the first of multiple force " - "field entries with directory name '%s%s' in " - "the list. If you want to use the next entry, " - "run pdb2gmx in a different directory, set GMXLIB " - "to point to the desired force field first, and/or " - "rename or move the force field directory present " - "in the current working directory.", - ffs[sel].c_str(), fflib_forcefield_dir_ext()); + "Can only select the first of multiple force " + "field entries with directory name '%s%s' in " + "the list. If you want to use the next entry, " + "run pdb2gmx in a different directory, set GMXLIB " + "to point to the desired force field first, and/or " + "rename or move the force field directory present " + "in the current working directory.", + ffs[sel].c_str(), fflib_forcefield_dir_ext()); GMX_THROW(gmx::NotImplementedError(message)); } } @@ -314,9 +313,8 @@ choose_ff_impl(const char *ffsel, if (ffs[sel].length() >= static_cast(ff_maxlen)) { - std::string message = gmx::formatString( - "Length of force field name (%d) >= maxlen (%d)", - static_cast(ffs[sel].length()), ff_maxlen); + std::string message = gmx::formatString("Length of force field name (%d) >= maxlen (%d)", + static_cast(ffs[sel].length()), ff_maxlen); GMX_THROW(gmx::InvalidInputError(message)); } strcpy(forcefield, ffs[sel].c_str()); @@ -332,35 +330,30 @@ choose_ff_impl(const char *ffsel, } if (ffpath.length() >= static_cast(ffdir_maxlen)) { - std::string message = gmx::formatString( - "Length of force field dir (%d) >= maxlen (%d)", - static_cast(ffpath.length()), ffdir_maxlen); + std::string message = gmx::formatString("Length of force field dir (%d) >= maxlen (%d)", + static_cast(ffpath.length()), ffdir_maxlen); GMX_THROW(gmx::InvalidInputError(message)); } strcpy(ffdir, ffpath.c_str()); } -void -choose_ff(const char *ffsel, - char *forcefield, int ff_maxlen, - char *ffdir, int ffdir_maxlen) +void choose_ff(const char* ffsel, char* forcefield, int ff_maxlen, char* ffdir, int ffdir_maxlen) { try { choose_ff_impl(ffsel, forcefield, ff_maxlen, ffdir, ffdir_maxlen); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } -void choose_watermodel(const char *wmsel, const char *ffdir, - char **watermodel) +void choose_watermodel(const char* wmsel, const char* ffdir, char** watermodel) { - const char *fn_watermodels = "watermodels.dat"; - FILE *fp; + const char* fn_watermodels = "watermodels.dat"; + FILE* fp; char buf[STRLEN]; int nwm, sel, i; - char **model; - char *pret; + char** model; + char* pret; if (strcmp(wmsel, "none") == 0) { @@ -378,8 +371,7 @@ void choose_watermodel(const char *wmsel, const char *ffdir, std::string filename = gmx::Path::join(ffdir, fn_watermodels); if (!fflib_fexist(filename)) { - fprintf(stderr, "No file '%s' found, will not include a water model\n", - fn_watermodels); + fprintf(stderr, "No file '%s' found, will not include a water model\n", fn_watermodels); *watermodel = nullptr; return; @@ -391,13 +383,13 @@ void choose_watermodel(const char *wmsel, const char *ffdir, model = nullptr; while (get_a_line(fp, buf, STRLEN)) { - srenew(model, nwm+1); + srenew(model, nwm + 1); snew(model[nwm], STRLEN); sscanf(buf, "%s%n", model[nwm], &i); if (i > 0) { - ltrim(buf+i); - fprintf(stderr, "%2d: %s\n", nwm+1, buf+i); + ltrim(buf + i); + fprintf(stderr, "%2d: %s\n", nwm + 1, buf + i); nwm++; } else @@ -406,7 +398,7 @@ void choose_watermodel(const char *wmsel, const char *ffdir, } } gmx_ffclose(fp); - fprintf(stderr, "%2d: %s\n", nwm+1, "None"); + fprintf(stderr, "%2d: %s\n", nwm + 1, "None"); sel = -1; do @@ -418,8 +410,7 @@ void choose_watermodel(const char *wmsel, const char *ffdir, sel = strtol(buf, nullptr, 10); sel--; } - } - while (pret == nullptr || sel < 0 || sel > nwm); + } while (pret == nullptr || sel < 0 || sel > nwm); if (sel == nwm) { @@ -437,33 +428,32 @@ void choose_watermodel(const char *wmsel, const char *ffdir, sfree(model); } -static int name2type(t_atoms *at, int **cgnr, - gmx::ArrayRef usedPpResidues, ResidueType *rt) +static int name2type(t_atoms* at, int** cgnr, gmx::ArrayRef usedPpResidues, ResidueType* rt) { - int i, j, prevresind, i0, prevcg, cg, curcg; - char *name; - bool bNterm; - double qt; - int nmissat; + int i, j, prevresind, i0, prevcg, cg, curcg; + char* name; + bool bNterm; + double qt; + int nmissat; nmissat = 0; int resind = -1; - bNterm = false; - i0 = 0; + bNterm = false; + i0 = 0; snew(*cgnr, at->nr); - qt = 0; - curcg = 0; - cg = -1; + qt = 0; + curcg = 0; + cg = -1; for (i = 0; (i < at->nr); i++) { prevresind = resind; if (at->atom[i].resind != resind) { - resind = at->atom[i].resind; - bool bProt = rt->namedResidueHasType(*(at->resinfo[resind].name), "Protein"); - bNterm = bProt && (resind == 0); + resind = at->atom[i].resind; + bool bProt = rt->namedResidueHasType(*(at->resinfo[resind].name), "Protein"); + bNterm = bProt && (resind == 0); if (resind > 0) { nmissat += missing_atoms(&usedPpResidues[prevresind], prevresind, at, i0, i); @@ -483,7 +473,7 @@ static int name2type(t_atoms *at, int **cgnr, /* A charge group number -1 signals a separate charge group * for this atom. */ - if ( (cg == -1) || (cg != prevcg) || (resind != prevresind) ) + if ((cg == -1) || (cg != prevcg) || (resind != prevresind)) { curcg++; } @@ -508,7 +498,7 @@ static int name2type(t_atoms *at, int **cgnr, return nmissat; } -static void print_top_heavy_H(FILE *out, real mHmult) +static void print_top_heavy_H(FILE* out, real mHmult) { if (mHmult == 2.0) { @@ -520,18 +510,17 @@ static void print_top_heavy_H(FILE *out, real mHmult) } else if (mHmult != 1.0) { - fprintf(stderr, "WARNING: unsupported proton mass multiplier (%g) " - "in pdb2top\n", mHmult); + fprintf(stderr, + "WARNING: unsupported proton mass multiplier (%g) " + "in pdb2top\n", + mHmult); } } -void print_top_comment(FILE *out, - const char *filename, - const char *ffdir, - bool bITP) +void print_top_comment(FILE* out, const char* filename, const char* ffdir, bool bITP) { char ffdir_parent[STRLEN]; - char *p; + char* p; try { @@ -545,7 +534,7 @@ void print_top_comment(FILE *out, settings.linePrefix(";\t"); gmx::printBinaryInformation(&writer, gmx::getProgramContext(), settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR if (strchr(ffdir, '/') == nullptr) { @@ -553,13 +542,15 @@ void print_top_comment(FILE *out, } else if (ffdir[0] == '.') { - fprintf(out, ";\tForce field was read from current directory or a relative path - path added.\n;\n\n"); + fprintf(out, + ";\tForce field was read from current directory or a relative path - path " + "added.\n;\n\n"); } else { - strncpy(ffdir_parent, ffdir, STRLEN-1); - ffdir_parent[STRLEN-1] = '\0'; /*make sure it is 0-terminated even for long string*/ - p = strrchr(ffdir_parent, '/'); + strncpy(ffdir_parent, ffdir, STRLEN - 1); + ffdir_parent[STRLEN - 1] = '\0'; /*make sure it is 0-terminated even for long string*/ + p = strrchr(ffdir_parent, '/'); *p = '\0'; @@ -568,17 +559,18 @@ void print_top_comment(FILE *out, ";\t%s\n" ";\n" ";\tNote:\n" - ";\tThis might be a non-standard force field location. When you use this topology, the\n" + ";\tThis might be a non-standard force field location. When you use this topology, " + "the\n" ";\tforce field must either be present in the current directory, or the location\n" - ";\tspecified in the GMXLIB path variable or with the 'include' mdp file option.\n;\n\n", + ";\tspecified in the GMXLIB path variable or with the 'include' mdp file " + "option.\n;\n\n", ffdir_parent); } } -void print_top_header(FILE *out, const char *filename, - bool bITP, const char *ffdir, real mHmult) +void print_top_header(FILE* out, const char* filename, bool bITP, const char* ffdir, real mHmult) { - const char *p; + const char* p; print_top_comment(out, filename, ffdir, bITP); @@ -586,12 +578,12 @@ void print_top_header(FILE *out, const char *filename, fprintf(out, "; Include forcefield parameters\n"); p = strrchr(ffdir, '/'); - p = (ffdir[0] == '.' || p == nullptr) ? ffdir : p+1; + p = (ffdir[0] == '.' || p == nullptr) ? ffdir : p + 1; fprintf(out, "#include \"%s/%s\"\n\n", p, fflib_forcefield_itp()); } -static void print_top_posre(FILE *out, const char *pr) +static void print_top_posre(FILE* out, const char* pr) { fprintf(out, "; Include Position restraint file\n"); fprintf(out, "#ifdef POSRES\n"); @@ -599,15 +591,15 @@ static void print_top_posre(FILE *out, const char *pr) fprintf(out, "#endif\n\n"); } -static void print_top_water(FILE *out, const char *ffdir, const char *water) +static void print_top_water(FILE* out, const char* ffdir, const char* water) { - const char *p; + const char* p; char buf[STRLEN]; fprintf(out, "; Include water topology\n"); p = strrchr(ffdir, '/'); - p = (ffdir[0] == '.' || p == nullptr) ? ffdir : p+1; + p = (ffdir[0] == '.' || p == nullptr) ? ffdir : p + 1; fprintf(out, "#include \"%s/%s.itp\"\n", p, water); fprintf(out, "\n"); @@ -629,23 +621,25 @@ static void print_top_water(FILE *out, const char *ffdir, const char *water) } } -static void print_top_system(FILE *out, const char *title) +static void print_top_system(FILE* out, const char* title) { fprintf(out, "[ %s ]\n", dir2str(Directive::d_system)); fprintf(out, "; Name\n"); fprintf(out, "%s\n\n", title[0] ? title : "Protein"); } -void print_top_mols(FILE *out, - const char *title, const char *ffdir, const char *water, +void print_top_mols(FILE* out, + const char* title, + const char* ffdir, + const char* water, gmx::ArrayRef incls, - gmx::ArrayRef mols) + gmx::ArrayRef mols) { if (!incls.empty()) { fprintf(out, "; Include chain topologies\n"); - for (const auto &incl : incls) + for (const auto& incl : incls) { fprintf(out, "#include \"%s\"\n", gmx::Path::getFilename(incl).c_str()); } @@ -662,17 +656,24 @@ void print_top_mols(FILE *out, { fprintf(out, "[ %s ]\n", dir2str(Directive::d_molecules)); fprintf(out, "; %-15s %5s\n", "Compound", "#mols"); - for (const auto &mol : mols) + for (const auto& mol : mols) { fprintf(out, "%-15s %5d\n", mol.name.c_str(), mol.nr); } } } -void write_top(FILE *out, const char *pr, const char *molname, - t_atoms *at, bool bRTPresname, - int bts[], gmx::ArrayRef plist, t_excls excls[], - PreprocessingAtomTypes *atype, int *cgnr, int nrexcl) +void write_top(FILE* out, + const char* pr, + const char* molname, + t_atoms* at, + bool bRTPresname, + int bts[], + gmx::ArrayRef plist, + t_excls excls[], + PreprocessingAtomTypes* atype, + int* cgnr, + int nrexcl) /* NOTE: nrexcl is not the size of *excl! */ { if (at && atype && cgnr) @@ -682,24 +683,24 @@ void write_top(FILE *out, const char *pr, const char *molname, fprintf(out, "%-15s %5d\n\n", molname ? molname : "Protein", nrexcl); print_atoms(out, atype, at, cgnr, bRTPresname); - print_bondeds(out, at->nr, Directive::d_bonds, F_BONDS, bts[ebtsBONDS], plist); - print_bondeds(out, at->nr, Directive::d_constraints, F_CONSTR, 0, plist); - print_bondeds(out, at->nr, Directive::d_constraints, F_CONSTRNC, 0, plist); - print_bondeds(out, at->nr, Directive::d_pairs, F_LJ14, 0, plist); + print_bondeds(out, at->nr, Directive::d_bonds, F_BONDS, bts[ebtsBONDS], plist); + print_bondeds(out, at->nr, Directive::d_constraints, F_CONSTR, 0, plist); + print_bondeds(out, at->nr, Directive::d_constraints, F_CONSTRNC, 0, plist); + print_bondeds(out, at->nr, Directive::d_pairs, F_LJ14, 0, plist); print_excl(out, at->nr, excls); - print_bondeds(out, at->nr, Directive::d_angles, F_ANGLES, bts[ebtsANGLES], plist); - print_bondeds(out, at->nr, Directive::d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist); - print_bondeds(out, at->nr, Directive::d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist); - print_bondeds(out, at->nr, Directive::d_cmap, F_CMAP, bts[ebtsCMAP], plist); - print_bondeds(out, at->nr, Directive::d_polarization, F_POLARIZATION, 0, plist); - print_bondeds(out, at->nr, Directive::d_thole_polarization, F_THOLE_POL, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites2, F_VSITE2, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3FD, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3FAD, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3OUT, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites4, F_VSITE4FD, 0, plist); - print_bondeds(out, at->nr, Directive::d_vsites4, F_VSITE4FDN, 0, plist); + print_bondeds(out, at->nr, Directive::d_angles, F_ANGLES, bts[ebtsANGLES], plist); + print_bondeds(out, at->nr, Directive::d_dihedrals, F_PDIHS, bts[ebtsPDIHS], plist); + print_bondeds(out, at->nr, Directive::d_dihedrals, F_IDIHS, bts[ebtsIDIHS], plist); + print_bondeds(out, at->nr, Directive::d_cmap, F_CMAP, bts[ebtsCMAP], plist); + print_bondeds(out, at->nr, Directive::d_polarization, F_POLARIZATION, 0, plist); + print_bondeds(out, at->nr, Directive::d_thole_polarization, F_THOLE_POL, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites2, F_VSITE2, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3FD, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3FAD, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites3, F_VSITE3OUT, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites4, F_VSITE4FD, 0, plist); + print_bondeds(out, at->nr, Directive::d_vsites4, F_VSITE4FDN, 0, plist); if (pr) { @@ -709,18 +710,17 @@ void write_top(FILE *out, const char *pr, const char *molname, } - -static void do_ssbonds(InteractionsOfType *ps, t_atoms *atoms, - gmx::ArrayRef ssbonds, bool bAllowMissing) +static void do_ssbonds(InteractionsOfType* ps, + t_atoms* atoms, + gmx::ArrayRef ssbonds, + bool bAllowMissing) { - for (const auto &bond : ssbonds) + for (const auto& bond : ssbonds) { int ri = bond.firstResidue; int rj = bond.secondResidue; - int ai = search_res_atom(bond.firstAtom.c_str(), ri, atoms, - "special bond", bAllowMissing); - int aj = search_res_atom(bond.secondAtom.c_str(), rj, atoms, - "special bond", bAllowMissing); + int ai = search_res_atom(bond.firstAtom.c_str(), ri, atoms, "special bond", bAllowMissing); + int aj = search_res_atom(bond.secondAtom.c_str(), rj, atoms, "special bond", bAllowMissing); if ((ai == -1) || (aj == -1)) { gmx_fatal(FARGS, "Trying to make impossible special bond (%s-%s)!", @@ -730,13 +730,15 @@ static void do_ssbonds(InteractionsOfType *ps, t_atoms *atoms, } } -static void at2bonds(InteractionsOfType *psb, gmx::ArrayRef globalPatches, - t_atoms *atoms, - gmx::ArrayRef x, - real long_bond_dist, real short_bond_dist) +static void at2bonds(InteractionsOfType* psb, + gmx::ArrayRef globalPatches, + t_atoms* atoms, + gmx::ArrayRef x, + real long_bond_dist, + real short_bond_dist) { real long_bond_dist2, short_bond_dist2; - const char *ptr; + const char* ptr; long_bond_dist2 = gmx::square(long_bond_dist); short_bond_dist2 = gmx::square(short_bond_dist); @@ -755,53 +757,50 @@ static void at2bonds(InteractionsOfType *psb, gmx::ArrayRefnres) && (i < atoms->nr); resind++) { /* add bonds from list of bonded interactions */ - for (const auto &patch : globalPatches[resind].rb[ebtsBONDS].b) + for (const auto& patch : globalPatches[resind].rb[ebtsBONDS].b) { /* Unfortunately we can not issue errors or warnings * for missing atoms in bonds, as the hydrogens and terminal atoms * have not been added yet. */ - int ai = search_atom(patch.ai().c_str(), i, atoms, - ptr, TRUE); - int aj = search_atom(patch.aj().c_str(), i, atoms, - ptr, TRUE); + int ai = search_atom(patch.ai().c_str(), i, atoms, ptr, TRUE); + int aj = search_atom(patch.aj().c_str(), i, atoms, ptr, TRUE); if (ai != -1 && aj != -1) { real dist2 = distance2(x[ai], x[aj]); if (dist2 > long_bond_dist2) { - fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n", - ai+1, aj+1, std::sqrt(dist2)); + fprintf(stderr, "Warning: Long Bond (%d-%d = %g nm)\n", ai + 1, aj + 1, + std::sqrt(dist2)); } else if (dist2 < short_bond_dist2) { - fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n", - ai+1, aj+1, std::sqrt(dist2)); + fprintf(stderr, "Warning: Short Bond (%d-%d = %g nm)\n", ai + 1, aj + 1, + std::sqrt(dist2)); } add_param(psb, ai, aj, {}, patch.s.c_str()); } } /* add bonds from list of hacks (each added atom gets a bond) */ - while ( (i < atoms->nr) && (atoms->atom[i].resind == resind) ) + while ((i < atoms->nr) && (atoms->atom[i].resind == resind)) { - for (const auto &patch : globalPatches[resind].hack) + for (const auto& patch : globalPatches[resind].hack) { - if ( ( patch.tp > 0 || - patch.type() == MoleculePatchType::Add ) && - patch.a[0] == *(atoms->atomname[i])) + if ((patch.tp > 0 || patch.type() == MoleculePatchType::Add) + && patch.a[0] == *(atoms->atomname[i])) { switch (patch.tp) { - case 9 : /* COOH terminus */ - add_param(psb, i, i+1, {}, nullptr); /* C-O */ - add_param(psb, i, i+2, {}, nullptr); /* C-OA */ - add_param(psb, i+2, i+3, {}, nullptr); /* OA-H */ + case 9: /* COOH terminus */ + add_param(psb, i, i + 1, {}, nullptr); /* C-O */ + add_param(psb, i, i + 2, {}, nullptr); /* C-OA */ + add_param(psb, i + 2, i + 3, {}, nullptr); /* OA-H */ break; default: for (int k = 0; (k < patch.nr); k++) { - add_param(psb, i, i+k+1, {}, nullptr); + add_param(psb, i, i + k + 1, {}, nullptr); } } } @@ -812,9 +811,9 @@ static void at2bonds(InteractionsOfType *psb, gmx::ArrayRefsize() > 0) { /* Sort bonds */ - for (auto &bond : ps->interactionTypes) + for (auto& bond : ps->interactionTypes) { bond.sortAtomIds(); } @@ -843,11 +842,10 @@ static void clean_bonds(InteractionsOfType *ps) /* remove doubles, keep the first one always. */ int oldNumber = ps->size(); - for (auto parm = ps->interactionTypes.begin() + 1; parm != ps->interactionTypes.end(); ) + for (auto parm = ps->interactionTypes.begin() + 1; parm != ps->interactionTypes.end();) { auto prev = parm - 1; - if (parm->ai() == prev->ai() && - parm->aj() == prev->aj()) + if (parm->ai() == prev->ai() && parm->aj() == prev->aj()) { parm = ps->interactionTypes.erase(parm); } @@ -864,11 +862,11 @@ static void clean_bonds(InteractionsOfType *ps) } } -void print_sums(const t_atoms *atoms, bool bSystem) +void print_sums(const t_atoms* atoms, bool bSystem) { double m, qtot; int i; - const char *where; + const char* where; if (bSystem) { @@ -883,7 +881,7 @@ void print_sums(const t_atoms *atoms, bool bSystem) qtot = 0; for (i = 0; (i < atoms->nr); i++) { - m += atoms->atom[i].m; + m += atoms->atom[i].m; qtot += atoms->atom[i].q; } @@ -891,7 +889,7 @@ void print_sums(const t_atoms *atoms, bool bSystem) fprintf(stderr, "Total charge%s %.3f e\n", where, qtot); } -static void check_restp_type(const char *name, int t1, int t2) +static void check_restp_type(const char* name, int t1, int t2) { if (t1 != t2) { @@ -899,12 +897,15 @@ static void check_restp_type(const char *name, int t1, int t2) } } -static void check_restp_types(const PreprocessResidue &r0, const PreprocessResidue &r1) +static void check_restp_types(const PreprocessResidue& r0, const PreprocessResidue& r1) { - check_restp_type("all dihedrals", static_cast(r0.bKeepAllGeneratedDihedrals), static_cast(r1.bKeepAllGeneratedDihedrals)); + check_restp_type("all dihedrals", static_cast(r0.bKeepAllGeneratedDihedrals), + static_cast(r1.bKeepAllGeneratedDihedrals)); check_restp_type("nrexcl", r0.nrexcl, r1.nrexcl); - check_restp_type("HH14", static_cast(r0.bGenerateHH14Interactions), static_cast(r1.bGenerateHH14Interactions)); - check_restp_type("remove dihedrals", static_cast(r0.bRemoveDihedralIfWithImproper), static_cast(r1.bRemoveDihedralIfWithImproper)); + check_restp_type("HH14", static_cast(r0.bGenerateHH14Interactions), + static_cast(r1.bGenerateHH14Interactions)); + check_restp_type("remove dihedrals", static_cast(r0.bRemoveDihedralIfWithImproper), + static_cast(r1.bRemoveDihedralIfWithImproper)); for (int i = 0; i < ebtsNR; i++) { @@ -912,10 +913,10 @@ static void check_restp_types(const PreprocessResidue &r0, const PreprocessResid } } -static void add_atom_to_restp(PreprocessResidue *usedPpResidues, - t_symtab *symtab, - int at_start, - const MoleculePatch *patch) +static void add_atom_to_restp(PreprocessResidue* usedPpResidues, + t_symtab* symtab, + int at_start, + const MoleculePatch* patch) { /* now add them */ for (int k = 0; k < patch->nr; k++) @@ -924,7 +925,7 @@ static void add_atom_to_restp(PreprocessResidue *usedPpResidues, std::string buf = patch->nname; if (patch->nr > 1) { - buf.append(gmx::formatString("%d", k+1)); + buf.append(gmx::formatString("%d", k + 1)); } usedPpResidues->atomname.insert(usedPpResidues->atomname.begin() + at_start + 1 + k, put_symtab(symtab, buf.c_str())); @@ -935,25 +936,27 @@ static void add_atom_to_restp(PreprocessResidue *usedPpResidues, } else { - usedPpResidues->cgnr.insert(usedPpResidues->cgnr.begin() + at_start + 1 + k, usedPpResidues->cgnr[at_start]); + usedPpResidues->cgnr.insert(usedPpResidues->cgnr.begin() + at_start + 1 + k, + usedPpResidues->cgnr[at_start]); } } } -void get_hackblocks_rtp(std::vector *globalPatches, - std::vector *usedPpResidues, +void get_hackblocks_rtp(std::vector* globalPatches, + std::vector* usedPpResidues, gmx::ArrayRef rtpFFDB, - int nres, t_resinfo *resinfo, - int nterpairs, - t_symtab *symtab, - gmx::ArrayRef ntdb, - gmx::ArrayRef ctdb, - gmx::ArrayRef rn, - gmx::ArrayRef rc, - bool bAllowMissing) + int nres, + t_resinfo* resinfo, + int nterpairs, + t_symtab* symtab, + gmx::ArrayRef ntdb, + gmx::ArrayRef ctdb, + gmx::ArrayRef rn, + gmx::ArrayRef rc, + bool bAllowMissing) { - char *key; - bool bRM; + char* key; + bool bRM; globalPatches->resize(nres); usedPpResidues->clear(); @@ -983,9 +986,9 @@ void get_hackblocks_rtp(std::vector *globalPatches, key = *resinfo[i].rtp; resinfo[i].rtp = put_symtab(symtab, searchResidueDatabase(key, rtpFFDB).c_str()); - auto res = getDatabaseEntry(*resinfo[i].rtp, rtpFFDB); + auto res = getDatabaseEntry(*resinfo[i].rtp, rtpFFDB); usedPpResidues->push_back(PreprocessResidue()); - PreprocessResidue *newentry = &usedPpResidues->back(); + PreprocessResidue* newentry = &usedPpResidues->back(); copyPreprocessResidues(*res, newentry, symtab); /* Check that we do not have different bonded types in one molecule */ @@ -1009,10 +1012,13 @@ void get_hackblocks_rtp(std::vector *globalPatches, } bRM = mergeBondedInteractionList(res->rb, globalPatches->at(i).rb, tern >= 0, terc >= 0); - if (bRM && ((tern >= 0 && ntdb[tern] == nullptr) || - (terc >= 0 && ctdb[terc] == nullptr))) + if (bRM && ((tern >= 0 && ntdb[tern] == nullptr) || (terc >= 0 && ctdb[terc] == nullptr))) { - const char *errString = "There is a dangling bond at at least one of the terminal ends and the force field does not provide terminal entries or files. Fix your terminal residues so that they match the residue database (.rtp) entries, or provide terminal database entries (.tdb)."; + const char* errString = + "There is a dangling bond at at least one of the terminal ends and the force " + "field does not provide terminal entries or files. Fix your terminal " + "residues so that they match the residue database (.rtp) entries, or provide " + "terminal database entries (.tdb)."; if (bAllowMissing) { fprintf(stderr, "%s\n", errString); @@ -1022,10 +1028,12 @@ void get_hackblocks_rtp(std::vector *globalPatches, gmx_fatal(FARGS, "%s", errString); } } - else if (bRM && ((tern >= 0 && ntdb[tern]->nhack() == 0) || - (terc >= 0 && ctdb[terc]->nhack() == 0))) + else if (bRM && ((tern >= 0 && ntdb[tern]->nhack() == 0) || (terc >= 0 && ctdb[terc]->nhack() == 0))) { - const char *errString = "There is a dangling bond at at least one of the terminal ends. Fix your coordinate file, add a new terminal database entry (.tdb), or select the proper existing terminal entry."; + const char* errString = + "There is a dangling bond at at least one of the terminal ends. Fix your " + "coordinate file, add a new terminal database entry (.tdb), or select the " + "proper existing terminal entry."; if (bAllowMissing) { fprintf(stderr, "%s\n", errString); @@ -1041,26 +1049,21 @@ void get_hackblocks_rtp(std::vector *globalPatches, i.e. add's and deletes from termini database will be added to/removed from residue topology we'll do this on one big dirty loop, so it won't make easy reading! */ - for (auto modifiedResidue = globalPatches->begin(); - modifiedResidue != globalPatches->end(); + for (auto modifiedResidue = globalPatches->begin(); modifiedResidue != globalPatches->end(); modifiedResidue++) { - const int pos = std::distance(globalPatches->begin(), modifiedResidue); - PreprocessResidue *posres = &usedPpResidues->at(pos); - for (auto patch = modifiedResidue->hack.begin(); - patch != modifiedResidue->hack.end(); - patch++) + const int pos = std::distance(globalPatches->begin(), modifiedResidue); + PreprocessResidue* posres = &usedPpResidues->at(pos); + for (auto patch = modifiedResidue->hack.begin(); patch != modifiedResidue->hack.end(); patch++) { if (patch->nr != 0) { /* find atom in restp */ - auto found = - std::find_if(posres->atomname.begin(), - posres->atomname.end(), - [&patch](char **name) - { return (patch->oname.empty() && - patch->a[0] == *name) || - (patch->oname == *name); }); + auto found = std::find_if(posres->atomname.begin(), posres->atomname.end(), + [&patch](char** name) { + return (patch->oname.empty() && patch->a[0] == *name) + || (patch->oname == *name); + }); if (found == posres->atomname.end()) { @@ -1076,9 +1079,8 @@ void get_hackblocks_rtp(std::vector *globalPatches, gmx_fatal(FARGS, "atom %s not found in buiding block %d%s " "while combining tdb and rtp", - patch->oname.empty() ? - patch->a[0].c_str() : patch->oname.c_str(), - pos+1, *resinfo[pos].rtp); + patch->oname.empty() ? patch->a[0].c_str() : patch->oname.c_str(), + pos + 1, *resinfo[pos].rtp); } } else @@ -1093,7 +1095,7 @@ void get_hackblocks_rtp(std::vector *globalPatches, break; } case MoleculePatchType::Delete: - { /* we're deleting */ + { /* we're deleting */ posres->atom.erase(posres->atom.begin() + l); posres->atomname.erase(posres->atomname.begin() + l); posres->cgnr.erase(posres->cgnr.begin() + l); @@ -1102,8 +1104,8 @@ void get_hackblocks_rtp(std::vector *globalPatches, case MoleculePatchType::Replace: { /* we're replacing */ - posres->atom[l] = patch->atom.back(); - posres->atomname[l] = put_symtab(symtab, patch->nname.c_str()); + posres->atom[l] = patch->atom.back(); + posres->atomname[l] = put_symtab(symtab, patch->nname.c_str()); if (patch->cgnr != NOTSET) { posres->cgnr[l] = patch->cgnr; @@ -1117,7 +1119,7 @@ void get_hackblocks_rtp(std::vector *globalPatches, } } -static bool atomname_cmp_nr(const char *anm, const MoleculePatch *patch, int *nr) +static bool atomname_cmp_nr(const char* anm, const MoleculePatch* patch, int* nr) { if (patch->nr == 1) @@ -1128,9 +1130,9 @@ static bool atomname_cmp_nr(const char *anm, const MoleculePatch *patch, int *nr } else { - if (isdigit(anm[strlen(anm)-1])) + if (isdigit(anm[strlen(anm) - 1])) { - *nr = anm[strlen(anm)-1] - '0'; + *nr = anm[strlen(anm) - 1] - '0'; } else { @@ -1142,46 +1144,40 @@ static bool atomname_cmp_nr(const char *anm, const MoleculePatch *patch, int *nr } else { - return (strlen(anm) == patch->nname.length() + 1 && - gmx_strncasecmp(anm, patch->nname.c_str(), patch->nname.length()) == 0); + return (strlen(anm) == patch->nname.length() + 1 + && gmx_strncasecmp(anm, patch->nname.c_str(), patch->nname.length()) == 0); } } } -static bool match_atomnames_with_rtp_atom(t_atoms *pdba, +static bool match_atomnames_with_rtp_atom(t_atoms* pdba, gmx::ArrayRef x, - t_symtab *symtab, + t_symtab* symtab, int atind, - PreprocessResidue *localPpResidue, - const MoleculePatchDatabase &singlePatch, + PreprocessResidue* localPpResidue, + const MoleculePatchDatabase& singlePatch, bool bVerbose) { - int resnr; - char *oldnm; - int anmnr; - bool bDeleted; + int resnr; + char* oldnm; + int anmnr; + bool bDeleted; oldnm = *pdba->atomname[atind]; resnr = pdba->resinfo[pdba->atom[atind].resind].nr; bDeleted = FALSE; - for (auto patch = singlePatch.hack.begin(); - patch != singlePatch.hack.end(); - patch++) + for (auto patch = singlePatch.hack.begin(); patch != singlePatch.hack.end(); patch++) { - if (patch->type() == MoleculePatchType::Replace && - gmx::equalCaseInsensitive(oldnm, patch->oname)) + if (patch->type() == MoleculePatchType::Replace && gmx::equalCaseInsensitive(oldnm, patch->oname)) { /* This is a replace entry. */ /* Check if we are not replacing a replaced atom. */ bool bReplaceReplace = false; - for (auto selfPatch = singlePatch.hack.begin(); - selfPatch != singlePatch.hack.end(); - selfPatch++) + for (auto selfPatch = singlePatch.hack.begin(); selfPatch != singlePatch.hack.end(); selfPatch++) { - if (patch != selfPatch && - selfPatch->type() == MoleculePatchType::Replace && - gmx::equalCaseInsensitive(selfPatch->nname, patch->oname)) + if (patch != selfPatch && selfPatch->type() == MoleculePatchType::Replace + && gmx::equalCaseInsensitive(selfPatch->nname, patch->oname)) { /* The replace in patch replaces an atom that * was already replaced in selfPatch, we do not want @@ -1198,10 +1194,9 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, /* This atom still has the old name, rename it */ std::string newnm = patch->nname; - auto found = std::find_if(localPpResidue->atomname.begin(), - localPpResidue->atomname.end(), - [&newnm](char** name) - { return gmx::equalCaseInsensitive(newnm, *name); }); + auto found = std::find_if( + localPpResidue->atomname.begin(), localPpResidue->atomname.end(), + [&newnm](char** name) { return gmx::equalCaseInsensitive(newnm, *name); }); if (found == localPpResidue->atomname.end()) { /* The new name is not present in the rtp. @@ -1213,13 +1208,12 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, */ bool bFoundInAdd = false; for (auto rtpModification = singlePatch.hack.begin(); - rtpModification != singlePatch.hack.end(); - rtpModification++) + rtpModification != singlePatch.hack.end(); rtpModification++) { int k = std::distance(localPpResidue->atomname.begin(), found); std::string start_at; - if (rtpModification->type() == MoleculePatchType::Add && - atomname_cmp_nr(newnm.c_str(), &(*rtpModification), &anmnr)) + if (rtpModification->type() == MoleculePatchType::Add + && atomname_cmp_nr(newnm.c_str(), &(*rtpModification), &anmnr)) { if (anmnr <= 1) { @@ -1227,15 +1221,19 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, } else { - start_at = gmx::formatString("%s%d", singlePatch.hack[k].nname.c_str(), anmnr-1); + start_at = gmx::formatString("%s%d", singlePatch.hack[k].nname.c_str(), + anmnr - 1); } - auto found2 = std::find_if(localPpResidue->atomname.begin(), - localPpResidue->atomname.end(), - [&start_at](char **name) - { return gmx::equalCaseInsensitive(start_at, *name); }); + auto found2 = + std::find_if(localPpResidue->atomname.begin(), + localPpResidue->atomname.end(), [&start_at](char** name) { + return gmx::equalCaseInsensitive(start_at, *name); + }); if (found2 == localPpResidue->atomname.end()) { - gmx_fatal(FARGS, "Could not find atom '%s' in residue building block '%s' to add atom '%s' to", + gmx_fatal(FARGS, + "Could not find atom '%s' in residue building block '%s' to " + "add atom '%s' to", start_at.c_str(), localPpResidue->resname.c_str(), newnm.c_str()); } /* We can add the atom after atom start_nr */ @@ -1249,30 +1247,32 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, if (!bFoundInAdd) { - gmx_fatal(FARGS, "Could not find an 'add' entry for atom named '%s' corresponding to the 'replace' entry from atom name '%s' to '%s' for tdb or hdb database of residue type '%s'", - newnm.c_str(), - patch->oname.c_str(), patch->nname.c_str(), + gmx_fatal(FARGS, + "Could not find an 'add' entry for atom named '%s' corresponding to " + "the 'replace' entry from atom name '%s' to '%s' for tdb or hdb " + "database of residue type '%s'", + newnm.c_str(), patch->oname.c_str(), patch->nname.c_str(), localPpResidue->resname.c_str()); } } if (bVerbose) { - printf("Renaming atom '%s' in residue '%s' %d to '%s'\n", - oldnm, localPpResidue->resname.c_str(), resnr, newnm.c_str()); + printf("Renaming atom '%s' in residue '%s' %d to '%s'\n", oldnm, + localPpResidue->resname.c_str(), resnr, newnm.c_str()); } /* Rename the atom in pdba */ pdba->atomname[atind] = put_symtab(symtab, newnm.c_str()); } - else if (patch->type() == MoleculePatchType::Delete && - gmx::equalCaseInsensitive(oldnm, patch->oname)) + else if (patch->type() == MoleculePatchType::Delete + && gmx::equalCaseInsensitive(oldnm, patch->oname)) { /* This is a delete entry, check if this atom is present * in the rtp entry of this residue. */ - auto found3 = std::find_if(localPpResidue->atomname.begin(), localPpResidue->atomname.end(), - [&oldnm](char **name) - { return gmx::equalCaseInsensitive(oldnm, *name); }); + auto found3 = std::find_if( + localPpResidue->atomname.begin(), localPpResidue->atomname.end(), + [&oldnm](char** name) { return gmx::equalCaseInsensitive(oldnm, *name); }); if (found3 == localPpResidue->atomname.end()) { /* This atom is not present in the rtp entry, @@ -1280,18 +1280,18 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, */ if (bVerbose) { - printf("Deleting atom '%s' in residue '%s' %d\n", - oldnm, localPpResidue->resname.c_str(), resnr); + printf("Deleting atom '%s' in residue '%s' %d\n", oldnm, + localPpResidue->resname.c_str(), resnr); } /* We should free the atom name, * but it might be used multiple times in the symtab. * sfree(pdba->atomname[atind]); */ - for (int k = atind+1; k < pdba->nr; k++) + for (int k = atind + 1; k < pdba->nr; k++) { - pdba->atom[k-1] = pdba->atom[k]; - pdba->atomname[k-1] = pdba->atomname[k]; - copy_rvec(x[k], x[k-1]); + pdba->atom[k - 1] = pdba->atom[k]; + pdba->atomname[k - 1] = pdba->atomname[k]; + copy_rvec(x[k], x[k - 1]); } pdba->nr--; bDeleted = true; @@ -1304,24 +1304,23 @@ static bool match_atomnames_with_rtp_atom(t_atoms *pdba, void match_atomnames_with_rtp(gmx::ArrayRef usedPpResidues, gmx::ArrayRef globalPatches, - t_atoms *pdba, - t_symtab *symtab, + t_atoms* pdba, + t_symtab* symtab, gmx::ArrayRef x, bool bVerbose) { for (int i = 0; i < pdba->nr; i++) { - const char *oldnm = *pdba->atomname[i]; - PreprocessResidue *localPpResidue = &usedPpResidues[pdba->atom[i].resind]; - auto found = std::find_if(localPpResidue->atomname.begin(), localPpResidue->atomname.end(), - [&oldnm](char **name) - { return gmx::equalCaseInsensitive(oldnm, *name); }); + const char* oldnm = *pdba->atomname[i]; + PreprocessResidue* localPpResidue = &usedPpResidues[pdba->atom[i].resind]; + auto found = std::find_if( + localPpResidue->atomname.begin(), localPpResidue->atomname.end(), + [&oldnm](char** name) { return gmx::equalCaseInsensitive(oldnm, *name); }); if (found == localPpResidue->atomname.end()) { /* Not found yet, check if we have to rename this atom */ - if (match_atomnames_with_rtp_atom(pdba, x, symtab, i, - localPpResidue, globalPatches[pdba->atom[i].resind], - bVerbose)) + if (match_atomnames_with_rtp_atom(pdba, x, symtab, i, localPpResidue, + globalPatches[pdba->atom[i].resind], bVerbose)) { /* We deleted this atom, decrease the atom counter by 1. */ i--; @@ -1331,11 +1330,11 @@ void match_atomnames_with_rtp(gmx::ArrayRef usedPpResidue } #define NUM_CMAP_ATOMS 5 -static void gen_cmap(InteractionsOfType *psb, gmx::ArrayRef usedPpResidues, t_atoms *atoms) +static void gen_cmap(InteractionsOfType* psb, gmx::ArrayRef usedPpResidues, t_atoms* atoms) { int residx; - const char *ptr; - t_resinfo *resinfo = atoms->resinfo; + const char* ptr; + t_resinfo* resinfo = atoms->resinfo; int nres = atoms->nres; int cmap_atomid[NUM_CMAP_ATOMS]; int cmap_chainnum = -1; @@ -1359,7 +1358,7 @@ static void gen_cmap(InteractionsOfType *psb, gmx::ArrayRefatom[i].resind < residx+1) + while (atoms->atom[i].resind < residx + 1) { i++; } @@ -1434,63 +1432,68 @@ static void gen_cmap(InteractionsOfType *psb, gmx::ArrayRef *x, PreprocessingAtomTypes *atype, t_symtab *tab, +void pdb2top(FILE* top_file, + const char* posre_fn, + const char* molname, + t_atoms* atoms, + std::vector* x, + PreprocessingAtomTypes* atype, + t_symtab* tab, gmx::ArrayRef rtpFFDB, - gmx::ArrayRef usedPpResidues, - gmx::ArrayRef globalPatches, - bool bAllowMissing, - bool bVsites, bool bVsiteAromatics, - const char *ffdir, - real mHmult, - gmx::ArrayRef ssbonds, - real long_bond_dist, real short_bond_dist, - bool bDeuterate, bool bChargeGroups, bool bCmap, - bool bRenumRes, bool bRTPresname) + gmx::ArrayRef usedPpResidues, + gmx::ArrayRef globalPatches, + bool bAllowMissing, + bool bVsites, + bool bVsiteAromatics, + const char* ffdir, + real mHmult, + gmx::ArrayRef ssbonds, + real long_bond_dist, + real short_bond_dist, + bool bDeuterate, + bool bChargeGroups, + bool bCmap, + bool bRenumRes, + bool bRTPresname) { - std::array plist; - t_excls *excls; - int *cgnr; - int *vsite_type; - int i, nmissat; - int bts[ebtsNR]; + std::array plist; + t_excls* excls; + int* cgnr; + int* vsite_type; + int i, nmissat; + int bts[ebtsNR]; ResidueType rt; /* Make bonds */ - at2bonds(&(plist[F_BONDS]), globalPatches, - atoms, *x, - long_bond_dist, short_bond_dist); + at2bonds(&(plist[F_BONDS]), globalPatches, atoms, *x, long_bond_dist, short_bond_dist); /* specbonds: disulphide bonds & heme-his */ - do_ssbonds(&(plist[F_BONDS]), - atoms, ssbonds, - bAllowMissing); + do_ssbonds(&(plist[F_BONDS]), atoms, ssbonds, bAllowMissing); nmissat = name2type(atoms, &cgnr, usedPpResidues, &rt); if (nmissat) { if (bAllowMissing) { - fprintf(stderr, "There were %d missing atoms in molecule %s\n", - nmissat, molname); + fprintf(stderr, "There were %d missing atoms in molecule %s\n", nmissat, molname); } else { - gmx_fatal(FARGS, "There were %d missing atoms in molecule %s, if you want to use this incomplete topology anyhow, use the option -missing", + gmx_fatal(FARGS, + "There were %d missing atoms in molecule %s, if you want to use this " + "incomplete topology anyhow, use the option -missing", nmissat, molname); } } @@ -1507,13 +1510,13 @@ void pdb2top(FILE *top_file, const char *posre_fn, const char *molname, { if (bVsiteAromatics) { - fprintf(stdout, "The conversion of aromatic rings into virtual sites is deprecated " + fprintf(stdout, + "The conversion of aromatic rings into virtual sites is deprecated " "and may be removed in a future version of GROMACS"); } /* determine which atoms will be vsites and add dummy masses also renumber atom numbers in plist[0..F_NRE]! */ - do_vsites(rtpFFDB, atype, atoms, tab, x, plist, - &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir); + do_vsites(rtpFFDB, atype, atoms, tab, x, plist, &vsite_type, &cgnr, mHmult, bVsiteAromatics, ffdir); } /* Make Angles and Dihedrals */ @@ -1527,8 +1530,7 @@ void pdb2top(FILE *top_file, const char *posre_fn, const char *molname, gen_cmap(&(plist[F_CMAP]), usedPpResidues, atoms); if (plist[F_CMAP].size() > 0) { - fprintf(stderr, "There are %4zu cmap torsion pairs\n", - plist[F_CMAP].size()); + fprintf(stderr, "There are %4zu cmap torsion pairs\n", plist[F_CMAP].size()); } } @@ -1547,13 +1549,9 @@ void pdb2top(FILE *top_file, const char *posre_fn, const char *molname, " %4zu pairs, %4zu bonds and %4zu virtual sites\n", plist[F_PDIHS].size(), plist[F_IDIHS].size(), plist[F_ANGLES].size(), plist[F_LJ14].size(), plist[F_BONDS].size(), - plist[F_VSITE2].size() + - plist[F_VSITE3].size() + - plist[F_VSITE3FD].size() + - plist[F_VSITE3FAD].size() + - plist[F_VSITE3OUT].size() + - plist[F_VSITE4FD].size() + - plist[F_VSITE4FDN].size() ); + plist[F_VSITE2].size() + plist[F_VSITE3].size() + plist[F_VSITE3FD].size() + + plist[F_VSITE3FAD].size() + plist[F_VSITE3OUT].size() + + plist[F_VSITE4FD].size() + plist[F_VSITE4FDN].size()); print_sums(atoms, FALSE); @@ -1581,9 +1579,8 @@ void pdb2top(FILE *top_file, const char *posre_fn, const char *molname, { bts[i] = usedPpResidues[0].rb[i].type; } - write_top(top_file, posre_fn, molname, - atoms, bRTPresname, - bts, plist, excls, atype, cgnr, usedPpResidues[0].nrexcl); + write_top(top_file, posre_fn, molname, atoms, bRTPresname, bts, plist, excls, atype, cgnr, + usedPpResidues[0].nrexcl); } diff --git a/src/gromacs/gmxpreprocess/pdb2top.h b/src/gromacs/gmxpreprocess/pdb2top.h index d350688a04..85538e3ea7 100644 --- a/src/gromacs/gmxpreprocess/pdb2top.h +++ b/src/gromacs/gmxpreprocess/pdb2top.h @@ -57,83 +57,104 @@ struct DisulfideBond; struct t_symtab; /* this *MUST* correspond to array in pdb2top.c */ -enum { - ehisA, ehisB, ehisH, ehis1, ehisNR +enum +{ + ehisA, + ehisB, + ehisH, + ehis1, + ehisNR }; -extern const char *hh[ehisNR]; +extern const char* hh[ehisNR]; -void choose_ff(const char *ffsel, - char *forcefield, int ff_maxlen, - char *ffdir, int ffdir_maxlen); +void choose_ff(const char* ffsel, char* forcefield, int ff_maxlen, char* ffdir, int ffdir_maxlen); /* Find force fields in the current and libdirs and choose an ff. * If ffsel!=NULL: search for ffsel. * If ffsel==NULL: interactive selection. */ -void choose_watermodel(const char *wmsel, const char *ffdir, - char **watermodel); +void choose_watermodel(const char* wmsel, const char* ffdir, char** watermodel); /* Choose, possibly interactively, which water model to include, * based on the wmsel command line option choice and watermodels.dat * in ffdir. */ -void get_hackblocks_rtp(std::vector *globalPatches, - std::vector *usedPpResidues, +void get_hackblocks_rtp(std::vector* globalPatches, + std::vector* usedPpResidues, gmx::ArrayRef rtpFFDB, - int nres, t_resinfo *resinfo, - int nterpairs, - t_symtab *symtab, - gmx::ArrayRef ntdb, - gmx::ArrayRef ctdb, - gmx::ArrayRef rn, - gmx::ArrayRef rc, - bool bAllowMissing); + int nres, + t_resinfo* resinfo, + int nterpairs, + t_symtab* symtab, + gmx::ArrayRef ntdb, + gmx::ArrayRef ctdb, + gmx::ArrayRef rn, + gmx::ArrayRef rc, + bool bAllowMissing); /* Get the database entries for the nres residues in resinfo * and store them in restp and hb. */ -void match_atomnames_with_rtp(gmx::ArrayRef usedPpResidues, +void match_atomnames_with_rtp(gmx::ArrayRef usedPpResidues, gmx::ArrayRef globalPatches, - t_atoms *pdba, t_symtab *symtab, gmx::ArrayRef x, - bool bVerbose); + t_atoms* pdba, + t_symtab* symtab, + gmx::ArrayRef x, + bool bVerbose); /* Check if atom in pdba need to be deleted of renamed due to tdb or hdb. * If renaming involves atoms added wrt to the rtp database, * add these atoms to restp. */ -void print_top_comment(FILE *out, const char *filename, const char *ffdir, bool bITP); +void print_top_comment(FILE* out, const char* filename, const char* ffdir, bool bITP); -void print_top_header(FILE *out, const char *filename, bool bITP, - const char *ffdir, real mHmult); +void print_top_header(FILE* out, const char* filename, bool bITP, const char* ffdir, real mHmult); -void print_top_mols(FILE *out, - const char *title, const char *ffdir, const char *water, +void print_top_mols(FILE* out, + const char* title, + const char* ffdir, + const char* water, gmx::ArrayRef incls, - gmx::ArrayRef mols); - -void write_top(FILE *out, const char *pr, const char *molname, - t_atoms *at, bool bRTPresname, - int bts[], gmx::ArrayRef plist, t_excls excls[], - PreprocessingAtomTypes *atype, int *cgnr, int nrexcl); + gmx::ArrayRef mols); + +void write_top(FILE* out, + const char* pr, + const char* molname, + t_atoms* at, + bool bRTPresname, + int bts[], + gmx::ArrayRef plist, + t_excls excls[], + PreprocessingAtomTypes* atype, + int* cgnr, + int nrexcl); /* NOTE: nrexcl is not the size of *excl! */ -void pdb2top(FILE *top_file, const char *posre_fn, const char *molname, - t_atoms *atoms, - std::vector *x, - PreprocessingAtomTypes *atype, t_symtab *tab, +void pdb2top(FILE* top_file, + const char* posre_fn, + const char* molname, + t_atoms* atoms, + std::vector* x, + PreprocessingAtomTypes* atype, + t_symtab* tab, gmx::ArrayRef rtpFFDB, - gmx::ArrayRef usedPpResidues, - gmx::ArrayRef globalPatches, - bool bAllowMissing, - bool bVsites, bool bVsiteAromatics, - const char *ffdir, - real mHmult, - gmx::ArrayRef ssbonds, - real long_bond_dist, real short_bond_dist, - bool bDeuterate, bool bChargeGroups, bool bCmap, - bool bRenumRes, bool bRTPresname); + gmx::ArrayRef usedPpResidues, + gmx::ArrayRef globalPatches, + bool bAllowMissing, + bool bVsites, + bool bVsiteAromatics, + const char* ffdir, + real mHmult, + gmx::ArrayRef ssbonds, + real long_bond_dist, + real short_bond_dist, + bool bDeuterate, + bool bChargeGroups, + bool bCmap, + bool bRenumRes, + bool bRTPresname); /* Create a topology ! */ -void print_sums(const t_atoms *atoms, bool bSystem); +void print_sums(const t_atoms* atoms, bool bSystem); #endif diff --git a/src/gromacs/gmxpreprocess/pgutil.cpp b/src/gromacs/gmxpreprocess/pgutil.cpp index 1693ca4ef4..1584f9f0be 100644 --- a/src/gromacs/gmxpreprocess/pgutil.cpp +++ b/src/gromacs/gmxpreprocess/pgutil.cpp @@ -48,10 +48,14 @@ #include "gromacs/utility/snprintf.h" #define BUFSIZE 1024 -static void atom_not_found(int fatal_errno, const char *file, int line, - const char *atomname, int resind, - const char *resname, - const char *bondtype, bool bAllowMissing) +static void atom_not_found(int fatal_errno, + const char* file, + int line, + const char* atomname, + int resind, + const char* resname, + const char* bondtype, + bool bAllowMissing) { char message_buffer[BUFSIZE]; if (strcmp(bondtype, "check") != 0) @@ -64,7 +68,7 @@ static void atom_not_found(int fatal_errno, const char *file, int line, "an interaction of type %s in that entry is not found in the\n" "input file. Perhaps your atom and/or residue naming needs to be\n" "fixed.\n", - resind+1, resname, atomname, bondtype); + resind + 1, resname, atomname, bondtype); } else { @@ -73,7 +77,7 @@ static void atom_not_found(int fatal_errno, const char *file, int line, "to an entry in the topology database, but the atom %s used in\n" "that entry is not found in the input file. Perhaps your atom\n" "and/or residue naming needs to be fixed.\n", - resind+1, resname, atomname); + resind + 1, resname, atomname); } if (bAllowMissing) { @@ -86,15 +90,13 @@ static void atom_not_found(int fatal_errno, const char *file, int line, } } -int search_atom(const char *type, int start, - const t_atoms *atoms, - const char *bondtype, bool bAllowMissing) +int search_atom(const char* type, int start, const t_atoms* atoms, const char* bondtype, bool bAllowMissing) { - int i, resind = -1; - bool bPrevious, bNext; - int natoms = atoms->nr; - t_atom *at = atoms->atom; - char ** const * anm = atoms->atomname; + int i, resind = -1; + bool bPrevious, bNext; + int natoms = atoms->nr; + t_atom* at = atoms->atom; + char** const* anm = atoms->atomname; bPrevious = (strchr(type, '-') != nullptr); bNext = (strchr(type, '+') != nullptr); @@ -123,9 +125,10 @@ int search_atom(const char *type, int start, return i; } } - if (!(bNext && at[start].resind == at[natoms-1].resind)) + if (!(bNext && at[start].resind == at[natoms - 1].resind)) { - atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing); + atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, + bAllowMissing); } } else @@ -134,9 +137,9 @@ int search_atom(const char *type, int start, type++; if (start > 0) { - resind = at[start-1].resind; + resind = at[start - 1].resind; } - for (i = start-1; (i >= 0) /*&& (at[i].resind == resind)*/; i--) + for (i = start - 1; (i >= 0) /*&& (at[i].resind == resind)*/; i--) { if (gmx_strcasecmp(type, *(anm[i])) == 0) { @@ -145,16 +148,14 @@ int search_atom(const char *type, int start, } if (start > 0) { - atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, bAllowMissing); + atom_not_found(FARGS, type, at[start].resind, *atoms->resinfo[resind].name, bondtype, + bAllowMissing); } } return -1; } -int -search_res_atom(const char *type, int resind, - const t_atoms *atoms, - const char *bondtype, bool bAllowMissing) +int search_res_atom(const char* type, int resind, const t_atoms* atoms, const char* bondtype, bool bAllowMissing) { int i; diff --git a/src/gromacs/gmxpreprocess/pgutil.h b/src/gromacs/gmxpreprocess/pgutil.h index 0409d15dfe..848dfcc0c4 100644 --- a/src/gromacs/gmxpreprocess/pgutil.h +++ b/src/gromacs/gmxpreprocess/pgutil.h @@ -50,16 +50,11 @@ struct t_atoms; * when bondtype="check" no error/warning is issued. * When bAllowMissing=FALSE an fatal error is issued, otherwise a warning. */ -int search_atom(const char *type, int start, - const t_atoms *atoms, - const char *bondtype, bool bAllowMissing); +int search_atom(const char* type, int start, const t_atoms* atoms, const char* bondtype, bool bAllowMissing); /* Similar to search_atom, but this routine searches for the specified * atom in residue resind. */ -int -search_res_atom(const char *type, int resind, - const t_atoms *atoms, - const char *bondtype, bool bAllowMissing); +int search_res_atom(const char* type, int resind, const t_atoms* atoms, const char* bondtype, bool bAllowMissing); #endif diff --git a/src/gromacs/gmxpreprocess/readir.cpp b/src/gromacs/gmxpreprocess/readir.cpp index 4c8ba71fa7..42b1f04e96 100644 --- a/src/gromacs/gmxpreprocess/readir.cpp +++ b/src/gromacs/gmxpreprocess/readir.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -87,7 +87,7 @@ #include "gromacs/utility/textwriter.h" #define MAXPTR 254 -#define NOGID 255 +#define NOGID 255 /* Resource parameters * Do not change any of these until you read the instruction @@ -98,31 +98,30 @@ typedef struct t_inputrec_strings { - char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], - acc[STRLEN], accgrps[STRLEN], freeze[STRLEN], frdim[STRLEN], - energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN], - couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN], - wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN], - imd_grp[STRLEN]; + char tcgrps[STRLEN], tau_t[STRLEN], ref_t[STRLEN], acc[STRLEN], accgrps[STRLEN], freeze[STRLEN], + frdim[STRLEN], energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], + x_compressed_groups[STRLEN], couple_moltype[STRLEN], orirefitgrp[STRLEN], + egptable[STRLEN], egpexcl[STRLEN], wall_atomtype[STRLEN], wall_density[STRLEN], + deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN]; char fep_lambda[efptNR][STRLEN]; char lambda_weights[STRLEN]; - char **pull_grp; - char **rot_grp; - char anneal[STRLEN], anneal_npoints[STRLEN], - anneal_time[STRLEN], anneal_temp[STRLEN]; - char QMmethod[STRLEN], QMbasis[STRLEN], QMcharge[STRLEN], QMmult[STRLEN], - bSH[STRLEN], CASorbitals[STRLEN], CASelectrons[STRLEN], SAon[STRLEN], - SAoff[STRLEN], SAsteps[STRLEN]; + char** pull_grp; + char** rot_grp; + char anneal[STRLEN], anneal_npoints[STRLEN], anneal_time[STRLEN], anneal_temp[STRLEN]; + char QMmethod[STRLEN], QMbasis[STRLEN], QMcharge[STRLEN], QMmult[STRLEN], bSH[STRLEN], + CASorbitals[STRLEN], CASelectrons[STRLEN], SAon[STRLEN], SAoff[STRLEN], SAsteps[STRLEN]; } gmx_inputrec_strings; -static gmx_inputrec_strings *is = nullptr; +static gmx_inputrec_strings* is = nullptr; void init_inputrec_strings() { if (is) { - gmx_incons("Attempted to call init_inputrec_strings before calling done_inputrec_strings. Only one inputrec (i.e. .mdp file) can be parsed at a time."); + gmx_incons( + "Attempted to call init_inputrec_strings before calling done_inputrec_strings. " + "Only one inputrec (i.e. .mdp file) can be parsed at a time."); } snew(is, 1); } @@ -134,7 +133,8 @@ void done_inputrec_strings() } -enum { +enum +{ egrptpALL, /* All particles have to be a member of a group. */ egrptpALL_GENREST, /* A rest group with name is generated for particles * * that are not part of any group. */ @@ -144,15 +144,12 @@ enum { * make a rest group for the remaining particles. */ }; -static const char *constraints[eshNR+1] = { - "none", "h-bonds", "all-bonds", "h-angles", "all-angles", nullptr -}; +static const char* constraints[eshNR + 1] = { "none", "h-bonds", "all-bonds", + "h-angles", "all-angles", nullptr }; -static const char *couple_lam[ecouplamNR+1] = { - "vdw-q", "vdw", "q", "none", nullptr -}; +static const char* couple_lam[ecouplamNR + 1] = { "vdw-q", "vdw", "q", "none", nullptr }; -static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lambdas) +static void GetSimTemps(int ntemps, t_simtemp* simtemp, double* temperature_lambdas) { int i; @@ -162,15 +159,22 @@ static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lamb /* simple linear scaling -- allows more control */ if (simtemp->eSimTempScale == esimtempLINEAR) { - simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*temperature_lambdas[i]; + simtemp->temperatures[i] = + simtemp->simtemp_low + + (simtemp->simtemp_high - simtemp->simtemp_low) * temperature_lambdas[i]; } - else if (simtemp->eSimTempScale == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */ + else if (simtemp->eSimTempScale + == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */ { - simtemp->temperatures[i] = simtemp->simtemp_low * std::pow(simtemp->simtemp_high/simtemp->simtemp_low, static_cast((1.0*i)/(ntemps-1))); + simtemp->temperatures[i] = simtemp->simtemp_low + * std::pow(simtemp->simtemp_high / simtemp->simtemp_low, + static_cast((1.0 * i) / (ntemps - 1))); } else if (simtemp->eSimTempScale == esimtempEXPONENTIAL) { - simtemp->temperatures[i] = simtemp->simtemp_low + (simtemp->simtemp_high-simtemp->simtemp_low)*(std::expm1(temperature_lambdas[i])/std::expm1(1.0)); + simtemp->temperatures[i] = simtemp->simtemp_low + + (simtemp->simtemp_high - simtemp->simtemp_low) + * (std::expm1(temperature_lambdas[i]) / std::expm1(1.0)); } else { @@ -182,8 +186,7 @@ static void GetSimTemps(int ntemps, t_simtemp *simtemp, double *temperature_lamb } - -static void _low_check(bool b, const char *s, warninp_t wi) +static void _low_check(bool b, const char* s, warninp_t wi) { if (b) { @@ -191,18 +194,15 @@ static void _low_check(bool b, const char *s, warninp_t wi) } } -static void check_nst(const char *desc_nst, int nst, - const char *desc_p, int *p, - warninp_t wi) +static void check_nst(const char* desc_nst, int nst, const char* desc_p, int* p, warninp_t wi) { char buf[STRLEN]; if (*p > 0 && *p % nst != 0) { /* Round up to the next multiple of nst */ - *p = ((*p)/nst + 1)*nst; - sprintf(buf, "%s should be a multiple of %s, changing %s to %d\n", - desc_p, desc_nst, desc_p, *p); + *p = ((*p) / nst + 1) * nst; + sprintf(buf, "%s should be a multiple of %s, changing %s to %d\n", desc_p, desc_nst, desc_p, *p); warning(wi, buf); } } @@ -224,7 +224,7 @@ static int lcd(int n1, int n2) } //! Convert legacy mdp entries to modern ones. -static void process_interaction_modifier(int *eintmod) +static void process_interaction_modifier(int* eintmod) { if (*eintmod == eintmodPOTSHIFT_VERLET_UNSUPPORTED) { @@ -232,8 +232,11 @@ static void process_interaction_modifier(int *eintmod) } } -void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifier, - t_inputrec *ir, t_gromppopts *opts, warninp_t wi) +void check_ir(const char* mdparin, + const gmx::MdModulesNotifier& mdModulesNotifier, + t_inputrec* ir, + t_gromppopts* opts, + warninp_t wi) /* Check internal consistency. * NOTE: index groups are not set here yet, don't check things * like temperature coupling group options here, but in triple_check @@ -247,15 +250,14 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi char err_buf[256], warn_buf[STRLEN]; int i, j; real dt_pcoupl; - t_lambda *fep = ir->fepvals; - t_expanded *expand = ir->expandedvals; + t_lambda* fep = ir->fepvals; + t_expanded* expand = ir->expandedvals; set_warning_line(wi, mdparin, -1); if (ir->coulombtype == eelRF_NEC_UNSUPPORTED) { - sprintf(warn_buf, "%s electrostatics is no longer supported", - eel_names[eelRF_NEC_UNSUPPORTED]); + sprintf(warn_buf, "%s electrostatics is no longer supported", eel_names[eelRF_NEC_UNSUPPORTED]); warning_error(wi, warn_buf); } @@ -268,12 +270,14 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { warning_error(wi, "rvdw should be >= 0"); } - if (ir->rlist < 0 && - !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0)) + if (ir->rlist < 0 && !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0)) { warning_error(wi, "rlist should be >= 0"); } - sprintf(err_buf, "nstlist can not be smaller than 0. (If you were trying to use the heuristic neighbour-list update scheme for efficient buffering for improved energy conservation, please use the Verlet cut-off scheme instead.)"); + sprintf(err_buf, + "nstlist can not be smaller than 0. (If you were trying to use the heuristic " + "neighbour-list update scheme for efficient buffering for improved energy " + "conservation, please use the Verlet cut-off scheme instead.)"); CHECK(ir->nstlist < 0); process_interaction_modifier(&ir->coulomb_modifier); @@ -300,45 +304,51 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { // Since we have PME coulomb + LJ cut-off kernels with rcoulomb>rvdw // for PME load balancing, we can support this exception. - bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) && - ir->vdwtype == evdwCUT && - ir->rcoulomb > ir->rvdw); + bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == evdwCUT + && ir->rcoulomb > ir->rvdw); if (!bUsesPmeTwinRangeKernel) { - warning_error(wi, "With Verlet lists rcoulomb!=rvdw is not supported (except for rcoulomb>rvdw with PME electrostatics)"); + warning_error(wi, + "With Verlet lists rcoulomb!=rvdw is not supported (except for " + "rcoulomb>rvdw with PME electrostatics)"); } } if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH) { - if (ir->vdw_modifier == eintmodNONE || - ir->vdw_modifier == eintmodPOTSHIFT) + if (ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT) { ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH); - sprintf(warn_buf, "Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and vdw_modifier=%s", evdw_names[ir->vdwtype], evdw_names[evdwCUT], eintmod_names[ir->vdw_modifier]); + sprintf(warn_buf, + "Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and " + "vdw_modifier=%s", + evdw_names[ir->vdwtype], evdw_names[evdwCUT], eintmod_names[ir->vdw_modifier]); warning_note(wi, warn_buf); ir->vdwtype = evdwCUT; } else { - sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s", evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]); + sprintf(warn_buf, "Unsupported combination of vdwtype=%s and vdw_modifier=%s", + evdw_names[ir->vdwtype], eintmod_names[ir->vdw_modifier]); warning_error(wi, warn_buf); } } if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME)) { - warning_error(wi, "With Verlet lists only cut-off and PME LJ interactions are supported"); + warning_error(wi, + "With Verlet lists only cut-off and PME LJ interactions are supported"); } - if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) || - EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD)) + if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) || EEL_PME(ir->coulombtype) + || ir->coulombtype == eelEWALD)) { - warning_error(wi, "With Verlet lists only cut-off, reaction-field, PME and Ewald electrostatics are supported"); + warning_error(wi, + "With Verlet lists only cut-off, reaction-field, PME and Ewald " + "electrostatics are supported"); } - if (!(ir->coulomb_modifier == eintmodNONE || - ir->coulomb_modifier == eintmodPOTSHIFT)) + if (!(ir->coulomb_modifier == eintmodNONE || ir->coulomb_modifier == eintmodPOTSHIFT)) { sprintf(warn_buf, "coulomb_modifier=%s is not supported", eintmod_names[ir->coulomb_modifier]); warning_error(wi, warn_buf); @@ -346,7 +356,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (EEL_USER(ir->coulombtype)) { - sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme", eel_names[ir->coulombtype]); + sprintf(warn_buf, "Coulomb type %s is not supported with the verlet scheme", + eel_names[ir->coulombtype]); warning_error(wi, warn_buf); } @@ -357,7 +368,10 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->nstlist < 10) { - warning_note(wi, "With Verlet lists the optimal nstlist is >= 10, with GPUs >= 20. Note that with the Verlet scheme, nstlist has no effect on the accuracy of your simulation."); + warning_note(wi, + "With Verlet lists the optimal nstlist is >= 10, with GPUs >= 20. Note " + "that with the Verlet scheme, nstlist has no effect on the accuracy of " + "your simulation."); } rc_max = std::max(ir->rvdw, ir->rcoulomb); @@ -377,19 +391,27 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->rlist < rc_max) { - warning_error(wi, "With verlet lists rlist can not be smaller than rvdw or rcoulomb"); + warning_error(wi, + "With verlet lists rlist can not be smaller than rvdw or rcoulomb"); } if (ir->rlist == rc_max && ir->nstlist > 1) { - warning_note(wi, "rlist is equal to rvdw and/or rcoulomb: there is no explicit Verlet buffer. The cluster pair list does have a buffering effect, but choosing a larger rlist might be necessary for good energy conservation."); + warning_note( + wi, + "rlist is equal to rvdw and/or rcoulomb: there is no explicit Verlet " + "buffer. The cluster pair list does have a buffering effect, but choosing " + "a larger rlist might be necessary for good energy conservation."); } } else { if (ir->rlist > rc_max) { - warning_note(wi, "You have set rlist larger than the interaction cut-off, but you also have verlet-buffer-tolerance > 0. Will set rlist using verlet-buffer-tolerance."); + warning_note(wi, + "You have set rlist larger than the interaction cut-off, but you also " + "have verlet-buffer-tolerance > 0. Will set rlist using " + "verlet-buffer-tolerance."); } if (ir->nstlist == 1) @@ -403,7 +425,12 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { if (inputrec2nboundeddim(ir) < 3) { - warning_error(wi, "The box volume is required for calculating rlist from the energy drift with verlet-buffer-tolerance > 0. You are using at least one unbounded dimension, so no volume can be computed. Either use a finite box, or set rlist yourself together with verlet-buffer-tolerance = -1."); + warning_error(wi, + "The box volume is required for calculating rlist from the " + "energy drift with verlet-buffer-tolerance > 0. You are " + "using at least one unbounded dimension, so no volume can be " + "computed. Either use a finite box, or set rlist yourself " + "together with verlet-buffer-tolerance = -1."); } /* Set rlist temporarily so we can continue processing */ ir->rlist = rc_max; @@ -411,7 +438,7 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi else { /* Set the buffer to 5% of the cut-off */ - ir->rlist = (1.0 + verlet_buffer_ratio_nodynamics)*rc_max; + ir->rlist = (1.0 + verlet_buffer_ratio_nodynamics) * rc_max; } } } @@ -424,11 +451,18 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { if (EI_RANDOM(ir->eI)) { - sprintf(warn_buf, "Setting tcoupl from '%s' to 'no'. %s handles temperature coupling implicitly. See the documentation for more information on which parameters affect temperature for %s.", etcoupl_names[ir->etc], ei_names[ir->eI], ei_names[ir->eI]); + sprintf(warn_buf, + "Setting tcoupl from '%s' to 'no'. %s handles temperature coupling " + "implicitly. See the documentation for more information on which " + "parameters affect temperature for %s.", + etcoupl_names[ir->etc], ei_names[ir->eI], ei_names[ir->eI]); } else { - sprintf(warn_buf, "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to %s.", etcoupl_names[ir->etc], ei_names[ir->eI]); + sprintf(warn_buf, + "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to " + "%s.", + etcoupl_names[ir->etc], ei_names[ir->eI]); } warning_note(wi, warn_buf); } @@ -436,14 +470,19 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi } if (ir->eI == eiVVAK) { - sprintf(warn_buf, "Integrator method %s is implemented primarily for validation purposes; for molecular dynamics, you should probably be using %s or %s", ei_names[eiVVAK], ei_names[eiMD], ei_names[eiVV]); + sprintf(warn_buf, + "Integrator method %s is implemented primarily for validation purposes; for " + "molecular dynamics, you should probably be using %s or %s", + ei_names[eiVVAK], ei_names[eiMD], ei_names[eiVV]); warning_note(wi, warn_buf); } if (!EI_DYNAMICS(ir->eI)) { if (ir->epc != epcNO) { - sprintf(warn_buf, "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.", epcoupl_names[ir->epc], ei_names[ir->eI]); + sprintf(warn_buf, + "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.", + epcoupl_names[ir->epc], ei_names[ir->eI]); warning_note(wi, warn_buf); } ir->epc = epcNO; @@ -468,27 +507,26 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi } } } - else if ( (ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) || - (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 && - (ir->nstcalcenergy > ir->fepvals->nstdhdl) ) ) + else if ((ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy) + || (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 + && (ir->nstcalcenergy > ir->fepvals->nstdhdl))) { - const char *nsten = "nstenergy"; - const char *nstdh = "nstdhdl"; - const char *min_name = nsten; + const char* nsten = "nstenergy"; + const char* nstdh = "nstdhdl"; + const char* min_name = nsten; int min_nst = ir->nstenergy; /* find the smallest of ( nstenergy, nstdhdl ) */ - if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 && - (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy)) + if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0 + && (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy)) { min_nst = ir->fepvals->nstdhdl; min_name = nstdh; } /* If the user sets nstenergy small, we should respect that */ - sprintf(warn_buf, - "Setting nstcalcenergy (%d) equal to %s (%d)", - ir->nstcalcenergy, min_name, min_nst); + sprintf(warn_buf, "Setting nstcalcenergy (%d) equal to %s (%d)", ir->nstcalcenergy, + min_name, min_nst); warning_note(wi, warn_buf); ir->nstcalcenergy = min_nst; } @@ -506,20 +544,18 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->efep != efepNO) { /* nstdhdl should be a multiple of nstcalcenergy */ - check_nst("nstcalcenergy", ir->nstcalcenergy, - "nstdhdl", &ir->fepvals->nstdhdl, wi); + check_nst("nstcalcenergy", ir->nstcalcenergy, "nstdhdl", &ir->fepvals->nstdhdl, wi); } if (ir->bExpanded) { /* nstexpanded should be a multiple of nstcalcenergy */ - check_nst("nstcalcenergy", ir->nstcalcenergy, - "nstexpanded", &ir->expandedvals->nstexpanded, wi); + check_nst("nstcalcenergy", ir->nstcalcenergy, "nstexpanded", + &ir->expandedvals->nstexpanded, wi); } /* for storing exact averages nstenergy should be * a multiple of nstcalcenergy */ - check_nst("nstcalcenergy", ir->nstcalcenergy, - "nstenergy", &ir->nstenergy, wi); + check_nst("nstcalcenergy", ir->nstcalcenergy, "nstenergy", &ir->nstenergy, wi); } // Inquire all MdModules, if their parameters match with the energy @@ -528,7 +564,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi mdModulesNotifier.notifier_.notify(&energyCalculationFrequencyErrors); // Emit all errors from the energy calculation frequency checks - for (const std::string &energyFrequencyErrorMessage : energyCalculationFrequencyErrors.errorMessages()) + for (const std::string& energyFrequencyErrorMessage : + energyCalculationFrequencyErrors.errorMessages()) { warning_error(wi, energyFrequencyErrorMessage); } @@ -536,14 +573,17 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->nsteps == 0 && !ir->bContinuation) { - warning_note(wi, "For a correct single-point energy evaluation with nsteps = 0, use continuation = yes to avoid constraining the input coordinates."); + warning_note(wi, + "For a correct single-point energy evaluation with nsteps = 0, use " + "continuation = yes to avoid constraining the input coordinates."); } /* LD STUFF */ - if ((EI_SD(ir->eI) || ir->eI == eiBD) && - ir->bContinuation && ir->ld_seed != -1) + if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1) { - warning_note(wi, "You are doing a continuation with SD or BD, make sure that ld_seed is different from the previous run (using ld_seed=-1 will ensure this)"); + warning_note(wi, + "You are doing a continuation with SD or BD, make sure that ld_seed is " + "different from the previous run (using ld_seed=-1 will ensure this)"); } /* TPI STUFF */ @@ -558,17 +598,17 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi } /* SHAKE / LINCS */ - if ( (opts->nshake > 0) && (opts->bMorse) ) + if ((opts->nshake > 0) && (opts->bMorse)) { - sprintf(warn_buf, - "Using morse bond-potentials while constraining bonds is useless"); + sprintf(warn_buf, "Using morse bond-potentials while constraining bonds is useless"); warning(wi, warn_buf); } - if ((EI_SD(ir->eI) || ir->eI == eiBD) && - ir->bContinuation && ir->ld_seed != -1) + if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1) { - warning_note(wi, "You are doing a continuation with SD or BD, make sure that ld_seed is different from the previous run (using ld_seed=-1 will ensure this)"); + warning_note(wi, + "You are doing a continuation with SD or BD, make sure that ld_seed is " + "different from the previous run (using ld_seed=-1 will ensure this)"); } /* verify simulated tempering options */ @@ -577,7 +617,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi bool bAllTempZero = TRUE; for (i = 0; i < fep->n_lambda; i++) { - sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, efpt_names[efptTEMPERATURE], fep->all_lambda[efptTEMPERATURE][i]); + sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, + efpt_names[efptTEMPERATURE], fep->all_lambda[efptTEMPERATURE][i]); CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1)); if (fep->all_lambda[efptTEMPERATURE][i] > 0) { @@ -594,19 +635,27 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->etc == etcNOSEHOOVER) { - sprintf(warn_buf, "Nose-Hoover based temperature control such as [%s] my not be entirelyconsistent with simulated tempering", etcoupl_names[ir->etc]); + sprintf(warn_buf, + "Nose-Hoover based temperature control such as [%s] my not be " + "entirelyconsistent with simulated tempering", + etcoupl_names[ir->etc]); warning_note(wi, warn_buf); } /* check that the temperatures make sense */ - sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= than the simulated tempering lower temperature (%g)", ir->simtempvals->simtemp_high, ir->simtempvals->simtemp_low); + sprintf(err_buf, + "Higher simulated tempering temperature (%g) must be >= than the simulated " + "tempering lower temperature (%g)", + ir->simtempvals->simtemp_high, ir->simtempvals->simtemp_low); CHECK(ir->simtempvals->simtemp_high <= ir->simtempvals->simtemp_low); - sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_high); + sprintf(err_buf, "Higher simulated tempering temperature (%g) must be >= zero", + ir->simtempvals->simtemp_high); CHECK(ir->simtempvals->simtemp_high <= 0); - sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", ir->simtempvals->simtemp_low); + sprintf(err_buf, "Lower simulated tempering temperature (%g) must be >= zero", + ir->simtempvals->simtemp_low); CHECK(ir->simtempvals->simtemp_low <= 0); } @@ -615,18 +664,21 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->efep != efepNO) { fep = ir->fepvals; - sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2", - fep->sc_power); + sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2", fep->sc_power); CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2); sprintf(err_buf, "The soft-core sc-r-power is %d and can only be 6 or 48", static_cast(fep->sc_r_power)); CHECK(fep->sc_alpha != 0 && fep->sc_r_power != 6.0 && fep->sc_r_power != 48.0); - sprintf(err_buf, "Can't use positive delta-lambda (%g) if initial state/lambda does not start at zero", fep->delta_lambda); - CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0))); + sprintf(err_buf, + "Can't use positive delta-lambda (%g) if initial state/lambda does not start at " + "zero", + fep->delta_lambda); + CHECK(fep->delta_lambda > 0 && ((fep->init_fep_state > 0) || (fep->init_lambda > 0))); - sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", fep->delta_lambda); + sprintf(err_buf, "Can't use positive delta-lambda (%g) with expanded ensemble simulations", + fep->delta_lambda); CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED)); sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)"); @@ -639,24 +691,28 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (fep->n_lambda == 0) { /* Clear output in case of no states:*/ - sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", fep->init_fep_state); + sprintf(err_buf, "init-lambda-state set to %d: no lambda states are defined.", + fep->init_fep_state); CHECK((fep->init_fep_state >= 0) && (fep->n_lambda == 0)); } else { - sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", fep->init_fep_state, fep->n_lambda-1); + sprintf(err_buf, "initial thermodynamic state %d does not exist, only goes to %d", + fep->init_fep_state, fep->n_lambda - 1); CHECK((fep->init_fep_state >= fep->n_lambda)); } - sprintf(err_buf, "Lambda state must be set, either with init-lambda-state or with init-lambda"); + sprintf(err_buf, + "Lambda state must be set, either with init-lambda-state or with init-lambda"); CHECK((fep->init_fep_state < 0) && (fep->init_lambda < 0)); - sprintf(err_buf, "init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with init-lambda-state or with init-lambda, but not both", + sprintf(err_buf, + "init-lambda=%g while init-lambda-state=%d. Lambda state must be set either with " + "init-lambda-state or with init-lambda, but not both", fep->init_lambda, fep->init_fep_state); CHECK((fep->init_fep_state >= 0) && (fep->init_lambda >= 0)); - if ((fep->init_lambda >= 0) && (fep->delta_lambda == 0)) { int n_lambda_terms; @@ -670,14 +726,18 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi } if (n_lambda_terms > 1) { - sprintf(warn_buf, "If lambda vector states (fep-lambdas, coul-lambdas etc.) are set, don't use init-lambda to set lambda state (except for slow growth). Use init-lambda-state instead."); + sprintf(warn_buf, + "If lambda vector states (fep-lambdas, coul-lambdas etc.) are set, don't " + "use init-lambda to set lambda state (except for slow growth). Use " + "init-lambda-state instead."); warning(wi, warn_buf); } if (n_lambda_terms < 2 && fep->n_lambda > 0) { warning_note(wi, - "init-lambda is deprecated for setting lambda state (except for slow growth). Use init-lambda-state instead."); + "init-lambda is deprecated for setting lambda state (except for slow " + "growth). Use init-lambda-state instead."); } } @@ -685,7 +745,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { for (i = 0; i < fep->n_lambda; i++) { - sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, efpt_names[j], fep->all_lambda[j][i]); + sprintf(err_buf, "Entry %d for %s must be between 0 and 1, instead is %g", i, + efpt_names[j], fep->all_lambda[j][i]); CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1)); } } @@ -694,13 +755,14 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { for (i = 0; i < fep->n_lambda; i++) { - sprintf(err_buf, "For state %d, vdw-lambdas (%f) is changing with vdw softcore, while coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to crashes, and is not supported.", i, fep->all_lambda[efptVDW][i], - fep->all_lambda[efptCOUL][i]); - CHECK((fep->sc_alpha > 0) && - (((fep->all_lambda[efptCOUL][i] > 0.0) && - (fep->all_lambda[efptCOUL][i] < 1.0)) && - ((fep->all_lambda[efptVDW][i] > 0.0) && - (fep->all_lambda[efptVDW][i] < 1.0)))); + sprintf(err_buf, + "For state %d, vdw-lambdas (%f) is changing with vdw softcore, while " + "coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to " + "crashes, and is not supported.", + i, fep->all_lambda[efptVDW][i], fep->all_lambda[efptCOUL][i]); + CHECK((fep->sc_alpha > 0) + && (((fep->all_lambda[efptCOUL][i] > 0.0) && (fep->all_lambda[efptCOUL][i] < 1.0)) + && ((fep->all_lambda[efptVDW][i] > 0.0) && (fep->all_lambda[efptVDW][i] < 1.0)))); } } @@ -708,13 +770,18 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { real sigma, lambda, r_sc; - sigma = 0.34; + sigma = 0.34; /* Maximum estimate for A and B charges equal with lambda power 1 */ lambda = 0.5; - r_sc = std::pow(lambda*fep->sc_alpha*std::pow(sigma/ir->rcoulomb, fep->sc_r_power) + 1.0, 1.0/fep->sc_r_power); - sprintf(warn_buf, "With PME there is a minor soft core effect present at the cut-off, proportional to (LJsigma/rcoulomb)^%g. This could have a minor effect on energy conservation, but usually other effects dominate. With a common sigma value of %g nm the fraction of the particle-particle potential at the cut-off at lambda=%g is around %.1e, while ewald-rtol is %.1e.", - fep->sc_r_power, - sigma, lambda, r_sc - 1.0, ir->ewald_rtol); + r_sc = std::pow(lambda * fep->sc_alpha * std::pow(sigma / ir->rcoulomb, fep->sc_r_power) + 1.0, + 1.0 / fep->sc_r_power); + sprintf(warn_buf, + "With PME there is a minor soft core effect present at the cut-off, " + "proportional to (LJsigma/rcoulomb)^%g. This could have a minor effect on " + "energy conservation, but usually other effects dominate. With a common sigma " + "value of %g nm the fraction of the particle-particle potential at the cut-off " + "at lambda=%g is around %.1e, while ewald-rtol is %.1e.", + fep->sc_r_power, sigma, lambda, r_sc - 1.0, ir->ewald_rtol); warning_note(wi, warn_buf); } @@ -733,39 +800,51 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if ((ir->bSimTemp) || (ir->efep == efepEXPANDED)) { - fep = ir->fepvals; + fep = ir->fepvals; /* checking equilibration of weights inputs for validity */ - sprintf(err_buf, "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal to %s", + sprintf(err_buf, + "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal " + "to %s", expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]); CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM)); - sprintf(err_buf, "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to %s", + sprintf(err_buf, + "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to " + "%s", expand->equil_samples, elmceq_names[elmceqSAMPLES]); CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES)); - sprintf(err_buf, "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s", + sprintf(err_buf, + "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s", expand->equil_steps, elmceq_names[elmceqSTEPS]); CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS)); - sprintf(err_buf, "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s", + sprintf(err_buf, + "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s", expand->equil_samples, elmceq_names[elmceqWLDELTA]); CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA)); - sprintf(err_buf, "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s", + sprintf(err_buf, + "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s", expand->equil_ratio, elmceq_names[elmceqRATIO]); CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO)); - sprintf(err_buf, "weight-equil-number-all-lambda (%d) must be a positive integer if lmc-weights-equil=%s", + sprintf(err_buf, + "weight-equil-number-all-lambda (%d) must be a positive integer if " + "lmc-weights-equil=%s", expand->equil_n_at_lam, elmceq_names[elmceqNUMATLAM]); CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM)); - sprintf(err_buf, "weight-equil-number-samples (%d) must be a positive integer if lmc-weights-equil=%s", + sprintf(err_buf, + "weight-equil-number-samples (%d) must be a positive integer if " + "lmc-weights-equil=%s", expand->equil_samples, elmceq_names[elmceqSAMPLES]); CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES)); - sprintf(err_buf, "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s", + sprintf(err_buf, + "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s", expand->equil_steps, elmceq_names[elmceqSTEPS]); CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS)); @@ -787,12 +866,16 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi CHECK((expand->minvarmin <= 0)); sprintf(err_buf, "weight-c-range (%d) must be greater or equal to 0", expand->c_range); CHECK((expand->c_range < 0)); - sprintf(err_buf, "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != 'no'", + sprintf(err_buf, + "init-lambda-state (%d) must be zero if lmc-forced-nstart (%d)> 0 and lmc-move != " + "'no'", fep->init_fep_state, expand->lmc_forced_nstart); - CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) && (expand->elmcmove != elmcmoveNO)); + CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0) + && (expand->elmcmove != elmcmoveNO)); sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart); CHECK((expand->lmc_forced_nstart < 0)); - sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", fep->init_fep_state); + sprintf(err_buf, "init-lambda-state (%d) must be in the interval [0,number of lambdas)", + fep->init_fep_state); CHECK((fep->init_fep_state < 0) || (fep->init_fep_state >= fep->n_lambda)); sprintf(err_buf, "init-wl-delta (%f) must be greater than or equal to 0", expand->init_wl_delta); @@ -803,9 +886,12 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1)); /* if there is no temperature control, we need to specify an MC temperature */ - if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) && (expand->mc_temp <= 0.0)) + if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO) + && (expand->mc_temp <= 0.0)) { - sprintf(err_buf, "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set to a positive number"); + sprintf(err_buf, + "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set " + "to a positive number"); warning_error(wi, err_buf); } if (expand->nstTij > 0) @@ -815,7 +901,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi // Avoid modulus by zero in the case that already triggered an error exit. if (ir->nstlog != 0) { - sprintf(err_buf, "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)", + sprintf(err_buf, + "nst-transition-matrix (%d) must be an integer multiple of nstlog (%d)", expand->nstTij, ir->nstlog); CHECK((expand->nstTij % ir->nstlog) != 0); } @@ -839,32 +926,32 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi } else { - sprintf(err_buf, "Can not have pressure coupling with pbc=%s", - epbc_names[ir->ePBC]); + sprintf(err_buf, "Can not have pressure coupling with pbc=%s", epbc_names[ir->ePBC]); CHECK(ir->epc != epcNO); } sprintf(err_buf, "Can not have Ewald with pbc=%s", epbc_names[ir->ePBC]); CHECK(EEL_FULL(ir->coulombtype)); - sprintf(err_buf, "Can not have dispersion correction with pbc=%s", - epbc_names[ir->ePBC]); + sprintf(err_buf, "Can not have dispersion correction with pbc=%s", epbc_names[ir->ePBC]); CHECK(ir->eDispCorr != edispcNO); } if (ir->rlist == 0.0) { - sprintf(err_buf, "can only have neighborlist cut-off zero (=infinite)\n" + sprintf(err_buf, + "can only have neighborlist cut-off zero (=infinite)\n" "with coulombtype = %s or coulombtype = %s\n" "without periodic boundary conditions (pbc = %s) and\n" "rcoulomb and rvdw set to zero", eel_names[eelCUT], eel_names[eelUSER], epbc_names[epbcNONE]); - CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) || - (ir->ePBC != epbcNONE) || - (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0)); + CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER)) + || (ir->ePBC != epbcNONE) || (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0)); if (ir->nstlist > 0) { - warning_note(wi, "Simulating without cut-offs can be (slightly) faster with nstlist=0, nstype=simple and only one MPI rank"); + warning_note(wi, + "Simulating without cut-offs can be (slightly) faster with nstlist=0, " + "nstype=simple and only one MPI rank"); } } @@ -883,30 +970,44 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi // helpful for a few years, we should reject such input, // lest we have to support every historical decision // forever. - warning(wi, "If you want to remove the rotation around the center of mass, you should set comm_mode = Angular instead of setting nstcomm < 0. nstcomm is modified to its absolute value"); + warning(wi, + "If you want to remove the rotation around the center of mass, you should set " + "comm_mode = Angular instead of setting nstcomm < 0. nstcomm is modified to " + "its absolute value"); ir->nstcomm = abs(ir->nstcomm); } if (ir->nstcalcenergy > 0 && ir->nstcomm < ir->nstcalcenergy) { - warning_note(wi, "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting nstcomm to nstcalcenergy"); + warning_note(wi, + "nstcomm < nstcalcenergy defeats the purpose of nstcalcenergy, setting " + "nstcomm to nstcalcenergy"); ir->nstcomm = ir->nstcalcenergy; } if (ir->comm_mode == ecmANGULAR) { - sprintf(err_buf, "Can not remove the rotation around the center of mass with periodic molecules"); + sprintf(err_buf, + "Can not remove the rotation around the center of mass with periodic " + "molecules"); CHECK(ir->bPeriodicMols); if (ir->ePBC != epbcNONE) { - warning(wi, "Removing the rotation around the center of mass in a periodic system, this can lead to artifacts. Only use this on a single (cluster of) molecules. This cluster should not cross periodic boundaries."); + warning(wi, + "Removing the rotation around the center of mass in a periodic system, " + "this can lead to artifacts. Only use this on a single (cluster of) " + "molecules. This cluster should not cross periodic boundaries."); } } } if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->ePBC == epbcNONE && ir->comm_mode != ecmANGULAR) { - sprintf(warn_buf, "Tumbling and flying ice-cubes: We are not removing rotation around center of mass in a non-periodic system. You should probably set comm_mode = ANGULAR or use integrator = %s.", ei_names[eiSD1]); + sprintf(warn_buf, + "Tumbling and flying ice-cubes: We are not removing rotation around center of mass " + "in a non-periodic system. You should probably set comm_mode = ANGULAR or use " + "integrator = %s.", + ei_names[eiSD1]); warning_note(wi, warn_buf); } @@ -914,7 +1015,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->etc == etcYES) { ir->etc = etcBERENDSEN; - warning_note(wi, "Old option for temperature coupling given: " + warning_note(wi, + "Old option for temperature coupling given: " "changing \"yes\" to \"Berendsen\"\n"); } @@ -922,14 +1024,19 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { if (ir->opts.nhchainlength < 1) { - sprintf(warn_buf, "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to 1\n", ir->opts.nhchainlength); + sprintf(warn_buf, + "number of Nose-Hoover chains (currently %d) cannot be less than 1,reset to " + "1\n", + ir->opts.nhchainlength); ir->opts.nhchainlength = 1; warning(wi, warn_buf); } if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1) { - warning_note(wi, "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1"); + warning_note( + wi, + "leapfrog does not yet support Nose-Hoover chains, nhchainlength reset to 1"); ir->opts.nhchainlength = 1; } } @@ -940,37 +1047,49 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->eI == eiVVAK) { - sprintf(err_buf, "%s implemented primarily for validation, and requires nsttcouple = 1 and nstpcouple = 1.", + sprintf(err_buf, + "%s implemented primarily for validation, and requires nsttcouple = 1 and " + "nstpcouple = 1.", ei_names[eiVVAK]); CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1)); } if (ETC_ANDERSEN(ir->etc)) { - sprintf(err_buf, "%s temperature control not supported for integrator %s.", etcoupl_names[ir->etc], ei_names[ir->eI]); + sprintf(err_buf, "%s temperature control not supported for integrator %s.", + etcoupl_names[ir->etc], ei_names[ir->eI]); CHECK(!(EI_VV(ir->eI))); if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN)) { - sprintf(warn_buf, "Center of mass removal not necessary for %s. All velocities of coupled groups are rerandomized periodically, so flying ice cube errors will not occur.", etcoupl_names[ir->etc]); + sprintf(warn_buf, + "Center of mass removal not necessary for %s. All velocities of coupled " + "groups are rerandomized periodically, so flying ice cube errors will not " + "occur.", + etcoupl_names[ir->etc]); warning_note(wi, warn_buf); } - sprintf(err_buf, "nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are randomized every time step", ir->nstcomm, etcoupl_names[ir->etc]); + sprintf(err_buf, + "nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are " + "randomized every time step", + ir->nstcomm, etcoupl_names[ir->etc]); CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN)); } if (ir->etc == etcBERENDSEN) { - sprintf(warn_buf, "The %s thermostat does not generate the correct kinetic energy distribution. You might want to consider using the %s thermostat.", + sprintf(warn_buf, + "The %s thermostat does not generate the correct kinetic energy distribution. You " + "might want to consider using the %s thermostat.", ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE)); warning_note(wi, warn_buf); } - if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) - && ir->epc == epcBERENDSEN) + if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) && ir->epc == epcBERENDSEN) { - sprintf(warn_buf, "Using Berendsen pressure coupling invalidates the " + sprintf(warn_buf, + "Using Berendsen pressure coupling invalidates the " "true ensemble for the thermostat"); warning(wi, warn_buf); } @@ -979,30 +1098,34 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->epc == epcISOTROPIC) { ir->epc = epcBERENDSEN; - warning_note(wi, "Old option for pressure coupling given: " + warning_note(wi, + "Old option for pressure coupling given: " "changing \"Isotropic\" to \"Berendsen\"\n"); } if (ir->epc != epcNO) { - dt_pcoupl = ir->nstpcouple*ir->delta_t; + dt_pcoupl = ir->nstpcouple * ir->delta_t; sprintf(err_buf, "tau-p must be > 0 instead of %g\n", ir->tau_p); CHECK(ir->tau_p <= 0); - if (ir->tau_p/dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10*GMX_REAL_EPS) + if (ir->tau_p / dt_pcoupl < pcouple_min_integration_steps(ir->epc) - 10 * GMX_REAL_EPS) { - sprintf(warn_buf, "For proper integration of the %s barostat, tau-p (%g) should be at least %d times larger than nstpcouple*dt (%g)", + sprintf(warn_buf, + "For proper integration of the %s barostat, tau-p (%g) should be at least %d " + "times larger than nstpcouple*dt (%g)", EPCOUPLTYPE(ir->epc), ir->tau_p, pcouple_min_integration_steps(ir->epc), dt_pcoupl); warning(wi, warn_buf); } - sprintf(err_buf, "compressibility must be > 0 when using pressure" - " coupling %s\n", EPCOUPLTYPE(ir->epc)); - CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || - ir->compress[ZZ][ZZ] < 0 || - (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && - ir->compress[ZZ][XX] <= 0 && ir->compress[ZZ][YY] <= 0)); + sprintf(err_buf, + "compressibility must be > 0 when using pressure" + " coupling %s\n", + EPCOUPLTYPE(ir->epc)); + CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || ir->compress[ZZ][ZZ] < 0 + || (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && ir->compress[ZZ][XX] <= 0 + && ir->compress[ZZ][YY] <= 0)); if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel) { @@ -1032,16 +1155,19 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->coulombtype == eelSWITCH) { - sprintf(warn_buf, "coulombtype = %s is only for testing purposes and can lead to serious " + sprintf(warn_buf, + "coulombtype = %s is only for testing purposes and can lead to serious " "artifacts, advice: use coulombtype = %s", - eel_names[ir->coulombtype], - eel_names[eelRF_ZERO]); + eel_names[ir->coulombtype], eel_names[eelRF_ZERO]); warning(wi, warn_buf); } if (EEL_RF(ir->coulombtype) && ir->epsilon_rf == 1 && ir->epsilon_r != 1) { - sprintf(warn_buf, "epsilon-r = %g and epsilon-rf = 1 with reaction field, proceeding assuming old format and exchanging epsilon-r and epsilon-rf", ir->epsilon_r); + sprintf(warn_buf, + "epsilon-r = %g and epsilon-rf = 1 with reaction field, proceeding assuming old " + "format and exchanging epsilon-r and epsilon-rf", + ir->epsilon_r); warning(wi, warn_buf); ir->epsilon_rf = ir->epsilon_r; ir->epsilon_r = 1.0; @@ -1050,8 +1176,10 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->epsilon_r == 0) { sprintf(err_buf, - "It is pointless to use long-range electrostatics with infinite relative permittivity." - "Since you are effectively turning of electrostatics, a plain cutoff will be much faster."); + "It is pointless to use long-range electrostatics with infinite relative " + "permittivity." + "Since you are effectively turning of electrostatics, a plain cutoff will be much " + "faster."); CHECK(EEL_FULL(ir->coulombtype)); } @@ -1067,15 +1195,15 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0) { - sprintf(warn_buf, "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0", + sprintf(warn_buf, + "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0", eel_names[ir->coulombtype]); warning(wi, warn_buf); ir->epsilon_rf = 0.0; } sprintf(err_buf, "epsilon-rf must be >= epsilon-r"); - CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) || - (ir->epsilon_r == 0)); + CHECK((ir->epsilon_rf < ir->epsilon_r && ir->epsilon_rf != 0) || (ir->epsilon_r == 0)); if (ir->epsilon_rf == ir->epsilon_r) { sprintf(warn_buf, "Using epsilon-rf = epsilon-r with %s does not make sense", @@ -1092,7 +1220,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir_coulomb_switched(ir)) { sprintf(err_buf, - "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the potential modifier options!", + "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the " + "potential modifier options!", eel_names[ir->coulombtype]); CHECK(ir->rcoulomb_switch >= ir->rcoulomb); } @@ -1101,31 +1230,37 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT) { sprintf(err_buf, - "Explicit switch/shift coulomb interactions cannot be used in combination with a secondary coulomb-modifier."); - CHECK( ir->coulomb_modifier != eintmodNONE); + "Explicit switch/shift coulomb interactions cannot be used in combination with a " + "secondary coulomb-modifier."); + CHECK(ir->coulomb_modifier != eintmodNONE); } if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT) { sprintf(err_buf, - "Explicit switch/shift vdw interactions cannot be used in combination with a secondary vdw-modifier."); - CHECK( ir->vdw_modifier != eintmodNONE); + "Explicit switch/shift vdw interactions cannot be used in combination with a " + "secondary vdw-modifier."); + CHECK(ir->vdw_modifier != eintmodNONE); } - if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT || - ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT) + if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT || ir->vdwtype == evdwSWITCH + || ir->vdwtype == evdwSHIFT) { sprintf(warn_buf, - "The switch/shift interaction settings are just for compatibility; you will get better " + "The switch/shift interaction settings are just for compatibility; you will get " + "better " "performance from applying potential modifiers to your interactions!\n"); warning_note(wi, warn_buf); } if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH) { - if (ir->rcoulomb_switch/ir->rcoulomb < 0.9499) + if (ir->rcoulomb_switch / ir->rcoulomb < 0.9499) { - real percentage = 100*(ir->rcoulomb-ir->rcoulomb_switch)/ir->rcoulomb; - sprintf(warn_buf, "The switching range should be 5%% or less (currently %.2f%% using a switching range of %4f-%4f) for accurate electrostatic energies, energy conservation will be good regardless, since ewald_rtol = %g.", + real percentage = 100 * (ir->rcoulomb - ir->rcoulomb_switch) / ir->rcoulomb; + sprintf(warn_buf, + "The switching range should be 5%% or less (currently %.2f%% using a switching " + "range of %4f-%4f) for accurate electrostatic energies, energy conservation " + "will be good regardless, since ewald_rtol = %g.", percentage, ir->rcoulomb_switch, ir->rcoulomb, ir->ewald_rtol); warning(wi, warn_buf); } @@ -1135,15 +1270,19 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { if (ir->rvdw_switch == 0) { - sprintf(warn_buf, "rvdw-switch is equal 0 even though you are using a switched Lennard-Jones potential. This suggests it was not set in the mdp, which can lead to large energy errors. In GROMACS, 0.05 to 0.1 nm is often a reasonable vdw switching range."); + sprintf(warn_buf, + "rvdw-switch is equal 0 even though you are using a switched Lennard-Jones " + "potential. This suggests it was not set in the mdp, which can lead to large " + "energy errors. In GROMACS, 0.05 to 0.1 nm is often a reasonable vdw " + "switching range."); warning(wi, warn_buf); } } if (EEL_FULL(ir->coulombtype)) { - if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER || - ir->coulombtype == eelPMEUSERSWITCH) + if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER + || ir->coulombtype == eelPMEUSERSWITCH) { sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist", eel_names[ir->coulombtype]); @@ -1159,7 +1298,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (ir->pme_order < orderMin || ir->pme_order > orderMax) { - sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", eel_names[ir->coulombtype], orderMin, orderMax); + sprintf(warn_buf, "With coulombtype = %s, you should have %d <= pme-order <= %d", + eel_names[ir->coulombtype], orderMin, orderMax); warning_error(wi, warn_buf); } } @@ -1168,16 +1308,15 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi { if (ir->ewald_geometry == eewg3D) { - sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s", - epbc_names[ir->ePBC], eewg_names[eewg3DC]); + sprintf(warn_buf, "With pbc=%s you should use ewald-geometry=%s", epbc_names[ir->ePBC], + eewg_names[eewg3DC]); warning(wi, warn_buf); } /* This check avoids extra pbc coding for exclusion corrections */ sprintf(err_buf, "wall-ewald-zfac should be >= 2"); CHECK(ir->wall_ewald_zfac < 2); } - if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) && - EEL_FULL(ir->coulombtype)) + if ((ir->ewald_geometry == eewg3DC) && (ir->ePBC != epbcXY) && EEL_FULL(ir->coulombtype)) { sprintf(warn_buf, "With %s and ewald_geometry = %s you should use pbc = %s", eel_names[ir->coulombtype], eewg_names[eewg3DC], epbc_names[epbcXY]); @@ -1191,7 +1330,8 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi warning_note(wi, warn_buf); sprintf(warn_buf, "With epsilon_surface > 0 you can only use domain decomposition " - "when there are only small molecules with all bonds constrained (mdrun will check for this)."); + "when there are only small molecules with all bonds constrained (mdrun will check " + "for this)."); warning_note(wi, warn_buf); } @@ -1200,9 +1340,12 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi sprintf(err_buf, "With switched vdw forces or potentials, rvdw-switch must be < rvdw"); CHECK(ir->rvdw_switch >= ir->rvdw); - if (ir->rvdw_switch < 0.5*ir->rvdw) + if (ir->rvdw_switch < 0.5 * ir->rvdw) { - sprintf(warn_buf, "You are applying a switch function to vdw forces or potentials from %g to %g nm, which is more than half the interaction range, whereas switch functions are intended to act only close to the cut-off.", + sprintf(warn_buf, + "You are applying a switch function to vdw forces or potentials from %g to %g " + "nm, which is more than half the interaction range, whereas switch functions " + "are intended to act only close to the cut-off.", ir->rvdw_switch, ir->rvdw); warning_note(wi, warn_buf); } @@ -1213,20 +1356,21 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT)) { sprintf(err_buf, "With vdwtype = %s, the only supported modifiers are %s and %s", - evdw_names[ir->vdwtype], - eintmod_names[eintmodPOTSHIFT], - eintmod_names[eintmodNONE]); + evdw_names[ir->vdwtype], eintmod_names[eintmodPOTSHIFT], eintmod_names[eintmodNONE]); warning_error(wi, err_buf); } } if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO) { - warning_note(wi, "You have selected user tables with dispersion correction, the dispersion will be corrected to -C6/r^6 beyond rvdw_switch (the tabulated interaction between rvdw_switch and rvdw will not be double counted). Make sure that you really want dispersion correction to -C6/r^6."); + warning_note(wi, + "You have selected user tables with dispersion correction, the dispersion " + "will be corrected to -C6/r^6 beyond rvdw_switch (the tabulated interaction " + "between rvdw_switch and rvdw will not be double counted). Make sure that you " + "really want dispersion correction to -C6/r^6."); } - if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT) - && ir->rvdw != 0) + if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT) && ir->rvdw != 0) { warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off."); } @@ -1239,8 +1383,7 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi /* IMPLICIT SOLVENT */ if (ir->coulombtype == eelGB_NOTUSED) { - sprintf(warn_buf, "Invalid option %s for coulombtype", - eel_names[ir->coulombtype]); + sprintf(warn_buf, "Invalid option %s for coulombtype", eel_names[ir->coulombtype]); warning_error(wi, warn_buf); } @@ -1266,10 +1409,10 @@ void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifi str = the input string n = the (pre-allocated) number of doubles read r = the output array of doubles. */ -static void parse_n_real(char *str, int *n, real **r, warninp_t wi) +static void parse_n_real(char* str, int* n, real** r, warninp_t wi) { auto values = gmx::splitString(str); - *n = values.size(); + *n = values.size(); snew(*r, *n); for (int i = 0; i < *n; i++) @@ -1278,21 +1421,22 @@ static void parse_n_real(char *str, int *n, real **r, warninp_t wi) { (*r)[i] = gmx::fromString(values[i]); } - catch (gmx::GromacsException &) + catch (gmx::GromacsException&) { - warning_error(wi, "Invalid value " + values[i] + " in string in mdp file. Expected a real number."); + warning_error(wi, "Invalid value " + values[i] + + " in string in mdp file. Expected a real number."); } } } -static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi) +static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi) { int i, j, max_n_lambda, nweights, nfep[efptNR]; - t_lambda *fep = ir->fepvals; - t_expanded *expand = ir->expandedvals; - real **count_fep_lambdas; + t_lambda* fep = ir->fepvals; + t_expanded* expand = ir->expandedvals; + real** count_fep_lambdas; bool bOneLambda = TRUE; snew(count_fep_lambdas, efptNR); @@ -1313,8 +1457,8 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight { if (nfep[i] > max_n_lambda) { - max_n_lambda = nfep[i]; /* here's a nonzero one. All of them - must have the same number if its not zero.*/ + max_n_lambda = nfep[i]; /* here's a nonzero one. All of them + must have the same number if its not zero.*/ break; } } @@ -1327,15 +1471,17 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight } else if (nfep[i] == max_n_lambda) { - if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute the derivative with - respect to the temperature currently */ + if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute + the derivative with respect to the temperature currently */ { ir->fepvals->separate_dvdl[i] = TRUE; } } else { - gmx_fatal(FARGS, "Number of lambdas (%d) for FEP type %s not equal to number of other types (%d)", + gmx_fatal(FARGS, + "Number of lambdas (%d) for FEP type %s not equal to number of other types " + "(%d)", nfep[i], efpt_names[i], max_n_lambda); } } @@ -1357,8 +1503,8 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight for (i = 0; i < efptNR; i++) { snew(fep->all_lambda[i], fep->n_lambda); - if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays - are zero */ + if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays + are zero */ { for (j = 0; j < fep->n_lambda; j++) { @@ -1369,8 +1515,8 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight } sfree(count_fep_lambdas); - /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for internal - bookkeeping -- for now, init_lambda */ + /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for + internal bookkeeping -- for now, init_lambda */ if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0)) { @@ -1423,7 +1569,9 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight { if (fep->sc_alpha > 0.1) { - gmx_fatal(FARGS, "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", fep->sc_alpha); + gmx_fatal(FARGS, + "sc_alpha (%f) for sc_r_power = 48 should usually be between 0.001 and 0.004", + fep->sc_alpha); } } @@ -1446,78 +1594,84 @@ static void do_fep_params(t_inputrec *ir, char fep_lambda[][STRLEN], char weight } -static void do_simtemp_params(t_inputrec *ir) +static void do_simtemp_params(t_inputrec* ir) { snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda); GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]); } -static void -convertYesNos(warninp_t /*wi*/, gmx::ArrayRef inputs, const char * /*name*/, gmx_bool *outputs) +static void convertYesNos(warninp_t /*wi*/, + gmx::ArrayRef inputs, + const char* /*name*/, + gmx_bool* outputs) { int i = 0; - for (const auto &input : inputs) + for (const auto& input : inputs) { outputs[i] = gmx::equalCaseInsensitive(input, "Y", 1); ++i; } } -template void -convertInts(warninp_t wi, gmx::ArrayRef inputs, const char *name, T *outputs) +template +void convertInts(warninp_t wi, gmx::ArrayRef inputs, const char* name, T* outputs) { int i = 0; - for (const auto &input : inputs) + for (const auto& input : inputs) { try { outputs[i] = gmx::fromStdString(input); } - catch (gmx::GromacsException &) + catch (gmx::GromacsException&) { - auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of integers separated by spaces.", - name, name); + auto message = gmx::formatString( + "Invalid value for mdp option %s. %s should only consist of integers separated " + "by spaces.", + name, name); warning_error(wi, message); } ++i; } } -static void -convertReals(warninp_t wi, gmx::ArrayRef inputs, const char *name, real *outputs) +static void convertReals(warninp_t wi, gmx::ArrayRef inputs, const char* name, real* outputs) { int i = 0; - for (const auto &input : inputs) + for (const auto& input : inputs) { try { outputs[i] = gmx::fromString(input); } - catch (gmx::GromacsException &) + catch (gmx::GromacsException&) { - auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.", - name, name); + auto message = gmx::formatString( + "Invalid value for mdp option %s. %s should only consist of real numbers " + "separated by spaces.", + name, name); warning_error(wi, message); } ++i; } } -static void -convertRvecs(warninp_t wi, gmx::ArrayRef inputs, const char *name, rvec *outputs) +static void convertRvecs(warninp_t wi, gmx::ArrayRef inputs, const char* name, rvec* outputs) { int i = 0, d = 0; - for (const auto &input : inputs) + for (const auto& input : inputs) { try { outputs[i][d] = gmx::fromString(input); } - catch (gmx::GromacsException &) + catch (gmx::GromacsException&) { - auto message = gmx::formatString("Invalid value for mdp option %s. %s should only consist of real numbers separated by spaces.", - name, name); + auto message = gmx::formatString( + "Invalid value for mdp option %s. %s should only consist of real numbers " + "separated by spaces.", + name, name); warning_error(wi, message); } ++d; @@ -1529,10 +1683,7 @@ convertRvecs(warninp_t wi, gmx::ArrayRef inputs, const char * } } -static void do_wall_params(t_inputrec *ir, - char *wall_atomtype, char *wall_density, - t_gromppopts *opts, - warninp_t wi) +static void do_wall_params(t_inputrec* ir, char* wall_atomtype, char* wall_density, t_gromppopts* opts, warninp_t wi) { opts->wall_atomtype[0] = nullptr; opts->wall_atomtype[1] = nullptr; @@ -1547,8 +1698,8 @@ static void do_wall_params(t_inputrec *ir, auto wallAtomTypes = gmx::splitString(wall_atomtype); if (wallAtomTypes.size() != size_t(ir->nwall)) { - gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu", - ir->nwall, wallAtomTypes.size()); + gmx_fatal(FARGS, "Expected %d elements for wall_atomtype, found %zu", ir->nwall, + wallAtomTypes.size()); } for (int i = 0; i < ir->nwall; i++) { @@ -1560,7 +1711,8 @@ static void do_wall_params(t_inputrec *ir, auto wallDensity = gmx::splitString(wall_density); if (wallDensity.size() != size_t(ir->nwall)) { - gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, wallDensity.size()); + gmx_fatal(FARGS, "Expected %d elements for wall-density, found %zu", ir->nwall, + wallDensity.size()); } convertReals(wi, wallDensity, "wall-density", ir->wall_density); for (int i = 0; i < ir->nwall; i++) @@ -1574,24 +1726,20 @@ static void do_wall_params(t_inputrec *ir, } } -static void add_wall_energrps(SimulationGroups *groups, int nwall, t_symtab *symtab) +static void add_wall_energrps(SimulationGroups* groups, int nwall, t_symtab* symtab) { if (nwall > 0) { - AtomGroupIndices *grps = &(groups->groups[SimulationAtomGroupType::EnergyOutput]); + AtomGroupIndices* grps = &(groups->groups[SimulationAtomGroupType::EnergyOutput]); for (int i = 0; i < nwall; i++) { - groups->groupNames.emplace_back( - put_symtab( - symtab, - gmx::formatString("wall%d", i).c_str())); + groups->groupNames.emplace_back(put_symtab(symtab, gmx::formatString("wall%d", i).c_str())); grps->emplace_back(groups->groupNames.size() - 1); } } } -static void read_expandedparams(std::vector *inp, - t_expanded *expand, warninp_t wi) +static void read_expandedparams(std::vector* inp, t_expanded* expand, warninp_t wi) { /* read expanded ensemble parameters */ printStringNewline(inp, "expanded ensemble variables"); @@ -1605,19 +1753,20 @@ static void read_expandedparams(std::vector *inp, expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi); expand->equil_ratio = get_ereal(inp, "weight-equil-count-ratio", -1, wi); printStringNewline(inp, "Seed for Monte Carlo in lambda space"); - expand->lmc_seed = get_eint(inp, "lmc-seed", -1, wi); - expand->mc_temp = get_ereal(inp, "mc-temperature", -1, wi); - expand->lmc_repeats = get_eint(inp, "lmc-repeats", 1, wi); - expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi); - expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi); - expand->bSymmetrizedTMatrix = (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0); - expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi); - expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */ - expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */ - expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi); - expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi); - expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi); - expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0); + expand->lmc_seed = get_eint(inp, "lmc-seed", -1, wi); + expand->mc_temp = get_ereal(inp, "mc-temperature", -1, wi); + expand->lmc_repeats = get_eint(inp, "lmc-repeats", 1, wi); + expand->gibbsdeltalam = get_eint(inp, "lmc-gibbsdelta", -1, wi); + expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi); + expand->bSymmetrizedTMatrix = + (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0); + expand->nstTij = get_eint(inp, "nst-transition-matrix", -1, wi); + expand->minvarmin = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */ + expand->c_range = get_eint(inp, "weight-c-range", 0, wi); /* default is just C=0 */ + expand->wl_scale = get_ereal(inp, "wl-scale", 0.8, wi); + expand->wl_ratio = get_ereal(inp, "wl-ratio", 0.8, wi); + expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi); + expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0); } /*! \brief Return whether an end state with the given coupling-lambda @@ -1628,8 +1777,7 @@ static void read_expandedparams(std::vector *inp, */ static bool couple_lambda_has_vdw_on(int couple_lambda_value) { - return (couple_lambda_value == ecouplamVDW || - couple_lambda_value == ecouplamVDWQ); + return (couple_lambda_value == ecouplamVDW || couple_lambda_value == ecouplamVDWQ); } namespace @@ -1637,57 +1785,55 @@ namespace class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler { - public: - explicit MdpErrorHandler(warninp_t wi) - : wi_(wi), mapping_(nullptr) - { - } +public: + explicit MdpErrorHandler(warninp_t wi) : wi_(wi), mapping_(nullptr) {} - void setBackMapping(const gmx::IKeyValueTreeBackMapping &mapping) - { - mapping_ = &mapping; - } + void setBackMapping(const gmx::IKeyValueTreeBackMapping& mapping) { mapping_ = &mapping; } - bool onError(gmx::UserInputError *ex, const gmx::KeyValueTreePath &context) override - { - ex->prependContext(gmx::formatString("Error in mdp option \"%s\":", - getOptionName(context).c_str())); - std::string message = gmx::formatExceptionMessageToString(*ex); - warning_error(wi_, message.c_str()); - return true; - } + bool onError(gmx::UserInputError* ex, const gmx::KeyValueTreePath& context) override + { + ex->prependContext( + gmx::formatString("Error in mdp option \"%s\":", getOptionName(context).c_str())); + std::string message = gmx::formatExceptionMessageToString(*ex); + warning_error(wi_, message.c_str()); + return true; + } - private: - std::string getOptionName(const gmx::KeyValueTreePath &context) +private: + std::string getOptionName(const gmx::KeyValueTreePath& context) + { + if (mapping_ != nullptr) { - if (mapping_ != nullptr) - { - gmx::KeyValueTreePath path = mapping_->originalPath(context); - GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options"); - return path[0]; - } - GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing"); - return context[0]; + gmx::KeyValueTreePath path = mapping_->originalPath(context); + GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options"); + return path[0]; } + GMX_ASSERT(context.size() == 1, "Inconsistent context for mdp option parsing"); + return context[0]; + } - warninp_t wi_; - const gmx::IKeyValueTreeBackMapping *mapping_; + warninp_t wi_; + const gmx::IKeyValueTreeBackMapping* mapping_; }; } // namespace -void get_ir(const char *mdparin, const char *mdparout, - gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts, - WriteMdpHeader writeMdpHeader, warninp_t wi) +void get_ir(const char* mdparin, + const char* mdparout, + gmx::MDModules* mdModules, + t_inputrec* ir, + t_gromppopts* opts, + WriteMdpHeader writeMdpHeader, + warninp_t wi) { - char *dumstr[2]; - double dumdub[2][6]; - int i, j, m; - char warn_buf[STRLEN]; - t_lambda *fep = ir->fepvals; - t_expanded *expand = ir->expandedvals; + char* dumstr[2]; + double dumdub[2][6]; + int i, j, m; + char warn_buf[STRLEN]; + t_lambda* fep = ir->fepvals; + t_expanded* expand = ir->expandedvals; - const char *no_names[] = { "no", nullptr }; + const char* no_names[] = { "no", nullptr }; init_inputrec_strings(); gmx::TextInputFile stream(mdparin); @@ -1746,115 +1892,120 @@ void get_ir(const char *mdparin, const char *mdparout, printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS"); printStringNoNewline(&inp, "Preprocessor information: use cpp syntax."); printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe"); - setStringEntry(&inp, "include", opts->include, nullptr); - printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)"); - setStringEntry(&inp, "define", opts->define, nullptr); + setStringEntry(&inp, "include", opts->include, nullptr); + printStringNoNewline( + &inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)"); + setStringEntry(&inp, "define", opts->define, nullptr); printStringNewline(&inp, "RUN CONTROL PARAMETERS"); - ir->eI = get_eeenum(&inp, "integrator", ei_names, wi); + ir->eI = get_eeenum(&inp, "integrator", ei_names, wi); printStringNoNewline(&inp, "Start time and timestep in ps"); ir->init_t = get_ereal(&inp, "tinit", 0.0, wi); - ir->delta_t = get_ereal(&inp, "dt", 0.001, wi); - ir->nsteps = get_eint64(&inp, "nsteps", 0, wi); + ir->delta_t = get_ereal(&inp, "dt", 0.001, wi); + ir->nsteps = get_eint64(&inp, "nsteps", 0, wi); printStringNoNewline(&inp, "For exact run continuation or redoing part of a run"); - ir->init_step = get_eint64(&inp, "init-step", 0, wi); - printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)"); + ir->init_step = get_eint64(&inp, "init-step", 0, wi); + printStringNoNewline( + &inp, "Part index is updated automatically on checkpointing (keeps files separate)"); ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi); printStringNoNewline(&inp, "mode for center of mass motion removal"); - ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi); + ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi); printStringNoNewline(&inp, "number of steps for center of mass motion removal"); - ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi); + ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi); printStringNoNewline(&inp, "group(s) for center of mass motion removal"); - setStringEntry(&inp, "comm-grps", is->vcm, nullptr); + setStringEntry(&inp, "comm-grps", is->vcm, nullptr); printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS"); printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed"); - ir->bd_fric = get_ereal(&inp, "bd-fric", 0.0, wi); - ir->ld_seed = get_eint64(&inp, "ld-seed", -1, wi); + ir->bd_fric = get_ereal(&inp, "bd-fric", 0.0, wi); + ir->ld_seed = get_eint64(&inp, "ld-seed", -1, wi); /* Em stuff */ printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS"); printStringNoNewline(&inp, "Force tolerance and initial step-size"); - ir->em_tol = get_ereal(&inp, "emtol", 10.0, wi); + ir->em_tol = get_ereal(&inp, "emtol", 10.0, wi); ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi); printStringNoNewline(&inp, "Max number of iterations in relax-shells"); - ir->niter = get_eint(&inp, "niter", 20, wi); + ir->niter = get_eint(&inp, "niter", 20, wi); printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints"); ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi); printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG"); ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi); - ir->nbfgscorr = get_eint(&inp, "nbfgscorr", 10, wi); + ir->nbfgscorr = get_eint(&inp, "nbfgscorr", 10, wi); printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS"); - ir->rtpi = get_ereal(&inp, "rtpi", 0.05, wi); + ir->rtpi = get_ereal(&inp, "rtpi", 0.05, wi); /* Output options */ printStringNewline(&inp, "OUTPUT CONTROL OPTIONS"); printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)"); - ir->nstxout = get_eint(&inp, "nstxout", 0, wi); - ir->nstvout = get_eint(&inp, "nstvout", 0, wi); - ir->nstfout = get_eint(&inp, "nstfout", 0, wi); + ir->nstxout = get_eint(&inp, "nstxout", 0, wi); + ir->nstvout = get_eint(&inp, "nstvout", 0, wi); + ir->nstfout = get_eint(&inp, "nstfout", 0, wi); printStringNoNewline(&inp, "Output frequency for energies to log file and energy file"); ir->nstlog = get_eint(&inp, "nstlog", 1000, wi); ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi); - ir->nstenergy = get_eint(&inp, "nstenergy", 1000, wi); + ir->nstenergy = get_eint(&inp, "nstenergy", 1000, wi); printStringNoNewline(&inp, "Output frequency and precision for .xtc file"); - ir->nstxout_compressed = get_eint(&inp, "nstxout-compressed", 0, wi); + ir->nstxout_compressed = get_eint(&inp, "nstxout-compressed", 0, wi); ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi); printStringNoNewline(&inp, "This selects the subset of atoms for the compressed"); printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By"); printStringNoNewline(&inp, "default, all atoms will be written."); setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr); printStringNoNewline(&inp, "Selection of energy groups"); - setStringEntry(&inp, "energygrps", is->energy, nullptr); + setStringEntry(&inp, "energygrps", is->energy, nullptr); /* Neighbor searching */ printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS"); - printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)"); - ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi); + printStringNoNewline( + &inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)"); + ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi); printStringNoNewline(&inp, "nblist update frequency"); - ir->nstlist = get_eint(&inp, "nstlist", 10, wi); + ir->nstlist = get_eint(&inp, "nstlist", 10, wi); printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy"); - ir->ePBC = get_eeenum(&inp, "pbc", epbc_names, wi); + ir->ePBC = get_eeenum(&inp, "pbc", epbc_names, wi); ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0; - printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,"); + printStringNoNewline(&inp, + "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,"); printStringNoNewline(&inp, "a value of -1 means: use rlist"); - ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance", 0.005, wi); + ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance", 0.005, wi); printStringNoNewline(&inp, "nblist cut-off"); - ir->rlist = get_ereal(&inp, "rlist", 1.0, wi); + ir->rlist = get_ereal(&inp, "rlist", 1.0, wi); printStringNoNewline(&inp, "long-range cut-off for switched potentials"); /* Electrostatics */ printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW"); printStringNoNewline(&inp, "Method for doing electrostatics"); - ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi); - ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi); + ir->coulombtype = get_eeenum(&inp, "coulombtype", eel_names, wi); + ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi); printStringNoNewline(&inp, "cut-off lengths"); - ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi); - ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi); - printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field"); - ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi); + ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi); + ir->rcoulomb = get_ereal(&inp, "rcoulomb", 1.0, wi); + printStringNoNewline(&inp, + "Relative dielectric constant for the medium and the reaction field"); + ir->epsilon_r = get_ereal(&inp, "epsilon-r", 1.0, wi); ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi); printStringNoNewline(&inp, "Method for doing Van der Waals"); - ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi); - ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi); + ir->vdwtype = get_eeenum(&inp, "vdw-type", evdw_names, wi); + ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi); printStringNoNewline(&inp, "cut-off lengths"); - ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi); - ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi); + ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi); + ir->rvdw = get_ereal(&inp, "rvdw", 1.0, wi); printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure"); - ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi); + ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi); printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off"); ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi); printStringNoNewline(&inp, "Separate tables between energy group pairs"); - setStringEntry(&inp, "energygrp-table", is->egptable, nullptr); + setStringEntry(&inp, "energygrp-table", is->egptable, nullptr); printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid"); ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi); printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used"); - ir->nkx = get_eint(&inp, "fourier-nx", 0, wi); - ir->nky = get_eint(&inp, "fourier-ny", 0, wi); - ir->nkz = get_eint(&inp, "fourier-nz", 0, wi); + ir->nkx = get_eint(&inp, "fourier-nx", 0, wi); + ir->nky = get_eint(&inp, "fourier-ny", 0, wi); + ir->nkz = get_eint(&inp, "fourier-nz", 0, wi); printStringNoNewline(&inp, "EWALD/PME/PPPM parameters"); - ir->pme_order = get_eint(&inp, "pme-order", 4, wi); + ir->pme_order = get_eint(&inp, "pme-order", 4, wi); ir->ewald_rtol = get_ereal(&inp, "ewald-rtol", 0.00001, wi); ir->ewald_rtol_lj = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi); ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi); @@ -1869,23 +2020,23 @@ void get_ir(const char *mdparin, const char *mdparout, /* Coupling stuff */ printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS"); printStringNoNewline(&inp, "Temperature coupling"); - ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi); - ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi); + ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi); + ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi); ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi); - ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0); + ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0); printStringNoNewline(&inp, "Groups to couple separately"); - setStringEntry(&inp, "tc-grps", is->tcgrps, nullptr); + setStringEntry(&inp, "tc-grps", is->tcgrps, nullptr); printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)"); - setStringEntry(&inp, "tau-t", is->tau_t, nullptr); - setStringEntry(&inp, "ref-t", is->ref_t, nullptr); + setStringEntry(&inp, "tau-t", is->tau_t, nullptr); + setStringEntry(&inp, "ref-t", is->ref_t, nullptr); printStringNoNewline(&inp, "pressure coupling"); - ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi); - ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi); - ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi); + ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi); + ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi); + ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi); printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)"); - ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi); - setStringEntry(&inp, "compressibility", dumstr[0], nullptr); - setStringEntry(&inp, "ref-p", dumstr[1], nullptr); + ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi); + setStringEntry(&inp, "compressibility", dumstr[0], nullptr); + setStringEntry(&inp, "ref-p", dumstr[1], nullptr); printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM"); ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi); @@ -1893,22 +2044,22 @@ void get_ir(const char *mdparin, const char *mdparout, printStringNewline(&inp, "OPTIONS FOR QMMM calculations"); ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0); printStringNoNewline(&inp, "Groups treated Quantum Mechanically"); - setStringEntry(&inp, "QMMM-grps", is->QMMM, nullptr); + setStringEntry(&inp, "QMMM-grps", is->QMMM, nullptr); printStringNoNewline(&inp, "QM method"); - setStringEntry(&inp, "QMmethod", is->QMmethod, nullptr); + setStringEntry(&inp, "QMmethod", is->QMmethod, nullptr); printStringNoNewline(&inp, "QMMM scheme"); - ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme", eQMMMscheme_names, wi); + ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme", eQMMMscheme_names, wi); printStringNoNewline(&inp, "QM basisset"); - setStringEntry(&inp, "QMbasis", is->QMbasis, nullptr); + setStringEntry(&inp, "QMbasis", is->QMbasis, nullptr); printStringNoNewline(&inp, "QM charge"); - setStringEntry(&inp, "QMcharge", is->QMcharge, nullptr); + setStringEntry(&inp, "QMcharge", is->QMcharge, nullptr); printStringNoNewline(&inp, "QM multiplicity"); - setStringEntry(&inp, "QMmult", is->QMmult, nullptr); + setStringEntry(&inp, "QMmult", is->QMmult, nullptr); printStringNoNewline(&inp, "Surface Hopping"); - setStringEntry(&inp, "SH", is->bSH, nullptr); + setStringEntry(&inp, "SH", is->bSH, nullptr); printStringNoNewline(&inp, "CAS space options"); - setStringEntry(&inp, "CASorbitals", is->CASorbitals, nullptr); - setStringEntry(&inp, "CASelectrons", is->CASelectrons, nullptr); + setStringEntry(&inp, "CASorbitals", is->CASorbitals, nullptr); + setStringEntry(&inp, "CASelectrons", is->CASelectrons, nullptr); setStringEntry(&inp, "SAon", is->SAon, nullptr); setStringEntry(&inp, "SAoff", is->SAoff, nullptr); setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr); @@ -1918,28 +2069,30 @@ void get_ir(const char *mdparin, const char *mdparout, /* Simulated annealing */ printStringNewline(&inp, "SIMULATED ANNEALING"); printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)"); - setStringEntry(&inp, "annealing", is->anneal, nullptr); - printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group"); + setStringEntry(&inp, "annealing", is->anneal, nullptr); + printStringNoNewline(&inp, + "Number of time points to use for specifying annealing in each group"); setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr); printStringNoNewline(&inp, "List of times at the annealing points for each group"); - setStringEntry(&inp, "annealing-time", is->anneal_time, nullptr); + setStringEntry(&inp, "annealing-time", is->anneal_time, nullptr); printStringNoNewline(&inp, "Temp. at each annealing point, for each group."); - setStringEntry(&inp, "annealing-temp", is->anneal_temp, nullptr); + setStringEntry(&inp, "annealing-temp", is->anneal_temp, nullptr); /* Startup run */ printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN"); - opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0); - opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi); - opts->seed = get_eint(&inp, "gen-seed", -1, wi); + opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0); + opts->tempi = get_ereal(&inp, "gen-temp", 300.0, wi); + opts->seed = get_eint(&inp, "gen-seed", -1, wi); /* Shake stuff */ printStringNewline(&inp, "OPTIONS FOR BONDS"); - opts->nshake = get_eeenum(&inp, "constraints", constraints, wi); + opts->nshake = get_eeenum(&inp, "constraints", constraints, wi); printStringNoNewline(&inp, "Type of constraint algorithm"); ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi); printStringNoNewline(&inp, "Do not constrain the start configuration"); ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0); - printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations"); + printStringNoNewline(&inp, + "Use successive overrelaxation to reduce the number of shake iterations"); ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0); printStringNoNewline(&inp, "Relative tolerance of shake"); ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi); @@ -1957,17 +2110,19 @@ void get_ir(const char *mdparin, const char *mdparout, /* Energy group exclusions */ printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS"); - printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded"); - setStringEntry(&inp, "energygrp-excl", is->egpexcl, nullptr); + printStringNoNewline( + &inp, "Pairs of energy groups for which all non-bonded interactions are excluded"); + setStringEntry(&inp, "energygrp-excl", is->egpexcl, nullptr); /* Walls */ printStringNewline(&inp, "WALLS"); - printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald"); + printStringNoNewline( + &inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald"); ir->nwall = get_eint(&inp, "nwall", 0, wi); - ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi); + ir->wall_type = get_eeenum(&inp, "wall-type", ewt_names, wi); ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi); setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr); - setStringEntry(&inp, "wall-density", is->wall_density, nullptr); + setStringEntry(&inp, "wall-density", is->wall_density, nullptr); ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi); /* COM pulling */ @@ -2018,35 +2173,36 @@ void get_ir(const char *mdparin, const char *mdparout, /* Refinement */ printStringNewline(&inp, "NMR refinement stuff"); printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble"); - ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi); - printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal"); + ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi); + printStringNoNewline( + &inp, "Force weighting of pairs in one distance restraint: Conservative or Equal"); ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi); printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation"); ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0); - ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi); + ir->dr_fc = get_ereal(&inp, "disre-fc", 1000.0, wi); ir->dr_tau = get_ereal(&inp, "disre-tau", 0.0, wi); printStringNoNewline(&inp, "Output frequency for pair distances to energy file"); ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi); printStringNoNewline(&inp, "Orientation restraints: No or Yes"); - opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0); + opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0); printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging"); - ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi); + ir->orires_fc = get_ereal(&inp, "orire-fc", 0.0, wi); ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi); - setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp, nullptr); + setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp, nullptr); printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file"); ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi); /* free energy variables */ printStringNewline(&inp, "Free energy variables"); ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi); - setStringEntry(&inp, "couple-moltype", is->couple_moltype, nullptr); + setStringEntry(&inp, "couple-moltype", is->couple_moltype, nullptr); opts->couple_lam0 = get_eeenum(&inp, "couple-lambda0", couple_lam, wi); opts->couple_lam1 = get_eeenum(&inp, "couple-lambda1", couple_lam, wi); opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0); - fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so - we can recognize if - it was not entered */ + fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so + we can recognize if + it was not entered */ fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi); fep->delta_lambda = get_ereal(&inp, "delta-lambda", 0.0, wi); fep->nstdhdl = get_eint(&inp, "nstdhdl", 50, wi); @@ -2074,19 +2230,19 @@ void get_ir(const char *mdparin, const char *mdparout, /* Non-equilibrium MD stuff */ printStringNewline(&inp, "Non-equilibrium MD stuff"); - setStringEntry(&inp, "acc-grps", is->accgrps, nullptr); - setStringEntry(&inp, "accelerate", is->acc, nullptr); - setStringEntry(&inp, "freezegrps", is->freeze, nullptr); - setStringEntry(&inp, "freezedim", is->frdim, nullptr); + setStringEntry(&inp, "acc-grps", is->accgrps, nullptr); + setStringEntry(&inp, "accelerate", is->acc, nullptr); + setStringEntry(&inp, "freezegrps", is->freeze, nullptr); + setStringEntry(&inp, "freezedim", is->frdim, nullptr); ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi); - setStringEntry(&inp, "deform", is->deform, nullptr); + setStringEntry(&inp, "deform", is->deform, nullptr); /* simulated tempering variables */ printStringNewline(&inp, "simulated tempering variables"); - ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0); + ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0); ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi); - ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi); - ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi); + ir->simtempvals->simtemp_low = get_ereal(&inp, "sim-temp-low", 300.0, wi); + ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi); /* expanded ensemble variables */ if (ir->efep == efepEXPANDED || ir->bSimTemp) @@ -2098,25 +2254,24 @@ void get_ir(const char *mdparin, const char *mdparout, { gmx::KeyValueTreeObject convertedValues = flatKeyValueTreeFromInpFile(inp); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive); + transform.rules()->addRule().keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive); mdModules->initMdpTransform(transform.rules()); - for (const auto &path : transform.mappedPaths()) + for (const auto& path : transform.mappedPaths()) { GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options"); mark_einp_set(inp, path[0].c_str()); } - MdpErrorHandler errorHandler(wi); - auto result - = transform.transform(convertedValues, &errorHandler); - ir->params = new gmx::KeyValueTreeObject(result.object()); + MdpErrorHandler errorHandler(wi); + auto result = transform.transform(convertedValues, &errorHandler); + ir->params = new gmx::KeyValueTreeObject(result.object()); mdModules->adjustInputrecBasedOnModules(ir); errorHandler.setBackMapping(result.backMapping()); mdModules->assignOptionsToModules(*ir->params, &errorHandler); } /* Ion/water position swapping ("computational electrophysiology") */ - printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups"); + printStringNewline(&inp, + "Ion/water position swapping for computational electrophysiology setups"); printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z"); ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi); if (ir->eSwapCoords != eswapNO) @@ -2140,19 +2295,28 @@ void get_ir(const char *mdparin, const char *mdparout, { snew(ir->swap->grp[i].molname, STRLEN); } - printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms"); + printStringNoNewline(&inp, + "Two index groups that contain the compartment-partitioning atoms"); setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr); setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr); - printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used"); + printStringNoNewline(&inp, + "Use center of mass of split groups (yes/no), otherwise center of " + "geometry is used"); ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0); ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0); printStringNoNewline(&inp, "Name of solvent molecules"); setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr); - printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)"); - printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,"); - printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel"); + printStringNoNewline(&inp, + "Split cylinder: radius, upper and lower extension (nm) (this will " + "define the channels)"); + printStringNoNewline(&inp, + "Note that the split cylinder settings do not have an influence on " + "the swapping protocol,"); + printStringNoNewline( + &inp, + "however, if correctly defined, the permeation events are recorded per channel"); ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi); ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi); ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi); @@ -2160,11 +2324,15 @@ void get_ir(const char *mdparin, const char *mdparout, ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi); ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi); - printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps"); + printStringNoNewline( + &inp, + "Average the number of ions per compartment over these many swap attempt steps"); ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi); - printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,"); - printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B"); + printStringNoNewline( + &inp, "Names of the ion types that can be exchanged with solvent molecules,"); + printStringNoNewline( + &inp, "and the requested number of ions of this type in compartments A and B"); printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0"); for (i = 0; i < nIonTypes; i++) { @@ -2178,19 +2346,27 @@ void get_ir(const char *mdparin, const char *mdparout, ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi); } - printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers"); - printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,"); - printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0"); - printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0)."); + printStringNoNewline( + &inp, + "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers"); + printStringNoNewline( + &inp, + "at maximum distance (= bulk concentration) to the split group layers. However,"); + printStringNoNewline(&inp, + "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk " + "layer from the middle at 0.0"); + printStringNoNewline(&inp, + "towards one of the compartment-partitioning layers (at +/- 1.0)."); ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi); ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi); if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0) - || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) ) + || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0)) { warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !"); } - printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached"); + printStringNoNewline( + &inp, "Start to swap ions if threshold difference to requested count is reached"); ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi); } @@ -2200,16 +2376,16 @@ void get_ir(const char *mdparin, const char *mdparout, /* User defined thingies */ printStringNewline(&inp, "User defined thingies"); - setStringEntry(&inp, "user1-grps", is->user1, nullptr); - setStringEntry(&inp, "user2-grps", is->user2, nullptr); - ir->userint1 = get_eint(&inp, "userint1", 0, wi); - ir->userint2 = get_eint(&inp, "userint2", 0, wi); - ir->userint3 = get_eint(&inp, "userint3", 0, wi); - ir->userint4 = get_eint(&inp, "userint4", 0, wi); - ir->userreal1 = get_ereal(&inp, "userreal1", 0, wi); - ir->userreal2 = get_ereal(&inp, "userreal2", 0, wi); - ir->userreal3 = get_ereal(&inp, "userreal3", 0, wi); - ir->userreal4 = get_ereal(&inp, "userreal4", 0, wi); + setStringEntry(&inp, "user1-grps", is->user1, nullptr); + setStringEntry(&inp, "user2-grps", is->user2, nullptr); + ir->userint1 = get_eint(&inp, "userint1", 0, wi); + ir->userint2 = get_eint(&inp, "userint2", 0, wi); + ir->userint3 = get_eint(&inp, "userint3", 0, wi); + ir->userint4 = get_eint(&inp, "userint4", 0, wi); + ir->userreal1 = get_ereal(&inp, "userreal1", 0, wi); + ir->userreal2 = get_ereal(&inp, "userreal2", 0, wi); + ir->userreal3 = get_ereal(&inp, "userreal3", 0, wi); + ir->userreal4 = get_ereal(&inp, "userreal4", 0, wi); #undef CTYPE { @@ -2230,7 +2406,7 @@ void get_ir(const char *mdparin, const char *mdparout, /* Process options if necessary */ for (m = 0; m < 2; m++) { - for (i = 0; i < 2*DIM; i++) + for (i = 0; i < 2 * DIM; i++) { dumdub[m][i] = 0.0; } @@ -2241,7 +2417,9 @@ void get_ir(const char *mdparin, const char *mdparout, case epctISOTROPIC: if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1) { - warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 1)"); + warning_error( + wi, + "Pressure coupling incorrect number of values (I need exactly 1)"); } dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX]; break; @@ -2249,16 +2427,20 @@ void get_ir(const char *mdparin, const char *mdparout, case epctSURFACETENSION: if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2) { - warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 2)"); + warning_error( + wi, + "Pressure coupling incorrect number of values (I need exactly 2)"); } dumdub[m][YY] = dumdub[m][XX]; break; case epctANISOTROPIC: - if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf", - &(dumdub[m][XX]), &(dumdub[m][YY]), &(dumdub[m][ZZ]), - &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) != 6) + if (sscanf(dumstr[m], "%lf%lf%lf%lf%lf%lf", &(dumdub[m][XX]), &(dumdub[m][YY]), + &(dumdub[m][ZZ]), &(dumdub[m][3]), &(dumdub[m][4]), &(dumdub[m][5])) + != 6) { - warning_error(wi, "Pressure coupling incorrect number of values (I need exactly 6)"); + warning_error( + wi, + "Pressure coupling incorrect number of values (I need exactly 6)"); } break; default: @@ -2281,7 +2463,9 @@ void get_ir(const char *mdparin, const char *mdparout, ir->ref_p[YY][ZZ] = dumdub[1][5]; if (ir->ref_p[XX][YY] != 0 && ir->ref_p[XX][ZZ] != 0 && ir->ref_p[YY][ZZ] != 0) { - warning(wi, "All off-diagonal reference pressures are non-zero. Are you sure you want to apply a threefold shear stress?\n"); + warning(wi, + "All off-diagonal reference pressures are non-zero. Are you sure you want to " + "apply a threefold shear stress?\n"); } ir->compress[XX][YY] = dumdub[0][3]; ir->compress[XX][ZZ] = dumdub[0][4]; @@ -2311,15 +2495,18 @@ void get_ir(const char *mdparin, const char *mdparout, { warning(wi, "The lambda=0 and lambda=1 states for coupling are identical"); } - if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE || - opts->couple_lam1 == ecouplamNONE)) + if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam1 == ecouplamNONE)) { - warning(wi, "For proper sampling of the (nearly) decoupled state, stochastic dynamics should be used"); + warning(wi, + "For proper sampling of the (nearly) decoupled state, stochastic dynamics " + "should be used"); } } else { - warning_note(wi, "Free energy is turned off, so we will not decouple the molecule listed in your input."); + warning_note(wi, + "Free energy is turned off, so we will not decouple the molecule listed " + "in your input."); } } /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */ @@ -2334,7 +2521,8 @@ void get_ir(const char *mdparin, const char *mdparout, if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES) { fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL; - warning_note(wi, "Old option for dhdl-print-energy given: " + warning_note(wi, + "Old option for dhdl-print-energy given: " "changing \"yes\" to \"total\"\n"); } @@ -2371,12 +2559,14 @@ void get_ir(const char *mdparin, const char *mdparout, * If the (advanced) user does FEP through manual topology changes, * this check will not be triggered. */ - if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 && - ir->fepvals->sc_alpha != 0 && - (couple_lambda_has_vdw_on(opts->couple_lam0) && - couple_lambda_has_vdw_on(opts->couple_lam1))) + if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 && ir->fepvals->sc_alpha != 0 + && (couple_lambda_has_vdw_on(opts->couple_lam0) && couple_lambda_has_vdw_on(opts->couple_lam1))) { - warning(wi, "You are using soft-core interactions while the Van der Waals interactions are not decoupled (note that the sc-coul option is only active when using lambda states). Although this will not lead to errors, you will need much more sampling than without soft-core interactions. Consider using sc-alpha=0."); + warning(wi, + "You are using soft-core interactions while the Van der Waals interactions are " + "not decoupled (note that the sc-coul option is only active when using lambda " + "states). Although this will not lead to errors, you will need much more " + "sampling than without soft-core interactions. Consider using sc-alpha=0."); } } else @@ -2404,13 +2594,15 @@ void get_ir(const char *mdparin, const char *mdparout, } double gmx_unused canary; - int ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf", - &(dumdub[0][0]), &(dumdub[0][1]), &(dumdub[0][2]), - &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary); + int ndeform = sscanf(is->deform, "%lf %lf %lf %lf %lf %lf %lf", &(dumdub[0][0]), &(dumdub[0][1]), + &(dumdub[0][2]), &(dumdub[0][3]), &(dumdub[0][4]), &(dumdub[0][5]), &canary); if (strlen(is->deform) > 0 && ndeform != 6) { - warning_error(wi, gmx::formatString("Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform).c_str()); + warning_error( + wi, gmx::formatString( + "Cannot parse exactly 6 box deformation velocities from string '%s'", is->deform) + .c_str()); } for (i = 0; i < 3; i++) { @@ -2441,7 +2633,10 @@ void get_ir(const char *mdparin, const char *mdparout, { if (ir->compress[m][j] != 0) { - sprintf(warn_buf, "An off-diagonal box element has deform set while compressibility > 0 for the same component of another box vector, this might lead to spurious periodicity effects."); + sprintf(warn_buf, + "An off-diagonal box element has deform set while " + "compressibility > 0 for the same component of another box " + "vector, this might lead to spurious periodicity effects."); warning(wi, warn_buf); } } @@ -2471,7 +2666,7 @@ void get_ir(const char *mdparin, const char *mdparout, sfree(dumstr[1]); } -static int search_QMstring(const char *s, int ng, const char *gn[]) +static int search_QMstring(const char* s, int ng, const char* gn[]) { /* same as normal search_string, but this one searches QM strings */ int i; @@ -2491,7 +2686,7 @@ static int search_QMstring(const char *s, int ng, const char *gn[]) /* TODO this is utility functionality (search for the index of a string in a collection), so should be refactored and located more centrally. */ -int search_string(const char *s, int ng, char *gn[]) +int search_string(const char* s, int ng, char* gn[]) { int i; @@ -2511,19 +2706,23 @@ int search_string(const char *s, int ng, char *gn[]) s); } -static bool do_numbering(int natoms, SimulationGroups *groups, +static bool do_numbering(int natoms, + SimulationGroups* groups, gmx::ArrayRef groupsFromMdpFile, - t_blocka *block, char *gnames[], - SimulationAtomGroupType gtype, int restnm, - int grptp, bool bVerbose, - warninp_t wi) + t_blocka* block, + char* gnames[], + SimulationAtomGroupType gtype, + int restnm, + int grptp, + bool bVerbose, + warninp_t wi) { - unsigned short *cbuf; - AtomGroupIndices *grps = &(groups->groups[gtype]); - int j, gid, aj, ognr, ntot = 0; - const char *title; - bool bRest; - char warn_buf[STRLEN]; + unsigned short* cbuf; + AtomGroupIndices* grps = &(groups->groups[gtype]); + int j, gid, aj, ognr, ntot = 0; + const char* title; + bool bRest; + char warn_buf[STRLEN]; title = shortName(gtype); @@ -2544,7 +2743,7 @@ static bool do_numbering(int natoms, SimulationGroups *groups, } /* Now go over the atoms in the group */ - for (j = block->index[gid]; (j < block->index[gid+1]); j++) + for (j = block->index[gid]; (j < block->index[gid + 1]); j++) { aj = block->a[j]; @@ -2558,8 +2757,8 @@ static bool do_numbering(int natoms, SimulationGroups *groups, ognr = cbuf[aj]; if (ognr != NOGID) { - gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", - aj+1, title, ognr+1, i+1); + gmx_fatal(FARGS, "Atom %d in multiple %s groups (%d and %d)", aj + 1, title, + ognr + 1, i + 1); } else { @@ -2583,13 +2782,11 @@ static bool do_numbering(int natoms, SimulationGroups *groups, { if (grptp == egrptpALL) { - gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups", - natoms-ntot, title); + gmx_fatal(FARGS, "%d atoms are not part of any of the %s groups", natoms - ntot, title); } else if (grptp == egrptpPART) { - sprintf(warn_buf, "%d atoms are not part of any of the %s groups", - natoms-ntot, title); + sprintf(warn_buf, "%d atoms are not part of any of the %s groups", natoms - ntot, title); warning_note(wi, warn_buf); } /* Assign all atoms currently unassigned to a rest group */ @@ -2605,9 +2802,8 @@ static bool do_numbering(int natoms, SimulationGroups *groups, { if (bVerbose) { - fprintf(stderr, - "Making dummy/rest group for %s containing %d elements\n", - title, natoms-ntot); + fprintf(stderr, "Making dummy/rest group for %s containing %d elements\n", title, + natoms - ntot); } /* Add group name "rest" */ grps->emplace_back(restnm); @@ -2642,15 +2838,15 @@ static bool do_numbering(int natoms, SimulationGroups *groups, return (bRest && grptp == egrptpPART); } -static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) +static void calc_nrdf(const gmx_mtop_t* mtop, t_inputrec* ir, char** gnames) { - t_grpopts *opts; - pull_params_t *pull; - int natoms, imin, jmin; - int *nrdf2, *na_vcm, na_tot; - double *nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub; - ivec *dof_vcm; - int as; + t_grpopts* opts; + pull_params_t* pull; + int natoms, imin, jmin; + int * nrdf2, *na_vcm, na_tot; + double * nrdf_tc, *nrdf_vcm, nrdf_uc, *nrdf_vcm_sub; + ivec* dof_vcm; + int as; /* Calculate nrdf. * First calc 3xnr-atoms for each group @@ -2661,26 +2857,27 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) opts = &ir->opts; - const SimulationGroups &groups = mtop->groups; - natoms = mtop->natoms; + const SimulationGroups& groups = mtop->groups; + natoms = mtop->natoms; /* Allocate one more for a possible rest group */ /* We need to sum degrees of freedom into doubles, * since floats give too low nrdf's above 3 million atoms. */ - snew(nrdf_tc, groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()+1); - snew(nrdf_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1); - snew(dof_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1); - snew(na_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1); - snew(nrdf_vcm_sub, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size()+1); + snew(nrdf_tc, groups.groups[SimulationAtomGroupType::TemperatureCoupling].size() + 1); + snew(nrdf_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size() + 1); + snew(dof_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size() + 1); + snew(na_vcm, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size() + 1); + snew(nrdf_vcm_sub, groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size() + 1); for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++) { nrdf_tc[i] = 0; } - for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; i++) + for (gmx::index i = 0; + i < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; i++) { - nrdf_vcm[i] = 0; + nrdf_vcm[i] = 0; clear_ivec(dof_vcm[i]); na_vcm[i] = 0; nrdf_vcm_sub[i] = 0; @@ -2688,9 +2885,9 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) snew(nrdf2, natoms); for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); - nrdf2[i] = 0; + nrdf2[i] = 0; if (local.ptype == eptAtom || local.ptype == eptNucleus) { int g = getGroupType(groups, SimulationAtomGroupType::Freeze, i); @@ -2699,27 +2896,30 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) if (opts->nFreeze[g][d] == 0) { /* Add one DOF for particle i (counted as 2*1) */ - nrdf2[i] += 2; + nrdf2[i] += 2; /* VCM group i has dim d as a DOF */ - dof_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)][d] = 1; + dof_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)][d] = + 1; } } - nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, i)] += 0.5*nrdf2[i]; - nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)] += 0.5*nrdf2[i]; + nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, i)] += + 0.5 * nrdf2[i]; + nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, i)] += + 0.5 * nrdf2[i]; } } as = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const gmx_moltype_t &molt = mtop->moltype[molb.type]; - const t_atom *atom = molt.atoms.atom; + const gmx_moltype_t& molt = mtop->moltype[molb.type]; + const t_atom* atom = molt.atoms.atom; for (int mol = 0; mol < molb.nmol; mol++) { for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++) { gmx::ArrayRef ia = molt.ilist[ftype].iatoms; - for (int i = 0; i < molt.ilist[ftype].size(); ) + for (int i = 0; i < molt.ilist[ftype].size();) { /* Subtract degrees of freedom for the constraints, * if the particles still have degrees of freedom left. @@ -2730,10 +2930,8 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) */ int ai = as + ia[i + 1]; int aj = as + ia[i + 2]; - if (((atom[ia[i + 1]].ptype == eptNucleus) || - (atom[ia[i + 1]].ptype == eptAtom)) && - ((atom[ia[i + 2]].ptype == eptNucleus) || - (atom[ia[i + 2]].ptype == eptAtom))) + if (((atom[ia[i + 1]].ptype == eptNucleus) || (atom[ia[i + 1]].ptype == eptAtom)) + && ((atom[ia[i + 2]].ptype == eptNucleus) || (atom[ia[i + 2]].ptype == eptAtom))) { if (nrdf2[ai] > 0) { @@ -2751,31 +2949,37 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) { imin = 2; } - imin = std::min(imin, nrdf2[ai]); - jmin = std::min(jmin, nrdf2[aj]); + imin = std::min(imin, nrdf2[ai]); + jmin = std::min(jmin, nrdf2[aj]); nrdf2[ai] -= imin; nrdf2[aj] -= jmin; - nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin; - nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, aj)] -= 0.5*jmin; - nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin; - nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, aj)] -= 0.5*jmin; + nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= + 0.5 * imin; + nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, aj)] -= + 0.5 * jmin; + nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= + 0.5 * imin; + nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, aj)] -= + 0.5 * jmin; } - i += interaction_function[ftype].nratoms+1; + i += interaction_function[ftype].nratoms + 1; } } gmx::ArrayRef ia = molt.ilist[F_SETTLE].iatoms; - for (int i = 0; i < molt.ilist[F_SETTLE].size(); ) + for (int i = 0; i < molt.ilist[F_SETTLE].size();) { /* Subtract 1 dof from every atom in the SETTLE */ for (int j = 0; j < 3; j++) { - int ai = as + ia[i + 1 + j]; - imin = std::min(2, nrdf2[ai]); + int ai = as + ia[i + 1 + j]; + imin = std::min(2, nrdf2[ai]); nrdf2[ai] -= imin; - nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin; - nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin; + nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= + 0.5 * imin; + nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= + 0.5 * imin; } - i += 4; + i += 4; } as += molt.atoms.nr; } @@ -2802,7 +3006,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) for (int j = 0; j < 2; j++) { - const t_pull_group *pgrp; + const t_pull_group* pgrp; pgrp = &pull->group[pull->coord[i].group[j]]; @@ -2810,11 +3014,17 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) { /* Subtract 1/2 dof from each group */ int ai = pgrp->ind[0]; - nrdf_tc [getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= 0.5*imin; - nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= 0.5*imin; + nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] -= + 0.5 * imin; + nrdf_vcm[getGroupType(groups, SimulationAtomGroupType::MassCenterVelocityRemoval, ai)] -= + 0.5 * imin; if (nrdf_tc[getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)] < 0) { - gmx_fatal(FARGS, "Center of mass pulling constraints caused the number of degrees of freedom for temperature coupling group %s to be negative", gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][getGroupType(groups, SimulationAtomGroupType::TemperatureCoupling, ai)]]); + gmx_fatal(FARGS, + "Center of mass pulling constraints caused the number of degrees " + "of freedom for temperature coupling group %s to be negative", + gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][getGroupType( + groups, SimulationAtomGroupType::TemperatureCoupling, ai)]]); } } else @@ -2837,7 +3047,8 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) * the number of degrees of freedom in each vcm group when COM * translation is removed and 6 when rotation is removed as well. */ - for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++) + for (gmx::index j = 0; + j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++) { switch (ir->comm_mode) { @@ -2852,18 +3063,17 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) } } break; - case ecmANGULAR: - nrdf_vcm_sub[j] = 6; - break; - default: - gmx_incons("Checking comm_mode"); + case ecmANGULAR: nrdf_vcm_sub[j] = 6; break; + default: gmx_incons("Checking comm_mode"); } } - for (gmx::index i = 0; i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++) + for (gmx::index i = 0; + i < gmx::ssize(groups.groups[SimulationAtomGroupType::TemperatureCoupling]); i++) { /* Count the number of atoms of TC group i for every VCM group */ - for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++) + for (gmx::index j = 0; + j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++) { na_vcm[j] = 0; } @@ -2881,12 +3091,13 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) */ nrdf_uc = nrdf_tc[i]; nrdf_tc[i] = 0; - for (gmx::index j = 0; j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval])+1; j++) + for (gmx::index j = 0; + j < gmx::ssize(groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval]) + 1; j++) { if (nrdf_vcm[j] > nrdf_vcm_sub[j]) { - nrdf_tc[i] += nrdf_uc*(static_cast(na_vcm[j])/static_cast(na_tot))* - (nrdf_vcm[j] - nrdf_vcm_sub[j])/nrdf_vcm[j]; + nrdf_tc[i] += nrdf_uc * (static_cast(na_vcm[j]) / static_cast(na_tot)) + * (nrdf_vcm[j] - nrdf_vcm_sub[j]) / nrdf_vcm[j]; } } } @@ -2898,8 +3109,7 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) { opts->nrdf[i] = 0; } - fprintf(stderr, - "Number of degrees of freedom in T-Coupling group %s is %.2f\n", + fprintf(stderr, "Number of degrees of freedom in T-Coupling group %s is %.2f\n", gnames[groups.groups[SimulationAtomGroupType::TemperatureCoupling][i]], opts->nrdf[i]); } @@ -2911,18 +3121,17 @@ static void calc_nrdf(const gmx_mtop_t *mtop, t_inputrec *ir, char **gnames) sfree(nrdf_vcm_sub); } -static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups, - const char *option, const char *val, int flag) +static bool do_egp_flag(t_inputrec* ir, SimulationGroups* groups, const char* option, const char* val, int flag) { /* The maximum number of energy group pairs would be MAXPTR*(MAXPTR+1)/2. * But since this is much larger than STRLEN, such a line can not be parsed. * The real maximum is the number of names that fit in a string: STRLEN/2. */ -#define EGP_MAX (STRLEN/2) - int j, k, nr; - bool bSet; +#define EGP_MAX (STRLEN / 2) + int j, k, nr; + bool bSet; - auto names = gmx::splitString(val); + auto names = gmx::splitString(val); if (names.size() % 2 != 0) { gmx_fatal(FARGS, "The number of groups for %s is odd", option); @@ -2933,31 +3142,33 @@ static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups, { // TODO this needs to be replaced by a solution using std::find_if j = 0; - while ((j < nr) && - gmx_strcasecmp(names[2*i].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]]))) + while ((j < nr) + && gmx_strcasecmp( + names[2 * i].c_str(), + *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]]))) { j++; } if (j == nr) { - gmx_fatal(FARGS, "%s in %s is not an energy group\n", - names[2*i].c_str(), option); + gmx_fatal(FARGS, "%s in %s is not an energy group\n", names[2 * i].c_str(), option); } k = 0; - while ((k < nr) && - gmx_strcasecmp(names[2*i+1].c_str(), *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]]))) + while ((k < nr) + && gmx_strcasecmp( + names[2 * i + 1].c_str(), + *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]]))) { k++; } if (k == nr) { - gmx_fatal(FARGS, "%s in %s is not an energy group\n", - names[2*i+1].c_str(), option); + gmx_fatal(FARGS, "%s in %s is not an energy group\n", names[2 * i + 1].c_str(), option); } if ((j < nr) && (k < nr)) { - ir->opts.egp_flags[nr*j+k] |= flag; - ir->opts.egp_flags[nr*k+j] |= flag; + ir->opts.egp_flags[nr * j + k] |= flag; + ir->opts.egp_flags[nr * k + j] |= flag; bSet = TRUE; } } @@ -2966,13 +3177,10 @@ static bool do_egp_flag(t_inputrec *ir, SimulationGroups *groups, } -static void make_swap_groups( - t_swapcoords *swap, - t_blocka *grps, - char **gnames) +static void make_swap_groups(t_swapcoords* swap, t_blocka* grps, char** gnames) { int ig = -1, i = 0, gind; - t_swapGroup *swapg; + t_swapGroup* swapg; /* Just a quick check here, more thorough checks are in mdrun */ @@ -2986,17 +3194,16 @@ static void make_swap_groups( { swapg = &swap->grp[ig]; gind = search_string(swap->grp[ig].molname, grps->nr, gnames); - swapg->nat = grps->index[gind+1] - grps->index[gind]; + swapg->nat = grps->index[gind + 1] - grps->index[gind]; if (swapg->nat > 0) { fprintf(stderr, "%s group '%s' contains %d atoms.\n", - ig < 3 ? eSwapFixedGrp_names[ig] : "Swap", - swap->grp[ig].molname, swapg->nat); + ig < 3 ? eSwapFixedGrp_names[ig] : "Swap", swap->grp[ig].molname, swapg->nat); snew(swapg->ind, swapg->nat); for (i = 0; i < swapg->nat; i++) { - swapg->ind[i] = grps->a[grps->index[gind]+i]; + swapg->ind[i] = grps->a[grps->index[gind] + i]; } } else @@ -3007,36 +3214,39 @@ static void make_swap_groups( } -static void make_IMD_group(t_IMD *IMDgroup, char *IMDgname, t_blocka *grps, char **gnames) +static void make_IMD_group(t_IMD* IMDgroup, char* IMDgname, t_blocka* grps, char** gnames) { - int ig, i; + int ig, i; ig = search_string(IMDgname, grps->nr, gnames); - IMDgroup->nat = grps->index[ig+1] - grps->index[ig]; + IMDgroup->nat = grps->index[ig + 1] - grps->index[ig]; if (IMDgroup->nat > 0) { - fprintf(stderr, "Group '%s' with %d atoms can be activated for interactive molecular dynamics (IMD).\n", + fprintf(stderr, + "Group '%s' with %d atoms can be activated for interactive molecular dynamics " + "(IMD).\n", IMDgname, IMDgroup->nat); snew(IMDgroup->ind, IMDgroup->nat); for (i = 0; i < IMDgroup->nat; i++) { - IMDgroup->ind[i] = grps->a[grps->index[ig]+i]; + IMDgroup->ind[i] = grps->a[grps->index[ig] + i]; } } } -void do_index(const char* mdparin, const char *ndx, - gmx_mtop_t *mtop, - bool bVerbose, - const gmx::MdModulesNotifier ¬ifier, - t_inputrec *ir, - warninp_t wi) +void do_index(const char* mdparin, + const char* ndx, + gmx_mtop_t* mtop, + bool bVerbose, + const gmx::MdModulesNotifier& notifier, + t_inputrec* ir, + warninp_t wi) { - t_blocka *defaultIndexGroups; + t_blocka* defaultIndexGroups; int natoms; - t_symtab *symtab; + t_symtab* symtab; t_atoms atoms_all; char warnbuf[STRLEN], **gnames; int nr; @@ -3064,39 +3274,39 @@ void do_index(const char* mdparin, const char *ndx, defaultIndexGroups = init_index(ndx, &gnames); } - SimulationGroups *groups = &mtop->groups; - natoms = mtop->natoms; - symtab = &mtop->symtab; + SimulationGroups* groups = &mtop->groups; + natoms = mtop->natoms; + symtab = &mtop->symtab; for (int i = 0; (i < defaultIndexGroups->nr); i++) { groups->groupNames.emplace_back(put_symtab(symtab, gnames[i])); } groups->groupNames.emplace_back(put_symtab(symtab, "rest")); - restnm = groups->groupNames.size() - 1; + restnm = groups->groupNames.size() - 1; GMX_RELEASE_ASSERT(restnm == defaultIndexGroups->nr, "Size of allocations must match"); - srenew(gnames, defaultIndexGroups->nr+1); - gnames[restnm] = *(groups->groupNames.back()); + srenew(gnames, defaultIndexGroups->nr + 1); + gnames[restnm] = *(groups->groupNames.back()); set_warning_line(wi, mdparin, -1); auto temperatureCouplingTauValues = gmx::splitString(is->tau_t); auto temperatureCouplingReferenceValues = gmx::splitString(is->ref_t); auto temperatureCouplingGroupNames = gmx::splitString(is->tcgrps); - if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() || - temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size()) + if (temperatureCouplingTauValues.size() != temperatureCouplingGroupNames.size() + || temperatureCouplingReferenceValues.size() != temperatureCouplingGroupNames.size()) { - gmx_fatal(FARGS, "Invalid T coupling input: %zu groups, %zu ref-t values and " + gmx_fatal(FARGS, + "Invalid T coupling input: %zu groups, %zu ref-t values and " "%zu tau-t values", - temperatureCouplingGroupNames.size(), - temperatureCouplingReferenceValues.size(), + temperatureCouplingGroupNames.size(), temperatureCouplingReferenceValues.size(), temperatureCouplingTauValues.size()); } const bool useReferenceTemperature = integratorHasReferenceTemperature(ir); do_numbering(natoms, groups, temperatureCouplingGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::TemperatureCoupling, - restnm, useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::TemperatureCoupling, restnm, + useReferenceTemperature ? egrptpALL : egrptpALL_GENREST, bVerbose, wi); nr = groups->groups[SimulationAtomGroupType::TemperatureCoupling].size(); ir->opts.ngtc = nr; snew(ir->opts.nrdf, nr); @@ -3126,7 +3336,10 @@ void do_index(const char* mdparin, const char *ndx, if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0) { - warning_note(wi, "tau-t = -1 is the value to signal that a group should not have temperature coupling. Treating your use of tau-t = 0 as if you used -1."); + warning_note( + wi, + "tau-t = -1 is the value to signal that a group should not have " + "temperature coupling. Treating your use of tau-t = 0 as if you used -1."); } if (ir->opts.tau_t[i] >= 0) @@ -3143,21 +3356,30 @@ void do_index(const char* mdparin, const char *ndx, { if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN)) { - gmx_fatal(FARGS, "Cannot do Nose-Hoover temperature with Berendsen pressure control with md-vv; use either vrescale temperature with berendsen pressure or Nose-Hoover temperature with MTTK pressure"); + gmx_fatal(FARGS, + "Cannot do Nose-Hoover temperature with Berendsen pressure control with " + "md-vv; use either vrescale temperature with berendsen pressure or " + "Nose-Hoover temperature with MTTK pressure"); } if (ir->epc == epcMTTK) { if (ir->etc != etcNOSEHOOVER) { - gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control"); + gmx_fatal(FARGS, + "Cannot do MTTK pressure coupling without Nose-Hoover temperature " + "control"); } else { if (ir->nstpcouple != ir->nsttcouple) { - int mincouple = std::min(ir->nstpcouple, ir->nsttcouple); + int mincouple = std::min(ir->nstpcouple, ir->nsttcouple); ir->nstpcouple = ir->nsttcouple = mincouple; - sprintf(warn_buf, "for current Trotter decomposition methods with vv, nsttcouple and nstpcouple must be equal. Both have been reset to min(nsttcouple,nstpcouple) = %d", mincouple); + sprintf(warn_buf, + "for current Trotter decomposition methods with vv, nsttcouple and " + "nstpcouple must be equal. Both have been reset to " + "min(nsttcouple,nstpcouple) = %d", + mincouple); warning_note(wi, warn_buf); } } @@ -3171,19 +3393,22 @@ void do_index(const char* mdparin, const char *ndx, if (ir->nsttcouple != 1) { ir->nsttcouple = 1; - sprintf(warn_buf, "Andersen temperature control methods assume nsttcouple = 1; there is no need for larger nsttcouple > 1, since no global parameters are computed. nsttcouple has been reset to 1"); + sprintf(warn_buf, + "Andersen temperature control methods assume nsttcouple = 1; there is no " + "need for larger nsttcouple > 1, since no global parameters are computed. " + "nsttcouple has been reset to 1"); warning_note(wi, warn_buf); } } nstcmin = tcouple_min_integration_steps(ir->etc); if (nstcmin > 1) { - if (tau_min/(ir->delta_t*ir->nsttcouple) < nstcmin - 10*GMX_REAL_EPS) + if (tau_min / (ir->delta_t * ir->nsttcouple) < nstcmin - 10 * GMX_REAL_EPS) { - sprintf(warn_buf, "For proper integration of the %s thermostat, tau-t (%g) should be at least %d times larger than nsttcouple*dt (%g)", - ETCOUPLTYPE(ir->etc), - tau_min, nstcmin, - ir->nsttcouple*ir->delta_t); + sprintf(warn_buf, + "For proper integration of the %s thermostat, tau-t (%g) should be at " + "least %d times larger than nsttcouple*dt (%g)", + ETCOUPLTYPE(ir->etc), tau_min, nstcmin, ir->nsttcouple * ir->delta_t); warning(wi, warn_buf); } } @@ -3205,13 +3430,12 @@ void do_index(const char* mdparin, const char *ndx, /* Simulated annealing for each group. There are nr groups */ auto simulatedAnnealingGroupNames = gmx::splitString(is->anneal); - if (simulatedAnnealingGroupNames.size() == 1 && - gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[0], "N", 1)) + if (simulatedAnnealingGroupNames.size() == 1 + && gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[0], "N", 1)) { simulatedAnnealingGroupNames.resize(0); } - if (!simulatedAnnealingGroupNames.empty() && - gmx::ssize(simulatedAnnealingGroupNames) != nr) + if (!simulatedAnnealingGroupNames.empty() && gmx::ssize(simulatedAnnealingGroupNames) != nr) { gmx_fatal(FARGS, "Wrong number of annealing values: %zu (for %d groups)\n", simulatedAnnealingGroupNames.size(), nr); @@ -3264,7 +3488,9 @@ void do_index(const char* mdparin, const char *ndx, { if (ir->opts.anneal_npoints[i] == 1) { - gmx_fatal(FARGS, "Please specify at least a start and an end point for annealing\n"); + gmx_fatal( + FARGS, + "Please specify at least a start and an end point for annealing\n"); } snew(ir->opts.anneal_time[i], ir->opts.anneal_npoints[i]); snew(ir->opts.anneal_temp[i], ir->opts.anneal_npoints[i]); @@ -3287,8 +3513,10 @@ void do_index(const char* mdparin, const char *ndx, std::vector allSimulatedAnnealingTimes(numSimulatedAnnealingFields); std::vector allSimulatedAnnealingTemperatures(numSimulatedAnnealingFields); - convertReals(wi, simulatedAnnealingTimes, "anneal-time", allSimulatedAnnealingTimes.data()); - convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", allSimulatedAnnealingTemperatures.data()); + convertReals(wi, simulatedAnnealingTimes, "anneal-time", + allSimulatedAnnealingTimes.data()); + convertReals(wi, simulatedAnnealingTemperatures, "anneal-temp", + allSimulatedAnnealingTemperatures.data()); for (i = 0, k = 0; i < nr; i++) { for (j = 0; j < ir->opts.anneal_npoints[i]; j++) @@ -3297,7 +3525,7 @@ void do_index(const char* mdparin, const char *ndx, ir->opts.anneal_temp[i][j] = allSimulatedAnnealingTemperatures[k]; if (j == 0) { - if (ir->opts.anneal_time[i][0] > (ir->init_t+GMX_REAL_EPS)) + if (ir->opts.anneal_time[i][0] > (ir->init_t + GMX_REAL_EPS)) { gmx_fatal(FARGS, "First time point for annealing > init_t.\n"); } @@ -3305,15 +3533,18 @@ void do_index(const char* mdparin, const char *ndx, else { /* j>0 */ - if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j-1]) + if (ir->opts.anneal_time[i][j] < ir->opts.anneal_time[i][j - 1]) { - gmx_fatal(FARGS, "Annealing timepoints out of order: t=%f comes after t=%f\n", - ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j-1]); + gmx_fatal(FARGS, + "Annealing timepoints out of order: t=%f comes after " + "t=%f\n", + ir->opts.anneal_time[i][j], ir->opts.anneal_time[i][j - 1]); } } if (ir->opts.anneal_temp[i][j] < 0) { - gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", ir->opts.anneal_temp[i][j]); + gmx_fatal(FARGS, "Found negative temperature in annealing: %f\n", + ir->opts.anneal_temp[i][j]); } k++; } @@ -3329,23 +3560,28 @@ void do_index(const char* mdparin, const char *ndx, ir->opts.anneal_npoints[i]); fprintf(stderr, "Time (ps) Temperature (K)\n"); /* All terms except the last one */ - for (j = 0; j < (ir->opts.anneal_npoints[i]-1); j++) + for (j = 0; j < (ir->opts.anneal_npoints[i] - 1); j++) { - fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]); + fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], + ir->opts.anneal_temp[i][j]); } /* Finally the last one */ - j = ir->opts.anneal_npoints[i]-1; + j = ir->opts.anneal_npoints[i] - 1; if (ir->opts.annealing[i] == eannSINGLE) { - fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]); + fprintf(stderr, "%9.1f- %5.1f\n", ir->opts.anneal_time[i][j], + ir->opts.anneal_temp[i][j]); } else { - fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], ir->opts.anneal_temp[i][j]); - if (std::fabs(ir->opts.anneal_temp[i][j]-ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS) + fprintf(stderr, "%9.1f %5.1f\n", ir->opts.anneal_time[i][j], + ir->opts.anneal_temp[i][j]); + if (std::fabs(ir->opts.anneal_temp[i][j] - ir->opts.anneal_temp[i][0]) > GMX_REAL_EPS) { - warning_note(wi, "There is a temperature jump when your annealing loops back.\n"); + warning_note(wi, + "There is a temperature jump when your annealing " + "loops back.\n"); } } } @@ -3389,8 +3625,7 @@ void do_index(const char* mdparin, const char *ndx, accelerationGroupNames.size(), accelerations.size()); } do_numbering(natoms, groups, accelerationGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::Acceleration, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::Acceleration, restnm, egrptpALL_GENREST, bVerbose, wi); nr = groups->groups[SimulationAtomGroupType::Acceleration].size(); snew(ir->opts.acc, nr); ir->opts.ngacc = nr; @@ -3405,8 +3640,7 @@ void do_index(const char* mdparin, const char *ndx, freezeGroupNames.size(), freezeDims.size()); } do_numbering(natoms, groups, freezeGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::Freeze, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::Freeze, restnm, egrptpALL_GENREST, bVerbose, wi); nr = groups->groups[SimulationAtomGroupType::Freeze].size(); ir->opts.ngfrz = nr; snew(ir->opts.nFreeze, nr); @@ -3419,8 +3653,10 @@ void do_index(const char* mdparin, const char *ndx, { if (!gmx::equalCaseInsensitive(freezeDims[k], "N", 1)) { - sprintf(warnbuf, "Please use Y(ES) or N(O) for freezedim only " - "(not %s)", freezeDims[k].c_str()); + sprintf(warnbuf, + "Please use Y(ES) or N(O) for freezedim only " + "(not %s)", + freezeDims[k].c_str()); warning(wi, warn_buf); } } @@ -3436,18 +3672,17 @@ void do_index(const char* mdparin, const char *ndx, auto energyGroupNames = gmx::splitString(is->energy); do_numbering(natoms, groups, energyGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::EnergyOutput, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::EnergyOutput, restnm, egrptpALL_GENREST, bVerbose, wi); add_wall_energrps(groups, ir->nwall, symtab); - ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); + ir->opts.ngener = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); auto vcmGroupNames = gmx::splitString(is->vcm); - bRest = - do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::MassCenterVelocityRemoval, - restnm, vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi); + bRest = do_numbering(natoms, groups, vcmGroupNames, defaultIndexGroups, gnames, + SimulationAtomGroupType::MassCenterVelocityRemoval, restnm, + vcmGroupNames.empty() ? egrptpALL_GENREST : egrptpPART, bVerbose, wi); if (bRest) { - warning(wi, "Some atoms are not part of any center of mass motion removal group.\n" + warning(wi, + "Some atoms are not part of any center of mass motion removal group.\n" "This may lead to artifacts.\n" "In most cases one should use one group for the whole system."); } @@ -3457,20 +3692,17 @@ void do_index(const char* mdparin, const char *ndx, auto user1GroupNames = gmx::splitString(is->user1); do_numbering(natoms, groups, user1GroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::User1, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::User1, restnm, egrptpALL_GENREST, bVerbose, wi); auto user2GroupNames = gmx::splitString(is->user2); do_numbering(natoms, groups, user2GroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::User2, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::User2, restnm, egrptpALL_GENREST, bVerbose, wi); auto compressedXGroupNames = gmx::splitString(is->x_compressed_groups); do_numbering(natoms, groups, compressedXGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::CompressedPositionOutput, - restnm, egrptpONE, bVerbose, wi); + SimulationAtomGroupType::CompressedPositionOutput, restnm, egrptpONE, bVerbose, wi); auto orirefFitGroupNames = gmx::splitString(is->orirefitgrp); do_numbering(natoms, groups, orirefFitGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::OrientationRestraintsFit, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::OrientationRestraintsFit, restnm, egrptpALL_GENREST, + bVerbose, wi); /* QMMM input processing */ auto qmGroupNames = gmx::splitString(is->QMMM); @@ -3478,17 +3710,16 @@ void do_index(const char* mdparin, const char *ndx, auto qmBasisSets = gmx::splitString(is->QMbasis); if (ir->eI != eiMimic) { - if (qmMethods.size() != qmGroupNames.size() || - qmBasisSets.size() != qmGroupNames.size()) + if (qmMethods.size() != qmGroupNames.size() || qmBasisSets.size() != qmGroupNames.size()) { - gmx_fatal(FARGS, "Invalid QMMM input: %zu groups %zu basissets" - " and %zu methods\n", qmGroupNames.size(), - qmBasisSets.size(), qmMethods.size()); + gmx_fatal(FARGS, + "Invalid QMMM input: %zu groups %zu basissets" + " and %zu methods\n", + qmGroupNames.size(), qmBasisSets.size(), qmMethods.size()); } /* group rest, if any, is always MM! */ do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::QuantumMechanics, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::QuantumMechanics, restnm, egrptpALL_GENREST, bVerbose, wi); nr = qmGroupNames.size(); /*atoms->grps[egcQMMM].nr;*/ ir->opts.ngQM = qmGroupNames.size(); snew(ir->opts.QMmethod, nr); @@ -3498,13 +3729,8 @@ void do_index(const char* mdparin, const char *ndx, /* input consists of strings: RHF CASSCF PM3 .. These need to be * converted to the corresponding enum in names.c */ - ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(), - eQMmethodNR, - eQMmethod_names); - ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(), - eQMbasisNR, - eQMbasis_names); - + ir->opts.QMmethod[i] = search_QMstring(qmMethods[i].c_str(), eQMmethodNR, eQMmethod_names); + ir->opts.QMbasis[i] = search_QMstring(qmBasisSets[i].c_str(), eQMbasisNR, eQMbasis_names); } auto qmMultiplicities = gmx::splitString(is->QMmult); auto qmCharges = gmx::splitString(is->QMcharge); @@ -3542,8 +3768,7 @@ void do_index(const char* mdparin, const char *ndx, } /* group rest, if any, is always MM! */ do_numbering(natoms, groups, qmGroupNames, defaultIndexGroups, gnames, - SimulationAtomGroupType::QuantumMechanics, - restnm, egrptpALL_GENREST, bVerbose, wi); + SimulationAtomGroupType::QuantumMechanics, restnm, egrptpALL_GENREST, bVerbose, wi); ir->opts.ngQM = qmGroupNames.size(); } @@ -3555,7 +3780,7 @@ void do_index(const char* mdparin, const char *ndx, for (auto group : gmx::keysOf(groups->groups)) { fprintf(stderr, "%-16s has %zu element(s):", shortName(group), groups->groups[group].size()); - for (const auto &entry : groups->groups[group]) + for (const auto& entry : groups->groups[group]) { fprintf(stderr, " %s", *(groups->groupNames[entry])); } @@ -3564,7 +3789,7 @@ void do_index(const char* mdparin, const char *ndx, } nr = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); - snew(ir->opts.egp_flags, nr*nr); + snew(ir->opts.egp_flags, nr * nr); bExcl = do_egp_flag(ir, groups, "energygrp-excl", is->egpexcl, EGP_EXCL); if (bExcl && ir->cutoff_scheme == ecutsVERLET) @@ -3577,11 +3802,12 @@ void do_index(const char* mdparin, const char *ndx, } bTable = do_egp_flag(ir, groups, "energygrp-table", is->egptable, EGP_TABLE); - if (bTable && !(ir->vdwtype == evdwUSER) && - !(ir->coulombtype == eelUSER) && !(ir->coulombtype == eelPMEUSER) && - !(ir->coulombtype == eelPMEUSERSWITCH)) + if (bTable && !(ir->vdwtype == evdwUSER) && !(ir->coulombtype == eelUSER) + && !(ir->coulombtype == eelPMEUSER) && !(ir->coulombtype == eelPMEUSERSWITCH)) { - gmx_fatal(FARGS, "Can only have energy group pair tables in combination with user tables for VdW and/or Coulomb"); + gmx_fatal(FARGS, + "Can only have energy group pair tables in combination with user tables for VdW " + "and/or Coulomb"); } /* final check before going out of scope if simulated tempering variables @@ -3589,11 +3815,12 @@ void do_index(const char* mdparin, const char *ndx, */ if ((ir->expandedvals->nstexpanded < 0) && ir->bSimTemp) { - ir->expandedvals->nstexpanded = 2*static_cast(ir->opts.tau_t[0]/ir->delta_t); - warning(wi, gmx::formatString("the value for nstexpanded was not specified for " - " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) " - "by default, but it is recommended to set it to an explicit value!", - ir->expandedvals->nstexpanded)); + ir->expandedvals->nstexpanded = 2 * static_cast(ir->opts.tau_t[0] / ir->delta_t); + warning(wi, gmx::formatString( + "the value for nstexpanded was not specified for " + " expanded ensemble simulated tempering. It is set to 2*tau_t (%d) " + "by default, but it is recommended to set it to an explicit value!", + ir->expandedvals->nstexpanded)); } for (i = 0; (i < defaultIndexGroups->nr); i++) { @@ -3602,16 +3829,14 @@ void do_index(const char* mdparin, const char *ndx, sfree(gnames); done_blocka(defaultIndexGroups); sfree(defaultIndexGroups); - } - -static void check_disre(const gmx_mtop_t *mtop) +static void check_disre(const gmx_mtop_t* mtop) { if (gmx_mtop_ftype_count(mtop, F_DISRES) > 0) { - const gmx_ffparams_t &ffparams = mtop->ffparams; + const gmx_ffparams_t& ffparams = mtop->ffparams; int ndouble = 0; int old_label = -1; for (int i = 0; i < ffparams.numTypes(); i++) @@ -3630,21 +3855,21 @@ static void check_disre(const gmx_mtop_t *mtop) } if (ndouble > 0) { - gmx_fatal(FARGS, "Found %d double distance restraint indices,\n" + gmx_fatal(FARGS, + "Found %d double distance restraint indices,\n" "probably the parameters for multiple pairs in one restraint " - "are not identical\n", ndouble); + "are not identical\n", + ndouble); } } } -static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys, - bool posres_only, - ivec AbsRef) +static bool absolute_reference(t_inputrec* ir, gmx_mtop_t* sys, bool posres_only, ivec AbsRef) { - int d, g, i; - gmx_mtop_ilistloop_t iloop; - int nmol; - t_iparams *pr; + int d, g, i; + gmx_mtop_ilistloop_t iloop; + int nmol; + t_iparams* pr; clear_ivec(AbsRef); @@ -3670,10 +3895,9 @@ static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys, /* Check for position restraints */ iloop = gmx_mtop_ilistloop_init(sys); - while (const InteractionLists *ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) + while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol)) { - if (nmol > 0 && - (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0)) + if (nmol > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0)) { for (i = 0; i < (*ilist)[F_POSRES].size(); i += 2) { @@ -3694,20 +3918,12 @@ static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys, { switch (pr->fbposres.geom) { - case efbposresSPHERE: - AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1; - break; - case efbposresCYLINDERX: - AbsRef[YY] = AbsRef[ZZ] = 1; - break; - case efbposresCYLINDERY: - AbsRef[XX] = AbsRef[ZZ] = 1; - break; + case efbposresSPHERE: AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1; break; + case efbposresCYLINDERX: AbsRef[YY] = AbsRef[ZZ] = 1; break; + case efbposresCYLINDERY: AbsRef[XX] = AbsRef[ZZ] = 1; break; case efbposresCYLINDER: /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */ - case efbposresCYLINDERZ: - AbsRef[XX] = AbsRef[YY] = 1; - break; + case efbposresCYLINDERZ: AbsRef[XX] = AbsRef[YY] = 1; break; case efbposresX: /* d=XX */ case efbposresY: /* d=YY */ case efbposresZ: /* d=ZZ */ @@ -3715,9 +3931,10 @@ static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys, AbsRef[d] = 1; break; default: - gmx_fatal(FARGS, " Invalid geometry for flat-bottom position restraint.\n" - "Expected nr between 1 and %d. Found %d\n", efbposresNR-1, - pr->fbposres.geom); + gmx_fatal(FARGS, + " Invalid geometry for flat-bottom position restraint.\n" + "Expected nr between 1 and %d. Found %d\n", + efbposresNR - 1, pr->fbposres.geom); } } } @@ -3727,20 +3944,20 @@ static bool absolute_reference(t_inputrec *ir, gmx_mtop_t *sys, return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0); } -static void -check_combination_rule_differences(const gmx_mtop_t *mtop, int state, - bool *bC6ParametersWorkWithGeometricRules, - bool *bC6ParametersWorkWithLBRules, - bool *bLBRulesPossible) +static void check_combination_rule_differences(const gmx_mtop_t* mtop, + int state, + bool* bC6ParametersWorkWithGeometricRules, + bool* bC6ParametersWorkWithLBRules, + bool* bLBRulesPossible) { - int ntypes, tpi, tpj; - int *typecount; - real tol; - double c6i, c6j, c12i, c12j; - double c6, c6_geometric, c6_LB; - double sigmai, sigmaj, epsi, epsj; - bool bCanDoLBRules, bCanDoGeometricRules; - const char *ptr; + int ntypes, tpi, tpj; + int* typecount; + real tol; + double c6i, c6j, c12i, c12j; + double c6, c6_geometric, c6_LB; + double sigmai, sigmaj, epsi, epsj; + bool bCanDoLBRules, bCanDoGeometricRules; + const char* ptr; /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed) * force-field floating point parameters. @@ -3749,23 +3966,24 @@ check_combination_rule_differences(const gmx_mtop_t *mtop, int state, ptr = getenv("GMX_LJCOMB_TOL"); if (ptr != nullptr) { - double dbl; + double dbl; double gmx_unused canary; if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1) { - gmx_fatal(FARGS, "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr); + gmx_fatal(FARGS, + "Could not parse a single floating-point number from GMX_LJCOMB_TOL (%s)", ptr); } tol = dbl; } - *bC6ParametersWorkWithLBRules = TRUE; - *bC6ParametersWorkWithGeometricRules = TRUE; - bCanDoLBRules = TRUE; - ntypes = mtop->ffparams.atnr; + *bC6ParametersWorkWithLBRules = TRUE; + *bC6ParametersWorkWithGeometricRules = TRUE; + bCanDoLBRules = TRUE; + ntypes = mtop->ffparams.atnr; snew(typecount, ntypes); gmx_mtop_count_atomtypes(mtop, state, typecount); - *bLBRulesPossible = TRUE; + *bLBRulesPossible = TRUE; for (tpi = 0; tpi < ntypes; ++tpi) { c6i = mtop->ffparams.iparams[(ntypes + 1) * tpi].lj.c6; @@ -3780,11 +3998,11 @@ check_combination_rule_differences(const gmx_mtop_t *mtop, int state, { if (!gmx_numzero(c12i) && !gmx_numzero(c12j)) { - sigmai = gmx::sixthroot(c12i / c6i); - sigmaj = gmx::sixthroot(c12j / c6j); - epsi = c6i * c6i /(4.0 * c12i); - epsj = c6j * c6j /(4.0 * c12j); - c6_LB = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj)); + sigmai = gmx::sixthroot(c12i / c6i); + sigmaj = gmx::sixthroot(c12j / c6j); + epsi = c6i * c6i / (4.0 * c12i); + epsj = c6j * c6j / (4.0 * c12j); + c6_LB = 4.0 * std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj)); } else { @@ -3810,21 +4028,18 @@ check_combination_rule_differences(const gmx_mtop_t *mtop, int state, sfree(typecount); } -static void -check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop, - warninp_t wi) +static void check_combination_rules(const t_inputrec* ir, const gmx_mtop_t* mtop, warninp_t wi) { bool bLBRulesPossible, bC6ParametersWorkWithGeometricRules, bC6ParametersWorkWithLBRules; - check_combination_rule_differences(mtop, 0, - &bC6ParametersWorkWithGeometricRules, - &bC6ParametersWorkWithLBRules, - &bLBRulesPossible); + check_combination_rule_differences(mtop, 0, &bC6ParametersWorkWithGeometricRules, + &bC6ParametersWorkWithLBRules, &bLBRulesPossible); if (ir->ljpme_combination_rule == eljpmeLB) { if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible) { - warning(wi, "You are using arithmetic-geometric combination rules " + warning(wi, + "You are using arithmetic-geometric combination rules " "in LJ-PME, but your non-bonded C6 parameters do not " "follow these rules."); } @@ -3835,33 +4050,36 @@ check_combination_rules(const t_inputrec *ir, const gmx_mtop_t *mtop, { if (ir->eDispCorr != edispcNO) { - warning_note(wi, "You are using geometric combination rules in " + warning_note(wi, + "You are using geometric combination rules in " "LJ-PME, but your non-bonded C6 parameters do " "not follow these rules. " "This will introduce very small errors in the forces and energies in " "your simulations. Dispersion correction will correct total energy " - "and/or pressure for isotropic systems, but not forces or surface tensions."); + "and/or pressure for isotropic systems, but not forces or surface " + "tensions."); } else { - warning_note(wi, "You are using geometric combination rules in " + warning_note(wi, + "You are using geometric combination rules in " "LJ-PME, but your non-bonded C6 parameters do " "not follow these rules. " "This will introduce very small errors in the forces and energies in " - "your simulations. If your system is homogeneous, consider using dispersion correction " + "your simulations. If your system is homogeneous, consider using " + "dispersion correction " "for the total energy and pressure."); } } } } -void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, - warninp_t wi) +void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_t wi) { char err_buf[STRLEN]; int i, m, c, nmol; bool bCharge, bAcc; - real *mgrp, mt; + real * mgrp, mt; rvec acc; gmx_mtop_atomloop_block_t aloopb; ivec AbsRef; @@ -3869,11 +4087,8 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, set_warning_line(wi, mdparin, -1); - if (ir->cutoff_scheme == ecutsVERLET && - ir->verletbuf_tol > 0 && - ir->nstlist > 1 && - ((EI_MD(ir->eI) || EI_SD(ir->eI)) && - (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN))) + if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1 + && ((EI_MD(ir->eI) || EI_SD(ir->eI)) && (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN))) { /* Check if a too small Verlet buffer might potentially * cause more drift than the thermostat can couple off. @@ -3882,7 +4097,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, const real T_error_warn = 0.002; const real T_error_suggest = 0.001; /* For safety: 2 DOF per atom (typical with constraints) */ - const real nrdf_at = 2; + const real nrdf_at = 2; real T, tau, max_T_error; int i; @@ -3900,14 +4115,16 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, * of errors. The factor 0.5 is because energy distributes * equally over Ekin and Epot. */ - max_T_error = 0.5*tau*ir->verletbuf_tol/(nrdf_at*BOLTZ*T); + max_T_error = 0.5 * tau * ir->verletbuf_tol / (nrdf_at * BOLTZ * T); if (max_T_error > T_error_warn) { - sprintf(warn_buf, "With a verlet-buffer-tolerance of %g kJ/mol/ps, a reference temperature of %g and a tau_t of %g, your temperature might be off by up to %.1f%%. To ensure the error is below %.1f%%, decrease verlet-buffer-tolerance to %.0e or decrease tau_t.", - ir->verletbuf_tol, T, tau, - 100*max_T_error, - 100*T_error_suggest, - ir->verletbuf_tol*T_error_suggest/max_T_error); + sprintf(warn_buf, + "With a verlet-buffer-tolerance of %g kJ/mol/ps, a reference temperature " + "of %g and a tau_t of %g, your temperature might be off by up to %.1f%%. " + "To ensure the error is below %.1f%%, decrease verlet-buffer-tolerance to " + "%.0e or decrease tau_t.", + ir->verletbuf_tol, T, tau, 100 * max_T_error, 100 * T_error_suggest, + ir->verletbuf_tol * T_error_suggest / max_T_error); warning(wi, warn_buf); } } @@ -3919,9 +4136,14 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, for (i = 0; i < ir->opts.ngtc; i++) { - sprintf(err_buf, "all tau_t must currently be equal using Andersen temperature control, violated for group %d", i); + sprintf(err_buf, + "all tau_t must currently be equal using Andersen temperature control, " + "violated for group %d", + i); CHECK(ir->opts.tau_t[0] != ir->opts.tau_t[i]); - sprintf(err_buf, "all tau_t must be positive using Andersen temperature control, tau_t[%d]=%10.6f", + sprintf(err_buf, + "all tau_t must be positive using Andersen temperature control, " + "tau_t[%d]=%10.6f", i, ir->opts.tau_t[i]); CHECK(ir->opts.tau_t[i] < 0); } @@ -3930,38 +4152,40 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { for (i = 0; i < ir->opts.ngtc; i++) { - int nsteps = gmx::roundToInt(ir->opts.tau_t[i]/ir->delta_t); - sprintf(err_buf, "tau_t/delta_t for group %d for temperature control method %s must be a multiple of nstcomm (%d), as velocities of atoms in coupled groups are randomized every time step. The input tau_t (%8.3f) leads to %d steps per randomization", i, etcoupl_names[ir->etc], ir->nstcomm, ir->opts.tau_t[i], nsteps); + int nsteps = gmx::roundToInt(ir->opts.tau_t[i] / ir->delta_t); + sprintf(err_buf, + "tau_t/delta_t for group %d for temperature control method %s must be a " + "multiple of nstcomm (%d), as velocities of atoms in coupled groups are " + "randomized every time step. The input tau_t (%8.3f) leads to %d steps per " + "randomization", + i, etcoupl_names[ir->etc], ir->nstcomm, ir->opts.tau_t[i], nsteps); CHECK(nsteps % ir->nstcomm != 0); } } } - if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD && - ir->comm_mode == ecmNO && - !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) && - !ETC_ANDERSEN(ir->etc)) + if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD && ir->comm_mode == ecmNO + && !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) && !ETC_ANDERSEN(ir->etc)) { - warning(wi, "You are not using center of mass motion removal (mdp option comm-mode), numerical rounding errors can lead to build up of kinetic energy of the center of mass"); + warning(wi, + "You are not using center of mass motion removal (mdp option comm-mode), numerical " + "rounding errors can lead to build up of kinetic energy of the center of mass"); } - if (ir->epc == epcPARRINELLORAHMAN && - ir->etc == etcNOSEHOOVER) + if (ir->epc == epcPARRINELLORAHMAN && ir->etc == etcNOSEHOOVER) { real tau_t_max = 0; for (int g = 0; g < ir->opts.ngtc; g++) { tau_t_max = std::max(tau_t_max, ir->opts.tau_t[g]); } - if (ir->tau_p < 1.9*tau_t_max) + if (ir->tau_p < 1.9 * tau_t_max) { - std::string message = - gmx::formatString("With %s T-coupling and %s p-coupling, " - "%s (%g) should be at least twice as large as %s (%g) to avoid resonances", - etcoupl_names[ir->etc], - epcoupl_names[ir->epc], - "tau-p", ir->tau_p, - "tau-t", tau_t_max); + std::string message = gmx::formatString( + "With %s T-coupling and %s p-coupling, " + "%s (%g) should be at least twice as large as %s (%g) to avoid resonances", + etcoupl_names[ir->etc], epcoupl_names[ir->epc], "tau-p", ir->tau_p, "tau-t", + tau_t_max); warning(wi, message.c_str()); } } @@ -3975,7 +4199,9 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { if (AbsRef[m] && norm2(ir->compress[m]) > 0) { - warning(wi, "You are using pressure coupling with absolute position restraints, this will give artifacts. Use the refcoord_scaling option."); + warning(wi, + "You are using pressure coupling with absolute position restraints, " + "this will give artifacts. Use the refcoord_scaling option."); break; } } @@ -3984,7 +4210,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, bCharge = FALSE; aloopb = gmx_mtop_atomloop_block_init(sys); - const t_atom *atom; + const t_atom* atom; while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol)) { if (atom->q != 0 || atom->qB != 0) @@ -3999,7 +4225,8 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { sprintf(err_buf, "You are using full electrostatics treatment %s for a system without charges.\n" - "This costs a lot of performance for just processing zeros, consider using %s instead.\n", + "This costs a lot of performance for just processing zeros, consider using %s " + "instead.\n", EELTYPE(ir->coulombtype), EELTYPE(eelCUT)); warning(wi, err_buf); } @@ -4025,8 +4252,10 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, /* Generalized reaction field */ if (ir->coulombtype == eelGRF_NOTUSED) { - warning_error(wi, "Generalized reaction-field electrostatics is no longer supported. " - "You can use normal reaction-field instead and compute the reaction-field constant by hand."); + warning_error(wi, + "Generalized reaction-field electrostatics is no longer supported. " + "You can use normal reaction-field instead and compute the reaction-field " + "constant by hand."); } bAcc = FALSE; @@ -4046,7 +4275,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, snew(mgrp, sys->groups.groups[SimulationAtomGroupType::Acceleration].size()); for (const AtomProxy atomP : AtomRange(*sys)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); mgrp[getGroupType(sys->groups, SimulationAtomGroupType::Acceleration, i)] += local.m; } @@ -4055,7 +4284,7 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { for (m = 0; (m < DIM); m++) { - acc[m] += ir->opts.acc[i][m]*mgrp[i]; + acc[m] += ir->opts.acc[i][m] * mgrp[i]; } mt += mgrp[i]; } @@ -4063,14 +4292,14 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { if (fabs(acc[m]) > 1e-6) { - const char *dim[DIM] = { "X", "Y", "Z" }; - fprintf(stderr, - "Net Acceleration in %s direction, will %s be corrected\n", - dim[m], ir->nstcomm != 0 ? "" : "not"); + const char* dim[DIM] = { "X", "Y", "Z" }; + fprintf(stderr, "Net Acceleration in %s direction, will %s be corrected\n", dim[m], + ir->nstcomm != 0 ? "" : "not"); if (ir->nstcomm != 0 && m < ndof_com(ir)) { acc[m] /= mt; - for (i = 0; (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++) + for (i = 0; + (i < gmx::ssize(sys->groups.groups[SimulationAtomGroupType::Acceleration])); i++) { ir->opts.acc[i][m] -= acc[m]; } @@ -4080,8 +4309,8 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, sfree(mgrp); } - if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 && - !gmx_within_tol(sys->ffparams.reppow, 12.0, 10*GMX_DOUBLE_EPS)) + if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0 + && !gmx_within_tol(sys->ffparams.reppow, 12.0, 10 * GMX_DOUBLE_EPS)) { gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12"); } @@ -4093,15 +4322,17 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, bWarned = FALSE; for (i = 0; i < ir->pull->ncoord && !bWarned; i++) { - if (ir->pull->coord[i].group[0] == 0 || - ir->pull->coord[i].group[1] == 0) + if (ir->pull->coord[i].group[0] == 0 || ir->pull->coord[i].group[1] == 0) { absolute_reference(ir, sys, FALSE, AbsRef); for (m = 0; m < DIM; m++) { if (ir->pull->coord[i].dim[m] && !AbsRef[m]) { - warning(wi, "You are using an absolute reference for pulling, but the rest of the system does not have an absolute reference. This will lead to artifacts."); + warning(wi, + "You are using an absolute reference for pulling, but the rest of " + "the system does not have an absolute reference. This will lead to " + "artifacts."); bWarned = TRUE; break; } @@ -4113,15 +4344,16 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, { for (m = 0; m <= i; m++) { - if ((ir->epc != epcNO && ir->compress[i][m] != 0) || - ir->deform[i][m] != 0) + if ((ir->epc != epcNO && ir->compress[i][m] != 0) || ir->deform[i][m] != 0) { for (c = 0; c < ir->pull->ncoord; c++) { - if (ir->pull->coord[c].eGeom == epullgDIRPBC && - ir->pull->coord[c].vec[m] != 0) + if (ir->pull->coord[c].eGeom == epullgDIRPBC && ir->pull->coord[c].vec[m] != 0) { - gmx_fatal(FARGS, "Can not have dynamic box while using pull geometry '%s' (dim %c)", EPULLGEOM(ir->pull->coord[c].eGeom), 'x'+m); + gmx_fatal(FARGS, + "Can not have dynamic box while using pull geometry '%s' " + "(dim %c)", + EPULLGEOM(ir->pull->coord[c].eGeom), 'x' + m); } } } @@ -4132,13 +4364,10 @@ void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, check_disre(sys); } -void double_check(t_inputrec *ir, matrix box, - bool bHasNormalConstraints, - bool bHasAnyConstraints, - warninp_t wi) +void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool bHasAnyConstraints, warninp_t wi) { char warn_buf[STRLEN]; - const char *ptr; + const char* ptr; ptr = check_box(ir->ePBC, box); if (ptr) @@ -4150,25 +4379,26 @@ void double_check(t_inputrec *ir, matrix box, { if (ir->shake_tol <= 0.0) { - sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n", - ir->shake_tol); + sprintf(warn_buf, "ERROR: shake-tol must be > 0 instead of %g\n", ir->shake_tol); warning_error(wi, warn_buf); } } - if ( (ir->eConstrAlg == econtLINCS) && bHasNormalConstraints) + if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints) { /* If we have Lincs constraints: */ - if (ir->eI == eiMD && ir->etc == etcNO && - ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1) + if (ir->eI == eiMD && ir->etc == etcNO && ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1) { - sprintf(warn_buf, "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n"); + sprintf(warn_buf, + "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n"); warning_note(wi, warn_buf); } if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8)) { - sprintf(warn_buf, "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", ei_names[ir->eI]); + sprintf(warn_buf, + "For accurate %s with LINCS constraints, lincs-order should be 8 or more.", + ei_names[ir->eI]); warning_note(wi, warn_buf); } if (ir->epc == epcMTTK) @@ -4193,11 +4423,16 @@ void double_check(t_inputrec *ir, matrix box, { if (ir->nstlist == 0) { - warning(wi, "With nstlist=0 atoms are only put into the box at step 0, therefore drifting atoms might cause the simulation to crash."); + warning(wi, + "With nstlist=0 atoms are only put into the box at step 0, therefore drifting " + "atoms might cause the simulation to crash."); } if (gmx::square(ir->rlist) >= max_cutoff2(ir->ePBC, box)) { - sprintf(warn_buf, "ERROR: The cut-off length is longer than half the shortest box vector or longer than the smallest box diagonal element. Increase the box size or decrease rlist.\n"); + sprintf(warn_buf, + "ERROR: The cut-off length is longer than half the shortest box vector or " + "longer than the smallest box diagonal element. Increase the box size or " + "decrease rlist.\n"); warning_error(wi, warn_buf); } } diff --git a/src/gromacs/gmxpreprocess/readir.h b/src/gromacs/gmxpreprocess/readir.h index fff4d452f5..7e200cb756 100644 --- a/src/gromacs/gmxpreprocess/readir.h +++ b/src/gromacs/gmxpreprocess/readir.h @@ -46,7 +46,7 @@ namespace gmx { class MDModules; struct MdModulesNotifier; -} +} // namespace gmx struct gmx_mtop_t; struct gmx_output_env_t; @@ -58,33 +58,44 @@ struct t_inpfile; struct t_inputrec; struct t_rot; struct warninp; -typedef warninp *warninp_t; +typedef warninp* warninp_t; -enum { - eshNONE, eshHBONDS, eshALLBONDS, eshHANGLES, eshALLANGLES, eshNR +enum +{ + eshNONE, + eshHBONDS, + eshALLBONDS, + eshHANGLES, + eshALLANGLES, + eshNR }; -enum { - ecouplamVDWQ, ecouplamVDW, ecouplamQ, ecouplamNONE, ecouplamNR +enum +{ + ecouplamVDWQ, + ecouplamVDW, + ecouplamQ, + ecouplamNONE, + ecouplamNR }; struct t_gromppopts { - int warnings; - int nshake; - char *include; - char *define; - bool bGenVel; - bool bGenPairs; - real tempi; - int seed; - bool bOrire; - bool bMorse; - char *wall_atomtype[2]; - char *couple_moltype; - int couple_lam0; - int couple_lam1; - bool bCoupleIntra; + int warnings; + int nshake; + char* include; + char* define; + bool bGenVel; + bool bGenPairs; + real tempi; + int seed; + bool bOrire; + bool bMorse; + char* wall_atomtype[2]; + char* couple_moltype; + int couple_lam0; + int couple_lam1; + bool bCoupleIntra; }; /*! \brief Initialise object to hold strings parsed from an .mdp file */ @@ -93,74 +104,69 @@ void init_inputrec_strings(); /*! \brief Clean up object that holds strings parsed from an .mdp file */ void done_inputrec_strings(); -void check_ir(const char *mdparin, const gmx::MdModulesNotifier &mdModulesNotifier, - t_inputrec *ir, t_gromppopts *opts, warninp_t wi); +void check_ir(const char* mdparin, + const gmx::MdModulesNotifier& mdModulesNotifier, + t_inputrec* ir, + t_gromppopts* opts, + warninp_t wi); /* Validate inputrec data. * Fatal errors will be added to nerror. */ -int search_string(const char *s, int ng, char *gn[]); +int search_string(const char* s, int ng, char* gn[]); /* Returns the index of string s in the index groups */ -void double_check(t_inputrec *ir, matrix box, - bool bHasNormalConstraints, - bool bHasAnyConstraints, - warninp_t wi); +void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool bHasAnyConstraints, warninp_t wi); /* Do more checks */ -void triple_check(const char *mdparin, t_inputrec *ir, gmx_mtop_t *sys, - warninp_t wi); +void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_t wi); /* Do even more checks */ -void get_ir(const char *mdparin, const char *mdparout, - gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts, - WriteMdpHeader writeMdpHeader, warninp_t wi); +void get_ir(const char* mdparin, + const char* mdparout, + gmx::MDModules* mdModules, + t_inputrec* ir, + t_gromppopts* opts, + WriteMdpHeader writeMdpHeader, + warninp_t wi); /* Read the input file, and retrieve data for inputrec. * More data are read, but the are only evaluated when the next * function is called. Also prints the input file back to mdparout. */ -void do_index(const char * mdparin, - const char *ndx, - gmx_mtop_t *mtop, - bool bVerbose, - const gmx::MdModulesNotifier ¬ifier, - t_inputrec *ir, - warninp_t wi); +void do_index(const char* mdparin, + const char* ndx, + gmx_mtop_t* mtop, + bool bVerbose, + const gmx::MdModulesNotifier& notifier, + t_inputrec* ir, + warninp_t wi); /* Read the index file and assign grp numbers to atoms. */ /* Routines In readpull.c */ -char **read_pullparams(std::vector *inp, - pull_params_t *pull, - warninp_t wi); +char** read_pullparams(std::vector* inp, pull_params_t* pull, warninp_t wi); /* Reads the pull parameters, returns a list of the pull group names */ -void make_pull_groups(pull_params_t *pull, - char **pgnames, - const t_blocka *grps, char **gnames); +void make_pull_groups(pull_params_t* pull, char** pgnames, const t_blocka* grps, char** gnames); /* Process the pull group parameters after reading the index groups */ -void make_pull_coords(pull_params_t *pull); +void make_pull_coords(pull_params_t* pull); /* Process the pull coordinates after reading the pull groups */ -pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, - rvec *x, matrix box, real lambda, - warninp_t wi); +pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix box, real lambda, warninp_t wi); /* Prints the initial pull group distances in x. * If requested, adds the current distance to the initial reference location. * Returns the pull_t pull work struct. This should be passed to finish_pull() * after all modules have registered their external potentials, if present. */ -char **read_rotparams(std::vector *inp, t_rot *rot, warninp_t wi); +char** read_rotparams(std::vector* inp, t_rot* rot, warninp_t wi); /* Reads enforced rotation parameters, returns a list of the rot group names */ -void make_rotation_groups(t_rot *rot, char **rotgnames, - t_blocka *grps, char **gnames); +void make_rotation_groups(t_rot* rot, char** rotgnames, t_blocka* grps, char** gnames); /* Process the rotation parameters after reading the index groups */ -void set_reference_positions(t_rot *rot, rvec *x, matrix box, - const char *fn, bool bSet, warninp_t wi); +void set_reference_positions(t_rot* rot, rvec* x, matrix box, const char* fn, bool bSet, warninp_t wi); #endif diff --git a/src/gromacs/gmxpreprocess/readpull.cpp b/src/gromacs/gmxpreprocess/readpull.cpp index d87bb5c155..238aca95ca 100644 --- a/src/gromacs/gmxpreprocess/readpull.cpp +++ b/src/gromacs/gmxpreprocess/readpull.cpp @@ -68,8 +68,7 @@ static void string2dvec(const char buf[], dvec nums) } } -static void init_pull_group(t_pull_group *pg, - const char *wbuf) +static void init_pull_group(t_pull_group* pg, const char* wbuf) { double d; int n; @@ -79,17 +78,17 @@ static void init_pull_group(t_pull_group *pg, { if (pg->nweight % 100 == 0) { - srenew(pg->weight, pg->nweight+100); + srenew(pg->weight, pg->nweight + 100); } pg->weight[pg->nweight++] = d; wbuf += n; } } -static void process_pull_dim(char *dim_buf, ivec dim, const t_pull_coord *pcrd) +static void process_pull_dim(char* dim_buf, ivec dim, const t_pull_coord* pcrd) { - int ndim, d, nchar; - char *ptr, pulldim1[STRLEN]; + int ndim, d, nchar; + char *ptr, pulldim1[STRLEN]; ptr = dim_buf; ndim = 0; @@ -97,8 +96,7 @@ static void process_pull_dim(char *dim_buf, ivec dim, const t_pull_coord *pcrd) { if (sscanf(ptr, "%s%n", pulldim1, &nchar) != 1) { - gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'", - dim_buf); + gmx_fatal(FARGS, "Less than 3 pull dimensions given in pull_dim: '%s'", dim_buf); } if (gmx::equalCaseInsensitive(pulldim1, "N", 1)) @@ -112,8 +110,7 @@ static void process_pull_dim(char *dim_buf, ivec dim, const t_pull_coord *pcrd) } else { - gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)", - pulldim1); + gmx_fatal(FARGS, "Please use Y(ES) or N(O) for pull_dim only (not %s)", pulldim1); } ptr += nchar; } @@ -125,47 +122,52 @@ static void process_pull_dim(char *dim_buf, ivec dim, const t_pull_coord *pcrd) { gmx_fatal(FARGS, "Pull geometry dihedral is only useful with pull-dim = Y Y Y"); } - if ((pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS ) && (ndim < 2)) + if ((pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS) && (ndim < 2)) { - gmx_fatal(FARGS, "Pull geometry %s is only useful with pull-dim = Y for at least 2 dimensions", + gmx_fatal(FARGS, + "Pull geometry %s is only useful with pull-dim = Y for at least 2 dimensions", EPULLGEOM(pcrd->eGeom)); } } -static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, - char *dim_buf, - const char *origin_buf, const char *vec_buf, - warninp_t wi) +static void init_pull_coord(t_pull_coord* pcrd, + int coord_index_for_output, + char* dim_buf, + const char* origin_buf, + const char* vec_buf, + warninp_t wi) { - int m; - dvec origin, vec; - char buf[STRLEN]; + int m; + dvec origin, vec; + char buf[STRLEN]; - if (pcrd->eType == epullCONSTRAINT && (pcrd->eGeom == epullgCYL || - pcrd->eGeom == epullgDIRRELATIVE || - pcrd->eGeom == epullgANGLE || - pcrd->eGeom == epullgANGLEAXIS || - pcrd->eGeom == epullgDIHEDRAL)) + if (pcrd->eType == epullCONSTRAINT + && (pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRRELATIVE || pcrd->eGeom == epullgANGLE + || pcrd->eGeom == epullgANGLEAXIS || pcrd->eGeom == epullgDIHEDRAL)) { - gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.", - epull_names[pcrd->eType], - epullg_names[pcrd->eGeom], - epull_names[epullUMBRELLA]); + gmx_fatal(FARGS, + "Pulling of type %s can not be combined with geometry %s. Consider using pull " + "type %s.", + epull_names[pcrd->eType], epullg_names[pcrd->eGeom], epull_names[epullUMBRELLA]); } if (pcrd->eType == epullEXTERNAL) { if (pcrd->externalPotentialProvider[0] == '\0') { - sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the name of the module providing the potential external is set with the option %s%d%s", - epull_names[pcrd->eType], coord_index_for_output, - "pull-coord", coord_index_for_output, "-potential-provider"); + sprintf(buf, + "The use of pull type '%s' for pull coordinate %d requires that the name of " + "the module providing the potential external is set with the option %s%d%s", + epull_names[pcrd->eType], coord_index_for_output, "pull-coord", + coord_index_for_output, "-potential-provider"); warning_error(wi, buf); } if (pcrd->rate != 0) { - sprintf(buf, "The use of pull type '%s' for pull coordinate %d requires that the pull rate is zero", + sprintf(buf, + "The use of pull type '%s' for pull coordinate %d requires that the pull rate " + "is zero", epull_names[pcrd->eType], coord_index_for_output); warning_error(wi, buf); } @@ -175,7 +177,10 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, /* Warn the user of a PBC restriction, caused by the fact that * there is no reference value with an external pull potential. */ - sprintf(buf, "With pull type '%s' and geometry '%s', the distance component along the cylinder axis between atoms in the cylinder group and the COM of the pull group should be smaller than half the box length", + sprintf(buf, + "With pull type '%s' and geometry '%s', the distance component along the " + "cylinder axis between atoms in the cylinder group and the COM of the pull " + "group should be smaller than half the box length", epull_names[pcrd->eType], epullg_names[pcrd->eGeom]); warning_note(wi, buf); } @@ -194,8 +199,11 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, { if (pcrd->bStart && pcrd->init < 0) { - sprintf(buf, "The initial reference distance set by pull-coord-init is set to a negative value (%g) with geometry %s while distances need to be non-negative. " - "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting distances. " + sprintf(buf, + "The initial reference distance set by pull-coord-init is set to a negative " + "value (%g) with geometry %s while distances need to be non-negative. " + "This may work, since you have set pull-coord-start to 'yes' which modifies " + "this value, but only for certain starting distances. " "If this is a mistake you may want to use geometry %s instead.", pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR)); warning(wi, buf); @@ -206,8 +214,11 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, if (pcrd->bStart && (pcrd->init < 0 || pcrd->init > 180)) { /* This value of pcrd->init may be ok depending on pcrd->bStart which modifies pcrd->init later on */ - sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [0, 180] degrees for geometry (%s). " - "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.", + sprintf(buf, + "The initial reference angle set by pull-coord-init (%g) is outside of the " + "allowed range [0, 180] degrees for geometry (%s). " + "This may work, since you have set pull-coord-start to 'yes' which modifies " + "this value, but only for certain starting angles.", pcrd->init, EPULLGEOM(pcrd->eGeom)); warning(wi, buf); } @@ -216,8 +227,11 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, { if (pcrd->bStart && (pcrd->init < -180 || pcrd->init > 180)) { - sprintf(buf, "The initial reference angle set by pull-coord-init (%g) is outside of the allowed range [-180, 180] degrees for geometry (%s). " - "This may work, since you have set pull-coord-start to 'yes' which modifies this value, but only for certain starting angles.", + sprintf(buf, + "The initial reference angle set by pull-coord-init (%g) is outside of the " + "allowed range [-180, 180] degrees for geometry (%s). " + "This may work, since you have set pull-coord-start to 'yes' which modifies " + "this value, but only for certain starting angles.", pcrd->init, EPULLGEOM(pcrd->eGeom)); warning(wi, buf); } @@ -227,7 +241,8 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, clear_dvec(vec); string2dvec(vec_buf, vec); - if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRPBC || pcrd->eGeom == epullgANGLEAXIS) + if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRPBC + || pcrd->eGeom == epullgANGLEAXIS) { if (dnorm2(vec) == 0) { @@ -238,18 +253,23 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, { if (vec[d] != 0 && pcrd->dim[d] == 0) { - gmx_fatal(FARGS, "pull-coord-vec has non-zero %c-component while pull_dim for the %c-dimension is set to N", 'x'+d, 'x'+d); + gmx_fatal(FARGS, + "pull-coord-vec has non-zero %c-component while pull_dim for the " + "%c-dimension is set to N", + 'x' + d, 'x' + d); } } /* Normalize the direction vector */ - dsvmul(1/dnorm(vec), vec, vec); + dsvmul(1 / dnorm(vec), vec, vec); } else /* This case is for are all the geometries where the pull vector is not used */ { if (dnorm2(vec) > 0) { - sprintf(buf, "A pull vector is given (%g %g %g) but will not be used with geometry %s. If you really want to use this " + sprintf(buf, + "A pull vector is given (%g %g %g) but will not be used with geometry %s. If " + "you really want to use this " "vector, consider using geometry %s instead.", vec[0], vec[1], vec[2], EPULLGEOM(pcrd->eGeom), pcrd->eGeom == epullgANGLE ? EPULLGEOM(epullgANGLEAXIS) : EPULLGEOM(epullgDIR)); @@ -263,28 +283,26 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output, } } -char **read_pullparams(std::vector *inp, - pull_params_t *pull, - warninp_t wi) +char** read_pullparams(std::vector* inp, pull_params_t* pull, warninp_t wi) { - int nscan, idum; - char **grpbuf; - char buf[STRLEN]; - char provider[STRLEN], groups[STRLEN], dim_buf[STRLEN]; - char wbuf[STRLEN], origin_buf[STRLEN], vec_buf[STRLEN]; + int nscan, idum; + char** grpbuf; + char buf[STRLEN]; + char provider[STRLEN], groups[STRLEN], dim_buf[STRLEN]; + char wbuf[STRLEN], origin_buf[STRLEN], vec_buf[STRLEN]; - t_pull_group *pgrp; - t_pull_coord *pcrd; + t_pull_group* pgrp; + t_pull_coord* pcrd; /* read pull parameters */ printStringNoNewline(inp, "Cylinder radius for dynamic reaction force groups (nm)"); - pull->cylinder_r = get_ereal(inp, "pull-cylinder-r", 1.5, wi); - pull->constr_tol = get_ereal(inp, "pull-constr-tol", 1E-6, wi); - pull->bPrintCOM = (get_eeenum(inp, "pull-print-com", yesno_names, wi) != 0); - pull->bPrintRefValue = (get_eeenum(inp, "pull-print-ref-value", yesno_names, wi) != 0); - pull->bPrintComp = (get_eeenum(inp, "pull-print-components", yesno_names, wi) != 0); - pull->nstxout = get_eint(inp, "pull-nstxout", 50, wi); - pull->nstfout = get_eint(inp, "pull-nstfout", 50, wi); + pull->cylinder_r = get_ereal(inp, "pull-cylinder-r", 1.5, wi); + pull->constr_tol = get_ereal(inp, "pull-constr-tol", 1E-6, wi); + pull->bPrintCOM = (get_eeenum(inp, "pull-print-com", yesno_names, wi) != 0); + pull->bPrintRefValue = (get_eeenum(inp, "pull-print-ref-value", yesno_names, wi) != 0); + pull->bPrintComp = (get_eeenum(inp, "pull-print-components", yesno_names, wi) != 0); + pull->nstxout = get_eint(inp, "pull-nstxout", 50, wi); + pull->nstfout = get_eint(inp, "pull-nstfout", 50, wi); pull->bSetPbcRefToPrevStepCOM = (get_eeenum(inp, "pull-pbc-ref-prev-step-com", yesno_names, wi) != 0); pull->bXOutAverage = (get_eeenum(inp, "pull-xout-average", yesno_names, wi) != 0); pull->bFOutAverage = (get_eeenum(inp, "pull-fout-average", yesno_names, wi) != 0); @@ -346,22 +364,19 @@ char **read_pullparams(std::vector *inp, switch (pcrd->eGeom) { - case epullgDIHEDRAL: - pcrd->ngroup = 6; break; + case epullgDIHEDRAL: pcrd->ngroup = 6; break; case epullgDIRRELATIVE: - case epullgANGLE: - pcrd->ngroup = 4; break; - default: - pcrd->ngroup = 2; break; + case epullgANGLE: pcrd->ngroup = 4; break; + default: pcrd->ngroup = 2; break; } - nscan = sscanf(groups, "%d %d %d %d %d %d %d", - &pcrd->group[0], &pcrd->group[1], &pcrd->group[2], &pcrd->group[3], - &pcrd->group[4], &pcrd->group[5], &idum); + nscan = sscanf(groups, "%d %d %d %d %d %d %d", &pcrd->group[0], &pcrd->group[1], + &pcrd->group[2], &pcrd->group[3], &pcrd->group[4], &pcrd->group[5], &idum); if (nscan != pcrd->ngroup) { - auto message = gmx::formatString("%s should contain %d pull group indices with geometry %s", - buf, pcrd->ngroup, epullg_names[pcrd->eGeom]); + auto message = + gmx::formatString("%s should contain %d pull group indices with geometry %s", + buf, pcrd->ngroup, epullg_names[pcrd->eGeom]); set_warning_line(wi, nullptr, -1); warning_error(wi, message); } @@ -370,7 +385,8 @@ char **read_pullparams(std::vector *inp, if (pcrd->group[g] < 0 || pcrd->group[g] >= pull->ngroup) { /* Quit with a fatal error to avoid invalid memory access */ - gmx_fatal(FARGS, "%s contains an invalid pull group %d, you should have %d <= group <= %d", + gmx_fatal(FARGS, + "%s contains an invalid pull group %d, you should have %d <= group <= %d", buf, pcrd->group[g], 0, pull->ngroup - 1); } } @@ -399,12 +415,10 @@ char **read_pullparams(std::vector *inp, return grpbuf; } -void make_pull_groups(pull_params_t *pull, - char **pgnames, - const t_blocka *grps, char **gnames) +void make_pull_groups(pull_params_t* pull, char** pgnames, const t_blocka* grps, char** gnames) { int g, ig = -1, i; - t_pull_group *pgrp; + t_pull_group* pgrp; /* Absolute reference group (might not be used) is special */ pgrp = &pull->group[0]; @@ -423,10 +437,9 @@ void make_pull_groups(pull_params_t *pull, } ig = search_string(pgnames[g], grps->nr, gnames); - pgrp->nat = grps->index[ig+1] - grps->index[ig]; + pgrp->nat = grps->index[ig + 1] - grps->index[ig]; - fprintf(stderr, "Pull group %d '%s' has %d atoms\n", - g, pgnames[g], pgrp->nat); + fprintf(stderr, "Pull group %d '%s' has %d atoms\n", g, pgnames[g], pgrp->nat); if (pgrp->nat == 0) { @@ -436,12 +449,14 @@ void make_pull_groups(pull_params_t *pull, snew(pgrp->ind, pgrp->nat); for (i = 0; i < pgrp->nat; i++) { - pgrp->ind[i] = grps->a[grps->index[ig]+i]; + pgrp->ind[i] = grps->a[grps->index[ig] + i]; } if (pgrp->nweight > 0 && pgrp->nweight != pgrp->nat) { - gmx_fatal(FARGS, "Number of weights (%d) for pull group %d '%s' does not match the number of atoms (%d)", + gmx_fatal(FARGS, + "Number of weights (%d) for pull group %d '%s' does not match the number of " + "atoms (%d)", pgrp->nweight, g, pgnames[g], pgrp->nat); } @@ -458,7 +473,7 @@ void make_pull_groups(pull_params_t *pull, } else if (pgrp->pbcatom == 0) { - pgrp->pbcatom = pgrp->ind[(pgrp->nat-1)/2]; + pgrp->pbcatom = pgrp->ind[(pgrp->nat - 1) / 2]; } else { @@ -469,51 +484,54 @@ void make_pull_groups(pull_params_t *pull, } } -void make_pull_coords(pull_params_t *pull) +void make_pull_coords(pull_params_t* pull) { int c; - t_pull_coord *pcrd; + t_pull_coord* pcrd; for (c = 0; c < pull->ncoord; c++) { pcrd = &pull->coord[c]; - if (pcrd->group[0] < 0 || pcrd->group[0] >= pull->ngroup || - pcrd->group[1] < 0 || pcrd->group[1] >= pull->ngroup) + if (pcrd->group[0] < 0 || pcrd->group[0] >= pull->ngroup || pcrd->group[1] < 0 + || pcrd->group[1] >= pull->ngroup) { - gmx_fatal(FARGS, "Pull group index in pull-coord%d-groups out of range, should be between %d and %d", c+1, 0, pull->ngroup+1); + gmx_fatal(FARGS, + "Pull group index in pull-coord%d-groups out of range, should be between %d " + "and %d", + c + 1, 0, pull->ngroup + 1); } if (pcrd->group[0] == pcrd->group[1]) { - gmx_fatal(FARGS, "Identical pull group indices in pull-coord%d-groups", c+1); + gmx_fatal(FARGS, "Identical pull group indices in pull-coord%d-groups", c + 1); } if (pcrd->eGeom == epullgCYL) { if (pull->group[pcrd->group[0]].nweight > 0) { - gmx_fatal(FARGS, "Weights are not supported for the reference group with cylinder pulling"); + gmx_fatal( + FARGS, + "Weights are not supported for the reference group with cylinder pulling"); } } } } -pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, - rvec *x, matrix box, real lambda, - warninp_t wi) +pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix box, real lambda, warninp_t wi) { - pull_params_t *pull; - pull_t *pull_work; + pull_params_t* pull; + pull_t* pull_work; t_pbc pbc; int c; double t_start; - pull = ir->pull; + pull = ir->pull; gmx::LocalAtomSetManager atomSets; - pull_work = init_pull(nullptr, pull, ir, mtop, nullptr, &atomSets, lambda); - auto mdAtoms = gmx::makeMDAtoms(nullptr, *mtop, *ir, false); - auto md = mdAtoms->mdatoms(); + pull_work = init_pull(nullptr, pull, ir, mtop, nullptr, &atomSets, lambda); + auto mdAtoms = gmx::makeMDAtoms(nullptr, *mtop, *ir, false); + auto md = mdAtoms->mdatoms(); atoms2md(mtop, ir, -1, nullptr, mtop->natoms, mdAtoms.get()); if (ir->efep) { @@ -522,7 +540,7 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, set_pbc(&pbc, ir->ePBC, box); - t_start = ir->init_t + ir->init_step*ir->delta_t; + t_start = ir->init_t + ir->init_step * ir->delta_t; if (pull->bSetPbcRefToPrevStepCOM) { @@ -532,44 +550,48 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, for (int g = 0; g < pull->ngroup; g++) { - bool groupObeysPbc = - pullCheckPbcWithinGroup(*pull_work, - gmx::arrayRefFromArray(reinterpret_cast(x), - mtop->natoms), - pbc, g, c_pullGroupSmallGroupThreshold); + bool groupObeysPbc = pullCheckPbcWithinGroup( + *pull_work, gmx::arrayRefFromArray(reinterpret_cast(x), mtop->natoms), + pbc, g, c_pullGroupSmallGroupThreshold); if (!groupObeysPbc) { char buf[STRLEN]; if (pull->group[g].pbcatom_input == 0) { - sprintf(buf, "When the maximum distance from a pull group reference atom to other atoms in the " + sprintf(buf, + "When the maximum distance from a pull group reference atom to other atoms " + "in the " "group is larger than %g times half the box size a centrally placed " - "atom should be chosen as pbcatom. Pull group %d is larger than that and does not have " - "a specific atom selected as reference atom.", c_pullGroupSmallGroupThreshold, g); + "atom should be chosen as pbcatom. Pull group %d is larger than that and " + "does not have " + "a specific atom selected as reference atom.", + c_pullGroupSmallGroupThreshold, g); warning_error(wi, buf); } else if (!pull->bSetPbcRefToPrevStepCOM) { - sprintf(buf, "The maximum distance from the chosen PBC atom (%d) of pull group %d to other " + sprintf(buf, + "The maximum distance from the chosen PBC atom (%d) of pull group %d to " + "other " "atoms in the group is larger than %g times half the box size. " - "Set the pull-pbc-ref-prev-step-com option to yes.", pull->group[g].pbcatom + 1, - g, c_pullGroupSmallGroupThreshold); + "Set the pull-pbc-ref-prev-step-com option to yes.", + pull->group[g].pbcatom + 1, g, c_pullGroupSmallGroupThreshold); warning_error(wi, buf); } } if (groupObeysPbc) { - groupObeysPbc = - pullCheckPbcWithinGroup(*pull_work, - gmx::arrayRefFromArray(reinterpret_cast(x), - mtop->natoms), - pbc, g, c_pullGroupPbcMargin); + groupObeysPbc = pullCheckPbcWithinGroup( + *pull_work, gmx::arrayRefFromArray(reinterpret_cast(x), mtop->natoms), + pbc, g, c_pullGroupPbcMargin); if (!groupObeysPbc) { char buf[STRLEN]; sprintf(buf, - "Pull group %d has atoms at a distance larger than %g times half the box size from the PBC atom (%d). " - "If atoms are or will more beyond half the box size from the PBC atom, the COM will be ill defined.", + "Pull group %d has atoms at a distance larger than %g times half the box " + "size from the PBC atom (%d). " + "If atoms are or will more beyond half the box size from the PBC atom, the " + "COM will be ill defined.", g, c_pullGroupPbcMargin, pull->group[g].pbcatom + 1); set_warning_line(wi, nullptr, -1); warning(wi, buf); @@ -580,19 +602,17 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, fprintf(stderr, "Pull group natoms pbc atom distance at start reference at t=0\n"); for (c = 0; c < pull->ncoord; c++) { - t_pull_coord *pcrd; + t_pull_coord* pcrd; t_pull_group *pgrp0, *pgrp1; double value; real init = 0; - pcrd = &pull->coord[c]; + pcrd = &pull->coord[c]; pgrp0 = &pull->group[pcrd->group[0]]; pgrp1 = &pull->group[pcrd->group[1]]; - fprintf(stderr, "%8d %8d %8d\n", - pcrd->group[0], pgrp0->nat, pgrp0->pbcatom+1); - fprintf(stderr, "%8d %8d %8d ", - pcrd->group[1], pgrp1->nat, pgrp1->pbcatom+1); + fprintf(stderr, "%8d %8d %8d\n", pcrd->group[0], pgrp0->nat, pgrp0->pbcatom + 1); + fprintf(stderr, "%8d %8d %8d ", pcrd->group[1], pgrp1->nat, pgrp1->pbcatom + 1); if (pcrd->bStart) { @@ -600,7 +620,7 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, pcrd->init = 0; } - value = get_pull_coord_value(pull_work, c, &pbc); + value = get_pull_coord_value(pull_work, c, &pbc); value *= pull_conversion_factor_internal2userinput(pcrd); fprintf(stderr, " %10.3f %s", value, pull_coordinate_units(pcrd)); @@ -614,7 +634,9 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, { if (pcrd->init < 0) { - gmx_fatal(FARGS, "The initial pull distance (%g) needs to be non-negative with geometry %s. If you want a signed distance, use geometry %s instead.", + gmx_fatal(FARGS, + "The initial pull distance (%g) needs to be non-negative with geometry " + "%s. If you want a signed distance, use geometry %s instead.", pcrd->init, EPULLGEOM(pcrd->eGeom), EPULLGEOM(epullgDIR)); } @@ -630,14 +652,19 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop, { if (pcrd->init < 0 || pcrd->init > 180) { - gmx_fatal(FARGS, "The initial pull reference angle (%g) is outside of the allowed range [0, 180] degrees.", pcrd->init); + gmx_fatal(FARGS, + "The initial pull reference angle (%g) is outside of the allowed range " + "[0, 180] degrees.", + pcrd->init); } } else if (pcrd->eGeom == epullgDIHEDRAL) { if (pcrd->init < -180 || pcrd->init > 180) { - gmx_fatal(FARGS, "The initial pull reference angle (%g) is outside of the allowed range [-180, 180] degrees.", + gmx_fatal(FARGS, + "The initial pull reference angle (%g) is outside of the allowed range " + "[-180, 180] degrees.", pcrd->init); } } diff --git a/src/gromacs/gmxpreprocess/readrot.cpp b/src/gromacs/gmxpreprocess/readrot.cpp index 1b423b01c5..88ec8c2515 100644 --- a/src/gromacs/gmxpreprocess/readrot.cpp +++ b/src/gromacs/gmxpreprocess/readrot.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,7 +54,7 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -static const char *RotStr = "Enforced rotation:"; +static const char* RotStr = "Enforced rotation:"; static char s_vec[STRLEN]; @@ -69,20 +69,22 @@ static void string2dvec(char buf[], dvec nums) } -extern char **read_rotparams(std::vector *inp, t_rot *rot, - warninp_t wi) +extern char** read_rotparams(std::vector* inp, t_rot* rot, warninp_t wi) { - int g, m; - char **grpbuf; - char buf[STRLEN]; - char warn_buf[STRLEN]; - dvec vec; - t_rotgrp *rotg; + int g, m; + char** grpbuf; + char buf[STRLEN]; + char warn_buf[STRLEN]; + dvec vec; + t_rotgrp* rotg; /* read rotation parameters */ - printStringNoNewline(inp, "Output frequency for angle, torque and rotation potential energy for the whole group"); + printStringNoNewline( + inp, + "Output frequency for angle, torque and rotation potential energy for the whole group"); rot->nstrout = get_eint(inp, "rot-nstrout", 100, wi); - printStringNoNewline(inp, "Output frequency for per-slab data (angles, torques and slab centers)"); + printStringNoNewline(inp, + "Output frequency for per-slab data (angles, torques and slab centers)"); rot->nstsout = get_eint(inp, "rot-nstsout", 1000, wi); printStringNoNewline(inp, "Number of rotation groups"); rot->ngrp = get_eint(inp, "rot-ngroups", 1, wi); @@ -104,7 +106,9 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, sprintf(buf, "rot-group%d", g); setStringEntry(inp, buf, grpbuf[g], ""); - printStringNoNewline(inp, "Rotation potential. Can be iso, iso-pf, pm, pm-pf, rm, rm-pf, rm2, rm2-pf, flex, flex-t, flex2, flex2-t"); + printStringNoNewline(inp, + "Rotation potential. Can be iso, iso-pf, pm, pm-pf, rm, rm-pf, rm2, " + "rm2-pf, flex, flex-t, flex2, flex2-t"); sprintf(buf, "rot-type%d", g); rotg->eType = get_eenum(inp, buf, erotg_names); @@ -119,15 +123,15 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, /* Normalize the rotation vector */ if (dnorm(vec) != 0) { - dsvmul(1.0/dnorm(vec), vec, vec); + dsvmul(1.0 / dnorm(vec), vec, vec); } else { sprintf(warn_buf, "rot-vec%d = 0", g); warning_error(wi, warn_buf); } - fprintf(stderr, "%s Group %d (%s) normalized rot. vector: %f %f %f\n", - RotStr, g, erotg_names[rotg->eType], vec[0], vec[1], vec[2]); + fprintf(stderr, "%s Group %d (%s) normalized rot. vector: %f %f %f\n", RotStr, g, + erotg_names[rotg->eType], vec[0], vec[1], vec[2]); for (m = 0; m < DIM; m++) { rotg->inputVec[m] = vec[m]; @@ -137,7 +141,8 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, sprintf(buf, "rot-pivot%d", g); setStringEntry(inp, buf, s_vec, "0.0 0.0 0.0"); clear_dvec(vec); - if ( (rotg->eType == erotgISO) || (rotg->eType == erotgPM) || (rotg->eType == erotgRM) || (rotg->eType == erotgRM2) ) + if ((rotg->eType == erotgISO) || (rotg->eType == erotgPM) || (rotg->eType == erotgRM) + || (rotg->eType == erotgRM2)) { string2dvec(s_vec, vec); } @@ -167,7 +172,9 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, warning_error(wi, warn_buf); } - printStringNoNewline(inp, "Minimum value of Gaussian function for the force to be evaluated (for flex* potentials)"); + printStringNoNewline(inp, + "Minimum value of Gaussian function for the force to be evaluated " + "(for flex* potentials)"); sprintf(buf, "rot-min-gauss%d", g); rotg->min_gaussian = get_ereal(inp, buf, 1e-3, wi); if (rotg->min_gaussian <= 0.0) @@ -176,27 +183,34 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, warning_error(wi, warn_buf); } - printStringNoNewline(inp, "Value of additive constant epsilon' (nm^2) for rm2* and flex2* potentials"); + printStringNoNewline( + inp, "Value of additive constant epsilon' (nm^2) for rm2* and flex2* potentials"); sprintf(buf, "rot-eps%d", g); rotg->eps = get_ereal(inp, buf, 1e-4, wi); - if ( (rotg->eps <= 0.0) && (rotg->eType == erotgRM2 || rotg->eType == erotgFLEX2) ) + if ((rotg->eps <= 0.0) && (rotg->eType == erotgRM2 || rotg->eType == erotgFLEX2)) { sprintf(warn_buf, "rot-eps%d <= 0", g); warning_error(wi, warn_buf); } - printStringNoNewline(inp, "Fitting method to determine angle of rotation group (rmsd, norm, or potential)"); + printStringNoNewline( + inp, + "Fitting method to determine angle of rotation group (rmsd, norm, or potential)"); sprintf(buf, "rot-fit-method%d", g); rotg->eFittype = get_eenum(inp, buf, erotg_fitnames); - printStringNoNewline(inp, "For fit type 'potential', nr. of angles around the reference for which the pot. is evaluated"); + printStringNoNewline(inp, + "For fit type 'potential', nr. of angles around the reference for " + "which the pot. is evaluated"); sprintf(buf, "rot-potfit-nsteps%d", g); rotg->PotAngle_nstep = get_eint(inp, buf, 21, wi); - if ( (rotg->eFittype == erotgFitPOT) && (rotg->PotAngle_nstep < 1) ) + if ((rotg->eFittype == erotgFitPOT) && (rotg->PotAngle_nstep < 1)) { sprintf(warn_buf, "rot-potfit-nsteps%d < 1", g); warning_error(wi, warn_buf); } - printStringNoNewline(inp, "For fit type 'potential', distance in degrees between two consecutive angles"); + printStringNoNewline( + inp, + "For fit type 'potential', distance in degrees between two consecutive angles"); sprintf(buf, "rot-potfit-step%d", g); rotg->PotAngle_step = get_ereal(inp, buf, 0.25, wi); } @@ -208,9 +222,9 @@ extern char **read_rotparams(std::vector *inp, t_rot *rot, /* Check whether the box is unchanged */ static void check_box_unchanged(matrix f_box, matrix box, const char fn[], warninp_t wi) { - int i, ii; - bool bSame = TRUE; - char warn_buf[STRLEN]; + int i, ii; + bool bSame = TRUE; + char warn_buf[STRLEN]; for (i = 0; i < DIM; i++) @@ -225,8 +239,7 @@ static void check_box_unchanged(matrix f_box, matrix box, const char fn[], warni } if (!bSame) { - sprintf(warn_buf, "%s Box size in reference file %s differs from actual box size!", - RotStr, fn); + sprintf(warn_buf, "%s Box size in reference file %s differs from actual box size!", RotStr, fn); warning(wi, warn_buf); pr_rvecs(stderr, 0, "Your box is:", box, 3); pr_rvecs(stderr, 0, "Box in file:", f_box, 3); @@ -235,12 +248,10 @@ static void check_box_unchanged(matrix f_box, matrix box, const char fn[], warni /* Extract the reference positions for the rotation group(s) */ -extern void set_reference_positions( - t_rot *rot, rvec *x, matrix box, - const char *fn, bool bSet, warninp_t wi) +extern void set_reference_positions(t_rot* rot, rvec* x, matrix box, const char* fn, bool bSet, warninp_t wi) { int g, i, ii; - t_rotgrp *rotg; + t_rotgrp* rotg; gmx_trr_header_t header; /* Header information of reference file */ rvec f_box[3]; /* Box from reference file */ @@ -251,14 +262,16 @@ extern void set_reference_positions( snew(rotg->x_ref, rotg->nat); /* Construct the name for the file containing the reference positions for this group: */ - std::string reffileString = gmx::Path::concatenateBeforeExtension(fn, gmx::formatString(".%d", g)); - const char *reffile = reffileString.c_str(); + std::string reffileString = + gmx::Path::concatenateBeforeExtension(fn, gmx::formatString(".%d", g)); + const char* reffile = reffileString.c_str(); /* If the base filename for the reference position files was explicitly set by * the user, we issue a fatal error if the group file can not be found */ if (bSet && !gmx_fexist(reffile)) { - gmx_fatal(FARGS, "%s The file containing the reference positions was not found.\n" + gmx_fatal(FARGS, + "%s The file containing the reference positions was not found.\n" "Expected the file '%s' for group %d.\n", RotStr, reffile, g); } @@ -269,10 +282,13 @@ extern void set_reference_positions( gmx_trr_read_single_header(reffile, &header); if (rotg->nat != header.natoms) { - gmx_fatal(FARGS, "Number of atoms in file %s (%d) does not match the number of atoms in rotation group (%d)!\n", + gmx_fatal(FARGS, + "Number of atoms in file %s (%d) does not match the number of atoms in " + "rotation group (%d)!\n", reffile, header.natoms, rotg->nat); } - gmx_trr_read_single_frame(reffile, &header.step, &header.t, &header.lambda, f_box, &header.natoms, rotg->x_ref, nullptr, nullptr); + gmx_trr_read_single_frame(reffile, &header.step, &header.t, &header.lambda, f_box, + &header.natoms, rotg->x_ref, nullptr, nullptr); /* Check whether the box is unchanged and output a warning if not: */ check_box_unchanged(f_box, box, reffile, wi); @@ -291,17 +307,17 @@ extern void set_reference_positions( } -extern void make_rotation_groups(t_rot *rot, char **rotgnames, t_blocka *grps, char **gnames) +extern void make_rotation_groups(t_rot* rot, char** rotgnames, t_blocka* grps, char** gnames) { int g, ig = -1, i; - t_rotgrp *rotg; + t_rotgrp* rotg; for (g = 0; g < rot->ngrp; g++) { rotg = &rot->grp[g]; ig = search_string(rotgnames[g], grps->nr, gnames); - rotg->nat = grps->index[ig+1] - grps->index[ig]; + rotg->nat = grps->index[ig + 1] - grps->index[ig]; if (rotg->nat > 0) { @@ -309,7 +325,7 @@ extern void make_rotation_groups(t_rot *rot, char **rotgnames, t_blocka *grps, c snew(rotg->ind, rotg->nat); for (i = 0; i < rotg->nat; i++) { - rotg->ind[i] = grps->a[grps->index[ig]+i]; + rotg->ind[i] = grps->a[grps->index[ig] + i]; } } else diff --git a/src/gromacs/gmxpreprocess/resall.cpp b/src/gromacs/gmxpreprocess/resall.cpp index 60df05b6fb..3d9ee28d8f 100644 --- a/src/gromacs/gmxpreprocess/resall.cpp +++ b/src/gromacs/gmxpreprocess/resall.cpp @@ -61,19 +61,19 @@ #include "hackblock.h" -PreprocessingAtomTypes read_atype(const char *ffdir, t_symtab *tab) +PreprocessingAtomTypes read_atype(const char* ffdir, t_symtab* tab) { - FILE *in; - char buf[STRLEN], name[STRLEN]; - double m; - int nratt = 0; - t_atom *a; + FILE* in; + char buf[STRLEN], name[STRLEN]; + double m; + int nratt = 0; + t_atom* a; std::vector files = fflib_search_file_end(ffdir, ".atp", TRUE); snew(a, 1); - PreprocessingAtomTypes at; + PreprocessingAtomTypes at; - for (const auto &filename : files) + for (const auto& filename : files) { in = fflib_open(filename); while (!feof(in)) @@ -86,8 +86,7 @@ PreprocessingAtomTypes read_atype(const char *ffdir, t_symtab *tab) strip_comment(buf); trim(buf); } - } - while ((feof(in) == 0) && strlen(buf) == 0); + } while ((feof(in) == 0) && strlen(buf) == 0); if (sscanf(buf, "%s%lf", name, &m) == 2) { @@ -108,7 +107,7 @@ PreprocessingAtomTypes read_atype(const char *ffdir, t_symtab *tab) return at; } -static void print_resatoms(FILE *out, const PreprocessingAtomTypes &atype, const PreprocessResidue &rtpDBEntry) +static void print_resatoms(FILE* out, const PreprocessingAtomTypes& atype, const PreprocessResidue& rtpDBEntry) { fprintf(out, "[ %s ]\n", rtpDBEntry.resname.c_str()); fprintf(out, " [ atoms ]\n"); @@ -116,18 +115,17 @@ static void print_resatoms(FILE *out, const PreprocessingAtomTypes &atype, const for (int j = 0; (j < rtpDBEntry.natom()); j++) { int tp = rtpDBEntry.atom[j].type; - const char *tpnm = atype.atomNameFromAtomType(tp); + const char* tpnm = atype.atomNameFromAtomType(tp); if (tpnm == nullptr) { gmx_fatal(FARGS, "Incorrect atomtype (%d)", tp); } - fprintf(out, "%6s %6s %8.3f %6d\n", - *(rtpDBEntry.atomname[j]), tpnm, rtpDBEntry.atom[j].q, rtpDBEntry.cgnr[j]); + fprintf(out, "%6s %6s %8.3f %6d\n", *(rtpDBEntry.atomname[j]), tpnm, + rtpDBEntry.atom[j].q, rtpDBEntry.cgnr[j]); } } -static bool read_atoms(FILE *in, char *line, - PreprocessResidue *r0, t_symtab *tab, PreprocessingAtomTypes *atype) +static bool read_atoms(FILE* in, char* line, PreprocessResidue* r0, t_symtab* tab, PreprocessingAtomTypes* atype) { int cg; char buf[256], buf1[256]; @@ -147,11 +145,13 @@ static bool read_atoms(FILE *in, char *line, r0->atom.emplace_back(); r0->atom.back().q = q; r0->cgnr.push_back(cg); - int j = atype->atomTypeFromName(buf1); + int j = atype->atomTypeFromName(buf1); if (j == NOTSET) { - gmx_fatal(FARGS, "Atom type %s (residue %s) not found in atomtype " - "database", buf1, r0->resname.c_str()); + gmx_fatal(FARGS, + "Atom type %s (residue %s) not found in atomtype " + "database", + buf1, r0->resname.c_str()); } r0->atom.back().type = j; r0->atom.back().m = atype->atomMassFromAtomType(j); @@ -160,21 +160,21 @@ static bool read_atoms(FILE *in, char *line, return TRUE; } -static bool read_bondeds(int bt, FILE *in, char *line, PreprocessResidue *rtpDBEntry) +static bool read_bondeds(int bt, FILE* in, char* line, PreprocessResidue* rtpDBEntry) { char str[STRLEN]; while (get_a_line(in, line, STRLEN) && (strchr(line, '[') == nullptr)) { - int n = 0; - int ni; + int n = 0; + int ni; rtpDBEntry->rb[bt].b.emplace_back(); - BondedInteraction *newBond = &rtpDBEntry->rb[bt].b.back(); + BondedInteraction* newBond = &rtpDBEntry->rb[bt].b.back(); for (int j = 0; j < btsNiatoms[bt]; j++) { - if (sscanf(line+n, "%s%n", str, &ni) == 1) + if (sscanf(line + n, "%s%n", str, &ni) == 1) { - newBond->a[j] = str; + newBond->a[j] = str; } else { @@ -186,20 +186,20 @@ static bool read_bondeds(int bt, FILE *in, char *line, PreprocessResidue *rtpDBE { n++; } - rtrim(line+n); - newBond->s = line+n; + rtrim(line + n); + newBond->s = line + n; } return TRUE; } -static void print_resbondeds(FILE *out, int bt, const PreprocessResidue &rtpDBEntry) +static void print_resbondeds(FILE* out, int bt, const PreprocessResidue& rtpDBEntry) { if (!rtpDBEntry.rb[bt].b.empty()) { fprintf(out, " [ %s ]\n", btsNames[bt]); - for (const auto &b : rtpDBEntry.rb[bt].b) + for (const auto& b : rtpDBEntry.rb[bt].b) { for (int j = 0; j < btsNiatoms[bt]; j++) { @@ -214,16 +214,15 @@ static void print_resbondeds(FILE *out, int bt, const PreprocessResidue &rtpDBEn } } -static void check_rtp(gmx::ArrayRef rtpDBEntry, const std::string &libfn) +static void check_rtp(gmx::ArrayRef rtpDBEntry, const std::string& libfn) { /* check for double entries, assuming list is already sorted */ for (auto it = rtpDBEntry.begin() + 1; it != rtpDBEntry.end(); it++) { - auto prev = it-1; + auto prev = it - 1; if (gmx::equalCaseInsensitive(prev->resname, it->resname)) { - fprintf(stderr, "WARNING double entry %s in file %s\n", - it->resname.c_str(), libfn.c_str()); + fprintf(stderr, "WARNING double entry %s in file %s\n", it->resname.c_str(), libfn.c_str()); } } } @@ -243,23 +242,20 @@ static int get_bt(char* header) } /* print all the ebtsNR type numbers */ -static void print_resall_header(FILE *out, gmx::ArrayRef rtpDBEntry) +static void print_resall_header(FILE* out, gmx::ArrayRef rtpDBEntry) { fprintf(out, "[ bondedtypes ]\n"); - fprintf(out, "; bonds angles dihedrals impropers all_dihedrals nr_exclusions HH14 remove_dih\n"); - fprintf(out, " %5d %6d %9d %9d %14d %14d %14d %14d\n\n", - rtpDBEntry[0].rb[0].type, - rtpDBEntry[0].rb[1].type, - rtpDBEntry[0].rb[2].type, - rtpDBEntry[0].rb[3].type, - static_cast(rtpDBEntry[0].bKeepAllGeneratedDihedrals), - rtpDBEntry[0].nrexcl, + fprintf(out, + "; bonds angles dihedrals impropers all_dihedrals nr_exclusions HH14 " + "remove_dih\n"); + fprintf(out, " %5d %6d %9d %9d %14d %14d %14d %14d\n\n", rtpDBEntry[0].rb[0].type, + rtpDBEntry[0].rb[1].type, rtpDBEntry[0].rb[2].type, rtpDBEntry[0].rb[3].type, + static_cast(rtpDBEntry[0].bKeepAllGeneratedDihedrals), rtpDBEntry[0].nrexcl, static_cast(rtpDBEntry[0].bGenerateHH14Interactions), static_cast(rtpDBEntry[0].bRemoveDihedralIfWithImproper)); } -void print_resall(FILE *out, gmx::ArrayRef rtpDBEntry, - const PreprocessingAtomTypes &atype) +void print_resall(FILE* out, gmx::ArrayRef rtpDBEntry, const PreprocessingAtomTypes& atype) { if (rtpDBEntry.empty()) { @@ -268,7 +264,7 @@ void print_resall(FILE *out, gmx::ArrayRef rtpDBEntry, print_resall_header(out, rtpDBEntry); - for (const auto &r : rtpDBEntry) + for (const auto& r : rtpDBEntry) { if (r.natom() > 0) { @@ -281,15 +277,17 @@ void print_resall(FILE *out, gmx::ArrayRef rtpDBEntry, } } -void readResidueDatabase(const std::string &rrdb, std::vector *rtpDBEntry, - PreprocessingAtomTypes *atype, t_symtab *tab, - bool bAllowOverrideRTP) +void readResidueDatabase(const std::string& rrdb, + std::vector* rtpDBEntry, + PreprocessingAtomTypes* atype, + t_symtab* tab, + bool bAllowOverrideRTP) { - FILE *in; - char filebase[STRLEN], line[STRLEN], header[STRLEN]; - int bt, nparam; - int dum1, dum2, dum3; - bool bNextResidue, bError; + FILE* in; + char filebase[STRLEN], line[STRLEN], header[STRLEN]; + int bt, nparam; + int dum1, dum2, dum3; + bool bNextResidue, bError; fflib_filename_base(rrdb.c_str(), filebase, STRLEN); @@ -336,12 +334,14 @@ void readResidueDatabase(const std::string &rrdb, std::vector if (gmx::equalCaseInsensitive("bondedtypes", header, 5)) { get_a_line(in, line, STRLEN); - if ((nparam = sscanf(line, "%d %d %d %d %d %d %d %d", - &header_settings.rb[ebtsBONDS].type, &header_settings.rb[ebtsANGLES].type, + if ((nparam = sscanf(line, "%d %d %d %d %d %d %d %d", &header_settings.rb[ebtsBONDS].type, + &header_settings.rb[ebtsANGLES].type, &header_settings.rb[ebtsPDIHS].type, &header_settings.rb[ebtsIDIHS].type, - &dum1, &header_settings.nrexcl, &dum2, &dum3)) < 4) + &dum1, &header_settings.nrexcl, &dum2, &dum3)) + < 4) { - gmx_fatal(FARGS, "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n", rrdb.c_str(), line); + gmx_fatal(FARGS, "need 4 to 8 parameters in the header of .rtp file %s at line:\n%s\n", + rrdb.c_str(), line); } header_settings.bKeepAllGeneratedDihedrals = (dum1 != 0); header_settings.bGenerateHH14Interactions = (dum2 != 0); @@ -364,7 +364,9 @@ void readResidueDatabase(const std::string &rrdb, std::vector } if (nparam < 8) { - fprintf(stderr, "Using default: removing proper dihedrals found on the same bond as a proper dihedral\n"); + fprintf(stderr, + "Using default: removing proper dihedrals found on the same bond as a proper " + "dihedral\n"); header_settings.bRemoveDihedralIfWithImproper = TRUE; } } @@ -381,7 +383,7 @@ void readResidueDatabase(const std::string &rrdb, std::vector { /* Initialise rtp entry structure */ rtpDBEntry->push_back(header_settings); - PreprocessResidue *res = &rtpDBEntry->back(); + PreprocessResidue* res = &rtpDBEntry->back(); if (!get_header(line, header)) { gmx_fatal(FARGS, "in .rtp file at line:\n%s\n", line); @@ -419,21 +421,19 @@ void readResidueDatabase(const std::string &rrdb, std::vector } if (bError) { - gmx_fatal(FARGS, "in .rtp file in residue %s at line:\n%s\n", - res->resname.c_str(), line); + gmx_fatal(FARGS, "in .rtp file in residue %s at line:\n%s\n", res->resname.c_str(), line); } - } - while ((feof(in) == 0) && !bNextResidue); + } while ((feof(in) == 0) && !bNextResidue); if (res->natom() == 0) { - gmx_fatal(FARGS, "No atoms found in .rtp file in residue %s\n", - res->resname.c_str()); + gmx_fatal(FARGS, "No atoms found in .rtp file in residue %s\n", res->resname.c_str()); } - auto found = std::find_if(rtpDBEntry->begin(), rtpDBEntry->end()-1, - [&res](const PreprocessResidue &entry) - { return gmx::equalCaseInsensitive(entry.resname, res->resname); }); + auto found = std::find_if(rtpDBEntry->begin(), rtpDBEntry->end() - 1, + [&res](const PreprocessResidue& entry) { + return gmx::equalCaseInsensitive(entry.resname, res->resname); + }); if (found == rtpDBEntry->end() - 1) { @@ -445,13 +445,15 @@ void readResidueDatabase(const std::string &rrdb, std::vector { if (found >= oldArrayEnd) { - gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'", - res->resname.c_str(), rrdb.c_str()); + gmx_fatal(FARGS, "Found a second entry for '%s' in '%s'", res->resname.c_str(), + rrdb.c_str()); } if (bAllowOverrideRTP) { fprintf(stderr, "\n"); - fprintf(stderr, "Found another rtp entry for '%s' in '%s', ignoring this entry and keeping the one from '%s.rtp'\n", + fprintf(stderr, + "Found another rtp entry for '%s' in '%s', ignoring this entry and keeping " + "the one from '%s.rtp'\n", res->resname.c_str(), rrdb.c_str(), found->filebase.c_str()); /* We should free all the data for this entry. * The current code gives a lot of dangling pointers. @@ -460,21 +462,21 @@ void readResidueDatabase(const std::string &rrdb, std::vector } else { - gmx_fatal(FARGS, "Found rtp entries for '%s' in both '%s' and '%s'. If you want the first definition to override the second one, set the -rtpo option of pdb2gmx.", res->resname.c_str(), found->filebase.c_str(), rrdb.c_str()); + gmx_fatal(FARGS, + "Found rtp entries for '%s' in both '%s' and '%s'. If you want the first " + "definition to override the second one, set the -rtpo option of pdb2gmx.", + res->resname.c_str(), found->filebase.c_str(), rrdb.c_str()); } } } gmx_ffclose(in); fprintf(stderr, "\nSorting it all out...\n"); - std::sort(rtpDBEntry->begin(), rtpDBEntry->end(), [] - (const PreprocessResidue &a, - const PreprocessResidue &b) - {return std::lexicographical_compare( - a.resname.begin(), a.resname.end(), - b.resname.begin(), b.resname.end(), - [](const char &c1, const char &c2) - { return std::toupper(c1) < std::toupper(c2); }); }); + std::sort(rtpDBEntry->begin(), rtpDBEntry->end(), [](const PreprocessResidue& a, const PreprocessResidue& b) { + return std::lexicographical_compare( + a.resname.begin(), a.resname.end(), b.resname.begin(), b.resname.end(), + [](const char& c1, const char& c2) { return std::toupper(c1) < std::toupper(c2); }); + }); check_rtp(*rtpDBEntry, rrdb); } @@ -492,7 +494,7 @@ static bool is_sign(char c) /* Compares if the strins match except for a sign at the end * of (only) one of the two. */ -static int neq_str_sign(const char *a1, const char *a2) +static int neq_str_sign(const char* a1, const char* a2) { int l1, l2, lm; @@ -500,10 +502,8 @@ static int neq_str_sign(const char *a1, const char *a2) l2 = static_cast(strlen(a2)); lm = std::min(l1, l2); - if (lm >= 1 && - ((l1 == l2+1 && is_sign(a1[l1-1])) || - (l2 == l1+1 && is_sign(a2[l2-1]))) && - gmx::equalCaseInsensitive(a1, a2, lm)) + if (lm >= 1 && ((l1 == l2 + 1 && is_sign(a1[l1 - 1])) || (l2 == l1 + 1 && is_sign(a2[l2 - 1]))) + && gmx::equalCaseInsensitive(a1, a2, lm)) { return lm; } @@ -513,15 +513,15 @@ static int neq_str_sign(const char *a1, const char *a2) } } -std::string searchResidueDatabase(const std::string &key, gmx::ArrayRef rtpDBEntry) +std::string searchResidueDatabase(const std::string& key, gmx::ArrayRef rtpDBEntry) { int nbest, best, besti; std::string bestbuf; - nbest = 0; + nbest = 0; besti = -1; /* We want to match at least one character */ - best = 1; + best = 1; for (auto it = rtpDBEntry.begin(); it != rtpDBEntry.end(); it++) { if (gmx::equalCaseInsensitive(key, it->resname)) @@ -534,9 +534,7 @@ std::string searchResidueDatabase(const std::string &key, gmx::ArrayRefresname.c_str()); - if (n >= best && - n+1 >= gmx::index(key.length()) && - n+1 >= gmx::index(it->resname.length())) + if (n >= best && n + 1 >= gmx::index(key.length()) && n + 1 >= gmx::index(it->resname.length())) { if (n == best) { @@ -562,7 +560,8 @@ std::string searchResidueDatabase(const std::string &key, gmx::ArrayRef 1) { - gmx_fatal(FARGS, "Residue '%s' not found in residue topology database, looks a bit like %s", key.c_str(), bestbuf.c_str()); + gmx_fatal(FARGS, "Residue '%s' not found in residue topology database, looks a bit like %s", + key.c_str(), bestbuf.c_str()); } else if (besti == -1) { @@ -572,18 +571,20 @@ std::string searchResidueDatabase(const std::string &key, gmx::ArrayRef::const_iterator -getDatabaseEntry(const std::string &rtpname, gmx::ArrayRef rtpDBEntry) +getDatabaseEntry(const std::string& rtpname, gmx::ArrayRef rtpDBEntry) { auto found = std::find_if(rtpDBEntry.begin(), rtpDBEntry.end(), - [&rtpname](const PreprocessResidue &entry) - { return gmx::equalCaseInsensitive(rtpname, entry.resname); }); + [&rtpname](const PreprocessResidue& entry) { + return gmx::equalCaseInsensitive(rtpname, entry.resname); + }); if (found == rtpDBEntry.end()) { /* This should never happen, since searchResidueDatabase should have been called diff --git a/src/gromacs/gmxpreprocess/resall.h b/src/gromacs/gmxpreprocess/resall.h index c5022ca246..78c74436f0 100644 --- a/src/gromacs/gmxpreprocess/resall.h +++ b/src/gromacs/gmxpreprocess/resall.h @@ -62,7 +62,7 @@ struct t_symtab; * \param[in] rtpDBEntry Database with residue information. * \returns The rtp residue name. */ -std::string searchResidueDatabase(const std::string &key, gmx::ArrayRef rtpDBEntry); +std::string searchResidueDatabase(const std::string& key, gmx::ArrayRef rtpDBEntry); /*! \brief * Returns matching entry in database. @@ -72,7 +72,7 @@ std::string searchResidueDatabase(const std::string &key, gmx::ArrayRef::const_iterator -getDatabaseEntry(const std::string &rtpname, gmx::ArrayRef rtpDBEntry); +getDatabaseEntry(const std::string& rtpname, gmx::ArrayRef rtpDBEntry); /*! \brief * Read atom types into database. @@ -81,7 +81,7 @@ getDatabaseEntry(const std::string &rtpname, gmx::ArrayRef *rtpDBEntry, - PreprocessingAtomTypes *atype, - t_symtab *tab, - bool bAllowOverrideRTP); +void readResidueDatabase(const std::string& resdb, + std::vector* rtpDBEntry, + PreprocessingAtomTypes* atype, + t_symtab* tab, + bool bAllowOverrideRTP); /*! \brief * Print out database. @@ -105,7 +105,8 @@ void readResidueDatabase(const std::string &resdb, * \param[in] rtpDBEntry Database to write out. * \param[in] atype Atom type information. */ -void print_resall(FILE *out, gmx::ArrayRef rtpDBEntry, - const PreprocessingAtomTypes &atype); +void print_resall(FILE* out, + gmx::ArrayRef rtpDBEntry, + const PreprocessingAtomTypes& atype); #endif diff --git a/src/gromacs/gmxpreprocess/solvate.cpp b/src/gromacs/gmxpreprocess/solvate.cpp index b66ceda742..23cad4d79b 100644 --- a/src/gromacs/gmxpreprocess/solvate.cpp +++ b/src/gromacs/gmxpreprocess/solvate.cpp @@ -78,39 +78,38 @@ struct MoleculeType //! molecule name std::string name; //! number of atoms in the molecule - int numAtoms = 0; + int numAtoms = 0; //! number of occurences of molecule - int numMolecules = 0; + int numMolecules = 0; }; -static void sort_molecule(t_atoms **atoms_solvt, - t_atoms **newatoms, - std::vector *x, - std::vector *v) +static void sort_molecule(t_atoms** atoms_solvt, t_atoms** newatoms, std::vector* x, std::vector* v) { fprintf(stderr, "Sorting configuration\n"); - t_atoms *atoms = *atoms_solvt; + t_atoms* atoms = *atoms_solvt; /* copy each residue from *atoms to a molecule in *molecule */ - std::vector molTypes; + std::vector molTypes; for (int i = 0; i < atoms->nr; i++) { - if ( (i == 0) || (atoms->atom[i].resind != atoms->atom[i-1].resind) ) + if ((i == 0) || (atoms->atom[i].resind != atoms->atom[i - 1].resind)) { /* see if this was a molecule type we haven't had yet: */ - auto matchingMolType = std::find_if(molTypes.begin(), molTypes.end(), - [atoms, i](const MoleculeType &molecule) - {return molecule.name == *atoms->resinfo[atoms->atom[i].resind].name; }); + auto matchingMolType = std::find_if( + molTypes.begin(), molTypes.end(), [atoms, i](const MoleculeType& molecule) { + return molecule.name == *atoms->resinfo[atoms->atom[i].resind].name; + }); if (matchingMolType == molTypes.end()) { int numAtomsInMolType = 0; - while ((i + numAtomsInMolType < atoms->nr) && - (atoms->atom[i].resind == atoms->atom[i + numAtomsInMolType].resind)) + while ((i + numAtomsInMolType < atoms->nr) + && (atoms->atom[i].resind == atoms->atom[i + numAtomsInMolType].resind)) { numAtomsInMolType++; } - molTypes.emplace_back(MoleculeType {*atoms->resinfo[atoms->atom[i].resind].name, numAtomsInMolType, 1}); + molTypes.emplace_back(MoleculeType{ *atoms->resinfo[atoms->atom[i].resind].name, + numAtomsInMolType, 1 }); } else { @@ -119,12 +118,12 @@ static void sort_molecule(t_atoms **atoms_solvt, } } - fprintf(stderr, "Found %zu%s molecule type%s:\n", - molTypes.size(), molTypes.size() == 1 ? "" : " different", molTypes.size() == 1 ? "" : "s"); - for (const auto &molType : molTypes) + fprintf(stderr, "Found %zu%s molecule type%s:\n", molTypes.size(), + molTypes.size() == 1 ? "" : " different", molTypes.size() == 1 ? "" : "s"); + for (const auto& molType : molTypes) { - fprintf(stderr, "%7s (%4d atoms): %5d residues\n", - molType.name.c_str(), molType.numAtoms, molType.numMolecules); + fprintf(stderr, "%7s (%4d atoms): %5d residues\n", molType.name.c_str(), molType.numAtoms, + molType.numMolecules); } /* if we have only 1 moleculetype, we don't have to sort */ @@ -138,9 +137,9 @@ static void sort_molecule(t_atoms **atoms_solvt, std::vector newx(x->size()); std::vector newv(v->size()); - int residIndex = 0; - int atomIndex = 0; - for (const auto &moleculeType : molTypes) + int residIndex = 0; + int atomIndex = 0; + for (const auto& moleculeType : molTypes) { int i = 0; while (i < atoms->nr) @@ -149,7 +148,7 @@ static void sort_molecule(t_atoms **atoms_solvt, if (moleculeType.name == *atoms->resinfo[residOfCurrAtom].name) { /* Copy the residue info */ - (*newatoms)->resinfo[residIndex] = atoms->resinfo[residOfCurrAtom]; + (*newatoms)->resinfo[residIndex] = atoms->resinfo[residOfCurrAtom]; // Residue numbering starts from 1, so +1 from the index (*newatoms)->resinfo[residIndex].nr = residIndex + 1; /* Copy the atom info */ @@ -165,8 +164,7 @@ static void sort_molecule(t_atoms **atoms_solvt, } i++; atomIndex++; - } - while (i < atoms->nr && atoms->atom[i].resind == residOfCurrAtom); + } while (i < atoms->nr && atoms->atom[i].resind == residOfCurrAtom); /* Increase the new residue counters */ residIndex++; } @@ -176,8 +174,7 @@ static void sort_molecule(t_atoms **atoms_solvt, do { i++; - } - while (i < atoms->nr && atoms->atom[i].resind == residOfCurrAtom); + } while (i < atoms->nr && atoms->atom[i].resind == residOfCurrAtom); } } } @@ -190,7 +187,7 @@ static void sort_molecule(t_atoms **atoms_solvt, } } -static void rm_res_pbc(const t_atoms *atoms, std::vector *x, matrix box) +static void rm_res_pbc(const t_atoms* atoms, std::vector* x, matrix box) { int start, nat; rvec xcg; @@ -205,8 +202,7 @@ static void rm_res_pbc(const t_atoms *atoms, std::vector *x, matrix box) nat++; rvec_inc(xcg, (*x)[n]); } - if ( (n+1 == atoms->nr) || - (atoms->atom[n+1].resind != atoms->atom[n].resind) ) + if ((n + 1 == atoms->nr) || (atoms->atom[n + 1].resind != atoms->atom[n].resind)) { /* if nat==0 we have only hydrogens in the solvent, we take last coordinate as cg */ @@ -215,7 +211,7 @@ static void rm_res_pbc(const t_atoms *atoms, std::vector *x, matrix box) nat = 1; copy_rvec((*x)[n], xcg); } - svmul(1.0/nat, xcg, xcg); + svmul(1.0 / nat, xcg, xcg); for (int d = 0; d < DIM; d++) { while (xcg[d] < 0) @@ -235,7 +231,7 @@ static void rm_res_pbc(const t_atoms *atoms, std::vector *x, matrix box) xcg[d] -= box[d][d]; } } - start = n+1; + start = n + 1; nat = 0; clear_rvec(xcg); } @@ -261,9 +257,12 @@ static void rm_res_pbc(const t_atoms *atoms, std::vector *x, matrix box) * Note that the input configuration should be in the rectangular unit cell and * have whole residues. */ -static void replicateSolventBox(t_atoms *atoms, std::vector *x, - std::vector *v, std::vector *r, - const matrix box, const matrix boxTarget) +static void replicateSolventBox(t_atoms* atoms, + std::vector* x, + std::vector* v, + std::vector* r, + const matrix box, + const matrix boxTarget) { // Calculate the box multiplication factors. ivec n_box; @@ -277,13 +276,13 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, } nmol *= n_box[i]; } - fprintf(stderr, "Will generate new solvent configuration of %dx%dx%d boxes\n", - n_box[XX], n_box[YY], n_box[ZZ]); + fprintf(stderr, "Will generate new solvent configuration of %dx%dx%d boxes\n", n_box[XX], + n_box[YY], n_box[ZZ]); // Create arrays for storing the generated system (cannot be done in-place // in case the target box is smaller than the original in one dimension, // but not in all). - t_atoms newAtoms; + t_atoms newAtoms; init_t_atoms(&newAtoms, 0, FALSE); gmx::AtomsBuilder builder(&newAtoms, nullptr); builder.reserve(atoms->nr * nmol, atoms->nres * nmol); @@ -291,25 +290,25 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, std::vector newV(!v->empty() ? atoms->nr * nmol : 0); std::vector newR(atoms->nr * nmol); - const real maxRadius = *std::max_element(r->begin(), r->end()); - rvec boxWithMargin; + const real maxRadius = *std::max_element(r->begin(), r->end()); + rvec boxWithMargin; for (int i = 0; i < DIM; ++i) { // The code below is only interested about the box diagonal. - boxWithMargin[i] = boxTarget[i][i] + 3*maxRadius; + boxWithMargin[i] = boxTarget[i][i] + 3 * maxRadius; } for (int ix = 0; ix < n_box[XX]; ++ix) { rvec delta; - delta[XX] = ix*box[XX][XX]; + delta[XX] = ix * box[XX][XX]; for (int iy = 0; iy < n_box[YY]; ++iy) { - delta[YY] = iy*box[YY][YY]; + delta[YY] = iy * box[YY][YY]; for (int iz = 0; iz < n_box[ZZ]; ++iz) { - delta[ZZ] = iz*box[ZZ][ZZ]; - bool bKeepResidue = false; + delta[ZZ] = iz * box[ZZ][ZZ]; + bool bKeepResidue = false; for (int i = 0; i < atoms->nr; ++i) { const int newIndex = builder.currentAtomCount(); @@ -317,8 +316,8 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, for (int m = 0; m < DIM; ++m) { const real newCoord = delta[m] + (*x)[i][m]; - bKeepAtom = bKeepAtom && (newCoord < boxWithMargin[m]); - newX[newIndex][m] = newCoord; + bKeepAtom = bKeepAtom && (newCoord < boxWithMargin[m]); + newX[newIndex][m] = newCoord; } bKeepResidue = bKeepResidue || bKeepAtom; if (!v->empty()) @@ -327,8 +326,7 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, } newR[newIndex] = (*r)[i]; builder.addAtom(*atoms, i); - if (i == atoms->nr - 1 - || atoms->atom[i+1].resind != atoms->atom[i].resind) + if (i == atoms->nr - 1 || atoms->atom[i + 1].resind != atoms->atom[i].resind) { if (bKeepResidue) { @@ -339,7 +337,7 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, builder.discardCurrentResidue(); } // Reset state for the next residue. - bKeepResidue = false; + bKeepResidue = false; } } } @@ -364,8 +362,7 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, newR.resize(atoms->nr); std::swap(*r, newR); - fprintf(stderr, "Solvent box contains %d atoms in %d residues\n", - atoms->nr, atoms->nres); + fprintf(stderr, "Solvent box contains %d atoms in %d residues\n", atoms->nr, atoms->nres); } /*! \brief @@ -387,26 +384,28 @@ static void replicateSolventBox(t_atoms *atoms, std::vector *x, * the opposite box edge in a way that is not part of the pre-equilibrated * configuration. */ -static void removeSolventBoxOverlap(t_atoms *atoms, std::vector *x, - std::vector *v, std::vector *r, - const t_pbc &pbc) +static void removeSolventBoxOverlap(t_atoms* atoms, + std::vector* x, + std::vector* v, + std::vector* r, + const t_pbc& pbc) { gmx::AtomsRemover remover(*atoms); // TODO: We could limit the amount of pairs searched significantly, // since we are only interested in pairs where the positions are on // opposite edges. - const real maxRadius = *std::max_element(r->begin(), r->end()); - gmx::AnalysisNeighborhood nb; - nb.setCutoff(2*maxRadius); + const real maxRadius = *std::max_element(r->begin(), r->end()); + gmx::AnalysisNeighborhood nb; + nb.setCutoff(2 * maxRadius); gmx::AnalysisNeighborhoodPositions pos(*x); gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, pos); gmx::AnalysisNeighborhoodPairSearch pairSearch = search.startPairSearch(pos); gmx::AnalysisNeighborhoodPair pair; while (pairSearch.findNextPair(&pair)) { - const int i1 = pair.refIndex(); - const int i2 = pair.testIndex(); + const int i1 = pair.refIndex(); + const int i2 = pair.testIndex(); if (remover.isMarked(i2)) { pairSearch.skipRemainingPairsForTestPosition(); @@ -475,19 +474,19 @@ static void removeSolventBoxOverlap(t_atoms *atoms, std::vector *x, * \param[in] x_solute Solute positions. * \param[in] rshell The radius outside the solute molecule. */ -static void removeSolventOutsideShell(t_atoms *atoms, - std::vector *x_solvent, - std::vector *v_solvent, - std::vector *r, - const t_pbc &pbc, - const std::vector &x_solute, +static void removeSolventOutsideShell(t_atoms* atoms, + std::vector* x_solvent, + std::vector* v_solvent, + std::vector* r, + const t_pbc& pbc, + const std::vector& x_solute, real rshell) { - gmx::AtomsRemover remover(*atoms); - gmx::AnalysisNeighborhood nb; + gmx::AtomsRemover remover(*atoms); + gmx::AnalysisNeighborhood nb; nb.setCutoff(rshell); gmx::AnalysisNeighborhoodPositions posSolute(x_solute); - gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, posSolute); + gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, posSolute); gmx::AnalysisNeighborhoodPositions pos(*x_solvent); gmx::AnalysisNeighborhoodPairSearch pairSearch = search.startPairSearch(pos); gmx::AnalysisNeighborhoodPair pair; @@ -523,26 +522,24 @@ static void removeSolventOutsideShell(t_atoms *atoms, * \param[in] x_solute Solute positions. * \param[in] r_solute Solute exclusion radii. */ -static void removeSolventOverlappingWithSolute(t_atoms *atoms, - std::vector *x, - std::vector *v, - std::vector *r, - const t_pbc &pbc, - const std::vector &x_solute, - const std::vector &r_solute) +static void removeSolventOverlappingWithSolute(t_atoms* atoms, + std::vector* x, + std::vector* v, + std::vector* r, + const t_pbc& pbc, + const std::vector& x_solute, + const std::vector& r_solute) { - gmx::AtomsRemover remover(*atoms); - const real maxRadius1 - = *std::max_element(r->begin(), r->end()); - const real maxRadius2 - = *std::max_element(r_solute.begin(), r_solute.end()); + gmx::AtomsRemover remover(*atoms); + const real maxRadius1 = *std::max_element(r->begin(), r->end()); + const real maxRadius2 = *std::max_element(r_solute.begin(), r_solute.end()); // Now check for overlap. - gmx::AnalysisNeighborhood nb; - gmx::AnalysisNeighborhoodPair pair; + gmx::AnalysisNeighborhood nb; + gmx::AnalysisNeighborhoodPair pair; nb.setCutoff(maxRadius1 + maxRadius2); gmx::AnalysisNeighborhoodPositions posSolute(x_solute); - gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, posSolute); + gmx::AnalysisNeighborhoodSearch search = nb.initSearch(&pbc, posSolute); gmx::AnalysisNeighborhoodPositions pos(*x); gmx::AnalysisNeighborhoodPairSearch pairSearch = search.startPairSearch(pos); while (pairSearch.findNextPair(&pair)) @@ -582,9 +579,7 @@ static void removeSolventOverlappingWithSolute(t_atoms *atoms, * so it does not operate on the exclusion radii, as no code after this needs * them. */ -static void removeExtraSolventMolecules(t_atoms *atoms, std::vector *x, - std::vector *v, - int numberToRemove) +static void removeExtraSolventMolecules(t_atoms* atoms, std::vector* x, std::vector* v, int numberToRemove) { gmx::AtomsRemover remover(*atoms); std::random_device rd; @@ -607,24 +602,30 @@ static void removeExtraSolventMolecules(t_atoms *atoms, std::vector *x, remover.removeMarkedAtoms(atoms); } -static void add_solv(const char *filename, t_atoms *atoms, - t_symtab *symtab, - std::vector *x, std::vector *v, - int ePBC, matrix box, AtomProperties *aps, - real defaultDistance, real scaleFactor, - real rshell, int max_sol) +static void add_solv(const char* filename, + t_atoms* atoms, + t_symtab* symtab, + std::vector* x, + std::vector* v, + int ePBC, + matrix box, + AtomProperties* aps, + real defaultDistance, + real scaleFactor, + real rshell, + int max_sol) { gmx_mtop_t topSolvent; std::vector xSolvent, vSolvent; - matrix boxSolvent = {{ 0 }}; + matrix boxSolvent = { { 0 } }; int ePBCSolvent; fprintf(stderr, "Reading solvent configuration\n"); - bool bTprFileWasRead; - rvec *temporaryX = nullptr, *temporaryV = nullptr; + bool bTprFileWasRead; + rvec *temporaryX = nullptr, *temporaryV = nullptr; readConfAndTopology(gmx::findLibraryFile(filename).c_str(), &bTprFileWasRead, &topSolvent, &ePBCSolvent, &temporaryX, &temporaryV, boxSolvent); - t_atoms *atomsSolvent; + t_atoms* atomsSolvent; snew(atomsSolvent, 1); *atomsSolvent = gmx_mtop_global_atoms(&topSolvent); xSolvent.assign(temporaryX, temporaryX + topSolvent.natoms); @@ -633,7 +634,8 @@ static void add_solv(const char *filename, t_atoms *atoms, sfree(temporaryV); if (gmx::boxIsZero(boxSolvent)) { - gmx_fatal(FARGS, "No box information for solvent in %s, please use a properly formatted file\n", + gmx_fatal(FARGS, + "No box information for solvent in %s, please use a properly formatted file\n", filename); } if (0 == atomsSolvent->nr) @@ -646,7 +648,7 @@ static void add_solv(const char *filename, t_atoms *atoms, fprintf(stderr, "Initialising inter-atomic distances...\n"); const std::vector exclusionDistances( makeExclusionDistances(atoms, aps, defaultDistance, scaleFactor)); - std::vector exclusionDistances_solvt( + std::vector exclusionDistances_solvt( makeExclusionDistances(atomsSolvent, aps, defaultDistance, scaleFactor)); /* generate a new solvent configuration */ @@ -657,13 +659,13 @@ static void add_solv(const char *filename, t_atoms *atoms, { if (TRICLINIC(boxSolvent)) { - gmx_fatal(FARGS, "Generating from non-rectangular solvent boxes is currently not supported.\n" + gmx_fatal(FARGS, + "Generating from non-rectangular solvent boxes is currently not supported.\n" "You can try to pass the same box for -cp and -cs."); } /* apply pbc for solvent configuration for whole molecules */ rm_res_pbc(atomsSolvent, &xSolvent, boxSolvent); - replicateSolventBox(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, - boxSolvent, box); + replicateSolventBox(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, boxSolvent, box); if (ePBC != epbcNONE) { removeSolventBoxOverlap(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, pbc); @@ -673,12 +675,11 @@ static void add_solv(const char *filename, t_atoms *atoms, { if (rshell > 0.0) { - removeSolventOutsideShell(atomsSolvent, &xSolvent, &vSolvent, - &exclusionDistances_solvt, pbc, *x, rshell); + removeSolventOutsideShell(atomsSolvent, &xSolvent, &vSolvent, &exclusionDistances_solvt, + pbc, *x, rshell); } removeSolventOverlappingWithSolute(atomsSolvent, &xSolvent, &vSolvent, - &exclusionDistances_solvt, pbc, *x, - exclusionDistances); + &exclusionDistances_solvt, pbc, *x, exclusionDistances); } if (max_sol > 0 && atomsSolvent->nres > max_sol) @@ -688,12 +689,12 @@ static void add_solv(const char *filename, t_atoms *atoms, } /* Sort the solvent mixture, not the protein... */ - t_atoms *newatoms = nullptr; + t_atoms* newatoms = nullptr; // The sort_molecule function does something creative with the // t_atoms pointers. We need to make sure we neither leak, nor // double-free, so make a shallow pointer that is fine for it to // change. - t_atoms *sortedAtomsSolvent = atomsSolvent; + t_atoms* sortedAtomsSolvent = atomsSolvent; sort_molecule(&sortedAtomsSolvent, &newatoms, &xSolvent, &vSolvent); // Merge the two configurations. @@ -706,8 +707,8 @@ static void add_solv(const char *filename, t_atoms *atoms, gmx::AtomsBuilder builder(atoms, symtab); builder.mergeAtoms(*sortedAtomsSolvent); } - fprintf(stderr, "Generated solvent containing %d atoms in %d residues\n", - atomsSolvent->nr, atomsSolvent->nres); + fprintf(stderr, "Generated solvent containing %d atoms in %d residues\n", atomsSolvent->nr, + atomsSolvent->nres); if (newatoms) { @@ -721,29 +722,28 @@ static void add_solv(const char *filename, t_atoms *atoms, } } -static void update_top(t_atoms *atoms, +static void update_top(t_atoms* atoms, int firstSolventResidueIndex, matrix box, int NFILE, t_filenm fnm[], - AtomProperties *aps) + AtomProperties* aps) { - FILE *fpin, *fpout; - char buf[STRLEN*2], buf2[STRLEN], *temp; - const char *topinout; - int line; - bool bSystem; - int i; - double mtot; - real vol, mm; + FILE * fpin, *fpout; + char buf[STRLEN * 2], buf2[STRLEN], *temp; + const char* topinout; + int line; + bool bSystem; + int i; + double mtot; + real vol, mm; - int nsol = atoms->nres - firstSolventResidueIndex; + int nsol = atoms->nres - firstSolventResidueIndex; mtot = 0; for (i = 0; (i < atoms->nr); i++) { - aps->setAtomProperty(epropMass, - std::string(*atoms->resinfo[atoms->atom[i].resind].name), + aps->setAtomProperty(epropMass, std::string(*atoms->resinfo[atoms->atom[i].resind].name), std::string(*atoms->atomname[i]), &mm); mtot += mm; } @@ -751,13 +751,12 @@ static void update_top(t_atoms *atoms, vol = det(box); fprintf(stderr, "Volume : %10g (nm^3)\n", vol); - fprintf(stderr, "Density : %10g (g/l)\n", - (mtot*1e24)/(AVOGADRO*vol)); + fprintf(stderr, "Density : %10g (g/l)\n", (mtot * 1e24) / (AVOGADRO * vol)); fprintf(stderr, "Number of solvent molecules: %5d \n\n", nsol); /* open topology file and append sol molecules */ - topinout = ftp2fn(efTOP, NFILE, fnm); - if (ftp2bSet(efTOP, NFILE, fnm) ) + topinout = ftp2fn(efTOP, NFILE, fnm); + if (ftp2bSet(efTOP, NFILE, fnm)) { char temporary_filename[STRLEN]; strncpy(temporary_filename, "temp.topXXXXXX", STRLEN); @@ -784,19 +783,19 @@ static void update_top(t_atoms *atoms, temp[0] = '\0'; } rtrim(buf2); - if (buf2[strlen(buf2)-1] == ']') + if (buf2[strlen(buf2) - 1] == ']') { - buf2[strlen(buf2)-1] = '\0'; + buf2[strlen(buf2) - 1] = '\0'; ltrim(buf2); rtrim(buf2); - bSystem = (gmx_strcasecmp(buf2, "system") == 0); + bSystem = (gmx_strcasecmp(buf2, "system") == 0); } } - else if (bSystem && nsol && (buf[0] != ';') ) + else if (bSystem && nsol && (buf[0] != ';')) { /* if sol present, append "in water" to system name */ rtrim(buf2); - if (buf2[0] && (!strstr(buf2, " water")) ) + if (buf2[0] && (!strstr(buf2, " water"))) { sprintf(buf, "%s in water\n", buf2); bSystem = false; @@ -822,16 +821,20 @@ static void update_top(t_atoms *atoms, else { // Change topology and restart count - fprintf(stdout, "Adding line for %d solvent molecules with resname (%s) to " - "topology file (%s)\n", resCount, currRes.c_str(), topinout); + fprintf(stdout, + "Adding line for %d solvent molecules with resname (%s) to " + "topology file (%s)\n", + resCount, currRes.c_str(), topinout); fprintf(fpout, "%-15s %5d\n", currRes.c_str(), resCount); currRes = *atoms->resinfo[i].name; resCount = 1; } } // One more print needed for last residue type - fprintf(stdout, "Adding line for %d solvent molecules with resname (%s) to " - "topology file (%s)\n", resCount, currRes.c_str(), topinout); + fprintf(stdout, + "Adding line for %d solvent molecules with resname (%s) to " + "topology file (%s)\n", + resCount, currRes.c_str(), topinout); fprintf(fpout, "%-15s %5d\n", currRes.c_str(), resCount); } gmx_ffclose(fpout); @@ -840,9 +843,9 @@ static void update_top(t_atoms *atoms, } } -int gmx_solvate(int argc, char *argv[]) +int gmx_solvate(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] can do one of 2 things:[PAR]", "1) Generate a box of solvent. Specify [TT]-cs[tt] and [TT]-box[tt].", @@ -895,79 +898,84 @@ int gmx_solvate(int argc, char *argv[]) "line with the total number of solvent molecules in your coordinate file." }; - const char *bugs[] = { + const char* bugs[] = { "Molecules must be whole in the initial configurations.", }; /* parameter data */ - gmx_bool bProt, bBox; - const char *conf_prot, *confout; + gmx_bool bProt, bBox; + const char *conf_prot, *confout; - t_filenm fnm[] = { + t_filenm fnm[] = { { efSTX, "-cp", "protein", ffOPTRD }, - { efSTX, "-cs", "spc216", ffLIBRD}, - { efSTO, nullptr, nullptr, ffWRITE}, - { efTOP, nullptr, nullptr, ffOPTRW}, + { efSTX, "-cs", "spc216", ffLIBRD }, + { efSTO, nullptr, nullptr, ffWRITE }, + { efTOP, nullptr, nullptr, ffOPTRW }, }; #define NFILE asize(fnm) - real defaultDistance = 0.105, r_shell = 0, scaleFactor = 0.57; - rvec new_box = {0.0, 0.0, 0.0}; + real defaultDistance = 0.105, r_shell = 0, scaleFactor = 0.57; + rvec new_box = { 0.0, 0.0, 0.0 }; gmx_bool bReadV = FALSE; int max_sol = 0; int firstSolventResidueIndex = 0; - gmx_output_env_t *oenv; - t_pargs pa[] = { - { "-box", FALSE, etRVEC, {new_box}, - "Box size (in nm)" }, - { "-radius", FALSE, etREAL, {&defaultDistance}, - "Default van der Waals distance"}, - { "-scale", FALSE, etREAL, {&scaleFactor}, - "Scale factor to multiply Van der Waals radii from the database in share/gromacs/top/vdwradii.dat. The default value of 0.57 yields density close to 1000 g/l for proteins in water." }, - { "-shell", FALSE, etREAL, {&r_shell}, - "Thickness of optional water layer around solute" }, - { "-maxsol", FALSE, etINT, {&max_sol}, - "Maximum number of solvent molecules to add if they fit in the box. If zero (default) this is ignored" }, - { "-vel", FALSE, etBOOL, {&bReadV}, - "Keep velocities from input solute and solvent" }, + gmx_output_env_t* oenv; + t_pargs pa[] = { + { "-box", FALSE, etRVEC, { new_box }, "Box size (in nm)" }, + { "-radius", FALSE, etREAL, { &defaultDistance }, "Default van der Waals distance" }, + { "-scale", + FALSE, + etREAL, + { &scaleFactor }, + "Scale factor to multiply Van der Waals radii from the database in " + "share/gromacs/top/vdwradii.dat. The default value of 0.57 yields density close to 1000 " + "g/l for proteins in water." }, + { "-shell", FALSE, etREAL, { &r_shell }, "Thickness of optional water layer around solute" }, + { "-maxsol", + FALSE, + etINT, + { &max_sol }, + "Maximum number of solvent molecules to add if they fit in the box. If zero (default) " + "this is ignored" }, + { "-vel", FALSE, etBOOL, { &bReadV }, "Keep velocities from input solute and solvent" }, }; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, + asize(bugs), bugs, &oenv)) { return 0; } - const char *solventFileName = opt2fn("-cs", NFILE, fnm); - bProt = opt2bSet("-cp", NFILE, fnm); - bBox = opt2parg_bSet("-box", asize(pa), pa); + const char* solventFileName = opt2fn("-cs", NFILE, fnm); + bProt = opt2bSet("-cp", NFILE, fnm); + bBox = opt2parg_bSet("-box", asize(pa), pa); /* check input */ if (!bProt && !bBox) { - gmx_fatal(FARGS, "When no solute (-cp) is specified, " + gmx_fatal(FARGS, + "When no solute (-cp) is specified, " "a box size (-box) must be specified"); } - AtomProperties aps; + AtomProperties aps; /* solute configuration data */ gmx_mtop_t top; std::vector x, v; - matrix box = {{ 0 }}; + matrix box = { { 0 } }; int ePBC = -1; - t_atoms *atoms; + t_atoms* atoms; snew(atoms, 1); if (bProt) { /* Generate a solute configuration */ conf_prot = opt2fn("-cp", NFILE, fnm); - fprintf(stderr, "Reading solute configuration%s\n", - bReadV ? " and velocities" : ""); + fprintf(stderr, "Reading solute configuration%s\n", bReadV ? " and velocities" : ""); bool bTprFileWasRead; rvec *temporaryX = nullptr, *temporaryV = nullptr; - readConfAndTopology(conf_prot, &bTprFileWasRead, &top, - &ePBC, &temporaryX, bReadV ? &temporaryV : nullptr, box); + readConfAndTopology(conf_prot, &bTprFileWasRead, &top, &ePBC, &temporaryX, + bReadV ? &temporaryV : nullptr, box); *atoms = gmx_mtop_global_atoms(&top); x.assign(temporaryX, temporaryX + top.natoms); sfree(temporaryX); @@ -1001,23 +1009,23 @@ int gmx_solvate(int argc, char *argv[]) } if (det(box) == 0) { - gmx_fatal(FARGS, "Undefined solute box.\nCreate one with gmx editconf " + gmx_fatal(FARGS, + "Undefined solute box.\nCreate one with gmx editconf " "or give explicit -box command line option"); } - add_solv(solventFileName, atoms, &top.symtab, &x, &v, ePBCForOutput, box, - &aps, defaultDistance, scaleFactor, r_shell, max_sol); + add_solv(solventFileName, atoms, &top.symtab, &x, &v, ePBCForOutput, box, &aps, defaultDistance, + scaleFactor, r_shell, max_sol); /* write new configuration 1 to file confout */ confout = ftp2fn(efSTO, NFILE, fnm); fprintf(stderr, "Writing generated configuration to %s\n", confout); - const char *outputTitle = (bProt ? *top.name : "Generated by gmx solvate"); + const char* outputTitle = (bProt ? *top.name : "Generated by gmx solvate"); write_sto_conf(confout, outputTitle, atoms, as_rvec_array(x.data()), !v.empty() ? as_rvec_array(v.data()) : nullptr, ePBCForOutput, box); /* print size of generated configuration */ - fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", - atoms->nr, atoms->nres); + fprintf(stderr, "\nOutput configuration contains %d atoms in %d residues\n", atoms->nr, atoms->nres); update_top(atoms, firstSolventResidueIndex, box, NFILE, fnm, &aps); done_atom(atoms); diff --git a/src/gromacs/gmxpreprocess/solvate.h b/src/gromacs/gmxpreprocess/solvate.h index d7b17f6fbc..cd81b5c5f1 100644 --- a/src/gromacs/gmxpreprocess/solvate.h +++ b/src/gromacs/gmxpreprocess/solvate.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_SOLVATE_H #define GMX_GMXPREPROCESS_SOLVATE_H -int gmx_solvate(int argc, char *argv[]); +int gmx_solvate(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/specbond.cpp b/src/gromacs/gmxpreprocess/specbond.cpp index 498a553258..f1f2292008 100644 --- a/src/gromacs/gmxpreprocess/specbond.cpp +++ b/src/gromacs/gmxpreprocess/specbond.cpp @@ -68,27 +68,27 @@ static bool yesno() do { c = toupper(fgetc(stdin)); - } - while ((c != 'Y') && (c != 'N')); + } while ((c != 'Y') && (c != 'N')); return (c == 'Y'); } std::vector generateSpecialBonds() { - const char *sbfile = "specbond.dat"; + const char* sbfile = "specbond.dat"; std::vector specialBonds; char r1buf[32], r2buf[32], a1buf[32], a2buf[32], nr1buf[32], nr2buf[32]; double length; int nb1, nb2; - char **lines; + char** lines; int nlines = get_lines(sbfile, &lines); for (int i = 0; (i < nlines); i++) { - if (sscanf(lines[i], "%s%s%d%s%s%d%lf%s%s", - r1buf, a1buf, &nb1, r2buf, a2buf, &nb2, &length, nr1buf, nr2buf) != 9) + if (sscanf(lines[i], "%s%s%d%s%s%d%lf%s%s", r1buf, a1buf, &nb1, r2buf, a2buf, &nb2, &length, + nr1buf, nr2buf) + != 9) { fprintf(stderr, "Invalid line '%s' in %s\n", lines[i], sbfile); } @@ -113,20 +113,20 @@ std::vector generateSpecialBonds() { sfree(lines); } - fprintf(stderr, "%zu out of %d lines of %s converted successfully\n", - specialBonds.size(), nlines, sbfile); + fprintf(stderr, "%zu out of %d lines of %s converted successfully\n", specialBonds.size(), + nlines, sbfile); return specialBonds; } -static bool is_special(gmx::ArrayRef sb, const char *res, const char *atom) +static bool is_special(gmx::ArrayRef sb, const char* res, const char* atom) { - for (const auto &bond : sb) + for (const auto& bond : sb) { - if (((strncmp(bond.firstResidue.c_str(), res, 3) == 0) && - (gmx::equalCaseInsensitive(bond.firstAtomName, atom))) || - ((strncmp(bond.secondResidue.c_str(), res, 3) == 0) && - (gmx::equalCaseInsensitive(bond.secondAtomName, atom)))) + if (((strncmp(bond.firstResidue.c_str(), res, 3) == 0) + && (gmx::equalCaseInsensitive(bond.firstAtomName, atom))) + || ((strncmp(bond.secondResidue.c_str(), res, 3) == 0) + && (gmx::equalCaseInsensitive(bond.secondAtomName, atom)))) { return TRUE; } @@ -134,36 +134,35 @@ static bool is_special(gmx::ArrayRef sb, const char *res, con return FALSE; } -static bool is_bond(gmx::ArrayRef sb, t_atoms *pdba, int a1, int a2, - real d, int *index_sb, bool *bSwap) +static bool is_bond(gmx::ArrayRef sb, t_atoms* pdba, int a1, int a2, real d, int* index_sb, bool* bSwap) { - const char *at1 = *pdba->atomname[a1]; - const char *at2 = *pdba->atomname[a2]; - const char *res1 = *pdba->resinfo[pdba->atom[a1].resind].name; - const char *res2 = *pdba->resinfo[pdba->atom[a2].resind].name; + const char* at1 = *pdba->atomname[a1]; + const char* at2 = *pdba->atomname[a2]; + const char* res1 = *pdba->resinfo[pdba->atom[a1].resind].name; + const char* res2 = *pdba->resinfo[pdba->atom[a2].resind].name; - int i = 0; - for (const auto &bond : sb) + int i = 0; + for (const auto& bond : sb) { *index_sb = i; - if (((strncmp(bond.firstResidue.c_str(), res1, 3) == 0) && - (gmx::equalCaseInsensitive(bond.firstAtomName, at1)) && - (strncmp(bond.secondResidue.c_str(), res2, 3) == 0) && - (gmx::equalCaseInsensitive(bond.secondAtomName, at2)))) + if (((strncmp(bond.firstResidue.c_str(), res1, 3) == 0) + && (gmx::equalCaseInsensitive(bond.firstAtomName, at1)) + && (strncmp(bond.secondResidue.c_str(), res2, 3) == 0) + && (gmx::equalCaseInsensitive(bond.secondAtomName, at2)))) { *bSwap = FALSE; - if ((0.9*bond.length < d) && (1.1*bond.length > d)) + if ((0.9 * bond.length < d) && (1.1 * bond.length > d)) { return TRUE; } } - if (((strncmp(bond.firstResidue.c_str(), res2, 3) == 0) && - (gmx::equalCaseInsensitive(bond.firstAtomName, at2)) && - (strncmp(bond.secondResidue.c_str(), res1, 3) == 0) && - (gmx::equalCaseInsensitive(bond.secondAtomName, at1)))) + if (((strncmp(bond.firstResidue.c_str(), res2, 3) == 0) + && (gmx::equalCaseInsensitive(bond.firstAtomName, at2)) + && (strncmp(bond.secondResidue.c_str(), res1, 3) == 0) + && (gmx::equalCaseInsensitive(bond.secondAtomName, at1)))) { *bSwap = TRUE; - if ((0.9*bond.length < d) && (1.1*bond.length > d)) + if ((0.9 * bond.length < d) && (1.1 * bond.length > d)) { return TRUE; } @@ -173,13 +172,11 @@ static bool is_bond(gmx::ArrayRef sb, t_atoms *pdba, int a1, return FALSE; } -static void rename_1res(t_atoms *pdba, int resind, const char *newres, bool bVerbose) +static void rename_1res(t_atoms* pdba, int resind, const char* newres, bool bVerbose) { if (bVerbose) { - printf("Using rtp entry %s for %s %d\n", - newres, - *pdba->resinfo[resind].name, + printf("Using rtp entry %s for %s %d\n", newres, *pdba->resinfo[resind].name, pdba->resinfo[resind].nr); } /* this used to free *resname, which messes up the symtab! */ @@ -187,10 +184,7 @@ static void rename_1res(t_atoms *pdba, int resind, const char *newres, bool bVer *pdba->resinfo[resind].rtp = gmx_strdup(newres); } -std::vector makeDisulfideBonds(t_atoms *pdba, - rvec x[], - bool bInteractive, - bool bVerbose) +std::vector makeDisulfideBonds(t_atoms* pdba, rvec x[], bool bInteractive, bool bVerbose) { std::vector specialBonds = generateSpecialBonds(); std::vector bonds; @@ -214,27 +208,24 @@ std::vector makeDisulfideBonds(t_atoms *pdba, { prevAtom = specialBondAtomIdxs.back(); } - if (is_special(specialBonds, *pdba->resinfo[pdba->atom[i].resind].name, - *pdba->atomname[i]) && - !(!specialBondAtomIdxs.empty() && - pdba->atom[prevAtom].resind == pdba->atom[i].resind && - gmx_strcasecmp(*pdba->atomname[prevAtom], - *pdba->atomname[i]) == 0)) + if (is_special(specialBonds, *pdba->resinfo[pdba->atom[i].resind].name, *pdba->atomname[i]) + && !(!specialBondAtomIdxs.empty() && pdba->atom[prevAtom].resind == pdba->atom[i].resind + && gmx_strcasecmp(*pdba->atomname[prevAtom], *pdba->atomname[i]) == 0)) { specialBondResIdxs.push_back(pdba->atom[i].resind); specialBondAtomIdxs.push_back(i); } } /* distance matrix d[nspec][nspec] */ - int nspec = specialBondAtomIdxs.size(); - std::vector < std::vector < real>> d(nspec); + int nspec = specialBondAtomIdxs.size(); + std::vector> d(nspec); for (int i = 0; (i < nspec); i++) { d[i].resize(nspec); int ai = specialBondAtomIdxs[i]; for (int j = 0; (j < nspec); j++) { - int aj = specialBondAtomIdxs[j]; + int aj = specialBondAtomIdxs[j]; d[i][j] = std::sqrt(distance2(x[ai], x[aj])); } } @@ -246,7 +237,7 @@ std::vector makeDisulfideBonds(t_atoms *pdba, { /* print resname/number column headings */ fprintf(stderr, "%8s%8s", "", ""); - int e = std::min(b+MAXCOL, nspec-1); + int e = std::min(b + MAXCOL, nspec - 1); for (int i = b; (i < e); i++) { sprintf(buf, "%s%d", *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name, @@ -256,21 +247,24 @@ std::vector makeDisulfideBonds(t_atoms *pdba, fprintf(stderr, "\n"); /* print atomname/number column headings */ fprintf(stderr, "%8s%8s", "", ""); - e = std::min(b+MAXCOL, nspec-1); + e = std::min(b + MAXCOL, nspec - 1); for (int i = b; (i < e); i++) { - std::string buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]], specialBondAtomIdxs[i]+1); + std::string buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]], + specialBondAtomIdxs[i] + 1); fprintf(stderr, "%8s", buf.c_str()); } fprintf(stderr, "\n"); /* print matrix */ - e = std::min(b+MAXCOL, nspec); - for (int i = b+1; (i < nspec); i++) + e = std::min(b + MAXCOL, nspec); + for (int i = b + 1; (i < nspec); i++) { - std::string buf = gmx::formatString("%s%d", *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name, - pdba->resinfo[specialBondResIdxs[i]].nr); + std::string buf = gmx::formatString( + "%s%d", *pdba->resinfo[pdba->atom[specialBondAtomIdxs[i]].resind].name, + pdba->resinfo[specialBondResIdxs[i]].nr); fprintf(stderr, "%8s", buf.c_str()); - buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]], specialBondAtomIdxs[i]+1); + buf = gmx::formatString("%s%d", *pdba->atomname[specialBondAtomIdxs[i]], + specialBondAtomIdxs[i] + 1); fprintf(stderr, "%8s", buf.c_str()); int e2 = std::min(i, e); for (int j = b; (j < e2); j++) @@ -285,21 +279,18 @@ std::vector makeDisulfideBonds(t_atoms *pdba, for (int i = 0; (i < nspec); i++) { int ai = specialBondAtomIdxs[i]; - for (int j = i+1; (j < nspec); j++) + for (int j = i + 1; (j < nspec); j++) { int aj = specialBondAtomIdxs[j]; /* Ensure creation of at most nspec special bonds to avoid overflowing bonds[] */ - if (bonds.size() < specialBondAtomIdxs.size() && - is_bond(specialBonds, pdba, ai, aj, d[i][j], &index_sb, &bSwap)) + if (bonds.size() < specialBondAtomIdxs.size() + && is_bond(specialBonds, pdba, ai, aj, d[i][j], &index_sb, &bSwap)) { - fprintf(stderr, "%s %s-%d %s-%d and %s-%d %s-%d%s", - bInteractive ? "Link" : "Linking", + fprintf(stderr, "%s %s-%d %s-%d and %s-%d %s-%d%s", bInteractive ? "Link" : "Linking", *pdba->resinfo[pdba->atom[ai].resind].name, - pdba->resinfo[specialBondResIdxs[i]].nr, - *pdba->atomname[ai], ai+1, + pdba->resinfo[specialBondResIdxs[i]].nr, *pdba->atomname[ai], ai + 1, *pdba->resinfo[pdba->atom[aj].resind].name, - pdba->resinfo[specialBondResIdxs[j]].nr, - *pdba->atomname[aj], aj+1, + pdba->resinfo[specialBondResIdxs[j]].nr, *pdba->atomname[aj], aj + 1, bInteractive ? " (y/n) ?" : "...\n"); bool bDoit = bInteractive ? yesno() : true; @@ -331,7 +322,6 @@ std::vector makeDisulfideBonds(t_atoms *pdba, } } } - } return bonds; diff --git a/src/gromacs/gmxpreprocess/specbond.h b/src/gromacs/gmxpreprocess/specbond.h index 8b4aa70468..008be6c82c 100644 --- a/src/gromacs/gmxpreprocess/specbond.h +++ b/src/gromacs/gmxpreprocess/specbond.h @@ -52,10 +52,7 @@ struct DisulfideBond std::string firstAtom, secondAtom; }; -std::vector makeDisulfideBonds(t_atoms *pdba, - rvec x[], - bool bInteractive, - bool bVerbose); +std::vector makeDisulfideBonds(t_atoms* pdba, rvec x[], bool bInteractive, bool bVerbose); std::vector generateSpecialBonds(); diff --git a/src/gromacs/gmxpreprocess/ter_db.cpp b/src/gromacs/gmxpreprocess/ter_db.cpp index bd98d016b7..f9434ba01b 100644 --- a/src/gromacs/gmxpreprocess/ter_db.cpp +++ b/src/gromacs/gmxpreprocess/ter_db.cpp @@ -62,15 +62,13 @@ #include "resall.h" /* use bonded types definitions in hackblock.h */ -#define ekwRepl (ebtsNR+1) -#define ekwAdd (ebtsNR+2) -#define ekwDel (ebtsNR+3) -#define ekwNR 3 -static const char *kw_names[ekwNR] = { - "replace", "add", "delete" -}; - -static int find_kw(char *keyw) +#define ekwRepl (ebtsNR + 1) +#define ekwAdd (ebtsNR + 2) +#define ekwDel (ebtsNR + 3) +#define ekwNR 3 +static const char* kw_names[ekwNR] = { "replace", "add", "delete" }; + +static int find_kw(char* keyw) { int i; @@ -94,8 +92,7 @@ static int find_kw(char *keyw) #define FATAL() gmx_fatal(FARGS, "Reading Termini Database: not enough items on line\n%s", line) -static void read_atom(char *line, bool bAdd, - std::string *nname, t_atom *a, PreprocessingAtomTypes *atype, int *cgnr) +static void read_atom(char* line, bool bAdd, std::string* nname, t_atom* a, PreprocessingAtomTypes* atype, int* cgnr) { int nr, i; char buf[5][30]; @@ -119,7 +116,10 @@ static void read_atom(char *line, bool bAdd, if (nr < 3 || nr > 4) { - gmx_fatal(FARGS, "Reading Termini Database: expected %d or %d items of atom data in stead of %d on line\n%s", 3, 4, nr, line); + gmx_fatal(FARGS, + "Reading Termini Database: expected %d or %d items of atom data in stead of %d " + "on line\n%s", + 3, 4, nr, line); } i = 0; if (!bAdd) @@ -148,28 +148,28 @@ static void read_atom(char *line, bool bAdd, } } -static void print_atom(FILE *out, const t_atom &a, PreprocessingAtomTypes *atype) +static void print_atom(FILE* out, const t_atom& a, PreprocessingAtomTypes* atype) { - fprintf(out, "\t%s\t%g\t%g\n", - atype->atomNameFromAtomType(a.type), a.m, a.q); + fprintf(out, "\t%s\t%g\t%g\n", atype->atomNameFromAtomType(a.type), a.m, a.q); } -static void print_ter_db(const char *ff, char C, gmx::ArrayRef tb, - PreprocessingAtomTypes *atype) +static void print_ter_db(const char* ff, + char C, + gmx::ArrayRef tb, + PreprocessingAtomTypes* atype) { std::string buf = gmx::formatString("%s-%c.tdb", ff, C); - FILE *out = gmx_fio_fopen(buf.c_str(), "w"); + FILE* out = gmx_fio_fopen(buf.c_str(), "w"); - for (const auto &modification : tb) + for (const auto& modification : tb) { fprintf(out, "[ %s ]\n", modification.name.c_str()); if (std::any_of(modification.hack.begin(), modification.hack.end(), - [](const auto &mod) - { return mod.type() == MoleculePatchType::Replace; })) + [](const auto& mod) { return mod.type() == MoleculePatchType::Replace; })) { - fprintf(out, "[ %s ]\n", kw_names[ekwRepl-ebtsNR-1]); - for (const auto &hack : modification.hack) + fprintf(out, "[ %s ]\n", kw_names[ekwRepl - ebtsNR - 1]); + for (const auto& hack : modification.hack) { if (hack.type() == MoleculePatchType::Replace) { @@ -179,11 +179,10 @@ static void print_ter_db(const char *ff, char C, gmx::ArrayRef *tbptr, - PreprocessingAtomTypes *atype) +static void read_ter_db_file(const char* fn, + std::vector* tbptr, + PreprocessingAtomTypes* atype) { - char filebase[STRLEN]; - char header[STRLEN], buf[STRLEN], line[STRLEN]; + char filebase[STRLEN]; + char header[STRLEN], buf[STRLEN], line[STRLEN]; fflib_filename_base(fn, filebase, STRLEN); /* Remove the C/N termini extension */ - char *ptr = strrchr(filebase, '.'); + char* ptr = strrchr(filebase, '.'); if (ptr != nullptr) { ptr[0] = '\0'; } - FILE *in = fflib_open(fn); + FILE* in = fflib_open(fn); - int kwnr = NOTSET; + int kwnr = NOTSET; get_a_line(in, line, STRLEN); - MoleculePatchDatabase *block = nullptr; + MoleculePatchDatabase* block = nullptr; while (!feof(in)) { if (get_header(line, header)) @@ -269,9 +267,11 @@ static void read_ter_db_file(const char { if (block == nullptr) { - gmx_fatal(FARGS, "reading termini database: " + gmx_fatal(FARGS, + "reading termini database: " "directive expected before line:\n%s\n" - "This might be a file in an old format.", line); + "This might be a file in an old format.", + line); } /* this is not a header, so it must be data */ if (kwnr >= ebtsNR) @@ -279,7 +279,7 @@ static void read_ter_db_file(const char /* this is a hack: add/rename/delete atoms */ /* make space for hacks */ block->hack.emplace_back(MoleculePatch()); - MoleculePatch *hack = &block->hack.back(); + MoleculePatch* hack = &block->hack.back(); /* get data */ int n = 0; @@ -287,8 +287,10 @@ static void read_ter_db_file(const char { if (sscanf(line, "%s%n", buf, &n) != 1) { - gmx_fatal(FARGS, "Reading Termini Database '%s': " - "expected atom name on line\n%s", fn, line); + gmx_fatal(FARGS, + "Reading Termini Database '%s': " + "expected atom name on line\n%s", + fn, line); } hack->oname = buf; /* we only replace or delete one atom at a time */ @@ -301,14 +303,12 @@ static void read_ter_db_file(const char } else { - gmx_fatal(FARGS, "unimplemented keyword number %d (%s:%d)", - kwnr, __FILE__, __LINE__); + gmx_fatal(FARGS, "unimplemented keyword number %d (%s:%d)", kwnr, __FILE__, __LINE__); } if (kwnr == ekwRepl || kwnr == ekwAdd) { hack->atom.emplace_back(); - read_atom(line+n, kwnr == ekwAdd, - &hack->nname, &hack->atom.back(), atype, + read_atom(line + n, kwnr == ekwAdd, &hack->nname, &hack->atom.back(), atype, &hack->cgnr); if (hack->nname.empty()) { @@ -318,7 +318,10 @@ static void read_ter_db_file(const char } else { - gmx_fatal(FARGS, "Reading Termini Database '%s': don't know which name the new atom should have on line\n%s", fn, line); + gmx_fatal(FARGS, + "Reading Termini Database '%s': don't know which name the " + "new atom should have on line\n%s", + fn, line); } } } @@ -326,30 +329,35 @@ static void read_ter_db_file(const char else if (kwnr >= 0 && kwnr < ebtsNR) { /* this is bonded data: bonds, angles, dihedrals or impropers */ - int n = 0; + int n = 0; block->rb[kwnr].b.emplace_back(); - BondedInteraction *newBond = &block->rb[kwnr].b.back(); + BondedInteraction* newBond = &block->rb[kwnr].b.back(); for (int j = 0; j < btsNiatoms[kwnr]; j++) { int ni; - if (sscanf(line+n, "%s%n", buf, &ni) == 1) + if (sscanf(line + n, "%s%n", buf, &ni) == 1) { newBond->a[j] = buf; } else { - gmx_fatal(FARGS, "Reading Termini Database '%s': expected %d atom names (found %d) on line\n%s", fn, btsNiatoms[kwnr], j-1, line); + gmx_fatal(FARGS, + "Reading Termini Database '%s': expected %d atom names (found " + "%d) on line\n%s", + fn, btsNiatoms[kwnr], j - 1, line); } n += ni; } strcpy(buf, ""); - sscanf(line+n, "%s", buf); + sscanf(line + n, "%s", buf); newBond->s = buf; } else { - gmx_fatal(FARGS, "Reading Termini Database: Expecting a header at line\n" - "%s", line); + gmx_fatal(FARGS, + "Reading Termini Database: Expecting a header at line\n" + "%s", + line); } } get_a_line(in, line, STRLEN); @@ -358,17 +366,16 @@ static void read_ter_db_file(const char gmx_ffclose(in); } -int read_ter_db(const char *ffdir, char ter, - std::vector *tbptr, PreprocessingAtomTypes *atype) +int read_ter_db(const char* ffdir, char ter, std::vector* tbptr, PreprocessingAtomTypes* atype) { std::string ext = gmx::formatString(".%c.tdb", ter); /* Search for termini database files. * Do not generate an error when none are found. */ - std::vector tdbf = fflib_search_file_end(ffdir, ext.c_str(), FALSE); + std::vector tdbf = fflib_search_file_end(ffdir, ext.c_str(), FALSE); tbptr->clear(); - for (const auto &filename : tdbf) + for (const auto& filename : tdbf) { read_ter_db_file(filename.c_str(), tbptr, atype); } @@ -381,9 +388,7 @@ int read_ter_db(const char *ffdir, char ter, return tbptr->size(); } -std::vector -filter_ter(gmx::ArrayRef tb, - const char *resname) +std::vector filter_ter(gmx::ArrayRef tb, const char* resname) { // TODO Four years later, no force fields have ever used this, so decide status of this feature /* Since some force fields (e.g. OPLS) needs different @@ -407,12 +412,12 @@ filter_ter(gmx::ArrayRef tb, * Remember to free the list when you are done with it... */ - auto none_idx = tb.end(); - std::vector list; + auto none_idx = tb.end(); + std::vector list; for (auto it = tb.begin(); it != tb.end(); it++) { - const char *s = it->name.c_str(); + const char* s = it->name.c_str(); bool found = false; do { @@ -430,8 +435,7 @@ filter_ter(gmx::ArrayRef tb, s++; } } - } - while (!found && s != nullptr); + } while (!found && s != nullptr); } /* All residue-specific termini have been added. We might have to fall @@ -442,7 +446,7 @@ filter_ter(gmx::ArrayRef tb, */ for (auto it = tb.begin(); it != tb.end(); it++) { - const char *s = it->name.c_str(); + const char* s = it->name.c_str(); if (gmx::equalCaseInsensitive("None", it->name)) { none_idx = it; @@ -451,7 +455,7 @@ filter_ter(gmx::ArrayRef tb, { /* Time to see if there's a generic terminus that matches. Is there a hyphen? */ - const char *c = strchr(s, '-'); + const char* c = strchr(s, '-'); /* A conjunction hyphen normally indicates a residue-specific terminus, which is named like "GLY-COOH". A generic terminus @@ -460,8 +464,7 @@ filter_ter(gmx::ArrayRef tb, /* '-' as the last character indicates charge, so if that's the only one found e.g. "COO-", then it was not a conjunction hyphen, so this is a generic terminus */ - bool bOnlyFoundChargeHyphen = (bFoundAnyHyphen && - *(c+1) == '\0'); + bool bOnlyFoundChargeHyphen = (bFoundAnyHyphen && *(c + 1) == '\0'); /* Thus, "GLY-COO-" is not recognized as a generic terminus. */ bool bFoundGenericTerminus = !bFoundAnyHyphen || bOnlyFoundChargeHyphen; if (bFoundGenericTerminus) @@ -469,9 +472,9 @@ filter_ter(gmx::ArrayRef tb, /* Check that we haven't already added a residue-specific version * of this terminus. */ - auto found = std::find_if(list.begin(), list.end(), - [&s](const MoleculePatchDatabase *b) - { return strstr(b->name.c_str(), s) != nullptr; }); + auto found = std::find_if(list.begin(), list.end(), [&s](const MoleculePatchDatabase* b) { + return strstr(b->name.c_str(), s) != nullptr; + }); if (found == list.end()) { list.push_back(it); @@ -488,13 +491,13 @@ filter_ter(gmx::ArrayRef tb, } -MoleculePatchDatabase *choose_ter(gmx::ArrayRef tb, const char *title) +MoleculePatchDatabase* choose_ter(gmx::ArrayRef tb, const char* title) { int sel, ret; printf("%s\n", title); int i = 0; - for (const auto &modification : tb) + for (const auto& modification : tb) { bool bIsZwitterion = (0 == gmx_wcmatch("*ZWITTERION*", modification->name.c_str())); printf("%2d: %s%s\n", i, modification->name.c_str(), @@ -504,8 +507,7 @@ MoleculePatchDatabase *choose_ter(gmx::ArrayRef tb, con do { ret = fscanf(stdin, "%d", &sel); - } - while ((ret != 1) || (sel < 0) || (sel >= tb.ssize())); + } while ((ret != 1) || (sel < 0) || (sel >= tb.ssize())); return tb[sel]; } diff --git a/src/gromacs/gmxpreprocess/ter_db.h b/src/gromacs/gmxpreprocess/ter_db.h index c3e531e7fd..f451c45074 100644 --- a/src/gromacs/gmxpreprocess/ter_db.h +++ b/src/gromacs/gmxpreprocess/ter_db.h @@ -54,8 +54,10 @@ struct MoleculePatchDatabase; * \param[in] atype Database for atomtype information. * \returns Number of entries entered into database. */ -int read_ter_db(const char *ffdir, char ter, - std::vector *tbptr, PreprocessingAtomTypes *atype); +int read_ter_db(const char* ffdir, + char ter, + std::vector* tbptr, + PreprocessingAtomTypes* atype); /*! \brief * Return entries for modification blocks that match a residue name. @@ -64,9 +66,7 @@ int read_ter_db(const char *ffdir, char ter, * \param[in] resname Residue name for terminus. * \returns A list of pointers to entries that match, or of nullptr for no matching entry. */ -std::vector -filter_ter(gmx::ArrayRef tb, - const char *resname); +std::vector filter_ter(gmx::ArrayRef tb, const char* resname); /*! \brief * Interactively select one terminus. @@ -75,6 +75,6 @@ filter_ter(gmx::ArrayRef tb, * \param[in] title Name of entry. * \returns The modification block selected. */ -MoleculePatchDatabase *choose_ter(gmx::ArrayRef tb, const char *title); +MoleculePatchDatabase* choose_ter(gmx::ArrayRef tb, const char* title); #endif diff --git a/src/gromacs/gmxpreprocess/tests/editconf.cpp b/src/gromacs/gmxpreprocess/tests/editconf.cpp index d4a2953322..292e202222 100644 --- a/src/gromacs/gmxpreprocess/tests/editconf.cpp +++ b/src/gromacs/gmxpreprocess/tests/editconf.cpp @@ -65,41 +65,40 @@ using test::TextFileMatch; //! Test parameter struct. using CommandLineOptionParams = std::tuple; -class EditconfTest : public test::CommandLineTestBase, - public ::testing::WithParamInterface +class EditconfTest : + public test::CommandLineTestBase, + public ::testing::WithParamInterface { - public: - EditconfTest() - { - const auto ¶ms = GetParam(); - setInputFile("-f", std::get<0>(params)); - - std::string outputfile = "output."; - outputfile += ftp2ext(std::get<1>(params)); - ExactTextMatch settings; - setOutputFile("-o", outputfile.c_str(), TextFileMatch(settings)); - } - - void runTest(const char *testName) - { - // Get the command line flags that were set up in the constructor - CommandLine &cmdline = commandLine(); - - // Provide the name of the module to call - std::string module[] = { - "editconf" - }; - cmdline.merge(CommandLine(module)); - - // Call the module - ASSERT_EQ(0, gmx_editconf(cmdline.argc(), cmdline.argv())); - - // Check the output - auto extension = ftp2ext(std::get<1>(GetParam())); - TestReferenceChecker rootChecker(this->rootChecker()); - rootChecker.checkString(extension, testName); - checkOutputFiles(); - } +public: + EditconfTest() + { + const auto& params = GetParam(); + setInputFile("-f", std::get<0>(params)); + + std::string outputfile = "output."; + outputfile += ftp2ext(std::get<1>(params)); + ExactTextMatch settings; + setOutputFile("-o", outputfile.c_str(), TextFileMatch(settings)); + } + + void runTest(const char* testName) + { + // Get the command line flags that were set up in the constructor + CommandLine& cmdline = commandLine(); + + // Provide the name of the module to call + std::string module[] = { "editconf" }; + cmdline.merge(CommandLine(module)); + + // Call the module + ASSERT_EQ(0, gmx_editconf(cmdline.argc(), cmdline.argv())); + + // Check the output + auto extension = ftp2ext(std::get<1>(GetParam())); + TestReferenceChecker rootChecker(this->rootChecker()); + rootChecker.checkString(extension, testName); + checkOutputFiles(); + } }; TEST_P(EditconfTest, ProducesMatchingOutputStructureFile) @@ -118,11 +117,11 @@ TEST_P(EditconfTest, ProducesMatchingOutputStructureFileUsingIndexGroup) // coordinates. It's better to run the tests only in single than not // have the tests. #if !GMX_DOUBLE -INSTANTIATE_TEST_CASE_P(SinglePeptideFragments, EditconfTest, - ::testing::Combine - (::testing::Values("fragment1.pdb", "fragment1.gro", "fragment1.g96"), - ::testing::Values(efPDB, efGRO, efG96)) - ); +INSTANTIATE_TEST_CASE_P( + SinglePeptideFragments, + EditconfTest, + ::testing::Combine(::testing::Values("fragment1.pdb", "fragment1.gro", "fragment1.g96"), + ::testing::Values(efPDB, efGRO, efG96))); #endif } // namespace diff --git a/src/gromacs/gmxpreprocess/tests/genconf.cpp b/src/gromacs/gmxpreprocess/tests/genconf.cpp index 15dc632af0..6b2401ad68 100644 --- a/src/gromacs/gmxpreprocess/tests/genconf.cpp +++ b/src/gromacs/gmxpreprocess/tests/genconf.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,58 +56,51 @@ using gmx::test::ExactTextMatch; class GenconfTest : public gmx::test::CommandLineTestBase { - public: - GenconfTest() - { - std::string confFileName = gmx::test::TestFileManager::getInputFilePath("spc-and-methanol.gro"); - commandLine().addOption("-f", confFileName); - commandLine().addOption("-seed", "1993"); // make random operations reproducible - setOutputFile("-o", "out.gro", ExactTextMatch()); - } +public: + GenconfTest() + { + std::string confFileName = + gmx::test::TestFileManager::getInputFilePath("spc-and-methanol.gro"); + commandLine().addOption("-f", confFileName); + commandLine().addOption("-seed", "1993"); // make random operations reproducible + setOutputFile("-o", "out.gro", ExactTextMatch()); + } - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); - gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); - rootChecker.checkString(args.toString(), "CommandLine"); + gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); + rootChecker.checkString(args.toString(), "CommandLine"); - ASSERT_EQ(0, gmx_genconf(cmdline.argc(), cmdline.argv())); + ASSERT_EQ(0, gmx_genconf(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } + checkOutputFiles(); + } }; TEST_F(GenconfTest, nbox_Works) { - const char *const cmdline[] = { - "genconf", "-nbox", "2", "1", "1" - }; + const char* const cmdline[] = { "genconf", "-nbox", "2", "1", "1" }; runTest(CommandLine(cmdline)); } TEST_F(GenconfTest, nbox_norenumber_Works) { - const char *const cmdline[] = { - "genconf", "-nbox", "2", "1", "1", "-norenumber" - }; + const char* const cmdline[] = { "genconf", "-nbox", "2", "1", "1", "-norenumber" }; runTest(CommandLine(cmdline)); } TEST_F(GenconfTest, nbox_dist_Works) { - const char *const cmdline[] = { - "genconf", "-nbox", "2", "2", "3", "-dist", "0.1" - }; + const char* const cmdline[] = { "genconf", "-nbox", "2", "2", "3", "-dist", "0.1" }; runTest(CommandLine(cmdline)); } TEST_F(GenconfTest, nbox_rot_Works) { - const char *const cmdline[] = { - "genconf", "-nbox", "2", "2", "3", "-rot" - }; + const char* const cmdline[] = { "genconf", "-nbox", "2", "2", "3", "-rot" }; runTest(CommandLine(cmdline)); } diff --git a/src/gromacs/gmxpreprocess/tests/genion.cpp b/src/gromacs/gmxpreprocess/tests/genion.cpp index 94de26d20f..e84a4b206d 100644 --- a/src/gromacs/gmxpreprocess/tests/genion.cpp +++ b/src/gromacs/gmxpreprocess/tests/genion.cpp @@ -66,55 +66,52 @@ namespace class GenionTest : public CommandLineTestBase { - public: - GenionTest() - { - CommandLine caller = commandLine(); - - const std::string mdpInputFileName(fileManager().getTemporaryFilePath("input.mdp")); - TextWriter::writeFileFromString(mdpInputFileName, - "verlet-buffer-tolerance =-1\nrcoulomb=0.5\nrvdw = 0.5\nrlist = 0.5\n"); - caller.addOption("-f", mdpInputFileName); - caller.addOption("-c", TestFileManager::getInputFilePath("spc216_with_methane.gro")); - caller.addOption("-p", TestFileManager::getInputFilePath("spc216_with_methane.top")); - caller.addOption("-o", tprFileName_); - - gmx_grompp(caller.argc(), caller.argv()); - - setOutputFile("-o", "out.gro", ConfMatch()); - } - - void runTest(const CommandLine &args, const std::string &interactiveCommandLineInput) - { - StdioTestHelper stdIoHelper(&fileManager()); - stdIoHelper.redirectStringToStdin(interactiveCommandLineInput.c_str()); - - CommandLine &cmdline = commandLine(); - cmdline.addOption("-s", tprFileName_); - cmdline.merge(args); - - ASSERT_EQ(0, gmx_genion(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } - private: - const std::string tprFileName_ - = fileManager().getTemporaryFilePath("spc216_with_methane.tpr"); +public: + GenionTest() + { + CommandLine caller = commandLine(); + + const std::string mdpInputFileName(fileManager().getTemporaryFilePath("input.mdp")); + TextWriter::writeFileFromString( + mdpInputFileName, + "verlet-buffer-tolerance =-1\nrcoulomb=0.5\nrvdw = 0.5\nrlist = 0.5\n"); + caller.addOption("-f", mdpInputFileName); + caller.addOption("-c", TestFileManager::getInputFilePath("spc216_with_methane.gro")); + caller.addOption("-p", TestFileManager::getInputFilePath("spc216_with_methane.top")); + caller.addOption("-o", tprFileName_); + + gmx_grompp(caller.argc(), caller.argv()); + + setOutputFile("-o", "out.gro", ConfMatch()); + } + + void runTest(const CommandLine& args, const std::string& interactiveCommandLineInput) + { + StdioTestHelper stdIoHelper(&fileManager()); + stdIoHelper.redirectStringToStdin(interactiveCommandLineInput.c_str()); + + CommandLine& cmdline = commandLine(); + cmdline.addOption("-s", tprFileName_); + cmdline.merge(args); + + ASSERT_EQ(0, gmx_genion(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); + } + +private: + const std::string tprFileName_ = fileManager().getTemporaryFilePath("spc216_with_methane.tpr"); }; TEST_F(GenionTest, HighConcentrationIonPlacement) { - const char *const cmdline[] = { - "genion", "-seed", "1997", "-conc", "1.0", "-rmin", "0.6" - }; + const char* const cmdline[] = { "genion", "-seed", "1997", "-conc", "1.0", "-rmin", "0.6" }; runTest(CommandLine(cmdline), "Water"); } TEST_F(GenionTest, NoIonPlacement) { - const char *const cmdline[] = { - "genion", "-seed", "1997", "-conc", "0.0", "-rmin", "0.6" - }; + const char* const cmdline[] = { "genion", "-seed", "1997", "-conc", "0.0", "-rmin", "0.6" }; runTest(CommandLine(cmdline), "Water"); } diff --git a/src/gromacs/gmxpreprocess/tests/gpp_atomtype.cpp b/src/gromacs/gmxpreprocess/tests/gpp_atomtype.cpp index 50042a8941..1c1f1a909c 100644 --- a/src/gromacs/gmxpreprocess/tests/gpp_atomtype.cpp +++ b/src/gromacs/gmxpreprocess/tests/gpp_atomtype.cpp @@ -57,34 +57,21 @@ namespace class PreprocessingAtomTypesTest : public ::testing::Test { - public: - PreprocessingAtomTypesTest() : - nb_({}, {}) - { - open_symtab(&symtab_); - } - - int addType(const char *name, - int bondAtomType, - int atomNumber) - { - return atypes_.addType(&symtab_, - atom_, - name, - nb_, - bondAtomType, - atomNumber); - } - - ~PreprocessingAtomTypesTest() override - { - done_symtab(&symtab_); - } - protected: - PreprocessingAtomTypes atypes_; - t_symtab symtab_; - t_atom atom_; - InteractionOfType nb_; +public: + PreprocessingAtomTypesTest() : nb_({}, {}) { open_symtab(&symtab_); } + + int addType(const char* name, int bondAtomType, int atomNumber) + { + return atypes_.addType(&symtab_, atom_, name, nb_, bondAtomType, atomNumber); + } + + ~PreprocessingAtomTypesTest() override { done_symtab(&symtab_); } + +protected: + PreprocessingAtomTypes atypes_; + t_symtab symtab_; + t_atom atom_; + InteractionOfType nb_; }; TEST_F(PreprocessingAtomTypesTest, EmptyOnCreate) diff --git a/src/gromacs/gmxpreprocess/tests/gpp_bond_atomtype.cpp b/src/gromacs/gmxpreprocess/tests/gpp_bond_atomtype.cpp index 6e1685284a..1f15b41d7d 100644 --- a/src/gromacs/gmxpreprocess/tests/gpp_bond_atomtype.cpp +++ b/src/gromacs/gmxpreprocess/tests/gpp_bond_atomtype.cpp @@ -52,27 +52,21 @@ class PreprocessingBondAtomTypeTest : public ::testing::Test { - public: - PreprocessingBondAtomTypeTest() - { - open_symtab(&symtab_); - } - - int addType(const char *name); - - ~PreprocessingBondAtomTypeTest() override - { - done_symtab(&symtab_); - } - protected: - PreprocessingBondAtomType bat_; - t_symtab symtab_; +public: + PreprocessingBondAtomTypeTest() { open_symtab(&symtab_); } + + int addType(const char* name); + + ~PreprocessingBondAtomTypeTest() override { done_symtab(&symtab_); } + +protected: + PreprocessingBondAtomType bat_; + t_symtab symtab_; }; -int PreprocessingBondAtomTypeTest::addType(const char *name) +int PreprocessingBondAtomTypeTest::addType(const char* name) { - return bat_.addBondAtomType(&symtab_, - name); + return bat_.addBondAtomType(&symtab_, name); } TEST_F(PreprocessingBondAtomTypeTest, EmptyOnCreate) diff --git a/src/gromacs/gmxpreprocess/tests/insert_molecules.cpp b/src/gromacs/gmxpreprocess/tests/insert_molecules.cpp index 39699fdb15..53cf3080ea 100644 --- a/src/gromacs/gmxpreprocess/tests/insert_molecules.cpp +++ b/src/gromacs/gmxpreprocess/tests/insert_molecules.cpp @@ -55,32 +55,27 @@ using gmx::test::ExactTextMatch; class InsertMoleculesTest : public gmx::test::CommandLineTestBase { - public: - InsertMoleculesTest() - { - setOutputFile("-o", "out.gro", ExactTextMatch()); - } +public: + InsertMoleculesTest() { setOutputFile("-o", "out.gro", ExactTextMatch()); } - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); - gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); - rootChecker.checkString(args.toString(), "CommandLine"); + gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); + rootChecker.checkString(args.toString(), "CommandLine"); - ASSERT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory( - &gmx::InsertMoleculesInfo::create, &cmdline)); + ASSERT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory( + &gmx::InsertMoleculesInfo::create, &cmdline)); - checkOutputFiles(); - } + checkOutputFiles(); + } }; TEST_F(InsertMoleculesTest, InsertsMoleculesIntoExistingConfiguration) { - const char *const cmdline[] = { - "insert-molecules", "-nmol", "1", "-seed", "1997" - }; + const char* const cmdline[] = { "insert-molecules", "-nmol", "1", "-seed", "1997" }; setInputFile("-f", "spc-and-methanol.gro"); setInputFile("-ci", "x2.gro"); runTest(CommandLine(cmdline)); @@ -88,18 +83,14 @@ TEST_F(InsertMoleculesTest, InsertsMoleculesIntoExistingConfiguration) TEST_F(InsertMoleculesTest, InsertsMoleculesIntoEmptyBox) { - const char *const cmdline[] = { - "insert-molecules", "-box", "4", "-nmol", "5", "-seed", "1997" - }; + const char* const cmdline[] = { "insert-molecules", "-box", "4", "-nmol", "5", "-seed", "1997" }; setInputFile("-ci", "x2.gro"); runTest(CommandLine(cmdline)); } TEST_F(InsertMoleculesTest, InsertsMoleculesIntoEnlargedBox) { - const char *const cmdline[] = { - "insert-molecules", "-box", "4", "-nmol", "2", "-seed", "1997" - }; + const char* const cmdline[] = { "insert-molecules", "-box", "4", "-nmol", "2", "-seed", "1997" }; setInputFile("-f", "spc-and-methanol.gro"); setInputFile("-ci", "x.gro"); runTest(CommandLine(cmdline)); @@ -107,7 +98,7 @@ TEST_F(InsertMoleculesTest, InsertsMoleculesIntoEnlargedBox) TEST_F(InsertMoleculesTest, InsertsMoleculesWithReplacement) { - const char *const cmdline[] = { + const char* const cmdline[] = { "insert-molecules", "-nmol", "4", "-replace", "all", "-seed", "1997" }; setInputFile("-f", "spc216.gro"); @@ -117,15 +108,9 @@ TEST_F(InsertMoleculesTest, InsertsMoleculesWithReplacement) TEST_F(InsertMoleculesTest, InsertsMoleculesIntoFixedPositions) { - const char *const cmdline[] = { - "insert-molecules", "-box", "4", "-seed", "1997" - }; - const char *const positions[] = { - "0.0 0.0 0.0", - "1.0 2.0 3.0", - "0.99 2.01 3.0", - "2.0 1.0 2.0" - }; + const char* const cmdline[] = { "insert-molecules", "-box", "4", "-seed", "1997" }; + const char* const positions[] = { "0.0 0.0 0.0", "1.0 2.0 3.0", "0.99 2.01 3.0", + "2.0 1.0 2.0" }; setInputFile("-ci", "x0.gro"); setInputFileContents("-ip", "dat", positions); runTest(CommandLine(cmdline)); diff --git a/src/gromacs/gmxpreprocess/tests/pdb2gmx.cpp b/src/gromacs/gmxpreprocess/tests/pdb2gmx.cpp index a5adabb596..0bfba1d840 100644 --- a/src/gromacs/gmxpreprocess/tests/pdb2gmx.cpp +++ b/src/gromacs/gmxpreprocess/tests/pdb2gmx.cpp @@ -64,8 +64,8 @@ namespace using test::CommandLine; //! Test parameter struct. -using CommandLineOptionParams = std::tuple; +using CommandLineOptionParams = + std::tuple; /*! \brief Strings containing regular expressions for lines to skip * when matching. @@ -76,64 +76,62 @@ using CommandLineOptionParams = std::tuple c_regexStringsToSkip = -{ - "^;[[:blank:]] *File '.*' was generated.*\n", - "^;[[:blank:]]*By user:.*\n", - "^;[[:blank:]]*On host:.*\n", - "^;[[:blank:]]*At date:.*\n", - "^;[[:blank:]]*:-\\).*\\(-:.*\n", - "^;[[:blank:]]*Executable:.*\n", - "^;[[:blank:]]*Data prefix:.*\n", - "^;[[:blank:]]*Working dir:.*\n", - "^;[[:blank:]]*pdb2gmx.*-test.*\n" -}; +std::vector c_regexStringsToSkip = { "^;[[:blank:]] *File '.*' was generated.*\n", + "^;[[:blank:]]*By user:.*\n", + "^;[[:blank:]]*On host:.*\n", + "^;[[:blank:]]*At date:.*\n", + "^;[[:blank:]]*:-\\).*\\(-:.*\n", + "^;[[:blank:]]*Executable:.*\n", + "^;[[:blank:]]*Data prefix:.*\n", + "^;[[:blank:]]*Working dir:.*\n", + "^;[[:blank:]]*pdb2gmx.*-test.*\n" }; //! Compiled regular expressions for lines to skip when matching. -FilteringExactTextMatch c_textMatcher(c_regexStringsToSkip); +FilteringExactTextMatch c_textMatcher(c_regexStringsToSkip); -class Pdb2gmxTest : public test::CommandLineTestBase, - public ::testing::WithParamInterface +class Pdb2gmxTest : public test::CommandLineTestBase, public ::testing::WithParamInterface { - public: - Pdb2gmxTest() +public: + Pdb2gmxTest() + { + int outputFileType = std::get<6>(GetParam()); + if (outputFileType == efPDB) { - int outputFileType = std::get<6>(GetParam()); - if (outputFileType == efPDB) - { - // If we're writing PDB output, we are interested in - // testing things like TER records and chain IDs. - std::string outputfile = "conf."; - outputfile += ftp2ext(outputFileType); - ExactTextMatch settings; - setOutputFile("-o", outputfile.c_str(), TextFileMatch(settings)); - } - else - { - setOutputFile("-o", "conf.gro", ConfMatch()); - } - setOutputFile("-p", "topol.top", TextFileMatch(c_textMatcher)); + // If we're writing PDB output, we are interested in + // testing things like TER records and chain IDs. + std::string outputfile = "conf."; + outputfile += ftp2ext(outputFileType); + ExactTextMatch settings; + setOutputFile("-o", outputfile.c_str(), TextFileMatch(settings)); } - - void runTest(const CommandLine &args) + else { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); + setOutputFile("-o", "conf.gro", ConfMatch()); + } + setOutputFile("-p", "topol.top", TextFileMatch(c_textMatcher)); + } - TestReferenceChecker rootChecker(this->rootChecker()); + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); - ASSERT_EQ(0, CommandLineTestHelper::runModuleFactory(&pdb2gmxInfo::create, &cmdline)); + TestReferenceChecker rootChecker(this->rootChecker()); - checkOutputFiles(); - } + ASSERT_EQ(0, CommandLineTestHelper::runModuleFactory(&pdb2gmxInfo::create, &cmdline)); + + checkOutputFiles(); + } }; TEST_P(Pdb2gmxTest, ProducesMatchingTopology) { - const auto ¶ms = GetParam(); - std::string cmdline[] = { - "pdb2gmx", "-ignh", "-ff", std::get<0>(params), "-water", std::get<1>(params), "-vsite", std::get<2>(params), - "-chainsep", std::get<3>(params), "-merge", std::get<4>(params) - }; + const auto& params = GetParam(); + std::string cmdline[] = { "pdb2gmx", "-ignh", + "-ff", std::get<0>(params), + "-water", std::get<1>(params), + "-vsite", std::get<2>(params), + "-chainsep", std::get<3>(params), + "-merge", std::get<4>(params) }; setInputFile("-f", std::get<5>(params)); runTest(CommandLine(cmdline)); } @@ -142,89 +140,97 @@ TEST_P(Pdb2gmxTest, ProducesMatchingTopology) // CMakeLists.txt file we split them into separtae test binaries. #if OPLSAA -INSTANTIATE_TEST_CASE_P(ForOplsaa, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("oplsaa"), - ::testing::Values("tip3p", "tip4p", "tip5p"), - ::testing::Values("none", "h"), - ::testing::Values("id_or_ter"), - ::testing::Values("no"), - ::testing::Values("fragment1.pdb", "fragment2.pdb", "fragment3.pdb", "fragment4.pdb"), - ::testing::Values(efGRO)) - ); +INSTANTIATE_TEST_CASE_P(ForOplsaa, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("oplsaa"), + ::testing::Values("tip3p", "tip4p", "tip5p"), + ::testing::Values("none", "h"), + ::testing::Values("id_or_ter"), + ::testing::Values("no"), + ::testing::Values("fragment1.pdb", + "fragment2.pdb", + "fragment3.pdb", + "fragment4.pdb"), + ::testing::Values(efGRO))); #endif #if GROMOS -INSTANTIATE_TEST_CASE_P(ForGromos43a1, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("gromos43a1"), - ::testing::Values("spc", "spce"), - ::testing::Values("none", "h"), - ::testing::Values("id_or_ter"), - ::testing::Values("no"), - ::testing::Values("fragment1.pdb", "fragment2.pdb", "fragment3.pdb", "fragment4.pdb"), - ::testing::Values(efGRO)) - ); - -INSTANTIATE_TEST_CASE_P(ForGromos53a6, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("gromos53a6"), - ::testing::Values("spc", "spce"), - ::testing::Values("none", "h"), - ::testing::Values("id_or_ter"), - ::testing::Values("no"), - ::testing::Values("fragment1.pdb", "fragment2.pdb", "fragment3.pdb", "fragment4.pdb"), - ::testing::Values(efGRO)) - ); +INSTANTIATE_TEST_CASE_P(ForGromos43a1, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("gromos43a1"), + ::testing::Values("spc", "spce"), + ::testing::Values("none", "h"), + ::testing::Values("id_or_ter"), + ::testing::Values("no"), + ::testing::Values("fragment1.pdb", + "fragment2.pdb", + "fragment3.pdb", + "fragment4.pdb"), + ::testing::Values(efGRO))); + +INSTANTIATE_TEST_CASE_P(ForGromos53a6, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("gromos53a6"), + ::testing::Values("spc", "spce"), + ::testing::Values("none", "h"), + ::testing::Values("id_or_ter"), + ::testing::Values("no"), + ::testing::Values("fragment1.pdb", + "fragment2.pdb", + "fragment3.pdb", + "fragment4.pdb"), + ::testing::Values(efGRO))); #endif #if AMBER -INSTANTIATE_TEST_CASE_P(ForAmber99sb_ildn, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("amber99sb-ildn"), - ::testing::Values("tip3p"), - ::testing::Values("none", "h"), - ::testing::Values("id_or_ter"), - ::testing::Values("no"), - ::testing::Values("fragment1.pdb", "fragment2.pdb", "fragment3.pdb", "fragment4.pdb"), - ::testing::Values(efGRO)) - ); +INSTANTIATE_TEST_CASE_P(ForAmber99sb_ildn, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("amber99sb-ildn"), + ::testing::Values("tip3p"), + ::testing::Values("none", "h"), + ::testing::Values("id_or_ter"), + ::testing::Values("no"), + ::testing::Values("fragment1.pdb", + "fragment2.pdb", + "fragment3.pdb", + "fragment4.pdb"), + ::testing::Values(efGRO))); #endif #if CHARMM -INSTANTIATE_TEST_CASE_P(ForCharmm27, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("charmm27"), - ::testing::Values("tip3p"), - ::testing::Values("none", "h"), - ::testing::Values("id_or_ter"), - ::testing::Values("no"), - ::testing::Values("fragment1.pdb", "fragment2.pdb", "fragment3.pdb", "fragment4.pdb"), - ::testing::Values(efGRO)) - ); - - -INSTANTIATE_TEST_CASE_P(ChainSep, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("charmm27"), - ::testing::Values("tip3p"), - ::testing::Values("none"), - ::testing::Values("id", "ter", "id_or_ter", "id_and_ter"), - ::testing::Values("all", "no"), - ::testing::Values("chainTer.pdb"), - ::testing::Values(efGRO)) - ); - -INSTANTIATE_TEST_CASE_P(ChainChanges, Pdb2gmxTest, - ::testing::Combine - (::testing::Values("charmm27"), - ::testing::Values("tip3p"), - ::testing::Values("none"), - ::testing::Values("id", "ter", "id_or_ter", "id_and_ter"), - ::testing::Values("no"), - ::testing::Values("two-fragments.pdb"), - ::testing::Values(efPDB)) - ); +INSTANTIATE_TEST_CASE_P(ForCharmm27, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("charmm27"), + ::testing::Values("tip3p"), + ::testing::Values("none", "h"), + ::testing::Values("id_or_ter"), + ::testing::Values("no"), + ::testing::Values("fragment1.pdb", + "fragment2.pdb", + "fragment3.pdb", + "fragment4.pdb"), + ::testing::Values(efGRO))); + + +INSTANTIATE_TEST_CASE_P(ChainSep, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("charmm27"), + ::testing::Values("tip3p"), + ::testing::Values("none"), + ::testing::Values("id", "ter", "id_or_ter", "id_and_ter"), + ::testing::Values("all", "no"), + ::testing::Values("chainTer.pdb"), + ::testing::Values(efGRO))); + +INSTANTIATE_TEST_CASE_P(ChainChanges, + Pdb2gmxTest, + ::testing::Combine(::testing::Values("charmm27"), + ::testing::Values("tip3p"), + ::testing::Values("none"), + ::testing::Values("id", "ter", "id_or_ter", "id_and_ter"), + ::testing::Values("no"), + ::testing::Values("two-fragments.pdb"), + ::testing::Values(efPDB))); #endif } // namespace diff --git a/src/gromacs/gmxpreprocess/tests/readir.cpp b/src/gromacs/gmxpreprocess/tests/readir.cpp index a8a391ba09..b9d06c00b6 100644 --- a/src/gromacs/gmxpreprocess/tests/readir.cpp +++ b/src/gromacs/gmxpreprocess/tests/readir.cpp @@ -70,103 +70,100 @@ namespace test class GetIrTest : public ::testing::Test { - public: - GetIrTest() : opts_(), - wi_(init_warning(FALSE, 0)), wiGuard_(wi_) - - { - snew(opts_.include, STRLEN); - snew(opts_.define, STRLEN); - } - ~GetIrTest() override - { - done_inputrec_strings(); - sfree(opts_.include); - sfree(opts_.define); - } - /*! \brief Test mdp reading and writing - * - * \todo Modernize read_inp and write_inp to use streams, - * which will make these tests run faster, because they don't - * use disk files. */ - void runTest(const std::string &inputMdpFileContents) - { - auto inputMdpFilename = fileManager_.getTemporaryFilePath("input.mdp"); - auto outputMdpFilename = fileManager_.getTemporaryFilePath("output.mdp"); - - TextWriter::writeFileFromString(inputMdpFilename, inputMdpFileContents); - - get_ir(inputMdpFilename.c_str(), outputMdpFilename.c_str(), - &mdModules_, &ir_, &opts_, WriteMdpHeader::no, wi_); - - check_ir(inputMdpFilename.c_str(), mdModules_.notifier(), &ir_, &opts_, wi_); - // Now check - bool failure = warning_errors_exist(wi_); - TestReferenceData data; - TestReferenceChecker checker(data.rootChecker()); - checker.checkBoolean(failure, "Error parsing mdp file"); - warning_reset(wi_); - - auto outputMdpContents = TextReader::readFileToString(outputMdpFilename); - checker.checkString(outputMdpContents, "OutputMdpFile"); - } - - TestFileManager fileManager_; - t_inputrec ir_; - MDModules mdModules_; - t_gromppopts opts_; - warninp_t wi_; - unique_cptr wiGuard_; +public: + GetIrTest() : opts_(), wi_(init_warning(FALSE, 0)), wiGuard_(wi_) + + { + snew(opts_.include, STRLEN); + snew(opts_.define, STRLEN); + } + ~GetIrTest() override + { + done_inputrec_strings(); + sfree(opts_.include); + sfree(opts_.define); + } + /*! \brief Test mdp reading and writing + * + * \todo Modernize read_inp and write_inp to use streams, + * which will make these tests run faster, because they don't + * use disk files. */ + void runTest(const std::string& inputMdpFileContents) + { + auto inputMdpFilename = fileManager_.getTemporaryFilePath("input.mdp"); + auto outputMdpFilename = fileManager_.getTemporaryFilePath("output.mdp"); + + TextWriter::writeFileFromString(inputMdpFilename, inputMdpFileContents); + + get_ir(inputMdpFilename.c_str(), outputMdpFilename.c_str(), &mdModules_, &ir_, &opts_, + WriteMdpHeader::no, wi_); + + check_ir(inputMdpFilename.c_str(), mdModules_.notifier(), &ir_, &opts_, wi_); + // Now check + bool failure = warning_errors_exist(wi_); + TestReferenceData data; + TestReferenceChecker checker(data.rootChecker()); + checker.checkBoolean(failure, "Error parsing mdp file"); + warning_reset(wi_); + + auto outputMdpContents = TextReader::readFileToString(outputMdpFilename); + checker.checkString(outputMdpContents, "OutputMdpFile"); + } + + TestFileManager fileManager_; + t_inputrec ir_; + MDModules mdModules_; + t_gromppopts opts_; + warninp_t wi_; + unique_cptr wiGuard_; }; TEST_F(GetIrTest, HandlesDifferentKindsOfMdpLines) { - const char *inputMdpFile[] = { - "; File to run my simulation", - "title = simulation", - "define = -DBOOLVAR -DVAR=VALUE", - ";", - "xtc_grps = System ; was Protein", - "include = -I/home/me/stuff", - "", - "tau-t = 0.1 0.3", - "ref-t = ;290 290", - "tinit = 0.3", - "init_step = 0", - "nstcomm = 100", - "integrator = steep" - }; + const char* inputMdpFile[] = { "; File to run my simulation", + "title = simulation", + "define = -DBOOLVAR -DVAR=VALUE", + ";", + "xtc_grps = System ; was Protein", + "include = -I/home/me/stuff", + "", + "tau-t = 0.1 0.3", + "ref-t = ;290 290", + "tinit = 0.3", + "init_step = 0", + "nstcomm = 100", + "integrator = steep" }; runTest(joinStrings(inputMdpFile, "\n")); } TEST_F(GetIrTest, RejectsNonCommentLineWithNoEquals) { - const char *inputMdpFile = "title simulation"; + const char* inputMdpFile = "title simulation"; EXPECT_DEATH_IF_SUPPORTED(runTest(inputMdpFile), "No '=' to separate"); } TEST_F(GetIrTest, AcceptsKeyWithoutValue) { // Users are probably using lines like this - const char *inputMdpFile = "xtc_grps = "; + const char* inputMdpFile = "xtc_grps = "; runTest(inputMdpFile); } TEST_F(GetIrTest, RejectsValueWithoutKey) { - const char *inputMdpFile = "= -I/home/me/stuff"; + const char* inputMdpFile = "= -I/home/me/stuff"; EXPECT_DEATH_IF_SUPPORTED(runTest(inputMdpFile), "No .mdp parameter name was found"); } TEST_F(GetIrTest, RejectsEmptyKeyAndEmptyValue) { - const char *inputMdpFile = " = "; + const char* inputMdpFile = " = "; EXPECT_DEATH_IF_SUPPORTED(runTest(inputMdpFile), "No .mdp parameter name or value was found"); } TEST_F(GetIrTest, AcceptsDefineParametersWithValuesIncludingAssignment) { - const char *inputMdpFile[] = { + const char* inputMdpFile[] = { "define = -DBOOL -DVAR=VALUE", }; runTest(joinStrings(inputMdpFile, "\n")); @@ -174,7 +171,7 @@ TEST_F(GetIrTest, AcceptsDefineParametersWithValuesIncludingAssignment) TEST_F(GetIrTest, AcceptsEmptyLines) { - const char *inputMdpFile = ""; + const char* inputMdpFile = ""; runTest(inputMdpFile); } @@ -182,45 +179,46 @@ TEST_F(GetIrTest, AcceptsEmptyLines) // are currently the only ones using the new Options-style handling. TEST_F(GetIrTest, AcceptsElectricField) { - const char *inputMdpFile = "electric-field-x = 1.2 0 0 0"; + const char* inputMdpFile = "electric-field-x = 1.2 0 0 0"; runTest(inputMdpFile); } TEST_F(GetIrTest, AcceptsElectricFieldPulsed) { - const char *inputMdpFile = "electric-field-y = 3.7 2.0 6.5 1.0"; + const char* inputMdpFile = "electric-field-y = 3.7 2.0 6.5 1.0"; runTest(inputMdpFile); } TEST_F(GetIrTest, AcceptsElectricFieldOscillating) { - const char *inputMdpFile = "electric-field-z = 3.7 7.5 0 0"; + const char* inputMdpFile = "electric-field-z = 3.7 7.5 0 0"; runTest(inputMdpFile); } TEST_F(GetIrTest, RejectsDuplicateOldAndNewKeys) { - const char *inputMdpFile[] = {"verlet-buffer-drift = 1.3", "verlet-buffer-tolerance = 2.7"}; - EXPECT_DEATH_IF_SUPPORTED(runTest(joinStrings(inputMdpFile, "\n")), "A parameter is present with both"); + const char* inputMdpFile[] = { "verlet-buffer-drift = 1.3", "verlet-buffer-tolerance = 2.7" }; + EXPECT_DEATH_IF_SUPPORTED(runTest(joinStrings(inputMdpFile, "\n")), + "A parameter is present with both"); } TEST_F(GetIrTest, AcceptsImplicitSolventNo) { - const char *inputMdpFile = "implicit-solvent = no"; + const char* inputMdpFile = "implicit-solvent = no"; runTest(inputMdpFile); } TEST_F(GetIrTest, RejectsImplicitSolventYes) { - const char *inputMdpFile = "implicit-solvent = yes"; + const char* inputMdpFile = "implicit-solvent = yes"; EXPECT_DEATH_IF_SUPPORTED(runTest(inputMdpFile), "Invalid enum"); } TEST_F(GetIrTest, AcceptsMimic) { - const char *inputMdpFile[] = {"integrator = mimic", "QMMM-grps = QMatoms"}; + const char* inputMdpFile[] = { "integrator = mimic", "QMMM-grps = QMatoms" }; runTest(joinStrings(inputMdpFile, "\n")); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/gmxpreprocess/tests/solvate.cpp b/src/gromacs/gmxpreprocess/tests/solvate.cpp index c4e5f36e9e..7a8f2e737a 100644 --- a/src/gromacs/gmxpreprocess/tests/solvate.cpp +++ b/src/gromacs/gmxpreprocess/tests/solvate.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,37 +62,30 @@ using gmx::test::ExactTextMatch; class SolvateTest : public gmx::test::CommandLineTestBase { - public: - SolvateTest() - { - setOutputFile("-o", "out.gro", ConfMatch()); - } - - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - - ASSERT_EQ(0, gmx_solvate(cmdline.argc(), cmdline.argv())); - checkOutputFiles(); - } +public: + SolvateTest() { setOutputFile("-o", "out.gro", ConfMatch()); } + + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + + ASSERT_EQ(0, gmx_solvate(cmdline.argc(), cmdline.argv())); + checkOutputFiles(); + } }; TEST_F(SolvateTest, cs_box_Works) { // use default solvent box (-cs without argument) - const char *const cmdline[] = { - "solvate", "-cs", "-box", "1.1" - }; + const char* const cmdline[] = { "solvate", "-cs", "-box", "1.1" }; runTest(CommandLine(cmdline)); } TEST_F(SolvateTest, cs_cp_Works) { // use default solvent box (-cs without argument) - const char *const cmdline[] = { - "solvate", "-cs" - }; + const char* const cmdline[] = { "solvate", "-cs" }; setInputFile("-cp", "spc-and-methanol.gro"); runTest(CommandLine(cmdline)); } @@ -100,9 +93,7 @@ TEST_F(SolvateTest, cs_cp_Works) TEST_F(SolvateTest, cs_cp_p_Works) { // use default solvent box (-cs without argument) - const char *const cmdline[] = { - "solvate", "-cs" - }; + const char* const cmdline[] = { "solvate", "-cs" }; setInputFile("-cp", "spc-and-methanol.gro"); setModifiableInputFile("-p", "spc-and-methanol.top"); @@ -112,9 +103,7 @@ TEST_F(SolvateTest, cs_cp_p_Works) TEST_F(SolvateTest, shell_Works) { // use default solvent box (-cs without argument) - const char *const cmdline[] = { - "solvate", "-cs" - }; + const char* const cmdline[] = { "solvate", "-cs" }; setInputFile("-cp", "spc-and-methanol.gro"); commandLine().addOption("-shell", 1.0); @@ -124,9 +113,7 @@ TEST_F(SolvateTest, shell_Works) TEST_F(SolvateTest, update_Topology_Works) { // use solvent box with 2 solvents, check that topology has been updated - const char *const cmdline[] = { - "solvate" - }; + const char* const cmdline[] = { "solvate" }; setInputFile("-cs", "mixed_solvent.gro"); setInputFile("-cp", "simple.gro"); setInputAndOutputFile("-p", "simple.top", ExactTextMatch()); diff --git a/src/gromacs/gmxpreprocess/tomorse.cpp b/src/gromacs/gmxpreprocess/tomorse.cpp index 72d14acfd0..514a35bcb0 100644 --- a/src/gromacs/gmxpreprocess/tomorse.cpp +++ b/src/gromacs/gmxpreprocess/tomorse.cpp @@ -53,17 +53,18 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ char *ai, *aj; real e_diss; } t_2morse; -static t_2morse *read_dissociation_energies(int *n2morse) +static t_2morse* read_dissociation_energies(int* n2morse) { char ai[32], aj[32]; double e_diss; - const char *fn = "edissoc.dat"; - t_2morse *t2m = nullptr; + const char* fn = "edissoc.dat"; + t_2morse* t2m = nullptr; int maxn2m = 0, n2m = 0; int nread; @@ -90,8 +91,7 @@ static t_2morse *read_dissociation_energies(int *n2morse) n2m++; } /* If we did not read three items, quit reading */ - } - while (nread == 3); + } while (nread == 3); /* Set the return values */ *n2morse = n2m; @@ -99,7 +99,7 @@ static t_2morse *read_dissociation_energies(int *n2morse) return t2m; } -static int nequal(const char *a1, const char *a2) +static int nequal(const char* a1, const char* a2) { int i; @@ -122,7 +122,7 @@ static int nequal(const char *a1, const char *a2) return i; } -static real search_e_diss(int n2m, t_2morse t2m[], const char *ai, const char *aj) +static real search_e_diss(int n2m, t_2morse t2m[], const char* ai, const char* aj) { int i; int ibest = -1; @@ -133,8 +133,8 @@ static real search_e_diss(int n2m, t_2morse t2m[], const char *ai, const char *a for (i = 0; (i < n2m); i++) { /* Check for a perfect match */ - if (((gmx_strcasecmp(t2m[i].ai, ai) == 0) && (gmx_strcasecmp(t2m[i].aj, aj) == 0)) || - ((gmx_strcasecmp(t2m[i].aj, ai) == 0) && (gmx_strcasecmp(t2m[i].ai, aj) == 0))) + if (((gmx_strcasecmp(t2m[i].ai, ai) == 0) && (gmx_strcasecmp(t2m[i].aj, aj) == 0)) + || ((gmx_strcasecmp(t2m[i].aj, ai) == 0) && (gmx_strcasecmp(t2m[i].ai, aj) == 0))) { ibest = i; break; @@ -146,8 +146,7 @@ static real search_e_diss(int n2m, t_2morse t2m[], const char *ai, const char *a */ nii = nequal(t2m[i].ai, ai); njj = nequal(t2m[i].aj, aj); - if (((nii > nbstii) && (njj >= nbstjj)) || - ((nii >= nbstii) && (njj > nbstjj))) + if (((nii > nbstii) && (njj >= nbstjj)) || ((nii >= nbstii) && (njj > nbstjj))) { if ((nii > 0) && (njj > 0)) { @@ -161,8 +160,7 @@ static real search_e_diss(int n2m, t_2morse t2m[], const char *ai, const char *a /* Swap ai and aj (at least in counting the number of equal chars) */ nii = nequal(t2m[i].ai, aj); njj = nequal(t2m[i].aj, ai); - if (((nii > nbstii) && (njj >= nbstjj)) || - ((nii >= nbstii) && (njj > nbstjj))) + if (((nii > nbstii) && (njj >= nbstjj)) || ((nii >= nbstii) && (njj > nbstjj))) { if ((nii > 0) && (njj > 0)) { @@ -187,10 +185,10 @@ static real search_e_diss(int n2m, t_2morse t2m[], const char *ai, const char *a } } -void convert_harmonics(gmx::ArrayRef mols, PreprocessingAtomTypes *atype) +void convert_harmonics(gmx::ArrayRef mols, PreprocessingAtomTypes* atype) { int n2m; - t_2morse *t2m; + t_2morse* t2m; /* First get the data */ t2m = read_dissociation_energies(&n2m); @@ -202,7 +200,7 @@ void convert_harmonics(gmx::ArrayRef mols, PreprocessingAto /* For all the molecule types */ int i = 0; - for (auto &mol : mols) + for (auto& mol : mols) { /* Check how many morse and harmonic BONDSs there are, increase size of * morse with the number of harmonics @@ -211,25 +209,24 @@ void convert_harmonics(gmx::ArrayRef mols, PreprocessingAto { if ((interaction_function[bb].flags & IF_BTYPE) && (bb != F_MORSE)) { - int nrharm = mol.interactions[bb].size(); + int nrharm = mol.interactions[bb].size(); /* Now loop over the harmonics, trying to convert them */ for (auto harmonic = mol.interactions[bb].interactionTypes.begin(); - harmonic != mol.interactions[bb].interactionTypes.end(); ) + harmonic != mol.interactions[bb].interactionTypes.end();) { int ni = harmonic->ai(); int nj = harmonic->aj(); - real edis = - search_e_diss(n2m, t2m, - atype->atomNameFromAtomType(mol.atoms.atom[ni].type), - atype->atomNameFromAtomType(mol.atoms.atom[nj].type)); + real edis = search_e_diss(n2m, t2m, + atype->atomNameFromAtomType(mol.atoms.atom[ni].type), + atype->atomNameFromAtomType(mol.atoms.atom[nj].type)); if (edis != 0) { - real b0 = harmonic->c0(); - real kb = harmonic->c1(); - real beta = std::sqrt(kb/(2*edis)); - std::vector atoms = {ni, nj}; - std::vector forceParam = {b0, edis, beta}; + real b0 = harmonic->c0(); + real kb = harmonic->c1(); + real beta = std::sqrt(kb / (2 * edis)); + std::vector atoms = { ni, nj }; + std::vector forceParam = { b0, edis, beta }; mol.interactions[F_MORSE].interactionTypes.emplace_back( InteractionOfType(atoms, forceParam)); harmonic = mol.interactions[bb].interactionTypes.erase(harmonic); @@ -242,7 +239,7 @@ void convert_harmonics(gmx::ArrayRef mols, PreprocessingAto int newHarmonics = mol.interactions[bb].size(); fprintf(stderr, "Converted %d out of %d %s to morse bonds for mol %d\n", - nrharm-newHarmonics, nrharm, interaction_function[bb].name, i); + nrharm - newHarmonics, nrharm, interaction_function[bb].name, i); } } i++; diff --git a/src/gromacs/gmxpreprocess/tomorse.h b/src/gromacs/gmxpreprocess/tomorse.h index eb20491064..647279996a 100644 --- a/src/gromacs/gmxpreprocess/tomorse.h +++ b/src/gromacs/gmxpreprocess/tomorse.h @@ -43,6 +43,6 @@ class PreprocessingAtomTypes; struct MoleculeInformation; -void convert_harmonics(gmx::ArrayRef mols, PreprocessingAtomTypes *atype); +void convert_harmonics(gmx::ArrayRef mols, PreprocessingAtomTypes* atype); #endif diff --git a/src/gromacs/gmxpreprocess/topdirs.cpp b/src/gromacs/gmxpreprocess/topdirs.cpp index 8f7aea5bd7..c409664222 100644 --- a/src/gromacs/gmxpreprocess/topdirs.cpp +++ b/src/gromacs/gmxpreprocess/topdirs.cpp @@ -50,51 +50,18 @@ #include "gromacs/utility/smalloc.h" /* Must correspond to the Directive enum in grompp_impl.h */ -static gmx::EnumerationArray directive_names - = { { - "defaults", - "atomtypes", - "bondtypes", - "constrainttypes", - "pairtypes", - "angletypes", - "dihedraltypes", - "nonbond_params", - "implicit_genborn_params", - "implicit_surface_params", - "cmaptypes", - /* All the directives above can not appear after moleculetype */ - "moleculetype", - "atoms", - "virtual_sites2", - "virtual_sites3", - "virtual_sites4", - "virtual_sitesn", - "bonds", - "exclusions", - "pairs", - "pairs_nb", - "angles", - "dihedrals", - "constraints", - "settles", - "polarization", - "water_polarization", - "thole_polarization", - "system", - "molecules", - "position_restraints", - "angle_restraints", - "angle_restraints_z", - "distance_restraints", - "orientation_restraints", - "dihedral_restraints", - "cmap", - "intermolecular_interactions", - "maxdirs", - "invalid", - "none" - }}; +static gmx::EnumerationArray directive_names = { + { "defaults", "atomtypes", "bondtypes", "constrainttypes", "pairtypes", "angletypes", + "dihedraltypes", "nonbond_params", "implicit_genborn_params", "implicit_surface_params", + "cmaptypes", + /* All the directives above can not appear after moleculetype */ + "moleculetype", "atoms", "virtual_sites2", "virtual_sites3", "virtual_sites4", + "virtual_sitesn", "bonds", "exclusions", "pairs", "pairs_nb", "angles", "dihedrals", + "constraints", "settles", "polarization", "water_polarization", "thole_polarization", + "system", "molecules", "position_restraints", "angle_restraints", "angle_restraints_z", + "distance_restraints", "orientation_restraints", "dihedral_restraints", "cmap", + "intermolecular_interactions", "maxdirs", "invalid", "none" } +}; int ifunc_index(Directive d, int type) { @@ -104,53 +71,32 @@ int ifunc_index(Directive d, int type) case Directive::d_bonds: switch (type) { - case 1: - return F_BONDS; - case 2: - return F_G96BONDS; - case 3: - return F_MORSE; - case 4: - return F_CUBICBONDS; - case 5: - return F_CONNBONDS; - case 6: - return F_HARMONIC; - case 7: - return F_FENEBONDS; - case 8: - return F_TABBONDS; - case 9: - return F_TABBONDSNC; - case 10: - return F_RESTRBONDS; - default: - gmx_fatal(FARGS, "Invalid bond type %d", type); + case 1: return F_BONDS; + case 2: return F_G96BONDS; + case 3: return F_MORSE; + case 4: return F_CUBICBONDS; + case 5: return F_CONNBONDS; + case 6: return F_HARMONIC; + case 7: return F_FENEBONDS; + case 8: return F_TABBONDS; + case 9: return F_TABBONDSNC; + case 10: return F_RESTRBONDS; + default: gmx_fatal(FARGS, "Invalid bond type %d", type); } case Directive::d_angles: case Directive::d_angletypes: switch (type) { - case 1: - return F_ANGLES; - case 2: - return F_G96ANGLES; - case 3: - return F_CROSS_BOND_BONDS; - case 4: - return F_CROSS_BOND_ANGLES; - case 5: - return F_UREY_BRADLEY; - case 6: - return F_QUARTIC_ANGLES; - case 8: - return F_TABANGLES; - case 9: - return F_LINEAR_ANGLES; - case 10: - return F_RESTRANGLES; - default: - gmx_fatal(FARGS, "Invalid angle type %d", type); + case 1: return F_ANGLES; + case 2: return F_G96ANGLES; + case 3: return F_CROSS_BOND_BONDS; + case 4: return F_CROSS_BOND_ANGLES; + case 5: return F_UREY_BRADLEY; + case 6: return F_QUARTIC_ANGLES; + case 8: return F_TABANGLES; + case 9: return F_LINEAR_ANGLES; + case 10: return F_RESTRANGLES; + default: gmx_fatal(FARGS, "Invalid angle type %d", type); } case Directive::d_pairs: case Directive::d_pairtypes: @@ -166,36 +112,25 @@ int ifunc_index(Directive d, int type) { gmx_fatal(FARGS, "Invalid pairs type %d", type); } - case Directive::d_pairs_nb: - return F_LJC_PAIRS_NB; + case Directive::d_pairs_nb: return F_LJC_PAIRS_NB; case Directive::d_dihedrals: case Directive::d_dihedraltypes: switch (type) { - case 1: - return F_PDIHS; - case 2: - return F_IDIHS; - case 3: - return F_RBDIHS; - case 4: - return F_PIDIHS; - case 5: - return F_FOURDIHS; - case 8: - return F_TABDIHS; + case 1: return F_PDIHS; + case 2: return F_IDIHS; + case 3: return F_RBDIHS; + case 4: return F_PIDIHS; + case 5: return F_FOURDIHS; + case 8: return F_TABDIHS; case 9: return F_PDIHS; /* proper dihedrals where we allow multiple terms over single bond */ - case 10: - return F_RESTRDIHS; - case 11: - return F_CBTDIHS; - default: - gmx_fatal(FARGS, "Invalid dihedral type %d", type); + case 10: return F_RESTRDIHS; + case 11: return F_CBTDIHS; + default: gmx_fatal(FARGS, "Invalid dihedral type %d", type); } case Directive::d_cmaptypes: - case Directive::d_cmap: - return F_CMAP; + case Directive::d_cmap: return F_CMAP; case Directive::d_nonbond_params: if (type == 1) @@ -209,106 +144,76 @@ int ifunc_index(Directive d, int type) case Directive::d_vsites2: switch (type) { - case 1: - return F_VSITE2; - case 2: - return F_VSITE2FD; - default: - gmx_fatal(FARGS, "Invalid vsites2 type %d", type); + case 1: return F_VSITE2; + case 2: return F_VSITE2FD; + default: gmx_fatal(FARGS, "Invalid vsites2 type %d", type); } case Directive::d_vsites3: switch (type) { - case 1: - return F_VSITE3; - case 2: - return F_VSITE3FD; - case 3: - return F_VSITE3FAD; - case 4: - return F_VSITE3OUT; - default: - gmx_fatal(FARGS, "Invalid vsites3 type %d", type); + case 1: return F_VSITE3; + case 2: return F_VSITE3FD; + case 3: return F_VSITE3FAD; + case 4: return F_VSITE3OUT; + default: gmx_fatal(FARGS, "Invalid vsites3 type %d", type); } case Directive::d_vsites4: switch (type) { - case 1: - return F_VSITE4FD; - case 2: - return F_VSITE4FDN; - default: - gmx_fatal(FARGS, "Invalid vsites4 type %d", type); + case 1: return F_VSITE4FD; + case 2: return F_VSITE4FDN; + default: gmx_fatal(FARGS, "Invalid vsites4 type %d", type); } - case Directive::d_vsitesn: - return F_VSITEN; + case Directive::d_vsitesn: return F_VSITEN; case Directive::d_constraints: case Directive::d_constrainttypes: switch (type) { - case 1: - return F_CONSTR; - case 2: - return F_CONSTRNC; - default: - gmx_fatal(FARGS, "Invalid constraints type %d", type); + case 1: return F_CONSTR; + case 2: return F_CONSTRNC; + default: gmx_fatal(FARGS, "Invalid constraints type %d", type); } - case Directive::d_settles: - return F_SETTLE; + case Directive::d_settles: return F_SETTLE; case Directive::d_position_restraints: switch (type) { - case 1: - return F_POSRES; - case 2: - return F_FBPOSRES; - default: - gmx_fatal(FARGS, "Invalid position restraint type %d", type); + case 1: return F_POSRES; + case 2: return F_FBPOSRES; + default: gmx_fatal(FARGS, "Invalid position restraint type %d", type); } case Directive::d_polarization: switch (type) { - case 1: - return F_POLARIZATION; - case 2: - return F_ANHARM_POL; - default: - gmx_fatal(FARGS, "Invalid polarization type %d", type); + case 1: return F_POLARIZATION; + case 2: return F_ANHARM_POL; + default: gmx_fatal(FARGS, "Invalid polarization type %d", type); } - case Directive::d_thole_polarization: - return F_THOLE_POL; - case Directive::d_water_polarization: - return F_WATER_POL; - case Directive::d_angle_restraints: - return F_ANGRES; - case Directive::d_angle_restraints_z: - return F_ANGRESZ; - case Directive::d_distance_restraints: - return F_DISRES; - case Directive::d_orientation_restraints: - return F_ORIRES; - case Directive::d_dihedral_restraints: - return F_DIHRES; + case Directive::d_thole_polarization: return F_THOLE_POL; + case Directive::d_water_polarization: return F_WATER_POL; + case Directive::d_angle_restraints: return F_ANGRES; + case Directive::d_angle_restraints_z: return F_ANGRESZ; + case Directive::d_distance_restraints: return F_DISRES; + case Directive::d_orientation_restraints: return F_ORIRES; + case Directive::d_dihedral_restraints: return F_DIHRES; default: - gmx_fatal(FARGS, "invalid directive %s in ifunc_index (%s:%d)", - dir2str(d), __FILE__, __LINE__); + gmx_fatal(FARGS, "invalid directive %s in ifunc_index (%s:%d)", dir2str(d), __FILE__, __LINE__); } } -const char *dir2str (Directive d) +const char* dir2str(Directive d) { int index = static_cast(d); return directive_names[index]; } -Directive str2dir (char *dstr) +Directive str2dir(char* dstr) { char buf[STRLEN], *ptr; /* Hack to be able to read old topologies */ if (gmx_strncasecmp_min(dstr, "dummies", 7) == 0) { - sprintf(buf, "virtual_sites%s", dstr+7); + sprintf(buf, "virtual_sites%s", dstr + 7); ptr = buf; } else @@ -327,9 +232,9 @@ Directive str2dir (char *dstr) return Directive::d_invalid; } -static gmx::EnumerationArray necessary = {{ nullptr }}; +static gmx::EnumerationArray necessary = { { nullptr } }; -static void set_nec(Directive **n, ...) +static void set_nec(Directive** n, ...) /* Must always have at least one extra argument */ { va_list ap; @@ -341,13 +246,12 @@ static void set_nec(Directive **n, ...) { d = static_cast(va_arg(ap, int)); srenew(*n, ++ind); - (*n)[ind-1] = d; - } - while (d != Directive::d_none); + (*n)[ind - 1] = d; + } while (d != Directive::d_none); va_end(ap); } -void DS_Init(DirStack **DS) +void DS_Init(DirStack** DS) { if (necessary[0] == nullptr) { @@ -366,8 +270,10 @@ void DS_Init(DirStack **DS) // be in the same place that was valid in old versions (ie. child // directive of [atomtypes]) but any relevant case will // satisfy that. - set_nec(&(necessary[Directive::d_implicit_genborn_params]), Directive::d_atomtypes, Directive::d_none); - set_nec(&(necessary[Directive::d_implicit_surface_params]), Directive::d_atomtypes, Directive::d_none); + set_nec(&(necessary[Directive::d_implicit_genborn_params]), Directive::d_atomtypes, + Directive::d_none); + set_nec(&(necessary[Directive::d_implicit_surface_params]), Directive::d_atomtypes, + Directive::d_none); set_nec(&(necessary[Directive::d_cmaptypes]), Directive::d_atomtypes, Directive::d_none); set_nec(&(necessary[Directive::d_moleculetype]), Directive::d_atomtypes, Directive::d_none); set_nec(&(necessary[Directive::d_atoms]), Directive::d_moleculetype, Directive::d_none); @@ -376,7 +282,8 @@ void DS_Init(DirStack **DS) set_nec(&(necessary[Directive::d_vsites4]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_vsitesn]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_bonds]), Directive::d_atoms, Directive::d_none); - set_nec(&(necessary[Directive::d_exclusions]), Directive::d_bonds, Directive::d_constraints, Directive::d_settles, Directive::d_none); + set_nec(&(necessary[Directive::d_exclusions]), Directive::d_bonds, Directive::d_constraints, + Directive::d_settles, Directive::d_none); set_nec(&(necessary[Directive::d_pairs]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_pairs_nb]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_angles]), Directive::d_atoms, Directive::d_none); @@ -395,27 +302,27 @@ void DS_Init(DirStack **DS) set_nec(&(necessary[Directive::d_orientation_restraints]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_dihedral_restraints]), Directive::d_atoms, Directive::d_none); set_nec(&(necessary[Directive::d_cmap]), Directive::d_atoms, Directive::d_none); - set_nec(&(necessary[Directive::d_intermolecular_interactions]), Directive::d_molecules, Directive::d_none); + set_nec(&(necessary[Directive::d_intermolecular_interactions]), Directive::d_molecules, + Directive::d_none); } *DS = nullptr; - } -void DS_Done (DirStack **DS) +void DS_Done(DirStack** DS) { - DirStack *D; + DirStack* D; while (*DS != nullptr) { D = *DS; *DS = (*DS)->prev; - sfree (D); + sfree(D); } } -void DS_Push (DirStack **DS, Directive d) +void DS_Push(DirStack** DS, Directive d) { - DirStack *D; + DirStack* D; snew(D, 1); D->d = d; @@ -423,9 +330,9 @@ void DS_Push (DirStack **DS, Directive d) *DS = D; } -int DS_Search(DirStack *DS, Directive d) +int DS_Search(DirStack* DS, Directive d) { - DirStack *D; + DirStack* D; D = DS; while ((D != nullptr) && (D->d != d)) @@ -436,7 +343,7 @@ int DS_Search(DirStack *DS, Directive d) return static_cast(D != nullptr); } -int DS_Check_Order(DirStack *DS, Directive d) +int DS_Check_Order(DirStack* DS, Directive d) { Directive d0; int i = 0; @@ -461,8 +368,7 @@ int DS_Check_Order(DirStack *DS, Directive d) { return TRUE; } - } - while (d0 != Directive::d_none); + } while (d0 != Directive::d_none); } return FALSE; } diff --git a/src/gromacs/gmxpreprocess/topdirs.h b/src/gromacs/gmxpreprocess/topdirs.h index e869439aca..075d989f6b 100644 --- a/src/gromacs/gmxpreprocess/topdirs.h +++ b/src/gromacs/gmxpreprocess/topdirs.h @@ -87,24 +87,24 @@ enum class Directive : int struct DirStack { - Directive d; - DirStack *prev; + Directive d; + DirStack* prev; }; int ifunc_index(Directive d, int type); -const char *dir2str (Directive d); +const char* dir2str(Directive d); -Directive str2dir (char *dstr); +Directive str2dir(char* dstr); -void DS_Init (DirStack **DS); +void DS_Init(DirStack** DS); -void DS_Done (DirStack **DS); +void DS_Done(DirStack** DS); -void DS_Push (DirStack **DS, Directive d); +void DS_Push(DirStack** DS, Directive d); -int DS_Search (DirStack *DS, Directive d); +int DS_Search(DirStack* DS, Directive d); -int DS_Check_Order (DirStack *DS, Directive d); +int DS_Check_Order(DirStack* DS, Directive d); #endif diff --git a/src/gromacs/gmxpreprocess/topio.cpp b/src/gromacs/gmxpreprocess/topio.cpp index 65e3297e93..7058eb623b 100644 --- a/src/gromacs/gmxpreprocess/topio.cpp +++ b/src/gromacs/gmxpreprocess/topio.cpp @@ -82,20 +82,21 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -#define OPENDIR '[' /* starting sign for directive */ -#define CLOSEDIR ']' /* ending sign for directive */ +#define OPENDIR '[' /* starting sign for directive */ +#define CLOSEDIR ']' /* ending sign for directive */ -static void gen_pairs(const InteractionsOfType &nbs, InteractionsOfType *pairs, real fudge, int comb) +static void gen_pairs(const InteractionsOfType& nbs, InteractionsOfType* pairs, real fudge, int comb) { - real scaling; - int ntp = nbs.size(); - int nnn = static_cast(std::sqrt(static_cast(ntp))); - GMX_ASSERT(nnn * nnn == ntp, "Number of pairs of generated non-bonded parameters should be a perfect square"); - int nrfp = NRFP(F_LJ); - int nrfpA = interaction_function[F_LJ14].nrfpA; - int nrfpB = interaction_function[F_LJ14].nrfpB; - - if ((nrfp != nrfpA) || (nrfpA != nrfpB)) + real scaling; + int ntp = nbs.size(); + int nnn = static_cast(std::sqrt(static_cast(ntp))); + GMX_ASSERT(nnn * nnn == ntp, + "Number of pairs of generated non-bonded parameters should be a perfect square"); + int nrfp = NRFP(F_LJ); + int nrfpA = interaction_function[F_LJ14].nrfpA; + int nrfpB = interaction_function[F_LJ14].nrfpB; + + if ((nrfp != nrfpA) || (nrfpA != nrfpB)) { gmx_incons("Number of force parameters in gen_pairs wrong"); } @@ -104,21 +105,22 @@ static void gen_pairs(const InteractionsOfType &nbs, InteractionsOfType *pairs, pairs->interactionTypes.clear(); int i = 0; std::array atomNumbers; - std::array forceParam = {NOTSET}; - for (const auto &type : nbs.interactionTypes) + std::array forceParam = { NOTSET }; + for (const auto& type : nbs.interactionTypes) { /* Copy type.atoms */ - atomNumbers = {i / nnn, i % nnn }; + atomNumbers = { i / nnn, i % nnn }; /* Copy normal and FEP parameters and multiply by fudge factor */ gmx::ArrayRef existingParam = type.forceParam(); - GMX_RELEASE_ASSERT(2*nrfp <= MAXFORCEPARAM, "Can't have more parameters than half of maximum p arameter number"); + GMX_RELEASE_ASSERT(2 * nrfp <= MAXFORCEPARAM, + "Can't have more parameters than half of maximum p arameter number"); for (int j = 0; j < nrfp; j++) { /* If we are using sigma/epsilon values, only the epsilon values * should be scaled, but not sigma. * The sigma values have even indices 0,2, etc. */ - if ((comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS) && (j%2 == 0)) + if ((comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS) && (j % 2 == 0)) { scaling = 1.0; } @@ -127,30 +129,30 @@ static void gen_pairs(const InteractionsOfType &nbs, InteractionsOfType *pairs, scaling = fudge; } - forceParam[j] = scaling*existingParam[j]; - forceParam[nrfp+j] = scaling*existingParam[j]; + forceParam[j] = scaling * existingParam[j]; + forceParam[nrfp + j] = scaling * existingParam[j]; } pairs->interactionTypes.emplace_back(InteractionOfType(atomNumbers, forceParam)); i++; } } -double check_mol(const gmx_mtop_t *mtop, warninp *wi) +double check_mol(const gmx_mtop_t* mtop, warninp* wi) { - char buf[256]; - int i, ri, pt; - double q; - real m, mB; + char buf[256]; + int i, ri, pt; + double q; + real m, mB; /* Check mass and charge */ q = 0.0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const t_atoms *atoms = &mtop->moltype[molb.type].atoms; + const t_atoms* atoms = &mtop->moltype[molb.type].atoms; for (i = 0; (i < atoms->nr); i++) { - q += molb.nmol*atoms->atom[i].q; + q += molb.nmol * atoms->atom[i].q; m = atoms->atom[i].m; mB = atoms->atom[i].mB; pt = atoms->atom[i].ptype; @@ -161,22 +163,17 @@ double check_mol(const gmx_mtop_t *mtop, warninp *wi) { ri = atoms->atom[i].resind; sprintf(buf, "atom %s (Res %s-%d) has mass %g (state A) / %g (state B)\n", - *(atoms->atomname[i]), - *(atoms->resinfo[ri].name), - atoms->resinfo[ri].nr, - m, mB); + *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m, mB); warning_error(wi, buf); } - else - if (((m != 0) || (mB != 0)) && (pt == eptVSite)) + else if (((m != 0) || (mB != 0)) && (pt == eptVSite)) { ri = atoms->atom[i].resind; - sprintf(buf, "virtual site %s (Res %s-%d) has non-zero mass %g (state A) / %g (state B)\n" + sprintf(buf, + "virtual site %s (Res %s-%d) has non-zero mass %g (state A) / %g (state " + "B)\n" " Check your topology.\n", - *(atoms->atomname[i]), - *(atoms->resinfo[ri].name), - atoms->resinfo[ri].nr, - m, mB); + *(atoms->atomname[i]), *(atoms->resinfo[ri].name), atoms->resinfo[ri].nr, m, mB); warning_error(wi, buf); /* The following statements make LINCS break! */ /* atoms->atom[i].m=0; */ @@ -208,7 +205,7 @@ static double roundedMoleculeCharge(double qMol, double sumAbsQ) * have a near half-bit rounding error with the same sign. */ double tolAbs = 1e-6; - double tol = std::max(tolAbs, 0.5*GMX_REAL_EPS*sumAbsQ); + double tol = std::max(tolAbs, 0.5 * GMX_REAL_EPS * sumAbsQ); double qRound = std::round(qMol); if (std::abs(qMol - qRound) <= tol) { @@ -220,8 +217,7 @@ static double roundedMoleculeCharge(double qMol, double sumAbsQ) } } -static void sum_q(const t_atoms *atoms, int numMols, - double *qTotA, double *qTotB) +static void sum_q(const t_atoms* atoms, int numMols, double* qTotA, double* qTotB) { /* sum charge */ double qmolA = 0; @@ -230,23 +226,22 @@ static void sum_q(const t_atoms *atoms, int numMols, double sumAbsQB = 0; for (int i = 0; i < atoms->nr; i++) { - qmolA += atoms->atom[i].q; - qmolB += atoms->atom[i].qB; + qmolA += atoms->atom[i].q; + qmolB += atoms->atom[i].qB; sumAbsQA += std::abs(atoms->atom[i].q); sumAbsQB += std::abs(atoms->atom[i].qB); } - *qTotA += numMols*roundedMoleculeCharge(qmolA, sumAbsQA); - *qTotB += numMols*roundedMoleculeCharge(qmolB, sumAbsQB); + *qTotA += numMols * roundedMoleculeCharge(qmolA, sumAbsQA); + *qTotB += numMols * roundedMoleculeCharge(qmolB, sumAbsQB); } -static void get_nbparm(char *nb_str, char *comb_str, int *nb, int *comb, - warninp *wi) +static void get_nbparm(char* nb_str, char* comb_str, int* nb, int* comb, warninp* wi) { int i; char warn_buf[STRLEN]; - *nb = -1; + *nb = -1; for (i = 1; (i < eNBF_NR); i++) { if (gmx_strcasecmp(nb_str, enbf_names[i]) == 0) @@ -260,8 +255,7 @@ static void get_nbparm(char *nb_str, char *comb_str, int *nb, int *comb, } if ((*nb < 1) || (*nb >= eNBF_NR)) { - sprintf(warn_buf, "Invalid nonbond function selector '%s' using %s", - nb_str, enbf_names[1]); + sprintf(warn_buf, "Invalid nonbond function selector '%s' using %s", nb_str, enbf_names[1]); warning_error(wi, warn_buf); *nb = 1; } @@ -279,25 +273,23 @@ static void get_nbparm(char *nb_str, char *comb_str, int *nb, int *comb, } if ((*comb < 1) || (*comb >= eCOMB_NR)) { - sprintf(warn_buf, "Invalid combination rule selector '%s' using %s", - comb_str, ecomb_names[1]); + sprintf(warn_buf, "Invalid combination rule selector '%s' using %s", comb_str, ecomb_names[1]); warning_error(wi, warn_buf); *comb = 1; } } -static char ** cpp_opts(const char *define, const char *include, - warninp *wi) +static char** cpp_opts(const char* define, const char* include, warninp* wi) { int n, len; int ncppopts = 0; - const char *cppadds[2]; - char **cppopts = nullptr; - const char *option[2] = { "-D", "-I" }; - const char *nopt[2] = { "define", "include" }; - const char *ptr; - const char *rptr; - char *buf; + const char* cppadds[2]; + char** cppopts = nullptr; + const char* option[2] = { "-D", "-I" }; + const char* nopt[2] = { "define", "include" }; + const char* ptr; + const char* rptr; + char* buf; char warn_buf[STRLEN]; cppadds[0] = define; @@ -321,7 +313,7 @@ static char ** cpp_opts(const char *define, const char *include, len = (rptr - ptr); if (len > 2) { - snew(buf, (len+1)); + snew(buf, (len + 1)); strncpy(buf, ptr, len); if (strstr(ptr, option[n]) != ptr) { @@ -332,7 +324,7 @@ static char ** cpp_opts(const char *define, const char *include, else { srenew(cppopts, ++ncppopts); - cppopts[ncppopts-1] = gmx_strdup(buf); + cppopts[ncppopts - 1] = gmx_strdup(buf); } sfree(buf); ptr = rptr; @@ -341,7 +333,7 @@ static char ** cpp_opts(const char *define, const char *include, } } srenew(cppopts, ++ncppopts); - cppopts[ncppopts-1] = nullptr; + cppopts[ncppopts - 1] = nullptr; return cppopts; } @@ -349,16 +341,16 @@ static char ** cpp_opts(const char *define, const char *include, static void make_atoms_sys(gmx::ArrayRef molblock, gmx::ArrayRef molinfo, - t_atoms *atoms) + t_atoms* atoms) { atoms->nr = 0; atoms->atom = nullptr; - for (const gmx_molblock_t &molb : molblock) + for (const gmx_molblock_t& molb : molblock) { - const t_atoms &mol_atoms = molinfo[molb.type].atoms; + const t_atoms& mol_atoms = molinfo[molb.type].atoms; - srenew(atoms->atom, atoms->nr + molb.nmol*mol_atoms.nr); + srenew(atoms->atom, atoms->nr + molb.nmol * mol_atoms.nr); for (int m = 0; m < molb.nmol; m++) { @@ -371,50 +363,52 @@ static void make_atoms_sys(gmx::ArrayRef molblock, } -static char **read_topol(const char *infile, const char *outfile, - const char *define, const char *include, - t_symtab *symtab, - PreprocessingAtomTypes *atypes, - std::vector *molinfo, - std::unique_ptr *intermolecular_interactions, - gmx::ArrayRef interactions, - int *combination_rule, - double *reppow, - t_gromppopts *opts, - real *fudgeQQ, - std::vector *molblock, - bool *ffParametrizedWithHBondConstraints, - bool bFEP, - bool bZero, - bool usingFullRangeElectrostatics, - warninp *wi) +static char** read_topol(const char* infile, + const char* outfile, + const char* define, + const char* include, + t_symtab* symtab, + PreprocessingAtomTypes* atypes, + std::vector* molinfo, + std::unique_ptr* intermolecular_interactions, + gmx::ArrayRef interactions, + int* combination_rule, + double* reppow, + t_gromppopts* opts, + real* fudgeQQ, + std::vector* molblock, + bool* ffParametrizedWithHBondConstraints, + bool bFEP, + bool bZero, + bool usingFullRangeElectrostatics, + warninp* wi) { - FILE *out; - int sl, nb_funct; - char *pline = nullptr, **title = nullptr; - char line[STRLEN], errbuf[256], comb_str[256], nb_str[256]; - char genpairs[32]; - char *dirstr, *dummy2; - int nrcopies, nscan, ncombs, ncopy; - double fLJ, fQQ, fPOW; - MoleculeInformation *mi0 = nullptr; - DirStack *DS; - Directive d, newd; - t_nbparam **nbparam, **pair; - real fudgeLJ = -1; /* Multiplication factor to generate 1-4 from LJ */ - bool bReadDefaults, bReadMolType, bGenPairs, bWarn_copy_A_B; - double qt = 0, qBt = 0; /* total charge */ - int dcatt = -1, nmol_couple; + FILE* out; + int sl, nb_funct; + char * pline = nullptr, **title = nullptr; + char line[STRLEN], errbuf[256], comb_str[256], nb_str[256]; + char genpairs[32]; + char * dirstr, *dummy2; + int nrcopies, nscan, ncombs, ncopy; + double fLJ, fQQ, fPOW; + MoleculeInformation* mi0 = nullptr; + DirStack* DS; + Directive d, newd; + t_nbparam ** nbparam, **pair; + real fudgeLJ = -1; /* Multiplication factor to generate 1-4 from LJ */ + bool bReadDefaults, bReadMolType, bGenPairs, bWarn_copy_A_B; + double qt = 0, qBt = 0; /* total charge */ + int dcatt = -1, nmol_couple; /* File handling variables */ - int status; - bool done; - gmx_cpp_t handle; - char *tmp_line = nullptr; - char warn_buf[STRLEN]; - const char *floating_point_arithmetic_tip = - "Total charge should normally be an integer. See\n" - "http://www.gromacs.org/Documentation/Floating_Point_Arithmetic\n" - "for discussion on how close it should be to an integer.\n"; + int status; + bool done; + gmx_cpp_t handle; + char* tmp_line = nullptr; + char warn_buf[STRLEN]; + const char* floating_point_arithmetic_tip = + "Total charge should normally be an integer. See\n" + "http://www.gromacs.org/Documentation/Floating_Point_Arithmetic\n" + "for discussion on how close it should be to an integer.\n"; /* We need to open the output file before opening the input file, * because cpp_open_file can change the current working directory. */ @@ -429,21 +423,21 @@ static char **read_topol(const char *infile, const char *outfile, /* open input file */ auto cpp_opts_return = cpp_opts(define, include, wi); - status = cpp_open_file(infile, &handle, cpp_opts_return); + status = cpp_open_file(infile, &handle, cpp_opts_return); if (status != 0) { gmx_fatal(FARGS, "%s", cpp_error(&handle, status)); } /* some local variables */ - DS_Init(&DS); /* directive stack */ - d = Directive::d_invalid; /* first thing should be a directive */ - nbparam = nullptr; /* The temporary non-bonded matrix */ - pair = nullptr; /* The temporary pair interaction matrix */ - std::vector < std::vector < gmx::ExclusionBlock>> exclusionBlocks; - nb_funct = F_LJ; + DS_Init(&DS); /* directive stack */ + d = Directive::d_invalid; /* first thing should be a directive */ + nbparam = nullptr; /* The temporary non-bonded matrix */ + pair = nullptr; /* The temporary pair interaction matrix */ + std::vector> exclusionBlocks; + nb_funct = F_LJ; - *reppow = 12.0; /* Default value for repulsion power */ + *reppow = 12.0; /* Default value for repulsion power */ /* Init the number of CMAP torsion angles and grid spacing */ interactions[F_CMAP].cmakeGridSpacing = 0; @@ -479,9 +473,9 @@ static char **read_topol(const char *infile, const char *outfile, /* Strip trailing '\' from pline, if it exists */ sl = strlen(pline); - if ((sl > 0) && (pline[sl-1] == CONTINUE)) + if ((sl > 0) && (pline[sl - 1] == CONTINUE)) { - pline[sl-1] = ' '; + pline[sl - 1] = ' '; } /* build one long line from several fragments - necessary for CMAP */ @@ -496,9 +490,9 @@ static char **read_topol(const char *infile, const char *outfile, tmp_line = gmx_strdup(line); sl = strlen(tmp_line); - if ((sl > 0) && (tmp_line[sl-1] == CONTINUE)) + if ((sl > 0) && (tmp_line[sl - 1] == CONTINUE)) { - tmp_line[sl-1] = ' '; + tmp_line[sl - 1] = ' '; } done = (status == eCPP_EOF); @@ -514,14 +508,14 @@ static char **read_topol(const char *infile, const char *outfile, } } - srenew(pline, strlen(pline)+strlen(tmp_line)+1); + srenew(pline, strlen(pline) + strlen(tmp_line) + 1); strcat(pline, tmp_line); sfree(tmp_line); } /* skip trailing and leading spaces and comment text */ - strip_comment (pline); - trim (pline); + strip_comment(pline); + trim(pline); /* if there is something left... */ if (static_cast(strlen(pline)) > 0) @@ -532,12 +526,12 @@ static char **read_topol(const char *infile, const char *outfile, * without the brackets into dirstr, then * skip spaces and tabs on either side of directive */ - dirstr = gmx_strdup((pline+1)); - if ((dummy2 = strchr (dirstr, CLOSEDIR)) != nullptr) + dirstr = gmx_strdup((pline + 1)); + if ((dummy2 = strchr(dirstr, CLOSEDIR)) != nullptr) { (*dummy2) = 0; } - trim (dirstr); + trim(dirstr); if ((newd = str2dir(dirstr)) == Directive::d_invalid) { @@ -547,9 +541,9 @@ static char **read_topol(const char *infile, const char *outfile, else { /* Directive found */ - if (DS_Check_Order (DS, newd)) + if (DS_Check_Order(DS, newd)) { - DS_Push (&DS, newd); + DS_Push(&DS, newd); d = newd; } else @@ -569,11 +563,10 @@ static char **read_topol(const char *infile, const char *outfile, * to process the intermolecular interactions * by making a "molecule" of the size of the system. */ - *intermolecular_interactions = std::make_unique( ); - mi0 = intermolecular_interactions->get(); + *intermolecular_interactions = std::make_unique(); + mi0 = intermolecular_interactions->get(); mi0->initMolInfo(); - make_atoms_sys(*molblock, *molinfo, - &mi0->atoms); + make_atoms_sys(*molblock, *molinfo, &mi0->atoms); } } } @@ -594,8 +587,8 @@ static char **read_topol(const char *infile, const char *outfile, cpp_error(&handle, eCPP_SYNTAX)); } bReadDefaults = TRUE; - nscan = sscanf(pline, "%s%s%s%lf%lf%lf", - nb_str, comb_str, genpairs, &fLJ, &fQQ, &fPOW); + nscan = sscanf(pline, "%s%s%s%lf%lf%lf", nb_str, comb_str, genpairs, + &fLJ, &fQQ, &fPOW); if (nscan < 2) { too_few(wi); @@ -612,28 +605,30 @@ static char **read_topol(const char *infile, const char *outfile, bGenPairs = (gmx::equalCaseInsensitive(genpairs, "Y", 1)); if (nb_funct != eNBF_LJ && bGenPairs) { - gmx_fatal(FARGS, "Generating pair parameters is only supported with LJ non-bonded interactions"); + gmx_fatal(FARGS, + "Generating pair parameters is only supported " + "with LJ non-bonded interactions"); } } if (nscan >= 4) { - fudgeLJ = fLJ; + fudgeLJ = fLJ; } if (nscan >= 5) { - *fudgeQQ = fQQ; + *fudgeQQ = fQQ; } if (nscan >= 6) { - *reppow = fPOW; + *reppow = fPOW; } } nb_funct = ifunc_index(Directive::d_nonbond_params, nb_funct); break; case Directive::d_atomtypes: - push_at(symtab, atypes, &bondAtomType, pline, nb_funct, - &nbparam, bGenPairs ? &pair : nullptr, wi); + push_at(symtab, atypes, &bondAtomType, pline, nb_funct, &nbparam, + bGenPairs ? &pair : nullptr, wi); break; case Directive::d_bondtypes: @@ -685,28 +680,32 @@ static char **read_topol(const char *infile, const char *outfile, if (!bReadMolType) { int ntype; - if (opts->couple_moltype != nullptr && - (opts->couple_lam0 == ecouplamNONE || - opts->couple_lam0 == ecouplamQ || - opts->couple_lam1 == ecouplamNONE || - opts->couple_lam1 == ecouplamQ)) + if (opts->couple_moltype != nullptr + && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam0 == ecouplamQ + || opts->couple_lam1 == ecouplamNONE + || opts->couple_lam1 == ecouplamQ)) { - dcatt = add_atomtype_decoupled(symtab, atypes, - &nbparam, bGenPairs ? &pair : nullptr); + dcatt = add_atomtype_decoupled(symtab, atypes, &nbparam, + bGenPairs ? &pair : nullptr); } ntype = atypes->size(); - ncombs = (ntype*(ntype+1))/2; - generate_nbparams(*combination_rule, nb_funct, &(interactions[nb_funct]), atypes, wi); - ncopy = copy_nbparams(nbparam, nb_funct, &(interactions[nb_funct]), - ntype); - fprintf(stderr, "Generated %d of the %d non-bonded parameter combinations\n", ncombs-ncopy, ncombs); + ncombs = (ntype * (ntype + 1)) / 2; + generate_nbparams(*combination_rule, nb_funct, + &(interactions[nb_funct]), atypes, wi); + ncopy = copy_nbparams(nbparam, nb_funct, &(interactions[nb_funct]), ntype); + fprintf(stderr, + "Generated %d of the %d non-bonded parameter " + "combinations\n", + ncombs - ncopy, ncombs); free_nbparam(nbparam, ntype); if (bGenPairs) { - gen_pairs((interactions[nb_funct]), &(interactions[F_LJ14]), fudgeLJ, *combination_rule); - ncopy = copy_nbparams(pair, nb_funct, &(interactions[F_LJ14]), - ntype); - fprintf(stderr, "Generated %d of the %d 1-4 parameter combinations\n", ncombs-ncopy, ncombs); + gen_pairs((interactions[nb_funct]), &(interactions[F_LJ14]), + fudgeLJ, *combination_rule); + ncopy = copy_nbparams(pair, nb_funct, &(interactions[F_LJ14]), ntype); + fprintf(stderr, + "Generated %d of the %d 1-4 parameter combinations\n", + ncombs - ncopy, ncombs); free_nbparam(pair, ntype); } /* Copy GBSA parameters to atomtype array? */ @@ -716,12 +715,12 @@ static char **read_topol(const char *infile, const char *outfile, push_molt(symtab, molinfo, pline, wi); exclusionBlocks.emplace_back(); - mi0 = &molinfo->back(); - mi0->atoms.haveMass = TRUE; - mi0->atoms.haveCharge = TRUE; - mi0->atoms.haveType = TRUE; - mi0->atoms.haveBState = TRUE; - mi0->atoms.havePdbInfo = FALSE; + mi0 = &molinfo->back(); + mi0->atoms.haveMass = TRUE; + mi0->atoms.haveCharge = TRUE; + mi0->atoms.haveType = TRUE; + mi0->atoms.haveBState = TRUE; + mi0->atoms.havePdbInfo = FALSE; break; } case Directive::d_atoms: @@ -729,14 +728,18 @@ static char **read_topol(const char *infile, const char *outfile, break; case Directive::d_pairs: - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); - push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, pline, FALSE, - bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi); + GMX_RELEASE_ASSERT( + mi0, + "Need to have a valid MoleculeInformation object to work on"); + push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, + pline, FALSE, bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi); break; case Directive::d_pairs_nb: - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); - push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, pline, FALSE, - FALSE, 1.0, bZero, &bWarn_copy_A_B, wi); + GMX_RELEASE_ASSERT( + mi0, + "Need to have a valid MoleculeInformation object to work on"); + push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, + pline, FALSE, FALSE, 1.0, bZero, &bWarn_copy_A_B, wi); break; case Directive::d_vsites2: @@ -756,24 +759,34 @@ static char **read_topol(const char *infile, const char *outfile, case Directive::d_polarization: case Directive::d_water_polarization: case Directive::d_thole_polarization: - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); - push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, pline, TRUE, - bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi); + GMX_RELEASE_ASSERT( + mi0, + "Need to have a valid MoleculeInformation object to work on"); + push_bond(d, interactions, mi0->interactions, &(mi0->atoms), atypes, + pline, TRUE, bGenPairs, *fudgeQQ, bZero, &bWarn_copy_A_B, wi); break; case Directive::d_cmap: - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); + GMX_RELEASE_ASSERT( + mi0, + "Need to have a valid MoleculeInformation object to work on"); push_cmap(d, interactions, mi0->interactions, &(mi0->atoms), atypes, pline, wi); break; case Directive::d_vsitesn: - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); + GMX_RELEASE_ASSERT( + mi0, + "Need to have a valid MoleculeInformation object to work on"); push_vsitesn(d, mi0->interactions, &(mi0->atoms), pline, wi); break; case Directive::d_exclusions: - GMX_ASSERT(!exclusionBlocks.empty(), "exclusionBlocks must always be allocated so exclusions can be processed"); + GMX_ASSERT(!exclusionBlocks.empty(), + "exclusionBlocks must always be allocated so exclusions can " + "be processed"); if (exclusionBlocks.back().empty()) { - GMX_RELEASE_ASSERT(mi0, "Need to have a valid MoleculeInformation object to work on"); + GMX_RELEASE_ASSERT(mi0, + "Need to have a valid MoleculeInformation " + "object to work on"); exclusionBlocks.back().resize(mi0->atoms.nr); } push_excl(pline, exclusionBlocks.back(), wi); @@ -784,8 +797,8 @@ static char **read_topol(const char *infile, const char *outfile, break; case Directive::d_molecules: { - int whichmol; - bool bCouple; + int whichmol; + bool bCouple; push_mol(*molinfo, pline, &whichmol, &nrcopies, wi); mi0 = &((*molinfo)[whichmol]); @@ -793,9 +806,9 @@ static char **read_topol(const char *infile, const char *outfile, molblock->back().type = whichmol; molblock->back().nmol = nrcopies; - bCouple = (opts->couple_moltype != nullptr && - (gmx_strcasecmp("system", opts->couple_moltype) == 0 || - strcmp(*(mi0->name), opts->couple_moltype) == 0)); + bCouple = (opts->couple_moltype != nullptr + && (gmx_strcasecmp("system", opts->couple_moltype) == 0 + || strcmp(*(mi0->name), opts->couple_moltype) == 0)); if (bCouple) { nmol_couple += nrcopies; @@ -803,27 +816,21 @@ static char **read_topol(const char *infile, const char *outfile, if (mi0->atoms.nr == 0) { - gmx_fatal(FARGS, "Molecule type '%s' contains no atoms", - *mi0->name); + gmx_fatal(FARGS, "Molecule type '%s' contains no atoms", *mi0->name); } - fprintf(stderr, - "Excluding %d bonded neighbours molecule type '%s'\n", + fprintf(stderr, "Excluding %d bonded neighbours molecule type '%s'\n", mi0->nrexcl, *mi0->name); sum_q(&mi0->atoms, nrcopies, &qt, &qBt); if (!mi0->bProcessed) { - generate_excl(mi0->nrexcl, - mi0->atoms.nr, - mi0->interactions, - &(mi0->excls)); + generate_excl(mi0->nrexcl, mi0->atoms.nr, mi0->interactions, &(mi0->excls)); gmx::mergeExclusions(&(mi0->excls), exclusionBlocks[whichmol]); make_shake(mi0->interactions, &mi0->atoms, opts->nshake); if (bCouple) { - convert_moltype_couple(mi0, dcatt, *fudgeQQ, - opts->couple_lam0, opts->couple_lam1, - opts->bCoupleIntra, + convert_moltype_couple(mi0, dcatt, *fudgeQQ, opts->couple_lam0, + opts->couple_lam1, opts->bCoupleIntra, nb_funct, &(interactions[nb_funct]), wi); } stupid_fill_block(&mi0->mols, mi0->atoms.nr, TRUE); @@ -832,7 +839,7 @@ static char **read_topol(const char *infile, const char *outfile, break; } default: - fprintf (stderr, "case: %d\n", static_cast(d)); + fprintf(stderr, "case: %d\n", static_cast(d)); gmx_incons("unknown directive"); } } @@ -840,8 +847,7 @@ static char **read_topol(const char *infile, const char *outfile, sfree(pline); pline = nullptr; } - } - while (!done); + } while (!done); // Check that all strings defined with -D were used when processing topology std::string unusedDefineWarning = checkAndWarnForUnusedDefines(*handle); @@ -863,13 +869,9 @@ static char **read_topol(const char *infile, const char *outfile, * We should avoid hardcoded names, but this is hopefully only * needed temparorily for discouraging use of constraints=all-bonds. */ - const std::array ffDefines = { - "_FF_AMBER", - "_FF_CHARMM", - "_FF_OPLSAA" - }; - *ffParametrizedWithHBondConstraints = false; - for (const std::string &ffDefine : ffDefines) + const std::array ffDefines = { "_FF_AMBER", "_FF_CHARMM", "_FF_OPLSAA" }; + *ffParametrizedWithHBondConstraints = false; + for (const std::string& ffDefine : ffDefines) { if (cpp_find_define(&handle, ffDefine)) { @@ -894,11 +896,9 @@ static char **read_topol(const char *infile, const char *outfile, { if (nmol_couple == 0) { - gmx_fatal(FARGS, "Did not find any molecules of type '%s' for coupling", - opts->couple_moltype); + gmx_fatal(FARGS, "Did not find any molecules of type '%s' for coupling", opts->couple_moltype); } - fprintf(stderr, "Coupling %d copies of molecule type '%s'\n", - nmol_couple, opts->couple_moltype); + fprintf(stderr, "Coupling %d copies of molecule type '%s'\n", nmol_couple, opts->couple_moltype); } /* this is not very clean, but fixes core dump on empty system name */ @@ -914,16 +914,21 @@ static char **read_topol(const char *infile, const char *outfile, } if (fabs(qBt) > 1e-4 && !gmx_within_tol(qBt, qt, 1e-6)) { - sprintf(warn_buf, "State B has non-zero total charge: %.6f\n%s\n", qBt, floating_point_arithmetic_tip); + sprintf(warn_buf, "State B has non-zero total charge: %.6f\n%s\n", qBt, + floating_point_arithmetic_tip); warning_note(wi, warn_buf); } if (usingFullRangeElectrostatics && (fabs(qt) > 1e-4 || fabs(qBt) > 1e-4)) { - warning(wi, "You are using Ewald electrostatics in a system with net charge. This can lead to severe artifacts, such as ions moving into regions with low dielectric, due to the uniform background charge. We suggest to neutralize your system with counter ions, possibly in combination with a physiological salt concentration."); + warning(wi, + "You are using Ewald electrostatics in a system with net charge. This can lead to " + "severe artifacts, such as ions moving into regions with low dielectric, due to " + "the uniform background charge. We suggest to neutralize your system with counter " + "ions, possibly in combination with a physiological salt concentration."); please_cite(stdout, "Hub2014a"); } - DS_Done (&DS); + DS_Done(&DS); if (*intermolecular_interactions != nullptr) { @@ -933,27 +938,27 @@ static char **read_topol(const char *infile, const char *outfile, return title; } -char **do_top(bool bVerbose, - const char *topfile, - const char *topppfile, - t_gromppopts *opts, - bool bZero, - t_symtab *symtab, - gmx::ArrayRef interactions, - int *combination_rule, - double *repulsion_power, - real *fudgeQQ, - PreprocessingAtomTypes *atypes, - std::vector *molinfo, - std::unique_ptr *intermolecular_interactions, - const t_inputrec *ir, - std::vector *molblock, - bool *ffParametrizedWithHBondConstraints, - warninp *wi) +char** do_top(bool bVerbose, + const char* topfile, + const char* topppfile, + t_gromppopts* opts, + bool bZero, + t_symtab* symtab, + gmx::ArrayRef interactions, + int* combination_rule, + double* repulsion_power, + real* fudgeQQ, + PreprocessingAtomTypes* atypes, + std::vector* molinfo, + std::unique_ptr* intermolecular_interactions, + const t_inputrec* ir, + std::vector* molblock, + bool* ffParametrizedWithHBondConstraints, + warninp* wi) { /* Tmpfile might contain a long path */ - const char *tmpfile; - char **title; + const char* tmpfile; + char** title; if (topppfile) { @@ -968,19 +973,15 @@ char **do_top(bool bVerbose, { printf("processing topology...\n"); } - title = read_topol(topfile, tmpfile, opts->define, opts->include, - symtab, atypes, - molinfo, intermolecular_interactions, - interactions, combination_rule, repulsion_power, - opts, fudgeQQ, molblock, - ffParametrizedWithHBondConstraints, - ir->efep != efepNO, bZero, - EEL_FULL(ir->coulombtype), wi); - - if ((*combination_rule != eCOMB_GEOMETRIC) && - (ir->vdwtype == evdwUSER)) + title = read_topol(topfile, tmpfile, opts->define, opts->include, symtab, atypes, molinfo, + intermolecular_interactions, interactions, combination_rule, repulsion_power, + opts, fudgeQQ, molblock, ffParametrizedWithHBondConstraints, + ir->efep != efepNO, bZero, EEL_FULL(ir->coulombtype), wi); + + if ((*combination_rule != eCOMB_GEOMETRIC) && (ir->vdwtype == evdwUSER)) { - warning(wi, "Using sigma/epsilon based combination rules with" + warning(wi, + "Using sigma/epsilon based combination rules with" " user supplied potential function may produce unwanted" " results"); } @@ -1001,8 +1002,7 @@ char **do_top(bool bVerbose, * @param ir input record * @param qmmmMode QM/MM mode switch: original/MiMiC */ -static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *grpnr, - t_inputrec *ir, GmxQmmmMode qmmmMode) +static void generate_qmexcl_moltype(gmx_moltype_t* molt, const unsigned char* grpnr, t_inputrec* ir, GmxQmmmMode qmmmMode) { /* This routine expects molt->ilist to be of size F_NRE and ordered. */ @@ -1010,9 +1010,9 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr * these interactions should be handled by the QM subroutines and * not by the gromacs routines */ - int qm_max = 0, qm_nr = 0, link_nr = 0, link_max = 0; - int *qm_arr = nullptr, *link_arr = nullptr; - bool *bQMMM, *blink; + int qm_max = 0, qm_nr = 0, link_nr = 0, link_max = 0; + int * qm_arr = nullptr, *link_arr = nullptr; + bool *bQMMM, *blink; /* First we search and select the QM atoms in an qm_arr array that * we use to create the exclusions. @@ -1076,8 +1076,7 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr int ind_connbond = 0; if (molt->ilist[F_CONNBONDS].size() != 0) { - fprintf(stderr, "nr. of CONNBONDS present already: %d\n", - molt->ilist[F_CONNBONDS].size()/3); + fprintf(stderr, "nr. of CONNBONDS present already: %d\n", molt->ilist[F_CONNBONDS].size() / 3); ftype_connbond = molt->ilist[F_CONNBONDS].iatoms[0]; ind_connbond = molt->ilist[F_CONNBONDS].size(); } @@ -1086,8 +1085,7 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr */ for (int ftype = 0; ftype < F_NRE; ftype++) { - if (!(interaction_function[ftype].flags & IF_BOND) || - ftype == F_CONNBONDS) + if (!(interaction_function[ftype].flags & IF_BOND) || ftype == F_CONNBONDS) { continue; } @@ -1111,11 +1109,11 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr */ if (bexcl && IS_CHEMBOND(ftype)) { - InteractionList &ilist = molt->ilist[F_CONNBONDS]; + InteractionList& ilist = molt->ilist[F_CONNBONDS]; ilist.iatoms.resize(ind_connbond + 3); - ilist.iatoms[ind_connbond++] = ftype_connbond; - ilist.iatoms[ind_connbond++] = a1; - ilist.iatoms[ind_connbond++] = a2; + ilist.iatoms[ind_connbond++] = ftype_connbond; + ilist.iatoms[ind_connbond++] = a1; + ilist.iatoms[ind_connbond++] = a2; } } else @@ -1149,7 +1147,9 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr if (bexcl && ftype == F_SETTLE) { - gmx_fatal(FARGS, "Can not apply QM to molecules with SETTLE, replace the moleculetype using QM and SETTLE by one without SETTLE"); + gmx_fatal(FARGS, + "Can not apply QM to molecules with SETTLE, replace the moleculetype " + "using QM and SETTLE by one without SETTLE"); } } if (bexcl) @@ -1157,7 +1157,7 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr /* since the interaction involves QM atoms, these should be * removed from the MM ilist */ - InteractionList &ilist = molt->ilist[ftype]; + InteractionList& ilist = molt->ilist[ftype]; for (int k = j; k < ilist.size() - (nratoms + 1); k++) { ilist.iatoms[k] = ilist.iatoms[k + (nratoms + 1)]; @@ -1166,7 +1166,7 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr } else { - j += nratoms+1; /* the +1 is for the functype */ + j += nratoms + 1; /* the +1 is for the functype */ } } } @@ -1224,10 +1224,10 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr /* creating the exclusion block for the QM atoms. Each QM atom has * as excluded elements all the other QMatoms (and itself). */ - t_blocka qmexcl; + t_blocka qmexcl; qmexcl.nr = molt->atoms.nr; - qmexcl.nra = qm_nr*(qm_nr+link_nr)+link_nr*qm_nr; - snew(qmexcl.index, qmexcl.nr+1); + qmexcl.nra = qm_nr * (qm_nr + link_nr) + link_nr * qm_nr; + snew(qmexcl.index, qmexcl.nr + 1); snew(qmexcl.a, qmexcl.nra); int j = 0; for (int i = 0; i < qmexcl.nr; i++) @@ -1237,19 +1237,19 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr { for (int k = 0; k < qm_nr; k++) { - qmexcl.a[k+j] = qm_arr[k]; + qmexcl.a[k + j] = qm_arr[k]; } for (int k = 0; k < link_nr; k++) { - qmexcl.a[qm_nr+k+j] = link_arr[k]; + qmexcl.a[qm_nr + k + j] = link_arr[k]; } - j += (qm_nr+link_nr); + j += (qm_nr + link_nr); } if (blink[i]) { for (int k = 0; k < qm_nr; k++) { - qmexcl.a[k+j] = qm_arr[k]; + qmexcl.a[k + j] = qm_arr[k]; } j += qm_nr; } @@ -1274,17 +1274,16 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr int j = 0; while (j < molt->ilist[i].size()) { - int a1 = molt->ilist[i].iatoms[j+1]; - int a2 = molt->ilist[i].iatoms[j+2]; - bool bexcl = ((bQMMM[a1] && bQMMM[a2]) || - (blink[a1] && bQMMM[a2]) || - (bQMMM[a1] && blink[a2])); + int a1 = molt->ilist[i].iatoms[j + 1]; + int a2 = molt->ilist[i].iatoms[j + 2]; + bool bexcl = + ((bQMMM[a1] && bQMMM[a2]) || (blink[a1] && bQMMM[a2]) || (bQMMM[a1] && blink[a2])); if (bexcl) { /* since the interaction involves QM atoms, these should be * removed from the MM ilist */ - InteractionList &ilist = molt->ilist[i]; + InteractionList& ilist = molt->ilist[i]; for (int k = j; k < ilist.size() - (nratoms + 1); k++) { ilist.iatoms[k] = ilist.iatoms[k + (nratoms + 1)]; @@ -1293,7 +1292,7 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr } else { - j += nratoms+1; /* the +1 is for the functype */ + j += nratoms + 1; /* the +1 is for the functype */ } } } @@ -1304,17 +1303,17 @@ static void generate_qmexcl_moltype(gmx_moltype_t *molt, const unsigned char *gr free(blink); } /* generate_qmexcl */ -void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode qmmmMode) +void generate_qmexcl(gmx_mtop_t* sys, t_inputrec* ir, warninp* wi, GmxQmmmMode qmmmMode) { /* This routine expects molt->molt[m].ilist to be of size F_NRE and ordered. */ - unsigned char *grpnr; - int mol, nat_mol, nr_mol_with_qm_atoms = 0; - gmx_molblock_t *molb; - bool bQMMM; - int index_offset = 0; - int qm_nr = 0; + unsigned char* grpnr; + int mol, nat_mol, nr_mol_with_qm_atoms = 0; + gmx_molblock_t* molb; + bool bQMMM; + int index_offset = 0; + int qm_nr = 0; grpnr = sys->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data(); @@ -1329,7 +1328,7 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q { if ((grpnr ? grpnr[i] : 0) < (ir->opts.ngQM)) { - bQMMM = TRUE; + bQMMM = TRUE; qm_nr++; } } @@ -1345,8 +1344,8 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q /* Split the molblock at this molecule */ auto pos = sys->molblock.begin() + mb + 1; sys->molblock.insert(pos, sys->molblock[mb]); - sys->molblock[mb ].nmol = mol; - sys->molblock[mb+1].nmol -= mol; + sys->molblock[mb].nmol = mol; + sys->molblock[mb + 1].nmol -= mol; mb++; molb = &sys->molblock[mb]; } @@ -1355,9 +1354,9 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q /* Split the molblock after this molecule */ auto pos = sys->molblock.begin() + mb + 1; sys->molblock.insert(pos, sys->molblock[mb]); - molb = &sys->molblock[mb]; - sys->molblock[mb ].nmol = 1; - sys->molblock[mb+1].nmol -= 1; + molb = &sys->molblock[mb]; + sys->molblock[mb].nmol = 1; + sys->molblock[mb + 1].nmol -= 1; } /* Create a copy of a moltype for a molecule @@ -1377,8 +1376,7 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q /* Copy the exclusions to a new array, since this is the only * thing that needs to be modified for QMMM. */ - copy_blocka(&sys->moltype[molb->type].excls, - &sys->moltype.back().excls); + copy_blocka(&sys->moltype[molb->type].excls, &sys->moltype.back().excls); /* Set the molecule type for the QMMM molblock */ molb->type = sys->moltype.size() - 1; } @@ -1391,8 +1389,7 @@ void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp *wi, GmxQmmmMode q index_offset += nat_mol; } } - if (qmmmMode == GmxQmmmMode::GMX_QMMM_ORIGINAL && - nr_mol_with_qm_atoms > 1) + if (qmmmMode == GmxQmmmMode::GMX_QMMM_ORIGINAL && nr_mol_with_qm_atoms > 1) { /* generate a warning is there are QM atoms in different * topologies. In this case it is not possible at this stage to diff --git a/src/gromacs/gmxpreprocess/topio.h b/src/gromacs/gmxpreprocess/topio.h index 39e84c0474..70d85cef57 100644 --- a/src/gromacs/gmxpreprocess/topio.h +++ b/src/gromacs/gmxpreprocess/topio.h @@ -54,30 +54,30 @@ struct InteractionsOfType; struct t_symtab; struct warninp; enum struct GmxQmmmMode; -typedef warninp *warninp_t; +typedef warninp* warninp_t; -double check_mol(const gmx_mtop_t *mtop, warninp_t wi); +double check_mol(const gmx_mtop_t* mtop, warninp_t wi); /* Check mass and charge */ -char **do_top(bool bVerbose, - const char *topfile, - const char *topppfile, - t_gromppopts *opts, - bool bZero, - t_symtab *symtab, - gmx::ArrayRef plist, - int *combination_rule, - double *repulsion_power, - real *fudgeQQ, - PreprocessingAtomTypes *atype, - std::vector *molinfo, - std::unique_ptr *intermolecular_interactions, - const t_inputrec *ir, - std::vector *molblock, - bool *ffParametrizedWithHBondConstraints, - warninp_t wi); +char** do_top(bool bVerbose, + const char* topfile, + const char* topppfile, + t_gromppopts* opts, + bool bZero, + t_symtab* symtab, + gmx::ArrayRef plist, + int* combination_rule, + double* repulsion_power, + real* fudgeQQ, + PreprocessingAtomTypes* atype, + std::vector* molinfo, + std::unique_ptr* intermolecular_interactions, + const t_inputrec* ir, + std::vector* molblock, + bool* ffParametrizedWithHBondConstraints, + warninp_t wi); /* This routine expects sys->molt[m].ilist to be of size F_NRE and ordered. */ -void generate_qmexcl(gmx_mtop_t *sys, t_inputrec *ir, warninp_t wi, GmxQmmmMode qmmmMode); +void generate_qmexcl(gmx_mtop_t* sys, t_inputrec* ir, warninp_t wi, GmxQmmmMode qmmmMode); #endif diff --git a/src/gromacs/gmxpreprocess/toppush.cpp b/src/gromacs/gmxpreprocess/toppush.cpp index 4f2a8d760d..af199cdc79 100644 --- a/src/gromacs/gmxpreprocess/toppush.cpp +++ b/src/gromacs/gmxpreprocess/toppush.cpp @@ -66,21 +66,21 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -void generate_nbparams(int comb, - int ftype, - InteractionsOfType *interactions, - PreprocessingAtomTypes *atypes, - warninp *wi) +void generate_nbparams(int comb, + int ftype, + InteractionsOfType* interactions, + PreprocessingAtomTypes* atypes, + warninp* wi) { - int nr, nrfp; - real c, bi, bj, ci, cj, ci0, ci1, ci2, cj0, cj1, cj2; + int nr, nrfp; + real c, bi, bj, ci, cj, ci0, ci1, ci2, cj0, cj1, cj2; /* Lean mean shortcuts */ nr = atypes->size(); nrfp = NRFP(ftype); interactions->interactionTypes.clear(); - std::array forceParam = {NOTSET}; + std::array forceParam = { NOTSET }; /* Fill the matrix with force parameters */ switch (ftype) { @@ -111,11 +111,11 @@ void generate_nbparams(int comb, { for (int j = 0; (j < nr); j++) { - ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); - cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); - ci1 = atypes->atomNonBondedParamFromAtomType(i, 1); - cj1 = atypes->atomNonBondedParamFromAtomType(j, 1); - forceParam[0] = (fabs(ci0) + fabs(cj0))*0.5; + ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); + cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); + ci1 = atypes->atomNonBondedParamFromAtomType(i, 1); + cj1 = atypes->atomNonBondedParamFromAtomType(j, 1); + forceParam[0] = (fabs(ci0) + fabs(cj0)) * 0.5; /* Negative sigma signals that c6 should be set to zero later, * so we need to propagate that through the combination rules. */ @@ -123,7 +123,7 @@ void generate_nbparams(int comb, { forceParam[0] *= -1; } - forceParam[1] = std::sqrt(ci1*cj1); + forceParam[1] = std::sqrt(ci1 * cj1); interactions->interactionTypes.emplace_back(InteractionOfType({}, forceParam)); } } @@ -135,11 +135,11 @@ void generate_nbparams(int comb, { for (int j = 0; (j < nr); j++) { - ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); - cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); - ci1 = atypes->atomNonBondedParamFromAtomType(i, 1); - cj1 = atypes->atomNonBondedParamFromAtomType(j, 1); - forceParam[0] = std::sqrt(std::fabs(ci0*cj0)); + ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); + cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); + ci1 = atypes->atomNonBondedParamFromAtomType(i, 1); + cj1 = atypes->atomNonBondedParamFromAtomType(j, 1); + forceParam[0] = std::sqrt(std::fabs(ci0 * cj0)); /* Negative sigma signals that c6 should be set to zero later, * so we need to propagate that through the combination rules. */ @@ -147,7 +147,7 @@ void generate_nbparams(int comb, { forceParam[0] *= -1; } - forceParam[1] = std::sqrt(ci1*cj1); + forceParam[1] = std::sqrt(ci1 * cj1); interactions->interactionTypes.emplace_back(InteractionOfType({}, forceParam)); } } @@ -165,20 +165,20 @@ void generate_nbparams(int comb, { for (int j = 0; (j < nr); j++) { - ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); - cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); - ci2 = atypes->atomNonBondedParamFromAtomType(i, 2); - cj2 = atypes->atomNonBondedParamFromAtomType(j, 2); - bi = atypes->atomNonBondedParamFromAtomType(i, 1); - bj = atypes->atomNonBondedParamFromAtomType(j, 1); - forceParam[0] = std::sqrt(ci0 * cj0); + ci0 = atypes->atomNonBondedParamFromAtomType(i, 0); + cj0 = atypes->atomNonBondedParamFromAtomType(j, 0); + ci2 = atypes->atomNonBondedParamFromAtomType(i, 2); + cj2 = atypes->atomNonBondedParamFromAtomType(j, 2); + bi = atypes->atomNonBondedParamFromAtomType(i, 1); + bj = atypes->atomNonBondedParamFromAtomType(j, 1); + forceParam[0] = std::sqrt(ci0 * cj0); if ((bi == 0) || (bj == 0)) { forceParam[1] = 0; } else { - forceParam[1] = 2.0/(1/bi+1/bj); + forceParam[1] = 2.0 / (1 / bi + 1 / bj); } forceParam[2] = std::sqrt(ci2 * cj2); interactions->interactionTypes.emplace_back(InteractionOfType({}, forceParam)); @@ -198,26 +198,25 @@ void generate_nbparams(int comb, struct t_nbparam { //! Has this combination been set. - bool bSet; + bool bSet; //! The non-bonded parameters - real c[4]; + real c[4]; }; -static void realloc_nb_params(PreprocessingAtomTypes *atypes, - t_nbparam ***nbparam, t_nbparam ***pair) +static void realloc_nb_params(PreprocessingAtomTypes* atypes, t_nbparam*** nbparam, t_nbparam*** pair) { /* Add space in the non-bonded parameters matrix */ int atnr = atypes->size(); srenew(*nbparam, atnr); - snew((*nbparam)[atnr-1], atnr); + snew((*nbparam)[atnr - 1], atnr); if (pair) { srenew(*pair, atnr); - snew((*pair)[atnr-1], atnr); + snew((*pair)[atnr - 1], atnr); } } -int copy_nbparams(t_nbparam **param, int ftype, InteractionsOfType *interactions, int nr) +int copy_nbparams(t_nbparam** param, int ftype, InteractionsOfType* interactions, int nr) { int nrfp, ncopy; @@ -233,8 +232,8 @@ int copy_nbparams(t_nbparam **param, int ftype, InteractionsOfType *interactions { for (int f = 0; f < nrfp; f++) { - interactions->interactionTypes[nr*i+j].setForceParameter(f, param[i][j].c[f]); - interactions->interactionTypes[nr*j+i].setForceParameter(f, param[i][j].c[f]); + interactions->interactionTypes[nr * i + j].setForceParameter(f, param[i][j].c[f]); + interactions->interactionTypes[nr * j + i].setForceParameter(f, param[i][j].c[f]); } ncopy++; } @@ -244,7 +243,7 @@ int copy_nbparams(t_nbparam **param, int ftype, InteractionsOfType *interactions return ncopy; } -void free_nbparam(t_nbparam **param, int nr) +void free_nbparam(t_nbparam** param, int nr) { int i; @@ -257,7 +256,7 @@ void free_nbparam(t_nbparam **param, int nr) sfree(param); } -static void copy_B_from_A(int ftype, double *c) +static void copy_B_from_A(int ftype, double* c) { int nrfpA, nrfpB, i; @@ -267,25 +266,27 @@ static void copy_B_from_A(int ftype, double *c) /* Copy the B parameters from the first nrfpB A parameters */ for (i = 0; (i < nrfpB); i++) { - c[nrfpA+i] = c[i]; + c[nrfpA + i] = c[i]; } } -void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAtomType *bondAtomType, - char *line, int nb_funct, - t_nbparam ***nbparam, t_nbparam ***pair, - warninp *wi) +void push_at(t_symtab* symtab, + PreprocessingAtomTypes* at, + PreprocessingBondAtomType* bondAtomType, + char* line, + int nb_funct, + t_nbparam*** nbparam, + t_nbparam*** pair, + warninp* wi) { - typedef struct { - const char *entry; + typedef struct + { + const char* entry; int ptype; } t_xlate; t_xlate xl[eptNR] = { - { "A", eptAtom }, - { "N", eptNucleus }, - { "S", eptShell }, - { "B", eptBond }, - { "V", eptVSite }, + { "A", eptAtom }, { "N", eptNucleus }, { "S", eptShell }, + { "B", eptBond }, { "V", eptVSite }, }; int nr, nfields, j, pt, nfp0 = -1; @@ -294,7 +295,7 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto double m, q; double c[MAXFORCEPARAM]; char tmpfield[12][100]; /* Max 12 fields of width 100 */ - t_atom *atom; + t_atom* atom; int atomnr; bool have_atomic_number; bool have_bonded_type; @@ -302,9 +303,9 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto snew(atom, 1); /* First assign input line to temporary array */ - nfields = sscanf(line, "%s%s%s%s%s%s%s%s%s%s%s%s", - tmpfield[0], tmpfield[1], tmpfield[2], tmpfield[3], tmpfield[4], tmpfield[5], - tmpfield[6], tmpfield[7], tmpfield[8], tmpfield[9], tmpfield[10], tmpfield[11]); + nfields = sscanf(line, "%s%s%s%s%s%s%s%s%s%s%s%s", tmpfield[0], tmpfield[1], tmpfield[2], + tmpfield[3], tmpfield[4], tmpfield[5], tmpfield[6], tmpfield[7], tmpfield[8], + tmpfield[9], tmpfield[10], tmpfield[11]); /* Comments on optional fields in the atomtypes section: * @@ -342,24 +343,24 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto return; } - if ( (strlen(tmpfield[5]) == 1) && isalpha(tmpfield[5][0]) ) + if ((strlen(tmpfield[5]) == 1) && isalpha(tmpfield[5][0])) { have_bonded_type = TRUE; have_atomic_number = TRUE; } - else if ( (strlen(tmpfield[3]) == 1) && isalpha(tmpfield[3][0]) ) + else if ((strlen(tmpfield[3]) == 1) && isalpha(tmpfield[3][0])) { have_bonded_type = FALSE; have_atomic_number = FALSE; } else { - have_bonded_type = ( isalpha(tmpfield[1][0]) != 0 ); + have_bonded_type = (isalpha(tmpfield[1][0]) != 0); have_atomic_number = !have_bonded_type; } /* optional fields */ - atomnr = -1; + atomnr = -1; switch (nb_funct) { @@ -371,8 +372,8 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto { if (have_bonded_type) { - nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf", - type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1]); + nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf", type, btype, &atomnr, &m, &q, + ptype, &c[0], &c[1]); if (nread < 8) { too_few(wi); @@ -382,8 +383,7 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto else { /* have_atomic_number && !have_bonded_type */ - nread = sscanf(line, "%s%d%lf%lf%s%lf%lf", - type, &atomnr, &m, &q, ptype, &c[0], &c[1]); + nread = sscanf(line, "%s%d%lf%lf%s%lf%lf", type, &atomnr, &m, &q, ptype, &c[0], &c[1]); if (nread < 7) { too_few(wi); @@ -396,8 +396,7 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto if (have_bonded_type) { /* !have_atomic_number && have_bonded_type */ - nread = sscanf(line, "%s%s%lf%lf%s%lf%lf", - type, btype, &m, &q, ptype, &c[0], &c[1]); + nread = sscanf(line, "%s%s%lf%lf%s%lf%lf", type, btype, &m, &q, ptype, &c[0], &c[1]); if (nread < 7) { too_few(wi); @@ -407,8 +406,7 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto else { /* !have_atomic_number && !have_bonded_type */ - nread = sscanf(line, "%s%lf%lf%s%lf%lf", - type, &m, &q, ptype, &c[0], &c[1]); + nread = sscanf(line, "%s%lf%lf%s%lf%lf", type, &m, &q, ptype, &c[0], &c[1]); if (nread < 6) { too_few(wi); @@ -436,8 +434,8 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto { if (have_bonded_type) { - nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf%lf", - type, btype, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]); + nread = sscanf(line, "%s%s%d%lf%lf%s%lf%lf%lf", type, btype, &atomnr, &m, &q, + ptype, &c[0], &c[1], &c[2]); if (nread < 9) { too_few(wi); @@ -447,8 +445,8 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto else { /* have_atomic_number && !have_bonded_type */ - nread = sscanf(line, "%s%d%lf%lf%s%lf%lf%lf", - type, &atomnr, &m, &q, ptype, &c[0], &c[1], &c[2]); + nread = sscanf(line, "%s%d%lf%lf%s%lf%lf%lf", type, &atomnr, &m, &q, ptype, + &c[0], &c[1], &c[2]); if (nread < 8) { too_few(wi); @@ -461,8 +459,8 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto if (have_bonded_type) { /* !have_atomic_number && have_bonded_type */ - nread = sscanf(line, "%s%s%lf%lf%s%lf%lf%lf", - type, btype, &m, &q, ptype, &c[0], &c[1], &c[2]); + nread = sscanf(line, "%s%s%lf%lf%s%lf%lf%lf", type, btype, &m, &q, ptype, &c[0], + &c[1], &c[2]); if (nread < 8) { too_few(wi); @@ -472,8 +470,7 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto else { /* !have_atomic_number && !have_bonded_type */ - nread = sscanf(line, "%s%lf%lf%s%lf%lf%lf", - type, &m, &q, ptype, &c[0], &c[1], &c[2]); + nread = sscanf(line, "%s%lf%lf%s%lf%lf%lf", type, &m, &q, ptype, &c[0], &c[1], &c[2]); if (nread < 7) { too_few(wi); @@ -547,24 +544,23 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto if ((nr = at->atomTypeFromName(type)) != NOTSET) { - auto message = gmx::formatString - ("Atomtype %s was defined previously (e.g. in the forcefield files), " + auto message = gmx::formatString( + "Atomtype %s was defined previously (e.g. in the forcefield files), " "and has now been defined again. This could happen e.g. if you would " "use a self-contained molecule .itp file that duplicates or replaces " "the contents of the standard force-field files. You should check " "the contents of your files and remove such repetition. If you know " "you should override the previous definition, then you could choose " - "to suppress this warning with -maxwarn.", type); + "to suppress this warning with -maxwarn.", + type); warning(wi, message); - if ((nr = at->setType(nr, symtab, *atom, type, interactionType, batype_nr, - atomnr)) == NOTSET) + if ((nr = at->setType(nr, symtab, *atom, type, interactionType, batype_nr, atomnr)) == NOTSET) { auto message = gmx::formatString("Replacing atomtype %s failed", type); warning_error_and_exit(wi, message, FARGS); } } - else if ((at->addType(symtab, *atom, type, interactionType, - batype_nr, atomnr)) == NOTSET) + else if ((at->addType(symtab, *atom, type, interactionType, batype_nr, atomnr)) == NOTSET) { auto message = gmx::formatString("Adding atomtype %s failed", type); warning_error_and_exit(wi, message, FARGS); @@ -578,23 +574,22 @@ void push_at (t_symtab *symtab, PreprocessingAtomTypes *at, PreprocessingBondAto } //! Return whether the contents of \c a and \c b are the same, considering also reversed order. -template +template static bool equalEitherForwardOrBackward(gmx::ArrayRef a, gmx::ArrayRef b) { - return (std::equal(a.begin(), a.end(), b.begin()) || - std::equal(a.begin(), a.end(), b.rbegin())); + return (std::equal(a.begin(), a.end(), b.begin()) || std::equal(a.begin(), a.end(), b.rbegin())); } -static void push_bondtype(InteractionsOfType *bt, - const InteractionOfType &b, - int nral, - int ftype, - bool bAllowRepeat, - const char *line, - warninp *wi) +static void push_bondtype(InteractionsOfType* bt, + const InteractionOfType& b, + int nral, + int ftype, + bool bAllowRepeat, + const char* line, + warninp* wi) { - int nr = bt->size(); - int nrfp = NRFP(ftype); + int nr = bt->size(); + int nrfp = NRFP(ftype); /* If bAllowRepeat is TRUE, we allow multiple entries as long as they are on directly _adjacent_ lines. @@ -609,7 +604,7 @@ static void push_bondtype(InteractionsOfType *bt, bool isContinuationOfBlock = false; if (bAllowRepeat && nr > 1) { - isContinuationOfBlock = true; + isContinuationOfBlock = true; gmx::ArrayRef newParAtom = b.atoms(); gmx::ArrayRef sysParAtom = bt->interactionTypes[nr - 2].atoms(); for (int j = 0; j < nral; j++) @@ -631,12 +626,16 @@ static void push_bondtype(InteractionsOfType *bt, { gmx::ArrayRef bParams = b.atoms(); gmx::ArrayRef testParams = bt->interactionTypes[i].atoms(); - GMX_RELEASE_ASSERT(bParams.size() == testParams.size(), "Number of atoms needs to be the same between parameters"); + GMX_RELEASE_ASSERT(bParams.size() == testParams.size(), + "Number of atoms needs to be the same between parameters"); if (equalEitherForwardOrBackward(bParams, testParams)) { - GMX_ASSERT(nrfp <= MAXFORCEPARAM, "This is ensured in other places, but we need this assert to keep the clang analyzer happy"); - const bool identicalParameters = std::equal(bt->interactionTypes[i].forceParam().begin(), - bt->interactionTypes[i].forceParam().begin() + nrfp, b.forceParam().begin()); + GMX_ASSERT(nrfp <= MAXFORCEPARAM, + "This is ensured in other places, but we need this assert to keep the clang " + "analyzer happy"); + const bool identicalParameters = std::equal( + bt->interactionTypes[i].forceParam().begin(), + bt->interactionTypes[i].forceParam().begin() + nrfp, b.forceParam().begin()); if (!bAllowRepeat || identicalParameters) { @@ -653,16 +652,18 @@ static void push_bondtype(InteractionsOfType *bt, */ if (!isContinuationOfBlock && !haveErrored) { - warning_error(wi, "Encountered a second block of parameters for dihedral " + warning_error(wi, + "Encountered a second block of parameters for dihedral " "type 9 for the same atoms, with either different parameters " - "and/or the first block has multiple lines. This is not supported."); + "and/or the first block has multiple lines. This is not " + "supported."); haveErrored = true; } } else if (!haveWarned) { - auto message = gmx::formatString - ("Bondtype %s was defined previously (e.g. in the forcefield files), " + auto message = gmx::formatString( + "Bondtype %s was defined previously (e.g. in the forcefield files), " "and has now been defined again. This could happen e.g. if you would " "use a self-contained molecule .itp file that duplicates or replaces " "the contents of the standard force-field files. You should check " @@ -670,10 +671,11 @@ static void push_bondtype(InteractionsOfType *bt, "you should override the previous definition, then you could choose " "to suppress this warning with -maxwarn.%s", interaction_function[ftype].longname, - (ftype == F_PDIHS) ? - "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive " - "lines are combined. Non-consective lines overwrite each other." - : ""); + (ftype == F_PDIHS) ? "\nUse dihedraltype 9 to allow several " + "multiplicity terms. Only consecutive " + "lines are combined. Non-consective lines " + "overwrite each other." + : ""); warning(wi, message); fprintf(stderr, " old: "); @@ -716,8 +718,8 @@ static void push_bondtype(InteractionsOfType *bt, */ if (ftype == F_LINEAR_ANGLES) { - forceParam[0] = 1- forceParam[0]; - forceParam[2] = 1- forceParam[2]; + forceParam[0] = 1 - forceParam[0]; + forceParam[2] = 1 - forceParam[2]; } std::vector atoms; gmx::ArrayRef oldAtoms = b.atoms(); @@ -729,17 +731,17 @@ static void push_bondtype(InteractionsOfType *bt, } } -static std::vector atomTypesFromAtomNames(const PreprocessingAtomTypes *atomTypes, - const PreprocessingBondAtomType *bondAtomTypes, +static std::vector atomTypesFromAtomNames(const PreprocessingAtomTypes* atomTypes, + const PreprocessingBondAtomType* bondAtomTypes, gmx::ArrayRef atomNames, - warninp *wi) + warninp* wi) { GMX_RELEASE_ASSERT(!(!atomNames.empty() && !atomTypes && !bondAtomTypes), "Need to have either valid atomtypes or bondatomtypes object"); std::vector atomTypesFromAtomNames; - for (const auto &name : atomNames) + for (const auto& name : atomNames) { if (atomTypes != nullptr) { @@ -766,38 +768,30 @@ static std::vector atomTypesFromAtomNames(const PreprocessingAtomTypes * } -void push_bt(Directive d, - gmx::ArrayRef bt, - int nral, - PreprocessingAtomTypes *at, - PreprocessingBondAtomType *bondAtomType, - char *line, - warninp *wi) +void push_bt(Directive d, + gmx::ArrayRef bt, + int nral, + PreprocessingAtomTypes* at, + PreprocessingBondAtomType* bondAtomType, + char* line, + warninp* wi) { - const char *formal[MAXATOMLIST+1] = { - "%s", - "%s%s", - "%s%s%s", - "%s%s%s%s", - "%s%s%s%s%s", - "%s%s%s%s%s%s", - "%s%s%s%s%s%s%s" - }; - const char *formnl[MAXATOMLIST+1] = { - "%*s", - "%*s%*s", - "%*s%*s%*s", - "%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s%*s" + const char* formal[MAXATOMLIST + 1] = { + "%s", "%s%s", "%s%s%s", "%s%s%s%s", "%s%s%s%s%s", "%s%s%s%s%s%s", "%s%s%s%s%s%s%s" }; - const char *formlf = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf"; - int i, ft, ftype, nn, nrfp, nrfpA; - char f1[STRLEN]; - char alc[MAXATOMLIST+1][20]; + const char* formnl[MAXATOMLIST + 1] = { "%*s", + "%*s%*s", + "%*s%*s%*s", + "%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s%*s%*s" }; + const char* formlf = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf"; + int i, ft, ftype, nn, nrfp, nrfpA; + char f1[STRLEN]; + char alc[MAXATOMLIST + 1][20]; /* One force parameter more, so we can check if we read too many */ - double c[MAXFORCEPARAM+1]; + double c[MAXFORCEPARAM + 1]; if ((bondAtomType && at) || (!bondAtomType && !at)) { @@ -805,10 +799,9 @@ void push_bt(Directive d, } /* Make format string (nral ints+functype) */ - if ((nn = sscanf(line, formal[nral], - alc[0], alc[1], alc[2], alc[3], alc[4], alc[5])) != nral+1) + if ((nn = sscanf(line, formal[nral], alc[0], alc[1], alc[2], alc[3], alc[4], alc[5])) != nral + 1) { - auto message = gmx::formatString("Not enough atomtypes (%d instead of %d)", nn-1, nral); + auto message = gmx::formatString("Not enough atomtypes (%d instead of %d)", nn - 1, nral); warning_error(wi, message); return; } @@ -819,7 +812,8 @@ void push_bt(Directive d, nrfpA = interaction_function[ftype].nrfpA; strcpy(f1, formnl[nral]); strcat(f1, formlf); - if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11], &c[12])) + if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], + &c[10], &c[11], &c[12])) != nrfp) { if (nn == nrfpA) @@ -847,42 +841,34 @@ void push_bt(Directive d, } } } - std::vector atomTypes = atomTypesFromAtomNames(at, - bondAtomType, - gmx::arrayRefFromArray(alc, nral), - wi); + std::vector atomTypes = + atomTypesFromAtomNames(at, bondAtomType, gmx::arrayRefFromArray(alc, nral), wi); std::array forceParam; for (int i = 0; (i < nrfp); i++) { forceParam[i] = c[i]; } - push_bondtype (&(bt[ftype]), InteractionOfType(atomTypes, forceParam), nral, ftype, FALSE, line, wi); + push_bondtype(&(bt[ftype]), InteractionOfType(atomTypes, forceParam), nral, ftype, FALSE, line, wi); } -void push_dihedraltype(Directive d, gmx::ArrayRef bt, - PreprocessingBondAtomType *bondAtomType, char *line, - warninp *wi) +void push_dihedraltype(Directive d, + gmx::ArrayRef bt, + PreprocessingBondAtomType* bondAtomType, + char* line, + warninp* wi) { - const char *formal[MAXATOMLIST+1] = { - "%s", - "%s%s", - "%s%s%s", - "%s%s%s%s", - "%s%s%s%s%s", - "%s%s%s%s%s%s", - "%s%s%s%s%s%s%s" - }; - const char *formnl[MAXATOMLIST+1] = { - "%*s", - "%*s%*s", - "%*s%*s%*s", - "%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s%*s" + const char* formal[MAXATOMLIST + 1] = { + "%s", "%s%s", "%s%s%s", "%s%s%s%s", "%s%s%s%s%s", "%s%s%s%s%s%s", "%s%s%s%s%s%s%s" }; - const char *formlf[MAXFORCEPARAM] = { + const char* formnl[MAXATOMLIST + 1] = { "%*s", + "%*s%*s", + "%*s%*s%*s", + "%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s%*s%*s" }; + const char* formlf[MAXFORCEPARAM] = { "%lf", "%lf%lf", "%lf%lf%lf", @@ -896,11 +882,11 @@ void push_dihedraltype(Directive d, gmx::ArrayRef bt, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", }; - int i, ft, ftype, nn, nrfp, nrfpA, nral; - char f1[STRLEN]; - char alc[MAXATOMLIST+1][20]; - double c[MAXFORCEPARAM]; - bool bAllowRepeat; + int i, ft, ftype, nn, nrfp, nrfpA, nral; + char f1[STRLEN]; + char alc[MAXATOMLIST + 1][20]; + double c[MAXFORCEPARAM]; + bool bAllowRepeat; /* This routine accepts dihedraltypes defined from either 2 or 4 atoms. * @@ -911,8 +897,8 @@ void push_dihedraltype(Directive d, gmx::ArrayRef bt, nn = sscanf(line, formal[4], alc[0], alc[1], alc[2], alc[3], alc[4]); if (nn >= 3 && strlen(alc[2]) == 1 && isdigit(alc[2][0])) { - nral = 2; - ft = strtol(alc[nral], nullptr, 10); + nral = 2; + ft = strtol(alc[nral], nullptr, 10); /* Move atom types around a bit and use 'X' for wildcard atoms * to create a 4-atom dihedral definition with arbitrary atoms in * position 1 and 4. @@ -936,12 +922,13 @@ void push_dihedraltype(Directive d, gmx::ArrayRef bt, } else if (nn == 5 && strlen(alc[4]) == 1 && isdigit(alc[4][0])) { - nral = 4; - ft = strtol(alc[nral], nullptr, 10); + nral = 4; + ft = strtol(alc[nral], nullptr, 10); } else { - auto message = gmx::formatString("Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn-1); + auto message = gmx::formatString( + "Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn - 1); warning_error(wi, message); return; } @@ -970,10 +957,11 @@ void push_dihedraltype(Directive d, gmx::ArrayRef bt, nrfpA = interaction_function[ftype].nrfpA; strcpy(f1, formnl[nral]); - strcat(f1, formlf[nrfp-1]); + strcat(f1, formlf[nrfp - 1]); /* Check number of parameters given */ - if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], &c[10], &c[11])) + if ((nn = sscanf(line, f1, &c[0], &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], &c[7], &c[8], &c[9], + &c[10], &c[11])) != nrfp) { if (nn == nrfpA) @@ -1028,27 +1016,25 @@ void push_dihedraltype(Directive d, gmx::ArrayRef bt, /* Always use 4 atoms here, since we created two wildcard atoms * if there wasn't of them 4 already. */ - push_bondtype (&(bt[ftype]), InteractionOfType(atoms, forceParam), 4, ftype, bAllowRepeat, line, wi); + push_bondtype(&(bt[ftype]), InteractionOfType(atoms, forceParam), 4, ftype, bAllowRepeat, line, wi); } -void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes, - char *pline, int nb_funct, - warninp *wi) +void push_nbt(Directive d, t_nbparam** nbt, PreprocessingAtomTypes* atypes, char* pline, int nb_funct, warninp* wi) { /* swap the atoms */ - const char *form3 = "%*s%*s%*s%lf%lf%lf"; - const char *form4 = "%*s%*s%*s%lf%lf%lf%lf"; - const char *form5 = "%*s%*s%*s%lf%lf%lf%lf%lf"; + const char* form3 = "%*s%*s%*s%lf%lf%lf"; + const char* form4 = "%*s%*s%*s%lf%lf%lf%lf"; + const char* form5 = "%*s%*s%*s%lf%lf%lf%lf%lf"; char a0[80], a1[80]; int i, f, n, ftype, nrfp; double c[4], dum; real cr[4]; int ai, aj; - t_nbparam *nbp; + t_nbparam* nbp; bool bId; - if (sscanf (pline, "%s%s%d", a0, a1, &f) != 3) + if (sscanf(pline, "%s%s%d", a0, a1, &f) != 3) { too_few(wi); return; @@ -1081,7 +1067,7 @@ void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes, GMX_ASSERT(nrfp <= 4, "LJ-14 cannot have more than 4 parameters"); for (i = n; i < nrfp; i++) { - c[i] = c[i-2]; + c[i] = c[i - 2]; } } else if (ftype == F_LJC14_Q) @@ -1111,7 +1097,8 @@ void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes, } else { - auto message = gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp); + auto message = + gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp); warning_error_and_exit(wi, message, FARGS); } for (i = 0; (i < nrfp); i++) @@ -1141,8 +1128,8 @@ void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes, } if (!bId) { - auto message = gmx::formatString - ("Non-bonded parameters were defined previously (e.g. in the forcefield files), " + auto message = gmx::formatString( + "Non-bonded parameters were defined previously (e.g. in the forcefield files), " "and have now been defined again. This could happen e.g. if you would " "use a self-contained molecule .itp file that duplicates or replaces " "the contents of the standard force-field files. You should check " @@ -1165,21 +1152,20 @@ void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atypes, } } -void -push_cmaptype(Directive d, - gmx::ArrayRef bt, - int nral, - PreprocessingAtomTypes *atomtypes, - PreprocessingBondAtomType *bondAtomType, - char *line, - warninp *wi) +void push_cmaptype(Directive d, + gmx::ArrayRef bt, + int nral, + PreprocessingAtomTypes* atomtypes, + PreprocessingBondAtomType* bondAtomType, + char* line, + warninp* wi) { - const char *formal = "%s%s%s%s%s%s%s%s%n"; + const char* formal = "%s%s%s%s%s%s%s%s%n"; - int ft, ftype, nn, nrfp, nrfpA, nrfpB; - int start, nchar_consumed; - int nxcmap, nycmap, ncmap, read_cmap, sl, nct; - char s[20], alc[MAXATOMLIST+2][20]; + int ft, ftype, nn, nrfp, nrfpA, nrfpB; + int start, nchar_consumed; + int nxcmap, nycmap, ncmap, read_cmap, sl, nct; + char s[20], alc[MAXATOMLIST + 2][20]; /* Keep the compiler happy */ read_cmap = 0; @@ -1188,40 +1174,43 @@ push_cmaptype(Directive d, GMX_ASSERT(nral == 5, "CMAP requires 5 atoms per interaction"); /* Here we can only check for < 8 */ - if ((nn = sscanf(line, formal, alc[0], alc[1], alc[2], alc[3], alc[4], alc[5], alc[6], alc[7], &nchar_consumed)) < nral+3) + if ((nn = sscanf(line, formal, alc[0], alc[1], alc[2], alc[3], alc[4], alc[5], alc[6], alc[7], &nchar_consumed)) + < nral + 3) { - auto message = gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn-1); + auto message = + gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn - 1); warning_error(wi, message); return; } start += nchar_consumed; ft = strtol(alc[nral], nullptr, 10); - nxcmap = strtol(alc[nral+1], nullptr, 10); - nycmap = strtol(alc[nral+2], nullptr, 10); + nxcmap = strtol(alc[nral + 1], nullptr, 10); + nycmap = strtol(alc[nral + 2], nullptr, 10); /* Check for equal grid spacing in x and y dims */ if (nxcmap != nycmap) { - auto message = gmx::formatString("Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap); + auto message = gmx::formatString( + "Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap); warning_error(wi, message); } - ncmap = nxcmap*nycmap; - ftype = ifunc_index(d, ft); - nrfpA = strtol(alc[6], nullptr, 10)*strtol(alc[6], nullptr, 10); - nrfpB = strtol(alc[7], nullptr, 10)*strtol(alc[7], nullptr, 10); - nrfp = nrfpA+nrfpB; + ncmap = nxcmap * nycmap; + ftype = ifunc_index(d, ft); + nrfpA = strtol(alc[6], nullptr, 10) * strtol(alc[6], nullptr, 10); + nrfpB = strtol(alc[7], nullptr, 10) * strtol(alc[7], nullptr, 10); + nrfp = nrfpA + nrfpB; /* Read in CMAP parameters */ sl = 0; for (int i = 0; i < ncmap; i++) { - while (isspace(*(line+start+sl))) + while (isspace(*(line + start + sl))) { sl++; } - nn = sscanf(line+start+sl, " %s ", s); + nn = sscanf(line + start + sl, " %s ", s); sl += strlen(s); bt[F_CMAP].cmap.emplace_back(strtod(s, nullptr)); @@ -1231,10 +1220,11 @@ push_cmaptype(Directive d, } else { - auto message = gmx::formatString("Error in reading cmap parameter for angle %s %s %s %s %s", alc[0], alc[1], alc[2], alc[3], alc[4]); + auto message = + gmx::formatString("Error in reading cmap parameter for angle %s %s %s %s %s", + alc[0], alc[1], alc[2], alc[3], alc[4]); warning_error(wi, message); } - } /* Check do that we got the number of parameters we expected */ @@ -1262,12 +1252,12 @@ push_cmaptype(Directive d, } - /* Set grid spacing and the number of grids (we assume these numbers to be the same for all grids - * so we can safely assign them each time + /* Set grid spacing and the number of grids (we assume these numbers to be the same for all + * grids so we can safely assign them each time */ bt[F_CMAP].cmakeGridSpacing = nxcmap; /* Or nycmap, they need to be equal */ - bt[F_CMAP].cmapAngles++; /* Since we are incrementing here, we need to subtract later, see (*****) */ - nct = (nral+1) * bt[F_CMAP].cmapAngles; + bt[F_CMAP].cmapAngles++; /* Since we are incrementing here, we need to subtract later, see (*****) */ + nct = (nral + 1) * bt[F_CMAP].cmapAngles; for (int i = 0; (i < nral); i++) { @@ -1277,42 +1267,54 @@ push_cmaptype(Directive d, } /* Assign a type number to this cmap */ - bt[F_CMAP].cmapAtomTypes.emplace_back(bt[F_CMAP].cmapAngles-1); /* Since we inremented earlier, we need to subtrac here, to get the types right (****) */ + bt[F_CMAP].cmapAtomTypes.emplace_back( + bt[F_CMAP].cmapAngles + - 1); /* Since we inremented earlier, we need to subtrac here, to get the types right (****) */ /* Check for the correct number of atoms (again) */ if (bt[F_CMAP].nct() != nct) { - auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].cmapAngles); + auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", + nct, bt[F_CMAP].cmapAngles); warning_error(wi, message); } - std::vector atomTypes = atomTypesFromAtomNames(atomtypes, - bondAtomType, - gmx::constArrayRefFromArray(alc, nral), - wi); - std::array forceParam = {NOTSET}; + std::vector atomTypes = + atomTypesFromAtomNames(atomtypes, bondAtomType, gmx::constArrayRefFromArray(alc, nral), wi); + std::array forceParam = { NOTSET }; /* Push the bond to the bondlist */ - push_bondtype (&(bt[ftype]), InteractionOfType(atomTypes, forceParam), nral, ftype, FALSE, line, wi); + push_bondtype(&(bt[ftype]), InteractionOfType(atomTypes, forceParam), nral, ftype, FALSE, line, wi); } -static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr, - int atomicnumber, - int type, char *ctype, int ptype, - char *resnumberic, - char *resname, char *name, real m0, real q0, - int typeB, char *ctypeB, real mB, real qB, - warninp *wi) +static void push_atom_now(t_symtab* symtab, + t_atoms* at, + int atomnr, + int atomicnumber, + int type, + char* ctype, + int ptype, + char* resnumberic, + char* resname, + char* name, + real m0, + real q0, + int typeB, + char* ctypeB, + real mB, + real qB, + warninp* wi) { int j, resind = 0, resnr; unsigned char ric; int nr = at->nr; - if (((nr == 0) && (atomnr != 1)) || (nr && (atomnr != at->nr+1))) + if (((nr == 0) && (atomnr != 1)) || (nr && (atomnr != at->nr + 1))) { - auto message = gmx::formatString - ("Atoms in the .top are not numbered consecutively from 1 (rather, " - "atomnr = %d, while at->nr = %d)", atomnr, at->nr); + auto message = gmx::formatString( + "Atoms in the .top are not numbered consecutively from 1 (rather, " + "atomnr = %d, while at->nr = %d)", + atomnr, at->nr); warning_error_and_exit(wi, message, FARGS); } @@ -1324,10 +1326,10 @@ static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr, else { ric = resnumberic[j]; - if (j == 0 || !isdigit(resnumberic[j-1])) + if (j == 0 || !isdigit(resnumberic[j - 1])) { - auto message = gmx::formatString("Invalid residue number '%s' for atom %d", - resnumberic, atomnr); + auto message = + gmx::formatString("Invalid residue number '%s' for atom %d", resnumberic, atomnr); warning_error_and_exit(wi, message, FARGS); } } @@ -1335,11 +1337,10 @@ static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr, if (nr > 0) { - resind = at->atom[nr-1].resind; + resind = at->atom[nr - 1].resind; } - if (nr == 0 || strcmp(resname, *at->resinfo[resind].name) != 0 || - resnr != at->resinfo[resind].nr || - ric != at->resinfo[resind].ic) + if (nr == 0 || strcmp(resname, *at->resinfo[resind].name) != 0 + || resnr != at->resinfo[resind].nr || ric != at->resinfo[resind].ic) { if (nr == 0) { @@ -1357,16 +1358,16 @@ static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr, } else { - resind = at->atom[at->nr-1].resind; + resind = at->atom[at->nr - 1].resind; } /* New atom instance * get new space for arrays */ - srenew(at->atom, nr+1); - srenew(at->atomname, nr+1); - srenew(at->atomtype, nr+1); - srenew(at->atomtypeB, nr+1); + srenew(at->atom, nr + 1); + srenew(at->atomname, nr + 1); + srenew(at->atomtype, nr + 1); + srenew(at->atomtypeB, nr + 1); /* fill the list */ at->atom[nr].type = type; @@ -1385,26 +1386,23 @@ static void push_atom_now(t_symtab *symtab, t_atoms *at, int atomnr, at->nr++; } -void push_atom(t_symtab *symtab, - t_atoms *at, PreprocessingAtomTypes *atypes, char *line, - warninp *wi) +void push_atom(t_symtab* symtab, t_atoms* at, PreprocessingAtomTypes* atypes, char* line, warninp* wi) { - int ptype; - int cgnumber, atomnr, type, typeB, nscan; - char id[STRLEN], ctype[STRLEN], ctypeB[STRLEN], - resnumberic[STRLEN], resname[STRLEN], name[STRLEN], check[STRLEN]; - double m, q, mb, qb; - real m0, q0, mB, qB; + int ptype; + int cgnumber, atomnr, type, typeB, nscan; + char id[STRLEN], ctype[STRLEN], ctypeB[STRLEN], resnumberic[STRLEN], resname[STRLEN], + name[STRLEN], check[STRLEN]; + double m, q, mb, qb; + real m0, q0, mB, qB; /* Fixed parameters */ - if (sscanf(line, "%s%s%s%s%s%d", - id, ctype, resnumberic, resname, name, &cgnumber) != 6) + if (sscanf(line, "%s%s%s%s%s%d", id, ctype, resnumberic, resname, name, &cgnumber) != 6) { too_few(wi); return; } sscanf(id, "%d", &atomnr); - if ((type = atypes->atomTypeFromName(ctype)) == NOTSET) + if ((type = atypes->atomTypeFromName(ctype)) == NOTSET) { auto message = gmx::formatString("Atomtype %s not found", ctype); warning_error_and_exit(wi, message, FARGS); @@ -1419,8 +1417,7 @@ void push_atom(t_symtab *symtab, mB = m0; /* Optional parameters */ - nscan = sscanf(line, "%*s%*s%*s%*s%*s%*s%lf%lf%s%lf%lf%s", - &q, &m, ctypeB, &qb, &mb, check); + nscan = sscanf(line, "%*s%*s%*s%*s%*s%*s%lf%lf%s%lf%lf%s", &q, &m, ctypeB, &qb, &mb, check); /* Nasty switch that falls thru all the way down! */ if (nscan > 0) @@ -1454,19 +1451,14 @@ void push_atom(t_symtab *symtab, } } - push_atom_now(symtab, at, atomnr, atypes->atomNumberFromAtomType(type), - type, ctype, ptype, resnumberic, - resname, name, m0, q0, typeB, - typeB == type ? ctype : ctypeB, mB, qB, wi); + push_atom_now(symtab, at, atomnr, atypes->atomNumberFromAtomType(type), type, ctype, ptype, + resnumberic, resname, name, m0, q0, typeB, typeB == type ? ctype : ctypeB, mB, qB, wi); } -void push_molt(t_symtab *symtab, - std::vector *mol, - char *line, - warninp *wi) +void push_molt(t_symtab* symtab, std::vector* mol, char* line, warninp* wi) { - char type[STRLEN]; - int nrexcl; + char type[STRLEN]; + int nrexcl; if ((sscanf(line, "%s%d", type, &nrexcl)) != 2) { @@ -1475,8 +1467,7 @@ void push_molt(t_symtab *symtab, /* Test if this moleculetype overwrites another */ const auto found = std::find_if(mol->begin(), mol->end(), - [&type](const auto &m) - { return strcmp(*(m.name), type) == 0; }); + [&type](const auto& m) { return strcmp(*(m.name), type) == 0; }); if (found != mol->end()) { auto message = gmx::formatString("moleculetype %s is redefined", type); @@ -1492,10 +1483,10 @@ void push_molt(t_symtab *symtab, mol->back().excl_set = false; } -static bool findIfAllNBAtomsMatch(gmx::ArrayRef atomsFromParameterArray, - gmx::ArrayRef atomsFromCurrentParameter, - const t_atoms *at, - bool bB) +static bool findIfAllNBAtomsMatch(gmx::ArrayRef atomsFromParameterArray, + gmx::ArrayRef atomsFromCurrentParameter, + const t_atoms* at, + bool bB) { if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size()) { @@ -1525,16 +1516,21 @@ static bool findIfAllNBAtomsMatch(gmx::ArrayRef atomsFromParamet } } -static bool default_nb_params(int ftype, gmx::ArrayRef bt, t_atoms *at, - InteractionOfType *p, int c_start, bool bB, bool bGenPairs) +static bool default_nb_params(int ftype, + gmx::ArrayRef bt, + t_atoms* at, + InteractionOfType* p, + int c_start, + bool bB, + bool bGenPairs) { - int ti, tj, ntype; - bool bFound; - InteractionOfType *pi = nullptr; - int nr = bt[ftype].size(); - int nral = NRAL(ftype); - int nrfp = interaction_function[ftype].nrfpA; - int nrfpB = interaction_function[ftype].nrfpB; + int ti, tj, ntype; + bool bFound; + InteractionOfType* pi = nullptr; + int nr = bt[ftype].size(); + int nral = NRAL(ftype); + int nrfp = interaction_function[ftype].nrfpA; + int nrfpB = interaction_function[ftype].nrfpB; if ((!bB && nrfp == 0) || (bB && nrfpB == 0)) { @@ -1548,7 +1544,8 @@ static bool default_nb_params(int ftype, gmx::ArrayRef bt, t * time when we have 1000*1000 entries for e.g. OPLS... */ ntype = static_cast(std::sqrt(static_cast(nr))); - GMX_ASSERT(ntype * ntype == nr, "Number of pairs of generated non-bonded parameters should be a perfect square"); + GMX_ASSERT(ntype * ntype == nr, + "Number of pairs of generated non-bonded parameters should be a perfect square"); if (bB) { ti = at->atom[p->ai()].typeB; @@ -1559,7 +1556,7 @@ static bool default_nb_params(int ftype, gmx::ArrayRef bt, t ti = at->atom[p->ai()].type; tj = at->atom[p->aj()].type; } - pi = &(bt[ftype].interactionTypes[ntype*ti+tj]); + pi = &(bt[ftype].interactionTypes[ntype * ti + tj]); if (pi->atoms().ssize() < nral) { /* not initialized yet with atom names */ @@ -1575,10 +1572,11 @@ static bool default_nb_params(int ftype, gmx::ArrayRef bt, t /* Search explicitly if we didnt find it */ if (!bFound) { - auto foundParameter = std::find_if(bt[ftype].interactionTypes.begin(), - bt[ftype].interactionTypes.end(), - [¶mAtoms, &at, &bB](const auto ¶m) - { return findIfAllNBAtomsMatch(param.atoms(), paramAtoms, at, bB); }); + auto foundParameter = + std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(), + [¶mAtoms, &at, &bB](const auto& param) { + return findIfAllNBAtomsMatch(param.atoms(), paramAtoms, at, bB); + }); if (foundParameter != bt[ftype].interactionTypes.end()) { bFound = true; @@ -1591,13 +1589,13 @@ static bool default_nb_params(int ftype, gmx::ArrayRef bt, t gmx::ArrayRef forceParam = pi->forceParam(); if (bB) { - if (nrfp+nrfpB > MAXFORCEPARAM) + if (nrfp + nrfpB > MAXFORCEPARAM) { gmx_incons("Too many force parameters"); } for (int j = c_start; j < nrfpB; j++) { - p->setForceParameter(nrfp+j, forceParam[j]); + p->setForceParameter(nrfp + j, forceParam[j]); } } else @@ -1619,14 +1617,17 @@ static bool default_nb_params(int ftype, gmx::ArrayRef bt, t } static bool default_cmap_params(gmx::ArrayRef bondtype, - t_atoms *at, PreprocessingAtomTypes *atypes, - InteractionOfType *p, bool bB, - int *cmap_type, int *nparam_def, - warninp *wi) + t_atoms* at, + PreprocessingAtomTypes* atypes, + InteractionOfType* p, + bool bB, + int* cmap_type, + int* nparam_def, + warninp* wi) { - int nparam_found; - int ct; - bool bFound = false; + int nparam_found; + int ct; + bool bFound = false; nparam_found = 0; ct = 0; @@ -1634,22 +1635,23 @@ static bool default_cmap_params(gmx::ArrayRef bondtype, /* Match the current cmap angle against the list of cmap_types */ for (int i = 0; i < bondtype[F_CMAP].nct() && !bFound; i += 6) { - if (bB) - { - - } + if (bB) {} else { - if ( - (atypes->bondAtomTypeFromAtomType(at->atom[p->ai()].type) == bondtype[F_CMAP].cmapAtomTypes[i]) && - (atypes->bondAtomTypeFromAtomType(at->atom[p->aj()].type) == bondtype[F_CMAP].cmapAtomTypes[i+1]) && - (atypes->bondAtomTypeFromAtomType(at->atom[p->ak()].type) == bondtype[F_CMAP].cmapAtomTypes[i+2]) && - (atypes->bondAtomTypeFromAtomType(at->atom[p->al()].type) == bondtype[F_CMAP].cmapAtomTypes[i+3]) && - (atypes->bondAtomTypeFromAtomType(at->atom[p->am()].type) == bondtype[F_CMAP].cmapAtomTypes[i+4])) + if ((atypes->bondAtomTypeFromAtomType(at->atom[p->ai()].type) + == bondtype[F_CMAP].cmapAtomTypes[i]) + && (atypes->bondAtomTypeFromAtomType(at->atom[p->aj()].type) + == bondtype[F_CMAP].cmapAtomTypes[i + 1]) + && (atypes->bondAtomTypeFromAtomType(at->atom[p->ak()].type) + == bondtype[F_CMAP].cmapAtomTypes[i + 2]) + && (atypes->bondAtomTypeFromAtomType(at->atom[p->al()].type) + == bondtype[F_CMAP].cmapAtomTypes[i + 3]) + && (atypes->bondAtomTypeFromAtomType(at->atom[p->am()].type) + == bondtype[F_CMAP].cmapAtomTypes[i + 4])) { /* Found cmap torsion */ bFound = true; - ct = bondtype[F_CMAP].cmapAtomTypes[i+5]; + ct = bondtype[F_CMAP].cmapAtomTypes[i + 5]; nparam_found = 1; } } @@ -1658,8 +1660,8 @@ static bool default_cmap_params(gmx::ArrayRef bondtype, /* If we did not find a matching type for this cmap torsion */ if (!bFound) { - auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d", - p->ai()+1, p->aj()+1, p->ak()+1, p->al()+1, p->am()+1); + auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d", p->ai() + 1, + p->aj() + 1, p->ak() + 1, p->al() + 1, p->am() + 1); warning_error_and_exit(wi, message, FARGS); } @@ -1672,20 +1674,20 @@ static bool default_cmap_params(gmx::ArrayRef bondtype, /* Returns the number of exact atom type matches, i.e. non wild-card matches, * returns -1 when there are no matches at all. */ -static int natom_match(const InteractionOfType &pi, - int type_i, int type_j, int type_k, int type_l, +static int natom_match(const InteractionOfType& pi, + int type_i, + int type_j, + int type_k, + int type_l, const PreprocessingAtomTypes* atypes) { - if ((pi.ai() == -1 || atypes->bondAtomTypeFromAtomType(type_i) == pi.ai()) && - (pi.aj() == -1 || atypes->bondAtomTypeFromAtomType(type_j) == pi.aj()) && - (pi.ak() == -1 || atypes->bondAtomTypeFromAtomType(type_k) == pi.ak()) && - (pi.al() == -1 || atypes->bondAtomTypeFromAtomType(type_l) == pi.al())) + if ((pi.ai() == -1 || atypes->bondAtomTypeFromAtomType(type_i) == pi.ai()) + && (pi.aj() == -1 || atypes->bondAtomTypeFromAtomType(type_j) == pi.aj()) + && (pi.ak() == -1 || atypes->bondAtomTypeFromAtomType(type_k) == pi.ak()) + && (pi.al() == -1 || atypes->bondAtomTypeFromAtomType(type_l) == pi.al())) { - return - (pi.ai() == -1 ? 0 : 1) + - (pi.aj() == -1 ? 0 : 1) + - (pi.ak() == -1 ? 0 : 1) + - (pi.al() == -1 ? 0 : 1); + return (pi.ai() == -1 ? 0 : 1) + (pi.aj() == -1 ? 0 : 1) + (pi.ak() == -1 ? 0 : 1) + + (pi.al() == -1 ? 0 : 1); } else { @@ -1693,34 +1695,30 @@ static int natom_match(const InteractionOfType &pi, } } -static int findNumberOfDihedralAtomMatches(const InteractionOfType ¤tParamFromParameterArray, - const InteractionOfType ¶meterToAdd, - const t_atoms *at, - const PreprocessingAtomTypes *atypes, - bool bB) +static int findNumberOfDihedralAtomMatches(const InteractionOfType& currentParamFromParameterArray, + const InteractionOfType& parameterToAdd, + const t_atoms* at, + const PreprocessingAtomTypes* atypes, + bool bB) { if (bB) { - return natom_match(currentParamFromParameterArray, - at->atom[parameterToAdd.ai()].typeB, - at->atom[parameterToAdd.aj()].typeB, - at->atom[parameterToAdd.ak()].typeB, + return natom_match(currentParamFromParameterArray, at->atom[parameterToAdd.ai()].typeB, + at->atom[parameterToAdd.aj()].typeB, at->atom[parameterToAdd.ak()].typeB, at->atom[parameterToAdd.al()].typeB, atypes); } else { - return natom_match(currentParamFromParameterArray, - at->atom[parameterToAdd.ai()].type, - at->atom[parameterToAdd.aj()].type, - at->atom[parameterToAdd.ak()].type, + return natom_match(currentParamFromParameterArray, at->atom[parameterToAdd.ai()].type, + at->atom[parameterToAdd.aj()].type, at->atom[parameterToAdd.ak()].type, at->atom[parameterToAdd.al()].type, atypes); } } static bool findIfAllParameterAtomsMatch(gmx::ArrayRef atomsFromParameterArray, gmx::ArrayRef atomsFromCurrentParameter, - const t_atoms *at, - const PreprocessingAtomTypes *atypes, + const t_atoms* at, + const PreprocessingAtomTypes* atypes, bool bB) { if (atomsFromParameterArray.size() != atomsFromCurrentParameter.size()) @@ -1731,8 +1729,8 @@ static bool findIfAllParameterAtomsMatch(gmx::ArrayRef atomsFrom { for (gmx::index i = 0; i < atomsFromCurrentParameter.ssize(); i++) { - if (atypes->bondAtomTypeFromAtomType( - at->atom[atomsFromCurrentParameter[i]].typeB) != atomsFromParameterArray[i]) + if (atypes->bondAtomTypeFromAtomType(at->atom[atomsFromCurrentParameter[i]].typeB) + != atomsFromParameterArray[i]) { return false; } @@ -1743,8 +1741,8 @@ static bool findIfAllParameterAtomsMatch(gmx::ArrayRef atomsFrom { for (gmx::index i = 0; i < atomsFromCurrentParameter.ssize(); i++) { - if (atypes->bondAtomTypeFromAtomType( - at->atom[atomsFromCurrentParameter[i]].type) != atomsFromParameterArray[i]) + if (atypes->bondAtomTypeFromAtomType(at->atom[atomsFromCurrentParameter[i]].type) + != atomsFromParameterArray[i]) { return false; } @@ -1753,15 +1751,17 @@ static bool findIfAllParameterAtomsMatch(gmx::ArrayRef atomsFrom } } -static std::vector::iterator -defaultInteractionsOfType(int ftype, gmx::ArrayRef bt, - t_atoms *at, PreprocessingAtomTypes *atypes, - const InteractionOfType &p, bool bB, - int *nparam_def) +static std::vector::iterator defaultInteractionsOfType(int ftype, + gmx::ArrayRef bt, + t_atoms* at, + PreprocessingAtomTypes* atypes, + const InteractionOfType& p, + bool bB, + int* nparam_def) { - int nparam_found; - int nrfpA = interaction_function[ftype].nrfpA; - int nrfpB = interaction_function[ftype].nrfpB; + int nparam_found; + int nrfpA = interaction_function[ftype].nrfpA; + int nrfpB = interaction_function[ftype].nrfpB; if ((!bB && nrfpA == 0) || (bB && nrfpB == 0)) { @@ -1782,8 +1782,10 @@ defaultInteractionsOfType(int ftype, gmx::ArrayRef bt, while (pos != bt[ftype].interactionTypes.end() && nmatch_max < 4) { pos = std::find_if(bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(), - [&p, &at, &atypes, &bB, &nmatch_max](const auto ¶m) - { return (findNumberOfDihedralAtomMatches(param, p, at, atypes, bB) > nmatch_max); }); + [&p, &at, &atypes, &bB, &nmatch_max](const auto& param) { + return (findNumberOfDihedralAtomMatches(param, p, at, atypes, bB) + > nmatch_max); + }); if (pos != bt[ftype].interactionTypes.end()) { prevPos = pos; @@ -1800,18 +1802,19 @@ defaultInteractionsOfType(int ftype, gmx::ArrayRef bt, * The rule in that case is that additional matches * HAVE to be on adjacent lines! */ - bool bSame = true; - //Advance iterator (like std::advance) without incrementing past end (UB) - const auto safeAdvance = [](auto &it, auto n, auto end) { - it = end-it > n ? it+n : end; - }; + bool bSame = true; + // Advance iterator (like std::advance) without incrementing past end (UB) + const auto safeAdvance = [](auto& it, auto n, auto end) { + it = end - it > n ? it + n : end; + }; /* Continue from current iterator position */ auto nextPos = prevPos; const auto endIter = bt[ftype].interactionTypes.end(); safeAdvance(nextPos, 2, endIter); for (; nextPos < endIter && bSame; safeAdvance(nextPos, 2, endIter)) { - bSame = (prevPos->ai() == nextPos->ai() && prevPos->aj() == nextPos->aj() && prevPos->ak() == nextPos->ak() && prevPos->al() == nextPos->al()); + bSame = (prevPos->ai() == nextPos->ai() && prevPos->aj() == nextPos->aj() + && prevPos->ak() == nextPos->ak() && prevPos->al() == nextPos->al()); if (bSame) { nparam_found++; @@ -1822,13 +1825,14 @@ defaultInteractionsOfType(int ftype, gmx::ArrayRef bt, *nparam_def = nparam_found; return prevPos; } - else /* Not a dihedral */ + else /* Not a dihedral */ { gmx::ArrayRef atomParam = p.atoms(); - auto found = std::find_if(bt[ftype].interactionTypes.begin(), - bt[ftype].interactionTypes.end(), - [&atomParam, &at, &atypes, &bB](const auto ¶m) - { return findIfAllParameterAtomsMatch(param.atoms(), atomParam, at, atypes, bB); }); + auto found = std::find_if( + bt[ftype].interactionTypes.begin(), bt[ftype].interactionTypes.end(), + [&atomParam, &at, &atypes, &bB](const auto& param) { + return findIfAllParameterAtomsMatch(param.atoms(), atomParam, at, atypes, bB); + }); if (found != bt[ftype].interactionTypes.end()) { nparam_found = 1; @@ -1839,38 +1843,33 @@ defaultInteractionsOfType(int ftype, gmx::ArrayRef bt, } - -void push_bond(Directive d, gmx::ArrayRef bondtype, +void push_bond(Directive d, + gmx::ArrayRef bondtype, gmx::ArrayRef bond, - t_atoms *at, PreprocessingAtomTypes *atypes, char *line, - bool bBonded, bool bGenPairs, real fudgeQQ, - bool bZero, bool *bWarn_copy_A_B, - warninp *wi) + t_atoms* at, + PreprocessingAtomTypes* atypes, + char* line, + bool bBonded, + bool bGenPairs, + real fudgeQQ, + bool bZero, + bool* bWarn_copy_A_B, + warninp* wi) { - const char *aaformat[MAXATOMLIST] = { - "%d%d", - "%d%d%d", - "%d%d%d%d", - "%d%d%d%d%d", - "%d%d%d%d%d%d", - "%d%d%d%d%d%d%d" - }; - const char *asformat[MAXATOMLIST] = { - "%*s%*s", - "%*s%*s%*s", - "%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s", - "%*s%*s%*s%*s%*s%*s%*s" + const char* aaformat[MAXATOMLIST] = { "%d%d", "%d%d%d", "%d%d%d%d", + "%d%d%d%d%d", "%d%d%d%d%d%d", "%d%d%d%d%d%d%d" }; + const char* asformat[MAXATOMLIST] = { + "%*s%*s", "%*s%*s%*s", "%*s%*s%*s%*s", + "%*s%*s%*s%*s%*s", "%*s%*s%*s%*s%*s%*s", "%*s%*s%*s%*s%*s%*s%*s" }; - const char *ccformat = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf"; - int nral, nral_fmt, nread, ftype; - char format[STRLEN]; + const char* ccformat = "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf"; + int nral, nral_fmt, nread, ftype; + char format[STRLEN]; /* One force parameter more, so we can check if we read too many */ - double cc[MAXFORCEPARAM+1]; - int aa[MAXATOMLIST+1]; - bool bFoundA = FALSE, bFoundB = FALSE, bDef, bSwapParity = FALSE; - int nparam_defA, nparam_defB; + double cc[MAXFORCEPARAM + 1]; + int aa[MAXATOMLIST + 1]; + bool bFoundA = FALSE, bFoundB = FALSE, bDef, bSwapParity = FALSE; + int nparam_defA, nparam_defB; nparam_defA = nparam_defB = 0; @@ -1894,8 +1893,7 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, nral_fmt = nral; } - nread = sscanf(line, aaformat[nral_fmt-1], - &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]); + nread = sscanf(line, aaformat[nral_fmt - 1], &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]); if (ftype == F_SETTLE) { @@ -1923,12 +1921,12 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, switch (ftype) { case F_VSITE3FAD: - case F_VSITE3OUT: - break; + case F_VSITE3OUT: break; default: - auto message = gmx::formatString("Negative function types only allowed for %s and %s", - interaction_function[F_VSITE3FAD].longname, - interaction_function[F_VSITE3OUT].longname); + auto message = + gmx::formatString("Negative function types only allowed for %s and %s", + interaction_function[F_VSITE3FAD].longname, + interaction_function[F_VSITE3OUT].longname); warning_error_and_exit(wi, message, FARGS); } } @@ -1940,17 +1938,18 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, { if (aa[i] < 1 || aa[i] > at->nr) { - auto message = gmx::formatString - ("Atom index (%d) in %s out of bounds (1-%d).\n" + auto message = gmx::formatString( + "Atom index (%d) in %s out of bounds (1-%d).\n" "This probably means that you have inserted topology section \"%s\"\n" "in a part belonging to a different molecule than you intended to.\n" "In that case move the \"%s\" section to the right molecule.", aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d)); warning_error_and_exit(wi, message, FARGS); } - for (int j = i+1; (j < nral); j++) + for (int j = i + 1; (j < nral); j++) { - GMX_ASSERT(j < MAXATOMLIST + 1, "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy"); + GMX_ASSERT(j < MAXATOMLIST + 1, + "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy"); if (aa[i] == aa[j]) { auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d)); @@ -1971,13 +1970,13 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, } /* default force parameters */ - std::vector atoms; + std::vector atoms; for (int j = 0; (j < nral); j++) { - atoms.emplace_back(aa[j]-1); + atoms.emplace_back(aa[j] - 1); } /* need to have an empty but initialized param array for some reason */ - std::array forceParam = {0.0}; + std::array forceParam = { 0.0 }; /* Get force params for normal and free energy perturbation * studies, as determined by types! @@ -1988,19 +1987,15 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, std::vector::iterator foundBParameter = bondtype[ftype].interactionTypes.end(); if (bBonded) { - foundAParameter = defaultInteractionsOfType(ftype, - bondtype, - at, - atypes, - param, - FALSE, - &nparam_defA); + foundAParameter = + defaultInteractionsOfType(ftype, bondtype, at, atypes, param, FALSE, &nparam_defA); if (foundAParameter != bondtype[ftype].interactionTypes.end()) { /* Copy the A-state and B-state default parameters. */ - GMX_ASSERT(NRFPA(ftype)+NRFPB(ftype) <= MAXFORCEPARAM, "Bonded interactions may have at most 12 parameters"); + GMX_ASSERT(NRFPA(ftype) + NRFPB(ftype) <= MAXFORCEPARAM, + "Bonded interactions may have at most 12 parameters"); gmx::ArrayRef defaultParam = foundAParameter->forceParam(); - for (int j = 0; (j < NRFPA(ftype)+NRFPB(ftype)); j++) + for (int j = 0; (j < NRFPA(ftype) + NRFPB(ftype)); j++) { param.setForceParameter(j, defaultParam[j]); } @@ -2010,13 +2005,8 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, { bFoundA = true; } - foundBParameter = defaultInteractionsOfType(ftype, - bondtype, - at, - atypes, - param, - TRUE, - &nparam_defB); + foundBParameter = + defaultInteractionsOfType(ftype, bondtype, at, atypes, param, TRUE, &nparam_defB); if (foundBParameter != bondtype[ftype].interactionTypes.end()) { /* Copy only the B-state default parameters */ @@ -2062,11 +2052,11 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, { /* Manually specified parameters - in this case we discard multiple torsion info! */ - strcpy(format, asformat[nral_fmt-1]); + strcpy(format, asformat[nral_fmt - 1]); strcat(format, ccformat); - nread = sscanf(line, format, &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5], - &cc[6], &cc[7], &cc[8], &cc[9], &cc[10], &cc[11], &cc[12]); + nread = sscanf(line, format, &cc[0], &cc[1], &cc[2], &cc[3], &cc[4], &cc[5], &cc[6], &cc[7], + &cc[8], &cc[9], &cc[10], &cc[11], &cc[12]); if ((nread == NRFPA(ftype)) && (NRFPB(ftype) != 0)) { @@ -2080,9 +2070,10 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, if (bPert && *bWarn_copy_A_B) { - auto message = gmx::formatString("Some parameters for bonded interaction involving " - "perturbed atoms are specified explicitly in " - "state A, but not B - copying A to B"); + auto message = gmx::formatString( + "Some parameters for bonded interaction involving " + "perturbed atoms are specified explicitly in " + "state A, but not B - copying A to B"); warning(wi, message); *bWarn_copy_A_B = FALSE; } @@ -2103,11 +2094,10 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, * For F_LJC14_Q we allow supplying fudgeQQ only. * Anything else is an error! */ - if ((nread != 0) && (nread != EOF) && (nread != NRFP(ftype)) && - !(ftype == F_LJC14_Q && nread == 1)) + if ((nread != 0) && (nread != EOF) && (nread != NRFP(ftype)) && !(ftype == F_LJC14_Q && nread == 1)) { - auto message = gmx::formatString - ("Incorrect number of parameters - found %d, expected %d " + auto message = gmx::formatString( + "Incorrect number of parameters - found %d, expected %d " "or %d for %s (after the function type).", nread, NRFPA(ftype), NRFP(ftype), interaction_function[ftype].longname); warning_error_and_exit(wi, message, FARGS); @@ -2135,11 +2125,14 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, /* When we have multiple terms it would be very dangerous to allow perturbations to a different atom type! */ if (ftype == F_PDIHS) { - if ((nparam_defA != nparam_defB) || ((nparam_defA > 1 || nparam_defB > 1) && (foundAParameter != foundBParameter))) + if ((nparam_defA != nparam_defB) + || ((nparam_defA > 1 || nparam_defB > 1) && (foundAParameter != foundBParameter))) { - auto message = - gmx::formatString("Cannot automatically perturb a torsion with multiple terms to different form.\n" - "Please specify perturbed parameters manually for this torsion in your topology!"); + auto message = gmx::formatString( + "Cannot automatically perturb a torsion with multiple terms to different " + "form.\n" + "Please specify perturbed parameters manually for this torsion in your " + "topology!"); warning_error(wi, message); } } @@ -2147,7 +2140,8 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, if (nread > 0 && nread < NRFPA(ftype)) { /* Issue an error, do not use defaults */ - auto message = gmx::formatString("Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype)); + auto message = gmx::formatString( + "Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype)); warning_error(wi, message); } @@ -2176,7 +2170,8 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, } else { - auto message = gmx::formatString("No default %s types", interaction_function[ftype].longname); + auto message = gmx::formatString("No default %s types", + interaction_function[ftype].longname); warning_error(wi, message); } } @@ -2187,12 +2182,8 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, { switch (ftype) { - case F_VSITE3FAD: - param.setForceParameter(0, 360 - param.c0()); - break; - case F_VSITE3OUT: - param.setForceParameter(2, -param.c2()); - break; + case F_VSITE3FAD: param.setForceParameter(0, 360 - param.c0()); break; + case F_VSITE3OUT: param.setForceParameter(2, -param.c2()); break; } } } @@ -2208,8 +2199,10 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, if (bPert) { - auto message = gmx::formatString("No default %s types for perturbed atoms, " - "using normal values", interaction_function[ftype].longname); + auto message = gmx::formatString( + "No default %s types for perturbed atoms, " + "using normal values", + interaction_function[ftype].longname); warning(wi, message); } } @@ -2217,12 +2210,11 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, } gmx::ArrayRef paramValue = param.forceParam(); - if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ) - && paramValue[5] != paramValue[2]) + if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ) && paramValue[5] != paramValue[2]) { auto message = gmx::formatString("%s multiplicity can not be perturbed %f!=%f", - interaction_function[ftype].longname, - paramValue[2], paramValue[5]); + interaction_function[ftype].longname, paramValue[2], + paramValue[5]); warning_error_and_exit(wi, message, FARGS); } @@ -2253,7 +2245,7 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, } /* Put the values in the appropriate arrays */ - add_param_to_list (&bond[ftype], param); + add_param_to_list(&bond[ftype], param); /* Push additional torsions from FF for ftype==9 if we have them. * We have already checked that the A/B states do not differ in this case, @@ -2267,43 +2259,38 @@ void push_bond(Directive d, gmx::ArrayRef bondtype, /* Advance pointer! */ foundAParameter += 2; gmx::ArrayRef forceParam = foundAParameter->forceParam(); - for (int j = 0; j < (NRFPA(ftype)+NRFPB(ftype)); j++) + for (int j = 0; j < (NRFPA(ftype) + NRFPB(ftype)); j++) { param.setForceParameter(j, forceParam[j]); } /* And push the next term for this torsion */ - add_param_to_list (&bond[ftype], param); + add_param_to_list(&bond[ftype], param); } } } -void push_cmap(Directive d, gmx::ArrayRef bondtype, +void push_cmap(Directive d, + gmx::ArrayRef bondtype, gmx::ArrayRef bond, - t_atoms *at, PreprocessingAtomTypes *atypes, char *line, - warninp *wi) + t_atoms* at, + PreprocessingAtomTypes* atypes, + char* line, + warninp* wi) { - const char *aaformat[MAXATOMLIST+1] = - { - "%d", - "%d%d", - "%d%d%d", - "%d%d%d%d", - "%d%d%d%d%d", - "%d%d%d%d%d%d", - "%d%d%d%d%d%d%d" + const char* aaformat[MAXATOMLIST + 1] = { + "%d", "%d%d", "%d%d%d", "%d%d%d%d", "%d%d%d%d%d", "%d%d%d%d%d%d", "%d%d%d%d%d%d%d" }; - int ftype, nral, nread, ncmap_params; - int cmap_type; - int aa[MAXATOMLIST+1]; - bool bFound; + int ftype, nral, nread, ncmap_params; + int cmap_type; + int aa[MAXATOMLIST + 1]; + bool bFound; ftype = ifunc_index(d, 1); nral = NRAL(ftype); ncmap_params = 0; - nread = sscanf(line, aaformat[nral-1], - &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]); + nread = sscanf(line, aaformat[nral - 1], &aa[0], &aa[1], &aa[2], &aa[3], &aa[4], &aa[5]); if (nread < nral) { @@ -2320,8 +2307,8 @@ void push_cmap(Directive d, gmx::ArrayRef bondtype, { if (aa[i] < 1 || aa[i] > at->nr) { - auto message = gmx::formatString - ("Atom index (%d) in %s out of bounds (1-%d).\n" + auto message = gmx::formatString( + "Atom index (%d) in %s out of bounds (1-%d).\n" "This probably means that you have inserted topology section \"%s\"\n" "in a part belonging to a different molecule than you intended to.\n" "In that case move the \"%s\" section to the right molecule.", @@ -2329,7 +2316,7 @@ void push_cmap(Directive d, gmx::ArrayRef bondtype, warning_error_and_exit(wi, message, FARGS); } - for (int j = i+1; (j < nral); j++) + for (int j = i + 1; (j < nral); j++) { if (aa[i] == aa[j]) { @@ -2343,10 +2330,10 @@ void push_cmap(Directive d, gmx::ArrayRef bondtype, std::vector atoms; for (int j = 0; (j < nral); j++) { - atoms.emplace_back(aa[j]-1); + atoms.emplace_back(aa[j] - 1); } - std::array forceParam = {0.0}; - InteractionOfType param(atoms, forceParam, ""); + std::array forceParam = { 0.0 }; + InteractionOfType param(atoms, forceParam, ""); /* Get the cmap type for this cmap angle */ bFound = default_cmap_params(bondtype, at, atypes, ¶m, FALSE, &cmap_type, &ncmap_params, wi); @@ -2360,58 +2347,53 @@ void push_cmap(Directive d, gmx::ArrayRef bondtype, else { /* This is essentially the same check as in default_cmap_params() done one more time */ - auto message = gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n", - param.ai()+1, param.aj()+1, param.ak()+1, param.al()+1, param.am()+1); + auto message = gmx::formatString( + "Unable to assign a cmap type to torsion %d %d %d %d and %d\n", param.ai() + 1, + param.aj() + 1, param.ak() + 1, param.al() + 1, param.am() + 1); warning_error_and_exit(wi, message, FARGS); } } - -void push_vsitesn(Directive d, gmx::ArrayRef bond, - t_atoms *at, char *line, - warninp *wi) +void push_vsitesn(Directive d, gmx::ArrayRef bond, t_atoms* at, char* line, warninp* wi) { - char *ptr; - int type, ftype, n, ret, nj, a; - int *atc = nullptr; - double *weight = nullptr, weight_tot; - - std::array forceParam = {0.0}; - ptr = line; - ret = sscanf(ptr, "%d%n", &a, &n); + char* ptr; + int type, ftype, n, ret, nj, a; + int* atc = nullptr; + double *weight = nullptr, weight_tot; + + std::array forceParam = { 0.0 }; + ptr = line; + ret = sscanf(ptr, "%d%n", &a, &n); ptr += n; if (ret == 0) { - auto message = gmx::formatString("Expected an atom index in section \"%s\"", - dir2str(d)); + auto message = gmx::formatString("Expected an atom index in section \"%s\"", dir2str(d)); warning_error_and_exit(wi, message, FARGS); } sscanf(ptr, "%d%n", &type, &n); - ptr += n; - ftype = ifunc_index(d, type); + ptr += n; + ftype = ifunc_index(d, type); int firstAtom = a - 1; weight_tot = 0; nj = 0; do { - ret = sscanf(ptr, "%d%n", &a, &n); + ret = sscanf(ptr, "%d%n", &a, &n); ptr += n; if (ret > 0) { if (nj % 20 == 0) { - srenew(atc, nj+20); - srenew(weight, nj+20); + srenew(atc, nj + 20); + srenew(weight, nj + 20); } atc[nj] = a - 1; switch (type) { - case 1: - weight[nj] = 1; - break; + case 1: weight[nj] = 1; break; case 2: /* Here we use the A-state mass as a parameter. * Note that the B-state mass has no influence. @@ -2421,13 +2403,13 @@ void push_vsitesn(Directive d, gmx::ArrayRef bond, case 3: weight[nj] = -1; ret = sscanf(ptr, "%lf%n", &(weight[nj]), &n); - ptr += n; + ptr += n; if (weight[nj] < 0) { - auto message = gmx::formatString - ("No weight or negative weight found for vsiten " + auto message = gmx::formatString( + "No weight or negative weight found for vsiten " "constructing atom %d (atom index %d)", - nj+1, atc[nj]+1); + nj + 1, atc[nj] + 1); warning_error_and_exit(wi, message, FARGS); } break; @@ -2438,13 +2420,12 @@ void push_vsitesn(Directive d, gmx::ArrayRef bond, weight_tot += weight[nj]; nj++; } - } - while (ret > 0); + } while (ret > 0); if (nj == 0) { - auto message = gmx::formatString("Expected more than one atom index in section \"%s\"", - dir2str(d)); + auto message = + gmx::formatString("Expected more than one atom index in section \"%s\"", dir2str(d)); warning_error_and_exit(wi, message, FARGS); } @@ -2455,20 +2436,18 @@ void push_vsitesn(Directive d, gmx::ArrayRef bond, for (int j = 0; j < nj; j++) { - std::vector atoms = {firstAtom, atc[j]}; - forceParam[0] = nj; - forceParam[1] = weight[j]/weight_tot; + std::vector atoms = { firstAtom, atc[j] }; + forceParam[0] = nj; + forceParam[1] = weight[j] / weight_tot; /* Put the values in the appropriate arrays */ - add_param_to_list (&bond[ftype], InteractionOfType(atoms, forceParam)); + add_param_to_list(&bond[ftype], InteractionOfType(atoms, forceParam)); } sfree(atc); sfree(weight); } -void push_mol(gmx::ArrayRef mols, char *pline, int *whichmol, - int *nrcopies, - warninp *wi) +void push_mol(gmx::ArrayRef mols, char* pline, int* whichmol, int* nrcopies, warninp* wi) { char type[STRLEN]; @@ -2489,7 +2468,7 @@ void push_mol(gmx::ArrayRef mols, char *pline, int *whichmo int matchci = -1; int matchcs = -1; int i = 0; - for (const auto &mol : mols) + for (const auto& mol : mols) { if (strcmp(type, *(mol.name)) == 0) { @@ -2514,8 +2493,8 @@ void push_mol(gmx::ArrayRef mols, char *pline, int *whichmo // avoid matching case-insensitive when we have multiple matches if (nrci > 1) { - auto message = gmx::formatString - ("For moleculetype '%s' in [ system ] %d case insensitive " + auto message = gmx::formatString( + "For moleculetype '%s' in [ system ] %d case insensitive " "matches, but %d case sensitive matches were found. Check " "the case of the characters in the moleculetypes.", type, nrci, nrcs); @@ -2534,7 +2513,7 @@ void push_mol(gmx::ArrayRef mols, char *pline, int *whichmo } } -void push_excl(char *line, gmx::ArrayRef b2, warninp *wi) +void push_excl(char* line, gmx::ArrayRef b2, warninp* wi) { int i, j; int n; @@ -2575,15 +2554,13 @@ void push_excl(char *line, gmx::ArrayRef b2, warninp *wi) warning_error_and_exit(wi, message, FARGS); } } - } - while (n == 1); + } while (n == 1); } -int add_atomtype_decoupled(t_symtab *symtab, PreprocessingAtomTypes *at, - t_nbparam ***nbparam, t_nbparam ***pair) +int add_atomtype_decoupled(t_symtab* symtab, PreprocessingAtomTypes* at, t_nbparam*** nbparam, t_nbparam*** pair) { - t_atom atom; - int nr; + t_atom atom; + int nr; /* Define an atom type with all parameters set to zero (no interactions) */ atom.q = 0.0; @@ -2593,7 +2570,7 @@ int add_atomtype_decoupled(t_symtab *symtab, PreprocessingAtomTypes *at, */ atom.ptype = eptAtom; - std::array forceParam = {0.0}; + std::array forceParam = { 0.0 }; nr = at->addType(symtab, atom, "decoupled", InteractionOfType({}, forceParam, ""), -1, 0); /* Add space in the non-bonded parameters matrix */ @@ -2602,11 +2579,10 @@ int add_atomtype_decoupled(t_symtab *symtab, PreprocessingAtomTypes *at, return nr; } -static void convert_pairs_to_pairsQ(gmx::ArrayRef interactions, - real fudgeQQ, t_atoms *atoms) +static void convert_pairs_to_pairsQ(gmx::ArrayRef interactions, real fudgeQQ, t_atoms* atoms) { /* Add the pair list to the pairQ list */ - std::vector paramnew; + std::vector paramnew; gmx::ArrayRef paramp1 = interactions[F_LJ14].interactionTypes; gmx::ArrayRef paramp2 = interactions[F_LJC14_Q].interactionTypes; @@ -2618,48 +2594,47 @@ static void convert_pairs_to_pairsQ(gmx::ArrayRef interactio */ - for (const auto ¶m : paramp2) + for (const auto& param : paramp2) { paramnew.emplace_back(param); } - for (const auto ¶m : paramp1) + for (const auto& param : paramp1) { - std::vector forceParam = { - fudgeQQ, atoms->atom[param.ai()].q, atoms->atom[param.aj()].q, - param.c0(), param.c1() - }; + std::vector forceParam = { fudgeQQ, atoms->atom[param.ai()].q, + atoms->atom[param.aj()].q, param.c0(), param.c1() }; paramnew.emplace_back(InteractionOfType(param.atoms(), forceParam, "")); } /* now assign the new data to the F_LJC14_Q structure */ - interactions[F_LJC14_Q].interactionTypes = paramnew; + interactions[F_LJC14_Q].interactionTypes = paramnew; /* Empty the LJ14 pairlist */ interactions[F_LJ14].interactionTypes.clear(); } -static void generate_LJCpairsNB(MoleculeInformation *mol, int nb_funct, InteractionsOfType *nbp, warninp *wi) +static void generate_LJCpairsNB(MoleculeInformation* mol, int nb_funct, InteractionsOfType* nbp, warninp* wi) { - int n, ntype; - t_atom *atom; - t_blocka *excl; - bool bExcl; + int n, ntype; + t_atom* atom; + t_blocka* excl; + bool bExcl; n = mol->atoms.nr; atom = mol->atoms.atom; ntype = static_cast(std::sqrt(static_cast(nbp->size()))); - GMX_ASSERT(ntype * ntype == gmx::ssize(*nbp), "Number of pairs of generated non-bonded parameters should be a perfect square"); + GMX_ASSERT(ntype * ntype == gmx::ssize(*nbp), + "Number of pairs of generated non-bonded parameters should be a perfect square"); /* Add a pair interaction for all non-excluded atom pairs */ excl = &mol->excls; for (int i = 0; i < n; i++) { - for (int j = i+1; j < n; j++) + for (int j = i + 1; j < n; j++) { bExcl = FALSE; - for (int k = excl->index[i]; k < excl->index[i+1]; k++) + for (int k = excl->index[i]; k < excl->index[i + 1]; k++) { if (excl->a[k] == j) { @@ -2670,17 +2645,15 @@ static void generate_LJCpairsNB(MoleculeInformation *mol, int nb_funct, Interact { if (nb_funct != F_LJ) { - auto message = gmx::formatString - ("Can only generate non-bonded pair interactions " + auto message = gmx::formatString( + "Can only generate non-bonded pair interactions " "for Van der Waals type Lennard-Jones"); warning_error_and_exit(wi, message, FARGS); } - std::vector atoms = {i, j}; + std::vector atoms = { i, j }; std::vector forceParam = { - atom[i].q, - atom[j].q, - nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c0(), - nbp->interactionTypes[ntype*atom[i].type+atom[j].type].c1() + atom[i].q, atom[j].q, nbp->interactionTypes[ntype * atom[i].type + atom[j].type].c0(), + nbp->interactionTypes[ntype * atom[i].type + atom[j].type].c1() }; add_param_to_list(&mol->interactions[F_LJC_PAIRS_NB], InteractionOfType(atoms, forceParam)); } @@ -2688,13 +2661,13 @@ static void generate_LJCpairsNB(MoleculeInformation *mol, int nb_funct, Interact } } -static void set_excl_all(t_blocka *excl) +static void set_excl_all(t_blocka* excl) { int nat, i, j, k; /* Get rid of the current exclusions and exclude all atom pairs */ nat = excl->nr; - excl->nra = nat*nat; + excl->nra = nat * nat; srenew(excl->a, excl->nra); k = 0; for (i = 0; i < nat; i++) @@ -2708,22 +2681,25 @@ static void set_excl_all(t_blocka *excl) excl->index[nat] = k; } -static void decouple_atoms(t_atoms *atoms, int atomtype_decouple, - int couple_lam0, int couple_lam1, - const char *mol_name, warninp *wi) +static void decouple_atoms(t_atoms* atoms, + int atomtype_decouple, + int couple_lam0, + int couple_lam1, + const char* mol_name, + warninp* wi) { - int i; + int i; for (i = 0; i < atoms->nr; i++) { - t_atom *atom; + t_atom* atom; atom = &atoms->atom[i]; if (atom->qB != atom->q || atom->typeB != atom->type) { - auto message = gmx::formatString - ("Atom %d in molecule type '%s' has different A and B state " + auto message = gmx::formatString( + "Atom %d in molecule type '%s' has different A and B state " "charges and/or atom types set in the topology file as well " "as through the mdp option '%s'. You can not use both " "these methods simultaneously.", @@ -2733,15 +2709,15 @@ static void decouple_atoms(t_atoms *atoms, int atomtype_decouple, if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamVDW) { - atom->q = 0.0; + atom->q = 0.0; } if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamQ) { - atom->type = atomtype_decouple; + atom->type = atomtype_decouple; } if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamVDW) { - atom->qB = 0.0; + atom->qB = 0.0; } if (couple_lam1 == ecouplamNONE || couple_lam1 == ecouplamQ) { @@ -2750,10 +2726,15 @@ static void decouple_atoms(t_atoms *atoms, int atomtype_decouple, } } -void convert_moltype_couple(MoleculeInformation *mol, int atomtype_decouple, real fudgeQQ, - int couple_lam0, int couple_lam1, - bool bCoupleIntra, int nb_funct, InteractionsOfType *nbp, - warninp *wi) +void convert_moltype_couple(MoleculeInformation* mol, + int atomtype_decouple, + real fudgeQQ, + int couple_lam0, + int couple_lam1, + bool bCoupleIntra, + int nb_funct, + InteractionsOfType* nbp, + warninp* wi) { convert_pairs_to_pairsQ(mol->interactions, fudgeQQ, &mol->atoms); if (!bCoupleIntra) @@ -2761,6 +2742,5 @@ void convert_moltype_couple(MoleculeInformation *mol, int atomtype_decouple, rea generate_LJCpairsNB(mol, nb_funct, nbp, wi); set_excl_all(&mol->excls); } - decouple_atoms(&mol->atoms, atomtype_decouple, couple_lam0, couple_lam1, - *mol->name, wi); + decouple_atoms(&mol->atoms, atomtype_decouple, couple_lam0, couple_lam1, *mol->name, wi); } diff --git a/src/gromacs/gmxpreprocess/toppush.h b/src/gromacs/gmxpreprocess/toppush.h index 8982cfcd52..bd0f13c269 100644 --- a/src/gromacs/gmxpreprocess/toppush.h +++ b/src/gromacs/gmxpreprocess/toppush.h @@ -60,79 +60,93 @@ namespace gmx struct ExclusionBlock; } // namespace gmx -void generate_nbparams(int comb, int funct, InteractionsOfType *plist, - PreprocessingAtomTypes *atype, - warninp *wi); - -void push_at (struct t_symtab *symtab, PreprocessingAtomTypes *at, - PreprocessingBondAtomType *bat, char *line, int nb_funct, - t_nbparam ***nbparam, t_nbparam ***pair, - warninp *wi); - -void push_bt(Directive d, gmx::ArrayRef bt, int nral, - PreprocessingAtomTypes *at, PreprocessingBondAtomType *bat, char *line, - warninp *wi); - -void push_dihedraltype(Directive d, gmx::ArrayRef bt, - PreprocessingBondAtomType *bat, char *line, - warninp *wi); - -void push_cmaptype(Directive d, gmx::ArrayRef bt, int nral, PreprocessingAtomTypes *at, - PreprocessingBondAtomType *bat, char *line, - warninp *wi); - -void push_nbt(Directive d, t_nbparam **nbt, PreprocessingAtomTypes *atype, - char *plines, int nb_funct, - warninp *wi); - -void push_atom(struct t_symtab *symtab, - t_atoms *at, - PreprocessingAtomTypes *atype, - char *line, - warninp *wi); - -void push_bond(Directive d, gmx::ArrayRef bondtype, +void generate_nbparams(int comb, int funct, InteractionsOfType* plist, PreprocessingAtomTypes* atype, warninp* wi); + +void push_at(struct t_symtab* symtab, + PreprocessingAtomTypes* at, + PreprocessingBondAtomType* bat, + char* line, + int nb_funct, + t_nbparam*** nbparam, + t_nbparam*** pair, + warninp* wi); + +void push_bt(Directive d, + gmx::ArrayRef bt, + int nral, + PreprocessingAtomTypes* at, + PreprocessingBondAtomType* bat, + char* line, + warninp* wi); + +void push_dihedraltype(Directive d, + gmx::ArrayRef bt, + PreprocessingBondAtomType* bat, + char* line, + warninp* wi); + +void push_cmaptype(Directive d, + gmx::ArrayRef bt, + int nral, + PreprocessingAtomTypes* at, + PreprocessingBondAtomType* bat, + char* line, + warninp* wi); + +void push_nbt(Directive d, t_nbparam** nbt, PreprocessingAtomTypes* atype, char* plines, int nb_funct, warninp* wi); + +void push_atom(struct t_symtab* symtab, t_atoms* at, PreprocessingAtomTypes* atype, char* line, warninp* wi); + +void push_bond(Directive d, + gmx::ArrayRef bondtype, gmx::ArrayRef bond, - t_atoms *at, PreprocessingAtomTypes *atype, char *line, - bool bBonded, bool bGenPairs, real fudgeQQ, - bool bZero, bool *bWarn_copy_A_B, - warninp *wi); - -void push_cmap(Directive d, + t_atoms* at, + PreprocessingAtomTypes* atype, + char* line, + bool bBonded, + bool bGenPairs, + real fudgeQQ, + bool bZero, + bool* bWarn_copy_A_B, + warninp* wi); + +void push_cmap(Directive d, gmx::ArrayRef bondtype, gmx::ArrayRef bond, - t_atoms *at, PreprocessingAtomTypes *atype, char *line, - warninp *wi); + t_atoms* at, + PreprocessingAtomTypes* atype, + char* line, + warninp* wi); -void push_vsitesn(Directive d, gmx::ArrayRef bond, - t_atoms *at, char *line, - warninp *wi); +void push_vsitesn(Directive d, gmx::ArrayRef bond, t_atoms* at, char* line, warninp* wi); -void push_mol(gmx::ArrayRef mols, char *pline, - int *whichmol, int *nrcopies, - warninp *wi); +void push_mol(gmx::ArrayRef mols, char* pline, int* whichmol, int* nrcopies, warninp* wi); -void push_molt(struct t_symtab *symtab, std::vector *mol, char *line, - warninp *wi); +void push_molt(struct t_symtab* symtab, std::vector* mol, char* line, warninp* wi); -void push_excl(char *line, gmx::ArrayRef b2, warninp *wi); +void push_excl(char* line, gmx::ArrayRef b2, warninp* wi); -int copy_nbparams(t_nbparam **param, int ftype, InteractionsOfType *plist, int nr); +int copy_nbparams(t_nbparam** param, int ftype, InteractionsOfType* plist, int nr); -void free_nbparam(t_nbparam **param, int nr); +void free_nbparam(t_nbparam** param, int nr); -int add_atomtype_decoupled(struct t_symtab *symtab, PreprocessingAtomTypes *at, - t_nbparam ***nbparam, t_nbparam ***pair); +int add_atomtype_decoupled(struct t_symtab* symtab, + PreprocessingAtomTypes* at, + t_nbparam*** nbparam, + t_nbparam*** pair); /* Add an atom type with all parameters set to zero (no interactions). * Returns the atom type number. */ -void convert_moltype_couple(MoleculeInformation *mol, int atomtype_decouple, - real fudgeQQ, - int couple_lam0, int couple_lam1, - bool bCoupleIntra, - int nb_funct, InteractionsOfType *nbp, - warninp *wi); +void convert_moltype_couple(MoleculeInformation* mol, + int atomtype_decouple, + real fudgeQQ, + int couple_lam0, + int couple_lam1, + bool bCoupleIntra, + int nb_funct, + InteractionsOfType* nbp, + warninp* wi); /* Setup mol such that the B-state has no interaction with the rest * of the system, but full interaction with itself. */ diff --git a/src/gromacs/gmxpreprocess/topshake.cpp b/src/gromacs/gmxpreprocess/topshake.cpp index 37c25fabd3..4851e85c2c 100644 --- a/src/gromacs/gmxpreprocess/topshake.cpp +++ b/src/gromacs/gmxpreprocess/topshake.cpp @@ -53,14 +53,13 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static int count_hydrogens (char ***atomname, int nra, gmx::ArrayRef a) +static int count_hydrogens(char*** atomname, int nra, gmx::ArrayRef a) { - int nh; + int nh; if (!atomname) { - gmx_fatal(FARGS, "Cannot call count_hydrogens with no atomname (%s %d)", - __FILE__, __LINE__); + gmx_fatal(FARGS, "Cannot call count_hydrogens with no atomname (%s %d)", __FILE__, __LINE__); } nh = 0; @@ -75,28 +74,19 @@ static int count_hydrogens (char ***atomname, int nra, gmx::ArrayRef return nh; } -void make_shake(gmx::ArrayRef plist, t_atoms *atoms, int nshake) +void make_shake(gmx::ArrayRef plist, t_atoms* atoms, int nshake) { - char ***info = atoms->atomname; - real b_ij, b_jk; + char*** info = atoms->atomname; + real b_ij, b_jk; if (nshake != eshNONE) { switch (nshake) { - case eshHBONDS: - printf("turning H bonds into constraints...\n"); - break; - case eshALLBONDS: - printf("turning all bonds into constraints...\n"); - break; - case eshHANGLES: - printf("turning all bonds and H angles into constraints...\n"); - break; - case eshALLANGLES: - printf("turning all bonds and angles into constraints...\n"); - break; - default: - gmx_fatal(FARGS, "Invalid option for make_shake (%d)", nshake); + case eshHBONDS: printf("turning H bonds into constraints...\n"); break; + case eshALLBONDS: printf("turning all bonds into constraints...\n"); break; + case eshHANGLES: printf("turning all bonds and H angles into constraints...\n"); break; + case eshALLANGLES: printf("turning all bonds and angles into constraints...\n"); break; + default: gmx_fatal(FARGS, "Invalid option for make_shake (%d)", nshake); } if ((nshake == eshHANGLES) || (nshake == eshALLANGLES)) @@ -108,47 +98,43 @@ void make_shake(gmx::ArrayRef plist, t_atoms *atoms, int nsh { if (interaction_function[ftype].flags & IF_CHEMBOND) { - InteractionsOfType *bonds = &(plist[ftype]); + InteractionsOfType* bonds = &(plist[ftype]); for (int ftype_a = 0; (gmx::ssize(*bonds) > 0 && ftype_a < F_NRE); ftype_a++) { if (interaction_function[ftype_a].flags & IF_ATYPE) { - InteractionsOfType *pr = &(plist[ftype_a]); + InteractionsOfType* pr = &(plist[ftype_a]); - for (auto parm = pr->interactionTypes.begin(); parm != pr->interactionTypes.end(); ) + for (auto parm = pr->interactionTypes.begin(); + parm != pr->interactionTypes.end();) { - const InteractionOfType *ang = &(*parm); + const InteractionOfType* ang = &(*parm); #ifdef DEBUG printf("Angle: %d-%d-%d\n", ang->ai(), ang->aj(), ang->ak()); #endif int numhydrogens = count_hydrogens(info, 3, ang->atoms()); - if ((nshake == eshALLANGLES) || - (numhydrogens > 1) || - (numhydrogens == 1 && toupper(**(info[ang->aj()])) == 'O')) + if ((nshake == eshALLANGLES) || (numhydrogens > 1) + || (numhydrogens == 1 && toupper(**(info[ang->aj()])) == 'O')) { /* Can only add hydrogen angle shake, if the two bonds * are constrained. * append this angle to the shake list */ - std::vector atomNumbers = {ang->ai(), ang->ak()}; + std::vector atomNumbers = { ang->ai(), ang->ak() }; /* Calculate length of constraint */ bool bFound = false; - b_ij = b_jk = 0.0; - for (const auto &bond : bonds->interactionTypes) + b_ij = b_jk = 0.0; + for (const auto& bond : bonds->interactionTypes) { - if (((bond.ai() == ang->ai()) && - (bond.aj() == ang->aj())) || - ((bond.ai() == ang->aj()) && - (bond.aj() == ang->ai()))) + if (((bond.ai() == ang->ai()) && (bond.aj() == ang->aj())) + || ((bond.ai() == ang->aj()) && (bond.aj() == ang->ai()))) { b_ij = bond.c0(); } - if (((bond.ai() == ang->ak()) && - (bond.aj() == ang->aj())) || - ((bond.ai() == ang->aj()) && - (bond.aj() == ang->ak()))) + if (((bond.ai() == ang->ak()) && (bond.aj() == ang->aj())) + || ((bond.ai() == ang->aj()) && (bond.aj() == ang->ak()))) { b_jk = bond.c0(); } @@ -156,13 +142,15 @@ void make_shake(gmx::ArrayRef plist, t_atoms *atoms, int nsh } if (bFound) { - real param = std::sqrt( b_ij*b_ij + b_jk*b_jk - - 2.0*b_ij*b_jk*cos(DEG2RAD*ang->c0())); - std::vector forceParm = {param, param}; - if (ftype == F_CONNBONDS || - ftype_a == F_CONNBONDS) + real param = std::sqrt(b_ij * b_ij + b_jk * b_jk + - 2.0 * b_ij * b_jk + * cos(DEG2RAD * ang->c0())); + std::vector forceParm = { param, param }; + if (ftype == F_CONNBONDS || ftype_a == F_CONNBONDS) { - gmx_fatal(FARGS, "Can not constrain all angles when they involved bonds of type %s", + gmx_fatal(FARGS, + "Can not constrain all angles when they " + "involved bonds of type %s", interaction_function[F_CONNBONDS].longname); } /* apply law of cosines */ @@ -170,7 +158,8 @@ void make_shake(gmx::ArrayRef plist, t_atoms *atoms, int nsh printf("p: %d, q: %d, dist: %12.5e\n", atomNumbers[0], atomNumbers[1], forceParm[0]); #endif - add_param_to_list (&(plist[F_CONSTR]), InteractionOfType(atomNumbers, forceParm)); + add_param_to_list(&(plist[F_CONSTR]), + InteractionOfType(atomNumbers, forceParm)); /* move the last bond to this position */ *parm = *(pr->interactionTypes.end() - 1); pr->interactionTypes.erase(pr->interactionTypes.end() - 1); @@ -194,16 +183,15 @@ void make_shake(gmx::ArrayRef plist, t_atoms *atoms, int nsh { if (interaction_function[ftype].flags & IF_BTYPE) { - InteractionsOfType *pr = &(plist[ftype]); - for (auto parm = pr->interactionTypes.begin(); parm != pr->interactionTypes.end(); ) + InteractionsOfType* pr = &(plist[ftype]); + for (auto parm = pr->interactionTypes.begin(); parm != pr->interactionTypes.end();) { - if ( (nshake != eshHBONDS) || - (count_hydrogens (info, 2, parm->atoms()) > 0) ) + if ((nshake != eshHBONDS) || (count_hydrogens(info, 2, parm->atoms()) > 0)) { /* append this bond to the shake list */ - std::vector atomNumbers = {parm->ai(), parm->aj()}; - std::vector forceParm = { parm->c0(), parm->c2()}; - add_param_to_list (&(plist[F_CONSTR]), InteractionOfType(atomNumbers, forceParm)); + std::vector atomNumbers = { parm->ai(), parm->aj() }; + std::vector forceParm = { parm->c0(), parm->c2() }; + add_param_to_list(&(plist[F_CONSTR]), InteractionOfType(atomNumbers, forceParm)); parm = pr->interactionTypes.erase(parm); } else diff --git a/src/gromacs/gmxpreprocess/topshake.h b/src/gromacs/gmxpreprocess/topshake.h index 7f2d57fe08..db9f9b2200 100644 --- a/src/gromacs/gmxpreprocess/topshake.h +++ b/src/gromacs/gmxpreprocess/topshake.h @@ -43,6 +43,6 @@ struct t_atoms; struct InteractionsOfType; -void make_shake (gmx::ArrayRef plist, t_atoms *atoms, int nshake); +void make_shake(gmx::ArrayRef plist, t_atoms* atoms, int nshake); #endif diff --git a/src/gromacs/gmxpreprocess/toputil.cpp b/src/gromacs/gmxpreprocess/toputil.cpp index eadf902474..6ccc4d3620 100644 --- a/src/gromacs/gmxpreprocess/toputil.cpp +++ b/src/gromacs/gmxpreprocess/toputil.cpp @@ -57,25 +57,29 @@ /* UTILITIES */ -void add_param_to_list(InteractionsOfType *list, const InteractionOfType &b) +void add_param_to_list(InteractionsOfType* list, const InteractionOfType& b) { list->interactionTypes.emplace_back(b); } /* PRINTING STRUCTURES */ -static void print_bt(FILE *out, Directive d, PreprocessingAtomTypes *at, - int ftype, int fsubtype, gmx::ArrayRef plist, - bool bFullDih) +static void print_bt(FILE* out, + Directive d, + PreprocessingAtomTypes* at, + int ftype, + int fsubtype, + gmx::ArrayRef plist, + bool bFullDih) { /* This dihp is a DIRTY patch because the dih-types do not use * all four atoms to determine the type. */ - const int dihp[2][2] = { { 1, 2 }, { 0, 3 } }; - int nral, nrfp; - bool bDih = false, bSwapParity; + const int dihp[2][2] = { { 1, 2 }, { 0, 3 } }; + int nral, nrfp; + bool bDih = false, bSwapParity; - const InteractionsOfType *bt = &(plist[ftype]); + const InteractionsOfType* bt = &(plist[ftype]); if (bt->size() == 0) { @@ -85,63 +89,30 @@ static void print_bt(FILE *out, Directive d, PreprocessingAtomTypes *at, int f = 0; switch (ftype) { - case F_G96ANGLES: - f = 1; - break; - case F_G96BONDS: - f = 1; - break; - case F_MORSE: - f = 2; - break; - case F_CUBICBONDS: - f = 3; - break; - case F_CONNBONDS: - f = 4; - break; - case F_HARMONIC: - f = 5; - break; - case F_CROSS_BOND_ANGLES: - f = 2; - break; - case F_CROSS_BOND_BONDS: - f = 3; - break; - case F_UREY_BRADLEY: - f = 4; - break; + case F_G96ANGLES: f = 1; break; + case F_G96BONDS: f = 1; break; + case F_MORSE: f = 2; break; + case F_CUBICBONDS: f = 3; break; + case F_CONNBONDS: f = 4; break; + case F_HARMONIC: f = 5; break; + case F_CROSS_BOND_ANGLES: f = 2; break; + case F_CROSS_BOND_BONDS: f = 3; break; + case F_UREY_BRADLEY: f = 4; break; case F_PDIHS: case F_RBDIHS: - case F_FOURDIHS: - bDih = TRUE; - break; + case F_FOURDIHS: bDih = TRUE; break; case F_IDIHS: f = 1; bDih = TRUE; break; - case F_CONSTRNC: - f = 1; - break; - case F_VSITE3FD: - f = 1; - break; - case F_VSITE3FAD: - f = 2; - break; - case F_VSITE3OUT: - f = 3; - break; - case F_VSITE4FDN: - f = 1; - break; - case F_CMAP: - f = 1; - break; - - default: - bDih = FALSE; + case F_CONSTRNC: f = 1; break; + case F_VSITE3FD: f = 1; break; + case F_VSITE3FAD: f = 2; break; + case F_VSITE3OUT: f = 3; break; + case F_VSITE4FDN: f = 1; break; + case F_CMAP: f = 1; break; + + default: bDih = FALSE; } if (bFullDih) { @@ -149,7 +120,7 @@ static void print_bt(FILE *out, Directive d, PreprocessingAtomTypes *at, } if (fsubtype) { - f = fsubtype-1; + f = fsubtype - 1; } nral = NRAL(ftype); @@ -160,47 +131,47 @@ static void print_bt(FILE *out, Directive d, PreprocessingAtomTypes *at, fprintf(out, "; "); if (!bDih) { - fprintf (out, "%3s %4s", "ai", "aj"); + fprintf(out, "%3s %4s", "ai", "aj"); for (int j = 2; (j < nral); j++) { - fprintf (out, " %3c%c", 'a', 'i'+j); + fprintf(out, " %3c%c", 'a', 'i' + j); } } else { for (int j = 0; (j < 2); j++) { - fprintf (out, "%3c%c", 'a', 'i'+dihp[f][j]); + fprintf(out, "%3c%c", 'a', 'i' + dihp[f][j]); } } - fprintf (out, " funct"); + fprintf(out, " funct"); for (int j = 0; (j < nrfp); j++) { - fprintf (out, " %12c%1d", 'c', j); + fprintf(out, " %12c%1d", 'c', j); } - fprintf (out, "\n"); + fprintf(out, "\n"); /* print bondtypes */ - for (const auto &parm : bt->interactionTypes) + for (const auto& parm : bt->interactionTypes) { - bSwapParity = (parm.c0() == NOTSET) && (parm.c1() == -1); + bSwapParity = (parm.c0() == NOTSET) && (parm.c1() == -1); gmx::ArrayRef atoms = parm.atoms(); if (!bDih) { for (int j = 0; (j < nral); j++) { - fprintf (out, "%5s ", at->atomNameFromAtomType(atoms[j])); + fprintf(out, "%5s ", at->atomNameFromAtomType(atoms[j])); } } else { for (int j = 0; (j < 2); j++) { - fprintf (out, "%5s ", at->atomNameFromAtomType(atoms[dihp[f][j]])); + fprintf(out, "%5s ", at->atomNameFromAtomType(atoms[dihp[f][j]])); } } - fprintf (out, "%5d ", bSwapParity ? -f-1 : f+1); + fprintf(out, "%5d ", bSwapParity ? -f - 1 : f + 1); if (!parm.interactionTypeName().empty()) { @@ -211,21 +182,21 @@ static void print_bt(FILE *out, Directive d, PreprocessingAtomTypes *at, gmx::ArrayRef forceParam = parm.forceParam(); for (int j = 0; (j < nrfp) && (forceParam[j] != NOTSET); j++) { - fprintf (out, "%13.6e ", forceParam[j]); + fprintf(out, "%13.6e ", forceParam[j]); } } - fprintf (out, "\n"); + fprintf(out, "\n"); } - fprintf (out, "\n"); - fflush (out); + fprintf(out, "\n"); + fflush(out); } -void print_excl(FILE *out, int natoms, t_excls excls[]) +void print_excl(FILE* out, int natoms, t_excls excls[]) { - int i; - bool have_excl; - int j; + int i; + bool have_excl; + int j; have_excl = FALSE; for (i = 0; i < natoms && !have_excl; i++) @@ -235,26 +206,26 @@ void print_excl(FILE *out, int natoms, t_excls excls[]) if (have_excl) { - fprintf (out, "[ %s ]\n", dir2str(Directive::d_exclusions)); - fprintf (out, "; %4s %s\n", "i", "excluded from i"); + fprintf(out, "[ %s ]\n", dir2str(Directive::d_exclusions)); + fprintf(out, "; %4s %s\n", "i", "excluded from i"); for (i = 0; i < natoms; i++) { if (excls[i].nr > 0) { - fprintf (out, "%6d ", i+1); + fprintf(out, "%6d ", i + 1); for (j = 0; j < excls[i].nr; j++) { - fprintf (out, " %5d", excls[i].e[j]+1); + fprintf(out, " %5d", excls[i].e[j] + 1); } - fprintf (out, "\n"); + fprintf(out, "\n"); } } - fprintf (out, "\n"); + fprintf(out, "\n"); fflush(out); } } -static double get_residue_charge(const t_atoms *atoms, int at) +static double get_residue_charge(const t_atoms* atoms, int at) { int ri; double q; @@ -270,21 +241,20 @@ static double get_residue_charge(const t_atoms *atoms, int at) return q; } -void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgnr, - bool bRTPresname) +void print_atoms(FILE* out, PreprocessingAtomTypes* atype, t_atoms* at, int* cgnr, bool bRTPresname) { - int i, ri; - int tpA, tpB; - const char *as; - const char *tpnmA, *tpnmB; - double qres, qtot; + int i, ri; + int tpA, tpB; + const char* as; + const char *tpnmA, *tpnmB; + double qres, qtot; as = dir2str(Directive::d_atoms); fprintf(out, "[ %s ]\n", as); - fprintf(out, "; %4s %10s %6s %7s%6s %6s %10s %10s %6s %10s %10s\n", - "nr", "type", "resnr", "residue", "atom", "cgnr", "charge", "mass", "typeB", "chargeB", "massB"); + fprintf(out, "; %4s %10s %6s %7s%6s %6s %10s %10s %6s %10s %10s\n", "nr", "type", "resnr", + "residue", "atom", "cgnr", "charge", "mass", "typeB", "chargeB", "massB"); - qtot = 0; + qtot = 0; if (at->nres) { @@ -292,14 +262,11 @@ void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgn for (i = 0; (i < at->nr); i++) { ri = at->atom[i].resind; - if ((i == 0 || ri != at->atom[i-1].resind) && - at->resinfo[ri].rtp != nullptr) + if ((i == 0 || ri != at->atom[i - 1].resind) && at->resinfo[ri].rtp != nullptr) { qres = get_residue_charge(at, i); - fprintf(out, "; residue %3d %-3s rtp %-4s q ", - at->resinfo[ri].nr, - *at->resinfo[ri].name, - *at->resinfo[ri].rtp); + fprintf(out, "; residue %3d %-3s rtp %-4s q ", at->resinfo[ri].nr, + *at->resinfo[ri].name, *at->resinfo[ri].rtp); if (fabs(qres) < 0.001) { fprintf(out, " %s", "0.0"); @@ -317,16 +284,13 @@ void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgn } /* This is true by construction, but static analysers don't know */ - GMX_ASSERT(!bRTPresname || at->resinfo[at->atom[i].resind].rtp, "-rtpres did not have residue name available"); - fprintf(out, "%6d %10s %6d%c %5s %6s %6d %10g %10g", - i+1, tpnmA, - at->resinfo[ri].nr, + GMX_ASSERT(!bRTPresname || at->resinfo[at->atom[i].resind].rtp, + "-rtpres did not have residue name available"); + fprintf(out, "%6d %10s %6d%c %5s %6s %6d %10g %10g", i + 1, tpnmA, at->resinfo[ri].nr, at->resinfo[ri].ic, - bRTPresname ? - *(at->resinfo[at->atom[i].resind].rtp) : - *(at->resinfo[at->atom[i].resind].name), - *(at->atomname[i]), cgnr[i], - at->atom[i].q, at->atom[i].m); + bRTPresname ? *(at->resinfo[at->atom[i].resind].rtp) + : *(at->resinfo[at->atom[i].resind].name), + *(at->atomname[i]), cgnr[i], at->atom[i].q, at->atom[i].m); if (PERTURBED(at->atom[i])) { tpB = at->atom[i].typeB; @@ -334,8 +298,7 @@ void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgn { gmx_fatal(FARGS, "tpB = %d, i= %d in print_atoms", tpB, i); } - fprintf(out, " %6s %10g %10g", - tpnmB, at->atom[i].qB, at->atom[i].mB); + fprintf(out, " %6s %10g %10g", tpnmB, at->atom[i].qB, at->atom[i].mB); } // Accumulate the total charge to help troubleshoot issues. qtot += static_cast(at->atom[i].q); @@ -348,7 +311,7 @@ void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgn // Write the total charge for the last atom of the system // and/or residue, because generally that's where it is // expected to be an integer. - if (i == at->nr-1 || ri != at->atom[i+1].resind) + if (i == at->nr - 1 || ri != at->atom[i + 1].resind) { fprintf(out, " ; qtot %.4g\n", qtot); } @@ -362,11 +325,10 @@ void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgn fflush(out); } -void print_bondeds(FILE *out, int natoms, Directive d, - int ftype, int fsubtype, gmx::ArrayRef plist) +void print_bondeds(FILE* out, int natoms, Directive d, int ftype, int fsubtype, gmx::ArrayRef plist) { - t_symtab stab; - t_atom *a; + t_symtab stab; + t_atom* a; PreprocessingAtomTypes atype; snew(a, 1); @@ -374,7 +336,7 @@ void print_bondeds(FILE *out, int natoms, Directive d, for (int i = 0; (i < natoms); i++) { char buf[12]; - sprintf(buf, "%4d", (i+1)); + sprintf(buf, "%4d", (i + 1)); atype.addType(&stab, *a, buf, InteractionOfType({}, {}), 0, 0); } print_bt(out, d, &atype, ftype, fsubtype, plist, TRUE); diff --git a/src/gromacs/gmxpreprocess/toputil.h b/src/gromacs/gmxpreprocess/toputil.h index b24c48f327..829929bd46 100644 --- a/src/gromacs/gmxpreprocess/toputil.h +++ b/src/gromacs/gmxpreprocess/toputil.h @@ -55,16 +55,19 @@ struct InteractionsOfType; /* UTILITIES */ -void add_param_to_list(InteractionsOfType *list, const InteractionOfType &b); +void add_param_to_list(InteractionsOfType* list, const InteractionOfType& b); /* PRINTING */ -void print_atoms(FILE *out, PreprocessingAtomTypes *atype, t_atoms *at, int *cgnr, - bool bRTPresname); +void print_atoms(FILE* out, PreprocessingAtomTypes* atype, t_atoms* at, int* cgnr, bool bRTPresname); -void print_bondeds(FILE *out, int natoms, Directive d, - int ftype, int fsubtype, gmx::ArrayRef plist); +void print_bondeds(FILE* out, + int natoms, + Directive d, + int ftype, + int fsubtype, + gmx::ArrayRef plist); -void print_excl(FILE *out, int natoms, t_excls excls[]); +void print_excl(FILE* out, int natoms, t_excls excls[]); #endif diff --git a/src/gromacs/gmxpreprocess/vsite_parm.cpp b/src/gromacs/gmxpreprocess/vsite_parm.cpp index a54f64b0ff..c57f446029 100644 --- a/src/gromacs/gmxpreprocess/vsite_parm.cpp +++ b/src/gromacs/gmxpreprocess/vsite_parm.cpp @@ -70,35 +70,34 @@ */ class VsiteBondedInteraction { - public: - //! Constructor initializes datastructure. - VsiteBondedInteraction(gmx::ArrayRef atomIndex, - real parameterValue) - : parameterValue_(parameterValue) +public: + //! Constructor initializes datastructure. + VsiteBondedInteraction(gmx::ArrayRef atomIndex, real parameterValue) : + parameterValue_(parameterValue) + { + GMX_RELEASE_ASSERT(atomIndex.size() <= atomIndex_.size(), + "Cannot add more atom indices than maximum number"); + auto atomIndexIt = atomIndex_.begin(); + for (const auto index : atomIndex) { - GMX_RELEASE_ASSERT(atomIndex.size() <= atomIndex_.size(), - "Cannot add more atom indices than maximum number"); - auto atomIndexIt = atomIndex_.begin(); - for (const auto index : atomIndex) - { - *atomIndexIt++ = index; - } + *atomIndexIt++ = index; } - /*!@{*/ - //! Access the individual elements set for the vsite bonded interaction. - const int &ai() const { return atomIndex_[0]; } - const int &aj() const { return atomIndex_[1]; } - const int &ak() const { return atomIndex_[2]; } - const int &al() const { return atomIndex_[3]; } - - const real ¶meterValue() const { return parameterValue_; } - /*!@}*/ - - private: - //! The distance value for this bonded interaction. - real parameterValue_; - //! Array of atom indices - std::array atomIndex_; + } + /*!@{*/ + //! Access the individual elements set for the vsite bonded interaction. + const int& ai() const { return atomIndex_[0]; } + const int& aj() const { return atomIndex_[1]; } + const int& ak() const { return atomIndex_[2]; } + const int& al() const { return atomIndex_[3]; } + + const real& parameterValue() const { return parameterValue_; } + /*!@}*/ + +private: + //! The distance value for this bonded interaction. + real parameterValue_; + //! Array of atom indices + std::array atomIndex_; }; /*! \internal \brief @@ -107,11 +106,13 @@ class VsiteBondedInteraction struct VsiteBondParameter { //! Constructor initializes datastructure. - VsiteBondParameter(int ftype, const InteractionOfType &vsiteInteraction) - : ftype_(ftype), vsiteInteraction_(vsiteInteraction) - {} + VsiteBondParameter(int ftype, const InteractionOfType& vsiteInteraction) : + ftype_(ftype), + vsiteInteraction_(vsiteInteraction) + { + } //! Function type for virtual site. - int ftype_; + int ftype_; /*! \brief * Interaction type data. * @@ -119,7 +120,7 @@ struct VsiteBondParameter * used to construct it might go out of scope before this object, as it would cause * the reference to type_ to dangle. */ - const InteractionOfType &vsiteInteraction_; + const InteractionOfType& vsiteInteraction_; }; /*! \internal \brief @@ -128,7 +129,7 @@ struct VsiteBondParameter struct Atom2VsiteBond { //! Function type for conversion. - int ftype; + int ftype; //! The vsite parameters in a list. std::vector vSiteBondedParameters; }; @@ -152,8 +153,7 @@ static int vsite_bond_nrcheck(int ftype) return nrcheck; } -static void enter_bonded(int nratoms, std::vector *bondeds, - const InteractionOfType &type) +static void enter_bonded(int nratoms, std::vector* bondeds, const InteractionOfType& type) { GMX_RELEASE_ASSERT(nratoms == type.atoms().ssize(), "Size of atom array must match"); bondeds->emplace_back(VsiteBondedInteraction(type.atoms(), type.c0())); @@ -172,18 +172,17 @@ struct AllVsiteBondedInteractions std::vector dihedrals; }; -static AllVsiteBondedInteractions -createVsiteBondedInformation(int nrat, - gmx::ArrayRef atoms, - gmx::ArrayRef at2vb) +static AllVsiteBondedInteractions createVsiteBondedInformation(int nrat, + gmx::ArrayRef atoms, + gmx::ArrayRef at2vb) { AllVsiteBondedInteractions allVsiteBondeds; for (int k = 0; k < nrat; k++) { - for (auto &vsite : at2vb[atoms[k]].vSiteBondedParameters) + for (auto& vsite : at2vb[atoms[k]].vSiteBondedParameters) { int ftype = vsite.ftype_; - const InteractionOfType &type = vsite.vsiteInteraction_; + const InteractionOfType& type = vsite.vsiteInteraction_; int nrcheck = vsite_bond_nrcheck(ftype); /* abuse nrcheck to see if we're adding bond, angle or idih */ switch (nrcheck) @@ -197,10 +196,9 @@ createVsiteBondedInformation(int nrat, return allVsiteBondeds; } -static std::vector -make_at2vsitebond(int natoms, gmx::ArrayRef plist) +static std::vector make_at2vsitebond(int natoms, gmx::ArrayRef plist) { - bool *bVSI; + bool* bVSI; std::vector at2vb(natoms); @@ -232,7 +230,8 @@ make_at2vsitebond(int natoms, gmx::ArrayRef plist) { if (bVSI[aa[j]]) { - at2vb[aa[j]].vSiteBondedParameters.emplace_back(ftype, plist[ftype].interactionTypes[i]); + at2vb[aa[j]].vSiteBondedParameters.emplace_back( + ftype, plist[ftype].interactionTypes[i]); } } } @@ -243,8 +242,7 @@ make_at2vsitebond(int natoms, gmx::ArrayRef plist) return at2vb; } -static std::vector -make_at2vsitecon(int natoms, gmx::ArrayRef plist) +static std::vector make_at2vsitecon(int natoms, gmx::ArrayRef plist) { std::vector bVSI(natoms); std::vector at2vc(natoms); @@ -286,59 +284,55 @@ make_at2vsitecon(int natoms, gmx::ArrayRef plist) } /* for debug */ -static void print_bad(FILE *fp, +static void print_bad(FILE* fp, gmx::ArrayRef bonds, gmx::ArrayRef angles, - gmx::ArrayRef idihs ) + gmx::ArrayRef idihs) { if (!bonds.empty()) { fprintf(fp, "bonds:"); - for (const auto &bond : bonds) + for (const auto& bond : bonds) { - fprintf(fp, " %d-%d (%g)", - bond.ai()+1, bond.aj()+1, bond.parameterValue()); + fprintf(fp, " %d-%d (%g)", bond.ai() + 1, bond.aj() + 1, bond.parameterValue()); } fprintf(fp, "\n"); } if (!angles.empty()) { fprintf(fp, "angles:"); - for (const auto &angle : angles) + for (const auto& angle : angles) { - fprintf(fp, " %d-%d-%d (%g)", - angle.ai()+1, angle.aj()+1, - angle.ak()+1, angle.parameterValue()); + fprintf(fp, " %d-%d-%d (%g)", angle.ai() + 1, angle.aj() + 1, angle.ak() + 1, + angle.parameterValue()); } fprintf(fp, "\n"); } if (!idihs.empty()) { fprintf(fp, "idihs:"); - for (const auto &idih : idihs) + for (const auto& idih : idihs) { - fprintf(fp, " %d-%d-%d-%d (%g)", - idih.ai()+1, idih.aj()+1, - idih.ak()+1, idih.al()+1, idih.parameterValue()); + fprintf(fp, " %d-%d-%d-%d (%g)", idih.ai() + 1, idih.aj() + 1, idih.ak() + 1, + idih.al() + 1, idih.parameterValue()); } fprintf(fp, "\n"); } } -static void printInteractionOfType(FILE *fp, int ftype, int i, const InteractionOfType &type) +static void printInteractionOfType(FILE* fp, int ftype, int i, const InteractionOfType& type) { static int pass = 0; static int prev_ftype = NOTSET; static int prev_i = NOTSET; - if ( (ftype != prev_ftype) || (i != prev_i) ) + if ((ftype != prev_ftype) || (i != prev_i)) { pass = 0; prev_ftype = ftype; prev_i = i; } - fprintf(fp, "(%d) plist[%s].param[%d]", - pass, interaction_function[ftype].name, i); + fprintf(fp, "(%d) plist[%s].param[%d]", pass, interaction_function[ftype].name, i); gmx::ArrayRef forceParam = type.forceParam(); for (int j = 0; j < NRFP(ftype); j++) { @@ -348,17 +342,15 @@ static void printInteractionOfType(FILE *fp, int ftype, int i, const Interaction pass++; } -static real get_bond_length(gmx::ArrayRef bonds, - t_iatom ai, t_iatom aj) +static real get_bond_length(gmx::ArrayRef bonds, t_iatom ai, t_iatom aj) { real bondlen; bondlen = NOTSET; - for (const auto &bond : bonds) + for (const auto& bond : bonds) { /* check both ways */ - if ( ( (ai == bond.ai()) && (aj == bond.aj()) ) || - ( (ai == bond.aj()) && (aj == bond.ai()) ) ) + if (((ai == bond.ai()) && (aj == bond.aj())) || ((ai == bond.aj()) && (aj == bond.ai()))) { bondlen = bond.parameterValue(); /* note: parameterValue might be NOTSET */ break; @@ -367,26 +359,25 @@ static real get_bond_length(gmx::ArrayRef bonds, return bondlen; } -static real get_angle(gmx::ArrayRef angles, - t_iatom ai, t_iatom aj, t_iatom ak) +static real get_angle(gmx::ArrayRef angles, t_iatom ai, t_iatom aj, t_iatom ak) { real angle; angle = NOTSET; - for (const auto &ang : angles) + for (const auto& ang : angles) { /* check both ways */ - if ( ( (ai == ang.ai()) && (aj == ang.aj()) && (ak == ang.ak()) ) || - ( (ai == ang.ak()) && (aj == ang.aj()) && (ak == ang.ai()) ) ) + if (((ai == ang.ai()) && (aj == ang.aj()) && (ak == ang.ak())) + || ((ai == ang.ak()) && (aj == ang.aj()) && (ak == ang.ai()))) { - angle = DEG2RAD*ang.parameterValue(); + angle = DEG2RAD * ang.parameterValue(); break; } } return angle; } -static const char *get_atomtype_name_AB(t_atom *atom, PreprocessingAtomTypes *atypes) +static const char* get_atomtype_name_AB(t_atom* atom, PreprocessingAtomTypes* atypes) { const char* name = atypes->atomNameFromAtomType(atom->type); @@ -408,25 +399,28 @@ static const char *get_atomtype_name_AB(t_atom *atom, PreprocessingAtomTypes *at return name; } -static bool calc_vsite3_param(PreprocessingAtomTypes *atypes, - InteractionOfType *vsite, t_atoms *at, +static bool calc_vsite3_param(PreprocessingAtomTypes* atypes, + InteractionOfType* vsite, + t_atoms* at, gmx::ArrayRef bonds, - gmx::ArrayRef angles ) + gmx::ArrayRef angles) { /* i = virtual site | ,k * j = 1st bonded heavy atom | i-j * k,l = 2nd bonded atoms | `l */ - bool bXH3, bError; - real bjk, bjl, a = -1, b = -1; + bool bXH3, bError; + real bjk, bjl, a = -1, b = -1; /* check if this is part of a NH3 , NH2-umbrella or CH3 group, * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */ - bXH3 = - ( (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3)) && - (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MNH", 3)) ) || - ( (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MCH3", 4)) && - (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MCH3", 4)) ); + bXH3 = ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3)) + && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), + "MNH", 3))) + || ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), + "MCH3", 4)) + && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), + "MCH3", 4))); bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); @@ -442,7 +436,7 @@ static bool calc_vsite3_param(PreprocessingAtomTypes *atypes, bError = bError || (bjk != bjl); /* the X atom (C or N) in the XH2/XH3 group is the first after the masses: */ - aN = std::max(vsite->ak(), vsite->al())+1; + aN = std::max(vsite->ak(), vsite->al()) + 1; /* get common bonds */ bMM = get_bond_length(bonds, vsite->ak(), vsite->al()); @@ -451,35 +445,36 @@ static bool calc_vsite3_param(PreprocessingAtomTypes *atypes, bError = bError || (bMM == NOTSET) || (bCN == NOTSET); /* calculate common things */ - rM = 0.5*bMM; - dM = std::sqrt( gmx::square(bCM) - gmx::square(rM) ); + rM = 0.5 * bMM; + dM = std::sqrt(gmx::square(bCM) - gmx::square(rM)); /* are we dealing with the X atom? */ if (vsite->ai() == aN) { /* this is trivial */ - a = b = 0.5 * bCN/dM; - + a = b = 0.5 * bCN / dM; } else { /* get other bondlengths and angles: */ bNH = get_bond_length(bonds, aN, vsite->ai()); - aCNH = get_angle (angles, vsite->aj(), aN, vsite->ai()); + aCNH = get_angle(angles, vsite->aj(), aN, vsite->ai()); bError = bError || (bNH == NOTSET) || (aCNH == NOTSET); /* calculate */ - dH = bCN - bNH * std::cos(aCNH); - rH = bNH * std::sin(aCNH); + dH = bCN - bNH * std::cos(aCNH); + rH = bNH * std::sin(aCNH); - a = 0.5 * ( dH/dM + rH/rM ); - b = 0.5 * ( dH/dM - rH/rM ); + a = 0.5 * (dH / dM + rH / rM); + b = 0.5 * (dH / dM - rH / rM); } } else { - gmx_fatal(FARGS, "calc_vsite3_param not implemented for the general case " - "(atom %d)", vsite->ai()+1); + gmx_fatal(FARGS, + "calc_vsite3_param not implemented for the general case " + "(atom %d)", + vsite->ai() + 1); } vsite->setForceParameter(0, a); vsite->setForceParameter(1, b); @@ -487,7 +482,7 @@ static bool calc_vsite3_param(PreprocessingAtomTypes *atypes, return bError; } -static bool calc_vsite3fd_param(InteractionOfType *vsite, +static bool calc_vsite3fd_param(InteractionOfType* vsite, gmx::ArrayRef bonds, gmx::ArrayRef angles) { @@ -496,26 +491,25 @@ static bool calc_vsite3fd_param(InteractionOfType *vsit * k,l = 2nd bonded atoms | `l */ - bool bError; - real bij, bjk, bjl, aijk, aijl, rk, rl; + bool bError; + real bij, bjk, bjl, aijk, aijl, rk, rl; - bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); - bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); - bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); - aijk = get_angle (angles, vsite->ai(), vsite->aj(), vsite->ak()); - aijl = get_angle (angles, vsite->ai(), vsite->aj(), vsite->al()); - bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || - (aijk == NOTSET) || (aijl == NOTSET); + bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); + bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); + bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); + aijk = get_angle(angles, vsite->ai(), vsite->aj(), vsite->ak()); + aijl = get_angle(angles, vsite->ai(), vsite->aj(), vsite->al()); + bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (aijk == NOTSET) || (aijl == NOTSET); - rk = bjk * std::sin(aijk); - rl = bjl * std::sin(aijl); + rk = bjk * std::sin(aijk); + rl = bjl * std::sin(aijl); vsite->setForceParameter(0, rk / (rk + rl)); vsite->setForceParameter(1, -bij); return bError; } -static bool calc_vsite3fad_param(InteractionOfType *vsite, +static bool calc_vsite3fad_param(InteractionOfType* vsite, gmx::ArrayRef bonds, gmx::ArrayRef angles) { @@ -525,17 +519,17 @@ static bool calc_vsite3fad_param(InteractionOfType *vsi * l = 3d bonded heavy atom | */ - bool bSwapParity, bError; - real bij, aijk; + bool bSwapParity, bError; + real bij, aijk; - bSwapParity = ( vsite->c1() == -1 ); + bSwapParity = (vsite->c1() == -1); bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); - aijk = get_angle (angles, vsite->ai(), vsite->aj(), vsite->ak()); + aijk = get_angle(angles, vsite->ai(), vsite->aj(), vsite->ak()); bError = (bij == NOTSET) || (aijk == NOTSET); vsite->setForceParameter(1, bij); - vsite->setForceParameter(0, RAD2DEG*aijk); + vsite->setForceParameter(0, RAD2DEG * aijk); if (bSwapParity) { @@ -545,8 +539,9 @@ static bool calc_vsite3fad_param(InteractionOfType *vsi return bError; } -static bool calc_vsite3out_param(PreprocessingAtomTypes *atypes, - InteractionOfType *vsite, t_atoms *at, +static bool calc_vsite3out_param(PreprocessingAtomTypes* atypes, + InteractionOfType* vsite, + t_atoms* at, gmx::ArrayRef bonds, gmx::ArrayRef angles) { @@ -556,19 +551,21 @@ static bool calc_vsite3out_param(PreprocessingAtomTypes *atypes, * NOTE: i is out of the j-k-l plane! */ - bool bXH3, bError, bSwapParity; - real bij, bjk, bjl, aijk, aijl, akjl, pijk, pijl, a, b, c; + bool bXH3, bError, bSwapParity; + real bij, bjk, bjl, aijk, aijl, akjl, pijk, pijl, a, b, c; /* check if this is part of a NH2-umbrella, NH3 or CH3 group, * i.e. if atom k and l are dummy masses (MNH* or MCH3*) */ - bXH3 = - ( (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3)) && - (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MNH", 3)) ) || - ( (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MCH3", 4)) && - (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), "MCH3", 4)) ); + bXH3 = ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), "MNH", 3)) + && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), + "MNH", 3))) + || ((gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->ak()], atypes), + "MCH3", 4)) + && (gmx::equalCaseInsensitive(get_atomtype_name_AB(&at->atom[vsite->al()], atypes), + "MCH3", 4))); /* check if construction parity must be swapped */ - bSwapParity = ( vsite->c1() == -1 ); + bSwapParity = (vsite->c1() == -1); bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); @@ -584,49 +581,46 @@ static bool calc_vsite3out_param(PreprocessingAtomTypes *atypes, bError = bError || (bjk != bjl); /* the X atom (C or N) in the XH3 group is the first after the masses: */ - aN = std::max(vsite->ak(), vsite->al())+1; + aN = std::max(vsite->ak(), vsite->al()) + 1; /* get all bondlengths and angles: */ bMM = get_bond_length(bonds, vsite->ak(), vsite->al()); bCM = bjk; bCN = get_bond_length(bonds, vsite->aj(), aN); bNH = get_bond_length(bonds, aN, vsite->ai()); - aCNH = get_angle (angles, vsite->aj(), aN, vsite->ai()); - bError = bError || - (bMM == NOTSET) || (bCN == NOTSET) || (bNH == NOTSET) || (aCNH == NOTSET); + aCNH = get_angle(angles, vsite->aj(), aN, vsite->ai()); + bError = bError || (bMM == NOTSET) || (bCN == NOTSET) || (bNH == NOTSET) || (aCNH == NOTSET); /* calculate */ - dH = bCN - bNH * std::cos(aCNH); - rH = bNH * std::sin(aCNH); + dH = bCN - bNH * std::cos(aCNH); + rH = bNH * std::sin(aCNH); /* we assume the H's are symmetrically distributed */ - rHx = rH*std::cos(DEG2RAD*30); - rHy = rH*std::sin(DEG2RAD*30); - rM = 0.5*bMM; - dM = std::sqrt( gmx::square(bCM) - gmx::square(rM) ); - a = 0.5*( (dH/dM) - (rHy/rM) ); - b = 0.5*( (dH/dM) + (rHy/rM) ); - c = rHx / (2*dM*rM); - + rHx = rH * std::cos(DEG2RAD * 30); + rHy = rH * std::sin(DEG2RAD * 30); + rM = 0.5 * bMM; + dM = std::sqrt(gmx::square(bCM) - gmx::square(rM)); + a = 0.5 * ((dH / dM) - (rHy / rM)); + b = 0.5 * ((dH / dM) + (rHy / rM)); + c = rHx / (2 * dM * rM); } else { /* this is the general construction */ - bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); - aijk = get_angle (angles, vsite->ai(), vsite->aj(), vsite->ak()); - aijl = get_angle (angles, vsite->ai(), vsite->aj(), vsite->al()); - akjl = get_angle (angles, vsite->ak(), vsite->aj(), vsite->al()); - bError = bError || - (bij == NOTSET) || (aijk == NOTSET) || (aijl == NOTSET) || (akjl == NOTSET); - - pijk = std::cos(aijk)*bij; - pijl = std::cos(aijl)*bij; - a = ( pijk + (pijk*std::cos(akjl)-pijl) * std::cos(akjl) / gmx::square(std::sin(akjl)) ) / bjk; - b = ( pijl + (pijl*std::cos(akjl)-pijk) * std::cos(akjl) / gmx::square(std::sin(akjl)) ) / bjl; - c = -std::sqrt( gmx::square(bij) - - ( gmx::square(pijk) - 2*pijk*pijl*std::cos(akjl) + gmx::square(pijl) ) - / gmx::square(std::sin(akjl)) ) - / ( bjk*bjl*std::sin(akjl) ); + bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); + aijk = get_angle(angles, vsite->ai(), vsite->aj(), vsite->ak()); + aijl = get_angle(angles, vsite->ai(), vsite->aj(), vsite->al()); + akjl = get_angle(angles, vsite->ak(), vsite->aj(), vsite->al()); + bError = bError || (bij == NOTSET) || (aijk == NOTSET) || (aijl == NOTSET) || (akjl == NOTSET); + + pijk = std::cos(aijk) * bij; + pijl = std::cos(aijl) * bij; + a = (pijk + (pijk * std::cos(akjl) - pijl) * std::cos(akjl) / gmx::square(std::sin(akjl))) / bjk; + b = (pijl + (pijl * std::cos(akjl) - pijk) * std::cos(akjl) / gmx::square(std::sin(akjl))) / bjl; + c = -std::sqrt(gmx::square(bij) + - (gmx::square(pijk) - 2 * pijk * pijl * std::cos(akjl) + gmx::square(pijl)) + / gmx::square(std::sin(akjl))) + / (bjk * bjl * std::sin(akjl)); } vsite->setForceParameter(0, a); @@ -642,7 +636,7 @@ static bool calc_vsite3out_param(PreprocessingAtomTypes *atypes, return bError; } -static bool calc_vsite4fd_param(InteractionOfType *vsite, +static bool calc_vsite4fd_param(InteractionOfType* vsite, gmx::ArrayRef bonds, gmx::ArrayRef angles) { @@ -651,43 +645,44 @@ static bool calc_vsite4fd_param(InteractionOfType *vsit * k,l,m = 2nd bonded atoms | `l */ - bool bError; - real bij, bjk, bjl, bjm, aijk, aijl, aijm, akjm, akjl; - real pk, pl, pm, cosakl, cosakm, sinakl, sinakm, cl, cm; - - bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); - bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); - bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); - bjm = get_bond_length(bonds, vsite->aj(), vsite->am()); - aijk = get_angle (angles, vsite->ai(), vsite->aj(), vsite->ak()); - aijl = get_angle (angles, vsite->ai(), vsite->aj(), vsite->al()); - aijm = get_angle (angles, vsite->ai(), vsite->aj(), vsite->am()); - akjm = get_angle (angles, vsite->ak(), vsite->aj(), vsite->am()); - akjl = get_angle (angles, vsite->ak(), vsite->aj(), vsite->al()); - bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) || - (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET) || (akjm == NOTSET) || - (akjl == NOTSET); + bool bError; + real bij, bjk, bjl, bjm, aijk, aijl, aijm, akjm, akjl; + real pk, pl, pm, cosakl, cosakm, sinakl, sinakm, cl, cm; + + bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); + bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); + bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); + bjm = get_bond_length(bonds, vsite->aj(), vsite->am()); + aijk = get_angle(angles, vsite->ai(), vsite->aj(), vsite->ak()); + aijl = get_angle(angles, vsite->ai(), vsite->aj(), vsite->al()); + aijm = get_angle(angles, vsite->ai(), vsite->aj(), vsite->am()); + akjm = get_angle(angles, vsite->ak(), vsite->aj(), vsite->am()); + akjl = get_angle(angles, vsite->ak(), vsite->aj(), vsite->al()); + bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) || (aijk == NOTSET) + || (aijl == NOTSET) || (aijm == NOTSET) || (akjm == NOTSET) || (akjl == NOTSET); if (!bError) { - pk = bjk*std::sin(aijk); - pl = bjl*std::sin(aijl); - pm = bjm*std::sin(aijm); - cosakl = (std::cos(akjl) - std::cos(aijk)*std::cos(aijl)) / (std::sin(aijk)*std::sin(aijl)); - cosakm = (std::cos(akjm) - std::cos(aijk)*std::cos(aijm)) / (std::sin(aijk)*std::sin(aijm)); + pk = bjk * std::sin(aijk); + pl = bjl * std::sin(aijl); + pm = bjm * std::sin(aijm); + cosakl = (std::cos(akjl) - std::cos(aijk) * std::cos(aijl)) / (std::sin(aijk) * std::sin(aijl)); + cosakm = (std::cos(akjm) - std::cos(aijk) * std::cos(aijm)) / (std::sin(aijk) * std::sin(aijm)); if (cosakl < -1 || cosakl > 1 || cosakm < -1 || cosakm > 1) { fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n", - vsite->ai()+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm); - gmx_fatal(FARGS, "invalid construction in calc_vsite4fd for atom %d: " - "cosakl=%f, cosakm=%f\n", vsite->ai()+1, cosakl, cosakm); + vsite->ai() + 1, RAD2DEG * aijk, RAD2DEG * aijl, RAD2DEG * aijm); + gmx_fatal(FARGS, + "invalid construction in calc_vsite4fd for atom %d: " + "cosakl=%f, cosakm=%f\n", + vsite->ai() + 1, cosakl, cosakm); } - sinakl = std::sqrt(1-gmx::square(cosakl)); - sinakm = std::sqrt(1-gmx::square(cosakm)); + sinakl = std::sqrt(1 - gmx::square(cosakl)); + sinakm = std::sqrt(1 - gmx::square(cosakm)); /* note: there is a '+' because of the way the sines are calculated */ - cl = -pk / ( pl*cosakl - pk + pl*sinakl*(pm*cosakm-pk)/(pm*sinakm) ); - cm = -pk / ( pm*cosakm - pk + pm*sinakm*(pl*cosakl-pk)/(pl*sinakl) ); + cl = -pk / (pl * cosakl - pk + pl * sinakl * (pm * cosakm - pk) / (pm * sinakm)); + cm = -pk / (pm * cosakm - pk + pm * sinakm * (pl * cosakl - pk) / (pl * sinakl)); vsite->setForceParameter(0, cl); vsite->setForceParameter(1, cm); @@ -698,53 +693,54 @@ static bool calc_vsite4fd_param(InteractionOfType *vsit } -static bool -calc_vsite4fdn_param(InteractionOfType *vsite, - gmx::ArrayRef bonds, - gmx::ArrayRef angles) +static bool calc_vsite4fdn_param(InteractionOfType* vsite, + gmx::ArrayRef bonds, + gmx::ArrayRef angles) { /* i = virtual site | ,k * j = 1st bonded heavy atom | i-j-m * k,l,m = 2nd bonded atoms | `l */ - bool bError; - real bij, bjk, bjl, bjm, aijk, aijl, aijm; - real pk, pl, pm, a, b; + bool bError; + real bij, bjk, bjl, bjm, aijk, aijl, aijm; + real pk, pl, pm, a, b; - bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); - bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); - bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); - bjm = get_bond_length(bonds, vsite->aj(), vsite->am()); - aijk = get_angle (angles, vsite->ai(), vsite->aj(), vsite->ak()); - aijl = get_angle (angles, vsite->ai(), vsite->aj(), vsite->al()); - aijm = get_angle (angles, vsite->ai(), vsite->aj(), vsite->am()); + bij = get_bond_length(bonds, vsite->ai(), vsite->aj()); + bjk = get_bond_length(bonds, vsite->aj(), vsite->ak()); + bjl = get_bond_length(bonds, vsite->aj(), vsite->al()); + bjm = get_bond_length(bonds, vsite->aj(), vsite->am()); + aijk = get_angle(angles, vsite->ai(), vsite->aj(), vsite->ak()); + aijl = get_angle(angles, vsite->ai(), vsite->aj(), vsite->al()); + aijm = get_angle(angles, vsite->ai(), vsite->aj(), vsite->am()); - bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) || - (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET); + bError = (bij == NOTSET) || (bjk == NOTSET) || (bjl == NOTSET) || (bjm == NOTSET) + || (aijk == NOTSET) || (aijl == NOTSET) || (aijm == NOTSET); if (!bError) { /* Calculate component of bond j-k along the direction i-j */ - pk = -bjk*std::cos(aijk); + pk = -bjk * std::cos(aijk); /* Calculate component of bond j-l along the direction i-j */ - pl = -bjl*std::cos(aijl); + pl = -bjl * std::cos(aijl); /* Calculate component of bond j-m along the direction i-j */ - pm = -bjm*std::cos(aijm); + pm = -bjm * std::cos(aijm); - if (fabs(pl) < 1000*GMX_REAL_MIN || fabs(pm) < 1000*GMX_REAL_MIN) + if (fabs(pl) < 1000 * GMX_REAL_MIN || fabs(pm) < 1000 * GMX_REAL_MIN) { fprintf(stderr, "virtual site %d: angle ijk = %f, angle ijl = %f, angle ijm = %f\n", - vsite->ai()+1, RAD2DEG*aijk, RAD2DEG*aijl, RAD2DEG*aijm); - gmx_fatal(FARGS, "invalid construction in calc_vsite4fdn for atom %d: " - "pl=%f, pm=%f\n", vsite->ai()+1, pl, pm); + vsite->ai() + 1, RAD2DEG * aijk, RAD2DEG * aijl, RAD2DEG * aijm); + gmx_fatal(FARGS, + "invalid construction in calc_vsite4fdn for atom %d: " + "pl=%f, pm=%f\n", + vsite->ai() + 1, pl, pm); } - a = pk/pl; - b = pk/pm; + a = pk / pl; + b = pk / pm; vsite->setForceParameter(0, a); vsite->setForceParameter(1, b); @@ -755,13 +751,11 @@ calc_vsite4fdn_param(InteractionOfType *vsite, } - -int set_vsites(bool bVerbose, t_atoms *atoms, PreprocessingAtomTypes *atypes, - gmx::ArrayRef plist) +int set_vsites(bool bVerbose, t_atoms* atoms, PreprocessingAtomTypes* atypes, gmx::ArrayRef plist) { - int ftype; - int nvsite, nrset; - bool bFirst, bERROR; + int ftype; + int nvsite, nrset; + bool bFirst, bERROR; bFirst = TRUE; nvsite = 0; @@ -783,10 +777,10 @@ int set_vsites(bool bVerbose, t_atoms *atoms, PreprocessingAtomTypes *atypes, nrset = 0; int i = 0; - for (auto ¶m : plist[ftype].interactionTypes) + for (auto& param : plist[ftype].interactionTypes) { /* check if all parameters are set */ - bool bSet = true; + bool bSet = true; gmx::ArrayRef forceParam = param.forceParam(); for (int j = 0; (j < NRFP(ftype)) && bSet; j++) { @@ -809,89 +803,69 @@ int set_vsites(bool bVerbose, t_atoms *atoms, PreprocessingAtomTypes *atypes, nrset++; /* now set the vsite parameters: */ AllVsiteBondedInteractions allVsiteBondeds = - createVsiteBondedInformation(NRAL(ftype), param.atoms(), at2vb); + createVsiteBondedInformation(NRAL(ftype), param.atoms(), at2vb); if (debug) { - fprintf(debug, "Found %zu bonds, %zu angles and %zu idihs " + fprintf(debug, + "Found %zu bonds, %zu angles and %zu idihs " "for virtual site %d (%s)\n", - allVsiteBondeds.bonds.size(), - allVsiteBondeds.angles.size(), - allVsiteBondeds.dihedrals.size(), - param.ai()+1, + allVsiteBondeds.bonds.size(), allVsiteBondeds.angles.size(), + allVsiteBondeds.dihedrals.size(), param.ai() + 1, interaction_function[ftype].longname); - print_bad(debug, - allVsiteBondeds.bonds, - allVsiteBondeds.angles, + print_bad(debug, allVsiteBondeds.bonds, allVsiteBondeds.angles, allVsiteBondeds.dihedrals); } /* debug */ switch (ftype) { case F_VSITE3: - bERROR = - calc_vsite3_param(atypes, - ¶m, - atoms, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite3_param(atypes, ¶m, atoms, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; case F_VSITE3FD: - bERROR = - calc_vsite3fd_param(¶m, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite3fd_param(¶m, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; case F_VSITE3FAD: - bERROR = - calc_vsite3fad_param(¶m, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite3fad_param(¶m, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; case F_VSITE3OUT: - bERROR = - calc_vsite3out_param(atypes, - ¶m, - atoms, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite3out_param(atypes, ¶m, atoms, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; case F_VSITE4FD: - bERROR = - calc_vsite4fd_param(¶m, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite4fd_param(¶m, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; case F_VSITE4FDN: - bERROR = - calc_vsite4fdn_param(¶m, - allVsiteBondeds.bonds, - allVsiteBondeds.angles); + bERROR = calc_vsite4fdn_param(¶m, allVsiteBondeds.bonds, + allVsiteBondeds.angles); break; default: - gmx_fatal(FARGS, "Automatic parameter generation not supported " + gmx_fatal(FARGS, + "Automatic parameter generation not supported " "for %s atom %d", - interaction_function[ftype].longname, - param.ai()+1); + interaction_function[ftype].longname, param.ai() + 1); bERROR = TRUE; } /* switch */ if (bERROR) { - gmx_fatal(FARGS, "Automatic parameter generation not supported " + gmx_fatal(FARGS, + "Automatic parameter generation not supported " "for %s atom %d for this bonding configuration", - interaction_function[ftype].longname, - param.ai()+1); + interaction_function[ftype].longname, param.ai() + 1); } } /* if bSet */ i++; } - } /* if IF_VSITE */ - + } /* if IF_VSITE */ } return nvsite; } -void set_vsites_ptype(bool bVerbose, gmx_moltype_t *molt) +void set_vsites_ptype(bool bVerbose, gmx_moltype_t* molt) { - int ftype, i; + int ftype, i; if (bVerbose) { @@ -899,7 +873,7 @@ void set_vsites_ptype(bool bVerbose, gmx_moltype_t *molt) } for (ftype = 0; ftype < F_NRE; ftype++) { - InteractionList *il = &molt->ilist[ftype]; + InteractionList* il = &molt->ilist[ftype]; if (interaction_function[ftype].flags & IF_VSITE) { const int nra = interaction_function[ftype].nratoms; @@ -908,21 +882,20 @@ void set_vsites_ptype(bool bVerbose, gmx_moltype_t *molt) if (debug && nrd) { - fprintf(stderr, "doing %d %s virtual sites\n", - (nrd / (nra+1)), interaction_function[ftype].longname); + fprintf(stderr, "doing %d %s virtual sites\n", (nrd / (nra + 1)), + interaction_function[ftype].longname); } - for (i = 0; (i < nrd); ) + for (i = 0; (i < nrd);) { /* The virtual site */ - int avsite = ia[i + 1]; + int avsite = ia[i + 1]; molt->atoms.atom[avsite].ptype = eptVSite; - i += nra+1; + i += nra + 1; } } } - } /*! \brief @@ -934,30 +907,30 @@ void set_vsites_ptype(bool bVerbose, gmx_moltype_t *molt) */ class VsiteAtomMapping { - public: - //! Only construct with all information in place or nothing - VsiteAtomMapping(int functionType, int interactionIndex) - : functionType_(functionType), interactionIndex_(interactionIndex) - {} - VsiteAtomMapping() - : functionType_(-1), interactionIndex_(-1) - {} - //! Get function type. - const int &functionType() const { return functionType_; } - //! Get parameter number. - const int &interactionIndex() const { return interactionIndex_; } - private: - //! Function type for the linked parameter. - int functionType_; - //! The linked parameter. - int interactionIndex_; +public: + //! Only construct with all information in place or nothing + VsiteAtomMapping(int functionType, int interactionIndex) : + functionType_(functionType), + interactionIndex_(interactionIndex) + { + } + VsiteAtomMapping() : functionType_(-1), interactionIndex_(-1) {} + //! Get function type. + const int& functionType() const { return functionType_; } + //! Get parameter number. + const int& interactionIndex() const { return interactionIndex_; } + +private: + //! Function type for the linked parameter. + int functionType_; + //! The linked parameter. + int interactionIndex_; }; -static void check_vsite_constraints(gmx::ArrayRef plist, - int cftype, const int vsite_type[]) +static void check_vsite_constraints(gmx::ArrayRef plist, int cftype, const int vsite_type[]) { - int n = 0; - for (const auto ¶m : plist[cftype].interactionTypes) + int n = 0; + for (const auto& param : plist[cftype].interactionTypes) { gmx::ArrayRef atoms = param.atoms(); for (int k = 0; k < 2; k++) @@ -966,7 +939,7 @@ static void check_vsite_constraints(gmx::ArrayRef plist, if (vsite_type[atom] != NOTSET) { fprintf(stderr, "ERROR: Cannot have constraint (%d-%d) with virtual site (%d)\n", - param.ai()+1, param.aj()+1, atom+1); + param.ai() + 1, param.aj() + 1, atom + 1); n++; } } @@ -977,15 +950,16 @@ static void check_vsite_constraints(gmx::ArrayRef plist, } } -static void clean_vsite_bonds(gmx::ArrayRef plist, +static void clean_vsite_bonds(gmx::ArrayRef plist, gmx::ArrayRef pindex, - int cftype, const int vsite_type[]) + int cftype, + const int vsite_type[]) { - int ftype, nOut; - int nconverted, nremoved; - int oatom, at1, at2; - bool bKeep, bRemove, bAllFD; - InteractionsOfType *ps; + int ftype, nOut; + int nconverted, nremoved; + int oatom, at1, at2; + bool bKeep, bRemove, bAllFD; + InteractionsOfType* ps; if (cftype == F_CONNBONDS) { @@ -996,17 +970,17 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, nconverted = 0; nremoved = 0; nOut = 0; - for (auto bond = ps->interactionTypes.begin(); bond != ps->interactionTypes.end(); ) + for (auto bond = ps->interactionTypes.begin(); bond != ps->interactionTypes.end();) { - int vsnral = 0; - const int *first_atoms = nullptr; + int vsnral = 0; + const int* first_atoms = nullptr; bKeep = false; bRemove = false; bAllFD = true; /* check if all virtual sites are constructed from the same atoms */ - int nvsite = 0; - gmx::ArrayRef atoms = bond->atoms(); + int nvsite = 0; + gmx::ArrayRef atoms = bond->atoms(); for (int k = 0; (k < 2) && !bKeep && !bRemove; k++) { /* for all atoms in the bond */ @@ -1014,18 +988,21 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, if (vsite_type[atom] != NOTSET && vsite_type[atom] != F_VSITEN) { nvsite++; - bool bThisFD = ( (pindex[atom].functionType() == F_VSITE3FD ) || - (pindex[atom].functionType() == F_VSITE3FAD) || - (pindex[atom].functionType() == F_VSITE4FD ) || - (pindex[atom].functionType() == F_VSITE4FDN ) ); - bool bThisOUT = ( (pindex[atom].functionType() == F_VSITE3OUT) && - ((interaction_function[cftype].flags & IF_CONSTRAINT) != 0U) ); - bAllFD = bAllFD && bThisFD; + bool bThisFD = ((pindex[atom].functionType() == F_VSITE3FD) + || (pindex[atom].functionType() == F_VSITE3FAD) + || (pindex[atom].functionType() == F_VSITE4FD) + || (pindex[atom].functionType() == F_VSITE4FDN)); + bool bThisOUT = ((pindex[atom].functionType() == F_VSITE3OUT) + && ((interaction_function[cftype].flags & IF_CONSTRAINT) != 0U)); + bAllFD = bAllFD && bThisFD; if (bThisFD || bThisOUT) { - oatom = atoms[1-k]; /* the other atom */ - if (vsite_type[oatom] == NOTSET && - oatom == plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].aj()) + oatom = atoms[1 - k]; /* the other atom */ + if (vsite_type[oatom] == NOTSET + && oatom + == plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .aj()) { /* if the other atom isn't a vsite, and it is AI */ bRemove = true; @@ -1048,22 +1025,31 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, a C++ "vector view" class" with an STL-container-like interface. */ vsnral = NRAL(pindex[atom].functionType()) - 1; - first_atoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + first_atoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; } else { GMX_ASSERT(vsnral != 0, "nvsite > 1 must have vsnral != 0"); - GMX_ASSERT(first_atoms != nullptr, "nvsite > 1 must have first_atoms != NULL"); + GMX_ASSERT(first_atoms != nullptr, + "nvsite > 1 must have first_atoms != NULL"); /* if it is not the first then check if this vsite is constructed from the same atoms */ - if (vsnral == NRAL(pindex[atom].functionType())-1) + if (vsnral == NRAL(pindex[atom].functionType()) - 1) { for (int m = 0; (m < vsnral) && !bKeep; m++) { - const int *atoms; - - bool bPresent = false; - atoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + const int* atoms; + + bool bPresent = false; + atoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; for (int n = 0; (n < vsnral) && !bPresent; n++) { if (atoms[m] == first_atoms[n]) @@ -1111,7 +1097,9 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, bool bUsed = false; for (int m = 0; (m < vsnral) && !bUsed; m++) { - GMX_ASSERT(first_atoms != nullptr, "If we've seen a vsite before, we know what its first atom index was"); + GMX_ASSERT(first_atoms != nullptr, + "If we've seen a vsite before, we know what its first atom " + "index was"); if (atom == first_atoms[m]) { @@ -1126,7 +1114,7 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, } } - if (!( bAllFD && bFirstTwo ) ) + if (!(bAllFD && bFirstTwo)) { /* Two atom bonded interactions include constraints. * We need to remove constraints between vsite pairs that have @@ -1135,20 +1123,19 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, */ for (int m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */ { - at1 = first_atoms[m]; - at2 = first_atoms[(m+1) % vsnral]; + at1 = first_atoms[m]; + at2 = first_atoms[(m + 1) % vsnral]; bool bPresent = false; for (ftype = 0; ftype < F_NRE; ftype++) { if (interaction_function[ftype].flags & IF_CONSTRAINT) { - for (auto entry = plist[ftype].interactionTypes.begin(); (entry != plist[ftype].interactionTypes.end()) && !bPresent; entry++) + for (auto entry = plist[ftype].interactionTypes.begin(); + (entry != plist[ftype].interactionTypes.end()) && !bPresent; entry++) { /* all constraints until one matches */ - bPresent = ( ( (entry->ai() == at1) && - (entry->aj() == at2) ) || - ( (entry->ai() == at2) && - (entry->aj() == at1) ) ); + bPresent = (((entry->ai() == at1) && (entry->aj() == at2)) + || ((entry->ai() == at2) && (entry->aj() == at1))); } } } @@ -1179,8 +1166,8 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, if (nremoved) { - fprintf(stderr, "Removed %4d %15ss with virtual sites, %zu left\n", - nremoved, interaction_function[cftype].longname, ps->size()); + fprintf(stderr, "Removed %4d %15ss with virtual sites, %zu left\n", nremoved, + interaction_function[cftype].longname, ps->size()); } if (nconverted) { @@ -1189,33 +1176,34 @@ static void clean_vsite_bonds(gmx::ArrayRef plist, } if (nOut) { - fprintf(stderr, "Warning: removed %d %ss with vsite with %s construction\n" + fprintf(stderr, + "Warning: removed %d %ss with vsite with %s construction\n" " This vsite construction does not guarantee constant " "bond-length\n" " If the constructions were generated by pdb2gmx ignore " "this warning\n", - nOut, interaction_function[cftype].longname, - interaction_function[F_VSITE3OUT].longname ); + nOut, interaction_function[cftype].longname, interaction_function[F_VSITE3OUT].longname); } } -static void clean_vsite_angles(gmx::ArrayRef plist, - gmx::ArrayRef pindex, - int cftype, const int vsite_type[], +static void clean_vsite_angles(gmx::ArrayRef plist, + gmx::ArrayRef pindex, + int cftype, + const int vsite_type[], gmx::ArrayRef at2vc) { - int atom, at1, at2; - InteractionsOfType *ps; + int atom, at1, at2; + InteractionsOfType* ps; - ps = &(plist[cftype]); + ps = &(plist[cftype]); int oldSize = ps->size(); - for (auto angle = ps->interactionTypes.begin(); angle != ps->interactionTypes.end(); ) + for (auto angle = ps->interactionTypes.begin(); angle != ps->interactionTypes.end();) { - int vsnral = 0; - const int *first_atoms = nullptr; + int vsnral = 0; + const int* first_atoms = nullptr; - bool bKeep = false; - bool bAll3FAD = true; + bool bKeep = false; + bool bAll3FAD = true; /* check if all virtual sites are constructed from the same atoms */ int nvsite = 0; gmx::ArrayRef atoms = angle->atoms(); @@ -1230,21 +1218,33 @@ static void clean_vsite_angles(gmx::ArrayRef plist, { /* store construction atoms of first vsite */ vsnral = NRAL(pindex[atom].functionType()) - 1; - first_atoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + first_atoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; } else { - GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had"); - GMX_ASSERT(first_atoms != nullptr, "If we've seen a vsite before, we know what its first atom index was"); + GMX_ASSERT(vsnral != 0, + "If we've seen a vsite before, we know how many constructing atoms " + "it had"); + GMX_ASSERT( + first_atoms != nullptr, + "If we've seen a vsite before, we know what its first atom index was"); /* check if this vsite is constructed from the same atoms */ - if (vsnral == NRAL(pindex[atom].functionType())-1) + if (vsnral == NRAL(pindex[atom].functionType()) - 1) { for (int m = 0; (m < vsnral) && !bKeep; m++) { - const int *subAtoms; - - bool bPresent = false; - subAtoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + const int* subAtoms; + + bool bPresent = false; + subAtoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; for (int n = 0; (n < vsnral) && !bPresent; n++) { if (subAtoms[m] == first_atoms[n]) @@ -1283,7 +1283,9 @@ static void clean_vsite_angles(gmx::ArrayRef plist, bool bUsed = false; for (int m = 0; (m < vsnral) && !bUsed; m++) { - GMX_ASSERT(first_atoms != nullptr, "If we've seen a vsite before, we know what its first atom index was"); + GMX_ASSERT( + first_atoms != nullptr, + "If we've seen a vsite before, we know what its first atom index was"); if (atom == first_atoms[m]) { @@ -1298,13 +1300,13 @@ static void clean_vsite_angles(gmx::ArrayRef plist, } } - if (!( bAll3FAD && bFirstTwo ) ) + if (!(bAll3FAD && bFirstTwo)) { /* check if all constructing atoms are constrained together */ for (int m = 0; m < vsnral && !bKeep; m++) /* all constr. atoms */ { - at1 = first_atoms[m]; - at2 = first_atoms[(m+1) % vsnral]; + at1 = first_atoms[m]; + at2 = first_atoms[(m + 1) % vsnral]; bool bPresent = false; auto found = std::find(at2vc[at1].begin(), at2vc[at1].end(), at2); if (found != at2vc[at1].end()) @@ -1330,25 +1332,26 @@ static void clean_vsite_angles(gmx::ArrayRef plist, if (oldSize != gmx::ssize(*ps)) { - fprintf(stderr, "Removed %4zu %15ss with virtual sites, %zu left\n", - oldSize-ps->size(), interaction_function[cftype].longname, ps->size()); + fprintf(stderr, "Removed %4zu %15ss with virtual sites, %zu left\n", oldSize - ps->size(), + interaction_function[cftype].longname, ps->size()); } } -static void clean_vsite_dihs(gmx::ArrayRef plist, +static void clean_vsite_dihs(gmx::ArrayRef plist, gmx::ArrayRef pindex, - int cftype, const int vsite_type[]) + int cftype, + const int vsite_type[]) { - InteractionsOfType *ps; + InteractionsOfType* ps; ps = &(plist[cftype]); int oldSize = ps->size(); - for (auto dih = ps->interactionTypes.begin(); dih != ps->interactionTypes.end(); ) + for (auto dih = ps->interactionTypes.begin(); dih != ps->interactionTypes.end();) { - int vsnral = 0; - const int *first_atoms = nullptr; - int atom; + int vsnral = 0; + const int* first_atoms = nullptr; + int atom; gmx::ArrayRef atoms = dih->atoms(); bool bKeep = false; @@ -1363,21 +1366,33 @@ static void clean_vsite_dihs(gmx::ArrayRef plist, { /* store construction atoms of first vsite */ vsnral = NRAL(pindex[atom].functionType()) - 1; - first_atoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + first_atoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; } else { - GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had"); - GMX_ASSERT(first_atoms != nullptr, "If we've seen a vsite before, we know what its first atom index was"); + GMX_ASSERT(vsnral != 0, + "If we've seen a vsite before, we know how many constructing atoms " + "it had"); + GMX_ASSERT( + first_atoms != nullptr, + "If we've seen a vsite before, we know what its first atom index was"); /* check if this vsite is constructed from the same atoms */ - if (vsnral == NRAL(pindex[atom].functionType())-1) + if (vsnral == NRAL(pindex[atom].functionType()) - 1) { for (int m = 0; (m < vsnral) && !bKeep; m++) { - const int *subAtoms; - - bool bPresent = false; - subAtoms = plist[pindex[atom].functionType()].interactionTypes[pindex[atom].interactionIndex()].atoms().data() + 1; + const int* subAtoms; + + bool bPresent = false; + subAtoms = plist[pindex[atom].functionType()] + .interactionTypes[pindex[atom].interactionIndex()] + .atoms() + .data() + + 1; for (int n = 0; (n < vsnral) && !bPresent; n++) { if (subAtoms[m] == first_atoms[n]) @@ -1409,8 +1424,10 @@ static void clean_vsite_dihs(gmx::ArrayRef plist, construction of virtual sites. If so, keep it, if not throw away: */ for (int k = 0; (k < 4) && !bKeep; k++) /* for all atoms in the dihedral */ { - GMX_ASSERT(vsnral != 0, "If we've seen a vsite before, we know how many constructing atoms it had"); - GMX_ASSERT(first_atoms != nullptr, "If we've seen a vsite before, we know what its first atom index was"); + GMX_ASSERT(vsnral != 0, + "If we've seen a vsite before, we know how many constructing atoms it had"); + GMX_ASSERT(first_atoms != nullptr, + "If we've seen a vsite before, we know what its first atom index was"); atom = atoms[k]; if (vsite_type[atom] == NOTSET) { @@ -1438,23 +1455,22 @@ static void clean_vsite_dihs(gmx::ArrayRef plist, { dih = ps->interactionTypes.erase(dih); } - } if (oldSize != gmx::ssize(*ps)) { - fprintf(stderr, "Removed %4zu %15ss with virtual sites, %zu left\n", - oldSize-ps->size(), interaction_function[cftype].longname, ps->size()); + fprintf(stderr, "Removed %4zu %15ss with virtual sites, %zu left\n", oldSize - ps->size(), + interaction_function[cftype].longname, ps->size()); } } // TODO use gmx::compat::optional for pindex. void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bool bRmVSiteBds) { - int nvsite, vsite; - int *vsite_type; - std::vector pindex; - std::vector at2vc; + int nvsite, vsite; + int* vsite_type; + std::vector pindex; + std::vector at2vc; /* make vsite_type array */ snew(vsite_type, natoms); @@ -1468,7 +1484,7 @@ void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bo if (interaction_function[ftype].flags & IF_VSITE) { nvsite += plist[ftype].size(); - int i = 0; + int i = 0; while (i < gmx::ssize(plist[ftype])) { vsite = plist[ftype].interactionTypes[i].ai(); @@ -1478,7 +1494,7 @@ void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bo } else { - gmx_fatal(FARGS, "multiple vsite constructions for atom %d", vsite+1); + gmx_fatal(FARGS, "multiple vsite constructions for atom %d", vsite + 1); } if (ftype == F_VSITEN) { @@ -1518,14 +1534,12 @@ void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bo * constructions with fixed distance (which is anyhow useless). * This will generate a fatal error in check_vsite_constraints. */ - if ((interaction_function[ftype].flags & IF_VSITE) && - ftype != F_VSITEN) + if ((interaction_function[ftype].flags & IF_VSITE) && ftype != F_VSITEN) { - for (gmx::index interactionIndex = 0; - interactionIndex < gmx::ssize(plist[ftype]); + for (gmx::index interactionIndex = 0; interactionIndex < gmx::ssize(plist[ftype]); interactionIndex++) { - int k = plist[ftype].interactionTypes[interactionIndex].ai(); + int k = plist[ftype].interactionTypes[interactionIndex].ai(); pindex[k] = VsiteAtomMapping(ftype, interactionIndex); } } @@ -1534,20 +1548,20 @@ void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bo /* remove interactions that include virtual sites */ for (int ftype = 0; ftype < F_NRE; ftype++) { - if ( ( ( interaction_function[ftype].flags & IF_BOND ) && bRmVSiteBds ) || - ( interaction_function[ftype].flags & IF_CONSTRAINT ) ) + if (((interaction_function[ftype].flags & IF_BOND) && bRmVSiteBds) + || (interaction_function[ftype].flags & IF_CONSTRAINT)) { - if (interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT) ) + if (interaction_function[ftype].flags & (IF_BTYPE | IF_CONSTRAINT)) { - clean_vsite_bonds (plist, pindex, ftype, vsite_type); + clean_vsite_bonds(plist, pindex, ftype, vsite_type); } else if (interaction_function[ftype].flags & IF_ATYPE) { clean_vsite_angles(plist, pindex, ftype, vsite_type, at2vc); } - else if ( (ftype == F_PDIHS) || (ftype == F_IDIHS) ) + else if ((ftype == F_PDIHS) || (ftype == F_IDIHS)) { - clean_vsite_dihs (plist, pindex, ftype, vsite_type); + clean_vsite_dihs(plist, pindex, ftype, vsite_type); } } } @@ -1559,7 +1573,6 @@ void clean_vsite_bondeds(gmx::ArrayRef plist, int natoms, bo check_vsite_constraints(plist, ftype, vsite_type); } } - } sfree(vsite_type); } diff --git a/src/gromacs/gmxpreprocess/vsite_parm.h b/src/gromacs/gmxpreprocess/vsite_parm.h index 0026edc91a..8b597f8555 100644 --- a/src/gromacs/gmxpreprocess/vsite_parm.h +++ b/src/gromacs/gmxpreprocess/vsite_parm.h @@ -45,11 +45,13 @@ struct gmx_moltype_t; struct t_atoms; struct InteractionsOfType; -int set_vsites(bool bVerbose, t_atoms *atoms, PreprocessingAtomTypes *atype, +int set_vsites(bool bVerbose, + t_atoms* atoms, + PreprocessingAtomTypes* atype, gmx::ArrayRef plist); /* set parameters for virtual sites, return number of virtual sites */ -void set_vsites_ptype(bool bVerbose, gmx_moltype_t *molt); +void set_vsites_ptype(bool bVerbose, gmx_moltype_t* molt); /* set ptype to VSite for virtual sites */ /*! \brief Clean up the bonded interactions diff --git a/src/gromacs/gmxpreprocess/x2top.cpp b/src/gromacs/gmxpreprocess/x2top.cpp index 80097d53c8..287d776b86 100644 --- a/src/gromacs/gmxpreprocess/x2top.cpp +++ b/src/gromacs/gmxpreprocess/x2top.cpp @@ -71,7 +71,7 @@ #define MARGIN_FAC 1.1 -static bool is_bond(int nnm, t_nm2type nmt[], char *ai, char *aj, real blen) +static bool is_bond(int nnm, t_nm2type nmt[], char* ai, char* aj, real blen) { int i, j; @@ -79,11 +79,11 @@ static bool is_bond(int nnm, t_nm2type nmt[], char *ai, char *aj, real blen) { for (j = 0; (j < nmt[i].nbonds); j++) { - if ((((gmx::equalCaseInsensitive(ai, nmt[i].elem, 1)) && - (gmx::equalCaseInsensitive(aj, nmt[i].bond[j], 1))) || - ((gmx::equalCaseInsensitive(ai, nmt[i].bond[j], 1)) && - (gmx::equalCaseInsensitive(aj, nmt[i].elem, 1)))) && - (fabs(blen-nmt[i].blen[j]) <= 0.1*nmt[i].blen[j])) + if ((((gmx::equalCaseInsensitive(ai, nmt[i].elem, 1)) + && (gmx::equalCaseInsensitive(aj, nmt[i].bond[j], 1))) + || ((gmx::equalCaseInsensitive(ai, nmt[i].bond[j], 1)) + && (gmx::equalCaseInsensitive(aj, nmt[i].elem, 1)))) + && (fabs(blen - nmt[i].blen[j]) <= 0.1 * nmt[i].blen[j])) { return TRUE; } @@ -92,16 +92,21 @@ static bool is_bond(int nnm, t_nm2type nmt[], char *ai, char *aj, real blen) return FALSE; } -static void mk_bonds(int nnm, t_nm2type nmt[], - t_atoms *atoms, const rvec x[], InteractionsOfType *bond, int nbond[], - bool bPBC, matrix box) +static void mk_bonds(int nnm, + t_nm2type nmt[], + t_atoms* atoms, + const rvec x[], + InteractionsOfType* bond, + int nbond[], + bool bPBC, + matrix box) { - int i, j; - t_pbc pbc; - rvec dx; - real dx2; + int i, j; + t_pbc pbc; + rvec dx; + real dx2; - std::array forceParam = {0.0}; + std::array forceParam = { 0.0 }; if (bPBC) { set_pbc(&pbc, -1, box); @@ -113,7 +118,7 @@ static void mk_bonds(int nnm, t_nm2type nmt[], fprintf(stderr, "\ratom %d", i); fflush(stderr); } - for (j = i+1; (j < atoms->nr); j++) + for (j = i + 1; (j < atoms->nr); j++) { if (bPBC) { @@ -125,12 +130,11 @@ static void mk_bonds(int nnm, t_nm2type nmt[], } dx2 = iprod(dx, dx); - if (is_bond(nnm, nmt, *atoms->atomname[i], *atoms->atomname[j], - std::sqrt(dx2))) + if (is_bond(nnm, nmt, *atoms->atomname[i], *atoms->atomname[j], std::sqrt(dx2))) { - forceParam[0] = std::sqrt(dx2); - std::vector atoms = {i, j}; - add_param_to_list (bond, InteractionOfType(atoms, forceParam)); + forceParam[0] = std::sqrt(dx2); + std::vector atoms = { i, j }; + add_param_to_list(bond, InteractionOfType(atoms, forceParam)); nbond[i]++; nbond[j]++; } @@ -140,11 +144,11 @@ static void mk_bonds(int nnm, t_nm2type nmt[], fflush(stderr); } -static int *set_cgnr(t_atoms *atoms, bool bUsePDBcharge, real *qtot, real *mtot) +static int* set_cgnr(t_atoms* atoms, bool bUsePDBcharge, real* qtot, real* mtot) { - int i, n = 1; - int *cgnr; - double qt = 0; + int i, n = 1; + int* cgnr; + double qt = 0; *qtot = *mtot = 0; snew(cgnr, atoms->nr); @@ -154,9 +158,9 @@ static int *set_cgnr(t_atoms *atoms, bool bUsePDBcharge, real *qtot, real *mtot) { atoms->atom[i].q = atoms->pdbinfo[i].bfac; } - qt += atoms->atom[i].q; - *qtot += atoms->atom[i].q; - *mtot += atoms->atom[i].m; + qt += atoms->atom[i].q; + *qtot += atoms->atom[i].q; + *mtot += atoms->atom[i].m; cgnr[i] = n; if (is_int(qt)) { @@ -167,35 +171,32 @@ static int *set_cgnr(t_atoms *atoms, bool bUsePDBcharge, real *qtot, real *mtot) return cgnr; } -static void set_atom_type(PreprocessingAtomTypes *atypes, - t_symtab *tab, - t_atoms *atoms, - InteractionsOfType *bonds, - int *nbonds, - int nnm, - t_nm2type nm2t[]) +static void set_atom_type(PreprocessingAtomTypes* atypes, + t_symtab* tab, + t_atoms* atoms, + InteractionsOfType* bonds, + int* nbonds, + int nnm, + t_nm2type nm2t[]) { - int nresolved; + int nresolved; snew(atoms->atomtype, atoms->nr); nresolved = nm2type(nnm, nm2t, tab, atoms, atypes, nbonds, bonds); if (nresolved != atoms->nr) { - gmx_fatal(FARGS, "Could only find a forcefield type for %d out of %d atoms", - nresolved, atoms->nr); + gmx_fatal(FARGS, "Could only find a forcefield type for %d out of %d atoms", nresolved, atoms->nr); } - fprintf(stderr, "There are %zu different atom types in your sample\n", - atypes->size()); + fprintf(stderr, "There are %zu different atom types in your sample\n", atypes->size()); } -static void lo_set_force_const(InteractionsOfType *plist, real c[], int nrfp, bool bRound, - bool bDih, bool bParam) +static void lo_set_force_const(InteractionsOfType* plist, real c[], int nrfp, bool bRound, bool bDih, bool bParam) { double cc; char buf[32]; - for (auto ¶m : plist->interactionTypes) + for (auto& param : plist->interactionTypes) { if (!bParam) { @@ -219,7 +220,7 @@ static void lo_set_force_const(InteractionsOfType *plist, real c[], int nrfp, bo if (bDih) { c[0] *= c[2]; - c[0] = (static_cast(c[0] + 3600)) % 360; + c[0] = (static_cast(c[0] + 3600)) % 360; if (c[0] > 180) { c[0] -= 360; @@ -228,19 +229,18 @@ static void lo_set_force_const(InteractionsOfType *plist, real c[], int nrfp, bo c[0] += 180; } } - GMX_ASSERT(nrfp <= MAXFORCEPARAM/2, "Only 6 parameters may be used for an interaction"); + GMX_ASSERT(nrfp <= MAXFORCEPARAM / 2, "Only 6 parameters may be used for an interaction"); std::array forceParam; for (int j = 0; (j < nrfp); j++) { - forceParam[j] = c[j]; - forceParam[nrfp+j] = c[j]; + forceParam[j] = c[j]; + forceParam[nrfp + j] = c[j]; } param = InteractionOfType(param.atoms(), forceParam); } } -static void set_force_const(gmx::ArrayRef plist, real kb, real kt, real kp, bool bRound, - bool bParam) +static void set_force_const(gmx::ArrayRef plist, real kb, real kt, real kp, bool bRound, bool bParam) { real c[MAXFORCEPARAM]; @@ -254,25 +254,24 @@ static void set_force_const(gmx::ArrayRef plist, real kb, re lo_set_force_const(&plist[F_PDIHS], c, 3, bRound, TRUE, bParam); } -static void calc_angles_dihs(InteractionsOfType *ang, InteractionsOfType *dih, const rvec x[], bool bPBC, - matrix box) +static void calc_angles_dihs(InteractionsOfType* ang, InteractionsOfType* dih, const rvec x[], bool bPBC, matrix box) { - int t1, t2, t3; - rvec r_ij, r_kj, r_kl, m, n; - real costh; - t_pbc pbc; + int t1, t2, t3; + rvec r_ij, r_kj, r_kl, m, n; + real costh; + t_pbc pbc; if (bPBC) { set_pbc(&pbc, epbcXYZ, box); } - for (auto &angle : ang->interactionTypes) + for (auto& angle : ang->interactionTypes) { int ai = angle.ai(); int aj = angle.aj(); int ak = angle.ak(); - real th = RAD2DEG*bond_angle(x[ai], x[aj], x[ak], bPBC ? &pbc : nullptr, - r_ij, r_kj, &costh, &t1, &t2); + real th = RAD2DEG + * bond_angle(x[ai], x[aj], x[ak], bPBC ? &pbc : nullptr, r_ij, r_kj, &costh, &t1, &t2); angle.setForceParameter(0, th); } for (auto dihedral : dih->interactionTypes) @@ -281,13 +280,14 @@ static void calc_angles_dihs(InteractionsOfType *ang, InteractionsOfType *dih, c int aj = dihedral.aj(); int ak = dihedral.ak(); int al = dihedral.al(); - real ph = RAD2DEG*dih_angle(x[ai], x[aj], x[ak], x[al], bPBC ? &pbc : nullptr, - r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); + real ph = RAD2DEG + * dih_angle(x[ai], x[aj], x[ak], x[al], bPBC ? &pbc : nullptr, r_ij, r_kj, r_kl, + m, n, &t1, &t2, &t3); dihedral.setForceParameter(0, ph); } } -static void dump_hybridization(FILE *fp, t_atoms *atoms, int nbonds[]) +static void dump_hybridization(FILE* fp, t_atoms* atoms, int nbonds[]) { for (int i = 0; (i < atoms->nr); i++) { @@ -295,19 +295,19 @@ static void dump_hybridization(FILE *fp, t_atoms *atoms, int nbonds[]) } } -static void print_pl(FILE *fp, gmx::ArrayRef plist, int ftp, const char *name, - char ***atomname) +static void +print_pl(FILE* fp, gmx::ArrayRef plist, int ftp, const char* name, char*** atomname) { if (!plist[ftp].interactionTypes.empty()) { fprintf(fp, "\n"); fprintf(fp, "[ %s ]\n", name); int nrfp = interaction_function[ftp].nrfpA; - for (const auto ¶m : plist[ftp].interactionTypes) + for (const auto& param : plist[ftp].interactionTypes) { gmx::ArrayRef atoms = param.atoms(); gmx::ArrayRef forceParam = param.forceParam(); - for (const auto &atom : atoms) + for (const auto& atom : atoms) { fprintf(fp, " %5s", *atomname[atom]); } @@ -323,16 +323,16 @@ static void print_pl(FILE *fp, gmx::ArrayRef plist, in } } -static void print_rtp(const char *filenm, - const char *title, - t_atoms *atoms, - gmx::ArrayRef plist, - PreprocessingAtomTypes *atypes, - int cgnr[]) +static void print_rtp(const char* filenm, + const char* title, + t_atoms* atoms, + gmx::ArrayRef plist, + PreprocessingAtomTypes* atypes, + int cgnr[]) { - FILE *fp; + FILE* fp; int i, tp; - const char *tpnm; + const char* tpnm; fp = gmx_fio_fopen(filenm, "w"); fprintf(fp, "; %s\n", title); @@ -347,9 +347,7 @@ static void print_rtp(const char *filenm, { gmx_fatal(FARGS, "tp = %d, i = %d in print_rtp", tp, i); } - fprintf(fp, "%-8s %12s %8.4f %5d\n", - *atoms->atomname[i], tpnm, - atoms->atom[i].q, cgnr[i]); + fprintf(fp, "%-8s %12s %8.4f %5d\n", *atoms->atomname[i], tpnm, atoms->atom[i].q, cgnr[i]); } print_pl(fp, plist, F_BONDS, "bonds", atoms->atomname); print_pl(fp, plist, F_ANGLES, "angles", atoms->atomname); @@ -359,9 +357,9 @@ static void print_rtp(const char *filenm, gmx_fio_fclose(fp); } -int gmx_x2top(int argc, char *argv[]) +int gmx_x2top(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] generates a primitive topology from a coordinate file.", "The program assumes all hydrogens are present when defining", "the hybridization from the atom name and the number of bonds.", @@ -382,83 +380,86 @@ int gmx_x2top(int argc, char *argv[]) "one of the short names above on the command line instead. In that", "case [THISMODULE] just looks for the corresponding file.[PAR]", }; - const char *bugs[] = { + const char* bugs[] = { "The atom type selection is primitive. Virtually no chemical knowledge is used", - "Periodic boundary conditions screw up the bonding", - "No improper dihedrals are generated", - "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in the data directory). Please extend it and send the results back to the GROMACS crew." - }; - FILE *fp; - std::array plist; - t_excls *excls; - t_nm2type *nm2t; - t_mols mymol; - int nnm; - char forcefield[32], ffdir[STRLEN]; - rvec *x; /* coordinates? */ - int *nbonds, *cgnr; - int bts[] = { 1, 1, 1, 2 }; - matrix box; /* box length matrix */ - int natoms; /* number of atoms in one molecule */ - int epbc; - bool bRTP, bTOP, bOPLS; - t_symtab symtab; - real qtot, mtot; - char n2t[STRLEN]; - gmx_output_env_t *oenv; - - t_filenm fnm[] = { - { efSTX, "-f", "conf", ffREAD }, - { efTOP, "-o", "out", ffOPTWR }, - { efRTP, "-r", "out", ffOPTWR } + "Periodic boundary conditions screw up the bonding", "No improper dihedrals are generated", + "The atoms to atomtype translation table is incomplete ([TT]atomname2type.n2t[tt] file in " + "the data directory). Please extend it and send the results back to the GROMACS crew." }; + FILE* fp; + std::array plist; + t_excls* excls; + t_nm2type* nm2t; + t_mols mymol; + int nnm; + char forcefield[32], ffdir[STRLEN]; + rvec* x; /* coordinates? */ + int * nbonds, *cgnr; + int bts[] = { 1, 1, 1, 2 }; + matrix box; /* box length matrix */ + int natoms; /* number of atoms in one molecule */ + int epbc; + bool bRTP, bTOP, bOPLS; + t_symtab symtab; + real qtot, mtot; + char n2t[STRLEN]; + gmx_output_env_t* oenv; + + t_filenm fnm[] = { { efSTX, "-f", "conf", ffREAD }, + { efTOP, "-o", "out", ffOPTWR }, + { efRTP, "-r", "out", ffOPTWR } }; #define NFILE asize(fnm) - real kb = 4e5, kt = 400, kp = 5; - PreprocessResidue rtp_header_settings; - bool bRemoveDihedralIfWithImproper = FALSE; - bool bGenerateHH14Interactions = TRUE; - bool bKeepAllGeneratedDihedrals = FALSE; - int nrexcl = 3; - bool bParam = TRUE, bRound = TRUE; - bool bPairs = TRUE, bPBC = TRUE; - bool bUsePDBcharge = FALSE, bVerbose = FALSE; - const char *molnm = "ICE"; - const char *ff = "oplsaa"; - t_pargs pa[] = { - { "-ff", FALSE, etSTR, {&ff}, + real kb = 4e5, kt = 400, kp = 5; + PreprocessResidue rtp_header_settings; + bool bRemoveDihedralIfWithImproper = FALSE; + bool bGenerateHH14Interactions = TRUE; + bool bKeepAllGeneratedDihedrals = FALSE; + int nrexcl = 3; + bool bParam = TRUE, bRound = TRUE; + bool bPairs = TRUE, bPBC = TRUE; + bool bUsePDBcharge = FALSE, bVerbose = FALSE; + const char* molnm = "ICE"; + const char* ff = "oplsaa"; + t_pargs pa[] = { + { "-ff", + FALSE, + etSTR, + { &ff }, "Force field for your simulation. Type \"select\" for interactive selection." }, - { "-v", FALSE, etBOOL, {&bVerbose}, - "Generate verbose output in the top file." }, - { "-nexcl", FALSE, etINT, {&nrexcl}, - "Number of exclusions" }, - { "-H14", FALSE, etBOOL, {&bGenerateHH14Interactions}, + { "-v", FALSE, etBOOL, { &bVerbose }, "Generate verbose output in the top file." }, + { "-nexcl", FALSE, etINT, { &nrexcl }, "Number of exclusions" }, + { "-H14", + FALSE, + etBOOL, + { &bGenerateHH14Interactions }, "Use 3rd neighbour interactions for hydrogen atoms" }, - { "-alldih", FALSE, etBOOL, {&bKeepAllGeneratedDihedrals}, + { "-alldih", + FALSE, + etBOOL, + { &bKeepAllGeneratedDihedrals }, "Generate all proper dihedrals" }, - { "-remdih", FALSE, etBOOL, {&bRemoveDihedralIfWithImproper}, + { "-remdih", + FALSE, + etBOOL, + { &bRemoveDihedralIfWithImproper }, "Remove dihedrals on the same bond as an improper" }, - { "-pairs", FALSE, etBOOL, {&bPairs}, - "Output 1-4 interactions (pairs) in topology file" }, - { "-name", FALSE, etSTR, {&molnm}, - "Name of your molecule" }, - { "-pbc", FALSE, etBOOL, {&bPBC}, - "Use periodic boundary conditions." }, - { "-pdbq", FALSE, etBOOL, {&bUsePDBcharge}, + { "-pairs", FALSE, etBOOL, { &bPairs }, "Output 1-4 interactions (pairs) in topology file" }, + { "-name", FALSE, etSTR, { &molnm }, "Name of your molecule" }, + { "-pbc", FALSE, etBOOL, { &bPBC }, "Use periodic boundary conditions." }, + { "-pdbq", + FALSE, + etBOOL, + { &bUsePDBcharge }, "Use the B-factor supplied in a [REF].pdb[ref] file for the atomic charges" }, - { "-param", FALSE, etBOOL, {&bParam}, - "Print parameters in the output" }, - { "-round", FALSE, etBOOL, {&bRound}, - "Round off measured values" }, - { "-kb", FALSE, etREAL, {&kb}, - "Bonded force constant (kJ/mol/nm^2)" }, - { "-kt", FALSE, etREAL, {&kt}, - "Angle force constant (kJ/mol/rad^2)" }, - { "-kp", FALSE, etREAL, {&kp}, - "Dihedral angle force constant (kJ/mol/rad^2)" } + { "-param", FALSE, etBOOL, { &bParam }, "Print parameters in the output" }, + { "-round", FALSE, etBOOL, { &bRound }, "Round off measured values" }, + { "-kb", FALSE, etREAL, { &kb }, "Bonded force constant (kJ/mol/nm^2)" }, + { "-kt", FALSE, etREAL, { &kt }, "Angle force constant (kJ/mol/rad^2)" }, + { "-kp", FALSE, etREAL, { &kp }, "Dihedral angle force constant (kJ/mol/rad^2)" } }; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, + asize(bugs), bugs, &oenv)) { return 0; } @@ -469,7 +470,7 @@ int gmx_x2top(int argc, char *argv[]) rtp_header_settings.bRemoveDihedralIfWithImproper = bRemoveDihedralIfWithImproper; rtp_header_settings.bGenerateHH14Interactions = bGenerateHH14Interactions; rtp_header_settings.bKeepAllGeneratedDihedrals = bKeepAllGeneratedDihedrals; - rtp_header_settings.nrexcl = nrexcl; + rtp_header_settings.nrexcl = nrexcl; if (!bRTP && !bTOP) { @@ -477,9 +478,8 @@ int gmx_x2top(int argc, char *argv[]) } /* Force field selection, interactive or direct */ - choose_ff(strcmp(ff, "select") == 0 ? nullptr : ff, - forcefield, sizeof(forcefield), - ffdir, sizeof(ffdir)); + choose_ff(strcmp(ff, "select") == 0 ? nullptr : ff, forcefield, sizeof(forcefield), ffdir, + sizeof(ffdir)); bOPLS = (strcmp(forcefield, "oplsaa") == 0); @@ -488,11 +488,11 @@ int gmx_x2top(int argc, char *argv[]) mymol.nr = 1; /* Read coordinates */ - t_topology *top; + t_topology* top; snew(top, 1); read_tps_conf(opt2fn("-f", NFILE, fnm), top, &epbc, &x, nullptr, box, FALSE); - t_atoms *atoms = &top->atoms; - natoms = atoms->nr; + t_atoms* atoms = &top->atoms; + natoms = atoms->nr; if (atoms->pdbinfo == nullptr) { snew(atoms->pdbinfo, natoms); @@ -502,8 +502,7 @@ int gmx_x2top(int argc, char *argv[]) nm2t = rd_nm2type(n2t, &nnm); if (nnm == 0) { - gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)", - n2t); + gmx_fatal(FARGS, "No or incorrect atomname2type.n2t file found (looking for %s)", n2t); } else { @@ -533,10 +532,8 @@ int gmx_x2top(int argc, char *argv[]) fprintf(stderr, "There are %4zu %s dihedrals, %4zu impropers, %4zu angles\n" " %4zu pairs, %4zu bonds and %4d atoms\n", - plist[F_PDIHS].size(), - bOPLS ? "Ryckaert-Bellemans" : "proper", - plist[F_IDIHS].size(), plist[F_ANGLES].size(), - plist[F_LJ14].size(), plist[F_BONDS].size(), atoms->nr); + plist[F_PDIHS].size(), bOPLS ? "Ryckaert-Bellemans" : "proper", plist[F_IDIHS].size(), + plist[F_ANGLES].size(), plist[F_LJ14].size(), plist[F_BONDS].size(), atoms->nr); calc_angles_dihs(&plist[F_ANGLES], &plist[F_PDIHS], x, bPBC, box); @@ -555,16 +552,15 @@ int gmx_x2top(int argc, char *argv[]) fp = ftp2FILE(efTOP, NFILE, fnm, "w"); print_top_header(fp, ftp2fn(efTOP, NFILE, fnm), TRUE, ffdir, 1.0); - write_top(fp, nullptr, mymol.name.c_str(), atoms, FALSE, bts, plist, excls, &atypes, - cgnr, rtp_header_settings.nrexcl); + write_top(fp, nullptr, mymol.name.c_str(), atoms, FALSE, bts, plist, excls, &atypes, cgnr, + rtp_header_settings.nrexcl); print_top_mols(fp, mymol.name.c_str(), ffdir, nullptr, {}, gmx::arrayRefFromArray(&mymol, 1)); gmx_ffclose(fp); } if (bRTP) { - print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top", - atoms, plist, &atypes, cgnr); + print_rtp(ftp2fn(efRTP, NFILE, fnm), "Generated by x2top", atoms, plist, &atypes, cgnr); } if (debug) diff --git a/src/gromacs/gmxpreprocess/x2top.h b/src/gromacs/gmxpreprocess/x2top.h index 99a5911dfc..39794c9df4 100644 --- a/src/gromacs/gmxpreprocess/x2top.h +++ b/src/gromacs/gmxpreprocess/x2top.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,6 +35,6 @@ #ifndef GMX_GMXPREPROCESS_X2TOP_H #define GMX_GMXPREPROCESS_X2TOP_H -int gmx_x2top(int argc, char *argv[]); +int gmx_x2top(int argc, char* argv[]); #endif diff --git a/src/gromacs/gmxpreprocess/xlate.cpp b/src/gromacs/gmxpreprocess/xlate.cpp index 43f232facd..7c81461f18 100644 --- a/src/gromacs/gmxpreprocess/xlate.cpp +++ b/src/gromacs/gmxpreprocess/xlate.cpp @@ -56,22 +56,22 @@ #include "hackblock.h" -typedef struct { - char *filebase; - char *res; - char *atom; - char *replace; +typedef struct +{ + char* filebase; + char* res; + char* atom; + char* replace; } t_xlate_atom; -static void get_xlatoms(const std::string &filename, FILE *fp, - int *nptr, t_xlate_atom **xlptr) +static void get_xlatoms(const std::string& filename, FILE* fp, int* nptr, t_xlate_atom** xlptr) { char filebase[STRLEN]; char line[STRLEN]; char abuf[1024], rbuf[1024], repbuf[1024], dumbuf[1024]; - char *_ptr; + char* _ptr; int n, na, idum; - t_xlate_atom *xl; + t_xlate_atom* xl; fflib_filename_base(filename.c_str(), filebase, STRLEN); @@ -90,10 +90,11 @@ static void get_xlatoms(const std::string &filename, FILE *fp, } if (na != 3) { - gmx_fatal(FARGS, "Expected a residue name and two atom names in file '%s', not '%s'", filename.c_str(), line); + gmx_fatal(FARGS, "Expected a residue name and two atom names in file '%s', not '%s'", + filename.c_str(), line); } - srenew(xl, n+1); + srenew(xl, n + 1); xl[n].filebase = gmx_strdup(filebase); /* Use wildcards... */ @@ -121,7 +122,7 @@ static void get_xlatoms(const std::string &filename, FILE *fp, *xlptr = xl; } -static void done_xlatom(int nxlate, t_xlate_atom *xlatom) +static void done_xlatom(int nxlate, t_xlate_atom* xlatom) { int i; @@ -138,13 +139,18 @@ static void done_xlatom(int nxlate, t_xlate_atom *xlatom) sfree(xlatom); } -void rename_atoms(const char* xlfile, const char *ffdir, - t_atoms *atoms, t_symtab *symtab, gmx::ArrayRef localPpResidue, - bool bResname, ResidueType *rt, bool bReorderNum, - bool bVerbose) +void rename_atoms(const char* xlfile, + const char* ffdir, + t_atoms* atoms, + t_symtab* symtab, + gmx::ArrayRef localPpResidue, + bool bResname, + ResidueType* rt, + bool bReorderNum, + bool bVerbose) { int nxlate, a, i, resind; - t_xlate_atom *xlatom; + t_xlate_atom* xlatom; char c, *rnm, atombuf[32]; bool bReorderedNum, bRenamed, bMatch; bool bStartTerm, bEndTerm; @@ -159,9 +165,9 @@ void rename_atoms(const char* xlfile, const char *ffdir, else { std::vector fns = fflib_search_file_end(ffdir, ".arn", FALSE); - for (const auto &filename : fns) + for (const auto& filename : fns) { - FILE * fp = fflib_open(filename); + FILE* fp = fflib_open(filename); get_xlatoms(filename, fp, &nxlate, &xlatom); gmx_ffclose(fp); } @@ -171,8 +177,9 @@ void rename_atoms(const char* xlfile, const char *ffdir, { resind = atoms->atom[a].resind; - bStartTerm = (resind == 0) || atoms->resinfo[resind].chainnum != atoms->resinfo[resind-1].chainnum; - bEndTerm = (resind >= atoms->nres-1) || atoms->resinfo[resind].chainnum != atoms->resinfo[resind+1].chainnum; + bStartTerm = (resind == 0) || atoms->resinfo[resind].chainnum != atoms->resinfo[resind - 1].chainnum; + bEndTerm = (resind >= atoms->nres - 1) + || atoms->resinfo[resind].chainnum != atoms->resinfo[resind + 1].chainnum; if (bResname) { @@ -190,9 +197,9 @@ void rename_atoms(const char* xlfile, const char *ffdir, if (isdigit(atombuf[0])) { c = atombuf[0]; - for (i = 0; (static_cast(i) < strlen(atombuf)-1); i++) + for (i = 0; (static_cast(i) < strlen(atombuf) - 1); i++) { - atombuf[i] = atombuf[i+1]; + atombuf[i] = atombuf[i + 1]; } atombuf[i] = c; bReorderedNum = TRUE; @@ -202,27 +209,26 @@ void rename_atoms(const char* xlfile, const char *ffdir, for (i = 0; (i < nxlate) && !bRenamed; i++) { /* Check if the base file name of the rtp and arn entry match */ - if (localPpResidue.empty() || - gmx::equalCaseInsensitive(localPpResidue[resind].filebase, xlatom[i].filebase)) + if (localPpResidue.empty() + || gmx::equalCaseInsensitive(localPpResidue[resind].filebase, xlatom[i].filebase)) { /* Match the residue name */ - bMatch = (xlatom[i].res == nullptr || - (gmx_strcasecmp("protein-nterm", xlatom[i].res) == 0 && - rt->namedResidueHasType(rnm, "Protein") && bStartTerm) || - (gmx_strcasecmp("protein-cterm", xlatom[i].res) == 0 && - rt->namedResidueHasType(rnm, "Protein") && bEndTerm) || - (gmx_strcasecmp("protein", xlatom[i].res) == 0 && - rt->namedResidueHasType(rnm, "Protein")) || - (gmx_strcasecmp("DNA", xlatom[i].res) == 0 && - rt->namedResidueHasType(rnm, "DNA")) || - (gmx_strcasecmp("RNA", xlatom[i].res) == 0 && - rt->namedResidueHasType(rnm, "RNA"))); + bMatch = (xlatom[i].res == nullptr + || (gmx_strcasecmp("protein-nterm", xlatom[i].res) == 0 + && rt->namedResidueHasType(rnm, "Protein") && bStartTerm) + || (gmx_strcasecmp("protein-cterm", xlatom[i].res) == 0 + && rt->namedResidueHasType(rnm, "Protein") && bEndTerm) + || (gmx_strcasecmp("protein", xlatom[i].res) == 0 + && rt->namedResidueHasType(rnm, "Protein")) + || (gmx_strcasecmp("DNA", xlatom[i].res) == 0 + && rt->namedResidueHasType(rnm, "DNA")) + || (gmx_strcasecmp("RNA", xlatom[i].res) == 0 + && rt->namedResidueHasType(rnm, "RNA"))); if (!bMatch) { - const char *ptr0 = rnm; - const char *ptr1 = xlatom[i].res; - while (ptr0[0] != '\0' && ptr1[0] != '\0' && - (ptr0[0] == ptr1[0] || ptr1[0] == '?')) + const char* ptr0 = rnm; + const char* ptr1 = xlatom[i].res; + while (ptr0[0] != '\0' && ptr1[0] != '\0' && (ptr0[0] == ptr1[0] || ptr1[0] == '?')) { ptr0++; ptr1++; @@ -235,14 +241,11 @@ void rename_atoms(const char* xlfile, const char *ffdir, /* Don't free the old atomname, * since it might be in the symtab. */ - const char *ptr0 = xlatom[i].replace; + const char* ptr0 = xlatom[i].replace; if (bVerbose) { - printf("Renaming atom '%s' in residue %d %s to '%s'\n", - *atoms->atomname[a], - atoms->resinfo[resind].nr, - *atoms->resinfo[resind].name, - ptr0); + printf("Renaming atom '%s' in residue %d %s to '%s'\n", *atoms->atomname[a], + atoms->resinfo[resind].nr, *atoms->resinfo[resind].name, ptr0); } atoms->atomname[a] = put_symtab(symtab, ptr0); bRenamed = TRUE; diff --git a/src/gromacs/gmxpreprocess/xlate.h b/src/gromacs/gmxpreprocess/xlate.h index 357fa83576..bb2b12b375 100644 --- a/src/gromacs/gmxpreprocess/xlate.h +++ b/src/gromacs/gmxpreprocess/xlate.h @@ -48,9 +48,14 @@ struct t_symtab; /* If bResname is true renames atoms based on residue names, * otherwise renames atoms based on rtp entry names. */ -void rename_atoms(const char* xlfile, const char *ffdir, - t_atoms *atoms, t_symtab *symtab, gmx::ArrayRef restp, - bool bResname, ResidueType *rt, bool bReorderNum, - bool bVerbose); +void rename_atoms(const char* xlfile, + const char* ffdir, + t_atoms* atoms, + t_symtab* symtab, + gmx::ArrayRef restp, + bool bResname, + ResidueType* rt, + bool bReorderNum, + bool bVerbose); #endif diff --git a/src/gromacs/gpu_utils/clfftinitializer.cpp b/src/gromacs/gpu_utils/clfftinitializer.cpp index 458afc9634..ca6b0c2145 100644 --- a/src/gromacs/gpu_utils/clfftinitializer.cpp +++ b/src/gromacs/gpu_utils/clfftinitializer.cpp @@ -51,7 +51,7 @@ #include "gromacs/utility/stringutil.h" #if GMX_GPU == GMX_GPU_OPENCL -#include +# include #endif namespace gmx @@ -67,10 +67,10 @@ namespace * initialize it more than once. */ //! @{ gmx_unused bool g_clfftInitialized = false; -gmx::Mutex g_clfftMutex; +gmx::Mutex g_clfftMutex; //! @} -} // namespace +} // namespace ClfftInitializer::ClfftInitializer() { @@ -80,12 +80,14 @@ ClfftInitializer::ClfftInitializer() int initErrorCode = clfftInitSetupData(&fftSetup); if (initErrorCode != 0) { - GMX_THROW(InternalError(formatString("Failed to initialize the clFFT library, error code %d", initErrorCode))); + GMX_THROW(InternalError(formatString( + "Failed to initialize the clFFT library, error code %d", initErrorCode))); } initErrorCode = clfftSetup(&fftSetup); if (initErrorCode != 0) { - GMX_THROW(InternalError(formatString("Failed to initialize the clFFT library, error code %d", initErrorCode))); + GMX_THROW(InternalError(formatString( + "Failed to initialize the clFFT library, error code %d", initErrorCode))); } g_clfftInitialized = true; #else @@ -106,4 +108,4 @@ ClfftInitializer::~ClfftInitializer() #endif } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/gpu_utils/clfftinitializer.h b/src/gromacs/gpu_utils/clfftinitializer.h index 4e7d07d406..b07b71565c 100644 --- a/src/gromacs/gpu_utils/clfftinitializer.h +++ b/src/gromacs/gpu_utils/clfftinitializer.h @@ -82,21 +82,21 @@ namespace gmx * See Redmine #2535. */ class ClfftInitializer { - public: - /*! \brief Constructor - * - * This initializers the clFFT library if there is a - * possibility of an FFT task on the device, and preserves it - * until destruction. Any time required for this - * initialization or tear down should not be accrued to - * per-MD-step counters. */ - ClfftInitializer(); - //! Destructor - ~ClfftInitializer(); +public: + /*! \brief Constructor + * + * This initializers the clFFT library if there is a + * possibility of an FFT task on the device, and preserves it + * until destruction. Any time required for this + * initialization or tear down should not be accrued to + * per-MD-step counters. */ + ClfftInitializer(); + //! Destructor + ~ClfftInitializer(); - GMX_DISALLOW_COPY_AND_ASSIGN(ClfftInitializer); + GMX_DISALLOW_COPY_AND_ASSIGN(ClfftInitializer); }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/gpu_utils/cuda_arch_utils.cuh b/src/gromacs/gpu_utils/cuda_arch_utils.cuh index 8f97d1ab93..713a1224d4 100644 --- a/src/gromacs/gpu_utils/cuda_arch_utils.cuh +++ b/src/gromacs/gpu_utils/cuda_arch_utils.cuh @@ -48,9 +48,9 @@ * intended to be used instead of __CUDA_ARCH__. */ #ifndef __CUDA_ARCH__ - #define GMX_PTX_ARCH 0 +# define GMX_PTX_ARCH 0 #else - #define GMX_PTX_ARCH __CUDA_ARCH__ +# define GMX_PTX_ARCH __CUDA_ARCH__ #endif /* Until CC 5.2 and likely for the near future all NVIDIA architectures @@ -74,9 +74,9 @@ static const unsigned int c_fullWarpMask = 0xffffffff; * to provide fallback code. */ #if defined(GMX_DISABLE_CUDA_TEXTURES) || (defined(__clang__) && defined(__CUDA__)) -#define DISABLE_CUDA_TEXTURES 1 +# define DISABLE_CUDA_TEXTURES 1 #else -#define DISABLE_CUDA_TEXTURES 0 +# define DISABLE_CUDA_TEXTURES 0 #endif /*! \brief True if the use of texture fetch in the CUDA kernels is disabled. */ @@ -89,29 +89,29 @@ static const bool c_disableCudaTextures = DISABLE_CUDA_TEXTURES; * */ #if GMX_PTX_ARCH > 0 - #if GMX_PTX_ARCH <= 370 // CC 3.x - #define GMX_CUDA_MAX_BLOCKS_PER_MP 16 - #define GMX_CUDA_MAX_THREADS_PER_MP 2048 - #else // CC 5.x, 6.x - /* Note that this final branch covers all future architectures (current gen - * is 6.x as of writing), hence assuming that these *currently defined* upper - * limits will not be lowered. - */ - #define GMX_CUDA_MAX_BLOCKS_PER_MP 32 - #define GMX_CUDA_MAX_THREADS_PER_MP 2048 - #endif +# if GMX_PTX_ARCH <= 370 // CC 3.x +# define GMX_CUDA_MAX_BLOCKS_PER_MP 16 +# define GMX_CUDA_MAX_THREADS_PER_MP 2048 +# else // CC 5.x, 6.x +/* Note that this final branch covers all future architectures (current gen + * is 6.x as of writing), hence assuming that these *currently defined* upper + * limits will not be lowered. + */ +# define GMX_CUDA_MAX_BLOCKS_PER_MP 32 +# define GMX_CUDA_MAX_THREADS_PER_MP 2048 +# endif #else - #define GMX_CUDA_MAX_BLOCKS_PER_MP 0 - #define GMX_CUDA_MAX_THREADS_PER_MP 0 +# define GMX_CUDA_MAX_BLOCKS_PER_MP 0 +# define GMX_CUDA_MAX_THREADS_PER_MP 0 #endif // Macro defined for clang CUDA device compilation in the presence of debug symbols // used to work around codegen bug that breaks some kernels when assertions are on // at -O1 and higher (tested with clang 6-8). #if defined(__clang__) && defined(__CUDA__) && defined(__CUDA_ARCH__) && !defined(NDEBUG) -#define CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE __attribute__ ((optnone)) +# define CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE __attribute__((optnone)) #else -#define CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE +# define CLANG_DISABLE_OPTIMIZATION_ATTRIBUTE #endif diff --git a/src/gromacs/gpu_utils/cuda_kernel_utils.cuh b/src/gromacs/gpu_utils/cuda_kernel_utils.cuh index daebe3be29..1346c6218e 100644 --- a/src/gromacs/gpu_utils/cuda_kernel_utils.cuh +++ b/src/gromacs/gpu_utils/cuda_kernel_utils.cuh @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,10 +63,8 @@ __device__ __forceinline__ T LDG(const T* ptr) * \param[in] index Non-negative element index * \returns The value from the table at \p index */ -template -static __forceinline__ __device__ -T fetchFromTexture(const cudaTextureObject_t texObj, - int index) +template +static __forceinline__ __device__ T fetchFromTexture(const cudaTextureObject_t texObj, int index) { assert(index >= 0); assert(!c_disableCudaTextures); @@ -84,11 +82,10 @@ T fetchFromTexture(const cudaTextureObject_t texObj, * \param[in] index Non-negative element index * \returns The value from the table at \p index */ -template -static __forceinline__ __device__ -T fetchFromParamLookupTable(const T *d_ptr, - const cudaTextureObject_t texObj, - int index) +template +static __forceinline__ __device__ T fetchFromParamLookupTable(const T* d_ptr, + const cudaTextureObject_t texObj, + int index) { assert(index >= 0); T result; diff --git a/src/gromacs/gpu_utils/cudautils.cu b/src/gromacs/gpu_utils/cudautils.cu index bda125511b..baa91d59e3 100644 --- a/src/gromacs/gpu_utils/cudautils.cu +++ b/src/gromacs/gpu_utils/cudautils.cu @@ -47,8 +47,7 @@ /*** Generic CUDA data operation wrappers ***/ // TODO: template on transferKind to avoid runtime conditionals -int cu_copy_D2H(void *h_dest, void *d_src, size_t bytes, - GpuApiCallBehavior transferKind, cudaStream_t s = nullptr) +int cu_copy_D2H(void* h_dest, void* d_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t s = nullptr) { cudaError_t stat; @@ -70,14 +69,13 @@ int cu_copy_D2H(void *h_dest, void *d_src, size_t bytes, CU_RET_ERR(stat, "DtoH cudaMemcpy failed"); break; - default: - throw; + default: throw; } return 0; } -int cu_copy_D2H_sync(void * h_dest, void * d_src, size_t bytes) +int cu_copy_D2H_sync(void* h_dest, void* d_src, size_t bytes) { return cu_copy_D2H(h_dest, d_src, bytes, GpuApiCallBehavior::Sync); } @@ -85,14 +83,13 @@ int cu_copy_D2H_sync(void * h_dest, void * d_src, size_t bytes) /*! * The copy is launched in stream s or if not specified, in stream 0. */ -int cu_copy_D2H_async(void * h_dest, void * d_src, size_t bytes, cudaStream_t s = nullptr) +int cu_copy_D2H_async(void* h_dest, void* d_src, size_t bytes, cudaStream_t s = nullptr) { return cu_copy_D2H(h_dest, d_src, bytes, GpuApiCallBehavior::Async, s); } // TODO: template on transferKind to avoid runtime conditionals -int cu_copy_H2D(void *d_dest, const void *h_src, size_t bytes, - GpuApiCallBehavior transferKind, cudaStream_t s = nullptr) +int cu_copy_H2D(void* d_dest, const void* h_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t s = nullptr) { cudaError_t stat; @@ -114,14 +111,13 @@ int cu_copy_H2D(void *d_dest, const void *h_src, size_t bytes, CU_RET_ERR(stat, "HtoD cudaMemcpy failed"); break; - default: - throw; + default: throw; } return 0; } -int cu_copy_H2D_sync(void * d_dest, const void * h_src, size_t bytes) +int cu_copy_H2D_sync(void* d_dest, const void* h_src, size_t bytes) { return cu_copy_H2D(d_dest, h_src, bytes, GpuApiCallBehavior::Sync); } @@ -129,7 +125,7 @@ int cu_copy_H2D_sync(void * d_dest, const void * h_src, size_t bytes) /*! * The copy is launched in stream s or if not specified, in stream 0. */ -int cu_copy_H2D_async(void * d_dest, const void * h_src, size_t bytes, cudaStream_t s = nullptr) +int cu_copy_H2D_async(void* d_dest, const void* h_src, size_t bytes, cudaStream_t s = nullptr) { return cu_copy_H2D(d_dest, h_src, bytes, GpuApiCallBehavior::Async, s); } @@ -144,10 +140,8 @@ int cu_copy_H2D_async(void * d_dest, const void * h_src, size_t bytes, cudaStrea * \param[in] d_ptr pointer to device global memory to bind \p texObj to * \param[in] sizeInBytes size of memory area to bind \p texObj to */ -template -static void setup1DTexture(cudaTextureObject_t &texObj, - void *d_ptr, - size_t sizeInBytes) +template +static void setup1DTexture(cudaTextureObject_t& texObj, void* d_ptr, size_t sizeInBytes) { assert(!c_disableCudaTextures); @@ -162,21 +156,18 @@ static void setup1DTexture(cudaTextureObject_t &texObj, rd.res.linear.sizeInBytes = sizeInBytes; memset(&td, 0, sizeof(td)); - td.readMode = cudaReadModeElementType; - stat = cudaCreateTextureObject(&texObj, &rd, &td, nullptr); + td.readMode = cudaReadModeElementType; + stat = cudaCreateTextureObject(&texObj, &rd, &td, nullptr); CU_RET_ERR(stat, "cudaCreateTextureObject failed"); } -template -void initParamLookupTable(T * &d_ptr, - cudaTextureObject_t &texObj, - const T *h_ptr, - int numElem) +template +void initParamLookupTable(T*& d_ptr, cudaTextureObject_t& texObj, const T* h_ptr, int numElem) { const size_t sizeInBytes = numElem * sizeof(*d_ptr); - cudaError_t stat = cudaMalloc((void **)&d_ptr, sizeInBytes); + cudaError_t stat = cudaMalloc((void**)&d_ptr, sizeInBytes); CU_RET_ERR(stat, "cudaMalloc failed in initParamLookupTable"); - cu_copy_H2D_sync(d_ptr, (void *)h_ptr, sizeInBytes); + cu_copy_H2D_sync(d_ptr, (void*)h_ptr, sizeInBytes); if (!c_disableCudaTextures) { @@ -184,9 +175,8 @@ void initParamLookupTable(T * &d_ptr, } } -template -void destroyParamLookupTable(T *d_ptr, - cudaTextureObject_t texObj) +template +void destroyParamLookupTable(T* d_ptr, cudaTextureObject_t texObj) { if (!c_disableCudaTextures) { @@ -199,7 +189,7 @@ void destroyParamLookupTable(T *d_ptr, * One should also verify that the result of cudaCreateChannelDesc() during texture setup * looks reasonable, when instantiating the templates for new types - just in case. */ -template void initParamLookupTable(float * &, cudaTextureObject_t &, const float *, int); -template void destroyParamLookupTable(float *, cudaTextureObject_t); -template void initParamLookupTable(int * &, cudaTextureObject_t &, const int *, int); -template void destroyParamLookupTable(int *, cudaTextureObject_t); +template void initParamLookupTable(float*&, cudaTextureObject_t&, const float*, int); +template void destroyParamLookupTable(float*, cudaTextureObject_t); +template void initParamLookupTable(int*&, cudaTextureObject_t&, const int*, int); +template void destroyParamLookupTable(int*, cudaTextureObject_t); diff --git a/src/gromacs/gpu_utils/cudautils.cuh b/src/gromacs/gpu_utils/cudautils.cuh index 3efb65d0a9..c713bc9408 100644 --- a/src/gromacs/gpu_utils/cudautils.cuh +++ b/src/gromacs/gpu_utils/cudautils.cuh @@ -62,7 +62,7 @@ namespace * \todo This is similar to CU_CHECK_PREV_ERR, which should be * consolidated. */ -static inline void ensureNoPendingCudaError(const char *errorMessage) +static inline void ensureNoPendingCudaError(const char* errorMessage) { // Ensure there is no pending error that would otherwise affect // the behaviour of future error handling. @@ -75,16 +75,17 @@ static inline void ensureNoPendingCudaError(const char *errorMessage) // If we would find an error in a release build, we do not know // what is appropriate to do about it, so assert only for debug // builds. - auto fullMessage = formatString("%s An unhandled error from a previous CUDA operation was detected. %s: %s", - errorMessage, cudaGetErrorName(stat), cudaGetErrorString(stat)); + auto fullMessage = formatString( + "%s An unhandled error from a previous CUDA operation was detected. %s: %s", + errorMessage, cudaGetErrorName(stat), cudaGetErrorString(stat)); GMX_ASSERT(stat == cudaSuccess, fullMessage.c_str()); // TODO When we evolve a better logging framework, use that // for release-build error reporting. gmx_warning("%s", fullMessage.c_str()); } -} // namespace -} // namespace +} // namespace +} // namespace gmx enum class GpuApiCallBehavior; @@ -104,27 +105,39 @@ enum class GpuApiCallBehavior; #ifdef CHECK_CUDA_ERRORS /*! Check for CUDA error on the return status of a CUDA RT API call. */ -#define CU_RET_ERR(status, msg) \ - do { \ - if (status != cudaSuccess) \ - { \ - gmx_fatal(FARGS, "%s: %s\n", msg, cudaGetErrorString(status)); \ - } \ - } while (0) +# define CU_RET_ERR(status, msg) \ + do \ + { \ + if (status != cudaSuccess) \ + { \ + gmx_fatal(FARGS, "%s: %s\n", msg, cudaGetErrorString(status)); \ + } \ + } while (0) /*! Check for any previously occurred uncaught CUDA error. */ -#define CU_CHECK_PREV_ERR() \ - do { \ - cudaError_t _CU_CHECK_PREV_ERR_status = cudaGetLastError(); \ - if (_CU_CHECK_PREV_ERR_status != cudaSuccess) { \ - gmx_warning("Just caught a previously occurred CUDA error (%s), will try to continue.", cudaGetErrorString(_CU_CHECK_PREV_ERR_status)); \ - } \ - } while (0) +# define CU_CHECK_PREV_ERR() \ + do \ + { \ + cudaError_t _CU_CHECK_PREV_ERR_status = cudaGetLastError(); \ + if (_CU_CHECK_PREV_ERR_status != cudaSuccess) \ + { \ + gmx_warning( \ + "Just caught a previously occurred CUDA error (%s), will try to " \ + "continue.", \ + cudaGetErrorString(_CU_CHECK_PREV_ERR_status)); \ + } \ + } while (0) #else /* CHECK_CUDA_ERRORS */ -#define CU_RET_ERR(status, msg) do { } while (0) -#define CU_CHECK_PREV_ERR() do { } while (0) +# define CU_RET_ERR(status, msg) \ + do \ + { \ + } while (0) +# define CU_CHECK_PREV_ERR() \ + do \ + { \ + } while (0) #endif /* CHECK_CUDA_ERRORS */ @@ -136,34 +149,34 @@ enum class GpuApiCallBehavior; */ struct gmx_device_info_t { - int id; /* id of the CUDA device */ - cudaDeviceProp prop; /* CUDA device properties */ - int stat; /* result of the device check */ + int id; /* id of the CUDA device */ + cudaDeviceProp prop; /* CUDA device properties */ + int stat; /* result of the device check */ }; /*! Launches synchronous or asynchronous device to host memory copy. * * The copy is launched in stream s or if not specified, in stream 0. */ -int cu_copy_D2H(void *h_dest, void *d_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t /*s = nullptr*/); +int cu_copy_D2H(void* h_dest, void* d_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t /*s = nullptr*/); /*! Launches synchronous host to device memory copy in stream 0. */ -int cu_copy_D2H_sync(void * /*h_dest*/, void * /*d_src*/, size_t /*bytes*/); +int cu_copy_D2H_sync(void* /*h_dest*/, void* /*d_src*/, size_t /*bytes*/); /*! Launches asynchronous host to device memory copy in stream s. */ -int cu_copy_D2H_async(void * /*h_dest*/, void * /*d_src*/, size_t /*bytes*/, cudaStream_t /*s = nullptr*/); +int cu_copy_D2H_async(void* /*h_dest*/, void* /*d_src*/, size_t /*bytes*/, cudaStream_t /*s = nullptr*/); /*! Launches synchronous or asynchronous host to device memory copy. * * The copy is launched in stream s or if not specified, in stream 0. */ -int cu_copy_H2D(void *d_dest, const void *h_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t /*s = nullptr*/); +int cu_copy_H2D(void* d_dest, const void* h_src, size_t bytes, GpuApiCallBehavior transferKind, cudaStream_t /*s = nullptr*/); /*! Launches synchronous host to device memory copy. */ -int cu_copy_H2D_sync(void * /*d_dest*/, const void * /*h_src*/, size_t /*bytes*/); +int cu_copy_H2D_sync(void* /*d_dest*/, const void* /*h_src*/, size_t /*bytes*/); /*! Launches asynchronous host to device memory copy in stream s. */ -int cu_copy_H2D_async(void * /*d_dest*/, const void * /*h_src*/, size_t /*bytes*/, cudaStream_t /*s = nullptr*/); +int cu_copy_H2D_async(void* /*d_dest*/, const void* /*h_src*/, size_t /*bytes*/, cudaStream_t /*s = nullptr*/); // TODO: the 2 functions below are pretty much a constructor/destructor of a simple // GPU table object. There is also almost self-contained fetchFromParamLookupTable() @@ -180,16 +193,13 @@ int cu_copy_H2D_async(void * /*d_dest*/, const void * /*h_src*/, size_t /*bytes* * \param[in] h_ptr pointer to the host memory to be uploaded to the device * \param[in] numElem number of elements in the h_ptr */ -template -void initParamLookupTable(T * &d_ptr, - cudaTextureObject_t &texObj, - const T *h_ptr, - int numElem); +template +void initParamLookupTable(T*& d_ptr, cudaTextureObject_t& texObj, const T* h_ptr, int numElem); // Add extern declarations so each translation unit understands that // there will be a definition provided. -extern template void initParamLookupTable(int * &, cudaTextureObject_t &, const int *, int); -extern template void initParamLookupTable(float * &, cudaTextureObject_t &, const float *, int); +extern template void initParamLookupTable(int*&, cudaTextureObject_t&, const int*, int); +extern template void initParamLookupTable(float*&, cudaTextureObject_t&, const float*, int); /*! \brief Destroy parameter lookup table. * @@ -199,14 +209,13 @@ extern template void initParamLookupTable(float * &, cudaTextureObject_t * \param[in] d_ptr Device pointer to the memory to be deallocated * \param[in] texObj Texture object to be deinitialized */ -template -void destroyParamLookupTable(T *d_ptr, - cudaTextureObject_t texObj); +template +void destroyParamLookupTable(T* d_ptr, cudaTextureObject_t texObj); // Add extern declarations so each translation unit understands that // there will be a definition provided. -extern template void destroyParamLookupTable(int *, cudaTextureObject_t); -extern template void destroyParamLookupTable(float *, cudaTextureObject_t); +extern template void destroyParamLookupTable(int*, cudaTextureObject_t); +extern template void destroyParamLookupTable(float*, cudaTextureObject_t); /*! \brief Add a triplets stored in a float3 to an rvec variable. * @@ -215,7 +224,7 @@ extern template void destroyParamLookupTable(float *, cudaTextureObject_t */ static inline void rvec_inc(rvec a, const float3 b) { - rvec tmp = {b.x, b.y, b.z}; + rvec tmp = { b.x, b.y, b.z }; rvec_inc(a, tmp); } @@ -245,12 +254,13 @@ static inline bool haveStreamTasksCompleted(cudaStream_t s) return false; } - GMX_ASSERT(stat != cudaErrorInvalidResourceHandle, "Stream idnetifier not valid"); + GMX_ASSERT(stat != cudaErrorInvalidResourceHandle, "Stream idnetifier not valid"); // cudaSuccess and cudaErrorNotReady are the expected return values CU_RET_ERR(stat, "Unexpected cudaStreamQuery failure"); - GMX_ASSERT(stat == cudaSuccess, "Values other than cudaSuccess should have been explicitly handled"); + GMX_ASSERT(stat == cudaSuccess, + "Values other than cudaSuccess should have been explicitly handled"); return true; } @@ -266,9 +276,9 @@ static inline bool haveStreamTasksCompleted(cudaStream_t s) * \tparam KernelPtr Kernel function handle type * \param[in] argIndex Index of the current argument */ -template +template void prepareGpuKernelArgument(KernelPtr /*kernel*/, - std::array */* kernelArgsPtr */, + std::array* /* kernelArgsPtr */, size_t gmx_used_in_debug argIndex) { GMX_ASSERT(argIndex == totalArgsCount, "Tail expansion"); @@ -289,15 +299,15 @@ void prepareGpuKernelArgument(KernelPtr /*kernel*/, * \param[in] argPtr Pointer to the current argument * \param[in] otherArgsPtrs Pack of pointers to arguments remaining to process after the current one */ -template -void prepareGpuKernelArgument(KernelPtr kernel, - std::array *kernelArgsPtr, - size_t argIndex, - const CurrentArg *argPtr, - const RemainingArgs *... otherArgsPtrs) +template +void prepareGpuKernelArgument(KernelPtr kernel, + std::array* kernelArgsPtr, + size_t argIndex, + const CurrentArg* argPtr, + const RemainingArgs*... otherArgsPtrs) { - (*kernelArgsPtr)[argIndex] = (void *)argPtr; - prepareGpuKernelArgument(kernel, kernelArgsPtr, argIndex + 1, otherArgsPtrs ...); + (*kernelArgsPtr)[argIndex] = (void*)argPtr; + prepareGpuKernelArgument(kernel, kernelArgsPtr, argIndex + 1, otherArgsPtrs...); } /*! \brief @@ -310,13 +320,13 @@ void prepareGpuKernelArgument(KernelPtr kernel, * \param[in] argsPtrs Pointers to all the kernel arguments * \returns A prepared parameter pack to be used with launchGpuKernel() as the last argument. */ -template -std::array prepareGpuKernelArguments(KernelPtr kernel, - const KernelLaunchConfig & /*config */, - const Args *... argsPtrs) +template +std::array prepareGpuKernelArguments(KernelPtr kernel, + const KernelLaunchConfig& /*config */, + const Args*... argsPtrs) { - std::array kernelArgs; - prepareGpuKernelArgument(kernel, &kernelArgs, 0, argsPtrs ...); + std::array kernelArgs; + prepareGpuKernelArgument(kernel, &kernelArgs, 0, argsPtrs...); return kernelArgs; } @@ -326,25 +336,27 @@ std::array prepareGpuKernelArguments(KernelPtr * \param[in] kernel Kernel function handle * \param[in] config Kernel configuration for launching * \param[in] kernelName Human readable kernel description, for error handling only - * \param[in] kernelArgs Array of the pointers to the kernel arguments, prepared by prepareGpuKernelArguments() - * \throws gmx::InternalError on kernel launch failure + * \param[in] kernelArgs Array of the pointers to the kernel arguments, prepared by + * prepareGpuKernelArguments() \throws gmx::InternalError on kernel launch failure */ -template -void launchGpuKernel(void (*kernel)(Args...), - const KernelLaunchConfig &config, - CommandEvent */*timingEvent */, - const char *kernelName, - const std::array &kernelArgs) +template +void launchGpuKernel(void (*kernel)(Args...), + const KernelLaunchConfig& config, + CommandEvent* /*timingEvent */, + const char* kernelName, + const std::array& kernelArgs) { dim3 blockSize(config.blockSize[0], config.blockSize[1], config.blockSize[2]); dim3 gridSize(config.gridSize[0], config.gridSize[1], config.gridSize[2]); - cudaLaunchKernel((void *)kernel, gridSize, blockSize, const_cast(kernelArgs.data()), config.sharedMemorySize, config.stream); + cudaLaunchKernel((void*)kernel, gridSize, blockSize, const_cast(kernelArgs.data()), + config.sharedMemorySize, config.stream); cudaError_t status = cudaGetLastError(); if (cudaSuccess != status) { - const std::string errorMessage = "GPU kernel (" + std::string(kernelName) + - ") failed to launch: " + std::string(cudaGetErrorString(status)); + const std::string errorMessage = + "GPU kernel (" + std::string(kernelName) + + ") failed to launch: " + std::string(cudaGetErrorString(status)); GMX_THROW(gmx::InternalError(errorMessage)); } } diff --git a/src/gromacs/gpu_utils/device_utils.clh b/src/gromacs/gpu_utils/device_utils.clh index f741527328..dd95c9128f 100644 --- a/src/gromacs/gpu_utils/device_utils.clh +++ b/src/gromacs/gpu_utils/device_utils.clh @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,21 +56,19 @@ * \param[in] addr The address where the data to be added to resides * \param[in] val The value to increment with */ -gmx_opencl_inline -void atomicAdd_l_f(volatile __local float *addr, float val) +gmx_opencl_inline void atomicAdd_l_f(volatile __local float* addr, float val) { union { unsigned int u32; float f32; } next, expected, current; - current.f32 = *addr; + current.f32 = *addr; do { expected.f32 = current.f32; next.f32 = expected.f32 + val; - current.u32 = atomic_cmpxchg( (volatile __local unsigned int *)addr, expected.u32, next.u32); - } - while (current.u32 != expected.u32); + current.u32 = atomic_cmpxchg((volatile __local unsigned int*)addr, expected.u32, next.u32); + } while (current.u32 != expected.u32); } /* \brief Atomically increment the float3 value at address addr (in local memory) with value val. @@ -82,11 +80,11 @@ void atomicAdd_l_f(volatile __local float *addr, float val) * \param[in] addr The address where the data to be added to resides * \param[in] val The value to increment with */ -gmx_opencl_inline void atomicAdd_l_f3(__local float3 *addr, float3 val) +gmx_opencl_inline void atomicAdd_l_f3(__local float3* addr, float3 val) { - atomicAdd_l_f( ((__local float*)(addr)), val.x); - atomicAdd_l_f( ((__local float*)(addr))+1, val.y); - atomicAdd_l_f( ((__local float*)(addr))+2, val.z); + atomicAdd_l_f(((__local float*)(addr)), val.x); + atomicAdd_l_f(((__local float*)(addr)) + 1, val.y); + atomicAdd_l_f(((__local float*)(addr)) + 2, val.z); } /* \brief Atomically increment the float value at address addr (in global memory) with value val. @@ -96,20 +94,19 @@ gmx_opencl_inline void atomicAdd_l_f3(__local float3 *addr, float3 val) * \param[in] addr The address where the data to be added to resides * \param[in] val The value to increment with */ -gmx_opencl_inline void atomicAdd_g_f(volatile __global float *addr, float val) +gmx_opencl_inline void atomicAdd_g_f(volatile __global float* addr, float val) { union { unsigned int u32; float f32; } next, expected, current; - current.f32 = *addr; + current.f32 = *addr; do { expected.f32 = current.f32; next.f32 = expected.f32 + val; - current.u32 = atomic_cmpxchg( (volatile __global unsigned int *)addr, expected.u32, next.u32); - } - while (current.u32 != expected.u32); + current.u32 = atomic_cmpxchg((volatile __global unsigned int*)addr, expected.u32, next.u32); + } while (current.u32 != expected.u32); } /* \brief Atomically increment the float3 value at address addr (in local memory) with value val. @@ -122,7 +119,7 @@ gmx_opencl_inline void atomicAdd_g_f(volatile __global float *addr, float val) * \param[in] addr The address where the data to be added to resides * \param[in] val The value to increment with */ -gmx_opencl_inline void atomicAdd_g_f3(__global float *addr, const float3 val) +gmx_opencl_inline void atomicAdd_g_f3(__global float* addr, const float3 val) { atomicAdd_g_f(addr, val.x); atomicAdd_g_f(addr + 1, val.y); diff --git a/src/gromacs/gpu_utils/devicebuffer.cuh b/src/gromacs/gpu_utils/devicebuffer.cuh index 7e7cfe91a7..2005a71bb1 100644 --- a/src/gromacs/gpu_utils/devicebuffer.cuh +++ b/src/gromacs/gpu_utils/devicebuffer.cuh @@ -59,13 +59,11 @@ * \param[in] numValues Number of values to accomodate. * \param[in] deviceContext The buffer's dummy device context - not managed explicitly in CUDA RT. */ -template -void allocateDeviceBuffer(DeviceBuffer *buffer, - size_t numValues, - DeviceContext /* deviceContext */) +template +void allocateDeviceBuffer(DeviceBuffer* buffer, size_t numValues, DeviceContext /* deviceContext */) { GMX_ASSERT(buffer, "needs a buffer pointer"); - cudaError_t stat = cudaMalloc((void **)buffer, numValues * sizeof(ValueType)); + cudaError_t stat = cudaMalloc((void**)buffer, numValues * sizeof(ValueType)); GMX_RELEASE_ASSERT(stat == cudaSuccess, "cudaMalloc failure"); } @@ -77,8 +75,8 @@ void allocateDeviceBuffer(DeviceBuffer *buffer, * * \param[in] buffer Pointer to the buffer to free. */ -template -void freeDeviceBuffer(DeviceBuffer *buffer) +template +void freeDeviceBuffer(DeviceBuffer* buffer) { GMX_ASSERT(buffer, "needs a buffer pointer"); if (*buffer) @@ -102,14 +100,14 @@ void freeDeviceBuffer(DeviceBuffer *buffer) * \param[out] timingEvent A dummy pointer to the H2D copy timing event to be filled in. * Not used in CUDA implementation. */ -template -void copyToDeviceBuffer(DeviceBuffer *buffer, - const ValueType *hostBuffer, +template +void copyToDeviceBuffer(DeviceBuffer* buffer, + const ValueType* hostBuffer, size_t startingOffset, size_t numValues, CommandStream stream, GpuApiCallBehavior transferKind, - CommandEvent */*timingEvent*/) + CommandEvent* /*timingEvent*/) { if (numValues == 0) { @@ -123,18 +121,20 @@ void copyToDeviceBuffer(DeviceBuffer *buffer, switch (transferKind) { case GpuApiCallBehavior::Async: - GMX_ASSERT(isHostMemoryPinned(hostBuffer), "Source host buffer was not pinned for CUDA"); - stat = cudaMemcpyAsync(*((ValueType **)buffer) + startingOffset, hostBuffer, bytes, cudaMemcpyHostToDevice, stream); + GMX_ASSERT(isHostMemoryPinned(hostBuffer), + "Source host buffer was not pinned for CUDA"); + stat = cudaMemcpyAsync(*((ValueType**)buffer) + startingOffset, hostBuffer, bytes, + cudaMemcpyHostToDevice, stream); GMX_RELEASE_ASSERT(stat == cudaSuccess, "Asynchronous H2D copy failed"); break; case GpuApiCallBehavior::Sync: - stat = cudaMemcpy(*((ValueType **)buffer) + startingOffset, hostBuffer, bytes, cudaMemcpyHostToDevice); + stat = cudaMemcpy(*((ValueType**)buffer) + startingOffset, hostBuffer, bytes, + cudaMemcpyHostToDevice); GMX_RELEASE_ASSERT(stat == cudaSuccess, "Synchronous H2D copy failed"); break; - default: - throw; + default: throw; } } @@ -154,14 +154,14 @@ void copyToDeviceBuffer(DeviceBuffer *buffer, * \param[out] timingEvent A dummy pointer to the H2D copy timing event to be filled in. * Not used in CUDA implementation. */ -template -void copyFromDeviceBuffer(ValueType *hostBuffer, - DeviceBuffer *buffer, - size_t startingOffset, - size_t numValues, - CommandStream stream, - GpuApiCallBehavior transferKind, - CommandEvent */*timingEvent*/) +template +void copyFromDeviceBuffer(ValueType* hostBuffer, + DeviceBuffer* buffer, + size_t startingOffset, + size_t numValues, + CommandStream stream, + GpuApiCallBehavior transferKind, + CommandEvent* /*timingEvent*/) { GMX_ASSERT(buffer, "needs a buffer pointer"); GMX_ASSERT(hostBuffer, "needs a host buffer pointer"); @@ -171,18 +171,20 @@ void copyFromDeviceBuffer(ValueType *hostBuffer, switch (transferKind) { case GpuApiCallBehavior::Async: - GMX_ASSERT(isHostMemoryPinned(hostBuffer), "Destination host buffer was not pinned for CUDA"); - stat = cudaMemcpyAsync(hostBuffer, *((ValueType **)buffer) + startingOffset, bytes, cudaMemcpyDeviceToHost, stream); + GMX_ASSERT(isHostMemoryPinned(hostBuffer), + "Destination host buffer was not pinned for CUDA"); + stat = cudaMemcpyAsync(hostBuffer, *((ValueType**)buffer) + startingOffset, bytes, + cudaMemcpyDeviceToHost, stream); GMX_RELEASE_ASSERT(stat == cudaSuccess, "Asynchronous D2H copy failed"); break; case GpuApiCallBehavior::Sync: - stat = cudaMemcpy(hostBuffer, *((ValueType **)buffer) + startingOffset, bytes, cudaMemcpyDeviceToHost); + stat = cudaMemcpy(hostBuffer, *((ValueType**)buffer) + startingOffset, bytes, + cudaMemcpyDeviceToHost); GMX_RELEASE_ASSERT(stat == cudaSuccess, "Synchronous D2H copy failed"); break; - default: - throw; + default: throw; } } @@ -191,21 +193,17 @@ void copyFromDeviceBuffer(ValueType *hostBuffer, * * \tparam ValueType Raw value type of the \p buffer. * \param[in,out] buffer Pointer to the device-side buffer - * \param[in] startingOffset Offset (in values) at the device-side buffer to start clearing at. - * \param[in] numValues Number of values to clear. - * \param[in] stream GPU stream. + * \param[in] startingOffset Offset (in values) at the device-side buffer to start clearing + * at. \param[in] numValues Number of values to clear. \param[in] stream GPU stream. */ -template -void clearDeviceBufferAsync(DeviceBuffer *buffer, - size_t startingOffset, - size_t numValues, - CommandStream stream) +template +void clearDeviceBufferAsync(DeviceBuffer* buffer, size_t startingOffset, size_t numValues, CommandStream stream) { GMX_ASSERT(buffer, "needs a buffer pointer"); const size_t bytes = numValues * sizeof(ValueType); const char pattern = 0; - cudaError_t stat = cudaMemsetAsync(*((ValueType **)buffer) + startingOffset, pattern, bytes, stream); + cudaError_t stat = cudaMemsetAsync(*((ValueType**)buffer) + startingOffset, pattern, bytes, stream); GMX_RELEASE_ASSERT(stat == cudaSuccess, "Couldn't clear the device buffer"); } diff --git a/src/gromacs/gpu_utils/devicebuffer.h b/src/gromacs/gpu_utils/devicebuffer.h index 5c469cead9..4c28d49613 100644 --- a/src/gromacs/gpu_utils/devicebuffer.h +++ b/src/gromacs/gpu_utils/devicebuffer.h @@ -51,11 +51,11 @@ #include "gromacs/utility/smalloc.h" // TODO: this is only for over_alloc_large #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/devicebuffer.cuh" +# include "gromacs/gpu_utils/devicebuffer.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/devicebuffer_ocl.h" +# include "gromacs/gpu_utils/devicebuffer_ocl.h" #else -#error "devicebuffer.h included on non-GPU build!" +# error "devicebuffer.h included on non-GPU build!" #endif /*! \brief @@ -75,11 +75,11 @@ * \param[in,out] currentMaxNumValues The pointer to the buffer's capacity. * \param[in] deviceContext The buffer's device context. */ -template -void reallocateDeviceBuffer(DeviceBuffer *buffer, +template +void reallocateDeviceBuffer(DeviceBuffer* buffer, size_t numValues, - int *currentNumValues, - int *currentMaxNumValues, + int* currentNumValues, + int* currentMaxNumValues, DeviceContext deviceContext) { GMX_ASSERT(buffer, "needs a buffer pointer"); diff --git a/src/gromacs/gpu_utils/devicebuffer_datatype.h b/src/gromacs/gpu_utils/devicebuffer_datatype.h index 13a8bd4674..9ee6517318 100644 --- a/src/gromacs/gpu_utils/devicebuffer_datatype.h +++ b/src/gromacs/gpu_utils/devicebuffer_datatype.h @@ -50,11 +50,11 @@ //! \brief A device-side buffer of ValueTypes template -using DeviceBuffer = ValueType *; +using DeviceBuffer = ValueType*; #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gputraits_ocl.h" +# include "gromacs/gpu_utils/gputraits_ocl.h" /*! \libinternal \brief * A minimal cl_mem wrapper that remembers its allocation type. @@ -63,17 +63,22 @@ using DeviceBuffer = ValueType *; template class TypedClMemory { - private: - /*! \brief Underlying data - * - * \todo Make it nullptr when there are no snew()'s around - */ - cl_mem data_; - public: - //! \brief An assignment operator - the purpose is to make allocation/zeroing work - TypedClMemory &operator=(cl_mem data){data_ = data; return *this; } - //! \brief Returns underlying cl_mem transparently - operator cl_mem() {return data_; } +private: + /*! \brief Underlying data + * + * \todo Make it nullptr when there are no snew()'s around + */ + cl_mem data_; + +public: + //! \brief An assignment operator - the purpose is to make allocation/zeroing work + TypedClMemory& operator=(cl_mem data) + { + data_ = data; + return *this; + } + //! \brief Returns underlying cl_mem transparently + operator cl_mem() { return data_; } }; //! \libinternal \brief A device-side buffer of ValueTypes @@ -84,9 +89,9 @@ using DeviceBuffer = TypedClMemory; //! \brief A device-side buffer of ValueTypes template -using DeviceBuffer = void *; +using DeviceBuffer = void*; #endif -#endif // GMX_GPU_UTILS_DEVICEBUFFER_DATATYPE_H +#endif // GMX_GPU_UTILS_DEVICEBUFFER_DATATYPE_H diff --git a/src/gromacs/gpu_utils/devicebuffer_ocl.h b/src/gromacs/gpu_utils/devicebuffer_ocl.h index 723b391b13..ce1dcb74cb 100644 --- a/src/gromacs/gpu_utils/devicebuffer_ocl.h +++ b/src/gromacs/gpu_utils/devicebuffer_ocl.h @@ -59,15 +59,14 @@ * \param[in] numValues Number of values to accomodate. * \param[in] deviceContext The buffer's device context-to-be. */ -template -void allocateDeviceBuffer(DeviceBuffer *buffer, - size_t numValues, - DeviceContext deviceContext) +template +void allocateDeviceBuffer(DeviceBuffer* buffer, size_t numValues, DeviceContext deviceContext) { GMX_ASSERT(buffer, "needs a buffer pointer"); - void *hostPtr = nullptr; + void* hostPtr = nullptr; cl_int clError; - *buffer = clCreateBuffer(deviceContext, CL_MEM_READ_WRITE, numValues * sizeof(ValueType), hostPtr, &clError); + *buffer = clCreateBuffer(deviceContext, CL_MEM_READ_WRITE, numValues * sizeof(ValueType), + hostPtr, &clError); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "clCreateBuffer failure"); } @@ -79,8 +78,8 @@ void allocateDeviceBuffer(DeviceBuffer *buffer, * * \param[in] buffer Pointer to the buffer to free. */ -template -void freeDeviceBuffer(DeviceBuffer *buffer) +template +void freeDeviceBuffer(DeviceBuffer* buffer) { GMX_ASSERT(buffer, "needs a buffer pointer"); if (*buffer) @@ -105,14 +104,14 @@ void freeDeviceBuffer(DeviceBuffer *buffer) * If the pointer is not null, the event can further be used * to queue a wait for this operation or to query profiling information. */ -template -void copyToDeviceBuffer(DeviceBuffer *buffer, - const ValueType *hostBuffer, +template +void copyToDeviceBuffer(DeviceBuffer* buffer, + const ValueType* hostBuffer, size_t startingOffset, size_t numValues, CommandStream stream, GpuApiCallBehavior transferKind, - CommandEvent *timingEvent) + CommandEvent* timingEvent) { if (numValues == 0) { @@ -126,17 +125,18 @@ void copyToDeviceBuffer(DeviceBuffer *buffer, switch (transferKind) { case GpuApiCallBehavior::Async: - clError = clEnqueueWriteBuffer(stream, *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, nullptr, timingEvent); + clError = clEnqueueWriteBuffer(stream, *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, + nullptr, timingEvent); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "Asynchronous H2D copy failed"); break; case GpuApiCallBehavior::Sync: - clError = clEnqueueWriteBuffer(stream, *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, nullptr, timingEvent); + clError = clEnqueueWriteBuffer(stream, *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, + nullptr, timingEvent); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "Synchronous H2D copy failed"); break; - default: - throw; + default: throw; } } @@ -156,14 +156,14 @@ void copyToDeviceBuffer(DeviceBuffer *buffer, * If the pointer is not null, the event can further be used * to queue a wait for this operation or to query profiling information. */ -template -void copyFromDeviceBuffer(ValueType *hostBuffer, - DeviceBuffer *buffer, - size_t startingOffset, - size_t numValues, - CommandStream stream, - GpuApiCallBehavior transferKind, - CommandEvent *timingEvent) +template +void copyFromDeviceBuffer(ValueType* hostBuffer, + DeviceBuffer* buffer, + size_t startingOffset, + size_t numValues, + CommandStream stream, + GpuApiCallBehavior transferKind, + CommandEvent* timingEvent) { GMX_ASSERT(buffer, "needs a buffer pointer"); GMX_ASSERT(hostBuffer, "needs a host buffer pointer"); @@ -173,17 +173,18 @@ void copyFromDeviceBuffer(ValueType *hostBuffer, switch (transferKind) { case GpuApiCallBehavior::Async: - clError = clEnqueueReadBuffer(stream, *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, nullptr, timingEvent); + clError = clEnqueueReadBuffer(stream, *buffer, CL_FALSE, offset, bytes, hostBuffer, 0, + nullptr, timingEvent); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "Asynchronous D2H copy failed"); break; case GpuApiCallBehavior::Sync: - clError = clEnqueueReadBuffer(stream, *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, nullptr, timingEvent); + clError = clEnqueueReadBuffer(stream, *buffer, CL_TRUE, offset, bytes, hostBuffer, 0, + nullptr, timingEvent); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "Synchronous D2H copy failed"); break; - default: - throw; + default: throw; } } @@ -192,26 +193,21 @@ void copyFromDeviceBuffer(ValueType *hostBuffer, * * \tparam ValueType Raw value type of the \p buffer. * \param[in,out] buffer Pointer to the device-side buffer - * \param[in] startingOffset Offset (in values) at the device-side buffer to start clearing at. - * \param[in] numValues Number of values to clear. - * \param[in] stream GPU stream. + * \param[in] startingOffset Offset (in values) at the device-side buffer to start clearing + * at. \param[in] numValues Number of values to clear. \param[in] stream GPU stream. */ -template -void clearDeviceBufferAsync(DeviceBuffer *buffer, - size_t startingOffset, - size_t numValues, - CommandStream stream) +template +void clearDeviceBufferAsync(DeviceBuffer* buffer, size_t startingOffset, size_t numValues, CommandStream stream) { GMX_ASSERT(buffer, "needs a buffer pointer"); const size_t offset = startingOffset * sizeof(ValueType); const size_t bytes = numValues * sizeof(ValueType); const ValueType pattern = 0; const cl_uint numWaitEvents = 0; - const cl_event *waitEvents = nullptr; + const cl_event* waitEvents = nullptr; cl_event commandEvent; - cl_int clError = clEnqueueFillBuffer(stream, *buffer, &pattern, sizeof(pattern), - offset, bytes, - numWaitEvents, waitEvents, &commandEvent); + cl_int clError = clEnqueueFillBuffer(stream, *buffer, &pattern, sizeof(pattern), offset, bytes, + numWaitEvents, waitEvents, &commandEvent); GMX_RELEASE_ASSERT(clError == CL_SUCCESS, "Couldn't clear the device buffer"); } diff --git a/src/gromacs/gpu_utils/gmxopencl.h b/src/gromacs/gpu_utils/gmxopencl.h index 3e4f7e86ff..15a00fd033 100644 --- a/src/gromacs/gpu_utils/gmxopencl.h +++ b/src/gromacs/gpu_utils/gmxopencl.h @@ -53,13 +53,13 @@ features that were deprecated in 1.2 or 2.0, so that they don't warn about it. */ ///@{ -# define CL_USE_DEPRECATED_OPENCL_1_2_APIS -# define CL_USE_DEPRECATED_OPENCL_2_0_APIS +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS +#define CL_USE_DEPRECATED_OPENCL_2_0_APIS ///@} -# ifdef __APPLE__ +#ifdef __APPLE__ # include -# else +#else # include -# endif +#endif #endif diff --git a/src/gromacs/gpu_utils/gpu_macros.h b/src/gromacs/gpu_utils/gpu_macros.h index 6319feff69..4f6d557537 100644 --- a/src/gromacs/gpu_utils/gpu_macros.h +++ b/src/gromacs/gpu_utils/gpu_macros.h @@ -49,82 +49,87 @@ #define NULL_FUNC_QUALIFIER gmx_unused static #define NULL_FUNC_ARGUMENT(arg) arg gmx_unused -#define NULL_FUNC_TERM {} -#define NULL_FUNC_TERM_WITH_RETURN(arg) { return (arg); } +#define NULL_FUNC_TERM \ + { \ + } +#define NULL_FUNC_TERM_WITH_RETURN(arg) \ + { \ + return (arg); \ + } #ifdef DOXYGEN /* Doxygen build appreciates always having argument names, and doesn't * care about duplicate function definitions. */ -#define GPU_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define GPU_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define GPU_FUNC_TERM REAL_FUNC_TERM -#define GPU_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) -#define CUDA_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define CUDA_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define CUDA_FUNC_TERM REAL_FUNC_TERM -#define CUDA_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) -#define OPENCL_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define OPENCL_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define OPENCL_FUNC_TERM REAL_FUNC_TERM -#define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) +# define GPU_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define GPU_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define GPU_FUNC_TERM REAL_FUNC_TERM +# define GPU_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) +# define CUDA_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define CUDA_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define CUDA_FUNC_TERM REAL_FUNC_TERM +# define CUDA_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) +# define OPENCL_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define OPENCL_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define OPENCL_FUNC_TERM REAL_FUNC_TERM +# define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) #elif GMX_GPU != GMX_GPU_NONE /* GPU support is enabled, so these functions will have real code * defined somewhere */ -#define GPU_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define GPU_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define GPU_FUNC_TERM REAL_FUNC_TERM -#define GPU_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) +# define GPU_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define GPU_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define GPU_FUNC_TERM REAL_FUNC_TERM +# define GPU_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) -# if GMX_GPU == GMX_GPU_OPENCL +# if GMX_GPU == GMX_GPU_OPENCL /* OpenCL support is enabled, so CUDA-specific functions need empty * implementations, while OpenCL-specific functions will have real * code defined somewhere. */ -#define CUDA_FUNC_QUALIFIER NULL_FUNC_QUALIFIER -#define CUDA_FUNC_ARGUMENT NULL_FUNC_ARGUMENT -#define CUDA_FUNC_TERM NULL_FUNC_TERM -#define CUDA_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) -#define OPENCL_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define OPENCL_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define OPENCL_FUNC_TERM REAL_FUNC_TERM -#define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) - -# endif -# if GMX_GPU == GMX_GPU_CUDA +# define CUDA_FUNC_QUALIFIER NULL_FUNC_QUALIFIER +# define CUDA_FUNC_ARGUMENT NULL_FUNC_ARGUMENT +# define CUDA_FUNC_TERM NULL_FUNC_TERM +# define CUDA_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) +# define OPENCL_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define OPENCL_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define OPENCL_FUNC_TERM REAL_FUNC_TERM +# define OPENCL_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) + +# endif +# if GMX_GPU == GMX_GPU_CUDA /* CUDA support is enabled, so OpenCL-specific functions need empty * implementations, while CUDA-specific functions will have real * code defined somewhere. */ -#define CUDA_FUNC_QUALIFIER REAL_FUNC_QUALIFIER -#define CUDA_FUNC_ARGUMENT REAL_FUNC_ARGUMENT -#define CUDA_FUNC_TERM REAL_FUNC_TERM -#define CUDA_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) -#define OPENCL_FUNC_QUALIFIER NULL_FUNC_QUALIFIER -#define OPENCL_FUNC_ARGUMENT NULL_FUNC_ARGUMENT -#define OPENCL_FUNC_TERM NULL_FUNC_TERM -#define OPENCL_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) +# define CUDA_FUNC_QUALIFIER REAL_FUNC_QUALIFIER +# define CUDA_FUNC_ARGUMENT REAL_FUNC_ARGUMENT +# define CUDA_FUNC_TERM REAL_FUNC_TERM +# define CUDA_FUNC_TERM_WITH_RETURN(arg) REAL_FUNC_TERM_WITH_RETURN(arg) +# define OPENCL_FUNC_QUALIFIER NULL_FUNC_QUALIFIER +# define OPENCL_FUNC_ARGUMENT NULL_FUNC_ARGUMENT +# define OPENCL_FUNC_TERM NULL_FUNC_TERM +# define OPENCL_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) -# endif +# endif #elif GMX_GPU == GMX_GPU_NONE /* No GPU support is configured, so none of these functions will have * real definitions. */ -#define GPU_FUNC_QUALIFIER NULL_FUNC_QUALIFIER -#define GPU_FUNC_ARGUMENT NULL_FUNC_ARGUMENT -#define GPU_FUNC_TERM NULL_FUNC_TERM -#define GPU_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) -#define CUDA_FUNC_QUALIFIER NULL_FUNC_QUALIFIER -#define CUDA_FUNC_ARGUMENT NULL_FUNC_ARGUMENT -#define CUDA_FUNC_TERM NULL_FUNC_TERM -#define CUDA_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) -#define OPENCL_FUNC_QUALIFIER NULL_FUNC_QUALIFIER -#define OPENCL_FUNC_ARGUMENT NULL_FUNC_ARGUMENT -#define OPENCL_FUNC_TERM NULL_FUNC_TERM -#define OPENCL_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) +# define GPU_FUNC_QUALIFIER NULL_FUNC_QUALIFIER +# define GPU_FUNC_ARGUMENT NULL_FUNC_ARGUMENT +# define GPU_FUNC_TERM NULL_FUNC_TERM +# define GPU_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) +# define CUDA_FUNC_QUALIFIER NULL_FUNC_QUALIFIER +# define CUDA_FUNC_ARGUMENT NULL_FUNC_ARGUMENT +# define CUDA_FUNC_TERM NULL_FUNC_TERM +# define CUDA_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) +# define OPENCL_FUNC_QUALIFIER NULL_FUNC_QUALIFIER +# define OPENCL_FUNC_ARGUMENT NULL_FUNC_ARGUMENT +# define OPENCL_FUNC_TERM NULL_FUNC_TERM +# define OPENCL_FUNC_TERM_WITH_RETURN(arg) NULL_FUNC_TERM_WITH_RETURN(arg) #endif diff --git a/src/gromacs/gpu_utils/gpu_testutils.cpp b/src/gromacs/gpu_utils/gpu_testutils.cpp index 50be2b38a9..63a8756afc 100644 --- a/src/gromacs/gpu_utils/gpu_testutils.cpp +++ b/src/gromacs/gpu_utils/gpu_testutils.cpp @@ -47,7 +47,7 @@ bool canComputeOnGpu() { bool canComputeOnGpu = false; - gmx_gpu_info_t gpuInfo {}; + gmx_gpu_info_t gpuInfo{}; if (canPerformGpuDetection()) { findGpus(&gpuInfo); diff --git a/src/gromacs/gpu_utils/gpu_utils.cpp b/src/gromacs/gpu_utils/gpu_utils.cpp index d47abb3b17..51622063a7 100644 --- a/src/gromacs/gpu_utils/gpu_utils.cpp +++ b/src/gromacs/gpu_utils/gpu_utils.cpp @@ -51,7 +51,7 @@ #include "gromacs/utility/stringutil.h" #ifdef _MSC_VER -#pragma warning(disable: 6237) +# pragma warning(disable : 6237) #endif //! Constant used to help minimize preprocessed code @@ -59,8 +59,7 @@ static constexpr bool c_binarySupportsGpus = (GMX_GPU != GMX_GPU_NONE); bool canPerformGpuDetection() { - if (c_binarySupportsGpus && - getenv("GMX_DISABLE_GPU_DETECTION") == nullptr) + if (c_binarySupportsGpus && getenv("GMX_DISABLE_GPU_DETECTION") == nullptr) { return isGpuDetectionFunctional(nullptr); } @@ -71,18 +70,18 @@ bool canPerformGpuDetection() } #if GMX_GPU == GMX_GPU_NONE -int gpu_info_get_stat(const gmx_gpu_info_t & /*unused*/, int /*unused*/) +int gpu_info_get_stat(const gmx_gpu_info_t& /*unused*/, int /*unused*/) { return egpuNonexistent; } #endif -void free_gpu_info(const gmx_gpu_info_t *gpu_info) +void free_gpu_info(const gmx_gpu_info_t* gpu_info) { - sfree(static_cast(gpu_info->gpu_dev)); //circumvent is_pod check in sfree + sfree(static_cast(gpu_info->gpu_dev)); // circumvent is_pod check in sfree } -std::vector getCompatibleGpus(const gmx_gpu_info_t &gpu_info) +std::vector getCompatibleGpus(const gmx_gpu_info_t& gpu_info) { // Possible minor over-allocation here, but not important for anything std::vector compatibleGpus; @@ -98,31 +97,27 @@ std::vector getCompatibleGpus(const gmx_gpu_info_t &gpu_info) return compatibleGpus; } -const char *getGpuCompatibilityDescription(const gmx_gpu_info_t &gpu_info, - int index) +const char* getGpuCompatibilityDescription(const gmx_gpu_info_t& gpu_info, int index) { - return (index >= gpu_info.n_dev ? - gpu_detect_res_str[egpuNonexistent] : - gpu_detect_res_str[gpu_info_get_stat(gpu_info, index)]); + return (index >= gpu_info.n_dev ? gpu_detect_res_str[egpuNonexistent] + : gpu_detect_res_str[gpu_info_get_stat(gpu_info, index)]); } /*! \brief Help build a descriptive message in \c error if there are * \c errorReasons why nonbondeds on a GPU are not supported. * * \returns Whether the lack of errorReasons indicate there is support. */ -static bool -addMessageIfNotSupported(gmx::ArrayRef errorReasons, - std::string *error) +static bool addMessageIfNotSupported(gmx::ArrayRef errorReasons, std::string* error) { bool isSupported = errorReasons.empty(); if (!isSupported && error) { - *error = "Nonbonded interactions cannot run on GPUs: "; + *error = "Nonbonded interactions cannot run on GPUs: "; *error += joinStrings(errorReasons, "; ") + "."; } return isSupported; } -bool buildSupportsNonbondedOnGpu(std::string *error) +bool buildSupportsNonbondedOnGpu(std::string* error) { std::vector errorReasons; if (GMX_DOUBLE) diff --git a/src/gromacs/gpu_utils/gpu_utils.cu b/src/gromacs/gpu_utils/gpu_utils.cu index dec064397f..b7e5e0f77e 100644 --- a/src/gromacs/gpu_utils/gpu_utils.cu +++ b/src/gromacs/gpu_utils/gpu_utils.cu @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,17 +68,14 @@ * * In reality it is 16 with CUDA <=v5.0, but let's stay on the safe side. */ -static int cuda_max_device_count = 32; +static int cuda_max_device_count = 32; -static bool cudaProfilerRun = ((getenv("NVPROF_ID") != nullptr)); +static bool cudaProfilerRun = ((getenv("NVPROF_ID") != nullptr)); /** Dummy kernel used for sanity checking. */ -static __global__ void k_dummy_test(void) -{ -} +static __global__ void k_dummy_test(void) {} -static void checkCompiledTargetCompatibility(int deviceId, - const cudaDeviceProp &deviceProp) +static void checkCompiledTargetCompatibility(int deviceId, const cudaDeviceProp& deviceProp) { cudaFuncAttributes attributes; cudaError_t stat = cudaFuncGetAttributes(&attributes, k_dummy_test); @@ -101,17 +99,15 @@ static void checkCompiledTargetCompatibility(int deviceId, CU_RET_ERR(stat, "cudaFuncGetAttributes failed"); } -bool isHostMemoryPinned(const void *h_ptr) +bool isHostMemoryPinned(const void* h_ptr) { cudaPointerAttributes memoryAttributes; cudaError_t stat = cudaPointerGetAttributes(&memoryAttributes, h_ptr); - bool result = false; + bool result = false; switch (stat) { - case cudaSuccess: - result = true; - break; + case cudaSuccess: result = true; break; case cudaErrorInvalidValue: // If the buffer was not pinned, then it will not be recognized by CUDA at all @@ -120,8 +116,7 @@ bool isHostMemoryPinned(const void *h_ptr) cudaGetLastError(); break; - default: - CU_RET_ERR(stat, "Unexpected CUDA error"); + default: CU_RET_ERR(stat, "Unexpected CUDA error"); } return result; } @@ -138,7 +133,7 @@ bool isHostMemoryPinned(const void *h_ptr) * * TODO: introduce errors codes and handle errors more smoothly. */ -static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) +static int do_sanity_checks(int dev_id, const cudaDeviceProp& dev_prop) { cudaError_t cu_err; int dev_count, id; @@ -146,8 +141,7 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) cu_err = cudaGetDeviceCount(&dev_count); if (cu_err != cudaSuccess) { - fprintf(stderr, "Error %d while querying device count: %s\n", cu_err, - cudaGetErrorString(cu_err)); + fprintf(stderr, "Error %d while querying device count: %s\n", cu_err, cudaGetErrorString(cu_err)); return -1; } @@ -168,8 +162,7 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) cu_err = cudaGetDevice(&id); if (cu_err != cudaSuccess) { - fprintf(stderr, "Error %d while querying device id: %s\n", cu_err, - cudaGetErrorString(cu_err)); + fprintf(stderr, "Error %d while querying device id: %s\n", cu_err, cudaGetErrorString(cu_err)); return -1; } } @@ -178,7 +171,8 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) id = dev_id; if (id > dev_count - 1) /* pfff there's no such device */ { - fprintf(stderr, "The requested device with id %d does not seem to exist (device count=%d)\n", + fprintf(stderr, + "The requested device with id %d does not seem to exist (device count=%d)\n", dev_id, dev_count); return -1; } @@ -200,8 +194,8 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) cu_err = cudaSetDevice(id); if (cu_err != cudaSuccess) { - fprintf(stderr, "Error %d while switching to device #%d: %s\n", - cu_err, id, cudaGetErrorString(cu_err)); + fprintf(stderr, "Error %d while switching to device #%d: %s\n", cu_err, id, + cudaGetErrorString(cu_err)); return -1; } } @@ -210,8 +204,8 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) checkCompiledTargetCompatibility(dev_id, dev_prop); KernelLaunchConfig config; - config.blockSize[0] = 512; - const auto dummyArguments = prepareGpuKernelArguments(k_dummy_test, config); + config.blockSize[0] = 512; + const auto dummyArguments = prepareGpuKernelArguments(k_dummy_test, config); launchGpuKernel(k_dummy_test, config, nullptr, "Dummy kernel", dummyArguments); if (cudaDeviceSynchronize() != cudaSuccess) { @@ -228,7 +222,7 @@ static int do_sanity_checks(int dev_id, const cudaDeviceProp &dev_prop) return 0; } -void init_gpu(const gmx_device_info_t *deviceInfo) +void init_gpu(const gmx_device_info_t* deviceInfo) { cudaError_t stat; @@ -247,7 +241,7 @@ void init_gpu(const gmx_device_info_t *deviceInfo) } } -void free_gpu(const gmx_device_info_t *deviceInfo) +void free_gpu(const gmx_device_info_t* deviceInfo) { // One should only attempt to clear the device context when // it has been used, but currently the only way to know that a GPU @@ -257,7 +251,7 @@ void free_gpu(const gmx_device_info_t *deviceInfo) return; } - cudaError_t stat; + cudaError_t stat; if (debug) { @@ -274,8 +268,7 @@ void free_gpu(const gmx_device_info_t *deviceInfo) } } -gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info, - int deviceId) +gmx_device_info_t* getDeviceInfo(const gmx_gpu_info_t& gpu_info, int deviceId) { if (deviceId < 0 || deviceId >= gpu_info.n_dev) { @@ -291,7 +284,7 @@ gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info, * \returns true if the GPU properties passed indicate a compatible * GPU, otherwise false. */ -static bool is_gmx_supported_gpu(const cudaDeviceProp &dev_prop) +static bool is_gmx_supported_gpu(const cudaDeviceProp& dev_prop) { return (dev_prop.major >= 3); } @@ -310,8 +303,7 @@ static bool is_gmx_supported_gpu(const cudaDeviceProp &dev_prop) * \param[in] deviceProp the CUDA device properties of the device checked. * \returns the status of the requested device */ -static int is_gmx_supported_gpu_id(int deviceId, - const cudaDeviceProp &deviceProp) +static int is_gmx_supported_gpu_id(int deviceId, const cudaDeviceProp& deviceProp) { if (!is_gmx_supported_gpu(deviceProp)) { @@ -331,15 +323,18 @@ static int is_gmx_supported_gpu_id(int deviceId, return egpuCompatible; } -bool isGpuDetectionFunctional(std::string *errorMessage) +bool isGpuDetectionFunctional(std::string* errorMessage) { - cudaError_t stat; - int driverVersion = -1; - stat = cudaDriverGetVersion(&driverVersion); - GMX_ASSERT(stat != cudaErrorInvalidValue, "An impossible null pointer was passed to cudaDriverGetVersion"); - GMX_RELEASE_ASSERT(stat == cudaSuccess, - gmx::formatString("An unexpected value was returned from cudaDriverGetVersion %s: %s", - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + cudaError_t stat; + int driverVersion = -1; + stat = cudaDriverGetVersion(&driverVersion); + GMX_ASSERT(stat != cudaErrorInvalidValue, + "An impossible null pointer was passed to cudaDriverGetVersion"); + GMX_RELEASE_ASSERT( + stat == cudaSuccess, + gmx::formatString("An unexpected value was returned from cudaDriverGetVersion %s: %s", + cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); bool foundDriver = (driverVersion > 0); if (!foundDriver) { @@ -383,7 +378,7 @@ bool isGpuDetectionFunctional(std::string *errorMessage) return true; } -void findGpus(gmx_gpu_info_t *gpu_info) +void findGpus(gmx_gpu_info_t* gpu_info) { assert(gpu_info); @@ -393,14 +388,15 @@ void findGpus(gmx_gpu_info_t *gpu_info) cudaError_t stat = cudaGetDeviceCount(&ndev); if (stat != cudaSuccess) { - GMX_THROW(gmx::InternalError("Invalid call of findGpus() when CUDA API returned an error, perhaps " - "canDetectGpus() was not called appropriately beforehand.")); + GMX_THROW(gmx::InternalError( + "Invalid call of findGpus() when CUDA API returned an error, perhaps " + "canDetectGpus() was not called appropriately beforehand.")); } // We expect to start device support/sanity checks with a clean runtime error state gmx::ensureNoPendingCudaError(""); - gmx_device_info_t *devs; + gmx_device_info_t* devs; snew(devs, ndev); for (int i = 0; i < ndev; i++) { @@ -449,14 +445,16 @@ void findGpus(gmx_gpu_info_t *gpu_info) stat = cudaPeekAtLastError(); GMX_RELEASE_ASSERT(stat == cudaSuccess, - gmx::formatString("We promise to return with clean CUDA state, but non-success state encountered: %s: %s", - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + gmx::formatString("We promise to return with clean CUDA state, but " + "non-success state encountered: %s: %s", + cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); gpu_info->n_dev = ndev; gpu_info->gpu_dev = devs; } -void get_gpu_device_info_string(char *s, const gmx_gpu_info_t &gpu_info, int index) +void get_gpu_device_info_string(char* s, const gmx_gpu_info_t& gpu_info, int index) { assert(s); @@ -465,24 +463,19 @@ void get_gpu_device_info_string(char *s, const gmx_gpu_info_t &gpu_info, int ind return; } - gmx_device_info_t *dinfo = &gpu_info.gpu_dev[index]; + gmx_device_info_t* dinfo = &gpu_info.gpu_dev[index]; - bool bGpuExists = (dinfo->stat != egpuNonexistent && - dinfo->stat != egpuInsane); + bool bGpuExists = (dinfo->stat != egpuNonexistent && dinfo->stat != egpuInsane); if (!bGpuExists) { - sprintf(s, "#%d: %s, stat: %s", - dinfo->id, "N/A", - gpu_detect_res_str[dinfo->stat]); + sprintf(s, "#%d: %s, stat: %s", dinfo->id, "N/A", gpu_detect_res_str[dinfo->stat]); } else { - sprintf(s, "#%d: NVIDIA %s, compute cap.: %d.%d, ECC: %3s, stat: %s", - dinfo->id, dinfo->prop.name, - dinfo->prop.major, dinfo->prop.minor, - dinfo->prop.ECCEnabled ? "yes" : " no", - gpu_detect_res_str[dinfo->stat]); + sprintf(s, "#%d: NVIDIA %s, compute cap.: %d.%d, ECC: %3s, stat: %s", dinfo->id, + dinfo->prop.name, dinfo->prop.major, dinfo->prop.minor, + dinfo->prop.ECCEnabled ? "yes" : " no", gpu_detect_res_str[dinfo->stat]); } } @@ -542,7 +535,7 @@ void resetGpuProfiler(void) } } -int gpu_info_get_stat(const gmx_gpu_info_t &info, int index) +int gpu_info_get_stat(const gmx_gpu_info_t& info, int index) { return info.gpu_dev[index].stat; } @@ -554,21 +547,30 @@ int gpu_info_get_stat(const gmx_gpu_info_t &info, int index) * \param[in] mdlog Logger object * \param[in] cudaCallName name of CUDA peer access call */ -static void peerAccessCheckStat(const cudaError_t stat, const int gpuA, const int gpuB, const gmx::MDLogger &mdlog, const char *cudaCallName) +static void peerAccessCheckStat(const cudaError_t stat, + const int gpuA, + const int gpuB, + const gmx::MDLogger& mdlog, + const char* cudaCallName) { if ((stat == cudaErrorInvalidDevice) || (stat == cudaErrorInvalidValue)) { - std::string errorString = gmx::formatString("%s from GPU %d to GPU %d failed", cudaCallName, gpuA, gpuB); + std::string errorString = + gmx::formatString("%s from GPU %d to GPU %d failed", cudaCallName, gpuA, gpuB); CU_RET_ERR(stat, errorString.c_str()); } if (stat != cudaSuccess) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("GPU peer access not enabled between GPUs %d and %d due to unexpected return value from %s: %s", - gpuA, gpuB, cudaCallName, cudaGetErrorString(stat)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "GPU peer access not enabled between GPUs %d and %d due to unexpected " + "return value from %s: %s", + gpuA, gpuB, cudaCallName, cudaGetErrorString(stat)); } } -void setupGpuDevicePeerAccess(const std::vector &gpuIdsToUse, const gmx::MDLogger &mdlog) +void setupGpuDevicePeerAccess(const std::vector& gpuIdsToUse, const gmx::MDLogger& mdlog) { cudaError_t stat; @@ -577,16 +579,22 @@ void setupGpuDevicePeerAccess(const std::vector &gpuIdsToUse, const gmx::MD stat = cudaGetDevice(¤tGpu); CU_RET_ERR(stat, "cudaGetDevice in setupGpuDevicePeerAccess failed"); - std::string message = gmx::formatString("Note: Peer access enabled between the following GPU pairs in the node:\n "); - bool peerAccessEnabled = false; + std::string message = gmx::formatString( + "Note: Peer access enabled between the following GPU pairs in the node:\n "); + bool peerAccessEnabled = false; for (unsigned int i = 0; i < gpuIdsToUse.size(); i++) { int gpuA = gpuIdsToUse[i]; - stat = cudaSetDevice(gpuA); + stat = cudaSetDevice(gpuA); if (stat != cudaSuccess) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("GPU peer access not enabled due to unexpected return value from cudaSetDevice(%d): %s", gpuA, cudaGetErrorString(stat)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "GPU peer access not enabled due to unexpected return value from " + "cudaSetDevice(%d): %s", + gpuA, cudaGetErrorString(stat)); return; } for (unsigned int j = 0; j < gpuIdsToUse.size(); j++) @@ -595,7 +603,7 @@ void setupGpuDevicePeerAccess(const std::vector &gpuIdsToUse, const gmx::MD { int gpuB = gpuIdsToUse[j]; int canAccessPeer = 0; - stat = cudaDeviceCanAccessPeer(&canAccessPeer, gpuA, gpuB); + stat = cudaDeviceCanAccessPeer(&canAccessPeer, gpuA, gpuB); peerAccessCheckStat(stat, gpuA, gpuB, mdlog, "cudaDeviceCanAccessPeer"); if (canAccessPeer) @@ -610,7 +618,7 @@ void setupGpuDevicePeerAccess(const std::vector &gpuIdsToUse, const gmx::MD } } - //re-set GPU to that originally set + // re-set GPU to that originally set stat = cudaSetDevice(currentGpu); if (stat != cudaSuccess) { diff --git a/src/gromacs/gpu_utils/gpu_utils.h b/src/gromacs/gpu_utils/gpu_utils.h index edf3f17486..5ed09f4f9b 100644 --- a/src/gromacs/gpu_utils/gpu_utils.h +++ b/src/gromacs/gpu_utils/gpu_utils.h @@ -99,7 +99,8 @@ bool canPerformGpuDetection(); * * Does not throw. */ GPU_FUNC_QUALIFIER -bool isGpuDetectionFunctional(std::string *GPU_FUNC_ARGUMENT(errorMessage)) GPU_FUNC_TERM_WITH_RETURN(false); +bool isGpuDetectionFunctional(std::string* GPU_FUNC_ARGUMENT(errorMessage)) + GPU_FUNC_TERM_WITH_RETURN(false); /*! \brief Find all GPUs in the system. * @@ -120,7 +121,7 @@ bool isGpuDetectionFunctional(std::string *GPU_FUNC_ARGUMENT(errorMessage)) GPU_ * the call to canDetectGpus() should always prevent this occuring) */ GPU_FUNC_QUALIFIER -void findGpus(gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU_FUNC_TERM; +void findGpus(gmx_gpu_info_t* GPU_FUNC_ARGUMENT(gpu_info)) GPU_FUNC_TERM; /*! \brief Return a container of the detected GPUs that are compatible. * @@ -129,7 +130,7 @@ void findGpus(gmx_gpu_info_t *GPU_FUNC_ARGUMENT(gpu_info)) GPU_FUNC_TERM; * * \param[in] gpu_info Information detected about GPUs, including compatibility. * \return vector of IDs of GPUs already recorded as compatible */ -std::vector getCompatibleGpus(const gmx_gpu_info_t &gpu_info); +std::vector getCompatibleGpus(const gmx_gpu_info_t& gpu_info); /*! \brief Return a string describing how compatible the GPU with given \c index is. * @@ -137,14 +138,13 @@ std::vector getCompatibleGpus(const gmx_gpu_info_t &gpu_info); * \param[in] index index of GPU to ask about * \returns A null-terminated C string describing the compatibility status, useful for error messages. */ -const char *getGpuCompatibilityDescription(const gmx_gpu_info_t &gpu_info, - int index); +const char* getGpuCompatibilityDescription(const gmx_gpu_info_t& gpu_info, int index); /*! \brief Frees the gpu_dev and dev_use array fields of \p gpu_info. * * \param[in] gpu_info pointer to structure holding GPU information */ -void free_gpu_info(const gmx_gpu_info_t *gpu_info); +void free_gpu_info(const gmx_gpu_info_t* gpu_info); /*! \brief Initializes the GPU described by \c deviceInfo. * @@ -157,7 +157,7 @@ void free_gpu_info(const gmx_gpu_info_t *gpu_info); * initialization. */ GPU_FUNC_QUALIFIER -void init_gpu(const gmx_device_info_t *GPU_FUNC_ARGUMENT(deviceInfo)) GPU_FUNC_TERM; +void init_gpu(const gmx_device_info_t* GPU_FUNC_ARGUMENT(deviceInfo)) GPU_FUNC_TERM; /*! \brief Frees up the CUDA GPU used by the active context at the time of calling. * @@ -175,7 +175,7 @@ void init_gpu(const gmx_device_info_t *GPU_FUNC_ARGUMENT(deviceInfo)) GPU_FUNC_T * \returns true if no error occurs during the freeing. */ CUDA_FUNC_QUALIFIER -void free_gpu(const gmx_device_info_t *CUDA_FUNC_ARGUMENT(deviceInfo)) CUDA_FUNC_TERM; +void free_gpu(const gmx_device_info_t* CUDA_FUNC_ARGUMENT(deviceInfo)) CUDA_FUNC_TERM; /*! \brief Return a pointer to the device info for \c deviceId * @@ -185,7 +185,7 @@ void free_gpu(const gmx_device_info_t *CUDA_FUNC_ARGUMENT(deviceInfo)) CUDA_FUNC * \returns Pointer to the device info for \c deviceId. */ GPU_FUNC_QUALIFIER -gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &GPU_FUNC_ARGUMENT(gpu_info), +gmx_device_info_t* getDeviceInfo(const gmx_gpu_info_t& GPU_FUNC_ARGUMENT(gpu_info), int GPU_FUNC_ARGUMENT(deviceId)) GPU_FUNC_TERM_WITH_RETURN(nullptr); /*! \brief Returns the device ID of the CUDA GPU currently in use. @@ -208,9 +208,9 @@ int get_current_cuda_gpu_device_id() CUDA_FUNC_TERM_WITH_RETURN(-1); * \param[in] index an index *directly* into the array of available GPUs */ GPU_FUNC_QUALIFIER -void get_gpu_device_info_string(char *GPU_FUNC_ARGUMENT(s), - const gmx_gpu_info_t &GPU_FUNC_ARGUMENT(gpu_info), - int GPU_FUNC_ARGUMENT(index)) GPU_FUNC_TERM; +void get_gpu_device_info_string(char* GPU_FUNC_ARGUMENT(s), + const gmx_gpu_info_t& GPU_FUNC_ARGUMENT(gpu_info), + int GPU_FUNC_ARGUMENT(index)) GPU_FUNC_TERM; /*! \brief Returns the size of the gpu_dev_info struct. @@ -223,14 +223,14 @@ GPU_FUNC_QUALIFIER size_t sizeof_gpu_dev_info() GPU_FUNC_TERM_WITH_RETURN(0); //! Get status of device with specified index -int gpu_info_get_stat(const gmx_gpu_info_t &info, int index); +int gpu_info_get_stat(const gmx_gpu_info_t& info, int index); /*! \brief Check if GROMACS has been built with GPU support. * * \param[in] error Pointer to error string or nullptr. * \todo Move this to NB module once it exists. */ -bool buildSupportsNonbondedOnGpu(std::string *error); +bool buildSupportsNonbondedOnGpu(std::string* error); /*! \brief Starts the GPU profiler if mdrun is being profiled. * @@ -271,14 +271,14 @@ void stopGpuProfiler() CUDA_FUNC_TERM; //! Tells whether the host buffer was pinned for non-blocking transfers. Only implemented for CUDA. CUDA_FUNC_QUALIFIER -bool isHostMemoryPinned(const void *CUDA_FUNC_ARGUMENT(h_ptr)) CUDA_FUNC_TERM_WITH_RETURN(false); +bool isHostMemoryPinned(const void* CUDA_FUNC_ARGUMENT(h_ptr)) CUDA_FUNC_TERM_WITH_RETURN(false); /*! \brief Enable peer access between GPUs where supported * \param[in] gpuIdsToUse List of GPU IDs in use * \param[in] mdlog Logger object */ CUDA_FUNC_QUALIFIER -void setupGpuDevicePeerAccess(const std::vector &CUDA_FUNC_ARGUMENT(gpuIdsToUse), - const gmx::MDLogger &CUDA_FUNC_ARGUMENT(mdlog)) CUDA_FUNC_TERM; +void setupGpuDevicePeerAccess(const std::vector& CUDA_FUNC_ARGUMENT(gpuIdsToUse), + const gmx::MDLogger& CUDA_FUNC_ARGUMENT(mdlog)) CUDA_FUNC_TERM; #endif diff --git a/src/gromacs/gpu_utils/gpu_utils_ocl.cpp b/src/gromacs/gpu_utils/gpu_utils_ocl.cpp index 2ddde385f5..29fa7b0f72 100644 --- a/src/gromacs/gpu_utils/gpu_utils_ocl.cpp +++ b/src/gromacs/gpu_utils/gpu_utils_ocl.cpp @@ -79,8 +79,7 @@ * \return true if version is 14.4 or later (= OS X version 10.10.4), * or OS is not Darwin. */ -static bool -runningOnCompatibleOSForAmd() +static bool runningOnCompatibleOSForAmd() { #ifdef __APPLE__ int mib[2]; @@ -90,10 +89,10 @@ runningOnCompatibleOSForAmd() mib[0] = CTL_KERN; mib[1] = KERN_OSRELEASE; - sysctl(mib, sizeof(mib)/sizeof(mib[0]), kernelVersion, &len, NULL, 0); + sysctl(mib, sizeof(mib) / sizeof(mib[0]), kernelVersion, &len, NULL, 0); int major = strtod(kernelVersion, NULL); - int minor = strtod(strchr(kernelVersion, '.')+1, NULL); + int minor = strtod(strchr(kernelVersion, '.') + 1, NULL); // Kernel 14.4 corresponds to OS X 10.10.4 return (major > 14 || (major == 14 && minor >= 4)); @@ -114,20 +113,16 @@ namespace gmx * \param[in] status OpenCL API status code * \returns A string describing the OpenCL error. */ -static std::string -makeOpenClInternalErrorString(const char *message, cl_int status) +static std::string makeOpenClInternalErrorString(const char* message, cl_int status) { if (message != nullptr) { - return formatString("%s did %ssucceed %d: %s", - message, - ((status != CL_SUCCESS) ? "not " : ""), + return formatString("%s did %ssucceed %d: %s", message, ((status != CL_SUCCESS) ? "not " : ""), status, ocl_get_error_string(status).c_str()); } else { - return formatString("%sOpenCL error encountered %d: %s", - ((status != CL_SUCCESS) ? "" : "No "), + return formatString("%sOpenCL error encountered %d: %s", ((status != CL_SUCCESS) ? "" : "No "), status, ocl_get_error_string(status).c_str()); } } @@ -144,13 +139,10 @@ makeOpenClInternalErrorString(const char *message, cl_int status) * \throws std::bad_alloc When out of memory. * \returns Whether the device passed sanity checks */ -static bool isDeviceSane(const gmx_device_info_t *devInfo, - std::string *errorMessage) +static bool isDeviceSane(const gmx_device_info_t* devInfo, std::string* errorMessage) { cl_context_properties properties[] = { - CL_CONTEXT_PLATFORM, - reinterpret_cast(devInfo->ocl_gpu_id.ocl_platform_id), - 0 + CL_CONTEXT_PLATFORM, reinterpret_cast(devInfo->ocl_gpu_id.ocl_platform_id), 0 }; // uncrustify spacing @@ -170,7 +162,7 @@ static bool isDeviceSane(const gmx_device_info_t *devInfo, } // Some compilers such as Apple's require kernel functions to have at least one argument - const char *lines[] = { "__kernel void dummyKernel(__global void* input){}" }; + const char* lines[] = { "__kernel void dummyKernel(__global void* input){}" }; ClProgram program(clCreateProgramWithSource(context, 1, lines, nullptr, &status)); if (status != CL_SUCCESS) { @@ -194,9 +186,9 @@ static bool isDeviceSane(const gmx_device_info_t *devInfo, clSetKernelArg(kernel, 0, sizeof(void*), nullptr); const size_t localWorkSize = 1, globalWorkSize = 1; - if ((status = - clEnqueueNDRangeKernel(commandQueue, kernel, 1, nullptr, - &globalWorkSize, &localWorkSize, 0, nullptr, nullptr)) != CL_SUCCESS) + if ((status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, nullptr, &globalWorkSize, + &localWorkSize, 0, nullptr, nullptr)) + != CL_SUCCESS) { errorMessage->assign(makeOpenClInternalErrorString("clEnqueueNDRangeKernel", status)); return false; @@ -213,7 +205,7 @@ static bool isDeviceSane(const gmx_device_info_t *devInfo, * \param[in] devInfo The device info pointer. * \returns The result of the compatibility checks. */ -static int isDeviceSupported(const gmx_device_info_t *devInfo) +static int isDeviceSupported(const gmx_device_info_t* devInfo) { if (getenv("GMX_OCL_DISABLE_COMPATIBILITY_CHECK") != nullptr) { @@ -229,10 +221,12 @@ static int isDeviceSupported(const gmx_device_info_t *devInfo) // the device which has the following format: // OpenCL unsigned int deviceVersionMinor, deviceVersionMajor; - const int valuesScanned = std::sscanf(devInfo->device_version, "OpenCL %u.%u", &deviceVersionMajor, &deviceVersionMinor); - const bool versionLargeEnough = ((valuesScanned == 2) && - ((deviceVersionMajor > minVersionMajor) || - (deviceVersionMajor == minVersionMajor && deviceVersionMinor >= minVersionMinor))); + const int valuesScanned = std::sscanf(devInfo->device_version, "OpenCL %u.%u", + &deviceVersionMajor, &deviceVersionMinor); + const bool versionLargeEnough = + ((valuesScanned == 2) + && ((deviceVersionMajor > minVersionMajor) + || (deviceVersionMajor == minVersionMajor && deviceVersionMinor >= minVersionMinor))); if (!versionLargeEnough) { return egpuIncompatible; @@ -241,19 +235,16 @@ static int isDeviceSupported(const gmx_device_info_t *devInfo) /* Only AMD, Intel, and NVIDIA GPUs are supported for now */ switch (devInfo->vendor_e) { - case OCL_VENDOR_NVIDIA: - return egpuCompatible; + case OCL_VENDOR_NVIDIA: return egpuCompatible; case OCL_VENDOR_AMD: return runningOnCompatibleOSForAmd() ? egpuCompatible : egpuIncompatible; case OCL_VENDOR_INTEL: return GMX_OPENCL_NB_CLUSTER_SIZE == 4 ? egpuCompatible : egpuIncompatibleClusterSize; - default: - return egpuIncompatible; + default: return egpuIncompatible; } } - /*! \brief Check whether the \c ocl_gpu_device is suitable for use by mdrun * * Runs sanity checks: checking that the runtime can compile a dummy kernel @@ -266,8 +257,7 @@ static int isDeviceSupported(const gmx_device_info_t *devInfo) * \returns An e_gpu_detect_res_t to indicate how the GPU coped with * the sanity and compatibility check. */ -static int checkGpu(size_t deviceId, - const gmx_device_info_t *deviceInfo) +static int checkGpu(size_t deviceId, const gmx_device_info_t* deviceInfo) { int supportStatus = isDeviceSupported(deviceInfo); @@ -293,7 +283,7 @@ static int checkGpu(size_t deviceId, * \param[in] vendor_name String with OpenCL vendor name. * \returns ocl_vendor_id_t value for the input vendor_name */ -static ocl_vendor_id_t get_vendor_id(char *vendor_name) +static ocl_vendor_id_t get_vendor_id(char* vendor_name) { if (vendor_name) { @@ -301,14 +291,11 @@ static ocl_vendor_id_t get_vendor_id(char *vendor_name) { return OCL_VENDOR_NVIDIA; } - else - if (strstr(vendor_name, "AMD") || - strstr(vendor_name, "Advanced Micro Devices")) + else if (strstr(vendor_name, "AMD") || strstr(vendor_name, "Advanced Micro Devices")) { return OCL_VENDOR_AMD; } - else - if (strstr(vendor_name, "Intel")) + else if (strstr(vendor_name, "Intel")) { return OCL_VENDOR_INTEL; } @@ -316,10 +303,10 @@ static ocl_vendor_id_t get_vendor_id(char *vendor_name) return OCL_VENDOR_UNKNOWN; } -bool isGpuDetectionFunctional(std::string *errorMessage) +bool isGpuDetectionFunctional(std::string* errorMessage) { cl_uint numPlatforms; - cl_int status = clGetPlatformIDs(0, nullptr, &numPlatforms); + cl_int status = clGetPlatformIDs(0, nullptr, &numPlatforms); GMX_ASSERT(status != CL_INVALID_VALUE, "Incorrect call of clGetPlatformIDs detected"); #ifdef cl_khr_icd if (status == CL_PLATFORM_NOT_FOUND_KHR) @@ -332,9 +319,11 @@ bool isGpuDetectionFunctional(std::string *errorMessage) return false; } #endif - GMX_RELEASE_ASSERT(status == CL_SUCCESS, - gmx::formatString("An unexpected value was returned from clGetPlatformIDs %d: %s", - status, ocl_get_error_string(status).c_str()).c_str()); + GMX_RELEASE_ASSERT( + status == CL_SUCCESS, + gmx::formatString("An unexpected value was returned from clGetPlatformIDs %d: %s", + status, ocl_get_error_string(status).c_str()) + .c_str()); bool foundPlatform = (numPlatforms > 0); if (!foundPlatform && errorMessage != nullptr) { @@ -343,10 +332,10 @@ bool isGpuDetectionFunctional(std::string *errorMessage) return foundPlatform; } -void findGpus(gmx_gpu_info_t *gpu_info) +void findGpus(gmx_gpu_info_t* gpu_info) { cl_uint ocl_platform_count; - cl_platform_id *ocl_platform_ids; + cl_platform_id* ocl_platform_ids; cl_device_type req_dev_type = CL_DEVICE_TYPE_GPU; ocl_platform_ids = nullptr; @@ -361,8 +350,9 @@ void findGpus(gmx_gpu_info_t *gpu_info) cl_int status = clGetPlatformIDs(0, nullptr, &ocl_platform_count); if (CL_SUCCESS != status) { - GMX_THROW(gmx::InternalError(gmx::formatString("An unexpected value %d was returned from clGetPlatformIDs: ", - status) + ocl_get_error_string(status))); + GMX_THROW(gmx::InternalError( + gmx::formatString("An unexpected value %d was returned from clGetPlatformIDs: ", status) + + ocl_get_error_string(status))); } if (1 > ocl_platform_count) @@ -376,8 +366,9 @@ void findGpus(gmx_gpu_info_t *gpu_info) status = clGetPlatformIDs(ocl_platform_count, ocl_platform_ids, nullptr); if (CL_SUCCESS != status) { - GMX_THROW(gmx::InternalError(gmx::formatString("An unexpected value %d was returned from clGetPlatformIDs: ", - status) + ocl_get_error_string(status))); + GMX_THROW(gmx::InternalError( + gmx::formatString("An unexpected value %d was returned from clGetPlatformIDs: ", status) + + ocl_get_error_string(status))); } for (unsigned int i = 0; i < ocl_platform_count; i++) @@ -405,7 +396,7 @@ void findGpus(gmx_gpu_info_t *gpu_info) { int device_index; - cl_device_id *ocl_device_ids; + cl_device_id* ocl_device_ids; snew(ocl_device_ids, gpu_info->n_dev); device_index = 0; @@ -415,7 +406,9 @@ void findGpus(gmx_gpu_info_t *gpu_info) cl_uint ocl_device_count; /* If requesting req_dev_type devices fails, just go to the next platform */ - if (CL_SUCCESS != clGetDeviceIDs(ocl_platform_ids[i], req_dev_type, gpu_info->n_dev, ocl_device_ids, &ocl_device_count)) + if (CL_SUCCESS + != clGetDeviceIDs(ocl_platform_ids[i], req_dev_type, gpu_info->n_dev, + ocl_device_ids, &ocl_device_count)) { continue; } @@ -431,27 +424,41 @@ void findGpus(gmx_gpu_info_t *gpu_info) gpu_info->gpu_dev[device_index].ocl_gpu_id.ocl_device_id = ocl_device_ids[j]; gpu_info->gpu_dev[device_index].device_name[0] = 0; - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_NAME, sizeof(gpu_info->gpu_dev[device_index].device_name), gpu_info->gpu_dev[device_index].device_name, nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_NAME, + sizeof(gpu_info->gpu_dev[device_index].device_name), + gpu_info->gpu_dev[device_index].device_name, nullptr); gpu_info->gpu_dev[device_index].device_version[0] = 0; - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VERSION, sizeof(gpu_info->gpu_dev[device_index].device_version), gpu_info->gpu_dev[device_index].device_version, nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VERSION, + sizeof(gpu_info->gpu_dev[device_index].device_version), + gpu_info->gpu_dev[device_index].device_version, nullptr); gpu_info->gpu_dev[device_index].device_vendor[0] = 0; - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VENDOR, sizeof(gpu_info->gpu_dev[device_index].device_vendor), gpu_info->gpu_dev[device_index].device_vendor, nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_VENDOR, + sizeof(gpu_info->gpu_dev[device_index].device_vendor), + gpu_info->gpu_dev[device_index].device_vendor, nullptr); gpu_info->gpu_dev[device_index].compute_units = 0; - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(gpu_info->gpu_dev[device_index].compute_units), &(gpu_info->gpu_dev[device_index].compute_units), nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_COMPUTE_UNITS, + sizeof(gpu_info->gpu_dev[device_index].compute_units), + &(gpu_info->gpu_dev[device_index].compute_units), nullptr); gpu_info->gpu_dev[device_index].adress_bits = 0; - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_ADDRESS_BITS, sizeof(gpu_info->gpu_dev[device_index].adress_bits), &(gpu_info->gpu_dev[device_index].adress_bits), nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_ADDRESS_BITS, + sizeof(gpu_info->gpu_dev[device_index].adress_bits), + &(gpu_info->gpu_dev[device_index].adress_bits), nullptr); - gpu_info->gpu_dev[device_index].vendor_e = get_vendor_id(gpu_info->gpu_dev[device_index].device_vendor); + gpu_info->gpu_dev[device_index].vendor_e = + get_vendor_id(gpu_info->gpu_dev[device_index].device_vendor); - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_ITEM_SIZES, 3 * sizeof(size_t), &gpu_info->gpu_dev[device_index].maxWorkItemSizes, nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_ITEM_SIZES, 3 * sizeof(size_t), + &gpu_info->gpu_dev[device_index].maxWorkItemSizes, nullptr); - clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &gpu_info->gpu_dev[device_index].maxWorkGroupSize, nullptr); + clGetDeviceInfo(ocl_device_ids[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), + &gpu_info->gpu_dev[device_index].maxWorkGroupSize, nullptr); - gpu_info->gpu_dev[device_index].stat = gmx::checkGpu(device_index, gpu_info->gpu_dev + device_index); + gpu_info->gpu_dev[device_index].stat = + gmx::checkGpu(device_index, gpu_info->gpu_dev + device_index); if (egpuCompatible == gpu_info->gpu_dev[device_index].stat) { @@ -515,7 +522,7 @@ void findGpus(gmx_gpu_info_t *gpu_info) sfree(ocl_platform_ids); } -void get_gpu_device_info_string(char *s, const gmx_gpu_info_t &gpu_info, int index) +void get_gpu_device_info_string(char* s, const gmx_gpu_info_t& gpu_info, int index) { assert(s); @@ -524,28 +531,23 @@ void get_gpu_device_info_string(char *s, const gmx_gpu_info_t &gpu_info, int ind return; } - gmx_device_info_t *dinfo = &gpu_info.gpu_dev[index]; + gmx_device_info_t* dinfo = &gpu_info.gpu_dev[index]; - bool bGpuExists = (dinfo->stat != egpuNonexistent && - dinfo->stat != egpuInsane); + bool bGpuExists = (dinfo->stat != egpuNonexistent && dinfo->stat != egpuInsane); if (!bGpuExists) { - sprintf(s, "#%d: %s, stat: %s", - index, "N/A", - gpu_detect_res_str[dinfo->stat]); + sprintf(s, "#%d: %s, stat: %s", index, "N/A", gpu_detect_res_str[dinfo->stat]); } else { - sprintf(s, "#%d: name: %s, vendor: %s, device version: %s, stat: %s", - index, dinfo->device_name, dinfo->device_vendor, - dinfo->device_version, - gpu_detect_res_str[dinfo->stat]); + sprintf(s, "#%d: name: %s, vendor: %s, device version: %s, stat: %s", index, dinfo->device_name, + dinfo->device_vendor, dinfo->device_version, gpu_detect_res_str[dinfo->stat]); } } -void init_gpu(const gmx_device_info_t *deviceInfo) +void init_gpu(const gmx_device_info_t* deviceInfo) { assert(deviceInfo); @@ -567,8 +569,7 @@ void init_gpu(const gmx_device_info_t *deviceInfo) } } -gmx_device_info_t *getDeviceInfo(const gmx_gpu_info_t &gpu_info, - int deviceId) +gmx_device_info_t* getDeviceInfo(const gmx_gpu_info_t& gpu_info, int deviceId) { if (deviceId < 0 || deviceId >= gpu_info.n_dev) { @@ -582,7 +583,7 @@ size_t sizeof_gpu_dev_info() return sizeof(gmx_device_info_t); } -int gpu_info_get_stat(const gmx_gpu_info_t &info, int index) +int gpu_info_get_stat(const gmx_gpu_info_t& info, int index) { return info.gpu_dev[index].stat; } diff --git a/src/gromacs/gpu_utils/gpu_vec.cuh b/src/gromacs/gpu_utils/gpu_vec.cuh index 360dcba345..fa61b158dd 100644 --- a/src/gromacs/gpu_utils/gpu_vec.cuh +++ b/src/gromacs/gpu_utils/gpu_vec.cuh @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,198 +38,181 @@ /* Note that because of the duplicate of ivec, this header (or an * OpenCL port of it) cannot be included in a translation unit that * also includes the normal vectypes.h */ -#define XX 0 /* Defines for indexing in */ -#define YY 1 /* vectors */ -#define ZZ 2 -#define DIM 3 /* Dimension of vectors */ +#define XX 0 /* Defines for indexing in */ +#define YY 1 /* vectors */ +#define ZZ 2 +#define DIM 3 /* Dimension of vectors */ typedef int ivec[DIM]; typedef float fvec[DIM]; /* maths operations */ /* imported from cpu versions in math/vec.h */ -__forceinline__ __device__ -void svmul_gpu(float a, const fvec v1, fvec v2) +__forceinline__ __device__ void svmul_gpu(float a, const fvec v1, fvec v2) { - v2[XX] = a*v1[XX]; - v2[YY] = a*v1[YY]; - v2[ZZ] = a*v1[ZZ]; + v2[XX] = a * v1[XX]; + v2[YY] = a * v1[YY]; + v2[ZZ] = a * v1[ZZ]; } -__forceinline__ __device__ -void fvec_add_gpu(const fvec a, const fvec b, fvec c) +__forceinline__ __device__ void fvec_add_gpu(const fvec a, const fvec b, fvec c) { float x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; c[XX] = x; c[YY] = y; c[ZZ] = z; } -__forceinline__ __device__ -void ivec_add_gpu(const ivec a, const ivec b, ivec c) +__forceinline__ __device__ void ivec_add_gpu(const ivec a, const ivec b, ivec c) { int x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; c[XX] = x; c[YY] = y; c[ZZ] = z; } -__forceinline__ __device__ -void fvec_inc_atomic(fvec a, const fvec b) +__forceinline__ __device__ void fvec_inc_atomic(fvec a, const fvec b) { atomicAdd(&a[XX], b[XX]); atomicAdd(&a[YY], b[YY]); atomicAdd(&a[ZZ], b[ZZ]); } -__forceinline__ __device__ -void fvec_inc_gpu(fvec a, const fvec b) +__forceinline__ __device__ void fvec_inc_gpu(fvec a, const fvec b) { float x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; a[XX] = x; a[YY] = y; a[ZZ] = z; } -__forceinline__ __device__ -void fvec_dec_atomic(fvec a, const fvec b) +__forceinline__ __device__ void fvec_dec_atomic(fvec a, const fvec b) { - atomicAdd(&a[XX], -1.0f*b[XX]); - atomicAdd(&a[YY], -1.0f*b[YY]); - atomicAdd(&a[ZZ], -1.0f*b[ZZ]); + atomicAdd(&a[XX], -1.0f * b[XX]); + atomicAdd(&a[YY], -1.0f * b[YY]); + atomicAdd(&a[ZZ], -1.0f * b[ZZ]); } -__forceinline__ __device__ -void fvec_dec_gpu(fvec a, const fvec b) +__forceinline__ __device__ void fvec_dec_gpu(fvec a, const fvec b) { float x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; a[XX] = x; a[YY] = y; a[ZZ] = z; } -__forceinline__ __device__ -void cprod_gpu(const fvec a, const fvec b, fvec c) +__forceinline__ __device__ void cprod_gpu(const fvec a, const fvec b, fvec c) { - c[XX] = a[YY]*b[ZZ]-a[ZZ]*b[YY]; - c[YY] = a[ZZ]*b[XX]-a[XX]*b[ZZ]; - c[ZZ] = a[XX]*b[YY]-a[YY]*b[XX]; + c[XX] = a[YY] * b[ZZ] - a[ZZ] * b[YY]; + c[YY] = a[ZZ] * b[XX] - a[XX] * b[ZZ]; + c[ZZ] = a[XX] * b[YY] - a[YY] * b[XX]; } -__forceinline__ __device__ -float iprod_gpu(const fvec a, const fvec b) +__forceinline__ __device__ float iprod_gpu(const fvec a, const fvec b) { - return (a[XX]*b[XX]+a[YY]*b[YY]+a[ZZ]*b[ZZ]); + return (a[XX] * b[XX] + a[YY] * b[YY] + a[ZZ] * b[ZZ]); } -__forceinline__ __device__ -float norm_gpu(const fvec a) +__forceinline__ __device__ float norm_gpu(const fvec a) { return sqrt(iprod_gpu(a, a)); } -__forceinline__ __device__ -float gmx_angle_gpu(const fvec a, const fvec b) +__forceinline__ __device__ float gmx_angle_gpu(const fvec a, const fvec b) { fvec w; float wlen, s; cprod_gpu(a, b, w); - wlen = norm_gpu(w); - s = iprod_gpu(a, b); + wlen = norm_gpu(w); + s = iprod_gpu(a, b); - return atan2f(wlen, s); //requires float + return atan2f(wlen, s); // requires float } -__forceinline__ __device__ -void clear_ivec_gpu(ivec a) +__forceinline__ __device__ void clear_ivec_gpu(ivec a) { a[XX] = 0; a[YY] = 0; a[ZZ] = 0; } -__forceinline__ __device__ -void fvec_sub_gpu(const fvec a, const fvec b, fvec c) +__forceinline__ __device__ void fvec_sub_gpu(const fvec a, const fvec b, fvec c) { float x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; c[XX] = x; c[YY] = y; c[ZZ] = z; } -__forceinline__ __device__ -float norm2_gpu(const fvec a) +__forceinline__ __device__ float norm2_gpu(const fvec a) { - return a[XX]*a[XX]+a[YY]*a[YY]+a[ZZ]*a[ZZ]; + return a[XX] * a[XX] + a[YY] * a[YY] + a[ZZ] * a[ZZ]; } -__forceinline__ __device__ -void copy_fvec_gpu(const fvec a, fvec b) +__forceinline__ __device__ void copy_fvec_gpu(const fvec a, fvec b) { b[XX] = a[XX]; b[YY] = a[YY]; b[ZZ] = a[ZZ]; } -__forceinline__ __device__ -void copy_ivec_gpu(const ivec a, ivec b) +__forceinline__ __device__ void copy_ivec_gpu(const ivec a, ivec b) { b[XX] = a[XX]; b[YY] = a[YY]; b[ZZ] = a[ZZ]; } -__forceinline__ __device__ -float cos_angle_gpu(const fvec a, const fvec b) +__forceinline__ __device__ float cos_angle_gpu(const fvec a, const fvec b) { /* * ax*bx + ay*by + az*bz * cos-vec (a,b) = --------------------- * ||a|| * ||b|| */ - float cosval; - int m; - float aa, bb, ip, ipa, ipb, ipab; + float cosval; + int m; + float aa, bb, ip, ipa, ipb, ipab; ip = ipa = ipb = 0.0f; for (m = 0; (m < DIM); m++) { - aa = a[m]; - bb = b[m]; - ip += aa*bb; - ipa += aa*aa; - ipb += bb*bb; + aa = a[m]; + bb = b[m]; + ip += aa * bb; + ipa += aa * aa; + ipb += bb * bb; } - ipab = ipa*ipb; + ipab = ipa * ipb; if (ipab > 0.0f) { - cosval = ip*rsqrt(ipab); + cosval = ip * rsqrt(ipab); } else { @@ -248,15 +231,14 @@ float cos_angle_gpu(const fvec a, const fvec b) } -__device__ -static inline void unitv_gpu(const fvec src, fvec dest) +__device__ static inline void unitv_gpu(const fvec src, fvec dest) { float linv; linv = rsqrt(norm2_gpu(src)); - dest[XX] = linv*src[XX]; - dest[YY] = linv*src[YY]; - dest[ZZ] = linv*src[ZZ]; + dest[XX] = linv * src[XX]; + dest[YY] = linv * src[YY]; + dest[ZZ] = linv * src[ZZ]; } #endif diff --git a/src/gromacs/gpu_utils/gpueventsynchronizer.cuh b/src/gromacs/gpu_utils/gpueventsynchronizer.cuh index ad6f9b512a..e2e6ac8704 100644 --- a/src/gromacs/gpu_utils/gpueventsynchronizer.cuh +++ b/src/gromacs/gpu_utils/gpueventsynchronizer.cuh @@ -59,47 +59,47 @@ */ class GpuEventSynchronizer { - public: - GpuEventSynchronizer() - { - cudaError_t gmx_used_in_debug stat = cudaEventCreateWithFlags(&event_, cudaEventDisableTiming); - GMX_RELEASE_ASSERT(stat == cudaSuccess, "cudaEventCreate failed"); - } - ~GpuEventSynchronizer() - { - cudaError_t gmx_used_in_debug stat = cudaEventDestroy(event_); - GMX_ASSERT(stat == cudaSuccess, "cudaEventDestroy failed"); - } - //! No copying - GpuEventSynchronizer(const GpuEventSynchronizer &) = delete; - //! No assignment - GpuEventSynchronizer &operator = (GpuEventSynchronizer &&) = delete; - //! Moving is disabled but can be considered in the future if needed - GpuEventSynchronizer(GpuEventSynchronizer &&) = delete; +public: + GpuEventSynchronizer() + { + cudaError_t gmx_used_in_debug stat = cudaEventCreateWithFlags(&event_, cudaEventDisableTiming); + GMX_RELEASE_ASSERT(stat == cudaSuccess, "cudaEventCreate failed"); + } + ~GpuEventSynchronizer() + { + cudaError_t gmx_used_in_debug stat = cudaEventDestroy(event_); + GMX_ASSERT(stat == cudaSuccess, "cudaEventDestroy failed"); + } + //! No copying + GpuEventSynchronizer(const GpuEventSynchronizer&) = delete; + //! No assignment + GpuEventSynchronizer& operator=(GpuEventSynchronizer&&) = delete; + //! Moving is disabled but can be considered in the future if needed + GpuEventSynchronizer(GpuEventSynchronizer&&) = delete; - /*! \brief Marks the synchronization point in the \p stream. - * Should be followed by waitForEvent(). - */ - inline void markEvent(CommandStream stream) - { - cudaError_t gmx_used_in_debug stat = cudaEventRecord(event_, stream); - GMX_ASSERT(stat == cudaSuccess, "cudaEventRecord failed"); - } - /*! \brief Synchronizes the host thread on the marked event. */ - inline void waitForEvent() - { - cudaError_t gmx_used_in_debug stat = cudaEventSynchronize(event_); - GMX_ASSERT(stat == cudaSuccess, "cudaEventSynchronize failed"); - } - /*! \brief Enqueues a wait for the recorded event in stream \p stream */ - inline void enqueueWaitEvent(CommandStream stream) - { - cudaError_t gmx_used_in_debug stat = cudaStreamWaitEvent(stream, event_, 0); - GMX_ASSERT(stat == cudaSuccess, "cudaStreamWaitEvent failed"); - } + /*! \brief Marks the synchronization point in the \p stream. + * Should be followed by waitForEvent(). + */ + inline void markEvent(CommandStream stream) + { + cudaError_t gmx_used_in_debug stat = cudaEventRecord(event_, stream); + GMX_ASSERT(stat == cudaSuccess, "cudaEventRecord failed"); + } + /*! \brief Synchronizes the host thread on the marked event. */ + inline void waitForEvent() + { + cudaError_t gmx_used_in_debug stat = cudaEventSynchronize(event_); + GMX_ASSERT(stat == cudaSuccess, "cudaEventSynchronize failed"); + } + /*! \brief Enqueues a wait for the recorded event in stream \p stream */ + inline void enqueueWaitEvent(CommandStream stream) + { + cudaError_t gmx_used_in_debug stat = cudaStreamWaitEvent(stream, event_, 0); + GMX_ASSERT(stat == cudaSuccess, "cudaStreamWaitEvent failed"); + } - private: - cudaEvent_t event_; +private: + cudaEvent_t event_; }; #endif diff --git a/src/gromacs/gpu_utils/gpueventsynchronizer_ocl.h b/src/gromacs/gpu_utils/gpueventsynchronizer_ocl.h index 2e59065996..b9298f385f 100644 --- a/src/gromacs/gpu_utils/gpueventsynchronizer_ocl.h +++ b/src/gromacs/gpu_utils/gpueventsynchronizer_ocl.h @@ -61,80 +61,84 @@ */ class GpuEventSynchronizer { - public: - //! A constructor - GpuEventSynchronizer() : event_(nullptr){} - //! A destructor - ~GpuEventSynchronizer() +public: + //! A constructor + GpuEventSynchronizer() : event_(nullptr) {} + //! A destructor + ~GpuEventSynchronizer() + { + // This additional code only prevents cl_event leak in an unlikely situation of destructor + // being called after markEvent() but before waitForEvent() / enqueueWaitEvent(). + if (event_) { - // This additional code only prevents cl_event leak in an unlikely situation of destructor - // being called after markEvent() but before waitForEvent() / enqueueWaitEvent(). - if (event_) - { - ensureReferenceCount(event_, 1); - clReleaseEvent(event_); - } + ensureReferenceCount(event_, 1); + clReleaseEvent(event_); } - //! No copying - GpuEventSynchronizer(const GpuEventSynchronizer &) = delete; - //! No assignment - GpuEventSynchronizer &operator=(GpuEventSynchronizer &&) = delete; - //! Moving is disabled but can be considered in the future if needed - GpuEventSynchronizer(GpuEventSynchronizer &&) = delete; + } + //! No copying + GpuEventSynchronizer(const GpuEventSynchronizer&) = delete; + //! No assignment + GpuEventSynchronizer& operator=(GpuEventSynchronizer&&) = delete; + //! Moving is disabled but can be considered in the future if needed + GpuEventSynchronizer(GpuEventSynchronizer&&) = delete; - /*! \brief Marks the synchronization point in the \p stream. - * Should be called first and then followed by waitForEvent(). - */ - inline void markEvent(CommandStream stream) + /*! \brief Marks the synchronization point in the \p stream. + * Should be called first and then followed by waitForEvent(). + */ + inline void markEvent(CommandStream stream) + { + GMX_ASSERT(nullptr == event_, "Do not call markEvent more than once!"); + cl_int clError = clEnqueueMarkerWithWaitList(stream, 0, nullptr, &event_); + if (CL_SUCCESS != clError) { - GMX_ASSERT(nullptr == event_, "Do not call markEvent more than once!"); - cl_int clError = clEnqueueMarkerWithWaitList(stream, 0, nullptr, &event_); - if (CL_SUCCESS != clError) - { - GMX_THROW(gmx::InternalError("Failed to enqueue the GPU synchronization event: " + ocl_get_error_string(clError))); - } + GMX_THROW(gmx::InternalError("Failed to enqueue the GPU synchronization event: " + + ocl_get_error_string(clError))); } - /*! \brief Synchronizes the host thread on the marked event. */ - inline void waitForEvent() + } + /*! \brief Synchronizes the host thread on the marked event. */ + inline void waitForEvent() + { + cl_int clError = clWaitForEvents(1, &event_); + if (CL_SUCCESS != clError) { - cl_int clError = clWaitForEvents(1, &event_); - if (CL_SUCCESS != clError) - { - GMX_THROW(gmx::InternalError("Failed to synchronize on the GPU event: " + ocl_get_error_string(clError))); - } - - releaseEvent(); + GMX_THROW(gmx::InternalError("Failed to synchronize on the GPU event: " + + ocl_get_error_string(clError))); } - /*! \brief Enqueues a wait for the recorded event in stream \p stream - * - * After enqueue, the associated event is released, so this method should - * be only called once per markEvent() call. - */ - inline void enqueueWaitEvent(CommandStream stream) - { - cl_int clError = clEnqueueBarrierWithWaitList(stream, 1, &event_, nullptr); - if (CL_SUCCESS != clError) - { - GMX_THROW(gmx::InternalError("Failed to enqueue device barrier for the GPU event: " + ocl_get_error_string(clError))); - } - releaseEvent(); + releaseEvent(); + } + /*! \brief Enqueues a wait for the recorded event in stream \p stream + * + * After enqueue, the associated event is released, so this method should + * be only called once per markEvent() call. + */ + inline void enqueueWaitEvent(CommandStream stream) + { + cl_int clError = clEnqueueBarrierWithWaitList(stream, 1, &event_, nullptr); + if (CL_SUCCESS != clError) + { + GMX_THROW(gmx::InternalError("Failed to enqueue device barrier for the GPU event: " + + ocl_get_error_string(clError))); } - private: - inline void releaseEvent() + releaseEvent(); + } + +private: + inline void releaseEvent() + { + // Reference count can't be checked after the event's released, it seems (segfault on NVIDIA). + ensureReferenceCount(event_, 1); + cl_int clError = clReleaseEvent(event_); + if (CL_SUCCESS != clError) { - // Reference count can't be checked after the event's released, it seems (segfault on NVIDIA). - ensureReferenceCount(event_, 1); - cl_int clError = clReleaseEvent(event_); - if (CL_SUCCESS != clError) - { - GMX_THROW(gmx::InternalError("Failed to release the GPU event: " + ocl_get_error_string(clError))); - } - event_ = nullptr; + GMX_THROW(gmx::InternalError("Failed to release the GPU event: " + + ocl_get_error_string(clError))); } + event_ = nullptr; + } - cl_event event_; + cl_event event_; }; #endif diff --git a/src/gromacs/gpu_utils/gpuregiontimer.cuh b/src/gromacs/gpu_utils/gpuregiontimer.cuh index 393bd7f726..52e36c038a 100644 --- a/src/gromacs/gpu_utils/gpuregiontimer.cuh +++ b/src/gromacs/gpu_utils/gpuregiontimer.cuh @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,58 +59,55 @@ class GpuRegionTimerImpl //! The underlying timing event pair - the beginning and the end of the timespan cudaEvent_t eventStart_, eventStop_; - public: +public: + GpuRegionTimerImpl() + { + const int eventFlags = cudaEventDefault; + CU_RET_ERR(cudaEventCreate(&eventStart_, eventFlags), "GPU timing creation failure"); + CU_RET_ERR(cudaEventCreate(&eventStop_, eventFlags), "GPU timing creation failure"); + } + ~GpuRegionTimerImpl() + { + CU_RET_ERR(cudaEventDestroy(eventStart_), "GPU timing destruction failure"); + CU_RET_ERR(cudaEventDestroy(eventStop_), "GPU timing destruction failure"); + } + //! No copying + GpuRegionTimerImpl(const GpuRegionTimerImpl&) = delete; + //! No assignment + GpuRegionTimerImpl& operator=(GpuRegionTimerImpl&&) = delete; + //! Moving is disabled but can be considered in the future if needed + GpuRegionTimerImpl(GpuRegionTimerImpl&&) = delete; - GpuRegionTimerImpl() - { - const int eventFlags = cudaEventDefault; - CU_RET_ERR(cudaEventCreate(&eventStart_, eventFlags), "GPU timing creation failure"); - CU_RET_ERR(cudaEventCreate(&eventStop_, eventFlags), "GPU timing creation failure"); - } - ~GpuRegionTimerImpl() - { - CU_RET_ERR(cudaEventDestroy(eventStart_), "GPU timing destruction failure"); - CU_RET_ERR(cudaEventDestroy(eventStop_), "GPU timing destruction failure"); - } - //! No copying - GpuRegionTimerImpl(const GpuRegionTimerImpl &) = delete; - //! No assignment - GpuRegionTimerImpl &operator = (GpuRegionTimerImpl &&) = delete; - //! Moving is disabled but can be considered in the future if needed - GpuRegionTimerImpl(GpuRegionTimerImpl &&) = delete; + /*! \brief Will be called before the region start. */ + inline void openTimingRegion(CommandStream s) + { + CU_RET_ERR(cudaEventRecord(eventStart_, s), "GPU timing recording failure"); + } - /*! \brief Will be called before the region start. */ - inline void openTimingRegion(CommandStream s) - { - CU_RET_ERR(cudaEventRecord(eventStart_, s), "GPU timing recording failure"); - } + /*! \brief Will be called after the region end. */ + inline void closeTimingRegion(CommandStream s) + { + CU_RET_ERR(cudaEventRecord(eventStop_, s), "GPU timing recording failure"); + } - /*! \brief Will be called after the region end. */ - inline void closeTimingRegion(CommandStream s) - { - CU_RET_ERR(cudaEventRecord(eventStop_, s), "GPU timing recording failure"); - } + /*! \brief Returns the last measured region timespan (in milliseconds) and calls reset() */ + inline double getLastRangeTime() + { + float milliseconds = 0.0; + CU_RET_ERR(cudaEventElapsedTime(&milliseconds, eventStart_, eventStop_), + "GPU timing update failure"); + reset(); + return milliseconds; + } - /*! \brief Returns the last measured region timespan (in milliseconds) and calls reset() */ - inline double getLastRangeTime() - { - float milliseconds = 0.0; - CU_RET_ERR(cudaEventElapsedTime(&milliseconds, eventStart_, eventStop_), "GPU timing update failure"); - reset(); - return milliseconds; - } + /*! \brief Resets internal state */ + inline void reset() {} - /*! \brief Resets internal state */ - inline void reset(){} - - /*! \brief Returns a new raw timing event - * for passing into individual GPU API calls. - * This is just a dummy in CUDA. - */ - inline CommandEvent *fetchNextEvent() - { - return nullptr; - } + /*! \brief Returns a new raw timing event + * for passing into individual GPU API calls. + * This is just a dummy in CUDA. + */ + inline CommandEvent* fetchNextEvent() { return nullptr; } }; //! Short-hand for external use diff --git a/src/gromacs/gpu_utils/gpuregiontimer.h b/src/gromacs/gpu_utils/gpuregiontimer.h index d33cc9baec..6798159ac9 100644 --- a/src/gromacs/gpu_utils/gpuregiontimer.h +++ b/src/gromacs/gpu_utils/gpuregiontimer.h @@ -62,7 +62,8 @@ static const bool c_debugTimerState = true; * as far as current implementation allows (see TODO in getLastRangeTime() for a disabled check). * Internally it uses GpuRegionTimerImpl for measuring regions. */ -template class GpuRegionTimerWrapper +template +class GpuRegionTimerWrapper { //! The timer state used for debug-only assertions enum class TimerState @@ -73,108 +74,107 @@ template class GpuRegionTimerWrapper } debugState_ = TimerState::Idle; //! The number of times the timespan has been measured - unsigned int callCount_ = 0; + unsigned int callCount_ = 0; //! The accumulated duration of the timespans measured (milliseconds) - double totalMilliseconds_ = 0.0; + double totalMilliseconds_ = 0.0; //! The underlying region timer implementation GpuRegionTimerImpl impl_; - public: - - /*! \brief - * To be called before the region start. - * - * \param[in] s The GPU command stream where the event being measured takes place. - */ - void openTimingRegion(CommandStream s) - { - if (c_debugTimerState) - { - std::string error = "GPU timer should be idle, but is " + std::string((debugState_ == TimerState::Stopped) ? "stopped" : "recording") + "."; - GMX_ASSERT(debugState_ == TimerState::Idle, error.c_str()); - debugState_ = TimerState::Recording; - } - impl_.openTimingRegion(s); - } - /*! \brief - * To be called after the region end. - * - * \param[in] s The GPU command stream where the event being measured takes place. - */ - void closeTimingRegion(CommandStream s) - { - if (c_debugTimerState) - { - std::string error = "GPU timer should be recording, but is " + std::string((debugState_ == TimerState::Idle) ? "idle" : "stopped") + "."; - GMX_ASSERT(debugState_ == TimerState::Recording, error.c_str()); - debugState_ = TimerState::Stopped; - } - callCount_++; - impl_.closeTimingRegion(s); - } - /*! \brief - * Accumulates the last timespan of all the events used into the total duration, - * and resets the internal timer state. - * To be called after closeTimingRegion() and the command stream of the event having been synchronized. - * \returns The last timespan (in milliseconds). - */ - double getLastRangeTime() +public: + /*! \brief + * To be called before the region start. + * + * \param[in] s The GPU command stream where the event being measured takes place. + */ + void openTimingRegion(CommandStream s) + { + if (c_debugTimerState) { - if (c_debugTimerState) - { - /* The assertion below is commented because it is currently triggered on a special case: - * the early return before the local non-bonded kernel launch if there is nothing to do. - * This can be reproduced in OpenCL build by running - * mdrun-mpi-test -ntmpi 2 --gtest_filter=*Empty* - * Similarly, the GpuRegionTimerImpl suffers from non-nullptr - * cl_event conditionals which ideally should only be asserts. - * TODO: improve internal task scheduling, re-enable the assert, turn conditionals into asserts - */ - /* - std::string error = "GPU timer should be stopped, but is " + std::string((debugState_ == TimerState::Idle) ? "idle" : "recording") + "."; - GMX_ASSERT(debugState_ == TimerState::Stopped, error.c_str()); - */ - debugState_ = TimerState::Idle; - } - double milliseconds = impl_.getLastRangeTime(); - totalMilliseconds_ += milliseconds; - return milliseconds; + std::string error = "GPU timer should be idle, but is " + + std::string((debugState_ == TimerState::Stopped) ? "stopped" : "recording") + + "."; + GMX_ASSERT(debugState_ == TimerState::Idle, error.c_str()); + debugState_ = TimerState::Recording; } - /*! \brief Resets the implementation and total time/call count to zeroes. */ - void reset() + impl_.openTimingRegion(s); + } + /*! \brief + * To be called after the region end. + * + * \param[in] s The GPU command stream where the event being measured takes place. + */ + void closeTimingRegion(CommandStream s) + { + if (c_debugTimerState) { - if (c_debugTimerState) - { - debugState_ = TimerState::Idle; - } - totalMilliseconds_ = 0.0; - callCount_ = 0; - impl_.reset(); + std::string error = "GPU timer should be recording, but is " + + std::string((debugState_ == TimerState::Idle) ? "idle" : "stopped") + + "."; + GMX_ASSERT(debugState_ == TimerState::Recording, error.c_str()); + debugState_ = TimerState::Stopped; } - /*! \brief Gets total time recorded (in milliseconds). */ - double getTotalTime() const + callCount_++; + impl_.closeTimingRegion(s); + } + /*! \brief + * Accumulates the last timespan of all the events used into the total duration, + * and resets the internal timer state. + * To be called after closeTimingRegion() and the command stream of the event having been + * synchronized. \returns The last timespan (in milliseconds). + */ + double getLastRangeTime() + { + if (c_debugTimerState) { - return totalMilliseconds_; + /* The assertion below is commented because it is currently triggered on a special case: + * the early return before the local non-bonded kernel launch if there is nothing to do. + * This can be reproduced in OpenCL build by running + * mdrun-mpi-test -ntmpi 2 --gtest_filter=*Empty* + * Similarly, the GpuRegionTimerImpl suffers from non-nullptr + * cl_event conditionals which ideally should only be asserts. + * TODO: improve internal task scheduling, re-enable the assert, turn conditionals into asserts + */ + /* + std::string error = "GPU timer should be stopped, but is " + std::string((debugState_ == TimerState::Idle) ? "idle" : "recording") + "."; + GMX_ASSERT(debugState_ == TimerState::Stopped, error.c_str()); + */ + debugState_ = TimerState::Idle; } - /*! \brief Gets total call count recorded. */ - unsigned int getCallCount() const + double milliseconds = impl_.getLastRangeTime(); + totalMilliseconds_ += milliseconds; + return milliseconds; + } + /*! \brief Resets the implementation and total time/call count to zeroes. */ + void reset() + { + if (c_debugTimerState) { - return callCount_; + debugState_ = TimerState::Idle; } - /*! \brief - * Gets a pointer to a new timing event for passing into individual GPU API calls - * within the region if they require it (e.g. on OpenCL). - * \returns The pointer to the underlying single command timing event. - */ - CommandEvent *fetchNextEvent() + totalMilliseconds_ = 0.0; + callCount_ = 0; + impl_.reset(); + } + /*! \brief Gets total time recorded (in milliseconds). */ + double getTotalTime() const { return totalMilliseconds_; } + /*! \brief Gets total call count recorded. */ + unsigned int getCallCount() const { return callCount_; } + /*! \brief + * Gets a pointer to a new timing event for passing into individual GPU API calls + * within the region if they require it (e.g. on OpenCL). + * \returns The pointer to the underlying single command timing event. + */ + CommandEvent* fetchNextEvent() + { + if (c_debugTimerState) { - if (c_debugTimerState) - { - std::string error = "GPU timer should be recording, but is " + std::string((debugState_ == TimerState::Idle) ? "idle" : "stopped") + "."; - GMX_ASSERT(debugState_ == TimerState::Recording, error.c_str()); - } - return impl_.fetchNextEvent(); + std::string error = "GPU timer should be recording, but is " + + std::string((debugState_ == TimerState::Idle) ? "idle" : "stopped") + + "."; + GMX_ASSERT(debugState_ == TimerState::Recording, error.c_str()); } + return impl_.fetchNextEvent(); + } }; #endif diff --git a/src/gromacs/gpu_utils/gpuregiontimer_ocl.h b/src/gromacs/gpu_utils/gpuregiontimer_ocl.h index 47209b9bc4..3c1d9b2b84 100644 --- a/src/gromacs/gpu_utils/gpuregiontimer_ocl.h +++ b/src/gromacs/gpu_utils/gpuregiontimer_ocl.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,74 +67,73 @@ class GpuRegionTimerImpl * The maximum size is chosen arbitrarily to work with current code, and can be changed. * There is simply no need for run-time resizing, and it's unlikely we'll ever need more than 10. */ - std::array events_ = {{nullptr}}; + std::array events_ = { { nullptr } }; //! Index of the active event - size_t currentEvent_ = 0; + size_t currentEvent_ = 0; - public: +public: + GpuRegionTimerImpl() = default; + ~GpuRegionTimerImpl() = default; + //! No copying + GpuRegionTimerImpl(const GpuRegionTimerImpl&) = delete; + //! No assignment + GpuRegionTimerImpl& operator=(GpuRegionTimerImpl&&) = delete; + //! Moving is disabled but can be considered in the future if needed + GpuRegionTimerImpl(GpuRegionTimerImpl&&) = delete; - GpuRegionTimerImpl() = default; - ~GpuRegionTimerImpl() = default; - //! No copying - GpuRegionTimerImpl(const GpuRegionTimerImpl &) = delete; - //! No assignment - GpuRegionTimerImpl &operator=(GpuRegionTimerImpl &&) = delete; - //! Moving is disabled but can be considered in the future if needed - GpuRegionTimerImpl(GpuRegionTimerImpl &&) = delete; - - /*! \brief Should be called before the region start. */ - inline void openTimingRegion(CommandStream /*unused*/){} - /*! \brief Should be called after the region end. */ - inline void closeTimingRegion(CommandStream /*unused*/){} - /*! \brief Returns the last measured region timespan (in milliseconds) and calls reset(). */ - inline double getLastRangeTime() + /*! \brief Should be called before the region start. */ + inline void openTimingRegion(CommandStream /*unused*/) {} + /*! \brief Should be called after the region end. */ + inline void closeTimingRegion(CommandStream /*unused*/) {} + /*! \brief Returns the last measured region timespan (in milliseconds) and calls reset(). */ + inline double getLastRangeTime() + { + double milliseconds = 0.0; + for (size_t i = 0; i < currentEvent_; i++) { - double milliseconds = 0.0; - for (size_t i = 0; i < currentEvent_; i++) + if (events_[i]) // This conditional is ugly, but is required to make some tests (e.g. empty domain) pass { - if (events_[i]) // This conditional is ugly, but is required to make some tests (e.g. empty domain) pass - { - cl_ulong start_ns, end_ns; - cl_int gmx_unused cl_error; + cl_ulong start_ns, end_ns; + cl_int gmx_unused cl_error; - cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_START, - sizeof(cl_ulong), &start_ns, nullptr); - GMX_ASSERT(CL_SUCCESS == cl_error, "GPU timing update failure"); - cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_END, - sizeof(cl_ulong), &end_ns, nullptr); - GMX_ASSERT(CL_SUCCESS == cl_error, "GPU timing update failure"); - milliseconds += (end_ns - start_ns) / 1000000.0; - } + cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_START, + sizeof(cl_ulong), &start_ns, nullptr); + GMX_ASSERT(CL_SUCCESS == cl_error, "GPU timing update failure"); + cl_error = clGetEventProfilingInfo(events_[i], CL_PROFILING_COMMAND_END, + sizeof(cl_ulong), &end_ns, nullptr); + GMX_ASSERT(CL_SUCCESS == cl_error, "GPU timing update failure"); + milliseconds += (end_ns - start_ns) / 1000000.0; } - reset(); - return milliseconds; } - /*! \brief Resets the internal state, releasing the used cl_events. */ - inline void reset() + reset(); + return milliseconds; + } + /*! \brief Resets the internal state, releasing the used cl_events. */ + inline void reset() + { + for (size_t i = 0; i < currentEvent_; i++) { - for (size_t i = 0; i < currentEvent_; i++) + if (events_[i]) // This conditional is ugly, but is required to make some tests (e.g. empty domain) pass { - if (events_[i]) // This conditional is ugly, but is required to make some tests (e.g. empty domain) pass - { - cl_int gmx_unused cl_error = clReleaseEvent(events_[i]); - GMX_ASSERT(CL_SUCCESS == cl_error, "OpenCL event release failure"); - } + cl_int gmx_unused cl_error = clReleaseEvent(events_[i]); + GMX_ASSERT(CL_SUCCESS == cl_error, "OpenCL event release failure"); } - currentEvent_ = 0; - // As long as we're doing nullptr checks, we might want to be extra cautious. - events_.fill(nullptr); - } - /*! \brief Returns a new raw timing event - * for passing into individual GPU API calls - * within the region if the API requires it (e.g. on OpenCL). - */ - inline CommandEvent *fetchNextEvent() - { - GMX_ASSERT(currentEvent_ < events_.size(), "Increase c_maxEventNumber_ if needed"); - cl_event *result = &events_[currentEvent_]; - currentEvent_++; - return result; } + currentEvent_ = 0; + // As long as we're doing nullptr checks, we might want to be extra cautious. + events_.fill(nullptr); + } + /*! \brief Returns a new raw timing event + * for passing into individual GPU API calls + * within the region if the API requires it (e.g. on OpenCL). + */ + inline CommandEvent* fetchNextEvent() + { + GMX_ASSERT(currentEvent_ < events_.size(), "Increase c_maxEventNumber_ if needed"); + cl_event* result = &events_[currentEvent_]; + currentEvent_++; + return result; + } }; //! Short-hand for external use diff --git a/src/gromacs/gpu_utils/gputraits.cuh b/src/gromacs/gpu_utils/gputraits.cuh index 559cad265f..7ac35d5329 100644 --- a/src/gromacs/gpu_utils/gputraits.cuh +++ b/src/gromacs/gpu_utils/gputraits.cuh @@ -46,9 +46,9 @@ //! \brief GPU command stream using CommandStream = cudaStream_t; //! \brief Single GPU call timing event - meaningless in CUDA -using CommandEvent = void; +using CommandEvent = void; //! \brief Context used explicitly in OpenCL, does nothing in CUDA -using DeviceContext = void *; +using DeviceContext = void*; /*! \internal \brief * GPU kernels scheduling description. This is same in OpenCL/CUDA. @@ -57,10 +57,10 @@ using DeviceContext = void *; */ struct KernelLaunchConfig { - size_t gridSize[3] = {1, 1, 1}; //!< Block counts - size_t blockSize[3] = {1, 1, 1}; //!< Per-block thread counts - size_t sharedMemorySize = 0; //!< Shared memory size in bytes - CommandStream stream = nullptr; //!< Stream to launch kernel in + size_t gridSize[3] = { 1, 1, 1 }; //!< Block counts + size_t blockSize[3] = { 1, 1, 1 }; //!< Per-block thread counts + size_t sharedMemorySize = 0; //!< Shared memory size in bytes + CommandStream stream = nullptr; //!< Stream to launch kernel in }; //! Sets whether device code can use arrays that are embedded in structs. diff --git a/src/gromacs/gpu_utils/gputraits.h b/src/gromacs/gpu_utils/gputraits.h index 0a8b36517d..9b91c0ec18 100644 --- a/src/gromacs/gpu_utils/gputraits.h +++ b/src/gromacs/gpu_utils/gputraits.h @@ -47,20 +47,20 @@ #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/gputraits.cuh" +# include "gromacs/gpu_utils/gputraits.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gputraits_ocl.h" +# include "gromacs/gpu_utils/gputraits_ocl.h" #else //! \brief GPU command stream -using CommandStream = void *; +using CommandStream = void*; //! \brief Single GPU call timing event -using CommandEvent = void *; +using CommandEvent = void*; //! \brief GPU context -using DeviceContext = void *; +using DeviceContext = void*; #endif // GMX_GPU diff --git a/src/gromacs/gpu_utils/gputraits_ocl.h b/src/gromacs/gpu_utils/gputraits_ocl.h index 5e93698318..865c29967c 100644 --- a/src/gromacs/gpu_utils/gputraits_ocl.h +++ b/src/gromacs/gpu_utils/gputraits_ocl.h @@ -48,7 +48,7 @@ //! \brief GPU command stream using CommandStream = cl_command_queue; //! \brief Single GPU call timing event -using CommandEvent = cl_event; +using CommandEvent = cl_event; //! \brief Context used explicitly in OpenCL using DeviceContext = cl_context; @@ -59,10 +59,10 @@ using DeviceContext = cl_context; */ struct KernelLaunchConfig { - size_t gridSize[3] = {1, 1, 1}; //!< Work groups (CUDA blocks) counts - size_t blockSize[3] = {1, 1, 1}; //!< Per work group (CUDA block) thread counts - size_t sharedMemorySize = 0; //!< Shared memory size in bytes - CommandStream stream = nullptr; //!< Stream to launch kernel in + size_t gridSize[3] = { 1, 1, 1 }; //!< Work groups (CUDA blocks) counts + size_t blockSize[3] = { 1, 1, 1 }; //!< Per work group (CUDA block) thread counts + size_t sharedMemorySize = 0; //!< Shared memory size in bytes + CommandStream stream = nullptr; //!< Stream to launch kernel in }; /*! \brief Sets whether device code can use arrays that are embedded in structs. diff --git a/src/gromacs/gpu_utils/hostallocator.cpp b/src/gromacs/gpu_utils/hostallocator.cpp index 378dbab163..1ffa63d048 100644 --- a/src/gromacs/gpu_utils/hostallocator.cpp +++ b/src/gromacs/gpu_utils/hostallocator.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,23 +55,22 @@ namespace gmx { -HostAllocationPolicy::HostAllocationPolicy(PinningPolicy pinningPolicy) - : pinningPolicy_(pinningPolicy) +HostAllocationPolicy::HostAllocationPolicy(PinningPolicy pinningPolicy) : + pinningPolicy_(pinningPolicy) { } std::size_t HostAllocationPolicy::alignment() const noexcept { - return (pinningPolicy_ == PinningPolicy::PinnedIfSupported ? - PageAlignedAllocationPolicy::alignment() : - AlignedAllocationPolicy::alignment()); + return (pinningPolicy_ == PinningPolicy::PinnedIfSupported ? PageAlignedAllocationPolicy::alignment() + : AlignedAllocationPolicy::alignment()); } -void *HostAllocationPolicy::malloc(std::size_t bytes) const noexcept +void* HostAllocationPolicy::malloc(std::size_t bytes) const noexcept { if (pinningPolicy_ == PinningPolicy::PinnedIfSupported) { - void *p = PageAlignedAllocationPolicy::malloc(bytes); + void* p = PageAlignedAllocationPolicy::malloc(bytes); if (p) { /* For every pin, unpin has to be called or resources will @@ -96,7 +95,7 @@ void *HostAllocationPolicy::malloc(std::size_t bytes) const noexcept } } -void HostAllocationPolicy::free(void *buffer) const noexcept +void HostAllocationPolicy::free(void* buffer) const noexcept { if (buffer == nullptr) { diff --git a/src/gromacs/gpu_utils/hostallocator.h b/src/gromacs/gpu_utils/hostallocator.h index 89e9b0de49..888c86062e 100644 --- a/src/gromacs/gpu_utils/hostallocator.h +++ b/src/gromacs/gpu_utils/hostallocator.h @@ -72,9 +72,9 @@ namespace gmx * required for correct, efficient operation in all cases. */ enum class PinningPolicy : int { - CannotBePinned, // Memory is not known to be suitable for pinning. - PinnedIfSupported, // Memory is suitable for efficient pinning, e.g. because it is - // allocated to be page aligned, and will be pinned when supported. + CannotBePinned, // Memory is not known to be suitable for pinning. + PinnedIfSupported, // Memory is suitable for efficient pinning, e.g. because it is + // allocated to be page aligned, and will be pinned when supported. }; //! Forward declaration of host allocation policy class. @@ -90,16 +90,16 @@ class HostAllocationPolicy; * memory will always be allocated according to the behavior of * HostAllocationPolicy. */ -template +template using HostAllocator = Allocator; //! Convenience alias for std::vector that uses HostAllocator. -template -using HostVector = std::vector >; +template +using HostVector = std::vector>; //! Convenience alias for PaddedVector that uses HostAllocator. -template -using PaddedHostVector = PaddedVector >; +template +using PaddedHostVector = PaddedVector>; /*! \libinternal * \brief Policy class for configuring gmx::Allocator, to manage @@ -137,63 +137,60 @@ using PaddedHostVector = PaddedVector >; */ class HostAllocationPolicy { - public: - //! Constructor - HostAllocationPolicy(PinningPolicy policy = PinningPolicy::CannotBePinned); - /*! \brief Return the alignment size currently used by the active pinning policy. */ - std::size_t alignment() const noexcept; - /*! \brief Allocate and perhaps pin page-aligned memory suitable for - * e.g. GPU transfers. - * - * Before attempting to allocate, unpin() is called. After a - * successful allocation, pin() is called. (Whether these do - * things depends on the PinningPolicy that is in effect.) - * - * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for - * 0 bytes, which will return a non-null pointer that is properly - * aligned and padded (but that you should not use). - * - * \return Valid pointer if the allocation+optional pinning worked, otherwise nullptr. - * - * \note Memory allocated with this routine must be released - * with gmx::HostAllocationPolicy::free(), and - * absolutely not the system free(). - * - * Does not throw. - */ - void *malloc(std::size_t bytes) const noexcept; - /*! \brief Free the memory, after unpinning (if appropriate). - * - * \param buffer Memory pointer previously returned from gmx::HostAllocationPolicy::malloc() - * - * \note This routine should only be called with pointers - * obtained from gmx:HostAllocationPolicy::malloc(), - * and absolutely not any pointers obtained the system - * malloc(). - * - * Does not throw. - */ - void free(void *buffer) const noexcept; - /*! \brief Return the active pinning policy. - * - * Does not throw. - */ - PinningPolicy pinningPolicy() const { return pinningPolicy_; } - //! Don't propagate for copy - using propagate_on_container_copy_assignment = std::false_type; - //! Propagate for move - using propagate_on_container_move_assignment = std::true_type; - //! Propagate for move - using propagate_on_container_swap = std::true_type; - //! Use default allocator for copy (same as construct+copy) - HostAllocationPolicy select_on_container_copy_construction() const - { - return {}; - } +public: + //! Constructor + HostAllocationPolicy(PinningPolicy policy = PinningPolicy::CannotBePinned); + /*! \brief Return the alignment size currently used by the active pinning policy. */ + std::size_t alignment() const noexcept; + /*! \brief Allocate and perhaps pin page-aligned memory suitable for + * e.g. GPU transfers. + * + * Before attempting to allocate, unpin() is called. After a + * successful allocation, pin() is called. (Whether these do + * things depends on the PinningPolicy that is in effect.) + * + * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for + * 0 bytes, which will return a non-null pointer that is properly + * aligned and padded (but that you should not use). + * + * \return Valid pointer if the allocation+optional pinning worked, otherwise nullptr. + * + * \note Memory allocated with this routine must be released + * with gmx::HostAllocationPolicy::free(), and + * absolutely not the system free(). + * + * Does not throw. + */ + void* malloc(std::size_t bytes) const noexcept; + /*! \brief Free the memory, after unpinning (if appropriate). + * + * \param buffer Memory pointer previously returned from gmx::HostAllocationPolicy::malloc() + * + * \note This routine should only be called with pointers + * obtained from gmx:HostAllocationPolicy::malloc(), + * and absolutely not any pointers obtained the system + * malloc(). + * + * Does not throw. + */ + void free(void* buffer) const noexcept; + /*! \brief Return the active pinning policy. + * + * Does not throw. + */ + PinningPolicy pinningPolicy() const { return pinningPolicy_; } + //! Don't propagate for copy + using propagate_on_container_copy_assignment = std::false_type; + //! Propagate for move + using propagate_on_container_move_assignment = std::true_type; + //! Propagate for move + using propagate_on_container_swap = std::true_type; + //! Use default allocator for copy (same as construct+copy) + HostAllocationPolicy select_on_container_copy_construction() const { return {}; } - private: - //! Pinning policy - PinningPolicy pinningPolicy_; +private: + //! Pinning policy + PinningPolicy pinningPolicy_; }; /*! \brief Return true if two allocators are identical @@ -201,8 +198,7 @@ class HostAllocationPolicy * True if pinning policy is the same. */ template -bool operator==(const Allocator &a, - const Allocator &b) +bool operator==(const Allocator& a, const Allocator& b) { return a.pinningPolicy() == b.pinningPolicy(); } @@ -215,16 +211,15 @@ bool operator==(const Allocator &a, * restrictions. That cost is OK, because GROMACS will do this * operation very rarely (e.g. when auto-tuning and deciding to switch * whether a task will run on a GPU, or not). */ -template -void changePinningPolicy(PinnableVector *v, - PinningPolicy pinningPolicy) +template +void changePinningPolicy(PinnableVector* v, PinningPolicy pinningPolicy) { // Force reallocation by element-wise move (because policy is // different container is forced to realloc). Does nothing if // policy is the same. - *v = PinnableVector(std::move(*v), {pinningPolicy}); + *v = PinnableVector(std::move(*v), { pinningPolicy }); } -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/gpu_utils/ocl_caching.cpp b/src/gromacs/gpu_utils/ocl_caching.cpp index ef7fa819ea..44eaf47e16 100644 --- a/src/gromacs/gpu_utils/ocl_caching.cpp +++ b/src/gromacs/gpu_utils/ocl_caching.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,17 +68,18 @@ namespace gmx namespace ocl { -std::string makeBinaryCacheFilename(const std::string &kernelFilename, - cl_device_id deviceId) +std::string makeBinaryCacheFilename(const std::string& kernelFilename, cl_device_id deviceId) { // Note that the OpenCL API is defined in terms of bytes, and we // assume that sizeof(char) is one byte. std::array deviceName; size_t deviceNameLength; - cl_int cl_error = clGetDeviceInfo(deviceId, CL_DEVICE_NAME, deviceName.size(), deviceName.data(), &deviceNameLength); + cl_int cl_error = clGetDeviceInfo(deviceId, CL_DEVICE_NAME, deviceName.size(), + deviceName.data(), &deviceNameLength); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError(formatString("Could not get OpenCL device name, error was %s", ocl_get_error_string(cl_error).c_str()))); + GMX_THROW(InternalError(formatString("Could not get OpenCL device name, error was %s", + ocl_get_error_string(cl_error).c_str()))); } std::string cacheFilename = "OCL-cache"; @@ -92,16 +93,14 @@ std::string makeBinaryCacheFilename(const std::string &kernelFilename, (symbols), by permitting only alphanumeric characters from the current locale. We assume these work well enough in a filename. */ - std::copy_if(deviceName.begin(), deviceName.begin() + deviceNameLength, std::back_inserter(cacheFilename), isalnum); + std::copy_if(deviceName.begin(), deviceName.begin() + deviceNameLength, + std::back_inserter(cacheFilename), isalnum); cacheFilename += ".bin"; return cacheFilename; } -cl_program -makeProgramFromCache(const std::string &filename, - cl_context context, - cl_device_id deviceId) +cl_program makeProgramFromCache(const std::string& filename, cl_context context, cl_device_id deviceId) { // TODO all this file reading stuff should become gmx::BinaryReader const auto f = create_unique_with_deleter(fopen(filename.c_str(), "rb"), fclose); @@ -112,7 +111,7 @@ makeProgramFromCache(const std::string &filename, // TODO more stdio error handling fseek(f.get(), 0, SEEK_END); - unsigned char *binary; + unsigned char* binary; unique_cptr binaryGuard; size_t fileSize = ftell(f.get()); snew(binary, fileSize); @@ -134,40 +133,39 @@ makeProgramFromCache(const std::string &filename, /* Create program from pre-built binary */ cl_int cl_error; - cl_program program = clCreateProgramWithBinary(context, - 1, - &deviceId, - &fileSize, - const_cast(&binary), - nullptr, - &cl_error); + cl_program program = clCreateProgramWithBinary(context, 1, &deviceId, &fileSize, + const_cast(&binary), + nullptr, &cl_error); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not create OpenCL program, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not create OpenCL program, error was " + + ocl_get_error_string(cl_error))); } return program; } -void -writeBinaryToCache(cl_program program, const std::string &filename) +void writeBinaryToCache(cl_program program, const std::string& filename) { size_t fileSize; - cl_int cl_error = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(fileSize), &fileSize, nullptr); + cl_int cl_error = + clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(fileSize), &fileSize, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not get OpenCL program binary size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not get OpenCL program binary size, error was " + + ocl_get_error_string(cl_error))); } // TODO all this file writing stuff should become gmx::BinaryWriter - unsigned char *binary; + unsigned char* binary; snew(binary, fileSize); const unique_cptr binaryGuard(binary); cl_error = clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(binary), &binary, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not get OpenCL program binary, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not get OpenCL program binary, error was " + + ocl_get_error_string(cl_error))); } const auto f = create_unique_with_deleter(fopen(filename.c_str(), "wb"), fclose); diff --git a/src/gromacs/gpu_utils/ocl_caching.h b/src/gromacs/gpu_utils/ocl_caching.h index cb6c9811e0..df1f8ce75a 100644 --- a/src/gromacs/gpu_utils/ocl_caching.h +++ b/src/gromacs/gpu_utils/ocl_caching.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,8 +69,7 @@ namespace ocl * * \returns The name of the cache file. */ -std::string makeBinaryCacheFilename(const std::string &kernelFilename, - cl_device_id deviceId); +std::string makeBinaryCacheFilename(const std::string& kernelFilename, cl_device_id deviceId); /*! \brief Check if there's a valid cache available, and return it if so * @@ -83,10 +82,7 @@ std::string makeBinaryCacheFilename(const std::string &kernelFilename, * \throws InternalError if an OpenCL error was encountered * FileIOError if the file could not be opened */ -cl_program -makeProgramFromCache(const std::string &filename, - cl_context context, - cl_device_id deviceId); +cl_program makeProgramFromCache(const std::string& filename, cl_context context, cl_device_id deviceId); /*! \brief Implement caching of OpenCL binaries * @@ -96,8 +92,7 @@ makeProgramFromCache(const std::string &filename, * \throws InternalError if an OpenCL error was encountered * FileIOError if the file could not be opened */ -void -writeBinaryToCache(cl_program program, const std::string &filename); +void writeBinaryToCache(cl_program program, const std::string& filename); } // namespace ocl } // namespace gmx diff --git a/src/gromacs/gpu_utils/ocl_compiler.cpp b/src/gromacs/gpu_utils/ocl_compiler.cpp index f5b093e974..9d3b692df1 100644 --- a/src/gromacs/gpu_utils/ocl_compiler.cpp +++ b/src/gromacs/gpu_utils/ocl_compiler.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -87,20 +87,18 @@ static bool useBuildCache = getenv("GMX_OCL_GENCACHE") != nullptr; * \param program OpenCL program that was compiled * \param deviceId Id of the device for which compilation took place * \param kernelFilename File name containing the kernel - * \param preprocessorOptions String containing the preprocessor command-line options used for the build - * \param buildFailed Whether the OpenCL build succeeded + * \param preprocessorOptions String containing the preprocessor command-line options used for the + * build \param buildFailed Whether the OpenCL build succeeded * * \throws std::bad_alloc if out of memory */ -static void -writeOclBuildLog(FILE *fplog, - cl_program program, - cl_device_id deviceId, - const std::string &kernelFilename, - const std::string &preprocessorOptions, - bool buildFailed) +static void writeOclBuildLog(FILE* fplog, + cl_program program, + cl_device_id deviceId, + const std::string& kernelFilename, + const std::string& preprocessorOptions, + bool buildFailed) { - bool writeOutput = ((fplog != nullptr) && - (buildFailed || (getenv("GMX_OCL_DUMP_LOG") != nullptr))); + bool writeOutput = ((fplog != nullptr) && (buildFailed || (getenv("GMX_OCL_DUMP_LOG") != nullptr))); if (!writeOutput) { @@ -109,18 +107,15 @@ writeOclBuildLog(FILE *fplog, // Get build log string size size_t buildLogSize; - cl_int cl_error = clGetProgramBuildInfo(program, - deviceId, - CL_PROGRAM_BUILD_LOG, - 0, - nullptr, - &buildLogSize); + cl_int cl_error = + clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG, 0, nullptr, &buildLogSize); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not get OpenCL program build log size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not get OpenCL program build log size, error was " + + ocl_get_error_string(cl_error))); } - char *buildLog = nullptr; + char* buildLog = nullptr; unique_cptr buildLogGuard; if (buildLogSize != 0) { @@ -130,15 +125,12 @@ writeOclBuildLog(FILE *fplog, buildLogGuard.reset(buildLog); /* Get the actual compilation log */ - cl_error = clGetProgramBuildInfo(program, - deviceId, - CL_PROGRAM_BUILD_LOG, - buildLogSize, - buildLog, - nullptr); + cl_error = clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG, buildLogSize, + buildLog, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not get OpenCL program build log, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not get OpenCL program build log, error was " + + ocl_get_error_string(cl_error))); } } @@ -154,7 +146,8 @@ writeOclBuildLog(FILE *fplog, message += "-- Used build options: " + preprocessorOptions + "\n"; message += "--------------LOG START---------------\n"; message += buildLog; - message += "---------------LOG END----------------\n";; + message += "---------------LOG END----------------\n"; + ; fputs(message.c_str(), fplog); } @@ -165,12 +158,11 @@ writeOclBuildLog(FILE *fplog, * automatically enable some vendor-specific options * \return The string with the compiler options */ -static std::string -selectCompilerOptions(ocl_vendor_id_t deviceVendorId) +static std::string selectCompilerOptions(ocl_vendor_id_t deviceVendorId) { std::string compilerOptions; - if (getenv("GMX_OCL_NOOPT") ) + if (getenv("GMX_OCL_NOOPT")) { compilerOptions += " -cl-opt-disable"; } @@ -222,29 +214,28 @@ selectCompilerOptions(ocl_vendor_id_t deviceVendorId) * \throws std::bad_alloc if out of memory. * FileIOError if GMX_OCL_FILE_PATH does not specify a readable path */ -static std::string -getSourceRootPath(const std::string &sourceRelativePath) +static std::string getSourceRootPath(const std::string& sourceRelativePath) { std::string sourceRootPath; /* Use GMX_OCL_FILE_PATH if the user has defined it */ - const char *gmxOclFilePath = getenv("GMX_OCL_FILE_PATH"); + const char* gmxOclFilePath = getenv("GMX_OCL_FILE_PATH"); if (gmxOclFilePath == nullptr) { /* Normal way of getting ocl_root_dir. First get the right root path from the path to the binary that is running. */ - InstallationPrefixInfo info = getProgramContext().installationPrefix(); - std::string dataPathSuffix = (info.bSourceLayout ? - "src" : - GMX_INSTALL_OCLDIR); + InstallationPrefixInfo info = getProgramContext().installationPrefix(); + std::string dataPathSuffix = (info.bSourceLayout ? "src" : GMX_INSTALL_OCLDIR); sourceRootPath = Path::join(info.path, dataPathSuffix, sourceRelativePath); } else { if (!Directory::exists(gmxOclFilePath)) { - GMX_THROW(FileIOError(formatString("GMX_OCL_FILE_PATH must point to the directory where OpenCL" - "kernels are found, but '%s' does not exist", gmxOclFilePath))); + GMX_THROW(FileIOError( + formatString("GMX_OCL_FILE_PATH must point to the directory where OpenCL" + "kernels are found, but '%s' does not exist", + gmxOclFilePath))); } sourceRootPath = Path::join(gmxOclFilePath, sourceRelativePath); } @@ -256,11 +247,13 @@ getSourceRootPath(const std::string &sourceRelativePath) size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId) { size_t warpSize = 0; - cl_int cl_error = clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, - sizeof(warpSize), &warpSize, nullptr); + cl_int cl_error = + clGetKernelWorkGroupInfo(kernel, deviceId, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, + sizeof(warpSize), &warpSize, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not query OpenCL preferred workgroup size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not query OpenCL preferred workgroup size, error was " + + ocl_get_error_string(cl_error))); } if (warpSize == 0) { @@ -272,23 +265,27 @@ size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId) size_t getDeviceWarpSize(cl_context context, cl_device_id deviceId) { cl_int cl_error; - const char *warpSizeKernel = "__kernel void test(__global int* test){test[get_local_id(0)] = 0;}"; - cl_program program = clCreateProgramWithSource(context, 1, &warpSizeKernel, nullptr, &cl_error); + const char* warpSizeKernel = + "__kernel void test(__global int* test){test[get_local_id(0)] = 0;}"; + cl_program program = clCreateProgramWithSource(context, 1, &warpSizeKernel, nullptr, &cl_error); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not create OpenCL program to determine warp size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not create OpenCL program to determine warp size, error was " + + ocl_get_error_string(cl_error))); } cl_error = clBuildProgram(program, 0, nullptr, nullptr, nullptr, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not build OpenCL program to determine warp size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not build OpenCL program to determine warp size, error was " + + ocl_get_error_string(cl_error))); } cl_kernel kernel = clCreateKernel(program, "test", &cl_error); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not create OpenCL kernel to determine warp size, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not create OpenCL kernel to determine warp size, error was " + + ocl_get_error_string(cl_error))); } size_t warpSize = getKernelWarpSize(kernel, deviceId); @@ -296,12 +293,14 @@ size_t getDeviceWarpSize(cl_context context, cl_device_id deviceId) cl_error = clReleaseKernel(kernel); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not release OpenCL warp-size kernel, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not release OpenCL warp-size kernel, error was " + + ocl_get_error_string(cl_error))); } cl_error = clReleaseProgram(program); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not release OpenCL warp-size program, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not release OpenCL warp-size program, error was " + + ocl_get_error_string(cl_error))); } return warpSize; @@ -313,24 +312,15 @@ size_t getDeviceWarpSize(cl_context context, cl_device_id deviceId) * * \return The appropriate compilation-line define */ -static const char * -makeVendorFlavorChoice(ocl_vendor_id_t vendorId) +static const char* makeVendorFlavorChoice(ocl_vendor_id_t vendorId) { - const char *choice; + const char* choice; switch (vendorId) { - case OCL_VENDOR_AMD: - choice = "-D_AMD_SOURCE_"; - break; - case OCL_VENDOR_NVIDIA: - choice = "-D_NVIDIA_SOURCE_"; - break; - case OCL_VENDOR_INTEL: - choice = "-D_INTEL_SOURCE_"; - break; - default: - choice = ""; - break; + case OCL_VENDOR_AMD: choice = "-D_AMD_SOURCE_"; break; + case OCL_VENDOR_NVIDIA: choice = "-D_NVIDIA_SOURCE_"; break; + case OCL_VENDOR_INTEL: choice = "-D_INTEL_SOURCE_"; break; + default: choice = ""; break; } return choice; } @@ -341,7 +331,7 @@ makeVendorFlavorChoice(ocl_vendor_id_t vendorId) * * \throws std::bad_alloc if out of memory. */ -static std::string makeKernelIncludePathOption(const std::string &unescapedKernelRootPath) +static std::string makeKernelIncludePathOption(const std::string& unescapedKernelRootPath) { std::string includePathOption; @@ -375,29 +365,27 @@ static std::string makeKernelIncludePathOption(const std::string &unescapedKerne * * \param str String that will be modified. */ -static void -removeExtraSpaces(std::string *str) +static void removeExtraSpaces(std::string* str) { GMX_RELEASE_ASSERT(str != nullptr, "A pointer to an actual string must be provided"); - std::string::iterator newEnd = - std::unique( str->begin(), str->end(), [ = ](char a, char b){ return isspace(a) != 0 && (a == b); } ); + std::string::iterator newEnd = std::unique( + str->begin(), str->end(), [=](char a, char b) { return isspace(a) != 0 && (a == b); }); str->erase(newEnd, str->end()); } /*! \brief Builds a string with build options for the OpenCL kernels * * \throws std::bad_alloc if out of memory. */ -static std::string -makePreprocessorOptions(const std::string &kernelRootPath, - const std::string &includeRootPath, - size_t warpSize, - ocl_vendor_id_t deviceVendorId, - const std::string &extraDefines) +static std::string makePreprocessorOptions(const std::string& kernelRootPath, + const std::string& includeRootPath, + size_t warpSize, + ocl_vendor_id_t deviceVendorId, + const std::string& extraDefines) { std::string preprocessorOptions; /* Compose the complete build options */ - preprocessorOptions = formatString("-DWARP_SIZE_TEST=%d", static_cast(warpSize)); + preprocessorOptions = formatString("-DWARP_SIZE_TEST=%d", static_cast(warpSize)); preprocessorOptions += ' '; preprocessorOptions += makeVendorFlavorChoice(deviceVendorId); preprocessorOptions += ' '; @@ -415,35 +403,30 @@ makePreprocessorOptions(const std::string &kernelRootPath, return preprocessorOptions; } -cl_program -compileProgram(FILE *fplog, - const std::string &kernelRelativePath, - const std::string &kernelBaseFilename, - const std::string &extraDefines, - cl_context context, - cl_device_id deviceId, - ocl_vendor_id_t deviceVendorId) +cl_program compileProgram(FILE* fplog, + const std::string& kernelRelativePath, + const std::string& kernelBaseFilename, + const std::string& extraDefines, + cl_context context, + cl_device_id deviceId, + ocl_vendor_id_t deviceVendorId) { - cl_int cl_error; + cl_int cl_error; // Let the kernel find include files from its module. - std::string kernelRootPath = getSourceRootPath(kernelRelativePath); + std::string kernelRootPath = getSourceRootPath(kernelRelativePath); // Let the kernel find include files from other modules. std::string rootPath = getSourceRootPath(""); GMX_RELEASE_ASSERT(fplog != nullptr, "Need a valid log file for building OpenCL programs"); /* Load OpenCL source files */ - std::string kernelFilename = Path::join(kernelRootPath, - kernelBaseFilename); + std::string kernelFilename = Path::join(kernelRootPath, kernelBaseFilename); /* Make the build options */ - std::string preprocessorOptions = makePreprocessorOptions(kernelRootPath, - rootPath, - getDeviceWarpSize(context, deviceId), - deviceVendorId, - extraDefines); + std::string preprocessorOptions = makePreprocessorOptions( + kernelRootPath, rootPath, getDeviceWarpSize(context, deviceId), deviceVendorId, extraDefines); - bool buildCacheWasRead = false; + bool buildCacheWasRead = false; std::string cacheFilename; if (useBuildCache) @@ -463,7 +446,7 @@ compileProgram(FILE *fplog, program = makeProgramFromCache(cacheFilename, context, deviceId); buildCacheWasRead = true; } - catch (FileIOError &e) + catch (FileIOError& e) { // Failing to read from the cache is not a critical error formatExceptionMessageToFile(fplog, e); @@ -471,7 +454,8 @@ compileProgram(FILE *fplog, } else { - fprintf(fplog, "No OpenCL binary cache file was present, so will compile kernels normally.\n"); + fprintf(fplog, + "No OpenCL binary cache file was present, so will compile kernels normally.\n"); } } if (program == nullptr) @@ -482,36 +466,31 @@ compileProgram(FILE *fplog, { GMX_THROW(FileIOError("Error loading OpenCL code " + kernelFilename)); } - const char *kernelSourcePtr = kernelSource.c_str(); + const char* kernelSourcePtr = kernelSource.c_str(); size_t kernelSourceSize = kernelSource.size(); /* Create program from source code */ - program = clCreateProgramWithSource(context, - 1, - &kernelSourcePtr, - &kernelSourceSize, - &cl_error); + program = clCreateProgramWithSource(context, 1, &kernelSourcePtr, &kernelSourceSize, &cl_error); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not create OpenCL program, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not create OpenCL program, error was " + + ocl_get_error_string(cl_error))); } } /* Build the OpenCL program, keeping the status to potentially write to the simulation log file. */ - cl_int buildStatus = clBuildProgram(program, 0, nullptr, preprocessorOptions.c_str(), nullptr, nullptr); + cl_int buildStatus = + clBuildProgram(program, 0, nullptr, preprocessorOptions.c_str(), nullptr, nullptr); /* Write log first, and then throw exception that the user know what is the issue even if the build fails. */ - writeOclBuildLog(fplog, - program, - deviceId, - kernelFilename, - preprocessorOptions, + writeOclBuildLog(fplog, program, deviceId, kernelFilename, preprocessorOptions, buildStatus != CL_SUCCESS); if (buildStatus != CL_SUCCESS) { - GMX_THROW(InternalError("Could not build OpenCL program, error was " + ocl_get_error_string(buildStatus))); + GMX_THROW(InternalError("Could not build OpenCL program, error was " + + ocl_get_error_string(buildStatus))); } if (useBuildCache) @@ -524,7 +503,7 @@ compileProgram(FILE *fplog, { writeBinaryToCache(program, cacheFilename); } - catch (GromacsException &e) + catch (GromacsException& e) { // Failing to write the cache is not a critical error formatExceptionMessageToFile(fplog, e); @@ -540,7 +519,8 @@ compileProgram(FILE *fplog, cl_error = clGetDeviceInfo(deviceId, CL_DEVICE_NAME, sizeof(buffer), buffer, nullptr); if (cl_error != CL_SUCCESS) { - GMX_THROW(InternalError("Could not get OpenCL device info, error was " + ocl_get_error_string(cl_error))); + GMX_THROW(InternalError("Could not get OpenCL device info, error was " + + ocl_get_error_string(cl_error))); } std::string ptxFilename = buffer; ptxFilename += ".ptx"; @@ -549,7 +529,7 @@ compileProgram(FILE *fplog, { writeBinaryToCache(program, ptxFilename); } - catch (GromacsException &e) + catch (GromacsException& e) { // Failing to write the cache is not a critical error formatExceptionMessageToFile(fplog, e); diff --git a/src/gromacs/gpu_utils/ocl_compiler.h b/src/gromacs/gpu_utils/ocl_compiler.h index a155d1c695..68b34c1a22 100644 --- a/src/gromacs/gpu_utils/ocl_compiler.h +++ b/src/gromacs/gpu_utils/ocl_compiler.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,8 +55,8 @@ namespace ocl /*! \brief Get the device-specific warp size * - * This is platform implementation dependent and seems to only work on the Nvidia and AMD platforms! - * Nvidia reports 32, AMD for GPU 64. Intel seems to report 16, but that is not correct, + * This is platform implementation dependent and seems to only work on the Nvidia and AMD + * platforms! Nvidia reports 32, AMD for GPU 64. Intel seems to report 16, but that is not correct, * as it execution width can be between 8-32 and it's picked per-kernel at compile-time. * Therefore, for Intel it should actually be queried separately for each kernel (Redmine #2520). * @@ -84,11 +84,11 @@ size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId); * \param[out] fplog Open file pointer for log output * \param[in] kernelRelativePath Relative path to the kernel in the source tree, * e.g. "src/gromacs/mdlib/nbnxn_ocl" for NB kernels. - * \param[in] kernelBaseFilename The name of the kernel source file to compile, e.g. "nbnxn_ocl_kernels.cl" - * \param[in] extraDefines Preprocessor defines required by the calling code, e.g. for configuring the kernels - * \param[in] context OpenCL context on the device to compile for - * \param[in] deviceId OpenCL device id of the device to compile for - * \param[in] deviceVendorId Enumerator of the device vendor to compile for + * \param[in] kernelBaseFilename The name of the kernel source file to compile, e.g. + * "nbnxn_ocl_kernels.cl" \param[in] extraDefines Preprocessor defines required by the + * calling code, e.g. for configuring the kernels \param[in] context OpenCL context + * on the device to compile for \param[in] deviceId OpenCL device id of the device to + * compile for \param[in] deviceVendorId Enumerator of the device vendor to compile for * * \returns The compiled OpenCL program * @@ -100,16 +100,15 @@ size_t getKernelWarpSize(cl_kernel kernel, cl_device_id deviceId); * \throws std::bad_alloc if out of memory. * FileIOError if a file I/O error prevents returning a valid compiled program. * InternalError if an OpenCL API error prevents returning a valid compiled program. */ -cl_program -compileProgram(FILE *fplog, - const std::string &kernelRelativePath, - const std::string &kernelBaseFilename, - const std::string &extraDefines, - cl_context context, - cl_device_id deviceId, - ocl_vendor_id_t deviceVendorId); +cl_program compileProgram(FILE* fplog, + const std::string& kernelRelativePath, + const std::string& kernelBaseFilename, + const std::string& extraDefines, + cl_context context, + cl_device_id deviceId, + ocl_vendor_id_t deviceVendorId); -} // namespace ocl -} // namespace gmx +} // namespace ocl +} // namespace gmx #endif diff --git a/src/gromacs/gpu_utils/oclraii.h b/src/gromacs/gpu_utils/oclraii.h index 23c77ef14e..02aeae05c9 100644 --- a/src/gromacs/gpu_utils/oclraii.h +++ b/src/gromacs/gpu_utils/oclraii.h @@ -48,19 +48,19 @@ namespace gmx { /*! \libinternal \brief Stub for OpenCL type traits */ -template +template struct OpenClTraits; /*! \libinternal \brief Implements common trait infrastructure for OpenCL types. */ -template +template struct OpenClTraitsBase { //! Type of the function that will release a handle of this type. - using ReleaserType = cl_int(*)(cl_type); + using ReleaserType = cl_int (*)(cl_type); }; /*! \libinternal \brief Implements traits for cl_context. */ -template <> +template<> struct OpenClTraits : public OpenClTraitsBase { //! Function that will release a handle of this type. @@ -68,7 +68,7 @@ struct OpenClTraits : public OpenClTraitsBase }; /*! \libinternal \brief Implements traits for cl_command_queue. */ -template <> +template<> struct OpenClTraits : public OpenClTraitsBase { //! Function that will release a handle of this type. @@ -76,7 +76,7 @@ struct OpenClTraits : public OpenClTraitsBase +template<> struct OpenClTraits : public OpenClTraitsBase { //! Function that will release a handle of this type. @@ -84,7 +84,7 @@ struct OpenClTraits : public OpenClTraitsBase }; /*! \libinternal \brief Implements traits for cl_kernel. */ -template <> +template<> struct OpenClTraits : public OpenClTraitsBase { //! Function that will release a handle of this type. @@ -99,30 +99,31 @@ struct OpenClTraits : public OpenClTraitsBase * Simple copying and assignment are not supported, because there's no * need for that, and would require OpenCL API calls for deep copies * if they were needed. Move and move assignment are fine, however. */ -template +template class ClHandle { - public: - //! Constructor that takes an already created handle. - explicit ClHandle(cl_type handle) : handle_(handle) {} - //! Destructor that calls the releaser associated with cl_type. - ~ClHandle() { OpenClTraits::releaser(handle_); } - //! Deleted default constructor. - ClHandle() = delete; - //! Deleted assignment operator. - ClHandle &operator=(const ClHandle &) = delete; - //! Deleted copy constructor. - ClHandle(const ClHandle &) = delete; - //! Default move assignment operator. - ClHandle &operator=(ClHandle &&) noexcept = default; - //! Default copy constructor. - ClHandle(ClHandle &&) noexcept = default; - /*! \brief Convenience conversion operator so the wrapper type - * can simply convert to the wrapped type. */ - operator cl_type() const { return handle_; } - private: - //! The wrapped object. - cl_type handle_; +public: + //! Constructor that takes an already created handle. + explicit ClHandle(cl_type handle) : handle_(handle) {} + //! Destructor that calls the releaser associated with cl_type. + ~ClHandle() { OpenClTraits::releaser(handle_); } + //! Deleted default constructor. + ClHandle() = delete; + //! Deleted assignment operator. + ClHandle& operator=(const ClHandle&) = delete; + //! Deleted copy constructor. + ClHandle(const ClHandle&) = delete; + //! Default move assignment operator. + ClHandle& operator=(ClHandle&&) noexcept = default; + //! Default copy constructor. + ClHandle(ClHandle&&) noexcept = default; + /*! \brief Convenience conversion operator so the wrapper type + * can simply convert to the wrapped type. */ + operator cl_type() const { return handle_; } + +private: + //! The wrapped object. + cl_type handle_; }; //! Convenience declarations. diff --git a/src/gromacs/gpu_utils/oclutils.cpp b/src/gromacs/gpu_utils/oclutils.cpp index b5efc4397e..b14545f7ed 100644 --- a/src/gromacs/gpu_utils/oclutils.cpp +++ b/src/gromacs/gpu_utils/oclutils.cpp @@ -52,11 +52,13 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -int ocl_copy_H2D(cl_mem d_dest, const void* h_src, - size_t offset, size_t bytes, +int ocl_copy_H2D(cl_mem d_dest, + const void* h_src, + size_t offset, + size_t bytes, GpuApiCallBehavior transferKind, - cl_command_queue command_queue, - cl_event *copy_event) + cl_command_queue command_queue, + cl_event* copy_event) { cl_int gmx_unused cl_error; @@ -68,19 +70,20 @@ int ocl_copy_H2D(cl_mem d_dest, const void* h_src, switch (transferKind) { case GpuApiCallBehavior::Async: - cl_error = clEnqueueWriteBuffer(command_queue, d_dest, CL_FALSE, offset, bytes, h_src, 0, nullptr, copy_event); + cl_error = clEnqueueWriteBuffer(command_queue, d_dest, CL_FALSE, offset, bytes, h_src, + 0, nullptr, copy_event); assert(cl_error == CL_SUCCESS); // TODO: handle errors break; case GpuApiCallBehavior::Sync: - cl_error = clEnqueueWriteBuffer(command_queue, d_dest, CL_TRUE, offset, bytes, h_src, 0, nullptr, copy_event); + cl_error = clEnqueueWriteBuffer(command_queue, d_dest, CL_TRUE, offset, bytes, h_src, 0, + nullptr, copy_event); assert(cl_error == CL_SUCCESS); // TODO: handle errors break; - default: - throw; + default: throw; } return 0; @@ -92,28 +95,30 @@ int ocl_copy_H2D(cl_mem d_dest, const void* h_src, * identifying this particular host to device operation. The event can further * be used to queue a wait for this operation or to query profiling information. */ -int ocl_copy_H2D_async(cl_mem d_dest, const void * h_src, - size_t offset, size_t bytes, +int ocl_copy_H2D_async(cl_mem d_dest, + const void* h_src, + size_t offset, + size_t bytes, cl_command_queue command_queue, - cl_event *copy_event) + cl_event* copy_event) { return ocl_copy_H2D(d_dest, h_src, offset, bytes, GpuApiCallBehavior::Async, command_queue, copy_event); } /*! \brief Launches synchronous host to device memory copy. */ -int ocl_copy_H2D_sync(cl_mem d_dest, const void * h_src, - size_t offset, size_t bytes, - cl_command_queue command_queue) +int ocl_copy_H2D_sync(cl_mem d_dest, const void* h_src, size_t offset, size_t bytes, cl_command_queue command_queue) { return ocl_copy_H2D(d_dest, h_src, offset, bytes, GpuApiCallBehavior::Sync, command_queue, nullptr); } -int ocl_copy_D2H(void * h_dest, cl_mem d_src, - size_t offset, size_t bytes, +int ocl_copy_D2H(void* h_dest, + cl_mem d_src, + size_t offset, + size_t bytes, GpuApiCallBehavior transferKind, - cl_command_queue command_queue, - cl_event *copy_event) + cl_command_queue command_queue, + cl_event* copy_event) { cl_int gmx_unused cl_error; @@ -125,19 +130,20 @@ int ocl_copy_D2H(void * h_dest, cl_mem d_src, switch (transferKind) { case GpuApiCallBehavior::Async: - cl_error = clEnqueueReadBuffer(command_queue, d_src, CL_FALSE, offset, bytes, h_dest, 0, nullptr, copy_event); + cl_error = clEnqueueReadBuffer(command_queue, d_src, CL_FALSE, offset, bytes, h_dest, 0, + nullptr, copy_event); assert(cl_error == CL_SUCCESS); // TODO: handle errors break; case GpuApiCallBehavior::Sync: - cl_error = clEnqueueReadBuffer(command_queue, d_src, CL_TRUE, offset, bytes, h_dest, 0, nullptr, copy_event); + cl_error = clEnqueueReadBuffer(command_queue, d_src, CL_TRUE, offset, bytes, h_dest, 0, + nullptr, copy_event); assert(cl_error == CL_SUCCESS); // TODO: handle errors break; - default: - throw; + default: throw; } return 0; @@ -149,10 +155,12 @@ int ocl_copy_D2H(void * h_dest, cl_mem d_src, * identifying this particular host to device operation. The event can further * be used to queue a wait for this operation or to query profiling information. */ -int ocl_copy_D2H_async(void * h_dest, cl_mem d_src, - size_t offset, size_t bytes, +int ocl_copy_D2H_async(void* h_dest, + cl_mem d_src, + size_t offset, + size_t bytes, cl_command_queue command_queue, - cl_event *copy_event) + cl_event* copy_event) { return ocl_copy_D2H(h_dest, d_src, offset, bytes, GpuApiCallBehavior::Async, command_queue, copy_event); } @@ -166,12 +174,12 @@ int ocl_copy_D2H_async(void * h_dest, cl_mem d_src, * \param[in,out] h_ptr Pointer where to store the address of the newly allocated buffer. * \param[in] nbytes Size in bytes of the buffer to be allocated. */ -void pmalloc(void **h_ptr, size_t nbytes) +void pmalloc(void** h_ptr, size_t nbytes) { /* Need a temporary type whose size is 1 byte, so that the * implementation of snew_aligned can cope without issuing * warnings. */ - char **temporary = reinterpret_cast(h_ptr); + char** temporary = reinterpret_cast(h_ptr); /* 16-byte alignment is required by the neighbour-searching code, * because it uses four-wide SIMD for bounding-box calculation. @@ -185,7 +193,7 @@ void pmalloc(void **h_ptr, size_t nbytes) * * \param[in] h_ptr Buffer allocated with pmalloc that needs to be freed. */ -void pfree(void *h_ptr) +void pfree(void* h_ptr) { if (h_ptr) @@ -269,7 +277,6 @@ std::string ocl_get_error_string(cl_int error) case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR"; case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR"; case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR"; - default: return "Unknown OpenCL error: " + - std::to_string(static_cast(error)); + default: return "Unknown OpenCL error: " + std::to_string(static_cast(error)); } } diff --git a/src/gromacs/gpu_utils/oclutils.h b/src/gromacs/gpu_utils/oclutils.h index 18d281c2ed..00df0ffcaa 100644 --- a/src/gromacs/gpu_utils/oclutils.h +++ b/src/gromacs/gpu_utils/oclutils.h @@ -51,7 +51,8 @@ enum class GpuApiCallBehavior; /*! \brief OpenCL vendor IDs */ -typedef enum { +typedef enum +{ OCL_VENDOR_NVIDIA = 0, OCL_VENDOR_AMD, OCL_VENDOR_INTEL, @@ -66,8 +67,8 @@ typedef enum { */ typedef struct { - cl_platform_id ocl_platform_id; /**< Platform ID */ - cl_device_id ocl_device_id; /**< Device ID */ + cl_platform_id ocl_platform_id; /**< Platform ID */ + cl_device_id ocl_device_id; /**< Device ID */ } ocl_gpu_id_t; /*! \internal @@ -79,16 +80,16 @@ typedef struct */ struct gmx_device_info_t { - ocl_gpu_id_t ocl_gpu_id; /**< device ID assigned at detection */ - char device_name[256]; /**< device name */ - char device_version[256]; /**< device version */ - char device_vendor[256]; /**< device vendor */ - int compute_units; /**< number of compute units */ - int adress_bits; /**< number of adress bits the device is capable of */ - int stat; /**< device status takes values of e_gpu_detect_res_t */ - ocl_vendor_id_t vendor_e; /**< device vendor as defined by ocl_vendor_id_t */ - size_t maxWorkItemSizes[3]; /**< workgroup size limits (CL_DEVICE_MAX_WORK_ITEM_SIZES) */ - size_t maxWorkGroupSize; /**< workgroup total size limit (CL_DEVICE_MAX_WORK_GROUP_SIZE) */ + ocl_gpu_id_t ocl_gpu_id; /**< device ID assigned at detection */ + char device_name[256]; /**< device name */ + char device_version[256]; /**< device version */ + char device_vendor[256]; /**< device vendor */ + int compute_units; /**< number of compute units */ + int adress_bits; /**< number of adress bits the device is capable of */ + int stat; /**< device status takes values of e_gpu_detect_res_t */ + ocl_vendor_id_t vendor_e; /**< device vendor as defined by ocl_vendor_id_t */ + size_t maxWorkItemSizes[3]; /**< workgroup size limits (CL_DEVICE_MAX_WORK_ITEM_SIZES) */ + size_t maxWorkGroupSize; /**< workgroup total size limit (CL_DEVICE_MAX_WORK_GROUP_SIZE) */ }; /*! \internal @@ -113,18 +114,22 @@ struct gmx_device_runtime_data_t * identifying this particular device to host operation. The event can further * be used to queue a wait for this operation or to query profiling information. */ -int ocl_copy_D2H(void * h_dest, cl_mem d_src, - size_t offset, size_t bytes, +int ocl_copy_D2H(void* h_dest, + cl_mem d_src, + size_t offset, + size_t bytes, GpuApiCallBehavior transferKind, - cl_command_queue command_queue, - cl_event *copy_event); + cl_command_queue command_queue, + cl_event* copy_event); /*! \brief Launches asynchronous device to host memory copy. */ -int ocl_copy_D2H_async(void * h_dest, cl_mem d_src, - size_t offset, size_t bytes, +int ocl_copy_D2H_async(void* h_dest, + cl_mem d_src, + size_t offset, + size_t bytes, cl_command_queue command_queue, - cl_event *copy_event); + cl_event* copy_event); /*! \brief Launches synchronous or asynchronous host to device memory copy. * @@ -132,28 +137,30 @@ int ocl_copy_D2H_async(void * h_dest, cl_mem d_src, * identifying this particular host to device operation. The event can further * be used to queue a wait for this operation or to query profiling information. */ -int ocl_copy_H2D(cl_mem d_dest, const void* h_src, - size_t offset, size_t bytes, +int ocl_copy_H2D(cl_mem d_dest, + const void* h_src, + size_t offset, + size_t bytes, GpuApiCallBehavior transferKind, - cl_command_queue command_queue, - cl_event *copy_event); + cl_command_queue command_queue, + cl_event* copy_event); /*! \brief Launches asynchronous host to device memory copy. */ -int ocl_copy_H2D_async(cl_mem d_dest, const void * h_src, - size_t offset, size_t bytes, +int ocl_copy_H2D_async(cl_mem d_dest, + const void* h_src, + size_t offset, + size_t bytes, cl_command_queue command_queue, - cl_event *copy_event); + cl_event* copy_event); /*! \brief Launches synchronous host to device memory copy. */ -int ocl_copy_H2D_sync(cl_mem d_dest, const void * h_src, - size_t offset, size_t bytes, - cl_command_queue command_queue); +int ocl_copy_H2D_sync(cl_mem d_dest, const void* h_src, size_t offset, size_t bytes, cl_command_queue command_queue); /*! \brief Allocate host memory in malloc style */ -void pmalloc(void **h_ptr, size_t nbytes); +void pmalloc(void** h_ptr, size_t nbytes); /*! \brief Free host memory in malloc style */ -void pfree(void *h_ptr); +void pfree(void* h_ptr); /*! \brief Convert error code to diagnostic string */ std::string ocl_get_error_string(cl_int error); @@ -170,7 +177,7 @@ static inline void gpuStreamSynchronize(cl_command_queue s) } //! A debug checker to track cl_events being released correctly -inline void ensureReferenceCount(const cl_event &event, unsigned int refCount) +inline void ensureReferenceCount(const cl_event& event, unsigned int refCount) { #ifndef NDEBUG cl_int clError = clGetEventInfo(event, CL_EVENT_REFERENCE_COUNT, sizeof(refCount), &refCount, nullptr); @@ -207,13 +214,12 @@ static inline bool haveStreamTasksCompleted(cl_command_queue gmx_unused s) * \param[in] config Kernel configuration for launching * \param[in] argIndex Index of the current argument */ -void inline prepareGpuKernelArgument(cl_kernel kernel, - const KernelLaunchConfig &config, - size_t argIndex) +void inline prepareGpuKernelArgument(cl_kernel kernel, const KernelLaunchConfig& config, size_t argIndex) { if (config.sharedMemorySize > 0) { - cl_int gmx_used_in_debug clError = clSetKernelArg(kernel, argIndex, config.sharedMemorySize, nullptr); + cl_int gmx_used_in_debug clError = + clSetKernelArg(kernel, argIndex, config.sharedMemorySize, nullptr); GMX_ASSERT(CL_SUCCESS == clError, ocl_get_error_string(clError).c_str()); } } @@ -231,26 +237,25 @@ void inline prepareGpuKernelArgument(cl_kernel kernel, * \param[in] argPtr Pointer to the current argument * \param[in] otherArgsPtrs Pack of pointers to arguments remaining to process after the current one */ -template +template void prepareGpuKernelArgument(cl_kernel kernel, - const KernelLaunchConfig &config, + const KernelLaunchConfig& config, size_t argIndex, - const CurrentArg *argPtr, - const RemainingArgs *... otherArgsPtrs) + const CurrentArg* argPtr, + const RemainingArgs*... otherArgsPtrs) { cl_int gmx_used_in_debug clError = clSetKernelArg(kernel, argIndex, sizeof(CurrentArg), argPtr); GMX_ASSERT(CL_SUCCESS == clError, ocl_get_error_string(clError).c_str()); // Assert on types not allowed to be passed to a kernel // (as per section 6.9 of the OpenCL spec). - static_assert(!std::is_same::value && - !std::is_same::value && - !std::is_same::value && - !std::is_same::value && - !std::is_same::value, + static_assert(!std::is_same::value && !std::is_same::value + && !std::is_same::value + && !std::is_same::value + && !std::is_same::value, "Invalid type passed to OpenCL kernel functions (see OpenCL spec section 6.9)."); - prepareGpuKernelArgument(kernel, config, argIndex + 1, otherArgsPtrs ...); + prepareGpuKernelArgument(kernel, config, argIndex + 1, otherArgsPtrs...); } /*! \brief @@ -264,12 +269,10 @@ void prepareGpuKernelArgument(cl_kernel kernel, * \returns A handle for the prepared parameter pack to be used with launchGpuKernel() as the last argument * - currently always nullptr for OpenCL, as it manages kernel/arguments association by itself. */ -template -void *prepareGpuKernelArguments(cl_kernel kernel, - const KernelLaunchConfig &config, - const Args *... argsPtrs) +template +void* prepareGpuKernelArguments(cl_kernel kernel, const KernelLaunchConfig& config, const Args*... argsPtrs) { - prepareGpuKernelArgument(kernel, config, 0, argsPtrs ...); + prepareGpuKernelArgument(kernel, config, 0, argsPtrs...); return nullptr; } @@ -282,26 +285,27 @@ void *prepareGpuKernelArguments(cl_kernel kernel, * \throws gmx::InternalError on kernel launch failure */ inline void launchGpuKernel(cl_kernel kernel, - const KernelLaunchConfig &config, - CommandEvent *timingEvent, - const char *kernelName, - const void * /*kernelArgs*/) + const KernelLaunchConfig& config, + CommandEvent* timingEvent, + const char* kernelName, + const void* /*kernelArgs*/) { - const int workDimensions = 3; - const size_t *globalWorkOffset = nullptr; - const size_t waitListSize = 0; - const cl_event *waitList = nullptr; + const int workDimensions = 3; + const size_t* globalWorkOffset = nullptr; + const size_t waitListSize = 0; + const cl_event* waitList = nullptr; size_t globalWorkSize[3]; for (int i = 0; i < workDimensions; i++) { globalWorkSize[i] = config.gridSize[i] * config.blockSize[i]; } cl_int clError = clEnqueueNDRangeKernel(config.stream, kernel, workDimensions, globalWorkOffset, - globalWorkSize, config.blockSize, waitListSize, waitList, timingEvent); + globalWorkSize, config.blockSize, waitListSize, + waitList, timingEvent); if (CL_SUCCESS != clError) { - const std::string errorMessage = "GPU kernel (" + std::string(kernelName) + - ") failed to launch: " + ocl_get_error_string(clError); + const std::string errorMessage = "GPU kernel (" + std::string(kernelName) + + ") failed to launch: " + ocl_get_error_string(clError); GMX_THROW(gmx::InternalError(errorMessage)); } } diff --git a/src/gromacs/gpu_utils/pinning.cu b/src/gromacs/gpu_utils/pinning.cu index 880dad2e12..8bed9219b3 100644 --- a/src/gromacs/gpu_utils/pinning.cu +++ b/src/gromacs/gpu_utils/pinning.cu @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,31 +58,33 @@ namespace gmx #if !defined(NDEBUG) || defined(DOXYGEN) //! Is \c ptr aligned on a boundary that is a multiple of \c bytes. -gmx_unused static inline bool isAligned(const void *ptr, size_t bytes) +gmx_unused static inline bool isAligned(const void* ptr, size_t bytes) { return (reinterpret_cast(ptr) % bytes) == 0; } #endif -void pinBuffer(void *pointer, std::size_t numBytes) noexcept +void pinBuffer(void* pointer, std::size_t numBytes) noexcept { - const char *errorMessage = "Could not register the host memory for page locking for GPU transfers."; + const char* errorMessage = + "Could not register the host memory for page locking for GPU transfers."; GMX_ASSERT(isAligned(pointer, PageAlignedAllocationPolicy::alignment()), formatString("%s Host memory needs to be page aligned.", errorMessage).c_str()); - numBytes = std::max(1, numBytes); //C++11 3.7.4.1 gurantees that every pointer is different thus at least 1 byte + numBytes = std::max( + 1, numBytes); // C++11 3.7.4.1 gurantees that every pointer is different thus at least 1 byte ensureNoPendingCudaError(errorMessage); cudaError_t stat = cudaHostRegister(pointer, numBytes, cudaHostRegisterDefault); // These errors can only arise from a coding error somewhere. - GMX_RELEASE_ASSERT(stat != cudaErrorInvalidValue && - stat != cudaErrorNotSupported && - stat != cudaErrorHostMemoryAlreadyRegistered, - formatString("%s %s: %s", errorMessage, - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + GMX_RELEASE_ASSERT( + stat != cudaErrorInvalidValue && stat != cudaErrorNotSupported + && stat != cudaErrorHostMemoryAlreadyRegistered, + formatString("%s %s: %s", errorMessage, cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); // We always handle the error, but if it's a type we didn't expect // (e.g. because CUDA changes the set of errors it returns) then @@ -90,7 +92,8 @@ void pinBuffer(void *pointer, std::size_t numBytes) noexcept // to fix our expectations. GMX_ASSERT(stat != cudaErrorMemoryAllocation, formatString("%s %s: %s which was an unexpected error", errorMessage, - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); // It might be preferable to throw InternalError here, because the // failing condition can only happen when GROMACS is used with a @@ -98,14 +101,14 @@ void pinBuffer(void *pointer, std::size_t numBytes) noexcept // engineer GROMACS to be forward-compatible with future CUDA // versions, so if this proves to be a problem in practice, then // GROMACS must be patched, or a supported CUDA version used. - GMX_RELEASE_ASSERT(stat == cudaSuccess, - formatString("%s %s: %s", errorMessage, - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + GMX_RELEASE_ASSERT(stat == cudaSuccess, formatString("%s %s: %s", errorMessage, + cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); } -void unpinBuffer(void *pointer) noexcept +void unpinBuffer(void* pointer) noexcept { - const char *errorMessage = "Could not unregister pinned host memory used for GPU transfers."; + const char* errorMessage = "Could not unregister pinned host memory used for GPU transfers."; GMX_ASSERT(pointer != nullptr, formatString("%s pointer should not be nullptr when pinned.", errorMessage).c_str()); @@ -113,9 +116,10 @@ void unpinBuffer(void *pointer) noexcept ensureNoPendingCudaError(errorMessage); cudaError_t stat = cudaHostUnregister(pointer); // These errors can only arise from a coding error somewhere. - GMX_RELEASE_ASSERT(stat != cudaErrorInvalidValue && stat != cudaErrorHostMemoryNotRegistered, - formatString("%s %s: %s", errorMessage, - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + GMX_RELEASE_ASSERT( + stat != cudaErrorInvalidValue && stat != cudaErrorHostMemoryNotRegistered, + formatString("%s %s: %s", errorMessage, cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); // If there's an error whose type we didn't expect (e.g. because a // future CUDA changes the set of errors it returns) then we // should assert, because our code is wrong. @@ -126,7 +130,8 @@ void unpinBuffer(void *pointer) noexcept // release assertion is a better behaviour than that. GMX_RELEASE_ASSERT(stat == cudaSuccess, formatString("%s %s: %s which was an unexpected error", errorMessage, - cudaGetErrorName(stat), cudaGetErrorString(stat)).c_str()); + cudaGetErrorName(stat), cudaGetErrorString(stat)) + .c_str()); } } // namespace gmx diff --git a/src/gromacs/gpu_utils/pinning.h b/src/gromacs/gpu_utils/pinning.h index 870b7f85ce..c53e8e8c3d 100644 --- a/src/gromacs/gpu_utils/pinning.h +++ b/src/gromacs/gpu_utils/pinning.h @@ -53,7 +53,7 @@ namespace gmx * * Does not throw. */ -CUDA_FUNC_QUALIFIER void pinBuffer(void *CUDA_FUNC_ARGUMENT(pointer), +CUDA_FUNC_QUALIFIER void pinBuffer(void* CUDA_FUNC_ARGUMENT(pointer), std::size_t CUDA_FUNC_ARGUMENT(numBytes)) noexcept CUDA_FUNC_TERM; /*! \brief Unpin the allocation. @@ -63,6 +63,6 @@ CUDA_FUNC_QUALIFIER void pinBuffer(void *CUDA_FUNC_ARGUMENT(pointer), * * Does not throw. */ -CUDA_FUNC_QUALIFIER void unpinBuffer(void *CUDA_FUNC_ARGUMENT(pointer)) noexcept CUDA_FUNC_TERM; +CUDA_FUNC_QUALIFIER void unpinBuffer(void* CUDA_FUNC_ARGUMENT(pointer)) noexcept CUDA_FUNC_TERM; } // namespace gmx diff --git a/src/gromacs/gpu_utils/pmalloc_cuda.cu b/src/gromacs/gpu_utils/pmalloc_cuda.cu index 228661f9d8..0a88abb268 100644 --- a/src/gromacs/gpu_utils/pmalloc_cuda.cu +++ b/src/gromacs/gpu_utils/pmalloc_cuda.cu @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,7 @@ * This memory should always be freed using pfree (or with the page-locked * free functions provied by the CUDA library). */ -void pmalloc(void **h_ptr, size_t nbytes) +void pmalloc(void** h_ptr, size_t nbytes) { cudaError_t stat; char strbuf[STRLEN]; @@ -74,7 +74,7 @@ void pmalloc(void **h_ptr, size_t nbytes) * This memory should always be freed using pfree (or with the page-locked * free functions provied by the CUDA library). */ -void pmalloc_wc(void **h_ptr, size_t nbytes) +void pmalloc_wc(void** h_ptr, size_t nbytes) { cudaError_t stat; char strbuf[STRLEN]; @@ -97,7 +97,7 @@ void pmalloc_wc(void **h_ptr, size_t nbytes) * This function can safely be called also with a pointer to a page-locked * memory allocated directly with CUDA API calls. */ -void pfree(void *h_ptr) +void pfree(void* h_ptr) { cudaError_t stat; diff --git a/src/gromacs/gpu_utils/pmalloc_cuda.h b/src/gromacs/gpu_utils/pmalloc_cuda.h index 9297fb9ddc..2f2d8827df 100644 --- a/src/gromacs/gpu_utils/pmalloc_cuda.h +++ b/src/gromacs/gpu_utils/pmalloc_cuda.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,13 +48,13 @@ ///@cond INTERNAL /*! \brief Allocates nbytes of page-locked memory. */ -void pmalloc(void **h_ptr, size_t nbytes); +void pmalloc(void** h_ptr, size_t nbytes); /*! \brief Allocates nbytes of page-locked memory with write-combining. */ -void pmalloc_wc(void **h_ptr, size_t nbytes); +void pmalloc_wc(void** h_ptr, size_t nbytes); /*! \brief Frees page locked memory allocated with pmalloc. */ -void pfree(void *h_ptr); +void pfree(void* h_ptr); ///@endcond diff --git a/src/gromacs/gpu_utils/tests/devicetransfers.cpp b/src/gromacs/gpu_utils/tests/devicetransfers.cpp index 733cac2245..5ea7aadbaa 100644 --- a/src/gromacs/gpu_utils/tests/devicetransfers.cpp +++ b/src/gromacs/gpu_utils/tests/devicetransfers.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,9 +49,7 @@ namespace gmx { -void doDeviceTransfers(const gmx_gpu_info_t & /*gpuInfo*/, - ArrayRef input, - ArrayRef output) +void doDeviceTransfers(const gmx_gpu_info_t& /*gpuInfo*/, ArrayRef input, ArrayRef output) { GMX_RELEASE_ASSERT(input.size() == output.size(), "Input and output must have matching size"); // We can't have any valid GPUs for this build configuration. diff --git a/src/gromacs/gpu_utils/tests/devicetransfers.cu b/src/gromacs/gpu_utils/tests/devicetransfers.cu index 88a497c19e..e3a56be9c3 100644 --- a/src/gromacs/gpu_utils/tests/devicetransfers.cu +++ b/src/gromacs/gpu_utils/tests/devicetransfers.cu @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,19 +65,18 @@ namespace * * \throws InternalError If status indicates failure, supplying * descriptive text from \c message. */ -static void throwUponFailure(cudaError_t status, const char *message) +static void throwUponFailure(cudaError_t status, const char* message) { if (status != cudaSuccess) { - GMX_THROW(InternalError(formatString("Failure while %s", message)));; + GMX_THROW(InternalError(formatString("Failure while %s", message))); + ; } } -} // namespace +} // namespace -void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, - ArrayRef input, - ArrayRef output) +void doDeviceTransfers(const gmx_gpu_info_t& gpuInfo, ArrayRef input, ArrayRef output) { GMX_RELEASE_ASSERT(input.size() == output.size(), "Input and output must have matching size"); const auto compatibleGpus = getCompatibleGpus(gpuInfo); @@ -88,7 +87,7 @@ void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, } cudaError_t status; - const auto *device = getDeviceInfo(gpuInfo, compatibleGpus[0]); + const auto* device = getDeviceInfo(gpuInfo, compatibleGpus[0]); int oldDeviceId; status = cudaGetDevice(&oldDeviceId); @@ -96,7 +95,7 @@ void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, status = cudaSetDevice(device->id); throwUponFailure(status, "setting device id to the first compatible GPU"); - void *devicePointer; + void* devicePointer; status = cudaMalloc(&devicePointer, input.size()); throwUponFailure(status, "creating buffer"); diff --git a/src/gromacs/gpu_utils/tests/devicetransfers.h b/src/gromacs/gpu_utils/tests/devicetransfers.h index 9ce7a42815..730f2a1ec6 100644 --- a/src/gromacs/gpu_utils/tests/devicetransfers.h +++ b/src/gromacs/gpu_utils/tests/devicetransfers.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,9 +65,7 @@ namespace gmx * do a simple host-side buffer copy instead. * * \throws InternalError Upon any GPU API error condition. */ -void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, - ArrayRef input, - ArrayRef output); +void doDeviceTransfers(const gmx_gpu_info_t& gpuInfo, ArrayRef input, ArrayRef output); } // namespace gmx diff --git a/src/gromacs/gpu_utils/tests/devicetransfers_ocl.cpp b/src/gromacs/gpu_utils/tests/devicetransfers_ocl.cpp index 8cb3e99aac..ed38085954 100644 --- a/src/gromacs/gpu_utils/tests/devicetransfers_ocl.cpp +++ b/src/gromacs/gpu_utils/tests/devicetransfers_ocl.cpp @@ -60,19 +60,18 @@ namespace * * \throws InternalError If status indicates failure, supplying * descriptive text from \c message. */ -void throwUponFailure(cl_int status, const char *message) +void throwUponFailure(cl_int status, const char* message) { if (status != CL_SUCCESS) { - GMX_THROW(InternalError(formatString("Failure while %s, error was %s", message, ocl_get_error_string(status).c_str()))); + GMX_THROW(InternalError(formatString("Failure while %s, error was %s", message, + ocl_get_error_string(status).c_str()))); } } -} // namespace +} // namespace -void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, - ArrayRef input, - ArrayRef output) +void doDeviceTransfers(const gmx_gpu_info_t& gpuInfo, ArrayRef input, ArrayRef output) { GMX_RELEASE_ASSERT(input.size() == output.size(), "Input and output must have matching size"); const auto compatibleGpus = getCompatibleGpus(gpuInfo); @@ -81,13 +80,11 @@ void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, std::copy(input.begin(), input.end(), output.begin()); return; } - cl_int status; + cl_int status; - const auto *device = getDeviceInfo(gpuInfo, compatibleGpus[0]); + const auto* device = getDeviceInfo(gpuInfo, compatibleGpus[0]); cl_context_properties properties[] = { - CL_CONTEXT_PLATFORM, - reinterpret_cast(device->ocl_gpu_id.ocl_platform_id), - 0 + CL_CONTEXT_PLATFORM, reinterpret_cast(device->ocl_gpu_id.ocl_platform_id), 0 }; // Give uncrustify more space @@ -100,9 +97,11 @@ void doDeviceTransfers(const gmx_gpu_info_t &gpuInfo, auto devicePointer = clCreateBuffer(context, CL_MEM_READ_WRITE, input.size(), nullptr, &status); throwUponFailure(status, "creating buffer"); - status = clEnqueueWriteBuffer(commandQueue, devicePointer, CL_TRUE, 0, input.size(), input.data(), 0, nullptr, nullptr); + status = clEnqueueWriteBuffer(commandQueue, devicePointer, CL_TRUE, 0, input.size(), + input.data(), 0, nullptr, nullptr); throwUponFailure(status, "transferring host to device"); - status = clEnqueueReadBuffer(commandQueue, devicePointer, CL_TRUE, 0, output.size(), output.data(), 0, nullptr, nullptr); + status = clEnqueueReadBuffer(commandQueue, devicePointer, CL_TRUE, 0, output.size(), + output.data(), 0, nullptr, nullptr); throwUponFailure(status, "transferring device to host"); status = clReleaseMemObject(devicePointer); diff --git a/src/gromacs/gpu_utils/tests/gputest.cpp b/src/gromacs/gpu_utils/tests/gputest.cpp index 13044a5d72..2012d97da3 100644 --- a/src/gromacs/gpu_utils/tests/gputest.cpp +++ b/src/gromacs/gpu_utils/tests/gputest.cpp @@ -74,5 +74,5 @@ bool GpuTest::haveValidGpus() const return gpuInfo_->n_dev_compatible > 0; } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/gpu_utils/tests/gputest.h b/src/gromacs/gpu_utils/tests/gputest.h index 603ef7b0ce..788725170f 100644 --- a/src/gromacs/gpu_utils/tests/gputest.h +++ b/src/gromacs/gpu_utils/tests/gputest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,17 +54,17 @@ namespace test class GpuTest : public ::testing::Test { - public: - //! Information about GPUs that are present. - gmx_gpu_info_t *gpuInfo_; +public: + //! Information about GPUs that are present. + gmx_gpu_info_t* gpuInfo_; - GpuTest(); - ~GpuTest() override; - //! Getter for convenience in testing - bool haveValidGpus() const; + GpuTest(); + ~GpuTest() override; + //! Getter for convenience in testing + bool haveValidGpus() const; }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/gromacs/gpu_utils/tests/hostallocator.cpp b/src/gromacs/gpu_utils/tests/hostallocator.cpp index 301e0940c0..8a90b7e710 100644 --- a/src/gromacs/gpu_utils/tests/hostallocator.cpp +++ b/src/gromacs/gpu_utils/tests/hostallocator.cpp @@ -67,12 +67,12 @@ namespace test /*! \internal \brief Typed test fixture for infrastructure for * host-side memory used for GPU transfers. */ -template +template class HostMemoryTest : public test::GpuTest { - public: - //! Convenience type - using ValueType = T; +public: + //! Convenience type + using ValueType = T; }; /*! \brief Convenience function to transform a view into one with base @@ -86,19 +86,18 @@ class HostMemoryTest : public test::GpuTest * \param[in] size The size of the data pointer (in T). * \tparam T The base type of the container * */ -template -ArrayRef charArrayRefFromArray(T *data, size_t size) +template +ArrayRef charArrayRefFromArray(T* data, size_t size) { // Make a type like T, but without its possible const qualifier. using NonConstT = std::remove_const_t; - return arrayRefFromArray(reinterpret_cast(const_cast(data)), size * sizeof(T)); + return arrayRefFromArray(reinterpret_cast(const_cast(data)), + size * sizeof(T)); } //! Does a device transfer of \c input to the device in \c gpuInfo, and back to \c output. -template -void runTest(const gmx_gpu_info_t &gpuInfo, - ArrayRef input, - ArrayRef output) +template +void runTest(const gmx_gpu_info_t& gpuInfo, ArrayRef input, ArrayRef output) { // Convert the views of input and output to flat non-const chars, // so that there's no templating when we call doDeviceTransfers. @@ -110,18 +109,19 @@ void runTest(const gmx_gpu_info_t &gpuInfo, compareViews(input, output); } -struct MoveOnly { +struct MoveOnly +{ MoveOnly(real x = 0) : x(x) {} - MoveOnly(const MoveOnly &) = delete; - MoveOnly(MoveOnly &&) = default; - MoveOnly &operator=(const MoveOnly &) = delete; - MoveOnly &operator=(MoveOnly &&) = default; - bool operator==(const MoveOnly &o) const { return x == o.x; } - real operator*=(int scaleFactor) { return x *= scaleFactor; } - real x; + MoveOnly(const MoveOnly&) = delete; + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(const MoveOnly&) = delete; + MoveOnly& operator=(MoveOnly&&) = default; + bool operator==(const MoveOnly& o) const { return x == o.x; } + real operator*=(int scaleFactor) { return x *= scaleFactor; } + real x; }; -} // namespace test +} // namespace test namespace detail { @@ -129,11 +129,11 @@ namespace detail template<> struct PaddingTraits { - using SimdBaseType = real; + using SimdBaseType = real; static constexpr int maxSimdWidthOfBaseType = GMX_REAL_MAX_SIMD_WIDTH; }; -} // namespace detail +} // namespace detail namespace test { @@ -142,7 +142,7 @@ namespace test typedef ::testing::Types TestTypes; //! Typed test fixture -template +template struct HostAllocatorTest : HostMemoryTest { using VectorType = PaddedHostVector; //!< PaddedHostVector of type tested @@ -150,7 +150,7 @@ struct HostAllocatorTest : HostMemoryTest TYPED_TEST_CASE(HostAllocatorTest, TestTypes); //! Typed test fixture (no mem/gpu initializtion - much faster) -template +template struct HostAllocatorTestNoMem : ::testing::Test { using VectorType = PaddedHostVector; //!< PaddedHostVector of type tested @@ -158,15 +158,17 @@ struct HostAllocatorTestNoMem : ::testing::Test TYPED_TEST_CASE(HostAllocatorTestNoMem, TestTypes); //! Typed test fixture for tests requiring a copyable type -template -struct HostAllocatorTestNoMemCopyable : HostAllocatorTestNoMem {}; +template +struct HostAllocatorTestNoMemCopyable : HostAllocatorTestNoMem +{ +}; //! The types used in testing minus move only types using TestTypesCopyable = ::testing::Types; TYPED_TEST_CASE(HostAllocatorTestNoMemCopyable, TestTypesCopyable); //! Typed test fixture for tests requiring a copyable type -template +template using HostAllocatorTestCopyable = HostAllocatorTest; TYPED_TEST_CASE(HostAllocatorTestCopyable, TestTypesCopyable); @@ -215,19 +217,19 @@ TYPED_TEST(HostAllocatorTestNoMem, CreateVector) { typename TestFixture::VectorType input1; EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported}); - EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + typename TestFixture::VectorType input2({ PinningPolicy::PinnedIfSupported }); + EXPECT_TRUE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } TYPED_TEST(HostAllocatorTestNoMem, MoveAssignment) { - typename TestFixture::VectorType input1({PinningPolicy::PinnedIfSupported}); + typename TestFixture::VectorType input1({ PinningPolicy::PinnedIfSupported }); input1 = typename TestFixture::VectorType(); EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); typename TestFixture::VectorType input2; - input2 = typename TestFixture::VectorType({PinningPolicy::PinnedIfSupported}); - EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + input2 = typename TestFixture::VectorType({ PinningPolicy::PinnedIfSupported }); + EXPECT_TRUE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } TYPED_TEST(HostAllocatorTestNoMem, MoveConstruction) @@ -236,7 +238,7 @@ TYPED_TEST(HostAllocatorTestNoMem, MoveConstruction) typename TestFixture::VectorType input2(std::move(input1)); EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - typename TestFixture::VectorType input3({PinningPolicy::PinnedIfSupported}); + typename TestFixture::VectorType input3({ PinningPolicy::PinnedIfSupported }); typename TestFixture::VectorType input4(std::move(input3)); EXPECT_TRUE(input4.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } @@ -244,13 +246,13 @@ TYPED_TEST(HostAllocatorTestNoMem, MoveConstruction) TYPED_TEST(HostAllocatorTestNoMemCopyable, CopyAssignment) { typename TestFixture::VectorType input1; - typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported}); + typename TestFixture::VectorType input2({ PinningPolicy::PinnedIfSupported }); input1 = input2; EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + EXPECT_TRUE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); input2 = input1; EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + EXPECT_TRUE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } TYPED_TEST(HostAllocatorTestNoMemCopyable, CopyConstruction) @@ -259,7 +261,7 @@ TYPED_TEST(HostAllocatorTestNoMemCopyable, CopyConstruction) typename TestFixture::VectorType input2(input1); //NOLINT(performance-unnecessary-copy-initialization) EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - typename TestFixture::VectorType input3({PinningPolicy::PinnedIfSupported}); + typename TestFixture::VectorType input3({ PinningPolicy::PinnedIfSupported }); typename TestFixture::VectorType input4(input3); //NOLINT(performance-unnecessary-copy-initialization) EXPECT_FALSE(input4.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } @@ -267,21 +269,21 @@ TYPED_TEST(HostAllocatorTestNoMemCopyable, CopyConstruction) TYPED_TEST(HostAllocatorTestNoMem, Swap) { typename TestFixture::VectorType input1; - typename TestFixture::VectorType input2({PinningPolicy::PinnedIfSupported}); + typename TestFixture::VectorType input2({ PinningPolicy::PinnedIfSupported }); std::swap(input1, input2); - EXPECT_TRUE (input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + EXPECT_TRUE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); EXPECT_FALSE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); std::swap(input2, input1); EXPECT_FALSE(input1.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); - EXPECT_TRUE (input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); + EXPECT_TRUE(input2.get_allocator().pinningPolicy() == PinningPolicy::PinnedIfSupported); } TYPED_TEST(HostAllocatorTestNoMem, Comparison) { using AllocatorType = typename TestFixture::VectorType::allocator_type; - EXPECT_EQ(AllocatorType {}, AllocatorType {}); - //Should be false for different pinning policy - EXPECT_NE(AllocatorType {}, AllocatorType {PinningPolicy::PinnedIfSupported}); + EXPECT_EQ(AllocatorType{}, AllocatorType{}); + // Should be false for different pinning policy + EXPECT_NE(AllocatorType{}, AllocatorType{ PinningPolicy::PinnedIfSupported }); } #if GMX_GPU == GMX_GPU_CUDA @@ -306,10 +308,10 @@ TYPED_TEST(HostAllocatorTestCopyable, TransfersWithPinningWorkWithCuda) } //! Helper function for wrapping a call to isHostMemoryPinned. -template -bool isPinned(const VectorType &v) +template +bool isPinned(const VectorType& v) { - void *data = const_cast(static_cast(v.data())); + void* data = const_cast(static_cast(v.data())); return isHostMemoryPinned(data); } @@ -364,16 +366,13 @@ TYPED_TEST(HostAllocatorTest, StatefulAllocatorUsesMemory) TEST(HostAllocatorUntypedTest, Comparison) { - //Should always be true for the same policy, indpendent of value_type + // Should always be true for the same policy, indpendent of value_type EXPECT_EQ(HostAllocator{}, HostAllocator{}); } //! Declare allocator types to test. -using AllocatorTypesToTest = ::testing::Types, - HostAllocator, - HostAllocator, - HostAllocator - >; +using AllocatorTypesToTest = + ::testing::Types, HostAllocator, HostAllocator, HostAllocator>; TYPED_TEST_CASE(AllocatorTest, AllocatorTypesToTest); diff --git a/src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp b/src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp index 16beb2b85e..840aa1edb2 100644 --- a/src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp +++ b/src/gromacs/gpu_utils/tests/pinnedmemorychecker.cpp @@ -106,7 +106,7 @@ TEST_F(PinnedMemoryCheckerTest, DefaultCBufferIsRecognized) return; } - real *dummy; + real* dummy; snew(dummy, 3); EXPECT_FALSE(isHostMemoryPinned(dummy)); sfree(dummy); @@ -119,8 +119,8 @@ TEST_F(PinnedMemoryCheckerTest, PinnedCBufferIsRecognized) return; } - real *dummy = nullptr; - pmalloc(reinterpret_cast(&dummy), 3 * sizeof(real)); + real* dummy = nullptr; + pmalloc(reinterpret_cast(&dummy), 3 * sizeof(real)); EXPECT_TRUE(isHostMemoryPinned(dummy)); pfree(dummy); } diff --git a/src/gromacs/gpu_utils/vectype_ops.clh b/src/gromacs/gpu_utils/vectype_ops.clh index 3f81392afa..b19cee142a 100644 --- a/src/gromacs/gpu_utils/vectype_ops.clh +++ b/src/gromacs/gpu_utils/vectype_ops.clh @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,7 +35,7 @@ #include "device_utils.clh" #ifndef VECTYPE_OPS_CLH -#define VECTYPE_OPS_CLH +# define VECTYPE_OPS_CLH /**** float3 ****/ diff --git a/src/gromacs/gpu_utils/vectype_ops.cuh b/src/gromacs/gpu_utils/vectype_ops.cuh index 7864ead5b1..f4e6d6af39 100644 --- a/src/gromacs/gpu_utils/vectype_ops.cuh +++ b/src/gromacs/gpu_utils/vectype_ops.cuh @@ -45,7 +45,7 @@ __forceinline__ __host__ __device__ float3 make_float3(float4 a) { return make_float3(a.x, a.y, a.z); } -__forceinline__ __host__ __device__ float3 operator-(float3 &a) +__forceinline__ __host__ __device__ float3 operator-(float3& a) { return make_float3(-a.x, -a.y, -a.z); } @@ -65,17 +65,23 @@ __forceinline__ __host__ __device__ float3 operator*(float k, float3 a) { return make_float3(k * a.x, k * a.y, k * a.z); } -__forceinline__ __host__ __device__ void operator += (float3 &a, float3 b) +__forceinline__ __host__ __device__ void operator+=(float3& a, float3 b) { - a.x += b.x; a.y += b.y; a.z += b.z; + a.x += b.x; + a.y += b.y; + a.z += b.z; } -__forceinline__ __host__ __device__ void operator += (float3 &a, float4 b) +__forceinline__ __host__ __device__ void operator+=(float3& a, float4 b) { - a.x += b.x; a.y += b.y; a.z += b.z; + a.x += b.x; + a.y += b.y; + a.z += b.z; } -__forceinline__ __host__ __device__ void operator -= (float3 &a, float3 b) +__forceinline__ __host__ __device__ void operator-=(float3& a, float3 b) { - a.x -= b.x; a.y -= b.y; a.z -= b.z; + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; } __forceinline__ __host__ __device__ float norm(float3 a) { @@ -93,15 +99,19 @@ __forceinline__ __host__ __device__ float3 operator*(float3 a, float3 b) { return make_float3(a.x * b.x, a.y * b.y, a.z * b.z); } -__forceinline__ __host__ __device__ void operator *= (float3 &a, float3 b) +__forceinline__ __host__ __device__ void operator*=(float3& a, float3 b) { - a.x *= b.x; a.y *= b.y; a.z *= b.z; + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; } -__forceinline__ __host__ __device__ void operator *= (float3 &a, float b) +__forceinline__ __host__ __device__ void operator*=(float3& a, float b) { - a.x *= b; a.y *= b; a.z *= b; + a.x *= b; + a.y *= b; + a.z *= b; } -__forceinline__ __device__ void atomicAdd(float3 *addr, float3 val) +__forceinline__ __device__ void atomicAdd(float3* addr, float3 val) { atomicAdd(&addr->x, val.x); atomicAdd(&addr->y, val.y); @@ -134,17 +144,24 @@ __forceinline__ __host__ __device__ float4 operator*(float4 a, float k) { return make_float4(k * a.x, k * a.y, k * a.z, k * a.w); } -__forceinline__ __host__ __device__ void operator += (float4 &a, float4 b) +__forceinline__ __host__ __device__ void operator+=(float4& a, float4 b) { - a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; } -__forceinline__ __host__ __device__ void operator += (float4 &a, float3 b) +__forceinline__ __host__ __device__ void operator+=(float4& a, float3 b) { - a.x += b.x; a.y += b.y; a.z += b.z; + a.x += b.x; + a.y += b.y; + a.z += b.z; } -__forceinline__ __host__ __device__ void operator -= (float4 &a, float3 b) +__forceinline__ __host__ __device__ void operator-=(float4& a, float3 b) { - a.x -= b.x; a.y -= b.y; a.z -= b.z; + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; } __forceinline__ __host__ __device__ float norm(float4 a) diff --git a/src/gromacs/hardware/architecture.h b/src/gromacs/hardware/architecture.h index 34d5b082a1..4a82221d38 100644 --- a/src/gromacs/hardware/architecture.h +++ b/src/gromacs/hardware/architecture.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,31 +54,32 @@ enum class Architecture }; //! Whether the compilation is targeting 32-bit x86. -# if (defined __i386__ || defined __i386 || defined _X86_ || defined _M_IX86) -#define GMX_IS_X86_32 1 +#if (defined __i386__ || defined __i386 || defined _X86_ || defined _M_IX86) +# define GMX_IS_X86_32 1 #else -#define GMX_IS_X86_32 0 +# define GMX_IS_X86_32 0 #endif //! Whether the compilation is targeting 64-bit x86. -#if (defined __x86_64__ || defined __x86_64 || defined __amd64__ || defined __amd64 || defined _M_X64 || defined _M_AMD64) -#define GMX_IS_X86_64 1 +#if (defined __x86_64__ || defined __x86_64 || defined __amd64__ || defined __amd64 \ + || defined _M_X64 || defined _M_AMD64) +# define GMX_IS_X86_64 1 #else -#define GMX_IS_X86_64 0 +# define GMX_IS_X86_64 0 #endif //! Constant that tells what the architecture is static constexpr Architecture c_architecture = #if GMX_IS_X86_32 || GMX_IS_X86_64 - Architecture::X86; + Architecture::X86; #elif defined __arm__ || defined __arm || defined _M_ARM || defined __aarch64__ - Architecture::Arm; + Architecture::Arm; #elif defined __powerpc__ || defined __ppc__ || defined __PPC__ - Architecture::PowerPC; + Architecture::PowerPC; #else - Architecture::Unknown; + Architecture::Unknown; #endif -} // namespace gmx +} // namespace gmx #endif // GMX_ARCHITECTURE_H diff --git a/src/gromacs/hardware/cpuinfo.cpp b/src/gromacs/hardware/cpuinfo.cpp index 037204b15e..2004d8fcb1 100644 --- a/src/gromacs/hardware/cpuinfo.cpp +++ b/src/gromacs/hardware/cpuinfo.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2012-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,14 +74,14 @@ #endif #if GMX_NATIVE_WINDOWS -# include // sysinfo(), necessary for topology stuff +# include // sysinfo(), necessary for topology stuff #endif #ifdef HAVE_SCHED_H -# include // sched_getaffinity(), sched_setaffinity() +# include // sched_getaffinity(), sched_setaffinity() #endif #ifdef HAVE_UNISTD_H -# include // sysconf() +# include // sysconf() #endif #include @@ -119,13 +120,16 @@ namespace * * \param s Pointer to string where whitespace will be removed */ -void -trimString(std::string * s) +void trimString(std::string* s) { // heading - s->erase(s->begin(), std::find_if(s->begin(), s->end(), [](char &c) -> bool { return std::isspace(c) == 0; })); + s->erase(s->begin(), + std::find_if(s->begin(), s->end(), [](char& c) -> bool { return std::isspace(c) == 0; })); // trailing - s->erase(std::find_if(s->rbegin(), s->rend(), [](char &c) -> bool { return std::isspace(c) == 0; }).base(), s->end()); + s->erase( + std::find_if(s->rbegin(), s->rend(), [](char& c) -> bool { return std::isspace(c) == 0; }) + .base(), + s->end()); } @@ -146,13 +150,12 @@ trimString(std::string * s) * * \return 0 on success, or non-zero if the instruction could not execute. */ -int -executeX86CpuID(unsigned int gmx_unused level, - unsigned int gmx_unused ecxval, - unsigned int * eax, - unsigned int * ebx, - unsigned int * ecx, - unsigned int * edx) +int executeX86CpuID(unsigned int gmx_unused level, + unsigned int gmx_unused ecxval, + unsigned int* eax, + unsigned int* ebx, + unsigned int* ecx, + unsigned int* edx) { if (c_architecture == Architecture::X86) { @@ -166,14 +169,15 @@ executeX86CpuID(unsigned int gmx_unused level, # if GMX_IS_X86_32 && defined(__PIC__) // Avoid clobbering the global offset table in 32-bit pic code (ebx register) - __asm__ __volatile__ ("xchgl %%ebx, %1 \n\t" - "cpuid \n\t" - "xchgl %%ebx, %1 \n\t" - : "+a" (*eax), "+r" (*ebx), "+c" (*ecx), "+d" (*edx)); + __asm__ __volatile__( + "xchgl %%ebx, %1 \n\t" + "cpuid \n\t" + "xchgl %%ebx, %1 \n\t" + : "+a"(*eax), "+r"(*ebx), "+c"(*ecx), "+d"(*edx)); # elif GMX_IS_X86_64 // i386 without PIC, or x86-64. Things are easy and we can clobber any reg we want - __asm__ __volatile__ ("cpuid \n\t" - : "+a" (*eax), "+b" (*ebx), "+c" (*ecx), "+d" (*edx)); + __asm__ __volatile__("cpuid \n\t" + : "+a"(*eax), "+b"(*ebx), "+c"(*ecx), "+d"(*edx)); # else // Not a normal x86, which could happen when a compiler // targetting non-x86 pretends to be GCC. @@ -200,7 +204,7 @@ executeX86CpuID(unsigned int gmx_unused level, *edx = 0; return 1; -#endif // check for inline asm on x86 +#endif // check for inline asm on x86 } else { @@ -224,8 +228,7 @@ executeX86CpuID(unsigned int gmx_unused level, * Hygon can be identified, or if the code fails to execute, * gmx::CpuInfo::Vendor::Unknown is returned. */ -CpuInfo::Vendor -detectX86Vendor() +CpuInfo::Vendor detectX86Vendor() { unsigned int eax, ebx, ecx, edx; CpuInfo::Vendor v = CpuInfo::Vendor::Unknown; @@ -259,11 +262,10 @@ detectX86Vendor() * \note Nothing is done if the bit is not set. In particular, this will not * erase anything if the feature already exists in the set. */ -void -setFeatureFromBit(std::set * featureSet, - CpuInfo::Feature feature, - unsigned int registerValue, - unsigned char bit) +void setFeatureFromBit(std::set* featureSet, + CpuInfo::Feature feature, + unsigned int registerValue, + unsigned char bit) { if (registerValue & (1 << bit)) { @@ -279,12 +281,7 @@ setFeatureFromBit(std::set * featureSet, * \param[out] stepping Minor version of processor * \param[out] features Feature set where supported features are inserted */ -void -detectX86Features(std::string * brand, - int * family, - int * model, - int * stepping, - std::set * features) +void detectX86Features(std::string* brand, int* family, int* model, int* stepping, std::set* features) { unsigned int eax, ebx, ecx, edx; @@ -303,48 +300,48 @@ detectX86Features(std::string * brand, *model = ((eax & 0x000f0000) >> 12) + ((eax & 0x000000f0) >> 4); *stepping = (eax & 0x0000000f); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sse3, ecx, 0 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Pclmuldq, ecx, 1 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Ssse3, ecx, 9 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Fma, ecx, 12 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Cx16, ecx, 13 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Pdcm, ecx, 15 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Pcid, ecx, 17 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4_1, ecx, 19 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4_2, ecx, 20 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_X2Apic, ecx, 21 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Popcnt, ecx, 23 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Tdt, ecx, 24 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Aes, ecx, 25 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx, ecx, 28 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_F16C, ecx, 29 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Rdrnd, ecx, 30 ); - - setFeatureFromBit(features, CpuInfo::Feature::X86_Pse, edx, 3 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Msr, edx, 5 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Cx8, edx, 8 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Apic, edx, 9 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Cmov, edx, 15 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Clfsh, edx, 19 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Mmx, edx, 23 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sse2, edx, 26 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Htt, edx, 28 ); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sse3, ecx, 0); + setFeatureFromBit(features, CpuInfo::Feature::X86_Pclmuldq, ecx, 1); + setFeatureFromBit(features, CpuInfo::Feature::X86_Ssse3, ecx, 9); + setFeatureFromBit(features, CpuInfo::Feature::X86_Fma, ecx, 12); + setFeatureFromBit(features, CpuInfo::Feature::X86_Cx16, ecx, 13); + setFeatureFromBit(features, CpuInfo::Feature::X86_Pdcm, ecx, 15); + setFeatureFromBit(features, CpuInfo::Feature::X86_Pcid, ecx, 17); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4_1, ecx, 19); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4_2, ecx, 20); + setFeatureFromBit(features, CpuInfo::Feature::X86_X2Apic, ecx, 21); + setFeatureFromBit(features, CpuInfo::Feature::X86_Popcnt, ecx, 23); + setFeatureFromBit(features, CpuInfo::Feature::X86_Tdt, ecx, 24); + setFeatureFromBit(features, CpuInfo::Feature::X86_Aes, ecx, 25); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx, ecx, 28); + setFeatureFromBit(features, CpuInfo::Feature::X86_F16C, ecx, 29); + setFeatureFromBit(features, CpuInfo::Feature::X86_Rdrnd, ecx, 30); + + setFeatureFromBit(features, CpuInfo::Feature::X86_Pse, edx, 3); + setFeatureFromBit(features, CpuInfo::Feature::X86_Msr, edx, 5); + setFeatureFromBit(features, CpuInfo::Feature::X86_Cx8, edx, 8); + setFeatureFromBit(features, CpuInfo::Feature::X86_Apic, edx, 9); + setFeatureFromBit(features, CpuInfo::Feature::X86_Cmov, edx, 15); + setFeatureFromBit(features, CpuInfo::Feature::X86_Clfsh, edx, 19); + setFeatureFromBit(features, CpuInfo::Feature::X86_Mmx, edx, 23); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sse2, edx, 26); + setFeatureFromBit(features, CpuInfo::Feature::X86_Htt, edx, 28); } if (maxStdLevel >= 0x7) { executeX86CpuID(0x7, 0, &eax, &ebx, &ecx, &edx); - setFeatureFromBit(features, CpuInfo::Feature::X86_Hle, ebx, 4 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx2, ebx, 5 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Rtm, ebx, 11 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512F, ebx, 16 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512PF, ebx, 26 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512ER, ebx, 27 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512CD, ebx, 28 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sha, ebx, 29 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512BW, ebx, 30 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512VL, ebx, 31 ); + setFeatureFromBit(features, CpuInfo::Feature::X86_Hle, ebx, 4); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx2, ebx, 5); + setFeatureFromBit(features, CpuInfo::Feature::X86_Rtm, ebx, 11); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512F, ebx, 16); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512PF, ebx, 26); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512ER, ebx, 27); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512CD, ebx, 28); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sha, ebx, 29); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512BW, ebx, 30); + setFeatureFromBit(features, CpuInfo::Feature::X86_Avx512VL, ebx, 31); } // Check whether Hyper-threading is really possible to enable in the hardware, @@ -352,10 +349,10 @@ detectX86Features(std::string * brand, if ((features->count(CpuInfo::Feature::X86_Htt) != 0U) && maxStdLevel >= 0x4) { executeX86CpuID(0x1, 0, &eax, &ebx, &ecx, &edx); - unsigned int maxLogicalCores = (ebx >> 16) & 0x0ff; + unsigned int maxLogicalCores = (ebx >> 16) & 0x0ff; executeX86CpuID(0x4, 0, &eax, &ebx, &ecx, &edx); unsigned int maxPhysicalCores = ((eax >> 26) & 0x3f) + 1; - if (maxLogicalCores/maxPhysicalCores < 2) + if (maxLogicalCores / maxPhysicalCores < 2) { features->erase(CpuInfo::Feature::X86_Htt); } @@ -372,13 +369,13 @@ detectX86Features(std::string * brand, { executeX86CpuID(0x80000001, 0, &eax, &ebx, &ecx, &edx); - setFeatureFromBit(features, CpuInfo::Feature::X86_Lahf, ecx, 0 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4A, ecx, 6 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_MisalignSse, ecx, 7 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Xop, ecx, 11 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Fma4, ecx, 16 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_PDPE1GB, edx, 26 ); - setFeatureFromBit(features, CpuInfo::Feature::X86_Rdtscp, edx, 27 ); + setFeatureFromBit(features, CpuInfo::Feature::X86_Lahf, ecx, 0); + setFeatureFromBit(features, CpuInfo::Feature::X86_Sse4A, ecx, 6); + setFeatureFromBit(features, CpuInfo::Feature::X86_MisalignSse, ecx, 7); + setFeatureFromBit(features, CpuInfo::Feature::X86_Xop, ecx, 11); + setFeatureFromBit(features, CpuInfo::Feature::X86_Fma4, ecx, 16); + setFeatureFromBit(features, CpuInfo::Feature::X86_PDPE1GB, edx, 26); + setFeatureFromBit(features, CpuInfo::Feature::X86_Rdtscp, edx, 27); } if (maxExtLevel >= 0x80000005) @@ -389,10 +386,10 @@ detectX86Features(std::string * brand, { executeX86CpuID(level, 0, &eax, &ebx, &ecx, &edx); // Add eax, ebx, ecx, edx contents as 4 chars each to the brand string - brand->append(reinterpret_cast(&eax), sizeof(eax)); - brand->append(reinterpret_cast(&ebx), sizeof(ebx)); - brand->append(reinterpret_cast(&ecx), sizeof(ecx)); - brand->append(reinterpret_cast(&edx), sizeof(edx)); + brand->append(reinterpret_cast(&eax), sizeof(eax)); + brand->append(reinterpret_cast(&ebx), sizeof(ebx)); + brand->append(reinterpret_cast(&ecx), sizeof(ecx)); + brand->append(reinterpret_cast(&edx), sizeof(edx)); } trimString(brand); } @@ -401,7 +398,7 @@ detectX86Features(std::string * brand, { executeX86CpuID(0x80000007, 0, &eax, &ebx, &ecx, &edx); - setFeatureFromBit(features, CpuInfo::Feature::X86_NonstopTsc, edx, 8 ); + setFeatureFromBit(features, CpuInfo::Feature::X86_NonstopTsc, edx, 8); } } @@ -413,18 +410,17 @@ detectX86Features(std::string * brand, * \returns A new std::vector of unsigned integer APIC IDs, one for each * logical processor in the system. */ -std::vector -detectX86ApicIDs(bool gmx_unused haveX2Apic) +std::vector detectX86ApicIDs(bool gmx_unused haveX2Apic) { - std::vector apicID; + std::vector apicID; // We cannot just ask for all APIC IDs, but must force execution on each // hardware thread and extract the APIC id there. #if HAVE_SCHED_AFFINITY && defined HAVE_SYSCONF - unsigned int eax, ebx, ecx, edx; - unsigned int nApic = sysconf(_SC_NPROCESSORS_ONLN); - cpu_set_t saveCpuSet; - cpu_set_t cpuSet; + unsigned int eax, ebx, ecx, edx; + unsigned int nApic = sysconf(_SC_NPROCESSORS_ONLN); + cpu_set_t saveCpuSet; + cpu_set_t cpuSet; sched_getaffinity(0, sizeof(cpu_set_t), &saveCpuSet); CPU_ZERO(&cpuSet); for (unsigned int i = 0; i < nApic; i++) @@ -445,14 +441,14 @@ detectX86ApicIDs(bool gmx_unused haveX2Apic) } sched_setaffinity(0, sizeof(cpu_set_t), &saveCpuSet); #elif GMX_NATIVE_WINDOWS - unsigned int eax, ebx, ecx, edx; - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - unsigned int nApic = sysinfo.dwNumberOfProcessors; - unsigned int saveAffinity = SetThreadAffinityMask(GetCurrentThread(), 1); + unsigned int eax, ebx, ecx, edx; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + unsigned int nApic = sysinfo.dwNumberOfProcessors; + unsigned int saveAffinity = SetThreadAffinityMask(GetCurrentThread(), 1); for (DWORD_PTR i = 0; i < nApic; i++) { - SetThreadAffinityMask(GetCurrentThread(), (((DWORD_PTR)1)< * v) +void renumberIndex(std::vector* v) { - std::vector sortedV (*v); + std::vector sortedV(*v); std::sort(sortedV.begin(), sortedV.end()); - std::vector uniqueSortedV (sortedV); + std::vector uniqueSortedV(sortedV); auto it = std::unique(uniqueSortedV.begin(), uniqueSortedV.end()); - uniqueSortedV.resize( std::distance(uniqueSortedV.begin(), it) ); + uniqueSortedV.resize(std::distance(uniqueSortedV.begin(), it)); for (std::size_t i = 0; i < uniqueSortedV.size(); i++) { unsigned int val = uniqueSortedV[i]; - std::replace_if(v->begin(), v->end(), [val](unsigned int &c) -> bool { return c == val; }, static_cast(i)); + std::replace_if(v->begin(), v->end(), [val](unsigned int& c) -> bool { return c == val; }, + static_cast(i)); } } @@ -506,19 +502,18 @@ struct ApicIdLayout /*! \brief Detect the APIC ID layout for x2APIC */ -ApicIdLayout -detectX2ApicIdLayout() +ApicIdLayout detectX2ApicIdLayout() { - ApicIdLayout layout; + ApicIdLayout layout; - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; executeX86CpuID(0xb, 0, &eax, &ebx, &ecx, &edx); layout.hwThreadBits = eax & 0x1f; executeX86CpuID(0xb, 1, &eax, &ebx, &ecx, &edx); - layout.coreBits = (eax & 0x1f) - layout.hwThreadBits; + layout.coreBits = (eax & 0x1f) - layout.hwThreadBits; return layout; } @@ -527,8 +522,7 @@ detectX2ApicIdLayout() * * \param[in] maxExtLevel The largest CPUID extended function input value supported by the processor implementation */ -ApicIdLayout -detectAmdApicIdLayout(unsigned int maxExtLevel) +ApicIdLayout detectAmdApicIdLayout(unsigned int maxExtLevel) { ApicIdLayout layout; @@ -537,15 +531,13 @@ detectAmdApicIdLayout(unsigned int maxExtLevel) unsigned int ecx; unsigned int edx; executeX86CpuID(0x1, 0, &eax, &ebx, &ecx, &edx); - int family = ((eax & 0x0ff00000) >> 20) + ((eax & 0x00000f00) >> 8); + int family = ((eax & 0x0ff00000) >> 20) + ((eax & 0x00000f00) >> 8); executeX86CpuID(0x80000001, 0, &eax, &ebx, &ecx, &edx); - bool haveExtendedTopology = (ecx & (1 << 22)) != 0U; + bool haveExtendedTopology = (ecx & (1 << 22)) != 0U; // NOTE: Here we assume 1 thread per core, unless we have family >= 17h layout.hwThreadBits = 0; - if (family >= 0x17 && - haveExtendedTopology && - maxExtLevel >= 0x8000001e) + if (family >= 0x17 && haveExtendedTopology && maxExtLevel >= 0x8000001e) { executeX86CpuID(0x8000001e, 1, &eax, &ebx, &ecx, &edx); int numThreadsPerCore = ((ebx >> 8) & 0xff) + 1; @@ -581,17 +573,16 @@ detectAmdApicIdLayout(unsigned int maxExtLevel) * \return A new vector of entries with socket, core, hwthread information * for each logical processor. */ -std::vector -detectX86LogicalProcessors() +std::vector detectX86LogicalProcessors() { - unsigned int eax; - unsigned int ebx; - unsigned int ecx; - unsigned int edx; - unsigned int maxStdLevel; - unsigned int maxExtLevel; - bool haveApic; - bool haveX2Apic; + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int maxStdLevel; + unsigned int maxExtLevel; + bool haveApic; + bool haveX2Apic; std::vector logicalProcessors; @@ -605,7 +596,7 @@ detectX86LogicalProcessors() { executeX86CpuID(0x1, 0, &eax, &ebx, &ecx, &edx); haveX2Apic = ((ecx & (1 << 21)) != 0U) && maxStdLevel >= 0xb; - haveApic = ((edx & (1 << 9)) != 0U) && maxExtLevel >= 0x80000008; + haveApic = ((edx & (1 << 9)) != 0U) && maxExtLevel >= 0x80000008; } else { @@ -621,10 +612,9 @@ detectX86LogicalProcessors() { layout = detectX2ApicIdLayout(); } - else // haveApic + else // haveApic { - if (detectX86Vendor() == CpuInfo::Vendor::Amd || - detectX86Vendor() == CpuInfo::Vendor::Hygon) + if (detectX86Vendor() == CpuInfo::Vendor::Amd || detectX86Vendor() == CpuInfo::Vendor::Hygon) { layout = detectAmdApicIdLayout(maxExtLevel); @@ -642,35 +632,36 @@ detectX86LogicalProcessors() } } - std::vector apicID = detectX86ApicIDs(haveX2Apic); + std::vector apicID = detectX86ApicIDs(haveX2Apic); if (!apicID.empty()) { // APIC IDs can be buggy, and it is always a mess. Typically more bits are // reserved than needed, and the numbers might not increment by 1 even in // a single socket or core. Extract, renumber, and check that things make sense. - unsigned int hwThreadMask = (1 << layout.hwThreadBits) - 1; - unsigned int coreMask = (1 << layout.coreBits) - 1; - std::vector hwThreadRanks; - std::vector coreRanks; - std::vector socketRanks; + unsigned int hwThreadMask = (1 << layout.hwThreadBits) - 1; + unsigned int coreMask = (1 << layout.coreBits) - 1; + std::vector hwThreadRanks; + std::vector coreRanks; + std::vector socketRanks; for (auto a : apicID) { - hwThreadRanks.push_back( static_cast( a & hwThreadMask ) ); - coreRanks.push_back( static_cast( ( a >> layout.hwThreadBits ) & coreMask ) ); - socketRanks.push_back( static_cast( a >> ( layout.coreBits + layout.hwThreadBits ) ) ); + hwThreadRanks.push_back(static_cast(a & hwThreadMask)); + coreRanks.push_back(static_cast((a >> layout.hwThreadBits) & coreMask)); + socketRanks.push_back(static_cast(a >> (layout.coreBits + layout.hwThreadBits))); } renumberIndex(&hwThreadRanks); renumberIndex(&coreRanks); renumberIndex(&socketRanks); - unsigned int hwThreadRankSize = 1 + *std::max_element(hwThreadRanks.begin(), hwThreadRanks.end()); - unsigned int coreRankSize = 1 + *std::max_element(coreRanks.begin(), coreRanks.end()); - unsigned int socketRankSize = 1 + *std::max_element(socketRanks.begin(), socketRanks.end()); + unsigned int hwThreadRankSize = + 1 + *std::max_element(hwThreadRanks.begin(), hwThreadRanks.end()); + unsigned int coreRankSize = 1 + *std::max_element(coreRanks.begin(), coreRanks.end()); + unsigned int socketRankSize = 1 + *std::max_element(socketRanks.begin(), socketRanks.end()); - if (socketRankSize * coreRankSize * hwThreadRankSize == apicID.size() ) + if (socketRankSize * coreRankSize * hwThreadRankSize == apicID.size()) { // Alright, everything looks consistent, so put it in the result for (std::size_t i = 0; i < apicID.size(); i++) @@ -678,7 +669,8 @@ detectX86LogicalProcessors() // While the internal APIC IDs are always unsigned integers, we also cast to // plain integers for the externally exposed vectors, since that will make // it possible to use '-1' for invalid entries in the future. - logicalProcessors.push_back( { int(socketRanks[i]), int(coreRanks[i]), int(hwThreadRanks[i]) } ); + logicalProcessors.push_back( + { int(socketRanks[i]), int(coreRanks[i]), int(hwThreadRanks[i]) }); } } } @@ -704,12 +696,11 @@ detectX86LogicalProcessors() * \return New map with the contents. If the file is not available, the returned * map will be empty. */ -std::map -parseProcCpuInfo() +std::map parseProcCpuInfo() { - std::ifstream procCpuInfo("/proc/cpuinfo"); - std::string line; - std::map cpuInfo; + std::ifstream procCpuInfo("/proc/cpuinfo"); + std::string line; + std::map cpuInfo; while (std::getline(procCpuInfo, line)) { @@ -718,8 +709,8 @@ parseProcCpuInfo() std::stringstream iss(line); std::string key; std::string val; - std::getline(iss, key, ':'); // part before colon - std::getline(iss, val); // part after colon + std::getline(iss, key, ':'); // part before colon + std::getline(iss, val); // part after colon trimString(&key); trimString(&val); // put it in the map. This will overwrite previous processors, but we don't care. @@ -738,42 +729,41 @@ parseProcCpuInfo() * they begin with the name of a standard vendor. If the file cannot be read * or if no match is found, we return gmx::CpuInfo::Vendor::Unknown. */ -CpuInfo::Vendor -detectProcCpuInfoVendor(const std::map &cpuInfo) +CpuInfo::Vendor detectProcCpuInfoVendor(const std::map& cpuInfo) { - const std::map testVendors = - { - { "GenuineIntel", CpuInfo::Vendor::Intel }, - { "Intel", CpuInfo::Vendor::Intel }, - { "AuthenticAmd", CpuInfo::Vendor::Amd }, - { "AMD", CpuInfo::Vendor::Amd }, - { "ARM", CpuInfo::Vendor::Arm }, - { "AArch64", CpuInfo::Vendor::Arm }, - { "Fujitsu", CpuInfo::Vendor::Fujitsu }, - { "IBM", CpuInfo::Vendor::Ibm }, - { "POWER", CpuInfo::Vendor::Ibm }, - { "Oracle", CpuInfo::Vendor::Oracle }, - { "HygonGenuine", CpuInfo::Vendor::Hygon }, - { "Hygon", CpuInfo::Vendor::Hygon }, + const std::map testVendors = { + { "GenuineIntel", CpuInfo::Vendor::Intel }, + { "Intel", CpuInfo::Vendor::Intel }, + { "AuthenticAmd", CpuInfo::Vendor::Amd }, + { "AMD", CpuInfo::Vendor::Amd }, + { "ARM", CpuInfo::Vendor::Arm }, + { "AArch64", CpuInfo::Vendor::Arm }, + { "Fujitsu", CpuInfo::Vendor::Fujitsu }, + { "IBM", CpuInfo::Vendor::Ibm }, + { "POWER", CpuInfo::Vendor::Ibm }, + { "Oracle", CpuInfo::Vendor::Oracle }, + { "HygonGenuine", CpuInfo::Vendor::Hygon }, + { "Hygon", CpuInfo::Vendor::Hygon }, }; // For each label in /proc/cpuinfo, compare the value to the name in the // testNames map above, and if it's a match return the vendor. - for (auto &l : { "vendor_id", "vendor", "manufacture", "model", "processor", "cpu" }) + for (auto& l : { "vendor_id", "vendor", "manufacture", "model", "processor", "cpu" }) { if (cpuInfo.count(l) != 0U) { // there was a line with this left-hand side in /proc/cpuinfo - const std::string &s1 = cpuInfo.at(l); + const std::string& s1 = cpuInfo.at(l); - for (auto &t : testVendors) + for (auto& t : testVendors) { - const std::string &s2 = t.first; + const std::string& s2 = t.first; // If the entire name we are testing (s2) matches the first part of // the string after the colon in /proc/cpuinfo (s1) we found our vendor - if (std::equal(s2.begin(), s2.end(), s1.begin(), - [](const char &x, const char &y) -> bool { return tolower(x) == tolower(y); })) + if (std::equal(s2.begin(), s2.end(), s1.begin(), [](const char& x, const char& y) -> bool { + return tolower(x) == tolower(y); + })) { return t.second; } @@ -793,10 +783,9 @@ detectProcCpuInfoVendor(const std::map &cpuInfo) * This routine tries to match a few common labels in /proc/cpuinfo to see if * we can find the processor name and features. It is likely fragile. */ -void -detectProcCpuInfoIbm(const std::map &cpuInfo, - std::string * brand, - std::set * features) +void detectProcCpuInfoIbm(const std::map& cpuInfo, + std::string* brand, + std::set* features) { // Get brand string from 'cpu' label if present, otherwise 'Processor' if (cpuInfo.count("cpu") != 0U) @@ -814,7 +803,7 @@ detectProcCpuInfoIbm(const std::map &cpuInfo, features->insert(CpuInfo::Feature::Ibm_Qpx); } - for (auto &l : { "model name", "model", "Processor", "cpu" }) + for (auto& l : { "model name", "model", "Processor", "cpu" }) { if (cpuInfo.count(l) != 0U) { @@ -847,13 +836,12 @@ detectProcCpuInfoIbm(const std::map &cpuInfo, * This routine tries to match a few common labels in /proc/cpuinfo to see if * we can find the processor name and features. It is likely fragile. */ -void -detectProcCpuInfoArm(const std::map &cpuInfo, - std::string * brand, - int * family, - int * model, - int * stepping, - std::set * features) +void detectProcCpuInfoArm(const std::map& cpuInfo, + std::string* brand, + int* family, + int* model, + int* stepping, + std::set* features) { if (cpuInfo.count("Processor") != 0U) { @@ -870,12 +858,12 @@ detectProcCpuInfoArm(const std::map &cpuInfo, // For some 64-bit CPUs it appears to say 'AArch64' instead if (*family == 0 && cpuInfo.at("CPU architecture").find("AArch64") != std::string::npos) { - *family = 8; // fragile - no idea how a future ARMv9 will be represented in this case + *family = 8; // fragile - no idea how a future ARMv9 will be represented in this case } } if (cpuInfo.count("CPU variant") != 0U) { - *model = std::strtol(cpuInfo.at("CPU variant").c_str(), nullptr, 16); + *model = std::strtol(cpuInfo.at("CPU variant").c_str(), nullptr, 16); } if (cpuInfo.count("CPU revision") != 0U) { @@ -884,7 +872,7 @@ detectProcCpuInfoArm(const std::map &cpuInfo, if (cpuInfo.count("Features") != 0U) { - const std::string &s = cpuInfo.at("Features"); + const std::string& s = cpuInfo.at("Features"); if (s.find("neon") != std::string::npos) { features->insert(CpuInfo::Feature::Arm_Neon); @@ -894,7 +882,7 @@ detectProcCpuInfoArm(const std::map &cpuInfo, // At least Jetson TX1 runs a 32-bit environment by default, although // the kernel is 64-bits, and reports asimd feature flags. We cannot // use Neon-asimd in this case, so make sure we are on a 64-bit platform. - if (sizeof(void *) == 8) + if (sizeof(void*) == 8) { features->insert(CpuInfo::Feature::Arm_NeonAsimd); } @@ -917,13 +905,12 @@ detectProcCpuInfoArm(const std::map &cpuInfo, * much more fragile than our x86 detection, but it does not depend on * specific system calls, intrinsics or assembly instructions. */ -void -detectProcCpuInfo(CpuInfo::Vendor * vendor, - std::string * brand, - int * family, - int * model, - int * stepping, - std::set * features) +void detectProcCpuInfo(CpuInfo::Vendor* vendor, + std::string* brand, + int* family, + int* model, + int* stepping, + std::set* features) { std::map cpuInfo = parseProcCpuInfo(); @@ -937,9 +924,7 @@ detectProcCpuInfo(CpuInfo::Vendor * vendor, // To handle this slightly better we use one subroutine per vendor. switch (*vendor) { - case CpuInfo::Vendor::Ibm: - detectProcCpuInfoIbm(cpuInfo, brand, features); - break; + case CpuInfo::Vendor::Ibm: detectProcCpuInfoIbm(cpuInfo, brand, features); break; case CpuInfo::Vendor::Arm: detectProcCpuInfoArm(cpuInfo, brand, family, model, stepping, features); @@ -954,7 +939,7 @@ detectProcCpuInfo(CpuInfo::Vendor * vendor, } } /*! \endcond */ -} // namespace +} // namespace // static @@ -978,8 +963,8 @@ CpuInfo CpuInfo::detect() { result.features_.insert(CpuInfo::Feature::X86_Hygon); } - detectX86Features(&result.brandString_, &result.family_, &result.model_, - &result.stepping_, &result.features_); + detectX86Features(&result.brandString_, &result.family_, &result.model_, &result.stepping_, + &result.features_); result.logicalProcessors_ = detectX86LogicalProcessors(); } else @@ -987,14 +972,14 @@ CpuInfo CpuInfo::detect() // Not x86 if (c_architecture == Architecture::Arm) { - result.vendor_ = CpuInfo::Vendor::Arm; + result.vendor_ = CpuInfo::Vendor::Arm; } else if (c_architecture == Architecture::PowerPC) { - result.vendor_ = CpuInfo::Vendor::Ibm; + result.vendor_ = CpuInfo::Vendor::Ibm; } -#if defined __aarch64__ || ( defined _M_ARM && _M_ARM >= 8 ) +#if defined __aarch64__ || (defined _M_ARM && _M_ARM >= 8) result.features_.insert(Feature::Arm_Neon); // ARMv8 always has Neon result.features_.insert(Feature::Arm_NeonAsimd); // ARMv8 always has Neon-asimd #endif @@ -1005,8 +990,8 @@ CpuInfo CpuInfo::detect() // On Linux we might be able to find information in /proc/cpuinfo. If vendor or brand // is set to a known value this routine will not overwrite it. - detectProcCpuInfo(&result.vendor_, &result.brandString_, &result.family_, - &result.model_, &result.stepping_, &result.features_); + detectProcCpuInfo(&result.vendor_, &result.brandString_, &result.family_, &result.model_, + &result.stepping_, &result.features_); } if (!result.logicalProcessors_.empty()) @@ -1030,106 +1015,98 @@ CpuInfo CpuInfo::detect() return result; } -CpuInfo::CpuInfo() - : vendor_(CpuInfo::Vendor::Unknown), brandString_("Unknown CPU brand"), - family_(0), model_(0), stepping_(0) +CpuInfo::CpuInfo() : + vendor_(CpuInfo::Vendor::Unknown), + brandString_("Unknown CPU brand"), + family_(0), + model_(0), + stepping_(0) { } -const std::string &CpuInfo::vendorString() const +const std::string& CpuInfo::vendorString() const { - static const std::map vendorStrings = - { - { Vendor::Unknown, "Unknown vendor" }, - { Vendor::Intel, "Intel" }, - { Vendor::Amd, "AMD" }, - { Vendor::Fujitsu, "Fujitsu" }, - { Vendor::Ibm, "IBM" }, - { Vendor::Arm, "ARM" }, - { Vendor::Oracle, "Oracle" }, - { Vendor::Hygon, "Hygon" }, + static const std::map vendorStrings = { + { Vendor::Unknown, "Unknown vendor" }, { Vendor::Intel, "Intel" }, { Vendor::Amd, "AMD" }, + { Vendor::Fujitsu, "Fujitsu" }, { Vendor::Ibm, "IBM" }, { Vendor::Arm, "ARM" }, + { Vendor::Oracle, "Oracle" }, { Vendor::Hygon, "Hygon" }, }; return vendorStrings.at(vendor_); } -const std::string &CpuInfo::featureString(Feature f) +const std::string& CpuInfo::featureString(Feature f) { - static const std::map featureStrings = - { - { Feature::X86_Aes, "aes" }, - { Feature::X86_Amd, "amd" }, - { Feature::X86_Apic, "apic" }, - { Feature::X86_Avx, "avx" }, - { Feature::X86_Avx2, "avx2" }, - { Feature::X86_Avx512F, "avx512f" }, - { Feature::X86_Avx512PF, "avx512pf" }, - { Feature::X86_Avx512ER, "avx512er" }, - { Feature::X86_Avx512CD, "avx512cd" }, - { Feature::X86_Avx512BW, "avx512bw" }, - { Feature::X86_Avx512VL, "avx512vl" }, - { Feature::X86_Clfsh, "clfsh" }, - { Feature::X86_Cmov, "cmov" }, - { Feature::X86_Cx8, "cx8" }, - { Feature::X86_Cx16, "cx16" }, - { Feature::X86_F16C, "f16c" }, - { Feature::X86_Fma, "fma" }, - { Feature::X86_Fma4, "fma4" }, - { Feature::X86_Hle, "hle" }, - { Feature::X86_Htt, "htt" }, - { Feature::X86_Intel, "intel" }, - { Feature::X86_Lahf, "lahf" }, - { Feature::X86_MisalignSse, "misalignsse" }, - { Feature::X86_Mmx, "mmx" }, - { Feature::X86_Msr, "msr" }, - { Feature::X86_NonstopTsc, "nonstop_tsc" }, - { Feature::X86_Pcid, "pcid" }, - { Feature::X86_Pclmuldq, "pclmuldq" }, - { Feature::X86_Pdcm, "pdcm" }, - { Feature::X86_PDPE1GB, "pdpe1gb" }, - { Feature::X86_Popcnt, "popcnt" }, - { Feature::X86_Pse, "pse" }, - { Feature::X86_Rdrnd, "rdrnd" }, - { Feature::X86_Rdtscp, "rdtscp" }, - { Feature::X86_Rtm, "rtm" }, - { Feature::X86_Sha, "sha" }, - { Feature::X86_Sse2, "sse2" }, - { Feature::X86_Sse3, "sse3" }, - { Feature::X86_Sse4A, "sse4a" }, - { Feature::X86_Sse4_1, "sse4.1" }, - { Feature::X86_Sse4_2, "sse4.2" }, - { Feature::X86_Ssse3, "ssse3" }, - { Feature::X86_Tdt, "tdt" }, - { Feature::X86_X2Apic, "x2apic" }, - { Feature::X86_Xop, "xop" }, - { Feature::Arm_Neon, "neon" }, - { Feature::Arm_NeonAsimd, "neon_asimd" }, - { Feature::Ibm_Qpx, "qpx" }, - { Feature::Ibm_Vmx, "vmx" }, - { Feature::Ibm_Vsx, "vsx" }, - { Feature::Fujitsu_HpcAce, "hpc-ace" }, - { Feature::X86_Hygon, "hygon" } + static const std::map featureStrings = { + { Feature::X86_Aes, "aes" }, + { Feature::X86_Amd, "amd" }, + { Feature::X86_Apic, "apic" }, + { Feature::X86_Avx, "avx" }, + { Feature::X86_Avx2, "avx2" }, + { Feature::X86_Avx512F, "avx512f" }, + { Feature::X86_Avx512PF, "avx512pf" }, + { Feature::X86_Avx512ER, "avx512er" }, + { Feature::X86_Avx512CD, "avx512cd" }, + { Feature::X86_Avx512BW, "avx512bw" }, + { Feature::X86_Avx512VL, "avx512vl" }, + { Feature::X86_Clfsh, "clfsh" }, + { Feature::X86_Cmov, "cmov" }, + { Feature::X86_Cx8, "cx8" }, + { Feature::X86_Cx16, "cx16" }, + { Feature::X86_F16C, "f16c" }, + { Feature::X86_Fma, "fma" }, + { Feature::X86_Fma4, "fma4" }, + { Feature::X86_Hle, "hle" }, + { Feature::X86_Htt, "htt" }, + { Feature::X86_Intel, "intel" }, + { Feature::X86_Lahf, "lahf" }, + { Feature::X86_MisalignSse, "misalignsse" }, + { Feature::X86_Mmx, "mmx" }, + { Feature::X86_Msr, "msr" }, + { Feature::X86_NonstopTsc, "nonstop_tsc" }, + { Feature::X86_Pcid, "pcid" }, + { Feature::X86_Pclmuldq, "pclmuldq" }, + { Feature::X86_Pdcm, "pdcm" }, + { Feature::X86_PDPE1GB, "pdpe1gb" }, + { Feature::X86_Popcnt, "popcnt" }, + { Feature::X86_Pse, "pse" }, + { Feature::X86_Rdrnd, "rdrnd" }, + { Feature::X86_Rdtscp, "rdtscp" }, + { Feature::X86_Rtm, "rtm" }, + { Feature::X86_Sha, "sha" }, + { Feature::X86_Sse2, "sse2" }, + { Feature::X86_Sse3, "sse3" }, + { Feature::X86_Sse4A, "sse4a" }, + { Feature::X86_Sse4_1, "sse4.1" }, + { Feature::X86_Sse4_2, "sse4.2" }, + { Feature::X86_Ssse3, "ssse3" }, + { Feature::X86_Tdt, "tdt" }, + { Feature::X86_X2Apic, "x2apic" }, + { Feature::X86_Xop, "xop" }, + { Feature::Arm_Neon, "neon" }, + { Feature::Arm_NeonAsimd, "neon_asimd" }, + { Feature::Ibm_Qpx, "qpx" }, + { Feature::Ibm_Vmx, "vmx" }, + { Feature::Ibm_Vsx, "vsx" }, + { Feature::Fujitsu_HpcAce, "hpc-ace" }, + { Feature::X86_Hygon, "hygon" } }; return featureStrings.at(f); } -bool -cpuIsX86Nehalem(const CpuInfo &cpuInfo) +bool cpuIsX86Nehalem(const CpuInfo& cpuInfo) { - return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Intel && - cpuInfo.family() == 6 && - (cpuInfo.model() == 0x2E || cpuInfo.model() == 0x1A || - cpuInfo.model() == 0x1E || cpuInfo.model() == 0x2F || - cpuInfo.model() == 0x2C || cpuInfo.model() == 0x25) ); + return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Intel && cpuInfo.family() == 6 + && (cpuInfo.model() == 0x2E || cpuInfo.model() == 0x1A || cpuInfo.model() == 0x1E + || cpuInfo.model() == 0x2F || cpuInfo.model() == 0x2C || cpuInfo.model() == 0x25)); } -} // namespace gmx +} // namespace gmx #ifdef GMX_CPUINFO_STANDALONE -int -main(int argc, char **argv) +int main(int argc, char** argv) { if (argc < 2) { @@ -1146,8 +1123,8 @@ main(int argc, char **argv) exit(1); } - std::string arg(argv[1]); - gmx::CpuInfo cpuInfo(gmx::CpuInfo::detect()); + std::string arg(argv[1]); + gmx::CpuInfo cpuInfo(gmx::CpuInfo::detect()); if (arg == "-vendor") { @@ -1175,7 +1152,7 @@ main(int argc, char **argv) // GROMACS cmake code, surrounding whitespace is first // stripped by the CPU detection routine, and then added back // in the code for making the SIMD suggestion. - for (auto &f : cpuInfo.featureSet() ) + for (auto& f : cpuInfo.featureSet()) { printf("%s ", cpuInfo.featureString(f).c_str()); } @@ -1184,7 +1161,7 @@ main(int argc, char **argv) else if (arg == "-topology") { // Undocumented debug option, usually not present in standalone version - for (auto &t : cpuInfo.logicalProcessors() ) + for (auto& t : cpuInfo.logicalProcessors()) { printf("%3u %3u %3u\n", t.socketRankInMachine, t.coreRankInSocket, t.hwThreadRankInCore); } diff --git a/src/gromacs/hardware/cpuinfo.h b/src/gromacs/hardware/cpuinfo.h index 2f9bb8427e..b2e305838c 100644 --- a/src/gromacs/hardware/cpuinfo.h +++ b/src/gromacs/hardware/cpuinfo.h @@ -66,214 +66,201 @@ namespace gmx class CpuInfo { - public: +public: + /*! \brief Amount of cpu information present (incremental) */ + enum class SupportLevel + { + None, //!< No cpu information whatsoever. Sorry. + Name, //!< Only vendor and/or brand is set + Features, //!< Some features are set + LogicalProcessorInfo //!< Everything includling logical processor information + }; - /*! \brief Amount of cpu information present (incremental) */ - enum class SupportLevel - { - None, //!< No cpu information whatsoever. Sorry. - Name, //!< Only vendor and/or brand is set - Features, //!< Some features are set - LogicalProcessorInfo //!< Everything includling logical processor information - }; + /*! \brief Processor/system vendors */ + enum class Vendor + { + Unknown, //!< Unidentified + Intel, //!< GenuineIntel + Amd, //!< AuthenticAMD + Fujitsu, //!< Only works on Linux (parsed from /proc/cpuinfo) + Ibm, //!< Only works on Linux (parsed from /proc/cpuinfo) + Arm, //!< Only works on Linux (parsed from /proc/cpuinfo) + Oracle, //!< Cannot detect anything else yet (no /proc/cpuinfo available) + Hygon, //!< HygonGenuine + }; - /*! \brief Processor/system vendors */ - enum class Vendor - { - Unknown, //!< Unidentified - Intel, //!< GenuineIntel - Amd, //!< AuthenticAMD - Fujitsu, //!< Only works on Linux (parsed from /proc/cpuinfo) - Ibm, //!< Only works on Linux (parsed from /proc/cpuinfo) - Arm, //!< Only works on Linux (parsed from /proc/cpuinfo) - Oracle, //!< Cannot detect anything else yet (no /proc/cpuinfo available) - Hygon, //!< HygonGenuine - }; + /*! \brief List of CPU features + * + * These values can be used as arguments to the feature() method + * to check whether a specific feature was found on the CPU we are + * running on. + */ + enum class Feature + { + X86_Aes, //!< x86 advanced encryption standard accel. + X86_Amd, //!< This is an AMD x86 processor + X86_Apic, //!< APIC support + X86_Avx, //!< Advanced vector extensions + X86_Avx2, //!< AVX2 including gather support (not used yet) + X86_Avx512F, //!< Foundation AVX-512 instructions + X86_Avx512PF, //!< Extended gather/scatter for AVX-512 + X86_Avx512ER, //!< AVX-512 exponential and recpirocal extensions + X86_Avx512CD, //!< Memory conflict-detection for AVX-512 + X86_Avx512BW, //!< AVX-512 byte and word instructions + X86_Avx512VL, //!< AVX-512 vector length extensions + X86_Clfsh, //!< Supports CLFLUSH instruction + X86_Cmov, //!< Conditional move insn support + X86_Cx8, //!< Supports CMPXCHG8B (8-byte compare-exchange) + X86_Cx16, //!< Supports CMPXCHG16B (16-byte compare-exchg) + X86_F16C, //!< Supports 16-bit FP conversion instructions + X86_Fma, //!< Fused-multiply add support (mainly for AVX) + X86_Fma4, //!< 4-operand FMA, only on AMD for now + X86_Hle, //!< Hardware lock elision + X86_Htt, //!< Hyper-Threading enabled (NOTE: might not match the CPUID HTT support flag) + X86_Intel, //!< This is an Intel x86 processor + X86_Lahf, //!< LAHF/SAHF support in 64 bits + X86_MisalignSse, //!< Support for misaligned SSE data instructions + X86_Mmx, //!< MMX registers and instructions + X86_Msr, //!< Supports Intel model-specific-registers + X86_NonstopTsc, //!< Invariant TSC (constant rate in ACPI states) + X86_Pcid, //!< Process context identifier support + X86_Pclmuldq, //!< Carry-less 64-bit multiplication supported + X86_Pdcm, //!< Perfmon and Debug Capability + X86_PDPE1GB, //!< Support for 1GB pages + X86_Popcnt, //!< Supports the POPCNT (population count) insn + X86_Pse, //!< Supports 4MB-pages (page size extension) + X86_Rdrnd, //!< RDRAND high-quality hardware random numbers + X86_Rdtscp, //!< Serializing rdtscp instruction available + X86_Rtm, //!< Restricted transactional memory + X86_Sha, //!< Intel SHA extensions + X86_Sse2, //!< SSE 2 + X86_Sse3, //!< SSE 3 + X86_Sse4A, //!< SSE 4A + X86_Sse4_1, //!< SSE 4.1 + X86_Sse4_2, //!< SSE 4.2 + X86_Ssse3, //!< Supplemental SSE3 + X86_Tdt, //!< TSC deadline timer + X86_X2Apic, //!< Extended xAPIC Support + X86_Xop, //!< AMD extended instructions, only AMD for now + Arm_Neon, //!< 32-bit ARM NEON + Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD + Ibm_Qpx, //!< IBM QPX SIMD (BlueGene/Q) + Ibm_Vmx, //!< IBM VMX SIMD (Altivec on Power6 and later) + Ibm_Vsx, //!< IBM VSX SIMD (Power7 and later) + Fujitsu_HpcAce, //!< Fujitsu Sparc64 HPC-ACE + X86_Hygon //!< This is a Hygon x86 processor + }; - /*! \brief List of CPU features - * - * These values can be used as arguments to the feature() method - * to check whether a specific feature was found on the CPU we are - * running on. - */ - enum class Feature - { - X86_Aes, //!< x86 advanced encryption standard accel. - X86_Amd, //!< This is an AMD x86 processor - X86_Apic, //!< APIC support - X86_Avx, //!< Advanced vector extensions - X86_Avx2, //!< AVX2 including gather support (not used yet) - X86_Avx512F, //!< Foundation AVX-512 instructions - X86_Avx512PF, //!< Extended gather/scatter for AVX-512 - X86_Avx512ER, //!< AVX-512 exponential and recpirocal extensions - X86_Avx512CD, //!< Memory conflict-detection for AVX-512 - X86_Avx512BW, //!< AVX-512 byte and word instructions - X86_Avx512VL, //!< AVX-512 vector length extensions - X86_Clfsh, //!< Supports CLFLUSH instruction - X86_Cmov, //!< Conditional move insn support - X86_Cx8, //!< Supports CMPXCHG8B (8-byte compare-exchange) - X86_Cx16, //!< Supports CMPXCHG16B (16-byte compare-exchg) - X86_F16C, //!< Supports 16-bit FP conversion instructions - X86_Fma, //!< Fused-multiply add support (mainly for AVX) - X86_Fma4, //!< 4-operand FMA, only on AMD for now - X86_Hle, //!< Hardware lock elision - X86_Htt, //!< Hyper-Threading enabled (NOTE: might not match the CPUID HTT support flag) - X86_Intel, //!< This is an Intel x86 processor - X86_Lahf, //!< LAHF/SAHF support in 64 bits - X86_MisalignSse, //!< Support for misaligned SSE data instructions - X86_Mmx, //!< MMX registers and instructions - X86_Msr, //!< Supports Intel model-specific-registers - X86_NonstopTsc, //!< Invariant TSC (constant rate in ACPI states) - X86_Pcid, //!< Process context identifier support - X86_Pclmuldq, //!< Carry-less 64-bit multiplication supported - X86_Pdcm, //!< Perfmon and Debug Capability - X86_PDPE1GB, //!< Support for 1GB pages - X86_Popcnt, //!< Supports the POPCNT (population count) insn - X86_Pse, //!< Supports 4MB-pages (page size extension) - X86_Rdrnd, //!< RDRAND high-quality hardware random numbers - X86_Rdtscp, //!< Serializing rdtscp instruction available - X86_Rtm, //!< Restricted transactional memory - X86_Sha, //!< Intel SHA extensions - X86_Sse2, //!< SSE 2 - X86_Sse3, //!< SSE 3 - X86_Sse4A, //!< SSE 4A - X86_Sse4_1, //!< SSE 4.1 - X86_Sse4_2, //!< SSE 4.2 - X86_Ssse3, //!< Supplemental SSE3 - X86_Tdt, //!< TSC deadline timer - X86_X2Apic, //!< Extended xAPIC Support - X86_Xop, //!< AMD extended instructions, only AMD for now - Arm_Neon, //!< 32-bit ARM NEON - Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD - Ibm_Qpx, //!< IBM QPX SIMD (BlueGene/Q) - Ibm_Vmx, //!< IBM VMX SIMD (Altivec on Power6 and later) - Ibm_Vsx, //!< IBM VSX SIMD (Power7 and later) - Fujitsu_HpcAce, //!< Fujitsu Sparc64 HPC-ACE - X86_Hygon //!< This is a Hygon x86 processor - }; + /*! \libinternal \brief Entry with basic information for a single logical processor */ + struct LogicalProcessor + { + int socketRankInMachine; //!< Relative rank of the current socket in the system + int coreRankInSocket; //!< Relative rank of the current core in its socket + int hwThreadRankInCore; //!< Relative rank of logical processor in its core + }; - /*! \libinternal \brief Entry with basic information for a single logical processor */ - struct LogicalProcessor - { - int socketRankInMachine; //!< Relative rank of the current socket in the system - int coreRankInSocket; //!< Relative rank of the current core in its socket - int hwThreadRankInCore; //!< Relative rank of logical processor in its core - }; +public: + /*! \brief Perform detection and construct a CpuInfo class from the results. + * + * \note The detection should generally be performed again in different + * contexts. This might seem like overkill, but there + * are systems (e.g. Arm) where processors can go completely offline + * during deep sleep, so at least in theory it is good to have a + * possibility of forcing re-detection if necessary. + */ + static CpuInfo detect(); - public: - /*! \brief Perform detection and construct a CpuInfo class from the results. - * - * \note The detection should generally be performed again in different - * contexts. This might seem like overkill, but there - * are systems (e.g. Arm) where processors can go completely offline - * during deep sleep, so at least in theory it is good to have a - * possibility of forcing re-detection if necessary. - */ - static CpuInfo detect(); + /*! \brief Check what cpu information is available + * + * The amount of cpu information that can be detected depends on the + * OS, compiler, and CPU, and on non-x86 platforms it can be fragile. + * Before basing decisions on the output or warning the user about + * optimizations, you want to check whether it was possible to detect + * the information you need. + */ + SupportLevel supportLevel() const { return supportLevel_; } - /*! \brief Check what cpu information is available - * - * The amount of cpu information that can be detected depends on the - * OS, compiler, and CPU, and on non-x86 platforms it can be fragile. - * Before basing decisions on the output or warning the user about - * optimizations, you want to check whether it was possible to detect - * the information you need. - */ - SupportLevel - supportLevel() const { return supportLevel_; } + /*! \brief Enumerated value for vendor */ + Vendor vendor() const { return vendor_; } - /*! \brief Enumerated value for vendor */ - Vendor - vendor() const { return vendor_; } + /*! \brief String description of vendor: + * + * \throws std::out_of_range if the vendor is not present in the internal + * map of vendor names. This can only happen if we extend the enum + * type but forget to add the string with the vendor name. + */ + const std::string& vendorString() const; - /*! \brief String description of vendor: - * - * \throws std::out_of_range if the vendor is not present in the internal - * map of vendor names. This can only happen if we extend the enum - * type but forget to add the string with the vendor name. - */ - const std::string &vendorString() const; + /*! \brief String description of processor */ + const std::string& brandString() const { return brandString_; } - /*! \brief String description of processor */ - const std::string & - brandString() const { return brandString_; } + /*! \brief Major version/generation of the processor */ + int family() const { return family_; } - /*! \brief Major version/generation of the processor */ - int - family() const { return family_; } + /*! \brief Middle version of the processor */ + int model() const { return model_; } - /*! \brief Middle version of the processor */ - int - model() const { return model_; } + /*! \brief Minor version of the processor */ + int stepping() const { return stepping_; } - /*! \brief Minor version of the processor */ - int - stepping() const { return stepping_; } + /*! \brief Check for availability of specific feature + * + * \param f feature to query support for + * + * \return True if the feature is available, otherwise false. + */ + bool feature(Feature f) const + { + // If the entry is present in the set it is supported + return (features_.count(f) != 0); + } - /*! \brief Check for availability of specific feature - * - * \param f feature to query support for - * - * \return True if the feature is available, otherwise false. - */ - bool - feature(Feature f) const - { - // If the entry is present in the set it is supported - return (features_.count(f) != 0); - } + /*! \brief String description of a specific feature + * + * \throws std::out_of_range if the feature is not present in the internal + * map of feature names. This can only happen if we extend the enum + * type but forget to add the string with the feature name. + */ + static const std::string& featureString(Feature f); - /*! \brief String description of a specific feature - * - * \throws std::out_of_range if the feature is not present in the internal - * map of feature names. This can only happen if we extend the enum - * type but forget to add the string with the feature name. - */ - static const std::string &featureString(Feature f); + /*! \brief Set of all supported features on this processor + * + * This is only intended for logfiles, debugging or similar output when we + * need a full list of all the features available on the CPU. + */ + const std::set& featureSet() const { return features_; } - /*! \brief Set of all supported features on this processor - * - * This is only intended for logfiles, debugging or similar output when we - * need a full list of all the features available on the CPU. - */ - const std::set & - featureSet() const - { - return features_; - } + /*! \brief Reference to processing unit topology + * + * Only a few systems (x86) provide logical processor information in cpuinfo. + * This method returns a reference to a vector, whose length will either be + * zero (if topology information is not available) or the number of enabled + * processing units, as defined by the operating system. In the latter + * case, each entry will contain information about the relative rank in the + * core and socket of this hardware thread. + * + * This is only meant to be use as a fallback implementation for our + * HardwareTopology class; any user code that needs access to hardware + * topology information should use that class instead. + * + * \note For clarity, it is likely better to use the supportLevel() + * method to check if this information is available rather than + * relying on the length of the vector. + */ + const std::vector& logicalProcessors() const { return logicalProcessors_; } - /*! \brief Reference to processing unit topology - * - * Only a few systems (x86) provide logical processor information in cpuinfo. - * This method returns a reference to a vector, whose length will either be - * zero (if topology information is not available) or the number of enabled - * processing units, as defined by the operating system. In the latter - * case, each entry will contain information about the relative rank in the - * core and socket of this hardware thread. - * - * This is only meant to be use as a fallback implementation for our - * HardwareTopology class; any user code that needs access to hardware - * topology information should use that class instead. - * - * \note For clarity, it is likely better to use the supportLevel() - * method to check if this information is available rather than - * relying on the length of the vector. - */ - const std::vector & - logicalProcessors() const { return logicalProcessors_; } +private: + CpuInfo(); - private: - CpuInfo(); - - SupportLevel supportLevel_; //!< Available cpuinfo information - Vendor vendor_; //!< Value of vendor for current cpu - std::string brandString_; //!< Text description of cpu - int family_; //!< Major version of current cpu - int model_; //!< Middle version of current cpu - int stepping_; //!< Minor version of current cpu - std::set features_; //!< Set of features supported on this cpu - std::vector logicalProcessors_; //!< Simple logical processor topology -}; // class CpuInfo + SupportLevel supportLevel_; //!< Available cpuinfo information + Vendor vendor_; //!< Value of vendor for current cpu + std::string brandString_; //!< Text description of cpu + int family_; //!< Major version of current cpu + int model_; //!< Middle version of current cpu + int stepping_; //!< Minor version of current cpu + std::set features_; //!< Set of features supported on this cpu + std::vector logicalProcessors_; //!< Simple logical processor topology +}; // class CpuInfo /*! \brief Return true if the CPU is an Intel x86 Nehalem * @@ -281,9 +268,8 @@ class CpuInfo * * \returns True if running on Nehalem CPU */ -bool -cpuIsX86Nehalem(const CpuInfo &cpuInfo); +bool cpuIsX86Nehalem(const CpuInfo& cpuInfo); -} // namespace gmx +} // namespace gmx -#endif // GMX_HARDWARE_CPUINFO_H +#endif // GMX_HARDWARE_CPUINFO_H diff --git a/src/gromacs/hardware/detecthardware.cpp b/src/gromacs/hardware/detecthardware.cpp index 41071a6872..c24a8b2a4c 100644 --- a/src/gromacs/hardware/detecthardware.cpp +++ b/src/gromacs/hardware/detecthardware.cpp @@ -66,13 +66,13 @@ #include "architecture.h" #ifdef HAVE_UNISTD_H -# include // sysconf() +# include // sysconf() #endif gmx_hw_info_t::gmx_hw_info_t(std::unique_ptr cpuInfo, - std::unique_ptr hardwareTopology) - : cpuInfo(std::move(cpuInfo)), - hardwareTopology(std::move(hardwareTopology)) + std::unique_ptr hardwareTopology) : + cpuInfo(std::move(cpuInfo)), + hardwareTopology(std::move(hardwareTopology)) { } @@ -104,12 +104,12 @@ namespace gmx * lifetime exceeds that of the thread. */ static std::unique_ptr g_hardwareInfo; //! A mutex to protect the hwinfo structure -static Mutex g_hardwareInfoMutex; +static Mutex g_hardwareInfoMutex; //! Detect GPUs, if that makes sense to attempt. -static void gmx_detect_gpus(const gmx::MDLogger &mdlog, - const PhysicalNodeCommunicator &physicalNodeComm, - compat::not_null hardwareInfo) +static void gmx_detect_gpus(const gmx::MDLogger& mdlog, + const PhysicalNodeCommunicator& physicalNodeComm, + compat::not_null hardwareInfo) { hardwareInfo->gpu_info.bDetectGPUs = canPerformGpuDetection(); @@ -139,11 +139,13 @@ static void gmx_detect_gpus(const gmx::MDLogger &mdlog, gpusCanBeDetected = isGpuDetectionFunctional(&errorMessage); if (!gpusCanBeDetected) { - GMX_LOG(mdlog.info).asParagraph().appendTextFormatted( - "NOTE: Detection of GPUs failed. The API reported:\n" - " %s\n" - " GROMACS cannot run tasks on a GPU.", - errorMessage.c_str()); + GMX_LOG(mdlog.info) + .asParagraph() + .appendTextFormatted( + "NOTE: Detection of GPUs failed. The API reported:\n" + " %s\n" + " GROMACS cannot run tasks on a GPU.", + errorMessage.c_str()); } } @@ -164,45 +166,41 @@ static void gmx_detect_gpus(const gmx::MDLogger &mdlog, { int dev_size; - dev_size = hardwareInfo->gpu_info.n_dev*sizeof_gpu_dev_info(); + dev_size = hardwareInfo->gpu_info.n_dev * sizeof_gpu_dev_info(); if (!isMasterRankOfPhysicalNode) { - hardwareInfo->gpu_info.gpu_dev = - (struct gmx_device_info_t *)malloc(dev_size); + hardwareInfo->gpu_info.gpu_dev = (struct gmx_device_info_t*)malloc(dev_size); } - MPI_Bcast(hardwareInfo->gpu_info.gpu_dev, dev_size, MPI_BYTE, - 0, physicalNodeComm.comm_); - MPI_Bcast(&hardwareInfo->gpu_info.n_dev_compatible, 1, MPI_INT, - 0, physicalNodeComm.comm_); + MPI_Bcast(hardwareInfo->gpu_info.gpu_dev, dev_size, MPI_BYTE, 0, physicalNodeComm.comm_); + MPI_Bcast(&hardwareInfo->gpu_info.n_dev_compatible, 1, MPI_INT, 0, physicalNodeComm.comm_); } } #endif } //! Reduce the locally collected \p hardwareInfo over MPI ranks -static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo, - const PhysicalNodeCommunicator &physicalNodeComm, - compat::not_null hardwareInfo) +static void gmx_collect_hardware_mpi(const gmx::CpuInfo& cpuInfo, + const PhysicalNodeCommunicator& physicalNodeComm, + compat::not_null hardwareInfo) { - const int ncore = hardwareInfo->hardwareTopology->numberOfCores(); + const int ncore = hardwareInfo->hardwareTopology->numberOfCores(); /* Zen1 is assumed for: * - family=23 with the below listed models; * - Hygon as vendor. */ - const bool cpuIsAmdZen1 = ((cpuInfo.vendor() == CpuInfo::Vendor::Amd && - cpuInfo.family() == 23 && - (cpuInfo.model() == 1 || cpuInfo.model() == 17 || - cpuInfo.model() == 8 || cpuInfo.model() == 24)) || - cpuInfo.vendor() == CpuInfo::Vendor::Hygon); + const bool cpuIsAmdZen1 = ((cpuInfo.vendor() == CpuInfo::Vendor::Amd && cpuInfo.family() == 23 + && (cpuInfo.model() == 1 || cpuInfo.model() == 17 + || cpuInfo.model() == 8 || cpuInfo.model() == 24)) + || cpuInfo.vendor() == CpuInfo::Vendor::Hygon); #if GMX_LIB_MPI - int nhwthread, ngpu, i; - int gpu_hash; + int nhwthread, ngpu, i; + int gpu_hash; nhwthread = hardwareInfo->nthreads_hw_avail; ngpu = hardwareInfo->gpu_info.n_dev_compatible; /* Create a unique hash of the GPU type(s) in this node */ - gpu_hash = 0; + gpu_hash = 0; /* Here it might be better to only loop over the compatible GPU, but we * don't have that information available and it would also require * removing the device ID from the device info string. @@ -219,10 +217,10 @@ static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo, gpu_hash ^= gmx_string_fullhash_func(stmp, gmx_string_hash_init); } - constexpr int numElementsCounts = 4; - std::array countsReduced; + constexpr int numElementsCounts = 4; + std::array countsReduced; { - std::array countsLocal = {{0}}; + std::array countsLocal = { { 0 } }; // Organize to sum values from only one rank within each node, // so we get the sum over all nodes. bool isMasterRankOfPhysicalNode = (physicalNodeComm.rank_ == 0); @@ -234,12 +232,12 @@ static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo, countsLocal[3] = ngpu; } - MPI_Allreduce(countsLocal.data(), countsReduced.data(), countsLocal.size(), - MPI_INT, MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(countsLocal.data(), countsReduced.data(), countsLocal.size(), MPI_INT, + MPI_SUM, MPI_COMM_WORLD); } - constexpr int numElementsMax = 11; - std::array maxMinReduced; + constexpr int numElementsMax = 11; + std::array maxMinReduced; { std::array maxMinLocal; /* Store + and - values for all ranks, @@ -257,8 +255,8 @@ static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo, maxMinLocal[9] = -maxMinLocal[4]; maxMinLocal[10] = (cpuIsAmdZen1 ? 1 : 0); - MPI_Allreduce(maxMinLocal.data(), maxMinReduced.data(), maxMinLocal.size(), - MPI_INT, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(maxMinLocal.data(), maxMinReduced.data(), maxMinLocal.size(), MPI_INT, + MPI_MAX, MPI_COMM_WORLD); } hardwareInfo->nphysicalnode = countsReduced[0]; @@ -304,16 +302,15 @@ static void gmx_collect_hardware_mpi(const gmx::CpuInfo &cpuInfo, * * This routine will not throw exceptions. */ -static void -spinUpCore() noexcept +static void spinUpCore() noexcept { #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) && defined(_SC_NPROCESSORS_ONLN) float dummy = 0.1; int countConfigured = sysconf(_SC_NPROCESSORS_CONF); // noexcept auto start = std::chrono::steady_clock::now(); // noexcept - while (sysconf(_SC_NPROCESSORS_ONLN) < countConfigured && - std::chrono::steady_clock::now() - start < std::chrono::seconds(2)) + while (sysconf(_SC_NPROCESSORS_ONLN) < countConfigured + && std::chrono::steady_clock::now() - start < std::chrono::seconds(2)) { for (int i = 1; i < 10000; i++) { @@ -348,25 +345,23 @@ spinUpCore() noexcept * \note Cores will sleep relatively quickly again, so it's important to issue * the real detection code directly after this routine. */ -static void -hardwareTopologyPrepareDetection() +static void hardwareTopologyPrepareDetection() { -#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) && \ - (defined(THREAD_PTHREADS) || defined(THREAD_WINDOWS)) +#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) \ + && (defined(THREAD_PTHREADS) || defined(THREAD_WINDOWS)) // Modify this conditional when/if x86 or PowerPC starts to sleep some cores - if (c_architecture != Architecture::X86 && - c_architecture != Architecture::PowerPC) + if (c_architecture != Architecture::X86 && c_architecture != Architecture::PowerPC) { - int countConfigured = sysconf(_SC_NPROCESSORS_CONF); + int countConfigured = sysconf(_SC_NPROCESSORS_CONF); std::vector workThreads(countConfigured); - for (auto &t : workThreads) + for (auto& t : workThreads) { t = std::thread(spinUpCore); } - for (auto &t : workThreads) + for (auto& t : workThreads) { t.join(); } @@ -379,9 +374,8 @@ hardwareTopologyPrepareDetection() * \param mdlog Logger. * \param hardwareTopology Reference to hardwareTopology object. */ -static void -hardwareTopologyDoubleCheckDetection(const gmx::MDLogger gmx_unused &mdlog, - const gmx::HardwareTopology gmx_unused &hardwareTopology) +static void hardwareTopologyDoubleCheckDetection(const gmx::MDLogger gmx_unused& mdlog, + const gmx::HardwareTopology gmx_unused& hardwareTopology) { #if defined HAVE_SYSCONF && defined(_SC_NPROCESSORS_CONF) if (hardwareTopology.supportLevel() < gmx::HardwareTopology::SupportLevel::LogicalProcessorCount) @@ -399,29 +393,32 @@ hardwareTopologyDoubleCheckDetection(const gmx::MDLogger gmx_unused &mdl */ if (countConfigured >= 0 && countConfigured != countFromDetection) { - GMX_LOG(mdlog.info). - appendTextFormatted("Note: %d CPUs configured, but only %d were detected to be online.\n", countConfigured, countFromDetection); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Note: %d CPUs configured, but only %d were detected to be online.\n", + countConfigured, countFromDetection); - if (c_architecture == Architecture::X86 && - countConfigured == 2*countFromDetection) + if (c_architecture == Architecture::X86 && countConfigured == 2 * countFromDetection) { - GMX_LOG(mdlog.info). - appendText(" X86 Hyperthreading is likely disabled; enable it for better performance."); + GMX_LOG(mdlog.info) + .appendText( + " X86 Hyperthreading is likely disabled; enable it for better " + "performance."); } // For PowerPC (likely Power8) it is possible to set SMT to either 2,4, or 8-way hardware threads. // We only warn if it is completely disabled since default performance drops with SMT8. - if (c_architecture == Architecture::PowerPC && - countConfigured == 8*countFromDetection) + if (c_architecture == Architecture::PowerPC && countConfigured == 8 * countFromDetection) { - GMX_LOG(mdlog.info). - appendText(" PowerPC SMT is likely disabled; enable SMT2/SMT4 for better performance."); + GMX_LOG(mdlog.info) + .appendText( + " PowerPC SMT is likely disabled; enable SMT2/SMT4 for better " + "performance."); } } #endif } -gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog, - const PhysicalNodeCommunicator &physicalNodeComm) +gmx_hw_info_t* gmx_detect_hardware(const gmx::MDLogger& mdlog, const PhysicalNodeCommunicator& physicalNodeComm) { // By construction, only one thread ever runs hardware detection, // but we may as well prevent issues arising if that would change. @@ -440,8 +437,9 @@ gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog, // TODO: We should also do CPU hardware detection only once on each // physical node and broadcast it, instead of doing it on every MPI rank. - auto hardwareInfo = std::make_unique(std::make_unique(CpuInfo::detect()), - std::make_unique(HardwareTopology::detect())); + auto hardwareInfo = std::make_unique( + std::make_unique(CpuInfo::detect()), + std::make_unique(HardwareTopology::detect())); // If we detected the topology on this system, double-check that it makes sense if (hardwareInfo->hardwareTopology->isThisSystem()) @@ -467,9 +465,9 @@ gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog, return g_hardwareInfo.get(); } -bool compatibleGpusFound(const gmx_gpu_info_t &gpu_info) +bool compatibleGpusFound(const gmx_gpu_info_t& gpu_info) { return gpu_info.n_dev_compatible > 0; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/hardware/detecthardware.h b/src/gromacs/hardware/detecthardware.h index 0683cad96a..e0f5b69450 100644 --- a/src/gromacs/hardware/detecthardware.h +++ b/src/gromacs/hardware/detecthardware.h @@ -58,11 +58,11 @@ class PhysicalNodeCommunicator; * work, and any subsequent call receives the same handle. With real * MPI, communication is needed to coordinate the results. In all * cases, any thread within a process may use the returned handle. */ -gmx_hw_info_t *gmx_detect_hardware(const gmx::MDLogger &mdlog, - const PhysicalNodeCommunicator &physicalNodeComm); +gmx_hw_info_t* gmx_detect_hardware(const gmx::MDLogger& mdlog, + const PhysicalNodeCommunicator& physicalNodeComm); //! Return whether compatible GPUs were found. -bool compatibleGpusFound(const gmx_gpu_info_t &gpu_info); +bool compatibleGpusFound(const gmx_gpu_info_t& gpu_info); } // namespace gmx diff --git a/src/gromacs/hardware/gpu_hw_info.cpp b/src/gromacs/hardware/gpu_hw_info.cpp index a65c5cea0b..cf913ed041 100644 --- a/src/gromacs/hardware/gpu_hw_info.cpp +++ b/src/gromacs/hardware/gpu_hw_info.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,7 @@ // TODO If/when we unify CUDA and OpenCL support code, this should // move to a single place in gpu_utils. /* Names of the GPU detection/check results (see e_gpu_detect_res_t in hw_info.h). */ -const char * const gpu_detect_res_str[egpuNR] = -{ - "compatible", "nonexistent", "incompatible", "incompatible (please recompile with GMX_OPENCL_NB_CLUSTER_SIZE=4)", "insane" +const char* const gpu_detect_res_str[egpuNR] = { + "compatible", "nonexistent", "incompatible", + "incompatible (please recompile with GMX_OPENCL_NB_CLUSTER_SIZE=4)", "insane" }; diff --git a/src/gromacs/hardware/gpu_hw_info.h b/src/gromacs/hardware/gpu_hw_info.h index f7c2cfde5c..471eeb81e2 100644 --- a/src/gromacs/hardware/gpu_hw_info.h +++ b/src/gromacs/hardware/gpu_hw_info.h @@ -46,13 +46,18 @@ struct gmx_device_info_t; * incompatible driver/runtime. */ typedef enum { - egpuCompatible = 0, egpuNonexistent, egpuIncompatible, egpuIncompatibleClusterSize, egpuInsane, egpuNR + egpuCompatible = 0, + egpuNonexistent, + egpuIncompatible, + egpuIncompatibleClusterSize, + egpuInsane, + egpuNR } e_gpu_detect_res_t; /*! \brief Names of the GPU detection/check results * * \todo Make a proper class enumeration with helper string */ -extern const char * const gpu_detect_res_str[egpuNR]; +extern const char* const gpu_detect_res_str[egpuNR]; /*! \brief Information about GPU devices on this physical node. * @@ -63,13 +68,13 @@ extern const char * const gpu_detect_res_str[egpuNR]; struct gmx_gpu_info_t { //! Did we attempt GPU detection? - gmx_bool bDetectGPUs; + gmx_bool bDetectGPUs; //! Total number of GPU devices detected on this physical node - int n_dev; + int n_dev; //! Information about each GPU device detected on this physical node - gmx_device_info_t *gpu_dev; + gmx_device_info_t* gpu_dev; //! Number of GPU devices detected on this physical node that are compatible. - int n_dev_compatible; + int n_dev_compatible; }; #endif diff --git a/src/gromacs/hardware/hardwaretopology.cpp b/src/gromacs/hardware/hardwaretopology.cpp index 0d800311ab..c086002864 100644 --- a/src/gromacs/hardware/hardwaretopology.cpp +++ b/src/gromacs/hardware/hardwaretopology.cpp @@ -63,10 +63,10 @@ #include "gromacs/utility/gmxassert.h" #ifdef HAVE_UNISTD_H -# include // sysconf() +# include // sysconf() #endif #if GMX_NATIVE_WINDOWS -# include // GetSystemInfo() +# include // GetSystemInfo() #endif //! Convenience macro to help us avoid ifdefs each time we use sysconf @@ -94,9 +94,7 @@ namespace * this will be updated to reflect the amount of * information written to the machine structure. */ -void -parseCpuInfo(HardwareTopology::Machine * machine, - HardwareTopology::SupportLevel * supportLevel) +void parseCpuInfo(HardwareTopology::Machine* machine, HardwareTopology::SupportLevel* supportLevel) { CpuInfo cpuInfo(CpuInfo::detect()); @@ -107,9 +105,10 @@ parseCpuInfo(HardwareTopology::Machine * machine, int nHwThreads = 0; // Copy the logical processor information from cpuinfo - for (auto &l : cpuInfo.logicalProcessors()) + for (auto& l : cpuInfo.logicalProcessors()) { - machine->logicalProcessors.push_back( { l.socketRankInMachine, l.coreRankInSocket, l.hwThreadRankInCore, -1 } ); + machine->logicalProcessors.push_back( + { l.socketRankInMachine, l.coreRankInSocket, l.hwThreadRankInCore, -1 }); nSockets = std::max(nSockets, l.socketRankInMachine); nCores = std::max(nCores, l.coreRankInSocket); nHwThreads = std::max(nHwThreads, l.hwThreadRankInCore); @@ -121,16 +120,16 @@ parseCpuInfo(HardwareTopology::Machine * machine, int hwThreadId = 0; machine->sockets.resize(nSockets + 1); - for (auto &s : machine->sockets) + for (auto& s : machine->sockets) { s.id = socketId++; s.cores.resize(nCores + 1); - for (auto &c : s.cores) + for (auto& c : s.cores) { c.id = coreId++; c.numaNodeId = -1; // No numa information c.hwThreads.resize(nHwThreads + 1); - for (auto &t : c.hwThreads) + for (auto& t : c.hwThreads) { t.id = hwThreadId++; t.logicalProcessorId = -1; // set as unassigned for now @@ -141,8 +140,11 @@ parseCpuInfo(HardwareTopology::Machine * machine, // Fill the logical processor id in the right place for (std::size_t i = 0; i < machine->logicalProcessors.size(); i++) { - const HardwareTopology::LogicalProcessor &l = machine->logicalProcessors[i]; - machine->sockets[l.socketRankInMachine].cores[l.coreRankInSocket].hwThreads[l.hwThreadRankInCore].logicalProcessorId = static_cast(i); + const HardwareTopology::LogicalProcessor& l = machine->logicalProcessors[i]; + machine->sockets[l.socketRankInMachine] + .cores[l.coreRankInSocket] + .hwThreads[l.hwThreadRankInCore] + .logicalProcessorId = static_cast(i); } machine->logicalProcessorCount = machine->logicalProcessors.size(); *supportLevel = HardwareTopology::SupportLevel::Basic; @@ -155,17 +157,17 @@ parseCpuInfo(HardwareTopology::Machine * machine, #if GMX_USE_HWLOC -#if HWLOC_API_VERSION < 0x00010b00 -# define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET -# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE -#endif +# if HWLOC_API_VERSION < 0x00010b00 +# define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET +# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE +# endif // Preprocessor variable for if hwloc api is version 1.x.x or 2.x.x -#if HWLOC_API_VERSION >= 0x00020000 -# define GMX_HWLOC_API_VERSION_IS_2XX 1 -#else -# define GMX_HWLOC_API_VERSION_IS_2XX 0 -#endif +# if HWLOC_API_VERSION >= 0x00020000 +# define GMX_HWLOC_API_VERSION_IS_2XX 1 +# else +# define GMX_HWLOC_API_VERSION_IS_2XX 0 +# endif /***************************************************************************** * * @@ -174,14 +176,13 @@ parseCpuInfo(HardwareTopology::Machine * machine, *****************************************************************************/ // Compatibility function for accessing hwloc_obj_t object memory with different API versions of hwloc -std::size_t -getHwLocObjectMemory(const hwloc_obj* obj) +std::size_t getHwLocObjectMemory(const hwloc_obj* obj) { -#if GMX_HWLOC_API_VERSION_IS_2XX +# if GMX_HWLOC_API_VERSION_IS_2XX return obj->total_memory; -#else +# else return obj->memory.total_memory; -#endif +# endif } /*! \brief Return vector of all descendants of a given type in hwloc topology @@ -195,8 +196,9 @@ getHwLocObjectMemory(const hwloc_obj* obj) * descendants of the provided object. If no objects of this type * were found, the vector will be empty. */ -std::vector -getHwLocDescendantsByType(const hwloc_topology* topo, const hwloc_obj* obj, const hwloc_obj_type_t type) +std::vector getHwLocDescendantsByType(const hwloc_topology* topo, + const hwloc_obj* obj, + const hwloc_obj_type_t type) { GMX_RELEASE_ASSERT(obj, "NULL hwloc object provided to getHwLocDescendantsByType()"); @@ -210,8 +212,8 @@ getHwLocDescendantsByType(const hwloc_topology* topo, const hwloc_obj* obj, cons // and we'll return an empty vector. hwloc_obj_t tempNode = nullptr; while ((tempNode = hwloc_get_next_child(const_cast(topo), - const_cast(obj), - tempNode)) != nullptr) + const_cast(obj), tempNode)) + != nullptr) { std::vector v2 = getHwLocDescendantsByType(topo, tempNode, type); v.insert(v.end(), v2.begin(), v2.end()); @@ -227,12 +229,10 @@ getHwLocDescendantsByType(const hwloc_topology* topo, const hwloc_obj* obj, cons * * \return If all the data is found */ -bool -parseHwLocSocketsCoresThreads(hwloc_topology_t topo, - HardwareTopology::Machine * machine) +bool parseHwLocSocketsCoresThreads(hwloc_topology_t topo, HardwareTopology::Machine* machine) { - const hwloc_obj* root = hwloc_get_root_obj(topo); - std::vector hwlocSockets = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PACKAGE); + const hwloc_obj* root = hwloc_get_root_obj(topo); + std::vector hwlocSockets = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PACKAGE); machine->logicalProcessorCount = hwloc_get_nbobjs_by_type(topo, HWLOC_OBJ_PU); machine->logicalProcessors.resize(machine->logicalProcessorCount); @@ -246,7 +246,8 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t topo, machine->sockets[i].id = hwlocSockets[i]->logical_index; // Get children (cores) - std::vector hwlocCores = getHwLocDescendantsByType(topo, hwlocSockets[i], HWLOC_OBJ_CORE); + std::vector hwlocCores = + getHwLocDescendantsByType(topo, hwlocSockets[i], HWLOC_OBJ_CORE); machine->sockets[i].cores.resize(hwlocCores.size()); topologyOk = topologyOk && !hwlocCores.empty(); // Fail if we have no cores in socket @@ -259,7 +260,8 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t topo, machine->sockets[i].cores[j].numaNodeId = -1; // Get children (hwthreads) - std::vector hwlocPUs = getHwLocDescendantsByType(topo, hwlocCores[j], HWLOC_OBJ_PU); + std::vector hwlocPUs = + getHwLocDescendantsByType(topo, hwlocCores[j], HWLOC_OBJ_PU); machine->sockets[i].cores[j].hwThreads.resize(hwlocPUs.size()); topologyOk = topologyOk && !hwlocPUs.empty(); // Fail if we have no hwthreads in core @@ -268,17 +270,20 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t topo, for (std::size_t k = 0; k < hwlocPUs.size() && topologyOk; k++) { // Assign information about this hwthread - std::size_t logicalProcessorId = hwlocPUs[k]->os_index; - machine->sockets[i].cores[j].hwThreads[k].id = hwlocPUs[k]->logical_index; + std::size_t logicalProcessorId = hwlocPUs[k]->os_index; + machine->sockets[i].cores[j].hwThreads[k].id = hwlocPUs[k]->logical_index; machine->sockets[i].cores[j].hwThreads[k].logicalProcessorId = logicalProcessorId; if (logicalProcessorId < machine->logicalProcessors.size()) { // Cross-assign data for this hwthread to the logicalprocess vector - machine->logicalProcessors[logicalProcessorId].socketRankInMachine = static_cast(i); - machine->logicalProcessors[logicalProcessorId].coreRankInSocket = static_cast(j); - machine->logicalProcessors[logicalProcessorId].hwThreadRankInCore = static_cast(k); - machine->logicalProcessors[logicalProcessorId].numaNodeId = -1; + machine->logicalProcessors[logicalProcessorId].socketRankInMachine = + static_cast(i); + machine->logicalProcessors[logicalProcessorId].coreRankInSocket = + static_cast(j); + machine->logicalProcessors[logicalProcessorId].hwThreadRankInCore = + static_cast(k); + machine->logicalProcessors[logicalProcessorId].numaNodeId = -1; } else { @@ -304,12 +309,10 @@ parseHwLocSocketsCoresThreads(hwloc_topology_t topo, * * \return If any cache data is found */ -bool -parseHwLocCache(hwloc_topology_t topo, - HardwareTopology::Machine * machine) +bool parseHwLocCache(hwloc_topology_t topo, HardwareTopology::Machine* machine) { // Parse caches up to L5 - for (int cachelevel : { 1, 2, 3, 4, 5}) + for (int cachelevel : { 1, 2, 3, 4, 5 }) { int depth = hwloc_get_cache_type_depth(topo, cachelevel, HWLOC_OBJ_CACHE_DATA); @@ -318,15 +321,14 @@ parseHwLocCache(hwloc_topology_t topo, hwloc_obj_t cache = hwloc_get_next_obj_by_depth(topo, depth, nullptr); if (cache != nullptr) { - std::vector hwThreads = getHwLocDescendantsByType(topo, cache, HWLOC_OBJ_PU); - - machine->caches.push_back( { - static_cast(cache->attr->cache.depth), - static_cast(cache->attr->cache.size), - static_cast(cache->attr->cache.linesize), - static_cast(cache->attr->cache.associativity), - std::max(hwThreads.size(), 1) - } ); + std::vector hwThreads = + getHwLocDescendantsByType(topo, cache, HWLOC_OBJ_PU); + + machine->caches.push_back({ static_cast(cache->attr->cache.depth), + static_cast(cache->attr->cache.size), + static_cast(cache->attr->cache.linesize), + static_cast(cache->attr->cache.associativity), + std::max(hwThreads.size(), 1) }); } } } @@ -352,13 +354,12 @@ parseHwLocCache(hwloc_topology_t topo, * \return If the data found makes sense (either in the numa node or the * entire machine) */ -bool -parseHwLocNuma(hwloc_topology_t topo, - HardwareTopology::Machine * machine) +bool parseHwLocNuma(hwloc_topology_t topo, HardwareTopology::Machine* machine) { - const hwloc_obj* root = hwloc_get_root_obj(topo); - std::vector hwlocNumaNodes = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_NUMANODE); - bool topologyOk = true; + const hwloc_obj* root = hwloc_get_root_obj(topo); + std::vector hwlocNumaNodes = + getHwLocDescendantsByType(topo, root, HWLOC_OBJ_NUMANODE); + bool topologyOk = true; if (!hwlocNumaNodes.empty()) { @@ -367,33 +368,39 @@ parseHwLocNuma(hwloc_topology_t topo, for (std::size_t i = 0; i < hwlocNumaNodes.size(); i++) { machine->numa.nodes[i].id = hwlocNumaNodes[i]->logical_index; - machine->numa.nodes[i].memory = getHwLocObjectMemory(hwlocNumaNodes[i]);; + machine->numa.nodes[i].memory = getHwLocObjectMemory(hwlocNumaNodes[i]); + machine->numa.nodes[i].logicalProcessorId.clear(); // Get list of PUs in this numa node. Get from numa node if v1.x.x, get from numa node's parent if 2.x.x -#if GMX_HWLOC_API_VERSION_IS_2XX - std::vector hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i]->parent, HWLOC_OBJ_PU); -#else - std::vector hwlocPUs = getHwLocDescendantsByType(topo, hwlocNumaNodes[i], HWLOC_OBJ_PU); -#endif - for (auto &p : hwlocPUs) +# if GMX_HWLOC_API_VERSION_IS_2XX + std::vector hwlocPUs = + getHwLocDescendantsByType(topo, hwlocNumaNodes[i]->parent, HWLOC_OBJ_PU); +# else + std::vector hwlocPUs = + getHwLocDescendantsByType(topo, hwlocNumaNodes[i], HWLOC_OBJ_PU); +# endif + for (auto& p : hwlocPUs) { machine->numa.nodes[i].logicalProcessorId.push_back(p->os_index); - GMX_RELEASE_ASSERT(p->os_index < machine->logicalProcessors.size(), "OS index of PU in hwloc larger than processor count"); + GMX_RELEASE_ASSERT(p->os_index < machine->logicalProcessors.size(), + "OS index of PU in hwloc larger than processor count"); machine->logicalProcessors[p->os_index].numaNodeId = static_cast(i); std::size_t s = machine->logicalProcessors[p->os_index].socketRankInMachine; std::size_t c = machine->logicalProcessors[p->os_index].coreRankInSocket; - GMX_RELEASE_ASSERT(s < machine->sockets.size(), "Socket index in logicalProcessors larger than socket count"); - GMX_RELEASE_ASSERT(c < machine->sockets[s].cores.size(), "Core index in logicalProcessors larger than core count"); + GMX_RELEASE_ASSERT(s < machine->sockets.size(), + "Socket index in logicalProcessors larger than socket count"); + GMX_RELEASE_ASSERT(c < machine->sockets[s].cores.size(), + "Core index in logicalProcessors larger than core count"); // Set numaNodeId in core too machine->sockets[s].cores[c].numaNodeId = i; } } // Getting the distance matrix -#if GMX_HWLOC_API_VERSION_IS_2XX +# if GMX_HWLOC_API_VERSION_IS_2XX // with hwloc api v. 2.x.x, distances are no longer directly accessible. Need to retrieve and release hwloc_distances_s object // In addition, there can now be multiple types of distances, ie latency, bandwidth. We look only for latency, but have to check // if multiple distance matrices are returned. @@ -401,7 +408,7 @@ parseHwLocNuma(hwloc_topology_t topo, // If only 1 numa node exists, the v2.x.x hwloc api won't have a distances matrix, set manually if (hwlocNumaNodes.size() == 1) { - machine->numa.relativeLatency = { { 1.0 } }; + machine->numa.relativeLatency = { { 1.0 } }; } else { @@ -410,8 +417,8 @@ parseHwLocNuma(hwloc_topology_t topo, // for multiple distances types and therefore multiple distance matrices) unsigned nr = 1; hwloc_distances_get(topo, &nr, &dist, HWLOC_DISTANCES_KIND_MEANS_LATENCY, 0); - // If no distances were found, nr will be 0, otherwise distances will be populated with 1 - // hwloc_distances_s object + // If no distances were found, nr will be 0, otherwise distances will be populated with + // 1 hwloc_distances_s object if (nr > 0 && dist->nbobjs == hwlocNumaNodes.size()) { @@ -421,7 +428,7 @@ parseHwLocNuma(hwloc_topology_t topo, machine->numa.relativeLatency[i].resize(dist->nbobjs); for (std::size_t j = 0; j < dist->nbobjs; j++) { - machine->numa.relativeLatency[i][j] = dist->values[i*dist->nbobjs+j]; + machine->numa.relativeLatency[i][j] = dist->values[i * dist->nbobjs + j]; } } } @@ -432,31 +439,32 @@ parseHwLocNuma(hwloc_topology_t topo, hwloc_distances_release(topo, dist); } - // hwloc-2.x provides latencies as integers, but to make things more similar to the case of a single - // numa node as well as hwloc-1.x, we rescale to relative floating-point values and also set the - // largest relative latency value. + // hwloc-2.x provides latencies as integers, but to make things more similar to the case of + // a single numa node as well as hwloc-1.x, we rescale to relative floating-point values and + // also set the largest relative latency value. // find smallest value in matrix float minLatency = std::numeric_limits::max(); // large number float maxLatency = std::numeric_limits::min(); // 0.0 - for (const auto &v : machine->numa.relativeLatency) + for (const auto& v : machine->numa.relativeLatency) { auto result = std::minmax_element(v.begin(), v.end()); - minLatency = std::min(minLatency, *result.first); - maxLatency = std::max(maxLatency, *result.second); + minLatency = std::min(minLatency, *result.first); + maxLatency = std::max(maxLatency, *result.second); } // assign stuff - for (auto &v : machine->numa.relativeLatency) + for (auto& v : machine->numa.relativeLatency) { - std::transform(v.begin(), v.end(), v.begin(), std::bind(std::multiplies(), std::placeholders::_1, 1.0/minLatency)); + std::transform(v.begin(), v.end(), v.begin(), + std::bind(std::multiplies(), std::placeholders::_1, 1.0 / minLatency)); } - machine->numa.baseLatency = 1.0; // latencies still do not have any units in hwloc-2.x - machine->numa.maxRelativeLatency = maxLatency/minLatency; + machine->numa.baseLatency = 1.0; // latencies still do not have any units in hwloc-2.x + machine->numa.maxRelativeLatency = maxLatency / minLatency; -#else // GMX_HWLOC_API_VERSION_IS_2XX == false, hwloc api is 1.x.x - int depth = hwloc_get_type_depth(topo, HWLOC_OBJ_NUMANODE); - const struct hwloc_distances_s * dist = hwloc_get_whole_distance_matrix_by_depth(topo, depth); +# else // GMX_HWLOC_API_VERSION_IS_2XX == false, hwloc api is 1.x.x + int depth = hwloc_get_type_depth(topo, HWLOC_OBJ_NUMANODE); + const struct hwloc_distances_s* dist = hwloc_get_whole_distance_matrix_by_depth(topo, depth); if (dist != nullptr && dist->nbobjs == hwlocNumaNodes.size()) { machine->numa.baseLatency = dist->latency_base; @@ -467,7 +475,7 @@ parseHwLocNuma(hwloc_topology_t topo, machine->numa.relativeLatency[i].resize(dist->nbobjs); for (std::size_t j = 0; j < dist->nbobjs; j++) { - machine->numa.relativeLatency[i][j] = dist->latency[i*dist->nbobjs+j]; + machine->numa.relativeLatency[i][j] = dist->latency[i * dist->nbobjs + j]; } } } @@ -475,42 +483,42 @@ parseHwLocNuma(hwloc_topology_t topo, { topologyOk = false; } -#endif // end GMX_HWLOC_API_VERSION_IS_2XX == false +# endif // end GMX_HWLOC_API_VERSION_IS_2XX == false } else // Deals with the case of no numa nodes found. -#if GMX_HWLOC_API_VERSION_IS_2XX +# if GMX_HWLOC_API_VERSION_IS_2XX // If the hwloc version is 2.x.x, and there is no numa node, something went wrong { topologyOk = false; } -#else +# else { // No numa nodes found. Use the entire machine as a numa node. // Note that this should only be the case with hwloc api v 1.x.x, // a numa node is assigned to the machine by default in v 2.x.x - const hwloc_obj*const hwlocMachine = hwloc_get_next_obj_by_type(topo, HWLOC_OBJ_MACHINE, nullptr); + const hwloc_obj* const hwlocMachine = hwloc_get_next_obj_by_type(topo, HWLOC_OBJ_MACHINE, nullptr); if (hwlocMachine != nullptr) { machine->numa.nodes.resize(1); - machine->numa.nodes[0].id = 0; - machine->numa.nodes[0].memory = hwlocMachine->memory.total_memory; - machine->numa.baseLatency = 10; - machine->numa.maxRelativeLatency = 1; - machine->numa.relativeLatency = { { 1.0 } }; + machine->numa.nodes[0].id = 0; + machine->numa.nodes[0].memory = hwlocMachine->memory.total_memory; + machine->numa.baseLatency = 10; + machine->numa.maxRelativeLatency = 1; + machine->numa.relativeLatency = { { 1.0 } }; for (int i = 0; i < machine->logicalProcessorCount; i++) { machine->numa.nodes[0].logicalProcessorId.push_back(i); } - for (auto &l : machine->logicalProcessors) + for (auto& l : machine->logicalProcessors) { l.numaNodeId = 0; } - for (auto &s : machine->sockets) + for (auto& s : machine->sockets) { - for (auto &c : s.cores) + for (auto& c : s.cores) { c.numaNodeId = 0; } @@ -521,7 +529,7 @@ parseHwLocNuma(hwloc_topology_t topo, topologyOk = false; } } -#endif // end if not GMX_HWLOC_API_VERSION_IS_2XX +# endif // end if not GMX_HWLOC_API_VERSION_IS_2XX if (!topologyOk) { machine->numa.nodes.clear(); @@ -537,19 +545,17 @@ parseHwLocNuma(hwloc_topology_t topo, * * * \return If any devices were found */ -bool -parseHwLocDevices(hwloc_topology_t topo, - HardwareTopology::Machine * machine) +bool parseHwLocDevices(hwloc_topology_t topo, HardwareTopology::Machine* machine) { - const hwloc_obj * root = hwloc_get_root_obj(topo); + const hwloc_obj* root = hwloc_get_root_obj(topo); std::vector pcidevs = getHwLocDescendantsByType(topo, root, HWLOC_OBJ_PCI_DEVICE); - for (auto &p : pcidevs) + for (auto& p : pcidevs) { -#if GMX_HWLOC_API_VERSION_IS_2XX - const hwloc_obj * ancestor = nullptr; +# if GMX_HWLOC_API_VERSION_IS_2XX + const hwloc_obj* ancestor = nullptr; // Numa nodes not directly part of tree. Walk up the tree until we find an ancestor with a numa node - hwloc_obj_t parent = p->parent; + hwloc_obj_t parent = p->parent; while (parent && !parent->memory_arity) { parent = parent->parent; @@ -558,12 +564,12 @@ parseHwLocDevices(hwloc_topology_t topo, { ancestor = parent->memory_first_child; } -#else // GMX_HWLOC_API_VERSION_IS_2XX = false, api v 1.x.x +# else // GMX_HWLOC_API_VERSION_IS_2XX = false, api v 1.x.x // numa nodes are normal part of tree, can use hwloc ancestor function - const hwloc_obj * const ancestor = hwloc_get_ancestor_obj_by_type(topo, HWLOC_OBJ_NUMANODE, - const_cast(p)); -#endif // end if GMX_HWLOC_API_VERSION_IS_2XX - int numaId; + const hwloc_obj* const ancestor = + hwloc_get_ancestor_obj_by_type(topo, HWLOC_OBJ_NUMANODE, const_cast(p)); +# endif // end if GMX_HWLOC_API_VERSION_IS_2XX + int numaId; if (ancestor != nullptr) { numaId = ancestor->logical_index; @@ -571,31 +577,22 @@ parseHwLocDevices(hwloc_topology_t topo, else { // If we only have a single numa node we belong to it, otherwise set it to -1 (unknown) - numaId = (machine->numa.nodes.size() == 1) ? 0 : -1; + numaId = (machine->numa.nodes.size() == 1) ? 0 : -1; } GMX_RELEASE_ASSERT(p->attr, "Attributes should not be NULL for hwloc PCI object"); - machine->devices.push_back( { - p->attr->pcidev.vendor_id, - p->attr->pcidev.device_id, - p->attr->pcidev.class_id, - p->attr->pcidev.domain, - p->attr->pcidev.bus, - p->attr->pcidev.dev, - p->attr->pcidev.func, - numaId - } ); + machine->devices.push_back({ p->attr->pcidev.vendor_id, p->attr->pcidev.device_id, + p->attr->pcidev.class_id, p->attr->pcidev.domain, + p->attr->pcidev.bus, p->attr->pcidev.dev, p->attr->pcidev.func, + numaId }); } return !pcidevs.empty(); } -void -parseHwLoc(HardwareTopology::Machine * machine, - HardwareTopology::SupportLevel * supportLevel, - bool * isThisSystem) +void parseHwLoc(HardwareTopology::Machine* machine, HardwareTopology::SupportLevel* supportLevel, bool* isThisSystem) { - hwloc_topology_t topo; + hwloc_topology_t topo; // Initialize a hwloc object, set flags to request IO device information too, // try to load the topology, and get the root object. If either step fails, @@ -607,11 +604,11 @@ parseHwLoc(HardwareTopology::Machine * machine, } // Flags to look for io devices -#if GMX_HWLOC_API_VERSION_IS_2XX +# if GMX_HWLOC_API_VERSION_IS_2XX hwloc_topology_set_io_types_filter(topo, HWLOC_TYPE_FILTER_KEEP_IMPORTANT); -#else +# else hwloc_topology_set_flags(topo, HWLOC_TOPOLOGY_FLAG_IO_DEVICES); -#endif +# endif if (hwloc_topology_load(topo) != 0 || hwloc_get_root_obj(topo) == nullptr) { @@ -651,7 +648,7 @@ parseHwLoc(HardwareTopology::Machine * machine, } hwloc_topology_destroy(topo); -// SupportLevel::Full or SupportLevel::FullWithDevices. + // SupportLevel::Full or SupportLevel::FullWithDevices. } #endif @@ -660,8 +657,7 @@ parseHwLoc(HardwareTopology::Machine * machine, * * \return The number of hardware processing units, or 0 if it fails. */ -int -detectLogicalProcessorCount() +int detectLogicalProcessorCount() { int count = 0; @@ -669,7 +665,7 @@ detectLogicalProcessorCount() #if GMX_NATIVE_WINDOWS // Windows SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); + GetSystemInfo(&sysinfo); count = sysinfo.dwNumberOfProcessors; #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) // We are probably on Unix. Check if we have the argument to use before executing any calls @@ -682,7 +678,7 @@ detectLogicalProcessorCount() return count; } -} // namespace +} // namespace // static HardwareTopology HardwareTopology::detect() @@ -721,17 +717,17 @@ HardwareTopology::Machine::Machine() } -HardwareTopology::HardwareTopology() - : supportLevel_(SupportLevel::None), - machine_(), - isThisSystem_(true) +HardwareTopology::HardwareTopology() : + supportLevel_(SupportLevel::None), + machine_(), + isThisSystem_(true) { } -HardwareTopology::HardwareTopology(int logicalProcessorCount) - : supportLevel_(SupportLevel::None), - machine_(), - isThisSystem_(true) +HardwareTopology::HardwareTopology(int logicalProcessorCount) : + supportLevel_(SupportLevel::None), + machine_(), + isThisSystem_(true) { if (logicalProcessorCount > 0) { diff --git a/src/gromacs/hardware/hardwaretopology.h b/src/gromacs/hardware/hardwaretopology.h index 66abb682de..b52ad0a3b0 100644 --- a/src/gromacs/hardware/hardwaretopology.h +++ b/src/gromacs/hardware/hardwaretopology.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,206 +64,200 @@ namespace gmx */ class HardwareTopology { - public: +public: + /*! \brief Amount of topology information present (incremental) */ + enum class SupportLevel + { + None, //!< No hardware information whatsoever. Sorry. + LogicalProcessorCount, //!< Only machine().logicalProcessorCount is valid + Basic, //!< Socket, core and hardware thread info + Full, //!< Cache, memory and numa node info + FullWithDevices //!< Information about devices on the PCI bus + }; - /*! \brief Amount of topology information present (incremental) */ - enum class SupportLevel - { - None, //!< No hardware information whatsoever. Sorry. - LogicalProcessorCount, //!< Only machine().logicalProcessorCount is valid - Basic, //!< Socket, core and hardware thread info - Full, //!< Cache, memory and numa node info - FullWithDevices //!< Information about devices on the PCI bus - }; + /*! \libinternal \brief Information about a single cache level */ + struct Cache + { + int level; //!< Level relative to core (starts at 1) + std::size_t size; //!< size in bytes, 0 if unknown + int linesize; //!< size of each cache line in bytes, 0 if unknown + int associativity; //!< associativity, -1 means fully associative + int shared; //!< Number of logical processors sharing this cache + }; - /*! \libinternal \brief Information about a single cache level */ - struct Cache - { - int level; //!< Level relative to core (starts at 1) - std::size_t size; //!< size in bytes, 0 if unknown - int linesize; //!< size of each cache line in bytes, 0 if unknown - int associativity; //!< associativity, -1 means fully associative - int shared; //!< Number of logical processors sharing this cache - }; + /*! \libinternal \brief Information about a single hardware thread in a core + * + * The id of the thread typically increases continuously as you walk + * through sockets and cores in order of their ids. In general, this can + * be different from the logical processor id provided by the operating + * system. To achieve better load balancing when using SMT, Linux + * typically assigns logical processors in a round-robin fashion + * over all cores. + */ + struct HWThread + { + int id; //!< Absolute id of this thread in hardware topology + int logicalProcessorId; //!< Id of the operating system logical processor + }; - /*! \libinternal \brief Information about a single hardware thread in a core - * - * The id of the thread typically increases continuously as you walk - * through sockets and cores in order of their ids. In general, this can - * be different from the logical processor id provided by the operating - * system. To achieve better load balancing when using SMT, Linux - * typically assigns logical processors in a round-robin fashion - * over all cores. - */ - struct HWThread - { - int id; //!< Absolute id of this thread in hardware topology - int logicalProcessorId; //!< Id of the operating system logical processor - }; + /*! \libinternal \brief Information about a single core in a socket */ + struct Core + { + int id; //!< Absolute id of this core in hardware topology + int numaNodeId; //!< id of the numa node of this core + std::vector hwThreads; //!< All the hardware threads in this core + }; - /*! \libinternal \brief Information about a single core in a socket */ - struct Core - { - int id; //!< Absolute id of this core in hardware topology - int numaNodeId; //!< id of the numa node of this core - std::vector hwThreads; //!< All the hardware threads in this core - }; + /*! \libinternal \brief Information about a single socket in the system */ + struct Socket + { + int id; //!< Absolute id of this socket in hardware topology + std::vector cores; //!< All the cores in this socket + }; - /*! \libinternal \brief Information about a single socket in the system */ - struct Socket - { - int id; //!< Absolute id of this socket in hardware topology - std::vector cores; //!< All the cores in this socket - }; + /*! \libinternal \brief Information about each numa node in system */ + struct NumaNode + { + int id; //!< Absolute id of numa node in hardware topology + std::size_t memory; //!< Total detected memory in bytes + std::vector logicalProcessorId; //!< Vector of all the logical processors in this node + }; - /*! \libinternal \brief Information about each numa node in system */ - struct NumaNode - { - int id; //!< Absolute id of numa node in hardware topology - std::size_t memory; //!< Total detected memory in bytes - std::vector logicalProcessorId; //!< Vector of all the logical processors in this node - }; + /*! \libinternal \brief Information about a single numa node */ + struct Numa + { + std::vector nodes; //!< Information about each numa node + float baseLatency; //!< Scale factor for relative latencies + std::vector> relativeLatency; //!< 2D matrix of relative latencies between nodes + float maxRelativeLatency; //!< Largest relative latency + }; - /*! \libinternal \brief Information about a single numa node */ - struct Numa - { - std::vector nodes; //!< Information about each numa node - float baseLatency; //!< Scale factor for relative latencies - std::vector< std::vector > relativeLatency; //!< 2D matrix of relative latencies between nodes - float maxRelativeLatency; //!< Largest relative latency - }; + /*! \libinternal \brief Information about a single PCI device. + * + * \note On many systems the PCI bus is not directly connected to any numa node. + * For these systems the numaNodeId will be -1, so you cannot rely on this + * number reflecting a specific numa node. + */ + struct Device + { + std::uint16_t vendorId; //!< Vendor identification + std::uint16_t deviceId; //!< Vendor-specific device identification + std::uint16_t classId; //!< class (high 8 bits) and subclass (low 8 bits) + std::uint16_t domain; //!< Domain, usually 0 for PCI bus + std::uint8_t bus; //!< Bus number in domain + std::uint8_t dev; //!< Device on bus + std::uint8_t func; //!< Function id for multi-function devices + int numaNodeId; //!< Numa node, -1 if the bus is not located inside a node + }; - /*! \libinternal \brief Information about a single PCI device. - * - * \note On many systems the PCI bus is not directly connected to any numa node. - * For these systems the numaNodeId will be -1, so you cannot rely on this - * number reflecting a specific numa node. - */ - struct Device - { - std::uint16_t vendorId; //!< Vendor identification - std::uint16_t deviceId; //!< Vendor-specific device identification - std::uint16_t classId; //!< class (high 8 bits) and subclass (low 8 bits) - std::uint16_t domain; //!< Domain, usually 0 for PCI bus - std::uint8_t bus; //!< Bus number in domain - std::uint8_t dev; //!< Device on bus - std::uint8_t func; //!< Function id for multi-function devices - int numaNodeId; //!< Numa node, -1 if the bus is not located inside a node - }; + /*! \libinternal \brief Information about socket, core and hwthread for a logical processor */ + struct LogicalProcessor + { + int socketRankInMachine; //!< Index of socket in machine + int coreRankInSocket; //!< Index of core in socket + int hwThreadRankInCore; //!< Index of hardware thread in core + int numaNodeId; //!< Index of numa node + }; - /*! \libinternal \brief Information about socket, core and hwthread for a logical processor */ - struct LogicalProcessor - { - int socketRankInMachine; //!< Index of socket in machine - int coreRankInSocket; //!< Index of core in socket - int hwThreadRankInCore; //!< Index of hardware thread in core - int numaNodeId; //!< Index of numa node - }; + /*! \libinternal \brief Hardware topology information about the entire machine + * + * The machine structure is a tree with top-down information about all + * sockets, cores, and hardware threads in the system. For example, an + * operating system logical processor index can be found as + * machine.socket[0].core[1].hwthread[2].logicalProcessorId. + * In some cases you might need the opposite lookup, i.e. the physical + * hardware data for a specific logical processor. This is present in the + * logicalProcessor vector for convenience. + * + * \note The logicalProcessor vector will only have non-zero length if the + * support level is SupportLevel::Basic or higher. You cannot use the + * size of this vector to query the number of logical processors on + * lower support levels. + */ + struct Machine + { + Machine(); - /*! \libinternal \brief Hardware topology information about the entire machine - * - * The machine structure is a tree with top-down information about all - * sockets, cores, and hardware threads in the system. For example, an - * operating system logical processor index can be found as - * machine.socket[0].core[1].hwthread[2].logicalProcessorId. - * In some cases you might need the opposite lookup, i.e. the physical - * hardware data for a specific logical processor. This is present in the - * logicalProcessor vector for convenience. - * - * \note The logicalProcessor vector will only have non-zero length if the - * support level is SupportLevel::Basic or higher. You cannot use the - * size of this vector to query the number of logical processors on - * lower support levels. - */ - struct Machine - { - Machine(); + int logicalProcessorCount; //!< Number of logical processors in system + std::vector logicalProcessors; //!< Map logical processors to socket/core + std::vector sockets; //!< All the sockets in the system + std::vector caches; //!< Caches in increasing level order + Numa numa; //!< Structure with all numa information + std::vector devices; //!< Devices on PCI bus + }; - int logicalProcessorCount; //!< Number of logical processors in system - std::vector logicalProcessors; //!< Map logical processors to socket/core - std::vector sockets; //!< All the sockets in the system - std::vector caches; //!< Caches in increasing level order - Numa numa; //!< Structure with all numa information - std::vector devices; //!< Devices on PCI bus - }; +public: + /*! \brief Detects the hardware topology. */ + static HardwareTopology detect(); - public: + /*! \brief Creates a topology with given number of logical cores. + * + * The support level will be either None or LogicalProcessorCount. + * + * Intended for testing of code that uses the hardware topology. + */ + explicit HardwareTopology(int logicalProcessorCount); - /*! \brief Detects the hardware topology. */ - static HardwareTopology detect(); + /*! \brief Check what topology information that is available and valid + * + * The amount of hardware topology information that can be detected depends + * on both the hardware and whether GROMACS was linked with the external + * hwloc library. You cannot assume that any information is present, + * although we can almost always provide the number of logical processors. + * On x86 we can usually get basic information about how sockets, cores + * and hardware threads are ordered even without hwloc. + * With the hwloc library we can usually also get information about cache, + * memory and concepts such as core groups and ccNUMA nodes. + * Finally, if hwloc was built with support for libpci we can also + * detect how the PCI devices are connected. + */ + SupportLevel supportLevel() const { return supportLevel_; } - /*! \brief Creates a topology with given number of logical cores. - * - * The support level will be either None or LogicalProcessorCount. - * - * Intended for testing of code that uses the hardware topology. - */ - explicit HardwareTopology(int logicalProcessorCount); + /*! \brief Return true if we actually detected hardware. + * + * \return This method will normally return true, when we actually ran + * the hardware detection as part of this process to construct + * the object. It will be false when the object was constructed + * by reading a cached XML file, or possibly generated from + * synthetic data. + */ + bool isThisSystem() const { return isThisSystem_; } - /*! \brief Check what topology information that is available and valid - * - * The amount of hardware topology information that can be detected depends - * on both the hardware and whether GROMACS was linked with the external - * hwloc library. You cannot assume that any information is present, - * although we can almost always provide the number of logical processors. - * On x86 we can usually get basic information about how sockets, cores - * and hardware threads are ordered even without hwloc. - * With the hwloc library we can usually also get information about cache, - * memory and concepts such as core groups and ccNUMA nodes. - * Finally, if hwloc was built with support for libpci we can also - * detect how the PCI devices are connected. - */ - SupportLevel - supportLevel() const { return supportLevel_; } + /*! \brief Return the machine topology tree + * + * You can always call this routine, but be aware that some or all contents + * will not be valid unless supportLevel() returns a sufficient level. + * + * - With SupportLevel::LogicalProcessorCount, only the field + * machine.logicalProcessorCount is valid. + * - With SupportLevel::Basic, you can access the vectors of sockets, + * cores, and hardware threads, and query what logical processorId + * each hardware thread corresponds to. + * - SupportLevel::Full adds cache, memory and ccNUMA information. + * - SupportLevel::FullWithDevices also adds the PCI express bus. + * + * While data that is not valid has been initialized to special values, + * you should not rely on those but query the supportLevel() method before + * accessing it. + */ + const Machine& machine() const { return machine_; } - /*! \brief Return true if we actually detected hardware. - * - * \return This method will normally return true, when we actually ran - * the hardware detection as part of this process to construct - * the object. It will be false when the object was constructed - * by reading a cached XML file, or possibly generated from - * synthetic data. - */ - bool - isThisSystem() const { return isThisSystem_; } + /*! \brief Returns the number of cores. + * + * You can always call this routine, but if sufficient support is not + * available, it may return the logical processor count or zero instead + * of the physical core count. + */ + int numberOfCores() const; - /*! \brief Return the machine topology tree - * - * You can always call this routine, but be aware that some or all contents - * will not be valid unless supportLevel() returns a sufficient level. - * - * - With SupportLevel::LogicalProcessorCount, only the field - * machine.logicalProcessorCount is valid. - * - With SupportLevel::Basic, you can access the vectors of sockets, - * cores, and hardware threads, and query what logical processorId - * each hardware thread corresponds to. - * - SupportLevel::Full adds cache, memory and ccNUMA information. - * - SupportLevel::FullWithDevices also adds the PCI express bus. - * - * While data that is not valid has been initialized to special values, - * you should not rely on those but query the supportLevel() method before - * accessing it. - */ - const Machine & - machine() const { return machine_; } +private: + HardwareTopology(); - /*! \brief Returns the number of cores. - * - * You can always call this routine, but if sufficient support is not - * available, it may return the logical processor count or zero instead - * of the physical core count. - */ - int numberOfCores() const; - - private: - - HardwareTopology(); - - SupportLevel supportLevel_; //!< Available topology information - Machine machine_; //!< The machine map - bool isThisSystem_; //!< Machine map is real (vs. cached/synthetic) + SupportLevel supportLevel_; //!< Available topology information + Machine machine_; //!< The machine map + bool isThisSystem_; //!< Machine map is real (vs. cached/synthetic) }; -} // namespace gmx +} // namespace gmx #endif // GMX_HARDWARE_HARDWARETOPOLOGY_H diff --git a/src/gromacs/hardware/hw_info.h b/src/gromacs/hardware/hw_info.h index 15ebfa788e..caf19a5c6e 100644 --- a/src/gromacs/hardware/hw_info.h +++ b/src/gromacs/hardware/hw_info.h @@ -46,7 +46,7 @@ namespace gmx { class CpuInfo; class HardwareTopology; -} // namespace +} // namespace gmx /* Hardware information structure with CPU and GPU information. * It is initialized by gmx_detect_hardware(). @@ -70,27 +70,27 @@ struct gmx_hw_info_t int nthreads_hw_avail; - std::unique_ptr cpuInfo; /* Information about CPU capabilities */ - std::unique_ptr hardwareTopology; /* Information about hardware topology */ + std::unique_ptr cpuInfo; /* Information about CPU capabilities */ + std::unique_ptr hardwareTopology; /* Information about hardware topology */ /* Data reduced through MPI over all physical nodes */ - int nphysicalnode; /* Number of physical nodes */ - int ncore_tot; /* Sum of #cores over all nodes, can be 0 */ - int ncore_min; /* Min #cores over all nodes */ - int ncore_max; /* Max #cores over all nodes */ - int nhwthread_tot; /* Sum of #hwthreads over all nodes */ - int nhwthread_min; /* Min #hwthreads over all nodes */ - int nhwthread_max; /* Max #hwthreads over all nodes */ - int ngpu_compatible_tot; /* Sum of #GPUs over all nodes */ - int ngpu_compatible_min; /* Min #GPUs over all nodes */ - int ngpu_compatible_max; /* Max #GPUs over all nodes */ - - int simd_suggest_min; /* Highest SIMD instruction set supported by all ranks */ - int simd_suggest_max; /* Highest SIMD instruction set supported by at least one rank */ - - gmx_bool bIdenticalGPUs; /* TRUE if all ranks have the same type(s) and order of GPUs */ - bool haveAmdZen1Cpu; /* TRUE when at least one CPU in any of the nodes is AMD Zen of the first generation */ + int nphysicalnode; /* Number of physical nodes */ + int ncore_tot; /* Sum of #cores over all nodes, can be 0 */ + int ncore_min; /* Min #cores over all nodes */ + int ncore_max; /* Max #cores over all nodes */ + int nhwthread_tot; /* Sum of #hwthreads over all nodes */ + int nhwthread_min; /* Min #hwthreads over all nodes */ + int nhwthread_max; /* Max #hwthreads over all nodes */ + int ngpu_compatible_tot; /* Sum of #GPUs over all nodes */ + int ngpu_compatible_min; /* Min #GPUs over all nodes */ + int ngpu_compatible_max; /* Max #GPUs over all nodes */ + + int simd_suggest_min; /* Highest SIMD instruction set supported by all ranks */ + int simd_suggest_max; /* Highest SIMD instruction set supported by at least one rank */ + + gmx_bool bIdenticalGPUs; /* TRUE if all ranks have the same type(s) and order of GPUs */ + bool haveAmdZen1Cpu; /* TRUE when at least one CPU in any of the nodes is AMD Zen of the first generation */ }; @@ -116,25 +116,25 @@ enum class ThreadAffinity struct gmx_hw_opt_t { //! Total number of threads requested (thread-MPI + OpenMP). - int nthreads_tot = 0; + int nthreads_tot = 0; //! Number of thread-MPI threads requested. - int nthreads_tmpi = 0; + int nthreads_tmpi = 0; //! Number of OpenMP threads requested. - int nthreads_omp = 0; + int nthreads_omp = 0; //! Number of OpenMP threads to use on PME_only ranks. - int nthreads_omp_pme = 0; + int nthreads_omp_pme = 0; //! Thread affinity switch, see enum above. ThreadAffinity threadAffinity = ThreadAffinity::Select; //! Logical core pinning stride. - int core_pinning_stride = 0; + int core_pinning_stride = 0; //! Logical core pinning offset. - int core_pinning_offset = 0; + int core_pinning_offset = 0; //! Empty, or a string provided by the user declaring (unique) GPU IDs available for mdrun to use. - std::string gpuIdsAvailable = ""; + std::string gpuIdsAvailable = ""; //! Empty, or a string provided by the user mapping GPU tasks to devices. - std::string userGpuTaskAssignment = ""; + std::string userGpuTaskAssignment = ""; //! Tells whether mdrun is free to choose the total number of threads (by choosing the number of OpenMP and/or thread-MPI threads). - bool totNumThreadsIsAuto; + bool totNumThreadsIsAuto; }; #endif diff --git a/src/gromacs/hardware/identifyavx512fmaunits.cpp b/src/gromacs/hardware/identifyavx512fmaunits.cpp index a5a3b6dc75..3ee4686533 100644 --- a/src/gromacs/hardware/identifyavx512fmaunits.cpp +++ b/src/gromacs/hardware/identifyavx512fmaunits.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,13 +41,13 @@ */ #ifndef GMX_IDENTIFY_AVX512_FMA_UNITS_STANDALONE -#include "gmxpre.h" +# include "gmxpre.h" #endif #include "identifyavx512fmaunits.h" #ifndef GMX_IDENTIFY_AVX512_FMA_UNITS_STANDALONE -#include "config.h" +# include "config.h" #endif #include @@ -57,7 +57,7 @@ #include #ifndef GMX_IDENTIFY_AVX512_FMA_UNITS_STANDALONE -#include "gromacs/hardware/cpuinfo.h" +# include "gromacs/hardware/cpuinfo.h" #endif namespace gmx @@ -78,83 +78,83 @@ namespace * execute 12 FMA and 12 shuffle instructions. * \return Number of cycles used for the loop. */ -uint64_t -timeFmaAndShuffleLoop(uint64_t loopCount) +uint64_t timeFmaAndShuffleLoop(uint64_t loopCount) { uint64_t cycles; // Unfortunately we need to resort to inline ASM since we are // making a choice based on timing, and without efficient optimization // (e.g. when doing debugging) the usual intrinsics are often implemented // as independent load/store operations, which completely screws up timing. - __asm__ __volatile__("\tvpxord %%zmm0, %%zmm0, %%zmm0\n" - "\tvmovaps %%zmm0, %%zmm1\n" - "\tvmovaps %%zmm0, %%zmm2\n" - "\tvmovaps %%zmm0, %%zmm3\n" - "\tvmovaps %%zmm0, %%zmm4\n" - "\tvmovaps %%zmm0, %%zmm5\n" - "\tvmovaps %%zmm0, %%zmm6\n" - "\tvmovaps %%zmm0, %%zmm7\n" - "\tvmovaps %%zmm0, %%zmm8\n" - "\tvmovaps %%zmm0, %%zmm9\n" - "\tvmovaps %%zmm0, %%zmm10\n" - "\tvmovaps %%zmm0, %%zmm11\n" - "\tvpxord %%zmm12, %%zmm12, %%zmm12\n" - "\tvmovaps %%zmm12, %%zmm13\n" - "\tvmovaps %%zmm12, %%zmm14\n" - "\tvmovaps %%zmm12, %%zmm15\n" - "\tvmovaps %%zmm12, %%zmm16\n" - "\tvmovaps %%zmm12, %%zmm17\n" - "\tvmovaps %%zmm12, %%zmm18\n" - "\tvmovaps %%zmm12, %%zmm19\n" - "\tvmovaps %%zmm12, %%zmm20\n" - "\tvmovaps %%zmm12, %%zmm21\n" - "\tvmovaps %%zmm12, %%zmm22\n" - "\tvmovaps %%zmm12, %%zmm23\n" - "\tvmovaps %%zmm12, %%zmm30\n" - "\trdtscp\n" - "\tsalq $32, %%rdx\n" - "\tmovl %%eax, %%eax\n" - "\tmovq %%rdx, %%rbx\n" - "\torq %%rax, %%rbx\n" - "\tmovq %1, %%rdx\n" - "1:\n" - "\tvfmadd231pd %%zmm0, %%zmm0, %%zmm0\n" - "\tvfmadd231pd %%zmm1, %%zmm1, %%zmm1\n" - "\tvfmadd231pd %%zmm2, %%zmm2, %%zmm2\n" - "\tvfmadd231pd %%zmm3, %%zmm3, %%zmm3\n" - "\tvfmadd231pd %%zmm4, %%zmm4, %%zmm4\n" - "\tvfmadd231pd %%zmm5, %%zmm5, %%zmm5\n" - "\tvfmadd231pd %%zmm6, %%zmm6, %%zmm6\n" - "\tvfmadd231pd %%zmm7, %%zmm7, %%zmm7\n" - "\tvfmadd231pd %%zmm8, %%zmm8, %%zmm8\n" - "\tvfmadd231pd %%zmm9, %%zmm9, %%zmm9\n" - "\tvfmadd231pd %%zmm10, %%zmm10, %%zmm10\n" - "\tvfmadd231pd %%zmm11, %%zmm11, %%zmm11\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm12\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm13\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm14\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm15\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm16\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm17\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm18\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm19\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm20\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm21\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm22\n" - "\tvpermd %%zmm30, %%zmm30, %%zmm23\n" - "\tdec %%rdx\n" - "\tjg 1b\n" - "\trdtscp\n" - "\tsalq $32, %%rdx\n" - "\tmovl %%eax, %%eax\n" - "\torq %%rax, %%rdx\n" - "\tsubq %%rbx, %%rdx\n" - "\tmovq %%rdx, %0\n" - : "=r" (cycles) : "r" (loopCount) - : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", - "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", "zmm10", - "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", - "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm30"); + __asm__ __volatile__( + "\tvpxord %%zmm0, %%zmm0, %%zmm0\n" + "\tvmovaps %%zmm0, %%zmm1\n" + "\tvmovaps %%zmm0, %%zmm2\n" + "\tvmovaps %%zmm0, %%zmm3\n" + "\tvmovaps %%zmm0, %%zmm4\n" + "\tvmovaps %%zmm0, %%zmm5\n" + "\tvmovaps %%zmm0, %%zmm6\n" + "\tvmovaps %%zmm0, %%zmm7\n" + "\tvmovaps %%zmm0, %%zmm8\n" + "\tvmovaps %%zmm0, %%zmm9\n" + "\tvmovaps %%zmm0, %%zmm10\n" + "\tvmovaps %%zmm0, %%zmm11\n" + "\tvpxord %%zmm12, %%zmm12, %%zmm12\n" + "\tvmovaps %%zmm12, %%zmm13\n" + "\tvmovaps %%zmm12, %%zmm14\n" + "\tvmovaps %%zmm12, %%zmm15\n" + "\tvmovaps %%zmm12, %%zmm16\n" + "\tvmovaps %%zmm12, %%zmm17\n" + "\tvmovaps %%zmm12, %%zmm18\n" + "\tvmovaps %%zmm12, %%zmm19\n" + "\tvmovaps %%zmm12, %%zmm20\n" + "\tvmovaps %%zmm12, %%zmm21\n" + "\tvmovaps %%zmm12, %%zmm22\n" + "\tvmovaps %%zmm12, %%zmm23\n" + "\tvmovaps %%zmm12, %%zmm30\n" + "\trdtscp\n" + "\tsalq $32, %%rdx\n" + "\tmovl %%eax, %%eax\n" + "\tmovq %%rdx, %%rbx\n" + "\torq %%rax, %%rbx\n" + "\tmovq %1, %%rdx\n" + "1:\n" + "\tvfmadd231pd %%zmm0, %%zmm0, %%zmm0\n" + "\tvfmadd231pd %%zmm1, %%zmm1, %%zmm1\n" + "\tvfmadd231pd %%zmm2, %%zmm2, %%zmm2\n" + "\tvfmadd231pd %%zmm3, %%zmm3, %%zmm3\n" + "\tvfmadd231pd %%zmm4, %%zmm4, %%zmm4\n" + "\tvfmadd231pd %%zmm5, %%zmm5, %%zmm5\n" + "\tvfmadd231pd %%zmm6, %%zmm6, %%zmm6\n" + "\tvfmadd231pd %%zmm7, %%zmm7, %%zmm7\n" + "\tvfmadd231pd %%zmm8, %%zmm8, %%zmm8\n" + "\tvfmadd231pd %%zmm9, %%zmm9, %%zmm9\n" + "\tvfmadd231pd %%zmm10, %%zmm10, %%zmm10\n" + "\tvfmadd231pd %%zmm11, %%zmm11, %%zmm11\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm12\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm13\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm14\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm15\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm16\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm17\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm18\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm19\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm20\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm21\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm22\n" + "\tvpermd %%zmm30, %%zmm30, %%zmm23\n" + "\tdec %%rdx\n" + "\tjg 1b\n" + "\trdtscp\n" + "\tsalq $32, %%rdx\n" + "\tmovl %%eax, %%eax\n" + "\torq %%rax, %%rdx\n" + "\tsubq %%rbx, %%rdx\n" + "\tmovq %%rdx, %0\n" + : "=r"(cycles) + : "r"(loopCount) + : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", + "zmm7", "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", + "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm30"); return cycles; } @@ -170,81 +170,81 @@ timeFmaAndShuffleLoop(uint64_t loopCount) * execute 12 FMA instructions. * \return Number of cycles used for the loop. */ -uint64_t -timeFmaOnlyLoop(uint64_t loopCount) +uint64_t timeFmaOnlyLoop(uint64_t loopCount) { uint64_t cycles; // Unfortunately we need to resort to inline ASM since we are // making a choice based on timing, and without efficient optimization // (e.g. when doing debugging) the usual intrinsics are often implemented // as independent load/store operations, which completely screws up timing. - __asm__ __volatile__("\tvpxord %%zmm0, %%zmm0, %%zmm0\n" - "\tvmovaps %%zmm0, %%zmm1\n" - "\tvmovaps %%zmm0, %%zmm2\n" - "\tvmovaps %%zmm0, %%zmm3\n" - "\tvmovaps %%zmm0, %%zmm4\n" - "\tvmovaps %%zmm0, %%zmm5\n" - "\tvmovaps %%zmm0, %%zmm6\n" - "\tvmovaps %%zmm0, %%zmm7\n" - "\tvmovaps %%zmm0, %%zmm8\n" - "\tvmovaps %%zmm0, %%zmm9\n" - "\tvmovaps %%zmm0, %%zmm10\n" - "\tvmovaps %%zmm0, %%zmm11\n" - "\trdtscp\n" - "\tsalq $32, %%rdx\n" - "\tmovl %%eax, %%eax\n" - "\tmovq %%rdx, %%rbx\n" - "\torq %%rax, %%rbx\n" - "\tmovq %1, %%rdx\n" - "1:\n" - "\tvfmadd231pd %%zmm0, %%zmm0, %%zmm0\n" - "\tvfmadd231pd %%zmm1, %%zmm1, %%zmm1\n" - "\tvfmadd231pd %%zmm2, %%zmm2, %%zmm2\n" - "\tvfmadd231pd %%zmm3, %%zmm3, %%zmm3\n" - "\tvfmadd231pd %%zmm4, %%zmm4, %%zmm4\n" - "\tvfmadd231pd %%zmm5, %%zmm5, %%zmm5\n" - "\tvfmadd231pd %%zmm6, %%zmm6, %%zmm6\n" - "\tvfmadd231pd %%zmm7, %%zmm7, %%zmm7\n" - "\tvfmadd231pd %%zmm8, %%zmm8, %%zmm8\n" - "\tvfmadd231pd %%zmm9, %%zmm9, %%zmm9\n" - "\tvfmadd231pd %%zmm10, %%zmm10, %%zmm10\n" - "\tvfmadd231pd %%zmm11, %%zmm11, %%zmm11\n" - "\tdec %%rdx\n" - "\tjg 1b\n" - "\trdtscp\n" - "\tsalq $32, %%rdx\n" - "\tmovl %%eax, %%eax\n" - "\torq %%rax, %%rdx\n" - "\tsubq %%rbx, %%rdx\n" - "\tmovq %%rdx, %0\n" - : "=r" (cycles) : "r" (loopCount) - : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", - "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", "zmm10", "zmm11"); + __asm__ __volatile__( + "\tvpxord %%zmm0, %%zmm0, %%zmm0\n" + "\tvmovaps %%zmm0, %%zmm1\n" + "\tvmovaps %%zmm0, %%zmm2\n" + "\tvmovaps %%zmm0, %%zmm3\n" + "\tvmovaps %%zmm0, %%zmm4\n" + "\tvmovaps %%zmm0, %%zmm5\n" + "\tvmovaps %%zmm0, %%zmm6\n" + "\tvmovaps %%zmm0, %%zmm7\n" + "\tvmovaps %%zmm0, %%zmm8\n" + "\tvmovaps %%zmm0, %%zmm9\n" + "\tvmovaps %%zmm0, %%zmm10\n" + "\tvmovaps %%zmm0, %%zmm11\n" + "\trdtscp\n" + "\tsalq $32, %%rdx\n" + "\tmovl %%eax, %%eax\n" + "\tmovq %%rdx, %%rbx\n" + "\torq %%rax, %%rbx\n" + "\tmovq %1, %%rdx\n" + "1:\n" + "\tvfmadd231pd %%zmm0, %%zmm0, %%zmm0\n" + "\tvfmadd231pd %%zmm1, %%zmm1, %%zmm1\n" + "\tvfmadd231pd %%zmm2, %%zmm2, %%zmm2\n" + "\tvfmadd231pd %%zmm3, %%zmm3, %%zmm3\n" + "\tvfmadd231pd %%zmm4, %%zmm4, %%zmm4\n" + "\tvfmadd231pd %%zmm5, %%zmm5, %%zmm5\n" + "\tvfmadd231pd %%zmm6, %%zmm6, %%zmm6\n" + "\tvfmadd231pd %%zmm7, %%zmm7, %%zmm7\n" + "\tvfmadd231pd %%zmm8, %%zmm8, %%zmm8\n" + "\tvfmadd231pd %%zmm9, %%zmm9, %%zmm9\n" + "\tvfmadd231pd %%zmm10, %%zmm10, %%zmm10\n" + "\tvfmadd231pd %%zmm11, %%zmm11, %%zmm11\n" + "\tdec %%rdx\n" + "\tjg 1b\n" + "\trdtscp\n" + "\tsalq $32, %%rdx\n" + "\tmovl %%eax, %%eax\n" + "\torq %%rax, %%rdx\n" + "\tsubq %%rbx, %%rdx\n" + "\tmovq %%rdx, %0\n" + : "=r"(cycles) + : "r"(loopCount) + : "rax", "rbx", "rcx", "rdx", "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", + "zmm7", "zmm8", "zmm9", "zmm10", "zmm11"); return cycles; } -bool -checkDualAvx512FmaUnits() +bool checkDualAvx512FmaUnits() { - uint64_t timeFmaAndShuf = static_cast(1e9); // Large value + uint64_t timeFmaAndShuf = static_cast(1e9); // Large value // Make sure the CPU is in AVX512 mode by executing a fairly long loop. // Use the return value to make sure it is not optimized away. Later invocations // use fewer iterations, so they should always be faster. - uint64_t timeFmaOnly = timeFmaOnlyLoop(100000); + uint64_t timeFmaOnly = timeFmaOnlyLoop(100000); // Execute the loops three times for (int i = 0; i < 3; i++) { - timeFmaAndShuf = std::min(timeFmaAndShuf, timeFmaAndShuffleLoop(1000) ); - timeFmaOnly = std::min(timeFmaOnly, timeFmaOnlyLoop(1000) ); + timeFmaAndShuf = std::min(timeFmaAndShuf, timeFmaAndShuffleLoop(1000)); + timeFmaOnly = std::min(timeFmaOnly, timeFmaOnlyLoop(1000)); } return timeFmaAndShuf > 1.5 * timeFmaOnly; } -#endif // GMX_X86_GCC_INLINE_ASM && SIMD_AVX_512_CXX_SUPPORTED +#endif // GMX_X86_GCC_INLINE_ASM && SIMD_AVX_512_CXX_SUPPORTED /*! \brief Mutex to guard the execution of the timing test @@ -254,17 +254,16 @@ checkDualAvx512FmaUnits() */ std::mutex initMutex; -} // namespace +} // namespace -int -identifyAvx512FmaUnits() +int identifyAvx512FmaUnits() { static bool initialized = false; static int result = 0; if (!initialized) { - std::lock_guard lock(initMutex); + std::lock_guard lock(initMutex); if (!initialized) { @@ -298,8 +297,7 @@ identifyAvx512FmaUnits() } // namespace gmx #ifdef GMX_IDENTIFY_AVX512_FMA_UNITS_STANDALONE -int -main() +int main() { printf("%d\n", gmx::identifyAvx512FmaUnits()); return 0; diff --git a/src/gromacs/hardware/identifyavx512fmaunits.h b/src/gromacs/hardware/identifyavx512fmaunits.h index bcd6f13679..5e20d1e307 100644 --- a/src/gromacs/hardware/identifyavx512fmaunits.h +++ b/src/gromacs/hardware/identifyavx512fmaunits.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,6 @@ namespace gmx * not have AVX512 support, or -1 if the test cannot * run because the compiler lacked AVX512 support. */ -int -identifyAvx512FmaUnits(); +int identifyAvx512FmaUnits(); } // namespace gmx diff --git a/src/gromacs/hardware/printhardware.cpp b/src/gromacs/hardware/printhardware.cpp index 432778a025..4596fc770e 100644 --- a/src/gromacs/hardware/printhardware.cpp +++ b/src/gromacs/hardware/printhardware.cpp @@ -60,12 +60,12 @@ #include "gromacs/utility/sysinfo.h" //! Constant used to help minimize preprocessed code -static const bool bGPUBinary = GMX_GPU != GMX_GPU_NONE; +static const bool bGPUBinary = GMX_GPU != GMX_GPU_NONE; /*! \internal \brief * Returns the GPU information text, one GPU per line. */ -static std::string sprint_gpus(const gmx_gpu_info_t &gpu_info) +static std::string sprint_gpus(const gmx_gpu_info_t& gpu_info) { char stmp[STRLEN]; std::vector gpuStrings; @@ -79,23 +79,25 @@ static std::string sprint_gpus(const gmx_gpu_info_t &gpu_info) /* Give a suitable fatal error or warning if the build configuration and runtime CPU do not match. */ -static void -check_use_of_rdtscp_on_this_cpu(const gmx::MDLogger &mdlog, - const gmx::CpuInfo &cpuInfo) +static void check_use_of_rdtscp_on_this_cpu(const gmx::MDLogger& mdlog, const gmx::CpuInfo& cpuInfo) { - bool binaryUsesRdtscp = HAVE_RDTSCP; + bool binaryUsesRdtscp = HAVE_RDTSCP; - const char *programName = gmx::getProgramContext().displayName(); + const char* programName = gmx::getProgramContext().displayName(); if (cpuInfo.supportLevel() < gmx::CpuInfo::SupportLevel::Features) { if (binaryUsesRdtscp) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "The %s executable was compiled to use the rdtscp CPU instruction. " - "We cannot detect the features of your current CPU, but will proceed anyway. " - "If you get a crash, rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake option.", - programName); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "The %s executable was compiled to use the rdtscp CPU instruction. " + "We cannot detect the features of your current CPU, but will proceed " + "anyway. " + "If you get a crash, rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake " + "option.", + programName); } } else @@ -104,35 +106,38 @@ check_use_of_rdtscp_on_this_cpu(const gmx::MDLogger &mdlog, if (!cpuHasRdtscp && binaryUsesRdtscp) { - gmx_fatal(FARGS, "The %s executable was compiled to use the rdtscp CPU instruction. " - "However, this is not supported by the current hardware and continuing would lead to a crash. " + gmx_fatal(FARGS, + "The %s executable was compiled to use the rdtscp CPU instruction. " + "However, this is not supported by the current hardware and continuing would " + "lead to a crash. " "Please rebuild GROMACS with the GMX_USE_RDTSCP=OFF CMake option.", programName); } if (cpuHasRdtscp && !binaryUsesRdtscp) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "The current CPU can measure timings more accurately than the code in\n" - "%s was configured to use. This might affect your simulation\n" - "speed as accurate timings are needed for load-balancing.\n" - "Please consider rebuilding %s with the GMX_USE_RDTSCP=ON CMake option.", - programName, programName); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "The current CPU can measure timings more accurately than the code in\n" + "%s was configured to use. This might affect your simulation\n" + "speed as accurate timings are needed for load-balancing.\n" + "Please consider rebuilding %s with the GMX_USE_RDTSCP=ON CMake " + "option.", + programName, programName); } } } -static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, - bool bFullCpuInfo) +static std::string detected_hardware_string(const gmx_hw_info_t* hwinfo, bool bFullCpuInfo) { - std::string s; + std::string s; - const gmx::CpuInfo &cpuInfo = *hwinfo->cpuInfo; - const gmx::HardwareTopology &hwTop = *hwinfo->hardwareTopology; + const gmx::CpuInfo& cpuInfo = *hwinfo->cpuInfo; + const gmx::HardwareTopology& hwTop = *hwinfo->hardwareTopology; - s = gmx::formatString("\n"); - s += gmx::formatString("Running on %d node%s with total", - hwinfo->nphysicalnode, + s = gmx::formatString("\n"); + s += gmx::formatString("Running on %d node%s with total", hwinfo->nphysicalnode, hwinfo->nphysicalnode == 1 ? "" : "s"); if (hwinfo->ncore_tot > 0) { @@ -141,8 +146,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, s += gmx::formatString(" %d logical cores", hwinfo->nhwthread_tot); if (hwinfo->gpu_info.bDetectGPUs) { - s += gmx::formatString(", %d compatible GPU%s", - hwinfo->ngpu_compatible_tot, + s += gmx::formatString(", %d compatible GPU%s", hwinfo->ngpu_compatible_tot, hwinfo->ngpu_compatible_tot == 1 ? "" : "s"); } else if (bGPUBinary) @@ -171,8 +175,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, s += gmx::formatString("\n"); if (bGPUBinary) { - s += gmx::formatString(" Compatible GPUs per node: %2d", - hwinfo->ngpu_compatible_min); + s += gmx::formatString(" Compatible GPUs per node: %2d", hwinfo->ngpu_compatible_min); if (hwinfo->ngpu_compatible_max > hwinfo->ngpu_compatible_min) { s += gmx::formatString(" - %2d", hwinfo->ngpu_compatible_max); @@ -189,7 +192,8 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, /* This message will also appear with identical GPU types * when at least one node has no GPU. */ - s += gmx::formatString(" Different nodes have different type(s) and/or order of GPUs\n"); + s += gmx::formatString( + " Different nodes have different type(s) and/or order of GPUs\n"); } } } @@ -204,8 +208,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, MPI_Comm_rank(MPI_COMM_WORLD, &rank); // TODO Use a wrapper around MPI_Get_processor_name instead. - s += gmx::formatString("Hardware detected on host %s (the node of MPI rank %d):\n", - host, rank); + s += gmx::formatString("Hardware detected on host %s (the node of MPI rank %d):\n", host, rank); #else s += gmx::formatString("Hardware detected:\n"); #endif @@ -217,11 +220,11 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, if (bFullCpuInfo) { - s += gmx::formatString(" Family: %d Model: %d Stepping: %d\n", - cpuInfo.family(), cpuInfo.model(), cpuInfo.stepping()); + s += gmx::formatString(" Family: %d Model: %d Stepping: %d\n", cpuInfo.family(), + cpuInfo.model(), cpuInfo.stepping()); s += gmx::formatString(" Features:"); - for (auto &f : cpuInfo.featureSet()) + for (auto& f : cpuInfo.featureSet()) { s += gmx::formatString(" %s", gmx::CpuInfo::featureString(f).c_str()); } @@ -250,18 +253,12 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, s += gmx::formatString(" Hardware topology: "); switch (hwTop.supportLevel()) { - case gmx::HardwareTopology::SupportLevel::None: - s += gmx::formatString("None\n"); - break; + case gmx::HardwareTopology::SupportLevel::None: s += gmx::formatString("None\n"); break; case gmx::HardwareTopology::SupportLevel::LogicalProcessorCount: s += gmx::formatString("Only logical processor count\n"); break; - case gmx::HardwareTopology::SupportLevel::Basic: - s += gmx::formatString("Basic\n"); - break; - case gmx::HardwareTopology::SupportLevel::Full: - s += gmx::formatString("Full\n"); - break; + case gmx::HardwareTopology::SupportLevel::Basic: s += gmx::formatString("Basic\n"); break; + case gmx::HardwareTopology::SupportLevel::Full: s += gmx::formatString("Full\n"); break; case gmx::HardwareTopology::SupportLevel::FullWithDevices: s += gmx::formatString("Full, with devices\n"); break; @@ -270,7 +267,7 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, if (!hwTop.isThisSystem()) { s += gmx::formatString(" NOTE: Hardware topology cached or synthetic, not detected.\n"); - if (char *p = std::getenv("HWLOC_XMLFILE")) + if (char* p = std::getenv("HWLOC_XMLFILE")) { s += gmx::formatString(" HWLOC_XMLFILE=%s\n", p); } @@ -282,13 +279,13 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, { s += gmx::formatString(" Sockets, cores, and logical processors:\n"); - for (auto &socket : hwTop.machine().sockets) + for (auto& socket : hwTop.machine().sockets) { s += gmx::formatString(" Socket %2d:", socket.id); - for (auto &c : socket.cores) + for (auto& c : socket.cores) { s += gmx::formatString(" ["); - for (auto &t : c.hwThreads) + for (auto& t : c.hwThreads) { s += gmx::formatString(" %3d", t.logicalProcessorId); } @@ -300,10 +297,10 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, if (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::Full) { s += gmx::formatString(" Numa nodes:\n"); - for (auto &n : hwTop.machine().numa.nodes) + for (auto& n : hwTop.machine().numa.nodes) { s += gmx::formatString(" Node %2d (%zu bytes mem):", n.id, n.memory); - for (auto &l : n.logicalProcessorId) + for (auto& l : n.logicalProcessorId) { s += gmx::formatString(" %3d", l); } @@ -327,19 +324,21 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, s += gmx::formatString(" Caches:\n"); - for (auto &c : hwTop.machine().caches) + for (auto& c : hwTop.machine().caches) { - s += gmx::formatString(" L%d: %zu bytes, linesize %d bytes, assoc. %d, shared %d ways\n", - c.level, c.size, c.linesize, c.associativity, c.shared); + s += gmx::formatString( + " L%d: %zu bytes, linesize %d bytes, assoc. %d, shared %d ways\n", + c.level, c.size, c.linesize, c.associativity, c.shared); } } if (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::FullWithDevices) { s += gmx::formatString(" PCI devices:\n"); - for (auto &d : hwTop.machine().devices) + for (auto& d : hwTop.machine().devices) { - s += gmx::formatString(" %04x:%02x:%02x.%1x Id: %04x:%04x Class: 0x%04x Numa: %d\n", - d.domain, d.bus, d.dev, d.func, d.vendorId, d.deviceId, d.classId, d.numaNodeId); + s += gmx::formatString( + " %04x:%02x:%02x.%1x Id: %04x:%04x Class: 0x%04x Numa: %d\n", d.domain, + d.bus, d.dev, d.func, d.vendorId, d.deviceId, d.classId, d.numaNodeId); } } } @@ -347,19 +346,18 @@ static std::string detected_hardware_string(const gmx_hw_info_t *hwinfo, if (bGPUBinary && hwinfo->gpu_info.n_dev > 0) { s += gmx::formatString(" GPU info:\n"); - s += gmx::formatString(" Number of GPUs detected: %d\n", - hwinfo->gpu_info.n_dev); + s += gmx::formatString(" Number of GPUs detected: %d\n", hwinfo->gpu_info.n_dev); s += sprint_gpus(hwinfo->gpu_info) + "\n"; } return s; } -void gmx_print_detected_hardware(FILE *fplog, +void gmx_print_detected_hardware(FILE* fplog, const bool warnToStdErr, - const gmx::MDLogger &mdlog, - const gmx_hw_info_t *hwinfo) + const gmx::MDLogger& mdlog, + const gmx_hw_info_t* hwinfo) { - const gmx::CpuInfo &cpuInfo = *hwinfo->cpuInfo; + const gmx::CpuInfo& cpuInfo = *hwinfo->cpuInfo; if (fplog != nullptr) { diff --git a/src/gromacs/hardware/printhardware.h b/src/gromacs/hardware/printhardware.h index 17c27c07bb..ed3c77c17b 100644 --- a/src/gromacs/hardware/printhardware.h +++ b/src/gromacs/hardware/printhardware.h @@ -47,9 +47,9 @@ class MDLogger; /* Print information about the detected hardware to fplog (if != NULL) * and to stderr on the master rank of the master simulation. */ -void gmx_print_detected_hardware(FILE *fplog, +void gmx_print_detected_hardware(FILE* fplog, bool warnToStdErr, - const gmx::MDLogger &mdlog, - const gmx_hw_info_t *hwinfo); + const gmx::MDLogger& mdlog, + const gmx_hw_info_t* hwinfo); #endif diff --git a/src/gromacs/hardware/tests/cpuinfo.cpp b/src/gromacs/hardware/tests/cpuinfo.cpp index e90d83606b..53937307d6 100644 --- a/src/gromacs/hardware/tests/cpuinfo.cpp +++ b/src/gromacs/hardware/tests/cpuinfo.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,29 +58,32 @@ TEST(CpuInfoTest, SupportLevel) gmx::CpuInfo c(gmx::CpuInfo::detect()); - std::string commonMsg = - "\nGROMACS might still work, but it will likely hurt your performance." - "\nPlease mail gmx-developers@gromacs.org so we can try to fix it."; + std::string commonMsg = + "\nGROMACS might still work, but it will likely hurt your performance." + "\nPlease mail gmx-developers@gromacs.org so we can try to fix it."; // It is not the end of the world if any of these tests fail (Gromacs will // work fine without cpuinfo), but we might as well flag it so we add it to // our detection code EXPECT_GT(c.supportLevel(), gmx::CpuInfo::SupportLevel::None) - << "No CPU information at all could be detected. " << commonMsg << std::endl; + << "No CPU information at all could be detected. " << commonMsg << std::endl; #if GMX_TARGET_X86 EXPECT_GE(c.supportLevel(), gmx::CpuInfo::SupportLevel::Features) - << "No CPU features could be detected. " << commonMsg << std::endl; + << "No CPU features could be detected. " << commonMsg << std::endl; #endif if (c.supportLevel() >= gmx::CpuInfo::SupportLevel::LogicalProcessorInfo) { // Make sure assigned numbers are reasonable if we have them - for (auto &l : c.logicalProcessors()) + for (auto& l : c.logicalProcessors()) { - EXPECT_GE(l.socketRankInMachine, 0) << "Impossible socket index for logical processor. " << commonMsg << std::endl; - EXPECT_GE(l.coreRankInSocket, 0) << "Impossible core index for logical processor. " << commonMsg << std::endl; - EXPECT_GE(l.hwThreadRankInCore, 0) << "Impossible hwthread index for logical processor. " << commonMsg << std::endl; + EXPECT_GE(l.socketRankInMachine, 0) + << "Impossible socket index for logical processor. " << commonMsg << std::endl; + EXPECT_GE(l.coreRankInSocket, 0) + << "Impossible core index for logical processor. " << commonMsg << std::endl; + EXPECT_GE(l.hwThreadRankInCore, 0) + << "Impossible hwthread index for logical processor. " << commonMsg << std::endl; } } } diff --git a/src/gromacs/hardware/tests/hardwaretopology.cpp b/src/gromacs/hardware/tests/hardwaretopology.cpp index 61afde7935..f8bebdd2e6 100644 --- a/src/gromacs/hardware/tests/hardwaretopology.cpp +++ b/src/gromacs/hardware/tests/hardwaretopology.cpp @@ -73,23 +73,24 @@ TEST(HardwareTopologyTest, Execute) // If we cannot even find the number of logical processors we want to flag it EXPECT_GT(hwTop.supportLevel(), gmx::HardwareTopology::SupportLevel::None) - << "Cannot determine number of processors. " << std::endl - << "GROMACS might still work, but it will likely hurt your performance." << std::endl - << "Please mail gmx-developers@gromacs.org so we can try to fix it."; + << "Cannot determine number of processors. " << std::endl + << "GROMACS might still work, but it will likely hurt your performance." << std::endl + << "Please mail gmx-developers@gromacs.org so we can try to fix it."; } #if GMX_USE_HWLOC TEST(HardwareTopologyTest, HwlocExecute) { -#if defined(__linux__) +# if defined(__linux__) gmx::HardwareTopology hwTop(gmx::HardwareTopology::detect()); // On Linux with hwloc support we should be able to get at least basic information EXPECT_GE(hwTop.supportLevel(), gmx::HardwareTopology::SupportLevel::Basic) - << "Cannot determine basic hardware topology from hwloc. GROMACS will still\n" << std::endl - << "work, but it might affect your performance for large nodes." << std::endl - << "Please mail gmx-developers@gromacs.org so we can try to fix it."; -#endif + << "Cannot determine basic hardware topology from hwloc. GROMACS will still\n" + << std::endl + << "work, but it might affect your performance for large nodes." << std::endl + << "Please mail gmx-developers@gromacs.org so we can try to fix it."; +# endif } #endif @@ -101,37 +102,46 @@ TEST(HardwareTopologyTest, ProcessorSelfconsistency) { SCOPED_TRACE(gmx::formatString("Logical Processor count %d", hwTop.machine().logicalProcessorCount)); - int socketsInMachine = hwTop.machine().sockets.size(); - int coresPerSocket = hwTop.machine().sockets[0].cores.size(); - int hwThreadsPerCore = hwTop.machine().sockets[0].cores[0].hwThreads.size(); + int socketsInMachine = hwTop.machine().sockets.size(); + int coresPerSocket = hwTop.machine().sockets[0].cores.size(); + int hwThreadsPerCore = hwTop.machine().sockets[0].cores[0].hwThreads.size(); auto logicalProcessors = hwTop.machine().logicalProcessors; for (auto logicalProcessorIt = logicalProcessors.begin(); - logicalProcessorIt != logicalProcessors.end(); - ++logicalProcessorIt) + logicalProcessorIt != logicalProcessors.end(); ++logicalProcessorIt) { // Check that logical processor information contains // reasonable values. - SCOPED_TRACE(gmx::formatString("Socket rank in machine: %d", logicalProcessorIt->socketRankInMachine)); - SCOPED_TRACE(gmx::formatString("Core rank in socket: %d", logicalProcessorIt->coreRankInSocket)); - SCOPED_TRACE(gmx::formatString("Hw thread rank in core: %d", logicalProcessorIt->hwThreadRankInCore)); - EXPECT_TRUE(logicalProcessorIt->socketRankInMachine >= 0 && logicalProcessorIt->socketRankInMachine < socketsInMachine); - EXPECT_TRUE(logicalProcessorIt->coreRankInSocket >= 0 && logicalProcessorIt->coreRankInSocket < coresPerSocket); - EXPECT_TRUE(logicalProcessorIt->hwThreadRankInCore >= 0 && logicalProcessorIt->hwThreadRankInCore < hwThreadsPerCore); + SCOPED_TRACE(gmx::formatString("Socket rank in machine: %d", + logicalProcessorIt->socketRankInMachine)); + SCOPED_TRACE(gmx::formatString("Core rank in socket: %d", + logicalProcessorIt->coreRankInSocket)); + SCOPED_TRACE(gmx::formatString("Hw thread rank in core: %d", + logicalProcessorIt->hwThreadRankInCore)); + EXPECT_TRUE(logicalProcessorIt->socketRankInMachine >= 0 + && logicalProcessorIt->socketRankInMachine < socketsInMachine); + EXPECT_TRUE(logicalProcessorIt->coreRankInSocket >= 0 + && logicalProcessorIt->coreRankInSocket < coresPerSocket); + EXPECT_TRUE(logicalProcessorIt->hwThreadRankInCore >= 0 + && logicalProcessorIt->hwThreadRankInCore < hwThreadsPerCore); // Check that logical processor information is distinct // for each logical processor. for (auto remainingLogicalProcessorIt = logicalProcessorIt + 1; - remainingLogicalProcessorIt != logicalProcessors.end(); - ++remainingLogicalProcessorIt) + remainingLogicalProcessorIt != logicalProcessors.end(); ++remainingLogicalProcessorIt) { - SCOPED_TRACE(gmx::formatString("Other socket rank in machine: %d", remainingLogicalProcessorIt->socketRankInMachine)); - SCOPED_TRACE(gmx::formatString("Other core rank in socket: %d", remainingLogicalProcessorIt->coreRankInSocket)); - SCOPED_TRACE(gmx::formatString("Other hw thread rank in core: %d", remainingLogicalProcessorIt->hwThreadRankInCore)); - EXPECT_TRUE((logicalProcessorIt->socketRankInMachine != remainingLogicalProcessorIt->socketRankInMachine) || - (logicalProcessorIt->coreRankInSocket != remainingLogicalProcessorIt->coreRankInSocket) || - (logicalProcessorIt->hwThreadRankInCore != remainingLogicalProcessorIt->hwThreadRankInCore)) << - "This pair of logical processors have the same descriptive information, which is an error"; + SCOPED_TRACE(gmx::formatString("Other socket rank in machine: %d", + remainingLogicalProcessorIt->socketRankInMachine)); + SCOPED_TRACE(gmx::formatString("Other core rank in socket: %d", + remainingLogicalProcessorIt->coreRankInSocket)); + SCOPED_TRACE(gmx::formatString("Other hw thread rank in core: %d", + remainingLogicalProcessorIt->hwThreadRankInCore)); + EXPECT_TRUE((logicalProcessorIt->socketRankInMachine != remainingLogicalProcessorIt->socketRankInMachine) + || (logicalProcessorIt->coreRankInSocket != remainingLogicalProcessorIt->coreRankInSocket) + || (logicalProcessorIt->hwThreadRankInCore + != remainingLogicalProcessorIt->hwThreadRankInCore)) + << "This pair of logical processors have the same descriptive information, " + "which is an error"; } } } @@ -151,7 +161,7 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) // Check that the sum of numa domains is the total processor count int processorsinNumaNudes = 0; - for (auto &n : hwTop.machine().numa.nodes) + for (auto& n : hwTop.machine().numa.nodes) { processorsinNumaNudes += n.logicalProcessorId.size(); } @@ -159,13 +169,13 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) // Check that every processor is in a numa domain (i.e., that they are unique) std::vector v(hwTop.machine().logicalProcessorCount); - for (auto &elem : v) + for (auto& elem : v) { elem = 0; } - for (auto &n : hwTop.machine().numa.nodes) + for (auto& n : hwTop.machine().numa.nodes) { - for (auto &idx : n.logicalProcessorId) + for (auto& idx : n.logicalProcessorId) { v[idx] = 1; } @@ -174,7 +184,7 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) EXPECT_EQ(uniqueProcessorsinNumaNudes, hwTop.machine().logicalProcessorCount); // We must have some memory in a numa node - for (auto &n : hwTop.machine().numa.nodes) + for (auto& n : hwTop.machine().numa.nodes) { EXPECT_GT(n.memory, 0); } @@ -184,11 +194,11 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) EXPECT_GT(hwTop.machine().numa.maxRelativeLatency, 0); // Check number of rows matches # numa nodes EXPECT_EQ(hwTop.machine().numa.relativeLatency.size(), hwTop.machine().numa.nodes.size()); - for (auto &v2 : hwTop.machine().numa.relativeLatency) + for (auto& v2 : hwTop.machine().numa.relativeLatency) { // Check that size of each row matches # numa nodes EXPECT_EQ(v2.size(), hwTop.machine().numa.nodes.size()); - for (auto &latency : v2) + for (auto& latency : v2) { // Latency values should be positive EXPECT_GT(latency, 0); @@ -197,7 +207,7 @@ TEST(HardwareTopologyTest, NumaCacheSelfconsistency) // Check cache. The hwloc cache detection is fragile and can report // 0 for line size or associativity (=unknown), so we just check the size. - for (auto &c : hwTop.machine().caches) + for (auto& c : hwTop.machine().caches) { EXPECT_GT(c.size, 0); } diff --git a/src/gromacs/imd/imd.cpp b/src/gromacs/imd/imd.cpp index d80b4a181b..1d03d00a1d 100644 --- a/src/gromacs/imd/imd.cpp +++ b/src/gromacs/imd/imd.cpp @@ -111,16 +111,16 @@ constexpr int c_protocolVersion = 2; */ typedef struct { - int32_t tstep; /**< time step */ - float T_abs; /**< absolute temperature */ - float E_tot; /**< total energy */ - float E_pot; /**< potential energy */ - float E_vdw; /**< van der Waals energy */ - float E_coul; /**< Coulomb interaction energy */ - float E_bond; /**< bonds energy */ - float E_angle; /**< angles energy */ - float E_dihe; /**< dihedrals energy */ - float E_impr; /**< improper dihedrals energy */ + int32_t tstep; /**< time step */ + float T_abs; /**< absolute temperature */ + float E_tot; /**< total energy */ + float E_pot; /**< potential energy */ + float E_vdw; /**< van der Waals energy */ + float E_coul; /**< Coulomb interaction energy */ + float E_bond; /**< bonds energy */ + float E_angle; /**< angles energy */ + float E_dihe; /**< dihedrals energy */ + float E_impr; /**< improper dihedrals energy */ } IMDEnergyBlock; @@ -131,8 +131,8 @@ typedef struct */ typedef struct { - int32_t type; /**< Type of IMD message, see IMDType_t above */ - int32_t length; /**< Length */ + int32_t type; /**< Type of IMD message, see IMDType_t above */ + int32_t length; /**< Length */ } IMDHeader; @@ -145,176 +145,169 @@ typedef struct */ class ImdSession::Impl { - public: - //! Constructor - Impl(const MDLogger &mdlog); - ~Impl(); - - /*! \brief Prepare the socket on the MASTER. */ - void prepareMasterSocket(); - /*! \brief Disconnect the client. */ - void disconnectClient(); - /*! \brief Prints an error message and disconnects the client. - * - * Does not terminate mdrun! - */ - void issueFatalError(const char *msg); - /*! \brief Check whether we got an incoming connection. */ - bool tryConnect(); - /*! \brief Wrap imd_tryconnect in order to make it blocking. - * - * Used when the simulation should wait for an incoming connection. - */ - void blockConnect(); - /*! \brief Make sure that our array holding the forces received via IMD is large enough. */ - void prepareVmdForces(); - /*! \brief Reads forces received via IMD. */ - void readVmdForces(); - /*! \brief Prepares the MD force arrays. */ - void prepareMDForces(); - /*! \brief Copy IMD forces to MD forces. - * - * Do conversion from Cal->Joule and from - * Angstrom -> nm and from a pointer array to arrays to 3*N array. - */ - void copyToMDForces(); - /*! \brief Return true if any of the forces or indices changed. */ - bool bForcesChanged() const; - /*! \brief Update the old_f_ind and old_forces arrays to contain the current values. */ - void keepOldValues(); - /*! \brief Write the applied pull forces to logfile. - * - * Call on master only! - */ - void outputForces(double time); - /*! \brief Synchronize the nodes. */ - void syncNodes(const t_commrec *cr, double t); - /*! \brief Reads header from the client and decides what to do. */ - void readCommand(); - /*! \brief Open IMD output file and write header information. - * - * Call on master only. - */ - void openOutputFile(const char *fn, - int nat_total, - const gmx_output_env_t *oenv, - StartingBehavior startingBehavior); - /*! \brief Creates the molecule start-end position array of molecules in the IMD group. */ - void prepareMoleculesInImdGroup(const gmx_mtop_t *top_global); - /*! \brief Removes shifts of molecules diffused outside of the box. */ - void removeMolecularShifts(const matrix box); - /*! \brief Initialize arrays used to assemble the positions from the other nodes. */ - void prepareForPositionAssembly(const t_commrec *cr, const rvec x[]); - /*! \brief Interact with any connected VMD session */ - bool run(int64_t step, - bool bNS, - const matrix box, - const rvec x[], - double t); - - // TODO rename all the data members to have underscore suffixes - - //! True if tpr and mdrun input combine to permit IMD sessions - bool sessionPossible = false; - //! Output file for IMD data, mainly forces. - FILE *outf = nullptr; - - //! Number of atoms that can be pulled via IMD. - int nat = 0; - //! Part of the atoms that are local. - int nat_loc = 0; - //! Global indices of the IMD atoms. - int *ind = nullptr; - //! Local indices of the IMD atoms. - int *ind_loc = nullptr; - //! Allocation size for ind_loc. - int nalloc_loc = 0; - //! Positions for all IMD atoms assembled on the master node. - rvec *xa = nullptr; - //! Shifts for all IMD atoms, to make molecule(s) whole. - ivec *xa_shifts = nullptr; - //! Extra shifts since last DD step. - ivec *xa_eshifts = nullptr; - //! Old positions for all IMD atoms on master. - rvec *xa_old = nullptr; - //! Position of each local atom in the collective array. - int *xa_ind = nullptr; - - //! Global IMD frequency, known to all ranks. - int nstimd = 1; - //! New frequency from IMD client, master only. - int nstimd_new = 1; - //! Default IMD frequency when disconnected. - int defaultNstImd = -1; - - //! Port to use for network socket. - int port = 0; - //! The IMD socket on the master node. - IMDSocket *socket = nullptr; - //! The IMD socket on the client. - IMDSocket *clientsocket = nullptr; - //! Length we got with last header. - int length = 0; - - //! Shall we block and wait for connection? - bool bWConnect = false; - //! Set if MD is terminated. - bool bTerminated = false; - //! Set if MD can be terminated. - bool bTerminatable = false; - //! Set if connection is present. - bool bConnected = false; - //! Set if we received new forces. - bool bNewForces = false; - //! Set if pulling from VMD is allowed. - bool bForceActivated = false; - - //! Pointer to energies we send back. - IMDEnergyBlock *energies = nullptr; - - //! Number of VMD forces. - int32_t vmd_nforces = 0; - //! VMD forces indices. - int32_t *vmd_f_ind = nullptr; - //! The VMD forces flat in memory. - float *vmd_forces = nullptr; - //! Number of actual MD forces; this gets communicated to the clients. - int nforces = 0; - //! Force indices. - int *f_ind = nullptr; - //! The IMD pulling forces. - rvec *f = nullptr; - - //! Buffer for force sending. - char *forcesendbuf = nullptr; - //! Buffer for coordinate sending. - char *coordsendbuf = nullptr; - //! Send buffer for energies. - char *energysendbuf = nullptr; - //! Buffer to make molecules whole before sending. - rvec *sendxbuf = nullptr; - - //! Molecules block in IMD group. - t_block mols; - - /* The next block is used on the master node only to reduce the output - * without sacrificing information. If any of these values changes, - * we need to write output */ - //! Old value for nforces. - int old_nforces = 0; - //! Old values for force indices. - int *old_f_ind = nullptr; - //! Old values for IMD pulling forces. - rvec *old_forces = nullptr; - - //! Logger - const MDLogger &mdlog; - //! Commmunication object - const t_commrec *cr = nullptr; - //! Wallcycle counting manager. - gmx_wallcycle *wcycle = nullptr; - //! Energy output handler - gmx_enerdata_t *enerd = nullptr; +public: + //! Constructor + Impl(const MDLogger& mdlog); + ~Impl(); + + /*! \brief Prepare the socket on the MASTER. */ + void prepareMasterSocket(); + /*! \brief Disconnect the client. */ + void disconnectClient(); + /*! \brief Prints an error message and disconnects the client. + * + * Does not terminate mdrun! + */ + void issueFatalError(const char* msg); + /*! \brief Check whether we got an incoming connection. */ + bool tryConnect(); + /*! \brief Wrap imd_tryconnect in order to make it blocking. + * + * Used when the simulation should wait for an incoming connection. + */ + void blockConnect(); + /*! \brief Make sure that our array holding the forces received via IMD is large enough. */ + void prepareVmdForces(); + /*! \brief Reads forces received via IMD. */ + void readVmdForces(); + /*! \brief Prepares the MD force arrays. */ + void prepareMDForces(); + /*! \brief Copy IMD forces to MD forces. + * + * Do conversion from Cal->Joule and from + * Angstrom -> nm and from a pointer array to arrays to 3*N array. + */ + void copyToMDForces(); + /*! \brief Return true if any of the forces or indices changed. */ + bool bForcesChanged() const; + /*! \brief Update the old_f_ind and old_forces arrays to contain the current values. */ + void keepOldValues(); + /*! \brief Write the applied pull forces to logfile. + * + * Call on master only! + */ + void outputForces(double time); + /*! \brief Synchronize the nodes. */ + void syncNodes(const t_commrec* cr, double t); + /*! \brief Reads header from the client and decides what to do. */ + void readCommand(); + /*! \brief Open IMD output file and write header information. + * + * Call on master only. + */ + void openOutputFile(const char* fn, int nat_total, const gmx_output_env_t* oenv, StartingBehavior startingBehavior); + /*! \brief Creates the molecule start-end position array of molecules in the IMD group. */ + void prepareMoleculesInImdGroup(const gmx_mtop_t* top_global); + /*! \brief Removes shifts of molecules diffused outside of the box. */ + void removeMolecularShifts(const matrix box); + /*! \brief Initialize arrays used to assemble the positions from the other nodes. */ + void prepareForPositionAssembly(const t_commrec* cr, const rvec x[]); + /*! \brief Interact with any connected VMD session */ + bool run(int64_t step, bool bNS, const matrix box, const rvec x[], double t); + + // TODO rename all the data members to have underscore suffixes + + //! True if tpr and mdrun input combine to permit IMD sessions + bool sessionPossible = false; + //! Output file for IMD data, mainly forces. + FILE* outf = nullptr; + + //! Number of atoms that can be pulled via IMD. + int nat = 0; + //! Part of the atoms that are local. + int nat_loc = 0; + //! Global indices of the IMD atoms. + int* ind = nullptr; + //! Local indices of the IMD atoms. + int* ind_loc = nullptr; + //! Allocation size for ind_loc. + int nalloc_loc = 0; + //! Positions for all IMD atoms assembled on the master node. + rvec* xa = nullptr; + //! Shifts for all IMD atoms, to make molecule(s) whole. + ivec* xa_shifts = nullptr; + //! Extra shifts since last DD step. + ivec* xa_eshifts = nullptr; + //! Old positions for all IMD atoms on master. + rvec* xa_old = nullptr; + //! Position of each local atom in the collective array. + int* xa_ind = nullptr; + + //! Global IMD frequency, known to all ranks. + int nstimd = 1; + //! New frequency from IMD client, master only. + int nstimd_new = 1; + //! Default IMD frequency when disconnected. + int defaultNstImd = -1; + + //! Port to use for network socket. + int port = 0; + //! The IMD socket on the master node. + IMDSocket* socket = nullptr; + //! The IMD socket on the client. + IMDSocket* clientsocket = nullptr; + //! Length we got with last header. + int length = 0; + + //! Shall we block and wait for connection? + bool bWConnect = false; + //! Set if MD is terminated. + bool bTerminated = false; + //! Set if MD can be terminated. + bool bTerminatable = false; + //! Set if connection is present. + bool bConnected = false; + //! Set if we received new forces. + bool bNewForces = false; + //! Set if pulling from VMD is allowed. + bool bForceActivated = false; + + //! Pointer to energies we send back. + IMDEnergyBlock* energies = nullptr; + + //! Number of VMD forces. + int32_t vmd_nforces = 0; + //! VMD forces indices. + int32_t* vmd_f_ind = nullptr; + //! The VMD forces flat in memory. + float* vmd_forces = nullptr; + //! Number of actual MD forces; this gets communicated to the clients. + int nforces = 0; + //! Force indices. + int* f_ind = nullptr; + //! The IMD pulling forces. + rvec* f = nullptr; + + //! Buffer for force sending. + char* forcesendbuf = nullptr; + //! Buffer for coordinate sending. + char* coordsendbuf = nullptr; + //! Send buffer for energies. + char* energysendbuf = nullptr; + //! Buffer to make molecules whole before sending. + rvec* sendxbuf = nullptr; + + //! Molecules block in IMD group. + t_block mols; + + /* The next block is used on the master node only to reduce the output + * without sacrificing information. If any of these values changes, + * we need to write output */ + //! Old value for nforces. + int old_nforces = 0; + //! Old values for force indices. + int* old_f_ind = nullptr; + //! Old values for IMD pulling forces. + rvec* old_forces = nullptr; + + //! Logger + const MDLogger& mdlog; + //! Commmunication object + const t_commrec* cr = nullptr; + //! Wallcycle counting manager. + gmx_wallcycle* wcycle = nullptr; + //! Energy output handler + gmx_enerdata_t* enerd = nullptr; }; /*! \internal @@ -328,9 +321,9 @@ class ImdSession::Impl class InteractiveMolecularDynamics final : public IMDModule { // From IMDModule - IMdpOptionProvider *mdpOptionProvider() override { return nullptr; } - IMDOutputProvider *outputProvider() override { return nullptr; } - void initForceProviders(ForceProviders * /* forceProviders */) override {} + IMdpOptionProvider* mdpOptionProvider() override { return nullptr; } + IMDOutputProvider* outputProvider() override { return nullptr; } + void initForceProviders(ForceProviders* /* forceProviders */) override {} }; std::unique_ptr createInteractiveMolecularDynamicsModule() @@ -344,40 +337,30 @@ std::unique_ptr createInteractiveMolecularDynamicsModule() */ typedef enum IMDType_t { - IMD_DISCONNECT, /**< client disconnect */ - IMD_ENERGIES, /**< energy data */ - IMD_FCOORDS, /**< atomic coordinates */ - IMD_GO, /**< start command for the simulation */ - IMD_HANDSHAKE, /**< handshake to determine little/big endianness */ - IMD_KILL, /**< terminates the simulation */ - IMD_MDCOMM, /**< force data */ - IMD_PAUSE, /**< pauses the simulation */ - IMD_TRATE, /**< sets the IMD transmission and processing rate */ - IMD_IOERROR, /**< I/O error */ - IMD_NR /**< number of entries */ + IMD_DISCONNECT, /**< client disconnect */ + IMD_ENERGIES, /**< energy data */ + IMD_FCOORDS, /**< atomic coordinates */ + IMD_GO, /**< start command for the simulation */ + IMD_HANDSHAKE, /**< handshake to determine little/big endianness */ + IMD_KILL, /**< terminates the simulation */ + IMD_MDCOMM, /**< force data */ + IMD_PAUSE, /**< pauses the simulation */ + IMD_TRATE, /**< sets the IMD transmission and processing rate */ + IMD_IOERROR, /**< I/O error */ + IMD_NR /**< number of entries */ } IMDMessageType; /*! \brief Names of the IMDType for error messages. */ -static const char *eIMDType_names[IMD_NR + 1] = { - "IMD_DISCONNECT", - "IMD_ENERGIES", - "IMD_FCOORDS", - "IMD_GO", - "IMD_HANDSHAKE", - "IMD_KILL", - "IMD_MDCOMM", - "IMD_PAUSE", - "IMD_TRATE", - "IMD_IOERROR", - nullptr -}; - +static const char* eIMDType_names[IMD_NR + 1] = { "IMD_DISCONNECT", "IMD_ENERGIES", "IMD_FCOORDS", + "IMD_GO", "IMD_HANDSHAKE", "IMD_KILL", + "IMD_MDCOMM", "IMD_PAUSE", "IMD_TRATE", + "IMD_IOERROR", nullptr }; /*! \brief Fills the header with message and the length argument. */ -static void fill_header(IMDHeader *header, IMDMessageType type, int32_t length) +static void fill_header(IMDHeader* header, IMDMessageType type, int32_t length) { /* We (ab-)use htonl network function for the correct endianness */ header->type = imd_htonl(static_cast(type)); @@ -386,7 +369,7 @@ static void fill_header(IMDHeader *header, IMDMessageType type, int32_t length) /*! \brief Swaps the endianess of the header. */ -static void swap_header(IMDHeader *header) +static void swap_header(IMDHeader* header) { /* and vice versa... */ header->type = imd_ntohl(header->type); @@ -395,7 +378,7 @@ static void swap_header(IMDHeader *header) /*! \brief Reads multiple bytes from socket. */ -static int32_t imd_read_multiple(IMDSocket *socket, char *datptr, int32_t toread) +static int32_t imd_read_multiple(IMDSocket* socket, char* datptr, int32_t toread) { int32_t leftcount, countread; @@ -424,8 +407,8 @@ static int32_t imd_read_multiple(IMDSocket *socket, char *datptr, int32_t toread break; } leftcount -= countread; - datptr += countread; - } /* end while */ + datptr += countread; + } /* end while */ /* return nr of bytes read */ return toread - leftcount; @@ -433,7 +416,7 @@ static int32_t imd_read_multiple(IMDSocket *socket, char *datptr, int32_t toread /*! \brief Writes multiple bytes to socket in analogy to imd_read_multiple. */ -static int32_t imd_write_multiple(IMDSocket *socket, const char *datptr, int32_t towrite) +static int32_t imd_write_multiple(IMDSocket* socket, const char* datptr, int32_t towrite) { int32_t leftcount, countwritten; @@ -453,15 +436,15 @@ static int32_t imd_write_multiple(IMDSocket *socket, const char *datptr, int32_t } } leftcount -= countwritten; - datptr += countwritten; - } /* end while */ + datptr += countwritten; + } /* end while */ return towrite - leftcount; } /*! \brief Handshake with IMD client. */ -static int imd_handshake(IMDSocket *socket) +static int imd_handshake(IMDSocket* socket) { IMDHeader header; @@ -469,18 +452,19 @@ static int imd_handshake(IMDSocket *socket) fill_header(&header, IMD_HANDSHAKE, 1); header.length = c_protocolVersion; /* client wants unswapped version */ - return static_cast(imd_write_multiple(socket, reinterpret_cast(&header), c_headerSize) != c_headerSize); + return static_cast(imd_write_multiple(socket, reinterpret_cast(&header), c_headerSize) + != c_headerSize); } /*! \brief Send energies using the energy block and the send buffer. */ -static int imd_send_energies(IMDSocket *socket, const IMDEnergyBlock *energies, char *buffer) +static int imd_send_energies(IMDSocket* socket, const IMDEnergyBlock* energies, char* buffer) { int32_t recsize; recsize = c_headerSize + sizeof(IMDEnergyBlock); - fill_header(reinterpret_cast(buffer), IMD_ENERGIES, 1); + fill_header(reinterpret_cast(buffer), IMD_ENERGIES, 1); memcpy(buffer + c_headerSize, energies, sizeof(IMDEnergyBlock)); return static_cast(imd_write_multiple(socket, buffer, recsize) != recsize); @@ -488,12 +472,12 @@ static int imd_send_energies(IMDSocket *socket, const IMDEnergyBlock *energies, /*! \brief Receive IMD header from socket, sets the length and returns the IMD message. */ -static IMDMessageType imd_recv_header(IMDSocket *socket, int32_t *length) +static IMDMessageType imd_recv_header(IMDSocket* socket, int32_t* length) { IMDHeader header; - if (imd_read_multiple(socket, reinterpret_cast(&header), c_headerSize) != c_headerSize) + if (imd_read_multiple(socket, reinterpret_cast(&header), c_headerSize) != c_headerSize) { return IMD_IOERROR; } @@ -508,11 +492,11 @@ static IMDMessageType imd_recv_header(IMDSocket *socket, int32_t *length) * * The number of forces was previously communicated via the header. */ -static bool imd_recv_mdcomm(IMDSocket *socket, int32_t nforces, int32_t *forcendx, float *forces) +static bool imd_recv_mdcomm(IMDSocket* socket, int32_t nforces, int32_t* forcendx, float* forces) { /* reading indices */ int retsize = sizeof(int32_t) * nforces; - int retbytes = imd_read_multiple(socket, reinterpret_cast(forcendx), retsize); + int retbytes = imd_read_multiple(socket, reinterpret_cast(forcendx), retsize); if (retbytes != retsize) { return false; @@ -520,13 +504,17 @@ static bool imd_recv_mdcomm(IMDSocket *socket, int32_t nforces, int32_t *forcend /* reading forces as float array */ retsize = 3 * sizeof(float) * nforces; - retbytes = imd_read_multiple(socket, reinterpret_cast(forces), retsize); + retbytes = imd_read_multiple(socket, reinterpret_cast(forces), retsize); return (retbytes == retsize); } /* GROMACS specific functions for the IMD implementation */ -void write_IMDgroup_to_file(bool bIMD, t_inputrec *ir, const t_state *state, - const gmx_mtop_t *sys, int nfile, const t_filenm fnm[]) +void write_IMDgroup_to_file(bool bIMD, + t_inputrec* ir, + const t_state* state, + const gmx_mtop_t* sys, + int nfile, + const t_filenm fnm[]) { t_atoms IMDatoms; @@ -534,22 +522,21 @@ void write_IMDgroup_to_file(bool bIMD, t_inputrec *ir, const t_state *state, if (bIMD) { IMDatoms = gmx_mtop_global_atoms(sys); - write_sto_conf_indexed(opt2fn("-imd", nfile, fnm), "IMDgroup", &IMDatoms, - state->x.rvec_array(), state->v.rvec_array(), ir->ePBC, state->box, ir->imd->nat, ir->imd->ind); + write_sto_conf_indexed(opt2fn("-imd", nfile, fnm), "IMDgroup", &IMDatoms, state->x.rvec_array(), + state->v.rvec_array(), ir->ePBC, state->box, ir->imd->nat, ir->imd->ind); } } -void -ImdSession::dd_make_local_IMD_atoms(const gmx_domdec_t *dd) +void ImdSession::dd_make_local_IMD_atoms(const gmx_domdec_t* dd) { if (!impl_->sessionPossible) { return; } - dd_make_local_group_indices(dd->ga2la, impl_->nat, impl_->ind, &impl_->nat_loc, - &impl_->ind_loc, &impl_->nalloc_loc, impl_->xa_ind); + dd_make_local_group_indices(dd->ga2la, impl_->nat, impl_->ind, &impl_->nat_loc, &impl_->ind_loc, + &impl_->nalloc_loc, impl_->xa_ind); } @@ -557,19 +544,19 @@ ImdSession::dd_make_local_IMD_atoms(const gmx_domdec_t *dd) * * We need a separate send buffer and conversion to Angstrom. */ -static int imd_send_rvecs(IMDSocket *socket, int nat, rvec *x, char *buffer) +static int imd_send_rvecs(IMDSocket* socket, int nat, rvec* x, char* buffer) { - int32_t size; - int i; - float sendx[3]; - int tuplesize = 3 * sizeof(float); + int32_t size; + int i; + float sendx[3]; + int tuplesize = 3 * sizeof(float); /* Required size for the send buffer */ size = c_headerSize + 3 * sizeof(float) * nat; /* Prepare header */ - fill_header(reinterpret_cast(buffer), IMD_FCOORDS, static_cast(nat)); + fill_header(reinterpret_cast(buffer), IMD_FCOORDS, static_cast(nat)); for (i = 0; i < nat; i++) { sendx[0] = static_cast(x[i][0]) * NM2A; @@ -582,8 +569,7 @@ static int imd_send_rvecs(IMDSocket *socket, int nat, rvec *x, char *buffer) } -void -ImdSession::Impl::prepareMasterSocket() +void ImdSession::Impl::prepareMasterSocket() { if (imdsock_winsockinit() == -1) { @@ -619,8 +605,7 @@ ImdSession::Impl::prepareMasterSocket() } -void -ImdSession::Impl::disconnectClient() +void ImdSession::Impl::disconnectClient() { /* Write out any buffered pulling data */ fflush(outf); @@ -639,8 +624,7 @@ ImdSession::Impl::disconnectClient() } -void -ImdSession::Impl::issueFatalError(const char *msg) +void ImdSession::Impl::issueFatalError(const char* msg) { GMX_LOG(mdlog.warning).appendTextFormatted("%s %s", IMDstr, msg); disconnectClient(); @@ -648,8 +632,7 @@ ImdSession::Impl::issueFatalError(const char *msg) } -bool -ImdSession::Impl::tryConnect() +bool ImdSession::Impl::tryConnect() { if (imdsock_tryread(socket, 0, 0) > 0) { @@ -657,7 +640,8 @@ ImdSession::Impl::tryConnect() clientsocket = imdsock_accept(socket); if (!clientsocket) { - GMX_LOG(mdlog.warning).appendTextFormatted("%s Accepting the connection on the socket failed.", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted("%s Accepting the connection on the socket failed.", IMDstr); return false; } @@ -668,10 +652,12 @@ ImdSession::Impl::tryConnect() return false; } - GMX_LOG(mdlog.warning).appendTextFormatted("%s Connection established, checking if I got IMD_GO orders.", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted("%s Connection established, checking if I got IMD_GO orders.", IMDstr); /* Check if we get the proper "GO" command from client. */ - if (imdsock_tryread(clientsocket, c_connectWait, 0) != 1 || imd_recv_header(clientsocket, &(length)) != IMD_GO) + if (imdsock_tryread(clientsocket, c_connectWait, 0) != 1 + || imd_recv_header(clientsocket, &(length)) != IMD_GO) { issueFatalError("No IMD_GO order received. IMD connection failed."); } @@ -686,8 +672,7 @@ ImdSession::Impl::tryConnect() } -void -ImdSession::Impl::blockConnect() +void ImdSession::Impl::blockConnect() { /* do not wait for connection, when e.g. ctrl+c is pressed and we will terminate anyways. */ if (!(static_cast(gmx_get_stop_condition()) == gmx_stop_cond_none)) @@ -695,7 +680,8 @@ ImdSession::Impl::blockConnect() return; } - GMX_LOG(mdlog.warning).appendTextFormatted("%s Will wait until I have a connection and IMD_GO orders.", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted("%s Will wait until I have a connection and IMD_GO orders.", IMDstr); /* while we have no clientsocket... 2nd part: we should still react on ctrl+c */ while ((!clientsocket) && (static_cast(gmx_get_stop_condition()) == gmx_stop_cond_none)) @@ -706,16 +692,14 @@ ImdSession::Impl::blockConnect() } -void -ImdSession::Impl::prepareVmdForces() +void ImdSession::Impl::prepareVmdForces() { srenew((vmd_f_ind), vmd_nforces); - srenew((vmd_forces), 3*vmd_nforces); + srenew((vmd_forces), 3 * vmd_nforces); } -void -ImdSession::Impl::readVmdForces() +void ImdSession::Impl::readVmdForces() { /* the length of the previously received header tells us the nr of forces we will receive */ vmd_nforces = length; @@ -729,16 +713,14 @@ ImdSession::Impl::readVmdForces() } -void -ImdSession::Impl::prepareMDForces() +void ImdSession::Impl::prepareMDForces() { srenew((f_ind), nforces); - srenew((f ), nforces); + srenew((f), nforces); } -void -ImdSession::Impl::copyToMDForces() +void ImdSession::Impl::copyToMDForces() { int i; real conversion = CAL2JOULE * NM2A; @@ -752,9 +734,9 @@ ImdSession::Impl::copyToMDForces() f_ind[i] = vmd_f_ind[i]; /* Convert to rvecs and do a proper unit conversion */ - f[i][0] = vmd_forces[3*i ] * conversion; - f[i][1] = vmd_forces[3*i + 1] * conversion; - f[i][2] = vmd_forces[3*i + 2] * conversion; + f[i][0] = vmd_forces[3 * i] * conversion; + f[i][1] = vmd_forces[3 * i + 1] * conversion; + f[i][2] = vmd_forces[3 * i + 2] * conversion; } } @@ -773,8 +755,7 @@ static inline bool rvecs_differ(const rvec v1, const rvec v2) return false; } -bool -ImdSession::Impl::bForcesChanged() const +bool ImdSession::Impl::bForcesChanged() const { /* First, check whether the number of pulled atoms changed */ if (nforces != old_nforces) @@ -805,8 +786,7 @@ ImdSession::Impl::bForcesChanged() const } -void -ImdSession::Impl::keepOldValues() +void ImdSession::Impl::keepOldValues() { old_nforces = nforces; @@ -818,8 +798,7 @@ ImdSession::Impl::keepOldValues() } -void -ImdSession::Impl::outputForces(double time) +void ImdSession::Impl::outputForces(double time) { if (!bForcesChanged()) { @@ -845,8 +824,7 @@ ImdSession::Impl::outputForces(double time) } -void -ImdSession::Impl::syncNodes(const t_commrec *cr, double t) +void ImdSession::Impl::syncNodes(const t_commrec* cr, double t) { /* Notify the other nodes whether we are still connected. */ if (PAR(cr)) @@ -928,7 +906,7 @@ ImdSession::Impl::syncNodes(const t_commrec *cr, double t) if (PAR(cr)) { nblock_bc(cr, nforces, f_ind); - nblock_bc(cr, nforces, f ); + nblock_bc(cr, nforces, f); } /* done communicating the forces, reset bNewForces */ @@ -936,10 +914,9 @@ ImdSession::Impl::syncNodes(const t_commrec *cr, double t) } -void -ImdSession::Impl::readCommand() +void ImdSession::Impl::readCommand() { - bool IMDpaused = false; + bool IMDpaused = false; while (clientsocket && (imdsock_tryread(clientsocket, 0, 0) > 0 || IMDpaused)) { @@ -951,14 +928,22 @@ ImdSession::Impl::readCommand() case IMD_KILL: if (bTerminatable) { - GMX_LOG(mdlog.warning).appendTextFormatted(" %s Terminating connection and running simulation (if supported by integrator).", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + " %s Terminating connection and running simulation (if " + "supported by integrator).", + IMDstr); bTerminated = true; bWConnect = false; gmx_set_stop_condition(gmx_stop_cond_next); } else { - GMX_LOG(mdlog.warning).appendTextFormatted(" %s Set -imdterm command line switch to allow mdrun termination from within IMD.", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + " %s Set -imdterm command line switch to allow mdrun " + "termination from within IMD.", + IMDstr); } break; @@ -994,12 +979,15 @@ ImdSession::Impl::readCommand() * to the default. VMD filters 0 however */ case IMD_TRATE: nstimd_new = (length > 0) ? length : defaultNstImd; - GMX_LOG(mdlog.warning).appendTextFormatted(" %s Update frequency will be set to %d.", IMDstr, nstimd_new); + GMX_LOG(mdlog.warning) + .appendTextFormatted(" %s Update frequency will be set to %d.", IMDstr, nstimd_new); break; /* Catch all rule for the remaining IMD types which we don't expect */ default: - GMX_LOG(mdlog.warning).appendTextFormatted(" %s Received unexpected %s.", IMDstr, enum_name(static_cast(itype), IMD_NR, eIMDType_names)); + GMX_LOG(mdlog.warning) + .appendTextFormatted(" %s Received unexpected %s.", IMDstr, + enum_name(static_cast(itype), IMD_NR, eIMDType_names)); issueFatalError("Terminating connection"); break; } /* end switch */ @@ -1007,17 +995,19 @@ ImdSession::Impl::readCommand() } -void -ImdSession::Impl::openOutputFile(const char *fn, - int nat_total, - const gmx_output_env_t *oenv, - const gmx::StartingBehavior startingBehavior) +void ImdSession::Impl::openOutputFile(const char* fn, + int nat_total, + const gmx_output_env_t* oenv, + const gmx::StartingBehavior startingBehavior) { /* Open log file of applied IMD forces if requested */ if (!fn || !oenv) { - fprintf(stdout, "%s For a log of the IMD pull forces explicitly specify '-if' on the command line.\n" - "%s (Not possible with energy minimization.)\n", IMDstr, IMDstr); + fprintf(stdout, + "%s For a log of the IMD pull forces explicitly specify '-if' on the command " + "line.\n" + "%s (Not possible with energy minimization.)\n", + IMDstr, IMDstr); return; } @@ -1031,29 +1021,39 @@ ImdSession::Impl::openOutputFile(const char *fn, outf = gmx_fio_fopen(fn, "w+"); if (nat == nat_total) { - fprintf(outf, "# Note that you can select an IMD index group in the .mdp file if a subset of the atoms suffices.\n"); + fprintf(outf, + "# Note that you can select an IMD index group in the .mdp file if a subset of " + "the atoms suffices.\n"); } - xvgr_header(outf, "IMD Pull Forces", "Time (ps)", "# of Forces / Atom IDs / Forces (kJ/mol)", exvggtNONE, oenv); + xvgr_header(outf, "IMD Pull Forces", "Time (ps)", + "# of Forces / Atom IDs / Forces (kJ/mol)", exvggtNONE, oenv); fprintf(outf, "# Can display and manipulate %d (of a total of %d) atoms via IMD.\n", nat, nat_total); fprintf(outf, "# column 1 : time (ps)\n"); - fprintf(outf, "# column 2 : total number of atoms feeling an IMD pulling force at that time\n"); - fprintf(outf, "# cols. 3.-6 : global atom number of pulled atom, x-force, y-force, z-force (kJ/mol)\n"); - fprintf(outf, "# then follow : atom-ID, f[x], f[y], f[z] for more atoms in case the force on multiple atoms is changed simultaneously.\n"); - fprintf(outf, "# Note that the force on any atom is always equal to the last value for that atom-ID found in the data.\n"); + fprintf(outf, + "# column 2 : total number of atoms feeling an IMD pulling force at that " + "time\n"); + fprintf(outf, + "# cols. 3.-6 : global atom number of pulled atom, x-force, y-force, z-force " + "(kJ/mol)\n"); + fprintf(outf, + "# then follow : atom-ID, f[x], f[y], f[z] for more atoms in case the force on " + "multiple atoms is changed simultaneously.\n"); + fprintf(outf, + "# Note that the force on any atom is always equal to the last value for that " + "atom-ID found in the data.\n"); fflush(outf); } /* To reduce the output file size we remember the old values and output only * when something changed */ - snew(old_f_ind, nat); /* One can never pull on more atoms */ + snew(old_f_ind, nat); /* One can never pull on more atoms */ snew(old_forces, nat); } -ImdSession::Impl::Impl(const MDLogger &mdlog) - : mdlog(mdlog) +ImdSession::Impl::Impl(const MDLogger& mdlog) : mdlog(mdlog) { init_block(&mols); } @@ -1068,13 +1068,12 @@ ImdSession::Impl::~Impl() } -void -ImdSession::Impl::prepareMoleculesInImdGroup(const gmx_mtop_t *top_global) +void ImdSession::Impl::prepareMoleculesInImdGroup(const gmx_mtop_t* top_global) { /* check whether index is sorted */ - for (int i = 0; i < nat-1; i++) + for (int i = 0; i < nat - 1; i++) { - if (ind[i] > ind[i+1]) + if (ind[i] > ind[i + 1]) { gmx_fatal(FARGS, "%s IMD index is not sorted. This is currently not supported.\n", IMDstr); } @@ -1099,24 +1098,23 @@ ImdSession::Impl::prepareMoleculesInImdGroup(const gmx_mtop_t *top_global) } if (count > 0) { - lmols.index[lmols.nr+1] = lmols.index[lmols.nr]+count; - lmols.nr += 1; + lmols.index[lmols.nr + 1] = lmols.index[lmols.nr] + count; + lmols.nr += 1; } } - srenew(lmols.index, lmols.nr+1); - lmols.nalloc_index = lmols.nr+1; + srenew(lmols.index, lmols.nr + 1); + lmols.nalloc_index = lmols.nr + 1; mols = lmols; } /*! \brief Copied and modified from groupcoord.c shift_positions_group(). */ -static void shift_positions( - const matrix box, - rvec x[], /* The positions [0..nr] */ - const ivec is, /* The shift [0..nr] */ - int nr) /* The number of positions */ +static void shift_positions(const matrix box, + rvec x[], /* The positions [0..nr] */ + const ivec is, /* The shift [0..nr] */ + int nr) /* The number of positions */ { - int i, tx, ty, tz; + int i, tx, ty, tz; /* Loop over the group's atoms */ if (TRICLINIC(box)) @@ -1127,9 +1125,9 @@ static void shift_positions( ty = is[YY]; tz = is[ZZ]; - x[i][XX] = x[i][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX]; - x[i][YY] = x[i][YY]-ty*box[YY][YY]-tz*box[ZZ][YY]; - x[i][ZZ] = x[i][ZZ]-tz*box[ZZ][ZZ]; + x[i][XX] = x[i][XX] - tx * box[XX][XX] - ty * box[YY][XX] - tz * box[ZZ][XX]; + x[i][YY] = x[i][YY] - ty * box[YY][YY] - tz * box[ZZ][YY]; + x[i][ZZ] = x[i][ZZ] - tz * box[ZZ][ZZ]; } } else @@ -1140,9 +1138,9 @@ static void shift_positions( ty = is[YY]; tz = is[ZZ]; - x[i][XX] = x[i][XX]-tx*box[XX][XX]; - x[i][YY] = x[i][YY]-ty*box[YY][YY]; - x[i][ZZ] = x[i][ZZ]-tz*box[ZZ][ZZ]; + x[i][XX] = x[i][XX] - tx * box[XX][XX]; + x[i][YY] = x[i][YY] - ty * box[YY][YY]; + x[i][ZZ] = x[i][ZZ] - tz * box[ZZ][ZZ]; } } } @@ -1163,11 +1161,11 @@ void ImdSession::Impl::removeMolecularShifts(const matrix box) copy_ivec(xa_shifts[mols.index[i]], largest); copy_ivec(xa_shifts[mols.index[i]], smallest); - for (int ii = mols.index[i]+1; ii < mols.index[i+1]; ii++) + for (int ii = mols.index[i] + 1; ii < mols.index[i + 1]; ii++) { if (xa_shifts[ii][XX] > largest[XX]) { - largest[XX] = xa_shifts[ii][XX]; + largest[XX] = xa_shifts[ii][XX]; } if (xa_shifts[ii][XX] < smallest[XX]) { @@ -1176,7 +1174,7 @@ void ImdSession::Impl::removeMolecularShifts(const matrix box) if (xa_shifts[ii][YY] > largest[YY]) { - largest[YY] = xa_shifts[ii][YY]; + largest[YY] = xa_shifts[ii][YY]; } if (xa_shifts[ii][YY] < smallest[YY]) { @@ -1185,13 +1183,12 @@ void ImdSession::Impl::removeMolecularShifts(const matrix box) if (xa_shifts[ii][ZZ] > largest[ZZ]) { - largest[ZZ] = xa_shifts[ii][ZZ]; + largest[ZZ] = xa_shifts[ii][ZZ]; } if (xa_shifts[ii][ZZ] < smallest[ZZ]) { smallest[ZZ] = xa_shifts[ii][ZZ]; } - } /* check if we what we can subtract/add to the positions @@ -1225,23 +1222,21 @@ void ImdSession::Impl::removeMolecularShifts(const matrix box) /* is there a shift at all? */ if ((shift[XX]) || (shift[YY]) || (shift[ZZ])) { - int molsize = mols.index[i+1]-mols.index[i]; + int molsize = mols.index[i + 1] - mols.index[i]; /* shift the positions */ shift_positions(box, &(xa[mols.index[i]]), shift, molsize); } - } } -void -ImdSession::Impl::prepareForPositionAssembly(const t_commrec *cr, const rvec x[]) +void ImdSession::Impl::prepareForPositionAssembly(const t_commrec* cr, const rvec x[]) { - snew(xa, nat); - snew(xa_ind, nat); - snew(xa_shifts, nat); + snew(xa, nat); + snew(xa_ind, nat); + snew(xa_shifts, nat); snew(xa_eshifts, nat); - snew(xa_old, nat); + snew(xa_old, nat); /* Save the original (whole) set of positions such that later the * molecule can always be made whole again */ @@ -1275,34 +1270,36 @@ ImdSession::Impl::prepareForPositionAssembly(const t_commrec *cr, const rvec x[] /*! \brief Check for non-working integrator / parallel options. */ -static void imd_check_integrator_parallel(const t_inputrec *ir, const t_commrec *cr) +static void imd_check_integrator_parallel(const t_inputrec* ir, const t_commrec* cr) { if (PAR(cr)) { if (((ir->eI) == eiSteep) || ((ir->eI) == eiCG) || ((ir->eI) == eiLBFGS) || ((ir->eI) == eiNM)) { - gmx_fatal(FARGS, "%s Energy minimization via steep, CG, lbfgs and nm in parallel is currently not supported by IMD.\n", IMDstr); + gmx_fatal(FARGS, + "%s Energy minimization via steep, CG, lbfgs and nm in parallel is currently " + "not supported by IMD.\n", + IMDstr); } } } -std::unique_ptr -makeImdSession(const t_inputrec *ir, - const t_commrec *cr, - gmx_wallcycle *wcycle, - gmx_enerdata_t *enerd, - const gmx_multisim_t *ms, - const gmx_mtop_t *top_global, - const MDLogger &mdlog, - const rvec x[], - int nfile, - const t_filenm fnm[], - const gmx_output_env_t *oenv, - const ImdOptions &options, - const gmx::StartingBehavior startingBehavior) +std::unique_ptr makeImdSession(const t_inputrec* ir, + const t_commrec* cr, + gmx_wallcycle* wcycle, + gmx_enerdata_t* enerd, + const gmx_multisim_t* ms, + const gmx_mtop_t* top_global, + const MDLogger& mdlog, + const rvec x[], + int nfile, + const t_filenm fnm[], + const gmx_output_env_t* oenv, + const ImdOptions& options, + const gmx::StartingBehavior startingBehavior) { std::unique_ptr session(new ImdSession(mdlog)); - auto impl = session->impl_.get(); + auto impl = session->impl_.get(); /* We will allow IMD sessions only if supported by the binary and explicitly enabled in the .tpr file */ @@ -1329,16 +1326,24 @@ makeImdSession(const t_inputrec *ir, } else { - GMX_LOG(mdlog.warning).appendTextFormatted("%s Integrator '%s' is not supported for Interactive Molecular Dynamics, running normally instead", IMDstr, ei_names[ir->eI]); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s Integrator '%s' is not supported for Interactive Molecular Dynamics, " + "running normally instead", + IMDstr, ei_names[ir->eI]); return session; } if (isMultiSim(ms)) { - GMX_LOG(mdlog.warning).appendTextFormatted("%s Cannot use IMD for multiple simulations or replica exchange, running normally instead", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s Cannot use IMD for multiple simulations or replica exchange, running " + "normally instead", + IMDstr); return session; } - bool createSession = false; + bool createSession = false; /* It seems we have a .tpr file that defines an IMD group and thus allows IMD connections. * Check whether we can actually provide the IMD functionality for this setting: */ if (MASTER(cr)) @@ -1346,15 +1351,20 @@ makeImdSession(const t_inputrec *ir, /* Check whether IMD was enabled by one of the command line switches: */ if (options.wait || options.terminatable || options.pull) { - GMX_LOG(mdlog.warning).appendTextFormatted("%s Enabled. This simulation will accept incoming IMD connections.", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s Enabled. This simulation will accept incoming IMD connections.", IMDstr); createSession = true; } else { - GMX_LOG(mdlog.warning).appendTextFormatted("%s None of the -imd switches was used.\n" - "%s This run will not accept incoming IMD connections", IMDstr, IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s None of the -imd switches was used.\n" + "%s This run will not accept incoming IMD connections", + IMDstr, IMDstr); } - } /* end master only */ + } /* end master only */ /* Let the other nodes know whether we want IMD */ if (PAR(cr)) @@ -1387,7 +1397,7 @@ makeImdSession(const t_inputrec *ir, impl->nat = ir->imd->nat > 0 ? ir->imd->nat : nat_total; if (options.port >= 1) { - impl->port = options.port; + impl->port = options.port; } impl->cr = cr; impl->wcycle = wcycle; @@ -1426,21 +1436,26 @@ makeImdSession(const t_inputrec *ir, if (options.wait) { impl->bWConnect = true; - GMX_LOG(mdlog.warning).appendTextFormatted("%s Pausing simulation while no IMD connection present (-imdwait).", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s Pausing simulation while no IMD connection present (-imdwait).", IMDstr); } /* Will the IMD clients be able to terminate the simulation? */ if (options.terminatable) { impl->bTerminatable = true; - GMX_LOG(mdlog.warning).appendTextFormatted("%s Allow termination of the simulation from IMD client (-imdterm).", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted( + "%s Allow termination of the simulation from IMD client (-imdterm).", IMDstr); } /* Is pulling from IMD client allowed? */ if (options.pull) { impl->bForceActivated = true; - GMX_LOG(mdlog.warning).appendTextFormatted("%s Pulling from IMD remote is enabled (-imdpull).", IMDstr); + GMX_LOG(mdlog.warning) + .appendTextFormatted("%s Pulling from IMD remote is enabled (-imdpull).", IMDstr); } /* Initialize send buffers with constant size */ @@ -1487,11 +1502,7 @@ makeImdSession(const t_inputrec *ir, } -bool ImdSession::Impl::run(int64_t step, - bool bNS, - const matrix box, - const rvec x[], - double t) +bool ImdSession::Impl::run(int64_t step, bool bNS, const matrix box, const rvec x[], double t) { /* IMD at all? */ if (!sessionPossible) @@ -1536,14 +1547,12 @@ bool ImdSession::Impl::run(int64_t step, /* If a client is connected, we collect the positions * and put molecules back into the box before transfer */ - if ((imdstep && bConnected) - || bNS) /* independent of imdstep, we communicate positions at each NS step */ + if ((imdstep && bConnected) || bNS) /* independent of imdstep, we communicate positions at each NS step */ { /* Transfer the IMD positions to the master node. Every node contributes * its local positions x and stores them in the assembled xa array. */ - communicate_group_positions(cr, xa, xa_shifts, xa_eshifts, - true, x, nat, nat_loc, - ind_loc, xa_ind, xa_old, box); + communicate_group_positions(cr, xa, xa_shifts, xa_eshifts, true, x, nat, nat_loc, ind_loc, + xa_ind, xa_old, box); /* If connected and master -> remove shifts */ if ((imdstep && bConnected) && MASTER(cr)) @@ -1557,24 +1566,19 @@ bool ImdSession::Impl::run(int64_t step, return imdstep; } -bool ImdSession::run(int64_t step, - bool bNS, - const matrix box, - const rvec x[], - double t) +bool ImdSession::run(int64_t step, bool bNS, const matrix box, const rvec x[], double t) { return impl_->run(step, bNS, box, x, t); } -void ImdSession::fillEnergyRecord(int64_t step, - bool bHaveNewEnergies) +void ImdSession::fillEnergyRecord(int64_t step, bool bHaveNewEnergies) { if (!impl_->sessionPossible || !impl_->clientsocket) { return; } - IMDEnergyBlock *ene = impl_->energies; + IMDEnergyBlock* ene = impl_->energies; ene->tstep = step; @@ -1583,21 +1587,20 @@ void ImdSession::fillEnergyRecord(int64_t step, * last global communication step are still on display in the viewer. */ if (bHaveNewEnergies) { - ene->T_abs = static_cast(impl_->enerd->term[F_TEMP ]); - ene->E_pot = static_cast(impl_->enerd->term[F_EPOT ]); - ene->E_tot = static_cast(impl_->enerd->term[F_ETOT ]); - ene->E_bond = static_cast(impl_->enerd->term[F_BONDS ]); - ene->E_angle = static_cast(impl_->enerd->term[F_ANGLES ]); - ene->E_dihe = static_cast(impl_->enerd->term[F_PDIHS ]); - ene->E_impr = static_cast(impl_->enerd->term[F_IDIHS ]); - ene->E_vdw = static_cast(impl_->enerd->term[F_LJ ]); + ene->T_abs = static_cast(impl_->enerd->term[F_TEMP]); + ene->E_pot = static_cast(impl_->enerd->term[F_EPOT]); + ene->E_tot = static_cast(impl_->enerd->term[F_ETOT]); + ene->E_bond = static_cast(impl_->enerd->term[F_BONDS]); + ene->E_angle = static_cast(impl_->enerd->term[F_ANGLES]); + ene->E_dihe = static_cast(impl_->enerd->term[F_PDIHS]); + ene->E_impr = static_cast(impl_->enerd->term[F_IDIHS]); + ene->E_vdw = static_cast(impl_->enerd->term[F_LJ]); ene->E_coul = static_cast(impl_->enerd->term[F_COUL_SR]); } } -void -ImdSession::sendPositionsAndEnergies() +void ImdSession::sendPositionsAndEnergies() { if (!impl_->sessionPossible || !impl_->clientsocket) { @@ -1616,10 +1619,7 @@ ImdSession::sendPositionsAndEnergies() } -void -ImdSession::updateEnergyRecordAndSendPositionsAndEnergies(bool bIMDstep, - int64_t step, - bool bHaveNewEnergies) +void ImdSession::updateEnergyRecordAndSendPositionsAndEnergies(bool bIMDstep, int64_t step, bool bHaveNewEnergies) { if (!impl_->sessionPossible) { @@ -1640,7 +1640,7 @@ ImdSession::updateEnergyRecordAndSendPositionsAndEnergies(bool bIMDstep, wallcycle_stop(impl_->wcycle, ewcIMD); } -void ImdSession::applyForces(rvec *f) +void ImdSession::applyForces(rvec* f) { if (!impl_->sessionPossible || !impl_->bForceActivated) { @@ -1655,8 +1655,8 @@ void ImdSession::applyForces(rvec *f) int j = impl_->ind[impl_->f_ind[i]]; /* check if this is a local atom and find out locndx */ - const int *locndx; - const t_commrec *cr = impl_->cr; + const int* locndx; + const t_commrec* cr = impl_->cr; if (PAR(cr) && (locndx = cr->dd->ga2la->findHome(j))) { j = *locndx; @@ -1668,9 +1668,7 @@ void ImdSession::applyForces(rvec *f) wallcycle_stop(impl_->wcycle, ewcIMD); } -ImdSession::ImdSession(const MDLogger &mdlog) - : impl_(new Impl(mdlog)) -{} +ImdSession::ImdSession(const MDLogger& mdlog) : impl_(new Impl(mdlog)) {} ImdSession::~ImdSession() = default; diff --git a/src/gromacs/imd/imd.h b/src/gromacs/imd/imd.h index b7a6e3e674..8fb64c2317 100644 --- a/src/gromacs/imd/imd.h +++ b/src/gromacs/imd/imd.h @@ -111,8 +111,12 @@ static const char IMDstr[] = "IMD:"; /**< Tag output from the IMD module with th * \param nfile Number of files. * \param fnm Filename struct. */ -void write_IMDgroup_to_file(bool bIMD, t_inputrec *ir, const t_state *state, - const gmx_mtop_t *sys, int nfile, const t_filenm fnm[]); +void write_IMDgroup_to_file(bool bIMD, + t_inputrec* ir, + const t_state* state, + const gmx_mtop_t* sys, + int nfile, + const t_filenm fnm[]); /*! \brief Makes and returns an initialized IMD session, which may be inactive. @@ -133,110 +137,102 @@ void write_IMDgroup_to_file(bool bIMD, t_inputrec *ir, const t_state *state, * \param options Options for interactive MD. * \param startingBehavior Describes whether this is a restart appending to output files */ -std::unique_ptr -makeImdSession(const t_inputrec *ir, - const t_commrec *cr, - gmx_wallcycle *wcycle, - gmx_enerdata_t *enerd, - const gmx_multisim_t *ms, - const gmx_mtop_t *top_global, - const MDLogger &mdlog, - const rvec x[], - int nfile, - const t_filenm fnm[], - const gmx_output_env_t *oenv, - const ImdOptions &options, - StartingBehavior startingBehavior); +std::unique_ptr makeImdSession(const t_inputrec* ir, + const t_commrec* cr, + gmx_wallcycle* wcycle, + gmx_enerdata_t* enerd, + const gmx_multisim_t* ms, + const gmx_mtop_t* top_global, + const MDLogger& mdlog, + const rvec x[], + int nfile, + const t_filenm fnm[], + const gmx_output_env_t* oenv, + const ImdOptions& options, + StartingBehavior startingBehavior); class ImdSession { - private: - //! Private constructor, to force the use of makeImdSession() - ImdSession(const MDLogger &mdlog); - public: - ~ImdSession(); - - /*! \brief Make a selection of the home atoms for the IMD group. - * - * Should be called at every domain decomposition. - * Each node checks which of the atoms from "ind" are local and puts its local - * atom numbers into the "ind_local" array. Furthermore, in "xa_ind" it is - * stored at which position each local atom belongs in the assembled/collective - * array, so that on the master node all positions can be merged into the - * assembled array correctly. - * - * \param dd Structure containing domain decomposition data. - */ - void dd_make_local_IMD_atoms(const gmx_domdec_t *dd); - - /*! \brief Prepare to do IMD if required in this time step - * Also checks for new IMD connection and syncs the nodes. - * - * \param step The time step. - * \param bNS Is this a neighbor searching step? - * \param box The simulation box. - * \param x The local atomic positions on this node. - * \param t The time. - * - * \returns Whether or not we have to do IMD communication at this step. - */ - bool run(int64_t step, - bool bNS, - const matrix box, - const rvec x[], - double t); - - /*! \brief Add external forces from a running interactive molecular dynamics session. - * - * \param f The forces. - */ - void applyForces(rvec *f); - - /*! \brief Copy energies and convert to float from enerdata to the IMD energy record. - * - * We do no conversion, so units in client are SI! - * - * \param step The time step. - * \param bHaveNewEnergies Only copy energies if we have done global summing of them before. - */ - void fillEnergyRecord(int64_t step, - bool bHaveNewEnergies); - - /*! \brief Send positions and energies to the client. */ - void sendPositionsAndEnergies(); - - /*! \brief Updates the energy record sent to VMD if needed, and sends positions and energies. - * - * \param bIMDstep If true, transfer the positions. Otherwise just update the time step and potentially the energy record. - * \param step The time step. - * \param bHaveNewEnergies Update the energy record if we have done global summing of the energies. - */ - void updateEnergyRecordAndSendPositionsAndEnergies(bool bIMDstep, - int64_t step, - bool bHaveNewEnergies); - - private: - //! Implementation type. - class Impl; - //! Implementation object. - PrivateImplPointer impl_; - - public: - // Befriend the factory function. - friend std::unique_ptr - makeImdSession(const t_inputrec *ir, - const t_commrec *cr, - gmx_wallcycle *wcycle, - gmx_enerdata_t *enerd, - const gmx_multisim_t *ms, - const gmx_mtop_t *top_global, - const MDLogger &mdlog, - const rvec x[], - int nfile, - const t_filenm fnm[], - const gmx_output_env_t *oenv, - const ImdOptions &options, - StartingBehavior startingBehavior); +private: + //! Private constructor, to force the use of makeImdSession() + ImdSession(const MDLogger& mdlog); + +public: + ~ImdSession(); + + /*! \brief Make a selection of the home atoms for the IMD group. + * + * Should be called at every domain decomposition. + * Each node checks which of the atoms from "ind" are local and puts its local + * atom numbers into the "ind_local" array. Furthermore, in "xa_ind" it is + * stored at which position each local atom belongs in the assembled/collective + * array, so that on the master node all positions can be merged into the + * assembled array correctly. + * + * \param dd Structure containing domain decomposition data. + */ + void dd_make_local_IMD_atoms(const gmx_domdec_t* dd); + + /*! \brief Prepare to do IMD if required in this time step + * Also checks for new IMD connection and syncs the nodes. + * + * \param step The time step. + * \param bNS Is this a neighbor searching step? + * \param box The simulation box. + * \param x The local atomic positions on this node. + * \param t The time. + * + * \returns Whether or not we have to do IMD communication at this step. + */ + bool run(int64_t step, bool bNS, const matrix box, const rvec x[], double t); + + /*! \brief Add external forces from a running interactive molecular dynamics session. + * + * \param f The forces. + */ + void applyForces(rvec* f); + + /*! \brief Copy energies and convert to float from enerdata to the IMD energy record. + * + * We do no conversion, so units in client are SI! + * + * \param step The time step. + * \param bHaveNewEnergies Only copy energies if we have done global summing of them before. + */ + void fillEnergyRecord(int64_t step, bool bHaveNewEnergies); + + /*! \brief Send positions and energies to the client. */ + void sendPositionsAndEnergies(); + + /*! \brief Updates the energy record sent to VMD if needed, and sends positions and energies. + * + * \param bIMDstep If true, transfer the positions. Otherwise just update the time step and potentially the energy record. + * \param step The time step. + * \param bHaveNewEnergies Update the energy record if we have done global summing of the energies. + */ + void updateEnergyRecordAndSendPositionsAndEnergies(bool bIMDstep, int64_t step, bool bHaveNewEnergies); + +private: + //! Implementation type. + class Impl; + //! Implementation object. + PrivateImplPointer impl_; + +public: + // Befriend the factory function. + friend std::unique_ptr makeImdSession(const t_inputrec* ir, + const t_commrec* cr, + gmx_wallcycle* wcycle, + gmx_enerdata_t* enerd, + const gmx_multisim_t* ms, + const gmx_mtop_t* top_global, + const MDLogger& mdlog, + const rvec x[], + int nfile, + const t_filenm fnm[], + const gmx_output_env_t* oenv, + const ImdOptions& options, + StartingBehavior startingBehavior); }; } // namespace gmx diff --git a/src/gromacs/imd/imdsocket.cpp b/src/gromacs/imd/imdsocket.cpp index 67e6abde81..4fc4e34e4b 100644 --- a/src/gromacs/imd/imdsocket.cpp +++ b/src/gromacs/imd/imdsocket.cpp @@ -62,25 +62,25 @@ #if GMX_IMD -#if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS -#include -#include +# include +# include //! Constant for passing no flags constexpr int c_noFlags = 0; /*! \brief Define socklen type on Windows. */ typedef int socklen_t; -#else +# else -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include -#endif +# endif #endif @@ -96,8 +96,8 @@ namespace gmx struct IMDSocket { #if GMX_IMD - struct sockaddr_in address; /**< address of socket */ - int sockfd; /**< socket file descriptor */ + struct sockaddr_in address; /**< address of socket */ + int sockfd; /**< socket file descriptor */ #endif }; @@ -106,7 +106,7 @@ int imdsock_winsockinit() { #if GMX_IMD && GMX_NATIVE_WINDOWS fprintf(stderr, "%s Initializing winsock.\n", IMDstr); - int ret = -1; + int ret = -1; WSADATA wsd; @@ -121,9 +121,9 @@ int imdsock_winsockinit() /*! \brief Simple error handling. */ #if GMX_NATIVE_WINDOWS -#define ERR_ARGS __FILE__, __LINE__, NULL +# define ERR_ARGS __FILE__, __LINE__, NULL #else -#define ERR_ARGS __FILE__, __LINE__, strerror(errno) +# define ERR_ARGS __FILE__, __LINE__, strerror(errno) #endif @@ -132,7 +132,7 @@ constexpr int c_maxConnections = 1; /*! \brief Print a nice error message on UNIX systems, using errno.h. */ -static void print_IMD_error(const char *file, int line, char *msg) +static void print_IMD_error(const char* file, int line, char* msg) { fprintf(stderr, "%s Error in file %s on line %d.\n", IMDstr, file, line); @@ -145,7 +145,7 @@ static void print_IMD_error(const char *file, int line, char *msg) IMDSocket* imdsock_create() { - IMDSocket *sock = nullptr; + IMDSocket* sock = nullptr; #if GMX_IMD @@ -168,18 +168,18 @@ IMDSocket* imdsock_create() void imd_sleep(unsigned int seconds) { #if GMX_IMD -#if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS Sleep(seconds); -#else +# else sleep(seconds); -#endif +# endif #else GMX_UNUSED_VALUE(seconds); #endif } -int imdsock_bind(IMDSocket *sock, int port) +int imdsock_bind(IMDSocket* sock, int port) { int ret; @@ -190,7 +190,7 @@ int imdsock_bind(IMDSocket *sock, int port) sock->address.sin_port = htons(port); /* Try to bind to address and port ...*/ - ret = bind(sock->sockfd, reinterpret_cast(&sock->address), sizeof(sock->address)); + ret = bind(sock->sockfd, reinterpret_cast(&sock->address), sizeof(sock->address)); #else GMX_UNUSED_VALUE(port); GMX_UNUSED_VALUE(sock); @@ -206,7 +206,7 @@ int imdsock_bind(IMDSocket *sock, int port) } -int imd_sock_listen(IMDSocket *sock) +int imd_sock_listen(IMDSocket* sock) { int ret; @@ -229,21 +229,21 @@ int imd_sock_listen(IMDSocket *sock) } -IMDSocket* imdsock_accept(IMDSocket *sock) +IMDSocket* imdsock_accept(IMDSocket* sock) { #if GMX_IMD socklen_t length = sizeof(sock->address); - int ret = accept(sock->sockfd, reinterpret_cast(&sock->address), &length); + int ret = accept(sock->sockfd, reinterpret_cast(&sock->address), &length); /* successful, redirect to distinct clientsocket */ if (ret >= 0) { - IMDSocket *newsock; + IMDSocket* newsock; snew(newsock, 1); - newsock->address = sock->address; - newsock->sockfd = ret; + newsock->address = sock->address; + newsock->sockfd = ret; return newsock; } @@ -259,15 +259,15 @@ IMDSocket* imdsock_accept(IMDSocket *sock) } -int imdsock_getport(IMDSocket *sock, int *port) +int imdsock_getport(IMDSocket* sock, int* port) { - int ret; + int ret; #if GMX_IMD - socklen_t len; + socklen_t len; len = sizeof(struct sockaddr_in); - ret = getsockname(sock->sockfd, reinterpret_cast(&(sock->address)), &len); + ret = getsockname(sock->sockfd, reinterpret_cast(&(sock->address)), &len); if (ret) { fprintf(stderr, "%s getsockname failed with error %d.\n", IMDstr, ret); @@ -306,15 +306,15 @@ int imd_ntohl(int src) #endif } -int imdsock_write(IMDSocket *sock, const char *buffer, int length) +int imdsock_write(IMDSocket* sock, const char* buffer, int length) { #if GMX_IMD /* No read and write on windows, we have to use send and recv instead... */ -#if GMX_NATIVE_WINDOWS - return send(sock->sockfd, (const char *) buffer, length, c_noFlags); -#else +# if GMX_NATIVE_WINDOWS + return send(sock->sockfd, (const char*)buffer, length, c_noFlags); +# else return write(sock->sockfd, buffer, length); -#endif +# endif #else GMX_UNUSED_VALUE(buffer); GMX_UNUSED_VALUE(length); @@ -324,15 +324,15 @@ int imdsock_write(IMDSocket *sock, const char *buffer, int length) } -int imdsock_read(IMDSocket *sock, char *buffer, int length) +int imdsock_read(IMDSocket* sock, char* buffer, int length) { #if GMX_IMD /* See above... */ -#if GMX_NATIVE_WINDOWS - return recv(sock->sockfd, (char *) buffer, length, c_noFlags); -#else +# if GMX_NATIVE_WINDOWS + return recv(sock->sockfd, (char*)buffer, length, c_noFlags); +# else return read(sock->sockfd, buffer, length); -#endif +# endif #else GMX_UNUSED_VALUE(buffer); GMX_UNUSED_VALUE(length); @@ -342,7 +342,7 @@ int imdsock_read(IMDSocket *sock, char *buffer, int length) } -void imdsock_shutdown(IMDSocket *sock) +void imdsock_shutdown(IMDSocket* sock) { int ret = -1; @@ -366,7 +366,7 @@ void imdsock_shutdown(IMDSocket *sock) } -int imdsock_destroy(IMDSocket *sock) +int imdsock_destroy(IMDSocket* sock) { int ret = -1; @@ -377,11 +377,11 @@ int imdsock_destroy(IMDSocket *sock) } #if GMX_IMD -#if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS ret = closesocket(sock->sockfd); -#else +# else ret = close(sock->sockfd); -#endif +# endif #endif if (ret == -1) @@ -396,15 +396,15 @@ int imdsock_destroy(IMDSocket *sock) } -int imdsock_tryread(IMDSocket *sock, int timeoutsec, int timeoutusec) +int imdsock_tryread(IMDSocket* sock, int timeoutsec, int timeoutusec) { - int ret = -1; + int ret = -1; #if GMX_IMD - fd_set readfds; + fd_set readfds; /* Create new time structure with sec and usec. */ - struct timeval *tval; + struct timeval* tval; snew(tval, 1); @@ -422,8 +422,7 @@ int imdsock_tryread(IMDSocket *sock, int timeoutsec, int timeoutusec) /* check the set for read readiness. */ ret = select(sock->sockfd + 1, &readfds, nullptr, nullptr, tval); /* redo on system interrupt */ - } - while (ret < 0 && errno == EINTR); + } while (ret < 0 && errno == EINTR); sfree(tval); #else diff --git a/src/gromacs/imd/imdsocket.h b/src/gromacs/imd/imdsocket.h index 3cf846dbd7..fdf1b46efc 100644 --- a/src/gromacs/imd/imdsocket.h +++ b/src/gromacs/imd/imdsocket.h @@ -69,7 +69,7 @@ int imdsock_winsockinit(); * * \returns The IMD socket if successful. Otherwise prints an error message and returns NULL. */ -IMDSocket *imdsock_create(); +IMDSocket* imdsock_create(); //! Portability wrapper around sleep function void imd_sleep(unsigned int seconds); @@ -86,7 +86,7 @@ void imd_sleep(unsigned int seconds); * * \returns 0 if successful. */ -int imdsock_bind(IMDSocket *sock, int port); +int imdsock_bind(IMDSocket* sock, int port); /*! \brief Set socket to listening state. @@ -98,7 +98,7 @@ int imdsock_bind(IMDSocket *sock, int port); * \returns 0 if successful. * */ -int imd_sock_listen(IMDSocket *sock); +int imd_sock_listen(IMDSocket* sock); /*! \brief Accept incoming connection and redirect to client socket. @@ -109,7 +109,7 @@ int imd_sock_listen(IMDSocket *sock); * * \returns IMD socket if successful, NULL otherwise. */ -IMDSocket *imdsock_accept(IMDSocket *sock); +IMDSocket* imdsock_accept(IMDSocket* sock); /*! \brief Get the port number used for IMD connection. @@ -121,7 +121,7 @@ IMDSocket *imdsock_accept(IMDSocket *sock); * * \returns 0 if successful, an error code otherwise. */ -int imdsock_getport(IMDSocket *sock, int *port); +int imdsock_getport(IMDSocket* sock, int* port); //! Portability wrapper around system htonl function. int imd_htonl(int src); @@ -139,7 +139,7 @@ int imd_ntohl(int src); * * \returns The number of bytes written, or -1. */ -int imdsock_write(IMDSocket *sock, const char *buffer, int length); +int imdsock_write(IMDSocket* sock, const char* buffer, int length); /*! \brief Read from socket. @@ -150,7 +150,7 @@ int imdsock_write(IMDSocket *sock, const char *buffer, int length); * * \returns The number of bytes read, or -1 for errors. */ -int imdsock_read(IMDSocket *sock, char *buffer, int length); +int imdsock_read(IMDSocket* sock, char* buffer, int length); /*! \brief Shutdown the socket. @@ -158,7 +158,7 @@ int imdsock_read(IMDSocket *sock, char *buffer, int length); * \param sock The IMD socket. * */ -void imdsock_shutdown(IMDSocket *sock); +void imdsock_shutdown(IMDSocket* sock); /*! \brief Close the socket and free the sock struct memory. @@ -169,7 +169,7 @@ void imdsock_shutdown(IMDSocket *sock); * * \returns 1 on success, or 0 if unsuccessful. */ -int imdsock_destroy(IMDSocket *sock); +int imdsock_destroy(IMDSocket* sock); /*! \brief Try to read from the socket. @@ -182,7 +182,7 @@ int imdsock_destroy(IMDSocket *sock); * \param timeoutusec Time out microseconds * */ -int imdsock_tryread(IMDSocket *sock, int timeoutsec, int timeoutusec); +int imdsock_tryread(IMDSocket* sock, int timeoutsec, int timeoutusec); } // namespace gmx diff --git a/src/gromacs/linearalgebra/eigensolver.cpp b/src/gromacs/linearalgebra/eigensolver.cpp index 2195e5e8ad..827262198f 100644 --- a/src/gromacs/linearalgebra/eigensolver.cpp +++ b/src/gromacs/linearalgebra/eigensolver.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,22 +46,16 @@ #include "gmx_arpack.h" #include "gmx_lapack.h" -void -eigensolver(real * a, - int n, - int index_lower, - int index_upper, - real * eigenvalues, - real * eigenvectors) +void eigensolver(real* a, int n, int index_lower, int index_upper, real* eigenvalues, real* eigenvectors) { - int * isuppz; - int lwork, liwork; - int m, iw0, info; - real w0, abstol; - int * iwork; - real * work; - real vl, vu; - const char * jobz; + int* isuppz; + int lwork, liwork; + int m, iw0, info; + real w0, abstol; + int* iwork; + real* work; + real vl, vu; + const char* jobz; if (index_lower < 0) { @@ -70,7 +64,7 @@ eigensolver(real * a, if (index_upper >= n) { - index_upper = n-1; + index_upper = n - 1; } /* Make jobz point to the character "V" if eigenvectors @@ -79,7 +73,7 @@ eigensolver(real * a, jobz = (eigenvectors != nullptr) ? "V" : "N"; /* allocate lapack stuff */ - snew(isuppz, 2*n); + snew(isuppz, 2 * n); vl = vu = 0; /* First time we ask the routine how much workspace it needs */ @@ -95,13 +89,13 @@ eigensolver(real * a, * but this corresponds to lower storage ("L") in Fortran. */ #if GMX_DOUBLE - F77_FUNC(dsyevr, DSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, - &abstol, &m, eigenvalues, eigenvectors, &n, - isuppz, &w0, &lwork, &iw0, &liwork, &info); + F77_FUNC(dsyevr, DSYEVR) + (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues, + eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info); #else - F77_FUNC(ssyevr, SSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, - &abstol, &m, eigenvalues, eigenvectors, &n, - isuppz, &w0, &lwork, &iw0, &liwork, &info); + F77_FUNC(ssyevr, SSYEVR) + (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues, + eigenvectors, &n, isuppz, &w0, &lwork, &iw0, &liwork, &info); #endif if (info != 0) @@ -119,13 +113,13 @@ eigensolver(real * a, abstol = 0; #if GMX_DOUBLE - F77_FUNC(dsyevr, DSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, - &abstol, &m, eigenvalues, eigenvectors, &n, - isuppz, work, &lwork, iwork, &liwork, &info); + F77_FUNC(dsyevr, DSYEVR) + (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues, + eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info); #else - F77_FUNC(ssyevr, SSYEVR) (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, - &abstol, &m, eigenvalues, eigenvectors, &n, - isuppz, work, &lwork, iwork, &liwork, &info); + F77_FUNC(ssyevr, SSYEVR) + (jobz, "I", "L", &n, a, &n, &vl, &vu, &index_lower, &index_upper, &abstol, &m, eigenvalues, + eigenvectors, &n, isuppz, work, &lwork, iwork, &liwork, &info); #endif sfree(isuppz); @@ -136,34 +130,28 @@ eigensolver(real * a, { gmx_fatal(FARGS, "Internal errror in LAPACK diagonalization."); } - } #ifdef GMX_MPI_NOT -void -sparse_parallel_eigensolver(gmx_sparsematrix_t * A, - int neig, - real * eigenvalues, - real * eigenvectors, - int maxiter) +void sparse_parallel_eigensolver(gmx_sparsematrix_t* A, int neig, real* eigenvalues, real* eigenvectors, int maxiter) { - int iwork[80]; - int iparam[11]; - int ipntr[11]; - real * resid; - real * workd; - real * workl; - real * v; - int n; - int ido, info, lworkl, i, ncv, dovec; - real abstol; - int * select; - int iter; - int nnodes, rank; - - MPI_Comm_size( MPI_COMM_WORLD, &nnodes ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + int iwork[80]; + int iparam[11]; + int ipntr[11]; + real* resid; + real* workd; + real* workl; + real* v; + int n; + int ido, info, lworkl, i, ncv, dovec; + real abstol; + int* select; + int iter; + int nnodes, rank; + + MPI_Comm_size(MPI_COMM_WORLD, &nnodes); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (eigenvectors != NULL) { @@ -175,7 +163,7 @@ sparse_parallel_eigensolver(gmx_sparsematrix_t * A, } n = A->nrow; - ncv = 2*neig; + ncv = 2 * neig; if (ncv > n) { @@ -191,12 +179,12 @@ sparse_parallel_eigensolver(gmx_sparsematrix_t * A, iparam[2] = maxiter; /* Max number of iterations */ iparam[6] = 1; /* Standard symmetric eigenproblem */ - lworkl = ncv*(8+ncv); + lworkl = ncv * (8 + ncv); snew(resid, n); - snew(workd, (3*n+4)); + snew(workd, (3 * n + 4)); snew(workl, lworkl); snew(select, ncv); - snew(v, n*ncv); + snew(v, n * ncv); /* Use machine tolerance - roughly 1e-16 in double precision */ abstol = 0; @@ -207,24 +195,23 @@ sparse_parallel_eigensolver(gmx_sparsematrix_t * A, iter = 1; do { -#if GMX_DOUBLE - F77_FUNC(pdsaupd, PDSAUPD) (&ido, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, iwork, workl, &lworkl, &info); -#else - F77_FUNC(pssaupd, PSSAUPD) (&ido, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, iwork, workl, &lworkl, &info); -#endif +# if GMX_DOUBLE + F77_FUNC(pdsaupd, PDSAUPD) + (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, + workl, &lworkl, &info); +# else + F77_FUNC(pssaupd, PSSAUPD) + (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, + workl, &lworkl, &info); +# endif if (ido == -1 || ido == 1) { - gmx_sparsematrix_vector_multiply(A, workd+ipntr[0]-1, workd+ipntr[1]-1); + gmx_sparsematrix_vector_multiply(A, workd + ipntr[0] - 1, workd + ipntr[1] - 1); } fprintf(stderr, "\rIteration %4d: %3d out of %3d Ritz values converged.", iter++, iparam[4], neig); fflush(stderr); - } - while (info == 0 && (ido == -1 || ido == 1)); + } while (info == 0 && (ido == -1 || ido == 1)); fprintf(stderr, "\n"); if (info == 1) @@ -243,17 +230,15 @@ sparse_parallel_eigensolver(gmx_sparsematrix_t * A, /* Extract eigenvalues and vectors from data */ fprintf(stderr, "Calculating eigenvalues and eigenvectors...\n"); -#if GMX_DOUBLE - F77_FUNC(pdseupd, PDSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors, - &n, NULL, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, workl, &lworkl, &info); -#else - F77_FUNC(psseupd, PSSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors, - &n, NULL, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, workl, &lworkl, &info); -#endif +# if GMX_DOUBLE + F77_FUNC(pdseupd, PDSEUPD) + (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid, + &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info); +# else + F77_FUNC(psseupd, PSSEUPD) + (&dovec, "A", select, eigenvalues, eigenvectors, &n, NULL, "I", &n, "SA", &neig, &abstol, resid, + &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info); +# endif sfree(v); sfree(resid); @@ -264,28 +249,23 @@ sparse_parallel_eigensolver(gmx_sparsematrix_t * A, #endif -void -sparse_eigensolver(gmx_sparsematrix_t * A, - int neig, - real * eigenvalues, - real * eigenvectors, - int maxiter) +void sparse_eigensolver(gmx_sparsematrix_t* A, int neig, real* eigenvalues, real* eigenvectors, int maxiter) { - int iwork[80]; - int iparam[11]; - int ipntr[11]; - real * resid; - real * workd; - real * workl; - real * v; - int n; - int ido, info, lworkl, i, ncv, dovec; - real abstol; - int * select; - int iter; + int iwork[80]; + int iparam[11]; + int ipntr[11]; + real* resid; + real* workd; + real* workl; + real* v; + int n; + int ido, info, lworkl, i, ncv, dovec; + real abstol; + int* select; + int iter; #ifdef GMX_MPI_NOT - MPI_Comm_size( MPI_COMM_WORLD, &n ); + MPI_Comm_size(MPI_COMM_WORLD, &n); if (n > 1) { sparse_parallel_eigensolver(A, neig, eigenvalues, eigenvectors, maxiter); @@ -303,7 +283,7 @@ sparse_eigensolver(gmx_sparsematrix_t * A, } n = A->nrow; - ncv = 2*neig; + ncv = 2 * neig; if (ncv > n) { @@ -319,12 +299,12 @@ sparse_eigensolver(gmx_sparsematrix_t * A, iparam[2] = maxiter; /* Max number of iterations */ iparam[6] = 1; /* Standard symmetric eigenproblem */ - lworkl = ncv*(8+ncv); + lworkl = ncv * (8 + ncv); snew(resid, n); - snew(workd, (3*n+4)); + snew(workd, (3 * n + 4)); snew(workl, lworkl); snew(select, ncv); - snew(v, n*ncv); + snew(v, n * ncv); /* Use machine tolerance - roughly 1e-16 in double precision */ abstol = 0; @@ -336,23 +316,22 @@ sparse_eigensolver(gmx_sparsematrix_t * A, do { #if GMX_DOUBLE - F77_FUNC(dsaupd, DSAUPD) (&ido, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, iwork, workl, &lworkl, &info); + F77_FUNC(dsaupd, DSAUPD) + (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, + workl, &lworkl, &info); #else - F77_FUNC(ssaupd, SSAUPD) (&ido, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, iwork, workl, &lworkl, &info); + F77_FUNC(ssaupd, SSAUPD) + (&ido, "I", &n, "SA", &neig, &abstol, resid, &ncv, v, &n, iparam, ipntr, workd, iwork, + workl, &lworkl, &info); #endif if (ido == -1 || ido == 1) { - gmx_sparsematrix_vector_multiply(A, workd+ipntr[0]-1, workd+ipntr[1]-1); + gmx_sparsematrix_vector_multiply(A, workd + ipntr[0] - 1, workd + ipntr[1] - 1); } fprintf(stderr, "\rIteration %4d: %3d out of %3d Ritz values converged.", iter++, iparam[4], neig); fflush(stderr); - } - while (info == 0 && (ido == -1 || ido == 1)); + } while (info == 0 && (ido == -1 || ido == 1)); fprintf(stderr, "\n"); if (info == 1) @@ -372,15 +351,13 @@ sparse_eigensolver(gmx_sparsematrix_t * A, fprintf(stderr, "Calculating eigenvalues and eigenvectors...\n"); #if GMX_DOUBLE - F77_FUNC(dseupd, DSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors, - &n, nullptr, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, workl, &lworkl, &info); + F77_FUNC(dseupd, DSEUPD) + (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol, + resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info); #else - F77_FUNC(sseupd, SSEUPD) (&dovec, "A", select, eigenvalues, eigenvectors, - &n, nullptr, "I", &n, "SA", &neig, &abstol, - resid, &ncv, v, &n, iparam, ipntr, - workd, workl, &lworkl, &info); + F77_FUNC(sseupd, SSEUPD) + (&dovec, "A", select, eigenvalues, eigenvectors, &n, nullptr, "I", &n, "SA", &neig, &abstol, + resid, &ncv, v, &n, iparam, ipntr, workd, workl, &lworkl, &info); #endif sfree(v); diff --git a/src/gromacs/linearalgebra/eigensolver.h b/src/gromacs/linearalgebra/eigensolver.h index 2c4572879f..e8c54e1767 100644 --- a/src/gromacs/linearalgebra/eigensolver.h +++ b/src/gromacs/linearalgebra/eigensolver.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,14 +61,7 @@ * a matrix, i.e. eigenvector j starts at offset j*n, and * is of length n. */ -void -eigensolver(real * a, - int n, - int index_lower, - int index_upper, - real * eigenvalues, - real * eigenvec); - +void eigensolver(real* a, int n, int index_lower, int index_upper, real* eigenvalues, real* eigenvec); /*! \brief Sparse matrix eigensolver. @@ -80,11 +73,6 @@ eigensolver(real * a, * * maxiter=100000 should suffice in most cases! */ -void -sparse_eigensolver(gmx_sparsematrix_t * A, - int neig, - real * eigenvalues, - real * eigenvectors, - int maxiter); +void sparse_eigensolver(gmx_sparsematrix_t* A, int neig, real* eigenvalues, real* eigenvectors, int maxiter); #endif diff --git a/src/gromacs/linearalgebra/gmx_arpack.cpp b/src/gromacs/linearalgebra/gmx_arpack.cpp index a3de65eb74..29a1deb73d 100644 --- a/src/gromacs/linearalgebra/gmx_arpack.cpp +++ b/src/gromacs/linearalgebra/gmx_arpack.cpp @@ -46,13 +46,9 @@ #include "gmx_blas.h" #include "gmx_lapack.h" -static void -F77_FUNC(dstqrb, DSTQRB) (int * n, - double * d__, - double * e, - double * z__, - double * work, - int * info) +#ifndef DOXYGEN + +static void F77_FUNC(dstqrb, DSTQRB)(int* n, double* d__, double* e, double* z__, double* work, int* info) { int i__1, i__2; double d__1, d__2; @@ -107,7 +103,6 @@ F77_FUNC(dstqrb, DSTQRB) (int * n, for (j = 1; j <= i__1; ++j) { z__[j] = 0.; - } z__[*n] = 1.; @@ -136,7 +131,7 @@ L10: { goto L30; } - if (tst <= std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m+1])) * eps) + if (tst <= std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) { e[m] = 0.; goto L30; @@ -157,7 +152,7 @@ L30: } i__1 = lend - l + 1; - anorm = F77_FUNC(dlanst, DLANST) ("i", &i__1, &d__[l], &e[l]); + anorm = F77_FUNC(dlanst, DLANST)("i", &i__1, &d__[l], &e[l]); iscale = 0; if (anorm == 0.) { @@ -167,21 +162,19 @@ L30: { iscale = 1; i__1 = lend - l + 1; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, - info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, - info); + F77_FUNC(dlascl, DLASCL)("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, info); } else if (anorm < ssfmin) { iscale = 2; i__1 = lend - l + 1; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, - info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, - info); + F77_FUNC(dlascl, DLASCL)("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, info); } if (std::abs(d__[lend]) < std::abs(d__[l])) @@ -193,7 +186,7 @@ L30: if (lend > l) { -L40: + L40: if (l != lend) { lendm1 = lend - 1; @@ -211,7 +204,7 @@ L40: m = lend; -L60: + L60: if (m < lend) { e[m] = 0.; @@ -226,7 +219,7 @@ L60: { if (icompz > 0) { - F77_FUNC(dlaev2, DLAEV2) (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s); + F77_FUNC(dlaev2, DLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s); work[l] = c__; work[*n - 1 + l] = s; @@ -236,12 +229,12 @@ L60: } else { - F77_FUNC(dlae2, DLAE2) (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2); + F77_FUNC(dlae2, DLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2); } d__[l] = rt1; d__[l + 1] = rt2; e[l] = 0.; - l += 2; + l += 2; if (l <= lend) { goto L40; @@ -256,8 +249,8 @@ L60: ++jtot; g = (d__[l + 1] - p) / (e[l] * 2.); - r__ = F77_FUNC(dlapy2, DLAPY2) (&g, &c_b31); - g = d__[m] - p + e[l] / (g + ((g > 0) ? r__ : -r__ )); + r__ = F77_FUNC(dlapy2, DLAPY2)(&g, &c_b31); + g = d__[m] - p + e[l] / (g + ((g > 0) ? r__ : -r__)); s = 1.; c__ = 1.; @@ -269,7 +262,7 @@ L60: { f = s * e[i__]; b = c__ * e[i__]; - F77_FUNC(dlartg, DLARTG) (&g, &f, &c__, &s, &r__); + F77_FUNC(dlartg, DLARTG)(&g, &f, &c__, &s, &r__); if (i__ != m - 1) { e[i__ + 1] = r__; @@ -285,22 +278,21 @@ L60: work[i__] = c__; work[*n - 1 + i__] = -s; } - } if (icompz > 0) { mm = m - l + 1; - F77_FUNC(dlasr, DLASR) ("r", "v", "b", &c__1, &mm, &work[l], &work[*n - 1 + l], & - z__[l], &c__1); + F77_FUNC(dlasr, DLASR) + ("r", "v", "b", &c__1, &mm, &work[l], &work[*n - 1 + l], &z__[l], &c__1); } d__[l] -= p; - e[l] = g; + e[l] = g; goto L40; -L80: + L80: d__[l] = p; ++l; @@ -309,12 +301,11 @@ L80: goto L40; } goto L140; - } else { -L90: + L90: if (l != lend) { lendp1 = lend + 1; @@ -323,7 +314,7 @@ L90: { d__2 = std::abs(e[m - 1]); tst = d__2 * d__2; - if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) + if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m - 1]) + safmin) { goto L110; } @@ -332,7 +323,7 @@ L90: m = lend; -L110: + L110: if (m > lend) { e[m - 1] = 0.; @@ -347,8 +338,7 @@ L110: { if (icompz > 0) { - F77_FUNC(dlaev2, DLAEV2) (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s) - ; + F77_FUNC(dlaev2, DLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s); tst = z__[l]; z__[l] = c__ * tst - s * z__[l - 1]; @@ -356,12 +346,12 @@ L110: } else { - F77_FUNC(dlae2, DLAE2) (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2); + F77_FUNC(dlae2, DLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2); } d__[l - 1] = rt1; d__[l] = rt2; e[l - 1] = 0.; - l += -2; + l += -2; if (l >= lend) { goto L90; @@ -377,8 +367,8 @@ L110: g = (d__[l - 1] - p) / (e[l - 1] * 2.); - r__ = F77_FUNC(dlapy2, DLAPY2) (&g, &c_b31); - g = d__[m] - p + e[l - 1] / (g + ((g > 0) ? r__ : -r__ )); + r__ = F77_FUNC(dlapy2, DLAPY2)(&g, &c_b31); + g = d__[m] - p + e[l - 1] / (g + ((g > 0) ? r__ : -r__)); s = 1.; c__ = 1.; @@ -390,7 +380,7 @@ L110: { f = s * e[i__]; b = c__ * e[i__]; - F77_FUNC(dlartg, DLARTG) (&g, &f, &c__, &s, &r__); + F77_FUNC(dlartg, DLARTG)(&g, &f, &c__, &s, &r__); if (i__ != m) { e[i__ - 1] = r__; @@ -406,22 +396,21 @@ L110: work[i__] = c__; work[*n - 1 + i__] = s; } - } if (icompz > 0) { mm = l - m + 1; - F77_FUNC(dlasr, DLASR) ("r", "v", "f", &c__1, &mm, &work[m], &work[*n - 1 + m], & - z__[m], &c__1); + F77_FUNC(dlasr, DLASR) + ("r", "v", "f", &c__1, &mm, &work[m], &work[*n - 1 + m], &z__[m], &c__1); } d__[l] -= p; - e[lm1] = g; + e[lm1] = g; goto L90; -L130: + L130: d__[l] = p; --l; @@ -430,27 +419,26 @@ L130: goto L90; } goto L140; - } L140: if (iscale == 1) { i__1 = lendsv - lsv + 1; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], - n, info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, - info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, info); } else if (iscale == 2) { i__1 = lendsv - lsv + 1; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], - n, info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; - F77_FUNC(dlascl, DLASCL) ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, - info); + F77_FUNC(dlascl, DLASCL) + ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, info); } if (jtot < nmaxit) @@ -471,8 +459,7 @@ L160: if (icompz == 0) { - F77_FUNC(dlasrt, DLASRT) ("i", n, &d__[1], info); - + F77_FUNC(dlasrt, DLASRT)("i", n, &d__[1], info); } else { @@ -506,24 +493,22 @@ L160: L190: return; - } -static void -F77_FUNC(dgetv0, DGETV0) (int * ido, - const char * bmat, - int gmx_unused * itry, - int * initv, - int * n, - int * j, - double * v, - int * ldv, - double * resid, - double * rnorm, - int * ipntr, - double * workd, - int * iwork, - int * ierr) +static void F77_FUNC(dgetv0, DGETV0)(int* ido, + const char* bmat, + int gmx_unused* itry, + int* initv, + int* n, + int* j, + double* v, + int* ldv, + double* resid, + double* rnorm, + int* ipntr, + double* workd, + int* iwork, + int* ierr) { int c__1 = 1; double c_b22 = 1.; @@ -531,14 +516,14 @@ F77_FUNC(dgetv0, DGETV0) (int * ido, double c_b27 = -1.; int v_dim1, v_offset, i__1; - int jj; - int idist; + int jj; + int idist; --workd; --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --ipntr; --iwork; @@ -553,14 +538,14 @@ F77_FUNC(dgetv0, DGETV0) (int * ido, if (!(*initv)) { idist = 2; - F77_FUNC(dlarnv, DLARNV) (&idist, &iwork[1], n, &resid[1]); + F77_FUNC(dlarnv, DLARNV)(&idist, &iwork[1], n, &resid[1]); } if (*bmat == 'G') { ipntr[1] = 1; ipntr[2] = *n + 1; - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); *ido = -1; goto L9000; } @@ -579,7 +564,7 @@ F77_FUNC(dgetv0, DGETV0) (int * ido, iwork[5] = 1; if (*bmat == 'G') { - F77_FUNC(dcopy, DCOPY) (n, &workd[*n + 1], &c__1, &resid[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &workd[*n + 1], &c__1, &resid[1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -587,7 +572,7 @@ F77_FUNC(dgetv0, DGETV0) (int * ido, } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L20: @@ -596,12 +581,12 @@ L20: iwork[5] = 0; if (*bmat == 'G') { - workd[*n * 3 + 4] = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + workd[*n * 3 + 4] = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[1], &c__1); workd[*n * 3 + 4] = std::sqrt(std::abs(workd[*n * 3 + 4])); } else if (*bmat == 'I') { - workd[*n * 3 + 4] = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 4] = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } *rnorm = workd[*n * 3 + 4]; @@ -613,15 +598,15 @@ L20: L30: i__1 = *j - 1; - F77_FUNC(dgemv, DGEMV) ("T", n, &i__1, &c_b22, &v[v_offset], ldv, &workd[1], &c__1, &c_b24, - &workd[*n + 1], &c__1); + F77_FUNC(dgemv, DGEMV) + ("T", n, &i__1, &c_b22, &v[v_offset], ldv, &workd[1], &c__1, &c_b24, &workd[*n + 1], &c__1); i__1 = *j - 1; - F77_FUNC(dgemv, DGEMV) ("N", n, &i__1, &c_b27, &v[v_offset], ldv, &workd[*n + 1], &c__1, & - c_b22, &resid[1], &c__1); + F77_FUNC(dgemv, DGEMV) + ("N", n, &i__1, &c_b27, &v[v_offset], ldv, &workd[*n + 1], &c__1, &c_b22, &resid[1], &c__1); if (*bmat == 'G') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[*n + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[*n + 1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -629,19 +614,19 @@ L30: } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L40: if (*bmat == 'G') { - *rnorm = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + *rnorm = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[1], &c__1); *rnorm = std::sqrt(std::abs(*rnorm)); } else if (*bmat == 'I') { - *rnorm = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + *rnorm = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } if (*rnorm > workd[*n * 3 + 4] * .717F) @@ -677,29 +662,24 @@ L9000: } - - - -static void -F77_FUNC(dsapps, DSAPPS) (int * n, - int * kev, - int * np, - double * shift, - double * v, - int * ldv, - double * h__, - int * ldh, - double * resid, - double * q, - int * ldq, - double * workd) +static void F77_FUNC(dsapps, DSAPPS)(int* n, + int* kev, + int* np, + double* shift, + double* v, + int* ldv, + double* h__, + int* ldh, + double* resid, + double* q, + int* ldq, + double* workd) { double c_b4 = 0.; double c_b5 = 1.; double c_b14 = -1.; int c__1 = 1; - int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, - i__3, i__4; + int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4; double c__, f, g; int i__, j; double r__, s, a1, a2, a3, a4; @@ -714,13 +694,13 @@ F77_FUNC(dsapps, DSAPPS) (int * n, --shift; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; - q -= q_offset; + q -= q_offset; epsmch = GMX_DOUBLE_EPS; itop = 1; @@ -728,7 +708,7 @@ F77_FUNC(dsapps, DSAPPS) (int * n, kplusp = *kev + *np; - F77_FUNC(dlaset, DLASET) ("All", &kplusp, &kplusp, &c_b4, &c_b5, &q[q_offset], ldq); + F77_FUNC(dlaset, DLASET)("All", &kplusp, &kplusp, &c_b4, &c_b5, &q[q_offset], ldq); if (*np == 0) { @@ -741,12 +721,12 @@ F77_FUNC(dsapps, DSAPPS) (int * n, istart = itop; -L20: + L20: i__2 = kplusp - 1; for (i__ = istart; i__ <= i__2; ++i__) { - big = std::abs(h__[i__ + (h_dim1*2)]) + std::abs(h__[i__ + 1 + (h_dim1*2)]); + big = std::abs(h__[i__ + (h_dim1 * 2)]) + std::abs(h__[i__ + 1 + (h_dim1 * 2)]); if (h__[i__ + 1 + h_dim1] <= epsmch * big) { h__[i__ + 1 + h_dim1] = 0.; @@ -755,23 +735,19 @@ L20: } } iend = kplusp; -L40: + L40: if (istart < iend) { f = h__[istart + (h_dim1 << 1)] - shift[jj]; g = h__[istart + 1 + h_dim1]; - F77_FUNC(dlartg, DLARTG) (&f, &g, &c__, &s, &r__); - - a1 = c__ * h__[istart + (h_dim1 << 1)] + s * h__[istart + 1 + - h_dim1]; - a2 = c__ * h__[istart + 1 + h_dim1] + s * h__[istart + 1 + ( - h_dim1 << 1)]; - a4 = c__ * h__[istart + 1 + (h_dim1 << 1)] - s * h__[istart + 1 + - h_dim1]; - a3 = c__ * h__[istart + 1 + h_dim1] - s * h__[istart + (h_dim1 << - 1)]; + F77_FUNC(dlartg, DLARTG)(&f, &g, &c__, &s, &r__); + + a1 = c__ * h__[istart + (h_dim1 << 1)] + s * h__[istart + 1 + h_dim1]; + a2 = c__ * h__[istart + 1 + h_dim1] + s * h__[istart + 1 + (h_dim1 << 1)]; + a4 = c__ * h__[istart + 1 + (h_dim1 << 1)] - s * h__[istart + 1 + h_dim1]; + a3 = c__ * h__[istart + 1 + h_dim1] - s * h__[istart + (h_dim1 << 1)]; h__[istart + (h_dim1 << 1)] = c__ * a1 + s * a2; h__[istart + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3; h__[istart + 1 + h_dim1] = c__ * a3 + s * a4; @@ -780,12 +756,10 @@ L40: i__2 = (i__3 < kplusp) ? i__3 : kplusp; for (j = 1; j <= i__2; ++j) { - a1 = c__ * q[j + istart * q_dim1] + s * q[j + (istart + 1) * - q_dim1]; - q[j + (istart + 1) * q_dim1] = -s * q[j + istart * q_dim1] + - c__ * q[j + (istart + 1) * q_dim1]; + a1 = c__ * q[j + istart * q_dim1] + s * q[j + (istart + 1) * q_dim1]; + q[j + (istart + 1) * q_dim1] = + -s * q[j + istart * q_dim1] + c__ * q[j + (istart + 1) * q_dim1]; q[j + istart * q_dim1] = a1; - } i__2 = iend - 1; @@ -796,7 +770,7 @@ L40: g = s * h__[i__ + 1 + h_dim1]; h__[i__ + 1 + h_dim1] = c__ * h__[i__ + 1 + h_dim1]; - F77_FUNC(dlartg, DLARTG) (&f, &g, &c__, &s, &r__); + F77_FUNC(dlartg, DLARTG)(&f, &g, &c__, &s, &r__); if (r__ < 0.) { @@ -807,14 +781,10 @@ L40: h__[i__ + h_dim1] = r__; - a1 = c__ * h__[i__ + (h_dim1 << 1)] + s * h__[i__ + 1 + - h_dim1]; - a2 = c__ * h__[i__ + 1 + h_dim1] + s * h__[i__ + 1 + (h_dim1 - << 1)]; - a3 = c__ * h__[i__ + 1 + h_dim1] - s * h__[i__ + (h_dim1 << 1) - ]; - a4 = c__ * h__[i__ + 1 + (h_dim1 << 1)] - s * h__[i__ + 1 + - h_dim1]; + a1 = c__ * h__[i__ + (h_dim1 << 1)] + s * h__[i__ + 1 + h_dim1]; + a2 = c__ * h__[i__ + 1 + h_dim1] + s * h__[i__ + 1 + (h_dim1 << 1)]; + a3 = c__ * h__[i__ + 1 + h_dim1] - s * h__[i__ + (h_dim1 << 1)]; + a4 = c__ * h__[i__ + 1 + (h_dim1 << 1)] - s * h__[i__ + 1 + h_dim1]; h__[i__ + (h_dim1 << 1)] = c__ * a1 + s * a2; h__[i__ + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3; @@ -824,15 +794,11 @@ L40: i__3 = (i__4 < kplusp) ? i__4 : kplusp; for (j = 1; j <= i__3; ++j) { - a1 = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * - q_dim1]; - q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + - c__ * q[j + (i__ + 1) * q_dim1]; + a1 = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * q_dim1]; + q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + c__ * q[j + (i__ + 1) * q_dim1]; q[j + i__ * q_dim1] = a1; } - } - } istart = iend + 1; @@ -840,7 +806,7 @@ L40: if (h__[iend + h_dim1] < 0.) { h__[iend + h_dim1] = -h__[iend + h_dim1]; - F77_FUNC(dscal, DSCAL) (&kplusp, &c_b14, &q[iend * q_dim1 + 1], &c__1); + F77_FUNC(dscal, DSCAL)(&kplusp, &c_b14, &q[iend * q_dim1 + 1], &c__1); } if (iend < kplusp) @@ -858,81 +824,70 @@ L40: ++itop; } -L90: - ; + L90:; } i__1 = kplusp - 1; for (i__ = itop; i__ <= i__1; ++i__) { - big = std::abs(h__[i__ + (h_dim1*2)]) + std::abs(h__[i__+ 1 + (h_dim1*2)]); + big = std::abs(h__[i__ + (h_dim1 * 2)]) + std::abs(h__[i__ + 1 + (h_dim1 * 2)]); if (h__[i__ + 1 + h_dim1] <= epsmch * big) { h__[i__ + 1 + h_dim1] = 0.; } - } if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(dgemv, DGEMV) ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * - q_dim1 + 1], &c__1, &c_b4, &workd[*n + 1], &c__1); + F77_FUNC(dgemv, DGEMV) + ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4, + &workd[*n + 1], &c__1); } i__1 = *kev; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = kplusp - i__ + 1; - F77_FUNC(dgemv, DGEMV) ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * - q_dim1 + 1], &c__1, &c_b4, &workd[1], &c__1); - F77_FUNC(dcopy, DCOPY) (n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], & - c__1); - + F77_FUNC(dgemv, DGEMV) + ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4, + &workd[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], &c__1); } - F77_FUNC(dlacpy, DLACPY) ("All", n, kev, &v[(*np + 1) * v_dim1 + 1], ldv, &v[v_offset], ldv); + F77_FUNC(dlacpy, DLACPY)("All", n, kev, &v[(*np + 1) * v_dim1 + 1], ldv, &v[v_offset], ldv); if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(dcopy, DCOPY) (n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &c__1); } - F77_FUNC(dscal, DSCAL) (n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1); + F77_FUNC(dscal, DSCAL)(n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1); if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(daxpy, DAXPY) (n, &h__[*kev + 1 + h_dim1], &v[(*kev + 1) * v_dim1 + 1], &c__1, - &resid[1], &c__1); + F77_FUNC(daxpy, DAXPY) + (n, &h__[*kev + 1 + h_dim1], &v[(*kev + 1) * v_dim1 + 1], &c__1, &resid[1], &c__1); } - L9000: return; - } - -static void -F77_FUNC(dsortr, DSORTR) (const char * which, - int * apply, - int * n, - double * x1, - double * x2) +static void F77_FUNC(dsortr, DSORTR)(const char* which, int* apply, int* n, double* x1, double* x2) { - int i__1; + int i__1; int i__, j, igap; double temp; - igap = *n / 2; if (!std::strncmp(which, "SA", 2)) { -L10: + L10: if (igap == 0) { goto L9000; @@ -941,7 +896,7 @@ L10: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L20: + L20: if (j < 0) { @@ -966,17 +921,15 @@ L20: } j -= igap; goto L20; -L30: - ; + L30:; } igap /= 2; goto L10; - } else if (!std::strncmp(which, "SM", 2)) { -L40: + L40: if (igap == 0) { goto L9000; @@ -985,7 +938,7 @@ L40: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L50: + L50: if (j < 0) { @@ -1010,17 +963,15 @@ L50: } j -= igap; goto L50; -L60: - ; + L60:; } igap /= 2; goto L40; - } else if (!std::strncmp(which, "LA", 2)) { -L70: + L70: if (igap == 0) { goto L9000; @@ -1029,7 +980,7 @@ L70: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L80: + L80: if (j < 0) { @@ -1054,18 +1005,16 @@ L80: } j -= igap; goto L80; -L90: - ; + L90:; } igap /= 2; goto L70; - } else if (!std::strncmp(which, "LM", 2)) { -L100: + L100: if (igap == 0) { goto L9000; @@ -1074,7 +1023,7 @@ L100: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L110: + L110: if (j < 0) { @@ -1099,8 +1048,7 @@ L110: } j -= igap; goto L110; -L120: - ; + L120:; } igap /= 2; goto L100; @@ -1108,37 +1056,28 @@ L120: L9000: return; - } - - -static void -F77_FUNC(dsesrt, DSESRT) (const char * which, - int * apply, - int * n, - double * x, - int * na, - double * a, - int * lda) +static void F77_FUNC(dsesrt, + DSESRT)(const char* which, int* apply, int* n, double* x, int* na, double* a, int* lda) { - int a_dim1, a_offset, i__1; - int c__1 = 1; + int a_dim1, a_offset, i__1; + int c__1 = 1; int i__, j, igap; double temp; a_dim1 = *lda; a_offset = 1 + a_dim1 * 0; - a -= a_offset; + a -= a_offset; igap = *n / 2; if (!std::strncmp(which, "SA", 2)) { -L10: + L10: if (igap == 0) { goto L9000; @@ -1147,7 +1086,7 @@ L10: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L20: + L20: if (j < 0) { @@ -1161,8 +1100,8 @@ L20: x[j + igap] = temp; if (*apply) { - F77_FUNC(dswap, DSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(dswap, DSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -1171,17 +1110,15 @@ L20: } j -= igap; goto L20; -L30: - ; + L30:; } igap /= 2; goto L10; - } else if (!std::strncmp(which, "SM", 2)) { -L40: + L40: if (igap == 0) { goto L9000; @@ -1190,7 +1127,7 @@ L40: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L50: + L50: if (j < 0) { @@ -1204,8 +1141,8 @@ L50: x[j + igap] = temp; if (*apply) { - F77_FUNC(dswap, DSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(dswap, DSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -1214,17 +1151,15 @@ L50: } j -= igap; goto L50; -L60: - ; + L60:; } igap /= 2; goto L40; - } else if (!std::strncmp(which, "LA", 2)) { -L70: + L70: if (igap == 0) { goto L9000; @@ -1233,7 +1168,7 @@ L70: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L80: + L80: if (j < 0) { @@ -1247,8 +1182,8 @@ L80: x[j + igap] = temp; if (*apply) { - F77_FUNC(dswap, DSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(dswap, DSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -1257,17 +1192,15 @@ L80: } j -= igap; goto L80; -L90: - ; + L90:; } igap /= 2; goto L70; - } else if (!std::strncmp(which, "LM", 2)) { -L100: + L100: if (igap == 0) { goto L9000; @@ -1276,7 +1209,7 @@ L100: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L110: + L110: if (j < 0) { @@ -1290,8 +1223,8 @@ L110: x[j + igap] = temp; if (*apply) { - F77_FUNC(dswap, DSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(dswap, DSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -1300,8 +1233,7 @@ L110: } j -= igap; goto L110; -L120: - ; + L120:; } igap /= 2; goto L100; @@ -1309,20 +1241,11 @@ L120: L9000: return; - } - - -static void -F77_FUNC(dsgets, DSGETS) (int * ishift, - const char * which, - int * kev, - int * np, - double * ritz, - double * bounds, - double * shifts) +static void F77_FUNC(dsgets, + DSGETS)(int* ishift, const char* which, int* kev, int* np, double* ritz, double* bounds, double* shifts) { int c__1 = 1; int i__1, i__2; @@ -1335,32 +1258,29 @@ F77_FUNC(dsgets, DSGETS) (int * ishift, if (!std::strncmp(which, "BE", 2)) { i__1 = *kev + *np; - F77_FUNC(dsortr, DSORTR) ("LA", &c__1, &i__1, &ritz[1], &bounds[1]); + F77_FUNC(dsortr, DSORTR)("LA", &c__1, &i__1, &ritz[1], &bounds[1]); kevd2 = *kev / 2; if (*kev > 1) { i__1 = (kevd2 < *np) ? kevd2 : *np; i__2 = (kevd2 > *np) ? kevd2 : *np; - F77_FUNC(dswap, DSWAP) (&i__1, &ritz[1], &c__1, - &ritz[i__2 + 1], &c__1); + F77_FUNC(dswap, DSWAP)(&i__1, &ritz[1], &c__1, &ritz[i__2 + 1], &c__1); i__1 = (kevd2 < *np) ? kevd2 : *np; i__2 = (kevd2 > *np) ? kevd2 : *np; - F77_FUNC(dswap, DSWAP) (&i__1, &bounds[1], &c__1, - &bounds[i__2 + 1], &c__1); + F77_FUNC(dswap, DSWAP)(&i__1, &bounds[1], &c__1, &bounds[i__2 + 1], &c__1); } - } else { i__1 = *kev + *np; - F77_FUNC(dsortr, DSORTR) (which, &c__1, &i__1, &ritz[1], &bounds[1]); + F77_FUNC(dsortr, DSORTR)(which, &c__1, &i__1, &ritz[1], &bounds[1]); } if (*ishift == 1 && *np > 0) { - F77_FUNC(dsortr, DSORTR) ("SM", &c__1, np, &bounds[1], &ritz[1]); - F77_FUNC(dcopy, DCOPY) (np, &ritz[1], &c__1, &shifts[1], &c__1); + F77_FUNC(dsortr, DSORTR)("SM", &c__1, np, &bounds[1], &ritz[1]); + F77_FUNC(dcopy, DCOPY)(np, &ritz[1], &c__1, &shifts[1], &c__1); } @@ -1368,15 +1288,9 @@ F77_FUNC(dsgets, DSGETS) (int * ishift, } - -static void -F77_FUNC(dsconv, DSCONV) (int * n, - double * ritz, - double * bounds, - double * tol, - int * nconv) +static void F77_FUNC(dsconv, DSCONV)(int* n, double* ritz, double* bounds, double* tol, int* nconv) { - double c_b3 = 2/3.; + double c_b3 = 2 / 3.; int i__1; double d__2, d__3; @@ -1407,15 +1321,14 @@ F77_FUNC(dsconv, DSCONV) (int * n, } -static void -F77_FUNC(dseigt, DSEIGT) (double * rnorm, - int * n, - double * h__, - int * ldh, - double * eig, - double * bounds, - double * workl, - int * ierr) +static void F77_FUNC(dseigt, DSEIGT)(double* rnorm, + int* n, + double* h__, + int* ldh, + double* eig, + double* bounds, + double* workl, + int* ierr) { int c__1 = 1; int h_dim1, h_offset, i__1; @@ -1428,12 +1341,12 @@ F77_FUNC(dseigt, DSEIGT) (double * rnorm, --eig; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; - F77_FUNC(dcopy, DCOPY) (n, &h__[(h_dim1 << 1) + 1], &c__1, &eig[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &h__[(h_dim1 << 1) + 1], &c__1, &eig[1], &c__1); i__1 = *n - 1; - F77_FUNC(dcopy, DCOPY) (&i__1, &h__[h_dim1 + 2], &c__1, &workl[1], &c__1); - F77_FUNC(dstqrb, DSTQRB) (n, &eig[1], &workl[1], &bounds[1], &workl[*n + 1], ierr); + F77_FUNC(dcopy, DCOPY)(&i__1, &h__[h_dim1 + 2], &c__1, &workl[1], &c__1); + F77_FUNC(dstqrb, DSTQRB)(n, &eig[1], &workl[1], &bounds[1], &workl[*n + 1], ierr); if (*ierr != 0) { goto L9000; @@ -1443,7 +1356,6 @@ F77_FUNC(dseigt, DSEIGT) (double * rnorm, for (k = 1; k <= i__1; ++k) { bounds[k] = *rnorm * std::abs(bounds[k]); - } @@ -1452,25 +1364,22 @@ L9000: } - - -static void -F77_FUNC(dsaitr, DSAITR) (int * ido, - const char * bmat, - int * n, - int * k, - int * np, - int * mode, - double * resid, - double * rnorm, - double * v, - int * ldv, - double * h__, - int * ldh, - int * ipntr, - double * workd, - int * iwork, - int * info) +static void F77_FUNC(dsaitr, DSAITR)(int* ido, + const char* bmat, + int* n, + int* k, + int* np, + int* mode, + double* resid, + double* rnorm, + double* v, + int* ldv, + double* h__, + int* ldh, + int* ipntr, + double* workd, + int* iwork, + int* info) { int c__0 = 0; @@ -1490,10 +1399,10 @@ F77_FUNC(dsaitr, DSAITR) (int * ido, --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; --ipntr; --iwork; minval = GMX_DOUBLE_MIN; @@ -1550,8 +1459,9 @@ L20: *ido = 0; L30: - F77_FUNC(dgetv0, DGETV0) (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, - &resid[1], rnorm, &ipntr[1], &workd[1], &iwork[21], &iwork[7]); + F77_FUNC(dgetv0, DGETV0) + (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, &resid[1], rnorm, &ipntr[1], + &workd[1], &iwork[21], &iwork[7]); if (*ido != 99) { goto L9000; @@ -1571,24 +1481,24 @@ L30: L40: - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &v[iwork[12] * v_dim1 + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &v[iwork[12] * v_dim1 + 1], &c__1); if (*rnorm >= safmin) { temp1 = 1. / *rnorm; - F77_FUNC(dscal, DSCAL) (n, &temp1, &v[iwork[12] * v_dim1 + 1], &c__1); - F77_FUNC(dscal, DSCAL) (n, &temp1, &workd[iwork[8]], &c__1); + F77_FUNC(dscal, DSCAL)(n, &temp1, &v[iwork[12] * v_dim1 + 1], &c__1); + F77_FUNC(dscal, DSCAL)(n, &temp1, &workd[iwork[8]], &c__1); } else { - F77_FUNC(dlascl, DLASCL) ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &v[iwork[12] * - v_dim1 + 1], n, &infol); - F77_FUNC(dlascl, DLASCL) ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &workd[iwork[ - 8]], n, &infol); + F77_FUNC(dlascl, DLASCL) + ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &v[iwork[12] * v_dim1 + 1], n, &infol); + F77_FUNC(dlascl, DLASCL) + ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &workd[iwork[8]], n, &infol); } iwork[5] = 1; - F77_FUNC(dcopy, DCOPY) (n, &v[iwork[12] * v_dim1 + 1], &c__1, &workd[iwork[10]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &v[iwork[12] * v_dim1 + 1], &c__1, &workd[iwork[10]], &c__1); ipntr[1] = iwork[10]; ipntr[2] = iwork[9]; ipntr[3] = iwork[8]; @@ -1600,7 +1510,7 @@ L50: iwork[5] = 0; - F77_FUNC(dcopy, DCOPY) (n, &workd[iwork[9]], &c__1, &resid[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &workd[iwork[9]], &c__1, &resid[1], &c__1); if (*mode == 2) { @@ -1617,7 +1527,7 @@ L50: } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L60: @@ -1627,34 +1537,34 @@ L65: if (*mode == 2) { - workd[*n * 3 + 3] = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[iwork[10]], & - c__1); + workd[*n * 3 + 3] = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[iwork[10]], &c__1); workd[*n * 3 + 3] = std::sqrt(std::abs(workd[*n * 3 + 3])); } else if (*bmat == 'G') { - workd[*n * 3 + 3] = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[iwork[8]], & - c__1); + workd[*n * 3 + 3] = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); workd[*n * 3 + 3] = std::sqrt(std::abs(workd[*n * 3 + 3])); } else if (*bmat == 'I') { - workd[*n * 3 + 3] = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 3] = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } if (*mode != 2) { - F77_FUNC(dgemv, DGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], - &c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(dgemv, DGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); } else { - F77_FUNC(dgemv, DGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10] - ], &c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(dgemv, DGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); } - F77_FUNC(dgemv, DGEMV) ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], & - c__1, &c_b18, &resid[1], &c__1); + F77_FUNC(dgemv, DGEMV) + ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1); h__[iwork[12] + (h_dim1 << 1)] = workd[iwork[9] + iwork[12] - 1]; if (iwork[12] == 1 || iwork[4] == 1) @@ -1671,7 +1581,7 @@ L65: if (*bmat == 'G') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[iwork[9]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[iwork[9]], &c__1); ipntr[1] = iwork[9]; ipntr[2] = iwork[8]; *ido = 2; @@ -1680,7 +1590,7 @@ L65: } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L70: @@ -1688,12 +1598,12 @@ L70: if (*bmat == 'G') { - *rnorm = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + *rnorm = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); *rnorm = std::sqrt(std::abs(*rnorm)); } else if (*bmat == 'I') { - *rnorm = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + *rnorm = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } if (*rnorm > workd[*n * 3 + 3] * .717F) @@ -1703,11 +1613,12 @@ L70: L80: - F77_FUNC(dgemv, DGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], & - c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(dgemv, DGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); - F77_FUNC(dgemv, DGEMV) ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], & - c__1, &c_b18, &resid[1], &c__1); + F77_FUNC(dgemv, DGEMV) + ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1); if (iwork[12] == 1 || iwork[4] == 1) { @@ -1718,7 +1629,7 @@ L80: iwork[3] = 1; if (*bmat == 'G') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[iwork[9]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[iwork[9]], &c__1); ipntr[1] = iwork[9]; ipntr[2] = iwork[8]; *ido = 2; @@ -1727,20 +1638,19 @@ L80: } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L90: if (*bmat == 'G') { - workd[*n * 3 + 2] = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[iwork[8]], & - c__1); + workd[*n * 3 + 2] = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); workd[*n * 3 + 2] = std::sqrt(std::abs(workd[*n * 3 + 2])); } else if (*bmat == 'I') { - workd[*n * 3 + 2] = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 2] = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } @@ -1748,7 +1658,6 @@ L90: { *rnorm = workd[*n * 3 + 2]; - } else { @@ -1778,11 +1687,11 @@ L100: h__[iwork[12] + h_dim1] = -h__[iwork[12] + h_dim1]; if (iwork[12] < *k + *np) { - F77_FUNC(dscal, DSCAL) (n, &c_b50, &v[(iwork[12] + 1) * v_dim1 + 1], &c__1); + F77_FUNC(dscal, DSCAL)(n, &c_b50, &v[(iwork[12] + 1) * v_dim1 + 1], &c__1); } else { - F77_FUNC(dscal, DSCAL) (n, &c_b50, &resid[1], &c__1); + F77_FUNC(dscal, DSCAL)(n, &c_b50, &resid[1], &c__1); } } @@ -1802,43 +1711,37 @@ L9000: } - - - - -static void -F77_FUNC(dsaup2, DSAUP2) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - int * np, - double * tol, - double * resid, - int * mode, - int gmx_unused * iupd, - int * ishift, - int * mxiter, - double * v, - int * ldv, - double * h__, - int * ldh, - double * ritz, - double * bounds, - double * q, - int * ldq, - double * workl, - int * ipntr, - double * workd, - int * iwork, - int * info) +static void F77_FUNC(dsaup2, DSAUP2)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + int* np, + double* tol, + double* resid, + int* mode, + int gmx_unused* iupd, + int* ishift, + int* mxiter, + double* v, + int* ldv, + double* h__, + int* ldh, + double* ritz, + double* bounds, + double* q, + int* ldq, + double* workl, + int* ipntr, + double* workd, + int* iwork, + int* info) { - double c_b3 = 2/3.; + double c_b3 = 2 / 3.; int c__1 = 1; int c__0 = 0; - int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, - i__3; + int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, i__3; double d__2, d__3; int j; double eps23; @@ -1857,13 +1760,13 @@ F77_FUNC(dsaup2, DSAUP2) (int * ido, --ritz; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; - q -= q_offset; + q -= q_offset; --ipntr; --iwork; eps23 = GMX_DOUBLE_EPS; @@ -1903,9 +1806,9 @@ F77_FUNC(dsaup2, DSAUP2) (int * ido, if (iwork[2] == 1) { - F77_FUNC(dgetv0, DGETV0) (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, & - resid[1], &workd[*n * 3 + 1], &ipntr[1], &workd[1], &iwork[41], - info); + F77_FUNC(dgetv0, DGETV0) + (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, &resid[1], &workd[*n * 3 + 1], + &ipntr[1], &workd[1], &iwork[41], info); if (*ido != 99) { @@ -1937,9 +1840,9 @@ F77_FUNC(dsaup2, DSAUP2) (int * ido, goto L100; } - F77_FUNC(dsaitr, DSAITR) (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + - 1], &v[v_offset], ldv, &h__[h_offset], ldh, &ipntr[1], &workd[1], - &iwork[21], info); + F77_FUNC(dsaitr, DSAITR) + (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, + &h__[h_offset], ldh, &ipntr[1], &workd[1], &iwork[21], info); if (*ido != 99) { @@ -1964,9 +1867,9 @@ L1000: L20: iwork[4] = 1; - F77_FUNC(dsaitr, DSAITR) (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], - &v[v_offset], ldv, &h__[h_offset], ldh, &ipntr[1], &workd[1], - &iwork[21], info); + F77_FUNC(dsaitr, DSAITR) + (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, &h__[h_offset], + ldh, &ipntr[1], &workd[1], &iwork[21], info); if (*ido != 99) { @@ -1983,8 +1886,8 @@ L20: } iwork[4] = 0; - F77_FUNC(dseigt, DSEIGT) (&workd[*n * 3 + 1], &iwork[7], &h__[h_offset], ldh, &ritz[1], & - bounds[1], &workl[1], &ierr); + F77_FUNC(dseigt, DSEIGT) + (&workd[*n * 3 + 1], &iwork[7], &h__[h_offset], ldh, &ritz[1], &bounds[1], &workl[1], &ierr); if (ierr != 0) { @@ -1992,15 +1895,15 @@ L20: goto L1200; } - F77_FUNC(dcopy, DCOPY) (&iwork[7], &ritz[1], &c__1, &workl[iwork[7] + 1], &c__1); - F77_FUNC(dcopy, DCOPY) (&iwork[7], &bounds[1], &c__1, &workl[(iwork[7] << 1) + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(&iwork[7], &ritz[1], &c__1, &workl[iwork[7] + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(&iwork[7], &bounds[1], &c__1, &workl[(iwork[7] << 1) + 1], &c__1); *nev = iwork[9]; *np = iwork[10]; - F77_FUNC(dsgets, DSGETS) (ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); + F77_FUNC(dsgets, DSGETS)(ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); - F77_FUNC(dcopy, DCOPY) (nev, &bounds[*np + 1], &c__1, &workl[*np + 1], &c__1); - F77_FUNC(dsconv, DSCONV) (nev, &ritz[*np + 1], &workl[*np + 1], tol, &iwork[8]); + F77_FUNC(dcopy, DCOPY)(nev, &bounds[*np + 1], &c__1, &workl[*np + 1], &c__1); + F77_FUNC(dsconv, DSCONV)(nev, &ritz[*np + 1], &workl[*np + 1], tol, &iwork[8]); nptemp = *np; i__1 = nptemp; @@ -2020,23 +1923,20 @@ L20: { std::strncpy(wprime, "SA", 2); - F77_FUNC(dsortr, DSORTR) (wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); + F77_FUNC(dsortr, DSORTR)(wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); nevd2 = *nev / 2; nevm2 = *nev - nevd2; if (*nev > 1) { i__1 = (nevd2 < *np) ? nevd2 : *np; i__2 = iwork[7] - nevd2 + 1, i__3 = iwork[7] - *np + 1; - F77_FUNC(dswap, DSWAP) (&i__1, &ritz[nevm2 + 1], &c__1, - &ritz[((i__2 > i__3) ? i__2 : i__3)], - &c__1); + F77_FUNC(dswap, DSWAP) + (&i__1, &ritz[nevm2 + 1], &c__1, &ritz[((i__2 > i__3) ? i__2 : i__3)], &c__1); i__1 = (nevd2 < *np) ? nevd2 : *np; i__2 = iwork[7] - nevd2 + 1, i__3 = iwork[7] - *np; - F77_FUNC(dswap, DSWAP) (&i__1, &bounds[nevm2 + 1], &c__1, - &bounds[((i__2 > i__3) ? i__2 : i__3) + 1], - &c__1); + F77_FUNC(dswap, DSWAP) + (&i__1, &bounds[nevm2 + 1], &c__1, &bounds[((i__2 > i__3) ? i__2 : i__3) + 1], &c__1); } - } else { @@ -2058,28 +1958,27 @@ L20: std::strncpy(wprime, "LA", 2); } - F77_FUNC(dsortr, DSORTR) (wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); - + F77_FUNC(dsortr, DSORTR)(wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); } i__1 = iwork[9]; for (j = 1; j <= i__1; ++j) { - d__2 = eps23; - d__3 = std::abs(ritz[j]); - temp = (d__2 > d__3) ? d__2 : d__3; + d__2 = eps23; + d__3 = std::abs(ritz[j]); + temp = (d__2 > d__3) ? d__2 : d__3; bounds[j] /= temp; } std::strncpy(wprime, "LA", 2); - F77_FUNC(dsortr, DSORTR) (wprime, &c__1, &iwork[9], &bounds[1], &ritz[1]); + F77_FUNC(dsortr, DSORTR)(wprime, &c__1, &iwork[9], &bounds[1], &ritz[1]); i__1 = iwork[9]; for (j = 1; j <= i__1; ++j) { - d__2 = eps23; - d__3 = std::abs(ritz[j]); - temp = (d__2 > d__3) ? d__2 : d__3; + d__2 = eps23; + d__3 = std::abs(ritz[j]); + temp = (d__2 > d__3) ? d__2 : d__3; bounds[j] *= temp; } @@ -2087,13 +1986,11 @@ L20: { std::strncpy(wprime, "LA", 2); - F77_FUNC(dsortr, DSORTR) (wprime, &c__1, &iwork[8], &ritz[1], &bounds[1]); - + F77_FUNC(dsortr, DSORTR)(wprime, &c__1, &iwork[8], &ritz[1], &bounds[1]); } else { - F77_FUNC(dsortr, DSORTR) (which, &c__1, &iwork[8], &ritz[1], &bounds[1]); - + F77_FUNC(dsortr, DSORTR)(which, &c__1, &iwork[8], &ritz[1], &bounds[1]); } h__[h_dim1 + 1] = workd[*n * 3 + 1]; @@ -2110,13 +2007,12 @@ L20: *np = iwork[8]; goto L1100; - } else if (iwork[8] < *nev && *ishift == 1) { nevbef = *nev; - i__1 = iwork[8], i__2 = *np / 2; - *nev += (i__1 < i__2) ? i__1 : i__2; + i__1 = iwork[8], i__2 = *np / 2; + *nev += (i__1 < i__2) ? i__1 : i__2; if (*nev == 1 && iwork[7] >= 6) { *nev = iwork[7] / 2; @@ -2130,9 +2026,8 @@ L20: if (nevbef < *nev) { - F77_FUNC(dsgets, DSGETS) (ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); + F77_FUNC(dsgets, DSGETS)(ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); } - } @@ -2150,16 +2045,17 @@ L50: if (*ishift == 0) { - F77_FUNC(dcopy, DCOPY) (np, &workl[1], &c__1, &ritz[1], &c__1); + F77_FUNC(dcopy, DCOPY)(np, &workl[1], &c__1, &ritz[1], &c__1); } - F77_FUNC(dsapps, DSAPPS) (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, & - resid[1], &q[q_offset], ldq, &workd[1]); + F77_FUNC(dsapps, DSAPPS) + (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq, + &workd[1]); iwork[1] = 1; if (*bmat == 'G') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[*n + 1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[*n + 1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -2168,19 +2064,19 @@ L50: } else if (*bmat == 'I') { - F77_FUNC(dcopy, DCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(dcopy, DCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L100: if (*bmat == 'G') { - workd[*n * 3 + 1] = F77_FUNC(ddot, DDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + workd[*n * 3 + 1] = F77_FUNC(ddot, DDOT)(n, &resid[1], &c__1, &workd[1], &c__1); workd[*n * 3 + 1] = std::sqrt(std::abs(workd[*n * 3 + 1])); } else if (*bmat == 'I') { - workd[*n * 3 + 1] = F77_FUNC(dnrm2, DNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 1] = F77_FUNC(dnrm2, DNRM2)(n, &resid[1], &c__1); } iwork[1] = 0; @@ -2196,29 +2092,26 @@ L1200: L9000: return; - } - -void -F77_FUNC(dsaupd, DSAUPD) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - double * tol, - double * resid, - int * ncv, - double * v, - int * ldv, - int * iparam, - int * ipntr, - double * workd, - int * iwork, - double * workl, - int * lworkl, - int * info) +void F77_FUNC(dsaupd, DSAUPD)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + double* tol, + double* resid, + int* ncv, + double* v, + int* ldv, + int* iparam, + int* ipntr, + double* workd, + int* iwork, + double* workl, + int* lworkl, + int* info) { int v_dim1, v_offset, i__1, i__2; int j; @@ -2227,7 +2120,7 @@ F77_FUNC(dsaupd, DSAUPD) (int * ido, --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --iparam; --ipntr; --iwork; @@ -2266,9 +2159,8 @@ F77_FUNC(dsaupd, DSAUPD) (int * ido, { iwork[2] = -4; } - if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && - std::strncmp(which, "LA", 2) && std::strncmp(which, "SA", 2) && - std::strncmp(which, "BE", 2)) + if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && std::strncmp(which, "LA", 2) + && std::strncmp(which, "SA", 2) && std::strncmp(which, "BE", 2)) { iwork[2] = -5; } @@ -2341,11 +2233,10 @@ F77_FUNC(dsaupd, DSAUPD) (int * ido, ipntr[11] = iwork[7]; } - F77_FUNC(dsaup2, DSAUP2) (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], & - iwork[11], &iwork[6], &iwork[5], &iwork[10], &v[v_offset], ldv, & - workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]], & - workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], - &iwork[21], info); + F77_FUNC(dsaup2, DSAUP2) + (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], &iwork[11], &iwork[6], &iwork[5], + &iwork[10], &v[v_offset], ldv, &workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]], + &workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], &iwork[21], info); if (*ido == 3) { @@ -2371,36 +2262,33 @@ F77_FUNC(dsaupd, DSAUPD) (int * ido, L9000: return; - } - -void -F77_FUNC(dseupd, DSEUPD) (int * rvec, - const char * howmny, - int * select, - double * d__, - double * z__, - int * ldz, - double * sigma, - const char * bmat, - int * n, - const char * which, - int * nev, - double * tol, - double * resid, - int * ncv, - double * v, - int * ldv, - int * iparam, - int * ipntr, - double * workd, - double * workl, - int * lworkl, - int * info) +void F77_FUNC(dseupd, DSEUPD)(int* rvec, + const char* howmny, + int* select, + double* d__, + double* z__, + int* ldz, + double* sigma, + const char* bmat, + int* n, + const char* which, + int* nev, + double* tol, + double* resid, + int* ncv, + double* v, + int* ldv, + int* iparam, + int* ipntr, + double* workd, + double* workl, + int* lworkl, + int* info) { - double c_b21 = 2/3.; + double c_b21 = 2 / 3.; int c__1 = 1; double c_b102 = 1.; int v_dim1, v_offset, z_dim1, z_offset, i__1; @@ -2429,12 +2317,12 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, --resid; z_dim1 = *ldz; z_offset = 1 + z_dim1; - z__ -= z_offset; + z__ -= z_offset; --d__; --select; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --iparam; --ipntr; --workl; @@ -2465,9 +2353,8 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, { ierr = -3; } - if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && - std::strncmp(which, "LA", 2) && std::strncmp(which, "SA", 2) && - std::strncmp(which, "BE", 2)) + if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && std::strncmp(which, "LA", 2) + && std::strncmp(which, "SA", 2) && std::strncmp(which, "BE", 2)) { ierr = -5; } @@ -2475,8 +2362,7 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, { ierr = -6; } - if (*howmny != 'A' && *howmny != 'P' && - *howmny != 'S' && *rvec) + if (*howmny != 'A' && *howmny != 'P' && *howmny != 'S' && *rvec) { ierr = -15; } @@ -2554,28 +2440,24 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, } else if (*bmat == 'G') { - bnorm2 = F77_FUNC(dnrm2, DNRM2) (n, &workd[1], &c__1); + bnorm2 = F77_FUNC(dnrm2, DNRM2)(n, &workd[1], &c__1); } if (*rvec) { - if (!std::strncmp(which, "LM", 2) || !std::strncmp(which, "SM", 2) || - !std::strncmp(which, "LA", 2) || !std::strncmp(which, "SA", 2)) - { - - } + if (!std::strncmp(which, "LM", 2) || !std::strncmp(which, "SM", 2) + || !std::strncmp(which, "LA", 2) || !std::strncmp(which, "SA", 2)) + {} else if (!std::strncmp(which, "BE", 2)) { - ism = (*nev > nconv) ? *nev : nconv; - ism /= 2; + ism = (*nev > nconv) ? *nev : nconv; + ism /= 2; ilg = ism + 1; thres1 = workl[ism]; thres2 = workl[ilg]; - - } reord = 0; @@ -2660,11 +2542,11 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, } i__1 = *ncv - 1; - F77_FUNC(dcopy, DCOPY) (&i__1, &workl[ih + 1], &c__1, &workl[ihb], &c__1); - F77_FUNC(dcopy, DCOPY) (ncv, &workl[ih + ldh], &c__1, &workl[ihd], &c__1); + F77_FUNC(dcopy, DCOPY)(&i__1, &workl[ih + 1], &c__1, &workl[ihb], &c__1); + F77_FUNC(dcopy, DCOPY)(ncv, &workl[ih + ldh], &c__1, &workl[ihd], &c__1); - F77_FUNC(dsteqr, DSTEQR) ("Identity", ncv, &workl[ihd], &workl[ihb], &workl[iq], &ldq, & - workl[iw], &ierr); + F77_FUNC(dsteqr, DSTEQR) + ("Identity", ncv, &workl[ihd], &workl[ihb], &workl[iq], &ldq, &workl[iw], &ierr); if (ierr != 0) { @@ -2684,18 +2566,16 @@ F77_FUNC(dseupd, DSEUPD) (int * rvec, goto L30; } -L20: + L20: if (select[leftptr]) { ++leftptr; - } else if (!select[rghtptr]) { --rghtptr; - } else { @@ -2703,15 +2583,14 @@ L20: temp = workl[ihd + leftptr - 1]; workl[ihd + leftptr - 1] = workl[ihd + rghtptr - 1]; workl[ihd + rghtptr - 1] = temp; - F77_FUNC(dcopy, DCOPY) (ncv, &workl[iq + *ncv * (leftptr - 1)], &c__1, &workl[ - iw], &c__1); - F77_FUNC(dcopy, DCOPY) (ncv, &workl[iq + *ncv * (rghtptr - 1)], &c__1, &workl[ - iq + *ncv * (leftptr - 1)], &c__1); - F77_FUNC(dcopy, DCOPY) (ncv, &workl[iw], &c__1, &workl[iq + *ncv * (rghtptr - - 1)], &c__1); + F77_FUNC(dcopy, DCOPY) + (ncv, &workl[iq + *ncv * (leftptr - 1)], &c__1, &workl[iw], &c__1); + F77_FUNC(dcopy, DCOPY) + (ncv, &workl[iq + *ncv * (rghtptr - 1)], &c__1, &workl[iq + *ncv * (leftptr - 1)], &c__1); + F77_FUNC(dcopy, DCOPY) + (ncv, &workl[iw], &c__1, &workl[iq + *ncv * (rghtptr - 1)], &c__1); ++leftptr; --rghtptr; - } if (leftptr < rghtptr) @@ -2719,37 +2598,33 @@ L20: goto L20; } -L30: - ; + L30:; } - F77_FUNC(dcopy, DCOPY) (&nconv, &workl[ihd], &c__1, &d__[1], &c__1); - + F77_FUNC(dcopy, DCOPY)(&nconv, &workl[ihd], &c__1, &d__[1], &c__1); } else { - F77_FUNC(dcopy, DCOPY) (&nconv, &workl[ritz], &c__1, &d__[1], &c__1); - F77_FUNC(dcopy, DCOPY) (ncv, &workl[ritz], &c__1, &workl[ihd], &c__1); - + F77_FUNC(dcopy, DCOPY)(&nconv, &workl[ritz], &c__1, &d__[1], &c__1); + F77_FUNC(dcopy, DCOPY)(ncv, &workl[ritz], &c__1, &workl[ihd], &c__1); } if (!std::strncmp(type__, "REGULR", 6)) { if (*rvec) { - F77_FUNC(dsesrt, DSESRT) ("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); + F77_FUNC(dsesrt, DSESRT)("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); } else { - F77_FUNC(dcopy, DCOPY) (ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); + F77_FUNC(dcopy, DCOPY)(ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); } - } else { - F77_FUNC(dcopy, DCOPY) (ncv, &workl[ihd], &c__1, &workl[iw], &c__1); + F77_FUNC(dcopy, DCOPY)(ncv, &workl[ihd], &c__1, &workl[iw], &c__1); if (!std::strncmp(type__, "SHIFTI", 6)) { i__1 = *ncv; @@ -2763,8 +2638,7 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihd + k - 1] = *sigma * workl[ihd + k - 1] / (workl[ihd - + k - 1] - 1.); + workl[ihd + k - 1] = *sigma * workl[ihd + k - 1] / (workl[ihd + k - 1] - 1.); } } else if (!std::strncmp(type__, "CAYLEY", 6)) @@ -2772,36 +2646,35 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihd + k - 1] = *sigma * (workl[ihd + k - 1] + 1.) / ( - workl[ihd + k - 1] - 1.); + workl[ihd + k - 1] = *sigma * (workl[ihd + k - 1] + 1.) / (workl[ihd + k - 1] - 1.); } } - F77_FUNC(dcopy, DCOPY) (&nconv, &workl[ihd], &c__1, &d__[1], &c__1); - F77_FUNC(dsortr, DSORTR) ("LA", &c__1, &nconv, &workl[ihd], &workl[iw]); + F77_FUNC(dcopy, DCOPY)(&nconv, &workl[ihd], &c__1, &d__[1], &c__1); + F77_FUNC(dsortr, DSORTR)("LA", &c__1, &nconv, &workl[ihd], &workl[iw]); if (*rvec) { - F77_FUNC(dsesrt, DSESRT) ("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); + F77_FUNC(dsesrt, DSESRT)("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); } else { - F77_FUNC(dcopy, DCOPY) (ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); + F77_FUNC(dcopy, DCOPY)(ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); d__1 = bnorm2 / rnorm; - F77_FUNC(dscal, DSCAL) (ncv, &d__1, &workl[ihb], &c__1); - F77_FUNC(dsortr, DSORTR) ("LA", &c__1, &nconv, &d__[1], &workl[ihb]); + F77_FUNC(dscal, DSCAL)(ncv, &d__1, &workl[ihb], &c__1); + F77_FUNC(dsortr, DSORTR)("LA", &c__1, &nconv, &d__[1], &workl[ihb]); } - } if (*rvec && *howmny == 'A') { - F77_FUNC(dgeqr2, DGEQR2) (ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], - &ierr); + F77_FUNC(dgeqr2, DGEQR2) + (ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], &ierr); - F77_FUNC(dorm2r, DORM2R) ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, & - workl[iw + *ncv], &v[v_offset], ldv, &workd[*n + 1], &ierr); - F77_FUNC(dlacpy, DLACPY) ("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz); + F77_FUNC(dorm2r, DORM2R) + ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &v[v_offset], + ldv, &workd[*n + 1], &ierr); + F77_FUNC(dlacpy, DLACPY)("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz); i__1 = *ncv - 1; for (j = 1; j <= i__1; ++j) @@ -2809,13 +2682,12 @@ L30: workl[ihb + j - 1] = 0.; } workl[ihb + *ncv - 1] = 1.; - F77_FUNC(dorm2r, DORM2R) ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, & - workl[iw + *ncv], &workl[ihb], ncv, &temp, &ierr); - + F77_FUNC(dorm2r, DORM2R) + ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], + ncv, &temp, &ierr); } else if (*rvec && *howmny == 'S') { - } if (!std::strncmp(type__, "REGULR", 6) && *rvec) @@ -2826,12 +2698,11 @@ L30: { workl[ihb + j - 1] = rnorm * std::abs(workl[ihb + j - 1]); } - } else if (std::strncmp(type__, "REGULR", 6) && *rvec) { - F77_FUNC(dscal, DSCAL) (ncv, &bnorm2, &workl[ihb], &c__1); + F77_FUNC(dscal, DSCAL)(ncv, &bnorm2, &workl[ihb], &c__1); if (!std::strncmp(type__, "SHIFTI", 6)) { @@ -2839,9 +2710,8 @@ L30: for (k = 1; k <= i__1; ++k) { d__2 = workl[iw + k - 1]; - workl[ihb + k - 1] = std::abs(workl[ihb + k - 1])/(d__2 * d__2); + workl[ihb + k - 1] = std::abs(workl[ihb + k - 1]) / (d__2 * d__2); } - } else if (!std::strncmp(type__, "BUCKLE", 6)) { @@ -2850,9 +2720,8 @@ L30: for (k = 1; k <= i__1; ++k) { d__2 = workl[iw + k - 1] - 1.; - workl[ihb + k - 1] = *sigma * std::abs(workl[ihb + k - 1])/(d__2 * d__2); + workl[ihb + k - 1] = *sigma * std::abs(workl[ihb + k - 1]) / (d__2 * d__2); } - } else if (!std::strncmp(type__, "CAYLEY", 6)) { @@ -2860,12 +2729,10 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihb + k - 1] = std::abs(workl[ihb + k - 1] / workl[iw + k - 1] * (workl[iw + k - 1] - 1.)); - + workl[ihb + k - 1] = + std::abs(workl[ihb + k - 1] / workl[iw + k - 1] * (workl[iw + k - 1] - 1.)); } - } - } if (*rvec && (!std::strncmp(type__, "SHIFTI", 6) || !std::strncmp(type__, "CAYLEY", 6))) @@ -2876,7 +2743,6 @@ L30: { workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / workl[iw + k]; } - } else if (*rvec && !std::strncmp(type__, "BUCKLE", 6)) { @@ -2884,38 +2750,26 @@ L30: i__1 = nconv - 1; for (k = 0; k <= i__1; ++k) { - workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / (workl[iw + k] - - 1.); + workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / (workl[iw + k] - 1.); } - } if (std::strncmp(type__, "REGULR", 6)) { - F77_FUNC(dger, DGER) (n, &nconv, &c_b102, &resid[1], &c__1, &workl[iw], &c__1, &z__[ - z_offset], ldz); + F77_FUNC(dger, DGER) + (n, &nconv, &c_b102, &resid[1], &c__1, &workl[iw], &c__1, &z__[z_offset], ldz); } L9000: return; - } - - - /* Selected single precision arpack routines */ -static void -F77_FUNC(sstqrb, SSTQRB) (int * n, - float * d__, - float * e, - float * z__, - float * work, - int * info) +static void F77_FUNC(sstqrb, SSTQRB)(int* n, float* d__, float* e, float* z__, float* work, int* info) { int i__1, i__2; float d__1, d__2; @@ -2970,7 +2824,6 @@ F77_FUNC(sstqrb, SSTQRB) (int * n, for (j = 1; j <= i__1; ++j) { z__[j] = 0.; - } z__[*n] = 1.; @@ -2999,7 +2852,7 @@ L10: { goto L30; } - if (tst <= std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m+1])) * eps) + if (tst <= std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) { e[m] = 0.; goto L30; @@ -3020,7 +2873,7 @@ L30: } i__1 = lend - l + 1; - anorm = F77_FUNC(slanst, SLANST) ("i", &i__1, &d__[l], &e[l]); + anorm = F77_FUNC(slanst, SLANST)("i", &i__1, &d__[l], &e[l]); iscale = 0; if (anorm == 0.) { @@ -3030,21 +2883,19 @@ L30: { iscale = 1; i__1 = lend - l + 1; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, - info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, - info); + F77_FUNC(slascl, SLASCL)("g", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, info); } else if (anorm < ssfmin) { iscale = 2; i__1 = lend - l + 1; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, - info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, info); i__1 = lend - l; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, - info); + F77_FUNC(slascl, SLASCL)("g", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, info); } if (std::abs(d__[lend]) < std::abs(d__[l])) @@ -3056,7 +2907,7 @@ L30: if (lend > l) { -L40: + L40: if (l != lend) { lendm1 = lend - 1; @@ -3074,7 +2925,7 @@ L40: m = lend; -L60: + L60: if (m < lend) { e[m] = 0.; @@ -3089,7 +2940,7 @@ L60: { if (icompz > 0) { - F77_FUNC(slaev2, SLAEV2) (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s); + F77_FUNC(slaev2, SLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s); work[l] = c__; work[*n - 1 + l] = s; @@ -3099,12 +2950,12 @@ L60: } else { - F77_FUNC(slae2, SLAE2) (&d__[l], &e[l], &d__[l + 1], &rt1, &rt2); + F77_FUNC(slae2, SLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2); } d__[l] = rt1; d__[l + 1] = rt2; e[l] = 0.; - l += 2; + l += 2; if (l <= lend) { goto L40; @@ -3119,8 +2970,8 @@ L60: ++jtot; g = (d__[l + 1] - p) / (e[l] * 2.); - r__ = F77_FUNC(slapy2, SLAPY2) (&g, &c_b31); - g = d__[m] - p + e[l] / (g + ((g > 0) ? r__ : -r__ )); + r__ = F77_FUNC(slapy2, SLAPY2)(&g, &c_b31); + g = d__[m] - p + e[l] / (g + ((g > 0) ? r__ : -r__)); s = 1.; c__ = 1.; @@ -3132,7 +2983,7 @@ L60: { f = s * e[i__]; b = c__ * e[i__]; - F77_FUNC(slartg, SLARTG) (&g, &f, &c__, &s, &r__); + F77_FUNC(slartg, SLARTG)(&g, &f, &c__, &s, &r__); if (i__ != m - 1) { e[i__ + 1] = r__; @@ -3148,22 +2999,21 @@ L60: work[i__] = c__; work[*n - 1 + i__] = -s; } - } if (icompz > 0) { mm = m - l + 1; - F77_FUNC(slasr, SLASR) ("r", "v", "b", &c__1, &mm, &work[l], &work[*n - 1 + l], & - z__[l], &c__1); + F77_FUNC(slasr, SLASR) + ("r", "v", "b", &c__1, &mm, &work[l], &work[*n - 1 + l], &z__[l], &c__1); } d__[l] -= p; - e[l] = g; + e[l] = g; goto L40; -L80: + L80: d__[l] = p; ++l; @@ -3172,12 +3022,11 @@ L80: goto L40; } goto L140; - } else { -L90: + L90: if (l != lend) { lendp1 = lend + 1; @@ -3186,7 +3035,7 @@ L90: { d__2 = std::abs(e[m - 1]); tst = d__2 * d__2; - if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) + if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m - 1]) + safmin) { goto L110; } @@ -3195,7 +3044,7 @@ L90: m = lend; -L110: + L110: if (m > lend) { e[m - 1] = 0.; @@ -3210,8 +3059,7 @@ L110: { if (icompz > 0) { - F77_FUNC(slaev2, SLAEV2) (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s) - ; + F77_FUNC(slaev2, SLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s); tst = z__[l]; z__[l] = c__ * tst - s * z__[l - 1]; @@ -3219,12 +3067,12 @@ L110: } else { - F77_FUNC(slae2, SLAE2) (&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2); + F77_FUNC(slae2, SLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2); } d__[l - 1] = rt1; d__[l] = rt2; e[l - 1] = 0.; - l += -2; + l += -2; if (l >= lend) { goto L90; @@ -3240,8 +3088,8 @@ L110: g = (d__[l - 1] - p) / (e[l - 1] * 2.); - r__ = F77_FUNC(slapy2, SLAPY2) (&g, &c_b31); - g = d__[m] - p + e[l - 1] / (g + ((g > 0) ? r__ : -r__ )); + r__ = F77_FUNC(slapy2, SLAPY2)(&g, &c_b31); + g = d__[m] - p + e[l - 1] / (g + ((g > 0) ? r__ : -r__)); s = 1.; c__ = 1.; @@ -3253,7 +3101,7 @@ L110: { f = s * e[i__]; b = c__ * e[i__]; - F77_FUNC(slartg, SLARTG) (&g, &f, &c__, &s, &r__); + F77_FUNC(slartg, SLARTG)(&g, &f, &c__, &s, &r__); if (i__ != m) { e[i__ - 1] = r__; @@ -3269,22 +3117,21 @@ L110: work[i__] = c__; work[*n - 1 + i__] = s; } - } if (icompz > 0) { mm = l - m + 1; - F77_FUNC(slasr, SLASR) ("r", "v", "f", &c__1, &mm, &work[m], &work[*n - 1 + m], & - z__[m], &c__1); + F77_FUNC(slasr, SLASR) + ("r", "v", "f", &c__1, &mm, &work[m], &work[*n - 1 + m], &z__[m], &c__1); } d__[l] -= p; - e[lm1] = g; + e[lm1] = g; goto L90; -L130: + L130: d__[l] = p; --l; @@ -3293,27 +3140,26 @@ L130: goto L90; } goto L140; - } L140: if (iscale == 1) { i__1 = lendsv - lsv + 1; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], - n, info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, - info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, info); } else if (iscale == 2) { i__1 = lendsv - lsv + 1; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], - n, info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], n, info); i__1 = lendsv - lsv; - F77_FUNC(slascl, SLASCL) ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, - info); + F77_FUNC(slascl, SLASCL) + ("g", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, info); } if (jtot < nmaxit) @@ -3334,8 +3180,7 @@ L160: if (icompz == 0) { - F77_FUNC(slasrt, SLASRT) ("i", n, &d__[1], info); - + F77_FUNC(slasrt, SLASRT)("i", n, &d__[1], info); } else { @@ -3369,24 +3214,22 @@ L160: L190: return; - } -static void -F77_FUNC(sgetv0, SGETV0) (int * ido, - const char * bmat, - int gmx_unused * itry, - int * initv, - int * n, - int * j, - float * v, - int * ldv, - float * resid, - float * rnorm, - int * ipntr, - float * workd, - int * iwork, - int * ierr) +static void F77_FUNC(sgetv0, SGETV0)(int* ido, + const char* bmat, + int gmx_unused* itry, + int* initv, + int* n, + int* j, + float* v, + int* ldv, + float* resid, + float* rnorm, + int* ipntr, + float* workd, + int* iwork, + int* ierr) { int c__1 = 1; float c_b22 = 1.; @@ -3394,14 +3237,14 @@ F77_FUNC(sgetv0, SGETV0) (int * ido, float c_b27 = -1.; int v_dim1, v_offset, i__1; - int jj; - int idist; + int jj; + int idist; --workd; --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --ipntr; --iwork; @@ -3416,14 +3259,14 @@ F77_FUNC(sgetv0, SGETV0) (int * ido, if (!(*initv)) { idist = 2; - F77_FUNC(slarnv, SLARNV) (&idist, &iwork[1], n, &resid[1]); + F77_FUNC(slarnv, SLARNV)(&idist, &iwork[1], n, &resid[1]); } if (*bmat == 'G') { ipntr[1] = 1; ipntr[2] = *n + 1; - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); *ido = -1; goto L9000; } @@ -3442,7 +3285,7 @@ F77_FUNC(sgetv0, SGETV0) (int * ido, iwork[5] = 1; if (*bmat == 'G') { - F77_FUNC(scopy, SCOPY) (n, &workd[*n + 1], &c__1, &resid[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &workd[*n + 1], &c__1, &resid[1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -3450,7 +3293,7 @@ F77_FUNC(sgetv0, SGETV0) (int * ido, } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L20: @@ -3459,12 +3302,12 @@ L20: iwork[5] = 0; if (*bmat == 'G') { - workd[*n * 3 + 4] = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + workd[*n * 3 + 4] = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[1], &c__1); workd[*n * 3 + 4] = std::sqrt(std::abs(workd[*n * 3 + 4])); } else if (*bmat == 'I') { - workd[*n * 3 + 4] = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 4] = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } *rnorm = workd[*n * 3 + 4]; @@ -3476,15 +3319,15 @@ L20: L30: i__1 = *j - 1; - F77_FUNC(sgemv, SGEMV) ("T", n, &i__1, &c_b22, &v[v_offset], ldv, &workd[1], &c__1, &c_b24, - &workd[*n + 1], &c__1); + F77_FUNC(sgemv, SGEMV) + ("T", n, &i__1, &c_b22, &v[v_offset], ldv, &workd[1], &c__1, &c_b24, &workd[*n + 1], &c__1); i__1 = *j - 1; - F77_FUNC(sgemv, SGEMV) ("N", n, &i__1, &c_b27, &v[v_offset], ldv, &workd[*n + 1], &c__1, & - c_b22, &resid[1], &c__1); + F77_FUNC(sgemv, SGEMV) + ("N", n, &i__1, &c_b27, &v[v_offset], ldv, &workd[*n + 1], &c__1, &c_b22, &resid[1], &c__1); if (*bmat == 'G') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[*n + 1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[*n + 1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -3492,19 +3335,19 @@ L30: } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L40: if (*bmat == 'G') { - *rnorm = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + *rnorm = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[1], &c__1); *rnorm = std::sqrt(std::abs(*rnorm)); } else if (*bmat == 'I') { - *rnorm = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + *rnorm = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } if (*rnorm > workd[*n * 3 + 4] * .717F) @@ -3540,29 +3383,24 @@ L9000: } - - - -static void -F77_FUNC(ssapps, SSAPPS) (int * n, - int * kev, - int * np, - float * shift, - float * v, - int * ldv, - float * h__, - int * ldh, - float * resid, - float * q, - int * ldq, - float * workd) +static void F77_FUNC(ssapps, SSAPPS)(int* n, + int* kev, + int* np, + float* shift, + float* v, + int* ldv, + float* h__, + int* ldh, + float* resid, + float* q, + int* ldq, + float* workd) { float c_b4 = 0.; float c_b5 = 1.; float c_b14 = -1.; int c__1 = 1; - int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, - i__3, i__4; + int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, i__3, i__4; float c__, f, g; int i__, j; float r__, s, a1, a2, a3, a4; @@ -3577,13 +3415,13 @@ F77_FUNC(ssapps, SSAPPS) (int * n, --shift; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; - q -= q_offset; + q -= q_offset; epsmch = GMX_FLOAT_EPS; itop = 1; @@ -3591,7 +3429,7 @@ F77_FUNC(ssapps, SSAPPS) (int * n, kplusp = *kev + *np; - F77_FUNC(slaset, SLASET) ("All", &kplusp, &kplusp, &c_b4, &c_b5, &q[q_offset], ldq); + F77_FUNC(slaset, SLASET)("All", &kplusp, &kplusp, &c_b4, &c_b5, &q[q_offset], ldq); if (*np == 0) { @@ -3604,12 +3442,12 @@ F77_FUNC(ssapps, SSAPPS) (int * n, istart = itop; -L20: + L20: i__2 = kplusp - 1; for (i__ = istart; i__ <= i__2; ++i__) { - big = std::abs(h__[i__ + (h_dim1*2)]) + std::abs(h__[i__ + 1 + (h_dim1*2)]); + big = std::abs(h__[i__ + (h_dim1 * 2)]) + std::abs(h__[i__ + 1 + (h_dim1 * 2)]); if (h__[i__ + 1 + h_dim1] <= epsmch * big) { h__[i__ + 1 + h_dim1] = 0.; @@ -3618,23 +3456,19 @@ L20: } } iend = kplusp; -L40: + L40: if (istart < iend) { f = h__[istart + (h_dim1 << 1)] - shift[jj]; g = h__[istart + 1 + h_dim1]; - F77_FUNC(slartg, SLARTG) (&f, &g, &c__, &s, &r__); - - a1 = c__ * h__[istart + (h_dim1 << 1)] + s * h__[istart + 1 + - h_dim1]; - a2 = c__ * h__[istart + 1 + h_dim1] + s * h__[istart + 1 + ( - h_dim1 << 1)]; - a4 = c__ * h__[istart + 1 + (h_dim1 << 1)] - s * h__[istart + 1 + - h_dim1]; - a3 = c__ * h__[istart + 1 + h_dim1] - s * h__[istart + (h_dim1 << - 1)]; + F77_FUNC(slartg, SLARTG)(&f, &g, &c__, &s, &r__); + + a1 = c__ * h__[istart + (h_dim1 << 1)] + s * h__[istart + 1 + h_dim1]; + a2 = c__ * h__[istart + 1 + h_dim1] + s * h__[istart + 1 + (h_dim1 << 1)]; + a4 = c__ * h__[istart + 1 + (h_dim1 << 1)] - s * h__[istart + 1 + h_dim1]; + a3 = c__ * h__[istart + 1 + h_dim1] - s * h__[istart + (h_dim1 << 1)]; h__[istart + (h_dim1 << 1)] = c__ * a1 + s * a2; h__[istart + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3; h__[istart + 1 + h_dim1] = c__ * a3 + s * a4; @@ -3643,12 +3477,10 @@ L40: i__2 = (i__3 < kplusp) ? i__3 : kplusp; for (j = 1; j <= i__2; ++j) { - a1 = c__ * q[j + istart * q_dim1] + s * q[j + (istart + 1) * - q_dim1]; - q[j + (istart + 1) * q_dim1] = -s * q[j + istart * q_dim1] + - c__ * q[j + (istart + 1) * q_dim1]; + a1 = c__ * q[j + istart * q_dim1] + s * q[j + (istart + 1) * q_dim1]; + q[j + (istart + 1) * q_dim1] = + -s * q[j + istart * q_dim1] + c__ * q[j + (istart + 1) * q_dim1]; q[j + istart * q_dim1] = a1; - } i__2 = iend - 1; @@ -3659,7 +3491,7 @@ L40: g = s * h__[i__ + 1 + h_dim1]; h__[i__ + 1 + h_dim1] = c__ * h__[i__ + 1 + h_dim1]; - F77_FUNC(slartg, SLARTG) (&f, &g, &c__, &s, &r__); + F77_FUNC(slartg, SLARTG)(&f, &g, &c__, &s, &r__); if (r__ < 0.) { @@ -3670,14 +3502,10 @@ L40: h__[i__ + h_dim1] = r__; - a1 = c__ * h__[i__ + (h_dim1 << 1)] + s * h__[i__ + 1 + - h_dim1]; - a2 = c__ * h__[i__ + 1 + h_dim1] + s * h__[i__ + 1 + (h_dim1 - << 1)]; - a3 = c__ * h__[i__ + 1 + h_dim1] - s * h__[i__ + (h_dim1 << 1) - ]; - a4 = c__ * h__[i__ + 1 + (h_dim1 << 1)] - s * h__[i__ + 1 + - h_dim1]; + a1 = c__ * h__[i__ + (h_dim1 << 1)] + s * h__[i__ + 1 + h_dim1]; + a2 = c__ * h__[i__ + 1 + h_dim1] + s * h__[i__ + 1 + (h_dim1 << 1)]; + a3 = c__ * h__[i__ + 1 + h_dim1] - s * h__[i__ + (h_dim1 << 1)]; + a4 = c__ * h__[i__ + 1 + (h_dim1 << 1)] - s * h__[i__ + 1 + h_dim1]; h__[i__ + (h_dim1 << 1)] = c__ * a1 + s * a2; h__[i__ + 1 + (h_dim1 << 1)] = c__ * a4 - s * a3; @@ -3687,15 +3515,11 @@ L40: i__3 = (i__4 < kplusp) ? i__4 : kplusp; for (j = 1; j <= i__3; ++j) { - a1 = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * - q_dim1]; - q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + - c__ * q[j + (i__ + 1) * q_dim1]; + a1 = c__ * q[j + i__ * q_dim1] + s * q[j + (i__ + 1) * q_dim1]; + q[j + (i__ + 1) * q_dim1] = -s * q[j + i__ * q_dim1] + c__ * q[j + (i__ + 1) * q_dim1]; q[j + i__ * q_dim1] = a1; } - } - } istart = iend + 1; @@ -3703,7 +3527,7 @@ L40: if (h__[iend + h_dim1] < 0.) { h__[iend + h_dim1] = -h__[iend + h_dim1]; - F77_FUNC(sscal, SSCAL) (&kplusp, &c_b14, &q[iend * q_dim1 + 1], &c__1); + F77_FUNC(sscal, SSCAL)(&kplusp, &c_b14, &q[iend * q_dim1 + 1], &c__1); } if (iend < kplusp) @@ -3721,81 +3545,70 @@ L40: ++itop; } -L90: - ; + L90:; } i__1 = kplusp - 1; for (i__ = itop; i__ <= i__1; ++i__) { - big = std::abs(h__[i__ + (h_dim1*2)]) + std::abs(h__[i__+ 1 + (h_dim1*2)]); + big = std::abs(h__[i__ + (h_dim1 * 2)]) + std::abs(h__[i__ + 1 + (h_dim1 * 2)]); if (h__[i__ + 1 + h_dim1] <= epsmch * big) { h__[i__ + 1 + h_dim1] = 0.; } - } if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(sgemv, SGEMV) ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * - q_dim1 + 1], &c__1, &c_b4, &workd[*n + 1], &c__1); + F77_FUNC(sgemv, SGEMV) + ("N", n, &kplusp, &c_b5, &v[v_offset], ldv, &q[(*kev + 1) * q_dim1 + 1], &c__1, &c_b4, + &workd[*n + 1], &c__1); } i__1 = *kev; for (i__ = 1; i__ <= i__1; ++i__) { i__2 = kplusp - i__ + 1; - F77_FUNC(sgemv, SGEMV) ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * - q_dim1 + 1], &c__1, &c_b4, &workd[1], &c__1); - F77_FUNC(scopy, SCOPY) (n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], & - c__1); - + F77_FUNC(sgemv, SGEMV) + ("N", n, &i__2, &c_b5, &v[v_offset], ldv, &q[(*kev - i__ + 1) * q_dim1 + 1], &c__1, &c_b4, + &workd[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &workd[1], &c__1, &v[(kplusp - i__ + 1) * v_dim1 + 1], &c__1); } - F77_FUNC(slacpy, SLACPY) ("All", n, kev, &v[(*np + 1) * v_dim1 + 1], ldv, &v[v_offset], ldv); + F77_FUNC(slacpy, SLACPY)("All", n, kev, &v[(*np + 1) * v_dim1 + 1], ldv, &v[v_offset], ldv); if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(scopy, SCOPY) (n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &workd[*n + 1], &c__1, &v[(*kev + 1) * v_dim1 + 1], &c__1); } - F77_FUNC(sscal, SSCAL) (n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1); + F77_FUNC(sscal, SSCAL)(n, &q[kplusp + *kev * q_dim1], &resid[1], &c__1); if (h__[*kev + 1 + h_dim1] > 0.) { - F77_FUNC(saxpy, SAXPY) (n, &h__[*kev + 1 + h_dim1], &v[(*kev + 1) * v_dim1 + 1], &c__1, - &resid[1], &c__1); + F77_FUNC(saxpy, SAXPY) + (n, &h__[*kev + 1 + h_dim1], &v[(*kev + 1) * v_dim1 + 1], &c__1, &resid[1], &c__1); } - L9000: return; - } - -static void -F77_FUNC(ssortr, SSORTR) (const char * which, - int * apply, - int * n, - float * x1, - float * x2) +static void F77_FUNC(ssortr, SSORTR)(const char* which, int* apply, int* n, float* x1, float* x2) { - int i__1; + int i__1; int i__, j, igap; float temp; - igap = *n / 2; if (!std::strncmp(which, "SA", 2)) { -L10: + L10: if (igap == 0) { goto L9000; @@ -3804,7 +3617,7 @@ L10: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L20: + L20: if (j < 0) { @@ -3829,17 +3642,15 @@ L20: } j -= igap; goto L20; -L30: - ; + L30:; } igap /= 2; goto L10; - } else if (!std::strncmp(which, "SM", 2)) { -L40: + L40: if (igap == 0) { goto L9000; @@ -3848,7 +3659,7 @@ L40: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L50: + L50: if (j < 0) { @@ -3873,17 +3684,15 @@ L50: } j -= igap; goto L50; -L60: - ; + L60:; } igap /= 2; goto L40; - } else if (!std::strncmp(which, "LA", 2)) { -L70: + L70: if (igap == 0) { goto L9000; @@ -3892,7 +3701,7 @@ L70: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L80: + L80: if (j < 0) { @@ -3917,18 +3726,16 @@ L80: } j -= igap; goto L80; -L90: - ; + L90:; } igap /= 2; goto L70; - } else if (!std::strncmp(which, "LM", 2)) { -L100: + L100: if (igap == 0) { goto L9000; @@ -3937,7 +3744,7 @@ L100: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L110: + L110: if (j < 0) { @@ -3962,8 +3769,7 @@ L110: } j -= igap; goto L110; -L120: - ; + L120:; } igap /= 2; goto L100; @@ -3971,37 +3777,28 @@ L120: L9000: return; - } - - -static void -F77_FUNC(ssesrt, SSESRT) (const char * which, - int * apply, - int * n, - float * x, - int * na, - float * a, - int * lda) +static void F77_FUNC(ssesrt, + SSESRT)(const char* which, int* apply, int* n, float* x, int* na, float* a, int* lda) { - int a_dim1, a_offset, i__1; - int c__1 = 1; + int a_dim1, a_offset, i__1; + int c__1 = 1; int i__, j, igap; float temp; a_dim1 = *lda; a_offset = 1 + a_dim1 * 0; - a -= a_offset; + a -= a_offset; igap = *n / 2; if (!std::strncmp(which, "SA", 2)) { -L10: + L10: if (igap == 0) { goto L9000; @@ -4010,7 +3807,7 @@ L10: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L20: + L20: if (j < 0) { @@ -4024,8 +3821,8 @@ L20: x[j + igap] = temp; if (*apply) { - F77_FUNC(sswap, SSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(sswap, SSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -4034,17 +3831,15 @@ L20: } j -= igap; goto L20; -L30: - ; + L30:; } igap /= 2; goto L10; - } else if (!std::strncmp(which, "SM", 2)) { -L40: + L40: if (igap == 0) { goto L9000; @@ -4053,7 +3848,7 @@ L40: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L50: + L50: if (j < 0) { @@ -4067,8 +3862,8 @@ L50: x[j + igap] = temp; if (*apply) { - F77_FUNC(sswap, SSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(sswap, SSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -4077,17 +3872,15 @@ L50: } j -= igap; goto L50; -L60: - ; + L60:; } igap /= 2; goto L40; - } else if (!std::strncmp(which, "LA", 2)) { -L70: + L70: if (igap == 0) { goto L9000; @@ -4096,7 +3889,7 @@ L70: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L80: + L80: if (j < 0) { @@ -4110,8 +3903,8 @@ L80: x[j + igap] = temp; if (*apply) { - F77_FUNC(sswap, SSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(sswap, SSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -4120,17 +3913,15 @@ L80: } j -= igap; goto L80; -L90: - ; + L90:; } igap /= 2; goto L70; - } else if (!std::strncmp(which, "LM", 2)) { -L100: + L100: if (igap == 0) { goto L9000; @@ -4139,7 +3930,7 @@ L100: for (i__ = igap; i__ <= i__1; ++i__) { j = i__ - igap; -L110: + L110: if (j < 0) { @@ -4153,8 +3944,8 @@ L110: x[j + igap] = temp; if (*apply) { - F77_FUNC(sswap, SSWAP) (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * - a_dim1 + 1], &c__1); + F77_FUNC(sswap, SSWAP) + (na, &a[j * a_dim1 + 1], &c__1, &a[(j + igap) * a_dim1 + 1], &c__1); } } else @@ -4163,8 +3954,7 @@ L110: } j -= igap; goto L110; -L120: - ; + L120:; } igap /= 2; goto L100; @@ -4172,20 +3962,11 @@ L120: L9000: return; - } - - -static void -F77_FUNC(ssgets, SSGETS) (int * ishift, - const char * which, - int * kev, - int * np, - float * ritz, - float * bounds, - float * shifts) +static void F77_FUNC(ssgets, + SSGETS)(int* ishift, const char* which, int* kev, int* np, float* ritz, float* bounds, float* shifts) { int c__1 = 1; int i__1, i__2; @@ -4198,32 +3979,29 @@ F77_FUNC(ssgets, SSGETS) (int * ishift, if (!std::strncmp(which, "BE", 2)) { i__1 = *kev + *np; - F77_FUNC(ssortr, SSORTR) ("LA", &c__1, &i__1, &ritz[1], &bounds[1]); + F77_FUNC(ssortr, SSORTR)("LA", &c__1, &i__1, &ritz[1], &bounds[1]); kevd2 = *kev / 2; if (*kev > 1) { i__1 = (kevd2 < *np) ? kevd2 : *np; i__2 = (kevd2 > *np) ? kevd2 : *np; - F77_FUNC(sswap, SSWAP) (&i__1, &ritz[1], &c__1, - &ritz[i__2 + 1], &c__1); + F77_FUNC(sswap, SSWAP)(&i__1, &ritz[1], &c__1, &ritz[i__2 + 1], &c__1); i__1 = (kevd2 < *np) ? kevd2 : *np; i__2 = (kevd2 > *np) ? kevd2 : *np; - F77_FUNC(sswap, SSWAP) (&i__1, &bounds[1], &c__1, - &bounds[i__2 + 1], &c__1); + F77_FUNC(sswap, SSWAP)(&i__1, &bounds[1], &c__1, &bounds[i__2 + 1], &c__1); } - } else { i__1 = *kev + *np; - F77_FUNC(ssortr, SSORTR) (which, &c__1, &i__1, &ritz[1], &bounds[1]); + F77_FUNC(ssortr, SSORTR)(which, &c__1, &i__1, &ritz[1], &bounds[1]); } if (*ishift == 1 && *np > 0) { - F77_FUNC(ssortr, SSORTR) ("SM", &c__1, np, &bounds[1], &ritz[1]); - F77_FUNC(scopy, SCOPY) (np, &ritz[1], &c__1, &shifts[1], &c__1); + F77_FUNC(ssortr, SSORTR)("SM", &c__1, np, &bounds[1], &ritz[1]); + F77_FUNC(scopy, SCOPY)(np, &ritz[1], &c__1, &shifts[1], &c__1); } @@ -4231,15 +4009,9 @@ F77_FUNC(ssgets, SSGETS) (int * ishift, } - -static void -F77_FUNC(ssconv, SSCONV) (int * n, - float * ritz, - float * bounds, - float * tol, - int * nconv) +static void F77_FUNC(ssconv, SSCONV)(int* n, float* ritz, float* bounds, float* tol, int* nconv) { - float c_b3 = 2/3.; + float c_b3 = 2 / 3.; int i__1; float d__2, d__3; @@ -4270,15 +4042,9 @@ F77_FUNC(ssconv, SSCONV) (int * n, } -static void -F77_FUNC(sseigt, SSEIGT) (float * rnorm, - int * n, - float * h__, - int * ldh, - float * eig, - float * bounds, - float * workl, - int * ierr) +static void F77_FUNC( + sseigt, + SSEIGT)(float* rnorm, int* n, float* h__, int* ldh, float* eig, float* bounds, float* workl, int* ierr) { int c__1 = 1; int h_dim1, h_offset, i__1; @@ -4291,12 +4057,12 @@ F77_FUNC(sseigt, SSEIGT) (float * rnorm, --eig; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; - F77_FUNC(scopy, SCOPY) (n, &h__[(h_dim1 << 1) + 1], &c__1, &eig[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &h__[(h_dim1 << 1) + 1], &c__1, &eig[1], &c__1); i__1 = *n - 1; - F77_FUNC(scopy, SCOPY) (&i__1, &h__[h_dim1 + 2], &c__1, &workl[1], &c__1); - F77_FUNC(sstqrb, SSTQRB) (n, &eig[1], &workl[1], &bounds[1], &workl[*n + 1], ierr); + F77_FUNC(scopy, SCOPY)(&i__1, &h__[h_dim1 + 2], &c__1, &workl[1], &c__1); + F77_FUNC(sstqrb, SSTQRB)(n, &eig[1], &workl[1], &bounds[1], &workl[*n + 1], ierr); if (*ierr != 0) { goto L9000; @@ -4306,7 +4072,6 @@ F77_FUNC(sseigt, SSEIGT) (float * rnorm, for (k = 1; k <= i__1; ++k) { bounds[k] = *rnorm * std::abs(bounds[k]); - } @@ -4315,25 +4080,22 @@ L9000: } - - -static void -F77_FUNC(ssaitr, SSAITR) (int * ido, - const char * bmat, - int * n, - int * k, - int * np, - int * mode, - float * resid, - float * rnorm, - float * v, - int * ldv, - float * h__, - int * ldh, - int * ipntr, - float * workd, - int * iwork, - int * info) +static void F77_FUNC(ssaitr, SSAITR)(int* ido, + const char* bmat, + int* n, + int* k, + int* np, + int* mode, + float* resid, + float* rnorm, + float* v, + int* ldv, + float* h__, + int* ldh, + int* ipntr, + float* workd, + int* iwork, + int* info) { int c__0 = 0; @@ -4353,10 +4115,10 @@ F77_FUNC(ssaitr, SSAITR) (int * ido, --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; --ipntr; --iwork; minval = GMX_FLOAT_MIN; @@ -4413,8 +4175,9 @@ L20: *ido = 0; L30: - F77_FUNC(sgetv0, sgetv0) (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, - &resid[1], rnorm, &ipntr[1], &workd[1], &iwork[21], &iwork[7]); + F77_FUNC(sgetv0, sgetv0) + (ido, bmat, &iwork[11], &c__0, n, &iwork[12], &v[v_offset], ldv, &resid[1], rnorm, &ipntr[1], + &workd[1], &iwork[21], &iwork[7]); if (*ido != 99) { goto L9000; @@ -4434,24 +4197,24 @@ L30: L40: - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &v[iwork[12] * v_dim1 + 1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &v[iwork[12] * v_dim1 + 1], &c__1); if (*rnorm >= safmin) { temp1 = 1. / *rnorm; - F77_FUNC(sscal, SSCAL) (n, &temp1, &v[iwork[12] * v_dim1 + 1], &c__1); - F77_FUNC(sscal, SSCAL) (n, &temp1, &workd[iwork[8]], &c__1); + F77_FUNC(sscal, SSCAL)(n, &temp1, &v[iwork[12] * v_dim1 + 1], &c__1); + F77_FUNC(sscal, SSCAL)(n, &temp1, &workd[iwork[8]], &c__1); } else { - F77_FUNC(slascl, SLASCL) ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &v[iwork[12] * - v_dim1 + 1], n, &infol); - F77_FUNC(slascl, SLASCL) ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &workd[iwork[ - 8]], n, &infol); + F77_FUNC(slascl, SLASCL) + ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &v[iwork[12] * v_dim1 + 1], n, &infol); + F77_FUNC(slascl, SLASCL) + ("General", &i__, &i__, rnorm, &c_b18, n, &c__1, &workd[iwork[8]], n, &infol); } iwork[5] = 1; - F77_FUNC(scopy, SCOPY) (n, &v[iwork[12] * v_dim1 + 1], &c__1, &workd[iwork[10]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &v[iwork[12] * v_dim1 + 1], &c__1, &workd[iwork[10]], &c__1); ipntr[1] = iwork[10]; ipntr[2] = iwork[9]; ipntr[3] = iwork[8]; @@ -4463,7 +4226,7 @@ L50: iwork[5] = 0; - F77_FUNC(scopy, SCOPY) (n, &workd[iwork[9]], &c__1, &resid[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &workd[iwork[9]], &c__1, &resid[1], &c__1); if (*mode == 2) { @@ -4480,7 +4243,7 @@ L50: } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L60: @@ -4490,34 +4253,34 @@ L65: if (*mode == 2) { - workd[*n * 3 + 3] = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[iwork[10]], & - c__1); + workd[*n * 3 + 3] = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[iwork[10]], &c__1); workd[*n * 3 + 3] = std::sqrt(std::abs(workd[*n * 3 + 3])); } else if (*bmat == 'G') { - workd[*n * 3 + 3] = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[iwork[8]], & - c__1); + workd[*n * 3 + 3] = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); workd[*n * 3 + 3] = std::sqrt(std::abs(workd[*n * 3 + 3])); } else if (*bmat == 'I') { - workd[*n * 3 + 3] = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 3] = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } if (*mode != 2) { - F77_FUNC(sgemv, SGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], - &c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(sgemv, SGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); } else { - F77_FUNC(sgemv, SGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10] - ], &c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(sgemv, SGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[10]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); } - F77_FUNC(sgemv, SGEMV) ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], & - c__1, &c_b18, &resid[1], &c__1); + F77_FUNC(sgemv, SGEMV) + ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1); h__[iwork[12] + (h_dim1 << 1)] = workd[iwork[9] + iwork[12] - 1]; if (iwork[12] == 1 || iwork[4] == 1) @@ -4534,7 +4297,7 @@ L65: if (*bmat == 'G') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[iwork[9]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[iwork[9]], &c__1); ipntr[1] = iwork[9]; ipntr[2] = iwork[8]; *ido = 2; @@ -4543,7 +4306,7 @@ L65: } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L70: @@ -4551,12 +4314,12 @@ L70: if (*bmat == 'G') { - *rnorm = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + *rnorm = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); *rnorm = std::sqrt(std::abs(*rnorm)); } else if (*bmat == 'I') { - *rnorm = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + *rnorm = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } if (*rnorm > workd[*n * 3 + 3] * .717F) @@ -4566,11 +4329,12 @@ L70: L80: - F77_FUNC(sgemv, SGEMV) ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], & - c__1, &c_b42, &workd[iwork[9]], &c__1); + F77_FUNC(sgemv, SGEMV) + ("T", n, &iwork[12], &c_b18, &v[v_offset], ldv, &workd[iwork[8]], &c__1, &c_b42, + &workd[iwork[9]], &c__1); - F77_FUNC(sgemv, SGEMV) ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], & - c__1, &c_b18, &resid[1], &c__1); + F77_FUNC(sgemv, SGEMV) + ("N", n, &iwork[12], &c_b50, &v[v_offset], ldv, &workd[iwork[9]], &c__1, &c_b18, &resid[1], &c__1); if (iwork[12] == 1 || iwork[4] == 1) { @@ -4581,7 +4345,7 @@ L80: iwork[3] = 1; if (*bmat == 'G') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[iwork[9]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[iwork[9]], &c__1); ipntr[1] = iwork[9]; ipntr[2] = iwork[8]; *ido = 2; @@ -4590,20 +4354,19 @@ L80: } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[iwork[8]], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); } L90: if (*bmat == 'G') { - workd[*n * 3 + 2] = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[iwork[8]], & - c__1); + workd[*n * 3 + 2] = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[iwork[8]], &c__1); workd[*n * 3 + 2] = std::sqrt(std::abs(workd[*n * 3 + 2])); } else if (*bmat == 'I') { - workd[*n * 3 + 2] = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 2] = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } @@ -4611,7 +4374,6 @@ L90: { *rnorm = workd[*n * 3 + 2]; - } else { @@ -4641,11 +4403,11 @@ L100: h__[iwork[12] + h_dim1] = -h__[iwork[12] + h_dim1]; if (iwork[12] < *k + *np) { - F77_FUNC(sscal, SSCAL) (n, &c_b50, &v[(iwork[12] + 1) * v_dim1 + 1], &c__1); + F77_FUNC(sscal, SSCAL)(n, &c_b50, &v[(iwork[12] + 1) * v_dim1 + 1], &c__1); } else { - F77_FUNC(sscal, SSCAL) (n, &c_b50, &resid[1], &c__1); + F77_FUNC(sscal, SSCAL)(n, &c_b50, &resid[1], &c__1); } } @@ -4665,43 +4427,37 @@ L9000: } - - - - -static void -F77_FUNC(ssaup2, SSAUP2) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - int * np, - float * tol, - float * resid, - int * mode, - int gmx_unused * iupd, - int * ishift, - int * mxiter, - float * v, - int * ldv, - float * h__, - int * ldh, - float * ritz, - float * bounds, - float * q, - int * ldq, - float * workl, - int * ipntr, - float * workd, - int * iwork, - int * info) +static void F77_FUNC(ssaup2, SSAUP2)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + int* np, + float* tol, + float* resid, + int* mode, + int gmx_unused* iupd, + int* ishift, + int* mxiter, + float* v, + int* ldv, + float* h__, + int* ldh, + float* ritz, + float* bounds, + float* q, + int* ldq, + float* workl, + int* ipntr, + float* workd, + int* iwork, + int* info) { - float c_b3 = 2/3.; + float c_b3 = 2 / 3.; int c__1 = 1; int c__0 = 0; - int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, - i__3; + int h_dim1, h_offset, q_dim1, q_offset, v_dim1, v_offset, i__1, i__2, i__3; float d__2, d__3; int j; float eps23; @@ -4720,13 +4476,13 @@ F77_FUNC(ssaup2, SSAUP2) (int * ido, --ritz; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; h_dim1 = *ldh; h_offset = 1 + h_dim1; - h__ -= h_offset; + h__ -= h_offset; q_dim1 = *ldq; q_offset = 1 + q_dim1; - q -= q_offset; + q -= q_offset; --ipntr; --iwork; eps23 = GMX_FLOAT_EPS; @@ -4766,9 +4522,9 @@ F77_FUNC(ssaup2, SSAUP2) (int * ido, if (iwork[2] == 1) { - F77_FUNC(sgetv0, SGETV0) (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, & - resid[1], &workd[*n * 3 + 1], &ipntr[1], &workd[1], &iwork[41], - info); + F77_FUNC(sgetv0, SGETV0) + (ido, bmat, &c__1, &iwork[3], n, &c__1, &v[v_offset], ldv, &resid[1], &workd[*n * 3 + 1], + &ipntr[1], &workd[1], &iwork[41], info); if (*ido != 99) { @@ -4800,9 +4556,9 @@ F77_FUNC(ssaup2, SSAUP2) (int * ido, goto L100; } - F77_FUNC(ssaitr, SSAITR) (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + - 1], &v[v_offset], ldv, &h__[h_offset], ldh, &ipntr[1], &workd[1], - &iwork[21], info); + F77_FUNC(ssaitr, SSAITR) + (ido, bmat, n, &c__0, &iwork[9], mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, + &h__[h_offset], ldh, &ipntr[1], &workd[1], &iwork[21], info); if (*ido != 99) { @@ -4827,9 +4583,9 @@ L1000: L20: iwork[4] = 1; - F77_FUNC(ssaitr, SSAITR) (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], &v[ - v_offset], ldv, &h__[h_offset], ldh, &ipntr[1], &workd[1], &iwork[ - 21], info); + F77_FUNC(ssaitr, SSAITR) + (ido, bmat, n, nev, np, mode, &resid[1], &workd[*n * 3 + 1], &v[v_offset], ldv, &h__[h_offset], + ldh, &ipntr[1], &workd[1], &iwork[21], info); if (*ido != 99) { @@ -4846,8 +4602,8 @@ L20: } iwork[4] = 0; - F77_FUNC(sseigt, SSEIGT) (&workd[*n * 3 + 1], &iwork[7], &h__[h_offset], ldh, &ritz[1], & - bounds[1], &workl[1], &ierr); + F77_FUNC(sseigt, SSEIGT) + (&workd[*n * 3 + 1], &iwork[7], &h__[h_offset], ldh, &ritz[1], &bounds[1], &workl[1], &ierr); if (ierr != 0) { @@ -4855,15 +4611,15 @@ L20: goto L1200; } - F77_FUNC(scopy, SCOPY) (&iwork[7], &ritz[1], &c__1, &workl[iwork[7] + 1], &c__1); - F77_FUNC(scopy, SCOPY) (&iwork[7], &bounds[1], &c__1, &workl[(iwork[7] << 1) + 1], &c__1); + F77_FUNC(scopy, SCOPY)(&iwork[7], &ritz[1], &c__1, &workl[iwork[7] + 1], &c__1); + F77_FUNC(scopy, SCOPY)(&iwork[7], &bounds[1], &c__1, &workl[(iwork[7] << 1) + 1], &c__1); *nev = iwork[9]; *np = iwork[10]; - F77_FUNC(ssgets, SSGETS) (ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); + F77_FUNC(ssgets, SSGETS)(ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); - F77_FUNC(scopy, SCOPY) (nev, &bounds[*np + 1], &c__1, &workl[*np + 1], &c__1); - F77_FUNC(ssconv, SSCONV) (nev, &ritz[*np + 1], &workl[*np + 1], tol, &iwork[8]); + F77_FUNC(scopy, SCOPY)(nev, &bounds[*np + 1], &c__1, &workl[*np + 1], &c__1); + F77_FUNC(ssconv, SSCONV)(nev, &ritz[*np + 1], &workl[*np + 1], tol, &iwork[8]); nptemp = *np; @@ -4884,23 +4640,20 @@ L20: { std::strncpy(wprime, "SA", 2); - F77_FUNC(ssortr, SSORTR) (wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); + F77_FUNC(ssortr, SSORTR)(wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); nevd2 = *nev / 2; nevm2 = *nev - nevd2; if (*nev > 1) { i__1 = (nevd2 < *np) ? nevd2 : *np; i__2 = iwork[7] - nevd2 + 1, i__3 = iwork[7] - *np + 1; - F77_FUNC(sswap, SSWAP) (&i__1, &ritz[nevm2 + 1], &c__1, - &ritz[((i__2 > i__3) ? i__2 : i__3)], - &c__1); + F77_FUNC(sswap, SSWAP) + (&i__1, &ritz[nevm2 + 1], &c__1, &ritz[((i__2 > i__3) ? i__2 : i__3)], &c__1); i__1 = (nevd2 < *np) ? nevd2 : *np; i__2 = iwork[7] - nevd2 + 1, i__3 = iwork[7] - *np; - F77_FUNC(sswap, SSWAP) (&i__1, &bounds[nevm2 + 1], &c__1, - &bounds[((i__2 > i__3) ? i__2 : i__3) + 1], - &c__1); + F77_FUNC(sswap, SSWAP) + (&i__1, &bounds[nevm2 + 1], &c__1, &bounds[((i__2 > i__3) ? i__2 : i__3) + 1], &c__1); } - } else { @@ -4922,28 +4675,27 @@ L20: std::strncpy(wprime, "LA", 2); } - F77_FUNC(ssortr, SSORTR) (wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); - + F77_FUNC(ssortr, SSORTR)(wprime, &c__1, &iwork[7], &ritz[1], &bounds[1]); } i__1 = iwork[9]; for (j = 1; j <= i__1; ++j) { - d__2 = eps23; - d__3 = std::abs(ritz[j]); - temp = (d__2 > d__3) ? d__2 : d__3; + d__2 = eps23; + d__3 = std::abs(ritz[j]); + temp = (d__2 > d__3) ? d__2 : d__3; bounds[j] /= temp; } std::strncpy(wprime, "LA", 2); - F77_FUNC(ssortr, SSORTR) (wprime, &c__1, &iwork[9], &bounds[1], &ritz[1]); + F77_FUNC(ssortr, SSORTR)(wprime, &c__1, &iwork[9], &bounds[1], &ritz[1]); i__1 = iwork[9]; for (j = 1; j <= i__1; ++j) { - d__2 = eps23; - d__3 = std::abs(ritz[j]); - temp = (d__2 > d__3) ? d__2 : d__3; + d__2 = eps23; + d__3 = std::abs(ritz[j]); + temp = (d__2 > d__3) ? d__2 : d__3; bounds[j] *= temp; } @@ -4951,13 +4703,11 @@ L20: { std::strncpy(wprime, "LA", 2); - F77_FUNC(ssortr, SSORTR) (wprime, &c__1, &iwork[8], &ritz[1], &bounds[1]); - + F77_FUNC(ssortr, SSORTR)(wprime, &c__1, &iwork[8], &ritz[1], &bounds[1]); } else { - F77_FUNC(ssortr, SSORTR) (which, &c__1, &iwork[8], &ritz[1], &bounds[1]); - + F77_FUNC(ssortr, SSORTR)(which, &c__1, &iwork[8], &ritz[1], &bounds[1]); } h__[h_dim1 + 1] = workd[*n * 3 + 1]; @@ -4974,13 +4724,12 @@ L20: *np = iwork[8]; goto L1100; - } else if (iwork[8] < *nev && *ishift == 1) { nevbef = *nev; - i__1 = iwork[8], i__2 = *np / 2; - *nev += (i__1 < i__2) ? i__1 : i__2; + i__1 = iwork[8], i__2 = *np / 2; + *nev += (i__1 < i__2) ? i__1 : i__2; if (*nev == 1 && iwork[7] >= 6) { *nev = iwork[7] / 2; @@ -4994,9 +4743,8 @@ L20: if (nevbef < *nev) { - F77_FUNC(ssgets, SSGETS) (ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); + F77_FUNC(ssgets, SSGETS)(ishift, which, nev, np, &ritz[1], &bounds[1], &workl[1]); } - } @@ -5014,16 +4762,17 @@ L50: if (*ishift == 0) { - F77_FUNC(scopy, SCOPY) (np, &workl[1], &c__1, &ritz[1], &c__1); + F77_FUNC(scopy, SCOPY)(np, &workl[1], &c__1, &ritz[1], &c__1); } - F77_FUNC(ssapps, SSAPPS) (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, & - resid[1], &q[q_offset], ldq, &workd[1]); + F77_FUNC(ssapps, SSAPPS) + (n, nev, np, &ritz[1], &v[v_offset], ldv, &h__[h_offset], ldh, &resid[1], &q[q_offset], ldq, + &workd[1]); iwork[1] = 1; if (*bmat == 'G') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[*n + 1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[*n + 1], &c__1); ipntr[1] = *n + 1; ipntr[2] = 1; *ido = 2; @@ -5032,19 +4781,19 @@ L50: } else if (*bmat == 'I') { - F77_FUNC(scopy, SCOPY) (n, &resid[1], &c__1, &workd[1], &c__1); + F77_FUNC(scopy, SCOPY)(n, &resid[1], &c__1, &workd[1], &c__1); } L100: if (*bmat == 'G') { - workd[*n * 3 + 1] = F77_FUNC(sdot, SDOT) (n, &resid[1], &c__1, &workd[1], &c__1); + workd[*n * 3 + 1] = F77_FUNC(sdot, SDOT)(n, &resid[1], &c__1, &workd[1], &c__1); workd[*n * 3 + 1] = std::sqrt(std::abs(workd[*n * 3 + 1])); } else if (*bmat == 'I') { - workd[*n * 3 + 1] = F77_FUNC(snrm2, SNRM2) (n, &resid[1], &c__1); + workd[*n * 3 + 1] = F77_FUNC(snrm2, SNRM2)(n, &resid[1], &c__1); } iwork[1] = 0; @@ -5060,29 +4809,26 @@ L1200: L9000: return; - } - -void -F77_FUNC(ssaupd, SSAUPD) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - float * tol, - float * resid, - int * ncv, - float * v, - int * ldv, - int * iparam, - int * ipntr, - float * workd, - int * iwork, - float * workl, - int * lworkl, - int * info) +void F77_FUNC(ssaupd, SSAUPD)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + float* tol, + float* resid, + int* ncv, + float* v, + int* ldv, + int* iparam, + int* ipntr, + float* workd, + int* iwork, + float* workl, + int* lworkl, + int* info) { int v_dim1, v_offset, i__1, i__2; int j; @@ -5091,7 +4837,7 @@ F77_FUNC(ssaupd, SSAUPD) (int * ido, --resid; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --iparam; --ipntr; --iwork; @@ -5130,9 +4876,8 @@ F77_FUNC(ssaupd, SSAUPD) (int * ido, { iwork[2] = -4; } - if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && - std::strncmp(which, "LA", 2) && std::strncmp(which, "SA", 2) && - std::strncmp(which, "BE", 2)) + if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && std::strncmp(which, "LA", 2) + && std::strncmp(which, "SA", 2) && std::strncmp(which, "BE", 2)) { iwork[2] = -5; } @@ -5205,11 +4950,10 @@ F77_FUNC(ssaupd, SSAUPD) (int * ido, ipntr[11] = iwork[7]; } - F77_FUNC(ssaup2, SSAUP2) (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], & - iwork[11], &iwork[6], &iwork[5], &iwork[10], &v[v_offset], ldv, & - workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]], & - workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], - &iwork[21], info); + F77_FUNC(ssaup2, SSAUP2) + (ido, bmat, n, which, &iwork[13], &iwork[15], tol, &resid[1], &iwork[11], &iwork[6], &iwork[5], + &iwork[10], &v[v_offset], ldv, &workl[iwork[3]], &iwork[8], &workl[iwork[16]], &workl[iwork[1]], + &workl[iwork[4]], &iwork[9], &workl[iwork[7]], &ipntr[1], &workd[1], &iwork[21], info); if (*ido == 3) { @@ -5235,36 +4979,33 @@ F77_FUNC(ssaupd, SSAUPD) (int * ido, L9000: return; - } - -void -F77_FUNC(sseupd, SSEUPD) (int * rvec, - const char * howmny, - int * select, - float * d__, - float * z__, - int * ldz, - float * sigma, - const char * bmat, - int * n, - const char * which, - int * nev, - float * tol, - float * resid, - int * ncv, - float * v, - int * ldv, - int * iparam, - int * ipntr, - float * workd, - float * workl, - int * lworkl, - int * info) +void F77_FUNC(sseupd, SSEUPD)(int* rvec, + const char* howmny, + int* select, + float* d__, + float* z__, + int* ldz, + float* sigma, + const char* bmat, + int* n, + const char* which, + int* nev, + float* tol, + float* resid, + int* ncv, + float* v, + int* ldv, + int* iparam, + int* ipntr, + float* workd, + float* workl, + int* lworkl, + int* info) { - float c_b21 = 2/3.; + float c_b21 = 2 / 3.; int c__1 = 1; float c_b102 = 1.; int v_dim1, v_offset, z_dim1, z_offset, i__1; @@ -5293,12 +5034,12 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, --resid; z_dim1 = *ldz; z_offset = 1 + z_dim1; - z__ -= z_offset; + z__ -= z_offset; --d__; --select; v_dim1 = *ldv; v_offset = 1 + v_dim1; - v -= v_offset; + v -= v_offset; --iparam; --ipntr; --workl; @@ -5329,9 +5070,8 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, { ierr = -3; } - if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && - std::strncmp(which, "LA", 2) && std::strncmp(which, "SA", 2) && - std::strncmp(which, "BE", 2)) + if (std::strncmp(which, "LM", 2) && std::strncmp(which, "SM", 2) && std::strncmp(which, "LA", 2) + && std::strncmp(which, "SA", 2) && std::strncmp(which, "BE", 2)) { ierr = -5; } @@ -5339,8 +5079,7 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, { ierr = -6; } - if (*howmny != 'A' && *howmny != 'P' && - *howmny != 'S' && *rvec) + if (*howmny != 'A' && *howmny != 'P' && *howmny != 'S' && *rvec) { ierr = -15; } @@ -5418,28 +5157,24 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, } else if (*bmat == 'G') { - bnorm2 = F77_FUNC(snrm2, SNRM2) (n, &workd[1], &c__1); + bnorm2 = F77_FUNC(snrm2, SNRM2)(n, &workd[1], &c__1); } if (*rvec) { - if (!std::strncmp(which, "LM", 2) || !std::strncmp(which, "SM", 2) || - !std::strncmp(which, "LA", 2) || !std::strncmp(which, "SA", 2)) - { - - } + if (!std::strncmp(which, "LM", 2) || !std::strncmp(which, "SM", 2) + || !std::strncmp(which, "LA", 2) || !std::strncmp(which, "SA", 2)) + {} else if (!std::strncmp(which, "BE", 2)) { - ism = (*nev > nconv) ? *nev : nconv; - ism /= 2; + ism = (*nev > nconv) ? *nev : nconv; + ism /= 2; ilg = ism + 1; thres1 = workl[ism]; thres2 = workl[ilg]; - - } reord = 0; @@ -5524,11 +5259,11 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, } i__1 = *ncv - 1; - F77_FUNC(scopy, SCOPY) (&i__1, &workl[ih + 1], &c__1, &workl[ihb], &c__1); - F77_FUNC(scopy, SCOPY) (ncv, &workl[ih + ldh], &c__1, &workl[ihd], &c__1); + F77_FUNC(scopy, SCOPY)(&i__1, &workl[ih + 1], &c__1, &workl[ihb], &c__1); + F77_FUNC(scopy, SCOPY)(ncv, &workl[ih + ldh], &c__1, &workl[ihd], &c__1); - F77_FUNC(ssteqr, SSTEQR) ("Identity", ncv, &workl[ihd], &workl[ihb], &workl[iq], &ldq, & - workl[iw], &ierr); + F77_FUNC(ssteqr, SSTEQR) + ("Identity", ncv, &workl[ihd], &workl[ihb], &workl[iq], &ldq, &workl[iw], &ierr); if (ierr != 0) { @@ -5548,18 +5283,16 @@ F77_FUNC(sseupd, SSEUPD) (int * rvec, goto L30; } -L20: + L20: if (select[leftptr]) { ++leftptr; - } else if (!select[rghtptr]) { --rghtptr; - } else { @@ -5567,15 +5300,14 @@ L20: temp = workl[ihd + leftptr - 1]; workl[ihd + leftptr - 1] = workl[ihd + rghtptr - 1]; workl[ihd + rghtptr - 1] = temp; - F77_FUNC(scopy, SCOPY) (ncv, &workl[iq + *ncv * (leftptr - 1)], &c__1, &workl[ - iw], &c__1); - F77_FUNC(scopy, SCOPY) (ncv, &workl[iq + *ncv * (rghtptr - 1)], &c__1, &workl[ - iq + *ncv * (leftptr - 1)], &c__1); - F77_FUNC(scopy, SCOPY) (ncv, &workl[iw], &c__1, &workl[iq + *ncv * (rghtptr - - 1)], &c__1); + F77_FUNC(scopy, SCOPY) + (ncv, &workl[iq + *ncv * (leftptr - 1)], &c__1, &workl[iw], &c__1); + F77_FUNC(scopy, SCOPY) + (ncv, &workl[iq + *ncv * (rghtptr - 1)], &c__1, &workl[iq + *ncv * (leftptr - 1)], &c__1); + F77_FUNC(scopy, SCOPY) + (ncv, &workl[iw], &c__1, &workl[iq + *ncv * (rghtptr - 1)], &c__1); ++leftptr; --rghtptr; - } if (leftptr < rghtptr) @@ -5583,37 +5315,33 @@ L20: goto L20; } -L30: - ; + L30:; } - F77_FUNC(scopy, SCOPY) (&nconv, &workl[ihd], &c__1, &d__[1], &c__1); - + F77_FUNC(scopy, SCOPY)(&nconv, &workl[ihd], &c__1, &d__[1], &c__1); } else { - F77_FUNC(scopy, SCOPY) (&nconv, &workl[ritz], &c__1, &d__[1], &c__1); - F77_FUNC(scopy, SCOPY) (ncv, &workl[ritz], &c__1, &workl[ihd], &c__1); - + F77_FUNC(scopy, SCOPY)(&nconv, &workl[ritz], &c__1, &d__[1], &c__1); + F77_FUNC(scopy, SCOPY)(ncv, &workl[ritz], &c__1, &workl[ihd], &c__1); } if (!std::strncmp(type__, "REGULR", 6)) { if (*rvec) { - F77_FUNC(ssesrt, SSESRT) ("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); + F77_FUNC(ssesrt, SSESRT)("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); } else { - F77_FUNC(scopy, SCOPY) (ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); + F77_FUNC(scopy, SCOPY)(ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); } - } else { - F77_FUNC(scopy, SCOPY) (ncv, &workl[ihd], &c__1, &workl[iw], &c__1); + F77_FUNC(scopy, SCOPY)(ncv, &workl[ihd], &c__1, &workl[iw], &c__1); if (!std::strncmp(type__, "SHIFTI", 6)) { i__1 = *ncv; @@ -5627,8 +5355,7 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihd + k - 1] = *sigma * workl[ihd + k - 1] / (workl[ihd - + k - 1] - 1.); + workl[ihd + k - 1] = *sigma * workl[ihd + k - 1] / (workl[ihd + k - 1] - 1.); } } else if (!std::strncmp(type__, "CAYLEY", 6)) @@ -5636,36 +5363,35 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihd + k - 1] = *sigma * (workl[ihd + k - 1] + 1.) / ( - workl[ihd + k - 1] - 1.); + workl[ihd + k - 1] = *sigma * (workl[ihd + k - 1] + 1.) / (workl[ihd + k - 1] - 1.); } } - F77_FUNC(scopy, SCOPY) (&nconv, &workl[ihd], &c__1, &d__[1], &c__1); - F77_FUNC(ssortr, SSORTR) ("LA", &c__1, &nconv, &workl[ihd], &workl[iw]); + F77_FUNC(scopy, SCOPY)(&nconv, &workl[ihd], &c__1, &d__[1], &c__1); + F77_FUNC(ssortr, SSORTR)("LA", &c__1, &nconv, &workl[ihd], &workl[iw]); if (*rvec) { - F77_FUNC(ssesrt, SSESRT) ("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); + F77_FUNC(ssesrt, SSESRT)("LA", rvec, &nconv, &d__[1], ncv, &workl[iq], &ldq); } else { - F77_FUNC(scopy, SCOPY) (ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); + F77_FUNC(scopy, SCOPY)(ncv, &workl[bounds], &c__1, &workl[ihb], &c__1); d__1 = bnorm2 / rnorm; - F77_FUNC(sscal, SSCAL) (ncv, &d__1, &workl[ihb], &c__1); - F77_FUNC(ssortr, SSORTR) ("LA", &c__1, &nconv, &d__[1], &workl[ihb]); + F77_FUNC(sscal, SSCAL)(ncv, &d__1, &workl[ihb], &c__1); + F77_FUNC(ssortr, SSORTR)("LA", &c__1, &nconv, &d__[1], &workl[ihb]); } - } if (*rvec && *howmny == 'A') { - F77_FUNC(sgeqr2, SGEQR2) (ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], - &ierr); + F77_FUNC(sgeqr2, SGEQR2) + (ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], &ierr); - F77_FUNC(sorm2r, SORM2R) ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, & - workl[iw + *ncv], &v[v_offset], ldv, &workd[*n + 1], &ierr); - F77_FUNC(slacpy, SLACPY) ("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz); + F77_FUNC(sorm2r, SORM2R) + ("Right", "Notranspose", n, ncv, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &v[v_offset], + ldv, &workd[*n + 1], &ierr); + F77_FUNC(slacpy, SLACPY)("All", n, &nconv, &v[v_offset], ldv, &z__[z_offset], ldz); i__1 = *ncv - 1; for (j = 1; j <= i__1; ++j) @@ -5673,13 +5399,12 @@ L30: workl[ihb + j - 1] = 0.; } workl[ihb + *ncv - 1] = 1.; - F77_FUNC(sorm2r, SORM2R) ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, & - workl[iw + *ncv], &workl[ihb], ncv, &temp, &ierr); - + F77_FUNC(sorm2r, SORM2R) + ("Left", "Transpose", ncv, &c__1, &nconv, &workl[iq], &ldq, &workl[iw + *ncv], &workl[ihb], + ncv, &temp, &ierr); } else if (*rvec && *howmny == 'S') { - } if (!std::strncmp(type__, "REGULR", 6) && *rvec) @@ -5690,12 +5415,11 @@ L30: { workl[ihb + j - 1] = rnorm * std::abs(workl[ihb + j - 1]); } - } else if (std::strncmp(type__, "REGULR", 6) && *rvec) { - F77_FUNC(sscal, SSCAL) (ncv, &bnorm2, &workl[ihb], &c__1); + F77_FUNC(sscal, SSCAL)(ncv, &bnorm2, &workl[ihb], &c__1); if (!std::strncmp(type__, "SHIFTI", 6)) { @@ -5703,9 +5427,8 @@ L30: for (k = 1; k <= i__1; ++k) { d__2 = workl[iw + k - 1]; - workl[ihb + k - 1] = std::abs(workl[ihb + k - 1])/(d__2 * d__2); + workl[ihb + k - 1] = std::abs(workl[ihb + k - 1]) / (d__2 * d__2); } - } else if (!std::strncmp(type__, "BUCKLE", 6)) { @@ -5714,9 +5437,8 @@ L30: for (k = 1; k <= i__1; ++k) { d__2 = workl[iw + k - 1] - 1.; - workl[ihb + k - 1] = *sigma * std::abs(workl[ihb + k - 1])/(d__2 * d__2); + workl[ihb + k - 1] = *sigma * std::abs(workl[ihb + k - 1]) / (d__2 * d__2); } - } else if (!std::strncmp(type__, "CAYLEY", 6)) { @@ -5724,12 +5446,10 @@ L30: i__1 = *ncv; for (k = 1; k <= i__1; ++k) { - workl[ihb + k - 1] = std::abs(workl[ihb + k - 1] / workl[iw + k - 1] * (workl[iw + k - 1] - 1.)); - + workl[ihb + k - 1] = + std::abs(workl[ihb + k - 1] / workl[iw + k - 1] * (workl[iw + k - 1] - 1.)); } - } - } if (*rvec && (!std::strncmp(type__, "SHIFTI", 6) || !std::strncmp(type__, "CAYLEY", 6))) @@ -5740,7 +5460,6 @@ L30: { workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / workl[iw + k]; } - } else if (*rvec && !std::strncmp(type__, "BUCKLE", 6)) { @@ -5748,20 +5467,19 @@ L30: i__1 = nconv - 1; for (k = 0; k <= i__1; ++k) { - workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / (workl[iw + k] - - 1.); + workl[iw + k] = workl[iq + k * ldq + *ncv - 1] / (workl[iw + k] - 1.); } - } if (std::strncmp(type__, "REGULR", 6)) { - F77_FUNC(sger, SGER) (n, &nconv, &c_b102, &resid[1], &c__1, &workl[iw], &c__1, &z__[ - z_offset], ldz); + F77_FUNC(sger, SGER) + (n, &nconv, &c_b102, &resid[1], &c__1, &workl[iw], &c__1, &z__[z_offset], ldz); } L9000: return; - } + +#endif diff --git a/src/gromacs/linearalgebra/gmx_arpack.h b/src/gromacs/linearalgebra/gmx_arpack.h index 38b2db1d0d..e7b9511f0c 100644 --- a/src/gromacs/linearalgebra/gmx_arpack.h +++ b/src/gromacs/linearalgebra/gmx_arpack.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2004 David van der Spoel, Erik Lindahl, University of Groningen. - * Copyright (c) 2012,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -95,25 +95,23 @@ * and 3 that no shifts could be applied. Negative numbers * correspond to errors in the arguments provided. */ -void - F77_FUNC(dsaupd, DSAUPD) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - double * tol, - double * resid, - int * ncv, - double * v, - int * ldv, - int * iparam, - int * ipntr, - double * workd, - int * iwork, - double * workl, - int * lworkl, - int * info); - +void F77_FUNC(dsaupd, DSAUPD)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + double* tol, + double* resid, + int* ncv, + double* v, + int* ldv, + int* iparam, + int* ipntr, + double* workd, + int* iwork, + double* workl, + int* lworkl, + int* info); /*! \brief Get eigenvalues/vectors after Arnoldi iteration, double prec. @@ -154,32 +152,28 @@ void * \param lworkl Provide the same argument as you did to dsaupd() * \param info Provide the same argument as you did to dsaupd() */ -void - F77_FUNC(dseupd, DSEUPD) (int * rvec, - const char * howmny, - int * select, - double * d, - double * z, - int * ldz, - double * sigma, - const char * bmat, - int * n, - const char * which, - int * nev, - double * tol, - double * resid, - int * ncv, - double * v, - int * ldv, - int * iparam, - int * ipntr, - double * workd, - double * workl, - int * lworkl, - int * info); - - - +void F77_FUNC(dseupd, DSEUPD)(int* rvec, + const char* howmny, + int* select, + double* d, + double* z, + int* ldz, + double* sigma, + const char* bmat, + int* n, + const char* which, + int* nev, + double* tol, + double* resid, + int* ncv, + double* v, + int* ldv, + int* iparam, + int* ipntr, + double* workd, + double* workl, + int* lworkl, + int* info); /*! \brief Implicitly Restarted Arnoldi Iteration, single precision. @@ -226,27 +220,23 @@ void * and 3 that no shifts could be applied. Negative numbers * correspond to errors in the arguments provided. */ -void - F77_FUNC(ssaupd, SSAUPD) (int * ido, - const char * bmat, - int * n, - const char * which, - int * nev, - float * tol, - float * resid, - int * ncv, - float * v, - int * ldv, - int * iparam, - int * ipntr, - float * workd, - int * iwork, - float * workl, - int * lworkl, - int * info); - - - +void F77_FUNC(ssaupd, SSAUPD)(int* ido, + const char* bmat, + int* n, + const char* which, + int* nev, + float* tol, + float* resid, + int* ncv, + float* v, + int* ldv, + int* iparam, + int* ipntr, + float* workd, + int* iwork, + float* workl, + int* lworkl, + int* info); /*! \brief Get eigenvalues/vectors after Arnoldi iteration, single prec. @@ -287,28 +277,27 @@ void * \param lworkl Provide the same argument as you did to ssaupd() * \param info Provide the same argument as you did to ssaupd() */ -void - F77_FUNC(sseupd, SSEUPD) (int * rvec, - const char * howmny, - int * select, - float * d, - float * z, - int * ldz, - float * sigma, - const char * bmat, - int * n, - const char * which, - int * nev, - float * tol, - float * resid, - int * ncv, - float * v, - int * ldv, - int * iparam, - int * ipntr, - float * workd, - float * workl, - int * lworkl, - int * info); +void F77_FUNC(sseupd, SSEUPD)(int* rvec, + const char* howmny, + int* select, + float* d, + float* z, + int* ldz, + float* sigma, + const char* bmat, + int* n, + const char* which, + int* nev, + float* tol, + float* resid, + int* ncv, + float* v, + int* ldv, + int* iparam, + int* ipntr, + float* workd, + float* workl, + int* lworkl, + int* info); #endif diff --git a/src/gromacs/linearalgebra/gmx_blas.h b/src/gromacs/linearalgebra/gmx_blas.h index 991cf8b2e6..4e8e4d7d86 100644 --- a/src/gromacs/linearalgebra/gmx_blas.h +++ b/src/gromacs/linearalgebra/gmx_blas.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,145 +67,243 @@ #include "gromacs/utility/real.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #if 0 } #endif -/* Double precision versions */ -double - F77_FUNC(dasum, DASUM) (int *n, double *dx, int *incx); - -void - F77_FUNC(daxpy, DAXPY) (int *n, double *da, double *dx, int *incx, double *dy, int *incy); - -void - F77_FUNC(dcopy, DCOPY) (int *n, double *dx, int *incx, double *dy, int *incy); - -double - F77_FUNC(ddot, DDOT) (int *n, double *dx, int *incx, double *dy, int *incy); - -void - F77_FUNC(dgemm, DGEMM) (const char *transa, const char *transb, int *m, int *n, int *k, - double *alpha, double *a, int *lda, double *b, int *ldb, - double *beta, double *c, int *ldc); - -void - F77_FUNC(dgemv, DGEMV) (const char *trans, int *m, int *n, double *alpha, double *a, int *lda, - double *x, int *incx, double *beta, double *y, int *incy); - -void - F77_FUNC(dger, DGER) (int *m, int *n, double *alpha, double *x, int *incx, - double *y, int *incy, double *a, int *lda); - -double - F77_FUNC(dnrm2, DNRM2) (int *n, double *x, int *incx); - -void - F77_FUNC(drot, DROT) (int *n, double *dx, int *incx, - double *dy, int *incy, double *c, double *s); - -void - F77_FUNC(dscal, DSCAL) (int *n, double *fact, double *dx, int *incx); - -void - F77_FUNC(dswap, DSWAP) (int *n, double *dx, int *incx, double *dy, int *incy); - -void - F77_FUNC(dsymv, DSYMV) (const char *uplo, int *n, double *alpha, double *a, int *lda, - double *x, int *incx, double *beta, double *y, int *incy); - -void - F77_FUNC(dsyr2, DSYR2) (const char *uplo, int *n, double *alpha, double *x, int *incx, - double *y, int *incy, double *a, int *lda); - -void - F77_FUNC(dsyr2k, DSYR2K) (const char *uplo, const char *trans, int *n, int *k, double *alpha, double *a, - int *lda, double *b, int *ldb, double *beta, double *c, int *ldc); - -void - F77_FUNC(dtrmm, DTRMM) (const char *side, const char *uplo, const char *transa, const char *diag, int *m, int *n, - double *alpha, double *a, int *lda, double *b, int *ldb); - -void - F77_FUNC(dtrmv, DTRMV) (const char *uplo, const char *trans, const char *diag, int *n, - double *a, int *lda, double *x, int *incx); - -void - F77_FUNC(dtrsm, DTRSM) (const char *side, const char *uplo, const char *transa, const char *diag, int *m, int *n, - double *alpha, double *a, int *lda, double *b, int *ldb); - -int - F77_FUNC(idamax, IDAMAX) (int *n, double *dx, int *incx); - - - -/* Single precision versions */ -float - F77_FUNC(sasum, SASUM) (int *n, float *dx, int *incx); - -void - F77_FUNC(saxpy, SAXPY) (int *n, float *da, float *dx, int *incx, float *dy, int *incy); - -void - F77_FUNC(scopy, SCOPY) (int *n, float *dx, int *incx, float *dy, int *incy); - -float - F77_FUNC(sdot, SDOT) (int *n, float *dx, int *incx, float *dy, int *incy); - -void - F77_FUNC(sgemm, SGEMM) (const char *transa, const char *transb, int *m, int *n, int *k, - float *alpha, float *a, int *lda, float *b, int *ldb, - float *beta, float *c, int *ldc); - -void - F77_FUNC(sgemv, SGEMV) (const char *trans, int *m, int *n, float *alpha, float *a, int *lda, - float *x, int *incx, float *beta, float *y, int *incy); - -void - F77_FUNC(sger, SGER) (int *m, int *n, float *alpha, float *x, int *incx, - float *y, int *incy, float *a, int *lda); - -float - F77_FUNC(snrm2, SNRM2) (int *n, float *x, int *incx); - -void - F77_FUNC(srot, SROT) (int *n, float *dx, int *incx, - float *dy, int *incy, float *c, float *s); - -void - F77_FUNC(sscal, SSCAL) (int *n, float *fact, float *dx, int *incx); - -void - F77_FUNC(sswap, SSWAP) (int *n, float *dx, int *incx, float *dy, int *incy); - -void - F77_FUNC(ssymv, SSYMV) (const char *uplo, int *n, float *alpha, float *a, int *lda, - float *x, int *incx, float *beta, float *y, int *incy); - -void - F77_FUNC(ssyr2, SSYR2) (const char *uplo, int *n, float *alpha, float *x, int *incx, - float *y, int *incy, float *a, int *lda); - -void - F77_FUNC(ssyr2k, SSYR2K) (const char *uplo, const char *trans, int *n, int *k, float *alpha, float *a, - int *lda, float *b, int *ldb, float *beta, float *c, int *ldc); - -void - F77_FUNC(strmm, STRMM) (const char *side, const char *uplo, const char *transa, const char *diag, int *m, int *n, - float *alpha, float *a, int *lda, float *b, int *ldb); - -void - F77_FUNC(strmv, STRMV) (const char *uplo, const char *trans, const char *diag, int *n, - float *a, int *lda, float *x, int *incx); - -void - F77_FUNC(strsm, STRSM) (const char *side, const char *uplo, const char *transa, const char *diag, int *m, int *n, - float *alpha, float *a, int *lda, float *b, int *ldb); - -int - F77_FUNC(isamax, ISAMAX) (int *n, float *dx, int *incx); + /* Double precision versions */ + double F77_FUNC(dasum, DASUM)(int* n, double* dx, int* incx); + + void F77_FUNC(daxpy, DAXPY)(int* n, double* da, double* dx, int* incx, double* dy, int* incy); + + void F77_FUNC(dcopy, DCOPY)(int* n, double* dx, int* incx, double* dy, int* incy); + + double F77_FUNC(ddot, DDOT)(int* n, double* dx, int* incx, double* dy, int* incy); + + void F77_FUNC(dgemm, DGEMM)(const char* transa, + const char* transb, + int* m, + int* n, + int* k, + double* alpha, + double* a, + int* lda, + double* b, + int* ldb, + double* beta, + double* c, + int* ldc); + + void F77_FUNC(dgemv, DGEMV)(const char* trans, + int* m, + int* n, + double* alpha, + double* a, + int* lda, + double* x, + int* incx, + double* beta, + double* y, + int* incy); + + void F77_FUNC(dger, + DGER)(int* m, int* n, double* alpha, double* x, int* incx, double* y, int* incy, double* a, int* lda); + + double F77_FUNC(dnrm2, DNRM2)(int* n, double* x, int* incx); + + void F77_FUNC(drot, DROT)(int* n, double* dx, int* incx, double* dy, int* incy, double* c, double* s); + + void F77_FUNC(dscal, DSCAL)(int* n, double* fact, double* dx, int* incx); + + void F77_FUNC(dswap, DSWAP)(int* n, double* dx, int* incx, double* dy, int* incy); + + void F77_FUNC(dsymv, DSYMV)(const char* uplo, + int* n, + double* alpha, + double* a, + int* lda, + double* x, + int* incx, + double* beta, + double* y, + int* incy); + + void F77_FUNC(dsyr2, DSYR2)(const char* uplo, + int* n, + double* alpha, + double* x, + int* incx, + double* y, + int* incy, + double* a, + int* lda); + + void F77_FUNC(dsyr2k, DSYR2K)(const char* uplo, + const char* trans, + int* n, + int* k, + double* alpha, + double* a, + int* lda, + double* b, + int* ldb, + double* beta, + double* c, + int* ldc); + + void F77_FUNC(dtrmm, DTRMM)(const char* side, + const char* uplo, + const char* transa, + const char* diag, + int* m, + int* n, + double* alpha, + double* a, + int* lda, + double* b, + int* ldb); + + void F77_FUNC(dtrmv, DTRMV)(const char* uplo, + const char* trans, + const char* diag, + int* n, + double* a, + int* lda, + double* x, + int* incx); + + void F77_FUNC(dtrsm, DTRSM)(const char* side, + const char* uplo, + const char* transa, + const char* diag, + int* m, + int* n, + double* alpha, + double* a, + int* lda, + double* b, + int* ldb); + + int F77_FUNC(idamax, IDAMAX)(int* n, double* dx, int* incx); + + + /* Single precision versions */ + float F77_FUNC(sasum, SASUM)(int* n, float* dx, int* incx); + + void F77_FUNC(saxpy, SAXPY)(int* n, float* da, float* dx, int* incx, float* dy, int* incy); + + void F77_FUNC(scopy, SCOPY)(int* n, float* dx, int* incx, float* dy, int* incy); + + float F77_FUNC(sdot, SDOT)(int* n, float* dx, int* incx, float* dy, int* incy); + + void F77_FUNC(sgemm, SGEMM)(const char* transa, + const char* transb, + int* m, + int* n, + int* k, + float* alpha, + float* a, + int* lda, + float* b, + int* ldb, + float* beta, + float* c, + int* ldc); + + void F77_FUNC(sgemv, SGEMV)(const char* trans, + int* m, + int* n, + float* alpha, + float* a, + int* lda, + float* x, + int* incx, + float* beta, + float* y, + int* incy); + + void F77_FUNC(sger, + SGER)(int* m, int* n, float* alpha, float* x, int* incx, float* y, int* incy, float* a, int* lda); + + float F77_FUNC(snrm2, SNRM2)(int* n, float* x, int* incx); + + void F77_FUNC(srot, SROT)(int* n, float* dx, int* incx, float* dy, int* incy, float* c, float* s); + + void F77_FUNC(sscal, SSCAL)(int* n, float* fact, float* dx, int* incx); + + void F77_FUNC(sswap, SSWAP)(int* n, float* dx, int* incx, float* dy, int* incy); + + void F77_FUNC(ssymv, SSYMV)(const char* uplo, + int* n, + float* alpha, + float* a, + int* lda, + float* x, + int* incx, + float* beta, + float* y, + int* incy); + + void F77_FUNC(ssyr2, SSYR2)(const char* uplo, + int* n, + float* alpha, + float* x, + int* incx, + float* y, + int* incy, + float* a, + int* lda); + + void F77_FUNC(ssyr2k, SSYR2K)(const char* uplo, + const char* trans, + int* n, + int* k, + float* alpha, + float* a, + int* lda, + float* b, + int* ldb, + float* beta, + float* c, + int* ldc); + + void F77_FUNC(strmm, STRMM)(const char* side, + const char* uplo, + const char* transa, + const char* diag, + int* m, + int* n, + float* alpha, + float* a, + int* lda, + float* b, + int* ldb); + + void F77_FUNC(strmv, STRMV)(const char* uplo, + const char* trans, + const char* diag, + int* n, + float* a, + int* lda, + float* x, + int* incx); + + void F77_FUNC(strsm, STRSM)(const char* side, + const char* uplo, + const char* transa, + const char* diag, + int* m, + int* n, + float* alpha, + float* a, + int* lda, + float* b, + int* ldb); + + int F77_FUNC(isamax, ISAMAX)(int* n, float* dx, int* incx); #ifdef __cplusplus diff --git a/src/gromacs/linearalgebra/gmx_lapack.h b/src/gromacs/linearalgebra/gmx_lapack.h index b29535a6e5..3d9fb90217 100644 --- a/src/gromacs/linearalgebra/gmx_lapack.h +++ b/src/gromacs/linearalgebra/gmx_lapack.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,788 +73,1730 @@ #include "gromacs/utility/real.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #if 0 } #endif -/* Double precision */ - -void - F77_FUNC(dbdsdc, DBDSDC) (const char *uplo, const char *compq, int *n, double *d, double *e, double *u, - int *ldu, double *vt, int *ldvt, double *q, int *iq, double *work, - int *iwork, int *info); - -void - F77_FUNC(dgetf2, DGETF2) (int *m, int *n, double *a, int *lda, int *ipiv, int *info); - -void - F77_FUNC(dlamrg, DLAMRG) (int *n1, int *n2, double *a, int *dtrd1, int *dtrd2, int *index); - -void - F77_FUNC(dlarnv, DLARNV) (int *idist, int *iseed, int *n, double *x); - -void - F77_FUNC(dlasd0, DLASD0) (int *n, int *sqre, double *d, double *e, double *u, - int *ldu, double *vt, int *ldvt, int *smlsiz, int *iwork, - double *work, int *info); - -void - F77_FUNC(dlasda, DLASDA) (int *icompq, int *smlsiz, int *n, int *sqre, double *d, double *e, - double *u, int *ldu, double *vt, int *k, double *difl, double *difr, - double *z, double *poles, int *givptr, int *givcol, int *ldgcol, - int *perm, double *givnum, double *c, double *s, - double *work, int *iwork, int *info); - -void - F77_FUNC(dlasq6, DLASQ6) (int *i0, int *n0, double *z, int *pp, double *dmin, double *dmin1, - double *dmin2, double *dn, double *dnm1, double *dnm2); - -void - F77_FUNC(dorgl2, DORGL2) (int *m, int *n, int *k, double *a, int *lda, - double *tau, double *work, int *info); - -void - F77_FUNC(dbdsqr, DBDSQR) (const char *uplo, int *n, int *ncvt, int *nru, int *ncc, double *d, - double *e, double *vt, int *ldvt, double *u, int *ldu, - double *c, int *ldc, double *work, int *info); - -void - F77_FUNC(dgetrf, DGETRF) (int *m, int *n, double *a, int *lda, int *ipiv, int *info); - -void - F77_FUNC(dgetri, DGETRI) (int *n, double *a, int *lda, int *ipiv, double *work, - int *lwork, int *info); - -void - F77_FUNC(dgetrs, DGETRS) (const char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, - double *b, int *ldb, int *info); - -void - F77_FUNC(dtrtri, DTRTRI) (const char *uplo, const char *diag, int *n, double *a, int *lda, int *info); - -void - F77_FUNC(dtrti2, DTRTI2) (const char *uplo, const char *diag, int *n, double *a, int *lda, int *info); - -double - F77_FUNC(dlange, DLANGE) (const char *norm, int *m, int *n, double *a, int *lda, double *work); - -void - F77_FUNC(dlarrbx, DLARRBX) (int *n, double *d, double *l, double *ld, double *lld, int *ifirst, - int *ilast, double *rtol1, double *rtol2, int *offset, double *w, - double *wgap, double *werr, double *work, int *iwork, int *info); - -void - F77_FUNC(dlasd1, DLASD1) (int *nl, int *nr, int *sqre, double *d, double *alpha, double *beta, - double *u, int *ldu, double *vt, int *ldvt, int *idxq, int *iwork, - double *work, int *info); - -void - F77_FUNC(dlasdq, DLASDQ) (const char *uplo, int *sqre, int *n, int *ncvt, int *nru, int *ncc, - double *d, double *e, double *vt, int *ldvt, double *u, int *ldu, - double *c, int *ldc, double *work, int *info); - -void - F77_FUNC(dlasr, DLASR) (const char *side, const char *pivot, const char *direct, int *m, int *n, double *c, - double *s, double *a, int *lda); - -void - F77_FUNC(dorglq, DORGLQ) (int *m, int *n, int *k, double *a, int *lda, - double *tau, double *work, int *lwork, int *info); - -void - F77_FUNC(dormtr, DORMTR) (const char *side, const char *uplo, const char *trans, int *m, int *n, double *a, - int *lda, double *tau, double *c, int *ldc, - double *work, int *lwork, int *info); - -void - F77_FUNC(dgebd2, DGEBD2) (int *m, int *n, double *a, int *lda, double *d, double *e, - double *tauq, double *taup, double *work, int *info); - -void - F77_FUNC(dlabrd, DLABRD) (int *m, int *n, int *nb, double *a, int *lda, double *d, - double *e, double *tauq, double *taup, double *x, - int *ldx, double *y, int *ldy); - -double - F77_FUNC(dlanst, DLANST) (const char *norm, int *n, double *d, double *e); - -double - F77_FUNC(dlansy, DLANSY) (const char *norm, const char *uplo, int *n, double *a, int *lda, double *work); - -void - F77_FUNC(dlarrex, DLARREX) (const char *range, int *n, double *vl, double *vu, int *il, int *iu, - double *d, double *e, double *tol, int *nsplit, - int *isplit, int *m, double *w, int *iblock, int *indexw, - double *gersch, double *work, int *iwork, int *info); - -void - F77_FUNC(dlasd2, DLASD2) (int *nl, int *nr, int *sqre, int *k, double *d, double *z, - double *alpha, double *beta, double *u, int *ldu, double *vt, - int *ldvt, double *dsigma, double *u2, int *ldu2, double *vt2, - int *ldvt2, int *idxp, int *idx, int *idxc, - int *idxq, int *coltyp, int *info); - -void - F77_FUNC(dlasdt, DLASDT) (int *n, int *lvl, int *nd, int *inode, int *ndiml, - int *ndimr, int *msub); - -void - F77_FUNC(dlasrt, DLASRT) (const char *id, int *n, double *d, int *info); - -void - F77_FUNC(dlasrt2, DLASRT2) (const char *id, int *n, double *d, int *key, int *info); - -void - F77_FUNC(ilasrt2, ILASRT2) (const char *id, int *n, int *d, int *key, int *info); - -void - F77_FUNC(dorgqr, DORGQR) (int *m, int *n, int *k, double *a, int *lda, double *tau, - double *work, int *lwork, int *info); - -void - F77_FUNC(dstebz, DSTEBZ) (const char *range, const char *order, int *n, double *vl, double *vu, - int *il, int *iu, double *abstol, double *d, double *e, - int *m, int *nsplit, double *w, int *iblock, int *isplit, - double *work, int *iwork, int *info); - -void - F77_FUNC(dsteqr, DSTEQR) (const char *compz, int *n, double *d__, double *e, - double *z__, int *ldz, double *work, int *info); - -void - F77_FUNC(dgebrd, DGEBRD) (int *m, int *n, double *a, int *lda, double *d, double *e, - double *tauq, double *taup, double *work, int *lwork, int *info); - -void - F77_FUNC(dlacpy, DLACPY) (const char *uplo, int *m, int *n, double *a, int *lda, double *b, int *ldb); - -double - F77_FUNC(dlapy2, DLAPY2) (double * x, double * y); - - -void - F77_FUNC(dlarrfx, DLARRFX) (int *n, double *d, double *l, double *ld, double *lld, int *ifirst, - int *ilast, double *w, double *sigma, double *dplus, double *lplus, - double *work, int *info); - -void - F77_FUNC(dlasd3, DLASD3) (int *nl, int *nr, int *sqre, int *k, double *d, double *q, int *ldq, - double *dsigma, double *u, int *ldu, double *u2, int *ldu2, - double *vt, int *ldvt, double *vt2, int *ldvt2, int *idxc, - int *ctot, double *z, int *info); - -void - F77_FUNC(dlaset, DLASET) (const char *uplo, int *m, int *n, double *alpha, - double *beta, double *a, int *lda); - -void - F77_FUNC(dlassq, DLASSQ) (int *n, double *x, int *incx, double *scale, double *sumsq); - -void - F77_FUNC(dorm2l, DORM2L) (const char *side, const char *trans, int *m, int *n, int *k, double *a, int *lda, - double *tau, double *c, int *ldc, double *work, int *info); - -void - F77_FUNC(dstegr, DSTEGR) (const char *jobz, const char *range, int *n, double *d, double *e, double *vl, - double *vu, int *il, int *iu, double *abstol, int *m, double *w, - double *z, int *ldz, int *isuppz, double *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(ssteqr, SSTEQR) (const char *compz, int *n, float *d__, float *e, - float *z__, int *ldz, float *work, int *info); - -void - F77_FUNC(dgelq2, DGELQ2) (int *m, int *n, double *a, int *lda, double *tau, double *work, int *info); - -void - F77_FUNC(dlae2, DLAE2) (double *a, double *b, double *c, double *rt1, double *rt2); - -void - F77_FUNC(dlaev2, DLAEV2) (double *a, double *b, double *c, double *rt1, double *rt2, - double *cs1, double *cs2); - -void - F77_FUNC(dlar1vx, DLAR1VX) (int *n, int *b1, int *bn, double *sigma, double *d, double *l, double *ld, - double *lld, double *eval, double *gersch, double *z, double *ztz, double *mingma, - int *r, int *isuppz, double *work); - -void - F77_FUNC(dlarrvx, DLARRVX) (int *n, double *d, double *l, int *isplit, int *m, double *w, - int *iblock, int *indexw, double *gersch, double *tol, double *z, int *ldz, - int *isuppz, double *work, int *iwork, int *info); - -void - F77_FUNC(dlasd4, DLASD4) (int *n, int *i, double *d, double *z, double *delta, - double *rho, double *sigma, double *work, int *info); - -void - F77_FUNC(dlasq1, DLASQ1) (int *n, double *d, double *e, double *work, int *info); - - -void - F77_FUNC(dlasv2, DLASV2) (double *f, double *g, double *h, double *ssmin, double *ssmax, - double *snr, double *csr, double *snl, double *csl); - -void - F77_FUNC(dorm2r, DORM2R) (const char *side, const char *trans, int *m, int *n, int *k, double *a, - int *lda, double *tau, double *c, int *ldc, double *work, int *info); - -void - F77_FUNC(dstein, DSTEIN) (int *n, double *d, double *e, int *m, double *w, int *iblock, int *isplit, - double *z, int *ldz, double *work, int *iwork, int *ifail, int *info); - -void - F77_FUNC(dgelqf, DGELQF) (int *m, int *n, double *a, int *lda, double *tau, - double *work, int *lwork, int *info); - -void - F77_FUNC(dlaebz, DLAEBZ) (int *ijob, int *nitmax, int *n, int *mmax, int *minp, int *nbmin, - double *abstol, double *reltol, double *pivmin, double *d, double *e, - double *e2, int *nval, double *ab, double *c, int *mout, int *nab, - double *work, int *iwork, int *info); - -void - F77_FUNC(dlarf, DLARF) (const char *side, int *m, int *n, double *v, int *incv, double *tau, - double *c, int *ldc, double *work); - -void - F77_FUNC(dlartg, DLARTG) (double *f, double *g, double *cs, double *sn, double *r); - -void - F77_FUNC(dlasd5, DLASD5) (int *i, double *d, double *z, double *delta, - double *rho, double *dsigma, double *work); - -void - F77_FUNC(dlasq2, DLASQ2) (int *n, double *z, int *info); - -void - F77_FUNC(dlasq3, DLASQ3) (int *i0, int *n0, double *z, int *pp, double *dmin, - double *sigma, double *desig, double *qmax, int *nfail, - int *iter, int *ndiv, int *ieee); - -void - F77_FUNC(dlaswp, DLASWP) (int *n, double *a, int *lda, int *k1, int *k2, int *ipiv, int *incx); - -void - F77_FUNC(dormbr, DORMBR) (const char *vect, const char *side, const char *trans, int *m, int *n, int *k, - double *a, int *lda, double *tau, double *c, int *ldc, double *work, - int *lwork, int *info); - -void - F77_FUNC(dsterf, DSTERF) (int *n, double *d, double *e, int *info); - -void - F77_FUNC(dgeqr2, DGEQR2) (int *m, int *n, double *a, int *lda, double *tau, - double *work, int *info); - -void - F77_FUNC(dlaed6, DLAED6) (int *kniter, int *orgati, double *rho, double *d, - double *z, double *finit, double *tau, int *info); - -void - F77_FUNC(dlarfb, DLARFB) (const char *side, const char *trans, const char *direct, const char *storev, int *m, int *n, - int *k, double *v, int *ldv, double *t, int *ldt, double *c, - int *ldc, double *work, int *ldwork); - -void - F77_FUNC(dlaruv, DLARUV) (int *iseed, int *n, double *x); - -void - F77_FUNC(dlasd6, DLASD6) (int *icompq, int *nl, int *nr, int *sqre, double *d, double *vf, - double *vl, double *alpha, double *beta, int *idxq, int *perm, - int *givptr, int *givcol, int *ldgcol, double *givnum, int *ldgnum, - double *poles, double *difl, double *difr, double *z, int *k, - double *c, double *s, double *work, int *iwork, int *info); - -void - F77_FUNC(dlatrd, DLATRD) (const char *uplo, int *n, int *nb, double *a, int *lda, double *e, - double * tau, double *w, int *ldw); - -void - F77_FUNC(dorml2, DORML2) (const char *side, const char *trans, int *m, int *n, int *k, double *a, - int *lda, double *tau, double *c, int *ldc, double *work, int *info); - -void - F77_FUNC(dstevr, DSTEVR) (const char *jobz, const char *range, int *n, double *d, double *e, double *vl, - double *vu, int *il, int *iu, double *abstol, int *m, double *w, - double *z, int *ldz, int *isuppz, double *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(dsytrd, DSYTRD) (const char *uplo, int *n, double * a, int *lda, double *d, - double *e, double *tau, double *work, int *lwork, int *info); - -void - F77_FUNC(dsyevr, DSYEVR) (const char *jobz, const char *range, const char *uplo, int *n, - double *a, int *lda, double *vl, double *vu, int * - il, int *iu, double *abstol, int *m, double *w, - double *z__, int *ldz, int *isuppz, double *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(dormql, DORMQL) (const char *side, const char *trans, int *m, int *n, - int *k, double *a, int *lda, double *tau, double * - c, int *ldc, double *work, int *lwork, int *info); - -void - F77_FUNC(dormqr, DORMQR) (const char *side, const char *trans, int *m, int *n, int *k, double *a, - int *lda, double *tau, double *c, int *ldc, - double *work, int *lwork, int *info); - -void - F77_FUNC(dorgbr, DORGBR) (const char *vect, int *m, int *n, int *k, double *a, int *lda, - double *tau, double *work, int *lwork, int *info); - -void - F77_FUNC(dlasq5, DLASQ5) (int *i0, int *n0, double *z, int *pp, double *tau, double *dmin, - double *dmin1, double *dmin2, double *dn, double *dnm1, - double *dnm2, int *ieee); - -void - F77_FUNC(dlasd8, DLASD8) (int *icompq, int *k, double *d, double *z, double *vf, double *vl, - double *difl, double *difr, int *lddifr, double *dsigma, - double *work, int *info); - -void - F77_FUNC(dlascl, DLASCL) (const char *type, int *kl, int *ku, double *cfrom, double *cto, int *m, - int *n, double *a, int *lda, int *info); - -void - F77_FUNC(dlarft, DLARFT) (const char *direct, const char *storev, int *n, int *k, double *v, - int *ldv, double *tau, double *t, int *ldt); - -void - F77_FUNC(dlagts, DLAGTS) (int *job, int *n, double *a, double *b, double *c, double *d, - int *in, double *y, double *tol, int *info); - -void - F77_FUNC(dgesdd, DGESDD) (const char *jobz, int *m, int *n, double *a, int *lda, double *s, double *u, - int *ldu, double *vt, int *ldvt, double *work, int *lwork, - int *iwork, int *info); - -void - F77_FUNC(dsytd2, DSYTD2) (const char *uplo, int *n, double *a, int *lda, double *d, - double *e, double *tau, int *info); - -void - F77_FUNC(dormlq, DORMLQ) (const char *side, const char *trans, int *m, int *n, int *k, double *a, int *lda, - double *tau, double *c, int *ldc, double *work, int *lwork, int *info); - -void - F77_FUNC(dorg2r, DORG2R) (int *m, int *n, int *k, double *a, int *lda, double *tau, - double *work, int *info); - -void - F77_FUNC(dlasq4, DLASQ4) (int *i0, int *n0, double *z, int *pp, int *n0in, double *dmin, - double *dmin1, double *dmin2, double *dn, double *dn1, - double *dn2, double *tau, int *ttype); - -void - F77_FUNC(dlasd7, DLASD7) (int *icompq, int *nl, int *nr, int *sqre, int *k, double *d, double *z, - double *zw, double *vf, double *vfw, double *vl, double *vlw, - double *alpha, double *beta, double *dsigma, int *idx, int *idxp, - int *idxq, int *perm, int *givptr, int *givcol, int *ldgcol, - double *givnum, int *ldgnum, double *c, double *s, int *info); - -void - F77_FUNC(dlas2, DLAS2) (double *f, double *g, double *h, double *ssmin, double *ssmax); - -void - F77_FUNC(dlarfg, DLARFG) (int *n, double *alpha, double *x, int *incx, double *tau); - -void - F77_FUNC(dlagtf, DLAGTF) (int *n, double *a, double *lambda, double *b, double *c, - double *tol, double *d, int *in, int *info); - -void - F77_FUNC(dgeqrf, DGEQRF) (int *m, int *n, double *a, int *lda, double *tau, - double *work, int *lwork, int *info); - - - -/* Single precision */ - -void - F77_FUNC(sbdsdc, SBDSDC) (const char *uplo, const char *compq, int *n, float *d, float *e, float *u, - int *ldu, float *vt, int *ldvt, float *q, int *iq, float *work, - int *iwork, int *info); - -void - F77_FUNC(sgetf2, SGETF2) (int *m, int *n, float *a, int *lda, int *ipiv, int *info); - -void - F77_FUNC(slamrg, SLAMRG) (int *n1, int *n2, float *a, int *dtrd1, int *dtrd2, int *index); - -void - F77_FUNC(slarnv, SLARNV) (int *idist, int *iseed, int *n, float *x); - -void - F77_FUNC(slasd0, SLASD0) (int *n, int *sqre, float *d, float *e, float *u, - int *ldu, float *vt, int *ldvt, int *smlsiz, int *iwork, - float *work, int *info); - -void - F77_FUNC(slasda, SLASDA) (int *icompq, int *smlsiz, int *n, int *sqre, float *d, float *e, - float *u, int *ldu, float *vt, int *k, float *difl, float *difr, - float *z, float *poles, int *givptr, int *givcol, int *ldgcol, - int *perm, float *givnum, float *c, float *s, - float *work, int *iwork, int *info); - -void - F77_FUNC(slasq6, SLASQ6) (int *i0, int *n0, float *z, int *pp, float *dmin, float *dmin1, - float *dmin2, float *dn, float *dnm1, float *dnm2); - -void - F77_FUNC(sorgl2, SORGL2) (int *m, int *n, int *k, float *a, int *lda, - float *tau, float *work, int *info); - -void - F77_FUNC(sbdsqr, SBDSQR) (const char *uplo, int *n, int *ncvt, int *nru, int *ncc, float *d, - float *e, float *vt, int *ldvt, float *u, int *ldu, - float *c, int *ldc, float *work, int *info); - -void - F77_FUNC(sgetrf, SGETRF) (int *m, int *n, float *a, int *lda, int *ipiv, int *info); - -void - F77_FUNC(sgetri, SGETRI) (int *n, float *a, int *lda, int *ipiv, float *work, - int *lwork, int *info); - -void - F77_FUNC(sgetrs, SGETRS) (const char *trans, int *n, int *nrhs, float *a, int *lda, int *ipiv, - float *b, int *ldb, int *info); - -void - F77_FUNC(strtri, STRTRI) (const char *uplo, const char *diag, int *n, float *a, int *lda, int *info); - -void - F77_FUNC(strti2, STRTI2) (const char *uplo, const char *diag, int *n, float *a, int *lda, int *info); - -float - F77_FUNC(slange, SLANGE) (const char *norm, int *m, int *n, float *a, int *lda, float *work); - -void - F77_FUNC(slarrbx, SLARRBX) (int *n, float *d, float *l, float *ld, float *lld, int *ifirst, - int *ilast, float *rtol1, float *rtol2, int *offset, float *w, - float *wgap, float *werr, float *work, int *iwork, int *info); - -void - F77_FUNC(slasd1, SLASD1) (int *nl, int *nr, int *sqre, float *d, float *alpha, float *beta, - float *u, int *ldu, float *vt, int *ldvt, int *idxq, int *iwork, - float *work, int *info); - -void - F77_FUNC(slasdq, SLASDQ) (const char *uplo, int *sqre, int *n, int *ncvt, int *nru, int *ncc, - float *d, float *e, float *vt, int *ldvt, float *u, int *ldu, - float *c, int *ldc, float *work, int *info); - -void - F77_FUNC(slasr, SLASR) (const char *side, const char *pivot, const char *direct, int *m, int *n, float *c, - float *s, float *a, int *lda); - -void - F77_FUNC(sorglq, SORGLQ) (int *m, int *n, int *k, float *a, int *lda, - float *tau, float *work, int *lwork, int *info); - -void - F77_FUNC(sormtr, SORMTR) (const char *side, const char *uplo, const char *trans, int *m, int *n, float *a, - int *lda, float *tau, float *c, int *ldc, - float *work, int *lwork, int *info); - -void - F77_FUNC(sgebd2, SGEBD2) (int *m, int *n, float *a, int *lda, float *d, float *e, - float *tauq, float *taup, float *work, int *info); - -void - F77_FUNC(slabrd, SLABRD) (int *m, int *n, int *nb, float *a, int *lda, float *d, - float *e, float *tauq, float *taup, float *x, - int *ldx, float *y, int *ldy); - -float - F77_FUNC(slanst, SLANST) (const char *norm, int *n, float *d, float *e); - -float - F77_FUNC(slansy, SLANSY) (const char *norm, const char *uplo, int *n, float *a, int *lda, float *work); - -void - F77_FUNC(slarrex, SLARREX) (const char *range, int *n, float *vl, float *vu, int *il, int *iu, - float *d, float *e, float *tol, int *nsplit, - int *isplit, int *m, float *w, int *iblock, int *indexw, - float *gersch, float *work, int *iwork, int *info); - -void - F77_FUNC(slasd2, SLASD2) (int *nl, int *nr, int *sqre, int *k, float *d, float *z, - float *alpha, float *beta, float *u, int *ldu, float *vt, - int *ldvt, float *dsigma, float *u2, int *ldu2, float *vt2, - int *ldvt2, int *idxp, int *idx, int *idxc, - int *idxq, int *coltyp, int *info); - -void - F77_FUNC(slasdt, SLASDT) (int *n, int *lvl, int *nd, int *inode, int *ndiml, - int *ndimr, int *msub); - -void - F77_FUNC(slasrt, SLASRT) (const char *id, int *n, float *d, int *info); - -void - F77_FUNC(slasrt2, SLASRT2) (const char *id, int *n, float *d, int *key, int *info); - -void - F77_FUNC(sorgqr, SORGQR) (int *m, int *n, int *k, float *a, int *lda, float *tau, - float *work, int *lwork, int *info); - -void - F77_FUNC(sstebz, SSTEBZ) (const char *range, const char *order, int *n, float *vl, float *vu, - int *il, int *iu, float *abstol, float *d, float *e, - int *m, int *nsplit, float *w, int *iblock, int *isplit, - float *work, int *iwork, int *info); - -void - F77_FUNC(sgebrd, SGEBRD) (int *m, int *n, float *a, int *lda, float *d, float *e, - float *tauq, float *taup, float *work, int *lwork, int *info); - -void - F77_FUNC(slacpy, SLACPY) (const char *uplo, int *m, int *n, float *a, int *lda, float *b, int *ldb); - -float - F77_FUNC(slapy2, SLAPY2) (float * x, float * y); - -void - F77_FUNC(slarrfx, SLARRFX) (int *n, float *d, float *l, float *ld, float *lld, int *ifirst, - int *ilast, float *w, float *sigma, float *dplus, float *lplus, - float *work, int *info); - -void - F77_FUNC(slasd3, SLASD3) (int *nl, int *nr, int *sqre, int *k, float *d, float *q, int *ldq, - float *dsigma, float *u, int *ldu, float *u2, int *ldu2, - float *vt, int *ldvt, float *vt2, int *ldvt2, int *idxc, - int *ctot, float *z, int *info); - -void - F77_FUNC(slaset, SLASET) (const char *uplo, int *m, int *n, float *alpha, - float *beta, float *a, int *lda); - -void - F77_FUNC(slassq, SLASSQ) (int *n, float *x, int *incx, float *scale, float *sumsq); - -void - F77_FUNC(sorm2l, SORM2L) (const char *side, const char *trans, int *m, int *n, int *k, float *a, int *lda, - float *tau, float *c, int *ldc, float *work, int *info); - -void - F77_FUNC(sstegr, SSTEGR) (const char *jobz, const char *range, int *n, float *d, float *e, float *vl, - float *vu, int *il, int *iu, float *abstol, int *m, float *w, - float *z, int *ldz, int *isuppz, float *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(sgelq2, SGELQ2) (int *m, int *n, float *a, int *lda, float *tau, float *work, int *info); - -void - F77_FUNC(slae2, SLAE2) (float *a, float *b, float *c, float *rt1, float *rt2); - -void - F77_FUNC(slaev2, SLAEV2) (float *a, float *b, float *c, float *rt1, float *rt2, - float *cs1, float *cs2); - -void - F77_FUNC(slar1vx, SLAR1VX) (int *n, int *b1, int *bn, float *sigma, float *d, float *l, float *ld, - float *lld, float *eval, float *gersch, float *z, float *ztz, float *mingma, - int *r, int *isuppz, float *work); - -void - F77_FUNC(slarrvx, SLARRVX) (int *n, float *d, float *l, int *isplit, int *m, float *w, - int *iblock, int *indexw, float *gersch, float *tol, float *z, int *ldz, - int *isuppz, float *work, int *iwork, int *info); - -void - F77_FUNC(slasd4, SLASD4) (int *n, int *i, float *d, float *z, float *delta, - float *rho, float *sigma, float *work, int *info); - -void - F77_FUNC(slasq1, SLASQ1) (int *n, float *d, float *e, float *work, int *info); - - -void - F77_FUNC(slasv2, SLASV2) (float *f, float *g, float *h, float *ssmin, float *ssmax, - float *snr, float *csr, float *snl, float *csl); - -void - F77_FUNC(sorm2r, SORM2R) (const char *side, const char *trans, int *m, int *n, int *k, float *a, - int *lda, float *tau, float *c, int *ldc, float *work, int *info); - -void - F77_FUNC(sstein, SSTEIN) (int *n, float *d, float *e, int *m, float *w, int *iblock, int *isplit, - float *z, int *ldz, float *work, int *iwork, int *ifail, int *info); - -void - F77_FUNC(sgelqf, SGELQF) (int *m, int *n, float *a, int *lda, float *tau, - float *work, int *lwork, int *info); - -void - F77_FUNC(slaebz, SLAEBZ) (int *ijob, int *nitmax, int *n, int *mmax, int *minp, int *nbmin, - float *abstol, float *reltol, float *pivmin, float *d, float *e, - float *e2, int *nval, float *ab, float *c, int *mout, int *nab, - float *work, int *iwork, int *info); - -void - F77_FUNC(slarf, SLARF) (const char *side, int *m, int *n, float *v, int *incv, float *tau, - float *c, int *ldc, float *work); - -void - F77_FUNC(slartg, SLARTG) (float *f, float *g, float *cs, float *sn, float *r); - -void - F77_FUNC(slasd5, SLASD5) (int *i, float *d, float *z, float *delta, - float *rho, float *dsigma, float *work); - -void - F77_FUNC(slasq2, SLASQ2) (int *n, float *z, int *info); - -void - F77_FUNC(slasq3, SLASQ3) (int *i0, int *n0, float *z, int *pp, float *dmin, - float *sigma, float *desig, float *qmax, int *nfail, - int *iter, int *ndiv, int *ieee); - -void - F77_FUNC(slaswp, SLASWP) (int *n, float *a, int *lda, int *k1, int *k2, int *ipiv, int *incx); - -void - F77_FUNC(sormbr, SORMBR) (const char *vect, const char *side, const char *trans, int *m, int *n, int *k, - float *a, int *lda, float *tau, float *c, int *ldc, float *work, - int *lwork, int *info); - -void - F77_FUNC(ssterf, SSTERF) (int *n, float *d, float *e, int *info); - -void - F77_FUNC(sgeqr2, SGEQR2) (int *m, int *n, float *a, int *lda, float *tau, - float *work, int *info); - -void - F77_FUNC(slaed6, SLAED6) (int *kniter, int *orgati, float *rho, float *d, - float *z, float *finit, float *tau, int *info); - -void - F77_FUNC(slarfb, SLARFB) (const char *side, const char *trans, const char *direct, const char *storev, int *m, int *n, - int *k, float *v, int *ldv, float *t, int *ldt, float *c, - int *ldc, float *work, int *ldwork); - -void - F77_FUNC(slaruv, SLARUV) (int *iseed, int *n, float *x); - -void - F77_FUNC(slasd6, SLASD6) (int *icompq, int *nl, int *nr, int *sqre, float *d, float *vf, - float *vl, float *alpha, float *beta, int *idxq, int *perm, - int *givptr, int *givcol, int *ldgcol, float *givnum, int *ldgnum, - float *poles, float *difl, float *difr, float *z, int *k, - float *c, float *s, float *work, int *iwork, int *info); - -void - F77_FUNC(slatrd, SLATRD) (const char *uplo, int *n, int *nb, float *a, int *lda, float *e, - float * tau, float *w, int *ldw); - -void - F77_FUNC(sorml2, SORML2) (const char *side, const char *trans, int *m, int *n, int *k, float *a, - int *lda, float *tau, float *c, int *ldc, float *work, int *info); - -void - F77_FUNC(sstevr, SSTEVR) (const char *jobz, const char *range, int *n, float *d, float *e, float *vl, - float *vu, int *il, int *iu, float *abstol, int *m, float *w, - float *z, int *ldz, int *isuppz, float *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(ssytrd, SSYTRD) (const char *uplo, int *n, float * a, int *lda, float *d, - float *e, float *tau, float *work, int *lwork, int *info); - -void - F77_FUNC(ssyevr, SSYEVR) (const char *jobz, const char *range, const char *uplo, int *n, - float *a, int *lda, float *vl, float *vu, int * - il, int *iu, float *abstol, int *m, float *w, - float *z__, int *ldz, int *isuppz, float *work, - int *lwork, int *iwork, int *liwork, int *info); - -void - F77_FUNC(sormql, SORMQL) (const char *side, const char *trans, int *m, int *n, - int *k, float *a, int *lda, float *tau, float * - c, int *ldc, float *work, int *lwork, int *info); - -void - F77_FUNC(sormqr, SORMQR) (const char *side, const char *trans, int *m, int *n, int *k, float *a, - int *lda, float *tau, float *c, int *ldc, - float *work, int *lwork, int *info); - -void - F77_FUNC(sorgbr, SORGBR) (const char *vect, int *m, int *n, int *k, float *a, int *lda, - float *tau, float *work, int *lwork, int *info); - -void - F77_FUNC(slasq5, SLASQ5) (int *i0, int *n0, float *z, int *pp, float *tau, float *dmin, - float *dmin1, float *dmin2, float *dn, float *dnm1, - float *dnm2, int *ieee); - -void - F77_FUNC(slasd8, SLASD8) (int *icompq, int *k, float *d, float *z, float *vf, float *vl, - float *difl, float *difr, int *lddifr, float *dsigma, - float *work, int *info); - -void - F77_FUNC(slascl, SLASCL) (const char *type, int *kl, int *ku, float *cfrom, float *cto, int *m, - int *n, float *a, int *lda, int *info); - -void - F77_FUNC(slarft, SLARFT) (const char *direct, const char *storev, int *n, int *k, float *v, - int *ldv, float *tau, float *t, int *ldt); - -void - F77_FUNC(slagts, SLAGTS) (int *job, int *n, float *a, float *b, float *c, float *d, - int *in, float *y, float *tol, int *info); - -void - F77_FUNC(sgesdd, SGESDD) (const char *jobz, int *m, int *n, float *a, int *lda, float *s, float *u, - int *ldu, float *vt, int *ldvt, float *work, int *lwork, - int *iwork, int *info); - -void - F77_FUNC(ssytd2, SSYTD2) (const char *uplo, int *n, float *a, int *lda, float *d, - float *e, float *tau, int *info); - -void - F77_FUNC(sormlq, SORMLQ) (const char *side, const char *trans, int *m, int *n, int *k, float *a, int *lda, - float *tau, float *c, int *ldc, float *work, int *lwork, int *info); - -void - F77_FUNC(sorg2r, SORG2R) (int *m, int *n, int *k, float *a, int *lda, float *tau, - float *work, int *info); - -void - F77_FUNC(slasq4, SLASQ4) (int *i0, int *n0, float *z, int *pp, int *n0in, float *dmin, - float *dmin1, float *dmin2, float *dn, float *dn1, - float *dn2, float *tau, int *ttype); - -void - F77_FUNC(slasd7, SLASD7) (int *icompq, int *nl, int *nr, int *sqre, int *k, float *d, float *z, - float *zw, float *vf, float *vfw, float *vl, float *vlw, - float *alpha, float *beta, float *dsigma, int *idx, int *idxp, - int *idxq, int *perm, int *givptr, int *givcol, int *ldgcol, - float *givnum, int *ldgnum, float *c, float *s, int *info); - -void - F77_FUNC(slas2, SLAS2) (float *f, float *g, float *h, float *ssmin, float *ssmax); - -void - F77_FUNC(slarfg, SLARFG) (int *n, float *alpha, float *x, int *incx, float *tau); - -void - F77_FUNC(slagtf, SLAGTF) (int *n, float *a, float *lambda, float *b, float *c, - float *tol, float *d, int *in, int *info); - -void - F77_FUNC(sgeqrf, SGEQRF) (int *m, int *n, float *a, int *lda, float *tau, - float *work, int *lwork, int *info); + /* Double precision */ + + void F77_FUNC(dbdsdc, DBDSDC)(const char* uplo, + const char* compq, + int* n, + double* d, + double* e, + double* u, + int* ldu, + double* vt, + int* ldvt, + double* q, + int* iq, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dgetf2, DGETF2)(int* m, int* n, double* a, int* lda, int* ipiv, int* info); + + void F77_FUNC(dlamrg, DLAMRG)(int* n1, int* n2, double* a, int* dtrd1, int* dtrd2, int* index); + + void F77_FUNC(dlarnv, DLARNV)(int* idist, int* iseed, int* n, double* x); + + void F77_FUNC(dlasd0, DLASD0)(int* n, + int* sqre, + double* d, + double* e, + double* u, + int* ldu, + double* vt, + int* ldvt, + int* smlsiz, + int* iwork, + double* work, + int* info); + + void F77_FUNC(dlasda, DLASDA)(int* icompq, + int* smlsiz, + int* n, + int* sqre, + double* d, + double* e, + double* u, + int* ldu, + double* vt, + int* k, + double* difl, + double* difr, + double* z, + double* poles, + int* givptr, + int* givcol, + int* ldgcol, + int* perm, + double* givnum, + double* c, + double* s, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlasq6, DLASQ6)(int* i0, + int* n0, + double* z, + int* pp, + double* dmin, + double* dmin1, + double* dmin2, + double* dn, + double* dnm1, + double* dnm2); + + void F77_FUNC(dorgl2, + DORGL2)(int* m, int* n, int* k, double* a, int* lda, double* tau, double* work, int* info); + + void F77_FUNC(dbdsqr, DBDSQR)(const char* uplo, + int* n, + int* ncvt, + int* nru, + int* ncc, + double* d, + double* e, + double* vt, + int* ldvt, + double* u, + int* ldu, + double* c, + int* ldc, + double* work, + int* info); + + void F77_FUNC(dgetrf, DGETRF)(int* m, int* n, double* a, int* lda, int* ipiv, int* info); + + void F77_FUNC(dgetri, + DGETRI)(int* n, double* a, int* lda, int* ipiv, double* work, int* lwork, int* info); + + void F77_FUNC(dgetrs, DGETRS)(const char* trans, + int* n, + int* nrhs, + double* a, + int* lda, + int* ipiv, + double* b, + int* ldb, + int* info); + + void F77_FUNC(dtrtri, + DTRTRI)(const char* uplo, const char* diag, int* n, double* a, int* lda, int* info); + + void F77_FUNC(dtrti2, + DTRTI2)(const char* uplo, const char* diag, int* n, double* a, int* lda, int* info); + + double F77_FUNC(dlange, DLANGE)(const char* norm, int* m, int* n, double* a, int* lda, double* work); + + void F77_FUNC(dlarrbx, DLARRBX)(int* n, + double* d, + double* l, + double* ld, + double* lld, + int* ifirst, + int* ilast, + double* rtol1, + double* rtol2, + int* offset, + double* w, + double* wgap, + double* werr, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlasd1, DLASD1)(int* nl, + int* nr, + int* sqre, + double* d, + double* alpha, + double* beta, + double* u, + int* ldu, + double* vt, + int* ldvt, + int* idxq, + int* iwork, + double* work, + int* info); + + void F77_FUNC(dlasdq, DLASDQ)(const char* uplo, + int* sqre, + int* n, + int* ncvt, + int* nru, + int* ncc, + double* d, + double* e, + double* vt, + int* ldvt, + double* u, + int* ldu, + double* c, + int* ldc, + double* work, + int* info); + + void F77_FUNC(dlasr, DLASR)(const char* side, + const char* pivot, + const char* direct, + int* m, + int* n, + double* c, + double* s, + double* a, + int* lda); + + void F77_FUNC(dorglq, + DORGLQ)(int* m, int* n, int* k, double* a, int* lda, double* tau, double* work, int* lwork, int* info); + + void F77_FUNC(dormtr, DORMTR)(const char* side, + const char* uplo, + const char* trans, + int* m, + int* n, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dgebd2, DGEBD2)(int* m, + int* n, + double* a, + int* lda, + double* d, + double* e, + double* tauq, + double* taup, + double* work, + int* info); + + void F77_FUNC(dlabrd, DLABRD)(int* m, + int* n, + int* nb, + double* a, + int* lda, + double* d, + double* e, + double* tauq, + double* taup, + double* x, + int* ldx, + double* y, + int* ldy); + + double F77_FUNC(dlanst, DLANST)(const char* norm, int* n, double* d, double* e); + + double F77_FUNC(dlansy, + DLANSY)(const char* norm, const char* uplo, int* n, double* a, int* lda, double* work); + + void F77_FUNC(dlarrex, DLARREX)(const char* range, + int* n, + double* vl, + double* vu, + int* il, + int* iu, + double* d, + double* e, + double* tol, + int* nsplit, + int* isplit, + int* m, + double* w, + int* iblock, + int* indexw, + double* gersch, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlasd2, DLASD2)(int* nl, + int* nr, + int* sqre, + int* k, + double* d, + double* z, + double* alpha, + double* beta, + double* u, + int* ldu, + double* vt, + int* ldvt, + double* dsigma, + double* u2, + int* ldu2, + double* vt2, + int* ldvt2, + int* idxp, + int* idx, + int* idxc, + int* idxq, + int* coltyp, + int* info); + + void F77_FUNC(dlasdt, DLASDT)(int* n, int* lvl, int* nd, int* inode, int* ndiml, int* ndimr, int* msub); + + void F77_FUNC(dlasrt, DLASRT)(const char* id, int* n, double* d, int* info); + + void F77_FUNC(dlasrt2, DLASRT2)(const char* id, int* n, double* d, int* key, int* info); + + void F77_FUNC(ilasrt2, ILASRT2)(const char* id, int* n, int* d, int* key, int* info); + + void F77_FUNC(dorgqr, + DORGQR)(int* m, int* n, int* k, double* a, int* lda, double* tau, double* work, int* lwork, int* info); + + void F77_FUNC(dstebz, DSTEBZ)(const char* range, + const char* order, + int* n, + double* vl, + double* vu, + int* il, + int* iu, + double* abstol, + double* d, + double* e, + int* m, + int* nsplit, + double* w, + int* iblock, + int* isplit, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dsteqr, DSTEQR)(const char* compz, + int* n, + double* d__, + double* e, + double* z__, + int* ldz, + double* work, + int* info); + + void F77_FUNC(dgebrd, DGEBRD)(int* m, + int* n, + double* a, + int* lda, + double* d, + double* e, + double* tauq, + double* taup, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dlacpy, + DLACPY)(const char* uplo, int* m, int* n, double* a, int* lda, double* b, int* ldb); + + double F77_FUNC(dlapy2, DLAPY2)(double* x, double* y); + + + void F77_FUNC(dlarrfx, DLARRFX)(int* n, + double* d, + double* l, + double* ld, + double* lld, + int* ifirst, + int* ilast, + double* w, + double* sigma, + double* dplus, + double* lplus, + double* work, + int* info); + + void F77_FUNC(dlasd3, DLASD3)(int* nl, + int* nr, + int* sqre, + int* k, + double* d, + double* q, + int* ldq, + double* dsigma, + double* u, + int* ldu, + double* u2, + int* ldu2, + double* vt, + int* ldvt, + double* vt2, + int* ldvt2, + int* idxc, + int* ctot, + double* z, + int* info); + + void F77_FUNC(dlaset, + DLASET)(const char* uplo, int* m, int* n, double* alpha, double* beta, double* a, int* lda); + + void F77_FUNC(dlassq, DLASSQ)(int* n, double* x, int* incx, double* scale, double* sumsq); + + void F77_FUNC(dorm2l, DORM2L)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* info); + + void F77_FUNC(dstegr, DSTEGR)(const char* jobz, + const char* range, + int* n, + double* d, + double* e, + double* vl, + double* vu, + int* il, + int* iu, + double* abstol, + int* m, + double* w, + double* z, + int* ldz, + int* isuppz, + double* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(ssteqr, + SSTEQR)(const char* compz, int* n, float* d__, float* e, float* z__, int* ldz, float* work, int* info); + + void F77_FUNC(dgelq2, DGELQ2)(int* m, int* n, double* a, int* lda, double* tau, double* work, int* info); + + void F77_FUNC(dlae2, DLAE2)(double* a, double* b, double* c, double* rt1, double* rt2); + + void F77_FUNC(dlaev2, + DLAEV2)(double* a, double* b, double* c, double* rt1, double* rt2, double* cs1, double* cs2); + + void F77_FUNC(dlar1vx, DLAR1VX)(int* n, + int* b1, + int* bn, + double* sigma, + double* d, + double* l, + double* ld, + double* lld, + double* eval, + double* gersch, + double* z, + double* ztz, + double* mingma, + int* r, + int* isuppz, + double* work); + + void F77_FUNC(dlarrvx, DLARRVX)(int* n, + double* d, + double* l, + int* isplit, + int* m, + double* w, + int* iblock, + int* indexw, + double* gersch, + double* tol, + double* z, + int* ldz, + int* isuppz, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlasd4, DLASD4)(int* n, + int* i, + double* d, + double* z, + double* delta, + double* rho, + double* sigma, + double* work, + int* info); + + void F77_FUNC(dlasq1, DLASQ1)(int* n, double* d, double* e, double* work, int* info); + + + void F77_FUNC(dlasv2, DLASV2)(double* f, + double* g, + double* h, + double* ssmin, + double* ssmax, + double* snr, + double* csr, + double* snl, + double* csl); + + void F77_FUNC(dorm2r, DORM2R)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* info); + + void F77_FUNC(dstein, DSTEIN)(int* n, + double* d, + double* e, + int* m, + double* w, + int* iblock, + int* isplit, + double* z, + int* ldz, + double* work, + int* iwork, + int* ifail, + int* info); + + void F77_FUNC(dgelqf, + DGELQF)(int* m, int* n, double* a, int* lda, double* tau, double* work, int* lwork, int* info); + + void F77_FUNC(dlaebz, DLAEBZ)(int* ijob, + int* nitmax, + int* n, + int* mmax, + int* minp, + int* nbmin, + double* abstol, + double* reltol, + double* pivmin, + double* d, + double* e, + double* e2, + int* nval, + double* ab, + double* c, + int* mout, + int* nab, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlarf, DLARF)(const char* side, + int* m, + int* n, + double* v, + int* incv, + double* tau, + double* c, + int* ldc, + double* work); + + void F77_FUNC(dlartg, DLARTG)(double* f, double* g, double* cs, double* sn, double* r); + + void F77_FUNC(dlasd5, + DLASD5)(int* i, double* d, double* z, double* delta, double* rho, double* dsigma, double* work); + + void F77_FUNC(dlasq2, DLASQ2)(int* n, double* z, int* info); + + void F77_FUNC(dlasq3, DLASQ3)(int* i0, + int* n0, + double* z, + int* pp, + double* dmin, + double* sigma, + double* desig, + double* qmax, + int* nfail, + int* iter, + int* ndiv, + int* ieee); + + void F77_FUNC(dlaswp, DLASWP)(int* n, double* a, int* lda, int* k1, int* k2, int* ipiv, int* incx); + + void F77_FUNC(dormbr, DORMBR)(const char* vect, + const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dsterf, DSTERF)(int* n, double* d, double* e, int* info); + + void F77_FUNC(dgeqr2, DGEQR2)(int* m, int* n, double* a, int* lda, double* tau, double* work, int* info); + + void F77_FUNC(dlaed6, DLAED6)(int* kniter, + int* orgati, + double* rho, + double* d, + double* z, + double* finit, + double* tau, + int* info); + + void F77_FUNC(dlarfb, DLARFB)(const char* side, + const char* trans, + const char* direct, + const char* storev, + int* m, + int* n, + int* k, + double* v, + int* ldv, + double* t, + int* ldt, + double* c, + int* ldc, + double* work, + int* ldwork); + + void F77_FUNC(dlaruv, DLARUV)(int* iseed, int* n, double* x); + + void F77_FUNC(dlasd6, DLASD6)(int* icompq, + int* nl, + int* nr, + int* sqre, + double* d, + double* vf, + double* vl, + double* alpha, + double* beta, + int* idxq, + int* perm, + int* givptr, + int* givcol, + int* ldgcol, + double* givnum, + int* ldgnum, + double* poles, + double* difl, + double* difr, + double* z, + int* k, + double* c, + double* s, + double* work, + int* iwork, + int* info); + + void F77_FUNC(dlatrd, DLATRD)(const char* uplo, + int* n, + int* nb, + double* a, + int* lda, + double* e, + double* tau, + double* w, + int* ldw); + + void F77_FUNC(dorml2, DORML2)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* info); + + void F77_FUNC(dstevr, DSTEVR)(const char* jobz, + const char* range, + int* n, + double* d, + double* e, + double* vl, + double* vu, + int* il, + int* iu, + double* abstol, + int* m, + double* w, + double* z, + int* ldz, + int* isuppz, + double* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(dsytrd, DSYTRD)(const char* uplo, + int* n, + double* a, + int* lda, + double* d, + double* e, + double* tau, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dsyevr, DSYEVR)(const char* jobz, + const char* range, + const char* uplo, + int* n, + double* a, + int* lda, + double* vl, + double* vu, + int* il, + int* iu, + double* abstol, + int* m, + double* w, + double* z__, + int* ldz, + int* isuppz, + double* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(dormql, DORMQL)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dormqr, DORMQR)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dorgbr, DORGBR)(const char* vect, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dlasq5, DLASQ5)(int* i0, + int* n0, + double* z, + int* pp, + double* tau, + double* dmin, + double* dmin1, + double* dmin2, + double* dn, + double* dnm1, + double* dnm2, + int* ieee); + + void F77_FUNC(dlasd8, DLASD8)(int* icompq, + int* k, + double* d, + double* z, + double* vf, + double* vl, + double* difl, + double* difr, + int* lddifr, + double* dsigma, + double* work, + int* info); + + void F77_FUNC(dlascl, DLASCL)(const char* type, + int* kl, + int* ku, + double* cfrom, + double* cto, + int* m, + int* n, + double* a, + int* lda, + int* info); + + void F77_FUNC(dlarft, DLARFT)(const char* direct, + const char* storev, + int* n, + int* k, + double* v, + int* ldv, + double* tau, + double* t, + int* ldt); + + void F77_FUNC(dlagts, DLAGTS)(int* job, + int* n, + double* a, + double* b, + double* c, + double* d, + int* in, + double* y, + double* tol, + int* info); + + void F77_FUNC(dgesdd, DGESDD)(const char* jobz, + int* m, + int* n, + double* a, + int* lda, + double* s, + double* u, + int* ldu, + double* vt, + int* ldvt, + double* work, + int* lwork, + int* iwork, + int* info); + + void F77_FUNC(dsytd2, + DSYTD2)(const char* uplo, int* n, double* a, int* lda, double* d, double* e, double* tau, int* info); + + void F77_FUNC(dormlq, DORMLQ)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + double* a, + int* lda, + double* tau, + double* c, + int* ldc, + double* work, + int* lwork, + int* info); + + void F77_FUNC(dorg2r, + DORG2R)(int* m, int* n, int* k, double* a, int* lda, double* tau, double* work, int* info); + + void F77_FUNC(dlasq4, DLASQ4)(int* i0, + int* n0, + double* z, + int* pp, + int* n0in, + double* dmin, + double* dmin1, + double* dmin2, + double* dn, + double* dn1, + double* dn2, + double* tau, + int* ttype); + + void F77_FUNC(dlasd7, DLASD7)(int* icompq, + int* nl, + int* nr, + int* sqre, + int* k, + double* d, + double* z, + double* zw, + double* vf, + double* vfw, + double* vl, + double* vlw, + double* alpha, + double* beta, + double* dsigma, + int* idx, + int* idxp, + int* idxq, + int* perm, + int* givptr, + int* givcol, + int* ldgcol, + double* givnum, + int* ldgnum, + double* c, + double* s, + int* info); + + void F77_FUNC(dlas2, DLAS2)(double* f, double* g, double* h, double* ssmin, double* ssmax); + + void F77_FUNC(dlarfg, DLARFG)(int* n, double* alpha, double* x, int* incx, double* tau); + + void F77_FUNC(dlagtf, DLAGTF)(int* n, + double* a, + double* lambda, + double* b, + double* c, + double* tol, + double* d, + int* in, + int* info); + + void F77_FUNC(dgeqrf, + DGEQRF)(int* m, int* n, double* a, int* lda, double* tau, double* work, int* lwork, int* info); + + + /* Single precision */ + + void F77_FUNC(sbdsdc, SBDSDC)(const char* uplo, + const char* compq, + int* n, + float* d, + float* e, + float* u, + int* ldu, + float* vt, + int* ldvt, + float* q, + int* iq, + float* work, + int* iwork, + int* info); + + void F77_FUNC(sgetf2, SGETF2)(int* m, int* n, float* a, int* lda, int* ipiv, int* info); + + void F77_FUNC(slamrg, SLAMRG)(int* n1, int* n2, float* a, int* dtrd1, int* dtrd2, int* index); + + void F77_FUNC(slarnv, SLARNV)(int* idist, int* iseed, int* n, float* x); + + void F77_FUNC(slasd0, SLASD0)(int* n, + int* sqre, + float* d, + float* e, + float* u, + int* ldu, + float* vt, + int* ldvt, + int* smlsiz, + int* iwork, + float* work, + int* info); + + void F77_FUNC(slasda, SLASDA)(int* icompq, + int* smlsiz, + int* n, + int* sqre, + float* d, + float* e, + float* u, + int* ldu, + float* vt, + int* k, + float* difl, + float* difr, + float* z, + float* poles, + int* givptr, + int* givcol, + int* ldgcol, + int* perm, + float* givnum, + float* c, + float* s, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slasq6, SLASQ6)(int* i0, + int* n0, + float* z, + int* pp, + float* dmin, + float* dmin1, + float* dmin2, + float* dn, + float* dnm1, + float* dnm2); + + void F77_FUNC(sorgl2, + SORGL2)(int* m, int* n, int* k, float* a, int* lda, float* tau, float* work, int* info); + + void F77_FUNC(sbdsqr, SBDSQR)(const char* uplo, + int* n, + int* ncvt, + int* nru, + int* ncc, + float* d, + float* e, + float* vt, + int* ldvt, + float* u, + int* ldu, + float* c, + int* ldc, + float* work, + int* info); + + void F77_FUNC(sgetrf, SGETRF)(int* m, int* n, float* a, int* lda, int* ipiv, int* info); + + void F77_FUNC(sgetri, SGETRI)(int* n, float* a, int* lda, int* ipiv, float* work, int* lwork, int* info); + + void F77_FUNC(sgetrs, SGETRS)(const char* trans, + int* n, + int* nrhs, + float* a, + int* lda, + int* ipiv, + float* b, + int* ldb, + int* info); + + void F77_FUNC(strtri, STRTRI)(const char* uplo, const char* diag, int* n, float* a, int* lda, int* info); + + void F77_FUNC(strti2, STRTI2)(const char* uplo, const char* diag, int* n, float* a, int* lda, int* info); + + float F77_FUNC(slange, SLANGE)(const char* norm, int* m, int* n, float* a, int* lda, float* work); + + void F77_FUNC(slarrbx, SLARRBX)(int* n, + float* d, + float* l, + float* ld, + float* lld, + int* ifirst, + int* ilast, + float* rtol1, + float* rtol2, + int* offset, + float* w, + float* wgap, + float* werr, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slasd1, SLASD1)(int* nl, + int* nr, + int* sqre, + float* d, + float* alpha, + float* beta, + float* u, + int* ldu, + float* vt, + int* ldvt, + int* idxq, + int* iwork, + float* work, + int* info); + + void F77_FUNC(slasdq, SLASDQ)(const char* uplo, + int* sqre, + int* n, + int* ncvt, + int* nru, + int* ncc, + float* d, + float* e, + float* vt, + int* ldvt, + float* u, + int* ldu, + float* c, + int* ldc, + float* work, + int* info); + + void F77_FUNC(slasr, SLASR)(const char* side, + const char* pivot, + const char* direct, + int* m, + int* n, + float* c, + float* s, + float* a, + int* lda); + + void F77_FUNC(sorglq, + SORGLQ)(int* m, int* n, int* k, float* a, int* lda, float* tau, float* work, int* lwork, int* info); + + void F77_FUNC(sormtr, SORMTR)(const char* side, + const char* uplo, + const char* trans, + int* m, + int* n, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* lwork, + int* info); + + void F77_FUNC(sgebd2, SGEBD2)(int* m, + int* n, + float* a, + int* lda, + float* d, + float* e, + float* tauq, + float* taup, + float* work, + int* info); + + void F77_FUNC(slabrd, SLABRD)(int* m, + int* n, + int* nb, + float* a, + int* lda, + float* d, + float* e, + float* tauq, + float* taup, + float* x, + int* ldx, + float* y, + int* ldy); + + float F77_FUNC(slanst, SLANST)(const char* norm, int* n, float* d, float* e); + + float F77_FUNC(slansy, + SLANSY)(const char* norm, const char* uplo, int* n, float* a, int* lda, float* work); + + void F77_FUNC(slarrex, SLARREX)(const char* range, + int* n, + float* vl, + float* vu, + int* il, + int* iu, + float* d, + float* e, + float* tol, + int* nsplit, + int* isplit, + int* m, + float* w, + int* iblock, + int* indexw, + float* gersch, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slasd2, SLASD2)(int* nl, + int* nr, + int* sqre, + int* k, + float* d, + float* z, + float* alpha, + float* beta, + float* u, + int* ldu, + float* vt, + int* ldvt, + float* dsigma, + float* u2, + int* ldu2, + float* vt2, + int* ldvt2, + int* idxp, + int* idx, + int* idxc, + int* idxq, + int* coltyp, + int* info); + + void F77_FUNC(slasdt, SLASDT)(int* n, int* lvl, int* nd, int* inode, int* ndiml, int* ndimr, int* msub); + + void F77_FUNC(slasrt, SLASRT)(const char* id, int* n, float* d, int* info); + + void F77_FUNC(slasrt2, SLASRT2)(const char* id, int* n, float* d, int* key, int* info); + + void F77_FUNC(sorgqr, + SORGQR)(int* m, int* n, int* k, float* a, int* lda, float* tau, float* work, int* lwork, int* info); + + void F77_FUNC(sstebz, SSTEBZ)(const char* range, + const char* order, + int* n, + float* vl, + float* vu, + int* il, + int* iu, + float* abstol, + float* d, + float* e, + int* m, + int* nsplit, + float* w, + int* iblock, + int* isplit, + float* work, + int* iwork, + int* info); + + void F77_FUNC(sgebrd, SGEBRD)(int* m, + int* n, + float* a, + int* lda, + float* d, + float* e, + float* tauq, + float* taup, + float* work, + int* lwork, + int* info); + + void F77_FUNC(slacpy, SLACPY)(const char* uplo, int* m, int* n, float* a, int* lda, float* b, int* ldb); + + float F77_FUNC(slapy2, SLAPY2)(float* x, float* y); + + void F77_FUNC(slarrfx, SLARRFX)(int* n, + float* d, + float* l, + float* ld, + float* lld, + int* ifirst, + int* ilast, + float* w, + float* sigma, + float* dplus, + float* lplus, + float* work, + int* info); + + void F77_FUNC(slasd3, SLASD3)(int* nl, + int* nr, + int* sqre, + int* k, + float* d, + float* q, + int* ldq, + float* dsigma, + float* u, + int* ldu, + float* u2, + int* ldu2, + float* vt, + int* ldvt, + float* vt2, + int* ldvt2, + int* idxc, + int* ctot, + float* z, + int* info); + + void F77_FUNC(slaset, + SLASET)(const char* uplo, int* m, int* n, float* alpha, float* beta, float* a, int* lda); + + void F77_FUNC(slassq, SLASSQ)(int* n, float* x, int* incx, float* scale, float* sumsq); + + void F77_FUNC(sorm2l, SORM2L)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* info); + + void F77_FUNC(sstegr, SSTEGR)(const char* jobz, + const char* range, + int* n, + float* d, + float* e, + float* vl, + float* vu, + int* il, + int* iu, + float* abstol, + int* m, + float* w, + float* z, + int* ldz, + int* isuppz, + float* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(sgelq2, SGELQ2)(int* m, int* n, float* a, int* lda, float* tau, float* work, int* info); + + void F77_FUNC(slae2, SLAE2)(float* a, float* b, float* c, float* rt1, float* rt2); + + void F77_FUNC(slaev2, + SLAEV2)(float* a, float* b, float* c, float* rt1, float* rt2, float* cs1, float* cs2); + + void F77_FUNC(slar1vx, SLAR1VX)(int* n, + int* b1, + int* bn, + float* sigma, + float* d, + float* l, + float* ld, + float* lld, + float* eval, + float* gersch, + float* z, + float* ztz, + float* mingma, + int* r, + int* isuppz, + float* work); + + void F77_FUNC(slarrvx, SLARRVX)(int* n, + float* d, + float* l, + int* isplit, + int* m, + float* w, + int* iblock, + int* indexw, + float* gersch, + float* tol, + float* z, + int* ldz, + int* isuppz, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slasd4, SLASD4)(int* n, + int* i, + float* d, + float* z, + float* delta, + float* rho, + float* sigma, + float* work, + int* info); + + void F77_FUNC(slasq1, SLASQ1)(int* n, float* d, float* e, float* work, int* info); + + + void F77_FUNC(slasv2, SLASV2)(float* f, + float* g, + float* h, + float* ssmin, + float* ssmax, + float* snr, + float* csr, + float* snl, + float* csl); + + void F77_FUNC(sorm2r, SORM2R)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* info); + + void F77_FUNC(sstein, SSTEIN)(int* n, + float* d, + float* e, + int* m, + float* w, + int* iblock, + int* isplit, + float* z, + int* ldz, + float* work, + int* iwork, + int* ifail, + int* info); + + void F77_FUNC(sgelqf, + SGELQF)(int* m, int* n, float* a, int* lda, float* tau, float* work, int* lwork, int* info); + + void F77_FUNC(slaebz, SLAEBZ)(int* ijob, + int* nitmax, + int* n, + int* mmax, + int* minp, + int* nbmin, + float* abstol, + float* reltol, + float* pivmin, + float* d, + float* e, + float* e2, + int* nval, + float* ab, + float* c, + int* mout, + int* nab, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slarf, + SLARF)(const char* side, int* m, int* n, float* v, int* incv, float* tau, float* c, int* ldc, float* work); + + void F77_FUNC(slartg, SLARTG)(float* f, float* g, float* cs, float* sn, float* r); + + void F77_FUNC(slasd5, + SLASD5)(int* i, float* d, float* z, float* delta, float* rho, float* dsigma, float* work); + + void F77_FUNC(slasq2, SLASQ2)(int* n, float* z, int* info); + + void F77_FUNC(slasq3, SLASQ3)(int* i0, + int* n0, + float* z, + int* pp, + float* dmin, + float* sigma, + float* desig, + float* qmax, + int* nfail, + int* iter, + int* ndiv, + int* ieee); + + void F77_FUNC(slaswp, SLASWP)(int* n, float* a, int* lda, int* k1, int* k2, int* ipiv, int* incx); + + void F77_FUNC(sormbr, SORMBR)(const char* vect, + const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* lwork, + int* info); + + void F77_FUNC(ssterf, SSTERF)(int* n, float* d, float* e, int* info); + + void F77_FUNC(sgeqr2, SGEQR2)(int* m, int* n, float* a, int* lda, float* tau, float* work, int* info); + + void F77_FUNC(slaed6, + SLAED6)(int* kniter, int* orgati, float* rho, float* d, float* z, float* finit, float* tau, int* info); + + void F77_FUNC(slarfb, SLARFB)(const char* side, + const char* trans, + const char* direct, + const char* storev, + int* m, + int* n, + int* k, + float* v, + int* ldv, + float* t, + int* ldt, + float* c, + int* ldc, + float* work, + int* ldwork); + + void F77_FUNC(slaruv, SLARUV)(int* iseed, int* n, float* x); + + void F77_FUNC(slasd6, SLASD6)(int* icompq, + int* nl, + int* nr, + int* sqre, + float* d, + float* vf, + float* vl, + float* alpha, + float* beta, + int* idxq, + int* perm, + int* givptr, + int* givcol, + int* ldgcol, + float* givnum, + int* ldgnum, + float* poles, + float* difl, + float* difr, + float* z, + int* k, + float* c, + float* s, + float* work, + int* iwork, + int* info); + + void F77_FUNC(slatrd, + SLATRD)(const char* uplo, int* n, int* nb, float* a, int* lda, float* e, float* tau, float* w, int* ldw); + + void F77_FUNC(sorml2, SORML2)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* info); + + void F77_FUNC(sstevr, SSTEVR)(const char* jobz, + const char* range, + int* n, + float* d, + float* e, + float* vl, + float* vu, + int* il, + int* iu, + float* abstol, + int* m, + float* w, + float* z, + int* ldz, + int* isuppz, + float* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(ssytrd, SSYTRD)(const char* uplo, + int* n, + float* a, + int* lda, + float* d, + float* e, + float* tau, + float* work, + int* lwork, + int* info); + + void F77_FUNC(ssyevr, SSYEVR)(const char* jobz, + const char* range, + const char* uplo, + int* n, + float* a, + int* lda, + float* vl, + float* vu, + int* il, + int* iu, + float* abstol, + int* m, + float* w, + float* z__, + int* ldz, + int* isuppz, + float* work, + int* lwork, + int* iwork, + int* liwork, + int* info); + + void F77_FUNC(sormql, SORMQL)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* lwork, + int* info); + + void F77_FUNC(sormqr, SORMQR)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* lwork, + int* info); + + void F77_FUNC(sorgbr, SORGBR)(const char* vect, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* work, + int* lwork, + int* info); + + void F77_FUNC(slasq5, SLASQ5)(int* i0, + int* n0, + float* z, + int* pp, + float* tau, + float* dmin, + float* dmin1, + float* dmin2, + float* dn, + float* dnm1, + float* dnm2, + int* ieee); + + void F77_FUNC(slasd8, SLASD8)(int* icompq, + int* k, + float* d, + float* z, + float* vf, + float* vl, + float* difl, + float* difr, + int* lddifr, + float* dsigma, + float* work, + int* info); + + void F77_FUNC(slascl, SLASCL)(const char* type, + int* kl, + int* ku, + float* cfrom, + float* cto, + int* m, + int* n, + float* a, + int* lda, + int* info); + + void F77_FUNC(slarft, SLARFT)(const char* direct, + const char* storev, + int* n, + int* k, + float* v, + int* ldv, + float* tau, + float* t, + int* ldt); + + void F77_FUNC(slagts, + SLAGTS)(int* job, int* n, float* a, float* b, float* c, float* d, int* in, float* y, float* tol, int* info); + + void F77_FUNC(sgesdd, SGESDD)(const char* jobz, + int* m, + int* n, + float* a, + int* lda, + float* s, + float* u, + int* ldu, + float* vt, + int* ldvt, + float* work, + int* lwork, + int* iwork, + int* info); + + void F77_FUNC(ssytd2, + SSYTD2)(const char* uplo, int* n, float* a, int* lda, float* d, float* e, float* tau, int* info); + + void F77_FUNC(sormlq, SORMLQ)(const char* side, + const char* trans, + int* m, + int* n, + int* k, + float* a, + int* lda, + float* tau, + float* c, + int* ldc, + float* work, + int* lwork, + int* info); + + void F77_FUNC(sorg2r, + SORG2R)(int* m, int* n, int* k, float* a, int* lda, float* tau, float* work, int* info); + + void F77_FUNC(slasq4, SLASQ4)(int* i0, + int* n0, + float* z, + int* pp, + int* n0in, + float* dmin, + float* dmin1, + float* dmin2, + float* dn, + float* dn1, + float* dn2, + float* tau, + int* ttype); + + void F77_FUNC(slasd7, SLASD7)(int* icompq, + int* nl, + int* nr, + int* sqre, + int* k, + float* d, + float* z, + float* zw, + float* vf, + float* vfw, + float* vl, + float* vlw, + float* alpha, + float* beta, + float* dsigma, + int* idx, + int* idxp, + int* idxq, + int* perm, + int* givptr, + int* givcol, + int* ldgcol, + float* givnum, + int* ldgnum, + float* c, + float* s, + int* info); + + void F77_FUNC(slas2, SLAS2)(float* f, float* g, float* h, float* ssmin, float* ssmax); + + void F77_FUNC(slarfg, SLARFG)(int* n, float* alpha, float* x, int* incx, float* tau); + + void F77_FUNC(slagtf, + SLAGTF)(int* n, float* a, float* lambda, float* b, float* c, float* tol, float* d, int* in, int* info); + + void F77_FUNC(sgeqrf, + SGEQRF)(int* m, int* n, float* a, int* lda, float* tau, float* work, int* lwork, int* info); #ifdef __cplusplus diff --git a/src/gromacs/linearalgebra/matrix.cpp b/src/gromacs/linearalgebra/matrix.cpp index bd1b9510a7..0116144447 100644 --- a/src/gromacs/linearalgebra/matrix.cpp +++ b/src/gromacs/linearalgebra/matrix.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,38 +47,37 @@ #include "gmx_lapack.h" -double **alloc_matrix(int n, int m) +double** alloc_matrix(int n, int m) { - double **ptr; + double** ptr; int i; /* There's always time for more pointer arithmetic! */ /* This is necessary in order to be able to work with LAPACK */ snew(ptr, n); - snew(ptr[0], n*m); + snew(ptr[0], n * m); for (i = 1; (i < n); i++) { - ptr[i] = ptr[i-1]+m; + ptr[i] = ptr[i - 1] + m; } return ptr; } -void free_matrix(double **a) +void free_matrix(double** a) { sfree(a[0]); sfree(a); } #define DEBUG_MATRIX -void matrix_multiply(FILE *fp, int n, int m, double **x, double **y, double **z) +void matrix_multiply(FILE* fp, int n, int m, double** x, double** y, double** z) { int i, j, k; #ifdef DEBUG_MATRIX if (fp) { - fprintf(fp, "Multiplying %d x %d matrix with a %d x %d matrix\n", - n, m, m, n); + fprintf(fp, "Multiplying %d x %d matrix with a %d x %d matrix\n", n, m, m, n); } if (fp) { @@ -99,13 +98,13 @@ void matrix_multiply(FILE *fp, int n, int m, double **x, double **y, double **z) z[i][j] = 0; for (k = 0; (k < n); k++) { - z[i][j] += x[k][i]*y[j][k]; + z[i][j] += x[k][i] * y[j][k]; } } } } -static void dump_matrix(FILE *fp, const char *title, int n, double **a) +static void dump_matrix(FILE* fp, const char* title, int n, double** a) { double d = 1; int i, j; @@ -113,7 +112,7 @@ static void dump_matrix(FILE *fp, const char *title, int n, double **a) fprintf(fp, "%s\n", title); for (i = 0; (i < n); i++) { - d = d*a[i][i]; + d = d * a[i][i]; for (j = 0; (j < n); j++) { fprintf(fp, " %8.2f", a[i][j]); @@ -123,7 +122,7 @@ static void dump_matrix(FILE *fp, const char *title, int n, double **a) fprintf(fp, "Prod a[i][i] = %g\n", d); } -int matrix_invert(FILE *fp, int n, double **a) +int matrix_invert(FILE* fp, int n, double** a) { int i, j, m, lda, *ipiv, lwork, info; double **test = nullptr, **id, *work; @@ -144,11 +143,11 @@ int matrix_invert(FILE *fp, int n, double **a) } #endif snew(ipiv, n); - lwork = n*n; + lwork = n * n; snew(work, lwork); - m = lda = n; - info = 0; - F77_FUNC(dgetrf, DGETRF) (&n, &m, a[0], &lda, ipiv, &info); + m = lda = n; + info = 0; + F77_FUNC(dgetrf, DGETRF)(&n, &m, a[0], &lda, ipiv, &info); #ifdef DEBUG_MATRIX if (fp) { @@ -159,7 +158,7 @@ int matrix_invert(FILE *fp, int n, double **a) { return info; } - F77_FUNC(dgetri, DGETRI) (&n, a[0], &lda, ipiv, work, &lwork, &info); + F77_FUNC(dgetri, DGETRI)(&n, a[0], &lda, ipiv, work, &lwork, &info); #ifdef DEBUG_MATRIX if (fp) { @@ -187,8 +186,7 @@ int matrix_invert(FILE *fp, int n, double **a) return 0; } -double multi_regression(FILE *fp, int nrow, double *y, int ncol, - double **xx, double *a0) +double multi_regression(FILE* fp, int nrow, double* y, int ncol, double** xx, double* a0) { int row, i, j; double ax, chi2, **a, **at, **ata, *atx; @@ -206,8 +204,11 @@ double multi_regression(FILE *fp, int nrow, double *y, int ncol, matrix_multiply(fp, nrow, ncol, a, at, ata); if ((row = matrix_invert(fp, ncol, ata)) != 0) { - gmx_fatal(FARGS, "Matrix inversion failed. Incorrect row = %d.\nThis probably indicates that you do not have sufficient data points, or that some parameters are linearly dependent.", - row); + gmx_fatal( + FARGS, + "Matrix inversion failed. Incorrect row = %d.\nThis probably indicates that you do " + "not have sufficient data points, or that some parameters are linearly dependent.", + row); } snew(atx, ncol); @@ -216,7 +217,7 @@ double multi_regression(FILE *fp, int nrow, double *y, int ncol, atx[i] = 0; for (j = 0; (j < nrow); j++) { - atx[i] += at[i][j]*y[j]; + atx[i] += at[i][j] * y[j]; } } for (i = 0; (i < ncol); i++) @@ -224,7 +225,7 @@ double multi_regression(FILE *fp, int nrow, double *y, int ncol, a0[i] = 0; for (j = 0; (j < ncol); j++) { - a0[i] += ata[i][j]*atx[j]; + a0[i] += ata[i][j] * atx[j]; } } chi2 = 0; @@ -233,7 +234,7 @@ double multi_regression(FILE *fp, int nrow, double *y, int ncol, ax = 0; for (i = 0; (i < ncol); i++) { - ax += a0[i]*a[j][i]; + ax += a0[i] * a[j][i]; } chi2 += (y[j] - ax) * (y[j] - ax); } diff --git a/src/gromacs/linearalgebra/matrix.h b/src/gromacs/linearalgebra/matrix.h index 07ba1d92c9..43b37ca943 100644 --- a/src/gromacs/linearalgebra/matrix.h +++ b/src/gromacs/linearalgebra/matrix.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2013,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,17 +39,16 @@ #include -double **alloc_matrix(int n, int m); +double** alloc_matrix(int n, int m); -void free_matrix(double **a); +void free_matrix(double** a); -void matrix_multiply(FILE *fp, int n, int m, double **x, double **y, double **z); +void matrix_multiply(FILE* fp, int n, int m, double** x, double** y, double** z); /* Return 0 if OK or row number where inversion failed otherwise. */ -int matrix_invert(FILE *fp, int n, double **a); +int matrix_invert(FILE* fp, int n, double** a); -double multi_regression(FILE *fp, int ny, double *y, - int nx, double **xx, double *a0); +double multi_regression(FILE* fp, int ny, double* y, int nx, double** xx, double* a0); /* Perform a regression analysis to fit * y' = a0[0] xx[0] + a0[1] xx[1] ... + a0[nx-1] xx[nx-1] * with ny data points in each vector. diff --git a/src/gromacs/linearalgebra/nrjac.cpp b/src/gromacs/linearalgebra/nrjac.cpp index ade866903e..638d70b394 100644 --- a/src/gromacs/linearalgebra/nrjac.cpp +++ b/src/gromacs/linearalgebra/nrjac.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,8 +44,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static inline -void do_rotate(double **a, int i, int j, int k, int l, double tau, double s) +static inline void do_rotate(double** a, int i, int j, int k, int l, double tau, double s) { double g, h; g = a[i][j]; @@ -54,7 +53,7 @@ void do_rotate(double **a, int i, int j, int k, int l, double tau, double s) a[k][l] = h + s * (g - h * tau); } -void jacobi(double **a, int n, double d[], double **v, int *nrot) +void jacobi(double** a, int n, double d[], double** v, int* nrot) { int j, i; int iq, ip; @@ -73,15 +72,15 @@ void jacobi(double **a, int n, double d[], double **v, int *nrot) for (ip = 0; ip < n; ip++) { b[ip] = d[ip] = a[ip][ip]; - z[ip] = 0.0; + z[ip] = 0.0; } *nrot = 0; for (i = 1; i <= 50; i++) { sm = 0.0; - for (ip = 0; ip < n-1; ip++) + for (ip = 0; ip < n - 1; ip++) { - for (iq = ip+1; iq < n; iq++) + for (iq = ip + 1; iq < n; iq++) { sm += std::abs(a[ip][iq]); } @@ -94,56 +93,56 @@ void jacobi(double **a, int n, double d[], double **v, int *nrot) } if (i < 4) { - tresh = 0.2*sm/(n*n); + tresh = 0.2 * sm / (n * n); } else { tresh = 0.0; } - for (ip = 0; ip < n-1; ip++) + for (ip = 0; ip < n - 1; ip++) { - for (iq = ip+1; iq < n; iq++) + for (iq = ip + 1; iq < n; iq++) { - g = 100.0*std::abs(a[ip][iq]); - if (i > 4 && std::abs(d[ip])+g == std::abs(d[ip]) - && std::abs(d[iq])+g == std::abs(d[iq])) + g = 100.0 * std::abs(a[ip][iq]); + if (i > 4 && std::abs(d[ip]) + g == std::abs(d[ip]) + && std::abs(d[iq]) + g == std::abs(d[iq])) { a[ip][iq] = 0.0; } else if (std::abs(a[ip][iq]) > tresh) { - h = d[iq]-d[ip]; - if (std::abs(h)+g == std::abs(h)) + h = d[iq] - d[ip]; + if (std::abs(h) + g == std::abs(h)) { - t = (a[ip][iq])/h; + t = (a[ip][iq]) / h; } else { - theta = 0.5*h/(a[ip][iq]); - t = 1.0/(std::abs(theta)+std::sqrt(1.0+theta*theta)); + theta = 0.5 * h / (a[ip][iq]); + t = 1.0 / (std::abs(theta) + std::sqrt(1.0 + theta * theta)); if (theta < 0.0) { t = -t; } } - c = 1.0/std::sqrt(1+t*t); - s = t*c; - tau = s/(1.0+c); - h = t*a[ip][iq]; - z[ip] -= h; - z[iq] += h; - d[ip] -= h; - d[iq] += h; + c = 1.0 / std::sqrt(1 + t * t); + s = t * c; + tau = s / (1.0 + c); + h = t * a[ip][iq]; + z[ip] -= h; + z[iq] += h; + d[ip] -= h; + d[iq] += h; a[ip][iq] = 0.0; for (j = 0; j < ip; j++) { do_rotate(a, j, ip, j, iq, tau, s); } - for (j = ip+1; j < iq; j++) + for (j = ip + 1; j < iq; j++) { do_rotate(a, ip, j, j, iq, tau, s); } - for (j = iq+1; j < n; j++) + for (j = iq + 1; j < n; j++) { do_rotate(a, ip, j, iq, j, tau, s); } @@ -157,15 +156,15 @@ void jacobi(double **a, int n, double d[], double **v, int *nrot) } for (ip = 0; ip < n; ip++) { - b[ip] += z[ip]; - d[ip] = b[ip]; - z[ip] = 0.0; + b[ip] += z[ip]; + d[ip] = b[ip]; + z[ip] = 0.0; } } gmx_fatal(FARGS, "Error: Too many iterations in routine JACOBI\n"); } -int m_inv_gen(real *m, int n, real *minv) +int m_inv_gen(real* m, int n, real* minv) { double **md, **v, *eig, tol, s; int nzero, i, j, k, nrot; @@ -185,7 +184,7 @@ int m_inv_gen(real *m, int n, real *minv) { for (j = 0; j < n; j++) { - md[i][j] = m[i*n + j]; + md[i][j] = m[i * n + j]; } } @@ -194,7 +193,7 @@ int m_inv_gen(real *m, int n, real *minv) { tol += std::abs(md[i][i]); } - tol = 1e-6*tol/n; + tol = 1e-6 * tol / n; jacobi(md, n, eig, v, &nrot); @@ -208,7 +207,7 @@ int m_inv_gen(real *m, int n, real *minv) } else { - eig[i] = 1.0/eig[i]; + eig[i] = 1.0 / eig[i]; } } @@ -219,9 +218,9 @@ int m_inv_gen(real *m, int n, real *minv) s = 0; for (k = 0; k < n; k++) { - s += eig[k]*v[i][k]*v[j][k]; + s += eig[k] * v[i][k] * v[j][k]; } - minv[i*n + j] = s; + minv[i * n + j] = s; } } diff --git a/src/gromacs/linearalgebra/nrjac.h b/src/gromacs/linearalgebra/nrjac.h index f39df0e078..460c383fc2 100644 --- a/src/gromacs/linearalgebra/nrjac.h +++ b/src/gromacs/linearalgebra/nrjac.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,7 +39,7 @@ #include "gromacs/utility/real.h" -void jacobi(double **a, int n, double d[], double **v, int *nrot); +void jacobi(double** a, int n, double d[], double** v, int* nrot); /* * real **omega = input matrix a[0..n-1][0..n-1] must be symmetric * int natoms = number of rows and columns @@ -49,7 +49,7 @@ void jacobi(double **a, int n, double d[], double **v, int *nrot); * int *irot = number of jacobi rotations */ -int m_inv_gen(real *m, int n, real *minv); +int m_inv_gen(real* m, int n, real* minv); /* Produces minv, a generalized inverse of m, both stored as linear arrays. * Inversion is done via diagonalization, * eigenvalues smaller than 1e-6 times the average diagonal element diff --git a/src/gromacs/linearalgebra/sparsematrix.cpp b/src/gromacs/linearalgebra/sparsematrix.cpp index 79ec5912f0..bc6081b406 100644 --- a/src/gromacs/linearalgebra/sparsematrix.cpp +++ b/src/gromacs/linearalgebra/sparsematrix.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,11 +45,10 @@ #include "gromacs/utility/smalloc.h" -gmx_sparsematrix_t * -gmx_sparsematrix_init(int nrow) +gmx_sparsematrix_t* gmx_sparsematrix_init(int nrow) { int i; - gmx_sparsematrix_t *A; + gmx_sparsematrix_t* A; snew(A, 1); @@ -60,17 +59,15 @@ gmx_sparsematrix_init(int nrow) for (i = 0; i < nrow; i++) { - A->ndata[i] = 0; - A->nalloc[i] = 0; - A->data[i] = nullptr; + A->ndata[i] = 0; + A->nalloc[i] = 0; + A->data[i] = nullptr; } return A; } - -void -gmx_sparsematrix_destroy(gmx_sparsematrix_t * A) +void gmx_sparsematrix_destroy(gmx_sparsematrix_t* A) { int i; @@ -91,10 +88,7 @@ gmx_sparsematrix_destroy(gmx_sparsematrix_t * A) } - -void -gmx_sparsematrix_print(FILE * stream, - gmx_sparsematrix_t * A) +void gmx_sparsematrix_print(FILE* stream, gmx_sparsematrix_t* A) { int i, j, k; @@ -125,16 +119,12 @@ gmx_sparsematrix_print(FILE * stream, } fprintf(stream, "\n"); } - } -real -gmx_sparsematrix_value(gmx_sparsematrix_t * A, - int row, - int col) +real gmx_sparsematrix_value(gmx_sparsematrix_t* A, int row, int col) { - gmx_bool found = FALSE; + gmx_bool found = FALSE; int i; real value; @@ -157,14 +147,9 @@ gmx_sparsematrix_value(gmx_sparsematrix_t * A, } - -void -gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, - int row, - int col, - real difference) +void gmx_sparsematrix_increment_value(gmx_sparsematrix_t* A, int row, int col, real difference) { - gmx_bool found = FALSE; + gmx_bool found = FALSE; int i; assert(row < A->nrow); @@ -174,7 +159,7 @@ gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, { if (A->data[row][i].col == col) { - found = TRUE; + found = TRUE; A->data[row][i].value += difference; } } @@ -195,7 +180,7 @@ gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, srenew(A->data[row], A->nalloc[row]); } } - A->data[row][A->ndata[row]].col = col; + A->data[row][A->ndata[row]].col = col; /* Previous value was 0.0 */ A->data[row][A->ndata[row]].value = difference; A->ndata[row]++; @@ -208,11 +193,10 @@ gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, * The data entries to compare are of the type gmx_sparsematrix_entry_t, but quicksort * uses void pointers as arguments, so we cast them back internally. */ -static int -compare_columns(const void *v1, const void *v2) +static int compare_columns(const void* v1, const void* v2) { - int c1 = ((gmx_sparsematrix_entry_t *)v1)->col; - int c2 = ((gmx_sparsematrix_entry_t *)v2)->col; + int c1 = ((gmx_sparsematrix_entry_t*)v1)->col; + int c2 = ((gmx_sparsematrix_entry_t*)v2)->col; if (c1 < c2) { @@ -229,15 +213,14 @@ compare_columns(const void *v1, const void *v2) } -void -gmx_sparsematrix_compress(gmx_sparsematrix_t * A) +void gmx_sparsematrix_compress(gmx_sparsematrix_t* A) { int i, j; for (i = 0; i < A->nrow; i++) { /* Remove last value on this row while it is zero */ - while (A->ndata[i] > 0 && A->data[i][A->ndata[i]-1].value == 0) + while (A->ndata[i] > 0 && A->data[i][A->ndata[i] - 1].value == 0) { A->ndata[i]--; } @@ -250,28 +233,22 @@ gmx_sparsematrix_compress(gmx_sparsematrix_t * A) */ if (A->data[i][j].value == 0) { - A->data[i][j].value = A->data[i][A->ndata[i]-1].value; - A->data[i][j].col = A->data[i][A->ndata[i]-1].col; + A->data[i][j].value = A->data[i][A->ndata[i] - 1].value; + A->data[i][j].col = A->data[i][A->ndata[i] - 1].col; A->ndata[i]--; } } /* Only non-zero elements remaining on this row. Sort them after column index */ - qsort((void *)(A->data[i]), - A->ndata[i], - sizeof(gmx_sparsematrix_entry_t), - compare_columns); + qsort((void*)(A->data[i]), A->ndata[i], sizeof(gmx_sparsematrix_entry_t), compare_columns); } } -void -gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t * A, - real * x, - real * y) +void gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t* A, real* x, real* y) { - real s, v, xi; - int i, j, k; - gmx_sparsematrix_entry_t * data; /* pointer to simplify data access */ + real s, v, xi; + int i, j, k; + gmx_sparsematrix_entry_t* data; /* pointer to simplify data access */ for (i = 0; i < A->nrow; i++) { @@ -288,8 +265,8 @@ gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t * A, for (k = 0; k < A->ndata[i]; k++) { - j = data[k].col; - v = data[k].value; + j = data[k].col; + v = data[k].value; s += v * x[j]; if (i != j) { @@ -309,8 +286,8 @@ gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t * A, for (k = 0; k < A->ndata[i]; k++) { - j = data[k].col; - v = data[k].value; + j = data[k].col; + v = data[k].value; s += v * x[j]; } y[i] += s; diff --git a/src/gromacs/linearalgebra/sparsematrix.h b/src/gromacs/linearalgebra/sparsematrix.h index 48d768800b..15cec6311b 100644 --- a/src/gromacs/linearalgebra/sparsematrix.h +++ b/src/gromacs/linearalgebra/sparsematrix.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,11 +42,10 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -typedef struct - gmx_sparsematrix_entry +typedef struct gmx_sparsematrix_entry { - int col; - real value; + int col; + real value; } gmx_sparsematrix_entry_t; /*! \brief Sparse matrix storage format @@ -99,16 +98,14 @@ typedef struct * * In other words: Not perfect, but it works. */ -typedef struct - gmx_sparsematrix +typedef struct gmx_sparsematrix { - gmx_bool compressed_symmetric; /**< Store half elements and assume symmetry. */ - int nrow; /**< Number of rows in matrix */ - int * ndata; /**< Number of entries on each row (list) */ - int * nalloc; /**< Allocated entry list length for each row */ - gmx_sparsematrix_entry_t ** data; /**< data[i] is a list with entries on row i */ -} -gmx_sparsematrix_t; + gmx_bool compressed_symmetric; /**< Store half elements and assume symmetry. */ + int nrow; /**< Number of rows in matrix */ + int* ndata; /**< Number of entries on each row (list) */ + int* nalloc; /**< Allocated entry list length for each row */ + gmx_sparsematrix_entry_t** data; /**< data[i] is a list with entries on row i */ +} gmx_sparsematrix_t; /*! \brief Allocate a new sparse matrix structure @@ -121,16 +118,14 @@ gmx_sparsematrix_t; * be FALSE. Set it to TRUE manually if you are only storing either the * upper or lower half of the matrix. */ -gmx_sparsematrix_t * -gmx_sparsematrix_init (int nrow); +gmx_sparsematrix_t* gmx_sparsematrix_init(int nrow); /*! \brief Release all resources used by a sparse matrix structure * * All arrays in the structure will be freed, and the structure itself. */ -void -gmx_sparsematrix_destroy (gmx_sparsematrix_t * A); +void gmx_sparsematrix_destroy(gmx_sparsematrix_t* A); /*! \brief Print sparse matrix to a stream. @@ -138,9 +133,7 @@ gmx_sparsematrix_destroy (gmx_sparsematrix_t * A); * Mainly used for debugging. Be warned that the real sparse matrices used * in Gromacs runs can be HUGE (think 100,000 rows). */ -void -gmx_sparsematrix_print (FILE * stream, - gmx_sparsematrix_t * A); +void gmx_sparsematrix_print(FILE* stream, gmx_sparsematrix_t* A); /* Adds value at row,col. If the value did not exist * previously it is added, otherwise it is incremented with difference. @@ -148,10 +141,7 @@ gmx_sparsematrix_print (FILE * stream, * The column sort order might change, so you need to run fix_sparsematrix * once you are done changing the matrix. */ -real -gmx_sparsematrix_value (gmx_sparsematrix_t * A, - int row, - int col); +real gmx_sparsematrix_value(gmx_sparsematrix_t* A, int row, int col); /* Adds value at row,col. If the value did not exist @@ -160,12 +150,7 @@ gmx_sparsematrix_value (gmx_sparsematrix_t * A, * The column sort order might change, so you need to run fix_sparsematrix * once you are done changing the matrix. */ -void -gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, - int row, - int col, - real difference); - +void gmx_sparsematrix_increment_value(gmx_sparsematrix_t* A, int row, int col, real difference); /*! \brief Sort elements in each column and remove zeros. @@ -177,19 +162,14 @@ gmx_sparsematrix_increment_value(gmx_sparsematrix_t * A, * * It never hurts to run this routine if you have been updating the matrix... */ -void -gmx_sparsematrix_compress (gmx_sparsematrix_t * A); - +void gmx_sparsematrix_compress(gmx_sparsematrix_t* A); /*! \brief Sparse matrix vector multiplication * * Calculate y = A * x for a sparse matrix A. */ -void -gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t * A, - real * x, - real * y); +void gmx_sparsematrix_vector_multiply(gmx_sparsematrix_t* A, real* x, real* y); #endif diff --git a/src/gromacs/listed_forces/bonded.cpp b/src/gromacs/listed_forces/bonded.cpp index fcb85f8854..a0c04a6fea 100644 --- a/src/gromacs/listed_forces/bonded.cpp +++ b/src/gromacs/listed_forces/bonded.cpp @@ -85,39 +85,40 @@ namespace { //! Type of CPU function to compute a bonded interaction. -using BondedFunction = real(*)(int nbonds, const t_iatom iatoms[], - const t_iparams iparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int *ddgatindex); +using BondedFunction = real (*)(int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* ddgatindex); /*! \brief Mysterious CMAP coefficient matrix */ const int cmap_coeff_matrix[] = { - 1, 0, -3, 2, 0, 0, 0, 0, -3, 0, 9, -6, 2, 0, -6, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -9, 6, -2, 0, 6, -4, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, -6, 0, 0, -6, 4, - 0, 0, 3, -2, 0, 0, 0, 0, 0, 0, -9, 6, 0, 0, 6, -4, - 0, 0, 0, 0, 1, 0, -3, 2, -2, 0, 6, -4, 1, 0, -3, 2, - 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 3, -2, 1, 0, -3, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 2, 0, 0, 3, -2, - 0, 0, 0, 0, 0, 0, 3, -2, 0, 0, -6, 4, 0, 0, 3, -2, - 0, 1, -2, 1, 0, 0, 0, 0, 0, -3, 6, -3, 0, 2, -4, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -6, 3, 0, -2, 4, -2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 3, 0, 0, 2, -2, - 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, -2, 2, - 0, 0, 0, 0, 0, 1, -2, 1, 0, -2, 4, -2, 0, 1, -2, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 1, -2, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 1, - 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 2, -2, 0, 0, -1, 1 + 1, 0, -3, 2, 0, 0, 0, 0, -3, 0, 9, -6, 2, 0, -6, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, -9, 6, -2, 0, 6, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, -6, 0, 0, -6, 4, + 0, 0, 3, -2, 0, 0, 0, 0, 0, 0, -9, 6, 0, 0, 6, -4, 0, 0, 0, 0, 1, 0, -3, 2, + -2, 0, 6, -4, 1, 0, -3, 2, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 3, -2, 1, 0, -3, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 2, 0, 0, 3, -2, 0, 0, 0, 0, 0, 0, 3, -2, + 0, 0, -6, 4, 0, 0, 3, -2, 0, 1, -2, 1, 0, 0, 0, 0, 0, -3, 6, -3, 0, 2, -4, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -6, 3, 0, -2, 4, -2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -3, 3, 0, 0, 2, -2, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 3, -3, 0, 0, -2, 2, + 0, 0, 0, 0, 0, 1, -2, 1, 0, -2, 4, -2, 0, 1, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 2, -1, 0, 1, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 0, -1, 1, + 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 2, -2, 0, 0, -1, 1 }; /*! \brief Compute dx = xi - xj, modulo PBC if non-NULL * * \todo This kind of code appears in many places. Consolidate it */ -int pbc_rvec_sub(const t_pbc *pbc, const rvec xi, const rvec xj, rvec dx) +int pbc_rvec_sub(const t_pbc* pbc, const rvec xi, const rvec xj, rvec dx) { if (pbc) { @@ -133,9 +134,15 @@ int pbc_rvec_sub(const t_pbc *pbc, const rvec xi, const rvec xj, rvec dx) } // namespace //! \cond -real bond_angle(const rvec xi, const rvec xj, const rvec xk, const t_pbc *pbc, - rvec r_ij, rvec r_kj, real *costh, - int *t1, int *t2) +real bond_angle(const rvec xi, + const rvec xj, + const rvec xk, + const t_pbc* pbc, + rvec r_ij, + rvec r_kj, + real* costh, + int* t1, + int* t2) /* Return value is the angle between the bonds i-j and j-k */ { /* 41 FLOPS */ @@ -144,42 +151,51 @@ real bond_angle(const rvec xi, const rvec xj, const rvec xk, const t_pbc *pbc, *t1 = pbc_rvec_sub(pbc, xi, xj, r_ij); /* 3 */ *t2 = pbc_rvec_sub(pbc, xk, xj, r_kj); /* 3 */ - *costh = cos_angle(r_ij, r_kj); /* 25 */ - th = std::acos(*costh); /* 10 */ + *costh = cos_angle(r_ij, r_kj); /* 25 */ + th = std::acos(*costh); /* 10 */ /* 41 TOTAL */ return th; } -real dih_angle(const rvec xi, const rvec xj, const rvec xk, const rvec xl, - const t_pbc *pbc, - rvec r_ij, rvec r_kj, rvec r_kl, rvec m, rvec n, - int *t1, int *t2, int *t3) +real dih_angle(const rvec xi, + const rvec xj, + const rvec xk, + const rvec xl, + const t_pbc* pbc, + rvec r_ij, + rvec r_kj, + rvec r_kl, + rvec m, + rvec n, + int* t1, + int* t2, + int* t3) { *t1 = pbc_rvec_sub(pbc, xi, xj, r_ij); /* 3 */ *t2 = pbc_rvec_sub(pbc, xk, xj, r_kj); /* 3 */ *t3 = pbc_rvec_sub(pbc, xk, xl, r_kl); /* 3 */ - cprod(r_ij, r_kj, m); /* 9 */ - cprod(r_kj, r_kl, n); /* 9 */ - real phi = gmx_angle(m, n); /* 49 (assuming 25 for atan2) */ - real ipr = iprod(r_ij, n); /* 5 */ + cprod(r_ij, r_kj, m); /* 9 */ + cprod(r_kj, r_kl, n); /* 9 */ + real phi = gmx_angle(m, n); /* 49 (assuming 25 for atan2) */ + real ipr = iprod(r_ij, n); /* 5 */ real sign = (ipr < 0.0) ? -1.0 : 1.0; - phi = sign*phi; /* 1 */ + phi = sign * phi; /* 1 */ /* 82 TOTAL */ return phi; } //! \endcond -void make_dp_periodic(real *dp) /* 1 flop? */ +void make_dp_periodic(real* dp) /* 1 flop? */ { /* dp cannot be outside (-pi,pi) */ if (*dp >= M_PI) { - *dp -= 2*M_PI; + *dp -= 2 * M_PI; } else if (*dp < -M_PI) { - *dp += 2*M_PI; + *dp += 2 * M_PI; } } @@ -191,15 +207,15 @@ namespace * When \p g==nullptr, \p shiftIndex is used as the periodic shift. * When \p g!=nullptr, the graph is used to compute the periodic shift. */ -template +template inline void spreadBondForces(const real bondForce, const rvec dx, const int ai, const int aj, - rvec4 *f, + rvec4* f, int shiftIndex, - const t_graph *g, - rvec *fshift) + const t_graph* g, + rvec* fshift) { if (computeVirial(flavor) && g) { @@ -208,15 +224,15 @@ inline void spreadBondForces(const real bondForce, shiftIndex = IVEC2IS(dt); } - for (int m = 0; m < DIM; m++) /* 15 */ + for (int m = 0; m < DIM; m++) /* 15 */ { - const real fij = bondForce*dx[m]; - f[ai][m] += fij; - f[aj][m] -= fij; + const real fij = bondForce * dx[m]; + f[ai][m] += fij; + f[aj][m] -= fij; if (computeVirial(flavor)) { fshift[shiftIndex][m] += fij; - fshift[CENTRAL][m] -= fij; + fshift[CENTRAL][m] -= fij; } } } @@ -232,14 +248,20 @@ inline void spreadBondForces(const real bondForce, * Note: the potential is referenced to be +cb at infinite separation * and zero at the equilibrium distance! */ -template -real morse_bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real morse_bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { const real one = 1.0; const real two = 2.0; @@ -249,59 +271,66 @@ real morse_bonds(int nbonds, int i, ki, type, ai, aj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - b0A = forceparams[type].morse.b0A; - beA = forceparams[type].morse.betaA; - cbA = forceparams[type].morse.cbA; + b0A = forceparams[type].morse.b0A; + beA = forceparams[type].morse.betaA; + cbA = forceparams[type].morse.cbA; - b0B = forceparams[type].morse.b0B; - beB = forceparams[type].morse.betaB; - cbB = forceparams[type].morse.cbB; + b0B = forceparams[type].morse.b0B; + beB = forceparams[type].morse.betaB; + cbB = forceparams[type].morse.cbB; - L1 = one-lambda; /* 1 */ - b0 = L1*b0A + lambda*b0B; /* 3 */ - be = L1*beA + lambda*beB; /* 3 */ - cb = L1*cbA + lambda*cbB; /* 3 */ + L1 = one - lambda; /* 1 */ + b0 = L1 * b0A + lambda * b0B; /* 3 */ + be = L1 * beA + lambda * beB; /* 3 */ + cb = L1 * cbA + lambda * cbB; /* 3 */ ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ dr2 = iprod(dx, dx); /* 5 */ - dr = dr2*gmx::invsqrt(dr2); /* 10 */ - temp = std::exp(-be*(dr-b0)); /* 12 */ + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ + temp = std::exp(-be * (dr - b0)); /* 12 */ if (temp == one) { /* bonds are constrainted. This may _not_ include bond constraints if they are lambda dependent */ - *dvdlambda += cbB-cbA; + *dvdlambda += cbB - cbA; continue; } - omtemp = one-temp; /* 1 */ - cbomtemp = cb*omtemp; /* 1 */ - vbond = cbomtemp*omtemp; /* 1 */ - fbond = -two*be*temp*cbomtemp*gmx::invsqrt(dr2); /* 9 */ - vtot += vbond; /* 1 */ + omtemp = one - temp; /* 1 */ + cbomtemp = cb * omtemp; /* 1 */ + vbond = cbomtemp * omtemp; /* 1 */ + fbond = -two * be * temp * cbomtemp * gmx::invsqrt(dr2); /* 9 */ + vtot += vbond; /* 1 */ - *dvdlambda += (cbB - cbA) * omtemp * omtemp - (2-2*omtemp)*omtemp * cb * ((b0B-b0A)*be - (beB-beA)*(dr-b0)); /* 15 */ + *dvdlambda += (cbB - cbA) * omtemp * omtemp + - (2 - 2 * omtemp) * omtemp * cb * ((b0B - b0A) * be - (beB - beA) * (dr - b0)); /* 15 */ - spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ - } /* 83 TOTAL */ + spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ + } /* 83 TOTAL */ return vtot; } //! \cond -template -real cubic_bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real cubic_bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { const real three = 3.0; const real two = 2.0; @@ -311,7 +340,7 @@ real cubic_bonds(int nbonds, int i, ki, type, ai, aj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -321,37 +350,43 @@ real cubic_bonds(int nbonds, kb = forceparams[type].cubic.kb; kcub = forceparams[type].cubic.kcub; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ if (dr2 == 0.0) { continue; } - dr = dr2*gmx::invsqrt(dr2); /* 10 */ - dist = dr-b0; - kdist = kb*dist; - kdist2 = kdist*dist; + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ + dist = dr - b0; + kdist = kb * dist; + kdist2 = kdist * dist; - vbond = kdist2 + kcub*kdist2*dist; - fbond = -(two*kdist + three*kdist2*kcub)/dr; + vbond = kdist2 + kcub * kdist2 * dist; + fbond = -(two * kdist + three * kdist2 * kcub) / dr; - vtot += vbond; /* 21 */ + vtot += vbond; /* 21 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 54 TOTAL */ return vtot; } -template -real FENE_bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int *global_atom_index) +template +real FENE_bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int* global_atom_index) { const real half = 0.5; const real one = 1.0; @@ -361,66 +396,62 @@ real FENE_bonds(int nbonds, int i, ki, type, ai, aj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - bm = forceparams[type].fene.bm; - kb = forceparams[type].fene.kb; + bm = forceparams[type].fene.bm; + kb = forceparams[type].fene.kb; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ if (dr2 == 0.0) { continue; } - bm2 = bm*bm; + bm2 = bm * bm; if (dr2 >= bm2) { - gmx_fatal(FARGS, - "r^2 (%f) >= bm^2 (%f) in FENE bond between atoms %d and %d", - dr2, bm2, - glatnr(global_atom_index, ai), - glatnr(global_atom_index, aj)); + gmx_fatal(FARGS, "r^2 (%f) >= bm^2 (%f) in FENE bond between atoms %d and %d", dr2, bm2, + glatnr(global_atom_index, ai), glatnr(global_atom_index, aj)); } - omdr2obm2 = one - dr2/bm2; + omdr2obm2 = one - dr2 / bm2; - vbond = -half*kb*bm2*std::log(omdr2obm2); - fbond = -kb/omdr2obm2; + vbond = -half * kb * bm2 * std::log(omdr2obm2); + fbond = -kb / omdr2obm2; - vtot += vbond; /* 35 */ + vtot += vbond; /* 35 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 58 TOTAL */ return vtot; } -real harmonic(real kA, real kB, real xA, real xB, real x, real lambda, - real *V, real *F) +real harmonic(real kA, real kB, real xA, real xB, real x, real lambda, real* V, real* F) { const real half = 0.5; real L1, kk, x0, dx, dx2; real v, f, dvdlambda; - L1 = 1.0-lambda; - kk = L1*kA+lambda*kB; - x0 = L1*xA+lambda*xB; + L1 = 1.0 - lambda; + kk = L1 * kA + lambda * kB; + x0 = L1 * xA + lambda * xB; - dx = x-x0; - dx2 = dx*dx; + dx = x - x0; + dx2 = dx * dx; - f = -kk*dx; - v = half*kk*dx2; - dvdlambda = half*(kB-kA)*dx2 + (xA-xB)*kk*dx; + f = -kk * dx; + v = half * kk * dx2; + dvdlambda = half * (kB - kA) * dx2 + (xA - xB) * kk * dx; - *F = f; - *V = v; + *F = f; + *V = v; return dvdlambda; @@ -428,35 +459,39 @@ real harmonic(real kA, real kB, real xA, real xB, real x, real lambda, } -template -real bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type; real dr, dr2, fbond, vbond, vtot; rvec dx; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ - dr = std::sqrt(dr2); /* 10 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ + dr = std::sqrt(dr2); /* 10 */ - *dvdlambda += harmonic(forceparams[type].harmonic.krA, - forceparams[type].harmonic.krB, - forceparams[type].harmonic.rA, - forceparams[type].harmonic.rB, - dr, lambda, &vbond, &fbond); /* 19 */ + *dvdlambda += harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB, + forceparams[type].harmonic.rA, forceparams[type].harmonic.rB, dr, + lambda, &vbond, &fbond); /* 19 */ if (dr2 == 0.0) { @@ -464,22 +499,28 @@ real bonds(int nbonds, } - vtot += vbond; /* 1*/ - fbond *= gmx::invsqrt(dr2); /* 6 */ + vtot += vbond; /* 1*/ + fbond *= gmx::invsqrt(dr2); /* 6 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 59 TOTAL */ return vtot; } -template -real restraint_bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real restraint_bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type; real dr, dr2, fbond, vbond, vtot; @@ -488,37 +529,37 @@ real restraint_bonds(int nbonds, real drh, drh2; rvec dx; - L1 = 1.0 - lambda; + L1 = 1.0 - lambda; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ - dr = dr2*gmx::invsqrt(dr2); /* 10 */ - - low = L1*forceparams[type].restraint.lowA + lambda*forceparams[type].restraint.lowB; - dlow = -forceparams[type].restraint.lowA + forceparams[type].restraint.lowB; - up1 = L1*forceparams[type].restraint.up1A + lambda*forceparams[type].restraint.up1B; - dup1 = -forceparams[type].restraint.up1A + forceparams[type].restraint.up1B; - up2 = L1*forceparams[type].restraint.up2A + lambda*forceparams[type].restraint.up2B; - dup2 = -forceparams[type].restraint.up2A + forceparams[type].restraint.up2B; - k = L1*forceparams[type].restraint.kA + lambda*forceparams[type].restraint.kB; - dk = -forceparams[type].restraint.kA + forceparams[type].restraint.kB; + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ + + low = L1 * forceparams[type].restraint.lowA + lambda * forceparams[type].restraint.lowB; + dlow = -forceparams[type].restraint.lowA + forceparams[type].restraint.lowB; + up1 = L1 * forceparams[type].restraint.up1A + lambda * forceparams[type].restraint.up1B; + dup1 = -forceparams[type].restraint.up1A + forceparams[type].restraint.up1B; + up2 = L1 * forceparams[type].restraint.up2A + lambda * forceparams[type].restraint.up2B; + dup2 = -forceparams[type].restraint.up2A + forceparams[type].restraint.up2B; + k = L1 * forceparams[type].restraint.kA + lambda * forceparams[type].restraint.kB; + dk = -forceparams[type].restraint.kA + forceparams[type].restraint.kB; /* 24 */ if (dr < low) { - drh = dr - low; - drh2 = drh*drh; - vbond = 0.5*k*drh2; - fbond = -k*drh; - *dvdlambda += 0.5*dk*drh2 - k*dlow*drh; - } /* 11 */ + drh = dr - low; + drh2 = drh * drh; + vbond = 0.5 * k * drh2; + fbond = -k * drh; + *dvdlambda += 0.5 * dk * drh2 - k * dlow * drh; + } /* 11 */ else if (dr <= up1) { vbond = 0; @@ -526,20 +567,19 @@ real restraint_bonds(int nbonds, } else if (dr <= up2) { - drh = dr - up1; - drh2 = drh*drh; - vbond = 0.5*k*drh2; - fbond = -k*drh; - *dvdlambda += 0.5*dk*drh2 - k*dup1*drh; - } /* 11 */ + drh = dr - up1; + drh2 = drh * drh; + vbond = 0.5 * k * drh2; + fbond = -k * drh; + *dvdlambda += 0.5 * dk * drh2 - k * dup1 * drh; + } /* 11 */ else { - drh = dr - up2; - vbond = k*(up2 - up1)*(0.5*(up2 - up1) + drh); - fbond = -k*(up2 - up1); - *dvdlambda += dk*(up2 - up1)*(0.5*(up2 - up1) + drh) - + k*(dup2 - dup1)*(up2 - up1 + drh) - - k*(up2 - up1)*dup2; + drh = dr - up2; + vbond = k * (up2 - up1) * (0.5 * (up2 - up1) + drh); + fbond = -k * (up2 - up1); + *dvdlambda += dk * (up2 - up1) * (0.5 * (up2 - up1) + drh) + + k * (dup2 - dup1) * (up2 - up1 + drh) - k * (up2 - up1) * dup2; } if (dr2 == 0.0) @@ -547,8 +587,8 @@ real restraint_bonds(int nbonds, continue; } - vtot += vbond; /* 1*/ - fbond *= gmx::invsqrt(dr2); /* 6 */ + vtot += vbond; /* 1*/ + fbond *= gmx::invsqrt(dr2); /* 6 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 59 TOTAL */ @@ -556,30 +596,36 @@ real restraint_bonds(int nbonds, return vtot; } -template -real polarize(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real polarize(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type; real dr, dr2, fbond, vbond, vtot, ksh; rvec dx; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - ksh = gmx::square(md->chargeA[aj])*ONE_4PI_EPS0/forceparams[type].polarize.alpha; + ksh = gmx::square(md->chargeA[aj]) * ONE_4PI_EPS0 / forceparams[type].polarize.alpha; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ - dr = std::sqrt(dr2); /* 10 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ + dr = std::sqrt(dr2); /* 10 */ *dvdlambda += harmonic(ksh, ksh, 0, 0, dr, lambda, &vbond, &fbond); /* 19 */ @@ -588,40 +634,46 @@ real polarize(int nbonds, continue; } - vtot += vbond; /* 1*/ - fbond *= gmx::invsqrt(dr2); /* 6 */ + vtot += vbond; /* 1*/ + fbond *= gmx::invsqrt(dr2); /* 6 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 59 TOTAL */ return vtot; } -template -real anharm_polarize(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real anharm_polarize(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type; real dr, dr2, fbond, vbond, vtot, ksh, khyp, drcut, ddr, ddr3; rvec dx; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { - type = forceatoms[i++]; - ai = forceatoms[i++]; - aj = forceatoms[i++]; - ksh = gmx::square(md->chargeA[aj])*ONE_4PI_EPS0/forceparams[type].anharm_polarize.alpha; /* 7*/ + type = forceatoms[i++]; + ai = forceatoms[i++]; + aj = forceatoms[i++]; + ksh = gmx::square(md->chargeA[aj]) * ONE_4PI_EPS0 / forceparams[type].anharm_polarize.alpha; /* 7*/ khyp = forceparams[type].anharm_polarize.khyp; drcut = forceparams[type].anharm_polarize.drcut; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ - dr = dr2*gmx::invsqrt(dr2); /* 10 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ *dvdlambda += harmonic(ksh, ksh, 0, 0, dr, lambda, &vbond, &fbond); /* 19 */ @@ -632,27 +684,33 @@ real anharm_polarize(int nbonds, if (dr > drcut) { - ddr = dr-drcut; - ddr3 = ddr*ddr*ddr; - vbond += khyp*ddr*ddr3; - fbond -= 4*khyp*ddr3; + ddr = dr - drcut; + ddr3 = ddr * ddr * ddr; + vbond += khyp * ddr * ddr3; + fbond -= 4 * khyp * ddr3; } - fbond *= gmx::invsqrt(dr2); /* 6 */ - vtot += vbond; /* 1*/ + fbond *= gmx::invsqrt(dr2); /* 6 */ + vtot += vbond; /* 1*/ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 72 TOTAL */ return vtot; } -template -real water_pol(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec gmx_unused fshift[], - const t_pbc gmx_unused *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real water_pol(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec gmx_unused fshift[], + const t_pbc gmx_unused* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { /* This routine implements anisotropic polarizibility for water, through * a shell connected to a dummy with spring constant that differ in the @@ -669,23 +727,23 @@ real water_pol(int nbonds, type0 = forceatoms[0]; aS = forceatoms[5]; qS = md->chargeA[aS]; - kk[XX] = gmx::square(qS)*ONE_4PI_EPS0/forceparams[type0].wpol.al_x; - kk[YY] = gmx::square(qS)*ONE_4PI_EPS0/forceparams[type0].wpol.al_y; - kk[ZZ] = gmx::square(qS)*ONE_4PI_EPS0/forceparams[type0].wpol.al_z; - r_HH = 1.0/forceparams[type0].wpol.rHH; + kk[XX] = gmx::square(qS) * ONE_4PI_EPS0 / forceparams[type0].wpol.al_x; + kk[YY] = gmx::square(qS) * ONE_4PI_EPS0 / forceparams[type0].wpol.al_y; + kk[ZZ] = gmx::square(qS) * ONE_4PI_EPS0 / forceparams[type0].wpol.al_z; + r_HH = 1.0 / forceparams[type0].wpol.rHH; for (i = 0; (i < nbonds); i += 6) { type = forceatoms[i]; if (type != type0) { - gmx_fatal(FARGS, "Sorry, type = %d, type0 = %d, file = %s, line = %d", - type, type0, __FILE__, __LINE__); + gmx_fatal(FARGS, "Sorry, type = %d, type0 = %d, file = %s, line = %d", type, type0, + __FILE__, __LINE__); } - aO = forceatoms[i+1]; - aH1 = forceatoms[i+2]; - aH2 = forceatoms[i+3]; - aD = forceatoms[i+4]; - aS = forceatoms[i+5]; + aO = forceatoms[i + 1]; + aH1 = forceatoms[i + 2]; + aH2 = forceatoms[i + 3]; + aD = forceatoms[i + 4]; + aS = forceatoms[i + 5]; /* Compute vectors describing the water frame */ pbc_rvec_sub(pbc, x[aH1], x[aO], dOH1); @@ -714,7 +772,7 @@ real water_pol(int nbonds, /* Compute projection on the XY plane: dDS - dx[ZZ]*dOD */ for (m = 0; (m < DIM); m++) { - proj[m] = dDS[m]-dx[ZZ]*dOD[m]; + proj[m] = dDS[m] - dx[ZZ] * dOD[m]; } /*dx[XX] = iprod(dDS,nW); @@ -722,14 +780,14 @@ real water_pol(int nbonds, dx[XX] = iprod(proj, nW); for (m = 0; (m < DIM); m++) { - proj[m] -= dx[XX]*nW[m]; + proj[m] -= dx[XX] * nW[m]; } dx[YY] = iprod(proj, dHH); /* Now compute the forces and energy */ - kdx[XX] = kk[XX]*dx[XX]; - kdx[YY] = kk[YY]*dx[YY]; - kdx[ZZ] = kk[ZZ]*dx[ZZ]; - vtot += iprod(dx, kdx); + kdx[XX] = kk[XX] * dx[XX]; + kdx[YY] = kk[YY] * dx[YY]; + kdx[ZZ] = kk[ZZ] * dx[ZZ]; + vtot += iprod(dx, kdx); if (computeVirial(flavor) && g) { @@ -740,104 +798,115 @@ real water_pol(int nbonds, for (m = 0; (m < DIM); m++) { /* This is a tensor operation but written out for speed */ - tx = nW[m]*kdx[XX]; - ty = dHH[m]*kdx[YY]; - tz = dOD[m]*kdx[ZZ]; - fij = -tx-ty-tz; - f[aS][m] += fij; - f[aD][m] -= fij; + tx = nW[m] * kdx[XX]; + ty = dHH[m] * kdx[YY]; + tz = dOD[m] * kdx[ZZ]; + fij = -tx - ty - tz; + f[aS][m] += fij; + f[aD][m] -= fij; if (computeVirial(flavor)) { - fshift[ki][m] += fij; + fshift[ki][m] += fij; fshift[CENTRAL][m] -= fij; } } } } - return 0.5*vtot; + return 0.5 * vtot; } -template -static real do_1_thole(const rvec xi, const rvec xj, rvec fi, rvec fj, - const t_pbc *pbc, real qq, - rvec fshift[], real afac) +template +static real +do_1_thole(const rvec xi, const rvec xj, rvec fi, rvec fj, const t_pbc* pbc, real qq, rvec fshift[], real afac) { rvec r12; real r12sq, r12_1, r12bar, v0, v1, fscal, ebar, fff; int m, t; - t = pbc_rvec_sub(pbc, xi, xj, r12); /* 3 */ + t = pbc_rvec_sub(pbc, xi, xj, r12); /* 3 */ - r12sq = iprod(r12, r12); /* 5 */ - r12_1 = gmx::invsqrt(r12sq); /* 5 */ - r12bar = afac/r12_1; /* 5 */ - v0 = qq*ONE_4PI_EPS0*r12_1; /* 2 */ - ebar = std::exp(-r12bar); /* 5 */ - v1 = (1-(1+0.5*r12bar)*ebar); /* 4 */ - fscal = ((v0*r12_1)*v1 - v0*0.5*afac*ebar*(r12bar+1))*r12_1; /* 9 */ + r12sq = iprod(r12, r12); /* 5 */ + r12_1 = gmx::invsqrt(r12sq); /* 5 */ + r12bar = afac / r12_1; /* 5 */ + v0 = qq * ONE_4PI_EPS0 * r12_1; /* 2 */ + ebar = std::exp(-r12bar); /* 5 */ + v1 = (1 - (1 + 0.5 * r12bar) * ebar); /* 4 */ + fscal = ((v0 * r12_1) * v1 - v0 * 0.5 * afac * ebar * (r12bar + 1)) * r12_1; /* 9 */ for (m = 0; (m < DIM); m++) { - fff = fscal*r12[m]; - fi[m] += fff; - fj[m] -= fff; + fff = fscal * r12[m]; + fi[m] += fff; + fj[m] -= fff; if (computeVirial(flavor)) { - fshift[t][m] += fff; + fshift[t][m] += fff; fshift[CENTRAL][m] -= fff; } - } /* 15 */ + } /* 15 */ - return v0*v1; /* 1 */ + return v0 * v1; /* 1 */ /* 54 */ } -template -real thole_pol(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real thole_pol(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { /* Interaction between two pairs of particles with opposite charge */ - int i, type, a1, da1, a2, da2; - real q1, q2, qq, a, al1, al2, afac; - real V = 0; + int i, type, a1, da1, a2, da2; + real q1, q2, qq, a, al1, al2, afac; + real V = 0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { - type = forceatoms[i++]; - a1 = forceatoms[i++]; - da1 = forceatoms[i++]; - a2 = forceatoms[i++]; - da2 = forceatoms[i++]; - q1 = md->chargeA[da1]; - q2 = md->chargeA[da2]; - a = forceparams[type].thole.a; - al1 = forceparams[type].thole.alpha1; - al2 = forceparams[type].thole.alpha2; - qq = q1*q2; - afac = a*gmx::invsixthroot(al1*al2); - V += do_1_thole(x[a1], x[a2], f[a1], f[a2], pbc, qq, fshift, afac); - V += do_1_thole(x[da1], x[a2], f[da1], f[a2], pbc, -qq, fshift, afac); - V += do_1_thole(x[a1], x[da2], f[a1], f[da2], pbc, -qq, fshift, afac); - V += do_1_thole(x[da1], x[da2], f[da1], f[da2], pbc, qq, fshift, afac); + type = forceatoms[i++]; + a1 = forceatoms[i++]; + da1 = forceatoms[i++]; + a2 = forceatoms[i++]; + da2 = forceatoms[i++]; + q1 = md->chargeA[da1]; + q2 = md->chargeA[da2]; + a = forceparams[type].thole.a; + al1 = forceparams[type].thole.alpha1; + al2 = forceparams[type].thole.alpha2; + qq = q1 * q2; + afac = a * gmx::invsixthroot(al1 * al2); + V += do_1_thole(x[a1], x[a2], f[a1], f[a2], pbc, qq, fshift, afac); + V += do_1_thole(x[da1], x[a2], f[da1], f[a2], pbc, -qq, fshift, afac); + V += do_1_thole(x[a1], x[da2], f[a1], f[da2], pbc, -qq, fshift, afac); + V += do_1_thole(x[da1], x[da2], f[da1], f[da2], pbc, qq, fshift, afac); } /* 290 flops */ return V; } -template +template std::enable_if_t -angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ai, aj, ak, t1, t2, type; rvec r_ij, r_kj; @@ -845,21 +914,18 @@ angles(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; i < nbonds; ) + for (i = 0; i < nbonds;) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; ak = forceatoms[i++]; - theta = bond_angle(x[ai], x[aj], x[ak], pbc, - r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ + theta = bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ - *dvdlambda += harmonic(forceparams[type].harmonic.krA, - forceparams[type].harmonic.krB, - forceparams[type].harmonic.rA*DEG2RAD, - forceparams[type].harmonic.rB*DEG2RAD, - theta, lambda, &va, &dVdt); /* 21 */ + *dvdlambda += harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB, + forceparams[type].harmonic.rA * DEG2RAD, + forceparams[type].harmonic.rB * DEG2RAD, theta, lambda, &va, &dVdt); /* 21 */ vtot += va; cos_theta2 = gmx::square(cos_theta); @@ -872,23 +938,23 @@ angles(int nbonds, real nrkj_1, nrij_1; rvec f_i, f_j, f_k; - st = dVdt*gmx::invsqrt(1 - cos_theta2); /* 12 */ - sth = st*cos_theta; /* 1 */ - nrij2 = iprod(r_ij, r_ij); /* 5 */ - nrkj2 = iprod(r_kj, r_kj); /* 5 */ + st = dVdt * gmx::invsqrt(1 - cos_theta2); /* 12 */ + sth = st * cos_theta; /* 1 */ + nrij2 = iprod(r_ij, r_ij); /* 5 */ + nrkj2 = iprod(r_kj, r_kj); /* 5 */ - nrij_1 = gmx::invsqrt(nrij2); /* 10 */ - nrkj_1 = gmx::invsqrt(nrkj2); /* 10 */ + nrij_1 = gmx::invsqrt(nrij2); /* 10 */ + nrkj_1 = gmx::invsqrt(nrkj2); /* 10 */ - cik = st*nrij_1*nrkj_1; /* 2 */ - cii = sth*nrij_1*nrij_1; /* 2 */ - ckk = sth*nrkj_1*nrkj_1; /* 2 */ + cik = st * nrij_1 * nrkj_1; /* 2 */ + cii = sth * nrij_1 * nrij_1; /* 2 */ + ckk = sth * nrkj_1 * nrkj_1; /* 2 */ for (m = 0; m < DIM; m++) - { /* 39 */ - f_i[m] = -(cik*r_kj[m] - cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m] - ckk*r_kj[m]); - f_j[m] = -f_i[m] - f_k[m]; + { /* 39 */ + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -908,7 +974,7 @@ angles(int nbonds, rvec_inc(fshift[CENTRAL], f_j); rvec_inc(fshift[t2], f_k); } - } /* 161 TOTAL */ + } /* 161 TOTAL */ } return vtot; @@ -919,48 +985,54 @@ angles(int nbonds, /* As angles, but using SIMD to calculate many angles at once. * This routines does not calculate energies and shift forces. */ -template +template std::enable_if_t -angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec gmx_unused fshift[], - const t_pbc *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec gmx_unused fshift[], + const t_pbc* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - const int nfa1 = 4; - int i, iu, s; - int type; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) real coeff[2*GMX_SIMD_REAL_WIDTH]; - SimdReal deg2rad_S(DEG2RAD); - SimdReal xi_S, yi_S, zi_S; - SimdReal xj_S, yj_S, zj_S; - SimdReal xk_S, yk_S, zk_S; - SimdReal k_S, theta0_S; - SimdReal rijx_S, rijy_S, rijz_S; - SimdReal rkjx_S, rkjy_S, rkjz_S; - SimdReal one_S(1.0); - SimdReal min_one_plus_eps_S(-1.0 + 2.0*GMX_REAL_EPS); // Smallest number > -1 - - SimdReal rij_rkj_S; - SimdReal nrij2_S, nrij_1_S; - SimdReal nrkj2_S, nrkj_1_S; - SimdReal cos_S, invsin_S; - SimdReal theta_S; - SimdReal st_S, sth_S; - SimdReal cik_S, cii_S, ckk_S; - SimdReal f_ix_S, f_iy_S, f_iz_S; - SimdReal f_kx_S, f_ky_S, f_kz_S; - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + const int nfa1 = 4; + int i, iu, s; + int type; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real coeff[2 * GMX_SIMD_REAL_WIDTH]; + SimdReal deg2rad_S(DEG2RAD); + SimdReal xi_S, yi_S, zi_S; + SimdReal xj_S, yj_S, zj_S; + SimdReal xk_S, yk_S, zk_S; + SimdReal k_S, theta0_S; + SimdReal rijx_S, rijy_S, rijz_S; + SimdReal rkjx_S, rkjy_S, rkjz_S; + SimdReal one_S(1.0); + SimdReal min_one_plus_eps_S(-1.0 + 2.0 * GMX_REAL_EPS); // Smallest number > -1 + + SimdReal rij_rkj_S; + SimdReal nrij2_S, nrij_1_S; + SimdReal nrkj2_S, nrkj_1_S; + SimdReal cos_S, invsin_S; + SimdReal theta_S; + SimdReal st_S, sth_S; + SimdReal cik_S, cii_S, ckk_S; + SimdReal f_ix_S, f_iy_S, f_iz_S; + SimdReal f_kx_S, f_ky_S, f_kz_S; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; set_pbc_simd(pbc, pbc_simd); /* nbonds is the number of angles times nfa1, here we step GMX_SIMD_REAL_WIDTH angles */ - for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH*nfa1) + for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH * nfa1) { /* Collect atoms for GMX_SIMD_REAL_WIDTH angles. * iu indexes into forceatoms, we should not let iu go beyond nbonds. @@ -969,15 +1041,15 @@ angles(int nbonds, for (s = 0; s < GMX_SIMD_REAL_WIDTH; s++) { type = forceatoms[iu]; - ai[s] = forceatoms[iu+1]; - aj[s] = forceatoms[iu+2]; - ak[s] = forceatoms[iu+3]; + ai[s] = forceatoms[iu + 1]; + aj[s] = forceatoms[iu + 2]; + ak[s] = forceatoms[iu + 3]; /* At the end fill the arrays with the last atoms and 0 params */ - if (i + s*nfa1 < nbonds) + if (i + s * nfa1 < nbonds) { - coeff[s] = forceparams[type].harmonic.krA; - coeff[GMX_SIMD_REAL_WIDTH+s] = forceparams[type].harmonic.rA; + coeff[s] = forceparams[type].harmonic.krA; + coeff[GMX_SIMD_REAL_WIDTH + s] = forceparams[type].harmonic.rA; if (iu + nfa1 < nbonds) { @@ -986,15 +1058,15 @@ angles(int nbonds, } else { - coeff[s] = 0; - coeff[GMX_SIMD_REAL_WIDTH+s] = 0; + coeff[s] = 0; + coeff[GMX_SIMD_REAL_WIDTH + s] = 0; } } /* Store the non PBC corrected distances packed and aligned */ - gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); rijx_S = xi_S - xj_S; rijy_S = yi_S - yj_S; rijz_S = zi_S - zj_S; @@ -1002,22 +1074,21 @@ angles(int nbonds, rkjy_S = yk_S - yj_S; rkjz_S = zk_S - zj_S; - k_S = load(coeff); - theta0_S = load(coeff+GMX_SIMD_REAL_WIDTH) * deg2rad_S; + k_S = load(coeff); + theta0_S = load(coeff + GMX_SIMD_REAL_WIDTH) * deg2rad_S; pbc_correct_dx_simd(&rijx_S, &rijy_S, &rijz_S, pbc_simd); pbc_correct_dx_simd(&rkjx_S, &rkjy_S, &rkjz_S, pbc_simd); - rij_rkj_S = iprod(rijx_S, rijy_S, rijz_S, - rkjx_S, rkjy_S, rkjz_S); + rij_rkj_S = iprod(rijx_S, rijy_S, rijz_S, rkjx_S, rkjy_S, rkjz_S); - nrij2_S = norm2(rijx_S, rijy_S, rijz_S); - nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); + nrij2_S = norm2(rijx_S, rijy_S, rijz_S); + nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); - nrij_1_S = invsqrt(nrij2_S); - nrkj_1_S = invsqrt(nrkj2_S); + nrij_1_S = invsqrt(nrij2_S); + nrkj_1_S = invsqrt(nrkj2_S); - cos_S = rij_rkj_S * nrij_1_S * nrkj_1_S; + cos_S = rij_rkj_S * nrij_1_S * nrkj_1_S; /* To allow for 180 degrees, we take the max of cos and -1 + 1bit, * so we can safely get the 1/sin from 1/sqrt(1 - cos^2). @@ -1026,35 +1097,36 @@ angles(int nbonds, * Note that we do not take precautions for cos(0)=1, so the outer * atoms in an angle should not be on top of each other. */ - cos_S = max(cos_S, min_one_plus_eps_S); - - theta_S = acos(cos_S); - - invsin_S = invsqrt( one_S - cos_S * cos_S ); - - st_S = k_S * (theta0_S - theta_S) * invsin_S; - sth_S = st_S * cos_S; - - cik_S = st_S * nrij_1_S * nrkj_1_S; - cii_S = sth_S * nrij_1_S * nrij_1_S; - ckk_S = sth_S * nrkj_1_S * nrkj_1_S; - - f_ix_S = cii_S * rijx_S; - f_ix_S = fnma(cik_S, rkjx_S, f_ix_S); - f_iy_S = cii_S * rijy_S; - f_iy_S = fnma(cik_S, rkjy_S, f_iy_S); - f_iz_S = cii_S * rijz_S; - f_iz_S = fnma(cik_S, rkjz_S, f_iz_S); - f_kx_S = ckk_S * rkjx_S; - f_kx_S = fnma(cik_S, rijx_S, f_kx_S); - f_ky_S = ckk_S * rkjy_S; - f_ky_S = fnma(cik_S, rijy_S, f_ky_S); - f_kz_S = ckk_S * rkjz_S; - f_kz_S = fnma(cik_S, rijz_S, f_kz_S); - - transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_ix_S, f_iy_S, f_iz_S); - transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, f_iz_S + f_kz_S); - transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_kx_S, f_ky_S, f_kz_S); + cos_S = max(cos_S, min_one_plus_eps_S); + + theta_S = acos(cos_S); + + invsin_S = invsqrt(one_S - cos_S * cos_S); + + st_S = k_S * (theta0_S - theta_S) * invsin_S; + sth_S = st_S * cos_S; + + cik_S = st_S * nrij_1_S * nrkj_1_S; + cii_S = sth_S * nrij_1_S * nrij_1_S; + ckk_S = sth_S * nrkj_1_S * nrkj_1_S; + + f_ix_S = cii_S * rijx_S; + f_ix_S = fnma(cik_S, rkjx_S, f_ix_S); + f_iy_S = cii_S * rijy_S; + f_iy_S = fnma(cik_S, rkjy_S, f_iy_S); + f_iz_S = cii_S * rijz_S; + f_iz_S = fnma(cik_S, rkjz_S, f_iz_S); + f_kx_S = ckk_S * rkjx_S; + f_kx_S = fnma(cik_S, rijx_S, f_kx_S); + f_ky_S = ckk_S * rkjy_S; + f_ky_S = fnma(cik_S, rijy_S, f_ky_S); + f_kz_S = ckk_S * rkjz_S; + f_kz_S = fnma(cik_S, rijz_S, f_kz_S); + + transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_ix_S, f_iy_S, f_iz_S); + transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, + f_iz_S + f_kz_S); + transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_kx_S, f_ky_S, f_kz_S); } return 0; @@ -1062,14 +1134,20 @@ angles(int nbonds, #endif // GMX_SIMD_HAVE_REAL -template -real linear_angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real linear_angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, m, ai, aj, ak, t1, t2, type; rvec f_i, f_j, f_k; @@ -1077,9 +1155,9 @@ real linear_angles(int nbonds, ivec jt, dt_ij, dt_kj; rvec r_ij, r_kj, r_ik, dx; - L1 = 1-lambda; + L1 = 1 - lambda; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -1088,12 +1166,12 @@ real linear_angles(int nbonds, kA = forceparams[type].linangle.klinA; kB = forceparams[type].linangle.klinB; - klin = L1*kA + lambda*kB; + klin = L1 * kA + lambda * kB; - aA = forceparams[type].linangle.aA; - aB = forceparams[type].linangle.aB; - a = L1*aA+lambda*aB; - b = 1-a; + aA = forceparams[type].linangle.aA; + aB = forceparams[type].linangle.aB; + a = L1 * aA + lambda * aB; + b = 1 - a; t1 = pbc_rvec_sub(pbc, x[ai], x[aj], r_ij); t2 = pbc_rvec_sub(pbc, x[ak], x[aj], r_kj); @@ -1102,18 +1180,18 @@ real linear_angles(int nbonds, dr2 = 0; for (m = 0; (m < DIM); m++) { - dr = -a * r_ij[m] - b * r_kj[m]; - dr2 += dr*dr; - dx[m] = dr; - f_i[m] = a*klin*dr; - f_k[m] = b*klin*dr; - f_j[m] = -(f_i[m]+f_k[m]); + dr = -a * r_ij[m] - b * r_kj[m]; + dr2 += dr * dr; + dx[m] = dr; + f_i[m] = a * klin * dr; + f_k[m] = b * klin * dr; + f_j[m] = -(f_i[m] + f_k[m]); f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; } - va = 0.5*klin*dr2; - *dvdlambda += 0.5*(kB-kA)*dr2 + klin*(aB-aA)*iprod(dx, r_ik); + va = 0.5 * klin * dr2; + *dvdlambda += 0.5 * (kB - kA) * dr2 + klin * (aB - aA) * iprod(dx, r_ik); vtot += va; @@ -1132,19 +1210,25 @@ real linear_angles(int nbonds, rvec_inc(fshift[CENTRAL], f_j); rvec_inc(fshift[t2], f_k); } - } /* 57 TOTAL */ + } /* 57 TOTAL */ return vtot; } -template +template std::enable_if_t -urey_bradley(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +urey_bradley(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, m, ai, aj, ak, t1, t2, type, ki; rvec r_ij, r_kj, r_ik; @@ -1154,34 +1238,33 @@ urey_bradley(int nbonds, ivec jt, dt_ij, dt_kj, dt_ik; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { - type = forceatoms[i++]; - ai = forceatoms[i++]; - aj = forceatoms[i++]; - ak = forceatoms[i++]; - th0A = forceparams[type].u_b.thetaA*DEG2RAD; - kthA = forceparams[type].u_b.kthetaA; - r13A = forceparams[type].u_b.r13A; - kUBA = forceparams[type].u_b.kUBA; - th0B = forceparams[type].u_b.thetaB*DEG2RAD; - kthB = forceparams[type].u_b.kthetaB; - r13B = forceparams[type].u_b.r13B; - kUBB = forceparams[type].u_b.kUBB; - - theta = bond_angle(x[ai], x[aj], x[ak], pbc, - r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ + type = forceatoms[i++]; + ai = forceatoms[i++]; + aj = forceatoms[i++]; + ak = forceatoms[i++]; + th0A = forceparams[type].u_b.thetaA * DEG2RAD; + kthA = forceparams[type].u_b.kthetaA; + r13A = forceparams[type].u_b.r13A; + kUBA = forceparams[type].u_b.kUBA; + th0B = forceparams[type].u_b.thetaB * DEG2RAD; + kthB = forceparams[type].u_b.kthetaB; + r13B = forceparams[type].u_b.r13B; + kUBB = forceparams[type].u_b.kUBB; + + theta = bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ *dvdlambda += harmonic(kthA, kthB, th0A, th0B, theta, lambda, &va, &dVdt); /* 21 */ - vtot += va; + vtot += va; - ki = pbc_rvec_sub(pbc, x[ai], x[ak], r_ik); /* 3 */ - dr2 = iprod(r_ik, r_ik); /* 5 */ - dr = dr2*gmx::invsqrt(dr2); /* 10 */ + ki = pbc_rvec_sub(pbc, x[ai], x[ak], r_ik); /* 3 */ + dr2 = iprod(r_ik, r_ik); /* 5 */ + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ *dvdlambda += harmonic(kUBA, kUBB, r13A, r13B, dr, lambda, &vbond, &fbond); /* 19 */ - cos_theta2 = gmx::square(cos_theta); /* 1 */ + cos_theta2 = gmx::square(cos_theta); /* 1 */ if (cos_theta2 < 1) { real st, sth; @@ -1189,20 +1272,20 @@ urey_bradley(int nbonds, real nrkj2, nrij2; rvec f_i, f_j, f_k; - st = dVdt*gmx::invsqrt(1 - cos_theta2); /* 12 */ - sth = st*cos_theta; /* 1 */ - nrkj2 = iprod(r_kj, r_kj); /* 5 */ + st = dVdt * gmx::invsqrt(1 - cos_theta2); /* 12 */ + sth = st * cos_theta; /* 1 */ + nrkj2 = iprod(r_kj, r_kj); /* 5 */ nrij2 = iprod(r_ij, r_ij); - cik = st*gmx::invsqrt(nrkj2*nrij2); /* 12 */ - cii = sth/nrij2; /* 10 */ - ckk = sth/nrkj2; /* 10 */ + cik = st * gmx::invsqrt(nrkj2 * nrij2); /* 12 */ + cii = sth / nrij2; /* 10 */ + ckk = sth / nrkj2; /* 10 */ - for (m = 0; (m < DIM); m++) /* 39 */ + for (m = 0; (m < DIM); m++) /* 39 */ { - f_i[m] = -(cik*r_kj[m]-cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m]-ckk*r_kj[m]); - f_j[m] = -f_i[m]-f_k[m]; + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -1222,14 +1305,14 @@ urey_bradley(int nbonds, rvec_inc(fshift[CENTRAL], f_j); rvec_inc(fshift[t2], f_k); } - } /* 161 TOTAL */ + } /* 161 TOTAL */ /* Time for the bond calculations */ if (dr2 == 0.0) { continue; } - vtot += vbond; /* 1*/ + vtot += vbond; /* 1*/ fbond *= gmx::invsqrt(dr2); /* 6 */ if (computeVirial(flavor) && g) @@ -1237,14 +1320,14 @@ urey_bradley(int nbonds, ivec_sub(SHIFT_IVEC(g, ai), SHIFT_IVEC(g, ak), dt_ik); ki = IVEC2IS(dt_ik); } - for (m = 0; (m < DIM); m++) /* 15 */ + for (m = 0; (m < DIM); m++) /* 15 */ { - fik = fbond*r_ik[m]; - f[ai][m] += fik; - f[ak][m] -= fik; + fik = fbond * r_ik[m]; + f[ai][m] += fik; + f[ak][m] -= fik; if (computeVirial(flavor)) { - fshift[ki][m] += fik; + fshift[ki][m] += fik; fshift[CENTRAL][m] -= fik; } } @@ -1257,27 +1340,33 @@ urey_bradley(int nbonds, /* As urey_bradley, but using SIMD to calculate many potentials at once. * This routines does not calculate energies and shift forces. */ -template +template std::enable_if_t -urey_bradley(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec gmx_unused fshift[], - const t_pbc *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +urey_bradley(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec gmx_unused fshift[], + const t_pbc* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - constexpr int nfa1 = 4; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) real coeff[4*GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + constexpr int nfa1 = 4; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real coeff[4 * GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; set_pbc_simd(pbc, pbc_simd); /* nbonds is the number of angles times nfa1, here we step GMX_SIMD_REAL_WIDTH angles */ - for (int i = 0; i < nbonds; i += GMX_SIMD_REAL_WIDTH*nfa1) + for (int i = 0; i < nbonds; i += GMX_SIMD_REAL_WIDTH * nfa1) { /* Collect atoms for GMX_SIMD_REAL_WIDTH angles. * iu indexes into forceatoms, we should not let iu go beyond nbonds. @@ -1285,18 +1374,18 @@ urey_bradley(int nbonds, int iu = i; for (int s = 0; s < GMX_SIMD_REAL_WIDTH; s++) { - const int type = forceatoms[iu]; - ai[s] = forceatoms[iu+1]; - aj[s] = forceatoms[iu+2]; - ak[s] = forceatoms[iu+3]; + const int type = forceatoms[iu]; + ai[s] = forceatoms[iu + 1]; + aj[s] = forceatoms[iu + 2]; + ak[s] = forceatoms[iu + 3]; /* At the end fill the arrays with the last atoms and 0 params */ - if (i + s*nfa1 < nbonds) + if (i + s * nfa1 < nbonds) { - coeff[s] = forceparams[type].u_b.kthetaA; - coeff[GMX_SIMD_REAL_WIDTH+s] = forceparams[type].u_b.thetaA; - coeff[GMX_SIMD_REAL_WIDTH*2+s] = forceparams[type].u_b.kUBA; - coeff[GMX_SIMD_REAL_WIDTH*3+s] = forceparams[type].u_b.r13A; + coeff[s] = forceparams[type].u_b.kthetaA; + coeff[GMX_SIMD_REAL_WIDTH + s] = forceparams[type].u_b.thetaA; + coeff[GMX_SIMD_REAL_WIDTH * 2 + s] = forceparams[type].u_b.kUBA; + coeff[GMX_SIMD_REAL_WIDTH * 3 + s] = forceparams[type].u_b.r13A; if (iu + nfa1 < nbonds) { @@ -1305,10 +1394,10 @@ urey_bradley(int nbonds, } else { - coeff[s] = 0; - coeff[GMX_SIMD_REAL_WIDTH+s] = 0; - coeff[GMX_SIMD_REAL_WIDTH*2+s] = 0; - coeff[GMX_SIMD_REAL_WIDTH*3+s] = 0; + coeff[s] = 0; + coeff[GMX_SIMD_REAL_WIDTH + s] = 0; + coeff[GMX_SIMD_REAL_WIDTH * 2 + s] = 0; + coeff[GMX_SIMD_REAL_WIDTH * 3 + s] = 0; } } @@ -1317,43 +1406,41 @@ urey_bradley(int nbonds, SimdReal xk_S, yk_S, zk_S; /* Store the non PBC corrected distances packed and aligned */ - gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); - SimdReal rijx_S = xi_S - xj_S; - SimdReal rijy_S = yi_S - yj_S; - SimdReal rijz_S = zi_S - zj_S; - SimdReal rkjx_S = xk_S - xj_S; - SimdReal rkjy_S = yk_S - yj_S; - SimdReal rkjz_S = zk_S - zj_S; - SimdReal rikx_S = xi_S - xk_S; - SimdReal riky_S = yi_S - yk_S; - SimdReal rikz_S = zi_S - zk_S; + gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); + SimdReal rijx_S = xi_S - xj_S; + SimdReal rijy_S = yi_S - yj_S; + SimdReal rijz_S = zi_S - zj_S; + SimdReal rkjx_S = xk_S - xj_S; + SimdReal rkjy_S = yk_S - yj_S; + SimdReal rkjz_S = zk_S - zj_S; + SimdReal rikx_S = xi_S - xk_S; + SimdReal riky_S = yi_S - yk_S; + SimdReal rikz_S = zi_S - zk_S; const SimdReal ktheta_S = load(coeff); - const SimdReal theta0_S = load(coeff+GMX_SIMD_REAL_WIDTH) * DEG2RAD; - const SimdReal kUB_S = load(coeff+2*GMX_SIMD_REAL_WIDTH); - const SimdReal r13_S = load(coeff+3*GMX_SIMD_REAL_WIDTH); + const SimdReal theta0_S = load(coeff + GMX_SIMD_REAL_WIDTH) * DEG2RAD; + const SimdReal kUB_S = load(coeff + 2 * GMX_SIMD_REAL_WIDTH); + const SimdReal r13_S = load(coeff + 3 * GMX_SIMD_REAL_WIDTH); pbc_correct_dx_simd(&rijx_S, &rijy_S, &rijz_S, pbc_simd); pbc_correct_dx_simd(&rkjx_S, &rkjy_S, &rkjz_S, pbc_simd); pbc_correct_dx_simd(&rikx_S, &riky_S, &rikz_S, pbc_simd); - const SimdReal rij_rkj_S = iprod(rijx_S, rijy_S, rijz_S, - rkjx_S, rkjy_S, rkjz_S); + const SimdReal rij_rkj_S = iprod(rijx_S, rijy_S, rijz_S, rkjx_S, rkjy_S, rkjz_S); - const SimdReal dr2_S = iprod(rikx_S, riky_S, rikz_S, - rikx_S, riky_S, rikz_S); + const SimdReal dr2_S = iprod(rikx_S, riky_S, rikz_S, rikx_S, riky_S, rikz_S); - const SimdReal nrij2_S = norm2(rijx_S, rijy_S, rijz_S); - const SimdReal nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); + const SimdReal nrij2_S = norm2(rijx_S, rijy_S, rijz_S); + const SimdReal nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); - const SimdReal nrij_1_S = invsqrt(nrij2_S); - const SimdReal nrkj_1_S = invsqrt(nrkj2_S); - const SimdReal invdr2_S = invsqrt(dr2_S); - const SimdReal dr_S = dr2_S*invdr2_S; + const SimdReal nrij_1_S = invsqrt(nrij2_S); + const SimdReal nrkj_1_S = invsqrt(nrkj2_S); + const SimdReal invdr2_S = invsqrt(dr2_S); + const SimdReal dr_S = dr2_S * invdr2_S; - constexpr real min_one_plus_eps = -1.0 + 2.0*GMX_REAL_EPS; // Smallest number > -1 + constexpr real min_one_plus_eps = -1.0 + 2.0 * GMX_REAL_EPS; // Smallest number > -1 /* To allow for 180 degrees, we take the max of cos and -1 + 1bit, * so we can safely get the 1/sin from 1/sqrt(1 - cos^2). @@ -1362,33 +1449,34 @@ urey_bradley(int nbonds, * Note that we do not take precautions for cos(0)=1, so the bonds * in an angle should not align at an angle of 0 degrees. */ - const SimdReal cos_S = max(rij_rkj_S * nrij_1_S * nrkj_1_S, min_one_plus_eps); - - const SimdReal theta_S = acos(cos_S); - const SimdReal invsin_S = invsqrt( 1.0 - cos_S * cos_S ); - const SimdReal st_S = ktheta_S * (theta0_S - theta_S) * invsin_S; - const SimdReal sth_S = st_S * cos_S; - - const SimdReal cik_S = st_S * nrij_1_S * nrkj_1_S; - const SimdReal cii_S = sth_S * nrij_1_S * nrij_1_S; - const SimdReal ckk_S = sth_S * nrkj_1_S * nrkj_1_S; - - const SimdReal sUB_S = kUB_S * (r13_S - dr_S) * invdr2_S; - - const SimdReal f_ikx_S = sUB_S * rikx_S; - const SimdReal f_iky_S = sUB_S * riky_S; - const SimdReal f_ikz_S = sUB_S * rikz_S; - - const SimdReal f_ix_S = fnma(cik_S, rkjx_S, cii_S * rijx_S) + f_ikx_S; - const SimdReal f_iy_S = fnma(cik_S, rkjy_S, cii_S * rijy_S) + f_iky_S; - const SimdReal f_iz_S = fnma(cik_S, rkjz_S, cii_S * rijz_S) + f_ikz_S; - const SimdReal f_kx_S = fnma(cik_S, rijx_S, ckk_S * rkjx_S) - f_ikx_S; - const SimdReal f_ky_S = fnma(cik_S, rijy_S, ckk_S * rkjy_S) - f_iky_S; - const SimdReal f_kz_S = fnma(cik_S, rijz_S, ckk_S * rkjz_S) - f_ikz_S; - - transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_ix_S, f_iy_S, f_iz_S); - transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, f_iz_S + f_kz_S); - transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_kx_S, f_ky_S, f_kz_S); + const SimdReal cos_S = max(rij_rkj_S * nrij_1_S * nrkj_1_S, min_one_plus_eps); + + const SimdReal theta_S = acos(cos_S); + const SimdReal invsin_S = invsqrt(1.0 - cos_S * cos_S); + const SimdReal st_S = ktheta_S * (theta0_S - theta_S) * invsin_S; + const SimdReal sth_S = st_S * cos_S; + + const SimdReal cik_S = st_S * nrij_1_S * nrkj_1_S; + const SimdReal cii_S = sth_S * nrij_1_S * nrij_1_S; + const SimdReal ckk_S = sth_S * nrkj_1_S * nrkj_1_S; + + const SimdReal sUB_S = kUB_S * (r13_S - dr_S) * invdr2_S; + + const SimdReal f_ikx_S = sUB_S * rikx_S; + const SimdReal f_iky_S = sUB_S * riky_S; + const SimdReal f_ikz_S = sUB_S * rikz_S; + + const SimdReal f_ix_S = fnma(cik_S, rkjx_S, cii_S * rijx_S) + f_ikx_S; + const SimdReal f_iy_S = fnma(cik_S, rkjy_S, cii_S * rijy_S) + f_iky_S; + const SimdReal f_iz_S = fnma(cik_S, rkjz_S, cii_S * rijz_S) + f_ikz_S; + const SimdReal f_kx_S = fnma(cik_S, rijx_S, ckk_S * rkjx_S) - f_ikx_S; + const SimdReal f_ky_S = fnma(cik_S, rijy_S, ckk_S * rkjy_S) - f_iky_S; + const SimdReal f_kz_S = fnma(cik_S, rijz_S, ckk_S * rkjz_S) - f_ikz_S; + + transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_ix_S, f_iy_S, f_iz_S); + transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_ix_S + f_kx_S, f_iy_S + f_ky_S, + f_iz_S + f_kz_S); + transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_kx_S, f_ky_S, f_kz_S); } return 0; @@ -1396,14 +1484,20 @@ urey_bradley(int nbonds, #endif // GMX_SIMD_HAVE_REAL -template -real quartic_angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real quartic_angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, j, ai, aj, ak, t1, t2, type; rvec r_ij, r_kj; @@ -1411,33 +1505,32 @@ real quartic_angles(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; ak = forceatoms[i++]; - theta = bond_angle(x[ai], x[aj], x[ak], pbc, - r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ + theta = bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ - dt = theta - forceparams[type].qangle.theta*DEG2RAD; /* 2 */ + dt = theta - forceparams[type].qangle.theta * DEG2RAD; /* 2 */ dVdt = 0; va = forceparams[type].qangle.c[0]; dtp = 1.0; for (j = 1; j <= 4; j++) { - c = forceparams[type].qangle.c[j]; - dVdt -= j*c*dtp; - dtp *= dt; - va += c*dtp; + c = forceparams[type].qangle.c[j]; + dVdt -= j * c * dtp; + dtp *= dt; + va += c * dtp; } /* 20 */ vtot += va; - cos_theta2 = gmx::square(cos_theta); /* 1 */ + cos_theta2 = gmx::square(cos_theta); /* 1 */ if (cos_theta2 < 1) { int m; @@ -1446,20 +1539,20 @@ real quartic_angles(int nbonds, real nrkj2, nrij2; rvec f_i, f_j, f_k; - st = dVdt*gmx::invsqrt(1 - cos_theta2); /* 12 */ - sth = st*cos_theta; /* 1 */ - nrkj2 = iprod(r_kj, r_kj); /* 5 */ + st = dVdt * gmx::invsqrt(1 - cos_theta2); /* 12 */ + sth = st * cos_theta; /* 1 */ + nrkj2 = iprod(r_kj, r_kj); /* 5 */ nrij2 = iprod(r_ij, r_ij); - cik = st*gmx::invsqrt(nrkj2*nrij2); /* 12 */ - cii = sth/nrij2; /* 10 */ - ckk = sth/nrkj2; /* 10 */ + cik = st * gmx::invsqrt(nrkj2 * nrij2); /* 12 */ + cii = sth / nrij2; /* 10 */ + ckk = sth / nrkj2; /* 10 */ - for (m = 0; (m < DIM); m++) /* 39 */ + for (m = 0; (m < DIM); m++) /* 39 */ { - f_i[m] = -(cik*r_kj[m]-cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m]-ckk*r_kj[m]); - f_j[m] = -f_i[m]-f_k[m]; + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -1480,7 +1573,7 @@ real quartic_angles(int nbonds, rvec_inc(fshift[CENTRAL], f_j); rvec_inc(fshift[t2], f_k); } - } /* 153 TOTAL */ + } /* 153 TOTAL */ } return vtot; } @@ -1492,17 +1585,23 @@ real quartic_angles(int nbonds, * also calculates the pre-factor required for the dihedral force update. * Note that bv and buf should be register aligned. */ -inline void -dih_angle_simd(const rvec *x, - const int *ai, const int *aj, const int *ak, const int *al, - const real *pbc_simd, - SimdReal *phi_S, - SimdReal *mx_S, SimdReal *my_S, SimdReal *mz_S, - SimdReal *nx_S, SimdReal *ny_S, SimdReal *nz_S, - SimdReal *nrkj_m2_S, - SimdReal *nrkj_n2_S, - SimdReal *p_S, - SimdReal *q_S) +inline void dih_angle_simd(const rvec* x, + const int* ai, + const int* aj, + const int* ak, + const int* al, + const real* pbc_simd, + SimdReal* phi_S, + SimdReal* mx_S, + SimdReal* my_S, + SimdReal* mz_S, + SimdReal* nx_S, + SimdReal* ny_S, + SimdReal* nz_S, + SimdReal* nrkj_m2_S, + SimdReal* nrkj_n2_S, + SimdReal* p_S, + SimdReal* q_S) { SimdReal xi_S, yi_S, zi_S; SimdReal xj_S, yj_S, zj_S; @@ -1524,16 +1623,16 @@ dih_angle_simd(const rvec *x, /* Used to avoid division by zero. * We take into acount that we multiply the result by real_eps_S. */ - nrkj2_min_S = SimdReal(GMX_REAL_MIN/(2*GMX_REAL_EPS)); + nrkj2_min_S = SimdReal(GMX_REAL_MIN / (2 * GMX_REAL_EPS)); /* The value of the last significant bit (GMX_REAL_EPS is half of that) */ - real_eps_S = SimdReal(2*GMX_REAL_EPS); + real_eps_S = SimdReal(2 * GMX_REAL_EPS); /* Store the non PBC corrected distances packed and aligned */ - gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); - gatherLoadUTranspose<3>(reinterpret_cast(x), al, &xl_S, &yl_S, &zl_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi_S, &yi_S, &zi_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj_S, &yj_S, &zj_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), ak, &xk_S, &yk_S, &zk_S); + gatherLoadUTranspose<3>(reinterpret_cast(x), al, &xl_S, &yl_S, &zl_S); rijx_S = xi_S - xj_S; rijy_S = yi_S - yj_S; rijz_S = zi_S - zj_S; @@ -1548,42 +1647,35 @@ dih_angle_simd(const rvec *x, pbc_correct_dx_simd(&rkjx_S, &rkjy_S, &rkjz_S, pbc_simd); pbc_correct_dx_simd(&rklx_S, &rkly_S, &rklz_S, pbc_simd); - cprod(rijx_S, rijy_S, rijz_S, - rkjx_S, rkjy_S, rkjz_S, - mx_S, my_S, mz_S); + cprod(rijx_S, rijy_S, rijz_S, rkjx_S, rkjy_S, rkjz_S, mx_S, my_S, mz_S); - cprod(rkjx_S, rkjy_S, rkjz_S, - rklx_S, rkly_S, rklz_S, - nx_S, ny_S, nz_S); + cprod(rkjx_S, rkjy_S, rkjz_S, rklx_S, rkly_S, rklz_S, nx_S, ny_S, nz_S); - cprod(*mx_S, *my_S, *mz_S, - *nx_S, *ny_S, *nz_S, - &cx_S, &cy_S, &cz_S); + cprod(*mx_S, *my_S, *mz_S, *nx_S, *ny_S, *nz_S, &cx_S, &cy_S, &cz_S); - cn_S = sqrt(norm2(cx_S, cy_S, cz_S)); + cn_S = sqrt(norm2(cx_S, cy_S, cz_S)); - s_S = iprod(*mx_S, *my_S, *mz_S, *nx_S, *ny_S, *nz_S); + s_S = iprod(*mx_S, *my_S, *mz_S, *nx_S, *ny_S, *nz_S); /* Determine the dihedral angle, the sign might need correction */ - *phi_S = atan2(cn_S, s_S); + *phi_S = atan2(cn_S, s_S); - ipr_S = iprod(rijx_S, rijy_S, rijz_S, - *nx_S, *ny_S, *nz_S); + ipr_S = iprod(rijx_S, rijy_S, rijz_S, *nx_S, *ny_S, *nz_S); - iprm_S = norm2(*mx_S, *my_S, *mz_S); - iprn_S = norm2(*nx_S, *ny_S, *nz_S); + iprm_S = norm2(*mx_S, *my_S, *mz_S); + iprn_S = norm2(*nx_S, *ny_S, *nz_S); - nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); + nrkj2_S = norm2(rkjx_S, rkjy_S, rkjz_S); /* Avoid division by zero. When zero, the result is multiplied by 0 * anyhow, so the 3 max below do not affect the final result. */ - nrkj2_S = max(nrkj2_S, nrkj2_min_S); - nrkj_1_S = invsqrt(nrkj2_S); - nrkj_2_S = nrkj_1_S * nrkj_1_S; - nrkj_S = nrkj2_S * nrkj_1_S; + nrkj2_S = max(nrkj2_S, nrkj2_min_S); + nrkj_1_S = invsqrt(nrkj2_S); + nrkj_2_S = nrkj_1_S * nrkj_1_S; + nrkj_S = nrkj2_S * nrkj_1_S; - toler_S = nrkj2_S * real_eps_S; + toler_S = nrkj2_S * real_eps_S; /* Here the plain-C code uses a conditional, but we can't do that in SIMD. * So we take a max with the tolerance instead. Since we multiply with @@ -1595,24 +1687,37 @@ dih_angle_simd(const rvec *x, *nrkj_n2_S = nrkj_S * inv(iprn_S); /* Set sign of phi_S with the sign of ipr_S; phi_S is currently positive */ - *phi_S = copysign(*phi_S, ipr_S); - *p_S = iprod(rijx_S, rijy_S, rijz_S, rkjx_S, rkjy_S, rkjz_S); - *p_S = *p_S * nrkj_2_S; + *phi_S = copysign(*phi_S, ipr_S); + *p_S = iprod(rijx_S, rijy_S, rijz_S, rkjx_S, rkjy_S, rkjz_S); + *p_S = *p_S * nrkj_2_S; - *q_S = iprod(rklx_S, rkly_S, rklz_S, rkjx_S, rkjy_S, rkjz_S); - *q_S = *q_S * nrkj_2_S; + *q_S = iprod(rklx_S, rkly_S, rklz_S, rkjx_S, rkjy_S, rkjz_S); + *q_S = *q_S * nrkj_2_S; } #endif // GMX_SIMD_HAVE_REAL -} // namespace +} // namespace -template -void do_dih_fup(int i, int j, int k, int l, real ddphi, - rvec r_ij, rvec r_kj, rvec r_kl, - rvec m, rvec n, rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - const rvec x[], int t1, int t2, int t3) +template +void do_dih_fup(int i, + int j, + int k, + int l, + real ddphi, + rvec r_ij, + rvec r_kj, + rvec r_kl, + rvec m, + rvec n, + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + const rvec x[], + int t1, + int t2, + int t3) { /* 143 FLOPS */ rvec f_i, f_j, f_k, f_l; @@ -1624,29 +1729,29 @@ void do_dih_fup(int i, int j, int k, int l, real ddphi, iprm = iprod(m, m); /* 5 */ iprn = iprod(n, n); /* 5 */ nrkj2 = iprod(r_kj, r_kj); /* 5 */ - toler = nrkj2*GMX_REAL_EPS; + toler = nrkj2 * GMX_REAL_EPS; if ((iprm > toler) && (iprn > toler)) { - nrkj_1 = gmx::invsqrt(nrkj2); /* 10 */ - nrkj_2 = nrkj_1*nrkj_1; /* 1 */ - nrkj = nrkj2*nrkj_1; /* 1 */ - a = -ddphi*nrkj/iprm; /* 11 */ - svmul(a, m, f_i); /* 3 */ - b = ddphi*nrkj/iprn; /* 11 */ - svmul(b, n, f_l); /* 3 */ - p = iprod(r_ij, r_kj); /* 5 */ - p *= nrkj_2; /* 1 */ - q = iprod(r_kl, r_kj); /* 5 */ - q *= nrkj_2; /* 1 */ - svmul(p, f_i, uvec); /* 3 */ - svmul(q, f_l, vvec); /* 3 */ - rvec_sub(uvec, vvec, svec); /* 3 */ - rvec_sub(f_i, svec, f_j); /* 3 */ - rvec_add(f_l, svec, f_k); /* 3 */ - rvec_inc(f[i], f_i); /* 3 */ - rvec_dec(f[j], f_j); /* 3 */ - rvec_dec(f[k], f_k); /* 3 */ - rvec_inc(f[l], f_l); /* 3 */ + nrkj_1 = gmx::invsqrt(nrkj2); /* 10 */ + nrkj_2 = nrkj_1 * nrkj_1; /* 1 */ + nrkj = nrkj2 * nrkj_1; /* 1 */ + a = -ddphi * nrkj / iprm; /* 11 */ + svmul(a, m, f_i); /* 3 */ + b = ddphi * nrkj / iprn; /* 11 */ + svmul(b, n, f_l); /* 3 */ + p = iprod(r_ij, r_kj); /* 5 */ + p *= nrkj_2; /* 1 */ + q = iprod(r_kl, r_kj); /* 5 */ + q *= nrkj_2; /* 1 */ + svmul(p, f_i, uvec); /* 3 */ + svmul(q, f_l, vvec); /* 3 */ + rvec_sub(uvec, vvec, svec); /* 3 */ + rvec_sub(f_i, svec, f_j); /* 3 */ + rvec_add(f_l, svec, f_k); /* 3 */ + rvec_inc(f[i], f_i); /* 3 */ + rvec_dec(f[j], f_j); /* 3 */ + rvec_dec(f[k], f_k); /* 3 */ + rvec_inc(f[l], f_l); /* 3 */ if (computeVirial(flavor)) { @@ -1683,12 +1788,19 @@ namespace #if GMX_SIMD_HAVE_REAL /* As do_dih_fup_noshiftf above, but with SIMD and pre-calculated pre-factors */ -inline void gmx_simdcall -do_dih_fup_noshiftf_simd(const int *ai, const int *aj, const int *ak, const int *al, - SimdReal p, SimdReal q, - SimdReal f_i_x, SimdReal f_i_y, SimdReal f_i_z, - SimdReal mf_l_x, SimdReal mf_l_y, SimdReal mf_l_z, - rvec4 f[]) +inline void gmx_simdcall do_dih_fup_noshiftf_simd(const int* ai, + const int* aj, + const int* ak, + const int* al, + SimdReal p, + SimdReal q, + SimdReal f_i_x, + SimdReal f_i_y, + SimdReal f_i_z, + SimdReal mf_l_x, + SimdReal mf_l_y, + SimdReal mf_l_z, + rvec4 f[]) { SimdReal sx = p * f_i_x + q * mf_l_x; SimdReal sy = p * f_i_y + q * mf_l_y; @@ -1699,10 +1811,10 @@ do_dih_fup_noshiftf_simd(const int *ai, const int *aj, const int *ak, const int SimdReal f_k_x = mf_l_x - sx; SimdReal f_k_y = mf_l_y - sy; SimdReal f_k_z = mf_l_z - sz; - transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_i_x, f_i_y, f_i_z); - transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_j_x, f_j_y, f_j_z); - transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_k_x, f_k_y, f_k_z); - transposeScatterDecrU<4>(reinterpret_cast(f), al, mf_l_x, mf_l_y, mf_l_z); + transposeScatterIncrU<4>(reinterpret_cast(f), ai, f_i_x, f_i_y, f_i_z); + transposeScatterDecrU<4>(reinterpret_cast(f), aj, f_j_x, f_j_y, f_j_z); + transposeScatterIncrU<4>(reinterpret_cast(f), ak, f_k_x, f_k_y, f_k_z); + transposeScatterDecrU<4>(reinterpret_cast(f), al, mf_l_x, mf_l_y, mf_l_z); } #endif // GMX_SIMD_HAVE_REAL @@ -1711,24 +1823,23 @@ do_dih_fup_noshiftf_simd(const int *ai, const int *aj, const int *ak, const int * With the appropriate kernel flavor, also computes and accumulates * the energy and dV/dlambda. */ -template -real dopdihs(real cpA, real cpB, real phiA, real phiB, int mult, - real phi, real lambda, real *V, real *dvdlambda) +template +real dopdihs(real cpA, real cpB, real phiA, real phiB, int mult, real phi, real lambda, real* V, real* dvdlambda) { - const real L1 = 1.0 - lambda; - const real ph0 = (L1*phiA + lambda*phiB)*DEG2RAD; - const real dph0 = (phiB - phiA)*DEG2RAD; - const real cp = L1*cpA + lambda*cpB; + const real L1 = 1.0 - lambda; + const real ph0 = (L1 * phiA + lambda * phiB) * DEG2RAD; + const real dph0 = (phiB - phiA) * DEG2RAD; + const real cp = L1 * cpA + lambda * cpB; - const real mdphi = mult*phi - ph0; + const real mdphi = mult * phi - ph0; const real sdphi = std::sin(mdphi); - const real ddphi = -cp*mult*sdphi; + const real ddphi = -cp * mult * sdphi; if (computeEnergy(flavor)) { - const real v1 = 1 + std::cos(mdphi); - *V += cp*v1; + const real v1 = 1 + std::cos(mdphi); + *V += cp * v1; - *dvdlambda += (cpB - cpA)*v1 + cp*dph0*sdphi; + *dvdlambda += (cpB - cpA) * v1 + cp * dph0 * sdphi; } return ddphi; @@ -1736,22 +1847,21 @@ real dopdihs(real cpA, real cpB, real phiA, real phiB, int mult, } /*! \brief Similar to \p dopdihs(), except for a minus sign and a different treatment of mult/phi0 */ -real dopdihs_min(real cpA, real cpB, real phiA, real phiB, int mult, - real phi, real lambda, real *V, real *F) +real dopdihs_min(real cpA, real cpB, real phiA, real phiB, int mult, real phi, real lambda, real* V, real* F) { real v, dvdlambda, mdphi, v1, sdphi, ddphi; real L1 = 1.0 - lambda; - real ph0 = (L1*phiA + lambda*phiB)*DEG2RAD; - real dph0 = (phiB - phiA)*DEG2RAD; - real cp = L1*cpA + lambda*cpB; + real ph0 = (L1 * phiA + lambda * phiB) * DEG2RAD; + real dph0 = (phiB - phiA) * DEG2RAD; + real cp = L1 * cpA + lambda * cpB; - mdphi = mult*(phi-ph0); + mdphi = mult * (phi - ph0); sdphi = std::sin(mdphi); - ddphi = cp*mult*sdphi; - v1 = 1.0-std::cos(mdphi); - v = cp*v1; + ddphi = cp * mult * sdphi; + v1 = 1.0 - std::cos(mdphi); + v = cp * v1; - dvdlambda = (cpB-cpA)*v1 + cp*dph0*sdphi; + dvdlambda = (cpB - cpA) * v1 + cp * dph0 * sdphi; *V = v; *F = ddphi; @@ -1761,30 +1871,36 @@ real dopdihs_min(real cpA, real cpB, real phiA, real phiB, int mult, /* That was 40 flops */ } -template +template std::enable_if_t -pdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +pdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int t1, t2, t3; rvec r_ij, r_kj, r_kl, m, n; real vtot = 0.0; - for (int i = 0; i < nbonds; ) + for (int i = 0; i < nbonds;) { - const int ai = forceatoms[i + 1]; - const int aj = forceatoms[i + 2]; - const int ak = forceatoms[i + 3]; - const int al = forceatoms[i + 4]; + const int ai = forceatoms[i + 1]; + const int aj = forceatoms[i + 2]; + const int ak = forceatoms[i + 3]; + const int al = forceatoms[i + 4]; - const real phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); /* 84 */ + const real phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, + &t2, &t3); /* 84 */ /* Loop over dihedrals working on the same atoms, * so we avoid recalculating angles and distributing forces. @@ -1793,25 +1909,17 @@ pdihs(int nbonds, do { const int type = forceatoms[i]; - ddphi_tot += - dopdihs(forceparams[type].pdihs.cpA, - forceparams[type].pdihs.cpB, - forceparams[type].pdihs.phiA, - forceparams[type].pdihs.phiB, - forceparams[type].pdihs.mult, - phi, lambda, &vtot, dvdlambda); + ddphi_tot += dopdihs(forceparams[type].pdihs.cpA, forceparams[type].pdihs.cpB, + forceparams[type].pdihs.phiA, forceparams[type].pdihs.phiB, + forceparams[type].pdihs.mult, phi, lambda, &vtot, dvdlambda); i += 5; - } - while (i < nbonds && - forceatoms[i + 1] == ai && - forceatoms[i + 2] == aj && - forceatoms[i + 3] == ak && - forceatoms[i + 4] == al); + } while (i < nbonds && forceatoms[i + 1] == ai && forceatoms[i + 2] == aj + && forceatoms[i + 3] == ak && forceatoms[i + 4] == al); - do_dih_fup(ai, aj, ak, al, ddphi_tot, r_ij, r_kj, r_kl, m, n, - f, fshift, pbc, g, x, t1, t2, t3); /* 112 */ - } /* 223 TOTAL */ + do_dih_fup(ai, aj, ak, al, ddphi_tot, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, g, x, + t1, t2, t3); /* 112 */ + } /* 223 TOTAL */ return vtot; } @@ -1819,46 +1927,52 @@ pdihs(int nbonds, #if GMX_SIMD_HAVE_REAL /* As pdihs above, but using SIMD to calculate multiple dihedrals at once */ -template +template std::enable_if_t -pdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec gmx_unused fshift[], - const t_pbc *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +pdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec gmx_unused fshift[], + const t_pbc* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - const int nfa1 = 5; - int i, iu, s; - int type; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t al[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) real buf[3*GMX_SIMD_REAL_WIDTH]; - real *cp, *phi0, *mult; - SimdReal deg2rad_S(DEG2RAD); - SimdReal p_S, q_S; - SimdReal phi0_S, phi_S; - SimdReal mx_S, my_S, mz_S; - SimdReal nx_S, ny_S, nz_S; - SimdReal nrkj_m2_S, nrkj_n2_S; - SimdReal cp_S, mdphi_S, mult_S; - SimdReal sin_S, cos_S; - SimdReal mddphi_S; - SimdReal sf_i_S, msf_l_S; - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + const int nfa1 = 5; + int i, iu, s; + int type; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t al[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real buf[3 * GMX_SIMD_REAL_WIDTH]; + real * cp, *phi0, *mult; + SimdReal deg2rad_S(DEG2RAD); + SimdReal p_S, q_S; + SimdReal phi0_S, phi_S; + SimdReal mx_S, my_S, mz_S; + SimdReal nx_S, ny_S, nz_S; + SimdReal nrkj_m2_S, nrkj_n2_S; + SimdReal cp_S, mdphi_S, mult_S; + SimdReal sin_S, cos_S; + SimdReal mddphi_S; + SimdReal sf_i_S, msf_l_S; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; /* Extract aligned pointer for parameters and variables */ - cp = buf + 0*GMX_SIMD_REAL_WIDTH; - phi0 = buf + 1*GMX_SIMD_REAL_WIDTH; - mult = buf + 2*GMX_SIMD_REAL_WIDTH; + cp = buf + 0 * GMX_SIMD_REAL_WIDTH; + phi0 = buf + 1 * GMX_SIMD_REAL_WIDTH; + mult = buf + 2 * GMX_SIMD_REAL_WIDTH; set_pbc_simd(pbc, pbc_simd); /* nbonds is the number of dihedrals times nfa1, here we step GMX_SIMD_REAL_WIDTH dihs */ - for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH*nfa1) + for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH * nfa1) { /* Collect atoms quadruplets for GMX_SIMD_REAL_WIDTH dihedrals. * iu indexes into forceatoms, we should not let iu go beyond nbonds. @@ -1867,13 +1981,13 @@ pdihs(int nbonds, for (s = 0; s < GMX_SIMD_REAL_WIDTH; s++) { type = forceatoms[iu]; - ai[s] = forceatoms[iu+1]; - aj[s] = forceatoms[iu+2]; - ak[s] = forceatoms[iu+3]; - al[s] = forceatoms[iu+4]; + ai[s] = forceatoms[iu + 1]; + aj[s] = forceatoms[iu + 2]; + ak[s] = forceatoms[iu + 3]; + al[s] = forceatoms[iu + 4]; /* At the end fill the arrays with the last atoms and 0 params */ - if (i + s*nfa1 < nbonds) + if (i + s * nfa1 < nbonds) { cp[s] = forceparams[type].pdihs.cpA; phi0[s] = forceparams[type].pdihs.phiA; @@ -1893,19 +2007,14 @@ pdihs(int nbonds, } /* Caclulate GMX_SIMD_REAL_WIDTH dihedral angles at once */ - dih_angle_simd(x, ai, aj, ak, al, pbc_simd, - &phi_S, - &mx_S, &my_S, &mz_S, - &nx_S, &ny_S, &nz_S, - &nrkj_m2_S, - &nrkj_n2_S, - &p_S, &q_S); + dih_angle_simd(x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S, + &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S); - cp_S = load(cp); - phi0_S = load(phi0) * deg2rad_S; - mult_S = load(mult); + cp_S = load(cp); + phi0_S = load(phi0) * deg2rad_S; + mult_S = load(mult); - mdphi_S = fms(mult_S, phi_S, phi0_S); + mdphi_S = fms(mult_S, phi_S, phi0_S); /* Calculate GMX_SIMD_REAL_WIDTH sines at once */ sincos(mdphi_S, &sin_S, &cos_S); @@ -1914,20 +2023,16 @@ pdihs(int nbonds, msf_l_S = mddphi_S * nrkj_n2_S; /* After this m?_S will contain f[i] */ - mx_S = sf_i_S * mx_S; - my_S = sf_i_S * my_S; - mz_S = sf_i_S * mz_S; + mx_S = sf_i_S * mx_S; + my_S = sf_i_S * my_S; + mz_S = sf_i_S * mz_S; /* After this m?_S will contain -f[l] */ - nx_S = msf_l_S * nx_S; - ny_S = msf_l_S * ny_S; - nz_S = msf_l_S * nz_S; - - do_dih_fup_noshiftf_simd(ai, aj, ak, al, - p_S, q_S, - mx_S, my_S, mz_S, - nx_S, ny_S, nz_S, - f); + nx_S = msf_l_S * nx_S; + ny_S = msf_l_S * ny_S; + nz_S = msf_l_S * nz_S; + + do_dih_fup_noshiftf_simd(ai, aj, ak, al, p_S, q_S, mx_S, my_S, mz_S, nx_S, ny_S, nz_S, f); } return 0; @@ -1937,43 +2042,49 @@ pdihs(int nbonds, * the RB potential instead of a harmonic potential. * This function can replace rbdihs() when no energy and virial are needed. */ -template +template std::enable_if_t -rbdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec gmx_unused fshift[], - const t_pbc *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +rbdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec gmx_unused fshift[], + const t_pbc* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - const int nfa1 = 5; - int i, iu, s, j; - int type; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t al[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) real parm[NR_RBDIHS*GMX_SIMD_REAL_WIDTH]; - - SimdReal p_S, q_S; - SimdReal phi_S; - SimdReal ddphi_S, cosfac_S; - SimdReal mx_S, my_S, mz_S; - SimdReal nx_S, ny_S, nz_S; - SimdReal nrkj_m2_S, nrkj_n2_S; - SimdReal parm_S, c_S; - SimdReal sin_S, cos_S; - SimdReal sf_i_S, msf_l_S; - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; - - SimdReal pi_S(M_PI); - SimdReal one_S(1.0); + const int nfa1 = 5; + int i, iu, s, j; + int type; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ak[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t al[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real parm[NR_RBDIHS * GMX_SIMD_REAL_WIDTH]; + + SimdReal p_S, q_S; + SimdReal phi_S; + SimdReal ddphi_S, cosfac_S; + SimdReal mx_S, my_S, mz_S; + SimdReal nx_S, ny_S, nz_S; + SimdReal nrkj_m2_S, nrkj_n2_S; + SimdReal parm_S, c_S; + SimdReal sin_S, cos_S; + SimdReal sf_i_S, msf_l_S; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; + + SimdReal pi_S(M_PI); + SimdReal one_S(1.0); set_pbc_simd(pbc, pbc_simd); /* nbonds is the number of dihedrals times nfa1, here we step GMX_SIMD_REAL_WIDTH dihs */ - for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH*nfa1) + for (i = 0; (i < nbonds); i += GMX_SIMD_REAL_WIDTH * nfa1) { /* Collect atoms quadruplets for GMX_SIMD_REAL_WIDTH dihedrals. * iu indexes into forceatoms, we should not let iu go beyond nbonds. @@ -1982,21 +2093,20 @@ rbdihs(int nbonds, for (s = 0; s < GMX_SIMD_REAL_WIDTH; s++) { type = forceatoms[iu]; - ai[s] = forceatoms[iu+1]; - aj[s] = forceatoms[iu+2]; - ak[s] = forceatoms[iu+3]; - al[s] = forceatoms[iu+4]; + ai[s] = forceatoms[iu + 1]; + aj[s] = forceatoms[iu + 2]; + ak[s] = forceatoms[iu + 3]; + al[s] = forceatoms[iu + 4]; /* At the end fill the arrays with the last atoms and 0 params */ - if (i + s*nfa1 < nbonds) + if (i + s * nfa1 < nbonds) { /* We don't need the first parameter, since that's a constant * which only affects the energies, not the forces. */ for (j = 1; j < NR_RBDIHS; j++) { - parm[j*GMX_SIMD_REAL_WIDTH + s] = - forceparams[type].rbdihs.rbcA[j]; + parm[j * GMX_SIMD_REAL_WIDTH + s] = forceparams[type].rbdihs.rbcA[j]; } if (iu + nfa1 < nbonds) @@ -2008,31 +2118,26 @@ rbdihs(int nbonds, { for (j = 1; j < NR_RBDIHS; j++) { - parm[j*GMX_SIMD_REAL_WIDTH + s] = 0; + parm[j * GMX_SIMD_REAL_WIDTH + s] = 0; } } } /* Caclulate GMX_SIMD_REAL_WIDTH dihedral angles at once */ - dih_angle_simd(x, ai, aj, ak, al, pbc_simd, - &phi_S, - &mx_S, &my_S, &mz_S, - &nx_S, &ny_S, &nz_S, - &nrkj_m2_S, - &nrkj_n2_S, - &p_S, &q_S); + dih_angle_simd(x, ai, aj, ak, al, pbc_simd, &phi_S, &mx_S, &my_S, &mz_S, &nx_S, &ny_S, + &nz_S, &nrkj_m2_S, &nrkj_n2_S, &p_S, &q_S); /* Change to polymer convention */ phi_S = phi_S - pi_S; sincos(phi_S, &sin_S, &cos_S); - ddphi_S = setZero(); - c_S = one_S; - cosfac_S = one_S; + ddphi_S = setZero(); + c_S = one_S; + cosfac_S = one_S; for (j = 1; j < NR_RBDIHS; j++) { - parm_S = load(parm + j*GMX_SIMD_REAL_WIDTH); + parm_S = load(parm + j * GMX_SIMD_REAL_WIDTH); ddphi_S = fma(c_S * parm_S, cosfac_S, ddphi_S); cosfac_S = cosfac_S * cos_S; c_S = c_S + one_S; @@ -2041,26 +2146,22 @@ rbdihs(int nbonds, /* Note that here we do not use the minus sign which is present * in the normal RB code. This is corrected for through (m)sf below. */ - ddphi_S = ddphi_S * sin_S; + ddphi_S = ddphi_S * sin_S; - sf_i_S = ddphi_S * nrkj_m2_S; - msf_l_S = ddphi_S * nrkj_n2_S; + sf_i_S = ddphi_S * nrkj_m2_S; + msf_l_S = ddphi_S * nrkj_n2_S; /* After this m?_S will contain f[i] */ - mx_S = sf_i_S * mx_S; - my_S = sf_i_S * my_S; - mz_S = sf_i_S * mz_S; + mx_S = sf_i_S * mx_S; + my_S = sf_i_S * my_S; + mz_S = sf_i_S * mz_S; /* After this m?_S will contain -f[l] */ - nx_S = msf_l_S * nx_S; - ny_S = msf_l_S * ny_S; - nz_S = msf_l_S * nz_S; - - do_dih_fup_noshiftf_simd(ai, aj, ak, al, - p_S, q_S, - mx_S, my_S, mz_S, - nx_S, ny_S, nz_S, - f); + nx_S = msf_l_S * nx_S; + ny_S = msf_l_S * ny_S; + nz_S = msf_l_S * nz_S; + + do_dih_fup_noshiftf_simd(ai, aj, ak, al, p_S, q_S, mx_S, my_S, mz_S, nx_S, ny_S, nz_S, f); } return 0; @@ -2069,14 +2170,20 @@ rbdihs(int nbonds, #endif // GMX_SIMD_HAVE_REAL -template -real idihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real idihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, type, ai, aj, ak, al; int t1, t2, t3; @@ -2084,10 +2191,10 @@ real idihs(int nbonds, rvec r_ij, r_kj, r_kl, m, n; real L1, kk, dp, dp2, kA, kB, pA, pB, dvdl_term; - L1 = 1.0-lambda; + L1 = 1.0 - lambda; dvdl_term = 0; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2095,8 +2202,7 @@ real idihs(int nbonds, ak = forceatoms[i++]; al = forceatoms[i++]; - phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); /* 84 */ + phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* 84 */ /* phi can jump if phi0 is close to Pi/-Pi, which will cause huge * force changes if we just apply a normal harmonic. @@ -2110,23 +2216,23 @@ real idihs(int nbonds, pA = forceparams[type].harmonic.rA; pB = forceparams[type].harmonic.rB; - kk = L1*kA + lambda*kB; - phi0 = (L1*pA + lambda*pB)*DEG2RAD; - dphi0 = (pB - pA)*DEG2RAD; + kk = L1 * kA + lambda * kB; + phi0 = (L1 * pA + lambda * pB) * DEG2RAD; + dphi0 = (pB - pA) * DEG2RAD; - dp = phi-phi0; + dp = phi - phi0; make_dp_periodic(&dp); - dp2 = dp*dp; + dp2 = dp * dp; - vtot += 0.5*kk*dp2; - ddphi = -kk*dp; + vtot += 0.5 * kk * dp2; + ddphi = -kk * dp; - dvdl_term += 0.5*(kB - kA)*dp2 - kk*dphi0*dp; + dvdl_term += 0.5 * (kB - kA) * dp2 - kk * dphi0 * dp; - do_dih_fup(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, - f, fshift, pbc, g, x, t1, t2, t3); /* 112 */ + do_dih_fup(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, g, x, t1, + t2, t3); /* 112 */ /* 218 TOTAL */ } @@ -2135,36 +2241,41 @@ real idihs(int nbonds, } /*! \brief Computes angle restraints of two different types */ -template -real low_angres(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - gmx_bool bZAxis) +template +real low_angres(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + gmx_bool bZAxis) { int i, m, type, ai, aj, ak, al; int t1, t2; real phi, cos_phi, cos_phi2, vid, vtot, dVdphi; - rvec r_ij, r_kl, f_i, f_k = {0, 0, 0}; + rvec r_ij, r_kl, f_i, f_k = { 0, 0, 0 }; real st, sth, nrij2, nrkl2, c, cij, ckl; ivec dt; t2 = 0; /* avoid warning with gcc-3.3. It is never used uninitialized */ vtot = 0.0; - ak = al = 0; /* to avoid warnings */ - for (i = 0; i < nbonds; ) + ak = al = 0; /* to avoid warnings */ + for (i = 0; i < nbonds;) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - t1 = pbc_rvec_sub(pbc, x[aj], x[ai], r_ij); /* 3 */ + t1 = pbc_rvec_sub(pbc, x[aj], x[ai], r_ij); /* 3 */ if (!bZAxis) { - ak = forceatoms[i++]; - al = forceatoms[i++]; - t2 = pbc_rvec_sub(pbc, x[al], x[ak], r_kl); /* 3 */ + ak = forceatoms[i++]; + al = forceatoms[i++]; + t2 = pbc_rvec_sub(pbc, x[al], x[ak], r_kl); /* 3 */ } else { @@ -2176,35 +2287,32 @@ real low_angres(int nbonds, cos_phi = cos_angle(r_ij, r_kl); /* 25 */ phi = std::acos(cos_phi); /* 10 */ - *dvdlambda += dopdihs_min(forceparams[type].pdihs.cpA, - forceparams[type].pdihs.cpB, - forceparams[type].pdihs.phiA, - forceparams[type].pdihs.phiB, - forceparams[type].pdihs.mult, - phi, lambda, &vid, &dVdphi); /* 40 */ + *dvdlambda += dopdihs_min(forceparams[type].pdihs.cpA, forceparams[type].pdihs.cpB, + forceparams[type].pdihs.phiA, forceparams[type].pdihs.phiB, + forceparams[type].pdihs.mult, phi, lambda, &vid, &dVdphi); /* 40 */ vtot += vid; - cos_phi2 = gmx::square(cos_phi); /* 1 */ + cos_phi2 = gmx::square(cos_phi); /* 1 */ if (cos_phi2 < 1) { - st = -dVdphi*gmx::invsqrt(1 - cos_phi2); /* 12 */ - sth = st*cos_phi; /* 1 */ - nrij2 = iprod(r_ij, r_ij); /* 5 */ - nrkl2 = iprod(r_kl, r_kl); /* 5 */ + st = -dVdphi * gmx::invsqrt(1 - cos_phi2); /* 12 */ + sth = st * cos_phi; /* 1 */ + nrij2 = iprod(r_ij, r_ij); /* 5 */ + nrkl2 = iprod(r_kl, r_kl); /* 5 */ - c = st*gmx::invsqrt(nrij2*nrkl2); /* 11 */ - cij = sth/nrij2; /* 10 */ - ckl = sth/nrkl2; /* 10 */ + c = st * gmx::invsqrt(nrij2 * nrkl2); /* 11 */ + cij = sth / nrij2; /* 10 */ + ckl = sth / nrkl2; /* 10 */ - for (m = 0; m < DIM; m++) /* 18+18 */ + for (m = 0; m < DIM; m++) /* 18+18 */ { - f_i[m] = (c*r_kl[m]-cij*r_ij[m]); + f_i[m] = (c * r_kl[m] - cij * r_ij[m]); f[ai][m] += f_i[m]; f[aj][m] -= f_i[m]; if (!bZAxis) { - f_k[m] = (c*r_ij[m]-ckl*r_kl[m]); + f_k[m] = (c * r_ij[m] - ckl * r_kl[m]); f[ak][m] += f_k[m]; f[al][m] -= f_k[m]; } @@ -2236,40 +2344,58 @@ real low_angres(int nbonds, return vtot; /* 184 / 157 (bZAxis) total */ } -template -real angres(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real angres(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - return low_angres(nbonds, forceatoms, forceparams, x, f, fshift, pbc, g, - lambda, dvdlambda, FALSE); + return low_angres(nbonds, forceatoms, forceparams, x, f, fshift, pbc, g, lambda, + dvdlambda, FALSE); } -template -real angresz(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real angresz(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - return low_angres(nbonds, forceatoms, forceparams, x, f, fshift, pbc, g, - lambda, dvdlambda, TRUE); + return low_angres(nbonds, forceatoms, forceparams, x, f, fshift, pbc, g, lambda, + dvdlambda, TRUE); } -template -real dihres(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real dihres(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { real vtot = 0; int ai, aj, ak, al, i, type, t1, t2, t3; @@ -2277,11 +2403,11 @@ real dihres(int nbonds, real phi, ddphi, ddp, ddp2, dp, d2r, L1; rvec r_ij, r_kj, r_kl, m, n; - L1 = 1.0-lambda; + L1 = 1.0 - lambda; d2r = DEG2RAD; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2289,20 +2415,19 @@ real dihres(int nbonds, ak = forceatoms[i++]; al = forceatoms[i++]; - phi0A = forceparams[type].dihres.phiA*d2r; - dphiA = forceparams[type].dihres.dphiA*d2r; - kfacA = forceparams[type].dihres.kfacA; + phi0A = forceparams[type].dihres.phiA * d2r; + dphiA = forceparams[type].dihres.dphiA * d2r; + kfacA = forceparams[type].dihres.kfacA; - phi0B = forceparams[type].dihres.phiB*d2r; - dphiB = forceparams[type].dihres.dphiB*d2r; - kfacB = forceparams[type].dihres.kfacB; + phi0B = forceparams[type].dihres.phiB * d2r; + dphiB = forceparams[type].dihres.dphiB * d2r; + kfacB = forceparams[type].dihres.kfacB; - phi0 = L1*phi0A + lambda*phi0B; - dphi = L1*dphiA + lambda*dphiB; - kfac = L1*kfacA + lambda*kfacB; + phi0 = L1 * phi0A + lambda * phi0B; + dphi = L1 * dphiA + lambda * dphiB; + kfac = L1 * kfacA + lambda * kfacB; - phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); + phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* 84 flops */ /* phi can jump if phi0 is close to Pi/-Pi, which will cause huge @@ -2312,16 +2437,16 @@ real dihres(int nbonds, * the dihedral is Pi away from phiO, which is very unlikely due to * the potential. */ - dp = phi-phi0; + dp = phi - phi0; make_dp_periodic(&dp); if (dp > dphi) { - ddp = dp-dphi; + ddp = dp - dphi; } else if (dp < -dphi) { - ddp = dp+dphi; + ddp = dp + dphi; } else { @@ -2330,22 +2455,22 @@ real dihres(int nbonds, if (ddp != 0.0) { - ddp2 = ddp*ddp; - vtot += 0.5*kfac*ddp2; - ddphi = kfac*ddp; + ddp2 = ddp * ddp; + vtot += 0.5 * kfac * ddp2; + ddphi = kfac * ddp; - *dvdlambda += 0.5*(kfacB - kfacA)*ddp2; + *dvdlambda += 0.5 * (kfacB - kfacA) * ddp2; /* lambda dependence from changing restraint distances */ if (ddp > 0) { - *dvdlambda -= kfac*ddp*((dphiB - dphiA)+(phi0B - phi0A)); + *dvdlambda -= kfac * ddp * ((dphiB - dphiA) + (phi0B - phi0A)); } else if (ddp < 0) { - *dvdlambda += kfac*ddp*((dphiB - dphiA)-(phi0B - phi0A)); + *dvdlambda += kfac * ddp * ((dphiB - dphiA) - (phi0B - phi0A)); } - do_dih_fup(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, - f, fshift, pbc, g, x, t1, t2, t3); /* 112 */ + do_dih_fup(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, g, x, + t1, t2, t3); /* 112 */ } } return vtot; @@ -2353,24 +2478,36 @@ real dihres(int nbonds, real unimplemented(int gmx_unused nbonds, - const t_iatom gmx_unused forceatoms[], const t_iparams gmx_unused forceparams[], - const rvec gmx_unused x[], rvec4 gmx_unused f[], rvec gmx_unused fshift[], - const t_pbc gmx_unused *pbc, const t_graph gmx_unused *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) + const t_iatom gmx_unused forceatoms[], + const t_iparams gmx_unused forceparams[], + const rvec gmx_unused x[], + rvec4 gmx_unused f[], + rvec gmx_unused fshift[], + const t_pbc gmx_unused* pbc, + const t_graph gmx_unused* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { gmx_impl("*** you are using a not implemented function"); } -template -real restrangles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real restrangles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, d, ai, aj, ak, type, m; int t1, t2; @@ -2381,7 +2518,7 @@ real restrangles(int nbonds, rvec delta_ante, delta_post, vec_temp; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2426,14 +2563,15 @@ real restrangles(int nbonds, * {\sin^2\theta_i}\f] ({eq:ReB} and ref \cite{MonicaGoga2013} from the manual). * For more explanations see comments file "restcbt.h". */ - compute_factors_restangles(type, forceparams, delta_ante, delta_post, - &prefactor, &ratio_ante, &ratio_post, &v); + compute_factors_restangles(type, forceparams, delta_ante, delta_post, &prefactor, + &ratio_ante, &ratio_post, &v); /* Forces are computed per component */ for (d = 0; d < DIM; d++) { f_i[d] = prefactor * (ratio_ante * delta_ante[d] - delta_post[d]); - f_j[d] = prefactor * ((ratio_post + 1.0) * delta_post[d] - (ratio_ante + 1.0) * delta_ante[d]); + f_j[d] = prefactor + * ((ratio_post + 1.0) * delta_post[d] - (ratio_ante + 1.0) * delta_ante[d]); f_k[d] = prefactor * (delta_ante[d] - ratio_post * delta_post[d]); } @@ -2470,14 +2608,20 @@ real restrangles(int nbonds, } -template -real restrdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real restrdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, d, type, ai, aj, ak, al; rvec f_i, f_j, f_k, f_l; @@ -2485,7 +2629,7 @@ real restrdihs(int nbonds, ivec jt, dt_ij, dt_kj, dt_lj; int t1, t2, t3; real v, vtot; - rvec delta_ante, delta_crnt, delta_post, vec_temp; + rvec delta_ante, delta_crnt, delta_post, vec_temp; real factor_phi_ai_ante, factor_phi_ai_crnt, factor_phi_ai_post; real factor_phi_aj_ante, factor_phi_aj_crnt, factor_phi_aj_post; real factor_phi_ak_ante, factor_phi_ak_crnt, factor_phi_ak_post; @@ -2494,7 +2638,7 @@ real restrdihs(int nbonds, vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2517,29 +2661,34 @@ real restrdihs(int nbonds, * ({eq:ReB} and ref \cite{MonicaGoga2013} from the manual). * For more explanations see comments file "restcbt.h" */ - compute_factors_restrdihs(type, forceparams, - delta_ante, delta_crnt, delta_post, - &factor_phi_ai_ante, &factor_phi_ai_crnt, &factor_phi_ai_post, - &factor_phi_aj_ante, &factor_phi_aj_crnt, &factor_phi_aj_post, - &factor_phi_ak_ante, &factor_phi_ak_crnt, &factor_phi_ak_post, - &factor_phi_al_ante, &factor_phi_al_crnt, &factor_phi_al_post, - &prefactor_phi, &v); + compute_factors_restrdihs( + type, forceparams, delta_ante, delta_crnt, delta_post, &factor_phi_ai_ante, + &factor_phi_ai_crnt, &factor_phi_ai_post, &factor_phi_aj_ante, &factor_phi_aj_crnt, + &factor_phi_aj_post, &factor_phi_ak_ante, &factor_phi_ak_crnt, &factor_phi_ak_post, + &factor_phi_al_ante, &factor_phi_al_crnt, &factor_phi_al_post, &prefactor_phi, &v); /* Computation of forces per component */ for (d = 0; d < DIM; d++) { - f_i[d] = prefactor_phi * (factor_phi_ai_ante * delta_ante[d] + factor_phi_ai_crnt * delta_crnt[d] + factor_phi_ai_post * delta_post[d]); - f_j[d] = prefactor_phi * (factor_phi_aj_ante * delta_ante[d] + factor_phi_aj_crnt * delta_crnt[d] + factor_phi_aj_post * delta_post[d]); - f_k[d] = prefactor_phi * (factor_phi_ak_ante * delta_ante[d] + factor_phi_ak_crnt * delta_crnt[d] + factor_phi_ak_post * delta_post[d]); - f_l[d] = prefactor_phi * (factor_phi_al_ante * delta_ante[d] + factor_phi_al_crnt * delta_crnt[d] + factor_phi_al_post * delta_post[d]); + f_i[d] = prefactor_phi + * (factor_phi_ai_ante * delta_ante[d] + factor_phi_ai_crnt * delta_crnt[d] + + factor_phi_ai_post * delta_post[d]); + f_j[d] = prefactor_phi + * (factor_phi_aj_ante * delta_ante[d] + factor_phi_aj_crnt * delta_crnt[d] + + factor_phi_aj_post * delta_post[d]); + f_k[d] = prefactor_phi + * (factor_phi_ak_ante * delta_ante[d] + factor_phi_ak_crnt * delta_crnt[d] + + factor_phi_ak_post * delta_post[d]); + f_l[d] = prefactor_phi + * (factor_phi_al_ante * delta_ante[d] + factor_phi_al_crnt * delta_crnt[d] + + factor_phi_al_post * delta_post[d]); } /* Computation of the energy */ vtot += v; - /* Updating the forces */ rvec_inc(f[ai], f_i); @@ -2579,14 +2728,20 @@ real restrdihs(int nbonds, } -template -real cbtdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real cbtdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int type, ai, aj, ak, al, i, d; int t1, t2, t3; @@ -2601,10 +2756,8 @@ real cbtdihs(int nbonds, rvec f_theta_post_aj, f_theta_post_ak, f_theta_post_al; - - vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2631,11 +2784,9 @@ real cbtdihs(int nbonds, * --- the adjacent bending angles. * For more explanations see comments file "restcbt.h". */ - compute_factors_cbtdihs(type, forceparams, delta_ante, delta_crnt, delta_post, - f_phi_ai, f_phi_aj, f_phi_ak, f_phi_al, - f_theta_ante_ai, f_theta_ante_aj, f_theta_ante_ak, - f_theta_post_aj, f_theta_post_ak, f_theta_post_al, - &v); + compute_factors_cbtdihs(type, forceparams, delta_ante, delta_crnt, delta_post, f_phi_ai, + f_phi_aj, f_phi_ak, f_phi_al, f_theta_ante_ai, f_theta_ante_aj, + f_theta_ante_ak, f_theta_post_aj, f_theta_post_ak, f_theta_post_al, &v); /* Acumulate the resuts per beads */ @@ -2690,15 +2841,21 @@ real cbtdihs(int nbonds, return vtot; } -template +template std::enable_if_t -rbdihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +rbdihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { const real c0 = 0.0, c1 = 1.0, c2 = 2.0, c3 = 3.0, c4 = 4.0, c5 = 5.0; int type, ai, aj, ak, al, i, j; @@ -2710,11 +2867,11 @@ rbdihs(int nbonds, real cos_phi, phi, rbp, rbpBA; real v, ddphi, sin_phi; real cosfac, vtot; - real L1 = 1.0-lambda; + real L1 = 1.0 - lambda; real dvdl_term = 0; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -2722,8 +2879,7 @@ rbdihs(int nbonds, ak = forceatoms[i++]; al = forceatoms[i++]; - phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); /* 84 */ + phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* 84 */ /* Change to polymer convention */ if (phi < c0) @@ -2732,8 +2888,7 @@ rbdihs(int nbonds, } else { - phi -= M_PI; /* 1 */ - + phi -= M_PI; /* 1 */ } cos_phi = std::cos(phi); /* Beware of accuracy loss, cannot use 1-sqrt(cos^2) ! */ @@ -2743,52 +2898,52 @@ rbdihs(int nbonds, { parmA[j] = forceparams[type].rbdihs.rbcA[j]; parmB[j] = forceparams[type].rbdihs.rbcB[j]; - parm[j] = L1*parmA[j]+lambda*parmB[j]; + parm[j] = L1 * parmA[j] + lambda * parmB[j]; } /* Calculate cosine powers */ /* Calculate the energy */ /* Calculate the derivative */ - v = parm[0]; - dvdl_term += (parmB[0]-parmA[0]); - ddphi = c0; - cosfac = c1; - - rbp = parm[1]; - rbpBA = parmB[1]-parmA[1]; - ddphi += rbp*cosfac; - cosfac *= cos_phi; - v += cosfac*rbp; - dvdl_term += cosfac*rbpBA; - rbp = parm[2]; - rbpBA = parmB[2]-parmA[2]; - ddphi += c2*rbp*cosfac; - cosfac *= cos_phi; - v += cosfac*rbp; - dvdl_term += cosfac*rbpBA; - rbp = parm[3]; - rbpBA = parmB[3]-parmA[3]; - ddphi += c3*rbp*cosfac; - cosfac *= cos_phi; - v += cosfac*rbp; - dvdl_term += cosfac*rbpBA; - rbp = parm[4]; - rbpBA = parmB[4]-parmA[4]; - ddphi += c4*rbp*cosfac; - cosfac *= cos_phi; - v += cosfac*rbp; - dvdl_term += cosfac*rbpBA; - rbp = parm[5]; - rbpBA = parmB[5]-parmA[5]; - ddphi += c5*rbp*cosfac; - cosfac *= cos_phi; - v += cosfac*rbp; - dvdl_term += cosfac*rbpBA; - - ddphi = -ddphi*sin_phi; /* 11 */ - - do_dih_fup(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, - f, fshift, pbc, g, x, t1, t2, t3); /* 112 */ + v = parm[0]; + dvdl_term += (parmB[0] - parmA[0]); + ddphi = c0; + cosfac = c1; + + rbp = parm[1]; + rbpBA = parmB[1] - parmA[1]; + ddphi += rbp * cosfac; + cosfac *= cos_phi; + v += cosfac * rbp; + dvdl_term += cosfac * rbpBA; + rbp = parm[2]; + rbpBA = parmB[2] - parmA[2]; + ddphi += c2 * rbp * cosfac; + cosfac *= cos_phi; + v += cosfac * rbp; + dvdl_term += cosfac * rbpBA; + rbp = parm[3]; + rbpBA = parmB[3] - parmA[3]; + ddphi += c3 * rbp * cosfac; + cosfac *= cos_phi; + v += cosfac * rbp; + dvdl_term += cosfac * rbpBA; + rbp = parm[4]; + rbpBA = parmB[4] - parmA[4]; + ddphi += c4 * rbp * cosfac; + cosfac *= cos_phi; + v += cosfac * rbp; + dvdl_term += cosfac * rbpBA; + rbp = parm[5]; + rbpBA = parmB[5] - parmA[5]; + ddphi += c5 * rbp * cosfac; + cosfac *= cos_phi; + v += cosfac * rbp; + dvdl_term += cosfac * rbpBA; + + ddphi = -ddphi * sin_phi; /* 11 */ + + do_dih_fup(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, g, x, t1, + t2, t3); /* 112 */ vtot += v; } *dvdlambda += dvdl_term; @@ -2799,8 +2954,7 @@ rbdihs(int nbonds, //! \endcond /*! \brief Mysterious undocumented function */ -int -cmap_setup_grid_index(int ip, int grid_spacing, int *ipm1, int *ipp1, int *ipp2) +int cmap_setup_grid_index(int ip, int grid_spacing, int* ipm1, int* ipp1, int* ipp2) { int im1, ip1, ip2; @@ -2821,11 +2975,11 @@ cmap_setup_grid_index(int ip, int grid_spacing, int *ipm1, int *ipp1, int *ipp2) { im1 = grid_spacing - 1; } - else if (ip == grid_spacing-2) + else if (ip == grid_spacing - 2) { ip2 = 0; } - else if (ip == grid_spacing-1) + else if (ip == grid_spacing - 1) { ip1 = 0; ip2 = 1; @@ -2836,105 +2990,104 @@ cmap_setup_grid_index(int ip, int grid_spacing, int *ipm1, int *ipp1, int *ipp2) *ipp2 = ip2; return ip; - } } // namespace -real -cmap_dihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const gmx_cmap_t *cmap_grid, - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +real cmap_dihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const gmx_cmap_t* cmap_grid, + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { - int i, n; - int ai, aj, ak, al, am; - int a1i, a1j, a1k, a1l, a2i, a2j, a2k, a2l; - int type; - int t11, t21, t31, t12, t22, t32; - int iphi1, ip1m1, ip1p1, ip1p2; - int iphi2, ip2m1, ip2p1, ip2p2; - int l1, l2, l3; - int pos1, pos2, pos3, pos4; - - real ty[4], ty1[4], ty2[4], ty12[4], tx[16]; - real phi1, cos_phi1, sin_phi1, xphi1; - real phi2, cos_phi2, sin_phi2, xphi2; - real dx, tt, tu, e, df1, df2, vtot; - real ra21, rb21, rg21, rg1, rgr1, ra2r1, rb2r1, rabr1; - real ra22, rb22, rg22, rg2, rgr2, ra2r2, rb2r2, rabr2; - real fg1, hg1, fga1, hgb1, gaa1, gbb1; - real fg2, hg2, fga2, hgb2, gaa2, gbb2; - real fac; - - rvec r1_ij, r1_kj, r1_kl, m1, n1; - rvec r2_ij, r2_kj, r2_kl, m2, n2; - rvec f1_i, f1_j, f1_k, f1_l; - rvec f2_i, f2_j, f2_k, f2_l; - rvec a1, b1, a2, b2; - rvec f1, g1, h1, f2, g2, h2; - rvec dtf1, dtg1, dth1, dtf2, dtg2, dth2; - ivec jt1, dt1_ij, dt1_kj, dt1_lj; - ivec jt2, dt2_ij, dt2_kj, dt2_lj; - - int loop_index[4][4] = { - {0, 4, 8, 12}, - {1, 5, 9, 13}, - {2, 6, 10, 14}, - {3, 7, 11, 15} - }; + int i, n; + int ai, aj, ak, al, am; + int a1i, a1j, a1k, a1l, a2i, a2j, a2k, a2l; + int type; + int t11, t21, t31, t12, t22, t32; + int iphi1, ip1m1, ip1p1, ip1p2; + int iphi2, ip2m1, ip2p1, ip2p2; + int l1, l2, l3; + int pos1, pos2, pos3, pos4; + + real ty[4], ty1[4], ty2[4], ty12[4], tx[16]; + real phi1, cos_phi1, sin_phi1, xphi1; + real phi2, cos_phi2, sin_phi2, xphi2; + real dx, tt, tu, e, df1, df2, vtot; + real ra21, rb21, rg21, rg1, rgr1, ra2r1, rb2r1, rabr1; + real ra22, rb22, rg22, rg2, rgr2, ra2r2, rb2r2, rabr2; + real fg1, hg1, fga1, hgb1, gaa1, gbb1; + real fg2, hg2, fga2, hgb2, gaa2, gbb2; + real fac; + + rvec r1_ij, r1_kj, r1_kl, m1, n1; + rvec r2_ij, r2_kj, r2_kl, m2, n2; + rvec f1_i, f1_j, f1_k, f1_l; + rvec f2_i, f2_j, f2_k, f2_l; + rvec a1, b1, a2, b2; + rvec f1, g1, h1, f2, g2, h2; + rvec dtf1, dtg1, dth1, dtf2, dtg2, dth2; + ivec jt1, dt1_ij, dt1_kj, dt1_lj; + ivec jt2, dt2_ij, dt2_kj, dt2_lj; + + int loop_index[4][4] = { { 0, 4, 8, 12 }, { 1, 5, 9, 13 }, { 2, 6, 10, 14 }, { 3, 7, 11, 15 } }; /* Total CMAP energy */ vtot = 0; - for (n = 0; n < nbonds; ) + for (n = 0; n < nbonds;) { /* Five atoms are involved in the two torsions */ - type = forceatoms[n++]; - ai = forceatoms[n++]; - aj = forceatoms[n++]; - ak = forceatoms[n++]; - al = forceatoms[n++]; - am = forceatoms[n++]; + type = forceatoms[n++]; + ai = forceatoms[n++]; + aj = forceatoms[n++]; + ak = forceatoms[n++]; + al = forceatoms[n++]; + am = forceatoms[n++]; /* Which CMAP type is this */ const int cmapA = forceparams[type].cmap.cmapA; - const real *cmapd = cmap_grid->cmapdata[cmapA].cmap.data(); + const real* cmapd = cmap_grid->cmapdata[cmapA].cmap.data(); /* First torsion */ - a1i = ai; - a1j = aj; - a1k = ak; - a1l = al; + a1i = ai; + a1j = aj; + a1k = ak; + a1l = al; - phi1 = dih_angle(x[a1i], x[a1j], x[a1k], x[a1l], pbc, r1_ij, r1_kj, r1_kl, m1, n1, - &t11, &t21, &t31); /* 84 */ + phi1 = dih_angle(x[a1i], x[a1j], x[a1k], x[a1l], pbc, r1_ij, r1_kj, r1_kl, m1, n1, &t11, + &t21, &t31); /* 84 */ cos_phi1 = std::cos(phi1); - a1[0] = r1_ij[1]*r1_kj[2]-r1_ij[2]*r1_kj[1]; - a1[1] = r1_ij[2]*r1_kj[0]-r1_ij[0]*r1_kj[2]; - a1[2] = r1_ij[0]*r1_kj[1]-r1_ij[1]*r1_kj[0]; /* 9 */ + a1[0] = r1_ij[1] * r1_kj[2] - r1_ij[2] * r1_kj[1]; + a1[1] = r1_ij[2] * r1_kj[0] - r1_ij[0] * r1_kj[2]; + a1[2] = r1_ij[0] * r1_kj[1] - r1_ij[1] * r1_kj[0]; /* 9 */ - b1[0] = r1_kl[1]*r1_kj[2]-r1_kl[2]*r1_kj[1]; - b1[1] = r1_kl[2]*r1_kj[0]-r1_kl[0]*r1_kj[2]; - b1[2] = r1_kl[0]*r1_kj[1]-r1_kl[1]*r1_kj[0]; /* 9 */ + b1[0] = r1_kl[1] * r1_kj[2] - r1_kl[2] * r1_kj[1]; + b1[1] = r1_kl[2] * r1_kj[0] - r1_kl[0] * r1_kj[2]; + b1[2] = r1_kl[0] * r1_kj[1] - r1_kl[1] * r1_kj[0]; /* 9 */ pbc_rvec_sub(pbc, x[a1l], x[a1k], h1); - ra21 = iprod(a1, a1); /* 5 */ - rb21 = iprod(b1, b1); /* 5 */ - rg21 = iprod(r1_kj, r1_kj); /* 5 */ - rg1 = sqrt(rg21); + ra21 = iprod(a1, a1); /* 5 */ + rb21 = iprod(b1, b1); /* 5 */ + rg21 = iprod(r1_kj, r1_kj); /* 5 */ + rg1 = sqrt(rg21); - rgr1 = 1.0/rg1; - ra2r1 = 1.0/ra21; - rb2r1 = 1.0/rb21; - rabr1 = sqrt(ra2r1*rb2r1); + rgr1 = 1.0 / rg1; + ra2r1 = 1.0 / ra21; + rb2r1 = 1.0 / rb21; + rabr1 = sqrt(ra2r1 * rb2r1); sin_phi1 = rg1 * rabr1 * iprod(a1, h1) * (-1); @@ -2967,35 +3120,35 @@ cmap_dihs(int nbonds, xphi1 = phi1 + M_PI; /* 1 */ /* Second torsion */ - a2i = aj; - a2j = ak; - a2k = al; - a2l = am; + a2i = aj; + a2j = ak; + a2k = al; + a2l = am; - phi2 = dih_angle(x[a2i], x[a2j], x[a2k], x[a2l], pbc, r2_ij, r2_kj, r2_kl, m2, n2, - &t12, &t22, &t32); /* 84 */ + phi2 = dih_angle(x[a2i], x[a2j], x[a2k], x[a2l], pbc, r2_ij, r2_kj, r2_kl, m2, n2, &t12, + &t22, &t32); /* 84 */ cos_phi2 = std::cos(phi2); - a2[0] = r2_ij[1]*r2_kj[2]-r2_ij[2]*r2_kj[1]; - a2[1] = r2_ij[2]*r2_kj[0]-r2_ij[0]*r2_kj[2]; - a2[2] = r2_ij[0]*r2_kj[1]-r2_ij[1]*r2_kj[0]; /* 9 */ + a2[0] = r2_ij[1] * r2_kj[2] - r2_ij[2] * r2_kj[1]; + a2[1] = r2_ij[2] * r2_kj[0] - r2_ij[0] * r2_kj[2]; + a2[2] = r2_ij[0] * r2_kj[1] - r2_ij[1] * r2_kj[0]; /* 9 */ - b2[0] = r2_kl[1]*r2_kj[2]-r2_kl[2]*r2_kj[1]; - b2[1] = r2_kl[2]*r2_kj[0]-r2_kl[0]*r2_kj[2]; - b2[2] = r2_kl[0]*r2_kj[1]-r2_kl[1]*r2_kj[0]; /* 9 */ + b2[0] = r2_kl[1] * r2_kj[2] - r2_kl[2] * r2_kj[1]; + b2[1] = r2_kl[2] * r2_kj[0] - r2_kl[0] * r2_kj[2]; + b2[2] = r2_kl[0] * r2_kj[1] - r2_kl[1] * r2_kj[0]; /* 9 */ pbc_rvec_sub(pbc, x[a2l], x[a2k], h2); - ra22 = iprod(a2, a2); /* 5 */ - rb22 = iprod(b2, b2); /* 5 */ - rg22 = iprod(r2_kj, r2_kj); /* 5 */ - rg2 = sqrt(rg22); + ra22 = iprod(a2, a2); /* 5 */ + rb22 = iprod(b2, b2); /* 5 */ + rg22 = iprod(r2_kj, r2_kj); /* 5 */ + rg2 = sqrt(rg22); - rgr2 = 1.0/rg2; - ra2r2 = 1.0/ra22; - rb2r2 = 1.0/rb22; - rabr2 = sqrt(ra2r2*rb2r2); + rgr2 = 1.0 / rg2; + ra2r2 = 1.0 / ra22; + rb2r2 = 1.0 / rb22; + rabr2 = sqrt(ra2r2 * rb2r2); sin_phi2 = rg2 * rabr2 * iprod(a2, h2) * (-1); @@ -3030,56 +3183,56 @@ cmap_dihs(int nbonds, /* Range mangling */ if (xphi1 < 0) { - xphi1 = xphi1 + 2*M_PI; + xphi1 = xphi1 + 2 * M_PI; } - else if (xphi1 >= 2*M_PI) + else if (xphi1 >= 2 * M_PI) { - xphi1 = xphi1 - 2*M_PI; + xphi1 = xphi1 - 2 * M_PI; } if (xphi2 < 0) { - xphi2 = xphi2 + 2*M_PI; + xphi2 = xphi2 + 2 * M_PI; } - else if (xphi2 >= 2*M_PI) + else if (xphi2 >= 2 * M_PI) { - xphi2 = xphi2 - 2*M_PI; + xphi2 = xphi2 - 2 * M_PI; } /* Number of grid points */ - dx = 2*M_PI / cmap_grid->grid_spacing; + dx = 2 * M_PI / cmap_grid->grid_spacing; /* Where on the grid are we */ - iphi1 = static_cast(xphi1/dx); - iphi2 = static_cast(xphi2/dx); + iphi1 = static_cast(xphi1 / dx); + iphi2 = static_cast(xphi2 / dx); iphi1 = cmap_setup_grid_index(iphi1, cmap_grid->grid_spacing, &ip1m1, &ip1p1, &ip1p2); iphi2 = cmap_setup_grid_index(iphi2, cmap_grid->grid_spacing, &ip2m1, &ip2p1, &ip2p2); - pos1 = iphi1*cmap_grid->grid_spacing+iphi2; - pos2 = ip1p1*cmap_grid->grid_spacing+iphi2; - pos3 = ip1p1*cmap_grid->grid_spacing+ip2p1; - pos4 = iphi1*cmap_grid->grid_spacing+ip2p1; + pos1 = iphi1 * cmap_grid->grid_spacing + iphi2; + pos2 = ip1p1 * cmap_grid->grid_spacing + iphi2; + pos3 = ip1p1 * cmap_grid->grid_spacing + ip2p1; + pos4 = iphi1 * cmap_grid->grid_spacing + ip2p1; - ty[0] = cmapd[pos1*4]; - ty[1] = cmapd[pos2*4]; - ty[2] = cmapd[pos3*4]; - ty[3] = cmapd[pos4*4]; + ty[0] = cmapd[pos1 * 4]; + ty[1] = cmapd[pos2 * 4]; + ty[2] = cmapd[pos3 * 4]; + ty[3] = cmapd[pos4 * 4]; - ty1[0] = cmapd[pos1*4+1]; - ty1[1] = cmapd[pos2*4+1]; - ty1[2] = cmapd[pos3*4+1]; - ty1[3] = cmapd[pos4*4+1]; + ty1[0] = cmapd[pos1 * 4 + 1]; + ty1[1] = cmapd[pos2 * 4 + 1]; + ty1[2] = cmapd[pos3 * 4 + 1]; + ty1[3] = cmapd[pos4 * 4 + 1]; - ty2[0] = cmapd[pos1*4+2]; - ty2[1] = cmapd[pos2*4+2]; - ty2[2] = cmapd[pos3*4+2]; - ty2[3] = cmapd[pos4*4+2]; + ty2[0] = cmapd[pos1 * 4 + 2]; + ty2[1] = cmapd[pos2 * 4 + 2]; + ty2[2] = cmapd[pos3 * 4 + 2]; + ty2[3] = cmapd[pos4 * 4 + 2]; - ty12[0] = cmapd[pos1*4+3]; - ty12[1] = cmapd[pos2*4+3]; - ty12[2] = cmapd[pos3*4+3]; - ty12[3] = cmapd[pos4*4+3]; + ty12[0] = cmapd[pos1 * 4 + 3]; + ty12[1] = cmapd[pos2 * 4 + 3]; + ty12[2] = cmapd[pos3 * 4 + 3]; + ty12[3] = cmapd[pos4 * 4 + 3]; /* Switch to degrees */ dx = 360.0 / cmap_grid->grid_spacing; @@ -3088,27 +3241,27 @@ cmap_dihs(int nbonds, for (i = 0; i < 4; i++) /* 16 */ { - tx[i] = ty[i]; - tx[i+4] = ty1[i]*dx; - tx[i+8] = ty2[i]*dx; - tx[i+12] = ty12[i]*dx*dx; + tx[i] = ty[i]; + tx[i + 4] = ty1[i] * dx; + tx[i + 8] = ty2[i] * dx; + tx[i + 12] = ty12[i] * dx * dx; } - real tc[16] = {0}; + real tc[16] = { 0 }; for (int idx = 0; idx < 16; idx++) /* 1056 */ { for (int k = 0; k < 16; k++) { - tc[idx] += cmap_coeff_matrix[k*16+idx]*tx[k]; + tc[idx] += cmap_coeff_matrix[k * 16 + idx] * tx[k]; } } - tt = (xphi1-iphi1*dx)/dx; - tu = (xphi2-iphi2*dx)/dx; + tt = (xphi1 - iphi1 * dx) / dx; + tu = (xphi2 - iphi2 * dx) / dx; - e = 0; - df1 = 0; - df2 = 0; + e = 0; + df1 = 0; + df2 = 0; for (i = 3; i >= 0; i--) { @@ -3116,40 +3269,40 @@ cmap_dihs(int nbonds, l2 = loop_index[i][2]; l3 = loop_index[i][1]; - e = tt * e + ((tc[i*4+3]*tu+tc[i*4+2])*tu + tc[i*4+1])*tu+tc[i*4]; - df1 = tu * df1 + (3.0*tc[l1]*tt+2.0*tc[l2])*tt+tc[l3]; - df2 = tt * df2 + (3.0*tc[i*4+3]*tu+2.0*tc[i*4+2])*tu+tc[i*4+1]; + e = tt * e + ((tc[i * 4 + 3] * tu + tc[i * 4 + 2]) * tu + tc[i * 4 + 1]) * tu + tc[i * 4]; + df1 = tu * df1 + (3.0 * tc[l1] * tt + 2.0 * tc[l2]) * tt + tc[l3]; + df2 = tt * df2 + (3.0 * tc[i * 4 + 3] * tu + 2.0 * tc[i * 4 + 2]) * tu + tc[i * 4 + 1]; } - fac = RAD2DEG/dx; - df1 = df1 * fac; - df2 = df2 * fac; + fac = RAD2DEG / dx; + df1 = df1 * fac; + df2 = df2 * fac; /* CMAP energy */ vtot += e; /* Do forces - first torsion */ - fg1 = iprod(r1_ij, r1_kj); - hg1 = iprod(r1_kl, r1_kj); - fga1 = fg1*ra2r1*rgr1; - hgb1 = hg1*rb2r1*rgr1; - gaa1 = -ra2r1*rg1; - gbb1 = rb2r1*rg1; + fg1 = iprod(r1_ij, r1_kj); + hg1 = iprod(r1_kl, r1_kj); + fga1 = fg1 * ra2r1 * rgr1; + hgb1 = hg1 * rb2r1 * rgr1; + gaa1 = -ra2r1 * rg1; + gbb1 = rb2r1 * rg1; for (i = 0; i < DIM; i++) { - dtf1[i] = gaa1 * a1[i]; - dtg1[i] = fga1 * a1[i] - hgb1 * b1[i]; - dth1[i] = gbb1 * b1[i]; + dtf1[i] = gaa1 * a1[i]; + dtg1[i] = fga1 * a1[i] - hgb1 * b1[i]; + dth1[i] = gbb1 * b1[i]; - f1[i] = df1 * dtf1[i]; - g1[i] = df1 * dtg1[i]; - h1[i] = df1 * dth1[i]; + f1[i] = df1 * dtf1[i]; + g1[i] = df1 * dtg1[i]; + h1[i] = df1 * dth1[i]; - f1_i[i] = f1[i]; - f1_j[i] = -f1[i] - g1[i]; - f1_k[i] = h1[i] + g1[i]; - f1_l[i] = -h1[i]; + f1_i[i] = f1[i]; + f1_j[i] = -f1[i] - g1[i]; + f1_k[i] = h1[i] + g1[i]; + f1_l[i] = -h1[i]; f[a1i][i] = f[a1i][i] + f1_i[i]; f[a1j][i] = f[a1j][i] + f1_j[i]; /* - f1[i] - g1[i] */ @@ -3158,27 +3311,27 @@ cmap_dihs(int nbonds, } /* Do forces - second torsion */ - fg2 = iprod(r2_ij, r2_kj); - hg2 = iprod(r2_kl, r2_kj); - fga2 = fg2*ra2r2*rgr2; - hgb2 = hg2*rb2r2*rgr2; - gaa2 = -ra2r2*rg2; - gbb2 = rb2r2*rg2; + fg2 = iprod(r2_ij, r2_kj); + hg2 = iprod(r2_kl, r2_kj); + fga2 = fg2 * ra2r2 * rgr2; + hgb2 = hg2 * rb2r2 * rgr2; + gaa2 = -ra2r2 * rg2; + gbb2 = rb2r2 * rg2; for (i = 0; i < DIM; i++) { - dtf2[i] = gaa2 * a2[i]; - dtg2[i] = fga2 * a2[i] - hgb2 * b2[i]; - dth2[i] = gbb2 * b2[i]; + dtf2[i] = gaa2 * a2[i]; + dtg2[i] = fga2 * a2[i] - hgb2 * b2[i]; + dth2[i] = gbb2 * b2[i]; - f2[i] = df2 * dtf2[i]; - g2[i] = df2 * dtg2[i]; - h2[i] = df2 * dth2[i]; + f2[i] = df2 * dtf2[i]; + g2[i] = df2 * dtg2[i]; + h2[i] = df2 * dth2[i]; - f2_i[i] = f2[i]; - f2_j[i] = -f2[i] - g2[i]; - f2_k[i] = h2[i] + g2[i]; - f2_l[i] = -h2[i]; + f2_i[i] = f2[i]; + f2_j[i] = -f2[i] - g2[i]; + f2_k[i] = h2[i] + g2[i]; + f2_l[i] = -h2[i]; f[a2i][i] = f[a2i][i] + f2_i[i]; /* f2[i] */ f[a2j][i] = f[a2j][i] + f2_j[i]; /* - f2[i] - g2[i] */ @@ -3192,17 +3345,17 @@ cmap_dihs(int nbonds, if (g) { copy_ivec(SHIFT_IVEC(g, a1j), jt1); - ivec_sub(SHIFT_IVEC(g, a1i), jt1, dt1_ij); - ivec_sub(SHIFT_IVEC(g, a1k), jt1, dt1_kj); - ivec_sub(SHIFT_IVEC(g, a1l), jt1, dt1_lj); + ivec_sub(SHIFT_IVEC(g, a1i), jt1, dt1_ij); + ivec_sub(SHIFT_IVEC(g, a1k), jt1, dt1_kj); + ivec_sub(SHIFT_IVEC(g, a1l), jt1, dt1_lj); t11 = IVEC2IS(dt1_ij); t21 = IVEC2IS(dt1_kj); t31 = IVEC2IS(dt1_lj); copy_ivec(SHIFT_IVEC(g, a2j), jt2); - ivec_sub(SHIFT_IVEC(g, a2i), jt2, dt2_ij); - ivec_sub(SHIFT_IVEC(g, a2k), jt2, dt2_kj); - ivec_sub(SHIFT_IVEC(g, a2l), jt2, dt2_lj); + ivec_sub(SHIFT_IVEC(g, a2i), jt2, dt2_ij); + ivec_sub(SHIFT_IVEC(g, a2k), jt2, dt2_kj); + ivec_sub(SHIFT_IVEC(g, a2l), jt2, dt2_lj); t12 = IVEC2IS(dt2_ij); t22 = IVEC2IS(dt2_kj); t32 = IVEC2IS(dt2_lj); @@ -3241,71 +3394,72 @@ namespace * G R O M O S 9 6 F U N C T I O N S * ***********************************************************/ -real g96harmonic(real kA, real kB, real xA, real xB, real x, real lambda, - real *V, real *F) +real g96harmonic(real kA, real kB, real xA, real xB, real x, real lambda, real* V, real* F) { const real half = 0.5; real L1, kk, x0, dx, dx2; real v, f, dvdlambda; - L1 = 1.0-lambda; - kk = L1*kA+lambda*kB; - x0 = L1*xA+lambda*xB; + L1 = 1.0 - lambda; + kk = L1 * kA + lambda * kB; + x0 = L1 * xA + lambda * xB; - dx = x-x0; - dx2 = dx*dx; + dx = x - x0; + dx2 = dx * dx; - f = -kk*dx; - v = half*kk*dx2; - dvdlambda = half*(kB-kA)*dx2 + (xA-xB)*kk*dx; + f = -kk * dx; + v = half * kk * dx2; + dvdlambda = half * (kB - kA) * dx2 + (xA - xB) * kk * dx; - *F = f; - *V = v; + *F = f; + *V = v; return dvdlambda; /* That was 21 flops */ } -template -real g96bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real g96bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type; real dr2, fbond, vbond, vtot; rvec dx; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ - *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, - forceparams[type].harmonic.krB, - forceparams[type].harmonic.rA, - forceparams[type].harmonic.rB, - dr2, lambda, &vbond, &fbond); + *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB, + forceparams[type].harmonic.rA, forceparams[type].harmonic.rB, dr2, + lambda, &vbond, &fbond); - vtot += 0.5*vbond; /* 1*/ + vtot += 0.5 * vbond; /* 1*/ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 44 TOTAL */ return vtot; } -real g96bond_angle(const rvec xi, const rvec xj, const rvec xk, const t_pbc *pbc, - rvec r_ij, rvec r_kj, - int *t1, int *t2) +real g96bond_angle(const rvec xi, const rvec xj, const rvec xk, const t_pbc* pbc, rvec r_ij, rvec r_kj, int* t1, int* t2) /* Return value is the angle between the bonds i-j and j-k */ { real costh; @@ -3313,19 +3467,25 @@ real g96bond_angle(const rvec xi, const rvec xj, const rvec xk, const t_pbc *pbc *t1 = pbc_rvec_sub(pbc, xi, xj, r_ij); /* 3 */ *t2 = pbc_rvec_sub(pbc, xk, xj, r_kj); /* 3 */ - costh = cos_angle(r_ij, r_kj); /* 25 */ + costh = cos_angle(r_ij, r_kj); /* 25 */ /* 41 TOTAL */ return costh; } -template -real g96angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real g96angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { int i, ai, aj, ak, type, m, t1, t2; rvec r_ij, r_kj; @@ -3335,33 +3495,31 @@ real g96angles(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; ak = forceatoms[i++]; - cos_theta = g96bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &t1, &t2); + cos_theta = g96bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &t1, &t2); - *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, - forceparams[type].harmonic.krB, - forceparams[type].harmonic.rA, - forceparams[type].harmonic.rB, + *dvdlambda += g96harmonic(forceparams[type].harmonic.krA, forceparams[type].harmonic.krB, + forceparams[type].harmonic.rA, forceparams[type].harmonic.rB, cos_theta, lambda, &va, &dVdt); - vtot += va; + vtot += va; rij_1 = gmx::invsqrt(iprod(r_ij, r_ij)); rkj_1 = gmx::invsqrt(iprod(r_kj, r_kj)); - rij_2 = rij_1*rij_1; - rkj_2 = rkj_1*rkj_1; - rijrkj_1 = rij_1*rkj_1; /* 23 */ + rij_2 = rij_1 * rij_1; + rkj_2 = rkj_1 * rkj_1; + rijrkj_1 = rij_1 * rkj_1; /* 23 */ - for (m = 0; (m < DIM); m++) /* 42 */ + for (m = 0; (m < DIM); m++) /* 42 */ { - f_i[m] = dVdt*(r_kj[m]*rijrkj_1 - r_ij[m]*rij_2*cos_theta); - f_k[m] = dVdt*(r_ij[m]*rijrkj_1 - r_kj[m]*rkj_2*cos_theta); - f_j[m] = -f_i[m]-f_k[m]; + f_i[m] = dVdt * (r_kj[m] * rijrkj_1 - r_ij[m] * rij_2 * cos_theta); + f_k[m] = dVdt * (r_ij[m] * rijrkj_1 - r_kj[m] * rkj_2 * cos_theta); + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -3380,21 +3538,27 @@ real g96angles(int nbonds, } rvec_inc(fshift[t1], f_i); rvec_inc(fshift[CENTRAL], f_j); - rvec_inc(fshift[t2], f_k); /* 9 */ + rvec_inc(fshift[t2], f_k); /* 9 */ } /* 163 TOTAL */ } return vtot; } -template -real cross_bond_bond(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real cross_bond_bond(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { /* Potential from Lawrence and Skimmer, Chem. Phys. Lett. 372 (2003) * pp. 842-847 @@ -3406,7 +3570,7 @@ real cross_bond_bond(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -3425,20 +3589,20 @@ real cross_bond_bond(int nbonds, r2 = norm(r_kj); /* Deviations from ideality */ - s1 = r1-r1e; - s2 = r2-r2e; + s1 = r1 - r1e; + s2 = r2 - r2e; /* Energy (can be negative!) */ - vrr = krr*s1*s2; + vrr = krr * s1 * s2; vtot += vrr; /* Forces */ - svmul(-krr*s2/r1, r_ij, f_i); - svmul(-krr*s1/r2, r_kj, f_k); + svmul(-krr * s2 / r1, r_ij, f_i); + svmul(-krr * s1 / r2, r_kj, f_k); - for (m = 0; (m < DIM); m++) /* 12 */ + for (m = 0; (m < DIM); m++) /* 12 */ { - f_j[m] = -f_i[m] - f_k[m]; + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -3457,21 +3621,27 @@ real cross_bond_bond(int nbonds, } rvec_inc(fshift[t1], f_i); rvec_inc(fshift[CENTRAL], f_j); - rvec_inc(fshift[t2], f_k); /* 9 */ + rvec_inc(fshift[t2], f_k); /* 9 */ } /* 163 TOTAL */ } return vtot; } -template -real cross_bond_angle(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index) +template +real cross_bond_angle(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index) { /* Potential from Lawrence and Skimmer, Chem. Phys. Lett. 372 (2003) * pp. 842-847 @@ -3483,7 +3653,7 @@ real cross_bond_angle(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -3505,26 +3675,26 @@ real cross_bond_angle(int nbonds, r3 = norm(r_ik); /* Deviations from ideality */ - s1 = r1-r1e; - s2 = r2-r2e; - s3 = r3-r3e; + s1 = r1 - r1e; + s2 = r2 - r2e; + s3 = r3 - r3e; /* Energy (can be negative!) */ - vrt = krt*s3*(s1+s2); + vrt = krt * s3 * (s1 + s2); vtot += vrt; /* Forces */ - k1 = -krt*(s3/r1); - k2 = -krt*(s3/r2); - k3 = -krt*(s1+s2)/r3; + k1 = -krt * (s3 / r1); + k2 = -krt * (s3 / r2); + k3 = -krt * (s1 + s2) / r3; for (m = 0; (m < DIM); m++) { - f_i[m] = k1*r_ij[m] + k3*r_ik[m]; - f_k[m] = k2*r_kj[m] - k3*r_ik[m]; + f_i[m] = k1 * r_ij[m] + k3 * r_ik[m]; + f_k[m] = k2 * r_kj[m] - k3 * r_ik[m]; f_j[m] = -f_i[m] - f_k[m]; } - for (m = 0; (m < DIM); m++) /* 12 */ + for (m = 0; (m < DIM); m++) /* 12 */ { f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; @@ -3544,7 +3714,7 @@ real cross_bond_angle(int nbonds, } rvec_inc(fshift[t1], f_i); rvec_inc(fshift[CENTRAL], f_j); - rvec_inc(fshift[t2], f_k); /* 9 */ + rvec_inc(fshift[t2], f_k); /* 9 */ } /* 163 TOTAL */ } @@ -3552,77 +3722,88 @@ real cross_bond_angle(int nbonds, } /*! \brief Computes the potential and force for a tabulated potential */ -real bonded_tab(const char *type, int table_nr, - const bondedtable_t *table, real kA, real kB, real r, - real lambda, real *V, real *F) +real bonded_tab(const char* type, + int table_nr, + const bondedtable_t* table, + real kA, + real kB, + real r, + real lambda, + real* V, + real* F) { real k, tabscale, *VFtab, rt, eps, eps2, Yt, Ft, Geps, Heps2, Fp, VV, FF; int n0, nnn; real dvdlambda; - k = (1.0 - lambda)*kA + lambda*kB; + k = (1.0 - lambda) * kA + lambda * kB; tabscale = table->scale; VFtab = table->data; - rt = r*tabscale; - n0 = static_cast(rt); + rt = r * tabscale; + n0 = static_cast(rt); if (n0 >= table->n) { - gmx_fatal(FARGS, "A tabulated %s interaction table number %d is out of the table range: r %f, between table indices %d and %d, table length %d", - type, table_nr, r, n0, n0+1, table->n); + gmx_fatal(FARGS, + "A tabulated %s interaction table number %d is out of the table range: r %f, " + "between table indices %d and %d, table length %d", + type, table_nr, r, n0, n0 + 1, table->n); } eps = rt - n0; - eps2 = eps*eps; - nnn = 4*n0; + eps2 = eps * eps; + nnn = 4 * n0; Yt = VFtab[nnn]; - Ft = VFtab[nnn+1]; - Geps = VFtab[nnn+2]*eps; - Heps2 = VFtab[nnn+3]*eps2; + Ft = VFtab[nnn + 1]; + Geps = VFtab[nnn + 2] * eps; + Heps2 = VFtab[nnn + 3] * eps2; Fp = Ft + Geps + Heps2; - VV = Yt + Fp*eps; - FF = Fp + Geps + 2.0*Heps2; + VV = Yt + Fp * eps; + FF = Fp + Geps + 2.0 * Heps2; - *F = -k*FF*tabscale; - *V = k*VV; - dvdlambda = (kB - kA)*VV; + *F = -k * FF * tabscale; + *V = k * VV; + dvdlambda = (kB - kA) * VV; return dvdlambda; /* That was 22 flops */ } -template -real tab_bonds(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata *fcd, - int gmx_unused *global_atom_index) +template +real tab_bonds(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index) { int i, ki, ai, aj, type, table; real dr, dr2, fbond, vbond, vtot; rvec dx; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; - ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ - dr2 = iprod(dx, dx); /* 5 */ - dr = dr2*gmx::invsqrt(dr2); /* 10 */ + ki = pbc_rvec_sub(pbc, x[ai], x[aj], dx); /* 3 */ + dr2 = iprod(dx, dx); /* 5 */ + dr = dr2 * gmx::invsqrt(dr2); /* 10 */ table = forceparams[type].tab.table; - *dvdlambda += bonded_tab("bond", table, - &fcd->bondtab[table], - forceparams[type].tab.kA, - forceparams[type].tab.kB, - dr, lambda, &vbond, &fbond); /* 22 */ + *dvdlambda += bonded_tab("bond", table, &fcd->bondtab[table], forceparams[type].tab.kA, + forceparams[type].tab.kB, dr, lambda, &vbond, &fbond); /* 22 */ if (dr2 == 0.0) { @@ -3630,22 +3811,28 @@ real tab_bonds(int nbonds, } - vtot += vbond; /* 1*/ - fbond *= gmx::invsqrt(dr2); /* 6 */ + vtot += vbond; /* 1*/ + fbond *= gmx::invsqrt(dr2); /* 6 */ spreadBondForces(fbond, dx, ai, aj, f, ki, g, fshift); /* 15 */ } /* 62 TOTAL */ return vtot; } -template -real tab_angles(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata *fcd, - int gmx_unused *global_atom_index) +template +real tab_angles(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index) { int i, ai, aj, ak, t1, t2, type, table; rvec r_ij, r_kj; @@ -3653,26 +3840,22 @@ real tab_angles(int nbonds, ivec jt, dt_ij, dt_kj; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; aj = forceatoms[i++]; ak = forceatoms[i++]; - theta = bond_angle(x[ai], x[aj], x[ak], pbc, - r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ + theta = bond_angle(x[ai], x[aj], x[ak], pbc, r_ij, r_kj, &cos_theta, &t1, &t2); /* 41 */ table = forceparams[type].tab.table; - *dvdlambda += bonded_tab("angle", table, - &fcd->angletab[table], - forceparams[type].tab.kA, - forceparams[type].tab.kB, - theta, lambda, &va, &dVdt); /* 22 */ + *dvdlambda += bonded_tab("angle", table, &fcd->angletab[table], forceparams[type].tab.kA, + forceparams[type].tab.kB, theta, lambda, &va, &dVdt); /* 22 */ vtot += va; - cos_theta2 = gmx::square(cos_theta); /* 1 */ + cos_theta2 = gmx::square(cos_theta); /* 1 */ if (cos_theta2 < 1) { int m; @@ -3681,20 +3864,20 @@ real tab_angles(int nbonds, real nrkj2, nrij2; rvec f_i, f_j, f_k; - st = dVdt*gmx::invsqrt(1 - cos_theta2); /* 12 */ - sth = st*cos_theta; /* 1 */ - nrkj2 = iprod(r_kj, r_kj); /* 5 */ + st = dVdt * gmx::invsqrt(1 - cos_theta2); /* 12 */ + sth = st * cos_theta; /* 1 */ + nrkj2 = iprod(r_kj, r_kj); /* 5 */ nrij2 = iprod(r_ij, r_ij); - cik = st*gmx::invsqrt(nrkj2*nrij2); /* 12 */ - cii = sth/nrij2; /* 10 */ - ckk = sth/nrkj2; /* 10 */ + cik = st * gmx::invsqrt(nrkj2 * nrij2); /* 12 */ + cii = sth / nrij2; /* 10 */ + ckk = sth / nrkj2; /* 10 */ - for (m = 0; (m < DIM); m++) /* 39 */ + for (m = 0; (m < DIM); m++) /* 39 */ { - f_i[m] = -(cik*r_kj[m]-cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m]-ckk*r_kj[m]); - f_j[m] = -f_i[m]-f_k[m]; + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; f[ai][m] += f_i[m]; f[aj][m] += f_j[m]; f[ak][m] += f_k[m]; @@ -3715,19 +3898,25 @@ real tab_angles(int nbonds, rvec_inc(fshift[CENTRAL], f_j); rvec_inc(fshift[t2], f_k); } - } /* 169 TOTAL */ + } /* 169 TOTAL */ } return vtot; } -template -real tab_dihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata *fcd, - int gmx_unused *global_atom_index) +template +real tab_dihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index) { int i, type, ai, aj, ak, al, table; int t1, t2, t3; @@ -3735,7 +3924,7 @@ real tab_dihs(int nbonds, real phi, ddphi, vpd, vtot; vtot = 0.0; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; @@ -3743,23 +3932,19 @@ real tab_dihs(int nbonds, ak = forceatoms[i++]; al = forceatoms[i++]; - phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, - &t1, &t2, &t3); /* 84 */ + phi = dih_angle(x[ai], x[aj], x[ak], x[al], pbc, r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* 84 */ table = forceparams[type].tab.table; /* Hopefully phi+M_PI never results in values < 0 */ - *dvdlambda += bonded_tab("dihedral", table, - &fcd->dihtab[table], - forceparams[type].tab.kA, - forceparams[type].tab.kB, - phi+M_PI, lambda, &vpd, &ddphi); + *dvdlambda += bonded_tab("dihedral", table, &fcd->dihtab[table], forceparams[type].tab.kA, + forceparams[type].tab.kB, phi + M_PI, lambda, &vpd, &ddphi); vtot += vpd; - do_dih_fup(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, - f, fshift, pbc, g, x, t1, t2, t3); /* 112 */ + do_dih_fup(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, f, fshift, pbc, g, x, t1, + t2, t3); /* 112 */ - } /* 227 TOTAL */ + } /* 227 TOTAL */ return vtot; } @@ -3774,105 +3959,103 @@ struct BondedInteractions * * This must have as many entries as interaction_function in ifunc.cpp */ template -const std::array c_bondedInteractionFunctions - = { - BondedInteractions {bonds, eNR_BONDS }, // F_BONDS - BondedInteractions {g96bonds, eNR_BONDS }, // F_G96BONDS - BondedInteractions {morse_bonds, eNR_MORSE }, // F_MORSE - BondedInteractions {cubic_bonds, eNR_CUBICBONDS }, // F_CUBICBONDS - BondedInteractions {unimplemented, -1 }, // F_CONNBONDS - BondedInteractions {bonds, eNR_BONDS }, // F_HARMONIC - BondedInteractions {FENE_bonds, eNR_FENEBONDS }, // F_FENEBONDS - BondedInteractions {tab_bonds, eNR_TABBONDS }, // F_TABBONDS - BondedInteractions {tab_bonds, eNR_TABBONDS }, // F_TABBONDSNC - BondedInteractions {restraint_bonds, eNR_RESTRBONDS }, // F_RESTRBONDS - BondedInteractions {angles, eNR_ANGLES }, // F_ANGLES - BondedInteractions {g96angles, eNR_ANGLES }, // F_G96ANGLES - BondedInteractions {restrangles, eNR_ANGLES }, // F_RESTRANGLES - BondedInteractions {linear_angles, eNR_ANGLES }, // F_LINEAR_ANGLES - BondedInteractions {cross_bond_bond, eNR_CROSS_BOND_BOND }, // F_CROSS_BOND_BONDS - BondedInteractions {cross_bond_angle, eNR_CROSS_BOND_ANGLE }, // F_CROSS_BOND_ANGLES - BondedInteractions {urey_bradley, eNR_UREY_BRADLEY }, // F_UREY_BRADLEY - BondedInteractions {quartic_angles, eNR_QANGLES }, // F_QUARTIC_ANGLES - BondedInteractions {tab_angles, eNR_TABANGLES }, // F_TABANGLES - BondedInteractions {pdihs, eNR_PROPER }, // F_PDIHS - BondedInteractions {rbdihs, eNR_RB }, // F_RBDIHS - BondedInteractions {restrdihs, eNR_PROPER }, // F_RESTRDIHS - BondedInteractions {cbtdihs, eNR_RB }, // F_CBTDIHS - BondedInteractions {rbdihs, eNR_FOURDIH }, // F_FOURDIHS - BondedInteractions {idihs, eNR_IMPROPER }, // F_IDIHS - BondedInteractions {pdihs, eNR_IMPROPER }, // F_PIDIHS - BondedInteractions {tab_dihs, eNR_TABDIHS }, // F_TABDIHS - BondedInteractions {unimplemented, eNR_CMAP }, // F_CMAP - BondedInteractions {unimplemented, -1 }, // F_GB12_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_GB13_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_GB14_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_GBPOL_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_NPSOLVATION_NOLONGERUSED - BondedInteractions {unimplemented, eNR_NB14 }, // F_LJ14 - BondedInteractions {unimplemented, -1 }, // F_COUL14 - BondedInteractions {unimplemented, eNR_NB14 }, // F_LJC14_Q - BondedInteractions {unimplemented, eNR_NB14 }, // F_LJC_PAIRS_NB - BondedInteractions {unimplemented, -1 }, // F_LJ - BondedInteractions {unimplemented, -1 }, // F_BHAM - BondedInteractions {unimplemented, -1 }, // F_LJ_LR_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_BHAM_LR_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_DISPCORR - BondedInteractions {unimplemented, -1 }, // F_COUL_SR - BondedInteractions {unimplemented, -1 }, // F_COUL_LR_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_RF_EXCL - BondedInteractions {unimplemented, -1 }, // F_COUL_RECIP - BondedInteractions {unimplemented, -1 }, // F_LJ_RECIP - BondedInteractions {unimplemented, -1 }, // F_DPD - BondedInteractions {polarize, eNR_POLARIZE }, // F_POLARIZATION - BondedInteractions {water_pol, eNR_WPOL }, // F_WATER_POL - BondedInteractions {thole_pol, eNR_THOLE }, // F_THOLE_POL - BondedInteractions {anharm_polarize, eNR_ANHARM_POL }, // F_ANHARM_POL - BondedInteractions {unimplemented, -1 }, // F_POSRES - BondedInteractions {unimplemented, -1 }, // F_FBPOSRES - BondedInteractions {ta_disres, eNR_DISRES }, // F_DISRES - BondedInteractions {unimplemented, -1 }, // F_DISRESVIOL - BondedInteractions {orires, eNR_ORIRES }, // F_ORIRES - BondedInteractions {unimplemented, -1 }, // F_ORIRESDEV - BondedInteractions {angres, eNR_ANGRES }, // F_ANGRES - BondedInteractions {angresz, eNR_ANGRESZ }, // F_ANGRESZ - BondedInteractions {dihres, eNR_DIHRES }, // F_DIHRES - BondedInteractions {unimplemented, -1 }, // F_DIHRESVIOL - BondedInteractions {unimplemented, -1 }, // F_CONSTR - BondedInteractions {unimplemented, -1 }, // F_CONSTRNC - BondedInteractions {unimplemented, -1 }, // F_SETTLE - BondedInteractions {unimplemented, -1 }, // F_VSITE2 - BondedInteractions {unimplemented, -1 }, // F_VSITE3 - BondedInteractions {unimplemented, -1 }, // F_VSITE3FD - BondedInteractions {unimplemented, -1 }, // F_VSITE3FAD - BondedInteractions {unimplemented, -1 }, // F_VSITE3OUT - BondedInteractions {unimplemented, -1 }, // F_VSITE4FD - BondedInteractions {unimplemented, -1 }, // F_VSITE4FDN - BondedInteractions {unimplemented, -1 }, // F_VSITEN - BondedInteractions {unimplemented, -1 }, // F_COM_PULL - BondedInteractions {unimplemented, -1 }, // F_DENSITYFITTING - BondedInteractions {unimplemented, -1 }, // F_EQM - BondedInteractions {unimplemented, -1 }, // F_EPOT - BondedInteractions {unimplemented, -1 }, // F_EKIN - BondedInteractions {unimplemented, -1 }, // F_ETOT - BondedInteractions {unimplemented, -1 }, // F_ECONSERVED - BondedInteractions {unimplemented, -1 }, // F_TEMP - BondedInteractions {unimplemented, -1 }, // F_VTEMP_NOLONGERUSED - BondedInteractions {unimplemented, -1 }, // F_PDISPCORR - BondedInteractions {unimplemented, -1 }, // F_PRES - BondedInteractions {unimplemented, -1 }, // F_DVDL_CONSTR - BondedInteractions {unimplemented, -1 }, // F_DVDL - BondedInteractions {unimplemented, -1 }, // F_DKDL - BondedInteractions {unimplemented, -1 }, // F_DVDL_COUL - BondedInteractions {unimplemented, -1 }, // F_DVDL_VDW - BondedInteractions {unimplemented, -1 }, // F_DVDL_BONDED - BondedInteractions {unimplemented, -1 }, // F_DVDL_RESTRAINT - BondedInteractions {unimplemented, -1 }, // F_DVDL_TEMPERATURE - }; +const std::array c_bondedInteractionFunctions = { + BondedInteractions{ bonds, eNR_BONDS }, // F_BONDS + BondedInteractions{ g96bonds, eNR_BONDS }, // F_G96BONDS + BondedInteractions{ morse_bonds, eNR_MORSE }, // F_MORSE + BondedInteractions{ cubic_bonds, eNR_CUBICBONDS }, // F_CUBICBONDS + BondedInteractions{ unimplemented, -1 }, // F_CONNBONDS + BondedInteractions{ bonds, eNR_BONDS }, // F_HARMONIC + BondedInteractions{ FENE_bonds, eNR_FENEBONDS }, // F_FENEBONDS + BondedInteractions{ tab_bonds, eNR_TABBONDS }, // F_TABBONDS + BondedInteractions{ tab_bonds, eNR_TABBONDS }, // F_TABBONDSNC + BondedInteractions{ restraint_bonds, eNR_RESTRBONDS }, // F_RESTRBONDS + BondedInteractions{ angles, eNR_ANGLES }, // F_ANGLES + BondedInteractions{ g96angles, eNR_ANGLES }, // F_G96ANGLES + BondedInteractions{ restrangles, eNR_ANGLES }, // F_RESTRANGLES + BondedInteractions{ linear_angles, eNR_ANGLES }, // F_LINEAR_ANGLES + BondedInteractions{ cross_bond_bond, eNR_CROSS_BOND_BOND }, // F_CROSS_BOND_BONDS + BondedInteractions{ cross_bond_angle, eNR_CROSS_BOND_ANGLE }, // F_CROSS_BOND_ANGLES + BondedInteractions{ urey_bradley, eNR_UREY_BRADLEY }, // F_UREY_BRADLEY + BondedInteractions{ quartic_angles, eNR_QANGLES }, // F_QUARTIC_ANGLES + BondedInteractions{ tab_angles, eNR_TABANGLES }, // F_TABANGLES + BondedInteractions{ pdihs, eNR_PROPER }, // F_PDIHS + BondedInteractions{ rbdihs, eNR_RB }, // F_RBDIHS + BondedInteractions{ restrdihs, eNR_PROPER }, // F_RESTRDIHS + BondedInteractions{ cbtdihs, eNR_RB }, // F_CBTDIHS + BondedInteractions{ rbdihs, eNR_FOURDIH }, // F_FOURDIHS + BondedInteractions{ idihs, eNR_IMPROPER }, // F_IDIHS + BondedInteractions{ pdihs, eNR_IMPROPER }, // F_PIDIHS + BondedInteractions{ tab_dihs, eNR_TABDIHS }, // F_TABDIHS + BondedInteractions{ unimplemented, eNR_CMAP }, // F_CMAP + BondedInteractions{ unimplemented, -1 }, // F_GB12_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_GB13_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_GB14_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_GBPOL_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_NPSOLVATION_NOLONGERUSED + BondedInteractions{ unimplemented, eNR_NB14 }, // F_LJ14 + BondedInteractions{ unimplemented, -1 }, // F_COUL14 + BondedInteractions{ unimplemented, eNR_NB14 }, // F_LJC14_Q + BondedInteractions{ unimplemented, eNR_NB14 }, // F_LJC_PAIRS_NB + BondedInteractions{ unimplemented, -1 }, // F_LJ + BondedInteractions{ unimplemented, -1 }, // F_BHAM + BondedInteractions{ unimplemented, -1 }, // F_LJ_LR_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_BHAM_LR_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_DISPCORR + BondedInteractions{ unimplemented, -1 }, // F_COUL_SR + BondedInteractions{ unimplemented, -1 }, // F_COUL_LR_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_RF_EXCL + BondedInteractions{ unimplemented, -1 }, // F_COUL_RECIP + BondedInteractions{ unimplemented, -1 }, // F_LJ_RECIP + BondedInteractions{ unimplemented, -1 }, // F_DPD + BondedInteractions{ polarize, eNR_POLARIZE }, // F_POLARIZATION + BondedInteractions{ water_pol, eNR_WPOL }, // F_WATER_POL + BondedInteractions{ thole_pol, eNR_THOLE }, // F_THOLE_POL + BondedInteractions{ anharm_polarize, eNR_ANHARM_POL }, // F_ANHARM_POL + BondedInteractions{ unimplemented, -1 }, // F_POSRES + BondedInteractions{ unimplemented, -1 }, // F_FBPOSRES + BondedInteractions{ ta_disres, eNR_DISRES }, // F_DISRES + BondedInteractions{ unimplemented, -1 }, // F_DISRESVIOL + BondedInteractions{ orires, eNR_ORIRES }, // F_ORIRES + BondedInteractions{ unimplemented, -1 }, // F_ORIRESDEV + BondedInteractions{ angres, eNR_ANGRES }, // F_ANGRES + BondedInteractions{ angresz, eNR_ANGRESZ }, // F_ANGRESZ + BondedInteractions{ dihres, eNR_DIHRES }, // F_DIHRES + BondedInteractions{ unimplemented, -1 }, // F_DIHRESVIOL + BondedInteractions{ unimplemented, -1 }, // F_CONSTR + BondedInteractions{ unimplemented, -1 }, // F_CONSTRNC + BondedInteractions{ unimplemented, -1 }, // F_SETTLE + BondedInteractions{ unimplemented, -1 }, // F_VSITE2 + BondedInteractions{ unimplemented, -1 }, // F_VSITE3 + BondedInteractions{ unimplemented, -1 }, // F_VSITE3FD + BondedInteractions{ unimplemented, -1 }, // F_VSITE3FAD + BondedInteractions{ unimplemented, -1 }, // F_VSITE3OUT + BondedInteractions{ unimplemented, -1 }, // F_VSITE4FD + BondedInteractions{ unimplemented, -1 }, // F_VSITE4FDN + BondedInteractions{ unimplemented, -1 }, // F_VSITEN + BondedInteractions{ unimplemented, -1 }, // F_COM_PULL + BondedInteractions{ unimplemented, -1 }, // F_DENSITYFITTING + BondedInteractions{ unimplemented, -1 }, // F_EQM + BondedInteractions{ unimplemented, -1 }, // F_EPOT + BondedInteractions{ unimplemented, -1 }, // F_EKIN + BondedInteractions{ unimplemented, -1 }, // F_ETOT + BondedInteractions{ unimplemented, -1 }, // F_ECONSERVED + BondedInteractions{ unimplemented, -1 }, // F_TEMP + BondedInteractions{ unimplemented, -1 }, // F_VTEMP_NOLONGERUSED + BondedInteractions{ unimplemented, -1 }, // F_PDISPCORR + BondedInteractions{ unimplemented, -1 }, // F_PRES + BondedInteractions{ unimplemented, -1 }, // F_DVDL_CONSTR + BondedInteractions{ unimplemented, -1 }, // F_DVDL + BondedInteractions{ unimplemented, -1 }, // F_DKDL + BondedInteractions{ unimplemented, -1 }, // F_DVDL_COUL + BondedInteractions{ unimplemented, -1 }, // F_DVDL_VDW + BondedInteractions{ unimplemented, -1 }, // F_DVDL_BONDED + BondedInteractions{ unimplemented, -1 }, // F_DVDL_RESTRAINT + BondedInteractions{ unimplemented, -1 }, // F_DVDL_TEMPERATURE +}; /*! \brief List of instantiated BondedInteractions list */ -const gmx::EnumerationArray < BondedKernelFlavor, std::array < BondedInteractions, F_NRE>> c_bondedInteractionFunctionsPerFlavor = -{ +const gmx::EnumerationArray> c_bondedInteractionFunctionsPerFlavor = { c_bondedInteractionFunctions, c_bondedInteractionFunctions, c_bondedInteractionFunctions, @@ -3883,25 +4066,26 @@ const gmx::EnumerationArray < BondedKernelFlavor, std::array < BondedInteraction } // namespace -real calculateSimpleBond(const int ftype, - const int numForceatoms, const t_iatom forceatoms[], - const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, - const struct t_graph gmx_unused *g, - const real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int gmx_unused *global_atom_index, +real calculateSimpleBond(const int ftype, + const int numForceatoms, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph gmx_unused* g, + const real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index, const BondedKernelFlavor bondedKernelFlavor) { - const BondedInteractions &bonded = - c_bondedInteractionFunctionsPerFlavor[bondedKernelFlavor][ftype]; - - real v = bonded.function(numForceatoms, forceatoms, - forceparams, - x, f, fshift, - pbc, g, lambda, dvdlambda, - md, fcd, global_atom_index); + const BondedInteractions& bonded = c_bondedInteractionFunctionsPerFlavor[bondedKernelFlavor][ftype]; + + real v = bonded.function(numForceatoms, forceatoms, forceparams, x, f, fshift, pbc, g, lambda, + dvdlambda, md, fcd, global_atom_index); return v; } diff --git a/src/gromacs/listed_forces/bonded.h b/src/gromacs/listed_forces/bonded.h index bd17047729..e6d129dd78 100644 --- a/src/gromacs/listed_forces/bonded.h +++ b/src/gromacs/listed_forces/bonded.h @@ -59,42 +59,74 @@ struct t_nrnb; struct t_pbc; /*! \brief Calculate bond-angle. No PBC is taken into account (use mol-shift) */ -real bond_angle(const rvec xi, const rvec xj, const rvec xk, - const struct t_pbc *pbc, - rvec r_ij, rvec r_kj, real *costh, - int *t1, int *t2); /* out */ +real bond_angle(const rvec xi, + const rvec xj, + const rvec xk, + const struct t_pbc* pbc, + rvec r_ij, + rvec r_kj, + real* costh, + int* t1, + int* t2); /* out */ /*! \brief Calculate dihedral-angle. No PBC is taken into account (use mol-shift) */ -real dih_angle(const rvec xi, const rvec xj, const rvec xk, const rvec xl, - const struct t_pbc *pbc, - rvec r_ij, rvec r_kj, rvec r_kl, rvec m, rvec n, /* out */ - int *t1, int *t2, int *t3); +real dih_angle(const rvec xi, + const rvec xj, + const rvec xk, + const rvec xl, + const struct t_pbc* pbc, + rvec r_ij, + rvec r_kj, + rvec r_kl, + rvec m, + rvec n, /* out */ + int* t1, + int* t2, + int* t3); /*! \brief Do an update of the forces for dihedral potentials */ -void do_dih_fup(int i, int j, int k, int l, real ddphi, - rvec r_ij, rvec r_kj, rvec r_kl, - rvec m, rvec n, rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - const rvec *x, int t1, int t2, int t3); +void do_dih_fup(int i, + int j, + int k, + int l, + real ddphi, + rvec r_ij, + rvec r_kj, + rvec r_kl, + rvec m, + rvec n, + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + const rvec* x, + int t1, + int t2, + int t3); /*! \brief Make a dihedral fall in the range (-pi,pi) */ -void make_dp_periodic(real *dp); +void make_dp_periodic(real* dp); /*! \brief Compute CMAP dihedral energies and forces */ -real - cmap_dihs(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const gmx_cmap_t *cmap_grid, - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata gmx_unused *fcd, - int gmx_unused *global_atom_index); +real cmap_dihs(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const gmx_cmap_t* cmap_grid, + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata gmx_unused* fcd, + int gmx_unused* global_atom_index); /*! \brief For selecting which flavor of bonded kernel is used for simple bonded types */ enum class BondedKernelFlavor { - ForcesSimdWhenAvailable, //!< Compute only forces, use SIMD when available; should not be used with perturbed parameters + ForcesSimdWhenAvailable, //!< Compute only forces, use SIMD when available; should not be used with perturbed parameters ForcesNoSimd, //!< Compute only forces, do not use SIMD ForcesAndVirialAndEnergy, //!< Compute forces, virial and energy (no SIMD) ForcesAndEnergy, //!< Compute forces and energy (no SIMD) @@ -104,8 +136,8 @@ enum class BondedKernelFlavor /*! \brief Returns whether the energy should be computed */ static constexpr inline bool computeEnergy(const BondedKernelFlavor flavor) { - return (flavor == BondedKernelFlavor::ForcesAndVirialAndEnergy || - flavor == BondedKernelFlavor::ForcesAndEnergy); + return (flavor == BondedKernelFlavor::ForcesAndVirialAndEnergy + || flavor == BondedKernelFlavor::ForcesAndEnergy); } /*! \brief Returns whether the virial should be computed */ @@ -117,8 +149,8 @@ static constexpr inline bool computeVirial(const BondedKernelFlavor flavor) /*! \brief Returns whether the energy and/or virial should be computed */ static constexpr inline bool computeEnergyOrVirial(const BondedKernelFlavor flavor) { - return (flavor == BondedKernelFlavor::ForcesAndVirialAndEnergy || - flavor == BondedKernelFlavor::ForcesAndEnergy); + return (flavor == BondedKernelFlavor::ForcesAndVirialAndEnergy + || flavor == BondedKernelFlavor::ForcesAndEnergy); } /*! \brief Calculates bonded interactions for simple bonded types @@ -127,15 +159,20 @@ static constexpr inline bool computeEnergyOrVirial(const BondedKernelFlavor flav * All pointers should be non-null, except for pbc and g which can be nullptr. * \returns the energy or 0 when \p bondedKernelFlavor did not request the energy. */ -real calculateSimpleBond(int ftype, - int numForceatoms, const t_iatom forceatoms[], - const t_iparams forceparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, - const struct t_graph gmx_unused *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int gmx_unused *global_atom_index, +real calculateSimpleBond(int ftype, + int numForceatoms, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph gmx_unused* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index, BondedKernelFlavor bondedKernelFlavor); //! Getter for finding the flop count for an \c ftype interaction. diff --git a/src/gromacs/listed_forces/disre.cpp b/src/gromacs/listed_forces/disre.cpp index 6748654676..0847e759a8 100644 --- a/src/gromacs/listed_forces/disre.cpp +++ b/src/gromacs/listed_forces/disre.cpp @@ -67,17 +67,21 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -void init_disres(FILE *fplog, const gmx_mtop_t *mtop, - t_inputrec *ir, const t_commrec *cr, - const gmx_multisim_t *ms, - t_fcdata *fcd, t_state *state, gmx_bool bIsREMD) +void init_disres(FILE* fplog, + const gmx_mtop_t* mtop, + t_inputrec* ir, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_fcdata* fcd, + t_state* state, + gmx_bool bIsREMD) { - int fa, nmol, npair, np; - t_disresdata *dd; - history_t *hist; - gmx_mtop_ilistloop_t iloop; - char *ptr; - int type_min, type_max; + int fa, nmol, npair, np; + t_disresdata* dd; + history_t* hist; + gmx_mtop_ilistloop_t iloop; + char* ptr; + int type_min, type_max; dd = &(fcd->disres); @@ -97,11 +101,11 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, dd->dr_fc = ir->dr_fc; if (EI_DYNAMICS(ir->eI)) { - dd->dr_tau = ir->dr_tau; + dd->dr_tau = ir->dr_tau; } else { - dd->dr_tau = 0.0; + dd->dr_tau = 0.0; } if (dd->dr_tau == 0.0) { @@ -117,24 +121,30 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, */ if (cr && PAR(cr)) { - gmx_fatal(FARGS, "Time-averaged distance restraints are not supported with MPI parallelization. You can use OpenMP parallelization on a single node."); + gmx_fatal(FARGS, + "Time-averaged distance restraints are not supported with MPI " + "parallelization. You can use OpenMP parallelization on a single node."); } dd->dr_bMixed = ir->bDisreMixed; - dd->ETerm = std::exp(-(ir->delta_t/ir->dr_tau)); + dd->ETerm = std::exp(-(ir->delta_t / ir->dr_tau)); } - dd->ETerm1 = 1.0 - dd->ETerm; + dd->ETerm1 = 1.0 - dd->ETerm; dd->nres = 0; dd->npair = 0; type_min = INT_MAX; type_max = 0; iloop = gmx_mtop_ilistloop_init(mtop); - while (const InteractionLists *il = gmx_mtop_ilistloop_next(iloop, &nmol)) + while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) { if (nmol > 1 && (*il)[F_DISRES].size() > 0 && ir->eDisre != edrEnsemble) { - gmx_fatal(FARGS, "NMR distance restraints with multiple copies of the same molecule are currently only supported with ensemble averaging. If you just want to restrain distances between atom pairs using a flat-bottomed potential, use a restraint potential (bonds type 10) instead."); + gmx_fatal(FARGS, + "NMR distance restraints with multiple copies of the same molecule are " + "currently only supported with ensemble averaging. If you just want to " + "restrain distances between atom pairs using a flat-bottomed potential, use " + "a restraint potential (bonds type 10) instead."); } np = 0; @@ -142,18 +152,18 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, { int type; - type = (*il)[F_DISRES].iatoms[fa]; + type = (*il)[F_DISRES].iatoms[fa]; np++; npair = mtop->ffparams.iparams[type].disres.npair; if (np == npair) { - dd->nres += (ir->eDisre == edrEnsemble ? 1 : nmol); - dd->npair += nmol*npair; - np = 0; + dd->nres += (ir->eDisre == edrEnsemble ? 1 : nmol); + dd->npair += nmol * npair; + np = 0; - type_min = std::min(type_min, type); - type_max = std::max(type_max, type); + type_min = std::min(type_min, type); + type_max = std::max(type_max, type); } } } @@ -161,7 +171,9 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, if (cr && PAR(cr) && ir->nstdisreout > 0) { /* With DD we currently only have local pair information available */ - gmx_fatal(FARGS, "With MPI parallelization distance-restraint pair output is not supported. Use nstdisreout=0 or use OpenMP parallelization on a single node."); + gmx_fatal(FARGS, + "With MPI parallelization distance-restraint pair output is not supported. Use " + "nstdisreout=0 or use OpenMP parallelization on a single node."); } /* For communicating and/or reducing (sums of) r^-6 for pairs over threads @@ -172,7 +184,9 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, * This setup currently does not allow for multiple copies of the same * molecule without ensemble averaging, this is check for above. */ - GMX_RELEASE_ASSERT(type_max - type_min + 1 == dd->nres, "All distance restraint parameter entries in the topology should be consecutive"); + GMX_RELEASE_ASSERT( + type_max - type_min + 1 == dd->nres, + "All distance restraint parameter entries in the topology should be consecutive"); dd->type_min = type_min; @@ -180,14 +194,15 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, if (dd->dr_tau != 0.0) { - GMX_RELEASE_ASSERT(state != nullptr, "We need a valid state when using time-averaged distance restraints"); + GMX_RELEASE_ASSERT(state != nullptr, + "We need a valid state when using time-averaged distance restraints"); hist = &state->hist; /* Set the "history lack" factor to 1 */ - state->flags |= (1<flags |= (1 << estDISRE_INITF); hist->disre_initf = 1.0; /* Allocate space for the r^-3 time averages */ - state->flags |= (1<flags |= (1 << estDISRE_RM3TAV); hist->ndisrepairs = dd->npair; snew(hist->disre_rm3tav, hist->ndisrepairs); } @@ -199,7 +214,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, /* Allocate Rt_6 and Rtav_6 consecutively in memory so they can be * averaged over the processors in one call (in calc_disre_R_6) */ - snew(dd->Rt_6, 2*dd->nres); + snew(dd->Rt_6, 2 * dd->nres); dd->Rtav_6 = &(dd->Rt_6[dd->nres]); ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE"); @@ -217,9 +232,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, * than one processor per simulation system. */ if (MASTER(cr)) { - check_multi_int(fplog, ms, dd->nsystems, - "the number of systems per ensemble", - FALSE); + check_multi_int(fplog, ms, dd->nsystems, "the number of systems per ensemble", FALSE); } gmx_bcast_sim(sizeof(int), &dd->nsystems, cr); @@ -229,15 +242,17 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, */ if (!(ms->nsim == 1 || ms->nsim == dd->nsystems)) { - gmx_fatal(FARGS, "GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multidir) %d", dd->nsystems, ms->nsim); + gmx_fatal(FARGS, + "GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems " + "(option -multidir) %d", + dd->nsystems, ms->nsim); } if (fplog) { fprintf(fplog, "Our ensemble consists of systems:"); for (int i = 0; i < dd->nsystems; i++) { - fprintf(fplog, " %d", - (ms->sim/dd->nsystems)*dd->nsystems+i); + fprintf(fplog, " %d", (ms->sim / dd->nsystems) * dd->nsystems + i); } fprintf(fplog, "\n"); } @@ -250,7 +265,7 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, if (dd->nsystems == 1) { - dd->Rtl_6 = dd->Rt_6; + dd->Rtl_6 = dd->Rt_6; } else { @@ -261,7 +276,8 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, { if (fplog) { - fprintf(fplog, "There are %d distance restraints involving %d atom pairs\n", dd->nres, dd->npair); + fprintf(fplog, "There are %d distance restraints involving %d atom pairs\n", dd->nres, + dd->npair); } /* Have to avoid g_disre de-referencing cr blindly, mdrun not * doing consistency checks for ensemble-averaged distance @@ -271,45 +287,46 @@ void init_disres(FILE *fplog, const gmx_mtop_t *mtop, * succeed...) */ if (cr && ms && dd->nsystems > 1 && MASTER(cr)) { - check_multi_int(fplog, ms, fcd->disres.nres, - "the number of distance restraints", - FALSE); + check_multi_int(fplog, ms, fcd->disres.nres, "the number of distance restraints", FALSE); } please_cite(fplog, "Tropp80a"); please_cite(fplog, "Torda89a"); } } -void calc_disres_R_6(const t_commrec *cr, - const gmx_multisim_t *ms, - int nfa, const t_iatom forceatoms[], - const rvec x[], const t_pbc *pbc, - t_fcdata *fcd, history_t *hist) +void calc_disres_R_6(const t_commrec* cr, + const gmx_multisim_t* ms, + int nfa, + const t_iatom forceatoms[], + const rvec x[], + const t_pbc* pbc, + t_fcdata* fcd, + history_t* hist) { - rvec dx; - real *rt, *rm3tav, *Rtl_6, *Rt_6, *Rtav_6; - t_disresdata *dd; - real ETerm, ETerm1, cf1 = 0, cf2 = 0; - gmx_bool bTav; - - dd = &(fcd->disres); - bTav = (dd->dr_tau != 0); - ETerm = dd->ETerm; - ETerm1 = dd->ETerm1; - rt = dd->rt; - rm3tav = dd->rm3tav; - Rtl_6 = dd->Rtl_6; - Rt_6 = dd->Rt_6; - Rtav_6 = dd->Rtav_6; + rvec dx; + real * rt, *rm3tav, *Rtl_6, *Rt_6, *Rtav_6; + t_disresdata* dd; + real ETerm, ETerm1, cf1 = 0, cf2 = 0; + gmx_bool bTav; + + dd = &(fcd->disres); + bTav = (dd->dr_tau != 0); + ETerm = dd->ETerm; + ETerm1 = dd->ETerm1; + rt = dd->rt; + rm3tav = dd->rm3tav; + Rtl_6 = dd->Rtl_6; + Rt_6 = dd->Rt_6; + Rtav_6 = dd->Rtav_6; if (bTav) { /* scaling factor to smoothly turn on the restraint forces * * when using time averaging */ - dd->exp_min_t_tau = hist->disre_initf*ETerm; + dd->exp_min_t_tau = hist->disre_initf * ETerm; cf1 = dd->exp_min_t_tau; - cf2 = 1.0/(1.0 - dd->exp_min_t_tau); + cf2 = 1.0 / (1.0 - dd->exp_min_t_tau); } for (int res = 0; res < dd->nres; res++) @@ -324,9 +341,9 @@ void calc_disres_R_6(const t_commrec *cr, { int type = forceatoms[fa]; int res = type - dd->type_min; - int pair = fa/3; - int ai = forceatoms[fa+1]; - int aj = forceatoms[fa+2]; + int pair = fa / 3; + int ai = forceatoms[fa + 1]; + int aj = forceatoms[fa + 2]; if (pbc) { @@ -338,9 +355,9 @@ void calc_disres_R_6(const t_commrec *cr, } real rt2 = iprod(dx, dx); real rt_1 = gmx::invsqrt(rt2); - real rt_3 = rt_1*rt_1*rt_1; + real rt_3 = rt_1 * rt_1 * rt_1; - rt[pair] = rt2*rt_1; + rt[pair] = rt2 * rt_1; if (bTav) { /* Here we update rm3tav in t_fcdata using the data @@ -348,8 +365,7 @@ void calc_disres_R_6(const t_commrec *cr, * Thus the results stay correct when this routine * is called multiple times. */ - rm3tav[pair] = cf2*((ETerm - cf1)*hist->disre_rm3tav[pair] + - ETerm1*rt_3); + rm3tav[pair] = cf2 * ((ETerm - cf1) * hist->disre_rm3tav[pair] + ETerm1 * rt_3); } else { @@ -360,33 +376,33 @@ void calc_disres_R_6(const t_commrec *cr, * the same restraint get assigned to the same thread, so we could * run this loop thread-parallel. */ - Rt_6[res] += rt_3*rt_3; - Rtav_6[res] += rm3tav[pair]*rm3tav[pair]; + Rt_6[res] += rt_3 * rt_3; + Rtav_6[res] += rm3tav[pair] * rm3tav[pair]; } /* NOTE: Rt_6 and Rtav_6 are stored consecutively in memory */ if (cr && DOMAINDECOMP(cr)) { - gmx_sum(2*dd->nres, dd->Rt_6, cr); + gmx_sum(2 * dd->nres, dd->Rt_6, cr); } if (fcd->disres.nsystems > 1) { - real invn = 1.0/dd->nsystems; + real invn = 1.0 / dd->nsystems; for (int res = 0; res < dd->nres; res++) { - Rtl_6[res] = Rt_6[res]; - Rt_6[res] *= invn; + Rtl_6[res] = Rt_6[res]; + Rt_6[res] *= invn; Rtav_6[res] *= invn; } GMX_ASSERT(cr != nullptr && ms != nullptr, "We need multisim with nsystems>1"); - gmx_sum_sim(2*dd->nres, dd->Rt_6, ms); + gmx_sum_sim(2 * dd->nres, dd->Rt_6, ms); if (DOMAINDECOMP(cr)) { - gmx_bcast(2*dd->nres, dd->Rt_6, cr); + gmx_bcast(2 * dd->nres, dd->Rt_6, cr); } } @@ -396,30 +412,37 @@ void calc_disres_R_6(const t_commrec *cr, */ dd->forceatomsStart = forceatoms; - dd->sumviol = 0; + dd->sumviol = 0; } -real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata *fcd, - int gmx_unused *global_atom_index) +real ta_disres(int nfa, + const t_iatom forceatoms[], + const t_iparams ip[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index) { - const real seven_three = 7.0/3.0; - - rvec dx; - real weight_rt_1; - real smooth_fc, Rt, Rtav, rt2, *Rtl_6, *Rt_6, *Rtav_6; - real k0, f_scal = 0, fmax_scal, fk_scal, fij; - real tav_viol, instant_viol, mixed_viol, violtot, vtot; - real tav_viol_Rtav7, instant_viol_Rtav7; - real up1, up2, low; - gmx_bool bConservative, bMixed, bViolation; - ivec dt; - t_disresdata *dd; - int dr_weighting; - gmx_bool dr_bMixed; + const real seven_three = 7.0 / 3.0; + + rvec dx; + real weight_rt_1; + real smooth_fc, Rt, Rtav, rt2, *Rtl_6, *Rt_6, *Rtav_6; + real k0, f_scal = 0, fmax_scal, fk_scal, fij; + real tav_viol, instant_viol, mixed_viol, violtot, vtot; + real tav_viol_Rtav7, instant_viol_Rtav7; + real up1, up2, low; + gmx_bool bConservative, bMixed, bViolation; + ivec dt; + t_disresdata* dd; + int dr_weighting; + gmx_bool dr_bMixed; dd = &(fcd->disres); dr_weighting = dd->dr_weighting; @@ -451,9 +474,9 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], up1 = ip[type].disres.up1; up2 = ip[type].disres.up2; low = ip[type].disres.low; - k0 = smooth_fc*ip[type].disres.kfac; + k0 = smooth_fc * ip[type].disres.kfac; - int res = type - dd->type_min; + int res = type - dd->type_min; /* save some flops when there is only one pair */ if (ip[type].disres.type != 2) @@ -490,16 +513,16 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], if (bViolation) { /* Add 1/npair energy and violation for each of the npair pairs */ - real pairFac = 1/static_cast(npair); + real pairFac = 1 / static_cast(npair); /* NOTE: * there is no real potential when time averaging is applied */ - vtot += 0.5*k0*gmx::square(tav_viol)*pairFac; + vtot += 0.5 * k0 * gmx::square(tav_viol) * pairFac; if (!bMixed) { - f_scal = -k0*tav_viol; - violtot += fabs(tav_viol)*pairFac; + f_scal = -k0 * tav_viol; + violtot += fabs(tav_viol) * pairFac; } else { @@ -531,42 +554,42 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], } if (bViolation) { - mixed_viol = std::sqrt(tav_viol*instant_viol); - f_scal = -k0*mixed_viol; - violtot += mixed_viol*pairFac; + mixed_viol = std::sqrt(tav_viol * instant_viol); + f_scal = -k0 * mixed_viol; + violtot += mixed_viol * pairFac; } } } if (bViolation) { - fmax_scal = -k0*(up2-up1); + fmax_scal = -k0 * (up2 - up1); /* Correct the force for the number of restraints */ if (bConservative) { - f_scal = std::max(f_scal, fmax_scal); + f_scal = std::max(f_scal, fmax_scal); if (!bMixed) { - f_scal *= Rtav/Rtav_6[res]; + f_scal *= Rtav / Rtav_6[res]; } else { - f_scal /= 2*mixed_viol; - tav_viol_Rtav7 = tav_viol*Rtav/Rtav_6[res]; - instant_viol_Rtav7 = instant_viol*Rt/Rt_6[res]; + f_scal /= 2 * mixed_viol; + tav_viol_Rtav7 = tav_viol * Rtav / Rtav_6[res]; + instant_viol_Rtav7 = instant_viol * Rt / Rt_6[res]; } } else { f_scal /= npair; - f_scal = std::max(f_scal, fmax_scal); + f_scal = std::max(f_scal, fmax_scal); } /* Exert the force ... */ - int pair = (faOffset + fa)/3; - int ai = forceatoms[fa+1]; - int aj = forceatoms[fa+2]; + int pair = (faOffset + fa) / 3; + int ai = forceatoms[fa + 1]; + int aj = forceatoms[fa + 2]; int ki = CENTRAL; if (pbc) { @@ -588,12 +611,12 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], } else { - weight_rt_1 *= tav_viol_Rtav7*std::pow(dd->rm3tav[pair], seven_three)+ - instant_viol_Rtav7/(dd->rt[pair]*gmx::power6(dd->rt[pair])); + weight_rt_1 *= tav_viol_Rtav7 * std::pow(dd->rm3tav[pair], seven_three) + + instant_viol_Rtav7 / (dd->rt[pair] * gmx::power6(dd->rt[pair])); } } - fk_scal = f_scal*weight_rt_1; + fk_scal = f_scal * weight_rt_1; if (g) { @@ -603,13 +626,13 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], for (int m = 0; m < DIM; m++) { - fij = fk_scal*dx[m]; + fij = fk_scal * dx[m]; - f[ai][m] += fij; - f[aj][m] -= fij; + f[ai][m] += fij; + f[aj][m] -= fij; if (fshift) { - fshift[ki][m] += fij; + fshift[ki][m] += fij; fshift[CENTRAL][m] -= fij; } } @@ -623,9 +646,9 @@ real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], return vtot; } -void update_disres_history(const t_fcdata *fcd, history_t *hist) +void update_disres_history(const t_fcdata* fcd, history_t* hist) { - const t_disresdata *dd; + const t_disresdata* dd; int pair; dd = &(fcd->disres); diff --git a/src/gromacs/listed_forces/disre.h b/src/gromacs/listed_forces/disre.h index 7cbce33908..affe0c551e 100644 --- a/src/gromacs/listed_forces/disre.h +++ b/src/gromacs/listed_forces/disre.h @@ -67,30 +67,44 @@ class t_state; * The implementation of distance restraints with -multidir * must differ according to whether REMD is active. */ -void init_disres(FILE *fplog, const gmx_mtop_t *mtop, - t_inputrec *ir, const t_commrec *cr, - const gmx_multisim_t *ms, - t_fcdata *fcd, t_state *state, gmx_bool bIsREMD); +void init_disres(FILE* fplog, + const gmx_mtop_t* mtop, + t_inputrec* ir, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_fcdata* fcd, + t_state* state, + gmx_bool bIsREMD); /*! \brief * Calculates r and r^-3 (inst. and time averaged) for all pairs * and the ensemble averaged r^-6 (inst. and time averaged) for all restraints */ -void calc_disres_R_6(const t_commrec *cr, - const gmx_multisim_t *ms, - int nfa, const t_iatom *fa, - const rvec *x, const t_pbc *pbc, - t_fcdata *fcd, history_t *hist); +void calc_disres_R_6(const t_commrec* cr, + const gmx_multisim_t* ms, + int nfa, + const t_iatom* fa, + const rvec* x, + const t_pbc* pbc, + t_fcdata* fcd, + history_t* hist); //! Calculates the distance restraint forces, return the potential. -real ta_disres(int nfa, const t_iatom forceatoms[], const t_iparams ip[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int *global_atom_index); +real ta_disres(int nfa, + const t_iatom forceatoms[], + const t_iparams ip[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* global_atom_index); //! Copies the new time averages that have been calculated in calc_disres_R_6. -void update_disres_history(const t_fcdata *fcd, history_t *hist); +void update_disres_history(const t_fcdata* fcd, history_t* hist); #endif diff --git a/src/gromacs/listed_forces/gpubonded.h b/src/gromacs/listed_forces/gpubonded.h index 8fe7b49021..4cdc9655a4 100644 --- a/src/gromacs/listed_forces/gpubonded.h +++ b/src/gromacs/listed_forces/gpubonded.h @@ -77,17 +77,9 @@ static constexpr int numFTypesOnGpu = 8; * \note The function types in the list are ordered on increasing value. * \note Currently bonded are only supported with CUDA, not with OpenCL. */ -constexpr std::array fTypesOnGpu = -{ - F_BONDS, - F_ANGLES, - F_UREY_BRADLEY, - F_PDIHS, - F_RBDIHS, - F_IDIHS, - F_PIDIHS, - F_LJ14 -}; +constexpr std::array fTypesOnGpu = { F_BONDS, F_ANGLES, F_UREY_BRADLEY, + F_PDIHS, F_RBDIHS, F_IDIHS, + F_PIDIHS, F_LJ14 }; /*! \brief Checks whether the GROMACS build allows to compute bonded interactions on a GPU. * @@ -97,7 +89,7 @@ constexpr std::array fTypesOnGpu = * * \throws std::bad_alloc when out of memory. */ -bool buildSupportsGpuBondeds(std::string *error); +bool buildSupportsGpuBondeds(std::string* error); /*! \brief Checks whether the input system allows to compute bonded interactions on a GPU. * @@ -107,49 +99,43 @@ bool buildSupportsGpuBondeds(std::string *error); * * \returns true if PME can run on GPU with this input, false otherwise. */ -bool inputSupportsGpuBondeds(const t_inputrec &ir, - const gmx_mtop_t &mtop, - std::string *error); +bool inputSupportsGpuBondeds(const t_inputrec& ir, const gmx_mtop_t& mtop, std::string* error); class GpuBonded { - public: - //! Construct the manager with constant data and the stream to use. - GpuBonded(const gmx_ffparams_t &ffparams, - void *streamPtr, - gmx_wallcycle *wcycle); - //! Destructor - ~GpuBonded(); +public: + //! Construct the manager with constant data and the stream to use. + GpuBonded(const gmx_ffparams_t& ffparams, void* streamPtr, gmx_wallcycle* wcycle); + //! Destructor + ~GpuBonded(); - /*! \brief Update lists of interactions from idef suitable for the GPU, - * using the data structures prepared for PP work. - * - * Intended to be called after each neighbour search - * stage. Copies the bonded interactions assigned to the GPU - * to device data structures, and updates device buffers that - * may have been updated after search. */ - void updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, - const t_idef &idef, - void *xqDevice, - void *forceDevice, - void *fshiftDevice); - /*! \brief Returns whether there are bonded interactions - * assigned to the GPU */ - bool haveInteractions() const; - /*! \brief Launches bonded kernel on a GPU */ - void launchKernel(const t_forcerec *fr, - const gmx::StepWorkload &stepWork, - const matrix box); - /*! \brief Launches the transfer of computed bonded energies. */ - void launchEnergyTransfer(); - /*! \brief Waits on the energy transfer, and accumulates bonded energies to \c enerd. */ - void waitAccumulateEnergyTerms(gmx_enerdata_t *enerd); - /*! \brief Clears the device side energy buffer */ - void clearEnergies(); + /*! \brief Update lists of interactions from idef suitable for the GPU, + * using the data structures prepared for PP work. + * + * Intended to be called after each neighbour search + * stage. Copies the bonded interactions assigned to the GPU + * to device data structures, and updates device buffers that + * may have been updated after search. */ + void updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, + const t_idef& idef, + void* xqDevice, + void* forceDevice, + void* fshiftDevice); + /*! \brief Returns whether there are bonded interactions + * assigned to the GPU */ + bool haveInteractions() const; + /*! \brief Launches bonded kernel on a GPU */ + void launchKernel(const t_forcerec* fr, const gmx::StepWorkload& stepWork, const matrix box); + /*! \brief Launches the transfer of computed bonded energies. */ + void launchEnergyTransfer(); + /*! \brief Waits on the energy transfer, and accumulates bonded energies to \c enerd. */ + void waitAccumulateEnergyTerms(gmx_enerdata_t* enerd); + /*! \brief Clears the device side energy buffer */ + void clearEnergies(); - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/listed_forces/gpubonded_impl.cpp b/src/gromacs/listed_forces/gpubonded_impl.cpp index 13a7d37283..6d1dba6030 100644 --- a/src/gromacs/listed_forces/gpubonded_impl.cpp +++ b/src/gromacs/listed_forces/gpubonded_impl.cpp @@ -56,7 +56,7 @@ namespace gmx { //! Returns whether there are any interactions in ilists suitable for a GPU. -static bool someInteractionsCanRunOnGpu(const InteractionLists &ilists) +static bool someInteractionsCanRunOnGpu(const InteractionLists& ilists) { for (int fType : fTypesOnGpu) { @@ -76,10 +76,10 @@ static bool someInteractionsCanRunOnGpu(const InteractionLists &ilists) } //! Returns whether there are any bonded interactions in the global topology suitable for a GPU. -static bool bondedInteractionsCanRunOnGpu(const gmx_mtop_t &mtop) +static bool bondedInteractionsCanRunOnGpu(const gmx_mtop_t& mtop) { // Check the regular molecule types - for (const auto &moltype : mtop.moltype) + for (const auto& moltype : mtop.moltype) { if (someInteractionsCanRunOnGpu(moltype.ilist)) { @@ -101,20 +101,18 @@ static bool bondedInteractionsCanRunOnGpu(const gmx_mtop_t &mtop) * \c errorReasons why bondeds on a GPU are not supported. * * \returns Whether the lack of errorReasons indicate there is support. */ -static bool -addMessageIfNotSupported(ArrayRef errorReasons, - std::string *error) +static bool addMessageIfNotSupported(ArrayRef errorReasons, std::string* error) { bool isSupported = errorReasons.empty(); if (!isSupported && error) { - *error = "Bonded interactions cannot run on GPUs: "; + *error = "Bonded interactions cannot run on GPUs: "; *error += joinStrings(errorReasons, "; ") + "."; } return isSupported; } -bool buildSupportsGpuBondeds(std::string *error) +bool buildSupportsGpuBondeds(std::string* error) { std::vector errorReasons; @@ -133,9 +131,7 @@ bool buildSupportsGpuBondeds(std::string *error) return addMessageIfNotSupported(errorReasons, error); } -bool inputSupportsGpuBondeds(const t_inputrec &ir, - const gmx_mtop_t &mtop, - std::string *error) +bool inputSupportsGpuBondeds(const t_inputrec& ir, const gmx_mtop_t& mtop, std::string* error) { std::vector errorReasons; @@ -164,52 +160,38 @@ class GpuBonded::Impl { }; -GpuBonded::GpuBonded(const gmx_ffparams_t & /* ffparams */, - void * /*streamPtr */, - gmx_wallcycle * /* wcycle */) - : impl_(nullptr) +GpuBonded::GpuBonded(const gmx_ffparams_t& /* ffparams */, void* /*streamPtr */, gmx_wallcycle* /* wcycle */) : + impl_(nullptr) { } GpuBonded::~GpuBonded() = default; -void -GpuBonded::updateInteractionListsAndDeviceBuffers(ArrayRef /* nbnxnAtomOrder */, - const t_idef & /* idef */, - void * /* xqDevice */, - void * /* forceDevice */, - void * /* fshiftDevice */) +void GpuBonded::updateInteractionListsAndDeviceBuffers(ArrayRef /* nbnxnAtomOrder */, + const t_idef& /* idef */, + void* /* xqDevice */, + void* /* forceDevice */, + void* /* fshiftDevice */) { } -bool -GpuBonded::haveInteractions() const +bool GpuBonded::haveInteractions() const { return false; } -void -GpuBonded::launchKernel(const t_forcerec * /* fr */, - const gmx::StepWorkload & /* stepWork */, - const matrix /* box */) +void GpuBonded::launchKernel(const t_forcerec* /* fr */, + const gmx::StepWorkload& /* stepWork */, + const matrix /* box */) { } -void -GpuBonded::launchEnergyTransfer() -{ -} +void GpuBonded::launchEnergyTransfer() {} -void -GpuBonded::waitAccumulateEnergyTerms(gmx_enerdata_t * /* enerd */) -{ -} +void GpuBonded::waitAccumulateEnergyTerms(gmx_enerdata_t* /* enerd */) {} -void -GpuBonded::clearEnergies() -{ -} +void GpuBonded::clearEnergies() {} #endif /* GMX_GPU != GMX_GPU_CUDA */ -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/listed_forces/gpubonded_impl.cu b/src/gromacs/listed_forces/gpubonded_impl.cu index e71738f586..041ee514b7 100644 --- a/src/gromacs/listed_forces/gpubonded_impl.cu +++ b/src/gromacs/listed_forces/gpubonded_impl.cu @@ -62,9 +62,7 @@ namespace gmx // ---- GpuBonded::Impl -GpuBonded::Impl::Impl(const gmx_ffparams_t &ffparams, - void *streamPtr, - gmx_wallcycle *wcycle) +GpuBonded::Impl::Impl(const gmx_ffparams_t& ffparams, void* streamPtr, gmx_wallcycle* wcycle) { stream_ = *static_cast(streamPtr); wcycle_ = wcycle; @@ -73,9 +71,8 @@ GpuBonded::Impl::Impl(const gmx_ffparams_t &ffparams, // This could be an async transfer (if the source is pinned), so // long as it uses the same stream as the kernels and we are happy // to consume additional pinned pages. - copyToDeviceBuffer(&d_forceParams_, ffparams.iparams.data(), - 0, ffparams.numTypes(), - stream_, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_forceParams_, ffparams.iparams.data(), 0, ffparams.numTypes(), stream_, + GpuApiCallBehavior::Sync, nullptr); vTot_.resize(F_NRE); allocateDeviceBuffer(&d_vTot_, F_NRE, nullptr); clearDeviceBufferAsync(&d_vTot_, 0, F_NRE, stream_); @@ -87,11 +84,11 @@ GpuBonded::Impl::Impl(const gmx_ffparams_t &ffparams, d_iLists_[fType].nalloc = 0; } - kernelParams_.d_forceParams = d_forceParams_; - kernelParams_.d_xq = d_xq_; - kernelParams_.d_f = d_f_; - kernelParams_.d_fShift = d_fShift_; - kernelParams_.d_vTot = d_vTot_; + kernelParams_.d_forceParams = d_forceParams_; + kernelParams_.d_xq = d_xq_; + kernelParams_.d_f = d_f_; + kernelParams_.d_fShift = d_fShift_; + kernelParams_.d_vTot = d_vTot_; for (int i = 0; i < numFTypesOnGpu; i++) { kernelParams_.d_iatoms[i] = nullptr; @@ -116,20 +113,19 @@ GpuBonded::Impl::~Impl() } //! Return whether function type \p fType in \p idef has perturbed interactions -static bool fTypeHasPerturbedEntries(const t_idef &idef, - int fType) +static bool fTypeHasPerturbedEntries(const t_idef& idef, int fType) { GMX_ASSERT(idef.ilsort == ilsortNO_FE || idef.ilsort == ilsortFE_SORTED, "Perturbed interations should be sorted here"); - const t_ilist &ilist = idef.il[fType]; + const t_ilist& ilist = idef.il[fType]; return (idef.ilsort != ilsortNO_FE && ilist.nr_nonperturbed != ilist.nr); } //! Converts \p src with atom indices in state order to \p dest in nbnxn order -static void convertIlistToNbnxnOrder(const t_ilist &src, - HostInteractionList *dest, +static void convertIlistToNbnxnOrder(const t_ilist& src, + HostInteractionList* dest, int numAtomsPerInteraction, ArrayRef nbnxnAtomOrder) { @@ -175,12 +171,11 @@ static inline int roundUpToFactor(const int input, const int factor) * interaction type are stored in kernelParams_. Pointers to the relevant data structures on the * GPU are also stored in kernelParams_. */ -void -GpuBonded::Impl::updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, - const t_idef &idef, - void *d_xqPtr, - void *d_fPtr, - void *d_fShiftPtr) +void GpuBonded::Impl::updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, + const t_idef& idef, + void* d_xqPtr, + void* d_fPtr, + void* d_fShiftPtr) { // TODO wallcycle sub start haveInteractions_ = false; @@ -188,7 +183,7 @@ GpuBonded::Impl::updateInteractionListsAndDeviceBuffers(ArrayRef nbn for (int fType : fTypesOnGpu) { - auto &iList = iLists_[fType]; + auto& iList = iLists_[fType]; /* Perturbation is not implemented in the GPU bonded kernels. * But instead of doing all interactions on the CPU, we can @@ -198,9 +193,7 @@ GpuBonded::Impl::updateInteractionListsAndDeviceBuffers(ArrayRef nbn { haveInteractions_ = true; - convertIlistToNbnxnOrder(idef.il[fType], - &iList, - NRAL(fType), nbnxnAtomOrder); + convertIlistToNbnxnOrder(idef.il[fType], &iList, NRAL(fType), nbnxnAtomOrder); } else { @@ -213,74 +206,78 @@ GpuBonded::Impl::updateInteractionListsAndDeviceBuffers(ArrayRef nbn // end. if (iList.size() > 0) { - t_ilist &d_iList = d_iLists_[fType]; + t_ilist& d_iList = d_iLists_[fType]; reallocateDeviceBuffer(&d_iList.iatoms, iList.size(), &d_iList.nr, &d_iList.nalloc, nullptr); - copyToDeviceBuffer(&d_iList.iatoms, iList.iatoms.data(), - 0, iList.size(), - stream_, GpuApiCallBehavior::Async, nullptr); + copyToDeviceBuffer(&d_iList.iatoms, iList.iatoms.data(), 0, iList.size(), stream_, + GpuApiCallBehavior::Async, nullptr); } kernelParams_.fTypesOnGpu[fTypesCounter] = fType; kernelParams_.numFTypeIAtoms[fTypesCounter] = iList.size(); int numBonds = iList.size() / (interaction_function[fType].nratoms + 1); - kernelParams_.numFTypeBonds[fTypesCounter] = numBonds; - kernelParams_.d_iatoms[fTypesCounter] = d_iLists_[fType].iatoms; + kernelParams_.numFTypeBonds[fTypesCounter] = numBonds; + kernelParams_.d_iatoms[fTypesCounter] = d_iLists_[fType].iatoms; if (fTypesCounter == 0) { kernelParams_.fTypeRangeStart[fTypesCounter] = 0; } else { - kernelParams_.fTypeRangeStart[fTypesCounter] = kernelParams_.fTypeRangeEnd[fTypesCounter - 1] + 1; + kernelParams_.fTypeRangeStart[fTypesCounter] = + kernelParams_.fTypeRangeEnd[fTypesCounter - 1] + 1; } - kernelParams_.fTypeRangeEnd[fTypesCounter] = kernelParams_.fTypeRangeStart[fTypesCounter] + roundUpToFactor(numBonds, warp_size) - 1; - - GMX_ASSERT(numBonds > 0 || kernelParams_.fTypeRangeEnd[fTypesCounter] <= kernelParams_.fTypeRangeStart[fTypesCounter], - "Invalid GPU listed forces setup. numBonds must be > 0 if there are threads allocated to do work on that interaction function type."); - GMX_ASSERT(kernelParams_.fTypeRangeStart[fTypesCounter] % warp_size == 0 && (kernelParams_.fTypeRangeEnd[fTypesCounter] + 1) % warp_size == 0, + kernelParams_.fTypeRangeEnd[fTypesCounter] = kernelParams_.fTypeRangeStart[fTypesCounter] + + roundUpToFactor(numBonds, warp_size) - 1; + + GMX_ASSERT(numBonds > 0 + || kernelParams_.fTypeRangeEnd[fTypesCounter] + <= kernelParams_.fTypeRangeStart[fTypesCounter], + "Invalid GPU listed forces setup. numBonds must be > 0 if there are threads " + "allocated to do work on that interaction function type."); + GMX_ASSERT(kernelParams_.fTypeRangeStart[fTypesCounter] % warp_size == 0 + && (kernelParams_.fTypeRangeEnd[fTypesCounter] + 1) % warp_size == 0, "The bonded interactions must be assigned to the GPU in blocks of warp size."); fTypesCounter++; } - d_xq_ = static_cast(d_xqPtr); - d_f_ = static_cast(d_fPtr); - d_fShift_ = static_cast(d_fShiftPtr); + d_xq_ = static_cast(d_xqPtr); + d_f_ = static_cast(d_fPtr); + d_fShift_ = static_cast(d_fShiftPtr); - kernelParams_.d_xq = d_xq_; - kernelParams_.d_f = d_f_; - kernelParams_.d_fShift = d_fShift_; - kernelParams_.d_forceParams = d_forceParams_; - kernelParams_.d_vTot = d_vTot_; + kernelParams_.d_xq = d_xq_; + kernelParams_.d_f = d_f_; + kernelParams_.d_fShift = d_fShift_; + kernelParams_.d_forceParams = d_forceParams_; + kernelParams_.d_vTot = d_vTot_; // TODO wallcycle sub stop } -bool -GpuBonded::Impl::haveInteractions() const +bool GpuBonded::Impl::haveInteractions() const { return haveInteractions_; } -void -GpuBonded::Impl::launchEnergyTransfer() +void GpuBonded::Impl::launchEnergyTransfer() { - GMX_ASSERT(haveInteractions_, "No GPU bonded interactions, so no energies will be computed, so transfer should not be called"); + GMX_ASSERT(haveInteractions_, + "No GPU bonded interactions, so no energies will be computed, so transfer should " + "not be called"); wallcycle_sub_start_nocount(wcycle_, ewcsLAUNCH_GPU_BONDED); // TODO add conditional on whether there has been any compute (and make sure host buffer doesn't contain garbage) - float *h_vTot = vTot_.data(); - copyFromDeviceBuffer(h_vTot, &d_vTot_, - 0, F_NRE, - stream_, GpuApiCallBehavior::Async, nullptr); + float* h_vTot = vTot_.data(); + copyFromDeviceBuffer(h_vTot, &d_vTot_, 0, F_NRE, stream_, GpuApiCallBehavior::Async, nullptr); wallcycle_sub_stop(wcycle_, ewcsLAUNCH_GPU_BONDED); } -void -GpuBonded::Impl::waitAccumulateEnergyTerms(gmx_enerdata_t *enerd) +void GpuBonded::Impl::waitAccumulateEnergyTerms(gmx_enerdata_t* enerd) { - GMX_ASSERT(haveInteractions_, "No GPU bonded interactions, so no energies will be computed or transferred, so accumulation should not occur"); + GMX_ASSERT(haveInteractions_, + "No GPU bonded interactions, so no energies will be computed or transferred, so " + "accumulation should not occur"); wallcycle_start(wcycle_, ewcWAIT_GPU_BONDED); cudaError_t stat = cudaStreamSynchronize(stream_); @@ -296,14 +293,13 @@ GpuBonded::Impl::waitAccumulateEnergyTerms(gmx_enerdata_t *enerd) } // Note: We do not support energy groups here - gmx_grppairener_t *grppener = &enerd->grpp; + gmx_grppairener_t* grppener = &enerd->grpp; GMX_RELEASE_ASSERT(grppener->nener == 1, "No energy group support for bondeds on the GPU"); - grppener->ener[egLJ14][0] += vTot_[F_LJ14]; + grppener->ener[egLJ14][0] += vTot_[F_LJ14]; grppener->ener[egCOUL14][0] += vTot_[F_COUL14]; } -void -GpuBonded::Impl::clearEnergies() +void GpuBonded::Impl::clearEnergies() { wallcycle_start_nocount(wcycle_, ewcLAUNCH_GPU); wallcycle_sub_start_nocount(wcycle_, ewcsLAUNCH_GPU_BONDED); @@ -314,48 +310,40 @@ GpuBonded::Impl::clearEnergies() // ---- GpuBonded -GpuBonded::GpuBonded(const gmx_ffparams_t &ffparams, - void *streamPtr, - gmx_wallcycle *wcycle) - : impl_(new Impl(ffparams, streamPtr, wcycle)) +GpuBonded::GpuBonded(const gmx_ffparams_t& ffparams, void* streamPtr, gmx_wallcycle* wcycle) : + impl_(new Impl(ffparams, streamPtr, wcycle)) { } GpuBonded::~GpuBonded() = default; -void -GpuBonded::updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, - const t_idef &idef, - void *d_xq, - void *d_f, - void *d_fShift) +void GpuBonded::updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, + const t_idef& idef, + void* d_xq, + void* d_f, + void* d_fShift) { - impl_->updateInteractionListsAndDeviceBuffers - (nbnxnAtomOrder, idef, d_xq, d_f, d_fShift); + impl_->updateInteractionListsAndDeviceBuffers(nbnxnAtomOrder, idef, d_xq, d_f, d_fShift); } -bool -GpuBonded::haveInteractions() const +bool GpuBonded::haveInteractions() const { return impl_->haveInteractions(); } -void -GpuBonded::launchEnergyTransfer() +void GpuBonded::launchEnergyTransfer() { impl_->launchEnergyTransfer(); } -void -GpuBonded::waitAccumulateEnergyTerms(gmx_enerdata_t *enerd) +void GpuBonded::waitAccumulateEnergyTerms(gmx_enerdata_t* enerd) { impl_->waitAccumulateEnergyTerms(enerd); } -void -GpuBonded::clearEnergies() +void GpuBonded::clearEnergies() { impl_->clearEnergies(); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/listed_forces/gpubonded_impl.h b/src/gromacs/listed_forces/gpubonded_impl.h index 436cc88e56..236d7df982 100644 --- a/src/gromacs/listed_forces/gpubonded_impl.h +++ b/src/gromacs/listed_forces/gpubonded_impl.h @@ -64,13 +64,10 @@ namespace gmx struct HostInteractionList { /*! \brief Returns the total number of elements in iatoms */ - int size() const - { - return iatoms.size(); - } + int size() const { return iatoms.size(); } //! List of interactions, see \c HostInteractionLists - HostVector iatoms = {{}, gmx::HostAllocationPolicy(gmx::PinningPolicy::PinnedIfSupported)}; + HostVector iatoms = { {}, gmx::HostAllocationPolicy(gmx::PinningPolicy::PinnedIfSupported) }; }; /* \brief Bonded parameters and GPU pointers @@ -82,36 +79,36 @@ struct HostInteractionList struct BondedCudaKernelParameters { //! Periodic boundary data - PbcAiuc pbcAiuc; + PbcAiuc pbcAiuc; //! Scale factor - float scaleFactor; + float scaleFactor; //! The bonded types on GPU - int fTypesOnGpu[numFTypesOnGpu]; + int fTypesOnGpu[numFTypesOnGpu]; //! The number of interaction atom (iatom) elements for every function type - int numFTypeIAtoms[numFTypesOnGpu]; + int numFTypeIAtoms[numFTypesOnGpu]; //! The number of bonds for every function type - int numFTypeBonds[numFTypesOnGpu]; + int numFTypeBonds[numFTypesOnGpu]; //! The start index in the range of each interaction type - int fTypeRangeStart[numFTypesOnGpu]; + int fTypeRangeStart[numFTypesOnGpu]; //! The end index in the range of each interaction type - int fTypeRangeEnd[numFTypesOnGpu]; + int fTypeRangeEnd[numFTypesOnGpu]; //! Force parameters (on GPU) - t_iparams *d_forceParams; + t_iparams* d_forceParams; //! Coordinates before the timestep (on GPU) - const float4 *d_xq; + const float4* d_xq; //! Forces on atoms (on GPU) - fvec *d_f; + fvec* d_f; //! Force shifts on atoms (on GPU) - fvec *d_fShift; + fvec* d_fShift; //! Total Energy (on GPU) - float *d_vTot; + float* d_vTot; //! Interaction list atoms (on GPU) - t_iatom *d_iatoms[numFTypesOnGpu]; + t_iatom* d_iatoms[numFTypesOnGpu]; BondedCudaKernelParameters() { - matrix boxDummy = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; + matrix boxDummy = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; setPbcAiuc(0, boxDummy, &pbcAiuc); @@ -127,75 +124,72 @@ struct BondedCudaKernelParameters /*! \internal \brief Implements GPU bondeds */ class GpuBonded::Impl { - public: - //! Constructor - Impl(const gmx_ffparams_t &ffparams, - void *streamPtr, - gmx_wallcycle *wcycle); - /*! \brief Destructor, non-default needed for freeing - * device-side buffers */ - ~Impl(); - /*! \brief Update lists of interactions from idef suitable for the GPU, - * using the data structures prepared for PP work. - * - * Intended to be called after each neighbour search - * stage. Copies the bonded interactions assigned to the GPU - * to device data structures, and updates device buffers that - * may have been updated after search. */ - void updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, - const t_idef &idef, - void *xqDevice, - void *forceDevice, - void *fshiftDevice); - - /*! \brief Launches bonded kernel on a GPU */ - template - void - launchKernel(const t_forcerec *fr, - const matrix box); - /*! \brief Returns whether there are bonded interactions - * assigned to the GPU */ - bool haveInteractions() const; - /*! \brief Launches the transfer of computed bonded energies. */ - void launchEnergyTransfer(); - /*! \brief Waits on the energy transfer, and accumulates bonded energies to \c enerd. */ - void waitAccumulateEnergyTerms(gmx_enerdata_t *enerd); - /*! \brief Clears the device side energy buffer */ - void clearEnergies(); - private: - /*! \brief The interaction lists - * - * \todo This is potentially several pinned allocations, which - * could contribute to exhausting such pages. */ - std::array iLists_; - - //! Tells whether there are any interaction in iLists. - bool haveInteractions_; - //! Interaction lists on the device. - t_ilist d_iLists_[F_NRE]; - //! Bonded parameters for device-side use. - t_iparams *d_forceParams_ = nullptr; - //! Position-charge vector on the device. - const float4 *d_xq_ = nullptr; - //! Force vector on the device. - fvec *d_f_ = nullptr; - //! Shift force vector on the device. - fvec *d_fShift_ = nullptr; - //! \brief Host-side virial buffer - HostVector vTot_ = {{}, gmx::HostAllocationPolicy(gmx::PinningPolicy::PinnedIfSupported)}; - //! \brief Device-side total virial - float *d_vTot_ = nullptr; - - //! \brief Bonded GPU stream, not owned by this module - CommandStream stream_; - - //! Parameters and pointers, passed to the CUDA kernel - BondedCudaKernelParameters kernelParams_; - - //! \brief Pointer to wallcycle structure. - gmx_wallcycle *wcycle_; +public: + //! Constructor + Impl(const gmx_ffparams_t& ffparams, void* streamPtr, gmx_wallcycle* wcycle); + /*! \brief Destructor, non-default needed for freeing + * device-side buffers */ + ~Impl(); + /*! \brief Update lists of interactions from idef suitable for the GPU, + * using the data structures prepared for PP work. + * + * Intended to be called after each neighbour search + * stage. Copies the bonded interactions assigned to the GPU + * to device data structures, and updates device buffers that + * may have been updated after search. */ + void updateInteractionListsAndDeviceBuffers(ArrayRef nbnxnAtomOrder, + const t_idef& idef, + void* xqDevice, + void* forceDevice, + void* fshiftDevice); + + /*! \brief Launches bonded kernel on a GPU */ + template + void launchKernel(const t_forcerec* fr, const matrix box); + /*! \brief Returns whether there are bonded interactions + * assigned to the GPU */ + bool haveInteractions() const; + /*! \brief Launches the transfer of computed bonded energies. */ + void launchEnergyTransfer(); + /*! \brief Waits on the energy transfer, and accumulates bonded energies to \c enerd. */ + void waitAccumulateEnergyTerms(gmx_enerdata_t* enerd); + /*! \brief Clears the device side energy buffer */ + void clearEnergies(); + +private: + /*! \brief The interaction lists + * + * \todo This is potentially several pinned allocations, which + * could contribute to exhausting such pages. */ + std::array iLists_; + + //! Tells whether there are any interaction in iLists. + bool haveInteractions_; + //! Interaction lists on the device. + t_ilist d_iLists_[F_NRE]; + //! Bonded parameters for device-side use. + t_iparams* d_forceParams_ = nullptr; + //! Position-charge vector on the device. + const float4* d_xq_ = nullptr; + //! Force vector on the device. + fvec* d_f_ = nullptr; + //! Shift force vector on the device. + fvec* d_fShift_ = nullptr; + //! \brief Host-side virial buffer + HostVector vTot_ = { {}, gmx::HostAllocationPolicy(gmx::PinningPolicy::PinnedIfSupported) }; + //! \brief Device-side total virial + float* d_vTot_ = nullptr; + + //! \brief Bonded GPU stream, not owned by this module + CommandStream stream_; + + //! Parameters and pointers, passed to the CUDA kernel + BondedCudaKernelParameters kernelParams_; + + //! \brief Pointer to wallcycle structure. + gmx_wallcycle* wcycle_; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/listed_forces/gpubondedkernels.cu b/src/gromacs/listed_forces/gpubondedkernels.cu index e78b32c6fd..fbb6baee1f 100644 --- a/src/gromacs/listed_forces/gpubondedkernels.cu +++ b/src/gromacs/listed_forces/gpubondedkernels.cu @@ -66,59 +66,61 @@ #include "gpubonded_impl.h" #if defined(_MSVC) -#include +# include #endif -//CUDA threads per block +// CUDA threads per block #define TPB_BONDED 256 /*-------------------------------- CUDA kernels-------------------------------- */ /*------------------------------------------------------------------------------*/ -#define CUDA_DEG2RAD_F (CUDART_PI_F/180.0f) +#define CUDA_DEG2RAD_F (CUDART_PI_F / 180.0f) /*---------------- BONDED CUDA kernels--------------*/ /* Harmonic */ -__device__ __forceinline__ -static void harmonic_gpu(const float kA, const float xA, const float x, float *V, float *F) +__device__ __forceinline__ static void + harmonic_gpu(const float kA, const float xA, const float x, float* V, float* F) { constexpr float half = 0.5f; float dx, dx2; - dx = x-xA; - dx2 = dx*dx; + dx = x - xA; + dx2 = dx * dx; - *F = -kA*dx; - *V = half*kA*dx2; + *F = -kA * dx; + *V = half * kA * dx2; } -template -__device__ -void bonds_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void bonds_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { if (i < numBonds) { - int3 bondData = *(int3 *)(d_forceatoms + 3 * i); - int type = bondData.x; - int ai = bondData.y; - int aj = bondData.z; + int3 bondData = *(int3*)(d_forceatoms + 3 * i); + int type = bondData.x; + int ai = bondData.y; + int aj = bondData.z; /* dx = xi - xj, corrected for periodic boundary conditions. */ - fvec dx; - int ki = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[aj], dx); + fvec dx; + int ki = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[aj], dx); float dr2 = iprod_gpu(dx, dx); float dr = sqrt(dr2); float vbond; float fbond; - harmonic_gpu(d_forceparams[type].harmonic.krA, - d_forceparams[type].harmonic.rA, - dr, &vbond, &fbond); + harmonic_gpu(d_forceparams[type].harmonic.krA, d_forceparams[type].harmonic.rA, dr, &vbond, &fbond); if (calcEner) { @@ -132,7 +134,7 @@ void bonds_gpu(const int i, float *vtot_loc, const int numBonds, #pragma unroll for (int m = 0; m < DIM; m++) { - float fij = fbond*dx[m]; + float fij = fbond * dx[m]; atomicAdd(&gm_f[ai][m], fij); atomicAdd(&gm_f[aj][m], -fij); if (calcVir && ki != CENTRAL) @@ -145,16 +147,20 @@ void bonds_gpu(const int i, float *vtot_loc, const int numBonds, } } -template -__device__ __forceinline__ -static float bond_angle_gpu(const float4 xi, const float4 xj, const float4 xk, - const PbcAiuc &pbcAiuc, - fvec r_ij, fvec r_kj, float *costh, - int *t1, int *t2) +template +__device__ __forceinline__ static float bond_angle_gpu(const float4 xi, + const float4 xj, + const float4 xk, + const PbcAiuc& pbcAiuc, + fvec r_ij, + fvec r_kj, + float* costh, + int* t1, + int* t2) /* Return value is the angle between the bonds i-j and j-k */ { - *t1 = pbcDxAiuc(pbcAiuc, xi, xj, r_ij); - *t2 = pbcDxAiuc(pbcAiuc, xk, xj, r_kj); + *t1 = pbcDxAiuc(pbcAiuc, xi, xj, r_ij); + *t2 = pbcDxAiuc(pbcAiuc, xk, xj, r_kj); *costh = cos_angle_gpu(r_ij, r_kj); float th = acosf(*costh); @@ -162,65 +168,67 @@ static float bond_angle_gpu(const float4 xi, const float4 xj, const float4 xk, return th; } -template -__device__ -void angles_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void angles_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { if (i < numBonds) { - int4 angleData = *(int4 *)(d_forceatoms + 4 * i); - int type = angleData.x; - int ai = angleData.y; - int aj = angleData.z; - int ak = angleData.w; + int4 angleData = *(int4*)(d_forceatoms + 4 * i); + int type = angleData.x; + int ai = angleData.y; + int aj = angleData.z; + int ak = angleData.w; fvec r_ij; fvec r_kj; float cos_theta; int t1; int t2; - float theta = - bond_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, - r_ij, r_kj, &cos_theta, &t1, &t2); + float theta = bond_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, r_ij, r_kj, + &cos_theta, &t1, &t2); float va; float dVdt; harmonic_gpu(d_forceparams[type].harmonic.krA, - d_forceparams[type].harmonic.rA*CUDA_DEG2RAD_F, - theta, &va, &dVdt); + d_forceparams[type].harmonic.rA * CUDA_DEG2RAD_F, theta, &va, &dVdt); if (calcEner) { *vtot_loc += va; } - float cos_theta2 = cos_theta*cos_theta; + float cos_theta2 = cos_theta * cos_theta; if (cos_theta2 < 1.0f) { - float st = dVdt*rsqrtf(1.0f - cos_theta2); - float sth = st*cos_theta; + float st = dVdt * rsqrtf(1.0f - cos_theta2); + float sth = st * cos_theta; float nrij2 = iprod_gpu(r_ij, r_ij); float nrkj2 = iprod_gpu(r_kj, r_kj); float nrij_1 = rsqrtf(nrij2); float nrkj_1 = rsqrtf(nrkj2); - float cik = st*nrij_1*nrkj_1; - float cii = sth*nrij_1*nrij_1; - float ckk = sth*nrkj_1*nrkj_1; + float cik = st * nrij_1 * nrkj_1; + float cii = sth * nrij_1 * nrij_1; + float ckk = sth * nrkj_1 * nrkj_1; - fvec f_i; - fvec f_k; - fvec f_j; + fvec f_i; + fvec f_k; + fvec f_j; #pragma unroll for (int m = 0; m < DIM; m++) { - f_i[m] = -(cik*r_kj[m] - cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m] - ckk*r_kj[m]); - f_j[m] = -f_i[m] - f_k[m]; + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; atomicAdd(&gm_f[ai][m], f_i[m]); atomicAdd(&gm_f[aj][m], f_j[m]); atomicAdd(&gm_f[ak][m], f_k[m]); @@ -232,37 +240,40 @@ void angles_gpu(const int i, float *vtot_loc, const int numBonds, } } } - } } -template -__device__ -void urey_bradley_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void urey_bradley_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { if (i < numBonds) { - int4 ubData = *(int4 *)(d_forceatoms + 4 * i); - int type = ubData.x; - int ai = ubData.y; - int aj = ubData.z; - int ak = ubData.w; + int4 ubData = *(int4*)(d_forceatoms + 4 * i); + int type = ubData.x; + int ai = ubData.y; + int aj = ubData.z; + int ak = ubData.w; - float th0A = d_forceparams[type].u_b.thetaA*CUDA_DEG2RAD_F; - float kthA = d_forceparams[type].u_b.kthetaA; - float r13A = d_forceparams[type].u_b.r13A; - float kUBA = d_forceparams[type].u_b.kUBA; + float th0A = d_forceparams[type].u_b.thetaA * CUDA_DEG2RAD_F; + float kthA = d_forceparams[type].u_b.kthetaA; + float r13A = d_forceparams[type].u_b.r13A; + float kUBA = d_forceparams[type].u_b.kUBA; fvec r_ij; fvec r_kj; float cos_theta; int t1; int t2; - float theta = bond_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, - r_ij, r_kj, &cos_theta, &t1, &t2); + float theta = bond_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], pbcAiuc, r_ij, r_kj, + &cos_theta, &t1, &t2); float va; float dVdt; @@ -273,38 +284,38 @@ void urey_bradley_gpu(const int i, float *vtot_loc, const int numBonds, *vtot_loc += va; } - fvec r_ik; - int ki = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[ak], r_ik); + fvec r_ik; + int ki = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[ak], r_ik); - float dr2 = iprod_gpu(r_ik, r_ik); - float dr = dr2*rsqrtf(dr2); + float dr2 = iprod_gpu(r_ik, r_ik); + float dr = dr2 * rsqrtf(dr2); float vbond; float fbond; harmonic_gpu(kUBA, r13A, dr, &vbond, &fbond); - float cos_theta2 = cos_theta*cos_theta; + float cos_theta2 = cos_theta * cos_theta; if (cos_theta2 < 1.0f) { - float st = dVdt*rsqrtf(1.0f - cos_theta2); - float sth = st*cos_theta; + float st = dVdt * rsqrtf(1.0f - cos_theta2); + float sth = st * cos_theta; float nrkj2 = iprod_gpu(r_kj, r_kj); float nrij2 = iprod_gpu(r_ij, r_ij); - float cik = st*rsqrtf(nrkj2*nrij2); - float cii = sth/nrij2; - float ckk = sth/nrkj2; + float cik = st * rsqrtf(nrkj2 * nrij2); + float cii = sth / nrij2; + float ckk = sth / nrkj2; - fvec f_i; - fvec f_j; - fvec f_k; + fvec f_i; + fvec f_j; + fvec f_k; #pragma unroll for (int m = 0; m < DIM; m++) { - f_i[m] = -(cik*r_kj[m]-cii*r_ij[m]); - f_k[m] = -(cik*r_ij[m]-ckk*r_kj[m]); - f_j[m] = -f_i[m]-f_k[m]; + f_i[m] = -(cik * r_kj[m] - cii * r_ij[m]); + f_k[m] = -(cik * r_ij[m] - ckk * r_kj[m]); + f_j[m] = -f_i[m] - f_k[m]; atomicAdd(&gm_f[ai][m], f_i[m]); atomicAdd(&gm_f[aj][m], f_j[m]); atomicAdd(&gm_f[ak][m], f_k[m]); @@ -330,7 +341,7 @@ void urey_bradley_gpu(const int i, float *vtot_loc, const int numBonds, #pragma unroll for (int m = 0; m < DIM; m++) { - float fik = fbond*r_ik[m]; + float fik = fbond * r_ik[m]; atomicAdd(&gm_f[ai][m], fik); atomicAdd(&gm_f[ak][m], -fik); @@ -344,12 +355,20 @@ void urey_bradley_gpu(const int i, float *vtot_loc, const int numBonds, } } -template -__device__ __forceinline__ -static float dih_angle_gpu(const T xi, const T xj, const T xk, const T xl, - const PbcAiuc &pbcAiuc, - fvec r_ij, fvec r_kj, fvec r_kl, fvec m, fvec n, - int *t1, int *t2, int *t3) +template +__device__ __forceinline__ static float dih_angle_gpu(const T xi, + const T xj, + const T xk, + const T xl, + const PbcAiuc& pbcAiuc, + fvec r_ij, + fvec r_kj, + fvec r_kl, + fvec m, + fvec n, + int* t1, + int* t2, + int* t3) { *t1 = pbcDxAiuc(pbcAiuc, xi, xj, r_ij); *t2 = pbcDxAiuc(pbcAiuc, xk, xj, r_kj); @@ -360,60 +379,70 @@ static float dih_angle_gpu(const T xi, const T xj, const T xk, const T xl, float phi = gmx_angle_gpu(m, n); float ipr = iprod_gpu(r_ij, n); float sign = (ipr < 0.0f) ? -1.0f : 1.0f; - phi = sign*phi; + phi = sign * phi; return phi; } -__device__ __forceinline__ -static void dopdihs_gpu(const float cpA, const float phiA, const int mult, - const float phi, float *v, float *f) +__device__ __forceinline__ static void + dopdihs_gpu(const float cpA, const float phiA, const int mult, const float phi, float* v, float* f) { float mdphi, sdphi; - mdphi = mult*phi - phiA*CUDA_DEG2RAD_F; + mdphi = mult * phi - phiA * CUDA_DEG2RAD_F; sdphi = sinf(mdphi); *v = cpA * (1.0f + cosf(mdphi)); - *f = -cpA*mult*sdphi; + *f = -cpA * mult * sdphi; } -template -__device__ -static void do_dih_fup_gpu(const int i, const int j, const int k, const int l, - const float ddphi, const fvec r_ij, const fvec r_kj, const fvec r_kl, - const fvec m, const fvec n, fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc &pbcAiuc, - const float4 gm_xq[], const int t1, const int t2, const int gmx_unused t3) +template +__device__ static void do_dih_fup_gpu(const int i, + const int j, + const int k, + const int l, + const float ddphi, + const fvec r_ij, + const fvec r_kj, + const fvec r_kl, + const fvec m, + const fvec n, + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc& pbcAiuc, + const float4 gm_xq[], + const int t1, + const int t2, + const int gmx_unused t3) { float iprm = iprod_gpu(m, m); float iprn = iprod_gpu(n, n); float nrkj2 = iprod_gpu(r_kj, r_kj); - float toler = nrkj2*GMX_REAL_EPS; + float toler = nrkj2 * GMX_REAL_EPS; if ((iprm > toler) && (iprn > toler)) { float nrkj_1 = rsqrtf(nrkj2); // replacing std::invsqrt call - float nrkj_2 = nrkj_1*nrkj_1; - float nrkj = nrkj2*nrkj_1; - float a = -ddphi*nrkj/iprm; + float nrkj_2 = nrkj_1 * nrkj_1; + float nrkj = nrkj2 * nrkj_1; + float a = -ddphi * nrkj / iprm; fvec f_i; svmul_gpu(a, m, f_i); - float b = ddphi*nrkj/iprn; + float b = ddphi * nrkj / iprn; fvec f_l; svmul_gpu(b, n, f_l); - float p = iprod_gpu(r_ij, r_kj); - p *= nrkj_2; - float q = iprod_gpu(r_kl, r_kj); - q *= nrkj_2; - fvec uvec; + float p = iprod_gpu(r_ij, r_kj); + p *= nrkj_2; + float q = iprod_gpu(r_kl, r_kj); + q *= nrkj_2; + fvec uvec; svmul_gpu(p, f_i, uvec); - fvec vvec; + fvec vvec; svmul_gpu(q, f_l, vvec); - fvec svec; + fvec svec; fvec_sub_gpu(uvec, vvec, svec); - fvec f_j; + fvec f_j; fvec_sub_gpu(f_i, svec, f_j); - fvec f_k; + fvec f_k; fvec_add_gpu(f_l, svec, f_k); #pragma unroll for (int m = 0; (m < DIM); m++) @@ -441,20 +470,24 @@ static void do_dih_fup_gpu(const int i, const int j, const int k, const int l, } } -template -__device__ -void pdihs_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void pdihs_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { if (i < numBonds) { - int type = d_forceatoms[5*i]; - int ai = d_forceatoms[5*i + 1]; - int aj = d_forceatoms[5*i + 2]; - int ak = d_forceatoms[5*i + 3]; - int al = d_forceatoms[5*i + 4]; + int type = d_forceatoms[5 * i]; + int ai = d_forceatoms[5 * i + 1]; + int aj = d_forceatoms[5 * i + 2]; + int ak = d_forceatoms[5 * i + 3]; + int al = d_forceatoms[5 * i + 4]; fvec r_ij; fvec r_kj; @@ -464,46 +497,44 @@ void pdihs_gpu(const int i, float *vtot_loc, const int numBonds, int t1; int t2; int t3; - float phi = - dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, - r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); + float phi = dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, + r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); float vpd; float ddphi; - dopdihs_gpu(d_forceparams[type].pdihs.cpA, - d_forceparams[type].pdihs.phiA, - d_forceparams[type].pdihs.mult, - phi, &vpd, &ddphi); + dopdihs_gpu(d_forceparams[type].pdihs.cpA, d_forceparams[type].pdihs.phiA, + d_forceparams[type].pdihs.mult, phi, &vpd, &ddphi); if (calcEner) { *vtot_loc += vpd; } - do_dih_fup_gpu(ai, aj, ak, al, - ddphi, r_ij, r_kj, r_kl, m, n, - gm_f, sm_fShiftLoc, pbcAiuc, - gm_xq, t1, t2, t3); - + do_dih_fup_gpu(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, + pbcAiuc, gm_xq, t1, t2, t3); } } -template -__device__ -void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void rbdihs_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { - constexpr float c0 = 0.0f, c1 = 1.0f, c2 = 2.0f, c3 = 3.0f, c4 = 4.0f, c5 = 5.0f; + constexpr float c0 = 0.0f, c1 = 1.0f, c2 = 2.0f, c3 = 3.0f, c4 = 4.0f, c5 = 5.0f; if (i < numBonds) { - int type = d_forceatoms[5*i]; - int ai = d_forceatoms[5*i+1]; - int aj = d_forceatoms[5*i+2]; - int ak = d_forceatoms[5*i+3]; - int al = d_forceatoms[5*i+4]; + int type = d_forceatoms[5 * i]; + int ai = d_forceatoms[5 * i + 1]; + int aj = d_forceatoms[5 * i + 2]; + int ak = d_forceatoms[5 * i + 3]; + int al = d_forceatoms[5 * i + 4]; fvec r_ij; fvec r_kj; @@ -513,9 +544,8 @@ void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, int t1; int t2; int t3; - float phi = - dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, - r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); + float phi = dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, + r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* Change to polymer convention */ if (phi < c0) @@ -525,7 +555,6 @@ void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, else { phi -= CUDART_PI_F; - } float cos_phi = cosf(phi); /* Beware of accuracy loss, cannot use 1-sqrt(cos^2) ! */ @@ -534,7 +563,7 @@ void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, float parm[NR_RBDIHS]; for (int j = 0; j < NR_RBDIHS; j++) { - parm[j] = d_forceparams[type].rbdihs.rbcA[j]; + parm[j] = d_forceparams[type].rbdihs.rbcA[j]; } /* Calculate cosine powers */ /* Calculate the energy */ @@ -543,48 +572,46 @@ void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, float ddphi = c0; float cosfac = c1; - float rbp = parm[1]; - ddphi += rbp*cosfac; - cosfac *= cos_phi; + float rbp = parm[1]; + ddphi += rbp * cosfac; + cosfac *= cos_phi; if (calcEner) { - v += cosfac*rbp; + v += cosfac * rbp; } - rbp = parm[2]; - ddphi += c2*rbp*cosfac; - cosfac *= cos_phi; + rbp = parm[2]; + ddphi += c2 * rbp * cosfac; + cosfac *= cos_phi; if (calcEner) { - v += cosfac*rbp; + v += cosfac * rbp; } - rbp = parm[3]; - ddphi += c3*rbp*cosfac; - cosfac *= cos_phi; + rbp = parm[3]; + ddphi += c3 * rbp * cosfac; + cosfac *= cos_phi; if (calcEner) { - v += cosfac*rbp; + v += cosfac * rbp; } - rbp = parm[4]; - ddphi += c4*rbp*cosfac; - cosfac *= cos_phi; + rbp = parm[4]; + ddphi += c4 * rbp * cosfac; + cosfac *= cos_phi; if (calcEner) { - v += cosfac*rbp; + v += cosfac * rbp; } - rbp = parm[5]; - ddphi += c5*rbp*cosfac; - cosfac *= cos_phi; + rbp = parm[5]; + ddphi += c5 * rbp * cosfac; + cosfac *= cos_phi; if (calcEner) { - v += cosfac*rbp; + v += cosfac * rbp; } - ddphi = -ddphi*sin_phi; + ddphi = -ddphi * sin_phi; - do_dih_fup_gpu(ai, aj, ak, al, - ddphi, r_ij, r_kj, r_kl, m, n, - gm_f, sm_fShiftLoc, pbcAiuc, - gm_xq, t1, t2, t3); + do_dih_fup_gpu(ai, aj, ak, al, ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, + pbcAiuc, gm_xq, t1, t2, t3); if (calcEner) { *vtot_loc += v; @@ -592,34 +619,37 @@ void rbdihs_gpu(const int i, float *vtot_loc, const int numBonds, } } -__device__ __forceinline__ -static void make_dp_periodic_gpu(float *dp) +__device__ __forceinline__ static void make_dp_periodic_gpu(float* dp) { /* dp cannot be outside (-pi,pi) */ if (*dp >= CUDART_PI_F) { - *dp -= 2.0f*CUDART_PI_F; + *dp -= 2.0f * CUDART_PI_F; } else if (*dp < -CUDART_PI_F) { - *dp += 2.0f*CUDART_PI_F; + *dp += 2.0f * CUDART_PI_F; } } -template -__device__ -void idihs_gpu(const int i, float *vtot_loc, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams d_forceparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc) +template +__device__ void idihs_gpu(const int i, + float* vtot_loc, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams d_forceparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc) { if (i < numBonds) { - int type = d_forceatoms[5*i]; - int ai = d_forceatoms[5*i + 1]; - int aj = d_forceatoms[5*i + 2]; - int ak = d_forceatoms[5*i + 3]; - int al = d_forceatoms[5*i + 4]; + int type = d_forceatoms[5 * i]; + int ai = d_forceatoms[5 * i + 1]; + int aj = d_forceatoms[5 * i + 2]; + int ak = d_forceatoms[5 * i + 3]; + int al = d_forceatoms[5 * i + 4]; fvec r_ij; fvec r_kj; @@ -629,9 +659,8 @@ void idihs_gpu(const int i, float *vtot_loc, const int numBonds, int t1; int t2; int t3; - float phi = - dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, - r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); + float phi = dih_angle_gpu(gm_xq[ai], gm_xq[aj], gm_xq[ak], gm_xq[al], pbcAiuc, + r_ij, r_kj, r_kl, m, n, &t1, &t2, &t3); /* phi can jump if phi0 is close to Pi/-Pi, which will cause huge * force changes if we just apply a normal harmonic. @@ -640,63 +669,65 @@ void idihs_gpu(const int i, float *vtot_loc, const int numBonds, * the dihedral is Pi away from phiO, which is very unlikely due to * the potential. */ - float kA = d_forceparams[type].harmonic.krA; - float pA = d_forceparams[type].harmonic.rA; + float kA = d_forceparams[type].harmonic.krA; + float pA = d_forceparams[type].harmonic.rA; - float phi0 = pA*CUDA_DEG2RAD_F; + float phi0 = pA * CUDA_DEG2RAD_F; - float dp = phi - phi0; + float dp = phi - phi0; make_dp_periodic_gpu(&dp); - float ddphi = -kA*dp; + float ddphi = -kA * dp; - do_dih_fup_gpu(ai, aj, ak, al, - -ddphi, r_ij, r_kj, r_kl, m, n, - gm_f, sm_fShiftLoc, pbcAiuc, - gm_xq, t1, t2, t3); + do_dih_fup_gpu(ai, aj, ak, al, -ddphi, r_ij, r_kj, r_kl, m, n, gm_f, sm_fShiftLoc, + pbcAiuc, gm_xq, t1, t2, t3); if (calcEner) { - *vtot_loc += -0.5f*ddphi*dp; + *vtot_loc += -0.5f * ddphi * dp; } } } -template -__device__ -void pairs_gpu(const int i, const int numBonds, - const t_iatom d_forceatoms[], const t_iparams iparams[], - const float4 gm_xq[], fvec gm_f[], fvec sm_fShiftLoc[], - const PbcAiuc pbcAiuc, - const float scale_factor, - float *vtotVdw_loc, float *vtotElec_loc) +template +__device__ void pairs_gpu(const int i, + const int numBonds, + const t_iatom d_forceatoms[], + const t_iparams iparams[], + const float4 gm_xq[], + fvec gm_f[], + fvec sm_fShiftLoc[], + const PbcAiuc pbcAiuc, + const float scale_factor, + float* vtotVdw_loc, + float* vtotElec_loc) { - if (i < numBonds) + if (i < numBonds) { - int3 pairData = *(int3 *)(d_forceatoms + 3 * i); - int type = pairData.x; - int ai = pairData.y; - int aj = pairData.z; + int3 pairData = *(int3*)(d_forceatoms + 3 * i); + int type = pairData.x; + int ai = pairData.y; + int aj = pairData.z; - float qq = gm_xq[ai].w*gm_xq[aj].w; - float c6 = iparams[type].lj14.c6A; - float c12 = iparams[type].lj14.c12A; + float qq = gm_xq[ai].w * gm_xq[aj].w; + float c6 = iparams[type].lj14.c6A; + float c12 = iparams[type].lj14.c12A; /* Do we need to apply full periodic boundary conditions? */ - fvec dr; - int fshift_index = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[aj], dr); + fvec dr; + int fshift_index = pbcDxAiuc(pbcAiuc, gm_xq[ai], gm_xq[aj], dr); float r2 = norm2_gpu(dr); float rinv = rsqrtf(r2); - float rinv2 = rinv*rinv; - float rinv6 = rinv2*rinv2*rinv2; + float rinv2 = rinv * rinv; + float rinv6 = rinv2 * rinv2 * rinv2; /* Calculate the Coulomb force * r */ - float velec = scale_factor*qq*rinv; + float velec = scale_factor * qq * rinv; /* Calculate the LJ force * r and add it to the Coulomb part */ - float fr = (12.0f*c12*rinv6 - 6.0f*c6)*rinv6 + velec; + float fr = (12.0f * c12 * rinv6 - 6.0f * c6) * rinv6 + velec; float finvr = fr * rinv2; fvec f; @@ -717,7 +748,7 @@ void pairs_gpu(const int i, const int numBonds, if (calcEner) { - *vtotVdw_loc += (c12*rinv6 - c6)*rinv6; + *vtotVdw_loc += (c12 * rinv6 - c6) * rinv6; *vtotElec_loc += velec; } } @@ -726,15 +757,14 @@ void pairs_gpu(const int i, const int numBonds, namespace gmx { -template -__global__ -void exec_kernel_gpu(BondedCudaKernelParameters kernelParams) +template +__global__ void exec_kernel_gpu(BondedCudaKernelParameters kernelParams) { assert(blockDim.y == 1 && blockDim.z == 1); - const int tid = blockIdx.x*blockDim.x+threadIdx.x; - float vtot_loc = 0; - float vtotVdw_loc = 0; - float vtotElec_loc = 0; + const int tid = blockIdx.x * blockDim.x + threadIdx.x; + float vtot_loc = 0; + float vtotVdw_loc = 0; + float vtotElec_loc = 0; __shared__ fvec sm_fShiftLoc[SHIFTS]; if (calcVir) @@ -757,44 +787,51 @@ void exec_kernel_gpu(BondedCudaKernelParameters kernelParams) { const int numBonds = kernelParams.numFTypeBonds[j]; int fTypeTid = tid - kernelParams.fTypeRangeStart[j]; - const t_iatom *iatoms = kernelParams.d_iatoms[j]; + const t_iatom* iatoms = kernelParams.d_iatoms[j]; fType = kernelParams.fTypesOnGpu[j]; if (calcEner) { - threadComputedPotential = true; + threadComputedPotential = true; } switch (fType) { case F_BONDS: - bonds_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + bonds_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, + kernelParams.d_forceParams, kernelParams.d_xq, + kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_ANGLES: - angles_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + angles_gpu( + fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, + kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_UREY_BRADLEY: - urey_bradley_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + urey_bradley_gpu( + fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, + kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_PDIHS: case F_PIDIHS: - pdihs_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + pdihs_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, + kernelParams.d_forceParams, kernelParams.d_xq, + kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_RBDIHS: - rbdihs_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + rbdihs_gpu( + fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, + kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_IDIHS: - idihs_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); + idihs_gpu(fTypeTid, &vtot_loc, numBonds, iatoms, + kernelParams.d_forceParams, kernelParams.d_xq, + kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc); break; case F_LJ14: pairs_gpu(fTypeTid, numBonds, iatoms, kernelParams.d_forceParams, - kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, kernelParams.pbcAiuc, - kernelParams.scaleFactor, &vtotVdw_loc, &vtotElec_loc); + kernelParams.d_xq, kernelParams.d_f, sm_fShiftLoc, + kernelParams.pbcAiuc, kernelParams.scaleFactor, + &vtotVdw_loc, &vtotElec_loc); break; } break; @@ -803,8 +840,8 @@ void exec_kernel_gpu(BondedCudaKernelParameters kernelParams) if (threadComputedPotential) { - float *vtotVdw = kernelParams.d_vTot + F_LJ14; - float *vtotElec = kernelParams.d_vTot + F_COUL14; + float* vtotVdw = kernelParams.d_vTot + F_LJ14; + float* vtotElec = kernelParams.d_vTot + F_COUL14; atomicAdd(kernelParams.d_vTot + fType, vtot_loc); atomicAdd(vtotVdw, vtotVdw_loc); atomicAdd(vtotElec, vtotElec_loc); @@ -824,19 +861,18 @@ void exec_kernel_gpu(BondedCudaKernelParameters kernelParams) /*-------------------------------- End CUDA kernels-----------------------------*/ -template -void -GpuBonded::Impl::launchKernel(const t_forcerec *fr, - const matrix box) +template +void GpuBonded::Impl::launchKernel(const t_forcerec* fr, const matrix box) { GMX_ASSERT(haveInteractions_, "Cannot launch bonded GPU kernels unless bonded GPU work was scheduled"); - static_assert(TPB_BONDED >= SHIFTS, "TPB_BONDED must be >= SHIFTS for the virial kernel (calcVir=true)"); + static_assert(TPB_BONDED >= SHIFTS, + "TPB_BONDED must be >= SHIFTS for the virial kernel (calcVir=true)"); - PbcAiuc pbcAiuc; + PbcAiuc pbcAiuc; setPbcAiuc(fr->bMolPBC ? ePBC2npbcdim(fr->ePBC) : 0, box, &pbcAiuc); - int fTypeRangeEnd = kernelParams_.fTypeRangeEnd[numFTypesOnGpu - 1]; + int fTypeRangeEnd = kernelParams_.fTypeRangeEnd[numFTypesOnGpu - 1]; if (fTypeRangeEnd < 0) { @@ -847,40 +883,34 @@ GpuBonded::Impl::launchKernel(const t_forcerec *fr, config.blockSize[0] = TPB_BONDED; config.blockSize[1] = 1; config.blockSize[2] = 1; - config.gridSize[0] = (fTypeRangeEnd + TPB_BONDED)/TPB_BONDED; + config.gridSize[0] = (fTypeRangeEnd + TPB_BONDED) / TPB_BONDED; config.gridSize[1] = 1; config.gridSize[2] = 1; config.stream = stream_; auto kernelPtr = exec_kernel_gpu; - kernelParams_.scaleFactor = fr->ic->epsfac*fr->fudgeQQ; + kernelParams_.scaleFactor = fr->ic->epsfac * fr->fudgeQQ; kernelParams_.pbcAiuc = pbcAiuc; - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, &kernelParams_); + const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, &kernelParams_); launchGpuKernel(kernelPtr, config, nullptr, "exec_kernel_gpu", kernelArgs); } -void -GpuBonded::launchKernel(const t_forcerec *fr, - const gmx::StepWorkload &stepWork, - const matrix box) +void GpuBonded::launchKernel(const t_forcerec* fr, const gmx::StepWorkload& stepWork, const matrix box) { if (stepWork.computeEnergy) { // When we need the energy, we also need the virial - impl_->launchKernel - (fr, box); + impl_->launchKernel(fr, box); } else if (stepWork.computeVirial) { - impl_->launchKernel - (fr, box); + impl_->launchKernel(fr, box); } else { - impl_->launchKernel - (fr, box); + impl_->launchKernel(fr, box); } } diff --git a/src/gromacs/listed_forces/listed_forces.cpp b/src/gromacs/listed_forces/listed_forces.cpp index 0a094c4bbe..4b46781c2e 100644 --- a/src/gromacs/listed_forces/listed_forces.cpp +++ b/src/gromacs/listed_forces/listed_forces.cpp @@ -83,21 +83,19 @@ namespace /*! \brief Return true if ftype is an explicit pair-listed LJ or * COULOMB interaction type: bonded LJ (usually 1-4), or special * listed non-bonded for FEP. */ -bool -isPairInteraction(int ftype) +bool isPairInteraction(int ftype) { return ((ftype) >= F_LJ14 && (ftype) <= F_LJC_PAIRS_NB); } /*! \brief Zero thread-local output buffers */ -void -zero_thread_output(f_thread_t *f_t) +void zero_thread_output(f_thread_t* f_t) { - constexpr int nelem_fa = sizeof(f_t->f[0])/sizeof(real); + constexpr int nelem_fa = sizeof(f_t->f[0]) / sizeof(real); for (int i = 0; i < f_t->nblock_used; i++) { - int a0 = f_t->block_index[i]*reduction_block_size; + int a0 = f_t->block_index[i] * reduction_block_size; int a1 = a0 + reduction_block_size; for (int a = a0; a < a1; a++) { @@ -135,19 +133,14 @@ zero_thread_output(f_thread_t *f_t) #define MAX_BONDED_THREADS 256 /*! \brief Reduce thread-local force buffers */ -void -reduce_thread_forces(int n, - gmx::ArrayRef force, - const bonded_threading_t *bt, - int nthreads) +void reduce_thread_forces(int n, gmx::ArrayRef force, const bonded_threading_t* bt, int nthreads) { if (nthreads > MAX_BONDED_THREADS) { - gmx_fatal(FARGS, "Can not reduce bonded forces on more than %d threads", - MAX_BONDED_THREADS); + gmx_fatal(FARGS, "Can not reduce bonded forces on more than %d threads", MAX_BONDED_THREADS); } - rvec * gmx_restrict f = as_rvec_array(force.data()); + rvec* gmx_restrict f = as_rvec_array(force.data()); /* This reduction can run on any number of threads, * independently of bt->nthreads. @@ -163,7 +156,7 @@ reduce_thread_forces(int n, try { int ind = bt->block_index[b]; - rvec4 *fp[MAX_BONDED_THREADS]; + rvec4* fp[MAX_BONDED_THREADS]; /* Determine which threads contribute to this block */ int nfb = 0; @@ -177,10 +170,10 @@ reduce_thread_forces(int n, if (nfb > 0) { /* Reduce force buffers for threads that contribute */ - int a0 = ind *reduction_block_size; - int a1 = (ind + 1)*reduction_block_size; + int a0 = ind * reduction_block_size; + int a1 = (ind + 1) * reduction_block_size; /* It would be nice if we could pad f to avoid this min */ - a1 = std::min(a1, n); + a1 = std::min(a1, n); for (int a = a0; a < a1; a++) { for (int fb = 0; fb < nfb; fb++) @@ -190,16 +183,18 @@ reduce_thread_forces(int n, } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /*! \brief Reduce thread-local forces, shift forces and energies */ -void -reduce_thread_output(int n, gmx::ForceWithShiftForces *forceWithShiftForces, - real *ener, gmx_grppairener_t *grpp, real *dvdl, - const bonded_threading_t *bt, - const gmx::StepWorkload &stepWork) +void reduce_thread_output(int n, + gmx::ForceWithShiftForces* forceWithShiftForces, + real* ener, + gmx_grppairener_t* grpp, + real* dvdl, + const bonded_threading_t* bt, + const gmx::StepWorkload& stepWork) { assert(bt->haveBondeds); @@ -209,13 +204,12 @@ reduce_thread_output(int n, gmx::ForceWithShiftForces *forceWithShiftForces, reduce_thread_forces(n, forceWithShiftForces->force(), bt, bt->nthreads); } - rvec * gmx_restrict fshift = as_rvec_array(forceWithShiftForces->shiftForces().data()); + rvec* gmx_restrict fshift = as_rvec_array(forceWithShiftForces->shiftForces().data()); /* When necessary, reduce energy and virial using one thread only */ - if ((stepWork.computeEnergy || stepWork.computeVirial || stepWork.computeDhdl) && - bt->nthreads > 1) + if ((stepWork.computeEnergy || stepWork.computeVirial || stepWork.computeDhdl) && bt->nthreads > 1) { - gmx::ArrayRef < const std::unique_ptr < f_thread_t>> f_t = bt->f_t; + gmx::ArrayRef> f_t = bt->f_t; if (stepWork.computeVirial) { @@ -268,7 +262,7 @@ reduce_thread_output(int n, gmx::ForceWithShiftForces *forceWithShiftForces, * Note that currently we do not have bonded kernels that * do not compute forces. */ -BondedKernelFlavor selectBondedKernelFlavor(const gmx::StepWorkload &stepWork, +BondedKernelFlavor selectBondedKernelFlavor(const gmx::StepWorkload& stepWork, const bool useSimdKernels, const bool havePerturbedInteractions) { @@ -301,29 +295,33 @@ BondedKernelFlavor selectBondedKernelFlavor(const gmx::StepWorkload &stepWork, /*! \brief Calculate one element of the list of bonded interactions for this thread */ -real -calc_one_bond(int thread, - int ftype, const t_idef *idef, - const WorkDivision &workDivision, - const rvec x[], rvec4 f[], rvec fshift[], - const t_forcerec *fr, - const t_pbc *pbc, const t_graph *g, - gmx_grppairener_t *grpp, - t_nrnb *nrnb, - const real *lambda, real *dvdl, - const t_mdatoms *md, t_fcdata *fcd, - const gmx::StepWorkload &stepWork, - int *global_atom_index) +real calc_one_bond(int thread, + int ftype, + const t_idef* idef, + const WorkDivision& workDivision, + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_forcerec* fr, + const t_pbc* pbc, + const t_graph* g, + gmx_grppairener_t* grpp, + t_nrnb* nrnb, + const real* lambda, + real* dvdl, + const t_mdatoms* md, + t_fcdata* fcd, + const gmx::StepWorkload& stepWork, + int* global_atom_index) { GMX_ASSERT(idef->ilsort == ilsortNO_FE || idef->ilsort == ilsortFE_SORTED, "The topology should be marked either as no FE or sorted on FE"); - const bool havePerturbedInteractions = - (idef->ilsort == ilsortFE_SORTED && - idef->il[ftype].nr_nonperturbed < idef->il[ftype].nr); + const bool havePerturbedInteractions = + (idef->ilsort == ilsortFE_SORTED && idef->il[ftype].nr_nonperturbed < idef->il[ftype].nr); BondedKernelFlavor flavor = - selectBondedKernelFlavor(stepWork, fr->use_simd_kernels, havePerturbedInteractions); - int efptFTYPE; + selectBondedKernelFlavor(stepWork, fr->use_simd_kernels, havePerturbedInteractions); + int efptFTYPE; if (IS_RESTRAINT_TYPE(ftype)) { efptFTYPE = efptRESTRAINT; @@ -334,8 +332,8 @@ calc_one_bond(int thread, } const int nat1 = interaction_function[ftype].nratoms + 1; - const int nbonds = idef->il[ftype].nr/nat1; - const t_iatom *iatoms = idef->il[ftype].iatoms; + const int nbonds = idef->il[ftype].nr / nat1; + const t_iatom* iatoms = idef->il[ftype].iatoms; GMX_ASSERT(fr->gpuBonded != nullptr || workDivision.end(ftype) == idef->il[ftype].nr, "The thread division should match the topology"); @@ -343,7 +341,7 @@ calc_one_bond(int thread, const int nb0 = workDivision.bound(ftype, thread); const int nbn = workDivision.bound(ftype, thread + 1) - nb0; - real v = 0; + real v = 0; if (!isPairInteraction(ftype)) { if (ftype == F_CMAP) @@ -352,20 +350,14 @@ calc_one_bond(int thread, nice to account to its own subtimer, but first wallcycle needs to be extended to support calling from multiple threads. */ - v = cmap_dihs(nbn, iatoms+nb0, - idef->iparams, idef->cmap_grid, - x, f, fshift, - pbc, g, lambda[efptFTYPE], &(dvdl[efptFTYPE]), - md, fcd, global_atom_index); + v = cmap_dihs(nbn, iatoms + nb0, idef->iparams, idef->cmap_grid, x, f, fshift, pbc, g, + lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, global_atom_index); } else { - v = calculateSimpleBond(ftype, nbn, iatoms + nb0, - idef->iparams, - x, f, fshift, - pbc, g, lambda[efptFTYPE], &(dvdl[efptFTYPE]), - md, fcd, global_atom_index, - flavor); + v = calculateSimpleBond(ftype, nbn, iatoms + nb0, idef->iparams, x, f, fshift, pbc, g, + lambda[efptFTYPE], &(dvdl[efptFTYPE]), md, fcd, + global_atom_index, flavor); } } else @@ -373,10 +365,8 @@ calc_one_bond(int thread, /* TODO The execution time for pairs might be nice to account to its own subtimer, but first wallcycle needs to be extended to support calling from multiple threads. */ - do_pairs(ftype, nbn, iatoms+nb0, idef->iparams, x, f, fshift, - pbc, g, lambda, dvdl, md, fr, - havePerturbedInteractions, stepWork, - grpp, global_atom_index); + do_pairs(ftype, nbn, iatoms + nb0, idef->iparams, x, f, fshift, pbc, g, lambda, dvdl, md, + fr, havePerturbedInteractions, stepWork, grpp, global_atom_index); } if (thread == 0) @@ -391,40 +381,39 @@ calc_one_bond(int thread, /*! \brief Compute the bonded part of the listed forces, parallelized over threads */ -static void -calcBondedForces(const t_idef *idef, - const rvec x[], - const t_forcerec *fr, - const t_pbc *pbc_null, - const t_graph *g, - rvec *fshiftMasterBuffer, - gmx_enerdata_t *enerd, - t_nrnb *nrnb, - const real *lambda, - real *dvdl, - const t_mdatoms *md, - t_fcdata *fcd, - const gmx::StepWorkload &stepWork, - int *global_atom_index) +static void calcBondedForces(const t_idef* idef, + const rvec x[], + const t_forcerec* fr, + const t_pbc* pbc_null, + const t_graph* g, + rvec* fshiftMasterBuffer, + gmx_enerdata_t* enerd, + t_nrnb* nrnb, + const real* lambda, + real* dvdl, + const t_mdatoms* md, + t_fcdata* fcd, + const gmx::StepWorkload& stepWork, + int* global_atom_index) { - bonded_threading_t *bt = fr->bondedThreading; + bonded_threading_t* bt = fr->bondedThreading; #pragma omp parallel for num_threads(bt->nthreads) schedule(static) for (int thread = 0; thread < bt->nthreads; thread++) { try { - f_thread_t &threadBuffers = *bt->f_t[thread]; - int ftype; - real *epot, v; + f_thread_t& threadBuffers = *bt->f_t[thread]; + int ftype; + real * epot, v; /* thread stuff */ - rvec *fshift; - real *dvdlt; - gmx_grppairener_t *grpp; + rvec* fshift; + real* dvdlt; + gmx_grppairener_t* grpp; zero_thread_output(&threadBuffers); - rvec4 *ft = threadBuffers.f; + rvec4* ft = threadBuffers.f; /* Thread 0 writes directly to the main output buffers. * We might want to reconsider this. @@ -448,60 +437,54 @@ calcBondedForces(const t_idef *idef, { if (idef->il[ftype].nr > 0 && ftype_is_bonded_potential(ftype)) { - v = calc_one_bond(thread, ftype, idef, - fr->bondedThreading->workDivision, x, - ft, fshift, fr, pbc_null, g, grpp, - nrnb, lambda, dvdlt, - md, fcd, stepWork, - global_atom_index); + v = calc_one_bond(thread, ftype, idef, fr->bondedThreading->workDivision, x, ft, + fshift, fr, pbc_null, g, grpp, nrnb, lambda, dvdlt, md, fcd, + stepWork, global_atom_index); epot[ftype] += v; } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } -bool haveRestraints(const t_idef &idef, - const t_fcdata &fcd) +bool haveRestraints(const t_idef& idef, const t_fcdata& fcd) { - return - ((idef.il[F_POSRES].nr > 0) || - (idef.il[F_FBPOSRES].nr > 0) || - fcd.orires.nr > 0 || - fcd.disres.nres > 0); + return ((idef.il[F_POSRES].nr > 0) || (idef.il[F_FBPOSRES].nr > 0) || fcd.orires.nr > 0 + || fcd.disres.nres > 0); } -bool haveCpuBondeds(const t_forcerec &fr) +bool haveCpuBondeds(const t_forcerec& fr) { return fr.bondedThreading->haveBondeds; } -bool haveCpuListedForces(const t_forcerec &fr, - const t_idef &idef, - const t_fcdata &fcd) +bool haveCpuListedForces(const t_forcerec& fr, const t_idef& idef, const t_fcdata& fcd) { return haveCpuBondeds(fr) || haveRestraints(idef, fcd); } -void calc_listed(const t_commrec *cr, - const gmx_multisim_t *ms, - struct gmx_wallcycle *wcycle, - const t_idef *idef, - const rvec x[], history_t *hist, - gmx::ForceOutputs *forceOutputs, - const t_forcerec *fr, - const struct t_pbc *pbc, - const struct t_pbc *pbc_full, - const struct t_graph *g, - gmx_enerdata_t *enerd, t_nrnb *nrnb, - const real *lambda, - const t_mdatoms *md, - t_fcdata *fcd, int *global_atom_index, - const gmx::StepWorkload &stepWork) +void calc_listed(const t_commrec* cr, + const gmx_multisim_t* ms, + struct gmx_wallcycle* wcycle, + const t_idef* idef, + const rvec x[], + history_t* hist, + gmx::ForceOutputs* forceOutputs, + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_pbc* pbc_full, + const struct t_graph* g, + gmx_enerdata_t* enerd, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* global_atom_index, + const gmx::StepWorkload& stepWork) { - const t_pbc *pbc_null; - bonded_threading_t *bt = fr->bondedThreading; + const t_pbc* pbc_null; + bonded_threading_t* bt = fr->bondedThreading; if (fr->bMolPBC) { @@ -523,14 +506,12 @@ void calc_listed(const t_commrec *cr, if (idef->il[F_POSRES].nr > 0) { - posres_wrapper(nrnb, idef, pbc_full, x, enerd, lambda, fr, - &forceOutputs->forceWithVirial()); + posres_wrapper(nrnb, idef, pbc_full, x, enerd, lambda, fr, &forceOutputs->forceWithVirial()); } if (idef->il[F_FBPOSRES].nr > 0) { - fbposres_wrapper(nrnb, idef, pbc_full, x, enerd, fr, - &forceOutputs->forceWithVirial()); + fbposres_wrapper(nrnb, idef, pbc_full, x, enerd, fr, &forceOutputs->forceWithVirial()); } /* Do pre force calculation stuff which might require communication */ @@ -542,19 +523,14 @@ void calc_listed(const t_commrec *cr, * do with checking graph!=nullptr, which should tell us if we made * molecules whole before calling the current function. */ - GMX_RELEASE_ASSERT(fr->ePBC == epbcNONE || g != nullptr, "With orientation restraints molecules should be whole"); - enerd->term[F_ORIRESDEV] = - calc_orires_dev(ms, idef->il[F_ORIRES].nr, - idef->il[F_ORIRES].iatoms, - idef->iparams, md, x, - pbc_null, fcd, hist); + GMX_RELEASE_ASSERT(fr->ePBC == epbcNONE || g != nullptr, + "With orientation restraints molecules should be whole"); + enerd->term[F_ORIRESDEV] = calc_orires_dev(ms, idef->il[F_ORIRES].nr, idef->il[F_ORIRES].iatoms, + idef->iparams, md, x, pbc_null, fcd, hist); } if (fcd->disres.nres > 0) { - calc_disres_R_6(cr, ms, - idef->il[F_DISRES].nr, - idef->il[F_DISRES].iatoms, - x, pbc_null, + calc_disres_R_6(cr, ms, idef->il[F_DISRES].nr, idef->il[F_DISRES].iatoms, x, pbc_null, fcd, hist); } @@ -563,23 +539,20 @@ void calc_listed(const t_commrec *cr, if (haveCpuBondeds(*fr)) { - gmx::ForceWithShiftForces &forceWithShiftForces = forceOutputs->forceWithShiftForces(); + gmx::ForceWithShiftForces& forceWithShiftForces = forceOutputs->forceWithShiftForces(); wallcycle_sub_start(wcycle, ewcsLISTED); /* The dummy array is to have a place to store the dhdl at other values of lambda, which will be thrown away in the end */ - real dvdl[efptNR] = {0}; + real dvdl[efptNR] = { 0 }; calcBondedForces(idef, x, fr, pbc_null, g, - as_rvec_array(forceWithShiftForces.shiftForces().data()), - enerd, nrnb, lambda, dvdl, md, - fcd, stepWork, global_atom_index); + as_rvec_array(forceWithShiftForces.shiftForces().data()), enerd, nrnb, + lambda, dvdl, md, fcd, stepWork, global_atom_index); wallcycle_sub_stop(wcycle, ewcsLISTED); wallcycle_sub_start(wcycle, ewcsLISTED_BUF_OPS); - reduce_thread_output(fr->natoms_force, &forceWithShiftForces, - enerd->term, &enerd->grpp, dvdl, - bt, - stepWork); + reduce_thread_output(fr->natoms_force, &forceWithShiftForces, enerd->term, &enerd->grpp, + dvdl, bt, stepWork); if (stepWork.computeDhdl) { @@ -598,23 +571,26 @@ void calc_listed(const t_commrec *cr, } } -void calc_listed_lambda(const t_idef *idef, - const rvec x[], - const t_forcerec *fr, - const struct t_pbc *pbc, const struct t_graph *g, - gmx_grppairener_t *grpp, real *epot, t_nrnb *nrnb, - const real *lambda, - const t_mdatoms *md, - t_fcdata *fcd, - int *global_atom_index) +void calc_listed_lambda(const t_idef* idef, + const rvec x[], + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_graph* g, + gmx_grppairener_t* grpp, + real* epot, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* global_atom_index) { - real v; - real dvdl_dum[efptNR] = {0}; - rvec4 *f; - rvec *fshift; - const t_pbc *pbc_null; - t_idef idef_fe; - WorkDivision &workDivision = fr->bondedThreading->foreignLambdaWorkDivision; + real v; + real dvdl_dum[efptNR] = { 0 }; + rvec4* f; + rvec* fshift; + const t_pbc* pbc_null; + t_idef idef_fe; + WorkDivision& workDivision = fr->bondedThreading->foreignLambdaWorkDivision; if (fr->bMolPBC) { @@ -626,7 +602,7 @@ void calc_listed_lambda(const t_idef *idef, } /* Copy the whole idef, so we can modify the contents locally */ - idef_fe = *idef; + idef_fe = *idef; /* We already have the forces, so we use temp buffers here */ // TODO: Get rid of these allocations by using permanent force buffers @@ -638,9 +614,9 @@ void calc_listed_lambda(const t_idef *idef, { if (ftype_is_bonded_potential(ftype)) { - const t_ilist &ilist = idef->il[ftype]; + const t_ilist& ilist = idef->il[ftype]; /* Create a temporary t_ilist with only perturbed interactions */ - t_ilist &ilist_fe = idef_fe.il[ftype]; + t_ilist& ilist_fe = idef_fe.il[ftype]; ilist_fe.iatoms = ilist.iatoms + ilist.nr_nonperturbed; ilist_fe.nr_nonperturbed = 0; ilist_fe.nr = ilist.nr - ilist.nr_nonperturbed; @@ -651,12 +627,9 @@ void calc_listed_lambda(const t_idef *idef, if (ilist_fe.nr > 0) { gmx::StepWorkload tempFlags; - tempFlags.computeEnergy = true; - v = calc_one_bond(0, ftype, &idef_fe, workDivision, - x, f, fshift, fr, pbc_null, g, - grpp, nrnb, lambda, dvdl_dum, - md, fcd, tempFlags, - global_atom_index); + tempFlags.computeEnergy = true; + v = calc_one_bond(0, ftype, &idef_fe, workDivision, x, f, fshift, fr, pbc_null, g, + grpp, nrnb, lambda, dvdl_dum, md, fcd, tempFlags, global_atom_index); epot[ftype] += v; } } @@ -666,26 +639,25 @@ void calc_listed_lambda(const t_idef *idef, sfree(f); } -void -do_force_listed(struct gmx_wallcycle *wcycle, - const matrix box, - const t_lambda *fepvals, - const t_commrec *cr, - const gmx_multisim_t *ms, - const t_idef *idef, - const rvec x[], - history_t *hist, - gmx::ForceOutputs *forceOutputs, - const t_forcerec *fr, - const struct t_pbc *pbc, - const struct t_graph *graph, - gmx_enerdata_t *enerd, - t_nrnb *nrnb, - const real *lambda, - const t_mdatoms *md, - t_fcdata *fcd, - int *global_atom_index, - const gmx::StepWorkload &stepWork) +void do_force_listed(struct gmx_wallcycle* wcycle, + const matrix box, + const t_lambda* fepvals, + const t_commrec* cr, + const gmx_multisim_t* ms, + const t_idef* idef, + const rvec x[], + history_t* hist, + gmx::ForceOutputs* forceOutputs, + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_graph* graph, + gmx_enerdata_t* enerd, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* global_atom_index, + const gmx::StepWorkload& stepWork) { t_pbc pbc_full; /* Full PBC is needed for position restraints */ @@ -694,17 +666,13 @@ do_force_listed(struct gmx_wallcycle *wcycle, return; } - if ((idef->il[F_POSRES].nr > 0) || - (idef->il[F_FBPOSRES].nr > 0)) + if ((idef->il[F_POSRES].nr > 0) || (idef->il[F_FBPOSRES].nr > 0)) { /* Not enough flops to bother counting */ set_pbc(&pbc_full, fr->ePBC, box); } - calc_listed(cr, ms, wcycle, idef, x, hist, - forceOutputs, - fr, pbc, &pbc_full, - graph, enerd, nrnb, lambda, md, fcd, - global_atom_index, stepWork); + calc_listed(cr, ms, wcycle, idef, x, hist, forceOutputs, fr, pbc, &pbc_full, graph, enerd, nrnb, + lambda, md, fcd, global_atom_index, stepWork); /* Check if we have to determine energy differences * at foreign lambda's. @@ -727,10 +695,10 @@ do_force_listed(struct gmx_wallcycle *wcycle, reset_foreign_enerdata(enerd); for (int j = 0; j < efptNR; j++) { - lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i-1]); + lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]); } - calc_listed_lambda(idef, x, fr, pbc, graph, &(enerd->foreign_grpp), enerd->foreign_term, nrnb, lam_i, md, - fcd, global_atom_index); + calc_listed_lambda(idef, x, fr, pbc, graph, &(enerd->foreign_grpp), + enerd->foreign_term, nrnb, lam_i, md, fcd, global_atom_index); sum_epot(&(enerd->foreign_grpp), enerd->foreign_term); enerd->enerpart_lambda[i] += enerd->foreign_term[F_EPOT]; } diff --git a/src/gromacs/listed_forces/listed_forces.h b/src/gromacs/listed_forces/listed_forces.h index 2cb13d65cd..00aa11bb3e 100644 --- a/src/gromacs/listed_forces/listed_forces.h +++ b/src/gromacs/listed_forces/listed_forces.h @@ -88,16 +88,22 @@ namespace gmx { class ForceOutputs; class StepWorkload; -} +} // namespace gmx //! Type of CPU function to compute a bonded interaction. -using BondedFunction = real(*)(int nbonds, const t_iatom iatoms[], - const t_iparams iparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int *ddgatindex); +using BondedFunction = real (*)(int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* ddgatindex); //! Getter for finding a callable CPU function to compute an \c ftype interaction. BondedFunction bondedFunction(int ftype); @@ -106,70 +112,75 @@ BondedFunction bondedFunction(int ftype); * * Note that pbc_full is used only for position restraints, and is * not initialized if there are none. */ -void calc_listed(const t_commrec *cr, - const gmx_multisim_t *ms, - struct gmx_wallcycle *wcycle, - const t_idef *idef, - const rvec x[], history_t *hist, - gmx::ForceOutputs *forceOutputs, - const t_forcerec *fr, - const struct t_pbc *pbc, const struct t_pbc *pbc_full, - const struct t_graph *g, - gmx_enerdata_t *enerd, t_nrnb *nrnb, const real *lambda, - const t_mdatoms *md, - struct t_fcdata *fcd, int *ddgatindex, - const gmx::StepWorkload &stepWork); +void calc_listed(const t_commrec* cr, + const gmx_multisim_t* ms, + struct gmx_wallcycle* wcycle, + const t_idef* idef, + const rvec x[], + history_t* hist, + gmx::ForceOutputs* forceOutputs, + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_pbc* pbc_full, + const struct t_graph* g, + gmx_enerdata_t* enerd, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + struct t_fcdata* fcd, + int* ddgatindex, + const gmx::StepWorkload& stepWork); /*! \brief As calc_listed(), but only determines the potential energy * for the perturbed interactions. * * The shift forces in fr are not affected. */ -void calc_listed_lambda(const t_idef *idef, - const rvec x[], - const t_forcerec *fr, - const struct t_pbc *pbc, const struct t_graph *g, - gmx_grppairener_t *grpp, real *epot, t_nrnb *nrnb, - const real *lambda, - const t_mdatoms *md, - struct t_fcdata *fcd, int *global_atom_index); +void calc_listed_lambda(const t_idef* idef, + const rvec x[], + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_graph* g, + gmx_grppairener_t* grpp, + real* epot, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + struct t_fcdata* fcd, + int* global_atom_index); /*! \brief Do all aspects of energy and force calculations for mdrun * on the set of listed interactions */ -void -do_force_listed(struct gmx_wallcycle *wcycle, - const matrix box, - const t_lambda *fepvals, - const t_commrec *cr, - const gmx_multisim_t *ms, - const t_idef *idef, - const rvec x[], - history_t *hist, - gmx::ForceOutputs *forceOutputs, - const t_forcerec *fr, - const struct t_pbc *pbc, - const struct t_graph *graph, - gmx_enerdata_t *enerd, - t_nrnb *nrnb, - const real *lambda, - const t_mdatoms *md, - struct t_fcdata *fcd, - int *global_atom_index, - const gmx::StepWorkload &stepWork); +void do_force_listed(struct gmx_wallcycle* wcycle, + const matrix box, + const t_lambda* fepvals, + const t_commrec* cr, + const gmx_multisim_t* ms, + const t_idef* idef, + const rvec x[], + history_t* hist, + gmx::ForceOutputs* forceOutputs, + const t_forcerec* fr, + const struct t_pbc* pbc, + const struct t_graph* graph, + gmx_enerdata_t* enerd, + t_nrnb* nrnb, + const real* lambda, + const t_mdatoms* md, + struct t_fcdata* fcd, + int* global_atom_index, + const gmx::StepWorkload& stepWork); /*! \brief Returns true if there are position, distance or orientation restraints. */ -bool haveRestraints(const t_idef &idef, - const t_fcdata &fcd); +bool haveRestraints(const t_idef& idef, const t_fcdata& fcd); /*! \brief Returns true if there are CPU (i.e. not GPU-offloaded) bonded interactions to compute. */ -bool haveCpuBondeds(const t_forcerec &fr); +bool haveCpuBondeds(const t_forcerec& fr); /*! \brief Returns true if there are listed interactions to compute. * * NOTE: the current implementation returns true if there are position restraints * or any bonded interactions computed on the CPU. */ -bool haveCpuListedForces(const t_forcerec &fr, - const t_idef &idef, - const t_fcdata &fcd); +bool haveCpuListedForces(const t_forcerec& fr, const t_idef& idef, const t_fcdata& fcd); #endif diff --git a/src/gromacs/listed_forces/listed_internal.cpp b/src/gromacs/listed_forces/listed_internal.cpp index fe883968e8..516f6323e3 100644 --- a/src/gromacs/listed_forces/listed_internal.cpp +++ b/src/gromacs/listed_forces/listed_internal.cpp @@ -45,7 +45,7 @@ #include -int glatnr(const int *global_atom_index, int i) +int glatnr(const int* global_atom_index, int i) { int atnr; diff --git a/src/gromacs/listed_forces/listed_internal.h b/src/gromacs/listed_forces/listed_internal.h index 9a0871ce5e..a9e698deb8 100644 --- a/src/gromacs/listed_forces/listed_internal.h +++ b/src/gromacs/listed_forces/listed_internal.h @@ -56,45 +56,35 @@ * size on all systems. */ static const int reduction_block_size = 32; /**< Force buffer block size in atoms*/ -static const int reduction_block_bits = 5; /**< log2(reduction_block_size) */ +static const int reduction_block_bits = 5; /**< log2(reduction_block_size) */ /*! \internal \brief The division of bonded interactions of the threads */ class WorkDivision { - public: - //! Constructor - WorkDivision(int numThreads) : - stride_(numThreads + 1), - packedBounds_(F_NRE*stride_) - { - } - - //! Sets the bound between threads \p boundIndex-1 and \p boundIndex to \p count - void setBound(int functionType, - int boundIndex, - int count) - { - packedBounds_[functionType*stride_ + boundIndex] = count; - } - - //! Returns the bound between threads \p boundIndex-1 and \p boundIndex - int bound(int functionType, - int boundIndex) const - { - return packedBounds_[functionType*stride_ + boundIndex]; - } - - //! Returns the last bound - int end(int ftype) const - { - return bound(ftype, stride_ - 1); - } - - private: - //! The stride_ between and size of the entries for a function type - int stride_; - //! The bounds stored as a flat array for fast access - std::vector packedBounds_; +public: + //! Constructor + WorkDivision(int numThreads) : stride_(numThreads + 1), packedBounds_(F_NRE * stride_) {} + + //! Sets the bound between threads \p boundIndex-1 and \p boundIndex to \p count + void setBound(int functionType, int boundIndex, int count) + { + packedBounds_[functionType * stride_ + boundIndex] = count; + } + + //! Returns the bound between threads \p boundIndex-1 and \p boundIndex + int bound(int functionType, int boundIndex) const + { + return packedBounds_[functionType * stride_ + boundIndex]; + } + + //! Returns the last bound + int end(int ftype) const { return bound(ftype, stride_ - 1); } + +private: + //! The stride_ between and size of the entries for a function type + int stride_; + //! The bounds stored as a flat array for fast access + std::vector packedBounds_; }; /*! \internal \brief struct with output for bonded forces, used per thread */ @@ -105,44 +95,44 @@ struct f_thread_t ~f_thread_t(); - rvec4 *f = nullptr; /**< Force array */ - int f_nalloc = 0; /**< Allocation size of f */ - gmx_bitmask_t *mask = nullptr; /**< Mask for marking which parts of f are filled, working array for constructing mask in bonded_threading_t */ - int nblock_used; /**< Number of blocks touched by our thread */ - int *block_index = nullptr; /**< Index to touched blocks, size nblock_used */ - int block_nalloc = 0; /**< Allocation size of f (*reduction_block_size), mask_index, mask */ - - rvec *fshift; /**< Shift force array, size SHIFTS */ - real ener[F_NRE]; /**< Energy array */ - gmx_grppairener_t grpp; /**< Group pair energy data for pairs */ - real dvdl[efptNR]; /**< Free-energy dV/dl output */ + rvec4* f = nullptr; /**< Force array */ + int f_nalloc = 0; /**< Allocation size of f */ + gmx_bitmask_t* mask = + nullptr; /**< Mask for marking which parts of f are filled, working array for constructing mask in bonded_threading_t */ + int nblock_used; /**< Number of blocks touched by our thread */ + int* block_index = nullptr; /**< Index to touched blocks, size nblock_used */ + int block_nalloc = 0; /**< Allocation size of f (*reduction_block_size), mask_index, mask */ + + rvec* fshift; /**< Shift force array, size SHIFTS */ + real ener[F_NRE]; /**< Energy array */ + gmx_grppairener_t grpp; /**< Group pair energy data for pairs */ + real dvdl[efptNR]; /**< Free-energy dV/dl output */ }; /*! \internal \brief struct contain all data for bonded force threading */ struct bonded_threading_t { //! Constructor - bonded_threading_t(int numThreads, - int numEnergyGroups); + bonded_threading_t(int numThreads, int numEnergyGroups); //! Number of threads to be used for bondeds - int nthreads; + int nthreads; //! Force/energy data per thread, size nthreads, stored in unique_ptr to allow thread local allocation - std::vector < std::unique_ptr < f_thread_t>> f_t; + std::vector> f_t; //! The number of force blocks to reduce - int nblock_used; + int nblock_used; //! Index of size nblock_used into mask - std::vector block_index; + std::vector block_index; //! Mask array, one element corresponds to a block of reduction_block_size atoms of the force array, bit corresponding to thread indices set if a thread writes to that block - std::vector mask; + std::vector mask; //! true if we have and thus need to reduce bonded forces - bool haveBondeds; + bool haveBondeds; /* There are two different ways to distribute the bonded force calculation * over the threads. We dedice which to use based on the number of threads. */ //! Maximum thread count for uniform distribution of bondeds over threads - int max_nthread_uniform; + int max_nthread_uniform; //! The division of work in the t_list over threads. WorkDivision workDivision; @@ -158,7 +148,6 @@ struct bonded_threading_t * This function is intended for writing ascii output and returns atom * numbers starting at 1. When global_atom_index=NULL returns i+1. */ -int -glatnr(const int *global_atom_index, int i); +int glatnr(const int* global_atom_index, int i); #endif diff --git a/src/gromacs/listed_forces/manage_threading.cpp b/src/gromacs/listed_forces/manage_threading.cpp index 5546f1f040..f8d4ff0584 100644 --- a/src/gromacs/listed_forces/manage_threading.cpp +++ b/src/gromacs/listed_forces/manage_threading.cpp @@ -68,8 +68,9 @@ #include "utilities.h" /*! \brief struct for passing all data required for a function type */ -typedef struct { - const t_ilist *il; /**< pointer to t_ilist entry corresponding to ftype */ +typedef struct +{ + const t_ilist* il; /**< pointer to t_ilist entry corresponding to ftype */ int ftype; /**< the function type index */ int nat; /**< nr of atoms involved in a single ftype interaction */ } ilist_data_t; @@ -81,9 +82,7 @@ typedef struct { * equal load and different threads avoid touching the same atoms as much * as possible. */ -static void divide_bondeds_by_locality(bonded_threading_t *bt, - int numType, - const ilist_data_t *ild) +static void divide_bondeds_by_locality(bonded_threading_t* bt, int numType, const ilist_data_t* ild) { int nat_tot, nat_sum; int ind[F_NRE]; /* index into the ild[].il->iatoms */ @@ -96,9 +95,9 @@ static void divide_bondeds_by_locality(bonded_threading_t *bt, for (f = 0; f < numType; f++) { /* Sum #bondeds*#atoms_per_bond over all bonded types */ - nat_tot += ild[f].il->nr/(ild[f].nat + 1)*ild[f].nat; + nat_tot += ild[f].il->nr / (ild[f].nat + 1) * ild[f].nat; /* The start bound for thread 0 is 0 for all interactions */ - ind[f] = 0; + ind[f] = 0; /* Initialize the next atom index array */ assert(ild[f].il->nr > 0); at_ind[f] = ild[f].il->iatoms[1]; @@ -127,7 +126,7 @@ static void divide_bondeds_by_locality(bonded_threading_t *bt, * uniformly. Proper and RB dihedrals are often distributed * non-uniformly, but their cost is roughly equal. */ - nat_thread = (nat_tot*t)/bt->nthreads; + nat_thread = (nat_tot * t) / bt->nthreads; while (nat_sum < nat_thread) { @@ -159,7 +158,7 @@ static void divide_bondeds_by_locality(bonded_threading_t *bt, * index f_min) to thread t-1 by increasing ind. */ ind[f_min] += ild[f_min].nat + 1; - nat_sum += ild[f_min].nat; + nat_sum += ild[f_min].nat; /* Update the first unassigned atom index for this type */ if (ind[f_min] < ild[f_min].il->nr) @@ -190,21 +189,18 @@ static void divide_bondeds_by_locality(bonded_threading_t *bt, } //! Return whether function type \p ftype in \p idef has perturbed interactions -static bool ftypeHasPerturbedEntries(const t_idef &idef, - int ftype) +static bool ftypeHasPerturbedEntries(const t_idef& idef, int ftype) { GMX_ASSERT(idef.ilsort == ilsortNO_FE || idef.ilsort == ilsortFE_SORTED, "Perturbed interations should be sorted here"); - const t_ilist &ilist = idef.il[ftype]; + const t_ilist& ilist = idef.il[ftype]; return (idef.ilsort != ilsortNO_FE && ilist.nr_nonperturbed != ilist.nr); } //! Divides bonded interactions over threads and GPU -static void divide_bondeds_over_threads(bonded_threading_t *bt, - bool useGpuForBondeds, - const t_idef &idef) +static void divide_bondeds_over_threads(bonded_threading_t* bt, bool useGpuForBondeds, const t_idef& idef) { ilist_data_t ild[F_NRE]; @@ -221,12 +217,11 @@ static void divide_bondeds_over_threads(bonded_threading_t *bt, continue; } - const t_ilist &il = idef.il[fType]; + const t_ilist& il = idef.il[fType]; int nrToAssignToCpuThreads = il.nr; - if (useGpuForBondeds && - fTypeGpuIndex < gmx::fTypesOnGpu.size() && - gmx::fTypesOnGpu[fTypeGpuIndex] == fType) + if (useGpuForBondeds && fTypeGpuIndex < gmx::fTypesOnGpu.size() + && gmx::fTypesOnGpu[fTypeGpuIndex] == fType) { fTypeGpuIndex++; @@ -265,16 +260,16 @@ static void divide_bondeds_over_threads(bonded_threading_t *bt, for (int t = 0; t <= numThreads; t++) { /* Divide equally over the threads */ - int nr_t = (((nrToAssignToCpuThreads/stride)*t)/numThreads)*stride; + int nr_t = (((nrToAssignToCpuThreads / stride) * t) / numThreads) * stride; if (fType == F_DISRES) { /* Ensure that distance restraint pairs with the same label * end up on the same thread. */ - while (nr_t > 0 && nr_t < nrToAssignToCpuThreads && - idef.iparams[il.iatoms[nr_t]].disres.label == - idef.iparams[il.iatoms[nr_t - stride]].disres.label) + while (nr_t > 0 && nr_t < nrToAssignToCpuThreads + && idef.iparams[il.iatoms[nr_t]].disres.label + == idef.iparams[il.iatoms[nr_t - stride]].disres.label) { nr_t += stride; } @@ -286,7 +281,7 @@ static void divide_bondeds_over_threads(bonded_threading_t *bt, else { /* Add this fType to the list to be distributed */ - int nat = NRAL(fType); + int nat = NRAL(fType); ild[numType].ftype = fType; ild[numType].il = &il; ild[numType].nat = nat; @@ -318,9 +313,8 @@ static void divide_bondeds_over_threads(bonded_threading_t *bt, for (t = 0; t < numThreads; t++) { fprintf(debug, " %4d", - (bt->workDivision.bound(f, t + 1) - - bt->workDivision.bound(f, t))/ - (1 + NRAL(f))); + (bt->workDivision.bound(f, t + 1) - bt->workDivision.bound(f, t)) + / (1 + NRAL(f))); } fprintf(debug, "\n"); } @@ -329,37 +323,41 @@ static void divide_bondeds_over_threads(bonded_threading_t *bt, } //! Construct a reduction mask for which parts (blocks) of the force array are touched on which thread task -static void -calc_bonded_reduction_mask(int natoms, - f_thread_t *f_thread, - const t_idef &idef, - int thread, - const bonded_threading_t &bondedThreading) +static void calc_bonded_reduction_mask(int natoms, + f_thread_t* f_thread, + const t_idef& idef, + int thread, + const bonded_threading_t& bondedThreading) { - static_assert(BITMASK_SIZE == GMX_OPENMP_MAX_THREADS, "For the error message below we assume these two are equal."); + static_assert(BITMASK_SIZE == GMX_OPENMP_MAX_THREADS, + "For the error message below we assume these two are equal."); if (bondedThreading.nthreads > BITMASK_SIZE) { #pragma omp master - gmx_fatal(FARGS, "You are using %d OpenMP threads, which is larger than GMX_OPENMP_MAX_THREADS (%d). Decrease the number of OpenMP threads or rebuild GROMACS with a larger value for GMX_OPENMP_MAX_THREADS passed to CMake.", + gmx_fatal(FARGS, + "You are using %d OpenMP threads, which is larger than GMX_OPENMP_MAX_THREADS " + "(%d). Decrease the number of OpenMP threads or rebuild GROMACS with a larger " + "value for GMX_OPENMP_MAX_THREADS passed to CMake.", bondedThreading.nthreads, GMX_OPENMP_MAX_THREADS); #pragma omp barrier } - GMX_ASSERT(bondedThreading.nthreads <= BITMASK_SIZE, "We need at least nthreads bits in the mask"); + GMX_ASSERT(bondedThreading.nthreads <= BITMASK_SIZE, + "We need at least nthreads bits in the mask"); int nblock = (natoms + reduction_block_size - 1) >> reduction_block_bits; if (nblock > f_thread->block_nalloc) { f_thread->block_nalloc = over_alloc_large(nblock); - srenew(f_thread->mask, f_thread->block_nalloc); + srenew(f_thread->mask, f_thread->block_nalloc); srenew(f_thread->block_index, f_thread->block_nalloc); // NOTE: It seems f_thread->f does not need to be aligned sfree_aligned(f_thread->f); - snew_aligned(f_thread->f, f_thread->block_nalloc*reduction_block_size, 128); + snew_aligned(f_thread->f, f_thread->block_nalloc * reduction_block_size, 128); } - gmx_bitmask_t *mask = f_thread->mask; + gmx_bitmask_t* mask = f_thread->mask; for (int b = 0; b < nblock; b++) { @@ -382,7 +380,7 @@ calc_bonded_reduction_mask(int natoms, { for (int a = 1; a < nat1; a++) { - bitmask_set_bit(&mask[idef.il[ftype].iatoms[i+a] >> reduction_block_bits], thread); + bitmask_set_bit(&mask[idef.il[ftype].iatoms[i + a] >> reduction_block_bits], thread); } } } @@ -402,12 +400,9 @@ calc_bonded_reduction_mask(int natoms, } } -void setup_bonded_threading(bonded_threading_t *bt, - int numAtoms, - bool useGpuForBondeds, - const t_idef &idef) +void setup_bonded_threading(bonded_threading_t* bt, int numAtoms, bool useGpuForBondeds, const t_idef& idef) { - int ctot = 0; + int ctot = 0; assert(bt->nthreads >= 1); @@ -428,10 +423,9 @@ void setup_bonded_threading(bonded_threading_t *bt, { try { - calc_bonded_reduction_mask(numAtoms, bt->f_t[t].get(), - idef, t, *bt); + calc_bonded_reduction_mask(numAtoms, bt->f_t[t].get(), idef, t, *bt); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Reduce the masks over the threads and determine which blocks @@ -450,7 +444,7 @@ void setup_bonded_threading(bonded_threading_t *bt, bt->nblock_used = 0; for (int b = 0; b < nblock_tot; b++) { - gmx_bitmask_t *mask = &bt->mask[b]; + gmx_bitmask_t* mask = &bt->mask[b]; /* Generate the union over the threads of the bitmask */ bitmask_clear(mask); @@ -477,28 +471,25 @@ void setup_bonded_threading(bonded_threading_t *bt, if (gmx_debug_at) { - fprintf(debug, "block %d flags %s count %d\n", - b, to_hex_string(*mask).c_str(), c); + fprintf(debug, "block %d flags %s count %d\n", b, to_hex_string(*mask).c_str(), c); } } } if (debug) { - fprintf(debug, "Number of %d atom blocks to reduce: %d\n", - reduction_block_size, bt->nblock_used); + fprintf(debug, "Number of %d atom blocks to reduce: %d\n", reduction_block_size, bt->nblock_used); fprintf(debug, "Reduction density %.2f for touched blocks only %.2f\n", - ctot*reduction_block_size/static_cast(numAtoms), - ctot/static_cast(bt->nblock_used)); + ctot * reduction_block_size / static_cast(numAtoms), + ctot / static_cast(bt->nblock_used)); } } -void tear_down_bonded_threading(bonded_threading_t *bt) +void tear_down_bonded_threading(bonded_threading_t* bt) { delete bt; } -f_thread_t::f_thread_t(int numEnergyGroups) : - grpp(numEnergyGroups) +f_thread_t::f_thread_t(int numEnergyGroups) : grpp(numEnergyGroups) { snew(fshift, SHIFTS); } @@ -511,8 +502,7 @@ f_thread_t::~f_thread_t() sfree_aligned(f); } -bonded_threading_t::bonded_threading_t(const int numThreads, - const int numEnergyGroups) : +bonded_threading_t::bonded_threading_t(const int numThreads, const int numEnergyGroups) : nthreads(numThreads), nblock_used(0), haveBondeds(false), @@ -530,12 +520,11 @@ bonded_threading_t::bonded_threading_t(const int numThreads, */ f_t[t] = std::make_unique(numEnergyGroups); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } -bonded_threading_t *init_bonded_threading(FILE *fplog, - const int nenergrp) +bonded_threading_t* init_bonded_threading(FILE* fplog, const int nenergrp) { /* These thread local data structures are used for bondeds only. * @@ -546,15 +535,14 @@ bonded_threading_t *init_bonded_threading(FILE *fplog, * of doing transposeScatterIncr/DecrU with aligment 4 instead of 3 * is much larger than the reduction overhead. */ - bonded_threading_t *bt = new bonded_threading_t(gmx_omp_nthreads_get(emntBonded), - nenergrp); + bonded_threading_t* bt = new bonded_threading_t(gmx_omp_nthreads_get(emntBonded), nenergrp); /* The optimal value after which to switch from uniform to localized * bonded interaction distribution is 3, 4 or 5 depending on the system * and hardware. */ const int max_nthread_uniform = 4; - char * ptr; + char* ptr; if ((ptr = getenv("GMX_BONDED_NTHREAD_UNIFORM")) != nullptr) { diff --git a/src/gromacs/listed_forces/manage_threading.h b/src/gromacs/listed_forces/manage_threading.h index 8ca8f25315..6639b32525 100644 --- a/src/gromacs/listed_forces/manage_threading.h +++ b/src/gromacs/listed_forces/manage_threading.h @@ -56,13 +56,10 @@ struct t_idef; * This should be called each time the bonded setup changes; * i.e. at start-up without domain decomposition and at DD. */ -void setup_bonded_threading(bonded_threading_t *bt, - int numAtoms, - bool useGpuForBondes, - const t_idef &idef); +void setup_bonded_threading(bonded_threading_t* bt, int numAtoms, bool useGpuForBondes, const t_idef& idef); //! Destructor. -void tear_down_bonded_threading(bonded_threading_t *bt); +void tear_down_bonded_threading(bonded_threading_t* bt); /*! \brief Initialize the bonded threading data structures * @@ -71,7 +68,6 @@ void tear_down_bonded_threading(bonded_threading_t *bt); * * \todo Avoid explicit pointers by using Impl */ -bonded_threading_t *init_bonded_threading(FILE *fplog, - int nenergrp); +bonded_threading_t* init_bonded_threading(FILE* fplog, int nenergrp); #endif diff --git a/src/gromacs/listed_forces/orires.cpp b/src/gromacs/listed_forces/orires.cpp index 0a0d9b803c..c7d326571d 100644 --- a/src/gromacs/listed_forces/orires.cpp +++ b/src/gromacs/listed_forces/orires.cpp @@ -65,13 +65,13 @@ // TODO This implementation of ensemble orientation restraints is nasty because // a user can't just do multi-sim with single-sim orientation restraints. -void init_orires(FILE *fplog, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_state *globalState, - t_oriresdata *od) +void init_orires(FILE* fplog, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_state* globalState, + t_oriresdata* od) { od->nr = gmx_mtop_ftype_count(mtop, F_ORIRES); if (0 == od->nr) @@ -83,7 +83,9 @@ void init_orires(FILE *fplog, const int numFitParams = 5; if (od->nr <= numFitParams) { - gmx_fatal(FARGS, "The system has %d orientation restraints, but at least %d are required, since there are %d fitting parameters.", + gmx_fatal(FARGS, + "The system has %d orientation restraints, but at least %d are required, since " + "there are %d fitting parameters.", od->nr, numFitParams + 1, numFitParams); } @@ -92,12 +94,16 @@ void init_orires(FILE *fplog, /* Since we apply fitting, we need to make molecules whole and this * can not be done when periodic molecules are present. */ - gmx_fatal(FARGS, "Orientation restraints can not be applied when periodic molecules are present in the system"); + gmx_fatal(FARGS, + "Orientation restraints can not be applied when periodic molecules are present " + "in the system"); } if (PAR(cr)) { - gmx_fatal(FARGS, "Orientation restraints do not work with MPI parallelization. Choose 1 MPI rank, if possible."); + gmx_fatal(FARGS, + "Orientation restraints do not work with MPI parallelization. Choose 1 MPI rank, " + "if possible."); } GMX_RELEASE_ASSERT(globalState != nullptr, "We need a valid global state in init_orires"); @@ -109,16 +115,20 @@ void init_orires(FILE *fplog, od->eig = nullptr; od->v = nullptr; - int *nr_ex = nullptr; - int typeMin = INT_MAX; - int typeMax = 0; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol; - while (const InteractionLists *il = gmx_mtop_ilistloop_next(iloop, &nmol)) + int* nr_ex = nullptr; + int typeMin = INT_MAX; + int typeMax = 0; + gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); + int nmol; + while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) { if (nmol > 1) { - gmx_fatal(FARGS, "Found %d copies of a molecule with orientation restrains while the current code only supports a single copy. If you want to ensemble average, run multiple copies of the system using the multi-sim feature of mdrun.", nmol); + gmx_fatal(FARGS, + "Found %d copies of a molecule with orientation restrains while the current " + "code only supports a single copy. If you want to ensemble average, run " + "multiple copies of the system using the multi-sim feature of mdrun.", + nmol); } for (int i = 0; i < (*il)[F_ORIRES].size(); i += 3) @@ -127,12 +137,12 @@ void init_orires(FILE *fplog, int ex = mtop->ffparams.iparams[type].orires.ex; if (ex >= od->nex) { - srenew(nr_ex, ex+1); - for (int j = od->nex; j < ex+1; j++) + srenew(nr_ex, ex + 1); + for (int j = od->nex; j < ex + 1; j++) { nr_ex[j] = 0; } - od->nex = ex+1; + od->nex = ex + 1; } GMX_ASSERT(nr_ex, "Check for allocated nr_ex to keep the static analyzer happy"); nr_ex[ex]++; @@ -142,7 +152,9 @@ void init_orires(FILE *fplog, } } /* With domain decomposition we use the type index for indexing in global arrays */ - GMX_RELEASE_ASSERT(typeMax - typeMin + 1 == od->nr, "All orientation restraint parameter entries in the topology should be consecutive"); + GMX_RELEASE_ASSERT( + typeMax - typeMin + 1 == od->nr, + "All orientation restraint parameter entries in the topology should be consecutive"); /* Store typeMin so we can index array with the type offset */ od->typeMin = typeMin; @@ -170,14 +182,14 @@ void init_orires(FILE *fplog, else { snew(od->Dtav, od->nr); - od->edt = std::exp(-ir->delta_t/ir->orires_tau); + od->edt = std::exp(-ir->delta_t / ir->orires_tau); od->edt_1 = 1.0 - od->edt; /* Extend the state with the orires history */ - globalState->flags |= (1<flags |= (1 << estORIRE_INITF); globalState->hist.orire_initf = 1; - globalState->flags |= (1<hist.norire_Dtav = od->nr*5; + globalState->flags |= (1 << estORIRE_DTAV); + globalState->hist.norire_Dtav = od->nr * 5; snew(globalState->hist.orire_Dtav, globalState->hist.norire_Dtav); } @@ -212,22 +224,22 @@ void init_orires(FILE *fplog, snew(od->xref, od->nref); snew(od->xtmp, od->nref); - snew(od->eig, od->nex*12); + snew(od->eig, od->nex * 12); /* Determine the reference structure on the master node. * Copy it to the other nodes after checking multi compatibility, * so we are sure the subsystems match before copying. */ - auto x = makeArrayRef(globalState->x); - rvec com = { 0, 0, 0 }; - double mtot = 0.0; - int j = 0; + auto x = makeArrayRef(globalState->x); + rvec com = { 0, 0, 0 }; + double mtot = 0.0; + int j = 0; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); - if (mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit].empty() || - mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit][i] == 0) + if (mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit].empty() + || mtop->groups.groupNumbers[SimulationAtomGroupType::OrientationRestraintsFit][i] == 0) { /* Not correct for free-energy with changing masses */ od->mref[j] = local.m; @@ -237,14 +249,14 @@ void init_orires(FILE *fplog, copy_rvec(x[i], od->xref[j]); for (int d = 0; d < DIM; d++) { - com[d] += od->mref[j]*x[i][d]; + com[d] += od->mref[j] * x[i][d]; } } mtot += od->mref[j]; j++; } } - svmul(1.0/mtot, com, com); + svmul(1.0 / mtot, com, com); if (isMasterSim(ms)) { for (int j = 0; j < od->nref; j++) @@ -256,33 +268,28 @@ void init_orires(FILE *fplog, fprintf(fplog, "Found %d orientation experiments\n", od->nex); for (int i = 0; i < od->nex; i++) { - fprintf(fplog, " experiment %d has %d restraints\n", i+1, nr_ex[i]); + fprintf(fplog, " experiment %d has %d restraints\n", i + 1, nr_ex[i]); } sfree(nr_ex); - fprintf(fplog, " the fit group consists of %d atoms and has total mass %g\n", - od->nref, mtot); + fprintf(fplog, " the fit group consists of %d atoms and has total mass %g\n", od->nref, mtot); if (ms) { fprintf(fplog, " the orientation restraints are ensemble averaged over %d systems\n", ms->nsim); - check_multi_int(fplog, ms, od->nr, - "the number of orientation restraints", - FALSE); - check_multi_int(fplog, ms, od->nref, - "the number of fit atoms for orientation restraining", - FALSE); + check_multi_int(fplog, ms, od->nr, "the number of orientation restraints", FALSE); + check_multi_int(fplog, ms, od->nref, "the number of fit atoms for orientation restraining", FALSE); check_multi_int(fplog, ms, ir->nsteps, "nsteps", FALSE); /* Copy the reference coordinates from the master to the other nodes */ - gmx_sum_sim(DIM*od->nref, od->xref[0], ms); + gmx_sum_sim(DIM * od->nref, od->xref[0], ms); } please_cite(fplog, "Hess2003"); } -void diagonalize_orires_tensors(t_oriresdata *od) +void diagonalize_orires_tensors(t_oriresdata* od) { if (od->M == nullptr) { @@ -323,7 +330,7 @@ void diagonalize_orires_tensors(t_oriresdata *od) } for (int i = 0; i < DIM; i++) { - for (int j = i+1; j < DIM; j++) + for (int j = i + 1; j < DIM; j++) { if (gmx::square(od->eig_diag[ord[j]]) > gmx::square(od->eig_diag[ord[i]])) { @@ -336,62 +343,65 @@ void diagonalize_orires_tensors(t_oriresdata *od) for (int i = 0; i < DIM; i++) { - od->eig[ex*12 + i] = od->eig_diag[ord[i]]; + od->eig[ex * 12 + i] = od->eig_diag[ord[i]]; } for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - od->eig[ex*12 + 3 + 3*i + j] = od->v[j][ord[i]]; + od->eig[ex * 12 + 3 + 3 * i + j] = od->v[j][ord[i]]; } } } } -void print_orires_log(FILE *log, t_oriresdata *od) +void print_orires_log(FILE* log, t_oriresdata* od) { - real *eig; + real* eig; diagonalize_orires_tensors(od); for (int ex = 0; ex < od->nex; ex++) { - eig = od->eig + ex*12; - fprintf(log, " Orientation experiment %d:\n", ex+1); + eig = od->eig + ex * 12; + fprintf(log, " Orientation experiment %d:\n", ex + 1); fprintf(log, " order parameter: %g\n", eig[0]); for (int i = 0; i < DIM; i++) { - fprintf(log, " eig: %6.3f %6.3f %6.3f %6.3f\n", - (eig[0] != 0) ? eig[i]/eig[0] : eig[i], - eig[DIM+i*DIM+XX], - eig[DIM+i*DIM+YY], - eig[DIM+i*DIM+ZZ]); + fprintf(log, " eig: %6.3f %6.3f %6.3f %6.3f\n", (eig[0] != 0) ? eig[i] / eig[0] : eig[i], + eig[DIM + i * DIM + XX], eig[DIM + i * DIM + YY], eig[DIM + i * DIM + ZZ]); } fprintf(log, "\n"); } } -real calc_orires_dev(const gmx_multisim_t *ms, - int nfa, const t_iatom forceatoms[], const t_iparams ip[], - const t_mdatoms *md, const rvec x[], const t_pbc *pbc, - t_fcdata *fcd, history_t *hist) +real calc_orires_dev(const gmx_multisim_t* ms, + int nfa, + const t_iatom forceatoms[], + const t_iparams ip[], + const t_mdatoms* md, + const rvec x[], + const t_pbc* pbc, + t_fcdata* fcd, + history_t* hist) { - int nref; - real edt, edt_1, invn, pfac, r2, invr, corrfac, wsv2, sw, dev; - OriresMatEq *matEq; - real *mref; - double mtot; - rvec *xref, *xtmp, com, r_unrot, r; - t_oriresdata *od; - gmx_bool bTAV; - const real two_thr = 2.0/3.0; + int nref; + real edt, edt_1, invn, pfac, r2, invr, corrfac, wsv2, sw, dev; + OriresMatEq* matEq; + real* mref; + double mtot; + rvec * xref, *xtmp, com, r_unrot, r; + t_oriresdata* od; + gmx_bool bTAV; + const real two_thr = 2.0 / 3.0; od = &(fcd->orires); if (od->nr == 0) { /* This means that this is not the master node */ - gmx_fatal(FARGS, "Orientation restraints are only supported on the master rank, use fewer ranks"); + gmx_fatal(FARGS, + "Orientation restraints are only supported on the master rank, use fewer ranks"); } bTAV = (od->edt != 0); @@ -405,12 +415,12 @@ real calc_orires_dev(const gmx_multisim_t *ms, if (bTAV) { - od->exp_min_t_tau = hist->orire_initf*edt; + od->exp_min_t_tau = hist->orire_initf * edt; /* Correction factor to correct for the lack of history * at short times. */ - corrfac = 1.0/(1.0 - od->exp_min_t_tau); + corrfac = 1.0 / (1.0 - od->exp_min_t_tau); } else { @@ -419,7 +429,7 @@ real calc_orires_dev(const gmx_multisim_t *ms, if (ms) { - invn = 1.0/ms->nsim; + invn = 1.0 / ms->nsim; } else { @@ -437,13 +447,13 @@ real calc_orires_dev(const gmx_multisim_t *ms, mref[j] = md->massT[i]; for (int d = 0; d < DIM; d++) { - com[d] += mref[j]*xtmp[j][d]; + com[d] += mref[j] * xtmp[j][d]; } mtot += mref[j]; j++; } } - svmul(1.0/mtot, com, com); + svmul(1.0 / mtot, com, com); for (int j = 0; j < nref; j++) { rvec_dec(xtmp[j], com); @@ -457,40 +467,40 @@ real calc_orires_dev(const gmx_multisim_t *ms, const int restraintIndex = type - od->typeMin; if (pbc) { - pbc_dx_aiuc(pbc, x[forceatoms[fa+1]], x[forceatoms[fa+2]], r_unrot); + pbc_dx_aiuc(pbc, x[forceatoms[fa + 1]], x[forceatoms[fa + 2]], r_unrot); } else { - rvec_sub(x[forceatoms[fa+1]], x[forceatoms[fa+2]], r_unrot); + rvec_sub(x[forceatoms[fa + 1]], x[forceatoms[fa + 2]], r_unrot); } mvmul(od->R, r_unrot, r); r2 = norm2(r); invr = gmx::invsqrt(r2); /* Calculate the prefactor for the D tensor, this includes the factor 3! */ - pfac = ip[type].orires.c*invr*invr*3; + pfac = ip[type].orires.c * invr * invr * 3; for (int i = 0; i < ip[type].orires.power; i++) { pfac *= invr; } - rvec5 &Dinsl = od->Dinsl[restraintIndex]; - Dinsl[0] = pfac*(2*r[0]*r[0] + r[1]*r[1] - r2); - Dinsl[1] = pfac*(2*r[0]*r[1]); - Dinsl[2] = pfac*(2*r[0]*r[2]); - Dinsl[3] = pfac*(2*r[1]*r[1] + r[0]*r[0] - r2); - Dinsl[4] = pfac*(2*r[1]*r[2]); + rvec5& Dinsl = od->Dinsl[restraintIndex]; + Dinsl[0] = pfac * (2 * r[0] * r[0] + r[1] * r[1] - r2); + Dinsl[1] = pfac * (2 * r[0] * r[1]); + Dinsl[2] = pfac * (2 * r[0] * r[2]); + Dinsl[3] = pfac * (2 * r[1] * r[1] + r[0] * r[0] - r2); + Dinsl[4] = pfac * (2 * r[1] * r[2]); if (ms) { for (int i = 0; i < 5; i++) { - od->Dins[restraintIndex][i] = Dinsl[i]*invn; + od->Dins[restraintIndex][i] = Dinsl[i] * invn; } } } if (ms) { - gmx_sum_sim(5*od->nr, od->Dins[0], ms); + gmx_sum_sim(5 * od->nr, od->Dins[0], ms); } /* Calculate the order tensor S for each experiment via optimization */ @@ -508,9 +518,9 @@ real calc_orires_dev(const gmx_multisim_t *ms, for (int fa = 0; fa < nfa; fa += 3) { - const int type = forceatoms[fa]; - const int restraintIndex = type - od->typeMin; - rvec5 &Dtav = od->Dtav[restraintIndex]; + const int type = forceatoms[fa]; + const int restraintIndex = type - od->typeMin; + rvec5& Dtav = od->Dtav[restraintIndex]; if (bTAV) { /* Here we update Dtav in t_fcdata using the data in history_t. @@ -519,9 +529,8 @@ real calc_orires_dev(const gmx_multisim_t *ms, */ for (int i = 0; i < 5; i++) { - Dtav[i] = - edt*hist->orire_Dtav[restraintIndex*5 + i] + - edt_1*od->Dins[restraintIndex][i]; + Dtav[i] = edt * hist->orire_Dtav[restraintIndex * 5 + i] + + edt_1 * od->Dins[restraintIndex][i]; } } @@ -530,43 +539,43 @@ real calc_orires_dev(const gmx_multisim_t *ms, /* Calculate the vector rhs and half the matrix T for the 5 equations */ for (int i = 0; i < 5; i++) { - matEq[ex].rhs[i] += Dtav[i]*ip[type].orires.obs*weight; + matEq[ex].rhs[i] += Dtav[i] * ip[type].orires.obs * weight; for (int j = 0; j <= i; j++) { - matEq[ex].mat[i][j] += Dtav[i]*Dtav[j]*weight; + matEq[ex].mat[i][j] += Dtav[i] * Dtav[j] * weight; } } } /* Now we have all the data we can calculate S */ for (int ex = 0; ex < od->nex; ex++) { - OriresMatEq &eq = matEq[ex]; + OriresMatEq& eq = matEq[ex]; /* Correct corrfac and copy one half of T to the other half */ for (int i = 0; i < 5; i++) { - eq.rhs[i] *= corrfac; + eq.rhs[i] *= corrfac; eq.mat[i][i] *= gmx::square(corrfac); for (int j = 0; j < i; j++) { eq.mat[i][j] *= gmx::square(corrfac); - eq.mat[j][i] = eq.mat[i][j]; + eq.mat[j][i] = eq.mat[i][j]; } } m_inv_gen(&eq.mat[0][0], 5, &eq.mat[0][0]); /* Calculate the orientation tensor S for this experiment */ - matrix &S = od->S[ex]; - S[0][0] = 0; - S[0][1] = 0; - S[0][2] = 0; - S[1][1] = 0; - S[1][2] = 0; + matrix& S = od->S[ex]; + S[0][0] = 0; + S[0][1] = 0; + S[0][2] = 0; + S[1][1] = 0; + S[1][2] = 0; for (int i = 0; i < 5; i++) { - S[0][0] += 1.5*eq.mat[0][i]*eq.rhs[i]; - S[0][1] += 1.5*eq.mat[1][i]*eq.rhs[i]; - S[0][2] += 1.5*eq.mat[2][i]*eq.rhs[i]; - S[1][1] += 1.5*eq.mat[3][i]*eq.rhs[i]; - S[1][2] += 1.5*eq.mat[4][i]*eq.rhs[i]; + S[0][0] += 1.5 * eq.mat[0][i] * eq.rhs[i]; + S[0][1] += 1.5 * eq.mat[1][i] * eq.rhs[i]; + S[0][2] += 1.5 * eq.mat[2][i] * eq.rhs[i]; + S[1][1] += 1.5 * eq.mat[3][i] * eq.rhs[i]; + S[1][2] += 1.5 * eq.mat[4][i] * eq.rhs[i]; } S[1][0] = S[0][1]; S[2][0] = S[0][2]; @@ -574,48 +583,48 @@ real calc_orires_dev(const gmx_multisim_t *ms, S[2][2] = -S[0][0] - S[1][1]; } - const matrix *S = od->S; + const matrix* S = od->S; - wsv2 = 0; - sw = 0; + wsv2 = 0; + sw = 0; for (int fa = 0; fa < nfa; fa += 3) { - const int type = forceatoms[fa]; - const int restraintIndex = type - od->typeMin; - const int ex = ip[type].orires.ex; + const int type = forceatoms[fa]; + const int restraintIndex = type - od->typeMin; + const int ex = ip[type].orires.ex; - const rvec5 &Dtav = od->Dtav[restraintIndex]; - od->otav[restraintIndex] = two_thr* - corrfac*(S[ex][0][0]*Dtav[0] + S[ex][0][1]*Dtav[1] + - S[ex][0][2]*Dtav[2] + S[ex][1][1]*Dtav[3] + - S[ex][1][2]*Dtav[4]); + const rvec5& Dtav = od->Dtav[restraintIndex]; + od->otav[restraintIndex] = + two_thr * corrfac + * (S[ex][0][0] * Dtav[0] + S[ex][0][1] * Dtav[1] + S[ex][0][2] * Dtav[2] + + S[ex][1][1] * Dtav[3] + S[ex][1][2] * Dtav[4]); if (bTAV) { - const rvec5 &Dins = od->Dins[restraintIndex]; - od->oins[restraintIndex] = two_thr* - (S[ex][0][0]*Dins[0] + S[ex][0][1]*Dins[1] + - S[ex][0][2]*Dins[2] + S[ex][1][1]*Dins[3] + - S[ex][1][2]*Dins[4]); + const rvec5& Dins = od->Dins[restraintIndex]; + od->oins[restraintIndex] = + two_thr + * (S[ex][0][0] * Dins[0] + S[ex][0][1] * Dins[1] + S[ex][0][2] * Dins[2] + + S[ex][1][1] * Dins[3] + S[ex][1][2] * Dins[4]); } if (ms) { /* When ensemble averaging is used recalculate the local orientation * for output to the energy file. */ - const rvec5 &Dinsl = od->Dinsl[restraintIndex]; - od->oinsl[restraintIndex] = two_thr* - (S[ex][0][0]*Dinsl[0] + S[ex][0][1]*Dinsl[1] + - S[ex][0][2]*Dinsl[2] + S[ex][1][1]*Dinsl[3] + - S[ex][1][2]*Dinsl[4]); + const rvec5& Dinsl = od->Dinsl[restraintIndex]; + od->oinsl[restraintIndex] = + two_thr + * (S[ex][0][0] * Dinsl[0] + S[ex][0][1] * Dinsl[1] + S[ex][0][2] * Dinsl[2] + + S[ex][1][1] * Dinsl[3] + S[ex][1][2] * Dinsl[4]); } dev = od->otav[restraintIndex] - ip[type].orires.obs; - wsv2 += ip[type].orires.kfac*gmx::square(dev); - sw += ip[type].orires.kfac; + wsv2 += ip[type].orires.kfac * gmx::square(dev); + sw += ip[type].orires.kfac; } - od->rmsdev = std::sqrt(wsv2/sw); + od->rmsdev = std::sqrt(wsv2 / sw); /* Rotate the S matrices back, so we get the correct grad(tr(S D)) */ for (int ex = 0; ex < od->nex; ex++) @@ -630,19 +639,26 @@ real calc_orires_dev(const gmx_multisim_t *ms, /* Approx. 120*nfa/3 flops */ } -real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real gmx_unused lambda, real gmx_unused *dvdlambda, - const t_mdatoms gmx_unused *md, t_fcdata *fcd, - int gmx_unused *global_atom_index) +real orires(int nfa, + const t_iatom forceatoms[], + const t_iparams ip[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real gmx_unused lambda, + real gmx_unused* dvdlambda, + const t_mdatoms gmx_unused* md, + t_fcdata* fcd, + int gmx_unused* global_atom_index) { int ex, power, ki = CENTRAL; ivec dt; real r2, invr, invr2, fc, smooth_fc, dev, devins, pfac; rvec r, Sr, fij; real vtot; - const t_oriresdata *od; + const t_oriresdata* od; gmx_bool bTAV; vtot = 0; @@ -675,28 +691,28 @@ real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], } r2 = norm2(r); invr = gmx::invsqrt(r2); - invr2 = invr*invr; + invr2 = invr * invr; ex = ip[type].orires.ex; power = ip[type].orires.power; - fc = smooth_fc*ip[type].orires.kfac; + fc = smooth_fc * ip[type].orires.kfac; dev = od->otav[restraintIndex] - ip[type].orires.obs; /* NOTE: * there is no real potential when time averaging is applied */ - vtot += 0.5*fc*gmx::square(dev); + vtot += 0.5 * fc * gmx::square(dev); if (bTAV) { /* Calculate the force as the sqrt of tav times instantaneous */ devins = od->oins[restraintIndex] - ip[type].orires.obs; - if (dev*devins <= 0) + if (dev * devins <= 0) { dev = 0; } else { - dev = std::sqrt(dev*devins); + dev = std::sqrt(dev * devins); if (devins < 0) { dev = -dev; @@ -704,7 +720,7 @@ real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], } } - pfac = fc*ip[type].orires.c*invr2; + pfac = fc * ip[type].orires.c * invr2; for (int i = 0; i < power; i++) { pfac *= invr; @@ -712,8 +728,7 @@ real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], mvmul(od->S[ex], r, Sr); for (int i = 0; i < DIM; i++) { - fij[i] = - -pfac*dev*(4*Sr[i] - 2*(2+power)*invr2*iprod(Sr, r)*r[i]); + fij[i] = -pfac * dev * (4 * Sr[i] - 2 * (2 + power) * invr2 * iprod(Sr, r) * r[i]); } if (g) @@ -724,11 +739,11 @@ real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], for (int i = 0; i < DIM; i++) { - f[ai][i] += fij[i]; - f[aj][i] -= fij[i]; + f[ai][i] += fij[i]; + f[aj][i] -= fij[i]; if (fshift) { - fshift[ki][i] += fij[i]; + fshift[ki][i] += fij[i]; fshift[CENTRAL][i] -= fij[i]; } } @@ -740,9 +755,9 @@ real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], /* Approx. 80*nfa/3 flops */ } -void update_orires_history(const t_fcdata *fcd, history_t *hist) +void update_orires_history(const t_fcdata* fcd, history_t* hist) { - const t_oriresdata *od = &(fcd->orires); + const t_oriresdata* od = &(fcd->orires); if (od->edt != 0) { @@ -754,7 +769,7 @@ void update_orires_history(const t_fcdata *fcd, history_t *hist) { for (int i = 0; i < 5; i++) { - hist->orire_Dtav[pair*5+i] = od->Dtav[pair][i]; + hist->orire_Dtav[pair * 5 + i] = od->Dtav[pair][i]; } } } diff --git a/src/gromacs/listed_forces/orires.h b/src/gromacs/listed_forces/orires.h index 83e8b13e25..96cf3c53bd 100644 --- a/src/gromacs/listed_forces/orires.h +++ b/src/gromacs/listed_forces/orires.h @@ -66,23 +66,28 @@ class t_state; * on the master rank (which is the only rank, since orientation * restraints can not run in parallel). */ -void init_orires(FILE *fplog, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_state *globalState, - t_oriresdata *od); +void init_orires(FILE* fplog, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_state* globalState, + t_oriresdata* od); /*! \brief * Calculates the time averaged D matrices, the S matrix for each experiment. * * Returns the weighted RMS deviation of the orientation restraints. */ -real calc_orires_dev(const gmx_multisim_t *ms, - int nfa, const t_iatom fa[], const t_iparams ip[], - const t_mdatoms *md, const rvec x[], - const t_pbc *pbc, t_fcdata *fcd, history_t *hist); +real calc_orires_dev(const gmx_multisim_t* ms, + int nfa, + const t_iatom fa[], + const t_iparams ip[], + const t_mdatoms* md, + const rvec x[], + const t_pbc* pbc, + t_fcdata* fcd, + history_t* hist); /*! \brief * Diagonalizes the order tensor(s) of the orienation restraints. @@ -90,20 +95,27 @@ real calc_orires_dev(const gmx_multisim_t *ms, * For each experiment eig containts first 3 eigenvalues and then * the 3 eigenvectors. The eigenvalues are ordered on magnitude. */ -void diagonalize_orires_tensors(t_oriresdata *od); +void diagonalize_orires_tensors(t_oriresdata* od); //! Prints order parameter, eigenvalues and eigenvectors to the log file. -void print_orires_log(FILE *log, t_oriresdata *od); +void print_orires_log(FILE* log, t_oriresdata* od); //! Calculates the orientation restraint forces. -real orires(int nfa, const t_iatom forceatoms[], const t_iparams ip[], - const rvec x[], rvec4 f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g, - real lambda, real *dvdlambda, - const t_mdatoms *md, t_fcdata *fcd, - int *global_atom_index); +real orires(int nfa, + const t_iatom forceatoms[], + const t_iparams ip[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g, + real lambda, + real* dvdlambda, + const t_mdatoms* md, + t_fcdata* fcd, + int* global_atom_index); //! Copies the new time averages that have been calculated in calc_orires_dev. -void update_orires_history(const t_fcdata *fcd, history_t *hist); +void update_orires_history(const t_fcdata* fcd, history_t* hist); #endif diff --git a/src/gromacs/listed_forces/pairs.cpp b/src/gromacs/listed_forces/pairs.cpp index cede2598d1..d56a6aa546 100644 --- a/src/gromacs/listed_forces/pairs.cpp +++ b/src/gromacs/listed_forces/pairs.cpp @@ -71,89 +71,114 @@ using namespace gmx; // TODO: Remove when this file is moved into gmx namespace /*! \brief Issue a warning if a listed interaction is beyond a table limit */ -static void -warning_rlimit(const rvec *x, int ai, int aj, int * global_atom_index, real r, real rlimit) +static void warning_rlimit(const rvec* x, int ai, int aj, int* global_atom_index, real r, real rlimit) { - gmx_warning("Listed nonbonded interaction between particles %d and %d\n" - "at distance %.3f which is larger than the table limit %.3f nm.\n\n" - "This is likely either a 1,4 interaction, or a listed interaction inside\n" - "a smaller molecule you are decoupling during a free energy calculation.\n" - "Since interactions at distances beyond the table cannot be computed,\n" - "they are skipped until they are inside the table limit again. You will\n" - "only see this message once, even if it occurs for several interactions.\n\n" - "IMPORTANT: This should not happen in a stable simulation, so there is\n" - "probably something wrong with your system. Only change the table-extension\n" - "distance in the mdp file if you are really sure that is the reason.\n", - glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r, rlimit); + gmx_warning( + "Listed nonbonded interaction between particles %d and %d\n" + "at distance %.3f which is larger than the table limit %.3f nm.\n\n" + "This is likely either a 1,4 interaction, or a listed interaction inside\n" + "a smaller molecule you are decoupling during a free energy calculation.\n" + "Since interactions at distances beyond the table cannot be computed,\n" + "they are skipped until they are inside the table limit again. You will\n" + "only see this message once, even if it occurs for several interactions.\n\n" + "IMPORTANT: This should not happen in a stable simulation, so there is\n" + "probably something wrong with your system. Only change the table-extension\n" + "distance in the mdp file if you are really sure that is the reason.\n", + glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r, rlimit); if (debug) { fprintf(debug, - "%8f %8f %8f\n%8f %8f %8f\n1-4 (%d,%d) interaction not within cut-off! r=%g. Ignored\n", + "%8f %8f %8f\n%8f %8f %8f\n1-4 (%d,%d) interaction not within cut-off! r=%g. " + "Ignored\n", x[ai][XX], x[ai][YY], x[ai][ZZ], x[aj][XX], x[aj][YY], x[aj][ZZ], glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r); } } /*! \brief Compute the energy and force for a single pair interaction */ -static real -evaluate_single(real r2, real tabscale, const real *vftab, real tableStride, - real qq, real c6, real c12, real *velec, real *vvdw) +static real evaluate_single(real r2, + real tabscale, + const real* vftab, + real tableStride, + real qq, + real c6, + real c12, + real* velec, + real* vvdw) { - real rinv, r, rtab, eps, eps2, Y, F, Geps, Heps2, Fp, VVe, FFe, VVd, FFd, VVr, FFr, fscal; - int ntab; + real rinv, r, rtab, eps, eps2, Y, F, Geps, Heps2, Fp, VVe, FFe, VVd, FFd, VVr, FFr, fscal; + int ntab; /* Do the tabulated interactions - first table lookup */ - rinv = gmx::invsqrt(r2); - r = r2*rinv; - rtab = r*tabscale; - ntab = static_cast(rtab); - eps = rtab-ntab; - eps2 = eps*eps; - ntab = static_cast(tableStride*ntab); + rinv = gmx::invsqrt(r2); + r = r2 * rinv; + rtab = r * tabscale; + ntab = static_cast(rtab); + eps = rtab - ntab; + eps2 = eps * eps; + ntab = static_cast(tableStride * ntab); /* Electrostatics */ - Y = vftab[ntab]; - F = vftab[ntab+1]; - Geps = eps*vftab[ntab+2]; - Heps2 = eps2*vftab[ntab+3]; - Fp = F+Geps+Heps2; - VVe = Y+eps*Fp; - FFe = Fp+Geps+2.0*Heps2; + Y = vftab[ntab]; + F = vftab[ntab + 1]; + Geps = eps * vftab[ntab + 2]; + Heps2 = eps2 * vftab[ntab + 3]; + Fp = F + Geps + Heps2; + VVe = Y + eps * Fp; + FFe = Fp + Geps + 2.0 * Heps2; /* Dispersion */ - Y = vftab[ntab+4]; - F = vftab[ntab+5]; - Geps = eps*vftab[ntab+6]; - Heps2 = eps2*vftab[ntab+7]; - Fp = F+Geps+Heps2; - VVd = Y+eps*Fp; - FFd = Fp+Geps+2.0*Heps2; + Y = vftab[ntab + 4]; + F = vftab[ntab + 5]; + Geps = eps * vftab[ntab + 6]; + Heps2 = eps2 * vftab[ntab + 7]; + Fp = F + Geps + Heps2; + VVd = Y + eps * Fp; + FFd = Fp + Geps + 2.0 * Heps2; /* Repulsion */ - Y = vftab[ntab+8]; - F = vftab[ntab+9]; - Geps = eps*vftab[ntab+10]; - Heps2 = eps2*vftab[ntab+11]; - Fp = F+Geps+Heps2; - VVr = Y+eps*Fp; - FFr = Fp+Geps+2.0*Heps2; + Y = vftab[ntab + 8]; + F = vftab[ntab + 9]; + Geps = eps * vftab[ntab + 10]; + Heps2 = eps2 * vftab[ntab + 11]; + Fp = F + Geps + Heps2; + VVr = Y + eps * Fp; + FFr = Fp + Geps + 2.0 * Heps2; - *velec = qq*VVe; - *vvdw = c6*VVd+c12*VVr; + *velec = qq * VVe; + *vvdw = c6 * VVd + c12 * VVr; - fscal = -(qq*FFe+c6*FFd+c12*FFr)*tabscale*rinv; + fscal = -(qq * FFe + c6 * FFd + c12 * FFr) * tabscale * rinv; return fscal; } /*! \brief Compute the energy and force for a single pair interaction under FEP */ -static real -free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, - real alpha_vdw, real tabscale, const real *vftab, real tableStride, - real qqA, real c6A, real c12A, real qqB, - real c6B, real c12B, const real LFC[2], const real LFV[2], const real DLF[2], - const real lfac_coul[2], const real lfac_vdw[2], const real dlfac_coul[2], - const real dlfac_vdw[2], real sigma6_def, real sigma6_min, - real sigma2_def, real sigma2_min, - real *velectot, real *vvdwtot, real *dvdl) +static real free_energy_evaluate_single(real r2, + real sc_r_power, + real alpha_coul, + real alpha_vdw, + real tabscale, + const real* vftab, + real tableStride, + real qqA, + real c6A, + real c12A, + real qqB, + real c6B, + real c12B, + const real LFC[2], + const real LFV[2], + const real DLF[2], + const real lfac_coul[2], + const real lfac_vdw[2], + const real dlfac_coul[2], + const real dlfac_vdw[2], + real sigma6_def, + real sigma6_min, + real sigma2_def, + real sigma2_min, + real* velectot, + real* vvdwtot, + real* dvdl) { real rp, rpm2, rtab, eps, eps2, Y, F, Geps, Heps2, Fp, VV, FF, fscal; real qq[2], c6[2], c12[2], sigma6[2], sigma2[2], sigma_pow[2]; @@ -169,30 +194,30 @@ free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, const real six = 6.0; const real fourtyeight = 48.0; - qq[0] = qqA; - qq[1] = qqB; - c6[0] = c6A; - c6[1] = c6B; - c12[0] = c12A; - c12[1] = c12B; + qq[0] = qqA; + qq[1] = qqB; + c6[0] = c6A; + c6[1] = c6B; + c12[0] = c12A; + c12[1] = c12B; if (sc_r_power == six) { - rpm2 = r2*r2; /* r4 */ - rp = rpm2*r2; /* r6 */ + rpm2 = r2 * r2; /* r4 */ + rp = rpm2 * r2; /* r6 */ } else if (sc_r_power == fourtyeight) { - rp = r2*r2*r2; /* r6 */ - rp = rp*rp; /* r12 */ - rp = rp*rp; /* r24 */ - rp = rp*rp; /* r48 */ - rpm2 = rp/r2; /* r46 */ + rp = r2 * r2 * r2; /* r6 */ + rp = rp * rp; /* r12 */ + rp = rp * rp; /* r24 */ + rp = rp * rp; /* r48 */ + rpm2 = rp / r2; /* r46 */ } else { - rp = std::pow(r2, half * sc_r_power); /* not currently supported as input, but can handle it */ - rpm2 = rp/r2; + rp = std::pow(r2, half * sc_r_power); /* not currently supported as input, but can handle it */ + rpm2 = rp / r2; } /* Loop over state A(0) and B(1) */ @@ -203,11 +228,11 @@ free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, /* The c6 & c12 coefficients now contain the constants 6.0 and 12.0, respectively. * Correct for this by multiplying with (1/12.0)/(1/6.0)=6.0/12.0=0.5. */ - sigma6[i] = half*c12[i]/c6[i]; - sigma2[i] = std::cbrt(half*c12[i]/c6[i]); + sigma6[i] = half * c12[i] / c6[i]; + sigma2[i] = std::cbrt(half * c12[i] / c6[i]); /* should be able to get rid of this ^^^ internal pow call eventually. Will require agreement on what data to store externally. Can't be fixed without larger scale changes, so not 5.0 */ - if (sigma6[i] < sigma6_min) /* for disappearing coul and vdw with soft core at the same time */ + if (sigma6[i] < sigma6_min) /* for disappearing coul and vdw with soft core at the same time */ { sigma6[i] = sigma6_min; sigma2[i] = sigma2_min; @@ -215,35 +240,35 @@ free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, } else { - sigma6[i] = sigma6_def; - sigma2[i] = sigma2_def; + sigma6[i] = sigma6_def; + sigma2[i] = sigma2_def; } if (sc_r_power == six) { - sigma_pow[i] = sigma6[i]; + sigma_pow[i] = sigma6[i]; } else if (sc_r_power == fourtyeight) { - sigma_pow[i] = sigma6[i]*sigma6[i]; /* sigma^12 */ - sigma_pow[i] = sigma_pow[i]*sigma_pow[i]; /* sigma^24 */ - sigma_pow[i] = sigma_pow[i]*sigma_pow[i]; /* sigma^48 */ + sigma_pow[i] = sigma6[i] * sigma6[i]; /* sigma^12 */ + sigma_pow[i] = sigma_pow[i] * sigma_pow[i]; /* sigma^24 */ + sigma_pow[i] = sigma_pow[i] * sigma_pow[i]; /* sigma^48 */ } else - { /* not really supported as input, but in here for testing the general case*/ - sigma_pow[i] = std::pow(sigma2[i], sc_r_power/2); + { /* not really supported as input, but in here for testing the general case*/ + sigma_pow[i] = std::pow(sigma2[i], sc_r_power / 2); } } /* only use softcore if one of the states has a zero endstate - softcore is for avoiding infinities!*/ if ((c12[0] > 0) && (c12[1] > 0)) { - alpha_vdw_eff = 0; - alpha_coul_eff = 0; + alpha_vdw_eff = 0; + alpha_coul_eff = 0; } else { - alpha_vdw_eff = alpha_vdw; - alpha_coul_eff = alpha_coul; + alpha_vdw_eff = alpha_vdw; + alpha_coul_eff = alpha_coul; } /* Loop over A and B states again */ @@ -255,60 +280,60 @@ free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, vvdw[i] = 0; /* Only spend time on A or B state if it is non-zero */ - if ( (qq[i] != 0) || (c6[i] != 0) || (c12[i] != 0) ) + if ((qq[i] != 0) || (c6[i] != 0) || (c12[i] != 0)) { /* Coulomb */ - rpinv = one/(alpha_coul_eff*lfac_coul[i]*sigma_pow[i]+rp); - r_coul = std::pow(rpinv, minusOne / sc_r_power); + rpinv = one / (alpha_coul_eff * lfac_coul[i] * sigma_pow[i] + rp); + r_coul = std::pow(rpinv, minusOne / sc_r_power); /* Electrostatics table lookup data */ - rtab = r_coul*tabscale; - ntab = static_cast(rtab); - eps = rtab-ntab; - eps2 = eps*eps; - ntab = static_cast(tableStride*ntab); + rtab = r_coul * tabscale; + ntab = static_cast(rtab); + eps = rtab - ntab; + eps2 = eps * eps; + ntab = static_cast(tableStride * ntab); /* Electrostatics */ - Y = vftab[ntab]; - F = vftab[ntab+1]; - Geps = eps*vftab[ntab+2]; - Heps2 = eps2*vftab[ntab+3]; - Fp = F+Geps+Heps2; - VV = Y+eps*Fp; - FF = Fp+Geps+two*Heps2; - velec[i] = qq[i]*VV; - fscal_elec[i] = -qq[i]*FF*r_coul*rpinv*tabscale; + Y = vftab[ntab]; + F = vftab[ntab + 1]; + Geps = eps * vftab[ntab + 2]; + Heps2 = eps2 * vftab[ntab + 3]; + Fp = F + Geps + Heps2; + VV = Y + eps * Fp; + FF = Fp + Geps + two * Heps2; + velec[i] = qq[i] * VV; + fscal_elec[i] = -qq[i] * FF * r_coul * rpinv * tabscale; /* Vdw */ - rpinv = one/(alpha_vdw_eff*lfac_vdw[i]*sigma_pow[i]+rp); - r_vdw = std::pow(rpinv, minusOne / sc_r_power); + rpinv = one / (alpha_vdw_eff * lfac_vdw[i] * sigma_pow[i] + rp); + r_vdw = std::pow(rpinv, minusOne / sc_r_power); /* Vdw table lookup data */ - rtab = r_vdw*tabscale; - ntab = static_cast(rtab); - eps = rtab-ntab; - eps2 = eps*eps; - ntab = 12*ntab; + rtab = r_vdw * tabscale; + ntab = static_cast(rtab); + eps = rtab - ntab; + eps2 = eps * eps; + ntab = 12 * ntab; /* Dispersion */ - Y = vftab[ntab+4]; - F = vftab[ntab+5]; - Geps = eps*vftab[ntab+6]; - Heps2 = eps2*vftab[ntab+7]; - Fp = F+Geps+Heps2; - VV = Y+eps*Fp; - FF = Fp+Geps+two*Heps2; - vvdw[i] = c6[i]*VV; - fscal_vdw[i] = -c6[i]*FF; + Y = vftab[ntab + 4]; + F = vftab[ntab + 5]; + Geps = eps * vftab[ntab + 6]; + Heps2 = eps2 * vftab[ntab + 7]; + Fp = F + Geps + Heps2; + VV = Y + eps * Fp; + FF = Fp + Geps + two * Heps2; + vvdw[i] = c6[i] * VV; + fscal_vdw[i] = -c6[i] * FF; /* Repulsion */ - Y = vftab[ntab+8]; - F = vftab[ntab+9]; - Geps = eps*vftab[ntab+10]; - Heps2 = eps2*vftab[ntab+11]; - Fp = F+Geps+Heps2; - VV = Y+eps*Fp; - FF = Fp+Geps+two*Heps2; - vvdw[i] += c12[i]*VV; - fscal_vdw[i] -= c12[i]*FF; - fscal_vdw[i] *= r_vdw*rpinv*tabscale; + Y = vftab[ntab + 8]; + F = vftab[ntab + 9]; + Geps = eps * vftab[ntab + 10]; + Heps2 = eps2 * vftab[ntab + 11]; + Fp = F + Geps + Heps2; + VV = Y + eps * Fp; + FF = Fp + Geps + two * Heps2; + vvdw[i] += c12[i] * VV; + fscal_vdw[i] -= c12[i] * FF; + fscal_vdw[i] *= r_vdw * rpinv * tabscale; } } /* Now we have velec[i], vvdw[i], and fscal[i] for both states */ @@ -320,50 +345,58 @@ free_energy_evaluate_single(real r2, real sc_r_power, real alpha_coul, fscal = 0; for (i = 0; i < 2; i++) { - velecsum += LFC[i]*velec[i]; - vvdwsum += LFV[i]*vvdw[i]; + velecsum += LFC[i] * velec[i]; + vvdwsum += LFV[i] * vvdw[i]; - fscal += (LFC[i]*fscal_elec[i]+LFV[i]*fscal_vdw[i])*rpm2; + fscal += (LFC[i] * fscal_elec[i] + LFV[i] * fscal_vdw[i]) * rpm2; - dvdl_coul += velec[i]*DLF[i] + LFC[i]*alpha_coul_eff*dlfac_coul[i]*fscal_elec[i]*sigma_pow[i]; - dvdl_vdw += vvdw[i]*DLF[i] + LFV[i]*alpha_vdw_eff*dlfac_vdw[i]*fscal_vdw[i]*sigma_pow[i]; + dvdl_coul += velec[i] * DLF[i] + + LFC[i] * alpha_coul_eff * dlfac_coul[i] * fscal_elec[i] * sigma_pow[i]; + dvdl_vdw += vvdw[i] * DLF[i] + + LFV[i] * alpha_vdw_eff * dlfac_vdw[i] * fscal_vdw[i] * sigma_pow[i]; } - dvdl[efptCOUL] += dvdl_coul; - dvdl[efptVDW] += dvdl_vdw; + dvdl[efptCOUL] += dvdl_coul; + dvdl[efptVDW] += dvdl_vdw; - *velectot = velecsum; - *vvdwtot = vvdwsum; + *velectot = velecsum; + *vvdwtot = vvdwsum; return fscal; } /*! \brief Calculate pair interactions, supports all types and conditions. */ -template -static real -do_pairs_general(int ftype, int nbonds, - const t_iatom iatoms[], const t_iparams iparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - const real *lambda, real *dvdl, - const t_mdatoms *md, - const t_forcerec *fr, gmx_grppairener_t *grppener, - int *global_atom_index) +template +static real do_pairs_general(int ftype, + int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + const real* lambda, + real* dvdl, + const t_mdatoms* md, + const t_forcerec* fr, + gmx_grppairener_t* grppener, + int* global_atom_index) { - real qq, c6, c12; - rvec dx; - ivec dt; - int i, itype, ai, aj, gid; - int fshift_index; - real r2; - real fscal, velec, vvdw; - real * energygrp_elec; - real * energygrp_vdw; - static gmx_bool warned_rlimit = FALSE; + real qq, c6, c12; + rvec dx; + ivec dt; + int i, itype, ai, aj, gid; + int fshift_index; + real r2; + real fscal, velec, vvdw; + real* energygrp_elec; + real* energygrp_vdw; + static gmx_bool warned_rlimit = FALSE; /* Free energy stuff */ - gmx_bool bFreeEnergy; - real LFC[2], LFV[2], DLF[2], lfac_coul[2], lfac_vdw[2], dlfac_coul[2], dlfac_vdw[2]; - real qqB, c6B, c12B, sigma2_def, sigma2_min; + gmx_bool bFreeEnergy; + real LFC[2], LFV[2], DLF[2], lfac_coul[2], lfac_vdw[2], dlfac_coul[2], dlfac_vdw[2]; + real qqB, c6B, c12B, sigma2_def, sigma2_min; switch (ftype) { @@ -400,10 +433,12 @@ do_pairs_general(int ftype, int nbonds, for (i = 0; i < 2; i++) { - lfac_coul[i] = (fr->sc_power == 2 ? (1-LFC[i])*(1-LFC[i]) : (1-LFC[i])); - dlfac_coul[i] = DLF[i]*fr->sc_power/fr->sc_r_power*(fr->sc_power == 2 ? (1-LFC[i]) : 1); - lfac_vdw[i] = (fr->sc_power == 2 ? (1-LFV[i])*(1-LFV[i]) : (1-LFV[i])); - dlfac_vdw[i] = DLF[i]*fr->sc_power/fr->sc_r_power*(fr->sc_power == 2 ? (1-LFV[i]) : 1); + lfac_coul[i] = (fr->sc_power == 2 ? (1 - LFC[i]) * (1 - LFC[i]) : (1 - LFC[i])); + dlfac_coul[i] = + DLF[i] * fr->sc_power / fr->sc_r_power * (fr->sc_power == 2 ? (1 - LFC[i]) : 1); + lfac_vdw[i] = (fr->sc_power == 2 ? (1 - LFV[i]) * (1 - LFV[i]) : (1 - LFV[i])); + dlfac_vdw[i] = + DLF[i] * fr->sc_power / fr->sc_r_power * (fr->sc_power == 2 ? (1 - LFV[i]) : 1); } } else @@ -414,14 +449,17 @@ do_pairs_general(int ftype, int nbonds, /* TODO This code depends on the logic in tables.c that constructs the table layout, which should be made explicit in future cleanup. */ - GMX_ASSERT(etiNR == 3, "Pair-interaction code that uses GROMACS interaction tables supports exactly 3 tables"); - GMX_ASSERT(fr->pairsTable->interaction == GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, - "Pair interaction kernels need a table with Coulomb, repulsion and dispersion entries"); + GMX_ASSERT( + etiNR == 3, + "Pair-interaction code that uses GROMACS interaction tables supports exactly 3 tables"); + GMX_ASSERT( + fr->pairsTable->interaction == GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, + "Pair interaction kernels need a table with Coulomb, repulsion and dispersion entries"); const real epsfac = fr->ic->epsfac; bFreeEnergy = FALSE; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { itype = iatoms[i++]; ai = iatoms[i++]; @@ -432,24 +470,24 @@ do_pairs_general(int ftype, int nbonds, switch (ftype) { case F_LJ14: - bFreeEnergy = - (fr->efep != efepNO && - (((md->nPerturbed != 0) && (md->bPerturbed[ai] || md->bPerturbed[aj])) || - iparams[itype].lj14.c6A != iparams[itype].lj14.c6B || - iparams[itype].lj14.c12A != iparams[itype].lj14.c12B)); - qq = md->chargeA[ai]*md->chargeA[aj]*epsfac*fr->fudgeQQ; - c6 = iparams[itype].lj14.c6A; - c12 = iparams[itype].lj14.c12A; + bFreeEnergy = (fr->efep != efepNO + && (((md->nPerturbed != 0) && (md->bPerturbed[ai] || md->bPerturbed[aj])) + || iparams[itype].lj14.c6A != iparams[itype].lj14.c6B + || iparams[itype].lj14.c12A != iparams[itype].lj14.c12B)); + qq = md->chargeA[ai] * md->chargeA[aj] * epsfac * fr->fudgeQQ; + c6 = iparams[itype].lj14.c6A; + c12 = iparams[itype].lj14.c12A; break; case F_LJC14_Q: - qq = iparams[itype].ljc14.qi*iparams[itype].ljc14.qj*epsfac*iparams[itype].ljc14.fqq; - c6 = iparams[itype].ljc14.c6; - c12 = iparams[itype].ljc14.c12; + qq = iparams[itype].ljc14.qi * iparams[itype].ljc14.qj * epsfac + * iparams[itype].ljc14.fqq; + c6 = iparams[itype].ljc14.c6; + c12 = iparams[itype].ljc14.c12; break; case F_LJC_PAIRS_NB: - qq = iparams[itype].ljcnb.qi*iparams[itype].ljcnb.qj*epsfac; - c6 = iparams[itype].ljcnb.c6; - c12 = iparams[itype].ljcnb.c12; + qq = iparams[itype].ljcnb.qi * iparams[itype].ljcnb.qj * epsfac; + c6 = iparams[itype].ljcnb.c6; + c12 = iparams[itype].ljcnb.c12; break; default: /* Cannot happen since we called gmx_fatal() above in this case */ @@ -462,7 +500,7 @@ do_pairs_general(int ftype, int nbonds, * same factor, so when we use the original c6/c12 parameters from iparams[] they must * be scaled up. */ - c6 *= 6.0; + c6 *= 6.0; c12 *= 12.0; /* Do we need to apply full periodic boundary conditions? */ @@ -475,9 +513,9 @@ do_pairs_general(int ftype, int nbonds, fshift_index = CENTRAL; rvec_sub(x[ai], x[aj], dx); } - r2 = norm2(dx); + r2 = norm2(dx); - if (r2 >= fr->pairsTable->r*fr->pairsTable->r) + if (r2 >= fr->pairsTable->r * fr->pairsTable->r) { /* This check isn't race free. But it doesn't matter because if a race occurs the only * disadvantage is that the warning is printed twice */ @@ -492,25 +530,25 @@ do_pairs_general(int ftype, int nbonds, if (bFreeEnergy) { /* Currently free energy is only supported for F_LJ14, so no need to check for that if we got here */ - qqB = md->chargeB[ai]*md->chargeB[aj]*epsfac*fr->fudgeQQ; - c6B = iparams[itype].lj14.c6B*6.0; - c12B = iparams[itype].lj14.c12B*12.0; - - fscal = free_energy_evaluate_single(r2, fr->sc_r_power, fr->sc_alphacoul, fr->sc_alphavdw, - fr->pairsTable->scale, fr->pairsTable->data, fr->pairsTable->stride, - qq, c6, c12, qqB, c6B, c12B, - LFC, LFV, DLF, lfac_coul, lfac_vdw, dlfac_coul, dlfac_vdw, - fr->sc_sigma6_def, fr->sc_sigma6_min, sigma2_def, sigma2_min, &velec, &vvdw, dvdl); + qqB = md->chargeB[ai] * md->chargeB[aj] * epsfac * fr->fudgeQQ; + c6B = iparams[itype].lj14.c6B * 6.0; + c12B = iparams[itype].lj14.c12B * 12.0; + + fscal = free_energy_evaluate_single( + r2, fr->sc_r_power, fr->sc_alphacoul, fr->sc_alphavdw, fr->pairsTable->scale, + fr->pairsTable->data, fr->pairsTable->stride, qq, c6, c12, qqB, c6B, c12B, LFC, + LFV, DLF, lfac_coul, lfac_vdw, dlfac_coul, dlfac_vdw, fr->sc_sigma6_def, + fr->sc_sigma6_min, sigma2_def, sigma2_min, &velec, &vvdw, dvdl); } else { /* Evaluate tabulated interaction without free energy */ - fscal = evaluate_single(r2, fr->pairsTable->scale, fr->pairsTable->data, fr->pairsTable->stride, - qq, c6, c12, &velec, &vvdw); + fscal = evaluate_single(r2, fr->pairsTable->scale, fr->pairsTable->data, + fr->pairsTable->stride, qq, c6, c12, &velec, &vvdw); } - energygrp_elec[gid] += velec; - energygrp_vdw[gid] += vvdw; + energygrp_elec[gid] += velec; + energygrp_vdw[gid] += vvdw; svmul(fscal, dx, dx); /* Add the forces */ @@ -539,34 +577,34 @@ do_pairs_general(int ftype, int nbonds, * * This function is templated for real/SimdReal and for optimization. */ -template -static void -do_pairs_simple(int nbonds, - const t_iatom iatoms[], const t_iparams iparams[], - const rvec x[], rvec4 f[], - const pbc_type pbc, - const t_mdatoms *md, - const real scale_factor) +template +static void do_pairs_simple(int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + const pbc_type pbc, + const t_mdatoms* md, + const real scale_factor) { const int nfa1 = 1 + 2; - T six(6); - T twelve(12); - T ef(scale_factor); + T six(6); + T twelve(12); + T ef(scale_factor); #if GMX_SIMD_HAVE_REAL - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[pack_size]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[pack_size]; - alignas(GMX_SIMD_ALIGNMENT) real coeff[3*pack_size]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ai[pack_size]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t aj[pack_size]; + alignas(GMX_SIMD_ALIGNMENT) real coeff[3 * pack_size]; #else - std::int32_t ai[pack_size]; - std::int32_t aj[pack_size]; - real coeff[3*pack_size]; + std::int32_t ai[pack_size]; + std::int32_t aj[pack_size]; + real coeff[3 * pack_size]; #endif /* nbonds is #pairs*nfa1, here we step pack_size pairs */ - for (int i = 0; i < nbonds; i += pack_size*nfa1) + for (int i = 0; i < nbonds; i += pack_size * nfa1) { /* Collect atoms for pack_size pairs. * iu indexes into iatoms, we should not let iu go beyond nbonds. @@ -578,11 +616,11 @@ do_pairs_simple(int nbonds, ai[s] = iatoms[iu + 1]; aj[s] = iatoms[iu + 2]; - if (i + s*nfa1 < nbonds) + if (i + s * nfa1 < nbonds) { - coeff[0*pack_size + s] = iparams[itype].lj14.c6A; - coeff[1*pack_size + s] = iparams[itype].lj14.c12A; - coeff[2*pack_size + s] = md->chargeA[ai[s]]*md->chargeA[aj[s]]; + coeff[0 * pack_size + s] = iparams[itype].lj14.c6A; + coeff[1 * pack_size + s] = iparams[itype].lj14.c12A; + coeff[2 * pack_size + s] = md->chargeA[ai[s]] * md->chargeA[aj[s]]; /* Avoid indexing the iatoms array out of bounds. * We pad the coordinate indices with the last atom pair. @@ -595,71 +633,74 @@ do_pairs_simple(int nbonds, else { /* Pad the coefficient arrays with zeros to get zero forces */ - coeff[0*pack_size + s] = 0; - coeff[1*pack_size + s] = 0; - coeff[2*pack_size + s] = 0; + coeff[0 * pack_size + s] = 0; + coeff[1 * pack_size + s] = 0; + coeff[2 * pack_size + s] = 0; } } /* Load the coordinates */ T xi[DIM], xj[DIM]; - gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi[XX], &xi[YY], &xi[ZZ]); - gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj[XX], &xj[YY], &xj[ZZ]); + gatherLoadUTranspose<3>(reinterpret_cast(x), ai, &xi[XX], &xi[YY], &xi[ZZ]); + gatherLoadUTranspose<3>(reinterpret_cast(x), aj, &xj[XX], &xj[YY], &xj[ZZ]); - T c6 = load(coeff + 0*pack_size); - T c12 = load(coeff + 1*pack_size); - T qq = load(coeff + 2*pack_size); + T c6 = load(coeff + 0 * pack_size); + T c12 = load(coeff + 1 * pack_size); + T qq = load(coeff + 2 * pack_size); /* We could save these operations by storing 6*C6,12*C12 */ - c6 = six*c6; - c12 = twelve*c12; + c6 = six * c6; + c12 = twelve * c12; T dr[DIM]; pbc_dx_aiuc(pbc, xi, xj, dr); - T rsq = dr[XX]*dr[XX] + dr[YY]*dr[YY] + dr[ZZ]*dr[ZZ]; + T rsq = dr[XX] * dr[XX] + dr[YY] * dr[YY] + dr[ZZ] * dr[ZZ]; T rinv = gmx::invsqrt(rsq); - T rinv2 = rinv*rinv; - T rinv6 = rinv2*rinv2*rinv2; + T rinv2 = rinv * rinv; + T rinv6 = rinv2 * rinv2 * rinv2; /* Calculate the Coulomb force * r */ - T cfr = ef*qq*rinv; + T cfr = ef * qq * rinv; /* Calculate the LJ force * r and add it to the Coulomb part */ - T fr = gmx::fma(fms(c12, rinv6, c6), rinv6, cfr); + T fr = gmx::fma(fms(c12, rinv6, c6), rinv6, cfr); - T finvr = fr*rinv2; - T fx = finvr*dr[XX]; - T fy = finvr*dr[YY]; - T fz = finvr*dr[ZZ]; + T finvr = fr * rinv2; + T fx = finvr * dr[XX]; + T fy = finvr * dr[YY]; + T fz = finvr * dr[ZZ]; /* Add the pair forces to the force array. * Note that here we might add multiple force components for some atoms * due to the SIMD padding. But the extra force components are zero. */ - transposeScatterIncrU<4>(reinterpret_cast(f), ai, fx, fy, fz); - transposeScatterDecrU<4>(reinterpret_cast(f), aj, fx, fy, fz); + transposeScatterIncrU<4>(reinterpret_cast(f), ai, fx, fy, fz); + transposeScatterDecrU<4>(reinterpret_cast(f), aj, fx, fy, fz); } } /*! \brief Calculate all listed pair interactions */ -void -do_pairs(int ftype, int nbonds, - const t_iatom iatoms[], const t_iparams iparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - const real *lambda, real *dvdl, - const t_mdatoms *md, - const t_forcerec *fr, - const bool havePerturbedInteractions, - const gmx::StepWorkload &stepWork, - gmx_grppairener_t *grppener, - int *global_atom_index) +void do_pairs(int ftype, + int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + const real* lambda, + real* dvdl, + const t_mdatoms* md, + const t_forcerec* fr, + const bool havePerturbedInteractions, + const gmx::StepWorkload& stepWork, + gmx_grppairener_t* grppener, + int* global_atom_index) { - if (ftype == F_LJ14 && - fr->ic->vdwtype != evdwUSER && !EEL_USER(fr->ic->eeltype) && - !havePerturbedInteractions && - (!stepWork.computeVirial && !stepWork.computeEnergy)) + if (ftype == F_LJ14 && fr->ic->vdwtype != evdwUSER && !EEL_USER(fr->ic->eeltype) + && !havePerturbedInteractions && (!stepWork.computeVirial && !stepWork.computeEnergy)) { /* We use a fast code-path for plain LJ 1-4 without FEP. * @@ -672,51 +713,43 @@ do_pairs(int ftype, int nbonds, #if GMX_SIMD_HAVE_REAL if (fr->use_simd_kernels) { - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; set_pbc_simd(pbc, pbc_simd); - do_pairs_simple(nbonds, iatoms, iparams, - x, f, pbc_simd, - md, fr->ic->epsfac*fr->fudgeQQ); + do_pairs_simple( + nbonds, iatoms, iparams, x, f, pbc_simd, md, fr->ic->epsfac * fr->fudgeQQ); } else #endif { /* This construct is needed because pbc_dx_aiuc doesn't accept pbc=NULL */ t_pbc pbc_no; - const t_pbc *pbc_nonnull; + const t_pbc* pbc_nonnull; if (pbc != nullptr) { - pbc_nonnull = pbc; + pbc_nonnull = pbc; } else { set_pbc(&pbc_no, epbcNONE, nullptr); - pbc_nonnull = &pbc_no; + pbc_nonnull = &pbc_no; } - do_pairs_simple(nbonds, iatoms, iparams, - x, f, pbc_nonnull, - md, fr->ic->epsfac*fr->fudgeQQ); + do_pairs_simple(nbonds, iatoms, iparams, x, f, pbc_nonnull, md, + fr->ic->epsfac * fr->fudgeQQ); } } else if (stepWork.computeVirial) { do_pairs_general( - ftype, nbonds, iatoms, iparams, - x, f, fshift, pbc, g, - lambda, dvdl, - md, fr, grppener, global_atom_index); + ftype, nbonds, iatoms, iparams, x, f, fshift, pbc, g, lambda, dvdl, md, fr, + grppener, global_atom_index); } else { - do_pairs_general( - ftype, nbonds, iatoms, iparams, - x, f, fshift, pbc, g, - lambda, dvdl, - md, fr, grppener, global_atom_index); + do_pairs_general(ftype, nbonds, iatoms, iparams, x, f, + fshift, pbc, g, lambda, dvdl, md, fr, + grppener, global_atom_index); } } diff --git a/src/gromacs/listed_forces/pairs.h b/src/gromacs/listed_forces/pairs.h index 4bf0b96e74..e6760b7861 100644 --- a/src/gromacs/listed_forces/pairs.h +++ b/src/gromacs/listed_forces/pairs.h @@ -65,14 +65,22 @@ class StepWorkload; * * global_atom_index is only passed for printing error messages. */ -void -do_pairs(int ftype, int nbonds, const t_iatom iatoms[], const t_iparams iparams[], - const rvec x[], rvec4 f[], rvec fshift[], - const struct t_pbc *pbc, const struct t_graph *g, - const real *lambda, real *dvdl, const t_mdatoms *md, const t_forcerec *fr, - bool havePerturbedPairs, - const gmx::StepWorkload &stepWork, - gmx_grppairener_t *grppener, - int *global_atom_index); +void do_pairs(int ftype, + int nbonds, + const t_iatom iatoms[], + const t_iparams iparams[], + const rvec x[], + rvec4 f[], + rvec fshift[], + const struct t_pbc* pbc, + const struct t_graph* g, + const real* lambda, + real* dvdl, + const t_mdatoms* md, + const t_forcerec* fr, + bool havePerturbedPairs, + const gmx::StepWorkload& stepWork, + gmx_grppairener_t* grppener, + int* global_atom_index); #endif diff --git a/src/gromacs/listed_forces/position_restraints.cpp b/src/gromacs/listed_forces/position_restraints.cpp index b3309e6236..939d843396 100644 --- a/src/gromacs/listed_forces/position_restraints.cpp +++ b/src/gromacs/listed_forces/position_restraints.cpp @@ -70,17 +70,24 @@ namespace /*! \brief returns dx, rdist, and dpdl for functions posres() and fbposres() */ -void posres_dx(const rvec x, const rvec pos0A, const rvec pos0B, - const rvec comA_sc, const rvec comB_sc, - real lambda, - const t_pbc *pbc, int refcoord_scaling, int npbcdim, - rvec dx, rvec rdist, rvec dpdl) +void posres_dx(const rvec x, + const rvec pos0A, + const rvec pos0B, + const rvec comA_sc, + const rvec comB_sc, + real lambda, + const t_pbc* pbc, + int refcoord_scaling, + int npbcdim, + rvec dx, + rvec rdist, + rvec dpdl) { int m, d; real posA, posB, L1, ref = 0.; rvec pos; - L1 = 1.0-lambda; + L1 = 1.0 - lambda; for (m = 0; m < DIM; m++) { @@ -92,7 +99,7 @@ void posres_dx(const rvec x, const rvec pos0A, const rvec pos0B, { case erscNO: ref = 0; - rdist[m] = L1*posA + lambda*posB; + rdist[m] = L1 * posA + lambda * posB; dpdl[m] = posB - posA; break; case erscALL: @@ -100,27 +107,26 @@ void posres_dx(const rvec x, const rvec pos0A, const rvec pos0B, posA *= pbc->box[m][m]; posB *= pbc->box[m][m]; assert(npbcdim <= DIM); - for (d = m+1; d < npbcdim && d < DIM; d++) + for (d = m + 1; d < npbcdim && d < DIM; d++) { - posA += pos0A[d]*pbc->box[d][m]; - posB += pos0B[d]*pbc->box[d][m]; + posA += pos0A[d] * pbc->box[d][m]; + posB += pos0B[d] * pbc->box[d][m]; } - ref = L1*posA + lambda*posB; + ref = L1 * posA + lambda * posB; rdist[m] = 0; dpdl[m] = posB - posA; break; case erscCOM: - ref = L1*comA_sc[m] + lambda*comB_sc[m]; - rdist[m] = L1*posA + lambda*posB; + ref = L1 * comA_sc[m] + lambda * comB_sc[m]; + rdist[m] = L1 * posA + lambda * posB; dpdl[m] = comB_sc[m] - comA_sc[m] + posB - posA; break; - default: - gmx_fatal(FARGS, "No such scaling method implemented"); + default: gmx_fatal(FARGS, "No such scaling method implemented"); } } else { - ref = L1*posA + lambda*posB; + ref = L1 * posA + lambda * posB; rdist[m] = 0; dpdl[m] = posB - posA; } @@ -145,8 +151,8 @@ void posres_dx(const rvec x, const rvec pos0A, const rvec pos0B, * Returns the flat-bottom potential. */ real do_fbposres_cylinder(int fbdim, rvec fm, rvec dx, real rfb, real kk, gmx_bool bInvert) { - int d; - real dr, dr2, invdr, v, rfb2; + int d; + real dr, dr2, invdr, v, rfb2; dr2 = 0.0; rfb2 = gmx::square(rfb); @@ -160,18 +166,16 @@ real do_fbposres_cylinder(int fbdim, rvec fm, rvec dx, real rfb, real kk, gmx_bo } } - if (dr2 > 0.0 && - ( (dr2 > rfb2 && !bInvert ) || (dr2 < rfb2 && bInvert ) ) - ) + if (dr2 > 0.0 && ((dr2 > rfb2 && !bInvert) || (dr2 < rfb2 && bInvert))) { - dr = std::sqrt(dr2); - invdr = 1./dr; - v = 0.5*kk*gmx::square(dr - rfb); + dr = std::sqrt(dr2); + invdr = 1. / dr; + v = 0.5 * kk * gmx::square(dr - rfb); for (d = 0; d < DIM; d++) { if (d != fbdim) { - fm[d] = -kk*(dr-rfb)*dx[d]*invdr; /* Force pointing to the center */ + fm[d] = -kk * (dr - rfb) * dx[d] * invdr; /* Force pointing to the center */ } } } @@ -183,23 +187,26 @@ real do_fbposres_cylinder(int fbdim, rvec fm, rvec dx, real rfb, real kk, gmx_bo * * Returns the flat-bottomed potential. Same PBC treatment as in * normal position restraints */ -real fbposres(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], - gmx::ForceWithVirial *forceWithVirial, - const t_pbc *pbc, - int refcoord_scaling, int ePBC, const rvec com) +real fbposres(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + gmx::ForceWithVirial* forceWithVirial, + const t_pbc* pbc, + int refcoord_scaling, + int ePBC, + const rvec com) /* compute flat-bottomed positions restraints */ { int i, ai, m, d, type, npbcdim = 0, fbdim; - const t_iparams *pr; + const t_iparams* pr; real kk, v; real dr, dr2, rfb, rfb2, fact; rvec com_sc, rdist, dx, dpdl, fm; gmx_bool bInvert; npbcdim = ePBC2npbcdim(ePBC); - GMX_ASSERT((ePBC == epbcNONE) == (npbcdim == 0), ""); + GMX_ASSERT((ePBC == epbcNONE) == (npbcdim == 0), ""); if (refcoord_scaling == erscCOM) { clear_rvec(com_sc); @@ -208,25 +215,23 @@ real fbposres(int nbonds, assert(npbcdim <= DIM); for (d = m; d < npbcdim; d++) { - com_sc[m] += com[d]*pbc->box[d][m]; + com_sc[m] += com[d] * pbc->box[d][m]; } } } - rvec *f = as_rvec_array(forceWithVirial->force_.data()); + rvec* f = as_rvec_array(forceWithVirial->force_.data()); real vtot = 0.0; rvec virial = { 0 }; - for (i = 0; (i < nbonds); ) + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; pr = &forceparams[type]; /* same calculation as for normal posres, but with identical A and B states, and lambda==0 */ - posres_dx(x[ai], forceparams[type].fbposres.pos0, forceparams[type].fbposres.pos0, - com_sc, com_sc, 0.0, - pbc, refcoord_scaling, npbcdim, - dx, rdist, dpdl); + posres_dx(x[ai], forceparams[type].fbposres.pos0, forceparams[type].fbposres.pos0, com_sc, + com_sc, 0.0, pbc, refcoord_scaling, npbcdim, dx, rdist, dpdl); clear_rvec(fm); v = 0.0; @@ -248,13 +253,11 @@ real fbposres(int nbonds, case efbposresSPHERE: /* spherical flat-bottom posres */ dr2 = norm2(dx); - if (dr2 > 0.0 && - ( (dr2 > rfb2 && !bInvert ) || (dr2 < rfb2 && bInvert ) ) - ) + if (dr2 > 0.0 && ((dr2 > rfb2 && !bInvert) || (dr2 < rfb2 && bInvert))) { dr = std::sqrt(dr2); - v = 0.5*kk*gmx::square(dr - rfb); - fact = -kk*(dr-rfb)/dr; /* Force pointing to the center pos0 */ + v = 0.5 * kk * gmx::square(dr - rfb); + fact = -kk * (dr - rfb) / dr; /* Force pointing to the center pos0 */ svmul(fact, dx, fm); } break; @@ -281,15 +284,15 @@ real fbposres(int nbonds, /* 1D flat-bottom potential */ fbdim = pr->fbposres.geom - efbposresX; dr = dx[fbdim]; - if ( ( dr > rfb && !bInvert ) || ( 0 < dr && dr < rfb && bInvert ) ) + if ((dr > rfb && !bInvert) || (0 < dr && dr < rfb && bInvert)) { - v = 0.5*kk*gmx::square(dr - rfb); - fm[fbdim] = -kk*(dr - rfb); + v = 0.5 * kk * gmx::square(dr - rfb); + fm[fbdim] = -kk * (dr - rfb); } - else if ( (dr < (-rfb) && !bInvert ) || ( (-rfb) < dr && dr < 0 && bInvert )) + else if ((dr < (-rfb) && !bInvert) || ((-rfb) < dr && dr < 0 && bInvert)) { - v = 0.5*kk*gmx::square(dr + rfb); - fm[fbdim] = -kk*(dr + rfb); + v = 0.5 * kk * gmx::square(dr + rfb); + fm[fbdim] = -kk * (dr + rfb); } break; } @@ -298,9 +301,9 @@ real fbposres(int nbonds, for (m = 0; (m < DIM); m++) { - f[ai][m] += fm[m]; + f[ai][m] += fm[m]; /* Here we correct for the pbc_dx which included rdist */ - virial[m] -= 0.5*(dx[m] + rdist[m])*fm[m]; + virial[m] -= 0.5 * (dx[m] + rdist[m]) * fm[m]; } } @@ -315,21 +318,26 @@ real fbposres(int nbonds, * Note that position restraints require a different pbc treatment * from other bondeds */ template -real posres(int nbonds, - const t_iatom forceatoms[], const t_iparams forceparams[], - const rvec x[], - gmx::ForceWithVirial *forceWithVirial, - const struct t_pbc *pbc, - real lambda, real *dvdlambda, - int refcoord_scaling, int ePBC, const rvec comA, const rvec comB) +real posres(int nbonds, + const t_iatom forceatoms[], + const t_iparams forceparams[], + const rvec x[], + gmx::ForceWithVirial* forceWithVirial, + const struct t_pbc* pbc, + real lambda, + real* dvdlambda, + int refcoord_scaling, + int ePBC, + const rvec comA, + const rvec comB) { int i, ai, m, d, type, npbcdim = 0; - const t_iparams *pr; + const t_iparams* pr; real kk, fm; rvec comA_sc, comB_sc, rdist, dpdl, dx; npbcdim = ePBC2npbcdim(ePBC); - GMX_ASSERT((ePBC == epbcNONE) == (npbcdim == 0), ""); + GMX_ASSERT((ePBC == epbcNONE) == (npbcdim == 0), ""); if (refcoord_scaling == erscCOM) { clear_rvec(comA_sc); @@ -339,49 +347,45 @@ real posres(int nbonds, assert(npbcdim <= DIM); for (d = m; d < npbcdim; d++) { - comA_sc[m] += comA[d]*pbc->box[d][m]; - comB_sc[m] += comB[d]*pbc->box[d][m]; + comA_sc[m] += comA[d] * pbc->box[d][m]; + comB_sc[m] += comB[d] * pbc->box[d][m]; } } } - const real L1 = 1.0 - lambda; + const real L1 = 1.0 - lambda; - rvec *f; + rvec* f; if (computeForce) { GMX_ASSERT(forceWithVirial != nullptr, "When forces are requested we need a force object"); - f = as_rvec_array(forceWithVirial->force_.data()); + f = as_rvec_array(forceWithVirial->force_.data()); } - real vtot = 0.0; + real vtot = 0.0; /* Use intermediate virial buffer to reduce reduction rounding errors */ - rvec virial = { 0 }; - for (i = 0; (i < nbonds); ) + rvec virial = { 0 }; + for (i = 0; (i < nbonds);) { type = forceatoms[i++]; ai = forceatoms[i++]; pr = &forceparams[type]; /* return dx, rdist, and dpdl */ - posres_dx(x[ai], forceparams[type].posres.pos0A, forceparams[type].posres.pos0B, - comA_sc, comB_sc, lambda, - pbc, refcoord_scaling, npbcdim, - dx, rdist, dpdl); + posres_dx(x[ai], forceparams[type].posres.pos0A, forceparams[type].posres.pos0B, comA_sc, + comB_sc, lambda, pbc, refcoord_scaling, npbcdim, dx, rdist, dpdl); for (m = 0; (m < DIM); m++) { - kk = L1*pr->posres.fcA[m] + lambda*pr->posres.fcB[m]; - fm = -kk*dx[m]; - vtot += 0.5*kk*dx[m]*dx[m]; - *dvdlambda += - 0.5*(pr->posres.fcB[m] - pr->posres.fcA[m])*dx[m]*dx[m] - + fm*dpdl[m]; + kk = L1 * pr->posres.fcA[m] + lambda * pr->posres.fcB[m]; + fm = -kk * dx[m]; + vtot += 0.5 * kk * dx[m] * dx[m]; + *dvdlambda += 0.5 * (pr->posres.fcB[m] - pr->posres.fcA[m]) * dx[m] * dx[m] + fm * dpdl[m]; /* Here we correct for the pbc_dx which included rdist */ if (computeForce) { - f[ai][m] += fm; - virial[m] -= 0.5*(dx[m] + rdist[m])*fm; + f[ai][m] += fm; + virial[m] -= 0.5 * (dx[m] + rdist[m]) * fm; } } } @@ -396,26 +400,21 @@ real posres(int nbonds, } // namespace -void -posres_wrapper(t_nrnb *nrnb, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec *x, - gmx_enerdata_t *enerd, - const real *lambda, - const t_forcerec *fr, - gmx::ForceWithVirial *forceWithVirial) +void posres_wrapper(t_nrnb* nrnb, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec* x, + gmx_enerdata_t* enerd, + const real* lambda, + const t_forcerec* fr, + gmx::ForceWithVirial* forceWithVirial) { - real v, dvdl; + real v, dvdl; dvdl = 0; - v = posres(idef->il[F_POSRES].nr, idef->il[F_POSRES].iatoms, - idef->iparams_posres, - x, - forceWithVirial, - fr->ePBC == epbcNONE ? nullptr : pbc, - lambda[efptRESTRAINT], &dvdl, - fr->rc_scaling, fr->ePBC, fr->posres_com, fr->posres_comB); + v = posres(idef->il[F_POSRES].nr, idef->il[F_POSRES].iatoms, idef->iparams_posres, x, + forceWithVirial, fr->ePBC == epbcNONE ? nullptr : pbc, lambda[efptRESTRAINT], + &dvdl, fr->rc_scaling, fr->ePBC, fr->posres_com, fr->posres_comB); enerd->term[F_POSRES] += v; /* If just the force constant changes, the FEP term is linear, * but if k changes, it is not. @@ -424,17 +423,16 @@ posres_wrapper(t_nrnb *nrnb, inc_nrnb(nrnb, eNR_POSRES, gmx::exactDiv(idef->il[F_POSRES].nr, 2)); } -void -posres_wrapper_lambda(struct gmx_wallcycle *wcycle, - const t_lambda *fepvals, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec x[], - gmx_enerdata_t *enerd, - const real *lambda, - const t_forcerec *fr) +void posres_wrapper_lambda(struct gmx_wallcycle* wcycle, + const t_lambda* fepvals, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec x[], + gmx_enerdata_t* enerd, + const real* lambda, + const t_forcerec* fr) { - real v; + real v; if (0 == idef->il[F_POSRES].nr) { @@ -446,12 +444,10 @@ posres_wrapper_lambda(struct gmx_wallcycle *wcycle, { real dvdl_dum = 0, lambda_dum; - lambda_dum = (i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i-1]); - v = posres(idef->il[F_POSRES].nr, idef->il[F_POSRES].iatoms, - idef->iparams_posres, - x, nullptr, - fr->ePBC == epbcNONE ? nullptr : pbc, lambda_dum, &dvdl_dum, - fr->rc_scaling, fr->ePBC, fr->posres_com, fr->posres_comB); + lambda_dum = (i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i - 1]); + v = posres(idef->il[F_POSRES].nr, idef->il[F_POSRES].iatoms, idef->iparams_posres, x, + nullptr, fr->ePBC == epbcNONE ? nullptr : pbc, lambda_dum, &dvdl_dum, + fr->rc_scaling, fr->ePBC, fr->posres_com, fr->posres_comB); enerd->enerpart_lambda[i] += v; } wallcycle_sub_stop(wcycle, ewcsRESTRAINTS); @@ -459,22 +455,19 @@ posres_wrapper_lambda(struct gmx_wallcycle *wcycle, /*! \brief Helper function that wraps calls to fbposres for free-energy perturbation */ -void fbposres_wrapper(t_nrnb *nrnb, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec *x, - gmx_enerdata_t *enerd, - const t_forcerec *fr, - gmx::ForceWithVirial *forceWithVirial) +void fbposres_wrapper(t_nrnb* nrnb, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec* x, + gmx_enerdata_t* enerd, + const t_forcerec* fr, + gmx::ForceWithVirial* forceWithVirial) { - real v; - - v = fbposres(idef->il[F_FBPOSRES].nr, idef->il[F_FBPOSRES].iatoms, - idef->iparams_fbposres, - x, - forceWithVirial, - fr->ePBC == epbcNONE ? nullptr : pbc, - fr->rc_scaling, fr->ePBC, fr->posres_com); + real v; + + v = fbposres(idef->il[F_FBPOSRES].nr, idef->il[F_FBPOSRES].iatoms, idef->iparams_fbposres, x, + forceWithVirial, fr->ePBC == epbcNONE ? nullptr : pbc, fr->rc_scaling, fr->ePBC, + fr->posres_com); enerd->term[F_FBPOSRES] += v; inc_nrnb(nrnb, eNR_FBPOSRES, gmx::exactDiv(idef->il[F_FBPOSRES].nr, 2)); } diff --git a/src/gromacs/listed_forces/position_restraints.h b/src/gromacs/listed_forces/position_restraints.h index 79387ecb41..fe9eb6cb19 100644 --- a/src/gromacs/listed_forces/position_restraints.h +++ b/src/gromacs/listed_forces/position_restraints.h @@ -67,36 +67,34 @@ class ForceWithVirial; } /*! \brief Helper function that wraps calls to posres */ -void -posres_wrapper(t_nrnb *nrnb, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec *x, - gmx_enerdata_t *enerd, - const real *lambda, - const t_forcerec *fr, - gmx::ForceWithVirial *forceWithVirial); +void posres_wrapper(t_nrnb* nrnb, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec* x, + gmx_enerdata_t* enerd, + const real* lambda, + const t_forcerec* fr, + gmx::ForceWithVirial* forceWithVirial); /*! \brief Helper function that wraps calls to posres for free-energy pertubation */ -void -posres_wrapper_lambda(struct gmx_wallcycle *wcycle, - const t_lambda *fepvals, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec x[], - gmx_enerdata_t *enerd, - const real *lambda, - const t_forcerec *fr); +void posres_wrapper_lambda(struct gmx_wallcycle* wcycle, + const t_lambda* fepvals, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec x[], + gmx_enerdata_t* enerd, + const real* lambda, + const t_forcerec* fr); /*! \brief Helper function that wraps calls to fbposres for free-energy perturbation */ -void fbposres_wrapper(t_nrnb *nrnb, - const t_idef *idef, - const struct t_pbc *pbc, - const rvec *x, - gmx_enerdata_t *enerd, - const t_forcerec *fr, - gmx::ForceWithVirial *forceWithVirial); +void fbposres_wrapper(t_nrnb* nrnb, + const t_idef* idef, + const struct t_pbc* pbc, + const rvec* x, + gmx_enerdata_t* enerd, + const t_forcerec* fr, + gmx::ForceWithVirial* forceWithVirial); #endif diff --git a/src/gromacs/listed_forces/restcbt.cpp b/src/gromacs/listed_forces/restcbt.cpp index 01d0a67ea5..2da9dcf8fe 100644 --- a/src/gromacs/listed_forces/restcbt.cpp +++ b/src/gromacs/listed_forces/restcbt.cpp @@ -58,9 +58,14 @@ /* This function computes factors needed for restricted angle potential. * For explanations on formula used see file "restcbt.h" */ -void compute_factors_restangles(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_post, - double *prefactor, double *ratio_ante, double *ratio_post, real *v) +void compute_factors_restangles(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_post, + double* prefactor, + double* ratio_ante, + double* ratio_post, + real* v) { // These variables are double to make the code // reproducible. @@ -73,7 +78,7 @@ void compute_factors_restangles(int type, const t_iparams forceparams[], double term_theta_theta_equil; k_bending = forceparams[type].harmonic.krA; - theta_equil = forceparams[type].harmonic.rA*DEG2RAD; + theta_equil = forceparams[type].harmonic.rA * DEG2RAD; theta_equil = M_PI - theta_equil; cosine_theta_equil = cos(theta_equil); @@ -90,22 +95,33 @@ void compute_factors_restangles(int type, const t_iparams forceparams[], delta_cosine = cosine_theta - cosine_theta_equil; term_theta_theta_equil = 1 - cosine_theta * cosine_theta_equil; - *prefactor = -(k_bending) * delta_cosine * norm * term_theta_theta_equil / (sine_theta_sq * sine_theta_sq); + *prefactor = -(k_bending)*delta_cosine * norm * term_theta_theta_equil / (sine_theta_sq * sine_theta_sq); *v = k_bending * 0.5 * delta_cosine * delta_cosine / sine_theta_sq; - } /* Compute factors for restricted dihedral potential * For explanations on formula used see file "restcbt.h" */ -void compute_factors_restrdihs(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_crnt, rvec delta_post, - real *factor_phi_ai_ante, real *factor_phi_ai_crnt, real *factor_phi_ai_post, - real *factor_phi_aj_ante, real *factor_phi_aj_crnt, real *factor_phi_aj_post, - real *factor_phi_ak_ante, real *factor_phi_ak_crnt, real *factor_phi_ak_post, - real *factor_phi_al_ante, real *factor_phi_al_crnt, real *factor_phi_al_post, - real *prefactor_phi, real *v) +void compute_factors_restrdihs(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_crnt, + rvec delta_post, + real* factor_phi_ai_ante, + real* factor_phi_ai_crnt, + real* factor_phi_ai_post, + real* factor_phi_aj_ante, + real* factor_phi_aj_crnt, + real* factor_phi_aj_post, + real* factor_phi_ak_ante, + real* factor_phi_ak_crnt, + real* factor_phi_ak_post, + real* factor_phi_al_ante, + real* factor_phi_al_crnt, + real* factor_phi_al_post, + real* prefactor_phi, + real* v) { real phi0, cosine_phi0; @@ -171,7 +187,7 @@ void compute_factors_restrdihs(int type, const t_iparams forceparams[], ratio_phi_post = c_prod / d_post; /* Computation of the prefactor - common term for all forces */ - *prefactor_phi = -(k_torsion) * delta_cosine * norm_phi * term_phi_phi0 / (sine_phi_sq * sine_phi_sq); + *prefactor_phi = -(k_torsion)*delta_cosine * norm_phi * term_phi_phi0 / (sine_phi_sq * sine_phi_sq); /* Computation of force factors. Factors factor_phi_* are coming from the * derivatives of the torsion angle (phi) with respect to the beads ai, aj, al, ak, @@ -183,10 +199,12 @@ void compute_factors_restrdihs(int type, const t_iparams forceparams[], *factor_phi_ai_crnt = -c_cros_post - ratio_phi_ante * c_cros_ante; *factor_phi_ai_post = c_self_crnt; *factor_phi_aj_ante = -c_cros_post - ratio_phi_ante * (c_self_crnt + c_cros_ante); - *factor_phi_aj_crnt = c_cros_post + c_cros_acrs * 2.0 + ratio_phi_ante * (c_self_ante + c_cros_ante) + ratio_phi_post * c_self_post; + *factor_phi_aj_crnt = c_cros_post + c_cros_acrs * 2.0 + + ratio_phi_ante * (c_self_ante + c_cros_ante) + ratio_phi_post * c_self_post; *factor_phi_aj_post = -(c_cros_ante + c_self_crnt) - ratio_phi_post * c_cros_post; *factor_phi_ak_ante = c_cros_post + c_self_crnt + ratio_phi_ante * c_cros_ante; - *factor_phi_ak_crnt = -(c_cros_ante + c_cros_acrs * 2.0)- ratio_phi_ante * c_self_ante - ratio_phi_post * (c_self_post + c_cros_post); + *factor_phi_ak_crnt = -(c_cros_ante + c_cros_acrs * 2.0) - ratio_phi_ante * c_self_ante + - ratio_phi_post * (c_self_post + c_cros_post); *factor_phi_ak_post = c_cros_ante + ratio_phi_post * (c_self_crnt + c_cros_post); *factor_phi_al_ante = -c_self_crnt; *factor_phi_al_crnt = c_cros_ante + ratio_phi_post * c_cros_post; @@ -197,22 +215,31 @@ void compute_factors_restrdihs(int type, const t_iparams forceparams[], } - /* Compute factors for CBT potential * For explanations on formula used see file "restcbt.h" */ -void compute_factors_cbtdihs(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_crnt, rvec delta_post, - rvec f_phi_ai, rvec f_phi_aj, rvec f_phi_ak, rvec f_phi_al, - rvec f_theta_ante_ai, rvec f_theta_ante_aj, rvec f_theta_ante_ak, - rvec f_theta_post_aj, rvec f_theta_post_ak, rvec f_theta_post_al, - real * v) +void compute_factors_cbtdihs(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_crnt, + rvec delta_post, + rvec f_phi_ai, + rvec f_phi_aj, + rvec f_phi_ak, + rvec f_phi_al, + rvec f_theta_ante_ai, + rvec f_theta_ante_aj, + rvec f_theta_ante_ak, + rvec f_theta_post_aj, + rvec f_theta_post_ak, + rvec f_theta_post_al, + real* v) { int j, d; real torsion_coef[NR_CBTDIHS]; real c_self_ante, c_self_crnt, c_self_post; real c_cros_ante, c_cros_acrs, c_cros_post; - real c_prod, d_ante, d_post; + real c_prod, d_ante, d_post; real norm_phi, norm_theta_ante, norm_theta_post; real cosine_phi, cosine_theta_ante, cosine_theta_post; real sine_theta_ante_sq, sine_theta_post_sq; @@ -245,7 +272,7 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], for (j = 0; (j < NR_CBTDIHS); j++) { - torsion_coef[j] = forceparams[type].cbtdihs.cbtcA[j]; + torsion_coef[j] = forceparams[type].cbtdihs.cbtcA[j]; } /* Computation of the cosine of the dihedral angle. The scalar ("dot") product method @@ -307,8 +334,10 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], /* Computing 2nd power */ r1 = cosine_phi; - prefactor_phi = -torsion_coef[0] * norm_phi * (torsion_coef[2] + torsion_coef[3] * 2.0 * cosine_phi + torsion_coef[4] * 3.0 * (r1 * r1) + 4*torsion_coef[5]*r1*r1*r1) * - sine_theta_ante_sq * sine_theta_ante * sine_theta_post_sq * sine_theta_post; + prefactor_phi = -torsion_coef[0] * norm_phi + * (torsion_coef[2] + torsion_coef[3] * 2.0 * cosine_phi + + torsion_coef[4] * 3.0 * (r1 * r1) + 4 * torsion_coef[5] * r1 * r1 * r1) + * sine_theta_ante_sq * sine_theta_ante * sine_theta_post_sq * sine_theta_post; /* Computation of factors (important for gaining speed). Factors factor_phi_* are coming from the * derivatives of the torsion angle (phi) with respect to the beads ai, aj, al, ak, @@ -320,10 +349,12 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], factor_phi_ai_crnt = -c_cros_post - ratio_phi_ante * c_cros_ante; factor_phi_ai_post = c_self_crnt; factor_phi_aj_ante = -c_cros_post - ratio_phi_ante * (c_self_crnt + c_cros_ante); - factor_phi_aj_crnt = c_cros_post + c_cros_acrs * 2.0 + ratio_phi_ante * (c_self_ante + c_cros_ante) + ratio_phi_post * c_self_post; + factor_phi_aj_crnt = c_cros_post + c_cros_acrs * 2.0 + + ratio_phi_ante * (c_self_ante + c_cros_ante) + ratio_phi_post * c_self_post; factor_phi_aj_post = -(c_cros_ante + c_self_crnt) - ratio_phi_post * c_cros_post; factor_phi_ak_ante = c_cros_post + c_self_crnt + ratio_phi_ante * c_cros_ante; - factor_phi_ak_crnt = -(c_cros_ante + c_cros_acrs * 2.0) - ratio_phi_ante * c_self_ante - ratio_phi_post * (c_self_post + c_cros_post); + factor_phi_ak_crnt = -(c_cros_ante + c_cros_acrs * 2.0) - ratio_phi_ante * c_self_ante + - ratio_phi_post * (c_self_post + c_cros_post); factor_phi_ak_post = c_cros_ante + ratio_phi_post * (c_self_crnt + c_cros_post); factor_phi_al_ante = -c_self_crnt; factor_phi_al_crnt = c_cros_ante + ratio_phi_post * c_cros_post; @@ -332,10 +363,18 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], /* Computation of forces due to the derivatives of dihedral angle phi*/ for (d = 0; d < DIM; d++) { - f_phi_ai[d] = prefactor_phi * (factor_phi_ai_ante * delta_ante[d] + factor_phi_ai_crnt * delta_crnt[d] + factor_phi_ai_post * delta_post[d]); - f_phi_aj[d] = prefactor_phi * (factor_phi_aj_ante * delta_ante[d] + factor_phi_aj_crnt * delta_crnt[d] + factor_phi_aj_post * delta_post[d]); - f_phi_ak[d] = prefactor_phi * (factor_phi_ak_ante * delta_ante[d] + factor_phi_ak_crnt * delta_crnt[d] + factor_phi_ak_post * delta_post[d]); - f_phi_al[d] = prefactor_phi * (factor_phi_al_ante * delta_ante[d] + factor_phi_al_crnt * delta_crnt[d] + factor_phi_al_post * delta_post[d]); + f_phi_ai[d] = prefactor_phi + * (factor_phi_ai_ante * delta_ante[d] + factor_phi_ai_crnt * delta_crnt[d] + + factor_phi_ai_post * delta_post[d]); + f_phi_aj[d] = prefactor_phi + * (factor_phi_aj_ante * delta_ante[d] + factor_phi_aj_crnt * delta_crnt[d] + + factor_phi_aj_post * delta_post[d]); + f_phi_ak[d] = prefactor_phi + * (factor_phi_ak_ante * delta_ante[d] + factor_phi_ak_crnt * delta_crnt[d] + + factor_phi_ak_post * delta_post[d]); + f_phi_al[d] = prefactor_phi + * (factor_phi_al_ante * delta_ante[d] + factor_phi_al_crnt * delta_crnt[d] + + factor_phi_al_post * delta_post[d]); } /* PART 3 - COMPUTES THE FORCE COMPONENTS DUE TO THE DERIVATIVES OF BENDING ANGLE THETHA_ANTHE */ @@ -349,16 +388,23 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], /* Computing 3rd power */ r2 = cosine_phi; - prefactor_theta_ante = -torsion_coef[0] * norm_theta_ante * ( torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + - torsion_coef[4] * (r2 * (r2 * r2))+ torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) * (-3.0) * cosine_theta_ante * sine_theta_ante * sine_theta_post_sq * sine_theta_post; + prefactor_theta_ante = + -torsion_coef[0] * norm_theta_ante + * (torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + + torsion_coef[4] * (r2 * (r2 * r2)) + torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) + * (-3.0) * cosine_theta_ante * sine_theta_ante * sine_theta_post_sq * sine_theta_post; /* Computation of forces due to the derivatives of bending angle theta_ante */ for (d = 0; d < DIM; d++) { - f_theta_ante_ai[d] = prefactor_theta_ante * (ratio_theta_ante_ante * delta_ante[d] - delta_crnt[d]); - f_theta_ante_aj[d] = prefactor_theta_ante * ((ratio_theta_ante_crnt + 1.0) * delta_crnt[d] - (ratio_theta_ante_ante + 1.0) * delta_ante[d]); - f_theta_ante_ak[d] = prefactor_theta_ante * (delta_ante[d] - ratio_theta_ante_crnt * delta_crnt[d]); + f_theta_ante_ai[d] = + prefactor_theta_ante * (ratio_theta_ante_ante * delta_ante[d] - delta_crnt[d]); + f_theta_ante_aj[d] = prefactor_theta_ante + * ((ratio_theta_ante_crnt + 1.0) * delta_crnt[d] + - (ratio_theta_ante_ante + 1.0) * delta_ante[d]); + f_theta_ante_ak[d] = + prefactor_theta_ante * (delta_ante[d] - ratio_theta_ante_crnt * delta_crnt[d]); } /* PART 4 - COMPUTES THE FORCE COMPONENTS DUE TO THE DERIVATIVES OF THE BENDING ANGLE THETA_POST */ @@ -373,24 +419,30 @@ void compute_factors_cbtdihs(int type, const t_iparams forceparams[], /* Computing 3rd power */ r2 = cosine_phi; - prefactor_theta_post = -torsion_coef[0] * norm_theta_post * (torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + - torsion_coef[4] * (r2 * (r2 * r2)) + torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) * sine_theta_ante_sq * sine_theta_ante * (-3.0) * cosine_theta_post * sine_theta_post; + prefactor_theta_post = + -torsion_coef[0] * norm_theta_post + * (torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + + torsion_coef[4] * (r2 * (r2 * r2)) + torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) + * sine_theta_ante_sq * sine_theta_ante * (-3.0) * cosine_theta_post * sine_theta_post; /* Computation of forces due to the derivatives of bending angle Theta_Post */ for (d = 0; d < DIM; d++) { - f_theta_post_aj[d] = prefactor_theta_post * (ratio_theta_post_crnt * delta_crnt[d] - delta_post[d]); - f_theta_post_ak[d] = prefactor_theta_post * ((ratio_theta_post_post + 1.0) * delta_post[d] - (ratio_theta_post_crnt + 1.0) * delta_crnt[d]); - f_theta_post_al[d] = prefactor_theta_post * (delta_crnt[d] - ratio_theta_post_post * delta_post[d]); + f_theta_post_aj[d] = + prefactor_theta_post * (ratio_theta_post_crnt * delta_crnt[d] - delta_post[d]); + f_theta_post_ak[d] = prefactor_theta_post + * ((ratio_theta_post_post + 1.0) * delta_post[d] + - (ratio_theta_post_crnt + 1.0) * delta_crnt[d]); + f_theta_post_al[d] = + prefactor_theta_post * (delta_crnt[d] - ratio_theta_post_post * delta_post[d]); } r1 = cosine_phi; r2 = cosine_phi; /* Contribution to energy - for formula see file "restcbt.h" */ - *v = torsion_coef[0] * (torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + - torsion_coef[4] * (r2 * (r2 * r2)) + torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) * sine_theta_ante_sq * - sine_theta_ante * sine_theta_post_sq * sine_theta_post; - - + *v = torsion_coef[0] + * (torsion_coef[1] + torsion_coef[2] * cosine_phi + torsion_coef[3] * (r1 * r1) + + torsion_coef[4] * (r2 * (r2 * r2)) + torsion_coef[5] * (r2 * (r2 * (r2 * r2)))) + * sine_theta_ante_sq * sine_theta_ante * sine_theta_post_sq * sine_theta_post; } diff --git a/src/gromacs/listed_forces/restcbt.h b/src/gromacs/listed_forces/restcbt.h index 6670abd2e0..20dc9ab6f6 100644 --- a/src/gromacs/listed_forces/restcbt.h +++ b/src/gromacs/listed_forces/restcbt.h @@ -77,9 +77,14 @@ */ -void compute_factors_restangles(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_post, - double *prefactor, double *ratio_ante, double *ratio_post, real *v); +void compute_factors_restangles(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_post, + double* prefactor, + double* ratio_ante, + double* ratio_post, + real* v); /*! \brief Compute factors for restricted dihedral potentials. @@ -118,13 +123,25 @@ void compute_factors_restangles(int type, const t_iparams forceparams[], * \param[out] v contribution to energy (see formula above) */ -void compute_factors_restrdihs(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_crnt, rvec delta_post, - real *factor_phi_ai_ante, real *factor_phi_ai_crnt, real *factor_phi_ai_post, - real *factor_phi_aj_ante, real *factor_phi_aj_crnt, real *factor_phi_aj_post, - real *factor_phi_ak_ante, real *factor_phi_ak_crnt, real *factor_phi_ak_post, - real *factor_phi_al_ante, real *factor_phi_al_crnt, real *factor_phi_al_post, - real *prefactor_phi, real *v); +void compute_factors_restrdihs(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_crnt, + rvec delta_post, + real* factor_phi_ai_ante, + real* factor_phi_ai_crnt, + real* factor_phi_ai_post, + real* factor_phi_aj_ante, + real* factor_phi_aj_crnt, + real* factor_phi_aj_post, + real* factor_phi_ak_ante, + real* factor_phi_ak_crnt, + real* factor_phi_ak_post, + real* factor_phi_al_ante, + real* factor_phi_al_crnt, + real* factor_phi_al_post, + real* prefactor_phi, + real* v); /*! \brief Compute factors for combined bending-torsion (CBT) potentials. * @@ -136,7 +153,7 @@ void compute_factors_restrdihs(int type, const t_iparams forceparams[], * It contains in its expression not only the dihedral angle \f$\phi\f$ * but also \f$\theta_{i-1}\f$ (denoted as theta_ante below) and \f$\theta_{i}\f$ (denoted as theta_post below) * --- the adjacent bending angles. The derivative of the CBT potential is calculated as: - * \f[\frac{\partial V_{\rm CBT}(\theta_{i-1},\theta_i,\phi_i)} {\partial \vec r_{l}} = \frac{\partial V_ + * \f[\frac{\partial V_{\rm CBT}(\theta_{i-1},\theta_i,\phi_i)} {\partial \vec r_{l}} = \frac{\partial V_ * {\rm CBT}}{\partial \theta_{i-1}} \frac{\partial \theta_{i-1}}{\partial \vec r_{l}} + * \frac{\partial V_{\rm CBT}}{\partial \phi_{i }} \frac{\partial \phi_{i }}{\partial \vec r_{l}}\f] * where all the derivatives of the angles with respect to Cartesian coordinates are calculated as @@ -164,11 +181,21 @@ void compute_factors_restrdihs(int type, const t_iparams forceparams[], * \param[out] v contribution to energy (see formula above) */ -void compute_factors_cbtdihs(int type, const t_iparams forceparams[], - rvec delta_ante, rvec delta_crnt, rvec delta_post, - rvec f_phi_ai, rvec f_phi_aj, rvec f_phi_ak, rvec f_phi_al, - rvec f_theta_ante_ai, rvec f_theta_ante_aj, rvec f_theta_ante_ak, - rvec f_theta_post_aj, rvec f_theta_post_ak, rvec f_theta_post_al, - real * v); +void compute_factors_cbtdihs(int type, + const t_iparams forceparams[], + rvec delta_ante, + rvec delta_crnt, + rvec delta_post, + rvec f_phi_ai, + rvec f_phi_aj, + rvec f_phi_ak, + rvec f_phi_al, + rvec f_theta_ante_ai, + rvec f_theta_ante_aj, + rvec f_theta_ante_ak, + rvec f_theta_post_aj, + rvec f_theta_post_ak, + rvec f_theta_post_al, + real* v); #endif diff --git a/src/gromacs/listed_forces/tests/bonded.cpp b/src/gromacs/listed_forces/tests/bonded.cpp index 7037cfb57b..42d7284e08 100644 --- a/src/gromacs/listed_forces/tests/bonded.cpp +++ b/src/gromacs/listed_forces/tests/bonded.cpp @@ -77,13 +77,13 @@ constexpr int c_numAtoms = 4; struct OutputQuantities { //! Energy of this interaction - real energy = 0; + real energy = 0; //! Derivative with respect to lambda - real dvdlambda = 0; + real dvdlambda = 0; //! Shift vectors - rvec fshift[N_IVEC] = {{0}}; + rvec fshift[N_IVEC] = { { 0 } }; //! Forces - rvec4 f[c_numAtoms] = {{0}}; + rvec4 f[c_numAtoms] = { { 0 } }; }; /*! \brief Utility to check the output from bonded tests @@ -91,8 +91,7 @@ struct OutputQuantities * \param[in] checker Reference checker * \param[in] output The output from the test to check */ -void checkOutput(test::TestReferenceChecker *checker, - const OutputQuantities &output) +void checkOutput(test::TestReferenceChecker* checker, const OutputQuantities& output) { checker->checkReal(output.energy, "Epot "); // Should still be zero if not doing FEP, so may as well test it. @@ -105,390 +104,370 @@ void checkOutput(test::TestReferenceChecker *checker, */ struct iListInput { - public: - //! Function type - int ftype = -1; - //! Tolerance for float evaluation - float ftoler = 1e-6; - //! Tolerance for double evaluation - double dtoler = 1e-8; - //! Do free energy perturbation? - bool fep = false; - //! Interaction parameters - t_iparams iparams = {{ 0 }}; - - //! Constructor - iListInput() {} - - /*! \brief Constructor with tolerance - * - * \param[in] ftol Single precision tolerance - * \param[in] dtol Double precision tolerance - */ - iListInput(float ftol, double dtol) - { - ftoler = ftol; - dtoler = dtol; - } - /*! \brief Set parameters for harmonic potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] ft Function type - * \param[in] rA Equilibrium value A - * \param[in] krA Force constant A - * \param[in] rB Equilibrium value B - * \param[in] krB Force constant B - * \return The structure itself. - */ - iListInput setHarmonic(int ft, real rA, real krA, real rB, real krB) - { - iparams.harmonic.rA = rA; - iparams.harmonic.rB = rB; - iparams.harmonic.krA = krA; - iparams.harmonic.krB = krB; - ftype = ft; - fep = (rA != rB || krA != krB); - return *this; - } - /*! \brief Set parameters for harmonic potential - * - * \param[in] ft Function type - * \param[in] rA Equilibrium value - * \param[in] krA Force constant - * \return The structure itself. - */ - iListInput setHarmonic(int ft, real rA, real krA) - { - return setHarmonic(ft, rA, krA, rA, krA); - } - /*! \brief Set parameters for cubic potential - * - * \param[in] b0 Equilibrium bond length - * \param[in] kb Harmonic force constant - * \param[in] kcub Cubic force constant - * \return The structure itself. - */ - iListInput setCubic(real b0, real kb, real kcub) - { - ftype = F_CUBICBONDS; - iparams.cubic.b0 = b0; - iparams.cubic.kb = kb; - iparams.cubic.kcub = kcub; - return *this; - } - /*! \brief Set parameters for morse potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] b0A Equilibrium value A - * \param[in] cbA Force constant A - * \param[in] betaA Steepness parameter A - * \param[in] b0B Equilibrium value B - * \param[in] cbB Force constant B - * \param[in] betaB Steepness parameter B - * \return The structure itself. - */ - iListInput setMorse(real b0A, real cbA, real betaA, real b0B, real cbB, real betaB) - { - ftype = F_MORSE; - iparams.morse.b0A = b0A; - iparams.morse.cbA = cbA; - iparams.morse.betaA = betaA; - iparams.morse.b0B = b0B; - iparams.morse.cbB = cbB; - iparams.morse.betaB = betaB; - fep = (b0A != b0B || cbA != cbB || betaA != betaB); - return *this; - } - /*! \brief Set parameters for morse potential - * - * \param[in] b0A Equilibrium value - * \param[in] cbA Force constant - * \param[in] betaA Steepness parameter - * \return The structure itself. - */ - iListInput setMorse(real b0A, real cbA, real betaA) - { - return setMorse(b0A, cbA, betaA, b0A, cbA, betaA); - } - /*! \brief Set parameters for fene potential - * - * \param[in] bm Equilibrium bond length - * \param[in] kb Force constant - * \return The structure itself. - */ - iListInput setFene(real bm, real kb) - { - ftype = F_FENEBONDS; - iparams.fene.bm = bm; - iparams.fene.kb = kb; - return *this; - } - /*! \brief Set parameters for linear angle potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] klinA Force constant A - * \param[in] aA The position of the central atom A - * \param[in] klinB Force constant B - * \param[in] aB The position of the central atom B - * \return The structure itself. - */ - iListInput setLinearAngle(real klinA, real aA, real klinB, real aB) - { - ftype = F_LINEAR_ANGLES; - iparams.linangle.klinA = klinA; - iparams.linangle.aA = aA; - iparams.linangle.klinB = klinB; - iparams.linangle.aB = aB; - fep = (klinA != klinB || aA != aB); - return *this; - } - /*! \brief Set parameters for linear angle potential - * - * \param[in] klinA Force constant - * \param[in] aA The position of the central atom - * \return The structure itself. - */ - iListInput setLinearAngle(real klinA, real aA) - { - return setLinearAngle(klinA, aA, klinA, aA); - } - /*! \brief Set parameters for Urey Bradley potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] thetaA Equilibrium angle A - * \param[in] kthetaA Force constant A - * \param[in] r13A The distance between i and k atoms A - * \param[in] kUBA The force constant for 1-3 distance A - * \param[in] thetaB Equilibrium angle B - * \param[in] kthetaB Force constant B - * \param[in] r13B The distance between i and k atoms B - * \param[in] kUBB The force constant for 1-3 distance B - * \return The structure itself. - */ - iListInput setUreyBradley(real thetaA, real kthetaA, real r13A, real kUBA, - real thetaB, real kthetaB, real r13B, real kUBB) - { - ftype = F_UREY_BRADLEY; - iparams.u_b.thetaA = thetaA; - iparams.u_b.kthetaA = kthetaA; - iparams.u_b.r13A = r13A; - iparams.u_b.kUBA = kUBA; - iparams.u_b.thetaB = thetaB; - iparams.u_b.kthetaB = kthetaB; - iparams.u_b.r13B = r13B; - iparams.u_b.kUBB = kUBB; - fep = (thetaA != thetaB || kthetaA != kthetaB || r13A != r13B || kUBA != kUBB); - return *this; - } - /*! \brief Set parameters for Urey Bradley potential - * - * \param[in] thetaA Equilibrium angle - * \param[in] kthetaA Force constant - * \param[in] r13A The distance between i and k atoms - * \param[in] kUBA The force constant for 1-3 distance - * \return The structure itself. - */ - iListInput setUreyBradley(real thetaA, real kthetaA, real r13A, real kUBA) - { - return setUreyBradley(thetaA, kthetaA, r13A, kUBA, - thetaA, kthetaA, r13A, kUBA); - } - /*! \brief Set parameters for Cross Bond Bonds potential - * - * \param[in] r1e First bond length i-j - * \param[in] r2e Second bond length i-k - * \param[in] krr The force constant - * \return The structure itself. - */ - iListInput setCrossBondBonds(real r1e, real r2e, real krr) - { - ftype = F_CROSS_BOND_BONDS; - iparams.cross_bb.r1e = r1e; - iparams.cross_bb.r2e = r2e; - iparams.cross_bb.krr = krr; - return *this; - } - /*! \brief Set parameters for Cross Bond Angles potential - * - * \param[in] r1e First bond length i-j - * \param[in] r2e Second bond length j-k - * \param[in] r3e Third bond length i-k - * \param[in] krt The force constant - * \return The structure itself. - */ - iListInput setCrossBondAngles(real r1e, real r2e, real r3e, real krt) - { - ftype = F_CROSS_BOND_ANGLES; - iparams.cross_ba.r1e = r1e; - iparams.cross_ba.r2e = r2e; - iparams.cross_ba.r3e = r3e; - iparams.cross_ba.krt = krt; - return *this; - } - /*! \brief Set parameters for Quartic Angles potential - * - * \param[in] theta Angle - * \param[in] c Array of parameters - * \return The structure itself. - */ - iListInput setQuarticAngles(real theta, const real c[5]) - { - ftype = F_QUARTIC_ANGLES; - iparams.qangle.theta = theta; - iparams.qangle.c[0] = c[0]; - iparams.qangle.c[1] = c[1]; - iparams.qangle.c[2] = c[2]; - iparams.qangle.c[3] = c[3]; - iparams.qangle.c[4] = c[4]; - return *this; - } - /*! \brief Set parameters for proper dihedrals potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] ft Function type - * \param[in] phiA Dihedral angle A - * \param[in] cpA Force constant A - * \param[in] mult Multiplicity of the angle - * \param[in] phiB Dihedral angle B - * \param[in] cpB Force constant B - * \return The structure itself. - */ - iListInput setPDihedrals(int ft, real phiA, real cpA, int mult, real phiB, real cpB) - { - ftype = ft; - iparams.pdihs.phiA = phiA; - iparams.pdihs.cpA = cpA; - iparams.pdihs.phiB = phiB; - iparams.pdihs.cpB = cpB; - iparams.pdihs.mult = mult; - fep = (phiA != phiB || cpA != cpB); - return *this; - } - /*! \brief Set parameters for proper dihedrals potential - * - * \param[in] ft Function type - * \param[in] phiA Dihedral angle - * \param[in] cpA Force constant - * \param[in] mult Multiplicity of the angle - * \return The structure itself. - */ - iListInput setPDihedrals(int ft, real phiA, real cpA, int mult) - { - return setPDihedrals(ft, phiA, cpA, mult, phiA, cpA); - } - /*! \brief Set parameters for Ryckaert-Bellemans dihedrals potential - * - * Free energy perturbation is turned on when A - * and B parameters are different. - * \param[in] rbcA Force constants A - * \param[in] rbcB Force constants B - * \return The structure itself. - */ - iListInput setRbDihedrals(const real rbcA[NR_RBDIHS], const real rbcB[NR_RBDIHS]) - { - ftype = F_RBDIHS; - fep = false; - for (int i = 0; i < NR_RBDIHS; i++) - { - iparams.rbdihs.rbcA[i] = rbcA[i]; - iparams.rbdihs.rbcB[i] = rbcB[i]; - fep = fep || (rbcA[i] != rbcB[i]); - } - return *this; - } - /*! \brief Set parameters for Ryckaert-Bellemans dihedrals potential - * - * \param[in] rbc Force constants - * \return The structure itself. - */ - iListInput setRbDihedrals(const real rbc[NR_RBDIHS]) - { - return setRbDihedrals(rbc, rbc); - } - /*! \brief Set parameters for Polarization - * - * \param[in] alpha Polarizability - * \return The structure itself. - */ - iListInput setPolarization(real alpha) - { - ftype = F_POLARIZATION; - fep = false; - iparams.polarize.alpha = alpha; - return *this; - } - /*! \brief Set parameters for Anharmonic Polarization - * - * \param[in] alpha Polarizability (nm^3) - * \param[in] drcut The cut-off distance (nm) after which the - * fourth power kicks in - * \param[in] khyp The force constant for the fourth power - * \return The structure itself. - */ - iListInput setAnharmPolarization(real alpha, - real drcut, - real khyp) - { - ftype = F_ANHARM_POL; - fep = false; - iparams.anharm_polarize.alpha = alpha; - iparams.anharm_polarize.drcut = drcut; - iparams.anharm_polarize.khyp = khyp; - return *this; - } - /*! \brief Set parameters for Thole Polarization - * - * \param[in] a Thole factor - * \param[in] alpha1 Polarizability 1 (nm^3) - * \param[in] alpha2 Polarizability 2 (nm^3) - * \param[in] rfac Distance factor - * \return The structure itself. - */ - iListInput setTholePolarization(real a, - real alpha1, - real alpha2, - real rfac) - { - ftype = F_THOLE_POL; - fep = false; - iparams.thole.a = a; - iparams.thole.alpha1 = alpha1; - iparams.thole.alpha2 = alpha2; - iparams.thole.rfac = rfac; - return *this; - } - /*! \brief Set parameters for Water Polarization - * - * \param[in] alpha_x Polarizability X (nm^3) - * \param[in] alpha_y Polarizability Y (nm^3) - * \param[in] alpha_z Polarizability Z (nm^3) - * \param[in] rOH Oxygen-Hydrogen distance - * \param[in] rHH Hydrogen-Hydrogen distance - * \param[in] rOD Oxygen-Dummy distance - * \return The structure itself. - */ - iListInput setWaterPolarization(real alpha_x, - real alpha_y, - real alpha_z, - real rOH, - real rHH, - real rOD) +public: + //! Function type + int ftype = -1; + //! Tolerance for float evaluation + float ftoler = 1e-6; + //! Tolerance for double evaluation + double dtoler = 1e-8; + //! Do free energy perturbation? + bool fep = false; + //! Interaction parameters + t_iparams iparams = { { 0 } }; + + //! Constructor + iListInput() {} + + /*! \brief Constructor with tolerance + * + * \param[in] ftol Single precision tolerance + * \param[in] dtol Double precision tolerance + */ + iListInput(float ftol, double dtol) + { + ftoler = ftol; + dtoler = dtol; + } + /*! \brief Set parameters for harmonic potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] ft Function type + * \param[in] rA Equilibrium value A + * \param[in] krA Force constant A + * \param[in] rB Equilibrium value B + * \param[in] krB Force constant B + * \return The structure itself. + */ + iListInput setHarmonic(int ft, real rA, real krA, real rB, real krB) + { + iparams.harmonic.rA = rA; + iparams.harmonic.rB = rB; + iparams.harmonic.krA = krA; + iparams.harmonic.krB = krB; + ftype = ft; + fep = (rA != rB || krA != krB); + return *this; + } + /*! \brief Set parameters for harmonic potential + * + * \param[in] ft Function type + * \param[in] rA Equilibrium value + * \param[in] krA Force constant + * \return The structure itself. + */ + iListInput setHarmonic(int ft, real rA, real krA) { return setHarmonic(ft, rA, krA, rA, krA); } + /*! \brief Set parameters for cubic potential + * + * \param[in] b0 Equilibrium bond length + * \param[in] kb Harmonic force constant + * \param[in] kcub Cubic force constant + * \return The structure itself. + */ + iListInput setCubic(real b0, real kb, real kcub) + { + ftype = F_CUBICBONDS; + iparams.cubic.b0 = b0; + iparams.cubic.kb = kb; + iparams.cubic.kcub = kcub; + return *this; + } + /*! \brief Set parameters for morse potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] b0A Equilibrium value A + * \param[in] cbA Force constant A + * \param[in] betaA Steepness parameter A + * \param[in] b0B Equilibrium value B + * \param[in] cbB Force constant B + * \param[in] betaB Steepness parameter B + * \return The structure itself. + */ + iListInput setMorse(real b0A, real cbA, real betaA, real b0B, real cbB, real betaB) + { + ftype = F_MORSE; + iparams.morse.b0A = b0A; + iparams.morse.cbA = cbA; + iparams.morse.betaA = betaA; + iparams.morse.b0B = b0B; + iparams.morse.cbB = cbB; + iparams.morse.betaB = betaB; + fep = (b0A != b0B || cbA != cbB || betaA != betaB); + return *this; + } + /*! \brief Set parameters for morse potential + * + * \param[in] b0A Equilibrium value + * \param[in] cbA Force constant + * \param[in] betaA Steepness parameter + * \return The structure itself. + */ + iListInput setMorse(real b0A, real cbA, real betaA) + { + return setMorse(b0A, cbA, betaA, b0A, cbA, betaA); + } + /*! \brief Set parameters for fene potential + * + * \param[in] bm Equilibrium bond length + * \param[in] kb Force constant + * \return The structure itself. + */ + iListInput setFene(real bm, real kb) + { + ftype = F_FENEBONDS; + iparams.fene.bm = bm; + iparams.fene.kb = kb; + return *this; + } + /*! \brief Set parameters for linear angle potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] klinA Force constant A + * \param[in] aA The position of the central atom A + * \param[in] klinB Force constant B + * \param[in] aB The position of the central atom B + * \return The structure itself. + */ + iListInput setLinearAngle(real klinA, real aA, real klinB, real aB) + { + ftype = F_LINEAR_ANGLES; + iparams.linangle.klinA = klinA; + iparams.linangle.aA = aA; + iparams.linangle.klinB = klinB; + iparams.linangle.aB = aB; + fep = (klinA != klinB || aA != aB); + return *this; + } + /*! \brief Set parameters for linear angle potential + * + * \param[in] klinA Force constant + * \param[in] aA The position of the central atom + * \return The structure itself. + */ + iListInput setLinearAngle(real klinA, real aA) { return setLinearAngle(klinA, aA, klinA, aA); } + /*! \brief Set parameters for Urey Bradley potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] thetaA Equilibrium angle A + * \param[in] kthetaA Force constant A + * \param[in] r13A The distance between i and k atoms A + * \param[in] kUBA The force constant for 1-3 distance A + * \param[in] thetaB Equilibrium angle B + * \param[in] kthetaB Force constant B + * \param[in] r13B The distance between i and k atoms B + * \param[in] kUBB The force constant for 1-3 distance B + * \return The structure itself. + */ + iListInput + setUreyBradley(real thetaA, real kthetaA, real r13A, real kUBA, real thetaB, real kthetaB, real r13B, real kUBB) + { + ftype = F_UREY_BRADLEY; + iparams.u_b.thetaA = thetaA; + iparams.u_b.kthetaA = kthetaA; + iparams.u_b.r13A = r13A; + iparams.u_b.kUBA = kUBA; + iparams.u_b.thetaB = thetaB; + iparams.u_b.kthetaB = kthetaB; + iparams.u_b.r13B = r13B; + iparams.u_b.kUBB = kUBB; + fep = (thetaA != thetaB || kthetaA != kthetaB || r13A != r13B || kUBA != kUBB); + return *this; + } + /*! \brief Set parameters for Urey Bradley potential + * + * \param[in] thetaA Equilibrium angle + * \param[in] kthetaA Force constant + * \param[in] r13A The distance between i and k atoms + * \param[in] kUBA The force constant for 1-3 distance + * \return The structure itself. + */ + iListInput setUreyBradley(real thetaA, real kthetaA, real r13A, real kUBA) + { + return setUreyBradley(thetaA, kthetaA, r13A, kUBA, thetaA, kthetaA, r13A, kUBA); + } + /*! \brief Set parameters for Cross Bond Bonds potential + * + * \param[in] r1e First bond length i-j + * \param[in] r2e Second bond length i-k + * \param[in] krr The force constant + * \return The structure itself. + */ + iListInput setCrossBondBonds(real r1e, real r2e, real krr) + { + ftype = F_CROSS_BOND_BONDS; + iparams.cross_bb.r1e = r1e; + iparams.cross_bb.r2e = r2e; + iparams.cross_bb.krr = krr; + return *this; + } + /*! \brief Set parameters for Cross Bond Angles potential + * + * \param[in] r1e First bond length i-j + * \param[in] r2e Second bond length j-k + * \param[in] r3e Third bond length i-k + * \param[in] krt The force constant + * \return The structure itself. + */ + iListInput setCrossBondAngles(real r1e, real r2e, real r3e, real krt) + { + ftype = F_CROSS_BOND_ANGLES; + iparams.cross_ba.r1e = r1e; + iparams.cross_ba.r2e = r2e; + iparams.cross_ba.r3e = r3e; + iparams.cross_ba.krt = krt; + return *this; + } + /*! \brief Set parameters for Quartic Angles potential + * + * \param[in] theta Angle + * \param[in] c Array of parameters + * \return The structure itself. + */ + iListInput setQuarticAngles(real theta, const real c[5]) + { + ftype = F_QUARTIC_ANGLES; + iparams.qangle.theta = theta; + iparams.qangle.c[0] = c[0]; + iparams.qangle.c[1] = c[1]; + iparams.qangle.c[2] = c[2]; + iparams.qangle.c[3] = c[3]; + iparams.qangle.c[4] = c[4]; + return *this; + } + /*! \brief Set parameters for proper dihedrals potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] ft Function type + * \param[in] phiA Dihedral angle A + * \param[in] cpA Force constant A + * \param[in] mult Multiplicity of the angle + * \param[in] phiB Dihedral angle B + * \param[in] cpB Force constant B + * \return The structure itself. + */ + iListInput setPDihedrals(int ft, real phiA, real cpA, int mult, real phiB, real cpB) + { + ftype = ft; + iparams.pdihs.phiA = phiA; + iparams.pdihs.cpA = cpA; + iparams.pdihs.phiB = phiB; + iparams.pdihs.cpB = cpB; + iparams.pdihs.mult = mult; + fep = (phiA != phiB || cpA != cpB); + return *this; + } + /*! \brief Set parameters for proper dihedrals potential + * + * \param[in] ft Function type + * \param[in] phiA Dihedral angle + * \param[in] cpA Force constant + * \param[in] mult Multiplicity of the angle + * \return The structure itself. + */ + iListInput setPDihedrals(int ft, real phiA, real cpA, int mult) + { + return setPDihedrals(ft, phiA, cpA, mult, phiA, cpA); + } + /*! \brief Set parameters for Ryckaert-Bellemans dihedrals potential + * + * Free energy perturbation is turned on when A + * and B parameters are different. + * \param[in] rbcA Force constants A + * \param[in] rbcB Force constants B + * \return The structure itself. + */ + iListInput setRbDihedrals(const real rbcA[NR_RBDIHS], const real rbcB[NR_RBDIHS]) + { + ftype = F_RBDIHS; + fep = false; + for (int i = 0; i < NR_RBDIHS; i++) { - ftype = F_WATER_POL; - fep = false; - iparams.wpol.al_x = alpha_x; - iparams.wpol.al_y = alpha_y; - iparams.wpol.al_z = alpha_z; - iparams.wpol.rOH = rOH; - iparams.wpol.rHH = rHH; - iparams.wpol.rOD = rOD; - return *this; + iparams.rbdihs.rbcA[i] = rbcA[i]; + iparams.rbdihs.rbcB[i] = rbcB[i]; + fep = fep || (rbcA[i] != rbcB[i]); } + return *this; + } + /*! \brief Set parameters for Ryckaert-Bellemans dihedrals potential + * + * \param[in] rbc Force constants + * \return The structure itself. + */ + iListInput setRbDihedrals(const real rbc[NR_RBDIHS]) { return setRbDihedrals(rbc, rbc); } + /*! \brief Set parameters for Polarization + * + * \param[in] alpha Polarizability + * \return The structure itself. + */ + iListInput setPolarization(real alpha) + { + ftype = F_POLARIZATION; + fep = false; + iparams.polarize.alpha = alpha; + return *this; + } + /*! \brief Set parameters for Anharmonic Polarization + * + * \param[in] alpha Polarizability (nm^3) + * \param[in] drcut The cut-off distance (nm) after which the + * fourth power kicks in + * \param[in] khyp The force constant for the fourth power + * \return The structure itself. + */ + iListInput setAnharmPolarization(real alpha, real drcut, real khyp) + { + ftype = F_ANHARM_POL; + fep = false; + iparams.anharm_polarize.alpha = alpha; + iparams.anharm_polarize.drcut = drcut; + iparams.anharm_polarize.khyp = khyp; + return *this; + } + /*! \brief Set parameters for Thole Polarization + * + * \param[in] a Thole factor + * \param[in] alpha1 Polarizability 1 (nm^3) + * \param[in] alpha2 Polarizability 2 (nm^3) + * \param[in] rfac Distance factor + * \return The structure itself. + */ + iListInput setTholePolarization(real a, real alpha1, real alpha2, real rfac) + { + ftype = F_THOLE_POL; + fep = false; + iparams.thole.a = a; + iparams.thole.alpha1 = alpha1; + iparams.thole.alpha2 = alpha2; + iparams.thole.rfac = rfac; + return *this; + } + /*! \brief Set parameters for Water Polarization + * + * \param[in] alpha_x Polarizability X (nm^3) + * \param[in] alpha_y Polarizability Y (nm^3) + * \param[in] alpha_z Polarizability Z (nm^3) + * \param[in] rOH Oxygen-Hydrogen distance + * \param[in] rHH Hydrogen-Hydrogen distance + * \param[in] rOD Oxygen-Dummy distance + * \return The structure itself. + */ + iListInput setWaterPolarization(real alpha_x, real alpha_y, real alpha_z, real rOH, real rHH, real rOD) + { + ftype = F_WATER_POL; + fep = false; + iparams.wpol.al_x = alpha_x; + iparams.wpol.al_y = alpha_y; + iparams.wpol.al_z = alpha_z; + iparams.wpol.rOH = rOH; + iparams.wpol.rHH = rHH; + iparams.wpol.rOD = rOD; + return *this; + } }; /*! \brief Utility to fill iatoms struct @@ -496,107 +475,95 @@ struct iListInput * \param[in] ftype Function type * \param[out] iatoms Pointer to iatoms struct */ -void fillIatoms(int ftype, std::vector *iatoms) +void fillIatoms(int ftype, std::vector* iatoms) { - std::unordered_map > ia = - { { 2, { 0, 0, 1, 0, 1, 2, 0, 2, 3 } }, - { 3, { 0, 0, 1, 2, 0, 1, 2, 3 } }, - { 4, { 0, 0, 1, 2, 3 } }, - { 5, { 0, 0, 1, 2, 3, 0 } } }; + std::unordered_map> ia = { { 2, { 0, 0, 1, 0, 1, 2, 0, 2, 3 } }, + { 3, { 0, 0, 1, 2, 0, 1, 2, 3 } }, + { 4, { 0, 0, 1, 2, 3 } }, + { 5, { 0, 0, 1, 2, 3, 0 } } }; EXPECT_TRUE(ftype >= 0 && ftype < F_NRE); int nral = interaction_function[ftype].nratoms; - for (auto &i : ia[nral]) + for (auto& i : ia[nral]) { iatoms->push_back(i); } } -class ListedForcesTest : public ::testing::TestWithParam, int> > +class ListedForcesTest : + public ::testing::TestWithParam, int>> { - protected: - matrix box_; - t_pbc pbc_; - std::vector x_; - int epbc_; - iListInput input_; - test::TestReferenceData refData_; - test::TestReferenceChecker checker_; - ListedForcesTest( ) : - checker_(refData_.rootChecker()) - { - input_ = std::get<0>(GetParam()); - x_ = std::get<1>(GetParam()); - epbc_ = std::get<2>(GetParam()); - clear_mat(box_); - box_[0][0] = box_[1][1] = box_[2][2] = 1.5; - set_pbc(&pbc_, epbc_, box_); - // We need quite specific tolerances here since angle functions - // etc. are not very precise and reproducible. - test::FloatingPointTolerance tolerance(test::FloatingPointTolerance(input_.ftoler, 1.0e-6, - input_.dtoler, 1.0e-12, - 10000, 100, false)); - checker_.setDefaultTolerance(tolerance); - } - void testOneIfunc(test::TestReferenceChecker *checker, - const std::vector &iatoms, - const real lambda) - { - SCOPED_TRACE(std::string("Testing PBC ") + epbc_names[epbc_]); - std::vector ddgatindex = { 0, 1, 2, 3 }; - std::vector chargeA = { 1.5, -2.0, 1.5, -1.0 }; - t_mdatoms mdatoms = {0}; - mdatoms.chargeA = chargeA.data(); - OutputQuantities output; - output.energy = calculateSimpleBond(input_.ftype, - iatoms.size(), - iatoms.data(), - &input_.iparams, - as_rvec_array(x_.data()), - output.f, output.fshift, - &pbc_, - /* const struct t_graph *g */ nullptr, - lambda, &output.dvdlambda, - &mdatoms, - /* struct t_fcdata * */ nullptr, - ddgatindex.data(), - BondedKernelFlavor::ForcesAndVirialAndEnergy); - // Internal consistency test of both test input - // and bonded functions. - EXPECT_TRUE((input_.fep || (output.dvdlambda == 0.0))); - checkOutput(checker, output); - } - void testIfunc() +protected: + matrix box_; + t_pbc pbc_; + std::vector x_; + int epbc_; + iListInput input_; + test::TestReferenceData refData_; + test::TestReferenceChecker checker_; + ListedForcesTest() : checker_(refData_.rootChecker()) + { + input_ = std::get<0>(GetParam()); + x_ = std::get<1>(GetParam()); + epbc_ = std::get<2>(GetParam()); + clear_mat(box_); + box_[0][0] = box_[1][1] = box_[2][2] = 1.5; + set_pbc(&pbc_, epbc_, box_); + // We need quite specific tolerances here since angle functions + // etc. are not very precise and reproducible. + test::FloatingPointTolerance tolerance(test::FloatingPointTolerance( + input_.ftoler, 1.0e-6, input_.dtoler, 1.0e-12, 10000, 100, false)); + checker_.setDefaultTolerance(tolerance); + } + void testOneIfunc(test::TestReferenceChecker* checker, const std::vector& iatoms, const real lambda) + { + SCOPED_TRACE(std::string("Testing PBC ") + epbc_names[epbc_]); + std::vector ddgatindex = { 0, 1, 2, 3 }; + std::vector chargeA = { 1.5, -2.0, 1.5, -1.0 }; + t_mdatoms mdatoms = { 0 }; + mdatoms.chargeA = chargeA.data(); + OutputQuantities output; + output.energy = calculateSimpleBond( + input_.ftype, iatoms.size(), iatoms.data(), &input_.iparams, + as_rvec_array(x_.data()), output.f, output.fshift, &pbc_, + /* const struct t_graph *g */ nullptr, lambda, &output.dvdlambda, &mdatoms, + /* struct t_fcdata * */ nullptr, ddgatindex.data(), + BondedKernelFlavor::ForcesAndVirialAndEnergy); + // Internal consistency test of both test input + // and bonded functions. + EXPECT_TRUE((input_.fep || (output.dvdlambda == 0.0))); + checkOutput(checker, output); + } + void testIfunc() + { + test::TestReferenceChecker thisChecker = + checker_.checkCompound("FunctionType", interaction_function[input_.ftype].name) + .checkCompound("FEP", (input_.fep ? "Yes" : "No")); + std::vector iatoms; + fillIatoms(input_.ftype, &iatoms); + if (input_.fep) { - test::TestReferenceChecker thisChecker = - checker_.checkCompound("FunctionType", - interaction_function[input_.ftype].name).checkCompound("FEP", (input_.fep ? "Yes" : "No")); - std::vector iatoms; - fillIatoms(input_.ftype, &iatoms); - if (input_.fep) - { - const int numLambdas = 3; - for (int i = 0; i < numLambdas; ++i) - { - const real lambda = i / (numLambdas - 1.0); - auto valueChecker = thisChecker.checkCompound("Lambda", toString(lambda)); - testOneIfunc(&valueChecker, iatoms, lambda); - } - } - else + const int numLambdas = 3; + for (int i = 0; i < numLambdas; ++i) { - testOneIfunc(&thisChecker, iatoms, 0.0); + const real lambda = i / (numLambdas - 1.0); + auto valueChecker = thisChecker.checkCompound("Lambda", toString(lambda)); + testOneIfunc(&valueChecker, iatoms, lambda); } } + else + { + testOneIfunc(&thisChecker, iatoms, 0.0); + } + } }; -TEST_P (ListedForcesTest, Ifunc) +TEST_P(ListedForcesTest, Ifunc) { testIfunc(); } //! Function types for testing bonds. Add new terms at the end. -std::vector c_InputBonds = -{ +std::vector c_InputBonds = { { iListInput().setHarmonic(F_BONDS, 0.15, 500.0) }, { iListInput(2e-6F, 1e-8).setHarmonic(F_BONDS, 0.15, 500.0, 0.17, 400.0) }, { iListInput(1e-4F, 1e-8).setHarmonic(F_G96BONDS, 0.15, 50.0) }, @@ -611,8 +578,7 @@ std::vector c_InputBonds = const real cQuarticAngles[5] = { 1.1, 2.3, 4.6, 7.8, 9.2 }; //! Function types for testing angles. Add new terms at the end. -std::vector c_InputAngles = -{ +std::vector c_InputAngles = { { iListInput(2e-3, 1e-8).setHarmonic(F_ANGLES, 100.0, 50.0) }, { iListInput(2e-3, 1e-8).setHarmonic(F_ANGLES, 100.15, 50.0, 95.0, 30.0) }, { iListInput(8e-3, 1e-8).setHarmonic(F_G96ANGLES, 100.0, 50.0) }, @@ -623,7 +589,7 @@ std::vector c_InputAngles = { iListInput(2e-6, 1e-8).setCrossBondAngles(0.8, 0.7, 0.3, 45.0) }, { iListInput(2e-2, 1e-8).setUreyBradley(950.0, 46.0, 0.3, 5.0) }, { iListInput(2e-2, 1e-8).setUreyBradley(100.0, 45.0, 0.3, 5.0, 90.0, 47.0, 0.32, 7.0) }, - { iListInput(2e-3, 1e-8).setQuarticAngles(87.0, cQuarticAngles ) } + { iListInput(2e-3, 1e-8).setQuarticAngles(87.0, cQuarticAngles) } }; //! Constants for Ryckaert-Bellemans A @@ -636,8 +602,7 @@ const real rbcB[NR_RBDIHS] = { -6.35, 12.6, 8.1, -10.7, 0.9, 15.4 }; const real rbc[NR_RBDIHS] = { -7.35, 13.6, 8.4, -16.7, 1.3, 12.4 }; //! Function types for testing dihedrals. Add new terms at the end. -std::vector c_InputDihs = -{ +std::vector c_InputDihs = { { iListInput(1e-4, 1e-8).setPDihedrals(F_PDIHS, -100.0, 10.0, 2, -80.0, 20.0) }, { iListInput(1e-4, 1e-8).setPDihedrals(F_PDIHS, -105.0, 15.0, 2) }, { iListInput(2e-4, 1e-8).setHarmonic(F_IDIHS, 100.0, 50.0) }, @@ -647,8 +612,7 @@ std::vector c_InputDihs = }; //! Function types for testing polarization. Add new terms at the end. -std::vector c_InputPols = -{ +std::vector c_InputPols = { { iListInput(2e-5, 1e-8).setPolarization(0.12) }, { iListInput(1.7e-3, 1e-8).setAnharmPolarization(0.0013, 0.02, 1235.6) }, { iListInput(1.4e-3, 1e-8).setTholePolarization(0.26, 0.07, 0.09, 1.6) }, @@ -656,8 +620,7 @@ std::vector c_InputPols = }; //! Function types for testing polarization. Add new terms at the end. -std::vector c_InputRestraints = -{ +std::vector c_InputRestraints = { { iListInput(1e-4, 1e-8).setPDihedrals(F_ANGRES, -100.0, 10.0, 2, -80.0, 20.0) }, { iListInput(1e-4, 1e-8).setPDihedrals(F_ANGRES, -105.0, 15.0, 2) }, { iListInput(1e-4, 1e-8).setPDihedrals(F_ANGRESZ, -100.0, 10.0, 2, -80.0, 20.0) }, @@ -667,11 +630,10 @@ std::vector c_InputRestraints = }; //! Coordinates for testing -std::vector > c_coordinatesForTests = -{ - {{ 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.2 }, { 0.005, 0.0, 0.1 }, { -0.001, 0.1, 0.0 }}, - {{ 0.5, 0.0, 0.0 }, { 0.5, 0.0, 0.15 }, { 0.5, 0.07, 0.22 }, { 0.5, 0.18, 0.22 }}, - {{ -0.1143, -0.0282, 0.0 }, { 0.0, 0.0434, 0.0 }, { 0.1185, -0.0138, 0.0 }, { -0.0195, 0.1498, 0.0 }} +std::vector> c_coordinatesForTests = { + { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.2 }, { 0.005, 0.0, 0.1 }, { -0.001, 0.1, 0.0 } }, + { { 0.5, 0.0, 0.0 }, { 0.5, 0.0, 0.15 }, { 0.5, 0.07, 0.22 }, { 0.5, 0.18, 0.22 } }, + { { -0.1143, -0.0282, 0.0 }, { 0.0, 0.0434, 0.0 }, { 0.1185, -0.0138, 0.0 }, { -0.0195, 0.1498, 0.0 } } }; //! PBC values for testing @@ -679,16 +641,36 @@ std::vector c_pbcForTests = { epbcNONE, epbcXY, epbcXYZ }; // Those tests give errors with the intel compiler and nothing else, so we disable them only there. #ifndef __INTEL_COMPILER -INSTANTIATE_TEST_CASE_P(Bond, ListedForcesTest, ::testing::Combine(::testing::ValuesIn(c_InputBonds), ::testing::ValuesIn(c_coordinatesForTests), ::testing::ValuesIn(c_pbcForTests))); - -INSTANTIATE_TEST_CASE_P(Angle, ListedForcesTest, ::testing::Combine(::testing::ValuesIn(c_InputAngles), ::testing::ValuesIn(c_coordinatesForTests), ::testing::ValuesIn(c_pbcForTests))); - -INSTANTIATE_TEST_CASE_P(Dihedral, ListedForcesTest, ::testing::Combine(::testing::ValuesIn(c_InputDihs), ::testing::ValuesIn(c_coordinatesForTests), ::testing::ValuesIn(c_pbcForTests))); - -INSTANTIATE_TEST_CASE_P(Polarize, ListedForcesTest, ::testing::Combine(::testing::ValuesIn(c_InputPols), ::testing::ValuesIn(c_coordinatesForTests), ::testing::ValuesIn(c_pbcForTests))); - -INSTANTIATE_TEST_CASE_P(Restraints, ListedForcesTest, ::testing::Combine(::testing::ValuesIn(c_InputRestraints), ::testing::ValuesIn(c_coordinatesForTests), ::testing::ValuesIn(c_pbcForTests))); +INSTANTIATE_TEST_CASE_P(Bond, + ListedForcesTest, + ::testing::Combine(::testing::ValuesIn(c_InputBonds), + ::testing::ValuesIn(c_coordinatesForTests), + ::testing::ValuesIn(c_pbcForTests))); + +INSTANTIATE_TEST_CASE_P(Angle, + ListedForcesTest, + ::testing::Combine(::testing::ValuesIn(c_InputAngles), + ::testing::ValuesIn(c_coordinatesForTests), + ::testing::ValuesIn(c_pbcForTests))); + +INSTANTIATE_TEST_CASE_P(Dihedral, + ListedForcesTest, + ::testing::Combine(::testing::ValuesIn(c_InputDihs), + ::testing::ValuesIn(c_coordinatesForTests), + ::testing::ValuesIn(c_pbcForTests))); + +INSTANTIATE_TEST_CASE_P(Polarize, + ListedForcesTest, + ::testing::Combine(::testing::ValuesIn(c_InputPols), + ::testing::ValuesIn(c_coordinatesForTests), + ::testing::ValuesIn(c_pbcForTests))); + +INSTANTIATE_TEST_CASE_P(Restraints, + ListedForcesTest, + ::testing::Combine(::testing::ValuesIn(c_InputRestraints), + ::testing::ValuesIn(c_coordinatesForTests), + ::testing::ValuesIn(c_pbcForTests))); #endif -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/listed_forces/utilities.h b/src/gromacs/listed_forces/utilities.h index 3f4efac784..aee43d9ac9 100644 --- a/src/gromacs/listed_forces/utilities.h +++ b/src/gromacs/listed_forces/utilities.h @@ -52,12 +52,10 @@ * * \todo This function could go away when idef is not a big bucket of * everything. */ -static bool -ftype_is_bonded_potential(int ftype) +static bool ftype_is_bonded_potential(int ftype) { - return - ((interaction_function[ftype].flags & IF_BOND) != 0U) && - !(ftype == F_CONNBONDS || ftype == F_POSRES || ftype == F_FBPOSRES); + return ((interaction_function[ftype].flags & IF_BOND) != 0U) + && !(ftype == F_CONNBONDS || ftype == F_POSRES || ftype == F_FBPOSRES); } #endif diff --git a/src/gromacs/math/3dtransforms.cpp b/src/gromacs/math/3dtransforms.cpp index 05f62d8a61..cc2b0a1409 100644 --- a/src/gromacs/math/3dtransforms.cpp +++ b/src/gromacs/math/3dtransforms.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,7 +63,7 @@ void gmx_mat4_transform_point(mat4 m, const rvec x, vec4 v) for (i = 0; (i < N); i++) { - v[i] = m[XX][i]*x[XX]+m[YY][i]*x[YY]+m[ZZ][i]*x[ZZ]+m[WW][i]; + v[i] = m[XX][i] * x[XX] + m[YY][i] * x[YY] + m[ZZ][i] * x[ZZ] + m[WW][i]; } } @@ -78,7 +78,7 @@ void gmx_mat4_mmul(mat4 A, mat4 B, mat4 C) A[i][j] = 0; for (k = 0; (k < N); k++) { - A[i][j] += B[i][k]*C[k][j]; + A[i][j] += B[i][k] * C[k][j]; } } } @@ -111,25 +111,24 @@ void gmx_mat4_init_rotation(int axis, real angle, mat4 A) switch (axis) { case XX: - A[YY][YY] = cos(angle); + A[YY][YY] = cos(angle); A[YY][ZZ] = -sin(angle); - A[ZZ][YY] = sin(angle); - A[ZZ][ZZ] = cos(angle); + A[ZZ][YY] = sin(angle); + A[ZZ][ZZ] = cos(angle); break; case YY: - A[XX][XX] = cos(angle); - A[XX][ZZ] = sin(angle); + A[XX][XX] = cos(angle); + A[XX][ZZ] = sin(angle); A[ZZ][XX] = -sin(angle); - A[ZZ][ZZ] = cos(angle); + A[ZZ][ZZ] = cos(angle); break; case ZZ: - A[XX][XX] = cos(angle); + A[XX][XX] = cos(angle); A[XX][YY] = -sin(angle); - A[YY][XX] = sin(angle); - A[YY][YY] = cos(angle); + A[YY][XX] = sin(angle); + A[YY][YY] = cos(angle); break; - default: - gmx_fatal(FARGS, "Error: invalid axis: %d", axis); + default: gmx_fatal(FARGS, "Error: invalid axis: %d", axis); } } @@ -141,7 +140,7 @@ void gmx_mat4_init_translation(real tx, real ty, real tz, mat4 A) A[3][ZZ] = tz; } -void gmx_mat4_print(FILE *fp, const char *s, mat4 A) +void gmx_mat4_print(FILE* fp, const char* s, mat4 A) { int i, j; @@ -160,7 +159,7 @@ void gmx_mat4_print(FILE *fp, const char *s, mat4 A) } } -void gmx_vec4_print(FILE *fp, const char *s, vec4 a) +void gmx_vec4_print(FILE* fp, const char* s, vec4 a) { int j; diff --git a/src/gromacs/math/3dtransforms.h b/src/gromacs/math/3dtransforms.h index 45293d4334..3b146b35cf 100644 --- a/src/gromacs/math/3dtransforms.h +++ b/src/gromacs/math/3dtransforms.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -76,8 +76,8 @@ void gmx_mat4_init_rotation(int axis, real angle, mat4 A); void gmx_mat4_init_translation(real tx, real ty, real tz, mat4 A); -void gmx_mat4_print(FILE *fp, const char *s, mat4 A); +void gmx_mat4_print(FILE* fp, const char* s, mat4 A); -void gmx_vec4_print(FILE *fp, const char *s, vec4 a); +void gmx_vec4_print(FILE* fp, const char* s, vec4 a); #endif diff --git a/src/gromacs/math/arrayrefwithpadding.h b/src/gromacs/math/arrayrefwithpadding.h index 148eda69d3..3e5f535c6c 100644 --- a/src/gromacs/math/arrayrefwithpadding.h +++ b/src/gromacs/math/arrayrefwithpadding.h @@ -68,129 +68,123 @@ namespace gmx * \inlibraryapi * \ingroup module_math */ -template +template class ArrayRefWithPadding { - public: - //! Type of values stored in the reference. - using value_type = T; - //! Type for representing size of the reference. - using size_type = index; - //! Const pointer to an element. - using const_pointer = const T*; - //! Const iterator type to an element. - using const_iterator = const T*; - //! Pointer to an element. - using pointer = T*; - //! Iterator type to an element. - using iterator = T*; +public: + //! Type of values stored in the reference. + using value_type = T; + //! Type for representing size of the reference. + using size_type = index; + //! Const pointer to an element. + using const_pointer = const T*; + //! Const iterator type to an element. + using const_iterator = const T*; + //! Pointer to an element. + using pointer = T*; + //! Iterator type to an element. + using iterator = T*; - /*! \brief - * Constructs an empty reference. - */ - ArrayRefWithPadding() - : begin_(nullptr), end_(nullptr), paddedEnd_(nullptr) {} - /*! \brief - * Constructs a reference to a particular range. - * - * \param[in] begin Pointer to the beginning of a range. - * \param[in] end Pointer to the end of a range without padding. - * \param[in] paddedEnd Pointer to the end of a range including padding. - * - * Passed pointers must remain valid for the lifetime of this object. - */ - ArrayRefWithPadding(pointer begin, pointer end, pointer paddedEnd) - : begin_(begin), end_(end), paddedEnd_(paddedEnd) + /*! \brief + * Constructs an empty reference. + */ + ArrayRefWithPadding() : begin_(nullptr), end_(nullptr), paddedEnd_(nullptr) {} + /*! \brief + * Constructs a reference to a particular range. + * + * \param[in] begin Pointer to the beginning of a range. + * \param[in] end Pointer to the end of a range without padding. + * \param[in] paddedEnd Pointer to the end of a range including padding. + * + * Passed pointers must remain valid for the lifetime of this object. + */ + ArrayRefWithPadding(pointer begin, pointer end, pointer paddedEnd) : + begin_(begin), + end_(end), + paddedEnd_(paddedEnd) + { + GMX_ASSERT(end >= begin, "Invalid range"); + GMX_ASSERT(paddedEnd >= end, "Invalid range"); + } + //! Copy constructor + ArrayRefWithPadding(const ArrayRefWithPadding& o) : + begin_(o.begin_), + end_(o.end_), + paddedEnd_(o.paddedEnd_) + { + } + //! Move constructor + ArrayRefWithPadding(ArrayRefWithPadding&& o) noexcept : + begin_(std::move(o.begin_)), + end_(std::move(o.end_)), + paddedEnd_(std::move(o.paddedEnd_)) + { + } + //! Convenience overload constructor to make an ArrayRefWithPadding from a non-const one. + template::value_type>::value>> + ArrayRefWithPadding(U&& o) + { + auto constArrayRefWithPadding = o.constArrayRefWithPadding(); + this->swap(constArrayRefWithPadding); + } + //! Copy assignment operator + ArrayRefWithPadding& operator=(ArrayRefWithPadding const& o) + { + if (&o != this) { - GMX_ASSERT(end >= begin, "Invalid range"); - GMX_ASSERT(paddedEnd >= end, "Invalid range"); + begin_ = o.begin_; + end_ = o.end_; + paddedEnd_ = o.paddedEnd_; } - //! Copy constructor - ArrayRefWithPadding(const ArrayRefWithPadding &o) - : begin_(o.begin_), end_(o.end_), paddedEnd_(o.paddedEnd_) {} - //! Move constructor - ArrayRefWithPadding(ArrayRefWithPadding &&o) noexcept - : begin_(std::move(o.begin_)), end_(std::move(o.end_)), paddedEnd_(std::move(o.paddedEnd_)) {} - //! Convenience overload constructor to make an ArrayRefWithPadding from a non-const one. - template::value_type>::value> > - ArrayRefWithPadding(U &&o) + return *this; + } + //! Move assignment operator + ArrayRefWithPadding& operator=(ArrayRefWithPadding&& o) noexcept + { + if (&o != this) { - auto constArrayRefWithPadding = o.constArrayRefWithPadding(); - this->swap(constArrayRefWithPadding); - } - //! Copy assignment operator - ArrayRefWithPadding &operator=(ArrayRefWithPadding const &o) - { - if (&o != this) - { - begin_ = o.begin_; - end_ = o.end_; - paddedEnd_ = o.paddedEnd_; - } - return *this; - } - //! Move assignment operator - ArrayRefWithPadding &operator=(ArrayRefWithPadding &&o) noexcept - { - if (&o != this) - { - begin_ = std::move(o.begin_); - end_ = std::move(o.end_); - paddedEnd_ = std::move(o.paddedEnd_); - } - return *this; + begin_ = std::move(o.begin_); + end_ = std::move(o.end_); + paddedEnd_ = std::move(o.paddedEnd_); } + return *this; + } - //! Return the size of the view, i.e with the padding. - size_type size() const { return paddedEnd_ - begin_; } - //! Whether the reference refers to no memory. - bool empty() const { return begin_ == end_; } + //! Return the size of the view, i.e with the padding. + size_type size() const { return paddedEnd_ - begin_; } + //! Whether the reference refers to no memory. + bool empty() const { return begin_ == end_; } - //! Returns an ArrayRef of elements that does not include the padding region. - ArrayRef unpaddedArrayRef() - { - return {begin_, end_}; - } - //! Returns an ArrayRef of const elements that does not include the padding region. - ArrayRef unpaddedConstArrayRef() const - { - return {begin_, end_}; - } - //! Returns an ArrayRef of elements that does include the padding region. - ArrayRef paddedArrayRef() - { - return {begin_, paddedEnd_}; - } - //! Returns an ArrayRef of const elements that does include the padding region. - ArrayRef paddedConstArrayRef() const - { - return {begin_, paddedEnd_}; - } - //! Returns an identical ArrayRefWithPadding that refers to const elements. - ArrayRefWithPadding constArrayRefWithPadding() const - { - return {begin_, end_, paddedEnd_}; - } - /*! \brief - * Swaps referenced memory with the other object. - * - * The actual memory areas are not modified, only the references are - * swapped. - */ - void swap(ArrayRefWithPadding &other) - { - std::swap(begin_, other.begin_); - std::swap(end_, other.end_); - std::swap(paddedEnd_, other.paddedEnd_); - } + //! Returns an ArrayRef of elements that does not include the padding region. + ArrayRef unpaddedArrayRef() { return { begin_, end_ }; } + //! Returns an ArrayRef of const elements that does not include the padding region. + ArrayRef unpaddedConstArrayRef() const { return { begin_, end_ }; } + //! Returns an ArrayRef of elements that does include the padding region. + ArrayRef paddedArrayRef() { return { begin_, paddedEnd_ }; } + //! Returns an ArrayRef of const elements that does include the padding region. + ArrayRef paddedConstArrayRef() const { return { begin_, paddedEnd_ }; } + //! Returns an identical ArrayRefWithPadding that refers to const elements. + ArrayRefWithPadding constArrayRefWithPadding() const + { + return { begin_, end_, paddedEnd_ }; + } + /*! \brief + * Swaps referenced memory with the other object. + * + * The actual memory areas are not modified, only the references are + * swapped. + */ + void swap(ArrayRefWithPadding& other) + { + std::swap(begin_, other.begin_); + std::swap(end_, other.end_); + std::swap(paddedEnd_, other.paddedEnd_); + } - private: - pointer begin_; - pointer end_; - pointer paddedEnd_; +private: + pointer begin_; + pointer end_; + pointer paddedEnd_; }; } // namespace gmx diff --git a/src/gromacs/math/coordinatetransformation.cpp b/src/gromacs/math/coordinatetransformation.cpp index 6d057d4c67..c380efecf3 100644 --- a/src/gromacs/math/coordinatetransformation.cpp +++ b/src/gromacs/math/coordinatetransformation.cpp @@ -53,20 +53,18 @@ namespace gmx class ScaleCoordinates::Impl { - public: - Impl(const RVec &scale); - void inverseIgnoringZeroScale(ArrayRef coordinates) const; - void scale(ArrayRef coordinates) const; - private: - RVec scale_; -}; -ScaleCoordinates::Impl::Impl(const RVec &scale) : scale_ { scale } -{ +public: + Impl(const RVec& scale); + void inverseIgnoringZeroScale(ArrayRef coordinates) const; + void scale(ArrayRef coordinates) const; -} +private: + RVec scale_; +}; +ScaleCoordinates::Impl::Impl(const RVec& scale) : scale_{ scale } {} void ScaleCoordinates::Impl::scale(ArrayRef coordinates) const { - for (auto &coordinate : coordinates) + for (auto& coordinate : coordinates) { coordinate[XX] *= scale_[XX]; coordinate[YY] *= scale_[YY]; @@ -82,7 +80,7 @@ void ScaleCoordinates::Impl::inverseIgnoringZeroScale(ArrayRef coordinates inverseScale[dimension] = scale_[dimension] != 0 ? 1. / scale_[dimension] : 1.; } - for (auto &coordinate : coordinates) + for (auto& coordinate : coordinates) { coordinate[XX] *= inverseScale[XX]; coordinate[YY] *= inverseScale[YY]; @@ -94,10 +92,7 @@ void ScaleCoordinates::Impl::inverseIgnoringZeroScale(ArrayRef coordinates * ScaleCoordinates */ -ScaleCoordinates::ScaleCoordinates(const RVec &scale) : impl_ {new Impl(scale)} -{ - -} +ScaleCoordinates::ScaleCoordinates(const RVec& scale) : impl_{ new Impl(scale) } {} void ScaleCoordinates::operator()(ArrayRef coordinates) const { @@ -111,20 +106,17 @@ void ScaleCoordinates::inverseIgnoringZeroScale(ArrayRef coordinates) cons ScaleCoordinates::~ScaleCoordinates() = default; -ScaleCoordinates::ScaleCoordinates(const ScaleCoordinates &other) - : impl_(new Impl(*other.impl_)) -{ -} +ScaleCoordinates::ScaleCoordinates(const ScaleCoordinates& other) : impl_(new Impl(*other.impl_)) {} -ScaleCoordinates &ScaleCoordinates::operator=(const ScaleCoordinates &other) +ScaleCoordinates& ScaleCoordinates::operator=(const ScaleCoordinates& other) { *impl_ = *other.impl_; return *this; } -ScaleCoordinates::ScaleCoordinates(ScaleCoordinates &&) noexcept = default; +ScaleCoordinates::ScaleCoordinates(ScaleCoordinates&&) noexcept = default; -ScaleCoordinates &ScaleCoordinates::operator=(ScaleCoordinates &&) noexcept = default; +ScaleCoordinates& ScaleCoordinates::operator=(ScaleCoordinates&&) noexcept = default; /******************************************************************** * TranslateAndScale::Impl @@ -132,25 +124,24 @@ ScaleCoordinates &ScaleCoordinates::operator=(ScaleCoordinates &&) noexcept = de class TranslateAndScale::Impl { - public: - Impl(const RVec &scale, const RVec &translation); - void transform(ArrayRef coordinates) const; - RVec scale_; - RVec translation_; +public: + Impl(const RVec& scale, const RVec& translation); + void transform(ArrayRef coordinates) const; + RVec scale_; + RVec translation_; }; -TranslateAndScale::Impl::Impl(const RVec &scale, const RVec &translation) : - scale_ {scale}, translation_ { - translation -} +TranslateAndScale::Impl::Impl(const RVec& scale, const RVec& translation) : + scale_{ scale }, + translation_{ translation } { } void TranslateAndScale::Impl::transform(ArrayRef coordinates) const { - for (auto &coordinate : coordinates) + for (auto& coordinate : coordinates) { - coordinate += translation_; + coordinate += translation_; coordinate[XX] *= scale_[XX]; coordinate[YY] *= scale_[YY]; coordinate[ZZ] *= scale_[ZZ]; @@ -162,7 +153,7 @@ void TranslateAndScale::Impl::transform(ArrayRef coordinates) const * TranslateAndScale */ -TranslateAndScale::TranslateAndScale(const RVec &scale, const RVec &translation) : +TranslateAndScale::TranslateAndScale(const RVec& scale, const RVec& translation) : impl_(new Impl(scale, translation)) { } @@ -174,27 +165,24 @@ void TranslateAndScale::operator()(ArrayRef coordinates) const ScaleCoordinates TranslateAndScale::scaleOperationOnly() const { - return ScaleCoordinates { - impl_->scale_ - }; + return ScaleCoordinates{ impl_->scale_ }; } TranslateAndScale::~TranslateAndScale() = default; -TranslateAndScale::TranslateAndScale(const TranslateAndScale &other) - : impl_(new Impl(*other.impl_)) +TranslateAndScale::TranslateAndScale(const TranslateAndScale& other) : impl_(new Impl(*other.impl_)) { } -TranslateAndScale &TranslateAndScale::operator=(const TranslateAndScale &other) +TranslateAndScale& TranslateAndScale::operator=(const TranslateAndScale& other) { *impl_ = *other.impl_; return *this; } -TranslateAndScale::TranslateAndScale(TranslateAndScale &&) noexcept = default; +TranslateAndScale::TranslateAndScale(TranslateAndScale&&) noexcept = default; -TranslateAndScale &TranslateAndScale::operator=(TranslateAndScale &&) noexcept = default; +TranslateAndScale& TranslateAndScale::operator=(TranslateAndScale&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/math/coordinatetransformation.h b/src/gromacs/math/coordinatetransformation.h index e31fae9df1..5e962fc92f 100644 --- a/src/gromacs/math/coordinatetransformation.h +++ b/src/gromacs/math/coordinatetransformation.h @@ -52,31 +52,32 @@ namespace gmx class ScaleCoordinates { - public: - //! Set up coordinate scaling with the scaling factor in each dimension - explicit ScaleCoordinates(const RVec &scale); - ~ScaleCoordinates(); +public: + //! Set up coordinate scaling with the scaling factor in each dimension + explicit ScaleCoordinates(const RVec& scale); + ~ScaleCoordinates(); - //! Copy constructor - ScaleCoordinates(const ScaleCoordinates &other); - //! Copy assignment - ScaleCoordinates &operator=(const ScaleCoordinates &other); - //! Move constructor - ScaleCoordinates(ScaleCoordinates &&other) noexcept; - //! Move assignment - ScaleCoordinates &operator=(ScaleCoordinates &&other) noexcept; + //! Copy constructor + ScaleCoordinates(const ScaleCoordinates& other); + //! Copy assignment + ScaleCoordinates& operator=(const ScaleCoordinates& other); + //! Move constructor + ScaleCoordinates(ScaleCoordinates&& other) noexcept; + //! Move assignment + ScaleCoordinates& operator=(ScaleCoordinates&& other) noexcept; - /*! \brief Perform a coordinate transformation on input coordinates. - * \param[in] coordinates to be transformed - */ - void operator()(ArrayRef coordinates) const; - /*! \brief Apply the inverse scale to coordinates, ignoring dimensions for which scale is zero. - * \param[in] coordinates to be transformed - */ - void inverseIgnoringZeroScale(ArrayRef coordinates) const; - private: - class Impl; - PrivateImplPointer impl_; + /*! \brief Perform a coordinate transformation on input coordinates. + * \param[in] coordinates to be transformed + */ + void operator()(ArrayRef coordinates) const; + /*! \brief Apply the inverse scale to coordinates, ignoring dimensions for which scale is zero. + * \param[in] coordinates to be transformed + */ + void inverseIgnoringZeroScale(ArrayRef coordinates) const; + +private: + class Impl; + PrivateImplPointer impl_; }; /*! \libinternal \brief Transform coordinates in three dimensions by first @@ -84,38 +85,37 @@ class ScaleCoordinates */ class TranslateAndScale { - public: - - /*! \brief Construct a three-dimensional coordinate transformation. - * Coordinates are first translated, then scaled. - * \param[in] translation to be performed on the coordinates - * \param[in] scale to be applied to the coordinates - */ - TranslateAndScale(const RVec &scale, const RVec &translation); +public: + /*! \brief Construct a three-dimensional coordinate transformation. + * Coordinates are first translated, then scaled. + * \param[in] translation to be performed on the coordinates + * \param[in] scale to be applied to the coordinates + */ + TranslateAndScale(const RVec& scale, const RVec& translation); - ~TranslateAndScale(); + ~TranslateAndScale(); - //! Copy constructor - TranslateAndScale(const TranslateAndScale &other); - //! Copy assignment - TranslateAndScale &operator=(const TranslateAndScale &other); - //! Move constructor - TranslateAndScale(TranslateAndScale &&other) noexcept; - //! Move assignment - TranslateAndScale &operator=(TranslateAndScale &&other) noexcept; + //! Copy constructor + TranslateAndScale(const TranslateAndScale& other); + //! Copy assignment + TranslateAndScale& operator=(const TranslateAndScale& other); + //! Move constructor + TranslateAndScale(TranslateAndScale&& other) noexcept; + //! Move assignment + TranslateAndScale& operator=(TranslateAndScale&& other) noexcept; - /*! \brief Perform a coordinate transformation on input coordinates. - * \param[in] coordinates to be transformed - */ - void operator()(ArrayRef coordinates) const; + /*! \brief Perform a coordinate transformation on input coordinates. + * \param[in] coordinates to be transformed + */ + void operator()(ArrayRef coordinates) const; - /*! \brief Returns the scaling operation, discarding the translation. - */ - ScaleCoordinates scaleOperationOnly() const; + /*! \brief Returns the scaling operation, discarding the translation. + */ + ScaleCoordinates scaleOperationOnly() const; - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; -} // namespace gmx +} // namespace gmx #endif // CoordinateTransformation diff --git a/src/gromacs/math/densityfit.cpp b/src/gromacs/math/densityfit.cpp index 43c26a52d2..a9ae79c5e7 100644 --- a/src/gromacs/math/densityfit.cpp +++ b/src/gromacs/math/densityfit.cpp @@ -55,16 +55,16 @@ namespace gmx class DensitySimilarityMeasureImpl { - public: - virtual ~DensitySimilarityMeasureImpl(); - //! convenience typedef - using density = DensitySimilarityMeasure::density; - //! \copydoc DensitySimilarityMeasure::gradient(DensitySimilarityMeasure::density comparedDensity) - virtual density gradient(density comparedDensity) = 0; - //! \copydoc DensitySimilarityMeasure::similarity(density comparedDensity) - virtual real similarity(density comparedDensity) = 0; - //! clone to allow copy operations - virtual std::unique_ptr clone() = 0; +public: + virtual ~DensitySimilarityMeasureImpl(); + //! convenience typedef + using density = DensitySimilarityMeasure::density; + //! \copydoc DensitySimilarityMeasure::gradient(DensitySimilarityMeasure::density comparedDensity) + virtual density gradient(density comparedDensity) = 0; + //! \copydoc DensitySimilarityMeasure::similarity(density comparedDensity) + virtual real similarity(density comparedDensity) = 0; + //! clone to allow copy operations + virtual std::unique_ptr clone() = 0; }; DensitySimilarityMeasureImpl::~DensitySimilarityMeasureImpl() = default; @@ -80,33 +80,32 @@ namespace */ class DensitySimilarityInnerProduct final : public DensitySimilarityMeasureImpl { - public: - //! Construct similarity measure by setting the reference density - DensitySimilarityInnerProduct(density referenceDensity); - //! The gradient for the inner product similarity measure is the reference density divided by the number of voxels - density gradient(density comparedDensity) override; - //! Clone this - std::unique_ptr clone() override; - //! The similarity between reference density and compared density - real similarity(density comparedDensity) override; - private: - //! A view on the reference density - const density referenceDensity_; - //! Stores the gradient of the similarity measure in memory - MultiDimArray, dynamicExtents3D> gradient_; +public: + //! Construct similarity measure by setting the reference density + DensitySimilarityInnerProduct(density referenceDensity); + //! The gradient for the inner product similarity measure is the reference density divided by the number of voxels + density gradient(density comparedDensity) override; + //! Clone this + std::unique_ptr clone() override; + //! The similarity between reference density and compared density + real similarity(density comparedDensity) override; + +private: + //! A view on the reference density + const density referenceDensity_; + //! Stores the gradient of the similarity measure in memory + MultiDimArray, dynamicExtents3D> gradient_; }; DensitySimilarityInnerProduct::DensitySimilarityInnerProduct(density referenceDensity) : - referenceDensity_ {referenceDensity }, -gradient_ { - referenceDensity.extents() -} + referenceDensity_{ referenceDensity }, + gradient_{ referenceDensity.extents() } { const auto numVoxels = gradient_.asConstView().mapping().required_span_size(); /* the gradient for the inner product measure of fit is constant and does not * depend on the compared density, so it is pre-computed here */ std::transform(begin(referenceDensity_), end(referenceDensity), begin(gradient_), - [numVoxels](float x){return x/numVoxels; }); + [numVoxels](float x) { return x / numVoxels; }); } real DensitySimilarityInnerProduct::similarity(density comparedDensity) @@ -144,7 +143,7 @@ real relativeEntropyAtVoxel(real reference, real comparison) { if ((reference > 0) && (comparison > 0)) { - return reference * (std::log(comparison/reference)); + return reference * (std::log(comparison / reference)); } return 0.; } @@ -154,7 +153,7 @@ real relativeEntropyGradientAtVoxel(real reference, real comparison) { if ((reference > 0) && (comparison > 0)) { - return reference/comparison; + return reference / comparison; } return 0.; } @@ -166,25 +165,26 @@ real relativeEntropyGradientAtVoxel(real reference, real comparison) */ class DensitySimilarityRelativeEntropy final : public DensitySimilarityMeasureImpl { - public: - //! Construct similarity measure by setting the reference density - DensitySimilarityRelativeEntropy(density referenceDensity); - //! The gradient for the relative entropy similarity measure - density gradient(density comparedDensity) override; - //! Clone this - std::unique_ptr clone() override; - //! The similarity between reference density and compared density - real similarity(density comparedDensity) override; - private: - //! A view on the reference density - const density referenceDensity_; - //! Stores the gradient of the similarity measure in memory - MultiDimArray, dynamicExtents3D> gradient_; +public: + //! Construct similarity measure by setting the reference density + DensitySimilarityRelativeEntropy(density referenceDensity); + //! The gradient for the relative entropy similarity measure + density gradient(density comparedDensity) override; + //! Clone this + std::unique_ptr clone() override; + //! The similarity between reference density and compared density + real similarity(density comparedDensity) override; + +private: + //! A view on the reference density + const density referenceDensity_; + //! Stores the gradient of the similarity measure in memory + MultiDimArray, dynamicExtents3D> gradient_; }; DensitySimilarityRelativeEntropy::DensitySimilarityRelativeEntropy(density referenceDensity) : - referenceDensity_ {referenceDensity }, -gradient_(referenceDensity.extents()) + referenceDensity_{ referenceDensity }, + gradient_(referenceDensity.extents()) { } @@ -220,15 +220,15 @@ std::unique_ptr DensitySimilarityRelativeEntropy:: struct CrossCorrelationEvaluationHelperValues { //! The mean of the reference density - real meanReference = 0; + real meanReference = 0; //! The mean of the compared density - real meanComparison = 0; + real meanComparison = 0; //! The sum of the squared reference density voxel values - real referenceSquaredSum = 0; + real referenceSquaredSum = 0; //! The sum of the squared compared density voxel values - real comparisonSquaredSum = 0; + real comparisonSquaredSum = 0; //! The covariance of the refernce and the compared density - real covariance = 0; + real covariance = 0; }; /*! \brief Calculate helper values for the cross-correlation. @@ -238,24 +238,23 @@ struct CrossCorrelationEvaluationHelperValues * "Numerically Stable, Single-Pass, Parallel Statistics Algorithms" * and implemented in boost's correlation coefficient */ -CrossCorrelationEvaluationHelperValues -evaluateHelperValues(DensitySimilarityMeasure::density reference, - DensitySimilarityMeasure::density compared) +CrossCorrelationEvaluationHelperValues evaluateHelperValues(DensitySimilarityMeasure::density reference, + DensitySimilarityMeasure::density compared) { CrossCorrelationEvaluationHelperValues helperValues; index i = 0; - auto referenceIterator = begin(reference); + auto referenceIterator = begin(reference); for (const real comp : compared) { const real refHelper = *referenceIterator - helperValues.meanReference; const real comparisonHelper = comp - helperValues.meanComparison; - helperValues.referenceSquaredSum += (i * square(refHelper)) / (i + 1); + helperValues.referenceSquaredSum += (i * square(refHelper)) / (i + 1); helperValues.comparisonSquaredSum += (i * square(comparisonHelper)) / (i + 1); - helperValues.covariance += i * refHelper * comparisonHelper / (i + 1); - helperValues.meanReference += refHelper / (i + 1); - helperValues.meanComparison += comparisonHelper / (i + 1); + helperValues.covariance += i * refHelper * comparisonHelper / (i + 1); + helperValues.meanReference += refHelper / (i + 1); + helperValues.meanComparison += comparisonHelper / (i + 1); ++referenceIterator; ++i; @@ -267,33 +266,35 @@ evaluateHelperValues(DensitySimilarityMeasure::density reference, //! Calculate a single cross correlation gradient entry at a voxel. class CrossCorrelationGradientAtVoxel { - public: - - //! Set up the gradident calculation with pre-computed values - CrossCorrelationGradientAtVoxel(const CrossCorrelationEvaluationHelperValues &preComputed) - : prefactor_(evaluatePrefactor(preComputed.comparisonSquaredSum, preComputed.referenceSquaredSum)), - comparisonPrefactor_(preComputed.covariance / preComputed.comparisonSquaredSum), - meanReference_(preComputed.meanReference), meanComparison_(preComputed.meanComparison) - { - } - //! Evaluate the cross correlation gradient at a voxel - real operator()(real reference, real comparison) - { - return prefactor_ * (reference - meanReference_ - comparisonPrefactor_ * (comparison-meanComparison_)); - } - private: - real evaluatePrefactor(real comparisonSquaredSum, real referenceSquaredSum) - { - GMX_ASSERT(comparisonSquaredSum > 0, - "Squared sum of comparison values needs to be larger than zero."); - GMX_ASSERT(referenceSquaredSum > 0, - "Squared sum of reference values needs to be larger than zero."); - return 1.0 / (sqrt(comparisonSquaredSum) * sqrt(referenceSquaredSum)); - } - const real prefactor_; - const real comparisonPrefactor_; - const real meanReference_; - const real meanComparison_; +public: + //! Set up the gradident calculation with pre-computed values + CrossCorrelationGradientAtVoxel(const CrossCorrelationEvaluationHelperValues& preComputed) : + prefactor_(evaluatePrefactor(preComputed.comparisonSquaredSum, preComputed.referenceSquaredSum)), + comparisonPrefactor_(preComputed.covariance / preComputed.comparisonSquaredSum), + meanReference_(preComputed.meanReference), + meanComparison_(preComputed.meanComparison) + { + } + //! Evaluate the cross correlation gradient at a voxel + real operator()(real reference, real comparison) + { + return prefactor_ + * (reference - meanReference_ - comparisonPrefactor_ * (comparison - meanComparison_)); + } + +private: + real evaluatePrefactor(real comparisonSquaredSum, real referenceSquaredSum) + { + GMX_ASSERT(comparisonSquaredSum > 0, + "Squared sum of comparison values needs to be larger than zero."); + GMX_ASSERT(referenceSquaredSum > 0, + "Squared sum of reference values needs to be larger than zero."); + return 1.0 / (sqrt(comparisonSquaredSum) * sqrt(referenceSquaredSum)); + } + const real prefactor_; + const real comparisonPrefactor_; + const real meanReference_; + const real meanComparison_; }; /*! \internal @@ -303,25 +304,26 @@ class CrossCorrelationGradientAtVoxel */ class DensitySimilarityCrossCorrelation final : public DensitySimilarityMeasureImpl { - public: - //! Construct similarity measure by setting the reference density - DensitySimilarityCrossCorrelation(density referenceDensity); - //! The gradient for the cross correlation similarity measure - density gradient(density comparedDensity) override; - //! Clone this - std::unique_ptr clone() override; - //! The similarity between reference density and compared density - real similarity(density comparedDensity) override; - - private: - //! A view on the reference density - const density referenceDensity_; - //! Stores the gradient of the similarity measure in memory - MultiDimArray, dynamicExtents3D> gradient_; +public: + //! Construct similarity measure by setting the reference density + DensitySimilarityCrossCorrelation(density referenceDensity); + //! The gradient for the cross correlation similarity measure + density gradient(density comparedDensity) override; + //! Clone this + std::unique_ptr clone() override; + //! The similarity between reference density and compared density + real similarity(density comparedDensity) override; + +private: + //! A view on the reference density + const density referenceDensity_; + //! Stores the gradient of the similarity measure in memory + MultiDimArray, dynamicExtents3D> gradient_; }; -DensitySimilarityCrossCorrelation::DensitySimilarityCrossCorrelation(density referenceDensity) - : referenceDensity_ { referenceDensity }, gradient_(referenceDensity.extents()) +DensitySimilarityCrossCorrelation::DensitySimilarityCrossCorrelation(density referenceDensity) : + referenceDensity_{ referenceDensity }, + gradient_(referenceDensity.extents()) { } @@ -332,7 +334,8 @@ real DensitySimilarityCrossCorrelation::similarity(density comparedDensity) GMX_THROW(RangeError("Reference density and compared density need to have same extents.")); } - CrossCorrelationEvaluationHelperValues helperValues = evaluateHelperValues(referenceDensity_, comparedDensity); + CrossCorrelationEvaluationHelperValues helperValues = + evaluateHelperValues(referenceDensity_, comparedDensity); if ((helperValues.referenceSquaredSum == 0) || (helperValues.comparisonSquaredSum == 0)) { @@ -355,12 +358,11 @@ DensitySimilarityMeasure::density DensitySimilarityCrossCorrelation::gradient(de GMX_THROW(RangeError("Reference density and compared density need to have same extents.")); } - CrossCorrelationEvaluationHelperValues helperValues = evaluateHelperValues(referenceDensity_, comparedDensity); + CrossCorrelationEvaluationHelperValues helperValues = + evaluateHelperValues(referenceDensity_, comparedDensity); - std::transform(begin(referenceDensity_), end(referenceDensity_), - begin(comparedDensity), - begin(gradient_), - CrossCorrelationGradientAtVoxel(helperValues)); + std::transform(begin(referenceDensity_), end(referenceDensity_), begin(comparedDensity), + begin(gradient_), CrossCorrelationGradientAtVoxel(helperValues)); return gradient_.asConstView(); } @@ -371,10 +373,11 @@ std::unique_ptr DensitySimilarityCrossCorrelation: } -} // namespace +} // namespace -DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasureMethod method, density referenceDensity) +DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasureMethod method, + density referenceDensity) { // chose the implementation depending on the method of density comparison // throw an error if the method is not known @@ -389,8 +392,7 @@ DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasureMetho case DensitySimilarityMeasureMethod::crossCorrelation: impl_ = std::make_unique(referenceDensity); break; - default: - GMX_THROW(NotImplementedError("Similarity measure not implemented.")); + default: GMX_THROW(NotImplementedError("Similarity measure not implemented.")); } } @@ -404,21 +406,21 @@ real DensitySimilarityMeasure::similarity(density comparedDensity) return impl_->similarity(comparedDensity); } -DensitySimilarityMeasure::~DensitySimilarityMeasure() = default; +DensitySimilarityMeasure::~DensitySimilarityMeasure() = default; -DensitySimilarityMeasure::DensitySimilarityMeasure(const DensitySimilarityMeasure &other) - : impl_(other.impl_->clone()) +DensitySimilarityMeasure::DensitySimilarityMeasure(const DensitySimilarityMeasure& other) : + impl_(other.impl_->clone()) { } -DensitySimilarityMeasure &DensitySimilarityMeasure::operator=(const DensitySimilarityMeasure &other) +DensitySimilarityMeasure& DensitySimilarityMeasure::operator=(const DensitySimilarityMeasure& other) { impl_ = other.impl_->clone(); return *this; } -DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasure &&) noexcept = default; +DensitySimilarityMeasure::DensitySimilarityMeasure(DensitySimilarityMeasure&&) noexcept = default; -DensitySimilarityMeasure &DensitySimilarityMeasure::operator=(DensitySimilarityMeasure &&) noexcept = default; +DensitySimilarityMeasure& DensitySimilarityMeasure::operator=(DensitySimilarityMeasure&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/math/densityfit.h b/src/gromacs/math/densityfit.h index b817430d13..b3a3eb3f44 100644 --- a/src/gromacs/math/densityfit.h +++ b/src/gromacs/math/densityfit.h @@ -90,8 +90,9 @@ enum class DensitySimilarityMeasureMethod }; //! Name the methods that may be used to evaluate similarity between densities -const EnumerationArray -c_densitySimilarityMeasureMethodNames = {{ "inner-product", "relative-entropy", "cross-correlation"}}; +const EnumerationArray c_densitySimilarityMeasureMethodNames = { + { "inner-product", "relative-entropy", "cross-correlation" } +}; /* Forward declaration of implementation class outside class to allow * choose implementation class during construction of the DensitySimilarityMeasure*/ @@ -102,37 +103,38 @@ class DensitySimilarityMeasureImpl; */ class DensitySimilarityMeasure { - public: - //! a three-dimensional const view into density data - using density = basic_mdspan; - /*! \brief Chose comparison method and set reference density. - * \param[in] method defines how densities are compared to one another - * \param[in] referenceDensity - * \throws NotImplementedError if method is not known - */ - DensitySimilarityMeasure(DensitySimilarityMeasureMethod method, density referenceDensity); - ~DensitySimilarityMeasure(); - //! Copy constructor - DensitySimilarityMeasure(const DensitySimilarityMeasure &other); - //! Copy assignment - DensitySimilarityMeasure &operator=(const DensitySimilarityMeasure &other); - //! Move constructor - DensitySimilarityMeasure(DensitySimilarityMeasure &&other) noexcept; - //! Move assignment - DensitySimilarityMeasure &operator=(DensitySimilarityMeasure &&other) noexcept; +public: + //! a three-dimensional const view into density data + using density = basic_mdspan; + /*! \brief Chose comparison method and set reference density. + * \param[in] method defines how densities are compared to one another + * \param[in] referenceDensity + * \throws NotImplementedError if method is not known + */ + DensitySimilarityMeasure(DensitySimilarityMeasureMethod method, density referenceDensity); + ~DensitySimilarityMeasure(); + //! Copy constructor + DensitySimilarityMeasure(const DensitySimilarityMeasure& other); + //! Copy assignment + DensitySimilarityMeasure& operator=(const DensitySimilarityMeasure& other); + //! Move constructor + DensitySimilarityMeasure(DensitySimilarityMeasure&& other) noexcept; + //! Move assignment + DensitySimilarityMeasure& operator=(DensitySimilarityMeasure&& other) noexcept; + + /*! \brief Derivative of the density similarity measure at all voxels. + * \param[in] comparedDensity the variable density + * \returns density similarity measure derivative + */ + density gradient(density comparedDensity); + /*! \brief Similarity between reference and compared density. + * \param[in] comparedDensity the variable density + * \returns density similarity + */ + real similarity(density comparedDensity); - /*! \brief Derivative of the density similarity measure at all voxels. - * \param[in] comparedDensity the variable density - * \returns density similarity measure derivative - */ - density gradient(density comparedDensity); - /*! \brief Similarity between reference and compared density. - * \param[in] comparedDensity the variable density - * \returns density similarity - */ - real similarity(density comparedDensity); - private: - std::unique_ptr impl_; +private: + std::unique_ptr impl_; }; } // namespace gmx diff --git a/src/gromacs/math/densityfittingforce.cpp b/src/gromacs/math/densityfittingforce.cpp index 15c6ebce6b..ff4f26fbd9 100644 --- a/src/gromacs/math/densityfittingforce.cpp +++ b/src/gromacs/math/densityfittingforce.cpp @@ -58,43 +58,42 @@ namespace gmx */ class DensityFittingForce::Impl { - public: - /*! \brief Construct densityfitting force implementation from - * spread of function used to generate the density and spread range. - * \param[in] kernelShapeParameters determine the shape of the spreading kernel - */ - explicit Impl(const GaussianSpreadKernelParameters::Shape &kernelShapeParameters); - //! \copydoc DensityFittingForce::evaluateForce(const DensitySpreadKernelParameters::PositionAndAmplitude & localParameters, basic_mdspan densityDerivative) - RVec evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters, basic_mdspan densityDerivative); - //! The width of the Gaussian in lattice spacing units - DVec sigma_; - //! The spread range in lattice points - IVec latticeSpreadRange_; - //! The three one-dimensional Gaussians that are used in the force calculation - std::array gauss1d_; - //! The outer product of a Gaussian along the z and y dimension - OuterProductEvaluator outerProductZY_; +public: + /*! \brief Construct densityfitting force implementation from + * spread of function used to generate the density and spread range. + * \param[in] kernelShapeParameters determine the shape of the spreading kernel + */ + explicit Impl(const GaussianSpreadKernelParameters::Shape& kernelShapeParameters); + //! \copydoc DensityFittingForce::evaluateForce(const DensitySpreadKernelParameters::PositionAndAmplitude & localParameters, basic_mdspan densityDerivative) + RVec evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters, + basic_mdspan densityDerivative); + //! The width of the Gaussian in lattice spacing units + DVec sigma_; + //! The spread range in lattice points + IVec latticeSpreadRange_; + //! The three one-dimensional Gaussians that are used in the force calculation + std::array gauss1d_; + //! The outer product of a Gaussian along the z and y dimension + OuterProductEvaluator outerProductZY_; }; -DensityFittingForce::Impl::Impl(const GaussianSpreadKernelParameters::Shape &kernelShapeParameters) - : sigma_ {kernelShapeParameters.sigma_}, -latticeSpreadRange_ { - kernelShapeParameters.latticeSpreadRange() -}, -gauss1d_({GaussianOn1DLattice(latticeSpreadRange_[XX], sigma_[XX]), - GaussianOn1DLattice(latticeSpreadRange_[YY], sigma_[YY]), - GaussianOn1DLattice(latticeSpreadRange_[ZZ], sigma_[ZZ])}) +DensityFittingForce::Impl::Impl(const GaussianSpreadKernelParameters::Shape& kernelShapeParameters) : + sigma_{ kernelShapeParameters.sigma_ }, + latticeSpreadRange_{ kernelShapeParameters.latticeSpreadRange() }, + gauss1d_({ GaussianOn1DLattice(latticeSpreadRange_[XX], sigma_[XX]), + GaussianOn1DLattice(latticeSpreadRange_[YY], sigma_[YY]), + GaussianOn1DLattice(latticeSpreadRange_[ZZ], sigma_[ZZ]) }) { } -RVec DensityFittingForce::Impl::evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters, +RVec DensityFittingForce::Impl::evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters, basic_mdspan densityDerivative) { - const IVec closestLatticePoint( - roundToInt(localParameters.coordinate_[XX]), - roundToInt(localParameters.coordinate_[YY]), - roundToInt(localParameters.coordinate_[ZZ])); - const auto spreadRange = spreadRangeWithinLattice(closestLatticePoint, densityDerivative.extents(), latticeSpreadRange_); + const IVec closestLatticePoint(roundToInt(localParameters.coordinate_[XX]), + roundToInt(localParameters.coordinate_[YY]), + roundToInt(localParameters.coordinate_[ZZ])); + const auto spreadRange = spreadRangeWithinLattice( + closestLatticePoint, densityDerivative.extents(), latticeSpreadRange_); // do nothing if the added Gaussian will never reach the lattice if (spreadRange.empty()) @@ -106,23 +105,24 @@ RVec DensityFittingForce::Impl::evaluateForce(const GaussianSpreadKernelParamete { // multiply with amplitude so that Gauss3D = (amplitude * Gauss_x) * Gauss_y * Gauss_z const float gauss1DAmplitude = dimension > XX ? 1.0 : localParameters.amplitude_; - gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension] - closestLatticePoint[dimension]); + gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension] + - closestLatticePoint[dimension]); } - const auto spreadZY = outerProductZY_(gauss1d_[ZZ].view(), gauss1d_[YY].view()); - const auto spreadX = gauss1d_[XX].view(); - const IVec spreadGridOffset(latticeSpreadRange_[XX] - closestLatticePoint[XX], - latticeSpreadRange_[YY] - closestLatticePoint[YY], - latticeSpreadRange_[ZZ] - closestLatticePoint[ZZ]); + const auto spreadZY = outerProductZY_(gauss1d_[ZZ].view(), gauss1d_[YY].view()); + const auto spreadX = gauss1d_[XX].view(); + const IVec spreadGridOffset(latticeSpreadRange_[XX] - closestLatticePoint[XX], + latticeSpreadRange_[YY] - closestLatticePoint[YY], + latticeSpreadRange_[ZZ] - closestLatticePoint[ZZ]); - const DVec differenceVectorScale = - {1. / (square(sigma_[XX])), 1. / (square(sigma_[YY])), 1. / (square(sigma_[ZZ]))}; - const DVec differenceVectorOffset = - scaleByVector(spreadRange.begin().toDVec() - localParameters.coordinate_.toDVec(), differenceVectorScale); + const DVec differenceVectorScale = { 1. / (square(sigma_[XX])), 1. / (square(sigma_[YY])), + 1. / (square(sigma_[ZZ])) }; + const DVec differenceVectorOffset = scaleByVector( + spreadRange.begin().toDVec() - localParameters.coordinate_.toDVec(), differenceVectorScale); - DVec differenceVector = differenceVectorOffset; + DVec differenceVector = differenceVectorOffset; - DVec force = {0., 0., 0.}; + DVec force = { 0., 0., 0. }; for (int zLatticeIndex = spreadRange.begin()[ZZ]; zLatticeIndex < spreadRange.end()[ZZ]; ++zLatticeIndex, differenceVector[ZZ] += differenceVectorScale[ZZ]) @@ -135,53 +135,51 @@ RVec DensityFittingForce::Impl::evaluateForce(const GaussianSpreadKernelParamete { auto ySliceOfDerivative = zSliceOfDerivative[yLatticeIndex]; const auto zyPrefactor = spreadZY(zLatticeIndex + spreadGridOffset[ZZ], - yLatticeIndex + spreadGridOffset[YY]); + yLatticeIndex + spreadGridOffset[YY]); differenceVector[XX] = differenceVectorOffset[XX]; for (int xLatticeIndex = spreadRange.begin()[XX]; xLatticeIndex < spreadRange.end()[XX]; ++xLatticeIndex, differenceVector[XX] += differenceVectorScale[XX]) { - const double preFactor = zyPrefactor * - spreadX[xLatticeIndex + spreadGridOffset[XX]] * ySliceOfDerivative[xLatticeIndex]; + const double preFactor = zyPrefactor * spreadX[xLatticeIndex + spreadGridOffset[XX]] + * ySliceOfDerivative[xLatticeIndex]; force += preFactor * differenceVector; } } } - return localParameters.amplitude_*force.toRVec(); + return localParameters.amplitude_ * force.toRVec(); } /******************************************************************** * DensityFittingForce */ -DensityFittingForce::DensityFittingForce(const GaussianSpreadKernelParameters::Shape &kernelShapeParameters) : +DensityFittingForce::DensityFittingForce(const GaussianSpreadKernelParameters::Shape& kernelShapeParameters) : impl_(new Impl(kernelShapeParameters)) { } -RVec DensityFittingForce::evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters, +RVec DensityFittingForce::evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters, basic_mdspan densityDerivative) { return impl_->evaluateForce(localParameters, densityDerivative); } -DensityFittingForce::~DensityFittingForce() -{ -} +DensityFittingForce::~DensityFittingForce() {} -DensityFittingForce::DensityFittingForce(const DensityFittingForce &other) - : impl_(new Impl(*other.impl_)) +DensityFittingForce::DensityFittingForce(const DensityFittingForce& other) : + impl_(new Impl(*other.impl_)) { } -DensityFittingForce &DensityFittingForce::operator=(const DensityFittingForce &other) +DensityFittingForce& DensityFittingForce::operator=(const DensityFittingForce& other) { *impl_ = *other.impl_; return *this; } -DensityFittingForce::DensityFittingForce(DensityFittingForce &&) noexcept = default; +DensityFittingForce::DensityFittingForce(DensityFittingForce&&) noexcept = default; -DensityFittingForce &DensityFittingForce::operator=(DensityFittingForce &&) noexcept = default; +DensityFittingForce& DensityFittingForce::operator=(DensityFittingForce&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/math/densityfittingforce.h b/src/gromacs/math/densityfittingforce.h index 375f554ec7..5c16dadc77 100644 --- a/src/gromacs/math/densityfittingforce.h +++ b/src/gromacs/math/densityfittingforce.h @@ -71,41 +71,41 @@ namespace gmx */ class DensityFittingForce { - public: - /*! \brief Construct density fitting force evaluator. - * \param[in] kernelShapeParameters the global parameters of the density spreading kernel - */ - DensityFittingForce(const GaussianSpreadKernelParameters::Shape &kernelShapeParameters); +public: + /*! \brief Construct density fitting force evaluator. + * \param[in] kernelShapeParameters the global parameters of the density spreading kernel + */ + DensityFittingForce(const GaussianSpreadKernelParameters::Shape& kernelShapeParameters); - ~DensityFittingForce(); - //! Copy constructor - DensityFittingForce(const DensityFittingForce &other); - //! Copy assignment - DensityFittingForce &operator=(const DensityFittingForce &other); - //! Move constructor - DensityFittingForce(DensityFittingForce &&other) noexcept; - //! Move assignment - DensityFittingForce &operator=(DensityFittingForce &&other) noexcept; - /*! \brief - * Evaluate density-fitting force between a reference density and the - * density generated by a kernel. - * - * Implements the equation in the class description. - * - * \param[in] localParameters local parameters of the spreading kernel - * \param[in] densityDerivative the spatial derivative of the similarity - * measure between the reference density and - * a density that was generated using the - * spreading kernel - * - * \returns the force that increases the measure of the goodness of fit used to calculate the density derivative - */ - RVec evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters, - basic_mdspan densityDerivative); + ~DensityFittingForce(); + //! Copy constructor + DensityFittingForce(const DensityFittingForce& other); + //! Copy assignment + DensityFittingForce& operator=(const DensityFittingForce& other); + //! Move constructor + DensityFittingForce(DensityFittingForce&& other) noexcept; + //! Move assignment + DensityFittingForce& operator=(DensityFittingForce&& other) noexcept; + /*! \brief + * Evaluate density-fitting force between a reference density and the + * density generated by a kernel. + * + * Implements the equation in the class description. + * + * \param[in] localParameters local parameters of the spreading kernel + * \param[in] densityDerivative the spatial derivative of the similarity + * measure between the reference density and + * a density that was generated using the + * spreading kernel + * + * \returns the force that increases the measure of the goodness of fit used to calculate the density derivative + */ + RVec evaluateForce(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters, + basic_mdspan densityDerivative); - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/math/do_fit.cpp b/src/gromacs/math/do_fit.cpp index d3e11eb2d8..e4faa8e198 100644 --- a/src/gromacs/math/do_fit.cpp +++ b/src/gromacs/math/do_fit.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,8 +48,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -real calc_similar_ind(gmx_bool bRho, int nind, const int *index, const real mass[], - rvec x[], rvec xp[]) +real calc_similar_ind(gmx_bool bRho, int nind, const int* index, const real mass[], rvec x[], rvec xp[]) { int i, j, d; real m, tm, xs, xd, rs, rd; @@ -67,26 +66,26 @@ real calc_similar_ind(gmx_bool bRho, int nind, const int *index, const real mass { i = j; } - m = mass[i]; + m = mass[i]; tm += m; for (d = 0; d < DIM; d++) { - xd = x[i][d] - xp[i][d]; + xd = x[i][d] - xp[i][d]; rd += m * gmx::square(xd); if (bRho) { - xs = x[i][d] + xp[i][d]; + xs = x[i][d] + xp[i][d]; rs += m * gmx::square(xs); } } } if (bRho) { - return 2*std::sqrt(rd/rs); + return 2 * std::sqrt(rd / rs); } else { - return std::sqrt(rd/tm); + return std::sqrt(rd / tm); } } @@ -110,11 +109,11 @@ real rhodev(int natoms, real mass[], rvec x[], rvec xp[]) return calc_similar_ind(TRUE, natoms, nullptr, mass, x, xp); } -void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x, matrix R) +void calc_fit_R(int ndim, int natoms, const real* w_rls, const rvec* xp, rvec* x, matrix R) { int c, r, n, j, i, irot, s; double **omega, **om; - double d[2*DIM], xnr, xpc; + double d[2 * DIM], xnr, xpc; matrix vh, vk, u; real mn; int index; @@ -125,18 +124,18 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x gmx_fatal(FARGS, "calc_fit_R called with ndim=%d instead of 3 or 2", ndim); } - snew(omega, 2*ndim); - snew(om, 2*ndim); - for (i = 0; i < 2*ndim; i++) + snew(omega, 2 * ndim); + snew(om, 2 * ndim); + for (i = 0; i < 2 * ndim; i++) { - snew(omega[i], 2*ndim); - snew(om[i], 2*ndim); + snew(omega[i], 2 * ndim); + snew(om[i], 2 * ndim); } - for (i = 0; i < 2*ndim; i++) + for (i = 0; i < 2 * ndim; i++) { d[i] = 0; - for (j = 0; j < 2*ndim; j++) + for (j = 0; j < 2 * ndim; j++) { omega[i][j] = 0; om[i][j] = 0; @@ -154,8 +153,8 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x xpc = xp[n][c]; for (r = 0; (r < ndim); r++) { - xnr = x[n][r]; - u[c][r] += mn*xnr*xpc; + xnr = x[n][r]; + u[c][r] += mn * xnr * xpc; } } } @@ -163,14 +162,14 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x /*construct omega*/ /*omega is symmetric -> omega==omega' */ - for (r = 0; r < 2*ndim; r++) + for (r = 0; r < 2 * ndim; r++) { for (c = 0; c <= r; c++) { if (r >= ndim && c < ndim) { - omega[r][c] = u[r-ndim][c]; - omega[c][r] = u[r-ndim][c]; + omega[r][c] = u[r - ndim][c]; + omega[c][r] = u[r - ndim][c]; } else { @@ -181,7 +180,7 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x } /*determine h and k*/ - jacobi(omega, 2*ndim, d, om, &irot); + jacobi(omega, 2 * ndim, d, om, &irot); /*real **omega = input matrix a[0..n-1][0..n-1] must be symmetric * int natoms = number of rows and columns * real NULL = d[0]..d[n-1] are the eigenvalues of a[][] @@ -197,10 +196,10 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x index = 0; /* For the compiler only */ /* Copy only the first ndim-1 eigenvectors */ - for (j = 0; j < ndim-1; j++) + for (j = 0; j < ndim - 1; j++) { max_d = -1000; - for (i = 0; i < 2*ndim; i++) + for (i = 0; i < 2 * ndim; i++) { if (d[i] > max_d) { @@ -211,8 +210,8 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x d[index] = -10000; for (i = 0; i < ndim; i++) { - vh[j][i] = M_SQRT2*om[i][index]; - vk[j][i] = M_SQRT2*om[i+ndim][index]; + vh[j][i] = M_SQRT2 * om[i][index]; + vk[j][i] = M_SQRT2 * om[i + ndim][index]; } } if (ndim == 3) @@ -228,9 +227,9 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x { /* Calculate the last eigenvector from the first one */ vh[1][XX] = -vh[0][YY]; - vh[1][YY] = vh[0][XX]; + vh[1][YY] = vh[0][XX]; vk[1][XX] = -vk[0][YY]; - vk[1][YY] = vk[0][XX]; + vk[1][YY] = vk[0][XX]; } /* determine R */ @@ -241,7 +240,7 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x { for (s = 0; s < ndim; s++) { - R[r][c] += vk[s][r]*vh[s][c]; + R[r][c] += vk[s][r] * vh[s][c]; } } } @@ -250,7 +249,7 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x R[r][r] = 1; } - for (i = 0; i < 2*ndim; i++) + for (i = 0; i < 2 * ndim; i++) { sfree(omega[i]); sfree(om[i]); @@ -259,7 +258,7 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x sfree(om); } -void do_fit_ndim(int ndim, int natoms, real *w_rls, const rvec *xp, rvec *x) +void do_fit_ndim(int ndim, int natoms, real* w_rls, const rvec* xp, rvec* x) { int j, m, r, c; matrix R; @@ -280,20 +279,18 @@ void do_fit_ndim(int ndim, int natoms, real *w_rls, const rvec *xp, rvec *x) x[j][r] = 0; for (c = 0; c < DIM; c++) { - x[j][r] += R[r][c]*x_old[c]; + x[j][r] += R[r][c] * x_old[c]; } } } } -void do_fit(int natoms, real *w_rls, const rvec *xp, rvec *x) +void do_fit(int natoms, real* w_rls, const rvec* xp, rvec* x) { do_fit_ndim(3, natoms, w_rls, xp, x); } -void reset_x_ndim(int ndim, int ncm, const int *ind_cm, - int nreset, const int *ind_reset, - rvec x[], const real mass[]) +void reset_x_ndim(int ndim, int ncm, const int* ind_cm, int nreset, const int* ind_reset, rvec x[], const real mass[]) { int i, m, ai; rvec xcm; @@ -313,7 +310,7 @@ void reset_x_ndim(int ndim, int ncm, const int *ind_cm, mm = mass[ai]; for (m = 0; m < ndim; m++) { - xcm[m] += mm*x[ai][m]; + xcm[m] += mm * x[ai][m]; } tm += mm; } @@ -325,7 +322,7 @@ void reset_x_ndim(int ndim, int ncm, const int *ind_cm, mm = mass[i]; for (m = 0; m < ndim; m++) { - xcm[m] += mm*x[i][m]; + xcm[m] += mm * x[i][m]; } tm += mm; } @@ -351,9 +348,7 @@ void reset_x_ndim(int ndim, int ncm, const int *ind_cm, } } -void reset_x(int ncm, const int *ind_cm, - int nreset, const int *ind_reset, - rvec x[], const real mass[]) +void reset_x(int ncm, const int* ind_cm, int nreset, const int* ind_reset, rvec x[], const real mass[]) { reset_x_ndim(3, ncm, ind_cm, nreset, ind_reset, x, mass); } diff --git a/src/gromacs/math/do_fit.h b/src/gromacs/math/do_fit.h index d47a3c6d00..9a969f51fe 100644 --- a/src/gromacs/math/do_fit.h +++ b/src/gromacs/math/do_fit.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,12 +41,10 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -real calc_similar_ind(gmx_bool bRho, int nind, const int *index, const real mass[], - rvec x[], rvec xp[]); +real calc_similar_ind(gmx_bool bRho, int nind, const int* index, const real mass[], rvec x[], rvec xp[]); /* Returns RMSD or Rho (depending on bRho) over all atoms in index */ -real rmsdev_ind(int nind, int index[], real mass[], - rvec x[], rvec xp[]); +real rmsdev_ind(int nind, int index[], real mass[], rvec x[], rvec xp[]); /* Returns the RMS Deviation betweem x and xp over all atoms in index */ real rmsdev(int natoms, real mass[], rvec x[], rvec xp[]); @@ -62,8 +60,7 @@ real rhodev(int natoms, real mass[], rvec x[], rvec xp[]); * Maiorov & Crippen, PROTEINS 22, 273 (1995). */ -void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x, - matrix R); +void calc_fit_R(int ndim, int natoms, const real* w_rls, const rvec* xp, rvec* x, matrix R); /* Calculates the rotation matrix R for which * sum_i w_rls_i (xp_i - R x_i).(xp_i - R x_i) * is minimal. ndim=3 gives full fit, ndim=2 gives xy fit. @@ -71,7 +68,7 @@ void calc_fit_R(int ndim, int natoms, const real *w_rls, const rvec *xp, rvec *x * x_rotated[i] = sum R[i][j]*x[j] */ -void do_fit_ndim(int ndim, int natoms, real *w_rls, const rvec *xp, rvec *x); +void do_fit_ndim(int ndim, int natoms, real* w_rls, const rvec* xp, rvec* x); /* Do a least squares fit of x to xp. Atoms which have zero mass * (w_rls[i]) are not taken into account in fitting. * This makes is possible to fit eg. on Calpha atoms and orient @@ -79,12 +76,10 @@ void do_fit_ndim(int ndim, int natoms, real *w_rls, const rvec *xp, rvec *x); * therefore both xp and x should be centered round the origin. */ -void do_fit(int natoms, real *w_rls, const rvec *xp, rvec *x); +void do_fit(int natoms, real* w_rls, const rvec* xp, rvec* x); /* Calls do_fit with ndim=3, thus fitting in 3D */ -void reset_x_ndim(int ndim, int ncm, const int *ind_cm, - int nreset, const int *ind_reset, - rvec x[], const real mass[]); +void reset_x_ndim(int ndim, int ncm, const int* ind_cm, int nreset, const int* ind_reset, rvec x[], const real mass[]); /* Put the center of mass of atoms in the origin for dimensions 0 to ndim. * The center of mass is computed from the index ind_cm. * When ind_cm!=NULL the COM is determined using ind_cm. @@ -93,9 +88,7 @@ void reset_x_ndim(int ndim, int ncm, const int *ind_cm, * When ind_reset==NULL the coordinates up to nreset are reset. */ -void reset_x(int ncm, const int *ind_cm, - int nreset, const int *ind_reset, - rvec x[], const real mass[]); +void reset_x(int ncm, const int* ind_cm, int nreset, const int* ind_reset, rvec x[], const real mass[]); /* Calls reset_x with ndim=3, thus resetting all dimesions */ #endif diff --git a/src/gromacs/math/exponentialmovingaverage.cpp b/src/gromacs/math/exponentialmovingaverage.cpp index 59646f6aae..7a8bbbf000 100644 --- a/src/gromacs/math/exponentialmovingaverage.cpp +++ b/src/gromacs/math/exponentialmovingaverage.cpp @@ -50,7 +50,8 @@ namespace gmx { //! Convert the exponential moving average state as key-value-tree object -void exponentialMovingAverageStateAsKeyValueTree(KeyValueTreeObjectBuilder builder, const ExponentialMovingAverageState &state) +void exponentialMovingAverageStateAsKeyValueTree(KeyValueTreeObjectBuilder builder, + const ExponentialMovingAverageState& state) { builder.addValue("weighted-sum", state.weightedSum_); builder.addValue("weighted-count", state.weightedCount_); @@ -58,34 +59,35 @@ void exponentialMovingAverageStateAsKeyValueTree(KeyValueTreeObjectBuilder build } //! Sets the exponential moving average state from a key-value-tree object -ExponentialMovingAverageState -exponentialMovingAverageStateFromKeyValueTree(const KeyValueTreeObject &object) +ExponentialMovingAverageState exponentialMovingAverageStateFromKeyValueTree(const KeyValueTreeObject& object) { const real weightedSum = object["weighted-sum"].cast(); const real weightedCount = object["weighted-count"].cast(); const bool increasing = object["increasing"].cast(); - return {weightedSum, weightedCount, increasing}; + return { weightedSum, weightedCount, increasing }; } -ExponentialMovingAverage::ExponentialMovingAverage(real timeConstant, const ExponentialMovingAverageState &state) - : state_(state) +ExponentialMovingAverage::ExponentialMovingAverage(real timeConstant, + const ExponentialMovingAverageState& state) : + state_(state) { if (timeConstant < 1) { - GMX_THROW(InconsistentInputError("Lag time may not be negative or zero for exponential moving averages.")); + GMX_THROW(InconsistentInputError( + "Lag time may not be negative or zero for exponential moving averages.")); } inverseTimeConstant_ = 1. / timeConstant; } void ExponentialMovingAverage::updateWithDataPoint(real dataPoint) { - state_.weightedSum_ = dataPoint + (1-inverseTimeConstant_) * state_.weightedSum_; + state_.weightedSum_ = dataPoint + (1 - inverseTimeConstant_) * state_.weightedSum_; state_.weightedCount_ = 1 + (1 - inverseTimeConstant_) * state_.weightedCount_; state_.increasing_ = dataPoint * state_.weightedCount_ > state_.weightedSum_; } -const ExponentialMovingAverageState &ExponentialMovingAverage::state() const +const ExponentialMovingAverageState& ExponentialMovingAverage::state() const { return state_; } diff --git a/src/gromacs/math/exponentialmovingaverage.h b/src/gromacs/math/exponentialmovingaverage.h index f2c705d947..27a664b3c0 100644 --- a/src/gromacs/math/exponentialmovingaverage.h +++ b/src/gromacs/math/exponentialmovingaverage.h @@ -64,11 +64,11 @@ struct ExponentialMovingAverageState }; //! Convert the exponential moving average state as key-value-tree object -void exponentialMovingAverageStateAsKeyValueTree(KeyValueTreeObjectBuilder builder, const ExponentialMovingAverageState &state); +void exponentialMovingAverageStateAsKeyValueTree(KeyValueTreeObjectBuilder builder, + const ExponentialMovingAverageState& state); //! Sets the expoential moving average state from a key-value-tree object -ExponentialMovingAverageState -exponentialMovingAverageStateFromKeyValueTree(const KeyValueTreeObject &object); +ExponentialMovingAverageState exponentialMovingAverageStateFromKeyValueTree(const KeyValueTreeObject& object); /*! \libinternal * \brief Evaluate the exponential moving average with bias correction. @@ -84,38 +84,36 @@ exponentialMovingAverageStateFromKeyValueTree(const KeyValueTreeObject &object); */ class ExponentialMovingAverage { - public: - /*! \brief Construct by setting the time constant and state. - * Allows reinitiating with data from memory. - * \param[in] timeConstant time in number of data points - * \param[in] state of the exponential moving average - * \throws InconsistentInputError if timeConstant < 1 - */ - ExponentialMovingAverage(real timeConstant, - const ExponentialMovingAverageState &state = {} - ); - - //! Update the moving average with a data point - void updateWithDataPoint(real dataPoint); - - //! The exponential weighted average with bias correction - real biasCorrectedAverage() const; - - //! Returns true if last added data point increased the average - bool increasing() const; - - //! Return the current state of the exponential moving average - const ExponentialMovingAverageState &state() const; - - //! The inverse time constant for the exponential moving average - real inverseTimeConstant() const; - private: - - //! The current state of the exponential moving average - ExponentialMovingAverageState state_; - - //! The inverse time constant for the exponential moving average - real inverseTimeConstant_; +public: + /*! \brief Construct by setting the time constant and state. + * Allows reinitiating with data from memory. + * \param[in] timeConstant time in number of data points + * \param[in] state of the exponential moving average + * \throws InconsistentInputError if timeConstant < 1 + */ + ExponentialMovingAverage(real timeConstant, const ExponentialMovingAverageState& state = {}); + + //! Update the moving average with a data point + void updateWithDataPoint(real dataPoint); + + //! The exponential weighted average with bias correction + real biasCorrectedAverage() const; + + //! Returns true if last added data point increased the average + bool increasing() const; + + //! Return the current state of the exponential moving average + const ExponentialMovingAverageState& state() const; + + //! The inverse time constant for the exponential moving average + real inverseTimeConstant() const; + +private: + //! The current state of the exponential moving average + ExponentialMovingAverageState state_; + + //! The inverse time constant for the exponential moving average + real inverseTimeConstant_; }; } // namespace gmx diff --git a/src/gromacs/math/functions.cpp b/src/gromacs/math/functions.cpp index f6a4869de8..2cd3e3280a 100644 --- a/src/gromacs/math/functions.cpp +++ b/src/gromacs/math/functions.cpp @@ -63,8 +63,7 @@ namespace gmx { -unsigned int -log2I(std::uint32_t n) +unsigned int log2I(std::uint32_t n) { GMX_ASSERT(n > 0, "The behavior of log(0) is undefined"); #if HAVE_BUILTIN_CLZ @@ -82,26 +81,17 @@ log2I(std::uint32_t n) #else // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup - static const std::array - log2TableByte = - {{ - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - }}; + static const std::array log2TableByte = { + { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } + }; unsigned int result; unsigned int tmp1, tmp2; @@ -119,8 +109,7 @@ log2I(std::uint32_t n) } -unsigned int -log2I(std::uint64_t n) +unsigned int log2I(std::uint64_t n) { GMX_ASSERT(n > 0, "The behavior of log(0) is undefined"); #if HAVE_BUILTIN_CLZLL @@ -137,7 +126,7 @@ log2I(std::uint64_t n) // No 64-bit log2 instrinsic available. Solve it by calling our internal // 32-bit version (which in turn might defer to a software solution) - std::uint32_t high32Bits = static_cast(n>>32); + std::uint32_t high32Bits = static_cast(n >> 32); std::uint32_t result; if (high32Bits) @@ -153,23 +142,19 @@ log2I(std::uint64_t n) #endif } -unsigned int -log2I(std::int32_t n) +unsigned int log2I(std::int32_t n) { GMX_ASSERT(n > 0, "The behavior of log(n) for n<=0 is undefined"); return log2I(static_cast(n)); } -unsigned int -log2I(std::int64_t n) +unsigned int log2I(std::int64_t n) { GMX_ASSERT(n > 0, "The behavior of log(n) for n<=0 is undefined"); return log2I(static_cast(n)); } -std::int64_t -greatestCommonDivisor(std::int64_t p, - std::int64_t q) +std::int64_t greatestCommonDivisor(std::int64_t p, std::int64_t q) { while (q != 0) { @@ -180,8 +165,7 @@ greatestCommonDivisor(std::int64_t p, return p; } -double -erfinv(double x) +double erfinv(double x) { double xabs = std::abs(x); @@ -205,29 +189,28 @@ erfinv(double x) if (xabs <= 0.7) { // Rational approximation in range [0,0.7] - double z = x*x; + double z = x * x; double P = (((-0.140543331 * z + 0.914624893) * z - 1.645349621) * z + 0.886226899); double Q = ((((0.012229801 * z - 0.329097515) * z + 1.442710462) * z - 2.118377725) * z + 1.0); - res = x * P/Q; + res = x * P / Q; } else { // Rational approximation in range [0.7,1) - double z = std::sqrt(-std::log((1.0 - std::abs(x))/2.0)); + double z = std::sqrt(-std::log((1.0 - std::abs(x)) / 2.0)); double P = ((1.641345311 * z + 3.429567803) * z - 1.624906493) * z - 1.970840454; double Q = (1.637067800 * z + 3.543889200) * z + 1.0; - res = std::copysign(1.0, x) * P/Q; + res = std::copysign(1.0, x) * P / Q; } // Double precision requires two N-R iterations - res = res - (std::erf(res) - x)/( (2.0/std::sqrt(M_PI))*std::exp(-res*res)); - res = res - (std::erf(res) - x)/( (2.0/std::sqrt(M_PI))*std::exp(-res*res)); + res = res - (std::erf(res) - x) / ((2.0 / std::sqrt(M_PI)) * std::exp(-res * res)); + res = res - (std::erf(res) - x) / ((2.0 / std::sqrt(M_PI)) * std::exp(-res * res)); return res; } -float -erfinv(float x) +float erfinv(float x) { float xabs = std::abs(x); @@ -251,22 +234,22 @@ erfinv(float x) if (xabs <= 0.7F) { // Rational approximation in range [0,0.7] - float z = x*x; + float z = x * x; float P = (((-0.140543331F * z + 0.914624893F) * z - 1.645349621F) * z + 0.886226899F); float Q = ((((0.012229801F * z - 0.329097515F) * z + 1.442710462F) * z - 2.118377725F) * z + 1.0F); - res = x * P/Q; + res = x * P / Q; } else { // Rational approximation in range [0.7,1) - float z = std::sqrt(-std::log((1.0 - std::abs(x))/2.0F)); + float z = std::sqrt(-std::log((1.0 - std::abs(x)) / 2.0F)); float P = ((1.641345311F * z + 3.429567803F) * z - 1.624906493F) * z - 1.970840454F; float Q = (1.637067800F * z + 3.543889200F) * z + 1.0F; - res = std::copysign(1.0F, x) * P/Q; + res = std::copysign(1.0F, x) * P / Q; } // Single N-R iteration sufficient for single precision - res = res - (std::erf(res) - x)/( (2.0F/std::sqrt(M_PI))*std::exp(-res*res)); + res = res - (std::erf(res) - x) / ((2.0F / std::sqrt(M_PI)) * std::exp(-res * res)); return res; } diff --git a/src/gromacs/math/functions.h b/src/gromacs/math/functions.h index 5b523ad860..35150b3ddd 100644 --- a/src/gromacs/math/functions.h +++ b/src/gromacs/math/functions.h @@ -65,7 +65,8 @@ namespace gmx template struct StaticLog2 { - static const int value = StaticLog2::value+1; //!< Variable value used for recursive static calculation of Log2(int) + static const int value = StaticLog2::value + + 1; //!< Variable value used for recursive static calculation of Log2(int) }; /*! \brief Specialization of StaticLog2 for n==1. @@ -104,8 +105,7 @@ struct StaticLog2<0> * \note This version of the overloaded function will assert that x is * not negative. */ -unsigned int -log2I(std::int32_t x); +unsigned int log2I(std::int32_t x); /*! \brief Compute floor of logarithm to base 2, 64 bit signed argument * @@ -116,8 +116,7 @@ log2I(std::int32_t x); * \note This version of the overloaded function will assert that x is * not negative. */ -unsigned int -log2I(std::int64_t x); +unsigned int log2I(std::int64_t x); /*! \brief Compute floor of logarithm to base 2, 32 bit unsigned argument * @@ -128,8 +127,7 @@ log2I(std::int64_t x); * \note This version of the overloaded function uses unsigned arguments to * be able to handle arguments using all 32 bits. */ -unsigned int -log2I(std::uint32_t x); +unsigned int log2I(std::uint32_t x); /*! \brief Compute floor of logarithm to base 2, 64 bit unsigned argument * @@ -140,8 +138,7 @@ log2I(std::uint32_t x); * \note This version of the overloaded function uses unsigned arguments to * be able to handle arguments using all 64 bits. */ -unsigned int -log2I(std::uint64_t x); +unsigned int log2I(std::uint64_t x); /*! \brief Find greatest common divisor of two numbers * @@ -150,8 +147,7 @@ log2I(std::uint64_t x); * * \return Greatest common divisor of p and q */ -std::int64_t -greatestCommonDivisor(std::int64_t p, std::int64_t q); +std::int64_t greatestCommonDivisor(std::int64_t p, std::int64_t q); /*! \brief Calculate 1.0/sqrt(x) in single precision @@ -164,10 +160,9 @@ greatestCommonDivisor(std::int64_t p, std::int64_t q); * * \return 1.0/sqrt(x) */ -static inline float -invsqrt(float x) +static inline float invsqrt(float x) { - return 1.0F/std::sqrt(x); + return 1.0F / std::sqrt(x); } /*! \brief Calculate 1.0/sqrt(x) in double precision, but single range @@ -181,10 +176,9 @@ invsqrt(float x) * * \return 1.0/sqrt(x) */ -static inline double -invsqrt(double x) +static inline double invsqrt(double x) { - return 1.0/std::sqrt(x); + return 1.0 / std::sqrt(x); } /*! \brief Calculate 1.0/sqrt(x) for integer x in double precision. @@ -193,8 +187,7 @@ invsqrt(double x) * * \return 1.0/sqrt(x) */ -static inline double -invsqrt(int x) +static inline double invsqrt(int x) { return invsqrt(static_cast(x)); } @@ -207,10 +200,9 @@ invsqrt(int x) * * This routine is typically faster than using std::pow(). */ -static inline float -invcbrt(float x) +static inline float invcbrt(float x) { - return 1.0F/std::cbrt(x); + return 1.0F / std::cbrt(x); } /*! \brief Calculate inverse sixth root of x in double precision @@ -221,10 +213,9 @@ invcbrt(float x) * * This routine is typically faster than using std::pow(). */ -static inline double -invcbrt(double x) +static inline double invcbrt(double x) { - return 1.0/std::cbrt(x); + return 1.0 / std::cbrt(x); } /*! \brief Calculate inverse sixth root of integer x in double precision @@ -235,10 +226,9 @@ invcbrt(double x) * * This routine is typically faster than using std::pow(). */ -static inline double -invcbrt(int x) +static inline double invcbrt(int x) { - return 1.0/std::cbrt(x); + return 1.0 / std::cbrt(x); } /*! \brief Calculate sixth root of x in single precision. @@ -249,8 +239,7 @@ invcbrt(int x) * * This routine is typically faster than using std::pow(). */ -static inline float -sixthroot(float x) +static inline float sixthroot(float x) { return std::sqrt(std::cbrt(x)); } @@ -263,8 +252,7 @@ sixthroot(float x) * * This routine is typically faster than using std::pow(). */ -static inline double -sixthroot(double x) +static inline double sixthroot(double x) { return std::sqrt(std::cbrt(x)); } @@ -277,8 +265,7 @@ sixthroot(double x) * * This routine is typically faster than using std::pow(). */ -static inline double -sixthroot(int x) +static inline double sixthroot(int x) { return std::sqrt(std::cbrt(x)); } @@ -291,8 +278,7 @@ sixthroot(int x) * * This routine is typically faster than using std::pow(). */ -static inline float -invsixthroot(float x) +static inline float invsixthroot(float x) { return invsqrt(std::cbrt(x)); } @@ -305,8 +291,7 @@ invsixthroot(float x) * * This routine is typically faster than using std::pow(). */ -static inline double -invsixthroot(double x) +static inline double invsixthroot(double x) { return invsqrt(std::cbrt(x)); } @@ -319,8 +304,7 @@ invsixthroot(double x) * * This routine is typically faster than using std::pow(). */ -static inline double -invsixthroot(int x) +static inline double invsixthroot(int x) { return invsqrt(std::cbrt(x)); } @@ -332,11 +316,10 @@ invsixthroot(int x) * * \return x^2 */ -template -T -square(T x) +template +T square(T x) { - return x*x; + return x * x; } /*! \brief calculate x^3 @@ -346,11 +329,10 @@ square(T x) * * \return x^3 */ -template -T -power3(T x) +template +T power3(T x) { - return x*square(x); + return x * square(x); } /*! \brief calculate x^4 @@ -360,9 +342,8 @@ power3(T x) * * \return x^4 */ -template -T -power4(T x) +template +T power4(T x) { return square(square(x)); } @@ -374,11 +355,10 @@ power4(T x) * * \return x^5 */ -template -T -power5(T x) +template +T power5(T x) { - return x*power4(x); + return x * power4(x); } /*! \brief calculate x^6 @@ -388,9 +368,8 @@ power5(T x) * * \return x^6 */ -template -T -power6(T x) +template +T power6(T x) { return square(power3(x)); } @@ -402,9 +381,8 @@ power6(T x) * * \return x^12 */ -template -T -power12(T x) +template +T power12(T x) { return square(power6(x)); } @@ -417,8 +395,12 @@ power12(T x) */ static inline real series_sinhx(real x) { - real x2 = x*x; - return (1 + (x2/6.0_real)*(1 + (x2/20.0_real)*(1 + (x2/42.0_real)*(1 + (x2/72.0_real)*(1 + (x2/110.0_real)))))); + real x2 = x * x; + return (1 + + (x2 / 6.0_real) + * (1 + + (x2 / 20.0_real) + * (1 + (x2 / 42.0_real) * (1 + (x2 / 72.0_real) * (1 + (x2 / 110.0_real)))))); } /*! \brief Inverse error function, double precision. @@ -428,8 +410,7 @@ static inline real series_sinhx(real x) * \return The inverse of the error function if the argument is inside the * range, +/- infinity if it is exactly 1.0 or -1.0, and NaN otherwise. */ -double -erfinv(double x); +double erfinv(double x); /*! \brief Inverse error function, single precision. * @@ -438,8 +419,7 @@ erfinv(double x); * \return The inverse of the error function if the argument is inside the * range, +/- infinity if it is exactly 1.0 or -1.0, and NaN otherwise. */ -float -erfinv(float x); +float erfinv(float x); /*! \brief Exact integer division, 32bit. * @@ -450,13 +430,13 @@ erfinv(float x); */ constexpr int32_t exactDiv(int32_t a, int32_t b) { - return GMX_ASSERT(a%b == 0, "exactDiv called with non-divisible arguments"), a/b; + return GMX_ASSERT(a % b == 0, "exactDiv called with non-divisible arguments"), a / b; } //! Exact integer division, 64bit. constexpr int64_t exactDiv(int64_t a, int64_t b) { - return GMX_ASSERT(a%b == 0, "exactDiv called with non-divisible arguments"), a/b; + return GMX_ASSERT(a % b == 0, "exactDiv called with non-divisible arguments"), a / b; } /*! \brief Round float to int diff --git a/src/gromacs/math/gausstransform.cpp b/src/gromacs/math/gausstransform.cpp index 90c3165da7..111e2c7ccd 100644 --- a/src/gromacs/math/gausstransform.cpp +++ b/src/gromacs/math/gausstransform.cpp @@ -62,45 +62,45 @@ namespace gmx class GaussianOn1DLattice::Impl { - public: - Impl(int numGridPointsForSpreadingHalfWidth, real sigma); - ~Impl() = default; - Impl(const Impl &other) = default; - Impl &operator=(const Impl &other) = default; - - /*! \brief evaluate Gaussian function at all lattice points - * \param[in] amplitude the amplitude of the Gaussian - * \param[in] dx distance from the center - */ - void spread(double amplitude, real dx); - //! Largest distance in number of gridpoints from 0 - int numGridPointsForSpreadingHalfWidth_; - /*! \brief Avoid overflow for E2^offset and underflow for E3(i). - * - * Occurs when sigma is much smaller than numGridPointsForSpreadingHalfWidth_. - * - * E2^offset smaller than maximum float requires - * \f$exp(dx / (2*square(sigma))^numGridPointsForSpreadingHalfWidth_ \leq max_float \f$ - * The maximum expected distance of the Gaussian center to the next lattice point is dx = 0.5, - * thus the maximum spread distance here is \f$4 * sigma^2 * \log(\mathrm{maxfloat})\f$ . - * - * E3(i) larger than minmium float requires - * exp(i^2 / 2*(sigma)^2) > min_float - * Thus the maximum spread distance here is \f$\sigma \sqrt(-2\log(\mathrm{minfloat}))\f$ - */ - int maxEvaluatedSpreadDistance_; - //! Width of the Gaussian function - double sigma_; - //! The result of the spreading calculation - std::vector spreadingResult_; - //! Pre-calculated exp(-gridIndex^2/2 * (sigma^2)) named as in Greengard2004 - std::vector e3_; - /*! \brief Equal to std::floor(std::log(std::numeric_limits::max())). - * Above expression is not constexpr and a const variable would implicitly delete default copy assignment. - * Therefore resorting to setting number manually. - */ - static constexpr double c_logMaxFloat = 88.72284; - static constexpr double c_logMinFloat = -87.33654; +public: + Impl(int numGridPointsForSpreadingHalfWidth, real sigma); + ~Impl() = default; + Impl(const Impl& other) = default; + Impl& operator=(const Impl& other) = default; + + /*! \brief evaluate Gaussian function at all lattice points + * \param[in] amplitude the amplitude of the Gaussian + * \param[in] dx distance from the center + */ + void spread(double amplitude, real dx); + //! Largest distance in number of gridpoints from 0 + int numGridPointsForSpreadingHalfWidth_; + /*! \brief Avoid overflow for E2^offset and underflow for E3(i). + * + * Occurs when sigma is much smaller than numGridPointsForSpreadingHalfWidth_. + * + * E2^offset smaller than maximum float requires + * \f$exp(dx / (2*square(sigma))^numGridPointsForSpreadingHalfWidth_ \leq max_float \f$ + * The maximum expected distance of the Gaussian center to the next lattice point is dx = 0.5, + * thus the maximum spread distance here is \f$4 * sigma^2 * \log(\mathrm{maxfloat})\f$ . + * + * E3(i) larger than minmium float requires + * exp(i^2 / 2*(sigma)^2) > min_float + * Thus the maximum spread distance here is \f$\sigma \sqrt(-2\log(\mathrm{minfloat}))\f$ + */ + int maxEvaluatedSpreadDistance_; + //! Width of the Gaussian function + double sigma_; + //! The result of the spreading calculation + std::vector spreadingResult_; + //! Pre-calculated exp(-gridIndex^2/2 * (sigma^2)) named as in Greengard2004 + std::vector e3_; + /*! \brief Equal to std::floor(std::log(std::numeric_limits::max())). + * Above expression is not constexpr and a const variable would implicitly delete default copy + * assignment. Therefore resorting to setting number manually. + */ + static constexpr double c_logMaxFloat = 88.72284; + static constexpr double c_logMinFloat = -87.33654; }; GaussianOn1DLattice::Impl::Impl(int numGridPointsForSpreadingHalfWidth, real sigma) : @@ -108,8 +108,12 @@ GaussianOn1DLattice::Impl::Impl(int numGridPointsForSpreadingHalfWidth, real sig sigma_(sigma), spreadingResult_(2 * numGridPointsForSpreadingHalfWidth + 1) { - maxEvaluatedSpreadDistance_ = std::min(numGridPointsForSpreadingHalfWidth_, static_cast(std::floor(4 * square(sigma) * c_logMaxFloat)) - 1); - maxEvaluatedSpreadDistance_ = std::min(maxEvaluatedSpreadDistance_, static_cast(std::floor(sigma * sqrt(-2.0 * c_logMinFloat))) - 1); + maxEvaluatedSpreadDistance_ = + std::min(numGridPointsForSpreadingHalfWidth_, + static_cast(std::floor(4 * square(sigma) * c_logMaxFloat)) - 1); + maxEvaluatedSpreadDistance_ = + std::min(maxEvaluatedSpreadDistance_, + static_cast(std::floor(sigma * sqrt(-2.0 * c_logMinFloat))) - 1); std::generate_n(std::back_inserter(e3_), maxEvaluatedSpreadDistance_ + 1, [sigma, latticeIndex = 0]() mutable { @@ -147,32 +151,35 @@ void GaussianOn1DLattice::Impl::spread(double amplitude, real dx) const double e2 = exp(dx / square(sigma_)); - double e2pow = e2; //< powers of e2, e2^offset + double e2pow = e2; //< powers of e2, e2^offset // Move outwards from mid-point, using e2pow value for both points simultaneously // o o o<----O---->o o o for (int offset = 1; offset < maxEvaluatedSpreadDistance_; offset++) { - const double e1_3 = e1 * e3_[offset]; + const double e1_3 = e1 * e3_[offset]; spreadingResult_[numGridPointsForSpreadingHalfWidth_ + offset] = e1_3 * e2pow; spreadingResult_[numGridPointsForSpreadingHalfWidth_ - offset] = e1_3 / e2pow; e2pow *= e2; } // separate statement for gridpoints at the end of the range avoids // overflow for large sigma and saves one e2 multiplication operation - spreadingResult_[numGridPointsForSpreadingHalfWidth_ - maxEvaluatedSpreadDistance_] = (e1 / e2pow) * e3_[maxEvaluatedSpreadDistance_]; - spreadingResult_[numGridPointsForSpreadingHalfWidth_ + maxEvaluatedSpreadDistance_] = (e1 * e2pow) * e3_[maxEvaluatedSpreadDistance_]; + spreadingResult_[numGridPointsForSpreadingHalfWidth_ - maxEvaluatedSpreadDistance_] = + (e1 / e2pow) * e3_[maxEvaluatedSpreadDistance_]; + spreadingResult_[numGridPointsForSpreadingHalfWidth_ + maxEvaluatedSpreadDistance_] = + (e1 * e2pow) * e3_[maxEvaluatedSpreadDistance_]; } /******************************************************************** * GaussianOn1DLattice */ -GaussianOn1DLattice::GaussianOn1DLattice(int numGridPointsForSpreadingHalfWidth_, real sigma) : impl_(new Impl(numGridPointsForSpreadingHalfWidth_, sigma)) +GaussianOn1DLattice::GaussianOn1DLattice(int numGridPointsForSpreadingHalfWidth_, real sigma) : + impl_(new Impl(numGridPointsForSpreadingHalfWidth_, sigma)) { } -GaussianOn1DLattice::~GaussianOn1DLattice () {} +GaussianOn1DLattice::~GaussianOn1DLattice() {} void GaussianOn1DLattice::spread(double amplitude, real dx) { @@ -184,32 +191,28 @@ ArrayRef GaussianOn1DLattice::view() return impl_->spreadingResult_; } -GaussianOn1DLattice::GaussianOn1DLattice(const GaussianOn1DLattice &other) - : impl_(new Impl(*other.impl_)) +GaussianOn1DLattice::GaussianOn1DLattice(const GaussianOn1DLattice& other) : + impl_(new Impl(*other.impl_)) { } -GaussianOn1DLattice &GaussianOn1DLattice::operator=(const GaussianOn1DLattice &other) +GaussianOn1DLattice& GaussianOn1DLattice::operator=(const GaussianOn1DLattice& other) { *impl_ = *other.impl_; return *this; } -GaussianOn1DLattice::GaussianOn1DLattice(GaussianOn1DLattice &&) noexcept = default; +GaussianOn1DLattice::GaussianOn1DLattice(GaussianOn1DLattice&&) noexcept = default; -GaussianOn1DLattice &GaussianOn1DLattice::operator=(GaussianOn1DLattice &&) noexcept = default; +GaussianOn1DLattice& GaussianOn1DLattice::operator=(GaussianOn1DLattice&&) noexcept = default; namespace { //! rounds real-valued coordinate to the closest integer values -IVec closestIntegerPoint(const RVec &coordinate) +IVec closestIntegerPoint(const RVec& coordinate) { - return { - roundToInt(coordinate[XX]), - roundToInt(coordinate[YY]), - roundToInt(coordinate[ZZ]) - }; + return { roundToInt(coordinate[XX]), roundToInt(coordinate[YY]), roundToInt(coordinate[ZZ]) }; } /*! \brief Substracts a range from a three-dimensional integer coordinate and ensures @@ -218,9 +221,9 @@ IVec closestIntegerPoint(const RVec &coordinate) * \param[in] range to be shifted * \returns Shifted index or zero if shifted index is smaller than zero. */ -IVec rangeBeginWithinLattice(const IVec &index, const IVec &range) +IVec rangeBeginWithinLattice(const IVec& index, const IVec& range) { - return elementWiseMax({0, 0, 0}, index - range); + return elementWiseMax({ 0, 0, 0 }, index - range); } /*! \brief Adds a range from a three-dimensional integer coordinate and ensures @@ -230,21 +233,22 @@ IVec rangeBeginWithinLattice(const IVec &index, const IVec &range) * \param[in] range to be shifted * \returns Shifted index or the lattice extent if shifted index is larger than the extent */ -IVec rangeEndWithinLattice(const IVec &index, const dynamicExtents3D &extents, const IVec &range) +IVec rangeEndWithinLattice(const IVec& index, const dynamicExtents3D& extents, const IVec& range) { - IVec extentAsIvec(static_cast(extents.extent(ZZ)), static_cast(extents.extent(YY)), static_cast(extents.extent(XX))); + IVec extentAsIvec(static_cast(extents.extent(ZZ)), static_cast(extents.extent(YY)), + static_cast(extents.extent(XX))); return elementWiseMin(extentAsIvec, index + range); } -} // namespace +} // namespace /******************************************************************** * OuterProductEvaluator */ -mdspan -OuterProductEvaluator::operator()(ArrayRef x, ArrayRef y) +mdspan OuterProductEvaluator:: + operator()(ArrayRef x, ArrayRef y) { data_.resize(ssize(x), ssize(y)); for (gmx::index xIndex = 0; xIndex < ssize(x); ++xIndex) @@ -260,23 +264,27 @@ OuterProductEvaluator::operator()(ArrayRef x, ArrayRef * IntegerBox */ -IntegerBox::IntegerBox(const IVec &begin, const IVec &end) : begin_ {begin}, end_ { - end -} -{} +IntegerBox::IntegerBox(const IVec& begin, const IVec& end) : begin_{ begin }, end_{ end } {} -const IVec &IntegerBox::begin() const{return begin_; } -const IVec &IntegerBox::end() const { return end_; } +const IVec& IntegerBox::begin() const +{ + return begin_; +} +const IVec& IntegerBox::end() const +{ + return end_; +} -bool IntegerBox::empty() const { return !((begin_[XX] < end_[XX] ) && (begin_[YY] < end_[YY]) && (begin_[ZZ] < end_[ZZ])); } +bool IntegerBox::empty() const +{ + return !((begin_[XX] < end_[XX]) && (begin_[YY] < end_[YY]) && (begin_[ZZ] < end_[ZZ])); +} -IntegerBox spreadRangeWithinLattice(const IVec ¢er, dynamicExtents3D extent, IVec range) +IntegerBox spreadRangeWithinLattice(const IVec& center, dynamicExtents3D extent, IVec range) { const IVec begin = rangeBeginWithinLattice(center, range); const IVec end = rangeEndWithinLattice(center, extent, range); - return { - begin, end - }; + return { begin, end }; } /******************************************************************** * GaussianSpreadKernel @@ -284,7 +292,9 @@ IntegerBox spreadRangeWithinLattice(const IVec ¢er, dynamicExtents3D extent, IVec GaussianSpreadKernelParameters::Shape::latticeSpreadRange() const { - DVec range(std::ceil(sigma_[XX] * spreadWidthMultiplesOfSigma_), std::ceil(sigma_[YY] * spreadWidthMultiplesOfSigma_), std::ceil(sigma_[ZZ] * spreadWidthMultiplesOfSigma_)); + DVec range(std::ceil(sigma_[XX] * spreadWidthMultiplesOfSigma_), + std::ceil(sigma_[YY] * spreadWidthMultiplesOfSigma_), + std::ceil(sigma_[ZZ] * spreadWidthMultiplesOfSigma_)); return range.toIVec(); } @@ -297,48 +307,44 @@ IVec GaussianSpreadKernelParameters::Shape::latticeSpreadRange() const */ class GaussTransform3D::Impl { - public: - //! Construct from extent and spreading width and range - Impl(const dynamicExtents3D &extent, - const GaussianSpreadKernelParameters::Shape &kernelShapeParameters); - ~Impl() = default; - //! Copy constructor - Impl(const Impl &other) = default; - //! Copy assignment - Impl &operator=(const Impl &other) = default; - //! Add another gaussian - void add(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParamters ); - //! The width of the Gaussian in lattice spacing units - BasicVector sigma_; - //! The spread range in lattice points - IVec spreadRange_; - //! The result of the Gauss transform - MultiDimArray, dynamicExtents3D> data_; - //! The outer product of a Gaussian along the z and y dimension - OuterProductEvaluator outerProductZY_; - //! The three one-dimensional Gaussians, whose outer product is added to the Gauss transform - std::array gauss1d_; +public: + //! Construct from extent and spreading width and range + Impl(const dynamicExtents3D& extent, const GaussianSpreadKernelParameters::Shape& kernelShapeParameters); + ~Impl() = default; + //! Copy constructor + Impl(const Impl& other) = default; + //! Copy assignment + Impl& operator=(const Impl& other) = default; + //! Add another gaussian + void add(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParamters); + //! The width of the Gaussian in lattice spacing units + BasicVector sigma_; + //! The spread range in lattice points + IVec spreadRange_; + //! The result of the Gauss transform + MultiDimArray, dynamicExtents3D> data_; + //! The outer product of a Gaussian along the z and y dimension + OuterProductEvaluator outerProductZY_; + //! The three one-dimensional Gaussians, whose outer product is added to the Gauss transform + std::array gauss1d_; }; -GaussTransform3D::Impl::Impl(const dynamicExtents3D &extent, - const GaussianSpreadKernelParameters::Shape &kernelShapeParameters) - : sigma_ {kernelShapeParameters.sigma_ }, -spreadRange_ { - kernelShapeParameters.latticeSpreadRange() -}, -data_ { - extent -}, -gauss1d_( {GaussianOn1DLattice(spreadRange_[XX], sigma_[XX]), - GaussianOn1DLattice(spreadRange_[YY], sigma_[YY]), - GaussianOn1DLattice(spreadRange_[ZZ], sigma_[ZZ]) } ) +GaussTransform3D::Impl::Impl(const dynamicExtents3D& extent, + const GaussianSpreadKernelParameters::Shape& kernelShapeParameters) : + sigma_{ kernelShapeParameters.sigma_ }, + spreadRange_{ kernelShapeParameters.latticeSpreadRange() }, + data_{ extent }, + gauss1d_({ GaussianOn1DLattice(spreadRange_[XX], sigma_[XX]), + GaussianOn1DLattice(spreadRange_[YY], sigma_[YY]), + GaussianOn1DLattice(spreadRange_[ZZ], sigma_[ZZ]) }) { } -void GaussTransform3D::Impl::add(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters) +void GaussTransform3D::Impl::add(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters) { const IVec closestLatticePoint = closestIntegerPoint(localParameters.coordinate_); - const auto spreadRange = spreadRangeWithinLattice(closestLatticePoint, data_.asView().extents(), spreadRange_); + const auto spreadRange = + spreadRangeWithinLattice(closestLatticePoint, data_.asView().extents(), spreadRange_); // do nothing if the added Gaussian will never reach the lattice if (spreadRange.empty()) @@ -350,7 +356,8 @@ void GaussTransform3D::Impl::add(const GaussianSpreadKernelParameters::PositionA { // multiply with amplitude so that Gauss3D = (amplitude * Gauss_x) * Gauss_y * Gauss_z const float gauss1DAmplitude = dimension > XX ? 1.0 : localParameters.amplitude_; - gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension] - closestLatticePoint[dimension]); + gauss1d_[dimension].spread(gauss1DAmplitude, localParameters.coordinate_[dimension] + - closestLatticePoint[dimension]); } const auto spreadZY = outerProductZY_(gauss1d_[ZZ].view(), gauss1d_[YY].view()); @@ -366,9 +373,11 @@ void GaussTransform3D::Impl::add(const GaussianSpreadKernelParameters::PositionA for (int yLatticeIndex = spreadRange.begin()[YY]; yLatticeIndex < spreadRange.end()[YY]; ++yLatticeIndex) { const auto ySlice = zSlice[yLatticeIndex]; - const float zyPrefactor = spreadZY(zLatticeIndex + spreadGridOffset[ZZ], yLatticeIndex + spreadGridOffset[YY]); + const float zyPrefactor = spreadZY(zLatticeIndex + spreadGridOffset[ZZ], + yLatticeIndex + spreadGridOffset[YY]); - for (int xLatticeIndex = spreadRange.begin()[XX]; xLatticeIndex < spreadRange.end()[XX]; ++xLatticeIndex) + for (int xLatticeIndex = spreadRange.begin()[XX]; xLatticeIndex < spreadRange.end()[XX]; + ++xLatticeIndex) { const float xPrefactor = spreadX[xLatticeIndex + spreadGridOffset[XX]]; ySlice[xLatticeIndex] += zyPrefactor * xPrefactor; @@ -381,12 +390,13 @@ void GaussTransform3D::Impl::add(const GaussianSpreadKernelParameters::PositionA * GaussTransform3D */ -GaussTransform3D::GaussTransform3D(const dynamicExtents3D &extent, - const GaussianSpreadKernelParameters::Shape &kernelShapeParameters) : impl_(new Impl(extent, kernelShapeParameters)) +GaussTransform3D::GaussTransform3D(const dynamicExtents3D& extent, + const GaussianSpreadKernelParameters::Shape& kernelShapeParameters) : + impl_(new Impl(extent, kernelShapeParameters)) { } -void GaussTransform3D::add(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters) +void GaussTransform3D::add(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters) { impl_->add(localParameters); } @@ -406,22 +416,18 @@ basic_mdspan GaussTransform3D::constView() const return impl_->data_.asConstView(); } -GaussTransform3D::~GaussTransform3D() -{ } +GaussTransform3D::~GaussTransform3D() {} -GaussTransform3D::GaussTransform3D(const GaussTransform3D &other) - : impl_(new Impl(*other.impl_)) -{ -} +GaussTransform3D::GaussTransform3D(const GaussTransform3D& other) : impl_(new Impl(*other.impl_)) {} -GaussTransform3D &GaussTransform3D::operator=(const GaussTransform3D &other) +GaussTransform3D& GaussTransform3D::operator=(const GaussTransform3D& other) { *impl_ = *other.impl_; return *this; } -GaussTransform3D::GaussTransform3D(GaussTransform3D &&) noexcept = default; +GaussTransform3D::GaussTransform3D(GaussTransform3D&&) noexcept = default; -GaussTransform3D &GaussTransform3D::operator=(GaussTransform3D &&) noexcept = default; +GaussTransform3D& GaussTransform3D::operator=(GaussTransform3D&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/math/gausstransform.h b/src/gromacs/math/gausstransform.h index 10ae22368c..c5af105177 100644 --- a/src/gromacs/math/gausstransform.h +++ b/src/gromacs/math/gausstransform.h @@ -72,55 +72,56 @@ namespace gmx */ class GaussianOn1DLattice { - public: - /*! \brief Construct Gaussian spreader with spreading range and Gaussian width. - * - * Spread weights are distributed over a non-periodic lattice of length - * 2*numGridPointsForSpreadingHalfWidth+1. The lattice comprises a center point and - * spreadDistance points to the left and to the right. - * - * \note There is a maximum spreading width - * - * \param[in] numGridPointsForSpreadingHalfWidth maximum distance in number of gridpoints from 0 - * \param[in] sigma Gaussian width. - */ - GaussianOn1DLattice(int numGridPointsForSpreadingHalfWidth, real sigma); - ~GaussianOn1DLattice(); - //! Copy constructor - GaussianOn1DLattice(const GaussianOn1DLattice &other); - //! Copy assignment - GaussianOn1DLattice &operator=(const GaussianOn1DLattice &other); - //! Move constructor - GaussianOn1DLattice(GaussianOn1DLattice &&other) noexcept; - //! Move assignment - GaussianOn1DLattice &operator=(GaussianOn1DLattice &&other) noexcept; - /*! \brief Spreads weight onto grid points in one dimension. - * - * - * . : | : . - * o o o o o - * O---| - * latticeOffset - * O - atom position - * o - lattice positions - * . : | spreading value at grid points. - * - * \note Highest numerical accuracy is achieved when the spreading - * with offset to the nearest lattice coordinated < 0.5 - * - * Spreading on lattice coordinate \f$x_i\f$ - * \f[ - * f(x_i) = \frac{\mathrm{amplitude}}{\sigma\sqrt{2\pi}}\exp(-\frac{\mathrm{offset}-x_i^2}{2 \sigma ^2}) - * \f] - * \param[in] amplitude of the Gaussian spread. - * \param[in] latticeOffset The distance to the nearest grid point in lattice coordinates. - */ - void spread(double amplitude, real latticeOffset); - /*! \brief Returns view on spread result. */ - ArrayRef view(); - private: - class Impl; - PrivateImplPointer impl_; +public: + /*! \brief Construct Gaussian spreader with spreading range and Gaussian width. + * + * Spread weights are distributed over a non-periodic lattice of length + * 2*numGridPointsForSpreadingHalfWidth+1. The lattice comprises a center point and + * spreadDistance points to the left and to the right. + * + * \note There is a maximum spreading width + * + * \param[in] numGridPointsForSpreadingHalfWidth maximum distance in number of gridpoints from 0 + * \param[in] sigma Gaussian width. + */ + GaussianOn1DLattice(int numGridPointsForSpreadingHalfWidth, real sigma); + ~GaussianOn1DLattice(); + //! Copy constructor + GaussianOn1DLattice(const GaussianOn1DLattice& other); + //! Copy assignment + GaussianOn1DLattice& operator=(const GaussianOn1DLattice& other); + //! Move constructor + GaussianOn1DLattice(GaussianOn1DLattice&& other) noexcept; + //! Move assignment + GaussianOn1DLattice& operator=(GaussianOn1DLattice&& other) noexcept; + /*! \brief Spreads weight onto grid points in one dimension. + * + * + * . : | : . + * o o o o o + * O---| + * latticeOffset + * O - atom position + * o - lattice positions + * . : | spreading value at grid points. + * + * \note Highest numerical accuracy is achieved when the spreading + * with offset to the nearest lattice coordinated < 0.5 + * + * Spreading on lattice coordinate \f$x_i\f$ + * \f[ + * f(x_i) = \frac{\mathrm{amplitude}}{\sigma\sqrt{2\pi}}\exp(-\frac{\mathrm{offset}-x_i^2}{2 \sigma ^2}) + * \f] + * \param[in] amplitude of the Gaussian spread. + * \param[in] latticeOffset The distance to the nearest grid point in lattice coordinates. + */ + void spread(double amplitude, real latticeOffset); + /*! \brief Returns view on spread result. */ + ArrayRef view(); + +private: + class Impl; + PrivateImplPointer impl_; }; /*! \libinternal \brief Parameters for density spreading kernels. @@ -133,27 +134,26 @@ struct GaussianSpreadKernelParameters struct Shape { //! The width of the Gaussian function in lattice spacings - DVec sigma_; + DVec sigma_; //! The range of the spreading function in multiples of sigma - double spreadWidthMultiplesOfSigma_; + double spreadWidthMultiplesOfSigma_; //! The spread range in lattice coordinates - IVec latticeSpreadRange() const; + IVec latticeSpreadRange() const; }; /*! \libinternal \brief Parameters that describe the kernel position and amplitude. */ struct PositionAndAmplitude { //! position of the kernel to be spread onto the lattice - const RVec &coordinate_; + const RVec& coordinate_; //! amplitude of the spread kernel - real amplitude_; + real amplitude_; }; }; /*! \libinternal \brief Sums Gaussian values at three dimensional lattice coordinates. - * The Gaussian is defined as \f$A \frac{1}{\sigma^3 \sqrt(2^3\pi^3)} * \exp(-\frac{(x-x0)^2}{2 \sigma^2})\f$ - \verbatim - x0: X x + * The Gaussian is defined as \f$A \frac{1}{\sigma^3 \sqrt(2^3\pi^3)} * \exp(-\frac{(x-x0)^2}{2 + \sigma^2})\f$ \verbatim x0: X x / \ / \ -- -- -- -- lattice: | | | | | | | @@ -163,89 +163,93 @@ struct GaussianSpreadKernelParameters */ class GaussTransform3D { - public: - /*! \brief Construct a three-dimensional Gauss transform. - * - * Transform lattice values will be zero-initialized. - * - * \param[in] extent of the spread lattice - * \param[in] globalParameters of the spreading kernel - */ - GaussTransform3D(const dynamicExtents3D &extent, const GaussianSpreadKernelParameters::Shape &globalParameters); +public: + /*! \brief Construct a three-dimensional Gauss transform. + * + * Transform lattice values will be zero-initialized. + * + * \param[in] extent of the spread lattice + * \param[in] globalParameters of the spreading kernel + */ + GaussTransform3D(const dynamicExtents3D& extent, + const GaussianSpreadKernelParameters::Shape& globalParameters); - ~GaussTransform3D(); + ~GaussTransform3D(); - //! Copy constructor - GaussTransform3D(const GaussTransform3D &other); + //! Copy constructor + GaussTransform3D(const GaussTransform3D& other); - //! Copy assignment - GaussTransform3D &operator=(const GaussTransform3D &other); + //! Copy assignment + GaussTransform3D& operator=(const GaussTransform3D& other); - //! Move constructor - GaussTransform3D(GaussTransform3D &&other) noexcept; + //! Move constructor + GaussTransform3D(GaussTransform3D&& other) noexcept; - //! Move assignment - GaussTransform3D &operator=(GaussTransform3D &&other) noexcept; + //! Move assignment + GaussTransform3D& operator=(GaussTransform3D&& other) noexcept; - /*! \brief Add a three dimensional Gaussian with given amplitude at a coordinate. - * \param[in] localParameters of the spreading kernel - */ - void add(const GaussianSpreadKernelParameters::PositionAndAmplitude &localParameters); + /*! \brief Add a three dimensional Gaussian with given amplitude at a coordinate. + * \param[in] localParameters of the spreading kernel + */ + void add(const GaussianSpreadKernelParameters::PositionAndAmplitude& localParameters); - //! \brief Set all values on the lattice to zero. - void setZero(); + //! \brief Set all values on the lattice to zero. + void setZero(); - //! Return a view on the spread lattice. - basic_mdspan view(); + //! Return a view on the spread lattice. + basic_mdspan view(); - //! Return a const view on the spread lattice. - basic_mdspan constView() const; + //! Return a const view on the spread lattice. + basic_mdspan constView() const; - private: - class Impl; - PrivateImplPointer impl_; +private: + class Impl; + PrivateImplPointer impl_; }; /*! \internal \brief A 3-orthotope over integer intervals. */ class IntegerBox { - public: - //! Construct from begin and end - IntegerBox(const IVec &begin, const IVec &end); - //! Begin indices of the box - const IVec &begin() const; - //! End indices of the box - const IVec &end() const; - //! Empty if for any dimension, end <= begin; - bool empty() const; - private: - const IVec begin_; //< interger indices denoting begin of box - const IVec end_; //< integer indices denoting one-past end of box in any dimension +public: + //! Construct from begin and end + IntegerBox(const IVec& begin, const IVec& end); + //! Begin indices of the box + const IVec& begin() const; + //! End indices of the box + const IVec& end() const; + //! Empty if for any dimension, end <= begin; + bool empty() const; + +private: + const IVec begin_; //< interger indices denoting begin of box + const IVec end_; //< integer indices denoting one-past end of box in any dimension }; -/*! \brief Construct a box that holds all indices that are not more than a given range remote from center coordinates - * and still within a given lattice extent. +/*! \brief Construct a box that holds all indices that are not more than a given range remote from + * center coordinates and still within a given lattice extent. * * \param[in] center the coordinates of the center of the spread range * \param[in] extent the end of the lattice, number of lattice points in each dimension * \param[in] range the distance from the center * \returns box describing the range of indices */ -IntegerBox spreadRangeWithinLattice(const IVec ¢er, dynamicExtents3D extent, IVec range); +IntegerBox spreadRangeWithinLattice(const IVec& center, dynamicExtents3D extent, IVec range); /*! \internal \brief Evaluate the outer product of two number ranges. * Keeps the memory for the outer product allocated. */ class OuterProductEvaluator { - public: - //! Evaluate the outer product of two float number ranges. - mdspan operator()(ArrayRef x, ArrayRef y); - private: - MultiDimArray < std::vector, extents < dynamic_extent, dynamic_extent>> data_; +public: + //! Evaluate the outer product of two float number ranges. + mdspan operator()(ArrayRef x, + ArrayRef y); + +private: + MultiDimArray, extents> data_; }; -} // namespace gmx +} // namespace gmx #endif /* end of include guard: GMX_MATH_GAUSSTRANSFORM_H */ diff --git a/src/gromacs/math/gmxcomplex.h b/src/gromacs/math/gmxcomplex.h index 3faa4b960b..b329647bf1 100644 --- a/src/gromacs/math/gmxcomplex.h +++ b/src/gromacs/math/gmxcomplex.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,7 +42,8 @@ #include "gromacs/math/vectypes.h" #include "gromacs/utility/real.h" -struct t_complex{ +struct t_complex +{ real re, im; }; @@ -52,8 +53,8 @@ static t_complex rcmul(real r, t_complex c) { t_complex d; - d.re = r*c.re; - d.im = r*c.im; + d.re = r * c.re; + d.im = r * c.im; return d; } @@ -73,8 +74,8 @@ static inline t_complex cadd(t_complex a, t_complex b) { t_complex c; - c.re = a.re+b.re; - c.im = a.im+b.im; + c.re = a.re + b.re; + c.im = a.im + b.im; return c; } @@ -83,8 +84,8 @@ static inline t_complex csub(t_complex a, t_complex b) { t_complex c; - c.re = a.re-b.re; - c.im = a.im-b.im; + c.re = a.re - b.re; + c.im = a.im - b.im; return c; } @@ -93,8 +94,8 @@ static t_complex cmul(t_complex a, t_complex b) { t_complex c; - c.re = a.re*b.re - a.im*b.im; - c.im = a.re*b.im + a.im*b.re; + c.re = a.re * b.re - a.im * b.im; + c.im = a.re * b.im + a.im * b.re; return c; } @@ -103,7 +104,7 @@ static t_complex conjugate(t_complex c) { t_complex d; - d.re = c.re; + d.re = c.re; d.im = -c.im; return d; @@ -112,7 +113,7 @@ static t_complex conjugate(t_complex c) static inline real cabs2(t_complex c) { real abs2; - abs2 = (c.re*c.re)+(c.im*c.im); + abs2 = (c.re * c.re) + (c.im * c.im); return abs2; } @@ -124,10 +125,16 @@ static inline t_complex cdiv(t_complex teller, t_complex noemer) anoemer = cmul(conjugate(noemer), noemer); res = cmul(teller, conjugate(noemer)); - return rcmul(1.0/anoemer.re, res); + return rcmul(1.0 / anoemer.re, res); } -inline bool operator==(const t_complex &lhs, const t_complex &rhs){ return (lhs.re == rhs.re) && (lhs.im == rhs.im); } -inline bool operator!=(const t_complex &lhs, const t_complex &rhs){ return !(lhs == rhs); } +inline bool operator==(const t_complex& lhs, const t_complex& rhs) +{ + return (lhs.re == rhs.re) && (lhs.im == rhs.im); +} +inline bool operator!=(const t_complex& lhs, const t_complex& rhs) +{ + return !(lhs == rhs); +} #endif diff --git a/src/gromacs/math/invertmatrix.cpp b/src/gromacs/math/invertmatrix.cpp index b03ce46489..b136f147f6 100644 --- a/src/gromacs/math/invertmatrix.cpp +++ b/src/gromacs/math/invertmatrix.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,19 +53,18 @@ namespace gmx void invertBoxMatrix(const matrix src, matrix dest) { - double tmp = src[XX][XX]*src[YY][YY]*src[ZZ][ZZ]; - if (std::fabs(tmp) <= 100*GMX_REAL_MIN) + double tmp = src[XX][XX] * src[YY][YY] * src[ZZ][ZZ]; + if (std::fabs(tmp) <= 100 * GMX_REAL_MIN) { gmx_fatal(FARGS, "Can not invert matrix, determinant is zero"); } - dest[XX][XX] = 1/src[XX][XX]; - dest[YY][YY] = 1/src[YY][YY]; - dest[ZZ][ZZ] = 1/src[ZZ][ZZ]; - dest[ZZ][XX] = (src[YY][XX]*src[ZZ][YY]*dest[YY][YY] - - src[ZZ][XX])*dest[XX][XX]*dest[ZZ][ZZ]; - dest[YY][XX] = -src[YY][XX]*dest[XX][XX]*dest[YY][YY]; - dest[ZZ][YY] = -src[ZZ][YY]*dest[YY][YY]*dest[ZZ][ZZ]; + dest[XX][XX] = 1 / src[XX][XX]; + dest[YY][YY] = 1 / src[YY][YY]; + dest[ZZ][ZZ] = 1 / src[ZZ][ZZ]; + dest[ZZ][XX] = (src[YY][XX] * src[ZZ][YY] * dest[YY][YY] - src[ZZ][XX]) * dest[XX][XX] * dest[ZZ][ZZ]; + dest[YY][XX] = -src[YY][XX] * dest[XX][XX] * dest[YY][YY]; + dest[ZZ][YY] = -src[ZZ][YY] * dest[YY][YY] * dest[ZZ][ZZ]; dest[XX][YY] = 0.0; dest[XX][ZZ] = 0.0; dest[YY][ZZ] = 0.0; @@ -76,9 +75,9 @@ void invertMatrix(const matrix src, matrix dest) const real smallreal = 1.0e-24_real; const real largereal = 1.0e24_real; - real determinant = det(src); - real c = 1.0_real/determinant; - real fc = std::fabs(c); + real determinant = det(src); + real c = 1.0_real / determinant; + real fc = std::fabs(c); if ((fc <= smallreal) || (fc >= largereal)) { @@ -86,15 +85,15 @@ void invertMatrix(const matrix src, matrix dest) } GMX_ASSERT(dest != src, "Cannot do in-place inversion of matrix"); - dest[XX][XX] = c*(src[YY][YY]*src[ZZ][ZZ]-src[ZZ][YY]*src[YY][ZZ]); - dest[XX][YY] = -c*(src[XX][YY]*src[ZZ][ZZ]-src[ZZ][YY]*src[XX][ZZ]); - dest[XX][ZZ] = c*(src[XX][YY]*src[YY][ZZ]-src[YY][YY]*src[XX][ZZ]); - dest[YY][XX] = -c*(src[YY][XX]*src[ZZ][ZZ]-src[ZZ][XX]*src[YY][ZZ]); - dest[YY][YY] = c*(src[XX][XX]*src[ZZ][ZZ]-src[ZZ][XX]*src[XX][ZZ]); - dest[YY][ZZ] = -c*(src[XX][XX]*src[YY][ZZ]-src[YY][XX]*src[XX][ZZ]); - dest[ZZ][XX] = c*(src[YY][XX]*src[ZZ][YY]-src[ZZ][XX]*src[YY][YY]); - dest[ZZ][YY] = -c*(src[XX][XX]*src[ZZ][YY]-src[ZZ][XX]*src[XX][YY]); - dest[ZZ][ZZ] = c*(src[XX][XX]*src[YY][YY]-src[YY][XX]*src[XX][YY]); + dest[XX][XX] = c * (src[YY][YY] * src[ZZ][ZZ] - src[ZZ][YY] * src[YY][ZZ]); + dest[XX][YY] = -c * (src[XX][YY] * src[ZZ][ZZ] - src[ZZ][YY] * src[XX][ZZ]); + dest[XX][ZZ] = c * (src[XX][YY] * src[YY][ZZ] - src[YY][YY] * src[XX][ZZ]); + dest[YY][XX] = -c * (src[YY][XX] * src[ZZ][ZZ] - src[ZZ][XX] * src[YY][ZZ]); + dest[YY][YY] = c * (src[XX][XX] * src[ZZ][ZZ] - src[ZZ][XX] * src[XX][ZZ]); + dest[YY][ZZ] = -c * (src[XX][XX] * src[YY][ZZ] - src[YY][XX] * src[XX][ZZ]); + dest[ZZ][XX] = c * (src[YY][XX] * src[ZZ][YY] - src[ZZ][XX] * src[YY][YY]); + dest[ZZ][YY] = -c * (src[XX][XX] * src[ZZ][YY] - src[ZZ][XX] * src[XX][YY]); + dest[ZZ][ZZ] = c * (src[XX][XX] * src[YY][YY] - src[YY][XX] * src[XX][YY]); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/math/matrix.h b/src/gromacs/math/matrix.h index 9fcec3f388..c4b428c9ea 100644 --- a/src/gromacs/math/matrix.h +++ b/src/gromacs/math/matrix.h @@ -55,24 +55,24 @@ namespace gmx /*! \brief Three-by-three matrix of ElementType. * \tparam ElementType type of element to be stored in matrix */ -template -using BasicMatrix3x3 = MultiDimArray, extents <3, 3> >; +template +using BasicMatrix3x3 = MultiDimArray, extents<3, 3>>; /*! \brief Three-by-three real number matrix. * \note will replace the C-style real[3][3] "matrix" */ -using Matrix3x3 = BasicMatrix3x3; +using Matrix3x3 = BasicMatrix3x3; //! Convenience alias for a matrix view -using Matrix3x3Span = Matrix3x3::view_type; +using Matrix3x3Span = Matrix3x3::view_type; //! Convenience alias for a const matrix view using Matrix3x3ConstSpan = Matrix3x3::const_view_type; //! Determinant of a 3x3 matrix constexpr real determinant(Matrix3x3ConstSpan matrix) { - return ( matrix(0, 0)*(matrix(1, 1)*matrix(2, 2)-matrix(2, 1)*matrix(1, 2)) - -matrix(1, 0)*(matrix(0, 1)*matrix(2, 2)-matrix(2, 1)*matrix(0, 2)) - +matrix(2, 0)*(matrix(0, 1)*matrix(1, 2)-matrix(1, 1)*matrix(0, 2))); + return (matrix(0, 0) * (matrix(1, 1) * matrix(2, 2) - matrix(2, 1) * matrix(1, 2)) + - matrix(1, 0) * (matrix(0, 1) * matrix(2, 2) - matrix(2, 1) * matrix(0, 2)) + + matrix(2, 0) * (matrix(0, 1) * matrix(1, 2) - matrix(1, 1) * matrix(0, 2))); } //! Calculates the trace of a 3x3 matrix view @@ -85,9 +85,9 @@ constexpr real trace(Matrix3x3ConstSpan matrixView) static Matrix3x3 transpose(Matrix3x3ConstSpan matrixView) { - return Matrix3x3({matrixView(0, 0), matrixView(1, 0), matrixView(2, 0), - matrixView(0, 1), matrixView(1, 1), matrixView(2, 1), - matrixView(0, 2), matrixView(1, 2), matrixView(2, 2)}); + return Matrix3x3({ matrixView(0, 0), matrixView(1, 0), matrixView(2, 0), matrixView(0, 1), + matrixView(1, 1), matrixView(2, 1), matrixView(0, 2), matrixView(1, 2), + matrixView(2, 2) }); } //! Create new matrix type from legacy type. diff --git a/src/gromacs/math/multidimarray.h b/src/gromacs/math/multidimarray.h index 9b6aee3f2f..2e1a9e2eb6 100644 --- a/src/gromacs/math/multidimarray.h +++ b/src/gromacs/math/multidimarray.h @@ -54,19 +54,23 @@ namespace gmx namespace detail { //! Same as std::void_t from C++17 -template< class ... > +template using void_t = void; template -struct is_resizable : std::false_type {}; +struct is_resizable : std::false_type +{ +}; template -struct is_resizable().resize(size_t()))> > : std::true_type {}; +struct is_resizable().resize(size_t()))>> : std::true_type +{ +}; //! Type has a resize member function callable with size_t argument template constexpr bool is_resizable_v = is_resizable::value; -} //namespace detail +} // namespace detail /*! \libinternal \brief * Multidimensional array that manages its own memory. @@ -96,223 +100,216 @@ constexpr bool is_resizable_v = is_resizable::value; * Defaults to right aligned, so that the right-most index * is contiguous in memory. */ -template +template class MultiDimArray { - public: - //! the type of values that are stored - using value_type = typename TContainer::value_type; - //! reference type to the stored values - using reference = typename TContainer::reference; - //! const reference type to the stored values - using const_reference = typename TContainer::const_reference; - //! the view used to access the data - using view_type = basic_mdspan; - //! const view on the data - using const_view_type = basic_mdspan; - /*! \brief Iterator type for contiguous iteration over the stored data. - * Used, e.g., in free begin and end functions - */ - using iterator = typename ArrayRef::iterator; - /*! \brief Const iterator type for contiguous iteration over the stored data. - * used, e.g., in free begin and end functions - */ - using const_iterator = const typename ArrayRef::const_iterator; +public: + //! the type of values that are stored + using value_type = typename TContainer::value_type; + //! reference type to the stored values + using reference = typename TContainer::reference; + //! const reference type to the stored values + using const_reference = typename TContainer::const_reference; + //! the view used to access the data + using view_type = basic_mdspan; + //! const view on the data + using const_view_type = basic_mdspan; + /*! \brief Iterator type for contiguous iteration over the stored data. + * Used, e.g., in free begin and end functions + */ + using iterator = typename ArrayRef::iterator; + /*! \brief Const iterator type for contiguous iteration over the stored data. + * used, e.g., in free begin and end functions + */ + using const_iterator = const typename ArrayRef::const_iterator; + + static_assert(detail::is_resizable_v == (Extents::rank_dynamic() > 0), + "Resizable container (e.g. std::vector) requires at least one dynamic rank. " + "Non-resizable container (e.g. std::array) requires zero dynamic ranks."); - static_assert(detail::is_resizable_v == (Extents::rank_dynamic() > 0), - "Resizable container (e.g. std::vector) requires at least one dynamic rank. " - "Non-resizable container (e.g. std::array) requires zero dynamic ranks."); + /*! \brief + * Allocate dynamic array data and set view with the dynamic extents. + * + * \param[in] dynamicExtent A parameter pack that describes the dynamic + * size of the array. Empty if purely static. + * + * \tparam IndexType Parameter pack type holding the dynamic + * extents of the multidimensional array + */ + template>> + MultiDimArray(IndexType... dynamicExtent) + { + resize(dynamicExtent...); + } + /*! \brief + * Construction from fixed sized arrays if the array size is static and + * layout policy allows compile time determination of the container size. + * + * Enables the expected initialization + * MultiDimArray, extents<3,3>> arr = {{1,2...}} + * \tparam T Template parameter for activation via SFINAE. + */ + // SFINAE required because std::vector::size isn't constexpr and is_constexpr doesn't exist. + template>> + constexpr MultiDimArray(const TContainer& data = {}) noexcept : data_(data), view_(data_.data()) + { + static_assert(TContainer().size() == typename view_type::mapping_type().required_span_size(), + "Non-resizable container type size must match static MultiDimArray size."); + } + //! Copy constructor + constexpr MultiDimArray(const MultiDimArray& o) : + data_(o.data_), + view_(data_.data(), o.view_.extents()) + { + } + //! Move constructor + MultiDimArray(MultiDimArray&& o) noexcept : + data_(std::move(o.data_)), + view_(data_.data(), o.view_.extents()) + { + } + //! Copy assignment + MultiDimArray& operator=(const MultiDimArray& o) + { + data_ = o.data_; + view_ = view_type(data_.data(), o.view_.extents()); + return *this; + } + //! Move assignment + MultiDimArray& operator=(MultiDimArray&& o) noexcept + { + data_ = std::move(o.data_); + view_ = view_type(data_.data(), o.view_.extents()); + return *this; + } + //! Swaps content with other + void swap(MultiDimArray& o) + { + using std::swap; + swap(data_, o.data_); + // swap(view_, o.view_) also swaps the pointer to the data and thus does not work + // instead, restore the view as class invariant after the data swapping operation + o.view_ = view_type(o.data_.data(), view_.extents()); + view_ = view_type(data_.data(), o.view_.extents()); + } + /*! \brief + * Resize the dynamic extents of the array if any and set container size + * accordingly. + * + * Invalidates data and views of this array. + * + * \param[in] dynamicExtent A parameter pack that describes the dynamic + * size of the array. Empty if purely static. + * \tparam IndexType Parameter pack type holding the dynamic + * extents of the multidimensional array + */ + template + void resize(IndexType... dynamicExtent) + { + // use a mapping object to determine the required span size; + layout_right::mapping map{ Extents{ dynamicExtent... } }; + data_.resize(map.required_span_size()); + // to construct a valid view on the data, the container has to be resized before + // the assignment, so that data_.data() is valid + view_ = view_type(data_.data(), dynamicExtent...); + } + /*! \brief Data access via multidimensional indices. + * This allows referencing rank R array elements as array(x_0,x_1,x_2, .., x_R) + * + * \param[in] index multidimensional indices as parameter pack + * the number of parameters must match the rank of the array. + * + * \returns reference to array element + */ + template + reference operator()(IndexType... index) noexcept + { + return view_(index...); + } + /*! \brief Const data access via multidimensional indices. + * This allows referencing rank R array elements as array(x_0,x_1,x_2, .., x_R) + * + * \param[in] index multidimensional indices as parameter pack + * the number of parameters must match the rank of the array. + * + * \returns const reference to array element + */ + template + constexpr const_reference operator()(IndexType... index) const noexcept + { + return view_(index...); + } + /*! \brief Contiguous access to the data. + * \returns ArrayRef to stored data. + */ + ArrayRef toArrayRef() { return { data_.data(), data_.data() + data_.size() }; } + /*! \brief Contiguous const access to the data. + * \returns ArrayRef to stored data. + */ + constexpr ArrayRef toArrayRef() const + { + return { data_.data(), data_.data() + data_.size() }; + } + /*! \brief Return the extent. + * \param[in] k dimension to query for extent + * \returns extent along specified dimension + */ + constexpr typename view_type::index_type extent(int k) const noexcept + { + return view_.extent(k); + } + //! Conversion to multidimensional view on the data + constexpr view_type asView() noexcept { return view_; } + //! Conversion to const multidimensional view on the data + constexpr const_view_type asConstView() const noexcept + { + return { data_.data(), view_.mapping() }; + } - /*! \brief - * Allocate dynamic array data and set view with the dynamic extents. - * - * \param[in] dynamicExtent A parameter pack that describes the dynamic - * size of the array. Empty if purely static. - * - * \tparam IndexType Parameter pack type holding the dynamic - * extents of the multidimensional array - */ - template > > - MultiDimArray(IndexType... dynamicExtent) - { - resize(dynamicExtent ...); - } - /*! \brief - * Construction from fixed sized arrays if the array size is static and - * layout policy allows compile time determination of the container size. - * - * Enables the expected initialization - * MultiDimArray, extents<3,3>> arr = {{1,2...}} - * \tparam T Template parameter for activation via SFINAE. - */ - // SFINAE required because std::vector::size isn't constexpr and is_constexpr doesn't exist. - template > > - constexpr MultiDimArray(const TContainer &data = {} - ) noexcept : data_(data), view_(data_.data()) - { - static_assert(TContainer().size() == typename view_type::mapping_type().required_span_size(), - "Non-resizable container type size must match static MultiDimArray size."); - } - //! Copy constructor - constexpr MultiDimArray(const MultiDimArray &o) : - data_(o.data_), - view_(data_.data(), o.view_.extents()) - {} - //! Move constructor - MultiDimArray(MultiDimArray &&o) noexcept : data_(std::move(o.data_)), - view_(data_.data(), o.view_.extents()) - {} - //! Copy assignment - MultiDimArray &operator=(const MultiDimArray &o) - { - data_ = o.data_; - view_ = view_type(data_.data(), o.view_.extents()); - return *this; - } - //! Move assignment - MultiDimArray &operator=(MultiDimArray &&o) noexcept - { - data_ = std::move(o.data_); - view_ = view_type(data_.data(), o.view_.extents()); - return *this; - } - //! Swaps content with other - void swap(MultiDimArray &o) - { - using std::swap; - swap(data_, o.data_); - // swap(view_, o.view_) also swaps the pointer to the data and thus does not work - // instead, restore the view as class invariant after the data swapping operation - o.view_ = view_type(o.data_.data(), view_.extents()); - view_ = view_type(data_.data(), o.view_.extents()); - } - /*! \brief - * Resize the dynamic extents of the array if any and set container size - * accordingly. - * - * Invalidates data and views of this array. - * - * \param[in] dynamicExtent A parameter pack that describes the dynamic - * size of the array. Empty if purely static. - * \tparam IndexType Parameter pack type holding the dynamic - * extents of the multidimensional array - */ - template - void resize(IndexType... dynamicExtent) - { - // use a mapping object to determine the required span size; - layout_right::mapping map {Extents {dynamicExtent ...}}; - data_.resize(map.required_span_size()); - // to construct a valid view on the data, the container has to be resized before - // the assignment, so that data_.data() is valid - view_ = view_type(data_.data(), dynamicExtent ...); - } - /*! \brief Data access via multidimensional indices. - * This allows referencing rank R array elements as array(x_0,x_1,x_2, .., x_R) - * - * \param[in] index multidimensional indices as parameter pack - * the number of parameters must match the rank of the array. - * - * \returns reference to array element - */ - template< class... IndexType> - reference operator()(IndexType ... index) noexcept - { - return view_(index ...); - } - /*! \brief Const data access via multidimensional indices. - * This allows referencing rank R array elements as array(x_0,x_1,x_2, .., x_R) - * - * \param[in] index multidimensional indices as parameter pack - * the number of parameters must match the rank of the array. - * - * \returns const reference to array element - */ - template - constexpr const_reference operator()(IndexType... index) const noexcept - { - return view_(index ...); - } - /*! \brief Contiguous access to the data. - * \returns ArrayRef to stored data. - */ - ArrayRef toArrayRef() - { - return {data_.data(), data_.data()+data_.size()}; - } - /*! \brief Contiguous const access to the data. - * \returns ArrayRef to stored data. - */ - constexpr ArrayRef toArrayRef() const - { - return {data_.data(), data_.data()+data_.size()}; - } - /*! \brief Return the extent. - * \param[in] k dimension to query for extent - * \returns extent along specified dimension - */ - constexpr typename view_type::index_type extent(int k) const noexcept - { - return view_.extent(k); - } - //! Conversion to multidimensional view on the data - constexpr view_type asView() noexcept - { - return view_; - } - //! Conversion to const multidimensional view on the data - constexpr const_view_type asConstView() const noexcept - { - return {data_.data(), view_.mapping()}; - } - private: - //! The contiguous data that is equipped with multidimensional indexing in this class - TContainer data_; - //! Multidimensional view into data_. - view_type view_; +private: + //! The contiguous data that is equipped with multidimensional indexing in this class + TContainer data_; + //! Multidimensional view into data_. + view_type view_; }; //! Free MultiDimArray begin function addressing its contiguous memory. -template +template constexpr typename MultiDimArray::const_iterator -begin(const MultiDimArray &multiDimArray) +begin(const MultiDimArray& multiDimArray) { return multiDimArray.toArrayRef().begin(); } //! Free MultiDimArray begin function addressing its contiguous memory. -template -constexpr typename MultiDimArray::iterator -begin(MultiDimArray &multiDimArray) +template +constexpr typename MultiDimArray::iterator begin(MultiDimArray& multiDimArray) { return multiDimArray.toArrayRef().begin(); } //! Free MultiDimArray end function addressing its contiguous memory. -template +template constexpr typename MultiDimArray::const_iterator -end(const MultiDimArray &multiDimArray) +end(const MultiDimArray& multiDimArray) { return multiDimArray.toArrayRef().end(); } //! Free MultiDimArray end function addressing its contiguous memory. -template -constexpr typename MultiDimArray::iterator -end(MultiDimArray &multiDimArray) +template +constexpr typename MultiDimArray::iterator end(MultiDimArray& multiDimArray) { return multiDimArray.toArrayRef().end(); } //! Swap function -template -void swap(MultiDimArray &a, MultiDimArray &b) noexcept +template +void swap(MultiDimArray& a, MultiDimArray& b) noexcept { a.swap(b); } -} // namespace gmx +} // namespace gmx #endif // GMX_MATH_MULTIDIMARRAY_H_ diff --git a/src/gromacs/math/paddedvector.h b/src/gromacs/math/paddedvector.h index fa66983af8..79e5c1b08b 100644 --- a/src/gromacs/math/paddedvector.h +++ b/src/gromacs/math/paddedvector.h @@ -72,40 +72,42 @@ namespace detail * implementations. */ template -struct PaddingTraits {}; +struct PaddingTraits +{ +}; template<> struct PaddingTraits { - using SimdBaseType = int32_t; + using SimdBaseType = int32_t; static constexpr int maxSimdWidthOfBaseType = 16; }; template<> struct PaddingTraits { - using SimdBaseType = float; + using SimdBaseType = float; static constexpr int maxSimdWidthOfBaseType = GMX_FLOAT_MAX_SIMD_WIDTH; }; template<> struct PaddingTraits { - using SimdBaseType = double; + using SimdBaseType = double; static constexpr int maxSimdWidthOfBaseType = GMX_DOUBLE_MAX_SIMD_WIDTH; }; template<> -struct PaddingTraits < BasicVector < float>> +struct PaddingTraits> { - using SimdBaseType = float; + using SimdBaseType = float; static constexpr int maxSimdWidthOfBaseType = GMX_FLOAT_MAX_SIMD_WIDTH; }; template<> -struct PaddingTraits < BasicVector < double>> +struct PaddingTraits> { - using SimdBaseType = double; + using SimdBaseType = double; static constexpr int maxSimdWidthOfBaseType = GMX_DOUBLE_MAX_SIMD_WIDTH; }; @@ -116,7 +118,7 @@ struct PaddingTraits < BasicVector < double>> * \returns The number of T elements that must be allocated * (ie >= numElements). */ -template +template index computePaddedSize(index numElements) { // We don't need padding if there is no access. @@ -141,16 +143,15 @@ index computePaddedSize(index numElements) // We don't want a dependence on the SIMD module for the actual // SIMD width of the base type, so we use maximum for the base // type via the traits. A little extra padding won't really hurt. - constexpr int maxSimdWidth = PaddingTraits::maxSimdWidthOfBaseType; - index simdFlatAccessSize = (numElements + (maxSimdWidth-1)) / maxSimdWidth * maxSimdWidth; + constexpr int maxSimdWidth = PaddingTraits::maxSimdWidthOfBaseType; + index simdFlatAccessSize = (numElements + (maxSimdWidth - 1)) / maxSimdWidth * maxSimdWidth; return std::max(simdScatterAccessSize, simdFlatAccessSize); } //! Helper function to insert padding elements for most T. -template -inline void insertPaddingElements(std::vector *v, - index newPaddedSize) +template +inline void insertPaddingElements(std::vector* v, index newPaddedSize) { // Ensure the padding region is initialized to zero. There is no // way to insert a number of default-initialized elements. So we @@ -160,15 +161,14 @@ inline void insertPaddingElements(std::vector *v, } //! Specialization of helper function to insert padding elements, used for BasicVector. -template -inline void insertPaddingElements(std::vector, AllocatorType> *v, - index newPaddedSize) +template +inline void insertPaddingElements(std::vector, AllocatorType>* v, index newPaddedSize) { // Ensure the padding region is initialized to zero. v->insert(v->end(), newPaddedSize - v->size(), BasicVector(0, 0, 0)); } -} // namespace detail +} // namespace detail /*! \brief PaddedVector is a container of elements in contiguous * storage that allocates extra memory for safe SIMD-style loads for @@ -208,224 +208,210 @@ inline void insertPaddingElements(std::vector, AllocatorType> *v, * physical memory for efficient transfers. The default allocator * ensures alignment, but std::allocator also works. */ -template > +template> class PaddedVector { - public: - //! Standard helper types - //! \{ - using value_type = T; - using allocator_type = Allocator; - using size_type = index; - using reference = value_type &; - using const_reference = const value_type &; - using storage_type = std::vector; - using pointer = typename storage_type::pointer; - using const_pointer = typename storage_type::const_pointer; - using iterator = typename storage_type::iterator; - using const_iterator = typename storage_type::const_iterator; - using difference_type = typename storage_type::iterator::difference_type; - //! \} +public: + //! Standard helper types + //! \{ + using value_type = T; + using allocator_type = Allocator; + using size_type = index; + using reference = value_type&; + using const_reference = const value_type&; + using storage_type = std::vector; + using pointer = typename storage_type::pointer; + using const_pointer = typename storage_type::const_pointer; + using iterator = typename storage_type::iterator; + using const_iterator = typename storage_type::const_iterator; + using difference_type = typename storage_type::iterator::difference_type; + //! \} - PaddedVector() : - storage_(), - unpaddedEnd_(begin()) - {} - /*! \brief Constructor that specifes the initial size. */ - explicit PaddedVector(size_type count, - const allocator_type &allocator = Allocator()) : - storage_(count, allocator), - unpaddedEnd_(begin() + count) - { - // The count elements have been default inserted, and now - // the padding elements are added - resizeWithPadding(count); - } - /*! \brief Constructor that specifes the initial size and an element to copy. */ - explicit PaddedVector(size_type count, - value_type const &v, - const allocator_type &allocator = Allocator()) : - storage_(count, v, allocator), - unpaddedEnd_(begin() + count) - { - // The count elements have been default inserted, and now - // the padding elements are added - resizeWithPadding(count); - } - //! Default constructor with allocator - explicit PaddedVector(allocator_type const &allocator) : - storage_(allocator), - unpaddedEnd_(begin()) - {} - //! Copy constructor - PaddedVector(PaddedVector const &o) : - storage_(o.storage_), - unpaddedEnd_(begin() + o.size()) - {} - //! Move constructor - PaddedVector(PaddedVector &&o) noexcept : - storage_(std::move(o.storage_)), - unpaddedEnd_(std::move(o.unpaddedEnd_)) - { - unpaddedEnd_ = begin(); - } - //! Move constructor using \c alloc for the new vector. - PaddedVector(PaddedVector &&o, const Allocator &alloc) noexcept : - storage_(std::move(alloc)), - unpaddedEnd_(begin()) - { - auto unpaddedSize = o.size(); - if (alloc == o.storage_.get_allocator()) - { - storage_ = std::move(o.storage_); - } - else - { - // If the allocator compares differently, we must - // reallocate and copy. - resizeWithPadding(unpaddedSize); - std::copy(o.begin(), o.end(), storage_.begin()); - } - unpaddedEnd_ = begin() + unpaddedSize; - } - //! Construct from an initializer list - PaddedVector(std::initializer_list const &il) : - storage_(il), - unpaddedEnd_(storage_.end()) - { - // We can't choose the padding until we know the size of - // the normal vector, so we have to make the storage_ and - // then resize it. - resizeWithPadding(storage_.size()); - } - //! Reserve storage for the container to contain newExtent elements, plus the required padding. - void reserveWithPadding(const size_type newExtent) - { - auto unpaddedSize = end() - begin(); - /* v.reserve(13) should allocate enough memory so that - v.resize(13) does not reallocate. This means that the - new extent should be large enough for the padded - storage for a vector whose size is newExtent. */ - auto newPaddedExtent = detail::computePaddedSize(newExtent); - storage_.reserve(newPaddedExtent); - unpaddedEnd_ = begin() + unpaddedSize; - } - //! Resize the container to contain newSize elements, plus the required padding. - void resizeWithPadding(const size_type newSize) - { - // When the contained type is e.g. a scalar, then the - // default initialization behaviour is to zero all - // elements, which is OK, but we have to make sure that it - // happens for the elements in the padded region when the - // vector is shrinking. - auto newPaddedSize = detail::computePaddedSize(newSize); - // Make sure there is room for padding if we need to grow. - storage_.reserve(newPaddedSize); - // Make the unpadded size correct, with any additional - // elements initialized by the default constructor. It is - // particularly important to destruct former elements when - // newSize is smaller than the old size. - storage_.resize(newSize); - // Ensure the padding region is zeroed if required. - detail::insertPaddingElements(&storage_, newPaddedSize); - unpaddedEnd_ = begin() + newSize; - } - //! Return the size of the view without the padding. - size_type size() const { return end() - begin(); } - //! Return the container size including the padding. - size_type paddedSize() const { return storage_.size(); } - //! Return whether the storage is empty. - bool empty() const { return storage_.empty(); } - //! Swap two PaddedVectors - void swap(PaddedVector &x) + PaddedVector() : storage_(), unpaddedEnd_(begin()) {} + /*! \brief Constructor that specifes the initial size. */ + explicit PaddedVector(size_type count, const allocator_type& allocator = Allocator()) : + storage_(count, allocator), + unpaddedEnd_(begin() + count) + { + // The count elements have been default inserted, and now + // the padding elements are added + resizeWithPadding(count); + } + /*! \brief Constructor that specifes the initial size and an element to copy. */ + explicit PaddedVector(size_type count, value_type const& v, const allocator_type& allocator = Allocator()) : + storage_(count, v, allocator), + unpaddedEnd_(begin() + count) + { + // The count elements have been default inserted, and now + // the padding elements are added + resizeWithPadding(count); + } + //! Default constructor with allocator + explicit PaddedVector(allocator_type const& allocator) : + storage_(allocator), + unpaddedEnd_(begin()) + { + } + //! Copy constructor + PaddedVector(PaddedVector const& o) : storage_(o.storage_), unpaddedEnd_(begin() + o.size()) {} + //! Move constructor + PaddedVector(PaddedVector&& o) noexcept : + storage_(std::move(o.storage_)), + unpaddedEnd_(std::move(o.unpaddedEnd_)) + { + unpaddedEnd_ = begin(); + } + //! Move constructor using \c alloc for the new vector. + PaddedVector(PaddedVector&& o, const Allocator& alloc) noexcept : + storage_(std::move(alloc)), + unpaddedEnd_(begin()) + { + auto unpaddedSize = o.size(); + if (alloc == o.storage_.get_allocator()) { - std::swap(storage_, x.storage_); - std::swap(unpaddedEnd_, x.unpaddedEnd_); + storage_ = std::move(o.storage_); } - //! Clear the vector, ie. set size to zero and remove padding. - void clear() + else { - storage_.clear(); - unpaddedEnd_ = begin(); + // If the allocator compares differently, we must + // reallocate and copy. + resizeWithPadding(unpaddedSize); + std::copy(o.begin(), o.end(), storage_.begin()); } - //! Iterator getters refer to a view without padding. - //! \{ - pointer data() noexcept { return storage_.data(); } - const_pointer data() const noexcept { return storage_.data(); } + unpaddedEnd_ = begin() + unpaddedSize; + } + //! Construct from an initializer list + PaddedVector(std::initializer_list const& il) : + storage_(il), + unpaddedEnd_(storage_.end()) + { + // We can't choose the padding until we know the size of + // the normal vector, so we have to make the storage_ and + // then resize it. + resizeWithPadding(storage_.size()); + } + //! Reserve storage for the container to contain newExtent elements, plus the required padding. + void reserveWithPadding(const size_type newExtent) + { + auto unpaddedSize = end() - begin(); + /* v.reserve(13) should allocate enough memory so that + v.resize(13) does not reallocate. This means that the + new extent should be large enough for the padded + storage for a vector whose size is newExtent. */ + auto newPaddedExtent = detail::computePaddedSize(newExtent); + storage_.reserve(newPaddedExtent); + unpaddedEnd_ = begin() + unpaddedSize; + } + //! Resize the container to contain newSize elements, plus the required padding. + void resizeWithPadding(const size_type newSize) + { + // When the contained type is e.g. a scalar, then the + // default initialization behaviour is to zero all + // elements, which is OK, but we have to make sure that it + // happens for the elements in the padded region when the + // vector is shrinking. + auto newPaddedSize = detail::computePaddedSize(newSize); + // Make sure there is room for padding if we need to grow. + storage_.reserve(newPaddedSize); + // Make the unpadded size correct, with any additional + // elements initialized by the default constructor. It is + // particularly important to destruct former elements when + // newSize is smaller than the old size. + storage_.resize(newSize); + // Ensure the padding region is zeroed if required. + detail::insertPaddingElements(&storage_, newPaddedSize); + unpaddedEnd_ = begin() + newSize; + } + //! Return the size of the view without the padding. + size_type size() const { return end() - begin(); } + //! Return the container size including the padding. + size_type paddedSize() const { return storage_.size(); } + //! Return whether the storage is empty. + bool empty() const { return storage_.empty(); } + //! Swap two PaddedVectors + void swap(PaddedVector& x) + { + std::swap(storage_, x.storage_); + std::swap(unpaddedEnd_, x.unpaddedEnd_); + } + //! Clear the vector, ie. set size to zero and remove padding. + void clear() + { + storage_.clear(); + unpaddedEnd_ = begin(); + } + //! Iterator getters refer to a view without padding. + //! \{ + pointer data() noexcept { return storage_.data(); } + const_pointer data() const noexcept { return storage_.data(); } - iterator begin() { return storage_.begin(); } - iterator end() { return iterator(unpaddedEnd_); } + iterator begin() { return storage_.begin(); } + iterator end() { return iterator(unpaddedEnd_); } - const_iterator cbegin() { return const_iterator(begin()); } - const_iterator cend() { return const_iterator(unpaddedEnd_); } + const_iterator cbegin() { return const_iterator(begin()); } + const_iterator cend() { return const_iterator(unpaddedEnd_); } - const_iterator begin() const { return storage_.begin(); } - const_iterator end() const { return const_iterator(unpaddedEnd_); } + const_iterator begin() const { return storage_.begin(); } + const_iterator end() const { return const_iterator(unpaddedEnd_); } - const_iterator cbegin() const { return const_iterator(begin()); } - const_iterator cend() const { return const_iterator(unpaddedEnd_); } - //! \} - // TODO should these do bounds checking for the unpadded range? In debug mode? - //! Indexing operator. - reference operator[](int i) { return storage_[i]; } - //! Indexing operator as const. - const_reference operator[](int i) const { return storage_[i]; } - //! Returns an ArrayRef of elements that includes the padding region, e.g. for use in SIMD code. - ArrayRefWithPadding arrayRefWithPadding() - { - return ArrayRefWithPadding(data(), data()+size(), data()+paddedSize()); - } - //! Returns an ArrayRef of const elements that includes the padding region, e.g. for use in SIMD code. - ArrayRefWithPadding constArrayRefWithPadding() const - { - return ArrayRefWithPadding(data(), data()+size(), data()+paddedSize()); - } - //! Returns an rvec * pointer for containers of RVec, for use with legacy code. - template ::value> > - rvec *rvec_array() - { - return as_rvec_array(data()); - } - //! Returns a const rvec * pointer for containers of RVec, for use with legacy code. - template ::value> > - const rvec *rvec_array() const - { - return as_rvec_array(data()); - } - //! Copy assignment operator - PaddedVector &operator=(PaddedVector const &o) - { - if (&o != this) - { - storage_ = o.storage_; - unpaddedEnd_ = begin() + o.size(); - } - return *this; - } - //! Move assignment operator - PaddedVector &operator=(PaddedVector &&o) noexcept + const_iterator cbegin() const { return const_iterator(begin()); } + const_iterator cend() const { return const_iterator(unpaddedEnd_); } + //! \} + // TODO should these do bounds checking for the unpadded range? In debug mode? + //! Indexing operator. + reference operator[](int i) { return storage_[i]; } + //! Indexing operator as const. + const_reference operator[](int i) const { return storage_[i]; } + //! Returns an ArrayRef of elements that includes the padding region, e.g. for use in SIMD code. + ArrayRefWithPadding arrayRefWithPadding() + { + return ArrayRefWithPadding(data(), data() + size(), data() + paddedSize()); + } + //! Returns an ArrayRef of const elements that includes the padding region, e.g. for use in SIMD code. + ArrayRefWithPadding constArrayRefWithPadding() const + { + return ArrayRefWithPadding(data(), data() + size(), data() + paddedSize()); + } + //! Returns an rvec * pointer for containers of RVec, for use with legacy code. + template::value>> + rvec* rvec_array() + { + return as_rvec_array(data()); + } + //! Returns a const rvec * pointer for containers of RVec, for use with legacy code. + template::value>> + const rvec* rvec_array() const + { + return as_rvec_array(data()); + } + //! Copy assignment operator + PaddedVector& operator=(PaddedVector const& o) + { + if (&o != this) { - if (&o != this) - { - auto oSize = o.size(); - storage_ = std::move(o.storage_); - unpaddedEnd_ = begin() + oSize; - o.unpaddedEnd_ = o.begin(); - } - return *this; + storage_ = o.storage_; + unpaddedEnd_ = begin() + o.size(); } - //! Getter for the allocator - allocator_type - get_allocator() const + return *this; + } + //! Move assignment operator + PaddedVector& operator=(PaddedVector&& o) noexcept + { + if (&o != this) { - return storage_.get_allocator(); + auto oSize = o.size(); + storage_ = std::move(o.storage_); + unpaddedEnd_ = begin() + oSize; + o.unpaddedEnd_ = o.begin(); } + return *this; + } + //! Getter for the allocator + allocator_type get_allocator() const { return storage_.get_allocator(); } - private: - storage_type storage_; - iterator unpaddedEnd_; +private: + storage_type storage_; + iterator unpaddedEnd_; }; } // namespace gmx diff --git a/src/gromacs/math/tests/arrayrefwithpadding.cpp b/src/gromacs/math/tests/arrayrefwithpadding.cpp index e3774a476f..a06f144236 100644 --- a/src/gromacs/math/tests/arrayrefwithpadding.cpp +++ b/src/gromacs/math/tests/arrayrefwithpadding.cpp @@ -76,11 +76,7 @@ TEST(EmptyConstArrayRefWithPaddingTest, IsEmpty) #ifdef GTEST_HAS_TYPED_TEST //! Define the types that end up being available as TypeParam in the test cases for both kinds of ArrayRefWithPadding -typedef ::testing::Types< - ArrayRefWithPadding, - ArrayRefWithPadding, - ArrayRefWithPadding - > ArrayRefTypes; +typedef ::testing::Types, ArrayRefWithPadding, ArrayRefWithPadding> ArrayRefTypes; //! Helper constant used in the text fixture. constexpr index aSize = 3; @@ -89,80 +85,78 @@ constexpr index aSize = 3; * * The main objective is to verify that all the different kinds of * construction lead to the expected result. */ -template +template class ArrayRefWithPaddingTest : public ::testing::Test { - public: - typedef TypeParam ArrayRefType; - typedef typename ArrayRefType::value_type ValueType; - typedef PaddedVector PaddedVectorType; - - ValueType a[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; - PaddedVectorType v; - - //! Constructor, which prepares a padded vector to take array ref of. - ArrayRefWithPaddingTest() : v(aSize) +public: + typedef TypeParam ArrayRefType; + typedef typename ArrayRefType::value_type ValueType; + typedef PaddedVector PaddedVectorType; + + ValueType a[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; + PaddedVectorType v; + + //! Constructor, which prepares a padded vector to take array ref of. + ArrayRefWithPaddingTest() : v(aSize) { std::copy(a, a + aSize, v.begin()); } + + /*! \brief Run the same tests all the time + * + * Note that test cases must call this->runTests(), because + * that's how the derived-class templates that implement + * type-parameterized tests actually work. */ + void runTests(ArrayRefType& arrayRefWithPadding) + { + ASSERT_LE(aSize, arrayRefWithPadding.size()); + ASSERT_FALSE(arrayRefWithPadding.empty()); + auto unpaddedArrayRef = arrayRefWithPadding.unpaddedArrayRef(); + auto paddedArrayRef = arrayRefWithPadding.paddedArrayRef(); + EXPECT_LE(unpaddedArrayRef.size(), paddedArrayRef.size()); + for (index i = 0; i != aSize; ++i) { - std::copy(a, a + aSize, v.begin()); + EXPECT_EQ(paddedArrayRef[i], unpaddedArrayRef[i]); + EXPECT_EQ(a[i], unpaddedArrayRef[i]); } - /*! \brief Run the same tests all the time - * - * Note that test cases must call this->runTests(), because - * that's how the derived-class templates that implement - * type-parameterized tests actually work. */ - void runTests(ArrayRefType &arrayRefWithPadding) + using ConstArrayRefWithPaddingType = ArrayRefWithPadding; { - ASSERT_LE(aSize, arrayRefWithPadding.size()); - ASSERT_FALSE(arrayRefWithPadding.empty()); - auto unpaddedArrayRef = arrayRefWithPadding.unpaddedArrayRef(); - auto paddedArrayRef = arrayRefWithPadding.paddedArrayRef(); - EXPECT_LE(unpaddedArrayRef.size(), paddedArrayRef.size()); + // Check that we can make a padded view that refers to const elements + ConstArrayRefWithPaddingType constArrayRefWithPadding = + arrayRefWithPadding.constArrayRefWithPadding(); for (index i = 0; i != aSize; ++i) { - EXPECT_EQ(paddedArrayRef[i], unpaddedArrayRef[i]); - EXPECT_EQ(a[i], unpaddedArrayRef[i]); - } - - using ConstArrayRefWithPaddingType = ArrayRefWithPadding; - { - // Check that we can make a padded view that refers to const elements - ConstArrayRefWithPaddingType constArrayRefWithPadding = arrayRefWithPadding.constArrayRefWithPadding(); - for (index i = 0; i != aSize; ++i) - { - EXPECT_EQ(a[i], constArrayRefWithPadding.paddedArrayRef()[i]); - } + EXPECT_EQ(a[i], constArrayRefWithPadding.paddedArrayRef()[i]); } + } + { + // Check that we can implicitly make a padded view that refers to const elements + ConstArrayRefWithPaddingType constArrayRefWithPadding = arrayRefWithPadding; + for (index i = 0; i != aSize; ++i) { - // Check that we can implicitly make a padded view that refers to const elements - ConstArrayRefWithPaddingType constArrayRefWithPadding = arrayRefWithPadding; - for (index i = 0; i != aSize; ++i) - { - EXPECT_EQ(a[i], constArrayRefWithPadding.paddedArrayRef()[i]); - } + EXPECT_EQ(a[i], constArrayRefWithPadding.paddedArrayRef()[i]); } + } + { + // Check that a swap works, by making an empty padded + // vector, and a view of it, and observing what + // happens when we swap with the one constructed for + // the test. + PaddedVectorType w; + ArrayRefType view = w.arrayRefWithPadding(); + EXPECT_TRUE(view.empty()); + + view.swap(arrayRefWithPadding); + EXPECT_TRUE(arrayRefWithPadding.empty()); + EXPECT_LE(aSize, view.size()); + for (index i = 0; i != v.size(); ++i) { - // Check that a swap works, by making an empty padded - // vector, and a view of it, and observing what - // happens when we swap with the one constructed for - // the test. - PaddedVectorType w; - ArrayRefType view = w.arrayRefWithPadding(); - EXPECT_TRUE(view.empty()); - - view.swap(arrayRefWithPadding); - EXPECT_TRUE(arrayRefWithPadding.empty()); - EXPECT_LE(aSize, view.size()); - for (index i = 0; i != v.size(); ++i) - { - EXPECT_EQ(v[i], view.paddedArrayRef()[i]); - } - // Restore arrayRefWithPadding for future test code - view.swap(arrayRefWithPadding); + EXPECT_EQ(v[i], view.paddedArrayRef()[i]); } + // Restore arrayRefWithPadding for future test code + view.swap(arrayRefWithPadding); } + } }; TYPED_TEST_CASE(ArrayRefWithPaddingTest, ArrayRefTypes); @@ -176,8 +170,7 @@ TYPED_TEST(ArrayRefWithPaddingTest, AssignFromPaddedVectorWorks) TYPED_TEST(ArrayRefWithPaddingTest, ConstructFromPointersWorks) { - typename TestFixture::ArrayRefType arrayRef(this->v.data(), - this->v.data() + this->v.size(), + typename TestFixture::ArrayRefType arrayRef(this->v.data(), this->v.data() + this->v.size(), this->v.data() + this->v.paddedSize()); this->runTests(arrayRef); } @@ -186,29 +179,28 @@ template using makeConstIf_t = std::conditional_t; //! Helper struct for the case actually used in mdrun signalling -template +template struct Helper { - public: - T a[3]; - int size; +public: + T a[3]; + int size; }; -#else // GTEST_HAS_TYPED_TEST +#else // GTEST_HAS_TYPED_TEST /* A dummy test that at least signals that something is missing if one runs the * unit test executable itself. */ TEST(DISABLED_ArrayRefWithPaddingTest, GenericTests) { - ADD_FAILURE() - << "Tests for generic ArrayRefWithPadding functionality require support for " - << "Google Test typed tests, which was not available when the tests " - << "were compiled."; + ADD_FAILURE() << "Tests for generic ArrayRefWithPadding functionality require support for " + << "Google Test typed tests, which was not available when the tests " + << "were compiled."; } #endif // GTEST_HAS_TYPED_TEST -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/math/tests/coordinatetransformation.cpp b/src/gromacs/math/tests/coordinatetransformation.cpp index 805030c0d9..28533b42f2 100644 --- a/src/gromacs/math/tests/coordinatetransformation.cpp +++ b/src/gromacs/math/tests/coordinatetransformation.cpp @@ -60,11 +60,14 @@ namespace test using ::testing::Pointwise; class TranslateAndScaleTest : public ::testing::Test { - protected: - RVec identityScale_ = {1, 1, 1}; - RVec identityTranslation_ = {0, 0, 0}; - std::vector testVectors_ = {{0, 0, 0}, {1, 0, 0}, {0, -1, -1}, {1e10, 1e1, 1e-2}, {3, -6, 2.5}}; - +protected: + RVec identityScale_ = { 1, 1, 1 }; + RVec identityTranslation_ = { 0, 0, 0 }; + std::vector testVectors_ = { { 0, 0, 0 }, + { 1, 0, 0 }, + { 0, -1, -1 }, + { 1e10, 1e1, 1e-2 }, + { 3, -6, 2.5 } }; }; TEST_F(TranslateAndScaleTest, identityTransformation) @@ -77,25 +80,31 @@ TEST_F(TranslateAndScaleTest, identityTransformation) TEST_F(TranslateAndScaleTest, translationWithIdentityScaling) { - TranslateAndScale translateAndScale(identityScale_, {1, -1, 2}); + TranslateAndScale translateAndScale(identityScale_, { 1, -1, 2 }); translateAndScale(testVectors_); - std::vector expected = { {1, -1, 2}, {2, -1, 2}, {1, -2, 1}, {1e10+1, 1e1-1, 1e-2+2}, { 4, -7, 4.5 } }; + std::vector expected = { + { 1, -1, 2 }, { 2, -1, 2 }, { 1, -2, 1 }, { 1e10 + 1, 1e1 - 1, 1e-2 + 2 }, { 4, -7, 4.5 } + }; EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_)); } TEST_F(TranslateAndScaleTest, scalingWithZeroTranslation) { - TranslateAndScale translateAndScale({-1e10, 2, 0}, identityTranslation_); + TranslateAndScale translateAndScale({ -1e10, 2, 0 }, identityTranslation_); translateAndScale(testVectors_); - std::vector expected = {{0, 0, 0}, {-1e10, 0, 0}, {0, -2, 0}, {-1e20, 2e1, 0}, {-3e10, -12, 0}}; + std::vector expected = { + { 0, 0, 0 }, { -1e10, 0, 0 }, { 0, -2, 0 }, { -1e20, 2e1, 0 }, { -3e10, -12, 0 } + }; EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_)); } TEST_F(TranslateAndScaleTest, translationAndScalingNonTrivial) { - TranslateAndScale translateAndScale({-1e10, 2, 0}, {1, -1, 2}); + TranslateAndScale translateAndScale({ -1e10, 2, 0 }, { 1, -1, 2 }); translateAndScale(testVectors_); - std::vector expected = {{-1e+10, -2, 0}, {-2e+10, -2, 0}, {-1e+10, -4, 0}, {-1e+20, 18, 0}, {-4e+10, -14, 0}}; + std::vector expected = { + { -1e+10, -2, 0 }, { -2e+10, -2, 0 }, { -1e+10, -4, 0 }, { -1e+20, 18, 0 }, { -4e+10, -14, 0 } + }; EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_)); } @@ -109,15 +118,17 @@ TEST_F(TranslateAndScaleTest, scalingIdentity) TEST_F(TranslateAndScaleTest, scalingNonTrivial) { - ScaleCoordinates scale({-100, 0.1, 0}); - std::vector expected = {{0, 0, 0}, {-100, 0, 0}, {0, -0.1, 0}, {-1e12, 1e0, 0}, {-300, -0.6, 0}}; + ScaleCoordinates scale({ -100, 0.1, 0 }); + std::vector expected = { + { 0, 0, 0 }, { -100, 0, 0 }, { 0, -0.1, 0 }, { -1e12, 1e0, 0 }, { -300, -0.6, 0 } + }; scale(testVectors_); EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_)); } TEST_F(TranslateAndScaleTest, scalingInverseNoZero) { - ScaleCoordinates scale({-100, 0.1, 3}); + ScaleCoordinates scale({ -100, 0.1, 3 }); auto expected = testVectors_; scale(testVectors_); scale.inverseIgnoringZeroScale(testVectors_); @@ -126,8 +137,8 @@ TEST_F(TranslateAndScaleTest, scalingInverseNoZero) TEST_F(TranslateAndScaleTest, scalingInverseWithOneScaleDimensionZero) { - ScaleCoordinates scale({-100, 0.1, 0}); - std::vector expected = {{0, 0, 0}, {1, 0, 0}, {0, -1, 0}, {1e10, 1e1, 0}, {3, -6, 0}}; + ScaleCoordinates scale({ -100, 0.1, 0 }); + std::vector expected = { { 0, 0, 0 }, { 1, 0, 0 }, { 0, -1, 0 }, { 1e10, 1e1, 0 }, { 3, -6, 0 } }; scale(testVectors_); scale.inverseIgnoringZeroScale(testVectors_); EXPECT_THAT(expected, Pointwise(RVecEq(defaultFloatTolerance()), testVectors_)); diff --git a/src/gromacs/math/tests/densityfit.cpp b/src/gromacs/math/tests/densityfit.cpp index 83153062ad..d56bb7da53 100644 --- a/src/gromacs/math/tests/densityfit.cpp +++ b/src/gromacs/math/tests/densityfit.cpp @@ -64,13 +64,15 @@ TEST(DensitySimilarityTest, InnerProductIsCorrect) MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); std::iota(begin(referenceDensity), end(referenceDensity), 0); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 3); std::iota(begin(comparedDensity), end(comparedDensity), -18); // 0*(-18) + 1*(-17) .. + 26 * 8 / Number elements - const float expectedSimilarity = -117.0 / comparedDensity.asConstView().mapping().required_span_size(); + const float expectedSimilarity = + -117.0 / comparedDensity.asConstView().mapping().required_span_size(); EXPECT_FLOAT_EQ(expectedSimilarity, measure.similarity(comparedDensity.asConstView())); } @@ -79,7 +81,8 @@ TEST(DensitySimilarityTest, InnerProductGradientIsCorrect) MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); std::iota(begin(referenceDensity), end(referenceDensity), 0); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 3); std::iota(begin(comparedDensity), end(comparedDensity), -18); @@ -87,7 +90,7 @@ TEST(DensitySimilarityTest, InnerProductGradientIsCorrect) std::vector expectedSimilarityGradient; std::copy(begin(referenceDensity), end(referenceDensity), std::back_inserter(expectedSimilarityGradient)); - for (auto &x : expectedSimilarityGradient) + for (auto& x : expectedSimilarityGradient) { x /= comparedDensity.asConstView().mapping().required_span_size(); } @@ -96,15 +99,18 @@ TEST(DensitySimilarityTest, InnerProductGradientIsCorrect) // Need this conversion to vector of float, because Pointwise requires size() // member function not provided by basic_mdspan - const basic_mdspan gradient = measure.gradient(comparedDensity.asConstView()); - ArrayRef gradientView(gradient.data(), gradient.data() + gradient.mapping().required_span_size()); + const basic_mdspan gradient = + measure.gradient(comparedDensity.asConstView()); + ArrayRef gradientView(gradient.data(), + gradient.data() + gradient.mapping().required_span_size()); EXPECT_THAT(expectedSimilarityGradient, Pointwise(FloatEq(tolerance), gradientView)); } TEST(DensitySimilarityTest, GradientThrowsIfDensitiesDontMatch) { MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 5); EXPECT_THROW(measure.gradient(comparedDensity.asConstView()), RangeError); @@ -113,7 +119,8 @@ TEST(DensitySimilarityTest, GradientThrowsIfDensitiesDontMatch) TEST(DensitySimilarityTest, SimilarityThrowsIfDensitiesDontMatch) { MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 5); EXPECT_THROW(measure.similarity(comparedDensity.asConstView()), RangeError); } @@ -123,14 +130,16 @@ TEST(DensitySimilarityTest, CopiedMeasureInnerProductIsCorrect) MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); std::iota(begin(referenceDensity), end(referenceDensity), 0); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::innerProduct, + referenceDensity.asConstView()); - DensitySimilarityMeasure copiedMeasure = measure; + DensitySimilarityMeasure copiedMeasure = measure; MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 3); std::iota(begin(comparedDensity), end(comparedDensity), -18); // 0*(-18) + 1*(-17) .. + 26 * 8 / Number elements - const float expectedSimilarity = -117.0 / comparedDensity.asConstView().mapping().required_span_size(); + const float expectedSimilarity = + -117.0 / comparedDensity.asConstView().mapping().required_span_size(); EXPECT_FLOAT_EQ(expectedSimilarity, copiedMeasure.similarity(comparedDensity.asConstView())); } @@ -155,7 +164,8 @@ TEST(DensitySimilarityTest, RelativeEntropyIsCorrect) MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); std::iota(begin(referenceDensity), end(referenceDensity), -2); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::relativeEntropy, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::relativeEntropy, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 3); std::iota(begin(comparedDensity), end(comparedDensity), -1); @@ -169,18 +179,21 @@ TEST(DensitySimilarityTest, RelativeEntropyGradientIsCorrect) MultiDimArray, dynamicExtents3D> referenceDensity(3, 3, 3); std::iota(begin(referenceDensity), end(referenceDensity), -1); - DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::relativeEntropy, referenceDensity.asConstView()); + DensitySimilarityMeasure measure(DensitySimilarityMeasureMethod::relativeEntropy, + referenceDensity.asConstView()); MultiDimArray, dynamicExtents3D> comparedDensity(3, 3, 3); std::iota(begin(comparedDensity), end(comparedDensity), -2); // Need this conversion to ArrayRef, because Pointwise requires size() // member function not provided by basic_mdspan - const basic_mdspan gradient = measure.gradient(comparedDensity.asConstView()); - ArrayRef gradientView(gradient.data(), gradient.data() + gradient.mapping().required_span_size()); + const basic_mdspan gradient = + measure.gradient(comparedDensity.asConstView()); + ArrayRef gradientView(gradient.data(), + gradient.data() + gradient.mapping().required_span_size()); - TestReferenceData refData; - TestReferenceChecker checker(refData.rootChecker()); + TestReferenceData refData; + TestReferenceChecker checker(refData.rootChecker()); checker.setDefaultTolerance(defaultFloatTolerance()); checker.checkSequence(gradientView.begin(), gradientView.end(), "relative-entropy-gradient"); } @@ -204,7 +217,7 @@ TEST(DensitySimilarityTest, CrossCorrelationIsMinusOneWhenAntiCorrelated) { MultiDimArray, dynamicExtents3D> referenceDensity(100, 100, 100); std::iota(begin(referenceDensity), end(referenceDensity), 10000); - for (auto &referenceDensityValue : referenceDensity) + for (auto& referenceDensityValue : referenceDensity) { referenceDensityValue *= -1; } @@ -232,8 +245,8 @@ TEST(DensitySimilarityTest, CrossCorrelationGradientIsZeroWhenCorrelated) // Need this conversion to ArrayRef, because Pointwise requires size() // member function not provided by basic_mdspan - const basic_mdspan gradient - = measure.gradient(comparedDensity.asConstView()); + const basic_mdspan gradient = + measure.gradient(comparedDensity.asConstView()); ArrayRef gradientView(gradient.data(), gradient.data() + gradient.mapping().required_span_size()); @@ -254,15 +267,15 @@ TEST(DensitySimilarityTest, CrossCorrelationGradientIsCorrect) std::iota(begin(comparedDensity), end(comparedDensity), -2); // some non-linear transformation, so that we break the correlation - for (float &valueToCompare : comparedDensity) + for (float& valueToCompare : comparedDensity) { valueToCompare *= valueToCompare; } // Need this conversion to ArrayRef, because Pointwise requires size() // member function not provided by basic_mdspan - const basic_mdspan gradient - = measure.gradient(comparedDensity.asConstView()); + const basic_mdspan gradient = + measure.gradient(comparedDensity.asConstView()); ArrayRef gradientView(gradient.data(), gradient.data() + gradient.mapping().required_span_size()); diff --git a/src/gromacs/math/tests/densityfittingforce.cpp b/src/gromacs/math/tests/densityfittingforce.cpp index 1d84933638..b3d69670a4 100644 --- a/src/gromacs/math/tests/densityfittingforce.cpp +++ b/src/gromacs/math/tests/densityfittingforce.cpp @@ -64,16 +64,17 @@ namespace TEST(DensityFittingForce, isZeroWhenMatchingDensity) { - const float sigma = 1; - const float nSigma = 5; - const RVec gridCenter = {1, 1, 1}; + const float sigma = 1; + const float nSigma = 5; + const RVec gridCenter = { 1, 1, 1 }; - DensityFittingForce forceEvaluator({{sigma, sigma, sigma}, nSigma}); + DensityFittingForce forceEvaluator({ { sigma, sigma, sigma }, nSigma }); MultiDimArray, dynamicExtents3D> densityDerivative(3, 3, 3); std::fill(begin(densityDerivative), end(densityDerivative), 0); - const RVec result = forceEvaluator.evaluateForce({gridCenter, 1.0}, densityDerivative.asConstView()); - const RVec expected = {0, 0, 0}; + const RVec result = + forceEvaluator.evaluateForce({ gridCenter, 1.0 }, densityDerivative.asConstView()); + const RVec expected = { 0, 0, 0 }; FloatingPointTolerance tolerance(defaultFloatTolerance()); EXPECT_FLOAT_EQ_TOL(expected[XX], result[XX], tolerance); @@ -83,20 +84,21 @@ TEST(DensityFittingForce, isZeroWhenMatchingDensity) TEST(DensityFittingForce, isZeroWhenMismatchingSameAllDirections) { - const BasicVector sigma = {1., 1., 1.}; - const float nSigma = 5; - const RVec gridCenter = {1, 1, 1}; + const BasicVector sigma = { 1., 1., 1. }; + const float nSigma = 5; + const RVec gridCenter = { 1, 1, 1 }; - DensityFittingForce forceEvaluator({{sigma}, nSigma}); + DensityFittingForce forceEvaluator({ { sigma }, nSigma }); MultiDimArray, dynamicExtents3D> densityDerivative(3, 3, 3); std::fill(begin(densityDerivative), end(densityDerivative), 1); - const RVec result = forceEvaluator.evaluateForce({gridCenter, 1.}, densityDerivative.asConstView()); - const RVec expected = {0, 0, 0}; + const RVec result = + forceEvaluator.evaluateForce({ gridCenter, 1. }, densityDerivative.asConstView()); + const RVec expected = { 0, 0, 0 }; // need to increase the tolerance here, because the checked value is the - // result of a complex calculation (the sum of 27 3d Gaussians weighted with the distance to center) - // \todo increase tightness of this bound with better implementations + // result of a complex calculation (the sum of 27 3d Gaussians weighted with the distance to + // center) \todo increase tightness of this bound with better implementations FloatingPointTolerance tolerance(absoluteTolerance(1e-8)); EXPECT_FLOAT_EQ_TOL(expected[XX], result[XX], tolerance); @@ -106,17 +108,18 @@ TEST(DensityFittingForce, isZeroWhenMismatchingSameAllDirections) TEST(DensityFittingForce, pullsTowardsDerivative) { - const float sigma = 1; - const float nSigma = 5; - const RVec gridCenter = {1, 1, 1}; + const float sigma = 1; + const float nSigma = 5; + const RVec gridCenter = { 1, 1, 1 }; - DensityFittingForce forceEvaluator({{sigma, sigma, sigma}, nSigma}); + DensityFittingForce forceEvaluator({ { sigma, sigma, sigma }, nSigma }); MultiDimArray, dynamicExtents3D> densityDerivative(3, 3, 3); std::fill(begin(densityDerivative), end(densityDerivative), 0); densityDerivative(0, 0, 0) = 1; - const RVec result = forceEvaluator.evaluateForce({gridCenter, 1.}, densityDerivative.asConstView()); - real expected = -1/sqrt(2*2*2*M_PI*M_PI*M_PI)*exp(-0.5)*exp(-0.5)*exp(-0.5); + const RVec result = + forceEvaluator.evaluateForce({ gridCenter, 1. }, densityDerivative.asConstView()); + real expected = -1 / sqrt(2 * 2 * 2 * M_PI * M_PI * M_PI) * exp(-0.5) * exp(-0.5) * exp(-0.5); EXPECT_FLOAT_EQ(expected, result[XX]); EXPECT_FLOAT_EQ(expected, result[YY]); diff --git a/src/gromacs/math/tests/dofit.cpp b/src/gromacs/math/tests/dofit.cpp index c971c5bb00..2976200e98 100644 --- a/src/gromacs/math/tests/dofit.cpp +++ b/src/gromacs/math/tests/dofit.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,15 +57,15 @@ using gmx::RVec; using gmx::test::defaultRealTolerance; class StructureSimilarityTest : public ::testing::Test { - protected: - static constexpr int c_nAtoms = 4; - std::array structureA_ {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}}}; - std::array structureB_ {{{0, 1, 0}, {0, 0, 1}, {1, 0, 0}, {0, 0, 0}}}; - std::array masses_ {{1, 1, 1, 0}}; - std::array index_ {{0, 1, 2}}; - rvec * x1_ = gmx::as_rvec_array(structureA_.data()); - rvec * x2_ = gmx::as_rvec_array(structureB_.data()); - real * m_ = masses_.data(); +protected: + static constexpr int c_nAtoms = 4; + std::array structureA_{ { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, 0 } } }; + std::array structureB_{ { { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 0 }, { 0, 0, 0 } } }; + std::array masses_{ { 1, 1, 1, 0 } }; + std::array index_{ { 0, 1, 2 } }; + rvec* x1_ = gmx::as_rvec_array(structureA_.data()); + rvec* x2_ = gmx::as_rvec_array(structureB_.data()); + real* m_ = masses_.data(); }; TEST_F(StructureSimilarityTest, StructureComparedToSelfHasZeroRMSD) @@ -90,7 +90,8 @@ TEST_F(StructureSimilarityTest, YieldsCorrectRho) TEST_F(StructureSimilarityTest, YieldsCorrectRMSDWithIndex) { - EXPECT_REAL_EQ_TOL(sqrt(2.0), rmsdev_ind(index_.size(), index_.data(), m_, x1_, x2_), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(sqrt(2.0), rmsdev_ind(index_.size(), index_.data(), m_, x1_, x2_), + defaultRealTolerance()); } TEST_F(StructureSimilarityTest, YieldsCorrectRhoWidthIndex) diff --git a/src/gromacs/math/tests/exponentialmovingaverage.cpp b/src/gromacs/math/tests/exponentialmovingaverage.cpp index 338cb03ffc..83b11c28dc 100644 --- a/src/gromacs/math/tests/exponentialmovingaverage.cpp +++ b/src/gromacs/math/tests/exponentialmovingaverage.cpp @@ -103,7 +103,7 @@ TEST(ExponentialMovingAverage, SetAverageCorrectly) ExponentialMovingAverageState thisState = exponentialMovingAverage.state(); - ExponentialMovingAverage other(lagTime, thisState); + ExponentialMovingAverage other(lagTime, thisState); other.updateWithDataPoint(-10); EXPECT_REAL_EQ(-0.050251256281406857, other.biasCorrectedAverage()); @@ -131,7 +131,6 @@ TEST(ExponentialMovingAverage, DeterminesCorrectlyIfIncreasing) } - TEST(ExponentialMovingAverage, InverseLagTimeCorrect) { const real lagTime = 2.; @@ -145,11 +144,11 @@ TEST(ExponentialMovingAverage, RoundTripAsKeyValueTree) const real weightedSum = 9; const real weightedCount = 1; const bool increasing = true; - ExponentialMovingAverageState state = {weightedSum, weightedCount, increasing}; + ExponentialMovingAverageState state = { weightedSum, weightedCount, increasing }; exponentialMovingAverageStateAsKeyValueTree(builder.rootObject(), state); - state = {}; + state = {}; KeyValueTreeObject result = builder.build(); - state = exponentialMovingAverageStateFromKeyValueTree(result); + state = exponentialMovingAverageStateFromKeyValueTree(result); EXPECT_EQ(weightedSum, state.weightedSum_); EXPECT_EQ(weightedCount, state.weightedCount_); EXPECT_EQ(increasing, state.increasing_); diff --git a/src/gromacs/math/tests/functions.cpp b/src/gromacs/math/tests/functions.cpp index a0dcc01907..b444ee7841 100644 --- a/src/gromacs/math/tests/functions.cpp +++ b/src/gromacs/math/tests/functions.cpp @@ -56,9 +56,9 @@ namespace TEST(FunctionTest, StaticLog2) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result(11); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result(11); // This needs to be expanded manually since it is evaluated at compile time, // and the compiler chokes if we put it as formal arguments to push_back @@ -79,9 +79,9 @@ TEST(FunctionTest, StaticLog2) TEST(FunctionTest, Log2I32Bit) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (std::uint32_t i = 1; i <= 0xF; i++) { @@ -90,16 +90,16 @@ TEST(FunctionTest, Log2I32Bit) for (std::uint32_t i = 0; i <= 0xF; i++) { - result.push_back(gmx::log2I(static_cast(0xFFFFFFF0+i))); + result.push_back(gmx::log2I(static_cast(0xFFFFFFF0 + i))); } checker.checkSequence(result.begin(), result.end(), "Log2I32Bit"); } TEST(FunctionTest, Log2I64Bit) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (std::uint64_t i = 1; i <= 0xF; i++) { @@ -108,12 +108,12 @@ TEST(FunctionTest, Log2I64Bit) for (std::uint64_t i = 0; i <= 0x1F; i++) { - result.push_back(gmx::log2I(static_cast(0xFFFFFFF0ULL+i))); + result.push_back(gmx::log2I(static_cast(0xFFFFFFF0ULL + i))); } for (std::uint64_t i = 0; i <= 0xF; i++) { - result.push_back(gmx::log2I(static_cast(0xFFFFFFFFFFFFFFF0ULL+i))); + result.push_back(gmx::log2I(static_cast(0xFFFFFFFFFFFFFFF0ULL + i))); } checker.checkSequence(result.begin(), result.end(), "Log2I64Bit"); } @@ -127,9 +127,9 @@ TEST(FunctionTest, GreatestCommonDivisor) TEST(FunctionTest, InvsqrtFloat) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (float f = 1.0; f < 10.0; f += 1.0) { @@ -140,9 +140,9 @@ TEST(FunctionTest, InvsqrtFloat) TEST(FunctionTest, InvsqrtDouble) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (double f = 1.0; f < 10.0; f += 1.0) // NOLINT(clang-analyzer-security.FloatLoopCounter) { @@ -153,9 +153,9 @@ TEST(FunctionTest, InvsqrtDouble) TEST(FunctionTest, InvsqrtInteger) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (int i = 1; i < 10; i++) { @@ -166,11 +166,11 @@ TEST(FunctionTest, InvsqrtInteger) TEST(FunctionTest, InvcbrtFloat) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; - for (int f : {-5, -4, -3, -2, -1, 1, 2, 3, 4}) + for (int f : { -5, -4, -3, -2, -1, 1, 2, 3, 4 }) { result.push_back(gmx::invcbrt(f)); } @@ -179,11 +179,11 @@ TEST(FunctionTest, InvcbrtFloat) TEST(FunctionTest, InvcbrtDouble) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; - for (double d : {-5, -4, -3, -2, -1, 1, 2, 3, 4}) + for (double d : { -5, -4, -3, -2, -1, 1, 2, 3, 4 }) { result.push_back(gmx::invcbrt(d)); } @@ -192,11 +192,11 @@ TEST(FunctionTest, InvcbrtDouble) TEST(FunctionTest, InvcbrtInteger) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; - for (int i : {-5, -4, -3, -2, -1, 1, 2, 3, 4}) + for (int i : { -5, -4, -3, -2, -1, 1, 2, 3, 4 }) { result.push_back(gmx::invcbrt(i)); } @@ -206,9 +206,9 @@ TEST(FunctionTest, InvcbrtInteger) TEST(FunctionTest, SixthrootFloat) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (float f = 0; f < 10.0; f += 1.0) { @@ -219,9 +219,9 @@ TEST(FunctionTest, SixthrootFloat) TEST(FunctionTest, SixthrootDouble) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (double d = 0; d < 10.0; d += 1.0) // NOLINT(clang-analyzer-security.FloatLoopCounter) { @@ -232,9 +232,9 @@ TEST(FunctionTest, SixthrootDouble) TEST(FunctionTest, SixthrootInteger) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -246,9 +246,9 @@ TEST(FunctionTest, SixthrootInteger) TEST(FunctionTest, InvsixthrootFloat) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (float f = 1.0; f < 10.0; f += 1.0) { @@ -259,9 +259,9 @@ TEST(FunctionTest, InvsixthrootFloat) TEST(FunctionTest, InvsixthrootDouble) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (double d = 1.0; d < 10.0; d += 1.0) // NOLINT(clang-analyzer-security.FloatLoopCounter) { @@ -272,9 +272,9 @@ TEST(FunctionTest, InvsixthrootDouble) TEST(FunctionTest, InvsixthrootInteger) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; for (int i = 1; i < 10; i++) { @@ -287,31 +287,31 @@ TEST(FunctionTest, Powers) { // These should be remarkably difficult to screw up, but test each // of them once anyway with integer and fp arguments to catch typos. - EXPECT_EQ(4, gmx::square(2)); - EXPECT_EQ(8, gmx::power3(2)); - EXPECT_EQ(16, gmx::power4(2)); - EXPECT_EQ(32, gmx::power5(2)); - EXPECT_EQ(64, gmx::power6(2)); + EXPECT_EQ(4, gmx::square(2)); + EXPECT_EQ(8, gmx::power3(2)); + EXPECT_EQ(16, gmx::power4(2)); + EXPECT_EQ(32, gmx::power5(2)); + EXPECT_EQ(64, gmx::power6(2)); EXPECT_EQ(4096, gmx::power12(2)); - EXPECT_EQ(6.25, gmx::square(2.5)); - EXPECT_EQ(15.625, gmx::power3(2.5)); - EXPECT_EQ(39.0625, gmx::power4(2.5)); - EXPECT_EQ(97.65625, gmx::power5(2.5)); - EXPECT_EQ(244.140625, gmx::power6(2.5)); + EXPECT_EQ(6.25, gmx::square(2.5)); + EXPECT_EQ(15.625, gmx::power3(2.5)); + EXPECT_EQ(39.0625, gmx::power4(2.5)); + EXPECT_EQ(97.65625, gmx::power5(2.5)); + EXPECT_EQ(244.140625, gmx::power6(2.5)); EXPECT_EQ(59604.644775390625, gmx::power12(2.5)); } TEST(FunctionTest, ErfInvFloat) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; - int npoints = 10; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; + int npoints = 10; for (int i = 0; i < npoints; i++) { - float r = float(2*i - npoints + 1) / float(npoints); + float r = float(2 * i - npoints + 1) / float(npoints); result.push_back(gmx::erfinv(r)); } @@ -320,14 +320,14 @@ TEST(FunctionTest, ErfInvFloat) TEST(FunctionTest, ErfInvDouble) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; - int npoints = 10; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + std::vector result; + int npoints = 10; for (int i = 0; i < npoints; i++) { - double r = double(2*i - npoints + 1) / npoints; + double r = double(2 * i - npoints + 1) / npoints; result.push_back(gmx::erfinv(r)); } @@ -340,7 +340,7 @@ TEST(FunctionTest, ErfAndErfInvAreInversesFloat) for (int i = 0; i < npoints; i++) { - float r = float(2*i - npoints + 1) / float(npoints); + float r = float(2 * i - npoints + 1) / float(npoints); EXPECT_FLOAT_EQ_TOL(r, std::erf(gmx::erfinv(r)), gmx::test::ulpTolerance(10)); } } @@ -351,7 +351,7 @@ TEST(FunctionTest, ErfAndErfInvAreInversesDouble) for (int i = 0; i < npoints; i++) { - double r = double(2*i - npoints + 1) / npoints; + double r = double(2 * i - npoints + 1) / npoints; EXPECT_DOUBLE_EQ_TOL(r, std::erf(gmx::erfinv(r)), gmx::test::ulpTolerance(10)); } } diff --git a/src/gromacs/math/tests/gausstransform.cpp b/src/gromacs/math/tests/gausstransform.cpp index 3c53ab3240..a0f35646ac 100644 --- a/src/gromacs/math/tests/gausstransform.cpp +++ b/src/gromacs/math/tests/gausstransform.cpp @@ -67,13 +67,13 @@ namespace TEST(GaussianOn1DLattice, sumsCloseToOne) { - const int spreadWidth = 7; - const real sigma = 1.9; - const real shift = 0.1; - GaussianOn1DLattice gauss1d(spreadWidth, sigma); - const real amplitude = 1; + const int spreadWidth = 7; + const real sigma = 1.9; + const real shift = 0.1; + GaussianOn1DLattice gauss1d(spreadWidth, sigma); + const real amplitude = 1; gauss1d.spread(amplitude, shift); - auto sumOverLattice = std::accumulate(std::begin(gauss1d.view()), std::end(gauss1d.view()), 0.); + auto sumOverLattice = std::accumulate(std::begin(gauss1d.view()), std::end(gauss1d.view()), 0.); FloatingPointTolerance tolerance(defaultFloatTolerance()); // The sum over the lattice should be roughly one @@ -82,17 +82,17 @@ TEST(GaussianOn1DLattice, sumsCloseToOne) TEST(GaussianOn1DLattice, isCorrect) { - const int spreadWidth = 2; - const real sigma = 0.57; - const real shift = -0.2; - GaussianOn1DLattice gauss1d(spreadWidth, sigma); - const auto viewOnResult = gauss1d.view(); - FloatingPointTolerance tolerance(defaultFloatTolerance()); - const real amplitude = 1.0; + const int spreadWidth = 2; + const real sigma = 0.57; + const real shift = -0.2; + GaussianOn1DLattice gauss1d(spreadWidth, sigma); + const auto viewOnResult = gauss1d.view(); + FloatingPointTolerance tolerance(defaultFloatTolerance()); + const real amplitude = 1.0; gauss1d.spread(amplitude, shift); - std::array expected = { - 0.0047816522419452667236328125, 0.2613909542560577392578125, - 0.65811407566070556640625, 0.07631497085094451904296875, 0.000407583254855126142501831054688 + std::array expected = { + 0.0047816522419452667236328125, 0.2613909542560577392578125, 0.65811407566070556640625, + 0.07631497085094451904296875, 0.000407583254855126142501831054688 }; EXPECT_THAT(expected, Pointwise(FloatEq(tolerance), viewOnResult)); } @@ -107,7 +107,7 @@ TEST(GaussianOn1DLattice, complementaryAmplitudesSumToZero) FloatingPointTolerance tolerance(defaultFloatTolerance()); const real amplitude = 2.0; gauss1d.spread(amplitude, shift); - std::vector sumOfComplementaryGaussians; + std::vector sumOfComplementaryGaussians; // keep a copy of the first Gaussian std::copy(std::begin(viewOnResult), std::end(viewOnResult), std::back_inserter(sumOfComplementaryGaussians)); @@ -115,9 +115,10 @@ TEST(GaussianOn1DLattice, complementaryAmplitudesSumToZero) gauss1d.spread(-amplitude, shift); // add the two spread Gaussians std::transform(std::begin(viewOnResult), std::end(viewOnResult), - std::begin(sumOfComplementaryGaussians), std::begin(sumOfComplementaryGaussians), std::plus<>()); + std::begin(sumOfComplementaryGaussians), std::begin(sumOfComplementaryGaussians), + std::plus<>()); // Expect all zeros - std::array expected = {}; + std::array expected = {}; EXPECT_THAT(expected, Pointwise(FloatEq(tolerance), sumOfComplementaryGaussians)); } @@ -142,22 +143,22 @@ TEST(GaussianOn1DLattice, doesNotOverflowForLargeRange) 2.43432064870457987026952650922e-13, 2.66955679784075528004905208945e-10, 1.07697594842193211661651730537e-07, 1.59837418323149904608726501465e-05, 0.000872682663612067699432373046875, 0.01752830110490322113037109375, - 0.12951759994029998779296875, 0.3520653247833251953125 + 0.12951759994029998779296875, 0.3520653247833251953125 }; for (size_t i = 188; i < 200; i++) { - EXPECT_FLOAT_EQ(expectedResult[i-188], viewOnResult[i]); + EXPECT_FLOAT_EQ(expectedResult[i - 188], viewOnResult[i]); } for (size_t i = 200; i < 212; i++) { - EXPECT_FLOAT_EQ(expectedResult[211-i], viewOnResult[i]); + EXPECT_FLOAT_EQ(expectedResult[211 - i], viewOnResult[i]); } EXPECT_FLOAT_EQ(4.69519506491195688717869977423e-35, viewOnResult[212]); - for (size_t i = 213; i < 2*spreadWidth+1; i++) + for (size_t i = 213; i < 2 * spreadWidth + 1; i++) { EXPECT_FLOAT_EQ(0, viewOnResult[i]); } @@ -165,21 +166,22 @@ TEST(GaussianOn1DLattice, doesNotOverflowForLargeRange) class GaussTransformTest : public ::testing::Test { - public: - void isZeroWithinFloatTolerance() +public: + void isZeroWithinFloatTolerance() + { + for (const auto& x : gaussTransform_.constView()) { - for (const auto &x : gaussTransform_.constView()) - { - EXPECT_FLOAT_EQ_TOL(0, x, tolerance_); - } + EXPECT_FLOAT_EQ_TOL(0, x, tolerance_); } - protected: - extents latticeExtent_ = {3, 3, 3 }; - DVec sigma_ = {1., 1., 1.}; - double nSigma_ = 5; - GaussTransform3D gaussTransform_ = {latticeExtent_, {sigma_, nSigma_}}; - test::FloatingPointTolerance tolerance_ = test::defaultFloatTolerance(); - const RVec latticeCenter_ = {1, 1, 1}; + } + +protected: + extents latticeExtent_ = { 3, 3, 3 }; + DVec sigma_ = { 1., 1., 1. }; + double nSigma_ = 5; + GaussTransform3D gaussTransform_ = { latticeExtent_, { sigma_, nSigma_ } }; + test::FloatingPointTolerance tolerance_ = test::defaultFloatTolerance(); + const RVec latticeCenter_ = { 1, 1, 1 }; }; TEST_F(GaussTransformTest, isZeroUponConstruction) @@ -189,13 +191,13 @@ TEST_F(GaussTransformTest, isZeroUponConstruction) TEST_F(GaussTransformTest, isZeroAddingZeroAmplitudeGauss) { - gaussTransform_.add({latticeCenter_, 0.}); + gaussTransform_.add({ latticeCenter_, 0. }); isZeroWithinFloatTolerance(); } TEST_F(GaussTransformTest, isZeroAfterSettingZero) { - gaussTransform_.add({latticeCenter_, 1.}); + gaussTransform_.add({ latticeCenter_, 1. }); for (const auto value : gaussTransform_.constView()) { EXPECT_GT(value, 0); @@ -207,78 +209,63 @@ TEST_F(GaussTransformTest, isZeroAfterSettingZero) TEST_F(GaussTransformTest, isZeroWhenOutsideRangeinX) { DVec coordinateOutsideX(-nSigma_ * sigma_[XX], 0, 0); - gaussTransform_.add({coordinateOutsideX.toRVec(), 1.}); + gaussTransform_.add({ coordinateOutsideX.toRVec(), 1. }); isZeroWithinFloatTolerance(); } TEST_F(GaussTransformTest, isZeroWhenOutsideRangeinY) { DVec coordinateOutsideY(0, -nSigma_ * sigma_[YY], 0); - gaussTransform_.add({coordinateOutsideY.toRVec(), 1.}); + gaussTransform_.add({ coordinateOutsideY.toRVec(), 1. }); isZeroWithinFloatTolerance(); } TEST_F(GaussTransformTest, isZeroWhenOutsideRangeinZ) { RVec coordinateOutsideZ(0, 0, -nSigma_ * sigma_[ZZ]); - gaussTransform_.add({coordinateOutsideZ.toRVec(), 1.}); + gaussTransform_.add({ coordinateOutsideZ.toRVec(), 1. }); isZeroWithinFloatTolerance(); } TEST_F(GaussTransformTest, complementaryGaussAddToZero) { - gaussTransform_.add({latticeCenter_, -2.0}); - gaussTransform_.add({latticeCenter_, 0.8}); - gaussTransform_.add({latticeCenter_, 1.2}); + gaussTransform_.add({ latticeCenter_, -2.0 }); + gaussTransform_.add({ latticeCenter_, 0.8 }); + gaussTransform_.add({ latticeCenter_, 1.2 }); isZeroWithinFloatTolerance(); } TEST_F(GaussTransformTest, centerGaussianInCubeHasExpectedValues) { - gaussTransform_.add({latticeCenter_, 1.}); + gaussTransform_.add({ latticeCenter_, 1. }); const float center = 0.0634936392307281494140625; // center const float f = 0.0385108403861522674560546875; // face const float e = 0.0233580060303211212158203125; // edge const float c = 0.014167346991598606109619140625; // corner - std::vector expectedValues = { - c, e, c, - e, f, e, - c, e, c, - - e, f, e, - f, center, f, - e, f, e, - - c, e, c, - e, f, e, - c, e, c - }; + std::vector expectedValues = { c, e, c, e, f, e, c, e, c, + + e, f, e, f, center, f, e, f, e, + + c, e, c, e, f, e, c, e, c }; // This assignment to std::vector is needed because the view() on the GaussTransform (aka basic_mdspan) does not provide size() needed by Pointwise std::vector gaussTransformVector; gaussTransformVector.assign(gaussTransform_.constView().data(), - gaussTransform_.constView().data() + gaussTransform_.constView().mapping().required_span_size()); + gaussTransform_.constView().data() + + gaussTransform_.constView().mapping().required_span_size()); EXPECT_THAT(expectedValues, testing::Pointwise(FloatEq(tolerance_), gaussTransformVector)); } TEST_F(GaussTransformTest, view) { - gaussTransform_.add({latticeCenter_, 1.}); + gaussTransform_.add({ latticeCenter_, 1. }); const float f = 0.0385108403861522674560546875; // face const float e = 0.0233580060303211212158203125; // edge const float c = 0.014167346991598606109619140625; // corner - std::vector expectedValues = { - c, e, c, - e, f, e, - c, e, c, - - e, f, e, - f, 0., f, - e, f, e, - - c, e, c, - e, f, e, - c, e, c - }; + std::vector expectedValues = { c, e, c, e, f, e, c, e, c, + + e, f, e, f, 0., f, e, f, e, + + c, e, c, e, f, e, c, e, c }; gaussTransform_.view()[1][1][1] = 0; // This assignment to std::vector is needed because the view() on the @@ -286,8 +273,9 @@ TEST_F(GaussTransformTest, view) // needed by Pointwise // \todo Update when mdspan functionality is extended std::vector gaussTransformVector; - gaussTransformVector.assign(gaussTransform_.view().data(), - gaussTransform_.view().data() + gaussTransform_.view().mapping().required_span_size()); + gaussTransformVector.assign( + gaussTransform_.view().data(), + gaussTransform_.view().data() + gaussTransform_.view().mapping().required_span_size()); EXPECT_THAT(expectedValues, testing::Pointwise(FloatEq(tolerance_), gaussTransformVector)); } diff --git a/src/gromacs/math/tests/invertmatrix.cpp b/src/gromacs/math/tests/invertmatrix.cpp index 4021cb6594..cd085d1cf1 100644 --- a/src/gromacs/math/tests/invertmatrix.cpp +++ b/src/gromacs/math/tests/invertmatrix.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,13 +56,13 @@ namespace { -using gmx::invertMatrix; using gmx::invertBoxMatrix; +using gmx::invertMatrix; using gmx::test::defaultRealTolerance; TEST(InvertMatrixTest, IdentityIsImpotent) { - matrix in = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; + matrix in = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; matrix out; invertMatrix(in, out); @@ -80,17 +80,13 @@ TEST(InvertMatrixTest, IdentityIsImpotent) TEST(InvertMatrixTest, ComputesInverse) { - matrix in = {{1, 2, 3}, {-1, real(2.5), 1}, {10, -2, real(1.2)}}; + matrix in = { { 1, 2, 3 }, { -1, real(2.5), 1 }, { 10, -2, real(1.2) } }; matrix out; - matrix expected = {{real(-0.12019230769230768), - real(0.20192307692307693), - real(0.13221153846153844)}, - {real(-0.26923076923076916), - real(0.69230769230769229), - real(0.096153846153846145)}, - {real(0.55288461538461531), - real(-0.52884615384615374), - real(-0.10817307692307691)}}; + matrix expected = { + { real(-0.12019230769230768), real(0.20192307692307693), real(0.13221153846153844) }, + { real(-0.26923076923076916), real(0.69230769230769229), real(0.096153846153846145) }, + { real(0.55288461538461531), real(-0.52884615384615374), real(-0.10817307692307691) } + }; invertMatrix(in, out); @@ -107,7 +103,7 @@ TEST(InvertMatrixTest, ComputesInverse) TEST(InvertBoxMatrixTest, IdentityIsImpotent) { - matrix in = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; + matrix in = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; invertBoxMatrix(in, in); @@ -124,10 +120,10 @@ TEST(InvertBoxMatrixTest, IdentityIsImpotent) TEST(InvertBoxMatrixTest, ComputesInverseInPlace) { - matrix in = {{1, 0, 0}, {-1, real(2.5), 0}, {10, -2, real(1.2)}}; - matrix expected = {{1, 0, 0}, - {real(0.4), real(0.4), 0}, - {real(-23.0/3.0), real(2.0/3.0), real(5.0/6.0)}}; + matrix in = { { 1, 0, 0 }, { -1, real(2.5), 0 }, { 10, -2, real(1.2) } }; + matrix expected = { { 1, 0, 0 }, + { real(0.4), real(0.4), 0 }, + { real(-23.0 / 3.0), real(2.0 / 3.0), real(5.0 / 6.0) } }; invertBoxMatrix(in, in); diff --git a/src/gromacs/math/tests/matrix.cpp b/src/gromacs/math/tests/matrix.cpp index 919e17796a..fcd217dec6 100644 --- a/src/gromacs/math/tests/matrix.cpp +++ b/src/gromacs/math/tests/matrix.cpp @@ -64,20 +64,18 @@ namespace class MatrixTest : public ::testing::Test { - public: - MatrixTest() - { - std::fill(begin(matrix_), end(matrix_), testNumber_ - 1); - } - protected: - Matrix3x3 matrix_; - real testNumber_ = 42; +public: + MatrixTest() { std::fill(begin(matrix_), end(matrix_), testNumber_ - 1); } + +protected: + Matrix3x3 matrix_; + real testNumber_ = 42; }; TEST_F(MatrixTest, canSetFromArray) { - std::array arr = {{1, 2, 3, 4, 5, 6, 7, 8, 9}}; - Matrix3x3 newMatrix(arr); + std::array arr = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; + Matrix3x3 newMatrix(arr); EXPECT_EQ(newMatrix(0, 0), 1); EXPECT_EQ(newMatrix(0, 1), 2); EXPECT_EQ(newMatrix(0, 2), 3); @@ -91,7 +89,7 @@ TEST_F(MatrixTest, canSetFromArray) TEST_F(MatrixTest, canSetStaticallyFromList) { - Matrix3x3 newMatrix = {{1, 2, 3, 4, 5, 6, 7, 8, 9}}; + Matrix3x3 newMatrix = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; EXPECT_EQ(newMatrix(0, 0), 1); EXPECT_EQ(newMatrix(0, 1), 2); EXPECT_EQ(newMatrix(0, 2), 3); @@ -105,7 +103,7 @@ TEST_F(MatrixTest, canSetStaticallyFromList) TEST_F(MatrixTest, canConstructAndFill) { - for (const auto &x : matrix_) + for (const auto& x : matrix_) { EXPECT_EQ(testNumber_ - 1, x); } @@ -114,15 +112,15 @@ TEST_F(MatrixTest, canConstructAndFill) TEST_F(MatrixTest, canSetValues) { matrix_(1, 1) = testNumber_; - EXPECT_EQ(testNumber_, matrix_(1, 1) ); + EXPECT_EQ(testNumber_, matrix_(1, 1)); } TEST_F(MatrixTest, canCopyAssign) { Matrix3x3 other; other = matrix_; - using ::testing::Pointwise; using ::testing::Eq; + using ::testing::Pointwise; EXPECT_THAT(other.toArrayRef(), Pointwise(Eq(), matrix_.toArrayRef())); } @@ -146,35 +144,31 @@ TEST_F(MatrixTest, staticMultiDimArrayExtent) TEST_F(MatrixTest, determinantWorks) { - const Matrix3x3 mat = {{1.0, 2.0, 3.0, - 0.0, 1.0, 4.0, - 5.0, 6.0, 0.0}}; + const Matrix3x3 mat = { { 1.0, 2.0, 3.0, 0.0, 1.0, 4.0, 5.0, 6.0, 0.0 } }; EXPECT_EQ(determinant(mat), 1); } TEST_F(MatrixTest, noninvertableDeterminantIsZero) { - const Matrix3x3 mat = {{1, 0, 0, 0, 1, 0, 0, 0, 0}}; + const Matrix3x3 mat = { { 1, 0, 0, 0, 1, 0, 0, 0, 0 } }; EXPECT_EQ(determinant(mat), 0); } TEST_F(MatrixTest, determinantOfDiagonalMatrix) { - const Matrix3x3 mat = {{2, 0, 0, 0, 3, 0, 0, 0, 4}}; + const Matrix3x3 mat = { { 2, 0, 0, 0, 3, 0, 0, 0, 4 } }; EXPECT_EQ(determinant(mat), 24); } TEST_F(MatrixTest, traceWorks) { - const Matrix3x3 mat = {{1.5, 9, 9, 9, 2.0, 9, 9, 9, 0.25}}; + const Matrix3x3 mat = { { 1.5, 9, 9, 9, 2.0, 9, 9, 9, 0.25 } }; EXPECT_EQ(trace(mat), 3.75); } TEST_F(MatrixTest, transposeWorks) { - const Matrix3x3 asymmetricMat = {{1, 2, 3, - 4, 5, 6, - 7, 8, 9}}; + const Matrix3x3 asymmetricMat = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; const Matrix3x3 transposedAsymmetricMat = transpose(asymmetricMat); EXPECT_EQ(asymmetricMat(0, 0), transposedAsymmetricMat(0, 0)); @@ -186,14 +180,11 @@ TEST_F(MatrixTest, transposeWorks) EXPECT_EQ(asymmetricMat(2, 0), transposedAsymmetricMat(0, 2)); EXPECT_EQ(asymmetricMat(2, 1), transposedAsymmetricMat(1, 2)); EXPECT_EQ(asymmetricMat(2, 2), transposedAsymmetricMat(2, 2)); - } TEST_F(MatrixTest, transposeOfSymmetricMatrix) { - const Matrix3x3 symmetricMat = {{ 1, 2, 3, - 2, 5, 6, - 3, 6, 9}}; + const Matrix3x3 symmetricMat = { { 1, 2, 3, 2, 5, 6, 3, 6, 9 } }; const Matrix3x3 transposedSymmetricMat = transpose(symmetricMat); for (int i = 0; i < 3; i++) { @@ -206,7 +197,7 @@ TEST_F(MatrixTest, transposeOfSymmetricMatrix) TEST_F(MatrixTest, canCreateFromLegacyMatrix) { - matrix legacyMatrix = { { 1, 2, 3}, { 4, 5, 6}, {7, 8, 9}}; + matrix legacyMatrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; const Matrix3x3 fromLegacy = createMatrix3x3FromLegacyMatrix(legacyMatrix); for (int i = 0; i < 3; i++) { @@ -219,7 +210,7 @@ TEST_F(MatrixTest, canCreateFromLegacyMatrix) TEST_F(MatrixTest, canFillLegacyMatrix) { - matrix legacyMatrix = {{ -2 }}; + matrix legacyMatrix = { { -2 } }; fillLegacyMatrix(matrix_, legacyMatrix); for (int i = 0; i < 3; i++) { diff --git a/src/gromacs/math/tests/multidimarray.cpp b/src/gromacs/math/tests/multidimarray.cpp index 1a97ede00d..b82f514541 100644 --- a/src/gromacs/math/tests/multidimarray.cpp +++ b/src/gromacs/math/tests/multidimarray.cpp @@ -64,32 +64,32 @@ namespace class MultiDimArrayTest : public ::testing::Test { - public: - MultiDimArrayTest() - { - std::fill(begin(staticArray_), end(staticArray_), testNumber_ - 1); - std::fill(begin(dynamicArray_), end(dynamicArray_), testNumber_ - 1); - } - protected: - - using static_container_type = std::array; - using static_extents_type = extents<3, 3>; - using static_array_type = MultiDimArray; - - using dynamic_container_type = std::vector; - using dynamic_extents_type = extents; - using dynamic_array_type = MultiDimArray; - - static_array_type staticArray_; - dynamic_array_type dynamicArray_ {2, 2}; - - float testNumber_ = 42; +public: + MultiDimArrayTest() + { + std::fill(begin(staticArray_), end(staticArray_), testNumber_ - 1); + std::fill(begin(dynamicArray_), end(dynamicArray_), testNumber_ - 1); + } + +protected: + using static_container_type = std::array; + using static_extents_type = extents<3, 3>; + using static_array_type = MultiDimArray; + + using dynamic_container_type = std::vector; + using dynamic_extents_type = extents; + using dynamic_array_type = MultiDimArray; + + static_array_type staticArray_; + dynamic_array_type dynamicArray_{ 2, 2 }; + + float testNumber_ = 42; }; TEST_F(MultiDimArrayTest, canConstructAndFillStatic) { - for (const auto &x : staticArray_) + for (const auto& x : staticArray_) { EXPECT_EQ(testNumber_ - 1, x); } @@ -97,7 +97,7 @@ TEST_F(MultiDimArrayTest, canConstructAndFillStatic) TEST_F(MultiDimArrayTest, canConstructAndFillDynamic) { - for (const auto &x : dynamicArray_) + for (const auto& x : dynamicArray_) { EXPECT_EQ(testNumber_ - 1, x); } @@ -106,7 +106,7 @@ TEST_F(MultiDimArrayTest, canConstructAndFillDynamic) TEST_F(MultiDimArrayTest, canSetValuesInStatic) { staticArray_(1, 1) = testNumber_; - EXPECT_EQ(testNumber_, staticArray_(1, 1) ); + EXPECT_EQ(testNumber_, staticArray_(1, 1)); } TEST_F(MultiDimArrayTest, canSetValuesInDynamic) @@ -118,7 +118,7 @@ TEST_F(MultiDimArrayTest, canSetValuesInDynamic) TEST_F(MultiDimArrayTest, canMoveConstructStatic) { auto other(std::move(staticArray_)); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(testNumber_ - 1, x); } @@ -127,7 +127,7 @@ TEST_F(MultiDimArrayTest, canMoveConstructStatic) TEST_F(MultiDimArrayTest, canMoveConstructDynamic) { auto other(std::move(dynamicArray_)); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(testNumber_ - 1, x); } @@ -137,7 +137,7 @@ TEST_F(MultiDimArrayTest, canMoveAssignStatic) { static_array_type other; other = std::move(staticArray_); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(testNumber_ - 1, x); } @@ -147,7 +147,7 @@ TEST_F(MultiDimArrayTest, canMoveAssignDynamic) { dynamic_array_type other; other = std::move(dynamicArray_); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(testNumber_ - 1, x); } @@ -157,7 +157,7 @@ TEST_F(MultiDimArrayTest, canCopyConstructStatic) { auto other = staticArray_; auto twoDArrayIt = begin(staticArray_); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(*twoDArrayIt, x); ++twoDArrayIt; @@ -168,7 +168,7 @@ TEST_F(MultiDimArrayTest, canCopyConstructDynamic) { auto other = dynamicArray_; auto twoDArrayIt = begin(dynamicArray_); - for (const auto &x : other) + for (const auto& x : other) { EXPECT_EQ(*twoDArrayIt, x); ++twoDArrayIt; @@ -178,9 +178,9 @@ TEST_F(MultiDimArrayTest, canCopyConstructDynamic) TEST_F(MultiDimArrayTest, canCopyAssignStatic) { static_array_type other; - other = staticArray_; - auto twoDArrayIt = begin(staticArray_); - for (const auto &x : other) + other = staticArray_; + auto twoDArrayIt = begin(staticArray_); + for (const auto& x : other) { EXPECT_EQ(*twoDArrayIt, x); ++twoDArrayIt; @@ -190,9 +190,9 @@ TEST_F(MultiDimArrayTest, canCopyAssignStatic) TEST_F(MultiDimArrayTest, canCopyAssignDynamic) { dynamic_array_type other; - other = dynamicArray_; - auto twoDArrayIt = begin(dynamicArray_); - for (const auto &x : other) + other = dynamicArray_; + auto twoDArrayIt = begin(dynamicArray_); + for (const auto& x : other) { EXPECT_EQ(*twoDArrayIt, x); ++twoDArrayIt; @@ -251,7 +251,7 @@ TEST_F(MultiDimArrayTest, dynamicMultiDimArrayResizeAndSetValue) TEST_F(MultiDimArrayTest, staticMultiDimArrayFromArray) { - static_array_type arr = {{1, 2, 3, 4, 5, 6, 7, 8, 9}}; + static_array_type arr = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; EXPECT_EQ(arr(0, 0), 1); EXPECT_EQ(arr(0, 1), 2); EXPECT_EQ(arr(0, 2), 3); @@ -266,7 +266,7 @@ TEST_F(MultiDimArrayTest, staticMultiDimArrayFromArray) TEST_F(MultiDimArrayTest, conversionToView) { static_array_type::view_type view = staticArray_.asView(); - view(2, 2) = testNumber_; + view(2, 2) = testNumber_; EXPECT_EQ(testNumber_, view(2, 2)); } @@ -275,7 +275,7 @@ TEST_F(MultiDimArrayTest, conversionToConstView) static_array_type::const_view_type view = staticArray_.asConstView(); // the following must not compile: // view(2, 2) = testNumber_; - for (const auto &x : view) + for (const auto& x : view) { EXPECT_EQ(testNumber_ - 1, x); } @@ -284,14 +284,14 @@ TEST_F(MultiDimArrayTest, conversionToConstView) TEST_F(MultiDimArrayTest, viewBegin) { static_array_type::view_type view = staticArray_.asView(); - *begin(view) = testNumber_; + *begin(view) = testNumber_; EXPECT_EQ(*begin(view), testNumber_); } TEST_F(MultiDimArrayTest, viewEnd) { static_array_type::view_type view = staticArray_.asView(); - auto x = end(view); + auto x = end(view); --x; view(2, 2) = testNumber_; EXPECT_EQ(*x, testNumber_); @@ -300,7 +300,7 @@ TEST_F(MultiDimArrayTest, viewEnd) TEST_F(MultiDimArrayTest, constViewConstBegin) { staticArray_(0, 0) = testNumber_; - const auto view = staticArray_.asConstView(); + const auto view = staticArray_.asConstView(); // must not compile: *begin(view) = testNumber_; EXPECT_EQ(*begin(view), testNumber_); } @@ -308,16 +308,16 @@ TEST_F(MultiDimArrayTest, constViewConstBegin) TEST_F(MultiDimArrayTest, constViewConstEnd) { staticArray_(2, 2) = testNumber_; - const auto view = staticArray_.asConstView(); - auto x = end(view); + const auto view = staticArray_.asConstView(); + auto x = end(view); --x; EXPECT_EQ(*x, testNumber_); } TEST(MultiDimArrayToMdSpanTest, convertsToMdSpan) { - MultiDimArray < std::array, extents < 2, 2>> arr = {{0, 1, 2, 3}}; - basic_mdspan < int, extents < 2, 2>> span(arr); + MultiDimArray, extents<2, 2>> arr = { { 0, 1, 2, 3 } }; + basic_mdspan> span(arr); // test copy correctness EXPECT_EQ(span(1, 1), 3); @@ -329,24 +329,22 @@ TEST(MultiDimArrayToMdSpanTest, convertsToMdSpan) TEST(MultiDimArrayToMdSpanTest, constArrayToMdSpan) { - const MultiDimArray < std::array, extents < 2, 2>> constArr = {{0, 1, 2, 3}}; - basic_mdspan < const int, extents < 2, 2>> span(constArr); + const MultiDimArray, extents<2, 2>> constArr = { { 0, 1, 2, 3 } }; + basic_mdspan> span(constArr); EXPECT_EQ(span(0, 1), 1); } TEST(MultiDimArrayToMdSpanTest, nonConstArrayToConstMdSpan) { - MultiDimArray < std::array, extents < 2, 2>> arr = {{0, 1, 2, 3}}; - basic_mdspan < const int, extents < 2, 2>> span(arr); + MultiDimArray, extents<2, 2>> arr = { { 0, 1, 2, 3 } }; + basic_mdspan> span(arr); EXPECT_EQ(span(0, 1), 1); } TEST(MultiDimArrayToMdSpanTest, implicitConversionToMdSpan) { - auto testFunc = [](basic_mdspan < const int, extents < 2, 2>> a){ - return a(0, 0); - }; - MultiDimArray < std::array, extents < 2, 2>> arr = {{0, 1, 2, 3}}; + auto testFunc = [](basic_mdspan> a) { return a(0, 0); }; + MultiDimArray, extents<2, 2>> arr = { { 0, 1, 2, 3 } }; EXPECT_EQ(testFunc(arr), 0); } diff --git a/src/gromacs/math/tests/paddedvector.cpp b/src/gromacs/math/tests/paddedvector.cpp index 26790e83f6..14b1c3b763 100644 --- a/src/gromacs/math/tests/paddedvector.cpp +++ b/src/gromacs/math/tests/paddedvector.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,25 +64,23 @@ namespace test { //! Typed test fixture -template +template class PaddedVectorTest : public ::testing::Test { - public: +public: }; //! The types used in testing -using Implementations = ::testing::Types < - std::allocator, - std::allocator, - std::allocator, - std::allocator < BasicVector < float>>, - std::allocator < BasicVector < double>>, - AlignedAllocator, - AlignedAllocator, - AlignedAllocator, - AlignedAllocator < BasicVector < float>>, - AlignedAllocator < BasicVector> - >; +using Implementations = ::testing::Types, + std::allocator, + std::allocator, + std::allocator>, + std::allocator>, + AlignedAllocator, + AlignedAllocator, + AlignedAllocator, + AlignedAllocator>, + AlignedAllocator>>; TYPED_TEST_CASE(PaddedVectorTest, Implementations); TYPED_TEST(PaddedVectorTest, ConstructsResizesAndReserves) @@ -116,8 +114,7 @@ TYPED_TEST(PaddedVectorTest, CanCopyAssign) fillInput(&w, 2); w = v; - compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), - w.arrayRefWithPadding().unpaddedArrayRef()); + compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), w.arrayRefWithPadding().unpaddedArrayRef()); compareViews(makeArrayRef(v), makeArrayRef(v)); } @@ -131,16 +128,14 @@ TYPED_TEST(PaddedVectorTest, CanMoveAssign) fillInput(&x, 1); SCOPED_TRACE("Comparing padded views before move"); - compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), - x.arrayRefWithPadding().unpaddedArrayRef()); + compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), x.arrayRefWithPadding().unpaddedArrayRef()); SCOPED_TRACE("Comparing unpadded views before move"); compareViews(makeArrayRef(v), makeArrayRef(x)); w = std::move(x); SCOPED_TRACE("Comparing padded views"); - compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), - w.arrayRefWithPadding().unpaddedArrayRef()); + compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), w.arrayRefWithPadding().unpaddedArrayRef()); SCOPED_TRACE("Comparing unpadded views"); compareViews(makeArrayRef(v), makeArrayRef(w)); } @@ -155,8 +150,7 @@ TYPED_TEST(PaddedVectorTest, CanSwap) fillInput(&x, 1); std::swap(w, x); - compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), - w.arrayRefWithPadding().unpaddedArrayRef()); + compareViews(v.arrayRefWithPadding().unpaddedArrayRef(), w.arrayRefWithPadding().unpaddedArrayRef()); compareViews(makeArrayRef(v), makeArrayRef(w)); } diff --git a/src/gromacs/math/tests/testarrayrefs.h b/src/gromacs/math/tests/testarrayrefs.h index d0b5b0db8c..39da21cc11 100644 --- a/src/gromacs/math/tests/testarrayrefs.h +++ b/src/gromacs/math/tests/testarrayrefs.h @@ -52,37 +52,34 @@ namespace test { //! Initialization overload for non-BasicVector -template -void fillInputContents(ArrayRef inputRef, - int scaleFactor) +template +void fillInputContents(ArrayRef inputRef, int scaleFactor) { inputRef[0] = 1; inputRef[1] = 2; inputRef[2] = 3; - for (auto &element : inputRef) + for (auto& element : inputRef) { element *= scaleFactor; } } //! Initialization overload for BasicVector -template -void fillInputContents(ArrayRef < BasicVector < T>> inputRef, - int scaleFactor) +template +void fillInputContents(ArrayRef> inputRef, int scaleFactor) { - inputRef[0] = {1, 2, 3}; - inputRef[1] = {4, 5, 6}; - inputRef[2] = {7, 8, 9}; - for (auto &element : inputRef) + inputRef[0] = { 1, 2, 3 }; + inputRef[1] = { 4, 5, 6 }; + inputRef[2] = { 7, 8, 9 }; + for (auto& element : inputRef) { element *= scaleFactor; } } //! Dispatcher function for filling. -template -void fillInput(PaddedVectorOfT *input, - int scaleFactor) +template +void fillInput(PaddedVectorOfT* input, int scaleFactor) { // Use a size for the vector in tests that is prime enough to // expose problems where they exist. @@ -93,9 +90,8 @@ void fillInput(PaddedVectorOfT *input, } //! Comparison overload for non-BasicVector -template -void compareViews(ArrayRef input, - ArrayRef output) +template +void compareViews(ArrayRef input, ArrayRef output) { ASSERT_EQ(input.size(), output.size()); for (index i = 0; i != input.ssize(); ++i) @@ -105,9 +101,8 @@ void compareViews(ArrayRef input, } //! Comparison overload for BasicVector -template -void compareViews(ArrayRef < BasicVector < T>> input, - ArrayRef < BasicVector < T>> output) +template +void compareViews(ArrayRef> input, ArrayRef> output) { ASSERT_EQ(input.size(), output.size()); for (index i = 0; i != input.ssize(); ++i) diff --git a/src/gromacs/math/tests/vectypes.cpp b/src/gromacs/math/tests/vectypes.cpp index 4f208be6b3..3cbaab7b72 100644 --- a/src/gromacs/math/tests/vectypes.cpp +++ b/src/gromacs/math/tests/vectypes.cpp @@ -58,9 +58,9 @@ namespace { -using gmx::RVec; using gmx::DVec; using gmx::IVec; +using gmx::RVec; TEST(RVecTest, CanBeStoredInVector) { @@ -86,7 +86,7 @@ TEST(RVecTest, ConvertsImplicitlyTo_rvec) { std::vector v; v.emplace_back(1, 2, 3); - rvec x; + rvec x; copy_rvec(v[0], x); EXPECT_EQ(1, x[XX]); EXPECT_EQ(2, x[YY]); @@ -97,7 +97,7 @@ TEST(RVecTest, WorksAsMutable_rvec) { std::vector v; v.emplace_back(1, 2, 3); - rvec x = {2, 3, 4}; + rvec x = { 2, 3, 4 }; copy_rvec(x, v[0]); EXPECT_EQ(2, v[0][XX]); EXPECT_EQ(3, v[0][YY]); @@ -109,7 +109,7 @@ TEST(RVecTest, WorksAs_rvec_Array) std::vector v; v.emplace_back(1, 2, 3); v.emplace_back(2, 3, 4); - const rvec *r = as_rvec_array(v.data()); + const rvec* r = as_rvec_array(v.data()); EXPECT_EQ(1, r[0][XX]); EXPECT_EQ(2, r[0][YY]); EXPECT_EQ(3, r[0][ZZ]); @@ -195,7 +195,7 @@ TEST(RVecTest, CanDivideRVecInplace) RVec a(1, 2, 3); real b = 0.5; RVec c; - c = a/b; + c = a / b; EXPECT_EQ(2, c[XX]); EXPECT_EQ(4, c[YY]); EXPECT_EQ(6, c[ZZ]); @@ -276,7 +276,7 @@ TEST(RVecTest, CanLeftScalarMultiply) RVec a(1, 2, 3); real b = 2.0; RVec c; - c = b*a; + c = b * a; EXPECT_EQ(2, c[XX]); EXPECT_EQ(4, c[YY]); EXPECT_EQ(6, c[ZZ]); @@ -287,7 +287,7 @@ TEST(RVecTest, CanRightScalarMultiply) RVec a(1, 2, 3); real b = 2.0; RVec c; - c = a*b; + c = a * b; EXPECT_EQ(2, c[XX]); EXPECT_EQ(4, c[YY]); EXPECT_EQ(6, c[ZZ]); @@ -384,7 +384,7 @@ TEST(RVecTest, elementWiseMax) /*! \brief * Helper function for testing DVec to dvec conversions. */ -const dvec *testFunction(const dvec &x) +const dvec* testFunction(const dvec& x) { return &x; } @@ -392,7 +392,7 @@ const dvec *testFunction(const dvec &x) TEST(RVecTest, WorksAs_dvec_Reference) { DVec v(1, 2, 3); - const dvec *r = testFunction(v.as_vec()); + const dvec* r = testFunction(v.as_vec()); EXPECT_EQ(1, r[0][XX]); EXPECT_EQ(2, r[0][YY]); EXPECT_EQ(3, r[0][ZZ]); @@ -401,7 +401,7 @@ TEST(RVecTest, WorksAs_dvec_Reference) /*! \brief * Helper function for testing IVec to ivec conversions. */ -const ivec *testFunction(const ivec &x) +const ivec* testFunction(const ivec& x) { return &x; } @@ -409,7 +409,7 @@ const ivec *testFunction(const ivec &x) TEST(RVecTest, WorksAs_ivec_Reference) { IVec v(1, 2, 3); - const ivec *r = testFunction(v.as_vec()); + const ivec* r = testFunction(v.as_vec()); EXPECT_EQ(1, r[0][XX]); EXPECT_EQ(2, r[0][YY]); EXPECT_EQ(3, r[0][ZZ]); @@ -418,8 +418,8 @@ TEST(RVecTest, WorksAs_ivec_Reference) /*! \brief * Helper function for testing RVec to rvec conversions. */ -#if !GMX_DOUBLE //otherwise rvec==dvec -const rvec *testFunction(const rvec &x) +#if !GMX_DOUBLE // otherwise rvec==dvec +const rvec* testFunction(const rvec& x) { return &x; } @@ -428,7 +428,7 @@ const rvec *testFunction(const rvec &x) TEST(RVecTest, WorksAs_rvec_Reference) { RVec v(1, 2, 3); - const rvec *r = testFunction(v); + const rvec* r = testFunction(v); EXPECT_EQ(1, r[0][XX]); EXPECT_EQ(2, r[0][YY]); EXPECT_EQ(3, r[0][ZZ]); diff --git a/src/gromacs/math/units.cpp b/src/gromacs/math/units.cpp index f16e988a43..ed4d4f74e5 100644 --- a/src/gromacs/math/units.cpp +++ b/src/gromacs/math/units.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,30 +44,18 @@ double convert2gmx(double x, int unit) { switch (unit) { - case eg2cAngstrom: - return x*A2NM; - case eg2cNm: - return x; - case eg2cBohr: - return x*BOHR2NM; - case eg2cKcal_Mole: - return x/CAL2JOULE; - case eg2cHartree: - return x*ONE_4PI_EPS0/BOHR2NM; - case eg2cHartree_e: - return x*ONE_4PI_EPS0/BOHR2NM; - case eg2cAngstrom3: - return x*A2NM*A2NM*A2NM; - case eg2cCoulomb: - return x/E_CHARGE; - case eg2cDebye: - return x*DEBYE2ENM; - case eg2cElectron: - return x; - case eg2cBuckingham: - return x*A2NM*DEBYE2ENM; - default: - fprintf(stderr, "Unknown unit %d, not converting.\n", unit); + case eg2cAngstrom: return x * A2NM; + case eg2cNm: return x; + case eg2cBohr: return x * BOHR2NM; + case eg2cKcal_Mole: return x / CAL2JOULE; + case eg2cHartree: return x * ONE_4PI_EPS0 / BOHR2NM; + case eg2cHartree_e: return x * ONE_4PI_EPS0 / BOHR2NM; + case eg2cAngstrom3: return x * A2NM * A2NM * A2NM; + case eg2cCoulomb: return x / E_CHARGE; + case eg2cDebye: return x * DEBYE2ENM; + case eg2cElectron: return x; + case eg2cBuckingham: return x * A2NM * DEBYE2ENM; + default: fprintf(stderr, "Unknown unit %d, not converting.\n", unit); } return x; } @@ -76,42 +64,28 @@ double gmx2convert(double x, int unit) { switch (unit) { - case eg2cAngstrom: - return x/A2NM; - case eg2cNm: - return x; - case eg2cBohr: - return x/BOHR2NM; - case eg2cKcal_Mole: - return x*CAL2JOULE; - case eg2cHartree: - return x/(ONE_4PI_EPS0/BOHR2NM); - case eg2cHartree_e: - return x/(ONE_4PI_EPS0/BOHR2NM); - case eg2cAngstrom3: - return x/(A2NM*A2NM*A2NM); - case eg2cCoulomb: - return x*E_CHARGE; - case eg2cDebye: - return x/DEBYE2ENM; - case eg2cElectron: - return x; - case eg2cBuckingham: - return x/(A2NM*DEBYE2ENM); - default: - fprintf(stderr, "Unknown unit %d, not converting.\n", unit); + case eg2cAngstrom: return x / A2NM; + case eg2cNm: return x; + case eg2cBohr: return x / BOHR2NM; + case eg2cKcal_Mole: return x * CAL2JOULE; + case eg2cHartree: return x / (ONE_4PI_EPS0 / BOHR2NM); + case eg2cHartree_e: return x / (ONE_4PI_EPS0 / BOHR2NM); + case eg2cAngstrom3: return x / (A2NM * A2NM * A2NM); + case eg2cCoulomb: return x * E_CHARGE; + case eg2cDebye: return x / DEBYE2ENM; + case eg2cElectron: return x; + case eg2cBuckingham: return x / (A2NM * DEBYE2ENM); + default: fprintf(stderr, "Unknown unit %d, not converting.\n", unit); } return x; } /* This has to have the same order as the enums. */ -static const char *eg2c_names[eg2cNR] = { - "Angstrom", "Nm", "Bohr", "Kcal_Mole", - "Hartree", "Hartree_e", "Angstrom3", "Coulomb", - "Debye", "Electron", "Buckingham" -}; +static const char* eg2c_names[eg2cNR] = { "Angstrom", "Nm", "Bohr", "Kcal_Mole", + "Hartree", "Hartree_e", "Angstrom3", "Coulomb", + "Debye", "Electron", "Buckingham" }; -int string2unit(char *string) +int string2unit(char* string) { int i; @@ -125,7 +99,7 @@ int string2unit(char *string) return -1; } -const char *unit2string(int unit) +const char* unit2string(int unit) { if ((unit >= 0) && (unit < eg2cNR)) { diff --git a/src/gromacs/math/units.h b/src/gromacs/math/units.h index d241c5ee01..1dcfb3cf95 100644 --- a/src/gromacs/math/units.h +++ b/src/gromacs/math/units.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,70 +45,70 @@ #include "gromacs/math/utilities.h" -#define ANGSTROM (1e-10) /* Old... */ -#define KILO (1e3) /* Thousand */ -#define NANO (1e-9) /* A Number */ -#define PICO (1e-12) /* A Number */ -#define A2NM (ANGSTROM/NANO) /* NANO */ -#define NM2A (NANO/ANGSTROM) /* 10.0 */ -#define RAD2DEG (180.0/M_PI) /* Conversion */ -#define DEG2RAD (M_PI/180.0) /* id */ -#define CAL2JOULE (4.184) /* id */ -#define E_CHARGE (1.602176565e-19) /* Coulomb, NIST 2010 CODATA */ - -#define AMU (1.660538921e-27) /* kg, NIST 2010 CODATA */ -#define BOLTZMANN (1.3806488e-23) /* (J/K, NIST 2010 CODATA */ -#define AVOGADRO (6.02214129e23) /* no unit, NIST 2010 CODATA */ -#define RGAS (BOLTZMANN*AVOGADRO) /* (J/(mol K)) */ -#define BOLTZ (RGAS/KILO) /* (kJ/(mol K)) */ -#define FARADAY (E_CHARGE*AVOGADRO) /* (C/mol) */ -#define ELECTRONVOLT (E_CHARGE*AVOGADRO/KILO) /* (kJ/mol) */ -#define PLANCK1 (6.62606957e-34) /* J s, NIST 2010 CODATA */ -#define PLANCK (PLANCK1*AVOGADRO/(PICO*KILO)) /* (kJ/mol) ps */ - -#define EPSILON0_SI (8.854187817e-12) /* F/m, NIST 2010 CODATA */ +#define ANGSTROM (1e-10) /* Old... */ +#define KILO (1e3) /* Thousand */ +#define NANO (1e-9) /* A Number */ +#define PICO (1e-12) /* A Number */ +#define A2NM (ANGSTROM / NANO) /* NANO */ +#define NM2A (NANO / ANGSTROM) /* 10.0 */ +#define RAD2DEG (180.0 / M_PI) /* Conversion */ +#define DEG2RAD (M_PI / 180.0) /* id */ +#define CAL2JOULE (4.184) /* id */ +#define E_CHARGE (1.602176565e-19) /* Coulomb, NIST 2010 CODATA */ + +#define AMU (1.660538921e-27) /* kg, NIST 2010 CODATA */ +#define BOLTZMANN (1.3806488e-23) /* (J/K, NIST 2010 CODATA */ +#define AVOGADRO (6.02214129e23) /* no unit, NIST 2010 CODATA */ +#define RGAS (BOLTZMANN * AVOGADRO) /* (J/(mol K)) */ +#define BOLTZ (RGAS / KILO) /* (kJ/(mol K)) */ +#define FARADAY (E_CHARGE * AVOGADRO) /* (C/mol) */ +#define ELECTRONVOLT (E_CHARGE * AVOGADRO / KILO) /* (kJ/mol) */ +#define PLANCK1 (6.62606957e-34) /* J s, NIST 2010 CODATA */ +#define PLANCK (PLANCK1 * AVOGADRO / (PICO * KILO)) /* (kJ/mol) ps */ + +#define EPSILON0_SI (8.854187817e-12) /* F/m, NIST 2010 CODATA */ /* Epsilon in our MD units: (e^2 / Na (kJ nm)) == (e^2 mol/(kJ nm)) */ -#define EPSILON0 ((EPSILON0_SI*NANO*KILO)/(E_CHARGE*E_CHARGE*AVOGADRO)) +#define EPSILON0 ((EPSILON0_SI * NANO * KILO) / (E_CHARGE * E_CHARGE * AVOGADRO)) -#define SPEED_OF_LIGHT (2.99792458E05) /* nm/ps, NIST 2010 CODATA */ -#define ATOMICMASS_keV (931494.061) /* Atomic mass in keV, NIST 2010 CODATA */ -#define ELECTRONMASS_keV (510.998928) /* Electron mas in keV, NIST 2010 CODATA */ +#define SPEED_OF_LIGHT (2.99792458E05) /* nm/ps, NIST 2010 CODATA */ +#define ATOMICMASS_keV (931494.061) /* Atomic mass in keV, NIST 2010 CODATA */ +#define ELECTRONMASS_keV (510.998928) /* Electron mas in keV, NIST 2010 CODATA */ -#define RYDBERG (1.0973731568539e-02) /* nm^-1, NIST 2010 CODATA */ +#define RYDBERG (1.0973731568539e-02) /* nm^-1, NIST 2010 CODATA */ -#define ONE_4PI_EPS0 (1.0/(4.0*M_PI*EPSILON0)) -#define FACEL (10.0*ONE_4PI_EPS0) +#define ONE_4PI_EPS0 (1.0 / (4.0 * M_PI * EPSILON0)) +#define FACEL (10.0 * ONE_4PI_EPS0) /* Pressure in MD units is: * 1 bar = 1e5 Pa = 1e5 kg m^-1 s^-2 = 1e-28 kg nm^-1 ps^-2 = 1e-28 / AMU amu nm^1 ps ^2 */ -#define BAR_MDUNITS (1e5*NANO*PICO*PICO/AMU) -#define PRESFAC (1.0/BAR_MDUNITS) +#define BAR_MDUNITS (1e5 * NANO * PICO * PICO / AMU) +#define PRESFAC (1.0 / BAR_MDUNITS) /* DEBYE2ENM should be (1e-21*PICO)/(SPEED_OF_LIGHT*E_CHARGE*NANO*NANO), * but we need to factor out some of the exponents to avoid single-precision overflows. */ -#define DEBYE2ENM (1e-15/(SPEED_OF_LIGHT*E_CHARGE)) -#define ENM2DEBYE (1.0/DEBYE2ENM) +#define DEBYE2ENM (1e-15 / (SPEED_OF_LIGHT * E_CHARGE)) +#define ENM2DEBYE (1.0 / DEBYE2ENM) /* to convert from a acceleration in (e V)/(amu nm) */ /* FIELDFAC is also Faraday's constant and E_CHARGE/(1e6 AMU) */ -#define FIELDFAC (FARADAY/KILO) +#define FIELDFAC (FARADAY / KILO) /* to convert AU to MD units: */ -#define HARTREE2KJ ((2.0*RYDBERG*PLANCK*SPEED_OF_LIGHT)/AVOGADRO) -#define BOHR2NM (0.052917721092) /* nm^-1, NIST 2010 CODATA */ -#define HARTREE_BOHR2MD (HARTREE2KJ*AVOGADRO/BOHR2NM) +#define HARTREE2KJ ((2.0 * RYDBERG * PLANCK * SPEED_OF_LIGHT) / AVOGADRO) +#define BOHR2NM (0.052917721092) /* nm^-1, NIST 2010 CODATA */ +#define HARTREE_BOHR2MD (HARTREE2KJ * AVOGADRO / BOHR2NM) /* The four basic units */ -#define unit_length "nm" -#define unit_time "ps" -#define unit_mass "u" -#define unit_energy "kJ/mol" +#define unit_length "nm" +#define unit_time "ps" +#define unit_mass "u" +#define unit_energy "kJ/mol" /* Temperature unit, T in this unit times BOLTZ give energy in unit_energy */ -#define unit_temp_K "K" +#define unit_temp_K "K" /* Charge unit, electron charge, involves ONE_4PI_EPS0 */ #define unit_charge_e "e" @@ -120,27 +120,37 @@ #define unit_dipole_D "D" /* Derived units from basic units only */ -#define unit_vel unit_length "/" unit_time -#define unit_volume unit_length "^3" -#define unit_invtime "1/" unit_time +#define unit_vel unit_length "/" unit_time +#define unit_volume unit_length "^3" +#define unit_invtime "1/" unit_time /* Other derived units */ #define unit_surft_bar unit_pres_bar " " unit_length /* SI units, conversion from basic units involves NANO, PICO and AMU */ -#define unit_length_SI "m" -#define unit_time_SI "s" -#define unit_mass_SI "kg" +#define unit_length_SI "m" +#define unit_time_SI "s" +#define unit_mass_SI "kg" #define unit_density_SI unit_mass_SI "/" unit_length_SI "^3" #define unit_invvisc_SI unit_length_SI " " unit_time_SI "/" unit_mass_SI /* The routines below can be used for converting units from or to GROMACS internal units. */ -enum { - eg2cAngstrom, eg2cNm, eg2cBohr, eg2cKcal_Mole, - eg2cHartree, eg2cHartree_e, eg2cAngstrom3, eg2cCoulomb, - eg2cDebye, eg2cElectron, eg2cBuckingham, eg2cNR +enum +{ + eg2cAngstrom, + eg2cNm, + eg2cBohr, + eg2cKcal_Mole, + eg2cHartree, + eg2cHartree_e, + eg2cAngstrom3, + eg2cCoulomb, + eg2cDebye, + eg2cElectron, + eg2cBuckingham, + eg2cNR }; /* Convert value x to GROMACS units. Energy -> Energy, Length -> Length etc. @@ -153,9 +163,9 @@ extern double convert2gmx(double x, int unit); extern double gmx2convert(double x, int unit); /* Convert the string to one of the units supported. Returns -1 if not found. */ -extern int string2unit(char *string); +extern int string2unit(char* string); /* Convert the unit to a string. Return NULL when unit is out of range. */ -extern const char *unit2string(int unit); +extern const char* unit2string(int unit); #endif diff --git a/src/gromacs/math/utilities.cpp b/src/gromacs/math/utilities.cpp index aff1c7a203..68a45843ab 100644 --- a/src/gromacs/math/utilities.cpp +++ b/src/gromacs/math/utilities.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,26 +51,19 @@ //! Floating point exception set that we use and care about constexpr int c_FPexceptions = FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW; -bool -gmx_within_tol(double f1, - double f2, - double tol) +bool gmx_within_tol(double f1, double f2, double tol) { /* The or-equal is important - otherwise we return false if f1==f2==0 */ - return fabs(f1-f2) <= tol*0.5*(fabs(f1)+fabs(f2)); + return fabs(f1 - f2) <= tol * 0.5 * (fabs(f1) + fabs(f2)); } -bool -gmx_numzero(double a) +bool gmx_numzero(double a) { - return gmx_within_tol(a, 0.0, GMX_REAL_MIN/GMX_REAL_EPS); + return gmx_within_tol(a, 0.0, GMX_REAL_MIN / GMX_REAL_EPS); } -gmx_bool -check_int_multiply_for_overflow(int64_t a, - int64_t b, - int64_t *result) +gmx_bool check_int_multiply_for_overflow(int64_t a, int64_t b, int64_t* result) { int64_t sign = 1; if ((0 == a) || (0 == b)) @@ -123,14 +116,14 @@ int gmx_feenableexcept() static fenv_t fenv; unsigned int new_excepts = c_FPexceptions & FE_ALL_EXCEPT; - if (fegetenv (&fenv) ) + if (fegetenv(&fenv)) { return -1; } // unmask fenv.__control &= ~new_excepts; - fenv.__mxcsr &= ~(new_excepts << 7); + fenv.__mxcsr &= ~(new_excepts << 7); return fesetenv(&fenv); #else @@ -145,14 +138,14 @@ int gmx_fedisableexcept() #elif (defined(__i386__) || defined(__x86_64__)) && defined(__APPLE__) static fenv_t fenv; unsigned int new_excepts = c_FPexceptions & FE_ALL_EXCEPT; - if (fegetenv (&fenv) ) + if (fegetenv(&fenv)) { return -1; } // mask fenv.__control |= new_excepts; - fenv.__mxcsr |= new_excepts << 7; + fenv.__mxcsr |= new_excepts << 7; return fesetenv(&fenv); #else diff --git a/src/gromacs/math/utilities.h b/src/gromacs/math/utilities.h index 92b35e105f..fbf97184fd 100644 --- a/src/gromacs/math/utilities.h +++ b/src/gromacs/math/utilities.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,38 +45,38 @@ #include "gromacs/utility/real.h" #ifndef M_PI -#define M_PI 3.14159265358979323846 +# define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +# define M_PI_2 1.57079632679489661923 #endif #ifndef M_2PI -#define M_2PI 6.28318530717958647692 +# define M_2PI 6.28318530717958647692 #endif #ifndef M_SQRT2 -#define M_SQRT2 sqrt(2.0) +# define M_SQRT2 sqrt(2.0) #endif #ifndef M_1_PI -#define M_1_PI 0.31830988618379067154 +# define M_1_PI 0.31830988618379067154 #endif #ifndef M_FLOAT_1_SQRTPI /* used in GPU kernels */ /* 1.0 / sqrt(M_PI) */ -#define M_FLOAT_1_SQRTPI 0.564189583547756f +# define M_FLOAT_1_SQRTPI 0.564189583547756f #endif #ifndef M_1_SQRTPI /* 1.0 / sqrt(M_PI) */ -#define M_1_SQRTPI 0.564189583547756 +# define M_1_SQRTPI 0.564189583547756 #endif #ifndef M_2_SQRTPI /* 2.0 / sqrt(M_PI) */ -#define M_2_SQRTPI 1.128379167095513 +# define M_2_SQRTPI 1.128379167095513 #endif /*! \brief Enum to select safe or highly unsafe (faster) math functions. @@ -97,8 +97,8 @@ */ enum class MathOptimization { - Safe, //!< Don't do unsafe optimizations. This should always be default. - Unsafe //!< Allow optimizations that can be VERY dangerous for general code. + Safe, //!< Don't do unsafe optimizations. This should always be default. + Unsafe //!< Allow optimizations that can be VERY dangerous for general code. }; /*! \brief Check if two numbers are within a tolerance @@ -121,10 +121,7 @@ enum class MathOptimization * * \return 1 if the relative difference is within tolerance, 0 if not. */ -bool -gmx_within_tol(double f1, - double f2, - double tol); +bool gmx_within_tol(double f1, double f2, double tol); /*! * \brief Check if a number is smaller than some preset safe minimum @@ -135,24 +132,19 @@ gmx_within_tol(double f1, * * \return 1 if 'almost' numerically zero, 0 otherwise. */ -bool -gmx_numzero(double a); +bool gmx_numzero(double a); /*! \brief Multiply two large ints * * \return False iff overflow occurred */ -gmx_bool -check_int_multiply_for_overflow(int64_t a, - int64_t b, - int64_t *result); +gmx_bool check_int_multiply_for_overflow(int64_t a, int64_t b, int64_t* result); /*! \brief Find greatest common divisor of two numbers * * \return GCD of the two inputs */ -int -gmx_greatest_common_divisor(int p, int q); +int gmx_greatest_common_divisor(int p, int q); /*! \brief Enable floating-point exceptions if supported on OS diff --git a/src/gromacs/math/vec.h b/src/gromacs/math/vec.h index 0a522b47be..61f51d8b9b 100644 --- a/src/gromacs/math/vec.h +++ b/src/gromacs/math/vec.h @@ -115,9 +115,9 @@ static inline void rvec_add(const rvec a, const rvec b, rvec c) { real x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; c[XX] = x; c[YY] = y; @@ -128,9 +128,9 @@ static inline void ivec_add(const ivec a, const ivec b, ivec c) { int x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; c[XX] = x; c[YY] = y; @@ -141,9 +141,9 @@ static inline void rvec_inc(rvec a, const rvec b) { real x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; a[XX] = x; a[YY] = y; @@ -154,9 +154,9 @@ static inline void dvec_inc(dvec a, const dvec b) { double x, y, z; - x = a[XX]+b[XX]; - y = a[YY]+b[YY]; - z = a[ZZ]+b[ZZ]; + x = a[XX] + b[XX]; + y = a[YY] + b[YY]; + z = a[ZZ] + b[ZZ]; a[XX] = x; a[YY] = y; @@ -167,9 +167,9 @@ static inline void rvec_sub(const rvec a, const rvec b, rvec c) { real x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; c[XX] = x; c[YY] = y; @@ -180,9 +180,9 @@ static inline void dvec_sub(const dvec a, const dvec b, dvec c) { double x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; c[XX] = x; c[YY] = y; @@ -193,9 +193,9 @@ static inline void rvec_dec(rvec a, const rvec b) { real x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; a[XX] = x; a[YY] = y; @@ -223,7 +223,7 @@ static inline void copy_dvec_to_rvec(const dvec a, rvec b) b[ZZ] = static_cast(a[ZZ]); } -static inline void copy_rvecn(const rvec *a, rvec *b, int startn, int endn) +static inline void copy_rvecn(const rvec* a, rvec* b, int startn, int endn) { int i; for (i = startn; i < endn; i++) @@ -252,9 +252,9 @@ static inline void ivec_sub(const ivec a, const ivec b, ivec c) { int x, y, z; - x = a[XX]-b[XX]; - y = a[YY]-b[YY]; - z = a[ZZ]-b[ZZ]; + x = a[XX] - b[XX]; + y = a[YY] - b[YY]; + z = a[ZZ] - b[ZZ]; c[XX] = x; c[YY] = y; @@ -270,21 +270,21 @@ static inline void copy_mat(const matrix a, matrix b) static inline void svmul(real a, const rvec v1, rvec v2) { - v2[XX] = a*v1[XX]; - v2[YY] = a*v1[YY]; - v2[ZZ] = a*v1[ZZ]; + v2[XX] = a * v1[XX]; + v2[YY] = a * v1[YY]; + v2[ZZ] = a * v1[ZZ]; } static inline void dsvmul(double a, const dvec v1, dvec v2) { - v2[XX] = a*v1[XX]; - v2[YY] = a*v1[YY]; - v2[ZZ] = a*v1[ZZ]; + v2[XX] = a * v1[XX]; + v2[YY] = a * v1[YY]; + v2[ZZ] = a * v1[ZZ]; } static inline real distance2(const rvec v1, const rvec v2) { - return gmx::square(v2[XX]-v1[XX]) + gmx::square(v2[YY]-v1[YY]) + gmx::square(v2[ZZ]-v1[ZZ]); + return gmx::square(v2[XX] - v1[XX]) + gmx::square(v2[YY] - v1[YY]) + gmx::square(v2[ZZ] - v1[ZZ]); } static inline void clear_rvec(rvec a) @@ -335,22 +335,22 @@ static inline void clear_mat(matrix a) static inline real iprod(const rvec a, const rvec b) { - return (a[XX]*b[XX]+a[YY]*b[YY]+a[ZZ]*b[ZZ]); + return (a[XX] * b[XX] + a[YY] * b[YY] + a[ZZ] * b[ZZ]); } static inline double diprod(const dvec a, const dvec b) { - return (a[XX]*b[XX]+a[YY]*b[YY]+a[ZZ]*b[ZZ]); + return (a[XX] * b[XX] + a[YY] * b[YY] + a[ZZ] * b[ZZ]); } static inline real norm2(const rvec a) { - return a[XX]*a[XX]+a[YY]*a[YY]+a[ZZ]*a[ZZ]; + return a[XX] * a[XX] + a[YY] * a[YY] + a[ZZ] * a[ZZ]; } static inline double dnorm2(const dvec a) { - return a[XX]*a[XX]+a[YY]*a[YY]+a[ZZ]*a[ZZ]; + return a[XX] * a[XX] + a[YY] * a[YY] + a[ZZ] * a[ZZ]; } /* WARNING: @@ -389,16 +389,16 @@ static inline real cos_angle(const rvec a, const rvec b) ip = ipa = ipb = 0.0; for (m = 0; (m < DIM); m++) /* 18 */ { - aa = a[m]; - bb = b[m]; - ip += aa*bb; - ipa += aa*aa; - ipb += bb*bb; + aa = a[m]; + bb = b[m]; + ip += aa * bb; + ipa += aa * aa; + ipb += bb * bb; } - ipab = ipa*ipb; + ipab = ipa * ipb; if (ipab > 0) { - cosval = static_cast(ip*gmx::invsqrt(ipab)); /* 7 */ + cosval = static_cast(ip * gmx::invsqrt(ipab)); /* 7 */ } else { @@ -419,16 +419,16 @@ static inline real cos_angle(const rvec a, const rvec b) static inline void cprod(const rvec a, const rvec b, rvec c) { - c[XX] = a[YY]*b[ZZ]-a[ZZ]*b[YY]; - c[YY] = a[ZZ]*b[XX]-a[XX]*b[ZZ]; - c[ZZ] = a[XX]*b[YY]-a[YY]*b[XX]; + c[XX] = a[YY] * b[ZZ] - a[ZZ] * b[YY]; + c[YY] = a[ZZ] * b[XX] - a[XX] * b[ZZ]; + c[ZZ] = a[XX] * b[YY] - a[YY] * b[XX]; } static inline void dcprod(const dvec a, const dvec b, dvec c) { - c[XX] = a[YY]*b[ZZ]-a[ZZ]*b[YY]; - c[YY] = a[ZZ]*b[XX]-a[XX]*b[ZZ]; - c[ZZ] = a[XX]*b[YY]-a[YY]*b[XX]; + c[XX] = a[YY] * b[ZZ] - a[ZZ] * b[YY]; + c[YY] = a[ZZ] * b[XX] - a[XX] * b[ZZ]; + c[ZZ] = a[XX] * b[YY] - a[YY] * b[XX]; } /* This routine calculates the angle between a & b without any loss of accuracy close to 0/PI. @@ -442,8 +442,8 @@ static inline real gmx_angle(const rvec a, const rvec b) cprod(a, b, w); - wlen = norm(w); - s = iprod(a, b); + wlen = norm(w); + s = iprod(a, b); return std::atan2(wlen, s); } @@ -455,36 +455,36 @@ static inline double gmx_angle_between_dvecs(const dvec a, const dvec b) dcprod(a, b, w); - wlen = dnorm(w); - s = diprod(a, b); + wlen = dnorm(w); + s = diprod(a, b); return std::atan2(wlen, s); } static inline void mmul_ur0(const matrix a, const matrix b, matrix dest) { - dest[XX][XX] = a[XX][XX]*b[XX][XX]; + dest[XX][XX] = a[XX][XX] * b[XX][XX]; dest[XX][YY] = 0.0; dest[XX][ZZ] = 0.0; - dest[YY][XX] = a[YY][XX]*b[XX][XX]+a[YY][YY]*b[YY][XX]; - dest[YY][YY] = a[YY][YY]*b[YY][YY]; + dest[YY][XX] = a[YY][XX] * b[XX][XX] + a[YY][YY] * b[YY][XX]; + dest[YY][YY] = a[YY][YY] * b[YY][YY]; dest[YY][ZZ] = 0.0; - dest[ZZ][XX] = a[ZZ][XX]*b[XX][XX]+a[ZZ][YY]*b[YY][XX]+a[ZZ][ZZ]*b[ZZ][XX]; - dest[ZZ][YY] = a[ZZ][YY]*b[YY][YY]+a[ZZ][ZZ]*b[ZZ][YY]; - dest[ZZ][ZZ] = a[ZZ][ZZ]*b[ZZ][ZZ]; + dest[ZZ][XX] = a[ZZ][XX] * b[XX][XX] + a[ZZ][YY] * b[YY][XX] + a[ZZ][ZZ] * b[ZZ][XX]; + dest[ZZ][YY] = a[ZZ][YY] * b[YY][YY] + a[ZZ][ZZ] * b[ZZ][YY]; + dest[ZZ][ZZ] = a[ZZ][ZZ] * b[ZZ][ZZ]; } static inline void mmul(const matrix a, const matrix b, matrix dest) { - dest[XX][XX] = a[XX][XX]*b[XX][XX]+a[XX][YY]*b[YY][XX]+a[XX][ZZ]*b[ZZ][XX]; - dest[YY][XX] = a[YY][XX]*b[XX][XX]+a[YY][YY]*b[YY][XX]+a[YY][ZZ]*b[ZZ][XX]; - dest[ZZ][XX] = a[ZZ][XX]*b[XX][XX]+a[ZZ][YY]*b[YY][XX]+a[ZZ][ZZ]*b[ZZ][XX]; - dest[XX][YY] = a[XX][XX]*b[XX][YY]+a[XX][YY]*b[YY][YY]+a[XX][ZZ]*b[ZZ][YY]; - dest[YY][YY] = a[YY][XX]*b[XX][YY]+a[YY][YY]*b[YY][YY]+a[YY][ZZ]*b[ZZ][YY]; - dest[ZZ][YY] = a[ZZ][XX]*b[XX][YY]+a[ZZ][YY]*b[YY][YY]+a[ZZ][ZZ]*b[ZZ][YY]; - dest[XX][ZZ] = a[XX][XX]*b[XX][ZZ]+a[XX][YY]*b[YY][ZZ]+a[XX][ZZ]*b[ZZ][ZZ]; - dest[YY][ZZ] = a[YY][XX]*b[XX][ZZ]+a[YY][YY]*b[YY][ZZ]+a[YY][ZZ]*b[ZZ][ZZ]; - dest[ZZ][ZZ] = a[ZZ][XX]*b[XX][ZZ]+a[ZZ][YY]*b[YY][ZZ]+a[ZZ][ZZ]*b[ZZ][ZZ]; + dest[XX][XX] = a[XX][XX] * b[XX][XX] + a[XX][YY] * b[YY][XX] + a[XX][ZZ] * b[ZZ][XX]; + dest[YY][XX] = a[YY][XX] * b[XX][XX] + a[YY][YY] * b[YY][XX] + a[YY][ZZ] * b[ZZ][XX]; + dest[ZZ][XX] = a[ZZ][XX] * b[XX][XX] + a[ZZ][YY] * b[YY][XX] + a[ZZ][ZZ] * b[ZZ][XX]; + dest[XX][YY] = a[XX][XX] * b[XX][YY] + a[XX][YY] * b[YY][YY] + a[XX][ZZ] * b[ZZ][YY]; + dest[YY][YY] = a[YY][XX] * b[XX][YY] + a[YY][YY] * b[YY][YY] + a[YY][ZZ] * b[ZZ][YY]; + dest[ZZ][YY] = a[ZZ][XX] * b[XX][YY] + a[ZZ][YY] * b[YY][YY] + a[ZZ][ZZ] * b[ZZ][YY]; + dest[XX][ZZ] = a[XX][XX] * b[XX][ZZ] + a[XX][YY] * b[YY][ZZ] + a[XX][ZZ] * b[ZZ][ZZ]; + dest[YY][ZZ] = a[YY][XX] * b[XX][ZZ] + a[YY][YY] * b[YY][ZZ] + a[YY][ZZ] * b[ZZ][ZZ]; + dest[ZZ][ZZ] = a[ZZ][XX] * b[XX][ZZ] + a[ZZ][YY] * b[YY][ZZ] + a[ZZ][ZZ] * b[ZZ][ZZ]; } static inline void transpose(const matrix src, matrix dest) @@ -503,98 +503,98 @@ static inline void transpose(const matrix src, matrix dest) static inline void tmmul(const matrix a, const matrix b, matrix dest) { /* Computes dest=mmul(transpose(a),b,dest) - used in do_pr_pcoupl */ - dest[XX][XX] = a[XX][XX]*b[XX][XX]+a[YY][XX]*b[YY][XX]+a[ZZ][XX]*b[ZZ][XX]; - dest[XX][YY] = a[XX][XX]*b[XX][YY]+a[YY][XX]*b[YY][YY]+a[ZZ][XX]*b[ZZ][YY]; - dest[XX][ZZ] = a[XX][XX]*b[XX][ZZ]+a[YY][XX]*b[YY][ZZ]+a[ZZ][XX]*b[ZZ][ZZ]; - dest[YY][XX] = a[XX][YY]*b[XX][XX]+a[YY][YY]*b[YY][XX]+a[ZZ][YY]*b[ZZ][XX]; - dest[YY][YY] = a[XX][YY]*b[XX][YY]+a[YY][YY]*b[YY][YY]+a[ZZ][YY]*b[ZZ][YY]; - dest[YY][ZZ] = a[XX][YY]*b[XX][ZZ]+a[YY][YY]*b[YY][ZZ]+a[ZZ][YY]*b[ZZ][ZZ]; - dest[ZZ][XX] = a[XX][ZZ]*b[XX][XX]+a[YY][ZZ]*b[YY][XX]+a[ZZ][ZZ]*b[ZZ][XX]; - dest[ZZ][YY] = a[XX][ZZ]*b[XX][YY]+a[YY][ZZ]*b[YY][YY]+a[ZZ][ZZ]*b[ZZ][YY]; - dest[ZZ][ZZ] = a[XX][ZZ]*b[XX][ZZ]+a[YY][ZZ]*b[YY][ZZ]+a[ZZ][ZZ]*b[ZZ][ZZ]; + dest[XX][XX] = a[XX][XX] * b[XX][XX] + a[YY][XX] * b[YY][XX] + a[ZZ][XX] * b[ZZ][XX]; + dest[XX][YY] = a[XX][XX] * b[XX][YY] + a[YY][XX] * b[YY][YY] + a[ZZ][XX] * b[ZZ][YY]; + dest[XX][ZZ] = a[XX][XX] * b[XX][ZZ] + a[YY][XX] * b[YY][ZZ] + a[ZZ][XX] * b[ZZ][ZZ]; + dest[YY][XX] = a[XX][YY] * b[XX][XX] + a[YY][YY] * b[YY][XX] + a[ZZ][YY] * b[ZZ][XX]; + dest[YY][YY] = a[XX][YY] * b[XX][YY] + a[YY][YY] * b[YY][YY] + a[ZZ][YY] * b[ZZ][YY]; + dest[YY][ZZ] = a[XX][YY] * b[XX][ZZ] + a[YY][YY] * b[YY][ZZ] + a[ZZ][YY] * b[ZZ][ZZ]; + dest[ZZ][XX] = a[XX][ZZ] * b[XX][XX] + a[YY][ZZ] * b[YY][XX] + a[ZZ][ZZ] * b[ZZ][XX]; + dest[ZZ][YY] = a[XX][ZZ] * b[XX][YY] + a[YY][ZZ] * b[YY][YY] + a[ZZ][ZZ] * b[ZZ][YY]; + dest[ZZ][ZZ] = a[XX][ZZ] * b[XX][ZZ] + a[YY][ZZ] * b[YY][ZZ] + a[ZZ][ZZ] * b[ZZ][ZZ]; } static inline void mtmul(const matrix a, const matrix b, matrix dest) { /* Computes dest=mmul(a,transpose(b),dest) - used in do_pr_pcoupl */ - dest[XX][XX] = a[XX][XX]*b[XX][XX]+a[XX][YY]*b[XX][YY]+a[XX][ZZ]*b[XX][ZZ]; - dest[XX][YY] = a[XX][XX]*b[YY][XX]+a[XX][YY]*b[YY][YY]+a[XX][ZZ]*b[YY][ZZ]; - dest[XX][ZZ] = a[XX][XX]*b[ZZ][XX]+a[XX][YY]*b[ZZ][YY]+a[XX][ZZ]*b[ZZ][ZZ]; - dest[YY][XX] = a[YY][XX]*b[XX][XX]+a[YY][YY]*b[XX][YY]+a[YY][ZZ]*b[XX][ZZ]; - dest[YY][YY] = a[YY][XX]*b[YY][XX]+a[YY][YY]*b[YY][YY]+a[YY][ZZ]*b[YY][ZZ]; - dest[YY][ZZ] = a[YY][XX]*b[ZZ][XX]+a[YY][YY]*b[ZZ][YY]+a[YY][ZZ]*b[ZZ][ZZ]; - dest[ZZ][XX] = a[ZZ][XX]*b[XX][XX]+a[ZZ][YY]*b[XX][YY]+a[ZZ][ZZ]*b[XX][ZZ]; - dest[ZZ][YY] = a[ZZ][XX]*b[YY][XX]+a[ZZ][YY]*b[YY][YY]+a[ZZ][ZZ]*b[YY][ZZ]; - dest[ZZ][ZZ] = a[ZZ][XX]*b[ZZ][XX]+a[ZZ][YY]*b[ZZ][YY]+a[ZZ][ZZ]*b[ZZ][ZZ]; + dest[XX][XX] = a[XX][XX] * b[XX][XX] + a[XX][YY] * b[XX][YY] + a[XX][ZZ] * b[XX][ZZ]; + dest[XX][YY] = a[XX][XX] * b[YY][XX] + a[XX][YY] * b[YY][YY] + a[XX][ZZ] * b[YY][ZZ]; + dest[XX][ZZ] = a[XX][XX] * b[ZZ][XX] + a[XX][YY] * b[ZZ][YY] + a[XX][ZZ] * b[ZZ][ZZ]; + dest[YY][XX] = a[YY][XX] * b[XX][XX] + a[YY][YY] * b[XX][YY] + a[YY][ZZ] * b[XX][ZZ]; + dest[YY][YY] = a[YY][XX] * b[YY][XX] + a[YY][YY] * b[YY][YY] + a[YY][ZZ] * b[YY][ZZ]; + dest[YY][ZZ] = a[YY][XX] * b[ZZ][XX] + a[YY][YY] * b[ZZ][YY] + a[YY][ZZ] * b[ZZ][ZZ]; + dest[ZZ][XX] = a[ZZ][XX] * b[XX][XX] + a[ZZ][YY] * b[XX][YY] + a[ZZ][ZZ] * b[XX][ZZ]; + dest[ZZ][YY] = a[ZZ][XX] * b[YY][XX] + a[ZZ][YY] * b[YY][YY] + a[ZZ][ZZ] * b[YY][ZZ]; + dest[ZZ][ZZ] = a[ZZ][XX] * b[ZZ][XX] + a[ZZ][YY] * b[ZZ][YY] + a[ZZ][ZZ] * b[ZZ][ZZ]; } static inline real det(const matrix a) { - return ( a[XX][XX]*(a[YY][YY]*a[ZZ][ZZ]-a[ZZ][YY]*a[YY][ZZ]) - -a[YY][XX]*(a[XX][YY]*a[ZZ][ZZ]-a[ZZ][YY]*a[XX][ZZ]) - +a[ZZ][XX]*(a[XX][YY]*a[YY][ZZ]-a[YY][YY]*a[XX][ZZ])); + return (a[XX][XX] * (a[YY][YY] * a[ZZ][ZZ] - a[ZZ][YY] * a[YY][ZZ]) + - a[YY][XX] * (a[XX][YY] * a[ZZ][ZZ] - a[ZZ][YY] * a[XX][ZZ]) + + a[ZZ][XX] * (a[XX][YY] * a[YY][ZZ] - a[YY][YY] * a[XX][ZZ])); } static inline void m_add(const matrix a, const matrix b, matrix dest) { - dest[XX][XX] = a[XX][XX]+b[XX][XX]; - dest[XX][YY] = a[XX][YY]+b[XX][YY]; - dest[XX][ZZ] = a[XX][ZZ]+b[XX][ZZ]; - dest[YY][XX] = a[YY][XX]+b[YY][XX]; - dest[YY][YY] = a[YY][YY]+b[YY][YY]; - dest[YY][ZZ] = a[YY][ZZ]+b[YY][ZZ]; - dest[ZZ][XX] = a[ZZ][XX]+b[ZZ][XX]; - dest[ZZ][YY] = a[ZZ][YY]+b[ZZ][YY]; - dest[ZZ][ZZ] = a[ZZ][ZZ]+b[ZZ][ZZ]; + dest[XX][XX] = a[XX][XX] + b[XX][XX]; + dest[XX][YY] = a[XX][YY] + b[XX][YY]; + dest[XX][ZZ] = a[XX][ZZ] + b[XX][ZZ]; + dest[YY][XX] = a[YY][XX] + b[YY][XX]; + dest[YY][YY] = a[YY][YY] + b[YY][YY]; + dest[YY][ZZ] = a[YY][ZZ] + b[YY][ZZ]; + dest[ZZ][XX] = a[ZZ][XX] + b[ZZ][XX]; + dest[ZZ][YY] = a[ZZ][YY] + b[ZZ][YY]; + dest[ZZ][ZZ] = a[ZZ][ZZ] + b[ZZ][ZZ]; } static inline void m_sub(const matrix a, const matrix b, matrix dest) { - dest[XX][XX] = a[XX][XX]-b[XX][XX]; - dest[XX][YY] = a[XX][YY]-b[XX][YY]; - dest[XX][ZZ] = a[XX][ZZ]-b[XX][ZZ]; - dest[YY][XX] = a[YY][XX]-b[YY][XX]; - dest[YY][YY] = a[YY][YY]-b[YY][YY]; - dest[YY][ZZ] = a[YY][ZZ]-b[YY][ZZ]; - dest[ZZ][XX] = a[ZZ][XX]-b[ZZ][XX]; - dest[ZZ][YY] = a[ZZ][YY]-b[ZZ][YY]; - dest[ZZ][ZZ] = a[ZZ][ZZ]-b[ZZ][ZZ]; + dest[XX][XX] = a[XX][XX] - b[XX][XX]; + dest[XX][YY] = a[XX][YY] - b[XX][YY]; + dest[XX][ZZ] = a[XX][ZZ] - b[XX][ZZ]; + dest[YY][XX] = a[YY][XX] - b[YY][XX]; + dest[YY][YY] = a[YY][YY] - b[YY][YY]; + dest[YY][ZZ] = a[YY][ZZ] - b[YY][ZZ]; + dest[ZZ][XX] = a[ZZ][XX] - b[ZZ][XX]; + dest[ZZ][YY] = a[ZZ][YY] - b[ZZ][YY]; + dest[ZZ][ZZ] = a[ZZ][ZZ] - b[ZZ][ZZ]; } static inline void msmul(const matrix m1, real r1, matrix dest) { - dest[XX][XX] = r1*m1[XX][XX]; - dest[XX][YY] = r1*m1[XX][YY]; - dest[XX][ZZ] = r1*m1[XX][ZZ]; - dest[YY][XX] = r1*m1[YY][XX]; - dest[YY][YY] = r1*m1[YY][YY]; - dest[YY][ZZ] = r1*m1[YY][ZZ]; - dest[ZZ][XX] = r1*m1[ZZ][XX]; - dest[ZZ][YY] = r1*m1[ZZ][YY]; - dest[ZZ][ZZ] = r1*m1[ZZ][ZZ]; + dest[XX][XX] = r1 * m1[XX][XX]; + dest[XX][YY] = r1 * m1[XX][YY]; + dest[XX][ZZ] = r1 * m1[XX][ZZ]; + dest[YY][XX] = r1 * m1[YY][XX]; + dest[YY][YY] = r1 * m1[YY][YY]; + dest[YY][ZZ] = r1 * m1[YY][ZZ]; + dest[ZZ][XX] = r1 * m1[ZZ][XX]; + dest[ZZ][YY] = r1 * m1[ZZ][YY]; + dest[ZZ][ZZ] = r1 * m1[ZZ][ZZ]; } static inline void mvmul(const matrix a, const rvec src, rvec dest) { - dest[XX] = a[XX][XX]*src[XX]+a[XX][YY]*src[YY]+a[XX][ZZ]*src[ZZ]; - dest[YY] = a[YY][XX]*src[XX]+a[YY][YY]*src[YY]+a[YY][ZZ]*src[ZZ]; - dest[ZZ] = a[ZZ][XX]*src[XX]+a[ZZ][YY]*src[YY]+a[ZZ][ZZ]*src[ZZ]; + dest[XX] = a[XX][XX] * src[XX] + a[XX][YY] * src[YY] + a[XX][ZZ] * src[ZZ]; + dest[YY] = a[YY][XX] * src[XX] + a[YY][YY] * src[YY] + a[YY][ZZ] * src[ZZ]; + dest[ZZ] = a[ZZ][XX] * src[XX] + a[ZZ][YY] * src[YY] + a[ZZ][ZZ] * src[ZZ]; } static inline void mvmul_ur0(const matrix a, const rvec src, rvec dest) { - dest[ZZ] = a[ZZ][XX]*src[XX]+a[ZZ][YY]*src[YY]+a[ZZ][ZZ]*src[ZZ]; - dest[YY] = a[YY][XX]*src[XX]+a[YY][YY]*src[YY]; - dest[XX] = a[XX][XX]*src[XX]; + dest[ZZ] = a[ZZ][XX] * src[XX] + a[ZZ][YY] * src[YY] + a[ZZ][ZZ] * src[ZZ]; + dest[YY] = a[YY][XX] * src[XX] + a[YY][YY] * src[YY]; + dest[XX] = a[XX][XX] * src[XX]; } static inline void tmvmul_ur0(const matrix a, const rvec src, rvec dest) { - dest[XX] = a[XX][XX]*src[XX]+a[YY][XX]*src[YY]+a[ZZ][XX]*src[ZZ]; - dest[YY] = a[YY][YY]*src[YY]+a[ZZ][YY]*src[ZZ]; - dest[ZZ] = a[ZZ][ZZ]*src[ZZ]; + dest[XX] = a[XX][XX] * src[XX] + a[YY][XX] * src[YY] + a[ZZ][XX] * src[ZZ]; + dest[YY] = a[YY][YY] * src[YY] + a[ZZ][YY] * src[ZZ]; + dest[ZZ] = a[ZZ][ZZ] * src[ZZ]; } static inline void unitv(const rvec src, rvec dest) @@ -602,14 +602,14 @@ static inline void unitv(const rvec src, rvec dest) real linv; linv = gmx::invsqrt(norm2(src)); - dest[XX] = linv*src[XX]; - dest[YY] = linv*src[YY]; - dest[ZZ] = linv*src[ZZ]; + dest[XX] = linv * src[XX]; + dest[YY] = linv * src[YY]; + dest[ZZ] = linv * src[ZZ]; } static inline real trace(const matrix m) { - return (m[XX][XX]+m[YY][YY]+m[ZZ][ZZ]); + return (m[XX][XX] + m[YY][YY] + m[ZZ][ZZ]); } namespace gmx @@ -626,18 +626,18 @@ namespace gmx * \return magnitude or squared magnitude of vector * \{ */ -template std::remove_const_t -norm(T* v) +template +std::remove_const_t norm(T* v) { return ::norm(v); } -template std::remove_const_t -norm2(T* v) +template +std::remove_const_t norm2(T* v) { return ::norm2(v); } -} // namespace gmx +} // namespace gmx /*! \} */ diff --git a/src/gromacs/math/veccompare.cpp b/src/gromacs/math/veccompare.cpp index 54eece90e9..22c75d49f7 100644 --- a/src/gromacs/math/veccompare.cpp +++ b/src/gromacs/math/veccompare.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,44 +43,42 @@ #include "gromacs/utility/compare.h" -void cmp_rvec(FILE *fp, const char *s, int index, const rvec i1, const rvec i2, real ftol, real abstol) +void cmp_rvec(FILE* fp, const char* s, int index, const rvec i1, const rvec i2, real ftol, real abstol) { - if (!equal_real(i1[XX], i2[XX], ftol, abstol) || - !equal_real(i1[YY], i2[YY], ftol, abstol) || - !equal_real(i1[ZZ], i2[ZZ], ftol, abstol)) + if (!equal_real(i1[XX], i2[XX], ftol, abstol) || !equal_real(i1[YY], i2[YY], ftol, abstol) + || !equal_real(i1[ZZ], i2[ZZ], ftol, abstol)) { if (index != -1) { - fprintf(fp, "%s[%5d] (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", - s, index, i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]); + fprintf(fp, "%s[%5d] (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", s, index, + i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]); } else { - fprintf(fp, "%s (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", - s, i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]); + fprintf(fp, "%s (%12.5e %12.5e %12.5e) - (%12.5e %12.5e %12.5e)\n", s, i1[XX], i1[YY], + i1[ZZ], i2[XX], i2[YY], i2[ZZ]); } } } -void cmp_ivec(FILE *fp, const char *s, int index, const ivec i1, const ivec i2) +void cmp_ivec(FILE* fp, const char* s, int index, const ivec i1, const ivec i2) { if ((i1[XX] != i2[XX]) || (i1[YY] != i2[YY]) || (i1[ZZ] != i2[ZZ])) { if (index != -1) { - fprintf(fp, "%s[%5d] (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, index, - i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]); + fprintf(fp, "%s[%5d] (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, index, i1[XX], i1[YY], i1[ZZ], + i2[XX], i2[YY], i2[ZZ]); } else { - fprintf(fp, "%s (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, - i1[XX], i1[YY], i1[ZZ], i2[XX], i2[YY], i2[ZZ]); + fprintf(fp, "%s (%8d,%8d,%8d - %8d,%8d,%8d)\n", s, i1[XX], i1[YY], i1[ZZ], i2[XX], + i2[YY], i2[ZZ]); } } } -static void cmp_rvecs_rmstol(FILE *fp, const char *title, int n, const rvec x1[], const rvec x2[], - real ftol, real abstol) +static void cmp_rvecs_rmstol(FILE* fp, const char* title, int n, const rvec x1[], const rvec x2[], real ftol, real abstol) { int i, m; double rms; @@ -94,15 +92,15 @@ static void cmp_rvecs_rmstol(FILE *fp, const char *title, int n, const rvec x1[] { for (m = 0; m < DIM; m++) { - rms += x1[i][m]*x1[i][m] + x2[i][m]*x2[i][m]; + rms += x1[i][m] * x1[i][m] + x2[i][m] * x2[i][m]; } } - rms = sqrt(rms/(2*n*DIM)); + rms = sqrt(rms / (2 * n * DIM)); /* Convert the relative tolerance into an absolute tolerance */ - if (ftol*rms < abstol) + if (ftol * rms < abstol) { - abstol = ftol*rms; + abstol = ftol * rms; } /* And now do the actual comparision */ @@ -112,8 +110,7 @@ static void cmp_rvecs_rmstol(FILE *fp, const char *title, int n, const rvec x1[] } } -void cmp_rvecs(FILE *fp, const char *title, int n, const rvec x1[], const rvec x2[], - gmx_bool bRMSD, real ftol, real abstol) +void cmp_rvecs(FILE* fp, const char* title, int n, const rvec x1[], const rvec x2[], gmx_bool bRMSD, real ftol, real abstol) { int i, m; double d, ssd; @@ -125,11 +122,11 @@ void cmp_rvecs(FILE *fp, const char *title, int n, const rvec x1[], const rvec x { for (m = 0; m < DIM; m++) { - d = x1[i][m] - x2[i][m]; - ssd += d*d; + d = x1[i][m] - x2[i][m]; + ssd += d * d; } } - fprintf(fp, "%s RMSD %g\n", title, std::sqrt(ssd/n)); + fprintf(fp, "%s RMSD %g\n", title, std::sqrt(ssd / n)); } else { diff --git a/src/gromacs/math/veccompare.h b/src/gromacs/math/veccompare.h index 4b8ccca575..475fe6a066 100644 --- a/src/gromacs/math/veccompare.h +++ b/src/gromacs/math/veccompare.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,11 +43,10 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -void cmp_rvec(FILE *fp, const char *s, int index, const rvec i1, const rvec i2, real ftol, real abstol); +void cmp_rvec(FILE* fp, const char* s, int index, const rvec i1, const rvec i2, real ftol, real abstol); -void cmp_ivec(FILE *fp, const char *s, int index, const ivec i1, const ivec i2); +void cmp_ivec(FILE* fp, const char* s, int index, const ivec i1, const ivec i2); -void cmp_rvecs(FILE *fp, const char *title, int n, const rvec x1[], const rvec x2[], - gmx_bool bRMSD, real ftol, real abstol); +void cmp_rvecs(FILE* fp, const char* title, int n, const rvec x1[], const rvec x2[], gmx_bool bRMSD, real ftol, real abstol); #endif diff --git a/src/gromacs/math/vecdump.cpp b/src/gromacs/math/vecdump.cpp index b97f64f3c3..95fc3cf096 100644 --- a/src/gromacs/math/vecdump.cpp +++ b/src/gromacs/math/vecdump.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,7 @@ #include "gromacs/utility/strconvert.h" #include "gromacs/utility/txtdump.h" -void pr_ivec(FILE *fp, int indent, const char *title, const int vec[], int n, gmx_bool bShowNumbers) +void pr_ivec(FILE* fp, int indent, const char* title, const int vec[], int n, gmx_bool bShowNumbers) { int i; @@ -60,7 +60,7 @@ void pr_ivec(FILE *fp, int indent, const char *title, const int vec[], int n, gm } } -void pr_ivec_block(FILE *fp, int indent, const char *title, const int vec[], int n, gmx_bool bShowNumbers) +void pr_ivec_block(FILE* fp, int indent, const char* title, const int vec[], int n, gmx_bool bShowNumbers) { int i, j; @@ -70,8 +70,8 @@ void pr_ivec_block(FILE *fp, int indent, const char *title, const int vec[], int i = 0; while (i < n) { - j = i+1; - while (j < n && vec[j] == vec[j-1]+1) + j = i + 1; + while (j < n && vec[j] == vec[j - 1] + 1) { j++; } @@ -81,26 +81,22 @@ void pr_ivec_block(FILE *fp, int indent, const char *title, const int vec[], int while (i < j) { pr_indent(fp, indent); - fprintf(fp, "%s[%d]=%d\n", - title, bShowNumbers ? i : -1, vec[i]); + fprintf(fp, "%s[%d]=%d\n", title, bShowNumbers ? i : -1, vec[i]); i++; } } else { pr_indent(fp, indent); - fprintf(fp, "%s[%d,...,%d] = {%d,...,%d}\n", - title, - bShowNumbers ? i : -1, - bShowNumbers ? j-1 : -1, - vec[i], vec[j-1]); + fprintf(fp, "%s[%d,...,%d] = {%d,...,%d}\n", title, bShowNumbers ? i : -1, + bShowNumbers ? j - 1 : -1, vec[i], vec[j - 1]); i = j; } } } } -void pr_bvec(FILE *fp, int indent, const char *title, const gmx_bool vec[], int n, gmx_bool bShowNumbers) +void pr_bvec(FILE* fp, int indent, const char* title, const gmx_bool vec[], int n, gmx_bool bShowNumbers) { int i; @@ -110,13 +106,12 @@ void pr_bvec(FILE *fp, int indent, const char *title, const gmx_bool vec[], int for (i = 0; i < n; i++) { pr_indent(fp, indent); - fprintf(fp, "%s[%d]=%s\n", title, bShowNumbers ? i : -1, - gmx::boolToString(vec[i])); + fprintf(fp, "%s[%d]=%s\n", title, bShowNumbers ? i : -1, gmx::boolToString(vec[i])); } } } -void pr_ivecs(FILE *fp, int indent, const char *title, const ivec vec[], int n, gmx_bool bShowNumbers) +void pr_ivecs(FILE* fp, int indent, const char* title, const ivec vec[], int n, gmx_bool bShowNumbers) { int i, j; @@ -140,8 +135,8 @@ void pr_ivecs(FILE *fp, int indent, const char *title, const ivec vec[], int n, } } -template -static void printRealVector(FILE *fp, int indent, const char *title, const T vec[], int n, gmx_bool bShowNumbers) +template +static void printRealVector(FILE* fp, int indent, const char* title, const T vec[], int n, gmx_bool bShowNumbers) { if (available(fp, vec, indent, title)) { @@ -154,23 +149,23 @@ static void printRealVector(FILE *fp, int indent, const char *title, const T vec } } -void pr_rvec(FILE *fp, int indent, const char *title, const real vec[], int n, gmx_bool bShowNumbers) +void pr_rvec(FILE* fp, int indent, const char* title, const real vec[], int n, gmx_bool bShowNumbers) { printRealVector(fp, indent, title, vec, n, bShowNumbers); } -void pr_fvec(FILE *fp, int indent, const char *title, const float vec[], int n, gmx_bool bShowNumbers) +void pr_fvec(FILE* fp, int indent, const char* title, const float vec[], int n, gmx_bool bShowNumbers) { printRealVector(fp, indent, title, vec, n, bShowNumbers); } -void pr_dvec(FILE *fp, int indent, const char *title, const double vec[], int n, gmx_bool bShowNumbers) +void pr_dvec(FILE* fp, int indent, const char* title, const double vec[], int n, gmx_bool bShowNumbers) { printRealVector(fp, indent, title, vec, n, bShowNumbers); } -void pr_rvecs_len(FILE *fp, int indent, const char *title, const rvec vec[], int n) +void pr_rvecs_len(FILE* fp, int indent, const char* title, const rvec vec[], int n) { int i, j; @@ -194,11 +189,11 @@ void pr_rvecs_len(FILE *fp, int indent, const char *title, const rvec vec[], int } } -void pr_rvecs(FILE *fp, int indent, const char *title, const rvec vec[], int n) +void pr_rvecs(FILE* fp, int indent, const char* title, const rvec vec[], int n) { - const char *fshort = "%12.5e"; - const char *flong = "%15.8e"; - const char *format; + const char* fshort = "%12.5e"; + const char* flong = "%15.8e"; + const char* format; int i, j; if (getenv("GMX_PRINT_LONGFORMAT") != nullptr) @@ -231,11 +226,11 @@ void pr_rvecs(FILE *fp, int indent, const char *title, const rvec vec[], int n) } -void pr_rvecs_of_dim(FILE *fp, int indent, const char *title, const rvec vec[], int n, int dim) +void pr_rvecs_of_dim(FILE* fp, int indent, const char* title, const rvec vec[], int n, int dim) { - const char *fshort = "%12.5e"; - const char *flong = "%15.8e"; - const char *format; + const char* fshort = "%12.5e"; + const char* flong = "%15.8e"; + const char* format; int i, j; if (getenv("GMX_PRINT_LONGFORMAT") != nullptr) diff --git a/src/gromacs/math/vecdump.h b/src/gromacs/math/vecdump.h index 3c91d3f6a3..d94b0282cc 100644 --- a/src/gromacs/math/vecdump.h +++ b/src/gromacs/math/vecdump.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,15 +42,15 @@ #include "gromacs/math/vectypes.h" #include "gromacs/utility/basedefinitions.h" -void pr_ivec(FILE *fp, int indent, const char *title, const int vec[], int n, gmx_bool bShowNumbers); -void pr_ivec_block(FILE *fp, int indent, const char *title, const int vec[], int n, gmx_bool bShowNumbers); -void pr_ivecs(FILE *fp, int indent, const char *title, const ivec vec[], int n, gmx_bool bShowNumbers); -void pr_bvec(FILE *fp, int indent, const char *title, const gmx_bool vec[], int n, gmx_bool bShowNnumbers); -void pr_rvec(FILE *fp, int indent, const char *title, const real vec[], int n, gmx_bool bShowNumbers); -void pr_rvecs_of_dim(FILE *fp, int indent, const char *title, const rvec vec[], int n, int dim); -void pr_fvec(FILE *fp, int indent, const char *title, const float vec[], int n, gmx_bool bShowNumbers); -void pr_dvec(FILE *fp, int indent, const char *title, const double vec[], int n, gmx_bool bShowNumbers); -void pr_rvecs(FILE *fp, int indent, const char *title, const rvec vec[], int n); -void pr_rvecs_len(FILE *fp, int indent, const char *title, const rvec vec[], int n); +void pr_ivec(FILE* fp, int indent, const char* title, const int vec[], int n, gmx_bool bShowNumbers); +void pr_ivec_block(FILE* fp, int indent, const char* title, const int vec[], int n, gmx_bool bShowNumbers); +void pr_ivecs(FILE* fp, int indent, const char* title, const ivec vec[], int n, gmx_bool bShowNumbers); +void pr_bvec(FILE* fp, int indent, const char* title, const gmx_bool vec[], int n, gmx_bool bShowNnumbers); +void pr_rvec(FILE* fp, int indent, const char* title, const real vec[], int n, gmx_bool bShowNumbers); +void pr_rvecs_of_dim(FILE* fp, int indent, const char* title, const rvec vec[], int n, int dim); +void pr_fvec(FILE* fp, int indent, const char* title, const float vec[], int n, gmx_bool bShowNumbers); +void pr_dvec(FILE* fp, int indent, const char* title, const double vec[], int n, gmx_bool bShowNumbers); +void pr_rvecs(FILE* fp, int indent, const char* title, const rvec vec[], int n); +void pr_rvecs_len(FILE* fp, int indent, const char* title, const rvec vec[], int n); #endif diff --git a/src/gromacs/math/vectypes.h b/src/gromacs/math/vectypes.h index e03d0bf35f..d3835d2049 100644 --- a/src/gromacs/math/vectypes.h +++ b/src/gromacs/math/vectypes.h @@ -45,20 +45,20 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/real.h" -#define XX 0 /* Defines for indexing in */ -#define YY 1 /* vectors */ -#define ZZ 2 -#define DIM 3 /* Dimension of vectors */ +#define XX 0 /* Defines for indexing in */ +#define YY 1 /* vectors */ +#define ZZ 2 +#define DIM 3 /* Dimension of vectors */ -typedef real rvec[DIM]; +typedef real rvec[DIM]; -typedef double dvec[DIM]; +typedef double dvec[DIM]; -typedef real matrix[DIM][DIM]; +typedef real matrix[DIM][DIM]; -typedef real tensor[DIM][DIM]; +typedef real tensor[DIM][DIM]; -typedef int ivec[DIM]; +typedef int ivec[DIM]; namespace gmx { @@ -81,182 +81,161 @@ namespace gmx * * \inpublicapi */ -template +template class BasicVector { - public: - //! Underlying raw C array type (rvec/dvec/ivec). - using RawArray = ValueType[DIM]; - - // The code here assumes ValueType has been deduced as a data type like int - // and not a pointer like int*. If there is a use case for a 3-element array - // of pointers, the implementation will be different enough that the whole - // template class should have a separate partial specialization. We try to avoid - // accidental matching to pointers, but this assertion is a no-cost extra check. - static_assert(!std::is_pointer < std::remove_cv_t < ValueType>>::value, - "BasicVector value type must not be a pointer."); - - //! Constructs default (uninitialized) vector. - BasicVector() {} - //! Constructs a vector from given values. - BasicVector(ValueType x, ValueType y, ValueType z) : x_ {x, y, z} - {} - /*! \brief - * Constructs a vector from given values. - * - * This constructor is not explicit to support implicit conversions - * that allow, e.g., calling `std::vector:``:push_back()` directly - * with an `rvec` parameter. - */ - BasicVector(const RawArray x) : x_ {x[XX], x[YY], x[ZZ]} - {} - //! Default copy constructor. - BasicVector(const BasicVector &src) = default; - //! Default copy assignment operator. - BasicVector &operator=(const BasicVector &v) = default; - //! Default move constructor. - BasicVector(BasicVector &&src) noexcept = default; - //! Default move assignment operator. - BasicVector &operator=(BasicVector &&v) noexcept = default; - //! Indexing operator to make the class work as the raw array. - ValueType &operator[](int i) { return x_[i]; } - //! Indexing operator to make the class work as the raw array. - ValueType operator[](int i) const { return x_[i]; } - //! Allow inplace addition for BasicVector - BasicVector &operator+=(const BasicVector &right) - { - return *this = *this + right; - } - //! Allow inplace subtraction for BasicVector - BasicVector &operator-=(const BasicVector &right) - { - return *this = *this - right; - } - //! Allow vector addition - BasicVector operator+(const BasicVector &right) const - { - return {x_[0] + right[0], x_[1] + right[1], x_[2] + right[2]}; - } - //! Allow vector subtraction - BasicVector operator-(const BasicVector &right) const - { - return {x_[0] - right[0], x_[1] - right[1], x_[2] - right[2]}; - } - //! Allow vector scalar division - BasicVector operator/(const ValueType &right) const - { - GMX_ASSERT(right != 0, "Cannot divide by zero"); - - return *this*(1/right); - } - //! Scale vector by a scalar - BasicVector &operator*=(const ValueType &right) - { - x_[0] *= right; - x_[1] *= right; - x_[2] *= right; - - return *this; - } - //! Divide vector by a scalar - BasicVector &operator/=(const ValueType &right) - { - GMX_ASSERT(right != 0, "Cannot divide by zero"); - - return *this *= 1/right; - } - //! Return dot product - ValueType dot(const BasicVector &right) const - { - return x_[0]*right[0] + x_[1]*right[1] + x_[2]*right[2]; - } - - //! Allow vector vector multiplication (cross product) - BasicVector cross(const BasicVector &right) const - { - return { - x_[YY]*right.x_[ZZ]-x_[ZZ]*right.x_[YY], - x_[ZZ]*right.x_[XX]-x_[XX]*right.x_[ZZ], - x_[XX]*right.x_[YY]-x_[YY]*right.x_[XX] - }; - } - - //! Return normalized to unit vector - BasicVector unitVector() const - { - const ValueType vectorNorm = norm(); - GMX_ASSERT(vectorNorm != 0, "unitVector() should not be called with a zero vector"); - - return *this/vectorNorm; - } - - //! Length^2 of vector - ValueType norm2() const - { - return dot(*this); - } - - //! Norm or length of vector - ValueType norm() const - { - return std::sqrt(norm2()); - } - - //! cast to RVec - BasicVector toRVec() const - { - return {real(x_[0]), real(x_[1]), real(x_[2])}; - } - - //! cast to IVec - BasicVector toIVec() const - { - return { static_cast(x_[0]), static_cast(x_[1]), static_cast(x_[2]) }; - } - - //! cast to DVec - BasicVector toDVec() const - { - return {double(x_[0]), double(x_[1]), double(x_[2])}; - } - - //! Converts to a raw C array where implicit conversion does not work. - RawArray &as_vec() { return x_; } - //! Converts to a raw C array where implicit conversion does not work. - const RawArray &as_vec() const { return x_; } - //! Makes BasicVector usable in contexts where a raw C array is expected. - operator RawArray &() { return x_; } - //! Makes BasicVector usable in contexts where a raw C array is expected. - operator const RawArray &() const { return x_; } - private: - RawArray x_; +public: + //! Underlying raw C array type (rvec/dvec/ivec). + using RawArray = ValueType[DIM]; + + // The code here assumes ValueType has been deduced as a data type like int + // and not a pointer like int*. If there is a use case for a 3-element array + // of pointers, the implementation will be different enough that the whole + // template class should have a separate partial specialization. We try to avoid + // accidental matching to pointers, but this assertion is a no-cost extra check. + static_assert(!std::is_pointer>::value, + "BasicVector value type must not be a pointer."); + + //! Constructs default (uninitialized) vector. + BasicVector() {} + //! Constructs a vector from given values. + BasicVector(ValueType x, ValueType y, ValueType z) : x_{ x, y, z } {} + /*! \brief + * Constructs a vector from given values. + * + * This constructor is not explicit to support implicit conversions + * that allow, e.g., calling `std::vector:``:push_back()` directly + * with an `rvec` parameter. + */ + BasicVector(const RawArray x) : x_{ x[XX], x[YY], x[ZZ] } {} + //! Default copy constructor. + BasicVector(const BasicVector& src) = default; + //! Default copy assignment operator. + BasicVector& operator=(const BasicVector& v) = default; + //! Default move constructor. + BasicVector(BasicVector&& src) noexcept = default; + //! Default move assignment operator. + BasicVector& operator=(BasicVector&& v) noexcept = default; + //! Indexing operator to make the class work as the raw array. + ValueType& operator[](int i) { return x_[i]; } + //! Indexing operator to make the class work as the raw array. + ValueType operator[](int i) const { return x_[i]; } + //! Allow inplace addition for BasicVector + BasicVector& operator+=(const BasicVector& right) + { + return *this = *this + right; + } + //! Allow inplace subtraction for BasicVector + BasicVector& operator-=(const BasicVector& right) + { + return *this = *this - right; + } + //! Allow vector addition + BasicVector operator+(const BasicVector& right) const + { + return { x_[0] + right[0], x_[1] + right[1], x_[2] + right[2] }; + } + //! Allow vector subtraction + BasicVector operator-(const BasicVector& right) const + { + return { x_[0] - right[0], x_[1] - right[1], x_[2] - right[2] }; + } + //! Allow vector scalar division + BasicVector operator/(const ValueType& right) const + { + GMX_ASSERT(right != 0, "Cannot divide by zero"); + + return *this * (1 / right); + } + //! Scale vector by a scalar + BasicVector& operator*=(const ValueType& right) + { + x_[0] *= right; + x_[1] *= right; + x_[2] *= right; + + return *this; + } + //! Divide vector by a scalar + BasicVector& operator/=(const ValueType& right) + { + GMX_ASSERT(right != 0, "Cannot divide by zero"); + + return *this *= 1 / right; + } + //! Return dot product + ValueType dot(const BasicVector& right) const + { + return x_[0] * right[0] + x_[1] * right[1] + x_[2] * right[2]; + } + + //! Allow vector vector multiplication (cross product) + BasicVector cross(const BasicVector& right) const + { + return { x_[YY] * right.x_[ZZ] - x_[ZZ] * right.x_[YY], + x_[ZZ] * right.x_[XX] - x_[XX] * right.x_[ZZ], + x_[XX] * right.x_[YY] - x_[YY] * right.x_[XX] }; + } + + //! Return normalized to unit vector + BasicVector unitVector() const + { + const ValueType vectorNorm = norm(); + GMX_ASSERT(vectorNorm != 0, "unitVector() should not be called with a zero vector"); + + return *this / vectorNorm; + } + + //! Length^2 of vector + ValueType norm2() const { return dot(*this); } + + //! Norm or length of vector + ValueType norm() const { return std::sqrt(norm2()); } + + //! cast to RVec + BasicVector toRVec() const { return { real(x_[0]), real(x_[1]), real(x_[2]) }; } + + //! cast to IVec + BasicVector toIVec() const + { + return { static_cast(x_[0]), static_cast(x_[1]), static_cast(x_[2]) }; + } + + //! cast to DVec + BasicVector toDVec() const { return { double(x_[0]), double(x_[1]), double(x_[2]) }; } + + //! Converts to a raw C array where implicit conversion does not work. + RawArray& as_vec() { return x_; } + //! Converts to a raw C array where implicit conversion does not work. + const RawArray& as_vec() const { return x_; } + //! Makes BasicVector usable in contexts where a raw C array is expected. + operator RawArray&() { return x_; } + //! Makes BasicVector usable in contexts where a raw C array is expected. + operator const RawArray&() const { return x_; } + +private: + RawArray x_; }; //! Allow vector scalar multiplication template -BasicVector operator*(const BasicVector &basicVector, - const ValueType &scalar) +BasicVector operator*(const BasicVector& basicVector, const ValueType& scalar) { - return { - basicVector[0]*scalar, basicVector[1]*scalar, basicVector[2]*scalar - }; + return { basicVector[0] * scalar, basicVector[1] * scalar, basicVector[2] * scalar }; } //! Allow scalar vector multiplication template -BasicVector operator*(const ValueType &scalar, - const BasicVector &basicVector) +BasicVector operator*(const ValueType& scalar, const BasicVector& basicVector) { - return { - scalar*basicVector[0], scalar*basicVector[1], scalar*basicVector[2] - }; + return { scalar * basicVector[0], scalar * basicVector[1], scalar * basicVector[2] }; } /*! \brief * unitv for gmx::BasicVector */ -template static inline -VectorType unitVector(const VectorType &v) +template +static inline VectorType unitVector(const VectorType& v) { return v.unitVector(); } @@ -264,8 +243,8 @@ VectorType unitVector(const VectorType &v) /*! \brief * norm for gmx::BasicVector */ -template static inline -ValueType norm(BasicVector v) +template +static inline ValueType norm(BasicVector v) { return v.norm(); } @@ -273,8 +252,8 @@ ValueType norm(BasicVector v) /*! \brief * Square of the vector norm for gmx::BasicVector */ -template static inline -ValueType norm2(BasicVector v) +template +static inline ValueType norm2(BasicVector v) { return v.norm2(); } @@ -282,8 +261,8 @@ ValueType norm2(BasicVector v) /*! \brief * cross product for gmx::BasicVector */ -template static inline -VectorType cross(const VectorType &a, const VectorType &b) +template +static inline VectorType cross(const VectorType& a, const VectorType& b) { return a.cross(b); } @@ -291,8 +270,8 @@ VectorType cross(const VectorType &a, const VectorType &b) /*! \brief * dot product for gmx::BasicVector */ -template static inline -ValueType dot(BasicVector a, BasicVector b) +template +static inline ValueType dot(BasicVector a, BasicVector b) { return a.dot(b); } @@ -300,48 +279,46 @@ ValueType dot(BasicVector a, BasicVector b) /*! \brief * Multiply two vectors element by element and return the result. */ -template -static inline VectorType scaleByVector(const VectorType &a, const VectorType &b) +template +static inline VectorType scaleByVector(const VectorType& a, const VectorType& b) { - return {a[0] * b[0], a[1] * b[1], a[2] * b[2]}; + return { a[0] * b[0], a[1] * b[1], a[2] * b[2] }; } /*! \brief * Return the element-wise minimum of two vectors. */ -template -static inline VectorType elementWiseMin(const VectorType &a, const VectorType &b) +template +static inline VectorType elementWiseMin(const VectorType& a, const VectorType& b) { - return {std::min(a[0], b[0]), std::min(a[1], b[1]), std::min(a[2], b[2])}; + return { std::min(a[0], b[0]), std::min(a[1], b[1]), std::min(a[2], b[2]) }; } /*! \brief * Return the element-wise maximum of two vectors. */ -template -static inline VectorType elementWiseMax(const VectorType &a, const VectorType &b) +template +static inline VectorType elementWiseMax(const VectorType& a, const VectorType& b) { - return {std::max(a[0], b[0]), std::max(a[1], b[1]), std::max(a[2], b[2])}; + return { std::max(a[0], b[0]), std::max(a[1], b[1]), std::max(a[2], b[2]) }; } /*! \brief * Casts a gmx::BasicVector array into an equivalent raw C array. */ -template static inline -typename BasicVector::RawArray * -as_vec_array(BasicVector *x) +template +static inline typename BasicVector::RawArray* as_vec_array(BasicVector* x) { - return reinterpret_cast::RawArray *>(x); + return reinterpret_cast::RawArray*>(x); } /*! \brief * Casts a gmx::BasicVector array into an equivalent raw C array. */ -template static inline -const typename BasicVector::RawArray * -as_vec_array(const BasicVector *x) +template +static inline const typename BasicVector::RawArray* as_vec_array(const BasicVector* x) { - return reinterpret_cast::RawArray *>(x); + return reinterpret_cast::RawArray*>(x); } //! Shorthand for C++ `rvec`-equivalent type. @@ -351,34 +328,34 @@ typedef BasicVector DVec; //! Shorthand for C++ `ivec`-equivalent type. typedef BasicVector IVec; //! Casts a gmx::RVec array into an `rvec` array. -static inline rvec *as_rvec_array(RVec *x) +static inline rvec* as_rvec_array(RVec* x) { return as_vec_array(x); } //! Casts a gmx::RVec array into an `rvec` array. -static inline const rvec *as_rvec_array(const RVec *x) +static inline const rvec* as_rvec_array(const RVec* x) { return as_vec_array(x); } //! Casts a gmx::DVec array into an `Dvec` array. -static inline dvec *as_dvec_array(DVec *x) +static inline dvec* as_dvec_array(DVec* x) { return as_vec_array(x); } //! Casts a gmx::IVec array into an `ivec` array. -static inline ivec *as_ivec_array(IVec *x) +static inline ivec* as_ivec_array(IVec* x) { return as_vec_array(x); } //! Casts a gmx::DVec array into an `dvec` array. -static inline const dvec *as_dvec_array(const DVec *x) +static inline const dvec* as_dvec_array(const DVec* x) { return as_vec_array(x); } //! Casts a gmx::IVec array into an `ivec` array. -static inline const ivec *as_ivec_array(const IVec *x) +static inline const ivec* as_ivec_array(const IVec* x) { return as_vec_array(x); } @@ -386,6 +363,6 @@ static inline const ivec *as_ivec_array(const IVec *x) //! Shorthand for C++ `ivec`-equivalent type. typedef BasicVector IVec; -} // namespace gmx +} // namespace gmx #endif // include guard diff --git a/src/gromacs/mdlib/boxdeformation.cpp b/src/gromacs/mdlib/boxdeformation.cpp index aa81638708..6adb621b64 100644 --- a/src/gromacs/mdlib/boxdeformation.cpp +++ b/src/gromacs/mdlib/boxdeformation.cpp @@ -63,10 +63,9 @@ namespace gmx { -std::unique_ptr -prepareBoxDeformation(const matrix &initialBox, - t_commrec *cr, - const t_inputrec &inputrec) +std::unique_ptr prepareBoxDeformation(const matrix& initialBox, + t_commrec* cr, + const t_inputrec& inputrec) { if (!inputrecDeform(&inputrec)) { @@ -74,7 +73,8 @@ prepareBoxDeformation(const matrix &initialBox, } if (!EI_DYNAMICS(inputrec.eI)) { - GMX_THROW(NotImplementedError("Box deformation is only supported with dynamical integrators")); + GMX_THROW(NotImplementedError( + "Box deformation is only supported with dynamical integrators")); } matrix box; @@ -89,27 +89,21 @@ prepareBoxDeformation(const matrix &initialBox, gmx_bcast(sizeof(box), box, cr); } - return std::make_unique(inputrec.delta_t, - inputrec.init_step, - inputrec.deform, - box); + return std::make_unique(inputrec.delta_t, inputrec.init_step, inputrec.deform, box); } BoxDeformation::BoxDeformation(double timeStep, int64_t initialStep, - const tensor &deformationTensor, - const matrix &referenceBox) - : timeStep_(timeStep), - initialStep_(initialStep) + const tensor& deformationTensor, + const matrix& referenceBox) : + timeStep_(timeStep), + initialStep_(initialStep) { copy_mat(deformationTensor, deformationTensor_); copy_mat(referenceBox, referenceBox_); } -void -BoxDeformation::apply(ArrayRef x, - matrix box, - int64_t step) +void BoxDeformation::apply(ArrayRef x, matrix box, int64_t step) { matrix updatedBox, invbox, mu; @@ -121,8 +115,7 @@ BoxDeformation::apply(ArrayRef x, { if (deformationTensor_[i][j] != 0) { - updatedBox[i][j] = - referenceBox_[i][j] + elapsedTime * deformationTensor_[i][j]; + updatedBox[i][j] = referenceBox_[i][j] + elapsedTime * deformationTensor_[i][j]; } } } @@ -132,7 +125,7 @@ BoxDeformation::apply(ArrayRef x, */ for (int i = 1; i < DIM; i++) { - for (int j = i-1; j >= 0; j--) + for (int j = i - 1; j >= 0; j--) { while (updatedBox[i][j] - box[i][j] > 0.5 * updatedBox[j][j]) { @@ -149,12 +142,12 @@ BoxDeformation::apply(ArrayRef x, copy_mat(updatedBox, box); mmul_ur0(box, invbox, mu); - for (auto &thisX : x) + for (auto& thisX : x) { - thisX[XX] = mu[XX][XX]*thisX[XX] + mu[YY][XX]*thisX[YY] + mu[ZZ][XX]*thisX[ZZ]; - thisX[YY] = mu[YY][YY]*thisX[YY] + mu[ZZ][YY]*thisX[ZZ]; - thisX[ZZ] = mu[ZZ][ZZ]*thisX[ZZ]; + thisX[XX] = mu[XX][XX] * thisX[XX] + mu[YY][XX] * thisX[YY] + mu[ZZ][XX] * thisX[ZZ]; + thisX[YY] = mu[YY][YY] * thisX[YY] + mu[ZZ][YY] * thisX[ZZ]; + thisX[ZZ] = mu[ZZ][ZZ] * thisX[ZZ]; } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/boxdeformation.h b/src/gromacs/mdlib/boxdeformation.h index fe1351ee9c..9280e8f2a2 100644 --- a/src/gromacs/mdlib/boxdeformation.h +++ b/src/gromacs/mdlib/boxdeformation.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,29 +58,24 @@ namespace gmx class BoxDeformation { - public: - //! Trivial constructor. - BoxDeformation(double timeStep, - int64_t initialStep, - const tensor &deformationTensor, - const matrix &referenceBox); +public: + //! Trivial constructor. + BoxDeformation(double timeStep, int64_t initialStep, const tensor& deformationTensor, const matrix& referenceBox); - //! Deform \c x and \c box at this \c step; - void apply(ArrayRef x, - matrix box, - int64_t step); + //! Deform \c x and \c box at this \c step; + void apply(ArrayRef x, matrix box, int64_t step); - private: - //! The integrator time step. - double timeStep_; - //! The initial step number (from the .tpr, which permits checkpointing to work correctly). - int64_t initialStep_; - //! Non-zero elements provide a scaling factor for deformation in that box dimension. - tensor deformationTensor_; - //! The initial box, ie from the .tpr file. - matrix referenceBox_; +private: + //! The integrator time step. + double timeStep_; + //! The initial step number (from the .tpr, which permits checkpointing to work correctly). + int64_t initialStep_; + //! Non-zero elements provide a scaling factor for deformation in that box dimension. + tensor deformationTensor_; + //! The initial box, ie from the .tpr file. + matrix referenceBox_; - GMX_DISALLOW_COPY_AND_ASSIGN(BoxDeformation); + GMX_DISALLOW_COPY_AND_ASSIGN(BoxDeformation); }; /*! \brief Factory function for box deformation module. @@ -93,11 +88,10 @@ class BoxDeformation * \throws NotImplementedError if the \c inputrec specifies an * unsupported combination. */ -std::unique_ptr -prepareBoxDeformation(const matrix &initialBox, - t_commrec *cr, - const t_inputrec &inputrec); +std::unique_ptr prepareBoxDeformation(const matrix& initialBox, + t_commrec* cr, + const t_inputrec& inputrec); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/broadcaststructs.cpp b/src/gromacs/mdlib/broadcaststructs.cpp index a62979aa79..751bddf33a 100644 --- a/src/gromacs/mdlib/broadcaststructs.cpp +++ b/src/gromacs/mdlib/broadcaststructs.cpp @@ -44,16 +44,18 @@ #include "gromacs/mdtypes/commrec.h" #include "gromacs/mdtypes/state.h" -template -static void bcastPaddedRVecVector(const t_commrec *cr, gmx::PaddedVector *v, int numAtoms) +template +static void bcastPaddedRVecVector(const t_commrec* cr, gmx::PaddedVector* v, int numAtoms) { v->resizeWithPadding(numAtoms); nblock_bc(cr, makeArrayRef(*v)); } -void broadcastStateWithoutDynamics(const t_commrec *cr, t_state *state) +void broadcastStateWithoutDynamics(const t_commrec* cr, t_state* state) { - GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr), "broadcastStateWithoutDynamics should only be used for special cases without domain decomposition"); + GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr), + "broadcastStateWithoutDynamics should only be used for special cases " + "without domain decomposition"); if (!PAR(cr)) { @@ -72,27 +74,21 @@ void broadcastStateWithoutDynamics(const t_commrec *cr, t_state *state) { switch (i) { - case estLAMBDA: - nblock_bc(cr, efptNR, state->lambda.data()); - break; - case estFEPSTATE: - block_bc(cr, state->fep_state); - break; - case estBOX: - block_bc(cr, state->box); - break; - case estX: - bcastPaddedRVecVector(cr, &state->x, state->natoms); - break; + case estLAMBDA: nblock_bc(cr, efptNR, state->lambda.data()); break; + case estFEPSTATE: block_bc(cr, state->fep_state); break; + case estBOX: block_bc(cr, state->box); break; + case estX: bcastPaddedRVecVector(cr, &state->x, state->natoms); break; default: - GMX_RELEASE_ASSERT(false, "The state has a dynamic entry, while no dynamic entries should be present"); + GMX_RELEASE_ASSERT(false, + "The state has a dynamic entry, while no dynamic entries " + "should be present"); break; } } } } -static void bc_tpxheader(const t_commrec *cr, TpxFileHeader *tpx) +static void bc_tpxheader(const t_commrec* cr, TpxFileHeader* tpx) { block_bc(cr, tpx->bIr); block_bc(cr, tpx->bBox); @@ -110,7 +106,7 @@ static void bc_tpxheader(const t_commrec *cr, TpxFileHeader *tpx) block_bc(cr, tpx->isDouble); } -static void bc_tprCharBuffer(const t_commrec *cr, std::vector *charBuffer) +static void bc_tprCharBuffer(const t_commrec* cr, std::vector* charBuffer) { int elements = charBuffer->size(); block_bc(cr, elements); @@ -118,17 +114,12 @@ static void bc_tprCharBuffer(const t_commrec *cr, std::vector *charBuffer) nblock_abc(cr, elements, charBuffer); } -void init_parallel(t_commrec *cr, - t_inputrec *inputrec, - gmx_mtop_t *mtop, - PartialDeserializedTprFile *partialDeserializedTpr) +void init_parallel(t_commrec* cr, t_inputrec* inputrec, gmx_mtop_t* mtop, PartialDeserializedTprFile* partialDeserializedTpr) { bc_tpxheader(cr, &partialDeserializedTpr->header); bc_tprCharBuffer(cr, &partialDeserializedTpr->body); if (!MASTER(cr)) { - completeTprDeserialization(partialDeserializedTpr, - inputrec, - mtop); + completeTprDeserialization(partialDeserializedTpr, inputrec, mtop); } } diff --git a/src/gromacs/mdlib/broadcaststructs.h b/src/gromacs/mdlib/broadcaststructs.h index 3f8003d77b..877b39d31a 100644 --- a/src/gromacs/mdlib/broadcaststructs.h +++ b/src/gromacs/mdlib/broadcaststructs.h @@ -59,26 +59,26 @@ struct PartialDeserializedTprFile; class t_state; //! Convenience wrapper for gmx_bcast of a single value. -template -void block_bc(const t_commrec *cr, T &data) +template +void block_bc(const t_commrec* cr, T& data) { - gmx_bcast(sizeof(T), static_cast(&data), cr); + gmx_bcast(sizeof(T), static_cast(&data), cr); } //! Convenience wrapper for gmx_bcast of a C-style array. -template -void nblock_bc(const t_commrec *cr, int numElements, T *data) +template +void nblock_bc(const t_commrec* cr, int numElements, T* data) { - gmx_bcast(numElements * sizeof(T), static_cast(data), cr); + gmx_bcast(numElements * sizeof(T), static_cast(data), cr); } //! Convenience wrapper for gmx_bcast of an ArrayRef -template -void nblock_bc(const t_commrec *cr, gmx::ArrayRef data) +template +void nblock_bc(const t_commrec* cr, gmx::ArrayRef data) { - gmx_bcast(data.size() * sizeof(T), static_cast(data.data()), cr); + gmx_bcast(data.size() * sizeof(T), static_cast(data.data()), cr); } //! Convenience wrapper for allocation with snew of vectors that need allocation on non-master ranks. -template -void snew_bc(const t_commrec *cr, T * &data, int numElements) +template +void snew_bc(const t_commrec* cr, T*& data, int numElements) { if (!MASTER(cr)) { @@ -86,33 +86,33 @@ void snew_bc(const t_commrec *cr, T * &data, int numElements) } } //! Convenience wrapper for gmx_bcast of a C-style array which needs allocation on non-master ranks. -template -void nblock_abc(const t_commrec *cr, int numElements, T **v) +template +void nblock_abc(const t_commrec* cr, int numElements, T** v) { snew_bc(cr, v, numElements); nblock_bc(cr, numElements, *v); } //! Convenience wrapper for gmx_bcast of a std::vector which needs resizing on non-master ranks. -template -void nblock_abc(const t_commrec *cr, int numElements, std::vector *v) +template +void nblock_abc(const t_commrec* cr, int numElements, std::vector* v) { if (!MASTER(cr)) { v->resize(numElements); } - gmx_bcast(numElements*sizeof(T), v->data(), cr); + gmx_bcast(numElements * sizeof(T), v->data(), cr); } //! \brief Broadcasts the, non-dynamic, state from the master to all ranks in cr->mpi_comm_mygroup // // This is intended to be used with MPI parallelization without // domain decompostion (currently with NM and TPI). -void broadcastStateWithoutDynamics(const t_commrec *cr, t_state *state); +void broadcastStateWithoutDynamics(const t_commrec* cr, t_state* state); //! \brief Broadcast inputrec and mtop and allocate node-specific settings -void init_parallel(t_commrec *cr, - t_inputrec *inputrec, - gmx_mtop_t *mtop, - PartialDeserializedTprFile *partialDeserializedTpr); +void init_parallel(t_commrec* cr, + t_inputrec* inputrec, + gmx_mtop_t* mtop, + PartialDeserializedTprFile* partialDeserializedTpr); #endif diff --git a/src/gromacs/mdlib/calc_verletbuf.cpp b/src/gromacs/mdlib/calc_verletbuf.cpp index fc033fee5d..2a24be9977 100644 --- a/src/gromacs/mdlib/calc_verletbuf.cpp +++ b/src/gromacs/mdlib/calc_verletbuf.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2012-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -102,9 +103,9 @@ struct VerletbufAtomtype // Struct for derivatives of a non-bonded interaction potential struct pot_derivatives_t { - real md1; // -V' at the cutoff - real d2; // V'' at the cutoff - real md3; // -V''' at the cutoff + real md1; // -V' at the cutoff + real d2; // V'' at the cutoff + real md3; // -V''' at the cutoff }; VerletbufListSetup verletbufGetListSetup(Nbnxm::KernelType nbnxnKernelType) @@ -157,21 +158,15 @@ VerletbufListSetup verletbufGetSafeListSetup(ListSetupType listType) } // Returns whether prop1 and prop2 are identical -static bool -atom_nonbonded_kinetic_prop_equal(const atom_nonbonded_kinetic_prop_t &prop1, - const atom_nonbonded_kinetic_prop_t &prop2) +static bool atom_nonbonded_kinetic_prop_equal(const atom_nonbonded_kinetic_prop_t& prop1, + const atom_nonbonded_kinetic_prop_t& prop2) { - return (prop1.mass == prop2.mass && - prop1.type == prop2.type && - prop1.q == prop2.q && - prop1.bConstr == prop2.bConstr && - prop1.con_mass == prop2.con_mass && - prop1.con_len == prop2.con_len); + return (prop1.mass == prop2.mass && prop1.type == prop2.type && prop1.q == prop2.q + && prop1.bConstr == prop2.bConstr && prop1.con_mass == prop2.con_mass + && prop1.con_len == prop2.con_len); } -static void addAtomtype(std::vector *att, - const atom_nonbonded_kinetic_prop_t &prop, - int nmol) +static void addAtomtype(std::vector* att, const atom_nonbonded_kinetic_prop_t& prop, int nmol) { if (prop.mass == 0) { @@ -180,8 +175,7 @@ static void addAtomtype(std::vector *att, } size_t i = 0; - while (i < att->size() && - !atom_nonbonded_kinetic_prop_equal(prop, (*att)[i].prop)) + while (i < att->size() && !atom_nonbonded_kinetic_prop_equal(prop, (*att)[i].prop)) { i++; } @@ -197,9 +191,7 @@ static void addAtomtype(std::vector *att, } /* Returns the mass of atom atomIndex or 1 when setMassesToOne=true */ -static real getMass(const t_atoms &atoms, - int atomIndex, - bool setMassesToOne) +static real getMass(const t_atoms& atoms, int atomIndex, bool setMassesToOne) { if (!setMassesToOne) { @@ -212,19 +204,19 @@ static real getMass(const t_atoms &atoms, } // Set the masses of a vsites in vsite_m and the non-linear vsite count in n_nonlin_vsite -static void get_vsite_masses(const gmx_moltype_t &moltype, - const gmx_ffparams_t &ffparams, +static void get_vsite_masses(const gmx_moltype_t& moltype, + const gmx_ffparams_t& ffparams, bool setMassesToOne, gmx::ArrayRef vsite_m) { int numNonlinearVsites = 0; /* Check for virtual sites, determine mass from constructing atoms */ - for (const auto &ilist : extractILists(moltype.ilist, IF_VSITE)) + for (const auto& ilist : extractILists(moltype.ilist, IF_VSITE)) { for (size_t i = 0; i < ilist.iatoms.size(); i += ilistStride(ilist)) { - const t_iparams &ip = ffparams.iparams[ilist.iatoms[i]]; + const t_iparams& ip = ffparams.iparams[ilist.iatoms[i]]; const int a1 = ilist.iatoms[i + 1]; if (ilist.functionType != F_VSITEN) @@ -237,7 +229,7 @@ static void get_vsite_masses(const gmx_moltype_t &moltype, for (int j = 1; j < maxj; j++) { const int aj = ilist.iatoms[i + 1 + j]; - cam[j] = getMass(moltype.atoms, aj, setMassesToOne); + cam[j] = getMass(moltype.atoms, aj, setMassesToOne); if (cam[j] == 0) { cam[j] = vsite_m[aj]; @@ -253,11 +245,16 @@ static void get_vsite_masses(const gmx_moltype_t &moltype, { case F_VSITE2: /* Exact */ - vsite_m[a1] = (cam[1]*cam[2])/(cam[2]*gmx::square(1 - ip.vsite.a) + cam[1]*gmx::square(ip.vsite.a)); + vsite_m[a1] = (cam[1] * cam[2]) + / (cam[2] * gmx::square(1 - ip.vsite.a) + + cam[1] * gmx::square(ip.vsite.a)); break; case F_VSITE3: /* Exact */ - vsite_m[a1] = (cam[1]*cam[2]*cam[3])/(cam[2]*cam[3]*gmx::square(1 - ip.vsite.a - ip.vsite.b) + cam[1]*cam[3]*gmx::square(ip.vsite.a) + cam[1]*cam[2]*gmx::square(ip.vsite.b)); + vsite_m[a1] = (cam[1] * cam[2] * cam[3]) + / (cam[2] * cam[3] * gmx::square(1 - ip.vsite.a - ip.vsite.b) + + cam[1] * cam[3] * gmx::square(ip.vsite.a) + + cam[1] * cam[2] * gmx::square(ip.vsite.b)); break; case F_VSITEN: GMX_RELEASE_ASSERT(false, "VsiteN should not end up in this code path"); @@ -289,7 +286,7 @@ static void get_vsite_masses(const gmx_moltype_t &moltype, /* Exact */ real inv_mass = 0; int numConstructingAtoms = ffparams.iparams[ilist.iatoms[i]].vsiten.n; - for (int j = 0; j < 3*numConstructingAtoms; j += 3) + for (int j = 0; j < 3 * numConstructingAtoms; j += 3) { int aj = ilist.iatoms[i + j + 2]; real coeff = ffparams.iparams[ilist.iatoms[i + j]].vsiten.a; @@ -306,40 +303,37 @@ static void get_vsite_masses(const gmx_moltype_t &moltype, { gmx_incons("The mass of a vsiten constructing atom is <= 0"); } - inv_mass += coeff*coeff/m_aj; + inv_mass += coeff * coeff / m_aj; } - vsite_m[a1] = 1/inv_mass; + vsite_m[a1] = 1 / inv_mass; /* Correct the loop increment of i for processes more than 1 entry */ - i += (numConstructingAtoms - 1)*ilistStride(ilist); + i += (numConstructingAtoms - 1) * ilistStride(ilist); } if (gmx_debug_at) { - fprintf(debug, "atom %4d %-20s mass %6.3f\n", - a1, interaction_function[ilist.functionType].longname, vsite_m[a1]); + fprintf(debug, "atom %4d %-20s mass %6.3f\n", a1, + interaction_function[ilist.functionType].longname, vsite_m[a1]); } } } if (debug && numNonlinearVsites > 0) { - fprintf(debug, "The molecule type has %d non-linear virtual constructions\n", - numNonlinearVsites); + fprintf(debug, "The molecule type has %d non-linear virtual constructions\n", numNonlinearVsites); } } -static std::vector -getVerletBufferAtomtypes(const gmx_mtop_t &mtop, - const bool setMassesToOne) +static std::vector getVerletBufferAtomtypes(const gmx_mtop_t& mtop, const bool setMassesToOne) { std::vector att; int ft, i, a1, a2, a3, a; - const t_iparams *ip; + const t_iparams* ip; - for (const gmx_molblock_t &molblock : mtop.molblock) + for (const gmx_molblock_t& molblock : mtop.molblock) { int nmol = molblock.nmol; - const gmx_moltype_t &moltype = mtop.moltype[molblock.type]; - const t_atoms *atoms = &moltype.atoms; + const gmx_moltype_t& moltype = mtop.moltype[molblock.type]; + const t_atoms* atoms = &moltype.atoms; /* Check for constraints, as they affect the kinetic energy. * For virtual sites we need the masses and geometry of @@ -351,13 +345,13 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, for (ft = F_CONSTR; ft <= F_CONSTRNC; ft++) { - const InteractionList &il = moltype.ilist[ft]; + const InteractionList& il = moltype.ilist[ft]; - for (i = 0; i < il.size(); i += 1+NRAL(ft)) + for (i = 0; i < il.size(); i += 1 + NRAL(ft)) { ip = &mtop.ffparams.iparams[il.iatoms[i]]; - a1 = il.iatoms[i+1]; - a2 = il.iatoms[i+2]; + a1 = il.iatoms[i + 1]; + a2 = il.iatoms[i + 2]; real mass1 = getMass(*atoms, a1, setMassesToOne); real mass2 = getMass(*atoms, a2, setMassesToOne); if (mass2 > prop[a1].con_mass) @@ -373,14 +367,14 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, } } - const InteractionList &il = moltype.ilist[F_SETTLE]; + const InteractionList& il = moltype.ilist[F_SETTLE]; - for (i = 0; i < il.size(); i += 1+NRAL(F_SETTLE)) + for (i = 0; i < il.size(); i += 1 + NRAL(F_SETTLE)) { - ip = &mtop.ffparams.iparams[il.iatoms[i]]; - a1 = il.iatoms[i+1]; - a2 = il.iatoms[i+2]; - a3 = il.iatoms[i+3]; + ip = &mtop.ffparams.iparams[il.iatoms[i]]; + a1 = il.iatoms[i + 1]; + a2 = il.iatoms[i + 2]; + a3 = il.iatoms[i + 3]; /* Usually the mass of a1 (usually oxygen) is larger than a2/a3. * If this is not the case, we overestimate the displacement, * which leads to a larger buffer (ok since this is an exotic case). @@ -396,10 +390,7 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, } std::vector vsite_m(atoms->nr); - get_vsite_masses(moltype, - mtop.ffparams, - setMassesToOne, - vsite_m); + get_vsite_masses(moltype, mtop.ffparams, setMassesToOne, vsite_m); for (a = 0; a < atoms->nr; a++) { @@ -411,8 +402,8 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, { prop[a].mass = getMass(*atoms, a, setMassesToOne); } - prop[a].type = atoms->atom[a].type; - prop[a].q = atoms->atom[a].q; + prop[a].type = atoms->atom[a].type; + prop[a].q = atoms->atom[a].q; /* We consider an atom constrained, #DOF=2, when it is * connected with constraints to (at least one) atom with * a mass of more than 0.4x its own mass. This is not a critical @@ -420,7 +411,7 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, * and constrained displacement will not differ much (and both * overestimate the displacement). */ - prop[a].bConstr = (prop[a].con_mass > 0.4*prop[a].mass); + prop[a].bConstr = (prop[a].con_mass > 0.4 * prop[a].mass); addAtomtype(&att, prop[a], nmol); } @@ -432,8 +423,8 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, { fprintf(debug, "type %zu: m %5.2f t %d q %6.3f con %s con_m %5.3f con_l %5.3f n %d\n", a, att[a].prop.mass, att[a].prop.type, att[a].prop.q, - gmx::boolToString(att[a].prop.bConstr), att[a].prop.con_mass, att[a].prop.con_len, - att[a].n); + gmx::boolToString(att[a].prop.bConstr), att[a].prop.con_mass, + att[a].prop.con_len, att[a].n); } } @@ -451,24 +442,21 @@ getVerletBufferAtomtypes(const gmx_mtop_t &mtop, * into account. If an atom has multiple constraints, this will result in * an overestimate of the displacement, which gives a larger drift and buffer. */ -void constrained_atom_sigma2(real kT_fac, - const atom_nonbonded_kinetic_prop_t *prop, - real *sigma2_2d, - real *sigma2_3d) +void constrained_atom_sigma2(real kT_fac, const atom_nonbonded_kinetic_prop_t* prop, real* sigma2_2d, real* sigma2_3d) { /* Here we decompose the motion of a constrained atom into two * components: rotation around the COM and translation of the COM. */ /* Determine the variance of the arc length for the two rotational DOFs */ - real massFraction = prop->con_mass/(prop->mass + prop->con_mass); - real sigma2_rot = kT_fac*massFraction/prop->mass; + real massFraction = prop->con_mass / (prop->mass + prop->con_mass); + real sigma2_rot = kT_fac * massFraction / prop->mass; /* The distance from the atom to the COM, i.e. the rotational arm */ - real comDistance = prop->con_len*massFraction; + real comDistance = prop->con_len * massFraction; /* The variance relative to the arm */ - real sigma2_rel = sigma2_rot/gmx::square(comDistance); + real sigma2_rel = sigma2_rot / gmx::square(comDistance); /* For sigma2_rel << 1 we don't notice the rotational effect and * we have a normal, Gaussian displacement distribution. @@ -493,24 +481,21 @@ void constrained_atom_sigma2(real kT_fac, * whereas the actual distribution can not reach values larger than 2. */ /* Coeffients obtained from a Taylor expansion */ - const real a = 1.0/3.0; - const real b = 2.0/45.0; + const real a = 1.0 / 3.0; + const real b = 2.0 / 45.0; /* Our approximation is constant after sigma2_rel = 1/sqrt(b) */ - sigma2_rel = std::min(sigma2_rel, 1/std::sqrt(b)); + sigma2_rel = std::min(sigma2_rel, 1 / std::sqrt(b)); /* Compute the approximate sigma^2 for 2D motion due to the rotation */ - *sigma2_2d = gmx::square(comDistance)* - sigma2_rel/(1 + a*sigma2_rel + b*gmx::square(sigma2_rel)); + *sigma2_2d = + gmx::square(comDistance) * sigma2_rel / (1 + a * sigma2_rel + b * gmx::square(sigma2_rel)); /* The constrained atom also moves (in 3D) with the COM of both atoms */ - *sigma2_3d = kT_fac/(prop->mass + prop->con_mass); + *sigma2_3d = kT_fac / (prop->mass + prop->con_mass); } -static void get_atom_sigma2(real kT_fac, - const atom_nonbonded_kinetic_prop_t *prop, - real *sigma2_2d, - real *sigma2_3d) +static void get_atom_sigma2(real kT_fac, const atom_nonbonded_kinetic_prop_t* prop, real* sigma2_2d, real* sigma2_3d) { if (prop->bConstr) { @@ -521,11 +506,11 @@ static void get_atom_sigma2(real kT_fac, { /* Unconstrained atom: trivial */ *sigma2_2d = 0; - *sigma2_3d = kT_fac/prop->mass; + *sigma2_3d = kT_fac / prop->mass; } } -static void approx_2dof(real s2, real x, real *shift, real *scale) +static void approx_2dof(real s2, real x, real* shift, real* scale) { /* A particle with 1 DOF constrained has 2 DOFs instead of 3. * This code is also used for particles with multiple constraints, @@ -537,32 +522,34 @@ static void approx_2dof(real s2, real x, real *shift, real *scale) */ real ex, er; - ex = std::exp(-x*x/(2*s2)); - er = std::erfc(x/std::sqrt(2*s2)); + ex = std::exp(-x * x / (2 * s2)); + er = std::erfc(x / std::sqrt(2 * s2)); - *shift = -x + std::sqrt(2*s2/M_PI)*ex/er; - *scale = 0.5*M_PI*std::exp(ex*ex/(M_PI*er*er))*er; + *shift = -x + std::sqrt(2 * s2 / M_PI) * ex / er; + *scale = 0.5 * M_PI * std::exp(ex * ex / (M_PI * er * er)) * er; } // Returns an (over)estimate of the energy drift for a single atom pair, // given the kinetic properties, displacement variances and list buffer. -static real energyDriftAtomPair(bool isConstrained_i, - bool isConstrained_j, - real s2, real s2i_2d, real s2j_2d, - real r_buffer, - const pot_derivatives_t *der) +static real energyDriftAtomPair(bool isConstrained_i, + bool isConstrained_j, + real s2, + real s2i_2d, + real s2j_2d, + real r_buffer, + const pot_derivatives_t* der) { // For relatively small arguments erfc() is so small that if will be 0.0 // when stored in a float. We set an argument limit of 8 (Erfc(8)=1e-29), // such that we can divide by erfc and have some space left for arithmetic. const real erfc_arg_max = 8.0; - real rsh = r_buffer; - real sc_fac = 1.0; + real rsh = r_buffer; + real sc_fac = 1.0; - real c_exp, c_erfc; + real c_exp, c_erfc; - if (rsh*rsh > 2*s2*erfc_arg_max*erfc_arg_max) + if (rsh * rsh > 2 * s2 * erfc_arg_max * erfc_arg_max) { // Below we calculate c_erfc = 0.5*erfc(rsh/sqrt(2*s2)) // When rsh/sqrt(2*s2) increases, this erfc will be the first @@ -585,16 +572,16 @@ static real energyDriftAtomPair(bool isConstrained_i, { real sh, sc; - approx_2dof(s2i_2d, r_buffer*s2i_2d/s2, &sh, &sc); - rsh += sh; + approx_2dof(s2i_2d, r_buffer * s2i_2d / s2, &sh, &sc); + rsh += sh; sc_fac *= sc; } if (isConstrained_j) { real sh, sc; - approx_2dof(s2j_2d, r_buffer*s2j_2d/s2, &sh, &sc); - rsh += sh; + approx_2dof(s2j_2d, r_buffer * s2j_2d / s2, &sh, &sc); + rsh += sh; sc_fac *= sc; } @@ -609,31 +596,31 @@ static real energyDriftAtomPair(bool isConstrained_i, * Note that pot has unit energy*length, as the linear * atom density still needs to be put in. */ - c_exp = std::exp(-rsh*rsh/(2*s2))/std::sqrt(2*M_PI); - c_erfc = 0.5*std::erfc(rsh/(std::sqrt(2*s2))); + c_exp = std::exp(-rsh * rsh / (2 * s2)) / std::sqrt(2 * M_PI); + c_erfc = 0.5 * std::erfc(rsh / (std::sqrt(2 * s2))); } real s = std::sqrt(s2); - real rsh2 = rsh*rsh; + real rsh2 = rsh * rsh; - real pot1 = sc_fac* - der->md1/2*((rsh2 + s2)*c_erfc - rsh*s*c_exp); - real pot2 = sc_fac* - der->d2/6*(s*(rsh2 + 2*s2)*c_exp - rsh*(rsh2 + 3*s2)*c_erfc); - real pot3 = sc_fac* - der->md3/24*((rsh2*rsh2 + 6*rsh2*s2 + 3*s2*s2)*c_erfc - rsh*s*(rsh2 + 5*s2)*c_exp); + real pot1 = sc_fac * der->md1 / 2 * ((rsh2 + s2) * c_erfc - rsh * s * c_exp); + real pot2 = sc_fac * der->d2 / 6 * (s * (rsh2 + 2 * s2) * c_exp - rsh * (rsh2 + 3 * s2) * c_erfc); + real pot3 = sc_fac * der->md3 / 24 + * ((rsh2 * rsh2 + 6 * rsh2 * s2 + 3 * s2 * s2) * c_erfc - rsh * s * (rsh2 + 5 * s2) * c_exp); return pot1 + pot2 + pot3; } // Computes and returns an estimate of the energy drift for the whole system static real energyDrift(gmx::ArrayRef att, - const gmx_ffparams_t *ffp, - real kT_fac, - const pot_derivatives_t *ljDisp, - const pot_derivatives_t *ljRep, - const pot_derivatives_t *elec, - real rlj, real rcoulomb, - real rlist, real boxvol) + const gmx_ffparams_t* ffp, + real kT_fac, + const pot_derivatives_t* ljDisp, + const pot_derivatives_t* ljRep, + const pot_derivatives_t* elec, + real rlj, + real rcoulomb, + real rlist, + real boxvol) { double drift_tot = 0; @@ -648,14 +635,14 @@ static real energyDrift(gmx::ArrayRef att, for (gmx::index i = 0; i < att.ssize(); i++) { // Get the thermal displacement variance for the i-atom type - const atom_nonbonded_kinetic_prop_t *prop_i = &att[i].prop; + const atom_nonbonded_kinetic_prop_t* prop_i = &att[i].prop; real s2i_2d, s2i_3d; get_atom_sigma2(kT_fac, prop_i, &s2i_2d, &s2i_3d); for (gmx::index j = i; j < att.ssize(); j++) { // Get the thermal displacement variance for the j-atom type - const atom_nonbonded_kinetic_prop_t *prop_j = &att[j].prop; + const atom_nonbonded_kinetic_prop_t* prop_j = &att[j].prop; real s2j_2d, s2j_3d; get_atom_sigma2(kT_fac, prop_j, &s2j_2d, &s2j_3d); @@ -663,28 +650,24 @@ static real energyDrift(gmx::ArrayRef att, real s2 = s2i_2d + s2i_3d + s2j_2d + s2j_3d; // Set -V', V'' and -V''' at the cut-off for LJ */ - real c6 = ffp->iparams[prop_i->type*ffp->atnr + prop_j->type].lj.c6; - real c12 = ffp->iparams[prop_i->type*ffp->atnr + prop_j->type].lj.c12; + real c6 = ffp->iparams[prop_i->type * ffp->atnr + prop_j->type].lj.c6; + real c12 = ffp->iparams[prop_i->type * ffp->atnr + prop_j->type].lj.c12; pot_derivatives_t lj; - lj.md1 = c6*ljDisp->md1 + c12*ljRep->md1; - lj.d2 = c6*ljDisp->d2 + c12*ljRep->d2; - lj.md3 = c6*ljDisp->md3 + c12*ljRep->md3; + lj.md1 = c6 * ljDisp->md1 + c12 * ljRep->md1; + lj.d2 = c6 * ljDisp->d2 + c12 * ljRep->d2; + lj.md3 = c6 * ljDisp->md3 + c12 * ljRep->md3; - real pot_lj = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, - s2, s2i_2d, s2j_2d, - rlist - rlj, - &lj); + real pot_lj = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d, + rlist - rlj, &lj); // Set -V' and V'' at the cut-off for Coulomb pot_derivatives_t elec_qq; - elec_qq.md1 = elec->md1*prop_i->q*prop_j->q; - elec_qq.d2 = elec->d2 *prop_i->q*prop_j->q; + elec_qq.md1 = elec->md1 * prop_i->q * prop_j->q; + elec_qq.d2 = elec->d2 * prop_i->q * prop_j->q; elec_qq.md3 = 0; - real pot_q = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, - s2, s2i_2d, s2j_2d, - rlist - rcoulomb, - &elec_qq); + real pot_q = energyDriftAtomPair(prop_i->bConstr, prop_j->bConstr, s2, s2i_2d, s2j_2d, + rlist - rcoulomb, &elec_qq); // Note that attractive and repulsive potentials for individual // pairs can partially cancel. @@ -693,16 +676,16 @@ static real energyDrift(gmx::ArrayRef att, /* Multiply by the number of atom pairs */ if (j == i) { - pot *= static_cast(att[i].n)*(att[i].n - 1)/2; + pot *= static_cast(att[i].n) * (att[i].n - 1) / 2; } else { - pot *= static_cast(att[i].n)*att[j].n; + pot *= static_cast(att[i].n) * att[j].n; } /* We need the line density to get the energy drift of the system. * The effective average r^2 is close to (rlist+sigma)^2. */ - pot *= 4*M_PI*gmx::square(rlist + std::sqrt(s2))/boxvol; + pot *= 4 * M_PI * gmx::square(rlist + std::sqrt(s2)) / boxvol; /* Add the unsigned drift to avoid cancellation of errors */ drift_tot += std::abs(pot); @@ -718,14 +701,14 @@ static real surface_frac(int cluster_size, real particle_distance, real rlist) { real d, area_rel; - if (rlist < 0.5*particle_distance) + if (rlist < 0.5 * particle_distance) { /* We have non overlapping spheres */ return 1.0; } /* Half the inter-particle distance relative to rlist */ - d = 0.5*particle_distance/rlist; + d = 0.5 * particle_distance / rlist; /* Determine the area of the surface at distance rlist to the closest * particle, relative to surface of a sphere of radius rlist. @@ -751,17 +734,17 @@ static real surface_frac(int cluster_size, real particle_distance, real rlist) * The surface around a tetrahedron is too complex for a full * analytical solution, so we use a Taylor expansion. */ - area_rel = (1.0 + 1/M_PI*(6*std::acos(1/std::sqrt(3))*d + - std::sqrt(3)*d*d*(1.0 + - 5.0/18.0*d*d + - 7.0/45.0*d*d*d*d + - 83.0/756.0*d*d*d*d*d*d))); + area_rel = (1.0 + + 1 / M_PI + * (6 * std::acos(1 / std::sqrt(3)) * d + + std::sqrt(3) * d * d + * (1.0 + 5.0 / 18.0 * d * d + 7.0 / 45.0 * d * d * d * d + + 83.0 / 756.0 * d * d * d * d * d * d))); break; - default: - gmx_incons("surface_frac called with unsupported cluster_size"); + default: gmx_incons("surface_frac called with unsupported cluster_size"); } - return area_rel/cluster_size; + return area_rel / cluster_size; } /* Returns the negative of the third derivative of a potential r^-p @@ -775,11 +758,11 @@ static real md3_force_switch(real p, real rswitch, real rc) real a, b; real md3_pot, md3_sw; - a = -((p + 4)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*gmx::square(rc-rswitch)); - b = ((p + 3)*rc - (p + 1)*rswitch)/(pow(rc, p+2)*gmx::power3(rc-rswitch)); + a = -((p + 4) * rc - (p + 1) * rswitch) / (pow(rc, p + 2) * gmx::square(rc - rswitch)); + b = ((p + 3) * rc - (p + 1) * rswitch) / (pow(rc, p + 2) * gmx::power3(rc - rswitch)); - md3_pot = (p + 2)*(p + 1)*p*pow(rc, p+3); - md3_sw = 2*a + 6*b*(rc - rswitch); + md3_pot = (p + 2) * (p + 1) * p * pow(rc, p + 3); + md3_sw = 2 * a + 6 * b * (rc - rswitch); return md3_pot + md3_sw; } @@ -789,9 +772,7 @@ static real md3_force_switch(real p, real rswitch, real rc) * Note: When not using BD with a non-mass dependendent friction coefficient, * the return value still needs to be divided by the particle mass. */ -static real displacementVariance(const t_inputrec &ir, - real temperature, - real timePeriod) +static real displacementVariance(const t_inputrec& ir, real temperature, real timePeriod) { real kT_fac; @@ -802,7 +783,7 @@ static real displacementVariance(const t_inputrec &ir, * should be negligible (unless nstlist is extremely large, which * you wouldn't do anyhow). */ - kT_fac = 2*BOLTZ*temperature*timePeriod; + kT_fac = 2 * BOLTZ * temperature * timePeriod; if (ir.bd_fric > 0) { /* This is directly sigma^2 of the displacement */ @@ -823,7 +804,7 @@ static real displacementVariance(const t_inputrec &ir, } else { - kT_fac = BOLTZ*temperature*gmx::square(timePeriod); + kT_fac = BOLTZ * temperature * gmx::square(timePeriod); } return kT_fac; @@ -832,43 +813,41 @@ static real displacementVariance(const t_inputrec &ir, /* Returns the largest sigma of the Gaussian displacement over all particle * types. This ignores constraints, so is an overestimate. */ -static real maxSigma(real kT_fac, - gmx::ArrayRef att) +static real maxSigma(real kT_fac, gmx::ArrayRef att) { GMX_ASSERT(!att.empty(), "We should have at least one type"); real smallestMass = att[0].prop.mass; - for (const auto &atomType : att) + for (const auto& atomType : att) { smallestMass = std::min(smallestMass, atomType.prop.mass); } - ; - return 2*std::sqrt(kT_fac/smallestMass); + return 2 * std::sqrt(kT_fac / smallestMass); } -real -calcVerletBufferSize(const gmx_mtop_t &mtop, - const real boxVolume, - const t_inputrec &ir, - const int nstlist, - const int listLifetime, - real referenceTemperature, - const VerletbufListSetup &listSetup) +real calcVerletBufferSize(const gmx_mtop_t& mtop, + const real boxVolume, + const t_inputrec& ir, + const int nstlist, + const int listLifetime, + real referenceTemperature, + const VerletbufListSetup& listSetup) { - double resolution; - char *env; + double resolution; + char* env; - real particle_distance; - real nb_clust_frac_pairs_not_in_list_at_cutoff; + real particle_distance; + real nb_clust_frac_pairs_not_in_list_at_cutoff; - real elfac; - int ib0, ib1, ib; - real rb, rl; - real drift; + real elfac; + int ib0, ib1, ib; + real rb, rl; + real drift; if (!EI_DYNAMICS(ir.eI)) { - gmx_incons("Can only determine the Verlet buffer size for integrators that perform dynamics"); + gmx_incons( + "Can only determine the Verlet buffer size for integrators that perform dynamics"); } if (ir.verletbuf_tol <= 0) { @@ -883,7 +862,8 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, */ referenceTemperature = maxReferenceTemperature(ir); - GMX_RELEASE_ASSERT(referenceTemperature >= 0, "Without T-coupling we should not end up here"); + GMX_RELEASE_ASSERT(referenceTemperature >= 0, + "Without T-coupling we should not end up here"); } /* Resolution of the buffer size */ @@ -920,20 +900,18 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, */ /* Worst case assumption: HCP packing of particles gives largest distance */ - particle_distance = std::cbrt(boxVolume*std::sqrt(2)/mtop.natoms); + particle_distance = std::cbrt(boxVolume * std::sqrt(2) / mtop.natoms); /* TODO: Obtain masses through (future) integrator functionality * to avoid scattering the code with (or forgetting) checks. */ const bool setMassesToOne = (ir.eI == eiBD && ir.bd_fric > 0); - const auto att = - getVerletBufferAtomtypes(mtop, setMassesToOne); + const auto att = getVerletBufferAtomtypes(mtop, setMassesToOne); GMX_ASSERT(!att.empty(), "We expect at least one type"); if (debug) { - fprintf(debug, "particle distance assuming HCP packing: %f nm\n", - particle_distance); + fprintf(debug, "particle distance assuming HCP packing: %f nm\n", particle_distance); fprintf(debug, "energy drift atom types: %zu\n", att.size()); } @@ -950,50 +928,51 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, case eintmodNONE: case eintmodPOTSHIFT: /* -dV/dr of -r^-6 and r^-reppow */ - ljDisp.md1 = -6*std::pow(ir.rvdw, -7.0); - ljRep.md1 = repPow*std::pow(ir.rvdw, -(repPow + 1)); + ljDisp.md1 = -6 * std::pow(ir.rvdw, -7.0); + ljRep.md1 = repPow * std::pow(ir.rvdw, -(repPow + 1)); /* The contribution of the higher derivatives is negligible */ break; case eintmodFORCESWITCH: /* At the cut-off: V=V'=V''=0, so we use only V''' */ - ljDisp.md3 = -md3_force_switch(6.0, ir.rvdw_switch, ir.rvdw); - ljRep.md3 = md3_force_switch(repPow, ir.rvdw_switch, ir.rvdw); + ljDisp.md3 = -md3_force_switch(6.0, ir.rvdw_switch, ir.rvdw); + ljRep.md3 = md3_force_switch(repPow, ir.rvdw_switch, ir.rvdw); break; case eintmodPOTSWITCH: /* At the cut-off: V=V'=V''=0. * V''' is given by the original potential times * the third derivative of the switch function. */ - sw_range = ir.rvdw - ir.rvdw_switch; - md3_pswf = 60.0/gmx::power3(sw_range); + sw_range = ir.rvdw - ir.rvdw_switch; + md3_pswf = 60.0 / gmx::power3(sw_range); - ljDisp.md3 = -std::pow(ir.rvdw, -6.0 )*md3_pswf; - ljRep.md3 = std::pow(ir.rvdw, -repPow)*md3_pswf; + ljDisp.md3 = -std::pow(ir.rvdw, -6.0) * md3_pswf; + ljRep.md3 = std::pow(ir.rvdw, -repPow) * md3_pswf; break; - default: - gmx_incons("Unimplemented VdW modifier"); + default: gmx_incons("Unimplemented VdW modifier"); } } else if (EVDW_PME(ir.vdwtype)) { - real b = calc_ewaldcoeff_lj(ir.rvdw, ir.ewald_rtol_lj); - real r = ir.rvdw; - real br = b*r; - real br2 = br*br; - real br4 = br2*br2; - real br6 = br4*br2; + real b = calc_ewaldcoeff_lj(ir.rvdw, ir.ewald_rtol_lj); + real r = ir.rvdw; + real br = b * r; + real br2 = br * br; + real br4 = br2 * br2; + real br6 = br4 * br2; // -dV/dr of g(br)*r^-6 [where g(x) = exp(-x^2)(1+x^2+x^4/2), // see LJ-PME equations in manual] and r^-reppow - ljDisp.md1 = -std::exp(-br2)*(br6 + 3.0*br4 + 6.0*br2 + 6.0)*std::pow(r, -7.0); - ljRep.md1 = repPow*pow(r, -(repPow + 1)); + ljDisp.md1 = -std::exp(-br2) * (br6 + 3.0 * br4 + 6.0 * br2 + 6.0) * std::pow(r, -7.0); + ljRep.md1 = repPow * pow(r, -(repPow + 1)); // The contribution of the higher derivatives is negligible } else { - gmx_fatal(FARGS, "Energy drift calculation is only implemented for plain cut-off Lennard-Jones interactions"); + gmx_fatal(FARGS, + "Energy drift calculation is only implemented for plain cut-off Lennard-Jones " + "interactions"); } - elfac = ONE_4PI_EPS0/ir.epsilon_r; + elfac = ONE_4PI_EPS0 / ir.epsilon_r; // Determine the 1st and 2nd derivative for the electostatics pot_derivatives_t elec = { 0, 0, 0 }; @@ -1009,23 +988,23 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, } else { - eps_rf = ir.epsilon_rf/ir.epsilon_r; + eps_rf = ir.epsilon_rf / ir.epsilon_r; if (eps_rf != 0) { - k_rf = (eps_rf - ir.epsilon_r)/( gmx::power3(ir.rcoulomb) * (2*eps_rf + ir.epsilon_r) ); + k_rf = (eps_rf - ir.epsilon_r) / (gmx::power3(ir.rcoulomb) * (2 * eps_rf + ir.epsilon_r)); } else { /* epsilon_rf = infinity */ - k_rf = 0.5/gmx::power3(ir.rcoulomb); + k_rf = 0.5 / gmx::power3(ir.rcoulomb); } } if (eps_rf > 0) { - elec.md1 = elfac*(1.0/gmx::square(ir.rcoulomb) - 2*k_rf*ir.rcoulomb); + elec.md1 = elfac * (1.0 / gmx::square(ir.rcoulomb) - 2 * k_rf * ir.rcoulomb); } - elec.d2 = elfac*(2.0/gmx::power3(ir.rcoulomb) + 2*k_rf); + elec.d2 = elfac * (2.0 / gmx::power3(ir.rcoulomb) + 2 * k_rf); } else if (EEL_PME(ir.coulombtype) || ir.coulombtype == eelEWALD) { @@ -1033,13 +1012,16 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, b = calc_ewaldcoeff_q(ir.rcoulomb, ir.ewald_rtol); rc = ir.rcoulomb; - br = b*rc; - elec.md1 = elfac*(b*std::exp(-br*br)*M_2_SQRTPI/rc + std::erfc(br)/(rc*rc)); - elec.d2 = elfac/(rc*rc)*(2*b*(1 + br*br)*std::exp(-br*br)*M_2_SQRTPI + 2*std::erfc(br)/rc); + br = b * rc; + elec.md1 = elfac * (b * std::exp(-br * br) * M_2_SQRTPI / rc + std::erfc(br) / (rc * rc)); + elec.d2 = elfac / (rc * rc) + * (2 * b * (1 + br * br) * std::exp(-br * br) * M_2_SQRTPI + 2 * std::erfc(br) / rc); } else { - gmx_fatal(FARGS, "Energy drift calculation is only implemented for Reaction-Field and Ewald electrostatics"); + gmx_fatal(FARGS, + "Energy drift calculation is only implemented for Reaction-Field and Ewald " + "electrostatics"); } /* Determine the variance of the atomic displacement @@ -1047,8 +1029,7 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, * For inertial dynamics (not Brownian dynamics) the mass factor * is not included in kT_fac, it is added later. */ - const real kT_fac = displacementVariance(ir, referenceTemperature, - listLifetime*ir.delta_t); + const real kT_fac = displacementVariance(ir, referenceTemperature, listLifetime * ir.delta_t); if (debug) { @@ -1062,43 +1043,36 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, /* Search using bisection */ ib0 = -1; /* The drift will be neglible at 5 times the max sigma */ - ib1 = static_cast(5*maxSigma(kT_fac, att)/resolution) + 1; + ib1 = static_cast(5 * maxSigma(kT_fac, att) / resolution) + 1; while (ib1 - ib0 > 1) { - ib = (ib0 + ib1)/2; - rb = ib*resolution; + ib = (ib0 + ib1) / 2; + rb = ib * resolution; rl = std::max(ir.rvdw, ir.rcoulomb) + rb; /* Calculate the average energy drift at the last step * of the nstlist steps at which the pair-list is used. */ - drift = energyDrift(att, &mtop.ffparams, - kT_fac, - &ljDisp, &ljRep, &elec, - ir.rvdw, ir.rcoulomb, - rl, boxVolume); + drift = energyDrift(att, &mtop.ffparams, kT_fac, &ljDisp, &ljRep, &elec, ir.rvdw, + ir.rcoulomb, rl, boxVolume); /* Correct for the fact that we are using a Ni x Nj particle pair list * and not a 1 x 1 particle pair list. This reduces the drift. */ /* We don't have a formula for 8 (yet), use 4 which is conservative */ nb_clust_frac_pairs_not_in_list_at_cutoff = - surface_frac(std::min(listSetup.cluster_size_i, 4), - particle_distance, rl)* - surface_frac(std::min(listSetup.cluster_size_j, 4), - particle_distance, rl); + surface_frac(std::min(listSetup.cluster_size_i, 4), particle_distance, rl) + * surface_frac(std::min(listSetup.cluster_size_j, 4), particle_distance, rl); drift *= nb_clust_frac_pairs_not_in_list_at_cutoff; /* Convert the drift to drift per unit time per atom */ - drift /= nstlist*ir.delta_t*mtop.natoms; + drift /= nstlist * ir.delta_t * mtop.natoms; if (debug) { - fprintf(debug, "ib %3d %3d %3d rb %.3f %dx%d fac %.3f drift %.1e\n", - ib0, ib, ib1, rb, + fprintf(debug, "ib %3d %3d %3d rb %.3f %dx%d fac %.3f drift %.1e\n", ib0, ib, ib1, rb, listSetup.cluster_size_i, listSetup.cluster_size_j, - nb_clust_frac_pairs_not_in_list_at_cutoff, - drift); + nb_clust_frac_pairs_not_in_list_at_cutoff, drift); } if (std::abs(drift) > ir.verletbuf_tol) @@ -1111,7 +1085,7 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, } } - return std::max(ir.rvdw, ir.rcoulomb) + ib1*resolution; + return std::max(ir.rvdw, ir.rcoulomb) + ib1 * resolution; } /* Returns the pairlist buffer size for use as a minimum buffer size @@ -1120,15 +1094,12 @@ calcVerletBufferSize(const gmx_mtop_t &mtop, * set for good energy conservation or RF electrostatics. But it is * too small with PME and the buffer set with the default tolerance. */ -static real minCellSizeFromPairlistBuffer(const t_inputrec &ir) +static real minCellSizeFromPairlistBuffer(const t_inputrec& ir) { return ir.rlist - std::max(ir.rvdw, ir.rcoulomb); } -static real -chanceOfAtomCrossingCell(gmx::ArrayRef atomtypes, - real kT_fac, - real cellSize) +static real chanceOfAtomCrossingCell(gmx::ArrayRef atomtypes, real kT_fac, real cellSize) { /* We assume atoms are distributed uniformly over the cell width. * Once an atom has moved by more than the cellSize (as passed @@ -1139,20 +1110,18 @@ chanceOfAtomCrossingCell(gmx::ArrayRef atomtypes, * derivative = -1/cellSize. Using this in the energyDriftAtomPair * function will return the chance of crossing the next boundary. */ - const pot_derivatives_t boundaryInteraction = { 1/cellSize, 0, 0 }; + const pot_derivatives_t boundaryInteraction = { 1 / cellSize, 0, 0 }; - real chance = 0; - for (const VerletbufAtomtype &att : atomtypes) + real chance = 0; + for (const VerletbufAtomtype& att : atomtypes) { - const atom_nonbonded_kinetic_prop_t &propAtom = att.prop; - real s2_2d; - real s2_3d; + const atom_nonbonded_kinetic_prop_t& propAtom = att.prop; + real s2_2d; + real s2_3d; get_atom_sigma2(kT_fac, &propAtom, &s2_2d, &s2_3d); - real chancePerAtom = energyDriftAtomPair(propAtom.bConstr, false, - s2_2d + s2_3d, s2_2d, 0, - cellSize, - &boundaryInteraction); + real chancePerAtom = energyDriftAtomPair(propAtom.bConstr, false, s2_2d + s2_3d, s2_2d, 0, + cellSize, &boundaryInteraction); if (propAtom.bConstr) { @@ -1163,21 +1132,18 @@ chanceOfAtomCrossingCell(gmx::ArrayRef atomtypes, * Use this maximum, limited displacement when this results in * a smaller chance (note that this is still an overestimate). */ - real massFraction = propAtom.con_mass/(propAtom.mass + propAtom.con_mass); - real comDistance = propAtom.con_len*massFraction; - - real chanceWithMaxDistance = - energyDriftAtomPair(false, false, - s2_3d, 0, 0, - cellSize - 2*comDistance, - &boundaryInteraction); + real massFraction = propAtom.con_mass / (propAtom.mass + propAtom.con_mass); + real comDistance = propAtom.con_len * massFraction; + + real chanceWithMaxDistance = energyDriftAtomPair( + false, false, s2_3d, 0, 0, cellSize - 2 * comDistance, &boundaryInteraction); chancePerAtom = std::min(chancePerAtom, chanceWithMaxDistance); } /* Take into account the line density of the boundary */ chancePerAtom /= cellSize; - chance += att.n*chancePerAtom; + chance += att.n * chancePerAtom; } return chance; @@ -1189,7 +1155,7 @@ struct AtomConstraintProps void addConstraint(real length) { numConstraints += 1; - sumLengths += length; + sumLengths += length; } int numConstraints = 0; /* The number of constraints of an atom */ @@ -1197,14 +1163,13 @@ struct AtomConstraintProps }; /* Constructs and returns a list of constraint properties per atom */ -static std::vector -getAtomConstraintProps(const gmx_moltype_t &moltype, - const gmx_ffparams_t &ffparams) +static std::vector getAtomConstraintProps(const gmx_moltype_t& moltype, + const gmx_ffparams_t& ffparams) { - const t_atoms &atoms = moltype.atoms; - std::vector props(atoms.nr); + const t_atoms& atoms = moltype.atoms; + std::vector props(atoms.nr); - for (const auto &ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) + for (const auto& ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) { // Settles are handled separately if (ilist.functionType == F_SETTLE) @@ -1227,27 +1192,27 @@ getAtomConstraintProps(const gmx_moltype_t &moltype, } /* Return the chance of at least one update group in a molecule crossing a cell of size cellSize */ -static real -chanceOfUpdateGroupCrossingCell(const gmx_moltype_t &moltype, - const gmx_ffparams_t &ffparams, - const gmx::RangePartitioning &updateGrouping, - real kT_fac, - real cellSize) +static real chanceOfUpdateGroupCrossingCell(const gmx_moltype_t& moltype, + const gmx_ffparams_t& ffparams, + const gmx::RangePartitioning& updateGrouping, + real kT_fac, + real cellSize) { - const t_atoms &atoms = moltype.atoms; - GMX_ASSERT(updateGrouping.fullRange().end() == atoms.nr, "The update groups should match the molecule type"); + const t_atoms& atoms = moltype.atoms; + GMX_ASSERT(updateGrouping.fullRange().end() == atoms.nr, + "The update groups should match the molecule type"); - const pot_derivatives_t boundaryInteraction = { 1/cellSize, 0, 0 }; + const pot_derivatives_t boundaryInteraction = { 1 / cellSize, 0, 0 }; - const auto atomConstraintProps = getAtomConstraintProps(moltype, ffparams); + const auto atomConstraintProps = getAtomConstraintProps(moltype, ffparams); - real chance = 0; + real chance = 0; for (int group = 0; group < updateGrouping.numBlocks(); group++) { - const auto &block = updateGrouping.block(group); + const auto& block = updateGrouping.block(group); /* Determine the number of atoms with constraints and the mass of the COG */ - int numAtomsWithConstraints = 0; - real massSum = 0; + int numAtomsWithConstraints = 0; + real massSum = 0; for (const int atom : block) { if (atomConstraintProps[atom].numConstraints > 0) @@ -1268,7 +1233,8 @@ chanceOfUpdateGroupCrossingCell(const gmx_moltype_t &moltype, { GMX_ASSERT(atomConstraintProps[atom].numConstraints == 1, "Two atoms should be connected by one constraint"); - maxComCogDistance = std::abs(atoms.atom[atom].m/massSum - 0.5)*atomConstraintProps[atom].sumLengths; + maxComCogDistance = std::abs(atoms.atom[atom].m / massSum - 0.5) + * atomConstraintProps[atom].sumLengths; break; } } @@ -1279,8 +1245,8 @@ chanceOfUpdateGroupCrossingCell(const gmx_moltype_t &moltype, { if (atomConstraintProps[atom].numConstraints == numAtomsWithConstraints - 1) { - real comCogDistance = atomConstraintProps[atom].sumLengths/numAtomsWithConstraints; - maxComCogDistance = std::max(maxComCogDistance, comCogDistance); + real comCogDistance = atomConstraintProps[atom].sumLengths / numAtomsWithConstraints; + maxComCogDistance = std::max(maxComCogDistance, comCogDistance); } } } @@ -1289,58 +1255,56 @@ chanceOfUpdateGroupCrossingCell(const gmx_moltype_t &moltype, // All normal atoms must be connected by SETTLE for (const int atom : block) { - const auto &ilist = moltype.ilist[F_SETTLE]; - GMX_RELEASE_ASSERT(ilist.size() > 0, "There should be at least one settle in this moltype"); + const auto& ilist = moltype.ilist[F_SETTLE]; + GMX_RELEASE_ASSERT(ilist.size() > 0, + "There should be at least one settle in this moltype"); for (int i = 0; i < ilist.size(); i += 1 + NRAL(F_SETTLE)) { if (atom == ilist.iatoms[i + 1]) { - const t_iparams &iparams = ffparams.iparams[ilist.iatoms[i]]; + const t_iparams& iparams = ffparams.iparams[ilist.iatoms[i]]; real dOH = iparams.settle.doh; real dHH = iparams.settle.dhh; - real dOMidH = std::sqrt(dOH*dOH - 0.25_real*dHH*dHH); - maxComCogDistance = std::abs(atoms.atom[atom].m/massSum - 1.0_real/3.0_real)*dOMidH; + real dOMidH = std::sqrt(dOH * dOH - 0.25_real * dHH * dHH); + maxComCogDistance = + std::abs(atoms.atom[atom].m / massSum - 1.0_real / 3.0_real) * dOMidH; } } } } - real s2_3d = kT_fac/massSum; - chance += energyDriftAtomPair(false, false, - s2_3d, 0, 0, - cellSize - 2*maxComCogDistance, - &boundaryInteraction); + real s2_3d = kT_fac / massSum; + chance += energyDriftAtomPair(false, false, s2_3d, 0, 0, cellSize - 2 * maxComCogDistance, + &boundaryInteraction); } return chance; } /* Return the chance of at least one update group in the system crossing a cell of size cellSize */ -static real -chanceOfUpdateGroupCrossingCell(const gmx_mtop_t &mtop, - PartitioningPerMoltype updateGrouping, - real kT_fac, - real cellSize) +static real chanceOfUpdateGroupCrossingCell(const gmx_mtop_t& mtop, + PartitioningPerMoltype updateGrouping, + real kT_fac, + real cellSize) { GMX_RELEASE_ASSERT(updateGrouping.size() == mtop.moltype.size(), "The update groups should match the topology"); real chance = 0; - for (const gmx_molblock_t &molblock : mtop.molblock) + for (const gmx_molblock_t& molblock : mtop.molblock) { - const gmx_moltype_t &moltype = mtop.moltype[molblock.type]; - chance += - molblock.nmol*chanceOfUpdateGroupCrossingCell(moltype, mtop.ffparams, updateGrouping[molblock.type], - kT_fac, cellSize); + const gmx_moltype_t& moltype = mtop.moltype[molblock.type]; + chance += molblock.nmol + * chanceOfUpdateGroupCrossingCell(moltype, mtop.ffparams, + updateGrouping[molblock.type], kT_fac, cellSize); } return chance; } -real -minCellSizeForAtomDisplacement(const gmx_mtop_t &mtop, - const t_inputrec &ir, - PartitioningPerMoltype updateGrouping, - real chanceRequested) +real minCellSizeForAtomDisplacement(const gmx_mtop_t& mtop, + const t_inputrec& ir, + PartitioningPerMoltype updateGrouping, + real chanceRequested) { if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == etcNO)) { @@ -1357,21 +1321,20 @@ minCellSizeForAtomDisplacement(const gmx_mtop_t &mtop, const auto atomtypes = getVerletBufferAtomtypes(mtop, setMassesToOne); - const real kT_fac = displacementVariance(ir, temperature, - ir.nstlist*ir.delta_t); + const real kT_fac = displacementVariance(ir, temperature, ir.nstlist * ir.delta_t); /* Resolution of the cell size */ real resolution = 0.001; /* Search using bisection, avoid 0 and start at 1 */ - int ib0 = 0; + int ib0 = 0; /* The chance will be neglible at 10 times the max sigma */ - int ib1 = int(10*maxSigma(kT_fac, atomtypes)/resolution) + 1; + int ib1 = int(10 * maxSigma(kT_fac, atomtypes) / resolution) + 1; real cellSize = 0; while (ib1 - ib0 > 1) { - int ib = (ib0 + ib1)/2; - cellSize = ib*resolution; + int ib = (ib0 + ib1) / 2; + cellSize = ib * resolution; real chance; if (updateGrouping.empty()) @@ -1384,7 +1347,7 @@ minCellSizeForAtomDisplacement(const gmx_mtop_t &mtop, } /* Note: chance is for every nstlist steps */ - if (chance > chanceRequested*ir.nstlist) + if (chance > chanceRequested * ir.nstlist) { ib0 = ib; } diff --git a/src/gromacs/mdlib/calc_verletbuf.h b/src/gromacs/mdlib/calc_verletbuf.h index e0bc6bf650..eafd6e80fc 100644 --- a/src/gromacs/mdlib/calc_verletbuf.h +++ b/src/gromacs/mdlib/calc_verletbuf.h @@ -56,8 +56,8 @@ enum class KernelType; struct VerletbufListSetup { - int cluster_size_i; /* Cluster pair-list i-cluster size atom count */ - int cluster_size_j; /* Cluster pair-list j-cluster size atom count */ + int cluster_size_i; /* Cluster pair-list i-cluster size atom count */ + int cluster_size_j; /* Cluster pair-list j-cluster size atom count */ }; @@ -109,19 +109,18 @@ VerletbufListSetup verletbufGetSafeListSetup(ListSetupType listType); * \param[in] boxVolume The volume of the unit cell * \param[in] inputrec The input record * \param[in] nstlist The pair list update frequency in steps (is not taken from \p inputrec) - * \param[in] listLifetime The lifetime of the pair-list, usually nstlist-1, but could be different for dynamic pruning - * \param[in] referenceTemperature The reference temperature for the ensemble + * \param[in] listLifetime The lifetime of the pair-list, usually nstlist-1, but could be different + * for dynamic pruning \param[in] referenceTemperature The reference temperature for the ensemble * \param[in] listSetup The pair-list setup * \returns The computed pair-list radius including buffer */ -real -calcVerletBufferSize(const gmx_mtop_t &mtop, - real boxVolume, - const t_inputrec &inputrec, - int nstlist, - int listLifetime, - real referenceTemperature, - const VerletbufListSetup &listSetup); +real calcVerletBufferSize(const gmx_mtop_t& mtop, + real boxVolume, + const t_inputrec& inputrec, + int nstlist, + int listLifetime, + real referenceTemperature, + const VerletbufListSetup& listSetup); /* Convenience type */ using PartitioningPerMoltype = gmx::ArrayRef; @@ -141,11 +140,10 @@ using PartitioningPerMoltype = gmx::ArrayRef; * * Note: This size increases (very slowly) with system size. */ -real -minCellSizeForAtomDisplacement(const gmx_mtop_t &mtop, - const t_inputrec &ir, - PartitioningPerMoltype updateGrouping, - real chanceRequested); +real minCellSizeForAtomDisplacement(const gmx_mtop_t& mtop, + const t_inputrec& ir, + PartitioningPerMoltype updateGrouping, + real chanceRequested); /* Struct for unique atom type for calculating the energy drift. * The atom displacement depends on mass and constraints. @@ -170,9 +168,6 @@ struct atom_nonbonded_kinetic_prop_t * * Only exposed here for testing purposes. */ -void constrained_atom_sigma2(real kT_fac, - const atom_nonbonded_kinetic_prop_t *prop, - real *sigma2_2d, - real *sigma2_3d); +void constrained_atom_sigma2(real kT_fac, const atom_nonbonded_kinetic_prop_t* prop, real* sigma2_2d, real* sigma2_3d); #endif diff --git a/src/gromacs/mdlib/calcmu.cpp b/src/gromacs/mdlib/calcmu.cpp index cfd3fa127f..4fe1eaa104 100644 --- a/src/gromacs/mdlib/calcmu.cpp +++ b/src/gromacs/mdlib/calcmu.cpp @@ -47,14 +47,19 @@ #include "gromacs/math/vec.h" #include "gromacs/mdlib/gmx_omp_nthreads.h" -void calc_mu(int start, int homenr, gmx::ArrayRef x, const real q[], const real qB[], - int nChargePerturbed, - dvec mu, dvec mu_B) +void calc_mu(int start, + int homenr, + gmx::ArrayRef x, + const real q[], + const real qB[], + int nChargePerturbed, + dvec mu, + dvec mu_B) { int end, m; double mu_x, mu_y, mu_z; - end = start + homenr; + end = start + homenr; mu_x = mu_y = mu_z = 0.0; #pragma omp parallel for reduction(+: mu_x, mu_y, mu_z) schedule(static) \ @@ -62,9 +67,9 @@ void calc_mu(int start, int homenr, gmx::ArrayRef x, const real q[], for (int i = start; i < end; i++) { // Trivial OpenMP region that cannot throw - mu_x += q[i]*x[i][XX]; - mu_y += q[i]*x[i][YY]; - mu_z += q[i]*x[i][ZZ]; + mu_x += q[i] * x[i][XX]; + mu_y += q[i] * x[i][YY]; + mu_z += q[i] * x[i][ZZ]; } mu[XX] = mu_x; mu[YY] = mu_y; @@ -83,9 +88,9 @@ void calc_mu(int start, int homenr, gmx::ArrayRef x, const real q[], for (int i = start; i < end; i++) { // Trivial OpenMP region that cannot throw - mu_x += qB[i]*x[i][XX]; - mu_y += qB[i]*x[i][YY]; - mu_z += qB[i]*x[i][ZZ]; + mu_x += qB[i] * x[i][XX]; + mu_y += qB[i] * x[i][YY]; + mu_z += qB[i] * x[i][ZZ]; } mu_B[XX] = mu_x * ENM2DEBYE; mu_B[YY] = mu_y * ENM2DEBYE; @@ -97,12 +102,12 @@ void calc_mu(int start, int homenr, gmx::ArrayRef x, const real q[], } } -gmx_bool read_mu(FILE *fp, rvec mu, real *vol) +gmx_bool read_mu(FILE* fp, rvec mu, real* vol) { /* For backward compatibility */ real mmm[4]; - if (fread(mmm, static_cast(4*sizeof(real)), 1, fp) != 1) + if (fread(mmm, static_cast(4 * sizeof(real)), 1, fp) != 1) { return FALSE; } diff --git a/src/gromacs/mdlib/calcmu.h b/src/gromacs/mdlib/calcmu.h index aefeb44a9e..fc75cc1469 100644 --- a/src/gromacs/mdlib/calcmu.h +++ b/src/gromacs/mdlib/calcmu.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,11 +43,16 @@ #include "gromacs/utility/arrayref.h" #include "gromacs/utility/basedefinitions.h" -void calc_mu(int start, int homenr, gmx::ArrayRef x, const real q[], const real qB[], - int nChargePerturbed, - dvec mu, dvec mu_B); +void calc_mu(int start, + int homenr, + gmx::ArrayRef x, + const real q[], + const real qB[], + int nChargePerturbed, + dvec mu, + dvec mu_B); -gmx_bool read_mu(FILE *fp, rvec mu, real *vol); +gmx_bool read_mu(FILE* fp, rvec mu, real* vol); /* Return true on succes */ #endif diff --git a/src/gromacs/mdlib/calcvir.cpp b/src/gromacs/mdlib/calcvir.cpp index 795591ea39..a9d9f6b28d 100644 --- a/src/gromacs/mdlib/calcvir.cpp +++ b/src/gromacs/mdlib/calcvir.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,26 +51,24 @@ #include "gromacs/pbcutil/pbc.h" #include "gromacs/utility/gmxassert.h" -#define XXXX 0 -#define XXYY 1 -#define XXZZ 2 -#define YYXX 3 -#define YYYY 4 -#define YYZZ 5 -#define ZZXX 6 -#define ZZYY 7 -#define ZZZZ 8 +#define XXXX 0 +#define XXYY 1 +#define XXZZ 2 +#define YYXX 3 +#define YYYY 4 +#define YYZZ 5 +#define ZZXX 6 +#define ZZYY 7 +#define ZZZZ 8 static void upd_vir(rvec vir, real dvx, real dvy, real dvz) { - vir[XX] -= 0.5*dvx; - vir[YY] -= 0.5*dvy; - vir[ZZ] -= 0.5*dvz; + vir[XX] -= 0.5 * dvx; + vir[YY] -= 0.5 * dvy; + vir[ZZ] -= 0.5 * dvz; } -static void calc_x_times_f(int nxf, const rvec x[], const rvec f[], - gmx_bool bScrewPBC, const matrix box, - matrix x_times_f) +static void calc_x_times_f(int nxf, const rvec x[], const rvec f[], gmx_bool bScrewPBC, const matrix box, matrix x_times_f) { clear_mat(x_times_f); @@ -80,7 +78,7 @@ static void calc_x_times_f(int nxf, const rvec x[], const rvec f[], { for (int n = 0; n < DIM; n++) { - x_times_f[d][n] += x[i][d]*f[i][n]; + x_times_f[d][n] += x[i][d] * f[i][n]; } } @@ -94,7 +92,7 @@ static void calc_x_times_f(int nxf, const rvec x[], const rvec f[], { for (int n = 0; n < DIM; n++) { - x_times_f[d][n] += box[d][d]*f[i][n]; + x_times_f[d][n] += box[d][d] * f[i][n]; } } } @@ -102,12 +100,11 @@ static void calc_x_times_f(int nxf, const rvec x[], const rvec f[], } } -void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, - bool bScrewPBC, const matrix box) +void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, bool bScrewPBC, const matrix box) { matrix x_times_f; - int nthreads = gmx_omp_nthreads_get_simple_rvec_task(emntDefault, nxf*9); + int nthreads = gmx_omp_nthreads_get_simple_rvec_task(emntDefault, nxf * 9); GMX_ASSERT(nthreads >= 1, "Avoids uninitialized x_times_f (warning)"); @@ -121,21 +118,21 @@ void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, * We use 2 extra elements (=18 reals) per thread to separate thread * local data by at least a cache line. Element 0 is not used. */ - matrix xf_buf[GMX_OPENMP_MAX_THREADS*3]; + matrix xf_buf[GMX_OPENMP_MAX_THREADS * 3]; #pragma omp parallel for num_threads(nthreads) schedule(static) for (int thread = 0; thread < nthreads; thread++) { - int start = (nxf*thread)/nthreads; - int end = std::min(nxf*(thread + 1)/nthreads, nxf); + int start = (nxf * thread) / nthreads; + int end = std::min(nxf * (thread + 1) / nthreads, nxf); calc_x_times_f(end - start, x + start, f + start, bScrewPBC, box, - thread == 0 ? x_times_f : xf_buf[thread*3]); + thread == 0 ? x_times_f : xf_buf[thread * 3]); } for (int thread = 1; thread < nthreads; thread++) { - m_add(x_times_f, xf_buf[thread*3], x_times_f); + m_add(x_times_f, xf_buf[thread * 3], x_times_f); } } @@ -146,62 +143,61 @@ void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, } -static void lo_fcv(int i0, int i1, - const real x[], const real f[], tensor vir, - const int is[], const real box[], gmx_bool bTriclinic) +static void +lo_fcv(int i0, int i1, const real x[], const real f[], tensor vir, const int is[], const real box[], gmx_bool bTriclinic) { - int i, i3, tx, ty, tz; - real xx, yy, zz; - real dvxx = 0, dvxy = 0, dvxz = 0, dvyx = 0, dvyy = 0, dvyz = 0, dvzx = 0, dvzy = 0, dvzz = 0; + int i, i3, tx, ty, tz; + real xx, yy, zz; + real dvxx = 0, dvxy = 0, dvxz = 0, dvyx = 0, dvyy = 0, dvyz = 0, dvzx = 0, dvzy = 0, dvzz = 0; if (bTriclinic) { for (i = i0; (i < i1); i++) { - i3 = DIM*i; - tx = is[i3+XX]; - ty = is[i3+YY]; - tz = is[i3+ZZ]; - - xx = x[i3+XX]-tx*box[XXXX]-ty*box[YYXX]-tz*box[ZZXX]; - dvxx += xx*f[i3+XX]; - dvxy += xx*f[i3+YY]; - dvxz += xx*f[i3+ZZ]; - - yy = x[i3+YY]-ty*box[YYYY]-tz*box[ZZYY]; - dvyx += yy*f[i3+XX]; - dvyy += yy*f[i3+YY]; - dvyz += yy*f[i3+ZZ]; - - zz = x[i3+ZZ]-tz*box[ZZZZ]; - dvzx += zz*f[i3+XX]; - dvzy += zz*f[i3+YY]; - dvzz += zz*f[i3+ZZ]; + i3 = DIM * i; + tx = is[i3 + XX]; + ty = is[i3 + YY]; + tz = is[i3 + ZZ]; + + xx = x[i3 + XX] - tx * box[XXXX] - ty * box[YYXX] - tz * box[ZZXX]; + dvxx += xx * f[i3 + XX]; + dvxy += xx * f[i3 + YY]; + dvxz += xx * f[i3 + ZZ]; + + yy = x[i3 + YY] - ty * box[YYYY] - tz * box[ZZYY]; + dvyx += yy * f[i3 + XX]; + dvyy += yy * f[i3 + YY]; + dvyz += yy * f[i3 + ZZ]; + + zz = x[i3 + ZZ] - tz * box[ZZZZ]; + dvzx += zz * f[i3 + XX]; + dvzy += zz * f[i3 + YY]; + dvzz += zz * f[i3 + ZZ]; } } else { for (i = i0; (i < i1); i++) { - i3 = DIM*i; - tx = is[i3+XX]; - ty = is[i3+YY]; - tz = is[i3+ZZ]; - - xx = x[i3+XX]-tx*box[XXXX]; - dvxx += xx*f[i3+XX]; - dvxy += xx*f[i3+YY]; - dvxz += xx*f[i3+ZZ]; - - yy = x[i3+YY]-ty*box[YYYY]; - dvyx += yy*f[i3+XX]; - dvyy += yy*f[i3+YY]; - dvyz += yy*f[i3+ZZ]; - - zz = x[i3+ZZ]-tz*box[ZZZZ]; - dvzx += zz*f[i3+XX]; - dvzy += zz*f[i3+YY]; - dvzz += zz*f[i3+ZZ]; + i3 = DIM * i; + tx = is[i3 + XX]; + ty = is[i3 + YY]; + tz = is[i3 + ZZ]; + + xx = x[i3 + XX] - tx * box[XXXX]; + dvxx += xx * f[i3 + XX]; + dvxy += xx * f[i3 + YY]; + dvxz += xx * f[i3 + ZZ]; + + yy = x[i3 + YY] - ty * box[YYYY]; + dvyx += yy * f[i3 + XX]; + dvyy += yy * f[i3 + YY]; + dvyz += yy * f[i3 + ZZ]; + + zz = x[i3 + ZZ] - tz * box[ZZZZ]; + dvzx += zz * f[i3 + XX]; + dvzy += zz * f[i3 + YY]; + dvzz += zz * f[i3 + ZZ]; } } @@ -210,8 +206,7 @@ static void lo_fcv(int i0, int i1, upd_vir(vir[ZZ], dvzx, dvzy, dvzz); } -void f_calc_vir(int i0, int i1, const rvec x[], const rvec f[], tensor vir, - const t_graph *g, const matrix box) +void f_calc_vir(int i0, int i1, const rvec x[], const rvec f[], tensor vir, const t_graph* g, const matrix box) { int start, end; @@ -230,15 +225,15 @@ void f_calc_vir(int i0, int i1, const rvec x[], const rvec f[], tensor vir, */ if (start > i0) { - calc_vir(start-i0, x + i0, f + i0, vir, FALSE, box); + calc_vir(start - i0, x + i0, f + i0, vir, FALSE, box); } if (end < i1) { - calc_vir(i1-end, x + end, f + end, vir, FALSE, box); + calc_vir(i1 - end, x + end, f + end, vir, FALSE, box); } } else { - calc_vir(i1-i0, x + i0, f + i0, vir, FALSE, box); + calc_vir(i1 - i0, x + i0, f + i0, vir, FALSE, box); } } diff --git a/src/gromacs/mdlib/calcvir.h b/src/gromacs/mdlib/calcvir.h index c3db0b56c0..c2eedbc289 100644 --- a/src/gromacs/mdlib/calcvir.h +++ b/src/gromacs/mdlib/calcvir.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,12 +40,10 @@ struct t_graph; struct t_pbc; -void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, - bool bScrewPBC, const matrix box); +void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, bool bScrewPBC, const matrix box); /* Calculate virial for nxf atoms, and add it to vir */ -void f_calc_vir(int i0, int i1, const rvec x[], const rvec f[], tensor vir, - const t_graph *g, const rvec shift_vec[]); +void f_calc_vir(int i0, int i1, const rvec x[], const rvec f[], tensor vir, const t_graph* g, const rvec shift_vec[]); /* Calculate virial taking periodicity into account */ #endif diff --git a/src/gromacs/mdlib/checkpointhandler.cpp b/src/gromacs/mdlib/checkpointhandler.cpp index e2346eba83..57a93e6e0d 100644 --- a/src/gromacs/mdlib/checkpointhandler.cpp +++ b/src/gromacs/mdlib/checkpointhandler.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,13 +60,12 @@ static inline CheckpointSignal convertToCheckpointSignal(signed char sig) return sig >= 1 ? CheckpointSignal::doCheckpoint : CheckpointSignal::noSignal; } -CheckpointHandler::CheckpointHandler( - compat::not_null signal, - bool simulationsShareState, - bool neverUpdateNeighborList, - bool isMaster, - bool writeFinalCheckpoint, - real checkpointingPeriod) : +CheckpointHandler::CheckpointHandler(compat::not_null signal, + bool simulationsShareState, + bool neverUpdateNeighborList, + bool isMaster, + bool writeFinalCheckpoint, + real checkpointingPeriod) : signal_(*signal), checkpointThisStep_(false), numberOfNextCheckpoint_(1), @@ -82,25 +81,24 @@ CheckpointHandler::CheckpointHandler( } } -void CheckpointHandler::setSignalImpl( - gmx_walltime_accounting_t walltime_accounting) const +void CheckpointHandler::setSignalImpl(gmx_walltime_accounting_t walltime_accounting) const { const double secondsSinceStart = walltime_accounting_get_time_since_start(walltime_accounting); - if (convertToCheckpointSignal(signal_.set) == CheckpointSignal::noSignal && - convertToCheckpointSignal(signal_.sig) == CheckpointSignal::noSignal && - (checkpointingPeriod_ == 0 || secondsSinceStart >= numberOfNextCheckpoint_ * checkpointingPeriod_ * 60.0)) + if (convertToCheckpointSignal(signal_.set) == CheckpointSignal::noSignal + && convertToCheckpointSignal(signal_.sig) == CheckpointSignal::noSignal + && (checkpointingPeriod_ == 0 + || secondsSinceStart >= numberOfNextCheckpoint_ * checkpointingPeriod_ * 60.0)) { signal_.sig = static_cast(CheckpointSignal::doCheckpoint); } } -void CheckpointHandler::decideIfCheckpointingThisStepImpl( - bool bNS, bool bFirstStep, bool bLastStep) +void CheckpointHandler::decideIfCheckpointingThisStepImpl(bool bNS, bool bFirstStep, bool bLastStep) { - checkpointThisStep_ = (((convertToCheckpointSignal(signal_.set) == CheckpointSignal::doCheckpoint && - (bNS || neverUpdateNeighborlist_)) || - (bLastStep && writeFinalCheckpoint_)) && - !bFirstStep); + checkpointThisStep_ = (((convertToCheckpointSignal(signal_.set) == CheckpointSignal::doCheckpoint + && (bNS || neverUpdateNeighborlist_)) + || (bLastStep && writeFinalCheckpoint_)) + && !bFirstStep); if (checkpointThisStep_) { signal_.set = static_cast(CheckpointSignal::noSignal); diff --git a/src/gromacs/mdlib/checkpointhandler.h b/src/gromacs/mdlib/checkpointhandler.h index 7304d6e7ad..6725b48a01 100644 --- a/src/gromacs/mdlib/checkpointhandler.h +++ b/src/gromacs/mdlib/checkpointhandler.h @@ -72,7 +72,8 @@ namespace gmx */ enum class CheckpointSignal { - noSignal = 0, doCheckpoint = 1 + noSignal = 0, + doCheckpoint = 1 }; /*! \libinternal @@ -83,73 +84,69 @@ enum class CheckpointSignal */ class CheckpointHandler final { - public: - /*! \brief CheckpointHandler constructor - * - * Needs a non-null pointer to the signal which is reduced by compute_globals, and - * (const) references to data it needs to determine whether a signal needs to be - * set or handled. - */ - CheckpointHandler( - compat::not_null signal, - bool simulationsShareState, - bool neverUpdateNeighborList, - bool isMaster, - bool writeFinalCheckpoint, - real checkpointingPeriod); +public: + /*! \brief CheckpointHandler constructor + * + * Needs a non-null pointer to the signal which is reduced by compute_globals, and + * (const) references to data it needs to determine whether a signal needs to be + * set or handled. + */ + CheckpointHandler(compat::not_null signal, + bool simulationsShareState, + bool neverUpdateNeighborList, + bool isMaster, + bool writeFinalCheckpoint, + real checkpointingPeriod); - /*! \brief Decides whether a checkpointing signal needs to be set - * - * Checkpointing signal is set based on the elapsed run time and the checkpointing - * interval. - */ - void setSignal(gmx_walltime_accounting *walltime_accounting) const + /*! \brief Decides whether a checkpointing signal needs to be set + * + * Checkpointing signal is set based on the elapsed run time and the checkpointing + * interval. + */ + void setSignal(gmx_walltime_accounting* walltime_accounting) const + { + if (rankCanSetSignal_) { - if (rankCanSetSignal_) - { - setSignalImpl(walltime_accounting); - } + setSignalImpl(walltime_accounting); } + } - /*! \brief Decides whether a checkpoint shall be written at this step - * - * Checkpointing is done if this is not the initial step, and - * * a signal has been set and the current step is a neighborlist creation - * step, or - * * the current step is the last step and a the simulation is writing - * configurations. - * - * \todo Change these bools to enums to make calls more self-explanatory - */ - void decideIfCheckpointingThisStep(bool bNS, bool bFirstStep, bool bLastStep) + /*! \brief Decides whether a checkpoint shall be written at this step + * + * Checkpointing is done if this is not the initial step, and + * * a signal has been set and the current step is a neighborlist creation + * step, or + * * the current step is the last step and a the simulation is writing + * configurations. + * + * \todo Change these bools to enums to make calls more self-explanatory + */ + void decideIfCheckpointingThisStep(bool bNS, bool bFirstStep, bool bLastStep) + { + if (checkpointingIsActive_) { - if (checkpointingIsActive_) - { - decideIfCheckpointingThisStepImpl(bNS, bFirstStep, bLastStep); - } + decideIfCheckpointingThisStepImpl(bNS, bFirstStep, bLastStep); } + } - //! Query decision in decideIfCheckpointingThisStep() - bool isCheckpointingStep() const - { - return checkpointThisStep_; - } + //! Query decision in decideIfCheckpointingThisStep() + bool isCheckpointingStep() const { return checkpointThisStep_; } - private: - void setSignalImpl(gmx_walltime_accounting *walltime_accounting) const; +private: + void setSignalImpl(gmx_walltime_accounting* walltime_accounting) const; - void decideIfCheckpointingThisStepImpl(bool bNS, bool bFirstStep, bool bLastStep); + void decideIfCheckpointingThisStepImpl(bool bNS, bool bFirstStep, bool bLastStep); - SimulationSignal &signal_; - bool checkpointThisStep_; - int numberOfNextCheckpoint_; + SimulationSignal& signal_; + bool checkpointThisStep_; + int numberOfNextCheckpoint_; - const bool rankCanSetSignal_; - const bool checkpointingIsActive_; - const bool writeFinalCheckpoint_; - const bool neverUpdateNeighborlist_; - const real checkpointingPeriod_; + const bool rankCanSetSignal_; + const bool checkpointingIsActive_; + const bool writeFinalCheckpoint_; + const bool neverUpdateNeighborlist_; + const real checkpointingPeriod_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDLIB_CHECKPOINTHANDLER_H diff --git a/src/gromacs/mdlib/compute_io.cpp b/src/gromacs/mdlib/compute_io.cpp index 33607bc1af..32969441c1 100644 --- a/src/gromacs/mdlib/compute_io.cpp +++ b/src/gromacs/mdlib/compute_io.cpp @@ -50,7 +50,7 @@ static int div_nsteps(int nsteps, int nst) { if (nst > 0) { - return (1 + nsteps + nst - 1)/nst; + return (1 + nsteps + nst - 1) / nst; } else { @@ -58,8 +58,7 @@ static int div_nsteps(int nsteps, int nst) } } -double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &groups, - int nrener, int nrepl) +double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& groups, int nrener, int nrepl) { int nsteps = ir->nsteps; @@ -75,8 +74,8 @@ double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &grou { for (int i = 0; i < natoms; i++) { - if (groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput].empty() || - groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput][i] == 0) + if (groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput].empty() + || groups.groupNumbers[SimulationAtomGroupType::CompressedPositionOutput][i] == 0) { nxtcatoms++; } @@ -84,14 +83,14 @@ double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &grou } nstlog = div_nsteps(nsteps, ir->nstlog); /* We add 2 for the header */ - nste = div_nsteps(2+nsteps, ir->nstenergy); + nste = div_nsteps(2 + nsteps, ir->nstenergy); - cio = 80*natoms; - cio += (nstx+nstf+nstv)*sizeof(real)*(3.0*natoms); - cio += nstxtc*(14*4 + nxtcatoms*5.0); /* roughly 5 bytes per atom */ - cio += nstlog*(nrener*16*2.0); /* 16 bytes per energy term plus header */ + cio = 80 * natoms; + cio += (nstx + nstf + nstv) * sizeof(real) * (3.0 * natoms); + cio += nstxtc * (14 * 4 + nxtcatoms * 5.0); /* roughly 5 bytes per atom */ + cio += nstlog * (nrener * 16 * 2.0); /* 16 bytes per energy term plus header */ /* t_energy contains doubles, but real is written to edr */ - cio += (1.0*nste)*nrener*3*sizeof(real); + cio += (1.0 * nste) * nrener * 3 * sizeof(real); if ((ir->efep != efepNO || ir->bSimTemp) && (ir->fepvals->nstdhdl > 0)) { @@ -109,24 +108,24 @@ double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &grou if (ir->fepvals->separate_dhdl_file == esepdhdlfileYES) { - nchars = 8 + ndhdl*8 + ndh*10; /* time data ~8 chars/entry, dH data ~10 chars/entry */ + nchars = 8 + ndhdl * 8 + ndh * 10; /* time data ~8 chars/entry, dH data ~10 chars/entry */ if (ir->expandedvals->elmcmove > elmcmoveNO) { - nchars += 5; /* alchemical state */ + nchars += 5; /* alchemical state */ } if (ir->fepvals->edHdLPrintEnergy != edHdLPrintEnergyNO) { nchars += 12; /* energy for dhdl */ } - cio += div_nsteps(nsteps, ir->fepvals->nstdhdl)*nchars; + cio += div_nsteps(nsteps, ir->fepvals->nstdhdl) * nchars; } else { /* dH output to ener.edr: */ if (ir->fepvals->dh_hist_size <= 0) { - int ndh_tot = ndh+ndhdl; + int ndh_tot = ndh + ndhdl; if (ir->expandedvals->elmcmove > elmcmoveNO) { ndh_tot += 1; @@ -136,21 +135,20 @@ double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &grou ndh_tot += 1; } /* as data blocks: 1 real per dH point */ - cio += div_nsteps(nsteps, ir->fepvals->nstdhdl)*ndh_tot*sizeof(real); + cio += div_nsteps(nsteps, ir->fepvals->nstdhdl) * ndh_tot * sizeof(real); } else { /* as histograms: dh_hist_size ints per histogram */ - cio += div_nsteps(nsteps, ir->nstenergy)* - sizeof(int)*ir->fepvals->dh_hist_size*ndh; + cio += div_nsteps(nsteps, ir->nstenergy) * sizeof(int) * ir->fepvals->dh_hist_size * ndh; } } } if (ir->pull != nullptr) { - cio += div_nsteps(nsteps, ir->pull->nstxout)*20; /* roughly 20 chars per line */ - cio += div_nsteps(nsteps, ir->pull->nstfout)*20; /* roughly 20 chars per line */ + cio += div_nsteps(nsteps, ir->pull->nstxout) * 20; /* roughly 20 chars per line */ + cio += div_nsteps(nsteps, ir->pull->nstfout) * 20; /* roughly 20 chars per line */ } - return cio*nrepl/(1024*1024); + return cio * nrepl / (1024 * 1024); } diff --git a/src/gromacs/mdlib/compute_io.h b/src/gromacs/mdlib/compute_io.h index dbe6159c67..05422822e9 100644 --- a/src/gromacs/mdlib/compute_io.h +++ b/src/gromacs/mdlib/compute_io.h @@ -41,8 +41,7 @@ struct SimulationGroups; struct t_inputrec; -double compute_io(const t_inputrec *ir, int natoms, const SimulationGroups &groups, - int nrener, int nrepl); +double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& groups, int nrener, int nrepl); /* Return total output to be written from this simulation. */ #endif diff --git a/src/gromacs/mdlib/constr.cpp b/src/gromacs/mdlib/constr.cpp index 79158dd8b4..eccc21f1f0 100644 --- a/src/gromacs/mdlib/constr.cpp +++ b/src/gromacs/mdlib/constr.cpp @@ -98,89 +98,88 @@ namespace gmx * correctly, however. */ class Constraints::Impl { - public: - Impl(const gmx_mtop_t &mtop_p, - const t_inputrec &ir_p, - pull_t *pull_work, - FILE *log_p, - const t_mdatoms &md_p, - const t_commrec *cr_p, - const gmx_multisim_t *ms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle_p, - bool pbcHandlingRequired, - int numConstraints, - int numSettles); - ~Impl(); - void setConstraints(const gmx_localtop_t &top, - const t_mdatoms &md); - bool apply(bool bLog, - bool bEner, - int64_t step, - int delta_step, - real step_scaling, - rvec *x, - rvec *xprime, - rvec *min_proj, - const matrix box, - real lambda, - real *dvdlambda, - rvec *v, - tensor *vir, - ConstraintVariable econq); - //! The total number of constraints. - int ncon_tot = 0; - //! The number of flexible constraints. - int nflexcon = 0; - //! A list of atoms to constraints for each moleculetype. - std::vector at2con_mt; - //! A list of atoms to settles for each moleculetype - std::vector < std::vector < int>> at2settle_mt; - //! LINCS data. - Lincs *lincsd = nullptr; // TODO this should become a unique_ptr - //! SHAKE data. - shakedata *shaked = nullptr; - //! SETTLE data. - settledata *settled = nullptr; - //! The maximum number of warnings. - int maxwarn = 0; - //! The number of warnings for LINCS. - int warncount_lincs = 0; - //! The number of warnings for SETTLE. - int warncount_settle = 0; - //! The essential dynamics data. - gmx_edsam * ed = nullptr; - - //! Thread-local virial contribution. - tensor *vir_r_m_dr_th = {nullptr}; - //! Did a settle error occur? - bool *bSettleErrorHasOccurred = nullptr; - - //! Pointer to the global topology - only used for printing warnings. - const gmx_mtop_t &mtop; - //! Parameters for the interactions in this domain. - const t_idef *idef = nullptr; - //! Data about atoms in this domain. - const t_mdatoms &md; - //! Whether we need to do pbc for handling bonds. - bool pbcHandlingRequired_ = false; - - //! Logging support. - FILE *log = nullptr; - //! Communication support. - const t_commrec *cr = nullptr; - //! Multi-sim support. - const gmx_multisim_t *ms = nullptr; - //! Pulling code object, if any. - pull_t *pull_work = nullptr; - /*!\brief Input options. - * - * \todo Replace with IMdpOptions */ - const t_inputrec &ir; - //! Flop counting support. - t_nrnb *nrnb = nullptr; - //! Tracks wallcycle usage. - gmx_wallcycle *wcycle; +public: + Impl(const gmx_mtop_t& mtop_p, + const t_inputrec& ir_p, + pull_t* pull_work, + FILE* log_p, + const t_mdatoms& md_p, + const t_commrec* cr_p, + const gmx_multisim_t* ms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle_p, + bool pbcHandlingRequired, + int numConstraints, + int numSettles); + ~Impl(); + void setConstraints(const gmx_localtop_t& top, const t_mdatoms& md); + bool apply(bool bLog, + bool bEner, + int64_t step, + int delta_step, + real step_scaling, + rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + real lambda, + real* dvdlambda, + rvec* v, + tensor* vir, + ConstraintVariable econq); + //! The total number of constraints. + int ncon_tot = 0; + //! The number of flexible constraints. + int nflexcon = 0; + //! A list of atoms to constraints for each moleculetype. + std::vector at2con_mt; + //! A list of atoms to settles for each moleculetype + std::vector> at2settle_mt; + //! LINCS data. + Lincs* lincsd = nullptr; // TODO this should become a unique_ptr + //! SHAKE data. + shakedata* shaked = nullptr; + //! SETTLE data. + settledata* settled = nullptr; + //! The maximum number of warnings. + int maxwarn = 0; + //! The number of warnings for LINCS. + int warncount_lincs = 0; + //! The number of warnings for SETTLE. + int warncount_settle = 0; + //! The essential dynamics data. + gmx_edsam* ed = nullptr; + + //! Thread-local virial contribution. + tensor* vir_r_m_dr_th = { nullptr }; + //! Did a settle error occur? + bool* bSettleErrorHasOccurred = nullptr; + + //! Pointer to the global topology - only used for printing warnings. + const gmx_mtop_t& mtop; + //! Parameters for the interactions in this domain. + const t_idef* idef = nullptr; + //! Data about atoms in this domain. + const t_mdatoms& md; + //! Whether we need to do pbc for handling bonds. + bool pbcHandlingRequired_ = false; + + //! Logging support. + FILE* log = nullptr; + //! Communication support. + const t_commrec* cr = nullptr; + //! Multi-sim support. + const gmx_multisim_t* ms = nullptr; + //! Pulling code object, if any. + pull_t* pull_work = nullptr; + /*!\brief Input options. + * + * \todo Replace with IMdpOptions */ + const t_inputrec& ir; + //! Flop counting support. + t_nrnb* nrnb = nullptr; + //! Tracks wallcycle usage. + gmx_wallcycle* wcycle; }; Constraints::~Constraints() = default; @@ -192,13 +191,12 @@ int Constraints::numFlexibleConstraints() const bool Constraints::havePerturbedConstraints() const { - const gmx_ffparams_t &ffparams = impl_->mtop.ffparams; + const gmx_ffparams_t& ffparams = impl_->mtop.ffparams; for (size_t i = 0; i < ffparams.functype.size(); i++) { - if ((ffparams.functype[i] == F_CONSTR || - ffparams.functype[i] == F_CONSTRNC) && - ffparams.iparams[i].constr.dA != ffparams.iparams[i].constr.dB) + if ((ffparams.functype[i] == F_CONSTR || ffparams.functype[i] == F_CONSTRNC) + && ffparams.iparams[i].constr.dA != ffparams.iparams[i].constr.dB) { return true; } @@ -208,7 +206,7 @@ bool Constraints::havePerturbedConstraints() const } //! Clears constraint quantities for atoms in nonlocal region. -static void clear_constraint_quantity_nonlocal(gmx_domdec_t *dd, rvec *q) +static void clear_constraint_quantity_nonlocal(gmx_domdec_t* dd, rvec* q) { int nonlocal_at_start, nonlocal_at_end, at; @@ -222,27 +220,31 @@ static void clear_constraint_quantity_nonlocal(gmx_domdec_t *dd, rvec *q) void too_many_constraint_warnings(int eConstrAlg, int warncount) { - gmx_fatal(FARGS, - "Too many %s warnings (%d)\n" - "If you know what you are doing you can %s" - "set the environment variable GMX_MAXCONSTRWARN to -1,\n" - "but normally it is better to fix the problem", - (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE", warncount, - (eConstrAlg == econtLINCS) ? - "adjust the lincs warning threshold in your mdp file\nor " : "\n"); + gmx_fatal( + FARGS, + "Too many %s warnings (%d)\n" + "If you know what you are doing you can %s" + "set the environment variable GMX_MAXCONSTRWARN to -1,\n" + "but normally it is better to fix the problem", + (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE", warncount, + (eConstrAlg == econtLINCS) ? "adjust the lincs warning threshold in your mdp file\nor " : "\n"); } //! Writes out coordinates. -static void write_constr_pdb(const char *fn, const char *title, - const gmx_mtop_t &mtop, - int start, int homenr, const t_commrec *cr, - const rvec x[], const matrix box) +static void write_constr_pdb(const char* fn, + const char* title, + const gmx_mtop_t& mtop, + int start, + int homenr, + const t_commrec* cr, + const rvec x[], + const matrix box) { char fname[STRLEN]; - FILE *out; + FILE* out; int dd_ac0 = 0, dd_ac1 = 0, i, ii, resnr; - gmx_domdec_t *dd; - const char *anm, *resnm; + gmx_domdec_t* dd; + const char * anm, *resnm; dd = nullptr; if (DOMAINDECOMP(cr)) @@ -267,7 +269,7 @@ static void write_constr_pdb(const char *fn, const char *title, fprintf(out, "TITLE %s\n", title); gmx_write_pdb_box(out, -1, box); int molb = 0; - for (i = start; i < start+homenr; i++) + for (i = start; i < start + homenr; i++) { if (dd != nullptr) { @@ -282,8 +284,8 @@ static void write_constr_pdb(const char *fn, const char *title, ii = i; } mtopGetAtomAndResidueName(mtop, ii, &molb, &anm, &resnr, &resnm, nullptr); - gmx_fprintf_pdb_atomline(out, epdbATOM, ii+1, anm, ' ', resnm, ' ', resnr, ' ', - 10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ], 1.0, 0.0, ""); + gmx_fprintf_pdb_atomline(out, epdbATOM, ii + 1, anm, ' ', resnm, ' ', resnr, ' ', + 10 * x[i][XX], 10 * x[i][YY], 10 * x[i][ZZ], 1.0, 0.0, ""); } fprintf(out, "TER\n"); @@ -291,24 +293,28 @@ static void write_constr_pdb(const char *fn, const char *title, } //! Writes out domain contents to help diagnose crashes. -static void dump_confs(FILE *log, int64_t step, const gmx_mtop_t &mtop, - int start, int homenr, const t_commrec *cr, - const rvec x[], rvec xprime[], const matrix box) +static void dump_confs(FILE* log, + int64_t step, + const gmx_mtop_t& mtop, + int start, + int homenr, + const t_commrec* cr, + const rvec x[], + rvec xprime[], + const matrix box) { - char buf[STRLEN], buf2[22]; + char buf[STRLEN], buf2[22]; - char *env = getenv("GMX_SUPPRESS_DUMP"); + char* env = getenv("GMX_SUPPRESS_DUMP"); if (env) { return; } sprintf(buf, "step%sb", gmx_step_str(step, buf2)); - write_constr_pdb(buf, "initial coordinates", - mtop, start, homenr, cr, x, box); + write_constr_pdb(buf, "initial coordinates", mtop, start, homenr, cr, x, box); sprintf(buf, "step%sc", gmx_step_str(step, buf2)); - write_constr_pdb(buf, "coordinates after constraining", - mtop, start, homenr, cr, xprime, box); + write_constr_pdb(buf, "coordinates after constraining", mtop, start, homenr, cr, xprime, box); if (log) { fprintf(log, "Wrote pdb files with previous and current coordinates\n"); @@ -316,69 +322,58 @@ static void dump_confs(FILE *log, int64_t step, const gmx_mtop_t &mtop, fprintf(stderr, "Wrote pdb files with previous and current coordinates\n"); } -bool -Constraints::apply(bool bLog, - bool bEner, - int64_t step, - int delta_step, - real step_scaling, - rvec *x, - rvec *xprime, - rvec *min_proj, - const matrix box, - real lambda, - real *dvdlambda, - rvec *v, - tensor *vir, - ConstraintVariable econq) +bool Constraints::apply(bool bLog, + bool bEner, + int64_t step, + int delta_step, + real step_scaling, + rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + real lambda, + real* dvdlambda, + rvec* v, + tensor* vir, + ConstraintVariable econq) { - return impl_->apply(bLog, - bEner, - step, - delta_step, - step_scaling, - x, - xprime, - min_proj, - box, - lambda, - dvdlambda, - v, - vir, - econq); + return impl_->apply(bLog, bEner, step, delta_step, step_scaling, x, xprime, min_proj, box, + lambda, dvdlambda, v, vir, econq); } -bool -Constraints::Impl::apply(bool bLog, - bool bEner, - int64_t step, - int delta_step, - real step_scaling, - rvec *x, - rvec *xprime, - rvec *min_proj, - const matrix box, - real lambda, - real *dvdlambda, - rvec *v, - tensor *vir, - ConstraintVariable econq) +bool Constraints::Impl::apply(bool bLog, + bool bEner, + int64_t step, + int delta_step, + real step_scaling, + rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + real lambda, + real* dvdlambda, + rvec* v, + tensor* vir, + ConstraintVariable econq) { - bool bOK, bDump; - int start, homenr; - tensor vir_r_m_dr; - real scaled_delta_t; - real invdt, vir_fac = 0, t; - int nsettle; - t_pbc pbc, *pbc_null; - char buf[22]; - int nth; + bool bOK, bDump; + int start, homenr; + tensor vir_r_m_dr; + real scaled_delta_t; + real invdt, vir_fac = 0, t; + int nsettle; + t_pbc pbc, *pbc_null; + char buf[22]; + int nth; wallcycle_start(wcycle, ewcCONSTR); if (econq == ConstraintVariable::ForceDispl && !EI_ENERGY_MINIMIZATION(ir.eI)) { - gmx_incons("constrain called for forces displacements while not doing energy minimization, can not do this while the LINCS and SETTLE constraint connection matrices are mass weighted"); + gmx_incons( + "constrain called for forces displacements while not doing energy minimization, " + "can not do this while the LINCS and SETTLE constraint connection matrices are " + "mass weighted"); } bOK = TRUE; @@ -397,7 +392,7 @@ Constraints::Impl::apply(bool bLog, } else { - invdt = 1.0/scaled_delta_t; + invdt = 1.0 / scaled_delta_t; } if (ir.efep != efepNO && EI_DYNAMICS(ir.eI)) @@ -405,15 +400,15 @@ Constraints::Impl::apply(bool bLog, /* Set the constraint lengths for the step at which this configuration * is meant to be. The invmasses should not be changed. */ - lambda += delta_step*ir.fepvals->delta_lambda; + lambda += delta_step * ir.fepvals->delta_lambda; } if (vir != nullptr) { clear_mat(vir_r_m_dr); } - const t_ilist *settle = &idef->il[F_SETTLE]; - nsettle = settle->nr/(1+NRAL(F_SETTLE)); + const t_ilist* settle = &idef->il[F_SETTLE]; + nsettle = settle->nr / (1 + NRAL(F_SETTLE)); if (nsettle > 0) { @@ -429,16 +424,14 @@ Constraints::Impl::apply(bool bLog, * Note that PBC for constraints is different from PBC for bondeds. * For constraints there is both forward and backward communication. */ - if (ir.ePBC != epbcNONE && - (cr->dd || pbcHandlingRequired_) && !(cr->dd && cr->dd->constraint_comm == nullptr)) + if (ir.ePBC != epbcNONE && (cr->dd || pbcHandlingRequired_) + && !(cr->dd && cr->dd->constraint_comm == nullptr)) { /* With pbc=screw the screw has been changed to a shift * by the constraint coordinate communication routine, * so that here we can use normal pbc. */ - pbc_null = set_pbc_dd(&pbc, ir.ePBC, - DOMAINDECOMP(cr) ? cr->dd->nc : nullptr, - FALSE, box); + pbc_null = set_pbc_dd(&pbc, ir.ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : nullptr, FALSE, box); } else { @@ -464,12 +457,9 @@ Constraints::Impl::apply(bool bLog, if (lincsd != nullptr) { - bOK = constrain_lincs(bLog || bEner, ir, step, lincsd, md, cr, ms, - x, xprime, min_proj, - box, pbc_null, lambda, dvdlambda, - invdt, v, vir != nullptr, vir_r_m_dr, - econq, nrnb, - maxwarn, &warncount_lincs); + bOK = constrain_lincs(bLog || bEner, ir, step, lincsd, md, cr, ms, x, xprime, min_proj, box, + pbc_null, lambda, dvdlambda, invdt, v, vir != nullptr, vir_r_m_dr, + econq, nrnb, maxwarn, &warncount_lincs); if (!bOK && maxwarn < INT_MAX) { if (log != nullptr) @@ -483,12 +473,8 @@ Constraints::Impl::apply(bool bLog, if (shaked != nullptr) { - bOK = constrain_shake(log, shaked, - md.invmass, - *idef, ir, x, xprime, min_proj, nrnb, - lambda, dvdlambda, - invdt, v, vir != nullptr, vir_r_m_dr, - maxwarn < INT_MAX, econq); + bOK = constrain_shake(log, shaked, md.invmass, *idef, ir, x, xprime, min_proj, nrnb, lambda, + dvdlambda, invdt, v, vir != nullptr, vir_r_m_dr, maxwarn < INT_MAX, econq); if (!bOK && maxwarn < INT_MAX) { @@ -518,25 +504,20 @@ Constraints::Impl::apply(bool bLog, clear_mat(vir_r_m_dr_th[th]); } - csettle(settled, - nth, th, - pbc_null, - x[0], xprime[0], - invdt, v ? v[0] : nullptr, - vir != nullptr, - th == 0 ? vir_r_m_dr : vir_r_m_dr_th[th], + csettle(settled, nth, th, pbc_null, x[0], xprime[0], invdt, v ? v[0] : nullptr, + vir != nullptr, th == 0 ? vir_r_m_dr : vir_r_m_dr_th[th], th == 0 ? &bSettleErrorHasOccurred0 : &bSettleErrorHasOccurred[th]); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } inc_nrnb(nrnb, eNR_SETTLE, nsettle); if (v != nullptr) { - inc_nrnb(nrnb, eNR_CONSTR_V, nsettle*3); + inc_nrnb(nrnb, eNR_CONSTR_V, nsettle * 3); } if (vir != nullptr) { - inc_nrnb(nrnb, eNR_CONSTR_VIR, nsettle*3); + inc_nrnb(nrnb, eNR_CONSTR_VIR, nsettle * 3); } break; case ConstraintVariable::Velocities: @@ -564,21 +545,18 @@ Constraints::Impl::apply(bool bLog, clear_mat(vir_r_m_dr_th[th]); } - int start_th = (nsettle* th )/nth; - int end_th = (nsettle*(th+1))/nth; + int start_th = (nsettle * th) / nth; + int end_th = (nsettle * (th + 1)) / nth; if (start_th >= 0 && end_th - start_th > 0) { - settle_proj(settled, econq, - end_th-start_th, - settle->iatoms+start_th*(1+NRAL(F_SETTLE)), - pbc_null, - x, - xprime, min_proj, calcvir_atom_end, + settle_proj(settled, econq, end_th - start_th, + settle->iatoms + start_th * (1 + NRAL(F_SETTLE)), pbc_null, + x, xprime, min_proj, calcvir_atom_end, th == 0 ? vir_r_m_dr : vir_r_m_dr_th[th]); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* This is an overestimate */ inc_nrnb(nrnb, eNR_SETTLE, nsettle); @@ -586,8 +564,7 @@ Constraints::Impl::apply(bool bLog, case ConstraintVariable::Deriv_FlexCon: /* Nothing to do, since the are no flexible constraints in settles */ break; - default: - gmx_incons("Unknown constraint quantity for settle"); + default: gmx_incons("Unknown constraint quantity for settle"); } if (vir != nullptr) @@ -610,7 +587,9 @@ Constraints::Impl::apply(bool bLog, { char buf[STRLEN]; sprintf(buf, - "\nstep " "%" PRId64 ": One or more water molecules can not be settled.\n" + "\nstep " + "%" PRId64 + ": One or more water molecules can not be settled.\n" "Check for bad contacts and/or reduce the timestep if appropriate.\n", step); if (log) @@ -625,7 +604,7 @@ Constraints::Impl::apply(bool bLog, } bDump = TRUE; - bOK = FALSE; + bOK = FALSE; } } } @@ -642,29 +621,22 @@ Constraints::Impl::apply(bool bLog, assert(gmx_within_tol(step_scaling, 1.0, GMX_REAL_EPS)); switch (econq) { - case ConstraintVariable::Positions: - vir_fac = 0.5/(ir.delta_t*ir.delta_t); - break; - case ConstraintVariable::Velocities: - vir_fac = 0.5/ir.delta_t; - break; + case ConstraintVariable::Positions: vir_fac = 0.5 / (ir.delta_t * ir.delta_t); break; + case ConstraintVariable::Velocities: vir_fac = 0.5 / ir.delta_t; break; case ConstraintVariable::Force: - case ConstraintVariable::ForceDispl: - vir_fac = 0.5; - break; - default: - gmx_incons("Unsupported constraint quantity for virial"); + case ConstraintVariable::ForceDispl: vir_fac = 0.5; break; + default: gmx_incons("Unsupported constraint quantity for virial"); } if (EI_VV(ir.eI)) { - vir_fac *= 2; /* only constraining over half the distance here */ + vir_fac *= 2; /* only constraining over half the distance here */ } for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - (*vir)[i][j] = vir_fac*vir_r_m_dr[i][j]; + (*vir)[i][j] = vir_fac * vir_r_m_dr[i][j]; } } } @@ -680,7 +652,7 @@ Constraints::Impl::apply(bool bLog, { if (EI_DYNAMICS(ir.eI)) { - t = ir.init_t + (step + delta_step)*ir.delta_t; + t = ir.init_t + (step + delta_step) * ir.delta_t; } else { @@ -770,29 +742,29 @@ FlexibleConstraintTreatment flexibleConstraintTreatment(bool haveDynamicsIntegra * * \param[in] numAtoms The number of atoms to construct the list for * \param[in] ilists The interaction lists, size F_NRE - * \param[in] iparams Interaction parameters, can be null when flexibleConstraintTreatment=Include - * \param[in] flexibleConstraintTreatment The flexible constraint treatment, see enum above - * \returns a block struct with all constraints for each atom + * \param[in] iparams Interaction parameters, can be null when + * flexibleConstraintTreatment=Include \param[in] flexibleConstraintTreatment The flexible + * constraint treatment, see enum above \returns a block struct with all constraints for each atom */ -template -static t_blocka -makeAtomsToConstraintsList(int numAtoms, - const T *ilists, - const t_iparams *iparams, - FlexibleConstraintTreatment flexibleConstraintTreatment) +template +static t_blocka makeAtomsToConstraintsList(int numAtoms, + const T* ilists, + const t_iparams* iparams, + FlexibleConstraintTreatment flexibleConstraintTreatment) { - GMX_ASSERT(flexibleConstraintTreatment == FlexibleConstraintTreatment::Include || iparams != nullptr, "With flexible constraint detection we need valid iparams"); + GMX_ASSERT(flexibleConstraintTreatment == FlexibleConstraintTreatment::Include || iparams != nullptr, + "With flexible constraint detection we need valid iparams"); std::vector count(numAtoms); for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++) { - const T &ilist = ilists[ftype]; - const int stride = 1 + NRAL(ftype); + const T& ilist = ilists[ftype]; + const int stride = 1 + NRAL(ftype); for (int i = 0; i < ilist.size(); i += stride) { - if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include || - !isConstraintFlexible(iparams, ilist.iatoms[i])) + if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include + || !isConstraintFlexible(iparams, ilist.iatoms[i])) { for (int j = 1; j < 3; j++) { @@ -823,16 +795,16 @@ makeAtomsToConstraintsList(int numAtoms, int numConstraints = 0; for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++) { - const T &ilist = ilists[ftype]; - const int stride = 1 + NRAL(ftype); + const T& ilist = ilists[ftype]; + const int stride = 1 + NRAL(ftype); for (int i = 0; i < ilist.size(); i += stride) { - if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include || - !isConstraintFlexible(iparams, ilist.iatoms[i])) + if (flexibleConstraintTreatment == FlexibleConstraintTreatment::Include + || !isConstraintFlexible(iparams, ilist.iatoms[i])) { for (int j = 1; j < 3; j++) { - int a = ilist.iatoms[i + j]; + int a = ilist.iatoms[i + j]; at2con.a[at2con.index[a] + count[a]++] = numConstraints; } } @@ -843,26 +815,25 @@ makeAtomsToConstraintsList(int numAtoms, return at2con; } -t_blocka make_at2con(int numAtoms, - const t_ilist *ilist, - const t_iparams *iparams, - FlexibleConstraintTreatment flexibleConstraintTreatment) +t_blocka make_at2con(int numAtoms, + const t_ilist* ilist, + const t_iparams* iparams, + FlexibleConstraintTreatment flexibleConstraintTreatment) { return makeAtomsToConstraintsList(numAtoms, ilist, iparams, flexibleConstraintTreatment); } -t_blocka make_at2con(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams, - FlexibleConstraintTreatment flexibleConstraintTreatment) +t_blocka make_at2con(const gmx_moltype_t& moltype, + gmx::ArrayRef iparams, + FlexibleConstraintTreatment flexibleConstraintTreatment) { - return makeAtomsToConstraintsList(moltype.atoms.nr, moltype.ilist.data(), iparams.data(), flexibleConstraintTreatment); + return makeAtomsToConstraintsList(moltype.atoms.nr, moltype.ilist.data(), iparams.data(), + flexibleConstraintTreatment); } //! Return the number of flexible constraints in the \c ilist and \c iparams. -template -static int -countFlexibleConstraintsTemplate(const T *ilist, - const t_iparams *iparams) +template +static int countFlexibleConstraintsTemplate(const T* ilist, const t_iparams* iparams) { int nflexcon = 0; for (int ftype = F_CONSTR; ftype <= F_CONSTRNC; ftype++) @@ -871,8 +842,7 @@ countFlexibleConstraintsTemplate(const T *ilist, for (int i = 0; i < ilist[ftype].size(); i += numIatomsPerConstraint) { const int type = ilist[ftype].iatoms[i]; - if (iparams[type].constr.dA == 0 && - iparams[type].constr.dB == 0) + if (iparams[type].constr.dA == 0 && iparams[type].constr.dB == 0) { nflexcon++; } @@ -882,34 +852,30 @@ countFlexibleConstraintsTemplate(const T *ilist, return nflexcon; } -int countFlexibleConstraints(const t_ilist *ilist, - const t_iparams *iparams) +int countFlexibleConstraints(const t_ilist* ilist, const t_iparams* iparams) { return countFlexibleConstraintsTemplate(ilist, iparams); } //! Returns the index of the settle to which each atom belongs. -static std::vector make_at2settle(int natoms, - const InteractionList &ilist) +static std::vector make_at2settle(int natoms, const InteractionList& ilist) { /* Set all to no settle */ std::vector at2s(natoms, -1); - const int stride = 1 + NRAL(F_SETTLE); + const int stride = 1 + NRAL(F_SETTLE); for (int s = 0; s < ilist.size(); s += stride) { - at2s[ilist.iatoms[s + 1]] = s/stride; - at2s[ilist.iatoms[s + 2]] = s/stride; - at2s[ilist.iatoms[s + 3]] = s/stride; + at2s[ilist.iatoms[s + 1]] = s / stride; + at2s[ilist.iatoms[s + 2]] = s / stride; + at2s[ilist.iatoms[s + 3]] = s / stride; } return at2s; } -void -Constraints::Impl::setConstraints(const gmx_localtop_t &top, - const t_mdatoms &md) +void Constraints::Impl::setConstraints(const gmx_localtop_t& top, const t_mdatoms& md) { idef = &top.idef; @@ -939,8 +905,7 @@ Constraints::Impl::setConstraints(const gmx_localtop_t &top, if (settled) { - settle_set_constraints(settled, - &idef->il[F_SETTLE], md); + settle_set_constraints(settled, &idef->il[F_SETTLE], md); } /* Make a selection of the local atoms for essential dynamics */ @@ -950,9 +915,7 @@ Constraints::Impl::setConstraints(const gmx_localtop_t &top, } } -void -Constraints::setConstraints(const gmx_localtop_t &top, - const t_mdatoms &md) +void Constraints::setConstraints(const gmx_localtop_t& top, const t_mdatoms& md) { impl_->setConstraints(top, md); } @@ -961,71 +924,57 @@ Constraints::setConstraints(const gmx_localtop_t &top, * indices to constraint indices. * * Note that flexible constraints are only enabled with a dynamical integrator. */ -static std::vector -makeAtomToConstraintMappings(const gmx_mtop_t &mtop, - FlexibleConstraintTreatment flexibleConstraintTreatment) +static std::vector makeAtomToConstraintMappings(const gmx_mtop_t& mtop, + FlexibleConstraintTreatment flexibleConstraintTreatment) { std::vector mapping; mapping.reserve(mtop.moltype.size()); - for (const gmx_moltype_t &moltype : mtop.moltype) + for (const gmx_moltype_t& moltype : mtop.moltype) { - mapping.push_back(make_at2con(moltype, - mtop.ffparams.iparams, - flexibleConstraintTreatment)); + mapping.push_back(make_at2con(moltype, mtop.ffparams.iparams, flexibleConstraintTreatment)); } return mapping; } -Constraints::Constraints(const gmx_mtop_t &mtop, - const t_inputrec &ir, - pull_t *pull_work, - FILE *log, - const t_mdatoms &md, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, +Constraints::Constraints(const gmx_mtop_t& mtop, + const t_inputrec& ir, + pull_t* pull_work, + FILE* log, + const t_mdatoms& md, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, bool pbcHandlingRequired, int numConstraints, - int numSettles) - : impl_(new Impl(mtop, - ir, - pull_work, - log, - md, - cr, - ms, - nrnb, - wcycle, - pbcHandlingRequired, - numConstraints, - numSettles)) + int numSettles) : + impl_(new Impl(mtop, ir, pull_work, log, md, cr, ms, nrnb, wcycle, pbcHandlingRequired, numConstraints, numSettles)) { } -Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, - const t_inputrec &ir_p, - pull_t *pull_work, - FILE *log_p, - const t_mdatoms &md_p, - const t_commrec *cr_p, - const gmx_multisim_t *ms_p, - t_nrnb *nrnb_p, - gmx_wallcycle *wcycle_p, +Constraints::Impl::Impl(const gmx_mtop_t& mtop_p, + const t_inputrec& ir_p, + pull_t* pull_work, + FILE* log_p, + const t_mdatoms& md_p, + const t_commrec* cr_p, + const gmx_multisim_t* ms_p, + t_nrnb* nrnb_p, + gmx_wallcycle* wcycle_p, bool pbcHandlingRequired, int numConstraints, - int numSettles) - : ncon_tot(numConstraints), - mtop(mtop_p), - md(md_p), - pbcHandlingRequired_(pbcHandlingRequired), - log(log_p), - cr(cr_p), - ms(ms_p), - pull_work(pull_work), - ir(ir_p), - nrnb(nrnb_p), - wcycle(wcycle_p) + int numSettles) : + ncon_tot(numConstraints), + mtop(mtop_p), + md(md_p), + pbcHandlingRequired_(pbcHandlingRequired), + log(log_p), + cr(cr_p), + ms(ms_p), + pull_work(pull_work), + ir(ir_p), + nrnb(nrnb_p), + wcycle(wcycle_p) { if (numConstraints + numSettles > 0 && ir.epc == epcMTTK) { @@ -1035,29 +984,28 @@ Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, nflexcon = 0; if (numConstraints > 0) { - at2con_mt = makeAtomToConstraintMappings(mtop, - flexibleConstraintTreatment(EI_DYNAMICS(ir.eI))); + at2con_mt = makeAtomToConstraintMappings(mtop, flexibleConstraintTreatment(EI_DYNAMICS(ir.eI))); - for (const gmx_molblock_t &molblock : mtop.molblock) + for (const gmx_molblock_t& molblock : mtop.molblock) { - int count = - countFlexibleConstraintsTemplate(mtop.moltype[molblock.type].ilist.data(), - mtop.ffparams.iparams.data()); - nflexcon += molblock.nmol*count; + int count = countFlexibleConstraintsTemplate(mtop.moltype[molblock.type].ilist.data(), + mtop.ffparams.iparams.data()); + nflexcon += molblock.nmol * count; } if (nflexcon > 0) { if (log) { - fprintf(log, "There are %d flexible constraints\n", - nflexcon); + fprintf(log, "There are %d flexible constraints\n", nflexcon); if (ir.fc_stepsize == 0) { - fprintf(log, "\n" + fprintf(log, + "\n" "WARNING: step size for flexible constraining = 0\n" " All flexible constraints will be rigid.\n" - " Will try to keep all flexible constraints at their original length,\n" + " Will try to keep all flexible constraints at their original " + "length,\n" " but the lengths may exhibit some drift.\n\n"); nflexcon = 0; } @@ -1070,21 +1018,24 @@ Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, if (ir.eConstrAlg == econtLINCS) { - lincsd = init_lincs(log, mtop, - nflexcon, at2con_mt, - DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd), - ir.nLincsIter, ir.nProjOrder); + lincsd = init_lincs(log, mtop, nflexcon, at2con_mt, + DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd), ir.nLincsIter, + ir.nProjOrder); } if (ir.eConstrAlg == econtSHAKE) { if (DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd)) { - gmx_fatal(FARGS, "SHAKE is not supported with domain decomposition and constraint that cross domain boundaries, use LINCS"); + gmx_fatal(FARGS, + "SHAKE is not supported with domain decomposition and constraint that " + "cross domain boundaries, use LINCS"); } if (nflexcon) { - gmx_fatal(FARGS, "For this system also velocities and/or forces need to be constrained, this can not be done with SHAKE, you should select LINCS"); + gmx_fatal(FARGS, + "For this system also velocities and/or forces need to be constrained, " + "this can not be done with SHAKE, you should select LINCS"); } please_cite(log, "Ryckaert77a"); if (ir.bShakeSOR) @@ -1100,13 +1051,13 @@ Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, { please_cite(log, "Miyamoto92a"); - settled = settle_init(mtop); + settled = settle_init(mtop); /* Make an atom to settle index for use in domain decomposition */ for (size_t mt = 0; mt < mtop.moltype.size(); mt++) { - at2settle_mt.emplace_back(make_at2settle(mtop.moltype[mt].atoms.nr, - mtop.moltype[mt].ilist[F_SETTLE])); + at2settle_mt.emplace_back( + make_at2settle(mtop.moltype[mt].atoms.nr, mtop.moltype[mt].ilist[F_SETTLE])); } /* Allocate thread-local work arrays */ @@ -1118,8 +1069,8 @@ Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, } } - maxwarn = 999; - char *env = getenv("GMX_MAXCONSTRWARN"); + maxwarn = 999; + char* env = getenv("GMX_MAXCONSTRWARN"); if (env) { maxwarn = 0; @@ -1130,15 +1081,11 @@ Constraints::Impl::Impl(const gmx_mtop_t &mtop_p, } if (log) { - fprintf(log, - "Setting the maximum number of constraint warnings to %d\n", - maxwarn); + fprintf(log, "Setting the maximum number of constraint warnings to %d\n", maxwarn); } if (MASTER(cr)) { - fprintf(stderr, - "Setting the maximum number of constraint warnings to %d\n", - maxwarn); + fprintf(stderr, "Setting the maximum number of constraint warnings to %d\n", maxwarn); } } warncount_lincs = 0; @@ -1166,38 +1113,39 @@ Constraints::Impl::~Impl() done_lincs(lincsd); } -void Constraints::saveEdsamPointer(gmx_edsam * ed) +void Constraints::saveEdsamPointer(gmx_edsam* ed) { impl_->ed = ed; } -ArrayRef -Constraints::atom2constraints_moltype() const +ArrayRef Constraints::atom2constraints_moltype() const { return impl_->at2con_mt; } -ArrayRef < const std::vector < int>> Constraints::atom2settle_moltype() const +ArrayRef> Constraints::atom2settle_moltype() const { return impl_->at2settle_mt; } -void do_constrain_first(FILE *fplog, gmx::Constraints *constr, - const t_inputrec *ir, const t_mdatoms *md, - int natoms, +void do_constrain_first(FILE* fplog, + gmx::Constraints* constr, + const t_inputrec* ir, + const t_mdatoms* md, + int natoms, ArrayRefWithPadding x, ArrayRefWithPadding v, - const matrix box, - real lambda) + const matrix box, + real lambda) { - int i, m, start, end; - int64_t step; - real dt = ir->delta_t; - real dvdl_dum; - rvec *savex; + int i, m, start, end; + int64_t step; + real dt = ir->delta_t; + real dvdl_dum; + rvec* savex; - auto xRvec = as_rvec_array(x.paddedArrayRef().data()); - auto vRvec = as_rvec_array(v.paddedArrayRef().data()); + auto xRvec = as_rvec_array(x.paddedArrayRef().data()); + auto vRvec = as_rvec_array(v.paddedArrayRef().data()); /* We need to allocate one element extra, since we might use * (unaligned) 4-wide SIMD loads to access rvec entries. @@ -1209,35 +1157,25 @@ void do_constrain_first(FILE *fplog, gmx::Constraints *constr, if (debug) { - fprintf(debug, "vcm: start=%d, homenr=%d, end=%d\n", - start, md->homenr, end); + fprintf(debug, "vcm: start=%d, homenr=%d, end=%d\n", start, md->homenr, end); } /* Do a first constrain to reset particles... */ step = ir->init_step; if (fplog) { char buf[STEPSTRSIZE]; - fprintf(fplog, "\nConstraining the starting coordinates (step %s)\n", - gmx_step_str(step, buf)); + fprintf(fplog, "\nConstraining the starting coordinates (step %s)\n", gmx_step_str(step, buf)); } dvdl_dum = 0; /* constrain the current position */ - constr->apply(TRUE, FALSE, - step, 0, 1.0, - xRvec, xRvec, nullptr, - box, - lambda, &dvdl_dum, - nullptr, nullptr, gmx::ConstraintVariable::Positions); + constr->apply(TRUE, FALSE, step, 0, 1.0, xRvec, xRvec, nullptr, box, lambda, &dvdl_dum, nullptr, + nullptr, gmx::ConstraintVariable::Positions); if (EI_VV(ir->eI)) { /* constrain the inital velocity, and save it */ /* also may be useful if we need the ekin from the halfstep for velocity verlet */ - constr->apply(TRUE, FALSE, - step, 0, 1.0, - xRvec, vRvec, vRvec, - box, - lambda, &dvdl_dum, + constr->apply(TRUE, FALSE, step, 0, 1.0, xRvec, vRvec, vRvec, box, lambda, &dvdl_dum, nullptr, nullptr, gmx::ConstraintVariable::Velocities); } /* constrain the inital velocities at t-dt/2 */ @@ -1252,7 +1190,7 @@ void do_constrain_first(FILE *fplog, gmx::Constraints *constr, /* Reverse the velocity */ subV[i][m] = -subV[i][m]; /* Store the position at t-dt in buf */ - savex[i][m] = subX[i][m] + dt*subV[i][m]; + savex[i][m] = subX[i][m] + dt * subV[i][m]; } } /* Shake the positions at t=-dt with the positions at t=0 @@ -1261,15 +1199,10 @@ void do_constrain_first(FILE *fplog, gmx::Constraints *constr, if (fplog) { char buf[STEPSTRSIZE]; - fprintf(fplog, "\nConstraining the coordinates at t0-dt (step %s)\n", - gmx_step_str(step, buf)); + fprintf(fplog, "\nConstraining the coordinates at t0-dt (step %s)\n", gmx_step_str(step, buf)); } dvdl_dum = 0; - constr->apply(TRUE, FALSE, - step, -1, 1.0, - xRvec, savex, nullptr, - box, - lambda, &dvdl_dum, + constr->apply(TRUE, FALSE, step, -1, 1.0, xRvec, savex, nullptr, box, lambda, &dvdl_dum, vRvec, nullptr, gmx::ConstraintVariable::Positions); for (i = start; i < end; i++) @@ -1284,4 +1217,4 @@ void do_constrain_first(FILE *fplog, gmx::Constraints *constr, sfree(savex); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/constr.h b/src/gromacs/mdlib/constr.h index cb5a0d8aeb..2ddc2704d1 100644 --- a/src/gromacs/mdlib/constr.h +++ b/src/gromacs/mdlib/constr.h @@ -74,149 +74,148 @@ class t_state; namespace gmx { -template class ArrayRefWithPadding; +template +class ArrayRefWithPadding; //! Describes supported flavours of constrained updates. enum class ConstraintVariable : int { - Positions, /* Constrain positions (mass weighted) */ - Velocities, /* Constrain velocities (mass weighted) */ - Derivative, /* Constrain a derivative (mass weighted), * - * for instance velocity or acceleration, * - * constraint virial can not be calculated. */ - Deriv_FlexCon, /* As Derivative, but only output flex. con. */ - Force, /* Constrain forces (non mass-weighted) */ + Positions, /* Constrain positions (mass weighted) */ + Velocities, /* Constrain velocities (mass weighted) */ + Derivative, /* Constrain a derivative (mass weighted), * + * for instance velocity or acceleration, * + * constraint virial can not be calculated. */ + Deriv_FlexCon, /* As Derivative, but only output flex. con. */ + Force, /* Constrain forces (non mass-weighted) */ // TODO What does this do? Improve the comment. - ForceDispl /* Like Force, but free particles will have mass - * 1 and frozen particles mass 0 */ + ForceDispl /* Like Force, but free particles will have mass + * 1 and frozen particles mass 0 */ }; /*! \libinternal * \brief Handles constraints */ class Constraints { - private: - /*! \brief Constructor - * - * Private to enforce use of makeConstraints() factory - * function. */ - Constraints(const gmx_mtop_t &mtop, - const t_inputrec &ir, - pull_t *pull_work, - FILE *log, - const t_mdatoms &md, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - bool pbcHandlingRequired, - int numConstraints, - int numSettles); - public: - /*! \brief This member type helps implement a factory - * function, because its objects can access the private - * constructor. */ - struct CreationHelper; - - ~Constraints(); - - /*! \brief Returns the total number of flexible constraints in the system. */ - int numFlexibleConstraints() const; - - /*! \brief Returns whether the system contains perturbed constraints */ - bool havePerturbedConstraints() const; - - /*! \brief Set up all the local constraints for the domain. - * - * \todo Make this a callback that is called automatically - * once a new domain has been made. */ - void setConstraints(const gmx_localtop_t &top, - const t_mdatoms &md); - - /*! \brief Applies constraints to coordinates. - * - * When econq=ConstraintVariable::Positions constrains - * coordinates xprime using th directions in x, min_proj is - * not used. - * - * When econq=ConstraintVariable::Derivative, calculates the - * components xprime in the constraint directions and - * subtracts these components from min_proj. So when - * min_proj=xprime, the constraint components are projected - * out. - * - * When econq=ConstraintVariable::Deriv_FlexCon, the same is - * done as with ConstraintVariable::Derivative, but only the - * components of the flexible constraints are stored. - * - * delta_step is used for determining the constraint reference lengths - * when lenA != lenB or will the pull code with a pulling rate. - * step + delta_step is the step at which the final configuration - * is meant to be; for update delta_step = 1. - * - * step_scaling can be used to update coordinates based on the time - * step multiplied by this factor. Thus, normally 1.0 is passed. The - * SD1 integrator uses 0.5 in one of its calls, to correct positions - * for half a step of changed velocities. - * - * If v!=NULL also constrain v by adding the constraint corrections / dt. - * - * If vir!=NULL calculate the constraint virial. - * - * Return whether the application of constraints succeeded without error. - */ - bool apply(bool bLog, - bool bEner, - int64_t step, - int delta_step, - real step_scaling, - rvec *x, - rvec *xprime, - rvec *min_proj, - const matrix box, - real lambda, - real *dvdlambda, - rvec *v, - tensor *vir, - ConstraintVariable econq); - //! Links the essentialdynamics and constraint code. - void saveEdsamPointer(gmx_edsam *ed); - //! Getter for use by domain decomposition. - ArrayRef atom2constraints_moltype() const; - //! Getter for use by domain decomposition. - ArrayRef < const std::vector < int>> atom2settle_moltype() const; - - /*! \brief Return the data for reduction for determining - * constraint RMS relative deviations, or an empty ArrayRef - * when not supported for any active constraints. */ - ArrayRef rmsdData() const; - /*! \brief Return the RMSD of the constraints when available. */ - real rmsd() const; - - /*! \brief Get the total number of constraints. - * - * \returns Total number of constraints, including SETTLE and LINCS/SHAKE constraints. - */ - int numConstraintsTotal(); - - private: - //! Implementation type. - class Impl; - //! Implementation object. - PrivateImplPointer impl_; +private: + /*! \brief Constructor + * + * Private to enforce use of makeConstraints() factory + * function. */ + Constraints(const gmx_mtop_t& mtop, + const t_inputrec& ir, + pull_t* pull_work, + FILE* log, + const t_mdatoms& md, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + bool pbcHandlingRequired, + int numConstraints, + int numSettles); + +public: + /*! \brief This member type helps implement a factory + * function, because its objects can access the private + * constructor. */ + struct CreationHelper; + + ~Constraints(); + + /*! \brief Returns the total number of flexible constraints in the system. */ + int numFlexibleConstraints() const; + + /*! \brief Returns whether the system contains perturbed constraints */ + bool havePerturbedConstraints() const; + + /*! \brief Set up all the local constraints for the domain. + * + * \todo Make this a callback that is called automatically + * once a new domain has been made. */ + void setConstraints(const gmx_localtop_t& top, const t_mdatoms& md); + + /*! \brief Applies constraints to coordinates. + * + * When econq=ConstraintVariable::Positions constrains + * coordinates xprime using th directions in x, min_proj is + * not used. + * + * When econq=ConstraintVariable::Derivative, calculates the + * components xprime in the constraint directions and + * subtracts these components from min_proj. So when + * min_proj=xprime, the constraint components are projected + * out. + * + * When econq=ConstraintVariable::Deriv_FlexCon, the same is + * done as with ConstraintVariable::Derivative, but only the + * components of the flexible constraints are stored. + * + * delta_step is used for determining the constraint reference lengths + * when lenA != lenB or will the pull code with a pulling rate. + * step + delta_step is the step at which the final configuration + * is meant to be; for update delta_step = 1. + * + * step_scaling can be used to update coordinates based on the time + * step multiplied by this factor. Thus, normally 1.0 is passed. The + * SD1 integrator uses 0.5 in one of its calls, to correct positions + * for half a step of changed velocities. + * + * If v!=NULL also constrain v by adding the constraint corrections / dt. + * + * If vir!=NULL calculate the constraint virial. + * + * Return whether the application of constraints succeeded without error. + */ + bool apply(bool bLog, + bool bEner, + int64_t step, + int delta_step, + real step_scaling, + rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + real lambda, + real* dvdlambda, + rvec* v, + tensor* vir, + ConstraintVariable econq); + //! Links the essentialdynamics and constraint code. + void saveEdsamPointer(gmx_edsam* ed); + //! Getter for use by domain decomposition. + ArrayRef atom2constraints_moltype() const; + //! Getter for use by domain decomposition. + ArrayRef> atom2settle_moltype() const; + + /*! \brief Return the data for reduction for determining + * constraint RMS relative deviations, or an empty ArrayRef + * when not supported for any active constraints. */ + ArrayRef rmsdData() const; + /*! \brief Return the RMSD of the constraints when available. */ + real rmsd() const; + + /*! \brief Get the total number of constraints. + * + * \returns Total number of constraints, including SETTLE and LINCS/SHAKE constraints. + */ + int numConstraintsTotal(); + +private: + //! Implementation type. + class Impl; + //! Implementation object. + PrivateImplPointer impl_; }; /*! \brief Generate a fatal error because of too many LINCS/SETTLE warnings. */ -[[ noreturn ]] void too_many_constraint_warnings(int eConstrAlg, int warncount); +[[noreturn]] void too_many_constraint_warnings(int eConstrAlg, int warncount); /*! \brief Returns whether constraint with parameter \p iparamsIndex is a flexible constraint */ -static inline bool isConstraintFlexible(const t_iparams *iparams, - int iparamsIndex) +static inline bool isConstraintFlexible(const t_iparams* iparams, int iparamsIndex) { GMX_ASSERT(iparams != nullptr, "Need a valid iparams array"); - return (iparams[iparamsIndex].constr.dA == 0 && - iparams[iparamsIndex].constr.dB == 0); + return (iparams[iparamsIndex].constr.dA == 0 && iparams[iparamsIndex].constr.dB == 0); }; /* The at2con t_blocka struct returned by the routines below @@ -233,8 +232,7 @@ enum class FlexibleConstraintTreatment }; /*! \brief Returns the flexible constraint treatment depending on whether the integrator is dynamic */ -FlexibleConstraintTreatment -flexibleConstraintTreatment(bool haveDynamicsIntegrator); +FlexibleConstraintTreatment flexibleConstraintTreatment(bool haveDynamicsIntegrator); /*! \brief Returns a block struct to go from atoms to constraints * @@ -243,13 +241,13 @@ flexibleConstraintTreatment(bool haveDynamicsIntegrator); * the order in F_CONSTRNC offset by the number of constraints in F_CONSTR. * * \param[in] moltype The molecule data - * \param[in] iparams Interaction parameters, can be null when flexibleConstraintTreatment=Include - * \param[in] flexibleConstraintTreatment The flexible constraint treatment, see enum above - * \returns a block struct with all constraints for each atom + * \param[in] iparams Interaction parameters, can be null when + * flexibleConstraintTreatment=Include \param[in] flexibleConstraintTreatment The flexible + * constraint treatment, see enum above \returns a block struct with all constraints for each atom */ -t_blocka make_at2con(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams, - FlexibleConstraintTreatment flexibleConstraintTreatment); +t_blocka make_at2con(const gmx_moltype_t& moltype, + gmx::ArrayRef iparams, + FlexibleConstraintTreatment flexibleConstraintTreatment); /*! \brief Returns a block struct to go from atoms to constraints * @@ -259,55 +257,55 @@ t_blocka make_at2con(const gmx_moltype_t &moltype, * * \param[in] numAtoms The number of atoms to construct the list for * \param[in] ilist Interaction list, size F_NRE - * \param[in] iparams Interaction parameters, can be null when flexibleConstraintTreatment=Include - * \param[in] flexibleConstraintTreatment The flexible constraint treatment, see enum above - * \returns a block struct with all constraints for each atom + * \param[in] iparams Interaction parameters, can be null when + * flexibleConstraintTreatment=Include \param[in] flexibleConstraintTreatment The flexible + * constraint treatment, see enum above \returns a block struct with all constraints for each atom */ -t_blocka make_at2con(int numAtoms, - const t_ilist *ilist, - const t_iparams *iparams, - FlexibleConstraintTreatment flexibleConstraintTreatment); +t_blocka make_at2con(int numAtoms, + const t_ilist* ilist, + const t_iparams* iparams, + FlexibleConstraintTreatment flexibleConstraintTreatment); /*! \brief Returns an array of atom to constraints lists for the moltypes */ -const t_blocka *atom2constraints_moltype(const Constraints *constr); +const t_blocka* atom2constraints_moltype(const Constraints* constr); //! Return the number of flexible constraints in the \c ilist and \c iparams. -int countFlexibleConstraints(const t_ilist *ilist, - const t_iparams *iparams); +int countFlexibleConstraints(const t_ilist* ilist, const t_iparams* iparams); /*! \brief Returns the constraint iatoms for a constraint number con * which comes from a list where F_CONSTR and F_CONSTRNC constraints * are concatenated. */ -inline const int * -constr_iatomptr(gmx::ArrayRef iatom_constr, - gmx::ArrayRef iatom_constrnc, - int con) +inline const int* constr_iatomptr(gmx::ArrayRef iatom_constr, + gmx::ArrayRef iatom_constrnc, + int con) { - if (con*3 < iatom_constr.ssize()) + if (con * 3 < iatom_constr.ssize()) { - return iatom_constr.data() + con*3; + return iatom_constr.data() + con * 3; } else { - return iatom_constrnc.data() + con*3 - iatom_constr.size(); + return iatom_constrnc.data() + con * 3 - iatom_constr.size(); } }; /*! \brief Returns whether there are inter charge group constraints */ -bool inter_charge_group_constraints(const gmx_mtop_t &mtop); +bool inter_charge_group_constraints(const gmx_mtop_t& mtop); /*! \brief Returns whether there are inter charge group settles */ -bool inter_charge_group_settles(const gmx_mtop_t &mtop); +bool inter_charge_group_settles(const gmx_mtop_t& mtop); /*! \brief Constrain the initial coordinates and velocities */ -void do_constrain_first(FILE *log, gmx::Constraints *constr, - const t_inputrec *inputrec, const t_mdatoms *md, - int natoms, +void do_constrain_first(FILE* log, + gmx::Constraints* constr, + const t_inputrec* inputrec, + const t_mdatoms* md, + int natoms, ArrayRefWithPadding x, ArrayRefWithPadding v, - const matrix box, - real lambda); + const matrix box, + real lambda); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/constraintrange.cpp b/src/gromacs/mdlib/constraintrange.cpp index effc2bdae5..7e5b320e4d 100644 --- a/src/gromacs/mdlib/constraintrange.cpp +++ b/src/gromacs/mdlib/constraintrange.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,13 +57,18 @@ namespace gmx { //! Recursing function to help find all adjacent constraints. -static void constr_recur(const t_blocka *at2con, - const InteractionLists &ilist, +static void constr_recur(const t_blocka* at2con, + const InteractionLists& ilist, gmx::ArrayRef iparams, - gmx_bool bTopB, - int at, int depth, int nc, int *path, - real r0, real r1, real *r2max, - int *count) + gmx_bool bTopB, + int at, + int depth, + int nc, + int* path, + real r0, + real r1, + real* r2max, + int* count) { int c, con, a1; gmx_bool bUse; @@ -75,7 +80,7 @@ static void constr_recur(const t_blocka *at2con, gmx::ArrayRef ia2 = ilist[F_CONSTRNC].iatoms; /* Loop over all constraints connected to this atom */ - for (c = at2con->index[at]; c < at2con->index[at+1]; c++) + for (c = at2con->index[at]; c < at2con->index[at + 1]; c++) { con = at2con->a[c]; /* Do not walk over already used constraints */ @@ -89,7 +94,7 @@ static void constr_recur(const t_blocka *at2con, } if (bUse) { - const int *ia = constr_iatomptr(ia1, ia2, con); + const int* ia = constr_iatomptr(ia1, ia2, con); /* Flexible constraints currently have length 0, which is incorrect */ if (!bTopB) { @@ -111,16 +116,17 @@ static void constr_recur(const t_blocka *at2con, rn1 = r1 + len; } /* Assume angles of 120 degrees between all bonds */ - if (rn0*rn0 + rn1*rn1 + rn0*rn1 > *r2max) + if (rn0 * rn0 + rn1 * rn1 + rn0 * rn1 > *r2max) { - *r2max = rn0*rn0 + rn1*rn1 + r0*rn1; + *r2max = rn0 * rn0 + rn1 * rn1 + r0 * rn1; if (debug) { - fprintf(debug, "Found longer constraint distance: r0 %5.3f r1 %5.3f rmax %5.3f\n", rn0, rn1, sqrt(*r2max)); + fprintf(debug, + "Found longer constraint distance: r0 %5.3f r1 %5.3f rmax %5.3f\n", rn0, + rn1, sqrt(*r2max)); for (a1 = 0; a1 < depth; a1++) { - fprintf(debug, " %d %5.3f", - path[a1], + fprintf(debug, " %d %5.3f", path[a1], iparams[constr_iatomptr(ia1, ia2, con)[0]].constr.dA); } fprintf(debug, " %d %5.3f\n", con, len); @@ -130,7 +136,7 @@ static void constr_recur(const t_blocka *at2con, * so a call does not take more than a second, * even for highly connected systems. */ - if (depth + 1 < nc && *count < 1000*nc) + if (depth + 1 < nc && *count < 1000 * nc) { if (ia[1] == at) { @@ -142,8 +148,7 @@ static void constr_recur(const t_blocka *at2con, } /* Recursion */ path[depth] = con; - constr_recur(at2con, ilist, iparams, - bTopB, a1, depth+1, nc, path, rn0, rn1, r2max, count); + constr_recur(at2con, ilist, iparams, bTopB, a1, depth + 1, nc, path, rn0, rn1, r2max, count); path[depth] = -1; } } @@ -151,27 +156,25 @@ static void constr_recur(const t_blocka *at2con, } //! Find the interaction radius needed for constraints for this molecule type. -static real constr_r_max_moltype(const gmx_moltype_t *molt, - gmx::ArrayRef iparams, - const t_inputrec *ir) +static real constr_r_max_moltype(const gmx_moltype_t* molt, + gmx::ArrayRef iparams, + const t_inputrec* ir) { - int natoms, *path, at, count; + int natoms, *path, at, count; t_blocka at2con; real r0, r1, r2maxA, r2maxB, rmax, lam0, lam1; - if (molt->ilist[F_CONSTR].size() == 0 && - molt->ilist[F_CONSTRNC].size() == 0) + if (molt->ilist[F_CONSTR].size() == 0 && molt->ilist[F_CONSTRNC].size() == 0) { return 0; } natoms = molt->atoms.nr; - at2con = make_at2con(*molt, iparams, - flexibleConstraintTreatment(EI_DYNAMICS(ir->eI))); - snew(path, 1+ir->nProjOrder); - for (at = 0; at < 1+ir->nProjOrder; at++) + at2con = make_at2con(*molt, iparams, flexibleConstraintTreatment(EI_DYNAMICS(ir->eI))); + snew(path, 1 + ir->nProjOrder); + for (at = 0; at < 1 + ir->nProjOrder; at++) { path[at] = -1; } @@ -183,8 +186,8 @@ static real constr_r_max_moltype(const gmx_moltype_t *molt, r1 = 0; count = 0; - constr_recur(&at2con, molt->ilist, iparams, - FALSE, at, 0, 1+ir->nProjOrder, path, r0, r1, &r2maxA, &count); + constr_recur(&at2con, molt->ilist, iparams, FALSE, at, 0, 1 + ir->nProjOrder, path, r0, r1, + &r2maxA, &count); } if (ir->efep == efepNO) { @@ -198,19 +201,19 @@ static real constr_r_max_moltype(const gmx_moltype_t *molt, r0 = 0; r1 = 0; count = 0; - constr_recur(&at2con, molt->ilist, iparams, - TRUE, at, 0, 1+ir->nProjOrder, path, r0, r1, &r2maxB, &count); + constr_recur(&at2con, molt->ilist, iparams, TRUE, at, 0, 1 + ir->nProjOrder, path, r0, + r1, &r2maxB, &count); } lam0 = ir->fepvals->init_lambda; if (EI_DYNAMICS(ir->eI)) { - lam0 += ir->init_step*ir->fepvals->delta_lambda; + lam0 += ir->init_step * ir->fepvals->delta_lambda; } - rmax = (1 - lam0)*sqrt(r2maxA) + lam0*sqrt(r2maxB); + rmax = (1 - lam0) * sqrt(r2maxA) + lam0 * sqrt(r2maxB); if (EI_DYNAMICS(ir->eI)) { - lam1 = ir->fepvals->init_lambda + (ir->init_step + ir->nsteps)*ir->fepvals->delta_lambda; - rmax = std::max(rmax, (1 - lam1)*std::sqrt(r2maxA) + lam1*std::sqrt(r2maxB)); + lam1 = ir->fepvals->init_lambda + (ir->init_step + ir->nsteps) * ir->fepvals->delta_lambda; + rmax = std::max(rmax, (1 - lam1) * std::sqrt(r2maxA) + lam1 * std::sqrt(r2maxB)); } } @@ -220,21 +223,20 @@ static real constr_r_max_moltype(const gmx_moltype_t *molt, return rmax; } -real constr_r_max(const MDLogger &mdlog, const gmx_mtop_t *mtop, const t_inputrec *ir) +real constr_r_max(const MDLogger& mdlog, const gmx_mtop_t* mtop, const t_inputrec* ir) { real rmax = 0; - for (const gmx_moltype_t &molt : mtop->moltype) + for (const gmx_moltype_t& molt : mtop->moltype) { - rmax = std::max(rmax, - constr_r_max_moltype(&molt, - mtop->ffparams.iparams, ir)); + rmax = std::max(rmax, constr_r_max_moltype(&molt, mtop->ffparams.iparams, ir)); } - GMX_LOG(mdlog.info).appendTextFormatted( - "Maximum distance for %d constraints, at 120 deg. angles, all-trans: %.3f nm", - 1+ir->nProjOrder, rmax); + GMX_LOG(mdlog.info) + .appendTextFormatted( + "Maximum distance for %d constraints, at 120 deg. angles, all-trans: %.3f nm", + 1 + ir->nProjOrder, rmax); return rmax; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/constraintrange.h b/src/gromacs/mdlib/constraintrange.h index db915f1e86..2d5b2a5b03 100644 --- a/src/gromacs/mdlib/constraintrange.h +++ b/src/gromacs/mdlib/constraintrange.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,8 +48,8 @@ class MDLogger; /*! \brief Returns an estimate of the maximum distance between atoms * required for LINCS. */ -real constr_r_max(const MDLogger &mdlog, const gmx_mtop_t *mtop, const t_inputrec *ir); +real constr_r_max(const MDLogger& mdlog, const gmx_mtop_t* mtop, const t_inputrec* ir); -} // namespace +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/coupling.cpp b/src/gromacs/mdlib/coupling.cpp index 895d98b78c..f3a4a6ebe1 100644 --- a/src/gromacs/mdlib/coupling.cpp +++ b/src/gromacs/mdlib/coupling.cpp @@ -79,20 +79,14 @@ /* for n=5, w0 = w1 = w3 = w4 = 1/(4-4^-(1/3)), w1 = 1-4*w0 */ #define MAX_SUZUKI_YOSHIDA_NUM 5 -#define SUZUKI_YOSHIDA_NUM 5 +#define SUZUKI_YOSHIDA_NUM 5 -static const double sy_const_1[] = { 1. }; -static const double sy_const_3[] = { 0.828981543588751, -0.657963087177502, 0.828981543588751 }; -static const double sy_const_5[] = { 0.2967324292201065, 0.2967324292201065, -0.186929716880426, 0.2967324292201065, 0.2967324292201065 }; +static const double sy_const_1[] = { 1. }; +static const double sy_const_3[] = { 0.828981543588751, -0.657963087177502, 0.828981543588751 }; +static const double sy_const_5[] = { 0.2967324292201065, 0.2967324292201065, -0.186929716880426, + 0.2967324292201065, 0.2967324292201065 }; -static const double* sy_const[] = { - nullptr, - sy_const_1, - nullptr, - sy_const_3, - nullptr, - sy_const_5 -}; +static const double* sy_const[] = { nullptr, sy_const_1, nullptr, sy_const_3, nullptr, sy_const_5 }; /* static const double sy_const[MAX_SUZUKI_YOSHIDA_NUM+1][MAX_SUZUKI_YOSHIDA_NUM+1] = { @@ -105,26 +99,34 @@ static const double* sy_const[] = { };*/ /* these integration routines are only referenced inside this file */ -static void NHC_trotter(const t_grpopts *opts, int nvar, const gmx_ekindata_t *ekind, real dtfull, - double xi[], double vxi[], double scalefac[], real *veta, const t_extmass *MassQ, gmx_bool bEkinAveVel) +static void NHC_trotter(const t_grpopts* opts, + int nvar, + const gmx_ekindata_t* ekind, + real dtfull, + double xi[], + double vxi[], + double scalefac[], + real* veta, + const t_extmass* MassQ, + gmx_bool bEkinAveVel) { /* general routine for both barostat and thermostat nose hoover chains */ - int i, j, mi, mj; - double Ekin, Efac, reft, kT, nd; - double dt; - double *ivxi, *ixi; - double *GQ; - gmx_bool bBarostat; - int mstepsi, mstepsj; - int ns = SUZUKI_YOSHIDA_NUM; /* set the degree of integration in the types/state.h file */ - int nh = opts->nhchainlength; + int i, j, mi, mj; + double Ekin, Efac, reft, kT, nd; + double dt; + double * ivxi, *ixi; + double* GQ; + gmx_bool bBarostat; + int mstepsi, mstepsj; + int ns = SUZUKI_YOSHIDA_NUM; /* set the degree of integration in the types/state.h file */ + int nh = opts->nhchainlength; snew(GQ, nh); mstepsi = mstepsj = ns; -/* if scalefac is NULL, we are doing the NHC of the barostat */ + /* if scalefac is NULL, we are doing the NHC of the barostat */ bBarostat = FALSE; if (scalefac == nullptr) @@ -138,32 +140,32 @@ static void NHC_trotter(const t_grpopts *opts, int nvar, const gmx_ekindata_t *e /* make it easier to iterate by selecting out the sub-array that corresponds to this T group */ - ivxi = &vxi[i*nh]; - ixi = &xi[i*nh]; + ivxi = &vxi[i * nh]; + ixi = &xi[i * nh]; gmx::ArrayRef iQinv; if (bBarostat) { - iQinv = gmx::arrayRefFromArray(&MassQ->QPinv[i*nh], nh); + iQinv = gmx::arrayRefFromArray(&MassQ->QPinv[i * nh], nh); nd = 1.0; /* THIS WILL CHANGE IF NOT ISOTROPIC */ reft = std::max(0, opts->ref_t[0]); - Ekin = gmx::square(*veta)/MassQ->Winv; + Ekin = gmx::square(*veta) / MassQ->Winv; } else { - iQinv = gmx::arrayRefFromArray(&MassQ->Qinv[i*nh], nh); - const t_grp_tcstat *tcstat = &ekind->tcstat[i]; - nd = opts->nrdf[i]; - reft = std::max(0, opts->ref_t[i]); + iQinv = gmx::arrayRefFromArray(&MassQ->Qinv[i * nh], nh); + const t_grp_tcstat* tcstat = &ekind->tcstat[i]; + nd = opts->nrdf[i]; + reft = std::max(0, opts->ref_t[i]); if (bEkinAveVel) { - Ekin = 2*trace(tcstat->ekinf)*tcstat->ekinscalef_nhc; + Ekin = 2 * trace(tcstat->ekinf) * tcstat->ekinscalef_nhc; } else { - Ekin = 2*trace(tcstat->ekinh)*tcstat->ekinscaleh_nhc; + Ekin = 2 * trace(tcstat->ekinh) * tcstat->ekinscaleh_nhc; } } - kT = BOLTZ*reft; + kT = BOLTZ * reft; for (mi = 0; mi < mstepsi; mi++) { @@ -173,30 +175,30 @@ static void NHC_trotter(const t_grpopts *opts, int nvar, const gmx_ekindata_t *e dt = sy_const[ns][mj] * dtfull / mstepsi; /* compute the thermal forces */ - GQ[0] = iQinv[0]*(Ekin - nd*kT); + GQ[0] = iQinv[0] * (Ekin - nd * kT); - for (j = 0; j < nh-1; j++) + for (j = 0; j < nh - 1; j++) { - if (iQinv[j+1] > 0) + if (iQinv[j + 1] > 0) { /* we actually don't need to update here if we save the state of the GQ, but it's easier to just recompute*/ - GQ[j+1] = iQinv[j+1]*((gmx::square(ivxi[j])/iQinv[j])-kT); + GQ[j + 1] = iQinv[j + 1] * ((gmx::square(ivxi[j]) / iQinv[j]) - kT); } else { - GQ[j+1] = 0; + GQ[j + 1] = 0; } } - ivxi[nh-1] += 0.25*dt*GQ[nh-1]; - for (j = nh-1; j > 0; j--) + ivxi[nh - 1] += 0.25 * dt * GQ[nh - 1]; + for (j = nh - 1; j > 0; j--) { - Efac = exp(-0.125*dt*ivxi[j]); - ivxi[j-1] = Efac*(ivxi[j-1]*Efac + 0.25*dt*GQ[j-1]); + Efac = exp(-0.125 * dt * ivxi[j]); + ivxi[j - 1] = Efac * (ivxi[j - 1] * Efac + 0.25 * dt * GQ[j - 1]); } - Efac = exp(-0.5*dt*ivxi[0]); + Efac = exp(-0.5 * dt * ivxi[0]); if (bBarostat) { *veta *= Efac; @@ -205,42 +207,48 @@ static void NHC_trotter(const t_grpopts *opts, int nvar, const gmx_ekindata_t *e { scalefac[i] *= Efac; } - Ekin *= (Efac*Efac); + Ekin *= (Efac * Efac); - /* Issue - if the KE is an average of the last and the current temperatures, then we might not be - able to scale the kinetic energy directly with this factor. Might take more bookkeeping -- have to - think about this a bit more . . . */ + /* Issue - if the KE is an average of the last and the current temperatures, then we + might not be able to scale the kinetic energy directly with this factor. Might + take more bookkeeping -- have to think about this a bit more . . . */ - GQ[0] = iQinv[0]*(Ekin - nd*kT); + GQ[0] = iQinv[0] * (Ekin - nd * kT); /* update thermostat positions */ for (j = 0; j < nh; j++) { - ixi[j] += 0.5*dt*ivxi[j]; + ixi[j] += 0.5 * dt * ivxi[j]; } - for (j = 0; j < nh-1; j++) + for (j = 0; j < nh - 1; j++) { - Efac = exp(-0.125*dt*ivxi[j+1]); - ivxi[j] = Efac*(ivxi[j]*Efac + 0.25*dt*GQ[j]); - if (iQinv[j+1] > 0) + Efac = exp(-0.125 * dt * ivxi[j + 1]); + ivxi[j] = Efac * (ivxi[j] * Efac + 0.25 * dt * GQ[j]); + if (iQinv[j + 1] > 0) { - GQ[j+1] = iQinv[j+1]*((gmx::square(ivxi[j])/iQinv[j])-kT); + GQ[j + 1] = iQinv[j + 1] * ((gmx::square(ivxi[j]) / iQinv[j]) - kT); } else { - GQ[j+1] = 0; + GQ[j + 1] = 0; } } - ivxi[nh-1] += 0.25*dt*GQ[nh-1]; + ivxi[nh - 1] += 0.25 * dt * GQ[nh - 1]; } } } sfree(GQ); } -static void boxv_trotter(const t_inputrec *ir, real *veta, real dt, const tensor box, - const gmx_ekindata_t *ekind, const tensor vir, real pcorr, const t_extmass *MassQ) +static void boxv_trotter(const t_inputrec* ir, + real* veta, + real dt, + const tensor box, + const gmx_ekindata_t* ekind, + const tensor vir, + real pcorr, + const t_extmass* MassQ) { real pscal; @@ -274,18 +282,18 @@ static void boxv_trotter(const t_inputrec *ir, real *veta, real dt, const tensor gmx_fatal(FARGS, "Barostat is coupled to a T-group with no degrees of freedom\n"); } /* alpha factor for phase space volume, then multiply by the ekin scaling factor. */ - alpha = 1.0 + DIM/(static_cast(ir->opts.nrdf[0])); + alpha = 1.0 + DIM / (static_cast(ir->opts.nrdf[0])); alpha *= ekind->tcstat[0].ekinscalef_nhc; msmul(ekind->ekin, alpha, ekinmod); /* for now, we use Elr = 0, because if you want to get it right, you really should be using PME. Maybe print a warning? */ - pscal = calc_pres(ir->ePBC, nwall, box, ekinmod, vir, localpres)+pcorr; + pscal = calc_pres(ir->ePBC, nwall, box, ekinmod, vir, localpres) + pcorr; vol = det(box); - GW = (vol*(MassQ->Winv/PRESFAC))*(DIM*pscal - trace(ir->ref_p)); /* W is in ps^2 * bar * nm^3 */ + GW = (vol * (MassQ->Winv / PRESFAC)) * (DIM * pscal - trace(ir->ref_p)); /* W is in ps^2 * bar * nm^3 */ - *veta += 0.5*dt*GW; + *veta += 0.5 * dt * GW; } /* @@ -296,8 +304,7 @@ static void boxv_trotter(const t_inputrec *ir, real *veta, real dt, const tensor * */ -real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const tensor vir, - tensor pres) +real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const tensor vir, tensor pres) { int n, m; real fac; @@ -313,12 +320,12 @@ real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const t * het systeem... */ - fac = PRESFAC*2.0/det(box); + fac = PRESFAC * 2.0 / det(box); for (n = 0; (n < DIM); n++) { for (m = 0; (m < DIM); m++) { - pres[n][m] = (ekin[n][m] - vir[n][m])*fac; + pres[n][m] = (ekin[n][m] - vir[n][m]) * fac; } } @@ -330,14 +337,14 @@ real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const t pr_rvecs(debug, 0, "PC: box ", box, DIM); } } - return trace(pres)/DIM; + return trace(pres) / DIM; } real calc_temp(real ekin, real nrdf) { if (nrdf > 0) { - return (2.0*ekin)/(nrdf*BOLTZ); + return (2.0 * ekin) / (nrdf * BOLTZ); } else { @@ -346,8 +353,7 @@ real calc_temp(real ekin, real nrdf) } /*! \brief Sets 1/mass for Parrinello-Rahman in wInv; NOTE: PRESFAC is not included, so not in GROMACS units! */ -static void calcParrinelloRahmanInvMass(const t_inputrec *ir, const matrix box, - tensor wInv) +static void calcParrinelloRahmanInvMass(const t_inputrec* ir, const matrix box, tensor wInv) { real maxBoxLength; @@ -359,15 +365,22 @@ static void calcParrinelloRahmanInvMass(const t_inputrec *ir, const matrix box, { for (int n = 0; n < DIM; n++) { - wInv[d][n] = (4*M_PI*M_PI*ir->compress[d][n])/(3*ir->tau_p*ir->tau_p*maxBoxLength); + wInv[d][n] = (4 * M_PI * M_PI * ir->compress[d][n]) / (3 * ir->tau_p * ir->tau_p * maxBoxLength); } } } -void parrinellorahman_pcoupl(FILE *fplog, int64_t step, - const t_inputrec *ir, real dt, const tensor pres, - const tensor box, tensor box_rel, tensor boxv, - tensor M, matrix mu, gmx_bool bFirstStep) +void parrinellorahman_pcoupl(FILE* fplog, + int64_t step, + const t_inputrec* ir, + real dt, + const tensor pres, + const tensor box, + tensor box_rel, + tensor boxv, + tensor M, + matrix mu, + gmx_bool bFirstStep) { /* This doesn't do any coordinate updating. It just * integrates the box vector equations from the calculated @@ -394,7 +407,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, * b = vol/W inv(box') * (P-ref_P) (=h') */ - real vol = box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]; + real vol = box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]; real atot, arel, change; tensor invbox, pdiff, t1, t2; @@ -417,10 +430,10 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, * pressure correction here? On the other hand we don't scale the * box momentarily, but change accelerations, so it might not be crucial. */ - real xy_pressure = 0.5*(pres[XX][XX]+pres[YY][YY]); + real xy_pressure = 0.5 * (pres[XX][XX] + pres[YY][YY]); for (int d = 0; d < ZZ; d++) { - pdiff[d][d] = (xy_pressure-(pres[ZZ][ZZ]-ir->ref_p[d][d]/box[d][d])); + pdiff[d][d] = (xy_pressure - (pres[ZZ][ZZ] - ir->ref_p[d][d] / box[d][d])); } } @@ -433,7 +446,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, for (int n = 0; n < d; n++) { t1[d][n] += t1[n][d]; - t1[n][d] = 0; + t1[n][d] = 0; } } @@ -444,23 +457,22 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, { for (int n = 0; n <= d; n++) { - t1[d][n] *= winv[d][n]*vol; + t1[d][n] *= winv[d][n] * vol; } } break; case epctISOTROPIC: /* calculate total volume acceleration */ - atot = box[XX][XX]*box[YY][YY]*t1[ZZ][ZZ]+ - box[XX][XX]*t1[YY][YY]*box[ZZ][ZZ]+ - t1[XX][XX]*box[YY][YY]*box[ZZ][ZZ]; - arel = atot/(3*vol); + atot = box[XX][XX] * box[YY][YY] * t1[ZZ][ZZ] + box[XX][XX] * t1[YY][YY] * box[ZZ][ZZ] + + t1[XX][XX] * box[YY][YY] * box[ZZ][ZZ]; + arel = atot / (3 * vol); /* set all RELATIVE box accelerations equal, and maintain total V * change speed */ for (int d = 0; d < DIM; d++) { for (int n = 0; n <= d; n++) { - t1[d][n] = winv[0][0]*vol*arel*box[d][n]; + t1[d][n] = winv[0][0] * vol * arel * box[d][n]; } } break; @@ -469,25 +481,27 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, /* Note the correction to pdiff above for surftens. coupling */ /* calculate total XY volume acceleration */ - atot = box[XX][XX]*t1[YY][YY]+t1[XX][XX]*box[YY][YY]; - arel = atot/(2*box[XX][XX]*box[YY][YY]); + atot = box[XX][XX] * t1[YY][YY] + t1[XX][XX] * box[YY][YY]; + arel = atot / (2 * box[XX][XX] * box[YY][YY]); /* set RELATIVE XY box accelerations equal, and maintain total V * change speed. Dont change the third box vector accelerations */ for (int d = 0; d < ZZ; d++) { for (int n = 0; n <= d; n++) { - t1[d][n] = winv[d][n]*vol*arel*box[d][n]; + t1[d][n] = winv[d][n] * vol * arel * box[d][n]; } } for (int n = 0; n < DIM; n++) { - t1[ZZ][n] *= winv[ZZ][n]*vol; + t1[ZZ][n] *= winv[ZZ][n] * vol; } break; default: - gmx_fatal(FARGS, "Parrinello-Rahman pressure coupling type %s " - "not supported yet\n", EPCOUPLTYPETYPE(ir->epct)); + gmx_fatal(FARGS, + "Parrinello-Rahman pressure coupling type %s " + "not supported yet\n", + EPCOUPLTYPETYPE(ir->epct)); } real maxchange = 0; @@ -495,7 +509,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, { for (int n = 0; n <= d; n++) { - boxv[d][n] += dt*t1[d][n]; + boxv[d][n] += dt * t1[d][n]; /* We do NOT update the box vectors themselves here, since * we need them for shifting later. It is instead done last @@ -508,7 +522,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, to its current size. */ - change = std::fabs(dt*boxv[d][n]/box[d][d]); + change = std::fabs(dt * boxv[d][n] / box[d][d]); if (change > maxchange) { @@ -532,7 +546,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, preserve_box_shape(ir, box_rel, boxv); - mtmul(boxv, box, t1); /* t1=boxv * b' */ + mtmul(boxv, box, t1); /* t1=boxv * b' */ mmul(invbox, t1, t2); mtmul(t2, invbox, M); @@ -541,7 +555,7 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, { for (int n = 0; n <= d; n++) { - t1[d][n] = box[d][n] + dt*boxv[d][n]; + t1[d][n] = box[d][n] + dt * boxv[d][n]; } } preserve_box_shape(ir, box_rel, t1); @@ -549,15 +563,20 @@ void parrinellorahman_pcoupl(FILE *fplog, int64_t step, mmul_ur0(invbox, t1, mu); } -void berendsen_pcoupl(FILE *fplog, int64_t step, - const t_inputrec *ir, real dt, - const tensor pres, const matrix box, - const matrix force_vir, const matrix constraint_vir, - matrix mu, double *baros_integral) +void berendsen_pcoupl(FILE* fplog, + int64_t step, + const t_inputrec* ir, + real dt, + const tensor pres, + const matrix box, + const matrix force_vir, + const matrix constraint_vir, + matrix mu, + double* baros_integral) { - int d, n; - real scalar_pressure, xy_pressure, p_corr_z; - char buf[STRLEN]; + int d, n; + real scalar_pressure, xy_pressure, p_corr_z; + char buf[STRLEN]; /* * Calculate the scaling matrix mu @@ -566,14 +585,14 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, xy_pressure = 0; for (d = 0; d < DIM; d++) { - scalar_pressure += pres[d][d]/DIM; + scalar_pressure += pres[d][d] / DIM; if (d != ZZ) { - xy_pressure += pres[d][d]/(DIM-1); + xy_pressure += pres[d][d] / (DIM - 1); } } /* Pressure is now in bar, everywhere. */ -#define factor(d, m) (ir->compress[d][m]*dt/ir->tau_p) +#define factor(d, m) (ir->compress[d][m] * dt / ir->tau_p) /* mu has been changed from pow(1+...,1/3) to 1+.../3, since this is * necessary for triclinic scaling @@ -584,24 +603,22 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, case epctISOTROPIC: for (d = 0; d < DIM; d++) { - mu[d][d] = 1.0 - factor(d, d)*(ir->ref_p[d][d] - scalar_pressure) /DIM; + mu[d][d] = 1.0 - factor(d, d) * (ir->ref_p[d][d] - scalar_pressure) / DIM; } break; case epctSEMIISOTROPIC: for (d = 0; d < ZZ; d++) { - mu[d][d] = 1.0 - factor(d, d)*(ir->ref_p[d][d]-xy_pressure)/DIM; + mu[d][d] = 1.0 - factor(d, d) * (ir->ref_p[d][d] - xy_pressure) / DIM; } - mu[ZZ][ZZ] = - 1.0 - factor(ZZ, ZZ)*(ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ])/DIM; + mu[ZZ][ZZ] = 1.0 - factor(ZZ, ZZ) * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM; break; case epctANISOTROPIC: for (d = 0; d < DIM; d++) { for (n = 0; n < DIM; n++) { - mu[d][n] = (d == n ? 1.0 : 0.0) - -factor(d, n)*(ir->ref_p[d][n] - pres[d][n])/DIM; + mu[d][n] = (d == n ? 1.0 : 0.0) - factor(d, n) * (ir->ref_p[d][n] - pres[d][n]) / DIM; } } break; @@ -610,7 +627,7 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, * the number of surfaces */ if (ir->compress[ZZ][ZZ] != 0.0F) { - p_corr_z = dt/ir->tau_p*(ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]); + p_corr_z = dt / ir->tau_p * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]); } else { @@ -618,11 +635,14 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, * in the z-direction to zero to get the correct surface tension */ p_corr_z = 0; } - mu[ZZ][ZZ] = 1.0 - ir->compress[ZZ][ZZ]*p_corr_z; - for (d = 0; d < DIM-1; d++) + mu[ZZ][ZZ] = 1.0 - ir->compress[ZZ][ZZ] * p_corr_z; + for (d = 0; d < DIM - 1; d++) { - mu[d][d] = 1.0 + factor(d, d)*(ir->ref_p[d][d]/(mu[ZZ][ZZ]*box[ZZ][ZZ]) - - (pres[ZZ][ZZ]+p_corr_z - xy_pressure))/(DIM-1); + mu[d][d] = 1.0 + + factor(d, d) + * (ir->ref_p[d][d] / (mu[ZZ][ZZ] * box[ZZ][ZZ]) + - (pres[ZZ][ZZ] + p_corr_z - xy_pressure)) + / (DIM - 1); } break; default: @@ -636,9 +656,9 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, mu[YY][XX] += mu[XX][YY]; mu[ZZ][XX] += mu[XX][ZZ]; mu[ZZ][YY] += mu[YY][ZZ]; - mu[XX][YY] = 0; - mu[XX][ZZ] = 0; - mu[YY][ZZ] = 0; + mu[XX][YY] = 0; + mu[XX][ZZ] = 0; + mu[YY][ZZ] = 0; /* Keep track of the work the barostat applies on the system. * Without constraints force_vir tells us how Epot changes when scaling. @@ -653,7 +673,8 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, { for (int n = 0; n <= d; n++) { - *baros_integral -= 2*(mu[d][n] - (n == d ? 1 : 0))*(force_vir[d][n] + constraint_vir[d][n]); + *baros_integral -= + 2 * (mu[d][n] - (n == d ? 1 : 0)) * (force_vir[d][n] + constraint_vir[d][n]); } } @@ -663,12 +684,12 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, pr_rvecs(debug, 0, "PC: mu ", mu, 3); } - if (mu[XX][XX] < 0.99 || mu[XX][XX] > 1.01 || - mu[YY][YY] < 0.99 || mu[YY][YY] > 1.01 || - mu[ZZ][ZZ] < 0.99 || mu[ZZ][ZZ] > 1.01) + if (mu[XX][XX] < 0.99 || mu[XX][XX] > 1.01 || mu[YY][YY] < 0.99 || mu[YY][YY] > 1.01 + || mu[ZZ][ZZ] < 0.99 || mu[ZZ][ZZ] > 1.01) { char buf2[22]; - sprintf(buf, "\nStep %s Warning: pressure scaling more than 1%%, " + sprintf(buf, + "\nStep %s Warning: pressure scaling more than 1%%, " "mu: %g %g %g\n", gmx_step_str(step, buf2), mu[XX][XX], mu[YY][YY], mu[ZZ][ZZ]); if (fplog) @@ -679,15 +700,19 @@ void berendsen_pcoupl(FILE *fplog, int64_t step, } } -void berendsen_pscale(const t_inputrec *ir, const matrix mu, - matrix box, matrix box_rel, - int start, int nr_atoms, - rvec x[], const unsigned short cFREEZE[], - t_nrnb *nrnb) +void berendsen_pscale(const t_inputrec* ir, + const matrix mu, + matrix box, + matrix box_rel, + int start, + int nr_atoms, + rvec x[], + const unsigned short cFREEZE[], + t_nrnb* nrnb) { - ivec *nFreeze = ir->opts.nFreeze; - int d; - int nthreads gmx_unused; + ivec* nFreeze = ir->opts.nFreeze; + int d; + int nthreads gmx_unused; #ifndef __clang_analyzer__ nthreads = gmx_omp_nthreads_get(emntUpdate); @@ -695,7 +720,7 @@ void berendsen_pscale(const t_inputrec *ir, const matrix mu, /* Scale the positions */ #pragma omp parallel for num_threads(nthreads) schedule(static) - for (int n = start; n < start+nr_atoms; n++) + for (int n = start; n < start + nr_atoms; n++) { // Trivial OpenMP region that does not throw int g; @@ -711,23 +736,23 @@ void berendsen_pscale(const t_inputrec *ir, const matrix mu, if (!nFreeze[g][XX]) { - x[n][XX] = mu[XX][XX]*x[n][XX]+mu[YY][XX]*x[n][YY]+mu[ZZ][XX]*x[n][ZZ]; + x[n][XX] = mu[XX][XX] * x[n][XX] + mu[YY][XX] * x[n][YY] + mu[ZZ][XX] * x[n][ZZ]; } if (!nFreeze[g][YY]) { - x[n][YY] = mu[YY][YY]*x[n][YY]+mu[ZZ][YY]*x[n][ZZ]; + x[n][YY] = mu[YY][YY] * x[n][YY] + mu[ZZ][YY] * x[n][ZZ]; } if (!nFreeze[g][ZZ]) { - x[n][ZZ] = mu[ZZ][ZZ]*x[n][ZZ]; + x[n][ZZ] = mu[ZZ][ZZ] * x[n][ZZ]; } } /* compute final boxlengths */ for (d = 0; d < DIM; d++) { - box[d][XX] = mu[XX][XX]*box[d][XX]+mu[YY][XX]*box[d][YY]+mu[ZZ][XX]*box[d][ZZ]; - box[d][YY] = mu[YY][YY]*box[d][YY]+mu[ZZ][YY]*box[d][ZZ]; - box[d][ZZ] = mu[ZZ][ZZ]*box[d][ZZ]; + box[d][XX] = mu[XX][XX] * box[d][XX] + mu[YY][XX] * box[d][YY] + mu[ZZ][XX] * box[d][ZZ]; + box[d][YY] = mu[YY][YY] * box[d][YY] + mu[ZZ][YY] * box[d][ZZ]; + box[d][ZZ] = mu[ZZ][ZZ] * box[d][ZZ]; } preserve_box_shape(ir, box_rel, box); @@ -738,10 +763,9 @@ void berendsen_pscale(const t_inputrec *ir, const matrix mu, inc_nrnb(nrnb, eNR_PCOUPL, nr_atoms); } -void berendsen_tcoupl(const t_inputrec *ir, gmx_ekindata_t *ekind, real dt, - std::vector &therm_integral) +void berendsen_tcoupl(const t_inputrec* ir, gmx_ekindata_t* ekind, real dt, std::vector& therm_integral) { - const t_grpopts *opts = &ir->opts; + const t_grpopts* opts = &ir->opts; for (int i = 0; (i < opts->ngtc); i++) { @@ -761,7 +785,7 @@ void berendsen_tcoupl(const t_inputrec *ir, gmx_ekindata_t *ekind, real dt, if ((opts->tau_t[i] > 0) && (T > 0.0)) { real reft = std::max(0, opts->ref_t[i]); - real lll = std::sqrt(1.0 + (dt/opts->tau_t[i])*(reft/T-1.0)); + real lll = std::sqrt(1.0 + (dt / opts->tau_t[i]) * (reft / T - 1.0)); ekind->tcstat[i].lambda = std::max(std::min(lll, 1.25), 0.8); } else @@ -770,32 +794,34 @@ void berendsen_tcoupl(const t_inputrec *ir, gmx_ekindata_t *ekind, real dt, } /* Keep track of the amount of energy we are adding to the system */ - therm_integral[i] -= (gmx::square(ekind->tcstat[i].lambda) - 1)*Ek; + therm_integral[i] -= (gmx::square(ekind->tcstat[i].lambda) - 1) * Ek; if (debug) { - fprintf(debug, "TC: group %d: T: %g, Lambda: %g\n", - i, T, ekind->tcstat[i].lambda); + fprintf(debug, "TC: group %d: T: %g, Lambda: %g\n", i, T, ekind->tcstat[i].lambda); } } } -void andersen_tcoupl(const t_inputrec *ir, int64_t step, - const t_commrec *cr, const t_mdatoms *md, - gmx::ArrayRef v, - real rate, const std::vector &randomize, +void andersen_tcoupl(const t_inputrec* ir, + int64_t step, + const t_commrec* cr, + const t_mdatoms* md, + gmx::ArrayRef v, + real rate, + const std::vector& randomize, gmx::ArrayRef boltzfac) { - const int *gatindex = (DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); - int i; - int gc = 0; - gmx::ThreeFry2x64<0> rng(ir->andersen_seed, gmx::RandomDomain::Thermostat); + const int* gatindex = (DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); + int i; + int gc = 0; + gmx::ThreeFry2x64<0> rng(ir->andersen_seed, gmx::RandomDomain::Thermostat); gmx::UniformRealDistribution uniformDist; gmx::TabulatedNormalDistribution normalDist; /* randomize the velocities of the selected particles */ - for (i = 0; i < md->homenr; i++) /* now loop over the list of atoms */ + for (i = 0; i < md->homenr; i++) /* now loop over the list of atoms */ { int ng = gatindex ? gatindex[i] : i; gmx_bool bRandomize; @@ -804,7 +830,7 @@ void andersen_tcoupl(const t_inputrec *ir, int64_t step, if (md->cTC) { - gc = md->cTC[i]; /* assign the atom to a temperature group if there are more than one */ + gc = md->cTC[i]; /* assign the atom to a temperature group if there are more than one */ } if (randomize[gc]) { @@ -824,13 +850,13 @@ void andersen_tcoupl(const t_inputrec *ir, int64_t step, real scal; int d; - scal = std::sqrt(boltzfac[gc]*md->invmass[i]); + scal = std::sqrt(boltzfac[gc] * md->invmass[i]); normalDist.reset(); for (d = 0; d < DIM; d++) { - v[i][d] = scal*normalDist(rng); + v[i][d] = scal * normalDist(rng); } } } @@ -838,53 +864,60 @@ void andersen_tcoupl(const t_inputrec *ir, int64_t step, } -void nosehoover_tcoupl(const t_grpopts *opts, const gmx_ekindata_t *ekind, real dt, - double xi[], double vxi[], const t_extmass *MassQ) +void nosehoover_tcoupl(const t_grpopts* opts, + const gmx_ekindata_t* ekind, + real dt, + double xi[], + double vxi[], + const t_extmass* MassQ) { - int i; - real reft, oldvxi; + int i; + real reft, oldvxi; /* note that this routine does not include Nose-hoover chains yet. Should be easy to add. */ for (i = 0; (i < opts->ngtc); i++) { - reft = std::max(0, opts->ref_t[i]); - oldvxi = vxi[i]; - vxi[i] += dt*MassQ->Qinv[i]*(ekind->tcstat[i].Th - reft); - xi[i] += dt*(oldvxi + vxi[i])*0.5; + reft = std::max(0, opts->ref_t[i]); + oldvxi = vxi[i]; + vxi[i] += dt * MassQ->Qinv[i] * (ekind->tcstat[i].Th - reft); + xi[i] += dt * (oldvxi + vxi[i]) * 0.5; } } -void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, - const gmx_enerdata_t *enerd, t_state *state, - const tensor vir, const t_mdatoms *md, - const t_extmass *MassQ, gmx::ArrayRef < std::vector < int>> trotter_seqlist, - int trotter_seqno) +void trotter_update(const t_inputrec* ir, + int64_t step, + gmx_ekindata_t* ekind, + const gmx_enerdata_t* enerd, + t_state* state, + const tensor vir, + const t_mdatoms* md, + const t_extmass* MassQ, + gmx::ArrayRef> trotter_seqlist, + int trotter_seqno) { int n, i, d, ngtc, gc = 0, t; - t_grp_tcstat *tcstat; - const t_grpopts *opts; + t_grp_tcstat* tcstat; + const t_grpopts* opts; int64_t step_eff; real dt; - double *scalefac, dtc; - rvec sumv = {0, 0, 0}; + double * scalefac, dtc; + rvec sumv = { 0, 0, 0 }; gmx_bool bCouple; if (trotter_seqno <= ettTSEQ2) { - step_eff = step-1; /* the velocity verlet calls are actually out of order -- the first half step - is actually the last half step from the previous step. Thus the first half step - actually corresponds to the n-1 step*/ - + step_eff = step - 1; /* the velocity verlet calls are actually out of order -- the first + half step is actually the last half step from the previous step. + Thus the first half step actually corresponds to the n-1 step*/ } else { step_eff = step; } - bCouple = (ir->nsttcouple == 1 || - do_per_step(step_eff+ir->nsttcouple, ir->nsttcouple)); + bCouple = (ir->nsttcouple == 1 || do_per_step(step_eff + ir->nsttcouple, ir->nsttcouple)); const gmx::ArrayRef trotter_seq = trotter_seqlist[trotter_seqno]; @@ -892,8 +925,8 @@ void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, { return; } - dtc = ir->nsttcouple*ir->delta_t; /* This is OK for NPT, because nsttcouple == nstpcouple is enforcesd */ - opts = &(ir->opts); /* just for ease of referencing */ + dtc = ir->nsttcouple * ir->delta_t; /* This is OK for NPT, because nsttcouple == nstpcouple is enforcesd */ + opts = &(ir->opts); /* just for ease of referencing */ ngtc = opts->ngtc; assert(ngtc > 0); snew(scalefac, opts->ngtc); @@ -906,7 +939,8 @@ void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, for (i = 0; i < NTROTTERPARTS; i++) { /* allow for doubled intgrators by doubling dt instead of making 2 calls */ - if ((trotter_seq[i] == etrtBAROV2) || (trotter_seq[i] == etrtBARONHC2) || (trotter_seq[i] == etrtNHC2)) + if ((trotter_seq[i] == etrtBAROV2) || (trotter_seq[i] == etrtBARONHC2) + || (trotter_seq[i] == etrtNHC2)) { dt = 2 * dtc; } @@ -938,10 +972,10 @@ void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, for (t = 0; t < ngtc; t++) { - tcstat = &ekind->tcstat[t]; - tcstat->vscale_nhc = scalefac[t]; - tcstat->ekinscaleh_nhc *= (scalefac[t]*scalefac[t]); - tcstat->ekinscalef_nhc *= (scalefac[t]*scalefac[t]); + tcstat = &ekind->tcstat[t]; + tcstat->vscale_nhc = scalefac[t]; + tcstat->ekinscaleh_nhc *= (scalefac[t] * scalefac[t]); + tcstat->ekinscalef_nhc *= (scalefac[t] * scalefac[t]); } /* now that we've scaled the groupwise velocities, we can add them up to get the total */ /* but do we actually need the total? */ @@ -962,13 +996,12 @@ void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, { for (d = 0; d < DIM; d++) { - sumv[d] += (v[n][d])/md->invmass[n]; + sumv[d] += (v[n][d]) / md->invmass[n]; } } } break; - default: - break; + default: break; } } /* check for conserved momentum -- worth looking at this again eventually, but not working right now.*/ @@ -976,15 +1009,15 @@ void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, } -extern void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *MassQ, gmx_bool bInit) +extern void init_npt_masses(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool bInit) { int n, i, j, d, ngtc, nh; - const t_grpopts *opts; + const t_grpopts* opts; real reft, kT, ndj, nd; - opts = &(ir->opts); /* just for ease of referencing */ - ngtc = ir->opts.ngtc; - nh = state->nhchainlength; + opts = &(ir->opts); /* just for ease of referencing */ + ngtc = ir->opts.ngtc; + nh = state->nhchainlength; if (ir->eI == eiMD) { @@ -996,7 +1029,7 @@ extern void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *Mas { if ((opts->tau_t[i] > 0) && (opts->ref_t[i] > 0)) { - MassQ->Qinv[i] = 1.0/(gmx::square(opts->tau_t[i]/M_2PI)*opts->ref_t[i]); + MassQ->Qinv[i] = 1.0 / (gmx::square(opts->tau_t[i] / M_2PI) * opts->ref_t[i]); } else { @@ -1021,14 +1054,16 @@ extern void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *Mas /* units are nm^3 * ns^2 / (nm^3 * bar / kJ/mol) = kJ/mol */ /* Consider evaluating eventually if this the right mass to use. All are correct, some might be more stable */ - MassQ->Winv = (PRESFAC*trace(ir->compress)*BOLTZ*opts->ref_t[0])/(DIM*state->vol0*gmx::square(ir->tau_p/M_2PI)); + MassQ->Winv = (PRESFAC * trace(ir->compress) * BOLTZ * opts->ref_t[0]) + / (DIM * state->vol0 * gmx::square(ir->tau_p / M_2PI)); /* An alternate mass definition, from Tuckerman et al. */ /* MassQ->Winv = 1.0/(gmx::square(ir->tau_p/M_2PI)*(opts->nrdf[0]+DIM)*BOLTZ*opts->ref_t[0]); */ for (d = 0; d < DIM; d++) { for (n = 0; n < DIM; n++) { - MassQ->Winvm[d][n] = PRESFAC*ir->compress[d][n]/(state->vol0*gmx::square(ir->tau_p/M_2PI)); + MassQ->Winvm[d][n] = + PRESFAC * ir->compress[d][n] / (state->vol0 * gmx::square(ir->tau_p / M_2PI)); /* not clear this is correct yet for the anisotropic case. Will need to reevaluate before using MTTK for anisotropic states.*/ } @@ -1046,7 +1081,7 @@ extern void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *Mas { reft = std::max(0, opts->ref_t[i]); nd = opts->nrdf[i]; - kT = BOLTZ*reft; + kT = BOLTZ * reft; for (j = 0; j < nh; j++) { if (j == 0) @@ -1057,25 +1092,25 @@ extern void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *Mas { ndj = 1; } - MassQ->Qinv[i*nh+j] = 1.0/(gmx::square(opts->tau_t[i]/M_2PI)*ndj*kT); + MassQ->Qinv[i * nh + j] = 1.0 / (gmx::square(opts->tau_t[i] / M_2PI) * ndj * kT); } } else { for (j = 0; j < nh; j++) { - MassQ->Qinv[i*nh+j] = 0.0; + MassQ->Qinv[i * nh + j] = 0.0; } } } } } -std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, t_state *state, - t_extmass *MassQ, gmx_bool bTrotter) +std::array, ettTSEQMAX> +init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool bTrotter) { int i, j, nnhpres, nh; - const t_grpopts *opts; + const t_grpopts* opts; real bmass, qmass, reft, kT; opts = &(ir->opts); /* just for ease of referencing */ @@ -1084,13 +1119,14 @@ std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, if (EI_VV(ir->eI) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER)) { - gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control"); + gmx_fatal(FARGS, + "Cannot do MTTK pressure coupling without Nose-Hoover temperature control"); } init_npt_masses(ir, state, MassQ, TRUE); /* first, initialize clear all the trotter calls */ - std::array < std::vector < int>, ettTSEQMAX> trotter_seq; + std::array, ettTSEQMAX> trotter_seq; for (i = 0; i < ettTSEQMAX; i++) { trotter_seq[i].resize(NTROTTERPARTS, etrtNONE); @@ -1131,7 +1167,6 @@ std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, trotter_seq[3][2] = etrtBAROV; /* trotter_seq[4] is etrtNHC for second 1/2 step velocities - leave zero */ - } else if (inputrecNvtTrotter(ir)) { @@ -1215,17 +1250,16 @@ std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, switch (ir->epct) { case epctISOTROPIC: - default: - bmass = DIM*DIM; /* recommended mass parameters for isotropic barostat */ + default: bmass = DIM * DIM; /* recommended mass parameters for isotropic barostat */ } - MassQ->QPinv.resize(nnhpres*opts->nhchainlength); + MassQ->QPinv.resize(nnhpres * opts->nhchainlength); /* barostat temperature */ if ((ir->tau_p > 0) && (opts->ref_t[0] > 0)) { reft = std::max(0, opts->ref_t[0]); - kT = BOLTZ*reft; + kT = BOLTZ * reft; for (i = 0; i < nnhpres; i++) { for (j = 0; j < nh; j++) @@ -1238,7 +1272,8 @@ std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, { qmass = 1; } - MassQ->QPinv[i*opts->nhchainlength+j] = 1.0/(gmx::square(opts->tau_t[0]/M_2PI)*qmass*kT); + MassQ->QPinv[i * opts->nhchainlength + j] = + 1.0 / (gmx::square(opts->tau_t[0] / M_2PI) * qmass * kT); } } } @@ -1248,28 +1283,28 @@ std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, { for (j = 0; j < nh; j++) { - MassQ->QPinv[i*nh+j] = 0.0; + MassQ->QPinv[i * nh + j] = 0.0; } } } return trotter_seq; } -static real energyNoseHoover(const t_inputrec *ir, const t_state *state, const t_extmass *MassQ) +static real energyNoseHoover(const t_inputrec* ir, const t_state* state, const t_extmass* MassQ) { real energy = 0; - int nh = state->nhchainlength; + int nh = state->nhchainlength; for (int i = 0; i < ir->opts.ngtc; i++) { - const double *ixi = &state->nosehoover_xi[i*nh]; - const double *ivxi = &state->nosehoover_vxi[i*nh]; - const double *iQinv = &(MassQ->Qinv[i*nh]); + const double* ixi = &state->nosehoover_xi[i * nh]; + const double* ivxi = &state->nosehoover_vxi[i * nh]; + const double* iQinv = &(MassQ->Qinv[i * nh]); - int nd = static_cast(ir->opts.nrdf[i]); - real reft = std::max(ir->opts.ref_t[i], 0); - real kT = BOLTZ * reft; + int nd = static_cast(ir->opts.nrdf[i]); + real reft = std::max(ir->opts.ref_t[i], 0); + real kT = BOLTZ * reft; if (nd > 0.0) { @@ -1280,7 +1315,7 @@ static real energyNoseHoover(const t_inputrec *ir, const t_state *state, const t { if (iQinv[j] > 0) { - energy += 0.5*gmx::square(ivxi[j])/iQinv[j]; + energy += 0.5 * gmx::square(ivxi[j]) / iQinv[j]; /* contribution from the thermal variable of the NH chain */ int ndj; if (j == 0) @@ -1291,14 +1326,14 @@ static real energyNoseHoover(const t_inputrec *ir, const t_state *state, const t { ndj = 1; } - energy += ndj*ixi[j]*kT; + energy += ndj * ixi[j] * kT; } } } - else /* Other non Trotter temperature NH control -- no chains yet. */ + else /* Other non Trotter temperature NH control -- no chains yet. */ { - energy += 0.5*BOLTZ*nd*gmx::square(ivxi[0])/iQinv[0]; - energy += nd*ixi[0]*kT; + energy += 0.5 * BOLTZ * nd * gmx::square(ivxi[0]) / iQinv[0]; + energy += nd * ixi[0] * kT; } } } @@ -1307,30 +1342,31 @@ static real energyNoseHoover(const t_inputrec *ir, const t_state *state, const t } /* Returns the energy from the barostat thermostat chain */ -static real energyPressureMTTK(const t_inputrec *ir, const t_state *state, const t_extmass *MassQ) +static real energyPressureMTTK(const t_inputrec* ir, const t_state* state, const t_extmass* MassQ) { real energy = 0; - int nh = state->nhchainlength; + int nh = state->nhchainlength; for (int i = 0; i < state->nnhpres; i++) { /* note -- assumes only one degree of freedom that is thermostatted in barostat */ - real reft = std::max(ir->opts.ref_t[0], 0.0); /* using 'System' temperature */ - real kT = BOLTZ * reft; + real reft = std::max(ir->opts.ref_t[0], 0.0); /* using 'System' temperature */ + real kT = BOLTZ * reft; for (int j = 0; j < nh; j++) { - double iQinv = MassQ->QPinv[i*nh + j]; + double iQinv = MassQ->QPinv[i * nh + j]; if (iQinv > 0) { - energy += 0.5*gmx::square(state->nhpres_vxi[i*nh + j]/iQinv); + energy += 0.5 * gmx::square(state->nhpres_vxi[i * nh + j] / iQinv); /* contribution from the thermal variable of the NH chain */ - energy += state->nhpres_xi[i*nh + j]*kT; + energy += state->nhpres_xi[i * nh + j] * kT; } if (debug) { - fprintf(debug, "P-T-group: %10d Chain %4d ThermV: %15.8f ThermX: %15.8f", i, j, state->nhpres_vxi[i*nh + j], state->nhpres_xi[i*nh + j]); + fprintf(debug, "P-T-group: %10d Chain %4d ThermV: %15.8f ThermX: %15.8f", i, j, + state->nhpres_vxi[i * nh + j], state->nhpres_xi[i * nh + j]); } } } @@ -1339,7 +1375,7 @@ static real energyPressureMTTK(const t_inputrec *ir, const t_state *state, const } /* Returns the energy accumulated by the V-rescale or Berendsen thermostat */ -static real energyVrescale(const t_inputrec *ir, const t_state *state) +static real energyVrescale(const t_inputrec* ir, const t_state* state) { real energy = 0; for (int i = 0; i < ir->opts.ngtc; i++) @@ -1350,7 +1386,7 @@ static real energyVrescale(const t_inputrec *ir, const t_state *state) return energy; } -real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *MassQ) +real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* MassQ) { real energyNPT = 0; @@ -1358,7 +1394,7 @@ real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *Mas { /* Compute the contribution of the pressure to the conserved quantity*/ - real vol = det(state->box); + real vol = det(state->box); switch (ir->epc) { @@ -1373,7 +1409,7 @@ real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *Mas { if (invMass[d][n] > 0) { - energyNPT += 0.5*gmx::square(state->boxv[d][n])/(invMass[d][n]*PRESFAC); + energyNPT += 0.5 * gmx::square(state->boxv[d][n]) / (invMass[d][n] * PRESFAC); } } } @@ -1385,15 +1421,15 @@ real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *Mas * track of unwrapped box diagonal elements. This case is * excluded in integratorHasConservedEnergyQuantity(). */ - energyNPT += vol*trace(ir->ref_p)/(DIM*PRESFAC); + energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC); break; } case epcMTTK: /* contribution from the pressure momenta */ - energyNPT += 0.5*gmx::square(state->veta)/MassQ->Winv; + energyNPT += 0.5 * gmx::square(state->veta) / MassQ->Winv; /* contribution from the PV term */ - energyNPT += vol*trace(ir->ref_p)/(DIM*PRESFAC); + energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC); if (ir->epc == epcMTTK) { @@ -1401,49 +1437,48 @@ real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *Mas energyNPT += energyPressureMTTK(ir, state, MassQ); } break; - case epcBERENDSEN: - energyNPT += state->baros_integral; - break; + case epcBERENDSEN: energyNPT += state->baros_integral; break; default: - GMX_RELEASE_ASSERT(false, "Conserved energy quantity for pressure coupling is not handled. A case should be added with either the conserved quantity added or nothing added and an exclusion added to integratorHasConservedEnergyQuantity()."); + GMX_RELEASE_ASSERT( + false, + "Conserved energy quantity for pressure coupling is not handled. A case " + "should be added with either the conserved quantity added or nothing added " + "and an exclusion added to integratorHasConservedEnergyQuantity()."); } } switch (ir->etc) { - case etcNO: - break; + case etcNO: break; case etcVRESCALE: - case etcBERENDSEN: - energyNPT += energyVrescale(ir, state); - break; - case etcNOSEHOOVER: - energyNPT += energyNoseHoover(ir, state, MassQ); - break; + case etcBERENDSEN: energyNPT += energyVrescale(ir, state); break; + case etcNOSEHOOVER: energyNPT += energyNoseHoover(ir, state, MassQ); break; case etcANDERSEN: case etcANDERSENMASSIVE: // Not supported, excluded in integratorHasConservedEnergyQuantity() break; default: - GMX_RELEASE_ASSERT(false, "Conserved energy quantity for temperature coupling is not handled. A case should be added with either the conserved quantity added or nothing added and an exclusion added to integratorHasConservedEnergyQuantity()."); + GMX_RELEASE_ASSERT( + false, + "Conserved energy quantity for temperature coupling is not handled. A case " + "should be added with either the conserved quantity added or nothing added and " + "an exclusion added to integratorHasConservedEnergyQuantity()."); } return energyNPT; } -static real vrescale_sumnoises(real nn, - gmx::ThreeFry2x64<> *rng, - gmx::NormalDistribution *normalDist) +static real vrescale_sumnoises(real nn, gmx::ThreeFry2x64<>* rng, gmx::NormalDistribution* normalDist) { -/* - * Returns the sum of nn independent gaussian noises squared - * (i.e. equivalent to summing the square of the return values - * of nn calls to a normal distribution). - */ - const real ndeg_tol = 0.0001; - real r; - gmx::GammaDistribution gammaDist(0.5*nn, 1.0); + /* + * Returns the sum of nn independent gaussian noises squared + * (i.e. equivalent to summing the square of the return values + * of nn calls to a normal distribution). + */ + const real ndeg_tol = 0.0001; + real r; + gmx::GammaDistribution gammaDist(0.5 * nn, 1.0); if (nn < 2 + ndeg_tol) { @@ -1454,43 +1489,45 @@ static real vrescale_sumnoises(real nn, if (nn - nn_int < -ndeg_tol || nn - nn_int > ndeg_tol) { - gmx_fatal(FARGS, "The v-rescale thermostat was called with a group with #DOF=%f, but for #DOF<3 only integer #DOF are supported", nn + 1); + gmx_fatal(FARGS, + "The v-rescale thermostat was called with a group with #DOF=%f, but for " + "#DOF<3 only integer #DOF are supported", + nn + 1); } r = 0; for (i = 0; i < nn_int; i++) { gauss = (*normalDist)(*rng); - r += gauss*gauss; + r += gauss * gauss; } } else { /* Use a gamma distribution for any real nn > 2 */ - r = 2.0*gammaDist(*rng); + r = 2.0 * gammaDist(*rng); } return r; } -real vrescale_resamplekin(real kk, real sigma, real ndeg, real taut, - int64_t step, int64_t seed) +real vrescale_resamplekin(real kk, real sigma, real ndeg, real taut, int64_t step, int64_t seed) { -/* - * Generates a new value for the kinetic energy, - * according to Bussi et al JCP (2007), Eq. (A7) - * kk: present value of the kinetic energy of the atoms to be thermalized (in arbitrary units) - * sigma: target average value of the kinetic energy (ndeg k_b T/2) (in the same units as kk) - * ndeg: number of degrees of freedom of the atoms to be thermalized - * taut: relaxation time of the thermostat, in units of 'how often this routine is called' - */ - real factor, rr, ekin_new; - gmx::ThreeFry2x64<64> rng(seed, gmx::RandomDomain::Thermostat); - gmx::NormalDistribution normalDist; + /* + * Generates a new value for the kinetic energy, + * according to Bussi et al JCP (2007), Eq. (A7) + * kk: present value of the kinetic energy of the atoms to be thermalized (in arbitrary units) + * sigma: target average value of the kinetic energy (ndeg k_b T/2) (in the same units as kk) + * ndeg: number of degrees of freedom of the atoms to be thermalized + * taut: relaxation time of the thermostat, in units of 'how often this routine is called' + */ + real factor, rr, ekin_new; + gmx::ThreeFry2x64<64> rng(seed, gmx::RandomDomain::Thermostat); + gmx::NormalDistribution normalDist; if (taut > 0.1) { - factor = exp(-1.0/taut); + factor = exp(-1.0 / taut); } else { @@ -1501,19 +1538,17 @@ real vrescale_resamplekin(real kk, real sigma, real ndeg, real taut, rr = normalDist(rng); - ekin_new = - kk + - (1.0 - factor)*(sigma*(vrescale_sumnoises(ndeg-1, &rng, &normalDist) + rr*rr)/ndeg - kk) + - 2.0*rr*std::sqrt(kk*sigma/ndeg*(1.0 - factor)*factor); + ekin_new = kk + + (1.0 - factor) + * (sigma * (vrescale_sumnoises(ndeg - 1, &rng, &normalDist) + rr * rr) / ndeg - kk) + + 2.0 * rr * std::sqrt(kk * sigma / ndeg * (1.0 - factor) * factor); return ekin_new; } -void vrescale_tcoupl(const t_inputrec *ir, int64_t step, - gmx_ekindata_t *ekind, real dt, - double therm_integral[]) +void vrescale_tcoupl(const t_inputrec* ir, int64_t step, gmx_ekindata_t* ekind, real dt, double therm_integral[]) { - const t_grpopts *opts; + const t_grpopts* opts; int i; real Ek, Ek_ref1, Ek_ref, Ek_new; @@ -1532,12 +1567,10 @@ void vrescale_tcoupl(const t_inputrec *ir, int64_t step, if (opts->tau_t[i] >= 0 && opts->nrdf[i] > 0 && Ek > 0) { - Ek_ref1 = 0.5*opts->ref_t[i]*BOLTZ; - Ek_ref = Ek_ref1*opts->nrdf[i]; + Ek_ref1 = 0.5 * opts->ref_t[i] * BOLTZ; + Ek_ref = Ek_ref1 * opts->nrdf[i]; - Ek_new = vrescale_resamplekin(Ek, Ek_ref, opts->nrdf[i], - opts->tau_t[i]/dt, - step, ir->ld_seed); + Ek_new = vrescale_resamplekin(Ek, Ek_ref, opts->nrdf[i], opts->tau_t[i] / dt, step, ir->ld_seed); /* Analytically Ek_new>=0, but we check for rounding errors */ if (Ek_new <= 0) @@ -1546,15 +1579,15 @@ void vrescale_tcoupl(const t_inputrec *ir, int64_t step, } else { - ekind->tcstat[i].lambda = std::sqrt(Ek_new/Ek); + ekind->tcstat[i].lambda = std::sqrt(Ek_new / Ek); } therm_integral[i] -= Ek_new - Ek; if (debug) { - fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", - i, Ek_ref, Ek, Ek_new, ekind->tcstat[i].lambda); + fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", i, Ek_ref, + Ek, Ek_new, ekind->tcstat[i].lambda); } } else @@ -1564,22 +1597,21 @@ void vrescale_tcoupl(const t_inputrec *ir, int64_t step, } } -void rescale_velocities(const gmx_ekindata_t *ekind, const t_mdatoms *mdatoms, - int start, int end, rvec v[]) +void rescale_velocities(const gmx_ekindata_t* ekind, const t_mdatoms* mdatoms, int start, int end, rvec v[]) { unsigned short *cACC, *cTC; int ga, gt, n, d; real lg; rvec vrel; - cTC = mdatoms->cTC; + cTC = mdatoms->cTC; gmx::ArrayRef tcstat = ekind->tcstat; if (ekind->bNEMD) { gmx::ArrayRef gstat = ekind->grpstat; - cACC = mdatoms->cACC; + cACC = mdatoms->cACC; ga = 0; gt = 0; @@ -1587,18 +1619,18 @@ void rescale_velocities(const gmx_ekindata_t *ekind, const t_mdatoms *mdatoms, { if (cACC) { - ga = cACC[n]; + ga = cACC[n]; } if (cTC) { - gt = cTC[n]; + gt = cTC[n]; } /* Only scale the velocity component relative to the COM velocity */ rvec_sub(v[n], gstat[ga].u, vrel); lg = tcstat[gt].lambda; for (d = 0; d < DIM; d++) { - v[n][d] = gstat[ga].u[d] + lg*vrel[d]; + v[n][d] = gstat[ga].u[d] + lg * vrel[d]; } } } @@ -1609,7 +1641,7 @@ void rescale_velocities(const gmx_ekindata_t *ekind, const t_mdatoms *mdatoms, { if (cTC) { - gt = cTC[n]; + gt = cTC[n]; } lg = tcstat[gt].lambda; for (d = 0; d < DIM; d++) @@ -1621,7 +1653,7 @@ void rescale_velocities(const gmx_ekindata_t *ekind, const t_mdatoms *mdatoms, } //! Check whether we're doing simulated annealing -bool doSimulatedAnnealing(const t_inputrec *ir) +bool doSimulatedAnnealing(const t_inputrec* ir) { for (int i = 0; i < ir->opts.ngtc; i++) { @@ -1636,8 +1668,7 @@ bool doSimulatedAnnealing(const t_inputrec *ir) // TODO If we keep simulated annealing, make a proper module that // does not rely on changing inputrec. -bool initSimulatedAnnealing(t_inputrec *ir, - gmx::Update *upd) +bool initSimulatedAnnealing(t_inputrec* ir, gmx::Update* upd) { bool doSimAnnealing = doSimulatedAnnealing(ir); if (doSimAnnealing) @@ -1648,7 +1679,7 @@ bool initSimulatedAnnealing(t_inputrec *ir, } /* set target temperatures if we are annealing */ -void update_annealing_target_temp(t_inputrec *ir, real t, gmx::Update *upd) +void update_annealing_target_temp(t_inputrec* ir, real t, gmx::Update* upd) { int i, j, n, npoints; real pert, thist = 0, x; @@ -1658,61 +1689,59 @@ void update_annealing_target_temp(t_inputrec *ir, real t, gmx::Update *upd) npoints = ir->opts.anneal_npoints[i]; switch (ir->opts.annealing[i]) { - case eannNO: - continue; - case eannPERIODIC: + case eannNO: continue; + case eannPERIODIC: /* calculate time modulo the period */ - pert = ir->opts.anneal_time[i][npoints-1]; + pert = ir->opts.anneal_time[i][npoints - 1]; n = static_cast(t / pert); - thist = t - n*pert; /* modulo time */ + thist = t - n * pert; /* modulo time */ /* Make sure rounding didn't get us outside the interval */ - if (std::fabs(thist-pert) < GMX_REAL_EPS*100) + if (std::fabs(thist - pert) < GMX_REAL_EPS * 100) { thist = 0; } break; - case eannSINGLE: - thist = t; - break; + case eannSINGLE: thist = t; break; default: - gmx_fatal(FARGS, "Death horror in update_annealing_target_temp (i=%d/%d npoints=%d)", i, ir->opts.ngtc, npoints); + gmx_fatal(FARGS, "Death horror in update_annealing_target_temp (i=%d/%d npoints=%d)", + i, ir->opts.ngtc, npoints); } /* We are doing annealing for this group if we got here, * and we have the (relative) time as thist. * calculate target temp */ j = 0; - while ((j < npoints-1) && (thist > (ir->opts.anneal_time[i][j+1]))) + while ((j < npoints - 1) && (thist > (ir->opts.anneal_time[i][j + 1]))) { j++; } - if (j < npoints-1) + if (j < npoints - 1) { /* Found our position between points j and j+1. * Interpolate: x is the amount from j+1, (1-x) from point j * First treat possible jumps in temperature as a special case. */ - if ((ir->opts.anneal_time[i][j+1]-ir->opts.anneal_time[i][j]) < GMX_REAL_EPS*100) + if ((ir->opts.anneal_time[i][j + 1] - ir->opts.anneal_time[i][j]) < GMX_REAL_EPS * 100) { - ir->opts.ref_t[i] = ir->opts.anneal_temp[i][j+1]; + ir->opts.ref_t[i] = ir->opts.anneal_temp[i][j + 1]; } else { - x = ((thist-ir->opts.anneal_time[i][j])/ - (ir->opts.anneal_time[i][j+1]-ir->opts.anneal_time[i][j])); - ir->opts.ref_t[i] = x*ir->opts.anneal_temp[i][j+1]+(1-x)*ir->opts.anneal_temp[i][j]; + x = ((thist - ir->opts.anneal_time[i][j]) + / (ir->opts.anneal_time[i][j + 1] - ir->opts.anneal_time[i][j])); + ir->opts.ref_t[i] = + x * ir->opts.anneal_temp[i][j + 1] + (1 - x) * ir->opts.anneal_temp[i][j]; } } else { - ir->opts.ref_t[i] = ir->opts.anneal_temp[i][npoints-1]; + ir->opts.ref_t[i] = ir->opts.anneal_temp[i][npoints - 1]; } } update_temperature_constants(upd->sd(), ir); } -void pleaseCiteCouplingAlgorithms(FILE *fplog, - const t_inputrec &ir) +void pleaseCiteCouplingAlgorithms(FILE* fplog, const t_inputrec& ir) { if (EI_DYNAMICS(ir.eI)) { diff --git a/src/gromacs/mdlib/dispersioncorrection.cpp b/src/gromacs/mdlib/dispersioncorrection.cpp index 4c7b2d9049..7cbd9e41c7 100644 --- a/src/gromacs/mdlib/dispersioncorrection.cpp +++ b/src/gromacs/mdlib/dispersioncorrection.cpp @@ -56,37 +56,35 @@ DispersionCorrection::InteractionParams::~InteractionParams() = default; /* Returns a matrix, as flat list, of combination rule combined LJ parameters */ -static std::vector mk_nbfp_combination_rule(const gmx_ffparams_t &ffparams, - const int comb_rule) +static std::vector mk_nbfp_combination_rule(const gmx_ffparams_t& ffparams, const int comb_rule) { - const int atnr = ffparams.atnr; + const int atnr = ffparams.atnr; - std::vector nbfp(atnr*atnr*2); + std::vector nbfp(atnr * atnr * 2); for (int i = 0; i < atnr; ++i) { for (int j = 0; j < atnr; ++j) { - const real c6i = ffparams.iparams[i*(atnr + 1)].lj.c6; - const real c12i = ffparams.iparams[i*(atnr + 1)].lj.c12; - const real c6j = ffparams.iparams[j*(atnr + 1)].lj.c6; - const real c12j = ffparams.iparams[j*(atnr + 1)].lj.c12; - real c6 = std::sqrt(c6i * c6j); + const real c6i = ffparams.iparams[i * (atnr + 1)].lj.c6; + const real c12i = ffparams.iparams[i * (atnr + 1)].lj.c12; + const real c6j = ffparams.iparams[j * (atnr + 1)].lj.c6; + const real c12j = ffparams.iparams[j * (atnr + 1)].lj.c12; + real c6 = std::sqrt(c6i * c6j); real c12 = std::sqrt(c12i * c12j); - if (comb_rule == eCOMB_ARITHMETIC - && !gmx_numzero(c6) && !gmx_numzero(c12)) + if (comb_rule == eCOMB_ARITHMETIC && !gmx_numzero(c6) && !gmx_numzero(c12)) { const real sigmai = gmx::sixthroot(c12i / c6i); const real sigmaj = gmx::sixthroot(c12j / c6j); const real epsi = c6i * c6i / c12i; const real epsj = c6j * c6j / c12j; - const real sigma = 0.5*(sigmai + sigmaj); + const real sigma = 0.5 * (sigmai + sigmaj); const real eps = std::sqrt(epsi * epsj); c6 = eps * gmx::power6(sigma); c12 = eps * gmx::power12(sigma); } - C6(nbfp, atnr, i, j) = c6*6.0; - C12(nbfp, atnr, i, j) = c12*12.0; + C6(nbfp, atnr, i, j) = c6 * 6.0; + C12(nbfp, atnr, i, j) = c12 * 12.0; } } @@ -94,8 +92,7 @@ static std::vector mk_nbfp_combination_rule(const gmx_ffparams_t &ffparams } /* Returns the A-topology atom type when aOrB=0, the B-topology atom type when aOrB=1 */ -static int atomtypeAOrB(const t_atom &atom, - int aOrB) +static int atomtypeAOrB(const t_atom& atom, int aOrB) { if (aOrB == 0) { @@ -107,30 +104,30 @@ static int atomtypeAOrB(const t_atom &atom, } } -DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t &mtop, - const t_inputrec &inputrec, - bool useBuckingham, - int numAtomTypes, - gmx::ArrayRef nonbondedForceParameters) +DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t& mtop, + const t_inputrec& inputrec, + bool useBuckingham, + int numAtomTypes, + gmx::ArrayRef nonbondedForceParameters) { - const int ntp = numAtomTypes; - const gmx_bool bBHAM = useBuckingham; + const int ntp = numAtomTypes; + const gmx_bool bBHAM = useBuckingham; - gmx::ArrayRef nbfp = nonbondedForceParameters; + gmx::ArrayRef nbfp = nonbondedForceParameters; std::vector nbfp_comb; /* For LJ-PME, we want to correct for the difference between the * actual C6 values and the C6 values used by the LJ-PME based on * combination rules. */ if (EVDW_PME(inputrec.vdwtype)) { - nbfp_comb = mk_nbfp_combination_rule(mtop.ffparams, - (inputrec.ljpme_combination_rule == eljpmeLB) ? eCOMB_ARITHMETIC : eCOMB_GEOMETRIC); + nbfp_comb = mk_nbfp_combination_rule( + mtop.ffparams, + (inputrec.ljpme_combination_rule == eljpmeLB) ? eCOMB_ARITHMETIC : eCOMB_GEOMETRIC); for (int tpi = 0; tpi < ntp; ++tpi) { for (int tpj = 0; tpj < ntp; ++tpj) { - C6(nbfp_comb, ntp, tpi, tpj) = - C6(nbfp, ntp, tpi, tpj) - C6(nbfp_comb, ntp, tpi, tpj); + C6(nbfp_comb, ntp, tpi, tpj) = C6(nbfp, ntp, tpi, tpj) - C6(nbfp_comb, ntp, tpi, tpj); C12(nbfp_comb, ntp, tpi, tpj) = C12(nbfp, ntp, tpi, tpj); } } @@ -146,7 +143,7 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & if (!EI_TPI(inputrec.eI)) { numAtomsForDensity_ = mtop.natoms; - numCorrections_ = 0.5*mtop.natoms; + numCorrections_ = 0.5 * mtop.natoms; /* Count the types so we avoid natoms^2 operations */ std::vector typecount(ntp); @@ -161,22 +158,22 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & int npair_ij; if (tpi != tpj) { - npair_ij = iCount*jCount; + npair_ij = iCount * jCount; } else { - npair_ij = iCount*(iCount - 1)/2; + npair_ij = iCount * (iCount - 1) / 2; } if (bBHAM) { /* nbfp now includes the 6.0 derivative prefactor */ - csix += npair_ij*BHAMC(nbfp, ntp, tpi, tpj)/6.0; + csix += npair_ij * BHAMC(nbfp, ntp, tpi, tpj) / 6.0; } else { /* nbfp now includes the 6.0/12.0 derivative prefactors */ - csix += npair_ij* C6(nbfp, ntp, tpi, tpj)/6.0; - ctwelve += npair_ij* C12(nbfp, ntp, tpi, tpj)/12.0; + csix += npair_ij * C6(nbfp, ntp, tpi, tpj) / 6.0; + ctwelve += npair_ij * C12(nbfp, ntp, tpi, tpj) / 12.0; } npair += npair_ij; } @@ -187,16 +184,16 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & * any value. These unused values should not influence the dispersion * correction. */ - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { const int nmol = molb.nmol; - const t_atoms *atoms = &mtop.moltype[molb.type].atoms; - const t_blocka *excl = &mtop.moltype[molb.type].excls; + const t_atoms* atoms = &mtop.moltype[molb.type].atoms; + const t_blocka* excl = &mtop.moltype[molb.type].excls; for (int i = 0; (i < atoms->nr); i++) { - const int tpi = atomtypeAOrB( atoms->atom[i], q); + const int tpi = atomtypeAOrB(atoms->atom[i], q); const int j1 = excl->index[i]; - const int j2 = excl->index[i+1]; + const int j2 = excl->index[i + 1]; for (int j = j1; j < j2; j++) { const int k = excl->a[j]; @@ -206,13 +203,13 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & if (bBHAM) { /* nbfp now includes the 6.0 derivative prefactor */ - csix -= nmol*BHAMC(nbfp, ntp, tpi, tpj)/6.0; + csix -= nmol * BHAMC(nbfp, ntp, tpi, tpj) / 6.0; } else { /* nbfp now includes the 6.0/12.0 derivative prefactors */ - csix -= nmol*C6 (nbfp, ntp, tpi, tpj)/6.0; - ctwelve -= nmol*C12(nbfp, ntp, tpi, tpj)/12.0; + csix -= nmol * C6(nbfp, ntp, tpi, tpj) / 6.0; + ctwelve -= nmol * C12(nbfp, ntp, tpi, tpj) / 12.0; } nexcl += molb.nmol; } @@ -222,20 +219,19 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & } else { - const t_atoms &atoms_tpi = - mtop.moltype[mtop.molblock.back().type].atoms; + const t_atoms& atoms_tpi = mtop.moltype[mtop.molblock.back().type].atoms; /* Only correct for the interaction of the test particle * with the rest of the system. */ - numAtomsForDensity_ = mtop.natoms - atoms_tpi.nr; - numCorrections_ = atoms_tpi.nr; + numAtomsForDensity_ = mtop.natoms - atoms_tpi.nr; + numCorrections_ = atoms_tpi.nr; npair = 0; for (size_t mb = 0; mb < mtop.molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop.molblock[mb]; - const t_atoms &atoms = mtop.moltype[molb.type].atoms; + const gmx_molblock_t& molb = mtop.molblock[mb]; + const t_atoms& atoms = mtop.moltype[molb.type].atoms; for (int j = 0; j < atoms.nr; j++) { int nmolc = molb.nmol; @@ -248,7 +244,8 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & if (mb == 0 && molb.nmol == 1) { - gmx_fatal(FARGS, "Old format tpr with TPI, please generate a new tpr file"); + gmx_fatal(FARGS, + "Old format tpr with TPI, please generate a new tpr file"); } } const int tpj = atomtypeAOrB(atoms.atom[j], q); @@ -258,13 +255,13 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & if (bBHAM) { /* nbfp now includes the 6.0 derivative prefactor */ - csix += nmolc*BHAMC(nbfp, ntp, tpi, tpj)/6.0; + csix += nmolc * BHAMC(nbfp, ntp, tpi, tpj) / 6.0; } else { /* nbfp now includes the 6.0/12.0 derivative prefactors */ - csix += nmolc*C6 (nbfp, ntp, tpi, tpj)/6.0; - ctwelve += nmolc*C12(nbfp, ntp, tpi, tpj)/12.0; + csix += nmolc * C6(nbfp, ntp, tpi, tpj) / 6.0; + ctwelve += nmolc * C12(nbfp, ntp, tpi, tpj) / 12.0; } npair += nmolc; } @@ -273,12 +270,12 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & } if (npair - nexcl <= 0) { - csix = 0; - ctwelve = 0; + csix = 0; + ctwelve = 0; } else { - csix /= npair - nexcl; + csix /= npair - nexcl; ctwelve /= npair - nexcl; } if (debug) @@ -292,18 +289,17 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t & } } -static void -integrate_table(const real vdwtab[], - const real scale, - const int offstart, - const int rstart, - const int rend, - double *enerout, - double *virout) +static void integrate_table(const real vdwtab[], + const real scale, + const int offstart, + const int rstart, + const int rend, + double* enerout, + double* virout) { - const double invscale = 1.0/scale; - const double invscale2 = invscale*invscale; - const double invscale3 = invscale*invscale2; + const double invscale = 1.0 / scale; + const double invscale2 = invscale * invscale; + const double invscale3 = invscale * invscale2; /* Following summation derived from cubic spline definition, * Numerical Recipies in C, second edition, p. 113-116. Exact for @@ -321,34 +317,36 @@ integrate_table(const real vdwtab[], */ const double tabfactor = (offstart == 0 ? 6.0 : 12.0); - double enersum = 0.0; - double virsum = 0.0; + double enersum = 0.0; + double virsum = 0.0; for (int ri = rstart; ri < rend; ++ri) { - const double r = ri*invscale; + const double r = ri * invscale; const double ea = invscale3; - const double eb = 2.0*invscale2*r; - const double ec = invscale*r*r; + const double eb = 2.0 * invscale2 * r; + const double ec = invscale * r * r; const double pa = invscale3; - const double pb = 3.0*invscale2*r; - const double pc = 3.0*invscale*r*r; - const double pd = r*r*r; + const double pb = 3.0 * invscale2 * r; + const double pc = 3.0 * invscale * r * r; + const double pd = r * r * r; /* this "8" is from the packing in the vdwtab array - perhaps should be defined? */ - const int offset = 8*ri + offstart; + const int offset = 8 * ri + offstart; const double y0 = vdwtab[offset]; - const double f = vdwtab[offset+1]; - const double g = vdwtab[offset+2]; - const double h = vdwtab[offset+3]; - - enersum += y0*(ea/3 + eb/2 + ec) + f*(ea/4 + eb/3 + ec/2) + g*(ea/5 + eb/4 + ec/3) + h*(ea/6 + eb/5 + ec/4); - virsum += f*(pa/4 + pb/3 + pc/2 + pd) + 2*g*(pa/5 + pb/4 + pc/3 + pd/2) + 3*h*(pa/6 + pb/5 + pc/4 + pd/3); + const double f = vdwtab[offset + 1]; + const double g = vdwtab[offset + 2]; + const double h = vdwtab[offset + 3]; + + enersum += y0 * (ea / 3 + eb / 2 + ec) + f * (ea / 4 + eb / 3 + ec / 2) + + g * (ea / 5 + eb / 4 + ec / 3) + h * (ea / 6 + eb / 5 + ec / 4); + virsum += f * (pa / 4 + pb / 3 + pc / 2 + pd) + 2 * g * (pa / 5 + pb / 4 + pc / 3 + pd / 2) + + 3 * h * (pa / 6 + pb / 5 + pc / 4 + pd / 3); } - *enerout = 4.0*M_PI*enersum*tabfactor; - *virout = 4.0*M_PI*virsum*tabfactor; + *enerout = 4.0 * M_PI * enersum * tabfactor; + *virout = 4.0 * M_PI * virsum * tabfactor; } /* Struct for storing and passing energy or virial corrections */ @@ -359,23 +357,22 @@ struct InteractionCorrection }; /* Adds the energy and virial corrections beyond the cut-off */ -static void addCorrectionBeyondCutoff(InteractionCorrection *energy, - InteractionCorrection *virial, +static void addCorrectionBeyondCutoff(InteractionCorrection* energy, + InteractionCorrection* virial, const double cutoffDistance) { - const double rc3 = cutoffDistance*cutoffDistance*cutoffDistance; - const double rc9 = rc3*rc3*rc3; + const double rc3 = cutoffDistance * cutoffDistance * cutoffDistance; + const double rc9 = rc3 * rc3 * rc3; - energy->dispersion += -4.0*M_PI/(3.0*rc3); - energy->repulsion += 4.0*M_PI/(9.0*rc9); - virial->dispersion += 8.0*M_PI/rc3; - virial->repulsion += -16.0*M_PI/(3.0*rc9); + energy->dispersion += -4.0 * M_PI / (3.0 * rc3); + energy->repulsion += 4.0 * M_PI / (9.0 * rc9); + virial->dispersion += 8.0 * M_PI / rc3; + virial->repulsion += -16.0 * M_PI / (3.0 * rc9); } -void -DispersionCorrection::setInteractionParameters(InteractionParams *iParams, - const interaction_const_t &ic, - const char *tableFileName) +void DispersionCorrection::setInteractionParameters(InteractionParams* iParams, + const interaction_const_t& ic, + const char* tableFileName) { /* We only need to set the tables at first call, i.e. tableFileName!=nullptr * or when we changed the cut-off with LJ-PME tuning. @@ -383,25 +380,24 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam if (tableFileName || EVDW_PME(ic.vdwtype)) { iParams->dispersionCorrectionTable_ = - makeDispersionCorrectionTable(nullptr, &ic, ic.rvdw, tableFileName); + makeDispersionCorrectionTable(nullptr, &ic, ic.rvdw, tableFileName); } InteractionCorrection energy; InteractionCorrection virial; - if ((ic.vdw_modifier == eintmodPOTSHIFT) || - (ic.vdw_modifier == eintmodPOTSWITCH) || - (ic.vdw_modifier == eintmodFORCESWITCH) || - (ic.vdwtype == evdwSHIFT) || - (ic.vdwtype == evdwSWITCH)) + if ((ic.vdw_modifier == eintmodPOTSHIFT) || (ic.vdw_modifier == eintmodPOTSWITCH) + || (ic.vdw_modifier == eintmodFORCESWITCH) || (ic.vdwtype == evdwSHIFT) + || (ic.vdwtype == evdwSWITCH)) { - if (((ic.vdw_modifier == eintmodPOTSWITCH) || - (ic.vdw_modifier == eintmodFORCESWITCH) || - (ic.vdwtype == evdwSWITCH)) && ic.rvdw_switch == 0) + if (((ic.vdw_modifier == eintmodPOTSWITCH) || (ic.vdw_modifier == eintmodFORCESWITCH) + || (ic.vdwtype == evdwSWITCH)) + && ic.rvdw_switch == 0) { gmx_fatal(FARGS, "With dispersion correction rvdw-switch can not be zero " - "for vdw-type = %s", evdw_names[ic.vdwtype]); + "for vdw-type = %s", + evdw_names[ic.vdwtype]); } GMX_ASSERT(iParams->dispersionCorrectionTable_, "We need an initialized table"); @@ -410,13 +406,14 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam constructs the table layout, which should be made explicit in future cleanup. */ GMX_ASSERT(iParams->dispersionCorrectionTable_->interaction == GMX_TABLE_INTERACTION_VDWREP_VDWDISP, - "Dispersion-correction code needs a table with both repulsion and dispersion terms"); + "Dispersion-correction code needs a table with both repulsion and dispersion " + "terms"); const real scale = iParams->dispersionCorrectionTable_->scale; - const real *vdwtab = iParams->dispersionCorrectionTable_->data; + const real* vdwtab = iParams->dispersionCorrectionTable_->data; /* Round the cut-offs to exact table values for precision */ - int ri0 = static_cast(std::floor(ic.rvdw_switch*scale)); - int ri1 = static_cast(std::ceil(ic.rvdw*scale)); + int ri0 = static_cast(std::floor(ic.rvdw_switch * scale)); + int ri1 = static_cast(std::ceil(ic.rvdw * scale)); /* The code below has some support for handling force-switching, i.e. * when the force (instead of potential) is switched over a limited @@ -434,26 +431,25 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam * we need to calculate the constant shift up to the point where we * start modifying the potential. */ - ri0 = (ic.vdw_modifier == eintmodPOTSHIFT) ? ri1 : ri0; + ri0 = (ic.vdw_modifier == eintmodPOTSHIFT) ? ri1 : ri0; - const double r0 = ri0/scale; - const double rc3 = r0*r0*r0; - const double rc9 = rc3*rc3*rc3; + const double r0 = ri0 / scale; + const double rc3 = r0 * r0 * r0; + const double rc9 = rc3 * rc3 * rc3; - if ((ic.vdw_modifier == eintmodFORCESWITCH) || - (ic.vdwtype == evdwSHIFT)) + if ((ic.vdw_modifier == eintmodFORCESWITCH) || (ic.vdwtype == evdwSHIFT)) { /* Determine the constant energy shift below rvdw_switch. * Table has a scale factor since we have scaled it down to compensate * for scaling-up c6/c12 with the derivative factors to save flops in analytical kernels. */ - iParams->enershiftsix_ = static_cast(-1.0/(rc3*rc3)) - 6.0*vdwtab[8*ri0]; - iParams->enershifttwelve_ = static_cast( 1.0/(rc9*rc3)) - 12.0*vdwtab[8*ri0 + 4]; + iParams->enershiftsix_ = static_cast(-1.0 / (rc3 * rc3)) - 6.0 * vdwtab[8 * ri0]; + iParams->enershifttwelve_ = static_cast(1.0 / (rc9 * rc3)) - 12.0 * vdwtab[8 * ri0 + 4]; } else if (ic.vdw_modifier == eintmodPOTSHIFT) { - iParams->enershiftsix_ = static_cast(-1.0/(rc3*rc3)); - iParams->enershifttwelve_ = static_cast( 1.0/(rc9*rc3)); + iParams->enershiftsix_ = static_cast(-1.0 / (rc3 * rc3)); + iParams->enershifttwelve_ = static_cast(1.0 / (rc9 * rc3)); } /* Add the constant part from 0 to rvdw_switch. @@ -461,8 +457,8 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam * of interactions by 1, as it also counts the self interaction. * We will correct for this later. */ - energy.dispersion += 4.0*M_PI*iParams->enershiftsix_*rc3/3.0; - energy.repulsion += 4.0*M_PI*iParams->enershifttwelve_*rc3/3.0; + energy.dispersion += 4.0 * M_PI * iParams->enershiftsix_ * rc3 / 3.0; + energy.repulsion += 4.0 * M_PI * iParams->enershifttwelve_ * rc3 / 3.0; /* Calculate the contribution in the range [r0,r1] where we * modify the potential. For a pure potential-shift modifier we will @@ -488,9 +484,7 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam */ addCorrectionBeyondCutoff(&energy, &virial, r0); } - else if (ic.vdwtype == evdwCUT || - EVDW_PME(ic.vdwtype) || - ic.vdwtype == evdwUSER) + else if (ic.vdwtype == evdwCUT || EVDW_PME(ic.vdwtype) || ic.vdwtype == evdwUSER) { /* Note that with LJ-PME, the dispersion correction is multiplied * by the difference between the actual C6 and the value of C6 @@ -499,38 +493,37 @@ DispersionCorrection::setInteractionParameters(InteractionParams *iParam * can be used here. */ - const double rc3 = ic.rvdw*ic.rvdw*ic.rvdw; - const double rc9 = rc3*rc3*rc3; + const double rc3 = ic.rvdw * ic.rvdw * ic.rvdw; + const double rc9 = rc3 * rc3 * rc3; if (ic.vdw_modifier == eintmodPOTSHIFT) { /* Contribution within the cut-off */ - energy.dispersion += -4.0*M_PI/(3.0*rc3); - energy.repulsion += 4.0*M_PI/(3.0*rc9); + energy.dispersion += -4.0 * M_PI / (3.0 * rc3); + energy.repulsion += 4.0 * M_PI / (3.0 * rc9); } /* Contribution beyond the cut-off */ addCorrectionBeyondCutoff(&energy, &virial, ic.rvdw); } else { - gmx_fatal(FARGS, - "Dispersion correction is not implemented for vdw-type = %s", + gmx_fatal(FARGS, "Dispersion correction is not implemented for vdw-type = %s", evdw_names[ic.vdwtype]); } iParams->enerdiffsix_ = energy.dispersion; iParams->enerdifftwelve_ = energy.repulsion; /* The 0.5 is due to the Gromacs definition of the virial */ - iParams->virdiffsix_ = 0.5*virial.dispersion; - iParams->virdifftwelve_ = 0.5*virial.repulsion; + iParams->virdiffsix_ = 0.5 * virial.dispersion; + iParams->virdifftwelve_ = 0.5 * virial.repulsion; } -DispersionCorrection::DispersionCorrection(const gmx_mtop_t &mtop, - const t_inputrec &inputrec, +DispersionCorrection::DispersionCorrection(const gmx_mtop_t& mtop, + const t_inputrec& inputrec, bool useBuckingham, int numAtomTypes, gmx::ArrayRef nonbondedForceParameters, - const interaction_const_t &ic, - const char *tableFileName) : + const interaction_const_t& ic, + const char* tableFileName) : eDispCorr_(inputrec.eDispCorr), vdwType_(inputrec.vdwtype), eFep_(inputrec.efep), @@ -549,28 +542,30 @@ bool DispersionCorrection::correctFullInteraction() const return (eDispCorr_ == edispcAllEner || eDispCorr_ == edispcAllEnerPres); } -void DispersionCorrection::print(const gmx::MDLogger &mdlog) const +void DispersionCorrection::print(const gmx::MDLogger& mdlog) const { if (topParams_.avcsix_[0] == 0 && topParams_.avctwelve_[0] == 0) { - GMX_LOG(mdlog.warning).asParagraph().appendText("WARNING: There are no atom pairs for dispersion correction"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("WARNING: There are no atom pairs for dispersion correction"); } else if (vdwType_ == evdwUSER) { - GMX_LOG(mdlog.warning).asParagraph().appendText("WARNING: using dispersion correction with user tables\n"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("WARNING: using dispersion correction with user tables\n"); } - std::string text = gmx::formatString("Long Range LJ corr.: %10.4e", - topParams_.avcsix_[0]); + std::string text = gmx::formatString("Long Range LJ corr.: %10.4e", topParams_.avcsix_[0]); if (correctFullInteraction()) { - text += gmx::formatString(" %10.4e", - topParams_.avctwelve_[0]); + text += gmx::formatString(" %10.4e", topParams_.avctwelve_[0]); } GMX_LOG(mdlog.info).appendText(text); } -void DispersionCorrection::setParameters(const interaction_const_t &ic) +void DispersionCorrection::setParameters(const interaction_const_t& ic) { if (eDispCorr_ != edispcNO) { @@ -578,9 +573,7 @@ void DispersionCorrection::setParameters(const interaction_const_t &ic) } } -DispersionCorrection::Correction -DispersionCorrection::calculate(const matrix box, - const real lambda) const +DispersionCorrection::Correction DispersionCorrection::calculate(const matrix box, const real lambda) const { Correction corr; @@ -591,15 +584,14 @@ DispersionCorrection::calculate(const matrix box, } const bool bCorrAll = correctFullInteraction(); - const bool bCorrPres = (eDispCorr_ == edispcEnerPres || - eDispCorr_ == edispcAllEnerPres); + const bool bCorrPres = (eDispCorr_ == edispcEnerPres || eDispCorr_ == edispcAllEnerPres); - const real invvol = 1/det(box); - const real density = topParams_.numAtomsForDensity_*invvol; - const real numCorr = topParams_.numCorrections_; + const real invvol = 1 / det(box); + const real density = topParams_.numAtomsForDensity_ * invvol; + const real numCorr = topParams_.numCorrections_; - real avcsix; - real avctwelve; + real avcsix; + real avctwelve; if (eFep_ == efepNO) { avcsix = topParams_.avcsix_[0]; @@ -607,36 +599,36 @@ DispersionCorrection::calculate(const matrix box, } else { - avcsix = (1 - lambda)*topParams_.avcsix_[0] + lambda*topParams_.avcsix_[1]; - avctwelve = (1 - lambda)*topParams_.avctwelve_[0] + lambda*topParams_.avctwelve_[1]; + avcsix = (1 - lambda) * topParams_.avcsix_[0] + lambda * topParams_.avcsix_[1]; + avctwelve = (1 - lambda) * topParams_.avctwelve_[0] + lambda * topParams_.avctwelve_[1]; } - const real enerdiff = numCorr*(density*iParams_.enerdiffsix_ - iParams_.enershiftsix_); - corr.energy += avcsix*enerdiff; - real dvdlambda = 0; + const real enerdiff = numCorr * (density * iParams_.enerdiffsix_ - iParams_.enershiftsix_); + corr.energy += avcsix * enerdiff; + real dvdlambda = 0; if (eFep_ != efepNO) { - dvdlambda += (topParams_.avcsix_[1] - topParams_.avcsix_[0])*enerdiff; + dvdlambda += (topParams_.avcsix_[1] - topParams_.avcsix_[0]) * enerdiff; } if (bCorrAll) { - const real enerdiff = numCorr*(density*iParams_.enerdifftwelve_ - iParams_.enershifttwelve_); - corr.energy += avctwelve*enerdiff; + const real enerdiff = numCorr * (density * iParams_.enerdifftwelve_ - iParams_.enershifttwelve_); + corr.energy += avctwelve * enerdiff; if (eFep_ != efepNO) { - dvdlambda += (topParams_.avctwelve_[1] - topParams_.avctwelve_[0])*enerdiff; + dvdlambda += (topParams_.avctwelve_[1] - topParams_.avctwelve_[0]) * enerdiff; } } if (bCorrPres) { - corr.virial = numCorr*density*avcsix*iParams_.virdiffsix_/3.0; + corr.virial = numCorr * density * avcsix * iParams_.virdiffsix_ / 3.0; if (eDispCorr_ == edispcAllEnerPres) { - corr.virial += numCorr*density*avctwelve*iParams_.virdifftwelve_/3.0; + corr.virial += numCorr * density * avctwelve * iParams_.virdifftwelve_ / 3.0; } /* The factor 2 is because of the Gromacs virial definition */ - corr.pressure = -2.0*invvol*corr.virial*PRESFAC; + corr.pressure = -2.0 * invvol * corr.virial * PRESFAC; } if (eFep_ != efepNO) diff --git a/src/gromacs/mdlib/dispersioncorrection.h b/src/gromacs/mdlib/dispersioncorrection.h index 89e5130e1f..88c8c7b40b 100644 --- a/src/gromacs/mdlib/dispersioncorrection.h +++ b/src/gromacs/mdlib/dispersioncorrection.h @@ -55,149 +55,147 @@ class MDLogger; class DispersionCorrection { - public: - /*! \brief Constructor - * - * \param[in] mtop The global topology - * \param[in] inputrec The input record - * \param[in] useBuckingham True when Buckingham is used instead of LJ - * \param[in] numAtomTypes The number of non-bonded atom types - * \param[in] nonbondedForceParameters The LJ or Bham parameter matrix stored as a flat list - * \param[in] ic The nonbonded interaction parameters - * \param[in] tableFileName Table file name, should != nullptr (checked) - */ - DispersionCorrection(const gmx_mtop_t &mtop, - const t_inputrec &inputrec, - bool useBuckingham, - int numAtomTypes, - gmx::ArrayRef nonbondedForceParameters, - const interaction_const_t &ic, - const char *tableFileName); - - /*! \brief Print dispersion correction information to the log file +public: + /*! \brief Constructor + * + * \param[in] mtop The global topology + * \param[in] inputrec The input record + * \param[in] useBuckingham True when Buckingham is used instead of LJ + * \param[in] numAtomTypes The number of non-bonded atom types + * \param[in] nonbondedForceParameters The LJ or Bham parameter matrix stored as a flat list + * \param[in] ic The nonbonded interaction parameters + * \param[in] tableFileName Table file name, should != nullptr (checked) + */ + DispersionCorrection(const gmx_mtop_t& mtop, + const t_inputrec& inputrec, + bool useBuckingham, + int numAtomTypes, + gmx::ArrayRef nonbondedForceParameters, + const interaction_const_t& ic, + const char* tableFileName); + + /*! \brief Print dispersion correction information to the log file + * + * \param[in] mdlog The MD logger + */ + void print(const gmx::MDLogger& mdlog) const; + + /*! \brief Computes and sets energy and virial correction parameters + * + * Sets all parameters that are affected by the cut-off and/or the + * LJ-Ewald coefficient. Should be called before calling calculate() + * and whenever interaction settings change, e.g. PME tuning. + * + * \param[in] ic The nonbonded interaction parameters + */ + void setParameters(const interaction_const_t& ic); + + /*! \internal + * \brief Struct for returning all dispersion correction quantities + */ + struct Correction + { + /*! \brief Correct the virial tensor for the missing dispersion * - * \param[in] mdlog The MD logger + * \param[in,out] virialTensor The virial tensor to correct */ - void print(const gmx::MDLogger &mdlog) const; - - /*! \brief Computes and sets energy and virial correction parameters - * - * Sets all parameters that are affected by the cut-off and/or the - * LJ-Ewald coefficient. Should be called before calling calculate() - * and whenever interaction settings change, e.g. PME tuning. - * - * \param[in] ic The nonbonded interaction parameters - */ - void setParameters(const interaction_const_t &ic); - - /*! \internal - * \brief Struct for returning all dispersion correction quantities - */ - struct Correction + void correctVirial(tensor virialTensor) const { - /*! \brief Correct the virial tensor for the missing dispersion - * - * \param[in,out] virialTensor The virial tensor to correct - */ - void correctVirial(tensor virialTensor) const + for (int m = 0; m < DIM; m++) { - for (int m = 0; m < DIM; m++) - { - virialTensor[m][m] += virial; - } + virialTensor[m][m] += virial; } + } - /*! \brief Correct the pressure tensor for the missing dispersion - * - * \param[in,out] pressureTensor The pressure tensor to correct - */ - void correctPressure(tensor pressureTensor) const - { - for (int m = 0; m < DIM; m++) - { - pressureTensor[m][m] += pressure; - } - } - - real virial = 0; //!< Scalar correction to the virial - real pressure = 0; //!< Scalar correction to the pressure - real energy = 0; //!< Correction to the energy - real dvdl = 0; //!< Correction to dH/dlambda - }; - - /*! \brief Computes and returns the dispersion correction for the pressure and energy + /*! \brief Correct the pressure tensor for the missing dispersion * - * \param[in] box The simulation unit cell - * \param[in] lambda The free-energy coupling parameter - */ - Correction calculate(const matrix box, - real lambda) const; - - private: - /*! \internal \brief Parameters that depend on the topology only - */ - class TopologyParams - { - public: - TopologyParams(const gmx_mtop_t &mtop, - const t_inputrec &inputrec, - bool useBuckingham, - int numAtomTypes, - gmx::ArrayRef nonbondedForceParameters); - - //! The number of atoms for computing the atom density - int numAtomsForDensity_; - //! The number of interactions to correct for, usually num. atoms/2 - real numCorrections_; - //! Average C6 coefficient for for topology A/B ([0]/[1]) - std::array avcsix_; - //! Average C12 coefficient for for topology A/B ([0]/[1]) - std::array avctwelve_; - }; - - /*! \internal \brief Parameters that depend on the interaction functions and topology + * \param[in,out] pressureTensor The pressure tensor to correct */ - struct InteractionParams + void correctPressure(tensor pressureTensor) const { - public: - ~InteractionParams(); - - //! Table used for correcting modified LJ interactions - std::unique_ptr dispersionCorrectionTable_; - - //! Dispersion energy shift constant - real enershiftsix_ = 0; - //! Repulsion energy shift constant - real enershifttwelve_ = 0; - //! Dispersion energy difference per atom per unit of volume - real enerdiffsix_ = 0; - //! Repulsion energy difference per atom per unit of volume - real enerdifftwelve_ = 0; - //! Dispersion virial difference per atom per unit of volume - real virdiffsix_ = 0; - //! Repulsion virial difference per atom per unit of volume - real virdifftwelve_ = 0; - }; - - //! Sets the interaction parameters - static void - setInteractionParameters(DispersionCorrection::InteractionParams *iParams, - const interaction_const_t &ic, - const char *tableFileName); - - //! Returns whether we correct both dispersion and repulsion - bool correctFullInteraction() const; - - //! Type of dispersion correction - int eDispCorr_; - //! Type of Van der Waals interaction - int vdwType_; - //! Free-energy perturbation - int eFep_; - //! Topology parameters - TopologyParams topParams_; - //! Interaction parameters - InteractionParams iParams_; + for (int m = 0; m < DIM; m++) + { + pressureTensor[m][m] += pressure; + } + } + + real virial = 0; //!< Scalar correction to the virial + real pressure = 0; //!< Scalar correction to the pressure + real energy = 0; //!< Correction to the energy + real dvdl = 0; //!< Correction to dH/dlambda + }; + + /*! \brief Computes and returns the dispersion correction for the pressure and energy + * + * \param[in] box The simulation unit cell + * \param[in] lambda The free-energy coupling parameter + */ + Correction calculate(const matrix box, real lambda) const; + +private: + /*! \internal \brief Parameters that depend on the topology only + */ + class TopologyParams + { + public: + TopologyParams(const gmx_mtop_t& mtop, + const t_inputrec& inputrec, + bool useBuckingham, + int numAtomTypes, + gmx::ArrayRef nonbondedForceParameters); + + //! The number of atoms for computing the atom density + int numAtomsForDensity_; + //! The number of interactions to correct for, usually num. atoms/2 + real numCorrections_; + //! Average C6 coefficient for for topology A/B ([0]/[1]) + std::array avcsix_; + //! Average C12 coefficient for for topology A/B ([0]/[1]) + std::array avctwelve_; + }; + + /*! \internal \brief Parameters that depend on the interaction functions and topology + */ + struct InteractionParams + { + public: + ~InteractionParams(); + + //! Table used for correcting modified LJ interactions + std::unique_ptr dispersionCorrectionTable_; + + //! Dispersion energy shift constant + real enershiftsix_ = 0; + //! Repulsion energy shift constant + real enershifttwelve_ = 0; + //! Dispersion energy difference per atom per unit of volume + real enerdiffsix_ = 0; + //! Repulsion energy difference per atom per unit of volume + real enerdifftwelve_ = 0; + //! Dispersion virial difference per atom per unit of volume + real virdiffsix_ = 0; + //! Repulsion virial difference per atom per unit of volume + real virdifftwelve_ = 0; + }; + + //! Sets the interaction parameters + static void setInteractionParameters(DispersionCorrection::InteractionParams* iParams, + const interaction_const_t& ic, + const char* tableFileName); + + //! Returns whether we correct both dispersion and repulsion + bool correctFullInteraction() const; + + //! Type of dispersion correction + int eDispCorr_; + //! Type of Van der Waals interaction + int vdwType_; + //! Free-energy perturbation + int eFep_; + //! Topology parameters + TopologyParams topParams_; + //! Interaction parameters + InteractionParams iParams_; }; #endif diff --git a/src/gromacs/mdlib/ebin.cpp b/src/gromacs/mdlib/ebin.cpp index bdbe5aeadf..9fab6ae682 100644 --- a/src/gromacs/mdlib/ebin.cpp +++ b/src/gromacs/mdlib/ebin.cpp @@ -55,16 +55,16 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -t_ebin *mk_ebin() +t_ebin* mk_ebin() { - t_ebin *eb; + t_ebin* eb; snew(eb, 1); return eb; } -void done_ebin(t_ebin *eb) +void done_ebin(t_ebin* eb) { for (int i = 0; i < eb->nener; i++) { @@ -77,13 +77,13 @@ void done_ebin(t_ebin *eb) sfree(eb); } -int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *unit) +int get_ebin_space(t_ebin* eb, int nener, const char* const enm[], const char* unit) { int index; int i, f; - const char *u; + const char* u; - index = eb->nener; + index = eb->nener; eb->nener += nener; srenew(eb->e, eb->nener); srenew(eb->e_sim, eb->nener); @@ -96,7 +96,7 @@ int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *u eb->e_sim[i].e = 0; eb->e_sim[i].eav = 0; eb->e_sim[i].esum = 0; - eb->enm[i].name = gmx_strdup(enm[i-index]); + eb->enm[i].name = gmx_strdup(enm[i - index]); if (unit != nullptr) { eb->enm[i].unit = gmx_strdup(unit); @@ -112,17 +112,16 @@ int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *u u = unit_energy; for (f = 0; f < F_NRE; f++) { - if (strcmp(eb->enm[i].name, - interaction_function[f].longname) == 0) + if (strcmp(eb->enm[i].name, interaction_function[f].longname) == 0) { /* Only the terms in this list are not energies */ switch (f) { - case F_DISRESVIOL: u = unit_length; break; - case F_ORIRESDEV: u = "obs"; break; - case F_TEMP: u = unit_temp_K; break; + case F_DISRESVIOL: u = unit_length; break; + case F_ORIRESDEV: u = "obs"; break; + case F_TEMP: u = unit_temp_K; break; case F_PDISPCORR: - case F_PRES: u = unit_pres_bar; break; + case F_PRES: u = unit_pres_bar; break; } } } @@ -136,15 +135,15 @@ int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *u // ICC 19 -O3 -msse2 generates wrong code. Lower optimization levels // and other SIMD levels seem fine, however. #if defined __ICC -# pragma intel optimization_level 2 +# pragma intel optimization_level 2 #endif -void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool bSum) +void add_ebin(t_ebin* eb, int entryIndex, int nener, const real ener[], gmx_bool bSum) { int i, m; double e, invmm, diff; t_energy *eg, *egs; - if ((entryIndex+nener > eb->nener) || (entryIndex < 0)) + if ((entryIndex + nener > eb->nener) || (entryIndex < 0)) { gmx_fatal(FARGS, "%s-%d: Energies out of range: entryIndex=%d nener=%d maxener=%d", __FILE__, __LINE__, entryIndex, nener, eb->nener); @@ -154,7 +153,7 @@ void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool for (i = 0; (i < nener); i++) { - eg[i].e = ener[i]; + eg[i].e = ener[i]; } if (bSum) @@ -167,14 +166,14 @@ void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool { for (i = 0; (i < nener); i++) { - eg[i].eav = 0; - eg[i].esum = ener[i]; + eg[i].eav = 0; + eg[i].esum = ener[i]; egs[i].esum += ener[i]; } } else { - invmm = (1.0/m)/(m+1.0); + invmm = (1.0 / m) / (m + 1.0); for (i = 0; (i < nener); i++) { @@ -182,9 +181,9 @@ void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool e = ener[i]; /* first update sigma, then sum */ - diff = eg[i].esum - m*e; - eg[i].eav += diff*diff*invmm; - eg[i].esum += e; + diff = eg[i].esum - m * e; + eg[i].eav += diff * diff * invmm; + eg[i].esum += e; egs[i].esum += e; } } @@ -195,24 +194,26 @@ void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool // and whether eb->nsum was zero, to lift the branches out of the loop // over all possible energy terms, but that is true for a lot of the // ebin and mdebin functionality, so we should do it all or nothing. -void add_ebin_indexed(t_ebin *eb, int entryIndex, gmx::ArrayRef shouldUse, - gmx::ArrayRef ener, gmx_bool bSum) +void add_ebin_indexed(t_ebin* eb, + int entryIndex, + gmx::ArrayRef shouldUse, + gmx::ArrayRef ener, + gmx_bool bSum) { GMX_ASSERT(shouldUse.size() == ener.size(), "View sizes must match"); - GMX_ASSERT(entryIndex+std::count(shouldUse.begin(), shouldUse.end(), true) <= eb->nener, - gmx::formatString("Energies out of range: entryIndex=%d nener=%td maxener=%d", - entryIndex, - std::count(shouldUse.begin(), shouldUse.end(), true), - eb->nener).c_str()); + GMX_ASSERT(entryIndex + std::count(shouldUse.begin(), shouldUse.end(), true) <= eb->nener, + gmx::formatString("Energies out of range: entryIndex=%d nener=%td maxener=%d", entryIndex, + std::count(shouldUse.begin(), shouldUse.end(), true), eb->nener) + .c_str()); GMX_ASSERT(entryIndex >= 0, "Must have non-negative entry"); const int m = eb->nsum; - const double invmm = (m == 0) ? 0 : (1.0/m)/(m+1.0); - t_energy *energyEntry = &(eb->e[entryIndex]); - t_energy *simEnergyEntry = &(eb->e_sim[entryIndex]); + const double invmm = (m == 0) ? 0 : (1.0 / m) / (m + 1.0); + t_energy* energyEntry = &(eb->e[entryIndex]); + t_energy* simEnergyEntry = &(eb->e_sim[entryIndex]); auto shouldUseIter = shouldUse.begin(); - for (const auto &theEnergy : ener) + for (const auto& theEnergy : ener) { if (*shouldUseIter) { @@ -221,16 +222,16 @@ void add_ebin_indexed(t_ebin *eb, int entryIndex, gmx::ArrayRef shouldUse, { if (m == 0) { - energyEntry->eav = 0; - energyEntry->esum = theEnergy; + energyEntry->eav = 0; + energyEntry->esum = theEnergy; simEnergyEntry->esum += theEnergy; } else { /* first update sigma, then sum */ - double diff = energyEntry->esum - m*theEnergy; - energyEntry->eav += diff*diff*invmm; - energyEntry->esum += theEnergy; + double diff = energyEntry->esum - m * theEnergy; + energyEntry->eav += diff * diff * invmm; + energyEntry->esum += theEnergy; simEnergyEntry->esum += theEnergy; } ++simEnergyEntry; @@ -241,27 +242,26 @@ void add_ebin_indexed(t_ebin *eb, int entryIndex, gmx::ArrayRef shouldUse, } } -void ebin_increase_count(int increment, t_ebin *eb, gmx_bool bSum) +void ebin_increase_count(int increment, t_ebin* eb, gmx_bool bSum) { - eb->nsteps += increment; + eb->nsteps += increment; eb->nsteps_sim += increment; if (bSum) { - eb->nsum += increment; + eb->nsum += increment; eb->nsum_sim += increment; } } -void reset_ebin_sums(t_ebin *eb) +void reset_ebin_sums(t_ebin* eb) { eb->nsteps = 0; eb->nsum = 0; /* The actual sums are cleared when the next frame is stored */ } -void pr_ebin(FILE *fp, t_ebin *eb, int entryIndex, int nener, int nperline, - int prmode, gmx_bool bPrHead) +void pr_ebin(FILE* fp, t_ebin* eb, int entryIndex, int nener, int nperline, int prmode, gmx_bool bPrHead) { int i, j, i0; int rc; @@ -283,7 +283,7 @@ void pr_ebin(FILE *fp, t_ebin *eb, int entryIndex, int nener, int nperline, { end = entryIndex + nener; } - for (i = start; (i < end) && rc >= 0; ) + for (i = start; (i < end) && rc >= 0;) { if (bPrHead) { @@ -313,23 +313,19 @@ void pr_ebin(FILE *fp, t_ebin *eb, int entryIndex, int nener, int nperline, { switch (prmode) { - case eprNORMAL: - rc = fprintf(fp, " %12.5e", eb->e[i].e); - break; + case eprNORMAL: rc = fprintf(fp, " %12.5e", eb->e[i].e); break; case eprAVER: if (eb->nsum_sim > 0) { - rc = fprintf(fp, " %12.5e", eb->e_sim[i].esum/eb->nsum_sim); + rc = fprintf(fp, " %12.5e", eb->e_sim[i].esum / eb->nsum_sim); } else { rc = fprintf(fp, " %-12s", "N/A"); } break; - default: gmx_fatal(FARGS, "Invalid print mode %d in pr_ebin", - prmode); + default: gmx_fatal(FARGS, "Invalid print mode %d in pr_ebin", prmode); } - } if (rc >= 0) { diff --git a/src/gromacs/mdlib/ebin.h b/src/gromacs/mdlib/ebin.h index 55ad445f0a..d475e37cf0 100644 --- a/src/gromacs/mdlib/ebin.h +++ b/src/gromacs/mdlib/ebin.h @@ -63,37 +63,40 @@ struct t_ebin { //! Number of thermodynamic terms - int nener; + int nener; //! Name and units for each term - gmx_enxnm_t *enm; + gmx_enxnm_t* enm; //! Number of steps used for sum (for energy history) - int64_t nsteps; + int64_t nsteps; //! Number of values added to the sum so far - int64_t nsum; + int64_t nsum; //! Term values: each structure stores current, running average and sum. - t_energy *e; + t_energy* e; //! Total number of steps saved (for energy history) - int64_t nsteps_sim; + int64_t nsteps_sim; //! Total number of values added to sum (used when printing average values at the end of the run) - int64_t nsum_sim; + int64_t nsum_sim; //! Energy values throughout the entire simulation: structure stores current, average and sum, but only sum value is used to compute averages - t_energy *e_sim; + t_energy* e_sim; }; /* \brief Type of expected output: normal or average. */ -enum { - eprNORMAL, eprAVER, eprNR +enum +{ + eprNORMAL, + eprAVER, + eprNR }; /*! \brief Create the structure to store thermodynamic properties*/ -t_ebin *mk_ebin(); +t_ebin* mk_ebin(); /*! \brief Destroy the \c eb structure. * * \param[in,out] eb Pointer to the structure to destroy. */ -void done_ebin(t_ebin *eb); +void done_ebin(t_ebin* eb); /*! \brief Create space for the extra thermodynamic term(s) and register its(their) name(s). * @@ -106,12 +109,12 @@ void done_ebin(t_ebin *eb); * * \returns A serial number (index) for the newly allocated terms. */ -int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *unit); +int get_ebin_space(t_ebin* eb, int nener, const char* const enm[], const char* unit); /*! \brief Add current value of the thermodynamic term(s) to the bin(s). * - * Add nener reals (eg. energies, box-lengths, pressures) to the at position specified by \c entryIndex. - * If bSum is TRUE then the reals are also added to the sum and sum of squares. + * Add nener reals (eg. energies, box-lengths, pressures) to the at position specified by \c + * entryIndex. If bSum is TRUE then the reals are also added to the sum and sum of squares. * * \param[in] eb Structure that stores the thermodynamic values. * \param[in] entryIndex Internal index of the term(s) to add. @@ -119,7 +122,7 @@ int get_ebin_space(t_ebin *eb, int nener, const char *const enm[], const char *u * \param[in] ener Value(s) of thermodynamic term(s) (nener ptc.) * \param[in] bSum If the average value should be accumulated for this term(s). */ -void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool bSum); +void add_ebin(t_ebin* eb, int entryIndex, int nener, const real ener[], gmx_bool bSum); /*! \brief Add values from array to the bins if the matching entry in \c shouldUse is true. @@ -134,8 +137,11 @@ void add_ebin(t_ebin *eb, int entryIndex, int nener, const real ener[], gmx_bool * \param[in] ener Values of thermodinamic terms to add. * \param[in] bSum If the average value should be accumulated for these terms. */ -void add_ebin_indexed(t_ebin *eb, int entryIndex, gmx::ArrayRef shouldUse, - gmx::ArrayRef ener, gmx_bool bSum); +void add_ebin_indexed(t_ebin* eb, + int entryIndex, + gmx::ArrayRef shouldUse, + gmx::ArrayRef ener, + gmx_bool bSum); /*! \brief Increase the counters for the sums. * @@ -145,14 +151,14 @@ void add_ebin_indexed(t_ebin *eb, int entryIndex, gmx::ArrayRef shouldUse, * \param[in] eb Structure that stores the thermodynamic values. * \param[in] bSum If the sums counters should be increased as well. */ -void ebin_increase_count(int increment, t_ebin *eb, gmx_bool bSum); +void ebin_increase_count(int increment, t_ebin* eb, gmx_bool bSum); /*! \brief Reset the average and fluctuation sums. * * \param[in] eb Structure that stores the thermodynamic values. */ -void reset_ebin_sums(t_ebin *eb); +void reset_ebin_sums(t_ebin* eb); /*! \brief Print the contents of some energy bins. @@ -176,7 +182,6 @@ void reset_ebin_sums(t_ebin *eb); * \param[in] prmode Print current (eprNORMAL) or average (eprAVER) values. * \param[in] bPrHead If the header should be printed. */ -void pr_ebin(FILE *fp, t_ebin *eb, int entryIndex, int nener, int nperline, - int prmode, gmx_bool bPrHead); +void pr_ebin(FILE* fp, t_ebin* eb, int entryIndex, int nener, int nperline, int prmode, gmx_bool bPrHead); #endif diff --git a/src/gromacs/mdlib/enerdata_utils.cpp b/src/gromacs/mdlib/enerdata_utils.cpp index b5dd905e6f..ee70f7a130 100644 --- a/src/gromacs/mdlib/enerdata_utils.cpp +++ b/src/gromacs/mdlib/enerdata_utils.cpp @@ -43,8 +43,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -gmx_enerdata_t::gmx_enerdata_t(int numEnergyGroups, - int numFepLambdas) : +gmx_enerdata_t::gmx_enerdata_t(int numEnergyGroups, int numFepLambdas) : grpp(numEnergyGroups), enerpart_lambda(numFepLambdas == 0 ? 0 : numFepLambdas + 1), foreign_grpp(numEnergyGroups) @@ -65,20 +64,20 @@ static real sum_v(int n, gmx::ArrayRef v) return t; } -void sum_epot(gmx_grppairener_t *grpp, real *epot) +void sum_epot(gmx_grppairener_t* grpp, real* epot) { int i; /* Accumulate energies */ - epot[F_COUL_SR] = sum_v(grpp->nener, grpp->ener[egCOULSR]); - epot[F_LJ] = sum_v(grpp->nener, grpp->ener[egLJSR]); - epot[F_LJ14] = sum_v(grpp->nener, grpp->ener[egLJ14]); - epot[F_COUL14] = sum_v(grpp->nener, grpp->ener[egCOUL14]); + epot[F_COUL_SR] = sum_v(grpp->nener, grpp->ener[egCOULSR]); + epot[F_LJ] = sum_v(grpp->nener, grpp->ener[egLJSR]); + epot[F_LJ14] = sum_v(grpp->nener, grpp->ener[egLJ14]); + epot[F_COUL14] = sum_v(grpp->nener, grpp->ener[egCOUL14]); -/* lattice part of LR doesnt belong to any group - * and has been added earlier - */ - epot[F_BHAM] = sum_v(grpp->nener, grpp->ener[egBHAMSR]); + /* lattice part of LR doesnt belong to any group + * and has been added earlier + */ + epot[F_BHAM] = sum_v(grpp->nener, grpp->ener[egBHAMSR]); epot[F_EPOT] = 0; for (i = 0; (i < F_EPOT); i++) @@ -90,12 +89,12 @@ void sum_epot(gmx_grppairener_t *grpp, real *epot) } } -void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_lambda &fepvals) +void sum_dhdl(gmx_enerdata_t* enerd, gmx::ArrayRef lambda, const t_lambda& fepvals) { - int index; + int index; - enerd->dvdl_lin[efptVDW] += enerd->term[F_DVDL_VDW]; /* include dispersion correction */ - enerd->term[F_DVDL] = 0.0; + enerd->dvdl_lin[efptVDW] += enerd->term[F_DVDL_VDW]; /* include dispersion correction */ + enerd->term[F_DVDL] = 0.0; for (int i = 0; i < efptNR; i++) { if (fepvals.separate_dvdl[i]) @@ -103,30 +102,18 @@ void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_l /* could this be done more readably/compactly? */ switch (i) { - case (efptMASS): - index = F_DKDL; - break; - case (efptCOUL): - index = F_DVDL_COUL; - break; - case (efptVDW): - index = F_DVDL_VDW; - break; - case (efptBONDED): - index = F_DVDL_BONDED; - break; - case (efptRESTRAINT): - index = F_DVDL_RESTRAINT; - break; - default: - index = F_DVDL; - break; + case (efptMASS): index = F_DKDL; break; + case (efptCOUL): index = F_DVDL_COUL; break; + case (efptVDW): index = F_DVDL_VDW; break; + case (efptBONDED): index = F_DVDL_BONDED; break; + case (efptRESTRAINT): index = F_DVDL_RESTRAINT; break; + default: index = F_DVDL; break; } enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i]; if (debug) { - fprintf(debug, "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n", - efpt_names[i], i, enerd->term[index], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]); + fprintf(debug, "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n", efpt_names[i], i, + enerd->term[index], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]); } } else @@ -134,8 +121,8 @@ void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_l enerd->term[F_DVDL] += enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i]; if (debug) { - fprintf(debug, "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n", - efpt_names[0], i, enerd->term[F_DVDL], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]); + fprintf(debug, "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n", efpt_names[0], i, + enerd->term[F_DVDL], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]); } } } @@ -160,36 +147,35 @@ void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_l current lambda, because the contributions to the current lambda are automatically zeroed */ - double &enerpart_lambda = enerd->enerpart_lambda[i + 1]; + double& enerpart_lambda = enerd->enerpart_lambda[i + 1]; for (gmx::index j = 0; j < lambda.ssize(); j++) { /* Note that this loop is over all dhdl components, not just the separated ones */ - const double dlam = fepvals.all_lambda[j][i] - lambda[j]; + const double dlam = fepvals.all_lambda[j][i] - lambda[j]; - enerpart_lambda += dlam*enerd->dvdl_lin[j]; + enerpart_lambda += dlam * enerd->dvdl_lin[j]; /* Constraints can not be evaluated at foreign lambdas, so we add * a linear extrapolation. This is an approximation, but usually * quite accurate since constraints change little between lambdas. */ - if ((j == efptBONDED && fepvals.separate_dvdl[efptBONDED]) || - (j == efptFEP && !fepvals.separate_dvdl[efptBONDED])) + if ((j == efptBONDED && fepvals.separate_dvdl[efptBONDED]) + || (j == efptFEP && !fepvals.separate_dvdl[efptBONDED])) { - enerpart_lambda += dlam*enerd->term[F_DVDL_CONSTR]; + enerpart_lambda += dlam * enerd->term[F_DVDL_CONSTR]; } if (j == efptMASS && !fepvals.separate_dvdl[j]) { - enerpart_lambda += dlam*enerd->term[F_DKDL]; + enerpart_lambda += dlam * enerd->term[F_DKDL]; } if (debug) { fprintf(debug, "enerdiff lam %g: (%15s), non-linear %f linear %f*%f\n", fepvals.all_lambda[j][i], efpt_names[j], - enerpart_lambda - enerd->enerpart_lambda[0], - dlam, enerd->dvdl_lin[j]); + enerpart_lambda - enerd->enerpart_lambda[0], dlam, enerd->dvdl_lin[j]); } } } @@ -199,9 +185,9 @@ void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_l } -void reset_foreign_enerdata(gmx_enerdata_t *enerd) +void reset_foreign_enerdata(gmx_enerdata_t* enerd) { - int i, j; + int i, j; /* First reset all foreign energy components. Foreign energies always called on neighbor search steps */ @@ -220,9 +206,9 @@ void reset_foreign_enerdata(gmx_enerdata_t *enerd) } } -void reset_enerdata(gmx_enerdata_t *enerd) +void reset_enerdata(gmx_enerdata_t* enerd) { - int i, j; + int i, j; /* First reset all energy components. */ for (i = 0; (i < egNR); i++) @@ -243,12 +229,12 @@ void reset_enerdata(gmx_enerdata_t *enerd) { enerd->term[i] = 0.0; } - enerd->term[F_DVDL] = 0.0; - enerd->term[F_DVDL_COUL] = 0.0; - enerd->term[F_DVDL_VDW] = 0.0; - enerd->term[F_DVDL_BONDED] = 0.0; - enerd->term[F_DVDL_RESTRAINT] = 0.0; - enerd->term[F_DKDL] = 0.0; + enerd->term[F_DVDL] = 0.0; + enerd->term[F_DVDL_COUL] = 0.0; + enerd->term[F_DVDL_VDW] = 0.0; + enerd->term[F_DVDL_BONDED] = 0.0; + enerd->term[F_DVDL_RESTRAINT] = 0.0; + enerd->term[F_DKDL] = 0.0; std::fill(enerd->enerpart_lambda.begin(), enerd->enerpart_lambda.end(), 0); /* reset foreign energy data - separate function since we also call it elsewhere */ reset_foreign_enerdata(enerd); diff --git a/src/gromacs/mdlib/enerdata_utils.h b/src/gromacs/mdlib/enerdata_utils.h index bfecf22d5d..67e84377f8 100644 --- a/src/gromacs/mdlib/enerdata_utils.h +++ b/src/gromacs/mdlib/enerdata_utils.h @@ -46,16 +46,16 @@ struct gmx_enerdata_t; struct gmx_grppairener_t; struct t_lambda; -void reset_foreign_enerdata(gmx_enerdata_t *enerd); +void reset_foreign_enerdata(gmx_enerdata_t* enerd); /* Resets only the foreign energy data */ -void reset_enerdata(gmx_enerdata_t *enerd); +void reset_enerdata(gmx_enerdata_t* enerd); /* Resets the energy data */ -void sum_epot(gmx_grppairener_t *grpp, real *epot); +void sum_epot(gmx_grppairener_t* grpp, real* epot); /* Locally sum the non-bonded potential energy terms */ -void sum_dhdl(gmx_enerdata_t *enerd, gmx::ArrayRef lambda, const t_lambda &fepvals); +void sum_dhdl(gmx_enerdata_t* enerd, gmx::ArrayRef lambda, const t_lambda& fepvals); /* Sum the free energy contributions */ #endif diff --git a/src/gromacs/mdlib/energyoutput.cpp b/src/gromacs/mdlib/energyoutput.cpp index 5253f3b010..bb71c96b0f 100644 --- a/src/gromacs/mdlib/energyoutput.cpp +++ b/src/gromacs/mdlib/energyoutput.cpp @@ -85,32 +85,25 @@ //! Labels for energy file quantities //! \{ -static const char *conrmsd_nm[] = { "Constr. rmsd", "Constr.2 rmsd" }; +static const char* conrmsd_nm[] = { "Constr. rmsd", "Constr.2 rmsd" }; -static std::array boxs_nm = { "Box-X", "Box-Y", "Box-Z" }; +static std::array boxs_nm = { "Box-X", "Box-Y", "Box-Z" }; -static std::array tricl_boxs_nm = { - "Box-XX", "Box-YY", "Box-ZZ", - "Box-YX", "Box-ZX", "Box-ZY" -}; +static std::array tricl_boxs_nm = { "Box-XX", "Box-YY", "Box-ZZ", + "Box-YX", "Box-ZX", "Box-ZY" }; -static const char *vol_nm[] = { "Volume" }; +static const char* vol_nm[] = { "Volume" }; -static const char *dens_nm[] = {"Density" }; +static const char* dens_nm[] = { "Density" }; -static const char *pv_nm[] = {"pV" }; +static const char* pv_nm[] = { "pV" }; -static const char *enthalpy_nm[] = {"Enthalpy" }; +static const char* enthalpy_nm[] = { "Enthalpy" }; -static std::array boxvel_nm = { - "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ", - "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY" -}; +static std::array boxvel_nm = { "Box-Vel-XX", "Box-Vel-YY", "Box-Vel-ZZ", + "Box-Vel-YX", "Box-Vel-ZX", "Box-Vel-ZY" }; -const char *egrp_nm[egNR+1] = { - "Coul-SR", "LJ-SR", "Buck-SR", - "Coul-14", "LJ-14", nullptr -}; +const char* egrp_nm[egNR + 1] = { "Coul-SR", "LJ-SR", "Buck-SR", "Coul-14", "LJ-14", nullptr }; //! \} namespace gmx @@ -125,57 +118,37 @@ namespace gmx * \todo Remove GMX_CONSTRAINTVIR * \todo Write free-energy output also to energy file (after adding more tests) */ -EnergyOutput::EnergyOutput(ener_file * fp_ene, - const gmx_mtop_t * mtop, - const t_inputrec * ir, - const pull_t * pull_work, - FILE * fp_dhdl, +EnergyOutput::EnergyOutput(ener_file* fp_ene, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const pull_t* pull_work, + FILE* fp_dhdl, bool isRerun, - const MdModulesNotifier &mdModulesNotifier) + const MdModulesNotifier& mdModulesNotifier) { - const char *ener_nm[F_NRE]; - static const char *vir_nm[] = { - "Vir-XX", "Vir-XY", "Vir-XZ", - "Vir-YX", "Vir-YY", "Vir-YZ", - "Vir-ZX", "Vir-ZY", "Vir-ZZ" - }; - static const char *sv_nm[] = { - "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ", - "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ", - "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ" - }; - static const char *fv_nm[] = { - "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ", - "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ", - "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ" - }; - static const char *pres_nm[] = { - "Pres-XX", "Pres-XY", "Pres-XZ", - "Pres-YX", "Pres-YY", "Pres-YZ", - "Pres-ZX", "Pres-ZY", "Pres-ZZ" - }; - static const char *surft_nm[] = { - "#Surf*SurfTen" - }; - static const char *mu_nm[] = { - "Mu-X", "Mu-Y", "Mu-Z" - }; - static const char *vcos_nm[] = { - "2CosZ*Vel-X" - }; - static const char *visc_nm[] = { - "1/Viscosity" - }; - static const char *baro_nm[] = { - "Barostat" - }; - - const SimulationGroups *groups; - char **gnm; - char buf[256]; - const char *bufi; - int i, j, ni, nj, n, k, kk, ncon, nset; - bool bBHAM, b14; + const char* ener_nm[F_NRE]; + static const char* vir_nm[] = { "Vir-XX", "Vir-XY", "Vir-XZ", "Vir-YX", "Vir-YY", + "Vir-YZ", "Vir-ZX", "Vir-ZY", "Vir-ZZ" }; + static const char* sv_nm[] = { "ShakeVir-XX", "ShakeVir-XY", "ShakeVir-XZ", + "ShakeVir-YX", "ShakeVir-YY", "ShakeVir-YZ", + "ShakeVir-ZX", "ShakeVir-ZY", "ShakeVir-ZZ" }; + static const char* fv_nm[] = { "ForceVir-XX", "ForceVir-XY", "ForceVir-XZ", + "ForceVir-YX", "ForceVir-YY", "ForceVir-YZ", + "ForceVir-ZX", "ForceVir-ZY", "ForceVir-ZZ" }; + static const char* pres_nm[] = { "Pres-XX", "Pres-XY", "Pres-XZ", "Pres-YX", "Pres-YY", + "Pres-YZ", "Pres-ZX", "Pres-ZY", "Pres-ZZ" }; + static const char* surft_nm[] = { "#Surf*SurfTen" }; + static const char* mu_nm[] = { "Mu-X", "Mu-Y", "Mu-Z" }; + static const char* vcos_nm[] = { "2CosZ*Vel-X" }; + static const char* visc_nm[] = { "1/Viscosity" }; + static const char* baro_nm[] = { "Barostat" }; + + const SimulationGroups* groups; + char** gnm; + char buf[256]; + const char* bufi; + int i, j, ni, nj, n, k, kk, ncon, nset; + bool bBHAM, b14; if (EI_DYNAMICS(ir->eI)) { @@ -189,14 +162,13 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, groups = &mtop->groups; bBHAM = (mtop->ffparams.numTypes() > 0) && (mtop->ffparams.functype[0] == F_BHAM); - b14 = (gmx_mtop_ftype_count(mtop, F_LJ14) > 0 || - gmx_mtop_ftype_count(mtop, F_LJC14_Q) > 0); - - ncon = gmx_mtop_ftype_count(mtop, F_CONSTR); - nset = gmx_mtop_ftype_count(mtop, F_SETTLE); - bool bConstr = (ncon > 0 || nset > 0) && !isRerun; - bConstrVir_ = false; - nCrmsd_ = 0; + b14 = (gmx_mtop_ftype_count(mtop, F_LJ14) > 0 || gmx_mtop_ftype_count(mtop, F_LJC14_Q) > 0); + + ncon = gmx_mtop_ftype_count(mtop, F_CONSTR); + nset = gmx_mtop_ftype_count(mtop, F_SETTLE); + bool bConstr = (ncon > 0 || nset > 0) && !isRerun; + bConstrVir_ = false; + nCrmsd_ = 0; if (bConstr) { if (ncon > 0 && ir->eConstrAlg == econtLINCS) @@ -220,31 +192,31 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, // are not vsite terms (not VSITE2, VSITE3, VSITE3FD, VSITE3FAD, VSITE3OUT, VSITE4FD, VSITE4FDN, or VSITEN) for (i = 0; i < F_NRE; i++) { - bEner_[i] = (gmx_mtop_ftype_count(mtop, i) > 0) && - ((interaction_function[i].flags & IF_VSITE) == 0); + bEner_[i] = (gmx_mtop_ftype_count(mtop, i) > 0) + && ((interaction_function[i].flags & IF_VSITE) == 0); } if (!isRerun) { - bEner_[F_EKIN] = EI_DYNAMICS(ir->eI); - bEner_[F_ETOT] = EI_DYNAMICS(ir->eI); - bEner_[F_TEMP] = EI_DYNAMICS(ir->eI); + bEner_[F_EKIN] = EI_DYNAMICS(ir->eI); + bEner_[F_ETOT] = EI_DYNAMICS(ir->eI); + bEner_[F_TEMP] = EI_DYNAMICS(ir->eI); - bEner_[F_ECONSERVED] = integratorHasConservedEnergyQuantity(ir); - bEner_[F_PDISPCORR] = (ir->eDispCorr != edispcNO); - bEner_[F_PRES] = true; + bEner_[F_ECONSERVED] = integratorHasConservedEnergyQuantity(ir); + bEner_[F_PDISPCORR] = (ir->eDispCorr != edispcNO); + bEner_[F_PRES] = true; } - bEner_[F_LJ] = !bBHAM; - bEner_[F_BHAM] = bBHAM; - bEner_[F_EQM] = ir->bQMMM; - bEner_[F_RF_EXCL] = (EEL_RF(ir->coulombtype) && ir->cutoff_scheme == ecutsGROUP); - bEner_[F_COUL_RECIP] = EEL_FULL(ir->coulombtype); - bEner_[F_LJ_RECIP] = EVDW_PME(ir->vdwtype); - bEner_[F_LJ14] = b14; - bEner_[F_COUL14] = b14; - bEner_[F_LJC14_Q] = false; - bEner_[F_LJC_PAIRS_NB] = false; + bEner_[F_LJ] = !bBHAM; + bEner_[F_BHAM] = bBHAM; + bEner_[F_EQM] = ir->bQMMM; + bEner_[F_RF_EXCL] = (EEL_RF(ir->coulombtype) && ir->cutoff_scheme == ecutsGROUP); + bEner_[F_COUL_RECIP] = EEL_FULL(ir->coulombtype); + bEner_[F_LJ_RECIP] = EVDW_PME(ir->vdwtype); + bEner_[F_LJ14] = b14; + bEner_[F_COUL14] = b14; + bEner_[F_LJC14_Q] = false; + bEner_[F_LJC_PAIRS_NB] = false; bEner_[F_DVDL_COUL] = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptCOUL]; @@ -254,17 +226,17 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, bEner_[F_DKDL] = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptMASS]; bEner_[F_DVDL] = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptFEP]; - bEner_[F_CONSTR] = false; - bEner_[F_CONSTRNC] = false; - bEner_[F_SETTLE] = false; + bEner_[F_CONSTR] = false; + bEner_[F_CONSTRNC] = false; + bEner_[F_SETTLE] = false; - bEner_[F_COUL_SR] = true; - bEner_[F_EPOT] = true; + bEner_[F_COUL_SR] = true; + bEner_[F_EPOT] = true; - bEner_[F_DISPCORR] = (ir->eDispCorr != edispcNO); - bEner_[F_DISRESVIOL] = (gmx_mtop_ftype_count(mtop, F_DISRES) > 0); - bEner_[F_ORIRESDEV] = (gmx_mtop_ftype_count(mtop, F_ORIRES) > 0); - bEner_[F_COM_PULL] = ((ir->bPull && pull_have_potential(pull_work)) || ir->bRot); + bEner_[F_DISPCORR] = (ir->eDispCorr != edispcNO); + bEner_[F_DISRESVIOL] = (gmx_mtop_ftype_count(mtop, F_DISRES) > 0); + bEner_[F_ORIRESDEV] = (gmx_mtop_ftype_count(mtop, F_ORIRES) > 0); + bEner_[F_COM_PULL] = ((ir->bPull && pull_have_potential(pull_work)) || ir->bRot); MdModulesEnergyOutputToDensityFittingRequestChecker mdModulesAddOutputToDensityFittingFieldRequest; mdModulesNotifier.notifier_.notify(&mdModulesAddOutputToDensityFittingFieldRequest); @@ -285,7 +257,7 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, epc_ = isRerun ? epcNO : ir->epc; bDiagPres_ = !TRICLINIC(ir->ref_p) && !isRerun; - ref_p_ = (ir->ref_p[XX][XX]+ir->ref_p[YY][YY]+ir->ref_p[ZZ][ZZ])/DIM; + ref_p_ = (ir->ref_p[XX][XX] + ir->ref_p[YY][YY] + ir->ref_p[ZZ][ZZ]) / DIM; bTricl_ = TRICLINIC(ir->compress) || TRICLINIC(ir->deform); bDynBox_ = inputrecDynamicBox(ir); etc_ = isRerun ? etcNO : ir->etc; @@ -295,11 +267,11 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, bMu_ = inputrecNeedMutot(ir); bPres_ = !isRerun; - ebin_ = mk_ebin(); + ebin_ = mk_ebin(); /* Pass NULL for unit to let get_ebin_space determine the units * for interaction_function[i].longname */ - ie_ = get_ebin_space(ebin_, f_nre_, ener_nm, nullptr); + ie_ = get_ebin_space(ebin_, f_nre_, ener_nm, nullptr); if (nCrmsd_) { /* This should be called directly after the call for ie_, @@ -309,16 +281,14 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, } if (bDynBox_) { - ib_ = get_ebin_space(ebin_, - bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(), - bTricl_ ? tricl_boxs_nm.data() : boxs_nm.data(), - unit_length); - ivol_ = get_ebin_space(ebin_, 1, vol_nm, unit_volume); + ib_ = get_ebin_space(ebin_, bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(), + bTricl_ ? tricl_boxs_nm.data() : boxs_nm.data(), unit_length); + ivol_ = get_ebin_space(ebin_, 1, vol_nm, unit_volume); idens_ = get_ebin_space(ebin_, 1, dens_nm, unit_density_SI); if (bDiagPres_) { - ipv_ = get_ebin_space(ebin_, 1, pv_nm, unit_energy); - ienthalpy_ = get_ebin_space(ebin_, 1, enthalpy_nm, unit_energy); + ipv_ = get_ebin_space(ebin_, 1, pv_nm, unit_energy); + ienthalpy_ = get_ebin_space(ebin_, 1, enthalpy_nm, unit_energy); } } if (bConstrVir_) @@ -330,23 +300,20 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, { ivir_ = get_ebin_space(ebin_, asize(vir_nm), vir_nm, unit_energy); ipres_ = get_ebin_space(ebin_, asize(pres_nm), pres_nm, unit_pres_bar); - isurft_ = get_ebin_space(ebin_, asize(surft_nm), surft_nm, - unit_surft_bar); + isurft_ = get_ebin_space(ebin_, asize(surft_nm), surft_nm, unit_surft_bar); } if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK) { - ipc_ = get_ebin_space(ebin_, bTricl_ ? boxvel_nm.size() : DIM, - boxvel_nm.data(), unit_vel); + ipc_ = get_ebin_space(ebin_, bTricl_ ? boxvel_nm.size() : DIM, boxvel_nm.data(), unit_vel); } if (bMu_) { - imu_ = get_ebin_space(ebin_, asize(mu_nm), mu_nm, unit_dipole_D); + imu_ = get_ebin_space(ebin_, asize(mu_nm), mu_nm, unit_dipole_D); } if (ir->cos_accel != 0) { ivcos_ = get_ebin_space(ebin_, asize(vcos_nm), vcos_nm, unit_vel); - ivisc_ = get_ebin_space(ebin_, asize(visc_nm), visc_nm, - unit_invvisc_SI); + ivisc_ = get_ebin_space(ebin_, asize(visc_nm), visc_nm, unit_invvisc_SI); } /* Energy monitoring */ @@ -355,7 +322,7 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, bEInd_[i] = false; } bEInd_[egCOULSR] = true; - bEInd_[egLJSR ] = true; + bEInd_[egLJSR] = true; if (bBHAM) { @@ -375,9 +342,9 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, nEc_++; } } - n = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); - nEg_ = n; - nE_ = (n*(n+1))/2; + n = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); + nEg_ = n; + nE_ = (n * (n + 1)) / 2; snew(igrp_, nE_); if (nE_ > 1) @@ -398,13 +365,12 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, { if (bEInd_[k]) { - sprintf(gnm[kk], "%s:%s-%s", egrp_nm[k], - *(groups->groupNames[ni]), *(groups->groupNames[nj])); + sprintf(gnm[kk], "%s:%s-%s", egrp_nm[k], *(groups->groupNames[ni]), + *(groups->groupNames[nj])); kk++; } } - igrp_[n] = get_ebin_space(ebin_, nEc_, - gnm, unit_energy); + igrp_[n] = get_ebin_space(ebin_, nEc_, gnm, unit_energy); n++; } } @@ -424,8 +390,8 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, nNHC_ = ir->opts.nhchainlength; /* shorthand for number of NH chains */ if (bMTTK_) { - nTCP_ = 1; /* assume only one possible coupling system for barostat - for now */ + nTCP_ = 1; /* assume only one possible coupling system for barostat + for now */ } else { @@ -435,15 +401,15 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, { if (bNHC_trotter_) { - mde_n_ = 2*nNHC_*nTC_; + mde_n_ = 2 * nNHC_ * nTC_; } else { - mde_n_ = 2*nTC_; + mde_n_ = 2 * nTC_; } if (epc_ == epcMTTK) { - mdeb_n_ = 2*nNHC_*nTCP_; + mdeb_n_ = 2 * nNHC_ * nTCP_; } } else @@ -454,7 +420,7 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, snew(tmp_r_, mde_n_); // TODO redo the group name memory management to make it more clear - char **grpnms; + char** grpnms; snew(grpnms, std::max(mde_n_, mdeb_n_)); // Just in case mdeb_n_ > mde_n_ for (i = 0; (i < nTC_); i++) @@ -463,8 +429,7 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, sprintf(buf, "T-%s", *(groups->groupNames[ni])); grpnms[i] = gmx_strdup(buf); } - itemp_ = get_ebin_space(ebin_, nTC_, grpnms, - unit_temp_K); + itemp_ = get_ebin_space(ebin_, nTC_, grpnms, unit_temp_K); for (i = 0; i < nTC_; i++) { sfree(grpnms[i]); @@ -484,29 +449,27 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, for (j = 0; (j < nNHC_); j++) { sprintf(buf, "Xi-%d-%s", j, bufi); - grpnms[2*(i*nNHC_+j)] = gmx_strdup(buf); + grpnms[2 * (i * nNHC_ + j)] = gmx_strdup(buf); sprintf(buf, "vXi-%d-%s", j, bufi); - grpnms[2*(i*nNHC_+j)+1] = gmx_strdup(buf); + grpnms[2 * (i * nNHC_ + j) + 1] = gmx_strdup(buf); } } - itc_ = get_ebin_space(ebin_, mde_n_, - grpnms, unit_invtime); + itc_ = get_ebin_space(ebin_, mde_n_, grpnms, unit_invtime); allocated = mde_n_; if (bMTTK_) { for (i = 0; (i < nTCP_); i++) { - bufi = baro_nm[0]; /* All barostat DOF's together for now. */ + bufi = baro_nm[0]; /* All barostat DOF's together for now. */ for (j = 0; (j < nNHC_); j++) { sprintf(buf, "Xi-%d-%s", j, bufi); - grpnms[2*(i*nNHC_+j)] = gmx_strdup(buf); + grpnms[2 * (i * nNHC_ + j)] = gmx_strdup(buf); sprintf(buf, "vXi-%d-%s", j, bufi); - grpnms[2*(i*nNHC_+j)+1] = gmx_strdup(buf); + grpnms[2 * (i * nNHC_ + j) + 1] = gmx_strdup(buf); } } - itcb_ = get_ebin_space(ebin_, mdeb_n_, - grpnms, unit_invtime); + itcb_ = get_ebin_space(ebin_, mdeb_n_, grpnms, unit_invtime); allocated = mdeb_n_; } } @@ -517,18 +480,16 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, ni = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i]; bufi = *(groups->groupNames[ni]); sprintf(buf, "Xi-%s", bufi); - grpnms[2*i] = gmx_strdup(buf); + grpnms[2 * i] = gmx_strdup(buf); sprintf(buf, "vXi-%s", bufi); - grpnms[2*i+1] = gmx_strdup(buf); + grpnms[2 * i + 1] = gmx_strdup(buf); } - itc_ = get_ebin_space(ebin_, mde_n_, - grpnms, unit_invtime); + itc_ = get_ebin_space(ebin_, mde_n_, grpnms, unit_invtime); allocated = mde_n_; } } } - else if (etc_ == etcBERENDSEN || etc_ == etcYES || - etc_ == etcVRESCALE) + else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE) { for (i = 0; (i < nTC_); i++) { @@ -536,8 +497,8 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, sprintf(buf, "Lamb-%s", *(groups->groupNames[ni])); grpnms[i] = gmx_strdup(buf); } - itc_ = get_ebin_space(ebin_, mde_n_, grpnms, ""); - allocated = mde_n_; + itc_ = get_ebin_space(ebin_, mde_n_, grpnms, ""); + allocated = mde_n_; } for (i = 0; i < allocated; i++) @@ -550,19 +511,19 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, snew(tmp_v_, nU_); if (nU_ > 1) { - snew(grpnms, 3*nU_); + snew(grpnms, 3 * nU_); for (i = 0; (i < nU_); i++) { ni = groups->groups[SimulationAtomGroupType::Acceleration][i]; sprintf(buf, "Ux-%s", *(groups->groupNames[ni])); - grpnms[3*i+XX] = gmx_strdup(buf); + grpnms[3 * i + XX] = gmx_strdup(buf); sprintf(buf, "Uy-%s", *(groups->groupNames[ni])); - grpnms[3*i+YY] = gmx_strdup(buf); + grpnms[3 * i + YY] = gmx_strdup(buf); sprintf(buf, "Uz-%s", *(groups->groupNames[ni])); - grpnms[3*i+ZZ] = gmx_strdup(buf); + grpnms[3 * i + ZZ] = gmx_strdup(buf); } - iu_ = get_ebin_space(ebin_, 3*nU_, grpnms, unit_vel); - for (i = 0; i < 3*nU_; i++) + iu_ = get_ebin_space(ebin_, 3 * nU_, grpnms, unit_vel); + for (i = 0; i < 3 * nU_; i++) { sfree(grpnms[i]); } @@ -607,7 +568,6 @@ EnergyOutput::EnergyOutput(ener_file * fp_ene, { numTemperatures_ = 0; } - } EnergyOutput::~EnergyOutput() @@ -634,12 +594,10 @@ EnergyOutput::~EnergyOutput() * \param[in] get_names Whether to print the names rather than the values * \param[in,out] str The pre-allocated string buffer to print to. */ -static void print_lambda_vector(t_lambda *fep, int i, - bool get_native_lambda, bool get_names, - char *str) +static void print_lambda_vector(t_lambda* fep, int i, bool get_native_lambda, bool get_names, char* str) { - int j, k = 0; - int Nsep = 0; + int j, k = 0; + int Nsep = 0; for (j = 0; j < efptNR; j++) { @@ -673,7 +631,7 @@ static void print_lambda_vector(t_lambda *fep, int i, str += sprintf(str, "%s", efpt_singular_names[j]); } /* print comma for the next item */ - if (k < Nsep-1) + if (k < Nsep - 1) { str += sprintf(str, ", "); } @@ -687,22 +645,21 @@ static void print_lambda_vector(t_lambda *fep, int i, } } -FILE *open_dhdl(const char *filename, const t_inputrec *ir, - const gmx_output_env_t *oenv) +FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env_t* oenv) { - FILE *fp; + FILE* fp; const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda", - *lambdastate = "\\lambda state"; + *lambdastate = "\\lambda state"; int i, nsets, nsets_de, nsetsbegin; int n_lambda_terms = 0; - t_lambda *fep = ir->fepvals; /* for simplicity */ - t_expanded *expand = ir->expandedvals; + t_lambda* fep = ir->fepvals; /* for simplicity */ + t_expanded* expand = ir->expandedvals; char lambda_vec_str[STRLEN], lambda_name_str[STRLEN]; - int nsets_dhdl = 0; - int s = 0; - int nsetsextend; - bool write_pV = false; + int nsets_dhdl = 0; + int s = 0; + int nsetsextend; + bool write_pV = false; /* count the number of different lambda terms */ for (i = 0; i < efptNR; i++) @@ -718,15 +675,14 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, { title = gmx::formatString("%s", dhdl); label_x = gmx::formatString("Time (ps)"); - label_y = gmx::formatString("%s (%s %s)", - dhdl, unit_energy, "[\\lambda]\\S-1\\N"); + label_y = gmx::formatString("%s (%s %s)", dhdl, unit_energy, "[\\lambda]\\S-1\\N"); } else { title = gmx::formatString("%s and %s", dhdl, deltag); label_x = gmx::formatString("Time (ps)"); - label_y = gmx::formatString("%s and %s (%s %s)", - dhdl, deltag, unit_energy, "[\\8l\\4]\\S-1\\N"); + label_y = gmx::formatString("%s and %s (%s %s)", dhdl, deltag, unit_energy, + "[\\8l\\4]\\S-1\\N"); } fp = gmx_fio_fopen(filename, "w+"); xvgr_header(fp, title.c_str(), label_x, label_y, exvggtXNY, oenv); @@ -738,19 +694,16 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, } if ((ir->efep != efepSLOWGROWTH) && (ir->efep != efepEXPANDED)) { - if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 )) + if ((fep->init_lambda >= 0) && (n_lambda_terms == 1)) { /* compatibility output */ buf += gmx::formatString("%s = %.4f", lambda, fep->init_lambda); } else { - print_lambda_vector(fep, fep->init_fep_state, true, false, - lambda_vec_str); - print_lambda_vector(fep, fep->init_fep_state, true, true, - lambda_name_str); - buf += gmx::formatString("%s %d: %s = %s", - lambdastate, fep->init_fep_state, + print_lambda_vector(fep, fep->init_fep_state, true, false, lambda_vec_str); + print_lambda_vector(fep, fep->init_fep_state, true, true, lambda_name_str); + buf += gmx::formatString("%s %d: %s = %s", lambdastate, fep->init_fep_state, lambda_name_str, lambda_vec_str); } } @@ -769,12 +722,12 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, if (fep->n_lambda > 0 && (expand->elmcmove > elmcmoveNO)) { - nsets += 1; /*add fep state for expanded ensemble */ + nsets += 1; /*add fep state for expanded ensemble */ } if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO) { - nsets += 1; /* add energy to the dhdl as well */ + nsets += 1; /* add energy to the dhdl as well */ } nsetsextend = nsets; @@ -785,7 +738,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, lambda, and only output when init_lambda is not set in order to maintain compatibility of the dhdl.xvg file) */ - write_pV = true; + write_pV = true; } std::vector setname(nsetsextend); @@ -805,8 +758,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, break; case edHdLPrintEnergyTOTAL: case edHdLPrintEnergyYES: - default: - energy = gmx::formatString("%s (%s)", "Total Energy", unit_energy); + default: energy = gmx::formatString("%s (%s)", "Total Energy", unit_energy); } setname[s++] = energy; } @@ -818,7 +770,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, if (fep->separate_dvdl[i]) { std::string derivative; - if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 )) + if ((fep->init_lambda >= 0) && (n_lambda_terms == 1)) { /* compatibility output */ derivative = gmx::formatString("%s %s %.4f", dhdl, lambda, fep->init_lambda); @@ -830,8 +782,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, { lam = fep->all_lambda[i][fep->init_fep_state]; } - derivative = gmx::formatString("%s %s = %.4f", dhdl, efpt_singular_names[i], - lam); + derivative = gmx::formatString("%s %s = %.4f", dhdl, efpt_singular_names[i], lam); } setname[s++] = derivative; } @@ -846,7 +797,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, if (expand->elmcmove > elmcmoveNO) { - nsetsbegin = 1; /* for including the expanded ensemble */ + nsetsbegin = 1; /* for including the expanded ensemble */ } else { @@ -863,7 +814,7 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, { print_lambda_vector(fep, i, false, false, lambda_vec_str); std::string buf; - if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 )) + if ((fep->init_lambda >= 0) && (n_lambda_terms == 1)) { /* for compatible dhdl.xvg files */ buf = gmx::formatString("%s %s %s", deltag, lambda, lambda_vec_str); @@ -876,9 +827,8 @@ FILE *open_dhdl(const char *filename, const t_inputrec *ir, if (ir->bSimTemp) { /* print the temperature for this state if doing simulated annealing */ - buf += gmx::formatString("T = %g (%s)", - ir->simtempvals->temperatures[s-(nsetsbegin)], - unit_temp_K); + buf += gmx::formatString( + "T = %g (%s)", ir->simtempvals->temperatures[s - (nsetsbegin)], unit_temp_K); } setname[s++] = buf; } @@ -900,18 +850,18 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, bool bSum, double time, real tmass, - const gmx_enerdata_t *enerd, - const t_state *state, - const t_lambda *fep, - const t_expanded *expand, + const gmx_enerdata_t* enerd, + const t_state* state, + const t_lambda* fep, + const t_expanded* expand, const matrix box, const tensor svir, const tensor fvir, const tensor vir, const tensor pres, - const gmx_ekindata_t *ekind, + const gmx_ekindata_t* ekind, const rvec mu_tot, - const gmx::Constraints *constr) + const gmx::Constraints* constr) { int j, k, kk, n, gid; real crmsd[2], tmp6[6]; @@ -951,8 +901,8 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, bs[2] = box[ZZ][ZZ]; nboxs = boxs_nm.size(); } - vol = box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]; - dens = (tmass*AMU)/(vol*NANO*NANO*NANO); + vol = box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]; + dens = (tmass * AMU) / (vol * NANO * NANO * NANO); add_ebin(ebin_, ib_, nboxs, bs, bSum); add_ebin(ebin_, ivol_, 1, &vol, bSum); add_ebin(ebin_, idens_, 1, &dens, bSum); @@ -961,7 +911,7 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { /* This is pV (in kJ/mol). The pressure is the reference pressure, not the instantaneous pressure */ - pv = vol*ref_p_/PRESFAC; + pv = vol * ref_p_ / PRESFAC; add_ebin(ebin_, ipv_, 1, &pv, bSum); enthalpy = pv + enerd->term[F_ETOT]; @@ -977,7 +927,7 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { add_ebin(ebin_, ivir_, 9, vir[0], bSum); add_ebin(ebin_, ipres_, 9, pres[0], bSum); - tmp = (pres[ZZ][ZZ]-(pres[XX][XX]+pres[YY][YY])*0.5)*box[ZZ][ZZ]; + tmp = (pres[ZZ][ZZ] - (pres[XX][XX] + pres[YY][YY]) * 0.5) * box[ZZ][ZZ]; add_ebin(ebin_, isurft_, 1, &tmp, bSum); } if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK) @@ -996,12 +946,13 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, } if (ekind && ekind->cosacc.cos_accel != 0) { - vol = box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]; - dens = (tmass*AMU)/(vol*NANO*NANO*NANO); + vol = box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]; + dens = (tmass * AMU) / (vol * NANO * NANO * NANO); add_ebin(ebin_, ivcos_, 1, &(ekind->cosacc.vcos), bSum); /* 1/viscosity, unit 1/(kg m^-1 s^-1) */ - tmp = 1/(ekind->cosacc.cos_accel/(ekind->cosacc.vcos*PICO) - *dens*gmx::square(box[ZZ][ZZ]*NANO/(2*M_PI))); + tmp = 1 + / (ekind->cosacc.cos_accel / (ekind->cosacc.vcos * PICO) * dens + * gmx::square(box[ZZ][ZZ] * NANO / (2 * M_PI))); add_ebin(ebin_, ivisc_, 1, &tmp, bSum); } if (nE_ > 1) @@ -1044,9 +995,9 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { for (j = 0; j < nNHC_; j++) { - k = i*nNHC_+j; - tmp_r_[2*k] = state->nosehoover_xi[k]; - tmp_r_[2*k+1] = state->nosehoover_vxi[k]; + k = i * nNHC_ + j; + tmp_r_[2 * k] = state->nosehoover_xi[k]; + tmp_r_[2 * k + 1] = state->nosehoover_vxi[k]; } } add_ebin(ebin_, itc_, mde_n_, tmp_r_, bSum); @@ -1057,9 +1008,9 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { for (j = 0; j < nNHC_; j++) { - k = i*nNHC_+j; - tmp_r_[2*k] = state->nhpres_xi[k]; - tmp_r_[2*k+1] = state->nhpres_vxi[k]; + k = i * nNHC_ + j; + tmp_r_[2 * k] = state->nhpres_xi[k]; + tmp_r_[2 * k + 1] = state->nhpres_vxi[k]; } } add_ebin(ebin_, itcb_, mdeb_n_, tmp_r_, bSum); @@ -1069,15 +1020,14 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { for (int i = 0; (i < nTC_); i++) { - tmp_r_[2*i] = state->nosehoover_xi[i]; - tmp_r_[2*i+1] = state->nosehoover_vxi[i]; + tmp_r_[2 * i] = state->nosehoover_xi[i]; + tmp_r_[2 * i + 1] = state->nosehoover_vxi[i]; } add_ebin(ebin_, itc_, mde_n_, tmp_r_, bSum); } } } - else if (etc_ == etcBERENDSEN || etc_ == etcYES || - etc_ == etcVRESCALE) + else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE) { for (int i = 0; (i < nTC_); i++) { @@ -1093,7 +1043,7 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { copy_rvec(ekind->grpstat[i].u, tmp_v_[i]); } - add_ebin(ebin_, iu_, 3*nU_, tmp_v_[0], bSum); + add_ebin(ebin_, iu_, 3 * nU_, tmp_v_[0], bSum); } ebin_increase_count(1, ebin_, bSum); @@ -1104,16 +1054,17 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, for (gmx::index i = 0; i < static_cast(enerd->enerpart_lambda.size()) - 1; i++) { /* zero for simulated tempering */ - dE_[i] = enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0]; + dE_[i] = enerd->enerpart_lambda[i + 1] - enerd->enerpart_lambda[0]; if (numTemperatures_ > 0) { - GMX_RELEASE_ASSERT(numTemperatures_ > state->fep_state, "Number of lambdas in state is bigger then in input record"); - GMX_RELEASE_ASSERT(numTemperatures_ >= static_cast(enerd->enerpart_lambda.size()) - 1, "Number of lambdas in energy data is bigger then in input record"); + GMX_RELEASE_ASSERT(numTemperatures_ > state->fep_state, + "Number of lambdas in state is bigger then in input record"); + GMX_RELEASE_ASSERT( + numTemperatures_ >= static_cast(enerd->enerpart_lambda.size()) - 1, + "Number of lambdas in energy data is bigger then in input record"); /* MRS: is this right, given the way we have defined the exchange probabilities? */ /* is this even useful to have at all? */ - dE_[i] += (temperatures_[i]/ - temperatures_[state->fep_state]-1.0)* - enerd->term[F_EKIN]; + dE_[i] += (temperatures_[i] / temperatures_[state->fep_state] - 1.0) * enerd->term[F_EKIN]; } } @@ -1133,13 +1084,10 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { switch (fep->edHdLPrintEnergy) { - case edHdLPrintEnergyPOTENTIAL: - store_energy = enerd->term[F_EPOT]; - break; + case edHdLPrintEnergyPOTENTIAL: store_energy = enerd->term[F_EPOT]; break; case edHdLPrintEnergyTOTAL: case edHdLPrintEnergyYES: - default: - store_energy = enerd->term[F_ETOT]; + default: store_energy = enerd->term[F_ETOT]; } fprintf(fp_dhdl_, " %#.8g", store_energy); } @@ -1151,7 +1099,7 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, if (fep->separate_dvdl[i]) { /* assumes F_DVDL is first */ - fprintf(fp_dhdl_, " %#.8g", enerd->term[F_DVDL+i]); + fprintf(fp_dhdl_, " %#.8g", enerd->term[F_DVDL + i]); } } } @@ -1159,16 +1107,13 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, { fprintf(fp_dhdl_, " %#.8g", dE_[i]); } - if (bDynBox_ && - bDiagPres_ && - (epc_ != epcNO) && - !enerd->enerpart_lambda.empty() && - (fep->init_lambda < 0)) + if (bDynBox_ && bDiagPres_ && (epc_ != epcNO) && !enerd->enerpart_lambda.empty() + && (fep->init_lambda < 0)) { - fprintf(fp_dhdl_, " %#.8g", pv); /* PV term only needed when - there are alternate state - lambda and we're not in - compatibility mode */ + fprintf(fp_dhdl_, " %#.8g", pv); /* PV term only needed when + there are alternate state + lambda and we're not in + compatibility mode */ } fprintf(fp_dhdl_, "\n"); /* and the binary free energy output */ @@ -1181,22 +1126,16 @@ void EnergyOutput::addDataAtEnergyStep(bool bDoDHDL, if (fep->separate_dvdl[i]) { /* assumes F_DVDL is first */ - store_dhdl[idhdl] = enerd->term[F_DVDL+i]; - idhdl += 1; + store_dhdl[idhdl] = enerd->term[F_DVDL + i]; + idhdl += 1; } } store_energy = enerd->term[F_ETOT]; /* store_dh is dE */ - mde_delta_h_coll_add_dh(dhc_, - static_cast(state->fep_state), - store_energy, - pv, - store_dhdl, - dE_ + fep->lambda_start_n, - time); + mde_delta_h_coll_add_dh(dhc_, static_cast(state->fep_state), store_energy, pv, + store_dhdl, dE_ + fep->lambda_start_n, time); } } - ; } void EnergyOutput::recordNonEnergyStep() @@ -1204,36 +1143,41 @@ void EnergyOutput::recordNonEnergyStep() ebin_increase_count(1, ebin_, false); } -void EnergyOutput::printHeader(FILE *log, int64_t steps, double time) +void EnergyOutput::printHeader(FILE* log, int64_t steps, double time) { char buf[22]; - fprintf(log, " %12s %12s\n" + fprintf(log, + " %12s %12s\n" " %12s %12.5f\n\n", "Step", "Time", gmx_step_str(steps, buf), time); } -void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, bool bOR, - FILE *log, - int64_t step, double time, - t_fcdata *fcd, - gmx::Awh *awh) +void EnergyOutput::printStepToEnergyFile(ener_file* fp_ene, + bool bEne, + bool bDR, + bool bOR, + FILE* log, + int64_t step, + double time, + t_fcdata* fcd, + gmx::Awh* awh) { - t_enxframe fr; + t_enxframe fr; init_enxframe(&fr); - fr.t = time; - fr.step = step; - fr.nsteps = ebin_->nsteps; - fr.dt = delta_t_; - fr.nsum = ebin_->nsum; - fr.nre = (bEne) ? ebin_->nener : 0; - fr.ener = ebin_->e; - int ndisre = bDR ? fcd->disres.npair : 0; + fr.t = time; + fr.step = step; + fr.nsteps = ebin_->nsteps; + fr.dt = delta_t_; + fr.nsum = ebin_->nsum; + fr.nre = (bEne) ? ebin_->nener : 0; + fr.ener = ebin_->e; + int ndisre = bDR ? fcd->disres.npair : 0; /* these are for the old-style blocks (1 subblock, only reals), because there can be only one per ID for these */ - int nr[enxNR]; - int id[enxNR]; - real *block[enxNR]; + int nr[enxNR]; + int id[enxNR]; + real* block[enxNR]; /* Optional additional old-style (real-only) blocks. */ for (int i = 0; i < enxNR; i++) { @@ -1246,11 +1190,10 @@ void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, nr[enxOR] = fcd->orires.nr; block[enxOR] = fcd->orires.otav; id[enxOR] = enxOR; - nr[enxORI] = (fcd->orires.oinsl != fcd->orires.otav) ? - fcd->orires.nr : 0; + nr[enxORI] = (fcd->orires.oinsl != fcd->orires.otav) ? fcd->orires.nr : 0; block[enxORI] = fcd->orires.oinsl; id[enxORI] = enxORI; - nr[enxORT] = fcd->orires.nex*12; + nr[enxORT] = fcd->orires.nex * 12; block[enxORT] = fcd->orires.eig; id[enxORT] = enxORT; } @@ -1277,8 +1220,8 @@ void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, fr.block[b].sub[0].type = xdr_datatype_float; fr.block[b].sub[0].fval = block[b]; #else - fr.block[b].sub[0].type = xdr_datatype_double; - fr.block[b].sub[0].dval = block[b]; + fr.block[b].sub[0].type = xdr_datatype_double; + fr.block[b].sub[0].dval = block[b]; #endif } @@ -1320,7 +1263,7 @@ void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, } /* AWH bias blocks. */ - if (awh != nullptr) // TODO: add boolean flag. + if (awh != nullptr) // TODO: add boolean flag. { awh->writeToEnergyFrame(step, &fr); } @@ -1342,12 +1285,12 @@ void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, } fprintf(log, " Energies (%s)\n", unit_energy); - pr_ebin(log, ebin_, ie_, f_nre_+nCrmsd_, 5, eprNORMAL, true); + pr_ebin(log, ebin_, ie_, f_nre_ + nCrmsd_, 5, eprNORMAL, true); fprintf(log, "\n"); } } -void EnergyOutput::printAnnealingTemperatures(FILE *log, SimulationGroups *groups, t_grpopts *opts) +void EnergyOutput::printAnnealingTemperatures(FILE* log, SimulationGroups* groups, t_grpopts* opts) { if (log) { @@ -1367,7 +1310,7 @@ void EnergyOutput::printAnnealingTemperatures(FILE *log, SimulationGroups *group } } -void EnergyOutput::printAverages(FILE *log, const SimulationGroups *groups) +void EnergyOutput::printAverages(FILE* log, const SimulationGroups* groups) { if (ebin_->nsum_sim <= 0) { @@ -1387,18 +1330,16 @@ void EnergyOutput::printAverages(FILE *log, const SimulationGroups *groups) fprintf(log, "\t<== ############### ======>\n\n"); fprintf(log, "\tStatistics over %s steps using %s frames\n", - gmx_step_str(ebin_->nsteps_sim, buf1), - gmx_step_str(ebin_->nsum_sim, buf2)); + gmx_step_str(ebin_->nsteps_sim, buf1), gmx_step_str(ebin_->nsum_sim, buf2)); fprintf(log, "\n"); fprintf(log, " Energies (%s)\n", unit_energy); - pr_ebin(log, ebin_, ie_, f_nre_+nCrmsd_, 5, eprAVER, true); + pr_ebin(log, ebin_, ie_, f_nre_ + nCrmsd_, 5, eprAVER, true); fprintf(log, "\n"); if (bDynBox_) { - pr_ebin(log, ebin_, ib_, bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(), 5, - eprAVER, true); + pr_ebin(log, ebin_, ib_, bTricl_ ? tricl_boxs_nm.size() : boxs_nm.size(), 5, eprAVER, true); fprintf(log, "\n"); } if (bConstrVir_) @@ -1445,14 +1386,12 @@ void EnergyOutput::printAverages(FILE *log, const SimulationGroups *groups) int ni = groups->groups[SimulationAtomGroupType::EnergyOutput][i]; for (int j = i; (j < nEg_); j++) { - int nj = groups->groups[SimulationAtomGroupType::EnergyOutput][j]; - int padding = 14 - (strlen(*(groups->groupNames[ni])) + - strlen(*(groups->groupNames[nj]))); - fprintf(log, "%*s%s-%s", padding, "", - *(groups->groupNames[ni]), + int nj = groups->groups[SimulationAtomGroupType::EnergyOutput][j]; + int padding = + 14 - (strlen(*(groups->groupNames[ni])) + strlen(*(groups->groupNames[nj]))); + fprintf(log, "%*s%s-%s", padding, "", *(groups->groupNames[ni]), *(groups->groupNames[nj])); - pr_ebin(log, ebin_, igrp_[n], nEc_, nEc_, eprAVER, - false); + pr_ebin(log, ebin_, igrp_[n], nEc_, nEc_, eprAVER, false); n++; } } @@ -1465,22 +1404,21 @@ void EnergyOutput::printAverages(FILE *log, const SimulationGroups *groups) } if (nU_ > 1) { - fprintf(log, "%15s %12s %12s %12s\n", - "Group", "Ux", "Uy", "Uz"); + fprintf(log, "%15s %12s %12s %12s\n", "Group", "Ux", "Uy", "Uz"); for (int i = 0; (i < nU_); i++) { int ni = groups->groups[SimulationAtomGroupType::Acceleration][i]; fprintf(log, "%15s", *groups->groupNames[ni]); - pr_ebin(log, ebin_, iu_+3*i, 3, 3, eprAVER, false); + pr_ebin(log, ebin_, iu_ + 3 * i, 3, 3, eprAVER, false); } fprintf(log, "\n"); } } } -void EnergyOutput::fillEnergyHistory(energyhistory_t *enerhist) const +void EnergyOutput::fillEnergyHistory(energyhistory_t* enerhist) const { - const t_ebin * const ebin = ebin_; + const t_ebin* const ebin = ebin_; enerhist->nsteps = ebin->nsteps; enerhist->nsum = ebin->nsum; @@ -1516,14 +1454,16 @@ void EnergyOutput::fillEnergyHistory(energyhistory_t *enerhist) const } } -void EnergyOutput::restoreFromEnergyHistory(const energyhistory_t &enerhist) +void EnergyOutput::restoreFromEnergyHistory(const energyhistory_t& enerhist) { unsigned int nener = static_cast(ebin_->nener); - if ((enerhist.nsum > 0 && nener != enerhist.ener_sum.size()) || - (enerhist.nsum_sim > 0 && nener != enerhist.ener_sum_sim.size())) + if ((enerhist.nsum > 0 && nener != enerhist.ener_sum.size()) + || (enerhist.nsum_sim > 0 && nener != enerhist.ener_sum_sim.size())) { - gmx_fatal(FARGS, "Mismatch between number of energies in run input (%u) and checkpoint file (%zu or %zu).", + gmx_fatal(FARGS, + "Mismatch between number of energies in run input (%u) and checkpoint file (%zu " + "or %zu).", nener, enerhist.ener_sum.size(), enerhist.ener_sum_sim.size()); } @@ -1534,12 +1474,9 @@ void EnergyOutput::restoreFromEnergyHistory(const energyhistory_t &enerhist) for (int i = 0; i < ebin_->nener; i++) { - ebin_->e[i].eav = - (enerhist.nsum > 0 ? enerhist.ener_ave[i] : 0); - ebin_->e[i].esum = - (enerhist.nsum > 0 ? enerhist.ener_sum[i] : 0); - ebin_->e_sim[i].esum = - (enerhist.nsum_sim > 0 ? enerhist.ener_sum_sim[i] : 0); + ebin_->e[i].eav = (enerhist.nsum > 0 ? enerhist.ener_ave[i] : 0); + ebin_->e[i].esum = (enerhist.nsum > 0 ? enerhist.ener_sum[i] : 0); + ebin_->e_sim[i].esum = (enerhist.nsum_sim > 0 ? enerhist.ener_sum_sim[i] : 0); } if (dhc_) { diff --git a/src/gromacs/mdlib/energyoutput.h b/src/gromacs/mdlib/energyoutput.h index 1964feddc9..f8cc196d5e 100644 --- a/src/gromacs/mdlib/energyoutput.h +++ b/src/gromacs/mdlib/energyoutput.h @@ -72,16 +72,16 @@ namespace gmx class Awh; class Constraints; struct MdModulesNotifier; -} +} // namespace gmx //! \brief Printed names for intergroup energies -extern const char *egrp_nm[egNR+1]; +extern const char* egrp_nm[egNR + 1]; /* \brief delta_h block type enum: the kinds of energies written out. */ enum { //! Delta H BAR energy difference - dhbtDH = 0, + dhbtDH = 0, //! dH/dlambda derivative dhbtDHDL = 1, //! System energy @@ -108,290 +108,292 @@ namespace gmx */ class EnergyOutput { - public: - - /*! \brief Initiate MD energy bin - * - * \param[in] fp_ene Energy output file. - * \param[in] mtop Topology. - * \param[in] ir Input parameters. - * \param[in] pull_work Pulling simulations data - * \param[in] fp_dhdl FEP file. - * \param[in] isRerun Is this is a rerun instead of the simulations. - * \param[in] mdModulesNotifier Notifications to MD modules. - */ - EnergyOutput(ener_file * fp_ene, - const gmx_mtop_t * mtop, - const t_inputrec * ir, - const pull_t * pull_work, - FILE * fp_dhdl, - bool isRerun, - const MdModulesNotifier &mdModulesNotifier); - - ~EnergyOutput(); - - /*! \brief Update the averaging structures. - * - * Called every step on which the thermodynamic values are evaluated. - * - * \param[in] bDoDHDL Whether the FEP is enabled. - * \param[in] bSum If this stepshould be recorded to compute sums and averaes. - * \param[in] time Current simulation time. - * \param[in] tmass Total mass - * \param[in] enerd Energy data object. - * \param[in] state System state. - * \param[in] fep FEP data. - * \param[in] expand Expanded ensemble (for FEP). - * \param[in] lastbox PBC data. - * \param[in] svir Constraint virial. - * \param[in] fvir Force virial. - * \param[in] vir Total virial. - * \param[in] pres Pressure. - * \param[in] ekind Kinetic energy data. - * \param[in] mu_tot Total dipole. - * \param[in] constr Constraints object to get RMSD from (for LINCS only). - */ - void addDataAtEnergyStep(bool bDoDHDL, - bool bSum, - double time, - real tmass, - const gmx_enerdata_t *enerd, - const t_state *state, - const t_lambda *fep, - const t_expanded *expand, - const matrix lastbox, - const tensor svir, - const tensor fvir, - const tensor vir, - const tensor pres, - const gmx_ekindata_t *ekind, - const rvec mu_tot, - const gmx::Constraints *constr); - - /*! \brief Update the data averaging structure counts. - * - * Updates the number of steps, the values have not being computed. - */ - void recordNonEnergyStep(); - - /*! \brief Writes current quantites to log and energy files. - * - * Prints current values of energies, pressure, temperature, restraint - * data, etc. to energy output file and to the log file (if not nullptr). - * - * This function only does something useful when bEne || bDR || bOR || log. - * - * \todo Perhaps this responsibility should involve some other - * object visiting all the contributing objects. - * - * \param[in] fp_ene Energy file for the output. - * \param[in] bEne If it is a step for energy output or last step. - * \param[in] bDR If it is a step of writing distance restraints. - * \param[in] bOR If it is a step of writing orientation restraints. - * \param[in] log Pointer to the log file. - * \param[in] step Current step. - * \param[in] time Current simulation time. - * \param[in] fcd Bonded force computation data, - * including orientation and distance restraints. - * \param[in] awh AWH data. - */ - void printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, bool bOR, - FILE *log, - int64_t step, double time, - t_fcdata *fcd, - gmx::Awh *awh); - - /*! \brief Print reference temperatures for annealing groups. - * - * Nothing is done if log is nullptr. - * - * \param[in] log Log file to print to. - * \param[in] groups Information on atom groups. - * \param[in] opts Atom temperature coupling groups options - * (annealing is done by groups). - */ - void printAnnealingTemperatures(FILE *log, SimulationGroups *groups, t_grpopts *opts); - - /*! \brief Prints average values to log file. - * - * This is called at the end of the simulation run to print accumulated average values. - * Nothing it done if log is nullptr. - * - * \param[in] log Where to print. - * \param[in] groups Atom groups. - */ - void printAverages(FILE *log, const SimulationGroups *groups); - - /*! \brief Get the number of thermodynamic terms recorded. - * - * \todo Refactor this to return the expected output size, - * rather than exposing the implementation details about - * thermodynamic terms. - * - * \returns Number of thermodynamic terms. - */ - int numEnergyTerms() const; - - /*! \brief Fill the energyhistory_t data. - * - * Between .edr writes, the averages are history dependent, - * and that history needs to be retained in checkpoints. - * These functions set/read the energyhistory_t class - * that is written to checkpoints. - * - * \param[out] enerhist Energy history data structure. - */ - void fillEnergyHistory(energyhistory_t * enerhist) const; - - /*! \brief Restore from energyhistory_t data. - * - * \param[in] enerhist Energy history data structure. - */ - void restoreFromEnergyHistory(const energyhistory_t &enerhist); - - //! Print an output header to the log file. - void printHeader(FILE *log, int64_t steps, double time); - - private: - //! Timestep - double delta_t_ = 0; - - //! Structure to store energy components and their running averages - t_ebin *ebin_ = nullptr; - - //! Is the periodic box triclinic - bool bTricl_ = false; - //! NHC trotter is used - bool bNHC_trotter_ = false; - //! If Nose-Hoover chains should be printed - bool bPrintNHChains_ = false; - //! If MTTK integrator was used - bool bMTTK_ = false; - - //! Temperature control scheme - int etc_ = 0; - - //! Which of the main energy terms should be printed - bool bEner_[F_NRE] = {false}; - //! Index for main energy terms - int ie_ = 0; - //! Number of energy terms from F_NRE list to be saved (i.e. number of 'true' in bEner) - int f_nre_ = 0; - - //! Index for constraints RMSD - int iconrmsd_ = 0; - /* !\brief How many constraints RMSD terms there are. - * Usually 1 if LINCS is used and 0 otherwise) - * nCrmsd > 0 indicates when constraints RMSD is saves, hence no boolean - */ - int nCrmsd_ = 0; - - //! Is the periodic box dynamic - bool bDynBox_ = false; - //! Index for box dimensions - int ib_ = 0; - //! Index for box volume - int ivol_ = 0; - //! Index for density - int idens_ = 0; - //! Triclinic box and not a rerun - bool bDiagPres_ = false; - //! Reference pressure, averaged over dimensions - real ref_p_ = 0.0; - //! Index for thermodynamic work (pV) - int ipv_ = 0; - //! Index for entalpy (pV + total energy) - int ienthalpy_ = 0; - - /*! \brief If the constraints virial should be printed. - * Can only be true if "GMX_CONSTRAINTVIR" environmental variable is set */ - bool bConstrVir_ = false; - //! Index for constrains virial - int isvir_ = 0; - //! Index for force virial - int ifvir_ = 0; - - //! If we have pressure computed - bool bPres_ = false; - //! Index for total virial - int ivir_ = 0; - //! Index for pressure - int ipres_ = 0; - /*! \brief Index for surface tension - * [(pres[ZZ][ZZ]-(pres[XX][XX]+pres[YY][YY])*0.5)*box[ZZ][ZZ]]*/ - int isurft_ = 0; - - //! Pressure control scheme - int epc_ = 0; - //! Index for velocity of the box borders - int ipc_ = 0; - - //! If dipole was calculated - bool bMu_ = false; - //! Index for the dipole - int imu_ = 0; - - //! Index for coseine acceleration used for viscocity calculation - int ivcos_ = 0; - //! Index for viscocity - int ivisc_ = 0; - - //! Which energy terms from egNR list should be printed in group-to-group block - bool bEInd_[egNR] = {false}; - //! Number of energy terms to be printed (these, for which bEInd[] == true) - int nEc_ = 0; - //! Number of energy output groups - int nEg_ = 0; - //! Number of intergroup energy sets to be printed for each energy term (nE = (nEg*(nEg+1))/2) - int nE_ = 0; - //! Indexes for integroup energy sets (each set with nEc energies) - int *igrp_ = nullptr; - - //! Number of temperature coupling groups - int nTC_ = 0; - //! Index for temperature - int itemp_ = 0; - - //! Number of Nose-Hoover chains - int nNHC_ = 0; - //! Number of temperature coupling coefficients in case of NH Chains - int mde_n_ = 0; - //! Index for temperature coupling coefficient in case of NH chains - int itc_ = 0; - - //! Number of temperature coupling terms if the temperature control is dealt by barostat (MTTK case) - int nTCP_ = 0; - //! Scalling factors for temperaturs control in MTTK - int mdeb_n_ = 0; - //! Index for scalling factor of MTTK - int itcb_ = 0; - - //! Number of acceleration groups - int nU_ = 0; - //! Index for group velocities - int iu_ = 0; - - //! Array to accumulate values during update - real *tmp_r_ = nullptr; - //! Array to accumulate values during update - rvec *tmp_v_ = nullptr; - - //! The dhdl.xvg output file - FILE *fp_dhdl_ = nullptr; - //! Energy components for dhdl.xvg output - double *dE_ = nullptr; - //! The delta U components (raw data + histogram) - t_mde_delta_h_coll *dhc_ = nullptr; - //! Temperatures for simulated tempering groups - real *temperatures_ = nullptr; - //! Number of temperatures actually saved - int numTemperatures_ = 0; +public: + /*! \brief Initiate MD energy bin + * + * \param[in] fp_ene Energy output file. + * \param[in] mtop Topology. + * \param[in] ir Input parameters. + * \param[in] pull_work Pulling simulations data + * \param[in] fp_dhdl FEP file. + * \param[in] isRerun Is this is a rerun instead of the simulations. + * \param[in] mdModulesNotifier Notifications to MD modules. + */ + EnergyOutput(ener_file* fp_ene, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + const pull_t* pull_work, + FILE* fp_dhdl, + bool isRerun, + const MdModulesNotifier& mdModulesNotifier); + + ~EnergyOutput(); + + /*! \brief Update the averaging structures. + * + * Called every step on which the thermodynamic values are evaluated. + * + * \param[in] bDoDHDL Whether the FEP is enabled. + * \param[in] bSum If this stepshould be recorded to compute sums and averaes. + * \param[in] time Current simulation time. + * \param[in] tmass Total mass + * \param[in] enerd Energy data object. + * \param[in] state System state. + * \param[in] fep FEP data. + * \param[in] expand Expanded ensemble (for FEP). + * \param[in] lastbox PBC data. + * \param[in] svir Constraint virial. + * \param[in] fvir Force virial. + * \param[in] vir Total virial. + * \param[in] pres Pressure. + * \param[in] ekind Kinetic energy data. + * \param[in] mu_tot Total dipole. + * \param[in] constr Constraints object to get RMSD from (for LINCS only). + */ + void addDataAtEnergyStep(bool bDoDHDL, + bool bSum, + double time, + real tmass, + const gmx_enerdata_t* enerd, + const t_state* state, + const t_lambda* fep, + const t_expanded* expand, + const matrix lastbox, + const tensor svir, + const tensor fvir, + const tensor vir, + const tensor pres, + const gmx_ekindata_t* ekind, + const rvec mu_tot, + const gmx::Constraints* constr); + + /*! \brief Update the data averaging structure counts. + * + * Updates the number of steps, the values have not being computed. + */ + void recordNonEnergyStep(); + + /*! \brief Writes current quantites to log and energy files. + * + * Prints current values of energies, pressure, temperature, restraint + * data, etc. to energy output file and to the log file (if not nullptr). + * + * This function only does something useful when bEne || bDR || bOR || log. + * + * \todo Perhaps this responsibility should involve some other + * object visiting all the contributing objects. + * + * \param[in] fp_ene Energy file for the output. + * \param[in] bEne If it is a step for energy output or last step. + * \param[in] bDR If it is a step of writing distance restraints. + * \param[in] bOR If it is a step of writing orientation restraints. + * \param[in] log Pointer to the log file. + * \param[in] step Current step. + * \param[in] time Current simulation time. + * \param[in] fcd Bonded force computation data, + * including orientation and distance restraints. + * \param[in] awh AWH data. + */ + void printStepToEnergyFile(ener_file* fp_ene, + bool bEne, + bool bDR, + bool bOR, + FILE* log, + int64_t step, + double time, + t_fcdata* fcd, + gmx::Awh* awh); + + /*! \brief Print reference temperatures for annealing groups. + * + * Nothing is done if log is nullptr. + * + * \param[in] log Log file to print to. + * \param[in] groups Information on atom groups. + * \param[in] opts Atom temperature coupling groups options + * (annealing is done by groups). + */ + void printAnnealingTemperatures(FILE* log, SimulationGroups* groups, t_grpopts* opts); + + /*! \brief Prints average values to log file. + * + * This is called at the end of the simulation run to print accumulated average values. + * Nothing it done if log is nullptr. + * + * \param[in] log Where to print. + * \param[in] groups Atom groups. + */ + void printAverages(FILE* log, const SimulationGroups* groups); + + /*! \brief Get the number of thermodynamic terms recorded. + * + * \todo Refactor this to return the expected output size, + * rather than exposing the implementation details about + * thermodynamic terms. + * + * \returns Number of thermodynamic terms. + */ + int numEnergyTerms() const; + + /*! \brief Fill the energyhistory_t data. + * + * Between .edr writes, the averages are history dependent, + * and that history needs to be retained in checkpoints. + * These functions set/read the energyhistory_t class + * that is written to checkpoints. + * + * \param[out] enerhist Energy history data structure. + */ + void fillEnergyHistory(energyhistory_t* enerhist) const; + + /*! \brief Restore from energyhistory_t data. + * + * \param[in] enerhist Energy history data structure. + */ + void restoreFromEnergyHistory(const energyhistory_t& enerhist); + + //! Print an output header to the log file. + void printHeader(FILE* log, int64_t steps, double time); + +private: + //! Timestep + double delta_t_ = 0; + + //! Structure to store energy components and their running averages + t_ebin* ebin_ = nullptr; + + //! Is the periodic box triclinic + bool bTricl_ = false; + //! NHC trotter is used + bool bNHC_trotter_ = false; + //! If Nose-Hoover chains should be printed + bool bPrintNHChains_ = false; + //! If MTTK integrator was used + bool bMTTK_ = false; + + //! Temperature control scheme + int etc_ = 0; + + //! Which of the main energy terms should be printed + bool bEner_[F_NRE] = { false }; + //! Index for main energy terms + int ie_ = 0; + //! Number of energy terms from F_NRE list to be saved (i.e. number of 'true' in bEner) + int f_nre_ = 0; + + //! Index for constraints RMSD + int iconrmsd_ = 0; + /* !\brief How many constraints RMSD terms there are. + * Usually 1 if LINCS is used and 0 otherwise) + * nCrmsd > 0 indicates when constraints RMSD is saves, hence no boolean + */ + int nCrmsd_ = 0; + + //! Is the periodic box dynamic + bool bDynBox_ = false; + //! Index for box dimensions + int ib_ = 0; + //! Index for box volume + int ivol_ = 0; + //! Index for density + int idens_ = 0; + //! Triclinic box and not a rerun + bool bDiagPres_ = false; + //! Reference pressure, averaged over dimensions + real ref_p_ = 0.0; + //! Index for thermodynamic work (pV) + int ipv_ = 0; + //! Index for entalpy (pV + total energy) + int ienthalpy_ = 0; + + /*! \brief If the constraints virial should be printed. + * Can only be true if "GMX_CONSTRAINTVIR" environmental variable is set */ + bool bConstrVir_ = false; + //! Index for constrains virial + int isvir_ = 0; + //! Index for force virial + int ifvir_ = 0; + + //! If we have pressure computed + bool bPres_ = false; + //! Index for total virial + int ivir_ = 0; + //! Index for pressure + int ipres_ = 0; + /*! \brief Index for surface tension + * [(pres[ZZ][ZZ]-(pres[XX][XX]+pres[YY][YY])*0.5)*box[ZZ][ZZ]]*/ + int isurft_ = 0; + + //! Pressure control scheme + int epc_ = 0; + //! Index for velocity of the box borders + int ipc_ = 0; + + //! If dipole was calculated + bool bMu_ = false; + //! Index for the dipole + int imu_ = 0; + + //! Index for coseine acceleration used for viscocity calculation + int ivcos_ = 0; + //! Index for viscocity + int ivisc_ = 0; + + //! Which energy terms from egNR list should be printed in group-to-group block + bool bEInd_[egNR] = { false }; + //! Number of energy terms to be printed (these, for which bEInd[] == true) + int nEc_ = 0; + //! Number of energy output groups + int nEg_ = 0; + //! Number of intergroup energy sets to be printed for each energy term (nE = (nEg*(nEg+1))/2) + int nE_ = 0; + //! Indexes for integroup energy sets (each set with nEc energies) + int* igrp_ = nullptr; + + //! Number of temperature coupling groups + int nTC_ = 0; + //! Index for temperature + int itemp_ = 0; + + //! Number of Nose-Hoover chains + int nNHC_ = 0; + //! Number of temperature coupling coefficients in case of NH Chains + int mde_n_ = 0; + //! Index for temperature coupling coefficient in case of NH chains + int itc_ = 0; + + //! Number of temperature coupling terms if the temperature control is dealt by barostat (MTTK case) + int nTCP_ = 0; + //! Scalling factors for temperaturs control in MTTK + int mdeb_n_ = 0; + //! Index for scalling factor of MTTK + int itcb_ = 0; + + //! Number of acceleration groups + int nU_ = 0; + //! Index for group velocities + int iu_ = 0; + + //! Array to accumulate values during update + real* tmp_r_ = nullptr; + //! Array to accumulate values during update + rvec* tmp_v_ = nullptr; + + //! The dhdl.xvg output file + FILE* fp_dhdl_ = nullptr; + //! Energy components for dhdl.xvg output + double* dE_ = nullptr; + //! The delta U components (raw data + histogram) + t_mde_delta_h_coll* dhc_ = nullptr; + //! Temperatures for simulated tempering groups + real* temperatures_ = nullptr; + //! Number of temperatures actually saved + int numTemperatures_ = 0; }; } // namespace gmx //! Open the dhdl file for output -FILE *open_dhdl(const char *filename, const t_inputrec *ir, - const gmx_output_env_t *oenv); +FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env_t* oenv); #endif diff --git a/src/gromacs/mdlib/expanded.cpp b/src/gromacs/mdlib/expanded.cpp index 3f17c1078e..2d82013c81 100644 --- a/src/gromacs/mdlib/expanded.cpp +++ b/src/gromacs/mdlib/expanded.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2012-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,7 +70,7 @@ #include "gromacs/utility/gmxmpi.h" #include "gromacs/utility/smalloc.h" -static void init_df_history_weights(df_history_t *dfhist, const t_expanded *expand, int nlim) +static void init_df_history_weights(df_history_t* dfhist, const t_expanded* expand, int nlim) { int i; dfhist->wl_delta = expand->init_wl_delta; @@ -82,7 +83,7 @@ static void init_df_history_weights(df_history_t *dfhist, const t_expanded *expa /* Eventually should contain all the functions needed to initialize expanded ensemble before the md loop starts */ -void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec *ir, df_history_t *dfhist) +void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec* ir, df_history_t* dfhist) { if (!bStateFromCP) { @@ -90,7 +91,7 @@ void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec *ir, df_hist } } -static void GenerateGibbsProbabilities(const real *ene, double *p_k, double *pks, int minfep, int maxfep) +static void GenerateGibbsProbabilities(const real* ene, double* p_k, double* pks, int minfep, int maxfep) { int i; @@ -109,21 +110,22 @@ static void GenerateGibbsProbabilities(const real *ene, double *p_k, double *pks /* find the denominator */ for (i = minfep; i <= maxfep; i++) { - *pks += std::exp(ene[i]-maxene); + *pks += std::exp(ene[i] - maxene); } /*numerators*/ for (i = minfep; i <= maxfep; i++) { - p_k[i] = std::exp(ene[i]-maxene) / *pks; + p_k[i] = std::exp(ene[i] - maxene) / *pks; } } -static void GenerateWeightedGibbsProbabilities(const real *ene, double *p_k, double *pks, int nlim, real *nvals, real delta) +static void +GenerateWeightedGibbsProbabilities(const real* ene, double* p_k, double* pks, int nlim, real* nvals, real delta) { int i; real maxene; - real *nene; + real* nene; *pks = 0.0; snew(nene, nlim); @@ -133,7 +135,7 @@ static void GenerateWeightedGibbsProbabilities(const real *ene, double *p_k, dou { /* add the delta, since we need to make sure it's greater than zero, and we need a non-arbitrary number? */ - nene[i] = ene[i] + std::log(nvals[i]+delta); + nene[i] = ene[i] + std::log(nvals[i] + delta); } else { @@ -171,7 +173,7 @@ static void GenerateWeightedGibbsProbabilities(const real *ene, double *p_k, dou sfree(nene); } -static int FindMinimum(const real *min_metric, int N) +static int FindMinimum(const real* min_metric, int N) { real min_val; @@ -191,7 +193,7 @@ static int FindMinimum(const real *min_metric, int N) return min_nval; } -static gmx_bool CheckHistogramRatios(int nhisto, const real *histo, real ratio) +static gmx_bool CheckHistogramRatios(int nhisto, const real* histo, real ratio) { int i; @@ -216,7 +218,7 @@ static gmx_bool CheckHistogramRatios(int nhisto, const real *histo, real ratio) for (i = 0; i < nhisto; i++) { /* make sure that all points are in the ratio < x < 1/ratio range */ - if (!((histo[i]/nmean < 1.0/ratio) && (histo[i]/nmean > ratio))) + if (!((histo[i] / nmean < 1.0 / ratio) && (histo[i] / nmean > ratio))) { bIfFlat = FALSE; break; @@ -225,7 +227,7 @@ static gmx_bool CheckHistogramRatios(int nhisto, const real *histo, real ratio) return bIfFlat; } -static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded *expand, const df_history_t *dfhist, int64_t step) +static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded* expand, const df_history_t* dfhist, int64_t step) { int i, totalsamples; @@ -237,8 +239,9 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded *expand, con { for (i = 0; i < nlim; i++) { - if (dfhist->n_at_lam[i] < expand->lmc_forced_nstart) /* we are still doing the initial sweep, so we're definitely not - done equilibrating*/ + if (dfhist->n_at_lam[i] + < expand->lmc_forced_nstart) /* we are still doing the initial sweep, so we're + definitely not done equilibrating*/ { bDoneEquilibrating = FALSE; break; @@ -282,10 +285,11 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded *expand, con case elmceqNUMATLAM: for (i = 0; i < nlim; i++) { - if (dfhist->n_at_lam[i] < expand->equil_n_at_lam) /* we are still doing the initial sweep, so we're definitely not - done equilibrating*/ + if (dfhist->n_at_lam[i] + < expand->equil_n_at_lam) /* we are still doing the initial sweep, so we're + definitely not done equilibrating*/ { - bDoneEquilibrating = FALSE; + bDoneEquilibrating = FALSE; break; } } @@ -308,14 +312,14 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded *expand, con if (!(EWL(expand->elamstats) || expand->elamstats == elamstatsMINVAR)) { - /* we want to use flatness -avoiding- the forced-through samples. Plus, we need to convert to - floats for this histogram function. */ + /* we want to use flatness -avoiding- the forced-through samples. Plus, we need + to convert to floats for this histogram function. */ - real *modhisto; + real* modhisto; snew(modhisto, nlim); for (i = 0; i < nlim; i++) { - modhisto[i] = 1.0*(dfhist->n_at_lam[i]-expand->lmc_forced_nstart); + modhisto[i] = 1.0 * (dfhist->n_at_lam[i] - expand->lmc_forced_nstart); } bIfFlat = CheckHistogramRatios(nlim, modhisto, expand->equil_ratio); sfree(modhisto); @@ -325,29 +329,33 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded *expand, con } } break; - default: - bDoneEquilibrating = TRUE; - break; + default: bDoneEquilibrating = TRUE; break; } } return bDoneEquilibrating; } -static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist, - int fep_state, const real *scaled_lamee, const real *weighted_lamee, int64_t step) +static gmx_bool UpdateWeights(int nlim, + t_expanded* expand, + df_history_t* dfhist, + int fep_state, + const real* scaled_lamee, + const real* weighted_lamee, + int64_t step) { - gmx_bool bSufficientSamples; - int i; - int n0, np1, nm1, nval, min_nvalm, min_nvalp, maxc; - real omega_m1_0, omega_p1_0, clam_osum; - real de, de_function; - real cnval, zero_sum_weights; - real *omegam_array, *weightsm_array, *omegap_array, *weightsp_array, *varm_array, *varp_array, *dwp_array, *dwm_array; - real clam_varm, clam_varp, clam_weightsm, clam_weightsp, clam_minvar; - real *lam_variance, *lam_dg; - double *p_k; - double pks = 0; - real chi_m1_0, chi_p1_0, chi_m2_0, chi_p2_0, chi_p1_m1, chi_p2_m1, chi_m1_p1, chi_m2_p1; + gmx_bool bSufficientSamples; + int i; + int n0, np1, nm1, nval, min_nvalm, min_nvalp, maxc; + real omega_m1_0, omega_p1_0, clam_osum; + real de, de_function; + real cnval, zero_sum_weights; + real *omegam_array, *weightsm_array, *omegap_array, *weightsp_array, *varm_array, *varp_array, + *dwp_array, *dwm_array; + real clam_varm, clam_varp, clam_weightsm, clam_weightsp, clam_minvar; + real * lam_variance, *lam_dg; + double* p_k; + double pks = 0; + real chi_m1_0, chi_p1_0, chi_m2_0, chi_p2_0, chi_p1_m1, chi_p2_m1, chi_m1_p1, chi_m2_p1; /* if we have equilibrated the weights, exit now */ if (dfhist->bEquil) @@ -372,17 +380,17 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist if (EWL(expand->elamstats)) { - if (expand->elamstats == elamstatsWL) /* Standard Wang-Landau */ + if (expand->elamstats == elamstatsWL) /* Standard Wang-Landau */ { dfhist->sum_weights[fep_state] -= dfhist->wl_delta; - dfhist->wl_histo[fep_state] += 1.0; + dfhist->wl_histo[fep_state] += 1.0; } else if (expand->elamstats == elamstatsWWL) /* Weighted Wang-Landau */ { snew(p_k, nlim); /* first increment count */ - GenerateGibbsProbabilities(weighted_lamee, p_k, &pks, 0, nlim-1); + GenerateGibbsProbabilities(weighted_lamee, p_k, &pks, 0, nlim - 1); for (i = 0; i < nlim; i++) { dfhist->wl_histo[i] += static_cast(p_k[i]); @@ -390,11 +398,12 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist /* then increment weights (uses count) */ pks = 0.0; - GenerateWeightedGibbsProbabilities(weighted_lamee, p_k, &pks, nlim, dfhist->wl_histo, dfhist->wl_delta); + GenerateWeightedGibbsProbabilities(weighted_lamee, p_k, &pks, nlim, dfhist->wl_histo, + dfhist->wl_delta); for (i = 0; i < nlim; i++) { - dfhist->sum_weights[i] -= dfhist->wl_delta*static_cast(p_k[i]); + dfhist->sum_weights[i] -= dfhist->wl_delta * static_cast(p_k[i]); } /* Alternate definition, using logarithms. Shouldn't make very much difference! */ /* @@ -408,18 +417,19 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist sfree(p_k); } - zero_sum_weights = dfhist->sum_weights[0]; + zero_sum_weights = dfhist->sum_weights[0]; for (i = 0; i < nlim; i++) { dfhist->sum_weights[i] -= zero_sum_weights; } } - if (expand->elamstats == elamstatsBARKER || expand->elamstats == elamstatsMETROPOLIS || expand->elamstats == elamstatsMINVAR) + if (expand->elamstats == elamstatsBARKER || expand->elamstats == elamstatsMETROPOLIS + || expand->elamstats == elamstatsMINVAR) { - de_function = 0; /* to get rid of warnings, but this value will not be used because of the logic */ - maxc = 2*expand->c_range+1; + de_function = 0; /* to get rid of warnings, but this value will not be used because of the logic */ + maxc = 2 * expand->c_range + 1; snew(lam_dg, nlim); snew(lam_variance, nlim); @@ -436,24 +446,25 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist /* unpack the current lambdas -- we will only update 2 of these */ - for (i = 0; i < nlim-1; i++) - { /* only through the second to last */ - lam_dg[i] = dfhist->sum_dg[i+1] - dfhist->sum_dg[i]; - lam_variance[i] = gmx::square(dfhist->sum_variance[i+1]) - gmx::square(dfhist->sum_variance[i]); + for (i = 0; i < nlim - 1; i++) + { /* only through the second to last */ + lam_dg[i] = dfhist->sum_dg[i + 1] - dfhist->sum_dg[i]; + lam_variance[i] = + gmx::square(dfhist->sum_variance[i + 1]) - gmx::square(dfhist->sum_variance[i]); } /* accumulate running averages */ for (nval = 0; nval < maxc; nval++) { /* constants for later use */ - cnval = static_cast(nval-expand->c_range); + cnval = static_cast(nval - expand->c_range); /* actually, should be able to rewrite it w/o exponential, for better numerical stability */ if (fep_state > 0) { - de = std::exp(cnval - (scaled_lamee[fep_state]-scaled_lamee[fep_state-1])); + de = std::exp(cnval - (scaled_lamee[fep_state] - scaled_lamee[fep_state - 1])); if (expand->elamstats == elamstatsBARKER || expand->elamstats == elamstatsMINVAR) { - de_function = 1.0/(1.0+de); + de_function = 1.0 / (1.0 + de); } else if (expand->elamstats == elamstatsMETROPOLIS) { @@ -463,19 +474,19 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist } else { - de_function = 1.0/de; + de_function = 1.0 / de; } } - dfhist->accum_m[fep_state][nval] += de_function; - dfhist->accum_m2[fep_state][nval] += de_function*de_function; + dfhist->accum_m[fep_state][nval] += de_function; + dfhist->accum_m2[fep_state][nval] += de_function * de_function; } - if (fep_state < nlim-1) + if (fep_state < nlim - 1) { - de = std::exp(-cnval + (scaled_lamee[fep_state+1]-scaled_lamee[fep_state])); + de = std::exp(-cnval + (scaled_lamee[fep_state + 1] - scaled_lamee[fep_state])); if (expand->elamstats == elamstatsBARKER || expand->elamstats == elamstatsMINVAR) { - de_function = 1.0/(1.0+de); + de_function = 1.0 / (1.0 + de); } else if (expand->elamstats == elamstatsMETROPOLIS) { @@ -485,27 +496,27 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist } else { - de_function = 1.0/de; + de_function = 1.0 / de; } } - dfhist->accum_p[fep_state][nval] += de_function; - dfhist->accum_p2[fep_state][nval] += de_function*de_function; + dfhist->accum_p[fep_state][nval] += de_function; + dfhist->accum_p2[fep_state][nval] += de_function * de_function; } /* Metropolis transition and Barker transition (unoptimized Bennett) acceptance weight determination */ - n0 = dfhist->n_at_lam[fep_state]; + n0 = dfhist->n_at_lam[fep_state]; if (fep_state > 0) { - nm1 = dfhist->n_at_lam[fep_state-1]; + nm1 = dfhist->n_at_lam[fep_state - 1]; } else { nm1 = 0; } - if (fep_state < nlim-1) + if (fep_state < nlim - 1) { - np1 = dfhist->n_at_lam[fep_state+1]; + np1 = dfhist->n_at_lam[fep_state + 1]; } else { @@ -517,22 +528,22 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist if (n0 > 0) { - chi_m1_0 = dfhist->accum_m[fep_state][nval]/n0; - chi_p1_0 = dfhist->accum_p[fep_state][nval]/n0; - chi_m2_0 = dfhist->accum_m2[fep_state][nval]/n0; - chi_p2_0 = dfhist->accum_p2[fep_state][nval]/n0; + chi_m1_0 = dfhist->accum_m[fep_state][nval] / n0; + chi_p1_0 = dfhist->accum_p[fep_state][nval] / n0; + chi_m2_0 = dfhist->accum_m2[fep_state][nval] / n0; + chi_p2_0 = dfhist->accum_p2[fep_state][nval] / n0; } - if ((fep_state > 0 ) && (nm1 > 0)) + if ((fep_state > 0) && (nm1 > 0)) { - chi_p1_m1 = dfhist->accum_p[fep_state-1][nval]/nm1; - chi_p2_m1 = dfhist->accum_p2[fep_state-1][nval]/nm1; + chi_p1_m1 = dfhist->accum_p[fep_state - 1][nval] / nm1; + chi_p2_m1 = dfhist->accum_p2[fep_state - 1][nval] / nm1; } - if ((fep_state < nlim-1) && (np1 > 0)) + if ((fep_state < nlim - 1) && (np1 > 0)) { - chi_m1_p1 = dfhist->accum_m[fep_state+1][nval]/np1; - chi_m2_p1 = dfhist->accum_m2[fep_state+1][nval]/np1; + chi_m1_p1 = dfhist->accum_m[fep_state + 1][nval] / np1; + chi_m2_p1 = dfhist->accum_m2[fep_state + 1][nval] / np1; } omega_m1_0 = 0; @@ -546,68 +557,67 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist { if (n0 > 0) { - omega_m1_0 = chi_m2_0/(chi_m1_0*chi_m1_0) - 1.0; + omega_m1_0 = chi_m2_0 / (chi_m1_0 * chi_m1_0) - 1.0; if (nm1 > 0) { - real omega_p1_m1 = chi_p2_m1/(chi_p1_m1*chi_p1_m1) - 1.0; - clam_weightsm = (std::log(chi_m1_0) - std::log(chi_p1_m1)) + cnval; - clam_varm = (1.0/n0)*(omega_m1_0) + (1.0/nm1)*(omega_p1_m1); + real omega_p1_m1 = chi_p2_m1 / (chi_p1_m1 * chi_p1_m1) - 1.0; + clam_weightsm = (std::log(chi_m1_0) - std::log(chi_p1_m1)) + cnval; + clam_varm = (1.0 / n0) * (omega_m1_0) + (1.0 / nm1) * (omega_p1_m1); } } } - if (fep_state < nlim-1) + if (fep_state < nlim - 1) { if (n0 > 0) { - omega_p1_0 = chi_p2_0/(chi_p1_0*chi_p1_0) - 1.0; + omega_p1_0 = chi_p2_0 / (chi_p1_0 * chi_p1_0) - 1.0; if (np1 > 0) { - real omega_m1_p1 = chi_m2_p1/(chi_m1_p1*chi_m1_p1) - 1.0; - clam_weightsp = (std::log(chi_m1_p1) - std::log(chi_p1_0)) + cnval; - clam_varp = (1.0/np1)*(omega_m1_p1) + (1.0/n0)*(omega_p1_0); + real omega_m1_p1 = chi_m2_p1 / (chi_m1_p1 * chi_m1_p1) - 1.0; + clam_weightsp = (std::log(chi_m1_p1) - std::log(chi_p1_0)) + cnval; + clam_varp = (1.0 / np1) * (omega_m1_p1) + (1.0 / n0) * (omega_p1_0); } } } if (n0 > 0) { - omegam_array[nval] = omega_m1_0; + omegam_array[nval] = omega_m1_0; } else { - omegam_array[nval] = 0; + omegam_array[nval] = 0; } - weightsm_array[nval] = clam_weightsm; - varm_array[nval] = clam_varm; + weightsm_array[nval] = clam_weightsm; + varm_array[nval] = clam_varm; if (nm1 > 0) { - dwm_array[nval] = fabs( (cnval + std::log((1.0*n0)/nm1)) - lam_dg[fep_state-1] ); + dwm_array[nval] = fabs((cnval + std::log((1.0 * n0) / nm1)) - lam_dg[fep_state - 1]); } else { - dwm_array[nval] = std::fabs( cnval - lam_dg[fep_state-1] ); + dwm_array[nval] = std::fabs(cnval - lam_dg[fep_state - 1]); } if (n0 > 0) { - omegap_array[nval] = omega_p1_0; + omegap_array[nval] = omega_p1_0; } else { - omegap_array[nval] = 0; + omegap_array[nval] = 0; } - weightsp_array[nval] = clam_weightsp; - varp_array[nval] = clam_varp; + weightsp_array[nval] = clam_weightsp; + varp_array[nval] = clam_varp; if ((np1 > 0) && (n0 > 0)) { - dwp_array[nval] = fabs( (cnval + std::log((1.0*np1)/n0)) - lam_dg[fep_state] ); + dwp_array[nval] = fabs((cnval + std::log((1.0 * np1) / n0)) - lam_dg[fep_state]); } else { - dwp_array[nval] = std::fabs( cnval - lam_dg[fep_state] ); + dwp_array[nval] = std::fabs(cnval - lam_dg[fep_state]); } - } /* find the C's closest to the old weights value */ @@ -626,16 +636,16 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist clam_minvar = 0; if (clam_osum > 0) { - clam_minvar = 0.5*std::log(clam_osum); + clam_minvar = 0.5 * std::log(clam_osum); } if (fep_state > 0) { - lam_dg[fep_state-1] = clam_weightsm; - lam_variance[fep_state-1] = clam_varm; + lam_dg[fep_state - 1] = clam_weightsm; + lam_variance[fep_state - 1] = clam_varm; } - if (fep_state < nlim-1) + if (fep_state < nlim - 1) { lam_dg[fep_state] = clam_weightsp; lam_variance[fep_state] = clam_varp; @@ -659,7 +669,7 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist { for (i = 0; i < nlim; i++) { - dfhist->sum_minvar[i] += (expand->minvar_const-clam_minvar); + dfhist->sum_minvar[i] += (expand->minvar_const - clam_minvar); } expand->minvar_const = clam_minvar; dfhist->sum_minvar[fep_state] = 0.0; @@ -678,9 +688,10 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist for (i = 1; i < nlim; i++) { - dfhist->sum_dg[i] = lam_dg[i-1] + dfhist->sum_dg[i-1]; - dfhist->sum_variance[i] = std::sqrt(lam_variance[i-1] + gmx::square(dfhist->sum_variance[i-1])); - dfhist->sum_weights[i] = dfhist->sum_dg[i] + dfhist->sum_minvar[i]; + dfhist->sum_dg[i] = lam_dg[i - 1] + dfhist->sum_dg[i - 1]; + dfhist->sum_variance[i] = + std::sqrt(lam_variance[i - 1] + gmx::square(dfhist->sum_variance[i - 1])); + dfhist->sum_weights[i] = dfhist->sum_dg[i] + dfhist->sum_minvar[i]; } sfree(lam_dg); @@ -699,26 +710,32 @@ static gmx_bool UpdateWeights(int nlim, t_expanded *expand, df_history_t *dfhist return FALSE; } -static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfhist, int fep_state, - const real *weighted_lamee, double *p_k, - int64_t seed, int64_t step) +static int ChooseNewLambda(int nlim, + const t_expanded* expand, + df_history_t* dfhist, + int fep_state, + const real* weighted_lamee, + double* p_k, + int64_t seed, + int64_t step) { /* Choose new lambda value, and update transition matrix */ - int i, ifep, minfep, maxfep, lamnew, lamtrial, starting_fep_state; - real r1, r2, de, trialprob, tprob = 0; - double *propose, *accept, *remainder; - double pks; - real pnorm; - gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::ExpandedEnsemble); // We only draw once, so zero bits internal counter is fine - gmx::UniformRealDistribution dist; + int i, ifep, minfep, maxfep, lamnew, lamtrial, starting_fep_state; + real r1, r2, de, trialprob, tprob = 0; + double * propose, *accept, *remainder; + double pks; + real pnorm; + gmx::ThreeFry2x64<0> rng( + seed, gmx::RandomDomain::ExpandedEnsemble); // We only draw once, so zero bits internal counter is fine + gmx::UniformRealDistribution dist; starting_fep_state = fep_state; lamnew = fep_state; /* so that there is a default setting -- stays the same */ - if (!EWL(expand->elamstats)) /* ignore equilibrating the weights if using WL */ + if (!EWL(expand->elamstats)) /* ignore equilibrating the weights if using WL */ { - if ((expand->lmc_forced_nstart > 0) && (dfhist->n_at_lam[nlim-1] <= expand->lmc_forced_nstart)) + if ((expand->lmc_forced_nstart > 0) && (dfhist->n_at_lam[nlim - 1] <= expand->lmc_forced_nstart)) { /* Use a marching method to run through the lambdas and get preliminary free energy data, before starting 'free' sampling. We start free sampling when we have enough at each lambda */ @@ -727,8 +744,8 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh if (dfhist->n_at_lam[fep_state] == expand->lmc_forced_nstart) { - lamnew = fep_state+1; - if (lamnew == nlim) /* whoops, stepped too far! */ + lamnew = fep_state + 1; + if (lamnew == nlim) /* whoops, stepped too far! */ { lamnew -= 1; } @@ -761,8 +778,8 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh /* use the Gibbs sampler, with restricted range */ if (expand->gibbsdeltalam < 0) { - minfep = 0; - maxfep = nlim-1; + minfep = 0; + maxfep = nlim - 1; } else { @@ -772,9 +789,9 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh { minfep = 0; } - if (maxfep > nlim-1) + if (maxfep > nlim - 1) { - maxfep = nlim-1; + maxfep = nlim - 1; } } @@ -821,7 +838,7 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh { if (ifep != fep_state) { - propose[ifep] = p_k[ifep]/remainder[fep_state]; + propose[ifep] = p_k[ifep] / remainder[fep_state]; } else { @@ -832,7 +849,7 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh r1 = dist(rng); for (lamtrial = minfep; lamtrial <= maxfep; lamtrial++) { - pnorm = p_k[lamtrial]/remainder[fep_state]; + pnorm = p_k[lamtrial] / remainder[fep_state]; if (lamtrial != fep_state) { if (r1 <= pnorm) @@ -846,7 +863,7 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh /* we have now selected lamtrial according to p(lamtrial)/1-p(fep_state) */ tprob = 1.0; /* trial probability is min{1,\frac{1 - p(old)}{1-p(new)} MRS 1/8/2008 */ - trialprob = (remainder[fep_state])/(remainder[lamtrial]); + trialprob = (remainder[fep_state]) / (remainder[lamtrial]); if (trialprob < tprob) { tprob = trialprob; @@ -868,7 +885,7 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh tprob = 1.0; if (remainder[ifep] != 0) { - trialprob = (remainder[fep_state])/(remainder[ifep]); + trialprob = (remainder[fep_state]) / (remainder[ifep]); } else { @@ -886,7 +903,7 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh if (lamnew > maxfep) { /* it's possible some rounding is failing */ - if (gmx_within_tol(remainder[fep_state], 0, 50*GMX_DOUBLE_EPS)) + if (gmx_within_tol(remainder[fep_state], 0, 50 * GMX_DOUBLE_EPS)) { /* numerical rounding error -- no state other than the original has weight */ lamnew = fep_state; @@ -895,15 +912,21 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh { /* probably not a numerical issue */ int loc = 0; - int nerror = 200+(maxfep-minfep+1)*60; - char *errorstr; + int nerror = 200 + (maxfep - minfep + 1) * 60; + char* errorstr; snew(errorstr, nerror); - /* if its greater than maxfep, then something went wrong -- probably underflow in the calculation - of sum weights. Generated detailed info for failure */ - loc += sprintf(errorstr, "Something wrong in choosing new lambda state with a Gibbs move -- probably underflow in weight determination.\nDenominator is: %3d%17.10e\n i dE numerator weights\n", 0, pks); + /* if its greater than maxfep, then something went wrong -- probably underflow + in the calculation of sum weights. Generated detailed info for failure */ + loc += sprintf( + errorstr, + "Something wrong in choosing new lambda state with a Gibbs move -- " + "probably underflow in weight determination.\nDenominator is: " + "%3d%17.10e\n i dE numerator weights\n", + 0, pks); for (ifep = minfep; ifep <= maxfep; ifep++) { - loc += sprintf(&errorstr[loc], "%3d %17.10e%17.10e%17.10e\n", ifep, weighted_lamee[ifep], p_k[ifep], dfhist->sum_weights[ifep]); + loc += sprintf(&errorstr[loc], "%3d %17.10e%17.10e%17.10e\n", ifep, + weighted_lamee[ifep], p_k[ifep], dfhist->sum_weights[ifep]); } gmx_fatal(FARGS, "%s", errorstr); } @@ -921,18 +944,18 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh } else { - lamtrial = fep_state-1; + lamtrial = fep_state - 1; } } else { - if (fep_state == nlim-1) + if (fep_state == nlim - 1) { lamtrial = fep_state; } else { - lamtrial = fep_state+1; + lamtrial = fep_state + 1; } } @@ -947,18 +970,19 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh } propose[fep_state] = 0; propose[lamtrial] = 1.0; /* note that this overwrites the above line if fep_state = ntrial, which only occurs at the ends */ - accept[fep_state] = 1.0; /* doesn't actually matter, never proposed unless fep_state = ntrial, in which case it's 1.0 anyway */ - accept[lamtrial] = tprob; - + accept[fep_state] = + 1.0; /* doesn't actually matter, never proposed unless fep_state = ntrial, in which case it's 1.0 anyway */ + accept[lamtrial] = tprob; } else if (expand->elmcmove == elmcmoveBARKER) { - tprob = 1.0/(1.0+std::exp(-de)); + tprob = 1.0 / (1.0 + std::exp(-de)); - propose[fep_state] = (1-tprob); - propose[lamtrial] += tprob; /* we add, to account for the fact that at the end, they might be the same point */ - accept[fep_state] = 1.0; - accept[lamtrial] = 1.0; + propose[fep_state] = (1 - tprob); + propose[lamtrial] += + tprob; /* we add, to account for the fact that at the end, they might be the same point */ + accept[fep_state] = 1.0; + accept[lamtrial] = 1.0; } r2 = dist(rng); @@ -974,8 +998,8 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh for (ifep = 0; ifep < nlim; ifep++) { - dfhist->Tij[fep_state][ifep] += propose[ifep]*accept[ifep]; - dfhist->Tij[fep_state][fep_state] += propose[ifep]*(1.0-accept[ifep]); + dfhist->Tij[fep_state][ifep] += propose[ifep] * accept[ifep]; + dfhist->Tij[fep_state][fep_state] += propose[ifep] * (1.0 - accept[ifep]); } fep_state = lamnew; } @@ -990,13 +1014,19 @@ static int ChooseNewLambda(int nlim, const t_expanded *expand, df_history_t *dfh } /* print out the weights to the log, along with current state */ -void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expanded *expand, - const t_simtemp *simtemp, const df_history_t *dfhist, - int fep_state, int frequency, int64_t step) +void PrintFreeEnergyInfoToFile(FILE* outfile, + const t_lambda* fep, + const t_expanded* expand, + const t_simtemp* simtemp, + const df_history_t* dfhist, + int fep_state, + int frequency, + int64_t step) { int nlim, i, ifep, jfep; real dw, dg, dv, Tprint; - const char *print_names[efptNR] = {" FEPL", "MassL", "CoulL", " VdwL", "BondL", "RestT", "Temp.(K)"}; + const char* print_names[efptNR] = { " FEPL", "MassL", "CoulL", " VdwL", + "BondL", "RestT", "Temp.(K)" }; gmx_bool bSimTemp = FALSE; nlim = fep->n_lambda; @@ -1035,7 +1065,7 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan } for (ifep = 0; ifep < nlim; ifep++) { - if (ifep == nlim-1) + if (ifep == nlim - 1) { dw = 0.0; dg = 0.0; @@ -1043,11 +1073,12 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan } else { - dw = dfhist->sum_weights[ifep+1] - dfhist->sum_weights[ifep]; - dg = dfhist->sum_dg[ifep+1] - dfhist->sum_dg[ifep]; - dv = std::sqrt(gmx::square(dfhist->sum_variance[ifep+1]) - gmx::square(dfhist->sum_variance[ifep])); + dw = dfhist->sum_weights[ifep + 1] - dfhist->sum_weights[ifep]; + dg = dfhist->sum_dg[ifep + 1] - dfhist->sum_dg[ifep]; + dv = std::sqrt(gmx::square(dfhist->sum_variance[ifep + 1]) + - gmx::square(dfhist->sum_variance[ifep])); } - fprintf(outfile, "%3d", (ifep+1)); + fprintf(outfile, "%3d", (ifep + 1)); for (i = 0; i < efptNR; i++) { if (fep->separate_dvdl[i]) @@ -1059,7 +1090,8 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan fprintf(outfile, "%9.3f", simtemp->temperatures[ifep]); } } - if (EWL(expand->elamstats) && (!(dfhist->bEquil))) /* if performing WL and still haven't equilibrated */ + if (EWL(expand->elamstats) + && (!(dfhist->bEquil))) /* if performing WL and still haven't equilibrated */ { if (expand->elamstats == elamstatsWL) { @@ -1070,13 +1102,14 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan fprintf(outfile, " %8.3f", dfhist->wl_histo[ifep]); } } - else /* we have equilibrated weights */ + else /* we have equilibrated weights */ { fprintf(outfile, " %8d", dfhist->n_at_lam[ifep]); } if (expand->elamstats == elamstatsMINVAR) { - fprintf(outfile, " %10.5f %10.5f %10.5f %10.5f", dfhist->sum_weights[ifep], dfhist->sum_dg[ifep], dg, dv); + fprintf(outfile, " %10.5f %10.5f %10.5f %10.5f", dfhist->sum_weights[ifep], + dfhist->sum_dg[ifep], dg, dv); } else { @@ -1098,7 +1131,7 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan fprintf(outfile, " Transition Matrix\n"); for (ifep = 0; ifep < nlim; ifep++) { - fprintf(outfile, "%12d", (ifep+1)); + fprintf(outfile, "%12d", (ifep + 1)); } fprintf(outfile, "\n"); for (ifep = 0; ifep < nlim; ifep++) @@ -1109,11 +1142,12 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan { if (expand->bSymmetrizedTMatrix) { - Tprint = (dfhist->Tij[ifep][jfep]+dfhist->Tij[jfep][ifep])/(dfhist->n_at_lam[ifep]+dfhist->n_at_lam[jfep]); + Tprint = (dfhist->Tij[ifep][jfep] + dfhist->Tij[jfep][ifep]) + / (dfhist->n_at_lam[ifep] + dfhist->n_at_lam[jfep]); } else { - Tprint = (dfhist->Tij[ifep][jfep])/(dfhist->n_at_lam[ifep]); + Tprint = (dfhist->Tij[ifep][jfep]) / (dfhist->n_at_lam[ifep]); } } else @@ -1122,13 +1156,13 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan } fprintf(outfile, "%12.8f", Tprint); } - fprintf(outfile, "%3d\n", (ifep+1)); + fprintf(outfile, "%3d\n", (ifep + 1)); } fprintf(outfile, " Empirical Transition Matrix\n"); for (ifep = 0; ifep < nlim; ifep++) { - fprintf(outfile, "%12d", (ifep+1)); + fprintf(outfile, "%12d", (ifep + 1)); } fprintf(outfile, "\n"); for (ifep = 0; ifep < nlim; ifep++) @@ -1139,11 +1173,12 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan { if (expand->bSymmetrizedTMatrix) { - Tprint = (dfhist->Tij_empirical[ifep][jfep]+dfhist->Tij_empirical[jfep][ifep])/(dfhist->n_at_lam[ifep]+dfhist->n_at_lam[jfep]); + Tprint = (dfhist->Tij_empirical[ifep][jfep] + dfhist->Tij_empirical[jfep][ifep]) + / (dfhist->n_at_lam[ifep] + dfhist->n_at_lam[jfep]); } else { - Tprint = dfhist->Tij_empirical[ifep][jfep]/(dfhist->n_at_lam[ifep]); + Tprint = dfhist->Tij_empirical[ifep][jfep] / (dfhist->n_at_lam[ifep]); } } else @@ -1152,25 +1187,31 @@ void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expan } fprintf(outfile, "%12.8f", Tprint); } - fprintf(outfile, "%3d\n", (ifep+1)); + fprintf(outfile, "%3d\n", (ifep + 1)); } } } } -int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata_t *enerd, - t_state *state, t_extmass *MassQ, int fep_state, df_history_t *dfhist, - int64_t step, - rvec *v, const t_mdatoms *mdatoms) +int ExpandedEnsembleDynamics(FILE* log, + const t_inputrec* ir, + const gmx_enerdata_t* enerd, + t_state* state, + t_extmass* MassQ, + int fep_state, + df_history_t* dfhist, + int64_t step, + rvec* v, + const t_mdatoms* mdatoms) /* Note that the state variable is only needed for simulated tempering, not Hamiltonian expanded ensemble. May be able to remove it after integrator refactoring. */ { - real *pfep_lamee, *scaled_lamee, *weighted_lamee; - double *p_k; + real * pfep_lamee, *scaled_lamee, *weighted_lamee; + double* p_k; int i, nlim, lamnew, totalsamples; real oneovert, maxscaled = 0, maxweighted = 0; - t_expanded *expand; - t_simtemp *simtemp; + t_expanded* expand; + t_simtemp* simtemp; gmx_bool bIfReset, bSwitchtoOneOverT, bDoneEquilibrating = FALSE; expand = ir->expandedvals; @@ -1185,8 +1226,8 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata /* update the count at the current lambda*/ dfhist->n_at_lam[fep_state]++; - /* need to calculate the PV term somewhere, but not needed here? Not until there's a lambda state that's - pressure controlled.*/ + /* need to calculate the PV term somewhere, but not needed here? Not until there's a lambda + state that's pressure controlled.*/ /* pVTerm = 0; where does this PV term go? @@ -1207,12 +1248,17 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata if (ir->bSimTemp) { /* Note -- this assumes no mass changes, since kinetic energy is not added . . . */ - scaled_lamee[i] = (enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0])/(simtemp->temperatures[i]*BOLTZ) - + enerd->term[F_EPOT]*(1.0/(simtemp->temperatures[i])- 1.0/(simtemp->temperatures[fep_state]))/BOLTZ; + scaled_lamee[i] = (enerd->enerpart_lambda[i + 1] - enerd->enerpart_lambda[0]) + / (simtemp->temperatures[i] * BOLTZ) + + enerd->term[F_EPOT] + * (1.0 / (simtemp->temperatures[i]) + - 1.0 / (simtemp->temperatures[fep_state])) + / BOLTZ; } else { - scaled_lamee[i] = (enerd->enerpart_lambda[i+1]-enerd->enerpart_lambda[0])/(expand->mc_temp*BOLTZ); + scaled_lamee[i] = (enerd->enerpart_lambda[i + 1] - enerd->enerpart_lambda[0]) + / (expand->mc_temp * BOLTZ); /* mc_temp is currently set to the system reft unless otherwise defined */ } @@ -1227,7 +1273,9 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata { for (i = 0; i < nlim; i++) { - scaled_lamee[i] = enerd->term[F_EPOT]*(1.0/simtemp->temperatures[i] - 1.0/simtemp->temperatures[fep_state])/BOLTZ; + scaled_lamee[i] = + enerd->term[F_EPOT] + * (1.0 / simtemp->temperatures[i] - 1.0 / simtemp->temperatures[fep_state]) / BOLTZ; } } } @@ -1257,18 +1305,20 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata for (i = 0; i < nlim; i++) { - scaled_lamee[i] -= maxscaled; + scaled_lamee[i] -= maxscaled; weighted_lamee[i] -= maxweighted; } /* update weights - we decide whether or not to actually do this inside */ - bDoneEquilibrating = UpdateWeights(nlim, expand, dfhist, fep_state, scaled_lamee, weighted_lamee, step); + bDoneEquilibrating = + UpdateWeights(nlim, expand, dfhist, fep_state, scaled_lamee, weighted_lamee, step); if (bDoneEquilibrating) { if (log) { - fprintf(log, "\nStep %" PRId64 ": Weights have equilibrated, using criteria: %s\n", step, elmceq_names[expand->elmceq]); + fprintf(log, "\nStep %" PRId64 ": Weights have equilibrated, using criteria: %s\n", + step, elmceq_names[expand->elmceq]); } } @@ -1278,7 +1328,7 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata if (ir->bSimTemp && (lamnew != fep_state)) /* only need to change the temperatures if we change the state */ { int i, j, n, d; - real *buf_ngtc; + real* buf_ngtc; real told; int nstart, nend, gt; @@ -1289,8 +1339,8 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata if (ir->opts.ref_t[i] > 0) { told = ir->opts.ref_t[i]; - ir->opts.ref_t[i] = simtemp->temperatures[lamnew]; - buf_ngtc[i] = std::sqrt(ir->opts.ref_t[i]/told); /* using the buffer as temperature scaling */ + ir->opts.ref_t[i] = simtemp->temperatures[lamnew]; + buf_ngtc[i] = std::sqrt(ir->opts.ref_t[i] / told); /* using the buffer as temperature scaling */ } } @@ -1319,14 +1369,14 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata { for (j = 0; j < ir->opts.nhchainlength; j++) { - state->nhpres_vxi[i+j] *= buf_ngtc[i]; + state->nhpres_vxi[i + j] *= buf_ngtc[i]; } } for (i = 0; i < ir->opts.ngtc; i++) { for (j = 0; j < ir->opts.nhchainlength; j++) { - state->nosehoover_vxi[i+j] *= buf_ngtc[i]; + state->nosehoover_vxi[i + j] *= buf_ngtc[i]; } } } @@ -1345,18 +1395,19 @@ int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata { totalsamples += dfhist->n_at_lam[i]; } - oneovert = (1.0*nlim)/totalsamples; + oneovert = (1.0 * nlim) / totalsamples; /* oneovert has decreasd by a bit since last time, so we actually make sure its within one of this number */ /* switch to 1/t incrementing when wl_delta has decreased at least once, and wl_delta is now less than 1/t */ - if ((dfhist->wl_delta <= ((totalsamples)/(totalsamples-1.00001))*oneovert) && - (dfhist->wl_delta < expand->init_wl_delta)) + if ((dfhist->wl_delta <= ((totalsamples) / (totalsamples - 1.00001)) * oneovert) + && (dfhist->wl_delta < expand->init_wl_delta)) { bSwitchtoOneOverT = TRUE; } } if (bSwitchtoOneOverT) { - dfhist->wl_delta = oneovert; /* now we reduce by this each time, instead of only at flatness */ + dfhist->wl_delta = + oneovert; /* now we reduce by this each time, instead of only at flatness */ } else { diff --git a/src/gromacs/mdlib/expanded.h b/src/gromacs/mdlib/expanded.h index 48a63de024..6f6bec9804 100644 --- a/src/gromacs/mdlib/expanded.h +++ b/src/gromacs/mdlib/expanded.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,17 +50,28 @@ struct t_mdatoms; struct t_simtemp; class t_state; -void init_npt_masses(const t_inputrec *ir, t_state *state, t_extmass *MassQ, gmx_bool bInit); +void init_npt_masses(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool bInit); -void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec *ir, df_history_t *dfhist); +void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec* ir, df_history_t* dfhist); -int ExpandedEnsembleDynamics(FILE *log, const t_inputrec *ir, const gmx_enerdata_t *enerd, - t_state *state, t_extmass *MassQ, int fep_state, df_history_t *dfhist, - int64_t step, - rvec *v, const t_mdatoms *mdatoms); +int ExpandedEnsembleDynamics(FILE* log, + const t_inputrec* ir, + const gmx_enerdata_t* enerd, + t_state* state, + t_extmass* MassQ, + int fep_state, + df_history_t* dfhist, + int64_t step, + rvec* v, + const t_mdatoms* mdatoms); -void PrintFreeEnergyInfoToFile(FILE *outfile, const t_lambda *fep, const t_expanded *expand, - const t_simtemp *simtemp, const df_history_t *dfhist, - int fep_state, int frequency, int64_t step); +void PrintFreeEnergyInfoToFile(FILE* outfile, + const t_lambda* fep, + const t_expanded* expand, + const t_simtemp* simtemp, + const df_history_t* dfhist, + int fep_state, + int frequency, + int64_t step); #endif diff --git a/src/gromacs/mdlib/force.cpp b/src/gromacs/mdlib/force.cpp index a82e5a98af..f659874b92 100644 --- a/src/gromacs/mdlib/force.cpp +++ b/src/gromacs/mdlib/force.cpp @@ -73,7 +73,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void clearEwaldThreadOutput(ewald_corr_thread_t *ewc_t) +static void clearEwaldThreadOutput(ewald_corr_thread_t* ewc_t) { ewc_t->Vcorr_q = 0; ewc_t->Vcorr_lj = 0; @@ -83,46 +83,45 @@ static void clearEwaldThreadOutput(ewald_corr_thread_t *ewc_t) clear_mat(ewc_t->vir_lj); } -static void reduceEwaldThreadOuput(int nthreads, ewald_corr_thread_t *ewc_t) +static void reduceEwaldThreadOuput(int nthreads, ewald_corr_thread_t* ewc_t) { - ewald_corr_thread_t &dest = ewc_t[0]; + ewald_corr_thread_t& dest = ewc_t[0]; for (int t = 1; t < nthreads; t++) { - dest.Vcorr_q += ewc_t[t].Vcorr_q; - dest.Vcorr_lj += ewc_t[t].Vcorr_lj; + dest.Vcorr_q += ewc_t[t].Vcorr_q; + dest.Vcorr_lj += ewc_t[t].Vcorr_lj; dest.dvdl[efptCOUL] += ewc_t[t].dvdl[efptCOUL]; - dest.dvdl[efptVDW] += ewc_t[t].dvdl[efptVDW]; - m_add(dest.vir_q, ewc_t[t].vir_q, dest.vir_q); + dest.dvdl[efptVDW] += ewc_t[t].dvdl[efptVDW]; + m_add(dest.vir_q, ewc_t[t].vir_q, dest.vir_q); m_add(dest.vir_lj, ewc_t[t].vir_lj, dest.vir_lj); } } -void -do_force_lowlevel(t_forcerec *fr, - const t_inputrec *ir, - const t_idef *idef, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - const t_mdatoms *md, - gmx::ArrayRefWithPadding coordinates, - history_t *hist, - gmx::ForceOutputs *forceOutputs, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - const matrix box, - const real *lambda, - const t_graph *graph, - const rvec *mu_tot, - const gmx::StepWorkload &stepWork, - const DDBalanceRegionHandler &ddBalanceRegionHandler) +void do_force_lowlevel(t_forcerec* fr, + const t_inputrec* ir, + const t_idef* idef, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + const t_mdatoms* md, + gmx::ArrayRefWithPadding coordinates, + history_t* hist, + gmx::ForceOutputs* forceOutputs, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + const matrix box, + const real* lambda, + const t_graph* graph, + const rvec* mu_tot, + const gmx::StepWorkload& stepWork, + const DDBalanceRegionHandler& ddBalanceRegionHandler) { // TODO: Replace all uses of x by const coordinates - rvec *x = as_rvec_array(coordinates.paddedArrayRef().data()); + rvec* x = as_rvec_array(coordinates.paddedArrayRef().data()); - auto &forceWithVirial = forceOutputs->forceWithVirial(); + auto& forceWithVirial = forceOutputs->forceWithVirial(); /* do QMMM first if requested */ if (fr->bQMMM) @@ -135,8 +134,7 @@ do_force_lowlevel(t_forcerec *fr, if (ir->nwall) { /* foreign lambda component for walls */ - real dvdl_walls = do_walls(*ir, *fr, box, *md, x, - &forceWithVirial, lambda[efptVDW], + real dvdl_walls = do_walls(*ir, *fr, box, *md, x, &forceWithVirial, lambda[efptVDW], enerd->grpp.ener[egLJSR].data(), nrnb); enerd->dvdl_lin[efptVDW] += dvdl_walls; } @@ -160,7 +158,7 @@ do_force_lowlevel(t_forcerec *fr, shift_self(graph, box, x); if (TRICLINIC(box)) { - inc_nrnb(nrnb, eNR_SHIFTX, 2*graph->nnodes); + inc_nrnb(nrnb, eNR_SHIFTX, 2 * graph->nnodes); } else { @@ -169,48 +167,42 @@ do_force_lowlevel(t_forcerec *fr, } { - t_pbc pbc; + t_pbc pbc; /* Check whether we need to take into account PBC in listed interactions. */ - const auto needPbcForListedForces = fr->bMolPBC && stepWork.computeListedForces && haveCpuListedForces(*fr, *idef, *fcd); + const auto needPbcForListedForces = + fr->bMolPBC && stepWork.computeListedForces && haveCpuListedForces(*fr, *idef, *fcd); if (needPbcForListedForces) { /* Since all atoms are in the rectangular or triclinic unit-cell, * only single box vector shifts (2 in x) are required. */ - set_pbc_dd(&pbc, fr->ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : nullptr, - TRUE, box); + set_pbc_dd(&pbc, fr->ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : nullptr, TRUE, box); } - do_force_listed(wcycle, box, ir->fepvals, cr, ms, - idef, x, hist, - forceOutputs, - fr, &pbc, graph, enerd, nrnb, lambda, md, fcd, - DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr, - stepWork); + do_force_listed(wcycle, box, ir->fepvals, cr, ms, idef, x, hist, forceOutputs, fr, &pbc, + graph, enerd, nrnb, lambda, md, fcd, + DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr, stepWork); } - const bool computePmeOnCpu = - (EEL_PME(fr->ic->eeltype) || EVDW_PME(fr->ic->vdwtype)) && - thisRankHasDuty(cr, DUTY_PME) && - (pme_run_mode(fr->pmedata) == PmeRunMode::CPU); + const bool computePmeOnCpu = (EEL_PME(fr->ic->eeltype) || EVDW_PME(fr->ic->vdwtype)) + && thisRankHasDuty(cr, DUTY_PME) + && (pme_run_mode(fr->pmedata) == PmeRunMode::CPU); const bool haveEwaldSurfaceTerm = haveEwaldSurfaceContribution(*ir); /* Do long-range electrostatics and/or LJ-PME * and compute PME surface terms when necessary. */ - if (computePmeOnCpu || - fr->ic->eeltype == eelEWALD || - haveEwaldSurfaceTerm) + if (computePmeOnCpu || fr->ic->eeltype == eelEWALD || haveEwaldSurfaceTerm) { - int status = 0; - real Vlr_q = 0, Vlr_lj = 0; + int status = 0; + real Vlr_q = 0, Vlr_lj = 0; /* We reduce all virial, dV/dlambda and energy contributions, except * for the reciprocal energies (Vlr_q, Vlr_lj) into the same struct. */ - ewald_corr_thread_t &ewaldOutput = fr->ewc_t[0]; + ewald_corr_thread_t& ewaldOutput = fr->ewc_t[0]; clearEwaldThreadOutput(&ewaldOutput); if (EEL_PME_EWALD(fr->ic->eeltype) || EVDW_PME(fr->ic->vdwtype)) @@ -222,7 +214,9 @@ do_force_lowlevel(t_forcerec *fr, if (fr->n_tpi > 0) { - gmx_fatal(FARGS, "TPI with PME currently only works in a 3D geometry with tin-foil boundary conditions"); + gmx_fatal(FARGS, + "TPI with PME currently only works in a 3D geometry with tin-foil " + "boundary conditions"); } int nthreads = fr->nthread_ewc; @@ -231,7 +225,7 @@ do_force_lowlevel(t_forcerec *fr, { try { - ewald_corr_thread_t &ewc_t = fr->ewc_t[t]; + ewald_corr_thread_t& ewc_t = fr->ewc_t[t]; if (t > 0) { clearEwaldThreadOutput(&ewc_t); @@ -242,16 +236,12 @@ do_force_lowlevel(t_forcerec *fr, * exclusion forces) are calculated, so we can store * the forces in the normal, single forceWithVirial->force_ array. */ - ewald_LRcorrection(md->homenr, cr, nthreads, t, *fr, *ir, - md->chargeA, md->chargeB, - (md->nChargePerturbed != 0), - x, box, mu_tot, + ewald_LRcorrection(md->homenr, cr, nthreads, t, *fr, *ir, md->chargeA, + md->chargeB, (md->nChargePerturbed != 0), x, box, mu_tot, as_rvec_array(forceWithVirial.force_.data()), - &ewc_t.Vcorr_q, - lambda[efptCOUL], - &ewc_t.dvdl[efptCOUL]); + &ewc_t.Vcorr_q, lambda[efptCOUL], &ewc_t.dvdl[efptCOUL]); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (nthreads > 1) { @@ -264,10 +254,8 @@ do_force_lowlevel(t_forcerec *fr, { /* This is not in a subcounter because it takes a negligible and constant-sized amount of time */ - ewaldOutput.Vcorr_q += - ewald_charge_correction(cr, fr, lambda[efptCOUL], box, - &ewaldOutput.dvdl[efptCOUL], - ewaldOutput.vir_q); + ewaldOutput.Vcorr_q += ewald_charge_correction( + cr, fr, lambda[efptCOUL], box, &ewaldOutput.dvdl[efptCOUL], ewaldOutput.vir_q); } if (computePmeOnCpu) @@ -299,22 +287,17 @@ do_force_lowlevel(t_forcerec *fr, ddBalanceRegionHandler.closeAfterForceComputationCpu(); wallcycle_start(wcycle, ewcPMEMESH); - status = gmx_pme_do(fr->pmedata, - gmx::constArrayRefFromArray(coordinates.unpaddedConstArrayRef().data(), md->homenr - fr->n_tpi), - forceWithVirial.force_, - md->chargeA, md->chargeB, - md->sqrt_c6A, md->sqrt_c6B, - md->sigmaA, md->sigmaB, - box, cr, - DOMAINDECOMP(cr) ? dd_pme_maxshift_x(cr->dd) : 0, - DOMAINDECOMP(cr) ? dd_pme_maxshift_y(cr->dd) : 0, - nrnb, wcycle, - ewaldOutput.vir_q, ewaldOutput.vir_lj, - &Vlr_q, &Vlr_lj, - lambda[efptCOUL], lambda[efptVDW], - &ewaldOutput.dvdl[efptCOUL], - &ewaldOutput.dvdl[efptVDW], - pme_flags); + status = gmx_pme_do( + fr->pmedata, + gmx::constArrayRefFromArray(coordinates.unpaddedConstArrayRef().data(), + md->homenr - fr->n_tpi), + forceWithVirial.force_, md->chargeA, md->chargeB, md->sqrt_c6A, + md->sqrt_c6B, md->sigmaA, md->sigmaB, box, cr, + DOMAINDECOMP(cr) ? dd_pme_maxshift_x(cr->dd) : 0, + DOMAINDECOMP(cr) ? dd_pme_maxshift_y(cr->dd) : 0, nrnb, wcycle, + ewaldOutput.vir_q, ewaldOutput.vir_lj, &Vlr_q, &Vlr_lj, + lambda[efptCOUL], lambda[efptVDW], &ewaldOutput.dvdl[efptCOUL], + &ewaldOutput.dvdl[efptVDW], pme_flags); wallcycle_stop(wcycle, ewcPMEMESH); if (status != 0) { @@ -339,22 +322,20 @@ do_force_lowlevel(t_forcerec *fr, /* Determine the PME grid energy of the test molecule * with the PME grid potential of the other charges. */ - gmx_pme_calc_energy(fr->pmedata, - coordinates.unpaddedConstArrayRef().subArray(md->homenr - fr->n_tpi, fr->n_tpi), - gmx::arrayRefFromArray(md->chargeA + md->homenr - fr->n_tpi, fr->n_tpi), - &Vlr_q); + gmx_pme_calc_energy( + fr->pmedata, + coordinates.unpaddedConstArrayRef().subArray(md->homenr - fr->n_tpi, fr->n_tpi), + gmx::arrayRefFromArray(md->chargeA + md->homenr - fr->n_tpi, fr->n_tpi), + &Vlr_q); } } } if (fr->ic->eeltype == eelEWALD) { - Vlr_q = do_ewald(ir, x, as_rvec_array(forceWithVirial.force_.data()), - md->chargeA, md->chargeB, - box, cr, md->homenr, - ewaldOutput.vir_q, fr->ic->ewaldcoeff_q, - lambda[efptCOUL], &ewaldOutput.dvdl[efptCOUL], - fr->ewald_table); + Vlr_q = do_ewald(ir, x, as_rvec_array(forceWithVirial.force_.data()), md->chargeA, + md->chargeB, box, cr, md->homenr, ewaldOutput.vir_q, fr->ic->ewaldcoeff_q, + lambda[efptCOUL], &ewaldOutput.dvdl[efptCOUL], fr->ewald_table); } /* Note that with separate PME nodes we get the real energies later */ @@ -363,19 +344,19 @@ do_force_lowlevel(t_forcerec *fr, forceWithVirial.addVirialContribution(ewaldOutput.vir_q); forceWithVirial.addVirialContribution(ewaldOutput.vir_lj); enerd->dvdl_lin[efptCOUL] += ewaldOutput.dvdl[efptCOUL]; - enerd->dvdl_lin[efptVDW] += ewaldOutput.dvdl[efptVDW]; - enerd->term[F_COUL_RECIP] = Vlr_q + ewaldOutput.Vcorr_q; - enerd->term[F_LJ_RECIP] = Vlr_lj + ewaldOutput.Vcorr_lj; + enerd->dvdl_lin[efptVDW] += ewaldOutput.dvdl[efptVDW]; + enerd->term[F_COUL_RECIP] = Vlr_q + ewaldOutput.Vcorr_q; + enerd->term[F_LJ_RECIP] = Vlr_lj + ewaldOutput.Vcorr_lj; if (debug) { - fprintf(debug, "Vlr_q = %g, Vcorr_q = %g, Vlr_corr_q = %g\n", - Vlr_q, ewaldOutput.Vcorr_q, enerd->term[F_COUL_RECIP]); + fprintf(debug, "Vlr_q = %g, Vcorr_q = %g, Vlr_corr_q = %g\n", Vlr_q, + ewaldOutput.Vcorr_q, enerd->term[F_COUL_RECIP]); pr_rvecs(debug, 0, "vir_el_recip after corr", ewaldOutput.vir_q, DIM); - rvec *fshift = as_rvec_array(forceOutputs->forceWithShiftForces().shiftForces().data()); + rvec* fshift = as_rvec_array(forceOutputs->forceWithShiftForces().shiftForces().data()); pr_rvecs(debug, 0, "fshift after LR Corrections", fshift, SHIFTS); - fprintf(debug, "Vlr_lj: %g, Vcorr_lj = %g, Vlr_corr_lj = %g\n", - Vlr_lj, ewaldOutput.Vcorr_lj, enerd->term[F_LJ_RECIP]); + fprintf(debug, "Vlr_lj: %g, Vcorr_lj = %g, Vlr_corr_lj = %g\n", Vlr_lj, + ewaldOutput.Vcorr_lj, enerd->term[F_LJ_RECIP]); pr_rvecs(debug, 0, "vir_lj_recip after corr", ewaldOutput.vir_lj, DIM); } } @@ -387,8 +368,7 @@ do_force_lowlevel(t_forcerec *fr, if (debug) { - rvec *fshift = as_rvec_array(forceOutputs->forceWithShiftForces().shiftForces().data()); + rvec* fshift = as_rvec_array(forceOutputs->forceWithShiftForces().shiftForces().data()); pr_rvecs(debug, 0, "fshift after bondeds", fshift, SHIFTS); } - } diff --git a/src/gromacs/mdlib/force.h b/src/gromacs/mdlib/force.h index cc28a00939..c08e113b2d 100644 --- a/src/gromacs/mdlib/force.h +++ b/src/gromacs/mdlib/force.h @@ -71,38 +71,38 @@ class ImdSession; class MdrunScheduleWorkload; class MDLogger; class StepWorkload; -} +} // namespace gmx -void do_force(FILE *log, - const t_commrec *cr, - const gmx_multisim_t *ms, - const t_inputrec *inputrec, - gmx::Awh *awh, - gmx_enfrot *enforcedRotation, - gmx::ImdSession *imdSession, - pull_t *pull_work, - int64_t step, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - const gmx_localtop_t *top, - const matrix box, - gmx::ArrayRefWithPadding coordinates, - history_t *hist, - gmx::ArrayRefWithPadding force, - tensor vir_force, - const t_mdatoms *mdatoms, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - gmx::ArrayRef lambda, - t_graph *graph, - t_forcerec *fr, - gmx::MdrunScheduleWorkload *runScheduleWork, - const gmx_vsite_t *vsite, - rvec mu_tot, - double t, - gmx_edsam *ed, - int legacyFlags, - const DDBalanceRegionHandler &ddBalanceRegionHandler); +void do_force(FILE* log, + const t_commrec* cr, + const gmx_multisim_t* ms, + const t_inputrec* inputrec, + gmx::Awh* awh, + gmx_enfrot* enforcedRotation, + gmx::ImdSession* imdSession, + pull_t* pull_work, + int64_t step, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + const gmx_localtop_t* top, + const matrix box, + gmx::ArrayRefWithPadding coordinates, + history_t* hist, + gmx::ArrayRefWithPadding force, + tensor vir_force, + const t_mdatoms* mdatoms, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + gmx::ArrayRef lambda, + t_graph* graph, + t_forcerec* fr, + gmx::MdrunScheduleWorkload* runScheduleWork, + const gmx_vsite_t* vsite, + rvec mu_tot, + double t, + gmx_edsam* ed, + int legacyFlags, + const DDBalanceRegionHandler& ddBalanceRegionHandler); /* Communicate coordinates (if parallel). * Do neighbor searching (if necessary). @@ -114,26 +114,25 @@ void do_force(FILE *log, */ -void -do_force_lowlevel(t_forcerec *fr, - const t_inputrec *ir, - const t_idef *idef, - const t_commrec *cr, - const gmx_multisim_t *ms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - const t_mdatoms *md, - gmx::ArrayRefWithPadding coordinates, - history_t *hist, - gmx::ForceOutputs *forceOutputs, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - const matrix box, - const real *lambda, - const t_graph *graph, - const rvec *mu_tot, - const gmx::StepWorkload &stepWork, - const DDBalanceRegionHandler &ddBalanceRegionHandler); +void do_force_lowlevel(t_forcerec* fr, + const t_inputrec* ir, + const t_idef* idef, + const t_commrec* cr, + const gmx_multisim_t* ms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + const t_mdatoms* md, + gmx::ArrayRefWithPadding coordinates, + history_t* hist, + gmx::ForceOutputs* forceOutputs, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + const matrix box, + const real* lambda, + const t_graph* graph, + const rvec* mu_tot, + const gmx::StepWorkload& stepWork, + const DDBalanceRegionHandler& ddBalanceRegionHandler); /* Call all the force routines */ #endif diff --git a/src/gromacs/mdlib/force_flags.h b/src/gromacs/mdlib/force_flags.h index 4b97cca517..10f3969aaf 100644 --- a/src/gromacs/mdlib/force_flags.h +++ b/src/gromacs/mdlib/force_flags.h @@ -40,25 +40,25 @@ /* Flags to tell the force calculation routines what (not) to do */ /* The state has changed, always set unless TPI is used. */ -#define GMX_FORCE_STATECHANGED (1u<<0u) +#define GMX_FORCE_STATECHANGED (1u << 0u) /* The box might have changed */ -#define GMX_FORCE_DYNAMICBOX (1u<<1u) +#define GMX_FORCE_DYNAMICBOX (1u << 1u) /* Do neighbor searching */ -#define GMX_FORCE_NS (1u<<2u) +#define GMX_FORCE_NS (1u << 2u) /* Calculate listed energies/forces (e.g. bonds, restraints, 1-4, FEP non-bonded) */ -#define GMX_FORCE_LISTED (1u<<4u) +#define GMX_FORCE_LISTED (1u << 4u) /* Calculate non-bonded energies/forces */ -#define GMX_FORCE_NONBONDED (1u<<6u) +#define GMX_FORCE_NONBONDED (1u << 6u) /* Calculate forces (not only energies) */ -#define GMX_FORCE_FORCES (1u<<7u) +#define GMX_FORCE_FORCES (1u << 7u) /* Calculate the virial */ -#define GMX_FORCE_VIRIAL (1u<<8u) +#define GMX_FORCE_VIRIAL (1u << 8u) /* Calculate energies */ -#define GMX_FORCE_ENERGY (1u<<9u) +#define GMX_FORCE_ENERGY (1u << 9u) /* Calculate dHdl */ -#define GMX_FORCE_DHDL (1u<<10u) +#define GMX_FORCE_DHDL (1u << 10u) /* Normally one want all energy terms and forces */ -#define GMX_FORCE_ALLFORCES (GMX_FORCE_LISTED | GMX_FORCE_NONBONDED | GMX_FORCE_FORCES) +#define GMX_FORCE_ALLFORCES (GMX_FORCE_LISTED | GMX_FORCE_NONBONDED | GMX_FORCE_FORCES) #endif diff --git a/src/gromacs/mdlib/forcerec.cpp b/src/gromacs/mdlib/forcerec.cpp index 4372c3544f..b702a4a255 100644 --- a/src/gromacs/mdlib/forcerec.cpp +++ b/src/gromacs/mdlib/forcerec.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -99,18 +99,18 @@ #include "gromacs/utility/strconvert.h" /*! \brief environment variable to enable GPU P2P communication */ -static const bool c_enableGpuPmePpComms = (getenv("GMX_GPU_PME_PP_COMMS") != nullptr) - && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA); +static const bool c_enableGpuPmePpComms = + (getenv("GMX_GPU_PME_PP_COMMS") != nullptr) && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA); -static real *mk_nbfp(const gmx_ffparams_t *idef, gmx_bool bBHAM) +static real* mk_nbfp(const gmx_ffparams_t* idef, gmx_bool bBHAM) { - real *nbfp; + real* nbfp; int i, j, k, atnr; atnr = idef->atnr; if (bBHAM) { - snew(nbfp, 3*atnr*atnr); + snew(nbfp, 3 * atnr * atnr); for (i = k = 0; (i < atnr); i++) { for (j = 0; (j < atnr); j++, k++) @@ -118,20 +118,20 @@ static real *mk_nbfp(const gmx_ffparams_t *idef, gmx_bool bBHAM) BHAMA(nbfp, atnr, i, j) = idef->iparams[k].bham.a; BHAMB(nbfp, atnr, i, j) = idef->iparams[k].bham.b; /* nbfp now includes the 6.0 derivative prefactor */ - BHAMC(nbfp, atnr, i, j) = idef->iparams[k].bham.c*6.0; + BHAMC(nbfp, atnr, i, j) = idef->iparams[k].bham.c * 6.0; } } } else { - snew(nbfp, 2*atnr*atnr); + snew(nbfp, 2 * atnr * atnr); for (i = k = 0; (i < atnr); i++) { for (j = 0; (j < atnr); j++, k++) { /* nbfp now includes the 6.0/12.0 derivative prefactors */ - C6(nbfp, atnr, i, j) = idef->iparams[k].lj.c6*6.0; - C12(nbfp, atnr, i, j) = idef->iparams[k].lj.c12*12.0; + C6(nbfp, atnr, i, j) = idef->iparams[k].lj.c6 * 6.0; + C12(nbfp, atnr, i, j) = idef->iparams[k].lj.c12 * 12.0; } } } @@ -139,11 +139,11 @@ static real *mk_nbfp(const gmx_ffparams_t *idef, gmx_bool bBHAM) return nbfp; } -static real *make_ljpme_c6grid(const gmx_ffparams_t *idef, t_forcerec *fr) +static real* make_ljpme_c6grid(const gmx_ffparams_t* idef, t_forcerec* fr) { - int i, j, k, atnr; - real c6, c6i, c6j, c12i, c12j, epsi, epsj, sigmai, sigmaj; - real *grid; + int i, j, k, atnr; + real c6, c6i, c6j, c12i, c12j, epsi, epsj, sigmai, sigmaj; + real* grid; /* For LJ-PME simulations, we correct the energies with the reciprocal space * inside of the cut-off. To do this the non-bonded kernels needs to have @@ -151,46 +151,47 @@ static real *make_ljpme_c6grid(const gmx_ffparams_t *idef, t_forcerec *fr) */ atnr = idef->atnr; - snew(grid, 2*atnr*atnr); + snew(grid, 2 * atnr * atnr); for (i = k = 0; (i < atnr); i++) { for (j = 0; (j < atnr); j++, k++) { - c6i = idef->iparams[i*(atnr+1)].lj.c6; - c12i = idef->iparams[i*(atnr+1)].lj.c12; - c6j = idef->iparams[j*(atnr+1)].lj.c6; - c12j = idef->iparams[j*(atnr+1)].lj.c12; + c6i = idef->iparams[i * (atnr + 1)].lj.c6; + c12i = idef->iparams[i * (atnr + 1)].lj.c12; + c6j = idef->iparams[j * (atnr + 1)].lj.c6; + c12j = idef->iparams[j * (atnr + 1)].lj.c12; c6 = std::sqrt(c6i * c6j); - if (fr->ljpme_combination_rule == eljpmeLB - && !gmx_numzero(c6) && !gmx_numzero(c12i) && !gmx_numzero(c12j)) + if (fr->ljpme_combination_rule == eljpmeLB && !gmx_numzero(c6) && !gmx_numzero(c12i) + && !gmx_numzero(c12j)) { sigmai = gmx::sixthroot(c12i / c6i); sigmaj = gmx::sixthroot(c12j / c6j); epsi = c6i * c6i / c12i; epsj = c6j * c6j / c12j; - c6 = std::sqrt(epsi * epsj) * gmx::power6(0.5*(sigmai+sigmaj)); + c6 = std::sqrt(epsi * epsj) * gmx::power6(0.5 * (sigmai + sigmaj)); } /* Store the elements at the same relative positions as C6 in nbfp in order * to simplify access in the kernels */ - grid[2*(atnr*i+j)] = c6*6.0; + grid[2 * (atnr * i + j)] = c6 * 6.0; } } return grid; } -enum { - acNONE = 0, acCONSTRAINT, acSETTLE +enum +{ + acNONE = 0, + acCONSTRAINT, + acSETTLE }; -static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, - const t_forcerec *fr, - gmx_bool *bFEP_NonBonded) +static cginfo_mb_t* init_cginfo_mb(const gmx_mtop_t* mtop, const t_forcerec* fr, gmx_bool* bFEP_NonBonded) { - cginfo_mb_t *cginfo_mb; - gmx_bool *type_VDW; - int *cginfo; - int *a_con; + cginfo_mb_t* cginfo_mb; + gmx_bool* type_VDW; + int* cginfo; + int* a_con; snew(cginfo_mb, mtop->molblock.size()); @@ -200,21 +201,19 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, type_VDW[ai] = FALSE; for (int j = 0; j < fr->ntype; j++) { - type_VDW[ai] = type_VDW[ai] || - fr->bBHAM || - C6(fr->nbfp, fr->ntype, ai, j) != 0 || - C12(fr->nbfp, fr->ntype, ai, j) != 0; + type_VDW[ai] = type_VDW[ai] || fr->bBHAM || C6(fr->nbfp, fr->ntype, ai, j) != 0 + || C12(fr->nbfp, fr->ntype, ai, j) != 0; } } - *bFEP_NonBonded = FALSE; + *bFEP_NonBonded = FALSE; - int a_offset = 0; + int a_offset = 0; for (size_t mb = 0; mb < mtop->molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop->molblock[mb]; - const gmx_moltype_t &molt = mtop->moltype[molb.type]; - const t_blocka &excl = molt.excls; + const gmx_molblock_t& molb = mtop->molblock[mb]; + const gmx_moltype_t& molt = mtop->moltype[molb.type]; + const t_blocka& excl = molt.excls; /* Check if the cginfo is identical for all molecules in this block. * If so, we only need an array of the size of one molecule. @@ -223,18 +222,18 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, gmx_bool bId = TRUE; for (int m = 0; m < molb.nmol; m++) { - const int am = m*molt.atoms.nr; + const int am = m * molt.atoms.nr; for (int a = 0; a < molt.atoms.nr; a++) { - if (getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset + am + a) != - getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset + a)) + if (getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset + am + a) + != getGroupType(mtop->groups, SimulationAtomGroupType::QuantumMechanics, a_offset + a)) { bId = FALSE; } if (!mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty()) { - if (mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset +am + a] != - mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset + a]) + if (mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset + am + a] + != mtop->groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][a_offset + a]) { bId = FALSE; } @@ -243,8 +242,8 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, } cginfo_mb[mb].cg_start = a_offset; - cginfo_mb[mb].cg_end = a_offset + molb.nmol*molt.atoms.nr; - cginfo_mb[mb].cg_mod = (bId ? 1 : molb.nmol)*molt.atoms.nr; + cginfo_mb[mb].cg_end = a_offset + molb.nmol * molt.atoms.nr; + cginfo_mb[mb].cg_mod = (bId ? 1 : molb.nmol) * molt.atoms.nr; snew(cginfo_mb[mb].cginfo, cginfo_mb[mb].cg_mod); cginfo = cginfo_mb[mb].cginfo; @@ -262,7 +261,7 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, for (a = 0; a < nral; a++) { a_con[molt.ilist[ftype].iatoms[ia + 1 + a]] = - (ftype == F_SETTLE ? acSETTLE : acCONSTRAINT); + (ftype == F_SETTLE ? acSETTLE : acCONSTRAINT); } } } @@ -270,21 +269,19 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, for (int m = 0; m < (bId ? 1 : molb.nmol); m++) { - const int molculeOffsetInBlock = m*molt.atoms.nr; + const int molculeOffsetInBlock = m * molt.atoms.nr; for (int a = 0; a < molt.atoms.nr; a++) { - const t_atom &atom = molt.atoms.atom[a]; - int &atomInfo = cginfo[molculeOffsetInBlock + a]; + const t_atom& atom = molt.atoms.atom[a]; + int& atomInfo = cginfo[molculeOffsetInBlock + a]; /* Store the energy group in cginfo */ int gid = getGroupType(mtop->groups, SimulationAtomGroupType::EnergyOutput, a_offset + molculeOffsetInBlock + a); SET_CGINFO_GID(atomInfo, gid); - bool bHaveVDW = (type_VDW[atom.type] || - type_VDW[atom.typeB]); - bool bHaveQ = (atom.q != 0 || - atom.qB != 0); + bool bHaveVDW = (type_VDW[atom.type] || type_VDW[atom.typeB]); + bool bHaveQ = (atom.q != 0 || atom.qB != 0); bool haveExclusions = false; /* Loop over all the exclusions of atom ai */ @@ -299,14 +296,9 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, switch (a_con[a]) { - case acCONSTRAINT: - SET_CGINFO_CONSTR(atomInfo); - break; - case acSETTLE: - SET_CGINFO_SETTLE(atomInfo); - break; - default: - break; + case acCONSTRAINT: SET_CGINFO_CONSTR(atomInfo); break; + case acSETTLE: SET_CGINFO_SETTLE(atomInfo); break; + default: break; } if (haveExclusions) { @@ -330,35 +322,33 @@ static cginfo_mb_t *init_cginfo_mb(const gmx_mtop_t *mtop, sfree(a_con); - a_offset += molb.nmol*molt.atoms.nr; + a_offset += molb.nmol * molt.atoms.nr; } sfree(type_VDW); return cginfo_mb; } -static std::vector cginfo_expand(const int nmb, - const cginfo_mb_t *cgi_mb) +static std::vector cginfo_expand(const int nmb, const cginfo_mb_t* cgi_mb) { - const int ncg = cgi_mb[nmb - 1].cg_end; + const int ncg = cgi_mb[nmb - 1].cg_end; std::vector cginfo(ncg); - int mb = 0; + int mb = 0; for (int cg = 0; cg < ncg; cg++) { while (cg >= cgi_mb[mb].cg_end) { mb++; } - cginfo[cg] = - cgi_mb[mb].cginfo[(cg - cgi_mb[mb].cg_start) % cgi_mb[mb].cg_mod]; + cginfo[cg] = cgi_mb[mb].cginfo[(cg - cgi_mb[mb].cg_start) % cgi_mb[mb].cg_mod]; } return cginfo; } -static void done_cginfo_mb(cginfo_mb_t *cginfo_mb, int numMolBlocks) +static void done_cginfo_mb(cginfo_mb_t* cginfo_mb, int numMolBlocks) { if (cginfo_mb == nullptr) { @@ -374,58 +364,58 @@ static void done_cginfo_mb(cginfo_mb_t *cginfo_mb, int numMolBlocks) /* Sets the sum of charges (squared) and C6 in the system in fr. * Returns whether the system has a net charge. */ -static bool set_chargesum(FILE *log, t_forcerec *fr, const gmx_mtop_t *mtop) +static bool set_chargesum(FILE* log, t_forcerec* fr, const gmx_mtop_t* mtop) { /*This now calculates sum for q and c6*/ - double qsum, q2sum, q, c6sum, c6; + double qsum, q2sum, q, c6sum, c6; - qsum = 0; - q2sum = 0; - c6sum = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + qsum = 0; + q2sum = 0; + c6sum = 0; + for (const gmx_molblock_t& molb : mtop->molblock) { int nmol = molb.nmol; - const t_atoms *atoms = &mtop->moltype[molb.type].atoms; + const t_atoms* atoms = &mtop->moltype[molb.type].atoms; for (int i = 0; i < atoms->nr; i++) { - q = atoms->atom[i].q; - qsum += nmol*q; - q2sum += nmol*q*q; - c6 = mtop->ffparams.iparams[atoms->atom[i].type*(mtop->ffparams.atnr+1)].lj.c6; - c6sum += nmol*c6; + q = atoms->atom[i].q; + qsum += nmol * q; + q2sum += nmol * q * q; + c6 = mtop->ffparams.iparams[atoms->atom[i].type * (mtop->ffparams.atnr + 1)].lj.c6; + c6sum += nmol * c6; } } - fr->qsum[0] = qsum; - fr->q2sum[0] = q2sum; - fr->c6sum[0] = c6sum; + fr->qsum[0] = qsum; + fr->q2sum[0] = q2sum; + fr->c6sum[0] = c6sum; if (fr->efep != efepNO) { - qsum = 0; - q2sum = 0; - c6sum = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + qsum = 0; + q2sum = 0; + c6sum = 0; + for (const gmx_molblock_t& molb : mtop->molblock) { int nmol = molb.nmol; - const t_atoms *atoms = &mtop->moltype[molb.type].atoms; + const t_atoms* atoms = &mtop->moltype[molb.type].atoms; for (int i = 0; i < atoms->nr; i++) { - q = atoms->atom[i].qB; - qsum += nmol*q; - q2sum += nmol*q*q; - c6 = mtop->ffparams.iparams[atoms->atom[i].typeB*(mtop->ffparams.atnr+1)].lj.c6; - c6sum += nmol*c6; + q = atoms->atom[i].qB; + qsum += nmol * q; + q2sum += nmol * q * q; + c6 = mtop->ffparams.iparams[atoms->atom[i].typeB * (mtop->ffparams.atnr + 1)].lj.c6; + c6sum += nmol * c6; } - fr->qsum[1] = qsum; - fr->q2sum[1] = q2sum; - fr->c6sum[1] = c6sum; + fr->qsum[1] = qsum; + fr->q2sum[1] = q2sum; + fr->c6sum[1] = c6sum; } } else { - fr->qsum[1] = fr->qsum[0]; - fr->q2sum[1] = fr->q2sum[0]; - fr->c6sum[1] = fr->c6sum[0]; + fr->qsum[1] = fr->qsum[0]; + fr->q2sum[1] = fr->q2sum[0]; + fr->c6sum[1] = fr->c6sum[0]; } if (log) { @@ -435,17 +425,15 @@ static bool set_chargesum(FILE *log, t_forcerec *fr, const gmx_mtop_t *mtop) } else { - fprintf(log, "System total charge, top. A: %.3f top. B: %.3f\n", - fr->qsum[0], fr->qsum[1]); + fprintf(log, "System total charge, top. A: %.3f top. B: %.3f\n", fr->qsum[0], fr->qsum[1]); } } /* A cut-off of 1e-4 is used to catch rounding errors due to ascii input */ - return (std::abs(fr->qsum[0]) > 1e-4 || - std::abs(fr->qsum[1]) > 1e-4); + return (std::abs(fr->qsum[0]) > 1e-4 || std::abs(fr->qsum[1]) > 1e-4); } -static real calcBuckinghamBMax(FILE *fplog, const gmx_mtop_t *mtop) +static real calcBuckinghamBMax(FILE* fplog, const gmx_mtop_t* mtop) { const t_atoms *at1, *at2; int i, j, tpi, tpj, ntypes; @@ -480,7 +468,7 @@ static real calcBuckinghamBMax(FILE *fplog, const gmx_mtop_t *mtop) { gmx_fatal(FARGS, "Atomtype[%d] = %d, maximum = %d", j, tpj, ntypes); } - b = mtop->ffparams.iparams[tpi*ntypes + tpj].bham.b; + b = mtop->ffparams.iparams[tpi * ntypes + tpj].bham.b; if (b > bham_b_max) { bham_b_max = b; @@ -495,8 +483,7 @@ static real calcBuckinghamBMax(FILE *fplog, const gmx_mtop_t *mtop) } if (fplog) { - fprintf(fplog, "Buckingham b parameters, min: %g, max: %g\n", - bmin, bham_b_max); + fprintf(fplog, "Buckingham b parameters, min: %g, max: %g\n", bmin, bham_b_max); } return bham_b_max; @@ -515,13 +502,12 @@ static real calcBuckinghamBMax(FILE *fplog, const gmx_mtop_t *mtop) * \c ncount. It will contain zero for every bonded interaction index * for which no interactions are present in the topology. */ -static void count_tables(int ftype1, int ftype2, const gmx_mtop_t *mtop, - int *ncount, int **count) +static void count_tables(int ftype1, int ftype2, const gmx_mtop_t* mtop, int* ncount, int** count) { - int ftype, i, j, tabnr; + int ftype, i, j, tabnr; // Loop over all moleculetypes - for (const gmx_moltype_t &molt : mtop->moltype) + for (const gmx_moltype_t& molt : mtop->moltype) { // Loop over all interaction types for (ftype = 0; ftype < F_NRE; ftype++) @@ -529,7 +515,7 @@ static void count_tables(int ftype1, int ftype2, const gmx_mtop_t *mtop, // If the current interaction type is one of the types whose tables we're trying to count... if (ftype == ftype1 || ftype == ftype2) { - const InteractionList &il = molt.ilist[ftype]; + const InteractionList& il = molt.ilist[ftype]; const int stride = 1 + NRAL(ftype); // ... and there are actually some interactions for this type for (i = 0; i < il.size(); i += stride) @@ -543,12 +529,12 @@ static void count_tables(int ftype1, int ftype2, const gmx_mtop_t *mtop, // Make room for this index in the data structure if (tabnr >= *ncount) { - srenew(*count, tabnr+1); - for (j = *ncount; j < tabnr+1; j++) + srenew(*count, tabnr + 1); + for (j = *ncount; j < tabnr + 1; j++) { (*count)[j] = 0; } - *ncount = tabnr+1; + *ncount = tabnr + 1; } // Record that this table index is used and must have a valid file (*count)[tabnr]++; @@ -568,14 +554,15 @@ static void count_tables(int ftype1, int ftype2, const gmx_mtop_t *mtop, * * A fatal error occurs if no matching filename is found. */ -static bondedtable_t *make_bonded_tables(FILE *fplog, - int ftype1, int ftype2, - const gmx_mtop_t *mtop, +static bondedtable_t* make_bonded_tables(FILE* fplog, + int ftype1, + int ftype2, + const gmx_mtop_t* mtop, gmx::ArrayRef tabbfnm, - const char *tabext) + const char* tabext) { int ncount, *count; - bondedtable_t *tab; + bondedtable_t* tab; tab = nullptr; @@ -603,18 +590,19 @@ static bondedtable_t *make_bonded_tables(FILE *fplog, if (gmx::endsWith(tabbfnm[j], patternToFind)) { // Finally read the table from the file found - tab[i] = make_bonded_table(fplog, tabbfnm[j].c_str(), NRAL(ftype1)-2); + tab[i] = make_bonded_table(fplog, tabbfnm[j].c_str(), NRAL(ftype1) - 2); madeTable = true; } } if (!madeTable) { bool isPlural = (ftype2 != -1); - gmx_fatal(FARGS, "Tabulated interaction of type '%s%s%s' with index %d cannot be used because no table file whose name matched '%s' was passed via the gmx mdrun -tableb command-line option.", - interaction_function[ftype1].longname, - isPlural ? "' or '" : "", - isPlural ? interaction_function[ftype2].longname : "", - i, + gmx_fatal(FARGS, + "Tabulated interaction of type '%s%s%s' with index %d cannot be used " + "because no table file whose name matched '%s' was passed via the " + "gmx mdrun -tableb command-line option.", + interaction_function[ftype1].longname, isPlural ? "' or '" : "", + isPlural ? interaction_function[ftype2].longname : "", i, patternToFind.c_str()); } } @@ -625,9 +613,7 @@ static bondedtable_t *make_bonded_tables(FILE *fplog, return tab; } -void forcerec_set_ranges(t_forcerec *fr, - int natoms_force, - int natoms_force_constr, int natoms_f_novirsum) +void forcerec_set_ranges(t_forcerec* fr, int natoms_force, int natoms_force_constr, int natoms_f_novirsum) { fr->natoms_force = natoms_force; fr->natoms_force_constr = natoms_force_constr; @@ -654,9 +640,10 @@ static real cutoff_inf(real cutoff) } /*! \brief Print Coulomb Ewald citations and set ewald coefficients */ -static void initCoulombEwaldParameters(FILE *fp, const t_inputrec *ir, - bool systemHasNetCharge, - interaction_const_t *ic) +static void initCoulombEwaldParameters(FILE* fp, + const t_inputrec* ir, + bool systemHasNetCharge, + interaction_const_t* ic) { if (!EEL_PME_EWALD(ir->coulombtype)) { @@ -695,14 +682,13 @@ static void initCoulombEwaldParameters(FILE *fp, const t_inputrec *ir, ic->ewaldcoeff_q = calc_ewaldcoeff_q(ir->rcoulomb, ir->ewald_rtol); if (fp) { - fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for Ewald\n", - 1/ic->ewaldcoeff_q); + fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for Ewald\n", 1 / ic->ewaldcoeff_q); } if (ic->coulomb_modifier == eintmodPOTSHIFT) { GMX_RELEASE_ASSERT(ic->rcoulomb != 0, "Cutoff radius cannot be zero"); - ic->sh_ewald = std::erfc(ic->ewaldcoeff_q*ic->rcoulomb) / ic->rcoulomb; + ic->sh_ewald = std::erfc(ic->ewaldcoeff_q * ic->rcoulomb) / ic->rcoulomb; } else { @@ -711,8 +697,7 @@ static void initCoulombEwaldParameters(FILE *fp, const t_inputrec *ir, } /*! \brief Print Van der Waals Ewald citations and set ewald coefficients */ -static void initVdwEwaldParameters(FILE *fp, const t_inputrec *ir, - interaction_const_t *ic) +static void initVdwEwaldParameters(FILE* fp, const t_inputrec* ir, interaction_const_t* ic) { if (!EVDW_PME(ir->vdwtype)) { @@ -727,14 +712,13 @@ static void initVdwEwaldParameters(FILE *fp, const t_inputrec *ir, ic->ewaldcoeff_lj = calc_ewaldcoeff_lj(ir->rvdw, ir->ewald_rtol_lj); if (fp) { - fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for LJ Ewald\n", - 1/ic->ewaldcoeff_lj); + fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for LJ Ewald\n", 1 / ic->ewaldcoeff_lj); } if (ic->vdw_modifier == eintmodPOTSHIFT) { - real crc2 = gmx::square(ic->ewaldcoeff_lj*ic->rvdw); - ic->sh_lj_ewald = (std::exp(-crc2)*(1 + crc2 + 0.5*crc2*crc2) - 1)/gmx::power6(ic->rvdw); + real crc2 = gmx::square(ic->ewaldcoeff_lj * ic->rvdw); + ic->sh_lj_ewald = (std::exp(-crc2) * (1 + crc2 + 0.5 * crc2 * crc2) - 1) / gmx::power6(ic->rvdw); } else { @@ -748,9 +732,9 @@ static void initVdwEwaldParameters(FILE *fp, const t_inputrec *ir, * are non-null. The spacing for both table sets is the same and obeys * both accuracy requirements, when relevant. */ -static void init_ewald_f_table(const interaction_const_t &ic, - EwaldCorrectionTables *coulombTables, - EwaldCorrectionTables *vdwTables) +static void init_ewald_f_table(const interaction_const_t& ic, + EwaldCorrectionTables* coulombTables, + EwaldCorrectionTables* vdwTables) { const bool useCoulombTable = (EEL_PME_EWALD(ic.eeltype) && coulombTables != nullptr); const bool useVdwTable = (EVDW_PME(ic.vdwtype) && vdwTables != nullptr); @@ -760,11 +744,12 @@ static void init_ewald_f_table(const interaction_const_t &ic, */ const real tableScale = ewald_spline3_table_scale(ic, useCoulombTable, useVdwTable); - const int tableSize = static_cast(ic.rcoulomb*tableScale) + 2; + const int tableSize = static_cast(ic.rcoulomb * tableScale) + 2; if (useCoulombTable) { - *coulombTables = generateEwaldCorrectionTables(tableSize, tableScale, ic.ewaldcoeff_q, v_q_ewald_lr); + *coulombTables = + generateEwaldCorrectionTables(tableSize, tableScale, ic.ewaldcoeff_q, v_q_ewald_lr); } if (useVdwTable) @@ -773,8 +758,7 @@ static void init_ewald_f_table(const interaction_const_t &ic, } } -void init_interaction_const_tables(FILE *fp, - interaction_const_t *ic) +void init_interaction_const_tables(FILE* fp, interaction_const_t* ic) { if (EEL_PME_EWALD(ic->eeltype)) { @@ -782,21 +766,19 @@ void init_interaction_const_tables(FILE *fp, if (fp != nullptr) { fprintf(fp, "Initialized non-bonded Coulomb Ewald tables, spacing: %.2e size: %zu\n\n", - 1/ic->coulombEwaldTables->scale, ic->coulombEwaldTables->tableF.size()); + 1 / ic->coulombEwaldTables->scale, ic->coulombEwaldTables->tableF.size()); } } } -static void clear_force_switch_constants(shift_consts_t *sc) +static void clear_force_switch_constants(shift_consts_t* sc) { sc->c2 = 0; sc->c3 = 0; sc->cpot = 0; } -static void force_switch_constants(real p, - real rsw, real rc, - shift_consts_t *sc) +static void force_switch_constants(real p, real rsw, real rc, shift_consts_t* sc) { /* Here we determine the coefficient for shifting the force to zero * between distance rsw and the cut-off rc. @@ -806,13 +788,13 @@ static void force_switch_constants(real p, * force/p = r^-(p+1) + c2*r^2 + c3*r^3 * potential = r^-p + c2/3*r^3 + c3/4*r^4 + cpot */ - sc->c2 = ((p + 1)*rsw - (p + 4)*rc)/(pow(rc, p + 2)*gmx::square(rc - rsw)); - sc->c3 = -((p + 1)*rsw - (p + 3)*rc)/(pow(rc, p + 2)*gmx::power3(rc - rsw)); - sc->cpot = -pow(rc, -p) + p*sc->c2/3*gmx::power3(rc - rsw) + p*sc->c3/4*gmx::power4(rc - rsw); + sc->c2 = ((p + 1) * rsw - (p + 4) * rc) / (pow(rc, p + 2) * gmx::square(rc - rsw)); + sc->c3 = -((p + 1) * rsw - (p + 3) * rc) / (pow(rc, p + 2) * gmx::power3(rc - rsw)); + sc->cpot = -pow(rc, -p) + p * sc->c2 / 3 * gmx::power3(rc - rsw) + + p * sc->c3 / 4 * gmx::power4(rc - rsw); } -static void potential_switch_constants(real rsw, real rc, - switch_consts_t *sc) +static void potential_switch_constants(real rsw, real rc, switch_consts_t* sc) { /* The switch function is 1 at rsw and 0 at rc. * The derivative and second derivate are zero at both ends. @@ -822,9 +804,9 @@ static void potential_switch_constants(real rsw, real rc, * force = force*dsw - potential*sw * potential *= sw */ - sc->c3 = -10/gmx::power3(rc - rsw); - sc->c4 = 15/gmx::power4(rc - rsw); - sc->c5 = -6/gmx::power5(rc - rsw); + sc->c3 = -10 / gmx::power3(rc - rsw); + sc->c4 = 15 / gmx::power4(rc - rsw); + sc->c5 = -6 / gmx::power5(rc - rsw); } /*! \brief Construct interaction constants @@ -833,16 +815,15 @@ static void potential_switch_constants(real rsw, real rc, * short-range interactions. Many of these are constant for the whole * simulation; some are constant only after PME tuning completes. */ -static void -init_interaction_const(FILE *fp, - interaction_const_t **interaction_const, - const t_inputrec *ir, - const gmx_mtop_t *mtop, - bool systemHasNetCharge) +static void init_interaction_const(FILE* fp, + interaction_const_t** interaction_const, + const t_inputrec* ir, + const gmx_mtop_t* mtop, + bool systemHasNetCharge) { - interaction_const_t *ic = new interaction_const_t; + interaction_const_t* ic = new interaction_const_t; - ic->cutoff_scheme = ir->cutoff_scheme; + ic->cutoff_scheme = ir->cutoff_scheme; ic->coulombEwaldTables = std::make_unique(); @@ -868,27 +849,23 @@ init_interaction_const(FILE *fp, { case eintmodPOTSHIFT: /* Only shift the potential, don't touch the force */ - ic->dispersion_shift.cpot = -1.0/gmx::power6(ic->rvdw); - ic->repulsion_shift.cpot = -1.0/gmx::power12(ic->rvdw); + ic->dispersion_shift.cpot = -1.0 / gmx::power6(ic->rvdw); + ic->repulsion_shift.cpot = -1.0 / gmx::power12(ic->rvdw); break; case eintmodFORCESWITCH: /* Switch the force, switch and shift the potential */ - force_switch_constants(6.0, ic->rvdw_switch, ic->rvdw, - &ic->dispersion_shift); - force_switch_constants(12.0, ic->rvdw_switch, ic->rvdw, - &ic->repulsion_shift); + force_switch_constants(6.0, ic->rvdw_switch, ic->rvdw, &ic->dispersion_shift); + force_switch_constants(12.0, ic->rvdw_switch, ic->rvdw, &ic->repulsion_shift); break; case eintmodPOTSWITCH: /* Switch the potential and force */ - potential_switch_constants(ic->rvdw_switch, ic->rvdw, - &ic->vdw_switch); + potential_switch_constants(ic->rvdw_switch, ic->rvdw, &ic->vdw_switch); break; case eintmodNONE: case eintmodEXACTCUTOFF: /* Nothing to do here */ break; - default: - gmx_incons("unimplemented potential modifier"); + default: gmx_incons("unimplemented potential modifier"); } /* Electrostatics */ @@ -901,7 +878,7 @@ init_interaction_const(FILE *fp, /* Set the Coulomb energy conversion factor */ if (ic->epsilon_r != 0) { - ic->epsfac = ONE_4PI_EPS0/ic->epsilon_r; + ic->epsfac = ONE_4PI_EPS0 / ic->epsilon_r; } else { @@ -915,9 +892,7 @@ init_interaction_const(FILE *fp, GMX_RELEASE_ASSERT(ic->eeltype != eelGRF_NOTUSED, "GRF is no longer supported"); ic->epsilon_rf = ir->epsilon_rf; - calc_rffac(fp, ic->epsilon_r, ic->epsilon_rf, - ic->rcoulomb, - &ic->k_rf, &ic->c_rf); + calc_rffac(fp, ic->epsilon_r, ic->epsilon_rf, ic->rcoulomb, &ic->k_rf, &ic->c_rf); } else { @@ -926,11 +901,11 @@ init_interaction_const(FILE *fp, ic->k_rf = 0; if (ir->coulomb_modifier == eintmodPOTSHIFT) { - ic->c_rf = 1/ic->rcoulomb; + ic->c_rf = 1 / ic->rcoulomb; } else { - ic->c_rf = 0; + ic->c_rf = 0; } } @@ -945,8 +920,7 @@ init_interaction_const(FILE *fp, { dispersion_shift -= ic->sh_lj_ewald; } - fprintf(fp, "Potential shift: LJ r^-12: %.3e r^-6: %.3e", - ic->repulsion_shift.cpot, dispersion_shift); + fprintf(fp, "Potential shift: LJ r^-12: %.3e r^-6: %.3e", ic->repulsion_shift.cpot, dispersion_shift); if (ic->eeltype == eelCUT) { @@ -962,28 +936,28 @@ init_interaction_const(FILE *fp, *interaction_const = ic; } -void init_forcerec(FILE *fp, - const gmx::MDLogger &mdlog, - t_forcerec *fr, - t_fcdata *fcd, - const t_inputrec *ir, - const gmx_mtop_t *mtop, - const t_commrec *cr, - matrix box, - const char *tabfn, - const char *tabpfn, - gmx::ArrayRef tabbfnm, - const gmx_hw_info_t &hardwareInfo, - const gmx_device_info_t *deviceInfo, - const bool useGpuForBonded, - const bool pmeOnlyRankUsesGpu, - real print_force, - gmx_wallcycle *wcycle) +void init_forcerec(FILE* fp, + const gmx::MDLogger& mdlog, + t_forcerec* fr, + t_fcdata* fcd, + const t_inputrec* ir, + const gmx_mtop_t* mtop, + const t_commrec* cr, + matrix box, + const char* tabfn, + const char* tabpfn, + gmx::ArrayRef tabbfnm, + const gmx_hw_info_t& hardwareInfo, + const gmx_device_info_t* deviceInfo, + const bool useGpuForBonded, + const bool pmeOnlyRankUsesGpu, + real print_force, + gmx_wallcycle* wcycle) { - real rtab; - char *env; - double dbl; - gmx_bool bFEP_NonBonded; + real rtab; + char* env; + double dbl; + gmx_bool bFEP_NonBonded; /* By default we turn SIMD kernels on, but it might be turned off further down... */ fr->use_simd_kernels = TRUE; @@ -998,18 +972,16 @@ void init_forcerec(FILE *fp, { /* Set to the size of the molecule to be inserted (the last one) */ gmx::RangePartitioning molecules = gmx_mtop_molecules(*mtop); - fr->n_tpi = molecules.block(molecules.numBlocks() - 1).size(); + fr->n_tpi = molecules.block(molecules.numBlocks() - 1).size(); } else { fr->n_tpi = 0; } - if (ir->coulombtype == eelRF_NEC_UNSUPPORTED || - ir->coulombtype == eelGRF_NOTUSED) + if (ir->coulombtype == eelRF_NEC_UNSUPPORTED || ir->coulombtype == eelGRF_NOTUSED) { - gmx_fatal(FARGS, "%s electrostatics is no longer supported", - eel_names[ir->coulombtype]); + gmx_fatal(FARGS, "%s electrostatics is no longer supported", eel_names[ir->coulombtype]); } if (ir->bAdress) @@ -1067,12 +1039,14 @@ void init_forcerec(FILE *fp, { /* turn off non-bonded calculations */ fr->bNonbonded = FALSE; - GMX_LOG(mdlog.warning).asParagraph().appendText( - "Found environment variable GMX_NO_NONBONDED.\n" - "Disabling nonbonded calculations."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "Found environment variable GMX_NO_NONBONDED.\n" + "Disabling nonbonded calculations."); } - if ( (getenv("GMX_DISABLE_SIMD_KERNELS") != nullptr) || (getenv("GMX_NOOPTIMIZEDKERNELS") != nullptr) ) + if ((getenv("GMX_DISABLE_SIMD_KERNELS") != nullptr) || (getenv("GMX_NOOPTIMIZEDKERNELS") != nullptr)) { fr->use_simd_kernels = FALSE; if (fp != nullptr) @@ -1098,14 +1072,14 @@ void init_forcerec(FILE *fp, else { const bool useEwaldSurfaceCorrection = - (EEL_PME_EWALD(ir->coulombtype) && ir->epsilon_surface != 0); + (EEL_PME_EWALD(ir->coulombtype) && ir->epsilon_surface != 0); if (!DOMAINDECOMP(cr)) { gmx_bool bSHAKE; - bSHAKE = (ir->eConstrAlg == econtSHAKE && - (gmx_mtop_ftype_count(mtop, F_CONSTR) > 0 || - gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0)); + bSHAKE = (ir->eConstrAlg == econtSHAKE + && (gmx_mtop_ftype_count(mtop, F_CONSTR) > 0 + || gmx_mtop_ftype_count(mtop, F_CONSTRNC) > 0)); /* The group cut-off scheme and SHAKE assume charge groups * are whole, but not using molpbc is faster in most cases. @@ -1134,20 +1108,35 @@ void init_forcerec(FILE *fp, fr->bMolPBC = FALSE; if (fp) { - GMX_LOG(mdlog.warning).asParagraph().appendText("GMX_USE_GRAPH is set, using the graph for bonded interactions"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "GMX_USE_GRAPH is set, using the graph for bonded " + "interactions"); } if (mtop->bIntermolecularInteractions) { - GMX_LOG(mdlog.warning).asParagraph().appendText("WARNING: Molecules linked by intermolecular interactions have to reside in the same periodic image, otherwise artifacts will occur!"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "WARNING: Molecules linked by intermolecular interactions " + "have to reside in the same periodic image, otherwise " + "artifacts will occur!"); } } - GMX_RELEASE_ASSERT(fr->bMolPBC || !mtop->bIntermolecularInteractions, "We need to use PBC within molecules with inter-molecular interactions"); + GMX_RELEASE_ASSERT( + fr->bMolPBC || !mtop->bIntermolecularInteractions, + "We need to use PBC within molecules with inter-molecular interactions"); if (bSHAKE && fr->bMolPBC) { - gmx_fatal(FARGS, "SHAKE is not properly supported with intermolecular interactions. For short simulations where linked molecules remain in the same periodic image, the environment variable GMX_USE_GRAPH can be used to override this check.\n"); + gmx_fatal(FARGS, + "SHAKE is not properly supported with intermolecular interactions. " + "For short simulations where linked molecules remain in the same " + "periodic image, the environment variable GMX_USE_GRAPH can be used " + "to override this check.\n"); } } } @@ -1158,7 +1147,8 @@ void init_forcerec(FILE *fp, if (useEwaldSurfaceCorrection && !dd_moleculesAreAlwaysWhole(*cr->dd)) { gmx_fatal(FARGS, - "You requested dipole correction (epsilon_surface > 0), but molecules are broken " + "You requested dipole correction (epsilon_surface > 0), but molecules " + "are broken " "over periodic boundary conditions by the domain decomposition. " "Run without domain decomposition instead."); } @@ -1166,8 +1156,8 @@ void init_forcerec(FILE *fp, if (useEwaldSurfaceCorrection) { - GMX_RELEASE_ASSERT((!DOMAINDECOMP(cr) && !fr->bMolPBC) || - (DOMAINDECOMP(cr) && dd_moleculesAreAlwaysWhole(*cr->dd)), + GMX_RELEASE_ASSERT((!DOMAINDECOMP(cr) && !fr->bMolPBC) + || (DOMAINDECOMP(cr) && dd_moleculesAreAlwaysWhole(*cr->dd)), "Molecules can not be broken by PBC with epsilon_surface > 0"); } } @@ -1175,8 +1165,8 @@ void init_forcerec(FILE *fp, fr->rc_scaling = ir->refcoord_scaling; copy_rvec(ir->posres_com, fr->posres_com); copy_rvec(ir->posres_comB, fr->posres_comB); - fr->rlist = cutoff_inf(ir->rlist); - fr->ljpme_combination_rule = ir->ljpme_combination_rule; + fr->rlist = cutoff_inf(ir->rlist); + fr->ljpme_combination_rule = ir->ljpme_combination_rule; /* This now calculates sum for q and c6*/ bool systemHasNetCharge = set_chargesum(fp, fr, mtop); @@ -1185,7 +1175,7 @@ void init_forcerec(FILE *fp, init_interaction_const(fp, &fr->ic, ir, mtop, systemHasNetCharge); init_interaction_const_tables(fp, fr->ic); - const interaction_const_t *ic = fr->ic; + const interaction_const_t* ic = fr->ic; /* TODO: Replace this Ewald table or move it into interaction_const_t */ if (ir->coulombtype == eelEWALD) @@ -1196,14 +1186,10 @@ void init_forcerec(FILE *fp, /* Electrostatics: Translate from interaction-setting-in-mdp-file to kernel interaction format */ switch (ic->eeltype) { - case eelCUT: - fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_COULOMB; - break; + case eelCUT: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_COULOMB; break; case eelRF: - case eelRF_ZERO: - fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_REACTIONFIELD; - break; + case eelRF_ZERO: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_REACTIONFIELD; break; case eelSWITCH: case eelSHIFT: @@ -1217,9 +1203,7 @@ void init_forcerec(FILE *fp, case eelPME: case eelP3M_AD: - case eelEWALD: - fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_EWALD; - break; + case eelEWALD: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_EWALD; break; default: gmx_fatal(FARGS, "Unsupported electrostatic interaction: %s", eel_names[ic->eeltype]); @@ -1239,9 +1223,7 @@ void init_forcerec(FILE *fp, fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_LENNARDJONES; } break; - case evdwPME: - fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_LJEWALD; - break; + case evdwPME: fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_LJEWALD; break; case evdwSWITCH: case evdwSHIFT: @@ -1250,16 +1232,16 @@ void init_forcerec(FILE *fp, fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_CUBICSPLINETABLE; break; - default: - gmx_fatal(FARGS, "Unsupported vdw interaction: %s", evdw_names[ic->vdwtype]); + default: gmx_fatal(FARGS, "Unsupported vdw interaction: %s", evdw_names[ic->vdwtype]); } fr->nbkernel_vdw_modifier = ic->vdw_modifier; if (ir->cutoff_scheme == ecutsVERLET) { - if (!gmx_within_tol(ic->reppow, 12.0, 10*GMX_DOUBLE_EPS)) + if (!gmx_within_tol(ic->reppow, 12.0, 10 * GMX_DOUBLE_EPS)) { - gmx_fatal(FARGS, "Cut-off scheme %s only supports LJ repulsion power 12", ecutscheme_names[ir->cutoff_scheme]); + gmx_fatal(FARGS, "Cut-off scheme %s only supports LJ repulsion power 12", + ecutscheme_names[ir->cutoff_scheme]); } /* Older tpr files can contain Coulomb user tables with the Verlet cutoff-scheme, * while mdrun does not (and never did) support this. @@ -1278,14 +1260,9 @@ void init_forcerec(FILE *fp, fr->fudgeQQ = mtop->ffparams.fudgeQQ; fr->haveDirectVirialContributions = - (EEL_FULL(ic->eeltype) || EVDW_PME(ic->vdwtype) || - fr->forceProviders->hasForceProvider() || - gmx_mtop_ftype_count(mtop, F_POSRES) > 0 || - gmx_mtop_ftype_count(mtop, F_FBPOSRES) > 0 || - ir->nwall > 0 || - ir->bPull || - ir->bRot || - ir->bIMD); + (EEL_FULL(ic->eeltype) || EVDW_PME(ic->vdwtype) || fr->forceProviders->hasForceProvider() + || gmx_mtop_ftype_count(mtop, F_POSRES) > 0 || gmx_mtop_ftype_count(mtop, F_FBPOSRES) > 0 + || ir->nwall > 0 || ir->bPull || ir->bRot || ir->bIMD); if (fr->shift_vec == nullptr) { @@ -1300,7 +1277,7 @@ void init_forcerec(FILE *fp, fr->nbfp = mk_nbfp(&mtop->ffparams, fr->bBHAM); if (EVDW_PME(ic->vdwtype)) { - fr->ljpme_c6grid = make_ljpme_c6grid(&mtop->ffparams, fr); + fr->ljpme_c6grid = make_ljpme_c6grid(&mtop->ffparams, fr); } } @@ -1312,14 +1289,12 @@ void init_forcerec(FILE *fp, { if (ic->rvdw_switch >= ic->rvdw) { - gmx_fatal(FARGS, "rvdw_switch (%f) must be < rvdw (%f)", - ic->rvdw_switch, ic->rvdw); + gmx_fatal(FARGS, "rvdw_switch (%f) must be < rvdw (%f)", ic->rvdw_switch, ic->rvdw); } if (fp) { fprintf(fp, "Using %s Lennard-Jones, switch between %g and %g nm\n", - (ic->eeltype == eelSWITCH) ? "switched" : "shifted", - ic->rvdw_switch, ic->rvdw); + (ic->eeltype == eelSWITCH) ? "switched" : "shifted", ic->rvdw_switch, ic->rvdw); } } @@ -1340,8 +1315,8 @@ void init_forcerec(FILE *fp, if (fp && fr->cutoff_scheme == ecutsGROUP) { - fprintf(fp, "Cut-off's: NS: %g Coulomb: %g %s: %g\n", - fr->rlist, ic->rcoulomb, fr->bBHAM ? "BHAM" : "LJ", ic->rvdw); + fprintf(fp, "Cut-off's: NS: %g Coulomb: %g %s: %g\n", fr->rlist, ic->rcoulomb, + fr->bBHAM ? "BHAM" : "LJ", ic->rvdw); } if (ir->implicit_solvent) @@ -1359,12 +1334,10 @@ void init_forcerec(FILE *fp, /* We want to use unmodified tables for 1-4 coulombic * interactions, so we must in general have an extra set of * tables. */ - if (gmx_mtop_ftype_count(mtop, F_LJ14) > 0 || - gmx_mtop_ftype_count(mtop, F_LJC14_Q) > 0 || - gmx_mtop_ftype_count(mtop, F_LJC_PAIRS_NB) > 0) + if (gmx_mtop_ftype_count(mtop, F_LJ14) > 0 || gmx_mtop_ftype_count(mtop, F_LJC14_Q) > 0 + || gmx_mtop_ftype_count(mtop, F_LJC_PAIRS_NB) > 0) { - fr->pairsTable = make_tables(fp, ic, tabpfn, rtab, - GMX_MAKETABLES_14ONLY); + fr->pairsTable = make_tables(fp, ic, tabpfn, rtab, GMX_MAKETABLES_14ONLY); } /* Wall stuff */ @@ -1380,23 +1353,19 @@ void init_forcerec(FILE *fp, // TODO Don't need to catch this here, when merging with master branch try { - fcd->bondtab = make_bonded_tables(fp, - F_TABBONDS, F_TABBONDSNC, - mtop, tabbfnm, "b"); - fcd->angletab = make_bonded_tables(fp, - F_TABANGLES, -1, - mtop, tabbfnm, "a"); - fcd->dihtab = make_bonded_tables(fp, - F_TABDIHS, -1, - mtop, tabbfnm, "d"); + fcd->bondtab = make_bonded_tables(fp, F_TABBONDS, F_TABBONDSNC, mtop, tabbfnm, "b"); + fcd->angletab = make_bonded_tables(fp, F_TABANGLES, -1, mtop, tabbfnm, "a"); + fcd->dihtab = make_bonded_tables(fp, F_TABDIHS, -1, mtop, tabbfnm, "d"); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } else { if (debug) { - fprintf(debug, "No fcdata or table file name passed, can not read table, can not do bonded interactions\n"); + fprintf(debug, + "No fcdata or table file name passed, can not read table, can not do bonded " + "interactions\n"); } } @@ -1407,17 +1376,23 @@ void init_forcerec(FILE *fp, // Initialize QM/MM if supported if (GMX_QMMM) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Large parts of the QM/MM support is deprecated, and may be removed in a future " - "version. Please get in touch with the developers if you find the support useful, " - "as help is needed if the functionality is to continue to be available."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Large parts of the QM/MM support is deprecated, and may be removed in " + "a future " + "version. Please get in touch with the developers if you find the " + "support useful, " + "as help is needed if the functionality is to continue to be " + "available."); fr->qr = mk_QMMMrec(); init_QMMMrec(cr, mtop, ir, fr); } else { - gmx_incons("QM/MM was requested, but is only available when GROMACS " - "is configured with QM/MM support"); + gmx_incons( + "QM/MM was requested, but is only available when GROMACS " + "is configured with QM/MM support"); } } @@ -1430,15 +1405,14 @@ void init_forcerec(FILE *fp, if (!DOMAINDECOMP(cr)) { - forcerec_set_ranges(fr, - mtop->natoms, mtop->natoms, mtop->natoms); + forcerec_set_ranges(fr, mtop->natoms, mtop->natoms, mtop->natoms); } fr->print_force = print_force; /* Initialize the thread working data for bonded interactions */ - fr->bondedThreading = - init_bonded_threading(fp, mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size()); + fr->bondedThreading = init_bonded_threading( + fp, mtop->groups.groups[SimulationAtomGroupType::EnergyOutput].size()); fr->nthread_ewc = gmx_omp_nthreads_get(emntBonded); snew(fr->ewc_t, fr->nthread_ewc); @@ -1449,37 +1423,37 @@ void init_forcerec(FILE *fp, // We have PME+LJcutoff kernels for rcoulomb>rvdw. if (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == eelCUT) { - GMX_RELEASE_ASSERT(ir->rcoulomb >= ir->rvdw, "With Verlet lists and PME we should have rcoulomb>=rvdw"); + GMX_RELEASE_ASSERT(ir->rcoulomb >= ir->rvdw, + "With Verlet lists and PME we should have rcoulomb>=rvdw"); } else { - GMX_RELEASE_ASSERT(ir->rcoulomb == ir->rvdw, "With Verlet lists and no PME rcoulomb and rvdw should be identical"); + GMX_RELEASE_ASSERT( + ir->rcoulomb == ir->rvdw, + "With Verlet lists and no PME rcoulomb and rvdw should be identical"); } - fr->nbv = Nbnxm::init_nb_verlet(mdlog, bFEP_NonBonded, ir, fr, - cr, hardwareInfo, deviceInfo, + fr->nbv = Nbnxm::init_nb_verlet(mdlog, bFEP_NonBonded, ir, fr, cr, hardwareInfo, deviceInfo, mtop, box, wcycle); if (useGpuForBonded) { - auto stream = DOMAINDECOMP(cr) ? - Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, gmx::InteractionLocality::NonLocal) : - Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, gmx::InteractionLocality::Local); + auto stream = DOMAINDECOMP(cr) + ? Nbnxm::gpu_get_command_stream( + fr->nbv->gpu_nbv, gmx::InteractionLocality::NonLocal) + : Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, + gmx::InteractionLocality::Local); // TODO the heap allocation is only needed while // t_forcerec lacks a constructor. - fr->gpuBonded = new gmx::GpuBonded(mtop->ffparams, - stream, - wcycle); + fr->gpuBonded = new gmx::GpuBonded(mtop->ffparams, stream, wcycle); } } if (ir->eDispCorr != edispcNO) { - fr->dispersionCorrection = - std::make_unique(*mtop, *ir, fr->bBHAM, - fr->ntype, - gmx::arrayRefFromArray(fr->nbfp, fr->ntype*fr->ntype*2), - *fr->ic, tabfn); + fr->dispersionCorrection = std::make_unique( + *mtop, *ir, fr->bBHAM, fr->ntype, + gmx::arrayRefFromArray(fr->nbfp, fr->ntype * fr->ntype * 2), *fr->ic, tabfn); fr->dispersionCorrection->print(mdlog); } @@ -1494,8 +1468,7 @@ void init_forcerec(FILE *fp, if (pmeOnlyRankUsesGpu && c_enableGpuPmePpComms) { - fr->pmePpCommGpu = std::make_unique(cr->mpi_comm_mysim, - cr->dd->pme_nodeid); + fr->pmePpCommGpu = std::make_unique(cr->mpi_comm_mysim, cr->dd->pme_nodeid); } } @@ -1511,9 +1484,9 @@ t_forcerec::~t_forcerec() = default; * \todo Remove physical node barrier from this function after making sure * that it's not needed anymore (with a shared GPU run). */ -void free_gpu_resources(t_forcerec *fr, - const gmx::PhysicalNodeCommunicator &physicalNodeCommunicator, - const gmx_gpu_info_t &gpu_info) +void free_gpu_resources(t_forcerec* fr, + const gmx::PhysicalNodeCommunicator& physicalNodeCommunicator, + const gmx_gpu_info_t& gpu_info) { bool isPPrankUsingGPU = (fr != nullptr) && (fr->nbv != nullptr) && fr->nbv->useGpu(); @@ -1548,7 +1521,7 @@ void free_gpu_resources(t_forcerec *fr, } } -void done_forcerec(t_forcerec *fr, int numMolBlocks) +void done_forcerec(t_forcerec* fr, int numMolBlocks) { if (fr == nullptr) { diff --git a/src/gromacs/mdlib/forcerec.h b/src/gromacs/mdlib/forcerec.h index 7c6793c5d3..e28e717b50 100644 --- a/src/gromacs/mdlib/forcerec.h +++ b/src/gromacs/mdlib/forcerec.h @@ -57,17 +57,17 @@ namespace gmx { class MDLogger; class PhysicalNodeCommunicator; -} +} // namespace gmx //! Destroy a forcerec. -void done_forcerec(t_forcerec *fr, int numMolBlocks); +void done_forcerec(t_forcerec* fr, int numMolBlocks); /*! \brief Print the contents of the forcerec to a file * * \param[in] fplog The log file to print to * \param[in] fr The forcerec structure */ -void pr_forcerec(FILE *fplog, t_forcerec *fr); +void pr_forcerec(FILE* fplog, t_forcerec* fr); /*! \brief Set the number of charge groups and atoms. * @@ -79,10 +79,7 @@ void pr_forcerec(FILE *fplog, t_forcerec *fr); * \param[in] natoms_f_novirsum Number of atoms for which * force is to be compute but no virial */ -void -forcerec_set_ranges(t_forcerec *fr, - int natoms_force, - int natoms_force_constr, int natoms_f_novirsum); +void forcerec_set_ranges(t_forcerec* fr, int natoms_force, int natoms_force_constr, int natoms_f_novirsum); /*! \brief Initiate table constants * @@ -90,8 +87,7 @@ forcerec_set_ranges(t_forcerec *fr, * \param[in] fp File for debugging output * \param[in] ic Structure holding the table constant */ -void init_interaction_const_tables(FILE *fp, - interaction_const_t *ic); +void init_interaction_const_tables(FILE* fp, interaction_const_t* ic); /*! \brief Initialize forcerec structure. * @@ -113,23 +109,23 @@ void init_interaction_const_tables(FILE *fp, * \param[in] print_force Print forces for atoms with force >= print_force * \param[out] wcycle Pointer to cycle counter object */ -void init_forcerec(FILE *fplog, - const gmx::MDLogger &mdlog, - t_forcerec *fr, - t_fcdata *fcd, - const t_inputrec *ir, - const gmx_mtop_t *mtop, - const t_commrec *cr, - matrix box, - const char *tabfn, - const char *tabpfn, - gmx::ArrayRef tabbfnm, - const gmx_hw_info_t &hardwareInfo, - const gmx_device_info_t *deviceInfo, - bool useGpuForBonded, - bool pmeOnlyRankUsesGpu, - real print_force, - gmx_wallcycle *wcycle); +void init_forcerec(FILE* fplog, + const gmx::MDLogger& mdlog, + t_forcerec* fr, + t_fcdata* fcd, + const t_inputrec* ir, + const gmx_mtop_t* mtop, + const t_commrec* cr, + matrix box, + const char* tabfn, + const char* tabpfn, + gmx::ArrayRef tabbfnm, + const gmx_hw_info_t& hardwareInfo, + const gmx_device_info_t* deviceInfo, + bool useGpuForBonded, + bool pmeOnlyRankUsesGpu, + real print_force, + gmx_wallcycle* wcycle); /*! \brief Divide exclusions over threads * @@ -137,11 +133,10 @@ void init_forcerec(FILE *fplog, * \param[out] fr The force record * \param[in] top The topology */ -void forcerec_set_excl_load(t_forcerec *fr, - const gmx_localtop_t *top); +void forcerec_set_excl_load(t_forcerec* fr, const gmx_localtop_t* top); -void free_gpu_resources(t_forcerec *fr, - const gmx::PhysicalNodeCommunicator &physicalNodeCommunicator, - const gmx_gpu_info_t &gpu_info); +void free_gpu_resources(t_forcerec* fr, + const gmx::PhysicalNodeCommunicator& physicalNodeCommunicator, + const gmx_gpu_info_t& gpu_info); #endif diff --git a/src/gromacs/mdlib/forcerec_threading.h b/src/gromacs/mdlib/forcerec_threading.h index 26d40570a0..15bca48990 100644 --- a/src/gromacs/mdlib/forcerec_threading.h +++ b/src/gromacs/mdlib/forcerec_threading.h @@ -39,12 +39,13 @@ #include "gromacs/math/vectypes.h" #include "gromacs/mdtypes/md_enums.h" -struct ewald_corr_thread_t { - real Vcorr_q; - real Vcorr_lj; - real dvdl[efptNR]; - tensor vir_q; - tensor vir_lj; +struct ewald_corr_thread_t +{ + real Vcorr_q; + real Vcorr_lj; + real dvdl[efptNR]; + tensor vir_q; + tensor vir_lj; }; #endif diff --git a/src/gromacs/mdlib/gmx_omp_nthreads.cpp b/src/gromacs/mdlib/gmx_omp_nthreads.cpp index b2a0e46066..6ae2e122ff 100644 --- a/src/gromacs/mdlib/gmx_omp_nthreads.cpp +++ b/src/gromacs/mdlib/gmx_omp_nthreads.cpp @@ -56,33 +56,34 @@ * algorithmic module in mdrun. */ typedef struct { - int gnth; /**< Global num. of threads per PP or PP+PME process/tMPI thread. */ - int gnth_pme; /**< Global num. of threads per PME only process/tMPI thread. */ + int gnth; /**< Global num. of threads per PP or PP+PME process/tMPI thread. */ + int gnth_pme; /**< Global num. of threads per PME only process/tMPI thread. */ - int nth[emntNR]; /**< Number of threads for each module, indexed with module_nth_t */ - gmx_bool initialized; /**< TRUE if the module as been initialized. */ + int nth[emntNR]; /**< Number of threads for each module, indexed with module_nth_t */ + gmx_bool initialized; /**< TRUE if the module as been initialized. */ } omp_module_nthreads_t; /** Names of environment variables to set the per module number of threads. * * Indexed with the values of module_nth_t. * */ -static const char *modth_env_var[emntNR] = -{ - "GMX_DEFAULT_NUM_THREADS should never be set", - "GMX_DOMDEC_NUM_THREADS", "GMX_PAIRSEARCH_NUM_THREADS", - "GMX_NONBONDED_NUM_THREADS", "GMX_LISTED_FORCES_NUM_THREADS", - "GMX_PME_NUM_THREADS", "GMX_UPDATE_NUM_THREADS", - "GMX_VSITE_NUM_THREADS", - "GMX_LINCS_NUM_THREADS", "GMX_SETTLE_NUM_THREADS" -}; +static const char* modth_env_var[emntNR] = { "GMX_DEFAULT_NUM_THREADS should never be set", + "GMX_DOMDEC_NUM_THREADS", + "GMX_PAIRSEARCH_NUM_THREADS", + "GMX_NONBONDED_NUM_THREADS", + "GMX_LISTED_FORCES_NUM_THREADS", + "GMX_PME_NUM_THREADS", + "GMX_UPDATE_NUM_THREADS", + "GMX_VSITE_NUM_THREADS", + "GMX_LINCS_NUM_THREADS", + "GMX_SETTLE_NUM_THREADS" }; /** Names of the modules. */ -static const char *mod_name[emntNR] = -{ - "default", "domain decomposition", "pair search", "non-bonded", - "bonded", "PME", "update", "LINCS", "SETTLE" -}; +static const char* mod_name[emntNR] = { "default", "domain decomposition", + "pair search", "non-bonded", + "bonded", "PME", + "update", "LINCS", + "SETTLE" }; /** Number of threads for each algorithmic module. * @@ -92,7 +93,7 @@ static const char *mod_name[emntNR] = * All fields are initialized to 0 which should result in errors if * the init call is omitted. * */ -static omp_module_nthreads_t modth = { 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}, FALSE}; +static omp_module_nthreads_t modth = { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, FALSE }; /** Determine the number of threads for module \p mod. @@ -104,11 +105,10 @@ static omp_module_nthreads_t modth = { 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}, FALSE} * GMX_*_NUM_THERADS env var is set, case in which its value overrides * the default. */ -static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m, - gmx_bool bSepPME) +static void pick_module_nthreads(const gmx::MDLogger& mdlog, int m, gmx_bool bSepPME) { - char *env; - int nth; + char* env; + int nth; const bool bOMP = GMX_OPENMP; @@ -126,8 +126,7 @@ static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m, if (!bOMP) { - gmx_warning("%s=%d is set, but %s is compiled without OpenMP!", - modth_env_var[m], nth, + gmx_warning("%s=%d is set, but %s is compiled without OpenMP!", modth_env_var[m], nth, gmx::getProgramContext().displayName()); } @@ -135,17 +134,19 @@ static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m, * OMP_NUM_THREADS also has to be set */ if (getenv("OMP_NUM_THREADS") == nullptr) { - gmx_warning("%s=%d is set, the default number of threads also " - "needs to be set with OMP_NUM_THREADS!", - modth_env_var[m], nth); + gmx_warning( + "%s=%d is set, the default number of threads also " + "needs to be set with OMP_NUM_THREADS!", + modth_env_var[m], nth); } /* only babble if we are really overriding with a different value */ if ((bSepPME && m == emntPME && nth != modth.gnth_pme) || (nth != modth.gnth)) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "%s=%d set, overriding the default number of %s threads", - modth_env_var[m], nth, mod_name[m]); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted("%s=%d set, overriding the default number of %s threads", + modth_env_var[m], nth, mod_name[m]); } } else @@ -158,10 +159,9 @@ static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m, gmx_omp_nthreads_set(m, nth); } -void gmx_omp_nthreads_read_env(const gmx::MDLogger &mdlog, - int *nthreads_omp) +void gmx_omp_nthreads_read_env(const gmx::MDLogger& mdlog, int* nthreads_omp) { - char *env; + char* env; gmx_bool bCommandLineSetNthreadsOMP = *nthreads_omp > 0; char buffer[STRLEN]; @@ -179,7 +179,11 @@ void gmx_omp_nthreads_read_env(const gmx::MDLogger &mdlog, if (bCommandLineSetNthreadsOMP && nt_omp != *nthreads_omp) { - gmx_fatal(FARGS, "Environment variable OMP_NUM_THREADS (%d) and the number of threads requested on the command line (%d) have different values. Either omit one, or set them both to the same value.", nt_omp, *nthreads_omp); + gmx_fatal(FARGS, + "Environment variable OMP_NUM_THREADS (%d) and the number of threads " + "requested on the command line (%d) have different values. Either omit one, " + "or set them both to the same value.", + nt_omp, *nthreads_omp); } /* Setting the number of OpenMP threads. */ @@ -187,7 +191,8 @@ void gmx_omp_nthreads_read_env(const gmx::MDLogger &mdlog, /* Output the results */ sprintf(buffer, - "\nThe number of OpenMP threads was set by environment variable OMP_NUM_THREADS to %d%s\n\n", + "\nThe number of OpenMP threads was set by environment variable OMP_NUM_THREADS to " + "%d%s\n\n", nt_omp, bCommandLineSetNthreadsOMP ? " (and the command-line setting agreed with that)" : ""); @@ -208,18 +213,18 @@ void gmx_omp_nthreads_read_env(const gmx::MDLogger &mdlog, /*! \brief Helper function for parsing various input about the number of OpenMP threads to use in various modules and deciding what to do about it. */ -static void manage_number_of_openmp_threads(const gmx::MDLogger &mdlog, - const t_commrec *cr, +static void manage_number_of_openmp_threads(const gmx::MDLogger& mdlog, + const t_commrec* cr, bool bOMP, int nthreads_hw_avail, int omp_nthreads_req, int omp_nthreads_pme_req, - gmx_bool gmx_unused bThisNodePMEOnly, - int numRanksOnThisNode, - gmx_bool bSepPME) + gmx_bool gmx_unused bThisNodePMEOnly, + int numRanksOnThisNode, + gmx_bool bSepPME) { - int nth; - char *env; + int nth; + char* env; #if GMX_THREAD_MPI /* modth is shared among tMPI threads, so for thread safety, the @@ -343,7 +348,7 @@ static void manage_number_of_openmp_threads(const gmx::MDLogger &mdlog, gmx_omp_set_num_threads(modth.gnth_pme); } else -#endif /* GMX_THREAD_MPI */ +#endif /* GMX_THREAD_MPI */ { gmx_omp_set_num_threads(nth); } @@ -353,18 +358,14 @@ static void manage_number_of_openmp_threads(const gmx::MDLogger &mdlog, } /*! \brief Report on the OpenMP settings that will be used */ -static void -reportOpenmpSettings(const gmx::MDLogger &mdlog, - const t_commrec *cr, - gmx_bool bOMP, - gmx_bool bSepPME) +static void reportOpenmpSettings(const gmx::MDLogger& mdlog, const t_commrec* cr, gmx_bool bOMP, gmx_bool bSepPME) { #if GMX_THREAD_MPI - const char *mpi_str = "per tMPI thread"; + const char* mpi_str = "per tMPI thread"; #else - const char *mpi_str = "per MPI process"; + const char* mpi_str = "per MPI process"; #endif - int nth_min, nth_max, nth_pme_min, nth_pme_max; + int nth_min, nth_max, nth_pme_min, nth_pme_max; /* inform the user about the settings */ if (!bOMP) @@ -379,16 +380,16 @@ reportOpenmpSettings(const gmx::MDLogger &mdlog, int buf_in[4], buf_out[4]; buf_in[0] = -modth.gnth; - buf_in[1] = modth.gnth; + buf_in[1] = modth.gnth; buf_in[2] = -modth.gnth_pme; - buf_in[3] = modth.gnth_pme; + buf_in[3] = modth.gnth_pme; MPI_Allreduce(buf_in, buf_out, 4, MPI_INT, MPI_MAX, cr->mpi_comm_mysim); nth_min = -buf_out[0]; - nth_max = buf_out[1]; + nth_max = buf_out[1]; nth_pme_min = -buf_out[2]; - nth_pme_max = buf_out[3]; + nth_pme_max = buf_out[3]; } else #endif @@ -402,54 +403,49 @@ reportOpenmpSettings(const gmx::MDLogger &mdlog, if (nth_max == nth_min) { - GMX_LOG(mdlog.warning).appendTextFormatted( - "Using %d OpenMP thread%s %s", - nth_min, nth_min > 1 ? "s" : "", - cr->nnodes > 1 ? mpi_str : ""); + GMX_LOG(mdlog.warning) + .appendTextFormatted("Using %d OpenMP thread%s %s", nth_min, nth_min > 1 ? "s" : "", + cr->nnodes > 1 ? mpi_str : ""); } else { - GMX_LOG(mdlog.warning).appendTextFormatted( - "Using %d - %d OpenMP threads %s", - nth_min, nth_max, mpi_str); + GMX_LOG(mdlog.warning).appendTextFormatted("Using %d - %d OpenMP threads %s", nth_min, nth_max, mpi_str); } if (bSepPME && (nth_pme_min != nth_min || nth_pme_max != nth_max)) { if (nth_pme_max == nth_pme_min) { - GMX_LOG(mdlog.warning).appendTextFormatted( - "Using %d OpenMP thread%s %s for PME", - nth_pme_min, nth_pme_min > 1 ? "s" : "", - cr->nnodes > 1 ? mpi_str : ""); + GMX_LOG(mdlog.warning) + .appendTextFormatted("Using %d OpenMP thread%s %s for PME", nth_pme_min, + nth_pme_min > 1 ? "s" : "", cr->nnodes > 1 ? mpi_str : ""); } else { - GMX_LOG(mdlog.warning).appendTextFormatted( - "Using %d - %d OpenMP threads %s for PME", - nth_pme_min, nth_pme_max, mpi_str); + GMX_LOG(mdlog.warning) + .appendTextFormatted("Using %d - %d OpenMP threads %s for PME", nth_pme_min, + nth_pme_max, mpi_str); } } GMX_LOG(mdlog.warning); } -void gmx_omp_nthreads_init(const gmx::MDLogger &mdlog, t_commrec *cr, - int nthreads_hw_avail, - int numRanksOnThisNode, - int omp_nthreads_req, - int omp_nthreads_pme_req, - gmx_bool bThisNodePMEOnly) +void gmx_omp_nthreads_init(const gmx::MDLogger& mdlog, + t_commrec* cr, + int nthreads_hw_avail, + int numRanksOnThisNode, + int omp_nthreads_req, + int omp_nthreads_pme_req, + gmx_bool bThisNodePMEOnly) { - gmx_bool bSepPME; + gmx_bool bSepPME; const bool bOMP = GMX_OPENMP; bSepPME = (thisRankHasDuty(cr, DUTY_PP) != thisRankHasDuty(cr, DUTY_PME)); - manage_number_of_openmp_threads(mdlog, cr, bOMP, - nthreads_hw_avail, - omp_nthreads_req, omp_nthreads_pme_req, - bThisNodePMEOnly, numRanksOnThisNode, bSepPME); + manage_number_of_openmp_threads(mdlog, cr, bOMP, nthreads_hw_avail, omp_nthreads_req, + omp_nthreads_pme_req, bThisNodePMEOnly, numRanksOnThisNode, bSepPME); #if GMX_THREAD_MPI /* Non-master threads have to wait for the OpenMP management to be * done, so that code elsewhere that uses OpenMP can be certain @@ -476,8 +472,7 @@ int gmx_omp_nthreads_get(int mod) } } -void -gmx_omp_nthreads_set(int mod, int nthreads) +void gmx_omp_nthreads_set(int mod, int nthreads) { /* Catch an attempt to set the number of threads on an invalid * OpenMP module. */ diff --git a/src/gromacs/mdlib/gmx_omp_nthreads.h b/src/gromacs/mdlib/gmx_omp_nthreads.h index 5470b463ba..30ba196a5e 100644 --- a/src/gromacs/mdlib/gmx_omp_nthreads.h +++ b/src/gromacs/mdlib/gmx_omp_nthreads.h @@ -52,8 +52,16 @@ typedef enum module_nth { /* Default is meant to be used in OMP regions outside the named * algorithmic modules listed below. */ - emntDefault, emntDomdec, emntPairsearch, emntNonbonded, - emntBonded, emntPME, emntUpdate, emntVSITE, emntLINCS, emntSETTLE, + emntDefault, + emntDomdec, + emntPairsearch, + emntNonbonded, + emntBonded, + emntPME, + emntUpdate, + emntVSITE, + emntLINCS, + emntSETTLE, emntNR } module_nth_t; @@ -63,12 +71,13 @@ typedef enum module_nth * It is compatible with tMPI, thread-safety is ensured (for the features * available with tMPI). * This function should caled only once during the initialization of mdrun. */ -void gmx_omp_nthreads_init(const gmx::MDLogger &fplog, t_commrec *cr, - int nthreads_hw_avail, - int numRanksOnThisNode, - int omp_nthreads_req, - int omp_nthreads_pme_req, - gmx_bool bCurrNodePMEOnly); +void gmx_omp_nthreads_init(const gmx::MDLogger& fplog, + t_commrec* cr, + int nthreads_hw_avail, + int numRanksOnThisNode, + int omp_nthreads_req, + int omp_nthreads_pme_req, + gmx_bool bCurrNodePMEOnly); /*! \brief * Returns the number of threads to be used in the given module \p mod. */ @@ -116,7 +125,6 @@ void gmx_omp_nthreads_set(int mod, int nthreads); /*! \brief * Read the OMP_NUM_THREADS env. var. and check against the value set on the * command line. */ -void gmx_omp_nthreads_read_env(const gmx::MDLogger &mdlog, - int *nthreads_omp); +void gmx_omp_nthreads_read_env(const gmx::MDLogger& mdlog, int* nthreads_omp); #endif diff --git a/src/gromacs/mdlib/groupcoord.cpp b/src/gromacs/mdlib/groupcoord.cpp index 9e4ec821b0..bd8711ce77 100644 --- a/src/gromacs/mdlib/groupcoord.cpp +++ b/src/gromacs/mdlib/groupcoord.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,19 +48,17 @@ #define MIN(a, b) (((a) < (b)) ? (a) : (b)) - /* Select the indices of the group's atoms which are local and store them in * anrs_loc[0..nr_loc]. The indices are saved in coll_ind[] for later reduction * in communicate_group_positions() */ -void -dd_make_local_group_indices(const gmx_ga2la_t *ga2la, - const int nr, /* IN: Total number of atoms in the group */ - int anrs[], /* IN: Global atom numbers of the groups atoms */ - int *nr_loc, /* OUT: Number of group atoms found locally */ - int *anrs_loc[], /* OUT: Local atom numbers of the group */ - int *nalloc_loc, /* IN+OUT: Allocation size of anrs_loc */ - int coll_ind[]) /* OUT (opt): Where is this position found in the collective array? */ +void dd_make_local_group_indices(const gmx_ga2la_t* ga2la, + const int nr, /* IN: Total number of atoms in the group */ + int anrs[], /* IN: Global atom numbers of the groups atoms */ + int* nr_loc, /* OUT: Number of group atoms found locally */ + int* anrs_loc[], /* OUT: Local atom numbers of the group */ + int* nalloc_loc, /* IN+OUT: Allocation size of anrs_loc */ + int coll_ind[]) /* OUT (opt): Where is this position found in the collective array? */ { GMX_ASSERT(ga2la, "We need a valid ga2la object"); @@ -69,12 +67,12 @@ dd_make_local_group_indices(const gmx_ga2la_t *ga2la, int localnr = 0; for (int i = 0; i < nr; i++) { - if (const int *ii = ga2la->findHome(anrs[i])) + if (const int* ii = ga2la->findHome(anrs[i])) { /* The atom with this index is a home atom */ if (localnr >= *nalloc_loc) /* Check whether memory suffices */ { - *nalloc_loc = over_alloc_dd(localnr+1); + *nalloc_loc = over_alloc_dd(localnr + 1); /* We never need more memory than the number of atoms in the group */ *nalloc_loc = MIN(*nalloc_loc, nr); srenew(*anrs_loc, *nalloc_loc); @@ -100,13 +98,12 @@ dd_make_local_group_indices(const gmx_ga2la_t *ga2la, } -static void get_shifts_group( - int npbcdim, - const matrix box, - rvec *xcoll, /* IN: Collective set of positions [0..nr] */ - int nr, /* IN: Total number of atoms in the group */ - rvec *xcoll_old, /* IN: Positions from the last time step [0...nr] */ - ivec *shifts) /* OUT: Shifts for xcoll */ +static void get_shifts_group(int npbcdim, + const matrix box, + rvec* xcoll, /* IN: Collective set of positions [0..nr] */ + int nr, /* IN: Total number of atoms in the group */ + rvec* xcoll_old, /* IN: Positions from the last time step [0...nr] */ + ivec* shifts) /* OUT: Shifts for xcoll */ { int i, m, d; rvec dx; @@ -127,9 +124,9 @@ static void get_shifts_group( /* If this is more than just a bit, it has changed its home pbc box */ rvec_sub(xcoll[i], xcoll_old[i], dx); - for (m = npbcdim-1; m >= 0; m--) + for (m = npbcdim - 1; m >= 0; m--) { - while (dx[m] < -0.5*box[m][m]) + while (dx[m] < -0.5 * box[m][m]) { for (d = 0; d < DIM; d++) { @@ -137,7 +134,7 @@ static void get_shifts_group( } shifts[i][m]++; } - while (dx[m] >= 0.5*box[m][m]) + while (dx[m] >= 0.5 * box[m][m]) { for (d = 0; d < DIM; d++) { @@ -150,13 +147,12 @@ static void get_shifts_group( } -static void shift_positions_group( - const matrix box, - rvec x[], /* The positions [0..nr] */ - ivec *is, /* The shifts [0..nr] */ - int nr) /* The number of positions and shifts */ +static void shift_positions_group(const matrix box, + rvec x[], /* The positions [0..nr] */ + ivec* is, /* The shifts [0..nr] */ + int nr) /* The number of positions and shifts */ { - int i, tx, ty, tz; + int i, tx, ty, tz; /* Loop over the group's atoms */ @@ -168,9 +164,9 @@ static void shift_positions_group( ty = is[i][YY]; tz = is[i][ZZ]; - x[i][XX] = x[i][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX]; - x[i][YY] = x[i][YY]+ty*box[YY][YY]+tz*box[ZZ][YY]; - x[i][ZZ] = x[i][ZZ]+tz*box[ZZ][ZZ]; + x[i][XX] = x[i][XX] + tx * box[XX][XX] + ty * box[YY][XX] + tz * box[ZZ][XX]; + x[i][YY] = x[i][YY] + ty * box[YY][YY] + tz * box[ZZ][YY]; + x[i][ZZ] = x[i][ZZ] + tz * box[ZZ][ZZ]; } } else @@ -181,9 +177,9 @@ static void shift_positions_group( ty = is[i][YY]; tz = is[i][ZZ]; - x[i][XX] = x[i][XX]+tx*box[XX][XX]; - x[i][YY] = x[i][YY]+ty*box[YY][YY]; - x[i][ZZ] = x[i][ZZ]+tz*box[ZZ][ZZ]; + x[i][XX] = x[i][XX] + tx * box[XX][XX]; + x[i][YY] = x[i][YY] + ty * box[YY][YY]; + x[i][ZZ] = x[i][ZZ] + tz * box[ZZ][ZZ]; } } } @@ -192,20 +188,19 @@ static void shift_positions_group( /* Assemble the positions of the group such that every node has all of them. * The atom indices are retrieved from anrs_loc[0..nr_loc] * Note that coll_ind[i] = i is needed in the serial case */ -extern void communicate_group_positions( - const t_commrec *cr, /* Pointer to MPI communication data */ - rvec *xcoll, /* Collective array of positions */ - ivec *shifts, /* Collective array of shifts for xcoll (can be NULL) */ - ivec *extra_shifts, /* (optional) Extra shifts since last time step */ - const gmx_bool bNS, /* (optional) NS step, the shifts have changed */ - const rvec *x_loc, /* Local positions on this node */ - const int nr, /* Total number of atoms in the group */ - const int nr_loc, /* Local number of atoms in the group */ - const int *anrs_loc, /* Local atom numbers */ - const int *coll_ind, /* Collective index */ - rvec *xcoll_old, /* (optional) Positions from the last time step, - used to make group whole */ - const matrix box) /* (optional) The box */ +extern void communicate_group_positions(const t_commrec* cr, /* Pointer to MPI communication data */ + rvec* xcoll, /* Collective array of positions */ + ivec* shifts, /* Collective array of shifts for xcoll (can be NULL) */ + ivec* extra_shifts, /* (optional) Extra shifts since last time step */ + const gmx_bool bNS, /* (optional) NS step, the shifts have changed */ + const rvec* x_loc, /* Local positions on this node */ + const int nr, /* Total number of atoms in the group */ + const int nr_loc, /* Local number of atoms in the group */ + const int* anrs_loc, /* Local atom numbers */ + const int* coll_ind, /* Collective index */ + rvec* xcoll_old, /* (optional) Positions from the last time + step, used to make group whole */ + const matrix box) /* (optional) The box */ { int i; @@ -223,7 +218,7 @@ extern void communicate_group_positions( if (PAR(cr)) { /* Add the arrays from all nodes together */ - gmx_sum(nr*3, xcoll[0], cr); + gmx_sum(nr * 3, xcoll[0], cr); } /* Now we have all the positions of the group in the xcoll array present on all * nodes. @@ -318,10 +313,9 @@ extern void get_center(rvec x[], real weight[], const int nr, rvec rcenter) } else { - denom = nr; /* Divide by the number of atoms */ - + denom = nr; /* Divide by the number of atoms */ } - dsvmul(1.0/denom, dcenter, dcenter); + dsvmul(1.0 / denom, dcenter, dcenter); rcenter[XX] = dcenter[XX]; rcenter[YY] = dcenter[YY]; @@ -331,13 +325,12 @@ extern void get_center(rvec x[], real weight[], const int nr, rvec rcenter) /* Get the center from local positions that already have the correct * PBC representation */ -extern void get_center_comm( - const t_commrec *cr, - rvec x_loc[], /* Local positions */ - real weight_loc[], /* Local masses or other weights */ - int nr_loc, /* Local number of atoms */ - int nr_group, /* Total number of atoms of the group */ - rvec center) /* Weighted center */ +extern void get_center_comm(const t_commrec* cr, + rvec x_loc[], /* Local positions */ + real weight_loc[], /* Local masses or other weights */ + int nr_loc, /* Local number of atoms */ + int nr_group, /* Total number of atoms of the group */ + rvec center) /* Weighted center */ { double weight_sum, denom; dvec dsumvec; @@ -367,16 +360,15 @@ extern void get_center_comm( if (weight_loc != nullptr) { - denom = 1.0/weight_sum; /* Divide by the sum of weight to get center of mass e.g. */ + denom = 1.0 / weight_sum; /* Divide by the sum of weight to get center of mass e.g. */ } else { - denom = 1.0/nr_group; /* Divide by the number of atoms to get the geometrical center */ - + denom = 1.0 / nr_group; /* Divide by the number of atoms to get the geometrical center */ } - center[XX] = dsumvec[XX]*denom; - center[YY] = dsumvec[YY]*denom; - center[ZZ] = dsumvec[ZZ]*denom; + center[XX] = dsumvec[XX] * denom; + center[YY] = dsumvec[YY] * denom; + center[ZZ] = dsumvec[ZZ] * denom; } @@ -411,7 +403,7 @@ extern void rotate_x(rvec x[], const int nr, matrix rmat) x[i][j] = 0; for (k = 0; k < 3; k++) { - x[i][j] += rmat[k][j]*x_old[k]; + x[i][j] += rmat[k][j] * x_old[k]; } } } diff --git a/src/gromacs/mdlib/groupcoord.h b/src/gromacs/mdlib/groupcoord.h index 9d2443c76e..36fecea637 100644 --- a/src/gromacs/mdlib/groupcoord.h +++ b/src/gromacs/mdlib/groupcoord.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,10 +74,13 @@ struct t_commrec; * in the communicate_group_positions routine. */ -extern void dd_make_local_group_indices(const gmx_ga2la_t *ga2la, - int nr, int anrs[], int *nr_loc, - int *anrs_loc[], int *nalloc_loc, - int coll_ind[]); +extern void dd_make_local_group_indices(const gmx_ga2la_t* ga2la, + int nr, + int anrs[], + int* nr_loc, + int* anrs_loc[], + int* nalloc_loc, + int coll_ind[]); /*! \brief Assemble local positions into a collective array present on all nodes. @@ -123,11 +126,18 @@ extern void dd_make_local_group_indices(const gmx_ga2la_t *ga2la, * \param[in] box Simulation box matrix, needed to shift xcoll such that * the group becomes whole (optional). */ -extern void communicate_group_positions(const t_commrec *cr, rvec *xcoll, ivec *shifts, - ivec *extra_shifts, gmx_bool bNS, - const rvec *x_loc, int nr, int nr_loc, - const int *anrs_loc, const int *coll_ind, rvec *xcoll_old, - const matrix box); +extern void communicate_group_positions(const t_commrec* cr, + rvec* xcoll, + ivec* shifts, + ivec* extra_shifts, + gmx_bool bNS, + const rvec* x_loc, + int nr, + int nr_loc, + const int* anrs_loc, + const int* coll_ind, + rvec* xcoll_old, + const matrix box); /*! \brief Calculates the center of the positions x locally. * @@ -178,8 +188,7 @@ extern double get_sum_of_positions(rvec x[], real weight[], int nr, dvec dsumvec * \param[out] center The (weighted) center of all x_loc from all the * nodes. */ -extern void get_center_comm(const t_commrec *cr, rvec x_loc[], real weight_loc[], - int nr_loc, int nr_group, rvec center); +extern void get_center_comm(const t_commrec* cr, rvec x_loc[], real weight_loc[], int nr_loc, int nr_group, rvec center); /*! \brief Translate positions. diff --git a/src/gromacs/mdlib/leapfrog_cuda.cu b/src/gromacs/mdlib/leapfrog_cuda.cu index d99ed0cec4..6c4b5b5bf1 100644 --- a/src/gromacs/mdlib/leapfrog_cuda.cu +++ b/src/gromacs/mdlib/leapfrog_cuda.cu @@ -83,9 +83,9 @@ constexpr static int c_maxThreadsPerBlock = c_threadsPerBlock; */ enum class NumTempScaleValues { - None, //!< No temperature coupling - Single, //!< Single T-scaling value (one group) - Multiple //!< Multiple T-scaling values, need to use T-group indices + None, //!< No temperature coupling + Single, //!< Single T-scaling value (one group) + Multiple //!< Multiple T-scaling values, need to use T-group indices }; /*! \brief Different variants of the Parrinello-Rahman velocity scaling @@ -95,9 +95,9 @@ enum class NumTempScaleValues */ enum class VelocityScalingType { - None, //!< Do not apply velocity scaling (not a PR-coupling run or step) - Diagonal, //!< Apply velocity scaling using a diagonal matrix - Full //!< Apply velocity scaling using a full matrix + None, //!< Do not apply velocity scaling (not a PR-coupling run or step) + Diagonal, //!< Apply velocity scaling using a diagonal matrix + Full //!< Apply velocity scaling using a full matrix }; /*! \brief Main kernel for Leap-Frog integrator. @@ -126,44 +126,44 @@ enum class VelocityScalingType * \param[in] velocityScalingMatrixDiagonal Diagonal elements of Parrinello-Rahman velocity scaling matrix */ template -__launch_bounds__(c_maxThreadsPerBlock) -__global__ void leapfrog_kernel(const int numAtoms, - float3* __restrict__ gm_x, - float3* __restrict__ gm_xp, - float3* __restrict__ gm_v, - const float3* __restrict__ gm_f, - const float* __restrict__ gm_inverseMasses, - const float dt, - const float* __restrict__ gm_lambdas, - const unsigned short* __restrict__ gm_tempScaleGroups, - const float3 velocityScalingMatrixDiagonal); +__launch_bounds__(c_maxThreadsPerBlock) __global__ + void leapfrog_kernel(const int numAtoms, + float3* __restrict__ gm_x, + float3* __restrict__ gm_xp, + float3* __restrict__ gm_v, + const float3* __restrict__ gm_f, + const float* __restrict__ gm_inverseMasses, + const float dt, + const float* __restrict__ gm_lambdas, + const unsigned short* __restrict__ gm_tempScaleGroups, + const float3 velocityScalingMatrixDiagonal); template -__launch_bounds__(c_maxThreadsPerBlock) -__global__ void leapfrog_kernel(const int numAtoms, - float3* __restrict__ gm_x, - float3* __restrict__ gm_xp, - float3* __restrict__ gm_v, - const float3* __restrict__ gm_f, - const float* __restrict__ gm_inverseMasses, - const float dt, - const float* __restrict__ gm_lambdas, - const unsigned short* __restrict__ gm_tempScaleGroups, - const float3 velocityScalingMatrixDiagonal) +__launch_bounds__(c_maxThreadsPerBlock) __global__ + void leapfrog_kernel(const int numAtoms, + float3* __restrict__ gm_x, + float3* __restrict__ gm_xp, + float3* __restrict__ gm_v, + const float3* __restrict__ gm_f, + const float* __restrict__ gm_inverseMasses, + const float dt, + const float* __restrict__ gm_lambdas, + const unsigned short* __restrict__ gm_tempScaleGroups, + const float3 velocityScalingMatrixDiagonal) { - int threadIndex = blockIdx.x*blockDim.x + threadIdx.x; + int threadIndex = blockIdx.x * blockDim.x + threadIdx.x; if (threadIndex < numAtoms) { - float3 x = gm_x[threadIndex]; - float3 v = gm_v[threadIndex]; - float3 f = gm_f[threadIndex]; - float im = gm_inverseMasses[threadIndex]; - float imdt = im*dt; + float3 x = gm_x[threadIndex]; + float3 v = gm_v[threadIndex]; + float3 f = gm_f[threadIndex]; + float im = gm_inverseMasses[threadIndex]; + float imdt = im * dt; // Swapping places for xp and x so that the x will contain the updated coordinates and xp - the // coordinates before update. This should be taken into account when (if) constraints are applied // after the update: x and xp have to be passed to constraints in the 'wrong' order. - gm_xp[threadIndex] = x; + gm_xp[threadIndex] = x; if (numTempScaleValues != NumTempScaleValues::None || velocityScaling != VelocityScalingType::None) { @@ -174,7 +174,7 @@ __global__ void leapfrog_kernel(const int numAtoms, float lambda = 1.0F; if (numTempScaleValues == NumTempScaleValues::Single) { - lambda = gm_lambdas[0]; + lambda = gm_lambdas[0]; } else if (numTempScaleValues == NumTempScaleValues::Multiple) { @@ -186,20 +186,19 @@ __global__ void leapfrog_kernel(const int numAtoms, if (velocityScaling == VelocityScalingType::Diagonal) { - vp.x -= velocityScalingMatrixDiagonal.x*v.x; - vp.y -= velocityScalingMatrixDiagonal.y*v.y; - vp.z -= velocityScalingMatrixDiagonal.z*v.z; + vp.x -= velocityScalingMatrixDiagonal.x * v.x; + vp.y -= velocityScalingMatrixDiagonal.y * v.y; + vp.z -= velocityScalingMatrixDiagonal.z * v.z; } v = vp; } - v += f*imdt; - - x += v*dt; - gm_v[threadIndex] = v; - gm_x[threadIndex] = x; + v += f * imdt; + x += v * dt; + gm_v[threadIndex] = v; + gm_x[threadIndex] = x; } return; } @@ -234,11 +233,12 @@ inline auto selectLeapFrogKernelPtr(int numTempScaleValues, VelocityScalingType } else { - GMX_RELEASE_ASSERT(false, "Number of temperature coupling groups should be greater than zero (zero for no coupling)."); + GMX_RELEASE_ASSERT(false, + "Number of temperature coupling groups should be greater than zero " + "(zero for no coupling)."); } } - else - if (velocityScaling == VelocityScalingType::Diagonal) + else if (velocityScaling == VelocityScalingType::Diagonal) { if (numTempScaleValues == 0) { @@ -254,72 +254,74 @@ inline auto selectLeapFrogKernelPtr(int numTempScaleValues, VelocityScalingType } else { - GMX_RELEASE_ASSERT(false, "Number of temperature coupling groups should be greater than zero (zero for no coupling)."); + GMX_RELEASE_ASSERT(false, + "Number of temperature coupling groups should be greater than zero " + "(zero for no coupling)."); } } else { - GMX_RELEASE_ASSERT(false, "Only isotropic Parrinello-Rahman pressure coupling is supported."); + GMX_RELEASE_ASSERT(false, + "Only isotropic Parrinello-Rahman pressure coupling is supported."); } return kernelPtr; } -void LeapFrogCuda::integrate(const float3 *d_x, - float3 *d_xp, - float3 *d_v, - const float3 *d_f, - const real dt, - const bool doTempCouple, - gmx::ArrayRef tcstat, - const bool doPressureCouple, - const float dtPressureCouple, - const matrix velocityScalingMatrix) +void LeapFrogCuda::integrate(const float3* d_x, + float3* d_xp, + float3* d_v, + const float3* d_f, + const real dt, + const bool doTempCouple, + gmx::ArrayRef tcstat, + const bool doPressureCouple, + const float dtPressureCouple, + const matrix velocityScalingMatrix) { ensureNoPendingCudaError("In CUDA version of Leap-Frog integrator"); - auto kernelPtr = leapfrog_kernel; + auto kernelPtr = leapfrog_kernel; if (doTempCouple || doPressureCouple) { if (doTempCouple) { - GMX_ASSERT(numTempScaleValues_ == ssize(h_lambdas_), "Number of temperature scaling factors changed since it was set for the last time."); + GMX_ASSERT(numTempScaleValues_ == ssize(h_lambdas_), + "Number of temperature scaling factors changed since it was set for the " + "last time."); for (int i = 0; i < numTempScaleValues_; i++) { h_lambdas_[i] = tcstat[i].lambda; } - copyToDeviceBuffer(&d_lambdas_, h_lambdas_.data(), - 0, numTempScaleValues_, commandStream_, GpuApiCallBehavior::Async, nullptr); + copyToDeviceBuffer(&d_lambdas_, h_lambdas_.data(), 0, numTempScaleValues_, + commandStream_, GpuApiCallBehavior::Async, nullptr); } VelocityScalingType velocityScaling = VelocityScalingType::None; if (doPressureCouple) { velocityScaling = VelocityScalingType::Diagonal; - GMX_ASSERT(velocityScalingMatrix[YY][XX] == 0 && velocityScalingMatrix[ZZ][XX] == 0 && velocityScalingMatrix[ZZ][YY] == 0 && - velocityScalingMatrix[XX][YY] == 0 && velocityScalingMatrix[XX][ZZ] == 0 && velocityScalingMatrix[YY][ZZ] == 0, - "Fully anisotropic Parrinello-Rahman pressure coupling is not yet supported in GPU version of Leap-Frog integrator."); - velocityScalingMatrixDiagonal_ = make_float3(dtPressureCouple*velocityScalingMatrix[XX][XX], - dtPressureCouple*velocityScalingMatrix[YY][YY], - dtPressureCouple*velocityScalingMatrix[ZZ][ZZ]); + GMX_ASSERT(velocityScalingMatrix[YY][XX] == 0 && velocityScalingMatrix[ZZ][XX] == 0 + && velocityScalingMatrix[ZZ][YY] == 0 && velocityScalingMatrix[XX][YY] == 0 + && velocityScalingMatrix[XX][ZZ] == 0 && velocityScalingMatrix[YY][ZZ] == 0, + "Fully anisotropic Parrinello-Rahman pressure coupling is not yet supported " + "in GPU version of Leap-Frog integrator."); + velocityScalingMatrixDiagonal_ = + make_float3(dtPressureCouple * velocityScalingMatrix[XX][XX], + dtPressureCouple * velocityScalingMatrix[YY][YY], + dtPressureCouple * velocityScalingMatrix[ZZ][ZZ]); } kernelPtr = selectLeapFrogKernelPtr(numTempScaleValues_, velocityScaling); } - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, kernelLaunchConfig_, - &numAtoms_, - &d_x, &d_xp, - &d_v, - &d_f, - &d_inverseMasses_, &dt, - &d_lambdas_, &d_tempScaleGroups_, - &velocityScalingMatrixDiagonal_); + const auto kernelArgs = prepareGpuKernelArguments( + kernelPtr, kernelLaunchConfig_, &numAtoms_, &d_x, &d_xp, &d_v, &d_f, &d_inverseMasses_, + &dt, &d_lambdas_, &d_tempScaleGroups_, &velocityScalingMatrixDiagonal_); launchGpuKernel(kernelPtr, kernelLaunchConfig_, nullptr, "leapfrog_kernel", kernelArgs); return; } -LeapFrogCuda::LeapFrogCuda(CommandStream commandStream) : - commandStream_(commandStream) +LeapFrogCuda::LeapFrogCuda(CommandStream commandStream) : commandStream_(commandStream) { numAtoms_ = 0; @@ -335,33 +337,32 @@ LeapFrogCuda::LeapFrogCuda(CommandStream commandStream) : LeapFrogCuda::~LeapFrogCuda() { freeDeviceBuffer(&d_inverseMasses_); - } -void LeapFrogCuda::setPbc(const t_pbc *pbc) +void LeapFrogCuda::setPbc(const t_pbc* pbc) { setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_); } -void LeapFrogCuda::set(const t_mdatoms &md, - const int numTempScaleValues, - const unsigned short *tempScaleGroups) +void LeapFrogCuda::set(const t_mdatoms& md, const int numTempScaleValues, const unsigned short* tempScaleGroups) { numAtoms_ = md.nr; - kernelLaunchConfig_.gridSize[0] = (numAtoms_ + c_threadsPerBlock - 1)/c_threadsPerBlock; + kernelLaunchConfig_.gridSize[0] = (numAtoms_ + c_threadsPerBlock - 1) / c_threadsPerBlock; numTempScaleValues_ = numTempScaleValues; - reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_, &numInverseMassesAlloc_, nullptr); - copyToDeviceBuffer(&d_inverseMasses_, (float*)md.invmass, - 0, numAtoms_, commandStream_, GpuApiCallBehavior::Sync, nullptr); + reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_, + &numInverseMassesAlloc_, nullptr); + copyToDeviceBuffer(&d_inverseMasses_, (float*)md.invmass, 0, numAtoms_, commandStream_, + GpuApiCallBehavior::Sync, nullptr); // Temperature scale group map only used if there are more then one group if (numTempScaleValues > 1) { - reallocateDeviceBuffer(&d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_, &numTempScaleGroupsAlloc_, nullptr); - copyToDeviceBuffer(&d_tempScaleGroups_, tempScaleGroups, - 0, numAtoms_, commandStream_, GpuApiCallBehavior::Sync, nullptr); + reallocateDeviceBuffer(&d_tempScaleGroups_, numAtoms_, &numTempScaleGroups_, + &numTempScaleGroupsAlloc_, nullptr); + copyToDeviceBuffer(&d_tempScaleGroups_, tempScaleGroups, 0, numAtoms_, commandStream_, + GpuApiCallBehavior::Sync, nullptr); } // If the temperature coupling is enabled, we need to make space for scaling factors @@ -370,7 +371,6 @@ void LeapFrogCuda::set(const t_mdatoms &md, h_lambdas_.resize(numTempScaleValues); reallocateDeviceBuffer(&d_lambdas_, numTempScaleValues_, &numLambdas_, &numLambdasAlloc_, nullptr); } - } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/leapfrog_cuda.cuh b/src/gromacs/mdlib/leapfrog_cuda.cuh index 919fc1c9fe..f80697bfe0 100644 --- a/src/gromacs/mdlib/leapfrog_cuda.cuh +++ b/src/gromacs/mdlib/leapfrog_cuda.cuh @@ -61,113 +61,108 @@ namespace gmx class LeapFrogCuda { - public: - - /*! \brief Constructor. - * - * \param[in] commandStream Device command stream to use. - */ - LeapFrogCuda(CommandStream commandStream); - ~LeapFrogCuda(); - - /*! \brief - * Update PBC data. - * - * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. - * - * \param[in] pbc The PBC data in t_pbc format. - */ - void setPbc(const t_pbc *pbc); - - /*! \brief Integrate - * - * Integrates the equation of motion using Leap-Frog algorithm. - * Updates coordinates and velocities on the GPU. The current coordinates are saved for constraints. - * - * \param[in,out] d_x Coordinates to update - * \param[out] d_xp Place to save the values of initial coordinates coordinates to. - * \param[in,out] d_v Velocities (will be updated). - * \param[in] d_f Forces. - * \param[in] dt Timestep. - * \param[in] doTempCouple If the temperature coupling should be applied. - * \param[in] tcstat Temperature coupling data. - * \param[in] doPressureCouple If the temperature coupling should be applied. - * \param[in] dtPressureCouple Period between pressure coupling steps - * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix - */ - void integrate(const float3 *d_x, - float3 *d_xp, - float3 *d_v, - const float3 *d_f, - const real dt, - const bool doTempCouple, - gmx::ArrayRef tcstat, - const bool doPressureCouple, - const float dtPressureCouple, - const matrix velocityScalingMatrix); - - /*! \brief Set the integrator - * - * Allocates memory for inverse masses, and, if needed for temperature scaling factor(s) - * and temperature coupling groups. Copies inverse masses and temperature coupling groups - * to the GPU. - * - * \param[in] md MD atoms, from which inverse masses are taken. - * \param[in] numTempScaleValues Number of temperature scale groups. - * \param[in] tempScaleGroups Maps the atom index to temperature scale value. - */ - void set(const t_mdatoms &md, - int numTempScaleValues, - const unsigned short *tempScaleGroups); - - /*! \brief Class with hardware-specific interfaces and implementations.*/ - class Impl; - - private: - - //! CUDA stream - CommandStream commandStream_; - //! CUDA kernel launch config - KernelLaunchConfig kernelLaunchConfig_; - //! Periodic boundary data - PbcAiuc pbcAiuc_; - //! Number of atoms - int numAtoms_; - - //! 1/mass for all atoms (GPU) - real *d_inverseMasses_; - //! Current size of the reciprocal masses array - int numInverseMasses_ = -1; - //! Maximum size of the reciprocal masses array - int numInverseMassesAlloc_ = -1; - - //! Number of temperature coupling groups (zero = no coupling) - int numTempScaleValues_ = 0; - /*! \brief Array with temperature scaling factors. - * This is temporary solution to remap data from t_grp_tcstat into plain array - * \todo Replace with better solution. - */ - gmx::HostVector h_lambdas_; - //! Device-side temperature scaling factors - float *d_lambdas_; - //! Current size of the array with temperature scaling factors (lambdas) - int numLambdas_ = -1; - //! Maximum size of the array with temperature scaling factors (lambdas) - int numLambdasAlloc_ = -1; - - - //! Array that maps atom index onto the temperature scaling group to get scaling parameter - unsigned short *d_tempScaleGroups_; - //! Current size of the temperature coupling groups array - int numTempScaleGroups_ = -1; - //! Maximum size of the temperature coupling groups array - int numTempScaleGroupsAlloc_ = -1; - - //! Vector with diagonal elements of the pressure coupling velocity rescale factors - float3 velocityScalingMatrixDiagonal_; - +public: + /*! \brief Constructor. + * + * \param[in] commandStream Device command stream to use. + */ + LeapFrogCuda(CommandStream commandStream); + ~LeapFrogCuda(); + + /*! \brief + * Update PBC data. + * + * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. + * + * \param[in] pbc The PBC data in t_pbc format. + */ + void setPbc(const t_pbc* pbc); + + /*! \brief Integrate + * + * Integrates the equation of motion using Leap-Frog algorithm. + * Updates coordinates and velocities on the GPU. The current coordinates are saved for constraints. + * + * \param[in,out] d_x Coordinates to update + * \param[out] d_xp Place to save the values of initial coordinates coordinates to. + * \param[in,out] d_v Velocities (will be updated). + * \param[in] d_f Forces. + * \param[in] dt Timestep. + * \param[in] doTempCouple If the temperature coupling should be applied. + * \param[in] tcstat Temperature coupling data. + * \param[in] doPressureCouple If the temperature coupling should be applied. + * \param[in] dtPressureCouple Period between pressure coupling steps + * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix + */ + void integrate(const float3* d_x, + float3* d_xp, + float3* d_v, + const float3* d_f, + const real dt, + const bool doTempCouple, + gmx::ArrayRef tcstat, + const bool doPressureCouple, + const float dtPressureCouple, + const matrix velocityScalingMatrix); + + /*! \brief Set the integrator + * + * Allocates memory for inverse masses, and, if needed for temperature scaling factor(s) + * and temperature coupling groups. Copies inverse masses and temperature coupling groups + * to the GPU. + * + * \param[in] md MD atoms, from which inverse masses are taken. + * \param[in] numTempScaleValues Number of temperature scale groups. + * \param[in] tempScaleGroups Maps the atom index to temperature scale value. + */ + void set(const t_mdatoms& md, int numTempScaleValues, const unsigned short* tempScaleGroups); + + /*! \brief Class with hardware-specific interfaces and implementations.*/ + class Impl; + +private: + //! CUDA stream + CommandStream commandStream_; + //! CUDA kernel launch config + KernelLaunchConfig kernelLaunchConfig_; + //! Periodic boundary data + PbcAiuc pbcAiuc_; + //! Number of atoms + int numAtoms_; + + //! 1/mass for all atoms (GPU) + real* d_inverseMasses_; + //! Current size of the reciprocal masses array + int numInverseMasses_ = -1; + //! Maximum size of the reciprocal masses array + int numInverseMassesAlloc_ = -1; + + //! Number of temperature coupling groups (zero = no coupling) + int numTempScaleValues_ = 0; + /*! \brief Array with temperature scaling factors. + * This is temporary solution to remap data from t_grp_tcstat into plain array + * \todo Replace with better solution. + */ + gmx::HostVector h_lambdas_; + //! Device-side temperature scaling factors + float* d_lambdas_; + //! Current size of the array with temperature scaling factors (lambdas) + int numLambdas_ = -1; + //! Maximum size of the array with temperature scaling factors (lambdas) + int numLambdasAlloc_ = -1; + + + //! Array that maps atom index onto the temperature scaling group to get scaling parameter + unsigned short* d_tempScaleGroups_; + //! Current size of the temperature coupling groups array + int numTempScaleGroups_ = -1; + //! Maximum size of the temperature coupling groups array + int numTempScaleGroupsAlloc_ = -1; + + //! Vector with diagonal elements of the pressure coupling velocity rescale factors + float3 velocityScalingMatrixDiagonal_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/lincs.cpp b/src/gromacs/mdlib/lincs.cpp index 149c87590c..81fce32355 100644 --- a/src/gromacs/mdlib/lincs.cpp +++ b/src/gromacs/mdlib/lincs.cpp @@ -94,9 +94,7 @@ namespace gmx struct AtomPair { //! \brief Constructor, does not initialize to catch bugs and faster construction - AtomPair() - { - } + AtomPair() {} //! Index of atom 1 int index1; @@ -108,11 +106,11 @@ struct AtomPair struct Task { //! First constraint for this task. - int b0 = 0; + int b0 = 0; //! b1-1 is the last constraint for this task. - int b1 = 0; + int b1 = 0; //! The number of constraints in triangles. - int ntriangle = 0; + int ntriangle = 0; //! The list of triangle constraints. std::vector triangle; //! The bits tell if the matrix element should be used. @@ -122,97 +120,97 @@ struct Task //! Constraint index for updating atom data. std::vector ind_r; //! Temporary variable for virial calculation. - tensor vir_r_m_dr = {{0}}; + tensor vir_r_m_dr = { { 0 } }; //! Temporary variable for lambda derivative. - real dhdlambda; + real dhdlambda; }; /*! \brief Data for LINCS algorithm. */ class Lincs { - public: - //! The global number of constraints. - int ncg = 0; - //! The global number of flexible constraints. - int ncg_flex = 0; - //! The global number of constraints in triangles. - int ncg_triangle = 0; - //! The number of iterations. - int nIter = 0; - //! The order of the matrix expansion. - int nOrder = 0; - //! The maximum number of constraints connected to a single atom. - int max_connect = 0; - - //! The number of real constraints. - int nc_real = 0; - //! The number of constraints including padding for SIMD. - int nc = 0; - //! The number of constraint connections. - int ncc = 0; - //! The FE lambda value used for filling blc and blmf. - real matlam = 0; - //! mapping from topology to LINCS constraints. - std::vector con_index; - //! The reference distance in topology A. - std::vector < real, AlignedAllocator < real>> bllen0; - //! The reference distance in top B - the r.d. in top A. - std::vector < real, AlignedAllocator < real>> ddist; - //! The atom pairs involved in the constraints. - std::vector atoms; - //! 1/sqrt(invmass1 invmass2). - std::vector < real, AlignedAllocator < real>> blc; - //! As blc, but with all masses 1. - std::vector < real, AlignedAllocator < real>> blc1; - //! Index into blbnb and blmf. - std::vector blnr; - //! List of constraint connections. - std::vector blbnb; - //! The local number of constraints in triangles. - int ntriangle = 0; - //! The number of constraint connections in triangles. - int ncc_triangle = 0; - //! Communicate before each LINCS interation. - bool bCommIter = false; - //! Matrix of mass factors for constraint connections. - std::vector blmf; - //! As blmf, but with all masses 1. - std::vector blmf1; - //! The reference bond length. - std::vector < real, AlignedAllocator < real>> bllen; - //! The local atom count per constraint, can be NULL. - std::vector nlocat; - - /*! \brief The number of tasks used for LINCS work. - * - * \todo This is mostly used to loop over \c task, which would - * be nicer to do with range-based for loops, but the thread - * index is used for constructing bit masks and organizing the - * virial output buffer, so other things need to change, - * first. */ - int ntask = 0; - /*! \brief LINCS thread division */ - std::vector task; - //! Atom flags for thread parallelization. - std::vector atf; - //! Are the LINCS tasks interdependent? - bool bTaskDep = false; - //! Are there triangle constraints that cross task borders? - bool bTaskDepTri = false; - //! Arrays for temporary storage in the LINCS algorithm. - /*! @{ */ - PaddedVector tmpv; - std::vector tmpncc; - std::vector < real, AlignedAllocator < real>> tmp1; - std::vector < real, AlignedAllocator < real>> tmp2; - std::vector < real, AlignedAllocator < real>> tmp3; - std::vector < real, AlignedAllocator < real>> tmp4; - /*! @} */ - //! The Lagrange multipliers times -1. - std::vector < real, AlignedAllocator < real>> mlambda; - //! Storage for the constraint RMS relative deviation output. - std::array rmsdData = {{0}}; +public: + //! The global number of constraints. + int ncg = 0; + //! The global number of flexible constraints. + int ncg_flex = 0; + //! The global number of constraints in triangles. + int ncg_triangle = 0; + //! The number of iterations. + int nIter = 0; + //! The order of the matrix expansion. + int nOrder = 0; + //! The maximum number of constraints connected to a single atom. + int max_connect = 0; + + //! The number of real constraints. + int nc_real = 0; + //! The number of constraints including padding for SIMD. + int nc = 0; + //! The number of constraint connections. + int ncc = 0; + //! The FE lambda value used for filling blc and blmf. + real matlam = 0; + //! mapping from topology to LINCS constraints. + std::vector con_index; + //! The reference distance in topology A. + std::vector> bllen0; + //! The reference distance in top B - the r.d. in top A. + std::vector> ddist; + //! The atom pairs involved in the constraints. + std::vector atoms; + //! 1/sqrt(invmass1 invmass2). + std::vector> blc; + //! As blc, but with all masses 1. + std::vector> blc1; + //! Index into blbnb and blmf. + std::vector blnr; + //! List of constraint connections. + std::vector blbnb; + //! The local number of constraints in triangles. + int ntriangle = 0; + //! The number of constraint connections in triangles. + int ncc_triangle = 0; + //! Communicate before each LINCS interation. + bool bCommIter = false; + //! Matrix of mass factors for constraint connections. + std::vector blmf; + //! As blmf, but with all masses 1. + std::vector blmf1; + //! The reference bond length. + std::vector> bllen; + //! The local atom count per constraint, can be NULL. + std::vector nlocat; + + /*! \brief The number of tasks used for LINCS work. + * + * \todo This is mostly used to loop over \c task, which would + * be nicer to do with range-based for loops, but the thread + * index is used for constructing bit masks and organizing the + * virial output buffer, so other things need to change, + * first. */ + int ntask = 0; + /*! \brief LINCS thread division */ + std::vector task; + //! Atom flags for thread parallelization. + std::vector atf; + //! Are the LINCS tasks interdependent? + bool bTaskDep = false; + //! Are there triangle constraints that cross task borders? + bool bTaskDepTri = false; + //! Arrays for temporary storage in the LINCS algorithm. + /*! @{ */ + PaddedVector tmpv; + std::vector tmpncc; + std::vector> tmp1; + std::vector> tmp2; + std::vector> tmp3; + std::vector> tmp4; + /*! @} */ + //! The Lagrange multipliers times -1. + std::vector> mlambda; + //! Storage for the constraint RMS relative deviation output. + std::array rmsdData = { { 0 } }; }; /*! \brief Define simd_width for memory allocation used for SIMD code */ @@ -222,16 +220,16 @@ static const int simd_width = GMX_SIMD_REAL_WIDTH; static const int simd_width = 1; #endif -ArrayRef lincs_rmsdData(Lincs *lincsd) +ArrayRef lincs_rmsdData(Lincs* lincsd) { return lincsd->rmsdData; } -real lincs_rmsd(const Lincs *lincsd) +real lincs_rmsd(const Lincs* lincsd) { if (lincsd->rmsdData[0] > 0) { - return std::sqrt(lincsd->rmsdData[1]/lincsd->rmsdData[0]); + return std::sqrt(lincsd->rmsdData[1] / lincsd->rmsdData[0]); } else { @@ -244,19 +242,19 @@ real lincs_rmsd(const Lincs *lincsd) * This function will return with up to date thread-local * constraint data, without an OpenMP barrier. */ -static void lincs_matrix_expand(const Lincs &lincsd, - const Task &li_task, - gmx::ArrayRef blcc, - gmx::ArrayRef rhs1, - gmx::ArrayRef rhs2, - gmx::ArrayRef sol) +static void lincs_matrix_expand(const Lincs& lincsd, + const Task& li_task, + gmx::ArrayRef blcc, + gmx::ArrayRef rhs1, + gmx::ArrayRef rhs2, + gmx::ArrayRef sol) { gmx::ArrayRef blnr = lincsd.blnr; gmx::ArrayRef blbnb = lincsd.blbnb; - const int b0 = li_task.b0; - const int b1 = li_task.b1; - const int nrec = lincsd.nOrder; + const int b0 = li_task.b0; + const int b1 = li_task.b1; + const int nrec = lincsd.nOrder; for (int rec = 0; rec < nrec; rec++) { @@ -270,16 +268,16 @@ static void lincs_matrix_expand(const Lincs &lincsd, int n; mvb = 0; - for (n = blnr[b]; n < blnr[b+1]; n++) + for (n = blnr[b]; n < blnr[b + 1]; n++) { - mvb = mvb + blcc[n]*rhs1[blbnb[n]]; + mvb = mvb + blcc[n] * rhs1[blbnb[n]]; } rhs2[b] = mvb; sol[b] = sol[b] + mvb; } std::swap(rhs1, rhs2); - } /* nrec*(ncons+2*nrtot) flops */ + } /* nrec*(ncons+2*nrtot) flops */ if (lincsd.ntriangle > 0) { @@ -319,12 +317,12 @@ static void lincs_matrix_expand(const Lincs &lincsd, bits = tri_bits[tb]; mvb = 0; nr0 = blnr[b]; - nr1 = blnr[b+1]; + nr1 = blnr[b + 1]; for (n = nr0; n < nr1; n++) { if (bits & (1 << (n - nr0))) { - mvb = mvb + blcc[n]*rhs1[blbnb[n]]; + mvb = mvb + blcc[n] * rhs1[blbnb[n]]; } } rhs2[b] = mvb; @@ -332,7 +330,7 @@ static void lincs_matrix_expand(const Lincs &lincsd, } std::swap(rhs1, rhs2); - } /* nrec*(ntriangle + ncc_triangle*2) flops */ + } /* nrec*(ntriangle + ncc_triangle*2) flops */ if (lincsd.bTaskDepTri) { @@ -346,120 +344,116 @@ static void lincs_matrix_expand(const Lincs &lincsd, } //! Update atomic coordinates when an index is not required. -static void -lincs_update_atoms_noind(int ncons, - gmx::ArrayRef atoms, - real preFactor, - gmx::ArrayRef fac, - gmx::ArrayRef r, - const real *invmass, - rvec *x) +static void lincs_update_atoms_noind(int ncons, + gmx::ArrayRef atoms, + real preFactor, + gmx::ArrayRef fac, + gmx::ArrayRef r, + const real* invmass, + rvec* x) { if (invmass != nullptr) { for (int b = 0; b < ncons; b++) { - int i = atoms[b].index1; - int j = atoms[b].index2; - real mvb = preFactor*fac[b]; - real im1 = invmass[i]; - real im2 = invmass[j]; - real tmp0 = r[b][0]*mvb; - real tmp1 = r[b][1]*mvb; - real tmp2 = r[b][2]*mvb; - x[i][0] -= tmp0*im1; - x[i][1] -= tmp1*im1; - x[i][2] -= tmp2*im1; - x[j][0] += tmp0*im2; - x[j][1] += tmp1*im2; - x[j][2] += tmp2*im2; - } /* 16 ncons flops */ + int i = atoms[b].index1; + int j = atoms[b].index2; + real mvb = preFactor * fac[b]; + real im1 = invmass[i]; + real im2 = invmass[j]; + real tmp0 = r[b][0] * mvb; + real tmp1 = r[b][1] * mvb; + real tmp2 = r[b][2] * mvb; + x[i][0] -= tmp0 * im1; + x[i][1] -= tmp1 * im1; + x[i][2] -= tmp2 * im1; + x[j][0] += tmp0 * im2; + x[j][1] += tmp1 * im2; + x[j][2] += tmp2 * im2; + } /* 16 ncons flops */ } else { for (int b = 0; b < ncons; b++) { - int i = atoms[b].index1; - int j = atoms[b].index2; - real mvb = preFactor*fac[b]; - real tmp0 = r[b][0]*mvb; - real tmp1 = r[b][1]*mvb; - real tmp2 = r[b][2]*mvb; - x[i][0] -= tmp0; - x[i][1] -= tmp1; - x[i][2] -= tmp2; - x[j][0] += tmp0; - x[j][1] += tmp1; - x[j][2] += tmp2; + int i = atoms[b].index1; + int j = atoms[b].index2; + real mvb = preFactor * fac[b]; + real tmp0 = r[b][0] * mvb; + real tmp1 = r[b][1] * mvb; + real tmp2 = r[b][2] * mvb; + x[i][0] -= tmp0; + x[i][1] -= tmp1; + x[i][2] -= tmp2; + x[j][0] += tmp0; + x[j][1] += tmp1; + x[j][2] += tmp2; } } } //! Update atomic coordinates when an index is required. -static void -lincs_update_atoms_ind(gmx::ArrayRef ind, - gmx::ArrayRef atoms, - real preFactor, - gmx::ArrayRef fac, - gmx::ArrayRef r, - const real *invmass, - rvec *x) +static void lincs_update_atoms_ind(gmx::ArrayRef ind, + gmx::ArrayRef atoms, + real preFactor, + gmx::ArrayRef fac, + gmx::ArrayRef r, + const real* invmass, + rvec* x) { if (invmass != nullptr) { for (int b : ind) { - int i = atoms[b].index1; - int j = atoms[b].index2; - real mvb = preFactor*fac[b]; - real im1 = invmass[i]; - real im2 = invmass[j]; - real tmp0 = r[b][0]*mvb; - real tmp1 = r[b][1]*mvb; - real tmp2 = r[b][2]*mvb; - x[i][0] -= tmp0*im1; - x[i][1] -= tmp1*im1; - x[i][2] -= tmp2*im1; - x[j][0] += tmp0*im2; - x[j][1] += tmp1*im2; - x[j][2] += tmp2*im2; - } /* 16 ncons flops */ + int i = atoms[b].index1; + int j = atoms[b].index2; + real mvb = preFactor * fac[b]; + real im1 = invmass[i]; + real im2 = invmass[j]; + real tmp0 = r[b][0] * mvb; + real tmp1 = r[b][1] * mvb; + real tmp2 = r[b][2] * mvb; + x[i][0] -= tmp0 * im1; + x[i][1] -= tmp1 * im1; + x[i][2] -= tmp2 * im1; + x[j][0] += tmp0 * im2; + x[j][1] += tmp1 * im2; + x[j][2] += tmp2 * im2; + } /* 16 ncons flops */ } else { for (int b : ind) { - int i = atoms[b].index1; - int j = atoms[b].index2; - real mvb = preFactor*fac[b]; - real tmp0 = r[b][0]*mvb; - real tmp1 = r[b][1]*mvb; - real tmp2 = r[b][2]*mvb; - x[i][0] -= tmp0; - x[i][1] -= tmp1; - x[i][2] -= tmp2; - x[j][0] += tmp0; - x[j][1] += tmp1; - x[j][2] += tmp2; - } /* 16 ncons flops */ + int i = atoms[b].index1; + int j = atoms[b].index2; + real mvb = preFactor * fac[b]; + real tmp0 = r[b][0] * mvb; + real tmp1 = r[b][1] * mvb; + real tmp2 = r[b][2] * mvb; + x[i][0] -= tmp0; + x[i][1] -= tmp1; + x[i][2] -= tmp2; + x[j][0] += tmp0; + x[j][1] += tmp1; + x[j][2] += tmp2; + } /* 16 ncons flops */ } } //! Update coordinates for atoms. -static void -lincs_update_atoms(Lincs *li, - int th, - real preFactor, - gmx::ArrayRef fac, - gmx::ArrayRef r, - const real *invmass, - rvec *x) +static void lincs_update_atoms(Lincs* li, + int th, + real preFactor, + gmx::ArrayRef fac, + gmx::ArrayRef r, + const real* invmass, + rvec* x) { if (li->ntask == 1) { /* Single thread, we simply update for all constraints */ - lincs_update_atoms_noind(li->nc_real, - li->atoms, preFactor, fac, r, invmass, x); + lincs_update_atoms_noind(li->nc_real, li->atoms, preFactor, fac, r, invmass, x); } else { @@ -467,8 +461,7 @@ lincs_update_atoms(Lincs *li, * constraints that only access our local atom range. * This can be done without a barrier. */ - lincs_update_atoms_ind(li->task[th].ind, - li->atoms, preFactor, fac, r, invmass, x); + lincs_update_atoms_ind(li->task[th].ind, li->atoms, preFactor, fac, r, invmass, x); if (!li->task[li->ntask].ind.empty()) { @@ -478,8 +471,7 @@ lincs_update_atoms(Lincs *li, #pragma omp barrier #pragma omp master { - lincs_update_atoms_ind(li->task[li->ntask].ind, - li->atoms, preFactor, fac, r, invmass, x); + lincs_update_atoms_ind(li->task[li->ntask].ind, li->atoms, preFactor, fac, r, invmass, x); } } } @@ -487,20 +479,19 @@ lincs_update_atoms(Lincs *li, #if GMX_SIMD_HAVE_REAL //! Helper function so that we can run TSAN with SIMD support (where implemented). -template -static inline void gmx_simdcall -gatherLoadUTransposeTSANSafe(const real *base, - const std::int32_t *offset, - SimdReal *v0, - SimdReal *v1, - SimdReal *v2) +template +static inline void gmx_simdcall gatherLoadUTransposeTSANSafe(const real* base, + const std::int32_t* offset, + SimdReal* v0, + SimdReal* v1, + SimdReal* v2) { -#if (CMAKE_BUILD_TYPE == CMAKE_BUILD_TYPE_TSAN) && GMX_SIMD_X86_AVX2_256 +# if (CMAKE_BUILD_TYPE == CMAKE_BUILD_TYPE_TSAN) && GMX_SIMD_X86_AVX2_256 // This function is only implemented in this case gatherLoadUTransposeSafe(base, offset, v0, v1, v2); -#else +# else gatherLoadUTranspose(base, offset, v0, v1, v2); -#endif +# endif } /*! \brief Calculate the constraint distance vectors r to project on from x. @@ -508,17 +499,16 @@ gatherLoadUTransposeTSANSafe(const real *base, * Determine the right-hand side of the matrix equation using quantity f. * This function only differs from calc_dr_x_xp_simd below in that * no constraint length is subtracted and no PBC is used for f. */ -static void gmx_simdcall -calc_dr_x_f_simd(int b0, - int b1, - gmx::ArrayRef atoms, - const rvec * gmx_restrict x, - const rvec * gmx_restrict f, - const real * gmx_restrict blc, - const real * pbc_simd, - rvec * gmx_restrict r, - real * gmx_restrict rhs, - real * gmx_restrict sol) +static void gmx_simdcall calc_dr_x_f_simd(int b0, + int b1, + gmx::ArrayRef atoms, + const rvec* gmx_restrict x, + const rvec* gmx_restrict f, + const real* gmx_restrict blc, + const real* pbc_simd, + rvec* gmx_restrict r, + real* gmx_restrict rhs, + real* gmx_restrict sol) { assert(b0 % GMX_SIMD_REAL_WIDTH == 0); @@ -531,12 +521,12 @@ calc_dr_x_f_simd(int b0, for (int bs = b0; bs < b1; bs += GMX_SIMD_REAL_WIDTH) { - SimdReal x0_S, y0_S, z0_S; - SimdReal x1_S, y1_S, z1_S; - SimdReal rx_S, ry_S, rz_S, n2_S, il_S; - SimdReal fx_S, fy_S, fz_S, ip_S, rhs_S; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; + SimdReal x0_S, y0_S, z0_S; + SimdReal x1_S, y1_S, z1_S; + SimdReal rx_S, ry_S, rz_S, n2_S, il_S; + SimdReal fx_S, fy_S, fz_S, ip_S, rhs_S; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { @@ -544,30 +534,30 @@ calc_dr_x_f_simd(int b0, offset1[i] = atoms[bs + i].index2; } - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); rx_S = x0_S - x1_S; ry_S = y0_S - y1_S; rz_S = z0_S - z1_S; pbc_correct_dx_simd(&rx_S, &ry_S, &rz_S, pbc_simd); - n2_S = norm2(rx_S, ry_S, rz_S); - il_S = invsqrt(n2_S); + n2_S = norm2(rx_S, ry_S, rz_S); + il_S = invsqrt(n2_S); - rx_S = rx_S * il_S; - ry_S = ry_S * il_S; - rz_S = rz_S * il_S; + rx_S = rx_S * il_S; + ry_S = ry_S * il_S; + rz_S = rz_S * il_S; - transposeScatterStoreU<3>(reinterpret_cast(r + bs), offset2, rx_S, ry_S, rz_S); + transposeScatterStoreU<3>(reinterpret_cast(r + bs), offset2, rx_S, ry_S, rz_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(f), offset0, &x0_S, &y0_S, &z0_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(f), offset1, &x1_S, &y1_S, &z1_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(f), offset0, &x0_S, &y0_S, &z0_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(f), offset1, &x1_S, &y1_S, &z1_S); fx_S = x0_S - x1_S; fy_S = y0_S - y1_S; fz_S = z0_S - z1_S; - ip_S = iprod(rx_S, ry_S, rz_S, fx_S, fy_S, fz_S); + ip_S = iprod(rx_S, ry_S, rz_S, fx_S, fy_S, fz_S); rhs_S = load(blc + bs) * ip_S; @@ -578,22 +568,28 @@ calc_dr_x_f_simd(int b0, #endif // GMX_SIMD_HAVE_REAL /*! \brief LINCS projection, works on derivatives of the coordinates. */ -static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, - Lincs *lincsd, int th, - real *invmass, - ConstraintVariable econq, bool bCalcDHDL, - bool bCalcVir, tensor rmdf) +static void do_lincsp(const rvec* x, + rvec* f, + rvec* fp, + t_pbc* pbc, + Lincs* lincsd, + int th, + real* invmass, + ConstraintVariable econq, + bool bCalcDHDL, + bool bCalcVir, + tensor rmdf) { - const int b0 = lincsd->task[th].b0; - const int b1 = lincsd->task[th].b1; + const int b0 = lincsd->task[th].b0; + const int b1 = lincsd->task[th].b1; gmx::ArrayRef atoms = lincsd->atoms; gmx::ArrayRef r = lincsd->tmpv; gmx::ArrayRef blnr = lincsd->blnr; gmx::ArrayRef blbnb = lincsd->blbnb; - gmx::ArrayRef blc; - gmx::ArrayRef blmf; + gmx::ArrayRef blc; + gmx::ArrayRef blmf; if (econq != ConstraintVariable::Force) { /* Use mass-weighted parameters */ @@ -616,7 +612,7 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, * The only difference is that we always call pbc code, as with SIMD * the overhead of pbc computation (when not needed) is small. */ - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; /* Convert the pbc struct for SIMD */ set_pbc_simd(pbc, pbc_simd); @@ -624,11 +620,10 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, /* Compute normalized x i-j vectors, store in r. * Compute the inner product of r and xp i-j and store in rhs1. */ - calc_dr_x_f_simd(b0, b1, atoms, x, f, blc.data(), - pbc_simd, - as_rvec_array(r.data()), rhs1.data(), sol.data()); + calc_dr_x_f_simd(b0, b1, atoms, x, f, blc.data(), pbc_simd, as_rvec_array(r.data()), + rhs1.data(), sol.data()); -#else // GMX_SIMD_HAVE_REAL +#else // GMX_SIMD_HAVE_REAL /* Compute normalized i-j vectors */ if (pbc) @@ -649,22 +644,22 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, rvec_sub(x[atoms[b].index1], x[atoms[b].index2], dx); unitv(dx, r[b]); - } /* 16 ncons flops */ + } /* 16 ncons flops */ } for (int b = b0; b < b1; b++) { int i = atoms[b].index1; int j = atoms[b].index2; - real mvb = blc[b]*(r[b][0]*(f[i][0] - f[j][0]) + - r[b][1]*(f[i][1] - f[j][1]) + - r[b][2]*(f[i][2] - f[j][2])); + real mvb = blc[b] + * (r[b][0] * (f[i][0] - f[j][0]) + r[b][1] * (f[i][1] - f[j][1]) + + r[b][2] * (f[i][2] - f[j][2])); rhs1[b] = mvb; sol[b] = mvb; /* 7 flops */ } -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL if (lincsd->bTaskDep) { @@ -677,10 +672,10 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, /* Construct the (sparse) LINCS matrix */ for (int b = b0; b < b1; b++) { - for (int n = blnr[b]; n < blnr[b+1]; n++) + for (int n = blnr[b]; n < blnr[b + 1]; n++) { - blcc[n] = blmf[n]*::iprod(r[b], r[blbnb[n]]); - } /* 6 nr flops */ + blcc[n] = blmf[n] * ::iprod(r[b], r[blbnb[n]]); + } /* 6 nr flops */ } /* Together: 23*ncons + 6*nrtot flops */ @@ -718,7 +713,7 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, real dhdlambda = 0; for (int b = b0; b < b1; b++) { - dhdlambda -= sol[b]*lincsd->ddist[b]; + dhdlambda -= sol[b] * lincsd->ddist[b]; } lincsd->task[th].dhdlambda = dhdlambda; @@ -733,16 +728,16 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, */ for (int b = b0; b < b1; b++) { - const real mvb = lincsd->bllen[b]*sol[b]; + const real mvb = lincsd->bllen[b] * sol[b]; for (int i = 0; i < DIM; i++) { - const real tmp1 = mvb*r[b][i]; + const real tmp1 = mvb * r[b][i]; for (int j = 0; j < DIM; j++) { - rmdf[i][j] += tmp1*r[b][j]; + rmdf[i][j] += tmp1 * r[b][j]; } } - } /* 23 ncons flops */ + } /* 23 ncons flops */ } } @@ -751,18 +746,17 @@ static void do_lincsp(const rvec *x, rvec *f, rvec *fp, t_pbc *pbc, /*! \brief Calculate the constraint distance vectors r to project on from x. * * Determine the right-hand side of the matrix equation using coordinates xp. */ -static void gmx_simdcall -calc_dr_x_xp_simd(int b0, - int b1, - gmx::ArrayRef atoms, - const rvec * gmx_restrict x, - const rvec * gmx_restrict xp, - const real * gmx_restrict bllen, - const real * gmx_restrict blc, - const real * pbc_simd, - rvec * gmx_restrict r, - real * gmx_restrict rhs, - real * gmx_restrict sol) +static void gmx_simdcall calc_dr_x_xp_simd(int b0, + int b1, + gmx::ArrayRef atoms, + const rvec* gmx_restrict x, + const rvec* gmx_restrict xp, + const real* gmx_restrict bllen, + const real* gmx_restrict blc, + const real* pbc_simd, + rvec* gmx_restrict r, + real* gmx_restrict rhs, + real* gmx_restrict sol) { assert(b0 % GMX_SIMD_REAL_WIDTH == 0); alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset2[GMX_SIMD_REAL_WIDTH]; @@ -774,12 +768,12 @@ calc_dr_x_xp_simd(int b0, for (int bs = b0; bs < b1; bs += GMX_SIMD_REAL_WIDTH) { - SimdReal x0_S, y0_S, z0_S; - SimdReal x1_S, y1_S, z1_S; - SimdReal rx_S, ry_S, rz_S, n2_S, il_S; - SimdReal rxp_S, ryp_S, rzp_S, ip_S, rhs_S; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; + SimdReal x0_S, y0_S, z0_S; + SimdReal x1_S, y1_S, z1_S; + SimdReal rx_S, ry_S, rz_S, n2_S, il_S; + SimdReal rxp_S, ryp_S, rzp_S, ip_S, rhs_S; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { @@ -787,25 +781,25 @@ calc_dr_x_xp_simd(int b0, offset1[i] = atoms[bs + i].index2; } - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); rx_S = x0_S - x1_S; ry_S = y0_S - y1_S; rz_S = z0_S - z1_S; pbc_correct_dx_simd(&rx_S, &ry_S, &rz_S, pbc_simd); - n2_S = norm2(rx_S, ry_S, rz_S); - il_S = invsqrt(n2_S); + n2_S = norm2(rx_S, ry_S, rz_S); + il_S = invsqrt(n2_S); - rx_S = rx_S * il_S; - ry_S = ry_S * il_S; - rz_S = rz_S * il_S; + rx_S = rx_S * il_S; + ry_S = ry_S * il_S; + rz_S = rz_S * il_S; - transposeScatterStoreU<3>(reinterpret_cast(r + bs), offset2, rx_S, ry_S, rz_S); + transposeScatterStoreU<3>(reinterpret_cast(r + bs), offset2, rx_S, ry_S, rz_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(xp), offset0, &x0_S, &y0_S, &z0_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(xp), offset1, &x1_S, &y1_S, &z1_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(xp), offset0, &x0_S, &y0_S, &z0_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(xp), offset1, &x1_S, &y1_S, &z1_S); rxp_S = x0_S - x1_S; ryp_S = y0_S - y1_S; @@ -813,7 +807,7 @@ calc_dr_x_xp_simd(int b0, pbc_correct_dx_simd(&rxp_S, &ryp_S, &rzp_S, pbc_simd); - ip_S = iprod(rx_S, ry_S, rz_S, rxp_S, ryp_S, rzp_S); + ip_S = iprod(rx_S, ry_S, rz_S, rxp_S, ryp_S, rzp_S); rhs_S = load(blc + bs) * (ip_S - load(bllen + bs)); @@ -824,18 +818,17 @@ calc_dr_x_xp_simd(int b0, #endif // GMX_SIMD_HAVE_REAL /*! \brief Determine the distances and right-hand side for the next iteration. */ -gmx_unused static void calc_dist_iter( - int b0, - int b1, - gmx::ArrayRef atoms, - const rvec * gmx_restrict xp, - const real * gmx_restrict bllen, - const real * gmx_restrict blc, - const t_pbc * pbc, - real wfac, - real * gmx_restrict rhs, - real * gmx_restrict sol, - bool * bWarn) +gmx_unused static void calc_dist_iter(int b0, + int b1, + gmx::ArrayRef atoms, + const rvec* gmx_restrict xp, + const real* gmx_restrict bllen, + const real* gmx_restrict blc, + const t_pbc* pbc, + real wfac, + real* gmx_restrict rhs, + real* gmx_restrict sol, + bool* bWarn) { for (int b = b0; b < b1; b++) { @@ -849,9 +842,9 @@ gmx_unused static void calc_dist_iter( { rvec_sub(xp[atoms[b].index1], xp[atoms[b].index2], dx); } - real len2 = len*len; - real dlen2 = 2*len2 - ::norm2(dx); - if (dlen2 < wfac*len2) + real len2 = len * len; + real dlen2 = 2 * len2 - ::norm2(dx); + if (dlen2 < wfac * len2) { /* not race free - see detailed comment in caller */ *bWarn = TRUE; @@ -859,36 +852,35 @@ gmx_unused static void calc_dist_iter( real mvb; if (dlen2 > 0) { - mvb = blc[b]*(len - dlen2*gmx::invsqrt(dlen2)); + mvb = blc[b] * (len - dlen2 * gmx::invsqrt(dlen2)); } else { - mvb = blc[b]*len; + mvb = blc[b] * len; } - rhs[b] = mvb; - sol[b] = mvb; - } /* 20*ncons flops */ + rhs[b] = mvb; + sol[b] = mvb; + } /* 20*ncons flops */ } #if GMX_SIMD_HAVE_REAL /*! \brief As calc_dist_iter(), but using SIMD intrinsics. */ -static void gmx_simdcall -calc_dist_iter_simd(int b0, - int b1, - gmx::ArrayRef atoms, - const rvec * gmx_restrict x, - const real * gmx_restrict bllen, - const real * gmx_restrict blc, - const real * pbc_simd, - real wfac, - real * gmx_restrict rhs, - real * gmx_restrict sol, - bool * bWarn) +static void gmx_simdcall calc_dist_iter_simd(int b0, + int b1, + gmx::ArrayRef atoms, + const rvec* gmx_restrict x, + const real* gmx_restrict bllen, + const real* gmx_restrict blc, + const real* pbc_simd, + real wfac, + real* gmx_restrict rhs, + real* gmx_restrict sol, + bool* bWarn) { - SimdReal min_S(GMX_REAL_MIN); - SimdReal two_S(2.0); - SimdReal wfac_S(wfac); - SimdBool warn_S; + SimdReal min_S(GMX_REAL_MIN); + SimdReal two_S(2.0); + SimdReal wfac_S(wfac); + SimdBool warn_S; assert(b0 % GMX_SIMD_REAL_WIDTH == 0); @@ -897,12 +889,12 @@ calc_dist_iter_simd(int b0, for (int bs = b0; bs < b1; bs += GMX_SIMD_REAL_WIDTH) { - SimdReal x0_S, y0_S, z0_S; - SimdReal x1_S, y1_S, z1_S; - SimdReal rx_S, ry_S, rz_S, n2_S; - SimdReal len_S, len2_S, dlen2_S, lc_S, blc_S; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; + SimdReal x0_S, y0_S, z0_S; + SimdReal x1_S, y1_S, z1_S; + SimdReal rx_S, ry_S, rz_S, n2_S; + SimdReal len_S, len2_S, dlen2_S, lc_S, blc_S; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset0[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset1[GMX_SIMD_REAL_WIDTH]; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { @@ -910,8 +902,8 @@ calc_dist_iter_simd(int b0, offset1[i] = atoms[bs + i].index2; } - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); - gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset0, &x0_S, &y0_S, &z0_S); + gatherLoadUTransposeTSANSafe<3>(reinterpret_cast(x), offset1, &x1_S, &y1_S, &z1_S); rx_S = x0_S - x1_S; ry_S = y0_S - y1_S; @@ -919,14 +911,14 @@ calc_dist_iter_simd(int b0, pbc_correct_dx_simd(&rx_S, &ry_S, &rz_S, pbc_simd); - n2_S = norm2(rx_S, ry_S, rz_S); + n2_S = norm2(rx_S, ry_S, rz_S); - len_S = load(bllen + bs); - len2_S = len_S * len_S; + len_S = load(bllen + bs); + len2_S = len_S * len_S; dlen2_S = fms(two_S, len2_S, n2_S); - warn_S = warn_S || (dlen2_S < (wfac_S * len2_S)); + warn_S = warn_S || (dlen2_S < (wfac_S * len2_S)); /* Avoid 1/0 by taking the max with REAL_MIN. * Note: when dlen2 is close to zero (90 degree constraint rotation), @@ -934,11 +926,11 @@ calc_dist_iter_simd(int b0, */ dlen2_S = max(dlen2_S, min_S); - lc_S = fnma(dlen2_S, invsqrt(dlen2_S), len_S); + lc_S = fnma(dlen2_S, invsqrt(dlen2_S), len_S); - blc_S = load(blc + bs); + blc_S = load(blc + bs); - lc_S = blc_S * lc_S; + lc_S = blc_S * lc_S; store(rhs + bs, lc_S); store(sol + bs, lc_S); @@ -952,17 +944,24 @@ calc_dist_iter_simd(int b0, #endif // GMX_SIMD_HAVE_REAL //! Implements LINCS constraining. -static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, - Lincs *lincsd, int th, - const real *invmass, - const t_commrec *cr, - bool bCalcDHDL, - real wangle, bool *bWarn, - real invdt, rvec * gmx_restrict v, - bool bCalcVir, tensor vir_r_m_dr) +static void do_lincs(const rvec* x, + rvec* xp, + const matrix box, + t_pbc* pbc, + Lincs* lincsd, + int th, + const real* invmass, + const t_commrec* cr, + bool bCalcDHDL, + real wangle, + bool* bWarn, + real invdt, + rvec* gmx_restrict v, + bool bCalcVir, + tensor vir_r_m_dr) { - const int b0 = lincsd->task[th].b0; - const int b1 = lincsd->task[th].b1; + const int b0 = lincsd->task[th].b0; + const int b1 = lincsd->task[th].b1; gmx::ArrayRef atoms = lincsd->atoms; gmx::ArrayRef r = lincsd->tmpv; @@ -985,7 +984,7 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, * The only difference is that we always call pbc code, as with SIMD * the overhead of pbc computation (when not needed) is small. */ - alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9*GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real pbc_simd[9 * GMX_SIMD_REAL_WIDTH]; /* Convert the pbc struct for SIMD */ set_pbc_simd(pbc, pbc_simd); @@ -993,11 +992,10 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, /* Compute normalized x i-j vectors, store in r. * Compute the inner product of r and xp i-j and store in rhs1. */ - calc_dr_x_xp_simd(b0, b1, atoms, x, xp, bllen.data(), blc.data(), - pbc_simd, + calc_dr_x_xp_simd(b0, b1, atoms, x, xp, bllen.data(), blc.data(), pbc_simd, as_rvec_array(r.data()), rhs1.data(), sol.data()); -#else // GMX_SIMD_HAVE_REAL +#else // GMX_SIMD_HAVE_REAL if (pbc) { @@ -1009,9 +1007,9 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, unitv(dx, r[b]); pbc_dx_aiuc(pbc, xp[atoms[b].index1], xp[atoms[b].index2], dx); - real mvb = blc[b]*(::iprod(r[b], dx) - bllen[b]); - rhs1[b] = mvb; - sol[b] = mvb; + real mvb = blc[b] * (::iprod(r[b], dx) - bllen[b]); + rhs1[b] = mvb; + sol[b] = mvb; } } else @@ -1024,23 +1022,23 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, real tmp0 = x[i][0] - x[j][0]; real tmp1 = x[i][1] - x[j][1]; real tmp2 = x[i][2] - x[j][2]; - real rlen = gmx::invsqrt(tmp0*tmp0 + tmp1*tmp1 + tmp2*tmp2); - r[b][0] = rlen*tmp0; - r[b][1] = rlen*tmp1; - r[b][2] = rlen*tmp2; + real rlen = gmx::invsqrt(tmp0 * tmp0 + tmp1 * tmp1 + tmp2 * tmp2); + r[b][0] = rlen * tmp0; + r[b][1] = rlen * tmp1; + r[b][2] = rlen * tmp2; /* 16 ncons flops */ - real mvb = blc[b]*(r[b][0]*(xp[i][0] - xp[j][0]) + - r[b][1]*(xp[i][1] - xp[j][1]) + - r[b][2]*(xp[i][2] - xp[j][2]) - bllen[b]); - rhs1[b] = mvb; - sol[b] = mvb; + real mvb = blc[b] + * (r[b][0] * (xp[i][0] - xp[j][0]) + r[b][1] * (xp[i][1] - xp[j][1]) + + r[b][2] * (xp[i][2] - xp[j][2]) - bllen[b]); + rhs1[b] = mvb; + sol[b] = mvb; /* 10 flops */ } /* Together: 26*ncons + 6*nrtot flops */ } -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL if (lincsd->bTaskDep) { @@ -1053,9 +1051,9 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, /* Construct the (sparse) LINCS matrix */ for (int b = b0; b < b1; b++) { - for (int n = blnr[b]; n < blnr[b+1]; n++) + for (int n = blnr[b]; n < blnr[b + 1]; n++) { - blcc[n] = blmf[n]*gmx::dot(r[b], r[blbnb[n]]); + blcc[n] = blmf[n] * gmx::dot(r[b], r[blbnb[n]]); } } /* Together: 26*ncons + 6*nrtot flops */ @@ -1073,9 +1071,9 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, #else for (int b = b0; b < b1; b++) { - mlambda[b] = blc[b]*sol[b]; + mlambda[b] = blc[b] * sol[b]; } -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL /* Update the coordinates */ lincs_update_atoms(lincsd, th, 1.0, mlambda, r, invmass, xp); @@ -1086,8 +1084,8 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, real wfac; - wfac = std::cos(DEG2RAD*wangle); - wfac = wfac*wfac; + wfac = std::cos(DEG2RAD * wangle); + wfac = wfac * wfac; for (int iter = 0; iter < lincsd->nIter; iter++) { @@ -1110,15 +1108,13 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, } #if GMX_SIMD_HAVE_REAL - calc_dist_iter_simd(b0, b1, atoms, - xp, bllen.data(), blc.data(), pbc_simd, wfac, + calc_dist_iter_simd(b0, b1, atoms, xp, bllen.data(), blc.data(), pbc_simd, wfac, rhs1.data(), sol.data(), bWarn); #else - calc_dist_iter(b0, b1, atoms, xp, - bllen.data(), blc.data(), pbc, wfac, - rhs1.data(), sol.data(), bWarn); + calc_dist_iter(b0, b1, atoms, xp, bllen.data(), blc.data(), pbc, wfac, rhs1.data(), + sol.data(), bWarn); /* 20*ncons flops */ -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL lincs_matrix_expand(*lincsd, lincsd->task[th], blcc, rhs1, rhs2, sol); /* nrec*(ncons+2*nrtot) flops */ @@ -1135,11 +1131,11 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, #else for (int b = b0; b < b1; b++) { - real mvb = blc[b]*sol[b]; - blc_sol[b] = mvb; + real mvb = blc[b] * sol[b]; + blc_sol[b] = mvb; mlambda[b] += mvb; } -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL /* Update the coordinates */ lincs_update_atoms(lincsd, th, 1.0, blc_sol, r, invmass, xp); @@ -1164,7 +1160,7 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, /* Only account for local atoms */ for (int b = b0; b < b1; b++) { - mlambda[b] *= 0.5*nlocat[b]; + mlambda[b] *= 0.5 * nlocat[b]; } } @@ -1176,7 +1172,7 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, /* Note that this this is dhdl*dt^2, the dt^2 factor is corrected * later after the contributions are reduced over the threads. */ - dhdl -= lincsd->mlambda[b]*lincsd->ddist[b]; + dhdl -= lincsd->mlambda[b] * lincsd->ddist[b]; } lincsd->task[th].dhdlambda = dhdl; } @@ -1186,16 +1182,16 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, /* Constraint virial */ for (int b = b0; b < b1; b++) { - real tmp0 = -bllen[b]*mlambda[b]; + real tmp0 = -bllen[b] * mlambda[b]; for (int i = 0; i < DIM; i++) { - real tmp1 = tmp0*r[b][i]; + real tmp1 = tmp0 * r[b][i]; for (int j = 0; j < DIM; j++) { - vir_r_m_dr[i][j] -= tmp1*r[b][j]; + vir_r_m_dr[i][j] -= tmp1 * r[b][j]; } } - } /* 22 ncons flops */ + } /* 22 ncons flops */ } /* Total: @@ -1210,11 +1206,7 @@ static void do_lincs(const rvec *x, rvec *xp, const matrix box, t_pbc *pbc, } /*! \brief Sets the elements in the LINCS matrix for task task. */ -static void set_lincs_matrix_task(Lincs *li, - Task *li_task, - const real *invmass, - int *ncc_triangle, - int *nCrossTaskTriangles) +static void set_lincs_matrix_task(Lincs* li, Task* li_task, const real* invmass, int* ncc_triangle, int* nCrossTaskTriangles) { /* Construct the coupling coefficient matrix blmf */ li_task->ntriangle = 0; @@ -1255,44 +1247,44 @@ static void set_lincs_matrix_task(Lincs *li, center = a2; end = a1; } - li->blmf[n] = sign*invmass[center]*li->blc[i]*li->blc[k]; - li->blmf1[n] = sign*0.5; + li->blmf[n] = sign * invmass[center] * li->blc[i] * li->blc[k]; + li->blmf1[n] = sign * 0.5; if (li->ncg_triangle > 0) { /* Look for constraint triangles */ for (int nk = li->blnr[k]; nk < li->blnr[k + 1]; nk++) { const int kk = li->blbnb[nk]; - if (kk != i && kk != k && - (li->atoms[kk].index1 == end || - li->atoms[kk].index2 == end)) + if (kk != i && kk != k && (li->atoms[kk].index1 == end || li->atoms[kk].index2 == end)) { /* Check if the constraints in this triangle actually * belong to a different task. We still assign them * here, since it's convenient for the triangle * iterations, but we then need an extra barrier. */ - if (k < li_task->b0 || k >= li_task->b1 || - kk < li_task->b0 || kk >= li_task->b1) + if (k < li_task->b0 || k >= li_task->b1 || kk < li_task->b0 || kk >= li_task->b1) { (*nCrossTaskTriangles)++; } - if (li_task->ntriangle == 0 || - li_task->triangle[li_task->ntriangle - 1] < i) + if (li_task->ntriangle == 0 || li_task->triangle[li_task->ntriangle - 1] < i) { /* Add this constraint to the triangle list */ li_task->triangle[li_task->ntriangle] = i; li_task->tri_bits[li_task->ntriangle] = 0; li_task->ntriangle++; - if (li->blnr[i+1] - li->blnr[i] > static_cast(sizeof(li_task->tri_bits[0])*8 - 1)) + if (li->blnr[i + 1] - li->blnr[i] + > static_cast(sizeof(li_task->tri_bits[0]) * 8 - 1)) { - gmx_fatal(FARGS, "A constraint is connected to %d constraints, this is more than the %zu allowed for constraints participating in triangles", - li->blnr[i+1] - li->blnr[i], - sizeof(li_task->tri_bits[0])*8-1); + gmx_fatal(FARGS, + "A constraint is connected to %d constraints, this is " + "more than the %zu allowed for constraints participating " + "in triangles", + li->blnr[i + 1] - li->blnr[i], + sizeof(li_task->tri_bits[0]) * 8 - 1); } } - li_task->tri_bits[li_task->ntriangle-1] |= (1 << (n - li->blnr[i])); + li_task->tri_bits[li_task->ntriangle - 1] |= (1 << (n - li->blnr[i])); (*ncc_triangle)++; } } @@ -1302,7 +1294,7 @@ static void set_lincs_matrix_task(Lincs *li, } /*! \brief Sets the elements in the LINCS matrix. */ -static void set_lincs_matrix(Lincs *li, real *invmass, real lambda) +static void set_lincs_matrix(Lincs* li, real* invmass, real lambda) { const real invsqrt2 = 0.7071067811865475244; @@ -1321,11 +1313,10 @@ static void set_lincs_matrix(Lincs *li, real *invmass, real lambda) { try { - set_lincs_matrix_task(li, &li->task[th], invmass, - &ncc_triangle, &nCrossTaskTriangles); + set_lincs_matrix_task(li, &li->task[th], invmass, &ncc_triangle, &nCrossTaskTriangles); ntriangle += li->task[th].ntriangle; } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } li->ntriangle = ntriangle; li->ncc_triangle = ncc_triangle; @@ -1333,13 +1324,13 @@ static void set_lincs_matrix(Lincs *li, real *invmass, real lambda) if (debug) { - fprintf(debug, "The %d constraints participate in %d triangles\n", - li->nc, li->ntriangle); - fprintf(debug, "There are %d constraint couplings, of which %d in triangles\n", - li->ncc, li->ncc_triangle); + fprintf(debug, "The %d constraints participate in %d triangles\n", li->nc, li->ntriangle); + fprintf(debug, "There are %d constraint couplings, of which %d in triangles\n", li->ncc, + li->ncc_triangle); if (li->ntriangle > 0 && li->ntask > 1) { - fprintf(debug, "%d constraint triangles contain constraints assigned to different tasks\n", + fprintf(debug, + "%d constraint triangles contain constraints assigned to different tasks\n", nCrossTaskTriangles); } } @@ -1351,15 +1342,14 @@ static void set_lincs_matrix(Lincs *li, real *invmass, real lambda) } //! Finds all triangles of atoms that share constraints to a central atom. -static int count_triangle_constraints(const InteractionLists &ilist, - const t_blocka &at2con) +static int count_triangle_constraints(const InteractionLists& ilist, const t_blocka& at2con) { - int ncon1, ncon_tot; - int c0, n1, c1, ac1, n2, c2; - int ncon_triangle; + int ncon1, ncon_tot; + int c0, n1, c1, ac1, n2, c2; + int ncon_triangle; - ncon1 = ilist[F_CONSTR].size()/3; - ncon_tot = ncon1 + ilist[F_CONSTRNC].size()/3; + ncon1 = ilist[F_CONSTR].size() / 3; + ncon_tot = ncon1 + ilist[F_CONSTRNC].size() / 3; gmx::ArrayRef ia1 = ilist[F_CONSTR].iatoms; gmx::ArrayRef ia2 = ilist[F_CONSTRNC].iatoms; @@ -1368,15 +1358,15 @@ static int count_triangle_constraints(const InteractionLists &ilist, for (c0 = 0; c0 < ncon_tot; c0++) { bool bTriangle = FALSE; - const int *iap = constr_iatomptr(ia1, ia2, c0); + const int* iap = constr_iatomptr(ia1, ia2, c0); const int a00 = iap[1]; const int a01 = iap[2]; - for (n1 = at2con.index[a01]; n1 < at2con.index[a01+1]; n1++) + for (n1 = at2con.index[a01]; n1 < at2con.index[a01 + 1]; n1++) { c1 = at2con.a[n1]; if (c1 != c0) { - const int *iap = constr_iatomptr(ia1, ia2, c1); + const int* iap = constr_iatomptr(ia1, ia2, c1); const int a10 = iap[1]; const int a11 = iap[2]; if (a10 == a01) @@ -1387,12 +1377,12 @@ static int count_triangle_constraints(const InteractionLists &ilist, { ac1 = a10; } - for (n2 = at2con.index[ac1]; n2 < at2con.index[ac1+1]; n2++) + for (n2 = at2con.index[ac1]; n2 < at2con.index[ac1 + 1]; n2++) { c2 = at2con.a[n2]; if (c2 != c0 && c2 != c1) { - const int *iap = constr_iatomptr(ia1, ia2, c2); + const int* iap = constr_iatomptr(ia1, ia2, c2); const int a20 = iap[1]; const int a21 = iap[2]; if (a20 == a00 || a21 == a00) @@ -1413,14 +1403,13 @@ static int count_triangle_constraints(const InteractionLists &ilist, } //! Finds sequences of sequential constraints. -static bool more_than_two_sequential_constraints(const InteractionLists &ilist, - const t_blocka &at2con) +static bool more_than_two_sequential_constraints(const InteractionLists& ilist, const t_blocka& at2con) { - int ncon1, ncon_tot, c; - bool bMoreThanTwoSequentialConstraints; + int ncon1, ncon_tot, c; + bool bMoreThanTwoSequentialConstraints; - ncon1 = ilist[F_CONSTR].size()/3; - ncon_tot = ncon1 + ilist[F_CONSTRNC].size()/3; + ncon1 = ilist[F_CONSTR].size() / 3; + ncon_tot = ncon1 + ilist[F_CONSTRNC].size() / 3; gmx::ArrayRef ia1 = ilist[F_CONSTR].iatoms; gmx::ArrayRef ia2 = ilist[F_CONSTRNC].iatoms; @@ -1428,12 +1417,11 @@ static bool more_than_two_sequential_constraints(const InteractionLists &ilist, bMoreThanTwoSequentialConstraints = FALSE; for (c = 0; c < ncon_tot && !bMoreThanTwoSequentialConstraints; c++) { - const int *iap = constr_iatomptr(ia1, ia2, c); + const int* iap = constr_iatomptr(ia1, ia2, c); const int a1 = iap[1]; const int a2 = iap[2]; /* Check if this constraint has constraints connected at both atoms */ - if (at2con.index[a1+1] - at2con.index[a1] > 1 && - at2con.index[a2+1] - at2con.index[a2] > 1) + if (at2con.index[a1 + 1] - at2con.index[a1] > 1 && at2con.index[a2 + 1] - at2con.index[a2] > 1) { bMoreThanTwoSequentialConstraints = TRUE; } @@ -1442,25 +1430,26 @@ static bool more_than_two_sequential_constraints(const InteractionLists &ilist, return bMoreThanTwoSequentialConstraints; } -Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, - int nflexcon_global, ArrayRef at2con, - bool bPLINCS, int nIter, int nProjOrder) +Lincs* init_lincs(FILE* fplog, + const gmx_mtop_t& mtop, + int nflexcon_global, + ArrayRef at2con, + bool bPLINCS, + int nIter, + int nProjOrder) { // TODO this should become a unique_ptr - Lincs *li; - bool bMoreThanTwoSeq; + Lincs* li; + bool bMoreThanTwoSeq; if (fplog) { - fprintf(fplog, "\nInitializing%s LINear Constraint Solver\n", - bPLINCS ? " Parallel" : ""); + fprintf(fplog, "\nInitializing%s LINear Constraint Solver\n", bPLINCS ? " Parallel" : ""); } li = new Lincs; - li->ncg = - gmx_mtop_ftype_count(mtop, F_CONSTR) + - gmx_mtop_ftype_count(mtop, F_CONSTRNC); + li->ncg = gmx_mtop_ftype_count(mtop, F_CONSTR) + gmx_mtop_ftype_count(mtop, F_CONSTRNC); li->ncg_flex = nflexcon_global; li->nIter = nIter; @@ -1471,23 +1460,19 @@ Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, { for (int a = 0; a < mtop.moltype[mt].atoms.nr; a++) { - li->max_connect = std::max(li->max_connect, - at2con[mt].index[a + 1] - at2con[mt].index[a]); + li->max_connect = std::max(li->max_connect, at2con[mt].index[a + 1] - at2con[mt].index[a]); } } li->ncg_triangle = 0; bMoreThanTwoSeq = FALSE; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; - li->ncg_triangle += - molb.nmol* - count_triangle_constraints(molt.ilist, at2con[molb.type]); + li->ncg_triangle += molb.nmol * count_triangle_constraints(molt.ilist, at2con[molb.type]); - if (!bMoreThanTwoSeq && - more_than_two_sequential_constraints(molt.ilist, at2con[molb.type])) + if (!bMoreThanTwoSeq && more_than_two_sequential_constraints(molt.ilist, at2con[molb.type])) { bMoreThanTwoSeq = TRUE; } @@ -1504,8 +1489,7 @@ Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, if (debug && bPLINCS) { - fprintf(debug, "PLINCS communication before each iteration: %d\n", - static_cast(li->bCommIter)); + fprintf(debug, "PLINCS communication before each iteration: %d\n", static_cast(li->bCommIter)); } /* LINCS can run on any number of threads. @@ -1518,8 +1502,8 @@ Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, li->bTaskDep = (li->ntask > 1 && bMoreThanTwoSeq); if (debug) { - fprintf(debug, "LINCS: using %d threads, tasks are %sdependent\n", - li->ntask, li->bTaskDep ? "" : "in"); + fprintf(debug, "LINCS: using %d threads, tasks are %sdependent\n", li->ntask, + li->bTaskDep ? "" : "in"); } if (li->ntask == 1) { @@ -1545,7 +1529,8 @@ Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, fprintf(fplog, "The number of constraints is %d\n", li->ncg); if (bPLINCS) { - fprintf(fplog, "There are constraints between atoms in different decomposition domains,\n" + fprintf(fplog, + "There are constraints between atoms in different decomposition domains,\n" "will communicate selected coordinates each lincs iteration\n"); } if (li->ncg_triangle > 0) @@ -1561,20 +1546,20 @@ Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, return li; } -void done_lincs(Lincs *li) +void done_lincs(Lincs* li) { delete li; } /*! \brief Sets up the work division over the threads. */ -static void lincs_thread_setup(Lincs *li, int natoms) +static void lincs_thread_setup(Lincs* li, int natoms) { li->atf.resize(natoms); gmx::ArrayRef atf = li->atf; /* Clear the atom flags */ - for (gmx_bitmask_t &mask : atf) + for (gmx_bitmask_t& mask : atf) { bitmask_clear(&mask); } @@ -1586,7 +1571,7 @@ static void lincs_thread_setup(Lincs *li, int natoms) for (int th = 0; th < li->ntask; th++) { - const Task *li_task = &li->task[th]; + const Task* li_task = &li->task[th]; /* For each atom set a flag for constraints from each */ for (int b = li_task->b0; b < li_task->b1; b++) @@ -1601,9 +1586,9 @@ static void lincs_thread_setup(Lincs *li, int natoms) { try { - Task *li_task; - gmx_bitmask_t mask; - int b; + Task* li_task; + gmx_bitmask_t mask; + int b; li_task = &li->task[th]; @@ -1616,8 +1601,8 @@ static void lincs_thread_setup(Lincs *li, int natoms) /* We let the constraint with the lowest thread index * operate on atoms with constraints from multiple threads. */ - if (bitmask_is_disjoint(atf[li->atoms[b].index1], mask) && - bitmask_is_disjoint(atf[li->atoms[b].index2], mask)) + if (bitmask_is_disjoint(atf[li->atoms[b].index1], mask) + && bitmask_is_disjoint(atf[li->atoms[b].index2], mask)) { /* Add the constraint to the local atom update index */ li_task->ind.push_back(b); @@ -1629,18 +1614,18 @@ static void lincs_thread_setup(Lincs *li, int natoms) } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* We need to copy all constraints which have not be assigned * to a thread to a separate list which will be handled by one thread. */ - Task *li_m = &li->task[li->ntask]; + Task* li_m = &li->task[li->ntask]; li_m->ind.clear(); for (int th = 0; th < li->ntask; th++) { - const Task &li_task = li->task[th]; + const Task& li_task = li->task[th]; for (int ind_r : li_task.ind_r) { @@ -1649,24 +1634,18 @@ static void lincs_thread_setup(Lincs *li, int natoms) if (debug) { - fprintf(debug, "LINCS thread %d: %zu constraints\n", - th, li_task.ind.size()); + fprintf(debug, "LINCS thread %d: %zu constraints\n", th, li_task.ind.size()); } } if (debug) { - fprintf(debug, "LINCS thread r: %zu constraints\n", - li_m->ind.size()); + fprintf(debug, "LINCS thread r: %zu constraints\n", li_m->ind.size()); } } //! Assign a constraint. -static void assign_constraint(Lincs *li, - int constraint_index, - int a1, int a2, - real lenA, real lenB, - const t_blocka *at2con) +static void assign_constraint(Lincs* li, int constraint_index, int a1, int a2, real lenA, real lenB, const t_blocka* at2con) { int con; @@ -1675,8 +1654,8 @@ static void assign_constraint(Lincs *li, /* Make an mapping of local topology constraint index to LINCS index */ li->con_index[constraint_index] = con; - li->bllen0[con] = lenA; - li->ddist[con] = lenB - lenA; + li->bllen0[con] = lenA; + li->ddist[con] = lenB - lenA; /* Set the length to the topology A length */ li->bllen[con] = lenA; li->atoms[con].index1 = a1; @@ -1685,9 +1664,8 @@ static void assign_constraint(Lincs *li, /* Make space in the constraint connection matrix for constraints * connected to both end of the current constraint. */ - li->ncc += - at2con->index[a1 + 1] - at2con->index[a1] - 1 + - at2con->index[a2 + 1] - at2con->index[a2] - 1; + li->ncc += at2con->index[a1 + 1] - at2con->index[a1] - 1 + at2con->index[a2 + 1] + - at2con->index[a2] - 1; li->blnr[con + 1] = li->ncc; @@ -1697,12 +1675,13 @@ static void assign_constraint(Lincs *li, /*! \brief Check if constraint with topology index constraint_index is connected * to other constraints, and if so add those connected constraints to our task. */ -static void check_assign_connected(Lincs *li, - const t_iatom *iatom, - const t_idef &idef, - bool bDynamics, - int a1, int a2, - const t_blocka *at2con) +static void check_assign_connected(Lincs* li, + const t_iatom* iatom, + const t_idef& idef, + bool bDynamics, + int a1, + int a2, + const t_blocka* at2con) { /* Currently this function only supports constraint groups * in which all constraints share at least one atom @@ -1730,13 +1709,13 @@ static void check_assign_connected(Lincs *li, int type; real lenA, lenB; - type = iatom[cc*3]; + type = iatom[cc * 3]; lenA = idef.iparams[type].constr.dA; lenB = idef.iparams[type].constr.dB; if (bDynamics || lenA != 0 || lenB != 0) { - assign_constraint(li, cc, iatom[3*cc + 1], iatom[3*cc + 2], lenA, lenB, at2con); + assign_constraint(li, cc, iatom[3 * cc + 1], iatom[3 * cc + 2], lenA, lenB, at2con); } } } @@ -1746,13 +1725,14 @@ static void check_assign_connected(Lincs *li, /*! \brief Check if constraint with topology index constraint_index is involved * in a constraint triangle, and if so add the other two constraints * in the triangle to our task. */ -static void check_assign_triangle(Lincs *li, - const t_iatom *iatom, - const t_idef &idef, - bool bDynamics, - int constraint_index, - int a1, int a2, - const t_blocka *at2con) +static void check_assign_triangle(Lincs* li, + const t_iatom* iatom, + const t_idef& idef, + bool bDynamics, + int constraint_index, + int a1, + int a2, + const t_blocka* at2con) { int nca, cc[32], ca[32], k; int c_triangle[2] = { -1, -1 }; @@ -1767,8 +1747,8 @@ static void check_assign_triangle(Lincs *li, { int aa1, aa2; - aa1 = iatom[c*3 + 1]; - aa2 = iatom[c*3 + 2]; + aa1 = iatom[c * 3 + 1]; + aa2 = iatom[c * 3 + 2]; if (aa1 != a1) { cc[nca] = c; @@ -1793,8 +1773,8 @@ static void check_assign_triangle(Lincs *li, { int aa1, aa2, i; - aa1 = iatom[c*3 + 1]; - aa2 = iatom[c*3 + 2]; + aa1 = iatom[c * 3 + 1]; + aa2 = iatom[c * 3 + 2]; if (aa1 != a2) { for (i = 0; i < nca; i++) @@ -1832,7 +1812,7 @@ static void check_assign_triangle(Lincs *li, int i, type; real lenA, lenB; - i = c_triangle[end]*3; + i = c_triangle[end] * 3; type = iatom[i]; lenA = idef.iparams[type].constr.dA; lenB = idef.iparams[type].constr.dB; @@ -1847,17 +1827,14 @@ static void check_assign_triangle(Lincs *li, } //! Sets matrix indices. -static void set_matrix_indices(Lincs *li, - const Task &li_task, - const t_blocka *at2con, - bool bSortMatrix) +static void set_matrix_indices(Lincs* li, const Task& li_task, const t_blocka* at2con, bool bSortMatrix) { for (int b = li_task.b0; b < li_task.b1; b++) { const int a1 = li->atoms[b].index1; const int a2 = li->atoms[b].index2; - int i = li->blnr[b]; + int i = li->blnr[b]; for (int k = at2con->index[a1]; k < at2con->index[a1 + 1]; k++) { int concon = li->con_index[at2con->a[k]]; @@ -1878,20 +1855,16 @@ static void set_matrix_indices(Lincs *li, if (bSortMatrix) { /* Order the blbnb matrix to optimize memory access */ - std::sort(li->blbnb.begin()+li->blnr[b], li->blbnb.begin()+li->blnr[b+1]); + std::sort(li->blbnb.begin() + li->blnr[b], li->blbnb.begin() + li->blnr[b + 1]); } } } -void set_lincs(const t_idef &idef, - const t_mdatoms &md, - bool bDynamics, - const t_commrec *cr, - Lincs *li) +void set_lincs(const t_idef& idef, const t_mdatoms& md, bool bDynamics, const t_commrec* cr, Lincs* li) { - int natoms; - t_blocka at2con; - t_iatom *iatom; + int natoms; + t_blocka at2con; + t_iatom* iatom; li->nc_real = 0; li->nc = 0; @@ -1901,8 +1874,8 @@ void set_lincs(const t_idef &idef, */ for (int i = 0; i < li->ntask; i++) { - li->task[i].b0 = 0; - li->task[i].b1 = 0; + li->task[i].b0 = 0; + li->task[i].b1 = 0; li->task[i].ind.clear(); } if (li->ntask > 1) @@ -1942,13 +1915,12 @@ void set_lincs(const t_idef &idef, natoms = md.homenr; } - at2con = make_at2con(natoms, idef.il, idef.iparams, - flexibleConstraintTreatment(bDynamics)); + at2con = make_at2con(natoms, idef.il, idef.iparams, flexibleConstraintTreatment(bDynamics)); - const int ncon_tot = idef.il[F_CONSTR].nr/3; + const int ncon_tot = idef.il[F_CONSTR].nr / 3; /* Ensure we have enough padding for aligned loads for each thread */ - const int numEntries = ncon_tot + li->ntask*simd_width; + const int numEntries = ncon_tot + li->ntask * simd_width; li->con_index.resize(numEntries); li->bllen0.resize(numEntries); li->ddist.resize(numEntries); @@ -1970,7 +1942,7 @@ void set_lincs(const t_idef &idef, iatom = idef.il[F_CONSTR].iatoms; - li->blnr[0] = li->ncc; + li->blnr[0] = li->ncc; /* Assign the constraints for li->ntask LINCS tasks. * We target a uniform distribution of constraints over the tasks. @@ -1992,7 +1964,7 @@ void set_lincs(const t_idef &idef, /* Set the target constraint count per task to exactly uniform, * this might be overridden below. */ - int ncon_target = (ncon_assign + li->ntask - 1)/li->ntask; + int ncon_target = (ncon_assign + li->ntask - 1) / li->ntask; /* Mark all constraints as unassigned by setting their index to -1 */ for (int con = 0; con < ncon_tot; con++) @@ -2003,7 +1975,7 @@ void set_lincs(const t_idef &idef, int con = 0; for (int th = 0; th < li->ntask; th++) { - Task *li_task; + Task* li_task; li_task = &li->task[th]; @@ -2021,9 +1993,10 @@ void set_lincs(const t_idef &idef, * There are several ways to round here, we choose the one * that alternates block sizes, which helps with Intel HT. */ - ncon_target = ((ncon_assign*(th + 1))/li->ntask - li->nc_real + GMX_SIMD_REAL_WIDTH - 1) & ~(GMX_SIMD_REAL_WIDTH - 1); + ncon_target = ((ncon_assign * (th + 1)) / li->ntask - li->nc_real + GMX_SIMD_REAL_WIDTH - 1) + & ~(GMX_SIMD_REAL_WIDTH - 1); } -#endif // GMX_SIMD==2 && GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD==2 && GMX_SIMD_HAVE_REAL /* Continue filling the arrays where we left off with the previous task, * including padding for SIMD. @@ -2037,11 +2010,11 @@ void set_lincs(const t_idef &idef, int type, a1, a2; real lenA, lenB; - type = iatom[3*con]; - a1 = iatom[3*con + 1]; - a2 = iatom[3*con + 2]; - lenA = idef.iparams[type].constr.dA; - lenB = idef.iparams[type].constr.dB; + type = iatom[3 * con]; + a1 = iatom[3 * con + 1]; + a2 = iatom[3 * con + 2]; + lenA = idef.iparams[type].constr.dA; + lenB = idef.iparams[type].constr.dB; /* Skip the flexible constraints when not doing dynamics */ if (bDynamics || lenA != 0 || lenB != 0) { @@ -2052,16 +2025,14 @@ void set_lincs(const t_idef &idef, /* We can generate independent tasks. Check if we * need to assign connected constraints to our task. */ - check_assign_connected(li, iatom, idef, bDynamics, - a1, a2, &at2con); + check_assign_connected(li, iatom, idef, bDynamics, a1, a2, &at2con); } if (li->ntask > 1 && li->ncg_triangle > 0) { /* Ensure constraints in one triangle are assigned * to the same task. */ - check_assign_triangle(li, iatom, idef, bDynamics, - con, a1, a2, &at2con); + check_assign_triangle(li, iatom, idef, bDynamics, con, a1, a2, &at2con); } } } @@ -2079,15 +2050,15 @@ void set_lincs(const t_idef &idef, */ int i, last; - li->nc = ((li_task->b1 + simd_width - 1)/simd_width)*simd_width; + li->nc = ((li_task->b1 + simd_width - 1) / simd_width) * simd_width; last = li_task->b1 - 1; for (i = li_task->b1; i < li->nc; i++) { - li->atoms[i] = li->atoms[last]; - li->bllen0[i] = li->bllen0[last]; - li->ddist[i] = li->ddist[last]; - li->bllen[i] = li->bllen[last]; - li->blnr[i + 1] = li->blnr[last + 1]; + li->atoms[i] = li->atoms[last]; + li->bllen0[i] = li->bllen0[last]; + li->ddist[i] = li->ddist[last]; + li->bllen[i] = li->bllen[last]; + li->blnr[i + 1] = li->blnr[last + 1]; } } @@ -2096,8 +2067,7 @@ void set_lincs(const t_idef &idef, if (debug) { - fprintf(debug, "LINCS task %d constraints %d - %d\n", - th, li_task->b0, li_task->b1); + fprintf(debug, "LINCS task %d constraints %d - %d\n", th, li_task->b0, li_task->b1); } } @@ -2117,7 +2087,7 @@ void set_lincs(const t_idef &idef, { try { - Task &li_task = li->task[th]; + Task& li_task = li->task[th]; if (li->ncg_triangle > 0) { @@ -2128,7 +2098,7 @@ void set_lincs(const t_idef &idef, set_matrix_indices(li, li_task, &at2con, bSortMatrix); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } done_blocka(&at2con); @@ -2159,8 +2129,8 @@ void set_lincs(const t_idef &idef, if (debug) { - fprintf(debug, "Number of constraints is %d, padded %d, couplings %d\n", - li->nc_real, li->nc, li->ncc); + fprintf(debug, "Number of constraints is %d, padded %d, couplings %d\n", li->nc_real, + li->nc, li->ncc); } if (li->ntask > 1) @@ -2172,12 +2142,18 @@ void set_lincs(const t_idef &idef, } //! Issues a warning when LINCS constraints cannot be satisfied. -static void lincs_warning(gmx_domdec_t *dd, const rvec *x, rvec *xprime, t_pbc *pbc, - int ncons, gmx::ArrayRef atoms, - gmx::ArrayRef bllen, real wangle, - int maxwarn, int *warncount) +static void lincs_warning(gmx_domdec_t* dd, + const rvec* x, + rvec* xprime, + t_pbc* pbc, + int ncons, + gmx::ArrayRef atoms, + gmx::ArrayRef bllen, + real wangle, + int maxwarn, + int* warncount) { - real wfac = std::cos(DEG2RAD*wangle); + real wfac = std::cos(DEG2RAD * wangle); fprintf(stderr, "bonds that rotated more than %g degrees:\n" @@ -2202,13 +2178,11 @@ static void lincs_warning(gmx_domdec_t *dd, const rvec *x, rvec *xprime, t_pbc * } real d0 = norm(v0); real d1 = norm(v1); - real cosine = ::iprod(v0, v1)/(d0*d1); + real cosine = ::iprod(v0, v1) / (d0 * d1); if (cosine < wfac) { - fprintf(stderr, - " %6d %6d %5.1f %8.4f %8.4f %8.4f\n", - ddglatnr(dd, i), ddglatnr(dd, j), - RAD2DEG*std::acos(cosine), d0, d1, bllen[b]); + fprintf(stderr, " %6d %6d %5.1f %8.4f %8.4f %8.4f\n", ddglatnr(dd, i), + ddglatnr(dd, j), RAD2DEG * std::acos(cosine), d0, d1, bllen[b]); if (!std::isfinite(d1)) { gmx_fatal(FARGS, "Bond length not finite."); @@ -2231,21 +2205,18 @@ struct LincsDeviations //! Sum over all bonds in this domain of the squared relative deviation real sumSquaredDeviation = 0; //! Index of bond with max deviation - int indexOfMaxDeviation = -1; + int indexOfMaxDeviation = -1; //! Number of bonds constrained in this domain - int numConstraints = 0; + int numConstraints = 0; }; //! Determine how well the constraints have been satisfied. -static LincsDeviations -makeLincsDeviations(const Lincs &lincsd, - const rvec *x, - const t_pbc *pbc) +static LincsDeviations makeLincsDeviations(const Lincs& lincsd, const rvec* x, const t_pbc* pbc) { - LincsDeviations result; - const ArrayRef atoms = lincsd.atoms; - const ArrayRef bllen = lincsd.bllen; - const ArrayRef nlocat = lincsd.nlocat; + LincsDeviations result; + const ArrayRef atoms = lincsd.atoms; + const ArrayRef bllen = lincsd.bllen; + const ArrayRef nlocat = lincsd.nlocat; for (int task = 0; task < lincsd.ntask; task++) { @@ -2261,8 +2232,8 @@ makeLincsDeviations(const Lincs &lincsd, rvec_sub(x[atoms[b].index1], x[atoms[b].index2], dx); } real r2 = ::norm2(dx); - real len = r2*gmx::invsqrt(r2); - real d = std::abs(len/bllen[b] - 1.0_real); + real len = r2 * gmx::invsqrt(r2); + real d = std::abs(len / bllen[b] - 1.0_real); if (d > result.maxDeviation && (nlocat.empty() || nlocat[b])) { result.maxDeviation = d; @@ -2270,39 +2241,47 @@ makeLincsDeviations(const Lincs &lincsd, } if (nlocat.empty()) { - result.sumSquaredDeviation += d*d; + result.sumSquaredDeviation += d * d; result.numConstraints++; } else { - result.sumSquaredDeviation += nlocat[b]*d*d; - result.numConstraints += nlocat[b]; + result.sumSquaredDeviation += nlocat[b] * d * d; + result.numConstraints += nlocat[b]; } } } if (!nlocat.empty()) { - result.numConstraints /= 2; + result.numConstraints /= 2; result.sumSquaredDeviation *= 0.5; } return result; } -bool constrain_lincs(bool computeRmsd, - const t_inputrec &ir, - int64_t step, - Lincs *lincsd, const t_mdatoms &md, - const t_commrec *cr, - const gmx_multisim_t *ms, - const rvec *x, rvec *xprime, rvec *min_proj, - const matrix box, t_pbc *pbc, - real lambda, real *dvdlambda, - real invdt, rvec *v, - bool bCalcVir, tensor vir_r_m_dr, - ConstraintVariable econq, - t_nrnb *nrnb, - int maxwarn, int *warncount) +bool constrain_lincs(bool computeRmsd, + const t_inputrec& ir, + int64_t step, + Lincs* lincsd, + const t_mdatoms& md, + const t_commrec* cr, + const gmx_multisim_t* ms, + const rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + t_pbc* pbc, + real lambda, + real* dvdlambda, + real invdt, + rvec* v, + bool bCalcVir, + tensor vir_r_m_dr, + ConstraintVariable econq, + t_nrnb* nrnb, + int maxwarn, + int* warncount) { bool bOK = TRUE; @@ -2316,7 +2295,7 @@ bool constrain_lincs(bool computeRmsd, { if (computeRmsd) { - lincsd->rmsdData = {{0}}; + lincsd->rmsdData = { { 0 } }; } return bOK; @@ -2336,7 +2315,7 @@ bool constrain_lincs(bool computeRmsd, for (int i = 0; i < lincsd->nc; i++) { - lincsd->bllen[i] = lincsd->bllen0[i] + lambda*lincsd->ddist[i]; + lincsd->bllen[i] = lincsd->bllen0[i] + lambda * lincsd->ddist[i]; } } @@ -2361,9 +2340,8 @@ bool constrain_lincs(bool computeRmsd, { if (lincsd->bllen[i] == 0) { - lincsd->bllen[i] = - std::sqrt(distance2(x[lincsd->atoms[i].index1], - x[lincsd->atoms[i].index2])); + lincsd->bllen[i] = std::sqrt( + distance2(x[lincsd->atoms[i].index1], x[lincsd->atoms[i].index2])); } } } @@ -2375,7 +2353,7 @@ bool constrain_lincs(bool computeRmsd, LincsDeviations deviations = makeLincsDeviations(*lincsd, xprime, pbc); fprintf(debug, " Rel. Constraint Deviation: RMS MAX between atoms\n"); fprintf(debug, " Before LINCS %.6f %.6f %6d %6d\n", - std::sqrt(deviations.sumSquaredDeviation/deviations.numConstraints), + std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints), deviations.maxDeviation, ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1), ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index2)); @@ -2396,14 +2374,10 @@ bool constrain_lincs(bool computeRmsd, clear_mat(lincsd->task[th].vir_r_m_dr); - do_lincs(x, xprime, box, pbc, lincsd, th, - md.invmass, cr, - bCalcDHDL, - ir.LincsWarnAngle, &bWarn, - invdt, v, bCalcVir, - th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr); + do_lincs(x, xprime, box, pbc, lincsd, th, md.invmass, cr, bCalcDHDL, ir.LincsWarnAngle, + &bWarn, invdt, v, bCalcVir, th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (computeRmsd || printDebugOutput || bWarn) @@ -2420,13 +2394,12 @@ bool constrain_lincs(bool computeRmsd, else { // This is never read - lincsd->rmsdData = {{0}}; + lincsd->rmsdData = { { 0 } }; } if (printDebugOutput) { - fprintf(debug, - " After LINCS %.6f %.6f %6d %6d\n\n", - std::sqrt(deviations.sumSquaredDeviation/deviations.numConstraints), + fprintf(debug, " After LINCS %.6f %.6f %6d %6d\n\n", + std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints), deviations.maxDeviation, ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1), ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index2)); @@ -2442,18 +2415,17 @@ bool constrain_lincs(bool computeRmsd, simMesg += gmx::formatString(" in simulation %d", ms->sim); } fprintf(stderr, - "\nStep %" PRId64 ", time %g (ps) LINCS WARNING%s\n" + "\nStep %" PRId64 + ", time %g (ps) LINCS WARNING%s\n" "relative constraint deviation after LINCS:\n" "rms %.6f, max %.6f (between atoms %d and %d)\n", - step, ir.init_t+step*ir.delta_t, - simMesg.c_str(), - std::sqrt(deviations.sumSquaredDeviation/deviations.numConstraints), + step, ir.init_t + step * ir.delta_t, simMesg.c_str(), + std::sqrt(deviations.sumSquaredDeviation / deviations.numConstraints), deviations.maxDeviation, ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index1), ddglatnr(cr->dd, lincsd->atoms[deviations.indexOfMaxDeviation].index2)); - lincs_warning(cr->dd, x, xprime, pbc, - lincsd->nc, lincsd->atoms, lincsd->bllen, + lincs_warning(cr->dd, x, xprime, pbc, lincsd->nc, lincsd->atoms, lincsd->bllen, ir.LincsWarnAngle, maxwarn, warncount); } bOK = (deviations.maxDeviation < 0.5); @@ -2480,11 +2452,10 @@ bool constrain_lincs(bool computeRmsd, { int th = gmx_omp_get_thread_num(); - do_lincsp(x, xprime, min_proj, pbc, lincsd, th, - md.invmass, econq, bCalcDHDL, + do_lincsp(x, xprime, min_proj, pbc, lincsd, th, md.invmass, econq, bCalcDHDL, bCalcVir, th == 0 ? vir_r_m_dr : lincsd->task[th].vir_r_m_dr); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } @@ -2503,7 +2474,7 @@ bool constrain_lincs(bool computeRmsd, { /* dhdlambda contains dH/dlambda*dt^2, correct for this */ /* TODO This should probably use invdt, so that sd integrator scaling works properly */ - dhdlambda /= ir.delta_t*ir.delta_t; + dhdlambda /= ir.delta_t * ir.delta_t; } *dvdlambda += dhdlambda; } @@ -2518,14 +2489,14 @@ bool constrain_lincs(bool computeRmsd, /* count assuming nit=1 */ inc_nrnb(nrnb, eNR_LINCS, lincsd->nc_real); - inc_nrnb(nrnb, eNR_LINCSMAT, (2+lincsd->nOrder)*lincsd->ncc); + inc_nrnb(nrnb, eNR_LINCSMAT, (2 + lincsd->nOrder) * lincsd->ncc); if (lincsd->ntriangle > 0) { - inc_nrnb(nrnb, eNR_LINCSMAT, lincsd->nOrder*lincsd->ncc_triangle); + inc_nrnb(nrnb, eNR_LINCSMAT, lincsd->nOrder * lincsd->ncc_triangle); } if (v) { - inc_nrnb(nrnb, eNR_CONSTR_V, lincsd->nc_real*2); + inc_nrnb(nrnb, eNR_CONSTR_V, lincsd->nc_real * 2); } if (bCalcVir) { @@ -2535,4 +2506,4 @@ bool constrain_lincs(bool computeRmsd, return bOK; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/lincs.h b/src/gromacs/mdlib/lincs.h index 3405df1648..dfc847127e 100644 --- a/src/gromacs/mdlib/lincs.h +++ b/src/gromacs/mdlib/lincs.h @@ -70,43 +70,52 @@ enum class ConstraintVariable : int; class Lincs; /*! \brief Return the data for determining constraint RMS relative deviations. */ -ArrayRef lincs_rmsdData(Lincs *lincsd); +ArrayRef lincs_rmsdData(Lincs* lincsd); /*! \brief Return the RMSD of the constraint. */ -real lincs_rmsd(const Lincs *lincsd); +real lincs_rmsd(const Lincs* lincsd); /*! \brief Initializes and returns the lincs data struct. */ -Lincs *init_lincs(FILE *fplog, const gmx_mtop_t &mtop, - int nflexcon_global, ArrayRef at2con, - bool bPLINCS, int nIter, int nProjOrder); +Lincs* init_lincs(FILE* fplog, + const gmx_mtop_t& mtop, + int nflexcon_global, + ArrayRef at2con, + bool bPLINCS, + int nIter, + int nProjOrder); /*! \brief Destructs the lincs object when it is not nullptr. */ -void done_lincs(Lincs *li); +void done_lincs(Lincs* li); /*! \brief Initialize lincs stuff */ -void set_lincs(const t_idef &idef, const t_mdatoms &md, - bool bDynamics, const t_commrec *cr, - Lincs *li); +void set_lincs(const t_idef& idef, const t_mdatoms& md, bool bDynamics, const t_commrec* cr, Lincs* li); /*! \brief Applies LINCS constraints. * * \returns true if the constraining succeeded. */ -bool -constrain_lincs(bool computeRmsd, - const t_inputrec &ir, - int64_t step, - Lincs *lincsd, const t_mdatoms &md, - const t_commrec *cr, - const gmx_multisim_t *ms, - const rvec *x, rvec *xprime, rvec *min_proj, - const matrix box, t_pbc *pbc, - real lambda, real *dvdlambda, - real invdt, rvec *v, - bool bCalcVir, tensor vir_r_m_dr, - ConstraintVariable econq, - t_nrnb *nrnb, - int maxwarn, int *warncount); +bool constrain_lincs(bool computeRmsd, + const t_inputrec& ir, + int64_t step, + Lincs* lincsd, + const t_mdatoms& md, + const t_commrec* cr, + const gmx_multisim_t* ms, + const rvec* x, + rvec* xprime, + rvec* min_proj, + const matrix box, + t_pbc* pbc, + real lambda, + real* dvdlambda, + real invdt, + rvec* v, + bool bCalcVir, + tensor vir_r_m_dr, + ConstraintVariable econq, + t_nrnb* nrnb, + int maxwarn, + int* warncount); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/lincs_cuda.cu b/src/gromacs/mdlib/lincs_cuda.cu index 428f5f2e78..d1be193900 100644 --- a/src/gromacs/mdlib/lincs_cuda.cu +++ b/src/gromacs/mdlib/lincs_cuda.cu @@ -105,28 +105,28 @@ constexpr static int c_maxThreadsPerBlock = c_threadsPerBlock; * \param[in,out] kernelParams All parameters and pointers for the kernel condensed in single struct. * \param[in] invdt Inverse timestep (needed to update velocities). */ -template -__launch_bounds__(c_maxThreadsPerBlock) -__global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, - const float3* __restrict__ gm_x, - float3* gm_xp, - float3* gm_v, - const float invdt) +template +__launch_bounds__(c_maxThreadsPerBlock) __global__ + void lincs_kernel(LincsCudaKernelParameters kernelParams, + const float3* __restrict__ gm_x, + float3* gm_xp, + float3* gm_v, + const float invdt) { - const PbcAiuc pbcAiuc = kernelParams.pbcAiuc; - const int numConstraintsThreads = kernelParams.numConstraintsThreads; - const int numIterations = kernelParams.numIterations; - const int expansionOrder = kernelParams.expansionOrder; - const int2* __restrict__ gm_constraints = kernelParams.d_constraints; - const float* __restrict__ gm_constraintsTargetLengths = kernelParams.d_constraintsTargetLengths; - const int* __restrict__ gm_coupledConstraintsCounts = kernelParams.d_coupledConstraintsCounts; - const int* __restrict__ gm_coupledConstraintsIdxes = kernelParams.d_coupledConstraintsIndices; - const float* __restrict__ gm_massFactors = kernelParams.d_massFactors; - float* __restrict__ gm_matrixA = kernelParams.d_matrixA; - const float* __restrict__ gm_inverseMasses = kernelParams.d_inverseMasses; - float* __restrict__ gm_virialScaled = kernelParams.d_virialScaled; - - int threadIndex = blockIdx.x*blockDim.x+threadIdx.x; + const PbcAiuc pbcAiuc = kernelParams.pbcAiuc; + const int numConstraintsThreads = kernelParams.numConstraintsThreads; + const int numIterations = kernelParams.numIterations; + const int expansionOrder = kernelParams.expansionOrder; + const int2* __restrict__ gm_constraints = kernelParams.d_constraints; + const float* __restrict__ gm_constraintsTargetLengths = kernelParams.d_constraintsTargetLengths; + const int* __restrict__ gm_coupledConstraintsCounts = kernelParams.d_coupledConstraintsCounts; + const int* __restrict__ gm_coupledConstraintsIdxes = kernelParams.d_coupledConstraintsIndices; + const float* __restrict__ gm_massFactors = kernelParams.d_massFactors; + float* __restrict__ gm_matrixA = kernelParams.d_matrixA; + const float* __restrict__ gm_inverseMasses = kernelParams.d_inverseMasses; + float* __restrict__ gm_virialScaled = kernelParams.d_virialScaled; + + int threadIndex = blockIdx.x * blockDim.x + threadIdx.x; // numConstraintsThreads should be a integer multiple of blockSize (numConstraintsThreads = numBlocks*blockSize). // This is to ensure proper synchronizations and reduction. All array are padded to the required size. @@ -136,17 +136,17 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, // Needed to construct constrain matrix A extern __shared__ float3 sm_r[]; - int2 pair = gm_constraints[threadIndex]; - int i = pair.x; - int j = pair.y; + int2 pair = gm_constraints[threadIndex]; + int i = pair.x; + int j = pair.y; // Mass-scaled Lagrange multiplier - float lagrangeScaled = 0.0f; + float lagrangeScaled = 0.0f; - float targetLength; - float inverseMassi; - float inverseMassj; - float sqrtReducedMass; + float targetLength; + float inverseMassi; + float inverseMassj; + float sqrtReducedMass; float3 xi; float3 xj; @@ -178,10 +178,10 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, xi = gm_x[i]; xj = gm_x[j]; - float3 dx = pbcDxAiuc(pbcAiuc, xi, xj); + float3 dx = pbcDxAiuc(pbcAiuc, xi, xj); - float rlen = rsqrtf(dx.x*dx.x + dx.y*dx.y + dx.z*dx.z); - rc = rlen*dx; + float rlen = rsqrtf(dx.x * dx.x + dx.y * dx.y + dx.z * dx.z); + rc = rlen * dx; } sm_r[threadIdx.x] = rc; @@ -197,11 +197,11 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, int coupledConstraintsCount = gm_coupledConstraintsCounts[threadIndex]; for (int n = 0; n < coupledConstraintsCount; n++) { - int index = n*numConstraintsThreads + threadIndex; - int c1 = gm_coupledConstraintsIdxes[index]; + int index = n * numConstraintsThreads + threadIndex; + int c1 = gm_coupledConstraintsIdxes[index]; - float3 rc1 = sm_r[c1 - blockIdx.x*blockDim.x]; - gm_matrixA[index] = gm_massFactors[index]*(rc.x*rc1.x + rc.y*rc1.y + rc.z*rc1.z); + float3 rc1 = sm_r[c1 - blockIdx.x * blockDim.x]; + gm_matrixA[index] = gm_massFactors[index] * (rc.x * rc1.x + rc.y * rc1.y + rc.z * rc1.z); } // Skipping in dummy threads @@ -213,14 +213,14 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, float3 dx = pbcDxAiuc(pbcAiuc, xi, xj); - float sol = sqrtReducedMass*((rc.x*dx.x + rc.y*dx.y + rc.z*dx.z) - targetLength); + float sol = sqrtReducedMass * ((rc.x * dx.x + rc.y * dx.y + rc.z * dx.z) - targetLength); /* * Inverse matrix using a set of expansionOrder matrix multiplications */ // This will use the same memory space as sm_r, which is no longer needed. - extern __shared__ float sm_rhs[]; + extern __shared__ float sm_rhs[]; // Save current right-hand-side vector in the shared memory sm_rhs[threadIdx.x] = sol; @@ -232,29 +232,29 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, for (int n = 0; n < coupledConstraintsCount; n++) { - int index = n*numConstraintsThreads + threadIndex; + int index = n * numConstraintsThreads + threadIndex; int c1 = gm_coupledConstraintsIdxes[index]; // Convolute current right-hand-side with A // Different, non overlapping parts of sm_rhs[..] are read during odd and even iterations - mvb = mvb + gm_matrixA[index]*sm_rhs[c1 - blockIdx.x*blockDim.x + blockDim.x*(rec % 2)]; + mvb = mvb + gm_matrixA[index] * sm_rhs[c1 - blockIdx.x * blockDim.x + blockDim.x * (rec % 2)]; } // 'Switch' rhs vectors, save current result // These values will be accessed in the loop above during the next iteration. - sm_rhs[threadIdx.x + blockDim.x*((rec + 1) % 2)] = mvb; - sol = sol + mvb; + sm_rhs[threadIdx.x + blockDim.x * ((rec + 1) % 2)] = mvb; + sol = sol + mvb; } // Current mass-scaled Lagrange multipliers - lagrangeScaled = sqrtReducedMass*sol; + lagrangeScaled = sqrtReducedMass * sol; // Save updated coordinates before correction for the rotational lengthening - float3 tmp = rc*lagrangeScaled; + float3 tmp = rc * lagrangeScaled; // Writing for all but dummy constraints if (!isDummyThread) { - atomicAdd(&gm_xp[i], -tmp*inverseMassi); - atomicAdd(&gm_xp[j], tmp*inverseMassj); + atomicAdd(&gm_xp[i], -tmp * inverseMassi); + atomicAdd(&gm_xp[j], tmp * inverseMassj); } /* @@ -274,23 +274,23 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, float3 dx = pbcDxAiuc(pbcAiuc, xi, xj); - float len2 = targetLength*targetLength; - float dlen2 = 2.0f*len2 - norm2(dx); + float len2 = targetLength * targetLength; + float dlen2 = 2.0f * len2 - norm2(dx); // TODO A little bit more effective but slightly less readable version of the below would be: // float proj = sqrtReducedMass*(targetLength - (dlen2 > 0.0f ? 1.0f : 0.0f)*dlen2*rsqrt(dlen2)); - float proj; + float proj; if (dlen2 > 0.0f) { - proj = sqrtReducedMass*(targetLength - dlen2*rsqrt(dlen2)); + proj = sqrtReducedMass * (targetLength - dlen2 * rsqrt(dlen2)); } else { - proj = sqrtReducedMass*targetLength; + proj = sqrtReducedMass * targetLength; } - sm_rhs[threadIdx.x] = proj; - float sol = proj; + sm_rhs[threadIdx.x] = proj; + float sol = proj; /* * Same matrix inversion as above is used for updated data @@ -303,36 +303,35 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, for (int n = 0; n < coupledConstraintsCount; n++) { - int index = n*numConstraintsThreads + threadIndex; + int index = n * numConstraintsThreads + threadIndex; int c1 = gm_coupledConstraintsIdxes[index]; - mvb = mvb + gm_matrixA[index]*sm_rhs[c1 - blockIdx.x*blockDim.x + blockDim.x*(rec % 2)]; - + mvb = mvb + gm_matrixA[index] * sm_rhs[c1 - blockIdx.x * blockDim.x + blockDim.x * (rec % 2)]; } - sm_rhs[threadIdx.x + blockDim.x*((rec + 1) % 2)] = mvb; - sol = sol + mvb; + sm_rhs[threadIdx.x + blockDim.x * ((rec + 1) % 2)] = mvb; + sol = sol + mvb; } // Add corrections to Lagrange multipliers - float sqrtmu_sol = sqrtReducedMass*sol; + float sqrtmu_sol = sqrtReducedMass * sol; lagrangeScaled += sqrtmu_sol; // Save updated coordinates for the next iteration // Dummy constraints are skipped if (!isDummyThread) { - float3 tmp = rc*sqrtmu_sol; - atomicAdd(&gm_xp[i], -tmp*inverseMassi); - atomicAdd(&gm_xp[j], tmp*inverseMassj); + float3 tmp = rc * sqrtmu_sol; + atomicAdd(&gm_xp[i], -tmp * inverseMassi); + atomicAdd(&gm_xp[j], tmp * inverseMassj); } } // Updating particle velocities for all but dummy threads if (updateVelocities && !isDummyThread) { - float3 tmp = rc*invdt*lagrangeScaled; - atomicAdd(&gm_v[i], -tmp*inverseMassi); - atomicAdd(&gm_v[j], tmp*inverseMassj); + float3 tmp = rc * invdt * lagrangeScaled; + atomicAdd(&gm_v[i], -tmp * inverseMassi); + atomicAdd(&gm_v[j], tmp * inverseMassj); } @@ -354,14 +353,14 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, // lagrangeScaled and rc are all set to zero for them in the beginning of the kernel. // The sm_threadVirial[..] will overlap with the sm_r[..] and sm_rhs[..], but the latter // two are no longer in use. - extern __shared__ float sm_threadVirial[]; - float mult = targetLength*lagrangeScaled; - sm_threadVirial[0*blockDim.x + threadIdx.x] = mult*rc.x*rc.x; - sm_threadVirial[1*blockDim.x + threadIdx.x] = mult*rc.x*rc.y; - sm_threadVirial[2*blockDim.x + threadIdx.x] = mult*rc.x*rc.z; - sm_threadVirial[3*blockDim.x + threadIdx.x] = mult*rc.y*rc.y; - sm_threadVirial[4*blockDim.x + threadIdx.x] = mult*rc.y*rc.z; - sm_threadVirial[5*blockDim.x + threadIdx.x] = mult*rc.z*rc.z; + extern __shared__ float sm_threadVirial[]; + float mult = targetLength * lagrangeScaled; + sm_threadVirial[0 * blockDim.x + threadIdx.x] = mult * rc.x * rc.x; + sm_threadVirial[1 * blockDim.x + threadIdx.x] = mult * rc.x * rc.y; + sm_threadVirial[2 * blockDim.x + threadIdx.x] = mult * rc.x * rc.z; + sm_threadVirial[3 * blockDim.x + threadIdx.x] = mult * rc.y * rc.y; + sm_threadVirial[4 * blockDim.x + threadIdx.x] = mult * rc.y * rc.z; + sm_threadVirial[5 * blockDim.x + threadIdx.x] = mult * rc.z * rc.z; __syncthreads(); @@ -372,16 +371,17 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, // in the beginning of the kernel). for (int divideBy = 2; divideBy <= static_cast(blockDim.x); divideBy *= 2) { - int dividedAt = blockDim.x/divideBy; + int dividedAt = blockDim.x / divideBy; if (static_cast(threadIdx.x) < dividedAt) { for (int d = 0; d < 6; d++) { - sm_threadVirial[d*blockDim.x + threadIdx.x] += sm_threadVirial[d*blockDim.x + (threadIdx.x + dividedAt)]; + sm_threadVirial[d * blockDim.x + threadIdx.x] += + sm_threadVirial[d * blockDim.x + (threadIdx.x + dividedAt)]; } } // Syncronize if not within one warp - if (dividedAt > warpSize/2) + if (dividedAt > warpSize / 2) { __syncthreads(); } @@ -389,7 +389,7 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, // First 6 threads in the block add the results of 6 tensor components to the global memory address. if (threadIdx.x < 6) { - atomicAdd(&(gm_virialScaled[threadIdx.x]), sm_threadVirial[threadIdx.x*blockDim.x]); + atomicAdd(&(gm_virialScaled[threadIdx.x]), sm_threadVirial[threadIdx.x * blockDim.x]); } } @@ -405,8 +405,7 @@ __global__ void lincs_kernel(LincsCudaKernelParameters kernelParams, * * \return Pointer to CUDA kernel */ -inline auto getLincsKernelPtr(const bool updateVelocities, - const bool computeVirial) +inline auto getLincsKernelPtr(const bool updateVelocities, const bool computeVirial) { auto kernelPtr = lincs_kernel; @@ -429,10 +428,10 @@ inline auto getLincsKernelPtr(const bool updateVelocities, return kernelPtr; } -void LincsCuda::apply(const float3 *d_x, - float3 *d_xp, +void LincsCuda::apply(const float3* d_x, + float3* d_xp, const bool updateVelocities, - float3 *d_v, + float3* d_v, const real invdt, const bool computeVirial, tensor virialScaled) @@ -452,15 +451,15 @@ void LincsCuda::apply(const float3 *d_x, clearDeviceBufferAsync(&kernelParams_.d_virialScaled, 0, 6, commandStream_); } - auto kernelPtr = getLincsKernelPtr(updateVelocities, computeVirial); + auto kernelPtr = getLincsKernelPtr(updateVelocities, computeVirial); KernelLaunchConfig config; - config.blockSize[0] = c_threadsPerBlock; - config.blockSize[1] = 1; - config.blockSize[2] = 1; - config.gridSize[0] = (kernelParams_.numConstraintsThreads + c_threadsPerBlock - 1)/c_threadsPerBlock; - config.gridSize[1] = 1; - config.gridSize[2] = 1; + config.blockSize[0] = c_threadsPerBlock; + config.blockSize[1] = 1; + config.blockSize[2] = 1; + config.gridSize[0] = (kernelParams_.numConstraintsThreads + c_threadsPerBlock - 1) / c_threadsPerBlock; + config.gridSize[1] = 1; + config.gridSize[2] = 1; // Shared memory is used to store: // -- Current coordinates (3 floats per thread) @@ -471,27 +470,23 @@ void LincsCuda::apply(const float3 *d_x, // max{3, 2, 6} = 6 floats per thread are needed in case virial is computed, or max{3, 2} = 3 if not. if (computeVirial) { - config.sharedMemorySize = c_threadsPerBlock*6*sizeof(float); + config.sharedMemorySize = c_threadsPerBlock * 6 * sizeof(float); } else { - config.sharedMemorySize = c_threadsPerBlock*3*sizeof(float); + config.sharedMemorySize = c_threadsPerBlock * 3 * sizeof(float); } - config.stream = commandStream_; + config.stream = commandStream_; - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, - &kernelParams_, - &d_x, &d_xp, - &d_v, &invdt); + const auto kernelArgs = + prepareGpuKernelArguments(kernelPtr, config, &kernelParams_, &d_x, &d_xp, &d_v, &invdt); - launchGpuKernel(kernelPtr, config, nullptr, - "lincs_kernel", kernelArgs); + launchGpuKernel(kernelPtr, config, nullptr, "lincs_kernel", kernelArgs); if (computeVirial) { // Copy LINCS virial data and add it to the common virial - copyFromDeviceBuffer(h_virialScaled_.data(), &kernelParams_.d_virialScaled, - 0, 6, + copyFromDeviceBuffer(h_virialScaled_.data(), &kernelParams_.d_virialScaled, 0, 6, commandStream_, GpuApiCallBehavior::Sync, nullptr); // Mapping [XX, XY, XZ, YY, YZ, ZZ] internal format to a tensor object @@ -511,18 +506,17 @@ void LincsCuda::apply(const float3 *d_x, return; } -LincsCuda::LincsCuda(int numIterations, - int expansionOrder, - CommandStream commandStream) : +LincsCuda::LincsCuda(int numIterations, int expansionOrder, CommandStream commandStream) : commandStream_(commandStream) { - kernelParams_.numIterations = numIterations; - kernelParams_.expansionOrder = expansionOrder; + kernelParams_.numIterations = numIterations; + kernelParams_.expansionOrder = expansionOrder; static_assert(sizeof(real) == sizeof(float), "Real numbers should be in single precision in GPU code."); - static_assert(c_threadsPerBlock > 0 && ((c_threadsPerBlock & (c_threadsPerBlock - 1)) == 0), - "Number of threads per block should be a power of two in order for reduction to work."); + static_assert( + c_threadsPerBlock > 0 && ((c_threadsPerBlock & (c_threadsPerBlock - 1)) == 0), + "Number of threads per block should be a power of two in order for reduction to work."); allocateDeviceBuffer(&kernelParams_.d_virialScaled, 6, nullptr); h_virialScaled_.resize(6); @@ -570,8 +564,9 @@ LincsCuda::~LincsCuda() * the group has to be moved to the next one. * \param[in] atomAdjacencyList Stores information about connections between atoms. */ -inline int countCoupled(int a, std::vector *spaceNeeded, - std::vector > > *atomsAdjacencyList) +inline int countCoupled(int a, + std::vector* spaceNeeded, + std::vector>>* atomsAdjacencyList) { int c2, a2, sign; @@ -582,31 +577,30 @@ inline int countCoupled(int a, std::vector *spaceNeeded, if (spaceNeeded->at(c2) == -1) { spaceNeeded->at(c2) = 0; // To indicate we've been here - counted += 1 + countCoupled(a2, spaceNeeded, atomsAdjacencyList); + counted += 1 + countCoupled(a2, spaceNeeded, atomsAdjacencyList); } } return counted; } -void LincsCuda::set(const t_idef &idef, - const t_mdatoms &md) +void LincsCuda::set(const t_idef& idef, const t_mdatoms& md) { - int numAtoms = md.nr; + int numAtoms = md.nr; // List of constrained atoms (CPU memory) - std::vector constraintsHost; + std::vector constraintsHost; // Equilibrium distances for the constraints (CPU) - std::vector constraintsTargetLengthsHost; + std::vector constraintsTargetLengthsHost; // Number of constraints, coupled with the current one (CPU) - std::vector coupledConstraintsCountsHost; + std::vector coupledConstraintsCountsHost; // List of coupled with the current one (CPU) - std::vector coupledConstraintsIndicesHost; + std::vector coupledConstraintsIndicesHost; // Mass factors (CPU) - std::vector massFactorsHost; + std::vector massFactorsHost; // List of constrained atoms in local topology - t_iatom *iatoms = idef.il[F_CONSTR].iatoms; + t_iatom* iatoms = idef.il[F_CONSTR].iatoms; const int stride = NRAL(F_CONSTR) + 1; - const int numConstraints = idef.il[F_CONSTR].nr/stride; + const int numConstraints = idef.il[F_CONSTR].nr / stride; // Early exit if no constraints if (numConstraints == 0) @@ -616,15 +610,15 @@ void LincsCuda::set(const t_idef &idef, } // Constructing adjacency list --- usefull intermediate structure - std::vector > > atomsAdjacencyList(numAtoms); + std::vector>> atomsAdjacencyList(numAtoms); for (int c = 0; c < numConstraints; c++) { - int a1 = iatoms[stride*c + 1]; - int a2 = iatoms[stride*c + 2]; + int a1 = iatoms[stride * c + 1]; + int a2 = iatoms[stride * c + 2]; - // Each constraint will be represented as a tuple, containing index of the second constrained atom, - // index of the constraint and a sign that indicates the order of atoms in which they are listed. - // Sign is needed to compute the mass factors. + // Each constraint will be represented as a tuple, containing index of the second + // constrained atom, index of the constraint and a sign that indicates the order of atoms in + // which they are listed. Sign is needed to compute the mass factors. atomsAdjacencyList.at(a1).push_back(std::make_tuple(a2, c, +1)); atomsAdjacencyList.at(a2).push_back(std::make_tuple(a1, c, -1)); } @@ -639,12 +633,12 @@ void LincsCuda::set(const t_idef &idef, std::fill(spaceNeeded.begin(), spaceNeeded.end(), -1); for (int c = 0; c < numConstraints; c++) { - int a1 = iatoms[stride*c + 1]; - int a2 = iatoms[stride*c + 2]; + int a1 = iatoms[stride * c + 1]; + int a2 = iatoms[stride * c + 2]; if (spaceNeeded.at(c) == -1) { - spaceNeeded.at(c) = countCoupled(a1, &spaceNeeded, &atomsAdjacencyList) + - countCoupled(a2, &spaceNeeded, &atomsAdjacencyList); + spaceNeeded.at(c) = countCoupled(a1, &spaceNeeded, &atomsAdjacencyList) + + countCoupled(a2, &spaceNeeded, &atomsAdjacencyList); } } @@ -652,22 +646,27 @@ void LincsCuda::set(const t_idef &idef, // takes into account the empty spaces which might be needed in the end of each thread block. std::vector splitMap; splitMap.resize(numConstraints, -1); - int currentMapIndex = 0; + int currentMapIndex = 0; for (int c = 0; c < numConstraints; c++) { // Check if coupled constraints all fit in one block - GMX_RELEASE_ASSERT(spaceNeeded.at(c) < c_threadsPerBlock, "Maximum number of coupled constraints exceedes the size of the CUDA thread block. " - "Most likely, you are trying to use GPU version of LINCS with constraints on all-bonds, " - "which is not supported. Try using H-bonds constraints only."); + GMX_RELEASE_ASSERT( + spaceNeeded.at(c) < c_threadsPerBlock, + "Maximum number of coupled constraints exceedes the size of the CUDA thread block. " + "Most likely, you are trying to use GPU version of LINCS with constraints on " + "all-bonds, " + "which is not supported. Try using H-bonds constraints only."); if (currentMapIndex / c_threadsPerBlock != (currentMapIndex + spaceNeeded.at(c)) / c_threadsPerBlock) { - currentMapIndex = ((currentMapIndex/c_threadsPerBlock) + 1) * c_threadsPerBlock; + currentMapIndex = ((currentMapIndex / c_threadsPerBlock) + 1) * c_threadsPerBlock; } splitMap.at(c) = currentMapIndex; currentMapIndex++; } - kernelParams_.numConstraintsThreads = currentMapIndex + c_threadsPerBlock - currentMapIndex % c_threadsPerBlock; - GMX_RELEASE_ASSERT(kernelParams_.numConstraintsThreads % c_threadsPerBlock == 0, "Number of threads should be a multiple of the block size"); + kernelParams_.numConstraintsThreads = + currentMapIndex + c_threadsPerBlock - currentMapIndex % c_threadsPerBlock; + GMX_RELEASE_ASSERT(kernelParams_.numConstraintsThreads % c_threadsPerBlock == 0, + "Number of threads should be a multiple of the block size"); // Initialize constraints and their target indexes taking into account the splits in the data arrays. int2 pair; @@ -679,32 +678,32 @@ void LincsCuda::set(const t_idef &idef, std::fill(constraintsTargetLengthsHost.begin(), constraintsTargetLengthsHost.end(), 0.0); for (int c = 0; c < numConstraints; c++) { - int a1 = iatoms[stride*c + 1]; - int a2 = iatoms[stride*c + 2]; - int type = iatoms[stride*c]; + int a1 = iatoms[stride * c + 1]; + int a2 = iatoms[stride * c + 2]; + int type = iatoms[stride * c]; int2 pair; - pair.x = a1; - pair.y = a2; + pair.x = a1; + pair.y = a2; constraintsHost.at(splitMap.at(c)) = pair; constraintsTargetLengthsHost.at(splitMap.at(c)) = idef.iparams[type].constr.dA; - } // The adjacency list of constraints (i.e. the list of coupled constraints for each constraint). - // We map a single thread to a single constraint, hence each thread 'c' will be using one element from - // coupledConstraintsCountsHost array, which is the number of constraints coupled to the constraint 'c'. - // The coupled constraints indexes are placed into the coupledConstraintsIndicesHost array. Latter is organized - // as a one-dimensional array to ensure good memory alignment. It is addressed as [c + i*numConstraintsThreads], - // where 'i' goes from zero to the number of constraints coupled to 'c'. 'numConstraintsThreads' is the width of - // the array --- a number, greater then total number of constraints, taking into account the splits in the - // constraints array due to the GPU block borders. This number can be adjusted to improve memory access pattern. - // Mass factors are saved in a similar data structure. - int maxCoupledConstraints = 0; + // We map a single thread to a single constraint, hence each thread 'c' will be using one + // element from coupledConstraintsCountsHost array, which is the number of constraints coupled + // to the constraint 'c'. The coupled constraints indexes are placed into the + // coupledConstraintsIndicesHost array. Latter is organized as a one-dimensional array to ensure + // good memory alignment. It is addressed as [c + i*numConstraintsThreads], where 'i' goes from + // zero to the number of constraints coupled to 'c'. 'numConstraintsThreads' is the width of the + // array --- a number, greater then total number of constraints, taking into account the splits + // in the constraints array due to the GPU block borders. This number can be adjusted to improve + // memory access pattern. Mass factors are saved in a similar data structure. + int maxCoupledConstraints = 0; for (int c = 0; c < numConstraints; c++) { - int a1 = iatoms[stride*c + 1]; - int a2 = iatoms[stride*c + 2]; + int a1 = iatoms[stride * c + 1]; + int a2 = iatoms[stride * c + 2]; // Constraint 'c' is counted twice, but it should be excluded altogether. Hence '-2'. int nCoupedConstraints = atomsAdjacencyList.at(a1).size() + atomsAdjacencyList.at(a2).size() - 2; @@ -716,14 +715,14 @@ void LincsCuda::set(const t_idef &idef, } coupledConstraintsCountsHost.resize(kernelParams_.numConstraintsThreads, 0); - coupledConstraintsIndicesHost.resize(maxCoupledConstraints*kernelParams_.numConstraintsThreads, -1); - massFactorsHost.resize(maxCoupledConstraints*kernelParams_.numConstraintsThreads, -1); + coupledConstraintsIndicesHost.resize(maxCoupledConstraints * kernelParams_.numConstraintsThreads, -1); + massFactorsHost.resize(maxCoupledConstraints * kernelParams_.numConstraintsThreads, -1); for (int c1 = 0; c1 < numConstraints; c1++) { - coupledConstraintsCountsHost.at(splitMap.at(c1)) = 0; - int c1a1 = iatoms[stride*c1 + 1]; - int c1a2 = iatoms[stride*c1 + 2]; + coupledConstraintsCountsHost.at(splitMap.at(c1)) = 0; + int c1a1 = iatoms[stride * c1 + 1]; + int c1a2 = iatoms[stride * c1 + 2]; int c2; int c2a1; int c2a2; @@ -739,19 +738,20 @@ void LincsCuda::set(const t_idef &idef, if (c1 != c2) { - int index = kernelParams_.numConstraintsThreads*coupledConstraintsCountsHost.at(splitMap.at(c1)) + splitMap.at(c1); + int index = kernelParams_.numConstraintsThreads + * coupledConstraintsCountsHost.at(splitMap.at(c1)) + + splitMap.at(c1); coupledConstraintsIndicesHost.at(index) = splitMap.at(c2); - int center = c1a1; + int center = c1a1; - float sqrtmu1 = 1.0/sqrt(md.invmass[c1a1] + md.invmass[c1a2]); - float sqrtmu2 = 1.0/sqrt(md.invmass[c2a1] + md.invmass[c2a2]); + float sqrtmu1 = 1.0 / sqrt(md.invmass[c1a1] + md.invmass[c1a2]); + float sqrtmu2 = 1.0 / sqrt(md.invmass[c2a1] + md.invmass[c2a2]); - massFactorsHost.at(index) = -sign*md.invmass[center]*sqrtmu1*sqrtmu2; + massFactorsHost.at(index) = -sign * md.invmass[center] * sqrtmu1 * sqrtmu2; coupledConstraintsCountsHost.at(splitMap.at(c1))++; - } } @@ -764,19 +764,20 @@ void LincsCuda::set(const t_idef &idef, if (c1 != c2) { - int index = kernelParams_.numConstraintsThreads*coupledConstraintsCountsHost.at(splitMap.at(c1)) + splitMap.at(c1); + int index = kernelParams_.numConstraintsThreads + * coupledConstraintsCountsHost.at(splitMap.at(c1)) + + splitMap.at(c1); coupledConstraintsIndicesHost.at(index) = splitMap.at(c2); - int center = c1a2; + int center = c1a2; - float sqrtmu1 = 1.0/sqrt(md.invmass[c1a1] + md.invmass[c1a2]); - float sqrtmu2 = 1.0/sqrt(md.invmass[c2a1] + md.invmass[c2a2]); + float sqrtmu1 = 1.0 / sqrt(md.invmass[c1a1] + md.invmass[c1a2]); + float sqrtmu2 = 1.0 / sqrt(md.invmass[c2a1] + md.invmass[c2a2]); - massFactorsHost.at(index) = sign*md.invmass[center]*sqrtmu1*sqrtmu2; + massFactorsHost.at(index) = sign * md.invmass[center] * sqrtmu1 * sqrtmu2; coupledConstraintsCountsHost.at(splitMap.at(c1))++; - } } } @@ -794,19 +795,22 @@ void LincsCuda::set(const t_idef &idef, freeDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices); freeDeviceBuffer(&kernelParams_.d_massFactors); freeDeviceBuffer(&kernelParams_.d_matrixA); - } numConstraintsThreadsAlloc_ = kernelParams_.numConstraintsThreads; allocateDeviceBuffer(&kernelParams_.d_constraints, kernelParams_.numConstraintsThreads, nullptr); - allocateDeviceBuffer(&kernelParams_.d_constraintsTargetLengths, kernelParams_.numConstraintsThreads, nullptr); - - allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts, kernelParams_.numConstraintsThreads, nullptr); - allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices, maxCoupledConstraints*kernelParams_.numConstraintsThreads, nullptr); - allocateDeviceBuffer(&kernelParams_.d_massFactors, maxCoupledConstraints*kernelParams_.numConstraintsThreads, nullptr); - allocateDeviceBuffer(&kernelParams_.d_matrixA, maxCoupledConstraints*kernelParams_.numConstraintsThreads, nullptr); - + allocateDeviceBuffer(&kernelParams_.d_constraintsTargetLengths, + kernelParams_.numConstraintsThreads, nullptr); + + allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts, + kernelParams_.numConstraintsThreads, nullptr); + allocateDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices, + maxCoupledConstraints * kernelParams_.numConstraintsThreads, nullptr); + allocateDeviceBuffer(&kernelParams_.d_massFactors, + maxCoupledConstraints * kernelParams_.numConstraintsThreads, nullptr); + allocateDeviceBuffer(&kernelParams_.d_matrixA, + maxCoupledConstraints * kernelParams_.numConstraintsThreads, nullptr); } // (Re)allocate the memory, if the number of atoms has increased. @@ -821,30 +825,28 @@ void LincsCuda::set(const t_idef &idef, } // Copy data to GPU. - copyToDeviceBuffer(&kernelParams_.d_constraints, constraintsHost.data(), - 0, kernelParams_.numConstraintsThreads, - commandStream_, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&kernelParams_.d_constraintsTargetLengths, constraintsTargetLengthsHost.data(), - 0, kernelParams_.numConstraintsThreads, + copyToDeviceBuffer(&kernelParams_.d_constraints, constraintsHost.data(), 0, + kernelParams_.numConstraintsThreads, commandStream_, + GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&kernelParams_.d_constraintsTargetLengths, + constraintsTargetLengthsHost.data(), 0, kernelParams_.numConstraintsThreads, commandStream_, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts, coupledConstraintsCountsHost.data(), - 0, kernelParams_.numConstraintsThreads, + copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsCounts, + coupledConstraintsCountsHost.data(), 0, kernelParams_.numConstraintsThreads, commandStream_, GpuApiCallBehavior::Sync, nullptr); copyToDeviceBuffer(&kernelParams_.d_coupledConstraintsIndices, coupledConstraintsIndicesHost.data(), - 0, maxCoupledConstraints*kernelParams_.numConstraintsThreads, - commandStream_, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&kernelParams_.d_massFactors, massFactorsHost.data(), - 0, maxCoupledConstraints*kernelParams_.numConstraintsThreads, + 0, maxCoupledConstraints * kernelParams_.numConstraintsThreads, commandStream_, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&kernelParams_.d_massFactors, massFactorsHost.data(), 0, + maxCoupledConstraints * kernelParams_.numConstraintsThreads, commandStream_, + GpuApiCallBehavior::Sync, nullptr); GMX_RELEASE_ASSERT(md.invmass != nullptr, "Masses of attoms should be specified.\n"); - copyToDeviceBuffer(&kernelParams_.d_inverseMasses, md.invmass, - 0, numAtoms, - commandStream_, GpuApiCallBehavior::Sync, nullptr); - + copyToDeviceBuffer(&kernelParams_.d_inverseMasses, md.invmass, 0, numAtoms, commandStream_, + GpuApiCallBehavior::Sync, nullptr); } -void LincsCuda::setPbc(const t_pbc *pbc) +void LincsCuda::setPbc(const t_pbc* pbc) { setPbcAiuc(pbc->ndim_ePBC, pbc->box, &kernelParams_.pbcAiuc); } diff --git a/src/gromacs/mdlib/lincs_cuda.cuh b/src/gromacs/mdlib/lincs_cuda.cuh index d3cffb25de..99589f33cf 100644 --- a/src/gromacs/mdlib/lincs_cuda.cuh +++ b/src/gromacs/mdlib/lincs_cuda.cuh @@ -63,141 +63,135 @@ namespace gmx struct LincsCudaKernelParameters { //! Periodic boundary data - PbcAiuc pbcAiuc; + PbcAiuc pbcAiuc; //! Order of expansion when inverting the matrix - int expansionOrder; + int expansionOrder; //! Number of iterations used to correct the projection - int numIterations; + int numIterations; //! 1/mass for all atoms (GPU) - float *d_inverseMasses; + float* d_inverseMasses; //! Scaled virial tensor (6 floats: [XX, XY, XZ, YY, YZ, ZZ], GPU) - float *d_virialScaled; + float* d_virialScaled; /*! \brief Total number of threads. * * This covers all constraints and gaps in the ends of the thread blocks * that are necessary to avoid inter-block synchronizations. * Should be a multiple of block size (the last block is filled with dummy to the end). */ - int numConstraintsThreads; + int numConstraintsThreads; //! List of constrained atoms (GPU memory) - int2 *d_constraints; + int2* d_constraints; //! Equilibrium distances for the constraints (GPU) - float *d_constraintsTargetLengths; + float* d_constraintsTargetLengths; //! Number of constraints, coupled with the current one (GPU) - int *d_coupledConstraintsCounts; + int* d_coupledConstraintsCounts; //! List of coupled with the current one (GPU) - int *d_coupledConstraintsIndices; + int* d_coupledConstraintsIndices; //! Elements of the coupling matrix. - float *d_matrixA; + float* d_matrixA; //! Mass factors (GPU) - float *d_massFactors; + float* d_massFactors; }; /*! \internal \brief Class with interfaces and data for CUDA version of LINCS. */ class LincsCuda { - public: - - /*! \brief Constructor. - * - * \param[in] numIterations Number of iteration for the correction of the projection. - * \param[in] expansionOrder Order of the matrix inversion algorithm. - * \param[in] commandStream Device command stream. - */ - LincsCuda(int numIterations, - int expansionOrder, - CommandStream commandStream); - /*! \brief Destructor.*/ - ~LincsCuda(); - - /*! \brief Apply LINCS. - * - * Applies LINCS to coordinates and velocities, stored on GPU. - * The results are not automatically copied back to the CPU memory. - * Method uses this class data structures which should be updated - * when needed using set() and setPbc() method. - * - * \param[in] d_x Coordinates before timestep (in GPU memory) - * \param[in,out] d_xp Coordinates after timestep (in GPU memory). The - * resulting constrained coordinates will be saved here. - * \param[in] updateVelocities If the velocities should be updated. - * \param[in,out] d_v Velocities to update (in GPU memory, can be nullptr - * if not updated) - * \param[in] invdt Reciprocal timestep (to scale Lagrange - * multipliers when velocities are updated) - * \param[in] computeVirial If virial should be updated. - * \param[in,out] virialScaled Scaled virial tensor to be updated. - */ - void apply(const float3 *d_x, - float3 *d_xp, - const bool updateVelocities, - float3 *d_v, - const real invdt, - const bool computeVirial, - tensor virialScaled); - - /*! \brief - * Update data-structures (e.g. after NB search step). - * - * Updates the constraints data and copies it to the GPU. Should be - * called if the particles were sorted, redistributed between domains, etc. - * This version uses common data formats so it can be called from anywhere - * in the code. Does not recycle the data preparation routines from the CPU - * version. Works only with simple case when all the constraints in idef are - * are handled by a single GPU. Triangles are not handled as special case. - * - * Information about constraints is taken from: - * idef.il[F_CONSTR].iatoms --- type (T) of constraint and two atom indexes (i1, i2) - * idef.iparams[T].constr.dA --- target length for constraint of type T - * From t_mdatom, the code takes: - * md.invmass --- array of inverse square root of masses for each atom in the system. - * - * \param[in] idef Local topology data to get information on constraints from. - * \param[in] md Atoms data to get atom masses from. - */ - void set(const t_idef &idef, - const t_mdatoms &md); - - /*! \brief - * Update PBC data. - * - * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter. - * - * \todo Remove this method. LINCS should not manage PBC. - * - * \param[in] pbc The PBC data in t_pbc format. - */ - void setPbc(const t_pbc *pbc); - - - private: - - //! CUDA stream - CommandStream commandStream_; - - //! Parameters and pointers, passed to the CUDA kernel - LincsCudaKernelParameters kernelParams_; - - //! Scaled virial tensor (6 floats: [XX, XY, XZ, YY, YZ, ZZ]) - std::vector h_virialScaled_; - - /*! \brief Maximum total number of constraints so far. - * - * If the new number of constraints is larger then previous maximum, the GPU data arrays are - * reallocated. - */ - int numConstraintsThreadsAlloc_; - - /*! \brief Maximum total number of atoms so far. - * - * If the new number of atoms is larger then previous maximum, the GPU array with masses is - * reallocated. - */ - int numAtomsAlloc_; +public: + /*! \brief Constructor. + * + * \param[in] numIterations Number of iteration for the correction of the projection. + * \param[in] expansionOrder Order of the matrix inversion algorithm. + * \param[in] commandStream Device command stream. + */ + LincsCuda(int numIterations, int expansionOrder, CommandStream commandStream); + /*! \brief Destructor.*/ + ~LincsCuda(); + + /*! \brief Apply LINCS. + * + * Applies LINCS to coordinates and velocities, stored on GPU. + * The results are not automatically copied back to the CPU memory. + * Method uses this class data structures which should be updated + * when needed using set() and setPbc() method. + * + * \param[in] d_x Coordinates before timestep (in GPU memory) + * \param[in,out] d_xp Coordinates after timestep (in GPU memory). The + * resulting constrained coordinates will be saved here. + * \param[in] updateVelocities If the velocities should be updated. + * \param[in,out] d_v Velocities to update (in GPU memory, can be nullptr + * if not updated) + * \param[in] invdt Reciprocal timestep (to scale Lagrange + * multipliers when velocities are updated) + * \param[in] computeVirial If virial should be updated. + * \param[in,out] virialScaled Scaled virial tensor to be updated. + */ + void apply(const float3* d_x, + float3* d_xp, + const bool updateVelocities, + float3* d_v, + const real invdt, + const bool computeVirial, + tensor virialScaled); + + /*! \brief + * Update data-structures (e.g. after NB search step). + * + * Updates the constraints data and copies it to the GPU. Should be + * called if the particles were sorted, redistributed between domains, etc. + * This version uses common data formats so it can be called from anywhere + * in the code. Does not recycle the data preparation routines from the CPU + * version. Works only with simple case when all the constraints in idef are + * are handled by a single GPU. Triangles are not handled as special case. + * + * Information about constraints is taken from: + * idef.il[F_CONSTR].iatoms --- type (T) of constraint and two atom indexes (i1, i2) + * idef.iparams[T].constr.dA --- target length for constraint of type T + * From t_mdatom, the code takes: + * md.invmass --- array of inverse square root of masses for each atom in the system. + * + * \param[in] idef Local topology data to get information on constraints from. + * \param[in] md Atoms data to get atom masses from. + */ + void set(const t_idef& idef, const t_mdatoms& md); + + /*! \brief + * Update PBC data. + * + * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter. + * + * \todo Remove this method. LINCS should not manage PBC. + * + * \param[in] pbc The PBC data in t_pbc format. + */ + void setPbc(const t_pbc* pbc); + + +private: + //! CUDA stream + CommandStream commandStream_; + + //! Parameters and pointers, passed to the CUDA kernel + LincsCudaKernelParameters kernelParams_; + //! Scaled virial tensor (6 floats: [XX, XY, XZ, YY, YZ, ZZ]) + std::vector h_virialScaled_; + + /*! \brief Maximum total number of constraints so far. + * + * If the new number of constraints is larger then previous maximum, the GPU data arrays are + * reallocated. + */ + int numConstraintsThreadsAlloc_; + + /*! \brief Maximum total number of atoms so far. + * + * If the new number of atoms is larger then previous maximum, the GPU array with masses is + * reallocated. + */ + int numAtomsAlloc_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDLIB_LINCS_CUDA_CUH diff --git a/src/gromacs/mdlib/makeconstraints.h b/src/gromacs/mdlib/makeconstraints.h index baf42420cb..75c8157372 100644 --- a/src/gromacs/mdlib/makeconstraints.h +++ b/src/gromacs/mdlib/makeconstraints.h @@ -66,15 +66,16 @@ namespace gmx * to declare makeConstraints() as a template friend function. */ struct Constraints::CreationHelper : public Constraints { - public: - /*! \brief Constructor that can call the private constructor - * of Constraints. - * - * The parameter pack insulates this helper type from changes - * to the arguments to the constructor. */ - template - CreationHelper(Args && ... args) - : Constraints(std::forward(args) ...) {} +public: + /*! \brief Constructor that can call the private constructor + * of Constraints. + * + * The parameter pack insulates this helper type from changes + * to the arguments to the constructor. */ + template + CreationHelper(Args&&... args) : Constraints(std::forward(args)...) + { + } }; /*! \brief Factory function for Constraints. @@ -93,29 +94,28 @@ struct Constraints::CreationHelper : public Constraints * Using the parameter pack insulates the factory function from * changes to the type signature of the constructor that don't * affect the logic here. */ -template -std::unique_ptr makeConstraints(const gmx_mtop_t &mtop, - const t_inputrec &ir, - pull_t *pull_work, +template +std::unique_ptr makeConstraints(const gmx_mtop_t& mtop, + const t_inputrec& ir, + pull_t* pull_work, bool doEssentialDynamics, - Args && ... args) + Args&&... args) { - int numConstraints = (gmx_mtop_ftype_count(mtop, F_CONSTR) + - gmx_mtop_ftype_count(mtop, F_CONSTRNC)); + int numConstraints = (gmx_mtop_ftype_count(mtop, F_CONSTR) + gmx_mtop_ftype_count(mtop, F_CONSTRNC)); int numSettles = gmx_mtop_ftype_count(mtop, F_SETTLE); GMX_RELEASE_ASSERT(!ir.bPull || pull_work != nullptr, - "When COM pulling is active, it must be initialized before constraints are initialized"); + "When COM pulling is active, it must be initialized before constraints are " + "initialized"); bool doPullingWithConstraints = ir.bPull && pull_have_constraint(pull_work); - if (numConstraints + numSettles == 0 && - !doPullingWithConstraints && !doEssentialDynamics) + if (numConstraints + numSettles == 0 && !doPullingWithConstraints && !doEssentialDynamics) { // No work, so don't make a Constraints object. return nullptr; } - return std::make_unique - (mtop, ir, pull_work, std::forward(args) ..., numConstraints, numSettles); + return std::make_unique( + mtop, ir, pull_work, std::forward(args)..., numConstraints, numSettles); } -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/md_support.cpp b/src/gromacs/mdlib/md_support.cpp index b43e108126..3f6829005d 100644 --- a/src/gromacs/mdlib/md_support.cpp +++ b/src/gromacs/mdlib/md_support.cpp @@ -78,11 +78,10 @@ #include "gromacs/utility/snprintf.h" // TODO move this to multi-sim module -bool multisim_int_all_are_equal(const gmx_multisim_t *ms, - int64_t value) +bool multisim_int_all_are_equal(const gmx_multisim_t* ms, int64_t value) { - bool allValuesAreEqual = true; - int64_t *buf; + bool allValuesAreEqual = true; + int64_t* buf; GMX_RELEASE_ASSERT(ms, "Invalid use of multi-simulation pointer"); @@ -105,9 +104,9 @@ bool multisim_int_all_are_equal(const gmx_multisim_t *ms, return allValuesAreEqual; } -int multisim_min(const gmx_multisim_t *ms, int nmin, int n) +int multisim_min(const gmx_multisim_t* ms, int nmin, int n) { - int *buf; + int* buf; gmx_bool bPos, bEqual; int s, d; @@ -118,7 +117,7 @@ int multisim_min(const gmx_multisim_t *ms, int nmin, int n) bEqual = TRUE; for (s = 0; s < ms->nsim; s++) { - bPos = bPos && (buf[s] > 0); + bPos = bPos && (buf[s] > 0); bEqual = bEqual && (buf[s] == buf[0]); } if (bPos) @@ -153,20 +152,34 @@ int multisim_min(const gmx_multisim_t *ms, int nmin, int n) /* TODO Specialize this routine into init-time and loop-time versions? e.g. bReadEkin is only true when restoring from checkpoint */ -void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir, - t_forcerec *fr, gmx_ekindata_t *ekind, - const rvec *x, const rvec *v, const matrix box, - real vdwLambda, const t_mdatoms *mdatoms, - t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle, - gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir, - tensor pres, rvec mu_tot, gmx::Constraints *constr, - gmx::SimulationSignaller *signalCoordinator, - const matrix lastbox, int *totalNumberOfBondedInteractions, - gmx_bool *bSumEkinhOld, const int flags) +void compute_globals(gmx_global_stat* gstat, + t_commrec* cr, + const t_inputrec* ir, + t_forcerec* fr, + gmx_ekindata_t* ekind, + const rvec* x, + const rvec* v, + const matrix box, + real vdwLambda, + const t_mdatoms* mdatoms, + t_nrnb* nrnb, + t_vcm* vcm, + gmx_wallcycle_t wcycle, + gmx_enerdata_t* enerd, + tensor force_vir, + tensor shake_vir, + tensor total_vir, + tensor pres, + rvec mu_tot, + gmx::Constraints* constr, + gmx::SimulationSignaller* signalCoordinator, + const matrix lastbox, + int* totalNumberOfBondedInteractions, + gmx_bool* bSumEkinhOld, + const int flags) { gmx_bool bEner, bPres, bTemp; - gmx_bool bStopCM, bGStat, - bReadEkin, bEkinAveVel, bScaleEkin, bConstrain; + gmx_bool bStopCM, bGStat, bReadEkin, bEkinAveVel, bScaleEkin, bConstrain; gmx_bool bCheckNumberOfBondedInteractions; real dvdl_ekin; @@ -203,9 +216,7 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir } if (!bReadEkin) { - calc_ke_part( - x, v, box, - &(ir->opts), mdatoms, ekind, nrnb, bEkinAveVel); + calc_ke_part(x, v, box, &(ir->opts), mdatoms, ekind, nrnb, bEkinAveVel); } } @@ -223,7 +234,6 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir * so signal that we still have to do it. */ *bSumEkinhOld = TRUE; - } else { @@ -231,11 +241,9 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir if (PAR(cr)) { wallcycle_start(wcycle, ewcMoveE); - global_stat(gstat, cr, enerd, force_vir, shake_vir, mu_tot, - ir, ekind, constr, bStopCM ? vcm : nullptr, - signalBuffer.size(), signalBuffer.data(), - totalNumberOfBondedInteractions, - *bSumEkinhOld, flags); + global_stat(gstat, cr, enerd, force_vir, shake_vir, mu_tot, ir, ekind, constr, + bStopCM ? vcm : nullptr, signalBuffer.size(), signalBuffer.data(), + totalNumberOfBondedInteractions, *bSumEkinhOld, flags); wallcycle_stop(wcycle, ewcMoveE); } signalCoordinator->finalizeSignals(); @@ -246,7 +254,7 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir if (bEner) { /* Calculate the amplitude of the cosine velocity profile */ - ekind->cosacc.vcos = ekind->cosacc.mvcos/mdatoms->tmass; + ekind->cosacc.vcos = ekind->cosacc.mvcos / mdatoms->tmass; } if (bTemp) @@ -258,8 +266,7 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir bEkinAveVel: If TRUE, we simply multiply ekin by ekinscale to get a full step kinetic energy. If FALSE, we average ekinh_old and ekinh*ekinscale_nhc to get an averaged half step kinetic energy. */ - enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, &dvdl_ekin, - bEkinAveVel, bScaleEkin); + enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, &dvdl_ekin, bEkinAveVel, bScaleEkin); enerd->dvdl_lin[efptMASS] = static_cast(dvdl_ekin); enerd->term[F_EKIN] = trace(ekind->ekin); @@ -287,12 +294,12 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir total_vir and pres tensors */ const DispersionCorrection::Correction correction = - fr->dispersionCorrection->calculate(lastbox, vdwLambda); + fr->dispersionCorrection->calculate(lastbox, vdwLambda); if (bEner) { - enerd->term[F_DISPCORR] = correction.energy; - enerd->term[F_EPOT] += correction.energy; + enerd->term[F_DISPCORR] = correction.energy; + enerd->term[F_EPOT] += correction.energy; enerd->term[F_DVDL_VDW] += correction.dvdl; } if (bPres) @@ -300,16 +307,19 @@ void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir correction.correctVirial(total_vir); correction.correctPressure(pres); enerd->term[F_PDISPCORR] = correction.pressure; - enerd->term[F_PRES] += correction.pressure; + enerd->term[F_PRES] += correction.pressure; } } } -void setCurrentLambdasRerun(int64_t step, const t_lambda *fepvals, - const t_trxframe *rerun_fr, const double *lam0, - t_state *globalState) +void setCurrentLambdasRerun(int64_t step, + const t_lambda* fepvals, + const t_trxframe* rerun_fr, + const double* lam0, + t_state* globalState) { - GMX_RELEASE_ASSERT(globalState != nullptr, "setCurrentLambdasGlobalRerun should be called with a valid state object"); + GMX_RELEASE_ASSERT(globalState != nullptr, + "setCurrentLambdasGlobalRerun should be called with a valid state object"); if (rerun_fr->bLambda) { @@ -320,15 +330,16 @@ void setCurrentLambdasRerun(int64_t step, const t_lambda *fepvals, else { /* find out between which two value of lambda we should be */ - real frac = step*fepvals->delta_lambda; - int fep_state = static_cast(std::floor(frac*fepvals->n_lambda)); + real frac = step * fepvals->delta_lambda; + int fep_state = static_cast(std::floor(frac * fepvals->n_lambda)); /* interpolate between this state and the next */ /* this assumes that the initial lambda corresponds to lambda==0, which is verified in grompp */ - frac = frac*fepvals->n_lambda - fep_state; + frac = frac * fepvals->n_lambda - fep_state; for (int i = 0; i < efptNR; i++) { - globalState->lambda[i] = lam0[i] + (fepvals->all_lambda[i][fep_state]) + - frac*(fepvals->all_lambda[i][fep_state+1] - fepvals->all_lambda[i][fep_state]); + globalState->lambda[i] = + lam0[i] + (fepvals->all_lambda[i][fep_state]) + + frac * (fepvals->all_lambda[i][fep_state + 1] - fepvals->all_lambda[i][fep_state]); } } } @@ -342,26 +353,28 @@ void setCurrentLambdasRerun(int64_t step, const t_lambda *fepvals, } } -void setCurrentLambdasLocal(const int64_t step, const t_lambda *fepvals, - const double *lam0, gmx::ArrayRef lambda, - const int currentFEPState) +void setCurrentLambdasLocal(const int64_t step, + const t_lambda* fepvals, + const double* lam0, + gmx::ArrayRef lambda, + const int currentFEPState) /* find the current lambdas. If rerunning, we either read in a state, or a lambda value, requiring different logic. */ { if (fepvals->delta_lambda != 0) { /* find out between which two value of lambda we should be */ - real frac = step*fepvals->delta_lambda; + real frac = step * fepvals->delta_lambda; if (fepvals->n_lambda > 0) { - int fep_state = static_cast(std::floor(frac*fepvals->n_lambda)); + int fep_state = static_cast(std::floor(frac * fepvals->n_lambda)); /* interpolate between this state and the next */ /* this assumes that the initial lambda corresponds to lambda==0, which is verified in grompp */ - frac = frac*fepvals->n_lambda - fep_state; + frac = frac * fepvals->n_lambda - fep_state; for (int i = 0; i < efptNR; i++) { - lambda[i] = lam0[i] + (fepvals->all_lambda[i][fep_state]) + - frac*(fepvals->all_lambda[i][fep_state + 1] - fepvals->all_lambda[i][fep_state]); + lambda[i] = lam0[i] + (fepvals->all_lambda[i][fep_state]) + + frac * (fepvals->all_lambda[i][fep_state + 1] - fepvals->all_lambda[i][fep_state]); } } else @@ -385,7 +398,7 @@ void setCurrentLambdasLocal(const int64_t step, const t_lambda *fepvals, } } -static void min_zero(int *n, int i) +static void min_zero(int* n, int i) { if (i > 0 && (*n == 0 || i < *n)) { @@ -407,10 +420,9 @@ static int lcd4(int i1, int i2, int i3, int i4) gmx_incons("All 4 inputs for determining nstglobalcomm are <= 0"); } - while (nst > 1 && ((i1 > 0 && i1 % nst != 0) || - (i2 > 0 && i2 % nst != 0) || - (i3 > 0 && i3 % nst != 0) || - (i4 > 0 && i4 % nst != 0))) + while (nst > 1 + && ((i1 > 0 && i1 % nst != 0) || (i2 > 0 && i2 % nst != 0) || (i3 > 0 && i3 % nst != 0) + || (i4 > 0 && i4 % nst != 0))) { nst--; } @@ -418,17 +430,12 @@ static int lcd4(int i1, int i2, int i3, int i4) return nst; } -int computeGlobalCommunicationPeriod(const gmx::MDLogger &mdlog, - t_inputrec *ir, - const t_commrec *cr) +int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, t_inputrec* ir, const t_commrec* cr) { int nstglobalcomm; { // Set up the default behaviour - if (!(ir->nstcalcenergy > 0 || - ir->nstlist > 0 || - ir->etc != etcNO || - ir->epc != epcNO)) + if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != etcNO || ir->epc != epcNO)) { /* The user didn't choose the period for anything important, so we just make sure we can send signals and @@ -450,9 +457,7 @@ int computeGlobalCommunicationPeriod(const gmx::MDLogger &mdlog, * here a leftover of the twin-range scheme? Can we remove * nstlist when we remove the group scheme? */ - nstglobalcomm = lcd4(ir->nstcalcenergy, - ir->nstlist, - ir->etc != etcNO ? ir->nsttcouple : 0, + nstglobalcomm = lcd4(ir->nstcalcenergy, ir->nstlist, ir->etc != etcNO ? ir->nsttcouple : 0, ir->epc != epcNO ? ir->nstpcouple : 0); } } @@ -461,25 +466,24 @@ int computeGlobalCommunicationPeriod(const gmx::MDLogger &mdlog, // a (performance) note and mdrun should not change ir. if (ir->comm_mode != ecmNO && ir->nstcomm < nstglobalcomm) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "WARNING: Changing nstcomm from %d to %d", - ir->nstcomm, nstglobalcomm); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted("WARNING: Changing nstcomm from %d to %d", ir->nstcomm, nstglobalcomm); ir->nstcomm = nstglobalcomm; } if (cr->nnodes > 1) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Intra-simulation communication will occur every %d steps.\n", nstglobalcomm); + GMX_LOG(mdlog.info) + .appendTextFormatted("Intra-simulation communication will occur every %d steps.\n", + nstglobalcomm); } return nstglobalcomm; - } -void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, - gmx_bool *bLastStep) +void rerun_parallel_comm(t_commrec* cr, t_trxframe* fr, gmx_bool* bLastStep) { - rvec *xp, *vp; + rvec *xp, *vp; if (MASTER(cr) && *bLastStep) { @@ -492,11 +496,10 @@ void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, fr->v = vp; *bLastStep = (fr->natoms < 0); - } // TODO Most of this logic seems to belong in the respective modules -void set_state_entries(t_state *state, const t_inputrec *ir) +void set_state_entries(t_state* state, const t_inputrec* ir) { /* The entries in the state in the tpx file might not correspond * with what is needed, so we correct this here. @@ -504,57 +507,59 @@ void set_state_entries(t_state *state, const t_inputrec *ir) state->flags = 0; if (ir->efep != efepNO || ir->bExpanded) { - state->flags |= (1<flags |= (1<flags |= (1 << estLAMBDA); + state->flags |= (1 << estFEPSTATE); } - state->flags |= (1<x.size() == state->natoms, "We should start a run with an initialized state->x"); + state->flags |= (1 << estX); + GMX_RELEASE_ASSERT(state->x.size() == state->natoms, + "We should start a run with an initialized state->x"); if (EI_DYNAMICS(ir->eI)) { - state->flags |= (1<flags |= (1 << estV); } state->nnhpres = 0; if (ir->ePBC != epbcNONE) { - state->flags |= (1<flags |= (1 << estBOX); if (inputrecPreserveShape(ir)) { - state->flags |= (1<flags |= (1 << estBOX_REL); } if ((ir->epc == epcPARRINELLORAHMAN) || (ir->epc == epcMTTK)) { - state->flags |= (1<flags |= (1<flags |= (1 << estBOXV); + state->flags |= (1 << estPRES_PREV); } if (inputrecNptTrotter(ir) || (inputrecNphTrotter(ir))) { state->nnhpres = 1; - state->flags |= (1<flags |= (1<flags |= (1<flags |= (1<flags |= (1<flags |= (1<flags |= (1 << estNHPRES_XI); + state->flags |= (1 << estNHPRES_VXI); + state->flags |= (1 << estSVIR_PREV); + state->flags |= (1 << estFVIR_PREV); + state->flags |= (1 << estVETA); + state->flags |= (1 << estVOL0); } if (ir->epc == epcBERENDSEN) { - state->flags |= (1<flags |= (1 << estBAROS_INT); } } if (ir->etc == etcNOSEHOOVER) { - state->flags |= (1<flags |= (1<flags |= (1 << estNH_XI); + state->flags |= (1 << estNH_VXI); } if (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN) { - state->flags |= (1<flags |= (1 << estTHERM_INT); } - init_gtc_state(state, state->ngtc, state->nnhpres, ir->opts.nhchainlength); /* allocate the space for nose-hoover chains */ + init_gtc_state(state, state->ngtc, state->nnhpres, + ir->opts.nhchainlength); /* allocate the space for nose-hoover chains */ init_ekinstate(&state->ekinstate, ir); if (ir->bExpanded) @@ -565,6 +570,6 @@ void set_state_entries(t_state *state, const t_inputrec *ir) if (ir->pull && ir->pull->bSetPbcRefToPrevStepCOM) { - state->flags |= (1<flags |= (1 << estPULLCOMPREVSTEP); } } diff --git a/src/gromacs/mdlib/md_support.h b/src/gromacs/mdlib/md_support.h index 5a92104105..7023f4ec51 100644 --- a/src/gromacs/mdlib/md_support.h +++ b/src/gromacs/mdlib/md_support.h @@ -56,70 +56,71 @@ struct t_trxframe; namespace gmx { -template class ArrayRef; +template +class ArrayRef; class Constraints; class MDLogger; class SimulationSignaller; -} +} // namespace gmx /* Define a number of flags to better control the information * passed to compute_globals in md.c and global_stat. */ /* we are computing the kinetic energy from average velocities */ -#define CGLO_EKINAVEVEL (1u<<2u) +#define CGLO_EKINAVEVEL (1u << 2u) /* we are removing the center of mass momenta */ -#define CGLO_STOPCM (1u<<3u) +#define CGLO_STOPCM (1u << 3u) /* bGStat is defined in do_md */ -#define CGLO_GSTAT (1u<<4u) +#define CGLO_GSTAT (1u << 4u) /* Sum the energy terms in global computation */ -#define CGLO_ENERGY (1u<<6u) +#define CGLO_ENERGY (1u << 6u) /* Sum the kinetic energy terms in global computation */ -#define CGLO_TEMPERATURE (1u<<7u) +#define CGLO_TEMPERATURE (1u << 7u) /* Sum the kinetic energy terms in global computation */ -#define CGLO_PRESSURE (1u<<8u) +#define CGLO_PRESSURE (1u << 8u) /* Sum the constraint term in global computation */ -#define CGLO_CONSTRAINT (1u<<9u) +#define CGLO_CONSTRAINT (1u << 9u) /* Reading ekin from the trajectory */ -#define CGLO_READEKIN (1u<<10u) +#define CGLO_READEKIN (1u << 10u) /* we need to reset the ekin rescaling factor here */ -#define CGLO_SCALEEKIN (1u<<11u) +#define CGLO_SCALEEKIN (1u << 11u) /* After a new DD partitioning, we need to set a flag to schedule * global reduction of the total number of bonded interactions that * will be computed, to check none are missing. */ -#define CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS (1u<<12u) +#define CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS (1u << 12u) /*! \brief Return the number of steps that will take place between * intra-simulation communications, given the constraints of the * inputrec. */ -int computeGlobalCommunicationPeriod(const gmx::MDLogger &mdlog, - t_inputrec *ir, - const t_commrec *cr); +int computeGlobalCommunicationPeriod(const gmx::MDLogger& mdlog, t_inputrec* ir, const t_commrec* cr); /*! \brief Return true if the \p value is equal across the set of multi-simulations * * \todo This duplicates some of check_multi_int. Consolidate. */ -bool multisim_int_all_are_equal(const gmx_multisim_t *ms, - int64_t value); +bool multisim_int_all_are_equal(const gmx_multisim_t* ms, int64_t value); -void rerun_parallel_comm(t_commrec *cr, t_trxframe *fr, - gmx_bool *bLastStep); +void rerun_parallel_comm(t_commrec* cr, t_trxframe* fr, gmx_bool* bLastStep); //! \brief Allocate and initialize node-local state entries -void set_state_entries(t_state *state, const t_inputrec *ir); +void set_state_entries(t_state* state, const t_inputrec* ir); /* Set the lambda values in the global state from a frame read with rerun */ -void setCurrentLambdasRerun(int64_t step, const t_lambda *fepvals, - const t_trxframe *rerun_fr, const double *lam0, - t_state *globalState); +void setCurrentLambdasRerun(int64_t step, + const t_lambda* fepvals, + const t_trxframe* rerun_fr, + const double* lam0, + t_state* globalState); /* Set the lambda values at each step of mdrun when they change */ -void setCurrentLambdasLocal(int64_t step, const t_lambda *fepvals, - const double *lam0, gmx::ArrayRef lambda, - int currentFEPState); +void setCurrentLambdasLocal(int64_t step, + const t_lambda* fepvals, + const double* lam0, + gmx::ArrayRef lambda, + int currentFEPState); -int multisim_min(const gmx_multisim_t *ms, int nmin, int n); +int multisim_min(const gmx_multisim_t* ms, int nmin, int n); /* Set an appropriate value for n across the whole multi-simulation */ @@ -129,15 +130,30 @@ int multisim_min(const gmx_multisim_t *ms, int nmin, int n); * and for COM removal with rotational and acceleration correction modes. * Velocities v are needed for kinetic energy calculation and for COM removal. */ -void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir, - t_forcerec *fr, gmx_ekindata_t *ekind, - const rvec *x, const rvec *v, const matrix box, - real vdwLambda, const t_mdatoms *mdatoms, - t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle, - gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir, - tensor pres, rvec mu_tot, gmx::Constraints *constr, - gmx::SimulationSignaller *signalCoordinator, - const matrix lastbox, int *totalNumberOfBondedInteractions, - gmx_bool *bSumEkinhOld, int flags); +void compute_globals(gmx_global_stat* gstat, + t_commrec* cr, + const t_inputrec* ir, + t_forcerec* fr, + gmx_ekindata_t* ekind, + const rvec* x, + const rvec* v, + const matrix box, + real vdwLambda, + const t_mdatoms* mdatoms, + t_nrnb* nrnb, + t_vcm* vcm, + gmx_wallcycle_t wcycle, + gmx_enerdata_t* enerd, + tensor force_vir, + tensor shake_vir, + tensor total_vir, + tensor pres, + rvec mu_tot, + gmx::Constraints* constr, + gmx::SimulationSignaller* signalCoordinator, + const matrix lastbox, + int* totalNumberOfBondedInteractions, + gmx_bool* bSumEkinhOld, + int flags); #endif diff --git a/src/gromacs/mdlib/mdatoms.cpp b/src/gromacs/mdlib/mdatoms.cpp index 45202fe9ed..fc5d3f2c96 100644 --- a/src/gromacs/mdlib/mdatoms.cpp +++ b/src/gromacs/mdlib/mdatoms.cpp @@ -60,10 +60,7 @@ namespace gmx { -MDAtoms::MDAtoms() - : mdatoms_(nullptr) -{ -} +MDAtoms::MDAtoms() : mdatoms_(nullptr) {} MDAtoms::~MDAtoms() { @@ -110,17 +107,15 @@ void MDAtoms::reserve(int newCapacity) mdatoms_->chargeA = chargeA_.data(); } -std::unique_ptr -makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, - const bool rankHasPmeGpuTask) +std::unique_ptr makeMDAtoms(FILE* fp, const gmx_mtop_t& mtop, const t_inputrec& ir, const bool rankHasPmeGpuTask) { - auto mdAtoms = std::make_unique(); + auto mdAtoms = std::make_unique(); // GPU transfers may want to use a suitable pinning mode. if (rankHasPmeGpuTask) { changePinningPolicy(&mdAtoms->chargeA_, pme_get_pinning_policy()); } - t_mdatoms *md; + t_mdatoms* md; snew(md, 1); mdAtoms->mdatoms_.reset(md); @@ -135,17 +130,17 @@ makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, } /* Determine the total system mass and perturbed atom counts */ - double totalMassA = 0.0; - double totalMassB = 0.0; + double totalMassA = 0.0; + double totalMassB = 0.0; - md->haveVsites = FALSE; - gmx_mtop_atomloop_block_t aloop = gmx_mtop_atomloop_block_init(&mtop); - const t_atom *atom; - int nmol; + md->haveVsites = FALSE; + gmx_mtop_atomloop_block_t aloop = gmx_mtop_atomloop_block_init(&mtop); + const t_atom* atom; + int nmol; while (gmx_mtop_atomloop_block_next(aloop, &atom, &nmol)) { - totalMassA += nmol*atom->m; - totalMassB += nmol*atom->mB; + totalMassA += nmol * atom->m; + totalMassB += nmol * atom->mB; if (atom->ptype == eptVSite) { @@ -175,8 +170,7 @@ makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, if (ir.efep != efepNO && fp) { - fprintf(fp, - "There are %d atoms and %d charges for free energy perturbation\n", + fprintf(fp, "There are %d atoms and %d charges for free energy perturbation\n", md->nPerturbed, md->nChargePerturbed); } @@ -197,24 +191,21 @@ makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, return mdAtoms; } -} // namespace gmx +} // namespace gmx -void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, - int nindex, const int *index, - int homenr, - gmx::MDAtoms *mdAtoms) +void atoms2md(const gmx_mtop_t* mtop, const t_inputrec* ir, int nindex, const int* index, int homenr, gmx::MDAtoms* mdAtoms) { - gmx_bool bLJPME; - const t_grpopts *opts; - int nthreads gmx_unused; + gmx_bool bLJPME; + const t_grpopts* opts; + int nthreads gmx_unused; bLJPME = EVDW_PME(ir->vdwtype); opts = &ir->opts; - const SimulationGroups &groups = mtop->groups; + const SimulationGroups& groups = mtop->groups; - auto md = mdAtoms->mdatoms(); + auto md = mdAtoms->mdatoms(); /* nindex>=0 indicates DD where we use an index */ if (nindex >= 0) { @@ -239,7 +230,8 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, * The padding needs to be with zeros, which we set later below. */ gmx::AlignedAllocationPolicy::free(md->invmass); - md->invmass = new(gmx::AlignedAllocationPolicy::malloc((md->nalloc + GMX_REAL_MAX_SIMD_WIDTH)*sizeof(*md->invmass)))real; + md->invmass = new (gmx::AlignedAllocationPolicy::malloc( + (md->nalloc + GMX_REAL_MAX_SIMD_WIDTH) * sizeof(*md->invmass))) real; srenew(md->invMassPerDim, md->nalloc); // TODO eventually we will have vectors and just resize // everything, but for now the semantics of md->nalloc being @@ -276,9 +268,8 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, { srenew(md->cACC, md->nalloc); } - if (opts->nFreeze && - (opts->ngfrz > 1 || - opts->nFreeze[0][XX] || opts->nFreeze[0][YY] || opts->nFreeze[0][ZZ])) + if (opts->nFreeze + && (opts->ngfrz > 1 || opts->nFreeze[0][XX] || opts->nFreeze[0][YY] || opts->nFreeze[0][ZZ])) { srenew(md->cFREEZE, md->nalloc); } @@ -315,7 +306,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, } } - int molb = 0; + int molb = 0; nthreads = gmx_omp_nthreads_get(emntDefault); #pragma omp parallel for num_threads(nthreads) schedule(static) firstprivate(molb) @@ -323,9 +314,9 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, { try { - int g, ag; - real mA, mB, fac; - real c6, c12; + int g, ag; + real mA, mB, fac; + real c6, c12; if (index == nullptr) { @@ -335,7 +326,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, { ag = index[i]; } - const t_atom &atom = mtopGetAtomParameters(mtop, ag, &molb); + const t_atom& atom = mtopGetAtomParameters(mtop, ag, &molb); if (md->cFREEZE) { @@ -361,16 +352,16 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, */ if (ir->bd_fric > 0) { - mA = 0.5*ir->bd_fric*ir->delta_t; - mB = 0.5*ir->bd_fric*ir->delta_t; + mA = 0.5 * ir->bd_fric * ir->delta_t; + mB = 0.5 * ir->bd_fric * ir->delta_t; } else { /* The friction coefficient is mass/tau_t */ - fac = ir->delta_t/opts->tau_t[md->cTC ? - groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag] : 0]; - mA = 0.5*atom.m*fac; - mB = 0.5*atom.mB*fac; + fac = ir->delta_t + / opts->tau_t[md->cTC ? groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag] : 0]; + mA = 0.5 * atom.m * fac; + mB = 0.5 * atom.mB * fac; } } else @@ -380,10 +371,10 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, } if (md->nMassPerturbed) { - md->massA[i] = mA; - md->massB[i] = mB; + md->massA[i] = mA; + md->massB[i] = mB; } - md->massT[i] = mA; + md->massT[i] = mA; if (mA == 0.0) { @@ -395,13 +386,14 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, else if (md->cFREEZE) { g = md->cFREEZE[i]; - GMX_ASSERT(opts->nFreeze != nullptr, "Must have freeze groups to initialize masses"); + GMX_ASSERT(opts->nFreeze != nullptr, + "Must have freeze groups to initialize masses"); if (opts->nFreeze[g][XX] && opts->nFreeze[g][YY] && opts->nFreeze[g][ZZ]) { /* Set the mass of completely frozen particles to ALMOST_ZERO * iso 0 to avoid div by zero in lincs or shake. */ - md->invmass[i] = ALMOST_ZERO; + md->invmass[i] = ALMOST_ZERO; } else { @@ -409,38 +401,38 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, * If such particles are constrained, the frozen dimensions * should not be updated with the constrained coordinates. */ - md->invmass[i] = 1.0/mA; + md->invmass[i] = 1.0 / mA; } for (int d = 0; d < DIM; d++) { - md->invMassPerDim[i][d] = (opts->nFreeze[g][d] ? 0 : 1.0/mA); + md->invMassPerDim[i][d] = (opts->nFreeze[g][d] ? 0 : 1.0 / mA); } } else { - md->invmass[i] = 1.0/mA; + md->invmass[i] = 1.0 / mA; for (int d = 0; d < DIM; d++) { - md->invMassPerDim[i][d] = 1.0/mA; + md->invMassPerDim[i][d] = 1.0 / mA; } } - md->chargeA[i] = atom.q; - md->typeA[i] = atom.type; + md->chargeA[i] = atom.q; + md->typeA[i] = atom.type; if (bLJPME) { - c6 = mtop->ffparams.iparams[atom.type*(mtop->ffparams.atnr+1)].lj.c6; - c12 = mtop->ffparams.iparams[atom.type*(mtop->ffparams.atnr+1)].lj.c12; - md->sqrt_c6A[i] = sqrt(c6); + c6 = mtop->ffparams.iparams[atom.type * (mtop->ffparams.atnr + 1)].lj.c6; + c12 = mtop->ffparams.iparams[atom.type * (mtop->ffparams.atnr + 1)].lj.c12; + md->sqrt_c6A[i] = sqrt(c6); if (c6 == 0.0 || c12 == 0) { md->sigmaA[i] = 1.0; } else { - md->sigmaA[i] = gmx::sixthroot(c12/c6); + md->sigmaA[i] = gmx::sixthroot(c12 / c6); } - md->sigma3A[i] = 1/(md->sigmaA[i]*md->sigmaA[i]*md->sigmaA[i]); + md->sigma3A[i] = 1 / (md->sigmaA[i] * md->sigmaA[i] * md->sigmaA[i]); } if (md->nPerturbed) { @@ -449,62 +441,63 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, md->typeB[i] = atom.typeB; if (bLJPME) { - c6 = mtop->ffparams.iparams[atom.typeB*(mtop->ffparams.atnr+1)].lj.c6; - c12 = mtop->ffparams.iparams[atom.typeB*(mtop->ffparams.atnr+1)].lj.c12; - md->sqrt_c6B[i] = sqrt(c6); + c6 = mtop->ffparams.iparams[atom.typeB * (mtop->ffparams.atnr + 1)].lj.c6; + c12 = mtop->ffparams.iparams[atom.typeB * (mtop->ffparams.atnr + 1)].lj.c12; + md->sqrt_c6B[i] = sqrt(c6); if (c6 == 0.0 || c12 == 0) { md->sigmaB[i] = 1.0; } else { - md->sigmaB[i] = gmx::sixthroot(c12/c6); + md->sigmaB[i] = gmx::sixthroot(c12 / c6); } - md->sigma3B[i] = 1/(md->sigmaB[i]*md->sigmaB[i]*md->sigmaB[i]); + md->sigma3B[i] = 1 / (md->sigmaB[i] * md->sigmaB[i] * md->sigmaB[i]); } } - md->ptype[i] = atom.ptype; + md->ptype[i] = atom.ptype; if (md->cTC) { - md->cTC[i] = groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag]; + md->cTC[i] = groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ag]; } - md->cENER[i] = getGroupType(groups, SimulationAtomGroupType::EnergyOutput, ag); + md->cENER[i] = getGroupType(groups, SimulationAtomGroupType::EnergyOutput, ag); if (md->cACC) { - md->cACC[i] = groups.groupNumbers[SimulationAtomGroupType::Acceleration][ag]; + md->cACC[i] = groups.groupNumbers[SimulationAtomGroupType::Acceleration][ag]; } if (md->cVCM) { - md->cVCM[i] = groups.groupNumbers[SimulationAtomGroupType::MassCenterVelocityRemoval][ag]; + md->cVCM[i] = groups.groupNumbers[SimulationAtomGroupType::MassCenterVelocityRemoval][ag]; } if (md->cORF) { - md->cORF[i] = getGroupType(groups, SimulationAtomGroupType::OrientationRestraintsFit, ag); + md->cORF[i] = getGroupType(groups, SimulationAtomGroupType::OrientationRestraintsFit, ag); } if (md->cU1) { - md->cU1[i] = groups.groupNumbers[SimulationAtomGroupType::User1][ag]; + md->cU1[i] = groups.groupNumbers[SimulationAtomGroupType::User1][ag]; } if (md->cU2) { - md->cU2[i] = groups.groupNumbers[SimulationAtomGroupType::User2][ag]; + md->cU2[i] = groups.groupNumbers[SimulationAtomGroupType::User2][ag]; } if (ir->bQMMM) { - if (groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty() || - groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][ag] < groups.groups[SimulationAtomGroupType::QuantumMechanics].size()-1) + if (groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].empty() + || groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics][ag] + < groups.groups[SimulationAtomGroupType::QuantumMechanics].size() - 1) { - md->bQM[i] = TRUE; + md->bQM[i] = TRUE; } else { - md->bQM[i] = FALSE; + md->bQM[i] = FALSE; } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (md->nr > 0) @@ -524,7 +517,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, md->lambda = 0; } -void update_mdatoms(t_mdatoms *md, real lambda) +void update_mdatoms(t_mdatoms* md, real lambda) { if (md->nMassPerturbed && lambda != md->lambda) { @@ -537,16 +530,16 @@ void update_mdatoms(t_mdatoms *md, real lambda) { if (md->bPerturbed[i]) { - md->massT[i] = L1*md->massA[i] + lambda*md->massB[i]; + md->massT[i] = L1 * md->massA[i] + lambda * md->massB[i]; /* Atoms with invmass 0 or ALMOST_ZERO are massless or frozen * and their invmass does not depend on lambda. */ - if (md->invmass[i] > 1.1*ALMOST_ZERO) + if (md->invmass[i] > 1.1 * ALMOST_ZERO) { - md->invmass[i] = 1.0/md->massT[i]; + md->invmass[i] = 1.0 / md->massT[i]; for (int d = 0; d < DIM; d++) { - if (md->invMassPerDim[i][d] > 1.1*ALMOST_ZERO) + if (md->invMassPerDim[i][d] > 1.1 * ALMOST_ZERO) { md->invMassPerDim[i][d] = md->invmass[i]; } @@ -556,7 +549,7 @@ void update_mdatoms(t_mdatoms *md, real lambda) } /* Update the system mass for the change in lambda */ - md->tmass = L1*md->tmassA + lambda*md->tmassB; + md->tmass = L1 * md->tmassA + lambda * md->tmassB; } md->lambda = lambda; diff --git a/src/gromacs/mdlib/mdatoms.h b/src/gromacs/mdlib/mdatoms.h index 946223ecdf..2763e00a27 100644 --- a/src/gromacs/mdlib/mdatoms.h +++ b/src/gromacs/mdlib/mdatoms.h @@ -65,50 +65,44 @@ namespace gmx class MDAtoms { //! C-style mdatoms struct. - unique_cptr mdatoms_; + unique_cptr mdatoms_; //! Memory for chargeA that can be set up for efficient GPU transfer. gmx::PaddedHostVector chargeA_; - public: - // TODO make this private - MDAtoms(); - ~MDAtoms(); - //! Getter. - t_mdatoms *mdatoms() - { - return mdatoms_.get(); - } - //! Const getter. - const t_mdatoms *mdatoms() const - { - return mdatoms_.get(); - } - /*! \brief Resizes memory. - * - * \throws std::bad_alloc If out of memory. - */ - void resize(int newSize); - /*! \brief Reserves memory. - * - * \throws std::bad_alloc If out of memory. - */ - void reserve(int newCapacity); - //! Builder function. - friend std::unique_ptr - makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, - bool rankHasPmeGpuTask); + +public: + // TODO make this private + MDAtoms(); + ~MDAtoms(); + //! Getter. + t_mdatoms* mdatoms() { return mdatoms_.get(); } + //! Const getter. + const t_mdatoms* mdatoms() const { return mdatoms_.get(); } + /*! \brief Resizes memory. + * + * \throws std::bad_alloc If out of memory. + */ + void resize(int newSize); + /*! \brief Reserves memory. + * + * \throws std::bad_alloc If out of memory. + */ + void reserve(int newCapacity); + //! Builder function. + friend std::unique_ptr + makeMDAtoms(FILE* fp, const gmx_mtop_t& mtop, const t_inputrec& ir, bool rankHasPmeGpuTask); }; //! Builder function for MdAtomsWrapper. -std::unique_ptr -makeMDAtoms(FILE *fp, const gmx_mtop_t &mtop, const t_inputrec &ir, - bool useGpuForPme); +std::unique_ptr makeMDAtoms(FILE* fp, const gmx_mtop_t& mtop, const t_inputrec& ir, bool useGpuForPme); -} // namespace gmx +} // namespace gmx -void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, - int nindex, const int *index, - int homenr, - gmx::MDAtoms *mdAtoms); +void atoms2md(const gmx_mtop_t* mtop, + const t_inputrec* ir, + int nindex, + const int* index, + int homenr, + gmx::MDAtoms* mdAtoms); /* This routine copies the atoms->atom struct into md. * If index!=NULL only the indexed atoms are copied. * For the masses the A-state (lambda=0) mass is used. @@ -117,7 +111,7 @@ void atoms2md(const gmx_mtop_t *mtop, const t_inputrec *ir, * to set the masses corresponding to the value of lambda at each step. */ -void update_mdatoms(t_mdatoms *md, real lambda); +void update_mdatoms(t_mdatoms* md, real lambda); /* When necessary, sets all the mass parameters to values corresponding * to the free-energy parameter lambda. * Sets md->lambda = lambda. diff --git a/src/gromacs/mdlib/mdebin_bar.cpp b/src/gromacs/mdlib/mdebin_bar.cpp index 6a6d467999..a0db609099 100644 --- a/src/gromacs/mdlib/mdebin_bar.cpp +++ b/src/gromacs/mdlib/mdebin_bar.cpp @@ -61,17 +61,21 @@ constexpr int c_subblockDNumPreEntries = 5; constexpr int c_subblockINumPreEntries = 2; /* reset the delta_h list to prepare it for new values */ -static void mde_delta_h_reset(t_mde_delta_h *dh) +static void mde_delta_h_reset(t_mde_delta_h* dh) { dh->ndh = 0; dh->written = FALSE; } /* initialize the delta_h list */ -static void mde_delta_h_init(t_mde_delta_h *dh, int nbins, - double dx, unsigned int ndhmax, - int type, int derivative, int nlambda, - const double *lambda) +static void mde_delta_h_init(t_mde_delta_h* dh, + int nbins, + double dx, + unsigned int ndhmax, + int type, + int derivative, + int nlambda, + const double* lambda) { int i; @@ -87,9 +91,9 @@ static void mde_delta_h_init(t_mde_delta_h *dh, int nbins, } - snew(dh->subblock_meta_d, dh->nlambda+1); + snew(dh->subblock_meta_d, dh->nlambda + 1); - dh->ndhmax = ndhmax+2; + dh->ndhmax = ndhmax + 2; for (i = 0; i < 2; i++) { dh->bin[i] = nullptr; @@ -98,7 +102,7 @@ static void mde_delta_h_init(t_mde_delta_h *dh, int nbins, snew(dh->dh, dh->ndhmax); snew(dh->dhf, dh->ndhmax); - if (nbins <= 0 || dx < GMX_REAL_EPS*10) + if (nbins <= 0 || dx < GMX_REAL_EPS * 10) { dh->nhist = 0; } @@ -117,7 +121,7 @@ static void mde_delta_h_init(t_mde_delta_h *dh, int nbins, mde_delta_h_reset(dh); } -static void done_mde_delta_h(t_mde_delta_h *dh) +static void done_mde_delta_h(t_mde_delta_h* dh) { sfree(dh->lambda); sfree(dh->subblock_meta_d); @@ -130,7 +134,7 @@ static void done_mde_delta_h(t_mde_delta_h *dh) } /* Add a value to the delta_h list */ -static void mde_delta_h_add_dh(t_mde_delta_h *dh, double delta_h) +static void mde_delta_h_add_dh(t_mde_delta_h* dh, double delta_h) { if (dh->ndh >= dh->ndhmax) { @@ -141,7 +145,7 @@ static void mde_delta_h_add_dh(t_mde_delta_h *dh, double delta_h) } /* construct histogram with index hi */ -static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) +static void mde_delta_h_make_hist(t_mde_delta_h* dh, int hi, gmx_bool invert) { double min_dh = FLT_MAX; double max_dh = -FLT_MAX; @@ -149,7 +153,7 @@ static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) double max_dh_hist; /* maximum binnable dh value */ double min_dh_hist; /* minimum binnable dh value */ double dx = dh->dx; - double f; /* energy mult. factor */ + double f; /* energy mult. factor */ /* by applying a -1 scaling factor on the energies we get the same as having a negative dx, but we don't need to fix the min/max values @@ -159,13 +163,13 @@ static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) /* first find min and max */ for (i = 0; i < dh->ndh; i++) { - if (f*dh->dh[i] < min_dh) + if (f * dh->dh[i] < min_dh) { - min_dh = f*dh->dh[i]; + min_dh = f * dh->dh[i]; } - if (f*dh->dh[i] > max_dh) + if (f * dh->dh[i] > max_dh) { - max_dh = f*dh->dh[i]; + max_dh = f * dh->dh[i]; } } @@ -182,10 +186,10 @@ static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) Get this start value in number of histogram dxs from zero, as an integer.*/ - dh->x0[hi] = static_cast(floor(min_dh/dx)); + dh->x0[hi] = static_cast(floor(min_dh / dx)); - min_dh_hist = (dh->x0[hi])*dx; - max_dh_hist = (dh->x0[hi] + dh->nbins + 1)*dx; + min_dh_hist = (dh->x0[hi]) * dx; + max_dh_hist = (dh->x0[hi] + dh->nbins + 1) * dx; /* and fill the histogram*/ for (i = 0; i < dh->ndh; i++) @@ -196,18 +200,18 @@ static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) add it to the last bin. We check the max_dh_int range because converting to integers might lead to overflow with unpredictable results.*/ - if ( (f*dh->dh[i] >= min_dh_hist) && (f*dh->dh[i] <= max_dh_hist ) ) + if ((f * dh->dh[i] >= min_dh_hist) && (f * dh->dh[i] <= max_dh_hist)) { - bin = static_cast( (f*dh->dh[i] - min_dh_hist)/dx ); + bin = static_cast((f * dh->dh[i] - min_dh_hist) / dx); } else { - bin = dh->nbins-1; + bin = dh->nbins - 1; } /* double-check here because of possible round-off errors*/ if (bin >= dh->nbins) { - bin = dh->nbins-1; + bin = dh->nbins - 1; } if (bin > dh->maxbin[hi]) { @@ -220,14 +224,14 @@ static void mde_delta_h_make_hist(t_mde_delta_h *dh, int hi, gmx_bool invert) /* make sure we include a bin with 0 if we didn't use the full histogram width. This can then be used as an indication that all the data was binned. */ - if (dh->maxbin[hi] < dh->nbins-1) + if (dh->maxbin[hi] < dh->nbins - 1) { dh->maxbin[hi] += 1; } } -static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) +static void mde_delta_h_handle_block(t_mde_delta_h* dh, t_enxblock* blk) { /* first check which type we should use: histogram or raw data */ if (dh->nhist == 0) @@ -248,9 +252,9 @@ static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) applicable (in indices starting from first coord in the main delta_h_coll) */ - blk->sub[0].nr = 2; - blk->sub[0].type = xdr_datatype_int; - blk->sub[0].ival = dh->subblock_meta_i; + blk->sub[0].nr = 2; + blk->sub[0].type = xdr_datatype_int; + blk->sub[0].ival = dh->subblock_meta_i; /* subblock 2 */ for (i = 0; i < dh->nlambda; i++) @@ -309,7 +313,7 @@ static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) nhist_written++; /* check whether this histogram contains all data: if the last bin is 0, it does */ - if (dh->bin[i][dh->nbins-1] == 0) + if (dh->bin[i][dh->nbins - 1] == 0) { prev_complete = TRUE; } @@ -325,7 +329,7 @@ static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) /* A histogram consists of 2, 3 or 4 subblocks: the foreign lambda value + histogram spacing, the starting point, and the histogram data (0, 1 or 2 blocks). */ - add_subblocks_enxblock(blk, nhist_written+2); + add_subblocks_enxblock(blk, nhist_written + 2); blk->id = enxDHHIST; /* subblock 1: the lambda value + the histogram spacing */ @@ -339,18 +343,18 @@ static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) dh->subblock_meta_d[0] = -1; for (i = 0; i < dh->nlambda; i++) { - dh->subblock_meta_d[2+i] = dh->lambda[i]; + dh->subblock_meta_d[2 + i] = dh->lambda[i]; } } dh->subblock_meta_d[1] = dh->dx; - blk->sub[0].nr = 2+ ((dh->nlambda > 1) ? dh->nlambda : 0); + blk->sub[0].nr = 2 + ((dh->nlambda > 1) ? dh->nlambda : 0); blk->sub[0].type = xdr_datatype_double; blk->sub[0].dval = dh->subblock_meta_d; /* subblock 2: the starting point(s) as a long integer */ dh->subblock_meta_l[0] = nhist_written; dh->subblock_meta_l[1] = dh->type; /*dh->derivative ? 1 : 0;*/ - k = 2; + k = 2; for (i = 0; i < nhist_written; i++) { dh->subblock_meta_l[k++] = dh->x0[i]; @@ -358,39 +362,39 @@ static void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) /* append the derivative data */ dh->subblock_meta_l[k++] = dh->derivative; - blk->sub[1].nr = nhist_written+3; + blk->sub[1].nr = nhist_written + 3; blk->sub[1].type = xdr_datatype_int64; blk->sub[1].lval = dh->subblock_meta_l; /* subblock 3 + 4 : the histogram data */ for (i = 0; i < nhist_written; i++) { - blk->sub[i+2].nr = dh->maxbin[i]+1; /* it's +1 because size=index+1 - in C */ - blk->sub[i+2].type = xdr_datatype_int; - blk->sub[i+2].ival = dh->bin[i]; + blk->sub[i + 2].nr = dh->maxbin[i] + 1; /* it's +1 because size=index+1 + in C */ + blk->sub[i + 2].type = xdr_datatype_int; + blk->sub[i + 2].ival = dh->bin[i]; } } } /* initialize the collection*/ -void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) +void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir) { int i, j, n; - double *lambda_vec; - int ndhmax = ir->nstenergy/ir->nstcalcenergy; - t_lambda *fep = ir->fepvals; + double* lambda_vec; + int ndhmax = ir->nstenergy / ir->nstcalcenergy; + t_lambda* fep = ir->fepvals; dhc->temperature = ir->opts.ref_t[0]; /* only store system temperature */ dhc->start_time = 0.; - dhc->delta_time = ir->delta_t*ir->fepvals->nstdhdl; + dhc->delta_time = ir->delta_t * ir->fepvals->nstdhdl; dhc->start_time_set = FALSE; /* this is the compatibility lambda value. If it is >=0, it is valid, and there is either an old-style lambda or a slow growth simulation. */ dhc->start_lambda = ir->fepvals->init_lambda; /* for continuous change of lambda values */ - dhc->delta_lambda = ir->fepvals->delta_lambda*ir->fepvals->nstdhdl; + dhc->delta_lambda = ir->fepvals->delta_lambda * ir->fepvals->nstdhdl; if (dhc->start_lambda < 0) { @@ -412,11 +416,9 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) if (fep->separate_dvdl[i]) { dhc->native_lambda_components[j] = i; - if (fep->init_fep_state >= 0 && - fep->init_fep_state < fep->n_lambda) + if (fep->init_fep_state >= 0 && fep->init_fep_state < fep->n_lambda) { - dhc->native_lambda_vec[j] = - fep->all_lambda[i][fep->init_fep_state]; + dhc->native_lambda_vec[j] = fep->all_lambda[i][fep->init_fep_state]; } else { @@ -463,14 +465,14 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) { if (ir->fepvals->separate_dvdl[i]) { - dhc->ndh += 1; + dhc->ndh += 1; dhc->ndhdl += 1; } } } /* add the lambdas */ dhc->nlambda = ir->fepvals->lambda_stop_n - ir->fepvals->lambda_start_n; - dhc->ndh += dhc->nlambda; + dhc->ndh += dhc->nlambda; /* another compatibility check */ if (dhc->start_lambda < 0) { @@ -485,12 +487,12 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) if (ir->fepvals->edHdLPrintEnergy != edHdLPrintEnergyNO) { dhc->ndh += 1; - bEnergy = TRUE; + bEnergy = TRUE; } if (ir->epc > epcNO) { - dhc->ndh += 1; /* include pressure-volume work */ - bPV = TRUE; + dhc->ndh += 1; /* include pressure-volume work */ + bPV = TRUE; } } /* allocate them */ @@ -502,18 +504,16 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) n = 0; if (bExpanded) { - dhc->dh_expanded = dhc->dh+n; - mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size, - ir->fepvals->dh_hist_spacing, ndhmax, - dhbtEXPANDED, 0, 0, nullptr); + dhc->dh_expanded = dhc->dh + n; + mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, + ndhmax, dhbtEXPANDED, 0, 0, nullptr); n++; } if (bEnergy) { - dhc->dh_energy = dhc->dh+n; - mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size, - ir->fepvals->dh_hist_spacing, ndhmax, - dhbtEN, 0, 0, nullptr); + dhc->dh_energy = dhc->dh + n; + mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, + ndhmax, dhbtEN, 0, 0, nullptr); n++; } /* add the dhdl's */ @@ -526,10 +526,8 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) if (ir->fepvals->separate_dvdl[i]) { /* we give it init_lambda for compatibility */ - mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size, - ir->fepvals->dh_hist_spacing, ndhmax, - dhbtDHDL, n_lambda_components, 1, - &(fep->init_lambda)); + mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, + ndhmax, dhbtDHDL, n_lambda_components, 1, &(fep->init_lambda)); n++; n_lambda_components++; } @@ -544,7 +542,6 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) n_lambda_components++; /* count the components */ } } - } /* add the lambdas */ dhc->dh_du = dhc->dh + n; @@ -561,24 +558,22 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, const t_inputrec *ir) } } - mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size, - ir->fepvals->dh_hist_spacing, ndhmax, - dhbtDH, 0, n_lambda_components, lambda_vec); + mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, + ndhmax, dhbtDH, 0, n_lambda_components, lambda_vec); n++; } sfree(lambda_vec); if (bPV) { - dhc->dh_pv = dhc->dh+n; - mde_delta_h_init(dhc->dh+n, ir->fepvals->dh_hist_size, - ir->fepvals->dh_hist_spacing, ndhmax, - dhbtPV, 0, 0, nullptr); + dhc->dh_pv = dhc->dh + n; + mde_delta_h_init(dhc->dh + n, ir->fepvals->dh_hist_size, ir->fepvals->dh_hist_spacing, + ndhmax, dhbtPV, 0, 0, nullptr); n++; } } } -void done_mde_delta_h_coll(t_mde_delta_h_coll *dhc) +void done_mde_delta_h_coll(t_mde_delta_h_coll* dhc) { if (dhc == nullptr) { @@ -597,12 +592,12 @@ void done_mde_delta_h_coll(t_mde_delta_h_coll *dhc) } /* add a bunch of samples - note fep_state is double to allow for better data storage */ -void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc, +void mde_delta_h_coll_add_dh(t_mde_delta_h_coll* dhc, double fep_state, double energy, double pV, - double *dhdl, - double *foreign_dU, + double* dhdl, + double* foreign_dU, double time) { int i; @@ -615,11 +610,11 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc, for (i = 0; i < dhc->ndhdl; i++) { - mde_delta_h_add_dh(dhc->dh_dhdl+i, dhdl[i]); + mde_delta_h_add_dh(dhc->dh_dhdl + i, dhdl[i]); } for (i = 0; i < dhc->nlambda; i++) { - mde_delta_h_add_dh(dhc->dh_du+i, foreign_dU[i]); + mde_delta_h_add_dh(dhc->dh_du + i, foreign_dU[i]); } if (dhc->dh_pv != nullptr) { @@ -633,21 +628,19 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc, { mde_delta_h_add_dh(dhc->dh_expanded, fep_state); } - } /* write the metadata associated with all the du blocks, and call handle_block to write out all the du blocks */ -void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc, - t_enxframe *fr, int nblock) +void mde_delta_h_coll_handle_block(t_mde_delta_h_coll* dhc, t_enxframe* fr, int nblock) { int i; - t_enxblock *blk; + t_enxblock* blk; /* add one block with one subblock as the collection's own data */ nblock++; add_blocks_enxframe(fr, nblock); - blk = fr->block + (nblock-1); + blk = fr->block + (nblock - 1); /* only allocate lambda vector component blocks if they must be written out for backward compatibility */ @@ -696,14 +689,14 @@ void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc, { nblock++; add_blocks_enxframe(fr, nblock); - blk = fr->block + (nblock-1); + blk = fr->block + (nblock - 1); - mde_delta_h_handle_block(dhc->dh+i, blk); + mde_delta_h_handle_block(dhc->dh + i, blk); } } /* reset the data for a new round */ -void mde_delta_h_coll_reset(t_mde_delta_h_coll *dhc) +void mde_delta_h_coll_reset(t_mde_delta_h_coll* dhc) { int i; for (i = 0; i < dhc->ndh; i++) @@ -718,8 +711,7 @@ void mde_delta_h_coll_reset(t_mde_delta_h_coll *dhc) } /* set the energyhistory variables to save state */ -void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll *dhc, - energyhistory_t *enerhist) +void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll* dhc, energyhistory_t* enerhist) { if (enerhist->deltaHForeignLambdas == nullptr) { @@ -727,13 +719,15 @@ void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll *dhc, enerhist->deltaHForeignLambdas->dh.resize(dhc->ndh); } - delta_h_history_t * const deltaH = enerhist->deltaHForeignLambdas.get(); + delta_h_history_t* const deltaH = enerhist->deltaHForeignLambdas.get(); - GMX_RELEASE_ASSERT(deltaH->dh.size() == static_cast(dhc->ndh), "energy history number of delta_h histograms should match inputrec's number"); + GMX_RELEASE_ASSERT( + deltaH->dh.size() == static_cast(dhc->ndh), + "energy history number of delta_h histograms should match inputrec's number"); for (int i = 0; i < dhc->ndh; i++) { - std::vector &dh = deltaH->dh[i]; + std::vector& dh = deltaH->dh[i]; dh.resize(dhc->dh[i].ndh); std::copy(dh.begin(), dh.end(), dhc->dh[i].dh); } @@ -742,14 +736,14 @@ void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll *dhc, } - /* restore the variables from an energyhistory */ -void mde_delta_h_coll_restore_energyhistory(t_mde_delta_h_coll *dhc, - const delta_h_history_t *deltaH) +void mde_delta_h_coll_restore_energyhistory(t_mde_delta_h_coll* dhc, const delta_h_history_t* deltaH) { GMX_RELEASE_ASSERT(dhc, "Should have delta_h histograms"); GMX_RELEASE_ASSERT(deltaH, "Should have delta_h histograms in energy history"); - GMX_RELEASE_ASSERT(deltaH->dh.size() == static_cast(dhc->ndh), "energy history number of delta_h histograms should match inputrec's number"); + GMX_RELEASE_ASSERT( + deltaH->dh.size() == static_cast(dhc->ndh), + "energy history number of delta_h histograms should match inputrec's number"); for (gmx::index i = 0; i < gmx::ssize(deltaH->dh); i++) { diff --git a/src/gromacs/mdlib/mdebin_bar.h b/src/gromacs/mdlib/mdebin_bar.h index e7ce32b6f3..c75ab4347c 100644 --- a/src/gromacs/mdlib/mdebin_bar.h +++ b/src/gromacs/mdlib/mdebin_bar.h @@ -49,93 +49,91 @@ struct t_enxframe; /* Data for one foreign lambda, or derivative. */ typedef struct { - real *dh; /* the raw energy data. */ - float *dhf; /* raw difference data -- in floats, for storage. */ - unsigned int ndh; /* number of data points */ - unsigned int ndhmax; /* the maximum number of points */ - - int nhist; /* the number of histograms. There can either be - 0 (for no histograms) - 1 (for 'foreign lambda' histograms) - 2 (for derivative histograms: there's - a 'forward' and 'backward' histogram - containing the minimum and maximum - values, respectively). */ - int *bin[2]; /* the histogram(s) */ - double dx; /* the histogram spacing in kJ/mol. This is the - same for the two histograms? */ - unsigned int nbins; /* the number of bins in the histograms*/ - int64_t x0[2]; /* the starting point in units of spacing - of the histogram */ - unsigned int maxbin[2]; /* highest bin number with data */ - - int type; /* the block type according to dhbtDH, etc. */ - int derivative; /* The derivative direction (as an index in the lambda - vector) if this delta_h contains derivatives */ - double *lambda; /* lambda vector (or NULL if not applicable) */ - int nlambda; /* length of the lambda vector */ - gmx_bool written; /* whether this data has already been written out */ - - int64_t subblock_meta_l[5]; /* metadata for an mdebin subblock for - I/O: for histogram counts, etc.*/ - double *subblock_meta_d; /* metadata subblock for I/O, used for - communicating doubles (i.e. the lambda - vector) */ - int subblock_meta_i[4]; /* metadata subblock for I/O, used for - communicating ints (i.e. derivative indices, - etc.) */ + real* dh; /* the raw energy data. */ + float* dhf; /* raw difference data -- in floats, for storage. */ + unsigned int ndh; /* number of data points */ + unsigned int ndhmax; /* the maximum number of points */ + + int nhist; /* the number of histograms. There can either be + 0 (for no histograms) + 1 (for 'foreign lambda' histograms) + 2 (for derivative histograms: there's + a 'forward' and 'backward' histogram + containing the minimum and maximum + values, respectively). */ + int* bin[2]; /* the histogram(s) */ + double dx; /* the histogram spacing in kJ/mol. This is the + same for the two histograms? */ + unsigned int nbins; /* the number of bins in the histograms*/ + int64_t x0[2]; /* the starting point in units of spacing + of the histogram */ + unsigned int maxbin[2]; /* highest bin number with data */ + + int type; /* the block type according to dhbtDH, etc. */ + int derivative; /* The derivative direction (as an index in the lambda + vector) if this delta_h contains derivatives */ + double* lambda; /* lambda vector (or NULL if not applicable) */ + int nlambda; /* length of the lambda vector */ + gmx_bool written; /* whether this data has already been written out */ + + int64_t subblock_meta_l[5]; /* metadata for an mdebin subblock for + I/O: for histogram counts, etc.*/ + double* subblock_meta_d; /* metadata subblock for I/O, used for + communicating doubles (i.e. the lambda + vector) */ + int subblock_meta_i[4]; /* metadata subblock for I/O, used for + communicating ints (i.e. derivative indices, + etc.) */ } t_mde_delta_h; /* the type definition is in mdebin_bar.h */ struct t_mde_delta_h_coll { - t_mde_delta_h *dh; /* the delta h data */ - int ndh; /* the number of delta_h structures */ - - int nlambda; /* number of bar dU delta_h structures */ - t_mde_delta_h *dh_du; /* the delta h data (pointer into dh) */ - - int ndhdl; /* number of bar dU delta_h structures */ - t_mde_delta_h *dh_dhdl; /* the dhdl data (pointer into dh) */ - - t_mde_delta_h *dh_energy; /* energy output block (pointer into dh) */ - t_mde_delta_h *dh_pv; /* pV output block (pointer into dh) */ - t_mde_delta_h *dh_expanded; /* expanded ensemble output block (pointer - into dh) */ - - double start_time; /* start time of the current dh collection */ - double delta_time; /* time difference between samples */ - gmx_bool start_time_set; /* whether the start time has been set */ - double start_lambda; /* starting lambda for continuous motion of state*/ - double delta_lambda; /* delta lambda, for continuous motion of state */ - double temperature; /* the temperature of the samples*/ - - double *native_lambda_vec; /* The lambda vector describing the current - lambda state if it is set (NULL otherwise) */ - int n_lambda_vec; /* the size of the native lambda vector */ - int *native_lambda_components; /* the native lambda (and by extension, - foreign lambda) components in terms - of efptFEP, efptMASS, etc. */ - int lambda_index; /* the lambda_fep_state */ - - double *subblock_d; /* for writing a metadata mdebin subblock for I/O */ - int *subblock_i; /* for writing a metadata mdebin subblock for I/O */ - - double *lambda_vec_subblock; /* native lambda vector data subblock for - I/O */ - int *lambda_index_subblock; /* lambda vector index data subblock for I/O */ + t_mde_delta_h* dh; /* the delta h data */ + int ndh; /* the number of delta_h structures */ + + int nlambda; /* number of bar dU delta_h structures */ + t_mde_delta_h* dh_du; /* the delta h data (pointer into dh) */ + + int ndhdl; /* number of bar dU delta_h structures */ + t_mde_delta_h* dh_dhdl; /* the dhdl data (pointer into dh) */ + + t_mde_delta_h* dh_energy; /* energy output block (pointer into dh) */ + t_mde_delta_h* dh_pv; /* pV output block (pointer into dh) */ + t_mde_delta_h* dh_expanded; /* expanded ensemble output block (pointer + into dh) */ + + double start_time; /* start time of the current dh collection */ + double delta_time; /* time difference between samples */ + gmx_bool start_time_set; /* whether the start time has been set */ + double start_lambda; /* starting lambda for continuous motion of state*/ + double delta_lambda; /* delta lambda, for continuous motion of state */ + double temperature; /* the temperature of the samples*/ + + double* native_lambda_vec; /* The lambda vector describing the current + lambda state if it is set (NULL otherwise) */ + int n_lambda_vec; /* the size of the native lambda vector */ + int* native_lambda_components; /* the native lambda (and by extension, + foreign lambda) components in terms + of efptFEP, efptMASS, etc. */ + int lambda_index; /* the lambda_fep_state */ + + double* subblock_d; /* for writing a metadata mdebin subblock for I/O */ + int* subblock_i; /* for writing a metadata mdebin subblock for I/O */ + + double* lambda_vec_subblock; /* native lambda vector data subblock for + I/O */ + int* lambda_index_subblock; /* lambda vector index data subblock for I/O */ }; - /* initialize a collection of delta h histograms/sets dhc = the collection ir = the input record */ -void mde_delta_h_coll_init(t_mde_delta_h_coll *dhc, - const t_inputrec *ir); +void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir); -void done_mde_delta_h_coll(t_mde_delta_h_coll *dhc); +void done_mde_delta_h_coll(t_mde_delta_h_coll* dhc); /* add a bunch of samples to the delta_h collection dhc = the collection @@ -147,12 +145,12 @@ void done_mde_delta_h_coll(t_mde_delta_h_coll *dhc); */ /* add a bunch of samples - note fep_state is double to allow for better data storage */ -void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc, +void mde_delta_h_coll_add_dh(t_mde_delta_h_coll* dhc, double fep_state, double energy, double pV, - double *dhdl, - double *foreign_dU, + double* dhdl, + double* foreign_dU, double time); /* write the data associated with the du blocks collection as a collection @@ -160,21 +158,18 @@ void mde_delta_h_coll_add_dh(t_mde_delta_h_coll *dhc, dhc = the collection fr = the enxio frame nblock = the current number of blocks */ -void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc, - t_enxframe *fr, int nblock); +void mde_delta_h_coll_handle_block(t_mde_delta_h_coll* dhc, t_enxframe* fr, int nblock); /* reset the collection of delta_h buffers for a new round of data gathering */ -void mde_delta_h_coll_reset(t_mde_delta_h_coll *dhc); +void mde_delta_h_coll_reset(t_mde_delta_h_coll* dhc); /* set the energyhistory variables to save state */ -void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll *dhc, - energyhistory_t *enerhist); +void mde_delta_h_coll_update_energyhistory(const t_mde_delta_h_coll* dhc, energyhistory_t* enerhist); /* restore the variables from an energyhistory */ -void mde_delta_h_coll_restore_energyhistory(t_mde_delta_h_coll *dhc, - const delta_h_history_t *deltaH); +void mde_delta_h_coll_restore_energyhistory(t_mde_delta_h_coll* dhc, const delta_h_history_t* deltaH); -#endif /* _mdebin_bar_h */ +#endif /* _mdebin_bar_h */ diff --git a/src/gromacs/mdlib/mdoutf.cpp b/src/gromacs/mdlib/mdoutf.cpp index 206cf02564..24215b1b33 100644 --- a/src/gromacs/mdlib/mdoutf.cpp +++ b/src/gromacs/mdlib/mdoutf.cpp @@ -60,44 +60,49 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -struct gmx_mdoutf { - t_fileio *fp_trn; - t_fileio *fp_xtc; - gmx_tng_trajectory_t tng; - gmx_tng_trajectory_t tng_low_prec; - int x_compression_precision; /* only used by XTC output */ - ener_file_t fp_ene; - const char *fn_cpt; - gmx_bool bKeepAndNumCPT; - int eIntegrator; - gmx_bool bExpanded; - int elamstats; - int simulation_part; - FILE *fp_dhdl; - int natoms_global; - int natoms_x_compressed; - SimulationGroups *groups; /* for compressed position writing */ - gmx_wallcycle_t wcycle; - rvec *f_global; - gmx::IMDOutputProvider *outputProvider; - const gmx::MdModulesNotifier *mdModulesNotifier; +struct gmx_mdoutf +{ + t_fileio* fp_trn; + t_fileio* fp_xtc; + gmx_tng_trajectory_t tng; + gmx_tng_trajectory_t tng_low_prec; + int x_compression_precision; /* only used by XTC output */ + ener_file_t fp_ene; + const char* fn_cpt; + gmx_bool bKeepAndNumCPT; + int eIntegrator; + gmx_bool bExpanded; + int elamstats; + int simulation_part; + FILE* fp_dhdl; + int natoms_global; + int natoms_x_compressed; + SimulationGroups* groups; /* for compressed position writing */ + gmx_wallcycle_t wcycle; + rvec* f_global; + gmx::IMDOutputProvider* outputProvider; + const gmx::MdModulesNotifier* mdModulesNotifier; }; -gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], - const gmx::MdrunOptions &mdrunOptions, - const t_commrec *cr, - gmx::IMDOutputProvider *outputProvider, - const gmx::MdModulesNotifier &mdModulesNotifier, - const t_inputrec *ir, gmx_mtop_t *top_global, - const gmx_output_env_t *oenv, gmx_wallcycle_t wcycle, - const gmx::StartingBehavior startingBehavior) +gmx_mdoutf_t init_mdoutf(FILE* fplog, + int nfile, + const t_filenm fnm[], + const gmx::MdrunOptions& mdrunOptions, + const t_commrec* cr, + gmx::IMDOutputProvider* outputProvider, + const gmx::MdModulesNotifier& mdModulesNotifier, + const t_inputrec* ir, + gmx_mtop_t* top_global, + const gmx_output_env_t* oenv, + gmx_wallcycle_t wcycle, + const gmx::StartingBehavior startingBehavior) { - gmx_mdoutf_t of; - const char *appendMode = "a+", *writeMode = "w+", *filemode; - gmx_bool bCiteTng = FALSE; - int i; - bool restartWithAppending = (startingBehavior == gmx::StartingBehavior::RestartWithAppending); + gmx_mdoutf_t of; + const char * appendMode = "a+", *writeMode = "w+", *filemode; + gmx_bool bCiteTng = FALSE; + int i; + bool restartWithAppending = (startingBehavior == gmx::StartingBehavior::RestartWithAppending); snew(of, 1); @@ -123,16 +128,13 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], filemode = restartWithAppending ? appendMode : writeMode; - if (EI_DYNAMICS(ir->eI) && - ir->nstxout_compressed > 0) + if (EI_DYNAMICS(ir->eI) && ir->nstxout_compressed > 0) { - const char *filename; + const char* filename; filename = ftp2fn(efCOMPRESSED, nfile, fnm); switch (fn2ftp(filename)) { - case efXTC: - of->fp_xtc = open_xtc(filename, filemode); - break; + case efXTC: of->fp_xtc = open_xtc(filename, filemode); break; case efTNG: gmx_tng_open(filename, filemode[0], &of->tng_low_prec); if (filemode[0] == 'w') @@ -141,20 +143,14 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], } bCiteTng = TRUE; break; - default: - gmx_incons("Invalid reduced precision file format"); + default: gmx_incons("Invalid reduced precision file format"); } } - if ((EI_DYNAMICS(ir->eI) || EI_ENERGY_MINIMIZATION(ir->eI)) && - (!GMX_FAHCORE && - !(EI_DYNAMICS(ir->eI) && - ir->nstxout == 0 && - ir->nstvout == 0 && - ir->nstfout == 0) - ) - ) + if ((EI_DYNAMICS(ir->eI) || EI_ENERGY_MINIMIZATION(ir->eI)) + && (!GMX_FAHCORE + && !(EI_DYNAMICS(ir->eI) && ir->nstxout == 0 && ir->nstvout == 0 && ir->nstfout == 0))) { - const char *filename; + const char* filename; filename = ftp2fn(efTRN, nfile, fnm); switch (fn2ftp(filename)) { @@ -163,8 +159,7 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], /* If there is no uncompressed coordinate output and there is compressed TNG output write forces and/or velocities to the TNG file instead. */ - if (ir->nstxout != 0 || ir->nstxout_compressed == 0 || - !of->tng_low_prec) + if (ir->nstxout != 0 || ir->nstxout_compressed == 0 || !of->tng_low_prec) { of->fp_trn = gmx_trr_open(filename, filemode); } @@ -177,8 +172,7 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], } bCiteTng = TRUE; break; - default: - gmx_incons("Invalid full precision file format"); + default: gmx_incons("Invalid full precision file format"); } } if (EI_DYNAMICS(ir->eI) || EI_ENERGY_MINIMIZATION(ir->eI)) @@ -187,9 +181,8 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, int nfile, const t_filenm fnm[], } of->fn_cpt = opt2fn("-cpo", nfile, fnm); - if ((ir->efep != efepNO || ir->bSimTemp) && ir->fepvals->nstdhdl > 0 && - (ir->fepvals->separate_dhdl_file == esepdhdlfileYES ) && - EI_DYNAMICS(ir->eI)) + if ((ir->efep != efepNO || ir->bSimTemp) && ir->fepvals->nstdhdl > 0 + && (ir->fepvals->separate_dhdl_file == esepdhdlfileYES) && EI_DYNAMICS(ir->eI)) { if (restartWithAppending) { @@ -238,7 +231,7 @@ ener_file_t mdoutf_get_fp_ene(gmx_mdoutf_t of) return of->fp_ene; } -FILE *mdoutf_get_fp_dhdl(gmx_mdoutf_t of) +FILE* mdoutf_get_fp_dhdl(gmx_mdoutf_t of) { return of->fp_dhdl; } @@ -248,16 +241,19 @@ gmx_wallcycle_t mdoutf_get_wcycle(gmx_mdoutf_t of) return of->wcycle; } -void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, - gmx_mdoutf_t of, - int mdof_flags, - int natoms, - int64_t step, double t, - t_state *state_local, t_state *state_global, - ObservablesHistory *observablesHistory, +void mdoutf_write_to_trajectory_files(FILE* fplog, + const t_commrec* cr, + gmx_mdoutf_t of, + int mdof_flags, + int natoms, + int64_t step, + double t, + t_state* state_local, + t_state* state_global, + ObservablesHistory* observablesHistory, gmx::ArrayRef f_local) { - rvec *f_global; + rvec* f_global; if (DOMAINDECOMP(cr)) { @@ -281,7 +277,8 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, f_global = of->f_global; if (mdof_flags & MDOF_F) { - dd_collect_vec(cr->dd, state_local, f_local, gmx::arrayRefFromArray(reinterpret_cast(f_global), f_local.size())); + dd_collect_vec(cr->dd, state_local, f_local, + gmx::arrayRefFromArray(reinterpret_cast(f_global), f_local.size())); } } else @@ -289,7 +286,7 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, /* We have the whole state locally: copy the local state pointer */ state_global = state_local; - f_global = as_rvec_array(f_local.data()); + f_global = as_rvec_array(f_local.data()); } if (MASTER(cr)) @@ -299,26 +296,23 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, fflush_tng(of->tng); fflush_tng(of->tng_low_prec); ivec one_ivec = { 1, 1, 1 }; - write_checkpoint(of->fn_cpt, of->bKeepAndNumCPT, - fplog, cr, + write_checkpoint(of->fn_cpt, of->bKeepAndNumCPT, fplog, cr, DOMAINDECOMP(cr) ? cr->dd->nc : one_ivec, - DOMAINDECOMP(cr) ? cr->dd->nnodes : cr->nnodes, - of->eIntegrator, of->simulation_part, - of->bExpanded, of->elamstats, step, t, + DOMAINDECOMP(cr) ? cr->dd->nnodes : cr->nnodes, of->eIntegrator, + of->simulation_part, of->bExpanded, of->elamstats, step, t, state_global, observablesHistory, *(of->mdModulesNotifier)); } if (mdof_flags & (MDOF_X | MDOF_V | MDOF_F)) { - const rvec *x = (mdof_flags & MDOF_X) ? state_global->x.rvec_array() : nullptr; - const rvec *v = (mdof_flags & MDOF_V) ? state_global->v.rvec_array() : nullptr; - const rvec *f = (mdof_flags & MDOF_F) ? f_global : nullptr; + const rvec* x = (mdof_flags & MDOF_X) ? state_global->x.rvec_array() : nullptr; + const rvec* v = (mdof_flags & MDOF_V) ? state_global->v.rvec_array() : nullptr; + const rvec* f = (mdof_flags & MDOF_F) ? f_global : nullptr; if (of->fp_trn) { gmx_trr_write_frame(of->fp_trn, step, t, state_local->lambda[efptFEP], - state_local->box, natoms, - x, v, f); + state_local->box, natoms, x, v, f); if (gmx_fio_flush(of->fp_trn) != 0) { gmx_file("Cannot write trajectory; maybe you are out of disk space?"); @@ -330,23 +324,19 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, else if (of->tng) { gmx_fwrite_tng(of->tng, FALSE, step, t, state_local->lambda[efptFEP], - state_local->box, - natoms, - x, v, f); + state_local->box, natoms, x, v, f); } /* If only a TNG file is open for compressed coordinate output (no uncompressed coordinate output) also write forces and velocities to it. */ else if (of->tng_low_prec) { gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, state_local->lambda[efptFEP], - state_local->box, - natoms, - x, v, f); + state_local->box, natoms, x, v, f); } } if (mdof_flags & MDOF_X_COMPRESSED) { - rvec *xxtc = nullptr; + rvec* xxtc = nullptr; if (of->natoms_x_compressed == of->natoms_global) { @@ -371,35 +361,28 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, } } } - if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, - state_local->box, xxtc, of->x_compression_precision) == 0) + if (write_xtc(of->fp_xtc, of->natoms_x_compressed, step, t, state_local->box, xxtc, + of->x_compression_precision) + == 0) { gmx_fatal(FARGS, "XTC error. This indicates you are out of disk space, or a " "simulation with major instabilities resulting in coordinates " "that are NaN or too large to be represented in the XTC format.\n"); } - gmx_fwrite_tng(of->tng_low_prec, - TRUE, - step, - t, - state_local->lambda[efptFEP], - state_local->box, - of->natoms_x_compressed, - xxtc, - nullptr, - nullptr); + gmx_fwrite_tng(of->tng_low_prec, TRUE, step, t, state_local->lambda[efptFEP], + state_local->box, of->natoms_x_compressed, xxtc, nullptr, nullptr); if (of->natoms_x_compressed != of->natoms_global) { sfree(xxtc); } } - if (mdof_flags & (MDOF_BOX | MDOF_LAMBDA) && !(mdof_flags & (MDOF_X | MDOF_V | MDOF_F)) ) + if (mdof_flags & (MDOF_BOX | MDOF_LAMBDA) && !(mdof_flags & (MDOF_X | MDOF_V | MDOF_F))) { if (of->tng) { real lambda = -1; - rvec *box = nullptr; + rvec* box = nullptr; if (mdof_flags & MDOF_BOX) { box = state_local->box; @@ -408,17 +391,16 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, { lambda = state_local->lambda[efptFEP]; } - gmx_fwrite_tng(of->tng, FALSE, step, t, lambda, - box, natoms, - nullptr, nullptr, nullptr); + gmx_fwrite_tng(of->tng, FALSE, step, t, lambda, box, natoms, nullptr, nullptr, nullptr); } } - if (mdof_flags & (MDOF_BOX_COMPRESSED | MDOF_LAMBDA_COMPRESSED) && !(mdof_flags & (MDOF_X_COMPRESSED)) ) + if (mdof_flags & (MDOF_BOX_COMPRESSED | MDOF_LAMBDA_COMPRESSED) + && !(mdof_flags & (MDOF_X_COMPRESSED))) { if (of->tng_low_prec) { real lambda = -1; - rvec *box = nullptr; + rvec* box = nullptr; if (mdof_flags & MDOF_BOX_COMPRESSED) { box = state_local->box; @@ -427,9 +409,8 @@ void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, { lambda = state_local->lambda[efptFEP]; } - gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda, - box, natoms, - nullptr, nullptr, nullptr); + gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda, box, natoms, nullptr, + nullptr, nullptr); } } } diff --git a/src/gromacs/mdlib/mdoutf.h b/src/gromacs/mdlib/mdoutf.h index 161bb6b301..efca1c6dd3 100644 --- a/src/gromacs/mdlib/mdoutf.h +++ b/src/gromacs/mdlib/mdoutf.h @@ -57,25 +57,25 @@ enum class StartingBehavior; class IMDOutputProvider; struct MdModulesNotifier; struct MdrunOptions; -} +} // namespace gmx -typedef struct gmx_mdoutf *gmx_mdoutf_t; +typedef struct gmx_mdoutf* gmx_mdoutf_t; /*! \brief Allocate and initialize object to manager trajectory writing output * * Returns a pointer to a data structure with all output file pointers * and names required by mdrun. */ -gmx_mdoutf_t init_mdoutf(FILE *fplog, +gmx_mdoutf_t init_mdoutf(FILE* fplog, int nfile, const t_filenm fnm[], - const gmx::MdrunOptions &mdrunOptions, - const t_commrec *cr, - gmx::IMDOutputProvider *outputProvider, - const gmx::MdModulesNotifier &mdModulesNotifier, - const t_inputrec *ir, - gmx_mtop_t *mtop, - const gmx_output_env_t *oenv, + const gmx::MdrunOptions& mdrunOptions, + const t_commrec* cr, + gmx::IMDOutputProvider* outputProvider, + const gmx::MdModulesNotifier& mdModulesNotifier, + const t_inputrec* ir, + gmx_mtop_t* mtop, + const gmx_output_env_t* oenv, gmx_wallcycle_t wcycle, gmx::StartingBehavior startingBehavior); @@ -83,7 +83,7 @@ gmx_mdoutf_t init_mdoutf(FILE *fplog, ener_file_t mdoutf_get_fp_ene(gmx_mdoutf_t of); /*! \brief Getter for file pointer */ -FILE *mdoutf_get_fp_dhdl(gmx_mdoutf_t of); +FILE* mdoutf_get_fp_dhdl(gmx_mdoutf_t of); /*! \brief Getter for wallcycle timer */ gmx_wallcycle_t mdoutf_get_wcycle(gmx_mdoutf_t of); @@ -117,13 +117,16 @@ void done_mdoutf(gmx_mdoutf_t of); * \param[in] observablesHistory Pointer to the ObservableHistory object. * \param[in] f_local The local forces. */ -void mdoutf_write_to_trajectory_files(FILE *fplog, const t_commrec *cr, - gmx_mdoutf_t of, - int mdof_flags, - int natoms, - int64_t step, double t, - t_state *state_local, t_state *state_global, - ObservablesHistory *observablesHistory, +void mdoutf_write_to_trajectory_files(FILE* fplog, + const t_commrec* cr, + gmx_mdoutf_t of, + int mdof_flags, + int natoms, + int64_t step, + double t, + t_state* state_local, + t_state* state_global, + ObservablesHistory* observablesHistory, gmx::ArrayRef f_local); /*! \brief Get the output interval of box size of uncompressed TNG output. @@ -146,15 +149,15 @@ int mdoutf_get_tng_compressed_box_output_interval(gmx_mdoutf_t of); */ int mdoutf_get_tng_compressed_lambda_output_interval(gmx_mdoutf_t of); -#define MDOF_X (1u<<0u) -#define MDOF_V (1u<<1u) -#define MDOF_F (1u<<2u) -#define MDOF_X_COMPRESSED (1u<<3u) -#define MDOF_CPT (1u<<4u) -#define MDOF_IMD (1u<<5u) -#define MDOF_BOX (1u<<6u) -#define MDOF_LAMBDA (1u<<7u) -#define MDOF_BOX_COMPRESSED (1u<<8u) -#define MDOF_LAMBDA_COMPRESSED (1u<<9u) +#define MDOF_X (1u << 0u) +#define MDOF_V (1u << 1u) +#define MDOF_F (1u << 2u) +#define MDOF_X_COMPRESSED (1u << 3u) +#define MDOF_CPT (1u << 4u) +#define MDOF_IMD (1u << 5u) +#define MDOF_BOX (1u << 6u) +#define MDOF_LAMBDA (1u << 7u) +#define MDOF_BOX_COMPRESSED (1u << 8u) +#define MDOF_LAMBDA_COMPRESSED (1u << 9u) #endif diff --git a/src/gromacs/mdlib/membed.cpp b/src/gromacs/mdlib/membed.cpp index 9474756249..aa6ebecd6c 100644 --- a/src/gromacs/mdlib/membed.cpp +++ b/src/gromacs/mdlib/membed.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,54 +62,58 @@ #include "gromacs/utility/smalloc.h" /* information about scaling center */ -typedef struct { - rvec xmin; /* smallest coordinates of all embedded molecules */ - rvec xmax; /* largest coordinates of all embedded molecules */ - rvec *geom_cent; /* scaling center of each independent molecule to embed */ - int pieces; /* number of molecules to embed independently */ - int *nidx; /* n atoms for every independent embedded molecule (index in subindex) */ - int **subindex; /* atomids for independent molecule * - * atoms of piece i run from subindex[i][0] to subindex[i][nidx[i]] */ +typedef struct +{ + rvec xmin; /* smallest coordinates of all embedded molecules */ + rvec xmax; /* largest coordinates of all embedded molecules */ + rvec* geom_cent; /* scaling center of each independent molecule to embed */ + int pieces; /* number of molecules to embed independently */ + int* nidx; /* n atoms for every independent embedded molecule (index in subindex) */ + int** subindex; /* atomids for independent molecule * + * atoms of piece i run from subindex[i][0] to subindex[i][nidx[i]] */ } pos_ins_t; /* variables needed in do_md */ -struct gmx_membed_t { - int it_xy; /* number of iterations (steps) used to grow something in the xy-plane */ - int it_z; /* same, but for z */ - real xy_step; /* stepsize used during resize in xy-plane */ - real z_step; /* same, but in z */ - rvec fac; /* initial scaling of the molecule to grow into the membrane */ - rvec *r_ins; /* final coordinates of the molecule to grow */ - pos_ins_t *pos_ins; /* scaling center for each piece to embed */ +struct gmx_membed_t +{ + int it_xy; /* number of iterations (steps) used to grow something in the xy-plane */ + int it_z; /* same, but for z */ + real xy_step; /* stepsize used during resize in xy-plane */ + real z_step; /* same, but in z */ + rvec fac; /* initial scaling of the molecule to grow into the membrane */ + rvec* r_ins; /* final coordinates of the molecule to grow */ + pos_ins_t* pos_ins; /* scaling center for each piece to embed */ }; /* membrane related variables */ -typedef struct { - char *name; /* name of index group to embed molecule into (usually membrane) */ - t_block mem_at; /* list all atoms in membrane */ - int nmol; /* number of membrane molecules overlapping with the molecule to embed */ - int *mol_id; /* list of molecules in membrane that overlap with the molecule to embed */ - real lip_area; /* average area per lipid in membrane (only correct for homogeneous bilayers)*/ - real zmin; /* minimum z coordinate of membrane */ - real zmax; /* maximum z coordinate of membrane */ - real zmed; /* median z coordinate of membrane */ +typedef struct +{ + char* name; /* name of index group to embed molecule into (usually membrane) */ + t_block mem_at; /* list all atoms in membrane */ + int nmol; /* number of membrane molecules overlapping with the molecule to embed */ + int* mol_id; /* list of molecules in membrane that overlap with the molecule to embed */ + real lip_area; /* average area per lipid in membrane (only correct for homogeneous bilayers)*/ + real zmin; /* minimum z coordinate of membrane */ + real zmax; /* maximum z coordinate of membrane */ + real zmed; /* median z coordinate of membrane */ } mem_t; /* Lists all molecules in the membrane that overlap with the molecule to be embedded. * * These will then be removed from the system */ -typedef struct { - int nr; /* number of molecules to remove */ - int *mol; /* list of molecule ids to remove */ - int *block; /* id of the molblock that the molecule to remove is part of */ +typedef struct +{ + int nr; /* number of molecules to remove */ + int* mol; /* list of molecule ids to remove */ + int* block; /* id of the molblock that the molecule to remove is part of */ } rm_t; /* Get the global molecule id, and the corresponding molecule type and id of the * * molblock from the global atom nr. */ -static int get_mol_id(int at, gmx_mtop_t *mtop, int *type, int *block) +static int get_mol_id(int at, gmx_mtop_t* mtop, int* type, int* block) { - int mol_id = 0; - int i; - int atnr_mol; + int mol_id = 0; + int i; + int atnr_mol; *block = 0; mtopGetMolblockIndex(mtop, at, block, &mol_id, &atnr_mol); @@ -122,7 +127,7 @@ static int get_mol_id(int at, gmx_mtop_t *mtop, int *type, int *block) } /* Get the id of the molblock from a global molecule id */ -static int get_molblock(int mol_id, const std::vector &mblock) +static int get_molblock(int mol_id, const std::vector& mblock) { int nmol = 0; @@ -143,7 +148,7 @@ static int get_molblock(int mol_id, const std::vector &mblock) * level, if the same molecule type is found in another part of the system, these * * would also be affected. Therefore we have to check if the embedded and rest group * * share common molecule types. If so, membed will stop with an error. */ -static int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist) +static int get_mtype_list(t_block* at, gmx_mtop_t* mtop, t_block* tlist) { int i, j, nr; int type = 0, block = 0; @@ -153,7 +158,7 @@ static int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist) snew(tlist->index, at->nr); for (i = 0; i < at->nr; i++) { - bNEW = TRUE; + bNEW = TRUE; get_mol_id(at->index[i], mtop, &type, &block); for (j = 0; j < nr; j++) { @@ -174,14 +179,14 @@ static int get_mtype_list(t_block *at, gmx_mtop_t *mtop, t_block *tlist) } /* Do the actual check of the molecule types between embedded and rest group */ -static void check_types(t_block *ins_at, t_block *rest_at, gmx_mtop_t *mtop) +static void check_types(t_block* ins_at, t_block* rest_at, gmx_mtop_t* mtop) { - t_block *ins_mtype, *rest_mtype; - int i, j; + t_block *ins_mtype, *rest_mtype; + int i, j; snew(ins_mtype, 1); snew(rest_mtype, 1); - ins_mtype->nr = get_mtype_list(ins_at, mtop, ins_mtype ); + ins_mtype->nr = get_mtype_list(ins_at, mtop, ins_mtype); rest_mtype->nr = get_mtype_list(rest_at, mtop, rest_mtype); for (i = 0; i < ins_mtype->nr; i++) @@ -190,15 +195,23 @@ static void check_types(t_block *ins_at, t_block *rest_at, gmx_mtop_t *mtop) { if (ins_mtype->index[i] == rest_mtype->index[j]) { - gmx_fatal(FARGS, "Moleculetype %s is found both in the group to insert and the rest of the system.\n" - "1. Your *.ndx and *.top do not match\n" - "2. You are inserting some molecules of type %s (for example xray-solvent), while\n" - "the same moleculetype is also used in the rest of the system (solvent box). Because\n" - "we need to exclude all interactions between the atoms in the group to\n" - "insert, the same moleculetype can not be used in both groups. Change the\n" - "moleculetype of the molecules %s in the inserted group. Do not forget to provide\n" - "an appropriate *.itp file", *(mtop->moltype[rest_mtype->index[j]].name), - *(mtop->moltype[rest_mtype->index[j]].name), *(mtop->moltype[rest_mtype->index[j]].name)); + gmx_fatal( + FARGS, + "Moleculetype %s is found both in the group to insert and the rest of the " + "system.\n" + "1. Your *.ndx and *.top do not match\n" + "2. You are inserting some molecules of type %s (for example " + "xray-solvent), while\n" + "the same moleculetype is also used in the rest of the system (solvent " + "box). Because\n" + "we need to exclude all interactions between the atoms in the group to\n" + "insert, the same moleculetype can not be used in both groups. Change the\n" + "moleculetype of the molecules %s in the inserted group. Do not forget to " + "provide\n" + "an appropriate *.itp file", + *(mtop->moltype[rest_mtype->index[j]].name), + *(mtop->moltype[rest_mtype->index[j]].name), + *(mtop->moltype[rest_mtype->index[j]].name)); } } } @@ -209,12 +222,21 @@ static void check_types(t_block *ins_at, t_block *rest_at, gmx_mtop_t *mtop) sfree(rest_mtype); } -static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real *z_fac, real *z_max, - int *it_xy, int *it_z, real *probe_rad, int *low_up_rm, int *maxwarn, - int *pieces, gmx_bool *bALLOW_ASYMMETRY) +static void get_input(const char* membed_input, + real* xy_fac, + real* xy_max, + real* z_fac, + real* z_max, + int* it_xy, + int* it_z, + real* probe_rad, + int* low_up_rm, + int* maxwarn, + int* pieces, + gmx_bool* bALLOW_ASYMMETRY) { - warninp_t wi; - std::vector inp; + warninp_t wi; + std::vector inp; wi = init_warning(TRUE, 0); @@ -223,21 +245,18 @@ static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real inp = read_inpfile(&stream, membed_input, wi); stream.close(); } - *it_xy = get_eint(&inp, "nxy", 1000, wi); - *it_z = get_eint(&inp, "nz", 0, wi); - *xy_fac = get_ereal(&inp, "xyinit", 0.5, wi); - *xy_max = get_ereal(&inp, "xyend", 1.0, wi); - *z_fac = get_ereal(&inp, "zinit", 1.0, wi); - *z_max = get_ereal(&inp, "zend", 1.0, wi); - *probe_rad = get_ereal(&inp, "rad", 0.22, wi); - *low_up_rm = get_eint(&inp, "ndiff", 0, wi); - *maxwarn = get_eint(&inp, "maxwarn", 0, wi); - *pieces = get_eint(&inp, "pieces", 1, wi); - const char *yesno_names[BOOL_NR+1] = - { - "no", "yes", nullptr - }; - *bALLOW_ASYMMETRY = (get_eeenum(&inp, "asymmetry", yesno_names, wi) != 0); + *it_xy = get_eint(&inp, "nxy", 1000, wi); + *it_z = get_eint(&inp, "nz", 0, wi); + *xy_fac = get_ereal(&inp, "xyinit", 0.5, wi); + *xy_max = get_ereal(&inp, "xyend", 1.0, wi); + *z_fac = get_ereal(&inp, "zinit", 1.0, wi); + *z_max = get_ereal(&inp, "zend", 1.0, wi); + *probe_rad = get_ereal(&inp, "rad", 0.22, wi); + *low_up_rm = get_eint(&inp, "ndiff", 0, wi); + *maxwarn = get_eint(&inp, "maxwarn", 0, wi); + *pieces = get_eint(&inp, "pieces", 1, wi); + const char* yesno_names[BOOL_NR + 1] = { "no", "yes", nullptr }; + *bALLOW_ASYMMETRY = (get_eeenum(&inp, "asymmetry", yesno_names, wi) != 0); check_warning_error(wi, FARGS); { @@ -249,16 +268,22 @@ static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real } /* Obtain the maximum and minimum coordinates of the group to be embedded */ -static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_ins_t *pos_ins, - SimulationGroups *groups, int ins_grp_id, real xy_max) +static int init_ins_at(t_block* ins_at, + t_block* rest_at, + t_state* state, + pos_ins_t* pos_ins, + SimulationGroups* groups, + int ins_grp_id, + real xy_max) { int i, gid, c = 0; real xmin, xmax, ymin, ymax, zmin, zmax; - const real min_memthick = 6.0; /* minimum thickness of the bilayer that will be used to * - * determine the overlap between molecule to embed and membrane */ - const real fac_inp_size = 1.000001; /* scaling factor to obtain input_size + 0.000001 (comparing reals) */ + const real min_memthick = 6.0; /* minimum thickness of the bilayer that will be used to * + * determine the overlap between molecule to embed and membrane */ + const real fac_inp_size = + 1.000001; /* scaling factor to obtain input_size + 0.000001 (comparing reals) */ snew(rest_at->index, state->natoms); - auto x = makeArrayRef(state->x); + auto x = makeArrayRef(state->x); xmin = xmax = x[ins_at->index[0]][XX]; ymin = ymax = x[ins_at->index[0]][YY]; @@ -288,11 +313,11 @@ static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_in if (xy_max > fac_inp_size) { - pos_ins->xmin[XX] = xmin-((xmax-xmin)*xy_max-(xmax-xmin))/2; - pos_ins->xmin[YY] = ymin-((ymax-ymin)*xy_max-(ymax-ymin))/2; + pos_ins->xmin[XX] = xmin - ((xmax - xmin) * xy_max - (xmax - xmin)) / 2; + pos_ins->xmin[YY] = ymin - ((ymax - ymin) * xy_max - (ymax - ymin)) / 2; - pos_ins->xmax[XX] = xmax+((xmax-xmin)*xy_max-(xmax-xmin))/2; - pos_ins->xmax[YY] = ymax+((ymax-ymin)*xy_max-(ymax-ymin))/2; + pos_ins->xmax[XX] = xmax + ((xmax - xmin) * xy_max - (xmax - xmin)) / 2; + pos_ins->xmax[YY] = ymax + ((ymax - ymin) * xy_max - (ymax - ymin)) / 2; } else { @@ -303,10 +328,10 @@ static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_in pos_ins->xmax[YY] = ymax; } - if ( (zmax-zmin) < min_memthick) + if ((zmax - zmin) < min_memthick) { - pos_ins->xmin[ZZ] = zmin+(zmax-zmin)/2.0-0.5*min_memthick; - pos_ins->xmax[ZZ] = zmin+(zmax-zmin)/2.0+0.5*min_memthick; + pos_ins->xmin[ZZ] = zmin + (zmax - zmin) / 2.0 - 0.5 * min_memthick; + pos_ins->xmax[ZZ] = zmin + (zmax - zmin) / 2.0 + 0.5 * min_memthick; } else { @@ -319,7 +344,7 @@ static int init_ins_at(t_block *ins_at, t_block *rest_at, t_state *state, pos_in /* Estimate the area of the embedded molecule by projecting all coordinates on a grid in the * * xy-plane and counting the number of occupied grid points */ -static real est_prot_area(pos_ins_t *pos_ins, rvec *r, t_block *ins_at, mem_t *mem_p) +static real est_prot_area(pos_ins_t* pos_ins, rvec* r, t_block* ins_at, mem_t* mem_p) { real x, y, dx = 0.15, dy = 0.15, area = 0.0; real add, memmin, memmax; @@ -327,8 +352,8 @@ static real est_prot_area(pos_ins_t *pos_ins, rvec *r, t_block *ins_at, mem_t *m /* min and max membrane coordinate are altered to reduce the influence of the * * boundary region */ - memmin = mem_p->zmin+0.1*(mem_p->zmax-mem_p->zmin); - memmax = mem_p->zmax-0.1*(mem_p->zmax-mem_p->zmin); + memmin = mem_p->zmin + 0.1 * (mem_p->zmax - mem_p->zmin); + memmax = mem_p->zmax - 0.1 * (mem_p->zmax - mem_p->zmin); //NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for (x = pos_ins->xmin[XX]; x < pos_ins->xmax[XX]; x += dx) @@ -341,43 +366,41 @@ static real est_prot_area(pos_ins_t *pos_ins, rvec *r, t_block *ins_at, mem_t *m do { at = ins_at->index[c]; - if ( (r[at][XX] >= x) && (r[at][XX] < x+dx) && - (r[at][YY] >= y) && (r[at][YY] < y+dy) && - (r[at][ZZ] > memmin) && (r[at][ZZ] < memmax) ) + if ((r[at][XX] >= x) && (r[at][XX] < x + dx) && (r[at][YY] >= y) + && (r[at][YY] < y + dy) && (r[at][ZZ] > memmin) && (r[at][ZZ] < memmax)) { add = 1.0; } c++; - } - while ( (c < ins_at->nr) && (add < 0.5) ); + } while ((c < ins_at->nr) && (add < 0.5)); area += add; } } - area = area*dx*dy; + area = area * dx * dy; return area; } -static int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ins_t *pos_ins) +static int init_mem_at(mem_t* mem_p, gmx_mtop_t* mtop, rvec* r, matrix box, pos_ins_t* pos_ins) { int i, j, at, mol, nmol, nmolbox, count; - t_block *mem_a; + t_block* mem_a; real z, zmin, zmax, mem_area; gmx_bool bNew; - int *mol_id; + int* mol_id; int type = 0, block = 0; - nmol = count = 0; - mem_a = &(mem_p->mem_at); + nmol = count = 0; + mem_a = &(mem_p->mem_at); snew(mol_id, mem_a->nr); zmin = pos_ins->xmax[ZZ]; zmax = pos_ins->xmin[ZZ]; for (i = 0; i < mem_a->nr; i++) { at = mem_a->index[i]; - if ( (r[at][XX] > pos_ins->xmin[XX]) && (r[at][XX] < pos_ins->xmax[XX]) && - (r[at][YY] > pos_ins->xmin[YY]) && (r[at][YY] < pos_ins->xmax[YY]) && - (r[at][ZZ] > pos_ins->xmin[ZZ]) && (r[at][ZZ] < pos_ins->xmax[ZZ]) ) + if ((r[at][XX] > pos_ins->xmin[XX]) && (r[at][XX] < pos_ins->xmax[XX]) + && (r[at][YY] > pos_ins->xmin[YY]) && (r[at][YY] < pos_ins->xmax[YY]) + && (r[at][ZZ] > pos_ins->xmin[ZZ]) && (r[at][ZZ] < pos_ins->xmax[ZZ])) { mol = get_mol_id(at, mtop, &type, &block); bNew = TRUE; @@ -414,29 +437,32 @@ static int init_mem_at(mem_t *mem_p, gmx_mtop_t *mtop, rvec *r, matrix box, pos_ srenew(mol_id, nmol); mem_p->mol_id = mol_id; - if ((zmax-zmin) > (box[ZZ][ZZ]-0.5)) + if ((zmax - zmin) > (box[ZZ][ZZ] - 0.5)) { - gmx_fatal(FARGS, "Something is wrong with your membrane. Max and min z values are %f and %f.\n" - "Maybe your membrane is not centered in the box, but located at the box edge in the z-direction,\n" - "so that one membrane is distributed over two periodic box images. Another possibility is that\n" - "your water layer is not thick enough.\n", zmax, zmin); + gmx_fatal(FARGS, + "Something is wrong with your membrane. Max and min z values are %f and %f.\n" + "Maybe your membrane is not centered in the box, but located at the box edge in " + "the z-direction,\n" + "so that one membrane is distributed over two periodic box images. Another " + "possibility is that\n" + "your water layer is not thick enough.\n", + zmax, zmin); } mem_p->zmin = zmin; mem_p->zmax = zmax; - mem_p->zmed = (zmax-zmin)/2+zmin; + mem_p->zmed = (zmax - zmin) / 2 + zmin; /*number of membrane molecules in protein box*/ - nmolbox = count/mtop->moltype[mtop->molblock[block].type].atoms.nr; + nmolbox = count / mtop->moltype[mtop->molblock[block].type].atoms.nr; /*membrane area within the box defined by the min and max coordinates of the embedded molecule*/ - mem_area = (pos_ins->xmax[XX]-pos_ins->xmin[XX])*(pos_ins->xmax[YY]-pos_ins->xmin[YY]); + mem_area = (pos_ins->xmax[XX] - pos_ins->xmin[XX]) * (pos_ins->xmax[YY] - pos_ins->xmin[YY]); /*rough estimate of area per lipid, assuming there is only one type of lipid in the membrane*/ - mem_p->lip_area = 2.0*mem_area/static_cast(nmolbox); + mem_p->lip_area = 2.0 * mem_area / static_cast(nmolbox); return mem_p->mem_at.nr; } -static void init_resize(t_block *ins_at, rvec *r_ins, pos_ins_t *pos_ins, mem_t *mem_p, rvec *r, - gmx_bool bALLOW_ASYMMETRY) +static void init_resize(t_block* ins_at, rvec* r_ins, pos_ins_t* pos_ins, mem_t* mem_p, rvec* r, gmx_bool bALLOW_ASYMMETRY) { int i, j, at, c, outsidesum, gctr = 0; int idxsum = 0; @@ -449,7 +475,8 @@ static void init_resize(t_block *ins_at, rvec *r_ins, pos_ins_t *pos_ins, mem_t if (idxsum != ins_at->nr) { - gmx_fatal(FARGS, "Piecewise sum of inserted atoms not same as size of group selected to insert."); + gmx_fatal(FARGS, + "Piecewise sum of inserted atoms not same as size of group selected to insert."); } snew(pos_ins->geom_cent, pos_ins->pieces); @@ -466,7 +493,7 @@ static void init_resize(t_block *ins_at, rvec *r_ins, pos_ins_t *pos_ins, mem_t { at = pos_ins->subindex[i][j]; copy_rvec(r[at], r_ins[gctr]); - if ( (r_ins[gctr][ZZ] < mem_p->zmax) && (r_ins[gctr][ZZ] > mem_p->zmin) ) + if ((r_ins[gctr][ZZ] < mem_p->zmax) && (r_ins[gctr][ZZ] > mem_p->zmin)) { rvec_inc(pos_ins->geom_cent[i], r_ins[gctr]); c++; @@ -480,7 +507,7 @@ static void init_resize(t_block *ins_at, rvec *r_ins, pos_ins_t *pos_ins, mem_t if (c > 0) { - svmul(1/static_cast(c), pos_ins->geom_cent[i], pos_ins->geom_cent[i]); + svmul(1 / static_cast(c), pos_ins->geom_cent[i], pos_ins->geom_cent[i]); } if (!bALLOW_ASYMMETRY) @@ -488,14 +515,14 @@ static void init_resize(t_block *ins_at, rvec *r_ins, pos_ins_t *pos_ins, mem_t pos_ins->geom_cent[i][ZZ] = mem_p->zmed; } - fprintf(stderr, "Embedding piece %d with center of geometry: %f %f %f\n", - i, pos_ins->geom_cent[i][XX], pos_ins->geom_cent[i][YY], pos_ins->geom_cent[i][ZZ]); + fprintf(stderr, "Embedding piece %d with center of geometry: %f %f %f\n", i, + pos_ins->geom_cent[i][XX], pos_ins->geom_cent[i][YY], pos_ins->geom_cent[i][ZZ]); } fprintf(stderr, "\n"); } /* resize performed in the md loop */ -static void resize(rvec *r_ins, rvec *r, pos_ins_t *pos_ins, const rvec fac) +static void resize(rvec* r_ins, rvec* r, pos_ins_t* pos_ins, const rvec fac) { int i, j, k, at, c = 0; for (k = 0; k < pos_ins->pieces; k++) @@ -505,7 +532,7 @@ static void resize(rvec *r_ins, rvec *r, pos_ins_t *pos_ins, const rvec fac) at = pos_ins->subindex[k][i]; for (j = 0; j < DIM; j++) { - r[at][j] = pos_ins->geom_cent[k][j]+fac[j]*(r_ins[c][j]-pos_ins->geom_cent[k][j]); + r[at][j] = pos_ins->geom_cent[k][j] + fac[j] * (r_ins[c][j] - pos_ins->geom_cent[k][j]); } c++; } @@ -514,9 +541,17 @@ static void resize(rvec *r_ins, rvec *r, pos_ins_t *pos_ins, const rvec fac) /* generate the list of membrane molecules that overlap with the molecule to be embedded. * * The molecule to be embedded is already reduced in size. */ -static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc, gmx_mtop_t *mtop, - rvec *r, mem_t *mem_p, pos_ins_t *pos_ins, real probe_rad, - int low_up_rm, gmx_bool bALLOW_ASYMMETRY) +static int gen_rm_list(rm_t* rm_p, + t_block* ins_at, + t_block* rest_at, + t_pbc* pbc, + gmx_mtop_t* mtop, + rvec* r, + mem_t* mem_p, + pos_ins_t* pos_ins, + real probe_rad, + int low_up_rm, + gmx_bool bALLOW_ASYMMETRY) { int i, j, k, l, at, at2, mol_id; int type = 0, block = 0; @@ -524,15 +559,15 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc real r_min_rad, z_lip, min_norm; gmx_bool bRM; rvec dr, dr_tmp; - real *dist; - int *order; + real* dist; + int* order; - r_min_rad = probe_rad*probe_rad; + r_min_rad = probe_rad * probe_rad; gmx::RangePartitioning molecules = gmx_mtop_molecules(*mtop); snew(rm_p->block, molecules.numBlocks()); snew(rm_p->mol, molecules.numBlocks()); - nrm = nupper = 0; - nlower = low_up_rm; + nrm = nupper = 0; + nlower = low_up_rm; for (i = 0; i < ins_at->nr; i++) { at = ins_at->index[i]; @@ -584,7 +619,7 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc } /*make sure equal number of lipids from upper and lower layer are removed */ - if ( (nupper != nlower) && (!bALLOW_ASYMMETRY) ) + if ((nupper != nlower) && (!bALLOW_ASYMMETRY)) { snew(dist, mem_p->nmol); snew(order, mem_p->nmol); @@ -606,14 +641,14 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc } } } - dist[i] = dr[XX]*dr[XX]+dr[YY]*dr[YY]; - j = i-1; + dist[i] = dr[XX] * dr[XX] + dr[YY] * dr[YY]; + j = i - 1; while (j >= 0 && dist[i] < dist[order[j]]) { - order[j+1] = order[j]; + order[j + 1] = order[j]; j--; } - order[j+1] = i; + order[j + 1] = i; } i = 0; @@ -657,7 +692,8 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc if (i > mem_p->nmol) { - gmx_fatal(FARGS, "Trying to remove more lipid molecules than there are in the membrane"); + gmx_fatal(FARGS, + "Trying to remove more lipid molecules than there are in the membrane"); } } sfree(dist); @@ -668,19 +704,23 @@ static int gen_rm_list(rm_t *rm_p, t_block *ins_at, t_block *rest_at, t_pbc *pbc srenew(rm_p->mol, nrm); srenew(rm_p->block, nrm); - return nupper+nlower; + return nupper + nlower; } /*remove all lipids and waters overlapping and update all important structures (e.g. state and mtop)*/ -static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_state *state, - t_block *ins_at, pos_ins_t *pos_ins) +static void rm_group(SimulationGroups* groups, + gmx_mtop_t* mtop, + rm_t* rm_p, + t_state* state, + t_block* ins_at, + pos_ins_t* pos_ins) { - int j, k, n, rm, mol_id, at, block; - rvec *x_tmp, *v_tmp; - int *list; - gmx::EnumerationArray < SimulationAtomGroupType, std::vector < unsigned char>> new_egrp; - gmx_bool bRM; - int RMmolblock; + int j, k, n, rm, mol_id, at, block; + rvec *x_tmp, *v_tmp; + int* list; + gmx::EnumerationArray> new_egrp; + gmx_bool bRM; + int RMmolblock; /* Construct the molecule range information */ gmx::RangePartitioning molecules = gmx_mtop_molecules(*mtop); @@ -695,12 +735,12 @@ static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_s mtop->molblock[block].nmol--; for (j = 0; j < mtop->moltype[mtop->molblock[block].type].atoms.nr; j++) { - list[n] = at+j; + list[n] = at + j; n++; } } - mtop->natoms -= n; + mtop->natoms -= n; /* We cannot change the size of the state datastructures here * because we still access the coordinate arrays for all positions * before removing the molecules we want to remove. @@ -720,7 +760,7 @@ static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_s auto x = makeArrayRef(state->x); auto v = makeArrayRef(state->v); - rm = 0; + rm = 0; for (int i = 0; i < state->natoms; i++) { bRM = FALSE; @@ -739,16 +779,16 @@ static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_s { if (!groups->groupNumbers[group].empty()) { - new_egrp[group][i-rm] = groups->groupNumbers[group][i]; + new_egrp[group][i - rm] = groups->groupNumbers[group][i]; } } - copy_rvec(x[i], x_tmp[i-rm]); - copy_rvec(v[i], v_tmp[i-rm]); + copy_rvec(x[i], x_tmp[i - rm]); + copy_rvec(v[i], v_tmp[i - rm]); for (j = 0; j < ins_at->nr; j++) { if (i == ins_at->index[j]) { - ins_at->index[j] = i-rm; + ins_at->index[j] = i - rm; } } @@ -758,7 +798,7 @@ static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_s { if (i == pos_ins->subindex[j][k]) { - pos_ins->subindex[j][k] = i-rm; + pos_ins->subindex[j][k] = i - rm; } } } @@ -794,22 +834,22 @@ static void rm_group(SimulationGroups *groups, gmx_mtop_t *mtop, rm_t *rm_p, t_s } else { - mtop->molblock[i-RMmolblock] = mtop->molblock[i]; + mtop->molblock[i - RMmolblock] = mtop->molblock[i]; } } mtop->molblock.resize(mtop->molblock.size() - RMmolblock); } /* remove al bonded interactions from mtop for the molecule to be embedded */ -static int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop) +static int rm_bonded(t_block* ins_at, gmx_mtop_t* mtop) { int j, m; int type, natom, nmol, at, atom1 = 0, rm_at = 0; gmx_bool *bRM, bINS; /*this routine lives dangerously by assuming that all molecules of a given type are in order in the structure*/ - /*this routine does not live as dangerously as it seems. There is namely a check in init_membed to make * - * sure that g_membed exits with a warning when there are molecules of the same type not in the * - * ins_at index group. MGWolf 050710 */ + /*this routine does not live as dangerously as it seems. There is namely a check in init_membed + * to make * sure that g_membed exits with a warning when there are molecules of the same type + * not in the * ins_at index group. MGWolf 050710 */ snew(bRM, mtop->moltype.size()); @@ -821,14 +861,14 @@ static int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop) for (size_t i = 0; i < mtop->molblock.size(); i++) { /*loop over molecule blocks*/ - type = mtop->molblock[i].type; - natom = mtop->moltype[type].atoms.nr; - nmol = mtop->molblock[i].nmol; + type = mtop->molblock[i].type; + natom = mtop->moltype[type].atoms.nr; + nmol = mtop->molblock[i].nmol; - for (j = 0; j < natom*nmol && bRM[type]; j++) + for (j = 0; j < natom * nmol && bRM[type]; j++) { /*loop over atoms in the block*/ - at = j+atom1; /*atom index = block index + offset*/ + at = j + atom1; /*atom index = block index + offset*/ bINS = FALSE; for (m = 0; (m < ins_at->nr) && (!bINS); m++) @@ -841,10 +881,10 @@ static int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop) } bRM[type] = bINS; } - atom1 += natom*nmol; /*update offset*/ + atom1 += natom * nmol; /*update offset*/ if (bRM[type]) { - rm_at += natom*nmol; /*increment bonded removal counter by # atoms in block*/ + rm_at += natom * nmol; /*increment bonded removal counter by # atoms in block*/ } } @@ -869,15 +909,15 @@ static int rm_bonded(t_block *ins_at, gmx_mtop_t *mtop) } /* Write a topology where the number of molecules is correct for the system after embedding */ -static void top_update(const char *topfile, rm_t *rm_p, gmx_mtop_t *mtop) +static void top_update(const char* topfile, rm_t* rm_p, gmx_mtop_t* mtop) { - int bMolecules = 0; - FILE *fpin, *fpout; - char buf[STRLEN], buf2[STRLEN], *temp; - int i, *nmol_rm, nmol, line; - char temporary_filename[STRLEN]; + int bMolecules = 0; + FILE *fpin, *fpout; + char buf[STRLEN], buf2[STRLEN], *temp; + int i, *nmol_rm, nmol, line; + char temporary_filename[STRLEN]; - fpin = gmx_ffopen(topfile, "r"); + fpin = gmx_ffopen(topfile, "r"); strncpy(temporary_filename, "temp.topXXXXXX", STRLEN); gmx_tmpnam(temporary_filename); fpout = gmx_ffopen(temporary_filename, "w"); @@ -908,9 +948,9 @@ static void top_update(const char *topfile, rm_t *rm_p, gmx_mtop_t *mtop) temp[0] = '\0'; } rtrim(buf2); - if (buf2[strlen(buf2)-1] == ']') + if (buf2[strlen(buf2) - 1] == ']') { - buf2[strlen(buf2)-1] = '\0'; + buf2[strlen(buf2) - 1] = '\0'; ltrim(buf2); rtrim(buf2); if (gmx_strcasecmp(buf2, "molecules") == 0) @@ -952,7 +992,7 @@ static void top_update(const char *topfile, rm_t *rm_p, gmx_mtop_t *mtop) rename(temporary_filename, topfile); } -void rescale_membed(int step_rel, gmx_membed_t *membed, rvec *x) +void rescale_membed(int step_rel, gmx_membed_t* membed, rvec* x) { /* Set new positions for the group to embed */ if (step_rel <= membed->it_xy) @@ -960,53 +1000,59 @@ void rescale_membed(int step_rel, gmx_membed_t *membed, rvec *x) membed->fac[0] += membed->xy_step; membed->fac[1] += membed->xy_step; } - else if (step_rel <= (membed->it_xy+membed->it_z)) + else if (step_rel <= (membed->it_xy + membed->it_z)) { membed->fac[2] += membed->z_step; } resize(membed->r_ins, x, membed->pos_ins, membed->fac); } -gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop_t *mtop, - t_inputrec *inputrec, t_state *state, t_commrec *cr, real *cpt) +gmx_membed_t* init_membed(FILE* fplog, + int nfile, + const t_filenm fnm[], + gmx_mtop_t* mtop, + t_inputrec* inputrec, + t_state* state, + t_commrec* cr, + real* cpt) { - char *ins; - int i, rm_bonded_at, fr_id, fr_i = 0, tmp_id, warn = 0; - int ng, j, max_lip_rm, ins_grp_id, ntype, lip_rm; - real prot_area; - rvec *r_ins = nullptr; - t_block *ins_at, *rest_at; - pos_ins_t *pos_ins; - mem_t *mem_p; - rm_t *rm_p; - SimulationGroups *groups; - gmx_bool bExcl = FALSE; - t_atoms atoms; - t_pbc *pbc; - char **piecename = nullptr; - gmx_membed_t *membed = nullptr; + char* ins; + int i, rm_bonded_at, fr_id, fr_i = 0, tmp_id, warn = 0; + int ng, j, max_lip_rm, ins_grp_id, ntype, lip_rm; + real prot_area; + rvec* r_ins = nullptr; + t_block * ins_at, *rest_at; + pos_ins_t* pos_ins; + mem_t* mem_p; + rm_t* rm_p; + SimulationGroups* groups; + gmx_bool bExcl = FALSE; + t_atoms atoms; + t_pbc* pbc; + char** piecename = nullptr; + gmx_membed_t* membed = nullptr; /* input variables */ - real xy_fac = 0.5; - real xy_max = 1.0; - real z_fac = 1.0; - real z_max = 1.0; - int it_xy = 1000; - int it_z = 0; - real probe_rad = 0.22; - int low_up_rm = 0; - int maxwarn = 0; - int pieces = 1; - gmx_bool bALLOW_ASYMMETRY = FALSE; - - /* sanity check constants */ /* Issue a warning when: */ - const real min_probe_rad = 0.2199999; /* A probe radius for overlap between embedded molecule * - * and rest smaller than this value is probably too small */ - const real min_xy_init = 0.0999999; /* the initial shrinking of the molecule to embed is smaller */ - const int min_it_xy = 1000; /* the number of steps to embed in xy-plane is smaller */ - const int min_it_z = 100; /* the number of steps to embed in z is smaller */ - const real prot_vs_box = 7.5; /* molecule to embed is large (more then prot_vs_box) with respect */ - const real box_vs_prot = 50; /* to the box size (less than box_vs_prot) */ + real xy_fac = 0.5; + real xy_max = 1.0; + real z_fac = 1.0; + real z_max = 1.0; + int it_xy = 1000; + int it_z = 0; + real probe_rad = 0.22; + int low_up_rm = 0; + int maxwarn = 0; + int pieces = 1; + gmx_bool bALLOW_ASYMMETRY = FALSE; + + /* sanity check constants */ /* Issue a warning when: */ + const real min_probe_rad = 0.2199999; /* A probe radius for overlap between embedded molecule * + * and rest smaller than this value is probably too small */ + const real min_xy_init = 0.0999999; /* the initial shrinking of the molecule to embed is smaller */ + const int min_it_xy = 1000; /* the number of steps to embed in xy-plane is smaller */ + const int min_it_z = 100; /* the number of steps to embed in z is smaller */ + const real prot_vs_box = 7.5; /* molecule to embed is large (more then prot_vs_box) with respect */ + const real box_vs_prot = 50; /* to the box size (less than box_vs_prot) */ snew(membed, 1); snew(ins_at, 1); @@ -1014,18 +1060,18 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (MASTER(cr)) { - fprintf(fplog, "Note: it is expected that in future gmx mdrun -membed will not be the " + fprintf(fplog, + "Note: it is expected that in future gmx mdrun -membed will not be the " "way to access this feature, perhaps changing to e.g. gmx membed."); /* get input data out membed file */ try { - get_input(opt2fn("-membed", nfile, fnm), - &xy_fac, &xy_max, &z_fac, &z_max, &it_xy, &it_z, &probe_rad, &low_up_rm, - &maxwarn, &pieces, &bALLOW_ASYMMETRY); + get_input(opt2fn("-membed", nfile, fnm), &xy_fac, &xy_max, &z_fac, &z_max, &it_xy, + &it_z, &probe_rad, &low_up_rm, &maxwarn, &pieces, &bALLOW_ASYMMETRY); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR - if (!EI_DYNAMICS(inputrec->eI) ) + if (!EI_DYNAMICS(inputrec->eI)) { gmx_input("Change integrator to a dynamics integrator in mdp file (e.g. md or sd)."); } @@ -1037,12 +1083,14 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (*cpt >= 0) { - fprintf(stderr, "\nSetting -cpt to -1, because embedding cannot be restarted from cpt-files.\n"); + fprintf(stderr, + "\nSetting -cpt to -1, because embedding cannot be restarted from " + "cpt-files.\n"); *cpt = -1; } groups = &(mtop->groups); std::vector gnames; - for (const auto &groupName : groups->groupNames) + for (const auto& groupName : groups->groupNames) { gnames.emplace_back(*groupName); } @@ -1052,9 +1100,9 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop fprintf(stderr, "\nSelect a group to embed in the membrane:\n"); get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(ins_at->nr), &(ins_at->index), &ins); - auto found = std::find_if(gnames.begin(), gnames.end(), - [&ins](const auto &name) - { return gmx::equalCaseInsensitive(ins, name); }); + auto found = std::find_if(gnames.begin(), gnames.end(), [&ins](const auto& name) { + return gmx::equalCaseInsensitive(ins, name); + }); if (found == gnames.end()) { @@ -1062,14 +1110,16 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop "Group %s selected for embedding was not found in the index file.\n" "Group names must match either [moleculetype] names or custom index group\n" "names, in which case you must supply an index file to the '-n' option\n" - "of grompp.", ins); + "of grompp.", + ins); } else { ins_grp_id = std::distance(gnames.begin(), found); } fprintf(stderr, "\nSelect a group to embed %s into (e.g. the membrane):\n", ins); - get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(mem_p->mem_at.nr), &(mem_p->mem_at.index), &(mem_p->name)); + get_index(&atoms, opt2fn_null("-mn", nfile, fnm), 1, &(mem_p->mem_at.nr), + &(mem_p->mem_at.index), &(mem_p->name)); pos_ins->pieces = pieces; snew(pos_ins->nidx, pieces); @@ -1078,7 +1128,8 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (pieces > 1) { fprintf(stderr, "\nSelect pieces to embed:\n"); - get_index(&atoms, opt2fn_null("-mn", nfile, fnm), pieces, pos_ins->nidx, pos_ins->subindex, piecename); + get_index(&atoms, opt2fn_null("-mn", nfile, fnm), pieces, pos_ins->nidx, + pos_ins->subindex, piecename); } else { @@ -1092,9 +1143,11 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (probe_rad < min_probe_rad) { warn++; - fprintf(stderr, "\nWarning %d:\nA probe radius (-rad) smaller than 0.2 nm can result " + fprintf(stderr, + "\nWarning %d:\nA probe radius (-rad) smaller than 0.2 nm can result " "in overlap between waters and the group to embed, which will result " - "in Lincs errors etc.\n\n", warn); + "in Lincs errors etc.\n\n", + warn); } if (xy_fac < min_xy_init) @@ -1106,23 +1159,30 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (it_xy < min_it_xy) { warn++; - fprintf(stderr, "\nWarning %d;\nThe number of steps used to grow the xy-coordinates of %s (%d)" - " is probably too small.\nIncrease -nxy or.\n\n", warn, ins, it_xy); + fprintf(stderr, + "\nWarning %d;\nThe number of steps used to grow the xy-coordinates of %s (%d)" + " is probably too small.\nIncrease -nxy or.\n\n", + warn, ins, it_xy); } - if ( (it_z < min_it_z) && ( z_fac < 0.99999999 || z_fac > 1.0000001) ) + if ((it_z < min_it_z) && (z_fac < 0.99999999 || z_fac > 1.0000001)) { warn++; - fprintf(stderr, "\nWarning %d;\nThe number of steps used to grow the z-coordinate of %s (%d)" - " is probably too small.\nIncrease -nz or the maxwarn setting in the membed input file.\n\n", warn, ins, it_z); + fprintf(stderr, + "\nWarning %d;\nThe number of steps used to grow the z-coordinate of %s (%d)" + " is probably too small.\nIncrease -nz or the maxwarn setting in the membed " + "input file.\n\n", + warn, ins, it_z); } - if (it_xy+it_z > inputrec->nsteps) + if (it_xy + it_z > inputrec->nsteps) { warn++; - fprintf(stderr, "\nWarning %d:\nThe number of growth steps (-nxy + -nz) is larger than the " + fprintf(stderr, + "\nWarning %d:\nThe number of growth steps (-nxy + -nz) is larger than the " "number of steps in the tpr.\n" - "(increase maxwarn in the membed input file to override)\n\n", warn); + "(increase maxwarn in the membed input file to override)\n\n", + warn); } fr_id = -1; @@ -1157,22 +1217,27 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop ng = groups->groups[SimulationAtomGroupType::EnergyOutput].size(); if (ng == 1) { - gmx_input("No energy groups defined. This is necessary for energy exclusion in the freeze group"); + gmx_input( + "No energy groups defined. This is necessary for energy exclusion in the " + "freeze group"); } for (i = 0; i < ng; i++) { for (j = 0; j < ng; j++) { - if (inputrec->opts.egp_flags[ng*i+j] == EGP_EXCL) + if (inputrec->opts.egp_flags[ng * i + j] == EGP_EXCL) { bExcl = TRUE; - if ( (groups->groups[SimulationAtomGroupType::EnergyOutput][i] != ins_grp_id) || - (groups->groups[SimulationAtomGroupType::EnergyOutput][j] != ins_grp_id) ) + if ((groups->groups[SimulationAtomGroupType::EnergyOutput][i] != ins_grp_id) + || (groups->groups[SimulationAtomGroupType::EnergyOutput][j] != ins_grp_id)) { - gmx_fatal(FARGS, "Energy exclusions \"%s\" and \"%s\" do not match the group " - "to embed \"%s\"", *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][i]], - *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]], ins); + gmx_fatal(FARGS, + "Energy exclusions \"%s\" and \"%s\" do not match the group " + "to embed \"%s\"", + *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][i]], + *groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]], + ins); } } } @@ -1180,8 +1245,9 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (!bExcl) { - gmx_input("No energy exclusion groups defined. This is necessary for energy exclusion in " - "the freeze group"); + gmx_input( + "No energy exclusion groups defined. This is necessary for energy exclusion in " + "the freeze group"); } /* Obtain the maximum and minimum coordinates of the group to be embedded */ @@ -1193,30 +1259,41 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop init_mem_at(mem_p, mtop, state->x.rvec_array(), state->box, pos_ins); prot_area = est_prot_area(pos_ins, state->x.rvec_array(), ins_at, mem_p); - if ( (prot_area > prot_vs_box) && ( (state->box[XX][XX]*state->box[YY][YY]-state->box[XX][YY]*state->box[YY][XX]) < box_vs_prot) ) + if ((prot_area > prot_vs_box) + && ((state->box[XX][XX] * state->box[YY][YY] - state->box[XX][YY] * state->box[YY][XX]) + < box_vs_prot)) { warn++; - fprintf(stderr, "\nWarning %d:\nThe xy-area is very small compared to the area of the protein.\n" + fprintf(stderr, + "\nWarning %d:\nThe xy-area is very small compared to the area of the " + "protein.\n" "This might cause pressure problems during the growth phase. Just try with\n" - "current setup and increase 'maxwarn' in your membed settings file, but lower the\n" - "compressibility in the mdp-file or disable pressure coupling if problems occur.\n\n", warn); + "current setup and increase 'maxwarn' in your membed settings file, but lower " + "the\n" + "compressibility in the mdp-file or disable pressure coupling if problems " + "occur.\n\n", + warn); } if (warn > maxwarn) { - gmx_fatal(FARGS, "Too many warnings (override by setting maxwarn in the membed input file)\n"); + gmx_fatal(FARGS, + "Too many warnings (override by setting maxwarn in the membed input file)\n"); } printf("The estimated area of the protein in the membrane is %.3f nm^2\n", prot_area); printf("\nThere are %d lipids in the membrane part that overlaps the protein.\n" - "The area per lipid is %.4f nm^2.\n", mem_p->nmol, mem_p->lip_area); + "The area per lipid is %.4f nm^2.\n", + mem_p->nmol, mem_p->lip_area); /* Maximum number of lipids to be removed*/ - max_lip_rm = static_cast(2*prot_area/mem_p->lip_area); + max_lip_rm = static_cast(2 * prot_area / mem_p->lip_area); printf("Maximum number of lipids that will be removed is %d.\n", max_lip_rm); - printf("\nWill resize the protein by a factor of %.3f in the xy plane and %.3f in the z direction.\n" - "This resizing will be done with respect to the geometrical center of all protein atoms\n" + printf("\nWill resize the protein by a factor of %.3f in the xy plane and %.3f in the z " + "direction.\n" + "This resizing will be done with respect to the geometrical center of all protein " + "atoms\n" "that span the membrane region, i.e. z between %.3f and %.3f\n\n", xy_fac, z_fac, mem_p->zmin, mem_p->zmax); @@ -1224,10 +1301,10 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop snew(r_ins, ins_at->nr); init_resize(ins_at, r_ins, pos_ins, mem_p, state->x.rvec_array(), bALLOW_ASYMMETRY); membed->fac[0] = membed->fac[1] = xy_fac; - membed->fac[2] = z_fac; + membed->fac[2] = z_fac; - membed->xy_step = (xy_max-xy_fac)/static_cast(it_xy); - membed->z_step = (z_max-z_fac)/static_cast(it_z-1); + membed->xy_step = (xy_max - xy_fac) / static_cast(it_xy); + membed->z_step = (z_max - z_fac) / static_cast(it_z - 1); resize(r_ins, state->x.rvec_array(), pos_ins, membed->fac); @@ -1237,8 +1314,8 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop set_pbc(pbc, inputrec->ePBC, state->box); snew(rm_p, 1); - lip_rm = gen_rm_list(rm_p, ins_at, rest_at, pbc, mtop, state->x.rvec_array(), mem_p, pos_ins, - probe_rad, low_up_rm, bALLOW_ASYMMETRY); + lip_rm = gen_rm_list(rm_p, ins_at, rest_at, pbc, mtop, state->x.rvec_array(), mem_p, + pos_ins, probe_rad, low_up_rm, bALLOW_ASYMMETRY); lip_rm -= low_up_rm; if (fplog) @@ -1265,9 +1342,11 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop if (lip_rm > max_lip_rm) { warn++; - fprintf(stderr, "\nWarning %d:\nTrying to remove a larger lipid area than the estimated " + fprintf(stderr, + "\nWarning %d:\nTrying to remove a larger lipid area than the estimated " "protein area\nTry making the -xyinit resize factor smaller or increase " - "maxwarn in the membed input file.\n\n", warn); + "maxwarn in the membed input file.\n\n", + warn); } /*remove all lipids and waters overlapping and update all important structures*/ @@ -1276,14 +1355,19 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop rm_bonded_at = rm_bonded(ins_at, mtop); if (rm_bonded_at != ins_at->nr) { - fprintf(stderr, "Warning: The number of atoms for which the bonded interactions are removed is %d, " - "while %d atoms are embedded. Make sure that the atoms to be embedded are not in the same" - "molecule type as atoms that are not to be embedded.\n", rm_bonded_at, ins_at->nr); + fprintf(stderr, + "Warning: The number of atoms for which the bonded interactions are removed is " + "%d, " + "while %d atoms are embedded. Make sure that the atoms to be embedded are not " + "in the same" + "molecule type as atoms that are not to be embedded.\n", + rm_bonded_at, ins_at->nr); } if (warn > maxwarn) { - gmx_fatal(FARGS, "Too many warnings.\nIf you are sure these warnings are harmless,\n" + gmx_fatal(FARGS, + "Too many warnings.\nIf you are sure these warnings are harmless,\n" "you can increase the maxwarn setting in the membed input file."); } @@ -1312,7 +1396,7 @@ gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop return membed; } -void free_membed(gmx_membed_t *membed) +void free_membed(gmx_membed_t* membed) { sfree(membed); } diff --git a/src/gromacs/mdlib/membed.h b/src/gromacs/mdlib/membed.h index 8316323df9..e210ea11af 100644 --- a/src/gromacs/mdlib/membed.h +++ b/src/gromacs/mdlib/membed.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,12 +49,18 @@ struct t_inputrec; class t_state; /* initialisation of membed code */ -gmx_membed_t *init_membed(FILE *fplog, int nfile, const t_filenm fnm[], gmx_mtop_t *mtop, - t_inputrec *inputrec, t_state *state, t_commrec *cr, real *cpt); +gmx_membed_t* init_membed(FILE* fplog, + int nfile, + const t_filenm fnm[], + gmx_mtop_t* mtop, + t_inputrec* inputrec, + t_state* state, + t_commrec* cr, + real* cpt); /* rescaling the coordinates voor de membed code */ -void rescale_membed(int step_rel, gmx_membed_t *membed, rvec *x); +void rescale_membed(int step_rel, gmx_membed_t* membed, rvec* x); -void free_membed(gmx_membed_t *membed); +void free_membed(gmx_membed_t* membed); #endif diff --git a/src/gromacs/mdlib/nsgrid.cpp b/src/gromacs/mdlib/nsgrid.cpp index 1768a73ba7..db14315e70 100644 --- a/src/gromacs/mdlib/nsgrid.cpp +++ b/src/gromacs/mdlib/nsgrid.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,16 +61,16 @@ * Grid Routines ***********************************/ -static const char *range_warn = - "Explanation: During neighborsearching, we assign each particle to a grid\n" - "based on its coordinates. If your system contains collisions or parameter\n" - "errors that give particles very high velocities you might end up with some\n" - "coordinates being +-Infinity or NaN (not-a-number). Obviously, we cannot\n" - "put these on a grid, so this is usually where we detect those errors.\n" - "Make sure your system is properly energy-minimized and that the potential\n" - "energy seems reasonable before trying again."; +static const char* range_warn = + "Explanation: During neighborsearching, we assign each particle to a grid\n" + "based on its coordinates. If your system contains collisions or parameter\n" + "errors that give particles very high velocities you might end up with some\n" + "coordinates being +-Infinity or NaN (not-a-number). Obviously, we cannot\n" + "put these on a grid, so this is usually where we detect those errors.\n" + "Make sure your system is properly energy-minimized and that the potential\n" + "energy seems reasonable before trying again."; -static void calc_x_av_stddev(int n, rvec *x, rvec av, rvec stddev) +static void calc_x_av_stddev(int n, rvec* x, rvec av, rvec stddev) { dvec s1, s2; int i, d; @@ -83,23 +83,21 @@ static void calc_x_av_stddev(int n, rvec *x, rvec av, rvec stddev) for (d = 0; d < DIM; d++) { s1[d] += x[i][d]; - s2[d] += x[i][d]*x[i][d]; + s2[d] += x[i][d] * x[i][d]; } } - dsvmul(1.0/n, s1, s1); - dsvmul(1.0/n, s2, s2); + dsvmul(1.0 / n, s1, s1); + dsvmul(1.0 / n, s2, s2); for (d = 0; d < DIM; d++) { av[d] = s1[d]; - stddev[d] = std::sqrt(s2[d] - s1[d]*s1[d]); + stddev[d] = std::sqrt(s2[d] - s1[d] * s1[d]); } } -static void get_nsgrid_boundaries_vac(real av, real stddev, - real *bound0, real *bound1, - real *bdens0, real *bdens1) +static void get_nsgrid_boundaries_vac(real av, real stddev, real* bound0, real* bound1, real* bdens0, real* bdens1) { /* Set the grid to 2 times the standard deviation of * the charge group centers in both directions. @@ -108,32 +106,36 @@ static void get_nsgrid_boundaries_vac(real av, real stddev, * For a sphere stddev is r/sqrt(5): 99.2% falls within the width. * For a Gaussian distribution 98% fall within the width. */ - *bound0 = av - NSGRID_STDDEV_FAC*stddev; - *bound1 = av + NSGRID_STDDEV_FAC*stddev; + *bound0 = av - NSGRID_STDDEV_FAC * stddev; + *bound1 = av + NSGRID_STDDEV_FAC * stddev; - *bdens0 = av - GRID_STDDEV_FAC*stddev; - *bdens1 = av + GRID_STDDEV_FAC*stddev; + *bdens0 = av - GRID_STDDEV_FAC * stddev; + *bdens1 = av + GRID_STDDEV_FAC * stddev; } -static void dd_box_bounds_to_ns_bounds(real box0, real box_size, - real *gr0, real *gr1) +static void dd_box_bounds_to_ns_bounds(real box0, real box_size, real* gr0, real* gr1) { real av, stddev; /* Redetermine av and stddev from the DD box boundaries */ - av = box0 + 0.5*box_size; - stddev = 0.5*box_size/GRID_STDDEV_FAC; + av = box0 + 0.5 * box_size; + stddev = 0.5 * box_size / GRID_STDDEV_FAC; - *gr0 = av - NSGRID_STDDEV_FAC*stddev; - *gr1 = av + NSGRID_STDDEV_FAC*stddev; + *gr0 = av - NSGRID_STDDEV_FAC * stddev; + *gr1 = av + NSGRID_STDDEV_FAC * stddev; } -void get_nsgrid_boundaries(int nboundeddim, matrix box, - gmx_domdec_t *dd, - gmx_ddbox_t *ddbox, rvec *gr0, rvec *gr1, - int ncg, rvec *cgcm, - rvec grid_x0, rvec grid_x1, - real *grid_density) +void get_nsgrid_boundaries(int nboundeddim, + matrix box, + gmx_domdec_t* dd, + gmx_ddbox_t* ddbox, + rvec* gr0, + rvec* gr1, + int ncg, + rvec* cgcm, + rvec grid_x0, + rvec grid_x1, + real* grid_density) { rvec av, stddev; real vol, bdens0, bdens1; @@ -151,15 +153,13 @@ void get_nsgrid_boundaries(int nboundeddim, matrix box, { grid_x0[d] = (gr0 != nullptr ? (*gr0)[d] : 0); grid_x1[d] = (gr1 != nullptr ? (*gr1)[d] : box[d][d]); - vol *= (grid_x1[d] - grid_x0[d]); + vol *= (grid_x1[d] - grid_x0[d]); } else { if (ddbox == nullptr) { - get_nsgrid_boundaries_vac(av[d], stddev[d], - &grid_x0[d], &grid_x1[d], - &bdens0, &bdens1); + get_nsgrid_boundaries_vac(av[d], stddev[d], &grid_x0[d], &grid_x1[d], &bdens0, &bdens1); } else { @@ -168,8 +168,7 @@ void get_nsgrid_boundaries(int nboundeddim, matrix box, * Should be replaced by local boundaries, which makes * the ns grid smaller and does not require global comm. */ - dd_box_bounds_to_ns_bounds(ddbox->box0[d], ddbox->box_size[d], - &grid_x0[d], &grid_x1[d]); + dd_box_bounds_to_ns_bounds(ddbox->box0[d], ddbox->box_size[d], &grid_x0[d], &grid_x1[d]); bdens0 = grid_x0[d]; bdens1 = grid_x1[d]; } @@ -180,7 +179,7 @@ void get_nsgrid_boundaries(int nboundeddim, matrix box, bdens0 = (*gr0)[d]; } /* Check for a DD cell not at a higher edge */ - if (dd != nullptr && gr1 != nullptr && dd->ci[d] < dd->nc[d]-1) + if (dd != nullptr && gr1 != nullptr && dd->ci[d] < dd->nc[d] - 1) { grid_x1[d] = (*gr1)[d]; bdens1 = (*gr1)[d]; @@ -190,18 +189,21 @@ void get_nsgrid_boundaries(int nboundeddim, matrix box, if (debug) { - fprintf(debug, "Set grid boundaries dim %d: %f %f\n", - d, grid_x0[d], grid_x1[d]); + fprintf(debug, "Set grid boundaries dim %d: %f %f\n", d, grid_x0[d], grid_x1[d]); } } - *grid_density = ncg/vol; + *grid_density = ncg / vol; } -static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlist, - const gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, - t_grid *grid, - real grid_density) +static void set_grid_sizes(matrix box, + rvec izones_x0, + rvec izones_x1, + real rlist, + const gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + t_grid* grid, + real grid_density) { int i, j; gmx_bool bDD, bDDRect; @@ -212,23 +214,21 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis { if (debug) { - fprintf(debug, - "set_grid_sizes, i-zone bounds for dim %d: %6.3f %6.3f\n", - i, izones_x0[i], izones_x1[i]); + fprintf(debug, "set_grid_sizes, i-zone bounds for dim %d: %6.3f %6.3f\n", i, + izones_x0[i], izones_x1[i]); } izones_size[i] = izones_x1[i] - izones_x0[i]; } /* Use the ideal number of cg's per cell to set the ideal cell size */ - inv_r_ideal = std::cbrt(grid_density/grid->ncg_ideal); - if (rlist > 0 && inv_r_ideal*rlist < 1) + inv_r_ideal = std::cbrt(grid_density / grid->ncg_ideal); + if (rlist > 0 && inv_r_ideal * rlist < 1) { - inv_r_ideal = 1/rlist; + inv_r_ideal = 1 / rlist; } if (debug) { - fprintf(debug, "CG density %f ideal ns cell size %f\n", - grid_density, 1/inv_r_ideal); + fprintf(debug, "CG density %f ideal ns cell size %f\n", grid_density, 1 / inv_r_ideal); } clear_rvec(grid->cell_offset); @@ -248,13 +248,11 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis /* With DD grid cell jumps only the first decomposition * direction has uniform DD cell boundaries. */ - bDDRect = !((ddbox->tric_dir[i] != 0) || - (dd_dlb_is_on(dd) && i != dd->dim[0])); + bDDRect = !((ddbox->tric_dir[i] != 0) || (dd_dlb_is_on(dd) && i != dd->dim[0])); radd = rlist; - if (i >= ddbox->npbcdim && - (rlist == 0 || - izones_x1[i] + radd > ddbox->box0[i] + ddbox->box_size[i])) + if (i >= ddbox->npbcdim + && (rlist == 0 || izones_x1[i] + radd > ddbox->box0[i] + ddbox->box_size[i])) { radd = ddbox->box0[i] + ddbox->box_size[i] - izones_x1[i]; if (radd < 0) @@ -270,7 +268,7 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis } else { - size += radd/ddbox->skew_fac[i]; + size += radd / ddbox->skew_fac[i]; } /* Check if the cell boundary in this direction is @@ -279,12 +277,12 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis * any value, we help the compiler avoid warnings and potentially * optimize by ensuring that j < DIM here. */ - for (j = i+1; j < grid->npbcdim && j < DIM; j++) + for (j = i + 1; j < grid->npbcdim && j < DIM; j++) { if (box[j][i] != 0) { /* Correct the offset for the home cell location */ - grid->cell_offset[i] += izones_x0[j]*box[j][i]/box[j][j]; + grid->cell_offset[i] += izones_x0[j] * box[j][i] / box[j][j]; /* Correct the offset and size for the off-diagonal * displacement of opposing DD cell corners. @@ -293,7 +291,7 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis * box[j][i]*rlist/(dd->skew_fac[i]*box[j][j]) */ /* Determine the shift for the corners of the triclinic box */ - add_tric = izones_size[j]*box[j][i]/box[j][j]; + add_tric = izones_size[j] * box[j][i] / box[j][j]; if (dd->ndim == 1 && j == ZZ) { /* With 1D domain decomposition the cg's are not in @@ -301,12 +299,12 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis * Therefore we need to add the shift from the trilinic * corner to the corner at y=0. */ - add_tric += -box[YY][XX]*box[ZZ][YY]/box[YY][YY]; + add_tric += -box[YY][XX] * box[ZZ][YY] / box[YY][YY]; } if (box[j][i] < 0) { grid->cell_offset[i] += add_tric; - size -= add_tric; + size -= add_tric; } else { @@ -321,12 +319,12 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis * we will use the normal grid ns that checks all cells * that are within cut-off distance of the i-particle. */ - grid->n[i] = gmx::roundToInt(size*inv_r_ideal); + grid->n[i] = gmx::roundToInt(size * inv_r_ideal); if (grid->n[i] < 2) { grid->n[i] = 2; } - grid->cell_size[i] = size/grid->n[i]; + grid->cell_size[i] = size / grid->n[i]; grid->ncpddc[i] = 0; } else @@ -336,34 +334,32 @@ static void set_grid_sizes(matrix box, rvec izones_x0, rvec izones_x1, real rlis * We can then beforehand exclude certain ns grid cells * for non-home i-particles. */ - grid->ncpddc[i] = gmx::roundToInt(izones_size[i]*inv_r_ideal); + grid->ncpddc[i] = gmx::roundToInt(izones_size[i] * inv_r_ideal); if (grid->ncpddc[i] < 2) { grid->ncpddc[i] = 2; } - grid->cell_size[i] = izones_size[i]/grid->ncpddc[i]; - grid->n[i] = grid->ncpddc[i] + static_cast(radd/grid->cell_size[i]) + 1; + grid->cell_size[i] = izones_size[i] / grid->ncpddc[i]; + grid->n[i] = grid->ncpddc[i] + static_cast(radd / grid->cell_size[i]) + 1; } if (debug) { - fprintf(debug, "grid dim %d size %d x %f: %f - %f\n", - i, grid->n[i], grid->cell_size[i], - grid->cell_offset[i], - grid->cell_offset[i]+grid->n[i]*grid->cell_size[i]); + fprintf(debug, "grid dim %d size %d x %f: %f - %f\n", i, grid->n[i], grid->cell_size[i], + grid->cell_offset[i], grid->cell_offset[i] + grid->n[i] * grid->cell_size[i]); } } if (debug) { - fprintf(debug, "CG ncg ideal %d, actual density %.1f\n", - grid->ncg_ideal, grid_density*grid->cell_size[XX]*grid->cell_size[YY]*grid->cell_size[ZZ]); + fprintf(debug, "CG ncg ideal %d, actual density %.1f\n", grid->ncg_ideal, + grid_density * grid->cell_size[XX] * grid->cell_size[YY] * grid->cell_size[ZZ]); } } -t_grid *init_grid(FILE *fplog, t_forcerec *fr) +t_grid* init_grid(FILE* fplog, t_forcerec* fr) { - char *ptr; - t_grid *grid; + char* ptr; + t_grid* grid; snew(grid, 1); @@ -380,8 +376,7 @@ t_grid *init_grid(FILE *fplog, t_forcerec *fr) if (debug) { - fprintf(debug, "The coordinates are bounded in %d dimensions\n", - grid->nboundeddim); + fprintf(debug, "The coordinates are bounded in %d dimensions\n", grid->nboundeddim); } /* The ideal number of cg's per ns grid cell seems to be 10 */ @@ -407,15 +402,15 @@ t_grid *init_grid(FILE *fplog, t_forcerec *fr) return grid; } -void done_grid(t_grid *grid) +void done_grid(t_grid* grid) { if (grid == nullptr) { return; } - grid->nr = 0; + grid->nr = 0; clear_ivec(grid->n); - grid->ncells = 0; + grid->ncells = 0; sfree(grid->cell_index); sfree(grid->a); sfree(grid->index); @@ -436,36 +431,36 @@ void done_grid(t_grid *grid) int xyz2ci_(int nry, int nrz, int x, int y, int z) /* Return the cell index */ { - return (nry*nrz*x+nrz*y+z); + return (nry * nrz * x + nrz * y + z); } -void ci2xyz(t_grid *grid, int i, int *x, int *y, int *z) +void ci2xyz(t_grid* grid, int i, int* x, int* y, int* z) /* Return x,y and z from the cell index */ { int ci; range_check_mesg(i, 0, grid->nr, range_warn); - ci = grid->cell_index[i]; - *x = ci / (grid->n[YY]*grid->n[ZZ]); - ci -= (*x)*grid->n[YY]*grid->n[ZZ]; - *y = ci / grid->n[ZZ]; - ci -= (*y)*grid->n[ZZ]; - *z = ci; + ci = grid->cell_index[i]; + *x = ci / (grid->n[YY] * grid->n[ZZ]); + ci -= (*x) * grid->n[YY] * grid->n[ZZ]; + *y = ci / grid->n[ZZ]; + ci -= (*y) * grid->n[ZZ]; + *z = ci; } static int ci_not_used(const ivec n) { /* Return an improbable value */ - return xyz2ci(n[YY], n[ZZ], 3*n[XX], 3*n[YY], 3*n[ZZ]); + return xyz2ci(n[YY], n[ZZ], 3 * n[XX], 3 * n[YY], 3 * n[ZZ]); } -static void set_grid_ncg(t_grid *grid, int ncg) +static void set_grid_ncg(t_grid* grid, int ncg) { int nr_old, i; grid->nr = ncg; - if (grid->nr+1 > grid->nr_alloc) + if (grid->nr + 1 > grid->nr_alloc) { nr_old = grid->nr_alloc; grid->nr_alloc = over_alloc_dd(grid->nr) + 1; @@ -478,28 +473,32 @@ static void set_grid_ncg(t_grid *grid, int ncg) } } -void grid_first(FILE *fplog, t_grid *grid, - gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, - matrix box, rvec izones_x0, rvec izones_x1, - real rlist, real grid_density) +void grid_first(FILE* fplog, + t_grid* grid, + gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + matrix box, + rvec izones_x0, + rvec izones_x1, + real rlist, + real grid_density) { - int i, m; + int i, m; set_grid_sizes(box, izones_x0, izones_x1, rlist, dd, ddbox, grid, grid_density); - grid->ncells = grid->n[XX]*grid->n[YY]*grid->n[ZZ]; + grid->ncells = grid->n[XX] * grid->n[YY] * grid->n[ZZ]; - if (grid->ncells+1 > grid->cells_nalloc) + if (grid->ncells + 1 > grid->cells_nalloc) { /* Allocate double the size so we have some headroom */ - grid->cells_nalloc = 2*grid->ncells; - srenew(grid->nra, grid->cells_nalloc+1); - srenew(grid->index, grid->cells_nalloc+1); + grid->cells_nalloc = 2 * grid->ncells; + srenew(grid->nra, grid->cells_nalloc + 1); + srenew(grid->index, grid->cells_nalloc + 1); if (fplog) { - fprintf(fplog, "Grid: %d x %d x %d cells\n", - grid->n[XX], grid->n[YY], grid->n[ZZ]); + fprintf(fplog, "Grid: %d x %d x %d cells\n", grid->n[XX], grid->n[YY], grid->n[ZZ]); } } @@ -507,7 +506,7 @@ void grid_first(FILE *fplog, t_grid *grid, if (m > grid->dc_nalloc) { /* Allocate with double the initial size for box scaling */ - grid->dc_nalloc = 2*m; + grid->dc_nalloc = 2 * m; srenew(grid->dcx2, grid->dc_nalloc); srenew(grid->dcy2, grid->dc_nalloc); srenew(grid->dcz2, grid->dc_nalloc); @@ -527,7 +526,7 @@ static void calc_bor(int cg0, int cg1, int ncg, int CG0[2], int CG1[2]) CG0[0] = cg0; CG1[0] = ncg; CG0[1] = 0; - CG1[1] = cg1-ncg; + CG1[1] = cg1 - ncg; } else { @@ -546,16 +545,15 @@ static void calc_bor(int cg0, int cg1, int ncg, int CG0[2], int CG1[2]) fprintf(debug, "CG0[%d]=%d, CG1[%d]=%d\n", m, CG0[m], m, CG1[m]); } } - } -void calc_elemnr(t_grid *grid, int cg0, int cg1, int ncg) +void calc_elemnr(t_grid* grid, int cg0, int cg1, int ncg) { - int CG0[2], CG1[2]; - int *cell_index = grid->cell_index; - int *nra = grid->nra; - int i, m, ncells; - int ci, not_used; + int CG0[2], CG1[2]; + int* cell_index = grid->cell_index; + int* nra = grid->nra; + int i, m, ncells; + int ci, not_used; ncells = grid->ncells; if (ncells <= 0) @@ -580,10 +578,10 @@ void calc_elemnr(t_grid *grid, int cg0, int cg1, int ncg) } } -void calc_ptrs(t_grid *grid) +void calc_ptrs(t_grid* grid) { - int *index = grid->index; - int *nra = grid->nra; + int* index = grid->index; + int* nra = grid->nra; int ix, iy, iz, ci, nr; int nnra, ncells; @@ -603,22 +601,22 @@ void calc_ptrs(t_grid *grid) range_check_mesg(ci, 0, ncells, range_warn); index[ci] = nr; nnra = nra[ci]; - nr += nnra; - nra[ci] = 0; + nr += nnra; + nra[ci] = 0; } } } } -void grid_last(t_grid *grid, int cg0, int cg1, int ncg) +void grid_last(t_grid* grid, int cg0, int cg1, int ncg) { - int CG0[2], CG1[2]; - int i, m; - int ci, not_used, ind, ncells; - int *cell_index = grid->cell_index; - int *nra = grid->nra; - int *index = grid->index; - int *a = grid->a; + int CG0[2], CG1[2]; + int i, m; + int ci, not_used, ind, ncells; + int* cell_index = grid->cell_index; + int* nra = grid->nra; + int* index = grid->index; + int* a = grid->a; ncells = grid->ncells; if (ncells <= 0) @@ -633,11 +631,11 @@ void grid_last(t_grid *grid, int cg0, int cg1, int ncg) { for (i = CG0[m]; (i < CG1[m]); i++) { - ci = cell_index[i]; + ci = cell_index[i]; if (ci != not_used) { range_check_mesg(ci, 0, ncells, range_warn); - ind = index[ci]+nra[ci]++; + ind = index[ci] + nra[ci]++; range_check_mesg(ind, 0, grid->nr, range_warn); a[ind] = i; } @@ -645,16 +643,14 @@ void grid_last(t_grid *grid, int cg0, int cg1, int ncg) } } -void fill_grid(gmx_domdec_zones_t *dd_zones, - t_grid *grid, int ncg_tot, - int cg0, int cg1, rvec cg_cm[]) +void fill_grid(gmx_domdec_zones_t* dd_zones, t_grid* grid, int ncg_tot, int cg0, int cg1, rvec cg_cm[]) { - int *cell_index; - int nry, nrz; - rvec n_box, offset; - int zone, ccg0, ccg1, cg, d, not_used; - ivec shift0, useall, b0, b1, ind; - gmx_bool bUse; + int* cell_index; + int nry, nrz; + rvec n_box, offset; + int zone, ccg0, ccg1, cg, d, not_used; + ivec shift0, useall, b0, b1, ind; + gmx_bool bUse; if (cg0 == -1) { @@ -675,7 +671,7 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, { if (grid->cell_size[d] > 0) { - n_box[d] = 1/grid->cell_size[d]; + n_box[d] = 1 / grid->cell_size[d]; } else { @@ -695,7 +691,7 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, { for (d = 0; d < DIM; d++) { - ind[d] = static_cast((cg_cm[cg][d] - offset[d])*n_box[d]); + ind[d] = static_cast((cg_cm[cg][d] - offset[d]) * n_box[d]); /* With pbc we should be done here. * Without pbc cg's outside the grid * should be assigned to the closest grid cell. @@ -717,7 +713,7 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, for (zone = 0; zone < dd_zones->n; zone++) { ccg0 = dd_zones->cg_range[zone]; - ccg1 = dd_zones->cg_range[zone+1]; + ccg1 = dd_zones->cg_range[zone + 1]; if (ccg1 <= cg0 || ccg0 >= cg1) { continue; @@ -763,14 +759,14 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, if (cell_index[cg] == -1) { /* This cg has moved to another node */ - cell_index[cg] = NSGRID_SIGNAL_MOVED_FAC*grid->ncells; + cell_index[cg] = NSGRID_SIGNAL_MOVED_FAC * grid->ncells; continue; } bUse = TRUE; for (d = 0; d < DIM; d++) { - ind[d] = static_cast((cg_cm[cg][d] - offset[d])*n_box[d]); + ind[d] = static_cast((cg_cm[cg][d] - offset[d]) * n_box[d]); /* Here we have to correct for rounding problems, * as this cg_cm to cell index operation is not necessarily * binary identical to the operation for the DD zone assignment @@ -800,8 +796,8 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, } if (cg > grid->nr_alloc) { - fprintf(stderr, "WARNING: nra_alloc %d cg0 %d cg1 %d cg %d\n", - grid->nr_alloc, cg0, cg1, cg); + fprintf(stderr, "WARNING: nra_alloc %d cg0 %d cg1 %d cg %d\n", grid->nr_alloc, + cg0, cg1, cg); } if (bUse) { @@ -814,10 +810,9 @@ void fill_grid(gmx_domdec_zones_t *dd_zones, } } } - } -void check_grid(t_grid *grid) +void check_grid(t_grid* grid) { int ix, iy, iz, ci, cci, nra; @@ -836,11 +831,10 @@ void check_grid(t_grid *grid) { if (ci > 0) { - nra = grid->index[ci]-grid->index[cci]; + nra = grid->index[ci] - grid->index[cci]; if (nra != grid->nra[cci]) { - gmx_fatal(FARGS, "nra=%d, grid->nra=%d, cci=%d", - nra, grid->nra[cci], cci); + gmx_fatal(FARGS, "nra=%d, grid->nra=%d, cci=%d", nra, grid->nra[cci], cci); } } cci = xyz2ci(grid->n[YY], grid->n[ZZ], ix, iy, iz); @@ -855,7 +849,7 @@ void check_grid(t_grid *grid) } } -void print_grid(FILE *log, t_grid *grid) +void print_grid(FILE* log, t_grid* grid) { int i, nra, index; int ix, iy, iz, ci; @@ -884,7 +878,7 @@ void print_grid(FILE *log, t_grid *grid) fprintf(log, "%3d%3d%3d%5d%5d", ix, iy, iz, nra, index); for (i = 0; (i < nra); i++) { - fprintf(log, "%5d", grid->a[index+i]); + fprintf(log, "%5d", grid->a[index + i]); } fprintf(log, "\n"); } diff --git a/src/gromacs/mdlib/nsgrid.h b/src/gromacs/mdlib/nsgrid.h index c96b208d17..4606a8b0f6 100644 --- a/src/gromacs/mdlib/nsgrid.h +++ b/src/gromacs/mdlib/nsgrid.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,32 +48,33 @@ struct gmx_ddbox_t; struct t_forcerec; struct t_grid; -typedef struct t_grid { - int nr; // Total number of charge groups - int nboundeddim; // The number of bounded dimensions - int npbcdim; // The number of dimensions with pbc - int ncg_ideal; // The ideal number of cg's per cell - ivec n; // The dimension of the grid - int ncells; // Total number of cells - int cells_nalloc; // Allocation size of index and nra - ivec ncpddc; // The number of cells per DD cell - rvec cell_size; // The size of the cells - rvec cell_offset; // The offset of the cell (0,0,0) - int *cell_index; // The cell number of each cg - int *index; // The index into a for each cell - // The location of the cell in the index - // array can be found by calling xyz2ci - int *nra; // The number of entries in a cell - int icg0; // The start of the i-cg range - int icg1; // The end of the i-cg range - rvec *os0; - rvec *os1; - int *a; // The grid of cgs - int nr_alloc; // Allocation size of cell_index and a - real *dcx2; // Squared distance from atom to j-cell - real *dcy2; // Squared distance from atom to j-cell - real *dcz2; // Squared distance from atom to j-cell - int dc_nalloc; // Allocation size of dcx2, dyc2, dcz2 +typedef struct t_grid +{ + int nr; // Total number of charge groups + int nboundeddim; // The number of bounded dimensions + int npbcdim; // The number of dimensions with pbc + int ncg_ideal; // The ideal number of cg's per cell + ivec n; // The dimension of the grid + int ncells; // Total number of cells + int cells_nalloc; // Allocation size of index and nra + ivec ncpddc; // The number of cells per DD cell + rvec cell_size; // The size of the cells + rvec cell_offset; // The offset of the cell (0,0,0) + int* cell_index; // The cell number of each cg + int* index; // The index into a for each cell + // The location of the cell in the index + // array can be found by calling xyz2ci + int* nra; // The number of entries in a cell + int icg0; // The start of the i-cg range + int icg1; // The end of the i-cg range + rvec* os0; + rvec* os1; + int* a; // The grid of cgs + int nr_alloc; // Allocation size of cell_index and a + real* dcx2; // Squared distance from atom to j-cell + real* dcy2; // Squared distance from atom to j-cell + real* dcz2; // Squared distance from atom to j-cell + int dc_nalloc; // Allocation size of dcx2, dyc2, dcz2 } t_grid; /*! \brief Used when estimating the interaction density. @@ -93,22 +94,26 @@ static const real GRID_STDDEV_FAC = 1.73205080757; */ static const real NSGRID_STDDEV_FAC = 2.0; -#define NSGRID_SIGNAL_MOVED_FAC 4 +#define NSGRID_SIGNAL_MOVED_FAC 4 /* A cell index of NSGRID_SIGNAL_MOVED_FAC*ncells signals * that a charge group moved to another DD domain. */ -t_grid *init_grid(FILE *fplog, t_forcerec *fr); - -void done_grid(t_grid *grid); - -void get_nsgrid_boundaries(int nboundeddim, matrix box, - struct gmx_domdec_t *dd, - gmx_ddbox_t *ddbox, - rvec *gr0, rvec *gr1, - int ncg, rvec *cgcm, - rvec grid_x0, rvec grid_x1, - real *grid_density); +t_grid* init_grid(FILE* fplog, t_forcerec* fr); + +void done_grid(t_grid* grid); + +void get_nsgrid_boundaries(int nboundeddim, + matrix box, + struct gmx_domdec_t* dd, + gmx_ddbox_t* ddbox, + rvec* gr0, + rvec* gr1, + int ncg, + rvec* cgcm, + rvec grid_x0, + rvec grid_x1, + real* grid_density); /* Return the ns grid boundaries grid_x0 and grid_x1 * and the estimate for the grid density. * For non-bounded dimensions the boundaries are determined @@ -119,32 +124,36 @@ void get_nsgrid_boundaries(int nboundeddim, matrix box, * on the edges are determined from cgcm. */ -void grid_first(FILE *log, t_grid *grid, - struct gmx_domdec_t *dd, const gmx_ddbox_t *ddbox, matrix box, rvec izones_x0, rvec izones_x1, - real rlong, real grid_density); - -void fill_grid(struct gmx_domdec_zones_t *dd_zones, - t_grid *grid, int ncg_tot, - int cg0, int cg1, rvec cg_cm[]); +void grid_first(FILE* log, + t_grid* grid, + struct gmx_domdec_t* dd, + const gmx_ddbox_t* ddbox, + matrix box, + rvec izones_x0, + rvec izones_x1, + real rlong, + real grid_density); + +void fill_grid(struct gmx_domdec_zones_t* dd_zones, t_grid* grid, int ncg_tot, int cg0, int cg1, rvec cg_cm[]); /* Allocates space on the grid for ncg_tot cg's. * Fills the grid with cg's from cg0 to cg1. * When cg0 is -1, contiues filling from grid->nr to cg1. */ -void calc_elemnr(t_grid *grid, int cg0, int cg1, int ncg); +void calc_elemnr(t_grid* grid, int cg0, int cg1, int ncg); -void calc_ptrs(t_grid *grid); +void calc_ptrs(t_grid* grid); -void grid_last(t_grid *grid, int cg0, int cg1, int ncg); +void grid_last(t_grid* grid, int cg0, int cg1, int ncg); int xyz2ci_(int nry, int nrz, int x, int y, int z); -#define xyz2ci(nry, nrz, x, y, z) ((nry)*(nrz)*(x)+(nrz)*(y)+(z)) +#define xyz2ci(nry, nrz, x, y, z) ((nry) * (nrz) * (x) + (nrz) * (y) + (z)) /* Return the cell index */ -void ci2xyz(t_grid *grid, int i, int *x, int *y, int *z); +void ci2xyz(t_grid* grid, int i, int* x, int* y, int* z); -void check_grid(t_grid *grid); +void check_grid(t_grid* grid); -void print_grid(FILE *log, t_grid *grid); +void print_grid(FILE* log, t_grid* grid); #endif diff --git a/src/gromacs/mdlib/perf_est.cpp b/src/gromacs/mdlib/perf_est.cpp index 5ba7a740d5..c93de7f105 100644 --- a/src/gromacs/mdlib/perf_est.cpp +++ b/src/gromacs/mdlib/perf_est.cpp @@ -64,13 +64,13 @@ */ /* Cost of a pair interaction in the "Verlet" cut-off scheme, QEXP is Ewald */ -static const double c_nbnxn_lj = 2.5; -static const double c_nbnxn_qrf_lj = 2.9; -static const double c_nbnxn_qrf = 2.4; -static const double c_nbnxn_qexp_lj = 4.2; -static const double c_nbnxn_qexp = 3.8; +static const double c_nbnxn_lj = 2.5; +static const double c_nbnxn_qrf_lj = 2.9; +static const double c_nbnxn_qrf = 2.4; +static const double c_nbnxn_qexp_lj = 4.2; +static const double c_nbnxn_qexp = 3.8; /* Extra cost for expensive LJ interaction, e.g. pot-switch or LJ-PME */ -static const double c_nbnxn_ljexp_add = 1.0; +static const double c_nbnxn_ljexp_add = 1.0; /* Cost of the different components of PME. */ /* Cost of particle reordering and redistribution (no SIMD correction). @@ -81,20 +81,20 @@ static const double c_pme_redist = 100.0; /* Cost of q spreading and force interpolation per charge. This part almost * doesn't accelerate with SIMD, so we don't use SIMD correction. */ -static const double c_pme_spread = 5.0; +static const double c_pme_spread = 5.0; /* Cost of fft's, will be multiplied with 2 N log2(N) (no SIMD correction) * Without MPI the number is 2-3, depending on grid factors and thread count. * We take the high limit to be on the safe side and account for some MPI * communication cost, which will dominate at high parallelization. */ -static const double c_pme_fft = 3.0; +static const double c_pme_fft = 3.0; /* Cost of pme_solve, will be multiplied with N */ -static const double c_pme_solve = 9.0; +static const double c_pme_solve = 9.0; /* Cost of a bonded interaction divided by the number of distances calculations * required in one interaction. The actual cost is nearly propotional to this. */ -static const double c_bond = 25.0; +static const double c_bond = 25.0; #if GMX_SIMD_HAVE_REAL @@ -126,15 +126,15 @@ static double simd_cycle_factor(gmx_bool bUseSIMD) * As a rough, but actually not bad, approximation we use a sqrt * dependence on the width which gives a factor 4 for width=8. */ - speedup = std::sqrt(2.0*GMX_SIMD_REAL_WIDTH); -#if GMX_SIMD_HAVE_FMA + speedup = std::sqrt(2.0 * GMX_SIMD_REAL_WIDTH); +# if GMX_SIMD_HAVE_FMA /* FMA tends to give a bit more speedup */ speedup *= 1.25; -#endif +# endif } else { - speedup = 1.0; + speedup = 1.0; } #else if (bUseSIMD) @@ -142,7 +142,7 @@ static double simd_cycle_factor(gmx_bool bUseSIMD) gmx_incons("gmx_cycle_factor() compiled without SIMD called with bUseSIMD=TRUE"); } /* No SIMD, no speedup */ - speedup = 1.0; + speedup = 1.0; #endif /* Return speed compared to the reference (Haswell). @@ -150,24 +150,22 @@ static double simd_cycle_factor(gmx_bool bUseSIMD) * Sandy/Ivy Bridge than Haswell, but that only leads to a too high * PME load estimate on SB/IB, which is erring on the safe side. */ - return simd_cycle_no_simd/speedup; + return simd_cycle_no_simd / speedup; } -void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, - double *ndistance_c, double *ndistance_simd) +void count_bonded_distances(const gmx_mtop_t& mtop, const t_inputrec& ir, double* ndistance_c, double* ndistance_simd) { - gmx_bool bExcl; - double nonsimd_step_frac; - int ftype; - double ndtot_c, ndtot_simd; + gmx_bool bExcl; + double nonsimd_step_frac; + int ftype; + double ndtot_c, ndtot_simd; #if GMX_SIMD_HAVE_REAL - gmx_bool bSimdBondeds = TRUE; + gmx_bool bSimdBondeds = TRUE; #else - gmx_bool bSimdBondeds = FALSE; + gmx_bool bSimdBondeds = FALSE; #endif - bExcl = (ir.cutoff_scheme == ecutsGROUP && inputrecExclForces(&ir) - && !EEL_FULL(ir.coulombtype)); + bExcl = (ir.cutoff_scheme == ecutsGROUP && inputrecExclForces(&ir) && !EEL_FULL(ir.coulombtype)); if (bSimdBondeds) { @@ -176,15 +174,15 @@ void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, */ if (ir.nstcalcenergy > 0) { - nonsimd_step_frac = 1.0/ir.nstcalcenergy; + nonsimd_step_frac = 1.0 / ir.nstcalcenergy; } else { nonsimd_step_frac = 0; } - if (ir.epc != epcNO && 1.0/ir.nstpcouple > nonsimd_step_frac) + if (ir.epc != epcNO && 1.0 / ir.nstpcouple > nonsimd_step_frac) { - nonsimd_step_frac = 1.0/ir.nstpcouple; + nonsimd_step_frac = 1.0 / ir.nstpcouple; } } else @@ -197,9 +195,9 @@ void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, */ ndtot_c = 0; ndtot_simd = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t *molt = &mtop.moltype[molb.type]; + const gmx_moltype_t* molt = &mtop.moltype[molb.type]; for (ftype = 0; ftype < F_NRE; ftype++) { int nbonds; @@ -216,31 +214,26 @@ void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, switch (ftype) { case F_POSRES: - case F_FBPOSRES: - nd_c = 1; - break; - case F_CONNBONDS: - break; + case F_FBPOSRES: nd_c = 1; break; + case F_CONNBONDS: break; /* These bonded potentially use SIMD */ case F_ANGLES: case F_PDIHS: case F_RBDIHS: case F_LJ14: - nd_c = nonsimd_step_frac *(NRAL(ftype) - 1); - nd_simd = (1 - nonsimd_step_frac)*(NRAL(ftype) - 1); - break; - default: - nd_c = NRAL(ftype) - 1; + nd_c = nonsimd_step_frac * (NRAL(ftype) - 1); + nd_simd = (1 - nonsimd_step_frac) * (NRAL(ftype) - 1); break; + default: nd_c = NRAL(ftype) - 1; break; } - nbonds = molb.nmol*molt->ilist[ftype].size()/(1 + NRAL(ftype)); - ndtot_c += nbonds*nd_c; - ndtot_simd += nbonds*nd_simd; + nbonds = molb.nmol * molt->ilist[ftype].size() / (1 + NRAL(ftype)); + ndtot_c += nbonds * nd_c; + ndtot_simd += nbonds * nd_simd; } } if (bExcl) { - ndtot_c += molb.nmol*(molt->excls.nra - molt->atoms.nr)/2.; + ndtot_c += molb.nmol * (molt->excls.nra - molt->atoms.nr) / 2.; } } @@ -249,9 +242,9 @@ void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, fprintf(debug, "nr. of distance calculations in bondeds: C %.1f SIMD %.1f\n", ndtot_c, ndtot_simd); } - if (ndistance_c != nullptr) + if (ndistance_c != nullptr) { - *ndistance_c = ndtot_c; + *ndistance_c = ndtot_c; } if (ndistance_simd != nullptr) { @@ -259,45 +252,48 @@ void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, } } -static void pp_verlet_load(const gmx_mtop_t &mtop, const t_inputrec &ir, - const matrix box, - int *nq_tot, int *nlj_tot, - double *cost_pp, - gmx_bool *bChargePerturbed, gmx_bool *bTypePerturbed) +static void pp_verlet_load(const gmx_mtop_t& mtop, + const t_inputrec& ir, + const matrix box, + int* nq_tot, + int* nlj_tot, + double* cost_pp, + gmx_bool* bChargePerturbed, + gmx_bool* bTypePerturbed) { - int atnr, a, nqlj, nq, nlj; - gmx_bool bQRF; - real r_eff; - double c_qlj, c_q, c_lj; - double nppa; - int j_cluster_size; + int atnr, a, nqlj, nq, nlj; + gmx_bool bQRF; + real r_eff; + double c_qlj, c_q, c_lj; + double nppa; + int j_cluster_size; /* Conversion factor for reference vs SIMD kernel performance. * The factor is about right for SSE2/4, but should be 2 higher for AVX256. */ #if GMX_DOUBLE - const real nbnxn_refkernel_fac = 4.0; + const real nbnxn_refkernel_fac = 4.0; #else - const real nbnxn_refkernel_fac = 8.0; + const real nbnxn_refkernel_fac = 8.0; #endif bQRF = (EEL_RF(ir.coulombtype) || ir.coulombtype == eelCUT); gmx::ArrayRef iparams = mtop.ffparams.iparams; - atnr = mtop.ffparams.atnr; - nqlj = 0; - nq = 0; - *bChargePerturbed = FALSE; - *bTypePerturbed = FALSE; - for (const gmx_molblock_t &molb : mtop.molblock) + atnr = mtop.ffparams.atnr; + nqlj = 0; + nq = 0; + *bChargePerturbed = FALSE; + *bTypePerturbed = FALSE; + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t *molt = &mtop.moltype[molb.type]; - const t_atom *atom = molt->atoms.atom; + const gmx_moltype_t* molt = &mtop.moltype[molb.type]; + const t_atom* atom = molt->atoms.atom; for (a = 0; a < molt->atoms.nr; a++) { if (atom[a].q != 0 || atom[a].qB != 0) { - if (iparams[(atnr+1)*atom[a].type].lj.c6 != 0 || - iparams[(atnr+1)*atom[a].type].lj.c12 != 0) + if (iparams[(atnr + 1) * atom[a].type].lj.c6 != 0 + || iparams[(atnr + 1) * atom[a].type].lj.c12 != 0) { nqlj += molb.nmol; } @@ -326,55 +322,55 @@ static void pp_verlet_load(const gmx_mtop_t &mtop, const t_inputrec &ir, * This choice should match the one of pick_nbnxn_kernel_cpu(). * TODO: Make this function use pick_nbnxn_kernel_cpu(). */ -#if GMX_SIMD_HAVE_REAL && ((GMX_SIMD_REAL_WIDTH == 8 && defined GMX_SIMD_HAVE_FMA) || GMX_SIMD_REAL_WIDTH > 8) +#if GMX_SIMD_HAVE_REAL \ + && ((GMX_SIMD_REAL_WIDTH == 8 && defined GMX_SIMD_HAVE_FMA) || GMX_SIMD_REAL_WIDTH > 8) j_cluster_size = 8; #else - j_cluster_size = 4; + j_cluster_size = 4; #endif - r_eff = ir.rlist + nbnxn_get_rlist_effective_inc(j_cluster_size, mtop.natoms/det(box)); + r_eff = ir.rlist + nbnxn_get_rlist_effective_inc(j_cluster_size, mtop.natoms / det(box)); /* The average number of pairs per atom */ - nppa = 0.5*4/3*M_PI*r_eff*r_eff*r_eff*mtop.natoms/det(box); + nppa = 0.5 * 4 / 3 * M_PI * r_eff * r_eff * r_eff * mtop.natoms / det(box); if (debug) { - fprintf(debug, "nqlj %d nq %d nlj %d rlist %.3f r_eff %.3f pairs per atom %.1f\n", - nqlj, nq, nlj, ir.rlist, r_eff, nppa); + fprintf(debug, "nqlj %d nq %d nlj %d rlist %.3f r_eff %.3f pairs per atom %.1f\n", nqlj, nq, + nlj, ir.rlist, r_eff, nppa); } /* Determine the cost per pair interaction */ c_qlj = (bQRF ? c_nbnxn_qrf_lj : c_nbnxn_qexp_lj); - c_q = (bQRF ? c_nbnxn_qrf : c_nbnxn_qexp); + c_q = (bQRF ? c_nbnxn_qrf : c_nbnxn_qexp); c_lj = c_nbnxn_lj; if (ir.vdw_modifier == eintmodPOTSWITCH || EVDW_PME(ir.vdwtype)) { c_qlj += c_nbnxn_ljexp_add; - c_lj += c_nbnxn_ljexp_add; + c_lj += c_nbnxn_ljexp_add; } if (EVDW_PME(ir.vdwtype) && ir.ljpme_combination_rule == eljpmeLB) { /* We don't have LJ-PME LB comb. rule kernels, we use slow kernels */ c_qlj *= nbnxn_refkernel_fac; - c_q *= nbnxn_refkernel_fac; - c_lj *= nbnxn_refkernel_fac; + c_q *= nbnxn_refkernel_fac; + c_lj *= nbnxn_refkernel_fac; } /* For the PP non-bonded cost it is (unrealistically) assumed * that all atoms are distributed homogeneously in space. */ - *cost_pp = (nqlj*c_qlj + nq*c_q + nlj*c_lj)*nppa; + *cost_pp = (nqlj * c_qlj + nq * c_q + nlj * c_lj) * nppa; *cost_pp *= simd_cycle_factor(bHaveSIMD); } -float pme_load_estimate(const gmx_mtop_t &mtop, const t_inputrec &ir, - const matrix box) +float pme_load_estimate(const gmx_mtop_t& mtop, const t_inputrec& ir, const matrix box) { - int nq_tot, nlj_tot; - gmx_bool bChargePerturbed, bTypePerturbed; - double ndistance_c, ndistance_simd; - double cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve, cost_pme; - float ratio; + int nq_tot, nlj_tot; + gmx_bool bChargePerturbed, bTypePerturbed; + double ndistance_c, ndistance_simd; + double cost_bond, cost_pp, cost_redist, cost_spread, cost_fft, cost_solve, cost_pme; + float ratio; /* Computational cost of bonded, non-bonded and PME calculations. * This will be machine dependent. @@ -388,51 +384,47 @@ float pme_load_estimate(const gmx_mtop_t &mtop, const t_inputrec &ir, * so we need to scale the number of bonded interactions for which there * are only C implementations to the number of SIMD equivalents. */ - cost_bond = c_bond*(ndistance_c *simd_cycle_factor(FALSE) + - ndistance_simd*simd_cycle_factor(bHaveSIMD)); + cost_bond = c_bond + * (ndistance_c * simd_cycle_factor(FALSE) + ndistance_simd * simd_cycle_factor(bHaveSIMD)); - pp_verlet_load(mtop, ir, box, - &nq_tot, &nlj_tot, &cost_pp, - &bChargePerturbed, &bTypePerturbed); + pp_verlet_load(mtop, ir, box, &nq_tot, &nlj_tot, &cost_pp, &bChargePerturbed, &bTypePerturbed); cost_redist = 0; cost_spread = 0; cost_fft = 0; cost_solve = 0; - int gridNkzFactor = int{ - (ir.nkz + 1)/2 - }; + int gridNkzFactor = int{ (ir.nkz + 1) / 2 }; if (EEL_PME(ir.coulombtype)) { - double grid = ir.nkx*ir.nky*gridNkzFactor; + double grid = ir.nkx * ir.nky * gridNkzFactor; - int f = ((ir.efep != efepNO && bChargePerturbed) ? 2 : 1); - cost_redist += c_pme_redist*nq_tot; - cost_spread += f*c_pme_spread*nq_tot*gmx::power3(ir.pme_order); - cost_fft += f*c_pme_fft*grid*std::log(grid)/std::log(2.0); - cost_solve += f*c_pme_solve*grid*simd_cycle_factor(bHaveSIMD); + int f = ((ir.efep != efepNO && bChargePerturbed) ? 2 : 1); + cost_redist += c_pme_redist * nq_tot; + cost_spread += f * c_pme_spread * nq_tot * gmx::power3(ir.pme_order); + cost_fft += f * c_pme_fft * grid * std::log(grid) / std::log(2.0); + cost_solve += f * c_pme_solve * grid * simd_cycle_factor(bHaveSIMD); } if (EVDW_PME(ir.vdwtype)) { - double grid = ir.nkx*ir.nky*gridNkzFactor; + double grid = ir.nkx * ir.nky * gridNkzFactor; - int f = ((ir.efep != efepNO && bTypePerturbed) ? 2 : 1); + int f = ((ir.efep != efepNO && bTypePerturbed) ? 2 : 1); if (ir.ljpme_combination_rule == eljpmeLB) { /* LB combination rule: we have 7 mesh terms */ - f *= 7; + f *= 7; } - cost_redist += c_pme_redist*nlj_tot; - cost_spread += f*c_pme_spread*nlj_tot*gmx::power3(ir.pme_order); - cost_fft += f*c_pme_fft*2*grid*std::log(grid)/std::log(2.0); - cost_solve += f*c_pme_solve*grid*simd_cycle_factor(bHaveSIMD); + cost_redist += c_pme_redist * nlj_tot; + cost_spread += f * c_pme_spread * nlj_tot * gmx::power3(ir.pme_order); + cost_fft += f * c_pme_fft * 2 * grid * std::log(grid) / std::log(2.0); + cost_solve += f * c_pme_solve * grid * simd_cycle_factor(bHaveSIMD); } cost_pme = cost_redist + cost_spread + cost_fft + cost_solve; - ratio = cost_pme/(cost_bond + cost_pp + cost_pme); + ratio = cost_pme / (cost_bond + cost_pp + cost_pme); if (debug) { diff --git a/src/gromacs/mdlib/perf_est.h b/src/gromacs/mdlib/perf_est.h index 16fad2a057..cc635d3d98 100644 --- a/src/gromacs/mdlib/perf_est.h +++ b/src/gromacs/mdlib/perf_est.h @@ -43,16 +43,14 @@ struct gmx_mtop_t; struct t_inputrec; -void count_bonded_distances(const gmx_mtop_t &mtop, const t_inputrec &ir, - double *ndistance_c, double *ndistance_simd); +void count_bonded_distances(const gmx_mtop_t& mtop, const t_inputrec& ir, double* ndistance_c, double* ndistance_simd); /* Count the number of distance calculations in bonded interactions, * separately for plain-C and SIMD bonded functions. * The computational cost is nearly proportional to the numbers. * It is allowed to pass NULL for the last two arguments. */ -float pme_load_estimate(const gmx_mtop_t &mtop, const t_inputrec &ir, - const matrix box); +float pme_load_estimate(const gmx_mtop_t& mtop, const t_inputrec& ir, const matrix box); /* Returns an estimate for the relative load of the PME mesh calculation * in the total force calculation. * This estimate is reasonable for recent Intel and AMD x86_64 CPUs. diff --git a/src/gromacs/mdlib/qm_gamess.cpp b/src/gromacs/mdlib/qm_gamess.cpp index 1720aea264..697cea3434 100644 --- a/src/gromacs/mdlib/qm_gamess.cpp +++ b/src/gromacs/mdlib/qm_gamess.cpp @@ -67,12 +67,16 @@ /* mopac interface routines */ -static void - F77_FUNC(inigms, IMIGMS) (); +static void F77_FUNC(inigms, IMIGMS)(); -static void - F77_FUNC(grads, GRADS) (const int *nrqmat, real *qmcrd, const int *nrmmat, const real *mmchrg, - real *mmcrd, real *qmgrad, real *mmgrad, real *energy); +static void F77_FUNC(grads, GRADS)(const int* nrqmat, + real* qmcrd, + const int* nrmmat, + const real* mmchrg, + real* mmcrd, + real* qmgrad, + real* mmgrad, + real* energy); #if !GMX_QMMM_GAMESS // Stub definitions to make compilation succeed when not configured @@ -81,18 +85,12 @@ static void // issue fatal errors here, because that introduces problems with // tools suggesting and prohibiting noreturn attributes. -void F77_FUNC(inigms, IMIGMS) () -{ -}; +void F77_FUNC(inigms, IMIGMS)(){}; // NOLINTNEXTLINE(readability-named-parameter) -void F77_FUNC(grads, GRADS) (const int *, real *, const int *, - const real *, real *, real *, - real *, real *) -{ -}; +void F77_FUNC(grads, GRADS)(const int*, real*, const int*, const real*, real*, real*, real*, real*){}; #endif -void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm) +void init_gamess(const t_commrec* cr, t_QMrec* qm, t_MMrec* mm) { /* it works hopelessly complicated :-) * first a file is written. Then the standard gamess input/output @@ -102,21 +100,17 @@ void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm) * and energy evaluations are called. This setup works fine for * dynamics simulations. 7-6-2002 (London) */ - int - i, j; - FILE - *out; - char - periodic_system[37][3] = { - "XX", "H ", "He", "Li", "Be", "B ", "C ", "N ", - "O ", "F ", "Ne", "Na", "Mg", "Al", "Si", "P ", - "S ", "Cl", "Ar", "K ", "Ca", "Sc", "Ti", "V ", - "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", - "Ge", "As", "Se", "Br", "Kr" - }; + int i, j; + FILE* out; + char periodic_system[37][3] = { "XX", "H ", "He", "Li", "Be", "B ", "C ", "N ", "O ", "F ", + "Ne", "Na", "Mg", "Al", "Si", "P ", "S ", "Cl", "Ar", "K ", + "Ca", "Sc", "Ti", "V ", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", + "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr" }; if (!GMX_QMMM_GAMESS) { - gmx_fatal(FARGS, "Cannot call GAMESS unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=GAMESS, and ensure that linking will work correctly."); + gmx_fatal(FARGS, + "Cannot call GAMESS unless linked against it. Use cmake " + "-DGMX_QMMM_PROGRAM=GAMESS, and ensure that linking will work correctly."); } if (PAR(cr)) @@ -129,52 +123,35 @@ void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm) * preformance on more than 4 cpu's is rather poor at the moment. */ fprintf(out, "memory 48000000\nPARALLEL IOMODE SCREENED\n"); - fprintf(out, "ELEC %d\nMULT %d\nSUPER ON\nNOSYM\nGEOMETRY ANGSTROM\n", - qm->nelectrons, qm->multiplicity); + fprintf(out, "ELEC %d\nMULT %d\nSUPER ON\nNOSYM\nGEOMETRY ANGSTROM\n", qm->nelectrons, + qm->multiplicity); for (i = 0; i < qm->nrQMatoms; i++) { #ifdef DOUBLE - fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf %2s\n", - i/2., - i/3., - i/4., - qm->atomicnumberQM[i]*1.0, - periodic_system[qm->atomicnumberQM[i]]); + fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf %2s\n", i / 2., i / 3., i / 4., + qm->atomicnumberQM[i] * 1.0, periodic_system[qm->atomicnumberQM[i]]); #else - fprintf(out, "%10.7f %10.7f %10.7f %5.3f %2s\n", - i/2., - i/3., - i/4., - qm->atomicnumberQM[i]*1.0, - periodic_system[qm->atomicnumberQM[i]]); + fprintf(out, "%10.7f %10.7f %10.7f %5.3f %2s\n", i / 2., i / 3., i / 4., + qm->atomicnumberQM[i] * 1.0, periodic_system[qm->atomicnumberQM[i]]); #endif } if (mm->nrMMatoms) { - for (j = i; j < i+2; j++) + for (j = i; j < i + 2; j++) { #ifdef DOUBLE - fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf BQ\n", - j/5., - j/6., - j/7., - 1.0); + fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf BQ\n", j / 5., j / 6., j / 7., 1.0); #else - fprintf(out, "%10.7f %10.7f %10.7f %5.3f BQ\n", - j/5., - j/6., - j/7., - 2.0); + fprintf(out, "%10.7f %10.7f %10.7f %5.3f BQ\n", j / 5., j / 6., j / 7., 2.0); #endif } } fprintf(out, "END\nBASIS %s\nRUNTYPE GRADIENT\nSCFTYPE %s\n", - eQMbasis_names[qm->QMbasis], - eQMmethod_names[qm->QMmethod]); /* see enum.h */ + eQMbasis_names[qm->QMbasis], eQMmethod_names[qm->QMmethod]); /* see enum.h */ fclose(out); } gmx_barrier(cr); - F77_FUNC(inigms, IMIGMS) (); + F77_FUNC(inigms, IMIGMS)(); } else /* normal serial run */ @@ -183,69 +160,49 @@ void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm) /* of these options I am not completely sure.... the overall * preformance on more than 4 cpu's is rather poor at the moment. */ - fprintf(out, "ELEC %d\nMULT %d\nSUPER ON\nNOSYM\nGEOMETRY ANGSTROM\n", - qm->nelectrons, qm->multiplicity); + fprintf(out, "ELEC %d\nMULT %d\nSUPER ON\nNOSYM\nGEOMETRY ANGSTROM\n", qm->nelectrons, + qm->multiplicity); for (i = 0; i < qm->nrQMatoms; i++) { #ifdef DOUBLE - fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf %2s\n", - i/2., - i/3., - i/4., - qm->atomicnumberQM[i]*1.0, - periodic_system[qm->atomicnumberQM[i]]); + fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf %2s\n", i / 2., i / 3., i / 4., + qm->atomicnumberQM[i] * 1.0, periodic_system[qm->atomicnumberQM[i]]); #else - fprintf(out, "%10.7f %10.7f %10.7f %5.3f %2s\n", - i/2., - i/3., - i/4., - qm->atomicnumberQM[i]*1.0, - periodic_system[qm->atomicnumberQM[i]]); + fprintf(out, "%10.7f %10.7f %10.7f %5.3f %2s\n", i / 2., i / 3., i / 4., + qm->atomicnumberQM[i] * 1.0, periodic_system[qm->atomicnumberQM[i]]); #endif } if (mm->nrMMatoms) { - for (j = i; j < i+2; j++) + for (j = i; j < i + 2; j++) { #ifdef DOUBLE - fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf BQ\n", - j/5., - j/6., - j/7., - 1.0); + fprintf(out, "%10.7lf %10.7lf %10.7lf %5.3lf BQ\n", j / 5., j / 6., j / 7., 1.0); #else - fprintf(out, "%10.7f %10.7f %10.7f %5.3f BQ\n", - j/5., - j/6., - j/7., - 2.0); + fprintf(out, "%10.7f %10.7f %10.7f %5.3f BQ\n", j / 5., j / 6., j / 7., 2.0); #endif } } - fprintf(out, "END\nBASIS %s\nRUNTYPE GRADIENT\nSCFTYPE %s\n", - eQMbasis_names[qm->QMbasis], + fprintf(out, "END\nBASIS %s\nRUNTYPE GRADIENT\nSCFTYPE %s\n", eQMbasis_names[qm->QMbasis], eQMmethod_names[qm->QMmethod]); /* see enum.h */ - F77_FUNC(inigms, IMIGMS) (); + F77_FUNC(inigms, IMIGMS)(); } } -real call_gamess(const t_QMrec *qm, const t_MMrec *mm, - rvec f[], rvec fshift[]) +real call_gamess(const t_QMrec* qm, const t_MMrec* mm, rvec f[], rvec fshift[]) { /* do the actual QMMM calculation using GAMESS-UK. In this * implementation (3-2001) a system call is made to the GAMESS-UK * binary. Now we are working to get the electron integral, SCF, and * gradient routines linked directly */ - int - i, j; - real - QMener = 0.0, *qmgrad, *mmgrad, *mmcrd, *qmcrd, energy = 0; + int i, j; + real QMener = 0.0, *qmgrad, *mmgrad, *mmcrd, *qmcrd, energy = 0; - snew(qmcrd, 3*(qm->nrQMatoms)); - snew(mmcrd, 3*(mm->nrMMatoms)); - snew(qmgrad, 3*(qm->nrQMatoms)); - snew(mmgrad, 3*(mm->nrMMatoms)); + snew(qmcrd, 3 * (qm->nrQMatoms)); + snew(mmcrd, 3 * (mm->nrMMatoms)); + snew(qmgrad, 3 * (qm->nrQMatoms)); + snew(mmgrad, 3 * (mm->nrMMatoms)); /* copy the data from qr into the arrays that are going to be used * in the fortran routines of gamess @@ -254,46 +211,43 @@ real call_gamess(const t_QMrec *qm, const t_MMrec *mm, { for (j = 0; j < DIM; j++) { - qmcrd[DIM*i+j] = 1/BOHR2NM*qm->xQM[i][j]; + qmcrd[DIM * i + j] = 1 / BOHR2NM * qm->xQM[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - mmcrd[DIM*i+j] = 1/BOHR2NM*mm->xMM[i][j]; + mmcrd[DIM * i + j] = 1 / BOHR2NM * mm->xMM[i][j]; } } - for (i = 0; i < 3*qm->nrQMatoms; i += 3) + for (i = 0; i < 3 * qm->nrQMatoms; i += 3) { - fprintf(stderr, "%8.5f, %8.5f, %8.5f\n", - qmcrd[i], - qmcrd[i+1], - qmcrd[i+2]); + fprintf(stderr, "%8.5f, %8.5f, %8.5f\n", qmcrd[i], qmcrd[i + 1], qmcrd[i + 2]); } - F77_FUNC(grads, GRADS) (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, mm->MMcharges, - mmcrd, qmgrad, mmgrad, &energy); + F77_FUNC(grads, GRADS) + (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, mm->MMcharges, mmcrd, qmgrad, mmgrad, &energy); for (i = 0; i < qm->nrQMatoms; i++) { for (j = 0; j < DIM; j++) { - f[i][j] = HARTREE_BOHR2MD*qmgrad[3*i+j]; - fshift[i][j] = HARTREE_BOHR2MD*qmgrad[3*i+j]; + f[i][j] = HARTREE_BOHR2MD * qmgrad[3 * i + j]; + fshift[i][j] = HARTREE_BOHR2MD * qmgrad[3 * i + j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - f[i][j] = HARTREE_BOHR2MD*mmgrad[3*i+j]; - fshift[i][j] = HARTREE_BOHR2MD*mmgrad[3*i+j]; + f[i][j] = HARTREE_BOHR2MD * mmgrad[3 * i + j]; + fshift[i][j] = HARTREE_BOHR2MD * mmgrad[3 * i + j]; } } /* convert a.u to kJ/mol */ - QMener = energy*HARTREE2KJ*AVOGADRO; - return(QMener); + QMener = energy * HARTREE2KJ * AVOGADRO; + return (QMener); } #pragma GCC diagnostic pop diff --git a/src/gromacs/mdlib/qm_gamess.h b/src/gromacs/mdlib/qm_gamess.h index 417f4d6437..81c2b4c40e 100644 --- a/src/gromacs/mdlib/qm_gamess.h +++ b/src/gromacs/mdlib/qm_gamess.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,7 +44,7 @@ * \param[in] qm QM forcerec. * \param[in] mm MM part of forcerec. */ -void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm); +void init_gamess(const t_commrec* cr, t_QMrec* qm, t_MMrec* mm); /*! \brief * Run calculation with Gamess. @@ -54,8 +54,7 @@ void init_gamess(const t_commrec *cr, t_QMrec *qm, t_MMrec *mm); * \param[in] f Force vector. * \param[in] fshift Force shift vector. */ -real call_gamess(const t_QMrec *qm, const t_MMrec *mm, - rvec f[], rvec fshift[]); +real call_gamess(const t_QMrec* qm, const t_MMrec* mm, rvec f[], rvec fshift[]); #endif diff --git a/src/gromacs/mdlib/qm_gaussian.cpp b/src/gromacs/mdlib/qm_gaussian.cpp index 959769b081..b9885bfff3 100644 --- a/src/gromacs/mdlib/qm_gaussian.cpp +++ b/src/gromacs/mdlib/qm_gaussian.cpp @@ -68,27 +68,19 @@ /* Gaussian interface routines */ -void init_gaussian(t_QMrec *qm) +void init_gaussian(t_QMrec* qm) { - ivec - basissets[eQMbasisNR] = {{0, 3, 0}, - {0, 3, 0}, /*added for double sto-3g entry in names.c*/ - {5, 0, 0}, - {5, 0, 1}, - {5, 0, 11}, - {5, 6, 0}, - {1, 6, 0}, - {1, 6, 1}, - {1, 6, 11}, - {4, 6, 0}}; - char - *buf = nullptr; - int - i; + ivec basissets[eQMbasisNR] = { { 0, 3, 0 }, { 0, 3, 0 }, /*added for double sto-3g entry in names.c*/ + { 5, 0, 0 }, { 5, 0, 1 }, { 5, 0, 11 }, { 5, 6, 0 }, + { 1, 6, 0 }, { 1, 6, 1 }, { 1, 6, 11 }, { 4, 6, 0 } }; + char* buf = nullptr; + int i; if (!GMX_QMMM_GAUSSIAN) { - gmx_fatal(FARGS, "Cannot call GAUSSIAN unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=GAUSSIAN, and ensure that linking will work correctly."); + gmx_fatal(FARGS, + "Cannot call GAUSSIAN unless linked against it. Use cmake " + "-DGMX_QMMM_PROGRAM=GAUSSIAN, and ensure that linking will work correctly."); } /* using the ivec above to convert the basis read form the mdp file @@ -205,11 +197,12 @@ void init_gaussian(t_QMrec *qm) buf = getenv("GMX_QM_MODIFIED_LINKS_DIR"); if (buf) { - qm->devel_dir = gmx_strdup (buf); + qm->devel_dir = gmx_strdup(buf); } else { - gmx_fatal(FARGS, "no $GMX_QM_MODIFIED_LINKS_DIR, this is were the modified links reside.\n"); + gmx_fatal(FARGS, + "no $GMX_QM_MODIFIED_LINKS_DIR, this is were the modified links reside.\n"); } /* if(fr->bRF){*/ @@ -223,17 +216,12 @@ void init_gaussian(t_QMrec *qm) } -static void write_gaussian_SH_input(int step, gmx_bool swap, - const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) +static void write_gaussian_SH_input(int step, gmx_bool swap, const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm) { - int - i; - gmx_bool - bSA; - FILE - *out; - t_QMMMrec - *QMMMrec; + int i; + gmx_bool bSA; + FILE* out; + t_QMMMrec* QMMMrec; QMMMrec = fr->qr; bSA = (qm->SAstep > 0); @@ -243,9 +231,9 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, fprintf(out, "%s", "%rwf=input\n"); fprintf(out, "%s", "%int=input\n"); fprintf(out, "%s", "%d2e=input\n"); -/* if(step) - * fprintf(out,"%s","%nosave\n"); - */ + /* if(step) + * fprintf(out,"%s","%nosave\n"); + */ fprintf(out, "%s", "%chk=input\n"); fprintf(out, "%s%d\n", "%mem=", qm->QMmem); fprintf(out, "%s%3d\n", "%nprocshare=", qm->nQMcpus); @@ -257,65 +245,40 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, */ /* local version */ - fprintf(out, "%s%s%s", - "%subst l510 ", - qm->devel_dir, - "/l510\n"); - fprintf(out, "%s%s%s", - "%subst l301 ", - qm->devel_dir, - "/l301\n"); - fprintf(out, "%s%s%s", - "%subst l701 ", - qm->devel_dir, - "/l701\n"); - - fprintf(out, "%s%s%s", - "%subst l1003 ", - qm->devel_dir, - "/l1003\n"); - fprintf(out, "%s%s%s", - "%subst l9999 ", - qm->devel_dir, - "/l9999\n"); + fprintf(out, "%s%s%s", "%subst l510 ", qm->devel_dir, "/l510\n"); + fprintf(out, "%s%s%s", "%subst l301 ", qm->devel_dir, "/l301\n"); + fprintf(out, "%s%s%s", "%subst l701 ", qm->devel_dir, "/l701\n"); + + fprintf(out, "%s%s%s", "%subst l1003 ", qm->devel_dir, "/l1003\n"); + fprintf(out, "%s%s%s", "%subst l9999 ", qm->devel_dir, "/l9999\n"); /* print the nonstandard route */ - fprintf(out, "%s", - "#P nonstd\n 1/18=10,20=1,38=1/1;\n"); - fprintf(out, "%s", - " 2/9=110,15=1,17=6,18=5,40=1/2;\n"); + fprintf(out, "%s", "#P nonstd\n 1/18=10,20=1,38=1/1;\n"); + fprintf(out, "%s", " 2/9=110,15=1,17=6,18=5,40=1/2;\n"); if (mm->nrMMatoms) { - fprintf(out, - " 3/5=%d,6=%d,7=%d,25=1,32=1,43=1,94=-2/1,2,3;\n", - qm->SHbasis[0], - qm->SHbasis[1], - qm->SHbasis[2]); /*basisset stuff */ + fprintf(out, " 3/5=%d,6=%d,7=%d,25=1,32=1,43=1,94=-2/1,2,3;\n", qm->SHbasis[0], + qm->SHbasis[1], qm->SHbasis[2]); /*basisset stuff */ } else { - fprintf(out, - " 3/5=%d,6=%d,7=%d,25=1,32=1,43=0,94=-2/1,2,3;\n", - qm->SHbasis[0], - qm->SHbasis[1], - qm->SHbasis[2]); /*basisset stuff */ + fprintf(out, " 3/5=%d,6=%d,7=%d,25=1,32=1,43=0,94=-2/1,2,3;\n", qm->SHbasis[0], + qm->SHbasis[1], qm->SHbasis[2]); /*basisset stuff */ } /* development */ - if (step+1) /* fetch initial guess from check point file */ - { /* hack, to alyays read from chk file!!!!! */ - fprintf(out, "%s%d,%s%d%s", " 4/5=1,7=6,17=", - qm->CASelectrons, - "18=", qm->CASorbitals, "/1,5;\n"); + if (step + 1) /* fetch initial guess from check point file */ + { /* hack, to alyays read from chk file!!!!! */ + fprintf(out, "%s%d,%s%d%s", " 4/5=1,7=6,17=", qm->CASelectrons, "18=", qm->CASorbitals, + "/1,5;\n"); } else /* generate the first checkpoint file */ { - fprintf(out, "%s%d,%s%d%s", " 4/5=0,7=6,17=", - qm->CASelectrons, - "18=", qm->CASorbitals, "/1,5;\n"); + fprintf(out, "%s%d,%s%d%s", " 4/5=0,7=6,17=", qm->CASelectrons, "18=", qm->CASorbitals, + "/1,5;\n"); } /* the rest of the input depends on where the system is on the PES */ - if (swap && bSA) /* make a slide to the other surface */ + if (swap && bSA) /* make a slide to the other surface */ { if (qm->CASorbitals > 6) /* use direct and no full diag */ { @@ -325,8 +288,7 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, { if (qm->cpmcscf) { - fprintf(out, " 5/5=2,6=%d,17=31000200,28=2,32=2,38=6,97=100/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=31000200,28=2,32=2,38=6,97=100/10;\n", qm->accuracy); if (mm->nrMMatoms > 0) { fprintf(out, " 7/7=1,16=-2,30=1/1;\n"); @@ -337,13 +299,12 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, } else { - fprintf(out, " 5/5=2,6=%d,17=11000000,28=2,32=2,38=6,97=100/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=11000000,28=2,32=2,38=6,97=100/10;\n", qm->accuracy); fprintf(out, " 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n"); } } } - else if (bSA) /* do a "state-averaged" CAS calculation */ + else if (bSA) /* do a "state-averaged" CAS calculation */ { if (qm->CASorbitals > 6) /* no full diag */ { @@ -353,8 +314,7 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, { if (qm->cpmcscf) { - fprintf(out, " 5/5=2,6=%d,17=31000200,28=2,32=2,38=6/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=31000200,28=2,32=2,38=6/10;\n", qm->accuracy); if (mm->nrMMatoms > 0) { fprintf(out, " 7/7=1,16=-2,30=1/1;\n"); @@ -365,8 +325,7 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, } else { - fprintf(out, " 5/5=2,6=%d,17=11000000,28=2,32=2,38=6/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=11000000,28=2,32=2,38=6/10;\n", qm->accuracy); fprintf(out, " 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n"); } } @@ -379,8 +338,7 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, } else { - fprintf(out, " 5/5=2,6=%d,17=1000000,28=2,32=2,38=6,97=100/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=1000000,28=2,32=2,38=6,97=100/10;\n", qm->accuracy); } fprintf(out, " 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n"); } @@ -392,8 +350,7 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, } else { - fprintf(out, " 5/5=2,6=%d,17=1000000,28=2,32=2,38=6/10;\n", - qm->accuracy); + fprintf(out, " 5/5=2,6=%d,17=1000000,28=2,32=2,38=6/10;\n", qm->accuracy); } fprintf(out, " 7/7=1,16=-2,30=1/1,2,3,16;\n 99/10=4/99;\n"); } @@ -401,11 +358,8 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, fprintf(out, "%2d%2d\n", qm->QMcharge, qm->multiplicity); for (i = 0; i < qm->nrQMatoms; i++) { - fprintf(out, "%3d %10.7f %10.7f %10.7f\n", - qm->atomicnumberQM[i], - qm->xQM[i][XX]/BOHR2NM, - qm->xQM[i][YY]/BOHR2NM, - qm->xQM[i][ZZ]/BOHR2NM); + fprintf(out, "%3d %10.7f %10.7f %10.7f\n", qm->atomicnumberQM[i], + qm->xQM[i][XX] / BOHR2NM, qm->xQM[i][YY] / BOHR2NM, qm->xQM[i][ZZ] / BOHR2NM); } /* MM point charge data */ if (QMMMrec->QMMMscheme != eQMMMschemeoniom && mm->nrMMatoms) @@ -413,32 +367,24 @@ static void write_gaussian_SH_input(int step, gmx_bool swap, fprintf(out, "\n"); for (i = 0; i < mm->nrMMatoms; i++) { - fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n", - mm->xMM[i][XX]/BOHR2NM, - mm->xMM[i][YY]/BOHR2NM, - mm->xMM[i][ZZ]/BOHR2NM, - mm->MMcharges[i]); + fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n", mm->xMM[i][XX] / BOHR2NM, + mm->xMM[i][YY] / BOHR2NM, mm->xMM[i][ZZ] / BOHR2NM, mm->MMcharges[i]); } } if (bSA) /* put the SA coefficients at the end of the file */ { - fprintf(out, "\n%10.8f %10.8f\n", - qm->SAstep*0.5/qm->SAsteps, - 1-qm->SAstep*0.5/qm->SAsteps); + fprintf(out, "\n%10.8f %10.8f\n", qm->SAstep * 0.5 / qm->SAsteps, 1 - qm->SAstep * 0.5 / qm->SAsteps); fprintf(stderr, "State Averaging level = %d/%d\n", qm->SAstep, qm->SAsteps); } fprintf(out, "\n"); fclose(out); -} /* write_gaussian_SH_input */ +} /* write_gaussian_SH_input */ -static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) +static void write_gaussian_input(int step, const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm) { - int - i; - t_QMMMrec - *QMMMrec; - FILE - *out; + int i; + t_QMMMrec* QMMMrec; + FILE* out; QMMMrec = fr->qr; out = fopen("input.com", "w"); @@ -446,46 +392,35 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ if (qm->QMmethod >= eQMmethodRHF) { - fprintf(out, "%s", - "%chk=input\n"); + fprintf(out, "%s", "%chk=input\n"); } else { - fprintf(out, "%s", - "%chk=se\n"); + fprintf(out, "%s", "%chk=se\n"); } if (qm->nQMcpus > 1) { - fprintf(out, "%s%3d\n", - "%nprocshare=", qm->nQMcpus); + fprintf(out, "%s%3d\n", "%nprocshare=", qm->nQMcpus); } - fprintf(out, "%s%d\n", - "%mem=", qm->QMmem); - fprintf(out, "%s%s%s", - "%subst l701 ", qm->devel_dir, "/l701\n"); - fprintf(out, "%s%s%s", - "%subst l301 ", qm->devel_dir, "/l301\n"); - fprintf(out, "%s%s%s", - "%subst l9999 ", qm->devel_dir, "/l9999\n"); + fprintf(out, "%s%d\n", "%mem=", qm->QMmem); + fprintf(out, "%s%s%s", "%subst l701 ", qm->devel_dir, "/l701\n"); + fprintf(out, "%s%s%s", "%subst l301 ", qm->devel_dir, "/l301\n"); + fprintf(out, "%s%s%s", "%subst l9999 ", qm->devel_dir, "/l9999\n"); if (step) { - fprintf(out, "%s", - "#T "); + fprintf(out, "%s", "#T "); } else { - fprintf(out, "%s", - "#P "); + fprintf(out, "%s", "#P "); } if (qm->QMmethod == eQMmethodB3LYPLAN) { - fprintf(out, " %s", - "B3LYP/GEN Pseudo=Read"); + fprintf(out, " %s", "B3LYP/GEN Pseudo=Read"); } else { - fprintf(out, " %s", - eQMmethod_names[qm->QMmethod]); + fprintf(out, " %s", eQMmethod_names[qm->QMmethod]); if (qm->QMmethod >= eQMmethodRHF) { @@ -493,17 +428,14 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ { /* in case of cas, how many electrons and orbitals do we need? */ - fprintf(out, "(%d,%d)", - qm->CASelectrons, qm->CASorbitals); + fprintf(out, "(%d,%d)", qm->CASelectrons, qm->CASorbitals); } - fprintf(out, "/%s", - eQMbasis_names[qm->QMbasis]); + fprintf(out, "/%s", eQMbasis_names[qm->QMbasis]); } } if (QMMMrec->QMMMscheme == eQMMMschemenormal && mm->nrMMatoms) { - fprintf(out, " %s", - "Charge "); + fprintf(out, " %s", "Charge "); } if (step || qm->QMmethod == eQMmethodCASSCF) { @@ -518,11 +450,8 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ fprintf(out, "%2d%2d\n", qm->QMcharge, qm->multiplicity); for (i = 0; i < qm->nrQMatoms; i++) { - fprintf(out, "%3d %10.7f %10.7f %10.7f\n", - qm->atomicnumberQM[i], - qm->xQM[i][XX]/BOHR2NM, - qm->xQM[i][YY]/BOHR2NM, - qm->xQM[i][ZZ]/BOHR2NM); + fprintf(out, "%3d %10.7f %10.7f %10.7f\n", qm->atomicnumberQM[i], + qm->xQM[i][XX] / BOHR2NM, qm->xQM[i][YY] / BOHR2NM, qm->xQM[i][ZZ] / BOHR2NM); } /* Pseudo Potential and ECP are included here if selected (MEthod suffix LAN) */ @@ -533,7 +462,7 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ { if (qm->atomicnumberQM[i] < 21) { - fprintf(out, "%d ", i+1); + fprintf(out, "%d ", i + 1); } } fprintf(out, "\n%s\n****\n", eQMbasis_names[qm->QMbasis]); @@ -542,7 +471,7 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ { if (qm->atomicnumberQM[i] > 21) { - fprintf(out, "%d ", i+1); + fprintf(out, "%d ", i + 1); } } fprintf(out, "\n%s\n****\n\n", "lanl2dz"); @@ -551,14 +480,13 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ { if (qm->atomicnumberQM[i] > 21) { - fprintf(out, "%d ", i+1); + fprintf(out, "%d ", i + 1); } } fprintf(out, "\n%s\n", "lanl2dz"); } - /* MM point charge data */ if (QMMMrec->QMMMscheme != eQMMMschemeoniom && mm->nrMMatoms) { @@ -566,11 +494,8 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ fprintf(out, "\n"); for (i = 0; i < mm->nrMMatoms; i++) { - fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n", - mm->xMM[i][XX]/BOHR2NM, - mm->xMM[i][YY]/BOHR2NM, - mm->xMM[i][ZZ]/BOHR2NM, - mm->MMcharges[i]); + fprintf(out, "%10.7f %10.7f %10.7f %8.4f\n", mm->xMM[i][XX] / BOHR2NM, + mm->xMM[i][YY] / BOHR2NM, mm->xMM[i][ZZ] / BOHR2NM, mm->MMcharges[i]); } } fprintf(out, "\n"); @@ -578,18 +503,14 @@ static void write_gaussian_input(int step, const t_forcerec *fr, t_QMrec *qm, t_ fclose(out); -} /* write_gaussian_input */ +} /* write_gaussian_input */ -static real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], t_QMrec *qm, t_MMrec *mm) +static real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], t_QMrec* qm, t_MMrec* mm) { - int - i; - char - buf[300]; - real - QMener; - FILE - *in; + int i; + char buf[300]; + real QMener; + FILE* in; in = fopen("fort.7", "r"); @@ -618,15 +539,9 @@ static real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], t_QMrec *qm, t_MM gmx_fatal(FARGS, "Error reading Gaussian output"); } #if GMX_DOUBLE - sscanf(buf, "%lf %lf %lf\n", - &QMgrad[i][XX], - &QMgrad[i][YY], - &QMgrad[i][ZZ]); + sscanf(buf, "%lf %lf %lf\n", &QMgrad[i][XX], &QMgrad[i][YY], &QMgrad[i][ZZ]); #else - sscanf(buf, "%f %f %f\n", - &QMgrad[i][XX], - &QMgrad[i][YY], - &QMgrad[i][ZZ]); + sscanf(buf, "%f %f %f\n", &QMgrad[i][XX], &QMgrad[i][YY], &QMgrad[i][ZZ]); #endif } /* the next lines are the gradients of the MM atoms */ @@ -639,32 +554,22 @@ static real read_gaussian_output(rvec QMgrad[], rvec MMgrad[], t_QMrec *qm, t_MM gmx_fatal(FARGS, "Error reading Gaussian output"); } #if GMX_DOUBLE - sscanf(buf, "%lf %lf %lf\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); + sscanf(buf, "%lf %lf %lf\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); #else - sscanf(buf, "%f %f %f\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); + sscanf(buf, "%f %f %f\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); #endif } } fclose(in); - return(QMener); + return (QMener); } -static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QMrec *qm, t_MMrec *mm) +static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QMrec* qm, t_MMrec* mm) { - int - i; - char - buf[300]; - real - QMener, DeltaE; - FILE - *in; + int i; + char buf[300]; + real QMener, DeltaE; + FILE* in; in = fopen("fort.7", "r"); /* first line is the energy and in the case of CAS, the energy @@ -678,7 +583,7 @@ static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QM #if GMX_DOUBLE sscanf(buf, "%lf %lf\n", &QMener, &DeltaE); #else - sscanf(buf, "%f %f\n", &QMener, &DeltaE); + sscanf(buf, "%f %f\n", &QMener, &DeltaE); #endif /* switch on/off the State Averaging */ @@ -709,15 +614,9 @@ static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QM } #if GMX_DOUBLE - sscanf(buf, "%lf %lf %lf\n", - &QMgrad[i][XX], - &QMgrad[i][YY], - &QMgrad[i][ZZ]); + sscanf(buf, "%lf %lf %lf\n", &QMgrad[i][XX], &QMgrad[i][YY], &QMgrad[i][ZZ]); #else - sscanf(buf, "%f %f %f\n", - &QMgrad[i][XX], - &QMgrad[i][YY], - &QMgrad[i][ZZ]); + sscanf(buf, "%f %f %f\n", &QMgrad[i][XX], &QMgrad[i][YY], &QMgrad[i][ZZ]); #endif } /* the next lines, are the gradients of the MM atoms */ @@ -729,15 +628,9 @@ static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QM gmx_fatal(FARGS, "Error reading Gaussian output"); } #if GMX_DOUBLE - sscanf(buf, "%lf %lf %lf\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); + sscanf(buf, "%lf %lf %lf\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); #else - sscanf(buf, "%f %f %f\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); + sscanf(buf, "%f %f %f\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); #endif } @@ -792,32 +685,28 @@ static real read_gaussian_SH_output(rvec QMgrad[], rvec MMgrad[], int step, t_QM #endif } fclose(in); - return(QMener); + return (QMener); } -static real inproduct(const real *a, const real *b, int n) +static real inproduct(const real* a, const real* b, int n) { - int - i; - real - dot = 0.0; + int i; + real dot = 0.0; /* computes the inner product between two vectors (a.b), both of * which have length n. */ for (i = 0; i < n; i++) { - dot += a[i]*b[i]; + dot += a[i] * b[i]; } - return(dot); + return (dot); } -static int hop(int step, t_QMrec *qm) +static int hop(int step, t_QMrec* qm) { - int - swap = 0; - real - d11 = 0.0, d12 = 0.0, d21 = 0.0, d22 = 0.0; + int swap = 0; + real d11 = 0.0, d12 = 0.0, d21 = 0.0, d22 = 0.0; /* calculates the inproduct between the current Ci vector and the * previous CI vector. A diabatic hop will be made if d12 and d21 @@ -843,13 +732,12 @@ static int hop(int step, t_QMrec *qm) swap = 1; } - return(swap); + return (swap); } -static void do_gaussian(int step, char *exe) +static void do_gaussian(int step, char* exe) { - char - buf[STRLEN]; + char buf[STRLEN]; /* make the call to the gaussian binary through system() * The location of the binary will be picked up from the @@ -857,17 +745,11 @@ static void do_gaussian(int step, char *exe) */ if (step) /* hack to prevent long inputfiles */ { - sprintf(buf, "%s < %s > %s", - exe, - "input.com", - "input.log"); + sprintf(buf, "%s < %s > %s", exe, "input.com", "input.log"); } else { - sprintf(buf, "%s < %s > %s", - exe, - "input.com", - "input.log"); + sprintf(buf, "%s < %s > %s", exe, "input.com", "input.log"); } fprintf(stderr, "Calling '%s'\n", buf); if (system(buf) != 0) @@ -876,19 +758,14 @@ static void do_gaussian(int step, char *exe) } } -real call_gaussian(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) +real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]) { /* normal gaussian jobs */ - static int - step = 0; - int - i, j; - real - QMener = 0.0; - rvec - *QMgrad, *MMgrad; - char - *exe; + static int step = 0; + int i, j; + real QMener = 0.0; + rvec * QMgrad, *MMgrad; + char* exe; snew(exe, 30); sprintf(exe, "%s/%s", qm->gauss_dir, qm->gauss_exe); @@ -904,47 +781,39 @@ real call_gaussian(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rve { for (j = 0; j < DIM; j++) { - f[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; - fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; + f[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; + fshift[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - f[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; - fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; + f[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; + fshift[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; } } - QMener = QMener*HARTREE2KJ*AVOGADRO; + QMener = QMener * HARTREE2KJ * AVOGADRO; step++; free(exe); - return(QMener); + return (QMener); } /* call_gaussian */ -real call_gaussian_SH(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) +real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]) { /* a gaussian call routine intended for doing diabatic surface * "sliding". See the manual for the theoretical background of this * TSH method. */ - static int - step = 0; - int - state, i, j; - real - QMener = 0.0; - static gmx_bool - swapped = FALSE; /* handle for identifying the current PES */ - gmx_bool - swap = FALSE; /* the actual swap */ - rvec - *QMgrad, *MMgrad; - char - *buf; - char - *exe; + static int step = 0; + int state, i, j; + real QMener = 0.0; + static gmx_bool swapped = FALSE; /* handle for identifying the current PES */ + gmx_bool swap = FALSE; /* the actual swap */ + rvec * QMgrad, *MMgrad; + char* buf; + char* exe; snew(exe, 30); sprintf(exe, "%s/%s", qm->gauss_dir, qm->gauss_exe); @@ -996,7 +865,7 @@ real call_gaussian_SH(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], swap = ((step != 0) && (hop(step, qm) != 0)); swapped = !swap; /* so swapped shoud be false again */ } - if (swap) /* change surface, so do another call */ + if (swap) /* change surface, so do another call */ { write_gaussian_SH_input(step, swapped, fr, qm, mm); do_gaussian(step, exe); @@ -1009,24 +878,24 @@ real call_gaussian_SH(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], { for (j = 0; j < DIM; j++) { - f[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; - fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; + f[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; + fshift[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - f[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; - fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; + f[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; + fshift[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; } } - QMener = QMener*HARTREE2KJ*AVOGADRO; - fprintf(stderr, "step %5d, SA = %5d, swap = %5d\n", - step, static_cast(qm->SAstep > 0), static_cast(swapped)); + QMener = QMener * HARTREE2KJ * AVOGADRO; + fprintf(stderr, "step %5d, SA = %5d, swap = %5d\n", step, static_cast(qm->SAstep > 0), + static_cast(swapped)); step++; free(exe); - return(QMener); + return (QMener); } /* call_gaussian_SH */ diff --git a/src/gromacs/mdlib/qm_gaussian.h b/src/gromacs/mdlib/qm_gaussian.h index 108187f7d6..1933fc7893 100644 --- a/src/gromacs/mdlib/qm_gaussian.h +++ b/src/gromacs/mdlib/qm_gaussian.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,7 @@ struct t_forcerec; * * \param[in] qm QM forcerec. */ -void init_gaussian(t_QMrec *qm); +void init_gaussian(t_QMrec* qm); /*! \brief * Call gaussian to do qm calculation. @@ -56,7 +56,7 @@ void init_gaussian(t_QMrec *qm); * \param[in] f force vector. * \param[in] fshift shift of force vector. */ -real call_gaussian(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]); +real call_gaussian(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]); /*! \brief * Call gaussian SH(?) to do qm calculation. @@ -67,6 +67,6 @@ real call_gaussian(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rve * \param[in] f force vector. * \param[in] fshift shift of force vector. */ -real call_gaussian_SH(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]); +real call_gaussian_SH(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]); #endif diff --git a/src/gromacs/mdlib/qm_mopac.cpp b/src/gromacs/mdlib/qm_mopac.cpp index e1ae3c3d7a..1b1d9292e5 100644 --- a/src/gromacs/mdlib/qm_mopac.cpp +++ b/src/gromacs/mdlib/qm_mopac.cpp @@ -64,13 +64,17 @@ #if GMX_QMMM_MOPAC /* mopac interface routines */ -void - F77_FUNC(domldt, DOMLDT) (int *nrqmat, int labels[], char keywords[]); +void F77_FUNC(domldt, DOMLDT)(int* nrqmat, int labels[], char keywords[]); -void - F77_FUNC(domop, DOMOP) (int *nrqmat, double qmcrd[], int *nrmmat, - double mmchrg[], double mmcrd[], double qmgrad[], - double mmgrad[], double *energy, double qmcharges[]); +void F77_FUNC(domop, DOMOP)(int* nrqmat, + double qmcrd[], + int* nrmmat, + double mmchrg[], + double mmcrd[], + double qmgrad[], + double mmgrad[], + double* energy, + double qmcharges[]); #else /* GMX_QMMM_MOPAC */ // Stub definitions to make compilation succeed when not configured @@ -79,20 +83,24 @@ void // issue fatal errors here, because that introduces problems with // tools suggesting and prohibiting noreturn attributes. -static void F77_FUNC(domldt, DOMLDT) (int * /*unused*/, int /*unused*/[], char /*unused*/[]) -{ -} +static void F77_FUNC(domldt, DOMLDT)(int* /*unused*/, int /*unused*/[], char /*unused*/[]) {} -static void F77_FUNC(domop, DOMOP) (int * /*unused*/, double /*unused*/[], int * /*unused*/, - double /*unused*/[], double /*unused*/[], double /*unused*/[], - double /*unused*/[], double * /*unused*/, double /*unused*/[]) +static void F77_FUNC(domop, DOMOP)(int* /*unused*/, + double /*unused*/[], + int* /*unused*/, + double /*unused*/[], + double /*unused*/[], + double /*unused*/[], + double /*unused*/[], + double* /*unused*/, + double /*unused*/[]) { } #endif -void init_mopac(t_QMrec *qm) +void init_mopac(t_QMrec* qm) { /* initializes the mopac routines ans sets up the semiempirical * computation by calling moldat(). The inline mopac routines can @@ -100,49 +108,46 @@ void init_mopac(t_QMrec *qm) * structure or find a transition state at PM3 level, gaussian is * used instead. */ - char - *keywords; + char* keywords; if (!GMX_QMMM_MOPAC) { - gmx_fatal(FARGS, "Cannot call MOPAC unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=MOPAC, and ensure that linking will work correctly."); + gmx_fatal(FARGS, + "Cannot call MOPAC unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=MOPAC, " + "and ensure that linking will work correctly."); } snew(keywords, 240); - if (!qm->bSH) /* if rerun then grad should not be done! */ + if (!qm->bSH) /* if rerun then grad should not be done! */ { - sprintf(keywords, "PRECISE GEO-OK CHARGE=%d GRAD MMOK ANALYT %s\n", - qm->QMcharge, + sprintf(keywords, "PRECISE GEO-OK CHARGE=%d GRAD MMOK ANALYT %s\n", qm->QMcharge, eQMmethod_names[qm->QMmethod]); } else { sprintf(keywords, "PRECISE GEO-OK CHARGE=%d SINGLET GRAD %s C.I.=(%d,%d) root=2 MECI \n", - qm->QMcharge, - eQMmethod_names[qm->QMmethod], - qm->CASorbitals, qm->CASelectrons/2); + qm->QMcharge, eQMmethod_names[qm->QMmethod], qm->CASorbitals, qm->CASelectrons / 2); } - F77_FUNC(domldt, DOMLDT) (&qm->nrQMatoms, qm->atomicnumberQM, keywords); + F77_FUNC(domldt, DOMLDT)(&qm->nrQMatoms, qm->atomicnumberQM, keywords); fprintf(stderr, "keywords are: %s\n", keywords); free(keywords); } /* init_mopac */ -real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) +real call_mopac(t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]) { /* do the actual QMMM calculation using directly linked mopac subroutines */ double /* always double as the MOPAC routines are always compiled in double precission! */ - *qmcrd = nullptr, *qmchrg = nullptr, *mmcrd = nullptr, *mmchrg = nullptr, - *qmgrad, *mmgrad = nullptr, energy = 0; - int - i, j; - real - QMener = 0.0; - snew(qmcrd, 3*(qm->nrQMatoms)); - snew(qmgrad, 3*(qm->nrQMatoms)); + *qmcrd = nullptr, + *qmchrg = nullptr, *mmcrd = nullptr, *mmchrg = nullptr, *qmgrad, *mmgrad = nullptr, + energy = 0; + int i, j; + real QMener = 0.0; + snew(qmcrd, 3 * (qm->nrQMatoms)); + snew(qmgrad, 3 * (qm->nrQMatoms)); /* copy the data from qr into the arrays that are going to be used * in the fortran routines of MOPAC */ @@ -150,7 +155,7 @@ real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { for (j = 0; j < DIM; j++) { - qmcrd[3*i+j] = static_cast(qm->xQM[i][j])*10; + qmcrd[3 * i + j] = static_cast(qm->xQM[i][j]) * 10; } } if (mm->nrMMatoms) @@ -159,7 +164,8 @@ real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) * conceptual problems with semi-empirical QM in combination with * point charges that we need to solve first.... */ - gmx_fatal(FARGS, "At present only ONIOM is allowed in combination" + gmx_fatal(FARGS, + "At present only ONIOM is allowed in combination" " with MOPAC QM subroutines\n"); } else @@ -168,8 +174,8 @@ real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) */ snew(qmchrg, qm->nrQMatoms); - F77_FUNC(domop, DOMOP) (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, - mmchrg, mmcrd, qmgrad, mmgrad, &energy, qmchrg); + F77_FUNC(domop, DOMOP) + (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, mmchrg, mmcrd, qmgrad, mmgrad, &energy, qmchrg); /* add the gradients to the f[] array, and also to the fshift[]. * the mopac gradients are in kCal/angstrom. */ @@ -177,11 +183,11 @@ real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { for (j = 0; j < DIM; j++) { - f[i][j] = static_cast(10)*CAL2JOULE*qmgrad[3*i+j]; - fshift[i][j] = static_cast(10)*CAL2JOULE*qmgrad[3*i+j]; + f[i][j] = static_cast(10) * CAL2JOULE * qmgrad[3 * i + j]; + fshift[i][j] = static_cast(10) * CAL2JOULE * qmgrad[3 * i + j]; } } - QMener = static_castCAL2JOULE*energy; + QMener = static_cast CAL2JOULE * energy; /* do we do something with the mulliken charges?? */ free(qmchrg); @@ -191,22 +197,21 @@ real call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) return (QMener); } -real call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) +real call_mopac_SH(t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]) { /* do the actual SH QMMM calculation using directly linked mopac subroutines */ double /* always double as the MOPAC routines are always compiled in double precission! */ - *qmcrd = nullptr, *qmchrg = nullptr, *mmcrd = nullptr, *mmchrg = nullptr, - *qmgrad, *mmgrad = nullptr, energy = 0; - int - i, j; - real - QMener = 0.0; - - snew(qmcrd, 3*(qm->nrQMatoms)); - snew(qmgrad, 3*(qm->nrQMatoms)); + *qmcrd = nullptr, + *qmchrg = nullptr, *mmcrd = nullptr, *mmchrg = nullptr, *qmgrad, *mmgrad = nullptr, + energy = 0; + int i, j; + real QMener = 0.0; + + snew(qmcrd, 3 * (qm->nrQMatoms)); + snew(qmgrad, 3 * (qm->nrQMatoms)); /* copy the data from qr into the arrays that are going to be used * in the fortran routines of MOPAC */ @@ -214,7 +219,7 @@ real call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { for (j = 0; j < DIM; j++) { - qmcrd[3*i+j] = static_cast(qm->xQM[i][j])*10; + qmcrd[3 * i + j] = static_cast(qm->xQM[i][j]) * 10; } } if (mm->nrMMatoms) @@ -231,8 +236,8 @@ real call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) */ snew(qmchrg, qm->nrQMatoms); - F77_FUNC(domop, DOMOP) (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, - mmchrg, mmcrd, qmgrad, mmgrad, &energy, qmchrg); + F77_FUNC(domop, DOMOP) + (&qm->nrQMatoms, qmcrd, &mm->nrMMatoms, mmchrg, mmcrd, qmgrad, mmgrad, &energy, qmchrg); /* add the gradients to the f[] array, and also to the fshift[]. * the mopac gradients are in kCal/angstrom. */ @@ -240,11 +245,11 @@ real call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) { for (j = 0; j < DIM; j++) { - f[i][j] = static_cast(10)*CAL2JOULE*qmgrad[3*i+j]; - fshift[i][j] = static_cast(10)*CAL2JOULE*qmgrad[3*i+j]; + f[i][j] = static_cast(10) * CAL2JOULE * qmgrad[3 * i + j]; + fshift[i][j] = static_cast(10) * CAL2JOULE * qmgrad[3 * i + j]; } } - QMener = static_castCAL2JOULE*energy; + QMener = static_cast CAL2JOULE * energy; } free(qmgrad); free(qmcrd); diff --git a/src/gromacs/mdlib/qm_mopac.h b/src/gromacs/mdlib/qm_mopac.h index 6855dafbd3..0f6eca8776 100644 --- a/src/gromacs/mdlib/qm_mopac.h +++ b/src/gromacs/mdlib/qm_mopac.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,8 +42,7 @@ * * \param[in] qm QM forcerec. */ -void -init_mopac(t_QMrec *qm); +void init_mopac(t_QMrec* qm); /*! \brief * Run calculation with MOPAC. @@ -53,8 +52,7 @@ init_mopac(t_QMrec *qm); * \param[in] f Force vector. * \param[in] fshift Force shift vector. */ -real -call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]); +real call_mopac(t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]); /*! \brief * Run surface-hopping calculation with MOPAC. @@ -64,7 +62,6 @@ call_mopac(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]); * \param[in] f Force vector. * \param[in] fshift Force shift vector. */ -real -call_mopac_SH(t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]); +real call_mopac_SH(t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]); #endif diff --git a/src/gromacs/mdlib/qm_orca.cpp b/src/gromacs/mdlib/qm_orca.cpp index 7495484544..075d8d6834 100644 --- a/src/gromacs/mdlib/qm_orca.cpp +++ b/src/gromacs/mdlib/qm_orca.cpp @@ -63,14 +63,16 @@ /* ORCA interface routines */ -void init_orca(t_QMrec *qm) +void init_orca(t_QMrec* qm) { - char *buf; + char* buf; snew(buf, 200); if (!GMX_QMMM_ORCA) { - gmx_fatal(FARGS, "Cannot call ORCA unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=ORCA, and ensure that linking will work correctly."); + gmx_fatal(FARGS, + "Cannot call ORCA unless linked against it. Use cmake -DGMX_QMMM_PROGRAM=ORCA, " + "and ensure that linking will work correctly."); } /* ORCA settings on the system */ @@ -108,12 +110,12 @@ void init_orca(t_QMrec *qm) } -static void write_orca_input(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) +static void write_orca_input(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm) { int i; - t_QMMMrec *QMMMrec; - FILE *out, *pcFile, *addInputFile; - char *buf, *orcaInput, *addInputFilename, *pcFilename; + t_QMMMrec* QMMMrec; + FILE * out, *pcFile, *addInputFile; + char * buf, *orcaInput, *addInputFilename, *pcFilename; QMMMrec = fr->qr; @@ -164,11 +166,8 @@ static void write_orca_input(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) { atomNr = qm->atomicnumberQM[i]; } - fprintf(out, "%3d %10.7f %10.7f %10.7f\n", - atomNr, - qm->xQM[i][XX]/0.1, - qm->xQM[i][YY]/0.1, - qm->xQM[i][ZZ]/0.1); + fprintf(out, "%3d %10.7f %10.7f %10.7f\n", atomNr, qm->xQM[i][XX] / 0.1, + qm->xQM[i][YY] / 0.1, qm->xQM[i][ZZ] / 0.1); } fprintf(out, "*\n"); @@ -183,11 +182,8 @@ static void write_orca_input(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) fprintf(pcFile, "%d\n", mm->nrMMatoms); for (i = 0; i < mm->nrMMatoms; i++) { - fprintf(pcFile, "%8.4f %10.7f %10.7f %10.7f\n", - mm->MMcharges[i], - mm->xMM[i][XX]/0.1, - mm->xMM[i][YY]/0.1, - mm->xMM[i][ZZ]/0.1); + fprintf(pcFile, "%8.4f %10.7f %10.7f %10.7f\n", mm->MMcharges[i], + mm->xMM[i][XX] / 0.1, mm->xMM[i][YY] / 0.1, mm->xMM[i][ZZ] / 0.1); } fprintf(pcFile, "\n"); fclose(pcFile); @@ -195,22 +191,16 @@ static void write_orca_input(const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) fprintf(out, "\n"); fclose(out); -} /* write_orca_input */ +} /* write_orca_input */ -static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_forcerec *fr, - t_QMrec *qm, t_MMrec *mm) +static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm) { - int - i, j; - char - buf[300], orca_pcgradFilename[300], orca_engradFilename[300]; - real - QMener; - FILE - *pcgrad, *engrad; - int k; - t_QMMMrec - *QMMMrec; + int i, j; + char buf[300], orca_pcgradFilename[300], orca_engradFilename[300]; + real QMener; + FILE * pcgrad, *engrad; + int k; + t_QMMMrec* QMMMrec; QMMMrec = fr->qr; /* the energy and gradients for the QM part are stored in the engrad file @@ -254,36 +244,36 @@ static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_forcerec *fr, * (atom1 x \n atom1 y \n atom1 z \n atom2 x ... */ - for (i = 0; i < 3*qm->nrQMatoms; i++) + for (i = 0; i < 3 * qm->nrQMatoms; i++) { - k = i/3; + k = i / 3; if (fgets(buf, 300, engrad) == nullptr) { gmx_fatal(FARGS, "Unexpected end of ORCA output"); } #if GMX_DOUBLE - if (i%3 == 0) + if (i % 3 == 0) { sscanf(buf, "%lf\n", &QMgrad[k][XX]); } - else if (i%3 == 1) + else if (i % 3 == 1) { sscanf(buf, "%lf\n", &QMgrad[k][YY]); } - else if (i%3 == 2) + else if (i % 3 == 2) { sscanf(buf, "%lf\n", &QMgrad[k][ZZ]); } #else - if (i%3 == 0) + if (i % 3 == 0) { sscanf(buf, "%f\n", &QMgrad[k][XX]); } - else if (i%3 == 1) + else if (i % 3 == 1) { sscanf(buf, "%f\n", &QMgrad[k][YY]); } - else if (i%3 == 2) + else if (i % 3 == 2) { sscanf(buf, "%f\n", &QMgrad[k][ZZ]); } @@ -311,37 +301,26 @@ static real read_orca_output(rvec QMgrad[], rvec MMgrad[], const t_forcerec *fr, { gmx_fatal(FARGS, "Unexpected end of ORCA output"); } - #if GMX_DOUBLE - sscanf(buf, "%lf%lf%lf\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); - #else - sscanf(buf, "%f%f%f\n", - &MMgrad[i][XX], - &MMgrad[i][YY], - &MMgrad[i][ZZ]); - #endif +#if GMX_DOUBLE + sscanf(buf, "%lf%lf%lf\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); +#else + sscanf(buf, "%f%f%f\n", &MMgrad[i][XX], &MMgrad[i][YY], &MMgrad[i][ZZ]); +#endif } fclose(pcgrad); } - return(QMener); + return (QMener); } -static void do_orca(char *orca_dir, char *basename) +static void do_orca(char* orca_dir, char* basename) { /* make the call to the orca binary through system() * The location of the binary is set through the * environment. */ - char - buf[100]; - sprintf(buf, "%s/%s %s.inp >> %s.out", - orca_dir, - "orca", - basename, - basename); + char buf[100]; + sprintf(buf, "%s/%s %s.inp >> %s.out", orca_dir, "orca", basename, basename); fprintf(stderr, "Calling '%s'\n", buf); if (system(buf) != 0) { @@ -349,20 +328,14 @@ static void do_orca(char *orca_dir, char *basename) } } -real call_orca(const t_forcerec *fr, - t_QMrec *qm, t_MMrec *mm, rvec f[], rvec fshift[]) +real call_orca(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]) { /* normal orca jobs */ - static int - step = 0; - int - i, j; - real - QMener; - rvec - *QMgrad, *MMgrad; - char - *exe; + static int step = 0; + int i, j; + real QMener; + rvec * QMgrad, *MMgrad; + char* exe; snew(exe, 30); sprintf(exe, "%s", "orca"); @@ -378,22 +351,22 @@ real call_orca(const t_forcerec *fr, { for (j = 0; j < DIM; j++) { - f[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; - fshift[i][j] = HARTREE_BOHR2MD*QMgrad[i][j]; + f[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; + fshift[i][j] = HARTREE_BOHR2MD * QMgrad[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - f[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; - fshift[i+qm->nrQMatoms][j] = HARTREE_BOHR2MD*MMgrad[i][j]; + f[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; + fshift[i + qm->nrQMatoms][j] = HARTREE_BOHR2MD * MMgrad[i][j]; } } - QMener = QMener*HARTREE2KJ*AVOGADRO; + QMener = QMener * HARTREE2KJ * AVOGADRO; step++; free(exe); - return(QMener); + return (QMener); } /* call_orca */ /* end of orca sub routines */ diff --git a/src/gromacs/mdlib/qm_orca.h b/src/gromacs/mdlib/qm_orca.h index 2be832bef0..cf89d941c8 100644 --- a/src/gromacs/mdlib/qm_orca.h +++ b/src/gromacs/mdlib/qm_orca.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,13 +35,10 @@ #include "gromacs/mdlib/qmmm.h" #ifndef GMX_MDLIB_QM_ORCA_H -#define GMX_MDLIB_QM_ORCA_H +# define GMX_MDLIB_QM_ORCA_H -void -init_orca(t_QMrec *qm); +void init_orca(t_QMrec* qm); -real -call_orca(const t_forcerec *fr, t_QMrec *qm, - t_MMrec *mm, rvec f[], rvec fshift[]); +real call_orca(const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm, rvec f[], rvec fshift[]); #endif diff --git a/src/gromacs/mdlib/qmmm.cpp b/src/gromacs/mdlib/qmmm.cpp index 146ab1ff35..2482bf5927 100644 --- a/src/gromacs/mdlib/qmmm.cpp +++ b/src/gromacs/mdlib/qmmm.cpp @@ -83,18 +83,23 @@ * a QMMM input for the QM routines from the QMMM neighbor list. */ -typedef struct { - int j; - int shift; +typedef struct +{ + int j; + int shift; } t_j_particle; -static bool struct_comp(const t_j_particle &a, const t_j_particle &b) +static bool struct_comp(const t_j_particle& a, const t_j_particle& b) { return a.j < b.j; } -static real call_QMroutine(const t_commrec gmx_unused *cr, const t_forcerec gmx_unused *fr, t_QMrec gmx_unused *qm, - t_MMrec gmx_unused *mm, rvec gmx_unused f[], rvec gmx_unused fshift[]) +static real call_QMroutine(const t_commrec gmx_unused* cr, + const t_forcerec gmx_unused* fr, + t_QMrec gmx_unused* qm, + t_MMrec gmx_unused* mm, + rvec gmx_unused f[], + rvec gmx_unused fshift[]) { /* makes a call to the requested QM routine (qm->QMmethod) * Note that f is actually the gradient, i.e. -f @@ -149,13 +154,14 @@ static real call_QMroutine(const t_commrec gmx_unused *cr, const t_forcerec gmx_ } else { - gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); + gmx_fatal(FARGS, + "Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); } } } } -static void init_QMroutine(const t_commrec gmx_unused *cr, t_QMrec gmx_unused *qm, t_MMrec gmx_unused *mm) +static void init_QMroutine(const t_commrec gmx_unused* cr, t_QMrec gmx_unused* qm, t_MMrec gmx_unused* mm) { /* makes a call to the requested QM routine (qm->QMmethod) */ @@ -193,14 +199,13 @@ static void init_QMroutine(const t_commrec gmx_unused *cr, t_QMrec gmx_unused *q } } /* init_QMroutine */ -static void update_QMMM_coord(const rvec *x, const t_forcerec *fr, t_QMrec *qm, t_MMrec *mm) +static void update_QMMM_coord(const rvec* x, const t_forcerec* fr, t_QMrec* qm, t_MMrec* mm) { /* shifts the QM and MM particles into the central box and stores * these shifted coordinates in the coordinate arrays of the * QMMMrec. These coordinates are passed on the QM subroutines. */ - int - i; + int i; /* shift the QM atoms into the central box */ @@ -220,22 +225,21 @@ static void update_QMMM_coord(const rvec *x, const t_forcerec *fr, t_QMrec *qm, /* QMMM core routines */ -static t_QMrec *mk_QMrec() +static t_QMrec* mk_QMrec() { - t_QMrec *qm; + t_QMrec* qm; snew(qm, 1); return qm; } /* mk_QMrec */ -static t_MMrec *mk_MMrec() +static t_MMrec* mk_MMrec() { - t_MMrec *mm; + t_MMrec* mm; snew(mm, 1); return mm; } /* mk_MMrec */ -static void init_QMrec(int grpnr, t_QMrec *qm, int nr, const int *atomarray, - const gmx_mtop_t *mtop, const t_inputrec *ir) +static void init_QMrec(int grpnr, t_QMrec* qm, int nr, const int* atomarray, const gmx_mtop_t* mtop, const t_inputrec* ir) { /* fills the t_QMrec struct of QM group grpnr */ @@ -253,42 +257,39 @@ static void init_QMrec(int grpnr, t_QMrec *qm, int nr, const int *atomarray, int molb = 0; for (int i = 0; i < qm->nrQMatoms; i++) { - const t_atom &atom = mtopGetAtomParameters(mtop, qm->indexQM[i], &molb); - qm->nelectrons += mtop->atomtypes.atomnumber[atom.type]; + const t_atom& atom = mtopGetAtomParameters(mtop, qm->indexQM[i], &molb); + qm->nelectrons += mtop->atomtypes.atomnumber[atom.type]; qm->atomicnumberQM[i] = mtop->atomtypes.atomnumber[atom.type]; } - qm->QMcharge = ir->opts.QMcharge[grpnr]; - qm->multiplicity = ir->opts.QMmult[grpnr]; - qm->nelectrons -= ir->opts.QMcharge[grpnr]; + qm->QMcharge = ir->opts.QMcharge[grpnr]; + qm->multiplicity = ir->opts.QMmult[grpnr]; + qm->nelectrons -= ir->opts.QMcharge[grpnr]; - qm->QMmethod = ir->opts.QMmethod[grpnr]; - qm->QMbasis = ir->opts.QMbasis[grpnr]; + qm->QMmethod = ir->opts.QMmethod[grpnr]; + qm->QMbasis = ir->opts.QMbasis[grpnr]; /* trajectory surface hopping setup (Gaussian only) */ - qm->bSH = ir->opts.bSH[grpnr]; - qm->CASorbitals = ir->opts.CASorbitals[grpnr]; - qm->CASelectrons = ir->opts.CASelectrons[grpnr]; - qm->SAsteps = ir->opts.SAsteps[grpnr]; - qm->SAon = ir->opts.SAon[grpnr]; - qm->SAoff = ir->opts.SAoff[grpnr]; + qm->bSH = ir->opts.bSH[grpnr]; + qm->CASorbitals = ir->opts.CASorbitals[grpnr]; + qm->CASelectrons = ir->opts.CASelectrons[grpnr]; + qm->SAsteps = ir->opts.SAsteps[grpnr]; + qm->SAon = ir->opts.SAon[grpnr]; + qm->SAoff = ir->opts.SAoff[grpnr]; /* hack to prevent gaussian from reinitializing all the time */ - qm->nQMcpus = 0; /* number of CPU's to be used by g01, is set - * upon initializing gaussian - * (init_gaussian() - */ + qm->nQMcpus = 0; /* number of CPU's to be used by g01, is set + * upon initializing gaussian + * (init_gaussian() + */ /* print the current layer to allow users to check their input */ fprintf(stderr, "Layer %d\nnr of QM atoms %d\n", grpnr, nr); - fprintf(stderr, "QMlevel: %s/%s\n\n", - eQMmethod_names[qm->QMmethod], eQMbasis_names[qm->QMbasis]); + fprintf(stderr, "QMlevel: %s/%s\n\n", eQMmethod_names[qm->QMmethod], eQMbasis_names[qm->QMbasis]); } /* init_QMrec */ -static t_QMrec *copy_QMrec(t_QMrec *qm) +static t_QMrec* copy_QMrec(t_QMrec* qm) { /* copies the contents of qm into a new t_QMrec struct */ - t_QMrec - *qmcopy; - int - i; + t_QMrec* qmcopy; + int i; qmcopy = mk_QMrec(); qmcopy->nrQMatoms = qm->nrQMatoms; @@ -317,45 +318,45 @@ static t_QMrec *copy_QMrec(t_QMrec *qm) qmcopy->SAoff = qm->SAoff; /* Gaussian init. variables */ - qmcopy->nQMcpus = qm->nQMcpus; + qmcopy->nQMcpus = qm->nQMcpus; for (i = 0; i < DIM; i++) { qmcopy->SHbasis[i] = qm->SHbasis[i]; } - qmcopy->QMmem = qm->QMmem; - qmcopy->accuracy = qm->accuracy; - qmcopy->cpmcscf = qm->cpmcscf; - qmcopy->SAstep = qm->SAstep; + qmcopy->QMmem = qm->QMmem; + qmcopy->accuracy = qm->accuracy; + qmcopy->cpmcscf = qm->cpmcscf; + qmcopy->SAstep = qm->SAstep; - return(qmcopy); + return (qmcopy); } /*copy_QMrec */ #if GMX_QMMM -t_QMMMrec *mk_QMMMrec() +t_QMMMrec* mk_QMMMrec() { - t_QMMMrec *qr; + t_QMMMrec* qr; snew(qr, 1); return qr; -} /* mk_QMMMrec */ +} /* mk_QMMMrec */ #else /* GMX_QMMM */ -t_QMMMrec *mk_QMMMrec() +t_QMMMrec* mk_QMMMrec() { gmx_incons("Compiled without QMMM"); } /* mk_QMMMrec */ #endif -std::vector qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop) +std::vector qmmmAtomIndices(const t_inputrec& ir, const gmx_mtop_t& mtop) { - const int numQmmmGroups = ir.opts.ngQM; - const SimulationGroups &groups = mtop.groups; - std::vector qmmmAtoms; + const int numQmmmGroups = ir.opts.ngQM; + const SimulationGroups& groups = mtop.groups; + std::vector qmmmAtoms; for (int i = 0; i < numQmmmGroups; i++) { for (const AtomProxy atomP : AtomRange(mtop)) @@ -371,27 +372,27 @@ std::vector qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop) /* I assume that users specify the QM groups from small to * big(ger) in the mdp file */ - gmx_mtop_ilistloop_all_t iloop = gmx_mtop_ilistloop_all_init(&mtop); - int nral1 = 1 + NRAL(F_VSITE2); - int atomOffset = 0; - while (const InteractionLists *ilists = gmx_mtop_ilistloop_all_next(iloop, &atomOffset)) + gmx_mtop_ilistloop_all_t iloop = gmx_mtop_ilistloop_all_init(&mtop); + int nral1 = 1 + NRAL(F_VSITE2); + int atomOffset = 0; + while (const InteractionLists* ilists = gmx_mtop_ilistloop_all_next(iloop, &atomOffset)) { - const InteractionList &ilist = (*ilists)[F_VSITE2]; + const InteractionList& ilist = (*ilists)[F_VSITE2]; for (int j = 0; j < ilist.size(); j += nral1) { - const int vsite = atomOffset + ilist.iatoms[j ]; /* the vsite */ - const int ai = atomOffset + ilist.iatoms[j+1]; /* constructing atom */ - const int aj = atomOffset + ilist.iatoms[j+2]; /* constructing atom */ - if (getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, ai) - && - getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, aj)) + const int vsite = atomOffset + ilist.iatoms[j]; /* the vsite */ + const int ai = atomOffset + ilist.iatoms[j + 1]; /* constructing atom */ + const int aj = atomOffset + ilist.iatoms[j + 2]; /* constructing atom */ + if (getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) + == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, ai) + && getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, vsite) + == getGroupType(groups, SimulationAtomGroupType::QuantumMechanics, aj)) { /* this dummy link atom needs to be removed from qmmmAtoms * before making the QMrec of this layer! */ - qmmmAtoms.erase(std::remove_if(qmmmAtoms.begin(), - qmmmAtoms.end(), - [&vsite](int atom){return atom == vsite; }), + qmmmAtoms.erase(std::remove_if(qmmmAtoms.begin(), qmmmAtoms.end(), + [&vsite](int atom) { return atom == vsite; }), qmmmAtoms.end()); } } @@ -401,23 +402,20 @@ std::vector qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop) return qmmmAtoms; } -void removeQmmmAtomCharges(gmx_mtop_t *mtop, gmx::ArrayRef qmmmAtoms) +void removeQmmmAtomCharges(gmx_mtop_t* mtop, gmx::ArrayRef qmmmAtoms) { int molb = 0; for (gmx::index i = 0; i < qmmmAtoms.ssize(); i++) { - int indexInMolecule; + int indexInMolecule; mtopGetMolblockIndex(mtop, qmmmAtoms[i], &molb, nullptr, &indexInMolecule); - t_atom *atom = &mtop->moltype[mtop->molblock[molb].type].atoms.atom[indexInMolecule]; - atom->q = 0.0; - atom->qB = 0.0; + t_atom* atom = &mtop->moltype[mtop->molblock[molb].type].atoms.atom[indexInMolecule]; + atom->q = 0.0; + atom->qB = 0.0; } } -void init_QMMMrec(const t_commrec *cr, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_forcerec *fr) +void init_QMMMrec(const t_commrec* cr, const gmx_mtop_t* mtop, const t_inputrec* ir, const t_forcerec* fr) { /* we put the atomsnumbers of atoms that belong to the QMMM group in * an array that will be copied later to QMMMrec->indexQM[..]. Also @@ -425,8 +423,8 @@ void init_QMMMrec(const t_commrec *cr, * simply contains true/false for QM and MM (the other) atoms. */ - t_QMMMrec *qr; - t_MMrec *mm; + t_QMMMrec* qr; + t_MMrec* mm; if (!GMX_QMMM) { @@ -456,7 +454,7 @@ void init_QMMMrec(const t_commrec *cr, * the qm_arr (=MMrec->indexQM) to changes the elements * corresponding to the QM atoms at TRUE. */ - qr->QMMMscheme = ir->QMMMscheme; + qr->QMMMscheme = ir->QMMMscheme; /* we take the possibility into account that a user has * defined more than one QM group: @@ -520,17 +518,17 @@ void init_QMMMrec(const t_commrec *cr, init_QMrec(0, qr->qm[0], qmmmAtoms.size(), qmmmAtoms.data(), mtop, ir); /* MM rec creation */ - mm = mk_MMrec(); - mm->scalefactor = ir->scalefactor; - mm->nrMMatoms = (mtop->natoms)-(qr->qm[0]->nrQMatoms); /* rest of the atoms */ - qr->mm = mm; + mm = mk_MMrec(); + mm->scalefactor = ir->scalefactor; + mm->nrMMatoms = (mtop->natoms) - (qr->qm[0]->nrQMatoms); /* rest of the atoms */ + qr->mm = mm; } else /* ONIOM */ { /* MM rec creation */ - mm = mk_MMrec(); - mm->scalefactor = ir->scalefactor; - mm->nrMMatoms = 0; - qr->mm = mm; + mm = mk_MMrec(); + mm->scalefactor = ir->scalefactor; + mm->nrMMatoms = 0; + qr->mm = mm; } /* these variables get updated in the update QMMMrec */ @@ -571,17 +569,14 @@ void init_QMMMrec(const t_commrec *cr, } else { - gmx_fatal(FARGS, "Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); + gmx_fatal(FARGS, + "Ab-initio calculation only supported with Gamess, Gaussian or ORCA."); } } } } /* init_QMMMrec */ -void update_QMMMrec(const t_commrec *cr, - const t_forcerec *fr, - const rvec *x, - const t_mdatoms *md, - const matrix box) +void update_QMMMrec(const t_commrec* cr, const t_forcerec* fr, const rvec* x, const t_mdatoms* md, const matrix box) { /* updates the coordinates of both QM atoms and MM atoms and stores * them in the QMMMrec. @@ -589,26 +584,16 @@ void update_QMMMrec(const t_commrec *cr, * NOTE: is NOT yet working if there are no PBC. Also in ns.c, simple * ns needs to be fixed! */ - int - mm_max = 0, mm_nr = 0, mm_nr_new, i, j, is, k, shift; - t_j_particle - *mm_j_particles = nullptr, *qm_i_particles = nullptr; - t_QMMMrec - *qr; - t_nblist - *QMMMlist; - rvec - dx; - ivec - crd; - t_QMrec - *qm; - t_MMrec - *mm; - t_pbc - pbc; - int - *parallelMMarray = nullptr; + int mm_max = 0, mm_nr = 0, mm_nr_new, i, j, is, k, shift; + t_j_particle *mm_j_particles = nullptr, *qm_i_particles = nullptr; + t_QMMMrec* qr; + t_nblist* QMMMlist; + rvec dx; + ivec crd; + t_QMrec* qm; + t_MMrec* mm; + t_pbc pbc; + int* parallelMMarray = nullptr; if (!GMX_QMMM) { @@ -622,15 +607,14 @@ void update_QMMMrec(const t_commrec *cr, * whcih atoms are part of the QM subsystem. */ /* copy some pointers */ - qr = fr->qr; - mm = qr->mm; - QMMMlist = fr->QMMMlist; + qr = fr->qr; + mm = qr->mm; + QMMMlist = fr->QMMMlist; /* init_pbc(box); needs to be called first, see pbc.h */ ivec null_ivec; clear_ivec(null_ivec); - set_pbc_dd(&pbc, fr->ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : null_ivec, - FALSE, box); + set_pbc_dd(&pbc, fr->ePBC, DOMAINDECOMP(cr) ? cr->dd->nc : null_ivec, FALSE, box); /* only in standard (normal) QMMM we need the neighbouring MM * particles to provide a electric field of point charges for the QM * atoms. @@ -656,13 +640,12 @@ void update_QMMMrec(const t_commrec *cr, qm_i_particles[0].shift = XYZ2IS(0, 0, 0); for (i = 0; i < QMMMlist->nri; i++) { - qm_i_particles[i].j = QMMMlist->iinr[i]; + qm_i_particles[i].j = QMMMlist->iinr[i]; if (i) { - qm_i_particles[i].shift = pbc_dx_aiuc(&pbc, x[QMMMlist->iinr[0]], - x[QMMMlist->iinr[i]], dx); - + qm_i_particles[i].shift = + pbc_dx_aiuc(&pbc, x[QMMMlist->iinr[0]], x[QMMMlist->iinr[i]], dx); } /* However, since nri >= nrQMatoms, we do a quicksort, and throw * out double, triple, etc. entries later, as we do for the MM @@ -677,9 +660,7 @@ void update_QMMMrec(const t_commrec *cr, crd[1] = IS2Y(QMMMlist->shift[i]) + IS2Y(qm_i_particles[i].shift); crd[2] = IS2Z(QMMMlist->shift[i]) + IS2Z(qm_i_particles[i].shift); is = XYZ2IS(crd[0], crd[1], crd[2]); - for (j = QMMMlist->jindex[i]; - j < QMMMlist->jindex[i+1]; - j++) + for (j = QMMMlist->jindex[i]; j < QMMMlist->jindex[i + 1]; j++) { if (mm_nr >= mm_max) { @@ -696,12 +677,11 @@ void update_QMMMrec(const t_commrec *cr, /* quicksort QM and MM shift arrays and throw away multiple entries */ - - std::sort(qm_i_particles, qm_i_particles+QMMMlist->nri, struct_comp); + std::sort(qm_i_particles, qm_i_particles + QMMMlist->nri, struct_comp); /* The mm_j_particles argument to qsort is not allowed to be nullptr */ if (mm_nr > 0) { - std::sort(mm_j_particles, mm_j_particles+mm_nr, struct_comp); + std::sort(mm_j_particles, mm_j_particles + mm_nr, struct_comp); } /* remove multiples in the QM shift array, since in init_QMMM() we * went through the atom numbers from 0 to md.nr, the order sorted @@ -710,7 +690,7 @@ void update_QMMMrec(const t_commrec *cr, j = 0; for (i = 0; i < QMMMlist->nri; i++) { - if (i == 0 || qm_i_particles[i].j != qm_i_particles[i-1].j) + if (i == 0 || qm_i_particles[i].j != qm_i_particles[i - 1].j) { qm_i_particles[j++] = qm_i_particles[i]; } @@ -722,7 +702,7 @@ void update_QMMMrec(const t_commrec *cr, */ for (i = 0; i < mm_nr; i++) { - if ((i == 0 || mm_j_particles[i].j != mm_j_particles[i-1].j) + if ((i == 0 || mm_j_particles[i].j != mm_j_particles[i - 1].j) && !md->bQM[mm_j_particles[i].j] && ((md->chargeA[mm_j_particles[i].j] != 0.0_real) || (md->chargeB && (md->chargeB[mm_j_particles[i].j] != 0.0_real)))) @@ -758,21 +738,21 @@ void update_QMMMrec(const t_commrec *cr, /* parallel excecution */ if (PAR(cr)) { - snew(parallelMMarray, 2*(md->nr)); + snew(parallelMMarray, 2 * (md->nr)); /* only MM particles have a 1 at their atomnumber. The second part * of the array contains the shifts. Thus: * p[i]=1/0 depending on wether atomnumber i is a MM particle in the QM * step or not. p[i+md->nr] is the shift of atomnumber i. */ - for (i = 0; i < 2*(md->nr); i++) + for (i = 0; i < 2 * (md->nr); i++) { parallelMMarray[i] = 0; } for (i = 0; i < mm_nr; i++) { - parallelMMarray[mm_j_particles[i].j] = 1; - parallelMMarray[mm_j_particles[i].j+(md->nr)] = mm_j_particles[i].shift; + parallelMMarray[mm_j_particles[i].j] = 1; + parallelMMarray[mm_j_particles[i].j + (md->nr)] = mm_j_particles[i].shift; } gmx_sumi(md->nr, parallelMMarray, cr); mm_nr = 0; @@ -789,7 +769,7 @@ void update_QMMMrec(const t_commrec *cr, srenew(mm->shiftMM, mm_max); } mm->indexMM[mm_nr] = i; - mm->shiftMM[mm_nr++] = parallelMMarray[i+md->nr]/parallelMMarray[i]; + mm->shiftMM[mm_nr++] = parallelMMarray[i + md->nr] / parallelMMarray[i]; } } mm->nrMMatoms = mm_nr; @@ -806,7 +786,6 @@ void update_QMMMrec(const t_commrec *cr, mm->indexMM[i] = mm_j_particles[i].j; mm->shiftMM[i] = mm_j_particles[i].shift; } - } /* (re) allocate memory for the MM coordiate array. The QM * coordinate array was already allocated in init_QMMM, and is @@ -820,7 +799,7 @@ void update_QMMMrec(const t_commrec *cr, srenew(mm->MMcharges, mm->nrMMatoms); for (i = 0; i < mm->nrMMatoms; i++) /* no free energy yet */ { - mm->MMcharges[i] = md->chargeA[mm->indexMM[i]]*mm->scalefactor; + mm->MMcharges[i] = md->chargeA[mm->indexMM[i]] * mm->scalefactor; } /* the next routine fills the coordinate fields in the QMMM rec of * both the qunatum atoms and the MM atoms, using the shifts @@ -841,35 +820,26 @@ void update_QMMMrec(const t_commrec *cr, qm->shiftQM[0] = XYZ2IS(0, 0, 0); for (i = 1; i < qm->nrQMatoms; i++) { - qm->shiftQM[i] = pbc_dx_aiuc(&pbc, x[qm->indexQM[0]], x[qm->indexQM[i]], - dx); + qm->shiftQM[i] = pbc_dx_aiuc(&pbc, x[qm->indexQM[0]], x[qm->indexQM[i]], dx); } update_QMMM_coord(x, fr, qm, mm); } } } /* update_QMMM_rec */ -real calculate_QMMM(const t_commrec *cr, - gmx::ForceWithShiftForces *forceWithShiftForces, - const t_forcerec *fr) +real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_forcerec* fr) { - real - QMener = 0.0; + real QMener = 0.0; /* a selection for the QM package depending on which is requested * (Gaussian, GAMESS-UK, MOPAC or ORCA) needs to be implemented here. Now * it works through defines.... Not so nice yet */ - t_QMMMrec - *qr; - t_QMrec - *qm, *qm2; - t_MMrec - *mm = nullptr; - rvec - *forces = nullptr, *fshift = nullptr, - *forces2 = nullptr, *fshift2 = nullptr; /* needed for multilayer ONIOM */ - int - i, j, k; + t_QMMMrec* qr; + t_QMrec * qm, *qm2; + t_MMrec* mm = nullptr; + rvec * forces = nullptr, *fshift = nullptr, *forces2 = nullptr, + *fshift2 = nullptr; /* needed for multilayer ONIOM */ + int i, j, k; if (!GMX_QMMM) { @@ -889,35 +859,34 @@ real calculate_QMMM(const t_commrec *cr, if (qr->QMMMscheme == eQMMMschemenormal || qr->nrQMlayers == 1) { qm = qr->qm[0]; - snew(forces, (qm->nrQMatoms+mm->nrMMatoms)); - snew(fshift, (qm->nrQMatoms+mm->nrMMatoms)); + snew(forces, (qm->nrQMatoms + mm->nrMMatoms)); + snew(fshift, (qm->nrQMatoms + mm->nrMMatoms)); QMener = call_QMroutine(cr, fr, qm, mm, forces, fshift); for (i = 0; i < qm->nrQMatoms; i++) { for (j = 0; j < DIM; j++) { - fMM[qm->indexQM[i]][j] -= forces[i][j]; - fshiftMM[qm->shiftQM[i]][j] += fshift[i][j]; + fMM[qm->indexQM[i]][j] -= forces[i][j]; + fshiftMM[qm->shiftQM[i]][j] += fshift[i][j]; } } for (i = 0; i < mm->nrMMatoms; i++) { for (j = 0; j < DIM; j++) { - fMM[mm->indexMM[i]][j] -= forces[qm->nrQMatoms+i][j]; - fshiftMM[mm->shiftMM[i]][j] += fshift[qm->nrQMatoms+i][j]; + fMM[mm->indexMM[i]][j] -= forces[qm->nrQMatoms + i][j]; + fshiftMM[mm->shiftMM[i]][j] += fshift[qm->nrQMatoms + i][j]; } - } free(forces); free(fshift); } - else /* Multi-layer ONIOM */ + else /* Multi-layer ONIOM */ { - for (i = 0; i < qr->nrQMlayers-1; i++) /* last layer is special */ + for (i = 0; i < qr->nrQMlayers - 1; i++) /* last layer is special */ { qm = qr->qm[i]; - qm2 = copy_QMrec(qr->qm[i+1]); + qm2 = copy_QMrec(qr->qm[i + 1]); qm2->nrQMatoms = qm->nrQMatoms; @@ -925,7 +894,7 @@ real calculate_QMMM(const t_commrec *cr, { for (k = 0; k < DIM; k++) { - qm2->xQM[j][k] = qm->xQM[j][k]; + qm2->xQM[j][k] = qm->xQM[j][k]; } qm2->indexQM[j] = qm->indexQM[j]; qm2->atomicnumberQM[j] = qm->atomicnumberQM[j]; @@ -953,14 +922,14 @@ real calculate_QMMM(const t_commrec *cr, { for (j = 0; j < DIM; j++) { - fMM[qm->indexQM[i]][j] -= (forces[i][j]-forces2[i][j]); - fshiftMM[qm->shiftQM[i]][j] += (fshift[i][j]-fshift2[i][j]); + fMM[qm->indexQM[i]][j] -= (forces[i][j] - forces2[i][j]); + fshiftMM[qm->shiftQM[i]][j] += (fshift[i][j] - fshift2[i][j]); } } free(qm2); } /* now the last layer still needs to be done: */ - qm = qr->qm[qr->nrQMlayers-1]; /* C counts from 0 */ + qm = qr->qm[qr->nrQMlayers - 1]; /* C counts from 0 */ init_QMroutine(cr, qm, mm); srenew(forces, qm->nrQMatoms); srenew(fshift, qm->nrQMatoms); @@ -969,7 +938,7 @@ real calculate_QMMM(const t_commrec *cr, { for (j = 0; j < DIM; j++) { - fMM[qm->indexQM[i]][j] -= forces[i][j]; + fMM[qm->indexQM[i]][j] -= forces[i][j]; fshiftMM[qm->shiftQM[i]][j] += fshift[i][j]; } } @@ -978,7 +947,7 @@ real calculate_QMMM(const t_commrec *cr, free(forces2); free(fshift2); } - return(QMener); + return (QMener); } /* calculate_QMMM */ #pragma GCC diagnostic pop diff --git a/src/gromacs/mdlib/qmmm.h b/src/gromacs/mdlib/qmmm.h index ffa98d352b..8172e97660 100644 --- a/src/gromacs/mdlib/qmmm.h +++ b/src/gromacs/mdlib/qmmm.h @@ -60,71 +60,71 @@ namespace gmx class ForceWithShiftForces; } -typedef struct { - int nrQMatoms; /* total nr of QM atoms */ - rvec *xQM; /* shifted to center of box */ - int *indexQM; /* atom i = atom indexQM[i] in mdrun */ - int *atomicnumberQM; /* atomic numbers of QM atoms */ - real *QMcharges; /* atomic charges of QM atoms(ONIOM) */ - int *shiftQM; - int QMcharge; /* charge of the QM system */ - int multiplicity; /* multipicity (no of unpaired eln) */ - int QMmethod; /* see enums.h for all methods */ - int QMbasis; /* see enums.h for all bases */ - int nelectrons; /* total number of elecs in QM region*/ +typedef struct +{ + int nrQMatoms; /* total nr of QM atoms */ + rvec* xQM; /* shifted to center of box */ + int* indexQM; /* atom i = atom indexQM[i] in mdrun */ + int* atomicnumberQM; /* atomic numbers of QM atoms */ + real* QMcharges; /* atomic charges of QM atoms(ONIOM) */ + int* shiftQM; + int QMcharge; /* charge of the QM system */ + int multiplicity; /* multipicity (no of unpaired eln) */ + int QMmethod; /* see enums.h for all methods */ + int QMbasis; /* see enums.h for all bases */ + int nelectrons; /* total number of elecs in QM region*/ /* Gaussian specific stuff */ - int nQMcpus; /* no. of CPUs used for the QM calc. */ - int QMmem; /* memory for the gaussian calc. */ - int accuracy; /* convergence criterium (E(-x)) */ - gmx_bool cpmcscf; /* using cpmcscf(l1003)*/ - char *gauss_dir; - char *gauss_exe; - char *devel_dir; - char *orca_basename; /* basename for I/O with orca */ - char *orca_dir; /* directory for ORCA */ + int nQMcpus; /* no. of CPUs used for the QM calc. */ + int QMmem; /* memory for the gaussian calc. */ + int accuracy; /* convergence criterium (E(-x)) */ + gmx_bool cpmcscf; /* using cpmcscf(l1003)*/ + char* gauss_dir; + char* gauss_exe; + char* devel_dir; + char* orca_basename; /* basename for I/O with orca */ + char* orca_dir; /* directory for ORCA */ /* Surface hopping stuff */ - gmx_bool bSH; /* surface hopping (diabatic only) */ - real SAon; /* at which energy gap the SA starts */ - real SAoff; /* at which energy gap the SA stops */ - int SAsteps; /* stepwise switchinng on the SA */ - int SAstep; /* current state of SA */ - int CIdim; - real *CIvec1; - real *CIvec2; - real *CIvec1old; - real *CIvec2old; - ivec SHbasis; - int CASelectrons; - int CASorbitals; + gmx_bool bSH; /* surface hopping (diabatic only) */ + real SAon; /* at which energy gap the SA starts */ + real SAoff; /* at which energy gap the SA stops */ + int SAsteps; /* stepwise switchinng on the SA */ + int SAstep; /* current state of SA */ + int CIdim; + real* CIvec1; + real* CIvec2; + real* CIvec1old; + real* CIvec2old; + ivec SHbasis; + int CASelectrons; + int CASorbitals; } t_QMrec; -typedef struct { - int nrMMatoms; /* nr of MM atoms, updated every step*/ - rvec *xMM; /* shifted to center of box */ - int *indexMM; /* atom i = atom indexMM[I] in mdrun */ - real *MMcharges; /* MM point charges in std QMMM calc.*/ - int *shiftMM; - int *MMatomtype; /* only important for semi-emp. */ - real scalefactor; +typedef struct +{ + int nrMMatoms; /* nr of MM atoms, updated every step*/ + rvec* xMM; /* shifted to center of box */ + int* indexMM; /* atom i = atom indexMM[I] in mdrun */ + real* MMcharges; /* MM point charges in std QMMM calc.*/ + int* shiftMM; + int* MMatomtype; /* only important for semi-emp. */ + real scalefactor; } t_MMrec; -typedef struct t_QMMMrec { - int QMMMscheme; /* ONIOM (multi-layer) or normal */ - int nrQMlayers; /* number of QM layers (total layers +1 (MM)) */ - t_QMrec **qm; /* atoms and run params for each QM group */ - t_MMrec *mm; /* there can only be one MM subsystem ! */ +typedef struct t_QMMMrec +{ + int QMMMscheme; /* ONIOM (multi-layer) or normal */ + int nrQMlayers; /* number of QM layers (total layers +1 (MM)) */ + t_QMrec** qm; /* atoms and run params for each QM group */ + t_MMrec* mm; /* there can only be one MM subsystem ! */ } t_QMMMrec; -void atomic_number(int nr, char ***atomtype, int *nucnum); +void atomic_number(int nr, char*** atomtype, int* nucnum); -t_QMMMrec *mk_QMMMrec(); +t_QMMMrec* mk_QMMMrec(); /* allocates memory for QMMMrec */ -void init_QMMMrec(const t_commrec *cr, - const gmx_mtop_t *mtop, - const t_inputrec *ir, - const t_forcerec *fr); +void init_QMMMrec(const t_commrec* cr, const gmx_mtop_t* mtop, const t_inputrec* ir, const t_forcerec* fr); /* init_QMMMrec initializes the QMMM record. From * topology->atoms.atomname and topology->atoms.atomtype the atom @@ -132,20 +132,14 @@ void init_QMMMrec(const t_commrec *cr, * resp. inputrec->QMmult the nelecs and multiplicity are determined * and md->cQMMM gives numbers of the MM and QM atoms */ -void update_QMMMrec(const t_commrec *cr, - const t_forcerec *fr, - const rvec *x, - const t_mdatoms *md, - const matrix box); +void update_QMMMrec(const t_commrec* cr, const t_forcerec* fr, const rvec* x, const t_mdatoms* md, const matrix box); /* update_QMMMrec fills the MM stuff in QMMMrec. The MM atoms are * taken froom the neighbourlists of the QM atoms. In a QMMM run this * routine should be called at every step, since it updates the MM * elements of the t_QMMMrec struct. */ -real calculate_QMMM(const t_commrec *cr, - gmx::ForceWithShiftForces *forceWithShiftForces, - const t_forcerec *fr); +real calculate_QMMM(const t_commrec* cr, gmx::ForceWithShiftForces* forceWithShiftForces, const t_forcerec* fr); /* QMMM computes the QM forces. This routine makes either function * calls to gmx QM routines (derived from MOPAC7 (semi-emp.) and MPQC @@ -161,7 +155,7 @@ real calculate_QMMM(const t_commrec *cr, * \param[in] ir Inputrec used in simulation. * \returns Vector of atoms. */ -std::vector qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop); +std::vector qmmmAtomIndices(const t_inputrec& ir, const gmx_mtop_t& mtop); /*! \brief * Remove charges from QMMM atoms. @@ -169,6 +163,6 @@ std::vector qmmmAtomIndices(const t_inputrec &ir, const gmx_mtop_t &mtop); * \param[in] mtop Topology used for removing atoms. * \param[in] qmmmAtoms ArrayRef to vector conatining qmmm atom indices. */ -void removeQmmmAtomCharges(gmx_mtop_t *mtop, gmx::ArrayRef qmmmAtoms); +void removeQmmmAtomCharges(gmx_mtop_t* mtop, gmx::ArrayRef qmmmAtoms); #endif diff --git a/src/gromacs/mdlib/rbin.cpp b/src/gromacs/mdlib/rbin.cpp index 86e6db7585..0e8dc749bc 100644 --- a/src/gromacs/mdlib/rbin.cpp +++ b/src/gromacs/mdlib/rbin.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,16 +43,16 @@ #include "gromacs/utility/arrayref.h" #include "gromacs/utility/smalloc.h" -t_bin *mk_bin() +t_bin* mk_bin() { - t_bin *b; + t_bin* b; snew(b, 1); return b; } -void destroy_bin(t_bin *b) +void destroy_bin(t_bin* b) { if (b->maxreal > 0) { @@ -62,79 +62,79 @@ void destroy_bin(t_bin *b) sfree(b); } -void reset_bin(t_bin *b) +void reset_bin(t_bin* b) { b->nreal = 0; } -int add_binr(t_bin *b, int nr, const real r[]) +int add_binr(t_bin* b, int nr, const real r[]) { #define MULT 4 int i, rest, index; - double *rbuf; + double* rbuf; - if (b->nreal+nr > b->maxreal) + if (b->nreal + nr > b->maxreal) { - b->maxreal = b->nreal+nr; + b->maxreal = b->nreal + nr; rest = b->maxreal % MULT; if (rest != 0) { - b->maxreal += MULT-rest; + b->maxreal += MULT - rest; } srenew(b->rbuf, b->maxreal); } /* Copy pointer */ - rbuf = b->rbuf+b->nreal; + rbuf = b->rbuf + b->nreal; #if (defined __ICC && __ICC >= 1500 || defined __ICL && __ICL >= 1500) && defined __MIC__ -#pragma novector /* Work-around for incorrect vectorization */ +# pragma novector /* Work-around for incorrect vectorization */ #endif for (i = 0; (i < nr); i++) { rbuf[i] = r[i]; } - index = b->nreal; + index = b->nreal; b->nreal += nr; return index; } -int add_binr(t_bin *b, gmx::ArrayRef r) +int add_binr(t_bin* b, gmx::ArrayRef r) { return add_binr(b, r.size(), r.data()); } -int add_bind(t_bin *b, int nr, const double r[]) +int add_bind(t_bin* b, int nr, const double r[]) { #define MULT 4 int i, rest, index; - double *rbuf; + double* rbuf; - if (b->nreal+nr > b->maxreal) + if (b->nreal + nr > b->maxreal) { - b->maxreal = b->nreal+nr; + b->maxreal = b->nreal + nr; rest = b->maxreal % MULT; if (rest != 0) { - b->maxreal += MULT-rest; + b->maxreal += MULT - rest; } srenew(b->rbuf, b->maxreal); } /* Copy pointer */ - rbuf = b->rbuf+b->nreal; + rbuf = b->rbuf + b->nreal; for (i = 0; (i < nr); i++) { rbuf[i] = r[i]; } - index = b->nreal; + index = b->nreal; b->nreal += nr; return index; } -void sum_bin(t_bin *b, const t_commrec *cr) +void sum_bin(t_bin* b, const t_commrec* cr) { int i; @@ -145,29 +145,29 @@ void sum_bin(t_bin *b, const t_commrec *cr) gmx_sumd(b->maxreal, b->rbuf, cr); } -void extract_binr(t_bin *b, int index, int nr, real r[]) +void extract_binr(t_bin* b, int index, int nr, real r[]) { int i; - double *rbuf; + double* rbuf; - rbuf = b->rbuf+index; + rbuf = b->rbuf + index; for (i = 0; (i < nr); i++) { r[i] = rbuf[i]; } } -void extract_binr(t_bin *b, int index, gmx::ArrayRef r) +void extract_binr(t_bin* b, int index, gmx::ArrayRef r) { extract_binr(b, index, r.size(), r.data()); } -void extract_bind(t_bin *b, int index, int nr, double r[]) +void extract_bind(t_bin* b, int index, int nr, double r[]) { int i; - double *rbuf; + double* rbuf; - rbuf = b->rbuf+index; + rbuf = b->rbuf + index; for (i = 0; (i < nr); i++) { r[i] = rbuf[i]; diff --git a/src/gromacs/mdlib/rbin.h b/src/gromacs/mdlib/rbin.h index 129475cde5..20cf110ab7 100644 --- a/src/gromacs/mdlib/rbin.h +++ b/src/gromacs/mdlib/rbin.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,32 +42,33 @@ struct t_commrec; -typedef struct { +typedef struct +{ int nreal; int maxreal; - double *rbuf; + double* rbuf; } t_bin; -t_bin *mk_bin(); +t_bin* mk_bin(); /* Create a real bin */ -void destroy_bin(t_bin *b); +void destroy_bin(t_bin* b); /* Destroy the bin structure */ -void reset_bin(t_bin *b); +void reset_bin(t_bin* b); /* Reset number of entries to zero */ -int add_binr(t_bin *b, int nr, const real r[]); -int add_binr(t_bin *b, gmx::ArrayRef r); -int add_bind(t_bin *b, int nr, const double r[]); +int add_binr(t_bin* b, int nr, const real r[]); +int add_binr(t_bin* b, gmx::ArrayRef r); +int add_bind(t_bin* b, int nr, const double r[]); /* Add reals to the bin. Returns index */ -void sum_bin(t_bin *b, const t_commrec *cr); +void sum_bin(t_bin* b, const t_commrec* cr); /* Globally sum the reals in the bin */ -void extract_binr(t_bin *b, int index, int nr, real r[]); -void extract_binr(t_bin *b, int index, gmx::ArrayRef r); -void extract_bind(t_bin *b, int index, int nr, double r[]); +void extract_binr(t_bin* b, int index, int nr, real r[]); +void extract_binr(t_bin* b, int index, gmx::ArrayRef r); +void extract_bind(t_bin* b, int index, int nr, double r[]); /* Extract values from the bin, starting from index (see add_bin) */ #endif diff --git a/src/gromacs/mdlib/resethandler.cpp b/src/gromacs/mdlib/resethandler.cpp index 7d1f7ed8b9..3625d4a0dd 100644 --- a/src/gromacs/mdlib/resethandler.cpp +++ b/src/gromacs/mdlib/resethandler.cpp @@ -72,16 +72,15 @@ static inline ResetSignal convertToResetSignal(signed char sig) return sig >= 1 ? ResetSignal::doResetCounters : ResetSignal::noSignal; } -ResetHandler::ResetHandler( - compat::not_null signal, - bool simulationsShareState, - int64_t nsteps, - bool isMaster, - bool resetHalfway, - real maximumHoursToRun, - const MDLogger &mdlog, - gmx_wallcycle_t wcycle, - gmx_walltime_accounting_t walltime_accounting) : +ResetHandler::ResetHandler(compat::not_null signal, + bool simulationsShareState, + int64_t nsteps, + bool isMaster, + bool resetHalfway, + real maximumHoursToRun, + const MDLogger& mdlog, + gmx_wallcycle_t wcycle, + gmx_walltime_accounting_t walltime_accounting) : signal_(*signal), rankCanSetSignal_(false), simulationNeedsReset_(false), @@ -93,9 +92,11 @@ ResetHandler::ResetHandler( } if (resetHalfway) { - GMX_LOG(mdlog.info).asParagraph(). - appendText( - "The -resethway functionality is deprecated, and may be removed in a future version."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "The -resethway functionality is deprecated, and may be removed in a " + "future version."); if (nsteps > 0) { /* Signal to reset the counters half the simulation steps. */ @@ -133,22 +134,21 @@ bool ResetHandler::setSignalImpl(gmx_walltime_accounting_t walltime_accounting) return false; } -bool ResetHandler::resetCountersImpl( - int64_t step, - int64_t step_rel, - const MDLogger &mdlog, - FILE *fplog, - const t_commrec *cr, - nonbonded_verlet_t *nbv, - t_nrnb *nrnb, - const gmx_pme_t *pme, - const pme_load_balancing_t *pme_loadbal, - gmx_wallcycle_t wcycle, - gmx_walltime_accounting_t walltime_accounting) +bool ResetHandler::resetCountersImpl(int64_t step, + int64_t step_rel, + const MDLogger& mdlog, + FILE* fplog, + const t_commrec* cr, + nonbonded_verlet_t* nbv, + t_nrnb* nrnb, + const gmx_pme_t* pme, + const pme_load_balancing_t* pme_loadbal, + gmx_wallcycle_t wcycle, + gmx_walltime_accounting_t walltime_accounting) { /* Reset either if signal has been passed, or if reset step has been reached */ - if (convertToResetSignal(signal_.set) == ResetSignal::doResetCounters || - step_rel == wcycle_get_reset_counters(wcycle)) + if (convertToResetSignal(signal_.set) == ResetSignal::doResetCounters + || step_rel == wcycle_get_reset_counters(wcycle)) { if (pme_loadbal_is_active(pme_loadbal)) { @@ -161,18 +161,22 @@ bool ResetHandler::resetCountersImpl( * TODO consider fixing this by delaying the reset * until after load balancing completes, * e.g. https://gerrit.gromacs.org/#/c/4964/2 */ - gmx_fatal(FARGS, "PME tuning was still active when attempting to " - "reset mdrun counters at step %" PRId64 ". Try " + gmx_fatal(FARGS, + "PME tuning was still active when attempting to " + "reset mdrun counters at step %" PRId64 + ". Try " "resetting counters later in the run, e.g. with gmx " - "mdrun -resetstep.", step); + "mdrun -resetstep.", + step); } char sbuf[STEPSTRSIZE]; /* Reset all the counters related to performance over the run */ - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "step %s: resetting all time and cycle counters", - gmx_step_str(step, sbuf)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted("step %s: resetting all time and cycle counters", + gmx_step_str(step, sbuf)); if (nbv && nbv->useGpu()) { @@ -218,4 +222,4 @@ bool ResetHandler::resetCountersImpl( return false; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/resethandler.h b/src/gromacs/mdlib/resethandler.h index 11a0c462f4..2185c2b70a 100644 --- a/src/gromacs/mdlib/resethandler.h +++ b/src/gromacs/mdlib/resethandler.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -89,7 +89,8 @@ namespace gmx */ enum class ResetSignal { - noSignal = 0, doResetCounters = 1 + noSignal = 0, + doResetCounters = 1 }; /*! \libinternal @@ -101,103 +102,98 @@ enum class ResetSignal */ class ResetHandler final { - public: - /*! \brief ResetHandler constructor - * - * Needs a pointer to the signal to communicate between ranks, information on whether - * multiple simulations need to be synchronized, and additional data to determine - * whether counter resetting takes place at all, and whether the current rank can set - * the resetting signal. - */ - ResetHandler( - compat::not_null signal, - bool simulationsShareState, - int64_t nsteps, - bool isMaster, - bool resetHalfway, - real maximumHoursToRun, - const MDLogger &mdlog, - gmx_wallcycle *wcycle, - gmx_walltime_accounting *walltime_accounting); +public: + /*! \brief ResetHandler constructor + * + * Needs a pointer to the signal to communicate between ranks, information on whether + * multiple simulations need to be synchronized, and additional data to determine + * whether counter resetting takes place at all, and whether the current rank can set + * the resetting signal. + */ + ResetHandler(compat::not_null signal, + bool simulationsShareState, + int64_t nsteps, + bool isMaster, + bool resetHalfway, + real maximumHoursToRun, + const MDLogger& mdlog, + gmx_wallcycle* wcycle, + gmx_walltime_accounting* walltime_accounting); - /*! \brief Decides whether a reset signal needs to be set - * - * Reset signal is set if run time is greater than 49.5% of maximal run time. - */ - void setSignal(gmx_walltime_accounting *walltime_accounting) + /*! \brief Decides whether a reset signal needs to be set + * + * Reset signal is set if run time is greater than 49.5% of maximal run time. + */ + void setSignal(gmx_walltime_accounting* walltime_accounting) + { + if (rankCanSetSignal_) { - if (rankCanSetSignal_) + if (setSignalImpl(walltime_accounting)) { - if (setSignalImpl(walltime_accounting)) - { - // need to set the reset signal only once - rankCanSetSignal_ = false; - } + // need to set the reset signal only once + rankCanSetSignal_ = false; } } + } - /*! \brief Decides whether the counters are reset, and performs the reset if needed - * - * The counters are reset if - * - * * the signal for resetting was received, or - * * the (local) number of steps reached the defined counter reset step. - * - * Note that even if two reset conditions are present (at a specific step and a - * specific time), the reset will only take place once, whenever the first condition - * is met. - */ - void resetCounters( - int64_t step, - int64_t step_rel, - const MDLogger &mdlog, - FILE *fplog, - const t_commrec *cr, - nonbonded_verlet_t *nbv, - t_nrnb *nrnb, - const gmx_pme_t *pme, - const pme_load_balancing_t *pme_loadbal, - gmx_wallcycle *wcycle, - gmx_walltime_accounting *walltime_accounting) + /*! \brief Decides whether the counters are reset, and performs the reset if needed + * + * The counters are reset if + * + * * the signal for resetting was received, or + * * the (local) number of steps reached the defined counter reset step. + * + * Note that even if two reset conditions are present (at a specific step and a + * specific time), the reset will only take place once, whenever the first condition + * is met. + */ + void resetCounters(int64_t step, + int64_t step_rel, + const MDLogger& mdlog, + FILE* fplog, + const t_commrec* cr, + nonbonded_verlet_t* nbv, + t_nrnb* nrnb, + const gmx_pme_t* pme, + const pme_load_balancing_t* pme_loadbal, + gmx_wallcycle* wcycle, + gmx_walltime_accounting* walltime_accounting) + { + if (simulationNeedsReset_) { - if (simulationNeedsReset_) + if (resetCountersImpl(step, step_rel, mdlog, fplog, cr, nbv, nrnb, pme, pme_loadbal, + wcycle, walltime_accounting)) { - if (resetCountersImpl( - step, step_rel, mdlog, fplog, - cr, nbv, nrnb, pme, pme_loadbal, - wcycle, walltime_accounting)) - { - // need to reset the counters only once - simulationNeedsReset_ = false; - rankCanSetSignal_ = false; - } + // need to reset the counters only once + simulationNeedsReset_ = false; + rankCanSetSignal_ = false; } } + } - private: - //! Implementation of the setSignal() function - bool setSignalImpl(gmx_walltime_accounting *walltime_accounting); +private: + //! Implementation of the setSignal() function + bool setSignalImpl(gmx_walltime_accounting* walltime_accounting); - //! Implementation of the resetCounters() function - bool resetCountersImpl( - int64_t step, - int64_t step_rel, - const MDLogger &mdlog, - FILE *fplog, - const t_commrec *cr, - nonbonded_verlet_t *nbv, - t_nrnb *nrnb, - const gmx_pme_t *pme, - const pme_load_balancing_t *pme_loadbal, - gmx_wallcycle *wcycle, - gmx_walltime_accounting *walltime_accounting); + //! Implementation of the resetCounters() function + bool resetCountersImpl(int64_t step, + int64_t step_rel, + const MDLogger& mdlog, + FILE* fplog, + const t_commrec* cr, + nonbonded_verlet_t* nbv, + t_nrnb* nrnb, + const gmx_pme_t* pme, + const pme_load_balancing_t* pme_loadbal, + gmx_wallcycle* wcycle, + gmx_walltime_accounting* walltime_accounting); - SimulationSignal &signal_; + SimulationSignal& signal_; - bool rankCanSetSignal_; - bool simulationNeedsReset_; - const real maximumHoursToRun_; + bool rankCanSetSignal_; + bool simulationNeedsReset_; + const real maximumHoursToRun_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDLIB_RESETHANDLER_H diff --git a/src/gromacs/mdlib/rf_util.cpp b/src/gromacs/mdlib/rf_util.cpp index deb1285a59..fc4822182b 100644 --- a/src/gromacs/mdlib/rf_util.cpp +++ b/src/gromacs/mdlib/rf_util.cpp @@ -50,29 +50,27 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/pleasecite.h" -void calc_rffac(FILE *fplog, real eps_r, real eps_rf, real Rc, - real *krf, real *crf) +void calc_rffac(FILE* fplog, real eps_r, real eps_rf, real Rc, real* krf, real* crf) { /* eps == 0 signals infinite dielectric */ if (eps_rf == 0) { - *krf = 1/(2*Rc*Rc*Rc); + *krf = 1 / (2 * Rc * Rc * Rc); } else { - *krf = (eps_rf - eps_r)/(2*eps_rf + eps_r)/(Rc*Rc*Rc); + *krf = (eps_rf - eps_r) / (2 * eps_rf + eps_r) / (Rc * Rc * Rc); } - *crf = 1/Rc + *krf*Rc*Rc; + *crf = 1 / Rc + *krf * Rc * Rc; if (fplog) { - fprintf(fplog, "%s:\n" + fprintf(fplog, + "%s:\n" "epsRF = %g, rc = %g, krf = %g, crf = %g, epsfac = %g\n", - eel_names[eelRF], eps_rf, Rc, *krf, *crf, ONE_4PI_EPS0/eps_r); + eel_names[eelRF], eps_rf, Rc, *krf, *crf, ONE_4PI_EPS0 / eps_r); // Make sure we don't lose resolution in pow() by casting real arg to double - real rmin = gmx::invcbrt(static_cast(*krf*2.0)); - fprintf(fplog, - "The electrostatics potential has its minimum at r = %g\n", - rmin); + real rmin = gmx::invcbrt(static_cast(*krf * 2.0)); + fprintf(fplog, "The electrostatics potential has its minimum at r = %g\n", rmin); } } diff --git a/src/gromacs/mdlib/rf_util.h b/src/gromacs/mdlib/rf_util.h index a27fc16003..653c30ea27 100644 --- a/src/gromacs/mdlib/rf_util.h +++ b/src/gromacs/mdlib/rf_util.h @@ -44,9 +44,7 @@ struct gmx_mtop_t; struct t_forcerec; struct t_inputrec; -void calc_rffac(FILE *fplog, real eps_r, real eps_rf, - real Rc, - real *krf, real *crf); +void calc_rffac(FILE* fplog, real eps_r, real eps_rf, real Rc, real* krf, real* crf); /* Determine the reaction-field constants */ #endif diff --git a/src/gromacs/mdlib/settle.cpp b/src/gromacs/mdlib/settle.cpp index 3263c0ddd2..df62c5c213 100644 --- a/src/gromacs/mdlib/settle.cpp +++ b/src/gromacs/mdlib/settle.cpp @@ -73,15 +73,15 @@ namespace gmx struct settleparam_t { - real mO; - real mH; - real wh; - real dOH; - real dHH; - real ra; - real rb; - real rc; - real irc2; + real mO; + real mH; + real wh; + real dOH; + real dHH; + real ra; + real rb; + real rc; + real irc2; /* For projection */ real imO; real imH; @@ -92,37 +92,36 @@ struct settleparam_t struct settledata { - settleparam_t massw; /* Parameters for SETTLE for coordinates */ - settleparam_t mass1; /* Parameters with all masses 1, for forces */ + settleparam_t massw; /* Parameters for SETTLE for coordinates */ + settleparam_t mass1; /* Parameters with all masses 1, for forces */ - int nsettle; /* The number of settles on our rank */ - int *ow1; /* Index to OW1 atoms, size nsettle + SIMD padding */ - int *hw2; /* Index to HW2 atoms, size nsettle + SIMD padding */ - int *hw3; /* Index to HW3 atoms, size nsettle + SIMD padding */ - real *virfac; /* Virial factor 0 or 1, size nsettle + SIMD pad. */ - int nalloc; /* Allocation size of ow1, hw2, hw3, virfac */ + int nsettle; /* The number of settles on our rank */ + int* ow1; /* Index to OW1 atoms, size nsettle + SIMD padding */ + int* hw2; /* Index to HW2 atoms, size nsettle + SIMD padding */ + int* hw3; /* Index to HW3 atoms, size nsettle + SIMD padding */ + real* virfac; /* Virial factor 0 or 1, size nsettle + SIMD pad. */ + int nalloc; /* Allocation size of ow1, hw2, hw3, virfac */ - bool bUseSimd; /* Use SIMD intrinsics code, if possible */ + bool bUseSimd; /* Use SIMD intrinsics code, if possible */ }; //! Initializes a projection matrix. -static void init_proj_matrix(real invmO, real invmH, real dOH, real dHH, - matrix inverseCouplingMatrix) +static void init_proj_matrix(real invmO, real invmH, real dOH, real dHH, matrix inverseCouplingMatrix) { /* We normalize the inverse masses with invmO for the matrix inversion. * so we can keep using masses of almost zero for frozen particles, * without running out of the float range in invertMatrix. */ double invmORelative = 1.0; - double invmHRelative = invmH/static_cast(invmO); - double distanceRatio = dHH/static_cast(dOH); + double invmHRelative = invmH / static_cast(invmO); + double distanceRatio = dHH / static_cast(dOH); /* Construct the constraint coupling matrix */ matrix mat; mat[0][0] = invmORelative + invmHRelative; - mat[0][1] = invmORelative*(1.0 - 0.5*gmx::square(distanceRatio)); - mat[0][2] = invmHRelative*0.5*distanceRatio; + mat[0][1] = invmORelative * (1.0 - 0.5 * gmx::square(distanceRatio)); + mat[0][2] = invmHRelative * 0.5 * distanceRatio; mat[1][1] = mat[0][0]; mat[1][2] = mat[0][2]; mat[2][2] = invmHRelative + invmHRelative; @@ -132,13 +131,11 @@ static void init_proj_matrix(real invmO, real invmH, real dOH, real dHH, invertMatrix(mat, inverseCouplingMatrix); - msmul(inverseCouplingMatrix, 1/invmO, inverseCouplingMatrix); + msmul(inverseCouplingMatrix, 1 / invmO, inverseCouplingMatrix); } //! Initializes settle parameters. -static void settleparam_init(settleparam_t *p, - real mO, real mH, real invmO, real invmH, - real dOH, real dHH) +static void settleparam_init(settleparam_t* p, real mO, real mH, real invmO, real invmH, real dOH, real dHH) { /* We calculate parameters in double precision to minimize errors. * The velocity correction applied during SETTLE coordinate constraining @@ -149,45 +146,43 @@ static void settleparam_init(settleparam_t *p, p->mO = mO; p->mH = mH; - wohh = mO + 2.0*mH; - p->wh = mH/wohh; + wohh = mO + 2.0 * mH; + p->wh = mH / wohh; p->dOH = dOH; p->dHH = dHH; - double rc = dHH/2.0; - double ra = 2.0*mH*std::sqrt(dOH*dOH - rc*rc)/wohh; - p->rb = std::sqrt(dOH*dOH - rc*rc) - ra; + double rc = dHH / 2.0; + double ra = 2.0 * mH * std::sqrt(dOH * dOH - rc * rc) / wohh; + p->rb = std::sqrt(dOH * dOH - rc * rc) - ra; p->rc = rc; p->ra = ra; - p->irc2 = 1.0/dHH; + p->irc2 = 1.0 / dHH; /* For projection: inverse masses and coupling matrix inversion */ - p->imO = invmO; - p->imH = invmH; + p->imO = invmO; + p->imH = invmH; - p->invdOH = 1.0/dOH; - p->invdHH = 1.0/dHH; + p->invdOH = 1.0 / dOH; + p->invdHH = 1.0 / dHH; init_proj_matrix(invmO, invmH, dOH, dHH, p->invmat); if (debug) { - fprintf(debug, "wh =%g, rc = %g, ra = %g\n", - p->wh, p->rc, p->ra); - fprintf(debug, "rb = %g, irc2 = %g, dHH = %g, dOH = %g\n", - p->rb, p->irc2, p->dHH, p->dOH); + fprintf(debug, "wh =%g, rc = %g, ra = %g\n", p->wh, p->rc, p->ra); + fprintf(debug, "rb = %g, irc2 = %g, dHH = %g, dOH = %g\n", p->rb, p->irc2, p->dHH, p->dOH); } } -settledata *settle_init(const gmx_mtop_t &mtop) +settledata* settle_init(const gmx_mtop_t& mtop) { /* Check that we have only one settle type */ - int settle_type = -1; - gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); - int nmol; - const int nral1 = 1 + NRAL(F_SETTLE); - while (const InteractionLists *ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) + int settle_type = -1; + gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); + int nmol; + const int nral1 = 1 + NRAL(F_SETTLE); + while (const InteractionLists* ilists = gmx_mtop_ilistloop_next(iloop, &nmol)) { - const InteractionList &ilist = (*ilists)[F_SETTLE]; + const InteractionList& ilist = (*ilists)[F_SETTLE]; for (int i = 0; i < ilist.size(); i += nral1) { if (settle_type == -1) @@ -197,10 +192,12 @@ settledata *settle_init(const gmx_mtop_t &mtop) else if (ilist.iatoms[i] != settle_type) { gmx_fatal(FARGS, - "The [molecules] section of your topology specifies more than one block of\n" + "The [molecules] section of your topology specifies more than one block " + "of\n" "a [moleculetype] with a [settles] block. Only one such is allowed.\n" "If you are trying to partition your solvent into different *groups*\n" - "(e.g. for freezing, T-coupling, etc.), you are using the wrong approach. Index\n" + "(e.g. for freezing, T-coupling, etc.), you are using the wrong " + "approach. Index\n" "files specify groups. Otherwise, you may wish to change the least-used\n" "block of molecules with SETTLE constraints into 3 normal constraints."); } @@ -208,7 +205,7 @@ settledata *settle_init(const gmx_mtop_t &mtop) } GMX_RELEASE_ASSERT(settle_type >= 0, "settle_init called without settles"); - settledata *settled; + settledata* settled; snew(settled, 1); @@ -234,7 +231,7 @@ settledata *settle_init(const gmx_mtop_t &mtop) return settled; } -void settle_free(settledata *settled) +void settle_free(settledata* settled) { sfree_aligned(settled->ow1); sfree_aligned(settled->hw2); @@ -243,9 +240,7 @@ void settle_free(settledata *settled) sfree(settled); } -void settle_set_constraints(settledata *settled, - const t_ilist *il_settle, - const t_mdatoms &mdatoms) +void settle_set_constraints(settledata* settled, const t_ilist* il_settle, const t_mdatoms& mdatoms) { #if GMX_SIMD_HAVE_REAL const int pack_size = GMX_SIMD_REAL_WIDTH; @@ -253,25 +248,21 @@ void settle_set_constraints(settledata *settled, const int pack_size = 1; #endif - const int nral1 = 1 + NRAL(F_SETTLE); - int nsettle = il_settle->nr/nral1; - settled->nsettle = nsettle; + const int nral1 = 1 + NRAL(F_SETTLE); + int nsettle = il_settle->nr / nral1; + settled->nsettle = nsettle; if (nsettle > 0) { - const t_iatom *iatoms = il_settle->iatoms; + const t_iatom* iatoms = il_settle->iatoms; /* Here we initialize the normal SETTLE parameters */ if (settled->massw.mO < 0) { int firstO = iatoms[1]; int firstH = iatoms[2]; - settleparam_init(&settled->massw, - mdatoms.massT[firstO], - mdatoms.massT[firstH], - mdatoms.invmass[firstO], - mdatoms.invmass[firstH], - settled->mass1.dOH, + settleparam_init(&settled->massw, mdatoms.massT[firstO], mdatoms.massT[firstH], + mdatoms.invmass[firstO], mdatoms.invmass[firstH], settled->mass1.dOH, settled->mass1.dHH); } @@ -290,20 +281,20 @@ void settle_set_constraints(settledata *settled, for (int i = 0; i < nsettle; i++) { - settled->ow1[i] = iatoms[i*nral1 + 1]; - settled->hw2[i] = iatoms[i*nral1 + 2]; - settled->hw3[i] = iatoms[i*nral1 + 3]; + settled->ow1[i] = iatoms[i * nral1 + 1]; + settled->hw2[i] = iatoms[i * nral1 + 2]; + settled->hw3[i] = iatoms[i * nral1 + 3]; /* We should avoid double counting of virial contributions for * SETTLEs that appear in multiple DD domains, so we only count * the contribution on the home range of the oxygen atom. */ - settled->virfac[i] = (iatoms[i*nral1 + 1] < mdatoms.homenr ? 1 : 0); + settled->virfac[i] = (iatoms[i * nral1 + 1] < mdatoms.homenr ? 1 : 0); } /* Pack the index array to the full SIMD width with copies from * the last normal entry, but with no virial contribution. */ - int end_packed = ((nsettle + pack_size - 1)/pack_size)*pack_size; + int end_packed = ((nsettle + pack_size - 1) / pack_size) * pack_size; for (int i = nsettle; i < end_packed; i++) { settled->ow1[i] = settled->ow1[nsettle - 1]; @@ -314,19 +305,23 @@ void settle_set_constraints(settledata *settled, } } -void settle_proj(settledata *settled, ConstraintVariable econq, - int nsettle, const t_iatom iatoms[], - const t_pbc *pbc, - const rvec x[], - rvec *der, rvec *derp, - int calcvir_atom_end, tensor vir_r_m_dder) +void settle_proj(settledata* settled, + ConstraintVariable econq, + int nsettle, + const t_iatom iatoms[], + const t_pbc* pbc, + const rvec x[], + rvec* der, + rvec* derp, + int calcvir_atom_end, + tensor vir_r_m_dder) { /* Settle for projection out constraint components * of derivatives of the coordinates. * Berk Hess 2008-1-10 */ - settleparam_t *p; + settleparam_t* p; real imO, imH, dOH, dHH, invdOH, invdHH; matrix invmat; int i, m, m2, ow1, hw2, hw3; @@ -342,8 +337,8 @@ void settle_proj(settledata *settled, ConstraintVariable econq, { p = &settled->massw; } - imO = p->imO; - imH = p->imH; + imO = p->imO; + imH = p->imH; copy_mat(p->invmat, invmat); dOH = p->dOH; dHH = p->dHH; @@ -354,9 +349,9 @@ void settle_proj(settledata *settled, ConstraintVariable econq, for (i = 0; i < nsettle; i++) { - ow1 = iatoms[i*nral1 + 1]; - hw2 = iatoms[i*nral1 + 2]; - hw3 = iatoms[i*nral1 + 3]; + ow1 = iatoms[i * nral1 + 1]; + hw2 = iatoms[i * nral1 + 2]; + hw3 = iatoms[i * nral1 + 3]; if (pbc == nullptr) { @@ -379,9 +374,9 @@ void settle_proj(settledata *settled, ConstraintVariable econq, clear_rvec(dc); for (m = 0; m < DIM; m++) { - dc[0] += (der[ow1][m] - der[hw2][m])*roh2[m]; - dc[1] += (der[ow1][m] - der[hw3][m])*roh3[m]; - dc[2] += (der[hw2][m] - der[hw3][m])*rhh [m]; + dc[0] += (der[ow1][m] - der[hw2][m]) * roh2[m]; + dc[1] += (der[ow1][m] - der[hw3][m]) * roh3[m]; + dc[2] += (der[hw2][m] - der[hw3][m]) * rhh[m]; } /* 27 flops */ @@ -392,9 +387,9 @@ void settle_proj(settledata *settled, ConstraintVariable econq, /* Subtract the corrections from derp */ for (m = 0; m < DIM; m++) { - derp[ow1][m] -= imO*( fc[0]*roh2[m] + fc[1]*roh3[m]); - derp[hw2][m] -= imH*(-fc[0]*roh2[m] + fc[2]*rhh [m]); - derp[hw3][m] -= imH*(-fc[1]*roh3[m] - fc[2]*rhh [m]); + derp[ow1][m] -= imO * (fc[0] * roh2[m] + fc[1] * roh3[m]); + derp[hw2][m] -= imH * (-fc[0] * roh2[m] + fc[2] * rhh[m]); + derp[hw3][m] -= imH * (-fc[1] * roh3[m] - fc[2] * rhh[m]); } /* 45 flops */ @@ -409,10 +404,9 @@ void settle_proj(settledata *settled, ConstraintVariable econq, { for (m2 = 0; m2 < DIM; m2++) { - vir_r_m_dder[m][m2] += - dOH*roh2[m]*roh2[m2]*fc[0] + - dOH*roh3[m]*roh3[m2]*fc[1] + - dHH*rhh [m]*rhh [m2]*fc[2]; + vir_r_m_dder[m][m2] += dOH * roh2[m] * roh2[m2] * fc[0] + + dOH * roh3[m] * roh3[m2] * fc[1] + + dHH * rhh[m] * rhh[m2] * fc[2]; } } } @@ -421,17 +415,17 @@ void settle_proj(settledata *settled, ConstraintVariable econq, /*! \brief The actual settle code, templated for real/SimdReal and for optimization */ -template -static void settleTemplate(const settledata *settled, - int settleStart, int settleEnd, - const TypePbc pbc, - const real *x, real *xprime, - real invdt, real * gmx_restrict v, - tensor vir_r_m_dr, - bool *bErrorHasOccurred) +template +static void settleTemplate(const settledata* settled, + int settleStart, + int settleEnd, + const TypePbc pbc, + const real* x, + real* xprime, + real invdt, + real* gmx_restrict v, + tensor vir_r_m_dr, + bool* bErrorHasOccurred) { /* ******************************************************************* */ /* ** */ @@ -449,11 +443,11 @@ static void settleTemplate(const settledata *settled, /* ******************************************************************* */ assert(settleStart % packSize == 0); - assert(settleEnd % packSize == 0); + assert(settleEnd % packSize == 0); - TypeBool bError = TypeBool(false); + TypeBool bError = TypeBool(false); - const settleparam_t *p = &settled->massw; + const settleparam_t* p = &settled->massw; T wh = T(p->wh); T rc = T(p->rc); T ra = T(p->ra); @@ -462,9 +456,9 @@ static void settleTemplate(const settledata *settled, T mO = T(p->mO); T mH = T(p->mH); - T almost_zero = T(1e-12); + T almost_zero = T(1e-12); - T sum_r_m_dr[DIM][DIM]; + T sum_r_m_dr[DIM][DIM]; if (bCalcVirial) { @@ -483,11 +477,11 @@ static void settleTemplate(const settledata *settled, * This gives correct results, since we store (not increment) all * output, so we store the same output multiple times. */ - const int *ow1 = settled->ow1 + i; - const int *hw2 = settled->hw2 + i; - const int *hw3 = settled->hw3 + i; + const int* ow1 = settled->ow1 + i; + const int* hw2 = settled->hw2 + i; + const int* hw3 = settled->hw3 + i; - T x_ow1[DIM], x_hw2[DIM], x_hw3[DIM]; + T x_ow1[DIM], x_hw2[DIM], x_hw3[DIM]; gatherLoadUTranspose<3>(x, ow1, &x_ow1[XX], &x_ow1[YY], &x_ow1[ZZ]); gatherLoadUTranspose<3>(x, hw2, &x_hw2[XX], &x_hw2[YY], &x_hw2[ZZ]); @@ -536,12 +530,12 @@ static void settleTemplate(const settledata *settled, T b1[DIM]; for (int d = 0; d < DIM; d++) { - b1[d] = xprime_hw2[d] - com[d]; + b1[d] = xprime_hw2[d] - com[d]; } T c1[DIM]; for (int d = 0; d < DIM; d++) { - c1[d] = xprime_hw3[d] - com[d]; + c1[d] = xprime_hw3[d] - com[d]; } /* 15 flops */ @@ -593,30 +587,30 @@ static void settleTemplate(const settledata *settled, T tmp, tmp2; - T sinphi = a1d_z * gmx::invsqrt(ra*ra); + T sinphi = a1d_z * gmx::invsqrt(ra * ra); tmp2 = 1.0 - sinphi * sinphi; /* If tmp2 gets close to or beyond zero we have severly distorted * water molecules and we should terminate the simulation. * Below we take the max with almost_zero to continue the loop. */ - bError = bError || (tmp2 <= almost_zero); + bError = bError || (tmp2 <= almost_zero); tmp2 = max(tmp2, almost_zero); tmp = gmx::invsqrt(tmp2); - T cosphi = tmp2*tmp; + T cosphi = tmp2 * tmp; T sinpsi = (b1d[ZZ] - c1d[ZZ]) * irc2 * tmp; tmp2 = 1.0 - sinpsi * sinpsi; - T cospsi = tmp2*gmx::invsqrt(tmp2); + T cospsi = tmp2 * gmx::invsqrt(tmp2); /* 46 flops */ - T a2d_y = ra * cosphi; - T b2d_x = -rc * cospsi; - T t1 = -rb * cosphi; - T t2 = rc * sinpsi * sinphi; - T b2d_y = t1 - t2; - T c2d_y = t1 + t2; + T a2d_y = ra * cosphi; + T b2d_x = -rc * cospsi; + T t1 = -rb * cosphi; + T t2 = rc * sinpsi * sinphi; + T b2d_y = t1 - t2; + T c2d_y = t1 + t2; /* 7 flops */ /* --- Step3 al,be,ga --- */ @@ -625,38 +619,38 @@ static void settleTemplate(const settledata *settled, T gamma = b0d[XX] * b1d[YY] - b1d[XX] * b0d[YY] + c0d[XX] * c1d[YY] - c1d[XX] * c0d[YY]; T al2be2 = alpha * alpha + beta * beta; tmp2 = (al2be2 - gamma * gamma); - T sinthe = (alpha * gamma - beta * tmp2*gmx::invsqrt(tmp2)) * gmx::invsqrt(al2be2*al2be2); + T sinthe = (alpha * gamma - beta * tmp2 * gmx::invsqrt(tmp2)) * gmx::invsqrt(al2be2 * al2be2); /* 47 flops */ /* --- Step4 A3' --- */ tmp2 = 1.0 - sinthe * sinthe; - T costhe = tmp2*gmx::invsqrt(tmp2); + T costhe = tmp2 * gmx::invsqrt(tmp2); T a3d[DIM], b3d[DIM], c3d[DIM]; - a3d[XX] = -a2d_y * sinthe; - a3d[YY] = a2d_y * costhe; - a3d[ZZ] = a1d_z; - b3d[XX] = b2d_x * costhe - b2d_y * sinthe; - b3d[YY] = b2d_x * sinthe + b2d_y * costhe; - b3d[ZZ] = b1d[ZZ]; - c3d[XX] = -b2d_x * costhe - c2d_y * sinthe; - c3d[YY] = -b2d_x * sinthe + c2d_y * costhe; - c3d[ZZ] = c1d[ZZ]; + a3d[XX] = -a2d_y * sinthe; + a3d[YY] = a2d_y * costhe; + a3d[ZZ] = a1d_z; + b3d[XX] = b2d_x * costhe - b2d_y * sinthe; + b3d[YY] = b2d_x * sinthe + b2d_y * costhe; + b3d[ZZ] = b1d[ZZ]; + c3d[XX] = -b2d_x * costhe - c2d_y * sinthe; + c3d[YY] = -b2d_x * sinthe + c2d_y * costhe; + c3d[ZZ] = c1d[ZZ]; /* 26 flops */ /* --- Step5 A3 --- */ T a3[DIM], b3[DIM], c3[DIM]; - a3[XX] = trns1[XX]*a3d[XX] + trns1[YY]*a3d[YY] + trns1[ZZ]*a3d[ZZ]; - a3[YY] = trns2[XX]*a3d[XX] + trns2[YY]*a3d[YY] + trns2[ZZ]*a3d[ZZ]; - a3[ZZ] = trns3[XX]*a3d[XX] + trns3[YY]*a3d[YY] + trns3[ZZ]*a3d[ZZ]; - b3[XX] = trns1[XX]*b3d[XX] + trns1[YY]*b3d[YY] + trns1[ZZ]*b3d[ZZ]; - b3[YY] = trns2[XX]*b3d[XX] + trns2[YY]*b3d[YY] + trns2[ZZ]*b3d[ZZ]; - b3[ZZ] = trns3[XX]*b3d[XX] + trns3[YY]*b3d[YY] + trns3[ZZ]*b3d[ZZ]; - c3[XX] = trns1[XX]*c3d[XX] + trns1[YY]*c3d[YY] + trns1[ZZ]*c3d[ZZ]; - c3[YY] = trns2[XX]*c3d[XX] + trns2[YY]*c3d[YY] + trns2[ZZ]*c3d[ZZ]; - c3[ZZ] = trns3[XX]*c3d[XX] + trns3[YY]*c3d[YY] + trns3[ZZ]*c3d[ZZ]; + a3[XX] = trns1[XX] * a3d[XX] + trns1[YY] * a3d[YY] + trns1[ZZ] * a3d[ZZ]; + a3[YY] = trns2[XX] * a3d[XX] + trns2[YY] * a3d[YY] + trns2[ZZ] * a3d[ZZ]; + a3[ZZ] = trns3[XX] * a3d[XX] + trns3[YY] * a3d[YY] + trns3[ZZ] * a3d[ZZ]; + b3[XX] = trns1[XX] * b3d[XX] + trns1[YY] * b3d[YY] + trns1[ZZ] * b3d[ZZ]; + b3[YY] = trns2[XX] * b3d[XX] + trns2[YY] * b3d[YY] + trns2[ZZ] * b3d[ZZ]; + b3[ZZ] = trns3[XX] * b3d[XX] + trns3[YY] * b3d[YY] + trns3[ZZ] * b3d[ZZ]; + c3[XX] = trns1[XX] * c3d[XX] + trns1[YY] * c3d[YY] + trns1[ZZ] * c3d[ZZ]; + c3[YY] = trns2[XX] * c3d[XX] + trns2[YY] * c3d[YY] + trns2[ZZ] * c3d[ZZ]; + c3[ZZ] = trns3[XX] * c3d[XX] + trns3[YY] * c3d[YY] + trns3[ZZ] * c3d[ZZ]; /* 45 flops */ /* Compute and store the corrected new coordinate */ @@ -666,7 +660,7 @@ static void settleTemplate(const settledata *settled, } for (int d = 0; d < DIM; d++) { - xprime_hw2[d] = com[d] + b3[d] + sh_hw2[d];; + xprime_hw2[d] = com[d] + b3[d] + sh_hw2[d]; } for (int d = 0; d < DIM; d++) { @@ -727,26 +721,25 @@ static void settleTemplate(const settledata *settled, { /* Filter out the non-local settles */ T filter = load(settled->virfac + i); - T mOf = filter*mO; - T mHf = filter*mH; + T mOf = filter * mO; + T mHf = filter * mH; T mdo[DIM], mdb[DIM], mdc[DIM]; for (int d = 0; d < DIM; d++) { - mdb[d] = mHf*db[d]; - mdc[d] = mHf*dc[d]; - mdo[d] = mOf*da[d] + mdb[d] + mdc[d]; + mdb[d] = mHf * db[d]; + mdc[d] = mHf * dc[d]; + mdo[d] = mOf * da[d] + mdb[d] + mdc[d]; } for (int d2 = 0; d2 < DIM; d2++) { for (int d = 0; d < DIM; d++) { - sum_r_m_dr[d2][d] = sum_r_m_dr[d2][d] - - (x_ow1[d2]*mdo[d] + - dist21[d2]*mdb[d] + - dist31[d2]*mdc[d]); + sum_r_m_dr[d2][d] = + sum_r_m_dr[d2][d] + - (x_ow1[d2] * mdo[d] + dist21[d2] * mdb[d] + dist31[d2] * mdc[d]); } } /* 71 flops */ @@ -772,111 +765,81 @@ static void settleTemplate(const settledata *settled, * and instantiates the core template with instantiated booleans. */ template -static void settleTemplateWrapper(settledata *settled, - int nthread, int thread, - TypePbc pbc, - const real x[], real xprime[], - real invdt, real *v, - bool bCalcVirial, tensor vir_r_m_dr, - bool *bErrorHasOccurred) +static void settleTemplateWrapper(settledata* settled, + int nthread, + int thread, + TypePbc pbc, + const real x[], + real xprime[], + real invdt, + real* v, + bool bCalcVirial, + tensor vir_r_m_dr, + bool* bErrorHasOccurred) { /* We need to assign settles to threads in groups of pack_size */ - int numSettlePacks = (settled->nsettle + packSize - 1)/packSize; + int numSettlePacks = (settled->nsettle + packSize - 1) / packSize; /* Round the end value up to give thread 0 more work */ - int settleStart = ((numSettlePacks* thread + nthread - 1)/nthread)*packSize; - int settleEnd = ((numSettlePacks*(thread + 1) + nthread - 1)/nthread)*packSize; + int settleStart = ((numSettlePacks * thread + nthread - 1) / nthread) * packSize; + int settleEnd = ((numSettlePacks * (thread + 1) + nthread - 1) / nthread) * packSize; if (v != nullptr) { if (!bCalcVirial) { - settleTemplate - (settled, settleStart, settleEnd, - pbc, - x, xprime, - invdt, v, - nullptr, - bErrorHasOccurred); + settleTemplate( + settled, settleStart, settleEnd, pbc, x, xprime, invdt, v, nullptr, bErrorHasOccurred); } else { - settleTemplate - (settled, settleStart, settleEnd, - pbc, - x, xprime, - invdt, v, - vir_r_m_dr, - bErrorHasOccurred); + settleTemplate( + settled, settleStart, settleEnd, pbc, x, xprime, invdt, v, vir_r_m_dr, bErrorHasOccurred); } } else { if (!bCalcVirial) { - settleTemplate - (settled, settleStart, settleEnd, - pbc, - x, xprime, - invdt, v, - nullptr, - bErrorHasOccurred); + settleTemplate( + settled, settleStart, settleEnd, pbc, x, xprime, invdt, v, nullptr, bErrorHasOccurred); } else { - settleTemplate - (settled, settleStart, settleEnd, - pbc, - x, xprime, - invdt, v, - vir_r_m_dr, - bErrorHasOccurred); + settleTemplate( + settled, settleStart, settleEnd, pbc, x, xprime, invdt, v, vir_r_m_dr, bErrorHasOccurred); } } } -void csettle(settledata *settled, - int nthread, int thread, - const t_pbc *pbc, - const real x[], real xprime[], - real invdt, real *v, - bool bCalcVirial, tensor vir_r_m_dr, - bool *bErrorHasOccurred) +void csettle(settledata* settled, + int nthread, + int thread, + const t_pbc* pbc, + const real x[], + real xprime[], + real invdt, + real* v, + bool bCalcVirial, + tensor vir_r_m_dr, + bool* bErrorHasOccurred) { #if GMX_SIMD_HAVE_REAL if (settled->bUseSimd) { /* Convert the pbc struct for SIMD */ - alignas(GMX_SIMD_ALIGNMENT) real pbcSimd[9*GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real pbcSimd[9 * GMX_SIMD_REAL_WIDTH]; set_pbc_simd(pbc, pbcSimd); - settleTemplateWrapper(settled, - nthread, thread, - pbcSimd, - x, xprime, - invdt, - v, - bCalcVirial, vir_r_m_dr, - bErrorHasOccurred); + settleTemplateWrapper( + settled, nthread, thread, pbcSimd, x, xprime, invdt, v, bCalcVirial, vir_r_m_dr, + bErrorHasOccurred); } else #endif { /* This construct is needed because pbc_dx_aiuc doesn't accept pbc=NULL */ t_pbc pbcNo; - const t_pbc *pbcNonNull; + const t_pbc* pbcNonNull; if (pbc != nullptr) { @@ -888,16 +851,10 @@ void csettle(settledata *settled, pbcNonNull = &pbcNo; } - settleTemplateWrapper(settled, - nthread, thread, - pbcNonNull, - x, xprime, - invdt, - v, - bCalcVirial, vir_r_m_dr, - bErrorHasOccurred); + settleTemplateWrapper(settled, nthread, thread, pbcNonNull, x, + xprime, invdt, v, bCalcVirial, + vir_r_m_dr, bErrorHasOccurred); } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/settle.h b/src/gromacs/mdlib/settle.h index c5ba5fec36..f503ac8481 100644 --- a/src/gromacs/mdlib/settle.h +++ b/src/gromacs/mdlib/settle.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,42 +61,44 @@ enum class ConstraintVariable : int; struct settledata; /*! \brief Initializes and returns a structure with SETTLE parameters */ -settledata *settle_init(const gmx_mtop_t &mtop); +settledata* settle_init(const gmx_mtop_t& mtop); //! Cleans up. -void settle_free(settledata *settled); +void settle_free(settledata* settled); /*! \brief Set up the indices for the settle constraints */ -void settle_set_constraints(settledata *settled, - const t_ilist *il_settle, - const t_mdatoms &mdatoms); +void settle_set_constraints(settledata* settled, const t_ilist* il_settle, const t_mdatoms& mdatoms); /*! \brief Constrain coordinates using SETTLE. * Can be called on any number of threads. */ -void csettle(settledata *settled, /* The SETTLE structure */ - int nthread, /* The number of threads used */ - int thread, /* Our thread index */ - const t_pbc *pbc, /* PBC data pointer, can be NULL */ - const real x[], /* Reference coordinates */ - real xprime[], /* New coords, to be settled */ - real invdt, /* 1/delta_t */ - real *v, /* Also constrain v if v!=NULL */ - bool bCalcVirial, /* Calculate the virial contribution */ - tensor vir_r_m_dr, /* sum r x m delta_r */ - bool *bErrorHasOccurred /* True if a settle error occurred */ - ); +void csettle(settledata* settled, /* The SETTLE structure */ + int nthread, /* The number of threads used */ + int thread, /* Our thread index */ + const t_pbc* pbc, /* PBC data pointer, can be NULL */ + const real x[], /* Reference coordinates */ + real xprime[], /* New coords, to be settled */ + real invdt, /* 1/delta_t */ + real* v, /* Also constrain v if v!=NULL */ + bool bCalcVirial, /* Calculate the virial contribution */ + tensor vir_r_m_dr, /* sum r x m delta_r */ + bool* bErrorHasOccurred /* True if a settle error occurred */ +); /*! \brief Analytical algorithm to subtract the components of derivatives * of coordinates working on settle type constraint. */ -void settle_proj(settledata *settled, ConstraintVariable econq, - int nsettle, const t_iatom iatoms[], - const t_pbc *pbc, /* PBC data pointer, can be NULL */ - const rvec x[], - rvec *der, rvec *derp, - int CalcVirAtomEnd, tensor vir_r_m_dder); +void settle_proj(settledata* settled, + ConstraintVariable econq, + int nsettle, + const t_iatom iatoms[], + const t_pbc* pbc, /* PBC data pointer, can be NULL */ + const rvec x[], + rvec* der, + rvec* derp, + int CalcVirAtomEnd, + tensor vir_r_m_dder); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/settle_cuda.cu b/src/gromacs/mdlib/settle_cuda.cu index 883ac75d84..d09bc9bf7a 100644 --- a/src/gromacs/mdlib/settle_cuda.cu +++ b/src/gromacs/mdlib/settle_cuda.cu @@ -94,17 +94,17 @@ constexpr static int c_maxThreadsPerBlock = c_threadsPerBlock; * \param [in] gm_v Velocities of the particles. * \param [in] gm_virialScaled Virial tensor. */ -template -__launch_bounds__(c_maxThreadsPerBlock) -__global__ void settle_kernel(const int numSettles, - const int3* __restrict__ gm_settles, - const SettleParameters pars, - const float3* __restrict__ gm_x, - float3* __restrict__ gm_xprime, - const PbcAiuc pbcAiuc, - float invdt, - float3* __restrict__ gm_v, - float* __restrict__ gm_virialScaled) +template +__launch_bounds__(c_maxThreadsPerBlock) __global__ + void settle_kernel(const int numSettles, + const int3* __restrict__ gm_settles, + const SettleParameters pars, + const float3* __restrict__ gm_x, + float3* __restrict__ gm_xprime, + const PbcAiuc pbcAiuc, + float invdt, + float3* __restrict__ gm_v, + float* __restrict__ gm_virialScaled) { /* ******************************************************************* */ /* ** */ @@ -121,17 +121,17 @@ __global__ void settle_kernel(const int numSettles, /* ** */ /* ******************************************************************* */ - constexpr float almost_zero = real(1e-12); + constexpr float almost_zero = real(1e-12); - extern __shared__ float sm_threadVirial[]; + extern __shared__ float sm_threadVirial[]; - int tid = static_cast(blockIdx.x*blockDim.x + threadIdx.x); + int tid = static_cast(blockIdx.x * blockDim.x + threadIdx.x); if (tid < numSettles) { // These are the indexes of three atoms in a single 'water' molecule. // TODO Can be reduced to one integer if atoms are consecutive in memory. - int3 indices = gm_settles[tid]; + int3 indices = gm_settles[tid]; float3 x_ow1 = gm_x[indices.x]; float3 x_hw2 = gm_x[indices.y]; @@ -151,30 +151,30 @@ __global__ void settle_kernel(const int numSettles, float3 doh3 = pbcDxAiuc(pbcAiuc, xprime_hw3, xprime_ow1); float3 sh_hw3 = xprime_hw3 - (xprime_ow1 + doh3); - xprime_hw3 = xprime_hw3 - sh_hw3; + xprime_hw3 = xprime_hw3 - sh_hw3; float3 a1 = (-doh2 - doh3) * pars.wh; float3 com = xprime_ow1 - a1; - float3 b1 = xprime_hw2 - com; + float3 b1 = xprime_hw2 - com; - float3 c1 = xprime_hw3 - com; + float3 c1 = xprime_hw3 - com; - float xakszd = dist21.y * dist31.z - dist21.z * dist31.y; - float yakszd = dist21.z * dist31.x - dist21.x * dist31.z; - float zakszd = dist21.x * dist31.y - dist21.y * dist31.x; + float xakszd = dist21.y * dist31.z - dist21.z * dist31.y; + float yakszd = dist21.z * dist31.x - dist21.x * dist31.z; + float zakszd = dist21.x * dist31.y - dist21.y * dist31.x; - float xaksxd = a1.y * zakszd - a1.z * yakszd; - float yaksxd = a1.z * xakszd - a1.x * zakszd; - float zaksxd = a1.x * yakszd - a1.y * xakszd; + float xaksxd = a1.y * zakszd - a1.z * yakszd; + float yaksxd = a1.z * xakszd - a1.x * zakszd; + float zaksxd = a1.x * yakszd - a1.y * xakszd; - float xaksyd = yakszd * zaksxd - zakszd * yaksxd; - float yaksyd = zakszd * xaksxd - xakszd * zaksxd; - float zaksyd = xakszd * yaksxd - yakszd * xaksxd; + float xaksyd = yakszd * zaksxd - zakszd * yaksxd; + float yaksyd = zakszd * xaksxd - xakszd * zaksxd; + float zaksyd = xakszd * yaksxd - yakszd * xaksxd; - float axlng = rsqrt(xaksxd * xaksxd + yaksxd * yaksxd + zaksxd * zaksxd); - float aylng = rsqrt(xaksyd * xaksyd + yaksyd * yaksyd + zaksyd * zaksyd); - float azlng = rsqrt(xakszd * xakszd + yakszd * yakszd + zakszd * zakszd); + float axlng = rsqrt(xaksxd * xaksxd + yaksxd * yaksxd + zaksxd * zaksxd); + float aylng = rsqrt(xaksyd * xaksyd + yaksyd * yaksyd + zaksyd * zaksyd); + float azlng = rsqrt(xakszd * xakszd + yakszd * yakszd + zakszd * zakszd); // TODO {1,2,3} indexes should be swapped with {.x, .y, .z} components. // This way, we will be able to use vector ops more. @@ -203,7 +203,7 @@ __global__ void settle_kernel(const int numSettles, float3 b1d, c1d; - float a1d_z = trns1.z * a1.x + trns2.z * a1.y + trns3.z * a1.z; + float a1d_z = trns1.z * a1.x + trns2.z * a1.y + trns3.z * a1.z; b1d.x = trns1.x * b1.x + trns2.x * b1.y + trns3.x * b1.z; b1d.y = trns1.y * b1.x + trns2.y * b1.y + trns3.y * b1.z; @@ -214,66 +214,66 @@ __global__ void settle_kernel(const int numSettles, c1d.z = trns1.z * c1.x + trns2.z * c1.y + trns3.z * c1.z; - float sinphi = a1d_z * rsqrt(pars.ra*pars.ra); - float tmp2 = 1.0f - sinphi * sinphi; + float sinphi = a1d_z * rsqrt(pars.ra * pars.ra); + float tmp2 = 1.0f - sinphi * sinphi; if (almost_zero > tmp2) { tmp2 = almost_zero; } - float tmp = rsqrt(tmp2); - float cosphi = tmp2*tmp; - float sinpsi = (b1d.z - c1d.z) * pars.irc2 * tmp; - tmp2 = 1.0f - sinpsi * sinpsi; + float tmp = rsqrt(tmp2); + float cosphi = tmp2 * tmp; + float sinpsi = (b1d.z - c1d.z) * pars.irc2 * tmp; + tmp2 = 1.0f - sinpsi * sinpsi; - float cospsi = tmp2*rsqrt(tmp2); + float cospsi = tmp2 * rsqrt(tmp2); - float a2d_y = pars.ra * cosphi; - float b2d_x = -pars.rc * cospsi; - float t1 = -pars.rb * cosphi; - float t2 = pars.rc * sinpsi * sinphi; - float b2d_y = t1 - t2; - float c2d_y = t1 + t2; + float a2d_y = pars.ra * cosphi; + float b2d_x = -pars.rc * cospsi; + float t1 = -pars.rb * cosphi; + float t2 = pars.rc * sinpsi * sinphi; + float b2d_y = t1 - t2; + float c2d_y = t1 + t2; /* --- Step3 al,be,ga --- */ float alpha = b2d_x * (b0d.x - c0d.x) + b0d.y * b2d_y + c0d.y * c2d_y; float beta = b2d_x * (c0d.y - b0d.y) + b0d.x * b2d_y + c0d.x * c2d_y; float gamma = b0d.x * b1d.y - b1d.x * b0d.y + c0d.x * c1d.y - c1d.x * c0d.y; float al2be2 = alpha * alpha + beta * beta; - tmp2 = (al2be2 - gamma * gamma); - float sinthe = (alpha * gamma - beta * tmp2*rsqrt(tmp2)) * rsqrt(al2be2*al2be2); + tmp2 = (al2be2 - gamma * gamma); + float sinthe = (alpha * gamma - beta * tmp2 * rsqrt(tmp2)) * rsqrt(al2be2 * al2be2); /* --- Step4 A3' --- */ - tmp2 = 1.0f - sinthe * sinthe; - float costhe = tmp2*rsqrt(tmp2); + tmp2 = 1.0f - sinthe * sinthe; + float costhe = tmp2 * rsqrt(tmp2); float3 a3d, b3d, c3d; - a3d.x = -a2d_y * sinthe; - a3d.y = a2d_y * costhe; - a3d.z = a1d_z; - b3d.x = b2d_x * costhe - b2d_y * sinthe; - b3d.y = b2d_x * sinthe + b2d_y * costhe; - b3d.z = b1d.z; - c3d.x = -b2d_x * costhe - c2d_y * sinthe; - c3d.y = -b2d_x * sinthe + c2d_y * costhe; - c3d.z = c1d.z; + a3d.x = -a2d_y * sinthe; + a3d.y = a2d_y * costhe; + a3d.z = a1d_z; + b3d.x = b2d_x * costhe - b2d_y * sinthe; + b3d.y = b2d_x * sinthe + b2d_y * costhe; + b3d.z = b1d.z; + c3d.x = -b2d_x * costhe - c2d_y * sinthe; + c3d.y = -b2d_x * sinthe + c2d_y * costhe; + c3d.z = c1d.z; /* --- Step5 A3 --- */ float3 a3, b3, c3; - a3.x = trns1.x*a3d.x + trns1.y*a3d.y + trns1.z*a3d.z; - a3.y = trns2.x*a3d.x + trns2.y*a3d.y + trns2.z*a3d.z; - a3.z = trns3.x*a3d.x + trns3.y*a3d.y + trns3.z*a3d.z; + a3.x = trns1.x * a3d.x + trns1.y * a3d.y + trns1.z * a3d.z; + a3.y = trns2.x * a3d.x + trns2.y * a3d.y + trns2.z * a3d.z; + a3.z = trns3.x * a3d.x + trns3.y * a3d.y + trns3.z * a3d.z; - b3.x = trns1.x*b3d.x + trns1.y*b3d.y + trns1.z*b3d.z; - b3.y = trns2.x*b3d.x + trns2.y*b3d.y + trns2.z*b3d.z; - b3.z = trns3.x*b3d.x + trns3.y*b3d.y + trns3.z*b3d.z; + b3.x = trns1.x * b3d.x + trns1.y * b3d.y + trns1.z * b3d.z; + b3.y = trns2.x * b3d.x + trns2.y * b3d.y + trns2.z * b3d.z; + b3.z = trns3.x * b3d.x + trns3.y * b3d.y + trns3.z * b3d.z; - c3.x = trns1.x*c3d.x + trns1.y*c3d.y + trns1.z*c3d.z; - c3.y = trns2.x*c3d.x + trns2.y*c3d.y + trns2.z*c3d.z; - c3.z = trns3.x*c3d.x + trns3.y*c3d.y + trns3.z*c3d.z; + c3.x = trns1.x * c3d.x + trns1.y * c3d.y + trns1.z * c3d.z; + c3.y = trns2.x * c3d.x + trns2.y * c3d.y + trns2.z * c3d.z; + c3.z = trns3.x * c3d.x + trns3.y * c3d.y + trns3.z * c3d.z; /* Compute and store the corrected new coordinate */ @@ -281,9 +281,9 @@ __global__ void settle_kernel(const int numSettles, xprime_hw2 = com + b3 + sh_hw2; xprime_hw3 = com + c3 + sh_hw3; - gm_xprime[indices.x] = xprime_ow1; - gm_xprime[indices.y] = xprime_hw2; - gm_xprime[indices.z] = xprime_hw3; + gm_xprime[indices.x] = xprime_ow1; + gm_xprime[indices.y] = xprime_hw2; + gm_xprime[indices.z] = xprime_hw3; if (updateVelocities || computeVirial) @@ -301,29 +301,34 @@ __global__ void settle_kernel(const int numSettles, float3 v_hw3 = gm_v[indices.z]; /* Add the position correction divided by dt to the velocity */ - v_ow1 = da*invdt + v_ow1; - v_hw2 = db*invdt + v_hw2; - v_hw3 = dc*invdt + v_hw3; - - gm_v[indices.x] = v_ow1; - gm_v[indices.y] = v_hw2; - gm_v[indices.z] = v_hw3; + v_ow1 = da * invdt + v_ow1; + v_hw2 = db * invdt + v_hw2; + v_hw3 = dc * invdt + v_hw3; + gm_v[indices.x] = v_ow1; + gm_v[indices.y] = v_hw2; + gm_v[indices.z] = v_hw3; } if (computeVirial) { - float3 mdb = pars.mH*db; - float3 mdc = pars.mH*dc; - float3 mdo = pars.mO*da + mdb + mdc; - - sm_threadVirial[0*blockDim.x + threadIdx.x] = -(x_ow1.x*mdo.x + dist21.x*mdb.x + dist31.x*mdc.x); - sm_threadVirial[1*blockDim.x + threadIdx.x] = -(x_ow1.x*mdo.y + dist21.x*mdb.y + dist31.x*mdc.y); - sm_threadVirial[2*blockDim.x + threadIdx.x] = -(x_ow1.x*mdo.z + dist21.x*mdb.z + dist31.x*mdc.z); - sm_threadVirial[3*blockDim.x + threadIdx.x] = -(x_ow1.y*mdo.y + dist21.y*mdb.y + dist31.y*mdc.y); - sm_threadVirial[4*blockDim.x + threadIdx.x] = -(x_ow1.y*mdo.z + dist21.y*mdb.z + dist31.y*mdc.z); - sm_threadVirial[5*blockDim.x + threadIdx.x] = -(x_ow1.z*mdo.z + dist21.z*mdb.z + dist31.z*mdc.z); + float3 mdb = pars.mH * db; + float3 mdc = pars.mH * dc; + float3 mdo = pars.mO * da + mdb + mdc; + + sm_threadVirial[0 * blockDim.x + threadIdx.x] = + -(x_ow1.x * mdo.x + dist21.x * mdb.x + dist31.x * mdc.x); + sm_threadVirial[1 * blockDim.x + threadIdx.x] = + -(x_ow1.x * mdo.y + dist21.x * mdb.y + dist31.x * mdc.y); + sm_threadVirial[2 * blockDim.x + threadIdx.x] = + -(x_ow1.x * mdo.z + dist21.x * mdb.z + dist31.x * mdc.z); + sm_threadVirial[3 * blockDim.x + threadIdx.x] = + -(x_ow1.y * mdo.y + dist21.y * mdb.y + dist31.y * mdc.y); + sm_threadVirial[4 * blockDim.x + threadIdx.x] = + -(x_ow1.y * mdo.z + dist21.y * mdb.z + dist31.y * mdc.z); + sm_threadVirial[5 * blockDim.x + threadIdx.x] = + -(x_ow1.z * mdo.z + dist21.z * mdb.z + dist31.z * mdc.z); } } } @@ -334,7 +339,7 @@ __global__ void settle_kernel(const int numSettles, { for (int d = 0; d < 6; d++) { - sm_threadVirial[d*blockDim.x + threadIdx.x] = 0.0f; + sm_threadVirial[d * blockDim.x + threadIdx.x] = 0.0f; } } } @@ -345,8 +350,8 @@ __global__ void settle_kernel(const int numSettles, // This is to ensure that all threads saved the data before reduction starts __syncthreads(); // This casts unsigned into signed integers to avoid clang warnings - int tib = static_cast(threadIdx.x); - int blockSize = static_cast(blockDim.x); + int tib = static_cast(threadIdx.x); + int blockSize = static_cast(blockDim.x); // Reduce up to one virial per thread block // All blocks are divided by half, the first half of threads sums // two virials. Then the first half is divided by two and the first half @@ -354,15 +359,16 @@ __global__ void settle_kernel(const int numSettles, // Only works if the threads per blocks is a power of two. for (int divideBy = 2; divideBy <= blockSize; divideBy *= 2) { - int dividedAt = blockSize/divideBy; + int dividedAt = blockSize / divideBy; if (tib < dividedAt) { for (int d = 0; d < 6; d++) { - sm_threadVirial[d*blockSize + tib] += sm_threadVirial[d*blockSize + (tib + dividedAt)]; + sm_threadVirial[d * blockSize + tib] += + sm_threadVirial[d * blockSize + (tib + dividedAt)]; } } - if (dividedAt > warpSize/2) + if (dividedAt > warpSize / 2) { __syncthreads(); } @@ -370,7 +376,7 @@ __global__ void settle_kernel(const int numSettles, // First 6 threads in the block add the 6 components of virial to the global memory address if (tib < 6) { - atomicAdd(&(gm_virialScaled[tib]), sm_threadVirial[tib*blockSize]); + atomicAdd(&(gm_virialScaled[tib]), sm_threadVirial[tib * blockSize]); } } @@ -386,8 +392,7 @@ __global__ void settle_kernel(const int numSettles, * * \retrun Pointer to CUDA kernel */ -inline auto getSettleKernelPtr(const bool updateVelocities, - const bool computeVirial) +inline auto getSettleKernelPtr(const bool updateVelocities, const bool computeVirial) { auto kernelPtr = settle_kernel; @@ -410,10 +415,10 @@ inline auto getSettleKernelPtr(const bool updateVelocities, return kernelPtr; } -void SettleCuda::apply(const float3 *d_x, - float3 *d_xp, +void SettleCuda::apply(const float3* d_x, + float3* d_xp, const bool updateVelocities, - float3 *d_v, + float3* d_v, const real invdt, const bool computeVirial, tensor virialScaled) @@ -434,45 +439,36 @@ void SettleCuda::apply(const float3 *d_x, clearDeviceBufferAsync(&d_virialScaled_, 0, 6, commandStream_); } - auto kernelPtr = getSettleKernelPtr(updateVelocities, computeVirial); + auto kernelPtr = getSettleKernelPtr(updateVelocities, computeVirial); KernelLaunchConfig config; - config.blockSize[0] = c_threadsPerBlock; - config.blockSize[1] = 1; - config.blockSize[2] = 1; - config.gridSize[0] = (numSettles_ + c_threadsPerBlock - 1)/c_threadsPerBlock; - config.gridSize[1] = 1; - config.gridSize[2] = 1; + config.blockSize[0] = c_threadsPerBlock; + config.blockSize[1] = 1; + config.blockSize[2] = 1; + config.gridSize[0] = (numSettles_ + c_threadsPerBlock - 1) / c_threadsPerBlock; + config.gridSize[1] = 1; + config.gridSize[2] = 1; // Shared memory is only used for virial reduction if (computeVirial) { - config.sharedMemorySize = c_threadsPerBlock*6*sizeof(float); + config.sharedMemorySize = c_threadsPerBlock * 6 * sizeof(float); } else { config.sharedMemorySize = 0; } - config.stream = commandStream_; - - const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, - &numSettles_, - &d_atomIds_, - &settleParameters_, - &d_x, - &d_xp, - &pbcAiuc_, - &invdt, - &d_v, - &d_virialScaled_); - - launchGpuKernel(kernelPtr, config, nullptr, - "settle_kernel", kernelArgs); + config.stream = commandStream_; + + const auto kernelArgs = prepareGpuKernelArguments(kernelPtr, config, &numSettles_, &d_atomIds_, + &settleParameters_, &d_x, &d_xp, &pbcAiuc_, + &invdt, &d_v, &d_virialScaled_); + + launchGpuKernel(kernelPtr, config, nullptr, "settle_kernel", kernelArgs); if (computeVirial) { - copyFromDeviceBuffer(h_virialScaled_.data(), &d_virialScaled_, - 0, 6, - commandStream_, GpuApiCallBehavior::Sync, nullptr); + copyFromDeviceBuffer(h_virialScaled_.data(), &d_virialScaled_, 0, 6, commandStream_, + GpuApiCallBehavior::Sync, nullptr); // Mapping [XX, XY, XZ, YY, YZ, ZZ] internal format to a tensor object virialScaled[XX][XX] += h_virialScaled_[0]; @@ -491,14 +487,14 @@ void SettleCuda::apply(const float3 *d_x, return; } -SettleCuda::SettleCuda(const gmx_mtop_t &mtop, - CommandStream commandStream) : +SettleCuda::SettleCuda(const gmx_mtop_t& mtop, CommandStream commandStream) : commandStream_(commandStream) { static_assert(sizeof(real) == sizeof(float), "Real numbers should be in single precision in GPU code."); - static_assert(c_threadsPerBlock > 0 && ((c_threadsPerBlock & (c_threadsPerBlock - 1)) == 0), - "Number of threads per block should be a power of two in order for reduction to work."); + static_assert( + c_threadsPerBlock > 0 && ((c_threadsPerBlock & (c_threadsPerBlock - 1)) == 0), + "Number of threads per block should be a power of two in order for reduction to work."); // This is to prevent the assertion failure for the systems without water int totalSettles = 0; @@ -507,17 +503,17 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, const int nral1 = 1 + NRAL(F_SETTLE); InteractionList interactionList = mtop.moltype.at(mt).ilist[F_SETTLE]; std::vector iatoms = interactionList.iatoms; - totalSettles += iatoms.size()/nral1; + totalSettles += iatoms.size() / nral1; } if (totalSettles == 0) { return; } - // TODO This should be lifted to a separate subroutine that gets the values of Oxygen and Hydrogen - // masses, checks if they are consistent across the topology and if there is no more than two values - // for each mass if the free energy perturbation is enabled. In later case, masses may need to be - // updated on a regular basis (i.e. in set(...) method). + // TODO This should be lifted to a separate subroutine that gets the values of Oxygen and + // Hydrogen masses, checks if they are consistent across the topology and if there is no more + // than two values for each mass if the free energy perturbation is enabled. In later case, + // masses may need to be updated on a regular basis (i.e. in set(...) method). // TODO Do the checks for FEP real mO = -1.0; real mH = -1.0; @@ -527,12 +523,12 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, const int nral1 = 1 + NRAL(F_SETTLE); InteractionList interactionList = mtop.moltype.at(mt).ilist[F_SETTLE]; std::vector iatoms = interactionList.iatoms; - for (unsigned i = 0; i < iatoms.size()/nral1; i++) + for (unsigned i = 0; i < iatoms.size() / nral1; i++) { int3 settler; - settler.x = iatoms[i*nral1 + 1]; // Oxygen index - settler.y = iatoms[i*nral1 + 2]; // First hydrogen index - settler.z = iatoms[i*nral1 + 3]; // Second hydrogen index + settler.x = iatoms[i * nral1 + 1]; // Oxygen index + settler.y = iatoms[i * nral1 + 2]; // First hydrogen index + settler.z = iatoms[i * nral1 + 3]; // Second hydrogen index t_atom ow1 = mtop.moltype.at(mt).atoms.atom[settler.x]; t_atom hw2 = mtop.moltype.at(mt).atoms.atom[settler.y]; t_atom hw3 = mtop.moltype.at(mt).atoms.atom[settler.z]; @@ -545,8 +541,12 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, { mH = hw2.m; } - GMX_RELEASE_ASSERT(mO == ow1.m, "Topology has different values for oxygen mass. Should be identical in order to use SETTLE."); - GMX_RELEASE_ASSERT(hw2.m == hw3.m && hw2.m == mH, "Topology has different values for hydrogen mass. Should be identical in order to use SETTLE."); + GMX_RELEASE_ASSERT(mO == ow1.m, + "Topology has different values for oxygen mass. Should be identical " + "in order to use SETTLE."); + GMX_RELEASE_ASSERT(hw2.m == hw3.m && hw2.m == mH, + "Topology has different values for hydrogen mass. Should be " + "identical in order to use SETTLE."); } } @@ -555,7 +555,7 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, // TODO Very similar to SETTLE initialization on CPU. Should be lifted to a separate method // (one that gets dOH and dHH values and checks them for consistency) - int settle_type = -1; + int settle_type = -1; for (unsigned mt = 0; mt < mtop.moltype.size(); mt++) { const int nral1 = 1 + NRAL(F_SETTLE); @@ -569,10 +569,12 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, else if (interactionList.iatoms[i] != settle_type) { gmx_fatal(FARGS, - "The [molecules] section of your topology specifies more than one block of\n" + "The [molecules] section of your topology specifies more than one block " + "of\n" "a [moleculetype] with a [settles] block. Only one such is allowed.\n" "If you are trying to partition your solvent into different *groups*\n" - "(e.g. for freezing, T-coupling, etc.), you are using the wrong approach. Index\n" + "(e.g. for freezing, T-coupling, etc.), you are using the wrong " + "approach. Index\n" "files specify groups. Otherwise, you may wish to change the least-used\n" "block of molecules with SETTLE constraints into 3 normal constraints."); } @@ -588,7 +590,6 @@ SettleCuda::SettleCuda(const gmx_mtop_t &mtop, allocateDeviceBuffer(&d_virialScaled_, 6, nullptr); h_virialScaled_.resize(6); - } SettleCuda::~SettleCuda() @@ -605,31 +606,28 @@ SettleCuda::~SettleCuda() } } -void SettleCuda::set(const t_idef &idef, - const t_mdatoms gmx_unused &md) +void SettleCuda::set(const t_idef& idef, const t_mdatoms gmx_unused& md) { - const int nral1 = 1 + NRAL(F_SETTLE); - t_ilist il_settle = idef.il[F_SETTLE]; - t_iatom *iatoms = il_settle.iatoms; - numSettles_ = il_settle.nr/nral1; + const int nral1 = 1 + NRAL(F_SETTLE); + t_ilist il_settle = idef.il[F_SETTLE]; + t_iatom* iatoms = il_settle.iatoms; + numSettles_ = il_settle.nr / nral1; reallocateDeviceBuffer(&d_atomIds_, numSettles_, &numAtomIds_, &numAtomIdsAlloc_, nullptr); h_atomIds_.resize(numSettles_); for (int i = 0; i < numSettles_; i++) { int3 settler; - settler.x = iatoms[i*nral1 + 1]; // Oxygen index - settler.y = iatoms[i*nral1 + 2]; // First hydrogen index - settler.z = iatoms[i*nral1 + 3]; // Second hydrogen index - h_atomIds_.at(i) = settler; + settler.x = iatoms[i * nral1 + 1]; // Oxygen index + settler.y = iatoms[i * nral1 + 2]; // First hydrogen index + settler.z = iatoms[i * nral1 + 3]; // Second hydrogen index + h_atomIds_.at(i) = settler; } - copyToDeviceBuffer(&d_atomIds_, h_atomIds_.data(), - 0, numSettles_, - commandStream_, GpuApiCallBehavior::Sync, nullptr); - + copyToDeviceBuffer(&d_atomIds_, h_atomIds_.data(), 0, numSettles_, commandStream_, + GpuApiCallBehavior::Sync, nullptr); } -void SettleCuda::setPbc(const t_pbc *pbc) +void SettleCuda::setPbc(const t_pbc* pbc) { setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_); } diff --git a/src/gromacs/mdlib/settle_cuda.cuh b/src/gromacs/mdlib/settle_cuda.cuh index 3696514010..caef2dbedc 100644 --- a/src/gromacs/mdlib/settle_cuda.cuh +++ b/src/gromacs/mdlib/settle_cuda.cuh @@ -68,35 +68,35 @@ namespace gmx struct SettleParameters { //! Mass of oxygen atom - float mO; + float mO; //! Mass of hydrogen atom - float mH; + float mH; //! Relative hydrogen mass (i.e. mH/(mO+2*mH)) - float wh; + float wh; //! Target distance between oxygen and hydrogen - float dOH; + float dOH; //! Target distance between hydrogen atoms - float dHH; + float dHH; //! Double relative H mass times height of the H-O-H triangle. - float ra; + float ra; //! Height of the H-O-H triangle minus ra. - float rb; + float rb; //! Half the H-H distance. - float rc; + float rc; //! Reciprocal H-H distance - float irc2; + float irc2; /* Parameters below are used for projection */ //! Reciprocal oxygen mass - float imO; + float imO; //! Reciprocal hydrogen mass - float imH; + float imH; //! Reciprocal O-H distance - float invdOH; + float invdOH; //! Reciprocal H-H distance (again) - float invdHH; + float invdHH; //! Reciprocal projection matrix - matrix invmat; + matrix invmat; }; /*! \brief Initializes a projection matrix. @@ -109,22 +109,24 @@ struct SettleParameters * \param[in] dHH Target H-H bond length * \param[out] inverseCouplingMatrix Inverse bond coupling matrix for the projection version of SETTLE */ -static void initializeProjectionMatrix(const real invmO, const real invmH, - const real dOH, const real dHH, - matrix inverseCouplingMatrix) +static void initializeProjectionMatrix(const real invmO, + const real invmH, + const real dOH, + const real dHH, + matrix inverseCouplingMatrix) { // We normalize the inverse masses with invmO for the matrix inversion. // so we can keep using masses of almost zero for frozen particles, // without running out of the float range in invertMatrix. double invmORelative = 1.0; - double invmHRelative = invmH/static_cast(invmO); - double distanceRatio = dHH/static_cast(dOH); + double invmHRelative = invmH / static_cast(invmO); + double distanceRatio = dHH / static_cast(dOH); /* Construct the constraint coupling matrix */ matrix mat; mat[0][0] = invmORelative + invmHRelative; - mat[0][1] = invmORelative*(1.0 - 0.5*gmx::square(distanceRatio)); - mat[0][2] = invmHRelative*0.5*distanceRatio; + mat[0][1] = invmORelative * (1.0 - 0.5 * gmx::square(distanceRatio)); + mat[0][2] = invmHRelative * 0.5 * distanceRatio; mat[1][1] = mat[0][0]; mat[1][2] = mat[0][2]; mat[2][2] = invmHRelative + invmHRelative; @@ -134,7 +136,7 @@ static void initializeProjectionMatrix(const real invmO, const real invmH, gmx::invertMatrix(mat, inverseCouplingMatrix); - msmul(inverseCouplingMatrix, 1/invmO, inverseCouplingMatrix); + msmul(inverseCouplingMatrix, 1 / invmO, inverseCouplingMatrix); } /*! \brief Initializes settle parameters. @@ -148,9 +150,8 @@ static void initializeProjectionMatrix(const real invmO, const real invmH, * \param[in] dHH Target H-H bond length */ gmx_unused // Temporary solution to keep clang happy -static void initSettleParameters(SettleParameters *p, - const real mO, const real mH, - const real dOH, const real dHH) + static void + initSettleParameters(SettleParameters* p, const real mO, const real mH, const real dOH, const real dHH) { // We calculate parameters in double precision to minimize errors. // The velocity correction applied during SETTLE coordinate constraining @@ -158,28 +159,28 @@ static void initSettleParameters(SettleParameters *p, // depending on what the compiler does with the code. double wohh; - real invmO = 1.0/mO; - real invmH = 1.0/mH; + real invmO = 1.0 / mO; + real invmH = 1.0 / mH; p->mO = mO; p->mH = mH; - wohh = mO + 2.0*mH; - p->wh = mH/wohh; + wohh = mO + 2.0 * mH; + p->wh = mH / wohh; p->dOH = dOH; p->dHH = dHH; - double rc = dHH/2.0; - double ra = 2.0*mH*std::sqrt(dOH*dOH - rc*rc)/wohh; - p->rb = std::sqrt(dOH*dOH - rc*rc) - ra; + double rc = dHH / 2.0; + double ra = 2.0 * mH * std::sqrt(dOH * dOH - rc * rc) / wohh; + p->rb = std::sqrt(dOH * dOH - rc * rc) - ra; p->rc = rc; p->ra = ra; - p->irc2 = 1.0/dHH; + p->irc2 = 1.0 / dHH; // For projection: inverse masses and coupling matrix inversion - p->imO = invmO; - p->imH = invmH; + p->imO = invmO; + p->imH = invmH; - p->invdOH = 1.0/dOH; - p->invdHH = 1.0/dHH; + p->invdOH = 1.0 / dOH; + p->invdHH = 1.0 / dHH; initializeProjectionMatrix(invmO, invmH, dOH, dHH, p->invmat); } @@ -188,103 +189,100 @@ static void initSettleParameters(SettleParameters *p, class SettleCuda { - public: - /*! \brief Create SETTLE object - * - * Extracts masses for oxygen and hydrogen as well as the O-H and H-H target distances - * from the topology data (mtop), check their values for consistency and calls the - * following constructor. - * - * \param[in] mtop Topology of the system to gen the masses for O and H atoms and - * target O-H and H-H distances. These values are also checked for - * consistency. - * \param[in] commandStream Device stream to use. - */ - SettleCuda(const gmx_mtop_t &mtop, - CommandStream commandStream); +public: + /*! \brief Create SETTLE object + * + * Extracts masses for oxygen and hydrogen as well as the O-H and H-H target distances + * from the topology data (mtop), check their values for consistency and calls the + * following constructor. + * + * \param[in] mtop Topology of the system to gen the masses for O and H atoms and + * target O-H and H-H distances. These values are also checked for + * consistency. + * \param[in] commandStream Device stream to use. + */ + SettleCuda(const gmx_mtop_t& mtop, CommandStream commandStream); - ~SettleCuda(); + ~SettleCuda(); - /*! \brief Apply SETTLE. - * - * Applies SETTLE to coordinates and velocities, stored on GPU. Data at pointers d_xp and - * d_v change in the GPU memory. The results are not automatically copied back to the CPU - * memory. Method uses this class data structures which should be updated when needed using - * update method. - * - * \param[in] d_x Coordinates before timestep (in GPU memory) - * \param[in,out] d_xp Coordinates after timestep (in GPU memory). The - * resulting constrained coordinates will be saved here. - * \param[in] updateVelocities If the velocities should be updated. - * \param[in,out] d_v Velocities to update (in GPU memory, can be nullptr - * if not updated) - * \param[in] invdt Reciprocal timestep (to scale Lagrange - * multipliers when velocities are updated) - * \param[in] computeVirial If virial should be updated. - * \param[in,out] virialScaled Scaled virial tensor to be updated. - */ - void apply(const float3 *d_x, - float3 *d_xp, - const bool updateVelocities, - float3 *d_v, - const real invdt, - const bool computeVirial, - tensor virialScaled); + /*! \brief Apply SETTLE. + * + * Applies SETTLE to coordinates and velocities, stored on GPU. Data at pointers d_xp and + * d_v change in the GPU memory. The results are not automatically copied back to the CPU + * memory. Method uses this class data structures which should be updated when needed using + * update method. + * + * \param[in] d_x Coordinates before timestep (in GPU memory) + * \param[in,out] d_xp Coordinates after timestep (in GPU memory). The + * resulting constrained coordinates will be saved here. + * \param[in] updateVelocities If the velocities should be updated. + * \param[in,out] d_v Velocities to update (in GPU memory, can be nullptr + * if not updated) + * \param[in] invdt Reciprocal timestep (to scale Lagrange + * multipliers when velocities are updated) + * \param[in] computeVirial If virial should be updated. + * \param[in,out] virialScaled Scaled virial tensor to be updated. + */ + void apply(const float3* d_x, + float3* d_xp, + const bool updateVelocities, + float3* d_v, + const real invdt, + const bool computeVirial, + tensor virialScaled); - /*! \brief - * Update data-structures (e.g. after NB search step). - * - * Updates the constraints data and copies it to the GPU. Should be - * called if the particles were sorted, redistributed between domains, etc. - * Does not recycle the data preparation routines from the CPU version. - * All three atoms from single water molecule should be handled by the same GPU. - * - * SETTLEs atom ID's is taken from idef.il[F_SETTLE].iatoms. - * - * \param[in] idef System topology - * \param[in] md Atoms data. Can be used to update masses if needed (not used now). - */ - void set(const t_idef &idef, - const t_mdatoms &md); + /*! \brief + * Update data-structures (e.g. after NB search step). + * + * Updates the constraints data and copies it to the GPU. Should be + * called if the particles were sorted, redistributed between domains, etc. + * Does not recycle the data preparation routines from the CPU version. + * All three atoms from single water molecule should be handled by the same GPU. + * + * SETTLEs atom ID's is taken from idef.il[F_SETTLE].iatoms. + * + * \param[in] idef System topology + * \param[in] md Atoms data. Can be used to update masses if needed (not used now). + */ + void set(const t_idef& idef, const t_mdatoms& md); - /*! \brief - * Update PBC data. - * - * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter. - * - * \todo PBC should not be handled by constraints. - * - * \param[in] pbc The PBC data in t_pbc format. - */ - void setPbc(const t_pbc *pbc); + /*! \brief + * Update PBC data. + * + * Converts pbc data from t_pbc into the PbcAiuc format and stores the latter. + * + * \todo PBC should not be handled by constraints. + * + * \param[in] pbc The PBC data in t_pbc format. + */ + void setPbc(const t_pbc* pbc); - private: +private: + //! CUDA stream + CommandStream commandStream_; + //! Periodic boundary data + PbcAiuc pbcAiuc_; - //! CUDA stream - CommandStream commandStream_; - //! Periodic boundary data - PbcAiuc pbcAiuc_; + //! Scaled virial tensor (9 reals, GPU) + std::vector h_virialScaled_; + //! Scaled virial tensor (9 reals, GPU) + float* d_virialScaled_; - //! Scaled virial tensor (9 reals, GPU) - std::vector h_virialScaled_; - //! Scaled virial tensor (9 reals, GPU) - float *d_virialScaled_; + //! Number of settles + int numSettles_ = 0; - //! Number of settles - int numSettles_ = 0; + //! Indexes of atoms (.x for oxygen, .y and.z for hydrogens, CPU) + std::vector h_atomIds_; + //! Indexes of atoms (.x for oxygen, .y and.z for hydrogens, GPU) + int3* d_atomIds_; + //! Current size of the array of atom IDs + int numAtomIds_ = -1; + //! Allocated size for the array of atom IDs + int numAtomIdsAlloc_ = -1; - //! Indexes of atoms (.x for oxygen, .y and.z for hydrogens, CPU) - std::vector h_atomIds_; - //! Indexes of atoms (.x for oxygen, .y and.z for hydrogens, GPU) - int3 *d_atomIds_; - //! Current size of the array of atom IDs - int numAtomIds_ = -1; - //! Allocated size for the array of atom IDs - int numAtomIdsAlloc_ = -1; - - //! Settle parameters - SettleParameters settleParameters_; + //! Settle parameters + SettleParameters settleParameters_; }; } // namespace gmx diff --git a/src/gromacs/mdlib/shake.cpp b/src/gromacs/mdlib/shake.cpp index 7d8a05465e..3af852d212 100644 --- a/src/gromacs/mdlib/shake.cpp +++ b/src/gromacs/mdlib/shake.cpp @@ -68,29 +68,29 @@ namespace gmx struct shakedata { - rvec *rij; - real *half_of_reduced_mass; - real *distance_squared_tolerance; - real *constraint_distance_squared; + rvec* rij; + real* half_of_reduced_mass; + real* distance_squared_tolerance; + real* constraint_distance_squared; int nalloc; /* SOR stuff */ - real delta; - real omega; - real gamma; - int nblocks; /* The number of SHAKE blocks */ - int *sblock; /* The SHAKE blocks */ - int sblock_nalloc; /* The allocation size of sblock */ + real delta; + real omega; + real gamma; + int nblocks; /* The number of SHAKE blocks */ + int* sblock; /* The SHAKE blocks */ + int sblock_nalloc; /* The allocation size of sblock */ /*! \brief Scaled Lagrange multiplier for each constraint. * * Value is -2 * eta from p. 336 of the paper, divided by the * constraint distance. */ - real *scaled_lagrange_multiplier; - int lagr_nalloc; /* The allocation size of scaled_lagrange_multiplier */ + real* scaled_lagrange_multiplier; + int lagr_nalloc; /* The allocation size of scaled_lagrange_multiplier */ }; -shakedata *shake_init() +shakedata* shake_init() { - shakedata *d; + shakedata* d; snew(d, 1); @@ -108,7 +108,7 @@ shakedata *shake_init() return d; } -void done_shake(shakedata *d) +void done_shake(shakedata* d) { sfree(d->rij); sfree(d->half_of_reduced_mass); @@ -119,20 +119,21 @@ void done_shake(shakedata *d) sfree(d); } -typedef struct { +typedef struct +{ int iatom[3]; int blocknr; } t_sortblock; //! Compares sort blocks. -static int pcomp(const void *p1, const void *p2) +static int pcomp(const void* p1, const void* p2) { int db; int min1, min2, max1, max2; - const t_sortblock *a1 = reinterpret_cast(p1); - const t_sortblock *a2 = reinterpret_cast(p2); + const t_sortblock* a1 = reinterpret_cast(p1); + const t_sortblock* a2 = reinterpret_cast(p2); - db = a1->blocknr-a2->blocknr; + db = a1->blocknr - a2->blocknr; if (db != 0) { @@ -146,30 +147,29 @@ static int pcomp(const void *p1, const void *p2) if (min1 == min2) { - return max1-max2; + return max1 - max2; } else { - return min1-min2; + return min1 - min2; } } //! Prints sortblocks -static void pr_sortblock(FILE *fp, const char *title, int nsb, t_sortblock sb[]) +static void pr_sortblock(FILE* fp, const char* title, int nsb, t_sortblock sb[]) { int i; fprintf(fp, "%s\n", title); for (i = 0; (i < nsb); i++) { - fprintf(fp, "i: %5d, iatom: (%5d %5d %5d), blocknr: %5d\n", - i, sb[i].iatom[0], sb[i].iatom[1], sb[i].iatom[2], - sb[i].blocknr); + fprintf(fp, "i: %5d, iatom: (%5d %5d %5d), blocknr: %5d\n", i, sb[i].iatom[0], + sb[i].iatom[1], sb[i].iatom[2], sb[i].blocknr); } } //! Reallocates a vector. -static void resizeLagrangianData(shakedata *shaked, int ncons) +static void resizeLagrangianData(shakedata* shaked, int ncons) { if (ncons > shaked->lagr_nalloc) { @@ -178,21 +178,19 @@ static void resizeLagrangianData(shakedata *shaked, int ncons) } } -void -make_shake_sblock_serial(shakedata *shaked, - const t_idef *idef, const t_mdatoms &md) +void make_shake_sblock_serial(shakedata* shaked, const t_idef* idef, const t_mdatoms& md) { int i, j, m, ncons; int bstart, bnr; t_blocka sblocks; - t_sortblock *sb; - t_iatom *iatom; - int *inv_sblock; + t_sortblock* sb; + t_iatom* iatom; + int* inv_sblock; /* Since we are processing the local topology, * the F_CONSTRNC ilist has been concatenated to the F_CONSTR ilist. */ - ncons = idef->il[F_CONSTR].nr/3; + ncons = idef->il[F_CONSTR].nr / 3; init_blocka(&sblocks); sfree(sblocks.index); // To solve memory leak @@ -206,8 +204,7 @@ make_shake_sblock_serial(shakedata *shaked, shaked->nblocks = sblocks.nr; if (debug) { - fprintf(debug, "ncons: %d, bstart: %d, nblocks: %d\n", - ncons, bstart, shaked->nblocks); + fprintf(debug, "ncons: %d, bstart: %d, nblocks: %d\n", ncons, bstart, shaked->nblocks); } /* Calculate block number for each atom */ @@ -254,24 +251,23 @@ make_shake_sblock_serial(shakedata *shaked, } j = 0; - snew(shaked->sblock, shaked->nblocks+1); + snew(shaked->sblock, shaked->nblocks + 1); bnr = -2; for (i = 0; (i < ncons); i++) { if (sb[i].blocknr != bnr) { bnr = sb[i].blocknr; - shaked->sblock[j++] = 3*i; + shaked->sblock[j++] = 3 * i; } } /* Last block... */ - shaked->sblock[j++] = 3*ncons; + shaked->sblock[j++] = 3 * ncons; - if (j != (shaked->nblocks+1)) + if (j != (shaked->nblocks + 1)) { fprintf(stderr, "bstart: %d\n", bstart); - fprintf(stderr, "j: %d, nblocks: %d, ncons: %d\n", - j, shaked->nblocks, ncons); + fprintf(stderr, "j: %d, nblocks: %d, ncons: %d\n", j, shaked->nblocks, ncons); for (i = 0; (i < ncons); i++) { fprintf(stderr, "i: %5d sb[i].blocknr: %5d\n", i, sb[i].blocknr); @@ -280,7 +276,8 @@ make_shake_sblock_serial(shakedata *shaked, { fprintf(stderr, "sblock[%3d]=%5d\n", j, shaked->sblock[j]); } - gmx_fatal(FARGS, "DEATH HORROR: " + gmx_fatal(FARGS, + "DEATH HORROR: " "sblocks does not match idef->il[F_CONSTR]"); } sfree(sb); @@ -289,21 +286,18 @@ make_shake_sblock_serial(shakedata *shaked, } // TODO: Check if this code is useful. It might never be called. -void -make_shake_sblock_dd(shakedata *shaked, - const t_ilist *ilcon, - const gmx_domdec_t *dd) +void make_shake_sblock_dd(shakedata* shaked, const t_ilist* ilcon, const gmx_domdec_t* dd) { int ncons, c, cg; - t_iatom *iatom; + t_iatom* iatom; - if (dd->ncg_home+1 > shaked->sblock_nalloc) + if (dd->ncg_home + 1 > shaked->sblock_nalloc) { - shaked->sblock_nalloc = over_alloc_dd(dd->ncg_home+1); + shaked->sblock_nalloc = over_alloc_dd(dd->ncg_home + 1); srenew(shaked->sblock, shaked->sblock_nalloc); } - ncons = ilcon->nr/3; + ncons = ilcon->nr / 3; iatom = ilcon->iatoms; shaked->nblocks = 0; cg = 0; @@ -311,7 +305,7 @@ make_shake_sblock_dd(shakedata *shaked, { if (c == 0 || iatom[1] >= cg + 1) { - shaked->sblock[shaked->nblocks++] = 3*c; + shaked->sblock[shaked->nblocks++] = 3 * c; while (iatom[1] >= cg + 1) { cg++; @@ -319,7 +313,7 @@ make_shake_sblock_dd(shakedata *shaked, } iatom += 3; } - shaked->sblock[shaked->nblocks] = 3*ncons; + shaked->sblock[shaked->nblocks] = 3 * ncons; resizeLagrangianData(shaked, ncons); } @@ -352,25 +346,33 @@ make_shake_sblock_dd(shakedata *shaked, * problematic constraint if the input was malformed * * \todo Make SHAKE use better data structures, in particular for iatom. */ -void cshake(const int iatom[], int ncon, int *nnit, int maxnit, - const real constraint_distance_squared[], real positions[], - const real initial_displacements[], const real half_of_reduced_mass[], real omega, - const real invmass[], const real distance_squared_tolerance[], - real scaled_lagrange_multiplier[], int *nerror) +void cshake(const int iatom[], + int ncon, + int* nnit, + int maxnit, + const real constraint_distance_squared[], + real positions[], + const real initial_displacements[], + const real half_of_reduced_mass[], + real omega, + const real invmass[], + const real distance_squared_tolerance[], + real scaled_lagrange_multiplier[], + int* nerror) { /* default should be increased! MRS 8/4/2009 */ const real mytol = 1e-10; - int ll, i, j, i3, j3, l3; - int ix, iy, iz, jx, jy, jz; - real r_dot_r_prime; - real constraint_distance_squared_ll; - real r_prime_squared; - real scaled_lagrange_multiplier_ll; - real r_prime_x, r_prime_y, r_prime_z, diff, im, jm; - real xh, yh, zh, rijx, rijy, rijz; - int nit, error, nconv; - real iconvf; + int ll, i, j, i3, j3, l3; + int ix, iy, iz, jx, jy, jz; + real r_dot_r_prime; + real constraint_distance_squared_ll; + real r_prime_squared; + real scaled_lagrange_multiplier_ll; + real r_prime_x, r_prime_y, r_prime_z, diff, im, jm; + real xh, yh, zh, rijx, rijy, rijz; + int nit, error, nconv; + real iconvf; // TODO nconv is used solely as a boolean, so we should write the // code like that @@ -381,31 +383,29 @@ void cshake(const int iatom[], int ncon, int *nnit, int maxnit, nconv = 0; for (ll = 0; (ll < ncon) && (error == 0); ll++) { - l3 = 3*ll; - rijx = initial_displacements[l3+XX]; - rijy = initial_displacements[l3+YY]; - rijz = initial_displacements[l3+ZZ]; - i = iatom[l3+1]; - j = iatom[l3+2]; - i3 = 3*i; - j3 = 3*j; - ix = i3+XX; - iy = i3+YY; - iz = i3+ZZ; - jx = j3+XX; - jy = j3+YY; - jz = j3+ZZ; + l3 = 3 * ll; + rijx = initial_displacements[l3 + XX]; + rijy = initial_displacements[l3 + YY]; + rijz = initial_displacements[l3 + ZZ]; + i = iatom[l3 + 1]; + j = iatom[l3 + 2]; + i3 = 3 * i; + j3 = 3 * j; + ix = i3 + XX; + iy = i3 + YY; + iz = i3 + ZZ; + jx = j3 + XX; + jy = j3 + YY; + jz = j3 + ZZ; /* Compute r prime between atoms i and j, which is the displacement *before* this update stage */ - r_prime_x = positions[ix]-positions[jx]; - r_prime_y = positions[iy]-positions[jy]; - r_prime_z = positions[iz]-positions[jz]; - r_prime_squared = (r_prime_x * r_prime_x + - r_prime_y * r_prime_y + - r_prime_z * r_prime_z); + r_prime_x = positions[ix] - positions[jx]; + r_prime_y = positions[iy] - positions[jy]; + r_prime_z = positions[iz] - positions[jz]; + r_prime_squared = (r_prime_x * r_prime_x + r_prime_y * r_prime_y + r_prime_z * r_prime_z); constraint_distance_squared_ll = constraint_distance_squared[ll]; - diff = constraint_distance_squared_ll - r_prime_squared; + diff = constraint_distance_squared_ll - r_prime_squared; /* iconvf is less than 1 when the error is smaller than a bound */ iconvf = fabs(diff) * distance_squared_tolerance[ll]; @@ -413,31 +413,29 @@ void cshake(const int iatom[], int ncon, int *nnit, int maxnit, if (iconvf > 1.0) { nconv = static_cast(iconvf); - r_dot_r_prime = (rijx * r_prime_x + - rijy * r_prime_y + - rijz * r_prime_z); + r_dot_r_prime = (rijx * r_prime_x + rijy * r_prime_y + rijz * r_prime_z); if (r_dot_r_prime < constraint_distance_squared_ll * mytol) { - error = ll+1; + error = ll + 1; } else { /* The next line solves equation 5.6 (neglecting the term in g^2), for g */ - scaled_lagrange_multiplier_ll = omega*diff*half_of_reduced_mass[ll]/r_dot_r_prime; + scaled_lagrange_multiplier_ll = omega * diff * half_of_reduced_mass[ll] / r_dot_r_prime; scaled_lagrange_multiplier[ll] += scaled_lagrange_multiplier_ll; - xh = rijx * scaled_lagrange_multiplier_ll; - yh = rijy * scaled_lagrange_multiplier_ll; - zh = rijz * scaled_lagrange_multiplier_ll; - im = invmass[i]; - jm = invmass[j]; - positions[ix] += xh*im; - positions[iy] += yh*im; - positions[iz] += zh*im; - positions[jx] -= xh*jm; - positions[jy] -= yh*jm; - positions[jz] -= zh*jm; + xh = rijx * scaled_lagrange_multiplier_ll; + yh = rijy * scaled_lagrange_multiplier_ll; + zh = rijz * scaled_lagrange_multiplier_ll; + im = invmass[i]; + jm = invmass[j]; + positions[ix] += xh * im; + positions[iy] += yh * im; + positions[iz] += zh * im; + positions[jx] -= xh * jm; + positions[jy] -= yh * jm; + positions[jz] -= zh * jm; } } } @@ -447,11 +445,20 @@ void cshake(const int iatom[], int ncon, int *nnit, int maxnit, } //! Implements RATTLE (ie. SHAKE for velocity verlet integrators) -static void -crattle(const int iatom[], int ncon, int *nnit, int maxnit, - const real constraint_distance_squared[], real vp[], const real rij[], const real m2[], real omega, - const real invmass[], const real distance_squared_tolerance[], real scaled_lagrange_multiplier[], - int *nerror, real invdt) +static void crattle(const int iatom[], + int ncon, + int* nnit, + int maxnit, + const real constraint_distance_squared[], + real vp[], + const real rij[], + const real m2[], + real omega, + const real invmass[], + const real distance_squared_tolerance[], + real scaled_lagrange_multiplier[], + int* nerror, + real invdt) { /* * r.c. van schaik and w.f. van gunsteren @@ -462,13 +469,13 @@ crattle(const int iatom[], int ncon, int *nnit, int maxnit, * second part of rattle algorithm */ - int ll, i, j, i3, j3, l3; - int ix, iy, iz, jx, jy, jz; - real constraint_distance_squared_ll; - real vpijd, vx, vy, vz, acor, fac, im, jm; - real xh, yh, zh, rijx, rijy, rijz; - int nit, error, nconv; - real iconvf; + int ll, i, j, i3, j3, l3; + int ix, iy, iz, jx, jy, jz; + real constraint_distance_squared_ll; + real vpijd, vx, vy, vz, acor, fac, im, jm; + real xh, yh, zh, rijx, rijy, rijz; + int nit, error, nconv; + real iconvf; // TODO nconv is used solely as a boolean, so we should write the // code like that @@ -479,49 +486,49 @@ crattle(const int iatom[], int ncon, int *nnit, int maxnit, nconv = 0; for (ll = 0; (ll < ncon) && (error == 0); ll++) { - l3 = 3*ll; - rijx = rij[l3+XX]; - rijy = rij[l3+YY]; - rijz = rij[l3+ZZ]; - i = iatom[l3+1]; - j = iatom[l3+2]; - i3 = 3*i; - j3 = 3*j; - ix = i3+XX; - iy = i3+YY; - iz = i3+ZZ; - jx = j3+XX; - jy = j3+YY; - jz = j3+ZZ; - vx = vp[ix]-vp[jx]; - vy = vp[iy]-vp[jy]; - vz = vp[iz]-vp[jz]; - - vpijd = vx*rijx+vy*rijy+vz*rijz; + l3 = 3 * ll; + rijx = rij[l3 + XX]; + rijy = rij[l3 + YY]; + rijz = rij[l3 + ZZ]; + i = iatom[l3 + 1]; + j = iatom[l3 + 2]; + i3 = 3 * i; + j3 = 3 * j; + ix = i3 + XX; + iy = i3 + YY; + iz = i3 + ZZ; + jx = j3 + XX; + jy = j3 + YY; + jz = j3 + ZZ; + vx = vp[ix] - vp[jx]; + vy = vp[iy] - vp[jy]; + vz = vp[iz] - vp[jz]; + + vpijd = vx * rijx + vy * rijy + vz * rijz; constraint_distance_squared_ll = constraint_distance_squared[ll]; /* iconv is zero when the error is smaller than a bound */ - iconvf = fabs(vpijd)*(distance_squared_tolerance[ll]/invdt); + iconvf = fabs(vpijd) * (distance_squared_tolerance[ll] / invdt); if (iconvf > 1) { - nconv = static_cast(iconvf); - fac = omega*2.0*m2[ll]/constraint_distance_squared_ll; - acor = -fac*vpijd; + nconv = static_cast(iconvf); + fac = omega * 2.0 * m2[ll] / constraint_distance_squared_ll; + acor = -fac * vpijd; scaled_lagrange_multiplier[ll] += acor; - xh = rijx*acor; - yh = rijy*acor; - zh = rijz*acor; - - im = invmass[i]; - jm = invmass[j]; - - vp[ix] += xh*im; - vp[iy] += yh*im; - vp[iz] += zh*im; - vp[jx] -= xh*jm; - vp[jy] -= yh*jm; - vp[jz] -= zh*jm; + xh = rijx * acor; + yh = rijy * acor; + zh = rijz * acor; + + im = invmass[i]; + jm = invmass[j]; + + vp[ix] += xh * im; + vp[iy] += yh * im; + vp[iz] += zh * im; + vp[jx] -= xh * jm; + vp[jy] -= yh * jm; + vp[jz] -= zh * jm; } } } @@ -530,19 +537,30 @@ crattle(const int iatom[], int ncon, int *nnit, int maxnit, } //! Applies SHAKE -static int vec_shakef(FILE *fplog, shakedata *shaked, - const real invmass[], int ncon, - t_iparams ip[], t_iatom *iatom, - real tol, const rvec x[], rvec prime[], real omega, - bool bFEP, real lambda, real scaled_lagrange_multiplier[], - real invdt, rvec *v, - bool bCalcVir, tensor vir_r_m_dr, ConstraintVariable econq) +static int vec_shakef(FILE* fplog, + shakedata* shaked, + const real invmass[], + int ncon, + t_iparams ip[], + t_iatom* iatom, + real tol, + const rvec x[], + rvec prime[], + real omega, + bool bFEP, + real lambda, + real scaled_lagrange_multiplier[], + real invdt, + rvec* v, + bool bCalcVir, + tensor vir_r_m_dr, + ConstraintVariable econq) { - rvec *rij; - real *half_of_reduced_mass, *distance_squared_tolerance, *constraint_distance_squared; + rvec* rij; + real * half_of_reduced_mass, *distance_squared_tolerance, *constraint_distance_squared; int maxnit = 1000; int nit = 0, ll, i, j, d, d2, type; - t_iatom *ia; + t_iatom* ia; real L1; real mm = 0., tmp; int error = 0; @@ -556,46 +574,49 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, srenew(shaked->distance_squared_tolerance, shaked->nalloc); srenew(shaked->constraint_distance_squared, shaked->nalloc); } - rij = shaked->rij; - half_of_reduced_mass = shaked->half_of_reduced_mass; - distance_squared_tolerance = shaked->distance_squared_tolerance; - constraint_distance_squared = shaked->constraint_distance_squared; + rij = shaked->rij; + half_of_reduced_mass = shaked->half_of_reduced_mass; + distance_squared_tolerance = shaked->distance_squared_tolerance; + constraint_distance_squared = shaked->constraint_distance_squared; - L1 = 1.0-lambda; - ia = iatom; + L1 = 1.0 - lambda; + ia = iatom; for (ll = 0; (ll < ncon); ll++, ia += 3) { - type = ia[0]; - i = ia[1]; - j = ia[2]; - - mm = 2.0*(invmass[i]+invmass[j]); - rij[ll][XX] = x[i][XX]-x[j][XX]; - rij[ll][YY] = x[i][YY]-x[j][YY]; - rij[ll][ZZ] = x[i][ZZ]-x[j][ZZ]; - half_of_reduced_mass[ll] = 1.0/mm; + type = ia[0]; + i = ia[1]; + j = ia[2]; + + mm = 2.0 * (invmass[i] + invmass[j]); + rij[ll][XX] = x[i][XX] - x[j][XX]; + rij[ll][YY] = x[i][YY] - x[j][YY]; + rij[ll][ZZ] = x[i][ZZ] - x[j][ZZ]; + half_of_reduced_mass[ll] = 1.0 / mm; if (bFEP) { - constraint_distance = L1*ip[type].constr.dA + lambda*ip[type].constr.dB; + constraint_distance = L1 * ip[type].constr.dA + lambda * ip[type].constr.dB; } else { constraint_distance = ip[type].constr.dA; } - constraint_distance_squared[ll] = gmx::square(constraint_distance); - distance_squared_tolerance[ll] = 0.5/(constraint_distance_squared[ll]*tol); + constraint_distance_squared[ll] = gmx::square(constraint_distance); + distance_squared_tolerance[ll] = 0.5 / (constraint_distance_squared[ll] * tol); } switch (econq) { case ConstraintVariable::Positions: - cshake(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime[0], rij[0], half_of_reduced_mass, omega, invmass, distance_squared_tolerance, scaled_lagrange_multiplier, &error); + cshake(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime[0], rij[0], + half_of_reduced_mass, omega, invmass, distance_squared_tolerance, + scaled_lagrange_multiplier, &error); break; case ConstraintVariable::Velocities: - crattle(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime[0], rij[0], half_of_reduced_mass, omega, invmass, distance_squared_tolerance, scaled_lagrange_multiplier, &error, invdt); + crattle(iatom, ncon, &nit, maxnit, constraint_distance_squared, prime[0], rij[0], + half_of_reduced_mass, omega, invmass, distance_squared_tolerance, + scaled_lagrange_multiplier, &error, invdt); break; - default: - gmx_incons("Unknown constraint quantity for SHAKE"); + default: gmx_incons("Unknown constraint quantity for SHAKE"); } if (nit >= maxnit) @@ -611,13 +632,15 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, { if (fplog) { - fprintf(fplog, "Inner product between old and new vector <= 0.0!\n" + fprintf(fplog, + "Inner product between old and new vector <= 0.0!\n" "constraint #%d atoms %d and %d\n", - error-1, iatom[3*(error-1)+1]+1, iatom[3*(error-1)+2]+1); + error - 1, iatom[3 * (error - 1) + 1] + 1, iatom[3 * (error - 1) + 2] + 1); } - fprintf(stderr, "Inner product between old and new vector <= 0.0!\n" + fprintf(stderr, + "Inner product between old and new vector <= 0.0!\n" "constraint #%d atoms %d and %d\n", - error-1, iatom[3*(error-1)+1]+1, iatom[3*(error-1)+2]+1); + error - 1, iatom[3 * (error - 1) + 1] + 1, iatom[3 * (error - 1) + 2] + 1); nit = 0; } @@ -627,22 +650,22 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, for (ll = 0; (ll < ncon); ll++, ia += 3) { - type = ia[0]; - i = ia[1]; - j = ia[2]; + type = ia[0]; + i = ia[1]; + j = ia[2]; if ((econq == ConstraintVariable::Positions) && v != nullptr) { /* Correct the velocities */ - mm = scaled_lagrange_multiplier[ll]*invmass[i]*invdt; + mm = scaled_lagrange_multiplier[ll] * invmass[i] * invdt; for (d = 0; d < DIM; d++) { - v[ia[1]][d] += mm*rij[ll][d]; + v[ia[1]][d] += mm * rij[ll][d]; } - mm = scaled_lagrange_multiplier[ll]*invmass[j]*invdt; + mm = scaled_lagrange_multiplier[ll] * invmass[j] * invdt; for (d = 0; d < DIM; d++) { - v[ia[2]][d] -= mm*rij[ll][d]; + v[ia[2]][d] -= mm * rij[ll][d]; } /* 16 flops */ } @@ -653,10 +676,10 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, mm = scaled_lagrange_multiplier[ll]; for (d = 0; d < DIM; d++) { - tmp = mm*rij[ll][d]; + tmp = mm * rij[ll][d]; for (d2 = 0; d2 < DIM; d2++) { - vir_r_m_dr[d][d2] -= tmp*rij[ll][d2]; + vir_r_m_dr[d][d2] -= tmp * rij[ll][d2]; } } /* 21 flops */ @@ -666,7 +689,7 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, the reciprocal of the constraint length, so fix that */ if (bFEP) { - constraint_distance = L1*ip[type].constr.dA + lambda*ip[type].constr.dB; + constraint_distance = L1 * ip[type].constr.dA + lambda * ip[type].constr.dB; } else { @@ -679,19 +702,24 @@ static int vec_shakef(FILE *fplog, shakedata *shaked, } //! Check that constraints are satisfied. -static void check_cons(FILE *log, int nc, const rvec x[], rvec prime[], rvec v[], - t_iparams ip[], t_iatom *iatom, - const real invmass[], ConstraintVariable econq) +static void check_cons(FILE* log, + int nc, + const rvec x[], + rvec prime[], + rvec v[], + t_iparams ip[], + t_iatom* iatom, + const real invmass[], + ConstraintVariable econq) { - t_iatom *ia; + t_iatom* ia; int ai, aj; int i; real d, dp; rvec dx, dv; GMX_ASSERT(v, "Input has to be non-null"); - fprintf(log, - " i mi j mj before after should be\n"); + fprintf(log, " i mi j mj before after should be\n"); ia = iatom; for (i = 0; (i < nc); i++, ia += 3) { @@ -705,40 +733,46 @@ static void check_cons(FILE *log, int nc, const rvec x[], rvec prime[], rvec v[] case ConstraintVariable::Positions: rvec_sub(prime[ai], prime[aj], dx); dp = norm(dx); - fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", - ai+1, 1.0/invmass[ai], - aj+1, 1.0/invmass[aj], d, dp, ip[ia[0]].constr.dA); + fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", ai + 1, + 1.0 / invmass[ai], aj + 1, 1.0 / invmass[aj], d, dp, ip[ia[0]].constr.dA); break; case ConstraintVariable::Velocities: rvec_sub(v[ai], v[aj], dv); d = iprod(dx, dv); rvec_sub(prime[ai], prime[aj], dv); dp = iprod(dx, dv); - fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", - ai+1, 1.0/invmass[ai], - aj+1, 1.0/invmass[aj], d, dp, 0.); + fprintf(log, "%5d %5.2f %5d %5.2f %10.5f %10.5f %10.5f\n", ai + 1, + 1.0 / invmass[ai], aj + 1, 1.0 / invmass[aj], d, dp, 0.); break; - default: - gmx_incons("Unknown constraint quantity for SHAKE"); + default: gmx_incons("Unknown constraint quantity for SHAKE"); } } } //! Applies SHAKE. -static bool -bshakef(FILE *log, shakedata *shaked, - const real invmass[], - const t_idef &idef, const t_inputrec &ir, const rvec x_s[], rvec prime[], - t_nrnb *nrnb, real lambda, real *dvdlambda, - real invdt, rvec *v, bool bCalcVir, tensor vir_r_m_dr, - bool bDumpOnError, ConstraintVariable econq) +static bool bshakef(FILE* log, + shakedata* shaked, + const real invmass[], + const t_idef& idef, + const t_inputrec& ir, + const rvec x_s[], + rvec prime[], + t_nrnb* nrnb, + real lambda, + real* dvdlambda, + real invdt, + rvec* v, + bool bCalcVir, + tensor vir_r_m_dr, + bool bDumpOnError, + ConstraintVariable econq) { - t_iatom *iatoms; - real *lam, dt_2, dvdl; + t_iatom* iatoms; + real * lam, dt_2, dvdl; int i, n0, ncon, blen, type, ll; int tnit = 0, trij = 0; - ncon = idef.il[F_CONSTR].nr/3; + ncon = idef.il[F_CONSTR].nr / 3; for (ll = 0; ll < ncon; ll++) { @@ -750,14 +784,13 @@ bshakef(FILE *log, shakedata *shaked, // sblock data structure is organized differently? iatoms = &(idef.il[F_CONSTR].iatoms[shaked->sblock[0]]); lam = shaked->scaled_lagrange_multiplier; - for (i = 0; (i < shaked->nblocks); ) + for (i = 0; (i < shaked->nblocks);) { - blen = (shaked->sblock[i+1]-shaked->sblock[i]); + blen = (shaked->sblock[i + 1] - shaked->sblock[i]); blen /= 3; - n0 = vec_shakef(log, shaked, invmass, blen, idef.iparams, - iatoms, ir.shake_tol, x_s, prime, shaked->omega, - ir.efep != efepNO, lambda, lam, invdt, v, bCalcVir, vir_r_m_dr, - econq); + n0 = vec_shakef(log, shaked, invmass, blen, idef.iparams, iatoms, ir.shake_tol, x_s, prime, + shaked->omega, ir.efep != efepNO, lambda, lam, invdt, v, bCalcVir, + vir_r_m_dr, econq); if (n0 == 0) { @@ -769,10 +802,10 @@ bshakef(FILE *log, shakedata *shaked, } return FALSE; } - tnit += n0*blen; - trij += blen; - iatoms += 3*blen; /* Increment pointer! */ - lam += blen; + tnit += n0 * blen; + trij += blen; + iatoms += 3 * blen; /* Increment pointer! */ + lam += blen; i++; } /* only for position part? */ @@ -782,16 +815,16 @@ bshakef(FILE *log, shakedata *shaked, { real bondA, bondB; /* TODO This should probably use invdt, so that sd integrator scaling works properly */ - dt_2 = 1/gmx::square(ir.delta_t); + dt_2 = 1 / gmx::square(ir.delta_t); dvdl = 0; for (ll = 0; ll < ncon; ll++) { - type = idef.il[F_CONSTR].iatoms[3*ll]; + type = idef.il[F_CONSTR].iatoms[3 * ll]; /* Per equations in the manual, dv/dl = -2 \sum_ll lagrangian_ll * r_ll * (d_B - d_A) */ - /* The vector scaled_lagrange_multiplier[ll] contains the value -2 r_ll eta_ll (eta_ll is the - estimate of the Langrangian, definition on page 336 of Ryckaert et al 1977), - so the pre-factors are already present. */ + /* The vector scaled_lagrange_multiplier[ll] contains the value -2 r_ll eta_ll + (eta_ll is the estimate of the Langrangian, definition on page 336 of Ryckaert et + al 1977), so the pre-factors are already present. */ bondA = idef.iparams[type].constr.dA; bondB = idef.iparams[type].constr.dB; dvdl += shaked->scaled_lagrange_multiplier[ll] * dt_2 * (bondB - bondA); @@ -806,13 +839,13 @@ bshakef(FILE *log, shakedata *shaked, shaked->delta *= -0.5; } shaked->omega += shaked->delta; - shaked->gamma = tnit; + shaked->gamma = tnit; } inc_nrnb(nrnb, eNR_SHAKE, tnit); inc_nrnb(nrnb, eNR_SHAKE_RIJ, trij); if (v) { - inc_nrnb(nrnb, eNR_CONSTR_V, trij*2); + inc_nrnb(nrnb, eNR_CONSTR_V, trij * 2); } if (bCalcVir) { @@ -822,24 +855,23 @@ bshakef(FILE *log, shakedata *shaked, return TRUE; } -bool -constrain_shake(FILE *log, - shakedata *shaked, - const real invmass[], - const t_idef &idef, - const t_inputrec &ir, - const rvec x_s[], - rvec xprime[], - rvec vprime[], - t_nrnb *nrnb, - real lambda, - real *dvdlambda, - real invdt, - rvec *v, - bool bCalcVir, - tensor vir_r_m_dr, - bool bDumpOnError, - ConstraintVariable econq) +bool constrain_shake(FILE* log, + shakedata* shaked, + const real invmass[], + const t_idef& idef, + const t_inputrec& ir, + const rvec x_s[], + rvec xprime[], + rvec vprime[], + t_nrnb* nrnb, + real lambda, + real* dvdlambda, + real invdt, + rvec* v, + bool bCalcVir, + tensor vir_r_m_dr, + bool bDumpOnError, + ConstraintVariable econq) { if (shaked->nblocks == 0) { @@ -849,25 +881,19 @@ constrain_shake(FILE *log, switch (econq) { case (ConstraintVariable::Positions): - bOK = bshakef(log, shaked, - invmass, - idef, ir, x_s, xprime, nrnb, - lambda, dvdlambda, - invdt, v, bCalcVir, vir_r_m_dr, - bDumpOnError, econq); + bOK = bshakef(log, shaked, invmass, idef, ir, x_s, xprime, nrnb, lambda, dvdlambda, + invdt, v, bCalcVir, vir_r_m_dr, bDumpOnError, econq); break; case (ConstraintVariable::Velocities): - bOK = bshakef(log, shaked, - invmass, - idef, ir, x_s, vprime, nrnb, - lambda, dvdlambda, - invdt, nullptr, bCalcVir, vir_r_m_dr, - bDumpOnError, econq); + bOK = bshakef(log, shaked, invmass, idef, ir, x_s, vprime, nrnb, lambda, dvdlambda, + invdt, nullptr, bCalcVir, vir_r_m_dr, bDumpOnError, econq); break; default: - gmx_fatal(FARGS, "Internal error, SHAKE called for constraining something else than coordinates"); + gmx_fatal(FARGS, + "Internal error, SHAKE called for constraining something else than " + "coordinates"); } return bOK; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/shake.h b/src/gromacs/mdlib/shake.h index c1e19b14a6..1249d3c1f5 100644 --- a/src/gromacs/mdlib/shake.h +++ b/src/gromacs/mdlib/shake.h @@ -62,21 +62,16 @@ enum class ConstraintVariable : int; struct shakedata; /*! \brief Initializes and return the SHAKE data structure */ -shakedata *shake_init(); +shakedata* shake_init(); //! Destroy SHAKE. Needed to solve memory leaks. -void done_shake(shakedata *d); +void done_shake(shakedata* d); //! Make SHAKE blocks when not using DD. -void -make_shake_sblock_serial(shakedata *shaked, - const t_idef *idef, const t_mdatoms &md); +void make_shake_sblock_serial(shakedata* shaked, const t_idef* idef, const t_mdatoms& md); //! Make SHAKE blocks when using DD. -void -make_shake_sblock_dd(shakedata *shaked, - const t_ilist *ilcon, - const gmx_domdec_t *dd); +void make_shake_sblock_dd(shakedata* shaked, const t_ilist* ilcon, const gmx_domdec_t* dd); /*! \brief Shake all the atoms blockwise. It is assumed that all the constraints * in the idef->shakes field are sorted, to ascending block nr. The @@ -86,30 +81,39 @@ make_shake_sblock_dd(shakedata *shaked, * sblock[n] to sblock[n+1]. Array sblock should be large enough. * Return TRUE when OK, FALSE when shake-error */ -bool -constrain_shake(FILE *log, /* Log file */ - shakedata *shaked, /* Total number of atoms */ - const real invmass[], /* Atomic masses */ - const t_idef &idef, /* The interaction def */ - const t_inputrec &ir, /* Input record */ - const rvec x_s[], /* Coords before update */ - rvec xprime[], /* Output coords when constraining x */ - rvec vprime[], /* Output coords when constraining v */ - t_nrnb *nrnb, /* Performance measure */ - real lambda, /* FEP lambda */ - real *dvdlambda, /* FEP force */ - real invdt, /* 1/delta_t */ - rvec *v, /* Also constrain v if v!=NULL */ - bool bCalcVir, /* Calculate r x m delta_r */ - tensor vir_r_m_dr, /* sum r x m delta_r */ - bool bDumpOnError, /* Dump debugging stuff on error*/ - ConstraintVariable econq); /* which type of constraint is occurring */ +bool constrain_shake(FILE* log, /* Log file */ + shakedata* shaked, /* Total number of atoms */ + const real invmass[], /* Atomic masses */ + const t_idef& idef, /* The interaction def */ + const t_inputrec& ir, /* Input record */ + const rvec x_s[], /* Coords before update */ + rvec xprime[], /* Output coords when constraining x */ + rvec vprime[], /* Output coords when constraining v */ + t_nrnb* nrnb, /* Performance measure */ + real lambda, /* FEP lambda */ + real* dvdlambda, /* FEP force */ + real invdt, /* 1/delta_t */ + rvec* v, /* Also constrain v if v!=NULL */ + bool bCalcVir, /* Calculate r x m delta_r */ + tensor vir_r_m_dr, /* sum r x m delta_r */ + bool bDumpOnError, /* Dump debugging stuff on error*/ + ConstraintVariable econq); /* which type of constraint is occurring */ /*! \brief Regular iterative shake */ -void cshake(const int iatom[], int ncon, int *nnit, int maxnit, - const real dist2[], real xp[], const real rij[], const real m2[], real omega, - const real invmass[], const real tt[], real lagr[], int *nerror); +void cshake(const int iatom[], + int ncon, + int* nnit, + int maxnit, + const real dist2[], + real xp[], + const real rij[], + const real m2[], + real omega, + const real invmass[], + const real tt[], + real lagr[], + int* nerror); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/sighandler.cpp b/src/gromacs/mdlib/sighandler.cpp index c0d394a1fb..c883edee32 100644 --- a/src/gromacs/mdlib/sighandler.cpp +++ b/src/gromacs/mdlib/sighandler.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,26 +45,14 @@ #include "gromacs/utility/fatalerror.h" -const char *gmx_stop_cond_name[] = -{ - "None", - "Stop at the next neighbor search step", - "Stop at the next step", - "Abort" -}; +const char* gmx_stop_cond_name[] = { "None", "Stop at the next neighbor search step", + "Stop at the next step", "Abort" }; /* these do not neccesarily match the stop condition, but are referred to in the signal handler. */ -static const char *gmx_signal_name[] = -{ - "None", - "INT", - "TERM", - "second INT/TERM", - "remote INT/TERM", - "remote second INT/TERM", - "USR1", - "Abort" +static const char* gmx_signal_name[] = { + "None", "INT", "TERM", "second INT/TERM", "remote INT/TERM", "remote second INT/TERM", + "USR1", "Abort" }; static volatile sig_atomic_t stop_condition = gmx_stop_cond_none; @@ -74,7 +62,7 @@ static volatile sig_atomic_t usr_condition = 0; void gmx_reset_stop_condition() { - stop_condition = gmx_stop_cond_none; + stop_condition = gmx_stop_cond_none; // last_signal_name and usr_condition are left untouched by reset. } @@ -82,9 +70,9 @@ static void signal_handler(int n) { switch (n) { -/* windows doesn't do SIGINT correctly according to ANSI (yes, signals are in - ANSI C89, and windows spawns a thread specifically to run the INT signal - handler), but that doesn't matter for a simple signal handler like this. */ + /* windows doesn't do SIGINT correctly according to ANSI (yes, signals are in + ANSI C89, and windows spawns a thread specifically to run the INT signal + handler), but that doesn't matter for a simple signal handler like this. */ case SIGTERM: case SIGINT: /* we explicitly set things up to allow this: */ @@ -107,12 +95,9 @@ static void signal_handler(int n) } break; #if HAVE_SIGUSR1 - case SIGUSR1: - usr_condition = 1; - break; + case SIGUSR1: usr_condition = 1; break; #endif - default: - break; + default: break; } } @@ -180,7 +165,7 @@ void gmx_set_stop_condition(gmx_stop_cond_t recvd_stop_cond) } } -const char *gmx_get_signal_name() +const char* gmx_get_signal_name() { return gmx_signal_name[last_signal_name]; } @@ -188,7 +173,7 @@ const char *gmx_get_signal_name() gmx_bool gmx_got_usr_signal() { #if HAVE_SIGUSR1 - gmx_bool ret = static_cast(usr_condition); + gmx_bool ret = static_cast(usr_condition); usr_condition = 0; return ret; #else diff --git a/src/gromacs/mdlib/sighandler.h b/src/gromacs/mdlib/sighandler.h index 6ed971178e..35e8312037 100644 --- a/src/gromacs/mdlib/sighandler.h +++ b/src/gromacs/mdlib/sighandler.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,7 +56,7 @@ typedef enum /* Our names for the stop conditions. These must match the number given in gmx_stop_cond_t.*/ -extern const char *gmx_stop_cond_name[]; +extern const char* gmx_stop_cond_name[]; /* the externally visible functions: */ @@ -84,7 +84,7 @@ void gmx_set_stop_condition(gmx_stop_cond_t recvd_stop_cond); void gmx_reset_stop_condition(); /* get the signal name that lead to the current stop condition. */ -const char *gmx_get_signal_name(); +const char* gmx_get_signal_name(); /* check whether we received a USR1 signal. The condition is reset once a TRUE value is returned, so this function diff --git a/src/gromacs/mdlib/sim_util.cpp b/src/gromacs/mdlib/sim_util.cpp index d8edf70422..0183e47271 100644 --- a/src/gromacs/mdlib/sim_util.cpp +++ b/src/gromacs/mdlib/sim_util.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -114,12 +114,12 @@ #include "gromacs/utility/strconvert.h" #include "gromacs/utility/sysinfo.h" -using gmx::ForceOutputs; -using gmx::StepWorkload; -using gmx::DomainLifetimeWorkload; -using gmx::SimulationWorkload; using gmx::AtomLocality; +using gmx::DomainLifetimeWorkload; +using gmx::ForceOutputs; using gmx::InteractionLocality; +using gmx::SimulationWorkload; +using gmx::StepWorkload; // TODO: this environment variable allows us to verify before release // that on less common architectures the total cost of polling is not larger than @@ -129,7 +129,7 @@ static const bool c_disableAlternatingWait = (getenv("GMX_DISABLE_ALTERNATING_GP static void sum_forces(rvec f[], gmx::ArrayRef forceToAdd) { - const int end = forceToAdd.size(); + const int end = forceToAdd.size(); int gmx_unused nt = gmx_omp_nthreads_get(emntDefault); #pragma omp parallel for num_threads(nt) schedule(static) @@ -139,21 +139,27 @@ static void sum_forces(rvec f[], gmx::ArrayRef forceToAdd) } } -static void calc_virial(int start, int homenr, const rvec x[], - const gmx::ForceWithShiftForces &forceWithShiftForces, - tensor vir_part, const t_graph *graph, const matrix box, - t_nrnb *nrnb, const t_forcerec *fr, int ePBC) +static void calc_virial(int start, + int homenr, + const rvec x[], + const gmx::ForceWithShiftForces& forceWithShiftForces, + tensor vir_part, + const t_graph* graph, + const matrix box, + t_nrnb* nrnb, + const t_forcerec* fr, + int ePBC) { /* The short-range virial from surrounding boxes */ - const rvec *fshift = as_rvec_array(forceWithShiftForces.shiftForces().data()); + const rvec* fshift = as_rvec_array(forceWithShiftForces.shiftForces().data()); calc_vir(SHIFTS, fr->shift_vec, fshift, vir_part, ePBC == epbcSCREW, box); inc_nrnb(nrnb, eNR_VIRIAL, SHIFTS); /* Calculate partial virial, for local atoms only, based on short range. * Total virial is computed in global_stat, called from do_md */ - const rvec *f = as_rvec_array(forceWithShiftForces.force().data()); - f_calc_vir(start, start+homenr, x, f, vir_part, graph, box); + const rvec* f = as_rvec_array(forceWithShiftForces.force().data()); + f_calc_vir(start, start + homenr, x, f, vir_part, graph, box); inc_nrnb(nrnb, eNR_VIRIAL, homenr); if (debug) @@ -162,43 +168,43 @@ static void calc_virial(int start, int homenr, const rvec x[], } } -static void pull_potential_wrapper(const t_commrec *cr, - const t_inputrec *ir, - const matrix box, gmx::ArrayRef x, - gmx::ForceWithVirial *force, - const t_mdatoms *mdatoms, - gmx_enerdata_t *enerd, - pull_t *pull_work, - const real *lambda, - double t, - gmx_wallcycle_t wcycle) +static void pull_potential_wrapper(const t_commrec* cr, + const t_inputrec* ir, + const matrix box, + gmx::ArrayRef x, + gmx::ForceWithVirial* force, + const t_mdatoms* mdatoms, + gmx_enerdata_t* enerd, + pull_t* pull_work, + const real* lambda, + double t, + gmx_wallcycle_t wcycle) { - t_pbc pbc; - real dvdl; + t_pbc pbc; + real dvdl; /* Calculate the center of mass forces, this requires communication, * which is why pull_potential is called close to other communication. */ wallcycle_start(wcycle, ewcPULLPOT); set_pbc(&pbc, ir->ePBC, box); - dvdl = 0; - enerd->term[F_COM_PULL] += - pull_potential(pull_work, mdatoms, &pbc, - cr, t, lambda[efptRESTRAINT], as_rvec_array(x.data()), force, &dvdl); + dvdl = 0; + enerd->term[F_COM_PULL] += pull_potential(pull_work, mdatoms, &pbc, cr, t, lambda[efptRESTRAINT], + as_rvec_array(x.data()), force, &dvdl); enerd->dvdl_lin[efptRESTRAINT] += dvdl; wallcycle_stop(wcycle, ewcPULLPOT); } -static void pme_receive_force_ener(t_forcerec *fr, - const t_commrec *cr, - gmx::ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd, +static void pme_receive_force_ener(t_forcerec* fr, + const t_commrec* cr, + gmx::ForceWithVirial* forceWithVirial, + gmx_enerdata_t* enerd, bool useGpuPmePpComms, bool receivePmeForceToGpu, gmx_wallcycle_t wcycle) { - real e_q, e_lj, dvdl_q, dvdl_lj; - float cycles_ppdpme, cycles_seppme; + real e_q, e_lj, dvdl_q, dvdl_lj; + float cycles_ppdpme, cycles_seppme; cycles_ppdpme = wallcycle_stop(wcycle, ewcPPDURINGPME); dd_cycles_add(cr->dd, cycles_ppdpme, ddCyclPPduringPME); @@ -209,13 +215,12 @@ static void pme_receive_force_ener(t_forcerec *fr, wallcycle_start(wcycle, ewcPP_PMEWAITRECVF); dvdl_q = 0; dvdl_lj = 0; - gmx_pme_receive_f(fr->pmePpCommGpu.get(), - cr, forceWithVirial, &e_q, &e_lj, &dvdl_q, &dvdl_lj, + gmx_pme_receive_f(fr->pmePpCommGpu.get(), cr, forceWithVirial, &e_q, &e_lj, &dvdl_q, &dvdl_lj, useGpuPmePpComms, receivePmeForceToGpu, &cycles_seppme); enerd->term[F_COUL_RECIP] += e_q; - enerd->term[F_LJ_RECIP] += e_lj; + enerd->term[F_LJ_RECIP] += e_lj; enerd->dvdl_lin[efptCOUL] += dvdl_q; - enerd->dvdl_lin[efptVDW] += dvdl_lj; + enerd->dvdl_lin[efptVDW] += dvdl_lj; if (wcycle) { @@ -224,24 +229,23 @@ static void pme_receive_force_ener(t_forcerec *fr, wallcycle_stop(wcycle, ewcPP_PMEWAITRECVF); } -static void print_large_forces(FILE *fp, - const t_mdatoms *md, - const t_commrec *cr, +static void print_large_forces(FILE* fp, + const t_mdatoms* md, + const t_commrec* cr, int64_t step, real forceTolerance, - const rvec *x, - const rvec *f) + const rvec* x, + const rvec* f) { - real force2Tolerance = gmx::square(forceTolerance); - gmx::index numNonFinite = 0; + real force2Tolerance = gmx::square(forceTolerance); + gmx::index numNonFinite = 0; for (int i = 0; i < md->homenr; i++) { real force2 = norm2(f[i]); bool nonFinite = !std::isfinite(force2); if (force2 >= force2Tolerance || nonFinite) { - fprintf(fp, "step %" PRId64 " atom %6d x %8.3f %8.3f %8.3f force %12.5e\n", - step, + fprintf(fp, "step %" PRId64 " atom %6d x %8.3f %8.3f %8.3f force %12.5e\n", step, ddglatnr(cr->dd, i), x[i][XX], x[i][YY], x[i][ZZ], std::sqrt(force2)); } if (nonFinite) @@ -259,27 +263,27 @@ static void print_large_forces(FILE *fp, } } -static void post_process_forces(const t_commrec *cr, - int64_t step, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - const gmx_localtop_t *top, - const matrix box, - const rvec x[], - ForceOutputs *forceOutputs, - tensor vir_force, - const t_mdatoms *mdatoms, - const t_graph *graph, - const t_forcerec *fr, - const gmx_vsite_t *vsite, - const StepWorkload &stepWork) +static void post_process_forces(const t_commrec* cr, + int64_t step, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + const gmx_localtop_t* top, + const matrix box, + const rvec x[], + ForceOutputs* forceOutputs, + tensor vir_force, + const t_mdatoms* mdatoms, + const t_graph* graph, + const t_forcerec* fr, + const gmx_vsite_t* vsite, + const StepWorkload& stepWork) { - rvec *f = as_rvec_array(forceOutputs->forceWithShiftForces().force().data()); + rvec* f = as_rvec_array(forceOutputs->forceWithShiftForces().force().data()); if (fr->haveDirectVirialContributions) { - auto &forceWithVirial = forceOutputs->forceWithVirial(); - rvec *fDirectVir = as_rvec_array(forceWithVirial.force_.data()); + auto& forceWithVirial = forceOutputs->forceWithVirial(); + rvec* fDirectVir = as_rvec_array(forceWithVirial.force_.data()); if (vsite) { @@ -288,9 +292,7 @@ static void post_process_forces(const t_commrec *cr, * if the constructing atoms aren't local. */ matrix virial = { { 0 } }; - spread_vsite_f(vsite, x, fDirectVir, nullptr, - stepWork.computeVirial, virial, - nrnb, + spread_vsite_f(vsite, x, fDirectVir, nullptr, stepWork.computeVirial, virial, nrnb, &top->idef, fr->ePBC, fr->bMolPBC, graph, box, cr, wcycle); forceWithVirial.addVirialContribution(virial); } @@ -301,7 +303,9 @@ static void post_process_forces(const t_commrec *cr, sum_forces(f, forceWithVirial.force_); /* Add the direct virial contributions */ - GMX_ASSERT(forceWithVirial.computeVirial_, "forceWithVirial should request virial computation when we request the virial"); + GMX_ASSERT( + forceWithVirial.computeVirial_, + "forceWithVirial should request virial computation when we request the virial"); m_add(vir_force, forceWithVirial.getVirial(), vir_force); if (debug) @@ -317,15 +321,15 @@ static void post_process_forces(const t_commrec *cr, } } -static void do_nb_verlet(t_forcerec *fr, - const interaction_const_t *ic, - gmx_enerdata_t *enerd, - const StepWorkload &stepWork, - const InteractionLocality ilocality, - const int clearF, - const int64_t step, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle) +static void do_nb_verlet(t_forcerec* fr, + const interaction_const_t* ic, + gmx_enerdata_t* enerd, + const StepWorkload& stepWork, + const InteractionLocality ilocality, + const int clearF, + const int64_t step, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle) { if (!stepWork.computeNonbondedForces) { @@ -333,7 +337,7 @@ static void do_nb_verlet(t_forcerec *fr, return; } - nonbonded_verlet_t *nbv = fr->nbv.get(); + nonbonded_verlet_t* nbv = fr->nbv.get(); /* GPU kernel launch overhead is already timed separately */ if (fr->cutoff_scheme != ecutsVERLET) @@ -389,7 +393,7 @@ static inline void clear_rvecs_omp(int n, rvec v[]) * * \param groupOptions Group options, containing T-coupling options */ -static real averageKineticEnergyEstimate(const t_grpopts &groupOptions) +static real averageKineticEnergyEstimate(const t_grpopts& groupOptions) { real nrdfCoupled = 0; real nrdfUncoupled = 0; @@ -398,8 +402,8 @@ static real averageKineticEnergyEstimate(const t_grpopts &groupOptions) { if (groupOptions.tau_t[g] >= 0) { - nrdfCoupled += groupOptions.nrdf[g]; - kineticEnergy += groupOptions.nrdf[g]*0.5*groupOptions.ref_t[g]*BOLTZ; + nrdfCoupled += groupOptions.nrdf[g]; + kineticEnergy += groupOptions.nrdf[g] * 0.5 * groupOptions.ref_t[g] * BOLTZ; } else { @@ -410,7 +414,7 @@ static real averageKineticEnergyEstimate(const t_grpopts &groupOptions) /* This conditional with > also catches nrdf=0 */ if (nrdfCoupled > nrdfUncoupled) { - return kineticEnergy*(nrdfCoupled + nrdfUncoupled)/nrdfCoupled; + return kineticEnergy * (nrdfCoupled + nrdfUncoupled) / nrdfCoupled; } else { @@ -429,12 +433,10 @@ static real averageKineticEnergyEstimate(const t_grpopts &groupOptions) * and energies are finite. * * \param[in] step The step number, used for checking and printing - * \param[in] enerd The energy data; the non-bonded group energies need to be added to enerd.term[F_EPOT] before calling this routine - * \param[in] inputrec The input record + * \param[in] enerd The energy data; the non-bonded group energies need to be added to + * enerd.term[F_EPOT] before calling this routine \param[in] inputrec The input record */ -static void checkPotentialEnergyValidity(int64_t step, - const gmx_enerdata_t &enerd, - const t_inputrec &inputrec) +static void checkPotentialEnergyValidity(int64_t step, const gmx_enerdata_t& enerd, const t_inputrec& inputrec) { /* Threshold valid for comparing absolute potential energy against * the kinetic energy. Normally one should not consider absolute @@ -443,8 +445,8 @@ static void checkPotentialEnergyValidity(int64_t step, */ constexpr real c_thresholdFactor = 1e6; - bool energyIsNotFinite = !std::isfinite(enerd.term[F_EPOT]); - real averageKineticEnergy = 0; + bool energyIsNotFinite = !std::isfinite(enerd.term[F_EPOT]); + real averageKineticEnergy = 0; /* We only check for large potential energy at the initial step, * because that is by far the most likely step for this too occur * and because computing the average kinetic energy is not free. @@ -456,17 +458,20 @@ static void checkPotentialEnergyValidity(int64_t step, averageKineticEnergy = averageKineticEnergyEstimate(inputrec.opts); } - if (energyIsNotFinite || (averageKineticEnergy > 0 && - enerd.term[F_EPOT] > c_thresholdFactor*averageKineticEnergy)) + if (energyIsNotFinite + || (averageKineticEnergy > 0 && enerd.term[F_EPOT] > c_thresholdFactor * averageKineticEnergy)) { - gmx_fatal(FARGS, "Step %" PRId64 ": The total potential energy is %g, which is %s. The LJ and electrostatic contributions to the energy are %g and %g, respectively. A %s potential energy can be caused by overlapping interactions in bonded interactions or very large%s coordinate values. Usually this is caused by a badly- or non-equilibrated initial configuration, incorrect interactions or parameters in the topology.", - step, - enerd.term[F_EPOT], - energyIsNotFinite ? "not finite" : "extremely high", - enerd.term[F_LJ], - enerd.term[F_COUL_SR], - energyIsNotFinite ? "non-finite" : "very high", - energyIsNotFinite ? " or Nan" : ""); + gmx_fatal( + FARGS, + "Step %" PRId64 + ": The total potential energy is %g, which is %s. The LJ and electrostatic " + "contributions to the energy are %g and %g, respectively. A %s potential energy " + "can be caused by overlapping interactions in bonded interactions or very large%s " + "coordinate values. Usually this is caused by a badly- or non-equilibrated initial " + "configuration, incorrect interactions or parameters in the topology.", + step, enerd.term[F_EPOT], energyIsNotFinite ? "not finite" : "extremely high", + enerd.term[F_LJ], enerd.term[F_COUL_SR], + energyIsNotFinite ? "non-finite" : "very high", energyIsNotFinite ? " or Nan" : ""); } } @@ -474,20 +479,18 @@ static void checkPotentialEnergyValidity(int64_t step, * * The conditionals exactly correspond to those in computeSpecialForces(). */ -static bool -haveSpecialForces(const t_inputrec &inputrec, - const gmx::ForceProviders &forceProviders, - const pull_t *pull_work, - const bool computeForces, - const gmx_edsam *ed) +static bool haveSpecialForces(const t_inputrec& inputrec, + const gmx::ForceProviders& forceProviders, + const pull_t* pull_work, + const bool computeForces, + const gmx_edsam* ed) { - return - ((computeForces && forceProviders.hasForceProvider()) || // forceProviders - (inputrec.bPull && pull_have_potential(pull_work)) || // pull - inputrec.bRot || // enforced rotation - (ed != nullptr) || // flooding - (inputrec.bIMD && computeForces)); // IMD + return ((computeForces && forceProviders.hasForceProvider()) || // forceProviders + (inputrec.bPull && pull_have_potential(pull_work)) || // pull + inputrec.bRot || // enforced rotation + (ed != nullptr) || // flooding + (inputrec.bIMD && computeForces)); // IMD } /*! \brief Compute forces and/or energies for special algorithms @@ -524,27 +527,26 @@ haveSpecialForces(const t_inputrec &inputrec, * \todo Remove didNeighborSearch, which is used incorrectly. * \todo Convert all other algorithms called here to ForceProviders. */ -static void -computeSpecialForces(FILE *fplog, - const t_commrec *cr, - const t_inputrec *inputrec, - gmx::Awh *awh, - gmx_enfrot *enforcedRotation, - gmx::ImdSession *imdSession, - pull_t *pull_work, - int64_t step, - double t, - gmx_wallcycle_t wcycle, - gmx::ForceProviders *forceProviders, - const matrix box, - gmx::ArrayRef x, - const t_mdatoms *mdatoms, - real *lambda, - const StepWorkload &stepWork, - gmx::ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd, - gmx_edsam *ed, - bool didNeighborSearch) +static void computeSpecialForces(FILE* fplog, + const t_commrec* cr, + const t_inputrec* inputrec, + gmx::Awh* awh, + gmx_enfrot* enforcedRotation, + gmx::ImdSession* imdSession, + pull_t* pull_work, + int64_t step, + double t, + gmx_wallcycle_t wcycle, + gmx::ForceProviders* forceProviders, + const matrix box, + gmx::ArrayRef x, + const t_mdatoms* mdatoms, + real* lambda, + const StepWorkload& stepWork, + gmx::ForceWithVirial* forceWithVirial, + gmx_enerdata_t* enerd, + gmx_edsam* ed, + bool didNeighborSearch) { /* NOTE: Currently all ForceProviders only provide forces. * When they also provide energies, remove this conditional. @@ -560,21 +562,17 @@ computeSpecialForces(FILE *fplog, if (inputrec->bPull && pull_have_potential(pull_work)) { - pull_potential_wrapper(cr, inputrec, box, x, - forceWithVirial, - mdatoms, enerd, pull_work, lambda, t, - wcycle); + pull_potential_wrapper(cr, inputrec, box, x, forceWithVirial, mdatoms, enerd, pull_work, + lambda, t, wcycle); if (awh) { - enerd->term[F_COM_PULL] += - awh->applyBiasForcesAndUpdateBias(inputrec->ePBC, *mdatoms, box, - forceWithVirial, - t, step, wcycle, fplog); + enerd->term[F_COM_PULL] += awh->applyBiasForcesAndUpdateBias( + inputrec->ePBC, *mdatoms, box, forceWithVirial, t, step, wcycle, fplog); } } - rvec *f = as_rvec_array(forceWithVirial->force_.data()); + rvec* f = as_rvec_array(forceWithVirial->force_.data()); /* Add the forces from enforced rotation potentials (if any) */ if (inputrec->bRot) @@ -606,12 +604,11 @@ computeSpecialForces(FILE *fplog, * \param[in] stepWork Step schedule flags * \returns PME flags */ -static int makePmeFlags(const StepWorkload &stepWork) +static int makePmeFlags(const StepWorkload& stepWork) { - return GMX_PME_SPREAD | GMX_PME_SOLVE | - (stepWork.computeVirial ? GMX_PME_CALC_ENER_VIR : 0) | - (stepWork.computeEnergy ? GMX_PME_CALC_ENER_VIR : 0) | - (stepWork.computeForces ? GMX_PME_CALC_F : 0); + return GMX_PME_SPREAD | GMX_PME_SOLVE | (stepWork.computeVirial ? GMX_PME_CALC_ENER_VIR : 0) + | (stepWork.computeEnergy ? GMX_PME_CALC_ENER_VIR : 0) + | (stepWork.computeForces ? GMX_PME_CALC_F : 0); } /*! \brief Launch the prepare_step and spread stages of PME GPU. @@ -620,17 +617,18 @@ static int makePmeFlags(const StepWorkload &stepWork) * \param[in] box The box matrix * \param[in] stepWork Step schedule flags * \param[in] pmeFlags PME flags - * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory. - * \param[in] wcycle The wallcycle structure + * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in + * the device memory. \param[in] wcycle The wallcycle structure */ -static inline void launchPmeGpuSpread(gmx_pme_t *pmedata, +static inline void launchPmeGpuSpread(gmx_pme_t* pmedata, const matrix box, - const StepWorkload &stepWork, + const StepWorkload& stepWork, int pmeFlags, - GpuEventSynchronizer *xReadyOnDevice, + GpuEventSynchronizer* xReadyOnDevice, gmx_wallcycle_t wcycle) { - pme_gpu_prepare_computation(pmedata, stepWork.haveDynamicBox, box, wcycle, pmeFlags, stepWork.useGpuPmeFReduction); + pme_gpu_prepare_computation(pmedata, stepWork.haveDynamicBox, box, wcycle, pmeFlags, + stepWork.useGpuPmeFReduction); pme_gpu_launch_spread(pmedata, xReadyOnDevice, wcycle); } @@ -641,8 +639,7 @@ static inline void launchPmeGpuSpread(gmx_pme_t *pmedata, * \param[in] pmedata The PME structure * \param[in] wcycle The wallcycle structure */ -static void launchPmeGpuFftAndGather(gmx_pme_t *pmedata, - gmx_wallcycle_t wcycle) +static void launchPmeGpuFftAndGather(gmx_pme_t* pmedata, gmx_wallcycle_t wcycle) { pme_gpu_launch_complex_transforms(pmedata, wcycle); pme_gpu_launch_gather(pmedata, wcycle, PmeForceOutputHandling::Set); @@ -665,11 +662,11 @@ static void launchPmeGpuFftAndGather(gmx_pme_t *pmedata, * \param[in] pmeFlags PME flags * \param[in] wcycle The wallcycle structure */ -static void alternatePmeNbGpuWaitReduce(nonbonded_verlet_t *nbv, - gmx_pme_t *pmedata, - gmx::ForceOutputs *forceOutputs, - gmx_enerdata_t *enerd, - const StepWorkload &stepWork, +static void alternatePmeNbGpuWaitReduce(nonbonded_verlet_t* nbv, + gmx_pme_t* pmedata, + gmx::ForceOutputs* forceOutputs, + gmx_enerdata_t* enerd, + const StepWorkload& stepWork, int pmeFlags, gmx_wallcycle_t wcycle) { @@ -677,34 +674,33 @@ static void alternatePmeNbGpuWaitReduce(nonbonded_verlet_t *nbv, bool isNbGpuDone = false; + gmx::ForceWithShiftForces& forceWithShiftForces = forceOutputs->forceWithShiftForces(); + gmx::ForceWithVirial& forceWithVirial = forceOutputs->forceWithVirial(); - gmx::ForceWithShiftForces &forceWithShiftForces = forceOutputs->forceWithShiftForces(); - gmx::ForceWithVirial &forceWithVirial = forceOutputs->forceWithVirial(); - - gmx::ArrayRef pmeGpuForces; + gmx::ArrayRef pmeGpuForces; while (!isPmeGpuDone || !isNbGpuDone) { if (!isPmeGpuDone) { - GpuTaskCompletion completionType = (isNbGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check; - isPmeGpuDone = pme_gpu_try_finish_task(pmedata, pmeFlags, wcycle, &forceWithVirial, enerd, completionType); + GpuTaskCompletion completionType = + (isNbGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check; + isPmeGpuDone = pme_gpu_try_finish_task(pmedata, pmeFlags, wcycle, &forceWithVirial, + enerd, completionType); } if (!isNbGpuDone) { - GpuTaskCompletion completionType = (isPmeGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check; - isNbGpuDone = Nbnxm::gpu_try_finish_task(nbv->gpu_nbv, - stepWork, - AtomLocality::Local, - enerd->grpp.ener[egLJSR].data(), - enerd->grpp.ener[egCOULSR].data(), - forceWithShiftForces.shiftForces(), completionType, wcycle); + GpuTaskCompletion completionType = + (isPmeGpuDone) ? GpuTaskCompletion::Wait : GpuTaskCompletion::Check; + isNbGpuDone = Nbnxm::gpu_try_finish_task( + nbv->gpu_nbv, stepWork, AtomLocality::Local, enerd->grpp.ener[egLJSR].data(), + enerd->grpp.ener[egCOULSR].data(), forceWithShiftForces.shiftForces(), + completionType, wcycle); if (isNbGpuDone) { - nbv->atomdata_add_nbat_f_to_f(AtomLocality::Local, - forceWithShiftForces.force()); + nbv->atomdata_add_nbat_f_to_f(AtomLocality::Local, forceWithShiftForces.force()); } } } @@ -721,13 +717,12 @@ static void alternatePmeNbGpuWaitReduce(nonbonded_verlet_t *nbv, * * \returns Cleared force output structure */ -static ForceOutputs -setupForceOutputs(t_forcerec *fr, - pull_t *pull_work, - const t_inputrec &inputrec, - gmx::ArrayRefWithPadding force, - const StepWorkload &stepWork, - gmx_wallcycle_t wcycle) +static ForceOutputs setupForceOutputs(t_forcerec* fr, + pull_t* pull_work, + const t_inputrec& inputrec, + gmx::ArrayRefWithPadding force, + const StepWorkload& stepWork, + gmx_wallcycle_t wcycle) { wallcycle_sub_start(wcycle, ewcsCLEAR_FORCE_BUFFER); @@ -737,8 +732,7 @@ setupForceOutputs(t_forcerec *fr, if (stepWork.computeForces) { /* Clear the short- and long-range forces */ - clear_rvecs_omp(fr->natoms_force_constr, - as_rvec_array(forceWithShiftForces.force().data())); + clear_rvecs_omp(fr->natoms_force_constr, as_rvec_array(forceWithShiftForces.force().data())); } /* If we need to compute the virial, we might need a separate @@ -746,11 +740,11 @@ setupForceOutputs(t_forcerec *fr, * directly, such as PME. Otherwise, forceWithVirial uses the * the same force (f in legacy calls) buffer as other algorithms. */ - const bool useSeparateForceWithVirialBuffer = (stepWork.computeForces && - (stepWork.computeVirial && fr->haveDirectVirialContributions)); + const bool useSeparateForceWithVirialBuffer = + (stepWork.computeForces && (stepWork.computeVirial && fr->haveDirectVirialContributions)); /* forceWithVirial uses the local atom range only */ - gmx::ForceWithVirial forceWithVirial(useSeparateForceWithVirialBuffer ? - fr->forceBufferForDirectVirialContributions : force.unpaddedArrayRef(), + gmx::ForceWithVirial forceWithVirial(useSeparateForceWithVirialBuffer ? fr->forceBufferForDirectVirialContributions + : force.unpaddedArrayRef(), stepWork.computeVirial); if (useSeparateForceWithVirialBuffer) @@ -776,31 +770,32 @@ setupForceOutputs(t_forcerec *fr, /*! \brief Set up flags that have the lifetime of the domain indicating what type of work is there to compute. */ -static DomainLifetimeWorkload -setupDomainLifetimeWorkload(const t_inputrec &inputrec, - const t_forcerec &fr, - const pull_t *pull_work, - const gmx_edsam *ed, - const t_idef &idef, - const t_fcdata &fcd, - const t_mdatoms &mdatoms, - const SimulationWorkload &simulationWork, - const StepWorkload &stepWork) +static DomainLifetimeWorkload setupDomainLifetimeWorkload(const t_inputrec& inputrec, + const t_forcerec& fr, + const pull_t* pull_work, + const gmx_edsam* ed, + const t_idef& idef, + const t_fcdata& fcd, + const t_mdatoms& mdatoms, + const SimulationWorkload& simulationWork, + const StepWorkload& stepWork) { DomainLifetimeWorkload domainWork; // Note that haveSpecialForces is constant over the whole run - domainWork.haveSpecialForces = haveSpecialForces(inputrec, *fr.forceProviders, pull_work, stepWork.computeForces, ed); - domainWork.haveCpuBondedWork = haveCpuBondeds(fr); - domainWork.haveGpuBondedWork = ((fr.gpuBonded != nullptr) && fr.gpuBonded->haveInteractions()); - domainWork.haveRestraintsWork = haveRestraints(idef, fcd); + domainWork.haveSpecialForces = + haveSpecialForces(inputrec, *fr.forceProviders, pull_work, stepWork.computeForces, ed); + domainWork.haveCpuBondedWork = haveCpuBondeds(fr); + domainWork.haveGpuBondedWork = ((fr.gpuBonded != nullptr) && fr.gpuBonded->haveInteractions()); + domainWork.haveRestraintsWork = haveRestraints(idef, fcd); domainWork.haveCpuListedForceWork = haveCpuListedForces(fr, idef, fcd); // Note that haveFreeEnergyWork is constant over the whole run - domainWork.haveFreeEnergyWork = (fr.efep != efepNO && mdatoms.nPerturbed != 0); + domainWork.haveFreeEnergyWork = (fr.efep != efepNO && mdatoms.nPerturbed != 0); // We assume we have local force work if there are CPU // force tasks including PME or nonbondeds. - domainWork.haveCpuLocalForceWork = domainWork.haveSpecialForces || domainWork.haveCpuListedForceWork || domainWork.haveFreeEnergyWork || - simulationWork.useCpuNonbonded || simulationWork.useCpuPme || simulationWork.haveEwaldSurfaceContribution || - inputrec.nwall > 0; + domainWork.haveCpuLocalForceWork = + domainWork.haveSpecialForces || domainWork.haveCpuListedForceWork + || domainWork.haveFreeEnergyWork || simulationWork.useCpuNonbonded || simulationWork.useCpuPme + || simulationWork.haveEwaldSurfaceContribution || inputrec.nwall > 0; return domainWork; } @@ -814,11 +809,10 @@ setupDomainLifetimeWorkload(const t_inputrec &inputrec, * * \returns New Stepworkload description. */ -static StepWorkload -setupStepWorkload(const int legacyFlags, - const bool isNonbondedOn, - const SimulationWorkload &simulationWork, - const bool rankHasPmeDuty) +static StepWorkload setupStepWorkload(const int legacyFlags, + const bool isNonbondedOn, + const SimulationWorkload& simulationWork, + const bool rankHasPmeDuty) { StepWorkload flags; flags.stateChanged = ((legacyFlags & GMX_FORCE_STATECHANGED) != 0); @@ -833,13 +827,15 @@ setupStepWorkload(const int legacyFlags, if (simulationWork.useGpuBufferOps) { - GMX_ASSERT(simulationWork.useGpuNonbonded, "Can only offload buffer ops if nonbonded computation is also offloaded"); + GMX_ASSERT(simulationWork.useGpuNonbonded, + "Can only offload buffer ops if nonbonded computation is also offloaded"); } flags.useGpuXBufferOps = simulationWork.useGpuBufferOps; // on virial steps the CPU reduction path is taken flags.useGpuFBufferOps = simulationWork.useGpuBufferOps && !flags.computeVirial; - flags.useGpuPmeFReduction = flags.useGpuFBufferOps && (simulationWork.useGpuPme && - (rankHasPmeDuty || simulationWork.useGpuPmePpCommunication)); + flags.useGpuPmeFReduction = flags.useGpuFBufferOps + && (simulationWork.useGpuPme + && (rankHasPmeDuty || simulationWork.useGpuPmePpCommunication)); return flags; } @@ -850,16 +846,15 @@ setupStepWorkload(const int legacyFlags, * TODO: eliminate the \p useGpuNonbonded and \p useGpuNonbonded when these are * incorporated in DomainLifetimeWorkload. */ -static void -launchGpuEndOfStepTasks(nonbonded_verlet_t *nbv, - gmx::GpuBonded *gpuBonded, - gmx_pme_t *pmedata, - gmx_enerdata_t *enerd, - const gmx::MdrunScheduleWorkload &runScheduleWork, - bool useGpuNonbonded, - bool useGpuPme, - int64_t step, - gmx_wallcycle_t wcycle) +static void launchGpuEndOfStepTasks(nonbonded_verlet_t* nbv, + gmx::GpuBonded* gpuBonded, + gmx_pme_t* pmedata, + gmx_enerdata_t* enerd, + const gmx::MdrunScheduleWorkload& runScheduleWork, + bool useGpuNonbonded, + bool useGpuPme, + int64_t step, + gmx_wallcycle_t wcycle) { if (useGpuNonbonded) { @@ -897,42 +892,42 @@ launchGpuEndOfStepTasks(nonbonded_verlet_t *nbv, } -void do_force(FILE *fplog, - const t_commrec *cr, - const gmx_multisim_t *ms, - const t_inputrec *inputrec, - gmx::Awh *awh, - gmx_enfrot *enforcedRotation, - gmx::ImdSession *imdSession, - pull_t *pull_work, - int64_t step, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - const gmx_localtop_t *top, - const matrix box, - gmx::ArrayRefWithPadding x, - history_t *hist, - gmx::ArrayRefWithPadding force, - tensor vir_force, - const t_mdatoms *mdatoms, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - gmx::ArrayRef lambda, - t_graph *graph, - t_forcerec *fr, - gmx::MdrunScheduleWorkload *runScheduleWork, - const gmx_vsite_t *vsite, - rvec mu_tot, - double t, - gmx_edsam *ed, - int legacyFlags, - const DDBalanceRegionHandler &ddBalanceRegionHandler) +void do_force(FILE* fplog, + const t_commrec* cr, + const gmx_multisim_t* ms, + const t_inputrec* inputrec, + gmx::Awh* awh, + gmx_enfrot* enforcedRotation, + gmx::ImdSession* imdSession, + pull_t* pull_work, + int64_t step, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + const gmx_localtop_t* top, + const matrix box, + gmx::ArrayRefWithPadding x, + history_t* hist, + gmx::ArrayRefWithPadding force, + tensor vir_force, + const t_mdatoms* mdatoms, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + gmx::ArrayRef lambda, + t_graph* graph, + t_forcerec* fr, + gmx::MdrunScheduleWorkload* runScheduleWork, + const gmx_vsite_t* vsite, + rvec mu_tot, + double t, + gmx_edsam* ed, + int legacyFlags, + const DDBalanceRegionHandler& ddBalanceRegionHandler) { int i, j; - double mu[2*DIM]; - nonbonded_verlet_t *nbv = fr->nbv.get(); - interaction_const_t *ic = fr->ic; - gmx::StatePropagatorDataGpu *stateGpu = fr->stateGpu; + double mu[2 * DIM]; + nonbonded_verlet_t* nbv = fr->nbv.get(); + interaction_const_t* ic = fr->ic; + gmx::StatePropagatorDataGpu* stateGpu = fr->stateGpu; // TODO remove the code below when the legacy flags are not in use anymore /* modify force flag if not doing nonbonded */ @@ -941,12 +936,12 @@ void do_force(FILE *fplog, legacyFlags &= ~GMX_FORCE_NONBONDED; } - const SimulationWorkload &simulationWork = runScheduleWork->simulationWork; + const SimulationWorkload& simulationWork = runScheduleWork->simulationWork; - runScheduleWork->stepWork = setupStepWorkload(legacyFlags, fr->bNonbonded, - simulationWork, thisRankHasDuty(cr, DUTY_PME)); - const StepWorkload &stepWork = runScheduleWork->stepWork; + runScheduleWork->stepWork = setupStepWorkload(legacyFlags, fr->bNonbonded, simulationWork, + thisRankHasDuty(cr, DUTY_PME)); + const StepWorkload& stepWork = runScheduleWork->stepWork; const bool useGpuPmeOnThisRank = simulationWork.useGpuPme && thisRankHasDuty(cr, DUTY_PME); @@ -954,9 +949,11 @@ void do_force(FILE *fplog, // Switches on whether to use GPU for position and force buffer operations // TODO consider all possible combinations of triggers, and how to combine optimally in each case. - const BufferOpsUseGpu useGpuXBufOps = stepWork.useGpuXBufferOps ? BufferOpsUseGpu::True : BufferOpsUseGpu::False; + const BufferOpsUseGpu useGpuXBufOps = + stepWork.useGpuXBufferOps ? BufferOpsUseGpu::True : BufferOpsUseGpu::False; // GPU Force buffer ops are disabled on virial steps, because the virial calc is not yet ported to GPU - const BufferOpsUseGpu useGpuFBufOps = stepWork.useGpuFBufferOps ? BufferOpsUseGpu::True : BufferOpsUseGpu::False; + const BufferOpsUseGpu useGpuFBufOps = + stepWork.useGpuFBufferOps ? BufferOpsUseGpu::True : BufferOpsUseGpu::False; /* At a search step we need to start the first balancing region * somewhere early inside the step after communication during domain @@ -979,9 +976,8 @@ void do_force(FILE *fplog, /* Calculate total (local) dipole moment in a temporary common array. * This makes it possible to sum them over nodes faster. */ - calc_mu(start, homenr, - x.unpaddedArrayRef(), mdatoms->chargeA, mdatoms->chargeB, mdatoms->nChargePerturbed, - mu, mu+DIM); + calc_mu(start, homenr, x.unpaddedArrayRef(), mdatoms->chargeA, mdatoms->chargeB, + mdatoms->nChargePerturbed, mu, mu + DIM); } } @@ -999,7 +995,8 @@ void do_force(FILE *fplog, const bool calcCGCM = (fillGrid && !DOMAINDECOMP(cr)); if (calcCGCM) { - put_atoms_in_box_omp(fr->ePBC, box, x.unpaddedArrayRef().subArray(0, homenr), gmx_omp_nthreads_get(emntDefault)); + put_atoms_in_box_omp(fr->ePBC, box, x.unpaddedArrayRef().subArray(0, homenr), + gmx_omp_nthreads_get(emntDefault)); inc_nrnb(nrnb, eNR_SHIFTX, homenr); } else if (EI_ENERGY_MINIMIZATION(inputrec->eI) && graph) @@ -1008,8 +1005,7 @@ void do_force(FILE *fplog, } } - nbnxn_atomdata_copy_shiftvec(stepWork.haveDynamicBox, - fr->shift_vec, nbv->nbat.get()); + nbnxn_atomdata_copy_shiftvec(stepWork.haveDynamicBox, fr->shift_vec, nbv->nbat.get()); // Coordinates on the device are needed if PME or BufferOps are offloaded. // The local coordinates can be copied right away. @@ -1019,7 +1015,8 @@ void do_force(FILE *fplog, { if (stepWork.doNeighborSearch) { - stateGpu->reinit(mdatoms->homenr, cr->dd != nullptr ? dd_numAtomsZones(*cr->dd) : mdatoms->homenr); + stateGpu->reinit(mdatoms->homenr, + cr->dd != nullptr ? dd_numAtomsZones(*cr->dd) : mdatoms->homenr); if (useGpuPmeOnThisRank) { // TODO: This should be moved into PME setup function ( pme_gpu_prepare_computation(...) ) @@ -1037,15 +1034,17 @@ void do_force(FILE *fplog, // Copy coordinate from the GPU if update is on the GPU and there are forces to be computed on the CPU. At search steps the // current coordinates are already on the host, hence copy is not needed. - if (simulationWork.useGpuUpdate && !stepWork.doNeighborSearch && - runScheduleWork->domainWork.haveCpuLocalForceWork) + if (simulationWork.useGpuUpdate && !stepWork.doNeighborSearch + && runScheduleWork->domainWork.haveCpuLocalForceWork) { stateGpu->copyCoordinatesFromGpu(x.unpaddedArrayRef(), AtomLocality::Local); stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local); } - const auto localXReadyOnDevice = (stateGpu != nullptr) ? stateGpu->getCoordinatesReadyOnDeviceEvent(AtomLocality::Local, - simulationWork, stepWork) : nullptr; + const auto localXReadyOnDevice = (stateGpu != nullptr) + ? stateGpu->getCoordinatesReadyOnDeviceEvent( + AtomLocality::Local, simulationWork, stepWork) + : nullptr; #if GMX_MPI if (!thisRankHasDuty(cr, DUTY_PME)) @@ -1055,11 +1054,11 @@ void do_force(FILE *fplog, * and domain decomposition does not use the graph, * we do not need to worry about shifting. */ - bool reinitGpuPmePpComms = simulationWork.useGpuPmePpCommunication && (stepWork.doNeighborSearch); - bool sendCoordinatesFromGpu = simulationWork.useGpuPmePpCommunication && !(stepWork.doNeighborSearch); - gmx_pme_send_coordinates(fr, cr, box, as_rvec_array(x.unpaddedArrayRef().data()), - lambda[efptCOUL], lambda[efptVDW], - (stepWork.computeVirial || stepWork.computeEnergy), + bool reinitGpuPmePpComms = simulationWork.useGpuPmePpCommunication && (stepWork.doNeighborSearch); + bool sendCoordinatesFromGpu = + simulationWork.useGpuPmePpCommunication && !(stepWork.doNeighborSearch); + gmx_pme_send_coordinates(fr, cr, box, as_rvec_array(x.unpaddedArrayRef().data()), lambda[efptCOUL], + lambda[efptVDW], (stepWork.computeVirial || stepWork.computeEnergy), step, simulationWork.useGpuPmePpCommunication, reinitGpuPmePpComms, sendCoordinatesFromGpu, localXReadyOnDevice, wcycle); } @@ -1067,8 +1066,7 @@ void do_force(FILE *fplog, if (useGpuPmeOnThisRank) { - launchPmeGpuSpread(fr->pmedata, box, stepWork, pmeFlags, - localXReadyOnDevice, wcycle); + launchPmeGpuSpread(fr->pmedata, box, stepWork, pmeFlags, localXReadyOnDevice, wcycle); } /* do gridding for pair search */ @@ -1096,18 +1094,14 @@ void do_force(FILE *fplog, if (!DOMAINDECOMP(cr)) { wallcycle_sub_start(wcycle, ewcsNBS_GRID_LOCAL); - nbnxn_put_on_grid(nbv, box, - 0, vzero, box_diag, - nullptr, { 0, mdatoms->homenr }, -1, - fr->cginfo, x.unpaddedArrayRef(), - 0, nullptr); + nbnxn_put_on_grid(nbv, box, 0, vzero, box_diag, nullptr, { 0, mdatoms->homenr }, -1, + fr->cginfo, x.unpaddedArrayRef(), 0, nullptr); wallcycle_sub_stop(wcycle, ewcsNBS_GRID_LOCAL); } else { wallcycle_sub_start(wcycle, ewcsNBS_GRID_NONLOCAL); - nbnxn_put_on_grid_nonlocal(nbv, domdec_zones(cr->dd), - fr->cginfo, x.unpaddedArrayRef()); + nbnxn_put_on_grid_nonlocal(nbv, domdec_zones(cr->dd), fr->cginfo, x.unpaddedArrayRef()); wallcycle_sub_stop(wcycle, ewcsNBS_GRID_NONLOCAL); } @@ -1134,11 +1128,9 @@ void do_force(FILE *fplog, // TODO the xq, f, and fshift buffers are now shared // resources, so they should be maintained by a // higher-level object than the nb module. - fr->gpuBonded->updateInteractionListsAndDeviceBuffers(nbv->getGridIndices(), - top->idef, - Nbnxm::gpu_get_xq(nbv->gpu_nbv), - Nbnxm::gpu_get_f(nbv->gpu_nbv), - Nbnxm::gpu_get_fshift(nbv->gpu_nbv)); + fr->gpuBonded->updateInteractionListsAndDeviceBuffers( + nbv->getGridIndices(), top->idef, Nbnxm::gpu_get_xq(nbv->gpu_nbv), + Nbnxm::gpu_get_f(nbv->gpu_nbv), Nbnxm::gpu_get_fshift(nbv->gpu_nbv)); } wallcycle_stop(wcycle, ewcLAUNCH_GPU); } @@ -1148,22 +1140,13 @@ void do_force(FILE *fplog, { // Need to run after the GPU-offload bonded interaction lists // are set up to be able to determine whether there is bonded work. - runScheduleWork->domainWork = - setupDomainLifetimeWorkload(*inputrec, - *fr, - pull_work, - ed, - top->idef, - *fcd, - *mdatoms, - simulationWork, - stepWork); + runScheduleWork->domainWork = setupDomainLifetimeWorkload( + *inputrec, *fr, pull_work, ed, top->idef, *fcd, *mdatoms, simulationWork, stepWork); wallcycle_start_nocount(wcycle, ewcNS); wallcycle_sub_start(wcycle, ewcsNBS_SEARCH_LOCAL); /* Note that with a GPU the launch overhead of the list transfer is not timed separately */ - nbv->constructPairlist(InteractionLocality::Local, - &top->excls, step, nrnb); + nbv->constructPairlist(InteractionLocality::Local, &top->excls, step, nrnb); nbv->setupGpuShortRangeWork(fr->gpuBonded, InteractionLocality::Local); @@ -1188,18 +1171,16 @@ void do_force(FILE *fplog, if (useGpuXBufOps == BufferOpsUseGpu::True) { GMX_ASSERT(stateGpu, "stateGpu should be valid when buffer ops are offloaded"); - nbv->convertCoordinatesGpu(AtomLocality::Local, false, - stateGpu->getCoordinates(), + nbv->convertCoordinatesGpu(AtomLocality::Local, false, stateGpu->getCoordinates(), localXReadyOnDevice); } else { - nbv->convertCoordinates(AtomLocality::Local, false, - x.unpaddedArrayRef()); + nbv->convertCoordinates(AtomLocality::Local, false, x.unpaddedArrayRef()); } } - const gmx::DomainLifetimeWorkload &domainWork = runScheduleWork->domainWork; + const gmx::DomainLifetimeWorkload& domainWork = runScheduleWork->domainWork; if (simulationWork.useGpuNonbonded) { @@ -1211,8 +1192,7 @@ void do_force(FILE *fplog, Nbnxm::gpu_upload_shiftvec(nbv->gpu_nbv, nbv->nbat.get()); if (stepWork.doNeighborSearch || (useGpuXBufOps == BufferOpsUseGpu::False)) { - Nbnxm::gpu_copy_xq_to_gpu(nbv->gpu_nbv, nbv->nbat.get(), - AtomLocality::Local); + Nbnxm::gpu_copy_xq_to_gpu(nbv->gpu_nbv, nbv->nbat.get(), AtomLocality::Local); } wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED); // with X buffer ops offloaded to the GPU on all but the search steps @@ -1228,8 +1208,7 @@ void do_force(FILE *fplog, /* launch local nonbonded work on GPU */ wallcycle_sub_start_nocount(wcycle, ewcsLAUNCH_GPU_NONBONDED); - do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, enbvClearFNo, - step, nrnb, wcycle); + do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, enbvClearFNo, step, nrnb, wcycle); wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED); wallcycle_stop(wcycle, ewcLAUNCH_GPU); } @@ -1248,11 +1227,13 @@ void do_force(FILE *fplog, // The conditions for gpuHaloExchange e.g. using GPU buffer // operations were checked before construction, so here we can // just use it and assert upon any conditions. - gmx::GpuHaloExchange *gpuHaloExchange = (havePPDomainDecomposition(cr) ? cr->dd->gpuHaloExchange.get() : nullptr); - const bool ddUsesGpuDirectCommunication = (gpuHaloExchange != nullptr); + gmx::GpuHaloExchange* gpuHaloExchange = + (havePPDomainDecomposition(cr) ? cr->dd->gpuHaloExchange.get() : nullptr); + const bool ddUsesGpuDirectCommunication = (gpuHaloExchange != nullptr); GMX_ASSERT(!ddUsesGpuDirectCommunication || (useGpuXBufOps == BufferOpsUseGpu::True), "Must use coordinate buffer ops with GPU halo exchange"); - const bool useGpuForcesHaloExchange = ddUsesGpuDirectCommunication && (useGpuFBufOps == BufferOpsUseGpu::True); + const bool useGpuForcesHaloExchange = + ddUsesGpuDirectCommunication && (useGpuFBufOps == BufferOpsUseGpu::True); /* Communicate coordinates and sum dipole if necessary + do non-local pair search */ @@ -1264,8 +1245,7 @@ void do_force(FILE *fplog, wallcycle_start_nocount(wcycle, ewcNS); wallcycle_sub_start(wcycle, ewcsNBS_SEARCH_NONLOCAL); /* Note that with a GPU the launch overhead of the list transfer is not timed separately */ - nbv->constructPairlist(InteractionLocality::NonLocal, - &top->excls, step, nrnb); + nbv->constructPairlist(InteractionLocality::NonLocal, &top->excls, step, nrnb); nbv->setupGpuShortRangeWork(fr->gpuBonded, InteractionLocality::NonLocal); wallcycle_sub_stop(wcycle, ewcsNBS_SEARCH_NONLOCAL); @@ -1285,7 +1265,7 @@ void do_force(FILE *fplog, if (domainWork.haveCpuBondedWork || domainWork.haveFreeEnergyWork) { - //non-local part of coordinate buffer must be copied back to host for CPU work + // non-local part of coordinate buffer must be copied back to host for CPU work stateGpu->copyCoordinatesFromGpu(x.unpaddedArrayRef(), AtomLocality::NonLocal); } } @@ -1301,17 +1281,14 @@ void do_force(FILE *fplog, { stateGpu->copyCoordinatesToGpu(x.unpaddedArrayRef(), AtomLocality::NonLocal); } - nbv->convertCoordinatesGpu(AtomLocality::NonLocal, false, - stateGpu->getCoordinates(), - stateGpu->getCoordinatesReadyOnDeviceEvent(AtomLocality::NonLocal, - simulationWork, stepWork)); + nbv->convertCoordinatesGpu(AtomLocality::NonLocal, false, stateGpu->getCoordinates(), + stateGpu->getCoordinatesReadyOnDeviceEvent( + AtomLocality::NonLocal, simulationWork, stepWork)); } else { - nbv->convertCoordinates(AtomLocality::NonLocal, false, - x.unpaddedArrayRef()); + nbv->convertCoordinates(AtomLocality::NonLocal, false, x.unpaddedArrayRef()); } - } if (simulationWork.useGpuNonbonded) @@ -1321,8 +1298,7 @@ void do_force(FILE *fplog, if (stepWork.doNeighborSearch || (useGpuXBufOps == BufferOpsUseGpu::False)) { wallcycle_sub_start(wcycle, ewcsLAUNCH_GPU_NONBONDED); - Nbnxm::gpu_copy_xq_to_gpu(nbv->gpu_nbv, nbv->nbat.get(), - AtomLocality::NonLocal); + Nbnxm::gpu_copy_xq_to_gpu(nbv->gpu_nbv, nbv->nbat.get(), AtomLocality::NonLocal); wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED); } @@ -1335,8 +1311,8 @@ void do_force(FILE *fplog, /* launch non-local nonbonded tasks on GPU */ wallcycle_sub_start(wcycle, ewcsLAUNCH_GPU_NONBONDED); - do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, - step, nrnb, wcycle); + do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step, + nrnb, wcycle); wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED); wallcycle_stop(wcycle, ewcLAUNCH_GPU); @@ -1351,11 +1327,9 @@ void do_force(FILE *fplog, if (havePPDomainDecomposition(cr)) { - Nbnxm::gpu_launch_cpyback(nbv->gpu_nbv, nbv->nbat.get(), - stepWork, AtomLocality::NonLocal); + Nbnxm::gpu_launch_cpyback(nbv->gpu_nbv, nbv->nbat.get(), stepWork, AtomLocality::NonLocal); } - Nbnxm::gpu_launch_cpyback(nbv->gpu_nbv, nbv->nbat.get(), - stepWork, AtomLocality::Local); + Nbnxm::gpu_launch_cpyback(nbv->gpu_nbv, nbv->nbat.get(), stepWork, AtomLocality::Local); wallcycle_sub_stop(wcycle, ewcsLAUNCH_GPU_NONBONDED); if (domainWork.haveGpuBondedWork && stepWork.computeEnergy) @@ -1369,7 +1343,7 @@ void do_force(FILE *fplog, { if (PAR(cr)) { - gmx_sumd(2*DIM, mu, cr); + gmx_sumd(2 * DIM, mu, cr); ddBalanceRegionHandler.reopenRegionCpu(); } @@ -1378,7 +1352,7 @@ void do_force(FILE *fplog, { for (j = 0; j < DIM; j++) { - fr->mu_tot[i][j] = mu[i*DIM + j]; + fr->mu_tot[i][j] = mu[i * DIM + j]; } } } @@ -1390,9 +1364,7 @@ void do_force(FILE *fplog, { for (j = 0; j < DIM; j++) { - mu_tot[j] = - (1.0 - lambda[efptCOUL])*fr->mu_tot[0][j] + - lambda[efptCOUL]*fr->mu_tot[1][j]; + mu_tot[j] = (1.0 - lambda[efptCOUL]) * fr->mu_tot[0][j] + lambda[efptCOUL] * fr->mu_tot[1][j]; } } @@ -1400,7 +1372,7 @@ void do_force(FILE *fplog, reset_enerdata(enerd); /* Clear the shift forces */ // TODO: This should be linked to the shift force buffer in use, or cleared before use instead - for (gmx::RVec &elem : fr->shiftForces) + for (gmx::RVec& elem : fr->shiftForces) { elem = { 0.0_real, 0.0_real, 0.0_real }; } @@ -1414,7 +1386,8 @@ void do_force(FILE *fplog, if (inputrec->bRot) { wallcycle_start(wcycle, ewcROT); - do_rotation(cr, enforcedRotation, box, as_rvec_array(x.unpaddedArrayRef().data()), t, step, stepWork.doNeighborSearch); + do_rotation(cr, enforcedRotation, box, as_rvec_array(x.unpaddedArrayRef().data()), t, step, + stepWork.doNeighborSearch); wallcycle_stop(wcycle, ewcROT); } @@ -1425,7 +1398,8 @@ void do_force(FILE *fplog, // Set up and clear force outputs. // We use std::move to keep the compiler happy, it has no effect. - ForceOutputs forceOut = setupForceOutputs(fr, pull_work, *inputrec, std::move(force), stepWork, wcycle); + ForceOutputs forceOut = + setupForceOutputs(fr, pull_work, *inputrec, std::move(force), stepWork, wcycle); /* We calculate the non-bonded forces, when done on the CPU, here. * We do this before calling do_force_lowlevel, because in that @@ -1439,8 +1413,7 @@ void do_force(FILE *fplog, if (!useOrEmulateGpuNb) { - do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, enbvClearFYes, - step, nrnb, wcycle); + do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, enbvClearFYes, step, nrnb, wcycle); } if (fr->efep != efepNO) @@ -1448,17 +1421,17 @@ void do_force(FILE *fplog, /* Calculate the local and non-local free energy interactions here. * Happens here on the CPU both with and without GPU. */ - nbv->dispatchFreeEnergyKernel(InteractionLocality::Local, - fr, as_rvec_array(x.unpaddedArrayRef().data()), &forceOut.forceWithShiftForces(), *mdatoms, - inputrec->fepvals, lambda.data(), - enerd, stepWork, nrnb); + nbv->dispatchFreeEnergyKernel(InteractionLocality::Local, fr, + as_rvec_array(x.unpaddedArrayRef().data()), + &forceOut.forceWithShiftForces(), *mdatoms, inputrec->fepvals, + lambda.data(), enerd, stepWork, nrnb); if (havePPDomainDecomposition(cr)) { - nbv->dispatchFreeEnergyKernel(InteractionLocality::NonLocal, - fr, as_rvec_array(x.unpaddedArrayRef().data()), &forceOut.forceWithShiftForces(), *mdatoms, - inputrec->fepvals, lambda.data(), - enerd, stepWork, nrnb); + nbv->dispatchFreeEnergyKernel(InteractionLocality::NonLocal, fr, + as_rvec_array(x.unpaddedArrayRef().data()), + &forceOut.forceWithShiftForces(), *mdatoms, + inputrec->fepvals, lambda.data(), enerd, stepWork, nrnb); } } @@ -1466,8 +1439,8 @@ void do_force(FILE *fplog, { if (havePPDomainDecomposition(cr)) { - do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, - step, nrnb, wcycle); + do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::NonLocal, enbvClearFNo, step, + nrnb, wcycle); } if (stepWork.computeForces) @@ -1498,27 +1471,20 @@ void do_force(FILE *fplog, } // TODO Force flags should include haveFreeEnergyWork for this domain - if (ddUsesGpuDirectCommunication && - (domainWork.haveCpuBondedWork || domainWork.haveFreeEnergyWork)) + if (ddUsesGpuDirectCommunication && (domainWork.haveCpuBondedWork || domainWork.haveFreeEnergyWork)) { /* Wait for non-local coordinate data to be copied from device */ nbv->wait_nonlocal_x_copy_D2H_done(); } /* Compute the bonded and non-bonded energies and optionally forces */ - do_force_lowlevel(fr, inputrec, &(top->idef), - cr, ms, nrnb, wcycle, mdatoms, - x, hist, &forceOut, enerd, fcd, - box, lambda.data(), graph, fr->mu_tot, - stepWork, - ddBalanceRegionHandler); + do_force_lowlevel(fr, inputrec, &(top->idef), cr, ms, nrnb, wcycle, mdatoms, x, hist, &forceOut, enerd, + fcd, box, lambda.data(), graph, fr->mu_tot, stepWork, ddBalanceRegionHandler); wallcycle_stop(wcycle, ewcFORCE); - computeSpecialForces(fplog, cr, inputrec, awh, enforcedRotation, - imdSession, pull_work, step, t, wcycle, - fr->forceProviders, box, x.unpaddedArrayRef(), mdatoms, lambda.data(), - stepWork, &forceOut.forceWithVirial(), enerd, - ed, stepWork.doNeighborSearch); + computeSpecialForces(fplog, cr, inputrec, awh, enforcedRotation, imdSession, pull_work, step, t, + wcycle, fr->forceProviders, box, x.unpaddedArrayRef(), mdatoms, lambda.data(), + stepWork, &forceOut.forceWithVirial(), enerd, ed, stepWork.doNeighborSearch); // Will store the amount of cycles spent waiting for the GPU that @@ -1526,19 +1492,16 @@ void do_force(FILE *fplog, float cycles_wait_gpu = 0; if (useOrEmulateGpuNb) { - auto &forceWithShiftForces = forceOut.forceWithShiftForces(); + auto& forceWithShiftForces = forceOut.forceWithShiftForces(); /* wait for non-local forces (or calculate in emulation mode) */ if (havePPDomainDecomposition(cr)) { if (simulationWork.useGpuNonbonded) { - cycles_wait_gpu += Nbnxm::gpu_wait_finish_task(nbv->gpu_nbv, - stepWork, AtomLocality::NonLocal, - enerd->grpp.ener[egLJSR].data(), - enerd->grpp.ener[egCOULSR].data(), - forceWithShiftForces.shiftForces(), - wcycle); + cycles_wait_gpu += Nbnxm::gpu_wait_finish_task( + nbv->gpu_nbv, stepWork, AtomLocality::NonLocal, enerd->grpp.ener[egLJSR].data(), + enerd->grpp.ener[egCOULSR].data(), forceWithShiftForces.shiftForces(), wcycle); } else { @@ -1552,40 +1515,39 @@ void do_force(FILE *fplog, { gmx::FixedCapacityVector dependencyList; - // TODO: move this into DomainLifetimeWorkload, including the second part of the condition - // The bonded and free energy CPU tasks can have non-local force contributions - // which are a dependency for the GPU force reduction. - bool haveNonLocalForceContribInCpuBuffer = domainWork.haveCpuBondedWork || domainWork.haveFreeEnergyWork; + // TODO: move this into DomainLifetimeWorkload, including the second part of the + // condition The bonded and free energy CPU tasks can have non-local force + // contributions which are a dependency for the GPU force reduction. + bool haveNonLocalForceContribInCpuBuffer = + domainWork.haveCpuBondedWork || domainWork.haveFreeEnergyWork; if (haveNonLocalForceContribInCpuBuffer) { - stateGpu->copyForcesToGpu(forceOut.forceWithShiftForces().force(), AtomLocality::NonLocal); - dependencyList.push_back(stateGpu->getForcesReadyOnDeviceEvent(AtomLocality::NonLocal, - useGpuFBufOps == BufferOpsUseGpu::True)); + stateGpu->copyForcesToGpu(forceOut.forceWithShiftForces().force(), + AtomLocality::NonLocal); + dependencyList.push_back(stateGpu->getForcesReadyOnDeviceEvent( + AtomLocality::NonLocal, useGpuFBufOps == BufferOpsUseGpu::True)); } - nbv->atomdata_add_nbat_f_to_f_gpu(AtomLocality::NonLocal, - stateGpu->getForces(), - pme_gpu_get_device_f(fr->pmedata), - dependencyList, + nbv->atomdata_add_nbat_f_to_f_gpu(AtomLocality::NonLocal, stateGpu->getForces(), + pme_gpu_get_device_f(fr->pmedata), dependencyList, false, haveNonLocalForceContribInCpuBuffer); if (!useGpuForcesHaloExchange) { // copy from GPU input for dd_move_f() - stateGpu->copyForcesFromGpu(forceOut.forceWithShiftForces().force(), AtomLocality::NonLocal); + stateGpu->copyForcesFromGpu(forceOut.forceWithShiftForces().force(), + AtomLocality::NonLocal); } } else { - nbv->atomdata_add_nbat_f_to_f(AtomLocality::NonLocal, - forceWithShiftForces.force()); + nbv->atomdata_add_nbat_f_to_f(AtomLocality::NonLocal, forceWithShiftForces.force()); } if (fr->nbv->emulateGpu() && stepWork.computeVirial) { - nbnxn_atomdata_add_nbat_fshift_to_fshift(*nbv->nbat, - forceWithShiftForces.shiftForces()); + nbnxn_atomdata_add_nbat_fshift_to_fshift(*nbv->nbat, forceWithShiftForces.shiftForces()); } } } @@ -1618,18 +1580,16 @@ void do_force(FILE *fplog, } dd_move_f(cr->dd, &forceOut.forceWithShiftForces(), wcycle); } - } } // With both nonbonded and PME offloaded a GPU on the same rank, we use // an alternating wait/reduction scheme. - bool alternateGpuWait = (!c_disableAlternatingWait && useGpuPmeOnThisRank && simulationWork.useGpuNonbonded && !DOMAINDECOMP(cr) && - (useGpuFBufOps == BufferOpsUseGpu::False)); + bool alternateGpuWait = (!c_disableAlternatingWait && useGpuPmeOnThisRank && simulationWork.useGpuNonbonded + && !DOMAINDECOMP(cr) && (useGpuFBufOps == BufferOpsUseGpu::False)); if (alternateGpuWait) { - alternatePmeNbGpuWaitReduce(fr->nbv.get(), fr->pmedata, &forceOut, enerd, - stepWork, pmeFlags, wcycle); + alternatePmeNbGpuWaitReduce(fr->nbv.get(), fr->pmedata, &forceOut, enerd, stepWork, pmeFlags, wcycle); } if (!alternateGpuWait && useGpuPmeOnThisRank) @@ -1646,18 +1606,14 @@ void do_force(FILE *fplog, * of the step time. */ const float gpuWaitApiOverheadMargin = 2e6F; /* cycles */ - const float waitCycles = - Nbnxm::gpu_wait_finish_task(nbv->gpu_nbv, - stepWork, AtomLocality::Local, - enerd->grpp.ener[egLJSR].data(), - enerd->grpp.ener[egCOULSR].data(), - forceOut.forceWithShiftForces().shiftForces(), - wcycle); + const float waitCycles = Nbnxm::gpu_wait_finish_task( + nbv->gpu_nbv, stepWork, AtomLocality::Local, enerd->grpp.ener[egLJSR].data(), + enerd->grpp.ener[egCOULSR].data(), forceOut.forceWithShiftForces().shiftForces(), wcycle); if (ddBalanceRegionHandler.useBalancingRegion()) { DdBalanceRegionWaitedForGpu waitedForGpu = DdBalanceRegionWaitedForGpu::yes; - if (stepWork.computeForces && waitCycles <= gpuWaitApiOverheadMargin) + if (stepWork.computeForces && waitCycles <= gpuWaitApiOverheadMargin) { /* We measured few cycles, it could be that the kernel * and transfer finished earlier and there was no actual @@ -1677,8 +1633,7 @@ void do_force(FILE *fplog, // but emulation mode does not target performance anyway wallcycle_start_nocount(wcycle, ewcFORCE); do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, - DOMAINDECOMP(cr) ? enbvClearFNo : enbvClearFYes, - step, nrnb, wcycle); + DOMAINDECOMP(cr) ? enbvClearFNo : enbvClearFYes, step, nrnb, wcycle); wallcycle_stop(wcycle, ewcFORCE); } @@ -1689,7 +1644,9 @@ void do_force(FILE *fplog, /* In case of node-splitting, the PP nodes receive the long-range * forces, virial and energy from the PME nodes here. */ - pme_receive_force_ener(fr, cr, &forceOut.forceWithVirial(), enerd, simulationWork.useGpuPmePpCommunication, stepWork.useGpuPmeFReduction, wcycle); + pme_receive_force_ener(fr, cr, &forceOut.forceWithVirial(), enerd, + simulationWork.useGpuPmePpCommunication, + stepWork.useGpuPmeFReduction, wcycle); } @@ -1697,19 +1654,21 @@ void do_force(FILE *fplog, * on the non-alternating path. */ if (useOrEmulateGpuNb && !alternateGpuWait) { - //TODO simplify the below conditionals. Pass buffer and sync pointers at init stage rather than here. Unify getter fns for sameGPU/otherGPU cases. - void* pmeForcePtr = stepWork.useGpuPmeFReduction ? - (thisRankHasDuty(cr, DUTY_PME) ? - pme_gpu_get_device_f(fr->pmedata) : // PME force buffer on same GPU - fr->pmePpCommGpu->getGpuForceStagingPtr()) // buffer received from other GPU - : nullptr; // PME reduction not active on GPU - - GpuEventSynchronizer* const pmeSynchronizer = stepWork.useGpuPmeFReduction ? - (thisRankHasDuty(cr, DUTY_PME) ? - pme_gpu_get_f_ready_synchronizer(fr->pmedata) : // PME force buffer on same GPU - static_cast - (fr->pmePpCommGpu->getForcesReadySynchronizer())) // buffer received from other GPU - : nullptr; // PME reduction not active on GPU + // TODO simplify the below conditionals. Pass buffer and sync pointers at init stage rather than here. Unify getter fns for sameGPU/otherGPU cases. + void* pmeForcePtr = + stepWork.useGpuPmeFReduction + ? (thisRankHasDuty(cr, DUTY_PME) ? pme_gpu_get_device_f(fr->pmedata) + : // PME force buffer on same GPU + fr->pmePpCommGpu->getGpuForceStagingPtr()) // buffer received from other GPU + : nullptr; // PME reduction not active on GPU + + GpuEventSynchronizer* const pmeSynchronizer = + stepWork.useGpuPmeFReduction + ? (thisRankHasDuty(cr, DUTY_PME) ? pme_gpu_get_f_ready_synchronizer(fr->pmedata) + : // PME force buffer on same GPU + static_cast( + fr->pmePpCommGpu->getForcesReadySynchronizer())) // buffer received from other GPU + : nullptr; // PME reduction not active on GPU gmx::FixedCapacityVector dependencyList; @@ -1718,7 +1677,7 @@ void do_force(FILE *fplog, dependencyList.push_back(pmeSynchronizer); } - gmx::ArrayRef forceWithShift = forceOut.forceWithShiftForces().force(); + gmx::ArrayRef forceWithShift = forceOut.forceWithShiftForces().force(); if (useGpuFBufOps == BufferOpsUseGpu::True) { @@ -1726,7 +1685,8 @@ void do_force(FILE *fplog, // local atoms. This depends on whether there are CPU-based force tasks // or when DD is active the halo exchange has resulted in contributions // from the non-local part. - const bool haveLocalForceContribInCpuBuffer = (domainWork.haveCpuLocalForceWork || havePPDomainDecomposition(cr)); + const bool haveLocalForceContribInCpuBuffer = + (domainWork.haveCpuLocalForceWork || havePPDomainDecomposition(cr)); // TODO: move these steps as early as possible: // - CPU f H2D should be as soon as all CPU-side forces are done @@ -1738,8 +1698,8 @@ void do_force(FILE *fplog, if (haveLocalForceContribInCpuBuffer && !useGpuForcesHaloExchange) { stateGpu->copyForcesToGpu(forceWithShift, AtomLocality::Local); - dependencyList.push_back(stateGpu->getForcesReadyOnDeviceEvent(AtomLocality::Local, - useGpuFBufOps == BufferOpsUseGpu::True)); + dependencyList.push_back(stateGpu->getForcesReadyOnDeviceEvent( + AtomLocality::Local, useGpuFBufOps == BufferOpsUseGpu::True)); } if (useGpuForcesHaloExchange) { @@ -1752,11 +1712,9 @@ void do_force(FILE *fplog, // push the event into the dependencyList nbv->stream_local_wait_for_nonlocal(); } - nbv->atomdata_add_nbat_f_to_f_gpu(AtomLocality::Local, - stateGpu->getForces(), - pmeForcePtr, - dependencyList, - stepWork.useGpuPmeFReduction, haveLocalForceContribInCpuBuffer); + nbv->atomdata_add_nbat_f_to_f_gpu(AtomLocality::Local, stateGpu->getForces(), pmeForcePtr, + dependencyList, stepWork.useGpuPmeFReduction, + haveLocalForceContribInCpuBuffer); // Copy forces to host if they are needed for update or if virtual sites are enabled. // If there are vsites, we need to copy forces every step to spread vsite forces on host. // TODO: When the output flags will be included in step workload, this copy can be combined with the @@ -1773,14 +1731,10 @@ void do_force(FILE *fplog, { nbv->atomdata_add_nbat_f_to_f(AtomLocality::Local, forceWithShift); } - } - launchGpuEndOfStepTasks(nbv, fr->gpuBonded, fr->pmedata, enerd, - *runScheduleWork, - simulationWork.useGpuNonbonded, useGpuPmeOnThisRank, - step, - wcycle); + launchGpuEndOfStepTasks(nbv, fr->gpuBonded, fr->pmedata, enerd, *runScheduleWork, + simulationWork.useGpuNonbonded, useGpuPmeOnThisRank, step, wcycle); if (DOMAINDECOMP(cr)) { @@ -1789,24 +1743,23 @@ void do_force(FILE *fplog, if (stepWork.computeForces) { - rvec *f = as_rvec_array(forceOut.forceWithShiftForces().force().data()); + rvec* f = as_rvec_array(forceOut.forceWithShiftForces().force().data()); /* If we have NoVirSum forces, but we do not calculate the virial, * we sum fr->f_novirsum=forceOut.f later. */ if (vsite && !(fr->haveDirectVirialContributions && !stepWork.computeVirial)) { - rvec *fshift = as_rvec_array(forceOut.forceWithShiftForces().shiftForces().data()); - spread_vsite_f(vsite, as_rvec_array(x.unpaddedArrayRef().data()), f, fshift, FALSE, nullptr, nrnb, - &top->idef, fr->ePBC, fr->bMolPBC, graph, box, cr, wcycle); + rvec* fshift = as_rvec_array(forceOut.forceWithShiftForces().shiftForces().data()); + spread_vsite_f(vsite, as_rvec_array(x.unpaddedArrayRef().data()), f, fshift, FALSE, + nullptr, nrnb, &top->idef, fr->ePBC, fr->bMolPBC, graph, box, cr, wcycle); } if (stepWork.computeVirial) { /* Calculation of the virial must be done after vsites! */ calc_virial(0, mdatoms->homenr, as_rvec_array(x.unpaddedArrayRef().data()), - forceOut.forceWithShiftForces(), - vir_force, graph, box, nrnb, fr, inputrec->ePBC); + forceOut.forceWithShiftForces(), vir_force, graph, box, nrnb, fr, inputrec->ePBC); } } @@ -1822,10 +1775,8 @@ void do_force(FILE *fplog, if (stepWork.computeForces) { - post_process_forces(cr, step, nrnb, wcycle, - top, box, as_rvec_array(x.unpaddedArrayRef().data()), &forceOut, - vir_force, mdatoms, graph, fr, vsite, - stepWork); + post_process_forces(cr, step, nrnb, wcycle, top, box, as_rvec_array(x.unpaddedArrayRef().data()), + &forceOut, vir_force, mdatoms, graph, fr, vsite, stepWork); } if (stepWork.computeEnergy) diff --git a/src/gromacs/mdlib/simulationsignal.cpp b/src/gromacs/mdlib/simulationsignal.cpp index 3959555f64..6ea35c37d3 100644 --- a/src/gromacs/mdlib/simulationsignal.cpp +++ b/src/gromacs/mdlib/simulationsignal.cpp @@ -66,24 +66,26 @@ namespace gmx { -SimulationSignaller::SimulationSignaller(SimulationSignals *signals, - const t_commrec *cr, - const gmx_multisim_t *ms, +SimulationSignaller::SimulationSignaller(SimulationSignals* signals, + const t_commrec* cr, + const gmx_multisim_t* ms, bool doInterSim, - bool doIntraSim) - : signals_(signals), cr_(cr), ms_(ms), - doInterSim_(doInterSim), - doIntraSim_(doInterSim || doIntraSim), - mpiBuffer_ {} -{} + bool doIntraSim) : + signals_(signals), + cr_(cr), + ms_(ms), + doInterSim_(doInterSim), + doIntraSim_(doInterSim || doIntraSim), + mpiBuffer_{} +{ +} -gmx::ArrayRef -SimulationSignaller::getCommunicationBuffer() +gmx::ArrayRef SimulationSignaller::getCommunicationBuffer() { if (doIntraSim_) { std::transform(std::begin(*signals_), std::end(*signals_), std::begin(mpiBuffer_), - [](const SimulationSignals::value_type &s) { return s.sig; }); + [](const SimulationSignals::value_type& s) { return s.sig; }); return mpiBuffer_; } @@ -93,8 +95,7 @@ SimulationSignaller::getCommunicationBuffer() } } -void -SimulationSignaller::signalInterSim() +void SimulationSignaller::signalInterSim() { if (!doInterSim_) { @@ -111,7 +112,7 @@ SimulationSignaller::signalInterSim() gmx_sum_sim(eglsNR, mpiBuffer_.data(), ms_); } // Communicate the signals from the master to the others. - gmx_bcast(eglsNR*sizeof(mpiBuffer_[0]), mpiBuffer_.data(), cr_); + gmx_bcast(eglsNR * sizeof(mpiBuffer_[0]), mpiBuffer_.data(), cr_); } void SimulationSignaller::setSignals() @@ -121,7 +122,7 @@ void SimulationSignaller::setSignals() return; } - SimulationSignals &s = *signals_; + SimulationSignals& s = *signals_; for (size_t i = 0; i < s.size(); i++) { if (doInterSim_ || s[i].isLocal) @@ -149,4 +150,4 @@ void SimulationSignaller::finalizeSignals() setSignals(); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/simulationsignal.h b/src/gromacs/mdlib/simulationsignal.h index 9b6f455d7b..1a038a1801 100644 --- a/src/gromacs/mdlib/simulationsignal.h +++ b/src/gromacs/mdlib/simulationsignal.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,14 +60,18 @@ struct gmx_multisim_t; struct t_commrec; //! Kinds of simulation conditions to signal about. -enum { - eglsCHKPT, eglsSTOPCOND, eglsRESETCOUNTERS, eglsNR +enum +{ + eglsCHKPT, + eglsSTOPCOND, + eglsRESETCOUNTERS, + eglsNR }; namespace gmx { -template +template class ArrayRef; /*! @@ -86,15 +90,15 @@ class ArrayRef; * coordinate this at run time when a SimulationSignaller is made. */ class SimulationSignal { - public: - //! Constructor - SimulationSignal(bool isSignalLocal = true) : sig(0), set(0), isLocal(isSignalLocal) {} - //! The signal set by this rank in do_md(). - signed char sig; - //! The communicated signal that triggers action, which will be equal for all ranks, once communication has occured. - signed char set; - //! Is the signal in one simulation independent of other simulations? - bool isLocal; +public: + //! Constructor + SimulationSignal(bool isSignalLocal = true) : sig(0), set(0), isLocal(isSignalLocal) {} + //! The signal set by this rank in do_md(). + signed char sig; + //! The communicated signal that triggers action, which will be equal for all ranks, once communication has occured. + signed char set; + //! Is the signal in one simulation independent of other simulations? + bool isLocal; }; //! Convenience typedef for the group of signals used. @@ -112,53 +116,54 @@ typedef std::array SimulationSignals; * communication occurs. */ class SimulationSignaller { - public: - //! Constructor - SimulationSignaller(SimulationSignals *signals, - const t_commrec *cr, - const gmx_multisim_t *ms, - bool doInterSim, - bool doIntraSim); - /*! \brief Return a reference to an array of signal values to communicate. - * - * \return If intra-sim signalling will take place, fill and - * return a reference to the array of reals in which signals - * will be communicated with the signal values to be - * sent. Otherwise return a EmptyArrayRef. */ - gmx::ArrayRef getCommunicationBuffer(); - /*! \brief Handle inter-simulation signal communication. - * - * If an inter-simulation signal should be handled, communicate between - * simulation-master ranks, then propagate from the masters to the - * rest of the ranks for each simulation. It is the responsibility of - * the calling code to ensure that any necessary intra-simulation - * signalling has already occurred, e.g. in global_stat(). */ - void signalInterSim(); - /*! \brief Propagate signals when appropriate. - * - * Always propagate an mdrun signal value when doing - * inter-simulation signalling; otherwise, propagate it only - * if should be propagated within this simulation, - * ie. locally. See documentation of SimulationSignal for - * details. */ - void setSignals(); - //! Convenience wrapper that calls signalInterSim() then setSignals(). - void finalizeSignals(); - private: - //! Source and sink for mdrun signals - SimulationSignals *signals_; - //! Communication object. - const t_commrec *cr_; - //! Multi-sim handler. - const gmx_multisim_t *ms_; - //! Do inter-sim communication at this step. - bool doInterSim_; - //! Do intra-sim communication at this step. - bool doIntraSim_; - //! Buffer for MPI communication. - std::array mpiBuffer_; +public: + //! Constructor + SimulationSignaller(SimulationSignals* signals, + const t_commrec* cr, + const gmx_multisim_t* ms, + bool doInterSim, + bool doIntraSim); + /*! \brief Return a reference to an array of signal values to communicate. + * + * \return If intra-sim signalling will take place, fill and + * return a reference to the array of reals in which signals + * will be communicated with the signal values to be + * sent. Otherwise return a EmptyArrayRef. */ + gmx::ArrayRef getCommunicationBuffer(); + /*! \brief Handle inter-simulation signal communication. + * + * If an inter-simulation signal should be handled, communicate between + * simulation-master ranks, then propagate from the masters to the + * rest of the ranks for each simulation. It is the responsibility of + * the calling code to ensure that any necessary intra-simulation + * signalling has already occurred, e.g. in global_stat(). */ + void signalInterSim(); + /*! \brief Propagate signals when appropriate. + * + * Always propagate an mdrun signal value when doing + * inter-simulation signalling; otherwise, propagate it only + * if should be propagated within this simulation, + * ie. locally. See documentation of SimulationSignal for + * details. */ + void setSignals(); + //! Convenience wrapper that calls signalInterSim() then setSignals(). + void finalizeSignals(); + +private: + //! Source and sink for mdrun signals + SimulationSignals* signals_; + //! Communication object. + const t_commrec* cr_; + //! Multi-sim handler. + const gmx_multisim_t* ms_; + //! Do inter-sim communication at this step. + bool doInterSim_; + //! Do intra-sim communication at this step. + bool doIntraSim_; + //! Buffer for MPI communication. + std::array mpiBuffer_; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/splitter.cpp b/src/gromacs/mdlib/splitter.cpp index 3f53746ab6..e59521ce6c 100644 --- a/src/gromacs/mdlib/splitter.cpp +++ b/src/gromacs/mdlib/splitter.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,11 +50,12 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int atom, sid; } t_sid; -static bool sid_comp(const t_sid &sa, const t_sid &sb) +static bool sid_comp(const t_sid& sa, const t_sid& sb) { if (sa.sid == sb.sid) { @@ -66,10 +67,9 @@ static bool sid_comp(const t_sid &sa, const t_sid &sb) } } -static int mk_grey(egCol egc[], t_graph *g, int *AtomI, - int maxsid, t_sid sid[]) +static int mk_grey(egCol egc[], t_graph* g, int* AtomI, int maxsid, t_sid sid[]) { - int j, ng, ai, aj, g0; + int j, ng, ai, aj, g0; ng = 0; ai = *AtomI; @@ -78,7 +78,7 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, /* Loop over all the bonds */ for (j = 0; (j < g->nedge[ai]); j++) { - aj = g->edge[ai][j]-g0; + aj = g->edge[ai][j] - g0; /* If there is a white one, make it gray and set pbc */ if (egc[aj] == egcolWhite) { @@ -89,17 +89,17 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, egc[aj] = egcolGrey; /* Check whether this one has been set before... */ - range_check(aj+g0, 0, maxsid); - range_check(ai+g0, 0, maxsid); - if (sid[aj+g0].sid != -1) + range_check(aj + g0, 0, maxsid); + range_check(ai + g0, 0, maxsid); + if (sid[aj + g0].sid != -1) { - gmx_fatal(FARGS, "sid[%d]=%d, sid[%d]=%d, file %s, line %d", - ai, sid[ai+g0].sid, aj, sid[aj+g0].sid, __FILE__, __LINE__); + gmx_fatal(FARGS, "sid[%d]=%d, sid[%d]=%d, file %s, line %d", ai, sid[ai + g0].sid, + aj, sid[aj + g0].sid, __FILE__, __LINE__); } else { - sid[aj+g0].sid = sid[ai+g0].sid; - sid[aj+g0].atom = aj+g0; + sid[aj + g0].sid = sid[ai + g0].sid; + sid[aj + g0].atom = aj + g0; } ng++; } @@ -107,7 +107,7 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, return ng; } -static int first_colour(int fC, egCol Col, t_graph *g, const egCol egc[]) +static int first_colour(int fC, egCol Col, t_graph* g, const egCol egc[]) /* Return the first node with colour Col starting at fC. * return -1 if none found. */ @@ -125,13 +125,13 @@ static int first_colour(int fC, egCol Col, t_graph *g, const egCol egc[]) return -1; } -static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) +static int mk_sblocks(FILE* fp, t_graph* g, int maxsid, t_sid sid[]) { - int ng, nnodes; - int nW, nG, nB; /* Number of Grey, Black, White */ - int fW, fG; /* First of each category */ - egCol *egc = nullptr; /* The colour of each node */ - int g0, nblock; + int ng, nnodes; + int nW, nG, nB; /* Number of Grey, Black, White */ + int fW, fG; /* First of each category */ + egCol* egc = nullptr; /* The colour of each node */ + int g0, nblock; if (!g->nbound) { @@ -171,9 +171,9 @@ static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) } /* Make the first white node grey, and set the block number */ - egc[fW] = egcolGrey; - range_check(fW+g0, 0, maxsid); - sid[fW+g0].sid = nblock++; + egc[fW] = egcolGrey; + range_check(fW + g0, 0, maxsid); + sid[fW + g0].sid = nblock++; nG++; nW--; @@ -182,8 +182,7 @@ static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) if (debug) { - fprintf(debug, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", - nW, nG, nB, nW+nG+nB); + fprintf(debug, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", nW, nG, nB, nW + nG + nB); } while (nG > 0) @@ -218,20 +217,21 @@ static int mk_sblocks(FILE *fp, t_graph *g, int maxsid, t_sid sid[]) } -typedef struct { +typedef struct +{ int first, last, sid; } t_merge_sid; -static int ms_comp(const void *a, const void *b) +static int ms_comp(const void* a, const void* b) { - const t_merge_sid *ma = reinterpret_cast(a); - const t_merge_sid *mb = reinterpret_cast(b); + const t_merge_sid* ma = reinterpret_cast(a); + const t_merge_sid* mb = reinterpret_cast(b); int d; - d = ma->first-mb->first; + d = ma->first - mb->first; if (d == 0) { - return ma->last-mb->last; + return ma->last - mb->last; } else { @@ -239,11 +239,10 @@ static int ms_comp(const void *a, const void *b) } } -static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], - t_blocka *sblock) +static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], t_blocka* sblock) { int i, j, k, n, isid, ndel; - t_merge_sid *ms; + t_merge_sid* ms; /* We try to remdy the following problem: * Atom: 1 2 3 4 5 6 7 8 9 10 @@ -255,7 +254,7 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], for (k = 0; (k < nsid); k++) { - ms[k].first = at_end+1; + ms[k].first = at_end + 1; ms[k].last = -1; ms[k].sid = k; } @@ -273,9 +272,9 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], /* Now merge the overlapping ones */ ndel = 0; - for (k = 0; (k < nsid); ) + for (k = 0; (k < nsid);) { - for (j = k+1; (j < nsid); ) + for (j = k + 1; (j < nsid);) { if (ms[j].first <= ms[k].last) { @@ -288,7 +287,7 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], else { k = j; - j = k+1; + j = k + 1; } } if (j == nsid) @@ -298,11 +297,11 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], } for (k = 0; (k < nsid); k++) { - while ((k < nsid-1) && (ms[k].sid == -1)) + while ((k < nsid - 1) && (ms[k].sid == -1)) { - for (j = k+1; (j < nsid); j++) + for (j = k + 1; (j < nsid); j++) { - std::memcpy(&(ms[j-1]), &(ms[j]), sizeof(ms[0])); + std::memcpy(&(ms[j - 1]), &(ms[j]), sizeof(ms[0])); } nsid--; } @@ -314,7 +313,7 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], sid[k].sid = -1; } sblock->nr = nsid; - sblock->nalloc_index = sblock->nr+1; + sblock->nalloc_index = sblock->nr + 1; snew(sblock->index, sblock->nalloc_index); sblock->nra = at_end - at_start; sblock->nalloc_a = sblock->nra; @@ -322,7 +321,7 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], sblock->index[0] = 0; for (k = n = 0; (k < nsid); k++) { - sblock->index[k+1] = sblock->index[k] + ms[k].last - ms[k].first+1; + sblock->index[k + 1] = sblock->index[k] + ms[k].last - ms[k].first + 1; for (j = ms[k].first; (j <= ms[k].last); j++) { range_check(n, 0, sblock->nra); @@ -347,13 +346,11 @@ static int merge_sid(int at_start, int at_end, int nsid, t_sid sid[], return nsid; } -void gen_sblocks(FILE *fp, int at_start, int at_end, - const t_idef *idef, t_blocka *sblock, - gmx_bool bSettle) +void gen_sblocks(FILE* fp, int at_start, int at_end, const t_idef* idef, t_blocka* sblock, gmx_bool bSettle) { - t_graph *g; + t_graph* g; int i, i0; - t_sid *sid; + t_sid* sid; int nsid; g = mk_graph(nullptr, idef, at_start, at_end, TRUE, bSettle); @@ -364,7 +361,7 @@ void gen_sblocks(FILE *fp, int at_start, int at_end, snew(sid, at_end); for (i = at_start; (i < at_end); i++) { - sid[i].atom = i; + sid[i].atom = i; sid[i].sid = -1; } nsid = mk_sblocks(fp, g, at_end, sid); @@ -375,7 +372,7 @@ void gen_sblocks(FILE *fp, int at_start, int at_end, } /* Now sort the shake blocks... */ - std::sort(sid+at_start, sid+at_end, sid_comp); + std::sort(sid + at_start, sid + at_end, sid_comp); if (debug) { diff --git a/src/gromacs/mdlib/splitter.h b/src/gromacs/mdlib/splitter.h index 536ea97b10..88fb8f205d 100644 --- a/src/gromacs/mdlib/splitter.h +++ b/src/gromacs/mdlib/splitter.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,9 +44,7 @@ struct t_blocka; struct t_idef; -void gen_sblocks(FILE *fp, int at_start, int at_end, - const t_idef *idef, t_blocka *sblock, - gmx_bool bSettle); +void gen_sblocks(FILE* fp, int at_start, int at_end, const t_idef* idef, t_blocka* sblock, gmx_bool bSettle); /* Generate shake blocks from the constraint list. Set bSettle to yes for shake * blocks including settles. You normally do not want this. */ diff --git a/src/gromacs/mdlib/stat.cpp b/src/gromacs/mdlib/stat.cpp index 8bb3bedce3..53b1c7e985 100644 --- a/src/gromacs/mdlib/stat.cpp +++ b/src/gromacs/mdlib/stat.cpp @@ -64,12 +64,12 @@ typedef struct gmx_global_stat { - t_bin *rb; - int *itc0; - int *itc1; + t_bin* rb; + int* itc0; + int* itc1; } t_gmx_global_stat; -gmx_global_stat_t global_stat_init(const t_inputrec *ir) +gmx_global_stat_t global_stat_init(const t_inputrec* ir) { gmx_global_stat_t gs; @@ -90,8 +90,7 @@ void global_stat_destroy(gmx_global_stat_t gs) sfree(gs); } -static int filter_enerdterm(const real *afrom, gmx_bool bToBuffer, real *ato, - gmx_bool bTemp, gmx_bool bPres, gmx_bool bEner) +static int filter_enerdterm(const real* afrom, gmx_bool bToBuffer, real* ato, gmx_bool bTemp, gmx_bool bPres, gmx_bool bEner) { int i, to, from; @@ -136,37 +135,43 @@ static int filter_enerdterm(const real *afrom, gmx_bool bToBuffer, real *ato, return to; } -void global_stat(const gmx_global_stat *gs, - const t_commrec *cr, gmx_enerdata_t *enerd, - tensor fvir, tensor svir, rvec mu_tot, - const t_inputrec *inputrec, - gmx_ekindata_t *ekind, const gmx::Constraints *constr, - t_vcm *vcm, - int nsig, real *sig, - int *totalNumberOfBondedInteractions, - gmx_bool bSumEkinhOld, int flags) +void global_stat(const gmx_global_stat* gs, + const t_commrec* cr, + gmx_enerdata_t* enerd, + tensor fvir, + tensor svir, + rvec mu_tot, + const t_inputrec* inputrec, + gmx_ekindata_t* ekind, + const gmx::Constraints* constr, + t_vcm* vcm, + int nsig, + real* sig, + int* totalNumberOfBondedInteractions, + gmx_bool bSumEkinhOld, + int flags) /* instead of current system, gmx_booleans for summing virial, kinetic energy, and other terms */ { - t_bin *rb; - int *itc0, *itc1; - int ie = 0, ifv = 0, isv = 0, irmsd = 0, imu = 0; - int idedl = 0, idedlo = 0, idvdll = 0, idvdlnl = 0, iepl = 0, icm = 0, imass = 0, ica = 0, inb = 0; - int isig = -1; - int icj = -1, ici = -1, icx = -1; - int inn[egNR]; - real copyenerd[F_NRE]; - int nener, j; - double nb; - gmx_bool bVV, bTemp, bEner, bPres, bConstrVir, bEkinAveVel, bReadEkin; - bool checkNumberOfBondedInteractions = (flags & CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS) != 0; - - bVV = EI_VV(inputrec->eI); - bTemp = ((flags & CGLO_TEMPERATURE) != 0); - bEner = ((flags & CGLO_ENERGY) != 0); - bPres = ((flags & CGLO_PRESSURE) != 0); - bConstrVir = ((flags & CGLO_CONSTRAINT) != 0); - bEkinAveVel = (inputrec->eI == eiVV || (inputrec->eI == eiVVAK && bPres)); - bReadEkin = ((flags & CGLO_READEKIN) != 0); + t_bin* rb; + int * itc0, *itc1; + int ie = 0, ifv = 0, isv = 0, irmsd = 0, imu = 0; + int idedl = 0, idedlo = 0, idvdll = 0, idvdlnl = 0, iepl = 0, icm = 0, imass = 0, ica = 0, inb = 0; + int isig = -1; + int icj = -1, ici = -1, icx = -1; + int inn[egNR]; + real copyenerd[F_NRE]; + int nener, j; + double nb; + gmx_bool bVV, bTemp, bEner, bPres, bConstrVir, bEkinAveVel, bReadEkin; + bool checkNumberOfBondedInteractions = (flags & CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS) != 0; + + bVV = EI_VV(inputrec->eI); + bTemp = ((flags & CGLO_TEMPERATURE) != 0); + bEner = ((flags & CGLO_ENERGY) != 0); + bPres = ((flags & CGLO_PRESSURE) != 0); + bConstrVir = ((flags & CGLO_CONSTRAINT) != 0); + bEkinAveVel = (inputrec->eI == eiVV || (inputrec->eI == eiVVAK && bPres)); + bReadEkin = ((flags & CGLO_READEKIN) != 0); rb = gs->rb; itc0 = gs->itc0; @@ -189,10 +194,10 @@ void global_stat(const gmx_global_stat *gs, This is just the constraint virial.*/ if (bConstrVir) { - isv = add_binr(rb, DIM*DIM, svir[0]); + isv = add_binr(rb, DIM * DIM, svir[0]); } -/* We need the force virial and the kinetic energy for the first time through with velocity verlet */ + /* We need the force virial and the kinetic energy for the first time through with velocity verlet */ if (bTemp || !bVV) { if (ekind) @@ -201,15 +206,15 @@ void global_stat(const gmx_global_stat *gs, { if (bSumEkinhOld) { - itc0[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinh_old[0]); + itc0[j] = add_binr(rb, DIM * DIM, ekind->tcstat[j].ekinh_old[0]); } if (bEkinAveVel && !bReadEkin) { - itc1[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinf[0]); + itc1[j] = add_binr(rb, DIM * DIM, ekind->tcstat[j].ekinf[0]); } else if (!bReadEkin) { - itc1[j] = add_binr(rb, DIM*DIM, ekind->tcstat[j].ekinh[0]); + itc1[j] = add_binr(rb, DIM * DIM, ekind->tcstat[j].ekinh[0]); } } /* these probably need to be put into one of these categories */ @@ -220,20 +225,20 @@ void global_stat(const gmx_global_stat *gs, } if (ekind->cosacc.cos_accel != 0) { - ica = add_binr(rb, 1, &(ekind->cosacc.mvcos)); + ica = add_binr(rb, 1, &(ekind->cosacc.mvcos)); } } } if (bPres) { - ifv = add_binr(rb, DIM*DIM, fvir[0]); + ifv = add_binr(rb, DIM * DIM, fvir[0]); } gmx::ArrayRef rmsdData; if (bEner) { - ie = add_binr(rb, nener, copyenerd); + ie = add_binr(rb, nener, copyenerd); if (constr) { rmsdData = constr->rmsdData(); @@ -264,13 +269,13 @@ void global_stat(const gmx_global_stat *gs, if (vcm) { - icm = add_binr(rb, DIM*vcm->nr, vcm->group_p[0]); + icm = add_binr(rb, DIM * vcm->nr, vcm->group_p[0]); imass = add_binr(rb, vcm->nr, vcm->group_mass.data()); if (vcm->mode == ecmANGULAR) { - icj = add_binr(rb, DIM*vcm->nr, vcm->group_j[0]); - icx = add_binr(rb, DIM*vcm->nr, vcm->group_x[0]); - ici = add_binr(rb, DIM*DIM*vcm->nr, vcm->group_i[0][0]); + icj = add_binr(rb, DIM * vcm->nr, vcm->group_j[0]); + icx = add_binr(rb, DIM * vcm->nr, vcm->group_x[0]); + ici = add_binr(rb, DIM * DIM * vcm->nr, vcm->group_i[0][0]); } } @@ -295,7 +300,7 @@ void global_stat(const gmx_global_stat *gs, if (bConstrVir) { - extract_binr(rb, isv, DIM*DIM, svir[0]); + extract_binr(rb, isv, DIM * DIM, svir[0]); } /* We need the force virial and the kinetic energy for the first time through with velocity verlet */ @@ -307,15 +312,15 @@ void global_stat(const gmx_global_stat *gs, { if (bSumEkinhOld) { - extract_binr(rb, itc0[j], DIM*DIM, ekind->tcstat[j].ekinh_old[0]); + extract_binr(rb, itc0[j], DIM * DIM, ekind->tcstat[j].ekinh_old[0]); } if (bEkinAveVel && !bReadEkin) { - extract_binr(rb, itc1[j], DIM*DIM, ekind->tcstat[j].ekinf[0]); + extract_binr(rb, itc1[j], DIM * DIM, ekind->tcstat[j].ekinf[0]); } else if (!bReadEkin) { - extract_binr(rb, itc1[j], DIM*DIM, ekind->tcstat[j].ekinh[0]); + extract_binr(rb, itc1[j], DIM * DIM, ekind->tcstat[j].ekinh[0]); } } extract_binr(rb, idedl, 1, &(ekind->dekindl)); @@ -331,7 +336,7 @@ void global_stat(const gmx_global_stat *gs, } if (bPres) { - extract_binr(rb, ifv, DIM*DIM, fvir[0]); + extract_binr(rb, ifv, DIM * DIM, fvir[0]); } if (bEner) @@ -365,13 +370,13 @@ void global_stat(const gmx_global_stat *gs, if (vcm) { - extract_binr(rb, icm, DIM*vcm->nr, vcm->group_p[0]); + extract_binr(rb, icm, DIM * vcm->nr, vcm->group_p[0]); extract_binr(rb, imass, vcm->nr, vcm->group_mass.data()); if (vcm->mode == ecmANGULAR) { - extract_binr(rb, icj, DIM*vcm->nr, vcm->group_j[0]); - extract_binr(rb, icx, DIM*vcm->nr, vcm->group_x[0]); - extract_binr(rb, ici, DIM*DIM*vcm->nr, vcm->group_i[0][0]); + extract_binr(rb, icj, DIM * vcm->nr, vcm->group_j[0]); + extract_binr(rb, icx, DIM * vcm->nr, vcm->group_x[0]); + extract_binr(rb, ici, DIM * DIM * vcm->nr, vcm->group_i[0][0]); } } diff --git a/src/gromacs/mdlib/stat.h b/src/gromacs/mdlib/stat.h index 309f8d7969..cfb21e1802 100644 --- a/src/gromacs/mdlib/stat.h +++ b/src/gromacs/mdlib/stat.h @@ -51,22 +51,28 @@ namespace gmx class Constraints; } -typedef struct gmx_global_stat *gmx_global_stat_t; +typedef struct gmx_global_stat* gmx_global_stat_t; -gmx_global_stat_t global_stat_init(const t_inputrec *ir); +gmx_global_stat_t global_stat_init(const t_inputrec* ir); void global_stat_destroy(gmx_global_stat_t gs); /*! \brief All-reduce energy-like quantities over cr->mpi_comm_mysim */ -void global_stat(const gmx_global_stat *gs, - const t_commrec *cr, gmx_enerdata_t *enerd, - tensor fvir, tensor svir, rvec mu_tot, - const t_inputrec *inputrec, - gmx_ekindata_t *ekind, - const gmx::Constraints *constr, t_vcm *vcm, - int nsig, real *sig, - int *totalNumberOfBondedInteractions, - gmx_bool bSumEkinhOld, int flags); +void global_stat(const gmx_global_stat* gs, + const t_commrec* cr, + gmx_enerdata_t* enerd, + tensor fvir, + tensor svir, + rvec mu_tot, + const t_inputrec* inputrec, + gmx_ekindata_t* ekind, + const gmx::Constraints* constr, + t_vcm* vcm, + int nsig, + real* sig, + int* totalNumberOfBondedInteractions, + gmx_bool bSumEkinhOld, + int flags); /*! \brief Returns TRUE if io should be done */ inline bool do_per_step(int64_t step, int64_t nstep) @@ -81,4 +87,4 @@ inline bool do_per_step(int64_t step, int64_t nstep) } } -#endif //GMX_MDLIB_STAT_H +#endif // GMX_MDLIB_STAT_H diff --git a/src/gromacs/mdlib/stophandler.cpp b/src/gromacs/mdlib/stophandler.cpp index 94c141aca2..040fd5fb18 100644 --- a/src/gromacs/mdlib/stophandler.cpp +++ b/src/gromacs/mdlib/stophandler.cpp @@ -52,11 +52,10 @@ namespace gmx { -StopHandler::StopHandler( - compat::not_null signal, - bool simulationShareState, - std::vector < std::function > stopConditions, - bool neverUpdateNeighborList) : +StopHandler::StopHandler(compat::not_null signal, + bool simulationShareState, + std::vector> stopConditions, + bool neverUpdateNeighborList) : signal_(*signal), stopConditions_(std::move(stopConditions)), neverUpdateNeighborlist_(neverUpdateNeighborList) @@ -67,30 +66,28 @@ StopHandler::StopHandler( } } -StopConditionSignal::StopConditionSignal( - int nstList, - bool makeBinaryReproducibleSimulation, - int nstSignalComm) : +StopConditionSignal::StopConditionSignal(int nstList, bool makeBinaryReproducibleSimulation, int nstSignalComm) : handledStopCondition_(gmx_stop_cond_none), makeBinaryReproducibleSimulation_(makeBinaryReproducibleSimulation), nstSignalComm_(nstSignalComm), nstList_(nstList) -{} +{ +} -StopSignal StopConditionSignal::getSignal(FILE *fplog) +StopSignal StopConditionSignal::getSignal(FILE* fplog) { StopSignal signal = StopSignal::noSignal; /* Check whether everything is still alright */ if (static_cast(gmx_get_stop_condition()) > handledStopCondition_) { - int nsteps_stop = -1; + int nsteps_stop = -1; /* this just makes signals[].sig compatible with the hack of sending signals around by MPI_Reduce together with other floats */ - if ((gmx_get_stop_condition() == gmx_stop_cond_next_ns) || - (makeBinaryReproducibleSimulation_ && gmx_get_stop_condition() == gmx_stop_cond_next)) + if ((gmx_get_stop_condition() == gmx_stop_cond_next_ns) + || (makeBinaryReproducibleSimulation_ && gmx_get_stop_condition() == gmx_stop_cond_next)) { /* We need at least two global communication steps to pass * around the signal. We stop at a pair-list creation step @@ -109,13 +106,11 @@ StopSignal StopConditionSignal::getSignal(FILE *fplog) } if (fplog) { - fprintf(fplog, - "\n\nReceived the %s signal, stopping within %d steps\n\n", + fprintf(fplog, "\n\nReceived the %s signal, stopping within %d steps\n\n", gmx_get_signal_name(), nsteps_stop); fflush(fplog); } - fprintf(stderr, - "\n\nReceived the %s signal, stopping within %d steps\n\n", + fprintf(stderr, "\n\nReceived the %s signal, stopping within %d steps\n\n", gmx_get_signal_name(), nsteps_stop); fflush(stderr); handledStopCondition_ = static_cast(gmx_get_stop_condition()); @@ -124,41 +119,38 @@ StopSignal StopConditionSignal::getSignal(FILE *fplog) return signal; } -StopConditionTime::StopConditionTime( - int nstList, - real maximumHoursToRun, - int nstSignalComm) : +StopConditionTime::StopConditionTime(int nstList, real maximumHoursToRun, int nstSignalComm) : signalSent_(false), maximumHoursToRun_(maximumHoursToRun), nstList_(nstList), nstSignalComm_(nstSignalComm), neverUpdateNeighborlist_(nstList <= 0) -{} +{ +} -StopSignal StopConditionTime::getSignal( - bool bNS, - int64_t step, - FILE *fplog, - gmx_walltime_accounting_t walltime_accounting) +StopSignal StopConditionTime::getSignal(bool bNS, int64_t step, FILE* fplog, gmx_walltime_accounting_t walltime_accounting) { if (signalSent_) { // We only want to send it once, but might be called again before run is terminated return StopSignal::noSignal; } - if ((bNS || neverUpdateNeighborlist_) && - walltime_accounting_get_time_since_start(walltime_accounting) > maximumHoursToRun_ * 60.0 * 60.0 * 0.99) + if ((bNS || neverUpdateNeighborlist_) + && walltime_accounting_get_time_since_start(walltime_accounting) + > maximumHoursToRun_ * 60.0 * 60.0 * 0.99) { /* Signal to terminate the run */ char sbuf[STEPSTRSIZE]; int nsteps_stop = std::max(nstList_, 2 * nstSignalComm_); if (fplog) { - fprintf(fplog, "\nStep %s: Run time exceeded %.3f hours, " + fprintf(fplog, + "\nStep %s: Run time exceeded %.3f hours, " "will terminate the run within %d steps\n", gmx_step_str(step, sbuf), maximumHoursToRun_ * 0.99, nsteps_stop); } - fprintf(stderr, "\nStep %s: Run time exceeded %.3f hours, " + fprintf(stderr, + "\nStep %s: Run time exceeded %.3f hours, " "will terminate the run within %d steps\n", gmx_step_str(step, sbuf), maximumHoursToRun_ * 0.99, nsteps_stop); signalSent_ = true; @@ -172,42 +164,40 @@ void StopHandlerBuilder::registerStopCondition(std::function stopC stopConditions_.emplace_back(std::move(stopCondition)); }; -std::unique_ptr StopHandlerBuilder::getStopHandlerMD ( - compat::not_null signal, - bool simulationShareState, - bool isMaster, - int nstList, - bool makeBinaryReproducibleSimulation, - int nstSignalComm, - real maximumHoursToRun, - bool neverUpdateNeighborList, - FILE *fplog, - const int64_t &step, - const gmx_bool &bNS, - gmx_walltime_accounting_t walltime_accounting) +std::unique_ptr StopHandlerBuilder::getStopHandlerMD(compat::not_null signal, + bool simulationShareState, + bool isMaster, + int nstList, + bool makeBinaryReproducibleSimulation, + int nstSignalComm, + real maximumHoursToRun, + bool neverUpdateNeighborList, + FILE* fplog, + const int64_t& step, + const gmx_bool& bNS, + gmx_walltime_accounting_t walltime_accounting) { if (!GMX_THREAD_MPI || isMaster) { // Using shared ptr because move-only callable not supported by std::function. // Would require replacement such as fu2::function or cxx_function. auto stopConditionSignal = std::make_shared( - nstList, makeBinaryReproducibleSimulation, nstSignalComm); + nstList, makeBinaryReproducibleSimulation, nstSignalComm); registerStopCondition( - [stopConditionSignal, fplog]() - {return stopConditionSignal->getSignal(fplog); }); + [stopConditionSignal, fplog]() { return stopConditionSignal->getSignal(fplog); }); } if (isMaster && maximumHoursToRun > 0) { - auto stopConditionTime = std::make_shared( - nstList, maximumHoursToRun, nstSignalComm); - registerStopCondition( - [stopConditionTime, &bNS, &step, fplog, walltime_accounting]() - {return stopConditionTime->getSignal(bNS, step, fplog, walltime_accounting); }); + auto stopConditionTime = + std::make_shared(nstList, maximumHoursToRun, nstSignalComm); + registerStopCondition([stopConditionTime, &bNS, &step, fplog, walltime_accounting]() { + return stopConditionTime->getSignal(bNS, step, fplog, walltime_accounting); + }); } - return std::make_unique( - signal, simulationShareState, stopConditions_, neverUpdateNeighborList); + return std::make_unique(signal, simulationShareState, stopConditions_, + neverUpdateNeighborList); } } // namespace gmx diff --git a/src/gromacs/mdlib/stophandler.h b/src/gromacs/mdlib/stophandler.h index 59680e757f..d156b1c6d8 100644 --- a/src/gromacs/mdlib/stophandler.h +++ b/src/gromacs/mdlib/stophandler.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -86,7 +86,9 @@ namespace gmx */ enum class StopSignal { - noSignal = 0, stopAtNextNSStep = 1, stopImmediately = -1 + noSignal = 0, + stopAtNextNSStep = 1, + stopImmediately = -1 }; /*! \brief Convert signed char (as used by SimulationSignal) to StopSignal enum @@ -106,7 +108,7 @@ static inline StopSignal convertToStopSignal(signed char sig) { return StopSignal::stopAtNextNSStep; } - else // sig == 0 + else // sig == 0 { return StopSignal::noSignal; } @@ -123,66 +125,65 @@ static inline StopSignal convertToStopSignal(signed char sig) */ class StopHandler final { - public: - /*! \brief StopHandler constructor (will be called by StopHandlerBuilder) - * - * @param signal Non-null pointer to a signal used for reading and writing of signals - * @param simulationShareState Whether this signal needs to be shared across multiple simulations - * @param stopConditions Vector of callback functions setting the signal - * @param neverUpdateNeighborList Whether simulation keeps same neighbor list forever - * - * Note: As the StopHandler does not work without this signal, it keeps a non-const reference - * to it as a member variable. - */ - StopHandler( - compat::not_null signal, - bool simulationShareState, - std::vector< std::function > stopConditions, - bool neverUpdateNeighborList); +public: + /*! \brief StopHandler constructor (will be called by StopHandlerBuilder) + * + * @param signal Non-null pointer to a signal used for reading and writing of signals + * @param simulationShareState Whether this signal needs to be shared across multiple simulations + * @param stopConditions Vector of callback functions setting the signal + * @param neverUpdateNeighborList Whether simulation keeps same neighbor list forever + * + * Note: As the StopHandler does not work without this signal, it keeps a non-const reference + * to it as a member variable. + */ + StopHandler(compat::not_null signal, + bool simulationShareState, + std::vector> stopConditions, + bool neverUpdateNeighborList); - /*! \brief Decides whether a stop signal shall be sent - * - * Loops over the stopCondition vector passed at build time (consisting of conditions - * registered with StopHandlerBuilder, and conditions built by StopHandlerBuilder by - * default), and sets any signal obtained. - * Returns as soon as a StopSignal::stopImmediately signal was obtained, or after - * checking all registered stop conditions. - */ - void setSignal() const + /*! \brief Decides whether a stop signal shall be sent + * + * Loops over the stopCondition vector passed at build time (consisting of conditions + * registered with StopHandlerBuilder, and conditions built by StopHandlerBuilder by + * default), and sets any signal obtained. + * Returns as soon as a StopSignal::stopImmediately signal was obtained, or after + * checking all registered stop conditions. + */ + void setSignal() const + { + for (auto& condition : stopConditions_) { - for (auto &condition : stopConditions_) + const StopSignal sig = condition(); + if (sig != StopSignal::noSignal) { - const StopSignal sig = condition(); - if (sig != StopSignal::noSignal) + signal_.sig = static_cast(sig); + if (sig == StopSignal::stopImmediately) { - signal_.sig = static_cast(sig); - if (sig == StopSignal::stopImmediately) - { - // We don't want this to be overwritten by a less urgent stop - break; - } + // We don't want this to be overwritten by a less urgent stop + break; } } } + } - /*! \brief Decides whether the simulation shall be stopped after the current step - * - * The simulation is stopped after the current step if - * * the signal for immediate stop was received, or - * * the signal for stop at the next neighbor-searching step was received, and - * the current step is a neighbor-searching step. - */ - bool stoppingAfterCurrentStep(bool bNS) const - { - return convertToStopSignal(signal_.set) == StopSignal::stopImmediately || - (convertToStopSignal(signal_.set) == StopSignal::stopAtNextNSStep && - (bNS || neverUpdateNeighborlist_)); - } + /*! \brief Decides whether the simulation shall be stopped after the current step + * + * The simulation is stopped after the current step if + * * the signal for immediate stop was received, or + * * the signal for stop at the next neighbor-searching step was received, and + * the current step is a neighbor-searching step. + */ + bool stoppingAfterCurrentStep(bool bNS) const + { + return convertToStopSignal(signal_.set) == StopSignal::stopImmediately + || (convertToStopSignal(signal_.set) == StopSignal::stopAtNextNSStep + && (bNS || neverUpdateNeighborlist_)); + } - private: - SimulationSignal &signal_; - const std::vector< std::function > stopConditions_; - const bool neverUpdateNeighborlist_; +private: + SimulationSignal& signal_; + const std::vector> stopConditions_; + const bool neverUpdateNeighborlist_; }; /*! \libinternal @@ -192,28 +193,24 @@ class StopHandler final */ class StopConditionSignal final { - public: - /*! \brief StopConditionSignal constructor - */ - StopConditionSignal( - int nstList, - bool makeBinaryReproducibleSimulation, - int nstSignalComm); - - /*! \brief Decides whether a stopping signal needs to be set - * - * Stop signal is set based on the value of gmx_get_stop_condition(): Set signal for - * stop at the next neighbor-searching step at first SIGINT / SIGTERM, set signal - * for stop at the next step at second SIGINT / SIGTERM. - */ - StopSignal getSignal(FILE *fplog); +public: + /*! \brief StopConditionSignal constructor + */ + StopConditionSignal(int nstList, bool makeBinaryReproducibleSimulation, int nstSignalComm); - private: - int handledStopCondition_; - const bool makeBinaryReproducibleSimulation_; - const int nstSignalComm_; - const int nstList_; + /*! \brief Decides whether a stopping signal needs to be set + * + * Stop signal is set based on the value of gmx_get_stop_condition(): Set signal for + * stop at the next neighbor-searching step at first SIGINT / SIGTERM, set signal + * for stop at the next step at second SIGINT / SIGTERM. + */ + StopSignal getSignal(FILE* fplog); +private: + int handledStopCondition_; + const bool makeBinaryReproducibleSimulation_; + const int nstSignalComm_; + const int nstList_; }; /*! \libinternal @@ -223,32 +220,25 @@ class StopConditionSignal final */ class StopConditionTime final { - public: - /*! \brief StopConditionTime constructor - */ - StopConditionTime( - int nstList, - real maximumHoursToRun, - int nstSignalComm); +public: + /*! \brief StopConditionTime constructor + */ + StopConditionTime(int nstList, real maximumHoursToRun, int nstSignalComm); - /*! \brief Decides whether a stopping signal needs to be set - * - * Stop signal is set if run time is greater than 99% of maximal run time. Signal will - * trigger stopping of the simulation at the next neighbor-searching step. - */ - StopSignal getSignal( - bool bNS, - int64_t step, - FILE *fplog, - gmx_walltime_accounting *walltime_accounting); + /*! \brief Decides whether a stopping signal needs to be set + * + * Stop signal is set if run time is greater than 99% of maximal run time. Signal will + * trigger stopping of the simulation at the next neighbor-searching step. + */ + StopSignal getSignal(bool bNS, int64_t step, FILE* fplog, gmx_walltime_accounting* walltime_accounting); - private: - bool signalSent_; +private: + bool signalSent_; - const real maximumHoursToRun_; - const int nstList_; - const int nstSignalComm_; - const bool neverUpdateNeighborlist_; + const real maximumHoursToRun_; + const int nstList_; + const int nstSignalComm_; + const bool neverUpdateNeighborlist_; }; /*! \libinternal @@ -269,56 +259,55 @@ class StopConditionTime final */ class StopHandlerBuilder final { - public: - /*! \brief Register stop condition - * - * This allows code in the scope of the StopHandlerBuilder (runner level) to inject - * stop conditions in simulations. Stop conditions are defined as argument-less functions - * which return a StopSignal. The return value of this function is then propagated to all - * ranks, and allows to stop the simulation at the next global communication step (returned - * signal StopSignal::stopImmediately), or at the next NS step (returned signal - * StopSignal::stopAtNextNSStep, allows for exact continuation). - * - * Arguments needed by the stop condition function need to be bound / captured. If these - * arguments are captured by reference or using a pointer, it is the registrant's - * responsibility to ensure that these arguments do not go out of scope during the lifetime - * of the StopHandlerBuilder. - */ - void registerStopCondition(std::function stopCondition); +public: + /*! \brief Register stop condition + * + * This allows code in the scope of the StopHandlerBuilder (runner level) to inject + * stop conditions in simulations. Stop conditions are defined as argument-less functions + * which return a StopSignal. The return value of this function is then propagated to all + * ranks, and allows to stop the simulation at the next global communication step (returned + * signal StopSignal::stopImmediately), or at the next NS step (returned signal + * StopSignal::stopAtNextNSStep, allows for exact continuation). + * + * Arguments needed by the stop condition function need to be bound / captured. If these + * arguments are captured by reference or using a pointer, it is the registrant's + * responsibility to ensure that these arguments do not go out of scope during the lifetime + * of the StopHandlerBuilder. + */ + void registerStopCondition(std::function stopCondition); - /*! \brief Create StopHandler - * - * Gets called in the scope of the integrator (aka do_md()) to get a pointer to the - * StopHandler for the current simulations. Adds the standard MD stop conditions - * (e.g. gmx::StopConditionTime, gmx::StopConditionSignal) to the currently registered - * stop conditions. Initializes a new StopHandler with this extended vector of - * stop conditions. It is the caller's responsibility to make sure arguments passed by - * pointer or reference remain valid for the lifetime of the returned StopHandler. - */ - std::unique_ptr getStopHandlerMD ( - compat::not_null signal, - bool simulationShareState, - bool isMaster, - int nstList, - bool makeBinaryReproducibleSimulation, - int nstSignalComm, - real maximumHoursToRun, - bool neverUpdateNeighborList, - FILE *fplog, - const int64_t &step, - const gmx_bool &bNS, - gmx_walltime_accounting *walltime_accounting); + /*! \brief Create StopHandler + * + * Gets called in the scope of the integrator (aka do_md()) to get a pointer to the + * StopHandler for the current simulations. Adds the standard MD stop conditions + * (e.g. gmx::StopConditionTime, gmx::StopConditionSignal) to the currently registered + * stop conditions. Initializes a new StopHandler with this extended vector of + * stop conditions. It is the caller's responsibility to make sure arguments passed by + * pointer or reference remain valid for the lifetime of the returned StopHandler. + */ + std::unique_ptr getStopHandlerMD(compat::not_null signal, + bool simulationShareState, + bool isMaster, + int nstList, + bool makeBinaryReproducibleSimulation, + int nstSignalComm, + real maximumHoursToRun, + bool neverUpdateNeighborList, + FILE* fplog, + const int64_t& step, + const gmx_bool& bNS, + gmx_walltime_accounting* walltime_accounting); - private: - /*! \brief Initial stopConditions - * - * StopConditions registered via registerStopCondition(). getStopHandlerMD will - * copy this vector and add additional conditions before passing the new vector - * to the built StopHandler object. - */ - std::vector< std::function > stopConditions_; +private: + /*! \brief Initial stopConditions + * + * StopConditions registered via registerStopCondition(). getStopHandlerMD will + * copy this vector and add additional conditions before passing the new vector + * to the built StopHandler object. + */ + std::vector> stopConditions_; }; -} // namespace gmx +} // namespace gmx -#endif //GMX_MDLIB_STOPHANDLER_H +#endif // GMX_MDLIB_STOPHANDLER_H diff --git a/src/gromacs/mdlib/tests/calc_verletbuf.cpp b/src/gromacs/mdlib/tests/calc_verletbuf.cpp index da90ace13c..e9d6fa2c31 100644 --- a/src/gromacs/mdlib/tests/calc_verletbuf.cpp +++ b/src/gromacs/mdlib/tests/calc_verletbuf.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -76,11 +76,11 @@ TEST_F(VerletBufferConstraintTest, EqualMasses) // The location and value of the MSD maximum for the exact displacement // is described in the source file. We need to divide the maximum given // there by 2, since sigma2 is per DOF for the 2 DOF constraint rotation. - const real sigma2RelMaxLocation = 4.5119; - const real sigma2RelMaxValue = 2.5695/2; + const real sigma2RelMaxLocation = 4.5119; + const real sigma2RelMaxValue = 2.5695 / 2; // Our max of our current estimate is 3% above the exact value. - const real sigma2RelMaxMargin = 1.04; + const real sigma2RelMaxMargin = 1.04; // The exact parameter values here don't actually matter. real mass = 10; @@ -92,7 +92,7 @@ TEST_F(VerletBufferConstraintTest, EqualMasses) prop.q = 0; prop.bConstr = TRUE; prop.con_mass = mass; - prop.con_len = 2*arm; + prop.con_len = 2 * arm; // We scan a range of rotation distributions by scanning over T. int numPointsBeforeMax = 0; @@ -100,9 +100,9 @@ TEST_F(VerletBufferConstraintTest, EqualMasses) real sigma2_2d_prev = 0; for (int i = 0; i <= 200; i++) { - real ktFac = i*0.01; + real ktFac = i * 0.01; // The rotational displacement is Gaussian with a sigma^2 of: - real sigma2_rot = ktFac/(2*mass); + real sigma2_rot = ktFac / (2 * mass); // Get the estimate for the Cartesian displacement. real sigma2_2d, sigma2_3d; @@ -115,11 +115,12 @@ TEST_F(VerletBufferConstraintTest, EqualMasses) // Check that we don't underestimate sigma2_rot beyond the real maximum // and that our overestimate is tight. - real sigma2Rel = sigma2_rot/gmx::square(arm); + real sigma2Rel = sigma2_rot / gmx::square(arm); if (sigma2Rel >= sigma2RelMaxLocation) { - EXPECT_EQ(std::max(sigma2_2d, sigma2RelMaxValue*gmx::square(arm)), sigma2_2d); - EXPECT_EQ(std::min(sigma2_2d, sigma2RelMaxMargin*sigma2RelMaxValue*gmx::square(arm)), sigma2_2d); + EXPECT_EQ(std::max(sigma2_2d, sigma2RelMaxValue * gmx::square(arm)), sigma2_2d); + EXPECT_EQ(std::min(sigma2_2d, sigma2RelMaxMargin * sigma2RelMaxValue * gmx::square(arm)), + sigma2_2d); numPointsAfterMax++; } @@ -132,9 +133,12 @@ TEST_F(VerletBufferConstraintTest, EqualMasses) EXPECT_REAL_EQ_TOL(sigma2_rot, sigma2_3d, test::defaultRealTolerance()); } - GMX_RELEASE_ASSERT(numPointsBeforeMax >= 20 && numPointsAfterMax >= 20, "This test only provides full coverage when we test a sufficient number of points before and after the location of the maximum value for the exact formula."); + GMX_RELEASE_ASSERT( + numPointsBeforeMax >= 20 && numPointsAfterMax >= 20, + "This test only provides full coverage when we test a sufficient number of points " + "before and after the location of the maximum value for the exact formula."); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/constr.cpp b/src/gromacs/mdlib/tests/constr.cpp index 5c79f2e23f..5883fd9261 100644 --- a/src/gromacs/mdlib/tests/constr.cpp +++ b/src/gromacs/mdlib/tests/constr.cpp @@ -116,250 +116,247 @@ std::vector getRunnersNames() */ class ConstraintsTest : public ::testing::TestWithParam { - public: - //! PBC setups - std::unordered_map pbcs_; - //! Algorithms (SHAKE and LINCS) - std::unordered_map algorithms_; - - /*! \brief Test setup function. - * - * Setting up the pbcs and algorithms. Note, that corresponding string keywords - * have to be explicitly added at the end of this file when the tests are called. - * - */ - void SetUp() override - { +public: + //! PBC setups + std::unordered_map pbcs_; + //! Algorithms (SHAKE and LINCS) + std::unordered_map algorithms_; + + /*! \brief Test setup function. + * + * Setting up the pbcs and algorithms. Note, that corresponding string keywords + * have to be explicitly added at the end of this file when the tests are called. + * + */ + void SetUp() override + { - // - // PBC initialization - // - t_pbc pbc; - - // Infinitely small box - matrix boxNone = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; - set_pbc(&pbc, epbcNONE, boxNone); - pbcs_["PBCNone"] = pbc; - - // Rectangular box - matrix boxXyz = { {10.0, 0.0, 0.0}, {0.0, 20.0, 0.0}, {0.0, 0.0, 15.0} }; - set_pbc(&pbc, epbcXYZ, boxXyz); - pbcs_["PBCXYZ"] = pbc; - - // - // Algorithms - // - // SHAKE - algorithms_["SHAKE"] = applyShake; - // LINCS - algorithms_["LINCS"] = applyLincs; - // LINCS using CUDA (will only be called if CUDA is available) - algorithms_["LINCS_CUDA"] = applyLincsCuda; - } + // + // PBC initialization + // + t_pbc pbc; + + // Infinitely small box + matrix boxNone = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + set_pbc(&pbc, epbcNONE, boxNone); + pbcs_["PBCNone"] = pbc; + + // Rectangular box + matrix boxXyz = { { 10.0, 0.0, 0.0 }, { 0.0, 20.0, 0.0 }, { 0.0, 0.0, 15.0 } }; + set_pbc(&pbc, epbcXYZ, boxXyz); + pbcs_["PBCXYZ"] = pbc; + + // + // Algorithms + // + // SHAKE + algorithms_["SHAKE"] = applyShake; + // LINCS + algorithms_["LINCS"] = applyLincs; + // LINCS using CUDA (will only be called if CUDA is available) + algorithms_["LINCS_CUDA"] = applyLincsCuda; + } - /*! \brief - * The test on the final length of constrained bonds. - * - * Goes through all the constraints and checks if the final length of all the constraints is equal - * to the target length with provided tolerance. - * - * \param[in] tolerance Allowed tolerance in final lengths. - * \param[in] testData Test data structure. - * \param[in] pbc Periodic boundary data. - */ - void checkConstrainsLength(FloatingPointTolerance tolerance, const ConstraintsTestData &testData, t_pbc pbc) - { + /*! \brief + * The test on the final length of constrained bonds. + * + * Goes through all the constraints and checks if the final length of all the constraints is + * equal to the target length with provided tolerance. + * + * \param[in] tolerance Allowed tolerance in final lengths. + * \param[in] testData Test data structure. + * \param[in] pbc Periodic boundary data. + */ + void checkConstrainsLength(FloatingPointTolerance tolerance, const ConstraintsTestData& testData, t_pbc pbc) + { - // Test if all the constraints are satisfied - for (index c = 0; c < ssize(testData.constraints_)/3; c++) + // Test if all the constraints are satisfied + for (index c = 0; c < ssize(testData.constraints_) / 3; c++) + { + real r0 = testData.constraintsR0_.at(testData.constraints_.at(3 * c)); + int i = testData.constraints_.at(3 * c + 1); + int j = testData.constraints_.at(3 * c + 2); + RVec xij0, xij1; + real d0, d1; + if (pbc.ePBC == epbcXYZ) { - real r0 = testData.constraintsR0_.at(testData.constraints_.at(3*c)); - int i = testData.constraints_.at(3*c + 1); - int j = testData.constraints_.at(3*c + 2); - RVec xij0, xij1; - real d0, d1; - if (pbc.ePBC == epbcXYZ) - { - pbc_dx_aiuc(&pbc, testData.x_[i], testData.x_[j], xij0); - pbc_dx_aiuc(&pbc, testData.xPrime_[i], testData.xPrime_[j], xij1); - } - else - { - rvec_sub(testData.x_[i], testData.x_[j], xij0); - rvec_sub(testData.xPrime_[i], testData.xPrime_[j], xij1); - } - d0 = norm(xij0); - d1 = norm(xij1); - EXPECT_REAL_EQ_TOL(r0, d1, tolerance) << gmx::formatString( - "rij = %f, which is not equal to r0 = %f for constraint #%zd, between atoms %d and %d" - " (before constraining rij was %f).", d1, r0, c, i, j, d0); + pbc_dx_aiuc(&pbc, testData.x_[i], testData.x_[j], xij0); + pbc_dx_aiuc(&pbc, testData.xPrime_[i], testData.xPrime_[j], xij1); } - } - - /*! \brief - * The test on the final length of constrained bonds. - * - * Goes through all the constraints and checks if the direction of constraint has not changed - * by the algorithm (i.e. the constraints algorithm arrived to the solution that is closest - * to the initial system conformation). - * - * \param[in] testData Test data structure. - * \param[in] pbc Periodic boundary data. - */ - void checkConstrainsDirection(const ConstraintsTestData &testData, t_pbc pbc) - { - - for (index c = 0; c < ssize(testData.constraints_)/3; c++) + else { - int i = testData.constraints_.at(3*c + 1); - int j = testData.constraints_.at(3*c + 2); - RVec xij0, xij1; - if (pbc.ePBC == epbcXYZ) - { - pbc_dx_aiuc(&pbc, testData.x_[i], testData.x_[j], xij0); - pbc_dx_aiuc(&pbc, testData.xPrime_[i], testData.xPrime_[j], xij1); - } - else - { - rvec_sub(testData.x_[i], testData.x_[j], xij0); - rvec_sub(testData.xPrime_[i], testData.xPrime_[j], xij1); - } - - real dot = xij0.dot(xij1); - - EXPECT_GE(dot, 0.0) << gmx::formatString( - "The constraint %zd changed direction. Constraining algorithm might have returned the wrong root " - "of the constraints equation.", c); - + rvec_sub(testData.x_[i], testData.x_[j], xij0); + rvec_sub(testData.xPrime_[i], testData.xPrime_[j], xij1); } + d0 = norm(xij0); + d1 = norm(xij1); + EXPECT_REAL_EQ_TOL(r0, d1, tolerance) << gmx::formatString( + "rij = %f, which is not equal to r0 = %f for constraint #%zd, between atoms %d " + "and %d" + " (before constraining rij was %f).", + d1, r0, c, i, j, d0); } + } - /*! \brief - * The test on the coordinates of the center of the mass (COM) of the system. - * - * Checks if the center of mass has not been shifted by the constraints. Note, - * that this test does not take into account the periodic boundary conditions. - * Hence it will not work should the constraints decide to move atoms across - * PBC borders. - * - * \param[in] tolerance Allowed tolerance in COM coordinates. - * \param[in] testData Test data structure. - */ - void checkCOMCoordinates(FloatingPointTolerance tolerance, const ConstraintsTestData &testData) - { + /*! \brief + * The test on the final length of constrained bonds. + * + * Goes through all the constraints and checks if the direction of constraint has not changed + * by the algorithm (i.e. the constraints algorithm arrived to the solution that is closest + * to the initial system conformation). + * + * \param[in] testData Test data structure. + * \param[in] pbc Periodic boundary data. + */ + void checkConstrainsDirection(const ConstraintsTestData& testData, t_pbc pbc) + { - RVec comPrime0({0.0, 0.0, 0.0}); - RVec comPrime({0.0, 0.0, 0.0}); - for (int i = 0; i < testData.numAtoms_; i++) + for (index c = 0; c < ssize(testData.constraints_) / 3; c++) + { + int i = testData.constraints_.at(3 * c + 1); + int j = testData.constraints_.at(3 * c + 2); + RVec xij0, xij1; + if (pbc.ePBC == epbcXYZ) { - comPrime0 += testData.masses_[i]*testData.xPrime0_[i]; - comPrime += testData.masses_[i]*testData.xPrime_[i]; + pbc_dx_aiuc(&pbc, testData.x_[i], testData.x_[j], xij0); + pbc_dx_aiuc(&pbc, testData.xPrime_[i], testData.xPrime_[j], xij1); + } + else + { + rvec_sub(testData.x_[i], testData.x_[j], xij0); + rvec_sub(testData.xPrime_[i], testData.xPrime_[j], xij1); } - comPrime0 /= testData.numAtoms_; - comPrime /= testData.numAtoms_; - - EXPECT_REAL_EQ_TOL(comPrime[XX], comPrime0[XX], tolerance) - << "Center of mass was shifted by constraints in x-direction."; - EXPECT_REAL_EQ_TOL(comPrime[YY], comPrime0[YY], tolerance) - << "Center of mass was shifted by constraints in y-direction."; - EXPECT_REAL_EQ_TOL(comPrime[ZZ], comPrime0[ZZ], tolerance) - << "Center of mass was shifted by constraints in z-direction."; + real dot = xij0.dot(xij1); + EXPECT_GE(dot, 0.0) << gmx::formatString( + "The constraint %zd changed direction. Constraining algorithm might have " + "returned the wrong root " + "of the constraints equation.", + c); } + } - /*! \brief - * The test on the velocity of the center of the mass (COM) of the system. - * - * Checks if the velocity of the center of mass has not changed. - * - * \param[in] tolerance Allowed tolerance in COM velocity components. - * \param[in] testData Test data structure. - */ - void checkCOMVelocity(FloatingPointTolerance tolerance, const ConstraintsTestData &testData) + /*! \brief + * The test on the coordinates of the center of the mass (COM) of the system. + * + * Checks if the center of mass has not been shifted by the constraints. Note, + * that this test does not take into account the periodic boundary conditions. + * Hence it will not work should the constraints decide to move atoms across + * PBC borders. + * + * \param[in] tolerance Allowed tolerance in COM coordinates. + * \param[in] testData Test data structure. + */ + void checkCOMCoordinates(FloatingPointTolerance tolerance, const ConstraintsTestData& testData) + { + + RVec comPrime0({ 0.0, 0.0, 0.0 }); + RVec comPrime({ 0.0, 0.0, 0.0 }); + for (int i = 0; i < testData.numAtoms_; i++) { + comPrime0 += testData.masses_[i] * testData.xPrime0_[i]; + comPrime += testData.masses_[i] * testData.xPrime_[i]; + } - RVec comV0({0.0, 0.0, 0.0}); - RVec comV({0.0, 0.0, 0.0}); - for (int i = 0; i < testData.numAtoms_; i++) - { - comV0 += testData.masses_[i]*testData.v0_[i]; - comV += testData.masses_[i]*testData.v_[i]; - } - comV0 /= testData.numAtoms_; - comV /= testData.numAtoms_; - - EXPECT_REAL_EQ_TOL(comV[XX], comV0[XX], tolerance) - << "Velocity of the center of mass in x-direction has been changed by constraints."; - EXPECT_REAL_EQ_TOL(comV[YY], comV0[YY], tolerance) - << "Velocity of the center of mass in y-direction has been changed by constraints."; - EXPECT_REAL_EQ_TOL(comV[ZZ], comV0[ZZ], tolerance) - << "Velocity of the center of mass in z-direction has been changed by constraints."; + comPrime0 /= testData.numAtoms_; + comPrime /= testData.numAtoms_; + + EXPECT_REAL_EQ_TOL(comPrime[XX], comPrime0[XX], tolerance) + << "Center of mass was shifted by constraints in x-direction."; + EXPECT_REAL_EQ_TOL(comPrime[YY], comPrime0[YY], tolerance) + << "Center of mass was shifted by constraints in y-direction."; + EXPECT_REAL_EQ_TOL(comPrime[ZZ], comPrime0[ZZ], tolerance) + << "Center of mass was shifted by constraints in z-direction."; + } + + /*! \brief + * The test on the velocity of the center of the mass (COM) of the system. + * + * Checks if the velocity of the center of mass has not changed. + * + * \param[in] tolerance Allowed tolerance in COM velocity components. + * \param[in] testData Test data structure. + */ + void checkCOMVelocity(FloatingPointTolerance tolerance, const ConstraintsTestData& testData) + { + + RVec comV0({ 0.0, 0.0, 0.0 }); + RVec comV({ 0.0, 0.0, 0.0 }); + for (int i = 0; i < testData.numAtoms_; i++) + { + comV0 += testData.masses_[i] * testData.v0_[i]; + comV += testData.masses_[i] * testData.v_[i]; } + comV0 /= testData.numAtoms_; + comV /= testData.numAtoms_; + + EXPECT_REAL_EQ_TOL(comV[XX], comV0[XX], tolerance) + << "Velocity of the center of mass in x-direction has been changed by constraints."; + EXPECT_REAL_EQ_TOL(comV[YY], comV0[YY], tolerance) + << "Velocity of the center of mass in y-direction has been changed by constraints."; + EXPECT_REAL_EQ_TOL(comV[ZZ], comV0[ZZ], tolerance) + << "Velocity of the center of mass in z-direction has been changed by constraints."; + } - /*! \brief - * The test of virial tensor. - * - * Checks if the values in the scaled virial tensor are equal to pre-computed values. - * - * \param[in] tolerance Tolerance for the tensor values. - * \param[in] testData Test data structure. - */ - void checkVirialTensor(FloatingPointTolerance tolerance, const ConstraintsTestData &testData) + /*! \brief + * The test of virial tensor. + * + * Checks if the values in the scaled virial tensor are equal to pre-computed values. + * + * \param[in] tolerance Tolerance for the tensor values. + * \param[in] testData Test data structure. + */ + void checkVirialTensor(FloatingPointTolerance tolerance, const ConstraintsTestData& testData) + { + for (int i = 0; i < DIM; i++) { - for (int i = 0; i < DIM; i++) + for (int j = 0; j < DIM; j++) { - for (int j = 0; j < DIM; j++) - { - EXPECT_REAL_EQ_TOL(testData.virialScaledRef_[i][j], testData.virialScaled_[i][j], - tolerance) << gmx::formatString( - "Values in virial tensor at [%d][%d] are not within the tolerance from reference value.", i, j); - } + EXPECT_REAL_EQ_TOL(testData.virialScaledRef_[i][j], testData.virialScaled_[i][j], tolerance) + << gmx::formatString( + "Values in virial tensor at [%d][%d] are not within the " + "tolerance from reference value.", + i, j); } } + } }; -TEST_P(ConstraintsTest, SingleConstraint){ - std::string title = "one constraint (e.g. OH)"; - int numAtoms = 2; - - std::vector masses = {1.0, 12.0}; - std::vector constraints = {0, 0, 1}; - std::vector constraintsR0 = {0.1}; - - real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); - - std::vector x = {{ 0.0, oneTenthOverSqrtTwo, 0.0 }, - { oneTenthOverSqrtTwo, 0.0, 0.0 }}; - std::vector xPrime = {{ 0.01, 0.08, 0.01 }, - { 0.06, 0.01, -0.01 }}; - std::vector v = {{ 1.0, 2.0, 3.0 }, - { 3.0, 2.0, 1.0 }}; - - tensor virialScaledRef = {{-5.58e-04, 5.58e-04, 0.00e+00 }, - { 5.58e-04, -5.58e-04, 0.00e+00 }, - { 0.00e+00, 0.00e+00, 0.00e+00 }}; - - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; - - int lincsNIter = 1; - int lincslincsExpansionOrder = 4; - real lincsWarnAngle = 30.0; - - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); +TEST_P(ConstraintsTest, SingleConstraint) +{ + std::string title = "one constraint (e.g. OH)"; + int numAtoms = 2; + + std::vector masses = { 1.0, 12.0 }; + std::vector constraints = { 0, 0, 1 }; + std::vector constraintsR0 = { 0.1 }; + + real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); + + std::vector x = { { 0.0, oneTenthOverSqrtTwo, 0.0 }, { oneTenthOverSqrtTwo, 0.0, 0.0 } }; + std::vector xPrime = { { 0.01, 0.08, 0.01 }, { 0.06, 0.01, -0.01 } }; + std::vector v = { { 1.0, 2.0, 3.0 }, { 3.0, 2.0, 1.0 } }; + + tensor virialScaledRef = { { -5.58e-04, 5.58e-04, 0.00e+00 }, + { 5.58e-04, -5.58e-04, 0.00e+00 }, + { 0.00e+00, 0.00e+00, 0.00e+00 } }; + + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; + + int lincsNIter = 1; + int lincslincsExpansionOrder = 4; + real lincsWarnAngle = 30.0; + + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string algorithmName; std::tie(pbcName, algorithmName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(algorithmName)(testData.get(), pbc); @@ -370,58 +367,48 @@ TEST_P(ConstraintsTest, SingleConstraint){ checkCOMVelocity(absoluteTolerance(0.0001), *testData); checkVirialTensor(absoluteTolerance(0.0001), *testData); - } -TEST_P(ConstraintsTest, TwoDisjointConstraints){ +TEST_P(ConstraintsTest, TwoDisjointConstraints) +{ - std::string title = "two disjoint constraints"; - int numAtoms = 4; - std::vector masses = {0.5, 1.0/3.0, 0.25, 1.0}; - std::vector constraints = {0, 0, 1, 1, 2, 3}; - std::vector constraintsR0 = {2.0, 1.0}; + std::string title = "two disjoint constraints"; + int numAtoms = 4; + std::vector masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 }; + std::vector constraints = { 0, 0, 1, 1, 2, 3 }; + std::vector constraintsR0 = { 2.0, 1.0 }; - std::vector x = {{ 2.50, -3.10, 15.70 }, - { 0.51, -3.02, 15.55 }, - { -0.50, -3.00, 15.20 }, - { -1.51, -2.95, 15.05 }}; + std::vector x = { + { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 } + }; - std::vector xPrime = {{ 2.50, -3.10, 15.70 }, - { 0.51, -3.02, 15.55 }, - { -0.50, -3.00, 15.20 }, - { -1.51, -2.95, 15.05 }}; + std::vector xPrime = { + { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 } + }; - std::vector v = {{ 0.0, 1.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 0.0, 0.0, 1.0 }, - { 0.0, 0.0, 0.0 }}; + std::vector v = { { 0.0, 1.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0 } }; - tensor virialScaledRef = {{ 3.3e-03, -1.7e-04, 5.6e-04 }, - {-1.7e-04, 8.9e-06, -2.8e-05 }, - { 5.6e-04, -2.8e-05, 8.9e-05 }}; + tensor virialScaledRef = { { 3.3e-03, -1.7e-04, 5.6e-04 }, + { -1.7e-04, 8.9e-06, -2.8e-05 }, + { 5.6e-04, -2.8e-05, 8.9e-05 } }; - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; - int lincsNIter = 1; - int lincslincsExpansionOrder = 4; - real lincsWarnAngle = 30.0; + int lincsNIter = 1; + int lincslincsExpansionOrder = 4; + real lincsWarnAngle = 30.0; - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string algorithmName; std::tie(pbcName, algorithmName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(algorithmName)(testData.get(), pbc); @@ -432,57 +419,48 @@ TEST_P(ConstraintsTest, TwoDisjointConstraints){ checkCOMVelocity(absoluteTolerance(0.0001), *testData); checkVirialTensor(absoluteTolerance(0.0001), *testData); - } -TEST_P(ConstraintsTest, ThreeSequentialConstraints){ +TEST_P(ConstraintsTest, ThreeSequentialConstraints) +{ - std::string title = "three atoms, connected longitudinally (e.g. CH2)"; - int numAtoms = 3; - std::vector masses = {1.0, 12.0, 16.0 }; - std::vector constraints = {0, 0, 1, 1, 1, 2}; - std::vector constraintsR0 = {0.1, 0.2}; + std::string title = "three atoms, connected longitudinally (e.g. CH2)"; + int numAtoms = 3; + std::vector masses = { 1.0, 12.0, 16.0 }; + std::vector constraints = { 0, 0, 1, 1, 1, 2 }; + std::vector constraintsR0 = { 0.1, 0.2 }; - real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); - real twoTenthsOverSqrtThree = 0.2_real / std::sqrt(3.0_real); + real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); + real twoTenthsOverSqrtThree = 0.2_real / std::sqrt(3.0_real); - std::vector x = {{ oneTenthOverSqrtTwo, oneTenthOverSqrtTwo, 0.0 }, - { 0.0, 0.0, 0.0 }, - { twoTenthsOverSqrtThree, twoTenthsOverSqrtThree, twoTenthsOverSqrtThree }}; + std::vector x = { { oneTenthOverSqrtTwo, oneTenthOverSqrtTwo, 0.0 }, + { 0.0, 0.0, 0.0 }, + { twoTenthsOverSqrtThree, twoTenthsOverSqrtThree, twoTenthsOverSqrtThree } }; - std::vector xPrime = {{ 0.08, 0.07, 0.01 }, - { -0.02, 0.01, -0.02 }, - { 0.10, 0.12, 0.11 }}; + std::vector xPrime = { { 0.08, 0.07, 0.01 }, { -0.02, 0.01, -0.02 }, { 0.10, 0.12, 0.11 } }; - std::vector v = {{ 1.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 1.0 }}; + std::vector v = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } }; - tensor virialScaledRef = {{ 4.14e-03, 4.14e-03, 3.31e-03}, - { 4.14e-03, 4.14e-03, 3.31e-03}, - { 3.31e-03, 3.31e-03, 3.31e-03}}; + tensor virialScaledRef = { { 4.14e-03, 4.14e-03, 3.31e-03 }, + { 4.14e-03, 4.14e-03, 3.31e-03 }, + { 3.31e-03, 3.31e-03, 3.31e-03 } }; - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; - int lincsNIter = 1; - int lincslincsExpansionOrder = 4; - real lincsWarnAngle = 30.0; + int lincsNIter = 1; + int lincslincsExpansionOrder = 4; + real lincsWarnAngle = 30.0; - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string algorithmName; std::tie(pbcName, algorithmName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(algorithmName)(testData.get(), pbc); @@ -493,58 +471,49 @@ TEST_P(ConstraintsTest, ThreeSequentialConstraints){ checkCOMVelocity(absoluteTolerance(0.0001), *testData); checkVirialTensor(absoluteTolerance(0.0001), *testData); - } -TEST_P(ConstraintsTest, ThreeConstraintsWithCentralAtom){ +TEST_P(ConstraintsTest, ThreeConstraintsWithCentralAtom) +{ - std::string title = "three atoms, connected to the central atom (e.g. CH3)"; - int numAtoms = 4; - std::vector masses = {12.0, 1.0, 1.0, 1.0 }; - std::vector constraints = {0, 0, 1, 0, 0, 2, 0, 0, 3}; - std::vector constraintsR0 = {0.1}; + std::string title = "three atoms, connected to the central atom (e.g. CH3)"; + int numAtoms = 4; + std::vector masses = { 12.0, 1.0, 1.0, 1.0 }; + std::vector constraints = { 0, 0, 1, 0, 0, 2, 0, 0, 3 }; + std::vector constraintsR0 = { 0.1 }; - std::vector x = {{ 0.00, 0.00, 0.00 }, - { 0.10, 0.00, 0.00 }, - { 0.00, -0.10, 0.00 }, - { 0.00, 0.00, 0.10 }}; + std::vector x = { + { 0.00, 0.00, 0.00 }, { 0.10, 0.00, 0.00 }, { 0.00, -0.10, 0.00 }, { 0.00, 0.00, 0.10 } + }; - std::vector xPrime = {{ 0.004, 0.009, -0.010 }, - { 0.110, -0.006, 0.003 }, - {-0.007, -0.102, -0.007 }, - {-0.005, 0.011, 0.102 }}; + std::vector xPrime = { { 0.004, 0.009, -0.010 }, + { 0.110, -0.006, 0.003 }, + { -0.007, -0.102, -0.007 }, + { -0.005, 0.011, 0.102 } }; - std::vector v = {{ 1.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }}; + std::vector v = { { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 } }; - tensor virialScaledRef = {{7.14e-04, 0.00e+00, 0.00e+00}, - {0.00e+00, 1.08e-03, 0.00e+00}, - {0.00e+00, 0.00e+00, 1.15e-03}}; + tensor virialScaledRef = { { 7.14e-04, 0.00e+00, 0.00e+00 }, + { 0.00e+00, 1.08e-03, 0.00e+00 }, + { 0.00e+00, 0.00e+00, 1.15e-03 } }; - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; - int lincsNIter = 1; - int lincslincsExpansionOrder = 4; - real lincsWarnAngle = 30.0; + int lincsNIter = 1; + int lincslincsExpansionOrder = 4; + real lincsWarnAngle = 30.0; - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string algorithmName; std::tie(pbcName, algorithmName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(algorithmName)(testData.get(), pbc); @@ -557,55 +526,46 @@ TEST_P(ConstraintsTest, ThreeConstraintsWithCentralAtom){ checkVirialTensor(absoluteTolerance(0.0001), *testData); } -TEST_P(ConstraintsTest, FourSequentialConstraints){ +TEST_P(ConstraintsTest, FourSequentialConstraints) +{ - std::string title = "four atoms, connected longitudinally"; - int numAtoms = 4; - std::vector masses = {0.5, 1.0/3.0, 0.25, 1.0}; - std::vector constraints = {0, 0, 1, 1, 1, 2, 2, 2, 3}; - std::vector constraintsR0 = {2.0, 1.0, 1.0}; + std::string title = "four atoms, connected longitudinally"; + int numAtoms = 4; + std::vector masses = { 0.5, 1.0 / 3.0, 0.25, 1.0 }; + std::vector constraints = { 0, 0, 1, 1, 1, 2, 2, 2, 3 }; + std::vector constraintsR0 = { 2.0, 1.0, 1.0 }; - std::vector x = {{ 2.50, -3.10, 15.70 }, - { 0.51, -3.02, 15.55 }, - { -0.50, -3.00, 15.20 }, - { -1.51, -2.95, 15.05 }}; + std::vector x = { + { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 } + }; - std::vector xPrime = {{ 2.50, -3.10, 15.70 }, - { 0.51, -3.02, 15.55 }, - { -0.50, -3.00, 15.20 }, - { -1.51, -2.95, 15.05 }}; + std::vector xPrime = { + { 2.50, -3.10, 15.70 }, { 0.51, -3.02, 15.55 }, { -0.50, -3.00, 15.20 }, { -1.51, -2.95, 15.05 } + }; - std::vector v = {{ 0.0, 0.0, 2.0 }, - { 0.0, 0.0, 3.0 }, - { 0.0, 0.0, -4.0 }, - { 0.0, 0.0, -1.0 }}; + std::vector v = { { 0.0, 0.0, 2.0 }, { 0.0, 0.0, 3.0 }, { 0.0, 0.0, -4.0 }, { 0.0, 0.0, -1.0 } }; - tensor virialScaledRef = {{ 1.15e-01, -4.20e-03, 2.12e-02}, - {-4.20e-03, 1.70e-04, -6.41e-04}, - { 2.12e-02, -6.41e-04, 5.45e-03}}; + tensor virialScaledRef = { { 1.15e-01, -4.20e-03, 2.12e-02 }, + { -4.20e-03, 1.70e-04, -6.41e-04 }, + { 2.12e-02, -6.41e-04, 5.45e-03 } }; - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; - int lincsNIter = 4; - int lincslincsExpansionOrder = 8; - real lincsWarnAngle = 30.0; + int lincsNIter = 4; + int lincslincsExpansionOrder = 8; + real lincsWarnAngle = 30.0; - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string algorithmName; std::tie(pbcName, algorithmName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(algorithmName)(testData.get(), pbc); @@ -616,56 +576,47 @@ TEST_P(ConstraintsTest, FourSequentialConstraints){ checkCOMVelocity(absoluteTolerance(0.0001), *testData); checkVirialTensor(absoluteTolerance(0.01), *testData); - } -TEST_P(ConstraintsTest, TriangleOfConstraints){ +TEST_P(ConstraintsTest, TriangleOfConstraints) +{ - std::string title = "basic triangle (tree atoms, connected to each other)"; - int numAtoms = 3; - std::vector masses = {1.0, 1.0, 1.0}; - std::vector constraints = {0, 0, 1, 2, 0, 2, 1, 1, 2}; - std::vector constraintsR0 = {0.1, 0.1, 0.1}; + std::string title = "basic triangle (tree atoms, connected to each other)"; + int numAtoms = 3; + std::vector masses = { 1.0, 1.0, 1.0 }; + std::vector constraints = { 0, 0, 1, 2, 0, 2, 1, 1, 2 }; + std::vector constraintsR0 = { 0.1, 0.1, 0.1 }; - real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); + real oneTenthOverSqrtTwo = 0.1_real / std::sqrt(2.0_real); - std::vector x = {{ oneTenthOverSqrtTwo, 0.0, 0.0 }, - { 0.0, oneTenthOverSqrtTwo, 0.0 }, - { 0.0, 0.0, oneTenthOverSqrtTwo }}; + std::vector x = { { oneTenthOverSqrtTwo, 0.0, 0.0 }, + { 0.0, oneTenthOverSqrtTwo, 0.0 }, + { 0.0, 0.0, oneTenthOverSqrtTwo } }; - std::vector xPrime = {{ 0.09, -0.02, 0.01 }, - { -0.02, 0.10, -0.02 }, - { 0.03, -0.01, 0.07 }}; + std::vector xPrime = { { 0.09, -0.02, 0.01 }, { -0.02, 0.10, -0.02 }, { 0.03, -0.01, 0.07 } }; - std::vector v = {{ 1.0, 1.0, 1.0 }, - { -2.0, -2.0, -2.0 }, - { 1.0, 1.0, 1.0 }}; + std::vector v = { { 1.0, 1.0, 1.0 }, { -2.0, -2.0, -2.0 }, { 1.0, 1.0, 1.0 } }; - tensor virialScaledRef = {{ 6.00e-04, -1.61e-03, 1.01e-03}, - {-1.61e-03, 2.53e-03, -9.25e-04}, - { 1.01e-03, -9.25e-04, -8.05e-05}}; + tensor virialScaledRef = { { 6.00e-04, -1.61e-03, 1.01e-03 }, + { -1.61e-03, 2.53e-03, -9.25e-04 }, + { 1.01e-03, -9.25e-04, -8.05e-05 } }; - real shakeTolerance = 0.0001; - gmx_bool shakeUseSOR = false; + real shakeTolerance = 0.0001; + gmx_bool shakeUseSOR = false; - int lincsNIter = 1; - int lincslincsExpansionOrder = 4; - real lincsWarnAngle = 30.0; + int lincsNIter = 1; + int lincslincsExpansionOrder = 4; + real lincsWarnAngle = 30.0; - std::unique_ptr testData = std::make_unique - (title, numAtoms, masses, - constraints, constraintsR0, - true, virialScaledRef, - false, 0, - real(0.0), real(0.001), - x, xPrime, v, - shakeTolerance, shakeUseSOR, - lincsNIter, lincslincsExpansionOrder, lincsWarnAngle); + std::unique_ptr testData = std::make_unique( + title, numAtoms, masses, constraints, constraintsR0, true, virialScaledRef, false, 0, + real(0.0), real(0.001), x, xPrime, v, shakeTolerance, shakeUseSOR, lincsNIter, + lincslincsExpansionOrder, lincsWarnAngle); std::string pbcName; std::string runnerName; std::tie(pbcName, runnerName) = GetParam(); - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply constraints algorithms_.at(runnerName)(testData.get(), pbc); @@ -676,13 +627,13 @@ TEST_P(ConstraintsTest, TriangleOfConstraints){ checkCOMVelocity(absoluteTolerance(0.0001), *testData); checkVirialTensor(absoluteTolerance(0.00001), *testData); - } -INSTANTIATE_TEST_CASE_P(WithParameters, ConstraintsTest, - ::testing::Combine(::testing::Values("PBCNone", "PBCXYZ"), - ::testing::ValuesIn(getRunnersNames()))); +INSTANTIATE_TEST_CASE_P(WithParameters, + ConstraintsTest, + ::testing::Combine(::testing::Values("PBCNone", "PBCXYZ"), + ::testing::ValuesIn(getRunnersNames()))); } // namespace } // namespace test diff --git a/src/gromacs/mdlib/tests/constrtestdata.cpp b/src/gromacs/mdlib/tests/constrtestdata.cpp index 0873d45c2b..0679b51713 100644 --- a/src/gromacs/mdlib/tests/constrtestdata.cpp +++ b/src/gromacs/mdlib/tests/constrtestdata.cpp @@ -57,15 +57,25 @@ namespace gmx namespace test { -ConstraintsTestData::ConstraintsTestData(const std::string &title, - int numAtoms, std::vector masses, - std::vector constraints, std::vector constraintsR0, - bool computeVirial, tensor virialScaledRef, - bool compute_dHdLambda, float dHdLambdaRef, - real initialTime, real timestep, - const std::vector &x, const std::vector &xPrime, const std::vector &v, - real shakeTolerance, gmx_bool shakeUseSOR, - int lincsNumIterations, int lincsExpansionOrder, real lincsWarnAngle) +ConstraintsTestData::ConstraintsTestData(const std::string& title, + int numAtoms, + std::vector masses, + std::vector constraints, + std::vector constraintsR0, + bool computeVirial, + tensor virialScaledRef, + bool compute_dHdLambda, + float dHdLambdaRef, + real initialTime, + real timestep, + const std::vector& x, + const std::vector& xPrime, + const std::vector& v, + real shakeTolerance, + gmx_bool shakeUseSOR, + int lincsNumIterations, + int lincsExpansionOrder, + real lincsWarnAngle) { title_ = title; // Human-friendly name of the system numAtoms_ = numAtoms; // Number of atoms @@ -76,14 +86,14 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, for (int i = 0; i < numAtoms; i++) { - invmass_[i] = 1.0/masses.at(i); + invmass_[i] = 1.0 / masses.at(i); } // Saving constraints to check if they are satisfied after algorithm was applied constraints_ = constraints; // Constraints indices (in type-i-j format) constraintsR0_ = constraintsR0; // Equilibrium distances for each type of constraint - invdt_ = 1.0/timestep; // Inverse timestep + invdt_ = 1.0 / timestep; // Inverse timestep // Communication record cr_.nnodes = 1; @@ -94,10 +104,10 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, ms_.nsim = 1; // Input record - data that usually comes from configuration file (.mdp) - ir_.efep = 0; - ir_.init_t = initialTime; - ir_.delta_t = timestep; - ir_.eI = 0; + ir_.efep = 0; + ir_.init_t = initialTime; + ir_.delta_t = timestep; + ir_.eI = 0; // MD atoms data md_.nMassPerturbed = 0; @@ -126,13 +136,13 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, dHdLambda_ = 0; if (compute_dHdLambda_) { - ir_.efep = efepYES; - dHdLambdaRef_ = dHdLambdaRef; + ir_.efep = efepYES; + dHdLambdaRef_ = dHdLambdaRef; } else { - ir_.efep = efepNO; - dHdLambdaRef_ = 0; + ir_.efep = efepNO; + dHdLambdaRef_ = 0; } // Constraints and their parameters (local topology) @@ -140,7 +150,7 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, { idef_.il[i].nr = 0; } - idef_.il[F_CONSTR].nr = constraints.size(); + idef_.il[F_CONSTR].nr = constraints.size(); snew(idef_.il[F_CONSTR].iatoms, constraints.size()); int maxType = 0; @@ -156,10 +166,10 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, idef_.il[F_CONSTR].iatoms[i] = constraints.at(i); } snew(idef_.iparams, maxType + 1); - for (index i = 0; i < ssize(constraints)/3; i++) + for (index i = 0; i < ssize(constraints) / 3; i++) { - idef_.iparams[constraints.at(3*i)].constr.dA = constraintsR0.at(constraints.at(3*i)); - idef_.iparams[constraints.at(3*i)].constr.dB = constraintsR0.at(constraints.at(3*i)); + idef_.iparams[constraints.at(3 * i)].constr.dA = constraintsR0.at(constraints.at(3 * i)); + idef_.iparams[constraints.at(3 * i)].constr.dB = constraintsR0.at(constraints.at(3 * i)); } // Constraints and their parameters (global topology) @@ -206,8 +216,8 @@ ConstraintsTestData::ConstraintsTestData(const std::string &title, std::copy(v.begin(), v.end(), v0_.begin()); // SHAKE-specific parameters - ir_.shake_tol = shakeTolerance; - ir_.bShakeSOR = shakeUseSOR; + ir_.shake_tol = shakeTolerance; + ir_.bShakeSOR = shakeUseSOR; // LINCS-specific parameters ir_.nLincsIter = lincsNumIterations; @@ -238,7 +248,7 @@ void ConstraintsTestData::reset() } } } - dHdLambda_ = 0; + dHdLambda_ = 0; } /*! \brief diff --git a/src/gromacs/mdlib/tests/constrtestdata.h b/src/gromacs/mdlib/tests/constrtestdata.h index 8375d6bbc5..4283674b1f 100644 --- a/src/gromacs/mdlib/tests/constrtestdata.h +++ b/src/gromacs/mdlib/tests/constrtestdata.h @@ -78,132 +78,142 @@ namespace test */ class ConstraintsTestData { - public: - //! Human-friendly name for a system - std::string title_; - //! Number of atoms - int numAtoms_; - //! Topology - gmx_mtop_t mtop_; - //! Masses - std::vector masses_; - //! Inverse masses - std::vector invmass_; - //! Communication record - t_commrec cr_; - //! Input record (info that usually in .mdp file) - t_inputrec ir_; - //! Local topology - t_idef idef_; - //! MD atoms - t_mdatoms md_; - //! Multisim data - gmx_multisim_t ms_; - //! Computational time array (normally used to benchmark performance) - t_nrnb nrnb_; +public: + //! Human-friendly name for a system + std::string title_; + //! Number of atoms + int numAtoms_; + //! Topology + gmx_mtop_t mtop_; + //! Masses + std::vector masses_; + //! Inverse masses + std::vector invmass_; + //! Communication record + t_commrec cr_; + //! Input record (info that usually in .mdp file) + t_inputrec ir_; + //! Local topology + t_idef idef_; + //! MD atoms + t_mdatoms md_; + //! Multisim data + gmx_multisim_t ms_; + //! Computational time array (normally used to benchmark performance) + t_nrnb nrnb_; - //! Inverse timestep - real invdt_; - //! Number of flexible constraints - int nflexcon_ = 0; - //! Whether the virial should be computed - bool computeVirial_; - //! Scaled virial - tensor virialScaled_; - //! Scaled virial (reference values) - tensor virialScaledRef_; - //! If the free energy is computed - bool compute_dHdLambda_; - //! For free energy computation - real dHdLambda_; - //! For free energy computation (reference value) - real dHdLambdaRef_; + //! Inverse timestep + real invdt_; + //! Number of flexible constraints + int nflexcon_ = 0; + //! Whether the virial should be computed + bool computeVirial_; + //! Scaled virial + tensor virialScaled_; + //! Scaled virial (reference values) + tensor virialScaledRef_; + //! If the free energy is computed + bool compute_dHdLambda_; + //! For free energy computation + real dHdLambda_; + //! For free energy computation (reference value) + real dHdLambdaRef_; - //! Coordinates before the timestep - PaddedVector x_; - //! Coordinates after timestep, output for the constraints - PaddedVector xPrime_; - //! Backup for coordinates (for reset) - PaddedVector xPrime0_; - //! Intermediate set of coordinates (normally used for projection correction) - PaddedVector xPrime2_; - //! Velocities - PaddedVector v_; - //! Backup for velocities (for reset) - PaddedVector v0_; + //! Coordinates before the timestep + PaddedVector x_; + //! Coordinates after timestep, output for the constraints + PaddedVector xPrime_; + //! Backup for coordinates (for reset) + PaddedVector xPrime0_; + //! Intermediate set of coordinates (normally used for projection correction) + PaddedVector xPrime2_; + //! Velocities + PaddedVector v_; + //! Backup for velocities (for reset) + PaddedVector v0_; - //! Constraints data (type1-i1-j1-type2-i2-j2-...) - std::vector constraints_; - //! Target lengths for all constraint types - std::vector constraintsR0_; + //! Constraints data (type1-i1-j1-type2-i2-j2-...) + std::vector constraints_; + //! Target lengths for all constraint types + std::vector constraintsR0_; - /*! \brief - * Constructor for the object with all parameters and variables needed by constraints algorithms. - * - * This constructor assembles stubs for all the data structures, required to initialize - * and apply LINCS and SHAKE constraints. The coordinates and velocities before constraining - * are saved to allow for reset. The constraints data are stored for testing after constraints - * were applied. - * - * \param[in] title Human-friendly name of the system. - * \param[in] numAtoms Number of atoms in the system. - * \param[in] masses Atom masses. Size of this vector should be equal to numAtoms. - * \param[in] constraints List of constraints, organized in triples of integers. - * First integer is the index of type for a constraint, second - * and third are the indices of constrained atoms. The types - * of constraints should be sequential but not necessarily - * start from zero (which is the way they normally are in - * GROMACS). - * \param[in] constraintsR0 Target values for bond lengths for bonds of each type. The - * size of this vector should be equal to the total number of - * unique types in constraints vector. - * \param[in] computeVirial Whether the virial should be computed. - * \param[in] virialScaledRef Reference values for scaled virial tensor. - * \param[in] compute_dHdLambda Whether free energy should be computed. - * \param[in] dHdLambdaRef Reference value for dHdLambda. - * \param[in] initialTime Initial time. - * \param[in] timestep Timestep. - * \param[in] x Coordinates before integration step. - * \param[in] xPrime Coordinates after integration step, but before constraining. - * \param[in] v Velocities before constraining. - * \param[in] shakeTolerance Target tolerance for SHAKE. - * \param[in] shakeUseSOR Use successive over-relaxation method for SHAKE iterations. - * The general formula is: - * x_n+1 = (1-omega)*x_n + omega*f(x_n), - * where omega = 1 if SOR is off and may be < 1 if SOR is on. - * \param[in] lincsNumIterations Number of iterations used to compute the inverse matrix. - * \param[in] lincsExpansionOrder The order for algorithm that adjusts the direction of the - * bond after constraints are applied. - * \param[in] lincsWarnAngle The threshold value for the change in bond angle. When - * exceeded the program will issue a warning. - * - */ - ConstraintsTestData(const std::string &title, - int numAtoms, std::vector masses, - std::vector constraints, std::vector constraintsR0, - bool computeVirial, tensor virialScaledRef, - bool compute_dHdLambda, float dHdLambdaRef, - real initialTime, real timestep, - const std::vector &x, const std::vector &xPrime, const std::vector &v, - real shakeTolerance, gmx_bool shakeUseSOR, - int lincsNumIterations, int lincsExpansionOrder, real lincsWarnAngle); + /*! \brief + * Constructor for the object with all parameters and variables needed by constraints algorithms. + * + * This constructor assembles stubs for all the data structures, required to initialize + * and apply LINCS and SHAKE constraints. The coordinates and velocities before constraining + * are saved to allow for reset. The constraints data are stored for testing after constraints + * were applied. + * + * \param[in] title Human-friendly name of the system. + * \param[in] numAtoms Number of atoms in the system. + * \param[in] masses Atom masses. Size of this vector should be equal to numAtoms. + * \param[in] constraints List of constraints, organized in triples of integers. + * First integer is the index of type for a constraint, second + * and third are the indices of constrained atoms. The types + * of constraints should be sequential but not necessarily + * start from zero (which is the way they normally are in + * GROMACS). + * \param[in] constraintsR0 Target values for bond lengths for bonds of each type. The + * size of this vector should be equal to the total number of + * unique types in constraints vector. + * \param[in] computeVirial Whether the virial should be computed. + * \param[in] virialScaledRef Reference values for scaled virial tensor. + * \param[in] compute_dHdLambda Whether free energy should be computed. + * \param[in] dHdLambdaRef Reference value for dHdLambda. + * \param[in] initialTime Initial time. + * \param[in] timestep Timestep. + * \param[in] x Coordinates before integration step. + * \param[in] xPrime Coordinates after integration step, but before constraining. + * \param[in] v Velocities before constraining. + * \param[in] shakeTolerance Target tolerance for SHAKE. + * \param[in] shakeUseSOR Use successive over-relaxation method for SHAKE iterations. + * The general formula is: + * x_n+1 = (1-omega)*x_n + omega*f(x_n), + * where omega = 1 if SOR is off and may be < 1 if SOR is on. + * \param[in] lincsNumIterations Number of iterations used to compute the inverse matrix. + * \param[in] lincsExpansionOrder The order for algorithm that adjusts the direction of the + * bond after constraints are applied. + * \param[in] lincsWarnAngle The threshold value for the change in bond angle. When + * exceeded the program will issue a warning. + * + */ + ConstraintsTestData(const std::string& title, + int numAtoms, + std::vector masses, + std::vector constraints, + std::vector constraintsR0, + bool computeVirial, + tensor virialScaledRef, + bool compute_dHdLambda, + float dHdLambdaRef, + real initialTime, + real timestep, + const std::vector& x, + const std::vector& xPrime, + const std::vector& v, + real shakeTolerance, + gmx_bool shakeUseSOR, + int lincsNumIterations, + int lincsExpansionOrder, + real lincsWarnAngle); - /*! \brief - * Reset the data structure so it can be reused. - * - * Set the coordinates and velocities back to their values before - * constraining. The scaled virial tensor and dHdLambda are zeroed. - * - */ - void reset(); + /*! \brief + * Reset the data structure so it can be reused. + * + * Set the coordinates and velocities back to their values before + * constraining. The scaled virial tensor and dHdLambda are zeroed. + * + */ + void reset(); - /*! \brief - * Cleaning up the memory. - */ - ~ConstraintsTestData(); + /*! \brief + * Cleaning up the memory. + */ + ~ConstraintsTestData(); }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_CONSTRTESTDATA_H diff --git a/src/gromacs/mdlib/tests/constrtestrunners.cpp b/src/gromacs/mdlib/tests/constrtestrunners.cpp index 91aded8058..710e9ac48c 100644 --- a/src/gromacs/mdlib/tests/constrtestrunners.cpp +++ b/src/gromacs/mdlib/tests/constrtestrunners.cpp @@ -86,28 +86,16 @@ namespace test * \param[in] testData Test data structure. * \param[in] pbc Periodic boundary data. */ -void applyShake(ConstraintsTestData *testData, t_pbc gmx_unused pbc) +void applyShake(ConstraintsTestData* testData, t_pbc gmx_unused pbc) { shakedata* shaked = shake_init(); make_shake_sblock_serial(shaked, &testData->idef_, testData->md_); - bool success = constrain_shake( - nullptr, - shaked, - testData->invmass_.data(), - testData->idef_, - testData->ir_, - as_rvec_array(testData->x_.data()), - as_rvec_array(testData->xPrime_.data()), - as_rvec_array(testData->xPrime2_.data()), - &testData->nrnb_, - testData->md_.lambda, - &testData->dHdLambda_, - testData->invdt_, - as_rvec_array(testData->v_.data()), - testData->computeVirial_, - testData->virialScaled_, - false, - gmx::ConstraintVariable::Positions); + bool success = constrain_shake( + nullptr, shaked, testData->invmass_.data(), testData->idef_, testData->ir_, + as_rvec_array(testData->x_.data()), as_rvec_array(testData->xPrime_.data()), + as_rvec_array(testData->xPrime2_.data()), &testData->nrnb_, testData->md_.lambda, + &testData->dHdLambda_, testData->invdt_, as_rvec_array(testData->v_.data()), + testData->computeVirial_, testData->virialScaled_, false, gmx::ConstraintVariable::Positions); EXPECT_TRUE(success) << "Test failed with a false return value in SHAKE."; done_shake(shaked); } @@ -118,49 +106,39 @@ void applyShake(ConstraintsTestData *testData, t_pbc gmx_unused pbc) * \param[in] testData Test data structure. * \param[in] pbc Periodic boundary data. */ -void applyLincs(ConstraintsTestData *testData, t_pbc pbc) +void applyLincs(ConstraintsTestData* testData, t_pbc pbc) { - Lincs *lincsd; - int maxwarn = 100; - int warncount_lincs = 0; + Lincs* lincsd; + int maxwarn = 100; + int warncount_lincs = 0; gmx_omp_nthreads_set(emntLINCS, 1); // Make blocka structure for faster LINCS setup std::vector at2con_mt; at2con_mt.reserve(testData->mtop_.moltype.size()); - for (const gmx_moltype_t &moltype : testData->mtop_.moltype) + for (const gmx_moltype_t& moltype : testData->mtop_.moltype) { // This function is in constr.cpp - at2con_mt.push_back(make_at2con(moltype, - testData->mtop_.ffparams.iparams, + at2con_mt.push_back(make_at2con(moltype, testData->mtop_.ffparams.iparams, flexibleConstraintTreatment(EI_DYNAMICS(testData->ir_.eI)))); } // Initialize LINCS - lincsd = init_lincs(nullptr, testData->mtop_, - testData->nflexcon_, at2con_mt, - false, + lincsd = init_lincs(nullptr, testData->mtop_, testData->nflexcon_, at2con_mt, false, testData->ir_.nLincsIter, testData->ir_.nProjOrder); set_lincs(testData->idef_, testData->md_, EI_DYNAMICS(testData->ir_.eI), &testData->cr_, lincsd); // Evaluate constraints - bool success = constrain_lincs(false, testData->ir_, 0, lincsd, testData->md_, - &testData->cr_, - &testData->ms_, - as_rvec_array(testData->x_.data()), - as_rvec_array(testData->xPrime_.data()), - as_rvec_array(testData->xPrime2_.data()), - pbc.box, &pbc, - testData->md_.lambda, &testData->dHdLambda_, - testData->invdt_, - as_rvec_array(testData->v_.data()), - testData->computeVirial_, testData->virialScaled_, - gmx::ConstraintVariable::Positions, - &testData->nrnb_, - maxwarn, &warncount_lincs); + bool success = constrain_lincs( + false, testData->ir_, 0, lincsd, testData->md_, &testData->cr_, &testData->ms_, + as_rvec_array(testData->x_.data()), as_rvec_array(testData->xPrime_.data()), + as_rvec_array(testData->xPrime2_.data()), pbc.box, &pbc, testData->md_.lambda, + &testData->dHdLambda_, testData->invdt_, as_rvec_array(testData->v_.data()), + testData->computeVirial_, testData->virialScaled_, gmx::ConstraintVariable::Positions, + &testData->nrnb_, maxwarn, &warncount_lincs); EXPECT_TRUE(success) << "Test failed with a false return value in LINCS."; EXPECT_EQ(warncount_lincs, 0) << "There were warnings in LINCS."; - for (auto &moltype : at2con_mt) + for (auto& moltype : at2con_mt) { sfree(moltype.index); sfree(moltype.a); @@ -175,7 +153,7 @@ void applyLincs(ConstraintsTestData *testData, t_pbc pbc) * \param[in] testData Test data structure. * \param[in] pbc Periodic boundary data. */ -void applyLincsCuda(ConstraintsTestData gmx_unused *testData, t_pbc gmx_unused pbc) +void applyLincsCuda(ConstraintsTestData gmx_unused* testData, t_pbc gmx_unused pbc) { FAIL() << "Dummy LINCS CUDA function was called instead of the real one."; } diff --git a/src/gromacs/mdlib/tests/constrtestrunners.cu b/src/gromacs/mdlib/tests/constrtestrunners.cu index dc1fb3ba3a..c62e67e94b 100644 --- a/src/gromacs/mdlib/tests/constrtestrunners.cu +++ b/src/gromacs/mdlib/tests/constrtestrunners.cu @@ -68,11 +68,10 @@ namespace test * \param[in] testData Test data structure. * \param[in] pbc Periodic boundary data. */ -void applyLincsCuda(ConstraintsTestData *testData, t_pbc pbc) +void applyLincsCuda(ConstraintsTestData* testData, t_pbc pbc) { - auto lincsCuda = std::make_unique(testData->ir_.nLincsIter, - testData->ir_.nProjOrder, - nullptr); + auto lincsCuda = + std::make_unique(testData->ir_.nLincsIter, testData->ir_.nProjOrder, nullptr); bool updateVelocities = true; int numAtoms = testData->numAtoms_; @@ -81,24 +80,28 @@ void applyLincsCuda(ConstraintsTestData *testData, t_pbc pbc) lincsCuda->set(testData->idef_, testData->md_); lincsCuda->setPbc(&pbc); - allocateDeviceBuffer(&d_x, numAtoms, nullptr); + allocateDeviceBuffer(&d_x, numAtoms, nullptr); allocateDeviceBuffer(&d_xp, numAtoms, nullptr); - allocateDeviceBuffer(&d_v, numAtoms, nullptr); + allocateDeviceBuffer(&d_v, numAtoms, nullptr); - copyToDeviceBuffer(&d_x, (float3*)(testData->x_.data()), 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&d_xp, (float3*)(testData->xPrime_.data()), 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_x, (float3*)(testData->x_.data()), 0, numAtoms, nullptr, + GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_xp, (float3*)(testData->xPrime_.data()), 0, numAtoms, nullptr, + GpuApiCallBehavior::Sync, nullptr); if (updateVelocities) { - copyToDeviceBuffer(&d_v, (float3*)(testData->v_.data()), 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_v, (float3*)(testData->v_.data()), 0, numAtoms, nullptr, + GpuApiCallBehavior::Sync, nullptr); } - lincsCuda->apply(d_x, d_xp, - updateVelocities, d_v, testData->invdt_, - testData->computeVirial_, testData->virialScaled_); + lincsCuda->apply(d_x, d_xp, updateVelocities, d_v, testData->invdt_, testData->computeVirial_, + testData->virialScaled_); - copyFromDeviceBuffer((float3*)(testData->xPrime_.data()), &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyFromDeviceBuffer((float3*)(testData->xPrime_.data()), &d_xp, 0, numAtoms, nullptr, + GpuApiCallBehavior::Sync, nullptr); if (updateVelocities) { - copyFromDeviceBuffer((float3*)(testData->v_.data()), &d_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyFromDeviceBuffer((float3*)(testData->v_.data()), &d_v, 0, numAtoms, nullptr, + GpuApiCallBehavior::Sync, nullptr); } freeDeviceBuffer(&d_x); diff --git a/src/gromacs/mdlib/tests/constrtestrunners.h b/src/gromacs/mdlib/tests/constrtestrunners.h index 45a27abbaf..f4d24f6e35 100644 --- a/src/gromacs/mdlib/tests/constrtestrunners.h +++ b/src/gromacs/mdlib/tests/constrtestrunners.h @@ -57,18 +57,18 @@ namespace test /*! \brief Apply SHAKE constraints to the test data. */ -void applyShake(ConstraintsTestData *testData, t_pbc pbc); +void applyShake(ConstraintsTestData* testData, t_pbc pbc); /*! \brief Apply LINCS constraints to the test data. */ -void applyLincs(ConstraintsTestData *testData, t_pbc pbc); +void applyLincs(ConstraintsTestData* testData, t_pbc pbc); /*! \brief Apply CUDA version of LINCS constraints to the test data. * * All the data is copied to the GPU device, then LINCS is applied and * the resulting coordinates are copied back. */ -void applyLincsCuda(ConstraintsTestData *testData, t_pbc pbc); +void applyLincsCuda(ConstraintsTestData* testData, t_pbc pbc); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_CONSTRTESTRUNNERS_H diff --git a/src/gromacs/mdlib/tests/ebin.cpp b/src/gromacs/mdlib/tests/ebin.cpp index 9696ba2721..68851145c1 100644 --- a/src/gromacs/mdlib/tests/ebin.cpp +++ b/src/gromacs/mdlib/tests/ebin.cpp @@ -55,52 +55,53 @@ namespace { //! Wraps fclose to discard the return value to use it as a deleter with gmx::unique_cptr. -void fcloseWrapper(FILE *fp) +void fcloseWrapper(FILE* fp) { fclose(fp); } class PrEbinTest : public ::testing::Test { - public: - TestFileManager fileManager_; - - // TODO This will be more elegant (and run faster) when we - // refactor the output routines to write to a stream - // interface, which can already be handled in-memory when - // running tests. - std::string logFilename_; - FILE *log_; - unique_cptr logFileGuard_; - - TestReferenceData refData_; - TestReferenceChecker checker_; - - PrEbinTest() : - logFilename_(fileManager_.getTemporaryFilePath(".log")), - log_(std::fopen(logFilename_.c_str(), "w")), logFileGuard_(log_), - checker_(refData_.rootChecker()) - { - } +public: + TestFileManager fileManager_; + + // TODO This will be more elegant (and run faster) when we + // refactor the output routines to write to a stream + // interface, which can already be handled in-memory when + // running tests. + std::string logFilename_; + FILE* log_; + unique_cptr logFileGuard_; + + TestReferenceData refData_; + TestReferenceChecker checker_; + + PrEbinTest() : + logFilename_(fileManager_.getTemporaryFilePath(".log")), + log_(std::fopen(logFilename_.c_str(), "w")), + logFileGuard_(log_), + checker_(refData_.rootChecker()) + { + } }; TEST_F(PrEbinTest, HandlesAverages) { ASSERT_NE(log_, nullptr); - t_ebin *ebin = mk_ebin(); + t_ebin* ebin = mk_ebin(); unique_cptr ebinGuard(ebin); // Set up the energy entries - const char *firstName[] = {"first"}; - const char *secondName[] = {"second"}; - int first = get_ebin_space(ebin, 1, firstName, nullptr); - int second = get_ebin_space(ebin, 1, secondName, nullptr); + const char* firstName[] = { "first" }; + const char* secondName[] = { "second" }; + int first = get_ebin_space(ebin, 1, firstName, nullptr); + int second = get_ebin_space(ebin, 1, secondName, nullptr); // Put some data into the energy entries - const real timevalues[2][2] = { { 1.0, 20.0}, {2.0, 40.0} }; - gmx_bool bSum = true; - for (const auto &values : timevalues) + const real timevalues[2][2] = { { 1.0, 20.0 }, { 2.0, 40.0 } }; + gmx_bool bSum = true; + for (const auto& values : timevalues) { add_ebin(ebin, first, 1, &values[0], bSum); add_ebin(ebin, second, 1, &values[1], bSum); @@ -121,12 +122,12 @@ TEST_F(PrEbinTest, HandlesEmptyAverages) { ASSERT_NE(log_, nullptr); - t_ebin *ebin = mk_ebin(); + t_ebin* ebin = mk_ebin(); unique_cptr ebinGuard(ebin); // Set up the energy entries - const char *firstName[] = {"first"}; - const char *secondName[] = {"second"}; + const char* firstName[] = { "first" }; + const char* secondName[] = { "second" }; get_ebin_space(ebin, 1, firstName, nullptr); get_ebin_space(ebin, 1, secondName, nullptr); @@ -140,6 +141,6 @@ TEST_F(PrEbinTest, HandlesEmptyAverages) checker_.checkString(TextReader::readFileToString(logFilename_), "log"); } -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/energyoutput.cpp b/src/gromacs/mdlib/tests/energyoutput.cpp index 6ae860c0b1..32f3993dd9 100644 --- a/src/gromacs/mdlib/tests/energyoutput.cpp +++ b/src/gromacs/mdlib/tests/energyoutput.cpp @@ -85,7 +85,7 @@ namespace { //! Wraps fclose to discard the return value to use it as a deleter with gmx::unique_cptr. -void fcloseWrapper(FILE *fp) +void fcloseWrapper(FILE* fp) { fclose(fp); } @@ -97,13 +97,13 @@ void fcloseWrapper(FILE *fp) struct EnergyOutputTestParameters { //! Thermostat (enum) - int temperatureCouplingScheme; + int temperatureCouplingScheme; //! Barostat (enum) - int pressureCouplingScheme; + int pressureCouplingScheme; //! Integrator - int integrator; + int integrator; //! Number of saved energy frames (to test averages output). - int numFrames; + int numFrames; //! If output should be initialized as a rerun. bool isRerun; //! Is box triclinic (off-diagonal elements will be printed). @@ -112,20 +112,20 @@ struct EnergyOutputTestParameters /*! \brief Sets of parameters on which to run the tests. * - * Only several combinations of the parameters are used. Using all possible combinations will require ~10 MB of - * test data and ~2 sec to run the tests. + * Only several combinations of the parameters are used. Using all possible combinations will + * require ~10 MB of test data and ~2 sec to run the tests. */ -const EnergyOutputTestParameters parametersSets[] = {{etcNO, epcNO, eiMD, 1, false, false}, - {etcNO, epcNO, eiMD, 1, true, false}, - {etcNO, epcNO, eiMD, 1, false, true}, - {etcNO, epcNO, eiMD, 0, false, false}, - {etcNO, epcNO, eiMD, 10, false, false}, - {etcVRESCALE, epcNO, eiMD, 1, false, false}, - {etcNOSEHOOVER, epcNO, eiMD, 1, false, false}, - {etcNO, epcPARRINELLORAHMAN, eiMD, 1, false, false}, - {etcNO, epcMTTK, eiMD, 1, false, false}, - {etcNO, epcNO, eiVV, 1, false, false}, - {etcNO, epcMTTK, eiVV, 1, false, false}}; +const EnergyOutputTestParameters parametersSets[] = { { etcNO, epcNO, eiMD, 1, false, false }, + { etcNO, epcNO, eiMD, 1, true, false }, + { etcNO, epcNO, eiMD, 1, false, true }, + { etcNO, epcNO, eiMD, 0, false, false }, + { etcNO, epcNO, eiMD, 10, false, false }, + { etcVRESCALE, epcNO, eiMD, 1, false, false }, + { etcNOSEHOOVER, epcNO, eiMD, 1, false, false }, + { etcNO, epcPARRINELLORAHMAN, eiMD, 1, false, false }, + { etcNO, epcMTTK, eiMD, 1, false, false }, + { etcNO, epcNO, eiVV, 1, false, false }, + { etcNO, epcMTTK, eiVV, 1, false, false } }; /*! \brief Test fixture to test energy output. * @@ -135,475 +135,483 @@ const EnergyOutputTestParameters parametersSets[] = {{etcNO, epcNO, */ class EnergyOutputTest : public ::testing::TestWithParam { - public: - //! File manager - TestFileManager fileManager_; - //! Energy (.edr) file - ener_file_t energyFile_; - //! Input data - t_inputrec inputrec_; - //! Topology - gmx_mtop_t mtop_; - //! MD atoms - t_mdatoms mdatoms_; - //! Simulation time - double time_; - //! Total mass - real tmass_; - //! Potential energy data - std::unique_ptr enerdata_; - //! Kinetic energy data (for temperatures output) - gmx_ekindata_t ekindata_; - //! System state - t_state state_; - //! PBC box - matrix box_; - //! Virial from constraints - tensor constraintsVirial_; - //! Virial from force computation - tensor forceVirial_; - //! Total virial - tensor totalVirial_; - //! Pressure - tensor pressure_; - //! Names for the groups. - std::vector groupNameStrings_ = { "Protein", "Water", "Lipid" }; - //! Names for the groups as C strings. - std::vector < std::vector < char>> groupNameCStrings_; - //! Handles to the names as C strings in the way needed for SimulationGroups. - std::vector groupNameHandles_; - //! Total dipole momentum - rvec muTotal_; - //! Distance and orientation restraints data - t_fcdata fcd_; - //! Communication record - t_commrec cr_; - //! Constraints object (for constraints RMSD output in case of LINCS) - std::unique_ptr constraints_; - //! Temporary output filename - std::string logFilename_; - //! Temporary energy output filename - std::string edrFilename_; - //! Pointer to a temporary output file - FILE *log_; - //! Log file wrapper - unique_cptr logFileGuard_; - //! Reference data - TestReferenceData refData_; - //! Checker for reference data - TestReferenceChecker checker_; - - EnergyOutputTest() : - logFilename_(fileManager_.getTemporaryFilePath(".log")), - edrFilename_(fileManager_.getTemporaryFilePath(".edr")), - log_(std::fopen(logFilename_.c_str(), "w")), - logFileGuard_(log_), - checker_(refData_.rootChecker()) +public: + //! File manager + TestFileManager fileManager_; + //! Energy (.edr) file + ener_file_t energyFile_; + //! Input data + t_inputrec inputrec_; + //! Topology + gmx_mtop_t mtop_; + //! MD atoms + t_mdatoms mdatoms_; + //! Simulation time + double time_; + //! Total mass + real tmass_; + //! Potential energy data + std::unique_ptr enerdata_; + //! Kinetic energy data (for temperatures output) + gmx_ekindata_t ekindata_; + //! System state + t_state state_; + //! PBC box + matrix box_; + //! Virial from constraints + tensor constraintsVirial_; + //! Virial from force computation + tensor forceVirial_; + //! Total virial + tensor totalVirial_; + //! Pressure + tensor pressure_; + //! Names for the groups. + std::vector groupNameStrings_ = { "Protein", "Water", "Lipid" }; + //! Names for the groups as C strings. + std::vector> groupNameCStrings_; + //! Handles to the names as C strings in the way needed for SimulationGroups. + std::vector groupNameHandles_; + //! Total dipole momentum + rvec muTotal_; + //! Distance and orientation restraints data + t_fcdata fcd_; + //! Communication record + t_commrec cr_; + //! Constraints object (for constraints RMSD output in case of LINCS) + std::unique_ptr constraints_; + //! Temporary output filename + std::string logFilename_; + //! Temporary energy output filename + std::string edrFilename_; + //! Pointer to a temporary output file + FILE* log_; + //! Log file wrapper + unique_cptr logFileGuard_; + //! Reference data + TestReferenceData refData_; + //! Checker for reference data + TestReferenceChecker checker_; + + EnergyOutputTest() : + logFilename_(fileManager_.getTemporaryFilePath(".log")), + edrFilename_(fileManager_.getTemporaryFilePath(".edr")), + log_(std::fopen(logFilename_.c_str(), "w")), + logFileGuard_(log_), + checker_(refData_.rootChecker()) + { + // Input record + inputrec_.delta_t = 0.001; + + // F_EQM + inputrec_.bQMMM = true; + // F_RF_EXCL will not be tested - group scheme is not supported any more + inputrec_.cutoff_scheme = ecutsVERLET; + // F_COUL_RECIP + inputrec_.coulombtype = eelPME; + // F_LJ_RECIP + inputrec_.vdwtype = evdwPME; + + // F_DVDL_COUL, F_DVDL_VDW, F_DVDL_BONDED, F_DVDL_RESTRAINT, F_DKDL and F_DVDL + inputrec_.efep = efepYES; + inputrec_.fepvals->separate_dvdl[efptCOUL] = true; + inputrec_.fepvals->separate_dvdl[efptVDW] = true; + inputrec_.fepvals->separate_dvdl[efptBONDED] = true; + inputrec_.fepvals->separate_dvdl[efptRESTRAINT] = true; + inputrec_.fepvals->separate_dvdl[efptMASS] = true; + inputrec_.fepvals->separate_dvdl[efptCOUL] = true; + inputrec_.fepvals->separate_dvdl[efptFEP] = true; + + // F_DISPCORR and F_PDISPCORR + inputrec_.eDispCorr = edispcEner; + inputrec_.bRot = true; + + // F_ECONSERVED + inputrec_.ref_p[YY][XX] = 0.0; + inputrec_.ref_p[ZZ][XX] = 0.0; + inputrec_.ref_p[ZZ][YY] = 0.0; + + // Dipole (mu) + inputrec_.ewald_geometry = eewg3DC; + + // GMX_CONSTRAINTVIR environment variable should also be + // set to print constraints and force virials separately. + gmxSetenv("GMX_CONSTRAINTVIR", "true", 1); + // To print constrain RMSD, constraints algorithm should be set to LINCS. + inputrec_.eConstrAlg = econtLINCS; + + mtop_.bIntermolecularInteractions = false; + + // Constructing molecular topology + gmx_moltype_t molType; + + molType.atoms.nr = 2; + + // F_CONSTR + // This must be initialized so that Constraints object can be created below. + InteractionList interactionListConstr; + interactionListConstr.iatoms.resize(NRAL(F_CONSTR) + 1); + interactionListConstr.iatoms[0] = 0; + interactionListConstr.iatoms[1] = 0; + interactionListConstr.iatoms[2] = 1; + molType.ilist.at(F_CONSTR) = interactionListConstr; + + InteractionList interactionListEmpty; + interactionListEmpty.iatoms.resize(0); + molType.ilist.at(F_CONSTRNC) = interactionListEmpty; + molType.ilist.at(F_SETTLE) = interactionListEmpty; + + // F_LJ14 and F_COUL14 + InteractionList interactionListLJ14; + interactionListLJ14.iatoms.resize(NRAL(F_LJ14) + 1); + molType.ilist.at(F_LJ14) = interactionListLJ14; + + // F_LJC14_Q + InteractionList interactionListLJC14Q; + interactionListLJC14Q.iatoms.resize(NRAL(F_LJC14_Q) + 1); + molType.ilist.at(F_LJC14_Q) = interactionListLJC14Q; + + // TODO Do proper initialization for distance and orientation + // restraints and remove comments to enable their output + // F_DISRES + // InteractionList interactionListDISRES; + // interactionListDISRES.iatoms.resize(NRAL(F_DISRES) + 1); + // molType.ilist.at(F_DISRES) = interactionListDISRES; + // + // F_ORIRES + // InteractionList interactionListORIRES; + // interactionListORIRES.iatoms.resize(NRAL(F_ORIRES) + 1); + // molType.ilist.at(F_ORIRES) = interactionListORIRES; + + mtop_.moltype.push_back(molType); + + gmx_molblock_t molBlock; + molBlock.type = 0; + molBlock.nmol = 1; + mtop_.molblock.push_back(molBlock); + + // This is to keep constraints initialization happy + mtop_.natoms = 2; + mtop_.ffparams.iparams.resize(F_NRE); + mtop_.ffparams.functype.resize(F_NRE); + mtop_.ffparams.iparams.at(F_CONSTR).constr.dA = 1.0; + mtop_.ffparams.iparams.at(F_CONSTR).constr.dB = 1.0; + mtop_.ffparams.iparams.at(F_CONSTRNC).constr.dA = 1.0; + mtop_.ffparams.iparams.at(F_CONSTRNC).constr.dB = 1.0; + + // Groups for energy output, temperature coupling and acceleration + for (const auto& string : groupNameStrings_) { - // Input record - inputrec_.delta_t = 0.001; - - // F_EQM - inputrec_.bQMMM = true; - // F_RF_EXCL will not be tested - group scheme is not supported any more - inputrec_.cutoff_scheme = ecutsVERLET; - // F_COUL_RECIP - inputrec_.coulombtype = eelPME; - // F_LJ_RECIP - inputrec_.vdwtype = evdwPME; - - // F_DVDL_COUL, F_DVDL_VDW, F_DVDL_BONDED, F_DVDL_RESTRAINT, F_DKDL and F_DVDL - inputrec_.efep = efepYES; - inputrec_.fepvals->separate_dvdl[efptCOUL] = true; - inputrec_.fepvals->separate_dvdl[efptVDW] = true; - inputrec_.fepvals->separate_dvdl[efptBONDED] = true; - inputrec_.fepvals->separate_dvdl[efptRESTRAINT] = true; - inputrec_.fepvals->separate_dvdl[efptMASS] = true; - inputrec_.fepvals->separate_dvdl[efptCOUL] = true; - inputrec_.fepvals->separate_dvdl[efptFEP] = true; - - // F_DISPCORR and F_PDISPCORR - inputrec_.eDispCorr = edispcEner; - inputrec_.bRot = true; - - // F_ECONSERVED - inputrec_.ref_p[YY][XX] = 0.0; - inputrec_.ref_p[ZZ][XX] = 0.0; - inputrec_.ref_p[ZZ][YY] = 0.0; - - // Dipole (mu) - inputrec_.ewald_geometry = eewg3DC; - - // GMX_CONSTRAINTVIR environment variable should also be - // set to print constraints and force virials separately. - gmxSetenv("GMX_CONSTRAINTVIR", "true", 1); - // To print constrain RMSD, constraints algorithm should be set to LINCS. - inputrec_.eConstrAlg = econtLINCS; - - mtop_.bIntermolecularInteractions = false; - - // Constructing molecular topology - gmx_moltype_t molType; - - molType.atoms.nr = 2; - - // F_CONSTR - // This must be initialized so that Constraints object can be created below. - InteractionList interactionListConstr; - interactionListConstr.iatoms.resize(NRAL(F_CONSTR) + 1); - interactionListConstr.iatoms[0] = 0; - interactionListConstr.iatoms[1] = 0; - interactionListConstr.iatoms[2] = 1; - molType.ilist.at(F_CONSTR) = interactionListConstr; - - InteractionList interactionListEmpty; - interactionListEmpty.iatoms.resize(0); - molType.ilist.at(F_CONSTRNC) = interactionListEmpty; - molType.ilist.at(F_SETTLE) = interactionListEmpty; - - // F_LJ14 and F_COUL14 - InteractionList interactionListLJ14; - interactionListLJ14.iatoms.resize(NRAL(F_LJ14) + 1); - molType.ilist.at(F_LJ14) = interactionListLJ14; - - // F_LJC14_Q - InteractionList interactionListLJC14Q; - interactionListLJC14Q.iatoms.resize(NRAL(F_LJC14_Q) + 1); - molType.ilist.at(F_LJC14_Q) = interactionListLJC14Q; - - // TODO Do proper initialization for distance and orientation - // restraints and remove comments to enable their output - // F_DISRES - //InteractionList interactionListDISRES; - //interactionListDISRES.iatoms.resize(NRAL(F_DISRES) + 1); - //molType.ilist.at(F_DISRES) = interactionListDISRES; - // - // F_ORIRES - //InteractionList interactionListORIRES; - //interactionListORIRES.iatoms.resize(NRAL(F_ORIRES) + 1); - //molType.ilist.at(F_ORIRES) = interactionListORIRES; - - mtop_.moltype.push_back(molType); - - gmx_molblock_t molBlock; - molBlock.type = 0; - molBlock.nmol = 1; - mtop_.molblock.push_back(molBlock); - - // This is to keep constraints initialization happy - mtop_.natoms = 2; - mtop_.ffparams.iparams.resize(F_NRE); - mtop_.ffparams.functype.resize(F_NRE); - mtop_.ffparams.iparams.at(F_CONSTR).constr.dA = 1.0; - mtop_.ffparams.iparams.at(F_CONSTR).constr.dB = 1.0; - mtop_.ffparams.iparams.at(F_CONSTRNC).constr.dA = 1.0; - mtop_.ffparams.iparams.at(F_CONSTRNC).constr.dB = 1.0; - - // Groups for energy output, temperature coupling and acceleration - for (const auto &string : groupNameStrings_) - { - std::vector cString(string.begin(), string.end()); - // Need to add null termination - cString.push_back('\0'); - groupNameCStrings_.emplace_back(cString); - groupNameHandles_.emplace_back(groupNameCStrings_.back().data()); - } - for (auto &handle : groupNameHandles_) - { - mtop_.groups.groupNames.emplace_back(&handle); - } - - mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].resize(3); - mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][0] = 0; - mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][1] = 1; - mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][2] = 2; - - mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].resize(3); - mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][0] = 0; - mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][1] = 1; - mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][2] = 2; - - mtop_.groups.groups[SimulationAtomGroupType::Acceleration].resize(2); - mtop_.groups.groups[SimulationAtomGroupType::Acceleration][0] = 0; - mtop_.groups.groups[SimulationAtomGroupType::Acceleration][1] = 2; - - // Nose-Hoover chains - inputrec_.bPrintNHChains = true; - inputrec_.opts.nhchainlength = 2; - state_.nosehoover_xi.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()*inputrec_.opts.nhchainlength); - state_.nosehoover_vxi.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()*inputrec_.opts.nhchainlength); - - // This will be needed only with MTTK barostat - state_.nhpres_xi.resize(1*inputrec_.opts.nhchainlength); - state_.nhpres_vxi.resize(1*inputrec_.opts.nhchainlength); - - // Group pairs - enerdata_ = std::make_unique(mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].size(), 0); - - // Kinetic energy and related data - ekindata_.tcstat.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()); - ekindata_.grpstat.resize(mtop_.groups.groups[SimulationAtomGroupType::Acceleration].size()); - - // This is needed so that the ebin space will be allocated - inputrec_.cos_accel = 1.0; - // This is to keep the destructor happy (otherwise sfree() segfaults) - ekindata_.nthreads = 0; - snew(ekindata_.ekin_work_alloc, 1); - snew(ekindata_.ekin_work, 1); - snew(ekindata_.dekindl_work, 1); - - // Group options for annealing output - inputrec_.opts.ngtc = 3; - snew(inputrec_.opts.ref_t, inputrec_.opts.ngtc); - snew(inputrec_.opts.annealing, inputrec_.opts.ngtc); - inputrec_.opts.annealing[0] = eannNO; - inputrec_.opts.annealing[1] = eannSINGLE; - inputrec_.opts.annealing[2] = eannPERIODIC; - - // This is to keep done_inputrec happy (otherwise sfree() segfaults) - snew(inputrec_.opts.anneal_time, inputrec_.opts.ngtc); - snew(inputrec_.opts.anneal_temp, inputrec_.opts.ngtc); - - // Communication record (for Constraints constructor) - cr_.nnodes = 1; - cr_.dd = nullptr; - - // Constraints object (to get constraints RMSD from) - // TODO EnergyOutput should not take Constraints object - // TODO This object will always return zero as RMSD value. - // It is more relevant to have non-zero value for testing. - constraints_ = makeConstraints(mtop_, inputrec_, nullptr, false, nullptr, mdatoms_, &cr_, - nullptr, nullptr, nullptr, false); - - // No position/orientation restraints - fcd_.disres.npair = 0; - fcd_.orires.nr = 0; - + std::vector cString(string.begin(), string.end()); + // Need to add null termination + cString.push_back('\0'); + groupNameCStrings_.emplace_back(cString); + groupNameHandles_.emplace_back(groupNameCStrings_.back().data()); } - - /*! \brief Helper function to generate synthetic data to output - * - * \param[in,out] testValue Base value fr energy data. - */ - void setStepData(double *testValue) + for (auto& handle : groupNameHandles_) { + mtop_.groups.groupNames.emplace_back(&handle); + } - time_ = (*testValue += 0.1); - tmass_ = (*testValue += 0.1); - - enerdata_->term[F_LJ] = (*testValue += 0.1); - enerdata_->term[F_COUL_SR] = (*testValue += 0.1); - enerdata_->term[F_EPOT] = (*testValue += 0.1); - enerdata_->term[F_EKIN] = (*testValue += 0.1); - enerdata_->term[F_ETOT] = (*testValue += 0.1); - enerdata_->term[F_TEMP] = (*testValue += 0.1); - enerdata_->term[F_PRES] = (*testValue += 0.1); - - enerdata_->term[F_BHAM] = (*testValue += 0.1); - enerdata_->term[F_EQM] = (*testValue += 0.1); - enerdata_->term[F_RF_EXCL] = (*testValue += 0.1); - enerdata_->term[F_COUL_RECIP] = (*testValue += 0.1); - enerdata_->term[F_LJ_RECIP] = (*testValue += 0.1); - enerdata_->term[F_LJ14] = (*testValue += 0.1); - enerdata_->term[F_COUL14] = (*testValue += 0.1); - enerdata_->term[F_LJC14_Q] = (*testValue += 0.1); - enerdata_->term[F_LJC_PAIRS_NB] = (*testValue += 0.1); - - enerdata_->term[F_DVDL_COUL] = (*testValue += 0.1); - enerdata_->term[F_DVDL_VDW] = (*testValue += 0.1); - enerdata_->term[F_DVDL_BONDED] = (*testValue += 0.1); - enerdata_->term[F_DVDL_RESTRAINT] = (*testValue += 0.1); - enerdata_->term[F_DKDL] = (*testValue += 0.1); - enerdata_->term[F_DVDL] = (*testValue += 0.1); - - enerdata_->term[F_DISPCORR] = (*testValue += 0.1); - enerdata_->term[F_PDISPCORR] = (*testValue += 0.1); - enerdata_->term[F_DISRESVIOL] = (*testValue += 0.1); - enerdata_->term[F_ORIRESDEV] = (*testValue += 0.1); - enerdata_->term[F_COM_PULL] = (*testValue += 0.1); - enerdata_->term[F_ECONSERVED] = (*testValue += 0.1); - - // Group pairs - for (int i = 0; i < enerdata_->grpp.nener; i++) - { - for (int k = 0; k < egNR; k++) - { - enerdata_->grpp.ener[k][i] = (*testValue += 0.1); - } - } + mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].resize(3); + mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][0] = 0; + mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][1] = 1; + mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput][2] = 2; + + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].resize(3); + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][0] = 0; + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][1] = 1; + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling][2] = 2; + + mtop_.groups.groups[SimulationAtomGroupType::Acceleration].resize(2); + mtop_.groups.groups[SimulationAtomGroupType::Acceleration][0] = 0; + mtop_.groups.groups[SimulationAtomGroupType::Acceleration][1] = 2; + + // Nose-Hoover chains + inputrec_.bPrintNHChains = true; + inputrec_.opts.nhchainlength = 2; + state_.nosehoover_xi.resize( + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size() + * inputrec_.opts.nhchainlength); + state_.nosehoover_vxi.resize( + mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size() + * inputrec_.opts.nhchainlength); + + // This will be needed only with MTTK barostat + state_.nhpres_xi.resize(1 * inputrec_.opts.nhchainlength); + state_.nhpres_vxi.resize(1 * inputrec_.opts.nhchainlength); + + // Group pairs + enerdata_ = std::make_unique( + mtop_.groups.groups[SimulationAtomGroupType::EnergyOutput].size(), 0); + + // Kinetic energy and related data + ekindata_.tcstat.resize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling].size()); + ekindata_.grpstat.resize(mtop_.groups.groups[SimulationAtomGroupType::Acceleration].size()); + + // This is needed so that the ebin space will be allocated + inputrec_.cos_accel = 1.0; + // This is to keep the destructor happy (otherwise sfree() segfaults) + ekindata_.nthreads = 0; + snew(ekindata_.ekin_work_alloc, 1); + snew(ekindata_.ekin_work, 1); + snew(ekindata_.dekindl_work, 1); + + // Group options for annealing output + inputrec_.opts.ngtc = 3; + snew(inputrec_.opts.ref_t, inputrec_.opts.ngtc); + snew(inputrec_.opts.annealing, inputrec_.opts.ngtc); + inputrec_.opts.annealing[0] = eannNO; + inputrec_.opts.annealing[1] = eannSINGLE; + inputrec_.opts.annealing[2] = eannPERIODIC; + + // This is to keep done_inputrec happy (otherwise sfree() segfaults) + snew(inputrec_.opts.anneal_time, inputrec_.opts.ngtc); + snew(inputrec_.opts.anneal_temp, inputrec_.opts.ngtc); + + // Communication record (for Constraints constructor) + cr_.nnodes = 1; + cr_.dd = nullptr; + + // Constraints object (to get constraints RMSD from) + // TODO EnergyOutput should not take Constraints object + // TODO This object will always return zero as RMSD value. + // It is more relevant to have non-zero value for testing. + constraints_ = makeConstraints(mtop_, inputrec_, nullptr, false, nullptr, mdatoms_, &cr_, + nullptr, nullptr, nullptr, false); + + // No position/orientation restraints + fcd_.disres.npair = 0; + fcd_.orires.nr = 0; + } - // Kinetic energy and related data - for (auto &tcstat : ekindata_.tcstat) - { - tcstat.T = (*testValue += 0.1); - tcstat.lambda = (*testValue += 0.1); - } - for (auto &grpstat : ekindata_.grpstat) - { - grpstat.u[XX] = (*testValue += 0.1); - grpstat.u[YY] = (*testValue += 0.1); - grpstat.u[ZZ] = (*testValue += 0.1); - } + /*! \brief Helper function to generate synthetic data to output + * + * \param[in,out] testValue Base value fr energy data. + */ + void setStepData(double* testValue) + { - // This conditional is to check whether the ebin was allocated. - // Otherwise it will print cosacc data into the first bin. - if (inputrec_.cos_accel != 0) + time_ = (*testValue += 0.1); + tmass_ = (*testValue += 0.1); + + enerdata_->term[F_LJ] = (*testValue += 0.1); + enerdata_->term[F_COUL_SR] = (*testValue += 0.1); + enerdata_->term[F_EPOT] = (*testValue += 0.1); + enerdata_->term[F_EKIN] = (*testValue += 0.1); + enerdata_->term[F_ETOT] = (*testValue += 0.1); + enerdata_->term[F_TEMP] = (*testValue += 0.1); + enerdata_->term[F_PRES] = (*testValue += 0.1); + + enerdata_->term[F_BHAM] = (*testValue += 0.1); + enerdata_->term[F_EQM] = (*testValue += 0.1); + enerdata_->term[F_RF_EXCL] = (*testValue += 0.1); + enerdata_->term[F_COUL_RECIP] = (*testValue += 0.1); + enerdata_->term[F_LJ_RECIP] = (*testValue += 0.1); + enerdata_->term[F_LJ14] = (*testValue += 0.1); + enerdata_->term[F_COUL14] = (*testValue += 0.1); + enerdata_->term[F_LJC14_Q] = (*testValue += 0.1); + enerdata_->term[F_LJC_PAIRS_NB] = (*testValue += 0.1); + + enerdata_->term[F_DVDL_COUL] = (*testValue += 0.1); + enerdata_->term[F_DVDL_VDW] = (*testValue += 0.1); + enerdata_->term[F_DVDL_BONDED] = (*testValue += 0.1); + enerdata_->term[F_DVDL_RESTRAINT] = (*testValue += 0.1); + enerdata_->term[F_DKDL] = (*testValue += 0.1); + enerdata_->term[F_DVDL] = (*testValue += 0.1); + + enerdata_->term[F_DISPCORR] = (*testValue += 0.1); + enerdata_->term[F_PDISPCORR] = (*testValue += 0.1); + enerdata_->term[F_DISRESVIOL] = (*testValue += 0.1); + enerdata_->term[F_ORIRESDEV] = (*testValue += 0.1); + enerdata_->term[F_COM_PULL] = (*testValue += 0.1); + enerdata_->term[F_ECONSERVED] = (*testValue += 0.1); + + // Group pairs + for (int i = 0; i < enerdata_->grpp.nener; i++) + { + for (int k = 0; k < egNR; k++) { - ekindata_.cosacc.cos_accel = (*testValue += 0.1); - ekindata_.cosacc.vcos = (*testValue += 0.1); + enerdata_->grpp.ener[k][i] = (*testValue += 0.1); } + } - state_.box[XX][XX] = (*testValue += 0.1); - state_.box[XX][YY] = (*testValue += 0.1); - state_.box[XX][ZZ] = (*testValue += 0.1); - state_.box[YY][XX] = (*testValue += 0.1); - state_.box[YY][YY] = (*testValue += 0.1); - state_.box[YY][ZZ] = (*testValue += 0.1); - state_.box[ZZ][XX] = (*testValue += 0.1); - state_.box[ZZ][YY] = (*testValue += 0.1); - state_.box[ZZ][ZZ] = (*testValue += 0.1); - - box_[XX][XX] = (*testValue += 0.1); - box_[XX][YY] = (*testValue += 0.1); - box_[XX][ZZ] = (*testValue += 0.1); - box_[YY][XX] = (*testValue += 0.1); - box_[YY][YY] = (*testValue += 0.1); - box_[YY][ZZ] = (*testValue += 0.1); - box_[ZZ][XX] = (*testValue += 0.1); - box_[ZZ][YY] = (*testValue += 0.1); - box_[ZZ][ZZ] = (*testValue += 0.1); - - constraintsVirial_[XX][XX] = (*testValue += 0.1); - constraintsVirial_[XX][YY] = (*testValue += 0.1); - constraintsVirial_[XX][ZZ] = (*testValue += 0.1); - constraintsVirial_[YY][XX] = (*testValue += 0.1); - constraintsVirial_[YY][YY] = (*testValue += 0.1); - constraintsVirial_[YY][ZZ] = (*testValue += 0.1); - constraintsVirial_[ZZ][XX] = (*testValue += 0.1); - constraintsVirial_[ZZ][YY] = (*testValue += 0.1); - constraintsVirial_[ZZ][ZZ] = (*testValue += 0.1); - - forceVirial_[XX][XX] = (*testValue += 0.1); - forceVirial_[XX][YY] = (*testValue += 0.1); - forceVirial_[XX][ZZ] = (*testValue += 0.1); - forceVirial_[YY][XX] = (*testValue += 0.1); - forceVirial_[YY][YY] = (*testValue += 0.1); - forceVirial_[YY][ZZ] = (*testValue += 0.1); - forceVirial_[ZZ][XX] = (*testValue += 0.1); - forceVirial_[ZZ][YY] = (*testValue += 0.1); - forceVirial_[ZZ][ZZ] = (*testValue += 0.1); - - totalVirial_[XX][XX] = (*testValue += 0.1); - totalVirial_[XX][YY] = (*testValue += 0.1); - totalVirial_[XX][ZZ] = (*testValue += 0.1); - totalVirial_[YY][XX] = (*testValue += 0.1); - totalVirial_[YY][YY] = (*testValue += 0.1); - totalVirial_[YY][ZZ] = (*testValue += 0.1); - totalVirial_[ZZ][XX] = (*testValue += 0.1); - totalVirial_[ZZ][YY] = (*testValue += 0.1); - totalVirial_[ZZ][ZZ] = (*testValue += 0.1); - - pressure_[XX][XX] = (*testValue += 0.1); - pressure_[XX][YY] = (*testValue += 0.1); - pressure_[XX][ZZ] = (*testValue += 0.1); - pressure_[YY][XX] = (*testValue += 0.1); - pressure_[YY][YY] = (*testValue += 0.1); - pressure_[YY][ZZ] = (*testValue += 0.1); - pressure_[ZZ][XX] = (*testValue += 0.1); - pressure_[ZZ][YY] = (*testValue += 0.1); - pressure_[ZZ][ZZ] = (*testValue += 0.1); - - muTotal_[XX] = (*testValue += 0.1); - muTotal_[YY] = (*testValue += 0.1); - muTotal_[ZZ] = (*testValue += 0.1); - - state_.boxv[XX][XX] = (*testValue += 0.1); - state_.boxv[XX][YY] = (*testValue += 0.1); - state_.boxv[XX][ZZ] = (*testValue += 0.1); - state_.boxv[YY][XX] = (*testValue += 0.1); - state_.boxv[YY][YY] = (*testValue += 0.1); - state_.boxv[YY][ZZ] = (*testValue += 0.1); - state_.boxv[ZZ][XX] = (*testValue += 0.1); - state_.boxv[ZZ][YY] = (*testValue += 0.1); - state_.boxv[ZZ][ZZ] = (*testValue += 0.1); - - for (int i = 0; i < inputrec_.opts.ngtc; i++) - { - inputrec_.opts.ref_t[i] = (*testValue += 0.1); - } + // Kinetic energy and related data + for (auto& tcstat : ekindata_.tcstat) + { + tcstat.T = (*testValue += 0.1); + tcstat.lambda = (*testValue += 0.1); + } + for (auto& grpstat : ekindata_.grpstat) + { + grpstat.u[XX] = (*testValue += 0.1); + grpstat.u[YY] = (*testValue += 0.1); + grpstat.u[ZZ] = (*testValue += 0.1); + } - for (index k = 0; k < ssize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling])*inputrec_.opts.nhchainlength; k++) - { - state_.nosehoover_xi[k] = (*testValue += 0.1); - state_.nosehoover_vxi[k] = (*testValue += 0.1); - } - for (int k = 0; k < inputrec_.opts.nhchainlength; k++) - { - state_.nhpres_xi[k] = (*testValue += 0.1); - state_.nhpres_vxi[k] = (*testValue += 0.1); - } + // This conditional is to check whether the ebin was allocated. + // Otherwise it will print cosacc data into the first bin. + if (inputrec_.cos_accel != 0) + { + ekindata_.cosacc.cos_accel = (*testValue += 0.1); + ekindata_.cosacc.vcos = (*testValue += 0.1); } - /*! \brief Check if the contents of the .edr file correspond to the reference data. - * - * The code below is based on the 'gmx dump' tool. - * - * \param[in] fileName Name of the file to check. - * \param[in] frameCount Number of frames to check. - */ - void checkEdrFile(const char *fileName, int frameCount) + state_.box[XX][XX] = (*testValue += 0.1); + state_.box[XX][YY] = (*testValue += 0.1); + state_.box[XX][ZZ] = (*testValue += 0.1); + state_.box[YY][XX] = (*testValue += 0.1); + state_.box[YY][YY] = (*testValue += 0.1); + state_.box[YY][ZZ] = (*testValue += 0.1); + state_.box[ZZ][XX] = (*testValue += 0.1); + state_.box[ZZ][YY] = (*testValue += 0.1); + state_.box[ZZ][ZZ] = (*testValue += 0.1); + + box_[XX][XX] = (*testValue += 0.1); + box_[XX][YY] = (*testValue += 0.1); + box_[XX][ZZ] = (*testValue += 0.1); + box_[YY][XX] = (*testValue += 0.1); + box_[YY][YY] = (*testValue += 0.1); + box_[YY][ZZ] = (*testValue += 0.1); + box_[ZZ][XX] = (*testValue += 0.1); + box_[ZZ][YY] = (*testValue += 0.1); + box_[ZZ][ZZ] = (*testValue += 0.1); + + constraintsVirial_[XX][XX] = (*testValue += 0.1); + constraintsVirial_[XX][YY] = (*testValue += 0.1); + constraintsVirial_[XX][ZZ] = (*testValue += 0.1); + constraintsVirial_[YY][XX] = (*testValue += 0.1); + constraintsVirial_[YY][YY] = (*testValue += 0.1); + constraintsVirial_[YY][ZZ] = (*testValue += 0.1); + constraintsVirial_[ZZ][XX] = (*testValue += 0.1); + constraintsVirial_[ZZ][YY] = (*testValue += 0.1); + constraintsVirial_[ZZ][ZZ] = (*testValue += 0.1); + + forceVirial_[XX][XX] = (*testValue += 0.1); + forceVirial_[XX][YY] = (*testValue += 0.1); + forceVirial_[XX][ZZ] = (*testValue += 0.1); + forceVirial_[YY][XX] = (*testValue += 0.1); + forceVirial_[YY][YY] = (*testValue += 0.1); + forceVirial_[YY][ZZ] = (*testValue += 0.1); + forceVirial_[ZZ][XX] = (*testValue += 0.1); + forceVirial_[ZZ][YY] = (*testValue += 0.1); + forceVirial_[ZZ][ZZ] = (*testValue += 0.1); + + totalVirial_[XX][XX] = (*testValue += 0.1); + totalVirial_[XX][YY] = (*testValue += 0.1); + totalVirial_[XX][ZZ] = (*testValue += 0.1); + totalVirial_[YY][XX] = (*testValue += 0.1); + totalVirial_[YY][YY] = (*testValue += 0.1); + totalVirial_[YY][ZZ] = (*testValue += 0.1); + totalVirial_[ZZ][XX] = (*testValue += 0.1); + totalVirial_[ZZ][YY] = (*testValue += 0.1); + totalVirial_[ZZ][ZZ] = (*testValue += 0.1); + + pressure_[XX][XX] = (*testValue += 0.1); + pressure_[XX][YY] = (*testValue += 0.1); + pressure_[XX][ZZ] = (*testValue += 0.1); + pressure_[YY][XX] = (*testValue += 0.1); + pressure_[YY][YY] = (*testValue += 0.1); + pressure_[YY][ZZ] = (*testValue += 0.1); + pressure_[ZZ][XX] = (*testValue += 0.1); + pressure_[ZZ][YY] = (*testValue += 0.1); + pressure_[ZZ][ZZ] = (*testValue += 0.1); + + muTotal_[XX] = (*testValue += 0.1); + muTotal_[YY] = (*testValue += 0.1); + muTotal_[ZZ] = (*testValue += 0.1); + + state_.boxv[XX][XX] = (*testValue += 0.1); + state_.boxv[XX][YY] = (*testValue += 0.1); + state_.boxv[XX][ZZ] = (*testValue += 0.1); + state_.boxv[YY][XX] = (*testValue += 0.1); + state_.boxv[YY][YY] = (*testValue += 0.1); + state_.boxv[YY][ZZ] = (*testValue += 0.1); + state_.boxv[ZZ][XX] = (*testValue += 0.1); + state_.boxv[ZZ][YY] = (*testValue += 0.1); + state_.boxv[ZZ][ZZ] = (*testValue += 0.1); + + for (int i = 0; i < inputrec_.opts.ngtc; i++) { - ener_file_t edrFile; - gmx_enxnm_t *energyTermsEdr = nullptr; - int numEnergyTermsEdr; + inputrec_.opts.ref_t[i] = (*testValue += 0.1); + } + + for (index k = 0; k < ssize(mtop_.groups.groups[SimulationAtomGroupType::TemperatureCoupling]) + * inputrec_.opts.nhchainlength; + k++) + { + state_.nosehoover_xi[k] = (*testValue += 0.1); + state_.nosehoover_vxi[k] = (*testValue += 0.1); + } + for (int k = 0; k < inputrec_.opts.nhchainlength; k++) + { + state_.nhpres_xi[k] = (*testValue += 0.1); + state_.nhpres_vxi[k] = (*testValue += 0.1); + } + } - edrFile = open_enx(fileName, "r"); - do_enxnms(edrFile, &numEnergyTermsEdr, &energyTermsEdr); - assert(energyTermsEdr); + /*! \brief Check if the contents of the .edr file correspond to the reference data. + * + * The code below is based on the 'gmx dump' tool. + * + * \param[in] fileName Name of the file to check. + * \param[in] frameCount Number of frames to check. + */ + void checkEdrFile(const char* fileName, int frameCount) + { + ener_file_t edrFile; + gmx_enxnm_t* energyTermsEdr = nullptr; + int numEnergyTermsEdr; + + edrFile = open_enx(fileName, "r"); + do_enxnms(edrFile, &numEnergyTermsEdr, &energyTermsEdr); + assert(energyTermsEdr); + + // Check header + TestReferenceChecker edrFileRef(checker_.checkCompound("File", "EnergyFile")); + TestReferenceChecker energyTermsRef( + edrFileRef.checkSequenceCompound("EnergyTerms", numEnergyTermsEdr)); + for (int i = 0; i < numEnergyTermsEdr; i++) + { + TestReferenceChecker energyTermRef(energyTermsRef.checkCompound("EnergyTerm", nullptr)); + energyTermRef.checkString(energyTermsEdr[i].name, "Name"); + energyTermRef.checkString(energyTermsEdr[i].unit, "Units"); + } - // Check header - TestReferenceChecker edrFileRef(checker_.checkCompound("File", "EnergyFile")); - TestReferenceChecker energyTermsRef(edrFileRef.checkSequenceCompound("EnergyTerms", numEnergyTermsEdr)); + // Check frames + TestReferenceChecker framesRef(edrFileRef.checkSequenceCompound("Frames", frameCount)); + t_enxframe* frameEdr; + snew(frameEdr, 1); + char buffer[22]; + for (int frameId = 0; frameId < frameCount; frameId++) + { + bool bCont = do_enx(edrFile, frameEdr); + EXPECT_TRUE(bCont) << gmx::formatString("Cant read frame %d from .edr file.", frameId); + + TestReferenceChecker frameRef(framesRef.checkCompound("Frame", nullptr)); + frameRef.checkReal(frameEdr->t, "Time"); + frameRef.checkReal(frameEdr->dt, "Timestep"); + frameRef.checkString(gmx_step_str(frameEdr->step, buffer), "Step"); + frameRef.checkString(gmx_step_str(frameEdr->nsum, buffer), "NumSteps"); + + EXPECT_EQ(frameEdr->nre, numEnergyTermsEdr) + << gmx::formatString("Wrong number of energy terms in frame %d.", frameId); + TestReferenceChecker energyValuesRef( + frameRef.checkSequenceCompound("EnergyTerms", numEnergyTermsEdr)); for (int i = 0; i < numEnergyTermsEdr; i++) { - TestReferenceChecker energyTermRef(energyTermsRef.checkCompound("EnergyTerm", nullptr)); - energyTermRef.checkString(energyTermsEdr[i].name, "Name"); - energyTermRef.checkString(energyTermsEdr[i].unit, "Units"); - } - - // Check frames - TestReferenceChecker framesRef(edrFileRef.checkSequenceCompound("Frames", frameCount)); - t_enxframe *frameEdr; - snew(frameEdr, 1); - char buffer[22]; - for (int frameId = 0; frameId < frameCount; frameId++) - { - bool bCont = do_enx(edrFile, frameEdr); - EXPECT_TRUE(bCont) << gmx::formatString("Cant read frame %d from .edr file.", frameId); - - TestReferenceChecker frameRef(framesRef.checkCompound("Frame", nullptr)); - frameRef.checkReal(frameEdr->t, "Time"); - frameRef.checkReal(frameEdr->dt, "Timestep"); - frameRef.checkString(gmx_step_str(frameEdr->step, buffer), "Step"); - frameRef.checkString(gmx_step_str(frameEdr->nsum, buffer), "NumSteps"); - - EXPECT_EQ(frameEdr->nre, numEnergyTermsEdr) << gmx::formatString("Wrong number of energy terms in frame %d.", frameId); - TestReferenceChecker energyValuesRef(frameRef.checkSequenceCompound("EnergyTerms", numEnergyTermsEdr)); - for (int i = 0; i < numEnergyTermsEdr; i++) - { - TestReferenceChecker energyValueRef(energyValuesRef.checkCompound("EnergyTerm", nullptr)); - energyValueRef.checkString(energyTermsEdr[i].name, "Name"); - energyValueRef.checkReal(frameEdr->ener[i].e, "Value"); - } + TestReferenceChecker energyValueRef(energyValuesRef.checkCompound("EnergyTerm", nullptr)); + energyValueRef.checkString(energyTermsEdr[i].name, "Name"); + energyValueRef.checkReal(frameEdr->ener[i].e, "Value"); } - - free_enxnms(numEnergyTermsEdr, energyTermsEdr); - done_ener_file(edrFile); - - free_enxframe(frameEdr); - sfree(frameEdr); } + free_enxnms(numEnergyTermsEdr, energyTermsEdr); + done_ener_file(edrFile); + + free_enxframe(frameEdr); + sfree(frameEdr); + } }; TEST_P(EnergyOutputTest, CheckOutput) @@ -614,32 +622,31 @@ TEST_P(EnergyOutputTest, CheckOutput) ASSERT_NE(energyFile_, nullptr); EnergyOutputTestParameters parameters = GetParam(); - inputrec_.etc = parameters.temperatureCouplingScheme; - inputrec_.epc = parameters.pressureCouplingScheme; - inputrec_.eI = parameters.integrator; + inputrec_.etc = parameters.temperatureCouplingScheme; + inputrec_.epc = parameters.pressureCouplingScheme; + inputrec_.eI = parameters.integrator; if (parameters.isBoxTriclinic) { - inputrec_.ref_p[YY][XX] = 1.0; + inputrec_.ref_p[YY][XX] = 1.0; } MdModulesNotifier mdModulesNotifier; - std::unique_ptr energyOutput = std::make_unique(energyFile_, &mtop_, &inputrec_, nullptr, nullptr, parameters.isRerun, mdModulesNotifier); + std::unique_ptr energyOutput = std::make_unique( + energyFile_, &mtop_, &inputrec_, nullptr, nullptr, parameters.isRerun, mdModulesNotifier); // Add synthetic data for a single step double testValue = 10.0; for (int frame = 0; frame < parameters.numFrames; frame++) { setStepData(&testValue); - energyOutput->addDataAtEnergyStep(false, true, time_, tmass_, enerdata_.get(), - &state_, nullptr, nullptr, box_, - constraintsVirial_, forceVirial_, totalVirial_, pressure_, - &ekindata_, muTotal_, constraints_.get()); + energyOutput->addDataAtEnergyStep(false, true, time_, tmass_, enerdata_.get(), &state_, nullptr, + nullptr, box_, constraintsVirial_, forceVirial_, totalVirial_, + pressure_, &ekindata_, muTotal_, constraints_.get()); energyOutput->printAnnealingTemperatures(log_, &mtop_.groups, &inputrec_.opts); - energyOutput->printStepToEnergyFile(energyFile_, true, false, false, log_, - 100*frame, time_, - nullptr, nullptr); + energyOutput->printStepToEnergyFile(energyFile_, true, false, false, log_, 100 * frame, + time_, nullptr, nullptr); time_ += 1.0; } @@ -665,9 +672,8 @@ TEST_P(EnergyOutputTest, CheckOutput) checker_.checkString(TextReader::readFileToString(logFilename_), "log"); } -INSTANTIATE_TEST_CASE_P(WithParameters, EnergyOutputTest, - ::testing::ValuesIn(parametersSets)); +INSTANTIATE_TEST_CASE_P(WithParameters, EnergyOutputTest, ::testing::ValuesIn(parametersSets)); -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/leapfrog.cpp b/src/gromacs/mdlib/tests/leapfrog.cpp index 593fcd476e..abfe31c3ab 100644 --- a/src/gromacs/mdlib/tests/leapfrog.cpp +++ b/src/gromacs/mdlib/tests/leapfrog.cpp @@ -96,169 +96,164 @@ namespace struct LeapFrogTestParameters { //! Total number of atoms - int numAtoms; + int numAtoms; //! Timestep real timestep; //! Number of integration steps - int numSteps; + int numSteps; //! Initial velocity rvec v; //! Constant force rvec f; //! Number of temperature coupling group (zero for no temperature coupling) - int numTCoupleGroups; + int numTCoupleGroups; //! Number of steps between pressure coupling steps (zero for no pressure coupling). - int nstpcouple; + int nstpcouple; }; //! The set of parameters combinations to run the test on -const LeapFrogTestParameters parametersSets[] = {{ 1, 0.001, 1, {0.0, 0.0, 0.0}, { 0.0, 0.0, 0.0}, 0, 0}, // Zero velocity and force - { 1, 0.001, 1, {0.0, 0.0, 0.0}, {-3.0, 2.0, -1.0}, 0, 0}, // Zero velocity - { 1, 0.001, 1, {1.0, -2.0, 3.0}, { 0.0, 0.0, 0.0}, 0, 0}, // Zero force - { 1, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 1 particle - { 10, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 10 particles - {100, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 100 particles - {300, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 300 particles - { 1, 0.0005, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 0.0005 ps timestep - { 1, 0.001, 10, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 10 step - { 1, 0.001, 100, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 0}, // 100 steps - {100, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 1, 0}, // 1 temperature couple group - {100, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 2, 0}, // 2 temperature couple groups - {100, 0.001, 1, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 10, 0}, // 10 temperature couple groups - {100, 0.001, 10, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 1}, // With pressure coupling - {100, 0.001, 10, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 2, 1}, // With both temperature and pressure coupling - {100, 0.001, 10, {1.0, -2.0, 3.0}, {-3.0, 2.0, -1.0}, 0, 3}}; // Do pressure coupling not on every step - +const LeapFrogTestParameters parametersSets[] = { + { 1, 0.001, 1, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 }, 0, 0 }, // Zero velocity and force + { 1, 0.001, 1, { 0.0, 0.0, 0.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // Zero velocity + { 1, 0.001, 1, { 1.0, -2.0, 3.0 }, { 0.0, 0.0, 0.0 }, 0, 0 }, // Zero force + { 1, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 1 particle + { 10, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 10 particles + { 100, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 100 particles + { 300, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 300 particles + { 1, 0.0005, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 0.0005 ps timestep + { 1, 0.001, 10, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 10 step + { 1, 0.001, 100, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 0 }, // 100 steps + { 100, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 1, 0 }, // 1 temperature couple group + { 100, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 2, 0 }, // 2 temperature couple groups + { 100, 0.001, 1, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 10, 0 }, // 10 temperature couple groups + { 100, 0.001, 10, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 1 }, // With pressure coupling + { 100, 0.001, 10, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 2, 1 }, // With both temperature and pressure coupling + { 100, 0.001, 10, { 1.0, -2.0, 3.0 }, { -3.0, 2.0, -1.0 }, 0, 3 } +}; // Do pressure coupling not on every step /*! \brief Test fixture for LeapFrog integrator. */ class LeapFrogTest : public ::testing::TestWithParam { - public: - //! Availiable runners (CPU and GPU versions of the Leap-Frog) - static std::unordered_map s_runners_; - //! Reference data - TestReferenceData refData_; - //! Checker for reference data - TestReferenceChecker checker_; - - LeapFrogTest() : - checker_(refData_.rootChecker()) +public: + //! Availiable runners (CPU and GPU versions of the Leap-Frog) + static std::unordered_map s_runners_; + //! Reference data + TestReferenceData refData_; + //! Checker for reference data + TestReferenceChecker checker_; + + LeapFrogTest() : checker_(refData_.rootChecker()) {} + + //! Setup the runners one for all parameters sets + static void SetUpTestCase() + { + // + // All runners should be registered here under appropriate conditions + // + s_runners_["LeapFrogSimple"] = integrateLeapFrogSimple; + if (GMX_GPU == GMX_GPU_CUDA && canComputeOnGpu()) { + s_runners_["LeapFrogGpu"] = integrateLeapFrogGpu; } + } - //! Setup the runners one for all parameters sets - static void SetUpTestCase() + /*! \brief Test the numerical integrator against analytical solution for simple constant force case. + * + * \param[in] tolerance Tolerance + * \param[in] testData Test data object + * \param[in] totalTime Total numerical integration time + */ + void testAgainstAnalyticalSolution(FloatingPointTolerance tolerance, + const LeapFrogTestData& testData, + const real totalTime) + { + for (int i = 0; i < testData.numAtoms_; i++) { - // - // All runners should be registered here under appropriate conditions - // - s_runners_["LeapFrogSimple"] = integrateLeapFrogSimple; - if (GMX_GPU == GMX_GPU_CUDA && canComputeOnGpu()) + rvec xAnalytical; + rvec vAnalytical; + for (int d = 0; d < DIM; d++) { - s_runners_["LeapFrogGpu"] = integrateLeapFrogGpu; + // Analytical solution for constant-force particle movement + real x0 = testData.x0_[i][d]; + real v0 = testData.v0_[i][d]; + real f = testData.f_[i][d]; + real im = testData.inverseMasses_[i]; + + xAnalytical[d] = x0 + v0 * totalTime + 0.5 * f * totalTime * totalTime * im; + vAnalytical[d] = v0 + f * totalTime * im; + + EXPECT_REAL_EQ_TOL(xAnalytical[d], testData.xPrime_[i][d], tolerance) << gmx::formatString( + "Coordinate %d of atom %d is different from analytical solution.", d, i); + + EXPECT_REAL_EQ_TOL(vAnalytical[d], testData.v_[i][d], tolerance) << gmx::formatString( + "Velocity component %d of atom %d is different from analytical solution.", d, i); } } + } - /*! \brief Test the numerical integrator against analytical solution for simple constant force case. - * - * \param[in] tolerance Tolerance - * \param[in] testData Test data object - * \param[in] totalTime Total numerical integration time - */ - void testAgainstAnalyticalSolution(FloatingPointTolerance tolerance, - const LeapFrogTestData &testData, - const real totalTime) + /*! \brief Test the numerical integrator against pre-computed reference values. + * + * \param[in] testData Test data object + */ + void testAgainstReferenceData(const LeapFrogTestData& testData) + { + TestReferenceChecker finalPositionsRef( + checker_.checkSequenceCompound("FinalPositions", testData.numAtoms_)); + for (int i = 0; i < testData.numAtoms_; i++) { - for (int i = 0; i < testData.numAtoms_; i++) - { - rvec xAnalytical; - rvec vAnalytical; - for (int d = 0; d < DIM; d++) - { - // Analytical solution for constant-force particle movement - real x0 = testData.x0_[i][d]; - real v0 = testData.v0_[i][d]; - real f = testData.f_[i][d]; - real im = testData.inverseMasses_[i]; - - xAnalytical[d] = x0 + v0*totalTime + 0.5*f*totalTime*totalTime*im; - vAnalytical[d] = v0 + f*totalTime*im; - - EXPECT_REAL_EQ_TOL(xAnalytical[d], testData.xPrime_[i][d], tolerance) - << gmx::formatString("Coordinate %d of atom %d is different from analytical solution.", d, i); - - EXPECT_REAL_EQ_TOL(vAnalytical[d], testData.v_[i][d], tolerance) - << gmx::formatString("Velocity component %d of atom %d is different from analytical solution.", d, i); - } - } + const gmx::RVec& xPrime = testData.xPrime_[i]; + TestReferenceChecker xPrimeRef(finalPositionsRef.checkCompound("Atom", nullptr)); + xPrimeRef.checkReal(xPrime[XX], "XX"); + xPrimeRef.checkReal(xPrime[YY], "YY"); + xPrimeRef.checkReal(xPrime[ZZ], "ZZ"); } - /*! \brief Test the numerical integrator against pre-computed reference values. - * - * \param[in] testData Test data object - */ - void testAgainstReferenceData(const LeapFrogTestData &testData) + TestReferenceChecker finalVelocitiesRef( + checker_.checkSequenceCompound("FinalVelocities", testData.numAtoms_)); + for (int i = 0; i < testData.numAtoms_; i++) { - TestReferenceChecker finalPositionsRef(checker_.checkSequenceCompound("FinalPositions", testData.numAtoms_)); - for (int i = 0; i < testData.numAtoms_; i++) - { - const gmx::RVec &xPrime = testData.xPrime_[i]; - TestReferenceChecker xPrimeRef(finalPositionsRef.checkCompound("Atom", nullptr)); - xPrimeRef.checkReal(xPrime[XX], "XX"); - xPrimeRef.checkReal(xPrime[YY], "YY"); - xPrimeRef.checkReal(xPrime[ZZ], "ZZ"); - } - - TestReferenceChecker finalVelocitiesRef(checker_.checkSequenceCompound("FinalVelocities", testData.numAtoms_)); - for (int i = 0; i < testData.numAtoms_; i++) - { - const gmx::RVec &v = testData.v_[i]; - TestReferenceChecker vRef(finalVelocitiesRef.checkCompound("Atom", nullptr)); - vRef.checkReal(v[XX], "XX"); - vRef.checkReal(v[YY], "YY"); - vRef.checkReal(v[ZZ], "ZZ"); - } + const gmx::RVec& v = testData.v_[i]; + TestReferenceChecker vRef(finalVelocitiesRef.checkCompound("Atom", nullptr)); + vRef.checkReal(v[XX], "XX"); + vRef.checkReal(v[YY], "YY"); + vRef.checkReal(v[ZZ], "ZZ"); } + } }; -std::unordered_map LeapFrogTest::s_runners_; +std::unordered_map LeapFrogTest::s_runners_; TEST_P(LeapFrogTest, SimpleIntegration) { // Cycle through all available runners - for (const auto &runner : s_runners_) + for (const auto& runner : s_runners_) { - std::string runnerName = runner.first; + std::string runnerName = runner.first; LeapFrogTestParameters parameters = GetParam(); - std::string testDescription = formatString("Testing %s with %d atoms for %d timesteps with %d temperature coupling groups and %s pressure coupling (dt = %f, v0=(%f, %f, %f), f0=(%f, %f, %f), nstpcouple = %d)", - runnerName.c_str(), - parameters.numAtoms, parameters.numSteps, parameters.numTCoupleGroups, - parameters.nstpcouple == 0 ? "without" : "with", - parameters.timestep, - parameters.v[XX], parameters.v[YY], parameters.v[ZZ], - parameters.f[XX], parameters.f[YY], parameters.f[ZZ], - parameters.nstpcouple); + std::string testDescription = formatString( + "Testing %s with %d atoms for %d timesteps with %d temperature coupling groups and " + "%s pressure coupling (dt = %f, v0=(%f, %f, %f), f0=(%f, %f, %f), nstpcouple = %d)", + runnerName.c_str(), parameters.numAtoms, parameters.numSteps, + parameters.numTCoupleGroups, parameters.nstpcouple == 0 ? "without" : "with", + parameters.timestep, parameters.v[XX], parameters.v[YY], parameters.v[ZZ], + parameters.f[XX], parameters.f[YY], parameters.f[ZZ], parameters.nstpcouple); SCOPED_TRACE(testDescription); - std::unique_ptr testData = - std::make_unique(parameters.numAtoms, parameters.timestep, - parameters.v, parameters.f, - parameters.numTCoupleGroups, - parameters.nstpcouple); + std::unique_ptr testData = std::make_unique( + parameters.numAtoms, parameters.timestep, parameters.v, parameters.f, + parameters.numTCoupleGroups, parameters.nstpcouple); runner.second(testData.get(), parameters.numSteps); - real totalTime = parameters.numSteps*parameters.timestep; + real totalTime = parameters.numSteps * parameters.timestep; // TODO For the case of constant force, the numerical scheme is exact and // the only source of errors is floating point arithmetic. Hence, // the tolerance can be calculated. - FloatingPointTolerance tolerance = absoluteTolerance(parameters.numSteps*0.000005); + FloatingPointTolerance tolerance = absoluteTolerance(parameters.numSteps * 0.000005); // Test against the analytical solution (without temperature coupling) if (parameters.numTCoupleGroups == 0 && parameters.nstpcouple == 0) @@ -271,9 +266,8 @@ TEST_P(LeapFrogTest, SimpleIntegration) } } -INSTANTIATE_TEST_CASE_P(WithParameters, LeapFrogTest, - ::testing::ValuesIn(parametersSets)); +INSTANTIATE_TEST_CASE_P(WithParameters, LeapFrogTest, ::testing::ValuesIn(parametersSets)); -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/leapfrogtestdata.cpp b/src/gromacs/mdlib/tests/leapfrogtestdata.cpp index e68b893a6b..38c891274d 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestdata.cpp +++ b/src/gromacs/mdlib/tests/leapfrogtestdata.cpp @@ -67,7 +67,12 @@ namespace gmx namespace test { -LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, const rvec f0, int numTCoupleGroups, int nstpcouple) : +LeapFrogTestData::LeapFrogTestData(int numAtoms, + real timestep, + const rvec v0, + const rvec f0, + int numTCoupleGroups, + int nstpcouple) : numAtoms_(numAtoms), timestep_(timestep), x0_(numAtoms), @@ -85,9 +90,9 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, c for (int i = 0; i < numAtoms_; i++) { // Typical PBC box size is tens of nanometers - x_[i][XX] = (i%21)*1.0; - x_[i][YY] = 6.5 + (i%13)*(-1.0); - x_[i][ZZ] = (i%32)*(0.0); + x_[i][XX] = (i % 21) * 1.0; + x_[i][YY] = 6.5 + (i % 13) * (-1.0); + x_[i][ZZ] = (i % 32) * (0.0); for (int d = 0; d < DIM; d++) { @@ -101,7 +106,7 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, c v0_[i][d] = v_[i][d]; } // Atom masses are ~1-100 g/mol - inverseMasses_[i] = 1.0/(1.0 + i%100); + inverseMasses_[i] = 1.0 / (1.0 + i % 100); for (int d = 0; d < DIM; d++) { inverseMassesPerDim_[i][d] = inverseMasses_[i]; @@ -138,7 +143,7 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, c kineticEnergyData_.ngtc = numTCoupleGroups_; for (int i = 0; i < numTCoupleGroups; i++) { - real tCoupleLambda = 1.0 - (i + 1.0)/10.0; + real tCoupleLambda = 1.0 - (i + 1.0) / 10.0; t_grp_tcstat temperatureCouplingGroupData; temperatureCouplingGroupData.lambda = tCoupleLambda; kineticEnergyData_.tcstat.emplace_back(temperatureCouplingGroupData); @@ -184,7 +189,7 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, c { inputRecord_.epc = epcPARRINELLORAHMAN; inputRecord_.nstpcouple = nstpcouple; - dtPressureCouple_ = inputRecord_.nstpcouple*inputRecord_.delta_t; + dtPressureCouple_ = inputRecord_.nstpcouple * inputRecord_.delta_t; velocityScalingMatrix_[XX][XX] = 1.2; velocityScalingMatrix_[XX][YY] = 0.0; @@ -213,7 +218,6 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, real timestep, const rvec v0, c velocityScalingMatrix_[ZZ][YY] = 0.0; velocityScalingMatrix_[ZZ][ZZ] = 1.0; } - } LeapFrogTestData::~LeapFrogTestData() @@ -221,5 +225,5 @@ LeapFrogTestData::~LeapFrogTestData() sfree(mdAtoms_.cTC); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/leapfrogtestdata.h b/src/gromacs/mdlib/tests/leapfrogtestdata.h index 2eb1ea636e..56305dcfcb 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestdata.h +++ b/src/gromacs/mdlib/tests/leapfrogtestdata.h @@ -69,68 +69,67 @@ namespace test */ class LeapFrogTestData { - public: - //! Number of atoms in the system - int numAtoms_; - //! Integration timestep - real timestep_; +public: + //! Number of atoms in the system + int numAtoms_; + //! Integration timestep + real timestep_; - //! Initial coordinates - PaddedVector x0_; - //! Current coordinates - PaddedVector x_; - //! Coordinates after integrator update - PaddedVector xPrime_; - //! Initial velocities - PaddedVector v0_; - //! Current velocities - PaddedVector v_; - //! External forces - PaddedVector f_; - //! Inverse masses of the particles - PaddedVector inverseMasses_; - //! Inverse masses of the particles per dimension - PaddedVector inverseMassesPerDim_; + //! Initial coordinates + PaddedVector x0_; + //! Current coordinates + PaddedVector x_; + //! Coordinates after integrator update + PaddedVector xPrime_; + //! Initial velocities + PaddedVector v0_; + //! Current velocities + PaddedVector v_; + //! External forces + PaddedVector f_; + //! Inverse masses of the particles + PaddedVector inverseMasses_; + //! Inverse masses of the particles per dimension + PaddedVector inverseMassesPerDim_; - //! MD atoms structure in which inverse masses will be passed to the integrator - t_mdatoms mdAtoms_; - //! Input record (to get integrator type, temperature and pressure coupling) - t_inputrec inputRecord_; - //! System state - t_state state_; - //! Force calculation data - t_fcdata forceCalculationData_; - //! Kinetic energy data (to disable non-equilibrium MD integration) - gmx_ekindata_t kineticEnergyData_; - //! Update data - std::unique_ptr update_; + //! MD atoms structure in which inverse masses will be passed to the integrator + t_mdatoms mdAtoms_; + //! Input record (to get integrator type, temperature and pressure coupling) + t_inputrec inputRecord_; + //! System state + t_state state_; + //! Force calculation data + t_fcdata forceCalculationData_; + //! Kinetic energy data (to disable non-equilibrium MD integration) + gmx_ekindata_t kineticEnergyData_; + //! Update data + std::unique_ptr update_; - //! Number of temperature coupling groups - int numTCoupleGroups_; + //! Number of temperature coupling groups + int numTCoupleGroups_; - //! If the pressure coupling is enabled - bool doPressureCouple_; - //! Period between pressure coupling steps - float dtPressureCouple_; - //! Matrix for Parrinello-Rahman velocity scaling - matrix velocityScalingMatrix_; + //! If the pressure coupling is enabled + bool doPressureCouple_; + //! Period between pressure coupling steps + float dtPressureCouple_; + //! Matrix for Parrinello-Rahman velocity scaling + matrix velocityScalingMatrix_; - /*! \brief Constructor. - * - * \param[in] numAtoms Number of atoms in the system - * \param[in] timestep Integration timestep - * \param[in] v0 Initial velocity (same for all particles) - * \param[in] f0 External constant force, acting on all particles - * \param[in] numTCoupleGroups Number of temperature coupling groups (zero for no temperature coupling) - * \param[in] nstpcouple Number of steps between pressure coupling steps (zero for no pressure coupling) - */ - LeapFrogTestData(int numAtoms, real timestep, const rvec v0, const rvec f0, - int numTCoupleGroups, int nstpcouple); + /*! \brief Constructor. + * + * \param[in] numAtoms Number of atoms in the system + * \param[in] timestep Integration timestep + * \param[in] v0 Initial velocity (same for all particles) + * \param[in] f0 External constant force, acting on all particles + * \param[in] numTCoupleGroups Number of temperature coupling groups (zero for no temperature coupling) + * \param[in] nstpcouple Number of steps between pressure coupling steps (zero for no pressure coupling) + */ + LeapFrogTestData(int numAtoms, real timestep, const rvec v0, const rvec f0, int numTCoupleGroups, int nstpcouple); - ~LeapFrogTestData(); + ~LeapFrogTestData(); }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_LEAPFROGTESTDATA_H diff --git a/src/gromacs/mdlib/tests/leapfrogtestrunners.cpp b/src/gromacs/mdlib/tests/leapfrogtestrunners.cpp index 2f1e498ea6..ec6cff4b78 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestrunners.cpp +++ b/src/gromacs/mdlib/tests/leapfrogtestrunners.cpp @@ -70,8 +70,7 @@ namespace gmx namespace test { -void integrateLeapFrogSimple(LeapFrogTestData *testData, - int numSteps) +void integrateLeapFrogSimple(LeapFrogTestData* testData, int numSteps) { testData->state_.x.resizeWithPadding(testData->numAtoms_); testData->state_.v.resizeWithPadding(testData->numAtoms_); @@ -85,26 +84,12 @@ void integrateLeapFrogSimple(LeapFrogTestData *testData, for (int step = 0; step < numSteps; step++) { - update_coords(step, - &testData->inputRecord_, - &testData->mdAtoms_, - &testData->state_, - testData->f_, - &testData->forceCalculationData_, - &testData->kineticEnergyData_, - testData->velocityScalingMatrix_, - testData->update_.get(), - etrtNONE, - nullptr, - nullptr); - finish_update(&testData->inputRecord_, - &testData->mdAtoms_, - &testData->state_, - nullptr, - nullptr, - nullptr, - testData->update_.get(), + update_coords(step, &testData->inputRecord_, &testData->mdAtoms_, &testData->state_, + testData->f_, &testData->forceCalculationData_, &testData->kineticEnergyData_, + testData->velocityScalingMatrix_, testData->update_.get(), etrtNONE, nullptr, nullptr); + finish_update(&testData->inputRecord_, &testData->mdAtoms_, &testData->state_, nullptr, + nullptr, nullptr, testData->update_.get(), nullptr); } auto xp = makeArrayRef(*testData->update_->xp()).subArray(0, testData->numAtoms_); for (int i = 0; i < testData->numAtoms_; i++) @@ -120,13 +105,12 @@ void integrateLeapFrogSimple(LeapFrogTestData *testData, #if GMX_GPU != GMX_GPU_CUDA -void integrateLeapFrogGpu(gmx_unused LeapFrogTestData *testData, - gmx_unused int numSteps) +void integrateLeapFrogGpu(gmx_unused LeapFrogTestData* testData, gmx_unused int numSteps) { FAIL() << "Dummy Leap-Frog CUDA function was called instead of the real one."; } #endif // GMX_GPU != GMX_GPU_CUDA -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/leapfrogtestrunners.cu b/src/gromacs/mdlib/tests/leapfrogtestrunners.cu index de3537b501..34bd6a2685 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestrunners.cu +++ b/src/gromacs/mdlib/tests/leapfrogtestrunners.cu @@ -68,27 +68,26 @@ namespace test #if GMX_GPU == GMX_GPU_CUDA -void integrateLeapFrogGpu(LeapFrogTestData *testData, - int numSteps) +void integrateLeapFrogGpu(LeapFrogTestData* testData, int numSteps) { - int numAtoms = testData->numAtoms_; + int numAtoms = testData->numAtoms_; - float3 *h_x = reinterpret_cast(testData->x_.data()); - float3 *h_xp = reinterpret_cast(testData->xPrime_.data()); - float3 *h_v = reinterpret_cast(testData->v_.data()); - float3 *h_f = reinterpret_cast(testData->f_.data()); + float3* h_x = reinterpret_cast(testData->x_.data()); + float3* h_xp = reinterpret_cast(testData->xPrime_.data()); + float3* h_v = reinterpret_cast(testData->v_.data()); + float3* h_f = reinterpret_cast(testData->f_.data()); float3 *d_x, *d_xp, *d_v, *d_f; - allocateDeviceBuffer(&d_x, numAtoms, nullptr); + allocateDeviceBuffer(&d_x, numAtoms, nullptr); allocateDeviceBuffer(&d_xp, numAtoms, nullptr); - allocateDeviceBuffer(&d_v, numAtoms, nullptr); - allocateDeviceBuffer(&d_f, numAtoms, nullptr); + allocateDeviceBuffer(&d_v, numAtoms, nullptr); + allocateDeviceBuffer(&d_f, numAtoms, nullptr); - copyToDeviceBuffer(&d_x, h_x, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_x, h_x, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); copyToDeviceBuffer(&d_xp, h_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&d_v, h_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); - copyToDeviceBuffer(&d_f, h_f, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_v, h_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyToDeviceBuffer(&d_f, h_f, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); auto integrator = std::make_unique(nullptr); @@ -98,14 +97,16 @@ void integrateLeapFrogGpu(LeapFrogTestData *testData, for (int step = 0; step < numSteps; step++) { // This follows the logic of the CPU-based implementation - bool doPressureCouple = testData->doPressureCouple_ && do_per_step(step + testData->inputRecord_.nstpcouple - 1, testData->inputRecord_.nstpcouple); - integrator->integrate(d_x, d_xp, d_v, d_f, testData->timestep_, - doTempCouple, testData->kineticEnergyData_.tcstat, - doPressureCouple, testData->dtPressureCouple_, testData->velocityScalingMatrix_); + bool doPressureCouple = testData->doPressureCouple_ + && do_per_step(step + testData->inputRecord_.nstpcouple - 1, + testData->inputRecord_.nstpcouple); + integrator->integrate(d_x, d_xp, d_v, d_f, testData->timestep_, doTempCouple, + testData->kineticEnergyData_.tcstat, doPressureCouple, + testData->dtPressureCouple_, testData->velocityScalingMatrix_); } copyFromDeviceBuffer(h_xp, &d_x, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); - copyFromDeviceBuffer(h_v, &d_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); + copyFromDeviceBuffer(h_v, &d_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); freeDeviceBuffer(&d_x); freeDeviceBuffer(&d_xp); @@ -115,5 +116,5 @@ void integrateLeapFrogGpu(LeapFrogTestData *testData, #endif // GMX_GPU == GMX_GPU_CUDA -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/leapfrogtestrunners.h b/src/gromacs/mdlib/tests/leapfrogtestrunners.h index 9ef313640f..a47534e08a 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestrunners.h +++ b/src/gromacs/mdlib/tests/leapfrogtestrunners.h @@ -56,8 +56,7 @@ namespace test * \param[in] testData Data needed for the integrator * \param[in] numSteps Total number of steps to run integration for. */ -void integrateLeapFrogSimple(LeapFrogTestData *testData, - int numSteps); +void integrateLeapFrogSimple(LeapFrogTestData* testData, int numSteps); /*! \brief Integrate using CUDA version of Leap-Frog * @@ -68,10 +67,9 @@ void integrateLeapFrogSimple(LeapFrogTestData *testData, * \param[in] testData Data needed for the integrator * \param[in] numSteps Total number of steps to run integration for. */ -void integrateLeapFrogGpu(LeapFrogTestData *testData, - int numSteps); +void integrateLeapFrogGpu(LeapFrogTestData* testData, int numSteps); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_LEAPFROGTESTRUNNERS_H diff --git a/src/gromacs/mdlib/tests/settle.cpp b/src/gromacs/mdlib/tests/settle.cpp index a1aebac1aa..a97a131572 100644 --- a/src/gromacs/mdlib/tests/settle.cpp +++ b/src/gromacs/mdlib/tests/settle.cpp @@ -110,226 +110,226 @@ namespace struct SettleTestParameters { //! Number of water molecules (SETTLEs) [1, 2, 4, 5, 7, 10, 12, 15, 17] - int numSettles; + int numSettles; //! If the velocities should be updated while constraining [true/false] - bool updateVelocities; + bool updateVelocities; //! If the virial should be computed [true/false] - bool calcVirial; + bool calcVirial; //! Periodic boundary conditions [PBCXYZ/PBCNone] std::string pbcName; }; /*! \brief Sets of parameters on which to run the tests. */ -const SettleTestParameters parametersSets[] = {{ 1, false, false, "PBCXYZ" }, // 1 water molecule - { 2, false, false, "PBCXYZ" }, // 2 water molecules - { 4, false, false, "PBCXYZ" }, // 4 water molecules - { 5, false, false, "PBCXYZ" }, // 5 water molecules - { 6, false, false, "PBCXYZ" }, // 6 water molecules - {10, false, false, "PBCXYZ" }, // 10 water molecules - {12, false, false, "PBCXYZ" }, // 12 water molecules - {15, false, false, "PBCXYZ" }, // 15 water molecules - {17, true, false, "PBCXYZ" }, // Update velocities - {17, false, true, "PBCXYZ" }, // Compute virial - {17, false, false, "PBCNone"}, // No periodic boundary - {17, true, true, "PBCNone"}, // Update velocities, compute virial, without PBC - {17, true, true, "PBCXYZ" }}; // Update velocities, compute virial, with PBC +const SettleTestParameters parametersSets[] = { + { 1, false, false, "PBCXYZ" }, // 1 water molecule + { 2, false, false, "PBCXYZ" }, // 2 water molecules + { 4, false, false, "PBCXYZ" }, // 4 water molecules + { 5, false, false, "PBCXYZ" }, // 5 water molecules + { 6, false, false, "PBCXYZ" }, // 6 water molecules + { 10, false, false, "PBCXYZ" }, // 10 water molecules + { 12, false, false, "PBCXYZ" }, // 12 water molecules + { 15, false, false, "PBCXYZ" }, // 15 water molecules + { 17, true, false, "PBCXYZ" }, // Update velocities + { 17, false, true, "PBCXYZ" }, // Compute virial + { 17, false, false, "PBCNone" }, // No periodic boundary + { 17, true, true, "PBCNone" }, // Update velocities, compute virial, without PBC + { 17, true, true, "PBCXYZ" } +}; // Update velocities, compute virial, with PBC /*! \brief Test fixture for testing SETTLE. */ class SettleTest : public ::testing::TestWithParam { - public: - //! PBC setups - std::unordered_map pbcs_; - //! Runners (CPU and GPU versions of SETTLE) - std::unordered_map runners_; - //! Reference data - TestReferenceData refData_; - //! Checker for reference data - TestReferenceChecker checker_; - - /*! \brief Test setup function. - * - * Setting up the PBCs and algorithms. Note, that corresponding string keywords - * have to be explicitly specified when parameters are initialied. - * - */ - SettleTest() : - checker_(refData_.rootChecker()) - { +public: + //! PBC setups + std::unordered_map pbcs_; + //! Runners (CPU and GPU versions of SETTLE) + std::unordered_map + runners_; + //! Reference data + TestReferenceData refData_; + //! Checker for reference data + TestReferenceChecker checker_; + + /*! \brief Test setup function. + * + * Setting up the PBCs and algorithms. Note, that corresponding string keywords + * have to be explicitly specified when parameters are initialied. + * + */ + SettleTest() : checker_(refData_.rootChecker()) + { - // - // PBC initialization - // - t_pbc pbc; - - // Infinitely small box - matrix boxNone = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; - set_pbc(&pbc, epbcNONE, boxNone); - pbcs_["PBCNone"] = pbc; - - // Rectangular box - matrix boxXyz = {{real(1.86206), 0, 0}, {0, real(1.86206), 0}, {0, 0, real(1.86206)}}; - set_pbc(&pbc, epbcXYZ, boxXyz); - pbcs_["PBCXYZ"] = pbc; - - // - // All SETTLE runners should be registered here under appropriate conditions - // - runners_["SETTLE"] = applySettle; - - // CUDA version will be tested only if: - // 1. The code was compiled with CUDA - // 2. There is a CUDA-capable GPU in a system - // 3. This GPU is detectable - // 4. GPU detection was not disabled by GMX_DISABLE_GPU_DETECTION environment variable - if (s_hasCompatibleGpus) + // + // PBC initialization + // + t_pbc pbc; + + // Infinitely small box + matrix boxNone = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + set_pbc(&pbc, epbcNONE, boxNone); + pbcs_["PBCNone"] = pbc; + + // Rectangular box + matrix boxXyz = { { real(1.86206), 0, 0 }, { 0, real(1.86206), 0 }, { 0, 0, real(1.86206) } }; + set_pbc(&pbc, epbcXYZ, boxXyz); + pbcs_["PBCXYZ"] = pbc; + + // + // All SETTLE runners should be registered here under appropriate conditions + // + runners_["SETTLE"] = applySettle; + + // CUDA version will be tested only if: + // 1. The code was compiled with CUDA + // 2. There is a CUDA-capable GPU in a system + // 3. This GPU is detectable + // 4. GPU detection was not disabled by GMX_DISABLE_GPU_DETECTION environment variable + if (s_hasCompatibleGpus) + { + if (GMX_GPU == GMX_GPU_CUDA && s_hasCompatibleGpus) { - if (GMX_GPU == GMX_GPU_CUDA && s_hasCompatibleGpus) - { - runners_["SETTLE_GPU"] = applySettleGpu; - } + runners_["SETTLE_GPU"] = applySettleGpu; } } + } - /*! \brief Check if the final interatomic distances are equal to target set by constraints. - * - * \param[in] numSettles Number of water molecules in the tested system. - * \param[in] tolerance Tolerance to compare floating point numbers. - * \param[in] testData An object, containing all the data structures needed by SETTLE. - */ - void checkConstrainsSatisfied(const int numSettles, - const FloatingPointTolerance tolerance, - const SettleTestData &testData) + /*! \brief Check if the final interatomic distances are equal to target set by constraints. + * + * \param[in] numSettles Number of water molecules in the tested system. + * \param[in] tolerance Tolerance to compare floating point numbers. + * \param[in] testData An object, containing all the data structures needed by SETTLE. + */ + void checkConstrainsSatisfied(const int numSettles, + const FloatingPointTolerance tolerance, + const SettleTestData& testData) + { + for (int i = 0; i < numSettles; ++i) { - for (int i = 0; i < numSettles; ++i) - { - const gmx::RVec &positionO = testData.xPrime_[i*testData.atomsPerSettle_ + 0]; - const gmx::RVec &positionH1 = testData.xPrime_[i*testData.atomsPerSettle_ + 1]; - const gmx::RVec &positionH2 = testData.xPrime_[i*testData.atomsPerSettle_ + 2]; - - real dOH = testData.dOH_; - real dHH = testData.dHH_; - - EXPECT_REAL_EQ_TOL(dOH*dOH, distance2(positionO, positionH1), tolerance) << formatString("for water %d. ", i); - EXPECT_REAL_EQ_TOL(dOH*dOH, distance2(positionO, positionH2), tolerance) << formatString("for water %d. ", i); - EXPECT_REAL_EQ_TOL(dHH*dHH, distance2(positionH1, positionH2), tolerance) << formatString("for water %d. ", i); - - } + const gmx::RVec& positionO = testData.xPrime_[i * testData.atomsPerSettle_ + 0]; + const gmx::RVec& positionH1 = testData.xPrime_[i * testData.atomsPerSettle_ + 1]; + const gmx::RVec& positionH2 = testData.xPrime_[i * testData.atomsPerSettle_ + 2]; + + real dOH = testData.dOH_; + real dHH = testData.dHH_; + + EXPECT_REAL_EQ_TOL(dOH * dOH, distance2(positionO, positionH1), tolerance) + << formatString("for water %d. ", i); + EXPECT_REAL_EQ_TOL(dOH * dOH, distance2(positionO, positionH2), tolerance) + << formatString("for water %d. ", i); + EXPECT_REAL_EQ_TOL(dHH * dHH, distance2(positionH1, positionH2), tolerance) + << formatString("for water %d. ", i); } + } - /*! \brief Check if the virial was updated and symmetric. - * - * The two tests on virial are: - * 1. If it was updated in case calcVirial is true. - * 2. If it is symmetrical. - * - * \param[in] calcVirial If the virial is computed. - * \param[in] tolerance Tolerance to compare floating point numbers. - * \param[in] testData An object, containing all the data structures needed by SETTLE. - */ - void checkVirialSymmetric(const bool calcVirial, - const FloatingPointTolerance tolerance, - const SettleTestData &testData) + /*! \brief Check if the virial was updated and symmetric. + * + * The two tests on virial are: + * 1. If it was updated in case calcVirial is true. + * 2. If it is symmetrical. + * + * \param[in] calcVirial If the virial is computed. + * \param[in] tolerance Tolerance to compare floating point numbers. + * \param[in] testData An object, containing all the data structures needed by SETTLE. + */ + void checkVirialSymmetric(const bool calcVirial, + const FloatingPointTolerance tolerance, + const SettleTestData& testData) + { + for (int d = 0; d < DIM; ++d) { - for (int d = 0; d < DIM; ++d) + for (int dd = 0; dd < DIM; ++dd) { - for (int dd = 0; dd < DIM; ++dd) - { - EXPECT_TRUE(calcVirial == (0. != testData.virial_[d][dd])) - << formatString("for virial component[%d][%d]. ", d, dd); + EXPECT_TRUE(calcVirial == (0. != testData.virial_[d][dd])) + << formatString("for virial component[%d][%d]. ", d, dd); - if (calcVirial) - { - EXPECT_REAL_EQ_TOL(testData.virial_[d][dd], testData.virial_[dd][d], tolerance) - << formatString("Virial is not symmetrical for [%d][%d]. ", d, dd); - } + if (calcVirial) + { + EXPECT_REAL_EQ_TOL(testData.virial_[d][dd], testData.virial_[dd][d], tolerance) + << formatString("Virial is not symmetrical for [%d][%d]. ", d, dd); } } } + } - /*! \brief Check if the final positions correspond to reference values. - * - * \param[in] numSettles Number of water molecules in the tested system. - * \param[in] testData An object, containing all the data structures needed by SETTLE. - */ - void checkFinalPositions(const int numSettles, - const SettleTestData &testData) + /*! \brief Check if the final positions correspond to reference values. + * + * \param[in] numSettles Number of water molecules in the tested system. + * \param[in] testData An object, containing all the data structures needed by SETTLE. + */ + void checkFinalPositions(const int numSettles, const SettleTestData& testData) + { + TestReferenceChecker finalCoordinatesRef( + checker_.checkSequenceCompound("FinalCoordinates", numSettles)); + for (int i = 0; i < numSettles; ++i) { - TestReferenceChecker finalCoordinatesRef(checker_.checkSequenceCompound("FinalCoordinates", numSettles)); - for (int i = 0; i < numSettles; ++i) + TestReferenceChecker settlerRef(finalCoordinatesRef.checkCompound("Settler", nullptr)); + TestReferenceChecker atomsRef( + settlerRef.checkSequenceCompound("Atoms", testData.atomsPerSettle_)); + for (int j = 0; j < testData.atomsPerSettle_; ++j) { - TestReferenceChecker settlerRef(finalCoordinatesRef.checkCompound("Settler", nullptr)); - TestReferenceChecker atomsRef(settlerRef.checkSequenceCompound("Atoms", testData.atomsPerSettle_)); - for (int j = 0; j < testData.atomsPerSettle_; ++j) - { - const gmx::RVec &xPrime = testData.xPrime_[testData.atomsPerSettle_*i + j]; - TestReferenceChecker xPrimeRef(atomsRef.checkCompound("Atom", nullptr)); - xPrimeRef.checkReal(xPrime[XX], "XX"); - xPrimeRef.checkReal(xPrime[YY], "YY"); - xPrimeRef.checkReal(xPrime[ZZ], "ZZ"); - } + const gmx::RVec& xPrime = testData.xPrime_[testData.atomsPerSettle_ * i + j]; + TestReferenceChecker xPrimeRef(atomsRef.checkCompound("Atom", nullptr)); + xPrimeRef.checkReal(xPrime[XX], "XX"); + xPrimeRef.checkReal(xPrime[YY], "YY"); + xPrimeRef.checkReal(xPrime[ZZ], "ZZ"); } } + } - /*! \brief Check if the final velocities correspond to reference values. - * - * \param[in] numSettles Number of water molecules in the tested system. - * \param[in] testData An object, containing all the data structures needed by SETTLE. - */ - void checkFinalVelocities(const int numSettles, - const SettleTestData &testData) + /*! \brief Check if the final velocities correspond to reference values. + * + * \param[in] numSettles Number of water molecules in the tested system. + * \param[in] testData An object, containing all the data structures needed by SETTLE. + */ + void checkFinalVelocities(const int numSettles, const SettleTestData& testData) + { + TestReferenceChecker finalCoordinatesRef( + checker_.checkSequenceCompound("FinalVelocities", numSettles)); + for (int i = 0; i < numSettles; ++i) { - TestReferenceChecker finalCoordinatesRef(checker_.checkSequenceCompound("FinalVelocities", numSettles)); - for (int i = 0; i < numSettles; ++i) + TestReferenceChecker settlerRef(finalCoordinatesRef.checkCompound("Settler", nullptr)); + TestReferenceChecker atomsRef( + settlerRef.checkSequenceCompound("Atoms", testData.atomsPerSettle_)); + for (int j = 0; j < testData.atomsPerSettle_; ++j) { - TestReferenceChecker settlerRef(finalCoordinatesRef.checkCompound("Settler", nullptr)); - TestReferenceChecker atomsRef(settlerRef.checkSequenceCompound("Atoms", testData.atomsPerSettle_)); - for (int j = 0; j < testData.atomsPerSettle_; ++j) - { - const gmx::RVec &v = testData.v_[testData.atomsPerSettle_*i + j]; - TestReferenceChecker vRef(atomsRef.checkCompound("Atom", nullptr)); - vRef.checkReal(v[XX], "XX"); - vRef.checkReal(v[YY], "YY"); - vRef.checkReal(v[ZZ], "ZZ"); - } + const gmx::RVec& v = testData.v_[testData.atomsPerSettle_ * i + j]; + TestReferenceChecker vRef(atomsRef.checkCompound("Atom", nullptr)); + vRef.checkReal(v[XX], "XX"); + vRef.checkReal(v[YY], "YY"); + vRef.checkReal(v[ZZ], "ZZ"); } } + } - /*! \brief Check if the computed virial correspond to reference values. - * - * \param[in] testData An object, containing all the data structures needed by SETTLE. - */ - void checkVirial(const SettleTestData &testData) - { - const tensor &virial = testData.virial_; - TestReferenceChecker virialRef(checker_.checkCompound("Virial", nullptr)); - - // TODO: Is it worth it to make this in a loop?? - virialRef.checkReal(virial[XX][XX], "XX"); - virialRef.checkReal(virial[XX][YY], "XY"); - virialRef.checkReal(virial[XX][ZZ], "XZ"); - virialRef.checkReal(virial[YY][XX], "YX"); - virialRef.checkReal(virial[YY][YY], "YY"); - virialRef.checkReal(virial[YY][ZZ], "YZ"); - virialRef.checkReal(virial[ZZ][XX], "ZX"); - virialRef.checkReal(virial[ZZ][YY], "ZY"); - virialRef.checkReal(virial[ZZ][ZZ], "ZZ"); - } + /*! \brief Check if the computed virial correspond to reference values. + * + * \param[in] testData An object, containing all the data structures needed by SETTLE. + */ + void checkVirial(const SettleTestData& testData) + { + const tensor& virial = testData.virial_; + TestReferenceChecker virialRef(checker_.checkCompound("Virial", nullptr)); + + // TODO: Is it worth it to make this in a loop?? + virialRef.checkReal(virial[XX][XX], "XX"); + virialRef.checkReal(virial[XX][YY], "XY"); + virialRef.checkReal(virial[XX][ZZ], "XZ"); + virialRef.checkReal(virial[YY][XX], "YX"); + virialRef.checkReal(virial[YY][YY], "YY"); + virialRef.checkReal(virial[YY][ZZ], "YZ"); + virialRef.checkReal(virial[ZZ][XX], "ZX"); + virialRef.checkReal(virial[ZZ][YY], "ZY"); + virialRef.checkReal(virial[ZZ][ZZ], "ZZ"); + } - //! Store whether any compatible GPUs exist. - static bool s_hasCompatibleGpus; - //! Before any test is run, work out whether any compatible GPUs exist. - static void SetUpTestCase() - { - s_hasCompatibleGpus = canComputeOnGpu(); - } + //! Store whether any compatible GPUs exist. + static bool s_hasCompatibleGpus; + //! Before any test is run, work out whether any compatible GPUs exist. + static void SetUpTestCase() { s_hasCompatibleGpus = canComputeOnGpu(); } }; bool SettleTest::s_hasCompatibleGpus = false; @@ -337,50 +337,45 @@ bool SettleTest::s_hasCompatibleGpus = false; TEST_P(SettleTest, SatisfiesConstraints) { // Cycle through all available runners - for (const auto &runner : runners_) + for (const auto& runner : runners_) { std::string runnerName = runner.first; // Make some symbolic names for the parameter combination. - SettleTestParameters params = GetParam(); + SettleTestParameters params = GetParam(); - int numSettles = params.numSettles; - bool updateVelocities = params.updateVelocities; - bool calcVirial = params.calcVirial; - std::string pbcName = params.pbcName; + int numSettles = params.numSettles; + bool updateVelocities = params.updateVelocities; + bool calcVirial = params.calcVirial; + std::string pbcName = params.pbcName; // Make a string that describes which parameter combination is // being tested, to help make failing tests comprehensible. - std::string testDescription = formatString("Testing %s with %d SETTLEs, %s, %svelocities and %scalculating the virial.", - runnerName.c_str(), - numSettles, - pbcName.c_str(), - updateVelocities ? "with " : "without ", - calcVirial ? "" : "not "); + std::string testDescription = formatString( + "Testing %s with %d SETTLEs, %s, %svelocities and %scalculating the virial.", + runnerName.c_str(), numSettles, pbcName.c_str(), + updateVelocities ? "with " : "without ", calcVirial ? "" : "not "); SCOPED_TRACE(testDescription); auto testData = std::make_unique(numSettles); - ASSERT_LE(numSettles, testData->xPrime_.size() / testData->atomsPerSettle_) << "cannot test that many SETTLEs. " << testDescription; + ASSERT_LE(numSettles, testData->xPrime_.size() / testData->atomsPerSettle_) + << "cannot test that many SETTLEs. " << testDescription; - t_pbc pbc = pbcs_.at(pbcName); + t_pbc pbc = pbcs_.at(pbcName); // Apply SETTLE - runner.second(testData.get(), - pbc, - updateVelocities, - calcVirial, - testDescription); + runner.second(testData.get(), pbc, updateVelocities, calcVirial, testDescription); // The necessary tolerances for the test to pass were determined // empirically. This isn't nice, but the required behavior that // SETTLE produces constrained coordinates consistent with // sensible sampling needs to be tested at a much higher level. // TODO: Re-evaluate the tolerances. - real dOH = testData->dOH_; - FloatingPointTolerance tolerance = relativeToleranceAsPrecisionDependentUlp(dOH*dOH, 80, 380); + real dOH = testData->dOH_; + FloatingPointTolerance tolerance = relativeToleranceAsPrecisionDependentUlp(dOH * dOH, 80, 380); FloatingPointTolerance toleranceVirial = absoluteTolerance(0.000001); FloatingPointTolerance tolerancePositions = absoluteTolerance(0.000001); @@ -411,6 +406,6 @@ TEST_P(SettleTest, SatisfiesConstraints) // The test will cycle through all available runners, including CPU and, if applicable, GPU implementations of SETTLE. INSTANTIATE_TEST_CASE_P(WithParameters, SettleTest, ::testing::ValuesIn(parametersSets)); -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/settletestdata.cpp b/src/gromacs/mdlib/tests/settletestdata.cpp index 7b895ebfcc..8feab2e0a0 100644 --- a/src/gromacs/mdlib/tests/settletestdata.cpp +++ b/src/gromacs/mdlib/tests/settletestdata.cpp @@ -86,7 +86,7 @@ SettleTestData::SettleTestData(int numSettles) : // work to do. const real deltas[] = { 0.01, -0.01, +0.02, -0.02 }; int i = 0; - for (auto &xPrime : xPrime_) + for (auto& xPrime : xPrime_) { xPrime[XX] += deltas[i % 4]; ++i; @@ -95,50 +95,52 @@ SettleTestData::SettleTestData(int numSettles) : xPrime[ZZ] += deltas[i % 4]; ++i; } - std::fill(v_.begin(), v_.end(), RVec {0.0, 0.0, 0.0}); + std::fill(v_.begin(), v_.end(), RVec{ 0.0, 0.0, 0.0 }); // Set up the topology. const int settleType = 0; mtop_.moltype.resize(1); mtop_.molblock.resize(1); - mtop_.molblock[0].type = 0; - std::vector &iatoms = mtop_.moltype[0].ilist[F_SETTLE].iatoms; + mtop_.molblock[0].type = 0; + std::vector& iatoms = mtop_.moltype[0].ilist[F_SETTLE].iatoms; for (int i = 0; i < numSettles; ++i) { iatoms.push_back(settleType); - iatoms.push_back(i*atomsPerSettle_ + 0); - iatoms.push_back(i*atomsPerSettle_ + 1); - iatoms.push_back(i*atomsPerSettle_ + 2); + iatoms.push_back(i * atomsPerSettle_ + 0); + iatoms.push_back(i * atomsPerSettle_ + 1); + iatoms.push_back(i * atomsPerSettle_ + 2); } // Set up the SETTLE parameters. - t_iparams iparams; + t_iparams iparams; iparams.settle.doh = dOH_; iparams.settle.dhh = dHH_; mtop_.ffparams.iparams.push_back(iparams); // Set up the masses. - mtop_.moltype[0].atoms.atom = static_cast(calloc(numSettles*atomsPerSettle_, sizeof(t_atom))); - mdatoms_.homenr = numSettles * atomsPerSettle_; - mdatoms_.massT = static_cast(calloc(mdatoms_.homenr, sizeof(real))); - mdatoms_.invmass = static_cast(calloc(mdatoms_.homenr, sizeof(real))); + mtop_.moltype[0].atoms.atom = + static_cast(calloc(numSettles * atomsPerSettle_, sizeof(t_atom))); + mdatoms_.homenr = numSettles * atomsPerSettle_; + mdatoms_.massT = static_cast(calloc(mdatoms_.homenr, sizeof(real))); + mdatoms_.invmass = static_cast(calloc(mdatoms_.homenr, sizeof(real))); for (int i = 0; i < numSettles; ++i) { - mdatoms_.massT[i*atomsPerSettle_ + 0] = oxygenMass_; - mdatoms_.massT[i*atomsPerSettle_ + 1] = hydrogenMass_; - mdatoms_.massT[i*atomsPerSettle_ + 2] = hydrogenMass_; + mdatoms_.massT[i * atomsPerSettle_ + 0] = oxygenMass_; + mdatoms_.massT[i * atomsPerSettle_ + 1] = hydrogenMass_; + mdatoms_.massT[i * atomsPerSettle_ + 2] = hydrogenMass_; - mdatoms_.invmass[i*atomsPerSettle_ + 0] = 1.0/oxygenMass_; - mdatoms_.invmass[i*atomsPerSettle_ + 1] = 1.0/hydrogenMass_; - mdatoms_.invmass[i*atomsPerSettle_ + 2] = 1.0/hydrogenMass_; + mdatoms_.invmass[i * atomsPerSettle_ + 0] = 1.0 / oxygenMass_; + mdatoms_.invmass[i * atomsPerSettle_ + 1] = 1.0 / hydrogenMass_; + mdatoms_.invmass[i * atomsPerSettle_ + 2] = 1.0 / hydrogenMass_; - mtop_.moltype[0].atoms.atom[i*atomsPerSettle_ + 0].m = oxygenMass_; - mtop_.moltype[0].atoms.atom[i*atomsPerSettle_ + 1].m = hydrogenMass_; - mtop_.moltype[0].atoms.atom[i*atomsPerSettle_ + 2].m = hydrogenMass_; + mtop_.moltype[0].atoms.atom[i * atomsPerSettle_ + 0].m = oxygenMass_; + mtop_.moltype[0].atoms.atom[i * atomsPerSettle_ + 1].m = hydrogenMass_; + mtop_.moltype[0].atoms.atom[i * atomsPerSettle_ + 2].m = hydrogenMass_; } // Reshape some data so it can be directly used by the SETTLE constraints - ilist_ = { mtop_.moltype[0].ilist[F_SETTLE].size(), 0, mtop_.moltype[0].ilist[F_SETTLE].iatoms.data(), 0 }; + ilist_ = { mtop_.moltype[0].ilist[F_SETTLE].size(), 0, + mtop_.moltype[0].ilist[F_SETTLE].iatoms.data(), 0 }; idef_.il[F_SETTLE] = ilist_; } @@ -148,5 +150,5 @@ SettleTestData::~SettleTestData() free(mdatoms_.invmass); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/settletestdata.h b/src/gromacs/mdlib/tests/settletestdata.h index ac55d5c1fb..ad07c6501b 100644 --- a/src/gromacs/mdlib/tests/settletestdata.h +++ b/src/gromacs/mdlib/tests/settletestdata.h @@ -62,50 +62,50 @@ namespace test */ class SettleTestData { - public: - //! Initial (undisturbed) positions - PaddedVector x_; - //! Updated water atom positions to constrain - PaddedVector xPrime_; - //! Water atom velocities to constrain - PaddedVector v_; - //! SETTLE virial - tensor virial_ = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; +public: + //! Initial (undisturbed) positions + PaddedVector x_; + //! Updated water atom positions to constrain + PaddedVector xPrime_; + //! Water atom velocities to constrain + PaddedVector v_; + //! SETTLE virial + tensor virial_ = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; - //! Global topology - gmx_mtop_t mtop_; - //! Atoms data - t_mdatoms mdatoms_; - //! Interactions list - t_ilist ilist_; - //! Local topology - t_idef idef_; + //! Global topology + gmx_mtop_t mtop_; + //! Atoms data + t_mdatoms mdatoms_; + //! Interactions list + t_ilist ilist_; + //! Local topology + t_idef idef_; - //! Inverse timestep - const real reciprocalTimeStep_ = 1.0/0.002; - //! Target distance between oxygen and hydrogens - const real dOH_ = 0.09572; - //! Target distance between hydrogens - const real dHH_ = 0.15139; - //! Mass of oxygen atom - const real oxygenMass_ = 15.9994; - //! Mass of hydrogen atom - const real hydrogenMass_ = 1.008; + //! Inverse timestep + const real reciprocalTimeStep_ = 1.0 / 0.002; + //! Target distance between oxygen and hydrogens + const real dOH_ = 0.09572; + //! Target distance between hydrogens + const real dHH_ = 0.15139; + //! Mass of oxygen atom + const real oxygenMass_ = 15.9994; + //! Mass of hydrogen atom + const real hydrogenMass_ = 1.008; - //! Stride for array with atom indexes - const int atomsPerSettle_ = NRAL(F_SETTLE); + //! Stride for array with atom indexes + const int atomsPerSettle_ = NRAL(F_SETTLE); - /*! \brief Construct the object and initialize the data structures. - * - * \param[in] numSettles Number of SETTLE constraints in the system. - * - */ - SettleTestData(int numSettles); + /*! \brief Construct the object and initialize the data structures. + * + * \param[in] numSettles Number of SETTLE constraints in the system. + * + */ + SettleTestData(int numSettles); - ~SettleTestData(); + ~SettleTestData(); }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_SETTLETESTDATA_H diff --git a/src/gromacs/mdlib/tests/settletestrunners.cpp b/src/gromacs/mdlib/tests/settletestrunners.cpp index 702aea84f0..88a4c1774e 100644 --- a/src/gromacs/mdlib/tests/settletestrunners.cpp +++ b/src/gromacs/mdlib/tests/settletestrunners.cpp @@ -57,41 +57,35 @@ namespace gmx namespace test { -void applySettle(SettleTestData *testData, +void applySettle(SettleTestData* testData, const t_pbc pbc, const bool updateVelocities, const bool calcVirial, - const std::string &testDescription) + const std::string& testDescription) { - settledata *settled = settle_init(testData->mtop_); + settledata* settled = settle_init(testData->mtop_); settle_set_constraints(settled, &testData->ilist_, testData->mdatoms_); bool errorOccured; int numThreads = 1; int threadIndex = 0; - csettle(settled, - numThreads, - threadIndex, - &pbc, + csettle(settled, numThreads, threadIndex, &pbc, reinterpret_cast(as_rvec_array(testData->x_.data())), - reinterpret_cast(as_rvec_array(testData->xPrime_.data())), - testData->reciprocalTimeStep_, + reinterpret_cast(as_rvec_array(testData->xPrime_.data())), testData->reciprocalTimeStep_, updateVelocities ? reinterpret_cast(as_rvec_array(testData->v_.data())) : nullptr, - calcVirial, - testData->virial_, - &errorOccured); + calcVirial, testData->virial_, &errorOccured); settle_free(settled); EXPECT_FALSE(errorOccured) << testDescription; } #if GMX_GPU != GMX_GPU_CUDA -void applySettleGpu(gmx_unused SettleTestData *testData, - gmx_unused const t_pbc pbc, - gmx_unused const bool updateVelocities, - gmx_unused const bool calcVirial, - gmx_unused const std::string &testDescription) +void applySettleGpu(gmx_unused SettleTestData* testData, + gmx_unused const t_pbc pbc, + gmx_unused const bool updateVelocities, + gmx_unused const bool calcVirial, + gmx_unused const std::string& testDescription) { FAIL() << "Dummy SETTLE GPU function was called instead of the real one in the SETTLE test."; } diff --git a/src/gromacs/mdlib/tests/settletestrunners.cu b/src/gromacs/mdlib/tests/settletestrunners.cu index a5d50f711c..e75466af86 100644 --- a/src/gromacs/mdlib/tests/settletestrunners.cu +++ b/src/gromacs/mdlib/tests/settletestrunners.cu @@ -72,15 +72,16 @@ namespace test * \param[in] calcVirial If the virial should be computed. * \param[in] testDescription Brief description that will be printed in case of test failure. */ -void applySettleGpu(SettleTestData *testData, - const t_pbc pbc, - const bool updateVelocities, - const bool calcVirial, - gmx_unused const std::string &testDescription) +void applySettleGpu(SettleTestData* testData, + const t_pbc pbc, + const bool updateVelocities, + const bool calcVirial, + gmx_unused const std::string& testDescription) { // These should never fail since this function should only be called if CUDA is enabled and // there is a CUDA-capable device available. - GMX_RELEASE_ASSERT(GMX_GPU == GMX_GPU_CUDA, "CUDA version of SETTLE was called from non-CUDA build."); + GMX_RELEASE_ASSERT(GMX_GPU == GMX_GPU_CUDA, + "CUDA version of SETTLE was called from non-CUDA build."); // TODO: Here we should check that at least 1 suitable GPU is available GMX_RELEASE_ASSERT(canPerformGpuDetection(), "Can't detect CUDA-capable GPUs."); @@ -89,17 +90,17 @@ void applySettleGpu(SettleTestData *testData, settleCuda->setPbc(&pbc); settleCuda->set(testData->idef_, testData->mdatoms_); - int numAtoms = testData->mdatoms_.homenr; + int numAtoms = testData->mdatoms_.homenr; float3 *d_x, *d_xp, *d_v; - float3 *h_x = (float3*)(as_rvec_array(testData->x_.data())); - float3 *h_xp = (float3*)(as_rvec_array(testData->xPrime_.data())); - float3 *h_v = (float3*)(as_rvec_array(testData->v_.data())); + float3* h_x = (float3*)(as_rvec_array(testData->x_.data())); + float3* h_xp = (float3*)(as_rvec_array(testData->xPrime_.data())); + float3* h_v = (float3*)(as_rvec_array(testData->v_.data())); - allocateDeviceBuffer(&d_x, numAtoms, nullptr); + allocateDeviceBuffer(&d_x, numAtoms, nullptr); allocateDeviceBuffer(&d_xp, numAtoms, nullptr); - allocateDeviceBuffer(&d_v, numAtoms, nullptr); + allocateDeviceBuffer(&d_v, numAtoms, nullptr); copyToDeviceBuffer(&d_x, (float3*)h_x, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); copyToDeviceBuffer(&d_xp, (float3*)h_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); @@ -107,9 +108,8 @@ void applySettleGpu(SettleTestData *testData, { copyToDeviceBuffer(&d_v, (float3*)h_v, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); } - settleCuda->apply(d_x, d_xp, - updateVelocities, d_v, testData->reciprocalTimeStep_, - calcVirial, testData->virial_); + settleCuda->apply(d_x, d_xp, updateVelocities, d_v, testData->reciprocalTimeStep_, calcVirial, + testData->virial_); copyFromDeviceBuffer((float3*)h_xp, &d_xp, 0, numAtoms, nullptr, GpuApiCallBehavior::Sync, nullptr); if (updateVelocities) @@ -120,7 +120,6 @@ void applySettleGpu(SettleTestData *testData, freeDeviceBuffer(&d_x); freeDeviceBuffer(&d_xp); freeDeviceBuffer(&d_v); - } } // namespace test diff --git a/src/gromacs/mdlib/tests/settletestrunners.h b/src/gromacs/mdlib/tests/settletestrunners.h index 2aba713b21..0876121375 100644 --- a/src/gromacs/mdlib/tests/settletestrunners.h +++ b/src/gromacs/mdlib/tests/settletestrunners.h @@ -56,8 +56,8 @@ namespace test /*! \brief Apply SETTLE using CPU version of the algorithm * - * Initializes SETTLE object, applies algorithm, destroys the object. The coordinates, velocities and - * virial are updated in the testData object. + * Initializes SETTLE object, applies algorithm, destroys the object. The coordinates, velocities + * and virial are updated in the testData object. * * \param[in,out] testData An object, containing all the data structures needed by SETTLE. * \param[in] pbc Periodic boundary setup. @@ -65,11 +65,11 @@ namespace test * \param[in] calcVirial If the virial should be computed. * \param[in] testDescription Brief description that will be printed in case of test failure. */ -void applySettle(SettleTestData *testData, +void applySettle(SettleTestData* testData, t_pbc pbc, bool updateVelocities, bool calcVirial, - const std::string &testDescription); + const std::string& testDescription); /*! \brief Apply SETTLE using GPU version of the algorithm * @@ -82,13 +82,13 @@ void applySettle(SettleTestData *testData, * \param[in] calcVirial If the virial should be computed. * \param[in] testDescription Brief description that will be printed in case of test failure. */ -void applySettleGpu(SettleTestData *testData, +void applySettleGpu(SettleTestData* testData, t_pbc pbc, bool updateVelocities, bool calcVirial, - const std::string &testDescription); + const std::string& testDescription); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_MDLIB_TESTS_SETTLETESTRUNNERS_H diff --git a/src/gromacs/mdlib/tests/shake.cpp b/src/gromacs/mdlib/tests/shake.cpp index 459851e17b..44e1ec8dd2 100644 --- a/src/gromacs/mdlib/tests/shake.cpp +++ b/src/gromacs/mdlib/tests/shake.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,9 +65,7 @@ const int constraintStride = 3; /*! \brief Compute the displacements between pairs of constrained * atoms described in the iatom "topology". */ -std::vector -computeDisplacements(const std::vector &iatom, - const std::vector &positions) +std::vector computeDisplacements(const std::vector& iatom, const std::vector& positions) { assert(0 == iatom.size() % constraintStride); int numConstraints = iatom.size() / constraintStride; @@ -75,12 +73,12 @@ computeDisplacements(const std::vector &iatom, for (int ll = 0; ll != numConstraints; ++ll) { - int atom_i = iatom[ll*constraintStride + 1]; - int atom_j = iatom[ll*constraintStride + 2]; + int atom_i = iatom[ll * constraintStride + 1]; + int atom_j = iatom[ll * constraintStride + 2]; for (int d = 0; d != DIM; d++) { - displacements.push_back(positions[atom_i*DIM + d] - positions[atom_j*DIM + d]); + displacements.push_back(positions[atom_i * DIM + d] - positions[atom_j * DIM + d]); } } @@ -91,17 +89,16 @@ computeDisplacements(const std::vector &iatom, * atoms in the iatom "topology". * * The reduced mass is m = 1/(1/m_i + 1/m_j)) */ -std::vector -computeHalfOfReducedMasses(const std::vector &iatom, - const std::vector &inverseMasses) +std::vector computeHalfOfReducedMasses(const std::vector& iatom, + const std::vector& inverseMasses) { int numConstraints = iatom.size() / constraintStride; std::vector halfOfReducedMasses; for (int ll = 0; ll != numConstraints; ++ll) { - int atom_i = iatom[ll*constraintStride + 1]; - int atom_j = iatom[ll*constraintStride + 2]; + int atom_i = iatom[ll * constraintStride + 1]; + int atom_j = iatom[ll * constraintStride + 2]; halfOfReducedMasses.push_back(0.5 / (inverseMasses[atom_i] + inverseMasses[atom_j])); } @@ -110,8 +107,7 @@ computeHalfOfReducedMasses(const std::vector &iatom, } /*! \brief Compute the distances corresponding to the vector of displacements components */ -std::vector -computeDistancesSquared(const std::vector &displacements) +std::vector computeDistancesSquared(const std::vector& displacements) { assert(0 == displacements.size() % DIM); int numDistancesSquared = displacements.size() / DIM; @@ -122,7 +118,7 @@ computeDistancesSquared(const std::vector &displacements) distanceSquared.push_back(0.0); for (int d = 0; d != DIM; ++d) { - real displacement = displacements[i*DIM + d]; + real displacement = displacements[i * DIM + d]; distanceSquared.back() += displacement * displacement; } } @@ -133,121 +129,120 @@ computeDistancesSquared(const std::vector &displacements) /*! \brief Test fixture for testing SHAKE */ class ShakeTest : public ::testing::Test { - public: - /*! \brief Set up data for test cases to use when constructing - their input */ - void SetUp() override - { - inverseMassesDatabase_.push_back(2.0); - inverseMassesDatabase_.push_back(3.0); - inverseMassesDatabase_.push_back(4.0); - inverseMassesDatabase_.push_back(1.0); - - positionsDatabase_.push_back(2.5); - positionsDatabase_.push_back(-3.1); - positionsDatabase_.push_back(15.7); - - positionsDatabase_.push_back(0.51); - positionsDatabase_.push_back(-3.02); - positionsDatabase_.push_back(15.55); - - positionsDatabase_.push_back(-0.5); - positionsDatabase_.push_back(-3.0); - positionsDatabase_.push_back(15.2); - - positionsDatabase_.push_back(-1.51); - positionsDatabase_.push_back(-2.95); - positionsDatabase_.push_back(15.05); - } +public: + /*! \brief Set up data for test cases to use when constructing + their input */ + void SetUp() override + { + inverseMassesDatabase_.push_back(2.0); + inverseMassesDatabase_.push_back(3.0); + inverseMassesDatabase_.push_back(4.0); + inverseMassesDatabase_.push_back(1.0); + + positionsDatabase_.push_back(2.5); + positionsDatabase_.push_back(-3.1); + positionsDatabase_.push_back(15.7); + + positionsDatabase_.push_back(0.51); + positionsDatabase_.push_back(-3.02); + positionsDatabase_.push_back(15.55); + + positionsDatabase_.push_back(-0.5); + positionsDatabase_.push_back(-3.0); + positionsDatabase_.push_back(15.2); + + positionsDatabase_.push_back(-1.51); + positionsDatabase_.push_back(-2.95); + positionsDatabase_.push_back(15.05); + } - //! Run the test - void runTest(size_t gmx_unused numAtoms, - size_t numConstraints, - const std::vector &iatom, - const std::vector &constrainedDistances, - const std::vector &inverseMasses, - const std::vector &positions) + //! Run the test + void runTest(size_t gmx_unused numAtoms, + size_t numConstraints, + const std::vector& iatom, + const std::vector& constrainedDistances, + const std::vector& inverseMasses, + const std::vector& positions) + { + // Check the test input is consistent + assert(numConstraints * constraintStride == iatom.size()); + assert(numConstraints == constrainedDistances.size()); + assert(numAtoms == inverseMasses.size()); + assert(numAtoms * DIM == positions.size()); + for (size_t i = 0; i != numConstraints; ++i) { - // Check the test input is consistent - assert(numConstraints * constraintStride == iatom.size()); - assert(numConstraints == constrainedDistances.size()); - assert(numAtoms == inverseMasses.size()); - assert(numAtoms * DIM == positions.size()); - for (size_t i = 0; i != numConstraints; ++i) + for (size_t j = 1; j < 3; j++) { - for (size_t j = 1; j < 3; j++) - { - // Check that the topology refers to atoms that have masses and positions - assert(iatom[i*constraintStride + j] >= 0); - assert(iatom[i*constraintStride + j] < static_cast(numAtoms)); - } + // Check that the topology refers to atoms that have masses and positions + assert(iatom[i * constraintStride + j] >= 0); + assert(iatom[i * constraintStride + j] < static_cast(numAtoms)); } - std::vector distanceSquaredTolerances; - std::vector lagrangianValues; - std::vector constrainedDistancesSquared; + } + std::vector distanceSquaredTolerances; + std::vector lagrangianValues; + std::vector constrainedDistancesSquared; - real coordMax = 0; - for (size_t i = 0; i != numConstraints; ++i) - { - constrainedDistancesSquared.push_back(constrainedDistances[i] * constrainedDistances[i]); - distanceSquaredTolerances.push_back(0.5 / (constrainedDistancesSquared.back() * ShakeTest::tolerance_)); - lagrangianValues.push_back(0.0); + real coordMax = 0; + for (size_t i = 0; i != numConstraints; ++i) + { + constrainedDistancesSquared.push_back(constrainedDistances[i] * constrainedDistances[i]); + distanceSquaredTolerances.push_back( + 0.5 / (constrainedDistancesSquared.back() * ShakeTest::tolerance_)); + lagrangianValues.push_back(0.0); - for (size_t j = 1; j < constraintStride; j++) + for (size_t j = 1; j < constraintStride; j++) + { + for (int d = 0; d < DIM; d++) { - for (int d = 0; d < DIM; d++) - { - coordMax = std::max(coordMax, std::abs(positions[iatom[i*constraintStride + j]*DIM + d])); - } + coordMax = std::max( + coordMax, std::abs(positions[iatom[i * constraintStride + j] * DIM + d])); } } - std::vector halfOfReducedMasses = computeHalfOfReducedMasses(iatom, inverseMasses); - std::vector initialDisplacements = computeDisplacements(iatom, positions); - - std::vector finalPositions = positions; - int numIterations = 0; - int numErrors = 0; - - cshake(iatom.data(), numConstraints, &numIterations, - ShakeTest::maxNumIterations_, constrainedDistancesSquared.data(), - finalPositions.data(), initialDisplacements.data(), - halfOfReducedMasses.data(), omega_, inverseMasses.data(), - distanceSquaredTolerances.data(), - lagrangianValues.data(), - &numErrors); - - std::vector finalDisplacements = computeDisplacements(iatom, finalPositions); - std::vector finalDistancesSquared = computeDistancesSquared(finalDisplacements); - assert(numConstraints == finalDistancesSquared.size()); - - EXPECT_EQ(0, numErrors); - EXPECT_GT(numIterations, 1); - EXPECT_LT(numIterations, ShakeTest::maxNumIterations_); - // TODO wrap this in a Google Mock matcher if there's - // other tests like it some time? - for (size_t i = 0; i != numConstraints; ++i) - { - // We need to allow for the requested tolerance plus rounding - // errors due to the absolute size of the coordinate values - test::FloatingPointTolerance constraintTolerance = - test::absoluteTolerance(std::sqrt(constrainedDistancesSquared[i])*ShakeTest::tolerance_ + coordMax*GMX_REAL_EPS); - // Assert that the constrained distances are within the required tolerance - EXPECT_FLOAT_EQ_TOL(std::sqrt(constrainedDistancesSquared[i]), - std::sqrt(finalDistancesSquared[i]), - constraintTolerance); - } } + std::vector halfOfReducedMasses = computeHalfOfReducedMasses(iatom, inverseMasses); + std::vector initialDisplacements = computeDisplacements(iatom, positions); + + std::vector finalPositions = positions; + int numIterations = 0; + int numErrors = 0; + + cshake(iatom.data(), numConstraints, &numIterations, ShakeTest::maxNumIterations_, + constrainedDistancesSquared.data(), finalPositions.data(), + initialDisplacements.data(), halfOfReducedMasses.data(), omega_, inverseMasses.data(), + distanceSquaredTolerances.data(), lagrangianValues.data(), &numErrors); + + std::vector finalDisplacements = computeDisplacements(iatom, finalPositions); + std::vector finalDistancesSquared = computeDistancesSquared(finalDisplacements); + assert(numConstraints == finalDistancesSquared.size()); + + EXPECT_EQ(0, numErrors); + EXPECT_GT(numIterations, 1); + EXPECT_LT(numIterations, ShakeTest::maxNumIterations_); + // TODO wrap this in a Google Mock matcher if there's + // other tests like it some time? + for (size_t i = 0; i != numConstraints; ++i) + { + // We need to allow for the requested tolerance plus rounding + // errors due to the absolute size of the coordinate values + test::FloatingPointTolerance constraintTolerance = + test::absoluteTolerance(std::sqrt(constrainedDistancesSquared[i]) * ShakeTest::tolerance_ + + coordMax * GMX_REAL_EPS); + // Assert that the constrained distances are within the required tolerance + EXPECT_FLOAT_EQ_TOL(std::sqrt(constrainedDistancesSquared[i]), + std::sqrt(finalDistancesSquared[i]), constraintTolerance); + } + } - //! Tolerance for SHAKE conversion (ie. shake-tol .mdp setting) - static const real tolerance_; - //! Maximum number of iterations permitted in these tests - static const int maxNumIterations_; - //! SHAKE over-relaxation (SOR) factor - static const real omega_; - //! Database of inverse masses of atoms in the topology - std::vector inverseMassesDatabase_; - //! Database of atom positions (three reals per atom) - std::vector positionsDatabase_; + //! Tolerance for SHAKE conversion (ie. shake-tol .mdp setting) + static const real tolerance_; + //! Maximum number of iterations permitted in these tests + static const int maxNumIterations_; + //! SHAKE over-relaxation (SOR) factor + static const real omega_; + //! Database of inverse masses of atoms in the topology + std::vector inverseMassesDatabase_; + //! Database of atom positions (three reals per atom) + std::vector positionsDatabase_; }; const real ShakeTest::tolerance_ = 1e-5; @@ -256,10 +251,10 @@ const real ShakeTest::omega_ = 1.0; TEST_F(ShakeTest, ConstrainsOneBond) { - int numAtoms = 2; - int numConstraints = 1; + int numAtoms = 2; + int numConstraints = 1; - std::vector iatom; + std::vector iatom; iatom.push_back(-1); // unused iatom.push_back(0); // i atom index iatom.push_back(1); // j atom index @@ -269,18 +264,17 @@ TEST_F(ShakeTest, ConstrainsOneBond) std::vector inverseMasses(inverseMassesDatabase_.begin(), inverseMassesDatabase_.begin() + numAtoms); - std::vector positions(positionsDatabase_.begin(), - positionsDatabase_.begin() + numAtoms * DIM); + std::vector positions(positionsDatabase_.begin(), positionsDatabase_.begin() + numAtoms * DIM); runTest(numAtoms, numConstraints, iatom, constrainedDistances, inverseMasses, positions); } TEST_F(ShakeTest, ConstrainsTwoDisjointBonds) { - int numAtoms = 4; - int numConstraints = 2; + int numAtoms = 4; + int numConstraints = 2; - std::vector iatom; + std::vector iatom; iatom.push_back(-1); // unused iatom.push_back(0); // i atom index iatom.push_back(1); // j atom index @@ -295,18 +289,17 @@ TEST_F(ShakeTest, ConstrainsTwoDisjointBonds) std::vector inverseMasses(inverseMassesDatabase_.begin(), inverseMassesDatabase_.begin() + numAtoms); - std::vector positions(positionsDatabase_.begin(), - positionsDatabase_.begin() + numAtoms * DIM); + std::vector positions(positionsDatabase_.begin(), positionsDatabase_.begin() + numAtoms * DIM); runTest(numAtoms, numConstraints, iatom, constrainedDistances, inverseMasses, positions); } TEST_F(ShakeTest, ConstrainsTwoBondsWithACommonAtom) { - int numAtoms = 3; - int numConstraints = 2; + int numAtoms = 3; + int numConstraints = 2; - std::vector iatom; + std::vector iatom; iatom.push_back(-1); // unused iatom.push_back(0); // i atom index iatom.push_back(1); // j atom index @@ -321,18 +314,17 @@ TEST_F(ShakeTest, ConstrainsTwoBondsWithACommonAtom) std::vector inverseMasses(inverseMassesDatabase_.begin(), inverseMassesDatabase_.begin() + numAtoms); - std::vector positions(positionsDatabase_.begin(), - positionsDatabase_.begin() + numAtoms * DIM); + std::vector positions(positionsDatabase_.begin(), positionsDatabase_.begin() + numAtoms * DIM); runTest(numAtoms, numConstraints, iatom, constrainedDistances, inverseMasses, positions); } TEST_F(ShakeTest, ConstrainsThreeBondsWithCommonAtoms) { - int numAtoms = 4; - int numConstraints = 3; + int numAtoms = 4; + int numConstraints = 3; - std::vector iatom; + std::vector iatom; iatom.push_back(-1); // unused iatom.push_back(0); // i atom index iatom.push_back(1); // j atom index @@ -352,8 +344,7 @@ TEST_F(ShakeTest, ConstrainsThreeBondsWithCommonAtoms) std::vector inverseMasses(inverseMassesDatabase_.begin(), inverseMassesDatabase_.begin() + numAtoms); - std::vector positions(positionsDatabase_.begin(), - positionsDatabase_.begin() + numAtoms * DIM); + std::vector positions(positionsDatabase_.begin(), positionsDatabase_.begin() + numAtoms * DIM); runTest(numAtoms, numConstraints, iatom, constrainedDistances, inverseMasses, positions); } diff --git a/src/gromacs/mdlib/tests/simulationsignal.cpp b/src/gromacs/mdlib/tests/simulationsignal.cpp index 20e718d92d..2ff56dfba6 100644 --- a/src/gromacs/mdlib/tests/simulationsignal.cpp +++ b/src/gromacs/mdlib/tests/simulationsignal.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,14 +64,14 @@ TEST(NullSignalTest, NullSignallerWorks) //! Test fixture for mdrun signalling class SignalTest : public ::testing::Test { - public: - SignalTest() : signals_ {} - { - signals_[0].sig = 1; - signals_[1].sig = -1; - } - //! Default object to hold signals - SimulationSignals signals_; +public: + SignalTest() : signals_{} + { + signals_[0].sig = 1; + signals_[1].sig = -1; + } + //! Default object to hold signals + SimulationSignals signals_; }; TEST_F(SignalTest, NoSignalPropagatesIfNoSignallingTakesPlace) @@ -172,5 +172,5 @@ TEST_F(SignalTest, NonLocalSignalPropagatesWhenBothTakePlace) EXPECT_EQ(0, signals_[2].set); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/updategroups.cpp b/src/gromacs/mdlib/tests/updategroups.cpp index 49cabf1c05..ff2c420f3a 100644 --- a/src/gromacs/mdlib/tests/updategroups.cpp +++ b/src/gromacs/mdlib/tests/updategroups.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,12 +74,7 @@ gmx_moltype_t methane() gmx_moltype_t moltype = {}; moltype.atoms.nr = 5; - moltype.ilist[F_CONSTR].iatoms = { - 0, 0, 1, - 0, 0, 2, - 0, 0, 3, - 0, 0, 4 - }; + moltype.ilist[F_CONSTR].iatoms = { 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4 }; return moltype; } @@ -90,22 +85,9 @@ gmx_moltype_t ethane() gmx_moltype_t moltype = {}; moltype.atoms.nr = 8; - moltype.ilist[F_CONSTR].iatoms = { - 0, 0, 1, - 0, 0, 2, - 0, 0, 3, - 0, 4, 5, - 0, 4, 6, - 0, 4, 7 - }; - moltype.ilist[F_ANGLES].iatoms = { - 1, 1, 0, 2, - 1, 1, 0, 3, - 1, 2, 0, 3, - 1, 5, 4, 6, - 1, 5, 4, 7, - 1, 6, 4, 7 - }; + moltype.ilist[F_CONSTR].iatoms = { 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 4, 5, 0, 4, 6, 0, 4, 7 }; + moltype.ilist[F_ANGLES].iatoms = { 1, 1, 0, 2, 1, 1, 0, 3, 1, 2, 0, 3, + 1, 5, 4, 6, 1, 5, 4, 7, 1, 6, 4, 7 }; return moltype; } @@ -116,11 +98,7 @@ gmx_moltype_t butaneUA() gmx_moltype_t moltype = {}; moltype.atoms.nr = 4; - moltype.ilist[F_CONSTR].iatoms = { - 0, 0, 1, - 0, 1, 2, - 0, 2, 3 - }; + moltype.ilist[F_CONSTR].iatoms = { 0, 0, 1, 0, 1, 2, 0, 2, 3 }; return moltype; } @@ -131,7 +109,7 @@ gmx_moltype_t waterThreeSite() gmx_moltype_t moltype = {}; moltype.atoms.nr = 3; - moltype.ilist[F_SETTLE].iatoms = { 0, 0, 1, 2}; + moltype.ilist[F_SETTLE].iatoms = { 0, 0, 1, 2 }; return moltype; } @@ -143,7 +121,7 @@ gmx_moltype_t waterFourSite() moltype.atoms.nr = 4; moltype.ilist[F_SETTLE].iatoms = { 0, 1, 2, 3 }; - moltype.ilist[F_VSITE3].iatoms = { 1, 0, 1, 2, 3}; + moltype.ilist[F_VSITE3].iatoms = { 1, 0, 1, 2, 3 }; return moltype; } @@ -155,11 +133,13 @@ gmx_moltype_t waterFlexAngle() moltype.atoms.nr = 3; moltype.ilist[F_CONSTR].iatoms = { - 0, 0, 1, - 0, 0, 2, + 0, 0, 1, 0, 0, 2, }; moltype.ilist[F_ANGLES].iatoms = { - 1, 1, 0, 2, + 1, + 1, + 0, + 2, }; return moltype; @@ -171,7 +151,7 @@ TEST(UpdateGroups, ethaneUA) mtop.moltype.emplace_back(ethaneUA()); t_iparams iparams; - iparams.constr = { 0.3, 0.3 }; + iparams.constr = { 0.3, 0.3 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -181,7 +161,7 @@ TEST(UpdateGroups, ethaneUA) real temperature = 298; real maxRadius = computeMaxUpdateGroupRadius(mtop, updateGroups, temperature); - EXPECT_FLOAT_EQ(maxRadius, 0.3/2); + EXPECT_FLOAT_EQ(maxRadius, 0.3 / 2); } TEST(UpdateGroups, methane) @@ -190,7 +170,7 @@ TEST(UpdateGroups, methane) mtop.moltype.emplace_back(methane()); t_iparams iparams; - iparams.constr = { 0.1, 0.1 }; + iparams.constr = { 0.1, 0.1 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -208,9 +188,9 @@ TEST(UpdateGroups, ethane) mtop.moltype.emplace_back(ethane()); t_iparams iparams; - iparams.constr = { 0.1, 0.1 }; + iparams.constr = { 0.1, 0.1 }; mtop.ffparams.iparams.push_back(iparams); - iparams.harmonic = { 107.800, 276.144, 107.800, 276.144 }; + iparams.harmonic = { 107.800, 276.144, 107.800, 276.144 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -237,7 +217,7 @@ TEST(UpdateGroups, butaneUA) mtop.moltype.emplace_back(butaneUA()); t_iparams iparams; - iparams.constr = { 0.3, 0.3 }; + iparams.constr = { 0.3, 0.3 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -251,7 +231,7 @@ TEST(UpdateGroups, waterThreeSite) mtop.moltype.emplace_back(waterThreeSite()); t_iparams iparams; - iparams.settle = { 0.1, 0.1633 }; + iparams.settle = { 0.1, 0.1633 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -271,8 +251,8 @@ TEST(UpdateGroups, waterFourSite) mtop.moltype.emplace_back(waterFourSite()); t_iparams iparams[2]; - iparams[0].settle = { 0.1, 0.1633 }; - iparams[1].vsite = { 0.128, 0.128 }; + iparams[0].settle = { 0.1, 0.1633 }; + iparams[1].vsite = { 0.128, 0.128 }; mtop.ffparams.iparams.push_back(iparams[0]); mtop.ffparams.iparams.push_back(iparams[1]); @@ -302,9 +282,9 @@ TEST(UpdateGroups, waterFlexAngle) mtop.moltype.emplace_back(waterFlexAngle()); t_iparams iparams; - iparams.constr = { 0.1, 0.1 }; + iparams.constr = { 0.1, 0.1 }; mtop.ffparams.iparams.push_back(iparams); - iparams.harmonic = { 109.47, 383.0, 109.47, 383.0 }; + iparams.harmonic = { 109.47, 383.0, 109.47, 383.0 }; mtop.ffparams.iparams.push_back(iparams); auto updateGroups = gmx::makeUpdateGroups(mtop); @@ -331,7 +311,7 @@ TEST(UpdateGroups, twoMoltypes) mtop.moltype.emplace_back(methane()); t_iparams iparams; - iparams.constr = { 0.1, 0.1 }; + iparams.constr = { 0.1, 0.1 }; mtop.ffparams.iparams.push_back(iparams); mtop.moltype.emplace_back(waterThreeSite()); @@ -344,6 +324,6 @@ TEST(UpdateGroups, twoMoltypes) EXPECT_EQ(updateGroups[1].numBlocks(), 1); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/updategroupscog.cpp b/src/gromacs/mdlib/tests/updategroupscog.cpp index 309759e85c..ab21b65fd4 100644 --- a/src/gromacs/mdlib/tests/updategroupscog.cpp +++ b/src/gromacs/mdlib/tests/updategroupscog.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,59 +57,23 @@ namespace { //! Database of 51 water atom input positions (taken from spc216.gro) for use as test inputs. -gmx::RVec positions[] = { - { .130, -.041, -.291 }, - { .120, -.056, -.192 }, - { .044, -.005, -.327 }, - { -.854, -.406, .477 }, - { -.900, -.334, .425 }, - { -.858, -.386, .575 }, - { .351, -.061, .853 }, - { .401, -.147, .859 }, - { .416, .016, .850 }, - { -.067, -.796, .873 }, - { -.129, -.811, .797 }, - { -.119, -.785, .958 }, - { -.635, -.312, -.356 }, - { -.629, -.389, -.292 }, - { -.687, -.338, -.436 }, - { .321, -.919, .242 }, - { .403, -.880, .200 }, - { .294, -1.001, .193 }, - { -.404, .735, .728 }, - { -.409, .670, .803 }, - { -.324, .794, .741 }, - { .461, -.596, -.135 }, - { .411, -.595, -.221 }, - { .398, -.614, -.059 }, - { -.751, -.086, .237 }, - { -.811, -.148, .287 }, - { -.720, -.130, .152 }, - { .202, .285, -.364 }, - { .122, .345, -.377 }, - { .192, .236, -.278 }, - { -.230, -.485, .081 }, - { -.262, -.391, .071 }, - { -.306, -.548, .069 }, - { .464, -.119, .323 }, - { .497, -.080, .409 }, - { .540, -.126, .258 }, - { -.462, .107, .426 }, - { -.486, .070, .336 }, - { -.363, .123, .430 }, - { .249, -.077, -.621 }, - { .306, -.142, -.571 }, - { .233, -.110, -.714 }, - { -.922, -.164, .904 }, - { -.842, -.221, .925 }, - { -.971, -.204, .827 }, - { .382, .700, .480 }, - { .427, .610, .477 }, - { .288, .689, .513 }, - { .781, .264, -.113 }, - { .848, .203, -.070 }, - { .708, .283, -.048 } -}; +gmx::RVec positions[] = { { .130, -.041, -.291 }, { .120, -.056, -.192 }, { .044, -.005, -.327 }, + { -.854, -.406, .477 }, { -.900, -.334, .425 }, { -.858, -.386, .575 }, + { .351, -.061, .853 }, { .401, -.147, .859 }, { .416, .016, .850 }, + { -.067, -.796, .873 }, { -.129, -.811, .797 }, { -.119, -.785, .958 }, + { -.635, -.312, -.356 }, { -.629, -.389, -.292 }, { -.687, -.338, -.436 }, + { .321, -.919, .242 }, { .403, -.880, .200 }, { .294, -1.001, .193 }, + { -.404, .735, .728 }, { -.409, .670, .803 }, { -.324, .794, .741 }, + { .461, -.596, -.135 }, { .411, -.595, -.221 }, { .398, -.614, -.059 }, + { -.751, -.086, .237 }, { -.811, -.148, .287 }, { -.720, -.130, .152 }, + { .202, .285, -.364 }, { .122, .345, -.377 }, { .192, .236, -.278 }, + { -.230, -.485, .081 }, { -.262, -.391, .071 }, { -.306, -.548, .069 }, + { .464, -.119, .323 }, { .497, -.080, .409 }, { .540, -.126, .258 }, + { -.462, .107, .426 }, { -.486, .070, .336 }, { -.363, .123, .430 }, + { .249, -.077, -.621 }, { .306, -.142, -.571 }, { .233, -.110, -.714 }, + { -.922, -.164, .904 }, { -.842, -.221, .925 }, { -.971, -.204, .827 }, + { .382, .700, .480 }, { .427, .610, .477 }, { .288, .689, .513 }, + { .781, .264, -.113 }, { .848, .203, -.070 }, { .708, .283, -.048 } }; TEST(UpdateGroupsCog, ComputesCogs) { @@ -119,11 +83,11 @@ TEST(UpdateGroupsCog, ComputesCogs) const int numMolecules = gmx::exactDiv(numAtoms, atomsPerSettle); // Set up the topology. - gmx_mtop_t mtop; + gmx_mtop_t mtop; - gmx_moltype_t moltype; + gmx_moltype_t moltype; moltype.atoms.nr = atomsPerSettle; - std::vector &iatoms = moltype.ilist[F_SETTLE].iatoms; + std::vector& iatoms = moltype.ilist[F_SETTLE].iatoms; iatoms.push_back(settleType); iatoms.push_back(0); iatoms.push_back(1); @@ -137,16 +101,16 @@ TEST(UpdateGroupsCog, ComputesCogs) gmx_mtop_finalize(&mtop); // Set up the SETTLE parameters. - const real dOH = 0.1; - const real dHH = 0.1633; - t_iparams iparams; + const real dOH = 0.1; + const real dHH = 0.1633; + t_iparams iparams; iparams.settle.doh = dOH; iparams.settle.dhh = dHH; mtop.ffparams.iparams.push_back(iparams); // Run the test - auto updateGroups = makeUpdateGroups(mtop); - real temperature = 300; + auto updateGroups = makeUpdateGroups(mtop); + real temperature = 300; UpdateGroupsCog updateGroupsCog(mtop, updateGroups, temperature, numAtoms); @@ -187,5 +151,5 @@ TEST(UpdateGroupsCog, ComputesCogs) EXPECT_EQ(updateGroupsCog.numCogs(), 0); } -} // namespace -} // namespace gmx +} // namespace +} // namespace gmx diff --git a/src/gromacs/mdlib/tests/watersystem.h b/src/gromacs/mdlib/tests/watersystem.h index 29473b9ccd..bdab3ff7da 100644 --- a/src/gromacs/mdlib/tests/watersystem.h +++ b/src/gromacs/mdlib/tests/watersystem.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,60 +43,24 @@ namespace test //! Database of 51 water atom input positions (taken from spc216.gro) for use as test inputs. static const std::array c_waterPositions( - { { - { .130, -.041, -.291 }, - { .120, -.056, -.192 }, - { .044, -.005, -.327 }, - { -.854, -.406, .477 }, - { -.900, -.334, .425 }, - { -.858, -.386, .575 }, - { .351, -.061, .853 }, - { .401, -.147, .859 }, - { .416, .016, .850 }, - { -.067, -.796, .873 }, - { -.129, -.811, .797 }, - { -.119, -.785, .958 }, - { -.635, -.312, -.356 }, - { -.629, -.389, -.292 }, - { -.687, -.338, -.436 }, - { .321, -.919, .242 }, - { .403, -.880, .200 }, - { .294, -1.001, .193 }, - { -.404, .735, .728 }, - { -.409, .670, .803 }, - { -.324, .794, .741 }, - { .461, -.596, -.135 }, - { .411, -.595, -.221 }, - { .398, -.614, -.059 }, - { -.751, -.086, .237 }, - { -.811, -.148, .287 }, - { -.720, -.130, .152 }, - { .202, .285, -.364 }, - { .122, .345, -.377 }, - { .192, .236, -.278 }, - { -.230, -.485, .081 }, - { -.262, -.391, .071 }, - { -.306, -.548, .069 }, - { .464, -.119, .323 }, - { .497, -.080, .409 }, - { .540, -.126, .258 }, - { -.462, .107, .426 }, - { -.486, .070, .336 }, - { -.363, .123, .430 }, - { .249, -.077, -.621 }, - { .306, -.142, -.571 }, - { .233, -.110, -.714 }, - { -.922, -.164, .904 }, - { -.842, -.221, .925 }, - { -.971, -.204, .827 }, - { .382, .700, .480 }, - { .427, .610, .477 }, - { .288, .689, .513 }, - { .781, .264, -.113 }, - { .848, .203, -.070 }, - { .708, .283, -.048 } - } }); + { { { .130, -.041, -.291 }, { .120, -.056, -.192 }, { .044, -.005, -.327 }, + { -.854, -.406, .477 }, { -.900, -.334, .425 }, { -.858, -.386, .575 }, + { .351, -.061, .853 }, { .401, -.147, .859 }, { .416, .016, .850 }, + { -.067, -.796, .873 }, { -.129, -.811, .797 }, { -.119, -.785, .958 }, + { -.635, -.312, -.356 }, { -.629, -.389, -.292 }, { -.687, -.338, -.436 }, + { .321, -.919, .242 }, { .403, -.880, .200 }, { .294, -1.001, .193 }, + { -.404, .735, .728 }, { -.409, .670, .803 }, { -.324, .794, .741 }, + { .461, -.596, -.135 }, { .411, -.595, -.221 }, { .398, -.614, -.059 }, + { -.751, -.086, .237 }, { -.811, -.148, .287 }, { -.720, -.130, .152 }, + { .202, .285, -.364 }, { .122, .345, -.377 }, { .192, .236, -.278 }, + { -.230, -.485, .081 }, { -.262, -.391, .071 }, { -.306, -.548, .069 }, + { .464, -.119, .323 }, { .497, -.080, .409 }, { .540, -.126, .258 }, + { -.462, .107, .426 }, { -.486, .070, .336 }, { -.363, .123, .430 }, + { .249, -.077, -.621 }, { .306, -.142, -.571 }, { .233, -.110, -.714 }, + { -.922, -.164, .904 }, { -.842, -.221, .925 }, { -.971, -.204, .827 }, + { .382, .700, .480 }, { .427, .610, .477 }, { .288, .689, .513 }, + { .781, .264, -.113 }, { .848, .203, -.070 }, { .708, .283, -.048 } } }); -} // namespace test +} // namespace test -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/tgroup.cpp b/src/gromacs/mdlib/tgroup.cpp index 34672750ac..22cb5fa1f7 100644 --- a/src/gromacs/mdlib/tgroup.cpp +++ b/src/gromacs/mdlib/tgroup.cpp @@ -56,14 +56,14 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void init_grpstat(const gmx_mtop_t *mtop, int ngacc, t_grp_acc gstat[]) +static void init_grpstat(const gmx_mtop_t* mtop, int ngacc, t_grp_acc gstat[]) { if (ngacc > 0) { - const SimulationGroups &groups = mtop->groups; + const SimulationGroups& groups = mtop->groups; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); int grp = getGroupType(groups, SimulationAtomGroupType::Acceleration, i); if ((grp < 0) && (grp >= ngacc)) @@ -78,8 +78,11 @@ static void init_grpstat(const gmx_mtop_t *mtop, int ngacc, t_grp_acc gstat[]) } } -void init_ekindata(FILE gmx_unused *log, const gmx_mtop_t *mtop, const t_grpopts *opts, - gmx_ekindata_t *ekind, real cos_accel) +void init_ekindata(FILE gmx_unused* log, + const gmx_mtop_t* mtop, + const t_grpopts* opts, + gmx_ekindata_t* ekind, + real cos_accel) { int i; @@ -119,7 +122,7 @@ void init_ekindata(FILE gmx_unused *log, const gmx_mtop_t *mtop, const t_grpopts * EKIN_WORK_BUFFER_SIZE*DIM*DIM*sizeof(real) = 72/144 bytes * buffer on both sides to avoid cache pollution. */ - snew(ekind->ekin_work_alloc[thread], ekind->ngtc+2*EKIN_WORK_BUFFER_SIZE); + snew(ekind->ekin_work_alloc[thread], ekind->ngtc + 2 * EKIN_WORK_BUFFER_SIZE); ekind->ekin_work[thread] = ekind->ekin_work_alloc[thread] + EKIN_WORK_BUFFER_SIZE; /* Nasty hack so we can have the per-thread accumulation * variable for dekindl in the same thread-local cache lines @@ -128,7 +131,7 @@ void init_ekindata(FILE gmx_unused *log, const gmx_mtop_t *mtop, const t_grpopts ekind->dekindl_work[thread] = &(ekind->ekin_work[thread][ekind->ngtc][0][0]); #undef EKIN_WORK_BUFFER_SIZE } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } ekind->ngacc = opts->ngacc; @@ -138,10 +141,10 @@ void init_ekindata(FILE gmx_unused *log, const gmx_mtop_t *mtop, const t_grpopts ekind->cosacc.cos_accel = cos_accel; } -void accumulate_u(const t_commrec *cr, const t_grpopts *opts, gmx_ekindata_t *ekind) +void accumulate_u(const t_commrec* cr, const t_grpopts* opts, gmx_ekindata_t* ekind) { /* This routine will only be called when it's necessary */ - t_bin *rb; + t_bin* rb; int g; rb = mk_bin(); @@ -154,13 +157,18 @@ void accumulate_u(const t_commrec *cr, const t_grpopts *opts, gmx_ekindata_t *ek for (g = 0; (g < opts->ngacc); g++) { - extract_binr(rb, DIM*g, DIM, ekind->grpstat[g].u); + extract_binr(rb, DIM * g, DIM, ekind->grpstat[g].u); } destroy_bin(rb); } -void update_ekindata(int start, int homenr, gmx_ekindata_t *ekind, - const t_grpopts *opts, const rvec v[], const t_mdatoms *md, real lambda) +void update_ekindata(int start, + int homenr, + gmx_ekindata_t* ekind, + const t_grpopts* opts, + const rvec v[], + const t_mdatoms* md, + real lambda) { int d, g, n; real mv; @@ -179,7 +187,7 @@ void update_ekindata(int start, int homenr, gmx_ekindata_t *ekind, } g = 0; - for (n = start; (n < start+homenr); n++) + for (n = start; (n < start + homenr); n++) { if (md->cACC) { @@ -187,7 +195,7 @@ void update_ekindata(int start, int homenr, gmx_ekindata_t *ekind, } for (d = 0; (d < DIM); d++) { - mv = md->massT[n]*v[n][d]; + mv = md->massT[n] * v[n][d]; ekind->grpstat[g].u[d] += mv; } } @@ -197,18 +205,17 @@ void update_ekindata(int start, int homenr, gmx_ekindata_t *ekind, for (d = 0; (d < DIM); d++) { ekind->grpstat[g].u[d] /= - (1-lambda)*ekind->grpstat[g].mA + lambda*ekind->grpstat[g].mB; + (1 - lambda) * ekind->grpstat[g].mA + lambda * ekind->grpstat[g].mB; } } } } -real sum_ekin(const t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, - gmx_bool bEkinAveVel, gmx_bool bScaleEkin) +real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinAveVel, gmx_bool bScaleEkin) { int i, j, m, ngtc; real T; - t_grp_tcstat *tcstat; + t_grp_tcstat* tcstat; real nrdf, nd, *ndf; ngtc = opts->ngtc; @@ -247,8 +254,9 @@ real sum_ekin(const t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, { for (m = 0; (m < DIM); m++) { - tcstat->ekinf[j][m] = - 0.5*(tcstat->ekinh[j][m]*tcstat->ekinscaleh_nhc + tcstat->ekinh_old[j][m]); + tcstat->ekinf[j][m] = 0.5 + * (tcstat->ekinh[j][m] * tcstat->ekinscaleh_nhc + + tcstat->ekinh_old[j][m]); } } } @@ -272,7 +280,7 @@ real sum_ekin(const t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, tcstat->T = 0; tcstat->Th = 0; } - T += nd*tcstat->T; + T += nd * tcstat->T; nrdf += nd; } if (nrdf > 0) @@ -287,7 +295,7 @@ real sum_ekin(const t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, } else { - *dekindlambda = 0.5*(ekind->dekindl + ekind->dekindl_old); + *dekindlambda = 0.5 * (ekind->dekindl + ekind->dekindl_old); } } return T; diff --git a/src/gromacs/mdlib/tgroup.h b/src/gromacs/mdlib/tgroup.h index 274b077914..11349251dc 100644 --- a/src/gromacs/mdlib/tgroup.h +++ b/src/gromacs/mdlib/tgroup.h @@ -49,30 +49,30 @@ struct t_commrec; struct t_grpopts; struct t_mdatoms; -void init_ekindata(FILE *log, const gmx_mtop_t *mtop, - const t_grpopts *opts, - gmx_ekindata_t *ekind, - real cos_accel); +void init_ekindata(FILE* log, const gmx_mtop_t* mtop, const t_grpopts* opts, gmx_ekindata_t* ekind, real cos_accel); /* Allocate memory and set the grpnr array. */ -void done_ekindata(gmx_ekindata_t *ekind); +void done_ekindata(gmx_ekindata_t* ekind); /* Free the memory */ -void accumulate_u(const t_commrec *cr, const t_grpopts *opts, - gmx_ekindata_t *ekind); +void accumulate_u(const t_commrec* cr, const t_grpopts* opts, gmx_ekindata_t* ekind); /* Communicate subsystem - group velocities and subsystem ekin respectively * and sum them up. Return them in grps. */ -real sum_ekin(const t_grpopts *opts, gmx_ekindata_t *ekind, real *dekindlambda, - gmx_bool bEkinFullStep, gmx_bool bScaleEkin); +real sum_ekin(const t_grpopts* opts, gmx_ekindata_t* ekind, real* dekindlambda, gmx_bool bEkinFullStep, gmx_bool bScaleEkin); /* Sum the group ekins into total ekin and calc temp per group, * return total temperature. */ -void update_ekindata(int start, int homenr, gmx_ekindata_t *ekind, - const t_grpopts *opts, const rvec v[], const t_mdatoms *md, real lambda); +void update_ekindata(int start, + int homenr, + gmx_ekindata_t* ekind, + const t_grpopts* opts, + const rvec v[], + const t_mdatoms* md, + real lambda); /* Do the update of group velocities (if bNEMD) and * (partial) group ekin. */ diff --git a/src/gromacs/mdlib/trajectory_writing.cpp b/src/gromacs/mdlib/trajectory_writing.cpp index 8a02921e13..dc2cc747fc 100644 --- a/src/gromacs/mdlib/trajectory_writing.cpp +++ b/src/gromacs/mdlib/trajectory_writing.cpp @@ -53,33 +53,31 @@ #include "gromacs/topology/topology.h" #include "gromacs/utility/smalloc.h" -void -do_md_trajectory_writing(FILE *fplog, - t_commrec *cr, - int nfile, - const t_filenm fnm[], - int64_t step, - int64_t step_rel, - double t, - t_inputrec *ir, - t_state *state, - t_state *state_global, - ObservablesHistory *observablesHistory, - const gmx_mtop_t *top_global, - t_forcerec *fr, - gmx_mdoutf_t outf, - const gmx::EnergyOutput &energyOutput, - gmx_ekindata_t *ekind, - gmx::ArrayRef f, - gmx_bool bCPT, - gmx_bool bRerunMD, - gmx_bool bLastStep, - gmx_bool bDoConfOut, - gmx_bool bSumEkinhOld - ) +void do_md_trajectory_writing(FILE* fplog, + t_commrec* cr, + int nfile, + const t_filenm fnm[], + int64_t step, + int64_t step_rel, + double t, + t_inputrec* ir, + t_state* state, + t_state* state_global, + ObservablesHistory* observablesHistory, + const gmx_mtop_t* top_global, + t_forcerec* fr, + gmx_mdoutf_t outf, + const gmx::EnergyOutput& energyOutput, + gmx_ekindata_t* ekind, + gmx::ArrayRef f, + gmx_bool bCPT, + gmx_bool bRerunMD, + gmx_bool bLastStep, + gmx_bool bDoConfOut, + gmx_bool bSumEkinhOld) { int mdof_flags; - rvec *x_for_confout = nullptr; + rvec* x_for_confout = nullptr; mdof_flags = 0; if (do_per_step(step, ir->nstxout)) @@ -127,12 +125,12 @@ do_md_trajectory_writing(FILE *fplog, } if (MASTER(cr)) { - fcReportProgress( ir->nsteps, step ); + fcReportProgress(ir->nsteps, step); } -#if defined(__native_client__) +# if defined(__native_client__) fcCheckin(MASTER(cr)); -#endif +# endif /* sync bCPT and fc record-keeping */ if (bCPT && MASTER(cr)) @@ -161,11 +159,9 @@ do_md_trajectory_writing(FILE *fplog, energyOutput.fillEnergyHistory(observablesHistory->energyHistory.get()); } } - mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, - step, t, state, state_global, observablesHistory, f); - if (bLastStep && step_rel == ir->nsteps && - bDoConfOut && MASTER(cr) && - !bRerunMD) + mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step, t, + state, state_global, observablesHistory, f); + if (bLastStep && step_rel == ir->nsteps && bDoConfOut && MASTER(cr) && !bRerunMD) { if (fr->bMolPBC && state == state_global) { @@ -196,10 +192,8 @@ do_md_trajectory_writing(FILE *fplog, /* Make molecules whole only for confout writing */ do_pbc_mtop(ir->ePBC, state->box, top_global, x_for_confout); } - write_sto_conf_mtop(ftp2fn(efSTO, nfile, fnm), - *top_global->name, top_global, - x_for_confout, state_global->v.rvec_array(), - ir->ePBC, state->box); + write_sto_conf_mtop(ftp2fn(efSTO, nfile, fnm), *top_global->name, top_global, + x_for_confout, state_global->v.rvec_array(), ir->ePBC, state->box); if (fr->bMolPBC && state == state_global) { sfree(x_for_confout); diff --git a/src/gromacs/mdlib/trajectory_writing.h b/src/gromacs/mdlib/trajectory_writing.h index 01cebcc02c..d49614100b 100644 --- a/src/gromacs/mdlib/trajectory_writing.h +++ b/src/gromacs/mdlib/trajectory_writing.h @@ -59,30 +59,28 @@ class EnergyOutput; * * This routine does communication (e.g. collecting distributed coordinates) */ -void -do_md_trajectory_writing(FILE *fplog, - struct t_commrec *cr, - int nfile, - const t_filenm fnm[], - int64_t step, - int64_t step_rel, - double t, - t_inputrec *ir, - t_state *state, - t_state *state_global, - ObservablesHistory *observablesHistory, - const gmx_mtop_t *top_global, - t_forcerec *fr, - gmx_mdoutf_t outf, - const gmx::EnergyOutput &energyOutput, - gmx_ekindata_t *ekind, - gmx::ArrayRef f, - gmx_bool bCPT, - gmx_bool bRerunMD, - gmx_bool bLastStep, - gmx_bool bDoConfOut, - gmx_bool bSumEkinhOld - ); +void do_md_trajectory_writing(FILE* fplog, + struct t_commrec* cr, + int nfile, + const t_filenm fnm[], + int64_t step, + int64_t step_rel, + double t, + t_inputrec* ir, + t_state* state, + t_state* state_global, + ObservablesHistory* observablesHistory, + const gmx_mtop_t* top_global, + t_forcerec* fr, + gmx_mdoutf_t outf, + const gmx::EnergyOutput& energyOutput, + gmx_ekindata_t* ekind, + gmx::ArrayRef f, + gmx_bool bCPT, + gmx_bool bRerunMD, + gmx_bool bLastStep, + gmx_bool bDoConfOut, + gmx_bool bSumEkinhOld); #endif diff --git a/src/gromacs/mdlib/update.cpp b/src/gromacs/mdlib/update.cpp index 05d097f5e4..503fa4d20e 100644 --- a/src/gromacs/mdlib/update.cpp +++ b/src/gromacs/mdlib/update.cpp @@ -98,60 +98,55 @@ struct gmx_sd_sigma_t struct gmx_stochd_t { /* BD stuff */ - std::vector bd_rf; + std::vector bd_rf; /* SD stuff */ std::vector sdc; std::vector sdsig; /* andersen temperature control stuff */ - std::vector randomize_group; - std::vector boltzfac; + std::vector randomize_group; + std::vector boltzfac; - explicit gmx_stochd_t(const t_inputrec *ir); + explicit gmx_stochd_t(const t_inputrec* ir); }; //! pImpled implementation for Update class Update::Impl { - public: - //! Constructor - Impl(const t_inputrec *ir, BoxDeformation *boxDeformation); - //! Destructor - ~Impl() = default; - //! stochastic dynamics struct - std::unique_ptr sd; - //! xprime for constraint algorithms - PaddedVector xp; - //! Box deformation handler (or nullptr if inactive). - BoxDeformation *deform = nullptr; +public: + //! Constructor + Impl(const t_inputrec* ir, BoxDeformation* boxDeformation); + //! Destructor + ~Impl() = default; + //! stochastic dynamics struct + std::unique_ptr sd; + //! xprime for constraint algorithms + PaddedVector xp; + //! Box deformation handler (or nullptr if inactive). + BoxDeformation* deform = nullptr; }; -Update::Update(const t_inputrec *ir, BoxDeformation *boxDeformation) - : impl_(new Impl(ir, boxDeformation)) -{}; +Update::Update(const t_inputrec* ir, BoxDeformation* boxDeformation) : + impl_(new Impl(ir, boxDeformation)){}; -Update::~Update() -{}; +Update::~Update(){}; gmx_stochd_t* Update::sd() const { return impl_->sd.get(); } -PaddedVector * Update::xp() +PaddedVector* Update::xp() { return &impl_->xp; } -BoxDeformation * Update::deform() const +BoxDeformation* Update::deform() const { return impl_->deform; } /*! \brief Sets the velocities of virtual sites to zero */ -static void clearVsiteVelocities(int start, - int nrend, - const unsigned short *particleType, - rvec * gmx_restrict v) +static void clearVsiteVelocities(int start, int nrend, const unsigned short* particleType, rvec* gmx_restrict v) { for (int a = start; a < nrend; a++) { @@ -165,8 +160,8 @@ static void clearVsiteVelocities(int start, /*! \brief Sets the number of different temperature coupling values */ enum class NumTempScaleValues { - single, //!< Single T-scaling value (either one group or all values =1) - multiple //!< Multiple T-scaling values, need to use T-group indices + single, //!< Single T-scaling value (either one group or all values =1) + multiple //!< Multiple T-scaling values, need to use T-group indices }; /*! \brief Sets if to apply no or diagonal Parrinello-Rahman pressure scaling @@ -177,8 +172,8 @@ enum class NumTempScaleValues */ enum class ApplyParrinelloRahmanVScaling { - no, //!< Do not apply velocity scaling (not a PR-coupling run or step) - diagonal //!< Apply velocity scaling using a diagonal matrix + no, //!< Do not apply velocity scaling (not a PR-coupling run or step) + diagonal //!< Apply velocity scaling using a diagonal matrix }; /*! \brief Integrate using leap-frog with T-scaling and optionally diagonal Parrinello-Rahman p-coupling @@ -203,21 +198,19 @@ enum class ApplyParrinelloRahmanVScaling * Note that we might get even better SIMD acceleration when we introduce * aligned (and padded) memory, possibly with some hints for the compilers. */ -template -static void -updateMDLeapfrogSimple(int start, - int nrend, - real dt, - real dtPressureCouple, - const rvec * gmx_restrict invMassPerDim, - gmx::ArrayRef tcstat, - const unsigned short * cTC, - const rvec pRVScaleMatrixDiagonal, - const rvec * gmx_restrict x, - rvec * gmx_restrict xprime, - rvec * gmx_restrict v, - const rvec * gmx_restrict f) +template +static void updateMDLeapfrogSimple(int start, + int nrend, + real dt, + real dtPressureCouple, + const rvec* gmx_restrict invMassPerDim, + gmx::ArrayRef tcstat, + const unsigned short* cTC, + const rvec pRVScaleMatrixDiagonal, + const rvec* gmx_restrict x, + rvec* gmx_restrict xprime, + rvec* gmx_restrict v, + const rvec* gmx_restrict f) { real lambdaGroup; @@ -241,22 +234,22 @@ updateMDLeapfrogSimple(int start, * (then already slow) update by 20%. If all data remains in cache, * using rvec is much faster. */ - real vNew = lambdaGroup*v[a][d] + f[a][d]*invMassPerDim[a][d]*dt; + real vNew = lambdaGroup * v[a][d] + f[a][d] * invMassPerDim[a][d] * dt; if (applyPRVScaling == ApplyParrinelloRahmanVScaling::diagonal) { - vNew -= dtPressureCouple*pRVScaleMatrixDiagonal[d]*v[a][d]; + vNew -= dtPressureCouple * pRVScaleMatrixDiagonal[d] * v[a][d]; } v[a][d] = vNew; - xprime[a][d] = x[a][d] + vNew*dt; + xprime[a][d] = x[a][d] + vNew * dt; } } } #if GMX_SIMD && GMX_SIMD_HAVE_REAL -#define GMX_HAVE_SIMD_UPDATE 1 +# define GMX_HAVE_SIMD_UPDATE 1 #else -#define GMX_HAVE_SIMD_UPDATE 0 +# define GMX_HAVE_SIMD_UPDATE 0 #endif #if GMX_HAVE_SIMD_UPDATE @@ -274,19 +267,15 @@ updateMDLeapfrogSimple(int start, * \param[out] r1 Pointer to second SIMD register * \param[out] r2 Pointer to third SIMD register */ -static inline void simdLoadRvecs(const rvec *r, - int index, - SimdReal *r0, - SimdReal *r1, - SimdReal *r2) +static inline void simdLoadRvecs(const rvec* r, int index, SimdReal* r0, SimdReal* r1, SimdReal* r2) { - const real *realPtr = r[index]; + const real* realPtr = r[index]; GMX_ASSERT(isSimdAligned(realPtr), "Pointer should be SIMD aligned"); - *r0 = simdLoad(realPtr + 0*GMX_SIMD_REAL_WIDTH); - *r1 = simdLoad(realPtr + 1*GMX_SIMD_REAL_WIDTH); - *r2 = simdLoad(realPtr + 2*GMX_SIMD_REAL_WIDTH); + *r0 = simdLoad(realPtr + 0 * GMX_SIMD_REAL_WIDTH); + *r1 = simdLoad(realPtr + 1 * GMX_SIMD_REAL_WIDTH); + *r2 = simdLoad(realPtr + 2 * GMX_SIMD_REAL_WIDTH); } /*! \brief Store (aligned) 3 SIMD registers sequentially to GMX_SIMD_REAL_WIDTH rvec elements @@ -302,19 +291,15 @@ static inline void simdLoadRvecs(const rvec *r, * \param[in] r1 Second SIMD register * \param[in] r2 Third SIMD register */ -static inline void simdStoreRvecs(rvec *r, - int index, - SimdReal r0, - SimdReal r1, - SimdReal r2) +static inline void simdStoreRvecs(rvec* r, int index, SimdReal r0, SimdReal r1, SimdReal r2) { - real *realPtr = r[index]; + real* realPtr = r[index]; GMX_ASSERT(isSimdAligned(realPtr), "Pointer should be SIMD aligned"); - store(realPtr + 0*GMX_SIMD_REAL_WIDTH, r0); - store(realPtr + 1*GMX_SIMD_REAL_WIDTH, r1); - store(realPtr + 2*GMX_SIMD_REAL_WIDTH, r2); + store(realPtr + 0 * GMX_SIMD_REAL_WIDTH, r0); + store(realPtr + 1 * GMX_SIMD_REAL_WIDTH, r1); + store(realPtr + 2 * GMX_SIMD_REAL_WIDTH, r2); } /*! \brief Integrate using leap-frog with single group T-scaling and SIMD @@ -329,19 +314,18 @@ static inline void simdStoreRvecs(rvec *r, * \param[inout] v Velocities * \param[in] f Forces */ -static void -updateMDLeapfrogSimpleSimd(int start, - int nrend, - real dt, - const real * gmx_restrict invMass, - gmx::ArrayRef tcstat, - const rvec * gmx_restrict x, - rvec * gmx_restrict xprime, - rvec * gmx_restrict v, - const rvec * gmx_restrict f) +static void updateMDLeapfrogSimpleSimd(int start, + int nrend, + real dt, + const real* gmx_restrict invMass, + gmx::ArrayRef tcstat, + const rvec* gmx_restrict x, + rvec* gmx_restrict xprime, + rvec* gmx_restrict v, + const rvec* gmx_restrict f) { - SimdReal timestep(dt); - SimdReal lambdaSystem(tcstat[0].lambda); + SimdReal timestep(dt); + SimdReal lambdaSystem(tcstat[0].lambda); /* We declare variables here, since code is often slower when declaring them inside the loop */ @@ -351,17 +335,16 @@ updateMDLeapfrogSimpleSimd(int start, for (int a = start; a < nrend; a += GMX_SIMD_REAL_WIDTH) { SimdReal invMass0, invMass1, invMass2; - expandScalarsToTriplets(simdLoad(invMass + a), - &invMass0, &invMass1, &invMass2); + expandScalarsToTriplets(simdLoad(invMass + a), &invMass0, &invMass1, &invMass2); SimdReal v0, v1, v2; SimdReal f0, f1, f2; simdLoadRvecs(v, a, &v0, &v1, &v2); simdLoadRvecs(f, a, &f0, &f1, &f2); - v0 = fma(f0*invMass0, timestep, lambdaSystem*v0); - v1 = fma(f1*invMass1, timestep, lambdaSystem*v1); - v2 = fma(f2*invMass2, timestep, lambdaSystem*v2); + v0 = fma(f0 * invMass0, timestep, lambdaSystem * v0); + v1 = fma(f1 * invMass1, timestep, lambdaSystem * v1); + v2 = fma(f2 * invMass2, timestep, lambdaSystem * v2); simdStoreRvecs(v, a, v0, v1, v2); @@ -381,7 +364,9 @@ updateMDLeapfrogSimpleSimd(int start, /*! \brief Sets the NEMD acceleration type */ enum class AccelerationType { - none, group, cosine + none, + group, + cosine }; /*! \brief Integrate using leap-frog with support for everything @@ -391,35 +376,30 @@ enum class AccelerationType * \param[in] nrend Last atom to update: \p nrend - 1 * \param[in] doNoseHoover If to apply Nose-Hoover T-coupling * \param[in] dt The time step - * \param[in] dtPressureCouple Time step for pressure coupling, is 0 when no pressure coupling should be applied at this step - * \param[in] ir The input parameter record - * \param[in] md Atom properties - * \param[in] ekind Kinetic energy data - * \param[in] box The box dimensions - * \param[in] x Input coordinates - * \param[out] xprime Updated coordinates - * \param[inout] v Velocities - * \param[in] f Forces - * \param[in] nh_vxi Nose-Hoover velocity scaling factors - * \param[in] M Parrinello-Rahman scaling matrix + * \param[in] dtPressureCouple Time step for pressure coupling, is 0 when no pressure + * coupling should be applied at this step \param[in] ir The input parameter + * record \param[in] md Atom properties \param[in] ekind Kinetic energy + * data \param[in] box The box dimensions \param[in] x Input coordinates \param[out] + * xprime Updated coordinates \param[inout] v Velocities \param[in] + * f Forces \param[in] nh_vxi Nose-Hoover velocity scaling + * factors \param[in] M Parrinello-Rahman scaling matrix */ template -static void -updateMDLeapfrogGeneral(int start, - int nrend, - bool doNoseHoover, - real dt, - real dtPressureCouple, - const t_inputrec * ir, - const t_mdatoms * md, - const gmx_ekindata_t * ekind, - const matrix box, - const rvec * gmx_restrict x, - rvec * gmx_restrict xprime, - rvec * gmx_restrict v, - const rvec * gmx_restrict f, - const double * gmx_restrict nh_vxi, - const matrix M) +static void updateMDLeapfrogGeneral(int start, + int nrend, + bool doNoseHoover, + real dt, + real dtPressureCouple, + const t_inputrec* ir, + const t_mdatoms* md, + const gmx_ekindata_t* ekind, + const matrix box, + const rvec* gmx_restrict x, + rvec* gmx_restrict xprime, + rvec* gmx_restrict v, + const rvec* gmx_restrict f, + const double* gmx_restrict nh_vxi, + const matrix M) { /* This is a version of the leap-frog integrator that supports * all combinations of T-coupling, P-coupling and NEMD. @@ -427,39 +407,37 @@ updateMDLeapfrogGeneral(int start, * Holian et al. Phys Rev E 52(3) : 2338, 1995 */ - gmx::ArrayRef tcstat = ekind->tcstat; - gmx::ArrayRef grpstat = ekind->grpstat; - const unsigned short * cTC = md->cTC; - const unsigned short * cACC = md->cACC; - const rvec * accel = ir->opts.acc; + gmx::ArrayRef tcstat = ekind->tcstat; + gmx::ArrayRef grpstat = ekind->grpstat; + const unsigned short* cTC = md->cTC; + const unsigned short* cACC = md->cACC; + const rvec* accel = ir->opts.acc; - const rvec * gmx_restrict invMassPerDim = md->invMassPerDim; + const rvec* gmx_restrict invMassPerDim = md->invMassPerDim; /* Initialize group values, changed later when multiple groups are used */ int ga = 0; int gt = 0; real factorNH = 0; - real omega_Z = 2*static_cast(M_PI)/box[ZZ][ZZ]; + real omega_Z = 2 * static_cast(M_PI) / box[ZZ][ZZ]; for (int n = start; n < nrend; n++) { if (cTC) { - gt = cTC[n]; + gt = cTC[n]; } real lg = tcstat[gt].lambda; rvec vRel; real cosineZ, vCosine; #ifdef __INTEL_COMPILER -#pragma warning( disable : 280 ) +# pragma warning(disable : 280) #endif switch (accelerationType) { - case AccelerationType::none: - copy_rvec(v[n], vRel); - break; + case AccelerationType::none: copy_rvec(v[n], vRel); break; case AccelerationType::group: if (cACC) { @@ -469,8 +447,8 @@ updateMDLeapfrogGeneral(int start, rvec_sub(v[n], grpstat[ga].u, vRel); break; case AccelerationType::cosine: - cosineZ = std::cos(x[n][ZZ]*omega_Z); - vCosine = cosineZ*ekind->cosacc.vcos; + cosineZ = std::cos(x[n][ZZ] * omega_Z); + vCosine = cosineZ * ekind->cosacc.vcos; /* Avoid scaling the cosine profile velocity */ copy_rvec(v[n], vRel); vRel[XX] -= vCosine; @@ -482,65 +460,68 @@ updateMDLeapfrogGeneral(int start, /* Here we account for multiple time stepping, by increasing * the Nose-Hoover correction by nsttcouple */ - factorNH = 0.5*ir->nsttcouple*dt*nh_vxi[gt]; + factorNH = 0.5 * ir->nsttcouple * dt * nh_vxi[gt]; } for (int d = 0; d < DIM; d++) { - real vNew = - (lg*vRel[d] + (f[n][d]*invMassPerDim[n][d]*dt - factorNH*vRel[d] - - dtPressureCouple*iprod(M[d], vRel)))/(1 + factorNH); + real vNew = (lg * vRel[d] + + (f[n][d] * invMassPerDim[n][d] * dt - factorNH * vRel[d] + - dtPressureCouple * iprod(M[d], vRel))) + / (1 + factorNH); switch (accelerationType) { - case AccelerationType::none: - break; + case AccelerationType::none: break; case AccelerationType::group: /* Add back the mean velocity and apply acceleration */ - vNew += grpstat[ga].u[d] + accel[ga][d]*dt; + vNew += grpstat[ga].u[d] + accel[ga][d] * dt; break; case AccelerationType::cosine: if (d == XX) { /* Add back the mean velocity and apply acceleration */ - vNew += vCosine + cosineZ*ekind->cosacc.cos_accel*dt; + vNew += vCosine + cosineZ * ekind->cosacc.cos_accel * dt; } break; } - v[n][d] = vNew; - xprime[n][d] = x[n][d] + vNew*dt; + v[n][d] = vNew; + xprime[n][d] = x[n][d] + vNew * dt; } } } /*! \brief Handles the Leap-frog MD x and v integration */ -static void do_update_md(int start, - int nrend, - int64_t step, - real dt, - const t_inputrec * ir, - const t_mdatoms * md, - const gmx_ekindata_t * ekind, - const matrix box, - const rvec * gmx_restrict x, - rvec * gmx_restrict xprime, - rvec * gmx_restrict v, - const rvec * gmx_restrict f, - const double * gmx_restrict nh_vxi, - const matrix M) +static void do_update_md(int start, + int nrend, + int64_t step, + real dt, + const t_inputrec* ir, + const t_mdatoms* md, + const gmx_ekindata_t* ekind, + const matrix box, + const rvec* gmx_restrict x, + rvec* gmx_restrict xprime, + rvec* gmx_restrict v, + const rvec* gmx_restrict f, + const double* gmx_restrict nh_vxi, + const matrix M) { - GMX_ASSERT(nrend == start || xprime != x, "For SIMD optimization certain compilers need to have xprime != x"); - GMX_ASSERT(ir->eI == eiMD, "Leap-frog integrator was called while another integrator was requested"); + GMX_ASSERT(nrend == start || xprime != x, + "For SIMD optimization certain compilers need to have xprime != x"); + GMX_ASSERT(ir->eI == eiMD, + "Leap-frog integrator was called while another integrator was requested"); /* Note: Berendsen pressure scaling is handled after do_update_md() */ - bool doTempCouple = (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple)); - bool doNoseHoover = (ir->etc == etcNOSEHOOVER && doTempCouple); - bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple)); - bool doPROffDiagonal = (doParrinelloRahman && (M[YY][XX] != 0 || M[ZZ][XX] != 0 || M[ZZ][YY] != 0)); + bool doTempCouple = (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple)); + bool doNoseHoover = (ir->etc == etcNOSEHOOVER && doTempCouple); + bool doParrinelloRahman = + (ir->epc == epcPARRINELLORAHMAN && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple)); + bool doPROffDiagonal = (doParrinelloRahman && (M[YY][XX] != 0 || M[ZZ][XX] != 0 || M[ZZ][YY] != 0)); - real dtPressureCouple = (doParrinelloRahman ? ir->nstpcouple*dt : 0); + real dtPressureCouple = (doParrinelloRahman ? ir->nstpcouple * dt : 0); /* NEMD (also cosine) acceleration is applied in updateMDLeapFrogGeneral */ - bool doAcceleration = (ekind->bNEMD || ekind->cosacc.cos_accel != 0); + bool doAcceleration = (ekind->bNEMD || ekind->cosacc.cos_accel != 0); if (doNoseHoover || doPROffDiagonal || doAcceleration) { @@ -557,21 +538,21 @@ static void do_update_md(int start, if (!doAcceleration) { - updateMDLeapfrogGeneral - (start, nrend, doNoseHoover, dt, dtPressureCouple, - ir, md, ekind, box, x, xprime, v, f, nh_vxi, stepM); + updateMDLeapfrogGeneral(start, nrend, doNoseHoover, dt, + dtPressureCouple, ir, md, ekind, box, x, + xprime, v, f, nh_vxi, stepM); } else if (ekind->bNEMD) { - updateMDLeapfrogGeneral - (start, nrend, doNoseHoover, dt, dtPressureCouple, - ir, md, ekind, box, x, xprime, v, f, nh_vxi, stepM); + updateMDLeapfrogGeneral(start, nrend, doNoseHoover, dt, + dtPressureCouple, ir, md, ekind, box, + x, xprime, v, f, nh_vxi, stepM); } else { - updateMDLeapfrogGeneral - (start, nrend, doNoseHoover, dt, dtPressureCouple, - ir, md, ekind, box, x, xprime, v, f, nh_vxi, stepM); + updateMDLeapfrogGeneral(start, nrend, doNoseHoover, dt, + dtPressureCouple, ir, md, ekind, box, + x, xprime, v, f, nh_vxi, stepM); } } else @@ -597,13 +578,15 @@ static void do_update_md(int start, bool haveSingleTempScaleValue = (!doTempCouple || ekind->ngtc == 1); /* Extract some pointers needed by all cases */ - const unsigned short *cTC = md->cTC; + const unsigned short* cTC = md->cTC; gmx::ArrayRef tcstat = ekind->tcstat; - const rvec *invMassPerDim = md->invMassPerDim; + const rvec* invMassPerDim = md->invMassPerDim; if (doParrinelloRahman) { - GMX_ASSERT(!doPROffDiagonal, "updateMDLeapfrogSimple only support diagonal Parrinello-Rahman scaling matrices"); + GMX_ASSERT(!doPROffDiagonal, + "updateMDLeapfrogSimple only support diagonal Parrinello-Rahman scaling " + "matrices"); rvec diagM; for (int d = 0; d < DIM; d++) @@ -613,19 +596,15 @@ static void do_update_md(int start, if (haveSingleTempScaleValue) { - updateMDLeapfrogSimple - - (start, nrend, dt, dtPressureCouple, - invMassPerDim, tcstat, cTC, diagM, x, xprime, v, f); + updateMDLeapfrogSimple( + start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x, + xprime, v, f); } else { - updateMDLeapfrogSimple - - (start, nrend, dt, dtPressureCouple, - invMassPerDim, tcstat, cTC, diagM, x, xprime, v, f); + updateMDLeapfrogSimple( + start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, diagM, x, + xprime, v, f); } } else @@ -641,99 +620,109 @@ static void do_update_md(int start, /* Check if we can use invmass instead of invMassPerDim */ if (!md->havePartiallyFrozenAtoms) { - updateMDLeapfrogSimpleSimd - (start, nrend, dt, md->invmass, tcstat, x, xprime, v, f); + updateMDLeapfrogSimpleSimd(start, nrend, dt, md->invmass, tcstat, x, xprime, v, f); } else #endif { - updateMDLeapfrogSimple - - (start, nrend, dt, dtPressureCouple, - invMassPerDim, tcstat, cTC, nullptr, x, xprime, v, f); + updateMDLeapfrogSimple( + start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr, + x, xprime, v, f); } } else { - updateMDLeapfrogSimple - - (start, nrend, dt, dtPressureCouple, - invMassPerDim, tcstat, cTC, nullptr, x, xprime, v, f); + updateMDLeapfrogSimple( + start, nrend, dt, dtPressureCouple, invMassPerDim, tcstat, cTC, nullptr, x, + xprime, v, f); } } } } -static void do_update_vv_vel(int start, int nrend, real dt, - const rvec accel[], const ivec nFreeze[], const real invmass[], - const unsigned short ptype[], const unsigned short cFREEZE[], - const unsigned short cACC[], rvec v[], const rvec f[], - gmx_bool bExtended, real veta, real alpha) +static void do_update_vv_vel(int start, + int nrend, + real dt, + const rvec accel[], + const ivec nFreeze[], + const real invmass[], + const unsigned short ptype[], + const unsigned short cFREEZE[], + const unsigned short cACC[], + rvec v[], + const rvec f[], + gmx_bool bExtended, + real veta, + real alpha) { - int gf = 0, ga = 0; - int n, d; - real g, mv1, mv2; + int gf = 0, ga = 0; + int n, d; + real g, mv1, mv2; if (bExtended) { - g = 0.25*dt*veta*alpha; - mv1 = std::exp(-g); - mv2 = gmx::series_sinhx(g); + g = 0.25 * dt * veta * alpha; + mv1 = std::exp(-g); + mv2 = gmx::series_sinhx(g); } else { - mv1 = 1.0; - mv2 = 1.0; + mv1 = 1.0; + mv2 = 1.0; } for (n = start; n < nrend; n++) { - real w_dt = invmass[n]*dt; + real w_dt = invmass[n] * dt; if (cFREEZE) { - gf = cFREEZE[n]; + gf = cFREEZE[n]; } if (cACC) { - ga = cACC[n]; + ga = cACC[n]; } for (d = 0; d < DIM; d++) { if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d]) { - v[n][d] = mv1*(mv1*v[n][d] + 0.5*(w_dt*mv2*f[n][d]))+0.5*accel[ga][d]*dt; + v[n][d] = mv1 * (mv1 * v[n][d] + 0.5 * (w_dt * mv2 * f[n][d])) + 0.5 * accel[ga][d] * dt; } else { - v[n][d] = 0.0; + v[n][d] = 0.0; } } } } /* do_update_vv_vel */ -static void do_update_vv_pos(int start, int nrend, real dt, - const ivec nFreeze[], - const unsigned short ptype[], const unsigned short cFREEZE[], - const rvec x[], rvec xprime[], const rvec v[], - gmx_bool bExtended, real veta) +static void do_update_vv_pos(int start, + int nrend, + real dt, + const ivec nFreeze[], + const unsigned short ptype[], + const unsigned short cFREEZE[], + const rvec x[], + rvec xprime[], + const rvec v[], + gmx_bool bExtended, + real veta) { - int gf = 0; - int n, d; - real g, mr1, mr2; + int gf = 0; + int n, d; + real g, mr1, mr2; /* Would it make more sense if Parrinello-Rahman was put here? */ if (bExtended) { - g = 0.5*dt*veta; - mr1 = std::exp(g); - mr2 = gmx::series_sinhx(g); + g = 0.5 * dt * veta; + mr1 = std::exp(g); + mr2 = gmx::series_sinhx(g); } else { - mr1 = 1.0; - mr2 = 1.0; + mr1 = 1.0; + mr2 = 1.0; } for (n = start; n < nrend; n++) @@ -741,26 +730,26 @@ static void do_update_vv_pos(int start, int nrend, real dt, if (cFREEZE) { - gf = cFREEZE[n]; + gf = cFREEZE[n]; } for (d = 0; d < DIM; d++) { if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d]) { - xprime[n][d] = mr1*(mr1*x[n][d]+mr2*dt*v[n][d]); + xprime[n][d] = mr1 * (mr1 * x[n][d] + mr2 * dt * v[n][d]); } else { - xprime[n][d] = x[n][d]; + xprime[n][d] = x[n][d]; } } } } /* do_update_vv_pos */ -gmx_stochd_t::gmx_stochd_t(const t_inputrec *ir) +gmx_stochd_t::gmx_stochd_t(const t_inputrec* ir) { - const t_grpopts *opts = &ir->opts; + const t_grpopts* opts = &ir->opts; const int ngtc = opts->ngtc; if (ir->eI == eiBD) @@ -776,12 +765,12 @@ gmx_stochd_t::gmx_stochd_t(const t_inputrec *ir) { if (opts->tau_t[gt] > 0) { - sdc[gt].em = std::exp(-ir->delta_t/opts->tau_t[gt]); + sdc[gt].em = std::exp(-ir->delta_t / opts->tau_t[gt]); } else { /* No friction and noise on this group */ - sdc[gt].em = 1; + sdc[gt].em = 1; } } } @@ -796,10 +785,11 @@ gmx_stochd_t::gmx_stochd_t(const t_inputrec *ir) for (int gt = 0; gt < ngtc; gt++) { real reft = std::max(0, opts->ref_t[gt]); - if ((opts->tau_t[gt] > 0) && (reft > 0)) /* tau_t or ref_t = 0 means that no randomization is done */ + if ((opts->tau_t[gt] > 0) + && (reft > 0)) /* tau_t or ref_t = 0 means that no randomization is done */ { randomize_group[gt] = true; - boltzfac[gt] = BOLTZ*opts->ref_t[gt]; + boltzfac[gt] = BOLTZ * opts->ref_t[gt]; } else { @@ -809,7 +799,7 @@ gmx_stochd_t::gmx_stochd_t(const t_inputrec *ir) } } -void update_temperature_constants(gmx_stochd_t *sd, const t_inputrec *ir) +void update_temperature_constants(gmx_stochd_t* sd, const t_inputrec* ir) { if (ir->eI == eiBD) { @@ -817,14 +807,14 @@ void update_temperature_constants(gmx_stochd_t *sd, const t_inputrec *ir) { for (int gt = 0; gt < ir->opts.ngtc; gt++) { - sd->bd_rf[gt] = std::sqrt(2.0*BOLTZ*ir->opts.ref_t[gt]/(ir->bd_fric*ir->delta_t)); + sd->bd_rf[gt] = std::sqrt(2.0 * BOLTZ * ir->opts.ref_t[gt] / (ir->bd_fric * ir->delta_t)); } } else { for (int gt = 0; gt < ir->opts.ngtc; gt++) { - sd->bd_rf[gt] = std::sqrt(2.0*BOLTZ*ir->opts.ref_t[gt]); + sd->bd_rf[gt] = std::sqrt(2.0 * BOLTZ * ir->opts.ref_t[gt]); } } } @@ -832,14 +822,14 @@ void update_temperature_constants(gmx_stochd_t *sd, const t_inputrec *ir) { for (int gt = 0; gt < ir->opts.ngtc; gt++) { - real kT = BOLTZ*ir->opts.ref_t[gt]; + real kT = BOLTZ * ir->opts.ref_t[gt]; /* The mass is accounted for later, since this differs per atom */ - sd->sdsig[gt].V = std::sqrt(kT*(1 - sd->sdc[gt].em * sd->sdc[gt].em)); + sd->sdsig[gt].V = std::sqrt(kT * (1 - sd->sdc[gt].em * sd->sdc[gt].em)); } } } -Update::Impl::Impl(const t_inputrec *ir, BoxDeformation *boxDeformation) +Update::Impl::Impl(const t_inputrec* ir, BoxDeformation* boxDeformation) { sd = std::make_unique(ir); update_temperature_constants(sd.get(), ir); @@ -856,7 +846,9 @@ void Update::setNumAtoms(int nAtoms) /*! \brief Sets the SD update type */ enum class SDUpdate : int { - ForcesOnly, FrictionAndNoiseOnly, Combined + ForcesOnly, + FrictionAndNoiseOnly, + Combined }; /*! \brief SD integrator update @@ -872,16 +864,25 @@ enum class SDUpdate : int * * Thus three instantiations of this templated function will be made, * two with only one contribution, and one with both contributions. */ -template -static void -doSDUpdateGeneral(const gmx_stochd_t &sd, - int start, int nrend, real dt, - const rvec accel[], const ivec nFreeze[], - const real invmass[], const unsigned short ptype[], - const unsigned short cFREEZE[], const unsigned short cACC[], - const unsigned short cTC[], - const rvec x[], rvec xprime[], rvec v[], const rvec f[], - int64_t step, int seed, const int *gatindex) +template +static void doSDUpdateGeneral(const gmx_stochd_t& sd, + int start, + int nrend, + real dt, + const rvec accel[], + const ivec nFreeze[], + const real invmass[], + const unsigned short ptype[], + const unsigned short cFREEZE[], + const unsigned short cACC[], + const unsigned short cTC[], + const rvec x[], + rvec xprime[], + rvec v[], + const rvec f[], + int64_t step, + int seed, + const int* gatindex) { // cTC, cACC and cFREEZE can be nullptr any time, but various // instantiations do not make sense with particular pointer @@ -902,7 +903,7 @@ doSDUpdateGeneral(const gmx_stochd_t &sd, } // Even 0 bits internal counter gives 2x64 ints (more than enough for three table lookups) - gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::UpdateCoordinates); + gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::UpdateCoordinates); gmx::TabulatedNormalDistribution dist; for (int n = start; n < nrend; n++) @@ -911,12 +912,12 @@ doSDUpdateGeneral(const gmx_stochd_t &sd, rng.restart(step, globalAtomIndex); dist.reset(); - real inverseMass = invmass[n]; - real invsqrtMass = std::sqrt(inverseMass); + real inverseMass = invmass[n]; + real invsqrtMass = std::sqrt(inverseMass); - int freezeGroup = cFREEZE ? cFREEZE[n] : 0; - int accelerationGroup = cACC ? cACC[n] : 0; - int temperatureGroup = cTC ? cTC[n] : 0; + int freezeGroup = cFREEZE ? cFREEZE[n] : 0; + int accelerationGroup = cACC ? cACC[n] : 0; + int temperatureGroup = cTC ? cTC[n] : 0; for (int d = 0; d < DIM; d++) { @@ -924,29 +925,29 @@ doSDUpdateGeneral(const gmx_stochd_t &sd, { if (updateType == SDUpdate::ForcesOnly) { - real vn = v[n][d] + (inverseMass*f[n][d] + accel[accelerationGroup][d])*dt; - v[n][d] = vn; + real vn = v[n][d] + (inverseMass * f[n][d] + accel[accelerationGroup][d]) * dt; + v[n][d] = vn; // Simple position update. - xprime[n][d] = x[n][d] + v[n][d]*dt; + xprime[n][d] = x[n][d] + v[n][d] * dt; } else if (updateType == SDUpdate::FrictionAndNoiseOnly) { - real vn = v[n][d]; - v[n][d] = (vn*sd.sdc[temperatureGroup].em + - invsqrtMass*sd.sdsig[temperatureGroup].V*dist(rng)); + real vn = v[n][d]; + v[n][d] = (vn * sd.sdc[temperatureGroup].em + + invsqrtMass * sd.sdsig[temperatureGroup].V * dist(rng)); // The previous phase already updated the // positions with a full v*dt term that must // now be half removed. - xprime[n][d] = xprime[n][d] + 0.5*(v[n][d] - vn)*dt; + xprime[n][d] = xprime[n][d] + 0.5 * (v[n][d] - vn) * dt; } else { - real vn = v[n][d] + (inverseMass*f[n][d] + accel[accelerationGroup][d])*dt; - v[n][d] = (vn*sd.sdc[temperatureGroup].em + - invsqrtMass*sd.sdsig[temperatureGroup].V*dist(rng)); + real vn = v[n][d] + (inverseMass * f[n][d] + accel[accelerationGroup][d]) * dt; + v[n][d] = (vn * sd.sdc[temperatureGroup].em + + invsqrtMass * sd.sdsig[temperatureGroup].V * dist(rng)); // Here we include half of the friction+noise // update of v into the position update. - xprime[n][d] = x[n][d] + 0.5*(vn + v[n][d])*dt; + xprime[n][d] = x[n][d] + 0.5 * (vn + v[n][d]) * dt; } } else @@ -965,33 +966,42 @@ doSDUpdateGeneral(const gmx_stochd_t &sd, } } -static void do_update_bd(int start, int nrend, real dt, - const ivec nFreeze[], - const real invmass[], const unsigned short ptype[], - const unsigned short cFREEZE[], const unsigned short cTC[], - const rvec x[], rvec xprime[], rvec v[], - const rvec f[], real friction_coefficient, - const real *rf, int64_t step, int seed, - const int* gatindex) +static void do_update_bd(int start, + int nrend, + real dt, + const ivec nFreeze[], + const real invmass[], + const unsigned short ptype[], + const unsigned short cFREEZE[], + const unsigned short cTC[], + const rvec x[], + rvec xprime[], + rvec v[], + const rvec f[], + real friction_coefficient, + const real* rf, + int64_t step, + int seed, + const int* gatindex) { /* note -- these appear to be full step velocities . . . */ - int gf = 0, gt = 0; - real vn; - real invfr = 0; - int n, d; + int gf = 0, gt = 0; + real vn; + real invfr = 0; + int n, d; // Use 1 bit of internal counters to give us 2*2 64-bits values per stream // Each 64-bit value is enough for 4 normal distribution table numbers. - gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::UpdateCoordinates); + gmx::ThreeFry2x64<0> rng(seed, gmx::RandomDomain::UpdateCoordinates); gmx::TabulatedNormalDistribution dist; if (friction_coefficient != 0) { - invfr = 1.0/friction_coefficient; + invfr = 1.0 / friction_coefficient; } for (n = start; (n < nrend); n++) { - int ng = gatindex ? gatindex[n] : n; + int ng = gatindex ? gatindex[n] : n; rng.restart(step, ng); dist.reset(); @@ -1010,17 +1020,17 @@ static void do_update_bd(int start, int nrend, real dt, { if (friction_coefficient != 0) { - vn = invfr*f[n][d] + rf[gt]*dist(rng); + vn = invfr * f[n][d] + rf[gt] * dist(rng); } else { /* NOTE: invmass = 2/(mass*friction_constant*dt) */ - vn = 0.5*invmass[n]*f[n][d]*dt - + std::sqrt(0.5*invmass[n])*rf[gt]*dist(rng); + vn = 0.5 * invmass[n] * f[n][d] * dt + + std::sqrt(0.5 * invmass[n]) * rf[gt] * dist(rng); } v[n][d] = vn; - xprime[n][d] = x[n][d]+vn*dt; + xprime[n][d] = x[n][d] + vn * dt; } else { @@ -1031,8 +1041,12 @@ static void do_update_bd(int start, int nrend, real dt, } } -static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_mdatoms *md, - gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel) +static void calc_ke_part_normal(const rvec v[], + const t_grpopts* opts, + const t_mdatoms* md, + gmx_ekindata_t* ekind, + t_nrnb* nrnb, + gmx_bool bEkinAveVel) { int g; gmx::ArrayRef tcstat = ekind->tcstat; @@ -1053,7 +1067,7 @@ static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_m if (bEkinAveVel) { clear_mat(tcstat[g].ekinf); - tcstat[g].ekinscalef_nhc = 1.0; /* need to clear this -- logic is complicated! */ + tcstat[g].ekinscalef_nhc = 1.0; /* need to clear this -- logic is complicated! */ } else { @@ -1074,11 +1088,11 @@ static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_m rvec v_corrt; real hm; int d, m; - matrix *ekin_sum; - real *dekindl_sum; + matrix* ekin_sum; + real* dekindl_sum; - start_t = ((thread+0)*md->homenr)/nthread; - end_t = ((thread+1)*md->homenr)/nthread; + start_t = ((thread + 0) * md->homenr) / nthread; + end_t = ((thread + 1) * md->homenr) / nthread; ekin_sum = ekind->ekin_work[thread]; dekindl_sum = ekind->dekindl_work[thread]; @@ -1101,24 +1115,23 @@ static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_m { gt = md->cTC[n]; } - hm = 0.5*md->massT[n]; + hm = 0.5 * md->massT[n]; for (d = 0; (d < DIM); d++) { - v_corrt[d] = v[n][d] - grpstat[ga].u[d]; + v_corrt[d] = v[n][d] - grpstat[ga].u[d]; } for (d = 0; (d < DIM); d++) { for (m = 0; (m < DIM); m++) { /* if we're computing a full step velocity, v_corrt[d] has v(t). Otherwise, v(t+dt/2) */ - ekin_sum[gt][m][d] += hm*v_corrt[m]*v_corrt[d]; + ekin_sum[gt][m][d] += hm * v_corrt[m] * v_corrt[d]; } } if (md->nMassPerturbed && md->bPerturbed[n]) { - *dekindl_sum += - 0.5*(md->massB[n] - md->massA[n])*iprod(v_corrt, v_corrt); + *dekindl_sum += 0.5 * (md->massB[n] - md->massA[n]) * iprod(v_corrt, v_corrt); } } } @@ -1130,13 +1143,11 @@ static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_m { if (bEkinAveVel) { - m_add(tcstat[g].ekinf, ekind->ekin_work[thread][g], - tcstat[g].ekinf); + m_add(tcstat[g].ekinf, ekind->ekin_work[thread][g], tcstat[g].ekinf); } else { - m_add(tcstat[g].ekinh, ekind->ekin_work[thread][g], - tcstat[g].ekinh); + m_add(tcstat[g].ekinh, ekind->ekin_work[thread][g], tcstat[g].ekinh); } } @@ -1146,17 +1157,21 @@ static void calc_ke_part_normal(const rvec v[], const t_grpopts *opts, const t_m inc_nrnb(nrnb, eNR_EKIN, md->homenr); } -static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[], - const t_grpopts *opts, const t_mdatoms *md, - gmx_ekindata_t *ekind, - t_nrnb *nrnb, gmx_bool bEkinAveVel) +static void calc_ke_part_visc(const matrix box, + const rvec x[], + const rvec v[], + const t_grpopts* opts, + const t_mdatoms* md, + gmx_ekindata_t* ekind, + t_nrnb* nrnb, + gmx_bool bEkinAveVel) { int start = 0, homenr = md->homenr; int g, d, n, m, gt = 0; rvec v_corrt; real hm; gmx::ArrayRef tcstat = ekind->tcstat; - t_cos_acc *cosacc = &(ekind->cosacc); + t_cos_acc* cosacc = &(ekind->cosacc); real dekindl; real fac, cosz; double mvcos; @@ -1168,26 +1183,26 @@ static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[], } ekind->dekindl_old = ekind->dekindl; - fac = 2*M_PI/box[ZZ][ZZ]; + fac = 2 * M_PI / box[ZZ][ZZ]; mvcos = 0; dekindl = 0; - for (n = start; n < start+homenr; n++) + for (n = start; n < start + homenr; n++) { if (md->cTC) { gt = md->cTC[n]; } - hm = 0.5*md->massT[n]; + hm = 0.5 * md->massT[n]; /* Note that the times of x and v differ by half a step */ /* MRS -- would have to be changed for VV */ - cosz = std::cos(fac*x[n][ZZ]); + cosz = std::cos(fac * x[n][ZZ]); /* Calculate the amplitude of the new velocity profile */ - mvcos += 2*cosz*md->massT[n]*v[n][XX]; + mvcos += 2 * cosz * md->massT[n] * v[n][XX]; copy_rvec(v[n], v_corrt); /* Subtract the profile for the kinetic energy */ - v_corrt[XX] -= cosz*cosacc->vcos; + v_corrt[XX] -= cosz * cosacc->vcos; for (d = 0; (d < DIM); d++) { for (m = 0; (m < DIM); m++) @@ -1195,11 +1210,11 @@ static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[], /* if we're computing a full step velocity, v_corrt[d] has v(t). Otherwise, v(t+dt/2) */ if (bEkinAveVel) { - tcstat[gt].ekinf[m][d] += hm*v_corrt[m]*v_corrt[d]; + tcstat[gt].ekinf[m][d] += hm * v_corrt[m] * v_corrt[d]; } else { - tcstat[gt].ekinh[m][d] += hm*v_corrt[m]*v_corrt[d]; + tcstat[gt].ekinh[m][d] += hm * v_corrt[m] * v_corrt[d]; } } } @@ -1210,7 +1225,7 @@ static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[], * d m(l)/2 v^2 / dl, but rather from d p^2/2m(l) / dl, * where p are the momenta. The difference is only a minus sign. */ - dekindl -= 0.5*(md->massB[n] - md->massA[n])*iprod(v_corrt, v_corrt); + dekindl -= 0.5 * (md->massB[n] - md->massA[n]) * iprod(v_corrt, v_corrt); } } ekind->dekindl = dekindl; @@ -1219,10 +1234,14 @@ static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[], inc_nrnb(nrnb, eNR_EKIN, homenr); } -void calc_ke_part( - const rvec *x, const rvec *v, const matrix box, - const t_grpopts *opts, const t_mdatoms *md, - gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel) +void calc_ke_part(const rvec* x, + const rvec* v, + const matrix box, + const t_grpopts* opts, + const t_mdatoms* md, + gmx_ekindata_t* ekind, + t_nrnb* nrnb, + gmx_bool bEkinAveVel) { if (ekind->cosacc.cos_accel == 0) { @@ -1234,7 +1253,7 @@ void calc_ke_part( } } -extern void init_ekinstate(ekinstate_t *ekinstate, const t_inputrec *ir) +extern void init_ekinstate(ekinstate_t* ekinstate, const t_inputrec* ir) { ekinstate->ekin_n = ir->opts.ngtc; snew(ekinstate->ekinh, ekinstate->ekin_n); @@ -1248,7 +1267,7 @@ extern void init_ekinstate(ekinstate_t *ekinstate, const t_inputrec *ir) ekinstate->hasReadEkinState = false; } -void update_ekinstate(ekinstate_t *ekinstate, const gmx_ekindata_t *ekind) +void update_ekinstate(ekinstate_t* ekinstate, const gmx_ekindata_t* ekind) { int i; @@ -1265,11 +1284,9 @@ void update_ekinstate(ekinstate_t *ekinstate, const gmx_ekindata_t *ekind) copy_mat(ekind->ekin, ekinstate->ekin_total); ekinstate->dekindl = ekind->dekindl; ekinstate->mvcos = ekind->cosacc.mvcos; - } -void restore_ekinstate_from_state(const t_commrec *cr, - gmx_ekindata_t *ekind, const ekinstate_t *ekinstate) +void restore_ekinstate_from_state(const t_commrec* cr, gmx_ekindata_t* ekind, const ekinstate_t* ekinstate) { int i, n; @@ -1297,22 +1314,16 @@ void restore_ekinstate_from_state(const t_commrec *cr, gmx_bcast(sizeof(n), &n, cr); for (i = 0; i < n; i++) { - gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinh[0][0]), - ekind->tcstat[i].ekinh[0], cr); - gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinf[0][0]), - ekind->tcstat[i].ekinf[0], cr); - gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinh_old[0][0]), + gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinh[0][0]), ekind->tcstat[i].ekinh[0], cr); + gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinf[0][0]), ekind->tcstat[i].ekinf[0], cr); + gmx_bcast(DIM * DIM * sizeof(ekind->tcstat[i].ekinh_old[0][0]), ekind->tcstat[i].ekinh_old[0], cr); - gmx_bcast(sizeof(ekind->tcstat[i].ekinscalef_nhc), - &(ekind->tcstat[i].ekinscalef_nhc), cr); - gmx_bcast(sizeof(ekind->tcstat[i].ekinscaleh_nhc), - &(ekind->tcstat[i].ekinscaleh_nhc), cr); - gmx_bcast(sizeof(ekind->tcstat[i].vscale_nhc), - &(ekind->tcstat[i].vscale_nhc), cr); + gmx_bcast(sizeof(ekind->tcstat[i].ekinscalef_nhc), &(ekind->tcstat[i].ekinscalef_nhc), cr); + gmx_bcast(sizeof(ekind->tcstat[i].ekinscaleh_nhc), &(ekind->tcstat[i].ekinscaleh_nhc), cr); + gmx_bcast(sizeof(ekind->tcstat[i].vscale_nhc), &(ekind->tcstat[i].vscale_nhc), cr); } - gmx_bcast(DIM*DIM*sizeof(ekind->ekin[0][0]), - ekind->ekin[0], cr); + gmx_bcast(DIM * DIM * sizeof(ekind->ekin[0][0]), ekind->ekin[0], cr); gmx_bcast(sizeof(ekind->dekindl), &ekind->dekindl, cr); gmx_bcast(sizeof(ekind->cosacc.mvcos), &ekind->cosacc.mvcos, cr); @@ -1320,16 +1331,17 @@ void restore_ekinstate_from_state(const t_commrec *cr, } void update_tcouple(int64_t step, - const t_inputrec *inputrec, - t_state *state, - gmx_ekindata_t *ekind, - const t_extmass *MassQ, - const t_mdatoms *md) + const t_inputrec* inputrec, + t_state* state, + gmx_ekindata_t* ekind, + const t_extmass* MassQ, + const t_mdatoms* md) { // This condition was explicitly checked in previous version, but should have never been satisfied - GMX_ASSERT(!(EI_VV(inputrec->eI) && - (inputrecNvtTrotter(inputrec) || inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec))), + GMX_ASSERT(!(EI_VV(inputrec->eI) + && (inputrecNvtTrotter(inputrec) || inputrecNptTrotter(inputrec) + || inputrecNphTrotter(inputrec))), "Temperature coupling was requested with velocity verlet and trotter"); bool doTemperatureCoupling = false; @@ -1351,25 +1363,23 @@ void update_tcouple(int64_t step, if (doTemperatureCoupling) { - real dttc = inputrec->nsttcouple*inputrec->delta_t; + real dttc = inputrec->nsttcouple * inputrec->delta_t; - //TODO: berendsen_tcoupl(...), nosehoover_tcoupl(...) and vrescale_tcoupl(...) update + // TODO: berendsen_tcoupl(...), nosehoover_tcoupl(...) and vrescale_tcoupl(...) update // temperature coupling parameters, which should be reflected in the name of these // subroutines switch (inputrec->etc) { - case etcNO: - break; + case etcNO: break; case etcBERENDSEN: berendsen_tcoupl(inputrec, ekind, dttc, state->therm_integral); break; case etcNOSEHOOVER: - nosehoover_tcoupl(&(inputrec->opts), ekind, dttc, - state->nosehoover_xi.data(), state->nosehoover_vxi.data(), MassQ); + nosehoover_tcoupl(&(inputrec->opts), ekind, dttc, state->nosehoover_xi.data(), + state->nosehoover_vxi.data(), MassQ); break; case etcVRESCALE: - vrescale_tcoupl(inputrec, step, ekind, dttc, - state->therm_integral.data()); + vrescale_tcoupl(inputrec, step, ekind, dttc, state->therm_integral.data()); break; } /* rescale in place here */ @@ -1389,28 +1399,27 @@ void update_tcouple(int64_t step, } } -void getThreadAtomRange(int numThreads, int threadIndex, int numAtoms, - int *startAtom, int *endAtom) +void getThreadAtomRange(int numThreads, int threadIndex, int numAtoms, int* startAtom, int* endAtom) { #if GMX_HAVE_SIMD_UPDATE constexpr int blockSize = GMX_SIMD_REAL_WIDTH; #else constexpr int blockSize = 1; #endif - int numBlocks = (numAtoms + blockSize - 1)/blockSize; + int numBlocks = (numAtoms + blockSize - 1) / blockSize; - *startAtom = ((numBlocks* threadIndex )/numThreads)*blockSize; - *endAtom = ((numBlocks*(threadIndex + 1))/numThreads)*blockSize; + *startAtom = ((numBlocks * threadIndex) / numThreads) * blockSize; + *endAtom = ((numBlocks * (threadIndex + 1)) / numThreads) * blockSize; if (threadIndex == numThreads - 1) { - *endAtom = numAtoms; + *endAtom = numAtoms; } } -void update_pcouple_before_coordinates(FILE *fplog, +void update_pcouple_before_coordinates(FILE* fplog, int64_t step, - const t_inputrec *inputrec, - t_state *state, + const t_inputrec* inputrec, + t_state* state, matrix parrinellorahmanMu, matrix M, gmx_bool bInitStep) @@ -1418,25 +1427,24 @@ void update_pcouple_before_coordinates(FILE *fplog, /* Berendsen P-coupling is completely handled after the coordinate update. * Trotter P-coupling is handled by separate calls to trotter_update(). */ - if (inputrec->epc == epcPARRINELLORAHMAN && - do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple)) + if (inputrec->epc == epcPARRINELLORAHMAN + && do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple)) { - real dtpc = inputrec->nstpcouple*inputrec->delta_t; + real dtpc = inputrec->nstpcouple * inputrec->delta_t; - parrinellorahman_pcoupl(fplog, step, inputrec, dtpc, state->pres_prev, - state->box, state->box_rel, state->boxv, - M, parrinellorahmanMu, bInitStep); + parrinellorahman_pcoupl(fplog, step, inputrec, dtpc, state->pres_prev, state->box, + state->box_rel, state->boxv, M, parrinellorahmanMu, bInitStep); } } -void constrain_velocities(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - t_state *state, - tensor vir_part, - gmx::Constraints *constr, - gmx_bool bCalcVir, - bool do_log, - bool do_ene) +void constrain_velocities(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + t_state* state, + tensor vir_part, + gmx::Constraints* constr, + gmx_bool bCalcVir, + bool do_log, + bool do_ene) { if (!constr) { @@ -1456,11 +1464,8 @@ void constrain_velocities(int64_t step, clear_mat(vir_part); /* Constrain the coordinates upd->xp */ - constr->apply(do_log, do_ene, - step, 1, 1.0, - state->x.rvec_array(), state->v.rvec_array(), state->v.rvec_array(), - state->box, - state->lambda[efptBONDED], dvdlambda, + constr->apply(do_log, do_ene, step, 1, 1.0, state->x.rvec_array(), state->v.rvec_array(), + state->v.rvec_array(), state->box, state->lambda[efptBONDED], dvdlambda, nullptr, bCalcVir ? &vir_con : nullptr, ConstraintVariable::Velocities); if (bCalcVir) @@ -1470,12 +1475,12 @@ void constrain_velocities(int64_t step, } } -void constrain_coordinates(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - t_state *state, +void constrain_coordinates(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + t_state* state, tensor vir_part, - Update *upd, - gmx::Constraints *constr, + Update* upd, + gmx::Constraints* constr, gmx_bool bCalcVir, bool do_log, bool do_ene) @@ -1492,12 +1497,10 @@ void constrain_coordinates(int64_t step, clear_mat(vir_part); /* Constrain the coordinates upd->xp */ - constr->apply(do_log, do_ene, - step, 1, 1.0, - state->x.rvec_array(), upd->xp()->rvec_array(), nullptr, - state->box, - state->lambda[efptBONDED], dvdlambda, - as_rvec_array(state->v.data()), bCalcVir ? &vir_con : nullptr, ConstraintVariable::Positions); + constr->apply(do_log, do_ene, step, 1, 1.0, state->x.rvec_array(), upd->xp()->rvec_array(), + nullptr, state->box, state->lambda[efptBONDED], dvdlambda, + as_rvec_array(state->v.data()), bCalcVir ? &vir_con : nullptr, + ConstraintVariable::Positions); if (bCalcVir) { @@ -1506,19 +1509,18 @@ void constrain_coordinates(int64_t step, } } -void -update_sd_second_half(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - const t_inputrec *inputrec, /* input record and box stuff */ - const t_mdatoms *md, - t_state *state, - const t_commrec *cr, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - Update *upd, - gmx::Constraints *constr, - bool do_log, - bool do_ene) +void update_sd_second_half(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + const t_inputrec* inputrec, /* input record and box stuff */ + const t_mdatoms* md, + t_state* state, + const t_commrec* cr, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + Update* upd, + gmx::Constraints* constr, + bool do_log, + bool do_ene) { if (!constr) { @@ -1535,7 +1537,7 @@ update_sd_second_half(int64_t step, * integral += dt*integrand the increment is nearly always (much) smaller * than the integral (and the integrand has real precision). */ - real dt = inputrec->delta_t; + real dt = inputrec->delta_t; wallcycle_start(wcycle, ewcUPDATE); @@ -1549,40 +1551,32 @@ update_sd_second_half(int64_t step, int start_th, end_th; getThreadAtomRange(nth, th, homenr, &start_th, &end_th); - doSDUpdateGeneral - (*upd->sd(), - start_th, end_th, dt, - inputrec->opts.acc, inputrec->opts.nFreeze, - md->invmass, md->ptype, - md->cFREEZE, nullptr, md->cTC, - state->x.rvec_array(), upd->xp()->rvec_array(), - state->v.rvec_array(), nullptr, - step, inputrec->ld_seed, - DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); + doSDUpdateGeneral( + *upd->sd(), start_th, end_th, dt, inputrec->opts.acc, inputrec->opts.nFreeze, + md->invmass, md->ptype, md->cFREEZE, nullptr, md->cTC, state->x.rvec_array(), + upd->xp()->rvec_array(), state->v.rvec_array(), nullptr, step, inputrec->ld_seed, + DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } inc_nrnb(nrnb, eNR_UPDATE, homenr); wallcycle_stop(wcycle, ewcUPDATE); /* Constrain the coordinates upd->xp for half a time step */ - constr->apply(do_log, do_ene, - step, 1, 0.5, - state->x.rvec_array(), upd->xp()->rvec_array(), nullptr, - state->box, - state->lambda[efptBONDED], dvdlambda, + constr->apply(do_log, do_ene, step, 1, 0.5, state->x.rvec_array(), upd->xp()->rvec_array(), + nullptr, state->box, state->lambda[efptBONDED], dvdlambda, as_rvec_array(state->v.data()), nullptr, ConstraintVariable::Positions); } } -void finish_update(const t_inputrec *inputrec, /* input record and box stuff */ - const t_mdatoms *md, - t_state *state, - const t_graph *graph, - t_nrnb *nrnb, +void finish_update(const t_inputrec* inputrec, /* input record and box stuff */ + const t_mdatoms* md, + t_state* state, + const t_graph* graph, + t_nrnb* nrnb, gmx_wallcycle_t wcycle, - Update *upd, - const gmx::Constraints *constr) + Update* upd, + const gmx::Constraints* constr) { int homenr = md->homenr; @@ -1603,7 +1597,7 @@ void finish_update(const t_inputrec *inputrec, /* input record and box stu * be more elegant and slightly more efficient to copies zero * times instead of twice, but the graph case below prevents this. */ - const ivec *nFreeze = inputrec->opts.nFreeze; + const ivec* nFreeze = inputrec->opts.nFreeze; bool partialFreezeAndConstraints = false; for (int g = 0; g < inputrec->opts.ngfrz; g++) { @@ -1637,7 +1631,7 @@ void finish_update(const t_inputrec *inputrec, /* input record and box stu unshift_x(graph, state->box, state->x.rvec_array(), upd->xp()->rvec_array()); if (TRICLINIC(state->box)) { - inc_nrnb(nrnb, eNR_SHIFTX, 2*graph->nnodes); + inc_nrnb(nrnb, eNR_SHIFTX, 2 * graph->nnodes); } else { @@ -1646,8 +1640,8 @@ void finish_update(const t_inputrec *inputrec, /* input record and box stu } else { - auto xp = makeConstArrayRef(*upd->xp()).subArray(0, homenr); - auto x = makeArrayRef(state->x).subArray(0, homenr); + auto xp = makeConstArrayRef(*upd->xp()).subArray(0, homenr); + auto x = makeArrayRef(state->x).subArray(0, homenr); int gmx_unused nth = gmx_omp_nthreads_get(emntUpdate); @@ -1663,42 +1657,38 @@ void finish_update(const t_inputrec *inputrec, /* input record and box stu /* ############# END the update of velocities and positions ######### */ } -void update_pcouple_after_coordinates(FILE *fplog, +void update_pcouple_after_coordinates(FILE* fplog, int64_t step, - const t_inputrec *inputrec, - const t_mdatoms *md, + const t_inputrec* inputrec, + const t_mdatoms* md, const matrix pressure, const matrix forceVirial, const matrix constraintVirial, const matrix parrinellorahmanMu, - t_state *state, - t_nrnb *nrnb, - Update *upd) + t_state* state, + t_nrnb* nrnb, + Update* upd) { - int start = 0; - int homenr = md->homenr; + int start = 0; + int homenr = md->homenr; /* Cast to real for faster code, no loss in precision (see comment above) */ - real dt = inputrec->delta_t; + real dt = inputrec->delta_t; /* now update boxes */ switch (inputrec->epc) { - case (epcNO): - break; + case (epcNO): break; case (epcBERENDSEN): if (do_per_step(step, inputrec->nstpcouple)) { - real dtpc = inputrec->nstpcouple*dt; + real dtpc = inputrec->nstpcouple * dt; matrix mu; - berendsen_pcoupl(fplog, step, inputrec, dtpc, - pressure, state->box, - forceVirial, constraintVirial, - mu, &state->baros_integral); - berendsen_pscale(inputrec, mu, state->box, state->box_rel, - start, homenr, state->x.rvec_array(), - md->cFREEZE, nrnb); + berendsen_pcoupl(fplog, step, inputrec, dtpc, pressure, state->box, forceVirial, + constraintVirial, mu, &state->baros_integral); + berendsen_pscale(inputrec, mu, state->box, state->box_rel, start, homenr, + state->x.rvec_array(), md->cFREEZE, nrnb); } break; case (epcPARRINELLORAHMAN): @@ -1708,12 +1698,12 @@ void update_pcouple_after_coordinates(FILE *fplog, * but we dont change the box vectors until we get here * since we need to be able to shift/unshift above. */ - real dtpc = inputrec->nstpcouple*dt; + real dtpc = inputrec->nstpcouple * dt; for (int i = 0; i < DIM; i++) { for (int m = 0; m <= i; m++) { - state->box[i][m] += dtpc*state->boxv[i][m]; + state->box[i][m] += dtpc * state->boxv[i][m]; } } preserve_box_shape(inputrec, state->box_rel, state->box); @@ -1734,7 +1724,7 @@ void update_pcouple_after_coordinates(FILE *fplog, ln V_new = ln V_old + 3*dt*veta => V_new = V_old*exp(3*dt*veta) => Side length scales as exp(veta*dt) */ - msmul(state->box, std::exp(state->veta*dt), state->box); + msmul(state->box, std::exp(state->veta * dt), state->box); /* Relate veta to boxv. veta = d(eta)/dT = (1/DIM)*1/V dV/dT. o If we assume isotropic scaling, and box length scaling @@ -1747,12 +1737,10 @@ void update_pcouple_after_coordinates(FILE *fplog, msmul(state->box, state->veta, state->boxv); break; - default: - break; + default: break; } break; - default: - break; + default: break; } if (upd->deform()) @@ -1762,39 +1750,38 @@ void update_pcouple_after_coordinates(FILE *fplog, } } -void update_coords(int64_t step, - const t_inputrec *inputrec, /* input record and box stuff */ - const t_mdatoms *md, - t_state *state, +void update_coords(int64_t step, + const t_inputrec* inputrec, /* input record and box stuff */ + const t_mdatoms* md, + t_state* state, gmx::ArrayRefWithPadding f, - const t_fcdata *fcd, - const gmx_ekindata_t *ekind, + const t_fcdata* fcd, + const gmx_ekindata_t* ekind, const matrix M, - Update *upd, + Update* upd, int UpdatePart, - const t_commrec *cr, /* these shouldn't be here -- need to think about it */ - const gmx::Constraints *constr) + const t_commrec* cr, /* these shouldn't be here -- need to think about it */ + const gmx::Constraints* constr) { gmx_bool bDoConstr = (nullptr != constr); /* Running the velocity half does nothing except for velocity verlet */ - if ((UpdatePart == etrtVELOCITY1 || UpdatePart == etrtVELOCITY2) && - !EI_VV(inputrec->eI)) + if ((UpdatePart == etrtVELOCITY1 || UpdatePart == etrtVELOCITY2) && !EI_VV(inputrec->eI)) { gmx_incons("update_coords called for velocity without VV integrator"); } - int homenr = md->homenr; + int homenr = md->homenr; /* Cast to real for faster code, no loss in precision (see comment above) */ - real dt = inputrec->delta_t; + real dt = inputrec->delta_t; /* We need to update the NMR restraint history when time averaging is used */ - if (state->flags & (1<flags & (1 << estDISRE_RM3TAV)) { update_disres_history(fcd, &state->hist); } - if (state->flags & (1<flags & (1 << estORIRE_DTAV)) { update_orires_history(fcd, &state->hist); } @@ -1810,101 +1797,81 @@ void update_coords(int64_t step, int start_th, end_th; getThreadAtomRange(nth, th, homenr, &start_th, &end_th); - const rvec *x_rvec = state->x.rvec_array(); - rvec *xp_rvec = upd->xp()->rvec_array(); - rvec *v_rvec = state->v.rvec_array(); - const rvec *f_rvec = as_rvec_array(f.unpaddedArrayRef().data()); + const rvec* x_rvec = state->x.rvec_array(); + rvec* xp_rvec = upd->xp()->rvec_array(); + rvec* v_rvec = state->v.rvec_array(); + const rvec* f_rvec = as_rvec_array(f.unpaddedArrayRef().data()); switch (inputrec->eI) { case (eiMD): - do_update_md(start_th, end_th, step, dt, - inputrec, md, ekind, state->box, - x_rvec, xp_rvec, v_rvec, f_rvec, - state->nosehoover_vxi.data(), M); + do_update_md(start_th, end_th, step, dt, inputrec, md, ekind, state->box, + x_rvec, xp_rvec, v_rvec, f_rvec, state->nosehoover_vxi.data(), M); break; case (eiSD1): if (bDoConstr) { // With constraints, the SD update is done in 2 parts - doSDUpdateGeneral - (*upd->sd(), - start_th, end_th, dt, - inputrec->opts.acc, inputrec->opts.nFreeze, - md->invmass, md->ptype, - md->cFREEZE, md->cACC, nullptr, - x_rvec, xp_rvec, v_rvec, f_rvec, - step, inputrec->ld_seed, nullptr); + doSDUpdateGeneral( + *upd->sd(), start_th, end_th, dt, inputrec->opts.acc, inputrec->opts.nFreeze, + md->invmass, md->ptype, md->cFREEZE, md->cACC, nullptr, x_rvec, + xp_rvec, v_rvec, f_rvec, step, inputrec->ld_seed, nullptr); } else { - doSDUpdateGeneral - (*upd->sd(), - start_th, end_th, dt, - inputrec->opts.acc, inputrec->opts.nFreeze, - md->invmass, md->ptype, - md->cFREEZE, md->cACC, md->cTC, - x_rvec, xp_rvec, v_rvec, f_rvec, - step, inputrec->ld_seed, - DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); + doSDUpdateGeneral( + *upd->sd(), start_th, end_th, dt, inputrec->opts.acc, + inputrec->opts.nFreeze, md->invmass, md->ptype, md->cFREEZE, md->cACC, + md->cTC, x_rvec, xp_rvec, v_rvec, f_rvec, step, inputrec->ld_seed, + DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); } break; case (eiBD): - do_update_bd(start_th, end_th, dt, - inputrec->opts.nFreeze, md->invmass, md->ptype, - md->cFREEZE, md->cTC, - x_rvec, xp_rvec, v_rvec, f_rvec, - inputrec->bd_fric, - upd->sd()->bd_rf.data(), - step, inputrec->ld_seed, DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); + do_update_bd(start_th, end_th, dt, inputrec->opts.nFreeze, md->invmass, + md->ptype, md->cFREEZE, md->cTC, x_rvec, xp_rvec, v_rvec, f_rvec, + inputrec->bd_fric, upd->sd()->bd_rf.data(), step, inputrec->ld_seed, + DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr); break; case (eiVV): case (eiVVAK): { - gmx_bool bExtended = (inputrec->etc == etcNOSEHOOVER || - inputrec->epc == epcPARRINELLORAHMAN || - inputrec->epc == epcMTTK); + gmx_bool bExtended = (inputrec->etc == etcNOSEHOOVER || inputrec->epc == epcPARRINELLORAHMAN + || inputrec->epc == epcMTTK); /* assuming barostat coupled to group 0 */ - real alpha = 1.0 + DIM/static_cast(inputrec->opts.nrdf[0]); + real alpha = 1.0 + DIM / static_cast(inputrec->opts.nrdf[0]); switch (UpdatePart) { case etrtVELOCITY1: case etrtVELOCITY2: - do_update_vv_vel(start_th, end_th, dt, - inputrec->opts.acc, inputrec->opts.nFreeze, - md->invmass, md->ptype, - md->cFREEZE, md->cACC, - v_rvec, f_rvec, - bExtended, state->veta, alpha); + do_update_vv_vel(start_th, end_th, dt, inputrec->opts.acc, + inputrec->opts.nFreeze, md->invmass, md->ptype, md->cFREEZE, + md->cACC, v_rvec, f_rvec, bExtended, state->veta, alpha); break; case etrtPOSITION: - do_update_vv_pos(start_th, end_th, dt, - inputrec->opts.nFreeze, - md->ptype, md->cFREEZE, - x_rvec, xp_rvec, v_rvec, - bExtended, state->veta); + do_update_vv_pos(start_th, end_th, dt, inputrec->opts.nFreeze, md->ptype, + md->cFREEZE, x_rvec, xp_rvec, v_rvec, bExtended, state->veta); break; } break; } - default: - gmx_fatal(FARGS, "Don't know how to update coordinates"); + default: gmx_fatal(FARGS, "Don't know how to update coordinates"); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - } -extern gmx_bool update_randomize_velocities(const t_inputrec *ir, int64_t step, const t_commrec *cr, - const t_mdatoms *md, +extern gmx_bool update_randomize_velocities(const t_inputrec* ir, + int64_t step, + const t_commrec* cr, + const t_mdatoms* md, gmx::ArrayRef v, - const Update *upd, - const gmx::Constraints *constr) + const Update* upd, + const gmx::Constraints* constr) { - real rate = (ir->delta_t)/ir->opts.tau_t[0]; + real rate = (ir->delta_t) / ir->opts.tau_t[0]; if (ir->etc == etcANDERSEN && constr != nullptr) { @@ -1914,16 +1881,16 @@ extern gmx_bool update_randomize_velocities(const t_inputrec *ir, int64_t step, code could be ported to the current random-number generation approach, but has not yet been done because of lack of time and resources. */ - gmx_fatal(FARGS, "Normal Andersen is currently not supported with constraints, use massive Andersen instead"); + gmx_fatal(FARGS, + "Normal Andersen is currently not supported with constraints, use massive " + "Andersen instead"); } /* proceed with andersen if 1) it's fixed probability per particle andersen or 2) it's massive andersen and it's tau_t/dt */ - if ((ir->etc == etcANDERSEN) || do_per_step(step, roundToInt(1.0/rate))) + if ((ir->etc == etcANDERSEN) || do_per_step(step, roundToInt(1.0 / rate))) { - andersen_tcoupl(ir, step, cr, md, v, rate, - upd->sd()->randomize_group, - upd->sd()->boltzfac); + andersen_tcoupl(ir, step, cr, md, v, rate, upd->sd()->randomize_group, upd->sd()->boltzfac); return TRUE; } return FALSE; diff --git a/src/gromacs/mdlib/update.h b/src/gromacs/mdlib/update.h index 8272df55af..c5f2522f44 100644 --- a/src/gromacs/mdlib/update.h +++ b/src/gromacs/mdlib/update.h @@ -71,24 +71,25 @@ class Constraints; * \brief Contains data for update phase */ class Update { - public: - //! Constructor - Update(const t_inputrec *ir, BoxDeformation *boxDeformation); - ~Update(); - // TODO Get rid of getters when more free functions are incorporated as member methods - //! Returns handle to stochd_t struct - gmx_stochd_t * sd() const; - //! Returns pointer to PaddedVector xp - PaddedVector * xp(); - //! Returns handle to box deformation class - BoxDeformation * deform() const; - //! Resizes xp - void setNumAtoms(int nAtoms); - private: - //! Implementation type. - class Impl; - //! Implementation object. - PrivateImplPointer impl_; +public: + //! Constructor + Update(const t_inputrec* ir, BoxDeformation* boxDeformation); + ~Update(); + // TODO Get rid of getters when more free functions are incorporated as member methods + //! Returns handle to stochd_t struct + gmx_stochd_t* sd() const; + //! Returns pointer to PaddedVector xp + PaddedVector* xp(); + //! Returns handle to box deformation class + BoxDeformation* deform() const; + //! Resizes xp + void setNumAtoms(int nAtoms); + +private: + //! Implementation type. + class Impl; + //! Implementation object. + PrivateImplPointer impl_; }; }; // namespace gmx @@ -97,24 +98,23 @@ class Update * temperature for coupling. * * This could change e.g. in simulated annealing. */ -void update_temperature_constants(gmx_stochd_t *sd, const t_inputrec *ir); +void update_temperature_constants(gmx_stochd_t* sd, const t_inputrec* ir); /* Update the size of per-atom arrays (e.g. after DD re-partitioning, which might increase the number of home atoms). */ void update_tcouple(int64_t step, - const t_inputrec *inputrec, - t_state *state, - gmx_ekindata_t *ekind, - const t_extmass *MassQ, - const t_mdatoms *md - ); + const t_inputrec* inputrec, + t_state* state, + gmx_ekindata_t* ekind, + const t_extmass* MassQ, + const t_mdatoms* md); /* Update Parrinello-Rahman, to be called before the coordinate update */ -void update_pcouple_before_coordinates(FILE *fplog, +void update_pcouple_before_coordinates(FILE* fplog, int64_t step, - const t_inputrec *inputrec, - t_state *state, + const t_inputrec* inputrec, + t_state* state, matrix parrinellorahmanMu, matrix M, gmx_bool bInitStep); @@ -124,86 +124,92 @@ void update_pcouple_before_coordinates(FILE *fplog, * and scales the coordinates. * When the deform option is used, scales coordinates and box here. */ -void update_pcouple_after_coordinates(FILE *fplog, +void update_pcouple_after_coordinates(FILE* fplog, int64_t step, - const t_inputrec *inputrec, - const t_mdatoms *md, + const t_inputrec* inputrec, + const t_mdatoms* md, const matrix pressure, const matrix forceVirial, const matrix constraintVirial, const matrix parrinellorahmanMu, - t_state *state, - t_nrnb *nrnb, - gmx::Update *upd); - -void update_coords(int64_t step, - const t_inputrec *inputrec, /* input record and box stuff */ - const t_mdatoms *md, - t_state *state, + t_state* state, + t_nrnb* nrnb, + gmx::Update* upd); + +void update_coords(int64_t step, + const t_inputrec* inputrec, /* input record and box stuff */ + const t_mdatoms* md, + t_state* state, gmx::ArrayRefWithPadding f, /* forces on home particles */ - const t_fcdata *fcd, - const gmx_ekindata_t *ekind, + const t_fcdata* fcd, + const gmx_ekindata_t* ekind, const matrix M, - gmx::Update *upd, + gmx::Update* upd, int bUpdatePart, - const t_commrec *cr, /* these shouldn't be here -- need to think about it */ - const gmx::Constraints *constr); + const t_commrec* cr, /* these shouldn't be here -- need to think about it */ + const gmx::Constraints* constr); /* Return TRUE if OK, FALSE in case of Shake Error */ -extern gmx_bool update_randomize_velocities(const t_inputrec *ir, int64_t step, const t_commrec *cr, - const t_mdatoms *md, +extern gmx_bool update_randomize_velocities(const t_inputrec* ir, + int64_t step, + const t_commrec* cr, + const t_mdatoms* md, gmx::ArrayRef v, - const gmx::Update *upd, - const gmx::Constraints *constr); - -void constrain_velocities(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - t_state *state, - tensor vir_part, - gmx::Constraints *constr, - gmx_bool bCalcVir, - bool do_log, - bool do_ene); - -void constrain_coordinates(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - t_state *state, + const gmx::Update* upd, + const gmx::Constraints* constr); + +void constrain_velocities(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + t_state* state, + tensor vir_part, + gmx::Constraints* constr, + gmx_bool bCalcVir, + bool do_log, + bool do_ene); + +void constrain_coordinates(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + t_state* state, tensor vir_part, - gmx::Update *upd, - gmx::Constraints *constr, + gmx::Update* upd, + gmx::Constraints* constr, gmx_bool bCalcVir, bool do_log, bool do_ene); -void update_sd_second_half(int64_t step, - real *dvdlambda, /* the contribution to be added to the bonded interactions */ - const t_inputrec *inputrec, /* input record and box stuff */ - const t_mdatoms *md, - t_state *state, - const t_commrec *cr, - t_nrnb *nrnb, +void update_sd_second_half(int64_t step, + real* dvdlambda, /* the contribution to be added to the bonded interactions */ + const t_inputrec* inputrec, /* input record and box stuff */ + const t_mdatoms* md, + t_state* state, + const t_commrec* cr, + t_nrnb* nrnb, gmx_wallcycle_t wcycle, - gmx::Update *upd, - gmx::Constraints *constr, + gmx::Update* upd, + gmx::Constraints* constr, bool do_log, bool do_ene); -void finish_update(const t_inputrec *inputrec, - const t_mdatoms *md, - t_state *state, - const t_graph *graph, - t_nrnb *nrnb, +void finish_update(const t_inputrec* inputrec, + const t_mdatoms* md, + t_state* state, + const t_graph* graph, + t_nrnb* nrnb, gmx_wallcycle_t wcycle, - gmx::Update *upd, - const gmx::Constraints *constr); + gmx::Update* upd, + const gmx::Constraints* constr); /* Return TRUE if OK, FALSE in case of Shake Error */ -void calc_ke_part( - const rvec *x, const rvec *v, const matrix box, - const t_grpopts *opts, const t_mdatoms *md, - gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel); +void calc_ke_part(const rvec* x, + const rvec* v, + const matrix box, + const t_grpopts* opts, + const t_mdatoms* md, + gmx_ekindata_t* ekind, + t_nrnb* nrnb, + gmx_bool bEkinAveVel); /* * Compute the partial kinetic energy for home particles; * will be accumulated in the calling routine. @@ -221,90 +227,110 @@ void calc_ke_part( */ -void -init_ekinstate(ekinstate_t *ekinstate, const t_inputrec *ir); +void init_ekinstate(ekinstate_t* ekinstate, const t_inputrec* ir); -void -update_ekinstate(ekinstate_t *ekinstate, const gmx_ekindata_t *ekind); +void update_ekinstate(ekinstate_t* ekinstate, const gmx_ekindata_t* ekind); /*! \brief Restores data from \p ekinstate to \p ekind, then broadcasts it to the rest of the simulation */ -void -restore_ekinstate_from_state(const t_commrec *cr, - gmx_ekindata_t *ekind, const ekinstate_t *ekinstate); - -void berendsen_tcoupl(const t_inputrec *ir, gmx_ekindata_t *ekind, real dt, - std::vector &therm_integral); //NOLINT(google-runtime-references) - -void andersen_tcoupl(const t_inputrec *ir, int64_t step, - const t_commrec *cr, const t_mdatoms *md, - gmx::ArrayRef v, - real rate, const std::vector &randomize, +void restore_ekinstate_from_state(const t_commrec* cr, gmx_ekindata_t* ekind, const ekinstate_t* ekinstate); + +void berendsen_tcoupl(const t_inputrec* ir, + gmx_ekindata_t* ekind, + real dt, + std::vector& therm_integral); //NOLINT(google-runtime-references) + +void andersen_tcoupl(const t_inputrec* ir, + int64_t step, + const t_commrec* cr, + const t_mdatoms* md, + gmx::ArrayRef v, + real rate, + const std::vector& randomize, gmx::ArrayRef boltzfac); -void nosehoover_tcoupl(const t_grpopts *opts, const gmx_ekindata_t *ekind, real dt, - double xi[], double vxi[], const t_extmass *MassQ); - -void trotter_update(const t_inputrec *ir, int64_t step, gmx_ekindata_t *ekind, - const gmx_enerdata_t *enerd, t_state *state, const tensor vir, - const t_mdatoms *md, const t_extmass *MassQ, - gmx::ArrayRef < std::vector < int>> trotter_seqlist, int trotter_seqno); - -std::array < std::vector < int>, ettTSEQMAX> init_npt_vars(const t_inputrec *ir, t_state *state, - t_extmass *Mass, gmx_bool bTrotter); - -real NPT_energy(const t_inputrec *ir, const t_state *state, const t_extmass *MassQ); +void nosehoover_tcoupl(const t_grpopts* opts, + const gmx_ekindata_t* ekind, + real dt, + double xi[], + double vxi[], + const t_extmass* MassQ); + +void trotter_update(const t_inputrec* ir, + int64_t step, + gmx_ekindata_t* ekind, + const gmx_enerdata_t* enerd, + t_state* state, + const tensor vir, + const t_mdatoms* md, + const t_extmass* MassQ, + gmx::ArrayRef> trotter_seqlist, + int trotter_seqno); + +std::array, ettTSEQMAX> +init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* Mass, gmx_bool bTrotter); + +real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* MassQ); /* computes all the pressure/tempertature control energy terms to get a conserved energy */ -void vrescale_tcoupl(const t_inputrec *ir, int64_t step, - gmx_ekindata_t *ekind, real dt, - double therm_integral[]); +void vrescale_tcoupl(const t_inputrec* ir, int64_t step, gmx_ekindata_t* ekind, real dt, double therm_integral[]); /* Compute temperature scaling. For V-rescale it is done in update. */ -void rescale_velocities(const gmx_ekindata_t *ekind, const t_mdatoms *mdatoms, - int start, int end, rvec v[]); +void rescale_velocities(const gmx_ekindata_t* ekind, const t_mdatoms* mdatoms, int start, int end, rvec v[]); /* Rescale the velocities with the scaling factor in ekind */ //! Check whether we do simulated annealing. -bool doSimulatedAnnealing(const t_inputrec *ir); +bool doSimulatedAnnealing(const t_inputrec* ir); //! Initialize simulated annealing. -bool initSimulatedAnnealing(t_inputrec *ir, - gmx::Update *upd); +bool initSimulatedAnnealing(t_inputrec* ir, gmx::Update* upd); // TODO: This is the only function in update.h altering the inputrec -void update_annealing_target_temp(t_inputrec *ir, real t, gmx::Update *upd); +void update_annealing_target_temp(t_inputrec* ir, real t, gmx::Update* upd); /* Set reference temp for simulated annealing at time t*/ real calc_temp(real ekin, real nrdf); /* Calculate the temperature */ -real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const tensor vir, - tensor pres); +real calc_pres(int ePBC, int nwall, const matrix box, const tensor ekin, const tensor vir, tensor pres); /* Calculate the pressure tensor, returns the scalar pressure. * The unit of pressure is bar. */ -void parrinellorahman_pcoupl(FILE *fplog, int64_t step, - const t_inputrec *ir, real dt, const tensor pres, - const tensor box, tensor box_rel, tensor boxv, - tensor M, matrix mu, - gmx_bool bFirstStep); - -void berendsen_pcoupl(FILE *fplog, int64_t step, - const t_inputrec *ir, real dt, - const tensor pres, const matrix box, - const matrix force_vir, const matrix constraint_vir, - matrix mu, double *baros_integral); - -void berendsen_pscale(const t_inputrec *ir, const matrix mu, - matrix box, matrix box_rel, - int start, int nr_atoms, - rvec x[], const unsigned short cFREEZE[], - t_nrnb *nrnb); - -void pleaseCiteCouplingAlgorithms(FILE *fplog, - const t_inputrec &ir); +void parrinellorahman_pcoupl(FILE* fplog, + int64_t step, + const t_inputrec* ir, + real dt, + const tensor pres, + const tensor box, + tensor box_rel, + tensor boxv, + tensor M, + matrix mu, + gmx_bool bFirstStep); + +void berendsen_pcoupl(FILE* fplog, + int64_t step, + const t_inputrec* ir, + real dt, + const tensor pres, + const matrix box, + const matrix force_vir, + const matrix constraint_vir, + matrix mu, + double* baros_integral); + +void berendsen_pscale(const t_inputrec* ir, + const matrix mu, + matrix box, + matrix box_rel, + int start, + int nr_atoms, + rvec x[], + const unsigned short cFREEZE[], + t_nrnb* nrnb); + +void pleaseCiteCouplingAlgorithms(FILE* fplog, const t_inputrec& ir); /*! \brief Computes the atom range for a thread to operate on, ensuring SIMD aligned ranges * @@ -314,8 +340,7 @@ void pleaseCiteCouplingAlgorithms(FILE *fplog, * \param[out] startAtom The start of the atom range * \param[out] endAtom The end of the atom range, note that this is in general not a multiple of the SIMD width */ -void getThreadAtomRange(int numThreads, int threadIndex, int numAtoms, - int *startAtom, int *endAtom); +void getThreadAtomRange(int numThreads, int threadIndex, int numAtoms, int* startAtom, int* endAtom); /*! \brief Generate a new kinetic energy for the v-rescale thermostat * @@ -335,7 +360,6 @@ void getThreadAtomRange(int numThreads, int threadIndex, int numAtoms, * @param seed the random number generator seed * @return the new kinetic energy */ -real vrescale_resamplekin(real kk, real sigma, real ndeg, real taut, - int64_t step, int64_t seed); +real vrescale_resamplekin(real kk, real sigma, real ndeg, real taut, int64_t step, int64_t seed); #endif diff --git a/src/gromacs/mdlib/update_constrain_cuda.h b/src/gromacs/mdlib/update_constrain_cuda.h index 07add03456..0f83f710fd 100644 --- a/src/gromacs/mdlib/update_constrain_cuda.h +++ b/src/gromacs/mdlib/update_constrain_cuda.h @@ -65,90 +65,88 @@ namespace gmx class UpdateConstrainCuda { - public: - /*! \brief Create Update-Constrain object. - * - * The constructor is given a non-nullptr \p commandStream, in which all the update and constrain - * routines are executed. \p xUpdatedOnDevice should mark the completion of all kernels that modify - * coordinates. The event is maintained outside this class and also passed to all (if any) consumers - * of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr because the - * markEvent(...) method is called unconditionally. - * - * \param[in] ir Input record data: LINCS takes number of iterations and order of - * projection from it. - * \param[in] mtop Topology of the system: SETTLE gets the masses for O and H atoms - * and target O-H and H-H distances from this object. - * \param[in] commandStream GPU stream to use. Can be nullptr. - * \param[in] xUpdatedOnDevice The event synchronizer to use to mark that update is done on the GPU. - */ - UpdateConstrainCuda(const t_inputrec &ir, - const gmx_mtop_t &mtop, - const void *commandStream, - GpuEventSynchronizer *xUpdatedOnDevice); +public: + /*! \brief Create Update-Constrain object. + * + * The constructor is given a non-nullptr \p commandStream, in which all the update and constrain + * routines are executed. \p xUpdatedOnDevice should mark the completion of all kernels that modify + * coordinates. The event is maintained outside this class and also passed to all (if any) consumers + * of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr because the + * markEvent(...) method is called unconditionally. + * + * \param[in] ir Input record data: LINCS takes number of iterations and order of + * projection from it. + * \param[in] mtop Topology of the system: SETTLE gets the masses for O and H atoms + * and target O-H and H-H distances from this object. + * \param[in] commandStream GPU stream to use. Can be nullptr. + * \param[in] xUpdatedOnDevice The event synchronizer to use to mark that update is done on the GPU. + */ + UpdateConstrainCuda(const t_inputrec& ir, + const gmx_mtop_t& mtop, + const void* commandStream, + GpuEventSynchronizer* xUpdatedOnDevice); - ~UpdateConstrainCuda(); + ~UpdateConstrainCuda(); - /*! \brief Integrate - * - * This will extract temperature scaling factors from tcstat, transform them into the plain - * array and call the normal integrate method. - * - * \param[in] fReadyOnDevice Event synchronizer indicating that the forces are ready in the device memory. - * \param[in] dt Timestep. - * \param[in] updateVelocities If the velocities should be constrained. - * \param[in] computeVirial If virial should be updated. - * \param[out] virial Place to save virial tensor. - * \param[in] doTempCouple If the temperature coupling should be performed. - * \param[in] tcstat Temperature coupling data. - * \param[in] doPressureCouple If the temperature coupling should be applied. - * \param[in] dtPressureCouple Period between pressure coupling steps - * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix - */ - void integrate(GpuEventSynchronizer *fReadyOnDevice, - real dt, - bool updateVelocities, - bool computeVirial, - tensor virial, - bool doTempCouple, - gmx::ArrayRef tcstat, - bool doPressureCouple, - float dtPressureCouple, - const matrix velocityScalingMatrix); + /*! \brief Integrate + * + * This will extract temperature scaling factors from tcstat, transform them into the plain + * array and call the normal integrate method. + * + * \param[in] fReadyOnDevice Event synchronizer indicating that the forces are ready in + * the device memory. \param[in] dt Timestep. \param[in] updateVelocities + * If the velocities should be constrained. \param[in] computeVirial If virial should + * be updated. \param[out] virial Place to save virial tensor. \param[in] + * doTempCouple If the temperature coupling should be performed. \param[in] tcstat + * Temperature coupling data. \param[in] doPressureCouple If the temperature coupling + * should be applied. \param[in] dtPressureCouple Period between pressure coupling steps + * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix + */ + void integrate(GpuEventSynchronizer* fReadyOnDevice, + real dt, + bool updateVelocities, + bool computeVirial, + tensor virial, + bool doTempCouple, + gmx::ArrayRef tcstat, + bool doPressureCouple, + float dtPressureCouple, + const matrix velocityScalingMatrix); - /*! \brief Set the pointers and update data-structures (e.g. after NB search step). - * - * \param[in,out] d_x Device buffer with coordinates. - * \param[in,out] d_v Device buffer with velocities. - * \param[in] d_f Device buffer with forces. - * \param[in] idef System topology - * \param[in] md Atoms data. - * \param[in] numTempScaleValues Number of temperature scaling groups. Zero for no temperature scaling. - */ - void set(DeviceBuffer d_x, - DeviceBuffer d_v, - DeviceBuffer d_f, - const t_idef &idef, - const t_mdatoms &md, - int numTempScaleValues); + /*! \brief Set the pointers and update data-structures (e.g. after NB search step). + * + * \param[in,out] d_x Device buffer with coordinates. + * \param[in,out] d_v Device buffer with velocities. + * \param[in] d_f Device buffer with forces. + * \param[in] idef System topology + * \param[in] md Atoms data. + * \param[in] numTempScaleValues Number of temperature scaling groups. Zero for no temperature scaling. + */ + void set(DeviceBuffer d_x, + DeviceBuffer d_v, + DeviceBuffer d_f, + const t_idef& idef, + const t_mdatoms& md, + int numTempScaleValues); - /*! \brief - * Update PBC data. - * - * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. - * - * \param[in] pbc The PBC data in t_pbc format. - */ - void setPbc(const t_pbc *pbc); + /*! \brief + * Update PBC data. + * + * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. + * + * \param[in] pbc The PBC data in t_pbc format. + */ + void setPbc(const t_pbc* pbc); - /*! \brief Return the synchronizer associated with the event indicated that the coordinates are ready on the device. - */ - GpuEventSynchronizer* getCoordinatesReadySync(); + /*! \brief Return the synchronizer associated with the event indicated that the coordinates are ready on the device. + */ + GpuEventSynchronizer* getCoordinatesReadySync(); - private: - class Impl; - gmx::PrivateImplPointer impl_; +private: + class Impl; + gmx::PrivateImplPointer impl_; }; -} //namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdlib/update_constrain_cuda_impl.cpp b/src/gromacs/mdlib/update_constrain_cuda_impl.cpp index 80dadb153c..3f04316f2e 100644 --- a/src/gromacs/mdlib/update_constrain_cuda_impl.cpp +++ b/src/gromacs/mdlib/update_constrain_cuda_impl.cpp @@ -55,52 +55,57 @@ class UpdateConstrainCuda::Impl { }; -UpdateConstrainCuda::UpdateConstrainCuda(gmx_unused const t_inputrec &ir, - gmx_unused const gmx_mtop_t &mtop, - gmx_unused const void *commandStream, - gmx_unused GpuEventSynchronizer *xUpdatedOnDevice) - : impl_(nullptr) +UpdateConstrainCuda::UpdateConstrainCuda(gmx_unused const t_inputrec& ir, + gmx_unused const gmx_mtop_t& mtop, + gmx_unused const void* commandStream, + gmx_unused GpuEventSynchronizer* xUpdatedOnDevice) : + impl_(nullptr) { - GMX_ASSERT(false, "A CPU stub for UpdateConstrain was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for UpdateConstrain was called instead of the correct implementation."); } UpdateConstrainCuda::~UpdateConstrainCuda() = default; -void UpdateConstrainCuda::integrate(gmx_unused GpuEventSynchronizer *fReadyOnDevice, - gmx_unused const real dt, - gmx_unused const bool updateVelocities, - gmx_unused const bool computeVirial, - gmx_unused tensor virialScaled, - gmx_unused const bool doTempCouple, +void UpdateConstrainCuda::integrate(gmx_unused GpuEventSynchronizer* fReadyOnDevice, + gmx_unused const real dt, + gmx_unused const bool updateVelocities, + gmx_unused const bool computeVirial, + gmx_unused tensor virialScaled, + gmx_unused const bool doTempCouple, gmx_unused gmx::ArrayRef tcstat, gmx_unused const bool doPressureCouple, gmx_unused const float dtPressureCouple, - gmx_unused const matrix velocityScalingMatrix) + gmx_unused const matrix velocityScalingMatrix) { - GMX_ASSERT(false, "A CPU stub for UpdateConstrain was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for UpdateConstrain was called instead of the correct implementation."); } -void UpdateConstrainCuda::set(gmx_unused DeviceBuffer d_x, - gmx_unused DeviceBuffer d_v, - gmx_unused const DeviceBuffer d_f, - gmx_unused const t_idef &idef, - gmx_unused const t_mdatoms &md, - gmx_unused const int numTempScaleValues) +void UpdateConstrainCuda::set(gmx_unused DeviceBuffer d_x, + gmx_unused DeviceBuffer d_v, + gmx_unused const DeviceBuffer d_f, + gmx_unused const t_idef& idef, + gmx_unused const t_mdatoms& md, + gmx_unused const int numTempScaleValues) { - GMX_ASSERT(false, "A CPU stub for UpdateConstrain was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for UpdateConstrain was called instead of the correct implementation."); } -void UpdateConstrainCuda::setPbc(gmx_unused const t_pbc *pbc) +void UpdateConstrainCuda::setPbc(gmx_unused const t_pbc* pbc) { - GMX_ASSERT(false, "A CPU stub for UpdateConstrain was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for UpdateConstrain was called instead of the correct implementation."); } GpuEventSynchronizer* UpdateConstrainCuda::getCoordinatesReadySync() { - GMX_ASSERT(false, "A CPU stub for UpdateConstrain was called instead of the correct implementation."); + GMX_ASSERT(false, + "A CPU stub for UpdateConstrain was called instead of the correct implementation."); return nullptr; } -} // namespace gmx +} // namespace gmx #endif /* GMX_GPU != GMX_GPU_CUDA */ diff --git a/src/gromacs/mdlib/update_constrain_cuda_impl.cu b/src/gromacs/mdlib/update_constrain_cuda_impl.cu index e06aa7a5eb..b6ebffb24f 100644 --- a/src/gromacs/mdlib/update_constrain_cuda_impl.cu +++ b/src/gromacs/mdlib/update_constrain_cuda_impl.cu @@ -68,7 +68,7 @@ namespace gmx { -void UpdateConstrainCuda::Impl::integrate(GpuEventSynchronizer *fReadyOnDevice, +void UpdateConstrainCuda::Impl::integrate(GpuEventSynchronizer* fReadyOnDevice, const real dt, const bool updateVelocities, const bool computeVirial, @@ -86,28 +86,23 @@ void UpdateConstrainCuda::Impl::integrate(GpuEventSynchronizer *fRea // Make sure that the forces are ready on device before proceeding with the update. fReadyOnDevice->enqueueWaitEvent(commandStream_); - // The integrate should save a copy of the current coordinates in d_xp_ and write updated once into d_x_. - // The d_xp_ is only needed by constraints. - integrator_->integrate(d_x_, d_xp_, d_v_, d_f_, dt, - doTempCouple, tcstat, - doPressureCouple, dtPressureCouple, velocityScalingMatrix); + // The integrate should save a copy of the current coordinates in d_xp_ and write updated once + // into d_x_. The d_xp_ is only needed by constraints. + integrator_->integrate(d_x_, d_xp_, d_v_, d_f_, dt, doTempCouple, tcstat, doPressureCouple, + dtPressureCouple, velocityScalingMatrix); // Constraints need both coordinates before (d_x_) and after (d_xp_) update. However, after constraints // are applied, the d_x_ can be discarded. So we intentionally swap the d_x_ and d_xp_ here to avoid the // d_xp_ -> d_x_ copy after constraints. Note that the integrate saves them in the wrong order as well. - lincsCuda_->apply(d_xp_, d_x_, - updateVelocities, d_v_, 1.0/dt, - computeVirial, virial); - settleCuda_->apply(d_xp_, d_x_, - updateVelocities, d_v_, 1.0/dt, - computeVirial, virial); + lincsCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial); + settleCuda_->apply(d_xp_, d_x_, updateVelocities, d_v_, 1.0 / dt, computeVirial, virial); // scaledVirial -> virial (methods above returns scaled values) - float scaleFactor = 0.5f/(dt*dt); + float scaleFactor = 0.5f / (dt * dt); for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - virial[i][j] = scaleFactor*virial[i][j]; + virial[i][j] = scaleFactor * virial[i][j]; } } @@ -116,32 +111,30 @@ void UpdateConstrainCuda::Impl::integrate(GpuEventSynchronizer *fRea return; } -UpdateConstrainCuda::Impl::Impl(const t_inputrec &ir, - const gmx_mtop_t &mtop, - const void *commandStream, - GpuEventSynchronizer *xUpdatedOnDevice) : +UpdateConstrainCuda::Impl::Impl(const t_inputrec& ir, + const gmx_mtop_t& mtop, + const void* commandStream, + GpuEventSynchronizer* xUpdatedOnDevice) : coordinatesReady_(xUpdatedOnDevice) { GMX_ASSERT(xUpdatedOnDevice != nullptr, "The event synchronizer can not be nullptr."); - commandStream != nullptr ? commandStream_ = *static_cast(commandStream) : commandStream_ = nullptr; + commandStream != nullptr ? commandStream_ = *static_cast(commandStream) + : commandStream_ = nullptr; integrator_ = std::make_unique(commandStream_); lincsCuda_ = std::make_unique(ir.nLincsIter, ir.nProjOrder, commandStream_); settleCuda_ = std::make_unique(mtop, commandStream_); - } -UpdateConstrainCuda::Impl::~Impl() -{ -} +UpdateConstrainCuda::Impl::~Impl() {} -void UpdateConstrainCuda::Impl::set(DeviceBuffer d_x, - DeviceBuffer d_v, - const DeviceBuffer d_f, - const t_idef &idef, - const t_mdatoms &md, - const int numTempScaleValues) +void UpdateConstrainCuda::Impl::set(DeviceBuffer d_x, + DeviceBuffer d_v, + const DeviceBuffer d_f, + const t_idef& idef, + const t_mdatoms& md, + const int numTempScaleValues) { GMX_ASSERT(d_x != nullptr, "Coordinates device buffer should not be null."); GMX_ASSERT(d_v != nullptr, "Velocities device buffer should not be null."); @@ -155,8 +148,8 @@ void UpdateConstrainCuda::Impl::set(DeviceBuffer d_x, reallocateDeviceBuffer(&d_xp_, numAtoms_, &numXp_, &numXpAlloc_, nullptr); - reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, - &numInverseMasses_, &numInverseMassesAlloc_, nullptr); + reallocateDeviceBuffer(&d_inverseMasses_, numAtoms_, &numInverseMasses_, + &numInverseMassesAlloc_, nullptr); // Integrator should also update something, but it does not even have a method yet integrator_->set(md, numTempScaleValues, md.cTC); @@ -164,7 +157,7 @@ void UpdateConstrainCuda::Impl::set(DeviceBuffer d_x, settleCuda_->set(idef, md); } -void UpdateConstrainCuda::Impl::setPbc(const t_pbc *pbc) +void UpdateConstrainCuda::Impl::setPbc(const t_pbc* pbc) { setPbcAiuc(pbc->ndim_ePBC, pbc->box, &pbcAiuc_); integrator_->setPbc(pbc); @@ -177,17 +170,17 @@ GpuEventSynchronizer* UpdateConstrainCuda::Impl::getCoordinatesReadySync() return coordinatesReady_; } -UpdateConstrainCuda::UpdateConstrainCuda(const t_inputrec &ir, - const gmx_mtop_t &mtop, - const void *commandStream, - GpuEventSynchronizer *xUpdatedOnDevice) - : impl_(new Impl(ir, mtop, commandStream, xUpdatedOnDevice)) +UpdateConstrainCuda::UpdateConstrainCuda(const t_inputrec& ir, + const gmx_mtop_t& mtop, + const void* commandStream, + GpuEventSynchronizer* xUpdatedOnDevice) : + impl_(new Impl(ir, mtop, commandStream, xUpdatedOnDevice)) { } UpdateConstrainCuda::~UpdateConstrainCuda() = default; -void UpdateConstrainCuda::integrate(GpuEventSynchronizer *fReadyOnDevice, +void UpdateConstrainCuda::integrate(GpuEventSynchronizer* fReadyOnDevice, const real dt, const bool updateVelocities, const bool computeVirial, @@ -198,23 +191,21 @@ void UpdateConstrainCuda::integrate(GpuEventSynchronizer *fReadyOnDe const float dtPressureCouple, const matrix velocityScalingMatrix) { - impl_->integrate(fReadyOnDevice, - dt, updateVelocities, computeVirial, virialScaled, - doTempCouple, tcstat, - doPressureCouple, dtPressureCouple, velocityScalingMatrix); + impl_->integrate(fReadyOnDevice, dt, updateVelocities, computeVirial, virialScaled, doTempCouple, + tcstat, doPressureCouple, dtPressureCouple, velocityScalingMatrix); } -void UpdateConstrainCuda::set(DeviceBuffer d_x, - DeviceBuffer d_v, - const DeviceBuffer d_f, - const t_idef &idef, - const t_mdatoms &md, - const int numTempScaleValues) +void UpdateConstrainCuda::set(DeviceBuffer d_x, + DeviceBuffer d_v, + const DeviceBuffer d_f, + const t_idef& idef, + const t_mdatoms& md, + const int numTempScaleValues) { impl_->set(d_x, d_v, d_f, idef, md, numTempScaleValues); } -void UpdateConstrainCuda::setPbc(const t_pbc *pbc) +void UpdateConstrainCuda::setPbc(const t_pbc* pbc) { impl_->setPbc(pbc); } @@ -224,4 +215,4 @@ GpuEventSynchronizer* UpdateConstrainCuda::getCoordinatesReadySync() return impl_->getCoordinatesReadySync(); } -} //namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdlib/update_constrain_cuda_impl.h b/src/gromacs/mdlib/update_constrain_cuda_impl.h index b52cfce2c7..5ea66d34b9 100644 --- a/src/gromacs/mdlib/update_constrain_cuda_impl.h +++ b/src/gromacs/mdlib/update_constrain_cuda_impl.h @@ -62,132 +62,126 @@ namespace gmx class UpdateConstrainCuda::Impl { - public: - /*! \brief Create Update-Constrain object. - * - * The constructor is given a non-nullptr \p commandStream, in which all the update and constrain - * routines are executed. \p xUpdatedOnDevice should mark the completion of all kernels that modify - * coordinates. The event is maintained outside this class and also passed to all (if any) consumers - * of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr because the - * markEvent(...) method is called unconditionally. - * - * \param[in] ir Input record data: LINCS takes number of iterations and order of - * projection from it. - * \param[in] mtop Topology of the system: SETTLE gets the masses for O and H atoms - * and target O-H and H-H distances from this object. - * \param[in] commandStream GPU stream to use. Can be nullptr. - * \param[in] xUpdatedOnDevice The event synchronizer to use to mark that update is done on the GPU. - */ - Impl(const t_inputrec &ir, - const gmx_mtop_t &mtop, - const void *commandStream, - GpuEventSynchronizer *xUpdatedOnDevice); - - ~Impl(); - - /*! \brief Integrate - * - * Integrates the equation of motion using Leap-Frog algorithm and applies - * LINCS and SETTLE constraints. - * If computeVirial is true, constraints virial is written at the provided pointer. - * doTempCouple should be true if: - * 1. The temperature coupling is enabled. - * 2. This is the temperature coupling step. - * Parameters virial/lambdas can be nullptr if computeVirial/doTempCouple are false. - * - * \param[in] fReadyOnDevice Event synchronizer indicating that the forces are ready in the device memory. - * \param[in] dt Timestep. - * \param[in] updateVelocities If the velocities should be constrained. - * \param[in] computeVirial If virial should be updated. - * \param[out] virial Place to save virial tensor. - * \param[in] doTempCouple If the temperature coupling should be performed. - * \param[in] tcstat Temperature coupling data. - * \param[in] doPressureCouple If the temperature coupling should be applied. - * \param[in] dtPressureCouple Period between pressure coupling steps - * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix - */ - void integrate(GpuEventSynchronizer *fReadyOnDevice, - real dt, - bool updateVelocities, - bool computeVirial, - tensor virial, - bool doTempCouple, - gmx::ArrayRef tcstat, - bool doPressureCouple, - float dtPressureCouple, - const matrix velocityScalingMatrix); - - /*! \brief Set the pointers and update data-structures (e.g. after NB search step). - * - * \param[in,out] d_x Device buffer with coordinates. - * \param[in,out] d_v Device buffer with velocities. - * \param[in] d_f Device buffer with forces. - * \param[in] idef System topology - * \param[in] md Atoms data. - * \param[in] numTempScaleValues Number of temperature scaling groups. Set zero for no temperature coupling. - */ - void set(DeviceBuffer d_x, - DeviceBuffer d_v, - const DeviceBuffer d_f, - const t_idef &idef, - const t_mdatoms &md, - const int numTempScaleValues); - - /*! \brief - * Update PBC data. - * - * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. - * - * \param[in] pbc The PBC data in t_pbc format. - */ - void setPbc(const t_pbc *pbc); - - /*! \brief Return the synchronizer associated with the event indicated that the coordinates are ready on the device. - */ - GpuEventSynchronizer* getCoordinatesReadySync(); - - private: - - //! CUDA stream - CommandStream commandStream_ = nullptr; - - //! Periodic boundary data - PbcAiuc pbcAiuc_; - - //! Number of atoms - int numAtoms_; - - //! Local copy of the pointer to the device positions buffer - float3 *d_x_; - //! Local copy of the pointer to the device velocities buffer - float3 *d_v_; - //! Local copy of the pointer to the device forces buffer - float3 *d_f_; - - //! Device buffer for intermediate positions (maintained internally) - float3 *d_xp_; - //! Number of elements in shifted coordinates buffer - int numXp_ = -1; - //! Allocation size for the shifted coordinates buffer - int numXpAlloc_ = -1; - - - //! 1/mass for all atoms (GPU) - real *d_inverseMasses_; - //! Number of elements in reciprocal masses buffer - int numInverseMasses_ = -1; - //! Allocation size for the reciprocal masses buffer - int numInverseMassesAlloc_ = -1; - - //! Leap-Frog integrator - std::unique_ptr integrator_; - //! LINCS CUDA object to use for non-water constraints - std::unique_ptr lincsCuda_; - //! SETTLE CUDA object for water constrains - std::unique_ptr settleCuda_; - - //! An pointer to the event to indicate when the update of coordinates is complete - GpuEventSynchronizer *coordinatesReady_; +public: + /*! \brief Create Update-Constrain object. + * + * The constructor is given a non-nullptr \p commandStream, in which all the update and constrain + * routines are executed. \p xUpdatedOnDevice should mark the completion of all kernels that modify + * coordinates. The event is maintained outside this class and also passed to all (if any) consumers + * of the updated coordinates. The \p xUpdatedOnDevice also can not be a nullptr because the + * markEvent(...) method is called unconditionally. + * + * \param[in] ir Input record data: LINCS takes number of iterations and order of + * projection from it. + * \param[in] mtop Topology of the system: SETTLE gets the masses for O and H atoms + * and target O-H and H-H distances from this object. + * \param[in] commandStream GPU stream to use. Can be nullptr. + * \param[in] xUpdatedOnDevice The event synchronizer to use to mark that update is done on the GPU. + */ + Impl(const t_inputrec& ir, const gmx_mtop_t& mtop, const void* commandStream, GpuEventSynchronizer* xUpdatedOnDevice); + + ~Impl(); + + /*! \brief Integrate + * + * Integrates the equation of motion using Leap-Frog algorithm and applies + * LINCS and SETTLE constraints. + * If computeVirial is true, constraints virial is written at the provided pointer. + * doTempCouple should be true if: + * 1. The temperature coupling is enabled. + * 2. This is the temperature coupling step. + * Parameters virial/lambdas can be nullptr if computeVirial/doTempCouple are false. + * + * \param[in] fReadyOnDevice Event synchronizer indicating that the forces are ready in + * the device memory. \param[in] dt Timestep. \param[in] updateVelocities + * If the velocities should be constrained. \param[in] computeVirial If virial should + * be updated. \param[out] virial Place to save virial tensor. \param[in] + * doTempCouple If the temperature coupling should be performed. \param[in] tcstat + * Temperature coupling data. \param[in] doPressureCouple If the temperature coupling + * should be applied. \param[in] dtPressureCouple Period between pressure coupling steps + * \param[in] velocityScalingMatrix Parrinello-Rahman velocity scaling matrix + */ + void integrate(GpuEventSynchronizer* fReadyOnDevice, + real dt, + bool updateVelocities, + bool computeVirial, + tensor virial, + bool doTempCouple, + gmx::ArrayRef tcstat, + bool doPressureCouple, + float dtPressureCouple, + const matrix velocityScalingMatrix); + + /*! \brief Set the pointers and update data-structures (e.g. after NB search step). + * + * \param[in,out] d_x Device buffer with coordinates. + * \param[in,out] d_v Device buffer with velocities. + * \param[in] d_f Device buffer with forces. + * \param[in] idef System topology + * \param[in] md Atoms data. + * \param[in] numTempScaleValues Number of temperature scaling groups. Set zero for no temperature coupling. + */ + void set(DeviceBuffer d_x, + DeviceBuffer d_v, + const DeviceBuffer d_f, + const t_idef& idef, + const t_mdatoms& md, + const int numTempScaleValues); + + /*! \brief + * Update PBC data. + * + * Converts PBC data from t_pbc into the PbcAiuc format and stores the latter. + * + * \param[in] pbc The PBC data in t_pbc format. + */ + void setPbc(const t_pbc* pbc); + + /*! \brief Return the synchronizer associated with the event indicated that the coordinates are ready on the device. + */ + GpuEventSynchronizer* getCoordinatesReadySync(); + +private: + //! CUDA stream + CommandStream commandStream_ = nullptr; + + //! Periodic boundary data + PbcAiuc pbcAiuc_; + + //! Number of atoms + int numAtoms_; + + //! Local copy of the pointer to the device positions buffer + float3* d_x_; + //! Local copy of the pointer to the device velocities buffer + float3* d_v_; + //! Local copy of the pointer to the device forces buffer + float3* d_f_; + + //! Device buffer for intermediate positions (maintained internally) + float3* d_xp_; + //! Number of elements in shifted coordinates buffer + int numXp_ = -1; + //! Allocation size for the shifted coordinates buffer + int numXpAlloc_ = -1; + + + //! 1/mass for all atoms (GPU) + real* d_inverseMasses_; + //! Number of elements in reciprocal masses buffer + int numInverseMasses_ = -1; + //! Allocation size for the reciprocal masses buffer + int numInverseMassesAlloc_ = -1; + + //! Leap-Frog integrator + std::unique_ptr integrator_; + //! LINCS CUDA object to use for non-water constraints + std::unique_ptr lincsCuda_; + //! SETTLE CUDA object for water constrains + std::unique_ptr settleCuda_; + + //! An pointer to the event to indicate when the update of coordinates is complete + GpuEventSynchronizer* coordinatesReady_; }; } // namespace gmx diff --git a/src/gromacs/mdlib/updategroups.cpp b/src/gromacs/mdlib/updategroups.cpp index f78c58c00c..5ee169a473 100644 --- a/src/gromacs/mdlib/updategroups.cpp +++ b/src/gromacs/mdlib/updategroups.cpp @@ -61,10 +61,9 @@ namespace gmx { /*! \brief Returns whether \p moltype contains flexible constraints */ -static bool hasFlexibleConstraints(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams) +static bool hasFlexibleConstraints(const gmx_moltype_t& moltype, gmx::ArrayRef iparams) { - for (auto &ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) + for (auto& ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) { if (ilist.functionType != F_SETTLE) { @@ -86,18 +85,17 @@ static bool hasFlexibleConstraints(const gmx_moltype_t &moltype, * For simplicity the only compatible vsites are linear 2 or 3 atom sites * that are constructed in between the 2 or 3 contructing atoms, */ -static bool hasIncompatibleVsites(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams) +static bool hasIncompatibleVsites(const gmx_moltype_t& moltype, gmx::ArrayRef iparams) { bool hasIncompatibleVsites = false; - for (auto &ilist : extractILists(moltype.ilist, IF_VSITE)) + for (auto& ilist : extractILists(moltype.ilist, IF_VSITE)) { if (ilist.functionType == F_VSITE2 || ilist.functionType == F_VSITE3) { for (size_t i = 0; i < ilist.iatoms.size(); i += ilistStride(ilist)) { - const t_iparams &iparam = iparams[ilist.iatoms[i]]; + const t_iparams& iparam = iparams[ilist.iatoms[i]]; real coeffMin; real coeffSum; if (ilist.functionType == F_VSITE2) @@ -128,12 +126,12 @@ static bool hasIncompatibleVsites(const gmx_moltype_t &moltype, } /*! \brief Returns a merged list with constraints of all types */ -static InteractionList jointConstraintList(const gmx_moltype_t &moltype) +static InteractionList jointConstraintList(const gmx_moltype_t& moltype) { InteractionList ilistCombined; - std::vector &iatoms = ilistCombined.iatoms; + std::vector& iatoms = ilistCombined.iatoms; - for (auto &ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) + for (auto& ilist : extractILists(moltype.ilist, IF_CONSTRAINT)) { if (ilist.functionType == F_SETTLE) { @@ -152,10 +150,10 @@ static InteractionList jointConstraintList(const gmx_moltype_t &moltype) } else { - GMX_RELEASE_ASSERT(NRAL(ilist.functionType) == 2, "Can only handle two-atom non-SETTLE constraints"); + GMX_RELEASE_ASSERT(NRAL(ilist.functionType) == 2, + "Can only handle two-atom non-SETTLE constraints"); - iatoms.insert(iatoms.end(), - ilist.iatoms.begin(), ilist.iatoms.end()); + iatoms.insert(iatoms.end(), ilist.iatoms.begin(), ilist.iatoms.end()); } } @@ -170,13 +168,11 @@ struct AtomIndexExtremes }; /*! \brief Returns the range of constructing atom for vsite with atom index \p a */ -static AtomIndexExtremes -vsiteConstructRange(int a, - const gmx_moltype_t &moltype) +static AtomIndexExtremes vsiteConstructRange(int a, const gmx_moltype_t& moltype) { AtomIndexExtremes extremes = { -1, -1 }; - for (auto &ilist : extractILists(moltype.ilist, IF_VSITE)) + for (auto& ilist : extractILists(moltype.ilist, IF_VSITE)) { for (size_t i = 0; i < ilist.iatoms.size(); i += ilistStride(ilist)) { @@ -200,10 +196,7 @@ vsiteConstructRange(int a, } /*! \brief Returns the range of atoms constrained to atom \p a (including \p a itself) */ -static AtomIndexExtremes -constraintAtomRange(int a, - const t_blocka &at2con, - const InteractionList &ilistConstraints) +static AtomIndexExtremes constraintAtomRange(int a, const t_blocka& at2con, const InteractionList& ilistConstraints) { AtomIndexExtremes extremes = { a, a }; @@ -211,7 +204,7 @@ constraintAtomRange(int a, { for (int j = 0; j < 2; j++) { - int atomJ = ilistConstraints.iatoms[at2con.a[i]*3 + 1 + j]; + int atomJ = ilistConstraints.iatoms[at2con.a[i] * 3 + 1 + j]; extremes.minAtom = std::min(extremes.minAtom, atomJ); extremes.maxAtom = std::max(extremes.maxAtom, atomJ); } @@ -221,11 +214,11 @@ constraintAtomRange(int a, } /*! \brief Returns a list that tells whether atoms in \p moltype are vsites */ -static std::vector buildIsParticleVsite(const gmx_moltype_t &moltype) +static std::vector buildIsParticleVsite(const gmx_moltype_t& moltype) { std::vector isVsite(moltype.atoms.nr); - for (auto &ilist : extractILists(moltype.ilist, IF_VSITE)) + for (auto& ilist : extractILists(moltype.ilist, IF_VSITE)) { for (size_t i = 0; i < ilist.iatoms.size(); i += ilistStride(ilist)) { @@ -239,9 +232,9 @@ static std::vector buildIsParticleVsite(const gmx_moltype_t &moltype) /*! \brief Returns the size of the update group starting at \p firstAtom or 0 when criteria (see updategroups.h) are not met */ static int detectGroup(int firstAtom, - const gmx_moltype_t &moltype, - const t_blocka &at2con, - const InteractionList &ilistConstraints) + const gmx_moltype_t& moltype, + const t_blocka& at2con, + const InteractionList& ilistConstraints) { /* We should be using moltype.atoms.atom[].ptype for checking whether * a particle is a vsite. But the test code can't fill t_atoms, @@ -250,8 +243,7 @@ static int detectGroup(int firstAtom, std::vector isParticleVsite = buildIsParticleVsite(moltype); /* A non-vsite atom without constraints is an update group by itself */ - if (!isParticleVsite[firstAtom] && - at2con.index[firstAtom + 1] - at2con.index[firstAtom] == 0) + if (!isParticleVsite[firstAtom] && at2con.index[firstAtom + 1] - at2con.index[firstAtom] == 0) { return 1; } @@ -293,10 +285,9 @@ static int detectGroup(int firstAtom, * and whether we need to extend the group. */ numAtomsWithConstraints += 1; - maxConstraintsPerAtom = std::max(maxConstraintsPerAtom, numConstraints); + maxConstraintsPerAtom = std::max(maxConstraintsPerAtom, numConstraints); - AtomIndexExtremes extremes = - constraintAtomRange(a, at2con, ilistConstraints); + AtomIndexExtremes extremes = constraintAtomRange(a, at2con, ilistConstraints); if (extremes.minAtom < firstAtom) { /* Constraint to atom outside the "group" */ @@ -311,8 +302,7 @@ static int detectGroup(int firstAtom, /* lastAtom might be followed by a vsite that is constructed from atoms * with index <= lastAtom. Handle this case. */ - if (lastAtom + 1 < moltype.atoms.nr && - isParticleVsite[lastAtom + 1]) + if (lastAtom + 1 < moltype.atoms.nr && isParticleVsite[lastAtom + 1]) { AtomIndexExtremes extremes = vsiteConstructRange(lastAtom + 1, moltype); if (extremes.minAtom < firstAtom) @@ -345,9 +335,7 @@ static int detectGroup(int firstAtom, } /*! \brief Returns a list of update groups for \p moltype */ -static RangePartitioning -makeUpdateGroups(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams) +static RangePartitioning makeUpdateGroups(const gmx_moltype_t& moltype, gmx::ArrayRef iparams) { RangePartitioning groups; @@ -356,8 +344,7 @@ makeUpdateGroups(const gmx_moltype_t &moltype, * but since performance for EM/NM is less critical, we do not * use update groups to keep the code here simpler. */ - if (hasFlexibleConstraints(moltype, iparams) || - hasIncompatibleVsites(moltype, iparams)) + if (hasFlexibleConstraints(moltype, iparams) || hasIncompatibleVsites(moltype, iparams)) { return groups; } @@ -365,21 +352,19 @@ makeUpdateGroups(const gmx_moltype_t &moltype, /* Combine all constraint ilists into a single one */ InteractionList constraintsCombined = jointConstraintList(moltype); t_ilist ilistsCombined[F_NRE]; - ilistsCombined[F_CONSTR].nr = constraintsCombined.iatoms.size(); - ilistsCombined[F_CONSTR].iatoms = constraintsCombined.iatoms.data(); - ilistsCombined[F_CONSTRNC].nr = 0; + ilistsCombined[F_CONSTR].nr = constraintsCombined.iatoms.size(); + ilistsCombined[F_CONSTR].iatoms = constraintsCombined.iatoms.data(); + ilistsCombined[F_CONSTRNC].nr = 0; /* We "include" flexible constraints, but none are present (checked above) */ - t_blocka at2con = make_at2con(moltype.atoms.nr, - ilistsCombined, iparams.data(), - FlexibleConstraintTreatment::Include); + t_blocka at2con = make_at2con(moltype.atoms.nr, ilistsCombined, iparams.data(), + FlexibleConstraintTreatment::Include); bool satisfiesCriteria = true; - int firstAtom = 0; + int firstAtom = 0; while (satisfiesCriteria && firstAtom < moltype.atoms.nr) { - int numAtomsInGroup = - detectGroup(firstAtom, moltype, at2con, constraintsCombined); + int numAtomsInGroup = detectGroup(firstAtom, moltype, at2con, constraintsCombined); if (numAtomsInGroup == 0) { @@ -403,12 +388,12 @@ makeUpdateGroups(const gmx_moltype_t &moltype, return groups; } -std::vector makeUpdateGroups(const gmx_mtop_t &mtop) +std::vector makeUpdateGroups(const gmx_mtop_t& mtop) { std::vector updateGroups; - bool systemSatisfiesCriteria = true; - for (const gmx_moltype_t &moltype : mtop.moltype) + bool systemSatisfiesCriteria = true; + for (const gmx_moltype_t& moltype : mtop.moltype) { updateGroups.push_back(makeUpdateGroups(moltype, mtop.ffparams.iparams)); @@ -427,10 +412,9 @@ std::vector makeUpdateGroups(const gmx_mtop_t &mtop) } /*! \brief Returns a map of angles ilist.iatoms indices with the middle atom as key */ -static std::unordered_multimap -getAngleIndices(const gmx_moltype_t &moltype) +static std::unordered_multimap getAngleIndices(const gmx_moltype_t& moltype) { - const InteractionList &angles = moltype.ilist[F_ANGLES]; + const InteractionList& angles = moltype.ilist[F_ANGLES]; std::unordered_multimap indices(angles.size()); @@ -453,22 +437,23 @@ getAngleIndices(const gmx_moltype_t &moltype) * by one angle potential, when a potential is perturbed or when an angle * could reach more than 180 degrees. */ -template static real -constraintGroupRadius(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams, - const int centralAtom, - const t_blocka &at2con, - const std::unordered_multimap &angleIndices, - const real constraintLength, - const real temperature) +template +static real constraintGroupRadius(const gmx_moltype_t& moltype, + gmx::ArrayRef iparams, + const int centralAtom, + const t_blocka& at2con, + const std::unordered_multimap& angleIndices, + const real constraintLength, + const real temperature) { const int numConstraints = at2con.index[centralAtom + 1] - at2con.index[centralAtom]; - GMX_RELEASE_ASSERT(numConstraints == numPartnerAtoms, "We expect as many constraints as partner atoms here"); + GMX_RELEASE_ASSERT(numConstraints == numPartnerAtoms, + "We expect as many constraints as partner atoms here"); std::array partnerAtoms; for (int i = 0; i < numPartnerAtoms; i++) { - const int ind = at2con.a[at2con.index[centralAtom] + i]*3; + const int ind = at2con.a[at2con.index[centralAtom] + i] * 3; if (ind >= moltype.ilist[F_CONSTR].size()) { /* This is a flexible constraint, we don't optimize for that */ @@ -479,18 +464,18 @@ constraintGroupRadius(const gmx_moltype_t &moltype, partnerAtoms[i] = (a1 == centralAtom ? a2 : a1); } - const InteractionList &angles = moltype.ilist[F_ANGLES]; - auto range = angleIndices.equal_range(centralAtom); - int angleType = -1; - std::array numAngles = { 0 }; - bool areSameType = true; + const InteractionList& angles = moltype.ilist[F_ANGLES]; + auto range = angleIndices.equal_range(centralAtom); + int angleType = -1; + std::array numAngles = { 0 }; + bool areSameType = true; for (auto it = range.first; it != range.second; ++it) { /* Check if the outer atoms in the angle are both partner atoms */ int numAtomsFound = 0; for (int ind = it->second + 1; ind < it->second + 4; ind += 2) { - for (const int &partnerAtom : partnerAtoms) + for (const int& partnerAtom : partnerAtoms) { if (angles.iatoms[ind] == partnerAtom) { @@ -533,17 +518,16 @@ constraintGroupRadius(const gmx_moltype_t &moltype, } /* We don't bother optimizing the perturbed angle case */ - const t_iparams &angleParams = iparams[angleType]; - if (criteriaSatisfied && - angleParams.harmonic.rB == angleParams.harmonic.rA && - angleParams.harmonic.krB == angleParams.harmonic.krA) + const t_iparams& angleParams = iparams[angleType]; + if (criteriaSatisfied && angleParams.harmonic.rB == angleParams.harmonic.rA + && angleParams.harmonic.krB == angleParams.harmonic.krA) { /* Set number of stddevs such that change of exceeding < 10^-9 */ constexpr real c_numSigma = 6.0; /* Compute the maximally stretched angle */ - const real eqAngle = angleParams.harmonic.rA*DEG2RAD; - const real fc = angleParams.harmonic.krA; - const real maxAngle = eqAngle + c_numSigma*BOLTZ*temperature/((numPartnerAtoms - 1)*fc); + const real eqAngle = angleParams.harmonic.rA * DEG2RAD; + const real fc = angleParams.harmonic.krA; + const real maxAngle = eqAngle + c_numSigma * BOLTZ * temperature / ((numPartnerAtoms - 1) * fc); if (maxAngle >= M_PI) { return -1; @@ -556,9 +540,9 @@ constraintGroupRadius(const gmx_moltype_t &moltype, * Return the distance from the COG to the farthest two corners, * i.e. the partner atoms. */ - real distMidPartner = std::sin(0.5*maxAngle)*constraintLength; - real distCentralMid = std::cos(0.5*maxAngle)*constraintLength; - real distCogMid = distCentralMid*numPartnerAtoms/(numPartnerAtoms + 1); + real distMidPartner = std::sin(0.5 * maxAngle) * constraintLength; + real distCentralMid = std::cos(0.5 * maxAngle) * constraintLength; + real distCogMid = distCentralMid * numPartnerAtoms / (numPartnerAtoms + 1); real distCogPartner = std::sqrt(gmx::square(distMidPartner) + gmx::square(distCogMid)); return distCogPartner; @@ -577,14 +561,19 @@ constraintGroupRadius(const gmx_moltype_t &moltype, * Then we compute the distance of the central atom to the plane. * The distance of the COG to the ourlier is returned. */ - real halfDistEqPartner = std::sin(0.5*eqAngle)*constraintLength; - real distPartnerOutlier = 2*std::sin(0.5*maxAngle)*constraintLength; - real distMidOutlier = std::sqrt(gmx::square(distPartnerOutlier) - gmx::square(halfDistEqPartner)); - real distMidCenterInPlane = 0.5*(distMidOutlier - gmx::square(halfDistEqPartner)/distMidOutlier); - real distCentralToPlane = std::sqrt(gmx::square(constraintLength) - gmx::square(halfDistEqPartner) - gmx::square(distMidCenterInPlane)); - real distCogOutlierH = distCentralToPlane/(numPartnerAtoms + 1); - real distCogOutlierP = distMidOutlier - (distMidOutlier + distMidCenterInPlane)/(numPartnerAtoms + 1); - real distCogOutlier = std::sqrt(gmx::square(distCogOutlierH) + gmx::square(distCogOutlierP)); + real halfDistEqPartner = std::sin(0.5 * eqAngle) * constraintLength; + real distPartnerOutlier = 2 * std::sin(0.5 * maxAngle) * constraintLength; + real distMidOutlier = + std::sqrt(gmx::square(distPartnerOutlier) - gmx::square(halfDistEqPartner)); + real distMidCenterInPlane = + 0.5 * (distMidOutlier - gmx::square(halfDistEqPartner) / distMidOutlier); + real distCentralToPlane = + std::sqrt(gmx::square(constraintLength) - gmx::square(halfDistEqPartner) + - gmx::square(distMidCenterInPlane)); + real distCogOutlierH = distCentralToPlane / (numPartnerAtoms + 1); + real distCogOutlierP = + distMidOutlier - (distMidOutlier + distMidCenterInPlane) / (numPartnerAtoms + 1); + real distCogOutlier = std::sqrt(gmx::square(distCogOutlierH) + gmx::square(distCogOutlierP)); return distCogOutlier; } @@ -598,23 +587,21 @@ constraintGroupRadius(const gmx_moltype_t &moltype, } /*! \brief Returns the maximum update group radius for \p moltype */ -static real -computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, - gmx::ArrayRef iparams, - const RangePartitioning &updateGroups, - real temperature) +static real computeMaxUpdateGroupRadius(const gmx_moltype_t& moltype, + gmx::ArrayRef iparams, + const RangePartitioning& updateGroups, + real temperature) { GMX_RELEASE_ASSERT(!hasFlexibleConstraints(moltype, iparams), "Flexible constraints are not supported here"); - const InteractionList &settles = moltype.ilist[F_SETTLE]; + const InteractionList& settles = moltype.ilist[F_SETTLE]; - t_blocka at2con = - make_at2con(moltype, iparams, FlexibleConstraintTreatment::Include); + t_blocka at2con = make_at2con(moltype, iparams, FlexibleConstraintTreatment::Include); const auto angleIndices = getAngleIndices(moltype); - real maxRadius = 0; + real maxRadius = 0; for (int group = 0; group < updateGroups.numBlocks(); group++) { if (updateGroups.block(group).size() == 1) @@ -648,7 +635,7 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, real sumConstraintLengths = 0; for (int i = at2con.index[maxAtom]; i < at2con.index[maxAtom + 1]; i++) { - int conIndex = at2con.a[i]*(1 + NRAL(F_CONSTR)); + int conIndex = at2con.a[i] * (1 + NRAL(F_CONSTR)); int iparamsIndex; if (conIndex < moltype.ilist[F_CONSTR].size()) { @@ -656,7 +643,8 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, } else { - iparamsIndex = moltype.ilist[F_CONSTRNC].iatoms[conIndex - moltype.ilist[F_CONSTR].size()]; + iparamsIndex = + moltype.ilist[F_CONSTRNC].iatoms[conIndex - moltype.ilist[F_CONSTR].size()]; } if (i == at2con.index[maxAtom]) { @@ -670,11 +658,10 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, * topology, which assumes lambda is between 0 and 1 for * free-energy runs. */ - real constraintLength = std::max(iparams[iparamsIndex].constr.dA, - iparams[iparamsIndex].constr.dB); - maxConstraintLength = std::max(maxConstraintLength, - constraintLength); - sumConstraintLengths += constraintLength; + real constraintLength = + std::max(iparams[iparamsIndex].constr.dA, iparams[iparamsIndex].constr.dB); + maxConstraintLength = std::max(maxConstraintLength, constraintLength); + sumConstraintLengths += constraintLength; } int numConstraints = at2con.index[maxAtom + 1] - at2con.index[maxAtom]; @@ -682,7 +669,7 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, if (numConstraints == 1) { /* Single constraint: the radius is the distance from the midpoint */ - radius = 0.5_real*maxConstraintLength; + radius = 0.5_real * maxConstraintLength; } else { @@ -693,11 +680,8 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, */ if (numConstraints == 2 && allTypesAreEqual && temperature > 0) { - radius = constraintGroupRadius<2>(moltype, iparams, - maxAtom, at2con, - angleIndices, - maxConstraintLength, - temperature); + radius = constraintGroupRadius<2>(moltype, iparams, maxAtom, at2con, angleIndices, + maxConstraintLength, temperature); } /* With 3 constraints the maximum possible radius is 1.4 times * the constraint length, so it is worth computing a smaller @@ -705,11 +689,8 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, */ if (numConstraints == 3 && allTypesAreEqual && temperature >= 0) { - radius = constraintGroupRadius<3>(moltype, iparams, - maxAtom, at2con, - angleIndices, - maxConstraintLength, - temperature); + radius = constraintGroupRadius<3>(moltype, iparams, maxAtom, at2con, angleIndices, + maxConstraintLength, temperature); if (temperature == 0 && radius >= 0) { /* Add a 10% margin for deviation at 0 K */ @@ -722,7 +703,8 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, /* Worst case: atom with the longest constraint on one side * of the center, all others on the opposite side */ - radius = maxConstraintLength + (sumConstraintLengths - 2*maxConstraintLength)/(numConstraints + 1); + radius = maxConstraintLength + + (sumConstraintLengths - 2 * maxConstraintLength) / (numConstraints + 1); } } maxRadius = std::max(maxRadius, radius); @@ -730,11 +712,11 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, for (int i = 0; i < settles.size(); i += 1 + NRAL(F_SETTLE)) { - const real dOH = iparams[settles.iatoms[i]].settle.doh; - const real dHH = iparams[settles.iatoms[i]].settle.dhh; + const real dOH = iparams[settles.iatoms[i]].settle.doh; + const real dHH = iparams[settles.iatoms[i]].settle.dhh; /* Compute distance^2 from center of geometry to O and H */ - const real dCO2 = (4*dOH*dOH - dHH*dHH)/9; - const real dCH2 = (dOH*dOH + 2*dHH*dHH)/9; + const real dCO2 = (4 * dOH * dOH - dHH * dHH) / 9; + const real dCH2 = (dOH * dOH + 2 * dHH * dHH) / 9; const real dCAny = std::sqrt(std::max(dCO2, dCH2)); maxRadius = std::max(maxRadius, dCAny); } @@ -744,10 +726,9 @@ computeMaxUpdateGroupRadius(const gmx_moltype_t &moltype, return maxRadius; } -real -computeMaxUpdateGroupRadius(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroups, - real temperature) +real computeMaxUpdateGroupRadius(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroups, + real temperature) { if (updateGroups.empty()) { @@ -761,12 +742,9 @@ computeMaxUpdateGroupRadius(const gmx_mtop_t &mtop, for (size_t moltype = 0; moltype < mtop.moltype.size(); moltype++) { - maxRadius - = std::max(maxRadius, - computeMaxUpdateGroupRadius(mtop.moltype[moltype], - mtop.ffparams.iparams, - updateGroups[moltype], - temperature)); + maxRadius = std::max( + maxRadius, computeMaxUpdateGroupRadius(mtop.moltype[moltype], mtop.ffparams.iparams, + updateGroups[moltype], temperature)); } return maxRadius; diff --git a/src/gromacs/mdlib/updategroups.h b/src/gromacs/mdlib/updategroups.h index 775cdbf119..b88306b092 100644 --- a/src/gromacs/mdlib/updategroups.h +++ b/src/gromacs/mdlib/updategroups.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,7 +71,7 @@ class RangePartitioning; * * \param[in] mtop The system topology */ -std::vector makeUpdateGroups(const gmx_mtop_t &mtop); +std::vector makeUpdateGroups(const gmx_mtop_t& mtop); /*! \brief Returns the maximum update group radius * @@ -81,10 +81,10 @@ std::vector makeUpdateGroups(const gmx_mtop_t &mtop); * \param[in] updateGroups List of update group, size should match the number of moltypes in \p mtop or be 0 * \param[in] temperature The maximum reference temperature, pass -1 when unknown or not applicable */ -real computeMaxUpdateGroupRadius(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroups, - real temperature); +real computeMaxUpdateGroupRadius(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroups, + real temperature); -} // namespace gmx +} // namespace gmx #endif // GMX_MDLIB_UPDATEGROUPS diff --git a/src/gromacs/mdlib/updategroupscog.cpp b/src/gromacs/mdlib/updategroupscog.cpp index f17b9a9ebd..2739a398bc 100644 --- a/src/gromacs/mdlib/updategroupscog.cpp +++ b/src/gromacs/mdlib/updategroupscog.cpp @@ -52,62 +52,56 @@ namespace gmx { -UpdateGroupsCog::UpdateGroupsCog(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroupsPerMoleculetype, - real temperature, - int numHomeAtoms) : +UpdateGroupsCog::UpdateGroupsCog(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroupsPerMoleculetype, + real temperature, + int numHomeAtoms) : globalToLocalMap_(numHomeAtoms), mtop_(mtop) { int firstUpdateGroupInMolecule = 0; - for (const auto &molblock : mtop.molblock) + for (const auto& molblock : mtop.molblock) { - const auto &updateGroups = updateGroupsPerMoleculetype[molblock.type]; - indicesPerMoleculeblock_.push_back({ firstUpdateGroupInMolecule, - updateGroups.numBlocks(), - {} }); - auto &groupIndex = indicesPerMoleculeblock_.back().groupIndex_; + const auto& updateGroups = updateGroupsPerMoleculetype[molblock.type]; + indicesPerMoleculeblock_.push_back({ firstUpdateGroupInMolecule, updateGroups.numBlocks(), {} }); + auto& groupIndex = indicesPerMoleculeblock_.back().groupIndex_; for (int block = 0; block < updateGroups.numBlocks(); block++) { - groupIndex.insert(groupIndex.end(), - updateGroups.block(block).size(), - block); + groupIndex.insert(groupIndex.end(), updateGroups.block(block).size(), block); } - firstUpdateGroupInMolecule += molblock.nmol*updateGroups.numBlocks(); + firstUpdateGroupInMolecule += molblock.nmol * updateGroups.numBlocks(); } - maxUpdateGroupRadius_ = - computeMaxUpdateGroupRadius(mtop, updateGroupsPerMoleculetype, temperature); + maxUpdateGroupRadius_ = computeMaxUpdateGroupRadius(mtop, updateGroupsPerMoleculetype, temperature); } -void UpdateGroupsCog::addCogs(gmx::ArrayRef globalAtomIndices, - gmx::ArrayRef coordinates) +void UpdateGroupsCog::addCogs(gmx::ArrayRef globalAtomIndices, + gmx::ArrayRef coordinates) { const int localAtomBegin = cogIndices_.size(); const size_t cogBegin = cogs_.size(); GMX_RELEASE_ASSERT(globalAtomIndices.ssize() >= localAtomBegin, - "addCogs should only be called to add COGs to the list that is already present (which could be empty)"); + "addCogs should only be called to add COGs to the list that is already " + "present (which could be empty)"); cogIndices_.reserve(globalAtomIndices.size()); int moleculeBlock = 0; for (gmx::index localAtom = localAtomBegin; localAtom < globalAtomIndices.ssize(); localAtom++) { - const int globalAtom = globalAtomIndices[localAtom]; - int moleculeIndex; - int atomIndexInMolecule; - mtopGetMolblockIndex(&mtop_, globalAtom, - &moleculeBlock, &moleculeIndex, &atomIndexInMolecule); - const auto &indicesForBlock = indicesPerMoleculeblock_[moleculeBlock]; - int globalUpdateGroupIndex = - indicesForBlock.groupStart_ + - moleculeIndex*indicesForBlock.numGroupsPerMolecule_ + - indicesForBlock.groupIndex_[atomIndexInMolecule]; - - if (const int *cogIndexPtr = globalToLocalMap_.find(globalUpdateGroupIndex)) + const int globalAtom = globalAtomIndices[localAtom]; + int moleculeIndex; + int atomIndexInMolecule; + mtopGetMolblockIndex(&mtop_, globalAtom, &moleculeBlock, &moleculeIndex, &atomIndexInMolecule); + const auto& indicesForBlock = indicesPerMoleculeblock_[moleculeBlock]; + int globalUpdateGroupIndex = indicesForBlock.groupStart_ + + moleculeIndex * indicesForBlock.numGroupsPerMolecule_ + + indicesForBlock.groupIndex_[atomIndexInMolecule]; + + if (const int* cogIndexPtr = globalToLocalMap_.find(globalUpdateGroupIndex)) { GMX_ASSERT(static_cast(*cogIndexPtr) >= cogBegin, "Added atoms should not be part of previously present groups"); diff --git a/src/gromacs/mdlib/updategroupscog.h b/src/gromacs/mdlib/updategroupscog.h index b0c6c57168..65c6ac978d 100644 --- a/src/gromacs/mdlib/updategroupscog.h +++ b/src/gromacs/mdlib/updategroupscog.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,115 +60,105 @@ class RangePartitioning; */ class UpdateGroupsCog { - public: - /*! \brief Constructor - * - * The temperature is used for computing the maximum update group - * radius. - * - * \note \p numHomeAtoms only affects the performance up till the first - * call to clear(). - * - * \param[in] mtop The global topology - * \param[in] updateGroupsPerMoleculetype List of update groups for each molecule type in \p mtop - * \param[in] temperature The maximum reference temperature, pass -1 when unknown or not applicable - * \param[in] numHomeAtoms Estimate of the number of home atoms per DD cell - */ - UpdateGroupsCog(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroupsPerMoleculetype, - real temperature, - int numHomeAtoms); - - /*! \brief Compute centers of geometry for supplied coordinates - * - * Coordinates are processed starting after the last index - * processed in the previous call to \p addCogs(), unless \p clear() - * was called last, in which case processing starts at 0. - * - * \param[in] globalAtomIndices List of global atom indices for the atoms belonging to \p coordinates - * \param[in] coordinates List of coordinates to be processed, processing might not start at 0 (see above) - */ - void addCogs(gmx::ArrayRef globalAtomIndices, - gmx::ArrayRef coordinates); - - /*! \brief Returns the number of centers of geometry currently stored */ - int numCogs() const - { - return cogs_.size(); - } - - /*! \brief Returns a reference to a center of geometry - * - * \param[in] cogIndex The COG requested, should be; 0 <= \p cogIndex < cogs_.size() - */ - RVec &cog(int cogIndex) - { - GMX_ASSERT(cogIndex >= 0 && static_cast(cogIndex) < cogs_.size(), - "cogIndex should be in the range set in this object"); - - return cogs_[cogIndex]; - } - - /*! \brief Returns the COG index given an atom index - * - * \param[in] atomIndex The local atom index that maps to the COG - */ - int cogIndex(int atomIndex) const - { - GMX_ASSERT(atomIndex >= 0 && static_cast(atomIndex) < cogIndices_.size(), - "atomIndex should be in the range set in this object"); - - return cogIndices_[atomIndex]; - } - - /*! \brief Return a reference to a center of geometry given an atom index - * - * \param[in] atomIndex The atom index that maps to the COG requested - */ - const RVec &cogForAtom(int atomIndex) const - { - return cogs_[cogIndex(atomIndex)]; - } - - /*! \brief Clear the lists of stored center of geometry coordinates */ - void clear(); - - /*! \brief Returns the maximum radius over all update groups */ - real maxUpdateGroupRadius() const - { - return maxUpdateGroupRadius_; - } - - private: - /*! \libinternal - * \brief Helper struct for mapping atom indices to COG indices, used per molecule block in mtop - */ - struct IndexToGroup - { - //! \brief Starting index of groups for this molblock - int groupStart_; - //! \brief The number of atoms in a molecule - int numGroupsPerMolecule_; - //! \brief Map atom indices to group indices for one molecule - std::vector groupIndex_; - }; - - //! \brief Maps atom indices to COG indices - std::vector cogIndices_; - //! \brief List of COGs - std::vector cogs_; - //! \brief List of the number of atoms for each COG - std::vector numAtomsPerCog_; - //! \brief Maps global COG index to local COG index - HashedMap globalToLocalMap_; - //! \brief Helper data for mapping atom indices to COG indices - std::vector indicesPerMoleculeblock_; - //! \brief The maximum radius over all update groups - real maxUpdateGroupRadius_; - //! \brief Reference to mtop this object was constructed with - const gmx_mtop_t &mtop_; +public: + /*! \brief Constructor + * + * The temperature is used for computing the maximum update group + * radius. + * + * \note \p numHomeAtoms only affects the performance up till the first + * call to clear(). + * + * \param[in] mtop The global topology + * \param[in] updateGroupsPerMoleculetype List of update groups for each molecule type in \p mtop + * \param[in] temperature The maximum reference temperature, pass -1 when unknown or not applicable + * \param[in] numHomeAtoms Estimate of the number of home atoms per DD cell + */ + UpdateGroupsCog(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroupsPerMoleculetype, + real temperature, + int numHomeAtoms); + + /*! \brief Compute centers of geometry for supplied coordinates + * + * Coordinates are processed starting after the last index + * processed in the previous call to \p addCogs(), unless \p clear() + * was called last, in which case processing starts at 0. + * + * \param[in] globalAtomIndices List of global atom indices for the atoms belonging to \p coordinates + * \param[in] coordinates List of coordinates to be processed, processing might not start at 0 (see above) + */ + void addCogs(gmx::ArrayRef globalAtomIndices, gmx::ArrayRef coordinates); + + /*! \brief Returns the number of centers of geometry currently stored */ + int numCogs() const { return cogs_.size(); } + + /*! \brief Returns a reference to a center of geometry + * + * \param[in] cogIndex The COG requested, should be; 0 <= \p cogIndex < cogs_.size() + */ + RVec& cog(int cogIndex) + { + GMX_ASSERT(cogIndex >= 0 && static_cast(cogIndex) < cogs_.size(), + "cogIndex should be in the range set in this object"); + + return cogs_[cogIndex]; + } + + /*! \brief Returns the COG index given an atom index + * + * \param[in] atomIndex The local atom index that maps to the COG + */ + int cogIndex(int atomIndex) const + { + GMX_ASSERT(atomIndex >= 0 && static_cast(atomIndex) < cogIndices_.size(), + "atomIndex should be in the range set in this object"); + + return cogIndices_[atomIndex]; + } + + /*! \brief Return a reference to a center of geometry given an atom index + * + * \param[in] atomIndex The atom index that maps to the COG requested + */ + const RVec& cogForAtom(int atomIndex) const { return cogs_[cogIndex(atomIndex)]; } + + /*! \brief Clear the lists of stored center of geometry coordinates */ + void clear(); + + /*! \brief Returns the maximum radius over all update groups */ + real maxUpdateGroupRadius() const { return maxUpdateGroupRadius_; } + +private: + /*! \libinternal + * \brief Helper struct for mapping atom indices to COG indices, used per molecule block in mtop + */ + struct IndexToGroup + { + //! \brief Starting index of groups for this molblock + int groupStart_; + //! \brief The number of atoms in a molecule + int numGroupsPerMolecule_; + //! \brief Map atom indices to group indices for one molecule + std::vector groupIndex_; + }; + + //! \brief Maps atom indices to COG indices + std::vector cogIndices_; + //! \brief List of COGs + std::vector cogs_; + //! \brief List of the number of atoms for each COG + std::vector numAtomsPerCog_; + //! \brief Maps global COG index to local COG index + HashedMap globalToLocalMap_; + //! \brief Helper data for mapping atom indices to COG indices + std::vector indicesPerMoleculeblock_; + //! \brief The maximum radius over all update groups + real maxUpdateGroupRadius_; + //! \brief Reference to mtop this object was constructed with + const gmx_mtop_t& mtop_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDLIB_UPDATEGROUPSCOG diff --git a/src/gromacs/mdlib/vcm.cpp b/src/gromacs/mdlib/vcm.cpp index 34c5d7f9bf..28efb3b800 100644 --- a/src/gromacs/mdlib/vcm.cpp +++ b/src/gromacs/mdlib/vcm.cpp @@ -54,17 +54,16 @@ #include "gromacs/utility/gmxomp.h" #include "gromacs/utility/smalloc.h" -t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir) : +t_vcm::t_vcm(const SimulationGroups& groups, const t_inputrec& ir) : integratorConservesMomentum(!EI_RANDOM(ir.eI)) { mode = (ir.nstcomm > 0) ? ir.comm_mode : ecmNO; ndim = ndof_com(&ir); - timeStep = ir.nstcomm*ir.delta_t; + timeStep = ir.nstcomm * ir.delta_t; if (mode == ecmANGULAR && ndim < 3) { - gmx_fatal(FARGS, "Can not have angular comm removal with pbc=%s", - epbc_names[ir.ePBC]); + gmx_fatal(FARGS, "Can not have angular comm removal with pbc=%s", epbc_names[ir.ePBC]); } if (mode != ecmNO) @@ -83,7 +82,6 @@ t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir) : group_j.resize(size); group_x.resize(size); group_w.resize(size); - } group_name.resize(size); @@ -93,9 +91,9 @@ t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir) : group_ndf.resize(size); for (int g = 0; (g < nr); g++) { - group_ndf[g] = ir.opts.nrdf[g]; - group_name[g] = *groups.groupNames[groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval][g]]; - + group_ndf[g] = ir.opts.nrdf[g]; + group_name[g] = + *groups.groupNames[groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval][g]]; } thread_vcm.resize(gmx_omp_nthreads_get(emntDefault) * stride); @@ -112,15 +110,15 @@ t_vcm::~t_vcm() } } -void reportComRemovalInfo(FILE * fp, const t_vcm &vcm) +void reportComRemovalInfo(FILE* fp, const t_vcm& vcm) { /* Copy pointer to group names and print it. */ if (fp && vcm.mode != ecmNO) { - fprintf(fp, "Center of mass motion removal mode is %s\n", - ECOM(vcm.mode)); - fprintf(fp, "We have the following groups for center of" + fprintf(fp, "Center of mass motion removal mode is %s\n", ECOM(vcm.mode)); + fprintf(fp, + "We have the following groups for center of" " mass motion removal:\n"); for (int g = 0; (g < vcm.nr); g++) @@ -137,12 +135,12 @@ static void update_tensor(const rvec x, real m0, tensor I) real xy, xz, yz; /* Compute inertia tensor contribution due to this atom */ - xy = x[XX]*x[YY]*m0; - xz = x[XX]*x[ZZ]*m0; - yz = x[YY]*x[ZZ]*m0; - I[XX][XX] += x[XX]*x[XX]*m0; - I[YY][YY] += x[YY]*x[YY]*m0; - I[ZZ][ZZ] += x[ZZ]*x[ZZ]*m0; + xy = x[XX] * x[YY] * m0; + xz = x[XX] * x[ZZ] * m0; + yz = x[YY] * x[ZZ] * m0; + I[XX][XX] += x[XX] * x[XX] * m0; + I[YY][YY] += x[YY] * x[YY] * m0; + I[ZZ][ZZ] += x[ZZ] * x[ZZ] * m0; I[XX][YY] += xy; I[YY][XX] += xy; I[XX][ZZ] += xz; @@ -152,8 +150,7 @@ static void update_tensor(const rvec x, real m0, tensor I) } /* Center of mass code for groups */ -void calc_vcm_grp(const t_mdatoms &md, - const rvec x[], const rvec v[], t_vcm *vcm) +void calc_vcm_grp(const t_mdatoms& md, const rvec x[], const rvec v[], t_vcm* vcm) { int nthreads = gmx_omp_nthreads_get(emntDefault); if (vcm->mode != ecmNO) @@ -164,8 +161,8 @@ void calc_vcm_grp(const t_mdatoms &md, for (int g = 0; g < vcm->size; g++) { /* Reset linear momentum */ - t_vcm_thread *vcm_t = &vcm->thread_vcm[t*vcm->stride + g]; - vcm_t->mass = 0; + t_vcm_thread* vcm_t = &vcm->thread_vcm[t * vcm->stride + g]; + vcm_t->mass = 0; clear_rvec(vcm_t->p); if (vcm->mode == ecmANGULAR) { @@ -185,25 +182,25 @@ void calc_vcm_grp(const t_mdatoms &md, { g = md.cVCM[i]; } - t_vcm_thread *vcm_t = &vcm->thread_vcm[t*vcm->stride + g]; + t_vcm_thread* vcm_t = &vcm->thread_vcm[t * vcm->stride + g]; /* Calculate linear momentum */ - vcm_t->mass += m0; + vcm_t->mass += m0; int m; for (m = 0; (m < DIM); m++) { - vcm_t->p[m] += m0*v[i][m]; + vcm_t->p[m] += m0 * v[i][m]; } if (vcm->mode == ecmANGULAR) { /* Calculate angular momentum */ - rvec j0; + rvec j0; cprod(x[i], v[i], j0); for (m = 0; (m < DIM); m++) { - vcm_t->j[m] += m0*j0[m]; - vcm_t->x[m] += m0*x[i][m]; + vcm_t->j[m] += m0 * j0[m]; + vcm_t->x[m] += m0 * x[i][m]; } /* Update inertia tensor */ update_tensor(x[i], m0, vcm_t->i); @@ -226,7 +223,7 @@ void calc_vcm_grp(const t_mdatoms &md, for (int t = 0; t < nthreads; t++) { - t_vcm_thread *vcm_t = &vcm->thread_vcm[t*vcm->stride + g]; + t_vcm_thread* vcm_t = &vcm->thread_vcm[t * vcm->stride + g]; vcm->group_mass[g] += vcm_t->mass; rvec_inc(vcm->group_p[g], vcm_t->p); if (vcm->mode == ecmANGULAR) @@ -237,7 +234,6 @@ void calc_vcm_grp(const t_mdatoms &md, } } } - } } @@ -251,13 +247,10 @@ void calc_vcm_grp(const t_mdatoms &md, * \param[in] vcm VCM data */ template -static void -doStopComMotionLinear(const t_mdatoms &mdatoms, - rvec *v, - const t_vcm &vcm) +static void doStopComMotionLinear(const t_mdatoms& mdatoms, rvec* v, const t_vcm& vcm) { const int homenr = mdatoms.homenr; - const unsigned short *group_id = mdatoms.cVCM; + const unsigned short* group_id = mdatoms.cVCM; if (mdatoms.cFREEZE != nullptr) { @@ -314,14 +307,13 @@ doStopComMotionLinear(const t_mdatoms &mdatoms, * \param[in] vcm VCM data */ template -static void -doStopComMotionAccelerationCorrection(int homenr, - const unsigned short *group_id, - rvec * gmx_restrict x, - rvec * gmx_restrict v, - const t_vcm &vcm) +static void doStopComMotionAccelerationCorrection(int homenr, + const unsigned short* group_id, + rvec* gmx_restrict x, + rvec* gmx_restrict v, + const t_vcm& vcm) { - const real xCorrectionFactor = 0.5*vcm.timeStep; + const real xCorrectionFactor = 0.5 * vcm.timeStep; if (group_id == nullptr) { @@ -330,7 +322,7 @@ doStopComMotionAccelerationCorrection(int homenr, { for (int d = 0; d < numDimensions; d++) { - x[i][d] -= vcm.group_v[0][d]*xCorrectionFactor; + x[i][d] -= vcm.group_v[0][d] * xCorrectionFactor; v[i][d] -= vcm.group_v[0][d]; } } @@ -343,45 +335,39 @@ doStopComMotionAccelerationCorrection(int homenr, const int g = group_id[i]; for (int d = 0; d < numDimensions; d++) { - x[i][d] -= vcm.group_v[g][d]*xCorrectionFactor; + x[i][d] -= vcm.group_v[g][d] * xCorrectionFactor; v[i][d] -= vcm.group_v[g][d]; } } } } -static void do_stopcm_grp(const t_mdatoms &mdatoms, - rvec x[], rvec v[], const t_vcm &vcm) +static void do_stopcm_grp(const t_mdatoms& mdatoms, rvec x[], rvec v[], const t_vcm& vcm) { if (vcm.mode != ecmNO) { const int homenr = mdatoms.homenr; - const unsigned short *group_id = mdatoms.cVCM; + const unsigned short* group_id = mdatoms.cVCM; - int gmx_unused nth = gmx_omp_nthreads_get(emntDefault); + int gmx_unused nth = gmx_omp_nthreads_get(emntDefault); #pragma omp parallel num_threads(nth) { - if (vcm.mode == ecmLINEAR || - vcm.mode == ecmANGULAR || - (vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION && x == nullptr)) + if (vcm.mode == ecmLINEAR || vcm.mode == ecmANGULAR + || (vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION && x == nullptr)) { /* Subtract linear momentum for v */ switch (vcm.ndim) { - case 1: - doStopComMotionLinear<1>(mdatoms, v, vcm); - break; - case 2: - doStopComMotionLinear<2>(mdatoms, v, vcm); - break; - case 3: - doStopComMotionLinear<3>(mdatoms, v, vcm); - break; + case 1: doStopComMotionLinear<1>(mdatoms, v, vcm); break; + case 2: doStopComMotionLinear<2>(mdatoms, v, vcm); break; + case 3: doStopComMotionLinear<3>(mdatoms, v, vcm); break; } } else { - GMX_ASSERT(vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION, "When the mode is not linear or angular, it should be acceleration correction"); + GMX_ASSERT(vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION, + "When the mode is not linear or angular, it should be acceleration " + "correction"); /* Subtract linear momentum for v and x*/ switch (vcm.ndim) { @@ -395,7 +381,6 @@ static void do_stopcm_grp(const t_mdatoms &mdatoms, doStopComMotionAccelerationCorrection<3>(homenr, group_id, x, v, vcm); break; } - } if (vcm.mode == ecmANGULAR) { @@ -427,23 +412,23 @@ static void get_minv(tensor A, tensor B) double fac, rfac; tensor tmp; - tmp[XX][XX] = A[YY][YY] + A[ZZ][ZZ]; + tmp[XX][XX] = A[YY][YY] + A[ZZ][ZZ]; tmp[YY][XX] = -A[XX][YY]; tmp[ZZ][XX] = -A[XX][ZZ]; tmp[XX][YY] = -A[XX][YY]; - tmp[YY][YY] = A[XX][XX] + A[ZZ][ZZ]; + tmp[YY][YY] = A[XX][XX] + A[ZZ][ZZ]; tmp[ZZ][YY] = -A[YY][ZZ]; tmp[XX][ZZ] = -A[XX][ZZ]; tmp[YY][ZZ] = -A[YY][ZZ]; - tmp[ZZ][ZZ] = A[XX][XX] + A[YY][YY]; + tmp[ZZ][ZZ] = A[XX][XX] + A[YY][YY]; /* This is a hack to prevent very large determinants */ - rfac = (tmp[XX][XX]+tmp[YY][YY]+tmp[ZZ][ZZ])/3; + rfac = (tmp[XX][XX] + tmp[YY][YY] + tmp[ZZ][ZZ]) / 3; if (rfac == 0.0) { gmx_fatal(FARGS, "Can not stop center of mass: maybe 2dimensional system"); } - fac = 1.0/rfac; + fac = 1.0 / rfac; for (m = 0; (m < DIM); m++) { for (n = 0; (n < DIM); n++) @@ -462,7 +447,7 @@ static void get_minv(tensor A, tensor B) } /* Processes VCM after reduction over ranks and prints warning with high VMC and fp != nullptr */ -static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) +static void process_and_check_cm_grp(FILE* fp, t_vcm* vcm, real Temp_Max) { int m, g; real ekcm, ekrot, tm, tm_1, Temp_cm; @@ -477,7 +462,7 @@ static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) tm = vcm->group_mass[g]; if (tm != 0) { - tm_1 = 1.0/tm; + tm_1 = 1.0 / tm; svmul(tm_1, vcm->group_p[g], vcm->group_v[g]); } /* Else it's zero anyway! */ @@ -489,7 +474,7 @@ static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) tm = vcm->group_mass[g]; if (tm != 0) { - tm_1 = 1.0/tm; + tm_1 = 1.0 / tm; /* Compute center of mass for this group */ for (m = 0; (m < DIM); m++) @@ -503,7 +488,7 @@ static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) cprod(vcm->group_x[g], vcm->group_v[g], jcm); for (m = 0; (m < DIM); m++) { - vcm->group_j[g][m] -= tm*jcm[m]; + vcm->group_j[g][m] -= tm * jcm[m]; } /* Subtract the center of mass contribution from the inertia @@ -528,43 +513,43 @@ static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) } for (g = 0; (g < vcm->nr); g++) { - ekcm = 0; + ekcm = 0; if (vcm->group_mass[g] != 0 && vcm->group_ndf[g] > 0) { for (m = 0; m < vcm->ndim; m++) { ekcm += gmx::square(vcm->group_v[g][m]); } - ekcm *= 0.5*vcm->group_mass[g]; - Temp_cm = 2*ekcm/vcm->group_ndf[g]; + ekcm *= 0.5 * vcm->group_mass[g]; + Temp_cm = 2 * ekcm / vcm->group_ndf[g]; if ((Temp_cm > Temp_Max) && fp) { fprintf(fp, "Large VCM(group %s): %12.5f, %12.5f, %12.5f, Temp-cm: %12.5e\n", - vcm->group_name[g], vcm->group_v[g][XX], - vcm->group_v[g][YY], vcm->group_v[g][ZZ], Temp_cm); + vcm->group_name[g], vcm->group_v[g][XX], vcm->group_v[g][YY], + vcm->group_v[g][ZZ], Temp_cm); } if (vcm->mode == ecmANGULAR) { - ekrot = 0.5*iprod(vcm->group_j[g], vcm->group_w[g]); + ekrot = 0.5 * iprod(vcm->group_j[g], vcm->group_w[g]); // TODO: Change absolute energy comparison to relative if ((ekrot > 1) && fp && vcm->integratorConservesMomentum) { /* if we have an integrator that may not conserve momenta, skip */ - tm = vcm->group_mass[g]; + tm = vcm->group_mass[g]; fprintf(fp, "Group %s with mass %12.5e, Ekrot %12.5e Det(I) = %12.5e\n", vcm->group_name[g], tm, ekrot, det(vcm->group_i[g])); - fprintf(fp, " COM: %12.5f %12.5f %12.5f\n", - vcm->group_x[g][XX], vcm->group_x[g][YY], vcm->group_x[g][ZZ]); - fprintf(fp, " P: %12.5f %12.5f %12.5f\n", - vcm->group_p[g][XX], vcm->group_p[g][YY], vcm->group_p[g][ZZ]); - fprintf(fp, " V: %12.5f %12.5f %12.5f\n", - vcm->group_v[g][XX], vcm->group_v[g][YY], vcm->group_v[g][ZZ]); - fprintf(fp, " J: %12.5f %12.5f %12.5f\n", - vcm->group_j[g][XX], vcm->group_j[g][YY], vcm->group_j[g][ZZ]); - fprintf(fp, " w: %12.5f %12.5f %12.5f\n", - vcm->group_w[g][XX], vcm->group_w[g][YY], vcm->group_w[g][ZZ]); + fprintf(fp, " COM: %12.5f %12.5f %12.5f\n", vcm->group_x[g][XX], + vcm->group_x[g][YY], vcm->group_x[g][ZZ]); + fprintf(fp, " P: %12.5f %12.5f %12.5f\n", vcm->group_p[g][XX], + vcm->group_p[g][YY], vcm->group_p[g][ZZ]); + fprintf(fp, " V: %12.5f %12.5f %12.5f\n", vcm->group_v[g][XX], + vcm->group_v[g][YY], vcm->group_v[g][ZZ]); + fprintf(fp, " J: %12.5f %12.5f %12.5f\n", vcm->group_j[g][XX], + vcm->group_j[g][YY], vcm->group_j[g][ZZ]); + fprintf(fp, " w: %12.5f %12.5f %12.5f\n", vcm->group_w[g][XX], + vcm->group_w[g][YY], vcm->group_w[g][ZZ]); pr_rvecs(fp, 0, "Inertia tensor", vcm->group_i[g], DIM); } } @@ -572,10 +557,7 @@ static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max) } } -void process_and_stopcm_grp(FILE *fplog, - t_vcm *vcm, - const t_mdatoms &mdatoms, - rvec x[], rvec v[]) +void process_and_stopcm_grp(FILE* fplog, t_vcm* vcm, const t_mdatoms& mdatoms, rvec x[], rvec v[]) { if (vcm->mode != ecmNO) { diff --git a/src/gromacs/mdlib/vcm.h b/src/gromacs/mdlib/vcm.h index 92b48b2c5c..87b95e08f3 100644 --- a/src/gromacs/mdlib/vcm.h +++ b/src/gromacs/mdlib/vcm.h @@ -53,68 +53,67 @@ struct t_mdatoms; struct t_vcm_thread { //! Linear momentum - rvec p = {0}; + rvec p = { 0 }; //! Center of mass - rvec x = {0}; + rvec x = { 0 }; //! Angular momentum - rvec j = {0}; + rvec j = { 0 }; //! Moment of inertia - tensor i = {{0}}; + tensor i = { { 0 } }; //! Mass - real mass = 0; + real mass = 0; }; struct t_vcm { //! Number of groups - int nr = 0; + int nr = 0; //! Size of group arrays - int size = 0; + int size = 0; //! Stride for thread data - int stride = 0; + int stride = 0; //! One of the enums above - int mode = 0; + int mode = 0; //! The number of dimensions for corr. - int ndim = 0; + int ndim = 0; //! The time step for COMM removal - real timeStep = 0; + real timeStep = 0; //! Number of degrees of freedom - std::vector group_ndf; + std::vector group_ndf; //! Mass per group - std::vector group_mass; + std::vector group_mass; //! Linear momentum per group - std::vector group_p; + std::vector group_p; //! Linear velocity per group - std::vector group_v; + std::vector group_v; //! Center of mass per group - std::vector group_x; + std::vector group_x; //! Angular momentum per group - std::vector group_j; + std::vector group_j; //! Angular velocity (omega) - std::vector group_w; + std::vector group_w; //! Moment of inertia per group - tensor *group_i = nullptr; + tensor* group_i = nullptr; //! These two are copies to pointers in - std::vector group_name; + std::vector group_name; //! Tells whether dimensions are frozen per freeze group - ivec *nFreeze = nullptr; + ivec* nFreeze = nullptr; //! Temporary data per thread and group std::vector thread_vcm; //! Tell whether the integrator conserves momentum bool integratorConservesMomentum = false; - t_vcm(const SimulationGroups &groups, const t_inputrec &ir); + t_vcm(const SimulationGroups& groups, const t_inputrec& ir); ~t_vcm(); }; /* print COM removal info to log */ -void reportComRemovalInfo(FILE * fp, const t_vcm &vcm); +void reportComRemovalInfo(FILE* fp, const t_vcm& vcm); /* Do a per group center of mass things */ -void calc_vcm_grp(const t_mdatoms &md, - const rvec x[], const rvec v[], t_vcm *vcm); +void calc_vcm_grp(const t_mdatoms& md, const rvec x[], const rvec v[], t_vcm* vcm); /* Set the COM velocity to zero and potentially correct the COM position. * @@ -124,7 +123,6 @@ void calc_vcm_grp(const t_mdatoms &md, * and a pointer to the coordinates at normal MD steps. * When fplog != nullptr, a warning is printed to fplog with high COM velocity. */ -void process_and_stopcm_grp(FILE *fplog, t_vcm *vcm, const t_mdatoms &mdatoms, - rvec x[], rvec v[]); +void process_and_stopcm_grp(FILE* fplog, t_vcm* vcm, const t_mdatoms& mdatoms, rvec x[], rvec v[]); #endif diff --git a/src/gromacs/mdlib/vsite.cpp b/src/gromacs/mdlib/vsite.cpp index cbc42a8f4b..4a0fe17a00 100644 --- a/src/gromacs/mdlib/vsite.cpp +++ b/src/gromacs/mdlib/vsite.cpp @@ -87,7 +87,7 @@ using gmx::RVec; -static void init_ilist(t_ilist *ilist) +static void init_ilist(t_ilist* ilist) { for (int i = 0; i < F_NRE; i++) { @@ -98,7 +98,8 @@ static void init_ilist(t_ilist *ilist) } /*! \brief List of atom indices belonging to a task */ -struct AtomIndex { +struct AtomIndex +{ //! List of atom indices std::vector atom; }; @@ -107,21 +108,21 @@ struct AtomIndex { struct InterdependentTask { //! The interaction lists, only vsite entries are used - t_ilist ilist[F_NRE]; + t_ilist ilist[F_NRE]; //! Thread/task-local force buffer - std::vector force; + std::vector force; //! The atom indices of the vsites of our task - std::vector vsite; + std::vector vsite; //! Flags if elements in force are spread to or not - std::vector use; + std::vector use; //! The number of entries set to true in use - int nuse; + int nuse; //! Array of atoms indices, size nthreads, covering all nuse set elements in use std::vector atomIndex; //! List of tasks (force blocks) this task spread forces to - std::vector spreadTask; + std::vector spreadTask; //! List of tasks that write to this tasks force block range - std::vector reduceTask; + std::vector reduceTask; InterdependentTask() { @@ -134,25 +135,25 @@ struct InterdependentTask struct VsiteThread { //! Start of atom range of this task - int rangeStart; + int rangeStart; //! End of atom range of this task - int rangeEnd; + int rangeEnd; //! The interaction lists, only vsite entries are used - t_ilist ilist[F_NRE]; + t_ilist ilist[F_NRE]; //! Local fshift accumulation buffer - rvec fshift[SHIFTS]; + rvec fshift[SHIFTS]; //! Local virial dx*df accumulation buffer - matrix dxdf; + matrix dxdf; //! Tells if interdependent task idTask should be used (in addition to the rest of this task), this bool has the same value on all threads - bool useInterdependentTask; + bool useInterdependentTask; //! Data for vsites that involve constructing atoms in the atom range of other threads/tasks InterdependentTask idTask; /*! \brief Constructor */ VsiteThread() { - rangeStart = -1; - rangeEnd = -1; + rangeStart = -1; + rangeEnd = -1; init_ilist(ilist); clear_rvecs(SHIFTS, fshift); clear_mat(dxdf); @@ -164,8 +165,8 @@ struct VsiteThread * * \param[in] ilist The interaction list */ -template -static int vsiteIlistNrCount(const T *ilist) +template +static int vsiteIlistNrCount(const T* ilist) { int nr = 0; for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) @@ -176,7 +177,7 @@ static int vsiteIlistNrCount(const T *ilist) return nr; } -static int pbc_rvec_sub(const t_pbc *pbc, const rvec xi, const rvec xj, rvec dx) +static int pbc_rvec_sub(const t_pbc* pbc, const rvec xi, const rvec xj, rvec dx) { if (pbc) { @@ -196,7 +197,7 @@ static inline real inverseNorm(const rvec x) /* Vsite construction routines */ -static void constr_vsite2(const rvec xi, const rvec xj, rvec x, real a, const t_pbc *pbc) +static void constr_vsite2(const rvec xi, const rvec xj, rvec x, real a, const t_pbc* pbc) { real b = 1 - a; /* 1 flop */ @@ -205,41 +206,39 @@ static void constr_vsite2(const rvec xi, const rvec xj, rvec x, real a, const t_ { rvec dx; pbc_dx_aiuc(pbc, xj, xi, dx); - x[XX] = xi[XX] + a*dx[XX]; - x[YY] = xi[YY] + a*dx[YY]; - x[ZZ] = xi[ZZ] + a*dx[ZZ]; + x[XX] = xi[XX] + a * dx[XX]; + x[YY] = xi[YY] + a * dx[YY]; + x[ZZ] = xi[ZZ] + a * dx[ZZ]; } else { - x[XX] = b*xi[XX] + a*xj[XX]; - x[YY] = b*xi[YY] + a*xj[YY]; - x[ZZ] = b*xi[ZZ] + a*xj[ZZ]; + x[XX] = b * xi[XX] + a * xj[XX]; + x[YY] = b * xi[YY] + a * xj[YY]; + x[ZZ] = b * xi[ZZ] + a * xj[ZZ]; /* 9 Flops */ } /* TOTAL: 10 flops */ } -static void constr_vsite2FD(const rvec xi, const rvec xj, rvec x, real a, - const t_pbc *pbc) +static void constr_vsite2FD(const rvec xi, const rvec xj, rvec x, real a, const t_pbc* pbc) { rvec xij; pbc_rvec_sub(pbc, xj, xi, xij); /* 3 flops */ - const real b = a*inverseNorm(xij); + const real b = a * inverseNorm(xij); /* 6 + 10 flops */ - x[XX] = xi[XX] + b*xij[XX]; - x[YY] = xi[YY] + b*xij[YY]; - x[ZZ] = xi[ZZ] + b*xij[ZZ]; + x[XX] = xi[XX] + b * xij[XX]; + x[YY] = xi[YY] + b * xij[YY]; + x[ZZ] = xi[ZZ] + b * xij[ZZ]; /* 6 Flops */ /* TOTAL: 25 flops */ } -static void constr_vsite3(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, - const t_pbc *pbc) +static void constr_vsite3(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, const t_pbc* pbc) { real c = 1 - a - b; /* 2 flops */ @@ -250,23 +249,22 @@ static void constr_vsite3(const rvec xi, const rvec xj, const rvec xk, rvec x, r pbc_dx_aiuc(pbc, xj, xi, dxj); pbc_dx_aiuc(pbc, xk, xi, dxk); - x[XX] = xi[XX] + a*dxj[XX] + b*dxk[XX]; - x[YY] = xi[YY] + a*dxj[YY] + b*dxk[YY]; - x[ZZ] = xi[ZZ] + a*dxj[ZZ] + b*dxk[ZZ]; + x[XX] = xi[XX] + a * dxj[XX] + b * dxk[XX]; + x[YY] = xi[YY] + a * dxj[YY] + b * dxk[YY]; + x[ZZ] = xi[ZZ] + a * dxj[ZZ] + b * dxk[ZZ]; } else { - x[XX] = c*xi[XX] + a*xj[XX] + b*xk[XX]; - x[YY] = c*xi[YY] + a*xj[YY] + b*xk[YY]; - x[ZZ] = c*xi[ZZ] + a*xj[ZZ] + b*xk[ZZ]; + x[XX] = c * xi[XX] + a * xj[XX] + b * xk[XX]; + x[YY] = c * xi[YY] + a * xj[YY] + b * xk[YY]; + x[ZZ] = c * xi[ZZ] + a * xj[ZZ] + b * xk[ZZ]; /* 15 Flops */ } /* TOTAL: 17 flops */ } -static void constr_vsite3FD(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, - const t_pbc *pbc) +static void constr_vsite3FD(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, const t_pbc* pbc) { rvec xij, xjk, temp; real c; @@ -276,23 +274,23 @@ static void constr_vsite3FD(const rvec xi, const rvec xj, const rvec xk, rvec x, /* 6 flops */ /* temp goes from i to a point on the line jk */ - temp[XX] = xij[XX] + a*xjk[XX]; - temp[YY] = xij[YY] + a*xjk[YY]; - temp[ZZ] = xij[ZZ] + a*xjk[ZZ]; + temp[XX] = xij[XX] + a * xjk[XX]; + temp[YY] = xij[YY] + a * xjk[YY]; + temp[ZZ] = xij[ZZ] + a * xjk[ZZ]; /* 6 flops */ - c = b*inverseNorm(temp); + c = b * inverseNorm(temp); /* 6 + 10 flops */ - x[XX] = xi[XX] + c*temp[XX]; - x[YY] = xi[YY] + c*temp[YY]; - x[ZZ] = xi[ZZ] + c*temp[ZZ]; + x[XX] = xi[XX] + c * temp[XX]; + x[YY] = xi[YY] + c * temp[YY]; + x[ZZ] = xi[ZZ] + c * temp[ZZ]; /* 6 Flops */ /* TOTAL: 34 flops */ } -static void constr_vsite3FAD(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, const t_pbc *pbc) +static void constr_vsite3FAD(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, const t_pbc* pbc) { rvec xij, xjk, xp; real a1, b1, c1, invdij; @@ -303,23 +301,23 @@ static void constr_vsite3FAD(const rvec xi, const rvec xj, const rvec xk, rvec x invdij = inverseNorm(xij); c1 = invdij * invdij * iprod(xij, xjk); - xp[XX] = xjk[XX] - c1*xij[XX]; - xp[YY] = xjk[YY] - c1*xij[YY]; - xp[ZZ] = xjk[ZZ] - c1*xij[ZZ]; - a1 = a*invdij; - b1 = b*inverseNorm(xp); + xp[XX] = xjk[XX] - c1 * xij[XX]; + xp[YY] = xjk[YY] - c1 * xij[YY]; + xp[ZZ] = xjk[ZZ] - c1 * xij[ZZ]; + a1 = a * invdij; + b1 = b * inverseNorm(xp); /* 45 */ - x[XX] = xi[XX] + a1*xij[XX] + b1*xp[XX]; - x[YY] = xi[YY] + a1*xij[YY] + b1*xp[YY]; - x[ZZ] = xi[ZZ] + a1*xij[ZZ] + b1*xp[ZZ]; + x[XX] = xi[XX] + a1 * xij[XX] + b1 * xp[XX]; + x[YY] = xi[YY] + a1 * xij[YY] + b1 * xp[YY]; + x[ZZ] = xi[ZZ] + a1 * xij[ZZ] + b1 * xp[ZZ]; /* 12 Flops */ /* TOTAL: 63 flops */ } -static void constr_vsite3OUT(const rvec xi, const rvec xj, const rvec xk, rvec x, - real a, real b, real c, const t_pbc *pbc) +static void +constr_vsite3OUT(const rvec xi, const rvec xj, const rvec xk, rvec x, real a, real b, real c, const t_pbc* pbc) { rvec xij, xik, temp; @@ -328,16 +326,23 @@ static void constr_vsite3OUT(const rvec xi, const rvec xj, const rvec xk, rvec x cprod(xij, xik, temp); /* 15 Flops */ - x[XX] = xi[XX] + a*xij[XX] + b*xik[XX] + c*temp[XX]; - x[YY] = xi[YY] + a*xij[YY] + b*xik[YY] + c*temp[YY]; - x[ZZ] = xi[ZZ] + a*xij[ZZ] + b*xik[ZZ] + c*temp[ZZ]; + x[XX] = xi[XX] + a * xij[XX] + b * xik[XX] + c * temp[XX]; + x[YY] = xi[YY] + a * xij[YY] + b * xik[YY] + c * temp[YY]; + x[ZZ] = xi[ZZ] + a * xij[ZZ] + b * xik[ZZ] + c * temp[ZZ]; /* 18 Flops */ /* TOTAL: 33 flops */ } -static void constr_vsite4FD(const rvec xi, const rvec xj, const rvec xk, const rvec xl, rvec x, - real a, real b, real c, const t_pbc *pbc) +static void constr_vsite4FD(const rvec xi, + const rvec xj, + const rvec xk, + const rvec xl, + rvec x, + real a, + real b, + real c, + const t_pbc* pbc) { rvec xij, xjk, xjl, temp; real d; @@ -348,24 +353,31 @@ static void constr_vsite4FD(const rvec xi, const rvec xj, const rvec xk, const r /* 9 flops */ /* temp goes from i to a point on the plane jkl */ - temp[XX] = xij[XX] + a*xjk[XX] + b*xjl[XX]; - temp[YY] = xij[YY] + a*xjk[YY] + b*xjl[YY]; - temp[ZZ] = xij[ZZ] + a*xjk[ZZ] + b*xjl[ZZ]; + temp[XX] = xij[XX] + a * xjk[XX] + b * xjl[XX]; + temp[YY] = xij[YY] + a * xjk[YY] + b * xjl[YY]; + temp[ZZ] = xij[ZZ] + a * xjk[ZZ] + b * xjl[ZZ]; /* 12 flops */ - d = c*inverseNorm(temp); + d = c * inverseNorm(temp); /* 6 + 10 flops */ - x[XX] = xi[XX] + d*temp[XX]; - x[YY] = xi[YY] + d*temp[YY]; - x[ZZ] = xi[ZZ] + d*temp[ZZ]; + x[XX] = xi[XX] + d * temp[XX]; + x[YY] = xi[YY] + d * temp[YY]; + x[ZZ] = xi[ZZ] + d * temp[ZZ]; /* 6 Flops */ /* TOTAL: 43 flops */ } -static void constr_vsite4FDN(const rvec xi, const rvec xj, const rvec xk, const rvec xl, rvec x, - real a, real b, real c, const t_pbc *pbc) +static void constr_vsite4FDN(const rvec xi, + const rvec xj, + const rvec xk, + const rvec xl, + rvec x, + real a, + real b, + real c, + const t_pbc* pbc) { rvec xij, xik, xil, ra, rb, rja, rjb, rm; real d; @@ -375,13 +387,13 @@ static void constr_vsite4FDN(const rvec xi, const rvec xj, const rvec xk, const pbc_rvec_sub(pbc, xl, xi, xil); /* 9 flops */ - ra[XX] = a*xik[XX]; - ra[YY] = a*xik[YY]; - ra[ZZ] = a*xik[ZZ]; + ra[XX] = a * xik[XX]; + ra[YY] = a * xik[YY]; + ra[ZZ] = a * xik[ZZ]; - rb[XX] = b*xil[XX]; - rb[YY] = b*xil[YY]; - rb[ZZ] = b*xil[ZZ]; + rb[XX] = b * xil[XX]; + rb[YY] = b * xil[YY]; + rb[ZZ] = b * xil[ZZ]; /* 6 flops */ @@ -392,34 +404,33 @@ static void constr_vsite4FDN(const rvec xi, const rvec xj, const rvec xk, const cprod(rja, rjb, rm); /* 9 flops */ - d = c*inverseNorm(rm); + d = c * inverseNorm(rm); /* 5+5+1 flops */ - x[XX] = xi[XX] + d*rm[XX]; - x[YY] = xi[YY] + d*rm[YY]; - x[ZZ] = xi[ZZ] + d*rm[ZZ]; + x[XX] = xi[XX] + d * rm[XX]; + x[YY] = xi[YY] + d * rm[YY]; + x[ZZ] = xi[ZZ] + d * rm[ZZ]; /* 6 Flops */ /* TOTAL: 47 flops */ } -static int constr_vsiten(const t_iatom *ia, const t_iparams ip[], - rvec *x, const t_pbc *pbc) +static int constr_vsiten(const t_iatom* ia, const t_iparams ip[], rvec* x, const t_pbc* pbc) { rvec x1, dx; dvec dsum; int n3, av, ai; real a; - n3 = 3*ip[ia[0]].vsiten.n; + n3 = 3 * ip[ia[0]].vsiten.n; av = ia[1]; ai = ia[2]; copy_rvec(x[ai], x1); clear_dvec(dsum); for (int i = 3; i < n3; i += 3) { - ai = ia[i+2]; + ai = ia[i + 2]; a = ip[ia[i]].vsiten.a; if (pbc) { @@ -429,9 +440,9 @@ static int constr_vsiten(const t_iatom *ia, const t_iparams ip[], { rvec_sub(x[ai], x1, dx); } - dsum[XX] += a*dx[XX]; - dsum[YY] += a*dx[YY]; - dsum[ZZ] += a*dx[ZZ]; + dsum[XX] += a * dx[XX]; + dsum[YY] += a * dx[YY]; + dsum[ZZ] += a * dx[ZZ]; /* 9 Flops */ } @@ -445,15 +456,15 @@ static int constr_vsiten(const t_iatom *ia, const t_iparams ip[], /*! \brief PBC modes for vsite construction and spreading */ enum class PbcMode { - all, // Apply normal, simple PBC for all vsites - none // No PBC treatment needed + all, // Apply normal, simple PBC for all vsites + none // No PBC treatment needed }; /*! \brief Returns the PBC mode based on the system PBC and vsite properties * * \param[in] pbcPtr A pointer to a PBC struct or nullptr when no PBC treatment is required */ -static PbcMode getPbcMode(const t_pbc *pbcPtr) +static PbcMode getPbcMode(const t_pbc* pbcPtr) { if (pbcPtr == nullptr) { @@ -465,24 +476,26 @@ static PbcMode getPbcMode(const t_pbc *pbcPtr) } } -static void construct_vsites_thread(rvec x[], - real dt, rvec *v, - const t_iparams ip[], const t_ilist ilist[], - const t_pbc *pbc_null) +static void construct_vsites_thread(rvec x[], + real dt, + rvec* v, + const t_iparams ip[], + const t_ilist ilist[], + const t_pbc* pbc_null) { - real inv_dt; + real inv_dt; if (v != nullptr) { - inv_dt = 1.0/dt; + inv_dt = 1.0 / dt; } else { inv_dt = 1.0; } - const PbcMode pbcMode = getPbcMode(pbc_null); + const PbcMode pbcMode = getPbcMode(pbc_null); /* We need another pbc pointer, as with charge groups we switch per vsite */ - const t_pbc *pbc_null2 = pbc_null; + const t_pbc* pbc_null2 = pbc_null; for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { @@ -491,21 +504,21 @@ static void construct_vsites_thread(rvec x[], continue; } - { // TODO remove me - int nra = interaction_function[ftype].nratoms; - int inc = 1 + nra; - int nr = ilist[ftype].nr; + { // TODO remove me + int nra = interaction_function[ftype].nratoms; + int inc = 1 + nra; + int nr = ilist[ftype].nr; - const t_iatom *ia = ilist[ftype].iatoms; + const t_iatom* ia = ilist[ftype].iatoms; - for (int i = 0; i < nr; ) + for (int i = 0; i < nr;) { - int tp = ia[0]; + int tp = ia[0]; /* The vsite and constructing atoms */ - int avsite = ia[1]; - int ai = ia[2]; + int avsite = ia[1]; + int ai = ia[2]; /* Constants for constructing vsites */ - real a1 = ip[tp].vsite.a; + real a1 = ip[tp].vsite.a; /* Copy the old position */ rvec xv; copy_rvec(x[avsite], xv); @@ -554,8 +567,7 @@ static void construct_vsites_thread(rvec x[], al = ia[5]; b1 = ip[tp].vsite.b; c1 = ip[tp].vsite.c; - constr_vsite4FD(x[ai], x[aj], x[ak], x[al], x[avsite], a1, b1, c1, - pbc_null2); + constr_vsite4FD(x[ai], x[aj], x[ak], x[al], x[avsite], a1, b1, c1, pbc_null2); break; case F_VSITE4FDN: aj = ia[3]; @@ -563,15 +575,11 @@ static void construct_vsites_thread(rvec x[], al = ia[5]; b1 = ip[tp].vsite.b; c1 = ip[tp].vsite.c; - constr_vsite4FDN(x[ai], x[aj], x[ak], x[al], x[avsite], a1, b1, c1, - pbc_null2); - break; - case F_VSITEN: - inc = constr_vsiten(ia, ip, x, pbc_null2); + constr_vsite4FDN(x[ai], x[aj], x[ak], x[al], x[avsite], a1, b1, c1, pbc_null2); break; + case F_VSITEN: inc = constr_vsiten(ia, ip, x, pbc_null2); break; default: - gmx_fatal(FARGS, "No such vsite type %d in %s, line %d", - ftype, __FILE__, __LINE__); + gmx_fatal(FARGS, "No such vsite type %d in %s, line %d", ftype, __FILE__, __LINE__); } if (pbcMode == PbcMode::all) @@ -593,44 +601,47 @@ static void construct_vsites_thread(rvec x[], } /* Increment loop variables */ - i += inc; + i += inc; ia += inc; } } } } -void construct_vsites(const gmx_vsite_t *vsite, - rvec x[], - real dt, rvec *v, - const t_iparams ip[], const t_ilist ilist[], - int ePBC, gmx_bool bMolPBC, - const t_commrec *cr, - const matrix box) +void construct_vsites(const gmx_vsite_t* vsite, + rvec x[], + real dt, + rvec* v, + const t_iparams ip[], + const t_ilist ilist[], + int ePBC, + gmx_bool bMolPBC, + const t_commrec* cr, + const matrix box) { const bool useDomdec = (vsite != nullptr && vsite->useDomdec); - GMX_ASSERT(!useDomdec || (cr != nullptr && DOMAINDECOMP(cr)), "When vsites are set up with domain decomposition, we need a valid commrec"); + GMX_ASSERT(!useDomdec || (cr != nullptr && DOMAINDECOMP(cr)), + "When vsites are set up with domain decomposition, we need a valid commrec"); // TODO: Remove this assertion when we remove charge groups - GMX_ASSERT(vsite != nullptr || ePBC == epbcNONE, "Without a vsite struct we can not do PBC (in case we have charge groups)"); + GMX_ASSERT(vsite != nullptr || ePBC == epbcNONE, + "Without a vsite struct we can not do PBC (in case we have charge groups)"); - t_pbc pbc, *pbc_null; + t_pbc pbc, *pbc_null; /* We only need to do pbc when we have inter-cg vsites. * Note that with domain decomposition we do not need to apply PBC here * when we have at least 3 domains along each dimension. Currently we * do not optimize this case. */ - if (ePBC != epbcNONE && (useDomdec || bMolPBC) && - !(vsite != nullptr && vsite->numInterUpdategroupVsites == 0)) + if (ePBC != epbcNONE && (useDomdec || bMolPBC) + && !(vsite != nullptr && vsite->numInterUpdategroupVsites == 0)) { /* This is wasting some CPU time as we now do this multiple times * per MD step. */ ivec null_ivec; clear_ivec(null_ivec); - pbc_null = set_pbc_dd(&pbc, ePBC, - useDomdec ? cr->dd->nc : null_ivec, - FALSE, box); + pbc_null = set_pbc_dd(&pbc, ePBC, useDomdec ? cr->dd->nc : null_ivec, FALSE, box); } else { @@ -644,9 +655,7 @@ void construct_vsites(const gmx_vsite_t *vsite, if (vsite == nullptr || vsite->nthreads == 1) { - construct_vsites_thread(x, dt, v, - ip, ilist, - pbc_null); + construct_vsites_thread(x, dt, v, ip, ilist, pbc_null); } else { @@ -655,36 +664,34 @@ void construct_vsites(const gmx_vsite_t *vsite, try { const int th = gmx_omp_get_thread_num(); - const VsiteThread &tData = *vsite->tData[th]; - GMX_ASSERT(tData.rangeStart >= 0, "The thread data should be initialized before calling construct_vsites"); + const VsiteThread& tData = *vsite->tData[th]; + GMX_ASSERT(tData.rangeStart >= 0, + "The thread data should be initialized before calling construct_vsites"); - construct_vsites_thread(x, dt, v, - ip, tData.ilist, - pbc_null); + construct_vsites_thread(x, dt, v, ip, tData.ilist, pbc_null); if (tData.useInterdependentTask) { /* Here we don't need a barrier (unlike the spreading), * since both tasks only construct vsites from particles, * or local vsites, not from non-local vsites. */ - construct_vsites_thread(x, dt, v, - ip, tData.idTask.ilist, - pbc_null); + construct_vsites_thread(x, dt, v, ip, tData.idTask.ilist, pbc_null); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Now we can construct the vsites that might depend on other vsites */ - construct_vsites_thread(x, dt, v, - ip, vsite->tData[vsite->nthreads]->ilist, - pbc_null); + construct_vsites_thread(x, dt, v, ip, vsite->tData[vsite->nthreads]->ilist, pbc_null); } } -static void spread_vsite2(const t_iatom ia[], real a, - const rvec x[], - rvec f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g) +static void spread_vsite2(const t_iatom ia[], + real a, + const rvec x[], + rvec f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g) { rvec fi, fj, dx; t_iatom av, ai, aj; @@ -696,7 +703,7 @@ static void spread_vsite2(const t_iatom ia[], real a, aj = ia[3]; svmul(1 - a, f[av], fi); - svmul( a, f[av], fj); + svmul(a, f[av], fj); /* 7 flop */ rvec_inc(f[ai], fi); @@ -731,16 +738,16 @@ static void spread_vsite2(const t_iatom ia[], real a, /* TOTAL: 13 flops */ } -void constructVsitesGlobal(const gmx_mtop_t &mtop, - gmx::ArrayRef x) +void constructVsitesGlobal(const gmx_mtop_t& mtop, gmx::ArrayRef x) { GMX_ASSERT(x.ssize() >= mtop.natoms, "x should contain the whole system"); - GMX_ASSERT(!mtop.moleculeBlockIndices.empty(), "molblock indices are needed in constructVsitesGlobal"); + GMX_ASSERT(!mtop.moleculeBlockIndices.empty(), + "molblock indices are needed in constructVsitesGlobal"); for (size_t mb = 0; mb < mtop.molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop.molblock[mb]; - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_molblock_t& molb = mtop.molblock[mb]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; if (vsiteIlistNrCount(molt.ilist.data()) > 0) { int atomOffset = mtop.moleculeBlockIndices[mb].globalAtomStart; @@ -750,24 +757,26 @@ void constructVsitesGlobal(const gmx_mtop_t &mtop, for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { ilist[ftype].nr = molt.ilist[ftype].size(); - ilist[ftype].iatoms = const_cast(molt.ilist[ftype].iatoms.data()); + ilist[ftype].iatoms = const_cast(molt.ilist[ftype].iatoms.data()); } - construct_vsites(nullptr, as_rvec_array(x.data()) + atomOffset, - 0.0, nullptr, - mtop.ffparams.iparams.data(), ilist, - epbcNONE, TRUE, nullptr, nullptr); + construct_vsites(nullptr, as_rvec_array(x.data()) + atomOffset, 0.0, nullptr, + mtop.ffparams.iparams.data(), ilist, epbcNONE, TRUE, nullptr, nullptr); atomOffset += molt.atoms.nr; } } } } -static void spread_vsite2FD(const t_iatom ia[], real a, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite2FD(const t_iatom ia[], + real a, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { const int av = ia[1]; const int ai = ia[2]; @@ -780,15 +789,15 @@ static void spread_vsite2FD(const t_iatom ia[], real a, /* 6 flops */ const real invDistance = inverseNorm(xij); - const real b = a*invDistance; + const real b = a * invDistance; /* 4 + ?10? flops */ - const real fproj = iprod(xij, fv)*invDistance*invDistance; + const real fproj = iprod(xij, fv) * invDistance * invDistance; - rvec fj; - fj[XX] = b*(fv[XX] - fproj*xij[XX]); - fj[YY] = b*(fv[YY] - fproj*xij[YY]); - fj[ZZ] = b*(fv[ZZ] - fproj*xij[ZZ]); + rvec fj; + fj[XX] = b * (fv[XX] - fproj * xij[XX]); + fj[YY] = b * (fv[YY] - fproj * xij[YY]); + fj[ZZ] = b * (fv[ZZ] - fproj * xij[ZZ]); /* 9 */ /* b is already calculated in constr_vsite2FD @@ -829,9 +838,9 @@ static void spread_vsite2FD(const t_iatom ia[], real a, fshift[CENTRAL][XX] += fv[XX] - fj[XX]; fshift[CENTRAL][YY] += fv[YY] - fj[YY]; fshift[CENTRAL][ZZ] += fv[ZZ] - fj[ZZ]; - fshift[ sji][XX] += fj[XX]; - fshift[ sji][YY] += fj[YY]; - fshift[ sji][ZZ] += fj[ZZ]; + fshift[sji][XX] += fj[XX]; + fshift[sji][YY] += fj[YY]; + fshift[sji][ZZ] += fj[ZZ]; } } @@ -854,7 +863,7 @@ static void spread_vsite2FD(const t_iatom ia[], real a, for (int j = 0; j < DIM; j++) { /* As xix is a linear combination of j and k, use that here */ - dxdf[i][j] += -xiv[i]*fv[j] + xij[i]*fj[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xij[i] * fj[j]; } } } @@ -862,15 +871,19 @@ static void spread_vsite2FD(const t_iatom ia[], real a, /* TOTAL: 38 flops */ } -static void spread_vsite3(const t_iatom ia[], real a, real b, - const rvec x[], - rvec f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g) +static void spread_vsite3(const t_iatom ia[], + real a, + real b, + const rvec x[], + rvec f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g) { - rvec fi, fj, fk, dx; - int av, ai, aj, ak; - ivec di; - int siv, sij, sik; + rvec fi, fj, fk, dx; + int av, ai, aj, ak; + ivec di; + int siv, sij, sik; av = ia[1]; ai = ia[2]; @@ -878,8 +891,8 @@ static void spread_vsite3(const t_iatom ia[], real a, real b, ak = ia[4]; svmul(1 - a - b, f[av], fi); - svmul( a, f[av], fj); - svmul( b, f[av], fk); + svmul(a, f[av], fj); + svmul(b, f[av], fk); /* 11 flops */ rvec_inc(f[ai], fi); @@ -920,11 +933,16 @@ static void spread_vsite3(const t_iatom ia[], real a, real b, /* TOTAL: 20 flops */ } -static void spread_vsite3FD(const t_iatom ia[], real a, real b, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite3FD(const t_iatom ia[], + real a, + real b, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { real fproj, a1; rvec xvi, xij, xjk, xix, fv, temp; @@ -943,35 +961,35 @@ static void spread_vsite3FD(const t_iatom ia[], real a, real b, /* 6 flops */ /* xix goes from i to point x on the line jk */ - xix[XX] = xij[XX]+a*xjk[XX]; - xix[YY] = xij[YY]+a*xjk[YY]; - xix[ZZ] = xij[ZZ]+a*xjk[ZZ]; + xix[XX] = xij[XX] + a * xjk[XX]; + xix[YY] = xij[YY] + a * xjk[YY]; + xix[ZZ] = xij[ZZ] + a * xjk[ZZ]; /* 6 flops */ const real invDistance = inverseNorm(xix); - const real c = b*invDistance; + const real c = b * invDistance; /* 4 + ?10? flops */ - fproj = iprod(xix, fv)*invDistance*invDistance; /* = (xix . f)/(xix . xix) */ + fproj = iprod(xix, fv) * invDistance * invDistance; /* = (xix . f)/(xix . xix) */ - temp[XX] = c*(fv[XX]-fproj*xix[XX]); - temp[YY] = c*(fv[YY]-fproj*xix[YY]); - temp[ZZ] = c*(fv[ZZ]-fproj*xix[ZZ]); + temp[XX] = c * (fv[XX] - fproj * xix[XX]); + temp[YY] = c * (fv[YY] - fproj * xix[YY]); + temp[ZZ] = c * (fv[ZZ] - fproj * xix[ZZ]); /* 16 */ /* c is already calculated in constr_vsite3FD storing c somewhere will save 26 flops! */ - a1 = 1 - a; + a1 = 1 - a; f[ai][XX] += fv[XX] - temp[XX]; f[ai][YY] += fv[YY] - temp[YY]; f[ai][ZZ] += fv[ZZ] - temp[ZZ]; - f[aj][XX] += a1*temp[XX]; - f[aj][YY] += a1*temp[YY]; - f[aj][ZZ] += a1*temp[ZZ]; - f[ak][XX] += a*temp[XX]; - f[ak][YY] += a*temp[YY]; - f[ak][ZZ] += a*temp[ZZ]; + f[aj][XX] += a1 * temp[XX]; + f[aj][YY] += a1 * temp[YY]; + f[aj][ZZ] += a1 * temp[ZZ]; + f[ak][XX] += a * temp[XX]; + f[ak][YY] += a * temp[YY]; + f[ak][ZZ] += a * temp[ZZ]; /* 19 Flops */ if (g) @@ -995,15 +1013,15 @@ static void spread_vsite3FD(const t_iatom ia[], real a, real b, if (fshift && (svi != CENTRAL || sji != CENTRAL || skj != CENTRAL)) { rvec_dec(fshift[svi], fv); - fshift[CENTRAL][XX] += fv[XX] - (1 + a)*temp[XX]; - fshift[CENTRAL][YY] += fv[YY] - (1 + a)*temp[YY]; - fshift[CENTRAL][ZZ] += fv[ZZ] - (1 + a)*temp[ZZ]; - fshift[ sji][XX] += temp[XX]; - fshift[ sji][YY] += temp[YY]; - fshift[ sji][ZZ] += temp[ZZ]; - fshift[ skj][XX] += a*temp[XX]; - fshift[ skj][YY] += a*temp[YY]; - fshift[ skj][ZZ] += a*temp[ZZ]; + fshift[CENTRAL][XX] += fv[XX] - (1 + a) * temp[XX]; + fshift[CENTRAL][YY] += fv[YY] - (1 + a) * temp[YY]; + fshift[CENTRAL][ZZ] += fv[ZZ] - (1 + a) * temp[ZZ]; + fshift[sji][XX] += temp[XX]; + fshift[sji][YY] += temp[YY]; + fshift[sji][ZZ] += temp[ZZ]; + fshift[skj][XX] += a * temp[XX]; + fshift[skj][YY] += a * temp[YY]; + fshift[skj][ZZ] += a * temp[ZZ]; } if (VirCorr) @@ -1025,7 +1043,7 @@ static void spread_vsite3FD(const t_iatom ia[], real a, real b, for (int j = 0; j < DIM; j++) { /* As xix is a linear combination of j and k, use that here */ - dxdf[i][j] += -xiv[i]*fv[j] + xix[i]*temp[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xix[i] * temp[j]; } } } @@ -1033,11 +1051,16 @@ static void spread_vsite3FD(const t_iatom ia[], real a, real b, /* TOTAL: 61 flops */ } -static void spread_vsite3FAD(const t_iatom ia[], real a, real b, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite3FAD(const t_iatom ia[], + real a, + real b, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { rvec xvi, xij, xjk, xperp, Fpij, Fppp, fv, f1, f2, f3; real a1, b1, c1, c2, invdij, invdij2, invdp, fproj; @@ -1058,22 +1081,22 @@ static void spread_vsite3FAD(const t_iatom ia[], real a, real b, invdij = inverseNorm(xij); invdij2 = invdij * invdij; c1 = iprod(xij, xjk) * invdij2; - xperp[XX] = xjk[XX] - c1*xij[XX]; - xperp[YY] = xjk[YY] - c1*xij[YY]; - xperp[ZZ] = xjk[ZZ] - c1*xij[ZZ]; + xperp[XX] = xjk[XX] - c1 * xij[XX]; + xperp[YY] = xjk[YY] - c1 * xij[YY]; + xperp[ZZ] = xjk[ZZ] - c1 * xij[ZZ]; /* xperp in plane ijk, perp. to ij */ invdp = inverseNorm(xperp); - a1 = a*invdij; - b1 = b*invdp; + a1 = a * invdij; + b1 = b * invdp; /* 45 flops */ /* a1, b1 and c1 are already calculated in constr_vsite3FAD storing them somewhere will save 45 flops! */ - fproj = iprod(xij, fv)*invdij2; - svmul(fproj, xij, Fpij); /* proj. f on xij */ - svmul(iprod(xperp, fv)*invdp*invdp, xperp, Fppp); /* proj. f on xperp */ - svmul(b1*fproj, xperp, f3); + fproj = iprod(xij, fv) * invdij2; + svmul(fproj, xij, Fpij); /* proj. f on xij */ + svmul(iprod(xperp, fv) * invdp * invdp, xperp, Fppp); /* proj. f on xperp */ + svmul(b1 * fproj, xperp, f3); /* 23 flops */ rvec_sub(fv, Fpij, f1); /* f1 = f - Fpij */ @@ -1085,16 +1108,16 @@ static void spread_vsite3FAD(const t_iatom ia[], real a, real b, } /* 12 flops */ - c2 = 1 + c1; - f[ai][XX] += fv[XX] - f1[XX] + c1*f2[XX] + f3[XX]; - f[ai][YY] += fv[YY] - f1[YY] + c1*f2[YY] + f3[YY]; - f[ai][ZZ] += fv[ZZ] - f1[ZZ] + c1*f2[ZZ] + f3[ZZ]; - f[aj][XX] += f1[XX] - c2*f2[XX] - f3[XX]; - f[aj][YY] += f1[YY] - c2*f2[YY] - f3[YY]; - f[aj][ZZ] += f1[ZZ] - c2*f2[ZZ] - f3[ZZ]; - f[ak][XX] += f2[XX]; - f[ak][YY] += f2[YY]; - f[ak][ZZ] += f2[ZZ]; + c2 = 1 + c1; + f[ai][XX] += fv[XX] - f1[XX] + c1 * f2[XX] + f3[XX]; + f[ai][YY] += fv[YY] - f1[YY] + c1 * f2[YY] + f3[YY]; + f[ai][ZZ] += fv[ZZ] - f1[ZZ] + c1 * f2[ZZ] + f3[ZZ]; + f[aj][XX] += f1[XX] - c2 * f2[XX] - f3[XX]; + f[aj][YY] += f1[YY] - c2 * f2[YY] - f3[YY]; + f[aj][ZZ] += f1[ZZ] - c2 * f2[ZZ] - f3[ZZ]; + f[ak][XX] += f2[XX]; + f[ak][YY] += f2[YY]; + f[ak][ZZ] += f2[ZZ]; /* 30 Flops */ if (g) @@ -1118,15 +1141,15 @@ static void spread_vsite3FAD(const t_iatom ia[], real a, real b, if (fshift && (svi != CENTRAL || sji != CENTRAL || skj != CENTRAL)) { rvec_dec(fshift[svi], fv); - fshift[CENTRAL][XX] += fv[XX] - f1[XX] - (1-c1)*f2[XX] + f3[XX]; - fshift[CENTRAL][YY] += fv[YY] - f1[YY] - (1-c1)*f2[YY] + f3[YY]; - fshift[CENTRAL][ZZ] += fv[ZZ] - f1[ZZ] - (1-c1)*f2[ZZ] + f3[ZZ]; - fshift[ sji][XX] += f1[XX] - c1 *f2[XX] - f3[XX]; - fshift[ sji][YY] += f1[YY] - c1 *f2[YY] - f3[YY]; - fshift[ sji][ZZ] += f1[ZZ] - c1 *f2[ZZ] - f3[ZZ]; - fshift[ skj][XX] += f2[XX]; - fshift[ skj][YY] += f2[YY]; - fshift[ skj][ZZ] += f2[ZZ]; + fshift[CENTRAL][XX] += fv[XX] - f1[XX] - (1 - c1) * f2[XX] + f3[XX]; + fshift[CENTRAL][YY] += fv[YY] - f1[YY] - (1 - c1) * f2[YY] + f3[YY]; + fshift[CENTRAL][ZZ] += fv[ZZ] - f1[ZZ] - (1 - c1) * f2[ZZ] + f3[ZZ]; + fshift[sji][XX] += f1[XX] - c1 * f2[XX] - f3[XX]; + fshift[sji][YY] += f1[YY] - c1 * f2[YY] - f3[YY]; + fshift[sji][ZZ] += f1[ZZ] - c1 * f2[ZZ] - f3[ZZ]; + fshift[skj][XX] += f2[XX]; + fshift[skj][YY] += f2[YY]; + fshift[skj][ZZ] += f2[ZZ]; } if (VirCorr) @@ -1141,10 +1164,8 @@ static void spread_vsite3FAD(const t_iatom ia[], real a, real b, for (j = 0; j < DIM; j++) { /* Note that xik=xij+xjk, so we have to add xij*f2 */ - dxdf[i][j] += - -xiv[i]*fv[j] - + xij[i]*(f1[j] + (1 - c2)*f2[j] - f3[j]) - + xjk[i]*f2[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xij[i] * (f1[j] + (1 - c2) * f2[j] - f3[j]) + + xjk[i] * f2[j]; } } } @@ -1152,17 +1173,23 @@ static void spread_vsite3FAD(const t_iatom ia[], real a, real b, /* TOTAL: 113 flops */ } -static void spread_vsite3OUT(const t_iatom ia[], real a, real b, real c, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite3OUT(const t_iatom ia[], + real a, + real b, + real c, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { - rvec xvi, xij, xik, fv, fj, fk; - real cfx, cfy, cfz; - int av, ai, aj, ak; - ivec di; - int svi, sji, ski; + rvec xvi, xij, xik, fv, fj, fk; + real cfx, cfy, cfz; + int av, ai, aj, ak; + ivec di; + int svi, sji, ski; av = ia[1]; ai = ia[2]; @@ -1175,18 +1202,18 @@ static void spread_vsite3OUT(const t_iatom ia[], real a, real b, real c, copy_rvec(f[av], fv); - cfx = c*fv[XX]; - cfy = c*fv[YY]; - cfz = c*fv[ZZ]; + cfx = c * fv[XX]; + cfy = c * fv[YY]; + cfz = c * fv[ZZ]; /* 3 Flops */ - fj[XX] = a*fv[XX] - xik[ZZ]*cfy + xik[YY]*cfz; - fj[YY] = xik[ZZ]*cfx + a*fv[YY] - xik[XX]*cfz; - fj[ZZ] = -xik[YY]*cfx + xik[XX]*cfy + a*fv[ZZ]; + fj[XX] = a * fv[XX] - xik[ZZ] * cfy + xik[YY] * cfz; + fj[YY] = xik[ZZ] * cfx + a * fv[YY] - xik[XX] * cfz; + fj[ZZ] = -xik[YY] * cfx + xik[XX] * cfy + a * fv[ZZ]; - fk[XX] = b*fv[XX] + xij[ZZ]*cfy - xij[YY]*cfz; - fk[YY] = -xij[ZZ]*cfx + b*fv[YY] + xij[XX]*cfz; - fk[ZZ] = xij[YY]*cfx - xij[XX]*cfy + b*fv[ZZ]; + fk[XX] = b * fv[XX] + xij[ZZ] * cfy - xij[YY] * cfz; + fk[YY] = -xij[ZZ] * cfx + b * fv[YY] + xij[XX] * cfz; + fk[ZZ] = xij[YY] * cfx - xij[XX] * cfy + b * fv[ZZ]; /* 30 Flops */ f[ai][XX] += fv[XX] - fj[XX] - fk[XX]; @@ -1234,7 +1261,7 @@ static void spread_vsite3OUT(const t_iatom ia[], real a, real b, real c, { for (int j = 0; j < DIM; j++) { - dxdf[i][j] += -xiv[i]*fv[j] + xij[i]*fj[j] + xik[i]*fk[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xij[i] * fj[j] + xik[i] * fk[j]; } } } @@ -1242,17 +1269,23 @@ static void spread_vsite3OUT(const t_iatom ia[], real a, real b, real c, /* TOTAL: 54 flops */ } -static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite4FD(const t_iatom ia[], + real a, + real b, + real c, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { - real fproj, a1; - rvec xvi, xij, xjk, xjl, xix, fv, temp; - int av, ai, aj, ak, al; - ivec di; - int svi, sji, skj, slj, m; + real fproj, a1; + rvec xvi, xij, xjk, xjl, xix, fv, temp; + int av, ai, aj, ak, al; + ivec di; + int svi, sji, skj, slj, m; av = ia[1]; ai = ia[2]; @@ -1268,21 +1301,21 @@ static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, /* xix goes from i to point x on the plane jkl */ for (m = 0; m < DIM; m++) { - xix[m] = xij[m] + a*xjk[m] + b*xjl[m]; + xix[m] = xij[m] + a * xjk[m] + b * xjl[m]; } /* 12 flops */ const real invDistance = inverseNorm(xix); - const real d = c*invDistance; + const real d = c * invDistance; /* 4 + ?10? flops */ copy_rvec(f[av], fv); - fproj = iprod(xix, fv)*invDistance*invDistance; /* = (xix . f)/(xix . xix) */ + fproj = iprod(xix, fv) * invDistance * invDistance; /* = (xix . f)/(xix . xix) */ for (m = 0; m < DIM; m++) { - temp[m] = d*(fv[m] - fproj*xix[m]); + temp[m] = d * (fv[m] - fproj * xix[m]); } /* 16 */ @@ -1293,9 +1326,9 @@ static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, for (m = 0; m < DIM; m++) { f[ai][m] += fv[m] - temp[m]; - f[aj][m] += a1*temp[m]; - f[ak][m] += a*temp[m]; - f[al][m] += b*temp[m]; + f[aj][m] += a1 * temp[m]; + f[ak][m] += a * temp[m]; + f[al][m] += b * temp[m]; } /* 26 Flops */ @@ -1319,16 +1352,15 @@ static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, svi = CENTRAL; } - if (fshift && - (svi != CENTRAL || sji != CENTRAL || skj != CENTRAL || slj != CENTRAL)) + if (fshift && (svi != CENTRAL || sji != CENTRAL || skj != CENTRAL || slj != CENTRAL)) { rvec_dec(fshift[svi], fv); for (m = 0; m < DIM; m++) { - fshift[CENTRAL][m] += fv[m] - (1 + a + b)*temp[m]; - fshift[ sji][m] += temp[m]; - fshift[ skj][m] += a*temp[m]; - fshift[ slj][m] += b*temp[m]; + fshift[CENTRAL][m] += fv[m] - (1 + a + b) * temp[m]; + fshift[sji][m] += temp[m]; + fshift[skj][m] += a * temp[m]; + fshift[slj][m] += b * temp[m]; } } @@ -1343,7 +1375,7 @@ static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, { for (j = 0; j < DIM; j++) { - dxdf[i][j] += -xiv[i]*fv[j] + xix[i]*temp[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xix[i] * temp[j]; } } } @@ -1352,11 +1384,17 @@ static void spread_vsite4FD(const t_iatom ia[], real a, real b, real c, } -static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, - const rvec x[], - rvec f[], rvec fshift[], - gmx_bool VirCorr, matrix dxdf, - const t_pbc *pbc, const t_graph *g) +static void spread_vsite4FDN(const t_iatom ia[], + real a, + real b, + real c, + const rvec x[], + rvec f[], + rvec fshift[], + gmx_bool VirCorr, + matrix dxdf, + const t_pbc* pbc, + const t_graph* g) { rvec xvi, xij, xik, xil, ra, rb, rja, rjb, rab, rm, rt; rvec fv, fj, fk, fl; @@ -1380,13 +1418,13 @@ static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, sil = pbc_rvec_sub(pbc, x[al], x[ai], xil); /* 9 flops */ - ra[XX] = a*xik[XX]; - ra[YY] = a*xik[YY]; - ra[ZZ] = a*xik[ZZ]; + ra[XX] = a * xik[XX]; + ra[YY] = a * xik[YY]; + ra[ZZ] = a * xik[ZZ]; - rb[XX] = b*xil[XX]; - rb[YY] = b*xil[YY]; - rb[ZZ] = b*xil[ZZ]; + rb[XX] = b * xil[XX]; + rb[YY] = b * xil[YY]; + rb[ZZ] = b * xil[ZZ]; /* 6 flops */ @@ -1399,12 +1437,12 @@ static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, /* 9 flops */ invrm = inverseNorm(rm); - denom = invrm*invrm; + denom = invrm * invrm; /* 5+5+2 flops */ - cfx = c*invrm*fv[XX]; - cfy = c*invrm*fv[YY]; - cfz = c*invrm*fv[ZZ]; + cfx = c * invrm * fv[XX]; + cfy = c * invrm * fv[YY]; + cfz = c * invrm * fv[ZZ]; /* 6 Flops */ cprod(rm, rab, rt); @@ -1415,35 +1453,44 @@ static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, rt[ZZ] *= denom; /* 3flops */ - fj[XX] = ( -rm[XX]*rt[XX]) * cfx + ( rab[ZZ]-rm[YY]*rt[XX]) * cfy + (-rab[YY]-rm[ZZ]*rt[XX]) * cfz; - fj[YY] = (-rab[ZZ]-rm[XX]*rt[YY]) * cfx + ( -rm[YY]*rt[YY]) * cfy + ( rab[XX]-rm[ZZ]*rt[YY]) * cfz; - fj[ZZ] = ( rab[YY]-rm[XX]*rt[ZZ]) * cfx + (-rab[XX]-rm[YY]*rt[ZZ]) * cfy + ( -rm[ZZ]*rt[ZZ]) * cfz; + fj[XX] = (-rm[XX] * rt[XX]) * cfx + (rab[ZZ] - rm[YY] * rt[XX]) * cfy + + (-rab[YY] - rm[ZZ] * rt[XX]) * cfz; + fj[YY] = (-rab[ZZ] - rm[XX] * rt[YY]) * cfx + (-rm[YY] * rt[YY]) * cfy + + (rab[XX] - rm[ZZ] * rt[YY]) * cfz; + fj[ZZ] = (rab[YY] - rm[XX] * rt[ZZ]) * cfx + (-rab[XX] - rm[YY] * rt[ZZ]) * cfy + + (-rm[ZZ] * rt[ZZ]) * cfz; /* 30 flops */ cprod(rjb, rm, rt); /* 9 flops */ - rt[XX] *= denom*a; - rt[YY] *= denom*a; - rt[ZZ] *= denom*a; + rt[XX] *= denom * a; + rt[YY] *= denom * a; + rt[ZZ] *= denom * a; /* 3flops */ - fk[XX] = ( -rm[XX]*rt[XX]) * cfx + (-a*rjb[ZZ]-rm[YY]*rt[XX]) * cfy + ( a*rjb[YY]-rm[ZZ]*rt[XX]) * cfz; - fk[YY] = ( a*rjb[ZZ]-rm[XX]*rt[YY]) * cfx + ( -rm[YY]*rt[YY]) * cfy + (-a*rjb[XX]-rm[ZZ]*rt[YY]) * cfz; - fk[ZZ] = (-a*rjb[YY]-rm[XX]*rt[ZZ]) * cfx + ( a*rjb[XX]-rm[YY]*rt[ZZ]) * cfy + ( -rm[ZZ]*rt[ZZ]) * cfz; + fk[XX] = (-rm[XX] * rt[XX]) * cfx + (-a * rjb[ZZ] - rm[YY] * rt[XX]) * cfy + + (a * rjb[YY] - rm[ZZ] * rt[XX]) * cfz; + fk[YY] = (a * rjb[ZZ] - rm[XX] * rt[YY]) * cfx + (-rm[YY] * rt[YY]) * cfy + + (-a * rjb[XX] - rm[ZZ] * rt[YY]) * cfz; + fk[ZZ] = (-a * rjb[YY] - rm[XX] * rt[ZZ]) * cfx + (a * rjb[XX] - rm[YY] * rt[ZZ]) * cfy + + (-rm[ZZ] * rt[ZZ]) * cfz; /* 36 flops */ cprod(rm, rja, rt); /* 9 flops */ - rt[XX] *= denom*b; - rt[YY] *= denom*b; - rt[ZZ] *= denom*b; + rt[XX] *= denom * b; + rt[YY] *= denom * b; + rt[ZZ] *= denom * b; /* 3flops */ - fl[XX] = ( -rm[XX]*rt[XX]) * cfx + ( b*rja[ZZ]-rm[YY]*rt[XX]) * cfy + (-b*rja[YY]-rm[ZZ]*rt[XX]) * cfz; - fl[YY] = (-b*rja[ZZ]-rm[XX]*rt[YY]) * cfx + ( -rm[YY]*rt[YY]) * cfy + ( b*rja[XX]-rm[ZZ]*rt[YY]) * cfz; - fl[ZZ] = ( b*rja[YY]-rm[XX]*rt[ZZ]) * cfx + (-b*rja[XX]-rm[YY]*rt[ZZ]) * cfy + ( -rm[ZZ]*rt[ZZ]) * cfz; + fl[XX] = (-rm[XX] * rt[XX]) * cfx + (b * rja[ZZ] - rm[YY] * rt[XX]) * cfy + + (-b * rja[YY] - rm[ZZ] * rt[XX]) * cfz; + fl[YY] = (-b * rja[ZZ] - rm[XX] * rt[YY]) * cfx + (-rm[YY] * rt[YY]) * cfy + + (b * rja[XX] - rm[ZZ] * rt[YY]) * cfz; + fl[ZZ] = (b * rja[YY] - rm[XX] * rt[ZZ]) * cfx + (-b * rja[XX] - rm[YY] * rt[ZZ]) * cfy + + (-rm[ZZ] * rt[ZZ]) * cfz; /* 36 flops */ f[ai][XX] += fv[XX] - fj[XX] - fk[XX] - fl[XX]; @@ -1496,7 +1543,7 @@ static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, { for (j = 0; j < DIM; j++) { - dxdf[i][j] += -xiv[i]*fv[j] + xij[i]*fj[j] + xik[i]*fk[j] + xil[i]*fl[j]; + dxdf[i][j] += -xiv[i] * fv[j] + xij[i] * fj[j] + xik[i] * fk[j] + xil[i] * fl[j]; } } } @@ -1505,10 +1552,13 @@ static void spread_vsite4FDN(const t_iatom ia[], real a, real b, real c, } -static int spread_vsiten(const t_iatom ia[], const t_iparams ip[], - const rvec x[], - rvec f[], rvec fshift[], - const t_pbc *pbc, const t_graph *g) +static int spread_vsiten(const t_iatom ia[], + const t_iparams ip[], + const rvec x[], + rvec f[], + rvec fshift[], + const t_pbc* pbc, + const t_graph* g) { rvec xv, dx, fi; int n3, av, i, ai; @@ -1516,13 +1566,13 @@ static int spread_vsiten(const t_iatom ia[], const t_iparams ip[], ivec di; int siv; - n3 = 3*ip[ia[0]].vsiten.n; + n3 = 3 * ip[ia[0]].vsiten.n; av = ia[1]; copy_rvec(x[av], xv); for (i = 0; i < n3; i += 3) { - ai = ia[i+2]; + ai = ia[i + 2]; if (g) { ivec_sub(SHIFT_IVEC(g, ai), SHIFT_IVEC(g, av), di); @@ -1551,27 +1601,31 @@ static int spread_vsiten(const t_iatom ia[], const t_iparams ip[], } -static int vsite_count(const t_ilist *ilist, int ftype) +static int vsite_count(const t_ilist* ilist, int ftype) { if (ftype == F_VSITEN) { - return ilist[ftype].nr/3; + return ilist[ftype].nr / 3; } else { - return ilist[ftype].nr/(1 + interaction_function[ftype].nratoms); + return ilist[ftype].nr / (1 + interaction_function[ftype].nratoms); } } -static void spread_vsite_f_thread(const rvec x[], - rvec f[], rvec *fshift, - gmx_bool VirCorr, matrix dxdf, - t_iparams ip[], const t_ilist ilist[], - const t_graph *g, const t_pbc *pbc_null) +static void spread_vsite_f_thread(const rvec x[], + rvec f[], + rvec* fshift, + gmx_bool VirCorr, + matrix dxdf, + t_iparams ip[], + const t_ilist ilist[], + const t_graph* g, + const t_pbc* pbc_null) { - const PbcMode pbcMode = getPbcMode(pbc_null); + const PbcMode pbcMode = getPbcMode(pbc_null); /* We need another pbc pointer, as with charge groups we switch per vsite */ - const t_pbc *pbc_null2 = pbc_null; + const t_pbc* pbc_null2 = pbc_null; gmx::ArrayRef vsite_pbc; /* this loop goes backwards to be able to build * @@ -1583,19 +1637,19 @@ static void spread_vsite_f_thread(const rvec x[], continue; } - { // TODO remove me - int nra = interaction_function[ftype].nratoms; - int inc = 1 + nra; - int nr = ilist[ftype].nr; + { // TODO remove me + int nra = interaction_function[ftype].nratoms; + int inc = 1 + nra; + int nr = ilist[ftype].nr; - const t_iatom *ia = ilist[ftype].iatoms; + const t_iatom* ia = ilist[ftype].iatoms; if (pbcMode == PbcMode::all) { pbc_null2 = pbc_null; } - for (int i = 0; i < nr; ) + for (int i = 0; i < nr;) { int tp = ia[0]; @@ -1605,9 +1659,7 @@ static void spread_vsite_f_thread(const rvec x[], /* Construct the vsite depending on type */ switch (ftype) { - case F_VSITE2: - spread_vsite2(ia, a1, x, f, fshift, pbc_null2, g); - break; + case F_VSITE2: spread_vsite2(ia, a1, x, f, fshift, pbc_null2, g); break; case F_VSITE2FD: spread_vsite2FD(ia, a1, x, f, fshift, VirCorr, dxdf, pbc_null2, g); break; @@ -1638,17 +1690,14 @@ static void spread_vsite_f_thread(const rvec x[], c1 = ip[tp].vsite.c; spread_vsite4FDN(ia, a1, b1, c1, x, f, fshift, VirCorr, dxdf, pbc_null2, g); break; - case F_VSITEN: - inc = spread_vsiten(ia, ip, x, f, fshift, pbc_null2, g); - break; + case F_VSITEN: inc = spread_vsiten(ia, ip, x, f, fshift, pbc_null2, g); break; default: - gmx_fatal(FARGS, "No such vsite type %d in %s, line %d", - ftype, __FILE__, __LINE__); + gmx_fatal(FARGS, "No such vsite type %d in %s, line %d", ftype, __FILE__, __LINE__); } clear_rvec(f[ia[1]]); /* Increment loop variables */ - i += inc; + i += inc; ia += inc; } } @@ -1656,14 +1705,14 @@ static void spread_vsite_f_thread(const rvec x[], } /*! \brief Clears the task force buffer elements that are written by task idTask */ -static void clearTaskForceBufferUsedElements(InterdependentTask *idTask) +static void clearTaskForceBufferUsedElements(InterdependentTask* idTask) { int ntask = idTask->spreadTask.size(); for (int ti = 0; ti < ntask; ti++) { - const AtomIndex *atomList = &idTask->atomIndex[idTask->spreadTask[ti]]; + const AtomIndex* atomList = &idTask->atomIndex[idTask->spreadTask[ti]]; int natom = atomList->atom.size(); - RVec *force = idTask->force.data(); + RVec* force = idTask->force.data(); for (int i = 0; i < natom; i++) { clear_rvec(force[atomList->atom[i]]); @@ -1671,17 +1720,25 @@ static void clearTaskForceBufferUsedElements(InterdependentTask *idTask) } } -void spread_vsite_f(const gmx_vsite_t *vsite, - const rvec * gmx_restrict x, - rvec * gmx_restrict f, rvec * gmx_restrict fshift, - gmx_bool VirCorr, matrix vir, - t_nrnb *nrnb, const t_idef *idef, - int ePBC, gmx_bool bMolPBC, const t_graph *g, const matrix box, - const t_commrec *cr, gmx_wallcycle *wcycle) +void spread_vsite_f(const gmx_vsite_t* vsite, + const rvec* gmx_restrict x, + rvec* gmx_restrict f, + rvec* gmx_restrict fshift, + gmx_bool VirCorr, + matrix vir, + t_nrnb* nrnb, + const t_idef* idef, + int ePBC, + gmx_bool bMolPBC, + const t_graph* g, + const matrix box, + const t_commrec* cr, + gmx_wallcycle* wcycle) { wallcycle_start(wcycle, ewcVSITESPREAD); const bool useDomdec = vsite->useDomdec; - GMX_ASSERT(!useDomdec || (cr != nullptr && DOMAINDECOMP(cr)), "When vsites are set up with domain decomposition, we need a valid commrec"); + GMX_ASSERT(!useDomdec || (cr != nullptr && DOMAINDECOMP(cr)), + "When vsites are set up with domain decomposition, we need a valid commrec"); t_pbc pbc, *pbc_null; @@ -1710,10 +1767,7 @@ void spread_vsite_f(const gmx_vsite_t *vsite, { clear_mat(dxdf); } - spread_vsite_f_thread(x, f, fshift, - VirCorr, dxdf, - idef->iparams, idef->il, - g, pbc_null); + spread_vsite_f_thread(x, f, fshift, VirCorr, dxdf, idef->iparams, idef->il, g, pbc_null); if (VirCorr) { @@ -1721,7 +1775,7 @@ void spread_vsite_f(const gmx_vsite_t *vsite, { for (int j = 0; j < DIM; j++) { - vir[i][j] += -0.5*dxdf[i][j]; + vir[i][j] += -0.5 * dxdf[i][j]; } } } @@ -1733,20 +1787,17 @@ void spread_vsite_f(const gmx_vsite_t *vsite, { clear_mat(vsite->tData[vsite->nthreads]->dxdf); } - spread_vsite_f_thread(x, f, fshift, - VirCorr, vsite->tData[vsite->nthreads]->dxdf, - idef->iparams, - vsite->tData[vsite->nthreads]->ilist, - g, pbc_null); + spread_vsite_f_thread(x, f, fshift, VirCorr, vsite->tData[vsite->nthreads]->dxdf, + idef->iparams, vsite->tData[vsite->nthreads]->ilist, g, pbc_null); #pragma omp parallel num_threads(vsite->nthreads) { try { int thread = gmx_omp_get_thread_num(); - VsiteThread &tData = *vsite->tData[thread]; + VsiteThread& tData = *vsite->tData[thread]; - rvec *fshift_t; + rvec* fshift_t; if (thread == 0 || fshift == nullptr) { fshift_t = fshift; @@ -1771,7 +1822,7 @@ void spread_vsite_f(const gmx_vsite_t *vsite, * This is done using a thread-local force buffer force. * First we need to copy the input vsite forces to force. */ - InterdependentTask *idTask = &tData.idTask; + InterdependentTask* idTask = &tData.idTask; /* Clear the buffer elements set by our task during * the last call to spread_vsite_f. @@ -1781,14 +1832,10 @@ void spread_vsite_f(const gmx_vsite_t *vsite, int nvsite = idTask->vsite.size(); for (int i = 0; i < nvsite; i++) { - copy_rvec(f[idTask->vsite[i]], - idTask->force[idTask->vsite[i]]); + copy_rvec(f[idTask->vsite[i]], idTask->force[idTask->vsite[i]]); } - spread_vsite_f_thread(x, as_rvec_array(idTask->force.data()), fshift_t, - VirCorr, tData.dxdf, - idef->iparams, - tData.idTask.ilist, - g, pbc_null); + spread_vsite_f_thread(x, as_rvec_array(idTask->force.data()), fshift_t, VirCorr, + tData.dxdf, idef->iparams, tData.idTask.ilist, g, pbc_null); /* We need a barrier before reducing forces below * that have been produced by a different thread above. @@ -1803,9 +1850,10 @@ void spread_vsite_f(const gmx_vsite_t *vsite, int ntask = idTask->reduceTask.size(); for (int ti = 0; ti < ntask; ti++) { - const InterdependentTask *idt_foreign = &vsite->tData[idTask->reduceTask[ti]]->idTask; - const AtomIndex *atomList = &idt_foreign->atomIndex[thread]; - const RVec *f_foreign = idt_foreign->force.data(); + const InterdependentTask* idt_foreign = + &vsite->tData[idTask->reduceTask[ti]]->idTask; + const AtomIndex* atomList = &idt_foreign->atomIndex[thread]; + const RVec* f_foreign = idt_foreign->force.data(); int natom = atomList->atom.size(); for (int i = 0; i < natom; i++) @@ -1825,13 +1873,10 @@ void spread_vsite_f(const gmx_vsite_t *vsite, } /* Spread the vsites that spread locally only */ - spread_vsite_f_thread(x, f, fshift_t, - VirCorr, tData.dxdf, - idef->iparams, - tData.ilist, - g, pbc_null); + spread_vsite_f_thread(x, f, fshift_t, VirCorr, tData.dxdf, idef->iparams, + tData.ilist, g, pbc_null); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (fshift != nullptr) @@ -1850,13 +1895,13 @@ void spread_vsite_f(const gmx_vsite_t *vsite, for (int th = 0; th < vsite->nthreads + 1; th++) { /* MSVC doesn't like matrix references, so we use a pointer */ - const matrix *dxdf = &vsite->tData[th]->dxdf; + const matrix* dxdf = &vsite->tData[th]->dxdf; for (int i = 0; i < DIM; i++) { for (int j = 0; j < DIM; j++) { - vir[i][j] += -0.5*(*dxdf)[i][j]; + vir[i][j] += -0.5 * (*dxdf)[i][j]; } } } @@ -1868,15 +1913,15 @@ void spread_vsite_f(const gmx_vsite_t *vsite, dd_move_f_vsites(cr->dd, f, fshift); } - inc_nrnb(nrnb, eNR_VSITE2, vsite_count(idef->il, F_VSITE2)); + inc_nrnb(nrnb, eNR_VSITE2, vsite_count(idef->il, F_VSITE2)); inc_nrnb(nrnb, eNR_VSITE2FD, vsite_count(idef->il, F_VSITE2FD)); - inc_nrnb(nrnb, eNR_VSITE3, vsite_count(idef->il, F_VSITE3)); + inc_nrnb(nrnb, eNR_VSITE3, vsite_count(idef->il, F_VSITE3)); inc_nrnb(nrnb, eNR_VSITE3FD, vsite_count(idef->il, F_VSITE3FD)); inc_nrnb(nrnb, eNR_VSITE3FAD, vsite_count(idef->il, F_VSITE3FAD)); inc_nrnb(nrnb, eNR_VSITE3OUT, vsite_count(idef->il, F_VSITE3OUT)); inc_nrnb(nrnb, eNR_VSITE4FD, vsite_count(idef->il, F_VSITE4FD)); inc_nrnb(nrnb, eNR_VSITE4FDN, vsite_count(idef->il, F_VSITE4FDN)); - inc_nrnb(nrnb, eNR_VSITEN, vsite_count(idef->il, F_VSITEN)); + inc_nrnb(nrnb, eNR_VSITEN, vsite_count(idef->il, F_VSITEN)); wallcycle_stop(wcycle, ewcVSITESPREAD); } @@ -1885,35 +1930,32 @@ void spread_vsite_f(const gmx_vsite_t *vsite, * * \param[in] grouping The paritioning of the atom range into atom groups */ -static std::vector makeAtomToGroupMapping(const gmx::RangePartitioning &grouping) +static std::vector makeAtomToGroupMapping(const gmx::RangePartitioning& grouping) { std::vector atomToGroup(grouping.fullRange().end(), 0); for (int group = 0; group < grouping.numBlocks(); group++) { auto block = grouping.block(group); - std::fill(atomToGroup.begin() + block.begin(), - atomToGroup.begin() + block.end(), - group); + std::fill(atomToGroup.begin() + block.begin(), atomToGroup.begin() + block.end(), group); } return atomToGroup; } -int countNonlinearVsites(const gmx_mtop_t &mtop) +int countNonlinearVsites(const gmx_mtop_t& mtop) { int numNonlinearVsites = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; - for (const auto &ilist : extractILists(molt.ilist, IF_VSITE)) + for (const auto& ilist : extractILists(molt.ilist, IF_VSITE)) { - if (ilist.functionType != F_VSITE2 && - ilist.functionType != F_VSITE3 && - ilist.functionType != F_VSITEN) + if (ilist.functionType != F_VSITE2 && ilist.functionType != F_VSITE3 + && ilist.functionType != F_VSITEN) { - numNonlinearVsites += molb.nmol*ilist.iatoms.size()/(1 + NRAL(ilist.functionType)); + numNonlinearVsites += molb.nmol * ilist.iatoms.size() / (1 + NRAL(ilist.functionType)); } } } @@ -1921,15 +1963,15 @@ int countNonlinearVsites(const gmx_mtop_t &mtop) return numNonlinearVsites; } -int countInterUpdategroupVsites(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroupingPerMoleculetype) +int countInterUpdategroupVsites(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroupingPerMoleculetype) { int n_intercg_vsite = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; - std::vector atomToGroup; + std::vector atomToGroup; if (!updateGroupingPerMoleculetype.empty()) { atomToGroup = makeAtomToGroupMapping(updateGroupingPerMoleculetype[molb.type]); @@ -1937,7 +1979,7 @@ int countInterUpdategroupVsites(const gmx_mtop_t &mto for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { const int nral = NRAL(ftype); - const InteractionList &il = molt.ilist[ftype]; + const InteractionList& il = molt.ilist[ftype]; for (int i = 0; i < il.size(); i += 1 + nral) { bool isInterGroup = atomToGroup.empty(); @@ -1964,9 +2006,7 @@ int countInterUpdategroupVsites(const gmx_mtop_t &mto return n_intercg_vsite; } -std::unique_ptr -initVsite(const gmx_mtop_t &mtop, - const t_commrec *cr) +std::unique_ptr initVsite(const gmx_mtop_t& mtop, const t_commrec* cr) { GMX_RELEASE_ASSERT(cr != nullptr, "We need a valid commrec"); @@ -1978,13 +2018,15 @@ initVsite(const gmx_mtop_t &mtop, { if (interaction_function[ftype].flags & IF_VSITE) { - GMX_ASSERT(ftype >= c_ftypeVsiteStart && ftype < c_ftypeVsiteEnd, "c_ftypeVsiteStart and/or c_ftypeVsiteEnd do not have correct values"); + GMX_ASSERT(ftype >= c_ftypeVsiteStart && ftype < c_ftypeVsiteEnd, + "c_ftypeVsiteStart and/or c_ftypeVsiteEnd do not have correct values"); nvsite += gmx_mtop_ftype_count(&mtop, ftype); } else { - GMX_ASSERT(ftype < c_ftypeVsiteStart || ftype >= c_ftypeVsiteEnd, "c_ftypeVsiteStart and/or c_ftypeVsiteEnd do not have correct values"); + GMX_ASSERT(ftype < c_ftypeVsiteStart || ftype >= c_ftypeVsiteEnd, + "c_ftypeVsiteStart and/or c_ftypeVsiteEnd do not have correct values"); } } @@ -2002,9 +2044,9 @@ initVsite(const gmx_mtop_t &mtop, } vsite->numInterUpdategroupVsites = countInterUpdategroupVsites(mtop, updateGroupingPerMoleculetype); - vsite->useDomdec = (DOMAINDECOMP(cr) && cr->dd->nnodes > 1); + vsite->useDomdec = (DOMAINDECOMP(cr) && cr->dd->nnodes > 1); - vsite->nthreads = gmx_omp_nthreads_get(emntVSITE); + vsite->nthreads = gmx_omp_nthreads_get(emntVSITE); if (vsite->nthreads > 1) { @@ -2017,11 +2059,11 @@ initVsite(const gmx_mtop_t &mtop, { vsite->tData[thread] = std::make_unique(); - InterdependentTask &idTask = vsite->tData[thread]->idTask; + InterdependentTask& idTask = vsite->tData[thread]->idTask; idTask.nuse = 0; idTask.atomIndex.resize(vsite->nthreads); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (vsite->nthreads > 1) { @@ -2032,25 +2074,20 @@ initVsite(const gmx_mtop_t &mtop, return vsite; } -gmx_vsite_t::gmx_vsite_t() -{ -} +gmx_vsite_t::gmx_vsite_t() {} -gmx_vsite_t::~gmx_vsite_t() -{ -} +gmx_vsite_t::~gmx_vsite_t() {} -static inline void flagAtom(InterdependentTask *idTask, int atom, - int thread, int nthread, int natperthread) +static inline void flagAtom(InterdependentTask* idTask, int atom, int thread, int nthread, int natperthread) { if (!idTask->use[atom]) { idTask->use[atom] = true; - thread = atom/natperthread; + thread = atom / natperthread; /* Assign all non-local atom force writes to thread 0 */ if (thread >= nthread) { - thread = 0; + thread = 0; } idTask->atomIndex[thread].atom.push_back(atom); } @@ -2065,14 +2102,14 @@ static inline void flagAtom(InterdependentTask *idTask, int atom, * taskIndex[] is set for all vsites in our range, either to our local tasks * or to the single last task as taskIndex[]=2*nthreads. */ -static void assignVsitesToThread(VsiteThread *tData, - int thread, - int nthread, - int natperthread, - gmx::ArrayRef taskIndex, - const t_ilist *ilist, - const t_iparams *ip, - const unsigned short *ptype) +static void assignVsitesToThread(VsiteThread* tData, + int thread, + int nthread, + int natperthread, + gmx::ArrayRef taskIndex, + const t_ilist* ilist, + const t_iparams* ip, + const unsigned short* ptype) { for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { @@ -2081,17 +2118,16 @@ static void assignVsitesToThread(VsiteThread *tData, int nral1 = 1 + NRAL(ftype); int inc = nral1; - t_iatom *iat = ilist[ftype].iatoms; - for (int i = 0; i < ilist[ftype].nr; ) + t_iatom* iat = ilist[ftype].iatoms; + for (int i = 0; i < ilist[ftype].nr;) { if (ftype == F_VSITEN) { /* The 3 below is from 1+NRAL(ftype)=3 */ - inc = ip[iat[i]].vsiten.n*3; + inc = ip[iat[i]].vsiten.n * 3; } - if (iat[1 + i] < tData->rangeStart || - iat[1 + i] >= tData->rangeEnd) + if (iat[1 + i] < tData->rangeStart || iat[1 + i] >= tData->rangeEnd) { /* This vsite belongs to a different thread */ i += inc; @@ -2108,18 +2144,15 @@ static void assignVsitesToThread(VsiteThread *tData, for (int j = i + 2; j < i + nral1; j++) { /* Do a range check to avoid a harmless race on taskIndex */ - if (iat[j] < tData->rangeStart || - iat[j] >= tData->rangeEnd || - taskIndex[iat[j]] != thread) + if (iat[j] < tData->rangeStart || iat[j] >= tData->rangeEnd || taskIndex[iat[j]] != thread) { - if (!tData->useInterdependentTask || - ptype[iat[j]] == eptVSite) + if (!tData->useInterdependentTask || ptype[iat[j]] == eptVSite) { /* At least one constructing atom is a vsite * that is not assigned to the same thread. * Put this vsite into a separate task. */ - task = 2*nthread; + task = 2 * nthread; break; } @@ -2141,11 +2174,12 @@ static void assignVsitesToThread(VsiteThread *tData, for (int j = i + 2; j < i + inc; j += 3) { /* Do a range check to avoid a harmless race on taskIndex */ - if (iat[j] < tData->rangeStart || - iat[j] >= tData->rangeEnd || - taskIndex[iat[j]] != thread) + if (iat[j] < tData->rangeStart || iat[j] >= tData->rangeEnd || taskIndex[iat[j]] != thread) { - GMX_ASSERT(ptype[iat[j]] != eptVSite, "A vsite to be assigned in assignVsitesToThread has a vsite as a constructing atom that does not belong to our task, such vsites should be assigned to the single 'master' task"); + GMX_ASSERT(ptype[iat[j]] != eptVSite, + "A vsite to be assigned in assignVsitesToThread has a vsite as " + "a constructing atom that does not belong to our task, such " + "vsites should be assigned to the single 'master' task"); task = nthread + thread; } @@ -2153,12 +2187,12 @@ static void assignVsitesToThread(VsiteThread *tData, } /* Update this vsite's thread index entry */ - taskIndex[iat[1+i]] = task; + taskIndex[iat[1 + i]] = task; if (task == thread || task == nthread + thread) { /* Copy this vsite to the thread data struct of thread */ - t_ilist *il_task; + t_ilist* il_task; if (task == thread) { il_task = &tData->ilist[ftype]; @@ -2189,16 +2223,14 @@ static void assignVsitesToThread(VsiteThread *tData, { for (int j = i + 2; j < i + nral1; j++) { - flagAtom(&tData->idTask, iat[j], - thread, nthread, natperthread); + flagAtom(&tData->idTask, iat[j], thread, nthread, natperthread); } } else { for (int j = i + 2; j < i + inc; j += 3) { - flagAtom(&tData->idTask, iat[j], - thread, nthread, natperthread); + flagAtom(&tData->idTask, iat[j], thread, nthread, natperthread); } } } @@ -2210,11 +2242,11 @@ static void assignVsitesToThread(VsiteThread *tData, } /*! \brief Assign all vsites with taskIndex[]==task to task tData */ -static void assignVsitesToSingleTask(VsiteThread *tData, - int task, - gmx::ArrayRef taskIndex, - const t_ilist *ilist, - const t_iparams *ip) +static void assignVsitesToSingleTask(VsiteThread* tData, + int task, + gmx::ArrayRef taskIndex, + const t_ilist* ilist, + const t_iparams* ip) { for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { @@ -2223,15 +2255,15 @@ static void assignVsitesToSingleTask(VsiteThread *tData, int nral1 = 1 + NRAL(ftype); int inc = nral1; - t_iatom *iat = ilist[ftype].iatoms; - t_ilist *il_task = &tData->ilist[ftype]; + t_iatom* iat = ilist[ftype].iatoms; + t_ilist* il_task = &tData->ilist[ftype]; - for (int i = 0; i < ilist[ftype].nr; ) + for (int i = 0; i < ilist[ftype].nr;) { if (ftype == F_VSITEN) { /* The 3 below is from 1+NRAL(ftype)=3 */ - inc = ip[iat[i]].vsiten.n*3; + inc = ip[iat[i]].vsiten.n * 3; } /* Check if the vsite is assigned to our task */ if (taskIndex[iat[1 + i]] == task) @@ -2254,12 +2286,9 @@ static void assignVsitesToSingleTask(VsiteThread *tData, } } -void split_vsites_over_threads(const t_ilist *ilist, - const t_iparams *ip, - const t_mdatoms *mdatoms, - gmx_vsite_t *vsite) +void split_vsites_over_threads(const t_ilist* ilist, const t_iparams* ip, const t_mdatoms* mdatoms, gmx_vsite_t* vsite) { - int vsite_atom_range, natperthread; + int vsite_atom_range, natperthread; if (vsite->nthreads == 1) { @@ -2282,11 +2311,11 @@ void split_vsites_over_threads(const t_ilist *ilist, vsite_atom_range = -1; for (int ftype = c_ftypeVsiteStart; ftype < c_ftypeVsiteEnd; ftype++) { - { // TODO remove me + { // TODO remove me if (ftype != F_VSITEN) { int nral1 = 1 + NRAL(ftype); - const t_iatom *iat = ilist[ftype].iatoms; + const t_iatom* iat = ilist[ftype].iatoms; for (int i = 0; i < ilist[ftype].nr; i += nral1) { for (int j = i + 1; j < i + nral1; j++) @@ -2297,28 +2326,28 @@ void split_vsites_over_threads(const t_ilist *ilist, } else { - int vs_ind_end; + int vs_ind_end; - const t_iatom *iat = ilist[ftype].iatoms; + const t_iatom* iat = ilist[ftype].iatoms; - int i = 0; + int i = 0; while (i < ilist[ftype].nr) { /* The 3 below is from 1+NRAL(ftype)=3 */ - vs_ind_end = i + ip[iat[i]].vsiten.n*3; + vs_ind_end = i + ip[iat[i]].vsiten.n * 3; - vsite_atom_range = std::max(vsite_atom_range, iat[i+1]); + vsite_atom_range = std::max(vsite_atom_range, iat[i + 1]); while (i < vs_ind_end) { - vsite_atom_range = std::max(vsite_atom_range, iat[i+2]); - i += 3; + vsite_atom_range = std::max(vsite_atom_range, iat[i + 2]); + i += 3; } } } } } vsite_atom_range++; - natperthread = (vsite_atom_range + vsite->nthreads - 1)/vsite->nthreads; + natperthread = (vsite_atom_range + vsite->nthreads - 1) / vsite->nthreads; } else { @@ -2330,12 +2359,13 @@ void split_vsites_over_threads(const t_ilist *ilist, * threads also covers the non-local range. */ vsite_atom_range = mdatoms->nr; - natperthread = (mdatoms->homenr + vsite->nthreads - 1)/vsite->nthreads; + natperthread = (mdatoms->homenr + vsite->nthreads - 1) / vsite->nthreads; } if (debug) { - fprintf(debug, "virtual site thread dist: natoms %d, range %d, natperthread %d\n", mdatoms->nr, vsite_atom_range, natperthread); + fprintf(debug, "virtual site thread dist: natoms %d, range %d, natperthread %d\n", + mdatoms->nr, vsite_atom_range, natperthread); } /* To simplify the vsite assignment, we make an index which tells us @@ -2349,7 +2379,7 @@ void split_vsites_over_threads(const t_ilist *ilist, */ gmx::ArrayRef taskIndex = vsite->taskIndex; { - int thread = 0; + int thread = 0; for (int i = 0; i < mdatoms->nr; i++) { if (mdatoms->ptype[i] == eptVSite) @@ -2362,7 +2392,7 @@ void split_vsites_over_threads(const t_ilist *ilist, /* assign non-vsite particles to task thread */ taskIndex[i] = thread; } - if (i == (thread + 1)*natperthread && thread < vsite->nthreads) + if (i == (thread + 1) * natperthread && thread < vsite->nthreads) { thread++; } @@ -2374,12 +2404,12 @@ void split_vsites_over_threads(const t_ilist *ilist, try { int thread = gmx_omp_get_thread_num(); - VsiteThread &tData = *vsite->tData[thread]; + VsiteThread& tData = *vsite->tData[thread]; /* Clear the buffer use flags that were set before */ if (tData.useInterdependentTask) { - InterdependentTask &idTask = tData.idTask; + InterdependentTask& idTask = tData.idTask; /* To avoid an extra OpenMP barrier in spread_vsite_f, * we clear the force buffer at the next step, @@ -2390,7 +2420,7 @@ void split_vsites_over_threads(const t_ilist *ilist, idTask.vsite.resize(0); for (int t = 0; t < vsite->nthreads; t++) { - AtomIndex &atomIndex = idTask.atomIndex[t]; + AtomIndex& atomIndex = idTask.atomIndex[t]; int natom = atomIndex.atom.size(); for (int i = 0; i < natom; i++) { @@ -2411,12 +2441,11 @@ void split_vsites_over_threads(const t_ilist *ilist, if (tData.useInterdependentTask) { size_t natoms_use_in_vsites = vsite_atom_range; - InterdependentTask &idTask = tData.idTask; + InterdependentTask& idTask = tData.idTask; /* To avoid resizing and re-clearing every nstlist steps, * we never down size the force buffer. */ - if (natoms_use_in_vsites > idTask.force.size() || - natoms_use_in_vsites > idTask.use.size()) + if (natoms_use_in_vsites > idTask.force.size() || natoms_use_in_vsites > idTask.use.size()) { idTask.force.resize(natoms_use_in_vsites, { 0, 0, 0 }); idTask.use.resize(natoms_use_in_vsites, false); @@ -2424,21 +2453,18 @@ void split_vsites_over_threads(const t_ilist *ilist, } /* Assign all vsites that can execute independently on threads */ - tData.rangeStart = thread *natperthread; + tData.rangeStart = thread * natperthread; if (thread < vsite->nthreads - 1) { - tData.rangeEnd = (thread + 1)*natperthread; + tData.rangeEnd = (thread + 1) * natperthread; } else { /* The last thread should cover up to the end of the range */ - tData.rangeEnd = mdatoms->nr; + tData.rangeEnd = mdatoms->nr; } - assignVsitesToThread(&tData, - thread, vsite->nthreads, - natperthread, - taskIndex, - ilist, ip, mdatoms->ptype); + assignVsitesToThread(&tData, thread, vsite->nthreads, natperthread, taskIndex, ilist, + ip, mdatoms->ptype); if (tData.useInterdependentTask) { @@ -2449,7 +2475,7 @@ void split_vsites_over_threads(const t_ilist *ilist, * scaling at high thread counts we therefore construct * an index to only loop over the actually affected tasks. */ - InterdependentTask &idTask = tData.idTask; + InterdependentTask& idTask = tData.idTask; /* Ensure assignVsitesToThread finished on other threads */ #pragma omp barrier @@ -2471,14 +2497,12 @@ void split_vsites_over_threads(const t_ilist *ilist, } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Assign all remaining vsites, that will have taskIndex[]=2*vsite->nthreads, * to a single task that will not run in parallel with other tasks. */ - assignVsitesToSingleTask(vsite->tData[vsite->nthreads].get(), - 2*vsite->nthreads, - taskIndex, + assignVsitesToSingleTask(vsite->tData[vsite->nthreads].get(), 2 * vsite->nthreads, taskIndex, ilist, ip); if (debug && vsite->nthreads > 1) @@ -2495,12 +2519,10 @@ void split_vsites_over_threads(const t_ilist *ilist, { if (ilist[ftype].nr > 0) { - fprintf(debug, "%-20s thread dist:", - interaction_function[ftype].longname); + fprintf(debug, "%-20s thread dist:", interaction_function[ftype].longname); for (int th = 0; th < vsite->nthreads + 1; th++) { - fprintf(debug, " %4d %4d ", - vsite->tData[th]->ilist[ftype].nr, + fprintf(debug, " %4d %4d ", vsite->tData[th]->ilist[ftype].nr, vsite->tData[th]->idTask.ilist[ftype].nr); } fprintf(debug, "\n"); @@ -2513,21 +2535,19 @@ void split_vsites_over_threads(const t_ilist *ilist, int nrThreaded = 0; for (int th = 0; th < vsite->nthreads + 1; th++) { - nrThreaded += - vsiteIlistNrCount(vsite->tData[th]->ilist) + - vsiteIlistNrCount(vsite->tData[th]->idTask.ilist); + nrThreaded += vsiteIlistNrCount(vsite->tData[th]->ilist) + + vsiteIlistNrCount(vsite->tData[th]->idTask.ilist); } - GMX_ASSERT(nrThreaded == nrOrig, "The number of virtual sites assigned to all thread task has to match the total number of virtual sites"); + GMX_ASSERT(nrThreaded == nrOrig, + "The number of virtual sites assigned to all thread task has to match the total " + "number of virtual sites"); #endif } -void set_vsite_top(gmx_vsite_t *vsite, - const gmx_localtop_t *top, - const t_mdatoms *md) +void set_vsite_top(gmx_vsite_t* vsite, const gmx_localtop_t* top, const t_mdatoms* md) { if (vsite->nthreads > 1) { - split_vsites_over_threads(top->idef.il, top->idef.iparams, - md, vsite); + split_vsites_over_threads(top->idef.il, top->idef.iparams, md, vsite); } } diff --git a/src/gromacs/mdlib/vsite.h b/src/gromacs/mdlib/vsite.h index ac75839706..b224008d1b 100644 --- a/src/gromacs/mdlib/vsite.h +++ b/src/gromacs/mdlib/vsite.h @@ -80,49 +80,54 @@ struct gmx_vsite_t ~gmx_vsite_t(); /* The number of vsites that cross update groups, when =0 no PBC treatment is needed */ - int numInterUpdategroupVsites; - int nthreads; /* Number of threads used for vsites */ - std::vector < std::unique_ptr < VsiteThread>> tData; /* Thread local vsites and work structs */ - std::vector taskIndex; /* Work array */ - bool useDomdec; /* Tells whether we use domain decomposition with more than 1 DD rank */ + int numInterUpdategroupVsites; + int nthreads; /* Number of threads used for vsites */ + std::vector> tData; /* Thread local vsites and work structs */ + std::vector taskIndex; /* Work array */ + bool useDomdec; /* Tells whether we use domain decomposition with more than 1 DD rank */ }; /*! \brief Create positions of vsite atoms based for the local system * - * \param[in] vsite The vsite struct, when nullptr is passed, no MPI and no multi-threading is used - * \param[in,out] x The coordinates - * \param[in] dt The time step - * \param[in,out] v When != nullptr, velocities for vsites are set as displacement/dt - * \param[in] ip Interaction parameters - * \param[in] ilist The interaction list - * \param[in] ePBC The type of periodic boundary conditions - * \param[in] bMolPBC When true, molecules are broken over PBC - * \param[in] cr The communication record - * \param[in] box The box + * \param[in] vsite The vsite struct, when nullptr is passed, no MPI and no multi-threading + * is used \param[in,out] x The coordinates \param[in] dt The time step \param[in,out] + * v When != nullptr, velocities for vsites are set as displacement/dt \param[in] ip + * Interaction parameters \param[in] ilist The interaction list \param[in] ePBC The + * type of periodic boundary conditions \param[in] bMolPBC When true, molecules are broken over + * PBC \param[in] cr The communication record \param[in] box The box */ -void construct_vsites(const gmx_vsite_t *vsite, - rvec x[], - real dt, rvec v[], - const t_iparams ip[], const t_ilist ilist[], - int ePBC, gmx_bool bMolPBC, - const t_commrec *cr, - const matrix box); +void construct_vsites(const gmx_vsite_t* vsite, + rvec x[], + real dt, + rvec v[], + const t_iparams ip[], + const t_ilist ilist[], + int ePBC, + gmx_bool bMolPBC, + const t_commrec* cr, + const matrix box); /*! \brief Create positions of vsite atoms for the whole system assuming all molecules are wholex * * \param[in] mtop The global topology * \param[in,out] x The global coordinates */ -void constructVsitesGlobal(const gmx_mtop_t &mtop, - gmx::ArrayRef x); - -void spread_vsite_f(const gmx_vsite_t *vsite, - const rvec x[], - rvec f[], rvec *fshift, - gmx_bool VirCorr, matrix vir, - t_nrnb *nrnb, const t_idef *idef, - int ePBC, gmx_bool bMolPBC, const t_graph *g, const matrix box, - const t_commrec *cr, gmx_wallcycle *wcycle); +void constructVsitesGlobal(const gmx_mtop_t& mtop, gmx::ArrayRef x); + +void spread_vsite_f(const gmx_vsite_t* vsite, + const rvec x[], + rvec f[], + rvec* fshift, + gmx_bool VirCorr, + matrix vir, + t_nrnb* nrnb, + const t_idef* idef, + int ePBC, + gmx_bool bMolPBC, + const t_graph* g, + const matrix box, + const t_commrec* cr, + gmx_wallcycle* wcycle); /* Spread the force operating on the vsite atoms on the surrounding atoms. * If fshift!=NULL also update the shift forces. * If VirCorr=TRUE add the virial correction for non-linear vsite constructs @@ -132,15 +137,15 @@ void spread_vsite_f(const gmx_vsite_t *vsite, */ /* Return the number of non-linear virtual site constructions in the system */ -int countNonlinearVsites(const gmx_mtop_t &mtop); +int countNonlinearVsites(const gmx_mtop_t& mtop); /* Return the number of virtual sites that cross update groups * * \param[in] mtop The global topology * \param[in] updateGroupingPerMoleculetype Update grouping per molecule type, pass empty when not using update groups */ -int countInterUpdategroupVsites(const gmx_mtop_t &mtop, - gmx::ArrayRef updateGroupingPerMoleculetype); +int countInterUpdategroupVsites(const gmx_mtop_t& mtop, + gmx::ArrayRef updateGroupingPerMoleculetype); /* Initialize the virtual site struct, * @@ -148,21 +153,17 @@ int countInterUpdategroupVsites(const gmx_mtop_t &mto * \param[in] cr The communication record * \returns A valid vsite struct or nullptr when there are no virtual sites */ -std::unique_ptr -initVsite(const gmx_mtop_t &mtop, - const t_commrec *cr); - -void split_vsites_over_threads(const t_ilist *ilist, - const t_iparams *ip, - const t_mdatoms *mdatoms, - gmx_vsite_t *vsite); +std::unique_ptr initVsite(const gmx_mtop_t& mtop, const t_commrec* cr); + +void split_vsites_over_threads(const t_ilist* ilist, + const t_iparams* ip, + const t_mdatoms* mdatoms, + gmx_vsite_t* vsite); /* Divide the vsite work-load over the threads. * Should be called at the end of the domain decomposition. */ -void set_vsite_top(gmx_vsite_t *vsite, - const gmx_localtop_t *top, - const t_mdatoms *md); +void set_vsite_top(gmx_vsite_t* vsite, const gmx_localtop_t* top, const t_mdatoms* md); /* Set some vsite data for runs without domain decomposition. * Should be called once after init_vsite, before calling other routines. */ diff --git a/src/gromacs/mdlib/wall.cpp b/src/gromacs/mdlib/wall.cpp index b10b14b69b..d03f55344c 100644 --- a/src/gromacs/mdlib/wall.cpp +++ b/src/gromacs/mdlib/wall.cpp @@ -58,21 +58,21 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -void make_wall_tables(FILE *fplog, - const t_inputrec *ir, const char *tabfn, - const SimulationGroups *groups, - t_forcerec *fr) +void make_wall_tables(FILE* fplog, + const t_inputrec* ir, + const char* tabfn, + const SimulationGroups* groups, + t_forcerec* fr) { - int negp_pp; - char buf[STRLEN]; + int negp_pp; + char buf[STRLEN]; - negp_pp = ir->opts.ngener - ir->nwall; - gmx::ArrayRef nm_ind = groups->groups[SimulationAtomGroupType::EnergyOutput]; + negp_pp = ir->opts.ngener - ir->nwall; + gmx::ArrayRef nm_ind = groups->groups[SimulationAtomGroupType::EnergyOutput]; if (fplog) { - fprintf(fplog, "Reading user tables for %d energy groups with %d walls\n", - negp_pp, ir->nwall); + fprintf(fplog, "Reading user tables for %d energy groups with %d walls\n", negp_pp, ir->nwall); } snew(fr->wall_tab, ir->nwall); @@ -82,23 +82,21 @@ void make_wall_tables(FILE *fplog, for (int egp = 0; egp < negp_pp; egp++) { /* If the energy group pair is excluded, we don't need a table */ - if (!(fr->egp_flags[egp*ir->opts.ngener+negp_pp+w] & EGP_EXCL)) + if (!(fr->egp_flags[egp * ir->opts.ngener + negp_pp + w] & EGP_EXCL)) { sprintf(buf, "%s", tabfn); sprintf(buf + strlen(tabfn) - strlen(ftp2ext(efXVG)) - 1, "_%s_%s.%s", - *groups->groupNames[nm_ind[egp]], - *groups->groupNames[nm_ind[negp_pp+w]], + *groups->groupNames[nm_ind[egp]], *groups->groupNames[nm_ind[negp_pp + w]], ftp2ext(efXVG)); - fr->wall_tab[w][egp] = make_tables(fplog, fr->ic, buf, 0, - GMX_MAKETABLES_FORCEUSER); + fr->wall_tab[w][egp] = make_tables(fplog, fr->ic, buf, 0, GMX_MAKETABLES_FORCEUSER); /* Since wall have no charge, we can compress the table */ for (int i = 0; i <= fr->wall_tab[w][egp]->n; i++) { for (int j = 0; j < 8; j++) { - fr->wall_tab[w][egp]->data[8*i+j] = - fr->wall_tab[w][egp]->data[12*i+4+j]; + fr->wall_tab[w][egp]->data[8 * i + j] = + fr->wall_tab[w][egp]->data[12 * i + 4 + j]; } } } @@ -106,7 +104,7 @@ void make_wall_tables(FILE *fplog, } } -[[ noreturn ]] static void wall_error(int a, const rvec *x, real r) +[[noreturn]] static void wall_error(int a, const rvec* x, real r) { gmx_fatal(FARGS, "An atom is beyond the wall: coordinates %f %f %f, distance %f\n" @@ -114,100 +112,99 @@ void make_wall_tables(FILE *fplog, x[a][XX], x[a][YY], x[a][ZZ], r); } -static void tableForce(real r, - const t_forcetable &tab, - real Cd, - real Cr, - real *V, - real *F) +static void tableForce(real r, const t_forcetable& tab, real Cd, real Cr, real* V, real* F) { const real tabscale = tab.scale; - const real *VFtab = tab.data; + const real* VFtab = tab.data; - real rt = r*tabscale; - int n0 = static_cast(rt); + real rt = r * tabscale; + int n0 = static_cast(rt); if (n0 >= tab.n) { /* Beyond the table range, set V and F to zero */ - *V = 0; - *F = 0; + *V = 0; + *F = 0; } else { - real eps = rt - n0; - real eps2 = eps*eps; + real eps = rt - n0; + real eps2 = eps * eps; /* Dispersion */ - int nnn = 8*n0; + int nnn = 8 * n0; real Yt = VFtab[nnn]; real Ft = VFtab[nnn + 1]; - real Geps = VFtab[nnn + 2]*eps; - real Heps2 = VFtab[nnn + 3]*eps2; + real Geps = VFtab[nnn + 2] * eps; + real Heps2 = VFtab[nnn + 3] * eps2; real Fp = Ft + Geps + Heps2; - real VV = Yt + Fp*eps; - real FF = Fp + Geps + 2.0*Heps2; - real Vd = 6*Cd*VV; - real Fd = 6*Cd*FF; + real VV = Yt + Fp * eps; + real FF = Fp + Geps + 2.0 * Heps2; + real Vd = 6 * Cd * VV; + real Fd = 6 * Cd * FF; /* Repulsion */ - nnn = nnn + 4; - Yt = VFtab[nnn]; - Ft = VFtab[nnn+1]; - Geps = VFtab[nnn+2]*eps; - Heps2 = VFtab[nnn+3]*eps2; - Fp = Ft + Geps + Heps2; - VV = Yt + Fp*eps; - FF = Fp + Geps + 2.0*Heps2; - real Vr = 12*Cr*VV; - real Fr = 12*Cr*FF; - *V = Vd + Vr; - *F = -(Fd + Fr)*tabscale; + nnn = nnn + 4; + Yt = VFtab[nnn]; + Ft = VFtab[nnn + 1]; + Geps = VFtab[nnn + 2] * eps; + Heps2 = VFtab[nnn + 3] * eps2; + Fp = Ft + Geps + Heps2; + VV = Yt + Fp * eps; + FF = Fp + Geps + 2.0 * Heps2; + real Vr = 12 * Cr * VV; + real Fr = 12 * Cr * FF; + *V = Vd + Vr; + *F = -(Fd + Fr) * tabscale; } } -real do_walls(const t_inputrec &ir, const t_forcerec &fr, - const matrix box, const t_mdatoms &md, - const rvec *x, gmx::ForceWithVirial *forceWithVirial, - real lambda, real Vlj[], t_nrnb *nrnb) +real do_walls(const t_inputrec& ir, + const t_forcerec& fr, + const matrix box, + const t_mdatoms& md, + const rvec* x, + gmx::ForceWithVirial* forceWithVirial, + real lambda, + real Vlj[], + t_nrnb* nrnb) { - constexpr real sixth = 1.0/6.0; - constexpr real twelfth = 1.0/12.0; + constexpr real sixth = 1.0 / 6.0; + constexpr real twelfth = 1.0 / 12.0; int ntw[2]; real fac_d[2], fac_r[2]; - const unsigned short *gid = md.cENER; + const unsigned short* gid = md.cENER; - const int nwall = ir.nwall; - const int ngid = ir.opts.ngener; - const int ntype = fr.ntype; - const real *nbfp = fr.nbfp; - const int *egp_flags = fr.egp_flags; + const int nwall = ir.nwall; + const int ngid = ir.opts.ngener; + const int ntype = fr.ntype; + const real* nbfp = fr.nbfp; + const int* egp_flags = fr.egp_flags; for (int w = 0; w < nwall; w++) { - ntw[w] = 2*ntype*ir.wall_atomtype[w]; + ntw[w] = 2 * ntype * ir.wall_atomtype[w]; switch (ir.wall_type) { case ewt93: - fac_d[w] = ir.wall_density[w]*M_PI/6; - fac_r[w] = ir.wall_density[w]*M_PI/45; + fac_d[w] = ir.wall_density[w] * M_PI / 6; + fac_r[w] = ir.wall_density[w] * M_PI / 45; break; case ewt104: - fac_d[w] = ir.wall_density[w]*M_PI/2; - fac_r[w] = ir.wall_density[w]*M_PI/5; - break; - default: + fac_d[w] = ir.wall_density[w] * M_PI / 2; + fac_r[w] = ir.wall_density[w] * M_PI / 5; break; + default: break; } } - const real wall_z[2] = { 0, box[ZZ][ZZ] }; + const real wall_z[2] = { 0, box[ZZ][ZZ] }; - rvec * gmx_restrict f = as_rvec_array(forceWithVirial->force_.data()); + rvec* gmx_restrict f = as_rvec_array(forceWithVirial->force_.data()); - real dvdlambda = 0; - double sumRF = 0; + real dvdlambda = 0; + double sumRF = 0; for (int lam = 0; lam < (md.nPerturbed ? 2 : 1); lam++) { real lamfac; - const int *type; + const int* type; if (md.nPerturbed) { if (lam == 0) @@ -233,11 +230,11 @@ real do_walls(const t_inputrec &ir, const t_forcerec &fr, for (int w = 0; w < std::min(nwall, 2); w++) { /* The wall energy groups are always at the end of the list */ - const int ggid = gid[i]*ngid + ngid - nwall + w; - const int at = type[i]; + const int ggid = gid[i] * ngid + ngid - nwall + w; + const int at = type[i]; /* nbfp now includes the 6/12 derivative prefactors */ - const real Cd = nbfp[ntw[w] + 2*at]*sixth; - const real Cr = nbfp[ntw[w] + 2*at + 1]*twelfth; + const real Cd = nbfp[ntw[w] + 2 * at] * sixth; + const real Cr = nbfp[ntw[w] + 2 * at + 1] * twelfth; if (!((Cd == 0 && Cr == 0) || (egp_flags[ggid] & EGP_EXCL))) { real r, mr; @@ -272,55 +269,55 @@ real do_walls(const t_inputrec &ir, const t_forcerec &fr, F *= lamfac; break; case ewt93: - r1 = 1/r; - r2 = r1*r1; - r4 = r2*r2; - Vd = fac_d[w]*Cd*r2*r1; - Vr = fac_r[w]*Cr*r4*r4*r1; + r1 = 1 / r; + r2 = r1 * r1; + r4 = r2 * r2; + Vd = fac_d[w] * Cd * r2 * r1; + Vr = fac_r[w] * Cr * r4 * r4 * r1; V = Vr - Vd; - F = lamfac*(9*Vr - 3*Vd)*r1; + F = lamfac * (9 * Vr - 3 * Vd) * r1; break; case ewt104: - r1 = 1/r; - r2 = r1*r1; - r4 = r2*r2; - Vd = fac_d[w]*Cd*r4; - Vr = fac_r[w]*Cr*r4*r4*r2; + r1 = 1 / r; + r2 = r1 * r1; + r4 = r2 * r2; + Vd = fac_d[w] * Cd * r4; + Vr = fac_r[w] * Cr * r4 * r4 * r2; V = Vr - Vd; - F = lamfac*(10*Vr - 4*Vd)*r1; + F = lamfac * (10 * Vr - 4 * Vd) * r1; break; case ewt126: - r1 = 1/r; - r2 = r1*r1; - r4 = r2*r2; - Vd = Cd*r4*r2; - Vr = Cr*r4*r4*r4; + r1 = 1 / r; + r2 = r1 * r1; + r4 = r2 * r2; + Vd = Cd * r4 * r2; + Vr = Cr * r4 * r4 * r4; V = Vr - Vd; - F = lamfac*(12*Vr - 6*Vd)*r1; + F = lamfac * (12 * Vr - 6 * Vd) * r1; break; default: - V = 0; - F = 0; + V = 0; + F = 0; break; } if (mr > 0) { - V += mr*F; + V += mr * F; } - sumRF += r*F; + sumRF += r * F; if (w == 1) { - F = -F; + F = -F; } - Vlj[ggid] += lamfac*V; - Vlambda += V; - f[i][ZZ] += F; + Vlj[ggid] += lamfac * V; + Vlambda += V; + f[i][ZZ] += F; } } } if (md.nPerturbed) { - dvdlambda += (lam == 0 ? -1 : 1)*Vlambda; + dvdlambda += (lam == 0 ? -1 : 1) * Vlambda; } inc_nrnb(nrnb, eNR_WALLS, md.homenr); @@ -328,7 +325,7 @@ real do_walls(const t_inputrec &ir, const t_forcerec &fr, if (forceWithVirial->computeVirial_) { - rvec virial = { 0, 0, static_cast(-0.5*sumRF) }; + rvec virial = { 0, 0, static_cast(-0.5 * sumRF) }; forceWithVirial->addVirialContribution(virial); } diff --git a/src/gromacs/mdlib/wall.h b/src/gromacs/mdlib/wall.h index 1b9007ea2d..95437da770 100644 --- a/src/gromacs/mdlib/wall.h +++ b/src/gromacs/mdlib/wall.h @@ -51,19 +51,20 @@ namespace gmx class ForceWithVirial; } -void make_wall_tables(FILE *fplog, - const t_inputrec *ir, const char *tabfn, - const SimulationGroups *groups, - t_forcerec *fr); +void make_wall_tables(FILE* fplog, + const t_inputrec* ir, + const char* tabfn, + const SimulationGroups* groups, + t_forcerec* fr); -real do_walls(const t_inputrec &ir, - const t_forcerec &fr, - const matrix box, - const t_mdatoms &md, - const rvec x[], - gmx::ForceWithVirial *forceWithVirial, - real lambda, - real Vlj[], - t_nrnb *nrnb); +real do_walls(const t_inputrec& ir, + const t_forcerec& fr, + const matrix box, + const t_mdatoms& md, + const rvec x[], + gmx::ForceWithVirial* forceWithVirial, + real lambda, + real Vlj[], + t_nrnb* nrnb); #endif diff --git a/src/gromacs/mdrun/isimulator.h b/src/gromacs/mdrun/isimulator.h index 73f9a4119c..bd192bd8d5 100644 --- a/src/gromacs/mdrun/isimulator.h +++ b/src/gromacs/mdrun/isimulator.h @@ -89,162 +89,162 @@ struct MdrunOptions; */ class ISimulator { - public: - /*! \brief The simulation run - * - * This will be called by the owner of the simulator object. To be redefined - * by the child classes. This function is expected to run the simulation. - */ - virtual void run() = 0; - //! Standard destructor - virtual ~ISimulator() = default; - //! The constructor - ISimulator( - FILE *fplog, - t_commrec *cr, - const gmx_multisim_t *ms, - const MDLogger &mdlog, - int nfile, - const t_filenm *fnm, - const gmx_output_env_t *oenv, - const MdrunOptions &mdrunOptions, - StartingBehavior startingBehavior, - gmx_vsite_t *vsite, - Constraints *constr, - gmx_enfrot *enforcedRotation, - BoxDeformation *deform, - IMDOutputProvider *outputProvider, - const MdModulesNotifier &mdModulesNotifier, - t_inputrec *inputrec, - ImdSession *imdSession, - pull_t *pull_work, - t_swap *swap, - gmx_mtop_t *top_global, - t_fcdata *fcd, - t_state *state_global, - ObservablesHistory *observablesHistory, - MDAtoms *mdAtoms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - t_forcerec *fr, - gmx_enerdata_t *enerd, - gmx_ekindata_t *ekind, - MdrunScheduleWorkload *runScheduleWork, - const ReplicaExchangeParameters &replExParams, - gmx_membed_t *membed, - gmx_walltime_accounting *walltime_accounting, - std::unique_ptr stopHandlerBuilder, - bool doRerun) : - fplog(fplog), - cr(cr), - ms(ms), - mdlog(mdlog), - nfile(nfile), - fnm(fnm), - oenv(oenv), - mdrunOptions(mdrunOptions), - startingBehavior(startingBehavior), - vsite(vsite), - constr(constr), - enforcedRotation(enforcedRotation), - deform(deform), - outputProvider(outputProvider), - mdModulesNotifier(mdModulesNotifier), - inputrec(inputrec), - imdSession(imdSession), - pull_work(pull_work), - swap(swap), - top_global(top_global), - fcd(fcd), - state_global(state_global), - observablesHistory(observablesHistory), - mdAtoms(mdAtoms), - nrnb(nrnb), - wcycle(wcycle), - fr(fr), - enerd(enerd), - ekind(ekind), - runScheduleWork(runScheduleWork), - replExParams(replExParams), - membed(membed), - walltime_accounting(walltime_accounting), - stopHandlerBuilder(std::move(stopHandlerBuilder)), - doRerun(doRerun) - {} +public: + /*! \brief The simulation run + * + * This will be called by the owner of the simulator object. To be redefined + * by the child classes. This function is expected to run the simulation. + */ + virtual void run() = 0; + //! Standard destructor + virtual ~ISimulator() = default; + //! The constructor + ISimulator(FILE* fplog, + t_commrec* cr, + const gmx_multisim_t* ms, + const MDLogger& mdlog, + int nfile, + const t_filenm* fnm, + const gmx_output_env_t* oenv, + const MdrunOptions& mdrunOptions, + StartingBehavior startingBehavior, + gmx_vsite_t* vsite, + Constraints* constr, + gmx_enfrot* enforcedRotation, + BoxDeformation* deform, + IMDOutputProvider* outputProvider, + const MdModulesNotifier& mdModulesNotifier, + t_inputrec* inputrec, + ImdSession* imdSession, + pull_t* pull_work, + t_swap* swap, + gmx_mtop_t* top_global, + t_fcdata* fcd, + t_state* state_global, + ObservablesHistory* observablesHistory, + MDAtoms* mdAtoms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + t_forcerec* fr, + gmx_enerdata_t* enerd, + gmx_ekindata_t* ekind, + MdrunScheduleWorkload* runScheduleWork, + const ReplicaExchangeParameters& replExParams, + gmx_membed_t* membed, + gmx_walltime_accounting* walltime_accounting, + std::unique_ptr stopHandlerBuilder, + bool doRerun) : + fplog(fplog), + cr(cr), + ms(ms), + mdlog(mdlog), + nfile(nfile), + fnm(fnm), + oenv(oenv), + mdrunOptions(mdrunOptions), + startingBehavior(startingBehavior), + vsite(vsite), + constr(constr), + enforcedRotation(enforcedRotation), + deform(deform), + outputProvider(outputProvider), + mdModulesNotifier(mdModulesNotifier), + inputrec(inputrec), + imdSession(imdSession), + pull_work(pull_work), + swap(swap), + top_global(top_global), + fcd(fcd), + state_global(state_global), + observablesHistory(observablesHistory), + mdAtoms(mdAtoms), + nrnb(nrnb), + wcycle(wcycle), + fr(fr), + enerd(enerd), + ekind(ekind), + runScheduleWork(runScheduleWork), + replExParams(replExParams), + membed(membed), + walltime_accounting(walltime_accounting), + stopHandlerBuilder(std::move(stopHandlerBuilder)), + doRerun(doRerun) + { + } - protected: - //! Handles logging. - FILE *fplog; - //! Handles communication. - t_commrec *cr; - //! Coordinates multi-simulations. - const gmx_multisim_t *ms; - //! Handles logging. - const MDLogger &mdlog; - //! Count of input file options. - int nfile; - //! Content of input file options. - const t_filenm *fnm; - //! Handles writing text output. - const gmx_output_env_t *oenv; - //! Contains command-line options to mdrun. - const MdrunOptions &mdrunOptions; - //! Whether the simulation will start afresh, or restart with/without appending. - StartingBehavior startingBehavior; - //! Handles virtual sites. - gmx_vsite_t *vsite; - //! Handles constraints. - Constraints *constr; - //! Handles enforced rotation. - gmx_enfrot *enforcedRotation; - //! Handles box deformation. - BoxDeformation *deform; - //! Handles writing output files. - IMDOutputProvider *outputProvider; - //! Handles notifications to MdModules for checkpoint writing - const MdModulesNotifier &mdModulesNotifier; - //! Contains user input mdp options. - t_inputrec *inputrec; - //! The Interactive Molecular Dynamics session. - ImdSession *imdSession; - //! The pull work object. - pull_t *pull_work; - //! The coordinate-swapping session. - t_swap *swap; - //! Full system topology. - gmx_mtop_t *top_global; - //! Helper struct for force calculations. - t_fcdata *fcd; - //! Full simulation state (only non-nullptr on master rank). - t_state *state_global; - //! History of simulation observables. - ObservablesHistory *observablesHistory; - //! Atom parameters for this domain. - MDAtoms *mdAtoms; - //! Manages flop accounting. - t_nrnb *nrnb; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle; - //! Parameters for force calculations. - t_forcerec *fr; - //! Data for energy output. - gmx_enerdata_t *enerd; - //! Kinetic energy data. - gmx_ekindata_t *ekind; - //! Schedule of work for each MD step for this task. - MdrunScheduleWorkload *runScheduleWork; - //! Parameters for replica exchange algorihtms. - const ReplicaExchangeParameters &replExParams; - //! Parameters for membrane embedding. - gmx_membed_t *membed; - //! Manages wall time accounting. - gmx_walltime_accounting *walltime_accounting; - //! Registers stop conditions - std::unique_ptr stopHandlerBuilder; - //! Whether we're doing a rerun. - bool doRerun; +protected: + //! Handles logging. + FILE* fplog; + //! Handles communication. + t_commrec* cr; + //! Coordinates multi-simulations. + const gmx_multisim_t* ms; + //! Handles logging. + const MDLogger& mdlog; + //! Count of input file options. + int nfile; + //! Content of input file options. + const t_filenm* fnm; + //! Handles writing text output. + const gmx_output_env_t* oenv; + //! Contains command-line options to mdrun. + const MdrunOptions& mdrunOptions; + //! Whether the simulation will start afresh, or restart with/without appending. + StartingBehavior startingBehavior; + //! Handles virtual sites. + gmx_vsite_t* vsite; + //! Handles constraints. + Constraints* constr; + //! Handles enforced rotation. + gmx_enfrot* enforcedRotation; + //! Handles box deformation. + BoxDeformation* deform; + //! Handles writing output files. + IMDOutputProvider* outputProvider; + //! Handles notifications to MdModules for checkpoint writing + const MdModulesNotifier& mdModulesNotifier; + //! Contains user input mdp options. + t_inputrec* inputrec; + //! The Interactive Molecular Dynamics session. + ImdSession* imdSession; + //! The pull work object. + pull_t* pull_work; + //! The coordinate-swapping session. + t_swap* swap; + //! Full system topology. + gmx_mtop_t* top_global; + //! Helper struct for force calculations. + t_fcdata* fcd; + //! Full simulation state (only non-nullptr on master rank). + t_state* state_global; + //! History of simulation observables. + ObservablesHistory* observablesHistory; + //! Atom parameters for this domain. + MDAtoms* mdAtoms; + //! Manages flop accounting. + t_nrnb* nrnb; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle; + //! Parameters for force calculations. + t_forcerec* fr; + //! Data for energy output. + gmx_enerdata_t* enerd; + //! Kinetic energy data. + gmx_ekindata_t* ekind; + //! Schedule of work for each MD step for this task. + MdrunScheduleWorkload* runScheduleWork; + //! Parameters for replica exchange algorihtms. + const ReplicaExchangeParameters& replExParams; + //! Parameters for membrane embedding. + gmx_membed_t* membed; + //! Manages wall time accounting. + gmx_walltime_accounting* walltime_accounting; + //! Registers stop conditions + std::unique_ptr stopHandlerBuilder; + //! Whether we're doing a rerun. + bool doRerun; }; -} // namespace gmx +} // namespace gmx -#endif //GMX_MDRUN_ISIMULATOR_H +#endif // GMX_MDRUN_ISIMULATOR_H diff --git a/src/gromacs/mdrun/legacymdrunoptions.cpp b/src/gromacs/mdrun/legacymdrunoptions.cpp index 2e4b88f3a0..2b8e3a0760 100644 --- a/src/gromacs/mdrun/legacymdrunoptions.cpp +++ b/src/gromacs/mdrun/legacymdrunoptions.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +60,7 @@ namespace gmx /*! \brief Return whether the command-line parameter that * will trigger a multi-simulation is set */ -static bool is_multisim_option_set(int argc, const char *const argv[]) +static bool is_multisim_option_set(int argc, const char* const argv[]) { for (int i = 0; i < argc; ++i) { @@ -72,9 +72,9 @@ static bool is_multisim_option_set(int argc, const char *const argv[]) return false; } -int LegacyMdrunOptions::updateFromCommandLine(int argc, char **argv, ArrayRef desc) +int LegacyMdrunOptions::updateFromCommandLine(int argc, char** argv, ArrayRef desc) { - unsigned long PCA_Flags = PCA_CAN_SET_DEFFNM; + unsigned long PCA_Flags = PCA_CAN_SET_DEFFNM; // With -multidir, the working directory still needs to be // changed, so we can't check for the existence of files during // parsing. It isn't useful to do any completion based on file @@ -84,9 +84,8 @@ int LegacyMdrunOptions::updateFromCommandLine(int argc, char **argv, ArrayRef(nenum(ddrank_opt_choices)); diff --git a/src/gromacs/mdrun/legacymdrunoptions.h b/src/gromacs/mdrun/legacymdrunoptions.h index d5e47c872b..796e479490 100644 --- a/src/gromacs/mdrun/legacymdrunoptions.h +++ b/src/gromacs/mdrun/legacymdrunoptions.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -77,201 +77,306 @@ namespace gmx * the role of SimulationContext, and should be moved there */ class LegacyMdrunOptions { - public: - //! Ongoing collection of mdrun options - MdrunOptions mdrunOptions; - //! Options for the domain decomposition. - DomdecOptions domdecOptions; - //! Parallelism-related user options. - gmx_hw_opt_t hw_opt; - //! Command-line override for the duration of a neighbor list with the Verlet scheme. - int nstlist_cmdline = 0; - //! Parameters for replica-exchange simulations. - ReplicaExchangeParameters replExParams; +public: + //! Ongoing collection of mdrun options + MdrunOptions mdrunOptions; + //! Options for the domain decomposition. + DomdecOptions domdecOptions; + //! Parallelism-related user options. + gmx_hw_opt_t hw_opt; + //! Command-line override for the duration of a neighbor list with the Verlet scheme. + int nstlist_cmdline = 0; + //! Parameters for replica-exchange simulations. + ReplicaExchangeParameters replExParams; - //! Filename options to fill from command-line argument values. - std::vector filenames = - {{{ efTPR, nullptr, nullptr, ffREAD }, - { efTRN, "-o", nullptr, ffWRITE }, - { efCOMPRESSED, "-x", nullptr, ffOPTWR }, - { efCPT, "-cpi", nullptr, ffOPTRD | ffALLOW_MISSING }, - { efCPT, "-cpo", nullptr, ffOPTWR }, - { efSTO, "-c", "confout", ffWRITE }, - { efEDR, "-e", "ener", ffWRITE }, - { efLOG, "-g", "md", ffWRITE }, - { efXVG, "-dhdl", "dhdl", ffOPTWR }, - { efXVG, "-field", "field", ffOPTWR }, - { efXVG, "-table", "table", ffOPTRD }, - { efXVG, "-tablep", "tablep", ffOPTRD }, - { efXVG, "-tableb", "table", ffOPTRDMULT }, - { efTRX, "-rerun", "rerun", ffOPTRD }, - { efXVG, "-tpi", "tpi", ffOPTWR }, - { efXVG, "-tpid", "tpidist", ffOPTWR }, - { efEDI, "-ei", "sam", ffOPTRD }, - { efXVG, "-eo", "edsam", ffOPTWR }, - { efXVG, "-px", "pullx", ffOPTWR }, - { efXVG, "-pf", "pullf", ffOPTWR }, - { efXVG, "-ro", "rotation", ffOPTWR }, - { efLOG, "-ra", "rotangles", ffOPTWR }, - { efLOG, "-rs", "rotslabs", ffOPTWR }, - { efLOG, "-rt", "rottorque", ffOPTWR }, - { efMTX, "-mtx", "nm", ffOPTWR }, - { efRND, "-multidir", nullptr, ffOPTRDMULT}, - { efXVG, "-awh", "awhinit", ffOPTRD }, - { efDAT, "-membed", "membed", ffOPTRD }, - { efTOP, "-mp", "membed", ffOPTRD }, - { efNDX, "-mn", "membed", ffOPTRD }, - { efXVG, "-if", "imdforces", ffOPTWR }, - { efXVG, "-swap", "swapions", ffOPTWR }}}; + //! Filename options to fill from command-line argument values. + std::vector filenames = { { { efTPR, nullptr, nullptr, ffREAD }, + { efTRN, "-o", nullptr, ffWRITE }, + { efCOMPRESSED, "-x", nullptr, ffOPTWR }, + { efCPT, "-cpi", nullptr, ffOPTRD | ffALLOW_MISSING }, + { efCPT, "-cpo", nullptr, ffOPTWR }, + { efSTO, "-c", "confout", ffWRITE }, + { efEDR, "-e", "ener", ffWRITE }, + { efLOG, "-g", "md", ffWRITE }, + { efXVG, "-dhdl", "dhdl", ffOPTWR }, + { efXVG, "-field", "field", ffOPTWR }, + { efXVG, "-table", "table", ffOPTRD }, + { efXVG, "-tablep", "tablep", ffOPTRD }, + { efXVG, "-tableb", "table", ffOPTRDMULT }, + { efTRX, "-rerun", "rerun", ffOPTRD }, + { efXVG, "-tpi", "tpi", ffOPTWR }, + { efXVG, "-tpid", "tpidist", ffOPTWR }, + { efEDI, "-ei", "sam", ffOPTRD }, + { efXVG, "-eo", "edsam", ffOPTWR }, + { efXVG, "-px", "pullx", ffOPTWR }, + { efXVG, "-pf", "pullf", ffOPTWR }, + { efXVG, "-ro", "rotation", ffOPTWR }, + { efLOG, "-ra", "rotangles", ffOPTWR }, + { efLOG, "-rs", "rotslabs", ffOPTWR }, + { efLOG, "-rt", "rottorque", ffOPTWR }, + { efMTX, "-mtx", "nm", ffOPTWR }, + { efRND, "-multidir", nullptr, ffOPTRDMULT }, + { efXVG, "-awh", "awhinit", ffOPTRD }, + { efDAT, "-membed", "membed", ffOPTRD }, + { efTOP, "-mp", "membed", ffOPTRD }, + { efNDX, "-mn", "membed", ffOPTRD }, + { efXVG, "-if", "imdforces", ffOPTWR }, + { efXVG, "-swap", "swapions", ffOPTWR } } }; - //! Print a warning if any force is larger than this (in kJ/mol nm). - real pforce = -1; + //! Print a warning if any force is larger than this (in kJ/mol nm). + real pforce = -1; - //! The value of the -append option - bool appendOption = true; + //! The value of the -append option + bool appendOption = true; - /*! \brief Output context for writing text files - * - * \todo Clarify initialization, ownership, and lifetime. */ - gmx_output_env_t *oenv = nullptr; + /*! \brief Output context for writing text files + * + * \todo Clarify initialization, ownership, and lifetime. */ + gmx_output_env_t* oenv = nullptr; - /*! \brief Command line options, defaults, docs and storage for them to fill. */ - /*! \{ */ - rvec realddxyz = {0, 0, 0}; - const char *ddrank_opt_choices[static_cast(DdRankOrder::Count)+1] = - { nullptr, "interleave", "pp_pme", "cartesian", nullptr }; - const char *dddlb_opt_choices[static_cast(DlbOption::Count)+1] = - { nullptr, "auto", "no", "yes", nullptr }; - const char *thread_aff_opt_choices[static_cast(ThreadAffinity::Count) + 1] = - { nullptr, "auto", "on", "off", nullptr }; - const char *nbpu_opt_choices[5] = - { nullptr, "auto", "cpu", "gpu", nullptr }; - const char *pme_opt_choices[5] = - { nullptr, "auto", "cpu", "gpu", nullptr }; - const char *pme_fft_opt_choices[5] = - { nullptr, "auto", "cpu", "gpu", nullptr }; - const char *bonded_opt_choices[5] = - { nullptr, "auto", "cpu", "gpu", nullptr }; - const char *update_opt_choices[5] = - { nullptr, "auto", "cpu", "gpu", nullptr }; - const char *gpuIdsAvailable = ""; - const char *userGpuTaskAssignment = ""; + /*! \brief Command line options, defaults, docs and storage for them to fill. */ + /*! \{ */ + rvec realddxyz = { 0, 0, 0 }; + const char* ddrank_opt_choices[static_cast(DdRankOrder::Count) + 1] = { + nullptr, "interleave", "pp_pme", "cartesian", nullptr + }; + const char* dddlb_opt_choices[static_cast(DlbOption::Count) + 1] = { nullptr, "auto", "no", + "yes", nullptr }; + const char* thread_aff_opt_choices[static_cast(ThreadAffinity::Count) + 1] = { + nullptr, "auto", "on", "off", nullptr + }; + const char* nbpu_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr }; + const char* pme_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr }; + const char* pme_fft_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr }; + const char* bonded_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr }; + const char* update_opt_choices[5] = { nullptr, "auto", "cpu", "gpu", nullptr }; + const char* gpuIdsAvailable = ""; + const char* userGpuTaskAssignment = ""; - ImdOptions &imdOptions = mdrunOptions.imdOptions; + ImdOptions& imdOptions = mdrunOptions.imdOptions; - t_pargs pa[48] = { + t_pargs pa[48] = { - { "-dd", FALSE, etRVEC, {&realddxyz}, - "Domain decomposition grid, 0 is optimize" }, - { "-ddorder", FALSE, etENUM, {ddrank_opt_choices}, - "DD rank order" }, - { "-npme", FALSE, etINT, {&domdecOptions.numPmeRanks}, - "Number of separate ranks to be used for PME, -1 is guess" }, - { "-nt", FALSE, etINT, {&hw_opt.nthreads_tot}, - "Total number of threads to start (0 is guess)" }, - { "-ntmpi", FALSE, etINT, {&hw_opt.nthreads_tmpi}, - "Number of thread-MPI ranks to start (0 is guess)" }, - { "-ntomp", FALSE, etINT, {&hw_opt.nthreads_omp}, - "Number of OpenMP threads per MPI rank to start (0 is guess)" }, - { "-ntomp_pme", FALSE, etINT, {&hw_opt.nthreads_omp_pme}, - "Number of OpenMP threads per MPI rank to start (0 is -ntomp)" }, - { "-pin", FALSE, etENUM, {thread_aff_opt_choices}, - "Whether mdrun should try to set thread affinities" }, - { "-pinoffset", FALSE, etINT, {&hw_opt.core_pinning_offset}, - "The lowest logical core number to which mdrun should pin the first thread" }, - { "-pinstride", FALSE, etINT, {&hw_opt.core_pinning_stride}, - "Pinning distance in logical cores for threads, use 0 to minimize the number of threads per physical core" }, - { "-gpu_id", FALSE, etSTR, {&gpuIdsAvailable}, - "List of unique GPU device IDs available to use" }, - { "-gputasks", FALSE, etSTR, {&userGpuTaskAssignment}, - "List of GPU device IDs, mapping each PP task on each node to a device" }, - { "-ddcheck", FALSE, etBOOL, {&domdecOptions.checkBondedInteractions}, - "Check for all bonded interactions with DD" }, - { "-ddbondcomm", FALSE, etBOOL, {&domdecOptions.useBondedCommunication}, - "HIDDENUse special bonded atom communication when [TT]-rdd[tt] > cut-off" }, - { "-rdd", FALSE, etREAL, {&domdecOptions.minimumCommunicationRange}, - "The maximum distance for bonded interactions with DD (nm), 0 is determine from initial coordinates" }, - { "-rcon", FALSE, etREAL, {&domdecOptions.constraintCommunicationRange}, - "Maximum distance for P-LINCS (nm), 0 is estimate" }, - { "-dlb", FALSE, etENUM, {dddlb_opt_choices}, - "Dynamic load balancing (with DD)" }, - { "-dds", FALSE, etREAL, {&domdecOptions.dlbScaling}, - "Fraction in (0,1) by whose reciprocal the initial DD cell size will be increased in order to " - "provide a margin in which dynamic load balancing can act while preserving the minimum cell size." }, - { "-ddcsx", FALSE, etSTR, {&domdecOptions.cellSizeX}, - "HIDDENA string containing a vector of the relative sizes in the x " - "direction of the corresponding DD cells. Only effective with static " - "load balancing." }, - { "-ddcsy", FALSE, etSTR, {&domdecOptions.cellSizeY}, - "HIDDENA string containing a vector of the relative sizes in the y " - "direction of the corresponding DD cells. Only effective with static " - "load balancing." }, - { "-ddcsz", FALSE, etSTR, {&domdecOptions.cellSizeZ}, - "HIDDENA string containing a vector of the relative sizes in the z " - "direction of the corresponding DD cells. Only effective with static " - "load balancing." }, - { "-nb", FALSE, etENUM, {nbpu_opt_choices}, - "Calculate non-bonded interactions on" }, - { "-nstlist", FALSE, etINT, {&nstlist_cmdline}, - "Set nstlist when using a Verlet buffer tolerance (0 is guess)" }, - { "-tunepme", FALSE, etBOOL, {&mdrunOptions.tunePme}, - "Optimize PME load between PP/PME ranks or GPU/CPU" }, - { "-pme", FALSE, etENUM, {pme_opt_choices}, - "Perform PME calculations on" }, - { "-pmefft", FALSE, etENUM, {pme_fft_opt_choices}, - "Perform PME FFT calculations on" }, - { "-bonded", FALSE, etENUM, {bonded_opt_choices}, - "Perform bonded calculations on" }, - { "-update", FALSE, etENUM, {update_opt_choices}, - "Perform update and constraints on"}, - { "-v", FALSE, etBOOL, {&mdrunOptions.verbose}, - "Be loud and noisy" }, - { "-pforce", FALSE, etREAL, {&pforce}, - "Print all forces larger than this (kJ/mol nm)" }, - { "-reprod", FALSE, etBOOL, {&mdrunOptions.reproducible}, - "Try to avoid optimizations that affect binary reproducibility" }, - { "-cpt", FALSE, etREAL, {&mdrunOptions.checkpointOptions.period}, - "Checkpoint interval (minutes)" }, - { "-cpnum", FALSE, etBOOL, {&mdrunOptions.checkpointOptions.keepAndNumberCheckpointFiles}, - "Keep and number checkpoint files" }, - { "-append", FALSE, etBOOL, {&appendOption}, - "Append to previous output files when continuing from checkpoint instead of adding the simulation part number to all file names" }, - { "-nsteps", FALSE, etINT64, {&mdrunOptions.numStepsCommandline}, - "Run this number of steps (-1 means infinite, -2 means use mdp option, smaller is invalid)" }, - { "-maxh", FALSE, etREAL, {&mdrunOptions.maximumHoursToRun}, - "Terminate after 0.99 times this time (hours)" }, - { "-replex", FALSE, etINT, {&replExParams.exchangeInterval}, - "Attempt replica exchange periodically with this period (steps)" }, - { "-nex", FALSE, etINT, {&replExParams.numExchanges}, - "Number of random exchanges to carry out each exchange interval (N^3 is one suggestion). -nex zero or not specified gives neighbor replica exchange." }, - { "-reseed", FALSE, etINT, {&replExParams.randomSeed}, - "Seed for replica exchange, -1 is generate a seed" }, - { "-imdport", FALSE, etINT, {&imdOptions.port}, - "HIDDENIMD listening port" }, - { "-imdwait", FALSE, etBOOL, {&imdOptions.wait}, - "HIDDENPause the simulation while no IMD client is connected" }, - { "-imdterm", FALSE, etBOOL, {&imdOptions.terminatable}, - "HIDDENAllow termination of the simulation from IMD client" }, - { "-imdpull", FALSE, etBOOL, {&imdOptions.pull}, - "HIDDENAllow pulling in the simulation from IMD client" }, - { "-rerunvsite", FALSE, etBOOL, {&mdrunOptions.rerunConstructVsites}, - "HIDDENRecalculate virtual site coordinates with [TT]-rerun[tt]" }, - { "-confout", FALSE, etBOOL, {&mdrunOptions.writeConfout}, - "HIDDENWrite the last configuration with [TT]-c[tt] and force checkpointing at the last step" }, - { "-stepout", FALSE, etINT, {&mdrunOptions.verboseStepPrintInterval}, - "HIDDENFrequency of writing the remaining wall clock time for the run" }, - { "-resetstep", FALSE, etINT, {&mdrunOptions.timingOptions.resetStep}, - "HIDDENReset cycle counters after these many time steps" }, - { "-resethway", FALSE, etBOOL, {&mdrunOptions.timingOptions.resetHalfway}, - "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt]" } - }; - /*! \} */ + { "-dd", FALSE, etRVEC, { &realddxyz }, "Domain decomposition grid, 0 is optimize" }, + { "-ddorder", FALSE, etENUM, { ddrank_opt_choices }, "DD rank order" }, + { "-npme", + FALSE, + etINT, + { &domdecOptions.numPmeRanks }, + "Number of separate ranks to be used for PME, -1 is guess" }, + { "-nt", + FALSE, + etINT, + { &hw_opt.nthreads_tot }, + "Total number of threads to start (0 is guess)" }, + { "-ntmpi", + FALSE, + etINT, + { &hw_opt.nthreads_tmpi }, + "Number of thread-MPI ranks to start (0 is guess)" }, + { "-ntomp", + FALSE, + etINT, + { &hw_opt.nthreads_omp }, + "Number of OpenMP threads per MPI rank to start (0 is guess)" }, + { "-ntomp_pme", + FALSE, + etINT, + { &hw_opt.nthreads_omp_pme }, + "Number of OpenMP threads per MPI rank to start (0 is -ntomp)" }, + { "-pin", + FALSE, + etENUM, + { thread_aff_opt_choices }, + "Whether mdrun should try to set thread affinities" }, + { "-pinoffset", + FALSE, + etINT, + { &hw_opt.core_pinning_offset }, + "The lowest logical core number to which mdrun should pin the first thread" }, + { "-pinstride", + FALSE, + etINT, + { &hw_opt.core_pinning_stride }, + "Pinning distance in logical cores for threads, use 0 to minimize the number of threads " + "per physical core" }, + { "-gpu_id", + FALSE, + etSTR, + { &gpuIdsAvailable }, + "List of unique GPU device IDs available to use" }, + { "-gputasks", + FALSE, + etSTR, + { &userGpuTaskAssignment }, + "List of GPU device IDs, mapping each PP task on each node to a device" }, + { "-ddcheck", + FALSE, + etBOOL, + { &domdecOptions.checkBondedInteractions }, + "Check for all bonded interactions with DD" }, + { "-ddbondcomm", + FALSE, + etBOOL, + { &domdecOptions.useBondedCommunication }, + "HIDDENUse special bonded atom communication when [TT]-rdd[tt] > cut-off" }, + { "-rdd", + FALSE, + etREAL, + { &domdecOptions.minimumCommunicationRange }, + "The maximum distance for bonded interactions with DD (nm), 0 is determine from initial " + "coordinates" }, + { "-rcon", + FALSE, + etREAL, + { &domdecOptions.constraintCommunicationRange }, + "Maximum distance for P-LINCS (nm), 0 is estimate" }, + { "-dlb", FALSE, etENUM, { dddlb_opt_choices }, "Dynamic load balancing (with DD)" }, + { "-dds", + FALSE, + etREAL, + { &domdecOptions.dlbScaling }, + "Fraction in (0,1) by whose reciprocal the initial DD cell size will be increased in " + "order to " + "provide a margin in which dynamic load balancing can act while preserving the minimum " + "cell size." }, + { "-ddcsx", + FALSE, + etSTR, + { &domdecOptions.cellSizeX }, + "HIDDENA string containing a vector of the relative sizes in the x " + "direction of the corresponding DD cells. Only effective with static " + "load balancing." }, + { "-ddcsy", + FALSE, + etSTR, + { &domdecOptions.cellSizeY }, + "HIDDENA string containing a vector of the relative sizes in the y " + "direction of the corresponding DD cells. Only effective with static " + "load balancing." }, + { "-ddcsz", + FALSE, + etSTR, + { &domdecOptions.cellSizeZ }, + "HIDDENA string containing a vector of the relative sizes in the z " + "direction of the corresponding DD cells. Only effective with static " + "load balancing." }, + { "-nb", FALSE, etENUM, { nbpu_opt_choices }, "Calculate non-bonded interactions on" }, + { "-nstlist", + FALSE, + etINT, + { &nstlist_cmdline }, + "Set nstlist when using a Verlet buffer tolerance (0 is guess)" }, + { "-tunepme", + FALSE, + etBOOL, + { &mdrunOptions.tunePme }, + "Optimize PME load between PP/PME ranks or GPU/CPU" }, + { "-pme", FALSE, etENUM, { pme_opt_choices }, "Perform PME calculations on" }, + { "-pmefft", FALSE, etENUM, { pme_fft_opt_choices }, "Perform PME FFT calculations on" }, + { "-bonded", FALSE, etENUM, { bonded_opt_choices }, "Perform bonded calculations on" }, + { "-update", FALSE, etENUM, { update_opt_choices }, "Perform update and constraints on" }, + { "-v", FALSE, etBOOL, { &mdrunOptions.verbose }, "Be loud and noisy" }, + { "-pforce", FALSE, etREAL, { &pforce }, "Print all forces larger than this (kJ/mol nm)" }, + { "-reprod", + FALSE, + etBOOL, + { &mdrunOptions.reproducible }, + "Try to avoid optimizations that affect binary reproducibility" }, + { "-cpt", + FALSE, + etREAL, + { &mdrunOptions.checkpointOptions.period }, + "Checkpoint interval (minutes)" }, + { "-cpnum", + FALSE, + etBOOL, + { &mdrunOptions.checkpointOptions.keepAndNumberCheckpointFiles }, + "Keep and number checkpoint files" }, + { "-append", + FALSE, + etBOOL, + { &appendOption }, + "Append to previous output files when continuing from checkpoint instead of adding the " + "simulation part number to all file names" }, + { "-nsteps", + FALSE, + etINT64, + { &mdrunOptions.numStepsCommandline }, + "Run this number of steps (-1 means infinite, -2 means use mdp option, smaller is " + "invalid)" }, + { "-maxh", + FALSE, + etREAL, + { &mdrunOptions.maximumHoursToRun }, + "Terminate after 0.99 times this time (hours)" }, + { "-replex", + FALSE, + etINT, + { &replExParams.exchangeInterval }, + "Attempt replica exchange periodically with this period (steps)" }, + { "-nex", + FALSE, + etINT, + { &replExParams.numExchanges }, + "Number of random exchanges to carry out each exchange interval (N^3 is one suggestion). " + " -nex zero or not specified gives neighbor replica exchange." }, + { "-reseed", + FALSE, + etINT, + { &replExParams.randomSeed }, + "Seed for replica exchange, -1 is generate a seed" }, + { "-imdport", FALSE, etINT, { &imdOptions.port }, "HIDDENIMD listening port" }, + { "-imdwait", + FALSE, + etBOOL, + { &imdOptions.wait }, + "HIDDENPause the simulation while no IMD client is connected" }, + { "-imdterm", + FALSE, + etBOOL, + { &imdOptions.terminatable }, + "HIDDENAllow termination of the simulation from IMD client" }, + { "-imdpull", + FALSE, + etBOOL, + { &imdOptions.pull }, + "HIDDENAllow pulling in the simulation from IMD client" }, + { "-rerunvsite", + FALSE, + etBOOL, + { &mdrunOptions.rerunConstructVsites }, + "HIDDENRecalculate virtual site coordinates with [TT]-rerun[tt]" }, + { "-confout", + FALSE, + etBOOL, + { &mdrunOptions.writeConfout }, + "HIDDENWrite the last configuration with [TT]-c[tt] and force checkpointing at the last " + "step" }, + { "-stepout", + FALSE, + etINT, + { &mdrunOptions.verboseStepPrintInterval }, + "HIDDENFrequency of writing the remaining wall clock time for the run" }, + { "-resetstep", + FALSE, + etINT, + { &mdrunOptions.timingOptions.resetStep }, + "HIDDENReset cycle counters after these many time steps" }, + { "-resethway", + FALSE, + etBOOL, + { &mdrunOptions.timingOptions.resetHalfway }, + "HIDDENReset the cycle counters after half the number of steps or halfway " + "[TT]-maxh[tt]" } + }; + /*! \} */ - //! Parses the command-line input and prepares to start mdrun. - int updateFromCommandLine(int argc, char **argv, ArrayRef desc); + //! Parses the command-line input and prepares to start mdrun. + int updateFromCommandLine(int argc, char** argv, ArrayRef desc); - ~LegacyMdrunOptions(); + ~LegacyMdrunOptions(); }; } // end namespace gmx diff --git a/src/gromacs/mdrun/legacysimulator.cpp b/src/gromacs/mdrun/legacysimulator.cpp index b2cf95ff8d..c6687d7c3a 100644 --- a/src/gromacs/mdrun/legacysimulator.cpp +++ b/src/gromacs/mdrun/legacysimulator.cpp @@ -61,7 +61,8 @@ void LegacySimulator::run() case eiVVAK: if (!EI_DYNAMICS(inputrec->eI)) { - GMX_THROW(APIError("do_md integrator would be called for a non-dynamical integrator")); + GMX_THROW(APIError( + "do_md integrator would be called for a non-dynamical integrator")); } if (doRerun) { @@ -82,18 +83,10 @@ void LegacySimulator::run() do_mimic(); } break; - case eiSteep: - do_steep(); - break; - case eiCG: - do_cg(); - break; - case eiNM: - do_nm(); - break; - case eiLBFGS: - do_lbfgs(); - break; + case eiSteep: do_steep(); break; + case eiCG: do_cg(); break; + case eiNM: do_nm(); break; + case eiLBFGS: do_lbfgs(); break; case eiTPI: case eiTPIC: if (!EI_TPI(inputrec->eI)) @@ -102,11 +95,9 @@ void LegacySimulator::run() } do_tpi(); break; - case eiSD2_REMOVED: - GMX_THROW(NotImplementedError("SD2 integrator has been removed")); - default: - GMX_THROW(APIError("Non existing integrator selected")); + case eiSD2_REMOVED: GMX_THROW(NotImplementedError("SD2 integrator has been removed")); + default: GMX_THROW(APIError("Non existing integrator selected")); } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdrun/legacysimulator.h b/src/gromacs/mdrun/legacysimulator.h index bd12ef98c1..7cf2a00e45 100644 --- a/src/gromacs/mdrun/legacysimulator.h +++ b/src/gromacs/mdrun/legacysimulator.h @@ -73,35 +73,35 @@ using SimulatorFunctionType = void(); */ class LegacySimulator : public ISimulator { - private: - //! Implements the normal MD simulations. - SimulatorFunctionType do_md; - //! Implements the rerun functionality. - SimulatorFunctionType do_rerun; - //! Implements steepest descent EM. - SimulatorFunctionType do_steep; - //! Implements conjugate gradient energy minimization - SimulatorFunctionType do_cg; - //! Implements onjugate gradient energy minimization using the L-BFGS algorithm - SimulatorFunctionType do_lbfgs; - //! Implements normal mode analysis - SimulatorFunctionType do_nm; - //! Implements test particle insertion - SimulatorFunctionType do_tpi; - //! Implements MiMiC QM/MM workflow - SimulatorFunctionType do_mimic; - // Use the constructor of the base class - using ISimulator::ISimulator; +private: + //! Implements the normal MD simulations. + SimulatorFunctionType do_md; + //! Implements the rerun functionality. + SimulatorFunctionType do_rerun; + //! Implements steepest descent EM. + SimulatorFunctionType do_steep; + //! Implements conjugate gradient energy minimization + SimulatorFunctionType do_cg; + //! Implements onjugate gradient energy minimization using the L-BFGS algorithm + SimulatorFunctionType do_lbfgs; + //! Implements normal mode analysis + SimulatorFunctionType do_nm; + //! Implements test particle insertion + SimulatorFunctionType do_tpi; + //! Implements MiMiC QM/MM workflow + SimulatorFunctionType do_mimic; + // Use the constructor of the base class + using ISimulator::ISimulator; - public: - // Only builder can construct - friend class SimulatorBuilder; +public: + // Only builder can construct + friend class SimulatorBuilder; - /*! \brief Function to run the correct SimulatorFunctionType, - * based on the .mdp integrator field. */ - void run() override; + /*! \brief Function to run the correct SimulatorFunctionType, + * based on the .mdp integrator field. */ + void run() override; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDRUN_LEGACYSIMULATOR_H diff --git a/src/gromacs/mdrun/md.cpp b/src/gromacs/mdrun/md.cpp index 82125e4fb5..bdaf94ce3a 100644 --- a/src/gromacs/mdrun/md.cpp +++ b/src/gromacs/mdrun/md.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -147,7 +147,7 @@ #include "shellfc.h" #if GMX_FAHCORE -#include "corewrap.h" +# include "corewrap.h" #endif using gmx::SimulationSignaller; @@ -160,46 +160,45 @@ void gmx::LegacySimulator::do_md() // alias to avoid a large ripple of nearly useless changes. // t_inputrec is being replaced by IMdpOptionsProvider, so this // will go away eventually. - t_inputrec *ir = inputrec; - int64_t step, step_rel; - double t, t0 = ir->init_t, lam0[efptNR]; - gmx_bool bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner; - gmx_bool bNS, bNStList, bStopCM, - bFirstStep, bInitStep, bLastStep = FALSE; - gmx_bool bDoDHDL = FALSE, bDoFEP = FALSE, bDoExpanded = FALSE; - gmx_bool do_ene, do_log, do_verbose; - gmx_bool bMasterState; - unsigned int force_flags; - tensor force_vir = {{0}}, shake_vir = {{0}}, total_vir = {{0}}, - tmp_vir = {{0}}, pres = {{0}}; + t_inputrec* ir = inputrec; + int64_t step, step_rel; + double t, t0 = ir->init_t, lam0[efptNR]; + gmx_bool bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner; + gmx_bool bNS, bNStList, bStopCM, bFirstStep, bInitStep, bLastStep = FALSE; + gmx_bool bDoDHDL = FALSE, bDoFEP = FALSE, bDoExpanded = FALSE; + gmx_bool do_ene, do_log, do_verbose; + gmx_bool bMasterState; + unsigned int force_flags; + tensor force_vir = { { 0 } }, shake_vir = { { 0 } }, total_vir = { { 0 } }, tmp_vir = { { 0 } }, + pres = { { 0 } }; int i, m; rvec mu_tot; matrix parrinellorahmanMu, M; gmx_repl_ex_t repl_ex = nullptr; gmx_localtop_t top; - PaddedHostVector f {}; + PaddedHostVector f{}; gmx_global_stat_t gstat; - t_graph *graph = nullptr; - gmx_shellfc_t *shellfc; + t_graph* graph = nullptr; + gmx_shellfc_t* shellfc; gmx_bool bSumEkinhOld, bDoReplEx, bExchanged, bNeedRepartition; gmx_bool bTemp, bPres, bTrotter; real dvdl_constr; std::vector cbuf; matrix lastbox; - int lamnew = 0; + int lamnew = 0; /* for FEP */ - int nstfep = 0; - double cycles; - real saved_conserved_quantity = 0; - real last_ekin = 0; - t_extmass MassQ; - char sbuf[STEPSTRSIZE], sbuf2[STEPSTRSIZE]; + int nstfep = 0; + double cycles; + real saved_conserved_quantity = 0; + real last_ekin = 0; + t_extmass MassQ; + char sbuf[STEPSTRSIZE], sbuf2[STEPSTRSIZE]; /* PME load balancing data for GPU kernels */ - gmx_bool bPMETune = FALSE; - gmx_bool bPMETunePrinting = FALSE; + gmx_bool bPMETune = FALSE; + gmx_bool bPMETunePrinting = FALSE; - bool bInteractiveMDstep = false; + bool bInteractiveMDstep = false; /* Domain decomposition could incorrectly miss a bonded interaction, but checking for that requires a global @@ -207,8 +206,8 @@ void gmx::LegacySimulator::do_md() code. So we do that alongside the first global energy reduction after a new DD is made. These variables handle whether the check happens, and the result it returns. */ - bool shouldCheckNumberOfBondedInteractions = false; - int totalNumberOfBondedInteractions = -1; + bool shouldCheckNumberOfBondedInteractions = false; + int totalNumberOfBondedInteractions = -1; SimulationSignals signals; // Most global communnication stages don't propagate mdrun @@ -221,33 +220,32 @@ void gmx::LegacySimulator::do_md() // turning it off is for convenience in benchmarking, which is // something that should not show up in the general user // interface. - GMX_LOG(mdlog.info).asParagraph(). - appendText("The -noconfout functionality is deprecated, and may be removed in a future version."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "The -noconfout functionality is deprecated, and may be removed in a " + "future version."); } /* md-vv uses averaged full step velocities for T-control md-vv-avek uses averaged half step velocities for T-control (but full step ekin for P control) md uses averaged half step kinetic energies to determine temperature unless defined otherwise by GMX_EKIN_AVE_VEL; */ - bTrotter = (EI_VV(ir->eI) && (inputrecNptTrotter(ir) || inputrecNphTrotter(ir) || inputrecNvtTrotter(ir))); + bTrotter = (EI_VV(ir->eI) + && (inputrecNptTrotter(ir) || inputrecNphTrotter(ir) || inputrecNvtTrotter(ir))); - const bool bRerunMD = false; + const bool bRerunMD = false; - int nstglobalcomm = computeGlobalCommunicationPeriod(mdlog, ir, cr); - bGStatEveryStep = (nstglobalcomm == 1); + int nstglobalcomm = computeGlobalCommunicationPeriod(mdlog, ir, cr); + bGStatEveryStep = (nstglobalcomm == 1); - SimulationGroups *groups = &top_global->groups; + SimulationGroups* groups = &top_global->groups; std::unique_ptr ed = nullptr; if (opt2bSet("-ei", nfile, fnm)) { /* Initialize essential dynamics sampling */ - ed = init_edsam(mdlog, - opt2fn_null("-ei", nfile, fnm), opt2fn("-eo", nfile, fnm), - top_global, - ir, cr, constr, - state_global, observablesHistory, - oenv, - startingBehavior); + ed = init_edsam(mdlog, opt2fn_null("-ei", nfile, fnm), opt2fn("-eo", nfile, fnm), top_global, + ir, cr, constr, state_global, observablesHistory, oenv, startingBehavior); } else if (observablesHistory->edsamHistory) { @@ -264,30 +262,28 @@ void gmx::LegacySimulator::do_md() { pleaseCiteCouplingAlgorithms(fplog, *ir); } - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, ir, top_global, oenv, wcycle, - startingBehavior); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, mdoutf_get_fp_dhdl(outf), false, mdModulesNotifier); + gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, + mdModulesNotifier, ir, top_global, oenv, wcycle, startingBehavior); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, + mdoutf_get_fp_dhdl(outf), false, mdModulesNotifier); gstat = global_stat_init(ir); /* Check for polarizable models and flexible constraints */ - shellfc = init_shell_flexcon(fplog, - top_global, constr ? constr->numFlexibleConstraints() : 0, + shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0, ir->nstcalcenergy, DOMAINDECOMP(cr)); { double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1); if ((io > 2000) && MASTER(cr)) { - fprintf(stderr, - "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", - io); + fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io); } } // Local state only becomes valid now. std::unique_ptr stateInstance; - t_state * state; + t_state* state; auto mdatoms = mdAtoms->mdatoms(); @@ -303,11 +299,8 @@ void gmx::LegacySimulator::do_md() dd_init_local_state(cr->dd, state_global, state); /* Distribute the charge groups over the nodes from the master node */ - dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, + dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir, + imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr, nrnb, nullptr, FALSE); shouldCheckNumberOfBondedInteractions = true; upd.setNumAtoms(state->natoms); @@ -320,53 +313,64 @@ void gmx::LegacySimulator::do_md() state = state_global; /* Generate and initialize new topology */ - mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, - &graph, mdAtoms, constr, vsite, shellfc); + mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, &graph, mdAtoms, constr, vsite, shellfc); upd.setNumAtoms(state->natoms); } -/*****************************************************************************************/ -// TODO: The following block of code should be refactored, once: -// 1. We have the useGpuForBufferOps variable set and available here and in do_force(...) -// 2. The proper GPU syncronization is introduced, so that the H2D and D2H data copies can be performed in the separate -// stream owned by the StatePropagatorDataGpu - const auto &simulationWork = runScheduleWork->simulationWork; + /*****************************************************************************************/ + // TODO: The following block of code should be refactored, once: + // 1. We have the useGpuForBufferOps variable set and available here and in do_force(...) + // 2. The proper GPU syncronization is introduced, so that the H2D and D2H data copies can be performed in the separate + // stream owned by the StatePropagatorDataGpu + const auto& simulationWork = runScheduleWork->simulationWork; const bool useGpuForPme = simulationWork.useGpuPme; const bool useGpuForNonbonded = simulationWork.useGpuNonbonded; // Temporary solution to make sure that the buffer ops are offloaded when update is offloaded - const bool useGpuForBufferOps = simulationWork.useGpuBufferOps; - const bool useGpuForUpdate = simulationWork.useGpuUpdate; + const bool useGpuForBufferOps = simulationWork.useGpuBufferOps; + const bool useGpuForUpdate = simulationWork.useGpuUpdate; - StatePropagatorDataGpu *stateGpu = fr->stateGpu; + StatePropagatorDataGpu* stateGpu = fr->stateGpu; if (useGpuForUpdate) { - GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr), "Domain decomposition is not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr), + "Domain decomposition is not supported with the GPU update.\n"); GMX_RELEASE_ASSERT(useGpuForPme || (useGpuForNonbonded && simulationWork.useGpuBufferOps), - "Either PME or short-ranged non-bonded interaction tasks must run on the GPU to use GPU update.\n"); - GMX_RELEASE_ASSERT(ir->eI == eiMD, "Only the md integrator is supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(ir->etc != etcNOSEHOOVER, "Nose-Hoover temperature coupling is not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(ir->epc == epcNO, "Pressure coupling is not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(!mdatoms->haveVsites, "Virtual sites are not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(ed == nullptr, "Essential dynamics is not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(!ir->bPull && !ir->pull, "Pulling is not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(fcd->orires.nr == 0, "Orientation restraints are not supported with the GPU update.\n"); - GMX_RELEASE_ASSERT(ir->efep == efepNO, "Free energy perturbations are not supported with the GPU update."); + "Either PME or short-ranged non-bonded interaction tasks must run on " + "the GPU to use GPU update.\n"); + GMX_RELEASE_ASSERT(ir->eI == eiMD, + "Only the md integrator is supported with the GPU update.\n"); + GMX_RELEASE_ASSERT( + ir->etc != etcNOSEHOOVER, + "Nose-Hoover temperature coupling is not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(ir->epc == epcNO, + "Pressure coupling is not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(!mdatoms->haveVsites, + "Virtual sites are not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(ed == nullptr, + "Essential dynamics is not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(!ir->bPull && !ir->pull, + "Pulling is not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(fcd->orires.nr == 0, + "Orientation restraints are not supported with the GPU update.\n"); + GMX_RELEASE_ASSERT(ir->efep == efepNO, + "Free energy perturbations are not supported with the GPU update."); GMX_RELEASE_ASSERT(graph == nullptr, "The graph is not supported with GPU update."); if (constr != nullptr && constr->numConstraintsTotal() > 0) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Updating coordinates and applying constraints on the GPU."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText("Updating coordinates and applying constraints on the GPU."); } else { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Updating coordinates on the GPU."); + GMX_LOG(mdlog.info).asParagraph().appendText("Updating coordinates on the GPU."); } - integrator = std::make_unique(*ir, *top_global, stateGpu->getUpdateStream(), stateGpu->xUpdatedOnDevice()); + integrator = std::make_unique( + *ir, *top_global, stateGpu->getUpdateStream(), stateGpu->xUpdatedOnDevice()); } if (useGpuForPme || (useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate) @@ -381,7 +385,7 @@ void gmx::LegacySimulator::do_md() { changePinningPolicy(&state->v, PinningPolicy::PinnedIfSupported); } -/*****************************************************************************************/ + /*****************************************************************************************/ // NOTE: The global state is no longer used at this point. // But state_global is still used as temporary storage space for writing @@ -395,43 +399,40 @@ void gmx::LegacySimulator::do_md() /* Check nstexpanded here, because the grompp check was broken */ if (ir->expandedvals->nstexpanded % ir->nstcalcenergy != 0) { - gmx_fatal(FARGS, "With expanded ensemble, nstexpanded should be a multiple of nstcalcenergy"); + gmx_fatal(FARGS, + "With expanded ensemble, nstexpanded should be a multiple of nstcalcenergy"); } - init_expanded_ensemble(startingBehavior != StartingBehavior::NewSimulation, - ir, state->dfhist); + init_expanded_ensemble(startingBehavior != StartingBehavior::NewSimulation, ir, state->dfhist); } if (MASTER(cr)) { - EnergyElement::initializeEnergyHistory( - startingBehavior, observablesHistory, &energyOutput); + EnergyElement::initializeEnergyHistory(startingBehavior, observablesHistory, &energyOutput); } preparePrevStepPullCom(ir, pull_work, mdatoms, state, state_global, cr, startingBehavior != StartingBehavior::NewSimulation); // TODO: Remove this by converting AWH into a ForceProvider - auto awh = prepareAwhModule(fplog, *ir, state_global, cr, ms, startingBehavior != StartingBehavior::NewSimulation, - shellfc != nullptr, - opt2fn("-awh", nfile, fnm), pull_work); + auto awh = prepareAwhModule(fplog, *ir, state_global, cr, ms, + startingBehavior != StartingBehavior::NewSimulation, + shellfc != nullptr, opt2fn("-awh", nfile, fnm), pull_work); const bool useReplicaExchange = (replExParams.exchangeInterval > 0); if (useReplicaExchange && MASTER(cr)) { - repl_ex = init_replica_exchange(fplog, ms, top_global->natoms, ir, - replExParams); + repl_ex = init_replica_exchange(fplog, ms, top_global->natoms, ir, replExParams); } /* PME tuning is only supported in the Verlet scheme, with PME for * Coulomb. It is not supported with only LJ PME. */ - bPMETune = (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && - !mdrunOptions.reproducible && ir->cutoff_scheme != ecutsGROUP); + bPMETune = (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && !mdrunOptions.reproducible + && ir->cutoff_scheme != ecutsGROUP); - pme_load_balancing_t *pme_loadbal = nullptr; + pme_load_balancing_t* pme_loadbal = nullptr; if (bPMETune) { - pme_loadbal_init(&pme_loadbal, cr, mdlog, *ir, state->box, - *fr->ic, *fr->nbv, fr->pmedata, fr->nbv->useGpu(), - &bPMETunePrinting); + pme_loadbal_init(&pme_loadbal, cr, mdlog, *ir, state->box, *fr->ic, *fr->nbv, fr->pmedata, + fr->nbv->useGpu(), &bPMETunePrinting); } if (!ir->bContinuation) @@ -442,8 +443,7 @@ void gmx::LegacySimulator::do_md() /* Set the velocities of vsites, shells and frozen atoms to zero */ for (i = 0; i < mdatoms->homenr; i++) { - if (mdatoms->ptype[i] == eptVSite || - mdatoms->ptype[i] == eptShell) + if (mdatoms->ptype[i] == eptVSite || mdatoms->ptype[i] == eptShell) { clear_rvec(v[i]); } @@ -463,18 +463,14 @@ void gmx::LegacySimulator::do_md() if (constr) { /* Constrain the initial coordinates and velocities */ - do_constrain_first(fplog, constr, ir, mdatoms, - state->natoms, - state->x.arrayRefWithPadding(), - state->v.arrayRefWithPadding(), - state->box, state->lambda[efptBONDED]); + do_constrain_first(fplog, constr, ir, mdatoms, state->natoms, state->x.arrayRefWithPadding(), + state->v.arrayRefWithPadding(), state->box, state->lambda[efptBONDED]); } if (vsite) { /* Construct the virtual sites for the initial configuration */ - construct_vsites(vsite, state->x.rvec_array(), ir->delta_t, nullptr, - top.idef.iparams, top.idef.il, - fr->ePBC, fr->bMolPBC, cr, state->box); + construct_vsites(vsite, state->x.rvec_array(), ir->delta_t, nullptr, top.idef.iparams, + top.idef.il, fr->ePBC, fr->bMolPBC, cr, state->box); } } @@ -519,10 +515,9 @@ void gmx::LegacySimulator::do_md() restore_ekinstate_from_state(cr, ekind, &state_global->ekinstate); } - unsigned int cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT - | (EI_VV(ir->eI) ? CGLO_PRESSURE : 0) - | (EI_VV(ir->eI) ? CGLO_CONSTRAINT : 0) - | (hasReadEkinState ? CGLO_READEKIN : 0)); + unsigned int cglo_flags = + (CGLO_TEMPERATURE | CGLO_GSTAT | (EI_VV(ir->eI) ? CGLO_PRESSURE : 0) + | (EI_VV(ir->eI) ? CGLO_CONSTRAINT : 0) | (hasReadEkinState ? CGLO_READEKIN : 0)); bSumEkinhOld = FALSE; @@ -542,19 +537,19 @@ void gmx::LegacySimulator::do_md() cglo_flags_iteration |= CGLO_STOPCM; cglo_flags_iteration &= ~CGLO_TEMPERATURE; } - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags_iteration - | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0)); + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, nullptr, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, + cglo_flags_iteration + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0)); if (cglo_flags_iteration & CGLO_STOPCM) { /* At initialization, do not pass x with acceleration-correction mode * to avoid (incorrect) correction of the initial coordinates. */ - rvec *xPtr = nullptr; + rvec* xPtr = nullptr; if (vcm.mode != ecmLINEAR_ACCELERATION_CORRECTION) { xPtr = state->x.rvec_array(); @@ -563,8 +558,8 @@ void gmx::LegacySimulator::do_md() inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr); } } - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top, + state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); if (ir->eI == eiVVAK) { @@ -574,13 +569,10 @@ void gmx::LegacySimulator::do_md() kinetic energy calculation. This minimized excess variables, but perhaps loses some logic?*/ - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, state->box, - nullptr, &bSumEkinhOld, - cglo_flags & ~CGLO_PRESSURE); + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, nullptr, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, + state->box, nullptr, &bSumEkinhOld, cglo_flags & ~CGLO_PRESSURE); } /* Calculate the initial half step temperature, and save the ekinh_old */ @@ -592,8 +584,8 @@ void gmx::LegacySimulator::do_md() } } - /* need to make an initiation call to get the Trotter variables set, as well as other constants for non-trotter - temperature control */ + /* need to make an initiation call to get the Trotter variables set, as well as other constants + for non-trotter temperature control */ auto trotter_seq = init_npt_vars(ir, state, &MassQ, bTrotter); if (MASTER(cr)) @@ -602,8 +594,7 @@ void gmx::LegacySimulator::do_md() { if (constr && ir->eConstrAlg == econtLINCS) { - fprintf(fplog, - "RMS relative constraint deviation after constraining: %.2e\n", + fprintf(fplog, "RMS relative constraint deviation after constraining: %.2e\n", constr->rmsd()); } if (EI_STATE_VELOCITY(ir->eI)) @@ -621,11 +612,10 @@ void gmx::LegacySimulator::do_md() } char tbuf[20]; - fprintf(stderr, "starting mdrun '%s'\n", - *(top_global->name)); + fprintf(stderr, "starting mdrun '%s'\n", *(top_global->name)); if (ir->nsteps >= 0) { - sprintf(tbuf, "%8.1f", (ir->init_step+ir->nsteps)*ir->delta_t); + sprintf(tbuf, "%8.1f", (ir->init_step + ir->nsteps) * ir->delta_t); } else { @@ -634,14 +624,12 @@ void gmx::LegacySimulator::do_md() if (ir->init_step > 0) { fprintf(stderr, "%s steps, %s ps (continuing from step %s, %8.1f ps).\n", - gmx_step_str(ir->init_step+ir->nsteps, sbuf), tbuf, - gmx_step_str(ir->init_step, sbuf2), - ir->init_step*ir->delta_t); + gmx_step_str(ir->init_step + ir->nsteps, sbuf), tbuf, + gmx_step_str(ir->init_step, sbuf2), ir->init_step * ir->delta_t); } else { - fprintf(stderr, "%s steps, %s ps.\n", - gmx_step_str(ir->nsteps, sbuf), tbuf); + fprintf(stderr, "%s steps, %s ps.\n", gmx_step_str(ir->nsteps, sbuf), tbuf); } fprintf(fplog, "\n"); } @@ -652,11 +640,10 @@ void gmx::LegacySimulator::do_md() #if GMX_FAHCORE /* safest point to do file checkpointing is here. More general point would be immediately before integrator call */ - int chkpt_ret = fcCheckPointParallel( cr->nodeid, - NULL, 0); + int chkpt_ret = fcCheckPointParallel(cr->nodeid, NULL, 0); if (chkpt_ret == 0) { - gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", 0 ); + gmx_fatal(3, __FILE__, __LINE__, "Checkpoint error on step %d\n", 0); } #endif @@ -666,7 +653,7 @@ void gmx::LegacySimulator::do_md() * ************************************************************/ - bFirstStep = TRUE; + bFirstStep = TRUE; /* Skip the first Nose-Hoover integration when we get the state from tpx */ bInitStep = startingBehavior == StartingBehavior::NewSimulation || EI_VV(ir->eI); bSumEkinhOld = FALSE; @@ -678,8 +665,9 @@ void gmx::LegacySimulator::do_md() { // TODO This implementation of ensemble orientation restraints is nasty because // a user can't just do multi-sim with single-sim orientation restraints. - bool usingEnsembleRestraints = (fcd->disres.nsystems > 1) || ((ms != nullptr) && (fcd->orires.nr != 0)); - bool awhUsesMultiSim = (ir->bDoAwh && ir->awhParams->shareBiasMultisim && (ms != nullptr)); + bool usingEnsembleRestraints = + (fcd->disres.nsystems > 1) || ((ms != nullptr) && (fcd->orires.nr != 0)); + bool awhUsesMultiSim = (ir->bDoAwh && ir->awhParams->shareBiasMultisim && (ms != nullptr)); // Replica exchange, ensemble restraints and AWH need all // simulations to remain synchronized, so they need @@ -694,25 +682,26 @@ void gmx::LegacySimulator::do_md() // Inter-simulation signal communication does not need to happen // often, so we use a minimum of 200 steps to reduce overhead. const int c_minimumInterSimulationSignallingInterval = 200; - nstSignalComm = ((c_minimumInterSimulationSignallingInterval + nstglobalcomm - 1)/nstglobalcomm)*nstglobalcomm; + nstSignalComm = ((c_minimumInterSimulationSignallingInterval + nstglobalcomm - 1) / nstglobalcomm) + * nstglobalcomm; } } auto stopHandler = stopHandlerBuilder->getStopHandlerMD( - compat::not_null(&signals[eglsSTOPCOND]), simulationsShareState, - MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstSignalComm, - mdrunOptions.maximumHoursToRun, ir->nstlist == 0, fplog, step, bNS, walltime_accounting); + compat::not_null(&signals[eglsSTOPCOND]), simulationsShareState, + MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstSignalComm, + mdrunOptions.maximumHoursToRun, ir->nstlist == 0, fplog, step, bNS, walltime_accounting); auto checkpointHandler = std::make_unique( - compat::make_not_null(&signals[eglsCHKPT]), - simulationsShareState, ir->nstlist == 0, MASTER(cr), - mdrunOptions.writeConfout, mdrunOptions.checkpointOptions.period); + compat::make_not_null(&signals[eglsCHKPT]), simulationsShareState, + ir->nstlist == 0, MASTER(cr), mdrunOptions.writeConfout, + mdrunOptions.checkpointOptions.period); const bool resetCountersIsLocal = true; auto resetHandler = std::make_unique( - compat::make_not_null(&signals[eglsRESETCOUNTERS]), !resetCountersIsLocal, - ir->nsteps, MASTER(cr), mdrunOptions.timingOptions.resetHalfway, - mdrunOptions.maximumHoursToRun, mdlog, wcycle, walltime_accounting); + compat::make_not_null(&signals[eglsRESETCOUNTERS]), + !resetCountersIsLocal, ir->nsteps, MASTER(cr), mdrunOptions.timingOptions.resetHalfway, + mdrunOptions.maximumHoursToRun, mdlog, wcycle, walltime_accounting); const DDBalanceRegionHandler ddBalanceRegionHandler(cr); @@ -724,15 +713,18 @@ void gmx::LegacySimulator::do_md() { if (!multisim_int_all_are_equal(ms, ir->nsteps)) { - GMX_LOG(mdlog.warning).appendText( - "Note: The number of steps is not consistent across multi simulations,\n" - "but we are proceeding anyway!"); + GMX_LOG(mdlog.warning) + .appendText( + "Note: The number of steps is not consistent across multi " + "simulations,\n" + "but we are proceeding anyway!"); } if (!multisim_int_all_are_equal(ms, ir->init_step)) { - GMX_LOG(mdlog.warning).appendText( - "Note: The initial step is not consistent across multi simulations,\n" - "but we are proceeding anyway!"); + GMX_LOG(mdlog.warning) + .appendText( + "Note: The initial step is not consistent across multi simulations,\n" + "but we are proceeding anyway!"); } } @@ -742,7 +734,7 @@ void gmx::LegacySimulator::do_md() { /* Determine if this is a neighbor search step */ - bNStList = (ir->nstlist > 0 && step % ir->nstlist == 0); + bNStList = (ir->nstlist > 0 && step % ir->nstlist == 0); if (bPMETune && bNStList) { @@ -754,19 +746,15 @@ void gmx::LegacySimulator::do_md() stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local); } /* PME grid + cut-off optimization with GPUs or PME nodes */ - pme_loadbal_do(pme_loadbal, cr, - (mdrunOptions.verbose && MASTER(cr)) ? stderr : nullptr, - fplog, mdlog, - *ir, fr, state->box, state->x, - wcycle, - step, step_rel, + pme_loadbal_do(pme_loadbal, cr, (mdrunOptions.verbose && MASTER(cr)) ? stderr : nullptr, + fplog, mdlog, *ir, fr, state->box, state->x, wcycle, step, step_rel, &bPMETunePrinting); } wallcycle_start(wcycle, ewcSTEP); bLastStep = (step_rel == ir->nsteps); - t = t0 + step*ir->delta_t; + t = t0 + step * ir->delta_t; // TODO Refactor this, so that nstfep does not need a default value of zero if (ir->efep != efepNO || ir->bSimTemp) @@ -774,15 +762,14 @@ void gmx::LegacySimulator::do_md() /* find and set the current lambdas */ setCurrentLambdasLocal(step, ir->fepvals, lam0, state->lambda, state->fep_state); - bDoDHDL = do_per_step(step, ir->fepvals->nstdhdl); - bDoFEP = ((ir->efep != efepNO) && do_per_step(step, nstfep)); - bDoExpanded = (do_per_step(step, ir->expandedvals->nstexpanded) - && (ir->bExpanded) && (step > 0) && - (startingBehavior == StartingBehavior::NewSimulation)); + bDoDHDL = do_per_step(step, ir->fepvals->nstdhdl); + bDoFEP = ((ir->efep != efepNO) && do_per_step(step, nstfep)); + bDoExpanded = (do_per_step(step, ir->expandedvals->nstexpanded) && (ir->bExpanded) + && (step > 0) && (startingBehavior == StartingBehavior::NewSimulation)); } - bDoReplEx = (useReplicaExchange && (step > 0) && !bLastStep && - do_per_step(step, replExParams.exchangeInterval)); + bDoReplEx = (useReplicaExchange && (step > 0) && !bLastStep + && do_per_step(step, replExParams.exchangeInterval)); if (doSimulatedAnnealing) { @@ -808,12 +795,10 @@ void gmx::LegacySimulator::do_md() * Note that the || bLastStep can result in non-exact continuation * beyond the last step. But we don't consider that to be an issue. */ - do_log = - (do_per_step(step, ir->nstlog) || - (bFirstStep && startingBehavior == StartingBehavior::NewSimulation) || - bLastStep); - do_verbose = mdrunOptions.verbose && - (step % mdrunOptions.verboseStepPrintInterval == 0 || bFirstStep || bLastStep); + do_log = (do_per_step(step, ir->nstlog) + || (bFirstStep && startingBehavior == StartingBehavior::NewSimulation) || bLastStep); + do_verbose = mdrunOptions.verbose + && (step % mdrunOptions.verboseStepPrintInterval == 0 || bFirstStep || bLastStep); if (useGpuForUpdate && !bFirstStep) { @@ -855,14 +840,9 @@ void gmx::LegacySimulator::do_md() if (DOMAINDECOMP(cr)) { /* Repartition the domain decomposition */ - dd_partition_system(fplog, mdlog, step, cr, - bMasterState, nstglobalcomm, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, - nrnb, wcycle, - do_verbose && !bPMETunePrinting); + dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global, + *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top, + fr, vsite, constr, nrnb, wcycle, do_verbose && !bPMETunePrinting); shouldCheckNumberOfBondedInteractions = true; upd.setNumAtoms(state->natoms); } @@ -884,15 +864,13 @@ void gmx::LegacySimulator::do_md() /* We need the kinetic energy at minus the half step for determining * the full step kinetic energy and possibly for T-coupling.*/ /* This may not be quite working correctly yet . . . . */ - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot, - constr, &nullSignaller, state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, wcycle, enerd, + nullptr, nullptr, nullptr, nullptr, mu_tot, constr, &nullSignaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, CGLO_GSTAT | CGLO_TEMPERATURE | CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS); - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, + &top, state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); } clear_mat(force_vir); @@ -905,14 +883,14 @@ void gmx::LegacySimulator::do_md() if (EI_VV(ir->eI) && (!bInitStep)) { bCalcEnerStep = do_per_step(step, ir->nstcalcenergy); - bCalcVir = bCalcEnerStep || - (ir->epc != epcNO && (do_per_step(step, ir->nstpcouple) || do_per_step(step-1, ir->nstpcouple))); + bCalcVir = bCalcEnerStep + || (ir->epc != epcNO + && (do_per_step(step, ir->nstpcouple) || do_per_step(step - 1, ir->nstpcouple))); } else { bCalcEnerStep = do_per_step(step, ir->nstcalcenergy); - bCalcVir = bCalcEnerStep || - (ir->epc != epcNO && do_per_step(step, ir->nstpcouple)); + bCalcVir = bCalcEnerStep || (ir->epc != epcNO && do_per_step(step, ir->nstpcouple)); } bCalcEner = bCalcEnerStep; @@ -925,47 +903,33 @@ void gmx::LegacySimulator::do_md() } /* Do we need global communication ? */ - bGStat = (bCalcVir || bCalcEner || bStopCM || - do_per_step(step, nstglobalcomm) || - (EI_VV(ir->eI) && inputrecNvtTrotter(ir) && do_per_step(step-1, nstglobalcomm))); - - force_flags = (GMX_FORCE_STATECHANGED | - ((inputrecDynamicBox(ir)) ? GMX_FORCE_DYNAMICBOX : 0) | - GMX_FORCE_ALLFORCES | - (bCalcVir ? GMX_FORCE_VIRIAL : 0) | - (bCalcEner ? GMX_FORCE_ENERGY : 0) | - (bDoFEP ? GMX_FORCE_DHDL : 0) - ); + bGStat = (bCalcVir || bCalcEner || bStopCM || do_per_step(step, nstglobalcomm) + || (EI_VV(ir->eI) && inputrecNvtTrotter(ir) && do_per_step(step - 1, nstglobalcomm))); + + force_flags = (GMX_FORCE_STATECHANGED | ((inputrecDynamicBox(ir)) ? GMX_FORCE_DYNAMICBOX : 0) + | GMX_FORCE_ALLFORCES | (bCalcVir ? GMX_FORCE_VIRIAL : 0) + | (bCalcEner ? GMX_FORCE_ENERGY : 0) | (bDoFEP ? GMX_FORCE_DHDL : 0)); if (shellfc) { /* Now is the time to relax the shells */ - relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, - enforcedRotation, step, - ir, imdSession, pull_work, bNS, force_flags, &top, - constr, enerd, fcd, - state->natoms, - state->x.arrayRefWithPadding(), - state->v.arrayRefWithPadding(), - state->box, - state->lambda, - &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, - nrnb, wcycle, graph, - shellfc, fr, runScheduleWork, t, mu_tot, - vsite, - ddBalanceRegionHandler); + relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir, + imdSession, pull_work, bNS, force_flags, &top, constr, enerd, fcd, + state->natoms, state->x.arrayRefWithPadding(), + state->v.arrayRefWithPadding(), state->box, state->lambda, &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, nrnb, wcycle, graph, + shellfc, fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler); } else { - /* The AWH history need to be saved _before_ doing force calculations where the AWH bias is updated - (or the AWH update will be performed twice for one step when continuing). It would be best to - call this update function from do_md_trajectory_writing but that would occur after do_force. - One would have to divide the update_awh function into one function applying the AWH force - and one doing the AWH bias update. The update AWH bias function could then be called after - do_md_trajectory_writing (then containing update_awh_history). - The checkpointing will in the future probably moved to the start of the md loop which will - rid of this issue. */ + /* The AWH history need to be saved _before_ doing force calculations where the AWH bias + is updated (or the AWH update will be performed twice for one step when continuing). + It would be best to call this update function from do_md_trajectory_writing but that + would occur after do_force. One would have to divide the update_awh function into one + function applying the AWH force and one doing the AWH bias update. The update AWH + bias function could then be called after do_md_trajectory_writing (then containing + update_awh_history). The checkpointing will in the future probably moved to the start + of the md loop which will rid of this issue. */ if (awh && checkpointHandler->isCheckpointingStep() && MASTER(cr)) { awh->updateHistory(state_global->awhHistory.get()); @@ -976,15 +940,11 @@ void gmx::LegacySimulator::do_md() * This is parallellized as well, and does communication too. * Check comments in sim_util.c */ - do_force(fplog, cr, ms, ir, awh.get(), enforcedRotation, imdSession, - pull_work, - step, nrnb, wcycle, &top, - state->box, state->x.arrayRefWithPadding(), &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, - state->lambda, graph, + do_force(fplog, cr, ms, ir, awh.get(), enforcedRotation, imdSession, pull_work, step, + nrnb, wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, state->lambda, graph, fr, runScheduleWork, vsite, mu_tot, t, ed ? ed->getLegacyED() : nullptr, - (bNS ? GMX_FORCE_NS : 0) | force_flags, - ddBalanceRegionHandler); + (bNS ? GMX_FORCE_NS : 0) | force_flags, ddBalanceRegionHandler); } // VV integrators do not need the following velocity half step @@ -994,7 +954,7 @@ void gmx::LegacySimulator::do_md() if (EI_VV(ir->eI) && (!bFirstStep || startingBehavior == StartingBehavior::NewSimulation)) /* ############### START FIRST UPDATE HALF-STEP FOR VV METHODS############### */ { - rvec *vbuf = nullptr; + rvec* vbuf = nullptr; wallcycle_start(wcycle, ewcUPDATE); if (ir->eI == eiVV && bInitStep) @@ -1006,24 +966,21 @@ void gmx::LegacySimulator::do_md() * so that the input is actually the initial step. */ snew(vbuf, state->natoms); - copy_rvecn(state->v.rvec_array(), vbuf, 0, state->natoms); /* should make this better for parallelizing? */ + copy_rvecn(state->v.rvec_array(), vbuf, 0, + state->natoms); /* should make this better for parallelizing? */ } else { /* this is for NHC in the Ekin(t+dt/2) version of vv */ - trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, trotter_seq, ettTSEQ1); + trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, + trotter_seq, ettTSEQ1); } - update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, - ekind, M, &upd, etrtVELOCITY1, - cr, constr); + update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, ekind, M, &upd, + etrtVELOCITY1, cr, constr); wallcycle_stop(wcycle, ewcUPDATE); - constrain_velocities(step, nullptr, - state, - shake_vir, - constr, - bCalcVir, do_log, do_ene); + constrain_velocities(step, nullptr, state, shake_vir, constr, bCalcVir, do_log, do_ene); wallcycle_start(wcycle, ewcUPDATE); /* if VV, compute the pressure and constraints */ /* For VV2, we strictly only need this if using pressure @@ -1042,24 +999,19 @@ void gmx::LegacySimulator::do_md() } /* for vv, the first half of the integration actually corresponds to the previous step. So we need information from the last step in the first half of the integration */ - if (bGStat || do_per_step(step-1, nstglobalcomm)) + if (bGStat || do_per_step(step - 1, nstglobalcomm)) { wallcycle_stop(wcycle, ewcUPDATE); - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, - (bGStat ? CGLO_GSTAT : 0) - | (bCalcEner ? CGLO_ENERGY : 0) - | (bTemp ? CGLO_TEMPERATURE : 0) - | (bPres ? CGLO_PRESSURE : 0) - | (bPres ? CGLO_CONSTRAINT : 0) - | (bStopCM ? CGLO_STOPCM : 0) - | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - | CGLO_SCALEEKIN - ); + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, wcycle, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, + (bGStat ? CGLO_GSTAT : 0) | (bCalcEner ? CGLO_ENERGY : 0) + | (bTemp ? CGLO_TEMPERATURE : 0) | (bPres ? CGLO_PRESSURE : 0) + | (bPres ? CGLO_CONSTRAINT : 0) | (bStopCM ? CGLO_STOPCM : 0) + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0) + | CGLO_SCALEEKIN); /* explanation of above: a) We compute Ekin at the full time step if 1) we are using the AveVel Ekin, and it's not the @@ -1072,7 +1024,8 @@ void gmx::LegacySimulator::do_md() &shouldCheckNumberOfBondedInteractions); if (bStopCM) { - process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), state->v.rvec_array()); + process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), + state->v.rvec_array()); inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr); } wallcycle_start(wcycle, ewcUPDATE); @@ -1082,8 +1035,10 @@ void gmx::LegacySimulator::do_md() { if (bTrotter) { - m_add(force_vir, shake_vir, total_vir); /* we need the un-dispersion corrected total vir here */ - trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, trotter_seq, ettTSEQ2); + m_add(force_vir, shake_vir, + total_vir); /* we need the un-dispersion corrected total vir here */ + trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, + trotter_seq, ettTSEQ2); /* TODO This is only needed when we're about to write * a checkpoint, because we use it after the restart @@ -1097,7 +1052,8 @@ void gmx::LegacySimulator::do_md() if (inputrecNvtTrotter(ir) && ir->eI == eiVV) { /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */ - enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, nullptr, (ir->eI == eiVV), FALSE); + enerd->term[F_TEMP] = + sum_ekin(&(ir->opts), ekind, nullptr, (ir->eI == eiVV), FALSE); enerd->term[F_EKIN] = trace(ekind->ekin); } } @@ -1107,13 +1063,11 @@ void gmx::LegacySimulator::do_md() /* We need the kinetic energy at minus the half step for determining * the full step kinetic energy and possibly for T-coupling.*/ /* This may not be quite working correctly yet . . . . */ - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot, - constr, &nullSignaller, state->box, - nullptr, &bSumEkinhOld, - CGLO_GSTAT | CGLO_TEMPERATURE); + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), + state->v.rvec_array(), state->box, state->lambda[efptVDW], + mdatoms, nrnb, &vcm, wcycle, enerd, nullptr, nullptr, nullptr, + nullptr, mu_tot, constr, &nullSignaller, state->box, nullptr, + &bSumEkinhOld, CGLO_GSTAT | CGLO_TEMPERATURE); wallcycle_start(wcycle, ewcUPDATE); } } @@ -1154,7 +1108,8 @@ void gmx::LegacySimulator::do_md() statistics, but if performing simulated tempering, we do update the velocities and the tau_t. */ - lamnew = ExpandedEnsembleDynamics(fplog, ir, enerd, state, &MassQ, state->fep_state, state->dfhist, step, state->v.rvec_array(), mdatoms); + lamnew = ExpandedEnsembleDynamics(fplog, ir, enerd, state, &MassQ, state->fep_state, + state->dfhist, step, state->v.rvec_array(), mdatoms); /* history is maintained in state->dfhist, but state_global is what is sent to trajectory and log output */ if (MASTER(cr)) { @@ -1164,8 +1119,8 @@ void gmx::LegacySimulator::do_md() // Copy coordinate from the GPU for the output if the update is offloaded and // coordinates have not already been copied for i) search or ii) CPU force tasks. - if (useGpuForUpdate && !bNS && !runScheduleWork->domainWork.haveCpuLocalForceWork && - (do_per_step(step, ir->nstxout) || do_per_step(step, ir->nstxout_compressed))) + if (useGpuForUpdate && !bNS && !runScheduleWork->domainWork.haveCpuLocalForceWork + && (do_per_step(step, ir->nstxout) || do_per_step(step, ir->nstxout_compressed))) { stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local); stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local); @@ -1181,7 +1136,8 @@ void gmx::LegacySimulator::do_md() // copy call in do_force(...). // NOTE: The forces should not be copied here if the vsites are present, since they were modified // on host after the D2H copy in do_force(...). - if (runScheduleWork->stepWork.useGpuFBufferOps && (simulationWork.useGpuUpdate && !vsite) && do_per_step(step, ir->nstfout)) + if (runScheduleWork->stepWork.useGpuFBufferOps && (simulationWork.useGpuUpdate && !vsite) + && do_per_step(step, ir->nstfout)) { stateGpu->copyForcesFromGpu(ArrayRef(f), AtomLocality::Local); stateGpu->waitForcesReadyOnHost(AtomLocality::Local); @@ -1190,20 +1146,16 @@ void gmx::LegacySimulator::do_md() * coordinates at time t. We must output all of this before * the update. */ - do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, - ir, state, state_global, observablesHistory, - top_global, fr, - outf, energyOutput, ekind, f, - checkpointHandler->isCheckpointingStep(), - bRerunMD, bLastStep, - mdrunOptions.writeConfout, - bSumEkinhOld); + do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state, state_global, + observablesHistory, top_global, fr, outf, energyOutput, ekind, f, + checkpointHandler->isCheckpointingStep(), bRerunMD, bLastStep, + mdrunOptions.writeConfout, bSumEkinhOld); /* Check if IMD step and do IMD communication, if bIMD is TRUE. */ bInteractiveMDstep = imdSession->run(step, bNS, state->box, state->x.rvec_array(), t); /* kludge -- virial is lost with restart for MTTK NPT control. Must reload (saved earlier). */ - if (startingBehavior != StartingBehavior::NewSimulation && - (inputrecNptTrotter(ir) || inputrecNphTrotter(ir))) + if (startingBehavior != StartingBehavior::NewSimulation + && (inputrecNptTrotter(ir) || inputrecNphTrotter(ir))) { copy_mat(state->svir_prev, shake_vir); copy_mat(state->fvir_prev, force_vir); @@ -1223,8 +1175,8 @@ void gmx::LegacySimulator::do_md() /* ######### START SECOND UPDATE STEP ################# */ - /* at the start of step, randomize or scale the velocities ((if vv. Restriction of Andersen controlled - in preprocessing */ + /* at the start of step, randomize or scale the velocities ((if vv. Restriction of Andersen + controlled in preprocessing */ if (ETC_ANDERSEN(ir->etc)) /* keep this outside of update_tcouple because of the extra info required to pass */ { @@ -1233,11 +1185,7 @@ void gmx::LegacySimulator::do_md() /* if we have constraints, we have to remove the kinetic energy parallel to the bonds */ if (constr && bIfRandomize) { - constrain_velocities(step, nullptr, - state, - tmp_vir, - constr, - bCalcVir, do_log, do_ene); + constrain_velocities(step, nullptr, state, tmp_vir, constr, bCalcVir, do_log, do_ene); } } /* Box is changed in update() when we do pressure coupling, @@ -1263,17 +1211,14 @@ void gmx::LegacySimulator::do_md() else { update_tcouple(step, ir, state, ekind, &MassQ, mdatoms); - update_pcouple_before_coordinates(fplog, step, ir, state, - parrinellorahmanMu, M, - bInitStep); + update_pcouple_before_coordinates(fplog, step, ir, state, parrinellorahmanMu, M, bInitStep); } if (EI_VV(ir->eI)) { /* velocity half-step update */ - update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, - ekind, M, &upd, etrtVELOCITY2, - cr, constr); + update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, ekind, M, &upd, + etrtVELOCITY2, cr, constr); } /* Above, initialize just copies ekinh into ekin, @@ -1292,14 +1237,14 @@ void gmx::LegacySimulator::do_md() * energies of two subsequent steps. Therefore we need to compute the * half step kinetic energy also if we need energies at the next step. */ - const bool needHalfStepKineticEnergy = (!EI_VV(ir->eI) && do_per_step(step+1, nstglobalcomm)); + const bool needHalfStepKineticEnergy = (!EI_VV(ir->eI) && do_per_step(step + 1, nstglobalcomm)); if (useGpuForUpdate) { if (bNS) { - integrator->set(stateGpu->getCoordinates(), stateGpu->getVelocities(), stateGpu->getForces(), - top.idef, *mdatoms, ekind->ngtc); + integrator->set(stateGpu->getCoordinates(), stateGpu->getVelocities(), + stateGpu->getForces(), top.idef, *mdatoms, ekind->ngtc); t_pbc pbc; set_pbc(&pbc, epbcXYZ, state->box); integrator->setPbc(&pbc); @@ -1315,14 +1260,16 @@ void gmx::LegacySimulator::do_md() stateGpu->copyForcesToGpu(ArrayRef(f), AtomLocality::Local); } - bool doTempCouple = (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple)); - bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple)); + bool doTempCouple = + (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple)); + bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN + && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple)); // This applies Leap-Frog, LINCS and SETTLE in succession - integrator->integrate(stateGpu->getForcesReadyOnDeviceEvent(AtomLocality::Local, runScheduleWork->stepWork.useGpuFBufferOps), - ir->delta_t, true, bCalcVir, shake_vir, - doTempCouple, ekind->tcstat, - doParrinelloRahman, ir->nstpcouple*ir->delta_t, M); + integrator->integrate(stateGpu->getForcesReadyOnDeviceEvent( + AtomLocality::Local, runScheduleWork->stepWork.useGpuFBufferOps), + ir->delta_t, true, bCalcVir, shake_vir, doTempCouple, + ekind->tcstat, doParrinelloRahman, ir->nstpcouple * ir->delta_t, M); // Copy velocities D2H after update if: // - Globals are computed this step (includes the energy output steps). @@ -1335,21 +1282,17 @@ void gmx::LegacySimulator::do_md() } else { - update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, - ekind, M, &upd, etrtPOSITION, cr, constr); + update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, ekind, M, &upd, + etrtPOSITION, cr, constr); wallcycle_stop(wcycle, ewcUPDATE); - constrain_coordinates(step, &dvdl_constr, state, - shake_vir, - &upd, constr, - bCalcVir, do_log, do_ene); + constrain_coordinates(step, &dvdl_constr, state, shake_vir, &upd, constr, bCalcVir, + do_log, do_ene); - update_sd_second_half(step, &dvdl_constr, ir, mdatoms, state, - cr, nrnb, wcycle, &upd, constr, do_log, do_ene); - finish_update(ir, mdatoms, - state, graph, - nrnb, wcycle, &upd, constr); + update_sd_second_half(step, &dvdl_constr, ir, mdatoms, state, cr, nrnb, wcycle, &upd, + constr, do_log, do_ene); + finish_update(ir, mdatoms, state, graph, nrnb, wcycle, &upd, constr); } if (ir->bPull && ir->pull->bSetPbcRefToPrevStepCOM) @@ -1361,21 +1304,17 @@ void gmx::LegacySimulator::do_md() { /* erase F_EKIN and F_TEMP here? */ /* just compute the kinetic energy at the half step to perform a trotter step */ - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, lastbox, - nullptr, &bSumEkinhOld, - (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE - ); + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, wcycle, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, lastbox, + nullptr, &bSumEkinhOld, (bGStat ? CGLO_GSTAT : 0) | CGLO_TEMPERATURE); wallcycle_start(wcycle, ewcUPDATE); trotter_update(ir, step, ekind, enerd, state, total_vir, mdatoms, &MassQ, trotter_seq, ettTSEQ4); /* now we know the scaling, we can compute the positions again */ std::copy(cbuf.begin(), cbuf.end(), state->x.begin()); - update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, - ekind, M, &upd, etrtPOSITION, cr, constr); + update_coords(step, ir, mdatoms, state, f.arrayRefWithPadding(), fcd, ekind, M, &upd, + etrtPOSITION, cr, constr); wallcycle_stop(wcycle, ewcUPDATE); /* do we need an extra constraint here? just need to copy out of as_rvec_array(state->v.data()) to upd->xp? */ @@ -1383,9 +1322,7 @@ void gmx::LegacySimulator::do_md() * to numerical errors, or are they important * physically? I'm thinking they are just errors, but not completely sure. * For now, will call without actually constraining, constr=NULL*/ - finish_update(ir, mdatoms, - state, graph, - nrnb, wcycle, &upd, nullptr); + finish_update(ir, mdatoms, state, graph, nrnb, wcycle, &upd, nullptr); } if (EI_VV(ir->eI)) { @@ -1403,7 +1340,7 @@ void gmx::LegacySimulator::do_md() this current solution is much better than having it completely wrong. */ - enerd->term[F_DVDL_CONSTR] += 2*dvdl_constr; + enerd->term[F_DVDL_CONSTR] += 2 * dvdl_constr; } else { @@ -1418,8 +1355,7 @@ void gmx::LegacySimulator::do_md() shift_self(graph, state->box, state->x.rvec_array()); } construct_vsites(vsite, state->x.rvec_array(), ir->delta_t, state->v.rvec_array(), - top.idef.iparams, top.idef.il, - fr->ePBC, fr->bMolPBC, cr, state->box); + top.idef.iparams, top.idef.il, fr->ePBC, fr->bMolPBC, cr, state->box); if (graph != nullptr) { @@ -1442,8 +1378,7 @@ void gmx::LegacySimulator::do_md() // kinetic energy at the step before we need to write // the full-step kinetic energy const bool needEkinAtNextStep = - (!EI_VV(ir->eI) && (do_per_step(step + 1, nstglobalcomm) || - step_rel + 1 == ir->nsteps)); + (!EI_VV(ir->eI) && (do_per_step(step + 1, nstglobalcomm) || step_rel + 1 == ir->nsteps)); if (bGStat || needEkinAtNextStep || doInterSimSignal) { @@ -1463,27 +1398,24 @@ void gmx::LegacySimulator::do_md() bool doIntraSimSignal = true; SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal); - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, &vcm, - wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &signaller, - lastbox, - &totalNumberOfBondedInteractions, &bSumEkinhOld, - (bGStat ? CGLO_GSTAT : 0) - | (!EI_VV(ir->eI) && bCalcEner ? CGLO_ENERGY : 0) + compute_globals( + gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, &vcm, wcycle, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &signaller, lastbox, + &totalNumberOfBondedInteractions, &bSumEkinhOld, + (bGStat ? CGLO_GSTAT : 0) | (!EI_VV(ir->eI) && bCalcEner ? CGLO_ENERGY : 0) | (!EI_VV(ir->eI) && bStopCM ? CGLO_STOPCM : 0) | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0) - | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) - | CGLO_CONSTRAINT - | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - ); + | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) | CGLO_CONSTRAINT + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0)); checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top, state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); if (!EI_VV(ir->eI) && bStopCM) { - process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), state->v.rvec_array()); + process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), + state->v.rvec_array()); inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr); // TODO: The special case of removing CM motion should be dealt more gracefully @@ -1510,10 +1442,8 @@ void gmx::LegacySimulator::do_md() sum_dhdl(enerd, state->lambda, *ir->fepvals); } - update_pcouple_after_coordinates(fplog, step, ir, mdatoms, - pres, force_vir, shake_vir, - parrinellorahmanMu, - state, nrnb, &upd); + update_pcouple_after_coordinates(fplog, step, ir, mdatoms, pres, force_vir, shake_vir, + parrinellorahmanMu, state, nrnb, &upd); /* ################# END UPDATE STEP 2 ################# */ /* #### We now have r(t+dt) and v(t+dt/2) ############# */ @@ -1558,24 +1488,23 @@ void gmx::LegacySimulator::do_md() if (fplog && do_log && bDoExpanded) { /* only needed if doing expanded ensemble */ - PrintFreeEnergyInfoToFile(fplog, ir->fepvals, ir->expandedvals, ir->bSimTemp ? ir->simtempvals : nullptr, + PrintFreeEnergyInfoToFile(fplog, ir->fepvals, ir->expandedvals, + ir->bSimTemp ? ir->simtempvals : nullptr, state_global->dfhist, state->fep_state, ir->nstlog, step); } if (bCalcEner) { - energyOutput.addDataAtEnergyStep(bDoDHDL, bCalcEnerStep, - t, mdatoms->tmass, enerd, state, - ir->fepvals, ir->expandedvals, lastbox, - shake_vir, force_vir, total_vir, pres, - ekind, mu_tot, constr); + energyOutput.addDataAtEnergyStep(bDoDHDL, bCalcEnerStep, t, mdatoms->tmass, enerd, state, + ir->fepvals, ir->expandedvals, lastbox, shake_vir, + force_vir, total_vir, pres, ekind, mu_tot, constr); } else { energyOutput.recordNonEnergyStep(); } - gmx_bool do_dr = do_per_step(step, ir->nstdisreout); - gmx_bool do_or = do_per_step(step, ir->nstorireout); + gmx_bool do_dr = do_per_step(step, ir->nstdisreout); + gmx_bool do_or = do_per_step(step, ir->nstorireout); if (doSimulatedAnnealing) { @@ -1584,9 +1513,7 @@ void gmx::LegacySimulator::do_md() if (do_log || do_ene || do_dr || do_or) { energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, - do_log ? fplog : nullptr, - step, t, - fcd, awh.get()); + do_log ? fplog : nullptr, step, t, fcd, awh.get()); } if (ir->bPull) @@ -1609,9 +1536,7 @@ void gmx::LegacySimulator::do_md() state->fep_state = lamnew; } /* Print the remaining wall clock time for the run */ - if (isMasterSimMasterRank(ms, MASTER(cr)) && - (do_verbose || gmx_got_usr_signal()) && - !bPMETunePrinting) + if (isMasterSimMasterRank(ms, MASTER(cr)) && (do_verbose || gmx_got_usr_signal()) && !bPMETunePrinting) { if (shellfc) { @@ -1624,14 +1549,11 @@ void gmx::LegacySimulator::do_md() * Not done in last step since trajectory writing happens before this call * in the MD loop and exchanges would be lost anyway. */ bNeedRepartition = FALSE; - if ((ir->eSwapCoords != eswapNO) && (step > 0) && !bLastStep && - do_per_step(step, ir->swap->nstswap)) + if ((ir->eSwapCoords != eswapNO) && (step > 0) && !bLastStep && do_per_step(step, ir->swap->nstswap)) { - bNeedRepartition = do_swapcoords(cr, step, t, ir, swap, wcycle, - as_rvec_array(state->x.data()), - state->box, - MASTER(cr) && mdrunOptions.verbose, - bRerunMD); + bNeedRepartition = + do_swapcoords(cr, step, t, ir, swap, wcycle, as_rvec_array(state->x.data()), + state->box, MASTER(cr) && mdrunOptions.verbose, bRerunMD); if (bNeedRepartition && DOMAINDECOMP(cr)) { @@ -1643,33 +1565,27 @@ void gmx::LegacySimulator::do_md() bExchanged = FALSE; if (bDoReplEx) { - bExchanged = replica_exchange(fplog, cr, ms, repl_ex, - state_global, enerd, - state, step, t); + bExchanged = replica_exchange(fplog, cr, ms, repl_ex, state_global, enerd, state, step, t); } - if ( (bExchanged || bNeedRepartition) && DOMAINDECOMP(cr) ) + if ((bExchanged || bNeedRepartition) && DOMAINDECOMP(cr)) { - dd_partition_system(fplog, mdlog, step, cr, TRUE, 1, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, + dd_partition_system(fplog, mdlog, step, cr, TRUE, 1, state_global, *top_global, ir, + imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr, nrnb, wcycle, FALSE); shouldCheckNumberOfBondedInteractions = true; upd.setNumAtoms(state->natoms); } - bFirstStep = FALSE; - bInitStep = FALSE; + bFirstStep = FALSE; + bInitStep = FALSE; /* ####### SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */ /* With all integrators, except VV, we need to retain the pressure * at the current step for coupling at the next step. */ - if ((state->flags & (1U<nstpcouple > 0 && step % ir->nstpcouple == 0))) + if ((state->flags & (1U << estPRES_PREV)) + && (bGStatEveryStep || (ir->nstpcouple > 0 && step % ir->nstpcouple == 0))) { /* Store the pressure in t_state for pressure coupling * at the next MD step. @@ -1679,7 +1595,7 @@ void gmx::LegacySimulator::do_md() /* ####### END SET VARIABLES FOR NEXT ITERATION ###### */ - if ( (membed != nullptr) && (!bLastStep) ) + if ((membed != nullptr) && (!bLastStep)) { rescale_membed(step_rel, membed, as_rvec_array(state_global->x.data())); } @@ -1694,13 +1610,11 @@ void gmx::LegacySimulator::do_md() step++; step_rel++; - resetHandler->resetCounters( - step, step_rel, mdlog, fplog, cr, fr->nbv.get(), - nrnb, fr->pmedata, pme_loadbal, wcycle, walltime_accounting); + resetHandler->resetCounters(step, step_rel, mdlog, fplog, cr, fr->nbv.get(), nrnb, + fr->pmedata, pme_loadbal, wcycle, walltime_accounting); /* If bIMD is TRUE, the master updates the IMD energy record and sends positions to VMD client */ imdSession->updateEnergyRecordAndSendPositionsAndEnergies(bInteractiveMDstep, step, bCalcEner); - } /* End of main MD loop */ @@ -1748,5 +1662,4 @@ void gmx::LegacySimulator::do_md() } global_stat_destroy(gstat); - } diff --git a/src/gromacs/mdrun/mdmodules.cpp b/src/gromacs/mdrun/mdmodules.cpp index 727fb5c26f..19dfd2869a 100644 --- a/src/gromacs/mdrun/mdmodules.cpp +++ b/src/gromacs/mdrun/mdmodules.cpp @@ -61,86 +61,79 @@ namespace gmx class MDModules::Impl : public IMDOutputProvider { - public: - - Impl() - : densityFitting_(DensityFittingModuleInfo::create(¬ifier_)), - field_(createElectricFieldModule()), - imd_(createInteractiveMolecularDynamicsModule()), - swapCoordinates_(createSwapCoordinatesModule()) - { - } - - void makeModuleOptions(Options *options) - { - // Create a section for applied-forces modules - auto appliedForcesOptions = options->addSection(OptionSection("applied-forces")); - field_->mdpOptionProvider()->initMdpOptions(&appliedForcesOptions); - densityFitting_->mdpOptionProvider()->initMdpOptions(&appliedForcesOptions); - // In future, other sections would also go here. - } - - // From IMDOutputProvider - void initOutput(FILE *fplog, int nfile, const t_filenm fnm[], - bool bAppendFiles, const gmx_output_env_t *oenv) override - { - field_->outputProvider()->initOutput(fplog, nfile, fnm, bAppendFiles, oenv); - densityFitting_->outputProvider()->initOutput(fplog, nfile, fnm, bAppendFiles, oenv); - } - void finishOutput() override - { - field_->outputProvider()->finishOutput(); - densityFitting_->outputProvider()->finishOutput(); - } - - /*! \brief Manages callbacks and notifies the MD modules. - * - * \note The notifier must be constructed before the modules and shall - * not be destructed before the modules are destructed. - */ - MdModulesNotifier notifier_; - - std::unique_ptr densityFitting_; - std::unique_ptr field_; - std::unique_ptr forceProviders_; - std::unique_ptr imd_; - std::unique_ptr swapCoordinates_; - - /*! \brief List of registered MDModules - * - * Note that MDModules::Impl owns this container, but it is only used by - * the MDModules::initForceProviders() function. To be consistent with - * IMDModule's vision, as indicated by its docs, we should - * \todo update IMDModule docs to allow nullptr return values - * \todo check for nullptr returned by IMDModule methods. - * \todo include field_ in modules_ - */ - std::vector< std::shared_ptr > modules_; +public: + Impl() : + densityFitting_(DensityFittingModuleInfo::create(¬ifier_)), + field_(createElectricFieldModule()), + imd_(createInteractiveMolecularDynamicsModule()), + swapCoordinates_(createSwapCoordinatesModule()) + { + } + + void makeModuleOptions(Options* options) + { + // Create a section for applied-forces modules + auto appliedForcesOptions = options->addSection(OptionSection("applied-forces")); + field_->mdpOptionProvider()->initMdpOptions(&appliedForcesOptions); + densityFitting_->mdpOptionProvider()->initMdpOptions(&appliedForcesOptions); + // In future, other sections would also go here. + } + + // From IMDOutputProvider + void initOutput(FILE* fplog, int nfile, const t_filenm fnm[], bool bAppendFiles, const gmx_output_env_t* oenv) override + { + field_->outputProvider()->initOutput(fplog, nfile, fnm, bAppendFiles, oenv); + densityFitting_->outputProvider()->initOutput(fplog, nfile, fnm, bAppendFiles, oenv); + } + void finishOutput() override + { + field_->outputProvider()->finishOutput(); + densityFitting_->outputProvider()->finishOutput(); + } + + /*! \brief Manages callbacks and notifies the MD modules. + * + * \note The notifier must be constructed before the modules and shall + * not be destructed before the modules are destructed. + */ + MdModulesNotifier notifier_; + + std::unique_ptr densityFitting_; + std::unique_ptr field_; + std::unique_ptr forceProviders_; + std::unique_ptr imd_; + std::unique_ptr swapCoordinates_; + + /*! \brief List of registered MDModules + * + * Note that MDModules::Impl owns this container, but it is only used by + * the MDModules::initForceProviders() function. To be consistent with + * IMDModule's vision, as indicated by its docs, we should + * \todo update IMDModule docs to allow nullptr return values + * \todo check for nullptr returned by IMDModule methods. + * \todo include field_ in modules_ + */ + std::vector> modules_; }; -MDModules::MDModules() : impl_(new Impl) -{ -} +MDModules::MDModules() : impl_(new Impl) {} -MDModules::~MDModules() -{ -} +MDModules::~MDModules() {} -void MDModules::initMdpTransform(IKeyValueTreeTransformRules *rules) +void MDModules::initMdpTransform(IKeyValueTreeTransformRules* rules) { auto appliedForcesScope = rules->scopedTransform("/applied-forces"); impl_->field_->mdpOptionProvider()->initMdpTransform(appliedForcesScope.rules()); impl_->densityFitting_->mdpOptionProvider()->initMdpTransform(appliedForcesScope.rules()); } -void MDModules::buildMdpOutput(KeyValueTreeObjectBuilder *builder) +void MDModules::buildMdpOutput(KeyValueTreeObjectBuilder* builder) { impl_->field_->mdpOptionProvider()->buildMdpOutput(builder); impl_->densityFitting_->mdpOptionProvider()->buildMdpOutput(builder); } -void MDModules::assignOptionsToModules(const KeyValueTreeObject ¶ms, - IKeyValueTreeErrorHandler *errorHandler) +void MDModules::assignOptionsToModules(const KeyValueTreeObject& params, IKeyValueTreeErrorHandler* errorHandler) { Options moduleOptions; impl_->makeModuleOptions(&moduleOptions); @@ -149,7 +142,7 @@ void MDModules::assignOptionsToModules(const KeyValueTreeObject ¶ms, assignOptionsFromKeyValueTree(&moduleOptions, params, errorHandler); } -void MDModules::adjustInputrecBasedOnModules(t_inputrec *ir) +void MDModules::adjustInputrecBasedOnModules(t_inputrec* ir) { Options moduleOptions; impl_->makeModuleOptions(&moduleOptions); @@ -157,25 +150,24 @@ void MDModules::adjustInputrecBasedOnModules(t_inputrec *ir) checkForUnknownOptionsInKeyValueTree(*ir->params, moduleOptions); std::unique_ptr params( - new KeyValueTreeObject( - adjustKeyValueTreeFromOptions(*ir->params, moduleOptions))); + new KeyValueTreeObject(adjustKeyValueTreeFromOptions(*ir->params, moduleOptions))); delete ir->params; ir->params = params.release(); } -IMDOutputProvider *MDModules::outputProvider() +IMDOutputProvider* MDModules::outputProvider() { return impl_.get(); } -ForceProviders *MDModules::initForceProviders() +ForceProviders* MDModules::initForceProviders() { GMX_RELEASE_ASSERT(impl_->forceProviders_ == nullptr, "Force providers initialized multiple times"); impl_->forceProviders_ = std::make_unique(); impl_->field_->initForceProviders(impl_->forceProviders_.get()); impl_->densityFitting_->initForceProviders(impl_->forceProviders_.get()); - for (auto && module : impl_->modules_) + for (auto&& module : impl_->modules_) { module->initForceProviders(impl_->forceProviders_.get()); } @@ -187,7 +179,7 @@ void MDModules::add(std::shared_ptr module) impl_->modules_.emplace_back(std::move(module)); } -const MdModulesNotifier &MDModules::notifier() +const MdModulesNotifier& MDModules::notifier() { return impl_->notifier_; } diff --git a/src/gromacs/mdrun/mdmodules.h b/src/gromacs/mdrun/mdmodules.h index 698f12ebd4..3f956431e5 100644 --- a/src/gromacs/mdrun/mdmodules.h +++ b/src/gromacs/mdrun/mdmodules.h @@ -91,92 +91,91 @@ struct MdModulesNotifier; */ class MDModules { - public: - MDModules(); - ~MDModules(); - - /*! \brief - * Initializes a transform from mdp values to sectioned options. - * - * \see IMdpOptionProvider::initMdpTransform() - * - * Initializes the combined transform from all modules. - */ - void initMdpTransform(IKeyValueTreeTransformRules *rules); - - /*! \brief Initializes a builder of flat mdp-style key-value pairs - * suitable for output. - * - * If used as input to initMdpTransform(), the key-value pairs - * resulting from this function would leave the module - * settings unchanged. - * - * Once the transition from mdp to key-value input is - * complete, this method will probably not exist. - */ - void buildMdpOutput(KeyValueTreeObjectBuilder *builder); - - /*! \brief - * Sets input parameters from `params` for each module. - * - * \param[in] params Contains keys and values from user - * input (and defaults) to configure modules that have - * registered options with those keys. - * \param[out] errorHandler Called to report errors. - */ - void assignOptionsToModules(const KeyValueTreeObject ¶ms, - IKeyValueTreeErrorHandler *errorHandler); - - /*! \brief - * Normalizes inputrec parameters to match current code version. - * - * This orders the parameters in `ir->param` to match the current code - * and adds any missing defaults. It also throws an error if the - * inputrec contains parameters that are not recognized by any module. - */ - void adjustInputrecBasedOnModules(t_inputrec *ir); - - /*! \brief - * Returns an interface for initializing and finalizing output for modules. - */ - IMDOutputProvider *outputProvider(); - /*! \brief - * Returns an object for computing forces from the modules. - */ - ForceProviders *initForceProviders(); - - /*! - * \brief Add a module to the container. - * - * An object may be added by a client to the bound MD Modules at run time. - * Both the client and the MDModules object may need to extend the life - * of the provided object. However, the MDModules container guarantees - * to extend the life of a provided object for as long as its consumers - * may attempt to use its the interfaces accessible through IMDModule - * methods. - * - * \param module implements some sort of modular functionality for MD. - * - * \note: There is not yet a way to add a IMDModule object between - * creation of the MDModules container and the execution of the various - * initialization protocols it supports. - * - * \internal - * Adding a module at an arbitrary point in the MDModules life breaks - * some assumptions in the protocol of the other member functions. If - * MDModules should not change after some point, we should move this - * to a builder class. - */ - void add(std::shared_ptr module); - - /*! \brief Return a handle to the callbacks. - */ - const MdModulesNotifier ¬ifier(); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + MDModules(); + ~MDModules(); + + /*! \brief + * Initializes a transform from mdp values to sectioned options. + * + * \see IMdpOptionProvider::initMdpTransform() + * + * Initializes the combined transform from all modules. + */ + void initMdpTransform(IKeyValueTreeTransformRules* rules); + + /*! \brief Initializes a builder of flat mdp-style key-value pairs + * suitable for output. + * + * If used as input to initMdpTransform(), the key-value pairs + * resulting from this function would leave the module + * settings unchanged. + * + * Once the transition from mdp to key-value input is + * complete, this method will probably not exist. + */ + void buildMdpOutput(KeyValueTreeObjectBuilder* builder); + + /*! \brief + * Sets input parameters from `params` for each module. + * + * \param[in] params Contains keys and values from user + * input (and defaults) to configure modules that have + * registered options with those keys. + * \param[out] errorHandler Called to report errors. + */ + void assignOptionsToModules(const KeyValueTreeObject& params, IKeyValueTreeErrorHandler* errorHandler); + + /*! \brief + * Normalizes inputrec parameters to match current code version. + * + * This orders the parameters in `ir->param` to match the current code + * and adds any missing defaults. It also throws an error if the + * inputrec contains parameters that are not recognized by any module. + */ + void adjustInputrecBasedOnModules(t_inputrec* ir); + + /*! \brief + * Returns an interface for initializing and finalizing output for modules. + */ + IMDOutputProvider* outputProvider(); + /*! \brief + * Returns an object for computing forces from the modules. + */ + ForceProviders* initForceProviders(); + + /*! + * \brief Add a module to the container. + * + * An object may be added by a client to the bound MD Modules at run time. + * Both the client and the MDModules object may need to extend the life + * of the provided object. However, the MDModules container guarantees + * to extend the life of a provided object for as long as its consumers + * may attempt to use its the interfaces accessible through IMDModule + * methods. + * + * \param module implements some sort of modular functionality for MD. + * + * \note: There is not yet a way to add a IMDModule object between + * creation of the MDModules container and the execution of the various + * initialization protocols it supports. + * + * \internal + * Adding a module at an arbitrary point in the MDModules life breaks + * some assumptions in the protocol of the other member functions. If + * MDModules should not change after some point, we should move this + * to a builder class. + */ + void add(std::shared_ptr module); + + /*! \brief Return a handle to the callbacks. + */ + const MdModulesNotifier& notifier(); + +private: + class Impl; + + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/mdrun/mimic.cpp b/src/gromacs/mdrun/mimic.cpp index 2b2f9e9ada..a86999fb3d 100644 --- a/src/gromacs/mdrun/mimic.cpp +++ b/src/gromacs/mdrun/mimic.cpp @@ -141,21 +141,21 @@ using gmx::SimulationSignaller; void gmx::LegacySimulator::do_mimic() { - t_inputrec *ir = inputrec; - int64_t step, step_rel; - double t, lam0[efptNR]; - bool isLastStep = false; - bool doFreeEnergyPerturbation = false; - unsigned int force_flags; - tensor force_vir, shake_vir, total_vir, pres; - rvec mu_tot; - gmx_localtop_t top; - PaddedHostVector f {}; - gmx_global_stat_t gstat; - t_graph *graph = nullptr; - gmx_shellfc_t *shellfc; - - double cycles; + t_inputrec* ir = inputrec; + int64_t step, step_rel; + double t, lam0[efptNR]; + bool isLastStep = false; + bool doFreeEnergyPerturbation = false; + unsigned int force_flags; + tensor force_vir, shake_vir, total_vir, pres; + rvec mu_tot; + gmx_localtop_t top; + PaddedHostVector f{}; + gmx_global_stat_t gstat; + t_graph* graph = nullptr; + gmx_shellfc_t* shellfc; + + double cycles; /* Domain decomposition could incorrectly miss a bonded interaction, but checking for that requires a global @@ -163,8 +163,8 @@ void gmx::LegacySimulator::do_mimic() code. So we do that alongside the first global energy reduction after a new DD is made. These variables handle whether the check happens, and the result it returns. */ - bool shouldCheckNumberOfBondedInteractions = false; - int totalNumberOfBondedInteractions = -1; + bool shouldCheckNumberOfBondedInteractions = false; + int totalNumberOfBondedInteractions = -1; SimulationSignals signals; // Most global communnication stages don't propagate mdrun @@ -200,19 +200,19 @@ void gmx::LegacySimulator::do_mimic() gmx_fatal(FARGS, "Multiple simulations not supported by MiMiC."); } if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, - [](int i){return i != eannNO; })) + [](int i) { return i != eannNO; })) { gmx_fatal(FARGS, "Simulated annealing not supported by MiMiC."); } /* Settings for rerun */ - ir->nstlist = 1; - ir->nstcalcenergy = 1; + ir->nstlist = 1; + ir->nstcalcenergy = 1; int nstglobalcomm = 1; const bool bNS = true; // Communicator to interact with MiMiC - MimicCommunicator mimicCommunicator {}; + MimicCommunicator mimicCommunicator{}; if (MASTER(cr)) { mimicCommunicator.init(); @@ -221,35 +221,33 @@ void gmx::LegacySimulator::do_mimic() } ir->nstxout_compressed = 0; - SimulationGroups *groups = &top_global->groups; + SimulationGroups* groups = &top_global->groups; top_global->intermolecularExclusionGroup = genQmmmIndices(*top_global); initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda, lam0); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, ir, top_global, oenv, wcycle, - StartingBehavior::NewSimulation); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, mdoutf_get_fp_dhdl(outf), true, mdModulesNotifier); + gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + ir, top_global, oenv, wcycle, StartingBehavior::NewSimulation); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, + mdoutf_get_fp_dhdl(outf), true, mdModulesNotifier); gstat = global_stat_init(ir); /* Check for polarizable models and flexible constraints */ - shellfc = init_shell_flexcon(fplog, - top_global, constr ? constr->numFlexibleConstraints() : 0, + shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0, ir->nstcalcenergy, DOMAINDECOMP(cr)); { double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1); if ((io > 2000) && MASTER(cr)) { - fprintf(stderr, - "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", - io); + fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io); } } // Local state only becomes valid now. std::unique_ptr stateInstance; - t_state * state; + t_state* state; if (DOMAINDECOMP(cr)) { @@ -260,11 +258,8 @@ void gmx::LegacySimulator::do_mimic() dd_init_local_state(cr->dd, state_global, state); /* Distribute the charge groups over the nodes from the master node */ - dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, + dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir, + imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr, nrnb, nullptr, FALSE); shouldCheckNumberOfBondedInteractions = true; gmx_bcast(sizeof(ir->nsteps), &ir->nsteps, cr); @@ -279,8 +274,7 @@ void gmx::LegacySimulator::do_mimic() /* Copy the pointer to the global state */ state = state_global; - mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, - &graph, mdAtoms, constr, vsite, shellfc); + mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, &graph, mdAtoms, constr, vsite, shellfc); } auto mdatoms = mdAtoms->mdatoms(); @@ -298,29 +292,27 @@ void gmx::LegacySimulator::do_mimic() } { - int cglo_flags = (CGLO_GSTAT | - (shouldCheckNumberOfBondedInteractions ? - CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0)); + int cglo_flags = + (CGLO_GSTAT + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0)); bool bSumEkinhOld = false; - t_vcm *vcm = nullptr; - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, vcm, - nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags); + t_vcm* vcm = nullptr; + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, vcm, nullptr, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags); } - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top, + state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); if (MASTER(cr)) { - fprintf(stderr, "starting MiMiC MD run '%s'\n\n", - *(top_global->name)); + fprintf(stderr, "starting MiMiC MD run '%s'\n\n", *(top_global->name)); if (mdrunOptions.verbose) { - fprintf(stderr, "Calculated time to finish depends on nsteps from " + fprintf(stderr, + "Calculated time to finish depends on nsteps from " "run input file,\nwhich may not correspond to the time " "needed to process input trajectory.\n\n"); } @@ -339,18 +331,23 @@ void gmx::LegacySimulator::do_mimic() if (constr) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Simulations has constraints. Constraints will " - "be handled by CPMD."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Simulations has constraints. Constraints will " + "be handled by CPMD."); } - GMX_LOG(mdlog.info).asParagraph(). - appendText("MiMiC does not report kinetic energy, total energy, temperature, virial and pressure."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "MiMiC does not report kinetic energy, total energy, temperature, virial and " + "pressure."); auto stopHandler = stopHandlerBuilder->getStopHandlerMD( - compat::not_null(&signals[eglsSTOPCOND]), false, - MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, - mdrunOptions.maximumHoursToRun, ir->nstlist == 0, fplog, step, bNS, walltime_accounting); + compat::not_null(&signals[eglsSTOPCOND]), false, MASTER(cr), + ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun, + ir->nstlist == 0, fplog, step, bNS, walltime_accounting); // we don't do counter resetting in rerun - finish will always be valid walltime_accounting_set_valid_finish(walltime_accounting); @@ -384,7 +381,9 @@ void gmx::LegacySimulator::do_mimic() const bool constructVsites = ((vsite != nullptr) && mdrunOptions.rerunConstructVsites); if (constructVsites && DOMAINDECOMP(cr)) { - gmx_fatal(FARGS, "Vsite recalculation with -rerun is not implemented with domain decomposition, " + gmx_fatal(FARGS, + "Vsite recalculation with -rerun is not implemented with domain " + "decomposition, " "use a single rank"); } } @@ -393,14 +392,9 @@ void gmx::LegacySimulator::do_mimic() { /* Repartition the domain decomposition */ const bool bMasterState = true; - dd_partition_system(fplog, mdlog, step, cr, - bMasterState, nstglobalcomm, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, - nrnb, wcycle, - mdrunOptions.verbose); + dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global, + *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top, + fr, vsite, constr, nrnb, wcycle, mdrunOptions.verbose); shouldCheckNumberOfBondedInteractions = true; } @@ -414,31 +408,19 @@ void gmx::LegacySimulator::do_mimic() update_mdatoms(mdatoms, state->lambda[efptMASS]); } - force_flags = (GMX_FORCE_STATECHANGED | - GMX_FORCE_DYNAMICBOX | - GMX_FORCE_ALLFORCES | - GMX_FORCE_VIRIAL | // TODO: Get rid of this once #2649 is solved - GMX_FORCE_ENERGY | - (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0)); + force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES + | GMX_FORCE_VIRIAL | // TODO: Get rid of this once #2649 is solved + GMX_FORCE_ENERGY | (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0)); if (shellfc) { /* Now is the time to relax the shells */ - relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, - enforcedRotation, step, - ir, imdSession, pull_work, bNS, force_flags, &top, - constr, enerd, fcd, - state->natoms, - state->x.arrayRefWithPadding(), - state->v.arrayRefWithPadding(), - state->box, - state->lambda, - &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, - nrnb, wcycle, graph, - shellfc, fr, runScheduleWork, t, mu_tot, - vsite, - ddBalanceRegionHandler); + relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir, + imdSession, pull_work, bNS, force_flags, &top, constr, enerd, fcd, + state->natoms, state->x.arrayRefWithPadding(), + state->v.arrayRefWithPadding(), state->box, state->lambda, &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, nrnb, wcycle, graph, + shellfc, fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler); } else { @@ -447,16 +429,12 @@ void gmx::LegacySimulator::do_mimic() * This is parallellized as well, and does communication too. * Check comments in sim_util.c */ - Awh *awh = nullptr; - gmx_edsam *ed = nullptr; - do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, - pull_work, - step, nrnb, wcycle, &top, - state->box, state->x.arrayRefWithPadding(), &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, - state->lambda, graph, - fr, runScheduleWork, vsite, mu_tot, t, ed, - GMX_FORCE_NS | force_flags, + Awh* awh = nullptr; + gmx_edsam* ed = nullptr; + do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, pull_work, step, nrnb, + wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, state->lambda, graph, + fr, runScheduleWork, vsite, mu_tot, t, ed, GMX_FORCE_NS | force_flags, ddBalanceRegionHandler); } @@ -467,13 +445,10 @@ void gmx::LegacySimulator::do_mimic() const bool isCheckpointingStep = false; const bool doRerun = false; const bool bSumEkinhOld = false; - do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, - ir, state, state_global, observablesHistory, - top_global, fr, - outf, energyOutput, ekind, f, - isCheckpointingStep, doRerun, isLastStep, - mdrunOptions.writeConfout, - bSumEkinhOld); + do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state, + state_global, observablesHistory, top_global, fr, outf, + energyOutput, ekind, f, isCheckpointingStep, doRerun, + isLastStep, mdrunOptions.writeConfout, bSumEkinhOld); } stopHandler->setSignal(); @@ -491,8 +466,8 @@ void gmx::LegacySimulator::do_mimic() { shift_self(graph, state->box, as_rvec_array(state->x.data())); } - construct_vsites(vsite, as_rvec_array(state->x.data()), ir->delta_t, as_rvec_array(state->v.data()), - top.idef.iparams, top.idef.il, + construct_vsites(vsite, as_rvec_array(state->x.data()), ir->delta_t, + as_rvec_array(state->v.data()), top.idef.iparams, top.idef.il, fr->ePBC, fr->bMolPBC, cr, state->box); if (graph != nullptr) @@ -506,21 +481,18 @@ void gmx::LegacySimulator::do_mimic() const bool doInterSimSignal = false; const bool doIntraSimSignal = true; bool bSumEkinhOld = false; - t_vcm *vcm = nullptr; + t_vcm* vcm = nullptr; SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal); - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, vcm, - wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot, - constr, &signaller, - state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, vcm, wcycle, enerd, + nullptr, nullptr, nullptr, nullptr, mu_tot, constr, &signaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, CGLO_GSTAT | CGLO_ENERGY - | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - ); - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0)); + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, + &top, state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); } @@ -546,7 +518,6 @@ void gmx::LegacySimulator::do_mimic() } - /* Note: this is OK, but there are some numerical precision issues with using the convergence of the virial that should probably be addressed eventually. state->veta has better properies, but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could @@ -563,23 +534,20 @@ void gmx::LegacySimulator::do_mimic() if (MASTER(cr)) { const bool bCalcEnerStep = true; - energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep, - t, mdatoms->tmass, enerd, state, - ir->fepvals, ir->expandedvals, state->box, - shake_vir, force_vir, total_vir, pres, - ekind, mu_tot, constr); + energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep, t, + mdatoms->tmass, enerd, state, ir->fepvals, + ir->expandedvals, state->box, shake_vir, force_vir, + total_vir, pres, ekind, mu_tot, constr); const bool do_ene = true; const bool do_log = true; - Awh *awh = nullptr; + Awh* awh = nullptr; const bool do_dr = ir->nstdisreout != 0; const bool do_or = ir->nstorireout != 0; energyOutput.printAnnealingTemperatures(do_log ? fplog : nullptr, groups, &(ir->opts)); energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, - do_log ? fplog : nullptr, - step, t, - fcd, awh); + do_log ? fplog : nullptr, step, t, fcd, awh); if (do_per_step(step, ir->nstlog)) { @@ -591,8 +559,7 @@ void gmx::LegacySimulator::do_mimic() } /* Print the remaining wall clock time for the run */ - if (isMasterSimMasterRank(ms, MASTER(cr)) && - (mdrunOptions.verbose || gmx_got_usr_signal())) + if (isMasterSimMasterRank(ms, MASTER(cr)) && (mdrunOptions.verbose || gmx_got_usr_signal())) { if (shellfc) { diff --git a/src/gromacs/mdrun/minimize.cpp b/src/gromacs/mdrun/minimize.cpp index 4f90ef49e9..cab90eb55d 100644 --- a/src/gromacs/mdrun/minimize.cpp +++ b/src/gromacs/mdrun/minimize.cpp @@ -110,27 +110,28 @@ using gmx::MdrunScheduleWorkload; //! Utility structure for manipulating states during EM -typedef struct { +typedef struct +{ //! Copy of the global state - t_state s; + t_state s; //! Force array PaddedHostVector f; //! Potential energy - real epot; + real epot; //! Norm of the force - real fnorm; + real fnorm; //! Maximum force - real fmax; + real fmax; //! Direction - int a_fmax; + int a_fmax; } em_state_t; //! Print the EM starting conditions -static void print_em_start(FILE *fplog, - const t_commrec *cr, +static void print_em_start(FILE* fplog, + const t_commrec* cr, gmx_walltime_accounting_t walltime_accounting, gmx_wallcycle_t wcycle, - const char *name) + const char* name) { walltime_accounting_start_time(walltime_accounting); wallcycle_start(wcycle, ewcRUN); @@ -138,8 +139,7 @@ static void print_em_start(FILE *fplog, } //! Stop counting time for EM -static void em_time_end(gmx_walltime_accounting_t walltime_accounting, - gmx_wallcycle_t wcycle) +static void em_time_end(gmx_walltime_accounting_t walltime_accounting, gmx_wallcycle_t wcycle) { wallcycle_stop(wcycle, ewcRUN); @@ -147,7 +147,7 @@ static void em_time_end(gmx_walltime_accounting_t walltime_accounting, } //! Printing a log file and console header -static void sp_header(FILE *out, const char *minimizer, real ftol, int nsteps) +static void sp_header(FILE* out, const char* minimizer, real ftol, int nsteps) { fprintf(out, "\n"); fprintf(out, "%s:\n", minimizer); @@ -156,11 +156,7 @@ static void sp_header(FILE *out, const char *minimizer, real ftol, int nsteps) } //! Print warning message -static void warn_step(FILE *fp, - real ftol, - real fmax, - gmx_bool bLastStep, - gmx_bool bConstrain) +static void warn_step(FILE* fp, real ftol, real fmax, gmx_bool bLastStep, gmx_bool bConstrain) { constexpr bool realIsDouble = GMX_DOUBLE; char buffer[2048]; @@ -173,17 +169,17 @@ static void warn_step(FILE *fp, "atoms are overlapping. Modify the input coordinates to " "remove atom overlap or use soft-core potentials with " "the free energy code to avoid infinite forces.\n%s", - !realIsDouble ? - "You could also be lucky that switching to double precision " - "is sufficient to obtain finite forces.\n" : - ""); + !realIsDouble ? "You could also be lucky that switching to double precision " + "is sufficient to obtain finite forces.\n" + : ""); } else if (bLastStep) { sprintf(buffer, "\nEnergy minimization reached the maximum number " "of steps before the forces reached the requested " - "precision Fmax < %g.\n", ftol); + "precision Fmax < %g.\n", + ftol); } else { @@ -197,15 +193,13 @@ static void warn_step(FILE *fp, "converged to within the available machine precision, " "given your starting configuration and EM parameters.\n%s%s", ftol, - !realIsDouble ? - "\nDouble precision normally gives you higher accuracy, but " - "this is often not needed for preparing to run molecular " - "dynamics.\n" : - "", - bConstrain ? - "You might need to increase your constraint accuracy, or turn\n" - "off constraints altogether (set constraints = none in mdp file)\n" : - ""); + !realIsDouble ? "\nDouble precision normally gives you higher accuracy, but " + "this is often not needed for preparing to run molecular " + "dynamics.\n" + : "", + bConstrain ? "You might need to increase your constraint accuracy, or turn\n" + "off constraints altogether (set constraints = none in mdp file)\n" + : ""); } fputs(wrap_lines(buffer, 78, 0, FALSE), stderr); @@ -213,44 +207,53 @@ static void warn_step(FILE *fp, } //! Print message about convergence of the EM -static void print_converged(FILE *fp, const char *alg, real ftol, - int64_t count, gmx_bool bDone, int64_t nsteps, - const em_state_t *ems, double sqrtNumAtoms) +static void print_converged(FILE* fp, + const char* alg, + real ftol, + int64_t count, + gmx_bool bDone, + int64_t nsteps, + const em_state_t* ems, + double sqrtNumAtoms) { char buf[STEPSTRSIZE]; if (bDone) { - fprintf(fp, "\n%s converged to Fmax < %g in %s steps\n", - alg, ftol, gmx_step_str(count, buf)); + fprintf(fp, "\n%s converged to Fmax < %g in %s steps\n", alg, ftol, gmx_step_str(count, buf)); } else if (count < nsteps) { - fprintf(fp, "\n%s converged to machine precision in %s steps,\n" + fprintf(fp, + "\n%s converged to machine precision in %s steps,\n" "but did not reach the requested Fmax < %g.\n", alg, gmx_step_str(count, buf), ftol); } else { - fprintf(fp, "\n%s did not converge to Fmax < %g in %s steps.\n", - alg, ftol, gmx_step_str(count, buf)); + fprintf(fp, "\n%s did not converge to Fmax < %g in %s steps.\n", alg, ftol, + gmx_step_str(count, buf)); } #if GMX_DOUBLE fprintf(fp, "Potential Energy = %21.14e\n", ems->epot); fprintf(fp, "Maximum force = %21.14e on atom %d\n", ems->fmax, ems->a_fmax + 1); - fprintf(fp, "Norm of force = %21.14e\n", ems->fnorm/sqrtNumAtoms); + fprintf(fp, "Norm of force = %21.14e\n", ems->fnorm / sqrtNumAtoms); #else fprintf(fp, "Potential Energy = %14.7e\n", ems->epot); fprintf(fp, "Maximum force = %14.7e on atom %d\n", ems->fmax, ems->a_fmax + 1); - fprintf(fp, "Norm of force = %14.7e\n", ems->fnorm/sqrtNumAtoms); + fprintf(fp, "Norm of force = %14.7e\n", ems->fnorm / sqrtNumAtoms); #endif } //! Compute the norm and max of the force array in parallel -static void get_f_norm_max(const t_commrec *cr, - t_grpopts *opts, t_mdatoms *mdatoms, const rvec *f, - real *fnorm, real *fmax, int *a_fmax) +static void get_f_norm_max(const t_commrec* cr, + t_grpopts* opts, + t_mdatoms* mdatoms, + const rvec* f, + real* fnorm, + real* fmax, + int* a_fmax) { double fnorm2, *sum; real fmax2, fam; @@ -289,7 +292,7 @@ static void get_f_norm_max(const t_commrec *cr, { for (i = start; i < end; i++) { - fam = norm2(f[i]); + fam = norm2(f[i]); fnorm2 += fam; if (fam > fmax2) { @@ -309,19 +312,19 @@ static void get_f_norm_max(const t_commrec *cr, } if (PAR(cr)) { - snew(sum, 2*cr->nnodes+1); - sum[2*cr->nodeid] = fmax2; - sum[2*cr->nodeid+1] = a_max; - sum[2*cr->nnodes] = fnorm2; - gmx_sumd(2*cr->nnodes+1, sum, cr); - fnorm2 = sum[2*cr->nnodes]; + snew(sum, 2 * cr->nnodes + 1); + sum[2 * cr->nodeid] = fmax2; + sum[2 * cr->nodeid + 1] = a_max; + sum[2 * cr->nnodes] = fnorm2; + gmx_sumd(2 * cr->nnodes + 1, sum, cr); + fnorm2 = sum[2 * cr->nnodes]; /* Determine the global maximum */ for (i = 0; i < cr->nnodes; i++) { - if (sum[2*i] > fmax2) + if (sum[2 * i] > fmax2) { - fmax2 = sum[2*i]; - a_max = gmx::roundToInt(sum[2*i+1]); + fmax2 = sum[2 * i]; + a_max = gmx::roundToInt(sum[2 * i + 1]); } } sfree(sum); @@ -333,7 +336,7 @@ static void get_f_norm_max(const t_commrec *cr, } if (fmax) { - *fmax = sqrt(fmax2); + *fmax = sqrt(fmax2); } if (a_fmax) { @@ -342,28 +345,31 @@ static void get_f_norm_max(const t_commrec *cr, } //! Compute the norm of the force -static void get_state_f_norm_max(const t_commrec *cr, - t_grpopts *opts, t_mdatoms *mdatoms, - em_state_t *ems) +static void get_state_f_norm_max(const t_commrec* cr, t_grpopts* opts, t_mdatoms* mdatoms, em_state_t* ems) { - get_f_norm_max(cr, opts, mdatoms, ems->f.rvec_array(), - &ems->fnorm, &ems->fmax, &ems->a_fmax); + get_f_norm_max(cr, opts, mdatoms, ems->f.rvec_array(), &ems->fnorm, &ems->fmax, &ems->a_fmax); } //! Initialize the energy minimization -static void init_em(FILE *fplog, - const gmx::MDLogger &mdlog, - const char *title, - const t_commrec *cr, - t_inputrec *ir, - gmx::ImdSession *imdSession, - pull_t *pull_work, - t_state *state_global, gmx_mtop_t *top_global, - em_state_t *ems, gmx_localtop_t *top, - t_nrnb *nrnb, - t_forcerec *fr, - t_graph **graph, gmx::MDAtoms *mdAtoms, gmx_global_stat_t *gstat, - gmx_vsite_t *vsite, gmx::Constraints *constr, gmx_shellfc_t **shellfc) +static void init_em(FILE* fplog, + const gmx::MDLogger& mdlog, + const char* title, + const t_commrec* cr, + t_inputrec* ir, + gmx::ImdSession* imdSession, + pull_t* pull_work, + t_state* state_global, + gmx_mtop_t* top_global, + em_state_t* ems, + gmx_localtop_t* top, + t_nrnb* nrnb, + t_forcerec* fr, + t_graph** graph, + gmx::MDAtoms* mdAtoms, + gmx_global_stat_t* gstat, + gmx_vsite_t* vsite, + gmx::Constraints* constr, + gmx_shellfc_t** shellfc) { real dvdl_constr; @@ -382,15 +388,14 @@ static void init_em(FILE *fplog, { GMX_ASSERT(shellfc != nullptr, "With NM we always support shells"); - *shellfc = init_shell_flexcon(stdout, - top_global, - constr ? constr->numFlexibleConstraints() : 0, - ir->nstcalcenergy, - DOMAINDECOMP(cr)); + *shellfc = init_shell_flexcon(stdout, top_global, constr ? constr->numFlexibleConstraints() : 0, + ir->nstcalcenergy, DOMAINDECOMP(cr)); } else { - GMX_ASSERT(EI_ENERGY_MINIMIZATION(ir->eI), "This else currently only handles energy minimizers, consider if your algorithm needs shell/flexible-constraint support"); + GMX_ASSERT(EI_ENERGY_MINIMIZATION(ir->eI), + "This else currently only handles energy minimizers, consider if your algorithm " + "needs shell/flexible-constraint support"); /* With energy minimization, shells and flexible constraints are * automatically minimized when treated like normal DOFS. @@ -410,11 +415,9 @@ static void init_em(FILE *fplog, dd_init_local_state(cr->dd, state_global, &ems->s); /* Distribute the charge groups over the nodes from the master node */ - dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, - state_global, *top_global, ir, imdSession, pull_work, - &ems->s, &ems->f, mdAtoms, top, - fr, vsite, constr, - nrnb, nullptr, FALSE); + dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir, + imdSession, pull_work, &ems->s, &ems->f, mdAtoms, top, fr, vsite, + constr, nrnb, nullptr, FALSE); dd_store_state(cr->dd, &ems->s); *graph = nullptr; @@ -427,9 +430,8 @@ static void init_em(FILE *fplog, state_change_natoms(&ems->s, ems->s.natoms); ems->f.resizeWithPadding(ems->s.natoms); - mdAlgorithmsSetupAtomData(cr, ir, *top_global, top, fr, - graph, mdAtoms, - constr, vsite, shellfc ? *shellfc : nullptr); + mdAlgorithmsSetupAtomData(cr, ir, *top_global, top, fr, graph, mdAtoms, constr, vsite, + shellfc ? *shellfc : nullptr); if (vsite) { @@ -442,8 +444,7 @@ static void init_em(FILE *fplog, if (constr) { // TODO how should this cross-module support dependency be managed? - if (ir->eConstrAlg == econtSHAKE && - gmx_mtop_ftype_count(top_global, F_CONSTR) > 0) + if (ir->eConstrAlg == econtSHAKE && gmx_mtop_ftype_count(top_global, F_CONSTR) > 0) { gmx_fatal(FARGS, "Can not do energy minimization with %s, use %s\n", econstr_names[econtSHAKE], econstr_names[econtLINCS]); @@ -453,14 +454,9 @@ static void init_em(FILE *fplog, { /* Constrain the starting coordinates */ dvdl_constr = 0; - constr->apply(TRUE, TRUE, - -1, 0, 1.0, - ems->s.x.rvec_array(), - ems->s.x.rvec_array(), - nullptr, - ems->s.box, - ems->s.lambda[efptFEP], &dvdl_constr, - nullptr, nullptr, gmx::ConstraintVariable::Positions); + constr->apply(TRUE, TRUE, -1, 0, 1.0, ems->s.x.rvec_array(), ems->s.x.rvec_array(), + nullptr, ems->s.box, ems->s.lambda[efptFEP], &dvdl_constr, nullptr, + nullptr, gmx::ConstraintVariable::Positions); } } @@ -477,9 +473,10 @@ static void init_em(FILE *fplog, } //! Finalize the minimization -static void finish_em(const t_commrec *cr, gmx_mdoutf_t outf, +static void finish_em(const t_commrec* cr, + gmx_mdoutf_t outf, gmx_walltime_accounting_t walltime_accounting, - gmx_wallcycle_t wcycle) + gmx_wallcycle_t wcycle) { if (!thisRankHasDuty(cr, DUTY_PME)) { @@ -493,9 +490,9 @@ static void finish_em(const t_commrec *cr, gmx_mdoutf_t outf, } //! Swap two different EM states during minimization -static void swap_em_state(em_state_t **ems1, em_state_t **ems2) +static void swap_em_state(em_state_t** ems1, em_state_t** ems2) { - em_state_t *tmp; + em_state_t* tmp; tmp = *ems1; *ems1 = *ems2; @@ -503,14 +500,18 @@ static void swap_em_state(em_state_t **ems1, em_state_t **ems2) } //! Save the EM trajectory -static void write_em_traj(FILE *fplog, const t_commrec *cr, - gmx_mdoutf_t outf, - gmx_bool bX, gmx_bool bF, const char *confout, - gmx_mtop_t *top_global, - t_inputrec *ir, int64_t step, - em_state_t *state, - t_state *state_global, - ObservablesHistory *observablesHistory) +static void write_em_traj(FILE* fplog, + const t_commrec* cr, + gmx_mdoutf_t outf, + gmx_bool bX, + gmx_bool bF, + const char* confout, + gmx_mtop_t* top_global, + t_inputrec* ir, + int64_t step, + em_state_t* state, + t_state* state_global, + ObservablesHistory* observablesHistory) { int mdof_flags = 0; @@ -529,10 +530,9 @@ static void write_em_traj(FILE *fplog, const t_commrec *cr, mdof_flags |= MDOF_IMD; } - mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, - top_global->natoms, step, static_cast(step), - &state->s, state_global, observablesHistory, - state->f); + mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step, + static_cast(step), &state->s, state_global, + observablesHistory, state->f); if (confout != nullptr) { @@ -556,12 +556,10 @@ static void write_em_traj(FILE *fplog, const t_commrec *cr, if (ir->ePBC != epbcNONE && !ir->bPeriodicMols && DOMAINDECOMP(cr)) { /* Make molecules whole only for confout writing */ - do_pbc_mtop(ir->ePBC, state->s.box, top_global, - state_global->x.rvec_array()); + do_pbc_mtop(ir->ePBC, state->s.box, top_global, state_global->x.rvec_array()); } - write_sto_conf_mtop(confout, - *top_global->name, top_global, + write_sto_conf_mtop(confout, *top_global->name, top_global, state_global->x.rvec_array(), nullptr, ir->ePBC, state->s.box); } } @@ -570,20 +568,23 @@ static void write_em_traj(FILE *fplog, const t_commrec *cr, //! \brief Do one minimization step // // \returns true when the step succeeded, false when a constraint error occurred -static bool do_em_step(const t_commrec *cr, - t_inputrec *ir, t_mdatoms *md, - em_state_t *ems1, real a, const PaddedHostVector *force, - em_state_t *ems2, - gmx::Constraints *constr, - int64_t count) +static bool do_em_step(const t_commrec* cr, + t_inputrec* ir, + t_mdatoms* md, + em_state_t* ems1, + real a, + const PaddedHostVector* force, + em_state_t* ems2, + gmx::Constraints* constr, + int64_t count) { t_state *s1, *s2; int start, end; real dvdl_constr; - int nthreads gmx_unused; + int nthreads gmx_unused; - bool validStep = true; + bool validStep = true; s1 = &ems1->s; s2 = &ems2->s; @@ -616,11 +617,11 @@ static bool do_em_step(const t_commrec *cr, nthreads = gmx_omp_nthreads_get(emntUpdate); #pragma omp parallel num_threads(nthreads) { - const rvec *x1 = s1->x.rvec_array(); - rvec *x2 = s2->x.rvec_array(); - const rvec *f = force->rvec_array(); + const rvec* x1 = s1->x.rvec_array(); + rvec* x2 = s2->x.rvec_array(); + const rvec* f = force->rvec_array(); - int gf = 0; + int gf = 0; #pragma omp for schedule(static) nowait for (int i = start; i < end; i++) { @@ -638,18 +639,18 @@ static bool do_em_step(const t_commrec *cr, } else { - x2[i][m] = x1[i][m] + a*f[i][m]; + x2[i][m] = x1[i][m] + a * f[i][m]; } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - if (s2->flags & (1<flags & (1 << estCGP)) { /* Copy the CG p vector */ - const rvec *p1 = s1->cg_p.rvec_array(); - rvec *p2 = s2->cg_p.rvec_array(); + const rvec* p1 = s1->cg_p.rvec_array(); + rvec* p2 = s2->cg_p.rvec_array(); #pragma omp for schedule(static) nowait for (int i = start; i < end; i++) { @@ -678,13 +679,9 @@ static bool do_em_step(const t_commrec *cr, if (constr) { dvdl_constr = 0; - validStep = - constr->apply(TRUE, TRUE, - count, 0, 1.0, - s1->x.rvec_array(), s2->x.rvec_array(), - nullptr, s2->box, - s2->lambda[efptBONDED], &dvdl_constr, - nullptr, nullptr, gmx::ConstraintVariable::Positions); + validStep = constr->apply(TRUE, TRUE, count, 0, 1.0, s1->x.rvec_array(), s2->x.rvec_array(), + nullptr, s2->box, s2->lambda[efptBONDED], &dvdl_constr, nullptr, + nullptr, gmx::ConstraintVariable::Positions); if (cr->nnodes > 1) { @@ -694,13 +691,15 @@ static bool do_em_step(const t_commrec *cr, */ int reductionBuffer = static_cast(!validStep); gmx_sumi(1, &reductionBuffer, cr); - validStep = (reductionBuffer == 0); + validStep = (reductionBuffer == 0); } // We should move this check to the different minimizers if (!validStep && ir->eI != eiSteep) { - gmx_fatal(FARGS, "The coordinates could not be constrained. Minimizer '%s' can not handle constraint failures, use minimizer '%s' before using '%s'.", + gmx_fatal(FARGS, + "The coordinates could not be constrained. Minimizer '%s' can not handle " + "constraint failures, use minimizer '%s' before using '%s'.", EI(ir->eI), EI(eiSteep), EI(ir->eI)); } } @@ -709,23 +708,26 @@ static bool do_em_step(const t_commrec *cr, } //! Prepare EM for using domain decomposition parallellization -static void em_dd_partition_system(FILE *fplog, - const gmx::MDLogger &mdlog, - int step, const t_commrec *cr, - gmx_mtop_t *top_global, t_inputrec *ir, - gmx::ImdSession *imdSession, - pull_t *pull_work, - em_state_t *ems, gmx_localtop_t *top, - gmx::MDAtoms *mdAtoms, t_forcerec *fr, - gmx_vsite_t *vsite, gmx::Constraints *constr, - t_nrnb *nrnb, gmx_wallcycle_t wcycle) +static void em_dd_partition_system(FILE* fplog, + const gmx::MDLogger& mdlog, + int step, + const t_commrec* cr, + gmx_mtop_t* top_global, + t_inputrec* ir, + gmx::ImdSession* imdSession, + pull_t* pull_work, + em_state_t* ems, + gmx_localtop_t* top, + gmx::MDAtoms* mdAtoms, + t_forcerec* fr, + gmx_vsite_t* vsite, + gmx::Constraints* constr, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle) { /* Repartition the domain decomposition */ - dd_partition_system(fplog, mdlog, step, cr, FALSE, 1, - nullptr, *top_global, ir, imdSession, pull_work, - &ems->s, &ems->f, - mdAtoms, top, fr, vsite, constr, - nrnb, wcycle, FALSE); + dd_partition_system(fplog, mdlog, step, cr, FALSE, 1, nullptr, *top_global, ir, imdSession, pull_work, + &ems->s, &ems->f, mdAtoms, top, fr, vsite, constr, nrnb, wcycle, FALSE); dd_store_state(cr->dd, &ems->s); } @@ -746,64 +748,59 @@ namespace * Use a braced initializer list to construct one of these. */ class EnergyEvaluator { - public: - /*! \brief Evaluates an energy on the state in \c ems. - * - * \todo In practice, the same objects mu_tot, vir, and pres - * are always passed to this function, so we would rather have - * them as data members. However, their C-array types are - * unsuited for aggregate initialization. When the types - * improve, the call signature of this method can be reduced. - */ - void run(em_state_t *ems, rvec mu_tot, - tensor vir, tensor pres, - int64_t count, gmx_bool bFirst); - //! Handles logging (deprecated). - FILE *fplog; - //! Handles logging. - const gmx::MDLogger &mdlog; - //! Handles communication. - const t_commrec *cr; - //! Coordinates multi-simulations. - const gmx_multisim_t *ms; - //! Holds the simulation topology. - gmx_mtop_t *top_global; - //! Holds the domain topology. - gmx_localtop_t *top; - //! User input options. - t_inputrec *inputrec; - //! The Interactive Molecular Dynamics session. - gmx::ImdSession *imdSession; - //! The pull work object. - pull_t *pull_work; - //! Manages flop accounting. - t_nrnb *nrnb; - //! Manages wall cycle accounting. - gmx_wallcycle_t wcycle; - //! Coordinates global reduction. - gmx_global_stat_t gstat; - //! Handles virtual sites. - gmx_vsite_t *vsite; - //! Handles constraints. - gmx::Constraints *constr; - //! Handles strange things. - t_fcdata *fcd; - //! Molecular graph for SHAKE. - t_graph *graph; - //! Per-atom data for this domain. - gmx::MDAtoms *mdAtoms; - //! Handles how to calculate the forces. - t_forcerec *fr; - //! Schedule of force-calculation work each step for this task. - MdrunScheduleWorkload *runScheduleWork; - //! Stores the computed energies. - gmx_enerdata_t *enerd; +public: + /*! \brief Evaluates an energy on the state in \c ems. + * + * \todo In practice, the same objects mu_tot, vir, and pres + * are always passed to this function, so we would rather have + * them as data members. However, their C-array types are + * unsuited for aggregate initialization. When the types + * improve, the call signature of this method can be reduced. + */ + void run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst); + //! Handles logging (deprecated). + FILE* fplog; + //! Handles logging. + const gmx::MDLogger& mdlog; + //! Handles communication. + const t_commrec* cr; + //! Coordinates multi-simulations. + const gmx_multisim_t* ms; + //! Holds the simulation topology. + gmx_mtop_t* top_global; + //! Holds the domain topology. + gmx_localtop_t* top; + //! User input options. + t_inputrec* inputrec; + //! The Interactive Molecular Dynamics session. + gmx::ImdSession* imdSession; + //! The pull work object. + pull_t* pull_work; + //! Manages flop accounting. + t_nrnb* nrnb; + //! Manages wall cycle accounting. + gmx_wallcycle_t wcycle; + //! Coordinates global reduction. + gmx_global_stat_t gstat; + //! Handles virtual sites. + gmx_vsite_t* vsite; + //! Handles constraints. + gmx::Constraints* constr; + //! Handles strange things. + t_fcdata* fcd; + //! Molecular graph for SHAKE. + t_graph* graph; + //! Per-atom data for this domain. + gmx::MDAtoms* mdAtoms; + //! Handles how to calculate the forces. + t_forcerec* fr; + //! Schedule of force-calculation work each step for this task. + MdrunScheduleWorkload* runScheduleWork; + //! Stores the computed energies. + gmx_enerdata_t* enerd; }; -void -EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, - tensor vir, tensor pres, - int64_t count, gmx_bool bFirst) +void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres, int64_t count, gmx_bool bFirst) { real t; gmx_bool bNS; @@ -814,8 +811,7 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, /* Set the time to the initial time, the time does not change during EM */ t = inputrec->init_t; - if (bFirst || - (DOMAINDECOMP(cr) && ems->s.ddp_count < cr->dd->ddp_count)) + if (bFirst || (DOMAINDECOMP(cr) && ems->s.ddp_count < cr->dd->ddp_count)) { /* This is the first state or an old state used before the last ns */ bNS = TRUE; @@ -831,33 +827,27 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, if (vsite) { - construct_vsites(vsite, ems->s.x.rvec_array(), 1, nullptr, - top->idef.iparams, top->idef.il, + construct_vsites(vsite, ems->s.x.rvec_array(), 1, nullptr, top->idef.iparams, top->idef.il, fr->ePBC, fr->bMolPBC, cr, ems->s.box); } if (DOMAINDECOMP(cr) && bNS) { /* Repartition the domain decomposition */ - em_dd_partition_system(fplog, mdlog, count, cr, top_global, inputrec, imdSession, - pull_work, - ems, top, mdAtoms, fr, vsite, constr, - nrnb, wcycle); + em_dd_partition_system(fplog, mdlog, count, cr, top_global, inputrec, imdSession, pull_work, + ems, top, mdAtoms, fr, vsite, constr, nrnb, wcycle); } /* Calc force & energy on new trial position */ /* do_force always puts the charge groups in the box and shifts again * We do not unshift, so molecules are always whole in congrad.c */ - do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, - pull_work, - count, nrnb, wcycle, top, - ems->s.box, ems->s.x.arrayRefWithPadding(), &ems->s.hist, - ems->f.arrayRefWithPadding(), force_vir, mdAtoms->mdatoms(), enerd, fcd, - ems->s.lambda, graph, fr, runScheduleWork, vsite, mu_tot, t, nullptr, - GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES | - GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY | - (bNS ? GMX_FORCE_NS : 0), + do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, pull_work, count, nrnb, wcycle, + top, ems->s.box, ems->s.x.arrayRefWithPadding(), &ems->s.hist, + ems->f.arrayRefWithPadding(), force_vir, mdAtoms->mdatoms(), enerd, fcd, ems->s.lambda, + graph, fr, runScheduleWork, vsite, mu_tot, t, nullptr, + GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES | GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY + | (bNS ? GMX_FORCE_NS : 0), DDBalanceRegionHandler(cr)); /* Clear the unused shake virial and pressure */ @@ -869,12 +859,8 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, { wallcycle_start(wcycle, ewcMoveE); - global_stat(gstat, cr, enerd, force_vir, shake_vir, mu_tot, - inputrec, nullptr, nullptr, nullptr, 1, &terminate, - nullptr, FALSE, - CGLO_ENERGY | - CGLO_PRESSURE | - CGLO_CONSTRAINT); + global_stat(gstat, cr, enerd, force_vir, shake_vir, mu_tot, inputrec, nullptr, nullptr, nullptr, + 1, &terminate, nullptr, FALSE, CGLO_ENERGY | CGLO_PRESSURE | CGLO_CONSTRAINT); wallcycle_stop(wcycle, ewcMoveE); } @@ -883,12 +869,12 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, { /* Calculate long range corrections to pressure and energy */ const DispersionCorrection::Correction correction = - fr->dispersionCorrection->calculate(ems->s.box, ems->s.lambda[efptVDW]); + fr->dispersionCorrection->calculate(ems->s.box, ems->s.lambda[efptVDW]); enerd->term[F_DISPCORR] = correction.energy; - enerd->term[F_EPOT] += correction.energy; - enerd->term[F_PRES] += correction.pressure; - enerd->term[F_DVDL] += correction.dvdl; + enerd->term[F_EPOT] += correction.energy; + enerd->term[F_PRES] += correction.pressure; + enerd->term[F_DVDL] += correction.dvdl; } else { @@ -900,14 +886,11 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, if (constr) { /* Project out the constraint components of the force */ - dvdl_constr = 0; - rvec *f_rvec = ems->f.rvec_array(); - constr->apply(FALSE, FALSE, - count, 0, 1.0, - ems->s.x.rvec_array(), f_rvec, f_rvec, - ems->s.box, - ems->s.lambda[efptBONDED], &dvdl_constr, - nullptr, &shake_vir, gmx::ConstraintVariable::ForceDispl); + dvdl_constr = 0; + rvec* f_rvec = ems->f.rvec_array(); + constr->apply(FALSE, FALSE, count, 0, 1.0, ems->s.x.rvec_array(), f_rvec, f_rvec, + ems->s.box, ems->s.lambda[efptBONDED], &dvdl_constr, nullptr, &shake_vir, + gmx::ConstraintVariable::ForceDispl); enerd->term[F_DVDL_CONSTR] += dvdl_constr; m_add(force_vir, shake_vir, vir); } @@ -917,8 +900,7 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, } clear_mat(ekin); - enerd->term[F_PRES] = - calc_pres(fr->ePBC, inputrec->nwall, ems->s.box, ekin, vir, pres); + enerd->term[F_PRES] = calc_pres(fr->ePBC, inputrec->nwall, ems->s.box, ekin, vir, pres); sum_dhdl(enerd, ems->s.lambda, *inputrec->fepvals); @@ -931,42 +913,45 @@ EnergyEvaluator::run(em_state_t *ems, rvec mu_tot, } // namespace //! Parallel utility summing energies and forces -static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, - gmx_mtop_t *top_global, - em_state_t *s_min, em_state_t *s_b) +static double reorder_partsum(const t_commrec* cr, + t_grpopts* opts, + gmx_mtop_t* top_global, + em_state_t* s_min, + em_state_t* s_b) { if (debug) { fprintf(debug, "Doing reorder_partsum\n"); } - const rvec *fm = s_min->f.rvec_array(); - const rvec *fb = s_b->f.rvec_array(); + const rvec* fm = s_min->f.rvec_array(); + const rvec* fb = s_b->f.rvec_array(); /* Collect fm in a global vector fmg. * This conflicts with the spirit of domain decomposition, * but to fully optimize this a much more complicated algorithm is required. */ - const int natoms = top_global->natoms; - rvec *fmg; + const int natoms = top_global->natoms; + rvec* fmg; snew(fmg, natoms); gmx::ArrayRef indicesMin = s_min->s.cg_gl; - int i = 0; + int i = 0; for (int a : indicesMin) { copy_rvec(fm[i], fmg[a]); i++; } - gmx_sum(top_global->natoms*3, fmg[0], cr); + gmx_sum(top_global->natoms * 3, fmg[0], cr); /* Now we will determine the part of the sum for the cgs in state s_b */ gmx::ArrayRef indicesB = s_b->s.cg_gl; - double partsum = 0; - i = 0; - int gf = 0; - gmx::ArrayRef grpnrFREEZE = top_global->groups.groupNumbers[SimulationAtomGroupType::Freeze]; + double partsum = 0; + i = 0; + int gf = 0; + gmx::ArrayRef grpnrFREEZE = + top_global->groups.groupNumbers[SimulationAtomGroupType::Freeze]; for (int a : indicesB) { if (!grpnrFREEZE.empty()) @@ -977,7 +962,7 @@ static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, { if (!opts->nFreeze[gf][m]) { - partsum += (fb[i][m] - fmg[a][m])*fb[i][m]; + partsum += (fb[i][m] - fmg[a][m]) * fb[i][m]; } } i++; @@ -989,9 +974,12 @@ static double reorder_partsum(const t_commrec *cr, t_grpopts *opts, } //! Print some stuff, like beta, whatever that means. -static real pr_beta(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms, - gmx_mtop_t *top_global, - em_state_t *s_min, em_state_t *s_b) +static real pr_beta(const t_commrec* cr, + t_grpopts* opts, + t_mdatoms* mdatoms, + gmx_mtop_t* top_global, + em_state_t* s_min, + em_state_t* s_b) { double sum; @@ -1000,14 +988,13 @@ static real pr_beta(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms, * and might have to sum it in parallel runs. */ - if (!DOMAINDECOMP(cr) || - (s_min->s.ddp_count == cr->dd->ddp_count && - s_b->s.ddp_count == cr->dd->ddp_count)) + if (!DOMAINDECOMP(cr) + || (s_min->s.ddp_count == cr->dd->ddp_count && s_b->s.ddp_count == cr->dd->ddp_count)) { - const rvec *fm = s_min->f.rvec_array(); - const rvec *fb = s_b->f.rvec_array(); - sum = 0; - int gf = 0; + const rvec* fm = s_min->f.rvec_array(); + const rvec* fb = s_b->f.rvec_array(); + sum = 0; + int gf = 0; /* This part of code can be incorrect with DD, * since the atom ordering in s_b and s_min might differ. */ @@ -1021,7 +1008,7 @@ static real pr_beta(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms, { if (!opts->nFreeze[gf][m]) { - sum += (fb[i][m] - fm[i][m])*fb[i][m]; + sum += (fb[i][m] - fm[i][m]) * fb[i][m]; } } } @@ -1036,72 +1023,72 @@ static real pr_beta(const t_commrec *cr, t_grpopts *opts, t_mdatoms *mdatoms, gmx_sumd(1, &sum, cr); } - return sum/gmx::square(s_min->fnorm); + return sum / gmx::square(s_min->fnorm); } namespace gmx { -void -LegacySimulator::do_cg() +void LegacySimulator::do_cg() { - const char *CG = "Polak-Ribiere Conjugate Gradients"; + const char* CG = "Polak-Ribiere Conjugate Gradients"; - gmx_localtop_t top; - gmx_global_stat_t gstat; - t_graph *graph; - double tmp, minstep; - real stepsize; - real a, b, c, beta = 0.0; - real epot_repl = 0; - real pnorm; - gmx_bool converged, foundlower; - rvec mu_tot = {0}; - gmx_bool do_log = FALSE, do_ene = FALSE, do_x, do_f; - tensor vir, pres; - int number_steps, neval = 0, nstcg = inputrec->nstcgsteep; - int m, step, nminstep; - auto mdatoms = mdAtoms->mdatoms(); - - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that activating conjugate gradient energy minimization via the " - "integrator .mdp option and the command gmx mdrun may " - "be available in a different form in a future version of GROMACS, " - "e.g. gmx minimize and an .mdp option."); + gmx_localtop_t top; + gmx_global_stat_t gstat; + t_graph* graph; + double tmp, minstep; + real stepsize; + real a, b, c, beta = 0.0; + real epot_repl = 0; + real pnorm; + gmx_bool converged, foundlower; + rvec mu_tot = { 0 }; + gmx_bool do_log = FALSE, do_ene = FALSE, do_x, do_f; + tensor vir, pres; + int number_steps, neval = 0, nstcg = inputrec->nstcgsteep; + int m, step, nminstep; + auto mdatoms = mdAtoms->mdatoms(); + + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that activating conjugate gradient energy minimization via the " + "integrator .mdp option and the command gmx mdrun may " + "be available in a different form in a future version of GROMACS, " + "e.g. gmx minimize and an .mdp option."); step = 0; if (MASTER(cr)) { // In CG, the state is extended with a search direction - state_global->flags |= (1<flags |= (1 << estCGP); // Ensure the extra per-atom state array gets allocated state_change_natoms(state_global, state_global->natoms); // Initialize the search direction to zero - for (RVec &cg_p : state_global->cg_p) + for (RVec& cg_p : state_global->cg_p) { cg_p = { 0, 0, 0 }; } } /* Create 4 states on the stack and extract pointers that we will swap */ - em_state_t s0 {}, s1 {}, s2 {}, s3 {}; - em_state_t *s_min = &s0; - em_state_t *s_a = &s1; - em_state_t *s_b = &s2; - em_state_t *s_c = &s3; + em_state_t s0{}, s1{}, s2{}, s3{}; + em_state_t* s_min = &s0; + em_state_t* s_a = &s1; + em_state_t* s_b = &s2; + em_state_t* s_c = &s3; /* Init em and store the local state in s_min */ - init_em(fplog, mdlog, CG, cr, inputrec, imdSession, - pull_work, - state_global, top_global, s_min, &top, - nrnb, fr, &graph, mdAtoms, &gstat, - vsite, constr, nullptr); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, top_global, nullptr, wcycle, - StartingBehavior::NewSimulation); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr, false, mdModulesNotifier); + init_em(fplog, mdlog, CG, cr, inputrec, imdSession, pull_work, state_global, top_global, s_min, + &top, nrnb, fr, &graph, mdAtoms, &gstat, vsite, constr, nullptr); + gmx_mdoutf* outf = + init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + inputrec, top_global, nullptr, wcycle, StartingBehavior::NewSimulation); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, + nullptr, false, mdModulesNotifier); /* Print to log file */ print_em_start(fplog, cr, walltime_accounting, wcycle, CG); @@ -1118,12 +1105,10 @@ LegacySimulator::do_cg() sp_header(fplog, CG, inputrec->em_tol, number_steps); } - EnergyEvaluator energyEvaluator { - fplog, mdlog, cr, ms, - top_global, &top, - inputrec, imdSession, pull_work, nrnb, wcycle, gstat, - vsite, constr, fcd, graph, - mdAtoms, fr, runScheduleWork, enerd + EnergyEvaluator energyEvaluator{ + fplog, mdlog, cr, ms, top_global, &top, inputrec, + imdSession, pull_work, nrnb, wcycle, gstat, vsite, constr, + fcd, graph, mdAtoms, fr, runScheduleWork, enerd }; /* Call the force routine and some auxiliary (neighboursearching etc.) */ /* do_force always puts the charge groups in the box and shifts again @@ -1135,32 +1120,27 @@ LegacySimulator::do_cg() { /* Copy stuff to the energy bin for easy printing etc. */ matrix nullBox = {}; - energyOutput.addDataAtEnergyStep(false, false, static_cast(step), - mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox, - nullptr, nullptr, vir, pres, nullptr, mu_tot, constr); + energyOutput.addDataAtEnergyStep(false, false, static_cast(step), mdatoms->tmass, + enerd, nullptr, nullptr, nullptr, nullBox, nullptr, + nullptr, vir, pres, nullptr, mu_tot, constr); energyOutput.printHeader(fplog, step, step); - energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, - fplog, step, step, - fcd, nullptr); + energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, + step, fcd, nullptr); } /* Estimate/guess the initial stepsize */ - stepsize = inputrec->em_stepsize/s_min->fnorm; + stepsize = inputrec->em_stepsize / s_min->fnorm; if (MASTER(cr)) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - fprintf(stderr, " F-max = %12.5e on atom %d\n", - s_min->fmax, s_min->a_fmax+1); - fprintf(stderr, " F-Norm = %12.5e\n", - s_min->fnorm/sqrtNumAtoms); + fprintf(stderr, " F-max = %12.5e on atom %d\n", s_min->fmax, s_min->a_fmax + 1); + fprintf(stderr, " F-Norm = %12.5e\n", s_min->fnorm / sqrtNumAtoms); fprintf(stderr, "\n"); /* and copy to the log file too... */ - fprintf(fplog, " F-max = %12.5e on atom %d\n", - s_min->fmax, s_min->a_fmax+1); - fprintf(fplog, " F-Norm = %12.5e\n", - s_min->fnorm/sqrtNumAtoms); + fprintf(fplog, " F-max = %12.5e on atom %d\n", s_min->fmax, s_min->a_fmax + 1); + fprintf(fplog, " F-Norm = %12.5e\n", s_min->fnorm / sqrtNumAtoms); fprintf(fplog, "\n"); } /* Start the loop over CG steps. @@ -1177,8 +1157,8 @@ LegacySimulator::do_cg() */ /* Calculate the new direction in p, and the gradient in this direction, gpa */ - rvec *pm = s_min->s.cg_p.rvec_array(); - const rvec *sfm = s_min->f.rvec_array(); + rvec* pm = s_min->s.cg_p.rvec_array(); + const rvec* sfm = s_min->f.rvec_array(); double gpa = 0; int gf = 0; for (int i = 0; i < mdatoms->homenr; i++) @@ -1191,8 +1171,8 @@ LegacySimulator::do_cg() { if (!inputrec->opts.nFreeze[gf][m]) { - pm[i][m] = sfm[i][m] + beta*pm[i][m]; - gpa -= pm[i][m]*sfm[i][m]; + pm[i][m] = sfm[i][m] + beta * pm[i][m]; + gpa -= pm[i][m] * sfm[i][m]; /* f is negative gradient, thus the sign */ } else @@ -1214,7 +1194,7 @@ LegacySimulator::do_cg() /* Just in case stepsize reaches zero due to numerical precision... */ if (stepsize <= 0) { - stepsize = inputrec->em_stepsize/pnorm; + stepsize = inputrec->em_stepsize / pnorm; } /* @@ -1233,7 +1213,7 @@ LegacySimulator::do_cg() /* Calculate minimum allowed stepsize, before the average (norm) * relative change in coordinate is smaller than precision */ - minstep = 0; + minstep = 0; auto s_min_x = makeArrayRef(s_min->s.x); for (int i = 0; i < mdatoms->homenr; i++) { @@ -1244,8 +1224,8 @@ LegacySimulator::do_cg() { tmp = 1.0; } - tmp = pm[i][m]/tmp; - minstep += tmp*tmp; + tmp = pm[i][m] / tmp; + minstep += tmp * tmp; } } /* Add up from all CPUs */ @@ -1254,7 +1234,7 @@ LegacySimulator::do_cg() gmx_sumd(1, &minstep, cr); } - minstep = GMX_REAL_EPS/sqrt(minstep/(3*top_global->natoms)); + minstep = GMX_REAL_EPS / sqrt(minstep / (3 * top_global->natoms)); if (stepsize < minstep) { @@ -1266,9 +1246,8 @@ LegacySimulator::do_cg() do_x = do_per_step(step, inputrec->nstxout); do_f = do_per_step(step, inputrec->nstfout); - write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, - top_global, inputrec, step, - s_min, state_global, observablesHistory); + write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, step, s_min, + state_global, observablesHistory); /* Take a step downhill. * In theory, we should minimize the function along this direction. @@ -1294,28 +1273,25 @@ LegacySimulator::do_cg() if (DOMAINDECOMP(cr) && s_min->s.ddp_count < cr->dd->ddp_count) { em_dd_partition_system(fplog, mdlog, step, cr, top_global, inputrec, imdSession, - pull_work, - s_min, &top, mdAtoms, fr, vsite, constr, - nrnb, wcycle); + pull_work, s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle); } /* Take a trial step (new coords in s_c) */ - do_em_step(cr, inputrec, mdatoms, s_min, c, &s_min->s.cg_p, s_c, - constr, -1); + do_em_step(cr, inputrec, mdatoms, s_min, c, &s_min->s.cg_p, s_c, constr, -1); neval++; /* Calculate energy for the trial step */ energyEvaluator.run(s_c, mu_tot, vir, pres, -1, FALSE); /* Calc derivative along line */ - const rvec *pc = s_c->s.cg_p.rvec_array(); - const rvec *sfc = s_c->f.rvec_array(); + const rvec* pc = s_c->s.cg_p.rvec_array(); + const rvec* sfc = s_c->f.rvec_array(); double gpc = 0; for (int i = 0; i < mdatoms->homenr; i++) { for (m = 0; m < DIM; m++) { - gpc -= pc[i][m]*sfc[i][m]; /* f is negative gradient, thus the sign */ + gpc -= pc[i][m] * sfc[i][m]; /* f is negative gradient, thus the sign */ } } /* Sum the gradient along the line across CPUs */ @@ -1325,7 +1301,7 @@ LegacySimulator::do_cg() } /* This is the max amount of increase in energy we tolerate */ - tmp = std::sqrt(GMX_REAL_EPS)*fabs(s_a->epot); + tmp = std::sqrt(GMX_REAL_EPS) * fabs(s_a->epot); /* Accept the step if the energy is lower, or if it is not significantly higher * and the line derivative is still negative. @@ -1351,12 +1327,10 @@ LegacySimulator::do_cg() * to find a smaller value in the interval. Take smaller step next time! */ foundlower = FALSE; - stepsize *= 0.618034; + stepsize *= 0.618034; } - - /* OK, if we didn't find a lower value we will have to locate one now - there must * be one in the interval [a=0,c]. * The same thing is valid here, though: Don't spend dozens of iterations to find @@ -1381,11 +1355,11 @@ LegacySimulator::do_cg() */ if (gpa < 0 && gpc > 0) { - b = a + gpa*(a-c)/(gpc-gpa); + b = a + gpa * (a - c) / (gpc - gpa); } else { - b = 0.5*(a+c); + b = 0.5 * (a + c); } /* safeguard if interpolation close to machine accuracy causes errors: @@ -1393,21 +1367,18 @@ LegacySimulator::do_cg() */ if (b <= a || b >= c) { - b = 0.5*(a+c); + b = 0.5 * (a + c); } if (DOMAINDECOMP(cr) && s_min->s.ddp_count != cr->dd->ddp_count) { /* Reload the old state */ - em_dd_partition_system(fplog, mdlog, -1, cr, top_global, inputrec, imdSession, - pull_work, - s_min, &top, mdAtoms, fr, vsite, constr, - nrnb, wcycle); + em_dd_partition_system(fplog, mdlog, -1, cr, top_global, inputrec, imdSession, pull_work, + s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle); } /* Take a trial step to this new point - new coords in s_b */ - do_em_step(cr, inputrec, mdatoms, s_min, b, &s_min->s.cg_p, s_b, - constr, -1); + do_em_step(cr, inputrec, mdatoms, s_min, b, &s_min->s.cg_p, s_b, constr, -1); neval++; /* Calculate energy for the trial step */ @@ -1416,14 +1387,14 @@ LegacySimulator::do_cg() /* p does not change within a step, but since the domain decomposition * might change, we have to use cg_p of s_b here. */ - const rvec *pb = s_b->s.cg_p.rvec_array(); - const rvec *sfb = s_b->f.rvec_array(); + const rvec* pb = s_b->s.cg_p.rvec_array(); + const rvec* sfb = s_b->f.rvec_array(); gpb = 0; for (int i = 0; i < mdatoms->homenr; i++) { for (m = 0; m < DIM; m++) { - gpb -= pb[i][m]*sfb[i][m]; /* f is negative gradient, thus the sign */ + gpb -= pb[i][m] * sfb[i][m]; /* f is negative gradient, thus the sign */ } } /* Sum the gradient along the line across CPUs */ @@ -1434,8 +1405,8 @@ LegacySimulator::do_cg() if (debug) { - fprintf(debug, "CGE: EpotA %f EpotB %f EpotC %f gpb %f\n", - s_a->epot, s_b->epot, s_c->epot, gpb); + fprintf(debug, "CGE: EpotA %f EpotB %f EpotC %f gpb %f\n", s_a->epot, s_b->epot, + s_c->epot, gpb); } epot_repl = s_b->epot; @@ -1461,12 +1432,9 @@ LegacySimulator::do_cg() * Never run more than 20 steps, no matter what. */ nminstep++; - } - while ((epot_repl > s_a->epot || epot_repl > s_c->epot) && - (nminstep < 20)); + } while ((epot_repl > s_a->epot || epot_repl > s_c->epot) && (nminstep < 20)); - if (std::fabs(epot_repl - s_min->epot) < fabs(s_min->epot)*GMX_REAL_EPS || - nminstep >= 20) + if (std::fabs(epot_repl - s_min->epot) < fabs(s_min->epot) * GMX_REAL_EPS || nminstep >= 20) { /* OK. We couldn't find a significantly lower energy. * If beta==0 this was steepest descent, and then we give up. @@ -1492,8 +1460,8 @@ LegacySimulator::do_cg() { if (debug) { - fprintf(debug, "CGE: C (%f) is lower than A (%f), moving C to B\n", - s_c->epot, s_a->epot); + fprintf(debug, "CGE: C (%f) is lower than A (%f), moving C to B\n", s_c->epot, + s_a->epot); } swap_em_state(&s_b, &s_c); gpb = gpc; @@ -1502,20 +1470,18 @@ LegacySimulator::do_cg() { if (debug) { - fprintf(debug, "CGE: A (%f) is lower than C (%f), moving A to B\n", - s_a->epot, s_c->epot); + fprintf(debug, "CGE: A (%f) is lower than C (%f), moving A to B\n", s_a->epot, + s_c->epot); } swap_em_state(&s_b, &s_a); gpb = gpa; } - } else { if (debug) { - fprintf(debug, "CGE: Found a lower energy %f, moving C to B\n", - s_c->epot); + fprintf(debug, "CGE: Found a lower energy %f, moving C to B\n", s_c->epot); } swap_em_state(&s_b, &s_c); gpb = gpc; @@ -1555,16 +1521,15 @@ LegacySimulator::do_cg() if (mdrunOptions.verbose) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", - step, s_min->epot, s_min->fnorm/sqrtNumAtoms, - s_min->fmax, s_min->a_fmax+1); + fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", step, + s_min->epot, s_min->fnorm / sqrtNumAtoms, s_min->fmax, s_min->a_fmax + 1); fflush(stderr); } /* Store the new (lower) energies */ matrix nullBox = {}; - energyOutput.addDataAtEnergyStep(false, false, static_cast(step), - mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox, - nullptr, nullptr, vir, pres, nullptr, mu_tot, constr); + energyOutput.addDataAtEnergyStep(false, false, static_cast(step), mdatoms->tmass, + enerd, nullptr, nullptr, nullptr, nullBox, nullptr, + nullptr, vir, pres, nullptr, mu_tot, constr); do_log = do_per_step(step, inputrec->nstlog); do_ene = do_per_step(step, inputrec->nstenergy); @@ -1576,8 +1541,7 @@ LegacySimulator::do_cg() energyOutput.printHeader(fplog, step, step); } energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE, - do_log ? fplog : nullptr, step, step, - fcd, nullptr); + do_log ? fplog : nullptr, step, step, fcd, nullptr); } /* Send energies and positions to the IMD client if bIMD is TRUE. */ @@ -1591,19 +1555,17 @@ LegacySimulator::do_cg() */ converged = converged || (s_min->fmax < inputrec->em_tol); - } /* End of the loop */ + } /* End of the loop */ if (converged) { step--; /* we never took that last step in this case */ - } if (s_min->fmax > inputrec->em_tol) { if (MASTER(cr)) { - warn_step(fplog, inputrec->em_tol, s_min->fmax, - step-1 == number_steps, FALSE); + warn_step(fplog, inputrec->em_tol, s_min->fmax, step - 1 == number_steps, FALSE); } converged = FALSE; } @@ -1622,8 +1584,7 @@ LegacySimulator::do_cg() { /* Write final energy file entries */ energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE, - !do_log ? fplog : nullptr, step, step, - fcd, nullptr); + !do_log ? fplog : nullptr, step, step, fcd, nullptr); } } @@ -1646,18 +1607,15 @@ LegacySimulator::do_cg() do_x = !do_per_step(step, inputrec->nstxout); do_f = (inputrec->nstfout > 0 && !do_per_step(step, inputrec->nstfout)); - write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), - top_global, inputrec, step, - s_min, state_global, observablesHistory); + write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec, + step, s_min, state_global, observablesHistory); if (MASTER(cr)) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - print_converged(stderr, CG, inputrec->em_tol, step, converged, number_steps, - s_min, sqrtNumAtoms); - print_converged(fplog, CG, inputrec->em_tol, step, converged, number_steps, - s_min, sqrtNumAtoms); + print_converged(stderr, CG, inputrec->em_tol, step, converged, number_steps, s_min, sqrtNumAtoms); + print_converged(fplog, CG, inputrec->em_tol, step, converged, number_steps, s_min, sqrtNumAtoms); fprintf(fplog, "\nPerformed %d energy evaluations in total.\n", neval); } @@ -1669,22 +1627,21 @@ LegacySimulator::do_cg() } -void -LegacySimulator::do_lbfgs() +void LegacySimulator::do_lbfgs() { - static const char *LBFGS = "Low-Memory BFGS Minimizer"; + static const char* LBFGS = "Low-Memory BFGS Minimizer"; em_state_t ems; gmx_localtop_t top; gmx_global_stat_t gstat; - t_graph *graph; + t_graph* graph; int ncorr, nmaxcorr, point, cp, neval, nminstep; double stepsize, step_taken, gpa, gpb, gpc, tmp, minstep; - real *rho, *alpha, *p, *s, **dx, **dg; + real * rho, *alpha, *p, *s, **dx, **dg; real a, b, c, maxdelta, delta; real diag, Epot0; real dgdx, dgdg, sq, yr, beta; gmx_bool converged; - rvec mu_tot = {0}; + rvec mu_tot = { 0 }; gmx_bool do_log, do_ene, do_x, do_f, foundlower, *frozen; tensor vir, pres; int start, end, number_steps; @@ -1692,11 +1649,13 @@ LegacySimulator::do_lbfgs() int mdof_flags; auto mdatoms = mdAtoms->mdatoms(); - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that activating L-BFGS energy minimization via the " - "integrator .mdp option and the command gmx mdrun may " - "be available in a different form in a future version of GROMACS, " - "e.g. gmx minimize and an .mdp option."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that activating L-BFGS energy minimization via the " + "integrator .mdp option and the command gmx mdrun may " + "be available in a different form in a future version of GROMACS, " + "e.g. gmx minimize and an .mdp option."); if (PAR(cr)) { @@ -1705,10 +1664,13 @@ LegacySimulator::do_lbfgs() if (nullptr != constr) { - gmx_fatal(FARGS, "The combination of constraints and L-BFGS minimization is not implemented. Either do not use constraints, or use another minimizer (e.g. steepest descent)."); + gmx_fatal( + FARGS, + "The combination of constraints and L-BFGS minimization is not implemented. Either " + "do not use constraints, or use another minimizer (e.g. steepest descent)."); } - n = 3*state_global->natoms; + n = 3 * state_global->natoms; nmaxcorr = inputrec->nbfgscorr; snew(frozen, n); @@ -1733,28 +1695,27 @@ LegacySimulator::do_lbfgs() neval = 0; /* Init em */ - init_em(fplog, mdlog, LBFGS, cr, inputrec, imdSession, - pull_work, - state_global, top_global, &ems, &top, - nrnb, fr, &graph, mdAtoms, &gstat, - vsite, constr, nullptr); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, top_global, nullptr, wcycle, - StartingBehavior::NewSimulation); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr, false, mdModulesNotifier); + init_em(fplog, mdlog, LBFGS, cr, inputrec, imdSession, pull_work, state_global, top_global, + &ems, &top, nrnb, fr, &graph, mdAtoms, &gstat, vsite, constr, nullptr); + gmx_mdoutf* outf = + init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + inputrec, top_global, nullptr, wcycle, StartingBehavior::NewSimulation); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, + nullptr, false, mdModulesNotifier); start = 0; end = mdatoms->homenr; /* We need 4 working states */ - em_state_t s0 {}, s1 {}, s2 {}, s3 {}; - em_state_t *sa = &s0; - em_state_t *sb = &s1; - em_state_t *sc = &s2; - em_state_t *last = &s3; + em_state_t s0{}, s1{}, s2{}, s3{}; + em_state_t* sa = &s0; + em_state_t* sb = &s1; + em_state_t* sc = &s2; + em_state_t* last = &s3; /* Initialize by copying the state from ems (we could skip x and f here) */ - *sa = ems; - *sb = ems; - *sc = ems; + *sa = ems; + *sb = ems; + *sc = ems; /* Print to log file */ print_em_start(fplog, cr, walltime_accounting, wcycle, LBFGS); @@ -1774,7 +1735,7 @@ LegacySimulator::do_lbfgs() } for (m = 0; m < DIM; m++) { - frozen[3*i+m] = (inputrec->opts.nFreeze[gf][m] != 0); + frozen[3 * i + m] = (inputrec->opts.nFreeze[gf][m] != 0); } } if (MASTER(cr)) @@ -1788,9 +1749,8 @@ LegacySimulator::do_lbfgs() if (vsite) { - construct_vsites(vsite, state_global->x.rvec_array(), 1, nullptr, - top.idef.iparams, top.idef.il, - fr->ePBC, fr->bMolPBC, cr, state_global->box); + construct_vsites(vsite, state_global->x.rvec_array(), 1, nullptr, top.idef.iparams, + top.idef.il, fr->ePBC, fr->bMolPBC, cr, state_global->box); } /* Call the force routine and some auxiliary (neighboursearching etc.) */ @@ -1798,12 +1758,10 @@ LegacySimulator::do_lbfgs() * We do not unshift, so molecules are always whole */ neval++; - EnergyEvaluator energyEvaluator { - fplog, mdlog, cr, ms, - top_global, &top, - inputrec, imdSession, pull_work, nrnb, wcycle, gstat, - vsite, constr, fcd, graph, - mdAtoms, fr, runScheduleWork, enerd + EnergyEvaluator energyEvaluator{ + fplog, mdlog, cr, ms, top_global, &top, inputrec, + imdSession, pull_work, nrnb, wcycle, gstat, vsite, constr, + fcd, graph, mdAtoms, fr, runScheduleWork, enerd }; energyEvaluator.run(&ems, mu_tot, vir, pres, -1, TRUE); @@ -1811,14 +1769,13 @@ LegacySimulator::do_lbfgs() { /* Copy stuff to the energy bin for easy printing etc. */ matrix nullBox = {}; - energyOutput.addDataAtEnergyStep(false, false, static_cast(step), - mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox, - nullptr, nullptr, vir, pres, nullptr, mu_tot, constr); + energyOutput.addDataAtEnergyStep(false, false, static_cast(step), mdatoms->tmass, + enerd, nullptr, nullptr, nullptr, nullBox, nullptr, + nullptr, vir, pres, nullptr, mu_tot, constr); energyOutput.printHeader(fplog, step, step); - energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, - fplog, step, step, - fcd, nullptr); + energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, + step, fcd, nullptr); } /* Set the initial step. @@ -1832,12 +1789,12 @@ LegacySimulator::do_lbfgs() double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); fprintf(stderr, "Using %d BFGS correction steps.\n\n", nmaxcorr); fprintf(stderr, " F-max = %12.5e on atom %d\n", ems.fmax, ems.a_fmax + 1); - fprintf(stderr, " F-Norm = %12.5e\n", ems.fnorm/sqrtNumAtoms); + fprintf(stderr, " F-Norm = %12.5e\n", ems.fnorm / sqrtNumAtoms); fprintf(stderr, "\n"); /* and copy to the log file too... */ fprintf(fplog, "Using %d BFGS correction steps.\n\n", nmaxcorr); fprintf(fplog, " F-max = %12.5e on atom %d\n", ems.fmax, ems.a_fmax + 1); - fprintf(fplog, " F-Norm = %12.5e\n", ems.fnorm/sqrtNumAtoms); + fprintf(fplog, " F-Norm = %12.5e\n", ems.fnorm / sqrtNumAtoms); fprintf(fplog, "\n"); } @@ -1845,7 +1802,7 @@ LegacySimulator::do_lbfgs() point = 0; // Set initial search direction to the force (-gradient), or 0 for frozen particles. - real *fInit = static_cast(ems.f.rvec_array()[0]); + real* fInit = static_cast(ems.f.rvec_array()[0]); for (i = 0; i < n; i++) { if (!frozen[i]) @@ -1862,7 +1819,7 @@ LegacySimulator::do_lbfgs() // (the main efficiency in the algorithm comes from changing directions), but // we still need an initial value, so estimate it as the inverse of the norm // so we take small steps where the potential fluctuates a lot. - stepsize = 1.0/ems.fnorm; + stepsize = 1.0 / ems.fnorm; /* Start the loop over BFGS steps. * Each successful step is counted, and we continue until @@ -1896,22 +1853,22 @@ LegacySimulator::do_lbfgs() mdof_flags |= MDOF_IMD; } - mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, - top_global->natoms, step, static_cast(step), &ems.s, - state_global, observablesHistory, ems.f); + mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global->natoms, step, + static_cast(step), &ems.s, state_global, + observablesHistory, ems.f); /* Do the linesearching in the direction dx[point][0..(n-1)] */ /* make s a pointer to current search direction - point=0 first time we get here */ s = dx[point]; - real *xx = static_cast(ems.s.x.rvec_array()[0]); - real *ff = static_cast(ems.f.rvec_array()[0]); + real* xx = static_cast(ems.s.x.rvec_array()[0]); + real* ff = static_cast(ems.f.rvec_array()[0]); // calculate line gradient in position A for (gpa = 0, i = 0; i < n; i++) { - gpa -= s[i]*ff[i]; + gpa -= s[i] * ff[i]; } /* Calculate minimum allowed stepsize along the line, before the average (norm) @@ -1924,10 +1881,10 @@ LegacySimulator::do_lbfgs() { tmp = 1.0; } - tmp = s[i]/tmp; - minstep += tmp*tmp; + tmp = s[i] / tmp; + minstep += tmp * tmp; } - minstep = GMX_REAL_EPS/sqrt(minstep/n); + minstep = GMX_REAL_EPS / sqrt(minstep / n); if (stepsize < minstep) { @@ -1937,11 +1894,11 @@ LegacySimulator::do_lbfgs() // Before taking any steps along the line, store the old position *last = ems; - real *lastx = static_cast(last->s.x.data()[0]); - real *lastf = static_cast(last->f.data()[0]); + real* lastx = static_cast(last->s.x.data()[0]); + real* lastf = static_cast(last->f.data()[0]); Epot0 = ems.epot; - *sa = ems; + *sa = ems; /* Take a step downhill. * In theory, we should find the actual minimum of the function in this @@ -1970,7 +1927,7 @@ LegacySimulator::do_lbfgs() // State "A" is the first position along the line. // reference position along line is initially zero - a = 0.0; + a = 0.0; // Check stepsize first. We do not allow displacements // larger than emstep. @@ -1978,14 +1935,14 @@ LegacySimulator::do_lbfgs() do { // Pick a new position C by adding stepsize to A. - c = a + stepsize; + c = a + stepsize; // Calculate what the largest change in any individual coordinate // would be (translation along line * gradient along line) maxdelta = 0; for (i = 0; i < n; i++) { - delta = c*s[i]; + delta = c * s[i]; if (delta > maxdelta) { maxdelta = delta; @@ -1996,14 +1953,13 @@ LegacySimulator::do_lbfgs() { stepsize *= 0.1; } - } - while (maxdelta > inputrec->em_stepsize); + } while (maxdelta > inputrec->em_stepsize); // Take a trial step and move the coordinate array xc[] to position C - real *xc = static_cast(sc->s.x.rvec_array()[0]); + real* xc = static_cast(sc->s.x.rvec_array()[0]); for (i = 0; i < n; i++) { - xc[i] = lastx[i] + c*s[i]; + xc[i] = lastx[i] + c * s[i]; } neval++; @@ -2011,10 +1967,10 @@ LegacySimulator::do_lbfgs() energyEvaluator.run(sc, mu_tot, vir, pres, step, FALSE); // Calc line gradient in position C - real *fc = static_cast(sc->f.rvec_array()[0]); + real* fc = static_cast(sc->f.rvec_array()[0]); for (gpc = 0, i = 0; i < n; i++) { - gpc -= s[i]*fc[i]; /* f is negative gradient, thus the sign */ + gpc -= s[i] * fc[i]; /* f is negative gradient, thus the sign */ } /* Sum the gradient along the line across CPUs */ if (PAR(cr)) @@ -2025,7 +1981,7 @@ LegacySimulator::do_lbfgs() // This is the max amount of increase in energy we tolerate. // By allowing VERY small changes (close to numerical precision) we // frequently find even better (lower) final energies. - tmp = std::sqrt(GMX_REAL_EPS)*fabs(sa->epot); + tmp = std::sqrt(GMX_REAL_EPS) * fabs(sa->epot); // Accept the step if the energy is lower in the new position C (compared to A), // or if it is not significantly higher and the line derivative is still negative. @@ -2065,11 +2021,11 @@ LegacySimulator::do_lbfgs() // inside the interval. if (gpa < 0 && gpc > 0) { - b = a + gpa*(a-c)/(gpc-gpa); + b = a + gpa * (a - c) / (gpc - gpa); } else { - b = 0.5*(a+c); + b = 0.5 * (a + c); } /* safeguard if interpolation close to machine accuracy causes errors: @@ -2077,14 +2033,14 @@ LegacySimulator::do_lbfgs() */ if (b <= a || b >= c) { - b = 0.5*(a+c); + b = 0.5 * (a + c); } // Take a trial step to point B - real *xb = static_cast(sb->s.x.rvec_array()[0]); + real* xb = static_cast(sb->s.x.rvec_array()[0]); for (i = 0; i < n; i++) { - xb[i] = lastx[i] + b*s[i]; + xb[i] = lastx[i] + b * s[i]; } neval++; @@ -2093,11 +2049,10 @@ LegacySimulator::do_lbfgs() fnorm = sb->fnorm; // Calculate gradient in point B - real *fb = static_cast(sb->f.rvec_array()[0]); + real* fb = static_cast(sb->f.rvec_array()[0]); for (gpb = 0, i = 0; i < n; i++) { - gpb -= s[i]*fb[i]; /* f is negative gradient, thus the sign */ - + gpb -= s[i] * fb[i]; /* f is negative gradient, thus the sign */ } /* Sum the gradient along the line across CPUs */ if (PAR(cr)) @@ -2110,14 +2065,14 @@ LegacySimulator::do_lbfgs() if (gpb > 0) { /* Replace c endpoint with b */ - c = b; + c = b; /* copy state b to c */ *sc = *sb; } else { /* Replace a endpoint with b */ - a = b; + a = b; /* copy state b to a */ *sa = *sb; } @@ -2128,8 +2083,7 @@ LegacySimulator::do_lbfgs() * Never run more than 20 steps, no matter what. */ nminstep++; - } - while ((sb->epot > sa->epot || sb->epot > sc->epot) && (nminstep < 20)); + } while ((sb->epot > sa->epot || sb->epot > sc->epot) && (nminstep < 20)); if (std::fabs(sb->epot - Epot0) < GMX_REAL_EPS || nminstep >= 20) { @@ -2153,7 +2107,7 @@ LegacySimulator::do_lbfgs() dx[point][i] = ff[i]; } /* Reset stepsize */ - stepsize = 1.0/fnorm; + stepsize = 1.0 / fnorm; continue; } } @@ -2172,7 +2126,6 @@ LegacySimulator::do_lbfgs() ems = *sa; step_taken = a; } - } else { @@ -2194,7 +2147,7 @@ LegacySimulator::do_lbfgs() for (i = 0; i < n; i++) { - dg[point][i] = lastf[i]-ff[i]; + dg[point][i] = lastf[i] - ff[i]; dx[point][i] *= step_taken; } @@ -2202,13 +2155,13 @@ LegacySimulator::do_lbfgs() dgdx = 0; for (i = 0; i < n; i++) { - dgdg += dg[point][i]*dg[point][i]; - dgdx += dg[point][i]*dx[point][i]; + dgdg += dg[point][i] * dg[point][i]; + dgdx += dg[point][i] * dx[point][i]; } - diag = dgdx/dgdg; + diag = dgdx / dgdg; - rho[point] = 1.0/dgdx; + rho[point] = 1.0 / dgdx; point++; if (point >= nmaxcorr) @@ -2230,20 +2183,20 @@ LegacySimulator::do_lbfgs() cp--; if (cp < 0) { - cp = ncorr-1; + cp = ncorr - 1; } sq = 0; for (i = 0; i < n; i++) { - sq += dx[cp][i]*p[i]; + sq += dx[cp][i] * p[i]; } - alpha[cp] = rho[cp]*sq; + alpha[cp] = rho[cp] * sq; for (i = 0; i < n; i++) { - p[i] -= alpha[cp]*dg[cp][i]; + p[i] -= alpha[cp] * dg[cp][i]; } } @@ -2258,15 +2211,15 @@ LegacySimulator::do_lbfgs() yr = 0; for (i = 0; i < n; i++) { - yr += p[i]*dg[cp][i]; + yr += p[i] * dg[cp][i]; } - beta = rho[cp]*yr; - beta = alpha[cp]-beta; + beta = rho[cp] * yr; + beta = alpha[cp] - beta; for (i = 0; i < n; i++) { - p[i] += beta*dx[cp][i]; + p[i] += beta * dx[cp][i]; } cp++; @@ -2294,15 +2247,15 @@ LegacySimulator::do_lbfgs() if (mdrunOptions.verbose) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", - step, ems.epot, ems.fnorm/sqrtNumAtoms, ems.fmax, ems.a_fmax + 1); + fprintf(stderr, "\rStep %d, Epot=%12.6e, Fnorm=%9.3e, Fmax=%9.3e (atom %d)\n", step, + ems.epot, ems.fnorm / sqrtNumAtoms, ems.fmax, ems.a_fmax + 1); fflush(stderr); } /* Store the new (lower) energies */ matrix nullBox = {}; - energyOutput.addDataAtEnergyStep(false, false, static_cast(step), - mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox, - nullptr, nullptr, vir, pres, nullptr, mu_tot, constr); + energyOutput.addDataAtEnergyStep(false, false, static_cast(step), mdatoms->tmass, + enerd, nullptr, nullptr, nullptr, nullBox, nullptr, + nullptr, vir, pres, nullptr, mu_tot, constr); do_log = do_per_step(step, inputrec->nstlog); do_ene = do_per_step(step, inputrec->nstenergy); @@ -2314,8 +2267,7 @@ LegacySimulator::do_lbfgs() energyOutput.printHeader(fplog, step, step); } energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE, - do_log ? fplog : nullptr, step, step, - fcd, nullptr); + do_log ? fplog : nullptr, step, step, fcd, nullptr); } /* Send x and E to IMD client, if bIMD is TRUE. */ @@ -2332,19 +2284,17 @@ LegacySimulator::do_lbfgs() */ converged = converged || (ems.fmax < inputrec->em_tol); - } /* End of the loop */ + } /* End of the loop */ if (converged) { step--; /* we never took that last step in this case */ - } if (ems.fmax > inputrec->em_tol) { if (MASTER(cr)) { - warn_step(fplog, inputrec->em_tol, ems.fmax, - step-1 == number_steps, FALSE); + warn_step(fplog, inputrec->em_tol, ems.fmax, step - 1 == number_steps, FALSE); } converged = FALSE; } @@ -2359,8 +2309,7 @@ LegacySimulator::do_lbfgs() if (!do_ene || !do_log) /* Write final energy file entries */ { energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE, - !do_log ? fplog : nullptr, step, step, - fcd, nullptr); + !do_log ? fplog : nullptr, step, step, fcd, nullptr); } /* Print some stuff... */ @@ -2378,17 +2327,14 @@ LegacySimulator::do_lbfgs() */ do_x = !do_per_step(step, inputrec->nstxout); do_f = !do_per_step(step, inputrec->nstfout); - write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), - top_global, inputrec, step, - &ems, state_global, observablesHistory); + write_em_traj(fplog, cr, outf, do_x, do_f, ftp2fn(efSTO, nfile, fnm), top_global, inputrec, + step, &ems, state_global, observablesHistory); if (MASTER(cr)) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - print_converged(stderr, LBFGS, inputrec->em_tol, step, converged, - number_steps, &ems, sqrtNumAtoms); - print_converged(fplog, LBFGS, inputrec->em_tol, step, converged, - number_steps, &ems, sqrtNumAtoms); + print_converged(stderr, LBFGS, inputrec->em_tol, step, converged, number_steps, &ems, sqrtNumAtoms); + print_converged(fplog, LBFGS, inputrec->em_tol, step, converged, number_steps, &ems, sqrtNumAtoms); fprintf(fplog, "\nPerformed %d energy evaluations in total.\n", neval); } @@ -2399,43 +2345,43 @@ LegacySimulator::do_lbfgs() walltime_accounting_set_nsteps_done(walltime_accounting, step); } -void -LegacySimulator::do_steep() +void LegacySimulator::do_steep() { - const char *SD = "Steepest Descents"; + const char* SD = "Steepest Descents"; gmx_localtop_t top; gmx_global_stat_t gstat; - t_graph *graph; + t_graph* graph; real stepsize; real ustep; gmx_bool bDone, bAbort, do_x, do_f; tensor vir, pres; - rvec mu_tot = {0}; + rvec mu_tot = { 0 }; int nsteps; int count = 0; int steps_accepted = 0; auto mdatoms = mdAtoms->mdatoms(); - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that activating steepest-descent energy minimization via the " - "integrator .mdp option and the command gmx mdrun may " - "be available in a different form in a future version of GROMACS, " - "e.g. gmx minimize and an .mdp option."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that activating steepest-descent energy minimization via the " + "integrator .mdp option and the command gmx mdrun may " + "be available in a different form in a future version of GROMACS, " + "e.g. gmx minimize and an .mdp option."); /* Create 2 states on the stack and extract pointers that we will swap */ - em_state_t s0 {}, s1 {}; - em_state_t *s_min = &s0; - em_state_t *s_try = &s1; + em_state_t s0{}, s1{}; + em_state_t* s_min = &s0; + em_state_t* s_try = &s1; /* Init em and store the local state in s_try */ - init_em(fplog, mdlog, SD, cr, inputrec, imdSession, - pull_work, - state_global, top_global, s_try, &top, - nrnb, fr, &graph, mdAtoms, &gstat, - vsite, constr, nullptr); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, top_global, nullptr, wcycle, - StartingBehavior::NewSimulation); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr, false, mdModulesNotifier); + init_em(fplog, mdlog, SD, cr, inputrec, imdSession, pull_work, state_global, top_global, s_try, + &top, nrnb, fr, &graph, mdAtoms, &gstat, vsite, constr, nullptr); + gmx_mdoutf* outf = + init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + inputrec, top_global, nullptr, wcycle, StartingBehavior::NewSimulation); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, + nullptr, false, mdModulesNotifier); /* Print to log file */ print_em_start(fplog, cr, walltime_accounting, wcycle, SD); @@ -2458,12 +2404,10 @@ LegacySimulator::do_steep() { sp_header(fplog, SD, inputrec->em_tol, nsteps); } - EnergyEvaluator energyEvaluator { - fplog, mdlog, cr, ms, - top_global, &top, - inputrec, imdSession, pull_work, nrnb, wcycle, gstat, - vsite, constr, fcd, graph, - mdAtoms, fr, runScheduleWork, enerd + EnergyEvaluator energyEvaluator{ + fplog, mdlog, cr, ms, top_global, &top, inputrec, + imdSession, pull_work, nrnb, wcycle, gstat, vsite, constr, + fcd, graph, mdAtoms, fr, runScheduleWork, enerd }; /**** HERE STARTS THE LOOP **** @@ -2483,10 +2427,7 @@ LegacySimulator::do_steep() bool validStep = true; if (count > 0) { - validStep = - do_em_step(cr, inputrec, mdatoms, - s_min, stepsize, &s_min->f, s_try, - constr, count); + validStep = do_em_step(cr, inputrec, mdatoms, s_min, stepsize, &s_min->f, s_try, constr, count); } if (validStep) @@ -2515,27 +2456,25 @@ LegacySimulator::do_steep() if (mdrunOptions.verbose) { fprintf(stderr, "Step=%5d, Dmax= %6.1e nm, Epot= %12.5e Fmax= %11.5e, atom= %d%c", - count, ustep, s_try->epot, s_try->fmax, s_try->a_fmax+1, - ( (count == 0) || (s_try->epot < s_min->epot) ) ? '\n' : '\r'); + count, ustep, s_try->epot, s_try->fmax, s_try->a_fmax + 1, + ((count == 0) || (s_try->epot < s_min->epot)) ? '\n' : '\r'); fflush(stderr); } - if ( (count == 0) || (s_try->epot < s_min->epot) ) + if ((count == 0) || (s_try->epot < s_min->epot)) { /* Store the new (lower) energies */ matrix nullBox = {}; - energyOutput.addDataAtEnergyStep(false, false, static_cast(count), - mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox, - nullptr, nullptr, vir, pres, nullptr, mu_tot, constr); + energyOutput.addDataAtEnergyStep(false, false, static_cast(count), mdatoms->tmass, + enerd, nullptr, nullptr, nullptr, nullBox, nullptr, + nullptr, vir, pres, nullptr, mu_tot, constr); imdSession->fillEnergyRecord(count, TRUE); const bool do_dr = do_per_step(steps_accepted, inputrec->nstdisreout); const bool do_or = do_per_step(steps_accepted, inputrec->nstorireout); - energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, - do_dr, do_or, - fplog, count, count, - fcd, nullptr); + energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, do_dr, do_or, + fplog, count, count, fcd, nullptr); fflush(fplog); } } @@ -2545,7 +2484,7 @@ LegacySimulator::do_steep() * or if we did random steps! */ - if ( (count == 0) || (s_try->epot < s_min->epot) ) + if ((count == 0) || (s_try->epot < s_min->epot)) { steps_accepted++; @@ -2564,9 +2503,8 @@ LegacySimulator::do_steep() /* Write to trn, if necessary */ do_x = do_per_step(steps_accepted, inputrec->nstxout); do_f = do_per_step(steps_accepted, inputrec->nstfout); - write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, - top_global, inputrec, count, - s_min, state_global, observablesHistory); + write_em_traj(fplog, cr, outf, do_x, do_f, nullptr, top_global, inputrec, count, s_min, + state_global, observablesHistory); } else { @@ -2577,9 +2515,7 @@ LegacySimulator::do_steep() { /* Reload the old state */ em_dd_partition_system(fplog, mdlog, count, cr, top_global, inputrec, imdSession, - pull_work, - s_min, &top, mdAtoms, fr, vsite, constr, - nrnb, wcycle); + pull_work, s_min, &top, mdAtoms, fr, vsite, constr, nrnb, wcycle); } } @@ -2590,7 +2526,7 @@ LegacySimulator::do_steep() if (!bDone) { /* Determine new step */ - stepsize = ustep/s_min->fmax; + stepsize = ustep / s_min->fmax; } /* Check if stepsize is too small, with 1 nm as a characteristic length */ @@ -2602,23 +2538,21 @@ LegacySimulator::do_steep() { if (MASTER(cr)) { - warn_step(fplog, inputrec->em_tol, s_min->fmax, - count == nsteps, constr != nullptr); + warn_step(fplog, inputrec->em_tol, s_min->fmax, count == nsteps, constr != nullptr); } bAbort = TRUE; } /* Send IMD energies and positions, if bIMD is TRUE. */ if (imdSession->run(count, TRUE, state_global->box, - MASTER(cr) ? state_global->x.rvec_array() : nullptr, - 0) && - MASTER(cr)) + MASTER(cr) ? state_global->x.rvec_array() : nullptr, 0) + && MASTER(cr)) { imdSession->sendPositionsAndEnergies(); } count++; - } /* End of the loop */ + } /* End of the loop */ /* Print some data... */ if (MASTER(cr)) @@ -2626,17 +2560,14 @@ LegacySimulator::do_steep() fprintf(stderr, "\nwriting lowest energy coordinates.\n"); } write_em_traj(fplog, cr, outf, TRUE, inputrec->nstfout != 0, ftp2fn(efSTO, nfile, fnm), - top_global, inputrec, count, - s_min, state_global, observablesHistory); + top_global, inputrec, count, s_min, state_global, observablesHistory); if (MASTER(cr)) { double sqrtNumAtoms = sqrt(static_cast(state_global->natoms)); - print_converged(stderr, SD, inputrec->em_tol, count, bDone, nsteps, - s_min, sqrtNumAtoms); - print_converged(fplog, SD, inputrec->em_tol, count, bDone, nsteps, - s_min, sqrtNumAtoms); + print_converged(stderr, SD, inputrec->em_tol, count, bDone, nsteps, s_min, sqrtNumAtoms); + print_converged(fplog, SD, inputrec->em_tol, count, bDone, nsteps, s_min, sqrtNumAtoms); } finish_em(cr, outf, walltime_accounting, wcycle); @@ -2647,55 +2578,56 @@ LegacySimulator::do_steep() walltime_accounting_set_nsteps_done(walltime_accounting, count); } -void -LegacySimulator::do_nm() +void LegacySimulator::do_nm() { - const char *NM = "Normal Mode Analysis"; - int nnodes; - gmx_localtop_t top; - gmx_global_stat_t gstat; - t_graph *graph; - tensor vir, pres; - rvec mu_tot = {0}; - rvec *dfdx; - gmx_bool bSparse; /* use sparse matrix storage format */ - size_t sz; - gmx_sparsematrix_t * sparse_matrix = nullptr; - real * full_matrix = nullptr; + const char* NM = "Normal Mode Analysis"; + int nnodes; + gmx_localtop_t top; + gmx_global_stat_t gstat; + t_graph* graph; + tensor vir, pres; + rvec mu_tot = { 0 }; + rvec* dfdx; + gmx_bool bSparse; /* use sparse matrix storage format */ + size_t sz; + gmx_sparsematrix_t* sparse_matrix = nullptr; + real* full_matrix = nullptr; /* added with respect to mdrun */ - int row, col; - real der_range = 10.0*std::sqrt(GMX_REAL_EPS); - real x_min; - bool bIsMaster = MASTER(cr); - auto mdatoms = mdAtoms->mdatoms(); - - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that activating normal-mode analysis via the integrator " - ".mdp option and the command gmx mdrun may " - "be available in a different form in a future version of GROMACS, " - "e.g. gmx normal-modes."); + int row, col; + real der_range = 10.0 * std::sqrt(GMX_REAL_EPS); + real x_min; + bool bIsMaster = MASTER(cr); + auto mdatoms = mdAtoms->mdatoms(); + + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that activating normal-mode analysis via the integrator " + ".mdp option and the command gmx mdrun may " + "be available in a different form in a future version of GROMACS, " + "e.g. gmx normal-modes."); if (constr != nullptr) { - gmx_fatal(FARGS, "Constraints present with Normal Mode Analysis, this combination is not supported"); + gmx_fatal( + FARGS, + "Constraints present with Normal Mode Analysis, this combination is not supported"); } - gmx_shellfc_t *shellfc; + gmx_shellfc_t* shellfc; - em_state_t state_work {}; + em_state_t state_work{}; /* Init em and store the local state in state_minimum */ - init_em(fplog, mdlog, NM, cr, inputrec, imdSession, - pull_work, - state_global, top_global, &state_work, &top, - nrnb, fr, &graph, mdAtoms, &gstat, - vsite, constr, &shellfc); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, top_global, nullptr, wcycle, - StartingBehavior::NewSimulation); + init_em(fplog, mdlog, NM, cr, inputrec, imdSession, pull_work, state_global, top_global, + &state_work, &top, nrnb, fr, &graph, mdAtoms, &gstat, vsite, constr, &shellfc); + gmx_mdoutf* outf = + init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + inputrec, top_global, nullptr, wcycle, StartingBehavior::NewSimulation); std::vector atom_index = get_atom_index(top_global); - std::vector fneg(atom_index.size(), {0, 0, 0}); + std::vector fneg(atom_index.size(), { 0, 0, 0 }); snew(dfdx, atom_index.size()); #if !GMX_DOUBLE @@ -2717,13 +2649,15 @@ LegacySimulator::do_nm() */ if (EEL_FULL(fr->ic->eeltype) || fr->rlist == 0.0) { - GMX_LOG(mdlog.warning).appendText("Non-cutoff electrostatics used, forcing full Hessian format."); + GMX_LOG(mdlog.warning) + .appendText("Non-cutoff electrostatics used, forcing full Hessian format."); bSparse = FALSE; } else if (atom_index.size() < 1000) { - GMX_LOG(mdlog.warning).appendTextFormatted("Small system size (N=%zu), using full Hessian format.", - atom_index.size()); + GMX_LOG(mdlog.warning) + .appendTextFormatted("Small system size (N=%zu), using full Hessian format.", + atom_index.size()); bSparse = FALSE; } else @@ -2733,25 +2667,25 @@ LegacySimulator::do_nm() } /* Number of dimensions, based on real atoms, that is not vsites or shell */ - sz = DIM*atom_index.size(); + sz = DIM * atom_index.size(); fprintf(stderr, "Allocating Hessian memory...\n\n"); if (bSparse) { - sparse_matrix = gmx_sparsematrix_init(sz); + sparse_matrix = gmx_sparsematrix_init(sz); sparse_matrix->compressed_symmetric = TRUE; } else { - snew(full_matrix, sz*sz); + snew(full_matrix, sz * sz); } /* Write start time and temperature */ print_em_start(fplog, cr, walltime_accounting, wcycle, NM); /* fudge nr of steps to nr of atoms */ - inputrec->nsteps = atom_index.size()*2; + inputrec->nsteps = atom_index.size() * 2; if (bIsMaster) { @@ -2763,12 +2697,10 @@ LegacySimulator::do_nm() /* Make evaluate_energy do a single node force calculation */ cr->nnodes = 1; - EnergyEvaluator energyEvaluator { - fplog, mdlog, cr, ms, - top_global, &top, - inputrec, imdSession, pull_work, nrnb, wcycle, gstat, - vsite, constr, fcd, graph, - mdAtoms, fr, runScheduleWork, enerd + EnergyEvaluator energyEvaluator{ + fplog, mdlog, cr, ms, top_global, &top, inputrec, + imdSession, pull_work, nrnb, wcycle, gstat, vsite, constr, + fcd, graph, mdAtoms, fr, runScheduleWork, enerd }; energyEvaluator.run(&state_work, mu_tot, vir, pres, -1, TRUE); cr->nnodes = nnodes; @@ -2779,11 +2711,12 @@ LegacySimulator::do_nm() GMX_LOG(mdlog.warning).appendTextFormatted("Maximum force:%12.5e", state_work.fmax); if (state_work.fmax > 1.0e-3) { - GMX_LOG(mdlog.warning).appendText( - "The force is probably not small enough to " - "ensure that you are at a minimum.\n" - "Be aware that negative eigenvalues may occur\n" - "when the resulting matrix is diagonalized."); + GMX_LOG(mdlog.warning) + .appendText( + "The force is probably not small enough to " + "ensure that you are at a minimum.\n" + "Be aware that negative eigenvalues may occur\n" + "when the resulting matrix is diagonalized."); } /*********************************************************** @@ -2804,9 +2737,9 @@ LegacySimulator::do_nm() size_t atom = atom_index[aid]; for (size_t d = 0; d < DIM; d++) { - int64_t step = 0; - int force_flags = GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES; - double t = 0; + int64_t step = 0; + int force_flags = GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES; + double t = 0; x_min = state_work_x[atom][d]; @@ -2826,53 +2759,28 @@ LegacySimulator::do_nm() if (shellfc) { /* Now is the time to relax the shells */ - relax_shell_flexcon(fplog, - cr, - ms, - mdrunOptions.verbose, - nullptr, - step, - inputrec, - imdSession, - pull_work, - bNS, - force_flags, - &top, - constr, - enerd, - fcd, - state_work.s.natoms, - state_work.s.x.arrayRefWithPadding(), - state_work.s.v.arrayRefWithPadding(), - state_work.s.box, - state_work.s.lambda, - &state_work.s.hist, - state_work.f.arrayRefWithPadding(), - vir, - mdatoms, - nrnb, - wcycle, - graph, - shellfc, - fr, - runScheduleWork, - t, - mu_tot, - vsite, - DDBalanceRegionHandler(nullptr)); + relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, nullptr, step, inputrec, + imdSession, pull_work, bNS, force_flags, &top, constr, enerd, + fcd, state_work.s.natoms, state_work.s.x.arrayRefWithPadding(), + state_work.s.v.arrayRefWithPadding(), state_work.s.box, + state_work.s.lambda, &state_work.s.hist, + state_work.f.arrayRefWithPadding(), vir, mdatoms, nrnb, + wcycle, graph, shellfc, fr, runScheduleWork, t, mu_tot, + vsite, DDBalanceRegionHandler(nullptr)); bNS = false; step++; } else { - energyEvaluator.run(&state_work, mu_tot, vir, pres, aid*2+dx, FALSE); + energyEvaluator.run(&state_work, mu_tot, vir, pres, aid * 2 + dx, FALSE); } cr->nnodes = nnodes; if (dx == 0) { - std::copy(state_work_f.begin(), state_work_f.begin()+atom_index.size(), fneg.begin()); + std::copy(state_work_f.begin(), state_work_f.begin() + atom_index.size(), + fneg.begin()); } } @@ -2883,52 +2791,50 @@ LegacySimulator::do_nm() { for (size_t k = 0; (k < DIM); k++) { - dfdx[j][k] = - -(state_work_f[atom_index[j]][k] - fneg[j][k])/(2*der_range); + dfdx[j][k] = -(state_work_f[atom_index[j]][k] - fneg[j][k]) / (2 * der_range); } } if (!bIsMaster) { #if GMX_MPI -#define mpi_type GMX_MPI_REAL - MPI_Send(dfdx[0], atom_index.size()*DIM, mpi_type, MASTER(cr), - cr->nodeid, cr->mpi_comm_mygroup); +# define mpi_type GMX_MPI_REAL + MPI_Send(dfdx[0], atom_index.size() * DIM, mpi_type, MASTER(cr), cr->nodeid, + cr->mpi_comm_mygroup); #endif } else { - for (index node = 0; (node < nnodes && aid+node < ssize(atom_index)); node++) + for (index node = 0; (node < nnodes && aid + node < ssize(atom_index)); node++) { if (node > 0) { #if GMX_MPI MPI_Status stat; - MPI_Recv(dfdx[0], atom_index.size()*DIM, mpi_type, node, node, + MPI_Recv(dfdx[0], atom_index.size() * DIM, mpi_type, node, node, cr->mpi_comm_mygroup, &stat); -#undef mpi_type +# undef mpi_type #endif } - row = (aid + node)*DIM + d; + row = (aid + node) * DIM + d; for (size_t j = 0; j < atom_index.size(); j++) { for (size_t k = 0; k < DIM; k++) { - col = j*DIM + k; + col = j * DIM + k; if (bSparse) { if (col >= row && dfdx[j][k] != 0.0) { - gmx_sparsematrix_increment_value(sparse_matrix, - row, col, dfdx[j][k]); + gmx_sparsematrix_increment_value(sparse_matrix, row, col, dfdx[j][k]); } } else { - full_matrix[row*sz+col] = dfdx[j][k]; + full_matrix[row * sz + col] = dfdx[j][k]; } } } @@ -2944,8 +2850,7 @@ LegacySimulator::do_nm() if (bIsMaster && mdrunOptions.verbose) { fprintf(stderr, "\rFinished step %d out of %td", - std::min(atom+nnodes, atom_index.size()), - ssize(atom_index)); + std::min(atom + nnodes, atom_index.size()), ssize(atom_index)); fflush(stderr); } } @@ -2958,7 +2863,7 @@ LegacySimulator::do_nm() finish_em(cr, outf, walltime_accounting, wcycle); - walltime_accounting_set_nsteps_done(walltime_accounting, atom_index.size()*2); + walltime_accounting_set_nsteps_done(walltime_accounting, atom_index.size() * 2); } } // namespace gmx diff --git a/src/gromacs/mdrun/minimize.h b/src/gromacs/mdrun/minimize.h index bb72216af8..836760e16d 100644 --- a/src/gromacs/mdrun/minimize.h +++ b/src/gromacs/mdrun/minimize.h @@ -45,6 +45,6 @@ namespace gmx { -} // namespace gmx +} // namespace gmx #endif // GMX_MDRUN_MINIMIZE_H diff --git a/src/gromacs/mdrun/replicaexchange.cpp b/src/gromacs/mdrun/replicaexchange.cpp index 9ff7fa478b..9ff4b3817d 100644 --- a/src/gromacs/mdrun/replicaexchange.cpp +++ b/src/gromacs/mdrun/replicaexchange.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -76,11 +76,16 @@ constexpr int c_probabilityCutoff = 100; /* we don't bother evaluating if events are more rare than exp(-100) = 3.7x10^-44 */ //! Rank in the multisimulation -#define MSRANK(ms, nodeid) (nodeid) +#define MSRANK(ms, nodeid) (nodeid) //! Enum for replica exchange flavours -enum { - ereTEMP, ereLAMBDA, ereENDSINGLE, ereTL, ereNR +enum +{ + ereTEMP, + ereLAMBDA, + ereENDSINGLE, + ereTL, + ereNR }; /*! \brief Strings describing replica exchange flavours. * @@ -92,72 +97,72 @@ enum { * 'lambda_and_pressure', 'temperature_lambda_pressure'?; Let's wait * until we feel better about the pressure control methods giving * exact ensembles. Right now, we assume constant pressure */ -static const char *erename[ereNR] = { "temperature", "lambda", "end_single_marker", "temperature and lambda"}; +static const char* erename[ereNR] = { "temperature", "lambda", "end_single_marker", + "temperature and lambda" }; //! Working data for replica exchange. struct gmx_repl_ex { //! Replica ID - int repl; + int repl; //! Total number of replica - int nrepl; + int nrepl; //! Temperature - real temp; + real temp; //! Replica exchange type from ere enum - int type; + int type; //! Quantity, e.g. temperature or lambda; first index is ere, second index is replica ID - real **q; + real** q; //! Use constant pressure and temperature - gmx_bool bNPT; + gmx_bool bNPT; //! Replica pressures - real *pres; + real* pres; //! Replica indices - int *ind; + int* ind; //! Used for keeping track of all the replica swaps - int *allswaps; + int* allswaps; //! Replica exchange interval (number of steps) - int nst; + int nst; //! Number of exchanges per interval - int nex; + int nex; //! Random seed - int seed; + int seed; //! Number of even and odd replica change attempts - int nattempt[2]; + int nattempt[2]; //! Sum of probabilities - real *prob_sum; + real* prob_sum; //! Number of moves between replicas i and j - int **nmoves; + int** nmoves; //! i-th element of the array is the number of exchanges between replica i-1 and i - int *nexchange; + int* nexchange; /*! \brief Helper arrays for replica exchange; allocated here * so they don't have to be allocated each time */ //! \{ - int *destinations; - int **cyclic; - int **order; - int *tmpswap; - gmx_bool *incycle; - gmx_bool *bEx; + int* destinations; + int** cyclic; + int** order; + int* tmpswap; + gmx_bool* incycle; + gmx_bool* bEx; //! \} //! Helper arrays to hold the quantities that are exchanged. //! \{ - real *prob; - real *Epot; - real *beta; - real *Vol; - real **de; + real* prob; + real* Epot; + real* beta; + real* Vol; + real** de; //! \} }; // TODO We should add Doxygen here some time. //! \cond -static gmx_bool repl_quantity(const gmx_multisim_t *ms, - struct gmx_repl_ex *re, int ere, real q) +static gmx_bool repl_quantity(const gmx_multisim_t* ms, struct gmx_repl_ex* re, int ere, real q) { - real *qall; + real* qall; gmx_bool bDiff; int s; @@ -189,16 +194,15 @@ static gmx_bool repl_quantity(const gmx_multisim_t *ms, return bDiff; } -gmx_repl_ex_t -init_replica_exchange(FILE *fplog, - const gmx_multisim_t *ms, - int numAtomsInSystem, - const t_inputrec *ir, - const ReplicaExchangeParameters &replExParams) +gmx_repl_ex_t init_replica_exchange(FILE* fplog, + const gmx_multisim_t* ms, + int numAtomsInSystem, + const t_inputrec* ir, + const ReplicaExchangeParameters& replExParams) { real pres; int i, j; - struct gmx_repl_ex *re; + struct gmx_repl_ex* re; gmx_bool bTemp; gmx_bool bLambda = FALSE; @@ -206,7 +210,9 @@ init_replica_exchange(FILE *fplog, if (!isMultiSim(ms) || ms->nsim == 1) { - gmx_fatal(FARGS, "Nothing to exchange with only one replica, maybe you forgot to set the -multidir option of mdrun?"); + gmx_fatal(FARGS, + "Nothing to exchange with only one replica, maybe you forgot to set the " + "-multidir option of mdrun?"); } if (replExParams.numExchanges < 0) { @@ -229,8 +235,8 @@ init_replica_exchange(FILE *fplog, snew(re, 1); - re->repl = ms->sim; - re->nrepl = ms->nsim; + re->repl = ms->sim; + re->nrepl = ms->nsim; snew(re->q, ereENDSINGLE); fprintf(fplog, "Repl There are %d replicas:\n", re->nrepl); @@ -241,13 +247,12 @@ init_replica_exchange(FILE *fplog, */ check_multi_int(fplog, ms, numAtomsInSystem, "the number of atoms", FALSE); check_multi_int(fplog, ms, ir->eI, "the integrator", FALSE); - check_multi_int64(fplog, ms, ir->init_step+ir->nsteps, "init_step+nsteps", FALSE); + check_multi_int64(fplog, ms, ir->init_step + ir->nsteps, "init_step+nsteps", FALSE); const int nst = replExParams.exchangeInterval; - check_multi_int64(fplog, ms, (ir->init_step+nst-1)/nst, + check_multi_int64(fplog, ms, (ir->init_step + nst - 1) / nst, "first exchange step: init_step/-replex", FALSE); check_multi_int(fplog, ms, ir->etc, "the temperature coupling", FALSE); - check_multi_int(fplog, ms, ir->opts.ngtc, - "the number of temperature coupling groups", FALSE); + check_multi_int(fplog, ms, ir->opts.ngtc, "the number of temperature coupling groups", FALSE); check_multi_int(fplog, ms, ir->epc, "the pressure coupling", FALSE); check_multi_int(fplog, ms, ir->efep, "free energy", FALSE); check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE); @@ -257,8 +262,12 @@ init_replica_exchange(FILE *fplog, { if (ir->opts.ref_t[i] != re->temp) { - fprintf(fplog, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); - fprintf(stderr, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); + fprintf(fplog, + "\nWARNING: The temperatures of the different temperature coupling groups are " + "not identical\n\n"); + fprintf(stderr, + "\nWARNING: The temperatures of the different temperature coupling groups are " + "not identical\n\n"); } } @@ -268,9 +277,11 @@ init_replica_exchange(FILE *fplog, { bLambda = repl_quantity(ms, re, ereLAMBDA, static_cast(ir->fepvals->init_fep_state)); } - if (re->type == -1) /* nothing was assigned */ + if (re->type == -1) /* nothing was assigned */ { - gmx_fatal(FARGS, "The properties of the %d systems are all the same, there is nothing to exchange", re->nrepl); + gmx_fatal(FARGS, + "The properties of the %d systems are all the same, there is nothing to exchange", + re->nrepl); } if (bLambda && bTemp) { @@ -288,13 +299,15 @@ init_replica_exchange(FILE *fplog, } if (ir->etc == etcBERENDSEN) { - gmx_fatal(FARGS, "REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead", + gmx_fatal(FARGS, + "REMD with the %s thermostat does not produce correct potential energy " + "distributions, consider using the %s thermostat instead", ETCOUPLTYPE(ir->etc), ETCOUPLTYPE(etcVRESCALE)); } } if (bLambda) { - if (ir->fepvals->delta_lambda != 0) /* check this? */ + if (ir->fepvals->delta_lambda != 0) /* check this? */ { gmx_fatal(FARGS, "delta_lambda is not zero"); } @@ -338,7 +351,7 @@ init_replica_exchange(FILE *fplog, for (i = 0; i < re->nrepl; i++) { - for (j = i+1; j < re->nrepl; j++) + for (j = i + 1; j < re->nrepl; j++) { if (re->q[re->type][re->ind[j]] < re->q[re->type][re->ind[i]]) { @@ -346,10 +359,10 @@ init_replica_exchange(FILE *fplog, * is still an issues somewhere. * Note that at this point still re->ind[i]=i. */ - gmx_fatal(FARGS, "Replicas with indices %d < %d have %ss %g > %g, please order your replicas on increasing %s", - i, j, - erename[re->type], - re->q[re->type][i], re->q[re->type][j], + gmx_fatal(FARGS, + "Replicas with indices %d < %d have %ss %g > %g, please order your " + "replicas on increasing %s", + i, j, erename[re->type], re->q[re->type][i], re->q[re->type][j], erename[re->type]); } else if (re->q[re->type][re->ind[j]] == re->q[re->type][re->ind[i]]) @@ -398,8 +411,7 @@ init_replica_exchange(FILE *fplog, } fprintf(fplog, "\n"); break; - default: - gmx_incons("Unknown replica exchange quantity"); + default: gmx_incons("Unknown replica exchange quantity"); } if (re->bNPT) { @@ -411,10 +423,14 @@ init_replica_exchange(FILE *fplog, for (i = 0; i < re->nrepl; i++) { - if ((i > 0) && (re->pres[re->ind[i]] < re->pres[re->ind[i-1]])) + if ((i > 0) && (re->pres[re->ind[i]] < re->pres[re->ind[i - 1]])) { - fprintf(fplog, "\nWARNING: The reference pressures decrease with increasing temperatures\n\n"); - fprintf(stderr, "\nWARNING: The reference pressures decrease with increasing temperatures\n\n"); + fprintf(fplog, + "\nWARNING: The reference pressures decrease with increasing " + "temperatures\n\n"); + fprintf(stderr, + "\nWARNING: The reference pressures decrease with increasing " + "temperatures\n\n"); } } } @@ -459,7 +475,7 @@ init_replica_exchange(FILE *fplog, snew(re->order, re->nrepl); for (i = 0; i < re->nrepl; i++) { - snew(re->cyclic[i], re->nrepl+1); + snew(re->cyclic[i], re->nrepl + 1); snew(re->order[i], re->nrepl); } /* allocate space for the functions storing the data for the replicas */ @@ -479,9 +495,9 @@ init_replica_exchange(FILE *fplog, return re; } -static void exchange_reals(const gmx_multisim_t gmx_unused *ms, int gmx_unused b, real *v, int n) +static void exchange_reals(const gmx_multisim_t gmx_unused* ms, int gmx_unused b, real* v, int n) { - real *buf; + real* buf; int i; if (v) @@ -496,10 +512,9 @@ static void exchange_reals(const gmx_multisim_t gmx_unused *ms, int gmx_unused b { MPI_Request mpi_req; - MPI_Isend(v, n*sizeof(real), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, &mpi_req); - MPI_Recv(buf, n*sizeof(real), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, MPI_STATUS_IGNORE); + MPI_Isend(v, n * sizeof(real), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, &mpi_req); + MPI_Recv(buf, n * sizeof(real), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, + MPI_STATUS_IGNORE); MPI_Wait(&mpi_req, MPI_STATUS_IGNORE); } #endif @@ -512,9 +527,9 @@ static void exchange_reals(const gmx_multisim_t gmx_unused *ms, int gmx_unused b } -static void exchange_doubles(const gmx_multisim_t gmx_unused *ms, int gmx_unused b, double *v, int n) +static void exchange_doubles(const gmx_multisim_t gmx_unused* ms, int gmx_unused b, double* v, int n) { - double *buf; + double* buf; int i; if (v) @@ -529,10 +544,9 @@ static void exchange_doubles(const gmx_multisim_t gmx_unused *ms, int gmx_unused { MPI_Request mpi_req; - MPI_Isend(v, n*sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, &mpi_req); - MPI_Recv(buf, n*sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, MPI_STATUS_IGNORE); + MPI_Isend(v, n * sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, &mpi_req); + MPI_Recv(buf, n * sizeof(double), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, + MPI_STATUS_IGNORE); MPI_Wait(&mpi_req, MPI_STATUS_IGNORE); } #endif @@ -544,9 +558,9 @@ static void exchange_doubles(const gmx_multisim_t gmx_unused *ms, int gmx_unused } } -static void exchange_rvecs(const gmx_multisim_t gmx_unused *ms, int gmx_unused b, rvec *v, int n) +static void exchange_rvecs(const gmx_multisim_t gmx_unused* ms, int gmx_unused b, rvec* v, int n) { - rvec *buf; + rvec* buf; int i; if (v) @@ -561,10 +575,9 @@ static void exchange_rvecs(const gmx_multisim_t gmx_unused *ms, int gmx_unused b { MPI_Request mpi_req; - MPI_Isend(v[0], n*sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, &mpi_req); - MPI_Recv(buf[0], n*sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, - ms->mpi_comm_masters, MPI_STATUS_IGNORE); + MPI_Isend(v[0], n * sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, &mpi_req); + MPI_Recv(buf[0], n * sizeof(rvec), MPI_BYTE, MSRANK(ms, b), 0, ms->mpi_comm_masters, + MPI_STATUS_IGNORE); MPI_Wait(&mpi_req, MPI_STATUS_IGNORE); } #endif @@ -576,12 +589,12 @@ static void exchange_rvecs(const gmx_multisim_t gmx_unused *ms, int gmx_unused b } } -static void exchange_state(const gmx_multisim_t *ms, int b, t_state *state) +static void exchange_state(const gmx_multisim_t* ms, int b, t_state* state) { /* When t_state changes, this code should be updated. */ int ngtc, nnhpres; ngtc = state->ngtc * state->nhchainlength; - nnhpres = state->nnhpres* state->nhchainlength; + nnhpres = state->nnhpres * state->nhchainlength; exchange_rvecs(ms, b, state->box, DIM); exchange_rvecs(ms, b, state->box_rel, DIM); exchange_rvecs(ms, b, state->boxv, DIM); @@ -600,7 +613,7 @@ static void exchange_state(const gmx_multisim_t *ms, int b, t_state *state) exchange_rvecs(ms, b, state->v.rvec_array(), state->natoms); } -static void copy_state_serial(const t_state *src, t_state *dest) +static void copy_state_serial(const t_state* src, t_state* dest) { if (dest != src) { @@ -614,13 +627,13 @@ static void copy_state_serial(const t_state *src, t_state *dest) static void scale_velocities(gmx::ArrayRef velocities, real fac) { - for (auto &v : velocities) + for (auto& v : velocities) { v *= fac; } } -static void print_transition_matrix(FILE *fplog, int n, int **nmoves, const int *nattempt) +static void print_transition_matrix(FILE* fplog, int n, int** nmoves, const int* nattempt) { int i, j, ntot; float Tprint; @@ -630,14 +643,14 @@ static void print_transition_matrix(FILE *fplog, int n, int **nmoves, const int fprintf(fplog, "Repl"); for (i = 0; i < n; i++) { - fprintf(fplog, " "); /* put the title closer to the center */ + fprintf(fplog, " "); /* put the title closer to the center */ } fprintf(fplog, "Empirical Transition Matrix\n"); fprintf(fplog, "Repl"); for (i = 0; i < n; i++) { - fprintf(fplog, "%8d", (i+1)); + fprintf(fplog, "%8d", (i + 1)); } fprintf(fplog, "\n"); @@ -649,7 +662,7 @@ static void print_transition_matrix(FILE *fplog, int n, int **nmoves, const int Tprint = 0.0; if (nmoves[i][j] > 0) { - Tprint = nmoves[i][j]/(2.0*ntot); + Tprint = nmoves[i][j] / (2.0 * ntot); } fprintf(fplog, "%8.4f", Tprint); } @@ -657,7 +670,7 @@ static void print_transition_matrix(FILE *fplog, int n, int **nmoves, const int } } -static void print_ind(FILE *fplog, const char *leg, int n, int *ind, const gmx_bool *bEx) +static void print_ind(FILE* fplog, const char* leg, int n, int* ind, const gmx_bool* bEx) { int i; @@ -669,7 +682,7 @@ static void print_ind(FILE *fplog, const char *leg, int n, int *ind, const gmx_b fprintf(fplog, "\n"); } -static void print_allswitchind(FILE *fplog, int n, int *pind, int *allswaps, int *tmpswap) +static void print_allswitchind(FILE* fplog, int n, int* pind, int* allswaps, int* tmpswap) { int i; @@ -708,7 +721,7 @@ static void print_allswitchind(FILE *fplog, int n, int *pind, int *allswaps, int fprintf(fplog, "\n\n"); } -static void print_prob(FILE *fplog, const char *leg, int n, real *prob) +static void print_prob(FILE* fplog, const char* leg, int n, real* prob) { int i; char buf[8]; @@ -719,7 +732,7 @@ static void print_prob(FILE *fplog, const char *leg, int n, real *prob) if (prob[i] >= 0) { sprintf(buf, "%4.2f", prob[i]); - fprintf(fplog, " %3s", buf[0] == '1' ? "1.0" : buf+1); + fprintf(fplog, " %3s", buf[0] == '1' ? "1.0" : buf + 1); } else { @@ -729,7 +742,7 @@ static void print_prob(FILE *fplog, const char *leg, int n, real *prob) fprintf(fplog, "\n"); } -static void print_count(FILE *fplog, const char *leg, int n, int *count) +static void print_count(FILE* fplog, const char* leg, int n, int* count) { int i; @@ -741,14 +754,14 @@ static void print_count(FILE *fplog, const char *leg, int n, int *count) fprintf(fplog, "\n"); } -static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int a, int b, int ap, int bp) +static real calc_delta(FILE* fplog, gmx_bool bPrint, struct gmx_repl_ex* re, int a, int b, int ap, int bp) { real ediff, dpV, delta = 0; - real *Epot = re->Epot; - real *Vol = re->Vol; - real **de = re->de; - real *beta = re->beta; + real* Epot = re->Epot; + real* Vol = re->Vol; + real** de = re->de; + real* beta = re->beta; /* Two cases; we are permuted and not. In all cases, setting ap = a and bp = b will reduce to the non permuted case */ @@ -760,7 +773,7 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int * Okabe et. al. Chem. Phys. Lett. 335 (2001) 435-439 */ ediff = Epot[b] - Epot[a]; - delta = -(beta[bp] - beta[ap])*ediff; + delta = -(beta[bp] - beta[ap]) * ediff; break; case ereLAMBDA: /* two cases: when we are permuted, and not. */ @@ -788,7 +801,7 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int */ ediff = (de[bp][a] - de[ap][a]) + (de[ap][b] - de[bp][b]); - delta = ediff*beta[a]; /* assume all same temperature in this case */ + delta = ediff * beta[a]; /* assume all same temperature in this case */ break; case ereTL: /* not permuted: */ @@ -816,10 +829,10 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int + beta_pb (H_a(x_a) - H_b(x_b)) - beta_ap (H_a(x_a) - H_b(x_b)) = ([beta_bp de[bp][a] - beta_ap de[ap][a]) + beta_ap de[ap][b] - beta_bp de[bp][b]) + (beta_pb-beta_ap)(H_a(x_a) - H_b(x_b)) */ - delta = beta[bp]*(de[bp][a] - de[bp][b]) + beta[ap]*(de[ap][b] - de[ap][a]) - (beta[bp]-beta[ap])*(Epot[b]-Epot[a]); + delta = beta[bp] * (de[bp][a] - de[bp][b]) + beta[ap] * (de[ap][b] - de[ap][a]) + - (beta[bp] - beta[ap]) * (Epot[b] - Epot[a]); break; - default: - gmx_incons("Unknown replica exchange quantity"); + default: gmx_incons("Unknown replica exchange quantity"); } if (bPrint) { @@ -828,7 +841,7 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int if (re->bNPT) { /* revist the calculation for 5.0. Might be some improvements. */ - dpV = (beta[ap]*re->pres[ap]-beta[bp]*re->pres[bp])*(Vol[b]-Vol[a])/PRESFAC; + dpV = (beta[ap] * re->pres[ap] - beta[bp] * re->pres[bp]) * (Vol[b] - Vol[a]) / PRESFAC; if (bPrint) { fprintf(fplog, " dpV = %10.3e d = %10.3e\n", dpV, delta + dpV); @@ -838,29 +851,28 @@ static real calc_delta(FILE *fplog, gmx_bool bPrint, struct gmx_repl_ex *re, int return delta; } -static void -test_for_replica_exchange(FILE *fplog, - const gmx_multisim_t *ms, - struct gmx_repl_ex *re, - const gmx_enerdata_t *enerd, - real vol, - int64_t step, - real time) +static void test_for_replica_exchange(FILE* fplog, + const gmx_multisim_t* ms, + struct gmx_repl_ex* re, + const gmx_enerdata_t* enerd, + real vol, + int64_t step, + real time) { - int m, i, j, a, b, ap, bp, i0, i1, tmp; - real delta = 0; - gmx_bool bPrint, bMultiEx; - gmx_bool *bEx = re->bEx; - real *prob = re->prob; - int *pind = re->destinations; /* permuted index */ - gmx_bool bEpot = FALSE; - gmx_bool bDLambda = FALSE; - gmx_bool bVol = FALSE; - gmx::ThreeFry2x64<64> rng(re->seed, gmx::RandomDomain::ReplicaExchange); - gmx::UniformRealDistribution uniformRealDist; - gmx::UniformIntDistribution uniformNreplDist(0, re->nrepl-1); - - bMultiEx = (re->nex > 1); /* multiple exchanges at each state */ + int m, i, j, a, b, ap, bp, i0, i1, tmp; + real delta = 0; + gmx_bool bPrint, bMultiEx; + gmx_bool* bEx = re->bEx; + real* prob = re->prob; + int* pind = re->destinations; /* permuted index */ + gmx_bool bEpot = FALSE; + gmx_bool bDLambda = FALSE; + gmx_bool bVol = FALSE; + gmx::ThreeFry2x64<64> rng(re->seed, gmx::RandomDomain::ReplicaExchange); + gmx::UniformRealDistribution uniformRealDist; + gmx::UniformIntDistribution uniformNreplDist(0, re->nrepl - 1); + + bMultiEx = (re->nex > 1); /* multiple exchanges at each state */ fprintf(fplog, "Replica exchange at step %" PRId64 " time %.5f\n", step, time); if (re->bNPT) @@ -869,8 +881,8 @@ test_for_replica_exchange(FILE *fplog, { re->Vol[i] = 0; } - bVol = TRUE; - re->Vol[re->repl] = vol; + bVol = TRUE; + re->Vol[re->repl] = vol; } if ((re->type == ereTEMP || re->type == ereTL)) { @@ -883,14 +895,14 @@ test_for_replica_exchange(FILE *fplog, /* temperatures of different states*/ for (i = 0; i < re->nrepl; i++) { - re->beta[i] = 1.0/(re->q[ereTEMP][i]*BOLTZ); + re->beta[i] = 1.0 / (re->q[ereTEMP][i] * BOLTZ); } } else { for (i = 0; i < re->nrepl; i++) { - re->beta[i] = 1.0/(re->temp*BOLTZ); /* we have a single temperature */ + re->beta[i] = 1.0 / (re->temp * BOLTZ); /* we have a single temperature */ } } if (re->type == ereLAMBDA || re->type == ereTL) @@ -908,7 +920,8 @@ test_for_replica_exchange(FILE *fplog, } for (i = 0; i < re->nrepl; i++) { - re->de[i][re->repl] = (enerd->enerpart_lambda[static_cast(re->q[ereLAMBDA][i])+1]-enerd->enerpart_lambda[0]); + re->de[i][re->repl] = (enerd->enerpart_lambda[static_cast(re->q[ereLAMBDA][i]) + 1] + - enerd->enerpart_lambda[0]); } } @@ -935,7 +948,7 @@ test_for_replica_exchange(FILE *fplog, pind[i] = re->ind[i]; } - rng.restart( step, 0 ); + rng.restart(step, 0); if (bMultiEx) { @@ -959,7 +972,7 @@ test_for_replica_exchange(FILE *fplog, if (i0 == i1) { nself++; - continue; /* self-exchange, back up and do it again */ + continue; /* self-exchange, back up and do it again */ } a = re->ind[i0]; /* what are the indices of these states? */ @@ -1009,7 +1022,7 @@ test_for_replica_exchange(FILE *fplog, pind[i1] = tmp; } } - re->nattempt[0]++; /* keep track of total permutation trials here */ + re->nattempt[0]++; /* keep track of total permutation trials here */ print_allswitchind(fplog, re->nrepl, pind, re->allswaps, re->tmpswap); } else @@ -1019,7 +1032,7 @@ test_for_replica_exchange(FILE *fplog, m = (step / re->nst) % 2; for (i = 1; i < re->nrepl; i++) { - a = re->ind[i-1]; + a = re->ind[i - 1]; b = re->ind[i]; bPrint = (re->repl == a || re->repl == b); @@ -1053,10 +1066,10 @@ test_for_replica_exchange(FILE *fplog, if (bEx[i]) { /* swap these two */ - tmp = pind[i-1]; - pind[i-1] = pind[i]; - pind[i] = tmp; - re->nexchange[i]++; /* statistics for back compatibility */ + tmp = pind[i - 1]; + pind[i - 1] = pind[i]; + pind[i] = tmp; + re->nexchange[i]++; /* statistics for back compatibility */ } } else @@ -1081,12 +1094,7 @@ test_for_replica_exchange(FILE *fplog, fflush(fplog); /* make sure we can see what the last exchange was */ } -static void -cyclic_decomposition(const int *destinations, - int **cyclic, - gmx_bool *incycle, - const int nrepl, - int *nswap) +static void cyclic_decomposition(const int* destinations, int** cyclic, gmx_bool* incycle, const int nrepl, int* nswap) { int i, j, c, p; @@ -1095,7 +1103,7 @@ cyclic_decomposition(const int *destinations, { incycle[i] = FALSE; } - for (i = 0; i < nrepl; i++) /* one cycle for each replica */ + for (i = 0; i < nrepl; i++) /* one cycle for each replica */ { if (incycle[i]) { @@ -1108,7 +1116,7 @@ cyclic_decomposition(const int *destinations, p = i; for (j = 0; j < nrepl; j++) /* potentially all cycles are part, but we will break first */ { - p = destinations[p]; /* start permuting */ + p = destinations[p]; /* start permuting */ if (p == i) { cyclic[i][c] = -1; @@ -1120,7 +1128,7 @@ cyclic_decomposition(const int *destinations, } else { - cyclic[i][c] = p; /* each permutation gives a new member of the cycle */ + cyclic[i][c] = p; /* each permutation gives a new member of the cycle */ incycle[p] = TRUE; c++; } @@ -1147,11 +1155,7 @@ cyclic_decomposition(const int *destinations, } } -static void -compute_exchange_order(int **cyclic, - int **order, - const int nrepl, - const int maxswap) +static void compute_exchange_order(int** cyclic, int** order, const int nrepl, const int maxswap) { int i, j; @@ -1159,10 +1163,10 @@ compute_exchange_order(int **cyclic, { for (i = 0; i < nrepl; i++) { - if (cyclic[i][j+1] >= 0) + if (cyclic[i][j + 1] >= 0) { - order[cyclic[i][j+1]][j] = cyclic[i][j]; - order[cyclic[i][j]][j] = cyclic[i][j+1]; + order[cyclic[i][j + 1]][j] = cyclic[i][j]; + order[cyclic[i][j]][j] = cyclic[i][j + 1]; } } for (i = 0; i < nrepl; i++) @@ -1194,17 +1198,13 @@ compute_exchange_order(int **cyclic, } } -static void -prepare_to_do_exchange(struct gmx_repl_ex *re, - const int replica_id, - int *maxswap, - gmx_bool *bThisReplicaExchanged) +static void prepare_to_do_exchange(struct gmx_repl_ex* re, const int replica_id, int* maxswap, gmx_bool* bThisReplicaExchanged) { int i, j; /* Hold the cyclic decomposition of the (multiple) replica * exchange. */ gmx_bool bAnyReplicaExchanged = FALSE; - *bThisReplicaExchanged = FALSE; + *bThisReplicaExchanged = FALSE; for (i = 0; i < re->nrepl; i++) { @@ -1247,10 +1247,15 @@ prepare_to_do_exchange(struct gmx_repl_ex *re, } } -gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, - const gmx_multisim_t *ms, struct gmx_repl_ex *re, - t_state *state, const gmx_enerdata_t *enerd, - t_state *state_local, int64_t step, real time) +gmx_bool replica_exchange(FILE* fplog, + const t_commrec* cr, + const gmx_multisim_t* ms, + struct gmx_repl_ex* re, + t_state* state, + const gmx_enerdata_t* enerd, + t_state* state_local, + int64_t step, + real time) { int j; int replica_id = 0; @@ -1264,7 +1269,7 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, if (MASTER(cr)) { - replica_id = re->repl; + replica_id = re->repl; test_for_replica_exchange(fplog, ms, re, enerd, det(state_local->box), step, time); prepare_to_do_exchange(re, replica_id, &maxswap, &bThisReplicaExchanged); } @@ -1275,8 +1280,7 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, if (DOMAINDECOMP(cr)) { #if GMX_MPI - MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr), - cr->mpi_comm_mygroup); + MPI_Bcast(&bThisReplicaExchanged, sizeof(gmx_bool), MPI_BYTE, MASTERRANK(cr), cr->mpi_comm_mygroup); #endif } @@ -1317,10 +1321,9 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, * the velocities. */ if (re->type == ereTEMP || re->type == ereTL) { - scale_velocities(state->v, - std::sqrt(re->q[ereTEMP][replica_id]/re->q[ereTEMP][re->destinations[replica_id]])); + scale_velocities(state->v, std::sqrt(re->q[ereTEMP][replica_id] + / re->q[ereTEMP][re->destinations[replica_id]])); } - } /* With domain decomposition the global state is distributed later */ @@ -1334,27 +1337,27 @@ gmx_bool replica_exchange(FILE *fplog, const t_commrec *cr, return bThisReplicaExchanged; } -void print_replica_exchange_statistics(FILE *fplog, struct gmx_repl_ex *re) +void print_replica_exchange_statistics(FILE* fplog, struct gmx_repl_ex* re) { - int i; + int i; fprintf(fplog, "\nReplica exchange statistics\n"); if (re->nex == 0) { - fprintf(fplog, "Repl %d attempts, %d odd, %d even\n", - re->nattempt[0]+re->nattempt[1], re->nattempt[1], re->nattempt[0]); + fprintf(fplog, "Repl %d attempts, %d odd, %d even\n", re->nattempt[0] + re->nattempt[1], + re->nattempt[1], re->nattempt[0]); fprintf(fplog, "Repl average probabilities:\n"); for (i = 1; i < re->nrepl; i++) { - if (re->nattempt[i%2] == 0) + if (re->nattempt[i % 2] == 0) { re->prob[i] = 0; } else { - re->prob[i] = re->prob_sum[i]/re->nattempt[i%2]; + re->prob[i] = re->prob_sum[i] / re->nattempt[i % 2]; } } print_ind(fplog, "", re->nrepl, re->ind, nullptr); @@ -1367,13 +1370,13 @@ void print_replica_exchange_statistics(FILE *fplog, struct gmx_repl_ex *re) fprintf(fplog, "Repl average number of exchanges:\n"); for (i = 1; i < re->nrepl; i++) { - if (re->nattempt[i%2] == 0) + if (re->nattempt[i % 2] == 0) { re->prob[i] = 0; } else { - re->prob[i] = (static_cast(re->nexchange[i]))/re->nattempt[i%2]; + re->prob[i] = (static_cast(re->nexchange[i])) / re->nattempt[i % 2]; } } print_ind(fplog, "", re->nrepl, re->ind, nullptr); diff --git a/src/gromacs/mdrun/replicaexchange.h b/src/gromacs/mdrun/replicaexchange.h index 8f4211febe..f6bead1071 100644 --- a/src/gromacs/mdrun/replicaexchange.h +++ b/src/gromacs/mdrun/replicaexchange.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,17 +70,16 @@ struct ReplicaExchangeParameters }; //! Abstract type for replica exchange -typedef struct gmx_repl_ex *gmx_repl_ex_t; +typedef struct gmx_repl_ex* gmx_repl_ex_t; /*! \brief Setup function. * * Should only be called on the master ranks */ -gmx_repl_ex_t -init_replica_exchange(FILE *fplog, - const gmx_multisim_t *ms, - int numAtomsInSystem, - const t_inputrec *ir, - const ReplicaExchangeParameters &replExParams); +gmx_repl_ex_t init_replica_exchange(FILE* fplog, + const gmx_multisim_t* ms, + int numAtomsInSystem, + const t_inputrec* ir, + const ReplicaExchangeParameters& replExParams); /*! \brief Attempts replica exchange. * @@ -92,17 +91,19 @@ init_replica_exchange(FILE *fplog, * * \returns TRUE if the state has been exchanged. */ -gmx_bool replica_exchange(FILE *fplog, - const t_commrec *cr, - const gmx_multisim_t *ms, - gmx_repl_ex_t re, - t_state *state, const gmx_enerdata_t *enerd, - t_state *state_local, - int64_t step, real time); +gmx_bool replica_exchange(FILE* fplog, + const t_commrec* cr, + const gmx_multisim_t* ms, + gmx_repl_ex_t re, + t_state* state, + const gmx_enerdata_t* enerd, + t_state* state_local, + int64_t step, + real time); /*! \brief Prints replica exchange statistics to the log file. * * Should only be called on the master ranks */ -void print_replica_exchange_statistics(FILE *fplog, gmx_repl_ex_t re); +void print_replica_exchange_statistics(FILE* fplog, gmx_repl_ex_t re); #endif diff --git a/src/gromacs/mdrun/rerun.cpp b/src/gromacs/mdrun/rerun.cpp index c8453f7683..4ef73be2c0 100644 --- a/src/gromacs/mdrun/rerun.cpp +++ b/src/gromacs/mdrun/rerun.cpp @@ -150,17 +150,17 @@ using gmx::SimulationSignaller; * \param[in] forceRec Force record, used for constructing vsites * \param[in,out] graph The molecular graph, used for constructing vsites when != nullptr */ -static void prepareRerunState(const t_trxframe &rerunFrame, - t_state *globalState, +static void prepareRerunState(const t_trxframe& rerunFrame, + t_state* globalState, bool constructVsites, - const gmx_vsite_t *vsite, - const t_idef &idef, + const gmx_vsite_t* vsite, + const t_idef& idef, double timeStep, - const t_forcerec &forceRec, - t_graph *graph) + const t_forcerec& forceRec, + t_graph* graph) { auto x = makeArrayRef(globalState->x); - auto rerunX = arrayRefFromArray(reinterpret_cast(rerunFrame.x), globalState->natoms); + auto rerunX = arrayRefFromArray(reinterpret_cast(rerunFrame.x), globalState->natoms); std::copy(rerunX.begin(), rerunX.end(), x.begin()); copy_mat(rerunFrame.box, globalState->box); @@ -177,8 +177,8 @@ static void prepareRerunState(const t_trxframe &rerunFrame, shift_self(graph, globalState->box, as_rvec_array(globalState->x.data())); } construct_vsites(vsite, globalState->x.rvec_array(), timeStep, globalState->v.rvec_array(), - idef.iparams, idef.il, - forceRec.ePBC, forceRec.bMolPBC, nullptr, globalState->box); + idef.iparams, idef.il, forceRec.ePBC, forceRec.bMolPBC, nullptr, + globalState->box); if (graph) { unshift_self(graph, globalState->box, globalState->x.rvec_array()); @@ -194,23 +194,23 @@ void gmx::LegacySimulator::do_rerun() // alias to avoid a large ripple of nearly useless changes. // t_inputrec is being replaced by IMdpOptionsProvider, so this // will go away eventually. - t_inputrec *ir = inputrec; + t_inputrec* ir = inputrec; int64_t step, step_rel; double t, lam0[efptNR]; bool isLastStep = false; bool doFreeEnergyPerturbation = false; unsigned int force_flags; tensor force_vir, shake_vir, total_vir, pres; - t_trxstatus *status = nullptr; + t_trxstatus* status = nullptr; rvec mu_tot; t_trxframe rerun_fr; gmx_localtop_t top; - PaddedHostVector f {}; + PaddedHostVector f{}; gmx_global_stat_t gstat; - t_graph *graph = nullptr; - gmx_shellfc_t *shellfc; + t_graph* graph = nullptr; + gmx_shellfc_t* shellfc; - double cycles; + double cycles; /* Domain decomposition could incorrectly miss a bonded interaction, but checking for that requires a global @@ -218,23 +218,26 @@ void gmx::LegacySimulator::do_rerun() code. So we do that alongside the first global energy reduction after a new DD is made. These variables handle whether the check happens, and the result it returns. */ - bool shouldCheckNumberOfBondedInteractions = false; - int totalNumberOfBondedInteractions = -1; + bool shouldCheckNumberOfBondedInteractions = false; + int totalNumberOfBondedInteractions = -1; SimulationSignals signals; // Most global communnication stages don't propagate mdrun // signals, and will use this object to achieve that. SimulationSignaller nullSignaller(nullptr, nullptr, nullptr, false, false); - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that it is planned that the command gmx mdrun -rerun will " - "be available in a different form in a future version of GROMACS, " - "e.g. gmx rerun -f."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that it is planned that the command gmx mdrun -rerun will " + "be available in a different form in a future version of GROMACS, " + "e.g. gmx rerun -f."); - if (ir->efep != efepNO && (mdAtoms->mdatoms()->nMassPerturbed > 0 || - (constr && constr->havePerturbedConstraints()))) + if (ir->efep != efepNO + && (mdAtoms->mdatoms()->nMassPerturbed > 0 || (constr && constr->havePerturbedConstraints()))) { - gmx_fatal(FARGS, "Perturbed masses or constraints are not supported by rerun. " + gmx_fatal(FARGS, + "Perturbed masses or constraints are not supported by rerun. " "Either make a .tpr without mass and constraint perturbation, " "or use GROMACS 2018.4, 2018.5 or later 2018 version."); } @@ -267,7 +270,7 @@ void gmx::LegacySimulator::do_rerun() gmx_fatal(FARGS, "Multiple simulations not supported by rerun."); } if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, - [](int i){return i != eannNO; })) + [](int i) { return i != eannNO; })) { gmx_fatal(FARGS, "Simulated annealing not supported by rerun."); } @@ -275,53 +278,52 @@ void gmx::LegacySimulator::do_rerun() /* Rerun can't work if an output file name is the same as the input file name. * If this is the case, the user will get an error telling them what the issue is. */ - if (strcmp(opt2fn("-rerun", nfile, fnm), opt2fn("-o", nfile, fnm)) == 0 || - strcmp(opt2fn("-rerun", nfile, fnm), opt2fn("-x", nfile, fnm)) == 0) + if (strcmp(opt2fn("-rerun", nfile, fnm), opt2fn("-o", nfile, fnm)) == 0 + || strcmp(opt2fn("-rerun", nfile, fnm), opt2fn("-x", nfile, fnm)) == 0) { - gmx_fatal(FARGS, "When using mdrun -rerun, the name of the input trajectory file " + gmx_fatal(FARGS, + "When using mdrun -rerun, the name of the input trajectory file " "%s cannot be identical to the name of an output file (whether " "given explicitly with -o or -x, or by default)", opt2fn("-rerun", nfile, fnm)); } /* Settings for rerun */ - ir->nstlist = 1; - ir->nstcalcenergy = 1; + ir->nstlist = 1; + ir->nstcalcenergy = 1; int nstglobalcomm = 1; const bool bNS = true; - ir->nstxout_compressed = 0; - SimulationGroups *groups = &top_global->groups; + ir->nstxout_compressed = 0; + SimulationGroups* groups = &top_global->groups; if (ir->eI == eiMimic) { top_global->intermolecularExclusionGroup = genQmmmIndices(*top_global); } initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda, lam0); - gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, ir, top_global, oenv, wcycle, - StartingBehavior::NewSimulation); - gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, mdoutf_get_fp_dhdl(outf), true, mdModulesNotifier); + gmx_mdoutf* outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, + ir, top_global, oenv, wcycle, StartingBehavior::NewSimulation); + gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work, + mdoutf_get_fp_dhdl(outf), true, mdModulesNotifier); gstat = global_stat_init(ir); /* Check for polarizable models and flexible constraints */ - shellfc = init_shell_flexcon(fplog, - top_global, constr ? constr->numFlexibleConstraints() : 0, + shellfc = init_shell_flexcon(fplog, top_global, constr ? constr->numFlexibleConstraints() : 0, ir->nstcalcenergy, DOMAINDECOMP(cr)); { double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1); if ((io > 2000) && MASTER(cr)) { - fprintf(stderr, - "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", - io); + fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io); } } // Local state only becomes valid now. std::unique_ptr stateInstance; - t_state * state; + t_state* state; if (DOMAINDECOMP(cr)) { @@ -332,11 +334,8 @@ void gmx::LegacySimulator::do_rerun() dd_init_local_state(cr->dd, state_global, state); /* Distribute the charge groups over the nodes from the master node */ - dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, + dd_partition_system(fplog, mdlog, ir->init_step, cr, TRUE, 1, state_global, *top_global, ir, + imdSession, pull_work, state, &f, mdAtoms, &top, fr, vsite, constr, nrnb, nullptr, FALSE); shouldCheckNumberOfBondedInteractions = true; } @@ -350,8 +349,7 @@ void gmx::LegacySimulator::do_rerun() /* Copy the pointer to the global state */ state = state_global; - mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, - &graph, mdAtoms, constr, vsite, shellfc); + mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, &graph, mdAtoms, constr, vsite, shellfc); } auto mdatoms = mdAtoms->mdatoms(); @@ -369,29 +367,30 @@ void gmx::LegacySimulator::do_rerun() } { - int cglo_flags = (CGLO_GSTAT | - (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0)); + int cglo_flags = + (CGLO_GSTAT + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0)); bool bSumEkinhOld = false; - t_vcm *vcm = nullptr; - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, vcm, - nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &nullSignaller, state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags); + t_vcm* vcm = nullptr; + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, vcm, nullptr, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &nullSignaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags); } - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, &top, + state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); if (MASTER(cr)) { - fprintf(stderr, "starting md rerun '%s', reading coordinates from" + fprintf(stderr, + "starting md rerun '%s', reading coordinates from" " input trajectory '%s'\n\n", *(top_global->name), opt2fn("-rerun", nfile, fnm)); if (mdrunOptions.verbose) { - fprintf(stderr, "Calculated time to finish depends on nsteps from " + fprintf(stderr, + "Calculated time to finish depends on nsteps from " "run input file,\nwhich may not correspond to the time " "needed to process input trajectory.\n\n"); } @@ -410,16 +409,15 @@ void gmx::LegacySimulator::do_rerun() if (constr) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Simulations has constraints. Rerun does not recalculate constraints."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText("Simulations has constraints. Rerun does not recalculate constraints."); } rerun_fr.natoms = 0; if (MASTER(cr)) { - isLastStep = !read_first_frame(oenv, &status, - opt2fn("-rerun", nfile, fnm), - &rerun_fr, TRX_NEED_X); + isLastStep = !read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm), &rerun_fr, TRX_NEED_X); if (rerun_fr.natoms != top_global->natoms) { gmx_fatal(FARGS, @@ -432,20 +430,28 @@ void gmx::LegacySimulator::do_rerun() { if (!rerun_fr.bBox) { - gmx_fatal(FARGS, "Rerun trajectory frame step %" PRId64 " time %f " + gmx_fatal(FARGS, + "Rerun trajectory frame step %" PRId64 + " time %f " "does not contain a box, while pbc is used", rerun_fr.step, rerun_fr.time); } if (max_cutoff2(ir->ePBC, rerun_fr.box) < gmx::square(fr->rlist)) { - gmx_fatal(FARGS, "Rerun trajectory frame step %" PRId64 " time %f " - "has too small box dimensions", rerun_fr.step, rerun_fr.time); + gmx_fatal(FARGS, + "Rerun trajectory frame step %" PRId64 + " time %f " + "has too small box dimensions", + rerun_fr.step, rerun_fr.time); } } } - GMX_LOG(mdlog.info).asParagraph(). - appendText("Rerun does not report kinetic energy, total energy, temperature, virial and pressure."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Rerun does not report kinetic energy, total energy, temperature, virial and " + "pressure."); if (PAR(cr)) { @@ -461,9 +467,9 @@ void gmx::LegacySimulator::do_rerun() } auto stopHandler = stopHandlerBuilder->getStopHandlerMD( - compat::not_null(&signals[eglsSTOPCOND]), false, - MASTER(cr), ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, - mdrunOptions.maximumHoursToRun, ir->nstlist == 0, fplog, step, bNS, walltime_accounting); + compat::not_null(&signals[eglsSTOPCOND]), false, MASTER(cr), + ir->nstlist, mdrunOptions.reproducible, nstglobalcomm, mdrunOptions.maximumHoursToRun, + ir->nstlist == 0, fplog, step, bNS, walltime_accounting); // we don't do counter resetting in rerun - finish will always be valid walltime_accounting_set_valid_finish(walltime_accounting); @@ -503,10 +509,13 @@ void gmx::LegacySimulator::do_rerun() const bool constructVsites = ((vsite != nullptr) && mdrunOptions.rerunConstructVsites); if (constructVsites && DOMAINDECOMP(cr)) { - gmx_fatal(FARGS, "Vsite recalculation with -rerun is not implemented with domain decomposition, " + gmx_fatal(FARGS, + "Vsite recalculation with -rerun is not implemented with domain " + "decomposition, " "use a single rank"); } - prepareRerunState(rerun_fr, state_global, constructVsites, vsite, top.idef, ir->delta_t, *fr, graph); + prepareRerunState(rerun_fr, state_global, constructVsites, vsite, top.idef, ir->delta_t, + *fr, graph); } isLastStep = isLastStep || stopHandler->stoppingAfterCurrentStep(bNS); @@ -515,14 +524,9 @@ void gmx::LegacySimulator::do_rerun() { /* Repartition the domain decomposition */ const bool bMasterState = true; - dd_partition_system(fplog, mdlog, step, cr, - bMasterState, nstglobalcomm, - state_global, *top_global, ir, imdSession, - pull_work, - state, &f, mdAtoms, &top, fr, - vsite, constr, - nrnb, wcycle, - mdrunOptions.verbose); + dd_partition_system(fplog, mdlog, step, cr, bMasterState, nstglobalcomm, state_global, + *top_global, ir, imdSession, pull_work, state, &f, mdAtoms, &top, + fr, vsite, constr, nrnb, wcycle, mdrunOptions.verbose); shouldCheckNumberOfBondedInteractions = true; } @@ -536,31 +540,19 @@ void gmx::LegacySimulator::do_rerun() update_mdatoms(mdatoms, state->lambda[efptMASS]); } - force_flags = (GMX_FORCE_STATECHANGED | - GMX_FORCE_DYNAMICBOX | - GMX_FORCE_ALLFORCES | - (GMX_GPU ? GMX_FORCE_VIRIAL : 0) | // TODO: Get rid of this once #2649 is solved - GMX_FORCE_ENERGY | - (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0)); + force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES + | (GMX_GPU ? GMX_FORCE_VIRIAL : 0) | // TODO: Get rid of this once #2649 is solved + GMX_FORCE_ENERGY | (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0)); if (shellfc) { /* Now is the time to relax the shells */ - relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, - enforcedRotation, step, - ir, imdSession, pull_work, bNS, force_flags, &top, - constr, enerd, fcd, - state->natoms, - state->x.arrayRefWithPadding(), - state->v.arrayRefWithPadding(), - state->box, - state->lambda, - &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, - nrnb, wcycle, graph, - shellfc, fr, runScheduleWork, t, mu_tot, - vsite, - ddBalanceRegionHandler); + relax_shell_flexcon(fplog, cr, ms, mdrunOptions.verbose, enforcedRotation, step, ir, + imdSession, pull_work, bNS, force_flags, &top, constr, enerd, fcd, + state->natoms, state->x.arrayRefWithPadding(), + state->v.arrayRefWithPadding(), state->box, state->lambda, &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, nrnb, wcycle, graph, + shellfc, fr, runScheduleWork, t, mu_tot, vsite, ddBalanceRegionHandler); } else { @@ -569,16 +561,12 @@ void gmx::LegacySimulator::do_rerun() * This is parallellized as well, and does communication too. * Check comments in sim_util.c */ - Awh *awh = nullptr; - gmx_edsam *ed = nullptr; - do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, - pull_work, - step, nrnb, wcycle, &top, - state->box, state->x.arrayRefWithPadding(), &state->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, - state->lambda, graph, - fr, runScheduleWork, vsite, mu_tot, t, ed, - GMX_FORCE_NS | force_flags, + Awh* awh = nullptr; + gmx_edsam* ed = nullptr; + do_force(fplog, cr, ms, ir, awh, enforcedRotation, imdSession, pull_work, step, nrnb, + wcycle, &top, state->box, state->x.arrayRefWithPadding(), &state->hist, + f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, state->lambda, graph, + fr, runScheduleWork, vsite, mu_tot, t, ed, GMX_FORCE_NS | force_flags, ddBalanceRegionHandler); } @@ -589,13 +577,10 @@ void gmx::LegacySimulator::do_rerun() const bool isCheckpointingStep = false; const bool doRerun = true; const bool bSumEkinhOld = false; - do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, - ir, state, state_global, observablesHistory, - top_global, fr, - outf, energyOutput, ekind, f, - isCheckpointingStep, doRerun, isLastStep, - mdrunOptions.writeConfout, - bSumEkinhOld); + do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t, ir, state, + state_global, observablesHistory, top_global, fr, outf, + energyOutput, ekind, f, isCheckpointingStep, doRerun, + isLastStep, mdrunOptions.writeConfout, bSumEkinhOld); } stopHandler->setSignal(); @@ -613,8 +598,8 @@ void gmx::LegacySimulator::do_rerun() { shift_self(graph, state->box, as_rvec_array(state->x.data())); } - construct_vsites(vsite, as_rvec_array(state->x.data()), ir->delta_t, as_rvec_array(state->v.data()), - top.idef.iparams, top.idef.il, + construct_vsites(vsite, as_rvec_array(state->x.data()), ir->delta_t, + as_rvec_array(state->v.data()), top.idef.iparams, top.idef.il, fr->ePBC, fr->bMolPBC, cr, state->box); if (graph != nullptr) @@ -628,21 +613,18 @@ void gmx::LegacySimulator::do_rerun() const bool doInterSimSignal = false; const bool doIntraSimSignal = true; bool bSumEkinhOld = false; - t_vcm *vcm = nullptr; + t_vcm* vcm = nullptr; SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal); - compute_globals(gstat, cr, ir, fr, ekind, - state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW], - mdatoms, nrnb, vcm, - wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot, - constr, &signaller, - state->box, - &totalNumberOfBondedInteractions, &bSumEkinhOld, + compute_globals(gstat, cr, ir, fr, ekind, state->x.rvec_array(), state->v.rvec_array(), + state->box, state->lambda[efptVDW], mdatoms, nrnb, vcm, wcycle, enerd, + force_vir, shake_vir, total_vir, pres, mu_tot, constr, &signaller, + state->box, &totalNumberOfBondedInteractions, &bSumEkinhOld, CGLO_GSTAT | CGLO_ENERGY - | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - ); - checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, - top_global, &top, state->x.rvec_array(), state->box, + | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0)); + checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions, top_global, + &top, state->x.rvec_array(), state->box, &shouldCheckNumberOfBondedInteractions); } @@ -662,24 +644,20 @@ void gmx::LegacySimulator::do_rerun() if (MASTER(cr)) { const bool bCalcEnerStep = true; - energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep, - t, mdatoms->tmass, enerd, state, - ir->fepvals, ir->expandedvals, state->box, - shake_vir, force_vir, total_vir, pres, - ekind, mu_tot, - constr); + energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep, t, + mdatoms->tmass, enerd, state, ir->fepvals, + ir->expandedvals, state->box, shake_vir, force_vir, + total_vir, pres, ekind, mu_tot, constr); const bool do_ene = true; const bool do_log = true; - Awh *awh = nullptr; + Awh* awh = nullptr; const bool do_dr = ir->nstdisreout != 0; const bool do_or = ir->nstorireout != 0; energyOutput.printAnnealingTemperatures(do_log ? fplog : nullptr, groups, &(ir->opts)); energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, - do_log ? fplog : nullptr, - step, t, - fcd, awh); + do_log ? fplog : nullptr, step, t, fcd, awh); if (do_per_step(step, ir->nstlog)) { @@ -691,8 +669,7 @@ void gmx::LegacySimulator::do_rerun() } /* Print the remaining wall clock time for the run */ - if (isMasterSimMasterRank(ms, MASTER(cr)) && - (mdrunOptions.verbose || gmx_got_usr_signal())) + if (isMasterSimMasterRank(ms, MASTER(cr)) && (mdrunOptions.verbose || gmx_got_usr_signal())) { if (shellfc) { @@ -704,15 +681,11 @@ void gmx::LegacySimulator::do_rerun() /* Ion/water position swapping. * Not done in last step since trajectory writing happens before this call * in the MD loop and exchanges would be lost anyway. */ - if ((ir->eSwapCoords != eswapNO) && (step > 0) && !isLastStep && - do_per_step(step, ir->swap->nstswap)) + if ((ir->eSwapCoords != eswapNO) && (step > 0) && !isLastStep && do_per_step(step, ir->swap->nstswap)) { const bool doRerun = true; - do_swapcoords(cr, step, t, ir, swap, wcycle, - rerun_fr.x, - rerun_fr.box, - MASTER(cr) && mdrunOptions.verbose, - doRerun); + do_swapcoords(cr, step, t, ir, swap, wcycle, rerun_fr.x, rerun_fr.box, + MASTER(cr) && mdrunOptions.verbose, doRerun); } if (MASTER(cr)) diff --git a/src/gromacs/mdrun/runner.cpp b/src/gromacs/mdrun/runner.cpp index dc647f6361..59abe3fcaa 100644 --- a/src/gromacs/mdrun/runner.cpp +++ b/src/gromacs/mdrun/runner.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -160,7 +160,7 @@ #include "simulatorbuilder.h" #if GMX_FAHCORE -#include "corewrap.h" +# include "corewrap.h" #endif namespace gmx @@ -174,13 +174,13 @@ struct DevelopmentFeatureFlags { //! True if the Buffer ops development feature is enabled // TODO: when the trigger of the buffer ops offload is fully automated this should go away - bool enableGpuBufferOps = false; + bool enableGpuBufferOps = false; //! If true, forces 'mdrun -update auto' default to 'gpu' bool forceGpuUpdateDefaultOn = false; //! True if the GPU halo exchange development feature is enabled - bool enableGpuHaloExchange = false; + bool enableGpuHaloExchange = false; //! True if the PME PP direct communication GPU development feature is enabled - bool enableGpuPmePPComm = false; + bool enableGpuPmePPComm = false; }; /*! \brief Manage any development feature flag variables encountered @@ -199,7 +199,7 @@ struct DevelopmentFeatureFlags * \param[in] useGpuForPme True if the PME task is offloaded in this run. * \returns The object populated with development feature flags. */ -static DevelopmentFeatureFlags manageDevelopmentFeatures(const gmx::MDLogger &mdlog, +static DevelopmentFeatureFlags manageDevelopmentFeatures(const gmx::MDLogger& mdlog, const bool useGpuForNonbonded, const bool useGpuForPme) { @@ -209,16 +209,22 @@ static DevelopmentFeatureFlags manageDevelopmentFeatures(const gmx::MDLogger &md // getenv results are ignored when clearly they are used. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" - devFlags.enableGpuBufferOps = (getenv("GMX_USE_GPU_BUFFER_OPS") != nullptr) && (GMX_GPU == GMX_GPU_CUDA) && useGpuForNonbonded; + devFlags.enableGpuBufferOps = (getenv("GMX_USE_GPU_BUFFER_OPS") != nullptr) + && (GMX_GPU == GMX_GPU_CUDA) && useGpuForNonbonded; devFlags.forceGpuUpdateDefaultOn = (getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") != nullptr); - devFlags.enableGpuHaloExchange = (getenv("GMX_GPU_DD_COMMS") != nullptr && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA)); - devFlags.enableGpuPmePPComm = (getenv("GMX_GPU_PME_PP_COMMS") != nullptr && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA)); + devFlags.enableGpuHaloExchange = + (getenv("GMX_GPU_DD_COMMS") != nullptr && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA)); + devFlags.enableGpuPmePPComm = + (getenv("GMX_GPU_PME_PP_COMMS") != nullptr && GMX_THREAD_MPI && (GMX_GPU == GMX_GPU_CUDA)); #pragma GCC diagnostic pop if (devFlags.enableGpuBufferOps) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: This run uses the 'GPU buffer ops' feature, enabled by the GMX_USE_GPU_BUFFER_OPS environment variable."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: This run uses the 'GPU buffer ops' feature, enabled by the " + "GMX_USE_GPU_BUFFER_OPS environment variable."); } if (devFlags.enableGpuHaloExchange) @@ -227,36 +233,55 @@ static DevelopmentFeatureFlags manageDevelopmentFeatures(const gmx::MDLogger &md { if (!devFlags.enableGpuBufferOps) { - gmx_fatal(FARGS, "Cannot enable GPU halo exchange without GPU buffer operations, set GMX_USE_GPU_BUFFER_OPS=1\n"); + gmx_fatal(FARGS, + "Cannot enable GPU halo exchange without GPU buffer operations, set " + "GMX_USE_GPU_BUFFER_OPS=1\n"); } - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: This run uses the 'GPU halo exchange' feature, enabled by the GMX_GPU_DD_COMMS environment variable."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: This run uses the 'GPU halo exchange' feature, enabled by the " + "GMX_GPU_DD_COMMS environment variable."); } else { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: GMX_GPU_DD_COMMS environment variable detected, but the 'GPU halo exchange' feature will not be enabled as nonbonded interactions are not offloaded."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: GMX_GPU_DD_COMMS environment variable detected, but the 'GPU " + "halo exchange' feature will not be enabled as nonbonded interactions " + "are not offloaded."); devFlags.enableGpuHaloExchange = false; } } if (devFlags.forceGpuUpdateDefaultOn) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: This run will default to '-update gpu' as requested by the GMX_FORCE_UPDATE_DEFAULT_GPU environment variable."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: This run will default to '-update gpu' as requested by the " + "GMX_FORCE_UPDATE_DEFAULT_GPU environment variable."); } if (devFlags.enableGpuPmePPComm) { if (useGpuForPme) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: This run uses the 'GPU PME-PP communications' feature, enabled by the GMX_GPU_PME_PP_COMMS environment variable."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: This run uses the 'GPU PME-PP communications' feature, enabled " + "by the GMX_GPU_PME_PP_COMMS environment variable."); } else { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: GMX_GPU_PME_PP_COMMS environment variable detected, but the 'GPU PME-PP communications' feature was not enabled as PME is not offloaded to the GPU."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: GMX_GPU_PME_PP_COMMS environment variable detected, but the " + "'GPU PME-PP communications' feature was not enabled as PME is not " + "offloaded to the GPU."); devFlags.enableGpuPmePPComm = false; } } @@ -292,17 +317,17 @@ Mdrunner Mdrunner::cloneOnSpawnedThread() const newRunner.hw_opt = hw_opt; newRunner.filenames = filenames; - newRunner.oenv = oenv; - newRunner.mdrunOptions = mdrunOptions; - newRunner.domdecOptions = domdecOptions; - newRunner.nbpu_opt = nbpu_opt; - newRunner.pme_opt = pme_opt; - newRunner.pme_fft_opt = pme_fft_opt; - newRunner.bonded_opt = bonded_opt; - newRunner.update_opt = update_opt; - newRunner.nstlist_cmdline = nstlist_cmdline; - newRunner.replExParams = replExParams; - newRunner.pforce = pforce; + newRunner.oenv = oenv; + newRunner.mdrunOptions = mdrunOptions; + newRunner.domdecOptions = domdecOptions; + newRunner.nbpu_opt = nbpu_opt; + newRunner.pme_opt = pme_opt; + newRunner.pme_fft_opt = pme_fft_opt; + newRunner.bonded_opt = bonded_opt; + newRunner.update_opt = update_opt; + newRunner.nstlist_cmdline = nstlist_cmdline; + newRunner.replExParams = replExParams; + newRunner.pforce = pforce; // Give the spawned thread the newly created valid communicator // for the simulation. newRunner.communicator = MPI_COMM_WORLD; @@ -321,18 +346,18 @@ Mdrunner Mdrunner::cloneOnSpawnedThread() const * argument permitted to the thread-launch API call, copies it to make * a new runner for this thread, reinitializes necessary data, and * proceeds to the simulation. */ -static void mdrunner_start_fn(const void *arg) +static void mdrunner_start_fn(const void* arg) { try { - auto masterMdrunner = reinterpret_cast(arg); + auto masterMdrunner = reinterpret_cast(arg); /* copy the arg list to make sure that it's thread-local. This doesn't copy pointed-to items, of course; fnm, cr and fplog are reset in the call below, all others should be const. */ gmx::Mdrunner mdrunner = masterMdrunner->cloneOnSpawnedThread(); mdrunner.mdrunner(); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } @@ -341,8 +366,9 @@ void Mdrunner::spawnThreads(int numThreadsToLaunch) #if GMX_THREAD_MPI /* now spawn new threads that start mdrunner_start_fn(), while the main thread returns. Thread affinity is handled later. */ - if (tMPI_Init_fn(TRUE, numThreadsToLaunch, TMPI_AFFINITY_NONE, - mdrunner_start_fn, static_cast(this)) != TMPI_SUCCESS) + if (tMPI_Init_fn(TRUE, numThreadsToLaunch, TMPI_AFFINITY_NONE, mdrunner_start_fn, + static_cast(this)) + != TMPI_SUCCESS) { GMX_THROW(gmx::InternalError("Failed to spawn thread-MPI threads")); } @@ -357,22 +383,20 @@ void Mdrunner::spawnThreads(int numThreadsToLaunch) #endif } -} // namespace gmx +} // namespace gmx /*! \brief Initialize variables for Verlet scheme simulation */ -static void prepare_verlet_scheme(FILE *fplog, - t_commrec *cr, - t_inputrec *ir, - int nstlist_cmdline, - const gmx_mtop_t *mtop, - const matrix box, - bool makeGpuPairList, - const gmx::CpuInfo &cpuinfo) +static void prepare_verlet_scheme(FILE* fplog, + t_commrec* cr, + t_inputrec* ir, + int nstlist_cmdline, + const gmx_mtop_t* mtop, + const matrix box, + bool makeGpuPairList, + const gmx::CpuInfo& cpuinfo) { /* For NVE simulations, we will retain the initial list buffer */ - if (EI_DYNAMICS(ir->eI) && - ir->verletbuf_tol > 0 && - !(EI_MD(ir->eI) && ir->etc == etcNO)) + if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0 && !(EI_MD(ir->eI) && ir->etc == etcNO)) { /* Update the Verlet buffer size for the current run setup */ @@ -380,21 +404,22 @@ static void prepare_verlet_scheme(FILE *fplog, * calc_verlet_buffer_size gives the same results for 4x8 and 4x4 * and 4x2 gives a larger buffer than 4x4, this is ok. */ - ListSetupType listType = (makeGpuPairList ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); + ListSetupType listType = + (makeGpuPairList ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); VerletbufListSetup listSetup = verletbufGetSafeListSetup(listType); - const real rlist_new = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup); + const real rlist_new = + calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup); if (rlist_new != ir->rlist) { if (fplog != nullptr) { - fprintf(fplog, "\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n", - ir->rlist, rlist_new, - listSetup.cluster_size_i, listSetup.cluster_size_j); + fprintf(fplog, + "\nChanging rlist from %g to %g for non-bonded %dx%d atom kernels\n\n", + ir->rlist, rlist_new, listSetup.cluster_size_i, listSetup.cluster_size_j); } - ir->rlist = rlist_new; + ir->rlist = rlist_new; } } @@ -415,9 +440,7 @@ static void prepare_verlet_scheme(FILE *fplog, * * with value passed on the command line (if any) */ -static void override_nsteps_cmdline(const gmx::MDLogger &mdlog, - int64_t nsteps_cmdline, - t_inputrec *ir) +static void override_nsteps_cmdline(const gmx::MDLogger& mdlog, int64_t nsteps_cmdline, t_inputrec* ir) { assert(ir); @@ -430,9 +453,9 @@ static void override_nsteps_cmdline(const gmx::MDLogger &mdlog, ir->nsteps = nsteps_cmdline; if (EI_DYNAMICS(ir->eI) && nsteps_cmdline != -1) { - sprintf(sbuf_msg, "Overriding nsteps with value passed on the command line: %s steps, %.3g ps", - gmx_step_str(nsteps_cmdline, sbuf_steps), - fabs(nsteps_cmdline*ir->delta_t)); + sprintf(sbuf_msg, + "Overriding nsteps with value passed on the command line: %s steps, %.3g ps", + gmx_step_str(nsteps_cmdline, sbuf_steps), fabs(nsteps_cmdline * ir->delta_t)); } else { @@ -444,8 +467,7 @@ static void override_nsteps_cmdline(const gmx::MDLogger &mdlog, } else if (nsteps_cmdline < -2) { - gmx_fatal(FARGS, "Invalid nsteps value passed on the command line: %" PRId64, - nsteps_cmdline); + gmx_fatal(FARGS, "Invalid nsteps value passed on the command line: %" PRId64, nsteps_cmdline); } /* Do nothing if nsteps_cmdline == -2 */ } @@ -458,9 +480,7 @@ namespace gmx * If not, and if a warning may be issued, logs a warning about * falling back to CPU code. With thread-MPI, only the first * call to this function should have \c issueWarning true. */ -static bool gpuAccelerationOfNonbondedIsUseful(const MDLogger &mdlog, - const t_inputrec &ir, - bool issueWarning) +static bool gpuAccelerationOfNonbondedIsUseful(const MDLogger& mdlog, const t_inputrec& ir, bool issueWarning) { bool gpuIsUseful = true; std::string warning; @@ -471,10 +491,10 @@ static bool gpuAccelerationOfNonbondedIsUseful(const MDLogger &mdlog, * If the user requested GPUs explicitly, a fatal error is given later. */ gpuIsUseful = false; - warning = - "Multiple energy groups is not implemented for GPUs, falling back to the CPU. " - "For better performance, run on the GPU without energy groups and then do " - "gmx mdrun -rerun option on the trajectory with an energy group .tpr file."; + warning = + "Multiple energy groups is not implemented for GPUs, falling back to the CPU. " + "For better performance, run on the GPU without energy groups and then do " + "gmx mdrun -rerun option on the trajectory with an energy group .tpr file."; } if (EI_TPI(ir.eI)) @@ -492,8 +512,7 @@ static bool gpuAccelerationOfNonbondedIsUseful(const MDLogger &mdlog, } //! Initializes the logger for mdrun. -static gmx::LoggerOwner buildLogger(FILE *fplog, - const bool isSimulationMasterRank) +static gmx::LoggerOwner buildLogger(FILE* fplog, const bool isSimulationMasterRank) { gmx::LoggerBuilder builder; if (fplog != nullptr) @@ -502,14 +521,13 @@ static gmx::LoggerOwner buildLogger(FILE *fplog, } if (isSimulationMasterRank) { - builder.addTargetStream(gmx::MDLogger::LogLevel::Warning, - &gmx::TextOutputFile::standardError()); + builder.addTargetStream(gmx::MDLogger::LogLevel::Warning, &gmx::TextOutputFile::standardError()); } return builder.build(); } //! Make a TaskTarget from an mdrun argument string. -static TaskTarget findTaskTarget(const char *optionString) +static TaskTarget findTaskTarget(const char* optionString) { TaskTarget returnValue = TaskTarget::Auto; @@ -534,21 +552,20 @@ static TaskTarget findTaskTarget(const char *optionString) } //! Finish run, aggregate data to print performance info. -static void finish_run(FILE *fplog, - const gmx::MDLogger &mdlog, - const t_commrec *cr, - const t_inputrec *inputrec, - t_nrnb nrnb[], gmx_wallcycle_t wcycle, +static void finish_run(FILE* fplog, + const gmx::MDLogger& mdlog, + const t_commrec* cr, + const t_inputrec* inputrec, + t_nrnb nrnb[], + gmx_wallcycle_t wcycle, gmx_walltime_accounting_t walltime_accounting, - nonbonded_verlet_t *nbv, - const gmx_pme_t *pme, - gmx_bool bWriteStat) + nonbonded_verlet_t* nbv, + const gmx_pme_t* pme, + gmx_bool bWriteStat) { - double delta_t = 0; - double nbfs = 0, mflop = 0; - double elapsed_time, - elapsed_time_over_all_ranks, - elapsed_time_over_all_threads, + double delta_t = 0; + double nbfs = 0, mflop = 0; + double elapsed_time, elapsed_time_over_all_ranks, elapsed_time_over_all_threads, elapsed_time_over_all_threads_over_all_ranks; /* Control whether it is valid to print a report. Only the simulation master may print, but it should not do so if the run @@ -567,19 +584,20 @@ static void finish_run(FILE *fplog, if (printReport && !walltime_accounting_get_valid_finish(walltime_accounting)) { - GMX_LOG(mdlog.warning).asParagraph().appendText("Simulation ended prematurely, no performance report will be written."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("Simulation ended prematurely, no performance report will be written."); printReport = false; } - t_nrnb *nrnb_tot; - std::unique_ptr nrnbTotalStorage; + t_nrnb* nrnb_tot; + std::unique_ptr nrnbTotalStorage; if (cr->nnodes > 1) { nrnbTotalStorage = std::make_unique(); nrnb_tot = nrnbTotalStorage.get(); #if GMX_MPI - MPI_Allreduce(nrnb->n, nrnb_tot->n, eNRNB, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mysim); + MPI_Allreduce(nrnb->n, nrnb_tot->n, eNRNB, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim); #endif } else @@ -587,23 +605,20 @@ static void finish_run(FILE *fplog, nrnb_tot = nrnb; } - elapsed_time = walltime_accounting_get_time_since_reset(walltime_accounting); - elapsed_time_over_all_threads = walltime_accounting_get_time_since_reset_over_all_threads(walltime_accounting); + elapsed_time = walltime_accounting_get_time_since_reset(walltime_accounting); + elapsed_time_over_all_threads = + walltime_accounting_get_time_since_reset_over_all_threads(walltime_accounting); if (cr->nnodes > 1) { #if GMX_MPI /* reduce elapsed_time over all MPI ranks in the current simulation */ - MPI_Allreduce(&elapsed_time, - &elapsed_time_over_all_ranks, - 1, MPI_DOUBLE, MPI_SUM, + MPI_Allreduce(&elapsed_time, &elapsed_time_over_all_ranks, 1, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim); elapsed_time_over_all_ranks /= cr->nnodes; /* Reduce elapsed_time_over_all_threads over all MPI ranks in the * current simulation. */ - MPI_Allreduce(&elapsed_time_over_all_threads, - &elapsed_time_over_all_threads_over_all_ranks, - 1, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mysim); + MPI_Allreduce(&elapsed_time_over_all_threads, &elapsed_time_over_all_threads_over_all_ranks, + 1, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim); #endif } else @@ -628,22 +643,22 @@ static void finish_run(FILE *fplog, * to task parallelism. */ int nthreads_pp = gmx_omp_nthreads_get(emntNonbonded); int nthreads_pme = gmx_omp_nthreads_get(emntPME); - wallcycle_scale_by_num_threads(wcycle, thisRankHasDuty(cr, DUTY_PME) && !thisRankHasDuty(cr, DUTY_PP), nthreads_pp, nthreads_pme); + wallcycle_scale_by_num_threads(wcycle, thisRankHasDuty(cr, DUTY_PME) && !thisRankHasDuty(cr, DUTY_PP), + nthreads_pp, nthreads_pme); auto cycle_sum(wallcycle_sum(cr, wcycle)); if (printReport) { - auto nbnxn_gpu_timings = (nbv != nullptr && nbv->useGpu()) ? Nbnxm::gpu_get_timings(nbv->gpu_nbv) : nullptr; - gmx_wallclock_gpu_pme_t pme_gpu_timings = {}; + auto nbnxn_gpu_timings = + (nbv != nullptr && nbv->useGpu()) ? Nbnxm::gpu_get_timings(nbv->gpu_nbv) : nullptr; + gmx_wallclock_gpu_pme_t pme_gpu_timings = {}; if (pme_gpu_task_enabled(pme)) { pme_gpu_get_timings(pme, &pme_gpu_timings); } wallcycle_print(fplog, mdlog, cr->nnodes, cr->npmenodes, nthreads_pp, nthreads_pme, - elapsed_time_over_all_ranks, - wcycle, cycle_sum, - nbnxn_gpu_timings, + elapsed_time_over_all_ranks, wcycle, cycle_sum, nbnxn_gpu_timings, &pme_gpu_timings); if (EI_DYNAMICS(inputrec->eI)) @@ -653,15 +668,13 @@ static void finish_run(FILE *fplog, if (fplog) { - print_perf(fplog, elapsed_time_over_all_threads_over_all_ranks, - elapsed_time_over_all_ranks, + print_perf(fplog, elapsed_time_over_all_threads_over_all_ranks, elapsed_time_over_all_ranks, walltime_accounting_get_nsteps_done_since_reset(walltime_accounting), delta_t, nbfs, mflop); } if (bWriteStat) { - print_perf(stderr, elapsed_time_over_all_threads_over_all_ranks, - elapsed_time_over_all_ranks, + print_perf(stderr, elapsed_time_over_all_threads_over_all_ranks, elapsed_time_over_all_ranks, walltime_accounting_get_nsteps_done_since_reset(walltime_accounting), delta_t, nbfs, mflop); } @@ -671,19 +684,19 @@ static void finish_run(FILE *fplog, int Mdrunner::mdrunner() { matrix box; - t_forcerec *fr = nullptr; - t_fcdata *fcd = nullptr; + t_forcerec* fr = nullptr; + t_fcdata* fcd = nullptr; real ewaldcoeff_q = 0; real ewaldcoeff_lj = 0; int nChargePerturbed = -1, nTypePerturbed = 0; gmx_wallcycle_t wcycle; gmx_walltime_accounting_t walltime_accounting = nullptr; - gmx_membed_t * membed = nullptr; - gmx_hw_info_t *hwinfo = nullptr; + gmx_membed_t* membed = nullptr; + gmx_hw_info_t* hwinfo = nullptr; /* CAUTION: threads may be started later on in this function, so cr doesn't reflect the final parallel state right now */ - gmx_mtop_t mtop; + gmx_mtop_t mtop; /* TODO: inputrec should tell us whether we use an algorithm, not a file option */ const bool doEssentialDynamics = opt2bSet("-ei", filenames.size(), filenames.data()); @@ -691,15 +704,15 @@ int Mdrunner::mdrunner() const bool doRerun = mdrunOptions.rerun; // Handle task-assignment related user options. - EmulateGpuNonbonded emulateGpuNonbonded = (getenv("GMX_EMULATE_GPU") != nullptr ? - EmulateGpuNonbonded::Yes : EmulateGpuNonbonded::No); + EmulateGpuNonbonded emulateGpuNonbonded = + (getenv("GMX_EMULATE_GPU") != nullptr ? EmulateGpuNonbonded::Yes : EmulateGpuNonbonded::No); std::vector userGpuTaskAssignment; try { userGpuTaskAssignment = parseUserTaskAssignmentString(hw_opt.userGpuTaskAssignment); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR auto nonbondedTarget = findTaskTarget(nbpu_opt); auto pmeTarget = findTaskTarget(pme_opt); auto pmeFftTarget = findTaskTarget(pme_fft_opt); @@ -707,7 +720,7 @@ int Mdrunner::mdrunner() auto updateTarget = findTaskTarget(update_opt); PmeRunMode pmeRunMode = PmeRunMode::None; - FILE *fplog = nullptr; + FILE* fplog = nullptr; // If we are appending, we don't write log output because we need // to check that the old log file matches what the checkpoint file // expects. Otherwise, we should start to write log output now if @@ -740,10 +753,10 @@ int Mdrunner::mdrunner() // TODO Replace this by unique_ptr once t_inputrec is C++ t_inputrec inputrecInstance; - t_inputrec *inputrec = nullptr; + t_inputrec* inputrec = nullptr; std::unique_ptr globalState; - auto partialDeserializedTpr = std::make_unique(); + auto partialDeserializedTpr = std::make_unique(); if (isSimulationMasterRank) { @@ -753,12 +766,14 @@ int Mdrunner::mdrunner() /* Read (nearly) all data required for the simulation * and keep the partly serialized tpr contents to send to other ranks later */ - *partialDeserializedTpr = read_tpx_state(ftp2fn(efTPR, filenames.size(), filenames.data()), &inputrecInstance, globalState.get(), &mtop); + *partialDeserializedTpr = read_tpx_state(ftp2fn(efTPR, filenames.size(), filenames.data()), + &inputrecInstance, globalState.get(), &mtop); inputrec = &inputrecInstance; } /* Check and update the hardware options for internal consistency */ - checkAndUpdateHardwareOptions(mdlog, &hw_opt, isSimulationMasterRank, domdecOptions.numPmeRanks, inputrec); + checkAndUpdateHardwareOptions(mdlog, &hw_opt, isSimulationMasterRank, domdecOptions.numPmeRanks, + inputrec); if (GMX_THREAD_MPI && isSimulationMasterRank) { @@ -772,31 +787,24 @@ int Mdrunner::mdrunner() // respect that, but in default mode, we need to allow for // the number of GPUs to choose the number of ranks. auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr); - useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi - (nonbondedTarget, gpuIdsToUse, userGpuTaskAssignment, emulateGpuNonbonded, + useGpuForNonbonded = decideWhetherToUseGpusForNonbondedWithThreadMpi( + nonbondedTarget, gpuIdsToUse, userGpuTaskAssignment, emulateGpuNonbonded, canUseGpuForNonbonded, gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, GMX_THREAD_MPI), hw_opt.nthreads_tmpi); - useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi - (useGpuForNonbonded, pmeTarget, gpuIdsToUse, userGpuTaskAssignment, - *hwinfo, *inputrec, mtop, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks); - + useGpuForPme = decideWhetherToUseGpusForPmeWithThreadMpi( + useGpuForNonbonded, pmeTarget, gpuIdsToUse, userGpuTaskAssignment, *hwinfo, + *inputrec, mtop, hw_opt.nthreads_tmpi, domdecOptions.numPmeRanks); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR /* Determine how many thread-MPI ranks to start. * * TODO Over-writing the user-supplied value here does * prevent any possible subsequent checks from working * correctly. */ - hw_opt.nthreads_tmpi = get_nthreads_mpi(hwinfo, - &hw_opt, - gpuIdsToUse, - useGpuForNonbonded, - useGpuForPme, - inputrec, &mtop, - mdlog, - doMembed); + hw_opt.nthreads_tmpi = get_nthreads_mpi(hwinfo, &hw_opt, gpuIdsToUse, useGpuForNonbonded, + useGpuForPme, inputrec, &mtop, mdlog, doMembed); // Now start the threads for thread MPI. spawnThreads(hw_opt.nthreads_tmpi); @@ -807,7 +815,7 @@ int Mdrunner::mdrunner() GMX_RELEASE_ASSERT(communicator == MPI_COMM_WORLD, "Must have valid world communicator"); CommrecHandle crHandle = init_commrec(communicator, ms); - t_commrec *cr = crHandle.get(); + t_commrec* cr = crHandle.get(); GMX_RELEASE_ASSERT(cr != nullptr, "Must have valid commrec"); if (PAR(cr)) @@ -829,19 +837,18 @@ int Mdrunner::mdrunner() // // TODO Should we do the communication in debug mode to support // having an assertion? - const bool useDomainDecomposition = (PAR(cr) && !(EI_TPI(inputrec->eI) || - inputrec->eI == eiNM)); + const bool useDomainDecomposition = (PAR(cr) && !(EI_TPI(inputrec->eI) || inputrec->eI == eiNM)); // Note that these variables describe only their own node. // // Note that when bonded interactions run on a GPU they always run // alongside a nonbonded task, so do not influence task assignment // even though they affect the force calculation workload. - bool useGpuForNonbonded = false; - bool useGpuForPme = false; - bool useGpuForBonded = false; - bool useGpuForUpdate = false; - bool gpusWereDetected = hwinfo->ngpu_compatible_tot > 0; + bool useGpuForNonbonded = false; + bool useGpuForPme = false; + bool useGpuForBonded = false; + bool useGpuForUpdate = false; + bool gpusWereDetected = hwinfo->ngpu_compatible_tot > 0; try { // It's possible that there are different numbers of GPUs on @@ -849,24 +856,20 @@ int Mdrunner::mdrunner() // handle. If unsuitable, we will notice that during task // assignment. auto canUseGpuForNonbonded = buildSupportsNonbondedOnGpu(nullptr); - useGpuForNonbonded = decideWhetherToUseGpusForNonbonded(nonbondedTarget, userGpuTaskAssignment, - emulateGpuNonbonded, - canUseGpuForNonbonded, - gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, !GMX_THREAD_MPI), - gpusWereDetected); - useGpuForPme = decideWhetherToUseGpusForPme(useGpuForNonbonded, pmeTarget, userGpuTaskAssignment, - *hwinfo, *inputrec, mtop, - cr->nnodes, domdecOptions.numPmeRanks, - gpusWereDetected); - auto canUseGpuForBonded = buildSupportsGpuBondeds(nullptr) && inputSupportsGpuBondeds(*inputrec, mtop, nullptr); - useGpuForBonded = - decideWhetherToUseGpusForBonded(useGpuForNonbonded, useGpuForPme, - bondedTarget, canUseGpuForBonded, - EVDW_PME(inputrec->vdwtype), - EEL_PME_EWALD(inputrec->coulombtype), - domdecOptions.numPmeRanks, gpusWereDetected); - - pmeRunMode = (useGpuForPme ? PmeRunMode::GPU : PmeRunMode::CPU); + useGpuForNonbonded = decideWhetherToUseGpusForNonbonded( + nonbondedTarget, userGpuTaskAssignment, emulateGpuNonbonded, canUseGpuForNonbonded, + gpuAccelerationOfNonbondedIsUseful(mdlog, *inputrec, !GMX_THREAD_MPI), gpusWereDetected); + useGpuForPme = decideWhetherToUseGpusForPme( + useGpuForNonbonded, pmeTarget, userGpuTaskAssignment, *hwinfo, *inputrec, mtop, + cr->nnodes, domdecOptions.numPmeRanks, gpusWereDetected); + auto canUseGpuForBonded = buildSupportsGpuBondeds(nullptr) + && inputSupportsGpuBondeds(*inputrec, mtop, nullptr); + useGpuForBonded = decideWhetherToUseGpusForBonded( + useGpuForNonbonded, useGpuForPme, bondedTarget, canUseGpuForBonded, + EVDW_PME(inputrec->vdwtype), EEL_PME_EWALD(inputrec->coulombtype), + domdecOptions.numPmeRanks, gpusWereDetected); + + pmeRunMode = (useGpuForPme ? PmeRunMode::GPU : PmeRunMode::CPU); if (pmeRunMode == PmeRunMode::GPU) { if (pmeFftTarget == TaskTarget::Cpu) @@ -876,33 +879,30 @@ int Mdrunner::mdrunner() } else if (pmeFftTarget == TaskTarget::Gpu) { - gmx_fatal(FARGS, "Assigning FFTs to GPU requires PME to be assigned to GPU as well. With PME on CPU you should not be using -pmefft."); + gmx_fatal(FARGS, + "Assigning FFTs to GPU requires PME to be assigned to GPU as well. With PME " + "on CPU you should not be using -pmefft."); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR // Initialize development feature flags that enabled by environment variable // and report those features that are enabled. - const DevelopmentFeatureFlags devFlags = manageDevelopmentFeatures(mdlog, useGpuForNonbonded, useGpuForPme); + const DevelopmentFeatureFlags devFlags = + manageDevelopmentFeatures(mdlog, useGpuForNonbonded, useGpuForPme); // NOTE: The devFlags need decideWhetherToUseGpusForNonbonded(...) and decideWhetherToUseGpusForPme(...) for overrides, // decideWhetherToUseGpuForUpdate() needs devFlags for the '-update auto' override, hence the interleaving. // NOTE: When the simulationWork is constructed, the useGpuForUpdate overrides the devFlags.enableGpuBufferOps. try { - useGpuForUpdate = decideWhetherToUseGpuForUpdate(devFlags.forceGpuUpdateDefaultOn, - useDomainDecomposition, - useGpuForPme, - useGpuForNonbonded, - updateTarget, - gpusWereDetected, - *inputrec, - gmx_mtop_interaction_count(mtop, IF_VSITE) > 0, - doEssentialDynamics, - gmx_mtop_ftype_count(mtop, F_ORIRES) > 0, - replExParams.exchangeInterval > 0); + useGpuForUpdate = decideWhetherToUseGpuForUpdate( + devFlags.forceGpuUpdateDefaultOn, useDomainDecomposition, useGpuForPme, + useGpuForNonbonded, updateTarget, gpusWereDetected, *inputrec, + gmx_mtop_interaction_count(mtop, IF_VSITE) > 0, doEssentialDynamics, + gmx_mtop_ftype_count(mtop, F_ORIRES) > 0, replExParams.exchangeInterval > 0); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR // Build restraints. @@ -911,16 +911,15 @@ int Mdrunner::mdrunner() // Mdrunner is concerned. The Mdrunner should just be getting a sequence of // factory functions from the SimulationContext on which to call mdModules_->add(). // TODO: capture all restraints into a single RestraintModule, passed to the runner builder. - for (auto && restraint : restraintManager_->getRestraints()) + for (auto&& restraint : restraintManager_->getRestraints()) { - auto module = RestraintMDModule::create(restraint, - restraint->sites()); + auto module = RestraintMDModule::create(restraint, restraint->sites()); mdModules_->add(std::move(module)); } // TODO: Error handling mdModules_->assignOptionsToModules(*inputrec->params, nullptr); - const auto &mdModulesNotifier = mdModules_->notifier().notifier_; + const auto& mdModulesNotifier = mdModules_->notifier().notifier_; if (inputrec->internalParameters != nullptr) { @@ -939,9 +938,11 @@ int Mdrunner::mdrunner() if (doRerun && ((globalState->flags & (1 << estV)) != 0)) { // rerun does not use velocities - GMX_LOG(mdlog.info).asParagraph().appendText( - "Rerun trajectory contains velocities. Rerun does only evaluate " - "potential energy and forces. The velocities will be ignored."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Rerun trajectory contains velocities. Rerun does only evaluate " + "potential energy and forces. The velocities will be ignored."); for (int i = 0; i < globalState->natoms; i++) { clear_rvec(globalState->v[i]); @@ -967,26 +968,29 @@ int Mdrunner::mdrunner() /* A parallel command line option consistency check that we can only do after any threads have started. */ - if (!PAR(cr) && (domdecOptions.numCells[XX] > 1 || - domdecOptions.numCells[YY] > 1 || - domdecOptions.numCells[ZZ] > 1 || - domdecOptions.numPmeRanks > 0)) + if (!PAR(cr) + && (domdecOptions.numCells[XX] > 1 || domdecOptions.numCells[YY] > 1 + || domdecOptions.numCells[ZZ] > 1 || domdecOptions.numPmeRanks > 0)) { gmx_fatal(FARGS, "The -dd or -npme option request a parallel simulation, " #if !GMX_MPI - "but %s was compiled without threads or MPI enabled", output_env_get_program_display_name(oenv)); + "but %s was compiled without threads or MPI enabled", + output_env_get_program_display_name(oenv)); #elif GMX_THREAD_MPI "but the number of MPI-threads (option -ntmpi) is not set or is 1"); #else - "but %s was not started through mpirun/mpiexec or only one rank was requested through mpirun/mpiexec", output_env_get_program_display_name(oenv)); + "but %s was not started through mpirun/mpiexec or only one rank was requested " + "through mpirun/mpiexec", + output_env_get_program_display_name(oenv)); #endif } - if (doRerun && - (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI)) + if (doRerun && (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI)) { - gmx_fatal(FARGS, "The .mdp file specified an energy mininization or normal mode algorithm, and these are not compatible with mdrun -rerun"); + gmx_fatal(FARGS, + "The .mdp file specified an energy mininization or normal mode algorithm, and " + "these are not compatible with mdrun -rerun"); } if (!(EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype))) @@ -994,7 +998,8 @@ int Mdrunner::mdrunner() if (domdecOptions.numPmeRanks > 0) { gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "PME-only ranks are requested, but the system does not use PME for electrostatics or LJ"); + "PME-only ranks are requested, but the system does not use PME " + "for electrostatics or LJ"); } domdecOptions.numPmeRanks = 0; @@ -1017,7 +1022,8 @@ int Mdrunner::mdrunner() } else { - GMX_RELEASE_ASSERT(domdecOptions.numPmeRanks <= 1, "PME GPU decomposition is not supported"); + GMX_RELEASE_ASSERT(domdecOptions.numPmeRanks <= 1, + "PME GPU decomposition is not supported"); } } @@ -1042,9 +1048,9 @@ int Mdrunner::mdrunner() init_orires(fplog, &mtop, inputrec, cr, ms, globalState.get(), &(fcd->orires)); - auto deform = prepareBoxDeformation(globalState->box, cr, *inputrec); + auto deform = prepareBoxDeformation(globalState->box, cr, *inputrec); - ObservablesHistory observablesHistory = {}; + ObservablesHistory observablesHistory = {}; if (startingBehavior != StartingBehavior::NewSimulation) { @@ -1061,16 +1067,13 @@ int Mdrunner::mdrunner() } load_checkpoint(opt2fn_master("-cpi", filenames.size(), filenames.data(), cr), - logFileHandle, - cr, domdecOptions.numCells, - inputrec, globalState.get(), - &observablesHistory, - mdrunOptions.reproducible, mdModules_->notifier()); + logFileHandle, cr, domdecOptions.numCells, inputrec, globalState.get(), + &observablesHistory, mdrunOptions.reproducible, mdModules_->notifier()); if (startingBehavior == StartingBehavior::RestartWithAppending && logFileHandle) { // Now we can start normal logging to the truncated log file. - fplog = gmx_fio_getfp(logFileHandle); + fplog = gmx_fio_getfp(logFileHandle); prepareLogAppending(fplog); logOwner = buildLogger(fplog, MASTER(cr)); mdlog = logOwner.logger(); @@ -1079,9 +1082,13 @@ int Mdrunner::mdrunner() if (mdrunOptions.numStepsCommandline > -2) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("The -nsteps functionality is deprecated, and may be removed in a future version. " - "Consider using gmx convert-tpr -nsteps or changing the appropriate .mdp file field."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "The -nsteps functionality is deprecated, and may be removed in a future " + "version. " + "Consider using gmx convert-tpr -nsteps or changing the appropriate .mdp " + "file field."); } /* override nsteps with value set on the commandline */ override_nsteps_cmdline(mdlog, mdrunOptions.numStepsCommandline, inputrec); @@ -1098,11 +1105,14 @@ int Mdrunner::mdrunner() if (inputrec->cutoff_scheme != ecutsVERLET) { - gmx_fatal(FARGS, "This group-scheme .tpr file can no longer be run by mdrun. Please update to the Verlet scheme, or use an earlier version of GROMACS if necessary."); + gmx_fatal(FARGS, + "This group-scheme .tpr file can no longer be run by mdrun. Please update to the " + "Verlet scheme, or use an earlier version of GROMACS if necessary."); } /* Update rlist and nstlist. */ prepare_verlet_scheme(fplog, cr, inputrec, nstlist_cmdline, &mtop, box, - useGpuForNonbonded || (emulateGpuNonbonded == EmulateGpuNonbonded::Yes), *hwinfo->cpuInfo); + useGpuForNonbonded || (emulateGpuNonbonded == EmulateGpuNonbonded::Yes), + *hwinfo->cpuInfo); const bool prefer1DAnd1PulseDD = (devFlags.enableGpuHaloExchange && useGpuForNonbonded); // This builder is necessary while we have multi-part construction @@ -1112,10 +1122,9 @@ int Mdrunner::mdrunner() std::unique_ptr ddBuilder; if (useDomainDecomposition) { - ddBuilder = std::make_unique - (mdlog, cr, domdecOptions, mdrunOptions, - prefer1DAnd1PulseDD, mtop, *inputrec, - box, positionsFromStatePointer(globalState.get())); + ddBuilder = std::make_unique( + mdlog, cr, domdecOptions, mdrunOptions, prefer1DAnd1PulseDD, mtop, *inputrec, box, + positionsFromStatePointer(globalState.get())); } else { @@ -1125,31 +1134,19 @@ int Mdrunner::mdrunner() if (inputrec->ePBC == epbcSCREW) { - gmx_fatal(FARGS, - "pbc=screw is only implemented with domain decomposition"); + gmx_fatal(FARGS, "pbc=screw is only implemented with domain decomposition"); } } // Produce the task assignment for this rank. GpuTaskAssignmentsBuilder gpuTaskAssignmentsBuilder; - GpuTaskAssignments gpuTaskAssignments = - gpuTaskAssignmentsBuilder.build(gpuIdsToUse, - userGpuTaskAssignment, - *hwinfo, - cr, - ms, - physicalNodeComm, - nonbondedTarget, - pmeTarget, - bondedTarget, - updateTarget, - useGpuForNonbonded, - useGpuForPme, - thisRankHasDuty(cr, DUTY_PP), - // TODO cr->duty & DUTY_PME should imply that a PME - // algorithm is active, but currently does not. - EEL_PME(inputrec->coulombtype) && - thisRankHasDuty(cr, DUTY_PME)); + GpuTaskAssignments gpuTaskAssignments = gpuTaskAssignmentsBuilder.build( + gpuIdsToUse, userGpuTaskAssignment, *hwinfo, cr, ms, physicalNodeComm, nonbondedTarget, + pmeTarget, bondedTarget, updateTarget, useGpuForNonbonded, useGpuForPme, + thisRankHasDuty(cr, DUTY_PP), + // TODO cr->duty & DUTY_PME should imply that a PME + // algorithm is active, but currently does not. + EEL_PME(inputrec->coulombtype) && thisRankHasDuty(cr, DUTY_PME)); const bool printHostName = (cr->nnodes > 1); gpuTaskAssignments.reportGpuUsage(mdlog, printHostName, useGpuForBonded, pmeRunMode); @@ -1158,13 +1155,12 @@ int Mdrunner::mdrunner() // where appropriate. if (!userGpuTaskAssignment.empty()) { - gpuTaskAssignments.logPerformanceHints(mdlog, - ssize(gpuIdsToUse)); + gpuTaskAssignments.logPerformanceHints(mdlog, ssize(gpuIdsToUse)); } // Get the device handles for the modules, nullptr when no task is assigned. - gmx_device_info_t *nonbondedDeviceInfo = gpuTaskAssignments.initNonbondedDevice(cr); - gmx_device_info_t *pmeDeviceInfo = gpuTaskAssignments.initPmeDevice(); + gmx_device_info_t* nonbondedDeviceInfo = gpuTaskAssignments.initNonbondedDevice(cr); + gmx_device_info_t* pmeDeviceInfo = gpuTaskAssignments.initPmeDevice(); // TODO Initialize GPU streams here. @@ -1195,19 +1191,20 @@ int Mdrunner::mdrunner() #if GMX_MPI if (isMultiSim(ms)) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "This is simulation %d out of %d running as a composite GROMACS\n" - "multi-simulation job. Setup for this simulation:\n", - ms->sim, ms->nsim); - } - GMX_LOG(mdlog.warning).appendTextFormatted( - "Using %d MPI %s\n", - cr->nnodes, -#if GMX_THREAD_MPI - cr->nnodes == 1 ? "thread" : "threads" -#else - cr->nnodes == 1 ? "process" : "processes" -#endif + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "This is simulation %d out of %d running as a composite GROMACS\n" + "multi-simulation job. Setup for this simulation:\n", + ms->sim, ms->nsim); + } + GMX_LOG(mdlog.warning) + .appendTextFormatted("Using %d MPI %s\n", cr->nnodes, +# if GMX_THREAD_MPI + cr->nnodes == 1 ? "thread" : "threads" +# else + cr->nnodes == 1 ? "process" : "processes" +# endif ); fflush(stderr); #endif @@ -1217,58 +1214,49 @@ int Mdrunner::mdrunner() // that existing affinity setting was from OpenMP or something // else, so we run this code both before and after we initialize // the OpenMP support. - gmx_check_thread_affinity_set(mdlog, - &hw_opt, hwinfo->nthreads_hw_avail, FALSE); + gmx_check_thread_affinity_set(mdlog, &hw_opt, hwinfo->nthreads_hw_avail, FALSE); /* Check and update the number of OpenMP threads requested */ checkAndUpdateRequestedNumOpenmpThreads(&hw_opt, *hwinfo, cr, ms, physicalNodeComm.size_, pmeRunMode, mtop, *inputrec); - gmx_omp_nthreads_init(mdlog, cr, - hwinfo->nthreads_hw_avail, - physicalNodeComm.size_, - hw_opt.nthreads_omp, - hw_opt.nthreads_omp_pme, - !thisRankHasDuty(cr, DUTY_PP)); + gmx_omp_nthreads_init(mdlog, cr, hwinfo->nthreads_hw_avail, physicalNodeComm.size_, + hw_opt.nthreads_omp, hw_opt.nthreads_omp_pme, !thisRankHasDuty(cr, DUTY_PP)); // Enable FP exception detection, but not in // Release mode and not for compilers with known buggy FP // exception support (clang with any optimization) or suspected // buggy FP exception support (gcc 7.* with optimization). -#if !defined NDEBUG && \ - !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \ - && defined __OPTIMIZE__) +#if !defined NDEBUG \ + && !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \ + && defined __OPTIMIZE__) const bool bEnableFPE = true; #else const bool bEnableFPE = false; #endif - //FIXME - reconcile with gmx_feenableexcept() call from CommandLineModuleManager::run() + // FIXME - reconcile with gmx_feenableexcept() call from CommandLineModuleManager::run() if (bEnableFPE) { gmx_feenableexcept(); } /* Now that we know the setup is consistent, check for efficiency */ - check_resource_division_efficiency(hwinfo, - gpuTaskAssignments.thisRankHasAnyGpuTask(), - mdrunOptions.ntompOptionIsSet, - cr, - mdlog); + check_resource_division_efficiency(hwinfo, gpuTaskAssignments.thisRankHasAnyGpuTask(), + mdrunOptions.ntompOptionIsSet, cr, mdlog); /* getting number of PP/PME threads on this MPI / tMPI rank. PME: env variable should be read only on one node to make sure it is identical everywhere; */ - const int numThreadsOnThisRank = - thisRankHasDuty(cr, DUTY_PP) ? gmx_omp_nthreads_get(emntNonbonded) : gmx_omp_nthreads_get(emntPME); - checkHardwareOversubscription(numThreadsOnThisRank, cr->nodeid, - *hwinfo->hardwareTopology, + const int numThreadsOnThisRank = thisRankHasDuty(cr, DUTY_PP) ? gmx_omp_nthreads_get(emntNonbonded) + : gmx_omp_nthreads_get(emntPME); + checkHardwareOversubscription(numThreadsOnThisRank, cr->nodeid, *hwinfo->hardwareTopology, physicalNodeComm, mdlog); // Enable Peer access between GPUs where available // Only for DD, only master PP rank needs to perform setup, and only if thread MPI plus // any of the GPU communication features are active. - if (DOMAINDECOMP(cr) && MASTER(cr) && thisRankHasDuty(cr, DUTY_PP) && GMX_THREAD_MPI && - (devFlags.enableGpuHaloExchange || devFlags.enableGpuPmePPComm)) + if (DOMAINDECOMP(cr) && MASTER(cr) && thisRankHasDuty(cr, DUTY_PP) && GMX_THREAD_MPI + && (devFlags.enableGpuHaloExchange || devFlags.enableGpuPmePPComm)) { setupGpuDevicePeerAccess(gpuIdsToUse, mdlog); } @@ -1279,23 +1267,24 @@ int Mdrunner::mdrunner() * - which indicates that probably the OpenMP library has changed it * since we first checked). */ - gmx_check_thread_affinity_set(mdlog, - &hw_opt, hwinfo->nthreads_hw_avail, TRUE); + gmx_check_thread_affinity_set(mdlog, &hw_opt, hwinfo->nthreads_hw_avail, TRUE); int numThreadsOnThisNode, intraNodeThreadOffset; analyzeThreadsOnThisNode(physicalNodeComm, numThreadsOnThisRank, &numThreadsOnThisNode, &intraNodeThreadOffset); /* Set the CPU affinity */ - gmx_set_thread_affinity(mdlog, cr, &hw_opt, *hwinfo->hardwareTopology, - numThreadsOnThisRank, numThreadsOnThisNode, - intraNodeThreadOffset, nullptr); + gmx_set_thread_affinity(mdlog, cr, &hw_opt, *hwinfo->hardwareTopology, numThreadsOnThisRank, + numThreadsOnThisNode, intraNodeThreadOffset, nullptr); } if (mdrunOptions.timingOptions.resetStep > -1) { - GMX_LOG(mdlog.info).asParagraph(). - appendText("The -resetstep functionality is deprecated, and may be removed in a future version."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "The -resetstep functionality is deprecated, and may be removed in a " + "future version."); } wcycle = wallcycle_init(fplog, mdrunOptions.timingOptions.resetStep, cr); @@ -1318,9 +1307,8 @@ int Mdrunner::mdrunner() /* Note that membed cannot work in parallel because mtop is * changed here. Fix this if we ever want to make it run with * multiple ranks. */ - membed = init_membed(fplog, filenames.size(), filenames.data(), &mtop, inputrec, globalState.get(), cr, - &mdrunOptions - .checkpointOptions.period); + membed = init_membed(fplog, filenames.size(), filenames.data(), &mtop, inputrec, + globalState.get(), cr, &mdrunOptions.checkpointOptions.period); } const bool thisRankHasPmeGpuTask = gpuTaskAssignments.thisRankHasPmeGpuTask(); @@ -1332,34 +1320,36 @@ int Mdrunner::mdrunner() { mdModulesNotifier.notify(*cr); mdModulesNotifier.notify(&atomSets); - mdModulesNotifier.notify(PeriodicBoundaryConditionType {inputrec->ePBC}); - mdModulesNotifier.notify(SimulationTimeStep { inputrec->delta_t }); + mdModulesNotifier.notify(PeriodicBoundaryConditionType{ inputrec->ePBC }); + mdModulesNotifier.notify(SimulationTimeStep{ inputrec->delta_t }); /* Initiate forcerecord */ fr = new t_forcerec; fr->forceProviders = mdModules_->initForceProviders(); - init_forcerec(fplog, mdlog, fr, fcd, - inputrec, &mtop, cr, box, + init_forcerec(fplog, mdlog, fr, fcd, inputrec, &mtop, cr, box, opt2fn("-table", filenames.size(), filenames.data()), opt2fn("-tablep", filenames.size(), filenames.data()), - opt2fns("-tableb", filenames.size(), filenames.data()), - *hwinfo, nonbondedDeviceInfo, - useGpuForBonded, - pmeRunMode == PmeRunMode::GPU && !thisRankHasDuty(cr, DUTY_PME), - pforce, - wcycle); + opt2fns("-tableb", filenames.size(), filenames.data()), *hwinfo, + nonbondedDeviceInfo, useGpuForBonded, + pmeRunMode == PmeRunMode::GPU && !thisRankHasDuty(cr, DUTY_PME), pforce, wcycle); // TODO Move this to happen during domain decomposition setup, // once stream and event handling works well with that. // TODO remove need to pass local stream into GPU halo exchange - Redmine #3093 if (havePPDomainDecomposition(cr) && prefer1DAnd1PulseDD && is1DAnd1PulseDD(*cr->dd)) { - GMX_RELEASE_ASSERT(devFlags.enableGpuBufferOps, "Must use GMX_USE_GPU_BUFFER_OPS=1 to use GMX_GPU_DD_COMMS=1"); - void *streamLocal = Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::Local); - void *streamNonLocal = Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::NonLocal); - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: This run uses the 'GPU halo exchange' feature, enabled by the GMX_GPU_DD_COMMS environment variable."); - cr->dd->gpuHaloExchange = std::make_unique(cr->dd, cr->mpi_comm_mysim, streamLocal, - streamNonLocal); + GMX_RELEASE_ASSERT(devFlags.enableGpuBufferOps, + "Must use GMX_USE_GPU_BUFFER_OPS=1 to use GMX_GPU_DD_COMMS=1"); + void* streamLocal = + Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::Local); + void* streamNonLocal = + Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::NonLocal); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: This run uses the 'GPU halo exchange' feature, enabled by the " + "GMX_GPU_DD_COMMS environment variable."); + cr->dd->gpuHaloExchange = std::make_unique( + cr->dd, cr->mpi_comm_mysim, streamLocal, streamNonLocal); } /* Initialize the mdAtoms structure. @@ -1372,8 +1362,8 @@ int Mdrunner::mdrunner() // The pinning of coordinates in the global state object works, because we only use // PME on GPU without DD or on a separate PME rank, and because the local state pointer // points to the global state object without DD. - // FIXME: MD and EM separately set up the local state - this should happen in the same function, - // which should also perform the pinning. + // FIXME: MD and EM separately set up the local state - this should happen in the same + // function, which should also perform the pinning. changePinningPolicy(&globalState->x, pme_get_pinning_policy()); } @@ -1385,8 +1375,7 @@ int Mdrunner::mdrunner() /* With periodic molecules the charge groups should be whole at start up * and the virtual sites should not be far from their proper positions. */ - if (!inputrec->bContinuation && MASTER(cr) && - !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols)) + if (!inputrec->bContinuation && MASTER(cr) && !(inputrec->ePBC != epbcNONE && inputrec->bPeriodicMols)) { /* Make molecules whole at start of run */ if (fr->ePBC != epbcNONE) @@ -1413,16 +1402,18 @@ int Mdrunner::mdrunner() { /* This is a PME only node */ - GMX_ASSERT(globalState == nullptr, "We don't need the state on a PME only rank and expect it to be unitialized"); + GMX_ASSERT(globalState == nullptr, + "We don't need the state on a PME only rank and expect it to be unitialized"); ewaldcoeff_q = calc_ewaldcoeff_q(inputrec->rcoulomb, inputrec->ewald_rtol); ewaldcoeff_lj = calc_ewaldcoeff_lj(inputrec->rvdw, inputrec->ewald_rtol_lj); } - gmx_pme_t *sepPmeData = nullptr; + gmx_pme_t* sepPmeData = nullptr; // This reference hides the fact that PME data is owned by runner on PME-only ranks and by forcerec on other ranks - GMX_ASSERT(thisRankHasDuty(cr, DUTY_PP) == (fr != nullptr), "Double-checking that only PME-only ranks have no forcerec"); - gmx_pme_t * &pmedata = fr ? fr->pmedata : sepPmeData; + GMX_ASSERT(thisRankHasDuty(cr, DUTY_PP) == (fr != nullptr), + "Double-checking that only PME-only ranks have no forcerec"); + gmx_pme_t*& pmedata = fr ? fr->pmedata : sepPmeData; // TODO should live in ewald module once its testing is improved // @@ -1444,7 +1435,7 @@ int Mdrunner::mdrunner() nChargePerturbed = mdAtoms->mdatoms()->nChargePerturbed; if (EVDW_PME(inputrec->vdwtype)) { - nTypePerturbed = mdAtoms->mdatoms()->nTypePerturbed; + nTypePerturbed = mdAtoms->mdatoms()->nTypePerturbed; } } if (cr->npmenodes > 0) @@ -1458,17 +1449,12 @@ int Mdrunner::mdrunner() { try { - pmedata = gmx_pme_init(cr, - getNumPmeDomains(cr->dd), - inputrec, - nChargePerturbed != 0, nTypePerturbed != 0, - mdrunOptions.reproducible, - ewaldcoeff_q, ewaldcoeff_lj, - gmx_omp_nthreads_get(emntPME), - pmeRunMode, nullptr, - pmeDeviceInfo, pmeGpuProgram.get(), mdlog); + pmedata = gmx_pme_init(cr, getNumPmeDomains(cr->dd), inputrec, nChargePerturbed != 0, + nTypePerturbed != 0, mdrunOptions.reproducible, ewaldcoeff_q, + ewaldcoeff_lj, gmx_omp_nthreads_get(emntPME), pmeRunMode, + nullptr, pmeDeviceInfo, pmeGpuProgram.get(), mdlog); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } @@ -1483,7 +1469,7 @@ int Mdrunner::mdrunner() signal_handler_install(); } - pull_t *pull_work = nullptr; + pull_t* pull_work = nullptr; if (thisRankHasDuty(cr, DUTY_PP)) { /* Assumes uniform use of the number of OpenMP threads */ @@ -1492,18 +1478,15 @@ int Mdrunner::mdrunner() if (inputrec->bPull) { /* Initialize pull code */ - pull_work = - init_pull(fplog, inputrec->pull, inputrec, - &mtop, cr, &atomSets, inputrec->fepvals->init_lambda); + pull_work = init_pull(fplog, inputrec->pull, inputrec, &mtop, cr, &atomSets, + inputrec->fepvals->init_lambda); if (inputrec->pull->bXOutAverage || inputrec->pull->bFOutAverage) { initPullHistory(pull_work, &observablesHistory); } if (EI_DYNAMICS(inputrec->eI) && MASTER(cr)) { - init_pull_output_files(pull_work, - filenames.size(), filenames.data(), oenv, - startingBehavior); + init_pull_output_files(pull_work, filenames.size(), filenames.data(), oenv, startingBehavior); } } @@ -1511,47 +1494,38 @@ int Mdrunner::mdrunner() if (inputrec->bRot) { /* Initialize enforced rotation code */ - enforcedRotation = init_rot(fplog, - inputrec, - filenames.size(), - filenames.data(), - cr, - &atomSets, - globalState.get(), - &mtop, - oenv, - mdrunOptions, - startingBehavior); + enforcedRotation = + init_rot(fplog, inputrec, filenames.size(), filenames.data(), cr, &atomSets, + globalState.get(), &mtop, oenv, mdrunOptions, startingBehavior); } - t_swap *swap = nullptr; + t_swap* swap = nullptr; if (inputrec->eSwapCoords != eswapNO) { /* Initialize ion swapping code */ swap = init_swapcoords(fplog, inputrec, opt2fn_master("-swap", filenames.size(), filenames.data(), cr), - &mtop, globalState.get(), &observablesHistory, - cr, &atomSets, oenv, mdrunOptions, - startingBehavior); + &mtop, globalState.get(), &observablesHistory, cr, &atomSets, + oenv, mdrunOptions, startingBehavior); } /* Let makeConstraints know whether we have essential dynamics constraints. */ - auto constr = makeConstraints(mtop, *inputrec, pull_work, doEssentialDynamics, - fplog, *mdAtoms->mdatoms(), - cr, ms, &nrnb, wcycle, fr->bMolPBC); + auto constr = makeConstraints(mtop, *inputrec, pull_work, doEssentialDynamics, fplog, + *mdAtoms->mdatoms(), cr, ms, &nrnb, wcycle, fr->bMolPBC); /* Energy terms and groups */ - gmx_enerdata_t enerd(mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].size(), inputrec->fepvals->n_lambda); + gmx_enerdata_t enerd(mtop.groups.groups[SimulationAtomGroupType::EnergyOutput].size(), + inputrec->fepvals->n_lambda); /* Kinetic energy data */ gmx_ekindata_t ekind; init_ekindata(fplog, &mtop, &(inputrec->opts), &ekind, inputrec->cos_accel); /* Set up interactive MD (IMD) */ - auto imdSession = makeImdSession(inputrec, cr, wcycle, &enerd, ms, &mtop, mdlog, - MASTER(cr) ? globalState->x.rvec_array() : nullptr, - filenames.size(), filenames.data(), oenv, mdrunOptions.imdOptions, - startingBehavior); + auto imdSession = + makeImdSession(inputrec, cr, wcycle, &enerd, ms, &mtop, mdlog, + MASTER(cr) ? globalState->x.rvec_array() : nullptr, filenames.size(), + filenames.data(), oenv, mdrunOptions.imdOptions, startingBehavior); if (DOMAINDECOMP(cr)) { @@ -1560,48 +1534,48 @@ int Mdrunner::mdrunner() * because fr->cginfo_mb is set later. */ dd_init_bondeds(fplog, cr->dd, &mtop, vsite.get(), inputrec, - domdecOptions.checkBondedInteractions, - fr->cginfo_mb); + domdecOptions.checkBondedInteractions, fr->cginfo_mb); } const bool inputIsCompatibleWithModularSimulator = ModularSimulator::isInputCompatible( - false, - inputrec, doRerun, vsite.get(), ms, replExParams, - fcd, static_cast(filenames.size()), filenames.data(), - &observablesHistory, membed); + false, inputrec, doRerun, vsite.get(), ms, replExParams, fcd, + static_cast(filenames.size()), filenames.data(), &observablesHistory, membed); - const bool useModularSimulator = inputIsCompatibleWithModularSimulator && !(getenv("GMX_DISABLE_MODULAR_SIMULATOR") != nullptr); + const bool useModularSimulator = inputIsCompatibleWithModularSimulator + && !(getenv("GMX_DISABLE_MODULAR_SIMULATOR") != nullptr); // TODO This is not the right place to manage the lifetime of // this data structure, but currently it's the easiest way to // make it work. MdrunScheduleWorkload runScheduleWork; // Also populates the simulation constant workload description. - runScheduleWork.simulationWork = createSimulationWorkload(useGpuForNonbonded, - pmeRunMode, - useGpuForBonded, - useGpuForUpdate, - devFlags.enableGpuBufferOps, - devFlags.enableGpuHaloExchange, - devFlags.enableGpuPmePPComm, - haveEwaldSurfaceContribution(*inputrec)); + runScheduleWork.simulationWork = createSimulationWorkload( + useGpuForNonbonded, pmeRunMode, useGpuForBonded, useGpuForUpdate, + devFlags.enableGpuBufferOps, devFlags.enableGpuHaloExchange, + devFlags.enableGpuPmePPComm, haveEwaldSurfaceContribution(*inputrec)); std::unique_ptr stateGpu; - if (gpusWereDetected && ((useGpuForPme && thisRankHasDuty(cr, DUTY_PME)) || runScheduleWork.simulationWork.useGpuBufferOps)) + if (gpusWereDetected + && ((useGpuForPme && thisRankHasDuty(cr, DUTY_PME)) + || runScheduleWork.simulationWork.useGpuBufferOps)) { - const void *pmeStream = pme_gpu_get_device_stream(fr->pmedata); - const void *localStream = fr->nbv->gpu_nbv != nullptr ? Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::Local) : nullptr; - const void *nonLocalStream = fr->nbv->gpu_nbv != nullptr ? Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::NonLocal) : nullptr; - const void *deviceContext = pme_gpu_get_device_context(fr->pmedata); - const int paddingSize = pme_gpu_get_padding_size(fr->pmedata); - GpuApiCallBehavior transferKind = (inputrec->eI == eiMD && !doRerun && !useModularSimulator) ? GpuApiCallBehavior::Async : GpuApiCallBehavior::Sync; - - stateGpu = std::make_unique(pmeStream, - localStream, - nonLocalStream, - deviceContext, - transferKind, - paddingSize); + const void* pmeStream = pme_gpu_get_device_stream(fr->pmedata); + const void* localStream = + fr->nbv->gpu_nbv != nullptr + ? Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::Local) + : nullptr; + const void* nonLocalStream = + fr->nbv->gpu_nbv != nullptr + ? Nbnxm::gpu_get_command_stream(fr->nbv->gpu_nbv, InteractionLocality::NonLocal) + : nullptr; + const void* deviceContext = pme_gpu_get_device_context(fr->pmedata); + const int paddingSize = pme_gpu_get_padding_size(fr->pmedata); + GpuApiCallBehavior transferKind = (inputrec->eI == eiMD && !doRerun && !useModularSimulator) + ? GpuApiCallBehavior::Async + : GpuApiCallBehavior::Sync; + + stateGpu = std::make_unique( + pmeStream, localStream, nonLocalStream, deviceContext, transferKind, paddingSize); fr->stateGpu = stateGpu.get(); } @@ -1610,29 +1584,14 @@ int Mdrunner::mdrunner() // build and run simulator object based on user-input auto simulator = simulatorBuilder.build( - inputIsCompatibleWithModularSimulator, - fplog, cr, ms, mdlog, static_cast(filenames.size()), filenames.data(), - oenv, - mdrunOptions, - startingBehavior, - vsite.get(), constr.get(), - enforcedRotation ? enforcedRotation->getLegacyEnfrot() : nullptr, - deform.get(), - mdModules_->outputProvider(), - mdModules_->notifier(), - inputrec, imdSession.get(), pull_work, swap, &mtop, - fcd, - globalState.get(), - &observablesHistory, - mdAtoms.get(), &nrnb, wcycle, fr, - &enerd, - &ekind, - &runScheduleWork, - replExParams, - membed, - walltime_accounting, - std::move(stopHandlerBuilder_), - doRerun); + inputIsCompatibleWithModularSimulator, fplog, cr, ms, mdlog, + static_cast(filenames.size()), filenames.data(), oenv, mdrunOptions, + startingBehavior, vsite.get(), constr.get(), + enforcedRotation ? enforcedRotation->getLegacyEnfrot() : nullptr, deform.get(), + mdModules_->outputProvider(), mdModules_->notifier(), inputrec, imdSession.get(), + pull_work, swap, &mtop, fcd, globalState.get(), &observablesHistory, mdAtoms.get(), + &nrnb, wcycle, fr, &enerd, &ekind, &runScheduleWork, replExParams, membed, + walltime_accounting, std::move(stopHandlerBuilder_), doRerun); simulator->run(); if (inputrec->bPull) @@ -1654,16 +1613,13 @@ int Mdrunner::mdrunner() /* Finish up, write some stuff * if rerunMD, don't write last frame again */ - finish_run(fplog, mdlog, cr, - inputrec, &nrnb, wcycle, walltime_accounting, - fr ? fr->nbv.get() : nullptr, - pmedata, - EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms)); + finish_run(fplog, mdlog, cr, inputrec, &nrnb, wcycle, walltime_accounting, + fr ? fr->nbv.get() : nullptr, pmedata, EI_DYNAMICS(inputrec->eI) && !isMultiSim(ms)); // clean up cycle counter wallcycle_destroy(wcycle); -// Free PME data + // Free PME data if (pmedata) { gmx_pme_destroy(pmedata); @@ -1676,7 +1632,7 @@ int Mdrunner::mdrunner() // As soon as we destroy GPU contexts after mdrunner() exits, these lines should go. mdAtoms.reset(nullptr); globalState.reset(nullptr); - mdModules_.reset(nullptr); // destruct force providers here as they might also use the GPU + mdModules_.reset(nullptr); // destruct force providers here as they might also use the GPU /* Free GPU memory and set a physical node tMPI barrier (which should eventually go away) */ free_gpu_resources(fr, physicalNodeComm, hwinfo->gpu_info); @@ -1731,12 +1687,12 @@ Mdrunner::~Mdrunner() { restraintManager_->clear(); GMX_ASSERT(restraintManager_->countRestraints() == 0, - "restraints added during runner life time should be cleared at runner destruction."); + "restraints added during runner life time should be cleared at runner " + "destruction."); } }; -void Mdrunner::addPotential(std::shared_ptr puller, - const std::string &name) +void Mdrunner::addPotential(std::shared_ptr puller, const std::string& name) { GMX_ASSERT(restraintManager_, "Mdrunner must have a restraint manager."); // Not sure if this should be logged through the md logger or something else, @@ -1745,122 +1701,116 @@ void Mdrunner::addPotential(std::shared_ptr puller, // When multiple restraints are used, it may be wasteful to register them separately. // Maybe instead register an entire Restraint Manager as a force provider. - restraintManager_->addToSpec(std::move(puller), - name); + restraintManager_->addToSpec(std::move(puller), name); } -Mdrunner::Mdrunner(std::unique_ptr mdModules) - : mdModules_(std::move(mdModules)) -{ -} +Mdrunner::Mdrunner(std::unique_ptr mdModules) : mdModules_(std::move(mdModules)) {} -Mdrunner::Mdrunner(Mdrunner &&) noexcept = default; +Mdrunner::Mdrunner(Mdrunner&&) noexcept = default; //NOLINTNEXTLINE(performance-noexcept-move-constructor) working around GCC bug 58265 -Mdrunner &Mdrunner::operator=(Mdrunner && /*handle*/) noexcept(BUGFREE_NOEXCEPT_STRING) = default; +Mdrunner& Mdrunner::operator=(Mdrunner&& /*handle*/) noexcept(BUGFREE_NOEXCEPT_STRING) = default; class Mdrunner::BuilderImplementation { - public: - BuilderImplementation() = delete; - BuilderImplementation(std::unique_ptr mdModules, - compat::not_null context); - ~BuilderImplementation(); - - BuilderImplementation &setExtraMdrunOptions(const MdrunOptions &options, - real forceWarningThreshold, - StartingBehavior startingBehavior); +public: + BuilderImplementation() = delete; + BuilderImplementation(std::unique_ptr mdModules, compat::not_null context); + ~BuilderImplementation(); - void addDomdec(const DomdecOptions &options); + BuilderImplementation& setExtraMdrunOptions(const MdrunOptions& options, + real forceWarningThreshold, + StartingBehavior startingBehavior); - void addVerletList(int nstlist); + void addDomdec(const DomdecOptions& options); - void addReplicaExchange(const ReplicaExchangeParameters ¶ms); + void addVerletList(int nstlist); - void addNonBonded(const char* nbpu_opt); + void addReplicaExchange(const ReplicaExchangeParameters& params); - void addPME(const char* pme_opt_, const char* pme_fft_opt_); + void addNonBonded(const char* nbpu_opt); - void addBondedTaskAssignment(const char* bonded_opt); + void addPME(const char* pme_opt_, const char* pme_fft_opt_); - void addUpdateTaskAssignment(const char* update_opt); + void addBondedTaskAssignment(const char* bonded_opt); - void addHardwareOptions(const gmx_hw_opt_t &hardwareOptions); + void addUpdateTaskAssignment(const char* update_opt); - void addFilenames(ArrayRef filenames); + void addHardwareOptions(const gmx_hw_opt_t& hardwareOptions); - void addOutputEnvironment(gmx_output_env_t* outputEnvironment); + void addFilenames(ArrayRef filenames); - void addLogFile(t_fileio *logFileHandle); + void addOutputEnvironment(gmx_output_env_t* outputEnvironment); - void addStopHandlerBuilder(std::unique_ptr builder); + void addLogFile(t_fileio* logFileHandle); - Mdrunner build(); + void addStopHandlerBuilder(std::unique_ptr builder); - private: + Mdrunner build(); - // Default parameters copied from runner.h - // \todo Clarify source(s) of default parameters. +private: + // Default parameters copied from runner.h + // \todo Clarify source(s) of default parameters. - const char* nbpu_opt_ = nullptr; - const char* pme_opt_ = nullptr; - const char* pme_fft_opt_ = nullptr; - const char *bonded_opt_ = nullptr; - const char *update_opt_ = nullptr; + const char* nbpu_opt_ = nullptr; + const char* pme_opt_ = nullptr; + const char* pme_fft_opt_ = nullptr; + const char* bonded_opt_ = nullptr; + const char* update_opt_ = nullptr; - MdrunOptions mdrunOptions_; + MdrunOptions mdrunOptions_; - DomdecOptions domdecOptions_; + DomdecOptions domdecOptions_; - ReplicaExchangeParameters replicaExchangeParameters_; + ReplicaExchangeParameters replicaExchangeParameters_; - //! Command-line override for the duration of a neighbor list with the Verlet scheme. - int nstlist_ = 0; + //! Command-line override for the duration of a neighbor list with the Verlet scheme. + int nstlist_ = 0; - //! Multisim communicator handle. - gmx_multisim_t *multiSimulation_; + //! Multisim communicator handle. + gmx_multisim_t* multiSimulation_; - //! mdrun communicator - MPI_Comm communicator_ = MPI_COMM_NULL; + //! mdrun communicator + MPI_Comm communicator_ = MPI_COMM_NULL; - //! Print a warning if any force is larger than this (in kJ/mol nm). - real forceWarningThreshold_ = -1; + //! Print a warning if any force is larger than this (in kJ/mol nm). + real forceWarningThreshold_ = -1; - //! Whether the simulation will start afresh, or restart with/without appending. - StartingBehavior startingBehavior_ = StartingBehavior::NewSimulation; + //! Whether the simulation will start afresh, or restart with/without appending. + StartingBehavior startingBehavior_ = StartingBehavior::NewSimulation; - //! The modules that comprise the functionality of mdrun. - std::unique_ptr mdModules_; + //! The modules that comprise the functionality of mdrun. + std::unique_ptr mdModules_; - //! \brief Parallelism information. - gmx_hw_opt_t hardwareOptions_; + //! \brief Parallelism information. + gmx_hw_opt_t hardwareOptions_; - //! filename options for simulation. - ArrayRef filenames_; - - /*! \brief Handle to output environment. - * - * \todo gmx_output_env_t needs lifetime management. - */ - gmx_output_env_t* outputEnvironment_ = nullptr; + //! filename options for simulation. + ArrayRef filenames_; - /*! \brief Non-owning handle to MD log file. - * - * \todo Context should own output facilities for client. - * \todo Improve log file handle management. - * \internal - * Code managing the FILE* relies on the ability to set it to - * nullptr to check whether the filehandle is valid. - */ - t_fileio* logFileHandle_ = nullptr; + /*! \brief Handle to output environment. + * + * \todo gmx_output_env_t needs lifetime management. + */ + gmx_output_env_t* outputEnvironment_ = nullptr; + + /*! \brief Non-owning handle to MD log file. + * + * \todo Context should own output facilities for client. + * \todo Improve log file handle management. + * \internal + * Code managing the FILE* relies on the ability to set it to + * nullptr to check whether the filehandle is valid. + */ + t_fileio* logFileHandle_ = nullptr; - /*! - * \brief Builder for simulation stop signal handler. - */ - std::unique_ptr stopHandlerBuilder_ = nullptr; + /*! + * \brief Builder for simulation stop signal handler. + */ + std::unique_ptr stopHandlerBuilder_ = nullptr; }; -Mdrunner::BuilderImplementation::BuilderImplementation(std::unique_ptr mdModules, +Mdrunner::BuilderImplementation::BuilderImplementation(std::unique_ptr mdModules, compat::not_null context) : mdModules_(std::move(mdModules)) { @@ -1870,8 +1820,8 @@ Mdrunner::BuilderImplementation::BuilderImplementation(std::unique_ptr mdModules, compat::not_null context) : - impl_ {std::make_unique(std::move(mdModules), context)} + impl_{ std::make_unique(std::move(mdModules), context) } { } MdrunnerBuilder::~MdrunnerBuilder() = default; -MdrunnerBuilder &MdrunnerBuilder::addSimulationMethod(const MdrunOptions &options, +MdrunnerBuilder& MdrunnerBuilder::addSimulationMethod(const MdrunOptions& options, real forceWarningThreshold, const StartingBehavior startingBehavior) { @@ -2049,32 +2001,31 @@ MdrunnerBuilder &MdrunnerBuilder::addSimulationMethod(const MdrunOptions &opt return *this; } -MdrunnerBuilder &MdrunnerBuilder::addDomainDecomposition(const DomdecOptions &options) +MdrunnerBuilder& MdrunnerBuilder::addDomainDecomposition(const DomdecOptions& options) { impl_->addDomdec(options); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addNeighborList(int nstlist) +MdrunnerBuilder& MdrunnerBuilder::addNeighborList(int nstlist) { impl_->addVerletList(nstlist); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addReplicaExchange(const ReplicaExchangeParameters ¶ms) +MdrunnerBuilder& MdrunnerBuilder::addReplicaExchange(const ReplicaExchangeParameters& params) { impl_->addReplicaExchange(params); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addNonBonded(const char* nbpu_opt) +MdrunnerBuilder& MdrunnerBuilder::addNonBonded(const char* nbpu_opt) { impl_->addNonBonded(nbpu_opt); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addElectrostatics(const char* pme_opt, - const char* pme_fft_opt) +MdrunnerBuilder& MdrunnerBuilder::addElectrostatics(const char* pme_opt, const char* pme_fft_opt) { // The builder method may become more general in the future, but in this version, // parameters for PME electrostatics are both required and the only parameters @@ -2085,18 +2036,19 @@ MdrunnerBuilder &MdrunnerBuilder::addElectrostatics(const char* pme_opt, } else { - GMX_THROW(gmx::InvalidInputError("addElectrostatics() arguments must be non-null pointers.")); + GMX_THROW( + gmx::InvalidInputError("addElectrostatics() arguments must be non-null pointers.")); } return *this; } -MdrunnerBuilder &MdrunnerBuilder::addBondedTaskAssignment(const char* bonded_opt) +MdrunnerBuilder& MdrunnerBuilder::addBondedTaskAssignment(const char* bonded_opt) { impl_->addBondedTaskAssignment(bonded_opt); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addUpdateTaskAssignment(const char* update_opt) +MdrunnerBuilder& MdrunnerBuilder::addUpdateTaskAssignment(const char* update_opt) { impl_->addUpdateTaskAssignment(update_opt); return *this; @@ -2107,38 +2059,38 @@ Mdrunner MdrunnerBuilder::build() return impl_->build(); } -MdrunnerBuilder &MdrunnerBuilder::addHardwareOptions(const gmx_hw_opt_t &hardwareOptions) +MdrunnerBuilder& MdrunnerBuilder::addHardwareOptions(const gmx_hw_opt_t& hardwareOptions) { impl_->addHardwareOptions(hardwareOptions); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addFilenames(ArrayRef filenames) +MdrunnerBuilder& MdrunnerBuilder::addFilenames(ArrayRef filenames) { impl_->addFilenames(filenames); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addOutputEnvironment(gmx_output_env_t* outputEnvironment) +MdrunnerBuilder& MdrunnerBuilder::addOutputEnvironment(gmx_output_env_t* outputEnvironment) { impl_->addOutputEnvironment(outputEnvironment); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addLogFile(t_fileio *logFileHandle) +MdrunnerBuilder& MdrunnerBuilder::addLogFile(t_fileio* logFileHandle) { impl_->addLogFile(logFileHandle); return *this; } -MdrunnerBuilder &MdrunnerBuilder::addStopHandlerBuilder(std::unique_ptr builder) +MdrunnerBuilder& MdrunnerBuilder::addStopHandlerBuilder(std::unique_ptr builder) { impl_->addStopHandlerBuilder(std::move(builder)); return *this; } -MdrunnerBuilder::MdrunnerBuilder(MdrunnerBuilder &&) noexcept = default; +MdrunnerBuilder::MdrunnerBuilder(MdrunnerBuilder&&) noexcept = default; -MdrunnerBuilder &MdrunnerBuilder::operator=(MdrunnerBuilder &&) noexcept = default; +MdrunnerBuilder& MdrunnerBuilder::operator=(MdrunnerBuilder&&) noexcept = default; } // namespace gmx diff --git a/src/gromacs/mdrun/runner.h b/src/gromacs/mdrun/runner.h index 9c642f279e..82eccd97d5 100644 --- a/src/gromacs/mdrun/runner.h +++ b/src/gromacs/mdrun/runner.h @@ -108,199 +108,198 @@ constexpr bool BUGFREE_NOEXCEPT_STRING = std::is_nothrow_move_assignable restraint, - const std::string &name); - - /*! \brief Prepare the thread-MPI communicator to have \c - * numThreadsToLaunch ranks, by spawning new thread-MPI - * threads. - * - * Called by mdrunner() to start a specific number of threads - * (including the main thread) for thread-parallel runs. This - * in turn calls mdrunner() for each thread. */ - void spawnThreads(int numThreadsToLaunch); - - /*! \brief Initializes a new Mdrunner from the master. - * - * Run this method in a new thread from a master runner to get additional - * workers on spawned threads. - * - * \returns New Mdrunner instance suitable for thread-MPI work on new ranks. - * - * \internal - * \todo clarify (multiple) invariants during MD runner start-up. - * The runner state before and after launching threads is distinct enough that - * it should be codified in the invariants of different classes. That would - * mean that the object returned by this method would be of a different type - * than the object held by the client up to the point of call, and its name - * would be changed to "launchOnSpawnedThread" or something not including the - * word "clone". - */ - Mdrunner cloneOnSpawnedThread() const; - - private: - /*! \brief Constructor. */ - explicit Mdrunner(std::unique_ptr mdModules); - - //! Parallelism-related user options. - gmx_hw_opt_t hw_opt; - - //! Filenames and properties from command-line argument values. - ArrayRef filenames; - - /*! \brief Output context for writing text files - * - * \internal - * \todo push this data member down when the information can be queried from an encapsulated resource. - */ - gmx_output_env_t *oenv = nullptr; - //! Ongoing collection of mdrun options - MdrunOptions mdrunOptions; - //! Options for the domain decomposition. - DomdecOptions domdecOptions; - - /*! \brief Target short-range interations for "cpu", "gpu", or "auto". Default is "auto". - * - * \internal - * \todo replace with string or enum class and initialize with sensible value. - */ - const char *nbpu_opt = nullptr; - - /*! \brief Target long-range interactions for "cpu", "gpu", or "auto". Default is "auto". - * - * \internal - * \todo replace with string or enum class and initialize with sensible value. - */ - const char *pme_opt = nullptr; - - /*! \brief Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto". Default is "auto". - * - * \internal - * \todo replace with string or enum class and initialize with sensible value. - */ - const char *pme_fft_opt = nullptr; - - /*! \brief Target bonded interations for "cpu", "gpu", or "auto". Default is "auto". - * - * \internal - * \todo replace with string or enum class and initialize with sensible value. - */ - const char *bonded_opt = nullptr; - - /*! \brief Target update calculation for "cpu", "gpu", or "auto". Default is "auto". - * - * \internal - * \todo replace with string or enum class and initialize with sensible value. - */ - const char *update_opt = nullptr; - - //! Command-line override for the duration of a neighbor list with the Verlet scheme. - int nstlist_cmdline = 0; - //! Parameters for replica-exchange simulations. - ReplicaExchangeParameters replExParams; - //! Print a warning if any force is larger than this (in kJ/mol nm). - real pforce = -1; - - //! Handle to file used for logging. - LogFilePtr logFileGuard = nullptr; - //! \brief Non-owning handle to file used for logging. - t_fileio *logFileHandle = nullptr; - - /*! \brief Non-owning handle to communication data structure. - * - * With real MPI, gets a value from the SimulationContext - * supplied to the MdrunnerBuilder. With thread-MPI gets a - * value after threads have been spawned. */ - MPI_Comm communicator = MPI_COMM_NULL; - - //! \brief Non-owning handle to multi-simulation handler. - gmx_multisim_t *ms = nullptr; - - //! Whether the simulation will start afresh, or restart with/without appending. - StartingBehavior startingBehavior = StartingBehavior::NewSimulation; - - /*! - * \brief Handle to restraints manager for the current process. - * - * \internal - * Use opaque pointer for this implementation detail. - */ - std::unique_ptr restraintManager_; - - /*! - * \brief Builder for stop signal handler - * - * Optionally provided through MdrunnerBuilder. Client may create a - * StopHandlerBuilder and register any number of signal providers before - * launching the Mdrunner. - * - * Default is an empty signal handler that will have local signal issuers - * added after being passed into the integrator. - * - * \internal - * We do not need a full type specification here, so we use an opaque pointer. - */ - std::unique_ptr stopHandlerBuilder_; - //! The modules that comprise mdrun. - std::unique_ptr mdModules_; +public: + /*! \brief Builder class to manage object creation. + * + * This class is a member of gmx::Mdrunner so that it can initialize + * private members of gmx::Mdrunner. + * + * It is non-trivial to establish an initialized gmx::Mdrunner invariant, + * so objects can be obtained by clients using a Builder or a move. + * Clients cannot default initialize or copy gmx::Mdrunner. + */ + class BuilderImplementation; + + ~Mdrunner(); + + /*! + * \brief Copy not allowed. + * + * An Mdrunner has unique resources and it is not clear whether any of + * one of those resources should be duplicated or shared unless the + * specific use case is known. Either build a fresh runner or use a + * helper function for clearly indicated behavior. API clarification may + * allow unambiguous initialization by copy in future versions. + * + * \{ + */ + Mdrunner(const Mdrunner&) = delete; + Mdrunner& operator=(const Mdrunner&) = delete; + /* \} */ + + /*! + * \brief Mdrunner objects can be passed by value via move semantics. + * + * \param handle runner instance to be moved from. + * \{ + */ + Mdrunner(Mdrunner&& handle) noexcept; + //NOLINTNEXTLINE(performance-noexcept-move-constructor) working around GCC bug 58265 + Mdrunner& operator=(Mdrunner&& handle) noexcept(BUGFREE_NOEXCEPT_STRING); + /* \} */ + + /*! \brief Driver routine, that calls the different simulation methods. */ + /*! + * Currently, thread-MPI does not spawn threads until during mdrunner() and parallelism + * is not initialized until some time during this call... + */ + int mdrunner(); + + /*! + * \brief Add a potential to be evaluated during MD integration. + * + * \param restraint MD restraint potential to apply + * \param name User-friendly plain-text name to uniquely identify the puller + * + * This implementation attaches an object providing the gmx::IRestraintPotential + * interface. + * \todo Mdrunner should fetch such resources from the SimulationContext + * rather than offering this public interface. + */ + void addPotential(std::shared_ptr restraint, const std::string& name); + + /*! \brief Prepare the thread-MPI communicator to have \c + * numThreadsToLaunch ranks, by spawning new thread-MPI + * threads. + * + * Called by mdrunner() to start a specific number of threads + * (including the main thread) for thread-parallel runs. This + * in turn calls mdrunner() for each thread. */ + void spawnThreads(int numThreadsToLaunch); + + /*! \brief Initializes a new Mdrunner from the master. + * + * Run this method in a new thread from a master runner to get additional + * workers on spawned threads. + * + * \returns New Mdrunner instance suitable for thread-MPI work on new ranks. + * + * \internal + * \todo clarify (multiple) invariants during MD runner start-up. + * The runner state before and after launching threads is distinct enough that + * it should be codified in the invariants of different classes. That would + * mean that the object returned by this method would be of a different type + * than the object held by the client up to the point of call, and its name + * would be changed to "launchOnSpawnedThread" or something not including the + * word "clone". + */ + Mdrunner cloneOnSpawnedThread() const; + +private: + /*! \brief Constructor. */ + explicit Mdrunner(std::unique_ptr mdModules); + + //! Parallelism-related user options. + gmx_hw_opt_t hw_opt; + + //! Filenames and properties from command-line argument values. + ArrayRef filenames; + + /*! \brief Output context for writing text files + * + * \internal + * \todo push this data member down when the information can be queried from an encapsulated resource. + */ + gmx_output_env_t* oenv = nullptr; + //! Ongoing collection of mdrun options + MdrunOptions mdrunOptions; + //! Options for the domain decomposition. + DomdecOptions domdecOptions; + + /*! \brief Target short-range interations for "cpu", "gpu", or "auto". Default is "auto". + * + * \internal + * \todo replace with string or enum class and initialize with sensible value. + */ + const char* nbpu_opt = nullptr; + + /*! \brief Target long-range interactions for "cpu", "gpu", or "auto". Default is "auto". + * + * \internal + * \todo replace with string or enum class and initialize with sensible value. + */ + const char* pme_opt = nullptr; + + /*! \brief Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto". Default is "auto". + * + * \internal + * \todo replace with string or enum class and initialize with sensible value. + */ + const char* pme_fft_opt = nullptr; + + /*! \brief Target bonded interations for "cpu", "gpu", or "auto". Default is "auto". + * + * \internal + * \todo replace with string or enum class and initialize with sensible value. + */ + const char* bonded_opt = nullptr; + + /*! \brief Target update calculation for "cpu", "gpu", or "auto". Default is "auto". + * + * \internal + * \todo replace with string or enum class and initialize with sensible value. + */ + const char* update_opt = nullptr; + + //! Command-line override for the duration of a neighbor list with the Verlet scheme. + int nstlist_cmdline = 0; + //! Parameters for replica-exchange simulations. + ReplicaExchangeParameters replExParams; + //! Print a warning if any force is larger than this (in kJ/mol nm). + real pforce = -1; + + //! Handle to file used for logging. + LogFilePtr logFileGuard = nullptr; + //! \brief Non-owning handle to file used for logging. + t_fileio* logFileHandle = nullptr; + + /*! \brief Non-owning handle to communication data structure. + * + * With real MPI, gets a value from the SimulationContext + * supplied to the MdrunnerBuilder. With thread-MPI gets a + * value after threads have been spawned. */ + MPI_Comm communicator = MPI_COMM_NULL; + + //! \brief Non-owning handle to multi-simulation handler. + gmx_multisim_t* ms = nullptr; + + //! Whether the simulation will start afresh, or restart with/without appending. + StartingBehavior startingBehavior = StartingBehavior::NewSimulation; + + /*! + * \brief Handle to restraints manager for the current process. + * + * \internal + * Use opaque pointer for this implementation detail. + */ + std::unique_ptr restraintManager_; + + /*! + * \brief Builder for stop signal handler + * + * Optionally provided through MdrunnerBuilder. Client may create a + * StopHandlerBuilder and register any number of signal providers before + * launching the Mdrunner. + * + * Default is an empty signal handler that will have local signal issuers + * added after being passed into the integrator. + * + * \internal + * We do not need a full type specification here, so we use an opaque pointer. + */ + std::unique_ptr stopHandlerBuilder_; + //! The modules that comprise mdrun. + std::unique_ptr mdModules_; }; /*! \libinternal @@ -346,256 +345,255 @@ class Mdrunner */ class MdrunnerBuilder final { - public: - /*! - * \brief Constructor requires a handle to a SimulationContext to share. - * - * \param mdModules The handle to the set of modules active in mdrun - * \param context Required handle to simulation context - * - * The calling code must guarantee that the - * pointer remains valid for the lifetime of the builder, and that the - * resources retrieved from the context remain valid for the lifetime of - * the runner produced. - */ - explicit MdrunnerBuilder(std::unique_ptr mdModules, - compat::not_null context); - - //! \cond - MdrunnerBuilder() = delete; - MdrunnerBuilder(const MdrunnerBuilder&) = delete; - MdrunnerBuilder &operator=(const MdrunnerBuilder &) = delete; - //! \endcond - - /*! \brief Allow transfer of ownership with move semantics. - * - * \param builder source object to transfer. - * - * \{ - */ - MdrunnerBuilder(MdrunnerBuilder && builder) noexcept; - MdrunnerBuilder &operator=(MdrunnerBuilder &&builder) noexcept; - //! \} - - /*! - * \brief Get ownership of an initialized gmx::Mdrunner. - * - * After build() is called, the Builder object should not be used - * again. It is an error to call build without first calling all builder - * methods described as "required." - * - * \return A new Mdrunner. - * - * \throws APIError if a required component has not been added before calling build(). - */ - Mdrunner build(); - - /*! - * \brief Set up non-bonded short-range force calculations. - * - * Required. Director code must provide valid options for the non-bonded - * interaction code. The builder does not apply any defaults. - * - * \param nbpu_opt Target short-range interactions for "cpu", "gpu", or "auto". - * - * Calling must guarantee that the pointed-to C string is valid through - * simulation launch. - * - * \internal - * \todo Replace with string or enum that we can have sensible defaults for. - * \todo Either the Builder or modular Director code should provide sensible defaults. - */ - MdrunnerBuilder &addNonBonded(const char* nbpu_opt); - - /*! - * \brief Set up long-range electrostatics calculations. - * - * Required. Director code should provide valid options for PME electrostatics, - * whether or not PME electrostatics are used. The builder does not apply - * any defaults, so client code should be prepared to provide (e.g.) "auto" - * in the event no user input or logic provides an alternative argument. - * - * \param pme_opt Target long-range interactions for "cpu", "gpu", or "auto". - * \param pme_fft_opt Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto". - * - * Calling must guarantee that the pointed-to C strings are valid through - * simulation launch. - * - * \internal - * The arguments are passed as references to elements of arrays of C strings. - * \todo Replace with modern strings or (better) enum classes. - * \todo Make optional and/or encapsulate into electrostatics module. - */ - MdrunnerBuilder &addElectrostatics(const char* pme_opt, - const char* pme_fft_opt); - - /*! - * \brief Assign responsibility for tasks for bonded interactions. - * - * Required. Director code should provide valid options for - * bonded interaction task assignment, whether or not such - * interactions are present. The builder does not apply any - * defaults, so client code should be prepared to provide - * (e.g.) "auto" in the event no user input or logic provides - * an alternative argument. - * - * \param bonded_opt Target bonded interactions for "cpu", "gpu", or "auto". - * - * Calling must guarantee that the pointed-to C strings are valid through - * simulation launch. - * - * \internal - * The arguments are passed as references to elements of arrays of C strings. - * \todo Replace with modern strings or (better) enum classes. - * \todo Make optional and/or encapsulate into task assignment module. - */ - MdrunnerBuilder &addBondedTaskAssignment(const char *bonded_opt); - - /*! \brief - * Assign responsibility for tasks for update and constrain calculation. - * - * Required. Director code should provide valid options for - * update and constraint task assignment. The builder does not apply any - * defaults, so client code should be prepared to provide - * (e.g.) "auto" in the event no user input or logic provides - * an alternative argument. - * - * \param[in] update_opt Target update calculation for "cpu", "gpu", or "auto". - * - * Calling must guarantee that the pointed-to C strings are valid through - * simulation launch. - * - * \internal - * The arguments are passed as references to elements of arrays of C strings. - * \todo Replace with modern strings or (better) enum classes. - * \todo Make optional and/or encapsulate into task assignment module. - */ - MdrunnerBuilder &addUpdateTaskAssignment(const char *update_opt); - - /*! - * \brief Set MD options not owned by some other module. - * - * Optional. Override simulation parameters - * - * \param options structure to copy - * \param forceWarningThreshold Print a warning if any force is larger than this (in kJ/mol nm) (default -1) - * \param startingBehavior Whether the simulation will start afresh, or restart with/without appending. - * - * \internal - * \todo Map these parameters to more appropriate encapsulating types. - * Find a better way to indicate "unspecified" than a magic value of the parameter type. - */ - MdrunnerBuilder &addSimulationMethod(const MdrunOptions &options, - real forceWarningThreshold, - StartingBehavior startingBehavior); - - /*! - * \brief Set the domain decomposition module. - * - * Optional. Overrides default constructed DomdecOptions if provided. - * - * \param options options with which to construct domain decomposition. - * - * \internal - * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort. - */ - MdrunnerBuilder &addDomainDecomposition(const DomdecOptions &options); - - /*! - * \brief Set Verlet list manager. - * - * Optional. Neighbor list existence, type, and parameters are mostly determined - * by the simulation parameters loaded elsewhere. This is just an override. - * - * \param rebuildInterval override for the duration of a neighbor list with the Verlet scheme. - */ - MdrunnerBuilder &addNeighborList(int rebuildInterval); - - /*! - * \brief Set replica exchange manager. - * - * Optional. For guidance on preparing a valid ReplicaExchangeParameters - * value, refer to the details in mdrun.cpp, the `t_pargs pa[]` defined there, - * and the action of parse_common_args() with regards to that structure. - * If not provided by client, a default constructed ReplicaExchangeParameters - * is used. - * - * \param params parameters with which to set up replica exchange. - * - * \internal - * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort. - */ - MdrunnerBuilder &addReplicaExchange(const ReplicaExchangeParameters ¶ms); - - /*! - * \brief Specify parameters determining hardware resource allocation. - * - * Optional. If not provided, default-constructed gmx_hw_opt_t will be used. - * - * \param hardwareOptions Parallelism-related user options. - */ - MdrunnerBuilder &addHardwareOptions(const gmx_hw_opt_t &hardwareOptions); - - /*! - * \brief Provide the filenames options structure with option values chosen - * - * Required. The object is assumed to have been updated by - * parse_common_args or equivalent. - * - * \param filenames Filenames and properties from command-line argument values or defaults. - * - * \internal - * \todo Modules should manage their own filename options and defaults. - */ - MdrunnerBuilder &addFilenames(ArrayRef filenames); - - /*! - * \brief Provide parameters for setting up output environment. - * - * Required. Handle is assumed to have been produced by output_env_init - * as in parse_common_args. - * - * \param outputEnvironment Output context for writing text files. - * - * \internal - * \todo Allow client code to set up output environment and provide as a resource. - * This parameter is used to set up resources that are dependent on the execution - * environment and API context. Such resources should be retrieved by the simulator - * from a client-provided resource, but currently the resources are only fully - * initialized in Mdrunner. - */ - MdrunnerBuilder &addOutputEnvironment(gmx_output_env_t* outputEnvironment); - - /*! - * \brief Provide the filehandle pointer to be used for the MD log. - * - * Required. Either nullptr if no log should be written, or - * valid and open reading for writing. - * - * \param logFileHandle Non-owning handle to file used for logging. - * \internal - */ - MdrunnerBuilder &addLogFile(t_fileio *logFileHandle); - - /*! - * \brief Provide a StopHandlerBuilder for the MD stop signal handling. - * - * Optional. Defaults to empty. - * - * Client may provide additional (non-default) issuers of simulation stop - * signals by preconfiguring the StopHandlerBuilder used later when the - * simulation runs. - * - * \param builder - */ - MdrunnerBuilder &addStopHandlerBuilder(std::unique_ptr builder); - - ~MdrunnerBuilder(); - - private: - std::unique_ptr impl_; +public: + /*! + * \brief Constructor requires a handle to a SimulationContext to share. + * + * \param mdModules The handle to the set of modules active in mdrun + * \param context Required handle to simulation context + * + * The calling code must guarantee that the + * pointer remains valid for the lifetime of the builder, and that the + * resources retrieved from the context remain valid for the lifetime of + * the runner produced. + */ + explicit MdrunnerBuilder(std::unique_ptr mdModules, + compat::not_null context); + + //! \cond + MdrunnerBuilder() = delete; + MdrunnerBuilder(const MdrunnerBuilder&) = delete; + MdrunnerBuilder& operator=(const MdrunnerBuilder&) = delete; + //! \endcond + + /*! \brief Allow transfer of ownership with move semantics. + * + * \param builder source object to transfer. + * + * \{ + */ + MdrunnerBuilder(MdrunnerBuilder&& builder) noexcept; + MdrunnerBuilder& operator=(MdrunnerBuilder&& builder) noexcept; + //! \} + + /*! + * \brief Get ownership of an initialized gmx::Mdrunner. + * + * After build() is called, the Builder object should not be used + * again. It is an error to call build without first calling all builder + * methods described as "required." + * + * \return A new Mdrunner. + * + * \throws APIError if a required component has not been added before calling build(). + */ + Mdrunner build(); + + /*! + * \brief Set up non-bonded short-range force calculations. + * + * Required. Director code must provide valid options for the non-bonded + * interaction code. The builder does not apply any defaults. + * + * \param nbpu_opt Target short-range interactions for "cpu", "gpu", or "auto". + * + * Calling must guarantee that the pointed-to C string is valid through + * simulation launch. + * + * \internal + * \todo Replace with string or enum that we can have sensible defaults for. + * \todo Either the Builder or modular Director code should provide sensible defaults. + */ + MdrunnerBuilder& addNonBonded(const char* nbpu_opt); + + /*! + * \brief Set up long-range electrostatics calculations. + * + * Required. Director code should provide valid options for PME electrostatics, + * whether or not PME electrostatics are used. The builder does not apply + * any defaults, so client code should be prepared to provide (e.g.) "auto" + * in the event no user input or logic provides an alternative argument. + * + * \param pme_opt Target long-range interactions for "cpu", "gpu", or "auto". + * \param pme_fft_opt Target long-range interactions FFT/solve stages for "cpu", "gpu", or "auto". + * + * Calling must guarantee that the pointed-to C strings are valid through + * simulation launch. + * + * \internal + * The arguments are passed as references to elements of arrays of C strings. + * \todo Replace with modern strings or (better) enum classes. + * \todo Make optional and/or encapsulate into electrostatics module. + */ + MdrunnerBuilder& addElectrostatics(const char* pme_opt, const char* pme_fft_opt); + + /*! + * \brief Assign responsibility for tasks for bonded interactions. + * + * Required. Director code should provide valid options for + * bonded interaction task assignment, whether or not such + * interactions are present. The builder does not apply any + * defaults, so client code should be prepared to provide + * (e.g.) "auto" in the event no user input or logic provides + * an alternative argument. + * + * \param bonded_opt Target bonded interactions for "cpu", "gpu", or "auto". + * + * Calling must guarantee that the pointed-to C strings are valid through + * simulation launch. + * + * \internal + * The arguments are passed as references to elements of arrays of C strings. + * \todo Replace with modern strings or (better) enum classes. + * \todo Make optional and/or encapsulate into task assignment module. + */ + MdrunnerBuilder& addBondedTaskAssignment(const char* bonded_opt); + + /*! \brief + * Assign responsibility for tasks for update and constrain calculation. + * + * Required. Director code should provide valid options for + * update and constraint task assignment. The builder does not apply any + * defaults, so client code should be prepared to provide + * (e.g.) "auto" in the event no user input or logic provides + * an alternative argument. + * + * \param[in] update_opt Target update calculation for "cpu", "gpu", or "auto". + * + * Calling must guarantee that the pointed-to C strings are valid through + * simulation launch. + * + * \internal + * The arguments are passed as references to elements of arrays of C strings. + * \todo Replace with modern strings or (better) enum classes. + * \todo Make optional and/or encapsulate into task assignment module. + */ + MdrunnerBuilder& addUpdateTaskAssignment(const char* update_opt); + + /*! + * \brief Set MD options not owned by some other module. + * + * Optional. Override simulation parameters + * + * \param options structure to copy + * \param forceWarningThreshold Print a warning if any force is larger than this (in kJ/mol nm) (default -1) + * \param startingBehavior Whether the simulation will start afresh, or restart with/without appending. + * + * \internal + * \todo Map these parameters to more appropriate encapsulating types. + * Find a better way to indicate "unspecified" than a magic value of the parameter type. + */ + MdrunnerBuilder& addSimulationMethod(const MdrunOptions& options, + real forceWarningThreshold, + StartingBehavior startingBehavior); + + /*! + * \brief Set the domain decomposition module. + * + * Optional. Overrides default constructed DomdecOptions if provided. + * + * \param options options with which to construct domain decomposition. + * + * \internal + * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort. + */ + MdrunnerBuilder& addDomainDecomposition(const DomdecOptions& options); + + /*! + * \brief Set Verlet list manager. + * + * Optional. Neighbor list existence, type, and parameters are mostly determined + * by the simulation parameters loaded elsewhere. This is just an override. + * + * \param rebuildInterval override for the duration of a neighbor list with the Verlet scheme. + */ + MdrunnerBuilder& addNeighborList(int rebuildInterval); + + /*! + * \brief Set replica exchange manager. + * + * Optional. For guidance on preparing a valid ReplicaExchangeParameters + * value, refer to the details in mdrun.cpp, the `t_pargs pa[]` defined there, + * and the action of parse_common_args() with regards to that structure. + * If not provided by client, a default constructed ReplicaExchangeParameters + * is used. + * + * \param params parameters with which to set up replica exchange. + * + * \internal + * \todo revisit whether we should be passing this parameter struct or a higher-level handle of some sort. + */ + MdrunnerBuilder& addReplicaExchange(const ReplicaExchangeParameters& params); + + /*! + * \brief Specify parameters determining hardware resource allocation. + * + * Optional. If not provided, default-constructed gmx_hw_opt_t will be used. + * + * \param hardwareOptions Parallelism-related user options. + */ + MdrunnerBuilder& addHardwareOptions(const gmx_hw_opt_t& hardwareOptions); + + /*! + * \brief Provide the filenames options structure with option values chosen + * + * Required. The object is assumed to have been updated by + * parse_common_args or equivalent. + * + * \param filenames Filenames and properties from command-line argument values or defaults. + * + * \internal + * \todo Modules should manage their own filename options and defaults. + */ + MdrunnerBuilder& addFilenames(ArrayRef filenames); + + /*! + * \brief Provide parameters for setting up output environment. + * + * Required. Handle is assumed to have been produced by output_env_init + * as in parse_common_args. + * + * \param outputEnvironment Output context for writing text files. + * + * \internal + * \todo Allow client code to set up output environment and provide as a resource. + * This parameter is used to set up resources that are dependent on the execution + * environment and API context. Such resources should be retrieved by the simulator + * from a client-provided resource, but currently the resources are only fully + * initialized in Mdrunner. + */ + MdrunnerBuilder& addOutputEnvironment(gmx_output_env_t* outputEnvironment); + + /*! + * \brief Provide the filehandle pointer to be used for the MD log. + * + * Required. Either nullptr if no log should be written, or + * valid and open reading for writing. + * + * \param logFileHandle Non-owning handle to file used for logging. + * \internal + */ + MdrunnerBuilder& addLogFile(t_fileio* logFileHandle); + + /*! + * \brief Provide a StopHandlerBuilder for the MD stop signal handling. + * + * Optional. Defaults to empty. + * + * Client may provide additional (non-default) issuers of simulation stop + * signals by preconfiguring the StopHandlerBuilder used later when the + * simulation runs. + * + * \param builder + */ + MdrunnerBuilder& addStopHandlerBuilder(std::unique_ptr builder); + + ~MdrunnerBuilder(); + +private: + std::unique_ptr impl_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDRUN_RUNNER_H diff --git a/src/gromacs/mdrun/shellfc.cpp b/src/gromacs/mdrun/shellfc.cpp index 42b1accb2b..1ef6cd58ed 100644 --- a/src/gromacs/mdrun/shellfc.cpp +++ b/src/gromacs/mdrun/shellfc.cpp @@ -80,57 +80,58 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -typedef struct { - int nnucl; - int shell; /* The shell id */ - int nucl1, nucl2, nucl3; /* The nuclei connected to the shell */ - /* gmx_bool bInterCG; */ /* Coupled to nuclei outside cg? */ - real k; /* force constant */ - real k_1; /* 1 over force constant */ - rvec xold; - rvec fold; - rvec step; +typedef struct +{ + int nnucl; + int shell; /* The shell id */ + int nucl1, nucl2, nucl3; /* The nuclei connected to the shell */ + /* gmx_bool bInterCG; */ /* Coupled to nuclei outside cg? */ + real k; /* force constant */ + real k_1; /* 1 over force constant */ + rvec xold; + rvec fold; + rvec step; } t_shell; -struct gmx_shellfc_t { +struct gmx_shellfc_t +{ /* Shell counts, indices, parameters and working data */ - int nshell_gl; /* The number of shells in the system */ - t_shell *shell_gl; /* All the shells (for DD only) */ - int *shell_index_gl; /* Global shell index (for DD only) */ - gmx_bool bInterCG; /* Are there inter charge-group shells? */ - int nshell; /* The number of local shells */ - t_shell *shell; /* The local shells */ - int shell_nalloc; /* The allocation size of shell */ - gmx_bool bPredict; /* Predict shell positions */ - gmx_bool bRequireInit; /* Require initialization of shell positions */ - int nflexcon; /* The number of flexible constraints */ + int nshell_gl; /* The number of shells in the system */ + t_shell* shell_gl; /* All the shells (for DD only) */ + int* shell_index_gl; /* Global shell index (for DD only) */ + gmx_bool bInterCG; /* Are there inter charge-group shells? */ + int nshell; /* The number of local shells */ + t_shell* shell; /* The local shells */ + int shell_nalloc; /* The allocation size of shell */ + gmx_bool bPredict; /* Predict shell positions */ + gmx_bool bRequireInit; /* Require initialization of shell positions */ + int nflexcon; /* The number of flexible constraints */ /* Temporary arrays, should be fixed size 2 when fully converted to C++ */ - PaddedHostVector *x; /* Array for iterative minimization */ - PaddedHostVector *f; /* Array for iterative minimization */ + PaddedHostVector* x; /* Array for iterative minimization */ + PaddedHostVector* f; /* Array for iterative minimization */ /* Flexible constraint working data */ - rvec *acc_dir; /* Acceleration direction for flexcon */ - rvec *x_old; /* Old coordinates for flexcon */ + rvec* acc_dir; /* Acceleration direction for flexcon */ + rvec* x_old; /* Old coordinates for flexcon */ int flex_nalloc; /* The allocation size of acc_dir and x_old */ - rvec *adir_xnold; /* Work space for init_adir */ - rvec *adir_xnew; /* Work space for init_adir */ + rvec* adir_xnold; /* Work space for init_adir */ + rvec* adir_xnew; /* Work space for init_adir */ int adir_nalloc; /* Work space for init_adir */ std::int64_t numForceEvaluations; /* Total number of force evaluations */ int numConvergedIterations; /* Total number of iterations that converged */ }; -static void pr_shell(FILE *fplog, int ns, t_shell s[]) +static void pr_shell(FILE* fplog, int ns, t_shell s[]) { int i; fprintf(fplog, "SHELL DATA\n"); - fprintf(fplog, "%5s %8s %5s %5s %5s\n", - "Shell", "Force k", "Nucl1", "Nucl2", "Nucl3"); + fprintf(fplog, "%5s %8s %5s %5s %5s\n", "Shell", "Force k", "Nucl1", "Nucl2", "Nucl3"); for (i = 0; (i < ns); i++) { - fprintf(fplog, "%5d %8.3f %5d", s[i].shell, 1.0/s[i].k_1, s[i].nucl1); + fprintf(fplog, "%5d %8.3f %5d", s[i].shell, 1.0 / s[i].k_1, s[i].nucl1); if (s[i].nnucl == 2) { fprintf(fplog, " %5d\n", s[i].nucl2); @@ -153,13 +154,19 @@ static void pr_shell(FILE *fplog, int ns, t_shell s[]) * started, but even when called, the prediction was always * over-written by a subsequent call in the MD loop, so has been * removed. */ -static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, - int ns, t_shell s[], - const real mass[], gmx_mtop_t *mtop, gmx_bool bInit) +static void predict_shells(FILE* fplog, + rvec x[], + rvec v[], + real dt, + int ns, + t_shell s[], + const real mass[], + gmx_mtop_t* mtop, + gmx_bool bInit) { - int i, m, s1, n1, n2, n3; - real dt_1, fudge, tm, m1, m2, m3; - rvec *ptr; + int i, m, s1, n1, n2, n3; + real dt_1, fudge, tm, m1, m2, m3; + rvec* ptr; GMX_RELEASE_ASSERT(mass || mtop, "Must have masses or a way to look them up"); @@ -181,7 +188,7 @@ static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, else { ptr = v; - dt_1 = fudge*dt; + dt_1 = fudge * dt; } int molb = 0; @@ -198,7 +205,7 @@ static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, n1 = s[i].nucl1; for (m = 0; (m < DIM); m++) { - x[s1][m] += ptr[n1][m]*dt_1; + x[s1][m] += ptr[n1][m] * dt_1; } break; case 2: @@ -215,10 +222,10 @@ static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, m1 = mtopGetAtomMass(mtop, n1, &molb); m2 = mtopGetAtomMass(mtop, n2, &molb); } - tm = dt_1/(m1+m2); + tm = dt_1 / (m1 + m2); for (m = 0; (m < DIM); m++) { - x[s1][m] += (m1*ptr[n1][m]+m2*ptr[n2][m])*tm; + x[s1][m] += (m1 * ptr[n1][m] + m2 * ptr[n2][m]) * tm; } break; case 3: @@ -238,14 +245,13 @@ static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, m2 = mtopGetAtomMass(mtop, n2, &molb); m3 = mtopGetAtomMass(mtop, n3, &molb); } - tm = dt_1/(m1+m2+m3); + tm = dt_1 / (m1 + m2 + m3); for (m = 0; (m < DIM); m++) { - x[s1][m] += (m1*ptr[n1][m]+m2*ptr[n2][m]+m3*ptr[n3][m])*tm; + x[s1][m] += (m1 * ptr[n1][m] + m2 * ptr[n2][m] + m3 * ptr[n3][m]) * tm; } break; - default: - gmx_fatal(FARGS, "Shell %d has %d nuclei!", i, s[i].nnucl); + default: gmx_fatal(FARGS, "Shell %d has %d nuclei!", i, s[i].nnucl); } } } @@ -258,8 +264,7 @@ static void predict_shells(FILE *fplog, rvec x[], rvec v[], real dt, * \param[in] mtop Molecular topology. * \returns Array holding the number of particles of a type */ -std::array countPtypes(FILE *fplog, - const gmx_mtop_t *mtop) +std::array countPtypes(FILE* fplog, const gmx_mtop_t* mtop) { std::array nptype = { { 0 } }; /* Count number of shells, and find their indices */ @@ -268,18 +273,16 @@ std::array countPtypes(FILE *fplog, nptype[i] = 0; } - gmx_mtop_atomloop_block_t aloopb = gmx_mtop_atomloop_block_init(mtop); - int nmol; - const t_atom *atom; + gmx_mtop_atomloop_block_t aloopb = gmx_mtop_atomloop_block_init(mtop); + int nmol; + const t_atom* atom; while (gmx_mtop_atomloop_block_next(aloopb, &atom, &nmol)) { switch (atom->ptype) { case eptAtom: case eptVSite: - case eptShell: - nptype[atom->ptype] += nmol; - break; + case eptShell: nptype[atom->ptype] += nmol; break; default: fprintf(stderr, "Warning unsupported particle type %d in countPtypes", static_cast(atom->ptype)); @@ -289,7 +292,7 @@ std::array countPtypes(FILE *fplog, { /* Print the number of each particle type */ int n = 0; - for (const auto &i : nptype) + for (const auto& i : nptype) { if (i != 0) { @@ -301,25 +304,22 @@ std::array countPtypes(FILE *fplog, return nptype; } -gmx_shellfc_t *init_shell_flexcon(FILE *fplog, - const gmx_mtop_t *mtop, int nflexcon, - int nstcalcenergy, - bool usingDomainDecomposition) +gmx_shellfc_t* init_shell_flexcon(FILE* fplog, const gmx_mtop_t* mtop, int nflexcon, int nstcalcenergy, bool usingDomainDecomposition) { - gmx_shellfc_t *shfc; - t_shell *shell; - int *shell_index = nullptr; - - int ns, nshell, nsi; - int i, j, type, a_offset, mol, ftype, nra; - real qS, alpha; - int aS, aN = 0; /* Shell and nucleus */ - int bondtypes[] = { F_BONDS, F_HARMONIC, F_CUBICBONDS, F_POLARIZATION, F_ANHARM_POL, F_WATER_POL }; + gmx_shellfc_t* shfc; + t_shell* shell; + int* shell_index = nullptr; + + int ns, nshell, nsi; + int i, j, type, a_offset, mol, ftype, nra; + real qS, alpha; + int aS, aN = 0; /* Shell and nucleus */ + int bondtypes[] = { F_BONDS, F_HARMONIC, F_CUBICBONDS, F_POLARIZATION, F_ANHARM_POL, F_WATER_POL }; #define NBT asize(bondtypes) - const gmx_ffparams_t *ffparams; + const gmx_ffparams_t* ffparams; - std::array n = countPtypes(fplog, mtop); - nshell = n[eptShell]; + std::array n = countPtypes(fplog, mtop); + nshell = n[eptShell]; if (nshell == 0 && nflexcon == 0) { @@ -345,11 +345,16 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, if (nstcalcenergy != 1) { - gmx_fatal(FARGS, "You have nstcalcenergy set to a value (%d) that is different from 1.\nThis is not supported in combination with shell particles.\nPlease make a new tpr file.", nstcalcenergy); + gmx_fatal(FARGS, + "You have nstcalcenergy set to a value (%d) that is different from 1.\nThis is " + "not supported in combination with shell particles.\nPlease make a new tpr file.", + nstcalcenergy); } if (usingDomainDecomposition) { - gmx_fatal(FARGS, "Shell particles are not implemented with domain decomposition, use a single rank"); + gmx_fatal( + FARGS, + "Shell particles are not implemented with domain decomposition, use a single rank"); } /* We have shells: fill the shell data structure */ @@ -360,7 +365,7 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, nshell = 0; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); if (local.ptype == eptShell) { @@ -379,8 +384,8 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, shell[i].nucl2 = -1; shell[i].nucl3 = -1; /* shell[i].bInterCG=FALSE; */ - shell[i].k_1 = 0; - shell[i].k = 0; + shell[i].k_1 = 0; + shell[i].k = 0; } ffparams = &mtop->ffparams; @@ -392,16 +397,16 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, a_offset = 0; for (size_t mb = 0; mb < mtop->molblock.size(); mb++) { - const gmx_molblock_t *molb = &mtop->molblock[mb]; - const gmx_moltype_t *molt = &mtop->moltype[molb->type]; + const gmx_molblock_t* molb = &mtop->molblock[mb]; + const gmx_moltype_t* molt = &mtop->moltype[molb->type]; - const t_atom *atom = molt->atoms.atom; + const t_atom* atom = molt->atoms.atom; for (mol = 0; mol < molb->nmol; mol++) { for (j = 0; (j < NBT); j++) { - const int *ia = molt->ilist[bondtypes[j]].iatoms.data(); - for (i = 0; (i < molt->ilist[bondtypes[j]].size()); ) + const int* ia = molt->ilist[bondtypes[j]].iatoms.data(); + for (i = 0; (i < molt->ilist[bondtypes[j]].size());) { type = ia[0]; ftype = ffparams->functype[type]; @@ -429,11 +434,10 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, } break; case F_WATER_POL: - aN = ia[4]; /* Dummy */ - aS = ia[5]; /* Shell */ + aN = ia[4]; /* Dummy */ + aS = ia[5]; /* Shell */ break; - default: - gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); + default: gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); } if (aS != -1) @@ -441,23 +445,22 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, qS = atom[aS].q; /* Check whether one of the particles is a shell... */ - nsi = shell_index[a_offset+aS]; + nsi = shell_index[a_offset + aS]; if ((nsi < 0) || (nsi >= nshell)) { - gmx_fatal(FARGS, "nsi is %d should be within 0 - %d. aS = %d", - nsi, nshell, aS); + gmx_fatal(FARGS, "nsi is %d should be within 0 - %d. aS = %d", nsi, nshell, aS); } if (shell[nsi].shell == -1) { shell[nsi].shell = a_offset + aS; ns++; } - else if (shell[nsi].shell != a_offset+aS) + else if (shell[nsi].shell != a_offset + aS) { gmx_fatal(FARGS, "Weird stuff in %s, %d", __FILE__, __LINE__); } - if (shell[nsi].nucl1 == -1) + if (shell[nsi].nucl1 == -1) { shell[nsi].nucl1 = a_offset + aN; } @@ -487,37 +490,43 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, { case F_BONDS: case F_HARMONIC: - shell[nsi].k += ffparams->iparams[type].harmonic.krA; + shell[nsi].k += ffparams->iparams[type].harmonic.krA; break; case F_CUBICBONDS: - shell[nsi].k += ffparams->iparams[type].cubic.kb; + shell[nsi].k += ffparams->iparams[type].cubic.kb; break; case F_POLARIZATION: case F_ANHARM_POL: - if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS*10)) + if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS * 10)) { - gmx_fatal(FARGS, "polarize can not be used with qA(%e) != qB(%e) for atom %d of molecule block %zu", qS, atom[aS].qB, aS+1, mb+1); + gmx_fatal(FARGS, + "polarize can not be used with qA(%e) != qB(%e) for " + "atom %d of molecule block %zu", + qS, atom[aS].qB, aS + 1, mb + 1); } - shell[nsi].k += gmx::square(qS)*ONE_4PI_EPS0/ - ffparams->iparams[type].polarize.alpha; + shell[nsi].k += gmx::square(qS) * ONE_4PI_EPS0 + / ffparams->iparams[type].polarize.alpha; break; case F_WATER_POL: - if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS*10)) + if (!gmx_within_tol(qS, atom[aS].qB, GMX_REAL_EPS * 10)) { - gmx_fatal(FARGS, "water_pol can not be used with qA(%e) != qB(%e) for atom %d of molecule block %zu", qS, atom[aS].qB, aS+1, mb+1); + gmx_fatal(FARGS, + "water_pol can not be used with qA(%e) != qB(%e) for " + "atom %d of molecule block %zu", + qS, atom[aS].qB, aS + 1, mb + 1); } - alpha = (ffparams->iparams[type].wpol.al_x+ - ffparams->iparams[type].wpol.al_y+ - ffparams->iparams[type].wpol.al_z)/3.0; - shell[nsi].k += gmx::square(qS)*ONE_4PI_EPS0/alpha; + alpha = (ffparams->iparams[type].wpol.al_x + + ffparams->iparams[type].wpol.al_y + + ffparams->iparams[type].wpol.al_z) + / 3.0; + shell[nsi].k += gmx::square(qS) * ONE_4PI_EPS0 / alpha; break; - default: - gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); + default: gmx_fatal(FARGS, "Death Horror: %s, %d", __FILE__, __LINE__); } shell[nsi].nnucl++; } - ia += nra+1; - i += nra+1; + ia += nra + 1; + i += nra + 1; } } a_offset += molt->atoms.nr; @@ -533,7 +542,7 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, for (i = 0; (i < ns); i++) { - shell[i].k_1 = 1.0/shell[i].k; + shell[i].k_1 = 1.0 / shell[i].k; } if (debug) @@ -570,7 +579,9 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, { if (fplog) { - fprintf(fplog, "\nNOTE: in the current version shell prediction during the crun is disabled\n\n"); + fprintf(fplog, + "\nNOTE: in the current version shell prediction during the crun is " + "disabled\n\n"); } /* Prediction improves performance, so we should implement either: * 1. communication for the atoms needed for prediction @@ -585,13 +596,11 @@ gmx_shellfc_t *init_shell_flexcon(FILE *fplog, return shfc; } -void make_local_shells(const t_commrec *cr, - const t_mdatoms *md, - gmx_shellfc_t *shfc) +void make_local_shells(const t_commrec* cr, const t_mdatoms* md, gmx_shellfc_t* shfc) { - t_shell *shell; + t_shell* shell; int a0, a1, *ind, nshell, i; - gmx_domdec_t *dd = nullptr; + gmx_domdec_t* dd = nullptr; if (DOMAINDECOMP(cr)) { @@ -616,9 +625,9 @@ void make_local_shells(const t_commrec *cr, { if (md->ptype[i] == eptShell) { - if (nshell+1 > shfc->shell_nalloc) + if (nshell + 1 > shfc->shell_nalloc) { - shfc->shell_nalloc = over_alloc_dd(nshell+1); + shfc->shell_nalloc = over_alloc_dd(nshell + 1); srenew(shell, shfc->shell_nalloc); } if (dd) @@ -635,7 +644,7 @@ void make_local_shells(const t_commrec *cr, */ if (!shfc->bInterCG) { - shell[nshell].nucl1 = i + shell[nshell].nucl1 - shell[nshell].shell; + shell[nshell].nucl1 = i + shell[nshell].nucl1 - shell[nshell].shell; if (shell[nshell].nnucl > 1) { shell[nshell].nucl2 = i + shell[nshell].nucl2 - shell[nshell].shell; @@ -663,13 +672,13 @@ static void do_1pos(rvec xnew, const rvec xold, const rvec f, real step) yo = xold[YY]; zo = xold[ZZ]; - dx = f[XX]*step; - dy = f[YY]*step; - dz = f[ZZ]*step; + dx = f[XX] * step; + dy = f[YY] * step; + dz = f[ZZ] * step; - xnew[XX] = xo+dx; - xnew[YY] = yo+dy; - xnew[ZZ] = zo+dz; + xnew[XX] = xo + dx; + xnew[YY] = yo + dy; + xnew[ZZ] = zo + dz; } static void do_1pos3(rvec xnew, const rvec xold, const rvec f, const rvec step) @@ -681,21 +690,23 @@ static void do_1pos3(rvec xnew, const rvec xold, const rvec f, const rvec step) yo = xold[YY]; zo = xold[ZZ]; - dx = f[XX]*step[XX]; - dy = f[YY]*step[YY]; - dz = f[ZZ]*step[ZZ]; + dx = f[XX] * step[XX]; + dy = f[YY] * step[YY]; + dz = f[ZZ] * step[ZZ]; - xnew[XX] = xo+dx; - xnew[YY] = yo+dy; - xnew[ZZ] = zo+dz; + xnew[XX] = xo + dx; + xnew[YY] = yo + dy; + xnew[ZZ] = zo + dz; } static void directional_sd(gmx::ArrayRef xold, - gmx::ArrayRef xnew, - const rvec acc_dir[], int homenr, real step) + gmx::ArrayRef xnew, + const rvec acc_dir[], + int homenr, + real step) { - const rvec *xo = as_rvec_array(xold.data()); - rvec *xn = as_rvec_array(xnew.data()); + const rvec* xo = as_rvec_array(xold.data()); + rvec* xn = as_rvec_array(xnew.data()); for (int i = 0; i < homenr; i++) { @@ -704,19 +715,19 @@ static void directional_sd(gmx::ArrayRef xold, } static void shell_pos_sd(gmx::ArrayRef xcur, - gmx::ArrayRef xnew, + gmx::ArrayRef xnew, gmx::ArrayRef f, - int ns, t_shell s[], int count) + int ns, + t_shell s[], + int count) { - const real step_scale_min = 0.8, - step_scale_increment = 0.2, - step_scale_max = 1.2, - step_scale_multiple = (step_scale_max - step_scale_min) / step_scale_increment; + const real step_scale_min = 0.8, step_scale_increment = 0.2, step_scale_max = 1.2, + step_scale_multiple = (step_scale_max - step_scale_min) / step_scale_increment; int i, shell, d; real dx, df, k_est; const real zero = 0; #ifdef PRINT_STEP - real step_min, step_max; + real step_min, step_max; step_min = 1e30; step_max = 0; @@ -740,20 +751,21 @@ static void shell_pos_sd(gmx::ArrayRef xcur, for (d = 0; d < DIM; d++) { dx = xcur[shell][d] - s[i].xold[d]; - df = f[shell][d] - s[i].fold[d]; + df = f[shell][d] - s[i].fold[d]; /* -dx/df gets used to generate an interpolated value, but would * cause a NaN if df were binary-equal to zero. Values close to * zero won't cause problems (because of the min() and max()), so * just testing for binary inequality is OK. */ if (zero != df) { - k_est = -dx/df; + k_est = -dx / df; /* Scale the step size by a factor interpolated from * step_scale_min to step_scale_max, as k_est goes from 0 to * step_scale_multiple * s[i].step[d] */ - s[i].step[d] = - step_scale_min * s[i].step[d] + - step_scale_increment * std::min(step_scale_multiple * s[i].step[d], std::max(k_est, zero)); + s[i].step[d] = step_scale_min * s[i].step[d] + + step_scale_increment + * std::min(step_scale_multiple * s[i].step[d], + std::max(k_est, zero)); } else { @@ -774,8 +786,8 @@ static void shell_pos_sd(gmx::ArrayRef xcur, #endif } } - copy_rvec(xcur [shell], s[i].xold); - copy_rvec(f[shell], s[i].fold); + copy_rvec(xcur[shell], s[i].xold); + copy_rvec(f[shell], s[i].fold); do_1pos3(xnew[shell], xcur[shell], f[shell], s[i].step); @@ -803,16 +815,14 @@ static void decrease_step_size(int nshell, t_shell s[]) } } -static void print_epot(FILE *fp, int64_t mdstep, int count, real epot, real df, - int ndir, real sf_dir) +static void print_epot(FILE* fp, int64_t mdstep, int count, real epot, real df, int ndir, real sf_dir) { char buf[22]; - fprintf(fp, "MDStep=%5s/%2d EPot: %12.8e, rmsF: %6.2e", - gmx_step_str(mdstep, buf), count, epot, df); + fprintf(fp, "MDStep=%5s/%2d EPot: %12.8e, rmsF: %6.2e", gmx_step_str(mdstep, buf), count, epot, df); if (ndir) { - fprintf(fp, ", dir. rmsF: %6.2e\n", std::sqrt(sf_dir/ndir)); + fprintf(fp, ", dir. rmsF: %6.2e\n", std::sqrt(sf_dir / ndir)); } else { @@ -821,17 +831,22 @@ static void print_epot(FILE *fp, int64_t mdstep, int count, real epot, real df, } -static real rms_force(const t_commrec *cr, gmx::ArrayRef force, int ns, t_shell s[], - int ndir, real *sf_dir, real *Epot) +static real rms_force(const t_commrec* cr, + gmx::ArrayRef force, + int ns, + t_shell s[], + int ndir, + real* sf_dir, + real* Epot) { double buf[4]; - const rvec *f = as_rvec_array(force.data()); + const rvec* f = as_rvec_array(force.data()); buf[0] = *sf_dir; for (int i = 0; i < ns; i++) { - int shell = s[i].shell; - buf[0] += norm2(f[shell]); + int shell = s[i].shell; + buf[0] += norm2(f[shell]); } int ntot = ns; @@ -847,10 +862,10 @@ static real rms_force(const t_commrec *cr, gmx::ArrayRef force, } ntot += ndir; - return (ntot ? std::sqrt(buf[0]/ntot) : 0); + return (ntot ? std::sqrt(buf[0] / ntot) : 0); } -static void dump_shells(FILE *fp, gmx::ArrayRef f, real ftol, int ns, t_shell s[]) +static void dump_shells(FILE* fp, gmx::ArrayRef f, real ftol, int ns, t_shell s[]) { int i, shell; real ft2, ff2; @@ -863,33 +878,33 @@ static void dump_shells(FILE *fp, gmx::ArrayRef f, real ftol, int ns, ff2 = iprod(f[shell], f[shell]); if (ff2 > ft2) { - fprintf(fp, "SHELL %5d, force %10.5f %10.5f %10.5f, |f| %10.5f\n", - shell, f[shell][XX], f[shell][YY], f[shell][ZZ], std::sqrt(ff2)); + fprintf(fp, "SHELL %5d, force %10.5f %10.5f %10.5f, |f| %10.5f\n", shell, + f[shell][XX], f[shell][YY], f[shell][ZZ], std::sqrt(ff2)); } } } -static void init_adir(gmx_shellfc_t *shfc, - gmx::Constraints *constr, - const t_inputrec *ir, - const t_commrec *cr, +static void init_adir(gmx_shellfc_t* shfc, + gmx::Constraints* constr, + const t_inputrec* ir, + const t_commrec* cr, int dd_ac1, int64_t step, - const t_mdatoms *md, + const t_mdatoms* md, int end, - rvec *x_old, - rvec *x_init, - rvec *x, - rvec *f, - rvec *acc_dir, + rvec* x_old, + rvec* x_init, + rvec* x, + rvec* f, + rvec* acc_dir, const matrix box, gmx::ArrayRef lambda, - real *dvdlambda) + real* dvdlambda) { - rvec *xnold, *xnew; + rvec * xnold, *xnew; double dt, w_dt; int n, d; - unsigned short *ptype; + unsigned short* ptype; if (DOMAINDECOMP(cr)) { @@ -915,14 +930,14 @@ static void init_adir(gmx_shellfc_t *shfc, /* Does NOT work with freeze or acceleration groups (yet) */ for (n = 0; n < end; n++) { - w_dt = md->invmass[n]*dt; + w_dt = md->invmass[n] * dt; for (d = 0; d < DIM; d++) { if ((ptype[n] != eptVSite) && (ptype[n] != eptShell)) { xnold[n][d] = x[n][d] - (x_init[n][d] - x_old[n][d]); - xnew[n][d] = 2*x[n][d] - x_old[n][d] + f[n][d]*w_dt*dt; + xnew[n][d] = 2 * x[n][d] - x_old[n][d] + f[n][d] * w_dt * dt; } else { @@ -931,75 +946,68 @@ static void init_adir(gmx_shellfc_t *shfc, } } } - constr->apply(FALSE, FALSE, step, 0, 1.0, - x, xnold, nullptr, box, - lambda[efptBONDED], &(dvdlambda[efptBONDED]), - nullptr, nullptr, gmx::ConstraintVariable::Positions); - constr->apply(FALSE, FALSE, step, 0, 1.0, - x, xnew, nullptr, box, - lambda[efptBONDED], &(dvdlambda[efptBONDED]), - nullptr, nullptr, gmx::ConstraintVariable::Positions); + constr->apply(FALSE, FALSE, step, 0, 1.0, x, xnold, nullptr, box, lambda[efptBONDED], + &(dvdlambda[efptBONDED]), nullptr, nullptr, gmx::ConstraintVariable::Positions); + constr->apply(FALSE, FALSE, step, 0, 1.0, x, xnew, nullptr, box, lambda[efptBONDED], + &(dvdlambda[efptBONDED]), nullptr, nullptr, gmx::ConstraintVariable::Positions); for (n = 0; n < end; n++) { for (d = 0; d < DIM; d++) { - xnew[n][d] = - -(2*x[n][d]-xnold[n][d]-xnew[n][d])/gmx::square(dt) - - f[n][d]*md->invmass[n]; + xnew[n][d] = -(2 * x[n][d] - xnold[n][d] - xnew[n][d]) / gmx::square(dt) + - f[n][d] * md->invmass[n]; } clear_rvec(acc_dir[n]); } /* Project the acceleration on the old bond directions */ - constr->apply(FALSE, FALSE, step, 0, 1.0, - x_old, xnew, acc_dir, box, - lambda[efptBONDED], &(dvdlambda[efptBONDED]), - nullptr, nullptr, gmx::ConstraintVariable::Deriv_FlexCon); + constr->apply(FALSE, FALSE, step, 0, 1.0, x_old, xnew, acc_dir, box, lambda[efptBONDED], + &(dvdlambda[efptBONDED]), nullptr, nullptr, gmx::ConstraintVariable::Deriv_FlexCon); } -void relax_shell_flexcon(FILE *fplog, - const t_commrec *cr, - const gmx_multisim_t *ms, - gmx_bool bVerbose, - gmx_enfrot *enforcedRotation, - int64_t mdstep, - const t_inputrec *inputrec, - gmx::ImdSession *imdSession, - pull_t *pull_work, - gmx_bool bDoNS, - int force_flags, - const gmx_localtop_t *top, - gmx::Constraints *constr, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - int natoms, - gmx::ArrayRefWithPadding x, - gmx::ArrayRefWithPadding v, - const matrix box, - gmx::ArrayRef lambda, - history_t *hist, - gmx::ArrayRefWithPadding f, - tensor force_vir, - const t_mdatoms *md, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - t_graph *graph, - gmx_shellfc_t *shfc, - t_forcerec *fr, - gmx::MdrunScheduleWorkload *runScheduleWork, - double t, - rvec mu_tot, - const gmx_vsite_t *vsite, - const DDBalanceRegionHandler &ddBalanceRegionHandler) +void relax_shell_flexcon(FILE* fplog, + const t_commrec* cr, + const gmx_multisim_t* ms, + gmx_bool bVerbose, + gmx_enfrot* enforcedRotation, + int64_t mdstep, + const t_inputrec* inputrec, + gmx::ImdSession* imdSession, + pull_t* pull_work, + gmx_bool bDoNS, + int force_flags, + const gmx_localtop_t* top, + gmx::Constraints* constr, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + int natoms, + gmx::ArrayRefWithPadding x, + gmx::ArrayRefWithPadding v, + const matrix box, + gmx::ArrayRef lambda, + history_t* hist, + gmx::ArrayRefWithPadding f, + tensor force_vir, + const t_mdatoms* md, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + t_graph* graph, + gmx_shellfc_t* shfc, + t_forcerec* fr, + gmx::MdrunScheduleWorkload* runScheduleWork, + double t, + rvec mu_tot, + const gmx_vsite_t* vsite, + const DDBalanceRegionHandler& ddBalanceRegionHandler) { - auto xRvec = as_rvec_array(x.paddedArrayRef().data()); - auto vRvec = as_rvec_array(v.paddedArrayRef().data()); + auto xRvec = as_rvec_array(x.paddedArrayRef().data()); + auto vRvec = as_rvec_array(v.paddedArrayRef().data()); int nshell; - t_shell *shell; - const t_idef *idef; - rvec *acc_dir = nullptr, *x_old = nullptr; + t_shell* shell; + const t_idef* idef; + rvec * acc_dir = nullptr, *x_old = nullptr; real Epot[2], df[2]; real sf_dir, invdt; real ftol, dum = 0; @@ -1008,7 +1016,7 @@ void relax_shell_flexcon(FILE *fplog, int nat, dd_ac0, dd_ac1 = 0, i; int homenr = md->homenr, end = homenr; int nflexcon, number_steps, d, Min = 0, count = 0; -#define Try (1-Min) /* At start Try = 1 */ +#define Try (1 - Min) /* At start Try = 1 */ bCont = (mdstep == inputrec->init_step) && inputrec->bContinuation; bInit = (mdstep == inputrec->init_step) || shfc->bRequireInit; @@ -1060,7 +1068,8 @@ void relax_shell_flexcon(FILE *fplog, * charge groups in the box. */ auto xRef = x.paddedArrayRef(); - put_atoms_in_box_omp(fr->ePBC, box, xRef.subArray(0, md->homenr), gmx_omp_nthreads_get(emntDefault)); + put_atoms_in_box_omp(fr->ePBC, box, xRef.subArray(0, md->homenr), + gmx_omp_nthreads_get(emntDefault)); if (graph) { @@ -1082,16 +1091,15 @@ void relax_shell_flexcon(FILE *fplog, srenew(shfc->acc_dir, shfc->flex_nalloc); srenew(shfc->x_old, shfc->flex_nalloc); } - acc_dir = shfc->acc_dir; - x_old = shfc->x_old; + acc_dir = shfc->acc_dir; + x_old = shfc->x_old; auto xArrayRef = x.paddedArrayRef(); auto vArrayRef = v.paddedArrayRef(); for (i = 0; i < homenr; i++) { for (d = 0; d < DIM; d++) { - shfc->x_old[i][d] = - xArrayRef[i][d] - vArrayRef[i][d]*inputrec->delta_t; + shfc->x_old[i][d] = xArrayRef[i][d] - vArrayRef[i][d] * inputrec->delta_t; } } } @@ -1101,8 +1109,7 @@ void relax_shell_flexcon(FILE *fplog, */ if (shfc->bPredict && !bCont && (EI_STATE_VELOCITY(inputrec->eI) || bInit)) { - predict_shells(fplog, xRvec, vRvec, inputrec->delta_t, nshell, shell, - md->massT, nullptr, bInit); + predict_shells(fplog, xRvec, vRvec, inputrec->delta_t, nshell, shell, md->massT, nullptr, bInit); } /* do_force expected the charge groups to be in the box */ @@ -1117,34 +1124,27 @@ void relax_shell_flexcon(FILE *fplog, pr_rvecs(debug, 0, "x b4 do_force", xRvec, homenr); } int shellfc_flags = force_flags | (bVerbose ? GMX_FORCE_ENERGY : 0); - do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, - pull_work, - mdstep, nrnb, wcycle, top, - box, x, hist, - forceWithPadding[Min], force_vir, md, enerd, fcd, - lambda, graph, - fr, runScheduleWork, vsite, mu_tot, t, nullptr, - (bDoNS ? GMX_FORCE_NS : 0) | shellfc_flags, - ddBalanceRegionHandler); + do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, pull_work, mdstep, + nrnb, wcycle, top, box, x, hist, forceWithPadding[Min], force_vir, md, enerd, fcd, + lambda, graph, fr, runScheduleWork, vsite, mu_tot, t, nullptr, + (bDoNS ? GMX_FORCE_NS : 0) | shellfc_flags, ddBalanceRegionHandler); sf_dir = 0; if (nflexcon) { - init_adir(shfc, - constr, inputrec, cr, dd_ac1, mdstep, md, end, - shfc->x_old, xRvec, xRvec, as_rvec_array(force[Min].data()), - shfc->acc_dir, - box, lambda, &dum); + init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end, shfc->x_old, xRvec, xRvec, + as_rvec_array(force[Min].data()), shfc->acc_dir, box, lambda, &dum); for (i = 0; i < end; i++) { - sf_dir += md->massT[i]*norm2(shfc->acc_dir[i]); + sf_dir += md->massT[i] * norm2(shfc->acc_dir[i]); } } sum_epot(&(enerd->grpp), enerd->term); Epot[Min] = enerd->term[F_EPOT]; - df[Min] = rms_force(cr, forceWithPadding[Min].paddedArrayRef(), nshell, shell, nflexcon, &sf_dir, &Epot[Min]); + df[Min] = rms_force(cr, forceWithPadding[Min].paddedArrayRef(), nshell, shell, nflexcon, + &sf_dir, &Epot[Min]); df[Try] = 0; if (debug) { @@ -1156,17 +1156,15 @@ void relax_shell_flexcon(FILE *fplog, pr_rvecs(debug, 0, "force0", as_rvec_array(force[Min].data()), md->nr); } - if (nshell+nflexcon > 0) + if (nshell + nflexcon > 0) { /* Copy x to pos[Min] & pos[Try]: during minimization only the * shell positions are updated, therefore the other particles must * be set here, in advance. */ - std::copy(x.paddedArrayRef().begin(), - x.paddedArrayRef().end(), + std::copy(x.paddedArrayRef().begin(), x.paddedArrayRef().end(), posWithPadding[Min].paddedArrayRef().begin()); - std::copy(x.paddedArrayRef().begin(), - x.paddedArrayRef().end(), + std::copy(x.paddedArrayRef().begin(), x.paddedArrayRef().end(), posWithPadding[Try].paddedArrayRef().begin()); } @@ -1177,12 +1175,9 @@ void relax_shell_flexcon(FILE *fplog, if (debug) { - fprintf(debug, "%17s: %14.10e\n", - interaction_function[F_EKIN].longname, enerd->term[F_EKIN]); - fprintf(debug, "%17s: %14.10e\n", - interaction_function[F_EPOT].longname, enerd->term[F_EPOT]); - fprintf(debug, "%17s: %14.10e\n", - interaction_function[F_ETOT].longname, enerd->term[F_ETOT]); + fprintf(debug, "%17s: %14.10e\n", interaction_function[F_EKIN].longname, enerd->term[F_EKIN]); + fprintf(debug, "%17s: %14.10e\n", interaction_function[F_EPOT].longname, enerd->term[F_EPOT]); + fprintf(debug, "%17s: %14.10e\n", interaction_function[F_ETOT].longname, enerd->term[F_ETOT]); fprintf(debug, "SHELLSTEP %s\n", gmx_step_str(mdstep, sbuf)); } @@ -1195,19 +1190,14 @@ void relax_shell_flexcon(FILE *fplog, { if (vsite) { - construct_vsites(vsite, as_rvec_array(pos[Min].data()), - inputrec->delta_t, vRvec, - idef->iparams, idef->il, - fr->ePBC, fr->bMolPBC, cr, box); + construct_vsites(vsite, as_rvec_array(pos[Min].data()), inputrec->delta_t, vRvec, + idef->iparams, idef->il, fr->ePBC, fr->bMolPBC, cr, box); } if (nflexcon) { - init_adir(shfc, - constr, inputrec, cr, dd_ac1, mdstep, md, end, - x_old, xRvec, - as_rvec_array(pos[Min].data()), - as_rvec_array(force[Min].data()), acc_dir, + init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end, x_old, xRvec, + as_rvec_array(pos[Min].data()), as_rvec_array(force[Min].data()), acc_dir, box, lambda, &dum); directional_sd(pos[Min], pos[Try], acc_dir, end, fr->fc_stepsize); @@ -1228,15 +1218,10 @@ void relax_shell_flexcon(FILE *fplog, pr_rvecs(debug, 0, "RELAX: pos[Try] ", as_rvec_array(pos[Try].data()), homenr); } /* Try the new positions */ - do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, - pull_work, - 1, nrnb, wcycle, - top, box, posWithPadding[Try], hist, - forceWithPadding[Try], force_vir, - md, enerd, fcd, lambda, graph, - fr, runScheduleWork, vsite, mu_tot, t, nullptr, - shellfc_flags, - ddBalanceRegionHandler); + do_force(fplog, cr, ms, inputrec, nullptr, enforcedRotation, imdSession, pull_work, 1, nrnb, + wcycle, top, box, posWithPadding[Try], hist, forceWithPadding[Try], force_vir, md, + enerd, fcd, lambda, graph, fr, runScheduleWork, vsite, mu_tot, t, nullptr, + shellfc_flags, ddBalanceRegionHandler); sum_epot(&(enerd->grpp), enerd->term); if (gmx_debug_at) { @@ -1246,16 +1231,13 @@ void relax_shell_flexcon(FILE *fplog, sf_dir = 0; if (nflexcon) { - init_adir(shfc, - constr, inputrec, cr, dd_ac1, mdstep, md, end, - x_old, xRvec, - as_rvec_array(pos[Try].data()), - as_rvec_array(force[Try].data()), - acc_dir, box, lambda, &dum); + init_adir(shfc, constr, inputrec, cr, dd_ac1, mdstep, md, end, x_old, xRvec, + as_rvec_array(pos[Try].data()), as_rvec_array(force[Try].data()), acc_dir, + box, lambda, &dum); for (i = 0; i < end; i++) { - sf_dir += md->massT[i]*norm2(acc_dir[i]); + sf_dir += md->massT[i] * norm2(acc_dir[i]); } } @@ -1297,17 +1279,17 @@ void relax_shell_flexcon(FILE *fplog, if (nflexcon) { /* Correct the velocities for the flexible constraints */ - invdt = 1/inputrec->delta_t; + invdt = 1 / inputrec->delta_t; auto vArrayRef = v.paddedArrayRef(); for (i = 0; i < end; i++) { for (d = 0; d < DIM; d++) { - vArrayRef[i][d] += (pos[Try][i][d] - pos[Min][i][d])*invdt; + vArrayRef[i][d] += (pos[Try][i][d] - pos[Min][i][d]) * invdt; } } } - Min = Try; + Min = Try; } else { @@ -1324,12 +1306,10 @@ void relax_shell_flexcon(FILE *fplog, /* Note that the energies and virial are incorrect when not converged */ if (fplog) { - fprintf(fplog, - "step %s: EM did not converge in %d iterations, RMS force %6.2e\n", + fprintf(fplog, "step %s: EM did not converge in %d iterations, RMS force %6.2e\n", gmx_step_str(mdstep, sbuf), number_steps, df[Min]); } - fprintf(stderr, - "step %s: EM did not converge in %d iterations, RMS force %6.2e\n", + fprintf(stderr, "step %s: EM did not converge in %d iterations, RMS force %6.2e\n", gmx_step_str(mdstep, sbuf), number_steps, df[Min]); } @@ -1338,15 +1318,15 @@ void relax_shell_flexcon(FILE *fplog, std::copy(force[Min].begin(), force[Min].end(), f.unpaddedArrayRef().begin()); } -void done_shellfc(FILE *fplog, gmx_shellfc_t *shfc, int64_t numSteps) +void done_shellfc(FILE* fplog, gmx_shellfc_t* shfc, int64_t numSteps) { if (shfc && fplog && numSteps > 0) { double numStepsAsDouble = static_cast(numSteps); fprintf(fplog, "Fraction of iterations that converged: %.2f %%\n", - (shfc->numConvergedIterations*100.0)/numStepsAsDouble); + (shfc->numConvergedIterations * 100.0) / numStepsAsDouble); fprintf(fplog, "Average number of force evaluations per MD step: %.2f\n\n", - shfc->numForceEvaluations/numStepsAsDouble); + shfc->numForceEvaluations / numStepsAsDouble); } // TODO Deallocate memory in shfc diff --git a/src/gromacs/mdrun/shellfc.h b/src/gromacs/mdrun/shellfc.h index 6ec6dc99d8..57aa4b60dd 100644 --- a/src/gromacs/mdrun/shellfc.h +++ b/src/gromacs/mdrun/shellfc.h @@ -63,53 +63,54 @@ namespace gmx class Constraints; class ImdSession; class MdrunScheduleWorkload; -} +} // namespace gmx /* Initialization function, also predicts the initial shell postions. */ -gmx_shellfc_t *init_shell_flexcon(FILE *fplog, - const gmx_mtop_t *mtop, int nflexcon, - int nstcalcenergy, - bool usingDomainDecomposition); +gmx_shellfc_t* init_shell_flexcon(FILE* fplog, + const gmx_mtop_t* mtop, + int nflexcon, + int nstcalcenergy, + bool usingDomainDecomposition); /* Optimize shell positions */ -void relax_shell_flexcon(FILE *log, - const t_commrec *cr, - const gmx_multisim_t *ms, - gmx_bool bVerbose, - gmx_enfrot *enforcedRotation, - int64_t mdstep, - const t_inputrec *inputrec, - gmx::ImdSession *imdSession, - pull_t *pull_work, - gmx_bool bDoNS, - int force_flags, - const gmx_localtop_t *top, - gmx::Constraints *constr, - gmx_enerdata_t *enerd, - t_fcdata *fcd, - int natoms, - gmx::ArrayRefWithPadding x, - gmx::ArrayRefWithPadding v, - const matrix box, - gmx::ArrayRef lambda, - history_t *hist, - gmx::ArrayRefWithPadding f, - tensor force_vir, - const t_mdatoms *md, - t_nrnb *nrnb, - gmx_wallcycle_t wcycle, - t_graph *graph, - gmx_shellfc_t *shfc, - t_forcerec *fr, - gmx::MdrunScheduleWorkload *runScheduleWork, - double t, - rvec mu_tot, - const gmx_vsite_t *vsite, - const DDBalanceRegionHandler &ddBalanceRegionHandler); +void relax_shell_flexcon(FILE* log, + const t_commrec* cr, + const gmx_multisim_t* ms, + gmx_bool bVerbose, + gmx_enfrot* enforcedRotation, + int64_t mdstep, + const t_inputrec* inputrec, + gmx::ImdSession* imdSession, + pull_t* pull_work, + gmx_bool bDoNS, + int force_flags, + const gmx_localtop_t* top, + gmx::Constraints* constr, + gmx_enerdata_t* enerd, + t_fcdata* fcd, + int natoms, + gmx::ArrayRefWithPadding x, + gmx::ArrayRefWithPadding v, + const matrix box, + gmx::ArrayRef lambda, + history_t* hist, + gmx::ArrayRefWithPadding f, + tensor force_vir, + const t_mdatoms* md, + t_nrnb* nrnb, + gmx_wallcycle_t wcycle, + t_graph* graph, + gmx_shellfc_t* shfc, + t_forcerec* fr, + gmx::MdrunScheduleWorkload* runScheduleWork, + double t, + rvec mu_tot, + const gmx_vsite_t* vsite, + const DDBalanceRegionHandler& ddBalanceRegionHandler); /* Print some final output */ -void done_shellfc(FILE *fplog, gmx_shellfc_t *shellfc, int64_t numSteps); +void done_shellfc(FILE* fplog, gmx_shellfc_t* shellfc, int64_t numSteps); /*! \brief Count the different particle types in a system * @@ -119,7 +120,6 @@ void done_shellfc(FILE *fplog, gmx_shellfc_t *shellfc, int64_t numSteps); * \param[in] mtop Molecular topology. * \returns Array holding the number of particles of a type */ -std::array countPtypes(FILE *fplog, - const gmx_mtop_t *mtop); +std::array countPtypes(FILE* fplog, const gmx_mtop_t* mtop); #endif diff --git a/src/gromacs/mdrun/simulationcontext.cpp b/src/gromacs/mdrun/simulationcontext.cpp index cf399454f3..91428c252b 100644 --- a/src/gromacs/mdrun/simulationcontext.cpp +++ b/src/gromacs/mdrun/simulationcontext.cpp @@ -54,8 +54,8 @@ SimulationContext::SimulationContext(MPI_Comm communica const ArrayRef multiSimDirectoryNames) : communicator_(communicator) { - GMX_RELEASE_ASSERT((GMX_LIB_MPI && (communicator != MPI_COMM_NULL)) || - (!GMX_LIB_MPI && (communicator == MPI_COMM_NULL)), + GMX_RELEASE_ASSERT((GMX_LIB_MPI && (communicator != MPI_COMM_NULL)) + || (!GMX_LIB_MPI && (communicator == MPI_COMM_NULL)), "With real MPI, a non-null communicator is required. " "Without it, the communicator must be null."); if (!multiSimDirectoryNames.empty()) diff --git a/src/gromacs/mdrun/simulationcontext.h b/src/gromacs/mdrun/simulationcontext.h index 1cb5b51036..2e4ca42e31 100644 --- a/src/gromacs/mdrun/simulationcontext.h +++ b/src/gromacs/mdrun/simulationcontext.h @@ -58,7 +58,8 @@ struct gmx_multisim_t; namespace gmx { -template class ArrayRef; +template +class ArrayRef; /*! \cond libapi * \libinternal @@ -99,49 +100,48 @@ template class ArrayRef; */ class SimulationContext final { - public: - /*! - * \brief Object must be initialized with non-default constructor. - */ - SimulationContext() = delete; - /*! - * \brief Construct - * - * \param communicator MPI communicator for this (set of) simulations - * \param multiSimDirectoryNames Names of any directories used with -multidir - */ - explicit SimulationContext(MPI_Comm communicator, - ArrayRef multiSimDirectoryNames); +public: + /*! + * \brief Object must be initialized with non-default constructor. + */ + SimulationContext() = delete; + /*! + * \brief Construct + * + * \param communicator MPI communicator for this (set of) simulations + * \param multiSimDirectoryNames Names of any directories used with -multidir + */ + explicit SimulationContext(MPI_Comm communicator, ArrayRef multiSimDirectoryNames); - /*! - * \brief MPI communicator object for this simulation object. - * - * With real MPI, - * the gmx wrapper binary has called MPI_Init, thus - * MPI_COMM_WORLD is now valid to use, and - * (in future) the gmxapi runner will handle such details - * (e.g. via mpi4py) before creating its SimulationContext. - * In both cases, if a multi-simulation is in use, then its - * communicator(s) are found in multiSimulation_. This - * communicator is that of all ranks from all simulations, and - * will later be split into one for each simulation. - * TODO Perhaps (for simplicity) that communicator splitting - * task can be undertaken during multi-sim setup. - * - * With thread-MPI in both cases, the communicator is set up later - * during the process of spawning the threads that will be the MPI - * ranks. (Multi-simulation is not supported with thread-MPI.) - */ - MPI_Comm communicator_ = MPI_COMM_NULL; + /*! + * \brief MPI communicator object for this simulation object. + * + * With real MPI, + * the gmx wrapper binary has called MPI_Init, thus + * MPI_COMM_WORLD is now valid to use, and + * (in future) the gmxapi runner will handle such details + * (e.g. via mpi4py) before creating its SimulationContext. + * In both cases, if a multi-simulation is in use, then its + * communicator(s) are found in multiSimulation_. This + * communicator is that of all ranks from all simulations, and + * will later be split into one for each simulation. + * TODO Perhaps (for simplicity) that communicator splitting + * task can be undertaken during multi-sim setup. + * + * With thread-MPI in both cases, the communicator is set up later + * during the process of spawning the threads that will be the MPI + * ranks. (Multi-simulation is not supported with thread-MPI.) + */ + MPI_Comm communicator_ = MPI_COMM_NULL; - /*! - * \brief Multi-sim handler (if required by e.g. gmx mdrun - * -multidir; only supported with real MPI) - */ - std::unique_ptr multiSimulation_; + /*! + * \brief Multi-sim handler (if required by e.g. gmx mdrun + * -multidir; only supported with real MPI) + */ + std::unique_ptr multiSimulation_; }; //! \endcond -} // end namespace gmx +} // end namespace gmx -#endif //GROMACS_SIMULATIONCONTEXT_H +#endif // GROMACS_SIMULATIONCONTEXT_H diff --git a/src/gromacs/mdrun/simulatorbuilder.h b/src/gromacs/mdrun/simulatorbuilder.h index b7847bf93a..df78b804ef 100644 --- a/src/gromacs/mdrun/simulatorbuilder.h +++ b/src/gromacs/mdrun/simulatorbuilder.h @@ -93,27 +93,23 @@ struct MdrunOptions; */ class SimulatorBuilder { - public: - /*! \brief Build a Simulator object based on input data - * - * Return a pointer to a simulation object. The use of a parameter - * pack insulates the builder from changes to the arguments of the - * Simulator objects. - * - * @return Unique pointer to a Simulator object - */ - template - std::unique_ptr build( - bool inputIsCompatibleWithModularSimulator, - Args && ... args); +public: + /*! \brief Build a Simulator object based on input data + * + * Return a pointer to a simulation object. The use of a parameter + * pack insulates the builder from changes to the arguments of the + * Simulator objects. + * + * @return Unique pointer to a Simulator object + */ + template + std::unique_ptr build(bool inputIsCompatibleWithModularSimulator, Args&&... args); }; //! Build a Simulator object -template -std::unique_ptr SimulatorBuilder::build( - bool inputIsCompatibleWithModularSimulator, - Args && ... args) +template +std::unique_ptr SimulatorBuilder::build(bool inputIsCompatibleWithModularSimulator, Args&&... args) { // GMX_DISABLE_MODULAR_SIMULATOR allows to disable modular simulator for all uses const auto disableModularSimulator = (getenv("GMX_DISABLE_MODULAR_SIMULATOR") != nullptr); @@ -121,16 +117,12 @@ std::unique_ptr SimulatorBuilder::build( if (!disableModularSimulator && inputIsCompatibleWithModularSimulator) { // NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor - return std::unique_ptr( - new ModularSimulator( - std::forward(args) ...)); + return std::unique_ptr(new ModularSimulator(std::forward(args)...)); } // NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor - return std::unique_ptr( - new LegacySimulator( - std::forward(args) ...)); + return std::unique_ptr(new LegacySimulator(std::forward(args)...)); } -} // namespace gmx +} // namespace gmx #endif // GMX_MDRUN_SIMULATORBUILDER_SIMULATORBUILDER_H diff --git a/src/gromacs/mdrun/tpi.cpp b/src/gromacs/mdrun/tpi.cpp index b58165c61a..2ed8bd4586 100644 --- a/src/gromacs/mdrun/tpi.cpp +++ b/src/gromacs/mdrun/tpi.cpp @@ -99,7 +99,7 @@ #include "legacysimulator.h" //! Global max algorithm -static void global_max(t_commrec *cr, int *n) +static void global_max(t_commrec* cr, int* n) { int *sum, i; @@ -115,7 +115,7 @@ static void global_max(t_commrec *cr, int *n) } //! Reallocate arrays. -static void realloc_bins(double **bin, int *nbin, int nbin_new) +static void realloc_bins(double** bin, int* nbin, int nbin_new) { int i; @@ -131,73 +131,73 @@ static void realloc_bins(double **bin, int *nbin, int nbin_new) } //! Computes and returns the RF exclusion energy for the last molecule starting at \p beginAtom -static real -reactionFieldExclusionCorrection(gmx::ArrayRef x, - const t_mdatoms &mdatoms, - const interaction_const_t &ic, - const int beginAtom) +static real reactionFieldExclusionCorrection(gmx::ArrayRef x, + const t_mdatoms& mdatoms, + const interaction_const_t& ic, + const int beginAtom) { real energy = 0; for (int i = beginAtom; i < mdatoms.homenr; i++) { const real qi = mdatoms.chargeA[i]; - energy -= 0.5*qi*qi*ic.c_rf; + energy -= 0.5 * qi * qi * ic.c_rf; for (int j = i + 1; j < mdatoms.homenr; j++) { const real qj = mdatoms.chargeA[j]; const real rsq = distance2(x[i], x[j]); - energy += qi*qj*(ic.k_rf*rsq - ic.c_rf); + energy += qi * qj * (ic.k_rf * rsq - ic.c_rf); } } - return ic.epsfac*energy; + return ic.epsfac * energy; } namespace gmx { // TODO: Convert to use the nbnxm kernels by putting the system and the teset molecule on two separate search grids -void -LegacySimulator::do_tpi() +void LegacySimulator::do_tpi() { GMX_RELEASE_ASSERT(gmx_omp_nthreads_get(emntDefault) == 1, "TPI does not support OpenMP"); gmx_localtop_t top; - PaddedHostVector f {}; + PaddedHostVector f{}; real lambda, t, temp, beta, drmax, epot; double embU, sum_embU, *sum_UgembU, V, V_all, VembU_all; - t_trxstatus *status; + t_trxstatus* status; t_trxframe rerun_fr; gmx_bool bDispCorr, bCharge, bRFExcl, bNotLastFrame, bStateChanged, bNS; tensor force_vir, shake_vir, vir, pres; int a_tp0, a_tp1, ngid, gid_tp, nener, e; - rvec *x_mol; + rvec* x_mol; rvec mu_tot, x_init, dx; int nnodes, frame; int64_t frame_step_prev, frame_step; int64_t nsteps, stepblocksize = 0, step; int64_t seed; int i; - FILE *fp_tpi = nullptr; - char *ptr, *dump_pdb, **leg, str[STRLEN], str2[STRLEN]; + FILE* fp_tpi = nullptr; + char * ptr, *dump_pdb, **leg, str[STRLEN], str2[STRLEN]; double dbl, dump_ener; gmx_bool bCavity; int nat_cavity = 0, d; - real *mass_cavity = nullptr, mass_tot; + real * mass_cavity = nullptr, mass_tot; int nbin; double invbinw, *bin, refvolshift, logV, bUlogV; gmx_bool bEnergyOutOfBounds; - const char *tpid_leg[2] = {"direct", "reweighted"}; + const char* tpid_leg[2] = { "direct", "reweighted" }; auto mdatoms = mdAtoms->mdatoms(); GMX_UNUSED_VALUE(outputProvider); - GMX_LOG(mdlog.info).asParagraph(). - appendText("Note that it is planned to change the command gmx mdrun -tpi " - "(and -tpic) to make the functionality available in a different " - "form in a future version of GROMACS, e.g. gmx test-particle-insertion."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "Note that it is planned to change the command gmx mdrun -tpi " + "(and -tpic) to make the functionality available in a different " + "form in a future version of GROMACS, e.g. gmx test-particle-insertion."); /* Since there is no upper limit to the insertion energies, * we need to set an upper limit for the distribution output. @@ -209,7 +209,7 @@ LegacySimulator::do_tpi() gmx_mtop_generate_local_top(*top_global, &top, inputrec->efep != efepNO); - SimulationGroups *groups = &top_global->groups; + SimulationGroups* groups = &top_global->groups; bCavity = (inputrec->eI == eiTPIC); if (bCavity) @@ -227,10 +227,9 @@ LegacySimulator::do_tpi() nat_cavity = 0; while (sscanf(ptr, "%20lf%n", &dbl, &i) > 0) { - srenew(mass_cavity, nat_cavity+1); + srenew(mass_cavity, nat_cavity + 1); mass_cavity[nat_cavity] = dbl; - fprintf(fplog, "mass[%d] = %f\n", - nat_cavity+1, mass_cavity[nat_cavity]); + fprintf(fplog, "mass[%d] = %f\n", nat_cavity + 1, mass_cavity[nat_cavity]); nat_cavity++; ptr += i; } @@ -254,15 +253,17 @@ LegacySimulator::do_tpi() { if (inputrec->opts.ref_t[i] != temp) { - fprintf(fplog, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); - fprintf(stderr, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); + fprintf(fplog, + "\nWARNING: The temperatures of the different temperature coupling groups " + "are not identical\n\n"); + fprintf(stderr, + "\nWARNING: The temperatures of the different temperature coupling groups " + "are not identical\n\n"); } } - fprintf(fplog, - "\n The temperature for test particle insertion is %.3f K\n\n", - temp); + fprintf(fplog, "\n The temperature for test particle insertion is %.3f K\n\n", temp); } - beta = 1.0/(BOLTZ*temp); + beta = 1.0 / (BOLTZ * temp); /* Number of insertions per frame */ nsteps = inputrec->nsteps; @@ -294,9 +295,9 @@ LegacySimulator::do_tpi() print_start(fplog, cr, walltime_accounting, "Test Particle Insertion"); /* The last charge group is the group to be inserted */ - const t_atoms &atomsToInsert = top_global->moltype[top_global->molblock.back().type].atoms; - a_tp0 = top_global->natoms - atomsToInsert.nr; - a_tp1 = top_global->natoms; + const t_atoms& atomsToInsert = top_global->moltype[top_global->molblock.back().type].atoms; + a_tp0 = top_global->natoms - atomsToInsert.nr; + a_tp1 = top_global->natoms; if (debug) { fprintf(debug, "TPI atoms %d-%d\n", a_tp0, a_tp1); @@ -323,17 +324,17 @@ LegacySimulator::do_tpi() } } - snew(x_mol, a_tp1-a_tp0); + snew(x_mol, a_tp1 - a_tp0); bDispCorr = (inputrec->eDispCorr != edispcNO); bCharge = FALSE; for (i = a_tp0; i < a_tp1; i++) { /* Copy the coordinates of the molecule to be insterted */ - copy_rvec(x[i], x_mol[i-a_tp0]); + copy_rvec(x[i], x_mol[i - a_tp0]); /* Check if we need to print electrostatic energies */ - bCharge |= (mdatoms->chargeA[i] != 0 || - ((mdatoms->chargeB != nullptr) && mdatoms->chargeB[i] != 0)); + bCharge |= (mdatoms->chargeA[i] != 0 + || ((mdatoms->chargeB != nullptr) && mdatoms->chargeB[i] != 0)); } bRFExcl = (bCharge && EEL_RF(fr->ic->eeltype)); @@ -343,7 +344,7 @@ LegacySimulator::do_tpi() { rvec_inc(cog, x[a]); } - svmul(1.0_real/(a_tp1 - a_tp0), cog, cog); + svmul(1.0_real / (a_tp1 - a_tp0), cog, cog); real molRadius = 0; for (int a = a_tp0; a < a_tp1; a++) { @@ -351,10 +352,10 @@ LegacySimulator::do_tpi() } molRadius = std::sqrt(molRadius); - const real maxCutoff = std::max(inputrec->rvdw, inputrec->rcoulomb); + const real maxCutoff = std::max(inputrec->rvdw, inputrec->rcoulomb); if (bCavity) { - if (norm(cog) > 0.5*maxCutoff && fplog) + if (norm(cog) > 0.5 * maxCutoff && fplog) { fprintf(fplog, "WARNING: Your TPI molecule is not centered at 0,0,0\n"); fprintf(stderr, "WARNING: Your TPI molecule is not centered at 0,0,0\n"); @@ -363,7 +364,7 @@ LegacySimulator::do_tpi() else { /* Center the molecule to be inserted at zero */ - for (i = 0; i < a_tp1-a_tp0; i++) + for (i = 0; i < a_tp1 - a_tp0; i++) { rvec_dec(x_mol[i], cog); } @@ -371,11 +372,11 @@ LegacySimulator::do_tpi() if (fplog) { - fprintf(fplog, "\nWill insert %d atoms %s partial charges\n", - a_tp1-a_tp0, bCharge ? "with" : "without"); + fprintf(fplog, "\nWill insert %d atoms %s partial charges\n", a_tp1 - a_tp0, + bCharge ? "with" : "without"); - fprintf(fplog, "\nWill insert %" PRId64 " times in each frame of %s\n", - nsteps, opt2fn("-rerun", nfile, fnm)); + fprintf(fplog, "\nWill insert %" PRId64 " times in each frame of %s\n", nsteps, + opt2fn("-rerun", nfile, fnm)); } if (!bCavity) @@ -384,13 +385,19 @@ LegacySimulator::do_tpi() { /* With the same pair list we insert in a sphere of radius rtpi in different orientations */ - if (drmax == 0 && a_tp1-a_tp0 == 1) + if (drmax == 0 && a_tp1 - a_tp0 == 1) { - gmx_fatal(FARGS, "Re-using the neighborlist %d times for insertions of a single atom in a sphere of radius %f does not make sense", inputrec->nstlist, drmax); + gmx_fatal(FARGS, + "Re-using the neighborlist %d times for insertions of a single atom in a " + "sphere of radius %f does not make sense", + inputrec->nstlist, drmax); } if (fplog) { - fprintf(fplog, "Will use the same neighborlist for %d insertions in a sphere of radius %f\n", inputrec->nstlist, drmax); + fprintf(fplog, + "Will use the same neighborlist for %d insertions in a sphere of radius " + "%f\n", + inputrec->nstlist, drmax); } } } @@ -398,7 +405,10 @@ LegacySimulator::do_tpi() { if (fplog) { - fprintf(fplog, "Will insert randomly in a sphere of radius %f around the center of the cavity\n", drmax); + fprintf(fplog, + "Will insert randomly in a sphere of radius %f around the center of the " + "cavity\n", + drmax); } } @@ -407,7 +417,7 @@ LegacySimulator::do_tpi() * inserted atoms located in the center of the sphere, so we need * a buffer of size of the sphere and molecule radius. */ - inputrec->rlist = maxCutoff + 2*inputrec->rtpi + 2*molRadius; + inputrec->rlist = maxCutoff + 2 * inputrec->rtpi + 2 * molRadius; fr->rlist = inputrec->rlist; fr->nbv->changePairlistRadii(inputrec->rlist, inputrec->rlist); @@ -423,7 +433,7 @@ LegacySimulator::do_tpi() break; } } - nener = 1 + ngid; + nener = 1 + ngid; if (bDispCorr) { nener += 1; @@ -445,16 +455,16 @@ LegacySimulator::do_tpi() /* Copy the random seed set by the user */ seed = inputrec->ld_seed; - gmx::ThreeFry2x64<16> rng(seed, gmx::RandomDomain::TestParticleInsertion); // 16 bits internal counter => 2^16 * 2 = 131072 values per stream - gmx::UniformRealDistribution dist; + gmx::ThreeFry2x64<16> rng( + seed, gmx::RandomDomain::TestParticleInsertion); // 16 bits internal counter => 2^16 * 2 = 131072 values per stream + gmx::UniformRealDistribution dist; if (MASTER(cr)) { - fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm), - "TPI energies", "Time (ps)", + fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm), "TPI energies", "Time (ps)", "(kJ mol\\S-1\\N) / (nm\\S3\\N)", oenv); xvgr_subtitle(fp_tpi, "f. are averages over one frame", oenv); - snew(leg, 4+nener); + snew(leg, 4 + nener); e = 0; sprintf(str, "-kT log(/)"); leg[e++] = gmx_strdup(str); @@ -496,8 +506,8 @@ LegacySimulator::do_tpi() leg[e++] = gmx_strdup(str); } } - xvgr_legend(fp_tpi, 4+nener, leg, oenv); - for (i = 0; i < 4+nener; i++) + xvgr_legend(fp_tpi, 4 + nener, leg, oenv); + for (i = 0; i < 4 + nener; i++) { sfree(leg[i]); } @@ -514,37 +524,30 @@ LegacySimulator::do_tpi() /* Avoid frame step numbers <= -1 */ frame_step_prev = -1; - bNotLastFrame = read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm), - &rerun_fr, TRX_NEED_X); - frame = 0; + bNotLastFrame = read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm), &rerun_fr, TRX_NEED_X); + frame = 0; - if (rerun_fr.natoms - (bCavity ? nat_cavity : 0) != - mdatoms->nr - (a_tp1 - a_tp0)) + if (rerun_fr.natoms - (bCavity ? nat_cavity : 0) != mdatoms->nr - (a_tp1 - a_tp0)) { - gmx_fatal(FARGS, "Number of atoms in trajectory (%d)%s " + gmx_fatal(FARGS, + "Number of atoms in trajectory (%d)%s " "is not equal the number in the run input file (%d) " "minus the number of atoms to insert (%d)\n", - rerun_fr.natoms, bCavity ? " minus one" : "", - mdatoms->nr, a_tp1-a_tp0); + rerun_fr.natoms, bCavity ? " minus one" : "", mdatoms->nr, a_tp1 - a_tp0); } refvolshift = log(det(rerun_fr.box)); switch (inputrec->eI) { - case eiTPI: - stepblocksize = inputrec->nstlist; - break; - case eiTPIC: - stepblocksize = 1; - break; - default: - gmx_fatal(FARGS, "Unknown integrator %s", ei_names[inputrec->eI]); + case eiTPI: stepblocksize = inputrec->nstlist; break; + case eiTPIC: stepblocksize = 1; break; + default: gmx_fatal(FARGS, "Unknown integrator %s", ei_names[inputrec->eI]); } while (bNotLastFrame) { - frame_step = rerun_fr.step; + frame_step = rerun_fr.step; if (frame_step <= frame_step_prev) { /* We don't have step number in the trajectory file, @@ -552,7 +555,7 @@ LegacySimulator::do_tpi() * Ensure we have increasing step numbers, since we use * the step numbers as a counter for random numbers. */ - frame_step = frame_step_prev + 1; + frame_step = frame_step_prev + 1; } frame_step_prev = frame_step; @@ -572,7 +575,7 @@ LegacySimulator::do_tpi() copy_rvec(rerun_fr.x[i], x[i]); } copy_mat(rerun_fr.box, state_global->box); - const matrix &box = state_global->box; + const matrix& box = state_global->box; V = det(box); logV = log(V); @@ -585,13 +588,10 @@ LegacySimulator::do_tpi() /* Put all atoms except for the inserted ones on the grid */ rvec vzero = { 0, 0, 0 }; rvec boxDiagonal = { box[XX][XX], box[YY][YY], box[ZZ][ZZ] }; - nbnxn_put_on_grid(fr->nbv.get(), box, - 0, vzero, boxDiagonal, - nullptr, { 0, a_tp0 }, -1, - fr->cginfo, x, - 0, nullptr); + nbnxn_put_on_grid(fr->nbv.get(), box, 0, vzero, boxDiagonal, nullptr, { 0, a_tp0 }, -1, + fr->cginfo, x, 0, nullptr); - step = cr->nodeid*stepblocksize; + step = cr->nodeid * stepblocksize; while (step < nsteps) { /* Restart random engine using the frame and insertion step @@ -603,7 +603,7 @@ LegacySimulator::do_tpi() * wrong you will get an exception when the stream is exhausted. */ rng.restart(frame_step, step); - dist.reset(); // erase any memory in the distribution + dist.reset(); // erase any memory in the distribution if (!bCavity) { @@ -614,7 +614,7 @@ LegacySimulator::do_tpi() /* Generate a random position in the box */ for (d = 0; d < DIM; d++) { - x_init[d] = dist(rng)*state_global->box[d][d]; + x_init[d] = dist(rng) * state_global->box[d][d]; } } } @@ -628,7 +628,7 @@ LegacySimulator::do_tpi() if (nat_cavity == 1) { /* Copy the location of the cavity */ - copy_rvec(rerun_fr.x[rerun_fr.natoms-1], x_init); + copy_rvec(rerun_fr.x[rerun_fr.natoms - 1], x_init); } else { @@ -639,8 +639,8 @@ LegacySimulator::do_tpi() { for (d = 0; d < DIM; d++) { - x_init[d] += - mass_cavity[i]*rerun_fr.x[rerun_fr.natoms-nat_cavity+i][d]; + x_init[d] += mass_cavity[i] + * rerun_fr.x[rerun_fr.natoms - nat_cavity + i][d]; } mass_tot += mass_cavity[i]; } @@ -660,17 +660,13 @@ LegacySimulator::do_tpi() } /* Put the inserted molecule on it's own search grid */ - nbnxn_put_on_grid(fr->nbv.get(), box, - 1, x_init, x_init, - nullptr, { a_tp0, a_tp1 }, -1, - fr->cginfo, x, - 0, nullptr); + nbnxn_put_on_grid(fr->nbv.get(), box, 1, x_init, x_init, nullptr, { a_tp0, a_tp1 }, + -1, fr->cginfo, x, 0, nullptr); /* TODO: Avoid updating all atoms at every bNS step */ fr->nbv->setAtomProperties(*mdatoms, fr->cginfo); - fr->nbv->constructPairlist(InteractionLocality::Local, - &top.excls, step, nrnb); + fr->nbv->constructPairlist(InteractionLocality::Local, &top.excls, step, nrnb); bNS = FALSE; } @@ -687,10 +683,9 @@ LegacySimulator::do_tpi() { for (d = 0; d < DIM; d++) { - dx[d] = (2*dist(rng) - 1)*drmax; + dx[d] = (2 * dist(rng) - 1) * drmax; } - } - while (norm2(dx) > drmax*drmax); + } while (norm2(dx) > drmax * drmax); rvec_add(x_init, dx, x_tp); } else @@ -708,14 +703,14 @@ LegacySimulator::do_tpi() /* Copy the coordinates from the top file */ for (i = a_tp0; i < a_tp1; i++) { - copy_rvec(x_mol[i-a_tp0], x[i]); + copy_rvec(x_mol[i - a_tp0], x[i]); } /* Rotate the molecule randomly */ - real angleX = 2*M_PI*dist(rng); - real angleY = 2*M_PI*dist(rng); - real angleZ = 2*M_PI*dist(rng); - rotate_conf(a_tp1-a_tp0, state_global->x.rvec_array()+a_tp0, nullptr, - angleX, angleY, angleZ); + real angleX = 2 * M_PI * dist(rng); + real angleY = 2 * M_PI * dist(rng); + real angleZ = 2 * M_PI * dist(rng); + rotate_conf(a_tp1 - a_tp0, state_global->x.rvec_array() + a_tp0, nullptr, angleX, + angleY, angleZ); /* Shift to the insertion location */ for (i = a_tp0; i < a_tp1; i++) { @@ -747,15 +742,11 @@ LegacySimulator::do_tpi() // might raise, then restore the old behaviour. std::fenv_t floatingPointEnvironment; std::feholdexcept(&floatingPointEnvironment); - do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, - pull_work, - step, nrnb, wcycle, &top, - state_global->box, state_global->x.arrayRefWithPadding(), &state_global->hist, - f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, - state_global->lambda, - nullptr, fr, runScheduleWork, nullptr, mu_tot, t, nullptr, - GMX_FORCE_NONBONDED | GMX_FORCE_ENERGY | - (bStateChanged ? GMX_FORCE_STATECHANGED : 0), + do_force(fplog, cr, ms, inputrec, nullptr, nullptr, imdSession, pull_work, step, nrnb, + wcycle, &top, state_global->box, state_global->x.arrayRefWithPadding(), + &state_global->hist, f.arrayRefWithPadding(), force_vir, mdatoms, enerd, fcd, + state_global->lambda, nullptr, fr, runScheduleWork, nullptr, mu_tot, t, nullptr, + GMX_FORCE_NONBONDED | GMX_FORCE_ENERGY | (bStateChanged ? GMX_FORCE_STATECHANGED : 0), DDBalanceRegionHandler(nullptr)); std::feclearexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); std::feupdateenv(&floatingPointEnvironment); @@ -767,20 +758,20 @@ LegacySimulator::do_tpi() { /* Calculate long range corrections to pressure and energy */ const DispersionCorrection::Correction correction = - fr->dispersionCorrection->calculate(state_global->box, lambda); + fr->dispersionCorrection->calculate(state_global->box, lambda); /* figure out how to rearrange the next 4 lines MRS 8/4/2009 */ enerd->term[F_DISPCORR] = correction.energy; - enerd->term[F_EPOT] += correction.energy; - enerd->term[F_PRES] += correction.pressure; - enerd->term[F_DVDL] += correction.dvdl; + enerd->term[F_EPOT] += correction.energy; + enerd->term[F_PRES] += correction.pressure; + enerd->term[F_DVDL] += correction.dvdl; } else { - enerd->term[F_DISPCORR] = 0; + enerd->term[F_DISPCORR] = 0; } if (EEL_RF(fr->ic->eeltype)) { - enerd->term[F_EPOT] += rfExclusionEnergy; + enerd->term[F_EPOT] += rfExclusionEnergy; } epot = enerd->term[F_EPOT]; @@ -808,37 +799,37 @@ LegacySimulator::do_tpi() { if (debug) { - fprintf(debug, "\n time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n", t, static_cast(step), epot); + fprintf(debug, + "\n time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n", t, + static_cast(step), epot); } embU = 0; } else { // Exponent argument is fine in SP range, but output can be in DP range - embU = exp(static_cast(-beta*epot)); + embU = exp(static_cast(-beta * epot)); sum_embU += embU; /* Determine the weighted energy contributions of each energy group */ - e = 0; - sum_UgembU[e++] += epot*embU; + e = 0; + sum_UgembU[e++] += epot * embU; if (fr->bBHAM) { for (i = 0; i < ngid; i++) { - sum_UgembU[e++] += - enerd->grpp.ener[egBHAMSR][GID(i, gid_tp, ngid)]*embU; + sum_UgembU[e++] += enerd->grpp.ener[egBHAMSR][GID(i, gid_tp, ngid)] * embU; } } else { for (i = 0; i < ngid; i++) { - sum_UgembU[e++] += - enerd->grpp.ener[egLJSR][GID(i, gid_tp, ngid)]*embU; + sum_UgembU[e++] += enerd->grpp.ener[egLJSR][GID(i, gid_tp, ngid)] * embU; } } if (bDispCorr) { - sum_UgembU[e++] += enerd->term[F_DISPCORR]*embU; + sum_UgembU[e++] += enerd->term[F_DISPCORR] * embU; } if (bCharge) { @@ -848,90 +839,87 @@ LegacySimulator::do_tpi() } if (bRFExcl) { - sum_UgembU[e++] += rfExclusionEnergy*embU; + sum_UgembU[e++] += rfExclusionEnergy * embU; } if (EEL_FULL(fr->ic->eeltype)) { - sum_UgembU[e++] += enerd->term[F_COUL_RECIP]*embU; + sum_UgembU[e++] += enerd->term[F_COUL_RECIP] * embU; } } } - if (embU == 0 || beta*epot > bU_bin_limit) + if (embU == 0 || beta * epot > bU_bin_limit) { bin[0]++; } else { - i = gmx::roundToInt((bU_logV_bin_limit - - (beta*epot - logV + refvolshift))*invbinw); + i = gmx::roundToInt((bU_logV_bin_limit - (beta * epot - logV + refvolshift)) * invbinw); if (i < 0) { i = 0; } if (i >= nbin) { - realloc_bins(&bin, &nbin, i+10); + realloc_bins(&bin, &nbin, i + 10); } bin[i]++; } if (debug) { - fprintf(debug, "TPI %7d %12.5e %12.5f %12.5f %12.5f\n", - static_cast(step), epot, x_tp[XX], x_tp[YY], x_tp[ZZ]); + fprintf(debug, "TPI %7d %12.5e %12.5f %12.5f %12.5f\n", static_cast(step), + epot, x_tp[XX], x_tp[YY], x_tp[ZZ]); } if (dump_pdb && epot <= dump_ener) { sprintf(str, "t%g_step%d.pdb", t, static_cast(step)); sprintf(str2, "t: %f step %d ener: %f", t, static_cast(step), epot); - write_sto_conf_mtop(str, str2, top_global, state_global->x.rvec_array(), state_global->v.rvec_array(), - inputrec->ePBC, state_global->box); + write_sto_conf_mtop(str, str2, top_global, state_global->x.rvec_array(), + state_global->v.rvec_array(), inputrec->ePBC, state_global->box); } step++; - if ((step/stepblocksize) % cr->nnodes != cr->nodeid) + if ((step / stepblocksize) % cr->nnodes != cr->nodeid) { /* Skip all steps assigned to the other MPI ranks */ - step += (cr->nnodes - 1)*stepblocksize; + step += (cr->nnodes - 1) * stepblocksize; } } if (PAR(cr)) { /* When running in parallel sum the energies over the processes */ - gmx_sumd(1, &sum_embU, cr); + gmx_sumd(1, &sum_embU, cr); gmx_sumd(nener, sum_UgembU, cr); } frame++; - V_all += V; - VembU_all += V*sum_embU/nsteps; + V_all += V; + VembU_all += V * sum_embU / nsteps; if (fp_tpi) { - if (mdrunOptions.verbose || frame%10 == 0 || frame < 10) + if (mdrunOptions.verbose || frame % 10 == 0 || frame < 10) { - fprintf(stderr, "mu %10.3e %10.3e\n", - -log(sum_embU/nsteps)/beta, -log(VembU_all/V_all)/beta); + fprintf(stderr, "mu %10.3e %10.3e\n", -log(sum_embU / nsteps) / beta, + -log(VembU_all / V_all) / beta); } - fprintf(fp_tpi, "%10.3f %12.5e %12.5e %12.5e %12.5e", - t, - VembU_all == 0 ? 20/beta : -log(VembU_all/V_all)/beta, - sum_embU == 0 ? 20/beta : -log(sum_embU/nsteps)/beta, - sum_embU/nsteps, V); + fprintf(fp_tpi, "%10.3f %12.5e %12.5e %12.5e %12.5e", t, + VembU_all == 0 ? 20 / beta : -log(VembU_all / V_all) / beta, + sum_embU == 0 ? 20 / beta : -log(sum_embU / nsteps) / beta, sum_embU / nsteps, V); for (e = 0; e < nener; e++) { - fprintf(fp_tpi, " %12.5e", sum_UgembU[e]/nsteps); + fprintf(fp_tpi, " %12.5e", sum_UgembU[e] / nsteps); } fprintf(fp_tpi, "\n"); fflush(fp_tpi); } bNotLastFrame = read_next_frame(oenv, status, &rerun_fr); - } /* End of the loop */ + } /* End of the loop */ walltime_accounting_end_time(walltime_accounting); close_trx(status); @@ -944,13 +932,15 @@ LegacySimulator::do_tpi() if (fplog != nullptr) { fprintf(fplog, "\n"); - fprintf(fplog, " = %12.5e nm^3\n", V_all/frame); - const double mu = -log(VembU_all/V_all)/beta; + fprintf(fplog, " = %12.5e nm^3\n", V_all / frame); + const double mu = -log(VembU_all / V_all) / beta; fprintf(fplog, " = %12.5e kJ/mol\n", mu); if (!std::isfinite(mu)) { - fprintf(fplog, "\nThe computed chemical potential is not finite - consider increasing the number of steps and/or the number of frames to insert into.\n"); + fprintf(fplog, + "\nThe computed chemical potential is not finite - consider increasing the " + "number of steps and/or the number of frames to insert into.\n"); } } @@ -965,19 +955,16 @@ LegacySimulator::do_tpi() } if (MASTER(cr)) { - fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm), - "TPI energy distribution", + fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm), "TPI energy distribution", "\\betaU - log(V/)", "count", oenv); sprintf(str, "number \\betaU > %g: %9.3e", bU_bin_limit, bin[0]); xvgr_subtitle(fp_tpi, str, oenv); xvgr_legend(fp_tpi, 2, tpid_leg, oenv); - for (i = nbin-1; i > 0; i--) + for (i = nbin - 1; i > 0; i--) { - bUlogV = -i/invbinw + bU_logV_bin_limit - refvolshift + log(V_all/frame); - fprintf(fp_tpi, "%6.2f %10d %12.5e\n", - bUlogV, - roundToInt(bin[i]), - bin[i]*exp(-bUlogV)*V_all/VembU_all); + bUlogV = -i / invbinw + bU_logV_bin_limit - refvolshift + log(V_all / frame); + fprintf(fp_tpi, "%6.2f %10d %12.5e\n", bUlogV, roundToInt(bin[i]), + bin[i] * exp(-bUlogV) * V_all / VembU_all); } xvgrclose(fp_tpi); } @@ -985,7 +972,7 @@ LegacySimulator::do_tpi() sfree(sum_UgembU); - walltime_accounting_set_nsteps_done(walltime_accounting, frame*inputrec->nsteps); + walltime_accounting_set_nsteps_done(walltime_accounting, frame * inputrec->nsteps); } } // namespace gmx diff --git a/src/gromacs/mdrunutility/handlerestart.cpp b/src/gromacs/mdrunutility/handlerestart.cpp index 964bfc48f7..d6fbdb1a76 100644 --- a/src/gromacs/mdrunutility/handlerestart.cpp +++ b/src/gromacs/mdrunutility/handlerestart.cpp @@ -57,8 +57,8 @@ #include #if GMX_NATIVE_WINDOWS -#include -#include +# include +# include #endif #include @@ -89,7 +89,7 @@ namespace /*! \brief Search for \p fnm_cp in fnm and return true iff found * * \todo This could be implemented sanely with a for loop. */ -gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm fnm[]) +gmx_bool exist_output_file(const char* fnm_cp, int nfile, const t_filenm fnm[]) { int i; @@ -97,8 +97,7 @@ gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm fnm[]) * is one of the output file names of mdrun. */ i = 0; - while (i < nfile && - !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].filenames[0].c_str()) == 0)) + while (i < nfile && !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].filenames[0].c_str()) == 0)) { i++; } @@ -112,24 +111,24 @@ gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm fnm[]) * file was found (so it is not the first part of a new run), but we are still missing * some or all checkpoint files. In this case we issue a fatal error since there are * so many special cases we cannot keep track of, and better safe than sorry. */ -[[noreturn]] void -throwBecauseOfMissingOutputFiles(const char *checkpointFilename, - ArrayRef outputfiles, - int nfile, const t_filenm fnm[], - size_t numFilesMissing) +[[noreturn]] void throwBecauseOfMissingOutputFiles(const char* checkpointFilename, + ArrayRef outputfiles, + int nfile, + const t_filenm fnm[], + size_t numFilesMissing) { StringOutputStream stream; TextWriter writer(&stream); - writer.writeStringFormatted - ("Some output files listed in the checkpoint file %s are not present or not named " - "as the output files by the current program:)", - checkpointFilename); + writer.writeStringFormatted( + "Some output files listed in the checkpoint file %s are not present or not named " + "as the output files by the current program:)", + checkpointFilename); auto settings = writer.wrapperSettings(); auto oldIndent = settings.indent(), newIndent = 2; writer.writeLine("Expected output files that are present:"); settings.setIndent(newIndent); - for (const auto &outputfile : outputfiles) + for (const auto& outputfile : outputfiles) { if (exist_output_file(outputfile.filename, nfile, fnm)) { @@ -141,10 +140,9 @@ throwBecauseOfMissingOutputFiles(const char *checkpointFilename, writer.writeLine("Expected output files that are not present or named differently:"); settings.setIndent(newIndent); - for (const auto &outputfile : outputfiles) + for (const auto& outputfile : outputfiles) { - if (!exist_output_file(outputfile.filename, - nfile, fnm)) + if (!exist_output_file(outputfile.filename, nfile, fnm)) { writer.writeLine(outputfile.filename); } @@ -162,7 +160,7 @@ In the last case, you will not be able to use appending in future for this simul } //! Return a string describing the precision of a build of GROMACS. -const char *precisionToString(bool isDoublePrecision) +const char* precisionToString(bool isDoublePrecision) { return isDoublePrecision ? "double" : "mixed"; } @@ -171,37 +169,36 @@ const char *precisionToString(bool isDoublePrecision) * functionality based on that data. */ class StartingBehaviorHandler { - public: - /*! \brief Throw unless all simulations in a multi-sim restart the same way. - * - * The restart could differ if checkpoint or other output files are - * not found in a consistent way across the set of multi-simulations, - * or are from different simulation parts. - * - * \param[in] ms Multi-sim handler. - * - * May only be called from the master rank of each simulation. - * - * \throws InconsistentInputError if either simulations restart - * differently, or from checkpoints from different simulation parts. - */ - void ensureMultiSimBehaviorsMatch(const gmx_multisim_t *ms); - /*! \brief Return an optional value that describes the index - * of the next simulation part when not appending. - * - * \param[in] appendingBehavior Whether this simulation is appending - * (relevant only when restarting) - * - * Does not throw */ - compat::optional makeIndexOfNextPart(AppendingBehavior appendingBehavior) const; - - //! Describes how mdrun will (re)start - StartingBehavior startingBehavior = StartingBehavior::NewSimulation; - //! When restarting from a checkpoint, contains the contents of its header - compat::optional headerContents; - //! When restarting from a checkpoint, contains the names of expected output files - compat::optional < std::vector < gmx_file_position_t>> outputFiles; - +public: + /*! \brief Throw unless all simulations in a multi-sim restart the same way. + * + * The restart could differ if checkpoint or other output files are + * not found in a consistent way across the set of multi-simulations, + * or are from different simulation parts. + * + * \param[in] ms Multi-sim handler. + * + * May only be called from the master rank of each simulation. + * + * \throws InconsistentInputError if either simulations restart + * differently, or from checkpoints from different simulation parts. + */ + void ensureMultiSimBehaviorsMatch(const gmx_multisim_t* ms); + /*! \brief Return an optional value that describes the index + * of the next simulation part when not appending. + * + * \param[in] appendingBehavior Whether this simulation is appending + * (relevant only when restarting) + * + * Does not throw */ + compat::optional makeIndexOfNextPart(AppendingBehavior appendingBehavior) const; + + //! Describes how mdrun will (re)start + StartingBehavior startingBehavior = StartingBehavior::NewSimulation; + //! When restarting from a checkpoint, contains the contents of its header + compat::optional headerContents; + //! When restarting from a checkpoint, contains the names of expected output files + compat::optional> outputFiles; }; /*! \brief Choose the starting behaviour for this simulation @@ -214,10 +211,9 @@ class StartingBehaviorHandler * found (and other files found, when appending), and so can differ * between multi-simulations. It is the caller's responsibility to * detect this and react accordingly. */ -StartingBehaviorHandler -chooseStartingBehavior(const AppendingBehavior appendingBehavior, - const int nfile, - t_filenm fnm[]) +StartingBehaviorHandler chooseStartingBehavior(const AppendingBehavior appendingBehavior, + const int nfile, + t_filenm fnm[]) { StartingBehaviorHandler handler; if (!opt2bSet("-cpi", nfile, fnm)) @@ -228,7 +224,7 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, } // A -cpi option was provided, do a restart if there is an input checkpoint file available - const char *checkpointFilename = opt2fn("-cpi", nfile, fnm); + const char* checkpointFilename = opt2fn("-cpi", nfile, fnm); if (!gmx_fexist(checkpointFilename)) { // This is interpreted as the user intending a new @@ -236,46 +232,47 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, // for all simulation parts. Thus, appending cannot occur. if (appendingBehavior == AppendingBehavior::Appending) { - GMX_THROW(InconsistentInputError - ("Could not do a restart with appending because the checkpoint file " - "was not found. Either supply the name of the right checkpoint file " - "or do not use -append")); + GMX_THROW(InconsistentInputError( + "Could not do a restart with appending because the checkpoint file " + "was not found. Either supply the name of the right checkpoint file " + "or do not use -append")); } // No need to tell the user that mdrun -cpi without a file means a new simulation handler.startingBehavior = StartingBehavior::NewSimulation; return handler; } - t_fileio *fp = gmx_fio_open(checkpointFilename, "r"); + t_fileio* fp = gmx_fio_open(checkpointFilename, "r"); if (fp == nullptr) { - GMX_THROW(FileIOError - (formatString("Checkpoint file '%s' was found but could not be opened for " - "reading. Check the file permissions.", checkpointFilename))); + GMX_THROW(FileIOError( + formatString("Checkpoint file '%s' was found but could not be opened for " + "reading. Check the file permissions.", + checkpointFilename))); } - std::vector < gmx_file_position_t> outputFiles; - CheckpointHeaderContents headerContents = - read_checkpoint_simulation_part_and_filenames(fp, &outputFiles); + std::vector outputFiles; + CheckpointHeaderContents headerContents = + read_checkpoint_simulation_part_and_filenames(fp, &outputFiles); GMX_RELEASE_ASSERT(!outputFiles.empty(), "The checkpoint file or its reading is broken, as no output " "file information is stored in it"); - const char *logFilename = outputFiles[0].filename; + const char* logFilename = outputFiles[0].filename; GMX_RELEASE_ASSERT(Path::extensionMatches(logFilename, ftp2ext(efLOG)), formatString("The checkpoint file or its reading is broken, the first " "output file '%s' must be a log file with extension '%s'", - logFilename, ftp2ext(efLOG)).c_str()); + logFilename, ftp2ext(efLOG)) + .c_str()); if (appendingBehavior != AppendingBehavior::NoAppending) { // See whether appending can be done. - size_t numFilesMissing = std::count_if(std::begin(outputFiles), std::end(outputFiles), - [nfile, fnm](const auto &outputFile) - { - return !exist_output_file(outputFile.filename, nfile, fnm); - }); + size_t numFilesMissing = std::count_if( + std::begin(outputFiles), std::end(outputFiles), [nfile, fnm](const auto& outputFile) { + return !exist_output_file(outputFile.filename, nfile, fnm); + }); if (numFilesMissing != 0) { // Appending is not possible, because not all previous @@ -287,7 +284,7 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, throwBecauseOfMissingOutputFiles(checkpointFilename, outputFiles, nfile, fnm, numFilesMissing); } - for (const auto &outputFile : outputFiles) + for (const auto& outputFile : outputFiles) { if (outputFile.offset < 0) { @@ -298,20 +295,20 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, // understanding that their infrastructure is not very // suitable for running a simulation producing lots of // output. - auto message = - formatString("The original mdrun wrote a file called '%s' which " - "is larger than 2 GB, but that mdrun or the filesystem " - "it ran on (e.g FAT32) did not support such large files. " - "This simulation cannot be restarted with appending. It will " - "be easier for you to use mdrun on a 64-bit filesystem, but " - "if you choose not to, then you must run mdrun with " - "-noappend once your output gets large enough.", - outputFile.filename); + auto message = formatString( + "The original mdrun wrote a file called '%s' which " + "is larger than 2 GB, but that mdrun or the filesystem " + "it ran on (e.g FAT32) did not support such large files. " + "This simulation cannot be restarted with appending. It will " + "be easier for you to use mdrun on a 64-bit filesystem, but " + "if you choose not to, then you must run mdrun with " + "-noappend once your output gets large enough.", + outputFile.filename); GMX_THROW(InconsistentInputError(message)); } } - const char *logFilename = outputFiles[0].filename; + const char* logFilename = outputFiles[0].filename; // If the precision does not match, we cannot continue with // appending, and will switch to not appending unless // instructed otherwise. @@ -319,12 +316,11 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, { if (appendingBehavior == AppendingBehavior::Appending) { - GMX_THROW(InconsistentInputError - (formatString("Cannot restart with appending because the previous simulation part used " - "%s precision which does not match the %s precision used by this build " - "of GROMACS. Either use matching precision or use mdrun -noappend.", - precisionToString(headerContents.double_prec), - precisionToString(GMX_DOUBLE)))); + GMX_THROW(InconsistentInputError(formatString( + "Cannot restart with appending because the previous simulation part used " + "%s precision which does not match the %s precision used by this build " + "of GROMACS. Either use matching precision or use mdrun -noappend.", + precisionToString(headerContents.double_prec), precisionToString(GMX_DOUBLE)))); } } // If the previous log filename had a part number, then we @@ -334,10 +330,10 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, { if (appendingBehavior == AppendingBehavior::Appending) { - GMX_THROW(InconsistentInputError - ("Cannot restart with appending because the previous simulation " - "part did not use appending. Either do not use mdrun -append, or " - "provide the correct checkpoint file.")); + GMX_THROW(InconsistentInputError( + "Cannot restart with appending because the previous simulation " + "part did not use appending. Either do not use mdrun -append, or " + "provide the correct checkpoint file.")); } } else @@ -352,35 +348,33 @@ chooseStartingBehavior(const AppendingBehavior appendingBehavior, // when they ask for it. } - GMX_RELEASE_ASSERT(appendingBehavior != AppendingBehavior::Appending, "Logic error in appending"); + GMX_RELEASE_ASSERT(appendingBehavior != AppendingBehavior::Appending, + "Logic error in appending"); handler = { StartingBehavior::RestartWithoutAppending, headerContents, outputFiles }; return handler; } //! Check whether chksum_file output file has a checksum that matches \c outputfile from the checkpoint. -void checkOutputFile(t_fileio *fileToCheck, - const gmx_file_position_t &outputfile) +void checkOutputFile(t_fileio* fileToCheck, const gmx_file_position_t& outputfile) { /* compute md5 chksum */ std::array digest; if (outputfile.checksumSize != -1) { - if (gmx_fio_get_file_md5(fileToCheck, outputfile.offset, - &digest) != outputfile.checksumSize) /*at the end of the call the file position is at the end of the file*/ + if (gmx_fio_get_file_md5(fileToCheck, outputfile.offset, &digest) + != outputfile.checksumSize) /*at the end of the call the file position is at the end of the file*/ { - auto message = - formatString("Can't read %d bytes of '%s' to compute checksum. The file " - "has been replaced or its contents have been modified. Cannot " - "do appending because of this condition.", - outputfile.checksumSize, - outputfile.filename); + auto message = formatString( + "Can't read %d bytes of '%s' to compute checksum. The file " + "has been replaced or its contents have been modified. Cannot " + "do appending because of this condition.", + outputfile.checksumSize, outputfile.filename); GMX_THROW(InconsistentInputError(message)); } } /* compare md5 chksum */ - if (outputfile.checksumSize != -1 && - digest != outputfile.checksum) + if (outputfile.checksumSize != -1 && digest != outputfile.checksum) { if (debug) { @@ -391,10 +385,11 @@ void checkOutputFile(t_fileio *fileToCheck, } fprintf(debug, "\n"); } - auto message = - formatString("Checksum wrong for '%s'. The file has been replaced " - "or its contents have been modified. Cannot do appending " - "because of this condition.", outputfile.filename); + auto message = formatString( + "Checksum wrong for '%s'. The file has been replaced " + "or its contents have been modified. Cannot do appending " + "because of this condition.", + outputfile.filename); GMX_THROW(InconsistentInputError(message)); } } @@ -403,8 +398,7 @@ void checkOutputFile(t_fileio *fileToCheck, * * This wil prevent e.g. other mdrun instances from changing it while * we attempt to restart with appending. */ -void lockLogFile(t_fileio *logfio, - const char *logFilename) +void lockLogFile(t_fileio* logfio, const char* logFilename) { /* Note that there are systems where the lock operation * will succeed, but a second process can also lock the file. @@ -429,22 +423,22 @@ void lockLogFile(t_fileio *logfio, { if (errno == ENOSYS) { - std::string message = "File locking is not supported on this system. " - "Use mdrun -noappend to restart."; + std::string message = + "File locking is not supported on this system. " + "Use mdrun -noappend to restart."; GMX_THROW(FileIOError(message)); } else if (errno == EACCES || errno == EAGAIN) { - auto message = - formatString("Failed to lock: %s. Already running " - "simulation?", logFilename); + auto message = formatString( + "Failed to lock: %s. Already running " + "simulation?", + logFilename); GMX_THROW(FileIOError(message)); } else { - auto message = - formatString("Failed to lock: %s. %s.", - logFilename, std::strerror(errno)); + auto message = formatString("Failed to lock: %s. %s.", logFilename, std::strerror(errno)); GMX_THROW(FileIOError(message)); } } @@ -459,9 +453,7 @@ void lockLogFile(t_fileio *logfio, * (maybe important) files. The log file is locked so that we can * avoid cases where another mdrun instance might still be writing to * the file. */ -void -prepareForAppending(const ArrayRef outputFiles, - t_fileio *logfio) +void prepareForAppending(const ArrayRef outputFiles, t_fileio* logfio) { if (GMX_FAHCORE) { @@ -474,22 +466,20 @@ prepareForAppending(const ArrayRef outputFiles, // because we have already opened the log file. This ensures that // we retain a lock on the open file that is never lifted after // the checksum is calculated. - const gmx_file_position_t &logOutputFile = outputFiles[0]; + const gmx_file_position_t& logOutputFile = outputFiles[0]; lockLogFile(logfio, logOutputFile.filename); checkOutputFile(logfio, logOutputFile); if (gmx_fio_seek(logfio, logOutputFile.offset) != 0) { - auto message = - formatString("Seek error! Failed to truncate log file: %s.", - std::strerror(errno)); + auto message = formatString("Seek error! Failed to truncate log file: %s.", std::strerror(errno)); GMX_THROW(FileIOError(message)); } // Now handle the remaining outputFiles - for (const auto &outputFile : outputFiles.subArray(1, outputFiles.size()-1)) + for (const auto& outputFile : outputFiles.subArray(1, outputFiles.size() - 1)) { - t_fileio *fileToCheck = gmx_fio_open(outputFile.filename, "r+"); + t_fileio* fileToCheck = gmx_fio_open(outputFile.filename, "r+"); checkOutputFile(fileToCheck, outputFile); gmx_fio_close(fileToCheck); @@ -501,15 +491,16 @@ prepareForAppending(const ArrayRef outputFiles, if (gmx_truncate(outputFile.filename, outputFile.offset) != 0) { - auto message = - formatString("Truncation of file %s failed. Cannot do appending " - "because of this failure.", outputFile.filename); + auto message = formatString( + "Truncation of file %s failed. Cannot do appending " + "because of this failure.", + outputFile.filename); GMX_THROW(FileIOError(message)); } } } -void StartingBehaviorHandler::ensureMultiSimBehaviorsMatch(const gmx_multisim_t *ms) +void StartingBehaviorHandler::ensureMultiSimBehaviorsMatch(const gmx_multisim_t* ms) { if (!isMultiSim(ms)) { @@ -517,13 +508,15 @@ void StartingBehaviorHandler::ensureMultiSimBehaviorsMatch(const gmx_multisim_t return; } - auto startingBehaviors = gatherIntFromMultiSimulation(ms, static_cast(startingBehavior)); - bool identicalStartingBehaviors = (std::adjacent_find(std::begin(startingBehaviors), - std::end(startingBehaviors), - std::not_equal_to<>()) == std::end(startingBehaviors)); + auto startingBehaviors = gatherIntFromMultiSimulation(ms, static_cast(startingBehavior)); + bool identicalStartingBehaviors = + (std::adjacent_find(std::begin(startingBehaviors), std::end(startingBehaviors), + std::not_equal_to<>()) + == std::end(startingBehaviors)); - const EnumerationArray behaviorStrings = - { { "restart with appending", "restart without appending", "new simulation" } }; + const EnumerationArray behaviorStrings = { + { "restart with appending", "restart without appending", "new simulation" } + }; if (!identicalStartingBehaviors) { std::string message = formatString(R"( @@ -538,11 +531,13 @@ checkpoint file was written). To help you identify which directories need attention, the %d simulations wanted the following respective behaviors: -)", ms->nsim); +)", + ms->nsim); for (index simIndex = 0; simIndex != ssize(startingBehaviors); ++simIndex) { auto behavior = static_cast(startingBehaviors[simIndex]); - message += formatString(" Simulation %6zd: %s\n", simIndex, behaviorStrings[behavior].c_str()); + message += formatString(" Simulation %6zd: %s\n", simIndex, + behaviorStrings[behavior].c_str()); } GMX_THROW(InconsistentInputError(message)); } @@ -556,10 +551,10 @@ simulations wanted the following respective behaviors: // Multi-simulation restarts require that each checkpoint // describes the same simulation part. If those don't match, then // the simulation cannot proceed. - auto simulationParts = gatherIntFromMultiSimulation(ms, headerContents->simulation_part); + auto simulationParts = gatherIntFromMultiSimulation(ms, headerContents->simulation_part); bool identicalSimulationParts = (std::adjacent_find(std::begin(simulationParts), - std::end(simulationParts), - std::not_equal_to<>()) == std::end(simulationParts)); + std::end(simulationParts), std::not_equal_to<>()) + == std::end(simulationParts)); if (!identicalSimulationParts) { @@ -576,7 +571,8 @@ written). To help you identify which directories need attention, the %d simulation checkpoint files were from the following respective simulation parts: -)", ms->nsim); +)", + ms->nsim); for (index partIndex = 0; partIndex != ssize(simulationParts); ++partIndex) { message += formatString(" Simulation %6zd: %d\n", partIndex, simulationParts[partIndex]); @@ -585,8 +581,7 @@ simulation parts: } } -compat::optional -StartingBehaviorHandler::makeIndexOfNextPart(const AppendingBehavior appendingBehavior) const +compat::optional StartingBehaviorHandler::makeIndexOfNextPart(const AppendingBehavior appendingBehavior) const { compat::optional indexOfNextPart; @@ -594,8 +589,8 @@ StartingBehaviorHandler::makeIndexOfNextPart(const AppendingBehavior appendingBe { indexOfNextPart = headerContents->simulation_part + 1; } - else if (startingBehavior == StartingBehavior::NewSimulation && - appendingBehavior == AppendingBehavior::NoAppending) + else if (startingBehavior == StartingBehavior::NewSimulation + && appendingBehavior == AppendingBehavior::NoAppending) { indexOfNextPart = 1; } @@ -603,15 +598,14 @@ StartingBehaviorHandler::makeIndexOfNextPart(const AppendingBehavior appendingBe return indexOfNextPart; } -} // namespace +} // namespace -std::tuple -handleRestart(const bool isSimulationMaster, - MPI_Comm communicator, - const gmx_multisim_t *ms, - const AppendingBehavior appendingBehavior, - const int nfile, - t_filenm fnm[]) +std::tuple handleRestart(const bool isSimulationMaster, + MPI_Comm communicator, + const gmx_multisim_t* ms, + const AppendingBehavior appendingBehavior, + const int nfile, + t_filenm fnm[]) { StartingBehaviorHandler handler; LogFilePtr logFileGuard = nullptr; @@ -633,8 +627,7 @@ handleRestart(const bool isSimulationMaster, handler.ensureMultiSimBehaviorsMatch(ms); // When not appending, prepare a suffix for the part number - compat::optional indexOfNextPart - = handler.makeIndexOfNextPart(appendingBehavior); + compat::optional indexOfNextPart = handler.makeIndexOfNextPart(appendingBehavior); // If a part suffix is used, change the file names accordingly. if (indexOfNextPart) @@ -653,7 +646,7 @@ handleRestart(const bool isSimulationMaster, prepareForAppending(*handler.outputFiles, logFileGuard.get()); } } - catch (const std::exception & /*ex*/) + catch (const std::exception& /*ex*/) { exceptionPtr = std::current_exception(); numErrorsFound = 1; diff --git a/src/gromacs/mdrunutility/handlerestart.h b/src/gromacs/mdrunutility/handlerestart.h index 5eeb4799e2..7e586c6000 100644 --- a/src/gromacs/mdrunutility/handlerestart.h +++ b/src/gromacs/mdrunutility/handlerestart.h @@ -113,13 +113,12 @@ enum class StartingBehavior : int * \param[inout] fnm Filename parameters to mdrun * * \return Description of how mdrun is starting */ -std::tuple -handleRestart(bool isSimulationMaster, - MPI_Comm communicator, - const gmx_multisim_t *ms, - AppendingBehavior appendingBehavior, - int nfile, - t_filenm fnm[]); +std::tuple handleRestart(bool isSimulationMaster, + MPI_Comm communicator, + const gmx_multisim_t* ms, + AppendingBehavior appendingBehavior, + int nfile, + t_filenm fnm[]); } // namespace gmx diff --git a/src/gromacs/mdrunutility/logging.cpp b/src/gromacs/mdrunutility/logging.cpp index 612559e616..cb82dd8412 100644 --- a/src/gromacs/mdrunutility/logging.cpp +++ b/src/gromacs/mdrunutility/logging.cpp @@ -57,8 +57,7 @@ namespace gmx { //! Implements aspects of logfile handling common to opening either for writing or appending. -static void prepareLogFile(BinaryInformationSettings settings, - FILE *fplog) +static void prepareLogFile(BinaryInformationSettings settings, FILE* fplog) { GMX_RELEASE_ASSERT(fplog != nullptr, "Log file must be already open"); // TODO This function is writing initial content to the log @@ -69,21 +68,18 @@ static void prepareLogFile(BinaryInformationSettings settings, try { - settings - .extendedInfo(true) - .processId(true); + settings.extendedInfo(true).processId(true); printBinaryInformation(fplog, getProgramContext(), settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR fprintf(fplog, "\n"); fflush(fplog); } -LogFilePtr openLogFile(const char *lognm, - bool appendFiles) +LogFilePtr openLogFile(const char* lognm, bool appendFiles) { - const char *fileOpeningMode = "w+"; + const char* fileOpeningMode = "w+"; if (appendFiles) { fileOpeningMode = GMX_FAHCORE ? "a" : "r+"; @@ -99,7 +95,7 @@ LogFilePtr openLogFile(const char *lognm, // checksum has been computed. if (!appendFiles) { - FILE *fplog = gmx_fio_getfp(logfio.get()); + FILE* fplog = gmx_fio_getfp(logfio.get()); gmx::BinaryInformationSettings settings; settings.copyright(true); prepareLogFile(settings, fplog); @@ -107,7 +103,7 @@ LogFilePtr openLogFile(const char *lognm, return logfio; } -void prepareLogAppending(FILE *fplog) +void prepareLogAppending(FILE* fplog) { GMX_RELEASE_ASSERT(fplog != nullptr, "Log file must be already open"); fprintf(fplog, @@ -115,14 +111,13 @@ void prepareLogAppending(FILE *fplog) "\n" "-----------------------------------------------------------\n" "Restarting from checkpoint, appending to previous log file.\n" - "\n" - ); + "\n"); gmx::BinaryInformationSettings settings; settings.copyright(false); prepareLogFile(settings, fplog); } -void closeLogFile(t_fileio *logfio) +void closeLogFile(t_fileio* logfio) { if (logfio) { @@ -131,4 +126,4 @@ void closeLogFile(t_fileio *logfio) } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/mdrunutility/logging.h b/src/gromacs/mdrunutility/logging.h index 4535fd9a93..c0894aa99d 100644 --- a/src/gromacs/mdrunutility/logging.h +++ b/src/gromacs/mdrunutility/logging.h @@ -54,23 +54,22 @@ namespace gmx { /*! \brief Close the log file */ -void closeLogFile(t_fileio *logfio); +void closeLogFile(t_fileio* logfio); //! Simple guard pointer See unique_cptr for details. -using LogFilePtr = std::unique_ptr < t_fileio, functor_wrapper < t_fileio, closeLogFile>>; +using LogFilePtr = std::unique_ptr>; /*! \brief Open the log file for writing/appending. * * \throws FileIOError when the log file cannot be opened. */ -LogFilePtr openLogFile(const char *lognm, - bool appendFiles); +LogFilePtr openLogFile(const char* lognm, bool appendFiles); /*! \brief Prepare to use the open log file when appending. * * Does not throw. */ -void prepareLogAppending(FILE *fplog); +void prepareLogAppending(FILE* fplog); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdrunutility/multisim.cpp b/src/gromacs/mdrunutility/multisim.cpp index 0171f0befd..597277dec6 100644 --- a/src/gromacs/mdrunutility/multisim.cpp +++ b/src/gromacs/mdrunutility/multisim.cpp @@ -54,8 +54,7 @@ gmx_multisim_t::gmx_multisim_t() = default; -gmx_multisim_t::gmx_multisim_t(MPI_Comm comm, - gmx::ArrayRef multidirs) +gmx_multisim_t::gmx_multisim_t(MPI_Comm comm, gmx::ArrayRef multidirs) { if (multidirs.empty()) { @@ -64,14 +63,16 @@ gmx_multisim_t::gmx_multisim_t(MPI_Comm comm, if (!GMX_LIB_MPI && !multidirs.empty()) { - gmx_fatal(FARGS, "mdrun -multidir is only supported when GROMACS has been " + gmx_fatal(FARGS, + "mdrun -multidir is only supported when GROMACS has been " "configured with a proper external MPI library."); } if (multidirs.size() == 1) { /* NOTE: It would be nice if this special case worked, but this requires checks/tests. */ - gmx_fatal(FARGS, "To run mdrun in multiple simulation mode, more then one " + gmx_fatal(FARGS, + "To run mdrun in multiple simulation mode, more then one " "actual simulation is required. The single simulation case is not supported."); } @@ -80,33 +81,35 @@ gmx_multisim_t::gmx_multisim_t(MPI_Comm comm, MPI_Comm_size(comm, &numRanks); if (numRanks % multidirs.size() != 0) { - gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%td)", numRanks, multidirs.ssize()); + gmx_fatal(FARGS, + "The number of ranks (%d) is not a multiple of the number of simulations (%td)", + numRanks, multidirs.ssize()); } - int numRanksPerSim = numRanks/multidirs.size(); + int numRanksPerSim = numRanks / multidirs.size(); int rankWithinComm; MPI_Comm_rank(comm, &rankWithinComm); if (debug) { - fprintf(debug, "We have %td simulations, %d ranks per simulation, local simulation is %d\n", multidirs.ssize(), numRanksPerSim, rankWithinComm/numRanksPerSim); + fprintf(debug, "We have %td simulations, %d ranks per simulation, local simulation is %d\n", + multidirs.ssize(), numRanksPerSim, rankWithinComm / numRanksPerSim); } nsim = multidirs.size(); - sim = rankWithinComm/numRanksPerSim; + sim = rankWithinComm / numRanksPerSim; /* Create a communicator for the master nodes */ std::vector rank(nsim); for (int i = 0; i < nsim; i++) { - rank[i] = i*numRanksPerSim; + rank[i] = i * numRanksPerSim; } MPI_Group mpi_group_world; MPI_Comm_group(comm, &mpi_group_world); MPI_Group_incl(mpi_group_world, nsim, rank.data(), &mpi_group_masters); - MPI_Comm_create(comm, mpi_group_masters, - &mpi_comm_masters); + MPI_Comm_create(comm, mpi_group_masters, &mpi_comm_masters); -#if !MPI_IN_PLACE_EXISTS +# if !MPI_IN_PLACE_EXISTS /* initialize the MPI_IN_PLACE replacement buffers */ snew(mpb, 1); mpb->ibuf = nullptr; @@ -117,7 +120,7 @@ gmx_multisim_t::gmx_multisim_t(MPI_Comm comm, mpb->libuf_alloc = 0; mpb->fbuf_alloc = 0; mpb->dbuf_alloc = 0; -#endif +# endif // TODO This should throw upon error gmx_chdir(multidirs[sim].c_str()); @@ -133,8 +136,7 @@ gmx_multisim_t::~gmx_multisim_t() #if GMX_MPI // TODO This would work better if the result of MPI_Comm_split was // put into an RAII-style guard, such as gmx::unique_cptr. - if (mpi_comm_masters != MPI_COMM_NULL && - mpi_comm_masters != MPI_COMM_WORLD) + if (mpi_comm_masters != MPI_COMM_NULL && mpi_comm_masters != MPI_COMM_WORLD) { MPI_Comm_free(&mpi_comm_masters); } @@ -148,13 +150,13 @@ gmx_multisim_t::~gmx_multisim_t() #if GMX_MPI static void gmx_sumd_comm(int nr, double r[], MPI_Comm mpi_comm) { -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_DOUBLE, MPI_SUM, mpi_comm); -#else +# else /* this function is only used in code that is not performance critical, (during setup, when comm_rec is not the appropriate communication structure), so this isn't as bad as it looks. */ - double *buf; + double* buf; int i; snew(buf, nr); @@ -164,20 +166,20 @@ static void gmx_sumd_comm(int nr, double r[], MPI_Comm mpi_comm) r[i] = buf[i]; } sfree(buf); -#endif +# endif } #endif #if GMX_MPI static void gmx_sumf_comm(int nr, float r[], MPI_Comm mpi_comm) { -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_FLOAT, MPI_SUM, mpi_comm); -#else +# else /* this function is only used in code that is not performance critical, (during setup, when comm_rec is not the appropriate communication structure), so this isn't as bad as it looks. */ - float *buf; + float* buf; int i; snew(buf, nr); @@ -187,11 +189,11 @@ static void gmx_sumf_comm(int nr, float r[], MPI_Comm mpi_comm) r[i] = buf[i]; } sfree(buf); -#endif +# endif } #endif -void gmx_sumd_sim(int gmx_unused nr, double gmx_unused r[], const gmx_multisim_t gmx_unused *ms) +void gmx_sumd_sim(int gmx_unused nr, double gmx_unused r[], const gmx_multisim_t gmx_unused* ms) { #if !GMX_MPI gmx_call("gmx_sumd_sim"); @@ -200,7 +202,7 @@ void gmx_sumd_sim(int gmx_unused nr, double gmx_unused r[], const gmx_multisim_t #endif } -void gmx_sumf_sim(int gmx_unused nr, float gmx_unused r[], const gmx_multisim_t gmx_unused *ms) +void gmx_sumf_sim(int gmx_unused nr, float gmx_unused r[], const gmx_multisim_t gmx_unused* ms) { #if !GMX_MPI gmx_call("gmx_sumf_sim"); @@ -209,14 +211,14 @@ void gmx_sumf_sim(int gmx_unused nr, float gmx_unused r[], const gmx_multisim_t #endif } -void gmx_sumi_sim(int gmx_unused nr, int gmx_unused r[], const gmx_multisim_t gmx_unused *ms) +void gmx_sumi_sim(int gmx_unused nr, int gmx_unused r[], const gmx_multisim_t gmx_unused* ms) { #if !GMX_MPI gmx_call("gmx_sumi_sim"); #else -#if MPI_IN_PLACE_EXISTS +# if MPI_IN_PLACE_EXISTS MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT, MPI_SUM, ms->mpi_comm_masters); -#else +# else /* this is thread-unsafe, but it will do for now: */ int i; @@ -230,19 +232,18 @@ void gmx_sumi_sim(int gmx_unused nr, int gmx_unused r[], const gmx_multisim_t gm { r[i] = ms->mpb->ibuf[i]; } -#endif +# endif #endif } -void gmx_sumli_sim(int gmx_unused nr, int64_t gmx_unused r[], const gmx_multisim_t gmx_unused *ms) +void gmx_sumli_sim(int gmx_unused nr, int64_t gmx_unused r[], const gmx_multisim_t gmx_unused* ms) { #if !GMX_MPI gmx_call("gmx_sumli_sim"); #else -#if MPI_IN_PLACE_EXISTS - MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, - ms->mpi_comm_masters); -#else +# if MPI_IN_PLACE_EXISTS + MPI_Allreduce(MPI_IN_PLACE, r, nr, MPI_INT64_T, MPI_SUM, ms->mpi_comm_masters); +# else /* this is thread-unsafe, but it will do for now: */ int i; @@ -251,18 +252,16 @@ void gmx_sumli_sim(int gmx_unused nr, int64_t gmx_unused r[], const gmx_multisim ms->mpb->libuf_alloc = nr; srenew(ms->mpb->libuf, ms->mpb->libuf_alloc); } - MPI_Allreduce(r, ms->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, - ms->mpi_comm_masters); + MPI_Allreduce(r, ms->mpb->libuf, nr, MPI_INT64_T, MPI_SUM, ms->mpi_comm_masters); for (i = 0; i < nr; i++) { r[i] = ms->mpb->libuf[i]; } -#endif +# endif #endif } -std::vector gatherIntFromMultiSimulation(const gmx_multisim_t *ms, - const int localValue) +std::vector gatherIntFromMultiSimulation(const gmx_multisim_t* ms, const int localValue) { std::vector valuesFromAllRanks; if (GMX_MPI && ms != nullptr) @@ -278,11 +277,9 @@ std::vector gatherIntFromMultiSimulation(const gmx_multisim_t *ms, return valuesFromAllRanks; } -void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val, - const char *name, - gmx_bool bQuiet) +void check_multi_int(FILE* log, const gmx_multisim_t* ms, int val, const char* name, gmx_bool bQuiet) { - int *ibuf, p; + int * ibuf, p; gmx_bool bCompatible; if (nullptr != log && !bQuiet) @@ -292,8 +289,7 @@ void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val, if (ms == nullptr) { - gmx_fatal(FARGS, - "check_multi_int called with a NULL communication pointer"); + gmx_fatal(FARGS, "check_multi_int called with a NULL communication pointer"); } snew(ibuf, ms->nsim); @@ -303,7 +299,7 @@ void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val, bCompatible = TRUE; for (p = 1; p < ms->nsim; p++) { - bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]); + bCompatible = bCompatible && (ibuf[p - 1] == ibuf[p]); } if (bCompatible) @@ -329,13 +325,11 @@ void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val, sfree(ibuf); } -void check_multi_int64(FILE *log, const gmx_multisim_t *ms, - int64_t val, const char *name, - gmx_bool bQuiet) +void check_multi_int64(FILE* log, const gmx_multisim_t* ms, int64_t val, const char* name, gmx_bool bQuiet) { - int64_t *ibuf; - int p; - gmx_bool bCompatible; + int64_t* ibuf; + int p; + gmx_bool bCompatible; if (nullptr != log && !bQuiet) { @@ -344,8 +338,7 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms, if (ms == nullptr) { - gmx_fatal(FARGS, - "check_multi_int called with a NULL communication pointer"); + gmx_fatal(FARGS, "check_multi_int called with a NULL communication pointer"); } snew(ibuf, ms->nsim); @@ -355,7 +348,7 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms, bCompatible = TRUE; for (p = 1; p < ms->nsim; p++) { - bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]); + bCompatible = bCompatible && (ibuf[p - 1] == ibuf[p]); } if (bCompatible) @@ -376,8 +369,7 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms, { char strbuf[255]; /* first make the format string */ - snprintf(strbuf, 255, " subsystem %%d: %s\n", - "%" PRId64); + snprintf(strbuf, 255, " subsystem %%d: %s\n", "%" PRId64); fprintf(log, strbuf, p, ibuf[p]); } } @@ -387,8 +379,7 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms, sfree(ibuf); } -bool findIsSimulationMasterRank(const gmx_multisim_t *ms, - MPI_Comm communicator) +bool findIsSimulationMasterRank(const gmx_multisim_t* ms, MPI_Comm communicator) { if (GMX_LIB_MPI) { @@ -410,8 +401,8 @@ bool findIsSimulationMasterRank(const gmx_multisim_t *ms, } else if (GMX_THREAD_MPI) { - GMX_RELEASE_ASSERT(communicator == MPI_COMM_NULL || - communicator == MPI_COMM_WORLD, "Invalid communicator"); + GMX_RELEASE_ASSERT(communicator == MPI_COMM_NULL || communicator == MPI_COMM_WORLD, + "Invalid communicator"); // Spawned threads have MPI_COMM_WORLD upon creation, so if // the communicator is MPI_COMM_NULL this is not a spawned thread, // ie is the master thread @@ -427,18 +418,17 @@ bool findIsSimulationMasterRank(const gmx_multisim_t *ms, return true; } -bool isMasterSim(const gmx_multisim_t *ms) +bool isMasterSim(const gmx_multisim_t* ms) { return !isMultiSim(ms) || ms->sim == 0; } -bool isMasterSimMasterRank(const gmx_multisim_t *ms, - const bool isMaster) +bool isMasterSimMasterRank(const gmx_multisim_t* ms, const bool isMaster) { return (isMaster && isMasterSim(ms)); } -void multiSimBarrier(const gmx_multisim_t *ms) +void multiSimBarrier(const gmx_multisim_t* ms) { if (isMultiSim(ms)) { diff --git a/src/gromacs/mdrunutility/multisim.h b/src/gromacs/mdrunutility/multisim.h index e4be0dffdf..cde06c2ae2 100644 --- a/src/gromacs/mdrunutility/multisim.h +++ b/src/gromacs/mdrunutility/multisim.h @@ -67,39 +67,37 @@ struct gmx_multisim_t * * Valid to call regardless of build configuration, but \c * multidirs must be empty unless a real MPI build is used. */ - gmx_multisim_t(MPI_Comm comm, - gmx::ArrayRef multidirs); + gmx_multisim_t(MPI_Comm comm, gmx::ArrayRef multidirs); //! Destructor ~gmx_multisim_t(); //! The number of simulations in the set of multi-simulations - int nsim = 1; + int nsim = 1; //! The index of the simulation that owns this object within the set - int sim = 0; + int sim = 0; //! The MPI Group between master ranks of simulations, valid only on master ranks. - MPI_Group mpi_group_masters = MPI_GROUP_NULL; + MPI_Group mpi_group_masters = MPI_GROUP_NULL; //! The MPI communicator between master ranks of simulations, valid only on master ranks. - MPI_Comm mpi_comm_masters = MPI_COMM_NULL; + MPI_Comm mpi_comm_masters = MPI_COMM_NULL; //! Communication buffers needed if MPI_IN_PLACE isn't supported - mpi_in_place_buf_t * mpb = nullptr; + mpi_in_place_buf_t* mpb = nullptr; }; //! Calculate the sum over the simulations of an array of ints -void gmx_sumi_sim(int nr, int r[], const gmx_multisim_t *ms); +void gmx_sumi_sim(int nr, int r[], const gmx_multisim_t* ms); //! Calculate the sum over the simulations of an array of large ints -void gmx_sumli_sim(int nr, int64_t r[], const gmx_multisim_t *ms); +void gmx_sumli_sim(int nr, int64_t r[], const gmx_multisim_t* ms); //! Calculate the sum over the simulations of an array of floats -void gmx_sumf_sim(int nr, float r[], const gmx_multisim_t *ms); +void gmx_sumf_sim(int nr, float r[], const gmx_multisim_t* ms); //! Calculate the sum over the simulations of an array of doubles -void gmx_sumd_sim(int nr, double r[], const gmx_multisim_t *ms); +void gmx_sumd_sim(int nr, double r[], const gmx_multisim_t* ms); /*! \brief Return a vector containing the gathered values of \c * localValue found on the master rank of each simulation. */ -std::vector gatherIntFromMultiSimulation(const gmx_multisim_t *ms, - int localValue); +std::vector gatherIntFromMultiSimulation(const gmx_multisim_t* ms, int localValue); /*! \brief Check if val is the same on all simulations for a mdrun * -multidir run @@ -107,24 +105,20 @@ std::vector gatherIntFromMultiSimulation(const gmx_multisim_t *ms, * The string name is used to print to the log file and in a fatal error * if the val's don't match. If bQuiet is true and the check passes, * no output is written. */ -void check_multi_int(FILE *log, const gmx_multisim_t *ms, - int val, const char *name, - gmx_bool bQuiet); +void check_multi_int(FILE* log, const gmx_multisim_t* ms, int val, const char* name, gmx_bool bQuiet); /*! \copydoc check_multi_int() */ -void check_multi_int64(FILE *log, const gmx_multisim_t *ms, - int64_t val, const char *name, - gmx_bool bQuiet); +void check_multi_int64(FILE* log, const gmx_multisim_t* ms, int64_t val, const char* name, gmx_bool bQuiet); #if GMX_DOUBLE //! Convenience define for sum of reals -#define gmx_sum_sim gmx_sumd_sim +# define gmx_sum_sim gmx_sumd_sim #else //! Convenience define for sum of reals -#define gmx_sum_sim gmx_sumf_sim +# define gmx_sum_sim gmx_sumf_sim #endif //! Are we doing multiple independent simulations? -static bool inline isMultiSim(const gmx_multisim_t *ms) +static bool inline isMultiSim(const gmx_multisim_t* ms) { return ms != nullptr; } @@ -132,19 +126,17 @@ static bool inline isMultiSim(const gmx_multisim_t *ms) /*! \brief Return whether this rank is the master rank of a * simulation, using \c ms (if it is valid) and otherwise \c * communicator */ -bool findIsSimulationMasterRank(const gmx_multisim_t *ms, - MPI_Comm communicator); +bool findIsSimulationMasterRank(const gmx_multisim_t* ms, MPI_Comm communicator); //! Are we the master simulation of a possible multi-simulation? -bool isMasterSim(const gmx_multisim_t *ms); +bool isMasterSim(const gmx_multisim_t* ms); /*! \brief Are we the master rank (of the master simulation, for a multi-sim). * * This rank prints the remaining run time etc. */ -bool isMasterSimMasterRank(const gmx_multisim_t *ms, - bool isMaster); +bool isMasterSimMasterRank(const gmx_multisim_t* ms, bool isMaster); //! Make a barrier across all multi-simulation master ranks -void multiSimBarrier(const gmx_multisim_t *ms); +void multiSimBarrier(const gmx_multisim_t* ms); #endif diff --git a/src/gromacs/mdrunutility/printtime.cpp b/src/gromacs/mdrunutility/printtime.cpp index deff0d91c5..138d012059 100644 --- a/src/gromacs/mdrunutility/printtime.cpp +++ b/src/gromacs/mdrunutility/printtime.cpp @@ -47,11 +47,11 @@ #include "gromacs/utility/strconvert.h" #include "gromacs/utility/sysinfo.h" -void print_time(FILE *out, +void print_time(FILE* out, gmx_walltime_accounting_t walltime_accounting, int64_t step, - const t_inputrec *ir, - const t_commrec *cr) + const t_inputrec* ir, + const t_commrec* cr) { time_t finish; double dt, elapsed_seconds, time_per_step; @@ -69,15 +69,16 @@ void print_time(FILE *out, if ((step >= ir->nstlist)) { double seconds_since_epoch = gmx_gettime(); - elapsed_seconds = seconds_since_epoch - walltime_accounting_get_start_time_stamp(walltime_accounting); - time_per_step = elapsed_seconds/(step - ir->init_step + 1); - dt = (ir->nsteps + ir->init_step - step) * time_per_step; + elapsed_seconds = + seconds_since_epoch - walltime_accounting_get_start_time_stamp(walltime_accounting); + time_per_step = elapsed_seconds / (step - ir->init_step + 1); + dt = (ir->nsteps + ir->init_step - step) * time_per_step; if (ir->nsteps >= 0) { if (dt >= 300) { - finish = static_cast(seconds_since_epoch + dt); + finish = static_cast(seconds_since_epoch + dt); auto timebuf = gmx_ctime_r(&finish); timebuf.erase(timebuf.find_first_of('\n')); fputs(", will finish ", out); @@ -90,8 +91,7 @@ void print_time(FILE *out, } else { - fprintf(out, " performance: %.1f ns/day ", - ir->delta_t/1000*24*60*60/time_per_step); + fprintf(out, " performance: %.1f ns/day ", ir->delta_t / 1000 * 24 * 60 * 60 / time_per_step); } } #if !GMX_THREAD_MPI @@ -106,8 +106,7 @@ void print_time(FILE *out, fflush(out); } -void print_date_and_time(FILE *fplog, int nodeid, const char *title, - double the_time) +void print_date_and_time(FILE* fplog, int nodeid, const char* title, double the_time) { if (!fplog) { @@ -116,14 +115,12 @@ void print_date_and_time(FILE *fplog, int nodeid, const char *title, time_t temp_time = static_cast(the_time); - auto timebuf = gmx_ctime_r(&temp_time); + auto timebuf = gmx_ctime_r(&temp_time); fprintf(fplog, "%s on rank %d %s\n", title, nodeid, timebuf.c_str()); } -void print_start(FILE *fplog, const t_commrec *cr, - gmx_walltime_accounting_t walltime_accounting, - const char *name) +void print_start(FILE* fplog, const t_commrec* cr, gmx_walltime_accounting_t walltime_accounting, const char* name) { char buf[STRLEN]; diff --git a/src/gromacs/mdrunutility/printtime.h b/src/gromacs/mdrunutility/printtime.h index 0b792e2401..52caa9e506 100644 --- a/src/gromacs/mdrunutility/printtime.h +++ b/src/gromacs/mdrunutility/printtime.h @@ -51,8 +51,11 @@ struct t_commrec; struct t_inputrec; //! Print time to \c out. -void print_time(FILE *out, gmx_walltime_accounting *walltime_accounting, - int64_t step, const t_inputrec *ir, const t_commrec *cr); +void print_time(FILE* out, + gmx_walltime_accounting* walltime_accounting, + int64_t step, + const t_inputrec* ir, + const t_commrec* cr); /*! \brief Print date, time, MPI rank and a description of this point * in time. @@ -62,12 +65,9 @@ void print_time(FILE *out, gmx_walltime_accounting *walltime_accounting, * \param[in] title Description to include in the output * \param[in] the_time Seconds since the epoch, e.g. as reported by gmx_gettime */ -void print_date_and_time(FILE *log, int rank, const char *title, - double the_time); +void print_date_and_time(FILE* log, int rank, const char* title, double the_time); //! Print start time to \c fplog. -void print_start(FILE *fplog, const t_commrec *cr, - gmx_walltime_accounting *walltime_accounting, - const char *name); +void print_start(FILE* fplog, const t_commrec* cr, gmx_walltime_accounting* walltime_accounting, const char* name); #endif diff --git a/src/gromacs/mdrunutility/tests/threadaffinity.cpp b/src/gromacs/mdrunutility/tests/threadaffinity.cpp index 7ee3f3d21b..a4424beac7 100644 --- a/src/gromacs/mdrunutility/tests/threadaffinity.cpp +++ b/src/gromacs/mdrunutility/tests/threadaffinity.cpp @@ -47,9 +47,8 @@ namespace class ThreadAffinityTest : public ::testing::Test { - public: - - gmx::test::ThreadAffinityTestHelper helper_; +public: + gmx::test::ThreadAffinityTestHelper helper_; }; TEST_F(ThreadAffinityTest, DoesNothingWhenDisabled) @@ -165,7 +164,7 @@ TEST_F(ThreadAffinityTest, PinsMultipleThreadsWithAuto) { helper_.setLogicalProcessorCount(2); helper_.expectPinningMessage(false, 1); - helper_.expectAffinitySet({0, 1}); + helper_.expectAffinitySet({ 0, 1 }); helper_.setAffinity(2); } @@ -175,7 +174,7 @@ TEST_F(ThreadAffinityTest, PinsMultipleThreadsWithStrideWhenForced) helper_.setOffsetAndStride(0, 2); helper_.setLogicalProcessorCount(4); helper_.expectPinningMessage(true, 2); - helper_.expectAffinitySet({0, 2}); + helper_.expectAffinitySet({ 0, 2 }); helper_.setAffinity(2); } @@ -184,7 +183,7 @@ TEST_F(ThreadAffinityTest, PinsWithAutoAndFewerAutoSetThreads) helper_.setLogicalProcessorCount(4); helper_.setTotNumThreadsIsAuto(true); helper_.expectPinningMessage(false, 2); - helper_.expectAffinitySet({0, 2}); + helper_.expectAffinitySet({ 0, 2 }); helper_.setAffinity(2); } diff --git a/src/gromacs/mdrunutility/tests/threadaffinity_mpi.cpp b/src/gromacs/mdrunutility/tests/threadaffinity_mpi.cpp index 421a06bfce..bc72cfaaed 100644 --- a/src/gromacs/mdrunutility/tests/threadaffinity_mpi.cpp +++ b/src/gromacs/mdrunutility/tests/threadaffinity_mpi.cpp @@ -68,7 +68,7 @@ TEST(ThreadAffinityMultiRankTest, PinsWithOffsetAndStride) helper.setLogicalProcessorCount(8); helper.expectWarningMatchingRegex("Applying core pinning offset 1"); helper.expectPinningMessage(true, 2); - helper.expectAffinitySet(1 + 2*gmx_node_rank()); + helper.expectAffinitySet(1 + 2 * gmx_node_rank()); helper.setAffinity(1); } @@ -76,10 +76,10 @@ TEST(ThreadAffinityMultiRankTest, PinsTwoNodes) { GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; - helper.setPhysicalNodeId(gmx_node_rank()/2); + helper.setPhysicalNodeId(gmx_node_rank() / 2); helper.setLogicalProcessorCount(2); helper.expectPinningMessage(false, 1); - helper.expectAffinitySet(gmx_node_rank()%2); + helper.expectAffinitySet(gmx_node_rank() % 2); helper.setAffinity(1); } @@ -113,24 +113,24 @@ TEST(ThreadAffinityMultiRankTest, HandlesTooManyThreadsWithForce) class ThreadAffinityHeterogeneousNodesTest : public ::testing::Test { - public: - int currentNode() const { return gmx_node_rank() / 2; } - int indexInNode() const { return gmx_node_rank() % 2; } - bool isMaster() const { return gmx_node_rank() == 0; } +public: + int currentNode() const { return gmx_node_rank() / 2; } + int indexInNode() const { return gmx_node_rank() % 2; } + bool isMaster() const { return gmx_node_rank() == 0; } - void setupNodes(ThreadAffinityTestHelper *helper, std::array cores) - { - const int node = currentNode(); - helper->setPhysicalNodeId(node); - helper->setLogicalProcessorCount(cores[node]); - } - void expectNodeAffinitySet(ThreadAffinityTestHelper *helper, int node, int core) + void setupNodes(ThreadAffinityTestHelper* helper, std::array cores) + { + const int node = currentNode(); + helper->setPhysicalNodeId(node); + helper->setLogicalProcessorCount(cores[node]); + } + void expectNodeAffinitySet(ThreadAffinityTestHelper* helper, int node, int core) + { + if (currentNode() == node) { - if (currentNode() == node) - { - helper->expectAffinitySet(core); - } + helper->expectAffinitySet(core); } + } }; TEST_F(ThreadAffinityHeterogeneousNodesTest, PinsOnMasterOnly) @@ -138,7 +138,7 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, PinsOnMasterOnly) GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; helper.setAffinityOption(ThreadAffinity::On); - setupNodes(&helper, {{2, 1}}); + setupNodes(&helper, { { 2, 1 } }); helper.expectWarningMatchingRegexIf("Oversubscribing the CPU", isMaster() || currentNode() == 1); if (currentNode() == 0) { @@ -153,7 +153,7 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, PinsOnNonMasterOnly) GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; helper.setAffinityOption(ThreadAffinity::On); - setupNodes(&helper, {{1, 2}}); + setupNodes(&helper, { { 1, 2 } }); helper.expectWarningMatchingRegexIf("Oversubscribing the CPU", currentNode() == 0); if (currentNode() == 1) { @@ -168,8 +168,9 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, HandlesUnknownHardwareOnNonMaster) GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; helper.setAffinityOption(ThreadAffinity::On); - setupNodes(&helper, {{2, 0}}); - helper.expectWarningMatchingRegexIf("No information on available cores", isMaster() || currentNode() == 1); + setupNodes(&helper, { { 2, 0 } }); + helper.expectWarningMatchingRegexIf("No information on available cores", + isMaster() || currentNode() == 1); if (currentNode() == 0) { helper.expectPinningMessage(false, 1); @@ -182,7 +183,7 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, PinsAutomaticallyOnMasterOnly) { GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; - setupNodes(&helper, {{2, 1}}); + setupNodes(&helper, { { 2, 1 } }); helper.expectWarningMatchingRegexIf("Oversubscribing the CPU", isMaster() || currentNode() == 1); if (currentNode() == 0) { @@ -196,7 +197,7 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, PinsAutomaticallyOnNonMasterOnly) { GMX_MPI_TEST(4); ThreadAffinityTestHelper helper; - setupNodes(&helper, {{1, 2}}); + setupNodes(&helper, { { 1, 2 } }); helper.expectWarningMatchingRegexIf("Oversubscribing the CPU", currentNode() == 0); if (currentNode() == 1) { @@ -212,14 +213,14 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, HandlesInvalidOffsetOnNonMasterOnly ThreadAffinityTestHelper helper; helper.setAffinityOption(ThreadAffinity::On); helper.setOffsetAndStride(2, 0); - setupNodes(&helper, {{4, 2}}); + setupNodes(&helper, { { 4, 2 } }); helper.expectWarningMatchingRegex("Applying core pinning offset 2"); helper.expectWarningMatchingRegexIf("Requested offset too large", isMaster() || currentNode() == 1); if (currentNode() == 0) { helper.expectPinningMessage(false, 1); } - expectNodeAffinitySet(&helper, 0, indexInNode()+2); + expectNodeAffinitySet(&helper, 0, indexInNode() + 2); helper.setAffinity(1); } @@ -229,13 +230,13 @@ TEST_F(ThreadAffinityHeterogeneousNodesTest, HandlesInvalidStrideOnNonMasterOnly ThreadAffinityTestHelper helper; helper.setAffinityOption(ThreadAffinity::On); helper.setOffsetAndStride(0, 2); - setupNodes(&helper, {{4, 2}}); + setupNodes(&helper, { { 4, 2 } }); helper.expectWarningMatchingRegexIf("Requested stride too large", isMaster() || currentNode() == 1); if (currentNode() == 0) { helper.expectPinningMessage(true, 2); } - expectNodeAffinitySet(&helper, 0, 2*indexInNode()); + expectNodeAffinitySet(&helper, 0, 2 * indexInNode()); helper.setAffinity(1); } diff --git a/src/gromacs/mdrunutility/tests/threadaffinitytest.cpp b/src/gromacs/mdrunutility/tests/threadaffinitytest.cpp index 49965e17ce..429ac458f3 100644 --- a/src/gromacs/mdrunutility/tests/threadaffinitytest.cpp +++ b/src/gromacs/mdrunutility/tests/threadaffinitytest.cpp @@ -53,28 +53,24 @@ namespace gmx namespace test { -MockThreadAffinityAccess::MockThreadAffinityAccess() - : supported_(true) +MockThreadAffinityAccess::MockThreadAffinityAccess() : supported_(true) { using ::testing::_; using ::testing::Return; #ifndef __clang_analyzer__ - ON_CALL(*this, setCurrentThreadAffinityToCore(_)) - .WillByDefault(Return(true)); + ON_CALL(*this, setCurrentThreadAffinityToCore(_)).WillByDefault(Return(true)); #endif } -MockThreadAffinityAccess::~MockThreadAffinityAccess() -{ -} +MockThreadAffinityAccess::~MockThreadAffinityAccess() {} ThreadAffinityTestHelper::ThreadAffinityTestHelper() { snew(cr_, 1); - cr_->nnodes = gmx_node_num(); - cr_->nodeid = gmx_node_rank(); - cr_->duty = DUTY_PP; + cr_->nnodes = gmx_node_num(); + cr_->nodeid = gmx_node_rank(); + cr_->duty = DUTY_PP; #if GMX_MPI cr_->mpi_comm_mysim = MPI_COMM_WORLD; #endif diff --git a/src/gromacs/mdrunutility/tests/threadaffinitytest.h b/src/gromacs/mdrunutility/tests/threadaffinitytest.h index 501e2a8ee8..6720e7a682 100644 --- a/src/gromacs/mdrunutility/tests/threadaffinitytest.h +++ b/src/gromacs/mdrunutility/tests/threadaffinitytest.h @@ -61,137 +61,114 @@ namespace test class MockThreadAffinityAccess : public IThreadAffinityAccess { - public: - MockThreadAffinityAccess(); - ~MockThreadAffinityAccess() override; +public: + MockThreadAffinityAccess(); + ~MockThreadAffinityAccess() override; - void setSupported(bool supported) { supported_ = supported; } + void setSupported(bool supported) { supported_ = supported; } - bool isThreadAffinitySupported() const override { return supported_; } - MOCK_METHOD1(setCurrentThreadAffinityToCore, bool(int core)); + bool isThreadAffinitySupported() const override { return supported_; } + MOCK_METHOD1(setCurrentThreadAffinityToCore, bool(int core)); - private: - bool supported_; +private: + bool supported_; }; class ThreadAffinityTestHelper { - public: - ThreadAffinityTestHelper(); - ~ThreadAffinityTestHelper(); - - void setAffinitySupported(bool supported) - { - affinityAccess_.setSupported(supported); - } - void setAffinityOption(ThreadAffinity affinityOption) - { - hwOpt_.threadAffinity = affinityOption; - } - void setOffsetAndStride(int offset, int stride) - { - hwOpt_.core_pinning_offset = offset; - hwOpt_.core_pinning_stride = stride; - } - - void setPhysicalNodeId(int nodeId) - { - physicalNodeId_ = nodeId; - } - - void setLogicalProcessorCount(int logicalProcessorCount); - - void setTotNumThreadsIsAuto(bool isAuto) - { - hwOpt_.totNumThreadsIsAuto = isAuto; - } - - void expectAffinitySet(int core) - { - EXPECT_CALL(affinityAccess_, setCurrentThreadAffinityToCore(core)); - } - void expectAffinitySet(std::initializer_list cores) - { - for (int core : cores) - { - expectAffinitySet(core); - } - } - void expectAffinitySetThatFails(int core) - { - using ::testing::Return; +public: + ThreadAffinityTestHelper(); + ~ThreadAffinityTestHelper(); + + void setAffinitySupported(bool supported) { affinityAccess_.setSupported(supported); } + void setAffinityOption(ThreadAffinity affinityOption) + { + hwOpt_.threadAffinity = affinityOption; + } + void setOffsetAndStride(int offset, int stride) + { + hwOpt_.core_pinning_offset = offset; + hwOpt_.core_pinning_stride = stride; + } + + void setPhysicalNodeId(int nodeId) { physicalNodeId_ = nodeId; } + + void setLogicalProcessorCount(int logicalProcessorCount); + + void setTotNumThreadsIsAuto(bool isAuto) { hwOpt_.totNumThreadsIsAuto = isAuto; } + + void expectAffinitySet(int core) + { + EXPECT_CALL(affinityAccess_, setCurrentThreadAffinityToCore(core)); + } + void expectAffinitySet(std::initializer_list cores) + { + for (int core : cores) + { + expectAffinitySet(core); + } + } + void expectAffinitySetThatFails(int core) + { + using ::testing::Return; #ifndef __clang_analyzer__ - EXPECT_CALL(affinityAccess_, setCurrentThreadAffinityToCore(core)) - .WillOnce(Return(false)); + EXPECT_CALL(affinityAccess_, setCurrentThreadAffinityToCore(core)).WillOnce(Return(false)); #else - GMX_UNUSED_VALUE(core); + GMX_UNUSED_VALUE(core); #endif - } - - void expectWarningMatchingRegex(const char *re) - { - expectWarningMatchingRegexIf(re, true); - } - void expectWarningMatchingRegexIf(const char *re, bool condition) - { - expectLogMessageMatchingRegexIf(MDLogger::LogLevel::Warning, re, condition); - } - void expectInfoMatchingRegex(const char *re) - { - expectInfoMatchingRegexIf(re, true); - } - void expectInfoMatchingRegexIf(const char *re, bool condition) - { - expectLogMessageMatchingRegexIf(MDLogger::LogLevel::Info, re, condition); - } - void expectGenericFailureMessage() - { - expectGenericFailureMessageIf(true); - } - void expectGenericFailureMessageIf(bool condition) - { - expectWarningMatchingRegexIf("NOTE: Thread affinity was not set.", condition); - } - void expectPinningMessage(bool userSpecifiedStride, int stride) - { - std::string pattern = formatString("Pinning threads .* %s.* stride of %d", - userSpecifiedStride ? "user" : "auto", - stride); - expectInfoMatchingRegex(pattern.c_str()); - } - void expectLogMessageMatchingRegexIf(MDLogger::LogLevel level, - const char *re, bool condition) - { - if (condition) - { - logHelper_.expectEntryMatchingRegex(level, re); - } - } - - void setAffinity(int numThreadsOnThisRank) - { - if (hwTop_ == nullptr) - { - setLogicalProcessorCount(1); - } - gmx::PhysicalNodeCommunicator comm(MPI_COMM_WORLD, physicalNodeId_); - int numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank; - analyzeThreadsOnThisNode(comm, - numThreadsOnThisRank, - &numThreadsOnThisNode, - &indexWithinNodeOfFirstThreadOnThisRank); - gmx_set_thread_affinity(logHelper_.logger(), cr_, &hwOpt_, *hwTop_, - numThreadsOnThisRank, numThreadsOnThisNode, - indexWithinNodeOfFirstThreadOnThisRank, &affinityAccess_); - } - - private: - t_commrec *cr_; - gmx_hw_opt_t hwOpt_; - std::unique_ptr hwTop_; - MockThreadAffinityAccess affinityAccess_; - LoggerTestHelper logHelper_; - int physicalNodeId_; + } + + void expectWarningMatchingRegex(const char* re) { expectWarningMatchingRegexIf(re, true); } + void expectWarningMatchingRegexIf(const char* re, bool condition) + { + expectLogMessageMatchingRegexIf(MDLogger::LogLevel::Warning, re, condition); + } + void expectInfoMatchingRegex(const char* re) { expectInfoMatchingRegexIf(re, true); } + void expectInfoMatchingRegexIf(const char* re, bool condition) + { + expectLogMessageMatchingRegexIf(MDLogger::LogLevel::Info, re, condition); + } + void expectGenericFailureMessage() { expectGenericFailureMessageIf(true); } + void expectGenericFailureMessageIf(bool condition) + { + expectWarningMatchingRegexIf("NOTE: Thread affinity was not set.", condition); + } + void expectPinningMessage(bool userSpecifiedStride, int stride) + { + std::string pattern = formatString("Pinning threads .* %s.* stride of %d", + userSpecifiedStride ? "user" : "auto", stride); + expectInfoMatchingRegex(pattern.c_str()); + } + void expectLogMessageMatchingRegexIf(MDLogger::LogLevel level, const char* re, bool condition) + { + if (condition) + { + logHelper_.expectEntryMatchingRegex(level, re); + } + } + + void setAffinity(int numThreadsOnThisRank) + { + if (hwTop_ == nullptr) + { + setLogicalProcessorCount(1); + } + gmx::PhysicalNodeCommunicator comm(MPI_COMM_WORLD, physicalNodeId_); + int numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank; + analyzeThreadsOnThisNode(comm, numThreadsOnThisRank, &numThreadsOnThisNode, + &indexWithinNodeOfFirstThreadOnThisRank); + gmx_set_thread_affinity(logHelper_.logger(), cr_, &hwOpt_, *hwTop_, numThreadsOnThisRank, + numThreadsOnThisNode, indexWithinNodeOfFirstThreadOnThisRank, + &affinityAccess_); + } + +private: + t_commrec* cr_; + gmx_hw_opt_t hwOpt_; + std::unique_ptr hwTop_; + MockThreadAffinityAccess affinityAccess_; + LoggerTestHelper logHelper_; + int physicalNodeId_; }; } // namespace test diff --git a/src/gromacs/mdrunutility/threadaffinity.cpp b/src/gromacs/mdrunutility/threadaffinity.cpp index 09434f885f..e2c099e446 100644 --- a/src/gromacs/mdrunutility/threadaffinity.cpp +++ b/src/gromacs/mdrunutility/threadaffinity.cpp @@ -43,8 +43,8 @@ #include #if HAVE_SCHED_AFFINITY -# include -# include +# include +# include #endif #include "thread_mpi/threads.h" @@ -69,16 +69,16 @@ namespace class DefaultThreadAffinityAccess : public gmx::IThreadAffinityAccess { - public: - bool isThreadAffinitySupported() const override - { - return tMPI_Thread_setaffinity_support() == TMPI_SETAFFINITY_SUPPORT_YES; - } - bool setCurrentThreadAffinityToCore(int core) override - { - const int ret = tMPI_Thread_setaffinity_single(tMPI_Thread_self(), core); - return ret == 0; - } +public: + bool isThreadAffinitySupported() const override + { + return tMPI_Thread_setaffinity_support() == TMPI_SETAFFINITY_SUPPORT_YES; + } + bool setCurrentThreadAffinityToCore(int core) override + { + const int ret = tMPI_Thread_setaffinity_single(tMPI_Thread_self(), core); + return ret == 0; + } }; //! Global instance of DefaultThreadAffinityAccess @@ -86,19 +86,16 @@ DefaultThreadAffinityAccess g_defaultAffinityAccess; } // namespace -gmx::IThreadAffinityAccess::~IThreadAffinityAccess() -{ -} +gmx::IThreadAffinityAccess::~IThreadAffinityAccess() {} -static bool invalidWithinSimulation(const t_commrec *cr, bool invalidLocally) +static bool invalidWithinSimulation(const t_commrec* cr, bool invalidLocally) { #if GMX_MPI if (cr->nnodes > 1) { int value = invalidLocally ? 1 : 0; int globalValue; - MPI_Reduce(&value, &globalValue, 1, MPI_INT, MPI_LOR, MASTERRANK(cr), - cr->mpi_comm_mysim); + MPI_Reduce(&value, &globalValue, 1, MPI_INT, MPI_LOR, MASTERRANK(cr), cr->mpi_comm_mysim); return SIMMASTER(cr) ? (globalValue != 0) : invalidLocally; } #else @@ -107,21 +104,21 @@ static bool invalidWithinSimulation(const t_commrec *cr, bool invalidLocally) return invalidLocally; } -static bool -get_thread_affinity_layout(const gmx::MDLogger &mdlog, - const t_commrec *cr, - const gmx::HardwareTopology &hwTop, - int threads, - bool affinityIsAutoAndNumThreadsIsNotAuto, - int pin_offset, int * pin_stride, - int **localityOrder, - bool *issuedWarning) +static bool get_thread_affinity_layout(const gmx::MDLogger& mdlog, + const t_commrec* cr, + const gmx::HardwareTopology& hwTop, + int threads, + bool affinityIsAutoAndNumThreadsIsNotAuto, + int pin_offset, + int* pin_stride, + int** localityOrder, + bool* issuedWarning) { - int hwThreads; - int hwThreadsPerCore = 0; - bool bPickPinStride; - bool haveTopology; - bool invalidValue; + int hwThreads; + int hwThreadsPerCore = 0; + bool bPickPinStride; + bool haveTopology; + bool invalidValue; haveTopology = (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::Basic); @@ -136,16 +133,16 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, if (haveTopology) { - hwThreads = hwTop.machine().logicalProcessorCount; + hwThreads = hwTop.machine().logicalProcessorCount; // Just use the value for the first core - hwThreadsPerCore = hwTop.machine().sockets[0].cores[0].hwThreads.size(); + hwThreadsPerCore = hwTop.machine().sockets[0].cores[0].hwThreads.size(); snew(*localityOrder, hwThreads); int i = 0; - for (auto &s : hwTop.machine().sockets) + for (auto& s : hwTop.machine().sockets) { - for (auto &c : s.cores) + for (auto& c : s.cores) { - for (auto &t : c.hwThreads) + for (auto& t : c.hwThreads) { (*localityOrder)[i++] = t.logicalProcessorId; } @@ -155,8 +152,8 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, else { /* topology information not available or invalid, ignore it */ - hwThreads = hwTop.machine().logicalProcessorCount; - *localityOrder = nullptr; + hwThreads = hwTop.machine().logicalProcessorCount; + *localityOrder = nullptr; } // Only warn about the first problem per node. Otherwise, the first test // failing would essentially always cause also the other problems get @@ -164,12 +161,13 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, // with this variable is important, since the MPI_Reduce() in // invalidWithinSimulation() needs to always happen. bool alreadyWarned = false; - invalidValue = (hwThreads <= 0); + invalidValue = (hwThreads <= 0); if (invalidWithinSimulation(cr, invalidValue)) { /* We don't know anything about the hardware, don't pin */ - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: No information on available cores, thread pinning disabled."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: No information on available cores, thread pinning disabled."); alreadyWarned = true; } bool validLayout = !invalidValue; @@ -177,14 +175,19 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, if (affinityIsAutoAndNumThreadsIsNotAuto) { invalidValue = (threads != hwThreads); - bool warn = (invalidValue && threads > 1 && threads < hwThreads); + bool warn = (invalidValue && threads > 1 && threads < hwThreads); if (invalidWithinSimulation(cr, warn) && !alreadyWarned) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: The number of threads is not equal to the number of (logical) cores\n" - " and the -pin option is set to auto: will not pin threads to cores.\n" - " This can lead to significant performance degradation.\n" - " Consider using -pin on (and -pinoffset in case you run multiple jobs)."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: The number of threads is not equal to the number of (logical) " + "cores\n" + " and the -pin option is set to auto: will not pin threads to " + "cores.\n" + " This can lead to significant performance degradation.\n" + " Consider using -pin on (and -pinoffset in case you run multiple " + "jobs)."); alreadyWarned = true; } validLayout = validLayout && !invalidValue; @@ -193,8 +196,9 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, invalidValue = (threads > hwThreads); if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: Oversubscribing the CPU, will not pin threads"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: Oversubscribing the CPU, will not pin threads"); alreadyWarned = true; } validLayout = validLayout && !invalidValue; @@ -202,20 +206,22 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, invalidValue = (pin_offset + threads > hwThreads); if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "WARNING: Requested offset too large for available cores, thread pinning disabled."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "WARNING: Requested offset too large for available cores, thread pinning " + "disabled."); alreadyWarned = true; - } validLayout = validLayout && !invalidValue; - invalidValue = false; + invalidValue = false; /* do we need to choose the pinning stride? */ bPickPinStride = (*pin_stride == 0); if (bPickPinStride) { - if (haveTopology && pin_offset + threads*hwThreadsPerCore <= hwThreads) + if (haveTopology && pin_offset + threads * hwThreadsPerCore <= hwThreads) { /* Put one thread on each physical core */ *pin_stride = hwThreadsPerCore; @@ -231,30 +237,32 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, * and probably threads are already pinned by the queuing system, * so we wouldn't end up here in the first place. */ - *pin_stride = (hwThreads - pin_offset)/threads; + *pin_stride = (hwThreads - pin_offset) / threads; } } else { /* Check the placement of the thread with the largest index to make sure * that the offset & stride doesn't cause pinning beyond the last hardware thread. */ - invalidValue = (pin_offset + (threads-1)*(*pin_stride) >= hwThreads); + invalidValue = (pin_offset + (threads - 1) * (*pin_stride) >= hwThreads); } if (invalidWithinSimulation(cr, invalidValue) && !alreadyWarned) { /* We are oversubscribing, don't pin */ - GMX_LOG(mdlog.warning).asParagraph().appendText( - "WARNING: Requested stride too large for available cores, thread pinning disabled."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "WARNING: Requested stride too large for available cores, thread pinning " + "disabled."); alreadyWarned = true; } validLayout = validLayout && !invalidValue; if (validLayout) { - GMX_LOG(mdlog.info).appendTextFormatted( - "Pinning threads with a%s logical core stride of %d", - bPickPinStride ? "n auto-selected" : " user-specified", - *pin_stride); + GMX_LOG(mdlog.info) + .appendTextFormatted("Pinning threads with a%s logical core stride of %d", + bPickPinStride ? "n auto-selected" : " user-specified", *pin_stride); } *issuedWarning = alreadyWarned; @@ -262,9 +270,13 @@ get_thread_affinity_layout(const gmx::MDLogger &mdlog, return validLayout; } -static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeThreadOffset, - int offset, int core_pinning_stride, const int *localityOrder, - gmx::IThreadAffinityAccess *affinityAccess) +static bool set_affinity(const t_commrec* cr, + int nthread_local, + int intraNodeThreadOffset, + int offset, + int core_pinning_stride, + const int* localityOrder, + gmx::IThreadAffinityAccess* affinityAccess) { // Set the per-thread affinity. In order to be able to check the success // of affinity settings, we will set nth_affinity_set to 1 on threads @@ -276,16 +288,16 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeTh // to zero outside the OpenMP block, and then add to it inside the block. // The value will still always be 0 or 1 from each thread. int nth_affinity_set = 0; -#pragma omp parallel num_threads(nthread_local) reduction(+:nth_affinity_set) +#pragma omp parallel num_threads(nthread_local) reduction(+ : nth_affinity_set) { try { - int thread_id, thread_id_node; - int index, core; + int thread_id, thread_id_node; + int index, core; thread_id = gmx_omp_get_thread_num(); thread_id_node = intraNodeThreadOffset + thread_id; - index = offset + thread_id_node*core_pinning_stride; + index = offset + thread_id_node * core_pinning_stride; if (localityOrder != nullptr) { core = localityOrder[index]; @@ -302,19 +314,23 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeTh if (debug) { - fprintf(debug, "On rank %2d, thread %2d, index %2d, core %2d the affinity setting returned %d\n", + fprintf(debug, + "On rank %2d, thread %2d, index %2d, core %2d the affinity setting " + "returned %d\n", cr->nodeid, gmx_omp_get_thread_num(), index, core, ret ? 1 : 0); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (nth_affinity_set > nthread_local) { char msg[STRLEN]; - sprintf(msg, "Looks like we have set affinity for more threads than " - "we have (%d > %d)!\n", nth_affinity_set, nthread_local); + sprintf(msg, + "Looks like we have set affinity for more threads than " + "we have (%d > %d)!\n", + nth_affinity_set, nthread_local); gmx_incons(msg); } @@ -330,18 +346,17 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeTh if (cr->nnodes > 1) { #if GMX_MPI -#if GMX_THREAD_MPI +# if GMX_THREAD_MPI sprintf(sbuf1, "In tMPI thread #%d: ", cr->nodeid); -#else /* GMX_LIB_MPI */ +# else /* GMX_LIB_MPI */ sprintf(sbuf1, "In MPI process #%d: ", cr->nodeid); -#endif -#endif /* GMX_MPI */ +# endif +#endif /* GMX_MPI */ } if (nthread_local > 1) { - sprintf(sbuf2, "for %d/%d thread%s ", - nthread_local - nth_affinity_set, nthread_local, + sprintf(sbuf2, "for %d/%d thread%s ", nthread_local - nth_affinity_set, nthread_local, nthread_local > 1 ? "s" : ""); } @@ -351,13 +366,13 @@ static bool set_affinity(const t_commrec *cr, int nthread_local, int intraNodeTh return allAffinitiesSet; } -void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator &physicalNodeComm, +void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator& physicalNodeComm, int numThreadsOnThisRank, - int *numThreadsOnThisNode, - int *intraNodeThreadOffset) + int* numThreadsOnThisNode, + int* intraNodeThreadOffset) { - *intraNodeThreadOffset = 0; - *numThreadsOnThisNode = numThreadsOnThisRank; + *intraNodeThreadOffset = 0; + *numThreadsOnThisNode = numThreadsOnThisRank; #if GMX_MPI if (physicalNodeComm.size_ > 1) { @@ -367,12 +382,12 @@ void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator &physicalNodeC /* MPI_Scan is inclusive, but here we need exclusive */ *intraNodeThreadOffset -= numThreadsOnThisRank; /* Get the total number of threads on this physical node */ - MPI_Allreduce(&numThreadsOnThisRank, numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, physicalNodeComm.comm_); + MPI_Allreduce(&numThreadsOnThisRank, numThreadsOnThisNode, 1, MPI_INT, MPI_SUM, + physicalNodeComm.comm_); } #else GMX_UNUSED_VALUE(physicalNodeComm); #endif - } /* Set CPU affinity. Can be important for performance. @@ -384,17 +399,16 @@ void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator &physicalNodeC Thus it is important that GROMACS sets the affinity internally if only PME is using threads. */ -void -gmx_set_thread_affinity(const gmx::MDLogger &mdlog, - const t_commrec *cr, - const gmx_hw_opt_t *hw_opt, - const gmx::HardwareTopology &hwTop, - int numThreadsOnThisRank, - int numThreadsOnThisNode, - int intraNodeThreadOffset, - gmx::IThreadAffinityAccess *affinityAccess) +void gmx_set_thread_affinity(const gmx::MDLogger& mdlog, + const t_commrec* cr, + const gmx_hw_opt_t* hw_opt, + const gmx::HardwareTopology& hwTop, + int numThreadsOnThisRank, + int numThreadsOnThisNode, + int intraNodeThreadOffset, + gmx::IThreadAffinityAccess* affinityAccess) { - int *localityOrder = nullptr; + int* localityOrder = nullptr; if (hw_opt->threadAffinity == ThreadAffinity::Off) { @@ -416,36 +430,33 @@ gmx_set_thread_affinity(const gmx::MDLogger &mdlog, no point in warning the user in that case. In any other case the user might be able to do something about it. */ #if !defined(__APPLE__) - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: Cannot set thread affinities on the current platform."); -#endif /* __APPLE__ */ + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("NOTE: Cannot set thread affinities on the current platform."); +#endif /* __APPLE__ */ return; } - int offset = hw_opt->core_pinning_offset; - int core_pinning_stride = hw_opt->core_pinning_stride; + int offset = hw_opt->core_pinning_offset; + int core_pinning_stride = hw_opt->core_pinning_stride; if (offset != 0) { GMX_LOG(mdlog.warning).appendTextFormatted("Applying core pinning offset %d", offset); } bool affinityIsAutoAndNumThreadsIsNotAuto = - (hw_opt->threadAffinity == ThreadAffinity::Auto && - !hw_opt->totNumThreadsIsAuto); + (hw_opt->threadAffinity == ThreadAffinity::Auto && !hw_opt->totNumThreadsIsAuto); bool issuedWarning; - bool validLayout - = get_thread_affinity_layout(mdlog, cr, hwTop, numThreadsOnThisNode, - affinityIsAutoAndNumThreadsIsNotAuto, - offset, &core_pinning_stride, &localityOrder, - &issuedWarning); - const gmx::sfree_guard localityOrderGuard(localityOrder); - - bool allAffinitiesSet; + bool validLayout = get_thread_affinity_layout( + mdlog, cr, hwTop, numThreadsOnThisNode, affinityIsAutoAndNumThreadsIsNotAuto, offset, + &core_pinning_stride, &localityOrder, &issuedWarning); + const gmx::sfree_guard localityOrderGuard(localityOrder); + + bool allAffinitiesSet; if (validLayout) { - allAffinitiesSet = set_affinity(cr, numThreadsOnThisRank, intraNodeThreadOffset, - offset, core_pinning_stride, localityOrder, - affinityAccess); + allAffinitiesSet = set_affinity(cr, numThreadsOnThisRank, intraNodeThreadOffset, offset, + core_pinning_stride, localityOrder, affinityAccess); } else { @@ -467,12 +478,12 @@ gmx_set_thread_affinity(const gmx::MDLogger &mdlog, */ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) { - bool detectedDefaultAffinityMask = true; + bool detectedDefaultAffinityMask = true; #if HAVE_SCHED_AFFINITY cpu_set_t mask_current; CPU_ZERO(&mask_current); - int ret; + int ret; if ((ret = sched_getaffinity(0, sizeof(cpu_set_t), &mask_current)) != 0) { /* failed to query affinity mask, will just return */ @@ -486,9 +497,8 @@ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) /* Before proceeding with the actual check, make sure that the number of * detected CPUs is >= the CPUs in the current set. * We need to check for CPU_COUNT as it was added only in glibc 2.6. */ -#ifdef CPU_COUNT - if (detectedDefaultAffinityMask && - nthreads_hw_avail < CPU_COUNT(&mask_current)) +# ifdef CPU_COUNT + if (detectedDefaultAffinityMask && nthreads_hw_avail < CPU_COUNT(&mask_current)) { if (debug) { @@ -497,7 +507,7 @@ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) } detectedDefaultAffinityMask = false; } -#endif /* CPU_COUNT */ +# endif /* CPU_COUNT */ if (detectedDefaultAffinityMask) { @@ -515,8 +525,7 @@ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) } if (debug) { - fprintf(debug, "%s affinity mask found\n", - allBitsAreSet ? "Default" : "Non-default"); + fprintf(debug, "%s affinity mask found\n", allBitsAreSet ? "Default" : "Non-default"); } if (!allBitsAreSet) { @@ -533,9 +542,8 @@ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) if (mpiIsInitialized) { bool detectedDefaultAffinityMaskOnAllRanks; - MPI_Allreduce(&detectedDefaultAffinityMask, - &detectedDefaultAffinityMaskOnAllRanks, - 1, MPI_C_BOOL, MPI_LAND, MPI_COMM_WORLD); + MPI_Allreduce(&detectedDefaultAffinityMask, &detectedDefaultAffinityMaskOnAllRanks, 1, + MPI_C_BOOL, MPI_LAND, MPI_COMM_WORLD); detectedDefaultAffinityMask = detectedDefaultAffinityMaskOnAllRanks; } #endif @@ -547,11 +555,10 @@ static bool detectDefaultAffinityMask(const int nthreads_hw_avail) * will honor it and disable mdrun internal affinity setting. * Note that this will only work on Linux as we use a GNU feature. */ -void -gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, - gmx_hw_opt_t *hw_opt, - int gmx_unused nthreads_hw_avail, - gmx_bool bAfterOpenmpInit) +void gmx_check_thread_affinity_set(const gmx::MDLogger& mdlog, + gmx_hw_opt_t* hw_opt, + int gmx_unused nthreads_hw_avail, + gmx_bool bAfterOpenmpInit) { GMX_RELEASE_ASSERT(hw_opt, "hw_opt must be a non-NULL pointer"); @@ -564,12 +571,11 @@ gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, */ if (hw_opt->threadAffinity != ThreadAffinity::Off) { - char *message; + char* message; if (!gmx_omp_check_thread_affinity(&message)) { /* We only pin automatically with totNumThreadsIsAuto=true */ - if (hw_opt->threadAffinity == ThreadAffinity::On || - hw_opt->totNumThreadsIsAuto) + if (hw_opt->threadAffinity == ThreadAffinity::On || hw_opt->totNumThreadsIsAuto) { GMX_LOG(mdlog.warning).asParagraph().appendText(message); } @@ -585,14 +591,19 @@ gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, { if (!bAfterOpenmpInit) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "Non-default thread affinity set, disabling internal thread affinity"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "Non-default thread affinity set, disabling internal thread " + "affinity"); } else { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "Non-default thread affinity set probably by the OpenMP library,\n" - "disabling internal thread affinity"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "Non-default thread affinity set probably by the OpenMP library,\n" + "disabling internal thread affinity"); } hw_opt->threadAffinity = ThreadAffinity::Off; } @@ -601,9 +612,10 @@ gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, /* Only warn once, at the last check (bAfterOpenmpInit==TRUE) */ if (bAfterOpenmpInit) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "Overriding thread affinity set outside %s", - gmx::getProgramContext().displayName()); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted("Overriding thread affinity set outside %s", + gmx::getProgramContext().displayName()); } } } diff --git a/src/gromacs/mdrunutility/threadaffinity.h b/src/gromacs/mdrunutility/threadaffinity.h index f5b890660f..820c93a901 100644 --- a/src/gromacs/mdrunutility/threadaffinity.h +++ b/src/gromacs/mdrunutility/threadaffinity.h @@ -59,22 +59,22 @@ class PhysicalNodeCommunicator; class IThreadAffinityAccess { - public: - virtual bool isThreadAffinitySupported() const = 0; - virtual bool setCurrentThreadAffinityToCore(int core) = 0; +public: + virtual bool isThreadAffinitySupported() const = 0; + virtual bool setCurrentThreadAffinityToCore(int core) = 0; - protected: - virtual ~IThreadAffinityAccess(); +protected: + virtual ~IThreadAffinityAccess(); }; } // namespace gmx /*! \brief Communicates within physical nodes to discover the * distribution of threads over ranks. */ -void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator &physicalNodeComm, +void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator& physicalNodeComm, int numThreadsOnThisRank, - int *numThreadsOnThisNode, - int *intraNodeThreadOffset); + int* numThreadsOnThisNode, + int* intraNodeThreadOffset); /*! \brief * Sets the thread affinity using the requested setting stored in hw_opt. @@ -91,15 +91,14 @@ void analyzeThreadsOnThisNode(const gmx::PhysicalNodeCommunicator &physicalNodeC * in the set of all the threads of all MPI ranks within a node (ordered by MPI rank ID). * \param[in] affinityAccess Interface for low-level access to affinity details. */ -void -gmx_set_thread_affinity(const gmx::MDLogger &mdlog, - const t_commrec *cr, - const gmx_hw_opt_t *hw_opt, - const gmx::HardwareTopology &hwTop, - int numThreadsOnThisRank, - int numThreadsOnThisNode, - int intraNodeThreadOffset, - gmx::IThreadAffinityAccess *affinityAccess); +void gmx_set_thread_affinity(const gmx::MDLogger& mdlog, + const t_commrec* cr, + const gmx_hw_opt_t* hw_opt, + const gmx::HardwareTopology& hwTop, + int numThreadsOnThisRank, + int numThreadsOnThisNode, + int intraNodeThreadOffset, + gmx::IThreadAffinityAccess* affinityAccess); /*! \brief * Checks the process affinity mask and if it is found to be non-zero, @@ -115,9 +114,9 @@ gmx_set_thread_affinity(const gmx::MDLogger &mdlog, * With bAfterOpenmpInit false, it will also detect whether OpenMP environment * variables for setting the affinity are set. */ -void -gmx_check_thread_affinity_set(const gmx::MDLogger &mdlog, - gmx_hw_opt_t *hw_opt, int ncpus, - gmx_bool bAfterOpenmpInit); +void gmx_check_thread_affinity_set(const gmx::MDLogger& mdlog, + gmx_hw_opt_t* hw_opt, + int ncpus, + gmx_bool bAfterOpenmpInit); #endif diff --git a/src/gromacs/mdspan/accessor_policy.h b/src/gromacs/mdspan/accessor_policy.h index d2520e23da..2a7d1e9b83 100644 --- a/src/gromacs/mdspan/accessor_policy.h +++ b/src/gromacs/mdspan/accessor_policy.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -98,40 +98,39 @@ namespace gmx template class accessor_basic { - public: - //! Type of element to be accessed. - using element_type = ElementType; - //! Pointer to element to be accessed. - using pointer = ElementType*; - //! How to determine a memory offset, provided by self accessor. - using offset_policy = accessor_basic; - //! Type of references. - using reference = ElementType&; +public: + //! Type of element to be accessed. + using element_type = ElementType; + //! Pointer to element to be accessed. + using pointer = ElementType*; + //! How to determine a memory offset, provided by self accessor. + using offset_policy = accessor_basic; + //! Type of references. + using reference = ElementType&; - /*! \brief Shift a pointer by an offset. - * \param[in] p Pointer to reference memory location. - * \param[in] i offset from memory location. - * \returns pointer to offset memory location. - */ - constexpr typename offset_policy::pointer - offset( pointer p, ptrdiff_t i ) const noexcept - { return typename offset_policy::pointer(p+i); } + /*! \brief Shift a pointer by an offset. + * \param[in] p Pointer to reference memory location. + * \param[in] i offset from memory location. + * \returns pointer to offset memory location. + */ + constexpr typename offset_policy::pointer offset(pointer p, ptrdiff_t i) const noexcept + { + return typename offset_policy::pointer(p + i); + } - /*! \brief Access element from an offset to given pointer. - * \param[in] p Pointer to reference memory location. - * \param[in] i offset from memory location. - * \returns reference to element stored at offset from memory location. - */ - constexpr reference access( pointer p, ptrdiff_t i ) const noexcept - { return p[i]; } + /*! \brief Access element from an offset to given pointer. + * \param[in] p Pointer to reference memory location. + * \param[in] i offset from memory location. + * \returns reference to element stored at offset from memory location. + */ + constexpr reference access(pointer p, ptrdiff_t i) const noexcept { return p[i]; } - /*! \brief Decay pointer to pointer to ElementType. - * NOTE This function does nothing, because it is the trivial implementation of an accessor. - * \returns input pointer as pointer to ElementType - */ - constexpr ElementType* decay( pointer p ) const noexcept - { return p; } + /*! \brief Decay pointer to pointer to ElementType. + * NOTE This function does nothing, because it is the trivial implementation of an accessor. + * \returns input pointer as pointer to ElementType + */ + constexpr ElementType* decay(pointer p) const noexcept { return p; } }; -} // namespace gmx +} // namespace gmx #endif /* end of include guard: MDSPAN_ACCESSOR_POLICY_H */ diff --git a/src/gromacs/mdspan/extensions.h b/src/gromacs/mdspan/extensions.h index 4b77415164..320fb74467 100644 --- a/src/gromacs/mdspan/extensions.h +++ b/src/gromacs/mdspan/extensions.h @@ -58,10 +58,9 @@ namespace gmx * \note Changing the elements that basic_mdspan views does not change * the view itself, so a single begin that takes a const view suffices. */ -template -constexpr std::enable_if_t -begin(const BasicMdspan &basicMdspan) +template +constexpr std::enable_if_t +begin(const BasicMdspan& basicMdspan) { return basicMdspan.data(); } @@ -72,10 +71,9 @@ begin(const BasicMdspan &basicMdspan) * \note Changing the elements that basic_mdspan views does not change * the view itself, so a single end that takes a const view suffices. */ -template -constexpr std::enable_if_t -end(const BasicMdspan &basicMdspan) +template +constexpr std::enable_if_t +end(const BasicMdspan& basicMdspan) { return basicMdspan.data() + basicMdspan.mapping().required_span_size(); } @@ -84,45 +82,45 @@ end(const BasicMdspan &basicMdspan) using dynamicExtents3D = extents; //! Elementwise addition -template -constexpr BasicMdspan addElementwise(const BasicMdspan &span1, const BasicMdspan &span2) +template +constexpr BasicMdspan addElementwise(const BasicMdspan& span1, const BasicMdspan& span2) { BasicMdspan result(span1); - std::transform(begin(span1), end(span1), begin(span2), - begin(result), std::plus()); + std::transform(begin(span1), end(span1), begin(span2), begin(result), + std::plus()); return result; } //! Elementwise subtraction - left minus right -template -constexpr BasicMdspan subtractElementwise(const BasicMdspan &span1, const BasicMdspan &span2) +template +constexpr BasicMdspan subtractElementwise(const BasicMdspan& span1, const BasicMdspan& span2) { BasicMdspan result(span1); - std::transform(begin(span1), end(span1), begin(span2), - begin(result), std::minus()); + std::transform(begin(span1), end(span1), begin(span2), begin(result), + std::minus()); return result; } //! Elementwise multiplication -template -constexpr BasicMdspan multiplyElementwise(const BasicMdspan &span1, const BasicMdspan &span2) +template +constexpr BasicMdspan multiplyElementwise(const BasicMdspan& span1, const BasicMdspan& span2) { BasicMdspan result(span1); - std::transform(begin(span1), end(span1), begin(span2), - begin(result), std::multiplies()); + std::transform(begin(span1), end(span1), begin(span2), begin(result), + std::multiplies()); return result; } //! Elementwise division - left / right -template -constexpr BasicMdspan divideElementwise(const BasicMdspan &span1, const BasicMdspan &span2) +template +constexpr BasicMdspan divideElementwise(const BasicMdspan& span1, const BasicMdspan& span2) { BasicMdspan result(span1); - std::transform(begin(span1), end(span1), begin(span2), - begin(result), std::divides()); + std::transform(begin(span1), end(span1), begin(span2), begin(result), + std::divides()); return result; } -} // namespace gmx +} // namespace gmx #endif // GMX_MDSPAN_EXTENSIONS_H_ diff --git a/src/gromacs/mdspan/extents.h b/src/gromacs/mdspan/extents.h index 06f1ef0f51..74ea8b0867 100644 --- a/src/gromacs/mdspan/extents.h +++ b/src/gromacs/mdspan/extents.h @@ -97,46 +97,49 @@ namespace gmx /*! \brief Define constant that signals dynamic extent. */ -enum : std::ptrdiff_t { +enum : std::ptrdiff_t +{ dynamic_extent = -1 }; -template< std::ptrdiff_t ... StaticExtents > +template class extents; template -constexpr bool operator==(const extents &lhs, - const extents &rhs) noexcept; +constexpr bool operator==(const extents& lhs, const extents& rhs) noexcept; template -constexpr bool operator!=(const extents &lhs, - const extents &rhs) noexcept; +constexpr bool operator!=(const extents& lhs, const extents& rhs) noexcept; namespace detail { -template< int R, std::ptrdiff_t ... StaticExtents > +template struct extents_analyse; /*! \libinternal \brief Enable querying extent of specific rank by splitting * a static extents off the variadic template arguments. * */ -template< int R, std::ptrdiff_t E0, std::ptrdiff_t ... StaticExtents > -struct extents_analyse { +template +struct extents_analyse +{ //! The extent analysis of the next lower rank. - using next_extents_analyse = extents_analyse; + using next_extents_analyse = extents_analyse; /*! \brief Accumulate the total rank from all extents. * \returns incremented rank of the next extent */ - static constexpr std::size_t rank() noexcept { return next_extents_analyse::rank()+1; } + static constexpr std::size_t rank() noexcept { return next_extents_analyse::rank() + 1; } /*! \brief Accumulate the dynamic rank from all extents. * This extent is static, so hand down query to the next extent analysis. * \returns the dynamic rank of the next extent analysis. */ - static constexpr std::size_t rank_dynamic() noexcept { return next_extents_analyse::rank_dynamic(); } + static constexpr std::size_t rank_dynamic() noexcept + { + return next_extents_analyse::rank_dynamic(); + } //! Store analysis of the next extent of next lower rank. next_extents_analyse next; @@ -148,8 +151,10 @@ struct extents_analyse { * to the next extents analysis of lower rank. * \param[in] de dynamic extents */ - template - constexpr extents_analyse(DynamicExtents... de) : next(de ...) {} + template + constexpr extents_analyse(DynamicExtents... de) : next(de...) + { + } /*! \brief Construct from an array of dynamic extentes and rank. * Hand down the dynamic rank parameters to the next extents analysis rank @@ -157,15 +162,20 @@ struct extents_analyse { * \param[in] r rank to read from the dynamic extent */ template - constexpr extents_analyse(const std::array &de, const std::size_t r) : next(de, r) {} + constexpr extents_analyse(const std::array& de, const std::size_t r) : + next(de, r) + { + } //! Copy constructor. template - extents_analyse(extents_analyse rhs) : next(rhs.next) {} + extents_analyse(extents_analyse rhs) : next(rhs.next) + { + } //! Assignment operator. template - extents_analyse &operator= (extents_analyse rhs) + extents_analyse& operator=(extents_analyse rhs) { next = rhs.next; return *this; @@ -189,32 +199,33 @@ struct extents_analyse { } //! Returns the extent with the first dimension sliced off - constexpr auto sliced_extents() const noexcept - { - return next; - } + constexpr auto sliced_extents() const noexcept { return next; } }; /*! \libinternal \brief Enable querying extent of specific rank by splitting * a dynamic extent off the variadic template arguments. */ -template< int R, std::ptrdiff_t ... StaticExtents > -struct extents_analyse { +template +struct extents_analyse +{ //! The extent analysis of the next lower rank. - using next_extents_analyse = extents_analyse; + using next_extents_analyse = extents_analyse; /*! \brief Accumulate the total rank from all extents. * \returns incremented rank of the next extent */ - static constexpr std::size_t rank() noexcept { return next_extents_analyse::rank()+1; } + static constexpr std::size_t rank() noexcept { return next_extents_analyse::rank() + 1; } /*! \brief Accumulate the dynamic rank from all extents. * \returns the dynamic rank of the next extent analysis. */ - static constexpr std::size_t rank_dynamic() noexcept { return next_extents_analyse::rank_dynamic()+1; } + static constexpr std::size_t rank_dynamic() noexcept + { + return next_extents_analyse::rank_dynamic() + 1; + } //! Store analysis of the next extent of next lower rank. next_extents_analyse next; //! The dynamic extent of this rank - std::ptrdiff_t this_extent; + std::ptrdiff_t this_extent; //! Trivial constructor. extents_analyse() : next(), this_extent(0) {} @@ -224,8 +235,10 @@ struct extents_analyse { * \param[in] E the dynamic extent of this rank. * \param[in] de dynamic extents */ - template - extents_analyse(std::ptrdiff_t E, DynamicExtents... de) : next(de ...), this_extent(E) {} + template + extents_analyse(std::ptrdiff_t E, DynamicExtents... de) : next(de...), this_extent(E) + { + } /*! \brief Construct from an array of dynamic extentes and rank. * Hand down the dynamic rank parameters to the next extents analysis rank @@ -233,15 +246,23 @@ struct extents_analyse { * \param[in] r rank to read from the dynamic extent */ template - extents_analyse(const std::array &de, const std::size_t r) : next(de, r+1), this_extent(de[r]) {} + extents_analyse(const std::array& de, const std::size_t r) : + next(de, r + 1), + this_extent(de[r]) + { + } //! Copy constructor. template - extents_analyse(extents_analyse rhs) : next(rhs.next), this_extent(rhs.extent(R)) {} + extents_analyse(extents_analyse rhs) : + next(rhs.next), + this_extent(rhs.extent(R)) + { + } //! Assignment operator. template - extents_analyse &operator= (extents_analyse rhs) + extents_analyse& operator=(extents_analyse rhs) { next = rhs.next; this_extent = rhs.extent(R); @@ -266,17 +287,15 @@ struct extents_analyse { } //! Returns the extent with the first dimension sliced off - constexpr auto sliced_extents() const noexcept - { - return next; - } + constexpr auto sliced_extents() const noexcept { return next; } }; /*! \libinternal \brief Specialisation for rank 0 extents analysis. * Ends recursive rank analysis. */ template<> -struct extents_analyse<0> { +struct extents_analyse<0> +{ /*! \brief Rank of extent of rank 0. * \returns 0 */ @@ -291,32 +310,27 @@ struct extents_analyse<0> { //! Construct from array and rank, doing nothing. template - extents_analyse(const std::array & /*de*/, const std::size_t /*r*/) {} + extents_analyse(const std::array& /*de*/, const std::size_t /*r*/) + { + } - //extents_analyse & operator=(extents_analyse) = default; + // extents_analyse & operator=(extents_analyse) = default; /*! \brief Extent of rank 0 is 1, ensuring that product of extents yields required size and not zero. * NOTE changed from ORNL reference implementation in making this static constexpr instead of constexpr .. const */ - static constexpr std::ptrdiff_t extent(const std::size_t /*r*/) noexcept - { - return 1; - } + static constexpr std::ptrdiff_t extent(const std::size_t /*r*/) noexcept { return 1; } //! Static extent of rank 0 is 1, ensuring that product of extents yields required size and not zero. - static constexpr std::ptrdiff_t static_extent(const std::size_t /*r*/) noexcept - { - return 1; - } - + static constexpr std::ptrdiff_t static_extent(const std::size_t /*r*/) noexcept { return 1; } }; -template< std::ptrdiff_t E0, std::ptrdiff_t ... StaticExtents > +template struct sliced_extents { using type = extents; }; -} // namespace detail +} // namespace detail /*! \libinternal \brief Multidimensional extents with static and dynamic dimensions. * @@ -329,92 +343,104 @@ struct sliced_extents * \tparam StaticExtents rank number of extents, where the dynamic_extent * constant for static extent is used to signal a dynamic extent. */ -template< std::ptrdiff_t ... StaticExtents > +template class extents { - private: - using extents_analyse_t = detail::extents_analyse; - - public: - //! Type used to index elements. - using index_type = std::ptrdiff_t; - //! Trivial constructor - constexpr extents() noexcept {} - //! Move constructor - constexpr extents( extents && ) noexcept = default; - //! Copy constructor. - constexpr extents( const extents & ) noexcept = default; - /*! \brief Construct with dynamic extents. - * - * Allows for extents(u,v,w..) syntax when setting dynamic extents - * - * \tparam IndexType type of index - * \param[in] dn first dynamic index - * \param[in] DynamicExtents parameter pack - */ - template< class ... IndexType > - constexpr extents( std::ptrdiff_t dn, - IndexType ... DynamicExtents ) noexcept - : impl( dn, DynamicExtents ... ) - { static_assert( 1+sizeof ... (DynamicExtents) == rank_dynamic(), "" ); } - - /*! \brief Construct from array of dynamic extents. - * - * Allows for extents({{u,v,w..}}) syntax when setting dynamic extents - * - * \param[in] dynamic_extents array of dynamic rank size containing extents - */ - constexpr extents( const std::array dynamic_extents) noexcept - : impl(dynamic_extents, 0) {} - - //! Copy constructor - template - extents( const extents &other ) - : impl( other.impl ) {} - - //! Default move assignment - extents &operator= ( extents && ) noexcept = default; - //! Default copy assignment - extents &operator= ( const extents & ) noexcept = default; - //! Copy assignment - template - extents &operator= ( const extents &other ) - { impl = other.impl; return *this; } - //! Default destructor - ~extents() = default; - - // [mdspan.extents.obs] - /*! \brief The rank of the extent. - * \returns the rank all extents together - */ - static constexpr std::size_t rank() noexcept - { return sizeof ... (StaticExtents); } - /*! \brief The rank of the dynamic extents. - * \returns Only the dynamic extents. - */ - static constexpr std::size_t rank_dynamic() noexcept - { return extents_analyse_t::rank_dynamic(); } - /*! \brief The rank of the static extents. - * \returns Only the static extents. - */ - static constexpr index_type static_extent(std::size_t k) noexcept - { return extents_analyse_t::static_extent(rank()-k); } - /*! \brief The extent along a specific dimension. - * \param[in] k the dimension - * \returns the extent along that dimension - */ - constexpr index_type extent(std::size_t k) const noexcept - { return impl.extent(rank()-k); } - //! Returns the extent with the first dimension sliced off - constexpr auto sliced_extents() const noexcept - { return typename detail::sliced_extents::type(impl.sliced_extents()); } - - private: - extents(extents_analyse_t o) : impl(o) {} - //! For copy assignment, extents are friends of extents. - template< std::ptrdiff_t... > friend class extents; - //! The implementation class. - extents_analyse_t impl; +private: + using extents_analyse_t = detail::extents_analyse; + +public: + //! Type used to index elements. + using index_type = std::ptrdiff_t; + //! Trivial constructor + constexpr extents() noexcept {} + //! Move constructor + constexpr extents(extents&&) noexcept = default; + //! Copy constructor. + constexpr extents(const extents&) noexcept = default; + /*! \brief Construct with dynamic extents. + * + * Allows for extents(u,v,w..) syntax when setting dynamic extents + * + * \tparam IndexType type of index + * \param[in] dn first dynamic index + * \param[in] DynamicExtents parameter pack + */ + template + constexpr extents(std::ptrdiff_t dn, IndexType... DynamicExtents) noexcept : + impl(dn, DynamicExtents...) + { + static_assert(1 + sizeof...(DynamicExtents) == rank_dynamic(), ""); + } + + /*! \brief Construct from array of dynamic extents. + * + * Allows for extents({{u,v,w..}}) syntax when setting dynamic extents + * + * \param[in] dynamic_extents array of dynamic rank size containing extents + */ + constexpr extents(const std::array dynamic_extents) noexcept : + impl(dynamic_extents, 0) + { + } + + //! Copy constructor + template + extents(const extents& other) : impl(other.impl) + { + } + + //! Default move assignment + extents& operator=(extents&&) noexcept = default; + //! Default copy assignment + extents& operator=(const extents&) noexcept = default; + //! Copy assignment + template + extents& operator=(const extents& other) + { + impl = other.impl; + return *this; + } + //! Default destructor + ~extents() = default; + + // [mdspan.extents.obs] + /*! \brief The rank of the extent. + * \returns the rank all extents together + */ + static constexpr std::size_t rank() noexcept { return sizeof...(StaticExtents); } + /*! \brief The rank of the dynamic extents. + * \returns Only the dynamic extents. + */ + static constexpr std::size_t rank_dynamic() noexcept + { + return extents_analyse_t::rank_dynamic(); + } + /*! \brief The rank of the static extents. + * \returns Only the static extents. + */ + static constexpr index_type static_extent(std::size_t k) noexcept + { + return extents_analyse_t::static_extent(rank() - k); + } + /*! \brief The extent along a specific dimension. + * \param[in] k the dimension + * \returns the extent along that dimension + */ + constexpr index_type extent(std::size_t k) const noexcept { return impl.extent(rank() - k); } + //! Returns the extent with the first dimension sliced off + constexpr auto sliced_extents() const noexcept + { + return typename detail::sliced_extents::type(impl.sliced_extents()); + } + +private: + extents(extents_analyse_t o) : impl(o) {} + //! For copy assignment, extents are friends of extents. + template + friend class extents; + //! The implementation class. + extents_analyse_t impl; }; @@ -422,13 +448,12 @@ class extents * \returns true if extents are equal */ template -constexpr bool operator==(const extents &lhs, - const extents &rhs) noexcept +constexpr bool operator==(const extents& lhs, const extents& rhs) noexcept { bool equal = lhs.rank() == rhs.rank(); for (std::size_t r = 0; r < lhs.rank(); r++) { - equal = equal && ( lhs.extent(r) == rhs.extent(r) ); + equal = equal && (lhs.extent(r) == rhs.extent(r)); } return equal; } @@ -437,11 +462,10 @@ constexpr bool operator==(const extents &lhs, * \returns true if extents are unequal */ template -constexpr bool operator!=(const extents &lhs, - const extents &rhs) noexcept +constexpr bool operator!=(const extents& lhs, const extents& rhs) noexcept { return !(lhs == rhs); } -} // namespace gmx +} // namespace gmx #endif /* end of include guard: MDSPAN_EXTENTS_H */ diff --git a/src/gromacs/mdspan/layouts.h b/src/gromacs/mdspan/layouts.h index 0b6d073c9e..7482508337 100644 --- a/src/gromacs/mdspan/layouts.h +++ b/src/gromacs/mdspan/layouts.h @@ -98,128 +98,127 @@ namespace gmx class layout_right { +public: + /*! \libinternal \brief Mapping from multidimensional indices within extents to 1D index. + * \tparam Extents the extents of the multidimensional integers for the mapping. + */ + template + class mapping + { + private: + //! The extents. + Extents m_extents; + public: - /*! \libinternal \brief Mapping from multidimensional indices within extents to 1D index. - * \tparam Extents the extents of the multidimensional integers for the mapping. + //! exposing the type of indices + using index_type = ptrdiff_t; + //! exposing the type of the extents + using extents_type = Extents; + //! Default constructor. + constexpr mapping() noexcept = default; + //! Default move constructor. + constexpr mapping(mapping&&) noexcept = default; + //! Default copy constructor. + constexpr mapping(const mapping&) noexcept = default; + //! Default move assignment + mapping& operator=(mapping&&) noexcept = default; + //! Default copy assignment + mapping& operator=(const mapping&) noexcept = default; + /*! \brief Construct mapping, setting extents + * \param[in] ext the extents */ - template - class mapping - { - private: - //! The extents. - Extents m_extents; - - public: - //! exposing the type of indices - using index_type = ptrdiff_t; - //! exposing the type of the extents - using extents_type = Extents; - //! Default constructor. - constexpr mapping() noexcept = default; - //! Default move constructor. - constexpr mapping( mapping && ) noexcept = default; - //! Default copy constructor. - constexpr mapping( const mapping & ) noexcept = default; - //! Default move assignment - mapping &operator= ( mapping && ) noexcept = default; - //! Default copy assignment - mapping &operator= ( const mapping & ) noexcept = default; - /*! \brief Construct mapping, setting extents - * \param[in] ext the extents - */ - constexpr mapping( const Extents &ext ) noexcept - : m_extents( ext ) {} - /*! \brief Return the extents. - * \returns extents - */ - constexpr const Extents &extents() const noexcept { return m_extents; } + constexpr mapping(const Extents& ext) noexcept : m_extents(ext) {} + /*! \brief Return the extents. + * \returns extents + */ + constexpr const Extents& extents() const noexcept { return m_extents; } - private: - /* \brief End recursion helper function for static offset calculation. - * \param[in] sum The accumulated offset over all dimensions - * \returns The offset. - */ - static constexpr index_type - offset( const size_t /*r*/, const ptrdiff_t sum) - { return sum; } + private: + /* \brief End recursion helper function for static offset calculation. + * \param[in] sum The accumulated offset over all dimensions + * \returns The offset. + */ + static constexpr index_type offset(const size_t /*r*/, const ptrdiff_t sum) { return sum; } - /* \brief Statically calculate offset from index and extent. - * For a multidimensional index (i0,i1,..,in), in a right memory - * layout, 'i0' denotes the slowest moving dimension and - * 'in' the fastest moving dimension. - * The overall offset within extents N = (N0,..,Nn) is then - * offest = i0 * N1 * .. * Nn + i1 * N2 * .. * Nn + in-1 * Nn + in - * = (((i0*N1+i1)*N2+i2)*N3+i3) ... - * \param[in] r current rank - * \param[in] sum current sum up to this rank - * \param[in] i index - * \oaram[in] indices The rest of the paramter pack. - * \returns The offset. - */ - template - inline constexpr index_type - offset( const size_t r, ptrdiff_t sum, const index_type i, Indices... indices) const noexcept - { - return offset( r+1, sum * m_extents.extent(r) + i, indices ...); - } + /* \brief Statically calculate offset from index and extent. + * For a multidimensional index (i0,i1,..,in), in a right memory + * layout, 'i0' denotes the slowest moving dimension and + * 'in' the fastest moving dimension. + * The overall offset within extents N = (N0,..,Nn) is then + * offest = i0 * N1 * .. * Nn + i1 * N2 * .. * Nn + in-1 * Nn + in + * = (((i0*N1+i1)*N2+i2)*N3+i3) ... + * \param[in] r current rank + * \param[in] sum current sum up to this rank + * \param[in] i index + * \oaram[in] indices The rest of the paramter pack. + * \returns The offset. + */ + template + inline constexpr index_type + offset(const size_t r, ptrdiff_t sum, const index_type i, Indices... indices) const noexcept + { + return offset(r + 1, sum * m_extents.extent(r) + i, indices...); + } - public: - /*! \brief Return the size of the underlying one-dimensional - * data structure, so that the mapping is always valid. - * - * \returns number of span elements - */ - constexpr index_type required_span_size() const noexcept - { - index_type size = 1; - for (size_t r = 0; r < m_extents.rank(); r++) - { - size *= m_extents.extent(r); - } - return size; - } + public: + /*! \brief Return the size of the underlying one-dimensional + * data structure, so that the mapping is always valid. + * + * \returns number of span elements + */ + constexpr index_type required_span_size() const noexcept + { + index_type size = 1; + for (size_t r = 0; r < m_extents.rank(); r++) + { + size *= m_extents.extent(r); + } + return size; + } - /*! \brief Map the multidimensional indices to 1D. - * Requires number of indicies have the same dimensionality as the mapping. - * \tparam Indices type of the indices to be mapped - * \param[in] indices the indices to be mapped - * \returns One-dimensional integer index. - */ - template - std::enable_if_t - constexpr operator()( Indices ... indices ) const noexcept - { return offset( 0, 0, indices ... ); } + /*! \brief Map the multidimensional indices to 1D. + * Requires number of indicies have the same dimensionality as the mapping. + * \tparam Indices type of the indices to be mapped + * \param[in] indices the indices to be mapped + * \returns One-dimensional integer index. + */ + template + std::enable_if_t constexpr + operator()(Indices... indices) const noexcept + { + return offset(0, 0, indices...); + } - //! Report that this mapping is always unique. - static constexpr bool is_always_unique() noexcept { return true; } - //! Report that this mapping is always contiguous. - static constexpr bool is_always_contiguous() noexcept { return true; } - //! Report that this mapping is always strided. - static constexpr bool is_always_strided() noexcept { return true; } + //! Report that this mapping is always unique. + static constexpr bool is_always_unique() noexcept { return true; } + //! Report that this mapping is always contiguous. + static constexpr bool is_always_contiguous() noexcept { return true; } + //! Report that this mapping is always strided. + static constexpr bool is_always_strided() noexcept { return true; } - //! Report that this mapping is unique. - constexpr bool is_unique() const noexcept { return true; } - //! Report that this mapping is contiguous. - constexpr bool is_contiguous() const noexcept { return true; } - //! Report that this mapping is strided. - constexpr bool is_strided() const noexcept { return true; } - /*!\brief Return the stride of dimension r. - * \param[in] R rank of the stride to be queried. - * \returns the stride along dimension r. - */ - constexpr index_type stride(const size_t R) const noexcept - { - ptrdiff_t stride = 1; - for (size_t r = m_extents.rank()-1; r > R; r--) - { - stride *= m_extents.extent(r); - } - return stride; - } + //! Report that this mapping is unique. + constexpr bool is_unique() const noexcept { return true; } + //! Report that this mapping is contiguous. + constexpr bool is_contiguous() const noexcept { return true; } + //! Report that this mapping is strided. + constexpr bool is_strided() const noexcept { return true; } + /*!\brief Return the stride of dimension r. + * \param[in] R rank of the stride to be queried. + * \returns the stride along dimension r. + */ + constexpr index_type stride(const size_t R) const noexcept + { + ptrdiff_t stride = 1; + for (size_t r = m_extents.rank() - 1; r > R; r--) + { + stride *= m_extents.extent(r); + } + return stride; + } - }; // class mapping + }; // class mapping -}; // class layout_right +}; // class layout_right -} // namespace gmx -#endif /* end of include guard: MDSPAN_LAYOUTS_H */ +} // namespace gmx +#endif /* end of include guard: MDSPAN_LAYOUTS_H */ diff --git a/src/gromacs/mdspan/mdspan.h b/src/gromacs/mdspan/mdspan.h index 2f2465181f..10499d655d 100644 --- a/src/gromacs/mdspan/mdspan.h +++ b/src/gromacs/mdspan/mdspan.h @@ -106,237 +106,244 @@ namespace gmx * \tparam LayoutPolicy Describes is the memory layout of the multidimensional array; right by default. * \tparam AccessorPolicy Describes memory access model. */ -template > +template> class basic_mdspan { - public: - //! Expose type used to define the extents of the data. - using extents_type = Extents; - //! Expose type used to define the layout of the data. - using layout_type = LayoutPolicy; - //! Expose type used to define the memory access model of the data. - using accessor_type = AccessorPolicy; - //! Expose type used to map multidimensional indices to one-dimensioal indices. - using mapping_type = typename layout_type::template mapping; - //! Exposes the type of stored element. - using element_type = typename accessor_type::element_type; - //! Expose the underlying type of the stored elements. - using value_type = std::remove_cv_t; - //! Expose the type used for indexing. - using index_type = ptrdiff_t; - //! Expose type for index differences. - using difference_type = ptrdiff_t; - //! Expose underlying pointer to data type. - using pointer = typename accessor_type::pointer; - //! Expose reference to data type. - using reference = typename accessor_type::reference; +public: + //! Expose type used to define the extents of the data. + using extents_type = Extents; + //! Expose type used to define the layout of the data. + using layout_type = LayoutPolicy; + //! Expose type used to define the memory access model of the data. + using accessor_type = AccessorPolicy; + //! Expose type used to map multidimensional indices to one-dimensioal indices. + using mapping_type = typename layout_type::template mapping; + //! Exposes the type of stored element. + using element_type = typename accessor_type::element_type; + //! Expose the underlying type of the stored elements. + using value_type = std::remove_cv_t; + //! Expose the type used for indexing. + using index_type = ptrdiff_t; + //! Expose type for index differences. + using difference_type = ptrdiff_t; + //! Expose underlying pointer to data type. + using pointer = typename accessor_type::pointer; + //! Expose reference to data type. + using reference = typename accessor_type::reference; - //! Trivial constructor - constexpr basic_mdspan() noexcept : acc_(), map_(), ptr_() {} - //! Move constructor - constexpr basic_mdspan(basic_mdspan &&other) noexcept = default; - //! copy constructor - constexpr basic_mdspan(const basic_mdspan &other) noexcept = default; - //! Copy assignment - basic_mdspan &operator=(const basic_mdspan &other) noexcept = default; - //! Move assignment - basic_mdspan &operator=(basic_mdspan &&other) noexcept = default; + //! Trivial constructor + constexpr basic_mdspan() noexcept : acc_(), map_(), ptr_() {} + //! Move constructor + constexpr basic_mdspan(basic_mdspan&& other) noexcept = default; + //! copy constructor + constexpr basic_mdspan(const basic_mdspan& other) noexcept = default; + //! Copy assignment + basic_mdspan& operator=(const basic_mdspan& other) noexcept = default; + //! Move assignment + basic_mdspan& operator=(basic_mdspan&& other) noexcept = default; - //! Copy constructor - template - constexpr basic_mdspan( - const basic_mdspan &rhs ) noexcept - : acc_( rhs.acc_ ), - map_( rhs.map_ ), - ptr_( rhs.ptr_ ) - {} - //! Copy assignment constructor - template - basic_mdspan &operator= ( - const basic_mdspan &rhs ) noexcept - { acc_ = rhs.acc_; map_ = rhs.map_; ptr_ = rhs.ptr_; return *this; } + //! Copy constructor + template + constexpr basic_mdspan( + const basic_mdspan& rhs) noexcept : + acc_(rhs.acc_), + map_(rhs.map_), + ptr_(rhs.ptr_) + { + } + //! Copy assignment constructor + template + basic_mdspan& + operator=(const basic_mdspan& rhs) noexcept + { + acc_ = rhs.acc_; + map_ = rhs.map_; + ptr_ = rhs.ptr_; + return *this; + } - /*!\brief Construct mdspan by setting the dynamic extents and pointer to data. - * \param[in] ptr Pointer to data to be accessed by this span - * \param[in] DynamicExtents - * \tparam IndexType index type to describe dynamic extents - */ - template - explicit constexpr basic_mdspan - ( pointer ptr, IndexType ... DynamicExtents ) noexcept - : acc_(accessor_type()), map_( extents_type(DynamicExtents ...) ), ptr_(ptr) {} - /*! \brief Construct from array describing dynamic extents. - * \param[in] ptr Pointer to data to be accessed by this span - * \param[in] dynamic_extents Array the size of dynamic extents. - */ - constexpr basic_mdspan( pointer ptr, const std::array &dynamic_extents) - : acc_(accessor_type()), map_( extents_type(dynamic_extents)), ptr_(ptr) {} - /*! \brief Construct from pointer and mapping. - * \param[in] ptr Pointer to data to be accessed by this span - * \param[in] m Mapping from multidimenisonal indices to one-dimensional offset. - */ - constexpr basic_mdspan( pointer ptr, const mapping_type &m ) noexcept - : acc_(accessor_type()), map_( m ), ptr_(ptr) {} - /*! \brief Construct with pointer, mapping and accessor. - * \param[in] ptr Pointer to data to be accessed by this span - * \param[in] m Mapping from multidimenisonal indices to one-dimensional offset. - * \param[in] a Accessor implementing memory access model. - */ - constexpr basic_mdspan( pointer ptr, const mapping_type &m, const accessor_type &a ) noexcept - : acc_(a), map_( m ), ptr_(ptr) {} - /*! \brief Construct mdspan from multidimensional arrays implemented with mdspan - * - * Requires the container to have a view_type describing the mdspan, which is - * accessible through an asView() call - * - * This allows functions to declare mdspans as arguments, but take e.g. multidimensional - * arrays implicitly during the function call - * \tparam U container type - * \param[in] other mdspan-implementing container - */ - template::view_type::element_type, - ElementType>::value> > - constexpr basic_mdspan(U &&other) : basic_mdspan(other.asView()) {} - /*! \brief Construct mdspan of const Elements from multidimensional arrays implemented with mdspan - * - * Requires the container to have a const_view_type describing the mdspan, which is - * accessible through an asConstView() call - * - * This allows functions to declare mdspans as arguments, but take e.g. multidimensional - * arrays implicitly during the function call - * \tparam U container type - * \param[in] other mdspan-implementing container - */ - template::const_view_type::element_type, - ElementType>::value> > - constexpr basic_mdspan(const U &other) : basic_mdspan(other.asConstView()) {} - /*! \brief Brace operator to access multidimensional array element. - * \param[in] indices The multidimensional indices of the object. - * Requires rank() == sizeof...(IndexType). Slicing is implemented via sub_span. - * \returns reference to element at indices. - */ - template - constexpr std::enable_if_t - operator()( IndexType... indices) const noexcept - { return acc_.access( ptr_, map_( indices ... ) ); } - /*! \brief Canonical bracket operator for one-dimensional arrays. - * Allows mdspan to act like array in one-dimension. - * Enabled only when rank==1. - * \param[in] i one-dimensional index - * \returns reference to element stored at position i - */ - template - constexpr std::enable_if_t::value && - extents_type::rank() == 1, reference> - operator[]( const IndexType &i ) const noexcept - { return acc_.access( ptr_, map_(i) ); } - /*! \brief Bracket operator for multi-dimensional arrays. - * - * \note Prefer operator() for better compile-time and run-time performance - * - * Slices two- and higher-dimensional arrays along a given slice by - * returning a new basic_mdspan that drops the first extent and indexes - * the remaining extents - * - * \note Currently only implemented for layout_right - * \note For layout_right this implementation has significant - * performance benefits over implementing a more general slicing - * operator with a strided layout - * \note Enabled only when rank() > 1 - * - * \tparam IndexType integral tyoe for the index that enables indexing - * with, e.g., int or size_t - * \param[in] index one-dimensional index of the slice to be indexed - * - * \returns basic_mdspan that is sliced at the given index - */ - template > - constexpr std::enable_if_t::value && - (extents_type::rank() > 1) && - std::is_same::value, - sliced_mdspan_type> operator[](const IndexType index) const noexcept - { - return sliced_mdspan_type(ptr_ + index * stride(0), - extents().sliced_extents()); - } - //! Report the rank. - static constexpr int rank() noexcept - { return extents_type::rank(); } - //! Report the dynamic rank. - static constexpr int rank_dynamic() noexcept - { return extents_type::rank_dynamic(); } - /*! \brief Return the static extent. - * \param[in] k dimension to query for static extent - * \returns static extent along specified dimension - */ - constexpr index_type static_extent( size_t k ) const noexcept - { return map_.extents().static_extent( k ); } + /*!\brief Construct mdspan by setting the dynamic extents and pointer to data. + * \param[in] ptr Pointer to data to be accessed by this span + * \param[in] DynamicExtents + * \tparam IndexType index type to describe dynamic extents + */ + template + explicit constexpr basic_mdspan(pointer ptr, IndexType... DynamicExtents) noexcept : + acc_(accessor_type()), + map_(extents_type(DynamicExtents...)), + ptr_(ptr) + { + } + /*! \brief Construct from array describing dynamic extents. + * \param[in] ptr Pointer to data to be accessed by this span + * \param[in] dynamic_extents Array the size of dynamic extents. + */ + constexpr basic_mdspan(pointer ptr, + const std::array& dynamic_extents) : + acc_(accessor_type()), + map_(extents_type(dynamic_extents)), + ptr_(ptr) + { + } + /*! \brief Construct from pointer and mapping. + * \param[in] ptr Pointer to data to be accessed by this span + * \param[in] m Mapping from multidimenisonal indices to one-dimensional offset. + */ + constexpr basic_mdspan(pointer ptr, const mapping_type& m) noexcept : + acc_(accessor_type()), + map_(m), + ptr_(ptr) + { + } + /*! \brief Construct with pointer, mapping and accessor. + * \param[in] ptr Pointer to data to be accessed by this span + * \param[in] m Mapping from multidimenisonal indices to one-dimensional offset. + * \param[in] a Accessor implementing memory access model. + */ + constexpr basic_mdspan(pointer ptr, const mapping_type& m, const accessor_type& a) noexcept : + acc_(a), + map_(m), + ptr_(ptr) + { + } + /*! \brief Construct mdspan from multidimensional arrays implemented with mdspan + * + * Requires the container to have a view_type describing the mdspan, which is + * accessible through an asView() call + * + * This allows functions to declare mdspans as arguments, but take e.g. multidimensional + * arrays implicitly during the function call + * \tparam U container type + * \param[in] other mdspan-implementing container + */ + template::view_type::element_type, ElementType>::value>> + constexpr basic_mdspan(U&& other) : basic_mdspan(other.asView()) + { + } + /*! \brief Construct mdspan of const Elements from multidimensional arrays implemented with mdspan + * + * Requires the container to have a const_view_type describing the mdspan, which is + * accessible through an asConstView() call + * + * This allows functions to declare mdspans as arguments, but take e.g. multidimensional + * arrays implicitly during the function call + * \tparam U container type + * \param[in] other mdspan-implementing container + */ + template::const_view_type::element_type, ElementType>::value>> + constexpr basic_mdspan(const U& other) : basic_mdspan(other.asConstView()) + { + } + /*! \brief Brace operator to access multidimensional array element. + * \param[in] indices The multidimensional indices of the object. + * Requires rank() == sizeof...(IndexType). Slicing is implemented via sub_span. + * \returns reference to element at indices. + */ + template + constexpr std::enable_if_t + operator()(IndexType... indices) const noexcept + { + return acc_.access(ptr_, map_(indices...)); + } + /*! \brief Canonical bracket operator for one-dimensional arrays. + * Allows mdspan to act like array in one-dimension. + * Enabled only when rank==1. + * \param[in] i one-dimensional index + * \returns reference to element stored at position i + */ + template + constexpr std::enable_if_t::value && extents_type::rank() == 1, reference> + operator[](const IndexType& i) const noexcept + { + return acc_.access(ptr_, map_(i)); + } + /*! \brief Bracket operator for multi-dimensional arrays. + * + * \note Prefer operator() for better compile-time and run-time performance + * + * Slices two- and higher-dimensional arrays along a given slice by + * returning a new basic_mdspan that drops the first extent and indexes + * the remaining extents + * + * \note Currently only implemented for layout_right + * \note For layout_right this implementation has significant + * performance benefits over implementing a more general slicing + * operator with a strided layout + * \note Enabled only when rank() > 1 + * + * \tparam IndexType integral tyoe for the index that enables indexing + * with, e.g., int or size_t + * \param[in] index one-dimensional index of the slice to be indexed + * + * \returns basic_mdspan that is sliced at the given index + */ + template> + constexpr std::enable_if_t::value && (extents_type::rank() > 1) + && std::is_same::value, + sliced_mdspan_type> + operator[](const IndexType index) const noexcept + { + return sliced_mdspan_type(ptr_ + index * stride(0), extents().sliced_extents()); + } + //! Report the rank. + static constexpr int rank() noexcept { return extents_type::rank(); } + //! Report the dynamic rank. + static constexpr int rank_dynamic() noexcept { return extents_type::rank_dynamic(); } + /*! \brief Return the static extent. + * \param[in] k dimension to query for static extent + * \returns static extent along specified dimension + */ + constexpr index_type static_extent(size_t k) const noexcept + { + return map_.extents().static_extent(k); + } - /*! \brief Return the extent. - * \param[in] k dimension to query for extent - * \returns extent along specified dimension - */ - constexpr index_type extent( int k ) const noexcept - { return map_.extents().extent( k ); } + /*! \brief Return the extent. + * \param[in] k dimension to query for extent + * \returns extent along specified dimension + */ + constexpr index_type extent(int k) const noexcept { return map_.extents().extent(k); } - //! Return all extents - constexpr const extents_type &extents() const noexcept - { return map_.extents(); } - //! Report if mappings for this basic_span is always unique. - static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); } - //! Report if mapping for this basic_span is always strided - static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); } - //! Report if mapping for this basic_span is always is_contiguous - static constexpr bool is_always_contiguous() noexcept { return mapping_type::is_always_contiguous(); } - //! Report if the currently applied map is unique - constexpr bool is_unique() const noexcept { return map_.is_unique(); } - //! Report if the currently applied map is strided - constexpr bool is_strided() const noexcept { return map_.is_strided(); } - //! Report if the currently applied map is contiguous - constexpr bool is_contiguous() const noexcept {return map_.is_contiguous(); } - //! Report stride along a specific rank. - constexpr index_type stride( size_t r ) const noexcept - { return map_.stride(r); } - //! Return the currently applied mapping. - constexpr mapping_type mapping() const noexcept { return map_; } - //! Return the memory access model. - constexpr accessor_type accessor() const noexcept { return acc_; } - //! Return pointer to underlying data - constexpr pointer data() const noexcept { return ptr_; } - private: - //! The memory access model - accessor_type acc_; - //! The transformation from multidimenisonal index to memory offset. - mapping_type map_; - //! Memory location handle - pointer ptr_; + //! Return all extents + constexpr const extents_type& extents() const noexcept { return map_.extents(); } + //! Report if mappings for this basic_span is always unique. + static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); } + //! Report if mapping for this basic_span is always strided + static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); } + //! Report if mapping for this basic_span is always is_contiguous + static constexpr bool is_always_contiguous() noexcept + { + return mapping_type::is_always_contiguous(); + } + //! Report if the currently applied map is unique + constexpr bool is_unique() const noexcept { return map_.is_unique(); } + //! Report if the currently applied map is strided + constexpr bool is_strided() const noexcept { return map_.is_strided(); } + //! Report if the currently applied map is contiguous + constexpr bool is_contiguous() const noexcept { return map_.is_contiguous(); } + //! Report stride along a specific rank. + constexpr index_type stride(size_t r) const noexcept { return map_.stride(r); } + //! Return the currently applied mapping. + constexpr mapping_type mapping() const noexcept { return map_; } + //! Return the memory access model. + constexpr accessor_type accessor() const noexcept { return acc_; } + //! Return pointer to underlying data + constexpr pointer data() const noexcept { return ptr_; } + +private: + //! The memory access model + accessor_type acc_; + //! The transformation from multidimenisonal index to memory offset. + mapping_type map_; + //! Memory location handle + pointer ptr_; }; //! basic_mdspan with wrapped indices, basic_accessor policiy and right-aligned memory layout. template -using mdspan = basic_mdspan, layout_right, accessor_basic >; +using mdspan = basic_mdspan, layout_right, accessor_basic>; -} // namespace gmx +} // namespace gmx #endif /* end of include guard: MDSPAN_MDSPAN_H */ diff --git a/src/gromacs/mdspan/tests/accessor_policy.cpp b/src/gromacs/mdspan/tests/accessor_policy.cpp index e604a5f3f0..4050cd0426 100644 --- a/src/gromacs/mdspan/tests/accessor_policy.cpp +++ b/src/gromacs/mdspan/tests/accessor_policy.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,30 +50,34 @@ namespace gmx class BasicAccessorPolicy : public ::testing::Test { - public: - std::array testdata = {{1., 2., 3.}}; - accessor_basic acc; +public: + std::array testdata = { { 1., 2., 3. } }; + accessor_basic acc; }; -TEST_F(BasicAccessorPolicy, Decay) { +TEST_F(BasicAccessorPolicy, Decay) +{ EXPECT_EQ(acc.decay(testdata.data()), testdata.data()); } -TEST_F(BasicAccessorPolicy, Access) { +TEST_F(BasicAccessorPolicy, Access) +{ for (size_t i = 0; i < testdata.size(); ++i) { EXPECT_EQ(acc.access(testdata.data(), i), testdata[i]); } } -TEST_F(BasicAccessorPolicy, Offset) { +TEST_F(BasicAccessorPolicy, Offset) +{ for (size_t i = 0; i < testdata.size(); ++i) { - EXPECT_EQ(acc.offset(testdata.data(), i), testdata.data() + i ); + EXPECT_EQ(acc.offset(testdata.data(), i), testdata.data() + i); } } -TEST_F(BasicAccessorPolicy, CopyAccessor) { +TEST_F(BasicAccessorPolicy, CopyAccessor) +{ const auto newAcc = acc; EXPECT_EQ(acc.decay(testdata.data()), newAcc.decay(testdata.data())); diff --git a/src/gromacs/mdspan/tests/extensions.cpp b/src/gromacs/mdspan/tests/extensions.cpp index 009ea92dde..5ace1e7f59 100644 --- a/src/gromacs/mdspan/tests/extensions.cpp +++ b/src/gromacs/mdspan/tests/extensions.cpp @@ -58,10 +58,8 @@ namespace gmx TEST(MdSpanExtension, SlicingAllStatic) { - std::array data = {1, 2, 3, 4, 5, 6}; - basic_mdspan > span { - data.data() - }; + std::array data = { 1, 2, 3, 4, 5, 6 }; + basic_mdspan> span{ data.data() }; EXPECT_EQ(span[0][0], 1); EXPECT_EQ(span[0][1], 2); @@ -74,10 +72,8 @@ TEST(MdSpanExtension, SlicingAllStatic) TEST(MdSpanExtension, SlicingDynamic) { - std::array data = {1, 2, 3, 4, 5, 6}; - basic_mdspan > span { - data.data(), 2, 2 - }; + std::array data = { 1, 2, 3, 4, 5, 6 }; + basic_mdspan> span{ data.data(), 2, 2 }; EXPECT_EQ(span[0][0], 1); EXPECT_EQ(span[0][1], 2); @@ -91,11 +87,8 @@ TEST(MdSpanExtension, SlicingDynamic) TEST(MdSpanExtension, SlicingAllStatic3D) { - std::array data = {1, 2, 3, 4, 5, 6, 7, 8 }; - basic_mdspan > - span { - data.data() - }; + std::array data = { 1, 2, 3, 4, 5, 6, 7, 8 }; + basic_mdspan> span{ data.data() }; EXPECT_EQ(span[0][0][0], 1); EXPECT_EQ(span[0][0][1], 2); @@ -107,15 +100,12 @@ TEST(MdSpanExtension, SlicingAllStatic3D) EXPECT_EQ(span[1][1][0], 7); EXPECT_EQ(span[1][1][1], 8); - } TEST(MdSpanExtension, SlicingEqualsView3D) { - std::array data = {1, 2, 3, 4, 5, 6, 7, 8}; - basic_mdspan > span { - data.data() - }; + std::array data = { 1, 2, 3, 4, 5, 6, 7, 8 }; + basic_mdspan> span{ data.data() }; EXPECT_EQ(span[0][0][0], span(0, 0, 0)); EXPECT_EQ(span[0][0][1], span(0, 0, 1)); EXPECT_EQ(span[0][1][0], span(0, 1, 0)); @@ -128,33 +118,25 @@ TEST(MdSpanExtension, SlicingEqualsView3D) TEST(MdSpanExtension, additionWorks) { - std::array arr1 = {{-4, -3, -2, -1, 0, 1, 2, 3}}; - std::array arr2 = {{1, 1, 1, 1, 1, 1, 1, 1}}; - basic_mdspan > span1 { - arr1.data() - }; - basic_mdspan > span2 { - arr2.data() - }; - - auto result = addElementwise(span1, span2); + std::array arr1 = { { -4, -3, -2, -1, 0, 1, 2, 3 } }; + std::array arr2 = { { 1, 1, 1, 1, 1, 1, 1, 1 } }; + basic_mdspan> span1{ arr1.data() }; + basic_mdspan> span2{ arr2.data() }; + + auto result = addElementwise(span1, span2); EXPECT_EQ(result[0][0][1], -2); EXPECT_EQ(result[0][1][0], -1); - EXPECT_EQ(result[1][0][0], 1); + EXPECT_EQ(result[1][0][0], 1); } TEST(MdSpanExtension, subtractionWorks) { - std::array arr1 = {{-4, -3, -2, -1, 0, 1, 2, 3}}; - std::array arr2 = {{1, 1, 1, 1, 1, 1, 1, 1}}; - basic_mdspan > span1 { - arr1.data() - }; - basic_mdspan > span2 { - arr2.data() - }; - - auto result = subtractElementwise(span1, span2); + std::array arr1 = { { -4, -3, -2, -1, 0, 1, 2, 3 } }; + std::array arr2 = { { 1, 1, 1, 1, 1, 1, 1, 1 } }; + basic_mdspan> span1{ arr1.data() }; + basic_mdspan> span2{ arr2.data() }; + + auto result = subtractElementwise(span1, span2); EXPECT_EQ(result[0][0][1], -4); EXPECT_EQ(result[0][1][0], -3); EXPECT_EQ(result[1][0][0], -1); @@ -162,35 +144,44 @@ TEST(MdSpanExtension, subtractionWorks) TEST(MdSpanExtension, multiplicationWorks) { - std::array arr1 = {{-4, -3, -2, -1, 0, 1, 2, 3}}; - std::array arr2 = {{2, 2, 2, 2, 2, 2, 2, }}; - basic_mdspan > span1 { - arr1.data() - }; - basic_mdspan > span2 { - arr2.data() - }; - - auto result = multiplyElementwise(span1, span2); + std::array arr1 = { { -4, -3, -2, -1, 0, 1, 2, 3 } }; + std::array arr2 = { { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + } }; + basic_mdspan> span1{ arr1.data() }; + basic_mdspan> span2{ arr2.data() }; + + auto result = multiplyElementwise(span1, span2); EXPECT_EQ(result[0][0][1], -6); EXPECT_EQ(result[0][1][0], -4); - EXPECT_EQ(result[1][0][0], 0); + EXPECT_EQ(result[1][0][0], 0); } TEST(MdSpanExtension, divisionWorks) { - std::array arr1 = {{-4, -3, -2, -1, 0, 1, 2, 3}}; - std::array arr2 = {{2, 2, 2, 2, 2, 2, 2, 2, }}; - basic_mdspan > span1 { - arr1.data() - }; - basic_mdspan > span2 { - arr2.data() - }; - - auto result = divideElementwise(span1, span2); + std::array arr1 = { { -4, -3, -2, -1, 0, 1, 2, 3 } }; + std::array arr2 = { { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + } }; + basic_mdspan> span1{ arr1.data() }; + basic_mdspan> span2{ arr2.data() }; + + auto result = divideElementwise(span1, span2); EXPECT_EQ(result[0][0][1], -1.5); EXPECT_EQ(result[0][1][0], -1); - EXPECT_EQ(result[1][0][0], 0); + EXPECT_EQ(result[1][0][0], 0); } } // namespace gmx diff --git a/src/gromacs/mdspan/tests/extents.cpp b/src/gromacs/mdspan/tests/extents.cpp index b7ccb34ffc..6d4e9c2c43 100644 --- a/src/gromacs/mdspan/tests/extents.cpp +++ b/src/gromacs/mdspan/tests/extents.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -92,72 +92,72 @@ namespace gmx { -template +template class ExtentsTest { - public: - using extents_type = gmx::extents; +public: + using extents_type = gmx::extents; - extents_type my_extents_explicit; - extents_type my_extents_array; - extents_type my_extents_copy; + extents_type my_extents_explicit; + extents_type my_extents_array; + extents_type my_extents_copy; - ExtentsTest() - { - my_extents_explicit = extents(); - my_extents_array = extents(std::array()); - my_extents_copy = extents(my_extents_explicit); - } + ExtentsTest() + { + my_extents_explicit = extents(); + my_extents_array = extents(std::array()); + my_extents_copy = extents(my_extents_explicit); + } - template - ExtentsTest(E ... e) - { - my_extents_explicit = extents(e ...); - my_extents_array = extents(std::array({{e ...}})); - my_extents_copy = extents(my_extents_explicit); - } + template + ExtentsTest(E... e) + { + my_extents_explicit = extents(e...); + my_extents_array = extents(std::array({ { e... } })); + my_extents_copy = extents(my_extents_explicit); + } - void check_rank(ptrdiff_t r) - { - EXPECT_EQ(my_extents_explicit.rank(), r); - EXPECT_EQ(my_extents_array.rank(), r); - EXPECT_EQ(my_extents_copy.rank(), r); - } - void check_rank_dynamic(ptrdiff_t r) - { - EXPECT_EQ(my_extents_explicit.rank_dynamic(), r); - EXPECT_EQ(my_extents_array.rank_dynamic(), r); - EXPECT_EQ(my_extents_copy.rank_dynamic(), r); - } - template - void check_extents(E ... e) + void check_rank(ptrdiff_t r) + { + EXPECT_EQ(my_extents_explicit.rank(), r); + EXPECT_EQ(my_extents_array.rank(), r); + EXPECT_EQ(my_extents_copy.rank(), r); + } + void check_rank_dynamic(ptrdiff_t r) + { + EXPECT_EQ(my_extents_explicit.rank_dynamic(), r); + EXPECT_EQ(my_extents_array.rank_dynamic(), r); + EXPECT_EQ(my_extents_copy.rank_dynamic(), r); + } + template + void check_extents(E... e) + { + std::array s = { { E_STATIC... } }; + std::array a = { { e... } }; + for (size_t r = 0; r < extents_type::rank(); r++) { - std::array s = {{E_STATIC ...}}; - std::array a = {{e ...}}; - for (size_t r = 0; r < extents_type::rank(); r++) - { - EXPECT_EQ(my_extents_explicit.static_extent(r), s[r]); - EXPECT_EQ(my_extents_explicit.extent(r), a[r]); - - EXPECT_EQ(my_extents_array.static_extent(r), s[r]); - EXPECT_EQ(my_extents_array.extent(r), a[r]); - - EXPECT_EQ(my_extents_copy.static_extent(r), s[r]); - EXPECT_EQ(my_extents_copy.extent(r), a[r]); - } - EXPECT_EQ(my_extents_explicit.static_extent(extents_type::rank()+1), 1); - EXPECT_EQ(my_extents_explicit.extent(extents_type::rank()+1), 1); - - EXPECT_EQ(my_extents_array.static_extent(extents_type::rank()+1), 1); - EXPECT_EQ(my_extents_array.extent(extents_type::rank()+1), 1); - - EXPECT_EQ(my_extents_copy.static_extent(extents_type::rank()+1), 1); - EXPECT_EQ(my_extents_copy.extent(extents_type::rank()+1), 1); + EXPECT_EQ(my_extents_explicit.static_extent(r), s[r]); + EXPECT_EQ(my_extents_explicit.extent(r), a[r]); + + EXPECT_EQ(my_extents_array.static_extent(r), s[r]); + EXPECT_EQ(my_extents_array.extent(r), a[r]); + + EXPECT_EQ(my_extents_copy.static_extent(r), s[r]); + EXPECT_EQ(my_extents_copy.extent(r), a[r]); } + EXPECT_EQ(my_extents_explicit.static_extent(extents_type::rank() + 1), 1); + EXPECT_EQ(my_extents_explicit.extent(extents_type::rank() + 1), 1); + + EXPECT_EQ(my_extents_array.static_extent(extents_type::rank() + 1), 1); + EXPECT_EQ(my_extents_array.extent(extents_type::rank() + 1), 1); + EXPECT_EQ(my_extents_copy.static_extent(extents_type::rank() + 1), 1); + EXPECT_EQ(my_extents_copy.extent(extents_type::rank() + 1), 1); + } }; -TEST(ExtentsTest, Construction) { +TEST(ExtentsTest, Construction) +{ // setting two dynamic extents ExtentsTest<5, dynamic_extent, 3, dynamic_extent, 1> test(4, 2); @@ -165,34 +165,37 @@ TEST(ExtentsTest, Construction) { test.check_rank(5); test.check_rank_dynamic(2); test.check_extents(5, 4, 3, 2, 1); - } -TEST(ExtentsTest, PurelyStatic) { +TEST(ExtentsTest, PurelyStatic) +{ ExtentsTest<5, 4, 3> test; test.check_rank(3); test.check_rank_dynamic(0); test.check_extents(5, 4, 3); } -TEST(ExtentsTest, RankNought) { +TEST(ExtentsTest, RankNought) +{ // Can construct extents of rank nought ExtentsTest<> test; test.check_rank(0); test.check_rank_dynamic(0); } -TEST(ExtentsTest, Assignment) { +TEST(ExtentsTest, Assignment) +{ extents<5, dynamic_extent, 3, dynamic_extent, 1> e1(4, 2); - extents<5, 4, 3, 2, 1> e2; + extents<5, 4, 3, 2, 1> e2; e2 = e1; for (size_t r = 0; r < 5; r++) { EXPECT_EQ(e2.extent(r), e1.extent(r)); } - extents e3(9, 8, 7, 6, 5); + extents e3( + 9, 8, 7, 6, 5); for (int r = 0; r < 5; r++) { - EXPECT_EQ(e3.extent(r), 9-r); + EXPECT_EQ(e3.extent(r), 9 - r); } e3 = e1; for (int r = 0; r < 5; r++) diff --git a/src/gromacs/mdspan/tests/layouts.cpp b/src/gromacs/mdspan/tests/layouts.cpp index bf1c0c6d77..c7f5be2c6f 100644 --- a/src/gromacs/mdspan/tests/layouts.cpp +++ b/src/gromacs/mdspan/tests/layouts.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,19 +50,20 @@ namespace gmx { -template -struct LayoutTests { +template +struct LayoutTests +{ - typedef Layout layout_type; - typedef extents extents_type; + typedef Layout layout_type; + typedef extents extents_type; typedef typename Layout::template mapping mapping_type; mapping_type my_mapping_explicit, my_mapping_copy; - template - LayoutTests(E ... e) + template + LayoutTests(E... e) { - my_mapping_explicit = mapping_type(extents_type(e ...)); + my_mapping_explicit = mapping_type(extents_type(e...)); my_mapping_copy = mapping_type(my_mapping_explicit); } @@ -76,20 +77,20 @@ struct LayoutTests { EXPECT_EQ(my_mapping_explicit.extents().rank_dynamic(), r); EXPECT_EQ(my_mapping_copy.extents().rank_dynamic(), r); } - template - void check_extents(E ... e) + template + void check_extents(E... e) { - std::array a = {{e ...}}; + std::array a = { { e... } }; for (size_t r = 0; r < extents_type::rank(); r++) { EXPECT_EQ(my_mapping_explicit.extents().extent(r), a[r]); EXPECT_EQ(my_mapping_copy.extents().extent(r), a[r]); } } - template - void check_strides(E ... e) + template + void check_strides(E... e) { - std::array a = {{e ...}}; + std::array a = { { e... } }; for (size_t r = 0; r < extents_type::rank(); r++) { EXPECT_EQ(my_mapping_explicit.stride(r), a[r]); @@ -102,8 +103,12 @@ struct LayoutTests { EXPECT_EQ(my_mapping_copy.required_span_size(), size); } - void check_properties(bool always_unique, bool always_contiguous, bool always_strided, - bool unique, bool contiguous, bool strided) + void check_properties(bool always_unique, + bool always_contiguous, + bool always_strided, + bool unique, + bool contiguous, + bool strided) { EXPECT_EQ(my_mapping_explicit.is_always_unique() ? 1 : 0, always_unique ? 1 : 0); EXPECT_EQ(my_mapping_explicit.is_always_contiguous() ? 1 : 0, always_contiguous ? 1 : 0); @@ -119,16 +124,16 @@ struct LayoutTests { EXPECT_EQ(my_mapping_copy.is_strided() ? 1 : 0, strided ? 1 : 0); } - template - void check_operator(ptrdiff_t offset, E ... e) + template + void check_operator(ptrdiff_t offset, E... e) { - EXPECT_EQ(my_mapping_explicit(e ...), offset); - EXPECT_EQ(my_mapping_copy(e ...), offset); + EXPECT_EQ(my_mapping_explicit(e...), offset); + EXPECT_EQ(my_mapping_copy(e...), offset); } - }; -TEST(LayoutTests, LayoutRightConstruction) { +TEST(LayoutTests, LayoutRightConstruction) +{ LayoutTests test(4, 2); test.check_rank(5); @@ -137,13 +142,15 @@ TEST(LayoutTests, LayoutRightConstruction) { test.check_strides(24, 6, 2, 1, 1); } -TEST(LayoutTests, LayoutRightProperties) { +TEST(LayoutTests, LayoutRightProperties) +{ LayoutTests test(4, 2); test.check_properties(true, true, true, true, true, true); } -TEST(LayoutTests, LayoutRightOperator) { +TEST(LayoutTests, LayoutRightOperator) +{ LayoutTests test(4, 2); test.check_operator(107, 4, 1, 2, 1, 0); diff --git a/src/gromacs/mdspan/tests/mdspan.cpp b/src/gromacs/mdspan/tests/mdspan.cpp index bb98daa7dc..c61c5598f2 100644 --- a/src/gromacs/mdspan/tests/mdspan.cpp +++ b/src/gromacs/mdspan/tests/mdspan.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -103,21 +103,24 @@ namespace // a multidimensional array of extent 5 x 4 x 3 x 2 x 1, i.e. 120 elements //! View on int data with mixed static and dynamic extents -using mdspan_int = basic_mdspan < int, extents<5, dynamic_extent, 3, dynamic_extent, 1>, layout_right, accessor_basic < int>>; +using mdspan_int = + basic_mdspan, layout_right, accessor_basic>; TEST(MdSpanTest, MdSpanWrapsBasicMdSpanCorrectly) { // Check that mdspan wraps basic_mdspan as expected - ::testing::StaticAssertTypeEq < mdspan_int, mdspan < int, 5, dynamic_extent, 3, dynamic_extent, 1>>(); + ::testing::StaticAssertTypeEq>(); } //! View on float data with mixed static and dynamic extents -using mdspan_float = basic_mdspan < float, extents<5, dynamic_extent, 3, dynamic_extent, 1>, layout_right, accessor_basic < float>>; +using mdspan_float = + basic_mdspan, layout_right, accessor_basic>; //! Types to be tested -using MdSpanTypes = ::testing::Types < mdspan_int, mdspan_float>; +using MdSpanTypes = ::testing::Types; template -struct fill_raw_data { +struct fill_raw_data +{ static void fill(ElementType* p, Mapping m) { typename Mapping::extents_type e = m.extents(); @@ -131,8 +134,9 @@ struct fill_raw_data { { for (ptrdiff_t i4 = 0; i4 < e.extent(4); i4++) { - p[i0*m.stride(0)+i1*m.stride(1)+i2*m.stride(2)+i3*m.stride(3)+i4*m.stride(4)] = - ElementType(i0*10000+i1*1000+i2*100+i3*10+i4); + p[i0 * m.stride(0) + i1 * m.stride(1) + i2 * m.stride(2) + + i3 * m.stride(3) + i4 * m.stride(4)] = + ElementType(i0 * 10000 + i1 * 1000 + i2 * 100 + i3 * 10 + i4); } } } @@ -150,27 +154,27 @@ struct MdSpanTest : public ::testing::Test using accessor_type = typename mdspan_type::accessor_type; using pointer_type = typename mdspan_type::pointer; - mdspan_type my_mdspan_extents; - mdspan_type my_mdspan_array; - mdspan_type my_mdspan_mapping; - mdspan_type my_mdspan_map_acc; - mdspan_type my_mdspan_copy; + mdspan_type my_mdspan_extents; + mdspan_type my_mdspan_array; + mdspan_type my_mdspan_mapping; + mdspan_type my_mdspan_map_acc; + mdspan_type my_mdspan_copy; std::vector rawData; - template - void SetUp(ED ... e) + template + void SetUp(ED... e) { - mapping_type map {extents_type(e ...)}; + mapping_type map{ extents_type(e...) }; accessor_type acc; rawData.resize(map.required_span_size()); fill_raw_data::fill(rawData.data(), map); - pointer_type p(rawData.data()); + pointer_type p(rawData.data()); - my_mdspan_array = mdspan_type(p, std::array({{e ...}})); + my_mdspan_array = mdspan_type(p, std::array({ { e... } })); my_mdspan_mapping = mdspan_type(p, map); my_mdspan_map_acc = mdspan_type(p, map, acc); - my_mdspan_extents = mdspan_type(p, e ...); + my_mdspan_extents = mdspan_type(p, e...); my_mdspan_copy = my_mdspan_mapping; } @@ -188,10 +192,10 @@ struct MdSpanTest : public ::testing::Test EXPECT_EQ(my_mdspan_extents.rank_dynamic(), r); EXPECT_EQ(my_mdspan_copy.rank_dynamic(), r); } - template - void check_extents(E ... e) + template + void check_extents(E... e) { - std::array a {{e ...}}; + std::array a{ { e... } }; for (size_t r = 0; r < extents_type::rank(); r++) { EXPECT_EQ(my_mdspan_mapping.extent(r), a[r]); @@ -200,10 +204,10 @@ struct MdSpanTest : public ::testing::Test EXPECT_EQ(my_mdspan_copy.extent(r), a[r]); } } - template - void check_strides(E ... e) + template + void check_strides(E... e) { - std::array a {{e ...}}; + std::array a{ { e... } }; for (size_t r = 0; r < extents_type::rank(); r++) { EXPECT_EQ(my_mdspan_mapping.stride(r), a[r]); @@ -213,8 +217,13 @@ struct MdSpanTest : public ::testing::Test } } - void check_properties_internal(mdspan_type my_mdspan, bool always_unique, bool always_contiguous, bool always_strided, - bool unique, bool contiguous, bool strided) + void check_properties_internal(mdspan_type my_mdspan, + bool always_unique, + bool always_contiguous, + bool always_strided, + bool unique, + bool contiguous, + bool strided) { EXPECT_EQ(my_mdspan.is_always_unique(), always_unique); EXPECT_EQ(my_mdspan.is_always_contiguous(), always_contiguous); @@ -224,13 +233,21 @@ struct MdSpanTest : public ::testing::Test EXPECT_EQ(my_mdspan.is_strided(), strided); } - void check_properties(bool always_unique, bool always_contiguous, bool always_strided, - bool unique, bool contiguous, bool strided) + void check_properties(bool always_unique, + bool always_contiguous, + bool always_strided, + bool unique, + bool contiguous, + bool strided) { - check_properties_internal(my_mdspan_mapping, always_unique, always_contiguous, always_strided, unique, contiguous, strided); - check_properties_internal(my_mdspan_map_acc, always_unique, always_contiguous, always_strided, unique, contiguous, strided); - check_properties_internal(my_mdspan_extents, always_unique, always_contiguous, always_strided, unique, contiguous, strided); - check_properties_internal(my_mdspan_copy, always_unique, always_contiguous, always_strided, unique, contiguous, strided); + check_properties_internal(my_mdspan_mapping, always_unique, always_contiguous, + always_strided, unique, contiguous, strided); + check_properties_internal(my_mdspan_map_acc, always_unique, always_contiguous, + always_strided, unique, contiguous, strided); + check_properties_internal(my_mdspan_extents, always_unique, always_contiguous, + always_strided, unique, contiguous, strided); + check_properties_internal(my_mdspan_copy, always_unique, always_contiguous, always_strided, + unique, contiguous, strided); } void check_operator() @@ -246,11 +263,11 @@ struct MdSpanTest : public ::testing::Test { for (ptrdiff_t i4 = 0; i4 < e.extent(4); i4++) { - element_type value = i0*10000+i1*1000+i2*100+i3*10+i4; + element_type value = i0 * 10000 + i1 * 1000 + i2 * 100 + i3 * 10 + i4; EXPECT_EQ(my_mdspan_mapping(i0, i1, i2, i3, i4), value); EXPECT_EQ(my_mdspan_map_acc(i0, i1, i2, i3, i4), value); EXPECT_EQ(my_mdspan_extents(i0, i1, i2, i3, i4), value); - EXPECT_EQ(my_mdspan_copy (i0, i1, i2, i3, i4), value); + EXPECT_EQ(my_mdspan_copy(i0, i1, i2, i3, i4), value); } } } @@ -261,27 +278,32 @@ struct MdSpanTest : public ::testing::Test TYPED_TEST_CASE(MdSpanTest, MdSpanTypes); -TYPED_TEST(MdSpanTest, Rank) { +TYPED_TEST(MdSpanTest, Rank) +{ this->SetUp(4, 2); this->check_rank(5); } -TYPED_TEST(MdSpanTest, DynamicRank) { +TYPED_TEST(MdSpanTest, DynamicRank) +{ this->SetUp(4, 2); this->check_rank_dynamic(2); } -TYPED_TEST(MdSpanTest, Extents) { +TYPED_TEST(MdSpanTest, Extents) +{ this->SetUp(4, 2); this->check_extents(5, 4, 3, 2, 1); } -TYPED_TEST(MdSpanTest, Strides) { +TYPED_TEST(MdSpanTest, Strides) +{ this->SetUp(4, 2); this->check_strides(24, 6, 2, 1, 1); } -TYPED_TEST(MdSpanTest, Properties) { +TYPED_TEST(MdSpanTest, Properties) +{ this->SetUp(4, 2); const bool always_unique = true; const bool always_contiguous = true; @@ -292,7 +314,8 @@ TYPED_TEST(MdSpanTest, Properties) { this->check_properties(always_unique, always_contiguous, always_strided, unique, contiguous, strided); } -TYPED_TEST(MdSpanTest, Operator) { +TYPED_TEST(MdSpanTest, Operator) +{ this->SetUp(4, 2); this->check_operator(); } diff --git a/src/gromacs/mdtypes/awh_correlation_history.h b/src/gromacs/mdtypes/awh_correlation_history.h index 56fd442648..47a1fb8ed8 100644 --- a/src/gromacs/mdtypes/awh_correlation_history.h +++ b/src/gromacs/mdtypes/awh_correlation_history.h @@ -58,26 +58,28 @@ namespace gmx //! Correlation block averaging data. struct CorrelationBlockDataHistory { - double blockSumWeight; /**< Sum weights for current block. */ - double blockSumSquareWeight; /**< Sum weights^2 for current block. */ - double blockSumWeightX; /**< Weighted sum of x for current block. */ - double blockSumWeightY; /**< Weighted sum of y for current block. */ - double sumOverBlocksSquareBlockWeight; /**< Sum over all blocks in the simulation of block weight^2 over the whole simulation. */ - double sumOverBlocksBlockSquareWeight; /**< Sum over all blocks in the simulation of weight^2 over the whole simulation. */ + double blockSumWeight; /**< Sum weights for current block. */ + double blockSumSquareWeight; /**< Sum weights^2 for current block. */ + double blockSumWeightX; /**< Weighted sum of x for current block. */ + double blockSumWeightY; /**< Weighted sum of y for current block. */ + double sumOverBlocksSquareBlockWeight; /**< Sum over all blocks in the simulation of block weight^2 over the whole simulation. */ + double sumOverBlocksBlockSquareWeight; /**< Sum over all blocks in the simulation of weight^2 over the whole simulation. */ double sumOverBlocksBlockWeightBlockWeightX; /**< Sum over all blocks in the simulation of block weight times blockSumWeightX over the whole simulation. */ double sumOverBlocksBlockWeightBlockWeightY; /**< Sum over all blocks in the simulation of block weight times blockSumWeightY over the whole simulation. */ - double blockLength; /**< The length of each block used for block averaging. */ - int previousBlockIndex; /**< The last block index data was added to (needed only for block length in terms of time). */ - double correlationIntegral; /**< The time integral of the correlation function of x and y, corr(x(0), y(t)). */ + double blockLength; /**< The length of each block used for block averaging. */ + int previousBlockIndex; /**< The last block index data was added to (needed only for block length in terms of time). */ + double correlationIntegral; /**< The time integral of the correlation function of x and y, corr(x(0), y(t)). */ }; //! Grid of local correlation matrices. struct CorrelationGridHistory { /* These counts here since we curently need them for initializing the correlation grid when reading a checkpoint */ - int numCorrelationTensors = 0; /**< Number correlation tensors in the grid (equal to the number of points). */ - int tensorSize = 0; /**< The number of stored correlation matrix elements. */ - int blockDataListSize = 0; /**< To be able to increase the block length later on, data is saved for several block lengths for each element. */ + int numCorrelationTensors = + 0; /**< Number correlation tensors in the grid (equal to the number of points). */ + int tensorSize = 0; /**< The number of stored correlation matrix elements. */ + int blockDataListSize = + 0; /**< To be able to increase the block length later on, data is saved for several block lengths for each element. */ /* We store all tensor sequentially in a buffer */ std::vector blockDataBuffer; /**< Buffer that contains the correlation data. */ @@ -93,11 +95,11 @@ struct CorrelationGridHistory * \param[in] tensorSize Number of correlation elements in each tensor. * \param[in] blockDataListSize The number of blocks in the list of each tensor element. */ -void initCorrelationGridHistory(CorrelationGridHistory *correlationGridHistory, +void initCorrelationGridHistory(CorrelationGridHistory* correlationGridHistory, int numCorrelationTensors, int tensorSize, int blockDataListSize); -} // namespace gmx +} // namespace gmx #endif /* GMX_MDTYPES_AWH_CORRELATION_HISTORY_H */ diff --git a/src/gromacs/mdtypes/awh_history.h b/src/gromacs/mdtypes/awh_history.h index b33f7e5a33..3b55749313 100644 --- a/src/gromacs/mdtypes/awh_history.h +++ b/src/gromacs/mdtypes/awh_history.h @@ -60,42 +60,43 @@ namespace gmx //! Grid point state history data. struct AwhPointStateHistory { - double bias; /**< Current biasing function estimate */ - double free_energy; /**< Current estimate of the convolved free energy/PMF. */ - double target; /**< Current target distribution, normalized to 1 */ - double weightsum_iteration; /**< Accumulated weight this iteration (1 replica) */ - double weightsum_covering; /**< Accumulated weights for covering checks */ - double weightsum_tot; /**< Accumulated weights, never reset */ - double weightsum_ref; /**< The reference weight histogram determining the f updates */ - int64_t last_update_index; /**< The last update that was performed at this point. */ - double log_pmfsum; /**< Logarithm of the PMF histogram (for 1 replica) */ - double visits_iteration; /**< Visits to this bin this iteration (1 replica) */ - double visits_tot; /**< Accumulated visits to this bin */ + double bias; /**< Current biasing function estimate */ + double free_energy; /**< Current estimate of the convolved free energy/PMF. */ + double target; /**< Current target distribution, normalized to 1 */ + double weightsum_iteration; /**< Accumulated weight this iteration (1 replica) */ + double weightsum_covering; /**< Accumulated weights for covering checks */ + double weightsum_tot; /**< Accumulated weights, never reset */ + double weightsum_ref; /**< The reference weight histogram determining the f updates */ + int64_t last_update_index; /**< The last update that was performed at this point. */ + double log_pmfsum; /**< Logarithm of the PMF histogram (for 1 replica) */ + double visits_iteration; /**< Visits to this bin this iteration (1 replica) */ + double visits_tot; /**< Accumulated visits to this bin */ }; //! The global AWH bias history state, contains most data of the corresponding struct in awh.h. struct AwhBiasStateHistory { - int umbrellaGridpoint; /**< Index for the current umbrella reference coordinate point (for umbrella potential type) */ - int origin_index_updatelist; /**< Point index of the origin of the subgrid that has been touched since last update. */ - int end_index_updatelist; /**< Point index of the end of the subgrid that has been touched since last update. */ - bool in_initial; /**< True if in the intial stage. */ - bool equilibrateHistogram; /**< True if histogram needs equilibration. */ - double histSize; /**< Size of reference weight histogram. */ - double logScaledSampleWeight; /**< The log of the current sample weight, scaled because of the histogram rescaling. */ - double maxLogScaledSampleWeight; /**< Maximum sample weight obtained for previous (smaller) histogram sizes. */ - int64_t numUpdates; /**< The number of updates. */ + int umbrellaGridpoint; /**< Index for the current umbrella reference coordinate point (for umbrella potential type) */ + int origin_index_updatelist; /**< Point index of the origin of the subgrid that has been touched since last update. */ + int end_index_updatelist; /**< Point index of the end of the subgrid that has been touched since last update. */ + bool in_initial; /**< True if in the intial stage. */ + bool equilibrateHistogram; /**< True if histogram needs equilibration. */ + double histSize; /**< Size of reference weight histogram. */ + double logScaledSampleWeight; /**< The log of the current sample weight, scaled because of the histogram rescaling. */ + double maxLogScaledSampleWeight; /**< Maximum sample weight obtained for previous (smaller) histogram sizes. */ + int64_t numUpdates; /**< The number of updates. */ /*! \brief Constructor. */ - AwhBiasStateHistory() : umbrellaGridpoint(0), - origin_index_updatelist(0), - end_index_updatelist(0), - in_initial(false), - equilibrateHistogram(false), - histSize(0), - logScaledSampleWeight(0), - maxLogScaledSampleWeight(0), - numUpdates(0) + AwhBiasStateHistory() : + umbrellaGridpoint(0), + origin_index_updatelist(0), + end_index_updatelist(0), + in_initial(false), + equilibrateHistogram(false), + histSize(0), + logScaledSampleWeight(0), + maxLogScaledSampleWeight(0), + numUpdates(0) { } }; @@ -103,23 +104,20 @@ struct AwhBiasStateHistory //! AWH bias history data. Note that this is a copy of an AWH internal struct. struct AwhBiasHistory { - std::vector pointState; /**< History for grid coordinate points. */ + std::vector pointState; /**< History for grid coordinate points. */ - AwhBiasStateHistory state; /**< The global state of the AWH bias. */ - CorrelationGridHistory forceCorrelationGrid; /**< History for force correlation statistics. */ + AwhBiasStateHistory state; /**< The global state of the AWH bias. */ + CorrelationGridHistory forceCorrelationGrid; /**< History for force correlation statistics. */ }; //! A collection of AWH bias history data. */ struct AwhHistory { - std::vector bias; /**< History for each bias. */ - double potentialOffset; /**< The offset of the bias potential due to bias updates. */ + std::vector bias; /**< History for each bias. */ + double potentialOffset; /**< The offset of the bias potential due to bias updates. */ /*! \brief Constructor. */ - AwhHistory() : - potentialOffset(0) - { - } + AwhHistory() : potentialOffset(0) {} }; /*! \endcond */ diff --git a/src/gromacs/mdtypes/awh_params.h b/src/gromacs/mdtypes/awh_params.h index f01286deb1..1342e90d51 100644 --- a/src/gromacs/mdtypes/awh_params.h +++ b/src/gromacs/mdtypes/awh_params.h @@ -57,40 +57,53 @@ namespace gmx { //! Target distribution enum. -enum { - eawhtargetCONSTANT, eawhtargetCUTOFF, eawhtargetBOLTZMANN, eawhtargetLOCALBOLTZMANN, eawhtargetNR +enum +{ + eawhtargetCONSTANT, + eawhtargetCUTOFF, + eawhtargetBOLTZMANN, + eawhtargetLOCALBOLTZMANN, + eawhtargetNR }; //! String for target distribution. -extern const char *eawhtarget_names[eawhtargetNR+1]; +extern const char* eawhtarget_names[eawhtargetNR + 1]; //! Macro for target distribution string. -#define EAWHTARGET(e) enum_name(e, gmx::eawhtargetNR, gmx::eawhtarget_names) +#define EAWHTARGET(e) enum_name(e, gmx::eawhtargetNR, gmx::eawhtarget_names) //! Weight histogram growth enum. -enum { - eawhgrowthEXP_LINEAR, eawhgrowthLINEAR, eawhgrowthNR +enum +{ + eawhgrowthEXP_LINEAR, + eawhgrowthLINEAR, + eawhgrowthNR }; //! String for weight histogram growth -extern const char *eawhgrowth_names[eawhgrowthNR+1]; +extern const char* eawhgrowth_names[eawhgrowthNR + 1]; //! Macro for weight histogram growth string. -#define EAWHGROWTH(e) enum_name(e, gmx::eawhgrowthNR, gmx::eawhgrowth_names) +#define EAWHGROWTH(e) enum_name(e, gmx::eawhgrowthNR, gmx::eawhgrowth_names) //! AWH potential type enum. -enum { - eawhpotentialCONVOLVED, eawhpotentialUMBRELLA, eawhpotentialNR +enum +{ + eawhpotentialCONVOLVED, + eawhpotentialUMBRELLA, + eawhpotentialNR }; //! String for AWH potential type -extern const char *eawhpotential_names[eawhpotentialNR+1]; +extern const char* eawhpotential_names[eawhpotentialNR + 1]; //! Macro for AWH potential type string. -#define EAWHPOTENTIAL(e) enum_name(e, gmx::eawhpotentialNR, gmx::eawhpotential_names) +#define EAWHPOTENTIAL(e) enum_name(e, gmx::eawhpotentialNR, gmx::eawhpotential_names) //! AWH bias reaction coordinate provider -enum { - eawhcoordproviderPULL, eawhcoordproviderNR +enum +{ + eawhcoordproviderPULL, + eawhcoordproviderNR }; //! String for AWH bias reaction coordinate provider. -extern const char *eawhcoordprovider_names[eawhcoordproviderNR+1]; +extern const char* eawhcoordprovider_names[eawhcoordproviderNR + 1]; //! Macro for AWH bias reaction coordinate provider. -#define EAWHCOORDPROVIDER(e) enum_name(e, gmx::eawhcoordproviderNR, gmx::eawhcoordprovider_names) +#define EAWHCOORDPROVIDER(e) enum_name(e, gmx::eawhcoordproviderNR, gmx::eawhcoordprovider_names) /*! \cond INTERNAL */ @@ -105,41 +118,41 @@ struct AwhDimParams double forceConstant; /**< The force constant in kJ/mol/nm^2, kJ/mol/rad^2 */ double diffusion; /**< Estimated diffusion constant in units of nm^2/ps or rad^2/ps. */ double coordValueInit; /**< The initial coordinate value. */ - double coverDiameter; /**< The diameter that needs to be sampled around a point before it is considered covered. */ + double coverDiameter; /**< The diameter that needs to be sampled around a point before it is considered covered. */ }; //! Parameters for an AWH bias. struct AwhBiasParams { // TODO: Turn dimParams into a std::vector when moved into AWH module - int ndim; /**< Dimension of the coordinate space. */ - AwhDimParams *dimParams; /**< AWH parameters per dimension. */ - int eTarget; /**< Type of target distribution. */ - double targetBetaScaling; /**< Beta scaling value for Boltzmann type target distributions. */ - double targetCutoff; /**< Free energy cutoff value for cutoff type target distribution in kJ/mol.*/ - int eGrowth; /**< How the biasing histogram grows. */ - int bUserData; /**< Is there a user-defined initial PMF estimate and target estimate? */ - double errorInitial; /**< Estimated initial free energy error in kJ/mol. */ - int shareGroup; /**< When >0, the bias is shared with biases of the same group and across multiple simulations when shareBiasMultisim=true */ - gmx_bool equilibrateHistogram; /**< True if the simulation starts out by equilibrating the histogram. */ + int ndim; /**< Dimension of the coordinate space. */ + AwhDimParams* dimParams; /**< AWH parameters per dimension. */ + int eTarget; /**< Type of target distribution. */ + double targetBetaScaling; /**< Beta scaling value for Boltzmann type target distributions. */ + double targetCutoff; /**< Free energy cutoff value for cutoff type target distribution in kJ/mol.*/ + int eGrowth; /**< How the biasing histogram grows. */ + int bUserData; /**< Is there a user-defined initial PMF estimate and target estimate? */ + double errorInitial; /**< Estimated initial free energy error in kJ/mol. */ + int shareGroup; /**< When >0, the bias is shared with biases of the same group and across multiple simulations when shareBiasMultisim=true */ + gmx_bool equilibrateHistogram; /**< True if the simulation starts out by equilibrating the histogram. */ }; //! Parameters for AWH. struct AwhParams { // TODO: Turn awhBiasParams into a std::vector when moved into AWH module - int numBias; /**< The number of AWH biases.*/ - AwhBiasParams *awhBiasParams; /**< AWH bias parameters.*/ - int64_t seed; /**< Random seed.*/ - int nstOut; /**< Output step interval.*/ - int nstSampleCoord; /**< Number of samples per coordinate sample (also used for PMF) */ - int numSamplesUpdateFreeEnergy; /**< Number of samples per free energy update. */ - int ePotential; /**< Type of potential. */ - gmx_bool shareBiasMultisim; /**< When true, share biases with shareGroup>0 between multi-simulations */ + int numBias; /**< The number of AWH biases.*/ + AwhBiasParams* awhBiasParams; /**< AWH bias parameters.*/ + int64_t seed; /**< Random seed.*/ + int nstOut; /**< Output step interval.*/ + int nstSampleCoord; /**< Number of samples per coordinate sample (also used for PMF) */ + int numSamplesUpdateFreeEnergy; /**< Number of samples per free energy update. */ + int ePotential; /**< Type of potential. */ + gmx_bool shareBiasMultisim; /**< When true, share biases with shareGroup>0 between multi-simulations */ }; /*! \endcond */ -} // namespace gmx +} // namespace gmx #endif /* GMX_MDTYPES_AWH_PARAMS_H */ diff --git a/src/gromacs/mdtypes/commrec.h b/src/gromacs/mdtypes/commrec.h index b8c68de92d..47973cd7ee 100644 --- a/src/gromacs/mdtypes/commrec.h +++ b/src/gromacs/mdtypes/commrec.h @@ -46,10 +46,11 @@ struct mpi_in_place_buf_t; struct gmx_domdec_t; -#define DUTY_PP (1U<<0U) -#define DUTY_PME (1U<<1U) +#define DUTY_PP (1U << 0U) +#define DUTY_PME (1U << 1U) -typedef struct { +typedef struct +{ int bUse; MPI_Comm comm_intra; int rank_intra; @@ -57,7 +58,8 @@ typedef struct { } gmx_nodecomm_t; -struct t_commrec { +struct t_commrec +{ /* The nodeids in one sim are numbered sequentially from 0. * All communication within some simulation should happen * in mpi_comm_mysim, or its subset mpi_comm_mygroup. @@ -67,35 +69,35 @@ struct t_commrec { /* thread numbers: */ /* Not used yet: int threadid, nthreads; */ /* The nodeid in the PP/PME, PP or PME group */ - int nodeid; + int nodeid; /* MPI communicators within a single simulation * Note: other parts of the code may further subset these communicators. */ - MPI_Comm mpi_comm_mysim; /* communicator including all ranks of - a single simulation */ - MPI_Comm mpi_comm_mygroup; /* subset of mpi_comm_mysim including only - the ranks in the same group (PP or PME) */ + MPI_Comm mpi_comm_mysim; /* communicator including all ranks of + a single simulation */ + MPI_Comm mpi_comm_mygroup; /* subset of mpi_comm_mysim including only + the ranks in the same group (PP or PME) */ gmx_nodecomm_t nc; /* For domain decomposition */ - gmx_domdec_t *dd; + gmx_domdec_t* dd; /* The duties of this node, see the DUTY_ defines above. * This should be read through thisRankHasDuty() or getThisRankDuties(). */ - int duty; + int duty; /* these buffers are used as destination buffers if MPI_IN_PLACE isn't supported.*/ - mpi_in_place_buf_t *mpb; + mpi_in_place_buf_t* mpb; }; /*! \brief * Returns the rank's duty, and asserts that it has been initialized. */ -inline int getThisRankDuties(const t_commrec *cr) +inline int getThisRankDuties(const t_commrec* cr) { GMX_ASSERT(cr, "Invalid commrec pointer"); GMX_ASSERT(cr->duty != 0, "Commrec duty was not initialized!"); @@ -111,26 +113,26 @@ inline int getThisRankDuties(const t_commrec *cr) * * \returns Whether this duty is assigned to this rank. */ -inline bool thisRankHasDuty(const t_commrec *cr, int duty) +inline bool thisRankHasDuty(const t_commrec* cr, int duty) { GMX_ASSERT((duty == DUTY_PME) || (duty == DUTY_PP), "Invalid duty type"); return (getThisRankDuties(cr) & duty) != 0; } //! True if this is a simulation with more than 1 node -#define PAR(cr) ((cr)->nnodes > 1) +#define PAR(cr) ((cr)->nnodes > 1) //! True of this is the master node -#define MASTER(cr) (((cr)->nodeid == 0) || !PAR(cr)) +#define MASTER(cr) (((cr)->nodeid == 0) || !PAR(cr)) //! True if this is the particle-particle master -#define SIMMASTER(cr) ((MASTER(cr) && thisRankHasDuty((cr), DUTY_PP)) || !PAR(cr)) +#define SIMMASTER(cr) ((MASTER(cr) && thisRankHasDuty((cr), DUTY_PP)) || !PAR(cr)) //! The node id for this rank -#define RANK(cr, nodeid) (nodeid) +#define RANK(cr, nodeid) (nodeid) //! The node id for the master -#define MASTERRANK(cr) (0) +#define MASTERRANK(cr) (0) /*! \brief Do we use domain decomposition * @@ -139,21 +141,22 @@ inline bool thisRankHasDuty(const t_commrec *cr, int duty) * PAR(cr) and DOMAINDECOMP(cr) are not universally synonymous. In * particular, DOMAINDECOMP(cr) == true indicates that there is more * than one domain, not just that the dd algorithm is active. */ -#define DOMAINDECOMP(cr) (((cr)->dd != nullptr) && PAR(cr)) +#define DOMAINDECOMP(cr) (((cr)->dd != nullptr) && PAR(cr)) /*! \brief Returns whether we have actual domain decomposition for the particle-particle interactions * * Will return false when we use 1 rank for PP and 1 for PME */ -static bool inline havePPDomainDecomposition(const t_commrec *cr) +static bool inline havePPDomainDecomposition(const t_commrec* cr) { /* NOTE: It would be better to use cr->dd->nnodes, but we do not want * to pull in a dependency on domdec.h into this file. */ GMX_ASSERT(cr != nullptr, "Invalid call of havePPDomainDecomposition before commrec is made"); - GMX_ASSERT(cr->npmenodes >= 0, "Invalid call of havePPDomainDecomposition before MPMD automated decomposition was chosen."); - return (cr->dd != nullptr && - cr->nnodes - cr->npmenodes > 1); + GMX_ASSERT(cr->npmenodes >= 0, + "Invalid call of havePPDomainDecomposition before MPMD automated decomposition was " + "chosen."); + return (cr->dd != nullptr && cr->nnodes - cr->npmenodes > 1); } #endif diff --git a/src/gromacs/mdtypes/df_history.cpp b/src/gromacs/mdtypes/df_history.cpp index 6068b97fc7..3a3a7a7bdb 100644 --- a/src/gromacs/mdtypes/df_history.cpp +++ b/src/gromacs/mdtypes/df_history.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,7 +40,7 @@ #include "gromacs/mdtypes/state.h" #include "gromacs/utility/smalloc.h" -void init_df_history(df_history_t *dfhist, int nlambda) +void init_df_history(df_history_t* dfhist, int nlambda) { int i; @@ -80,7 +80,7 @@ void init_df_history(df_history_t *dfhist, int nlambda) } } -void copy_df_history(df_history_t *df_dest, df_history_t *df_source) +void copy_df_history(df_history_t* df_dest, df_history_t* df_source) { int i, j; @@ -104,17 +104,17 @@ void copy_df_history(df_history_t *df_dest, df_history_t *df_source) { for (j = 0; j < df_dest->nlambda; j++) { - df_dest->accum_p[i][j] = df_source->accum_p[i][j]; - df_dest->accum_m[i][j] = df_source->accum_m[i][j]; - df_dest->accum_p2[i][j] = df_source->accum_p2[i][j]; - df_dest->accum_m2[i][j] = df_source->accum_m2[i][j]; - df_dest->Tij[i][j] = df_source->Tij[i][j]; - df_dest->Tij_empirical[i][j] = df_source->Tij_empirical[i][j]; + df_dest->accum_p[i][j] = df_source->accum_p[i][j]; + df_dest->accum_m[i][j] = df_source->accum_m[i][j]; + df_dest->accum_p2[i][j] = df_source->accum_p2[i][j]; + df_dest->accum_m2[i][j] = df_source->accum_m2[i][j]; + df_dest->Tij[i][j] = df_source->Tij[i][j]; + df_dest->Tij_empirical[i][j] = df_source->Tij_empirical[i][j]; } } } -void done_df_history(df_history_t *dfhist) +void done_df_history(df_history_t* dfhist) { int i; diff --git a/src/gromacs/mdtypes/df_history.h b/src/gromacs/mdtypes/df_history.h index 90b14523ad..abcdd0a518 100644 --- a/src/gromacs/mdtypes/df_history.h +++ b/src/gromacs/mdtypes/df_history.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,10 +38,10 @@ struct df_history_t; -void init_df_history(df_history_t *dfhist, int nlambda); +void init_df_history(df_history_t* dfhist, int nlambda); -void done_df_history(df_history_t *dfhist); +void done_df_history(df_history_t* dfhist); -void copy_df_history(df_history_t * df_dest, df_history_t *df_source); +void copy_df_history(df_history_t* df_dest, df_history_t* df_source); #endif diff --git a/src/gromacs/mdtypes/edsamhistory.h b/src/gromacs/mdtypes/edsamhistory.h index 0c33bebd2c..6500061611 100644 --- a/src/gromacs/mdtypes/edsamhistory.h +++ b/src/gromacs/mdtypes/edsamhistory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,15 +56,14 @@ */ typedef struct edsamhistory_t { - gmx_bool bFromCpt; // Did we start from a checkpoint file? - int nED; // No. of ED/Flooding data sets, if <1 no ED - int *nref; // No. of atoms in i'th reference structure - int *nav; // Same for average structure - rvec **old_sref; // Positions of the reference atoms at the last time step (with correct PBC representation) - rvec **old_sref_p; // Pointer to these positions - rvec **old_sav; // Same for the average positions - rvec **old_sav_p; // Pointer to these positions -} -edsamhistory_t; + gmx_bool bFromCpt; // Did we start from a checkpoint file? + int nED; // No. of ED/Flooding data sets, if <1 no ED + int* nref; // No. of atoms in i'th reference structure + int* nav; // Same for average structure + rvec** old_sref; // Positions of the reference atoms at the last time step (with correct PBC representation) + rvec** old_sref_p; // Pointer to these positions + rvec** old_sav; // Same for the average positions + rvec** old_sav_p; // Pointer to these positions +} edsamhistory_t; #endif diff --git a/src/gromacs/mdtypes/enerdata.h b/src/gromacs/mdtypes/enerdata.h index cd297594ee..5180f4e353 100644 --- a/src/gromacs/mdtypes/enerdata.h +++ b/src/gromacs/mdtypes/enerdata.h @@ -42,17 +42,21 @@ #include "gromacs/topology/idef.h" #include "gromacs/utility/real.h" -enum { - egCOULSR, egLJSR, egBHAMSR, - egCOUL14, egLJ14, egNR +enum +{ + egCOULSR, + egLJSR, + egBHAMSR, + egCOUL14, + egLJ14, + egNR }; struct gmx_grppairener_t { - gmx_grppairener_t(int numEnergyGroups) : - nener(numEnergyGroups*numEnergyGroups) + gmx_grppairener_t(int numEnergyGroups) : nener(numEnergyGroups * numEnergyGroups) { - for (auto &elem : ener) + for (auto& elem : ener) { elem.resize(nener); } @@ -64,22 +68,21 @@ struct gmx_grppairener_t struct gmx_enerdata_t { - gmx_enerdata_t(int numEnergyGroups, - int numFepLambdas); + gmx_enerdata_t(int numEnergyGroups, int numFepLambdas); - real term[F_NRE] = { 0 }; /* The energies for all different interaction types */ + real term[F_NRE] = { 0 }; /* The energies for all different interaction types */ struct gmx_grppairener_t grpp; - double dvdl_lin[efptNR] = { 0 }; /* Contributions to dvdl with linear lam-dependence */ - double dvdl_nonlin[efptNR] = { 0 }; /* Idem, but non-linear dependence */ + double dvdl_lin[efptNR] = { 0 }; /* Contributions to dvdl with linear lam-dependence */ + double dvdl_nonlin[efptNR] = { 0 }; /* Idem, but non-linear dependence */ /* The idea is that dvdl terms with linear lambda dependence will be added * automatically to enerpart_lambda. Terms with non-linear lambda dependence * should explicitly determine the energies at foreign lambda points * when n_lambda > 0. */ - int fep_state = 0; /*current fep state -- just for printing */ - std::vector enerpart_lambda; /* Partial Hamiltonian for lambda and flambda[], includes at least all perturbed terms */ - real foreign_term[F_NRE] = { 0 }; /* alternate array for storing foreign lambda energies */ - struct gmx_grppairener_t foreign_grpp; /* alternate array for storing foreign lambda energies */ + int fep_state = 0; /*current fep state -- just for printing */ + std::vector enerpart_lambda; /* Partial Hamiltonian for lambda and flambda[], includes at least all perturbed terms */ + real foreign_term[F_NRE] = { 0 }; /* alternate array for storing foreign lambda energies */ + struct gmx_grppairener_t foreign_grpp; /* alternate array for storing foreign lambda energies */ }; #endif diff --git a/src/gromacs/mdtypes/energyhistory.h b/src/gromacs/mdtypes/energyhistory.h index 61ffc4dc24..8f463a6efd 100644 --- a/src/gromacs/mdtypes/energyhistory.h +++ b/src/gromacs/mdtypes/energyhistory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,48 +59,44 @@ //! \brief Energy history for delta_h histograms in between energy file frames class delta_h_history_t { - public: - //! Vector (size number of intermediate data points) of vector of Hamiltonian differences for each foreign lambda - std::vector > dh; - //! The start time of these energy diff blocks - double start_time; - //! Lambda at start time - double start_lambda; - //! Whether the lambda value is set. Here for backward-compatibility. - gmx_bool start_lambda_set; +public: + //! Vector (size number of intermediate data points) of vector of Hamiltonian differences for each foreign lambda + std::vector> dh; + //! The start time of these energy diff blocks + double start_time; + //! Lambda at start time + double start_lambda; + //! Whether the lambda value is set. Here for backward-compatibility. + gmx_bool start_lambda_set; - delta_h_history_t() : - start_time(0), - start_lambda(0), - start_lambda_set(false) - { - } + delta_h_history_t() : start_time(0), start_lambda(0), start_lambda_set(false) {} }; //! \brief Energy statistics history, only used for output and reporting class energyhistory_t { - public: - int64_t nsteps; //! The number of steps in the history - int64_t nsum; //! Nr. of steps in the ener_ave and ener_sum - std::vector ener_ave; //! Energy terms difference^2 sum to get fluctuations - std::vector ener_sum; //! Energy terms sum - int64_t nsteps_sim; //! The number of steps in ener_sum_sim - int64_t nsum_sim; //! The number of frames in ener_sum_sim - std::vector ener_sum_sim; //! Energy term history sum of the whole sim +public: + int64_t nsteps; //! The number of steps in the history + int64_t nsum; //! Nr. of steps in the ener_ave and ener_sum + std::vector ener_ave; //! Energy terms difference^2 sum to get fluctuations + std::vector ener_sum; //! Energy terms sum + int64_t nsteps_sim; //! The number of steps in ener_sum_sim + int64_t nsum_sim; //! The number of frames in ener_sum_sim + std::vector ener_sum_sim; //! Energy term history sum of the whole sim - //! History for energy difference for foreign lambdas (useful for BAR) - std::unique_ptr deltaHForeignLambdas; + //! History for energy difference for foreign lambdas (useful for BAR) + std::unique_ptr deltaHForeignLambdas; - energyhistory_t() : nsteps(0), - nsum(0), + energyhistory_t() : + nsteps(0), + nsum(0), - nsteps_sim(0), - nsum_sim(0), - ener_sum_sim(0) - { - } + nsteps_sim(0), + nsum_sim(0), + ener_sum_sim(0) + { + } }; //! \endcond diff --git a/src/gromacs/mdtypes/fcdata.h b/src/gromacs/mdtypes/fcdata.h index f5aec67e11..70a6b8df88 100644 --- a/src/gromacs/mdtypes/fcdata.h +++ b/src/gromacs/mdtypes/fcdata.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,11 +45,12 @@ typedef real rvec5[5]; /* Distance restraining stuff */ -typedef struct t_disresdata { +typedef struct t_disresdata +{ int dr_weighting; /* Weighting of pairs in one restraint */ gmx_bool dr_bMixed; /* Use sqrt of the instantaneous times * * the time averaged violation */ - real dr_fc; /* Force constant for disres, * + real dr_fc; /* Force constant for disres, * * which is multiplied by a (possibly) * * different factor for each restraint */ real dr_tau; /* Time constant for disres */ @@ -60,15 +61,15 @@ typedef struct t_disresdata { int npair; /* The number of distance restraint pairs */ int type_min; /* The minimum iparam type index for restraints */ real sumviol; /* The sum of violations */ - real *rt; /* The instantaneous distance (npair) */ - real *rm3tav; /* The time averaged distance (npair) */ - real *Rtl_6; /* The instantaneous r^-6 (nres) */ - real *Rt_6; /* The instantaneous ensemble averaged r^-6 (nres) */ - real *Rtav_6; /* The time and ensemble averaged r^-6 (nres) */ + real* rt; /* The instantaneous distance (npair) */ + real* rm3tav; /* The time averaged distance (npair) */ + real* Rtl_6; /* The instantaneous r^-6 (nres) */ + real* Rt_6; /* The instantaneous ensemble averaged r^-6 (nres) */ + real* Rtav_6; /* The time and ensemble averaged r^-6 (nres) */ int nsystems; /* The number of systems for ensemble averaging */ /* TODO: Implement a proper solution for parallel disre indexing */ - const t_iatom *forceatomsStart; /* Pointer to the start of the disre forceatoms */ + const t_iatom* forceatomsStart; /* Pointer to the start of the disre forceatoms */ } t_disresdata; /* All coefficients for the matrix equation for the orientation tensor */ @@ -79,7 +80,8 @@ struct OriresMatEq }; /* Orientation restraining stuff */ -typedef struct t_oriresdata { +typedef struct t_oriresdata +{ real fc; /* Force constant for the restraints */ real edt; /* Multiplication factor for time averaging */ real edt_1; /* 1 - edt */ @@ -88,31 +90,32 @@ typedef struct t_oriresdata { int nex; /* The number of experiments */ int typeMin; /* The minimum iparam type index for restraints */ int nref; /* The number of atoms for the fit */ - real *mref; /* The masses of the reference atoms */ - rvec *xref; /* The reference coordinates for the fit (nref) */ - rvec *xtmp; /* Temporary array for fitting (nref) */ + real* mref; /* The masses of the reference atoms */ + rvec* xref; /* The reference coordinates for the fit (nref) */ + rvec* xtmp; /* Temporary array for fitting (nref) */ matrix R; /* Rotation matrix to rotate to the reference coor. */ - tensor *S; /* Array of order tensors for each experiment (nexp) */ - rvec5 *Dinsl; /* The order matrix D for all restraints (nr x 5) */ - rvec5 *Dins; /* The ensemble averaged D (nr x 5) */ - rvec5 *Dtav; /* The time and ensemble averaged D (nr x 5) */ - real *oinsl; /* The calculated instantaneous orientations */ - real *oins; /* The calculated emsemble averaged orientations */ - real *otav; /* The calculated time and ensemble averaged orient. */ + tensor* S; /* Array of order tensors for each experiment (nexp) */ + rvec5* Dinsl; /* The order matrix D for all restraints (nr x 5) */ + rvec5* Dins; /* The ensemble averaged D (nr x 5) */ + rvec5* Dtav; /* The time and ensemble averaged D (nr x 5) */ + real* oinsl; /* The calculated instantaneous orientations */ + real* oins; /* The calculated emsemble averaged orientations */ + real* otav; /* The calculated time and ensemble averaged orient. */ real rmsdev; /* The weighted (using kfac) RMS deviation */ - OriresMatEq *tmpEq; /* An temporary array of matrix + rhs */ - real *eig; /* Eigenvalues/vectors, for output only (nex x 12) */ + OriresMatEq* tmpEq; /* An temporary array of matrix + rhs */ + real* eig; /* Eigenvalues/vectors, for output only (nex x 12) */ /* variables for diagonalization with diagonalize_orires_tensors()*/ - double **M; - double *eig_diag; - double **v; + double** M; + double* eig_diag; + double** v; } t_oriresdata; -typedef struct bondedtable_t { - int n; /* n+1 is the number of points */ - real scale; /* distance between two points */ - real *data; /* the actual table data, per point there are 4 numbers */ +typedef struct bondedtable_t +{ + int n; /* n+1 is the number of points */ + real scale; /* distance between two points */ + real* data; /* the actual table data, per point there are 4 numbers */ } bondedtable_t; /* @@ -122,13 +125,14 @@ typedef struct bondedtable_t { * (for instance for time averaging in distance retraints) * or for storing output, since force routines only return the potential. */ -typedef struct t_fcdata { - bondedtable_t *bondtab; - bondedtable_t *angletab; - bondedtable_t *dihtab; +typedef struct t_fcdata +{ + bondedtable_t* bondtab; + bondedtable_t* angletab; + bondedtable_t* dihtab; - t_disresdata disres; - t_oriresdata orires; + t_disresdata disres; + t_oriresdata orires; } t_fcdata; #endif diff --git a/src/gromacs/mdtypes/forceoutput.h b/src/gromacs/mdtypes/forceoutput.h index 5995a32e59..f17e61deeb 100644 --- a/src/gromacs/mdtypes/forceoutput.h +++ b/src/gromacs/mdtypes/forceoutput.h @@ -69,57 +69,44 @@ namespace gmx */ class ForceWithShiftForces { - public: - /*! \brief Constructor - * - * \param[in] force A force buffer that will be used for storing forces - * \param[in] computeVirial True when algorithms are required to provide their virial contribution (for the current force evaluation) - * \param[in] shiftForces A shift forces buffer of size SHIFTS, only used with \p computeVirial = true - */ - ForceWithShiftForces(const gmx::ArrayRefWithPadding &force, - const bool computeVirial, - const gmx::ArrayRef &shiftForces) : - force_(force), - computeVirial_(computeVirial), - shiftForces_(computeVirial ? shiftForces : gmx::ArrayRef()) {} - - //! Returns an arrayref to the force buffer without padding - gmx::ArrayRef force() - { - return force_.unpaddedArrayRef(); - } - - //! Returns a const arrayref to the force buffer without padding - gmx::ArrayRef force() const - { - return force_.unpaddedConstArrayRef(); - } - - //! Returns whether the virial needs to be computed - bool computeVirial() const - { - return computeVirial_; - } - - //! Returns the shift forces buffer - gmx::ArrayRef shiftForces() - { - return shiftForces_; - } - - //! Returns a const shift forces buffer - gmx::ArrayRef shiftForces() const - { - return shiftForces_; - } - - private: - //! The force buffer - gmx::ArrayRefWithPadding force_; - //! True when virial computation is requested - bool computeVirial_; - //! A buffer for storing the shift forces, size SHIFTS - gmx::ArrayRef shiftForces_; +public: + /*! \brief Constructor + * + * \param[in] force A force buffer that will be used for storing forces + * \param[in] computeVirial True when algorithms are required to provide their virial contribution (for the current force evaluation) + * \param[in] shiftForces A shift forces buffer of size SHIFTS, only used with \p computeVirial = true + */ + ForceWithShiftForces(const gmx::ArrayRefWithPadding& force, + const bool computeVirial, + const gmx::ArrayRef& shiftForces) : + force_(force), + computeVirial_(computeVirial), + shiftForces_(computeVirial ? shiftForces : gmx::ArrayRef()) + { + } + + //! Returns an arrayref to the force buffer without padding + gmx::ArrayRef force() { return force_.unpaddedArrayRef(); } + + //! Returns a const arrayref to the force buffer without padding + gmx::ArrayRef force() const { return force_.unpaddedConstArrayRef(); } + + //! Returns whether the virial needs to be computed + bool computeVirial() const { return computeVirial_; } + + //! Returns the shift forces buffer + gmx::ArrayRef shiftForces() { return shiftForces_; } + + //! Returns a const shift forces buffer + gmx::ArrayRef shiftForces() const { return shiftForces_; } + +private: + //! The force buffer + gmx::ArrayRefWithPadding force_; + //! True when virial computation is requested + bool computeVirial_; + //! A buffer for storing the shift forces, size SHIFTS + gmx::ArrayRef shiftForces_; }; /*! \libinternal \brief Container for force and virial for algorithms that provide their own virial tensor contribution @@ -128,112 +115,103 @@ class ForceWithShiftForces */ class ForceWithVirial { - public: - /*! \brief Constructor - * - * \param[in] force A force buffer that will be used for storing forces - * \param[in] computeVirial True when algorithms are required to provide their virial contribution (for the current force evaluation) - */ - ForceWithVirial(const ArrayRef &force, - const bool computeVirial) : - force_(force), - computeVirial_(computeVirial) +public: + /*! \brief Constructor + * + * \param[in] force A force buffer that will be used for storing forces + * \param[in] computeVirial True when algorithms are required to provide their virial contribution (for the current force evaluation) + */ + ForceWithVirial(const ArrayRef& force, const bool computeVirial) : + force_(force), + computeVirial_(computeVirial) + { + for (int dim1 = 0; dim1 < DIM; dim1++) { - for (int dim1 = 0; dim1 < DIM; dim1++) + for (int dim2 = 0; dim2 < DIM; dim2++) { - for (int dim2 = 0; dim2 < DIM; dim2++) - { - virial_[dim1][dim2] = 0; - } + virial_[dim1][dim2] = 0; } } - - /*! \brief Adds a virial contribution - * - * \note Can be called with \p computeVirial=false. - * \note It is recommended to accumulate the virial contributions - * of a module internally before calling this method, as that - * will reduce rounding errors. - * - * \param[in] virial The virial contribution to add - */ - void addVirialContribution(const matrix virial) + } + + /*! \brief Adds a virial contribution + * + * \note Can be called with \p computeVirial=false. + * \note It is recommended to accumulate the virial contributions + * of a module internally before calling this method, as that + * will reduce rounding errors. + * + * \param[in] virial The virial contribution to add + */ + void addVirialContribution(const matrix virial) + { + if (computeVirial_) { - if (computeVirial_) + for (int dim1 = 0; dim1 < DIM; dim1++) { - for (int dim1 = 0; dim1 < DIM; dim1++) + for (int dim2 = 0; dim2 < DIM; dim2++) { - for (int dim2 = 0; dim2 < DIM; dim2++) - { - virial_[dim1][dim2] += virial[dim1][dim2]; - } + virial_[dim1][dim2] += virial[dim1][dim2]; } } } - - /*! \brief Adds a virial diagonal contribution - * - * \note Can be called with \p computeVirial=false. - * \note It is recommended to accumulate the virial contributions - * of a module internally before calling this method, as that - * will reduce rounding errors. - * - * \param[in] virial The virial contribution to add - */ - void addVirialContribution(const RVec virial) + } + + /*! \brief Adds a virial diagonal contribution + * + * \note Can be called with \p computeVirial=false. + * \note It is recommended to accumulate the virial contributions + * of a module internally before calling this method, as that + * will reduce rounding errors. + * + * \param[in] virial The virial contribution to add + */ + void addVirialContribution(const RVec virial) + { + if (computeVirial_) { - if (computeVirial_) + for (int dim = 0; dim < DIM; dim++) { - for (int dim = 0; dim < DIM; dim++) - { - virial_[dim][dim] += virial[dim]; - } + virial_[dim][dim] += virial[dim]; } } + } - /*! \brief Returns the accumulated virial contributions - */ - const matrix &getVirial() const - { - return virial_; - } + /*! \brief Returns the accumulated virial contributions + */ + const matrix& getVirial() const { return virial_; } - const ArrayRef force_; //!< Force accumulation buffer reference - const bool computeVirial_; //!< True when algorithms are required to provide their virial contribution (for the current force evaluation) - private: - matrix virial_; //!< Virial accumulation buffer + const ArrayRef force_; //!< Force accumulation buffer reference + const bool computeVirial_; //!< True when algorithms are required to provide their virial contribution (for the current force evaluation) +private: + matrix virial_; //!< Virial accumulation buffer }; /*! \libinternal \brief Force and virial output buffers for use in force computation */ class ForceOutputs { - public: - //! Constructor - ForceOutputs(const ForceWithShiftForces &forceWithShiftForces, - const ForceWithVirial &forceWithVirial) : - forceWithShiftForces_(forceWithShiftForces), - forceWithVirial_(forceWithVirial) {} - - //! Returns a reference to the force with shift forces object - ForceWithShiftForces &forceWithShiftForces() - { - return forceWithShiftForces_; - } - - //! Returns a reference to the force with virial object - ForceWithVirial &forceWithVirial() - { - return forceWithVirial_; - } - - private: - //! Force output buffer used by legacy modules (without SIMD padding) - ForceWithShiftForces forceWithShiftForces_; - //! Force with direct virial contribution (if there are any; without SIMD padding) - ForceWithVirial forceWithVirial_; +public: + //! Constructor + ForceOutputs(const ForceWithShiftForces& forceWithShiftForces, const ForceWithVirial& forceWithVirial) : + forceWithShiftForces_(forceWithShiftForces), + forceWithVirial_(forceWithVirial) + { + } + + //! Returns a reference to the force with shift forces object + ForceWithShiftForces& forceWithShiftForces() { return forceWithShiftForces_; } + + //! Returns a reference to the force with virial object + ForceWithVirial& forceWithVirial() { return forceWithVirial_; } + +private: + //! Force output buffer used by legacy modules (without SIMD padding) + ForceWithShiftForces forceWithShiftForces_; + //! Force with direct virial contribution (if there are any; without SIMD padding) + ForceWithVirial forceWithVirial_; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/mdtypes/forcerec.h b/src/gromacs/mdtypes/forcerec.h index 1a5c88a7d2..2b0832a80a 100644 --- a/src/gromacs/mdtypes/forcerec.h +++ b/src/gromacs/mdtypes/forcerec.h @@ -62,7 +62,7 @@ class GpuBonded; class ForceProviders; class StatePropagatorDataGpu; class PmePpCommGpu; -} +} // namespace gmx /* macros for the cginfo data in forcerec * @@ -73,23 +73,23 @@ class PmePpCommGpu; * because we only have space for 6 bits in cginfo, * this cg size entry is actually only read with domain decomposition. */ -#define SET_CGINFO_GID(cgi, gid) (cgi) = (((cgi) & ~255) | (gid)) -#define GET_CGINFO_GID(cgi) ( (cgi) & 255) -#define SET_CGINFO_FEP(cgi) (cgi) = ((cgi) | (1<<15)) -#define GET_CGINFO_FEP(cgi) ( (cgi) & (1<<15)) -#define SET_CGINFO_EXCL_INTER(cgi) (cgi) = ((cgi) | (1<<17)) -#define GET_CGINFO_EXCL_INTER(cgi) ( (cgi) & (1<<17)) -#define SET_CGINFO_CONSTR(cgi) (cgi) = ((cgi) | (1<<20)) -#define GET_CGINFO_CONSTR(cgi) ( (cgi) & (1<<20)) -#define SET_CGINFO_SETTLE(cgi) (cgi) = ((cgi) | (1<<21)) -#define GET_CGINFO_SETTLE(cgi) ( (cgi) & (1<<21)) +#define SET_CGINFO_GID(cgi, gid) (cgi) = (((cgi) & ~255) | (gid)) +#define GET_CGINFO_GID(cgi) ((cgi)&255) +#define SET_CGINFO_FEP(cgi) (cgi) = ((cgi) | (1 << 15)) +#define GET_CGINFO_FEP(cgi) ((cgi) & (1 << 15)) +#define SET_CGINFO_EXCL_INTER(cgi) (cgi) = ((cgi) | (1 << 17)) +#define GET_CGINFO_EXCL_INTER(cgi) ((cgi) & (1 << 17)) +#define SET_CGINFO_CONSTR(cgi) (cgi) = ((cgi) | (1 << 20)) +#define GET_CGINFO_CONSTR(cgi) ((cgi) & (1 << 20)) +#define SET_CGINFO_SETTLE(cgi) (cgi) = ((cgi) | (1 << 21)) +#define GET_CGINFO_SETTLE(cgi) ((cgi) & (1 << 21)) /* This bit is only used with bBondComm in the domain decomposition */ -#define SET_CGINFO_BOND_INTER(cgi) (cgi) = ((cgi) | (1<<22)) -#define GET_CGINFO_BOND_INTER(cgi) ( (cgi) & (1<<22)) -#define SET_CGINFO_HAS_VDW(cgi) (cgi) = ((cgi) | (1<<23)) -#define GET_CGINFO_HAS_VDW(cgi) ( (cgi) & (1<<23)) -#define SET_CGINFO_HAS_Q(cgi) (cgi) = ((cgi) | (1<<24)) -#define GET_CGINFO_HAS_Q(cgi) ( (cgi) & (1<<24)) +#define SET_CGINFO_BOND_INTER(cgi) (cgi) = ((cgi) | (1 << 22)) +#define GET_CGINFO_BOND_INTER(cgi) ((cgi) & (1 << 22)) +#define SET_CGINFO_HAS_VDW(cgi) (cgi) = ((cgi) | (1 << 23)) +#define GET_CGINFO_HAS_VDW(cgi) ((cgi) & (1 << 23)) +#define SET_CGINFO_HAS_Q(cgi) (cgi) = ((cgi) | (1 << 24)) +#define GET_CGINFO_HAS_Q(cgi) ((cgi) & (1 << 24)) /* Value to be used in mdrun for an infinite cut-off. @@ -99,8 +99,13 @@ class PmePpCommGpu; #define GMX_CUTOFF_INF 1E+18 /* enums for the neighborlist type */ -enum { - enbvdwNONE, enbvdwLJ, enbvdwBHAM, enbvdwTAB, enbvdwNR +enum +{ + enbvdwNONE, + enbvdwLJ, + enbvdwBHAM, + enbvdwTAB, + enbvdwNR }; struct cginfo_mb_t @@ -108,7 +113,7 @@ struct cginfo_mb_t int cg_start; int cg_end; int cg_mod; - int *cginfo; + int* cginfo; }; @@ -117,7 +122,8 @@ struct gmx_ewald_tab_t; struct ewald_corr_thread_t; -struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) +struct t_forcerec +{ // NOLINT (clang-analyzer-optin.performance.Padding) // Declare an explicit constructor and destructor, so they can be // implemented in a single source file, so that not every source // file that includes this one needs to understand how to find the @@ -125,19 +131,19 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) t_forcerec(); ~t_forcerec(); - struct interaction_const_t *ic = nullptr; + struct interaction_const_t* ic = nullptr; /* PBC stuff */ - int ePBC = 0; + int ePBC = 0; //! Tells whether atoms inside a molecule can be in different periodic images, // i.e. whether we need to take into account PBC when computing distances inside molecules. // This determines whether PBC must be considered for e.g. bonded interactions. - gmx_bool bMolPBC = FALSE; - int rc_scaling = 0; - rvec posres_com = { 0 }; - rvec posres_comB = { 0 }; + gmx_bool bMolPBC = FALSE; + int rc_scaling = 0; + rvec posres_com = { 0 }; + rvec posres_comB = { 0 }; - gmx_bool use_simd_kernels = FALSE; + gmx_bool use_simd_kernels = FALSE; /* Interaction for calculated in kernels. In many cases this is similar to * the electrostatics settings in the inputrecord, but the difference is that @@ -171,36 +177,36 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) real fudgeQQ = 0; /* Table stuff */ - gmx_bool bcoultab = FALSE; - gmx_bool bvdwtab = FALSE; + gmx_bool bcoultab = FALSE; + gmx_bool bvdwtab = FALSE; - t_forcetable *pairsTable = nullptr; /* for 1-4 interactions, [pairs] and [pairs_nb] */ + t_forcetable* pairsTable = nullptr; /* for 1-4 interactions, [pairs] and [pairs_nb] */ /* Free energy */ - int efep = 0; - real sc_alphavdw = 0; - real sc_alphacoul = 0; - int sc_power = 0; - real sc_r_power = 0; - real sc_sigma6_def = 0; - real sc_sigma6_min = 0; + int efep = 0; + real sc_alphavdw = 0; + real sc_alphacoul = 0; + int sc_power = 0; + real sc_r_power = 0; + real sc_sigma6_def = 0; + real sc_sigma6_min = 0; /* Information about atom properties for the molecule blocks in the system */ - struct cginfo_mb_t *cginfo_mb = nullptr; + struct cginfo_mb_t* cginfo_mb = nullptr; /* Information about atom properties for local and non-local atoms */ - std::vector cginfo; + std::vector cginfo; - rvec *shift_vec = nullptr; + rvec* shift_vec = nullptr; - int cutoff_scheme = 0; /* group- or Verlet-style cutoff */ - gmx_bool bNonbonded = FALSE; /* true if nonbonded calculations are *not* turned off */ + int cutoff_scheme = 0; /* group- or Verlet-style cutoff */ + gmx_bool bNonbonded = FALSE; /* true if nonbonded calculations are *not* turned off */ /* The Nbnxm Verlet non-bonded machinery */ std::unique_ptr nbv; /* The wall tables (if used) */ - int nwall = 0; - t_forcetable ***wall_tab = nullptr; + int nwall = 0; + t_forcetable*** wall_tab = nullptr; /* The number of atoms participating in do_force_lowlevel */ int natoms_force = 0; @@ -213,16 +219,16 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) * PPPM/PME/Ewald/posres/ForceProviders */ /* True when we have contributions that are directly added to the virial */ - bool haveDirectVirialContributions = false; + bool haveDirectVirialContributions = false; /* Force buffer for force computation with direct virial contributions */ std::vector forceBufferForDirectVirialContributions; /* Data for PPPM/PME/Ewald */ - struct gmx_pme_t *pmedata = nullptr; + struct gmx_pme_t* pmedata = nullptr; int ljpme_combination_rule = 0; /* PME/Ewald stuff */ - struct gmx_ewald_tab_t *ewald_table = nullptr; + struct gmx_ewald_tab_t* ewald_table = nullptr; /* Shift force array for computing the virial, size SHIFTS */ std::vector shiftForces; @@ -230,11 +236,11 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) /* Non bonded Parameter lists */ int ntype = 0; /* Number of atom types */ gmx_bool bBHAM = FALSE; - real *nbfp = nullptr; - real *ljpme_c6grid = nullptr; /* C6-values used on grid in LJPME */ + real* nbfp = nullptr; + real* ljpme_c6grid = nullptr; /* C6-values used on grid in LJPME */ /* Energy group pair flags */ - int *egp_flags = nullptr; + int* egp_flags = nullptr; /* Shell molecular dynamics flexible constraints */ real fc_stepsize = 0; @@ -248,10 +254,10 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) /* QMMM stuff */ gmx_bool bQMMM = FALSE; - struct t_QMMMrec *qr = nullptr; + struct t_QMMMrec* qr = nullptr; /* QM-MM neighborlists */ - struct t_nblist *QMMMlist = nullptr; + struct t_nblist* QMMMlist = nullptr; /* Limit for printing large forces, negative is don't print */ real print_force = 0; @@ -267,21 +273,21 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) real userreal4 = 0; /* Pointer to struct for managing threading of bonded force calculation */ - struct bonded_threading_t *bondedThreading = nullptr; + struct bonded_threading_t* bondedThreading = nullptr; /* TODO: Replace the pointer by an object once we got rid of C */ - gmx::GpuBonded *gpuBonded = nullptr; + gmx::GpuBonded* gpuBonded = nullptr; /* Ewald correction thread local virial and energy data */ int nthread_ewc = 0; - struct ewald_corr_thread_t *ewc_t = nullptr; + struct ewald_corr_thread_t* ewc_t = nullptr; - gmx::ForceProviders *forceProviders = nullptr; + gmx::ForceProviders* forceProviders = nullptr; // The stateGpu object is created in runner, forcerec just keeps the copy of the pointer. // TODO: This is not supposed to be here. StatePropagatorDataGpu should be a part of // general StatePropagatorData object that is passed around - gmx::StatePropagatorDataGpu *stateGpu = nullptr; + gmx::StatePropagatorDataGpu* stateGpu = nullptr; /* For PME-PP GPU communication */ std::unique_ptr pmePpCommGpu; @@ -291,10 +297,10 @@ struct t_forcerec { // NOLINT (clang-analyzer-optin.performance.Padding) * been scaled by 6.0 or 12.0 to save flops in the kernels. We have corrected this everywhere * in the code, but beware if you are using these macros externally. */ -#define C6(nbfp, ntp, ai, aj) (nbfp)[2*((ntp)*(ai)+(aj))] -#define C12(nbfp, ntp, ai, aj) (nbfp)[2*((ntp)*(ai)+(aj))+1] -#define BHAMC(nbfp, ntp, ai, aj) (nbfp)[3*((ntp)*(ai)+(aj))] -#define BHAMA(nbfp, ntp, ai, aj) (nbfp)[3*((ntp)*(ai)+(aj))+1] -#define BHAMB(nbfp, ntp, ai, aj) (nbfp)[3*((ntp)*(ai)+(aj))+2] +#define C6(nbfp, ntp, ai, aj) (nbfp)[2 * ((ntp) * (ai) + (aj))] +#define C12(nbfp, ntp, ai, aj) (nbfp)[2 * ((ntp) * (ai) + (aj)) + 1] +#define BHAMC(nbfp, ntp, ai, aj) (nbfp)[3 * ((ntp) * (ai) + (aj))] +#define BHAMA(nbfp, ntp, ai, aj) (nbfp)[3 * ((ntp) * (ai) + (aj)) + 1] +#define BHAMB(nbfp, ntp, ai, aj) (nbfp)[3 * ((ntp) * (ai) + (aj)) + 2] #endif diff --git a/src/gromacs/mdtypes/group.h b/src/gromacs/mdtypes/group.h index 33738660b5..d39e7c8cb5 100644 --- a/src/gromacs/mdtypes/group.h +++ b/src/gromacs/mdtypes/group.h @@ -44,82 +44,87 @@ #include "gromacs/utility/real.h" #include "gromacs/utility/smalloc.h" -struct t_grp_tcstat{ +struct t_grp_tcstat +{ //! Temperature at half step - real Th = 0; + real Th = 0; //! Temperature at full step - real T = 0; + real T = 0; //! Kinetic energy at half step - tensor ekinh = {{0}}; + tensor ekinh = { { 0 } }; //! Kinetic energy at old half step - tensor ekinh_old = {{0}}; + tensor ekinh_old = { { 0 } }; //! Kinetic energy at full step - tensor ekinf = {{0}}; + tensor ekinf = { { 0 } }; //! Berendsen coupling lambda - real lambda = 0; + real lambda = 0; //! Scaling factor for NHC- full step - double ekinscalef_nhc = 0; + double ekinscalef_nhc = 0; //! Scaling factor for NHC- half step - double ekinscaleh_nhc = 0; + double ekinscaleh_nhc = 0; //! Scaling factor for NHC- velocity - double vscale_nhc = 0; + double vscale_nhc = 0; }; -struct t_grp_acc { +struct t_grp_acc +{ //! Number of atoms in this group - int nat = 0; + int nat = 0; //! Mean velocities of home particles - rvec u = { 0 }; + rvec u = { 0 }; //! Previous mean velocities of home particles - rvec uold = { 0 }; + rvec uold = { 0 }; //! Mass for topology A - double mA = 0; + double mA = 0; //! Mass for topology B - double mB = 0; + double mB = 0; }; -struct t_cos_acc{ +struct t_cos_acc +{ //! The acceleration for the cosine profile - real cos_accel = 0; + real cos_accel = 0; //! The cos momenta of home particles - real mvcos = 0; + real mvcos = 0; //! The velocity of the cosine profile - real vcos = 0; + real vcos = 0; }; -struct gmx_ekindata_t { +struct gmx_ekindata_t +{ //! Whether non-equilibrium MD is active (ie. constant or cosine acceleration) - gmx_bool bNEMD; + gmx_bool bNEMD; //! The number of T-coupling groups - int ngtc = 0; + int ngtc = 0; //! For size of ekin_work - int nthreads = 0; + int nthreads = 0; //! T-coupling data std::vector tcstat; //! Allocated locations for *_work members - tensor **ekin_work_alloc = nullptr; + tensor** ekin_work_alloc = nullptr; //! Work arrays for tcstat per thread - tensor **ekin_work = nullptr; + tensor** ekin_work = nullptr; //! Work location for dekindl per thread - real **dekindl_work = nullptr; + real** dekindl_work = nullptr; //! The number of acceleration groups - int ngacc = 0; + int ngacc = 0; //! Acceleration data - std::vector grpstat; + std::vector grpstat; //! overall kinetic energy - tensor ekin = {{ 0 }}; + tensor ekin = { { 0 } }; //! overall 1/2 step kinetic energy - tensor ekinh = {{ 0 }}; + tensor ekinh = { { 0 } }; //! dEkin/dlambda at half step - real dekindl = 0; + real dekindl = 0; //! dEkin/dlambda at old half step - real dekindl_old = 0; + real dekindl_old = 0; //! Cosine acceleration data - t_cos_acc cosacc; + t_cos_acc cosacc; ~gmx_ekindata_t(); }; -#define GID(igid, jgid, gnr) (((igid) < (jgid)) ? ((igid)*(gnr)+(jgid)) : ((jgid)*(gnr)+(igid))) +#define GID(igid, jgid, gnr) \ + (((igid) < (jgid)) ? ((igid) * (gnr) + (jgid)) : ((jgid) * (gnr) + (igid))) #endif diff --git a/src/gromacs/mdtypes/iforceprovider.cpp b/src/gromacs/mdtypes/iforceprovider.cpp index 703bd5f162..52a50e5097 100644 --- a/src/gromacs/mdtypes/iforceprovider.cpp +++ b/src/gromacs/mdtypes/iforceprovider.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,20 +51,15 @@ using namespace gmx; class ForceProviders::Impl { - public: - std::vector providers_; +public: + std::vector providers_; }; -ForceProviders::ForceProviders() - : impl_(new Impl) -{ -} +ForceProviders::ForceProviders() : impl_(new Impl) {} -ForceProviders::~ForceProviders() -{ -} +ForceProviders::~ForceProviders() {} -void ForceProviders::addForceProvider(gmx::IForceProvider *provider) +void ForceProviders::addForceProvider(gmx::IForceProvider* provider) { impl_->providers_.push_back(provider); } @@ -74,8 +69,8 @@ bool ForceProviders::hasForceProvider() const return !impl_->providers_.empty(); } -void ForceProviders::calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) const +void ForceProviders::calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) const { for (auto provider : impl_->providers_) { diff --git a/src/gromacs/mdtypes/iforceprovider.h b/src/gromacs/mdtypes/iforceprovider.h index 09bfc5a723..f15de6adb7 100644 --- a/src/gromacs/mdtypes/iforceprovider.h +++ b/src/gromacs/mdtypes/iforceprovider.h @@ -59,7 +59,7 @@ struct t_mdatoms; namespace gmx { -template +template class ArrayRef; class ForceWithVirial; @@ -78,35 +78,39 @@ class ForceWithVirial; */ class ForceProviderInput { - public: - /*! \brief Constructor assembles all necessary force provider input data - * - * \param[in] x Atomic positions - * \param[in] cr Communication record structure - * \param[in] box The simulation box - * \param[in] time The current time in the simulation - * \param[in] mdatoms The atomic data - */ - ForceProviderInput(ArrayRef x, - const t_mdatoms &mdatoms, - double time, - const matrix box, - const t_commrec &cr) - : x_(x), mdatoms_(mdatoms), t_(time), cr_(cr) - { - copy_mat(box, box_); - } - - ArrayRef x_; //!< The atomic positions - const t_mdatoms &mdatoms_; //!< Atomic data - double t_; //!< The current time in the simulation - matrix box_ = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; //!< The simulation box - const t_commrec &cr_; //!< Communication record structure +public: + /*! \brief Constructor assembles all necessary force provider input data + * + * \param[in] x Atomic positions + * \param[in] cr Communication record structure + * \param[in] box The simulation box + * \param[in] time The current time in the simulation + * \param[in] mdatoms The atomic data + */ + ForceProviderInput(ArrayRef x, + const t_mdatoms& mdatoms, + double time, + const matrix box, + const t_commrec& cr) : + x_(x), + mdatoms_(mdatoms), + t_(time), + cr_(cr) + { + copy_mat(box, box_); + } + + ArrayRef x_; //!< The atomic positions + const t_mdatoms& mdatoms_; //!< Atomic data + double t_; //!< The current time in the simulation + matrix box_ = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; //!< The simulation box + const t_commrec& cr_; //!< Communication record structure }; /*! \brief Take pointer, check if valid, return reference */ -template T &makeRefFromPointer(T *ptr) +template +T& makeRefFromPointer(T* ptr) { GMX_ASSERT(ptr != nullptr, "got null pointer"); return *ptr; @@ -119,20 +123,20 @@ template T &makeRefFromPointer(T *ptr) */ class ForceProviderOutput { - public: - /*! \brief Constructor assembles all necessary force provider output data - * - * \param[in,out] forceWithVirial Container for force and virial - * \param[in,out] enerd Structure containing energy data - */ - ForceProviderOutput(ForceWithVirial *forceWithVirial, - gmx_enerdata_t *enerd) - : forceWithVirial_(makeRefFromPointer(forceWithVirial)), enerd_(makeRefFromPointer(enerd)) - { - } - - ForceWithVirial &forceWithVirial_; //!< Container for force and virial - gmx_enerdata_t &enerd_; //!< Structure containing energy data +public: + /*! \brief Constructor assembles all necessary force provider output data + * + * \param[in,out] forceWithVirial Container for force and virial + * \param[in,out] enerd Structure containing energy data + */ + ForceProviderOutput(ForceWithVirial* forceWithVirial, gmx_enerdata_t* enerd) : + forceWithVirial_(makeRefFromPointer(forceWithVirial)), + enerd_(makeRefFromPointer(enerd)) + { + } + + ForceWithVirial& forceWithVirial_; //!< Container for force and virial + gmx_enerdata_t& enerd_; //!< Structure containing energy data }; @@ -155,18 +159,18 @@ class ForceProviderOutput */ class IForceProvider { - public: - /*! \brief - * Computes forces. - * - * \param[in] forceProviderInput struct that collects input data for the force providers - * \param[in,out] forceProviderOutput struct that collects output data of the force providers - */ - virtual void calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) = 0; - - protected: - ~IForceProvider() {} +public: + /*! \brief + * Computes forces. + * + * \param[in] forceProviderInput struct that collects input data for the force providers + * \param[in,out] forceProviderOutput struct that collects output data of the force providers + */ + virtual void calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) = 0; + +protected: + ~IForceProvider() {} }; /*! \libinternal \brief @@ -177,26 +181,26 @@ class IForceProvider */ class ForceProviders { - public: - ForceProviders(); - ~ForceProviders(); +public: + ForceProviders(); + ~ForceProviders(); - /*! \brief - * Adds a provider. - */ - void addForceProvider(gmx::IForceProvider *provider); + /*! \brief + * Adds a provider. + */ + void addForceProvider(gmx::IForceProvider* provider); - //! Whether there are modules added. - bool hasForceProvider() const; + //! Whether there are modules added. + bool hasForceProvider() const; - //! Computes forces. - void calculateForces(const gmx::ForceProviderInput &forceProviderInput, - gmx::ForceProviderOutput *forceProviderOutput) const; + //! Computes forces. + void calculateForces(const gmx::ForceProviderInput& forceProviderInput, + gmx::ForceProviderOutput* forceProviderOutput) const; - private: - class Impl; +private: + class Impl; - gmx::PrivateImplPointer impl_; + gmx::PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/mdtypes/imdmodule.h b/src/gromacs/mdtypes/imdmodule.h index 26ab489cff..c9b1f59402 100644 --- a/src/gromacs/mdtypes/imdmodule.h +++ b/src/gromacs/mdtypes/imdmodule.h @@ -64,15 +64,15 @@ class IMdpOptionProvider; */ class IMDModule { - public: - virtual ~IMDModule() {} +public: + virtual ~IMDModule() {} - //! Returns an interface for handling mdp input (and tpr I/O). - virtual IMdpOptionProvider *mdpOptionProvider() = 0; - //! Returns an interface for handling output files during simulation. - virtual IMDOutputProvider *outputProvider() = 0; - //! Initializes force providers from this module. - virtual void initForceProviders(ForceProviders *forceProviders) = 0; + //! Returns an interface for handling mdp input (and tpr I/O). + virtual IMdpOptionProvider* mdpOptionProvider() = 0; + //! Returns an interface for handling output files during simulation. + virtual IMDOutputProvider* outputProvider() = 0; + //! Initializes force providers from this module. + virtual void initForceProviders(ForceProviders* forceProviders) = 0; }; } // namespace gmx diff --git a/src/gromacs/mdtypes/imdoutputprovider.h b/src/gromacs/mdtypes/imdoutputprovider.h index 4a437fe19a..6feba4ed7f 100644 --- a/src/gromacs/mdtypes/imdoutputprovider.h +++ b/src/gromacs/mdtypes/imdoutputprovider.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,24 +72,27 @@ namespace gmx */ class IMDOutputProvider { - public: - /*! \brief - * Initializes file output from a simulation run. - * - * \param[in] fplog File pointer for log messages - * \param[in] nfile Number of files - * \param[in] fnm Array of filenames and properties - * \param[in] bAppendFiles Whether or not we should append to files - * \param[in] oenv The output environment for xvg files - */ - virtual void initOutput(FILE *fplog, int nfile, const t_filenm fnm[], - bool bAppendFiles, const gmx_output_env_t *oenv) = 0; +public: + /*! \brief + * Initializes file output from a simulation run. + * + * \param[in] fplog File pointer for log messages + * \param[in] nfile Number of files + * \param[in] fnm Array of filenames and properties + * \param[in] bAppendFiles Whether or not we should append to files + * \param[in] oenv The output environment for xvg files + */ + virtual void initOutput(FILE* fplog, + int nfile, + const t_filenm fnm[], + bool bAppendFiles, + const gmx_output_env_t* oenv) = 0; - //! Finalizes output from a simulation run. - virtual void finishOutput() = 0; + //! Finalizes output from a simulation run. + virtual void finishOutput() = 0; - protected: - virtual ~IMDOutputProvider() {} +protected: + virtual ~IMDOutputProvider() {} }; } // namespace gmx diff --git a/src/gromacs/mdtypes/imdpoptionprovider.h b/src/gromacs/mdtypes/imdpoptionprovider.h index b3f8471237..63bda6e410 100644 --- a/src/gromacs/mdtypes/imdpoptionprovider.h +++ b/src/gromacs/mdtypes/imdpoptionprovider.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,31 +79,31 @@ class KeyValueTreeObjectBuilder; */ class IMdpOptionProvider { - public: - /*! \brief - * Initializes a transform from mdp values to sectioned options. - * - * The transform is specified from a flat KeyValueTreeObject that - * contains each mdp value as a property, to a structured - * key-value tree that should match the options defined in - * initMdpOptions(). - * - * This method may be removed once the flat mdp file is replaced with a - * more structure input file (that can be directly read into the - * internal key-value tree), and there is no longer any need for - * backward compatibility with old files. - */ - virtual void initMdpTransform(IKeyValueTreeTransformRules *transform) = 0; - /*! \brief - * Initializes options that declare input (mdp) parameters for this - * module. - */ - virtual void initMdpOptions(IOptionsContainerWithSections *options) = 0; - //! Prepares to write a flat key-value tree like an mdp file. - virtual void buildMdpOutput(KeyValueTreeObjectBuilder *builder) const = 0; +public: + /*! \brief + * Initializes a transform from mdp values to sectioned options. + * + * The transform is specified from a flat KeyValueTreeObject that + * contains each mdp value as a property, to a structured + * key-value tree that should match the options defined in + * initMdpOptions(). + * + * This method may be removed once the flat mdp file is replaced with a + * more structure input file (that can be directly read into the + * internal key-value tree), and there is no longer any need for + * backward compatibility with old files. + */ + virtual void initMdpTransform(IKeyValueTreeTransformRules* transform) = 0; + /*! \brief + * Initializes options that declare input (mdp) parameters for this + * module. + */ + virtual void initMdpOptions(IOptionsContainerWithSections* options) = 0; + //! Prepares to write a flat key-value tree like an mdp file. + virtual void buildMdpOutput(KeyValueTreeObjectBuilder* builder) const = 0; - protected: - virtual ~IMdpOptionProvider() {} +protected: + virtual ~IMdpOptionProvider() {} }; } // namespace gmx diff --git a/src/gromacs/mdtypes/inputrec.cpp b/src/gromacs/mdtypes/inputrec.cpp index 354d39f8ea..04d60adb04 100644 --- a/src/gromacs/mdtypes/inputrec.cpp +++ b/src/gromacs/mdtypes/inputrec.cpp @@ -62,12 +62,12 @@ #include "gromacs/utility/txtdump.h" //! Macro to select a bool name -#define EBOOL(e) gmx::boolToString(e) +#define EBOOL(e) gmx::boolToString(e) /* The minimum number of integration steps required for reasonably accurate * integration of first and second order coupling algorithms. */ -const int nstmin_berendsen_tcouple = 5; +const int nstmin_berendsen_tcouple = 5; const int nstmin_berendsen_pcouple = 10; const int nstmin_harmonic = 20; @@ -86,7 +86,7 @@ t_inputrec::~t_inputrec() done_inputrec(this); } -static int nst_wanted(const t_inputrec *ir) +static int nst_wanted(const t_inputrec* ir) { if (ir->nstlist > 0) { @@ -98,7 +98,7 @@ static int nst_wanted(const t_inputrec *ir) } } -int ir_optimal_nstcalcenergy(const t_inputrec *ir) +int ir_optimal_nstcalcenergy(const t_inputrec* ir) { return nst_wanted(ir); } @@ -109,32 +109,23 @@ int tcouple_min_integration_steps(int etc) switch (etc) { - case etcNO: - n = 0; - break; + case etcNO: n = 0; break; case etcBERENDSEN: - case etcYES: - n = nstmin_berendsen_tcouple; - break; + case etcYES: n = nstmin_berendsen_tcouple; break; case etcVRESCALE: /* V-rescale supports instantaneous rescaling */ n = 0; break; - case etcNOSEHOOVER: - n = nstmin_harmonic; - break; + case etcNOSEHOOVER: n = nstmin_harmonic; break; case etcANDERSEN: - case etcANDERSENMASSIVE: - n = 1; - break; - default: - gmx_incons("Unknown etc value"); + case etcANDERSENMASSIVE: n = 1; break; + default: gmx_incons("Unknown etc value"); } return n; } -int ir_optimal_nsttcouple(const t_inputrec *ir) +int ir_optimal_nsttcouple(const t_inputrec* ir) { int nmin, nwanted, n; real tau_min; @@ -156,13 +147,13 @@ int ir_optimal_nsttcouple(const t_inputrec *ir) } } - if (nmin == 0 || ir->delta_t*nwanted <= tau_min) + if (nmin == 0 || ir->delta_t * nwanted <= tau_min) { n = nwanted; } else { - n = static_cast(tau_min/(ir->delta_t*nmin) + 0.001); + n = static_cast(tau_min / (ir->delta_t * nmin) + 0.001); if (n < 1) { n = 1; @@ -182,39 +173,32 @@ int pcouple_min_integration_steps(int epc) switch (epc) { - case epcNO: - n = 0; - break; + case epcNO: n = 0; break; case etcBERENDSEN: - case epcISOTROPIC: - n = nstmin_berendsen_pcouple; - break; + case epcISOTROPIC: n = nstmin_berendsen_pcouple; break; case epcPARRINELLORAHMAN: - case epcMTTK: - n = nstmin_harmonic; - break; - default: - gmx_incons("Unknown epc value"); + case epcMTTK: n = nstmin_harmonic; break; + default: gmx_incons("Unknown epc value"); } return n; } -int ir_optimal_nstpcouple(const t_inputrec *ir) +int ir_optimal_nstpcouple(const t_inputrec* ir) { - int nmin, nwanted, n; + int nmin, nwanted, n; nmin = pcouple_min_integration_steps(ir->epc); nwanted = nst_wanted(ir); - if (nmin == 0 || ir->delta_t*nwanted <= ir->tau_p) + if (nmin == 0 || ir->delta_t * nwanted <= ir->tau_p) { n = nwanted; } else { - n = static_cast(ir->tau_p/(ir->delta_t*nmin) + 0.001); + n = static_cast(ir->tau_p / (ir->delta_t * nmin) + 0.001); if (n < 1) { n = 1; @@ -228,50 +212,41 @@ int ir_optimal_nstpcouple(const t_inputrec *ir) return n; } -gmx_bool ir_coulomb_switched(const t_inputrec *ir) +gmx_bool ir_coulomb_switched(const t_inputrec* ir) { - return (ir->coulombtype == eelSWITCH || - ir->coulombtype == eelSHIFT || - ir->coulombtype == eelENCADSHIFT || - ir->coulombtype == eelPMESWITCH || - ir->coulombtype == eelPMEUSERSWITCH || - ir->coulomb_modifier == eintmodPOTSWITCH || - ir->coulomb_modifier == eintmodFORCESWITCH); + return (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT || ir->coulombtype == eelENCADSHIFT + || ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSERSWITCH + || ir->coulomb_modifier == eintmodPOTSWITCH || ir->coulomb_modifier == eintmodFORCESWITCH); } -gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec *ir) +gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec* ir) { - return (ir->cutoff_scheme == ecutsVERLET || - ir_coulomb_switched(ir) || ir->coulomb_modifier != eintmodNONE || - ir->coulombtype == eelRF_ZERO); + return (ir->cutoff_scheme == ecutsVERLET || ir_coulomb_switched(ir) + || ir->coulomb_modifier != eintmodNONE || ir->coulombtype == eelRF_ZERO); } -gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec *ir) +gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec* ir) { return (ir_coulomb_is_zero_at_cutoff(ir) || ir->coulombtype == eelUSER || ir->coulombtype == eelPMEUSER); } -gmx_bool ir_vdw_switched(const t_inputrec *ir) +gmx_bool ir_vdw_switched(const t_inputrec* ir) { - return (ir->vdwtype == evdwSWITCH || - ir->vdwtype == evdwSHIFT || - ir->vdwtype == evdwENCADSHIFT || - ir->vdw_modifier == eintmodPOTSWITCH || - ir->vdw_modifier == eintmodFORCESWITCH); + return (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwENCADSHIFT + || ir->vdw_modifier == eintmodPOTSWITCH || ir->vdw_modifier == eintmodFORCESWITCH); } -gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec *ir) +gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec* ir) { - return (ir->cutoff_scheme == ecutsVERLET || - ir_vdw_switched(ir) || ir->vdw_modifier != eintmodNONE); + return (ir->cutoff_scheme == ecutsVERLET || ir_vdw_switched(ir) || ir->vdw_modifier != eintmodNONE); } -gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec *ir) +gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec* ir) { return (ir_vdw_is_zero_at_cutoff(ir) || ir->vdwtype == evdwUSER); } -static void done_pull_group(t_pull_group *pgrp) +static void done_pull_group(t_pull_group* pgrp) { if (pgrp->nat > 0) { @@ -280,11 +255,11 @@ static void done_pull_group(t_pull_group *pgrp) } } -static void done_pull_params(pull_params_t *pull) +static void done_pull_params(pull_params_t* pull) { int i; - for (i = 0; i < pull->ngroup+1; i++) + for (i = 0; i < pull->ngroup + 1; i++) { done_pull_group(pull->group); } @@ -293,7 +268,7 @@ static void done_pull_params(pull_params_t *pull) sfree(pull->coord); } -static void done_lambdas(t_lambda *fep) +static void done_lambdas(t_lambda* fep) { if (fep->n_lambda > 0) { @@ -305,7 +280,7 @@ static void done_lambdas(t_lambda *fep) sfree(fep->all_lambda); } -void done_inputrec(t_inputrec *ir) +void done_inputrec(t_inputrec* ir) { sfree(ir->opts.nrdf); sfree(ir->opts.ref_t); @@ -345,7 +320,7 @@ void done_inputrec(t_inputrec *ir) delete ir->params; } -static void pr_qm_opts(FILE *fp, int indent, const char *title, const t_grpopts *opts) +static void pr_qm_opts(FILE* fp, int indent, const char* title, const t_grpopts* opts) { fprintf(fp, "%s:\n", title); @@ -365,8 +340,7 @@ static void pr_qm_opts(FILE *fp, int indent, const char *title, const t_grpopts } } -static void pr_grp_opts(FILE *out, int indent, const char *title, const t_grpopts *opts, - gmx_bool bMDPformat) +static void pr_grp_opts(FILE* out, int indent, const char* title, const t_grpopts* opts, gmx_bool bMDPformat) { int i, m, j; @@ -462,7 +436,7 @@ static void pr_grp_opts(FILE *out, int indent, const char *title, const t_grpopt fprintf(out, "energygrp-flags[%3d]:", i); for (m = 0; (m < opts->ngener); m++) { - fprintf(out, " %d", opts->egp_flags[opts->ngener*i+m]); + fprintf(out, " %d", opts->egp_flags[opts->ngener * i + m]); } fprintf(out, "\n"); } @@ -470,13 +444,12 @@ static void pr_grp_opts(FILE *out, int indent, const char *title, const t_grpopt fflush(out); } -static void pr_matrix(FILE *fp, int indent, const char *title, const rvec *m, - gmx_bool bMDPformat) +static void pr_matrix(FILE* fp, int indent, const char* title, const rvec* m, gmx_bool bMDPformat) { if (bMDPformat) { - fprintf(fp, "%-10s = %g %g %g %g %g %g\n", title, - m[XX][XX], m[YY][YY], m[ZZ][ZZ], m[XX][YY], m[XX][ZZ], m[YY][ZZ]); + fprintf(fp, "%-10s = %g %g %g %g %g %g\n", title, m[XX][XX], m[YY][YY], m[ZZ][ZZ], + m[XX][YY], m[XX][ZZ], m[YY][ZZ]); } else { @@ -490,7 +463,7 @@ static void pr_matrix(FILE *fp, int indent, const char *title, const rvec *m, #define PR(t, s) pr_real(fp, indent, t, s) #define PD(t, s) pr_double(fp, indent, t, s) -static void pr_pull_group(FILE *fp, int indent, int g, const t_pull_group *pgrp) +static void pr_pull_group(FILE* fp, int indent, int g, const t_pull_group* pgrp) { pr_indent(fp, indent); fprintf(fp, "pull-group %d:\n", g); @@ -500,7 +473,7 @@ static void pr_pull_group(FILE *fp, int indent, int g, const t_pull_group *pgrp) PI("pbcatom", pgrp->pbcatom); } -static void pr_pull_coord(FILE *fp, int indent, int c, const t_pull_coord *pcrd) +static void pr_pull_coord(FILE* fp, int indent, int c, const t_pull_coord* pcrd) { int g; @@ -529,7 +502,7 @@ static void pr_pull_coord(FILE *fp, int indent, int c, const t_pull_coord *pcrd) PR("kB", pcrd->kB); } -static void pr_simtempvals(FILE *fp, int indent, const t_simtemp *simtemp, int n_lambda) +static void pr_simtempvals(FILE* fp, int indent, const t_simtemp* simtemp, int n_lambda) { PS("simulated-tempering-scaling", ESIMTEMP(simtemp->eSimTempScale)); PR("sim-temp-low", simtemp->simtemp_low); @@ -537,7 +510,7 @@ static void pr_simtempvals(FILE *fp, int indent, const t_simtemp *simtemp, int n pr_rvec(fp, indent, "simulated tempering temperatures", simtemp->temperatures, n_lambda, TRUE); } -static void pr_expandedvals(FILE *fp, int indent, const t_expanded *expand, int n_lambda) +static void pr_expandedvals(FILE* fp, int indent, const t_expanded* expand, int n_lambda) { PI("nstexpanded", expand->nstexpanded); @@ -583,7 +556,7 @@ static void pr_expandedvals(FILE *fp, int indent, const t_expanded *expand, int PS("init-weights", EBOOL(expand->bInit_weights)); } -static void pr_fepvals(FILE *fp, int indent, const t_lambda *fep, gmx_bool bMDPformat) +static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPformat) { int i, j; @@ -638,7 +611,7 @@ static void pr_fepvals(FILE *fp, int indent, const t_lambda *fep, gmx_bool bMDPf PS("dhdl-derivatives", DHDLDERIVATIVESTYPE(fep->dhdl_derivatives)); }; -static void pr_pull(FILE *fp, int indent, const pull_params_t *pull) +static void pr_pull(FILE* fp, int indent, const pull_params_t* pull) { int g; @@ -664,11 +637,11 @@ static void pr_pull(FILE *fp, int indent, const pull_params_t *pull) } } -static void pr_awh_bias_dim(FILE *fp, int indent, gmx::AwhDimParams *awhDimParams, const char *prefix) +static void pr_awh_bias_dim(FILE* fp, int indent, gmx::AwhDimParams* awhDimParams, const char* prefix) { pr_indent(fp, indent); indent++; - fprintf(fp, "%s:\n", prefix); + fprintf(fp, "%s:\n", prefix); PS("coord-provider", EAWHCOORDPROVIDER(awhDimParams->eCoordProvider)); PI("coord-index", awhDimParams->coordIndex + 1); PR("start", awhDimParams->origin); @@ -681,7 +654,7 @@ static void pr_awh_bias_dim(FILE *fp, int indent, gmx::AwhDimParams *awhDimParam PR("cover-diameter", awhDimParams->coverDiameter); } -static void pr_awh_bias(FILE *fp, int indent, gmx::AwhBiasParams *awhBiasParams, const char *prefix) +static void pr_awh_bias(FILE* fp, int indent, gmx::AwhBiasParams* awhBiasParams, const char* prefix) { char opt[STRLEN]; @@ -712,7 +685,7 @@ static void pr_awh_bias(FILE *fp, int indent, gmx::AwhBiasParams *awhBiasParams, } } -static void pr_awh(FILE *fp, int indent, gmx::AwhParams *awhParams) +static void pr_awh(FILE* fp, int indent, gmx::AwhParams* awhParams) { PS("awh-potential", EAWHPOTENTIAL(awhParams->ePotential)); PI("awh-seed", awhParams->seed); @@ -729,7 +702,7 @@ static void pr_awh(FILE *fp, int indent, gmx::AwhParams *awhParams) } } -static void pr_rotgrp(FILE *fp, int indent, int g, const t_rotgrp *rotg) +static void pr_rotgrp(FILE* fp, int indent, int g, const t_rotgrp* rotg) { pr_indent(fp, indent); fprintf(fp, "rot-group %d:\n", g); @@ -750,7 +723,7 @@ static void pr_rotgrp(FILE *fp, int indent, int g, const t_rotgrp *rotg) PR("rot-potfit-step", rotg->PotAngle_step); } -static void pr_rot(FILE *fp, int indent, const t_rot *rot) +static void pr_rot(FILE* fp, int indent, const t_rot* rot) { int g; @@ -764,13 +737,15 @@ static void pr_rot(FILE *fp, int indent, const t_rot *rot) } -static void pr_swap(FILE *fp, int indent, const t_swapcoords *swap) +static void pr_swap(FILE* fp, int indent, const t_swapcoords* swap) { char str[STRLEN]; /* Enums for better readability of the code */ - enum { - eCompA = 0, eCompB + enum + { + eCompA = 0, + eCompB }; @@ -809,7 +784,7 @@ static void pr_swap(FILE *fp, int indent, const t_swapcoords *swap) { for (int ig = eSwapFixedGrpNR; ig < swap->ngrp; ig++) { - snprintf(str, STRLEN, "%s-in-%c", swap->grp[ig].molname, 'A'+ic); + snprintf(str, STRLEN, "%s-in-%c", swap->grp[ig].molname, 'A' + ic); PI(str, swap->grp[ig].nmolReq[ic]); } } @@ -820,17 +795,16 @@ static void pr_swap(FILE *fp, int indent, const t_swapcoords *swap) } -static void pr_imd(FILE *fp, int indent, const t_IMD *imd) +static void pr_imd(FILE* fp, int indent, const t_IMD* imd) { PI("IMD-atoms", imd->nat); pr_ivec_block(fp, indent, "atom", imd->ind, imd->nat, TRUE); } -void pr_inputrec(FILE *fp, int indent, const char *title, const t_inputrec *ir, - gmx_bool bMDPformat) +void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir, gmx_bool bMDPformat) { - const char *infbuf = "inf"; + const char* infbuf = "inf"; if (available(fp, ir, indent, title)) { @@ -939,10 +913,10 @@ void pr_inputrec(FILE *fp, int indent, const char *title, const t_inputrec *ir, if (bMDPformat) { - fprintf(fp, "posres-com = %g %g %g\n", ir->posres_com[XX], - ir->posres_com[YY], ir->posres_com[ZZ]); - fprintf(fp, "posres-comB = %g %g %g\n", ir->posres_comB[XX], - ir->posres_comB[YY], ir->posres_comB[ZZ]); + fprintf(fp, "posres-com = %g %g %g\n", ir->posres_com[XX], ir->posres_com[YY], + ir->posres_com[ZZ]); + fprintf(fp, "posres-comB = %g %g %g\n", ir->posres_comB[XX], ir->posres_comB[YY], + ir->posres_comB[ZZ]); } else { @@ -1072,12 +1046,12 @@ void pr_inputrec(FILE *fp, int indent, const char *title, const t_inputrec *ir, #undef PR #undef PI -static void cmp_grpopts(FILE *fp, const t_grpopts *opt1, const t_grpopts *opt2, real ftol, real abstol) +static void cmp_grpopts(FILE* fp, const t_grpopts* opt1, const t_grpopts* opt2, real ftol, real abstol) { int i, j; char buf1[256], buf2[256]; - cmp_int(fp, "inputrec->grpopts.ngtc", -1, opt1->ngtc, opt2->ngtc); + cmp_int(fp, "inputrec->grpopts.ngtc", -1, opt1->ngtc, opt2->ngtc); cmp_int(fp, "inputrec->grpopts.ngacc", -1, opt1->ngacc, opt2->ngacc); cmp_int(fp, "inputrec->grpopts.ngfrz", -1, opt1->ngfrz, opt2->ngfrz); cmp_int(fp, "inputrec->grpopts.ngener", -1, opt1->ngener, opt2->ngener); @@ -1087,8 +1061,8 @@ static void cmp_grpopts(FILE *fp, const t_grpopts *opt1, const t_grpopts *opt2, cmp_real(fp, "inputrec->grpopts.ref_t", i, opt1->ref_t[i], opt2->ref_t[i], ftol, abstol); cmp_real(fp, "inputrec->grpopts.tau_t", i, opt1->tau_t[i], opt2->tau_t[i], ftol, abstol); cmp_int(fp, "inputrec->grpopts.annealing", i, opt1->annealing[i], opt2->annealing[i]); - cmp_int(fp, "inputrec->grpopts.anneal_npoints", i, - opt1->anneal_npoints[i], opt2->anneal_npoints[i]); + cmp_int(fp, "inputrec->grpopts.anneal_npoints", i, opt1->anneal_npoints[i], + opt2->anneal_npoints[i]); if (opt1->anneal_npoints[i] == opt2->anneal_npoints[i]) { sprintf(buf1, "inputrec->grpopts.anneal_time[%d]", i); @@ -1107,9 +1081,8 @@ static void cmp_grpopts(FILE *fp, const t_grpopts *opt1, const t_grpopts *opt2, for (j = i; j < opt1->ngener; j++) { sprintf(buf1, "inputrec->grpopts.egp_flags[%d]", i); - cmp_int(fp, buf1, j, - opt1->egp_flags[opt1->ngener*i+j], - opt2->egp_flags[opt1->ngener*i+j]); + cmp_int(fp, buf1, j, opt1->egp_flags[opt1->ngener * i + j], + opt2->egp_flags[opt1->ngener * i + j]); } } } @@ -1123,34 +1096,56 @@ static void cmp_grpopts(FILE *fp, const t_grpopts *opt1, const t_grpopts *opt2, } } -static void cmp_pull(FILE *fp) +static void cmp_pull(FILE* fp) { - fprintf(fp, "WARNING: Both files use COM pulling, but comparing of the pull struct is not implemented (yet). The pull parameters could be the same or different.\n"); + fprintf(fp, + "WARNING: Both files use COM pulling, but comparing of the pull struct is not " + "implemented (yet). The pull parameters could be the same or different.\n"); } -static void cmp_awhDimParams(FILE *fp, const gmx::AwhDimParams *dimp1, const gmx::AwhDimParams *dimp2, int dimIndex, real ftol, real abstol) +static void cmp_awhDimParams(FILE* fp, + const gmx::AwhDimParams* dimp1, + const gmx::AwhDimParams* dimp2, + int dimIndex, + real ftol, + real abstol) { /* Note that we have double index here, but the compare functions only * support one index, so here we only print the dim index and not the bias. */ - cmp_int(fp, "inputrec.awhParams->bias?->dim->coord_index", dimIndex, dimp1->coordIndex, dimp2->coordIndex); - cmp_double(fp, "inputrec->awhParams->bias?->dim->period", dimIndex, dimp1->period, dimp2->period, ftol, abstol); - cmp_double(fp, "inputrec->awhParams->bias?->dim->diffusion", dimIndex, dimp1->diffusion, dimp2->diffusion, ftol, abstol); - cmp_double(fp, "inputrec->awhParams->bias?->dim->origin", dimIndex, dimp1->origin, dimp2->origin, ftol, abstol); + cmp_int(fp, "inputrec.awhParams->bias?->dim->coord_index", dimIndex, dimp1->coordIndex, + dimp2->coordIndex); + cmp_double(fp, "inputrec->awhParams->bias?->dim->period", dimIndex, dimp1->period, + dimp2->period, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->bias?->dim->diffusion", dimIndex, dimp1->diffusion, + dimp2->diffusion, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->bias?->dim->origin", dimIndex, dimp1->origin, + dimp2->origin, ftol, abstol); cmp_double(fp, "inputrec->awhParams->bias?->dim->end", dimIndex, dimp1->end, dimp2->end, ftol, abstol); - cmp_double(fp, "inputrec->awhParams->bias?->dim->coord_value_init", dimIndex, dimp1->coordValueInit, dimp2->coordValueInit, ftol, abstol); - cmp_double(fp, "inputrec->awhParams->bias?->dim->coverDiameter", dimIndex, dimp1->coverDiameter, dimp2->coverDiameter, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->bias?->dim->coord_value_init", dimIndex, + dimp1->coordValueInit, dimp2->coordValueInit, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->bias?->dim->coverDiameter", dimIndex, dimp1->coverDiameter, + dimp2->coverDiameter, ftol, abstol); } -static void cmp_awhBiasParams(FILE *fp, const gmx::AwhBiasParams *bias1, const gmx::AwhBiasParams *bias2, int biasIndex, real ftol, real abstol) +static void cmp_awhBiasParams(FILE* fp, + const gmx::AwhBiasParams* bias1, + const gmx::AwhBiasParams* bias2, + int biasIndex, + real ftol, + real abstol) { cmp_int(fp, "inputrec->awhParams->ndim", biasIndex, bias1->ndim, bias2->ndim); cmp_int(fp, "inputrec->awhParams->biaseTarget", biasIndex, bias1->eTarget, bias2->eTarget); - cmp_double(fp, "inputrec->awhParams->biastargetBetaScaling", biasIndex, bias1->targetBetaScaling, bias2->targetBetaScaling, ftol, abstol); - cmp_double(fp, "inputrec->awhParams->biastargetCutoff", biasIndex, bias1->targetCutoff, bias2->targetCutoff, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->biastargetBetaScaling", biasIndex, + bias1->targetBetaScaling, bias2->targetBetaScaling, ftol, abstol); + cmp_double(fp, "inputrec->awhParams->biastargetCutoff", biasIndex, bias1->targetCutoff, + bias2->targetCutoff, ftol, abstol); cmp_int(fp, "inputrec->awhParams->biaseGrowth", biasIndex, bias1->eGrowth, bias2->eGrowth); - cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData != 0, bias2->bUserData != 0); - cmp_double(fp, "inputrec->awhParams->biaserror_initial", biasIndex, bias1->errorInitial, bias2->errorInitial, ftol, abstol); + cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData != 0, + bias2->bUserData != 0); + cmp_double(fp, "inputrec->awhParams->biaserror_initial", biasIndex, bias1->errorInitial, + bias2->errorInitial, ftol, abstol); cmp_int(fp, "inputrec->awhParams->biasShareGroup", biasIndex, bias1->shareGroup, bias2->shareGroup); for (int dim = 0; dim < std::min(bias1->ndim, bias2->ndim); dim++) @@ -1159,15 +1154,17 @@ static void cmp_awhBiasParams(FILE *fp, const gmx::AwhBiasParams *bias1, const g } } -static void cmp_awhParams(FILE *fp, const gmx::AwhParams *awh1, const gmx::AwhParams *awh2, real ftol, real abstol) +static void cmp_awhParams(FILE* fp, const gmx::AwhParams* awh1, const gmx::AwhParams* awh2, real ftol, real abstol) { cmp_int(fp, "inputrec->awhParams->nbias", -1, awh1->numBias, awh2->numBias); cmp_int64(fp, "inputrec->awhParams->seed", awh1->seed, awh2->seed); cmp_int(fp, "inputrec->awhParams->nstout", -1, awh1->nstOut, awh2->nstOut); cmp_int(fp, "inputrec->awhParams->nstsample_coord", -1, awh1->nstSampleCoord, awh2->nstSampleCoord); - cmp_int(fp, "inputrec->awhParams->nsamples_update_free_energy", -1, awh1->numSamplesUpdateFreeEnergy, awh2->numSamplesUpdateFreeEnergy); + cmp_int(fp, "inputrec->awhParams->nsamples_update_free_energy", -1, + awh1->numSamplesUpdateFreeEnergy, awh2->numSamplesUpdateFreeEnergy); cmp_int(fp, "inputrec->awhParams->ePotential", -1, awh1->ePotential, awh2->ePotential); - cmp_bool(fp, "inputrec->awhParams->shareBiasMultisim", -1, awh1->shareBiasMultisim, awh2->shareBiasMultisim); + cmp_bool(fp, "inputrec->awhParams->shareBiasMultisim", -1, awh1->shareBiasMultisim, + awh2->shareBiasMultisim); if (awh1->numBias == awh2->numBias) { @@ -1178,19 +1175,32 @@ static void cmp_awhParams(FILE *fp, const gmx::AwhParams *awh1, const gmx::AwhPa } } -static void cmp_simtempvals(FILE *fp, const t_simtemp *simtemp1, const t_simtemp *simtemp2, int n_lambda, real ftol, real abstol) +static void cmp_simtempvals(FILE* fp, + const t_simtemp* simtemp1, + const t_simtemp* simtemp2, + int n_lambda, + real ftol, + real abstol) { int i; cmp_int(fp, "inputrec->simtempvals->eSimTempScale", -1, simtemp1->eSimTempScale, simtemp2->eSimTempScale); - cmp_real(fp, "inputrec->simtempvals->simtemp_high", -1, simtemp1->simtemp_high, simtemp2->simtemp_high, ftol, abstol); - cmp_real(fp, "inputrec->simtempvals->simtemp_low", -1, simtemp1->simtemp_low, simtemp2->simtemp_low, ftol, abstol); + cmp_real(fp, "inputrec->simtempvals->simtemp_high", -1, simtemp1->simtemp_high, + simtemp2->simtemp_high, ftol, abstol); + cmp_real(fp, "inputrec->simtempvals->simtemp_low", -1, simtemp1->simtemp_low, + simtemp2->simtemp_low, ftol, abstol); for (i = 0; i < n_lambda; i++) { - cmp_real(fp, "inputrec->simtempvals->temperatures", -1, simtemp1->temperatures[i], simtemp2->temperatures[i], ftol, abstol); + cmp_real(fp, "inputrec->simtempvals->temperatures", -1, simtemp1->temperatures[i], + simtemp2->temperatures[i], ftol, abstol); } } -static void cmp_expandedvals(FILE *fp, const t_expanded *expand1, const t_expanded *expand2, int n_lambda, real ftol, real abstol) +static void cmp_expandedvals(FILE* fp, + const t_expanded* expand1, + const t_expanded* expand2, + int n_lambda, + real ftol, + real abstol) { int i; @@ -1207,41 +1217,53 @@ static void cmp_expandedvals(FILE *fp, const t_expanded *expand1, const t_expand cmp_int(fp, "inputrec->expandedvals->lambda-mc-move", -1, expand1->elmcmove, expand2->elmcmove); cmp_int(fp, "inputrec->expandedvals->lmc-repeats", -1, expand1->lmc_repeats, expand2->lmc_repeats); cmp_int(fp, "inputrec->expandedvals->lmc-gibbsdelta", -1, expand1->gibbsdeltalam, expand2->gibbsdeltalam); - cmp_int(fp, "inputrec->expandedvals->lmc-forced-nstart", -1, expand1->lmc_forced_nstart, expand2->lmc_forced_nstart); + cmp_int(fp, "inputrec->expandedvals->lmc-forced-nstart", -1, expand1->lmc_forced_nstart, + expand2->lmc_forced_nstart); cmp_int(fp, "inputrec->expandedvals->lambda-weights-equil", -1, expand1->elmceq, expand2->elmceq); - cmp_int(fp, "inputrec->expandedvals->,weight-equil-number-all-lambda", -1, expand1->equil_n_at_lam, expand2->equil_n_at_lam); - cmp_int(fp, "inputrec->expandedvals->weight-equil-number-samples", -1, expand1->equil_samples, expand2->equil_samples); - cmp_int(fp, "inputrec->expandedvals->weight-equil-number-steps", -1, expand1->equil_steps, expand2->equil_steps); - cmp_real(fp, "inputrec->expandedvals->weight-equil-wl-delta", -1, expand1->equil_wl_delta, expand2->equil_wl_delta, ftol, abstol); - cmp_real(fp, "inputrec->expandedvals->weight-equil-count-ratio", -1, expand1->equil_ratio, expand2->equil_ratio, ftol, abstol); - cmp_bool(fp, "inputrec->expandedvals->symmetrized-transition-matrix", -1, expand1->bSymmetrizedTMatrix, expand2->bSymmetrizedTMatrix); + cmp_int(fp, "inputrec->expandedvals->,weight-equil-number-all-lambda", -1, + expand1->equil_n_at_lam, expand2->equil_n_at_lam); + cmp_int(fp, "inputrec->expandedvals->weight-equil-number-samples", -1, expand1->equil_samples, + expand2->equil_samples); + cmp_int(fp, "inputrec->expandedvals->weight-equil-number-steps", -1, expand1->equil_steps, + expand2->equil_steps); + cmp_real(fp, "inputrec->expandedvals->weight-equil-wl-delta", -1, expand1->equil_wl_delta, + expand2->equil_wl_delta, ftol, abstol); + cmp_real(fp, "inputrec->expandedvals->weight-equil-count-ratio", -1, expand1->equil_ratio, + expand2->equil_ratio, ftol, abstol); + cmp_bool(fp, "inputrec->expandedvals->symmetrized-transition-matrix", -1, + expand1->bSymmetrizedTMatrix, expand2->bSymmetrizedTMatrix); cmp_int(fp, "inputrec->expandedvals->nstTij", -1, expand1->nstTij, expand2->nstTij); - cmp_int(fp, "inputrec->expandedvals->mininum-var-min", -1, expand1->minvarmin, expand2->minvarmin); /*default is reasonable */ - cmp_int(fp, "inputrec->expandedvals->weight-c-range", -1, expand1->c_range, expand2->c_range); /* default is just C=0 */ + cmp_int(fp, "inputrec->expandedvals->mininum-var-min", -1, expand1->minvarmin, + expand2->minvarmin); /*default is reasonable */ + cmp_int(fp, "inputrec->expandedvals->weight-c-range", -1, expand1->c_range, expand2->c_range); /* default is just C=0 */ cmp_real(fp, "inputrec->expandedvals->wl-scale", -1, expand1->wl_scale, expand2->wl_scale, ftol, abstol); - cmp_real(fp, "inputrec->expandedvals->init-wl-delta", -1, expand1->init_wl_delta, expand2->init_wl_delta, ftol, abstol); + cmp_real(fp, "inputrec->expandedvals->init-wl-delta", -1, expand1->init_wl_delta, + expand2->init_wl_delta, ftol, abstol); cmp_real(fp, "inputrec->expandedvals->wl-ratio", -1, expand1->wl_ratio, expand2->wl_ratio, ftol, abstol); cmp_int(fp, "inputrec->expandedvals->nstexpanded", -1, expand1->nstexpanded, expand2->nstexpanded); cmp_int(fp, "inputrec->expandedvals->lmc-seed", -1, expand1->lmc_seed, expand2->lmc_seed); - cmp_real(fp, "inputrec->expandedvals->mc-temperature", -1, expand1->mc_temp, expand2->mc_temp, ftol, abstol); + cmp_real(fp, "inputrec->expandedvals->mc-temperature", -1, expand1->mc_temp, expand2->mc_temp, + ftol, abstol); } -static void cmp_fepvals(FILE *fp, const t_lambda *fep1, const t_lambda *fep2, real ftol, real abstol) +static void cmp_fepvals(FILE* fp, const t_lambda* fep1, const t_lambda* fep2, real ftol, real abstol) { int i, j; cmp_int(fp, "inputrec->nstdhdl", -1, fep1->nstdhdl, fep2->nstdhdl); - cmp_double(fp, "inputrec->fepvals->init_fep_state", -1, fep1->init_fep_state, fep2->init_fep_state, ftol, abstol); - cmp_double(fp, "inputrec->fepvals->delta_lambda", -1, fep1->delta_lambda, fep2->delta_lambda, ftol, abstol); + cmp_double(fp, "inputrec->fepvals->init_fep_state", -1, fep1->init_fep_state, + fep2->init_fep_state, ftol, abstol); + cmp_double(fp, "inputrec->fepvals->delta_lambda", -1, fep1->delta_lambda, fep2->delta_lambda, + ftol, abstol); cmp_int(fp, "inputrec->fepvals->n_lambda", -1, fep1->n_lambda, fep2->n_lambda); for (i = 0; i < efptNR; i++) { for (j = 0; j < std::min(fep1->n_lambda, fep2->n_lambda); j++) { - cmp_double(fp, "inputrec->fepvals->all_lambda", -1, fep1->all_lambda[i][j], fep2->all_lambda[i][j], ftol, abstol); + cmp_double(fp, "inputrec->fepvals->all_lambda", -1, fep1->all_lambda[i][j], + fep2->all_lambda[i][j], ftol, abstol); } } - cmp_int(fp, "inputrec->fepvals->lambda_neighbors", 1, fep1->lambda_neighbors, - fep2->lambda_neighbors); + cmp_int(fp, "inputrec->fepvals->lambda_neighbors", 1, fep1->lambda_neighbors, fep2->lambda_neighbors); cmp_real(fp, "inputrec->fepvals->sc_alpha", -1, fep1->sc_alpha, fep2->sc_alpha, ftol, abstol); cmp_int(fp, "inputrec->fepvals->sc_power", -1, fep1->sc_power, fep2->sc_power); cmp_real(fp, "inputrec->fepvals->sc_r_power", -1, fep1->sc_r_power, fep2->sc_r_power, ftol, abstol); @@ -1251,10 +1273,11 @@ static void cmp_fepvals(FILE *fp, const t_lambda *fep1, const t_lambda *fep2, re cmp_int(fp, "inputrec->separate_dhdl_file", -1, fep1->separate_dhdl_file, fep2->separate_dhdl_file); cmp_int(fp, "inputrec->dhdl_derivatives", -1, fep1->dhdl_derivatives, fep2->dhdl_derivatives); cmp_int(fp, "inputrec->dh_hist_size", -1, fep1->dh_hist_size, fep2->dh_hist_size); - cmp_double(fp, "inputrec->dh_hist_spacing", -1, fep1->dh_hist_spacing, fep2->dh_hist_spacing, ftol, abstol); + cmp_double(fp, "inputrec->dh_hist_spacing", -1, fep1->dh_hist_spacing, fep2->dh_hist_spacing, + ftol, abstol); } -void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real ftol, real abstol) +void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real ftol, real abstol) { fprintf(fp, "comparing inputrec\n"); @@ -1284,7 +1307,8 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f cmp_int(fp, "inputrec->nstxout_compressed", -1, ir1->nstxout_compressed, ir2->nstxout_compressed); cmp_double(fp, "inputrec->init_t", -1, ir1->init_t, ir2->init_t, ftol, abstol); cmp_double(fp, "inputrec->delta_t", -1, ir1->delta_t, ir2->delta_t, ftol, abstol); - cmp_real(fp, "inputrec->x_compression_precision", -1, ir1->x_compression_precision, ir2->x_compression_precision, ftol, abstol); + cmp_real(fp, "inputrec->x_compression_precision", -1, ir1->x_compression_precision, + ir2->x_compression_precision, ftol, abstol); cmp_real(fp, "inputrec->fourierspacing", -1, ir1->fourier_spacing, ir2->fourier_spacing, ftol, abstol); cmp_int(fp, "inputrec->nkx", -1, ir1->nkx, ir2->nkx); cmp_int(fp, "inputrec->nky", -1, ir1->nky, ir2->nky); @@ -1293,10 +1317,13 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f cmp_real(fp, "inputrec->ewald_rtol", -1, ir1->ewald_rtol, ir2->ewald_rtol, ftol, abstol); cmp_int(fp, "inputrec->ewald_geometry", -1, ir1->ewald_geometry, ir2->ewald_geometry); cmp_real(fp, "inputrec->epsilon_surface", -1, ir1->epsilon_surface, ir2->epsilon_surface, ftol, abstol); - cmp_int(fp, "inputrec->bContinuation", -1, static_cast(ir1->bContinuation), static_cast(ir2->bContinuation)); - cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast(ir1->bShakeSOR), static_cast(ir2->bShakeSOR)); + cmp_int(fp, "inputrec->bContinuation", -1, static_cast(ir1->bContinuation), + static_cast(ir2->bContinuation)); + cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast(ir1->bShakeSOR), + static_cast(ir2->bShakeSOR)); cmp_int(fp, "inputrec->etc", -1, ir1->etc, ir2->etc); - cmp_int(fp, "inputrec->bPrintNHChains", -1, static_cast(ir1->bPrintNHChains), static_cast(ir2->bPrintNHChains)); + cmp_int(fp, "inputrec->bPrintNHChains", -1, static_cast(ir1->bPrintNHChains), + static_cast(ir2->bPrintNHChains)); cmp_int(fp, "inputrec->epc", -1, ir1->epc, ir2->epc); cmp_int(fp, "inputrec->epct", -1, ir1->epct, ir2->epct); cmp_real(fp, "inputrec->tau_p", -1, ir1->tau_p, ir2->tau_p, ftol, abstol); @@ -1317,7 +1344,8 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f cmp_real(fp, "inputrec->rcoulomb_switch", -1, ir1->rcoulomb_switch, ir2->rcoulomb_switch, ftol, abstol); cmp_real(fp, "inputrec->rcoulomb", -1, ir1->rcoulomb, ir2->rcoulomb, ftol, abstol); cmp_int(fp, "inputrec->vdwtype", -1, ir1->vdwtype, ir2->vdwtype); - cmp_int(fp, "inputrec->vdw_modifier", -1, ir1->vdw_modifier, ir2->vdw_modifier); cmp_real(fp, "inputrec->rvdw_switch", -1, ir1->rvdw_switch, ir2->rvdw_switch, ftol, abstol); + cmp_int(fp, "inputrec->vdw_modifier", -1, ir1->vdw_modifier, ir2->vdw_modifier); + cmp_real(fp, "inputrec->rvdw_switch", -1, ir1->rvdw_switch, ir2->rvdw_switch, ftol, abstol); cmp_real(fp, "inputrec->rvdw", -1, ir1->rvdw, ir2->rvdw, ftol, abstol); cmp_real(fp, "inputrec->epsilon_r", -1, ir1->epsilon_r, ir2->epsilon_r, ftol, abstol); cmp_real(fp, "inputrec->epsilon_rf", -1, ir1->epsilon_rf, ir2->epsilon_rf, ftol, abstol); @@ -1330,12 +1358,15 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f cmp_int(fp, "inputrec->bSimTemp", -1, static_cast(ir1->bSimTemp), static_cast(ir2->bSimTemp)); if ((ir1->bSimTemp == ir2->bSimTemp) && (ir1->bSimTemp)) { - cmp_simtempvals(fp, ir1->simtempvals, ir2->simtempvals, std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol); + cmp_simtempvals(fp, ir1->simtempvals, ir2->simtempvals, + std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol); } - cmp_int(fp, "inputrec->bExpanded", -1, static_cast(ir1->bExpanded), static_cast(ir2->bExpanded)); + cmp_int(fp, "inputrec->bExpanded", -1, static_cast(ir1->bExpanded), + static_cast(ir2->bExpanded)); if ((ir1->bExpanded == ir2->bExpanded) && (ir1->bExpanded)) { - cmp_expandedvals(fp, ir1->expandedvals, ir2->expandedvals, std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol); + cmp_expandedvals(fp, ir1->expandedvals, ir2->expandedvals, + std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda), ftol, abstol); } cmp_int(fp, "inputrec->nwall", -1, ir1->nwall, ir2->nwall); cmp_int(fp, "inputrec->wall_type", -1, ir1->wall_type, ir2->wall_type); @@ -1360,7 +1391,8 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f cmp_int(fp, "inputrec->eDisre", -1, ir1->eDisre, ir2->eDisre); cmp_real(fp, "inputrec->dr_fc", -1, ir1->dr_fc, ir2->dr_fc, ftol, abstol); cmp_int(fp, "inputrec->eDisreWeighting", -1, ir1->eDisreWeighting, ir2->eDisreWeighting); - cmp_int(fp, "inputrec->bDisreMixed", -1, static_cast(ir1->bDisreMixed), static_cast(ir2->bDisreMixed)); + cmp_int(fp, "inputrec->bDisreMixed", -1, static_cast(ir1->bDisreMixed), + static_cast(ir2->bDisreMixed)); cmp_int(fp, "inputrec->nstdisreout", -1, ir1->nstdisreout, ir2->nstdisreout); cmp_real(fp, "inputrec->dr_tau", -1, ir1->dr_tau, ir2->dr_tau, ftol, abstol); cmp_real(fp, "inputrec->orires_fc", -1, ir1->orires_fc, ir2->orires_fc, ftol, abstol); @@ -1397,7 +1429,7 @@ void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real f gmx::compareKeyValueTrees(&writer, *ir1->params, *ir2->params, ftol, abstol); } -void comp_pull_AB(FILE *fp, pull_params_t *pull, real ftol, real abstol) +void comp_pull_AB(FILE* fp, pull_params_t* pull, real ftol, real abstol) { int i; @@ -1408,58 +1440,55 @@ void comp_pull_AB(FILE *fp, pull_params_t *pull, real ftol, real abstol) } } -gmx_bool inputrecDeform(const t_inputrec *ir) +gmx_bool inputrecDeform(const t_inputrec* ir) { - return (ir->deform[XX][XX] != 0 || ir->deform[YY][YY] != 0 || ir->deform[ZZ][ZZ] != 0 || - ir->deform[YY][XX] != 0 || ir->deform[ZZ][XX] != 0 || ir->deform[ZZ][YY] != 0); + return (ir->deform[XX][XX] != 0 || ir->deform[YY][YY] != 0 || ir->deform[ZZ][ZZ] != 0 + || ir->deform[YY][XX] != 0 || ir->deform[ZZ][XX] != 0 || ir->deform[ZZ][YY] != 0); } -gmx_bool inputrecDynamicBox(const t_inputrec *ir) +gmx_bool inputrecDynamicBox(const t_inputrec* ir) { return (ir->epc != epcNO || ir->eI == eiTPI || inputrecDeform(ir)); } -gmx_bool inputrecPreserveShape(const t_inputrec *ir) +gmx_bool inputrecPreserveShape(const t_inputrec* ir) { - return (ir->epc != epcNO && ir->deform[XX][XX] == 0 && - (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC)); + return (ir->epc != epcNO && ir->deform[XX][XX] == 0 + && (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC)); } -gmx_bool inputrecNeedMutot(const t_inputrec *ir) +gmx_bool inputrecNeedMutot(const t_inputrec* ir) { - return ((ir->coulombtype == eelEWALD || EEL_PME(ir->coulombtype)) && - (ir->ewald_geometry == eewg3DC || ir->epsilon_surface != 0)); + return ((ir->coulombtype == eelEWALD || EEL_PME(ir->coulombtype)) + && (ir->ewald_geometry == eewg3DC || ir->epsilon_surface != 0)); } -gmx_bool inputrecExclForces(const t_inputrec *ir) +gmx_bool inputrecExclForces(const t_inputrec* ir) { return (EEL_FULL(ir->coulombtype) || (EEL_RF(ir->coulombtype))); } -gmx_bool inputrecNptTrotter(const t_inputrec *ir) +gmx_bool inputrecNptTrotter(const t_inputrec* ir) { - return ( ( (ir->eI == eiVV) || (ir->eI == eiVVAK) ) && - (ir->epc == epcMTTK) && (ir->etc == etcNOSEHOOVER) ); + return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc == etcNOSEHOOVER)); } -gmx_bool inputrecNvtTrotter(const t_inputrec *ir) +gmx_bool inputrecNvtTrotter(const t_inputrec* ir) { - return ( ( (ir->eI == eiVV) || (ir->eI == eiVVAK) ) && - (ir->epc != epcMTTK) && (ir->etc == etcNOSEHOOVER) ); + return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != epcMTTK) && (ir->etc == etcNOSEHOOVER)); } -gmx_bool inputrecNphTrotter(const t_inputrec *ir) +gmx_bool inputrecNphTrotter(const t_inputrec* ir) { - return ( ( (ir->eI == eiVV) || (ir->eI == eiVVAK) ) && - (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER) ); + return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER)); } -bool inputrecPbcXY2Walls(const t_inputrec *ir) +bool inputrecPbcXY2Walls(const t_inputrec* ir) { return (ir->ePBC == epbcXY && ir->nwall == 2); } -bool integratorHasConservedEnergyQuantity(const t_inputrec *ir) +bool integratorHasConservedEnergyQuantity(const t_inputrec* ir) { if (!EI_MD(ir->eI)) { @@ -1475,19 +1504,19 @@ bool integratorHasConservedEnergyQuantity(const t_inputrec *ir) { // Shear stress with Parrinello-Rahman is not supported (tedious) bool shearWithPR = - ((ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK) && - (ir->ref_p[YY][XX] != 0 || ir->ref_p[ZZ][XX] != 0 || ir->ref_p[ZZ][YY] != 0)); + ((ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK) + && (ir->ref_p[YY][XX] != 0 || ir->ref_p[ZZ][XX] != 0 || ir->ref_p[ZZ][YY] != 0)); return !ETC_ANDERSEN(ir->etc) && !shearWithPR; } } -bool integratorHasReferenceTemperature(const t_inputrec *ir) +bool integratorHasReferenceTemperature(const t_inputrec* ir) { return ((ir->etc != etcNO) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI)); } -int inputrec2nboundeddim(const t_inputrec *ir) +int inputrec2nboundeddim(const t_inputrec* ir) { if (inputrecPbcXY2Walls(ir)) { @@ -1499,30 +1528,23 @@ int inputrec2nboundeddim(const t_inputrec *ir) } } -int ndof_com(const t_inputrec *ir) +int ndof_com(const t_inputrec* ir) { int n = 0; switch (ir->ePBC) { case epbcXYZ: - case epbcNONE: - n = 3; - break; - case epbcXY: - n = (ir->nwall == 0 ? 3 : 2); - break; - case epbcSCREW: - n = 1; - break; - default: - gmx_incons("Unknown pbc in calc_nrdf"); + case epbcNONE: n = 3; break; + case epbcXY: n = (ir->nwall == 0 ? 3 : 2); break; + case epbcSCREW: n = 1; break; + default: gmx_incons("Unknown pbc in calc_nrdf"); } return n; } -real maxReferenceTemperature(const t_inputrec &ir) +real maxReferenceTemperature(const t_inputrec& ir) { if (EI_ENERGY_MINIMIZATION(ir.eI) || ir.eI == eiNM) { @@ -1550,8 +1572,7 @@ real maxReferenceTemperature(const t_inputrec &ir) return maxTemperature; } -bool haveEwaldSurfaceContribution(const t_inputrec &ir) +bool haveEwaldSurfaceContribution(const t_inputrec& ir) { - return EEL_PME_EWALD(ir.coulombtype) && (ir.ewald_geometry == eewg3DC || - ir.epsilon_surface != 0); + return EEL_PME_EWALD(ir.coulombtype) && (ir.ewald_geometry == eewg3DC || ir.epsilon_surface != 0); } diff --git a/src/gromacs/mdtypes/inputrec.h b/src/gromacs/mdtypes/inputrec.h index 86dc181cd1..266670f3ef 100644 --- a/src/gromacs/mdtypes/inputrec.h +++ b/src/gromacs/mdtypes/inputrec.h @@ -46,8 +46,8 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -#define EGP_EXCL (1<<0) -#define EGP_TABLE (1<<1) +#define EGP_EXCL (1 << 0) +#define EGP_TABLE (1 << 1) struct gmx_enfrot; struct gmx_enfrotgrp; @@ -58,249 +58,250 @@ namespace gmx class Awh; struct AwhParams; class KeyValueTreeObject; -} +} // namespace gmx struct t_grpopts { //! Number of T-Coupl groups - int ngtc; + int ngtc; //! Number of of Nose-Hoover chains per group - int nhchainlength; + int nhchainlength; //! Number of Accelerate groups - int ngacc; + int ngacc; //! Number of Freeze groups - int ngfrz; + int ngfrz; //! Number of Energy groups - int ngener; + int ngener; //! Number of degrees of freedom in a group - real *nrdf; + real* nrdf; //! Coupling temperature per group - real *ref_t; + real* ref_t; //! No/simple/periodic simulated annealing for each group - int *annealing; + int* annealing; //! Number of annealing time points per group - int *anneal_npoints; + int* anneal_npoints; //! For each group: Time points - real **anneal_time; + real** anneal_time; //! For each group: Temperature at these times. Final temp after all intervals is ref_t - real **anneal_temp; + real** anneal_temp; //! Tau coupling time - real *tau_t; + real* tau_t; //! Acceleration per group - rvec *acc; + rvec* acc; //! Whether the group will be frozen in each direction - ivec *nFreeze; + ivec* nFreeze; //! Exclusions/tables of energy group pairs - int *egp_flags; + int* egp_flags; /* QMMM stuff */ //! Number of QM groups - int ngQM; + int ngQM; //! Level of theory in the QM calculation - int *QMmethod; + int* QMmethod; //! Basisset in the QM calculation - int *QMbasis; + int* QMbasis; //! Total charge in the QM region - int *QMcharge; + int* QMcharge; //! Spin multiplicicty in the QM region - int *QMmult; + int* QMmult; //! Surface hopping (diabatic hop only) - gmx_bool *bSH; + gmx_bool* bSH; //! Number of orbiatls in the active space - int *CASorbitals; + int* CASorbitals; //! Number of electrons in the active space - int *CASelectrons; + int* CASelectrons; //! At which gap (A.U.) the SA is switched on - real *SAon; + real* SAon; //! At which gap (A.U.) the SA is switched off - real *SAoff; + real* SAoff; //! In how many steps SA goes from 1-1 to 0.5-0.5 - int *SAsteps; + int* SAsteps; }; struct t_simtemp { //! Simulated temperature scaling; linear or exponential - int eSimTempScale; + int eSimTempScale; //! The low temperature for simulated tempering - real simtemp_low; + real simtemp_low; //! The high temperature for simulated tempering - real simtemp_high; + real simtemp_high; //! The range of temperatures used for simulated tempering - real *temperatures; + real* temperatures; }; struct t_lambda { //! The frequency for calculating dhdl - int nstdhdl; + int nstdhdl; //! Fractional value of lambda (usually will use init_fep_state, this will only be for slow growth, and for legacy free energy code. Only has a valid value if positive) - double init_lambda; + double init_lambda; //! The initial number of the state - int init_fep_state; + int init_fep_state; //! Change of lambda per time step (fraction of (0.1) - double delta_lambda; + double delta_lambda; //! Print no, total or potential energies in dhdl - int edHdLPrintEnergy; + int edHdLPrintEnergy; //! The number of foreign lambda points - int n_lambda; + int n_lambda; //! The array of all lambda values - double **all_lambda; + double** all_lambda; //! The number of neighboring lambda states to calculate the energy for in up and down directions (-1 for all) - int lambda_neighbors; + int lambda_neighbors; //! The first lambda to calculate energies for - int lambda_start_n; + int lambda_start_n; //! The last lambda +1 to calculate energies for - int lambda_stop_n; + int lambda_stop_n; //! Free energy soft-core parameter - real sc_alpha; + real sc_alpha; //! Lambda power for soft-core interactions - int sc_power; + int sc_power; //! R power for soft-core interactions - real sc_r_power; + real sc_r_power; //! Free energy soft-core sigma when c6 or c12=0 - real sc_sigma; + real sc_sigma; //! Free energy soft-core sigma for ????? - real sc_sigma_min; + real sc_sigma_min; //! Use softcore for the coulomb portion as well (default FALSE) gmx_bool bScCoul; //! Whether to print the dvdl term associated with this term; if it is not specified as separate, it is lumped with the FEP term gmx_bool separate_dvdl[efptNR]; //! Whether to write a separate dhdl.xvg file note: NOT a gmx_bool, but an enum - int separate_dhdl_file; + int separate_dhdl_file; //! Whether to calculate+write dhdl derivatives note: NOT a gmx_bool, but an enum - int dhdl_derivatives; + int dhdl_derivatives; //! The maximum table size for the dH histogram - int dh_hist_size; + int dh_hist_size; //! The spacing for the dH histogram - double dh_hist_spacing; + double dh_hist_spacing; }; -struct t_expanded { +struct t_expanded +{ //! The frequency of expanded ensemble state changes - int nstexpanded; + int nstexpanded; //! Which type of move updating do we use for lambda monte carlo (or no for none) - int elamstats; + int elamstats; //! What move set will be we using for state space moves - int elmcmove; + int elmcmove; //! The method we use to decide of we have equilibrated the weights - int elmceq; + int elmceq; //! The minumum number of samples at each lambda for deciding whether we have reached a minimum - int equil_n_at_lam; + int equil_n_at_lam; //! Wang-Landau delta at which we stop equilibrating weights - real equil_wl_delta; + real equil_wl_delta; //! Use the ratio of weights (ratio of minimum to maximum) to decide when to stop equilibrating - real equil_ratio; + real equil_ratio; //! After equil_steps steps we stop equilibrating the weights - int equil_steps; + int equil_steps; //! After equil_samples total samples (steps/nstfep), we stop equilibrating the weights - int equil_samples; + int equil_samples; //! Random number seed for lambda mc switches - int lmc_seed; + int lmc_seed; //! Whether to use minumum variance weighting gmx_bool minvar; //! The number of samples needed before kicking into minvar routine - int minvarmin; + int minvarmin; //! The offset for the variance in MinVar - real minvar_const; + real minvar_const; //! Range of cvalues used for BAR - int c_range; + int c_range; //! Whether to print symmetrized matrices gmx_bool bSymmetrizedTMatrix; //! How frequently to print the transition matrices - int nstTij; + int nstTij; //! Number of repetitions in the MC lambda jumps MRS -- VERIFY THIS - int lmc_repeats; + int lmc_repeats; //! Minimum number of samples for each state before free sampling MRS -- VERIFY THIS! - int lmc_forced_nstart; + int lmc_forced_nstart; //! Distance in lambda space for the gibbs interval - int gibbsdeltalam; + int gibbsdeltalam; //! Scaling factor for Wang-Landau - real wl_scale; + real wl_scale; //! Ratio between largest and smallest number for freezing the weights - real wl_ratio; + real wl_ratio; //! Starting delta for Wang-Landau - real init_wl_delta; + real init_wl_delta; //! Use one over t convergence for Wang-Landau when the delta get sufficiently small gmx_bool bWLoneovert; //! Did we initialize the weights? TODO: REMOVE FOR 5.0, no longer needed with new logic gmx_bool bInit_weights; //! To override the main temperature, or define it if it's not defined - real mc_temp; + real mc_temp; //! User-specified initial weights to start with - real *init_lambda_weights; + real* init_lambda_weights; }; struct t_rotgrp { //! Rotation type for this group - int eType; + int eType; //! Use mass-weighed positions? - int bMassW; + int bMassW; //! Number of atoms in the group - int nat; + int nat; //! The global atoms numbers - int *ind; + int* ind; //! The reference positions - rvec *x_ref; + rvec* x_ref; //! The normalized rotation vector - rvec inputVec; + rvec inputVec; //! Rate of rotation (degree/ps) - real rate; + real rate; //! Force constant (kJ/(mol nm^2) - real k; + real k; //! Pivot point of rotation axis (nm) - rvec pivot; + rvec pivot; //! Type of fit to determine actual group angle - int eFittype; + int eFittype; //! Number of angles around the reference angle for which the rotation potential is also evaluated (for fit type 'potential' only) - int PotAngle_nstep; + int PotAngle_nstep; //! Distance between two angles in degrees (for fit type 'potential' only) - real PotAngle_step; + real PotAngle_step; //! Slab distance (nm) - real slab_dist; + real slab_dist; //! Minimum value the gaussian must have so that the force is actually evaluated - real min_gaussian; + real min_gaussian; //! Additive constant for radial motion2 and flexible2 potentials (nm^2) - real eps; + real eps; }; struct t_rot { //! Number of rotation groups - int ngrp; + int ngrp; //! Output frequency for main rotation outfile - int nstrout; + int nstrout; //! Output frequency for per-slab data - int nstsout; + int nstsout; //! Groups to rotate - t_rotgrp *grp; + t_rotgrp* grp; }; struct t_IMD { //! Number of interactive atoms - int nat; + int nat; //! The global indices of the interactive atoms - int *ind; + int* ind; }; struct t_swapGroup { //! Name of the swap group, e.g. NA, CL, SOL - char *molname; + char* molname; //! Number of atoms in this group - int nat; + int nat; //! The global ion group atoms numbers - int *ind; + int* ind; //! Requested number of molecules of this type per compartment - int nmolReq[eCompNR]; + int nmolReq[eCompNR]; }; struct t_swapcoords { //! Period between when a swap is attempted - int nstswap; + int nstswap; //! Use mass-weighted positions in split group gmx_bool massw_split[2]; /*! \brief Split cylinders defined by radius, upper and lower @@ -312,245 +313,245 @@ struct t_swapcoords real cyl0l, cyl1l; /**@}*/ //! Coupling constant (number of swap attempt steps) - int nAverage; + int nAverage; //! Ion counts may deviate from the requested values by +-threshold before a swap is done - real threshold; + real threshold; //! Offset of the swap layer (='bulk') with respect to the compartment-defining layers - real bulkOffset[eCompNR]; + real bulkOffset[eCompNR]; //! Number of groups to be controlled - int ngrp; + int ngrp; //! All swap groups, including split and solvent - t_swapGroup *grp; + t_swapGroup* grp; }; struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding) { t_inputrec(); - explicit t_inputrec(const t_inputrec &) = delete; - t_inputrec &operator=(const t_inputrec &) = delete; + explicit t_inputrec(const t_inputrec&) = delete; + t_inputrec& operator=(const t_inputrec&) = delete; ~t_inputrec(); //! Integration method - int eI; + int eI; //! Number of steps to be taken - int64_t nsteps; + int64_t nsteps; //! Used in checkpointing to separate chunks - int simulation_part; + int simulation_part; //! Start at a stepcount >0 (used w. convert-tpr) - int64_t init_step; + int64_t init_step; //! Frequency of energy calc. and T/P coupl. upd. - int nstcalcenergy; + int nstcalcenergy; //! Group or verlet cutoffs - int cutoff_scheme; + int cutoff_scheme; //! Number of steps before pairlist is generated - int nstlist; + int nstlist; //! Number of steps after which center of mass motion is removed - int nstcomm; + int nstcomm; //! Center of mass motion removal algorithm - int comm_mode; + int comm_mode; //! Number of steps after which print to logfile - int nstlog; + int nstlog; //! Number of steps after which X is output - int nstxout; + int nstxout; //! Number of steps after which V is output - int nstvout; + int nstvout; //! Number of steps after which F is output - int nstfout; + int nstfout; //! Number of steps after which energies printed - int nstenergy; + int nstenergy; //! Number of steps after which compressed trj (.xtc,.tng) is output - int nstxout_compressed; + int nstxout_compressed; //! Initial time (ps) - double init_t; + double init_t; //! Time step (ps) - double delta_t; + double delta_t; //! Precision of x in compressed trajectory file - real x_compression_precision; + real x_compression_precision; //! Requested fourier_spacing, when nk? not set - real fourier_spacing; + real fourier_spacing; //! Number of k vectors in x dimension for fourier methods for long range electrost. - int nkx; + int nkx; //! Number of k vectors in y dimension for fourier methods for long range electrost. - int nky; + int nky; //! Number of k vectors in z dimension for fourier methods for long range electrost. - int nkz; + int nkz; //! Interpolation order for PME - int pme_order; + int pme_order; //! Real space tolerance for Ewald, determines the real/reciprocal space relative weight - real ewald_rtol; + real ewald_rtol; //! Real space tolerance for LJ-Ewald - real ewald_rtol_lj; + real ewald_rtol_lj; //! Normal/3D ewald, or pseudo-2D LR corrections - int ewald_geometry; + int ewald_geometry; //! Epsilon for PME dipole correction - real epsilon_surface; + real epsilon_surface; //! Type of combination rule in LJ-PME - int ljpme_combination_rule; + int ljpme_combination_rule; //! Type of periodic boundary conditions - int ePBC; + int ePBC; //! Periodic molecules - bool bPeriodicMols; + bool bPeriodicMols; //! Continuation run: starting state is correct (ie. constrained) - gmx_bool bContinuation; + gmx_bool bContinuation; //! Temperature coupling - int etc; + int etc; //! Interval in steps for temperature coupling - int nsttcouple; + int nsttcouple; //! Whether to print nose-hoover chains - gmx_bool bPrintNHChains; + gmx_bool bPrintNHChains; //! Pressure coupling - int epc; + int epc; //! Pressure coupling type - int epct; + int epct; //! Interval in steps for pressure coupling - int nstpcouple; + int nstpcouple; //! Pressure coupling time (ps) - real tau_p; + real tau_p; //! Reference pressure (kJ/(mol nm^3)) - tensor ref_p; + tensor ref_p; //! Compressibility ((mol nm^3)/kJ) - tensor compress; + tensor compress; //! How to scale absolute reference coordinates - int refcoord_scaling; + int refcoord_scaling; //! The COM of the posres atoms - rvec posres_com; + rvec posres_com; //! The B-state COM of the posres atoms - rvec posres_comB; + rvec posres_comB; //! Random seed for Andersen thermostat (obsolete) - int andersen_seed; + int andersen_seed; //! Per atom pair energy drift tolerance (kJ/mol/ps/atom) for list buffer - real verletbuf_tol; + real verletbuf_tol; //! Short range pairlist cut-off (nm) - real rlist; + real rlist; //! Radius for test particle insertion - real rtpi; + real rtpi; //! Type of electrostatics treatment - int coulombtype; + int coulombtype; //! Modify the Coulomb interaction - int coulomb_modifier; + int coulomb_modifier; //! Coulomb switch range start (nm) - real rcoulomb_switch; + real rcoulomb_switch; //! Coulomb cutoff (nm) - real rcoulomb; + real rcoulomb; //! Relative dielectric constant - real epsilon_r; + real epsilon_r; //! Relative dielectric constant of the RF - real epsilon_rf; + real epsilon_rf; //! Always false (no longer supported) - bool implicit_solvent; + bool implicit_solvent; //! Type of Van der Waals treatment - int vdwtype; + int vdwtype; //! Modify the Van der Waals interaction - int vdw_modifier; + int vdw_modifier; //! Van der Waals switch range start (nm) - real rvdw_switch; + real rvdw_switch; //! Van der Waals cutoff (nm) - real rvdw; + real rvdw; //! Perform Long range dispersion corrections - int eDispCorr; + int eDispCorr; //! Extension of the table beyond the cut-off, as well as the table length for 1-4 interac. - real tabext; + real tabext; //! Tolerance for shake - real shake_tol; + real shake_tol; //! Free energy calculations - int efep; + int efep; //! Data for the FEP state - t_lambda *fepvals; + t_lambda* fepvals; //! Whether to do simulated tempering - gmx_bool bSimTemp; + gmx_bool bSimTemp; //! Variables for simulated tempering - t_simtemp *simtempvals; + t_simtemp* simtempvals; //! Whether expanded ensembles are used - gmx_bool bExpanded; + gmx_bool bExpanded; //! Expanded ensemble parameters - t_expanded *expandedvals; + t_expanded* expandedvals; //! Type of distance restraining - int eDisre; + int eDisre; //! Force constant for time averaged distance restraints - real dr_fc; + real dr_fc; //! Type of weighting of pairs in one restraints - int eDisreWeighting; + int eDisreWeighting; //! Use combination of time averaged and instantaneous violations - gmx_bool bDisreMixed; + gmx_bool bDisreMixed; //! Frequency of writing pair distances to enx - int nstdisreout; + int nstdisreout; //! Time constant for memory function in disres - real dr_tau; + real dr_tau; //! Force constant for orientational restraints - real orires_fc; + real orires_fc; //! Time constant for memory function in orires - real orires_tau; + real orires_tau; //! Frequency of writing tr(SD) to energy output - int nstorireout; + int nstorireout; //! The stepsize for updating - real em_stepsize; + real em_stepsize; //! The tolerance - real em_tol; + real em_tol; //! Number of iterations for convergence of steepest descent in relax_shells - int niter; + int niter; //! Stepsize for directional minimization in relax_shells - real fc_stepsize; + real fc_stepsize; //! Number of steps after which a steepest descents step is done while doing cg - int nstcgsteep; + int nstcgsteep; //! Number of corrections to the Hessian to keep - int nbfgscorr; + int nbfgscorr; //! Type of constraint algorithm - int eConstrAlg; + int eConstrAlg; //! Order of the LINCS Projection Algorithm - int nProjOrder; + int nProjOrder; //! Warn if any bond rotates more than this many degrees - real LincsWarnAngle; + real LincsWarnAngle; //! Number of iterations in the final LINCS step - int nLincsIter; + int nLincsIter; //! Use successive overrelaxation for shake - gmx_bool bShakeSOR; + gmx_bool bShakeSOR; //! Friction coefficient for BD (amu/ps) - real bd_fric; + real bd_fric; //! Random seed for SD and BD - int64_t ld_seed; + int64_t ld_seed; //! The number of walls - int nwall; + int nwall; //! The type of walls - int wall_type; + int wall_type; //! The potentail is linear for r<=wall_r_linpot - real wall_r_linpot; + real wall_r_linpot; //! The atom type for walls - int wall_atomtype[2]; + int wall_atomtype[2]; //! Number density for walls - real wall_density[2]; + real wall_density[2]; //! Scaling factor for the box for Ewald - real wall_ewald_zfac; + real wall_ewald_zfac; /* COM pulling data */ //! Do we do COM pulling? - gmx_bool bPull; + gmx_bool bPull; //! The data for center of mass pulling - pull_params_t *pull; + pull_params_t* pull; /* AWH bias data */ //! Whether to use AWH biasing for PMF calculations - gmx_bool bDoAwh; + gmx_bool bDoAwh; //! AWH biasing parameters - gmx::AwhParams *awhParams; + gmx::AwhParams* awhParams; /* Enforced rotation data */ //! Whether to calculate enforced rotation potential(s) - gmx_bool bRot; + gmx_bool bRot; //! The data for enforced rotation potentials - t_rot *rot; + t_rot* rot; //! Whether to do ion/water position exchanges (CompEL) - int eSwapCoords; + int eSwapCoords; //! Swap data structure. - t_swapcoords *swap; + t_swapcoords* swap; //! Whether the tpr makes an interactive MD session possible. - gmx_bool bIMD; + gmx_bool bIMD; //! Interactive molecular dynamics - t_IMD *imd; + t_IMD* imd; //! Acceleration for viscosity calculation - real cos_accel; + real cos_accel; //! Triclinic deformation velocities (nm/ps) tensor deform; /*! \brief User determined parameters */ @@ -567,62 +568,62 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding) //! Group options t_grpopts opts; //! QM/MM calculation - gmx_bool bQMMM; + gmx_bool bQMMM; //! Constraints on QM bonds - int QMconstraints; + int QMconstraints; //! Scheme: ONIOM or normal - int QMMMscheme; + int QMMMscheme; //! Factor for scaling the MM charges in QM calc. - real scalefactor; + real scalefactor; /* Fields for removed features go here (better caching) */ //! Whether AdResS is enabled - always false if a valid .tpr was read - gmx_bool bAdress; + gmx_bool bAdress; //! Whether twin-range scheme is active - always false if a valid .tpr was read - gmx_bool useTwinRange; + gmx_bool useTwinRange; //! KVT object that contains input parameters converted to the new style. - gmx::KeyValueTreeObject *params; + gmx::KeyValueTreeObject* params; //! KVT for storing simulation parameters that are not part of the mdp file. - std::unique_ptr internalParameters; + std::unique_ptr internalParameters; }; -int ir_optimal_nstcalcenergy(const t_inputrec *ir); +int ir_optimal_nstcalcenergy(const t_inputrec* ir); int tcouple_min_integration_steps(int etc); -int ir_optimal_nsttcouple(const t_inputrec *ir); +int ir_optimal_nsttcouple(const t_inputrec* ir); int pcouple_min_integration_steps(int epc); -int ir_optimal_nstpcouple(const t_inputrec *ir); +int ir_optimal_nstpcouple(const t_inputrec* ir); /* Returns if the Coulomb force or potential is switched to zero */ -gmx_bool ir_coulomb_switched(const t_inputrec *ir); +gmx_bool ir_coulomb_switched(const t_inputrec* ir); /* Returns if the Coulomb interactions are zero beyond the rcoulomb. * Note: always returns TRUE for the Verlet cut-off scheme. */ -gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec *ir); +gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec* ir); /* As ir_coulomb_is_zero_at_cutoff, but also returns TRUE for user tabulated * interactions, since these might be zero beyond rcoulomb. */ -gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec *ir); +gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec* ir); /* Returns if the Van der Waals force or potential is switched to zero */ -gmx_bool ir_vdw_switched(const t_inputrec *ir); +gmx_bool ir_vdw_switched(const t_inputrec* ir); /* Returns if the Van der Waals interactions are zero beyond the rvdw. * Note: always returns TRUE for the Verlet cut-off scheme. */ -gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec *ir); +gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec* ir); /* As ir_vdw_is_zero_at_cutoff, but also returns TRUE for user tabulated * interactions, since these might be zero beyond rvdw. */ -gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec *ir); +gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec* ir); /*! \brief Free memory from input record. * @@ -630,44 +631,43 @@ gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec *ir); * * \param[in] ir The data structure */ -void done_inputrec(t_inputrec *ir); +void done_inputrec(t_inputrec* ir); -void pr_inputrec(FILE *fp, int indent, const char *title, const t_inputrec *ir, - gmx_bool bMDPformat); +void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir, gmx_bool bMDPformat); -void cmp_inputrec(FILE *fp, const t_inputrec *ir1, const t_inputrec *ir2, real ftol, real abstol); +void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real ftol, real abstol); -void comp_pull_AB(FILE *fp, pull_params_t *pull, real ftol, real abstol); +void comp_pull_AB(FILE* fp, pull_params_t* pull, real ftol, real abstol); -gmx_bool inputrecDeform(const t_inputrec *ir); +gmx_bool inputrecDeform(const t_inputrec* ir); -gmx_bool inputrecDynamicBox(const t_inputrec *ir); +gmx_bool inputrecDynamicBox(const t_inputrec* ir); -gmx_bool inputrecPreserveShape(const t_inputrec *ir); +gmx_bool inputrecPreserveShape(const t_inputrec* ir); -gmx_bool inputrecNeedMutot(const t_inputrec *ir); +gmx_bool inputrecNeedMutot(const t_inputrec* ir); -gmx_bool inputrecTwinRange(const t_inputrec *ir); +gmx_bool inputrecTwinRange(const t_inputrec* ir); -gmx_bool inputrecExclForces(const t_inputrec *ir); +gmx_bool inputrecExclForces(const t_inputrec* ir); -gmx_bool inputrecNptTrotter(const t_inputrec *ir); +gmx_bool inputrecNptTrotter(const t_inputrec* ir); -gmx_bool inputrecNvtTrotter(const t_inputrec *ir); +gmx_bool inputrecNvtTrotter(const t_inputrec* ir); -gmx_bool inputrecNphTrotter(const t_inputrec *ir); +gmx_bool inputrecNphTrotter(const t_inputrec* ir); /*! \brief Return true if the simulation is 2D periodic with two walls. */ -bool inputrecPbcXY2Walls(const t_inputrec *ir); +bool inputrecPbcXY2Walls(const t_inputrec* ir); /*! \brief Returns true for MD integator with T and/or P-coupling that supports * calculating the conserved energy quantity. */ -bool integratorHasConservedEnergyQuantity(const t_inputrec *ir); +bool integratorHasConservedEnergyQuantity(const t_inputrec* ir); /*! \brief Returns true when temperature is coupled or constant. */ -bool integratorHasReferenceTemperature(const t_inputrec *ir); +bool integratorHasReferenceTemperature(const t_inputrec* ir); /*! \brief Return the number of bounded dimensions * @@ -675,14 +675,14 @@ bool integratorHasReferenceTemperature(const t_inputrec *ir); * \return the number of dimensions in which * the coordinates of the particles are bounded, starting at X. */ -int inputrec2nboundeddim(const t_inputrec *ir); +int inputrec2nboundeddim(const t_inputrec* ir); /*! \brief Returns the number of degrees of freedom in center of mass motion * * \param[in] ir The inputrec structure * \return the number of degrees of freedom of the center of mass */ -int ndof_com(const t_inputrec *ir); +int ndof_com(const t_inputrec* ir); /*! \brief Returns the maximum reference temperature over all coupled groups * @@ -691,10 +691,10 @@ int ndof_com(const t_inputrec *ir); * * \param[in] ir The inputrec structure */ -real maxReferenceTemperature(const t_inputrec &ir); +real maxReferenceTemperature(const t_inputrec& ir); /*! \brief Returns whether there is an Ewald surface contribution */ -bool haveEwaldSurfaceContribution(const t_inputrec &ir); +bool haveEwaldSurfaceContribution(const t_inputrec& ir); #endif /* GMX_MDTYPES_INPUTREC_H */ diff --git a/src/gromacs/mdtypes/interaction_const.h b/src/gromacs/mdtypes/interaction_const.h index 0e0e435ecd..90b77649ae 100644 --- a/src/gromacs/mdtypes/interaction_const.h +++ b/src/gromacs/mdtypes/interaction_const.h @@ -72,7 +72,7 @@ struct switch_consts_t /* Convenience type for vector with aligned memory */ template -using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; +using AlignedVector = std::vector>; /* Force/energy interpolation tables for Ewald long-range corrections * @@ -81,7 +81,7 @@ using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; struct EwaldCorrectionTables { // 1/table_spacing, units 1/nm - real scale = 0; + real scale = 0; // Force table AlignedVector tableF; // Energy table @@ -103,7 +103,7 @@ struct EwaldCorrectionTables */ struct interaction_const_t { - int cutoff_scheme = ecutsVERLET; + int cutoff_scheme = ecutsVERLET; /* VdW */ int vdwtype = evdwCUT; @@ -118,8 +118,8 @@ struct interaction_const_t real buckinghamBMax = 0; /* type of electrostatics */ - int eeltype = eelCUT; - int coulomb_modifier = eintmodNONE; + int eeltype = eelCUT; + int coulomb_modifier = eintmodNONE; /* Coulomb */ real rcoulomb = 1; diff --git a/src/gromacs/mdtypes/locality.h b/src/gromacs/mdtypes/locality.h index dc26063874..4805336f1c 100644 --- a/src/gromacs/mdtypes/locality.h +++ b/src/gromacs/mdtypes/locality.h @@ -62,7 +62,9 @@ enum class AtomLocality : int }; /*! \brief Descriptive strings for atom localities */ -static const EnumerationArray c_atomLocalityNames = { { "local", "non-local", "all" } }; +static const EnumerationArray c_atomLocalityNames = { + { "local", "non-local", "all" } +}; /*! \brief Interaction locality indicator: local, non-local, all. * @@ -77,8 +79,10 @@ enum class InteractionLocality : int }; /*! \brief Descriptive strings for interaction localities */ -static const EnumerationArray c_interactionLocalityNames = { { "local", "non-local" } }; +static const EnumerationArray c_interactionLocalityNames = { + { "local", "non-local" } +}; -} // namespace gmx +} // namespace gmx #endif // GMX_MDTYPES_LOCALITY_H diff --git a/src/gromacs/mdtypes/md_enums.cpp b/src/gromacs/mdtypes/md_enums.cpp index b3f231d4d0..98d46895b9 100644 --- a/src/gromacs/mdtypes/md_enums.cpp +++ b/src/gromacs/mdtypes/md_enums.cpp @@ -38,11 +38,11 @@ #include "md_enums.h" -const char *enum_name(int index, int max_index, const char *names[]) +const char* enum_name(int index, int max_index, const char* names[]) { if (index < 0 || index >= max_index) { - static const char *undef = "no name defined"; + static const char* undef = "no name defined"; return undef; } else @@ -51,197 +51,153 @@ const char *enum_name(int index, int max_index, const char *names[]) } } -const char *yesno_names[BOOL_NR+1] = -{ - "no", "yes", nullptr -}; +const char* yesno_names[BOOL_NR + 1] = { "no", "yes", nullptr }; -const char *ei_names[eiNR+1] = -{ - "md", "steep", "cg", "bd", "sd2 - removed", "nm", "l-bfgs", "tpi", "tpic", "sd", "md-vv", "md-vv-avek", "mimic", nullptr -}; +const char* ei_names[eiNR + 1] = { "md", "steep", "cg", "bd", "sd2 - removed", + "nm", "l-bfgs", "tpi", "tpic", "sd", + "md-vv", "md-vv-avek", "mimic", nullptr }; -const char *ecutscheme_names[ecutsNR+1] = { - "Verlet", "Group", nullptr -}; +const char* ecutscheme_names[ecutsNR + 1] = { "Verlet", "Group", nullptr }; -const char *erefscaling_names[erscNR+1] = { - "No", "All", "COM", nullptr -}; +const char* erefscaling_names[erscNR + 1] = { "No", "All", "COM", nullptr }; -const char *eel_names[eelNR+1] = { - "Cut-off", "Reaction-Field", "Generalized-Reaction-Field (unused)", - "PME", "Ewald", "P3M-AD", "Poisson", "Switch", "Shift", "User", - "Generalized-Born (unused)", "Reaction-Field-nec", "Encad-shift", - "PME-User", "PME-Switch", "PME-User-Switch", - "Reaction-Field-zero", nullptr -}; +const char* eel_names[eelNR + 1] = { "Cut-off", + "Reaction-Field", + "Generalized-Reaction-Field (unused)", + "PME", + "Ewald", + "P3M-AD", + "Poisson", + "Switch", + "Shift", + "User", + "Generalized-Born (unused)", + "Reaction-Field-nec", + "Encad-shift", + "PME-User", + "PME-Switch", + "PME-User-Switch", + "Reaction-Field-zero", + nullptr }; -const char *eewg_names[eewgNR+1] = { - "3d", "3dc", nullptr -}; +const char* eewg_names[eewgNR + 1] = { "3d", "3dc", nullptr }; -const char *eljpme_names[eljpmeNR+1] = { - "Geometric", "Lorentz-Berthelot", nullptr -}; +const char* eljpme_names[eljpmeNR + 1] = { "Geometric", "Lorentz-Berthelot", nullptr }; -const char *evdw_names[evdwNR+1] = { - "Cut-off", "Switch", "Shift", "User", "Encad-shift", - "PME", nullptr -}; +const char* evdw_names[evdwNR + 1] = { "Cut-off", "Switch", "Shift", "User", + "Encad-shift", "PME", nullptr }; -const char *econstr_names[econtNR+1] = { - "Lincs", "Shake", nullptr -}; +const char* econstr_names[econtNR + 1] = { "Lincs", "Shake", nullptr }; -const char *eintmod_names[eintmodNR+1] = { - "Potential-shift-Verlet", "Potential-shift", "None", "Potential-switch", "Exact-cutoff", "Force-switch", nullptr +const char* eintmod_names[eintmodNR + 1] = { + "Potential-shift-Verlet", "Potential-shift", "None", "Potential-switch", + "Exact-cutoff", "Force-switch", nullptr }; -const char *etcoupl_names[etcNR+1] = { +const char* etcoupl_names[etcNR + 1] = { "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale", nullptr }; /* yes is alias for berendsen */ -const char *epcoupl_names[epcNR+1] = { +const char* epcoupl_names[epcNR + 1] = { "No", "Berendsen", "Parrinello-Rahman", "Isotropic", "MTTK", nullptr }; /* isotropic is alias for berendsen */ -const char *epcoupltype_names[epctNR+1] = { - "Isotropic", "Semiisotropic", "Anisotropic", "Surface-Tension", nullptr -}; +const char* epcoupltype_names[epctNR + 1] = { "Isotropic", "Semiisotropic", "Anisotropic", + "Surface-Tension", nullptr }; -const char *edisre_names[edrNR+1] = { - "No", "Simple", "Ensemble", nullptr -}; +const char* edisre_names[edrNR + 1] = { "No", "Simple", "Ensemble", nullptr }; -const char *edisreweighting_names[edrwNR+1] = { - "Conservative", "Equal", nullptr -}; +const char* edisreweighting_names[edrwNR + 1] = { "Conservative", "Equal", nullptr }; -const char *enbf_names[eNBF_NR+1] = { - "", "LJ", "Buckingham", nullptr -}; +const char* enbf_names[eNBF_NR + 1] = { "", "LJ", "Buckingham", nullptr }; -const char *ecomb_names[eCOMB_NR+1] = { - "", "Geometric", "Arithmetic", "GeomSigEps", nullptr -}; +const char* ecomb_names[eCOMB_NR + 1] = { "", "Geometric", "Arithmetic", "GeomSigEps", nullptr }; -const char *esimtemp_names[esimtempNR+1] = { - "geometric", "exponential", "linear", nullptr -}; +const char* esimtemp_names[esimtempNR + 1] = { "geometric", "exponential", "linear", nullptr }; -const char *efep_names[efepNR+1] = { - "no", "yes", "static", "slow-growth", "expanded", nullptr -}; +const char* efep_names[efepNR + 1] = { "no", "yes", "static", "slow-growth", "expanded", nullptr }; -const char *efpt_names[efptNR+1] = { - "fep-lambdas", "mass-lambdas", "coul-lambdas", "vdw-lambdas", "bonded-lambdas", "restraint-lambdas", "temperature-lambdas", nullptr -}; +const char* efpt_names[efptNR + 1] = { "fep-lambdas", "mass-lambdas", "coul-lambdas", + "vdw-lambdas", "bonded-lambdas", "restraint-lambdas", + "temperature-lambdas", nullptr }; -const char *efpt_singular_names[efptNR+1] = { - "fep-lambda", "mass-lambda", "coul-lambda", "vdw-lambda", "bonded-lambda", "restraint-lambda", "temperature-lambda", nullptr -}; +const char* efpt_singular_names[efptNR + 1] = { "fep-lambda", "mass-lambda", + "coul-lambda", "vdw-lambda", + "bonded-lambda", "restraint-lambda", + "temperature-lambda", nullptr }; -const char *edHdLPrintEnergy_names[edHdLPrintEnergyNR+1] = { - "no", "total", "potential", "yes", nullptr -}; +const char* edHdLPrintEnergy_names[edHdLPrintEnergyNR + 1] = { "no", "total", "potential", "yes", nullptr }; -const char *elamstats_names[elamstatsNR+1] = { - "no", "metropolis-transition", "barker-transition", "minvar", "wang-landau", "weighted-wang-landau", nullptr +const char* elamstats_names[elamstatsNR + 1] = { + "no", "metropolis-transition", "barker-transition", + "minvar", "wang-landau", "weighted-wang-landau", + nullptr }; -const char *elmcmove_names[elmcmoveNR+1] = { - "no", "metropolis", "barker", "gibbs", "metropolized-gibbs", nullptr -}; +const char* elmcmove_names[elmcmoveNR + 1] = { "no", "metropolis", "barker", + "gibbs", "metropolized-gibbs", nullptr }; -const char *elmceq_names[elmceqNR+1] = { - "no", "yes", "wl-delta", "number-all-lambda", "number-steps", "number-samples", "count-ratio", nullptr -}; +const char* elmceq_names[elmceqNR + 1] = { "no", "yes", + "wl-delta", "number-all-lambda", + "number-steps", "number-samples", + "count-ratio", nullptr }; -const char *separate_dhdl_file_names[esepdhdlfileNR+1] = { - "yes", "no", nullptr -}; +const char* separate_dhdl_file_names[esepdhdlfileNR + 1] = { "yes", "no", nullptr }; -const char *dhdl_derivatives_names[edhdlderivativesNR+1] = { - "yes", "no", nullptr -}; +const char* dhdl_derivatives_names[edhdlderivativesNR + 1] = { "yes", "no", nullptr }; -const char *esol_names[esolNR+1] = { - "No", "SPC", "TIP4p", nullptr -}; +const char* esol_names[esolNR + 1] = { "No", "SPC", "TIP4p", nullptr }; -const char *edispc_names[edispcNR+1] = { - "No", "EnerPres", "Ener", "AllEnerPres", "AllEner", nullptr -}; +const char* edispc_names[edispcNR + 1] = { "No", "EnerPres", "Ener", + "AllEnerPres", "AllEner", nullptr }; -const char *ecm_names[ecmNR+1] = { - "Linear", "Angular", "None", "Linear-acceleration-correction", nullptr -}; +const char* ecm_names[ecmNR + 1] = { "Linear", "Angular", "None", "Linear-acceleration-correction", nullptr }; -const char *eann_names[eannNR+1] = { - "No", "Single", "Periodic", nullptr -}; +const char* eann_names[eannNR + 1] = { "No", "Single", "Periodic", nullptr }; -const char *ewt_names[ewtNR+1] = { - "9-3", "10-4", "table", "12-6", nullptr -}; +const char* ewt_names[ewtNR + 1] = { "9-3", "10-4", "table", "12-6", nullptr }; -const char *epull_names[epullNR+1] = { - "umbrella", "constraint", "constant-force", "flat-bottom", "flat-bottom-high", "external-potential", nullptr -}; +const char* epull_names[epullNR + 1] = { "umbrella", "constraint", "constant-force", + "flat-bottom", "flat-bottom-high", "external-potential", + nullptr }; -const char *epullg_names[epullgNR+1] = { - "distance", "direction", "cylinder", "direction-periodic", "direction-relative", "angle", "dihedral", "angle-axis", nullptr -}; +const char* epullg_names[epullgNR + 1] = { "distance", "direction", "cylinder", + "direction-periodic", "direction-relative", "angle", + "dihedral", "angle-axis", nullptr }; -const char *erotg_names[erotgNR+1] = { - "iso", "iso-pf", "pm", "pm-pf", "rm", "rm-pf", "rm2", "rm2-pf", "flex", "flex-t", "flex2", "flex2-t", nullptr -}; +const char* erotg_names[erotgNR + 1] = { "iso", "iso-pf", "pm", "pm-pf", "rm", + "rm-pf", "rm2", "rm2-pf", "flex", "flex-t", + "flex2", "flex2-t", nullptr }; -const char *erotg_fitnames[erotgFitNR+1] = { - "rmsd", "norm", "potential", nullptr -}; +const char* erotg_fitnames[erotgFitNR + 1] = { "rmsd", "norm", "potential", nullptr }; -const char *eSwapTypes_names[eSwapTypesNR+1] = { - "no", "X", "Y", "Z", nullptr -}; +const char* eSwapTypes_names[eSwapTypesNR + 1] = { "no", "X", "Y", "Z", nullptr }; -const char *eSwapFixedGrp_names[eSwapFixedGrpNR+1] = { - "Split0", "Split1", "Solvent", nullptr -}; +const char* eSwapFixedGrp_names[eSwapFixedGrpNR + 1] = { "Split0", "Split1", "Solvent", nullptr }; -const char *eQMmethod_names[eQMmethodNR+1] = { - "AM1", "PM3", "RHF", - "UHF", "DFT", "B3LYP", "MP2", "CASSCF", "B3LYPLAN", - "DIRECT", nullptr -}; +const char* eQMmethod_names[eQMmethodNR + 1] = { "AM1", "PM3", "RHF", "UHF", + "DFT", "B3LYP", "MP2", "CASSCF", + "B3LYPLAN", "DIRECT", nullptr }; -const char *eQMbasis_names[eQMbasisNR+1] = { - "STO3G", "STO-3G", "3-21G", - "3-21G*", "3-21+G*", "6-21G", - "6-31G", "6-31G*", "6-31+G*", - "6-311G", nullptr -}; +const char* eQMbasis_names[eQMbasisNR + 1] = { "STO3G", "STO-3G", "3-21G", "3-21G*", + "3-21+G*", "6-21G", "6-31G", "6-31G*", + "6-31+G*", "6-311G", nullptr }; -const char *eQMMMscheme_names[eQMMMschemeNR+1] = { - "normal", "ONIOM", nullptr -}; +const char* eQMMMscheme_names[eQMMMschemeNR + 1] = { "normal", "ONIOM", nullptr }; -const char *gmx_nblist_geometry_names[GMX_NBLIST_GEOMETRY_NR+1] = { - "Particle-Particle", "Water3-Particle", "Water3-Water3", "Water4-Particle", "Water4-Water4", "CG-CG", nullptr +const char* gmx_nblist_geometry_names[GMX_NBLIST_GEOMETRY_NR + 1] = { + "Particle-Particle", "Water3-Particle", "Water3-Water3", "Water4-Particle", + "Water4-Water4", "CG-CG", nullptr }; -const char *gmx_nblist_interaction_names[GMX_NBLIST_INTERACTION_NR+1] = { - "Standard", "Free_Energy", nullptr -}; +const char* gmx_nblist_interaction_names[GMX_NBLIST_INTERACTION_NR + 1] = { "Standard", + "Free_Energy", nullptr }; -const char *gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR+1] = -{ +const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1] = { "None", "Coulomb", "Reaction-Field", "Cubic-Spline-Table", "Ewald", nullptr }; -const char *gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR+1] = -{ - "None", "Lennard-Jones", "Buckingham", "Cubic-Spline-Table", "LJEwald", nullptr -}; +const char* gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR + 1] = { "None", "Lennard-Jones", + "Buckingham", "Cubic-Spline-Table", + "LJEwald", nullptr }; diff --git a/src/gromacs/mdtypes/md_enums.h b/src/gromacs/mdtypes/md_enums.h index d731900352..307f69e56a 100644 --- a/src/gromacs/mdtypes/md_enums.h +++ b/src/gromacs/mdtypes/md_enums.h @@ -57,33 +57,47 @@ * \param[in] names The array * \return the correct string or "no name defined" */ -const char *enum_name(int index, int max_index, const char *names[]); +const char* enum_name(int index, int max_index, const char* names[]); //! Boolean strings no or yes -extern const char *yesno_names[BOOL_NR+1]; +extern const char* yesno_names[BOOL_NR + 1]; //! \brief The two compartments for CompEL setups. -enum eCompartment { - eCompA, eCompB, eCompNR +enum eCompartment +{ + eCompA, + eCompB, + eCompNR }; /*! \brief The channels that define with their COM the compartment boundaries in CompEL setups. * * In principle one could also use modified setups with more than two channels. */ -enum eChannel { - eChan0, eChan1, eChanNR +enum eChannel +{ + eChan0, + eChan1, + eChanNR }; /*! \brief Temperature coupling type * * yes is an alias for berendsen */ -enum { - etcNO, etcBERENDSEN, etcNOSEHOOVER, etcYES, etcANDERSEN, etcANDERSENMASSIVE, etcVRESCALE, etcNR +enum +{ + etcNO, + etcBERENDSEN, + etcNOSEHOOVER, + etcYES, + etcANDERSEN, + etcANDERSENMASSIVE, + etcVRESCALE, + etcNR }; //! Strings corresponding to temperatyre coupling types -extern const char *etcoupl_names[etcNR+1]; +extern const char* etcoupl_names[etcNR + 1]; //! Macro for selecting t coupling string #define ETCOUPLTYPE(e) enum_name(e, etcNR, etcoupl_names) //! Return whether this is andersen coupling @@ -93,95 +107,166 @@ extern const char *etcoupl_names[etcNR+1]; * * isotropic is an alias for berendsen */ -enum { - epcNO, epcBERENDSEN, epcPARRINELLORAHMAN, epcISOTROPIC, epcMTTK, epcNR +enum +{ + epcNO, + epcBERENDSEN, + epcPARRINELLORAHMAN, + epcISOTROPIC, + epcMTTK, + epcNR }; //! String corresponding to pressure coupling algorithm -extern const char *epcoupl_names[epcNR+1]; +extern const char* epcoupl_names[epcNR + 1]; //! Macro to return the correct pcoupling string #define EPCOUPLTYPE(e) enum_name(e, epcNR, epcoupl_names) //! Flat-bottom posres geometries -enum { - efbposresZERO, efbposresSPHERE, efbposresCYLINDER, efbposresX, efbposresY, efbposresZ, - efbposresCYLINDERX, efbposresCYLINDERY, efbposresCYLINDERZ, efbposresNR +enum +{ + efbposresZERO, + efbposresSPHERE, + efbposresCYLINDER, + efbposresX, + efbposresY, + efbposresZ, + efbposresCYLINDERX, + efbposresCYLINDERY, + efbposresCYLINDERZ, + efbposresNR }; //! Relative coordinate scaling type for position restraints. -enum { - erscNO, erscALL, erscCOM, erscNR +enum +{ + erscNO, + erscALL, + erscCOM, + erscNR }; //! String corresponding to relativ coordinate scaling. -extern const char *erefscaling_names[erscNR+1]; +extern const char* erefscaling_names[erscNR + 1]; //! Macro to select correct coordinate scaling string. #define EREFSCALINGTYPE(e) enum_name(e, erscNR, erefscaling_names) //! Trotter decomposition extended variable parts. -enum { - etrtNONE, etrtNHC, etrtBAROV, etrtBARONHC, etrtNHC2, etrtBAROV2, etrtBARONHC2, - etrtVELOCITY1, etrtVELOCITY2, etrtPOSITION, etrtSKIPALL, etrtNR +enum +{ + etrtNONE, + etrtNHC, + etrtBAROV, + etrtBARONHC, + etrtNHC2, + etrtBAROV2, + etrtBARONHC2, + etrtVELOCITY1, + etrtVELOCITY2, + etrtPOSITION, + etrtSKIPALL, + etrtNR }; //! Sequenced parts of the trotter decomposition. -enum { - ettTSEQ0, ettTSEQ1, ettTSEQ2, ettTSEQ3, ettTSEQ4, ettTSEQMAX +enum +{ + ettTSEQ0, + ettTSEQ1, + ettTSEQ2, + ettTSEQ3, + ettTSEQ4, + ettTSEQMAX }; //! Pressure coupling type -enum { - epctISOTROPIC, epctSEMIISOTROPIC, epctANISOTROPIC, - epctSURFACETENSION, epctNR +enum +{ + epctISOTROPIC, + epctSEMIISOTROPIC, + epctANISOTROPIC, + epctSURFACETENSION, + epctNR }; //! String corresponding to pressure coupling type -extern const char *epcoupltype_names[epctNR+1]; +extern const char* epcoupltype_names[epctNR + 1]; //! Macro to select the right string for pcoupl type #define EPCOUPLTYPETYPE(e) enum_name(e, epctNR, epcoupltype_names) //! \\brief Cutoff scheme -enum { - ecutsVERLET, ecutsGROUP, ecutsNR +enum +{ + ecutsVERLET, + ecutsGROUP, + ecutsNR }; //! String corresponding to cutoff scheme -extern const char *ecutscheme_names[ecutsNR+1]; +extern const char* ecutscheme_names[ecutsNR + 1]; //! Macro to select the right string for cutoff scheme -#define ECUTSCHEME(e) enum_name(e, ecutsNR, ecutscheme_names) +#define ECUTSCHEME(e) enum_name(e, ecutsNR, ecutscheme_names) /*! \brief Coulomb / VdW interaction modifiers. * * grompp replaces eintmodPOTSHIFT_VERLET_UNSUPPORTED by eintmodPOTSHIFT. * Exactcutoff is only used by Reaction-field-zero, and is not user-selectable. */ -enum eintmod { - eintmodPOTSHIFT_VERLET_UNSUPPORTED, eintmodPOTSHIFT, eintmodNONE, eintmodPOTSWITCH, eintmodEXACTCUTOFF, eintmodFORCESWITCH, eintmodNR +enum eintmod +{ + eintmodPOTSHIFT_VERLET_UNSUPPORTED, + eintmodPOTSHIFT, + eintmodNONE, + eintmodPOTSWITCH, + eintmodEXACTCUTOFF, + eintmodFORCESWITCH, + eintmodNR }; //! String corresponding to interaction modifiers -extern const char *eintmod_names[eintmodNR+1]; +extern const char* eintmod_names[eintmodNR + 1]; //! Macro to select the correct string for modifiers #define INTMODIFIER(e) enum_name(e, eintmodNR, eintmod_names) /*! \brief Cut-off treatment for Coulomb */ -enum { - eelCUT, eelRF, eelGRF_NOTUSED, eelPME, eelEWALD, eelP3M_AD, - eelPOISSON, eelSWITCH, eelSHIFT, eelUSER, eelGB_NOTUSED, eelRF_NEC_UNSUPPORTED, eelENCADSHIFT, - eelPMEUSER, eelPMESWITCH, eelPMEUSERSWITCH, eelRF_ZERO, eelNR +enum +{ + eelCUT, + eelRF, + eelGRF_NOTUSED, + eelPME, + eelEWALD, + eelP3M_AD, + eelPOISSON, + eelSWITCH, + eelSHIFT, + eelUSER, + eelGB_NOTUSED, + eelRF_NEC_UNSUPPORTED, + eelENCADSHIFT, + eelPMEUSER, + eelPMESWITCH, + eelPMEUSERSWITCH, + eelRF_ZERO, + eelNR }; //! String corresponding to Coulomb treatment -extern const char *eel_names[eelNR+1]; +extern const char* eel_names[eelNR + 1]; //! Macro for correct string for Coulomb treatment -#define EELTYPE(e) enum_name(e, eelNR, eel_names) +#define EELTYPE(e) enum_name(e, eelNR, eel_names) //! Ewald geometry. -enum { - eewg3D, eewg3DC, eewgNR +enum +{ + eewg3D, + eewg3DC, + eewgNR }; //! String corresponding to Ewald geometry -extern const char *eewg_names[eewgNR+1]; +extern const char* eewg_names[eewgNR + 1]; //! Macro telling us whether we use reaction field -#define EEL_RF(e) ((e) == eelRF || (e) == eelGRF_NOTUSED || (e) == eelRF_NEC_UNSUPPORTED || (e) == eelRF_ZERO ) +#define EEL_RF(e) \ + ((e) == eelRF || (e) == eelGRF_NOTUSED || (e) == eelRF_NEC_UNSUPPORTED || (e) == eelRF_ZERO) //! Macro telling us whether we use PME -#define EEL_PME(e) ((e) == eelPME || (e) == eelPMESWITCH || (e) == eelPMEUSER || (e) == eelPMEUSERSWITCH || (e) == eelP3M_AD) +#define EEL_PME(e) \ + ((e) == eelPME || (e) == eelPMESWITCH || (e) == eelPMEUSER || (e) == eelPMEUSERSWITCH || (e) == eelP3M_AD) //! Macro telling us whether we use PME or full Ewald #define EEL_PME_EWALD(e) (EEL_PME(e) || (e) == eelEWALD) //! Macro telling us whether we use full electrostatics of any sort @@ -190,21 +275,30 @@ extern const char *eewg_names[eewgNR+1]; #define EEL_USER(e) ((e) == eelUSER || (e) == eelPMEUSER || (e) == (eelPMEUSERSWITCH)) //! Van der Waals interaction treatment -enum { - evdwCUT, evdwSWITCH, evdwSHIFT, evdwUSER, evdwENCADSHIFT, - evdwPME, evdwNR +enum +{ + evdwCUT, + evdwSWITCH, + evdwSHIFT, + evdwUSER, + evdwENCADSHIFT, + evdwPME, + evdwNR }; //! String corresponding to Van der Waals treatment -extern const char *evdw_names[evdwNR+1]; +extern const char* evdw_names[evdwNR + 1]; //! Macro for selecting correct string for VdW treatment -#define EVDWTYPE(e) enum_name(e, evdwNR, evdw_names) +#define EVDWTYPE(e) enum_name(e, evdwNR, evdw_names) //! Type of long-range VdW treatment of combination rules -enum { - eljpmeGEOM, eljpmeLB, eljpmeNR +enum +{ + eljpmeGEOM, + eljpmeLB, + eljpmeNR }; //! String for LJPME combination rule treatment -extern const char *eljpme_names[eljpmeNR+1]; +extern const char* eljpme_names[eljpmeNR + 1]; //! Macro for correct LJPME comb rule name #define ELJPMECOMBNAMES(e) enum_name(e, eljpmeNR, eljpme_names) @@ -219,13 +313,27 @@ extern const char *eljpme_names[eljpmeNR+1]; * eiVVAK uses 1/2*(KE(t-dt/2)+KE(t+dt/2)) as the kinetic energy, * and the half step kinetic energy for temperature control */ -enum { - eiMD, eiSteep, eiCG, eiBD, eiSD2_REMOVED, eiNM, eiLBFGS, eiTPI, eiTPIC, eiSD1, eiVV, eiVVAK, eiMimic, eiNR +enum +{ + eiMD, + eiSteep, + eiCG, + eiBD, + eiSD2_REMOVED, + eiNM, + eiLBFGS, + eiTPI, + eiTPIC, + eiSD1, + eiVV, + eiVVAK, + eiMimic, + eiNR }; //! Name of the integrator algorithm -extern const char *ei_names[eiNR+1]; +extern const char* ei_names[eiNR + 1]; //! Macro returning integrator string -#define EI(e) enum_name(e, eiNR, ei_names) +#define EI(e) enum_name(e, eiNR, ei_names) //! Do we use MiMiC QM/MM? #define EI_MIMIC(e) ((e) == eiMimic) //! Do we use velocity Verlet @@ -247,58 +355,81 @@ extern const char *ei_names[eiNR+1]; #define EI_STATE_VELOCITY(e) (EI_MD(e) || EI_SD(e)) //! Constraint algorithm -enum { - econtLINCS, econtSHAKE, econtNR +enum +{ + econtLINCS, + econtSHAKE, + econtNR }; //! String corresponding to constraint algorithm -extern const char *econstr_names[econtNR+1]; +extern const char* econstr_names[econtNR + 1]; //! Macro to select the correct string #define ECONSTRTYPE(e) enum_name(e, econtNR, econstr_names) //! Distance restraint refinement algorithm -enum { - edrNone, edrSimple, edrEnsemble, edrNR +enum +{ + edrNone, + edrSimple, + edrEnsemble, + edrNR }; //! String corresponding to distance restraint algorithm -extern const char *edisre_names[edrNR+1]; +extern const char* edisre_names[edrNR + 1]; //! Macro to select the right disre algorithm string -#define EDISRETYPE(e) enum_name(e, edrNR, edisre_names) +#define EDISRETYPE(e) enum_name(e, edrNR, edisre_names) //! Distance restraints weighting type -enum { - edrwConservative, edrwEqual, edrwNR +enum +{ + edrwConservative, + edrwEqual, + edrwNR }; //! String corresponding to distance restraint weighting -extern const char *edisreweighting_names[edrwNR+1]; +extern const char* edisreweighting_names[edrwNR + 1]; //! Macro corresponding to dr weighting -#define EDISREWEIGHTING(e) enum_name(e, edrwNR, edisreweighting_names) +#define EDISREWEIGHTING(e) enum_name(e, edrwNR, edisreweighting_names) //! Combination rule algorithm. -enum { - eCOMB_NONE, eCOMB_GEOMETRIC, eCOMB_ARITHMETIC, eCOMB_GEOM_SIG_EPS, eCOMB_NR +enum +{ + eCOMB_NONE, + eCOMB_GEOMETRIC, + eCOMB_ARITHMETIC, + eCOMB_GEOM_SIG_EPS, + eCOMB_NR }; //! String for combination rule algorithm -extern const char *ecomb_names[eCOMB_NR+1]; +extern const char* ecomb_names[eCOMB_NR + 1]; //! Macro to select the comb rule string -#define ECOMBNAME(e) enum_name(e, eCOMB_NR, ecomb_names) +#define ECOMBNAME(e) enum_name(e, eCOMB_NR, ecomb_names) //! Van der Waals potential. -enum { - eNBF_NONE, eNBF_LJ, eNBF_BHAM, eNBF_NR +enum +{ + eNBF_NONE, + eNBF_LJ, + eNBF_BHAM, + eNBF_NR }; //! String corresponding to Van der Waals potential -extern const char *enbf_names[eNBF_NR+1]; +extern const char* enbf_names[eNBF_NR + 1]; //! Macro for correct VdW potential string -#define ENBFNAME(e) enum_name(e, eNBF_NR, enbf_names) +#define ENBFNAME(e) enum_name(e, eNBF_NR, enbf_names) //! Simulated tempering methods. -enum { - esimtempGEOMETRIC, esimtempEXPONENTIAL, esimtempLINEAR, esimtempNR +enum +{ + esimtempGEOMETRIC, + esimtempEXPONENTIAL, + esimtempLINEAR, + esimtempNR }; //! String corresponding to simulated tempering -extern const char *esimtemp_names[esimtempNR+1]; +extern const char* esimtemp_names[esimtempNR + 1]; //! Macro for correct tempering string -#define ESIMTEMP(e) enum_name(e, esimtempNR, esimtemp_names) +#define ESIMTEMP(e) enum_name(e, esimtempNR, esimtemp_names) /*! \brief Free energy perturbation type * @@ -309,22 +440,36 @@ extern const char *esimtemp_names[esimtempNR+1]; * throughout the simulation. * efepEXPANDED, then expanded ensemble simulations are occuring. */ -enum { - efepNO, efepYES, efepSTATIC, efepSLOWGROWTH, efepEXPANDED, efepNR +enum +{ + efepNO, + efepYES, + efepSTATIC, + efepSLOWGROWTH, + efepEXPANDED, + efepNR }; //! String corresponding to FEP type. -extern const char *efep_names[efepNR+1]; +extern const char* efep_names[efepNR + 1]; //! Macro corresponding to FEP string. -#define EFEPTYPE(e) enum_name(e, efepNR, efep_names) +#define EFEPTYPE(e) enum_name(e, efepNR, efep_names) //! Free energy pertubation coupling types. -enum { - efptFEP, efptMASS, efptCOUL, efptVDW, efptBONDED, efptRESTRAINT, efptTEMPERATURE, efptNR +enum +{ + efptFEP, + efptMASS, + efptCOUL, + efptVDW, + efptBONDED, + efptRESTRAINT, + efptTEMPERATURE, + efptNR }; //! String for FEP coupling type -extern const char *efpt_names[efptNR+1]; +extern const char* efpt_names[efptNR + 1]; //! Long names for FEP coupling type -extern const char *efpt_singular_names[efptNR+1]; +extern const char* efpt_singular_names[efptNR + 1]; /*! \brief What to print for free energy calculations * @@ -332,11 +477,16 @@ extern const char *efpt_singular_names[efptNR+1]; * YES is an alias to TOTAL, and * will be converted in readir, so we never have to account for it in code. */ -enum { - edHdLPrintEnergyNO, edHdLPrintEnergyTOTAL, edHdLPrintEnergyPOTENTIAL, edHdLPrintEnergyYES, edHdLPrintEnergyNR +enum +{ + edHdLPrintEnergyNO, + edHdLPrintEnergyTOTAL, + edHdLPrintEnergyPOTENTIAL, + edHdLPrintEnergyYES, + edHdLPrintEnergyNR }; //! String corresponding to printing of free energy -extern const char *edHdLPrintEnergy_names[edHdLPrintEnergyNR+1]; +extern const char* edHdLPrintEnergy_names[edHdLPrintEnergyNR + 1]; /*! \brief How the lambda weights are calculated * @@ -348,11 +498,18 @@ extern const char *edHdLPrintEnergy_names[edHdLPrintEnergyNR+1]; * elamstatsWWL - Weighted Wang-Landau (using optimized Gibbs * weighted visitation counts) */ -enum { - elamstatsNO, elamstatsMETROPOLIS, elamstatsBARKER, elamstatsMINVAR, elamstatsWL, elamstatsWWL, elamstatsNR +enum +{ + elamstatsNO, + elamstatsMETROPOLIS, + elamstatsBARKER, + elamstatsMINVAR, + elamstatsWL, + elamstatsWWL, + elamstatsNR }; //! String corresponding to lambda weights -extern const char *elamstats_names[elamstatsNR+1]; +extern const char* elamstats_names[elamstatsNR + 1]; //! Macro telling us whether we use expanded ensemble #define ELAMSTATS_EXPANDED(e) ((e) > elamstatsNO) //! Macro telling us whether we use some kind of Wang-Landau @@ -368,11 +525,17 @@ extern const char *elamstats_names[elamstatsNR+1]; * version of Gibbs (Monte Carlo Strategies in * Scientific computing, Liu, p. 134) */ -enum { - elmcmoveNO, elmcmoveMETROPOLIS, elmcmoveBARKER, elmcmoveGIBBS, elmcmoveMETGIBBS, elmcmoveNR +enum +{ + elmcmoveNO, + elmcmoveMETROPOLIS, + elmcmoveBARKER, + elmcmoveGIBBS, + elmcmoveMETGIBBS, + elmcmoveNR }; //! String corresponding to lambda moves -extern const char *elmcmove_names[elmcmoveNR+1]; +extern const char* elmcmove_names[elmcmoveNR + 1]; /*! \brief How we decide whether weights have reached equilibrium * @@ -386,11 +549,19 @@ extern const char *elmcmove_names[elmcmoveNR+1]; * elmceqRATIO - stop when the ratio of samples (lowest to highest) * is sufficiently large */ -enum { - elmceqNO, elmceqYES, elmceqWLDELTA, elmceqNUMATLAM, elmceqSTEPS, elmceqSAMPLES, elmceqRATIO, elmceqNR +enum +{ + elmceqNO, + elmceqYES, + elmceqWLDELTA, + elmceqNUMATLAM, + elmceqSTEPS, + elmceqSAMPLES, + elmceqRATIO, + elmceqNR }; //! String corresponding to equilibrium algorithm -extern const char *elmceq_names[elmceqNR+1]; +extern const char* elmceq_names[elmceqNR + 1]; /*! \brief separate_dhdl_file selection * @@ -398,10 +569,12 @@ extern const char *elmceq_names[elmceqNR+1]; */ enum { - esepdhdlfileYES, esepdhdlfileNO, esepdhdlfileNR + esepdhdlfileYES, + esepdhdlfileNO, + esepdhdlfileNR }; //! String corresponding to separate DHDL file selection -extern const char *separate_dhdl_file_names[esepdhdlfileNR+1]; +extern const char* separate_dhdl_file_names[esepdhdlfileNR + 1]; //! Monster macro for DHDL file selection #define SEPDHDLFILETYPE(e) enum_name(e, esepdhdlfileNR, separate_dhdl_file_names) @@ -411,10 +584,12 @@ extern const char *separate_dhdl_file_names[esepdhdlfileNR+1]; */ enum { - edhdlderivativesYES, edhdlderivativesNO, edhdlderivativesNR + edhdlderivativesYES, + edhdlderivativesNO, + edhdlderivativesNR }; //! String for DHDL derivatives -extern const char *dhdl_derivatives_names[edhdlderivativesNR+1]; +extern const char* dhdl_derivatives_names[edhdlderivativesNR + 1]; //! YAMM (Yet another monster macro) #define DHDLDERIVATIVESTYPE(e) enum_name(e, edhdlderivativesNR, dhdl_derivatives_names) @@ -422,148 +597,228 @@ extern const char *dhdl_derivatives_names[edhdlderivativesNR+1]; * * Distinguishes classical water types with 3 or 4 particles */ -enum { - esolNO, esolSPC, esolTIP4P, esolNR +enum +{ + esolNO, + esolSPC, + esolTIP4P, + esolNR }; //! String corresponding to solvent type -extern const char *esol_names[esolNR+1]; +extern const char* esol_names[esolNR + 1]; //! Macro lest we print the wrong solvent model string -#define ESOLTYPE(e) enum_name(e, esolNR, esol_names) +#define ESOLTYPE(e) enum_name(e, esolNR, esol_names) //! Dispersion correction. -enum { - edispcNO, edispcEnerPres, edispcEner, edispcAllEnerPres, edispcAllEner, edispcNR +enum +{ + edispcNO, + edispcEnerPres, + edispcEner, + edispcAllEnerPres, + edispcAllEner, + edispcNR }; //! String corresponding to dispersion corrections -extern const char *edispc_names[edispcNR+1]; +extern const char* edispc_names[edispcNR + 1]; //! Macro for dispcorr string -#define EDISPCORR(e) enum_name(e, edispcNR, edispc_names) +#define EDISPCORR(e) enum_name(e, edispcNR, edispc_names) //! Center of mass motion removal algorithm. -enum { - ecmLINEAR, ecmANGULAR, ecmNO, ecmLINEAR_ACCELERATION_CORRECTION, ecmNR +enum +{ + ecmLINEAR, + ecmANGULAR, + ecmNO, + ecmLINEAR_ACCELERATION_CORRECTION, + ecmNR }; //! String corresponding to COM removal -extern const char *ecm_names[ecmNR+1]; +extern const char* ecm_names[ecmNR + 1]; //! Macro for COM removal string -#define ECOM(e) enum_name(e, ecmNR, ecm_names) +#define ECOM(e) enum_name(e, ecmNR, ecm_names) //! Algorithm for simulated annealing. -enum { - eannNO, eannSINGLE, eannPERIODIC, eannNR +enum +{ + eannNO, + eannSINGLE, + eannPERIODIC, + eannNR }; //! String for simulated annealing -extern const char *eann_names[eannNR+1]; +extern const char* eann_names[eannNR + 1]; //! And macro for simulated annealing string -#define EANNEAL(e) enum_name(e, eannNR, eann_names) +#define EANNEAL(e) enum_name(e, eannNR, eann_names) //! Wall types. -enum { - ewt93, ewt104, ewtTABLE, ewt126, ewtNR +enum +{ + ewt93, + ewt104, + ewtTABLE, + ewt126, + ewtNR }; //! String corresponding to wall type -extern const char *ewt_names[ewtNR+1]; +extern const char* ewt_names[ewtNR + 1]; //! Macro for wall type string -#define EWALLTYPE(e) enum_name(e, ewtNR, ewt_names) +#define EWALLTYPE(e) enum_name(e, ewtNR, ewt_names) //! Pulling algorithm. -enum { - epullUMBRELLA, epullCONSTRAINT, epullCONST_F, epullFLATBOTTOM, epullFLATBOTTOMHIGH, epullEXTERNAL, epullNR +enum +{ + epullUMBRELLA, + epullCONSTRAINT, + epullCONST_F, + epullFLATBOTTOM, + epullFLATBOTTOMHIGH, + epullEXTERNAL, + epullNR }; //! String for pulling algorithm -extern const char *epull_names[epullNR+1]; +extern const char* epull_names[epullNR + 1]; //! Macro for pulling string -#define EPULLTYPE(e) enum_name(e, epullNR, epull_names) +#define EPULLTYPE(e) enum_name(e, epullNR, epull_names) //! Control of pull groups -enum { - epullgDIST, epullgDIR, epullgCYL, epullgDIRPBC, epullgDIRRELATIVE, epullgANGLE, epullgDIHEDRAL, epullgANGLEAXIS, epullgNR +enum +{ + epullgDIST, + epullgDIR, + epullgCYL, + epullgDIRPBC, + epullgDIRRELATIVE, + epullgANGLE, + epullgDIHEDRAL, + epullgANGLEAXIS, + epullgNR }; //! String for pull groups -extern const char *epullg_names[epullgNR+1]; +extern const char* epullg_names[epullgNR + 1]; //! Macro for pull group string -#define EPULLGEOM(e) enum_name(e, epullgNR, epullg_names) +#define EPULLGEOM(e) enum_name(e, epullgNR, epullg_names) //! Enforced rotation groups. -enum { - erotgISO, erotgISOPF, - erotgPM, erotgPMPF, - erotgRM, erotgRMPF, - erotgRM2, erotgRM2PF, - erotgFLEX, erotgFLEXT, - erotgFLEX2, erotgFLEX2T, +enum +{ + erotgISO, + erotgISOPF, + erotgPM, + erotgPMPF, + erotgRM, + erotgRMPF, + erotgRM2, + erotgRM2PF, + erotgFLEX, + erotgFLEXT, + erotgFLEX2, + erotgFLEX2T, erotgNR }; //! Rotation group names -extern const char *erotg_names[erotgNR+1]; +extern const char* erotg_names[erotgNR + 1]; //! Macro for rot group names -#define EROTGEOM(e) enum_name(e, erotgNR, erotg_names) +#define EROTGEOM(e) enum_name(e, erotgNR, erotg_names) //! String for rotation group origin names -extern const char *erotg_originnames[erotgNR+1]; +extern const char* erotg_originnames[erotgNR + 1]; //! Macro for rot group origin names -#define EROTORIGIN(e) enum_name(e, erotgOriginNR, erotg_originnames) +#define EROTORIGIN(e) enum_name(e, erotgOriginNR, erotg_originnames) //! Rotation group fitting type -enum { - erotgFitRMSD, erotgFitNORM, erotgFitPOT, erotgFitNR +enum +{ + erotgFitRMSD, + erotgFitNORM, + erotgFitPOT, + erotgFitNR }; //! String corresponding to rotation group fitting -extern const char *erotg_fitnames[erotgFitNR+1]; +extern const char* erotg_fitnames[erotgFitNR + 1]; //! Macro for rot group fit names -#define EROTFIT(e) enum_name(e, erotgFitNR, erotg_fitnames) +#define EROTFIT(e) enum_name(e, erotgFitNR, erotg_fitnames) /*! \brief Direction along which ion/water swaps happen * * Part of "Computational Electrophysiology" (CompEL) setups */ -enum eSwaptype { - eswapNO, eswapX, eswapY, eswapZ, eSwapTypesNR +enum eSwaptype +{ + eswapNO, + eswapX, + eswapY, + eswapZ, + eSwapTypesNR }; //! Names for swapping -extern const char *eSwapTypes_names[eSwapTypesNR+1]; +extern const char* eSwapTypes_names[eSwapTypesNR + 1]; //! Macro for swapping string -#define ESWAPTYPE(e) enum_name(e, eSwapTypesNR, eSwapTypes_names) +#define ESWAPTYPE(e) enum_name(e, eSwapTypesNR, eSwapTypes_names) /*! \brief Swap group splitting type * * These are just the fixed groups we need for any setup. In t_swap's grp * entry after that follows the variable number of swap groups. */ -enum { - eGrpSplit0, eGrpSplit1, eGrpSolvent, eSwapFixedGrpNR +enum +{ + eGrpSplit0, + eGrpSplit1, + eGrpSolvent, + eSwapFixedGrpNR }; //! String for swap group splitting -extern const char *eSwapFixedGrp_names[eSwapFixedGrpNR+1]; +extern const char* eSwapFixedGrp_names[eSwapFixedGrpNR + 1]; //! QMMM methods. -enum { - eQMmethodAM1, eQMmethodPM3, eQMmethodRHF, - eQMmethodUHF, eQMmethodDFT, eQMmethodB3LYP, eQMmethodMP2, eQMmethodCASSCF, eQMmethodB3LYPLAN, - eQMmethodDIRECT, eQMmethodNR +enum +{ + eQMmethodAM1, + eQMmethodPM3, + eQMmethodRHF, + eQMmethodUHF, + eQMmethodDFT, + eQMmethodB3LYP, + eQMmethodMP2, + eQMmethodCASSCF, + eQMmethodB3LYPLAN, + eQMmethodDIRECT, + eQMmethodNR }; //! String corresponding to QMMM methods -extern const char *eQMmethod_names[eQMmethodNR+1]; +extern const char* eQMmethod_names[eQMmethodNR + 1]; //! Macro to pick QMMM method name -#define EQMMETHOD(e) enum_name(e, eQMmethodNR, eQMmethod_names) +#define EQMMETHOD(e) enum_name(e, eQMmethodNR, eQMmethod_names) //! QMMM basis function for QM part -enum { - eQMbasisSTO3G, eQMbasisSTO3G2, eQMbasis321G, - eQMbasis321Gp, eQMbasis321dGp, eQMbasis621G, - eQMbasis631G, eQMbasis631Gp, eQMbasis631dGp, - eQMbasis6311G, eQMbasisNR +enum +{ + eQMbasisSTO3G, + eQMbasisSTO3G2, + eQMbasis321G, + eQMbasis321Gp, + eQMbasis321dGp, + eQMbasis621G, + eQMbasis631G, + eQMbasis631Gp, + eQMbasis631dGp, + eQMbasis6311G, + eQMbasisNR }; //! Name for QMMM basis function -extern const char *eQMbasis_names[eQMbasisNR+1]; +extern const char* eQMbasis_names[eQMbasisNR + 1]; //! Macro to pick right basis function string -#define EQMBASIS(e) enum_name(e, eQMbasisNR, eQMbasis_names) +#define EQMBASIS(e) enum_name(e, eQMbasisNR, eQMbasis_names) //! QMMM scheme -enum { - eQMMMschemenormal, eQMMMschemeoniom, eQMMMschemeNR +enum +{ + eQMMMschemenormal, + eQMMMschemeoniom, + eQMMMschemeNR }; //! QMMMM scheme names -extern const char *eQMMMscheme_names[eQMMMschemeNR+1]; +extern const char* eQMMMscheme_names[eQMMMschemeNR + 1]; //! Macro to pick QMMMM scheme name #define EQMMMSCHEME(e) enum_name(e, eQMMMschemeNR, eQMMMscheme_names) @@ -583,7 +838,7 @@ enum gmx_nblist_kernel_geometry GMX_NBLIST_GEOMETRY_NR }; //! String corresponding to nblist geometry names -extern const char *gmx_nblist_geometry_names[GMX_NBLIST_GEOMETRY_NR+1]; +extern const char* gmx_nblist_geometry_names[GMX_NBLIST_GEOMETRY_NR + 1]; /*! \brief Types of electrostatics calculations * @@ -601,7 +856,7 @@ enum gmx_nbkernel_elec GMX_NBKERNEL_ELEC_NR }; //! String corresponding to electrostatics kernels -extern const char *gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR+1]; +extern const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1]; /*! \brief Types of vdw calculations available * @@ -619,7 +874,7 @@ enum gmx_nbkernel_vdw GMX_NBKERNEL_VDW_NR }; //! String corresponding to VdW kernels -extern const char *gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR+1]; +extern const char* gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR + 1]; //! \brief Types of interactions inside the neighborlist enum gmx_nblist_interaction_type @@ -629,11 +884,12 @@ enum gmx_nblist_interaction_type GMX_NBLIST_INTERACTION_NR }; //! String corresponding to interactions in neighborlist code -extern const char *gmx_nblist_interaction_names[GMX_NBLIST_INTERACTION_NR+1]; +extern const char* gmx_nblist_interaction_names[GMX_NBLIST_INTERACTION_NR + 1]; //! \brief QM/MM mode -enum struct GmxQmmmMode { +enum struct GmxQmmmMode +{ GMX_QMMM_ORIGINAL, GMX_QMMM_MIMIC }; diff --git a/src/gromacs/mdtypes/mdatom.h b/src/gromacs/mdtypes/mdatom.h index 41fbe70e4b..56b3231063 100644 --- a/src/gromacs/mdtypes/mdatom.h +++ b/src/gromacs/mdtypes/mdatom.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,91 +47,92 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -typedef struct t_mdatoms { +typedef struct t_mdatoms +{ //! Total mass in state A - real tmassA; + real tmassA; //! Total mass in state B - real tmassB; + real tmassB; //! Total mass - real tmass; + real tmass; //! Number of atoms in arrays - int nr; + int nr; //! Number of elements in arrays - int nalloc; + int nalloc; //! Number of energy groups - int nenergrp; + int nenergrp; //! Do we have multiple center of mass motion removal groups - gmx_bool bVCMgrps; + gmx_bool bVCMgrps; //! Do we have any virtual sites? - gmx_bool haveVsites; + gmx_bool haveVsites; //! Do we have atoms that are frozen along 1 or 2 (not 3) dimensions? - gmx_bool havePartiallyFrozenAtoms; + gmx_bool havePartiallyFrozenAtoms; //! Number of perturbed atoms - int nPerturbed; + int nPerturbed; //! Number of atoms for which the mass is perturbed - int nMassPerturbed; + int nMassPerturbed; //! Number of atoms for which the charge is perturbed - int nChargePerturbed; + int nChargePerturbed; //! Number of atoms for which the type is perturbed - int nTypePerturbed; + int nTypePerturbed; //! Do we have orientation restraints - gmx_bool bOrires; + gmx_bool bOrires; //! Atomic mass in A state - real *massA; + real* massA; //! Atomic mass in B state - real *massB; + real* massB; //! Atomic mass in present state - real *massT; + real* massT; //! Inverse atomic mass per atom, 0 for vsites and shells - real *invmass; + real* invmass; //! Inverse atomic mass per atom and dimension, 0 for vsites, shells and frozen dimensions - rvec *invMassPerDim; + rvec* invMassPerDim; //! Atomic charge in A state - real *chargeA; + real* chargeA; //! Atomic charge in B state - real *chargeB; + real* chargeB; //! Dispersion constant C6 in A state - real *sqrt_c6A; + real* sqrt_c6A; //! Dispersion constant C6 in A state - real *sqrt_c6B; + real* sqrt_c6B; //! Van der Waals radius sigma in the A state - real *sigmaA; + real* sigmaA; //! Van der Waals radius sigma in the B state - real *sigmaB; + real* sigmaB; //! Van der Waals radius sigma^3 in the A state - real *sigma3A; + real* sigma3A; //! Van der Waals radius sigma^3 in the B state - real *sigma3B; + real* sigma3B; //! Is this atom perturbed - gmx_bool *bPerturbed; + gmx_bool* bPerturbed; //! Type of atom in the A state - int *typeA; + int* typeA; //! Type of atom in the B state - int *typeB; + int* typeB; //! Particle type - unsigned short *ptype; + unsigned short* ptype; //! Group index for temperature coupling - unsigned short *cTC; + unsigned short* cTC; //! Group index for energy matrix - unsigned short *cENER; + unsigned short* cENER; //! Group index for acceleration - unsigned short *cACC; + unsigned short* cACC; //! Group index for freezing - unsigned short *cFREEZE; + unsigned short* cFREEZE; //! Group index for center of mass motion removal - unsigned short *cVCM; + unsigned short* cVCM; //! Group index for user 1 - unsigned short *cU1; + unsigned short* cU1; //! Group index for user 2 - unsigned short *cU2; + unsigned short* cU2; //! Group index for orientation restraints - unsigned short *cORF; + unsigned short* cORF; //! QMMM atoms - gmx_bool *bQM; + gmx_bool* bQM; //! Number of atoms on this processor. TODO is this still used? - int homenr; + int homenr; //! The lambda value used to create the contents of the struct - real lambda; + real lambda; } t_mdatoms; #endif diff --git a/src/gromacs/mdtypes/mdrunoptions.h b/src/gromacs/mdtypes/mdrunoptions.h index 135e79b4c9..a36c9f41e4 100644 --- a/src/gromacs/mdtypes/mdrunoptions.h +++ b/src/gromacs/mdtypes/mdrunoptions.h @@ -72,14 +72,14 @@ struct CheckpointOptions //! True means keep all checkpoint file and add the step number to the name gmx_bool keepAndNumberCheckpointFiles = FALSE; //! The period in minutes for writing checkpoint files - real period = 15; + real period = 15; }; //! \internal \brief Options for timing (parts of) mdrun struct TimingOptions { //! Reset timers at the start of this MD step, -1 means do not reset - int resetStep = -1; + int resetStep = -1; //! If true, reset timers half-way the run gmx_bool resetHalfway = FALSE; }; @@ -88,7 +88,7 @@ struct TimingOptions struct ImdOptions { //! IMD listening port - int port = 8888; + int port = 8888; //! If true, pause the simulation while no IMD client is connected gmx_bool wait = FALSE; //! If true, allow termination of the simulation from IMD client @@ -101,33 +101,33 @@ struct ImdOptions struct MdrunOptions { //! Re-compute energies, and possibly forces, for frames from an input tracjectory - gmx_bool rerun = FALSE; + gmx_bool rerun = FALSE; //! Re-construct virual sites durin a rerun simulation - gmx_bool rerunConstructVsites = FALSE; + gmx_bool rerunConstructVsites = FALSE; //! Try to make the simulation binary reproducible - gmx_bool reproducible = FALSE; + gmx_bool reproducible = FALSE; //! Write confout.gro at the end of the run - gmx_bool writeConfout = TRUE; + gmx_bool writeConfout = TRUE; //! User option for appending. - AppendingBehavior appendingBehavior = AppendingBehavior::Auto; + AppendingBehavior appendingBehavior = AppendingBehavior::Auto; //! Options for checkpointing th simulation - CheckpointOptions checkpointOptions; + CheckpointOptions checkpointOptions; //! Number of steps to run, -2 is use inputrec, -1 is infinite - int64_t numStepsCommandline = -2; + int64_t numStepsCommandline = -2; //! Maximum duration of this simulation in wall-clock hours, -1 is no limit - real maximumHoursToRun = -1; + real maximumHoursToRun = -1; //! Options for timing the run - TimingOptions timingOptions; + TimingOptions timingOptions; //! If true and supported, will tune the PP-PME load balance - gmx_bool tunePme = TRUE; + gmx_bool tunePme = TRUE; //! True if the user explicitly set the -ntomp command line option - gmx_bool ntompOptionIsSet = FALSE; + gmx_bool ntompOptionIsSet = FALSE; //! Options for IMD - ImdOptions imdOptions; + ImdOptions imdOptions; //! Increase the verbosity level in the logging and/or stdout/stderr - gmx_bool verbose = FALSE; + gmx_bool verbose = FALSE; //! If verbose=true, print remaining runtime at this step interval - int verboseStepPrintInterval = 100; + int verboseStepPrintInterval = 100; }; } // end namespace gmx diff --git a/src/gromacs/mdtypes/nblist.h b/src/gromacs/mdtypes/nblist.h index 2e9a7c7073..1f542d7974 100644 --- a/src/gromacs/mdtypes/nblist.h +++ b/src/gromacs/mdtypes/nblist.h @@ -76,20 +76,28 @@ enum gmx_table_format GMX_TABLE_FORMAT_NR }; -enum { - eNL_VDWQQ, eNL_VDW, eNL_QQ, - eNL_VDWQQ_FREE, eNL_VDW_FREE, eNL_QQ_FREE, - eNL_VDWQQ_WATER, eNL_QQ_WATER, - eNL_VDWQQ_WATERWATER, eNL_QQ_WATERWATER, +enum +{ + eNL_VDWQQ, + eNL_VDW, + eNL_QQ, + eNL_VDWQQ_FREE, + eNL_VDW_FREE, + eNL_QQ_FREE, + eNL_VDWQQ_WATER, + eNL_QQ_WATER, + eNL_VDWQQ_WATERWATER, + eNL_QQ_WATERWATER, eNL_NR }; #define MAX_CG 1024 -typedef struct { - int ncg; - int nj; - int jcg[MAX_CG]; +typedef struct +{ + int ncg; + int nj; + int jcg[MAX_CG]; } t_ns_buf; @@ -105,39 +113,39 @@ typedef struct { typedef struct t_nblist { - int igeometry; /* The type of list (atom, water, etc.) */ - int ielec; /* Coulomb loop type index for kernels */ - int ielecmod; /* Coulomb modifier (e.g. switch/shift) */ - int ivdw; /* VdW loop type index for kernels */ - int ivdwmod; /* VdW modifier (e.g. switch/shift) */ - int type; /* Type of interaction, listed in - gmx_nblist_interaction_type */ - - int nri, maxnri; /* Current/max number of i particles */ - int nrj, maxnrj; /* Current/max number of j particles */ - int * iinr; /* The i-elements */ - int * iinr_end; /* The end atom, only with enlistCG */ - int * gid; /* Index in energy arrays */ - int * shift; /* Shift vector index */ - int * jindex; /* Index in jjnr */ - int * jjnr; /* The j-atom list */ - int * jjnr_end; /* The end atom, only with enltypeCG */ - char * excl_fep; /* Exclusions for FEP with Verlet scheme */ - t_excl * excl; /* Exclusions, only with enltypeCG */ + int igeometry; /* The type of list (atom, water, etc.) */ + int ielec; /* Coulomb loop type index for kernels */ + int ielecmod; /* Coulomb modifier (e.g. switch/shift) */ + int ivdw; /* VdW loop type index for kernels */ + int ivdwmod; /* VdW modifier (e.g. switch/shift) */ + int type; /* Type of interaction, listed in + gmx_nblist_interaction_type */ + + int nri, maxnri; /* Current/max number of i particles */ + int nrj, maxnrj; /* Current/max number of j particles */ + int* iinr; /* The i-elements */ + int* iinr_end; /* The end atom, only with enlistCG */ + int* gid; /* Index in energy arrays */ + int* shift; /* Shift vector index */ + int* jindex; /* Index in jjnr */ + int* jjnr; /* The j-atom list */ + int* jjnr_end; /* The end atom, only with enltypeCG */ + char* excl_fep; /* Exclusions for FEP with Verlet scheme */ + t_excl* excl; /* Exclusions, only with enltypeCG */ /* We use separate pointers for kernels that compute both potential * and force (vf suffix), only potential (v) or only force (f) */ - void * kernelptr_vf; - void * kernelptr_v; - void * kernelptr_f; + void* kernelptr_vf; + void* kernelptr_v; + void* kernelptr_f; /* Pad the list of neighbors for each i atom with "-1" entries up to the * simd_padding_width, if it is larger than 0. This is necessary for many * accelerated kernels using single-instruction multiple-data operations * internally. */ - int simd_padding_width; + int simd_padding_width; } t_nblist; @@ -160,34 +168,33 @@ typedef struct t_nblist /* Structure describing the data in a single table */ struct t_forcetable { - t_forcetable(enum gmx_table_interaction interaction, - enum gmx_table_format format); + t_forcetable(enum gmx_table_interaction interaction, enum gmx_table_format format); ~t_forcetable(); - enum gmx_table_interaction interaction; /* Types of interactions stored in this table */ - enum gmx_table_format format; /* Interpolation type and data format */ + enum gmx_table_interaction interaction; /* Types of interactions stored in this table */ + enum gmx_table_format format; /* Interpolation type and data format */ - real r; /* range of the table */ - int n; /* n+1 is the number of table points */ - real scale; /* distance (nm) between two table points */ - real * data; /* the actual table data */ + real r; /* range of the table */ + int n; /* n+1 is the number of table points */ + real scale; /* distance (nm) between two table points */ + real* data; /* the actual table data */ /* Some information about the table layout. This can also be derived from the interpolation - * type and the table interactions, but it is convenient to have here for sanity checks, and it makes it - * much easier to access the tables in the nonbonded kernels when we can set the data from variables. - * It is always true that stride = formatsize*ninteractions + * type and the table interactions, but it is convenient to have here for sanity checks, and it + * makes it much easier to access the tables in the nonbonded kernels when we can set the data + * from variables. It is always true that stride = formatsize*ninteractions */ - int formatsize; /* Number of fp variables for each table point (1 for F, 2 for VF, 4 for YFGH, etc.) */ - int ninteractions; /* Number of interactions in table, 1 for coul-only, 3 for coul+rep+disp. */ - int stride; /* Distance to next table point (number of fp variables per table point in total) */ + int formatsize; /* Number of fp variables for each table point (1 for F, 2 for VF, 4 for YFGH, etc.) */ + int ninteractions; /* Number of interactions in table, 1 for coul-only, 3 for coul+rep+disp. */ + int stride; /* Distance to next table point (number of fp variables per table point in total) */ }; struct t_nblists { - struct t_forcetable *table_elec; - struct t_forcetable *table_vdw; - struct t_forcetable *table_elec_vdw; + struct t_forcetable* table_elec; + struct t_forcetable* table_vdw; + struct t_forcetable* table_elec_vdw; /* The actual neighbor lists, short and long range, see enum above * for definition of neighborlist indices. @@ -196,25 +203,26 @@ struct t_nblists struct t_nblist nlist_lr[eNL_NR]; }; -struct gmx_ns_t { - gmx_bool bCGlist; - int *simple_aaj; - struct t_grid*grid; - t_excl *bexcl; - gmx_bool *bHaveVdW; - t_ns_buf **ns_buf; - gmx_bool *bExcludeAlleg; - int nra_alloc; - int cg_alloc; - int **nl_sr; - int *nsr; - int **nl_lr_ljc; - int **nl_lr_one; - int *nlr_ljc; - int *nlr_one; +struct gmx_ns_t +{ + gmx_bool bCGlist; + int* simple_aaj; + struct t_grid* grid; + t_excl* bexcl; + gmx_bool* bHaveVdW; + t_ns_buf** ns_buf; + gmx_bool* bExcludeAlleg; + int nra_alloc; + int cg_alloc; + int** nl_sr; + int* nsr; + int** nl_lr_ljc; + int** nl_lr_one; + int* nlr_ljc; + int* nlr_one; /* the nblists should probably go in here */ - gmx_bool nblist_initialized; /* has the nblist been initialized? */ - int dump_nl; /* neighbour list dump level (from env. var. GMX_DUMP_NL)*/ + gmx_bool nblist_initialized; /* has the nblist been initialized? */ + int dump_nl; /* neighbour list dump level (from env. var. GMX_DUMP_NL)*/ }; #endif /* GMX_MDTYPES_NBLIST_H */ diff --git a/src/gromacs/mdtypes/pull_params.h b/src/gromacs/mdtypes/pull_params.h index 3ec189d076..eae0243089 100644 --- a/src/gromacs/mdtypes/pull_params.h +++ b/src/gromacs/mdtypes/pull_params.h @@ -56,52 +56,55 @@ /*! \cond INTERNAL */ /*! \brief Struct that defines a pull group */ -typedef struct { - int nat; /**< Number of atoms in the pull group */ - int *ind; /**< The global atoms numbers */ - int nweight; /**< The number of weights (0 or nat) */ - real *weight; /**< Weights (use all 1 when weight==NULL) */ - int pbcatom; /**< The reference atom for pbc (global number) */ - int pbcatom_input; /**< The reference atom for pbc (global number) as specified in the input parameters */ +typedef struct +{ + int nat; /**< Number of atoms in the pull group */ + int* ind; /**< The global atoms numbers */ + int nweight; /**< The number of weights (0 or nat) */ + real* weight; /**< Weights (use all 1 when weight==NULL) */ + int pbcatom; /**< The reference atom for pbc (global number) */ + int pbcatom_input; /**< The reference atom for pbc (global number) as specified in the input parameters */ } t_pull_group; /*! Maximum number of pull groups that can be used in a pull coordinate */ static const int c_pullCoordNgroupMax = 6; /*! \brief Struct that defines a pull coordinate */ -typedef struct { - int eType; /**< The pull type: umbrella, constraint, ... */ - char *externalPotentialProvider; /**< Name of the module providing the external potential, only used with eType==epullEXTERNAL */ - int eGeom; /**< The pull geometry */ - int ngroup; /**< The number of groups, depends on eGeom */ - int group[c_pullCoordNgroupMax]; /**< The pull groups: indices into the group arrays in pull_t and pull_params_t, ngroup indices are used */ - ivec dim; /**< Used to select components for constraint */ - rvec origin; /**< The origin for the absolute reference */ - rvec vec; /**< The pull vector, direction or position */ - gmx_bool bStart; /**< Set init based on the initial structure */ - real init; /**< Initial reference displacement (nm) or (deg) */ - real rate; /**< Rate of motion (nm/ps) or (deg/ps) */ - real k; /**< Force constant (kJ/(mol nm^2) or kJ/(mol rad^2) for umbrella pull type, or kJ/(mol nm) or kJ/(mol rad) for constant force pull type */ - real kB; /**< Force constant for state B */ +typedef struct +{ + int eType; /**< The pull type: umbrella, constraint, ... */ + char* externalPotentialProvider; /**< Name of the module providing the external potential, only used with eType==epullEXTERNAL */ + int eGeom; /**< The pull geometry */ + int ngroup; /**< The number of groups, depends on eGeom */ + int group[c_pullCoordNgroupMax]; /**< The pull groups: indices into the group arrays in pull_t and pull_params_t, ngroup indices are used */ + ivec dim; /**< Used to select components for constraint */ + rvec origin; /**< The origin for the absolute reference */ + rvec vec; /**< The pull vector, direction or position */ + gmx_bool bStart; /**< Set init based on the initial structure */ + real init; /**< Initial reference displacement (nm) or (deg) */ + real rate; /**< Rate of motion (nm/ps) or (deg/ps) */ + real k; /**< Force constant (kJ/(mol nm^2) or kJ/(mol rad^2) for umbrella pull type, or kJ/(mol nm) or kJ/(mol rad) for constant force pull type */ + real kB; /**< Force constant for state B */ } t_pull_coord; /*! \brief Struct containing all pull parameters */ -typedef struct pull_params_t { - int ngroup; /**< Number of pull groups */ - int ncoord; /**< Number of pull coordinates */ - real cylinder_r; /**< Radius of cylinder for dynamic COM (nm) */ - real constr_tol; /**< Absolute tolerance for constraints in (nm) */ - gmx_bool bPrintCOM; /**< Print coordinates of COM for each coord */ - gmx_bool bPrintRefValue; /**< Print the reference value for each coord */ - gmx_bool bPrintComp; /**< Print cartesian components for each coord with geometry=distance */ - gmx_bool bSetPbcRefToPrevStepCOM; /**< Use the COM of each group from the previous step as reference */ - int nstxout; /**< Output interval for pull x */ - int nstfout; /**< Output interval for pull f */ - bool bXOutAverage; /**< Write the average coordinate during the output interval */ - bool bFOutAverage; /**< Write the average force during the output interval */ +typedef struct pull_params_t +{ + int ngroup; /**< Number of pull groups */ + int ncoord; /**< Number of pull coordinates */ + real cylinder_r; /**< Radius of cylinder for dynamic COM (nm) */ + real constr_tol; /**< Absolute tolerance for constraints in (nm) */ + gmx_bool bPrintCOM; /**< Print coordinates of COM for each coord */ + gmx_bool bPrintRefValue; /**< Print the reference value for each coord */ + gmx_bool bPrintComp; /**< Print cartesian components for each coord with geometry=distance */ + gmx_bool bSetPbcRefToPrevStepCOM; /**< Use the COM of each group from the previous step as reference */ + int nstxout; /**< Output interval for pull x */ + int nstfout; /**< Output interval for pull f */ + bool bXOutAverage; /**< Write the average coordinate during the output interval */ + bool bFOutAverage; /**< Write the average force during the output interval */ - t_pull_group *group; /**< groups to pull/restrain/etc/ */ - t_pull_coord *coord; /**< the pull coordinates */ + t_pull_group* group; /**< groups to pull/restrain/etc/ */ + t_pull_coord* coord; /**< the pull coordinates */ } pull_params_t; /*! \endcond */ diff --git a/src/gromacs/mdtypes/pullhistory.h b/src/gromacs/mdtypes/pullhistory.h index 624bad6233..7be3cb5080 100644 --- a/src/gromacs/mdtypes/pullhistory.h +++ b/src/gromacs/mdtypes/pullhistory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,54 +55,43 @@ //! \brief Contains the sum of coordinate observables to enable calculation of the average of pull data. class PullCoordinateHistory { - public: - double value; //!< The sum of the current value of the coordinate, units of nm or rad. - double valueRef; //!< The sum of the reference value of the coordinate, units of nm or rad. - double scalarForce; //!< The sum of the scalar force of the coordinate. - dvec dr01; //!< The sum of the direction vector of group 1 relative to group 0. - dvec dr23; //!< The sum of the direction vector of group 3 relative to group 2. - dvec dr45; //!< The sum of the direction vector of group 5 relative to group 4. - dvec dynaX; //!< The sum of the coordinate of the dynamic groups for geom=cylinder. +public: + double value; //!< The sum of the current value of the coordinate, units of nm or rad. + double valueRef; //!< The sum of the reference value of the coordinate, units of nm or rad. + double scalarForce; //!< The sum of the scalar force of the coordinate. + dvec dr01; //!< The sum of the direction vector of group 1 relative to group 0. + dvec dr23; //!< The sum of the direction vector of group 3 relative to group 2. + dvec dr45; //!< The sum of the direction vector of group 5 relative to group 4. + dvec dynaX; //!< The sum of the coordinate of the dynamic groups for geom=cylinder. - //! Constructor - PullCoordinateHistory() : value (0), - valueRef (0), - scalarForce(0), - dr01 (), - dr23 (), - dr45 (), - dynaX () - { - } + //! Constructor + PullCoordinateHistory() : value(0), valueRef(0), scalarForce(0), dr01(), dr23(), dr45(), dynaX() + { + } }; //! \brief Contains the sum of group observables to enable calculation of the average of pull data. class PullGroupHistory { - public: - dvec x; //!< The sum of the coordinates of the group. +public: + dvec x; //!< The sum of the coordinates of the group. - //! Constructor - PullGroupHistory() : x () - { - } + //! Constructor + PullGroupHistory() : x() {} }; //! \brief Pull statistics history, to allow output of average pull data. class PullHistory { - public: - int numValuesInXSum; //!< Number of values of the coordinate values in the pull sums. - int numValuesInFSum; //!< Number of values in the pull force sums. - std::vector pullCoordinateSums; //!< The container of the sums of the values of the pull coordinate, also contains the scalar force. - std::vector pullGroupSums; //!< The container of the sums of the values of the pull group. +public: + int numValuesInXSum; //!< Number of values of the coordinate values in the pull sums. + int numValuesInFSum; //!< Number of values in the pull force sums. + std::vector pullCoordinateSums; //!< The container of the sums of the values of the pull coordinate, also contains the scalar force. + std::vector pullGroupSums; //!< The container of the sums of the values of the pull group. - //! Constructor - PullHistory() : numValuesInXSum(0), - numValuesInFSum(0) - { - } + //! Constructor + PullHistory() : numValuesInXSum(0), numValuesInFSum(0) {} }; //! \endcond diff --git a/src/gromacs/mdtypes/simulation_workload.h b/src/gromacs/mdtypes/simulation_workload.h index 1c4d46c7e1..9bf230a593 100644 --- a/src/gromacs/mdtypes/simulation_workload.h +++ b/src/gromacs/mdtypes/simulation_workload.h @@ -62,35 +62,35 @@ namespace gmx */ class StepWorkload { - public: - //! Whether the state has changed, always set unless TPI is used. - bool stateChanged = false; - //! Whether the box might have changed - bool haveDynamicBox = false; - //! Whether neighbor searching needs to be done this step - bool doNeighborSearch = false; - //! Whether virial needs to be computed this step - bool computeVirial = false; - //! Whether energies need to be computed this step this step - bool computeEnergy = false; - //! Whether (any) forces need to be computed this step, not only energies - bool computeForces = false; - //! Whether nonbonded forces need to be computed this step - bool computeNonbondedForces = false; - //! Whether listed forces need to be computed this step - bool computeListedForces = false; - //! Whether this step DHDL needs to be computed - bool computeDhdl = false; - /*! \brief Whether coordinate buffer ops are done on the GPU this step - * \note This technically belongs to DomainLifetimeWorkload but due - * to needing the flag before DomainLifetimeWorkload is built we keep - * it here for now. - */ - bool useGpuXBufferOps = false; - //! Whether force buffer ops are done on the GPU this step - bool useGpuFBufferOps = false; - //! Whether PME forces are reduced with other contributions on the GPU this step - bool useGpuPmeFReduction = false; // TODO: add this flag to the internal PME GPU data structures too +public: + //! Whether the state has changed, always set unless TPI is used. + bool stateChanged = false; + //! Whether the box might have changed + bool haveDynamicBox = false; + //! Whether neighbor searching needs to be done this step + bool doNeighborSearch = false; + //! Whether virial needs to be computed this step + bool computeVirial = false; + //! Whether energies need to be computed this step this step + bool computeEnergy = false; + //! Whether (any) forces need to be computed this step, not only energies + bool computeForces = false; + //! Whether nonbonded forces need to be computed this step + bool computeNonbondedForces = false; + //! Whether listed forces need to be computed this step + bool computeListedForces = false; + //! Whether this step DHDL needs to be computed + bool computeDhdl = false; + /*! \brief Whether coordinate buffer ops are done on the GPU this step + * \note This technically belongs to DomainLifetimeWorkload but due + * to needing the flag before DomainLifetimeWorkload is built we keep + * it here for now. + */ + bool useGpuXBufferOps = false; + //! Whether force buffer ops are done on the GPU this step + bool useGpuFBufferOps = false; + //! Whether PME forces are reduced with other contributions on the GPU this step + bool useGpuPmeFReduction = false; // TODO: add this flag to the internal PME GPU data structures too }; /*! \libinternal @@ -108,23 +108,23 @@ class StepWorkload */ class DomainLifetimeWorkload { - public: - //! Whether the current nstlist step-range has bonded work to run on a GPU. - bool haveGpuBondedWork = false; - //! Whether the current nstlist step-range has bonded work to run on he CPU. - bool haveCpuBondedWork = false; - //! Whether the current nstlist step-range has restraints work to run on he CPU. - bool haveRestraintsWork = false; - //! Whether the current nstlist step-range has listed forces work to run on he CPU. - // Note: currently this is haveCpuBondedWork | haveRestraintsWork - bool haveCpuListedForceWork = false; - //! Whether the current nstlist step-range has special forces on the CPU. - bool haveSpecialForces = false; - //! Whether there are currently any local forces to be computed on the CPU - bool haveCpuLocalForceWork = false; +public: + //! Whether the current nstlist step-range has bonded work to run on a GPU. + bool haveGpuBondedWork = false; + //! Whether the current nstlist step-range has bonded work to run on he CPU. + bool haveCpuBondedWork = false; + //! Whether the current nstlist step-range has restraints work to run on he CPU. + bool haveRestraintsWork = false; + //! Whether the current nstlist step-range has listed forces work to run on he CPU. + // Note: currently this is haveCpuBondedWork | haveRestraintsWork + bool haveCpuListedForceWork = false; + //! Whether the current nstlist step-range has special forces on the CPU. + bool haveSpecialForces = false; + //! Whether there are currently any local forces to be computed on the CPU + bool haveCpuLocalForceWork = false; - //! Whether the current nstlist step-range Free energy work on the CPU. - bool haveFreeEnergyWork = false; + //! Whether the current nstlist step-range Free energy work on the CPU. + bool haveFreeEnergyWork = false; }; /*! \libinternal @@ -141,46 +141,46 @@ class DomainLifetimeWorkload */ class SimulationWorkload { - public: - //! If we have calculation of short range nonbondeds on CPU - bool useCpuNonbonded = false; - //! If we have calculation of short range nonbondeds on GPU - bool useGpuNonbonded = false; - //! If we have calculation of long range PME in GPU - bool useCpuPme = false; - //! If we have calculation of long range PME in GPU - bool useGpuPme = false; - //! If PME FFT solving is done on GPU. - bool useGpuPmeFft = false; - //! If bonded interactions are calculated on GPU. - bool useGpuBonded = false; - //! If update and constraint solving is performed on GPU. - bool useGpuUpdate = false; - //! If buffer operations are performed on GPU. - bool useGpuBufferOps = false; - //! If domain decomposition halo exchange is performed on GPU. - bool useGpuHaloExchange = false; - //! If direct PP-PME communication between GPU is used. - bool useGpuPmePpCommunication = false; - //! If direct GPU-GPU communication is enabled. - bool useGpuDirectCommunication = false; - //! If there is an Ewald surface (dipole) term to compute - bool haveEwaldSurfaceContribution = false; +public: + //! If we have calculation of short range nonbondeds on CPU + bool useCpuNonbonded = false; + //! If we have calculation of short range nonbondeds on GPU + bool useGpuNonbonded = false; + //! If we have calculation of long range PME in GPU + bool useCpuPme = false; + //! If we have calculation of long range PME in GPU + bool useGpuPme = false; + //! If PME FFT solving is done on GPU. + bool useGpuPmeFft = false; + //! If bonded interactions are calculated on GPU. + bool useGpuBonded = false; + //! If update and constraint solving is performed on GPU. + bool useGpuUpdate = false; + //! If buffer operations are performed on GPU. + bool useGpuBufferOps = false; + //! If domain decomposition halo exchange is performed on GPU. + bool useGpuHaloExchange = false; + //! If direct PP-PME communication between GPU is used. + bool useGpuPmePpCommunication = false; + //! If direct GPU-GPU communication is enabled. + bool useGpuDirectCommunication = false; + //! If there is an Ewald surface (dipole) term to compute + bool haveEwaldSurfaceContribution = false; }; class MdrunScheduleWorkload { - public: - //! Workload descriptor for information constant for an entire run - SimulationWorkload simulationWork; +public: + //! Workload descriptor for information constant for an entire run + SimulationWorkload simulationWork; - //! Workload descriptor for information constant for an nstlist range of steps - DomainLifetimeWorkload domainWork; + //! Workload descriptor for information constant for an nstlist range of steps + DomainLifetimeWorkload domainWork; - //! Workload descriptor for information that may change per-step - StepWorkload stepWork; + //! Workload descriptor for information that may change per-step + StepWorkload stepWork; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDTYPES_SIMULATION_WORKLOAD_H diff --git a/src/gromacs/mdtypes/state.cpp b/src/gromacs/mdtypes/state.cpp index 054ab2cc32..a949d589a3 100644 --- a/src/gromacs/mdtypes/state.cpp +++ b/src/gromacs/mdtypes/state.cpp @@ -61,45 +61,45 @@ /* The source code in this file should be thread-safe. Please keep it that way. */ -history_t::history_t() : disre_initf(0), - ndisrepairs(0), - disre_rm3tav(nullptr), - orire_initf(0), - norire_Dtav(0), - orire_Dtav(nullptr) -{ -}; - -ekinstate_t::ekinstate_t() : bUpToDate(FALSE), - ekin_n(0), - ekinh(nullptr), - ekinf(nullptr), - ekinh_old(nullptr), - ekin_total(), - - dekindl(0), - mvcos(0) +history_t::history_t() : + disre_initf(0), + ndisrepairs(0), + disre_rm3tav(nullptr), + orire_initf(0), + norire_Dtav(0), + orire_Dtav(nullptr){}; + +ekinstate_t::ekinstate_t() : + bUpToDate(FALSE), + ekin_n(0), + ekinh(nullptr), + ekinf(nullptr), + ekinh_old(nullptr), + ekin_total(), + + dekindl(0), + mvcos(0) { clear_mat(ekin_total); }; -void init_gtc_state(t_state *state, int ngtc, int nnhpres, int nhchainlength) +void init_gtc_state(t_state* state, int ngtc, int nnhpres, int nhchainlength) { state->ngtc = ngtc; state->nnhpres = nnhpres; state->nhchainlength = nhchainlength; - state->nosehoover_xi.resize(state->nhchainlength*state->ngtc, 0); - state->nosehoover_vxi.resize(state->nhchainlength*state->ngtc, 0); + state->nosehoover_xi.resize(state->nhchainlength * state->ngtc, 0); + state->nosehoover_vxi.resize(state->nhchainlength * state->ngtc, 0); state->therm_integral.resize(state->ngtc, 0); state->baros_integral = 0.0; - state->nhpres_xi.resize(state->nhchainlength*nnhpres, 0); - state->nhpres_vxi.resize(state->nhchainlength*nnhpres, 0); + state->nhpres_xi.resize(state->nhchainlength * nnhpres, 0); + state->nhpres_vxi.resize(state->nhchainlength * nnhpres, 0); } /* Checkpoint code relies on this function having no effect if state->natoms is > 0 and passed as natoms. */ -void state_change_natoms(t_state *state, int natoms) +void state_change_natoms(t_state* state, int natoms) { state->natoms = natoms; @@ -119,7 +119,7 @@ void state_change_natoms(t_state *state, int natoms) } } -void init_dfhist_state(t_state *state, int dfhistNumLambda) +void init_dfhist_state(t_state* state, int dfhistNumLambda) { if (dfhistNumLambda > 0) { @@ -132,8 +132,7 @@ void init_dfhist_state(t_state *state, int dfhistNumLambda) } } -void comp_state(const t_state *st1, const t_state *st2, - gmx_bool bRMSD, real ftol, real abstol) +void comp_state(const t_state* st1, const t_state* st2, gmx_bool bRMSD, real ftol, real abstol) { int i, j, nc; @@ -145,17 +144,17 @@ void comp_state(const t_state *st1, const t_state *st2, cmp_rvecs(stdout, "box_rel", DIM, st1->box_rel, st2->box_rel, FALSE, ftol, abstol); fprintf(stdout, "comparing boxv\n"); cmp_rvecs(stdout, "boxv", DIM, st1->boxv, st2->boxv, FALSE, ftol, abstol); - if (st1->flags & (1<flags & (1 << estSVIR_PREV)) { fprintf(stdout, "comparing shake vir_prev\n"); cmp_rvecs(stdout, "svir_prev", DIM, st1->svir_prev, st2->svir_prev, FALSE, ftol, abstol); } - if (st1->flags & (1<flags & (1 << estFVIR_PREV)) { fprintf(stdout, "comparing force vir_prev\n"); cmp_rvecs(stdout, "fvir_prev", DIM, st1->fvir_prev, st2->fvir_prev, FALSE, ftol, abstol); } - if (st1->flags & (1<flags & (1 << estPRES_PREV)) { fprintf(stdout, "comparing prev_pres\n"); cmp_rvecs(stdout, "pres_prev", DIM, st1->pres_prev, st2->pres_prev, FALSE, ftol, abstol); @@ -166,11 +165,11 @@ void comp_state(const t_state *st1, const t_state *st2, { for (i = 0; i < st1->ngtc; i++) { - nc = i*st1->nhchainlength; + nc = i * st1->nhchainlength; for (j = 0; j < nc; j++) { - cmp_real(stdout, "nosehoover_xi", - i, st1->nosehoover_xi[nc+j], st2->nosehoover_xi[nc+j], ftol, abstol); + cmp_real(stdout, "nosehoover_xi", i, st1->nosehoover_xi[nc + j], + st2->nosehoover_xi[nc + j], ftol, abstol); } } } @@ -179,11 +178,11 @@ void comp_state(const t_state *st1, const t_state *st2, { for (i = 0; i < st1->nnhpres; i++) { - nc = i*st1->nhchainlength; + nc = i * st1->nhchainlength; for (j = 0; j < nc; j++) { - cmp_real(stdout, "nosehoover_xi", - i, st1->nhpres_xi[nc+j], st2->nhpres_xi[nc+j], ftol, abstol); + cmp_real(stdout, "nosehoover_xi", i, st1->nhpres_xi[nc + j], st2->nhpres_xi[nc + j], + ftol, abstol); } } } @@ -191,29 +190,30 @@ void comp_state(const t_state *st1, const t_state *st2, cmp_int(stdout, "natoms", -1, st1->natoms, st2->natoms); if (st1->natoms == st2->natoms) { - if ((st1->flags & (1<flags & (1<flags & (1 << estX)) && (st2->flags & (1 << estX))) { fprintf(stdout, "comparing x\n"); - cmp_rvecs(stdout, "x", st1->natoms, st1->x.rvec_array(), st2->x.rvec_array(), bRMSD, ftol, abstol); + cmp_rvecs(stdout, "x", st1->natoms, st1->x.rvec_array(), st2->x.rvec_array(), bRMSD, + ftol, abstol); } - if ((st1->flags & (1<flags & (1<flags & (1 << estV)) && (st2->flags & (1 << estV))) { fprintf(stdout, "comparing v\n"); - cmp_rvecs(stdout, "v", st1->natoms, st1->v.rvec_array(), st2->v.rvec_array(), bRMSD, ftol, abstol); + cmp_rvecs(stdout, "v", st1->natoms, st1->v.rvec_array(), st2->v.rvec_array(), bRMSD, + ftol, abstol); } } } -rvec *makeRvecArray(gmx::ArrayRef v, - gmx::index n) +rvec* makeRvecArray(gmx::ArrayRef v, gmx::index n) { GMX_ASSERT(v.ssize() >= n, "We can't copy more elements than the vector size"); - rvec *dest; + rvec* dest; snew(dest, n); - const rvec *vPtr = as_rvec_array(v.data()); + const rvec* vPtr = as_rvec_array(v.data()); for (gmx::index i = 0; i < n; i++) { copy_rvec(vPtr[i], dest[i]); @@ -222,31 +222,32 @@ rvec *makeRvecArray(gmx::ArrayRef v, return dest; } -t_state::t_state() : natoms(0), - ngtc(0), - nnhpres(0), - nhchainlength(0), - flags(0), - fep_state(0), - lambda(), - - baros_integral(0), - veta(0), - vol0(0), - - ekinstate(), - hist(), - dfhist(nullptr), - awhHistory(nullptr), - ddp_count(0), - ddp_count_cg_gl(0) +t_state::t_state() : + natoms(0), + ngtc(0), + nnhpres(0), + nhchainlength(0), + flags(0), + fep_state(0), + lambda(), + + baros_integral(0), + veta(0), + vol0(0), + + ekinstate(), + hist(), + dfhist(nullptr), + awhHistory(nullptr), + ddp_count(0), + ddp_count_cg_gl(0) { // It would be nicer to initialize these with {} or {{0}} in the // above initialization list, but uncrustify doesn't understand // that. // TODO Fix this if we switch to clang-format some time. - lambda = {{ 0 }}; + lambda = { { 0 } }; clear_mat(box); clear_mat(box_rel); clear_mat(boxv); @@ -255,7 +256,7 @@ t_state::t_state() : natoms(0), clear_mat(fvir_prev); } -void set_box_rel(const t_inputrec *ir, t_state *state) +void set_box_rel(const t_inputrec* ir, t_state* state) { /* Make sure the box obeys the restrictions before we fix the ratios */ correct_box(nullptr, 0, state->box, nullptr); @@ -269,7 +270,7 @@ void set_box_rel(const t_inputrec *ir, t_state *state) } } -void preserve_box_shape(const t_inputrec *ir, matrix box_rel, matrix box) +void preserve_box_shape(const t_inputrec* ir, matrix box_rel, matrix box) { if (inputrecPreserveShape(ir)) { @@ -278,12 +279,12 @@ void preserve_box_shape(const t_inputrec *ir, matrix box_rel, matrix box) } } -void initialize_lambdas(FILE *fplog, - const t_inputrec &ir, +void initialize_lambdas(FILE* fplog, + const t_inputrec& ir, bool isMaster, - int *fep_state, + int* fep_state, gmx::ArrayRef lambda, - double *lam0) + double* lam0) { /* TODO: Clean up initialization of fep_state and lambda in t_state. This function works, but could probably use a logic @@ -294,7 +295,7 @@ void initialize_lambdas(FILE *fplog, return; } - const t_lambda *fep = ir.fepvals; + const t_lambda* fep = ir.fepvals; if (isMaster) { *fep_state = fep->init_fep_state; /* this might overwrite the checkpoint @@ -339,7 +340,7 @@ void initialize_lambdas(FILE *fplog, if (fplog != nullptr) { fprintf(fplog, "Initial vector of lambda components:[ "); - for (const auto &l : lambda) + for (const auto& l : lambda) { fprintf(fplog, "%10.4f ", l); } diff --git a/src/gromacs/mdtypes/state.h b/src/gromacs/mdtypes/state.h index 3bacabed39..e3a3ce5c6b 100644 --- a/src/gromacs/mdtypes/state.h +++ b/src/gromacs/mdtypes/state.h @@ -74,7 +74,7 @@ struct AwhHistory; } //! Convenience alias for until all is moved in the gmx namespace -template +template using PaddedHostVector = gmx::PaddedHostVector; /* @@ -89,21 +89,42 @@ using PaddedHostVector = gmx::PaddedHostVector; * The order of these enums should not be changed, * since that affects the checkpoint (.cpt) file format. */ -enum { +enum +{ estLAMBDA, - estBOX, estBOX_REL, estBOXV, estPRES_PREV, estNH_XI, estTHERM_INT, - estX, estV, estSDX_NOTSUPPORTED, estCGP, - estLD_RNG_NOTSUPPORTED, estLD_RNGI_NOTSUPPORTED, - estDISRE_INITF, estDISRE_RM3TAV, - estORIRE_INITF, estORIRE_DTAV, - estSVIR_PREV, estNH_VXI, estVETA, estVOL0, estNHPRES_XI, estNHPRES_VXI, estFVIR_PREV, - estFEPSTATE, estMC_RNG_NOTSUPPORTED, estMC_RNGI_NOTSUPPORTED, - estBAROS_INT, estPULLCOMPREVSTEP, + estBOX, + estBOX_REL, + estBOXV, + estPRES_PREV, + estNH_XI, + estTHERM_INT, + estX, + estV, + estSDX_NOTSUPPORTED, + estCGP, + estLD_RNG_NOTSUPPORTED, + estLD_RNGI_NOTSUPPORTED, + estDISRE_INITF, + estDISRE_RM3TAV, + estORIRE_INITF, + estORIRE_DTAV, + estSVIR_PREV, + estNH_VXI, + estVETA, + estVOL0, + estNHPRES_XI, + estNHPRES_VXI, + estFVIR_PREV, + estFEPSTATE, + estMC_RNG_NOTSUPPORTED, + estMC_RNGI_NOTSUPPORTED, + estBAROS_INT, + estPULLCOMPREVSTEP, estNR }; //! \brief The names of the state entries, defined in src/gmxlib/checkpoint.c -extern const char *est_names[estNR]; +extern const char* est_names[estNR]; /*! \libinternal \brief History information for NMR distance and orientation restraints * @@ -114,15 +135,15 @@ extern const char *est_names[estNR]; */ class history_t { - public: - history_t(); - - real disre_initf; //!< The scaling factor for initializing the time av. - int ndisrepairs; //!< The number of distance restraints - real *disre_rm3tav; //!< The r^-3 time averaged pair distances - real orire_initf; //!< The scaling factor for initializing the time av. - int norire_Dtav; //!< The number of matrix element in dtav (npair*5) - real *orire_Dtav; //!< The time averaged orientation tensors +public: + history_t(); + + real disre_initf; //!< The scaling factor for initializing the time av. + int ndisrepairs; //!< The number of distance restraints + real* disre_rm3tav; //!< The r^-3 time averaged pair distances + real orire_initf; //!< The scaling factor for initializing the time av. + int norire_Dtav; //!< The number of matrix element in dtav (npair*5) + real* orire_Dtav; //!< The time averaged orientation tensors }; /*! \libinternal \brief Struct used for checkpointing only @@ -134,26 +155,26 @@ class history_t */ class ekinstate_t { - public: - ekinstate_t(); - - gmx_bool bUpToDate; //!< Test if all data is up to date - int ekin_n; //!< The number of tensors - tensor *ekinh; //!< Half step Ekin, size \p ekin_n - tensor *ekinf; //!< Full step Ekin, size \p ekin_n - tensor *ekinh_old; //!< Half step Ekin of the previous step, size \p ekin_n - tensor ekin_total; //!< Total kinetic energy - std::vector ekinscalef_nhc; //!< Nose-Hoover Ekin scaling factors for full step Ekin - std::vector ekinscaleh_nhc; //!< Nose-Hoover Ekin scaling factors for half step Ekin - std::vector vscale_nhc; //!< Nose-Hoover velocity scaling factors - real dekindl; //!< dEkin/dlambda, with free-energy - real mvcos; //!< Cosine(z) component of the momentum, for viscosity calculations - /*! \brief Whether KE terms have been read from the checkpoint. - * - * Only used for managing whether the call to compute_globals - * before we enter the MD loop should compute these quantities - * fresh, or not. */ - bool hasReadEkinState; +public: + ekinstate_t(); + + gmx_bool bUpToDate; //!< Test if all data is up to date + int ekin_n; //!< The number of tensors + tensor* ekinh; //!< Half step Ekin, size \p ekin_n + tensor* ekinf; //!< Full step Ekin, size \p ekin_n + tensor* ekinh_old; //!< Half step Ekin of the previous step, size \p ekin_n + tensor ekin_total; //!< Total kinetic energy + std::vector ekinscalef_nhc; //!< Nose-Hoover Ekin scaling factors for full step Ekin + std::vector ekinscaleh_nhc; //!< Nose-Hoover Ekin scaling factors for half step Ekin + std::vector vscale_nhc; //!< Nose-Hoover velocity scaling factors + real dekindl; //!< dEkin/dlambda, with free-energy + real mvcos; //!< Cosine(z) component of the momentum, for viscosity calculations + /*! \brief Whether KE terms have been read from the checkpoint. + * + * Only used for managing whether the call to compute_globals + * before we enter the MD loop should compute these quantities + * fresh, or not. */ + bool hasReadEkinState; }; /*! \brief Free-energy sampling history struct @@ -162,25 +183,25 @@ class ekinstate_t */ typedef struct df_history_t { - int nlambda; //!< total number of lambda states - for history + int nlambda; //!< total number of lambda states - for history - gmx_bool bEquil; //!< Have we reached equilibration - int *n_at_lam; //!< number of points observed at each lambda - real *wl_histo; //!< histogram for WL flatness determination - real wl_delta; //!< current wang-landau delta + gmx_bool bEquil; //!< Have we reached equilibration + int* n_at_lam; //!< number of points observed at each lambda + real* wl_histo; //!< histogram for WL flatness determination + real wl_delta; //!< current wang-landau delta - real *sum_weights; //!< weights of the states - real *sum_dg; //!< free energies of the states -- not actually used for weighting, but informational - real *sum_minvar; //!< corrections to weights for minimum variance - real *sum_variance; //!< variances of the states + real* sum_weights; //!< weights of the states + real* sum_dg; //!< free energies of the states -- not actually used for weighting, but informational + real* sum_minvar; //!< corrections to weights for minimum variance + real* sum_variance; //!< variances of the states - real **accum_p; //!< accumulated bennett weights for n+1 - real **accum_m; //!< accumulated bennett weights for n-1 - real **accum_p2; //!< accumulated squared bennett weights for n+1 - real **accum_m2; //!< accumulated squared bennett weights for n-1 + real** accum_p; //!< accumulated bennett weights for n+1 + real** accum_m; //!< accumulated bennett weights for n-1 + real** accum_p2; //!< accumulated squared bennett weights for n+1 + real** accum_m2; //!< accumulated squared bennett weights for n-1 - real **Tij; //!< transition matrix - real **Tij_empirical; //!< Empirical transition matrix + real** Tij; //!< transition matrix + real** Tij_empirical; //!< Empirical transition matrix } df_history_t; @@ -195,47 +216,47 @@ typedef struct df_history_t */ class t_state { - public: - t_state(); - - // All things public - int natoms; //!< Number of atoms, local + non-local; this is the size of \p x, \p v and \p cg_p, when used - int ngtc; //!< The number of temperature coupling groups - int nnhpres; //!< The NH-chain length for the MTTK barostat - int nhchainlength; //!< The NH-chain length for temperature coupling - int flags; //!< Set of bit-flags telling which entries are present, see enum at the top of the file - int fep_state; //!< indicates which of the alchemical states we are in - std::array lambda; //!< Free-energy lambda vector - matrix box; //!< Matrix of box vectors - matrix box_rel; //!< Relative box vectors to preserve box shape - matrix boxv; //!< Box velocities for Parrinello-Rahman P-coupling - matrix pres_prev; //!< Pressure of the previous step for pcoupl - matrix svir_prev; //!< Shake virial for previous step for pcoupl - matrix fvir_prev; //!< Force virial of the previous step for pcoupl - std::vector nosehoover_xi; //!< Nose-Hoover coordinates (ngtc) - std::vector nosehoover_vxi; //!< Nose-Hoover velocities (ngtc) - std::vector nhpres_xi; //!< Pressure Nose-Hoover coordinates - std::vector nhpres_vxi; //!< Pressure Nose-Hoover velocities - std::vector therm_integral; //!< Work exterted N-H/V-rescale T-coupling (ngtc) - double baros_integral; //!< For Berendsen P-coupling conserved quantity - real veta; //!< Trotter based isotropic P-coupling - real vol0; //!< Initial volume,required for computing MTTK conserved quantity - PaddedHostVector x; //!< The coordinates (natoms) - PaddedHostVector v; //!< The velocities (natoms) - PaddedHostVector cg_p; //!< p vector for conjugate gradient minimization - - ekinstate_t ekinstate; //!< The state of the kinetic energy - - /* History for special algorithms, should be moved to a history struct */ - history_t hist; //!< Time history for restraints - df_history_t *dfhist; //!< Free-energy history for free energy analysis - std::shared_ptr awhHistory; //!< Accelerated weight histogram history - - int ddp_count; //!< The DD partitioning count for this state - int ddp_count_cg_gl; //!< The DD partitioning count for index_gl - std::vector cg_gl; //!< The global cg number of the local cgs - - std::vector pull_com_prev_step; //!< The COM of the previous step of each pull group +public: + t_state(); + + // All things public + int natoms; //!< Number of atoms, local + non-local; this is the size of \p x, \p v and \p cg_p, when used + int ngtc; //!< The number of temperature coupling groups + int nnhpres; //!< The NH-chain length for the MTTK barostat + int nhchainlength; //!< The NH-chain length for temperature coupling + int flags; //!< Set of bit-flags telling which entries are present, see enum at the top of the file + int fep_state; //!< indicates which of the alchemical states we are in + std::array lambda; //!< Free-energy lambda vector + matrix box; //!< Matrix of box vectors + matrix box_rel; //!< Relative box vectors to preserve box shape + matrix boxv; //!< Box velocities for Parrinello-Rahman P-coupling + matrix pres_prev; //!< Pressure of the previous step for pcoupl + matrix svir_prev; //!< Shake virial for previous step for pcoupl + matrix fvir_prev; //!< Force virial of the previous step for pcoupl + std::vector nosehoover_xi; //!< Nose-Hoover coordinates (ngtc) + std::vector nosehoover_vxi; //!< Nose-Hoover velocities (ngtc) + std::vector nhpres_xi; //!< Pressure Nose-Hoover coordinates + std::vector nhpres_vxi; //!< Pressure Nose-Hoover velocities + std::vector therm_integral; //!< Work exterted N-H/V-rescale T-coupling (ngtc) + double baros_integral; //!< For Berendsen P-coupling conserved quantity + real veta; //!< Trotter based isotropic P-coupling + real vol0; //!< Initial volume,required for computing MTTK conserved quantity + PaddedHostVector x; //!< The coordinates (natoms) + PaddedHostVector v; //!< The velocities (natoms) + PaddedHostVector cg_p; //!< p vector for conjugate gradient minimization + + ekinstate_t ekinstate; //!< The state of the kinetic energy + + /* History for special algorithms, should be moved to a history struct */ + history_t hist; //!< Time history for restraints + df_history_t* dfhist; //!< Free-energy history for free energy analysis + std::shared_ptr awhHistory; //!< Accelerated weight histogram history + + int ddp_count; //!< The DD partitioning count for this state + int ddp_count_cg_gl; //!< The DD partitioning count for index_gl + std::vector cg_gl; //!< The global cg number of the local cgs + + std::vector pull_com_prev_step; //!< The COM of the previous step of each pull group }; #ifndef DOXYGEN @@ -245,9 +266,9 @@ class t_state struct t_extmass { - std::vector Qinv; /* inverse mass of thermostat -- computed from inputs, but a good place to store */ + std::vector Qinv; /* inverse mass of thermostat -- computed from inputs, but a good place to store */ std::vector QPinv; /* inverse mass of thermostat for barostat -- computed from inputs, but a good place to store */ - double Winv; /* Pressure mass inverse -- computed, not input, but a good place to store. Need to make a matrix later */ + double Winv; /* Pressure mass inverse -- computed, not input, but a good place to store. Need to make a matrix later */ tensor Winvm; /* inverse pressure mass tensor, computed */ }; @@ -259,26 +280,25 @@ typedef struct double vscale; double rvscale; double alpha; - double *vscale_nhc; + double* vscale_nhc; } t_vetavars; #endif // DOXYGEN //! Resizes the T- and P-coupling state variables -void init_gtc_state(t_state *state, int ngtc, int nnhpres, int nhchainlength); +void init_gtc_state(t_state* state, int ngtc, int nnhpres, int nhchainlength); //! Change the number of atoms represented by this state, allocating memory as needed. -void state_change_natoms(t_state *state, int natoms); +void state_change_natoms(t_state* state, int natoms); //! Allocates memory for free-energy history -void init_dfhist_state(t_state *state, int dfhistNumLambda); +void init_dfhist_state(t_state* state, int dfhistNumLambda); /*! \brief Compares two states, write the differences to stdout */ -void comp_state(const t_state *st1, const t_state *st2, gmx_bool bRMSD, real ftol, real abstol); +void comp_state(const t_state* st1, const t_state* st2, gmx_bool bRMSD, real ftol, real abstol); /*! \brief Allocates an rvec pointer and copy the contents of v to it */ -rvec *makeRvecArray(gmx::ArrayRef v, - gmx::index n); +rvec* makeRvecArray(gmx::ArrayRef v, gmx::index n); /*! \brief Determine the relative box components * @@ -286,7 +306,7 @@ rvec *makeRvecArray(gmx::ArrayRef v, * \param[in] ir Input record * \param[inout] state State */ -void set_box_rel(const t_inputrec *ir, t_state *state); +void set_box_rel(const t_inputrec* ir, t_state* state); /*! \brief Make sure the relative box shape remains the same * @@ -298,7 +318,7 @@ void set_box_rel(const t_inputrec *ir, t_state *state); * \param[in] box_rel Relative box dimensions * \param[inout] box The corrected actual box dimensions */ -void preserve_box_shape(const t_inputrec *ir, matrix box_rel, matrix box); +void preserve_box_shape(const t_inputrec* ir, matrix box_rel, matrix box); /*! \brief Returns an arrayRef to the positions in \p state when \p state!=null * @@ -308,8 +328,7 @@ void preserve_box_shape(const t_inputrec *ir, matrix box_rel, matrix box); * * \param[in] state The state, can be nullptr */ -static inline gmx::ArrayRef -positionsFromStatePointer(const t_state *state) +static inline gmx::ArrayRef positionsFromStatePointer(const t_state* state) { if (state) { @@ -329,11 +348,11 @@ positionsFromStatePointer(const t_state *state) * on master rank fills fep_state and lambda. * * Reports the initial lambda state to the log file. */ -void initialize_lambdas(FILE *fplog, - const t_inputrec &ir, +void initialize_lambdas(FILE* fplog, + const t_inputrec& ir, bool isMaster, - int *fep_state, + int* fep_state, gmx::ArrayRef lambda, - double *lam0); + double* lam0); #endif diff --git a/src/gromacs/mdtypes/state_propagator_data_gpu.h b/src/gromacs/mdtypes/state_propagator_data_gpu.h index 5617395073..a0d9309f67 100644 --- a/src/gromacs/mdtypes/state_propagator_data_gpu.h +++ b/src/gromacs/mdtypes/state_propagator_data_gpu.h @@ -66,287 +66,279 @@ namespace gmx class StatePropagatorDataGpu { - public: - - /*! \brief Constructor - * - * The buffers are reallocated only at the reinit call, the padding is - * used there for the coordinates buffer. It is needed for PME and added at - * the end of the buffer. It is assumed that if the rank has PME duties on the - * GPU, all coordinates are copied to the GPU and hence, for this rank, the - * coordinates buffer is not split into local and non-local ranges. For other - * ranks, the padding size is zero. This works because only one rank ever does - * PME work on the GPU, and if that rank also does PP work that is the only - * rank. So all coordinates are always transferred. - * - * In OpenCL, only pmeStream is used since it is the only stream created in - * PME context. The local and non-local streams are only needed when buffer - * ops are offloaded. This feature is currently not available in OpenCL and - * hence these streams are not set in these builds. - * - * \note In CUDA, the update stream is created in the constructor as a temporary - * solution, in place until the stream manager is introduced. - * Note that this makes it impossible to construct this object in CUDA - * builds executing on a host without any CUDA-capable device available. - * - * \note In CUDA, \p deviceContext is unused, hence always nullptr; - * all stream arguments can also be nullptr in runs where the - * respective streams are not required. - * In OpenCL, \p deviceContext needs to be a valid device context. - * In OpenCL runs StatePropagatorDataGpu is currently only used - * with PME offload, and only on ranks with PME duty. Hence, the - * \p pmeStream argument needs to be a valid OpenCL queue object - * which must have been created in \p deviceContext. - * - * \todo Make a \p CommandStream visible in the CPU parts of the code so we - * will not have to pass a void*. - * \todo Make a \p DeviceContext object visible in CPU parts of the code so we - * will not have to pass a void*. - * - * \param[in] pmeStream Device PME stream, nullptr allowed. - * \param[in] localStream Device NBNXM local stream, nullptr allowed. - * \param[in] nonLocalStream Device NBNXM non-local stream, nullptr allowed. - * \param[in] deviceContext Device context, nullptr allowed. - * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). - * \param[in] paddingSize Padding size for coordinates buffer. - */ - StatePropagatorDataGpu(const void *pmeStream, - const void *localStream, - const void *nonLocalStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize); - - /*! \brief Constructor to use in PME-only rank and in tests. - * - * This constructor should be used if only a coordinate device buffer should be managed - * using a single stream. Any operation on force or velocity buffer as well as copy of - * non-local coordinates will exit with assertion failure. Note, that the pmeStream can - * not be a nullptr and the constructor will exit with an assertion failure. - * - * \todo Currently, unsupported copy operations are blocked by assertion that the stream - * not nullptr. This should be improved. - * - * \param[in] pmeStream Device PME stream, nullptr is not allowed. - * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds. - * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). - * \param[in] paddingSize Padding size for coordinates buffer. - */ - StatePropagatorDataGpu(const void *pmeStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize); - - //! Move constructor - StatePropagatorDataGpu(StatePropagatorDataGpu &&other) noexcept; - //! Move assignment - StatePropagatorDataGpu &operator=(StatePropagatorDataGpu &&other) noexcept; - //! Destructor - ~StatePropagatorDataGpu(); - - /*! \brief Set the ranges for local and non-local atoms and reallocates buffers. - * - * \note - * The coordinates buffer is (re)allocated, when required by PME, with a padding, - * the size of which is set by the constructor. The padding region clearing kernel - * is scheduled in the \p pmeStream_ (unlike the coordinates H2D) as only the PME - * task uses this padding area. - * - * \param[in] numAtomsLocal Number of atoms in local domain. - * \param[in] numAtomsAll Total number of atoms to handle. - */ - void reinit(int numAtomsLocal, int numAtomsAll); - - /*! \brief Returns the range of atoms to be copied based on the copy type (all, local or non-local). - * - * \todo There are at least three versions of the function with this functionality in the code: - * this one and two more in NBNXM. These should be unified in a shape of a general function - * in DD. - * - * \param[in] atomLocality If all, local or non-local ranges are needed. - * - * \returns Tuple, containing the index of the first atom in the range and the total number of atoms in the range. - */ - std::tuple getAtomRangesFromAtomLocality(AtomLocality atomLocality); - - - /*! \brief Get the positions buffer on the GPU. - * - * \returns GPU positions buffer. - */ - DeviceBuffer getCoordinates(); - - /*! \brief Copy positions to the GPU memory. - * - * \param[in] h_x Positions in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyCoordinatesToGpu(gmx::ArrayRef h_x, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer of the coordinates ready for the consumption on the device. - * - * Returns the event synchronizer which indicates that the coordinates are ready for the - * consumption on the device. Takes into account that the producer may be different. - * - * If the update is offloaded, and the current step is not a DD/search step, the returned - * synchronizer indicates the completion of GPU update-constraint kernels. Otherwise, on search - * steps and if update is not offloaded, the coordinates are provided by the H2D copy and the - * returned synchronizer indicates that the copy is complete. - * - * \param[in] atomLocality Locality of the particles to wait for. - * \param[in] simulationWork The simulation lifetime flags. - * \param[in] stepWork The step lifetime flags. - * - * \returns The event to synchronize the stream that consumes coordinates on device. - */ - GpuEventSynchronizer* getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, - const SimulationWorkload &simulationWork, - const StepWorkload &stepWork); - - /*! \brief Blocking wait until coordinates are copied to the device. - * - * Synchronizes the stream in which the copy was executed. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitCoordinatesCopiedToDevice(AtomLocality atomLocality); - - /*! \brief Getter for the event synchronizer for the update is done on th GPU - * - * \returns The event to synchronize the stream coordinates wre updated on device. - */ - GpuEventSynchronizer* xUpdatedOnDevice(); - - /*! \brief Copy positions from the GPU memory. - * - * \param[in] h_x Positions buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyCoordinatesFromGpu(gmx::ArrayRef h_x, - AtomLocality atomLocality); - - /*! \brief Wait until coordinates are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitCoordinatesReadyOnHost(AtomLocality atomLocality); - - - /*! \brief Get the velocities buffer on the GPU. - * - * \returns GPU velocities buffer. - */ - DeviceBuffer getVelocities(); - - /*! \brief Copy velocities to the GPU memory. - * - * \param[in] h_v Velocities in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyVelocitiesToGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer for the H2D velocities copy. - * - * \param[in] atomLocality Locality of the particles to wait for. - * - * \returns The event to synchronize the stream that consumes velocities on device. - */ - GpuEventSynchronizer* getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality); - - /*! \brief Copy velocities from the GPU memory. - * - * \param[in] h_v Velocities buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyVelocitiesFromGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality); - - /*! \brief Wait until velocities are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitVelocitiesReadyOnHost(AtomLocality atomLocality); - - - /*! \brief Get the force buffer on the GPU. - * - * \returns GPU force buffer. - */ - DeviceBuffer getForces(); - - /*! \brief Copy forces to the GPU memory. - * - * \param[in] h_f Forces in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyForcesToGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer for the forces ready on device. - * - * Returns either of the event synchronizers, depending on the offload scenario - * for the current simulation timestep: - * 1. The forces are copied to the device (when GPU buffer ops are off) - * 2. The forces are reduced on the device (GPU buffer ops are on) - * - * \todo Pass step workload instead of the useGpuFBufferOps boolean. - * - * \param[in] atomLocality Locality of the particles to wait for. - * \param[in] useGpuFBufferOps If the force buffer ops are offloaded to the GPU. - * - * \returns The event to synchronize the stream that consumes forces on device. - */ - GpuEventSynchronizer* getForcesReadyOnDeviceEvent(AtomLocality atomLocality, - bool useGpuFBufferOps); - - /*! \brief Getter for the event synchronizer for the forces are reduced on the GPU. - * - * \returns The event to mark when forces are reduced on the GPU. - */ - GpuEventSynchronizer* fReducedOnDevice(); - - /*! \brief Copy forces from the GPU memory. - * - * \param[in] h_f Forces buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyForcesFromGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality); - - /*! \brief Wait until forces are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitForcesReadyOnHost(AtomLocality atomLocality); - - /*! \brief Getter for the update stream. - * - * \todo This is temporary here, until the management of this stream is taken over. - * - * \returns The device command stream to use in update-constraints. - */ - void* getUpdateStream(); - - /*! \brief Getter for the number of local atoms. - * - * \returns The number of local atoms. - */ - int numAtomsLocal(); - - /*! \brief Getter for the total number of atoms. - * - * \returns The total number of atoms. - */ - int numAtomsAll(); - - private: - class Impl; - gmx::PrivateImplPointer impl_; - GMX_DISALLOW_COPY_AND_ASSIGN(StatePropagatorDataGpu); +public: + /*! \brief Constructor + * + * The buffers are reallocated only at the reinit call, the padding is + * used there for the coordinates buffer. It is needed for PME and added at + * the end of the buffer. It is assumed that if the rank has PME duties on the + * GPU, all coordinates are copied to the GPU and hence, for this rank, the + * coordinates buffer is not split into local and non-local ranges. For other + * ranks, the padding size is zero. This works because only one rank ever does + * PME work on the GPU, and if that rank also does PP work that is the only + * rank. So all coordinates are always transferred. + * + * In OpenCL, only pmeStream is used since it is the only stream created in + * PME context. The local and non-local streams are only needed when buffer + * ops are offloaded. This feature is currently not available in OpenCL and + * hence these streams are not set in these builds. + * + * \note In CUDA, the update stream is created in the constructor as a temporary + * solution, in place until the stream manager is introduced. + * Note that this makes it impossible to construct this object in CUDA + * builds executing on a host without any CUDA-capable device available. + * + * \note In CUDA, \p deviceContext is unused, hence always nullptr; + * all stream arguments can also be nullptr in runs where the + * respective streams are not required. + * In OpenCL, \p deviceContext needs to be a valid device context. + * In OpenCL runs StatePropagatorDataGpu is currently only used + * with PME offload, and only on ranks with PME duty. Hence, the + * \p pmeStream argument needs to be a valid OpenCL queue object + * which must have been created in \p deviceContext. + * + * \todo Make a \p CommandStream visible in the CPU parts of the code so we + * will not have to pass a void*. + * \todo Make a \p DeviceContext object visible in CPU parts of the code so we + * will not have to pass a void*. + * + * \param[in] pmeStream Device PME stream, nullptr allowed. + * \param[in] localStream Device NBNXM local stream, nullptr allowed. + * \param[in] nonLocalStream Device NBNXM non-local stream, nullptr allowed. + * \param[in] deviceContext Device context, nullptr allowed. + * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). + * \param[in] paddingSize Padding size for coordinates buffer. + */ + StatePropagatorDataGpu(const void* pmeStream, + const void* localStream, + const void* nonLocalStream, + const void* deviceContext, + GpuApiCallBehavior transferKind, + int paddingSize); + + /*! \brief Constructor to use in PME-only rank and in tests. + * + * This constructor should be used if only a coordinate device buffer should be managed + * using a single stream. Any operation on force or velocity buffer as well as copy of + * non-local coordinates will exit with assertion failure. Note, that the pmeStream can + * not be a nullptr and the constructor will exit with an assertion failure. + * + * \todo Currently, unsupported copy operations are blocked by assertion that the stream + * not nullptr. This should be improved. + * + * \param[in] pmeStream Device PME stream, nullptr is not allowed. + * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds. + * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). + * \param[in] paddingSize Padding size for coordinates buffer. + */ + StatePropagatorDataGpu(const void* pmeStream, + const void* deviceContext, + GpuApiCallBehavior transferKind, + int paddingSize); + + //! Move constructor + StatePropagatorDataGpu(StatePropagatorDataGpu&& other) noexcept; + //! Move assignment + StatePropagatorDataGpu& operator=(StatePropagatorDataGpu&& other) noexcept; + //! Destructor + ~StatePropagatorDataGpu(); + + /*! \brief Set the ranges for local and non-local atoms and reallocates buffers. + * + * \note + * The coordinates buffer is (re)allocated, when required by PME, with a padding, + * the size of which is set by the constructor. The padding region clearing kernel + * is scheduled in the \p pmeStream_ (unlike the coordinates H2D) as only the PME + * task uses this padding area. + * + * \param[in] numAtomsLocal Number of atoms in local domain. + * \param[in] numAtomsAll Total number of atoms to handle. + */ + void reinit(int numAtomsLocal, int numAtomsAll); + + /*! \brief Returns the range of atoms to be copied based on the copy type (all, local or non-local). + * + * \todo There are at least three versions of the function with this functionality in the code: + * this one and two more in NBNXM. These should be unified in a shape of a general function + * in DD. + * + * \param[in] atomLocality If all, local or non-local ranges are needed. + * + * \returns Tuple, containing the index of the first atom in the range and the total number of atoms in the range. + */ + std::tuple getAtomRangesFromAtomLocality(AtomLocality atomLocality); + + + /*! \brief Get the positions buffer on the GPU. + * + * \returns GPU positions buffer. + */ + DeviceBuffer getCoordinates(); + + /*! \brief Copy positions to the GPU memory. + * + * \param[in] h_x Positions in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyCoordinatesToGpu(gmx::ArrayRef h_x, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer of the coordinates ready for the consumption on the device. + * + * Returns the event synchronizer which indicates that the coordinates are ready for the + * consumption on the device. Takes into account that the producer may be different. + * + * If the update is offloaded, and the current step is not a DD/search step, the returned + * synchronizer indicates the completion of GPU update-constraint kernels. Otherwise, on search + * steps and if update is not offloaded, the coordinates are provided by the H2D copy and the + * returned synchronizer indicates that the copy is complete. + * + * \param[in] atomLocality Locality of the particles to wait for. + * \param[in] simulationWork The simulation lifetime flags. + * \param[in] stepWork The step lifetime flags. + * + * \returns The event to synchronize the stream that consumes coordinates on device. + */ + GpuEventSynchronizer* getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, + const SimulationWorkload& simulationWork, + const StepWorkload& stepWork); + + /*! \brief Blocking wait until coordinates are copied to the device. + * + * Synchronizes the stream in which the copy was executed. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitCoordinatesCopiedToDevice(AtomLocality atomLocality); + + /*! \brief Getter for the event synchronizer for the update is done on th GPU + * + * \returns The event to synchronize the stream coordinates wre updated on device. + */ + GpuEventSynchronizer* xUpdatedOnDevice(); + + /*! \brief Copy positions from the GPU memory. + * + * \param[in] h_x Positions buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyCoordinatesFromGpu(gmx::ArrayRef h_x, AtomLocality atomLocality); + + /*! \brief Wait until coordinates are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitCoordinatesReadyOnHost(AtomLocality atomLocality); + + + /*! \brief Get the velocities buffer on the GPU. + * + * \returns GPU velocities buffer. + */ + DeviceBuffer getVelocities(); + + /*! \brief Copy velocities to the GPU memory. + * + * \param[in] h_v Velocities in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyVelocitiesToGpu(gmx::ArrayRef h_v, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer for the H2D velocities copy. + * + * \param[in] atomLocality Locality of the particles to wait for. + * + * \returns The event to synchronize the stream that consumes velocities on device. + */ + GpuEventSynchronizer* getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality); + + /*! \brief Copy velocities from the GPU memory. + * + * \param[in] h_v Velocities buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyVelocitiesFromGpu(gmx::ArrayRef h_v, AtomLocality atomLocality); + + /*! \brief Wait until velocities are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitVelocitiesReadyOnHost(AtomLocality atomLocality); + + + /*! \brief Get the force buffer on the GPU. + * + * \returns GPU force buffer. + */ + DeviceBuffer getForces(); + + /*! \brief Copy forces to the GPU memory. + * + * \param[in] h_f Forces in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyForcesToGpu(gmx::ArrayRef h_f, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer for the forces ready on device. + * + * Returns either of the event synchronizers, depending on the offload scenario + * for the current simulation timestep: + * 1. The forces are copied to the device (when GPU buffer ops are off) + * 2. The forces are reduced on the device (GPU buffer ops are on) + * + * \todo Pass step workload instead of the useGpuFBufferOps boolean. + * + * \param[in] atomLocality Locality of the particles to wait for. + * \param[in] useGpuFBufferOps If the force buffer ops are offloaded to the GPU. + * + * \returns The event to synchronize the stream that consumes forces on device. + */ + GpuEventSynchronizer* getForcesReadyOnDeviceEvent(AtomLocality atomLocality, bool useGpuFBufferOps); + + /*! \brief Getter for the event synchronizer for the forces are reduced on the GPU. + * + * \returns The event to mark when forces are reduced on the GPU. + */ + GpuEventSynchronizer* fReducedOnDevice(); + + /*! \brief Copy forces from the GPU memory. + * + * \param[in] h_f Forces buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyForcesFromGpu(gmx::ArrayRef h_f, AtomLocality atomLocality); + + /*! \brief Wait until forces are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitForcesReadyOnHost(AtomLocality atomLocality); + + /*! \brief Getter for the update stream. + * + * \todo This is temporary here, until the management of this stream is taken over. + * + * \returns The device command stream to use in update-constraints. + */ + void* getUpdateStream(); + + /*! \brief Getter for the number of local atoms. + * + * \returns The number of local atoms. + */ + int numAtomsLocal(); + + /*! \brief Getter for the total number of atoms. + * + * \returns The total number of atoms. + */ + int numAtomsAll(); + +private: + class Impl; + gmx::PrivateImplPointer impl_; + GMX_DISALLOW_COPY_AND_ASSIGN(StatePropagatorDataGpu); }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDTYPES_STATE_PROPAGATOR_DATA_GPU_H diff --git a/src/gromacs/mdtypes/state_propagator_data_gpu_impl.cpp b/src/gromacs/mdtypes/state_propagator_data_gpu_impl.cpp index 43d707dc3c..9b201b9376 100644 --- a/src/gromacs/mdtypes/state_propagator_data_gpu_impl.cpp +++ b/src/gromacs/mdtypes/state_propagator_data_gpu_impl.cpp @@ -54,170 +54,216 @@ class StatePropagatorDataGpu::Impl { }; -StatePropagatorDataGpu::StatePropagatorDataGpu(const void * /* pmeStream */, - const void * /* localStream */, - const void * /* nonLocalStream */, - const void * /* deviceContext */, +StatePropagatorDataGpu::StatePropagatorDataGpu(const void* /* pmeStream */, + const void* /* localStream */, + const void* /* nonLocalStream */, + const void* /* deviceContext */, GpuApiCallBehavior /* transferKind */, - int /* paddingSize */) - : impl_(nullptr) + int /* paddingSize */) : + impl_(nullptr) { } -StatePropagatorDataGpu::StatePropagatorDataGpu(const void * /* pmeStream */, - const void * /* deviceContext */, +StatePropagatorDataGpu::StatePropagatorDataGpu(const void* /* pmeStream */, + const void* /* deviceContext */, GpuApiCallBehavior /* transferKind */, - int /* paddingSize */) - : impl_(nullptr) + int /* paddingSize */) : + impl_(nullptr) { } -StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu && /* other */) noexcept = default; +StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu&& /* other */) noexcept = default; -StatePropagatorDataGpu &StatePropagatorDataGpu::operator=(StatePropagatorDataGpu && /* other */) noexcept = default; +StatePropagatorDataGpu& StatePropagatorDataGpu::operator=(StatePropagatorDataGpu&& /* other */) noexcept = default; StatePropagatorDataGpu::~StatePropagatorDataGpu() = default; -void StatePropagatorDataGpu::reinit(int /* numAtomsLocal */, - int /* numAtomsAll */) +void StatePropagatorDataGpu::reinit(int /* numAtomsLocal */, int /* numAtomsAll */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -std::tuple StatePropagatorDataGpu::getAtomRangesFromAtomLocality(AtomLocality /* atomLocality */) +std::tuple StatePropagatorDataGpu::getAtomRangesFromAtomLocality(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return std::make_tuple(0, 0); } DeviceBuffer StatePropagatorDataGpu::getCoordinates() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); - return DeviceBuffer {}; + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); + return DeviceBuffer{}; } -GpuEventSynchronizer* StatePropagatorDataGpu::getCoordinatesReadyOnDeviceEvent(AtomLocality /* atomLocality */, - const SimulationWorkload & /* simulationWork */, - const StepWorkload & /* stepWork */) +GpuEventSynchronizer* StatePropagatorDataGpu::getCoordinatesReadyOnDeviceEvent( + AtomLocality /* atomLocality */, + const SimulationWorkload& /* simulationWork */, + const StepWorkload& /* stepWork */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } -void StatePropagatorDataGpu::waitCoordinatesCopiedToDevice(AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::waitCoordinatesCopiedToDevice(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } GpuEventSynchronizer* StatePropagatorDataGpu::xUpdatedOnDevice() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } -void StatePropagatorDataGpu::copyCoordinatesToGpu(const gmx::ArrayRef /* h_x */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyCoordinatesToGpu(const gmx::ArrayRef /* h_x */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -void StatePropagatorDataGpu::waitCoordinatesReadyOnHost(AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::waitCoordinatesReadyOnHost(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -void StatePropagatorDataGpu::copyCoordinatesFromGpu(gmx::ArrayRef /* h_x */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyCoordinatesFromGpu(gmx::ArrayRef /* h_x */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } DeviceBuffer StatePropagatorDataGpu::getVelocities() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); - return DeviceBuffer {}; + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); + return DeviceBuffer{}; } -void StatePropagatorDataGpu::copyVelocitiesToGpu(const gmx::ArrayRef /* h_v */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyVelocitiesToGpu(const gmx::ArrayRef /* h_v */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -GpuEventSynchronizer* StatePropagatorDataGpu::getVelocitiesReadyOnDeviceEvent(AtomLocality /* atomLocality */) +GpuEventSynchronizer* StatePropagatorDataGpu::getVelocitiesReadyOnDeviceEvent(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } -void StatePropagatorDataGpu::copyVelocitiesFromGpu(gmx::ArrayRef /* h_v */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyVelocitiesFromGpu(gmx::ArrayRef /* h_v */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -void StatePropagatorDataGpu::waitVelocitiesReadyOnHost(AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::waitVelocitiesReadyOnHost(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } DeviceBuffer StatePropagatorDataGpu::getForces() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); - return DeviceBuffer {}; + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); + return DeviceBuffer{}; } -void StatePropagatorDataGpu::copyForcesToGpu(const gmx::ArrayRef /* h_f */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyForcesToGpu(const gmx::ArrayRef /* h_f */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -GpuEventSynchronizer* StatePropagatorDataGpu::getForcesReadyOnDeviceEvent(AtomLocality /* atomLocality */, - bool /* useGpuFBufferOps */) +GpuEventSynchronizer* StatePropagatorDataGpu::getForcesReadyOnDeviceEvent(AtomLocality /* atomLocality */, + bool /* useGpuFBufferOps */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } GpuEventSynchronizer* StatePropagatorDataGpu::fReducedOnDevice() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } -void StatePropagatorDataGpu::copyForcesFromGpu(gmx::ArrayRef /* h_f */, - AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::copyForcesFromGpu(gmx::ArrayRef /* h_f */, + AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } -void StatePropagatorDataGpu::waitForcesReadyOnHost(AtomLocality /* atomLocality */) +void StatePropagatorDataGpu::waitForcesReadyOnHost(AtomLocality /* atomLocality */) { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); } void* StatePropagatorDataGpu::getUpdateStream() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return nullptr; } int StatePropagatorDataGpu::numAtomsLocal() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return 0; } int StatePropagatorDataGpu::numAtomsAll() { - GMX_ASSERT(false, "A CPU stub method from GPU state propagator data was called instead of one from GPU implementation."); + GMX_ASSERT(false, + "A CPU stub method from GPU state propagator data was called instead of one from " + "GPU implementation."); return 0; } -} // namespace gmx +} // namespace gmx #endif // GMX_GPU == GMX_GPU_NONE diff --git a/src/gromacs/mdtypes/state_propagator_data_gpu_impl.h b/src/gromacs/mdtypes/state_propagator_data_gpu_impl.h index 2b1db0d791..70365ac62e 100644 --- a/src/gromacs/mdtypes/state_propagator_data_gpu_impl.h +++ b/src/gromacs/mdtypes/state_propagator_data_gpu_impl.h @@ -49,9 +49,9 @@ #include "gromacs/gpu_utils/devicebuffer.h" #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/gpueventsynchronizer.cuh" +# include "gromacs/gpu_utils/gpueventsynchronizer.cuh" #elif GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gpueventsynchronizer_ocl.h" +# include "gromacs/gpu_utils/gpueventsynchronizer_ocl.h" #endif #include "gromacs/math/vectypes.h" #include "gromacs/mdtypes/state_propagator_data_gpu.h" @@ -63,386 +63,374 @@ namespace gmx class StatePropagatorDataGpu::Impl { - public: - - Impl(); - - - /*! \brief Constructor - * - * The buffers are reallocated only at the reinit call, the padding is - * used there for the coordinates buffer. It is needed for PME and added at - * the end of the buffer. It is assumed that if the rank has PME duties on the - * GPU, all coordinates are copied to the GPU and hence, for this rank, the - * coordinates buffer is not split into local and non-local ranges. For other - * ranks, the padding size is zero. This works because only one rank ever does - * PME work on the GPU, and if that rank also does PP work that is the only - * rank. So all coordinates are always transferred. - * - * In OpenCL, only pmeStream is used since it is the only stream created in - * PME context. The local and non-local streams are only needed when buffer - * ops are offloaded. This feature is currently not available in OpenCL and - * hence these streams are not set in these builds. - * - * \note In CUDA, the update stream is created in the constructor as a temporary - * solution, in place until the stream manager is introduced. - * Note that this makes it impossible to construct this object in CUDA - * builds executing on a host without any CUDA-capable device available. - * - * \note In CUDA, \p deviceContext is unused, hence always nullptr; - * all stream arguments can also be nullptr in runs where the - * respective streams are not required. - * In OpenCL, \p deviceContext needs to be a valid device context. - * In OpenCL runs StatePropagatorDataGpu is currently only used - * with PME offload, and only on ranks with PME duty. Hence, the - * \p pmeStream argument needs to be a valid OpenCL queue object - * which must have been created in \p deviceContext. - * - * \todo Make a \p CommandStream visible in the CPU parts of the code so we - * will not have to pass a void*. - * \todo Make a \p DeviceContext object visible in CPU parts of the code so we - * will not have to pass a void*. - * - * \param[in] pmeStream Device PME stream, nullptr allowed. - * \param[in] localStream Device NBNXM local stream, nullptr allowed. - * \param[in] nonLocalStream Device NBNXM non-local stream, nullptr allowed. - * \param[in] deviceContext Device context, nullptr allowed. - * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). - * \param[in] paddingSize Padding size for coordinates buffer. - */ - Impl(const void *pmeStream, - const void *localStream, - const void *nonLocalStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize); - - /*! \brief Constructor to use in PME-only rank and in tests. - * - * This constructor should be used if only a coordinate device buffer should be managed - * using a single stream. Any operation on force or velocity buffer as well as copy of - * non-local coordinates will exit with assertion failure. Note, that the pmeStream can - * not be a nullptr and the constructor will exit with an assertion failure. - * - * \todo Currently, unsupported copy operations are blocked by assertion that the stream - * not nullptr. This should be improved. - * - * \param[in] pmeStream Device PME stream, nullptr is not allowed. - * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds. - * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). - * \param[in] paddingSize Padding size for coordinates buffer. - */ - Impl(const void *pmeStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize); - - ~Impl(); - - - /*! \brief Set the ranges for local and non-local atoms and reallocates buffers. - * - * \note - * The coordinates buffer is (re)allocated, when required by PME, with a padding, - * the size of which is set by the constructor. The padding region clearing kernel - * is scheduled in the \p pmeStream_ (unlike the coordinates H2D) as only the PME - * task uses this padding area. - * - * \param[in] numAtomsLocal Number of atoms in local domain. - * \param[in] numAtomsAll Total number of atoms to handle. - */ - void reinit(int numAtomsLocal, int numAtomsAll); - - /*! \brief Returns the range of atoms to be copied based on the copy type (all, local or non-local). - * - * \todo There are at least three versions of the function with this functionality in the code: - * this one and two more in NBNXM. These should be unified in a shape of a general function - * in DD. - * - * \param[in] atomLocality If all, local or non-local ranges are needed. - * - * \returns Tuple, containing the index of the first atom in the range and the total number of atoms in the range. - */ - std::tuple getAtomRangesFromAtomLocality(AtomLocality atomLocality); - - - /*! \brief Get the positions buffer on the GPU. - * - * \returns GPU positions buffer. - */ - DeviceBuffer getCoordinates(); - - /*! \brief Copy positions to the GPU memory. - * - * \param[in] h_x Positions in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyCoordinatesToGpu(gmx::ArrayRef h_x, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer of the coordinates ready for the consumption on the device. - * - * Returns the event synchronizer which indicates that the coordinates are ready for the - * consumption on the device. Takes into account that the producer may be different. - * - * If the update is offloaded, and the current step is not a DD/search step, the returned - * synchronizer indicates the completion of GPU update-constraint kernels. Otherwise, on search - * steps and if update is not offloaded, the coordinates are provided by the H2D copy and the - * returned synchronizer indicates that the copy is complete. - * - * \param[in] atomLocality Locality of the particles to wait for. - * \param[in] simulationWork The simulation lifetime flags. - * \param[in] stepWork The step lifetime flags. - * - * \returns The event to synchronize the stream that consumes coordinates on device. - */ - GpuEventSynchronizer* getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, - const SimulationWorkload &simulationWork, - const StepWorkload &stepWork); - - /*! \brief Blocking wait until coordinates are copied to the device. - * - * Synchronizes the stream in which the copy was executed. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitCoordinatesCopiedToDevice(AtomLocality atomLocality); - - /*! \brief Getter for the event synchronizer for the update is done on th GPU - * - * \returns The event to synchronize the stream coordinates wre updated on device. - */ - GpuEventSynchronizer* xUpdatedOnDevice(); - - /*! \brief Copy positions from the GPU memory. - * - * \param[in] h_x Positions buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyCoordinatesFromGpu(gmx::ArrayRef h_x, - AtomLocality atomLocality); - - /*! \brief Wait until coordinates are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitCoordinatesReadyOnHost(AtomLocality atomLocality); - - - /*! \brief Get the velocities buffer on the GPU. - * - * \returns GPU velocities buffer. - */ - DeviceBuffer getVelocities(); - - /*! \brief Copy velocities to the GPU memory. - * - * \param[in] h_v Velocities in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyVelocitiesToGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer on the H2D velocities copy. - * - * \param[in] atomLocality Locality of the particles to wait for. - * - * \returns The event to synchronize the stream that consumes velocities on device. - */ - GpuEventSynchronizer* getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality); - - /*! \brief Copy velocities from the GPU memory. - * - * \param[in] h_v Velocities buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyVelocitiesFromGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality); - - /*! \brief Wait until velocities are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitVelocitiesReadyOnHost(AtomLocality atomLocality); - - - /*! \brief Get the force buffer on the GPU. - * - * \returns GPU force buffer. - */ - DeviceBuffer getForces(); - - /*! \brief Copy forces to the GPU memory. - * - * \param[in] h_f Forces in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyForcesToGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality); - - /*! \brief Get the event synchronizer for the forces ready on device. - * - * Returns either of the event synchronizers, depending on the offload scenario - * for the current simulation timestep: - * 1. The forces are copied to the device (when GPU buffer ops are off) - * 2. The forces are reduced on the device (GPU buffer ops are on) - * - * \todo Pass step workload instead of the useGpuFBufferOps boolean. - * - * \param[in] atomLocality Locality of the particles to wait for. - * \param[in] useGpuFBufferOps If the force buffer ops are offloaded to the GPU. - * - * \returns The event to synchronize the stream that consumes forces on device. - */ - GpuEventSynchronizer* getForcesReadyOnDeviceEvent(AtomLocality atomLocality, - bool useGpuFBufferOps); - - /*! \brief Getter for the event synchronizer for the forces are reduced on the GPU. - * - * \returns The event to mark when forces are reduced on the GPU. - */ - GpuEventSynchronizer* fReducedOnDevice(); - - /*! \brief Copy forces from the GPU memory. - * - * \param[in] h_f Forces buffer in the host memory. - * \param[in] atomLocality Locality of the particles to copy. - */ - void copyForcesFromGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality); - - /*! \brief Wait until forces are available on the host. - * - * \param[in] atomLocality Locality of the particles to wait for. - */ - void waitForcesReadyOnHost(AtomLocality atomLocality); - - /*! \brief Getter for the update stream. - * - * \todo This is temporary here, until the management of this stream is taken over. - * - * \returns The device command stream to use in update-constraints. - */ - void* getUpdateStream(); - - /*! \brief Getter for the number of local atoms. - * - * \returns The number of local atoms. - */ - int numAtomsLocal(); - - /*! \brief Getter for the total number of atoms. - * - * \returns The total number of atoms. - */ - int numAtomsAll(); - - private: - - //! GPU PME stream. - CommandStream pmeStream_ = nullptr; - //! GPU NBNXM local stream. - CommandStream localStream_ = nullptr; - //! GPU NBNXM non-local stream - CommandStream nonLocalStream_ = nullptr; - //! GPU Update-constreaints stream. - CommandStream updateStream_ = nullptr; - - // Streams to use for coordinates H2D and D2H copies (one event for each atom locality) - EnumerationArray xCopyStreams_ = {{nullptr}}; - // Streams to use for velocities H2D and D2H copies (one event for each atom locality) - EnumerationArray vCopyStreams_ = {{nullptr}}; - // Streams to use for forces H2D and D2H copies (one event for each atom locality) - EnumerationArray fCopyStreams_ = {{nullptr}}; - - /*! \brief An array of events that indicate H2D copy is complete (one event for each atom locality) - * - * \todo Reconsider naming. It should be xCopiedToDevice or xH2DCopyComplete, etc. - */ - EnumerationArray xReadyOnDevice_; - //! An event that the coordinates are ready after update-constraints execution - GpuEventSynchronizer xUpdatedOnDevice_; - //! An array of events that indicate D2H copy of coordinates is complete (one event for each atom locality) - EnumerationArray xReadyOnHost_; - - //! An array of events that indicate H2D copy of velocities is complete (one event for each atom locality) - EnumerationArray vReadyOnDevice_; - //! An array of events that indicate D2H copy of velocities is complete (one event for each atom locality) - EnumerationArray vReadyOnHost_; - - //! An array of events that indicate H2D copy of forces is complete (one event for each atom locality) - EnumerationArray fReadyOnDevice_; - //! An event that the forces were reduced on the GPU - GpuEventSynchronizer fReducedOnDevice_; - //! An array of events that indicate D2H copy of forces is complete (one event for each atom locality) - EnumerationArray fReadyOnHost_; - - /*! \brief GPU context (for OpenCL builds) - * \todo Make a Context class usable in CPU code - */ - DeviceContext deviceContext_ = nullptr; - //! Default GPU calls behavior - GpuApiCallBehavior transferKind_ = GpuApiCallBehavior::Async; - //! Padding size for the coordinates buffer - int paddingSize_ = 0; - - //! Number of local atoms - int numAtomsLocal_ = -1; - //! Total number of atoms - int numAtomsAll_ = -1; - - //! Device positions buffer - DeviceBuffer d_x_; - //! Number of particles saved in the positions buffer - int d_xSize_ = -1; - //! Allocation size for the positions buffer - int d_xCapacity_ = -1; - - //! Device velocities buffer - DeviceBuffer d_v_; - //! Number of particles saved in the velocities buffer - int d_vSize_ = -1; - //! Allocation size for the velocities buffer - int d_vCapacity_ = -1; - - //! Device force buffer - DeviceBuffer d_f_; - //! Number of particles saved in the force buffer - int d_fSize_ = -1; - //! Allocation size for the force buffer - int d_fCapacity_ = -1; - - /*! \brief Performs the copy of data from host to device buffer. - * - * \todo Template on locality. - * - * \param[out] d_data Device-side buffer. - * \param[in] h_data Host-side buffer. - * \param[in] dataSize Device-side data allocation size. - * \param[in] atomLocality If all, local or non-local ranges should be copied. - * \param[in] commandStream GPU stream to execute copy in. - */ - void copyToDevice(DeviceBuffer d_data, - gmx::ArrayRef h_data, - int dataSize, - AtomLocality atomLocality, - CommandStream commandStream); - - /*! \brief Performs the copy of data from device to host buffer. - * - * \param[out] h_data Host-side buffer. - * \param[in] d_data Device-side buffer. - * \param[in] dataSize Device-side data allocation size. - * \param[in] atomLocality If all, local or non-local ranges should be copied. - * \param[in] commandStream GPU stream to execute copy in. - */ - void copyFromDevice(gmx::ArrayRef h_data, - DeviceBuffer d_data, - int dataSize, - AtomLocality atomLocality, - CommandStream commandStream); +public: + Impl(); + + + /*! \brief Constructor + * + * The buffers are reallocated only at the reinit call, the padding is + * used there for the coordinates buffer. It is needed for PME and added at + * the end of the buffer. It is assumed that if the rank has PME duties on the + * GPU, all coordinates are copied to the GPU and hence, for this rank, the + * coordinates buffer is not split into local and non-local ranges. For other + * ranks, the padding size is zero. This works because only one rank ever does + * PME work on the GPU, and if that rank also does PP work that is the only + * rank. So all coordinates are always transferred. + * + * In OpenCL, only pmeStream is used since it is the only stream created in + * PME context. The local and non-local streams are only needed when buffer + * ops are offloaded. This feature is currently not available in OpenCL and + * hence these streams are not set in these builds. + * + * \note In CUDA, the update stream is created in the constructor as a temporary + * solution, in place until the stream manager is introduced. + * Note that this makes it impossible to construct this object in CUDA + * builds executing on a host without any CUDA-capable device available. + * + * \note In CUDA, \p deviceContext is unused, hence always nullptr; + * all stream arguments can also be nullptr in runs where the + * respective streams are not required. + * In OpenCL, \p deviceContext needs to be a valid device context. + * In OpenCL runs StatePropagatorDataGpu is currently only used + * with PME offload, and only on ranks with PME duty. Hence, the + * \p pmeStream argument needs to be a valid OpenCL queue object + * which must have been created in \p deviceContext. + * + * \todo Make a \p CommandStream visible in the CPU parts of the code so we + * will not have to pass a void*. + * \todo Make a \p DeviceContext object visible in CPU parts of the code so we + * will not have to pass a void*. + * + * \param[in] pmeStream Device PME stream, nullptr allowed. + * \param[in] localStream Device NBNXM local stream, nullptr allowed. + * \param[in] nonLocalStream Device NBNXM non-local stream, nullptr allowed. + * \param[in] deviceContext Device context, nullptr allowed. + * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). + * \param[in] paddingSize Padding size for coordinates buffer. + */ + Impl(const void* pmeStream, + const void* localStream, + const void* nonLocalStream, + const void* deviceContext, + GpuApiCallBehavior transferKind, + int paddingSize); + + /*! \brief Constructor to use in PME-only rank and in tests. + * + * This constructor should be used if only a coordinate device buffer should be managed + * using a single stream. Any operation on force or velocity buffer as well as copy of + * non-local coordinates will exit with assertion failure. Note, that the pmeStream can + * not be a nullptr and the constructor will exit with an assertion failure. + * + * \todo Currently, unsupported copy operations are blocked by assertion that the stream + * not nullptr. This should be improved. + * + * \param[in] pmeStream Device PME stream, nullptr is not allowed. + * \param[in] deviceContext Device context, nullptr allowed for non-OpenCL builds. + * \param[in] transferKind H2D/D2H transfer call behavior (synchronous or not). + * \param[in] paddingSize Padding size for coordinates buffer. + */ + Impl(const void* pmeStream, const void* deviceContext, GpuApiCallBehavior transferKind, int paddingSize); + + ~Impl(); + + + /*! \brief Set the ranges for local and non-local atoms and reallocates buffers. + * + * \note + * The coordinates buffer is (re)allocated, when required by PME, with a padding, + * the size of which is set by the constructor. The padding region clearing kernel + * is scheduled in the \p pmeStream_ (unlike the coordinates H2D) as only the PME + * task uses this padding area. + * + * \param[in] numAtomsLocal Number of atoms in local domain. + * \param[in] numAtomsAll Total number of atoms to handle. + */ + void reinit(int numAtomsLocal, int numAtomsAll); + + /*! \brief Returns the range of atoms to be copied based on the copy type (all, local or non-local). + * + * \todo There are at least three versions of the function with this functionality in the code: + * this one and two more in NBNXM. These should be unified in a shape of a general function + * in DD. + * + * \param[in] atomLocality If all, local or non-local ranges are needed. + * + * \returns Tuple, containing the index of the first atom in the range and the total number of atoms in the range. + */ + std::tuple getAtomRangesFromAtomLocality(AtomLocality atomLocality); + + + /*! \brief Get the positions buffer on the GPU. + * + * \returns GPU positions buffer. + */ + DeviceBuffer getCoordinates(); + + /*! \brief Copy positions to the GPU memory. + * + * \param[in] h_x Positions in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyCoordinatesToGpu(gmx::ArrayRef h_x, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer of the coordinates ready for the consumption on the device. + * + * Returns the event synchronizer which indicates that the coordinates are ready for the + * consumption on the device. Takes into account that the producer may be different. + * + * If the update is offloaded, and the current step is not a DD/search step, the returned + * synchronizer indicates the completion of GPU update-constraint kernels. Otherwise, on search + * steps and if update is not offloaded, the coordinates are provided by the H2D copy and the + * returned synchronizer indicates that the copy is complete. + * + * \param[in] atomLocality Locality of the particles to wait for. + * \param[in] simulationWork The simulation lifetime flags. + * \param[in] stepWork The step lifetime flags. + * + * \returns The event to synchronize the stream that consumes coordinates on device. + */ + GpuEventSynchronizer* getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, + const SimulationWorkload& simulationWork, + const StepWorkload& stepWork); + + /*! \brief Blocking wait until coordinates are copied to the device. + * + * Synchronizes the stream in which the copy was executed. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitCoordinatesCopiedToDevice(AtomLocality atomLocality); + + /*! \brief Getter for the event synchronizer for the update is done on th GPU + * + * \returns The event to synchronize the stream coordinates wre updated on device. + */ + GpuEventSynchronizer* xUpdatedOnDevice(); + + /*! \brief Copy positions from the GPU memory. + * + * \param[in] h_x Positions buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyCoordinatesFromGpu(gmx::ArrayRef h_x, AtomLocality atomLocality); + + /*! \brief Wait until coordinates are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitCoordinatesReadyOnHost(AtomLocality atomLocality); + + + /*! \brief Get the velocities buffer on the GPU. + * + * \returns GPU velocities buffer. + */ + DeviceBuffer getVelocities(); + + /*! \brief Copy velocities to the GPU memory. + * + * \param[in] h_v Velocities in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyVelocitiesToGpu(gmx::ArrayRef h_v, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer on the H2D velocities copy. + * + * \param[in] atomLocality Locality of the particles to wait for. + * + * \returns The event to synchronize the stream that consumes velocities on device. + */ + GpuEventSynchronizer* getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality); + + /*! \brief Copy velocities from the GPU memory. + * + * \param[in] h_v Velocities buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyVelocitiesFromGpu(gmx::ArrayRef h_v, AtomLocality atomLocality); + + /*! \brief Wait until velocities are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitVelocitiesReadyOnHost(AtomLocality atomLocality); + + + /*! \brief Get the force buffer on the GPU. + * + * \returns GPU force buffer. + */ + DeviceBuffer getForces(); + + /*! \brief Copy forces to the GPU memory. + * + * \param[in] h_f Forces in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyForcesToGpu(gmx::ArrayRef h_f, AtomLocality atomLocality); + + /*! \brief Get the event synchronizer for the forces ready on device. + * + * Returns either of the event synchronizers, depending on the offload scenario + * for the current simulation timestep: + * 1. The forces are copied to the device (when GPU buffer ops are off) + * 2. The forces are reduced on the device (GPU buffer ops are on) + * + * \todo Pass step workload instead of the useGpuFBufferOps boolean. + * + * \param[in] atomLocality Locality of the particles to wait for. + * \param[in] useGpuFBufferOps If the force buffer ops are offloaded to the GPU. + * + * \returns The event to synchronize the stream that consumes forces on device. + */ + GpuEventSynchronizer* getForcesReadyOnDeviceEvent(AtomLocality atomLocality, bool useGpuFBufferOps); + + /*! \brief Getter for the event synchronizer for the forces are reduced on the GPU. + * + * \returns The event to mark when forces are reduced on the GPU. + */ + GpuEventSynchronizer* fReducedOnDevice(); + + /*! \brief Copy forces from the GPU memory. + * + * \param[in] h_f Forces buffer in the host memory. + * \param[in] atomLocality Locality of the particles to copy. + */ + void copyForcesFromGpu(gmx::ArrayRef h_f, AtomLocality atomLocality); + + /*! \brief Wait until forces are available on the host. + * + * \param[in] atomLocality Locality of the particles to wait for. + */ + void waitForcesReadyOnHost(AtomLocality atomLocality); + + /*! \brief Getter for the update stream. + * + * \todo This is temporary here, until the management of this stream is taken over. + * + * \returns The device command stream to use in update-constraints. + */ + void* getUpdateStream(); + + /*! \brief Getter for the number of local atoms. + * + * \returns The number of local atoms. + */ + int numAtomsLocal(); + + /*! \brief Getter for the total number of atoms. + * + * \returns The total number of atoms. + */ + int numAtomsAll(); + +private: + //! GPU PME stream. + CommandStream pmeStream_ = nullptr; + //! GPU NBNXM local stream. + CommandStream localStream_ = nullptr; + //! GPU NBNXM non-local stream + CommandStream nonLocalStream_ = nullptr; + //! GPU Update-constreaints stream. + CommandStream updateStream_ = nullptr; + + // Streams to use for coordinates H2D and D2H copies (one event for each atom locality) + EnumerationArray xCopyStreams_ = { { nullptr } }; + // Streams to use for velocities H2D and D2H copies (one event for each atom locality) + EnumerationArray vCopyStreams_ = { { nullptr } }; + // Streams to use for forces H2D and D2H copies (one event for each atom locality) + EnumerationArray fCopyStreams_ = { { nullptr } }; + + /*! \brief An array of events that indicate H2D copy is complete (one event for each atom locality) + * + * \todo Reconsider naming. It should be xCopiedToDevice or xH2DCopyComplete, etc. + */ + EnumerationArray xReadyOnDevice_; + //! An event that the coordinates are ready after update-constraints execution + GpuEventSynchronizer xUpdatedOnDevice_; + //! An array of events that indicate D2H copy of coordinates is complete (one event for each atom locality) + EnumerationArray xReadyOnHost_; + + //! An array of events that indicate H2D copy of velocities is complete (one event for each atom locality) + EnumerationArray vReadyOnDevice_; + //! An array of events that indicate D2H copy of velocities is complete (one event for each atom locality) + EnumerationArray vReadyOnHost_; + + //! An array of events that indicate H2D copy of forces is complete (one event for each atom locality) + EnumerationArray fReadyOnDevice_; + //! An event that the forces were reduced on the GPU + GpuEventSynchronizer fReducedOnDevice_; + //! An array of events that indicate D2H copy of forces is complete (one event for each atom locality) + EnumerationArray fReadyOnHost_; + + /*! \brief GPU context (for OpenCL builds) + * \todo Make a Context class usable in CPU code + */ + DeviceContext deviceContext_ = nullptr; + //! Default GPU calls behavior + GpuApiCallBehavior transferKind_ = GpuApiCallBehavior::Async; + //! Padding size for the coordinates buffer + int paddingSize_ = 0; + + //! Number of local atoms + int numAtomsLocal_ = -1; + //! Total number of atoms + int numAtomsAll_ = -1; + + //! Device positions buffer + DeviceBuffer d_x_; + //! Number of particles saved in the positions buffer + int d_xSize_ = -1; + //! Allocation size for the positions buffer + int d_xCapacity_ = -1; + + //! Device velocities buffer + DeviceBuffer d_v_; + //! Number of particles saved in the velocities buffer + int d_vSize_ = -1; + //! Allocation size for the velocities buffer + int d_vCapacity_ = -1; + + //! Device force buffer + DeviceBuffer d_f_; + //! Number of particles saved in the force buffer + int d_fSize_ = -1; + //! Allocation size for the force buffer + int d_fCapacity_ = -1; + + /*! \brief Performs the copy of data from host to device buffer. + * + * \todo Template on locality. + * + * \param[out] d_data Device-side buffer. + * \param[in] h_data Host-side buffer. + * \param[in] dataSize Device-side data allocation size. + * \param[in] atomLocality If all, local or non-local ranges should be copied. + * \param[in] commandStream GPU stream to execute copy in. + */ + void copyToDevice(DeviceBuffer d_data, + gmx::ArrayRef h_data, + int dataSize, + AtomLocality atomLocality, + CommandStream commandStream); + + /*! \brief Performs the copy of data from device to host buffer. + * + * \param[out] h_data Host-side buffer. + * \param[in] d_data Device-side buffer. + * \param[in] dataSize Device-side data allocation size. + * \param[in] atomLocality If all, local or non-local ranges should be copied. + * \param[in] commandStream GPU stream to execute copy in. + */ + void copyFromDevice(gmx::ArrayRef h_data, + DeviceBuffer d_data, + int dataSize, + AtomLocality atomLocality, + CommandStream commandStream); }; -} // namespace gmx +} // namespace gmx #endif // GMX_MDTYPES_STATE_PROPAGATOR_DATA_GPU_IMPL_H diff --git a/src/gromacs/mdtypes/state_propagator_data_gpu_impl_gpu.cpp b/src/gromacs/mdtypes/state_propagator_data_gpu_impl_gpu.cpp index dacda5fed1..2a8a394bda 100644 --- a/src/gromacs/mdtypes/state_propagator_data_gpu_impl_gpu.cpp +++ b/src/gromacs/mdtypes/state_propagator_data_gpu_impl_gpu.cpp @@ -46,32 +46,33 @@ #if GMX_GPU != GMX_GPU_NONE -#if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/cudautils.cuh" -#endif -#include "gromacs/gpu_utils/devicebuffer.h" -#if GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/oclutils.h" -#endif -#include "gromacs/math/vectypes.h" -#include "gromacs/mdtypes/state_propagator_data_gpu.h" -#include "gromacs/utility/classhelpers.h" - -#include "state_propagator_data_gpu_impl.h" +# if GMX_GPU == GMX_GPU_CUDA +# include "gromacs/gpu_utils/cudautils.cuh" +# endif +# include "gromacs/gpu_utils/devicebuffer.h" +# if GMX_GPU == GMX_GPU_OPENCL +# include "gromacs/gpu_utils/oclutils.h" +# endif +# include "gromacs/math/vectypes.h" +# include "gromacs/mdtypes/state_propagator_data_gpu.h" +# include "gromacs/utility/classhelpers.h" + +# include "state_propagator_data_gpu_impl.h" namespace gmx { -StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, - const void *localStream, - const void *nonLocalStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize) : +StatePropagatorDataGpu::Impl::Impl(const void* pmeStream, + const void* localStream, + const void* nonLocalStream, + const void* deviceContext, + GpuApiCallBehavior transferKind, + int paddingSize) : transferKind_(transferKind), paddingSize_(paddingSize) { - static_assert(GMX_GPU != GMX_GPU_NONE, "This object should only be constructed on the GPU code-paths."); + static_assert(GMX_GPU != GMX_GPU_NONE, + "This object should only be constructed on the GPU code-paths."); // TODO: Refactor when the StreamManager is introduced. if (GMX_GPU == GMX_GPU_OPENCL) @@ -80,9 +81,9 @@ StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, GMX_ASSERT(pmeStream != nullptr, "GPU PME stream should be set in OpenCL builds."); // The update stream is set to the PME stream in OpenCL, since PME stream is the only stream created in the PME context. - pmeStream_ = *static_cast(pmeStream); - updateStream_ = *static_cast(pmeStream); - deviceContext_ = *static_cast(deviceContext); + pmeStream_ = *static_cast(pmeStream); + updateStream_ = *static_cast(pmeStream); + deviceContext_ = *static_cast(deviceContext); GMX_UNUSED_VALUE(localStream); GMX_UNUSED_VALUE(nonLocalStream); } @@ -103,11 +104,11 @@ StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, } // TODO: The update stream should be created only when it is needed. -#if (GMX_GPU == GMX_GPU_CUDA) +# if (GMX_GPU == GMX_GPU_CUDA) cudaError_t stat; stat = cudaStreamCreate(&updateStream_); CU_RET_ERR(stat, "CUDA stream creation failed in StatePropagatorDataGpu"); -#endif +# endif GMX_UNUSED_VALUE(deviceContext); } @@ -127,23 +128,24 @@ StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, fCopyStreams_[AtomLocality::All] = updateStream_; } -StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, - const void *deviceContext, - GpuApiCallBehavior transferKind, - int paddingSize) : +StatePropagatorDataGpu::Impl::Impl(const void* pmeStream, + const void* deviceContext, + GpuApiCallBehavior transferKind, + int paddingSize) : transferKind_(transferKind), paddingSize_(paddingSize) { - static_assert(GMX_GPU != GMX_GPU_NONE, "This object should only be constructed on the GPU code-paths."); + static_assert(GMX_GPU != GMX_GPU_NONE, + "This object should only be constructed on the GPU code-paths."); if (GMX_GPU == GMX_GPU_OPENCL) { GMX_ASSERT(deviceContext != nullptr, "GPU context should be set in OpenCL builds."); - deviceContext_ = *static_cast(deviceContext); + deviceContext_ = *static_cast(deviceContext); } GMX_ASSERT(pmeStream != nullptr, "GPU PME stream should be set."); - pmeStream_ = *static_cast(pmeStream); + pmeStream_ = *static_cast(pmeStream); localStream_ = nullptr; nonLocalStream_ = nullptr; @@ -165,9 +167,7 @@ StatePropagatorDataGpu::Impl::Impl(const void *pmeStream, fCopyStreams_[AtomLocality::All] = nullptr; } -StatePropagatorDataGpu::Impl::~Impl() -{ -} +StatePropagatorDataGpu::Impl::~Impl() {} void StatePropagatorDataGpu::Impl::reinit(int numAtomsLocal, int numAtomsAll) { @@ -177,58 +177,63 @@ void StatePropagatorDataGpu::Impl::reinit(int numAtomsLocal, int numAtomsAll) int numAtomsPadded; if (paddingSize_ > 0) { - numAtomsPadded = ((numAtomsAll_ + paddingSize_ - 1 ) / paddingSize_ )*paddingSize_; + numAtomsPadded = ((numAtomsAll_ + paddingSize_ - 1) / paddingSize_) * paddingSize_; } else { numAtomsPadded = numAtomsAll_; } - reallocateDeviceBuffer(&d_x_, DIM*numAtomsPadded, &d_xSize_, &d_xCapacity_, deviceContext_); + reallocateDeviceBuffer(&d_x_, DIM * numAtomsPadded, &d_xSize_, &d_xCapacity_, deviceContext_); const size_t paddingAllocationSize = numAtomsPadded - numAtomsAll_; if (paddingAllocationSize > 0) { // The PME stream is used here because the padding region of d_x_ is only in the PME task. - clearDeviceBufferAsync(&d_x_, DIM*numAtomsAll_, DIM*paddingAllocationSize, pmeStream_); + clearDeviceBufferAsync(&d_x_, DIM * numAtomsAll_, DIM * paddingAllocationSize, pmeStream_); } - reallocateDeviceBuffer(&d_v_, DIM*numAtomsAll_, &d_vSize_, &d_vCapacity_, deviceContext_); - reallocateDeviceBuffer(&d_f_, DIM*numAtomsAll_, &d_fSize_, &d_fCapacity_, deviceContext_); - + reallocateDeviceBuffer(&d_v_, DIM * numAtomsAll_, &d_vSize_, &d_vCapacity_, deviceContext_); + reallocateDeviceBuffer(&d_f_, DIM * numAtomsAll_, &d_fSize_, &d_fCapacity_, deviceContext_); } -std::tuple StatePropagatorDataGpu::Impl::getAtomRangesFromAtomLocality(AtomLocality atomLocality) +std::tuple StatePropagatorDataGpu::Impl::getAtomRangesFromAtomLocality(AtomLocality atomLocality) { int atomsStartAt = 0; int numAtomsToCopy = 0; switch (atomLocality) { case AtomLocality::All: - atomsStartAt = 0; - numAtomsToCopy = numAtomsAll_; + atomsStartAt = 0; + numAtomsToCopy = numAtomsAll_; break; case AtomLocality::Local: - atomsStartAt = 0; - numAtomsToCopy = numAtomsLocal_; + atomsStartAt = 0; + numAtomsToCopy = numAtomsLocal_; break; case AtomLocality::NonLocal: - atomsStartAt = numAtomsLocal_; - numAtomsToCopy = numAtomsAll_ - numAtomsLocal_; + atomsStartAt = numAtomsLocal_; + numAtomsToCopy = numAtomsAll_ - numAtomsLocal_; break; default: - GMX_RELEASE_ASSERT(false, "Wrong range of atoms requested in GPU state data manager. Should be All, Local or NonLocal."); + GMX_RELEASE_ASSERT(false, + "Wrong range of atoms requested in GPU state data manager. Should " + "be All, Local or NonLocal."); } - GMX_ASSERT(atomsStartAt >= 0, "The first elemtnt to copy has negative index. Probably, the GPU propagator state was not initialized."); - GMX_ASSERT(numAtomsToCopy >= 0, "Number of atoms to copy is negative. Probably, the GPU propagator state was not initialized."); + GMX_ASSERT(atomsStartAt >= 0, + "The first elemtnt to copy has negative index. Probably, the GPU propagator state " + "was not initialized."); + GMX_ASSERT(numAtomsToCopy >= 0, + "Number of atoms to copy is negative. Probably, the GPU propagator state was not " + "initialized."); return std::make_tuple(atomsStartAt, numAtomsToCopy); } -void StatePropagatorDataGpu::Impl::copyToDevice(DeviceBuffer d_data, - const gmx::ArrayRef h_data, - int dataSize, - AtomLocality atomLocality, - CommandStream commandStream) +void StatePropagatorDataGpu::Impl::copyToDevice(DeviceBuffer d_data, + const gmx::ArrayRef h_data, + int dataSize, + AtomLocality atomLocality, + CommandStream commandStream) { GMX_UNUSED_VALUE(dataSize); @@ -238,25 +243,26 @@ void StatePropagatorDataGpu::Impl::copyToDevice(DeviceBuffer int atomsStartAt, numAtomsToCopy; std::tie(atomsStartAt, numAtomsToCopy) = getAtomRangesFromAtomLocality(atomLocality); - int elementsStartAt = atomsStartAt*DIM; - int numElementsToCopy = numAtomsToCopy*DIM; + int elementsStartAt = atomsStartAt * DIM; + int numElementsToCopy = numAtomsToCopy * DIM; if (numAtomsToCopy != 0) { - GMX_ASSERT(elementsStartAt + numElementsToCopy <= dataSize, "The device allocation is smaller than requested copy range."); - GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(), "The host buffer is smaller than the requested copy range."); + GMX_ASSERT(elementsStartAt + numElementsToCopy <= dataSize, + "The device allocation is smaller than requested copy range."); + GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(), + "The host buffer is smaller than the requested copy range."); - copyToDeviceBuffer(&d_data, reinterpret_cast(&h_data.data()[atomsStartAt]), - elementsStartAt, numElementsToCopy, - commandStream, transferKind_, nullptr); + copyToDeviceBuffer(&d_data, reinterpret_cast(&h_data.data()[atomsStartAt]), + elementsStartAt, numElementsToCopy, commandStream, transferKind_, nullptr); } } -void StatePropagatorDataGpu::Impl::copyFromDevice(gmx::ArrayRef h_data, - DeviceBuffer d_data, - int dataSize, - AtomLocality atomLocality, - CommandStream commandStream) +void StatePropagatorDataGpu::Impl::copyFromDevice(gmx::ArrayRef h_data, + DeviceBuffer d_data, + int dataSize, + AtomLocality atomLocality, + CommandStream commandStream) { GMX_UNUSED_VALUE(dataSize); @@ -266,17 +272,18 @@ void StatePropagatorDataGpu::Impl::copyFromDevice(gmx::ArrayRef h_da int atomsStartAt, numAtomsToCopy; std::tie(atomsStartAt, numAtomsToCopy) = getAtomRangesFromAtomLocality(atomLocality); - int elementsStartAt = atomsStartAt*DIM; - int numElementsToCopy = numAtomsToCopy*DIM; + int elementsStartAt = atomsStartAt * DIM; + int numElementsToCopy = numAtomsToCopy * DIM; if (numAtomsToCopy != 0) { - GMX_ASSERT(elementsStartAt + numElementsToCopy <= dataSize, "The device allocation is smaller than requested copy range."); - GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(), "The host buffer is smaller than the requested copy range."); + GMX_ASSERT(elementsStartAt + numElementsToCopy <= dataSize, + "The device allocation is smaller than requested copy range."); + GMX_ASSERT(atomsStartAt + numAtomsToCopy <= h_data.ssize(), + "The host buffer is smaller than the requested copy range."); copyFromDeviceBuffer(reinterpret_cast(&h_data.data()[atomsStartAt]), &d_data, - elementsStartAt, numElementsToCopy, - commandStream, transferKind_, nullptr); + elementsStartAt, numElementsToCopy, commandStream, transferKind_, nullptr); } } @@ -285,12 +292,13 @@ DeviceBuffer StatePropagatorDataGpu::Impl::getCoordinates() return d_x_; } -void StatePropagatorDataGpu::Impl::copyCoordinatesToGpu(const gmx::ArrayRef h_x, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyCoordinatesToGpu(const gmx::ArrayRef h_x, + AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = xCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying positions with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying positions with given atom locality."); copyToDevice(d_x_, h_x, d_xSize_, atomLocality, commandStream); @@ -304,9 +312,10 @@ void StatePropagatorDataGpu::Impl::copyCoordinatesToGpu(const gmx::ArrayRef h_x, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyCoordinatesFromGpu(gmx::ArrayRef h_x, AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = xCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying positions with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying positions with given atom locality."); copyFromDevice(h_x, d_x_, d_xSize_, atomLocality, commandStream); // Note: unlike copyCoordinatesToGpu this is not used in OpenCL, and the conditional is not needed. xReadyOnHost_[atomLocality].markEvent(commandStream); } -void StatePropagatorDataGpu::Impl::waitCoordinatesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::waitCoordinatesReadyOnHost(AtomLocality atomLocality) { xReadyOnHost_[atomLocality].waitForEvent(); } @@ -364,35 +373,36 @@ DeviceBuffer StatePropagatorDataGpu::Impl::getVelocities() return d_v_; } -void StatePropagatorDataGpu::Impl::copyVelocitiesToGpu(const gmx::ArrayRef h_v, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyVelocitiesToGpu(const gmx::ArrayRef h_v, + AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = vCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying velocities with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying velocities with given atom locality."); copyToDevice(d_v_, h_v, d_vSize_, atomLocality, commandStream); vReadyOnDevice_[atomLocality].markEvent(commandStream); } -GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality) +GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality) { return &vReadyOnDevice_[atomLocality]; } -void StatePropagatorDataGpu::Impl::copyVelocitiesFromGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyVelocitiesFromGpu(gmx::ArrayRef h_v, AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = vCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying velocities with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying velocities with given atom locality."); copyFromDevice(h_v, d_v_, d_vSize_, atomLocality, commandStream); vReadyOnHost_[atomLocality].markEvent(commandStream); } -void StatePropagatorDataGpu::Impl::waitVelocitiesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::waitVelocitiesReadyOnHost(AtomLocality atomLocality) { vReadyOnHost_[atomLocality].waitForEvent(); } @@ -403,19 +413,20 @@ DeviceBuffer StatePropagatorDataGpu::Impl::getForces() return d_f_; } -void StatePropagatorDataGpu::Impl::copyForcesToGpu(const gmx::ArrayRef h_f, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyForcesToGpu(const gmx::ArrayRef h_f, + AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = fCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying forces with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying forces with given atom locality."); copyToDevice(d_f_, h_f, d_fSize_, atomLocality, commandStream); fReadyOnDevice_[atomLocality].markEvent(commandStream); } -GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getForcesReadyOnDeviceEvent(AtomLocality atomLocality, - bool useGpuFBufferOps) +GpuEventSynchronizer* StatePropagatorDataGpu::Impl::getForcesReadyOnDeviceEvent(AtomLocality atomLocality, + bool useGpuFBufferOps) { if ((atomLocality == AtomLocality::Local || atomLocality == AtomLocality::NonLocal) && useGpuFBufferOps) { @@ -432,18 +443,18 @@ GpuEventSynchronizer* StatePropagatorDataGpu::Impl::fReducedOnDevice() return &fReducedOnDevice_; } -void StatePropagatorDataGpu::Impl::copyForcesFromGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::copyForcesFromGpu(gmx::ArrayRef h_f, AtomLocality atomLocality) { GMX_ASSERT(atomLocality < AtomLocality::Count, "Wrong atom locality."); CommandStream commandStream = fCopyStreams_[atomLocality]; - GMX_ASSERT(commandStream != nullptr, "No stream is valid for copying forces with given atom locality."); + GMX_ASSERT(commandStream != nullptr, + "No stream is valid for copying forces with given atom locality."); copyFromDevice(h_f, d_f_, d_fSize_, atomLocality, commandStream); fReadyOnHost_[atomLocality].markEvent(commandStream); } -void StatePropagatorDataGpu::Impl::waitForcesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::Impl::waitForcesReadyOnHost(AtomLocality atomLocality) { fReadyOnHost_[atomLocality].waitForEvent(); } @@ -464,36 +475,27 @@ int StatePropagatorDataGpu::Impl::numAtomsAll() } - -StatePropagatorDataGpu::StatePropagatorDataGpu(const void *pmeStream, - const void *localStream, - const void *nonLocalStream, - const void *deviceContext, +StatePropagatorDataGpu::StatePropagatorDataGpu(const void* pmeStream, + const void* localStream, + const void* nonLocalStream, + const void* deviceContext, GpuApiCallBehavior transferKind, - int paddingSize) - : impl_(new Impl(pmeStream, - localStream, - nonLocalStream, - deviceContext, - transferKind, - paddingSize)) + int paddingSize) : + impl_(new Impl(pmeStream, localStream, nonLocalStream, deviceContext, transferKind, paddingSize)) { } -StatePropagatorDataGpu::StatePropagatorDataGpu(const void *pmeStream, - const void *deviceContext, +StatePropagatorDataGpu::StatePropagatorDataGpu(const void* pmeStream, + const void* deviceContext, GpuApiCallBehavior transferKind, - int paddingSize) - : impl_(new Impl(pmeStream, - deviceContext, - transferKind, - paddingSize)) + int paddingSize) : + impl_(new Impl(pmeStream, deviceContext, transferKind, paddingSize)) { } -StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu && /* other */) noexcept = default; +StatePropagatorDataGpu::StatePropagatorDataGpu(StatePropagatorDataGpu&& /* other */) noexcept = default; -StatePropagatorDataGpu &StatePropagatorDataGpu::operator=(StatePropagatorDataGpu && /* other */) noexcept = default; +StatePropagatorDataGpu& StatePropagatorDataGpu::operator=(StatePropagatorDataGpu&& /* other */) noexcept = default; StatePropagatorDataGpu::~StatePropagatorDataGpu() = default; @@ -503,7 +505,7 @@ void StatePropagatorDataGpu::reinit(int numAtomsLocal, int numAtomsAll) return impl_->reinit(numAtomsLocal, numAtomsAll); } -std::tuple StatePropagatorDataGpu::getAtomRangesFromAtomLocality(AtomLocality atomLocality) +std::tuple StatePropagatorDataGpu::getAtomRangesFromAtomLocality(AtomLocality atomLocality) { return impl_->getAtomRangesFromAtomLocality(atomLocality); } @@ -514,20 +516,21 @@ DeviceBuffer StatePropagatorDataGpu::getCoordinates() return impl_->getCoordinates(); } -void StatePropagatorDataGpu::copyCoordinatesToGpu(const gmx::ArrayRef h_x, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyCoordinatesToGpu(const gmx::ArrayRef h_x, + AtomLocality atomLocality) { return impl_->copyCoordinatesToGpu(h_x, atomLocality); } -GpuEventSynchronizer* StatePropagatorDataGpu::getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, - const SimulationWorkload &simulationWork, - const StepWorkload &stepWork) +GpuEventSynchronizer* +StatePropagatorDataGpu::getCoordinatesReadyOnDeviceEvent(AtomLocality atomLocality, + const SimulationWorkload& simulationWork, + const StepWorkload& stepWork) { return impl_->getCoordinatesReadyOnDeviceEvent(atomLocality, simulationWork, stepWork); } -void StatePropagatorDataGpu::waitCoordinatesCopiedToDevice(AtomLocality atomLocality) +void StatePropagatorDataGpu::waitCoordinatesCopiedToDevice(AtomLocality atomLocality) { return impl_->waitCoordinatesCopiedToDevice(atomLocality); } @@ -537,13 +540,12 @@ GpuEventSynchronizer* StatePropagatorDataGpu::xUpdatedOnDevice() return impl_->xUpdatedOnDevice(); } -void StatePropagatorDataGpu::copyCoordinatesFromGpu(gmx::ArrayRef h_x, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyCoordinatesFromGpu(gmx::ArrayRef h_x, AtomLocality atomLocality) { return impl_->copyCoordinatesFromGpu(h_x, atomLocality); } -void StatePropagatorDataGpu::waitCoordinatesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::waitCoordinatesReadyOnHost(AtomLocality atomLocality) { return impl_->waitCoordinatesReadyOnHost(atomLocality); } @@ -554,24 +556,23 @@ DeviceBuffer StatePropagatorDataGpu::getVelocities() return impl_->getVelocities(); } -void StatePropagatorDataGpu::copyVelocitiesToGpu(const gmx::ArrayRef h_v, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyVelocitiesToGpu(const gmx::ArrayRef h_v, + AtomLocality atomLocality) { return impl_->copyVelocitiesToGpu(h_v, atomLocality); } -GpuEventSynchronizer* StatePropagatorDataGpu::getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality) +GpuEventSynchronizer* StatePropagatorDataGpu::getVelocitiesReadyOnDeviceEvent(AtomLocality atomLocality) { return impl_->getVelocitiesReadyOnDeviceEvent(atomLocality); } -void StatePropagatorDataGpu::copyVelocitiesFromGpu(gmx::ArrayRef h_v, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyVelocitiesFromGpu(gmx::ArrayRef h_v, AtomLocality atomLocality) { return impl_->copyVelocitiesFromGpu(h_v, atomLocality); } -void StatePropagatorDataGpu::waitVelocitiesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::waitVelocitiesReadyOnHost(AtomLocality atomLocality) { return impl_->waitVelocitiesReadyOnHost(atomLocality); } @@ -582,14 +583,13 @@ DeviceBuffer StatePropagatorDataGpu::getForces() return impl_->getForces(); } -void StatePropagatorDataGpu::copyForcesToGpu(const gmx::ArrayRef h_f, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyForcesToGpu(const gmx::ArrayRef h_f, AtomLocality atomLocality) { return impl_->copyForcesToGpu(h_f, atomLocality); } -GpuEventSynchronizer* StatePropagatorDataGpu::getForcesReadyOnDeviceEvent(AtomLocality atomLocality, - bool useGpuFBufferOps) +GpuEventSynchronizer* StatePropagatorDataGpu::getForcesReadyOnDeviceEvent(AtomLocality atomLocality, + bool useGpuFBufferOps) { return impl_->getForcesReadyOnDeviceEvent(atomLocality, useGpuFBufferOps); } @@ -599,13 +599,12 @@ GpuEventSynchronizer* StatePropagatorDataGpu::fReducedOnDevice() return impl_->fReducedOnDevice(); } -void StatePropagatorDataGpu::copyForcesFromGpu(gmx::ArrayRef h_f, - AtomLocality atomLocality) +void StatePropagatorDataGpu::copyForcesFromGpu(gmx::ArrayRef h_f, AtomLocality atomLocality) { return impl_->copyForcesFromGpu(h_f, atomLocality); } -void StatePropagatorDataGpu::waitForcesReadyOnHost(AtomLocality atomLocality) +void StatePropagatorDataGpu::waitForcesReadyOnHost(AtomLocality atomLocality) { return impl_->waitForcesReadyOnHost(atomLocality); } @@ -626,6 +625,6 @@ int StatePropagatorDataGpu::numAtomsAll() return impl_->numAtomsAll(); } -} // namespace gmx +} // namespace gmx #endif // GMX_GPU == GMX_GPU_NONE diff --git a/src/gromacs/mdtypes/swaphistory.h b/src/gromacs/mdtypes/swaphistory.h index 3bc865259b..aeb26465c1 100644 --- a/src/gromacs/mdtypes/swaphistory.h +++ b/src/gromacs/mdtypes/swaphistory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,19 +47,19 @@ */ typedef struct swapstateIons_t { - int nMolReq[eCompNR]; // Requested # of molecules per compartment - int *nMolReq_p[eCompNR]; // Pointer to this data (for checkpoint writing) - int inflow_net[eCompNR]; // Flux determined from the # of swaps - int *inflow_net_p[eCompNR]; // Pointer to this data - int *nMolPast[eCompNR]; // Array with nAverage entries for history - int *nMolPast_p[eCompNR]; // Pointer points to the first entry only + int nMolReq[eCompNR]; // Requested # of molecules per compartment + int* nMolReq_p[eCompNR]; // Pointer to this data (for checkpoint writing) + int inflow_net[eCompNR]; // Flux determined from the # of swaps + int* inflow_net_p[eCompNR]; // Pointer to this data + int* nMolPast[eCompNR]; // Array with nAverage entries for history + int* nMolPast_p[eCompNR]; // Pointer points to the first entry only // Channel flux detection, this is counting only and has no influence on whether swaps are performed or not: */ - int fluxfromAtoB[eCompNR]; // Flux determined from the split cylinders - int *fluxfromAtoB_p[eCompNR]; // Pointer to this data - int nMol; // Number of molecules, size of the following arrays - unsigned char *comp_from; // Ion came from which compartment? - unsigned char *channel_label; // Through which channel did this ion pass? + int fluxfromAtoB[eCompNR]; // Flux determined from the split cylinders + int* fluxfromAtoB_p[eCompNR]; // Pointer to this data + int nMol; // Number of molecules, size of the following arrays + unsigned char* comp_from; // Ion came from which compartment? + unsigned char* channel_label; // Through which channel did this ion pass? } swapstateIons_t; /* Position swapping state @@ -74,17 +74,16 @@ typedef struct swapstateIons_t */ typedef struct swaphistory_t { - int eSwapCoords; // Swapping along x, y, or z-direction? - int nIonTypes; // Number of ion types, this is the size of the following arrays - int nAverage; // Use average over this many swap attempt steps when determining the ion counts - int fluxleak; // Ions not going through any channel (bad!) - int *fluxleak_p; // Pointer to this data - gmx_bool bFromCpt; // Did we start from a checkpoint file? - int nat[eChanNR]; // Size of xc_old_whole, i.e. the number of atoms in each channel - rvec *xc_old_whole[eChanNR]; // Last known whole positions of the two channels (important for multimeric ch.!) - rvec **xc_old_whole_p[eChanNR]; // Pointer to these positions - swapstateIons_t *ionType; // History information for one ion type -} -swaphistory_t; + int eSwapCoords; // Swapping along x, y, or z-direction? + int nIonTypes; // Number of ion types, this is the size of the following arrays + int nAverage; // Use average over this many swap attempt steps when determining the ion counts + int fluxleak; // Ions not going through any channel (bad!) + int* fluxleak_p; // Pointer to this data + gmx_bool bFromCpt; // Did we start from a checkpoint file? + int nat[eChanNR]; // Size of xc_old_whole, i.e. the number of atoms in each channel + rvec* xc_old_whole[eChanNR]; // Last known whole positions of the two channels (important for multimeric ch.!) + rvec** xc_old_whole_p[eChanNR]; // Pointer to these positions + swapstateIons_t* ionType; // History information for one ion type +} swaphistory_t; #endif diff --git a/src/gromacs/mimic/communicator.cpp b/src/gromacs/mimic/communicator.cpp index d83ccc3cee..7c2b89ff74 100644 --- a/src/gromacs/mimic/communicator.cpp +++ b/src/gromacs/mimic/communicator.cpp @@ -44,8 +44,8 @@ #include "gromacs/utility/fatalerror.h" #if GMX_MIMIC -#include -#include +# include +# include #endif // When not built in a configuration with QMMM support, much of this @@ -60,25 +60,31 @@ constexpr int TYPE_INT = 0, TYPE_DOUBLE = 0; /*! \brief Stub communication library function to call in case if * GROMACS is compiled without MiMiC. Calling causes GROMACS to exit! */ -static void MCL_init_client(const char *) // NOLINT(readability-named-parameter) +static void MCL_init_client(const char*) // NOLINT(readability-named-parameter) { - GMX_RELEASE_ASSERT(GMX_MIMIC, "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); + GMX_RELEASE_ASSERT( + GMX_MIMIC, + "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); } /*! \brief Stub communication library function to call in case if * GROMACS is compiled without MiMiC. Calling causes GROMACS to exit! */ -static void MCL_send(void *, int, int, int) // NOLINT(readability-named-parameter) +static void MCL_send(void*, int, int, int) // NOLINT(readability-named-parameter) { - GMX_RELEASE_ASSERT(GMX_MIMIC, "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); + GMX_RELEASE_ASSERT( + GMX_MIMIC, + "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); } /*! \brief Stub communication library function to call in case if * GROMACS is compiled without MiMiC. Calling causes GROMACS to exit! */ -static void MCL_receive(void *, int, int, int) // NOLINT(readability-named-parameter) +static void MCL_receive(void*, int, int, int) // NOLINT(readability-named-parameter) { - GMX_RELEASE_ASSERT(GMX_MIMIC, "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); + GMX_RELEASE_ASSERT( + GMX_MIMIC, + "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); } /*! \brief Stub communication library function to call in case if @@ -86,7 +92,9 @@ static void MCL_receive(void *, int, int, int) // NOLINT(readability-named-param */ static void MCL_destroy() { - GMX_RELEASE_ASSERT(GMX_MIMIC, "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); + GMX_RELEASE_ASSERT( + GMX_MIMIC, + "GROMACS is compiled without MiMiC support! Please, recompile with -DGMX_MIMIC=ON"); } #endif @@ -97,8 +105,7 @@ void gmx::MimicCommunicator::init() return MCL_init_client(path); } -void gmx::MimicCommunicator::sendInitData(gmx_mtop_t *mtop, - PaddedHostVector coords) +void gmx::MimicCommunicator::sendInitData(gmx_mtop_t* mtop, PaddedHostVector coords) { MCL_send(&mtop->natoms, 1, TYPE_INT, 0); MCL_send(&mtop->atomtypes.nr, 1, TYPE_INT, 0); @@ -117,23 +124,24 @@ void gmx::MimicCommunicator::sendInitData(gmx_mtop_t *mtop, charges.reserve(static_cast(mtop->natoms)); int offset = 0; - for (const gmx_molblock_t &molblock : mtop->molblock) + for (const gmx_molblock_t& molblock : mtop->molblock) { - gmx_moltype_t *type = &mtop->moltype[molblock.type]; + gmx_moltype_t* type = &mtop->moltype[molblock.type]; for (int mol = 0; mol < molblock.nmol; ++mol) { - int nconstr = type->ilist[F_CONSTR].size() / 3; - int nconstrc = type->ilist[F_CONSTRNC].size() / 3; - int nsettle = type->ilist[F_SETTLE].size() / 4; + int nconstr = type->ilist[F_CONSTR].size() / 3; + int nconstrc = type->ilist[F_CONSTRNC].size() / 3; + int nsettle = type->ilist[F_SETTLE].size() / 4; for (int ncon = 0; ncon < nconstr + nconstrc; ++ncon) { - int contype = type->ilist[F_CONSTR].iatoms[0]; - int at1 = type->ilist[F_CONSTR].iatoms[1]; - int at2 = type->ilist[F_CONSTR].iatoms[2]; + int contype = type->ilist[F_CONSTR].iatoms[0]; + int at1 = type->ilist[F_CONSTR].iatoms[1]; + int at2 = type->ilist[F_CONSTR].iatoms[2]; bonds.push_back(offset + at1 + 1); bonds.push_back(offset + at2 + 1); - bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) / BOHR2NM); + bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) + / BOHR2NM); } for (int ncon = 0; ncon < nsettle; ++ncon) @@ -142,7 +150,7 @@ void gmx::MimicCommunicator::sendInitData(gmx_mtop_t *mtop, t_iatom h1; t_iatom h2; - int contype = type->ilist[F_SETTLE].iatoms[0]; + int contype = type->ilist[F_SETTLE].iatoms[0]; ox = type->ilist[F_SETTLE].iatoms[1]; h1 = type->ilist[F_SETTLE].iatoms[2]; @@ -156,9 +164,12 @@ void gmx::MimicCommunicator::sendInitData(gmx_mtop_t *mtop, bonds.push_back(offset + h1 + 1); bonds.push_back(offset + h2 + 1); - bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) / BOHR2NM); - bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) / BOHR2NM); - bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dB) / BOHR2NM); + bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) + / BOHR2NM); + bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dA) + / BOHR2NM); + bondLengths.push_back(static_cast(mtop->ffparams.iparams[contype].constr.dB) + / BOHR2NM); } nAtomsMol.push_back(type->atoms.nr); @@ -221,7 +232,7 @@ void gmx::MimicCommunicator::sendInitData(gmx_mtop_t *mtop, MCL_send(&*elements.begin(), mtop->atomtypes.nr, TYPE_INT, 0); std::vector convertedCoords; - for (auto &coord : coords) + for (auto& coord : coords) { convertedCoords.push_back(static_cast(coord[0]) / BOHR2NM); convertedCoords.push_back(static_cast(coord[1]) / BOHR2NM); @@ -239,7 +250,7 @@ int64_t gmx::MimicCommunicator::getStepNumber() return steps; } -void gmx::MimicCommunicator::getCoords(PaddedHostVector *x, const int natoms) +void gmx::MimicCommunicator::getCoords(PaddedHostVector* x, const int natoms) { std::vector coords(natoms * 3); MCL_receive(&*coords.begin(), 3 * natoms, TYPE_DOUBLE, 0); diff --git a/src/gromacs/mimic/communicator.h b/src/gromacs/mimic/communicator.h index 89f72382bc..033a11d482 100644 --- a/src/gromacs/mimic/communicator.h +++ b/src/gromacs/mimic/communicator.h @@ -56,64 +56,62 @@ namespace gmx class MimicCommunicator { - public: - /*! \brief - * Initializes the communicator - */ - void init(); +public: + /*! \brief + * Initializes the communicator + */ + void init(); - /*! \brief - * Sends the data needed for MiMiC initialization - * - * That includes number of atoms, element numbers, charges, masses, - * maximal order of multipoles (0 for point-charge forcefields), - * number of molecules, number of atoms per each molecule, - * bond constraints data - * - * @param mtop global topology data - * @param coords coordinates of all atoms - */ - void sendInitData(gmx_mtop_t *mtop, - PaddedHostVector coords); + /*! \brief + * Sends the data needed for MiMiC initialization + * + * That includes number of atoms, element numbers, charges, masses, + * maximal order of multipoles (0 for point-charge forcefields), + * number of molecules, number of atoms per each molecule, + * bond constraints data + * + * @param mtop global topology data + * @param coords coordinates of all atoms + */ + void sendInitData(gmx_mtop_t* mtop, PaddedHostVector coords); - /*! \brief - * Gets the number of MD steps to perform from MiMiC - * - * @return nsteps the number of MD steps to perform - */ - int64_t getStepNumber(); + /*! \brief + * Gets the number of MD steps to perform from MiMiC + * + * @return nsteps the number of MD steps to perform + */ + int64_t getStepNumber(); - /*! \brief - * Receive and array of updated atomic coordinates from MiMiC - * - * @param x array of coordinates to fill - * @param natoms number of atoms in the system - */ - void getCoords(PaddedHostVector *x, int natoms); + /*! \brief + * Receive and array of updated atomic coordinates from MiMiC + * + * @param x array of coordinates to fill + * @param natoms number of atoms in the system + */ + void getCoords(PaddedHostVector* x, int natoms); - /*! \brief - * Send the potential energy value to MiMiC - * - * @param energy energy value to send - */ - void sendEnergies(real energy); + /*! \brief + * Send the potential energy value to MiMiC + * + * @param energy energy value to send + */ + void sendEnergies(real energy); - /*! \brief - * Send classical forces acting on all atoms in the system - * to MiMiC. - * - * @param forces array of forces to send - * @param natoms number of atoms in the system - */ - void sendForces(ArrayRef forces, int natoms); - - /*! \brief - * Finish communications and disconnect from the server - */ - void finalize(); + /*! \brief + * Send classical forces acting on all atoms in the system + * to MiMiC. + * + * @param forces array of forces to send + * @param natoms number of atoms in the system + */ + void sendForces(ArrayRef forces, int natoms); + /*! \brief + * Finish communications and disconnect from the server + */ + void finalize(); }; -} // namespace gmx +} // namespace gmx -#endif //GMX_MIMIC_COMMUNICATOR_H +#endif // GMX_MIMIC_COMMUNICATOR_H diff --git a/src/gromacs/mimic/utilities.cpp b/src/gromacs/mimic/utilities.cpp index eaf6b4c136..77ae79469f 100644 --- a/src/gromacs/mimic/utilities.cpp +++ b/src/gromacs/mimic/utilities.cpp @@ -39,12 +39,13 @@ #include "gromacs/topology/topology.h" -std::vector genQmmmIndices(const gmx_mtop_t &mtop) +std::vector genQmmmIndices(const gmx_mtop_t& mtop) { - std::vector output; - int global_at = 0; - const unsigned char *grpnr = mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data(); - for (const gmx_molblock_t &molb : mtop.molblock) + std::vector output; + int global_at = 0; + const unsigned char* grpnr = + mtop.groups.groupNumbers[SimulationAtomGroupType::QuantumMechanics].data(); + for (const gmx_molblock_t& molb : mtop.molblock) { for (int mol = 0; mol < molb.nmol; ++mol) { diff --git a/src/gromacs/mimic/utilities.h b/src/gromacs/mimic/utilities.h index ef538c8071..8c7a4d9c69 100644 --- a/src/gromacs/mimic/utilities.h +++ b/src/gromacs/mimic/utilities.h @@ -55,6 +55,6 @@ struct gmx_mtop_t; * \param[in] mtop Global topology object * \return The list of global IDs of QM atoms */ -std::vector genQmmmIndices(const gmx_mtop_t &mtop); +std::vector genQmmmIndices(const gmx_mtop_t& mtop); -#endif //GMX_MIMIC_MIMICUTILS_H +#endif // GMX_MIMIC_MIMICUTILS_H diff --git a/src/gromacs/modularsimulator/checkpointhelper.cpp b/src/gromacs/modularsimulator/checkpointhelper.cpp index 4f1330172e..6e83ded8bb 100644 --- a/src/gromacs/modularsimulator/checkpointhelper.cpp +++ b/src/gromacs/modularsimulator/checkpointhelper.cpp @@ -52,18 +52,17 @@ namespace gmx { -CheckpointHelper::CheckpointHelper( - std::vector clients, - std::unique_ptr checkpointHandler, - int initStep, - TrajectoryElement *trajectoryElement, - int globalNumAtoms, - FILE *fplog, - t_commrec *cr, - ObservablesHistory *observablesHistory, - gmx_walltime_accounting *walltime_accounting, - t_state *state_global, - bool writeFinalCheckpoint) : +CheckpointHelper::CheckpointHelper(std::vector clients, + std::unique_ptr checkpointHandler, + int initStep, + TrajectoryElement* trajectoryElement, + int globalNumAtoms, + FILE* fplog, + t_commrec* cr, + ObservablesHistory* observablesHistory, + gmx_walltime_accounting* walltime_accounting, + t_state* state_global, + bool writeFinalCheckpoint) : clients_(std::move(clients)), checkpointHandler_(std::move(checkpointHandler)), initStep_(initStep), @@ -79,10 +78,9 @@ CheckpointHelper::CheckpointHelper( state_global_(state_global) { // Get rid of nullptr in clients list - clients_.erase( - std::remove_if(clients_.begin(), clients_.end(), - [](ICheckpointHelperClient* ptr){return !ptr; }), - clients_.end()); + clients_.erase(std::remove_if(clients_.begin(), clients_.end(), + [](ICheckpointHelperClient* ptr) { return ptr == nullptr; }), + clients_.end()); if (DOMAINDECOMP(cr)) { localState_ = std::make_unique(); @@ -94,7 +92,6 @@ CheckpointHelper::CheckpointHelper( state_change_natoms(state_global, state_global->natoms); localStateInstance_ = state_global; } - } void CheckpointHelper::run(Step step, Time time) @@ -110,9 +107,7 @@ void CheckpointHelper::run(Step step, Time time) checkpointHandler_->setSignal(walltime_accounting_); } -void CheckpointHelper::scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) +void CheckpointHelper::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { // Only last step checkpointing is done here if (step != lastStep_ || !writeFinalCheckpoint_) @@ -120,29 +115,26 @@ void CheckpointHelper::scheduleTask( return; } (*registerRunFunction)(std::make_unique( - [this, step, time]() - {writeCheckpoint(step, time); })); + [this, step, time]() { writeCheckpoint(step, time); })); } void CheckpointHelper::writeCheckpoint(Step step, Time time) { localStateInstance_->flags = 0; - for (const auto &client : clients_) + for (const auto& client : clients_) { client->writeCheckpoint(localStateInstance_, state_global_); } - mdoutf_write_to_trajectory_files( - fplog_, cr_, trajectoryElement_->outf_, - MDOF_CPT, globalNumAtoms_, step, time, - localStateInstance_, state_global_, - observablesHistory_, ArrayRef()); + mdoutf_write_to_trajectory_files(fplog_, cr_, trajectoryElement_->outf_, MDOF_CPT, + globalNumAtoms_, step, time, localStateInstance_, + state_global_, observablesHistory_, ArrayRef()); } SignallerCallbackPtr CheckpointHelper::registerLastStepCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time){this->lastStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->lastStep_ = step; }); } } // namespace gmx diff --git a/src/gromacs/modularsimulator/checkpointhelper.h b/src/gromacs/modularsimulator/checkpointhelper.h index b989a2add8..905e636af3 100644 --- a/src/gromacs/modularsimulator/checkpointhelper.h +++ b/src/gromacs/modularsimulator/checkpointhelper.h @@ -90,97 +90,92 @@ class TrajectoryElement; * \todo Develop this into a module solely providing a file handler to * modules for checkpoint reading and writing. */ -class CheckpointHelper final : - public ILastStepSignallerClient, - public ISimulatorElement +class CheckpointHelper final : public ILastStepSignallerClient, public ISimulatorElement { - public: - //! Constructor - CheckpointHelper( - std::vector clients, - std::unique_ptr checkpointHandler, - int initStep, - TrajectoryElement *trajectoryElement, - int globalNumAtoms, - FILE *fplog, - t_commrec *cr, - ObservablesHistory *observablesHistory, - gmx_walltime_accounting *walltime_accounting, - t_state *state_global, - bool writeFinalCheckpoint); - - /*! \brief Run checkpointing - * - * Sets signal and / or performs checkpointing at neighbor searching steps - * - * @param step The step number - * @param time The time - */ - void run(Step step, Time time); - - /*! \brief Register run function for step / time - * - * Performs checkpointing at the last step. This is part of the element call - * list, as the checkpoint helper need to be able to react to the last step - * being signalled. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! No element setup needed - void elementSetup() override {} - //! No element teardown needed - void elementTeardown() override {} - - private: - //! List of checkpoint clients - std::vector clients_; - - //! The checkpoint handler - std::unique_ptr checkpointHandler_; - - //! The first step of the simulation - const Step initStep_; - //! The last step of the simulation - Step lastStep_; - //! The total number of atoms - const int globalNumAtoms_; - //! Whether a checkpoint is written on the last step - const bool writeFinalCheckpoint_; - - //! ILastStepSignallerClient implementation - SignallerCallbackPtr registerLastStepCallback() override; - - //! The actual checkpoint writing function - void writeCheckpoint(Step step, Time time); - - //! Pointer to the trajectory element - to use file pointer - TrajectoryElement *trajectoryElement_; - - //! A local t_state object to gather data in - //! { - std::unique_ptr localState_; - t_state *localStateInstance_; - //! } - - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - t_commrec *cr_; - //! History of simulation observables. - ObservablesHistory *observablesHistory_; - //! Manages wall time accounting. - gmx_walltime_accounting *walltime_accounting_; - //! Full simulation state (only non-nullptr on master rank). - t_state *state_global_; +public: + //! Constructor + CheckpointHelper(std::vector clients, + std::unique_ptr checkpointHandler, + int initStep, + TrajectoryElement* trajectoryElement, + int globalNumAtoms, + FILE* fplog, + t_commrec* cr, + ObservablesHistory* observablesHistory, + gmx_walltime_accounting* walltime_accounting, + t_state* state_global, + bool writeFinalCheckpoint); + + /*! \brief Run checkpointing + * + * Sets signal and / or performs checkpointing at neighbor searching steps + * + * @param step The step number + * @param time The time + */ + void run(Step step, Time time); + + /*! \brief Register run function for step / time + * + * Performs checkpointing at the last step. This is part of the element call + * list, as the checkpoint helper need to be able to react to the last step + * being signalled. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! No element setup needed + void elementSetup() override {} + //! No element teardown needed + void elementTeardown() override {} + +private: + //! List of checkpoint clients + std::vector clients_; + + //! The checkpoint handler + std::unique_ptr checkpointHandler_; + + //! The first step of the simulation + const Step initStep_; + //! The last step of the simulation + Step lastStep_; + //! The total number of atoms + const int globalNumAtoms_; + //! Whether a checkpoint is written on the last step + const bool writeFinalCheckpoint_; + + //! ILastStepSignallerClient implementation + SignallerCallbackPtr registerLastStepCallback() override; + + //! The actual checkpoint writing function + void writeCheckpoint(Step step, Time time); + + //! Pointer to the trajectory element - to use file pointer + TrajectoryElement* trajectoryElement_; + + //! A local t_state object to gather data in + //! { + std::unique_ptr localState_; + t_state* localStateInstance_; + //! } + + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + t_commrec* cr_; + //! History of simulation observables. + ObservablesHistory* observablesHistory_; + //! Manages wall time accounting. + gmx_walltime_accounting* walltime_accounting_; + //! Full simulation state (only non-nullptr on master rank). + t_state* state_global_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_CHECKPOINTHELPER_H diff --git a/src/gromacs/modularsimulator/compositesimulatorelement.cpp b/src/gromacs/modularsimulator/compositesimulatorelement.cpp index 2f04b8e126..fa2e5ce46f 100644 --- a/src/gromacs/modularsimulator/compositesimulatorelement.cpp +++ b/src/gromacs/modularsimulator/compositesimulatorelement.cpp @@ -46,17 +46,16 @@ namespace gmx { CompositeSimulatorElement::CompositeSimulatorElement( - std::vector< compat::not_null > elementCallList, - std::vector< std::unique_ptr > elements) : + std::vector> elementCallList, + std::vector> elements) : elementCallList_(std::move(elementCallList)), elementOwnershipList_(std::move(elements)) -{} +{ +} -void CompositeSimulatorElement::scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) +void CompositeSimulatorElement::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { - for (auto &element : elementCallList_) + for (auto& element : elementCallList_) { element->scheduleTask(step, time, registerRunFunction); } @@ -64,7 +63,7 @@ void CompositeSimulatorElement::scheduleTask( void CompositeSimulatorElement::elementSetup() { - for (auto &element : elementOwnershipList_) + for (auto& element : elementOwnershipList_) { element->elementSetup(); } @@ -72,10 +71,10 @@ void CompositeSimulatorElement::elementSetup() void CompositeSimulatorElement::elementTeardown() { - for (auto &element : elementOwnershipList_) + for (auto& element : elementOwnershipList_) { element->elementTeardown(); } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/compositesimulatorelement.h b/src/gromacs/modularsimulator/compositesimulatorelement.h index 36d75c0140..36a05af736 100644 --- a/src/gromacs/modularsimulator/compositesimulatorelement.h +++ b/src/gromacs/modularsimulator/compositesimulatorelement.h @@ -68,47 +68,43 @@ namespace gmx * owned by CompositeSimulatorElement is responsible to call setup and teardown * methods on these elements. */ -class CompositeSimulatorElement final : - public ISimulatorElement +class CompositeSimulatorElement final : public ISimulatorElement { - public: - //! Constructor - explicit CompositeSimulatorElement( - std::vector< compat::not_null > elementCallList, - std::vector< std::unique_ptr > elements); +public: + //! Constructor + explicit CompositeSimulatorElement(std::vector> elementCallList, + std::vector> elements); - /*! \brief Register run function for step / time - * - * Lets every member of the composite simulator register run functions - * for the given step. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; + /*! \brief Register run function for step / time + * + * Lets every member of the composite simulator register run functions + * for the given step. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; - /*! \brief Element setup - * - * Calls the setup functions of the single elements. - */ - void elementSetup() override; + /*! \brief Element setup + * + * Calls the setup functions of the single elements. + */ + void elementSetup() override; - /*! \brief Element teardown - * - * Calls the teardown functions of the single elements. - */ - void elementTeardown() override; + /*! \brief Element teardown + * + * Calls the teardown functions of the single elements. + */ + void elementTeardown() override; - private: - //! The call list of elements forming the composite element - std::vector< compat::not_null > elementCallList_; - //! List of elements owned by composite element - std::vector< std::unique_ptr > elementOwnershipList_; +private: + //! The call list of elements forming the composite element + std::vector> elementCallList_; + //! List of elements owned by composite element + std::vector> elementOwnershipList_; }; -} // namespace gmx +} // namespace gmx #endif // GROMACS_MDTYPES_COMPOSITESIMULATORELEMENT_H diff --git a/src/gromacs/modularsimulator/computeglobalselement.cpp b/src/gromacs/modularsimulator/computeglobalselement.cpp index aa239251a4..e902776573 100644 --- a/src/gromacs/modularsimulator/computeglobalselement.cpp +++ b/src/gromacs/modularsimulator/computeglobalselement.cpp @@ -58,24 +58,23 @@ namespace gmx { -template -ComputeGlobalsElement::ComputeGlobalsElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - SimulationSignals *signals, - int nstglobalcomm, - FILE *fplog, - const MDLogger &mdlog, - t_commrec *cr, - t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - t_forcerec *fr, - const gmx_mtop_t *global_top, - Constraints *constr, - bool hasReadEkinState) : +template +ComputeGlobalsElement::ComputeGlobalsElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + SimulationSignals* signals, + int nstglobalcomm, + FILE* fplog, + const MDLogger& mdlog, + t_commrec* cr, + t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + t_forcerec* fr, + const gmx_mtop_t* global_top, + Constraints* constr, + bool hasReadEkinState) : energyReductionStep_(-1), virialReductionStep_(-1), doStopCM_(inputrec->comm_mode != ecmNO), @@ -108,25 +107,25 @@ ComputeGlobalsElement::ComputeGlobalsElement( gstat_ = global_stat_init(inputrec_); } -template +template ComputeGlobalsElement::~ComputeGlobalsElement() { global_stat_destroy(gstat_); } -template +template void ComputeGlobalsElement::elementSetup() { GMX_ASSERT(localTopology_, "Setup called before local topology was set."); // Only do initial communication step for one of the velocity-verlet stages - if (algorithm == ComputeGlobalsAlgorithm::LeapFrog || - algorithm == ComputeGlobalsAlgorithm::VelocityVerletAtFullTimeStep) + if (algorithm == ComputeGlobalsAlgorithm::LeapFrog + || algorithm == ComputeGlobalsAlgorithm::VelocityVerletAtFullTimeStep) { - unsigned int cglo_flags = - (CGLO_TEMPERATURE | CGLO_GSTAT - | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - | (hasReadEkinState_ ? CGLO_READEKIN : 0)); + unsigned int cglo_flags = + (CGLO_TEMPERATURE | CGLO_GSTAT + | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) + | (hasReadEkinState_ ? CGLO_READEKIN : 0)); if (algorithm == ComputeGlobalsAlgorithm::VelocityVerletAtFullTimeStep) { @@ -155,7 +154,7 @@ void ComputeGlobalsElement::elementSetup() auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); // At initialization, do not pass x with acceleration-correction mode // to avoid (incorrect) correction of the initial coordinates. - rvec *xPtr = nullptr; + rvec* xPtr = nullptr; if (vcm_.mode != ecmLINEAR_ACCELERATION_CORRECTION) { xPtr = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); @@ -174,15 +173,14 @@ void ComputeGlobalsElement::elementSetup() } } -template -void ComputeGlobalsElement::scheduleTask( - Step step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +template +void ComputeGlobalsElement::scheduleTask(Step step, + Time gmx_unused time, + const RegisterRunFunctionPtr& registerRunFunction) { const bool needComReduction = doStopCM_ && do_per_step(step, nstcomm_); - const bool needGlobalReduction = - step == energyReductionStep_ || step == virialReductionStep_ || - needComReduction || do_per_step(step, nstglobalcomm_); + const bool needGlobalReduction = step == energyReductionStep_ || step == virialReductionStep_ + || needComReduction || do_per_step(step, nstglobalcomm_); // TODO: CGLO_GSTAT is only used for needToSumEkinhOld_, i.e. to signal that we do or do not // sum the previous kinetic energy. We should simplify / clarify this. @@ -196,9 +194,7 @@ void ComputeGlobalsElement::scheduleTask( // With leap-frog we also need to compute the half-step // kinetic energy at the step before we need to write // the full-step kinetic energy - const bool needEkinAtNextStep = - (do_per_step(step + 1, nstglobalcomm_) || - step + 1 == lastStep_); + const bool needEkinAtNextStep = (do_per_step(step + 1, nstglobalcomm_) || step + 1 == lastStep_); if (!needGlobalReduction && !needEkinAtNextStep) { @@ -206,32 +202,28 @@ void ComputeGlobalsElement::scheduleTask( } const bool doEnergy = step == energyReductionStep_; - int flags = - (needGlobalReduction ? CGLO_GSTAT : 0) - | (doEnergy ? CGLO_ENERGY : 0) - | (needComReduction ? CGLO_STOPCM : 0) - | CGLO_TEMPERATURE - | CGLO_PRESSURE - | CGLO_CONSTRAINT - | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0); + int flags = + (needGlobalReduction ? CGLO_GSTAT : 0) | (doEnergy ? CGLO_ENERGY : 0) + | (needComReduction ? CGLO_STOPCM : 0) | CGLO_TEMPERATURE | CGLO_PRESSURE | CGLO_CONSTRAINT + | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0); // Since we're already communicating at this step, we // can propagate intra-simulation signals. Note that // check_nstglobalcomm has the responsibility for // choosing the value of nstglobalcomm which satisfies // the need of the different signallers. - const bool doIntraSimSignal = true; + const bool doIntraSimSignal = true; // Disable functionality - const bool doInterSimSignal = false; + const bool doInterSimSignal = false; // Make signaller to signal stop / reset / checkpointing signals - auto signaller = std::make_shared( - signals_, cr_, nullptr, doInterSimSignal, doIntraSimSignal); + auto signaller = std::make_shared(signals_, cr_, nullptr, + doInterSimSignal, doIntraSimSignal); - (*registerRunFunction)( - std::make_unique( - [this, step, flags, signaller = std::move(signaller)]() - {compute(step, flags, signaller.get(), true); })); + (*registerRunFunction)(std::make_unique( + [this, step, flags, signaller = std::move(signaller)]() { + compute(step, flags, signaller.get(), true); + })); } else if (algorithm == ComputeGlobalsAlgorithm::VelocityVerletAtFullTimeStep) { @@ -246,19 +238,14 @@ void ComputeGlobalsElement::scheduleTask( const bool doTemperature = step != initStep_ || inputrec_->bContinuation; const bool doEnergy = step == energyReductionStep_; - int flags = - (needGlobalReduction ? CGLO_GSTAT : 0) - | (doEnergy ? CGLO_ENERGY : 0) - | (doTemperature ? CGLO_TEMPERATURE : 0) - | CGLO_PRESSURE - | CGLO_CONSTRAINT - | (needComReduction ? CGLO_STOPCM : 0) - | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) - | CGLO_SCALEEKIN; - - (*registerRunFunction)( - std::make_unique( - [this, step, flags]() { compute(step, flags, nullSignaller_.get(), false); })); + int flags = (needGlobalReduction ? CGLO_GSTAT : 0) | (doEnergy ? CGLO_ENERGY : 0) + | (doTemperature ? CGLO_TEMPERATURE : 0) | CGLO_PRESSURE | CGLO_CONSTRAINT + | (needComReduction ? CGLO_STOPCM : 0) + | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0) + | CGLO_SCALEEKIN; + + (*registerRunFunction)(std::make_unique( + [this, step, flags]() { compute(step, flags, nullSignaller_.get(), false); })); } else if (algorithm == ComputeGlobalsAlgorithm::VelocityVerletAfterCoordinateUpdate) { @@ -267,9 +254,9 @@ void ComputeGlobalsElement::scheduleTask( { return; } - int flags = - CGLO_GSTAT | CGLO_CONSTRAINT - | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0); + int flags = CGLO_GSTAT | CGLO_CONSTRAINT + | (shouldCheckNumberOfBondedInteractions_ ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS + : 0); // Since we're already communicating at this step, we // can propagate intra-simulation signals. Note that @@ -280,47 +267,41 @@ void ComputeGlobalsElement::scheduleTask( // Disable functionality const bool doInterSimSignal = false; - auto signaller = std::make_shared( - signals_, cr_, nullptr, doInterSimSignal, doIntraSimSignal); + auto signaller = std::make_shared(signals_, cr_, nullptr, + doInterSimSignal, doIntraSimSignal); - (*registerRunFunction)( - std::make_unique( - [this, step, flags, signaller = std::move(signaller)]() { - compute(step, flags, signaller.get(), true); - })); + (*registerRunFunction)(std::make_unique( + [this, step, flags, signaller = std::move(signaller)]() { + compute(step, flags, signaller.get(), true); + })); } } -template -void ComputeGlobalsElement::compute( - gmx::Step step, unsigned int flags, - SimulationSignaller *signaller, - bool useLastBox, bool isInit) +template +void ComputeGlobalsElement::compute(gmx::Step step, + unsigned int flags, + SimulationSignaller* signaller, + bool useLastBox, + bool isInit) { - auto x = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); - auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); - auto box = statePropagatorData_->constBox(); - auto lastbox = useLastBox ? statePropagatorData_->constPreviousBox() : statePropagatorData_->constBox(); - - const real vdwLambda = freeEnergyPerturbationElement_ ? - freeEnergyPerturbationElement_->constLambdaView()[efptVDW] : 0; - - compute_globals(gstat_, cr_, inputrec_, fr_, - energyElement_->ekindata(), - x, v, box, vdwLambda, - mdAtoms_->mdatoms(), nrnb_, &vcm_, - step != -1 ? wcycle_ : nullptr, - energyElement_->enerdata(), - energyElement_->forceVirial(step), - energyElement_->constraintVirial(step), - energyElement_->totalVirial(step), - energyElement_->pressure(step), - energyElement_->muTot(), - constr_, signaller, lastbox, + auto x = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); + auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + auto box = statePropagatorData_->constBox(); + auto lastbox = useLastBox ? statePropagatorData_->constPreviousBox() + : statePropagatorData_->constBox(); + + const real vdwLambda = freeEnergyPerturbationElement_ + ? freeEnergyPerturbationElement_->constLambdaView()[efptVDW] + : 0; + + compute_globals(gstat_, cr_, inputrec_, fr_, energyElement_->ekindata(), x, v, box, vdwLambda, + mdAtoms_->mdatoms(), nrnb_, &vcm_, step != -1 ? wcycle_ : nullptr, + energyElement_->enerdata(), energyElement_->forceVirial(step), + energyElement_->constraintVirial(step), energyElement_->totalVirial(step), + energyElement_->pressure(step), energyElement_->muTot(), constr_, signaller, lastbox, &totalNumberOfBondedInteractions_, energyElement_->needToSumEkinhOld(), flags); - checkNumberOfBondedInteractions(mdlog_, cr_, totalNumberOfBondedInteractions_, - top_global_, localTopology_, x, box, - &shouldCheckNumberOfBondedInteractions_); + checkNumberOfBondedInteractions(mdlog_, cr_, totalNumberOfBondedInteractions_, top_global_, + localTopology_, x, box, &shouldCheckNumberOfBondedInteractions_); if (flags & CGLO_STOPCM && !isInit) { process_and_stopcm_grp(fplog_, &vcm_, *mdAtoms_->mdatoms(), x, v); @@ -328,54 +309,48 @@ void ComputeGlobalsElement::compute( } } -template -CheckBondedInteractionsCallbackPtr -ComputeGlobalsElement::getCheckNumberOfBondedInteractionsCallback() +template +CheckBondedInteractionsCallbackPtr ComputeGlobalsElement::getCheckNumberOfBondedInteractionsCallback() { return std::make_unique( - [this](){needToCheckNumberOfBondedInteractions(); }); + [this]() { needToCheckNumberOfBondedInteractions(); }); } -template +template void ComputeGlobalsElement::needToCheckNumberOfBondedInteractions() { shouldCheckNumberOfBondedInteractions_ = true; } -template -void ComputeGlobalsElement::setTopology(const gmx_localtop_t *top) +template +void ComputeGlobalsElement::setTopology(const gmx_localtop_t* top) { localTopology_ = top; } -template -SignallerCallbackPtr ComputeGlobalsElement:: - registerEnergyCallback(EnergySignallerEvent event) +template +SignallerCallbackPtr ComputeGlobalsElement::registerEnergyCallback(EnergySignallerEvent event) { if (event == EnergySignallerEvent::EnergyCalculationStep) { return std::make_unique( - [this](Step step, Time) - {energyReductionStep_ = step; }); + [this](Step step, Time /*unused*/) { energyReductionStep_ = step; }); } if (event == EnergySignallerEvent::VirialCalculationStep) { return std::make_unique( - [this](Step step, Time){virialReductionStep_ = step; }); + [this](Step step, Time /*unused*/) { virialReductionStep_ = step; }); } return nullptr; - } -template -SignallerCallbackPtr ComputeGlobalsElement:: - registerTrajectorySignallerCallback(TrajectoryEvent event) +template +SignallerCallbackPtr ComputeGlobalsElement::registerTrajectorySignallerCallback(TrajectoryEvent event) { if (event == TrajectoryEvent::EnergyWritingStep) { return std::make_unique( - [this](Step step, Time) - {energyReductionStep_ = step; }); + [this](Step step, Time /*unused*/) { energyReductionStep_ = step; }); } return nullptr; } @@ -386,4 +361,4 @@ template class ComputeGlobalsElement; template class ComputeGlobalsElement; template class ComputeGlobalsElement; //! @} -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/computeglobalselement.h b/src/gromacs/modularsimulator/computeglobalselement.h index 83d914a03f..85d0aba1ff 100644 --- a/src/gromacs/modularsimulator/computeglobalselement.h +++ b/src/gromacs/modularsimulator/computeglobalselement.h @@ -96,160 +96,154 @@ typedef std::unique_ptr CheckBondedInteractions * * @tparam algorithm The global reduction scheme */ -template +template class ComputeGlobalsElement final : - public ISimulatorElement, - public IEnergySignallerClient, - public ITrajectorySignallerClient, - public ITopologyHolderClient + public ISimulatorElement, + public IEnergySignallerClient, + public ITrajectorySignallerClient, + public ITopologyHolderClient { - public: - //! Constructor - ComputeGlobalsElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - SimulationSignals *signals, - int nstglobalcomm, - FILE *fplog, - const MDLogger &mdlog, - t_commrec *cr, - t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - t_forcerec *fr, - const gmx_mtop_t *global_top, - Constraints *constr, - bool hasReadEkinState); - - //! Destructor - ~ComputeGlobalsElement() override; - - /*! \brief Element setup - first call to compute_globals - * - */ - void elementSetup() override; - - /*! \brief Register run function for step / time - * - * This registers the call to compute_globals when needed. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! Get callback to request checking of bonded interactions - CheckBondedInteractionsCallbackPtr getCheckNumberOfBondedInteractionsCallback(); - - //! No element teardown needed - void elementTeardown() override {} - - private: - //! ITopologyClient implementation - void setTopology(const gmx_localtop_t *top) override; - //! IEnergySignallerClient implementation - SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; - //! ITrajectorySignallerClient implementation - SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; - //! The compute_globals call - void compute( - Step step, unsigned int flags, - SimulationSignaller *signaller, bool useLastBox, - bool isInit = false); - - //! Next step at which energy needs to be reduced - Step energyReductionStep_; - //! Next step at which virial needs to be reduced - Step virialReductionStep_; - - //! Whether center of mass motion stopping is enabled - const bool doStopCM_; - //! Number of steps after which center of mass motion is removed - int nstcomm_; - //! Compute globals communication period - int nstglobalcomm_; - //! The last (planned) step (only used for LF) - const Step lastStep_; - //! The initial step (only used for VV) - const Step initStep_; - //! A dummy signaller (used for setup and VV) - std::unique_ptr nullSignaller_; - //! Whether we read kinetic energy from checkpoint - const bool hasReadEkinState_; - - /*! \brief Check that DD doesn't miss bonded interactions - * - * Domain decomposition could incorrectly miss a bonded - * interaction, but checking for that requires a global - * communication stage, which does not otherwise happen in DD - * code. So we do that alongside the first global energy reduction - * after a new DD is made. These variables handle whether the - * check happens, and the result it returns. - */ - //! @{ - int totalNumberOfBondedInteractions_; - bool shouldCheckNumberOfBondedInteractions_; - //! @} - - /*! \brief Signal to ComputeGlobalsElement that it should check for DD errors - * - * Note that this should really be the responsibility of the DD element. - * MDLogger, global and local topology are only needed due to the call to - * checkNumberOfBondedInteractions(...). - * - * The DD element should have a single variable which gets reduced, and then - * be responsible for the checking after a global reduction has happened. - * This would, however, require a new approach for the compute_globals calls, - * which is not yet implemented. So for now, we're leaving this here. - */ - void needToCheckNumberOfBondedInteractions(); - - //! Global reduction struct - gmx_global_stat *gstat_; - - //! Pointer to the microstate - StatePropagatorData *statePropagatorData_; - //! Pointer to the energy element (needed for the tensors and mu_tot) - EnergyElement *energyElement_; - //! Pointer to the local topology (only needed for checkNumberOfBondedInteractions) - const gmx_localtop_t *localTopology_; - //! Pointer to the free energy perturbation element - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; - - //! Center of mass motion removal - t_vcm vcm_; - //! Signals - SimulationSignals *signals_; - - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles logging. - const MDLogger &mdlog_; - //! Handles communication. - t_commrec *cr_; - //! Contains user input mdp options. - t_inputrec *inputrec_; - //! Full system topology - only needed for checkNumberOfBondedInteractions. - const gmx_mtop_t *top_global_; - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; - //! Handles constraints. - Constraints *constr_; - //! Manages flop accounting. - t_nrnb *nrnb_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; - //! Parameters for force calculations. - t_forcerec *fr_; +public: + //! Constructor + ComputeGlobalsElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + SimulationSignals* signals, + int nstglobalcomm, + FILE* fplog, + const MDLogger& mdlog, + t_commrec* cr, + t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + t_forcerec* fr, + const gmx_mtop_t* global_top, + Constraints* constr, + bool hasReadEkinState); + + //! Destructor + ~ComputeGlobalsElement() override; + + /*! \brief Element setup - first call to compute_globals + * + */ + void elementSetup() override; + + /*! \brief Register run function for step / time + * + * This registers the call to compute_globals when needed. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! Get callback to request checking of bonded interactions + CheckBondedInteractionsCallbackPtr getCheckNumberOfBondedInteractionsCallback(); + + //! No element teardown needed + void elementTeardown() override {} + +private: + //! ITopologyClient implementation + void setTopology(const gmx_localtop_t* top) override; + //! IEnergySignallerClient implementation + SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; + //! ITrajectorySignallerClient implementation + SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; + //! The compute_globals call + void compute(Step step, unsigned int flags, SimulationSignaller* signaller, bool useLastBox, bool isInit = false); + + //! Next step at which energy needs to be reduced + Step energyReductionStep_; + //! Next step at which virial needs to be reduced + Step virialReductionStep_; + + //! Whether center of mass motion stopping is enabled + const bool doStopCM_; + //! Number of steps after which center of mass motion is removed + int nstcomm_; + //! Compute globals communication period + int nstglobalcomm_; + //! The last (planned) step (only used for LF) + const Step lastStep_; + //! The initial step (only used for VV) + const Step initStep_; + //! A dummy signaller (used for setup and VV) + std::unique_ptr nullSignaller_; + //! Whether we read kinetic energy from checkpoint + const bool hasReadEkinState_; + + /*! \brief Check that DD doesn't miss bonded interactions + * + * Domain decomposition could incorrectly miss a bonded + * interaction, but checking for that requires a global + * communication stage, which does not otherwise happen in DD + * code. So we do that alongside the first global energy reduction + * after a new DD is made. These variables handle whether the + * check happens, and the result it returns. + */ + //! @{ + int totalNumberOfBondedInteractions_; + bool shouldCheckNumberOfBondedInteractions_; + //! @} + + /*! \brief Signal to ComputeGlobalsElement that it should check for DD errors + * + * Note that this should really be the responsibility of the DD element. + * MDLogger, global and local topology are only needed due to the call to + * checkNumberOfBondedInteractions(...). + * + * The DD element should have a single variable which gets reduced, and then + * be responsible for the checking after a global reduction has happened. + * This would, however, require a new approach for the compute_globals calls, + * which is not yet implemented. So for now, we're leaving this here. + */ + void needToCheckNumberOfBondedInteractions(); + + //! Global reduction struct + gmx_global_stat* gstat_; + + //! Pointer to the microstate + StatePropagatorData* statePropagatorData_; + //! Pointer to the energy element (needed for the tensors and mu_tot) + EnergyElement* energyElement_; + //! Pointer to the local topology (only needed for checkNumberOfBondedInteractions) + const gmx_localtop_t* localTopology_; + //! Pointer to the free energy perturbation element + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; + + //! Center of mass motion removal + t_vcm vcm_; + //! Signals + SimulationSignals* signals_; + + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles logging. + const MDLogger& mdlog_; + //! Handles communication. + t_commrec* cr_; + //! Contains user input mdp options. + t_inputrec* inputrec_; + //! Full system topology - only needed for checkNumberOfBondedInteractions. + const gmx_mtop_t* top_global_; + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; + //! Handles constraints. + Constraints* constr_; + //! Manages flop accounting. + t_nrnb* nrnb_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; + //! Parameters for force calculations. + t_forcerec* fr_; }; //! \} -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_COMPUTEGLOBALSELEMENT_H diff --git a/src/gromacs/modularsimulator/constraintelement.cpp b/src/gromacs/modularsimulator/constraintelement.cpp index 59ee9aad37..90f993f005 100644 --- a/src/gromacs/modularsimulator/constraintelement.cpp +++ b/src/gromacs/modularsimulator/constraintelement.cpp @@ -54,16 +54,15 @@ namespace gmx { -template -ConstraintsElement::ConstraintsElement( - Constraints *constr, - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isMaster, - FILE *fplog, - const t_inputrec *inputrec, - const t_mdatoms *mdAtoms) : +template +ConstraintsElement::ConstraintsElement(Constraints* constr, + StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isMaster, + FILE* fplog, + const t_inputrec* inputrec, + const t_mdatoms* mdAtoms) : nextVirialCalculationStep_(-1), nextEnergyWritingStep_(-1), nextLogWritingStep_(-1), @@ -79,93 +78,78 @@ ConstraintsElement::ConstraintsElement( GMX_ASSERT(constr_, "Constraint element created but constr == nullptr"); } -template +template void ConstraintsElement::elementSetup() { - if (!inputrec_->bContinuation && - ((variable == ConstraintVariable::Positions && inputrec_->eI == eiMD) || - (variable == ConstraintVariable::Velocities && inputrec_->eI == eiVV))) + if (!inputrec_->bContinuation + && ((variable == ConstraintVariable::Positions && inputrec_->eI == eiMD) + || (variable == ConstraintVariable::Velocities && inputrec_->eI == eiVV))) { - const real lambdaBonded = freeEnergyPerturbationElement_ ? - freeEnergyPerturbationElement_->constLambdaView()[efptBONDED] : 0; + const real lambdaBonded = freeEnergyPerturbationElement_ + ? freeEnergyPerturbationElement_->constLambdaView()[efptBONDED] + : 0; // Constrain the initial coordinates and velocities - do_constrain_first( - fplog_, constr_, inputrec_, mdAtoms_, - statePropagatorData_->localNumAtoms(), - statePropagatorData_->positionsView(), - statePropagatorData_->velocitiesView(), - statePropagatorData_->box(), - lambdaBonded); + do_constrain_first(fplog_, constr_, inputrec_, mdAtoms_, statePropagatorData_->localNumAtoms(), + statePropagatorData_->positionsView(), statePropagatorData_->velocitiesView(), + statePropagatorData_->box(), lambdaBonded); if (isMasterRank_) { if (inputrec_->eConstrAlg == econtLINCS) { - fprintf(fplog_, - "RMS relative constraint deviation after constraining: %.2e\n", + fprintf(fplog_, "RMS relative constraint deviation after constraining: %.2e\n", constr_->rmsd()); } } } } -template -void ConstraintsElement::scheduleTask( - Step step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +template +void ConstraintsElement::scheduleTask(Step step, + Time gmx_unused time, + const RegisterRunFunctionPtr& registerRunFunction) { bool calculateVirial = (step == nextVirialCalculationStep_); bool writeLog = (step == nextLogWritingStep_); bool writeEnergy = (step == nextEnergyWritingStep_); // register constraining - (*registerRunFunction)( - std::make_unique( - [this, step, calculateVirial, writeLog, writeEnergy]() - {apply(step, calculateVirial, writeLog, writeEnergy); })); + (*registerRunFunction)(std::make_unique( + [this, step, calculateVirial, writeLog, writeEnergy]() { + apply(step, calculateVirial, writeLog, writeEnergy); + })); } -template -void ConstraintsElement::apply( - Step step, - bool calculateVirial, - bool writeLog, - bool writeEnergy) +template +void ConstraintsElement::apply(Step step, bool calculateVirial, bool writeLog, bool writeEnergy) { tensor vir_con; - rvec *x, *xprime, *min_proj, *v; + rvec *x, *xprime, *min_proj, *v; // disabled functionality real lambda = 0; - real *dvdlambda = nullptr; + real* dvdlambda = nullptr; switch (variable) { case ConstraintVariable::Positions: - x = as_rvec_array(statePropagatorData_->previousPositionsView().paddedArrayRef().data()); + x = as_rvec_array(statePropagatorData_->previousPositionsView().paddedArrayRef().data()); xprime = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); min_proj = nullptr; - v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); break; case ConstraintVariable::Velocities: - x = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); - xprime = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + x = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); + xprime = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); min_proj = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); v = nullptr; break; - default: - gmx_fatal(FARGS, "Constraint algorithm not implemented for modular simulator."); + default: gmx_fatal(FARGS, "Constraint algorithm not implemented for modular simulator."); } - constr_->apply( - writeLog, writeEnergy, - step, 1, 1.0, - x, xprime, min_proj, - statePropagatorData_->box(), - lambda, dvdlambda, - v, calculateVirial ? &vir_con : nullptr, - variable); + constr_->apply(writeLog, writeEnergy, step, 1, 1.0, x, xprime, min_proj, statePropagatorData_->box(), + lambda, dvdlambda, v, calculateVirial ? &vir_con : nullptr, variable); if (calculateVirial) { @@ -180,36 +164,33 @@ void ConstraintsElement::apply( } } -template -SignallerCallbackPtr ConstraintsElement:: - registerEnergyCallback(EnergySignallerEvent event) +template +SignallerCallbackPtr ConstraintsElement::registerEnergyCallback(EnergySignallerEvent event) { if (event == EnergySignallerEvent::VirialCalculationStep) { return std::make_unique( - [this](Step step, Time){nextVirialCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextVirialCalculationStep_ = step; }); } return nullptr; } -template -SignallerCallbackPtr ConstraintsElement:: - registerTrajectorySignallerCallback(TrajectoryEvent event) +template +SignallerCallbackPtr ConstraintsElement::registerTrajectorySignallerCallback(TrajectoryEvent event) { if (event == TrajectoryEvent::EnergyWritingStep) { return std::make_unique( - [this](Step step, Time) - {nextEnergyWritingStep_ = step; }); + [this](Step step, Time /*unused*/) { nextEnergyWritingStep_ = step; }); } return nullptr; } -template +template SignallerCallbackPtr ConstraintsElement::registerLoggingCallback() { return std::make_unique( - [this](Step step, Time){nextLogWritingStep_ = step; }); + [this](Step step, Time /*unused*/) { nextLogWritingStep_ = step; }); } //! Explicit template initialization @@ -218,4 +199,4 @@ template class ConstraintsElement; template class ConstraintsElement; //! @} -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/constraintelement.h b/src/gromacs/modularsimulator/constraintelement.h index 16ea138252..996642b708 100644 --- a/src/gromacs/modularsimulator/constraintelement.h +++ b/src/gromacs/modularsimulator/constraintelement.h @@ -64,91 +64,84 @@ class StatePropagatorData; * * @tparam variable The constraining variable */ -template +template class ConstraintsElement final : - public ISimulatorElement, + public ISimulatorElement, public IEnergySignallerClient, public ITrajectorySignallerClient, public ILoggingSignallerClient { - public: - //! Constructor - ConstraintsElement( - Constraints *constr, - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isMaster, - FILE *fplog, - const t_inputrec *inputrec, - const t_mdatoms *mdAtoms); +public: + //! Constructor + ConstraintsElement(Constraints* constr, + StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isMaster, + FILE* fplog, + const t_inputrec* inputrec, + const t_mdatoms* mdAtoms); - /*! \brief Register constraining function for step / time - * - * Under LF, this is expected to be run once, constraining positions and velocities - * Under VV, this is expected to be run twice, once contraining velocities only, - * a second time constraining positions and velocities. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; + /*! \brief Register constraining function for step / time + * + * Under LF, this is expected to be run once, constraining positions and velocities + * Under VV, this is expected to be run twice, once contraining velocities only, + * a second time constraining positions and velocities. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; - /*! \brief Performs inital constraining - * \todo Should this rather happen at grompp time? Right position of this operation is currently - * depending on the integrator algorithm (after domdec, before compute globals...), - * so doing this earlier would be much more stable! - */ - void elementSetup() override; - //! No element teardown needed - void elementTeardown() override {} + /*! \brief Performs inital constraining + * \todo Should this rather happen at grompp time? Right position of this operation is currently + * depending on the integrator algorithm (after domdec, before compute globals...), + * so doing this earlier would be much more stable! + */ + void elementSetup() override; + //! No element teardown needed + void elementTeardown() override {} - private: - //! The actual constraining computation - void apply( - Step step, - bool calculateVirial, - bool writeLog, - bool writeEnergy); +private: + //! The actual constraining computation + void apply(Step step, bool calculateVirial, bool writeLog, bool writeEnergy); - //! IEnergySignallerClient implementation - SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; - //! ITrajectorySignallerClient implementation - SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; - //! ILoggingSignallerClient implementation - SignallerCallbackPtr registerLoggingCallback() override; + //! IEnergySignallerClient implementation + SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; + //! ITrajectorySignallerClient implementation + SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; + //! ILoggingSignallerClient implementation + SignallerCallbackPtr registerLoggingCallback() override; - //! The next energy calculation step - Step nextVirialCalculationStep_; - //! The next energy writing step - Step nextEnergyWritingStep_; - //! The next logging step - Step nextLogWritingStep_; + //! The next energy calculation step + Step nextVirialCalculationStep_; + //! The next energy writing step + Step nextEnergyWritingStep_; + //! The next logging step + Step nextLogWritingStep_; - //! Whether we're master rank - const bool isMasterRank_; + //! Whether we're master rank + const bool isMasterRank_; - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - //! Pointer to the energy element - EnergyElement *energyElement_; - //! Pointer to the free energy perturbation element (only for initial constraining) - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + //! Pointer to the energy element + EnergyElement* energyElement_; + //! Pointer to the free energy perturbation element (only for initial constraining) + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; - // Access to ISimulator data - //! Handles constraints. - Constraints *constr_; - //! Handles logging. - FILE *fplog_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Atom parameters for this domain. - const t_mdatoms *mdAtoms_; + // Access to ISimulator data + //! Handles constraints. + Constraints* constr_; + //! Handles logging. + FILE* fplog_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Atom parameters for this domain. + const t_mdatoms* mdAtoms_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_CONSTRAINTELEMENT_H diff --git a/src/gromacs/modularsimulator/domdechelper.cpp b/src/gromacs/modularsimulator/domdechelper.cpp index 52d5710ad0..858fe0b09e 100644 --- a/src/gromacs/modularsimulator/domdechelper.cpp +++ b/src/gromacs/modularsimulator/domdechelper.cpp @@ -55,25 +55,24 @@ namespace gmx { -DomDecHelper::DomDecHelper( - bool isVerbose, - int verbosePrintInterval, - StatePropagatorData *statePropagatorData, - TopologyHolder *topologyHolder, - CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback, - int nstglobalcomm, - FILE *fplog, - t_commrec *cr, - const MDLogger &mdlog, - Constraints *constr, - t_inputrec *inputrec, - MDAtoms *mdAtoms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - t_forcerec *fr, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work) : +DomDecHelper::DomDecHelper(bool isVerbose, + int verbosePrintInterval, + StatePropagatorData* statePropagatorData, + TopologyHolder* topologyHolder, + CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback, + int nstglobalcomm, + FILE* fplog, + t_commrec* cr, + const MDLogger& mdlog, + Constraints* constr, + t_inputrec* inputrec, + MDAtoms* mdAtoms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + t_forcerec* fr, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work) : nextNSStep_(-1), isVerbose_(isVerbose), verbosePrintInterval_(verbosePrintInterval), @@ -100,22 +99,21 @@ DomDecHelper::DomDecHelper( void DomDecHelper::setup() { std::unique_ptr localState = statePropagatorData_->localState(); - t_state *globalState = statePropagatorData_->globalState(); - PaddedHostVector *forcePointer = statePropagatorData_->forcePointer(); + t_state* globalState = statePropagatorData_->globalState(); + PaddedHostVector* forcePointer = statePropagatorData_->forcePointer(); // constant choices for this call to dd_partition_system const bool verbose = false; const bool isMasterState = true; const int nstglobalcomm = 1; - gmx_wallcycle *wcycle = nullptr; + gmx_wallcycle* wcycle = nullptr; // Distribute the charge groups over the nodes from the master node - dd_partition_system( - fplog_, mdlog_, inputrec_->init_step, cr_, isMasterState, - nstglobalcomm, globalState, topologyHolder_->globalTopology(), - inputrec_, imdSession_, pull_work_, localState.get(), forcePointer, - mdAtoms_, topologyHolder_->localTopology_.get(), fr_, - vsite_, constr_, nrnb_, wcycle, verbose); + dd_partition_system(fplog_, mdlog_, inputrec_->init_step, cr_, isMasterState, nstglobalcomm, + globalState, topologyHolder_->globalTopology(), inputrec_, imdSession_, + pull_work_, localState.get(), forcePointer, mdAtoms_, + topologyHolder_->localTopology_.get(), fr_, vsite_, constr_, nrnb_, wcycle, + verbose); topologyHolder_->updateLocalTopology(); (*checkBondedInteractionsCallback_)(); statePropagatorData_->setLocalState(std::move(localState)); @@ -128,19 +126,17 @@ void DomDecHelper::run(Step step, Time gmx_unused time) return; } std::unique_ptr localState = statePropagatorData_->localState(); - t_state *globalState = statePropagatorData_->globalState(); - PaddedHostVector *forcePointer = statePropagatorData_->forcePointer(); + t_state* globalState = statePropagatorData_->globalState(); + PaddedHostVector* forcePointer = statePropagatorData_->forcePointer(); // constant choices for this call to dd_partition_system - const bool verbose = - isVerbose_ && - (step % verbosePrintInterval_ == 0 || step == inputrec_->init_step); - bool isMasterState = false; + const bool verbose = isVerbose_ && (step % verbosePrintInterval_ == 0 || step == inputrec_->init_step); + bool isMasterState = false; // Correct the new box if it is too skewed if (inputrecDynamicBox(inputrec_)) { - t_graph *graph = nullptr; + t_graph* graph = nullptr; if (correct_box(fplog_, step, localState->box, graph)) { isMasterState = true; @@ -152,13 +148,10 @@ void DomDecHelper::run(Step step, Time gmx_unused time) } // Distribute the charge groups over the nodes from the master node - dd_partition_system( - fplog_, mdlog_, step, cr_, isMasterState, - nstglobalcomm_, globalState, topologyHolder_->globalTopology(), - inputrec_, imdSession_, pull_work_, - localState.get(), forcePointer, mdAtoms_, - topologyHolder_->localTopology_.get(), fr_, - vsite_, constr_, nrnb_, wcycle_, verbose); + dd_partition_system(fplog_, mdlog_, step, cr_, isMasterState, nstglobalcomm_, globalState, + topologyHolder_->globalTopology(), inputrec_, imdSession_, pull_work_, + localState.get(), forcePointer, mdAtoms_, topologyHolder_->localTopology_.get(), + fr_, vsite_, constr_, nrnb_, wcycle_, verbose); topologyHolder_->updateLocalTopology(); (*checkBondedInteractionsCallback_)(); statePropagatorData_->setLocalState(std::move(localState)); @@ -167,8 +160,7 @@ void DomDecHelper::run(Step step, Time gmx_unused time) SignallerCallbackPtr DomDecHelper::registerNSCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time) - {this->nextNSStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->nextNSStep_ = step; }); } } // namespace gmx diff --git a/src/gromacs/modularsimulator/domdechelper.h b/src/gromacs/modularsimulator/domdechelper.h index 993984115c..181698f3cc 100644 --- a/src/gromacs/modularsimulator/domdechelper.h +++ b/src/gromacs/modularsimulator/domdechelper.h @@ -83,93 +83,91 @@ typedef std::unique_ptr CheckBondedInteractions * steps. This allows elements to be aware of any changes before * deciding what functionality they need to run. */ -class DomDecHelper final : - public INeighborSearchSignallerClient +class DomDecHelper final : public INeighborSearchSignallerClient { - public: - //! Constructor - DomDecHelper( - bool isVerbose, - int verbosePrintInterval, - StatePropagatorData *statePropagatorData, - TopologyHolder *topologyHolder, - CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback, - int nstglobalcomm, - FILE *fplog, - t_commrec *cr, - const MDLogger &mdlog, - Constraints *constr, - t_inputrec *inputrec, - MDAtoms *mdAtoms, - t_nrnb *nrnb, - gmx_wallcycle *wcycle, - t_forcerec *fr, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work); +public: + //! Constructor + DomDecHelper(bool isVerbose, + int verbosePrintInterval, + StatePropagatorData* statePropagatorData, + TopologyHolder* topologyHolder, + CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback, + int nstglobalcomm, + FILE* fplog, + t_commrec* cr, + const MDLogger& mdlog, + Constraints* constr, + t_inputrec* inputrec, + MDAtoms* mdAtoms, + t_nrnb* nrnb, + gmx_wallcycle* wcycle, + t_forcerec* fr, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work); - /*! \brief Run domain decomposition - * - * Does domain decomposition partitioning at neighbor searching steps - * - * @param step The step number - * @param time The time - */ - void run(Step step, Time time); + /*! \brief Run domain decomposition + * + * Does domain decomposition partitioning at neighbor searching steps + * + * @param step The step number + * @param time The time + */ + void run(Step step, Time time); - /*! \brief The initial domain decomposition partitioning - * - */ - void setup(); + /*! \brief The initial domain decomposition partitioning + * + */ + void setup(); - private: - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; +private: + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; - //! The next NS step - Step nextNSStep_; - //! Whether we're being verbose - const bool isVerbose_; - //! If we're being verbose, how often? - const int verbosePrintInterval_; - //! The global communication frequency - const int nstglobalcomm_; + //! The next NS step + Step nextNSStep_; + //! Whether we're being verbose + const bool isVerbose_; + //! If we're being verbose, how often? + const int verbosePrintInterval_; + //! The global communication frequency + const int nstglobalcomm_; - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - //! Pointer to the topology - TopologyHolder *topologyHolder_; - //! Pointer to the ComputeGlobalsHelper object - to ask for # of bonded interaction checking - CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback_; + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + //! Pointer to the topology + TopologyHolder* topologyHolder_; + //! Pointer to the ComputeGlobalsHelper object - to ask for # of bonded interaction checking + CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback_; - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - t_commrec *cr_; - //! Handles logging. - const MDLogger &mdlog_; - //! Handles constraints. - Constraints *constr_; - //! Contains user input mdp options. - t_inputrec *inputrec_; - //! Atom parameters for this domain. - MDAtoms *mdAtoms_; - //! Manages flop accounting. - t_nrnb *nrnb_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; - //! Parameters for force calculations. - t_forcerec *fr_; - //! Handles virtual sites. - gmx_vsite_t *vsite_; - //! The Interactive Molecular Dynamics session. - ImdSession *imdSession_; - //! The pull work object. - pull_t *pull_work_; + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + t_commrec* cr_; + //! Handles logging. + const MDLogger& mdlog_; + //! Handles constraints. + Constraints* constr_; + //! Contains user input mdp options. + t_inputrec* inputrec_; + //! Atom parameters for this domain. + MDAtoms* mdAtoms_; + //! Manages flop accounting. + t_nrnb* nrnb_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; + //! Parameters for force calculations. + t_forcerec* fr_; + //! Handles virtual sites. + gmx_vsite_t* vsite_; + //! The Interactive Molecular Dynamics session. + ImdSession* imdSession_; + //! The pull work object. + pull_t* pull_work_; }; //! \} -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_DOMDECHELPER_H diff --git a/src/gromacs/modularsimulator/energyelement.cpp b/src/gromacs/modularsimulator/energyelement.cpp index d2629ff25f..faa84fdc9c 100644 --- a/src/gromacs/modularsimulator/energyelement.cpp +++ b/src/gromacs/modularsimulator/energyelement.cpp @@ -72,21 +72,20 @@ namespace gmx { class Awh; -EnergyElement::EnergyElement( - StatePropagatorData *statePropagatorData, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - const gmx_mtop_t *globalTopology, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - gmx_enerdata_t *enerd, - gmx_ekindata_t *ekind, - const Constraints *constr, - FILE *fplog, - t_fcdata *fcd, - const MdModulesNotifier &mdModulesNotifier, - bool isMasterRank, - ObservablesHistory *observablesHistory, - StartingBehavior startingBehavior) : +EnergyElement::EnergyElement(StatePropagatorData* statePropagatorData, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + const gmx_mtop_t* globalTopology, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + gmx_enerdata_t* enerd, + gmx_ekindata_t* ekind, + const Constraints* constr, + FILE* fplog, + t_fcdata* fcd, + const MdModulesNotifier& mdModulesNotifier, + bool isMasterRank, + ObservablesHistory* observablesHistory, + StartingBehavior startingBehavior) : isMasterRank_(isMasterRank), energyWritingStep_(-1), energyCalculationStep_(-1), @@ -97,7 +96,6 @@ EnergyElement::EnergyElement( pressureStep_(-1), needToSumEkinhOld_(false), startingBehavior_(startingBehavior), - dummyLegacyState_(), statePropagatorData_(statePropagatorData), freeEnergyPerturbationElement_(freeEnergyPerturbationElement), vRescaleThermostat_(nullptr), @@ -122,12 +120,11 @@ EnergyElement::EnergyElement( if (freeEnergyPerturbationElement_) { - dummyLegacyState_.flags = (1u << estFEPSTATE); + dummyLegacyState_.flags = (1U << estFEPSTATE); } } -void EnergyElement::scheduleTask( - Step step, Time time, const RegisterRunFunctionPtr ®isterRunFunction) +void EnergyElement::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { if (!isMasterRank_) { @@ -138,17 +135,15 @@ void EnergyElement::scheduleTask( auto isFreeEnergyCalculationStep = freeEnergyCalculationStep_ == step; if (isEnergyCalculationStep || writeEnergy) { - (*registerRunFunction)( - std::make_unique( - [this, time, isEnergyCalculationStep, isFreeEnergyCalculationStep]() { - doStep(time, isEnergyCalculationStep, isFreeEnergyCalculationStep); - })); + (*registerRunFunction)(std::make_unique( + [this, time, isEnergyCalculationStep, isFreeEnergyCalculationStep]() { + doStep(time, isEnergyCalculationStep, isFreeEnergyCalculationStep); + })); } else { - (*registerRunFunction)( - std::make_unique( - [this]() { energyOutput_->recordNonEnergyStep(); })); + (*registerRunFunction)(std::make_unique( + [this]() { energyOutput_->recordNonEnergyStep(); })); } } @@ -160,32 +155,27 @@ void EnergyElement::elementTeardown() } } -void EnergyElement::trajectoryWriterSetup(gmx_mdoutf *outf) +void EnergyElement::trajectoryWriterSetup(gmx_mdoutf* outf) { - pull_t *pull_work = nullptr; - energyOutput_ = std::make_unique( - mdoutf_get_fp_ene(outf), top_global_, - inputrec_, pull_work, mdoutf_get_fp_dhdl(outf), false, - mdModulesNotifier_); + pull_t* pull_work = nullptr; + energyOutput_ = std::make_unique(mdoutf_get_fp_ene(outf), top_global_, inputrec_, + pull_work, mdoutf_get_fp_dhdl(outf), false, + mdModulesNotifier_); if (!isMasterRank_) { return; } - initializeEnergyHistory( - startingBehavior_, observablesHistory_, energyOutput_.get()); + initializeEnergyHistory(startingBehavior_, observablesHistory_, energyOutput_.get()); // TODO: This probably doesn't really belong here... // but we have all we need in this element, // so we'll leave it here for now! - double io = compute_io(inputrec_, top_global_->natoms, *groups_, - energyOutput_->numEnergyTerms(), 1); + double io = compute_io(inputrec_, top_global_->natoms, *groups_, energyOutput_->numEnergyTerms(), 1); if ((io > 2000) && isMasterRank_) { - fprintf(stderr, - "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", - io); + fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io); } if (!inputrec_->bContinuation) { @@ -206,8 +196,8 @@ ITrajectoryWriterCallbackPtr EnergyElement::registerTrajectoryWriterCallback(Tra if (event == TrajectoryEvent::EnergyWritingStep && isMasterRank_) { return std::make_unique( - [this](gmx_mdoutf *mdoutf, Step step, Time time, bool writeTrajectory, bool writeLog) - {write(mdoutf, step, time, writeTrajectory, writeLog); }); + [this](gmx_mdoutf* mdoutf, Step step, Time time, bool writeTrajectory, + bool writeLog) { write(mdoutf, step, time, writeTrajectory, writeLog); }); } return nullptr; } @@ -217,7 +207,7 @@ SignallerCallbackPtr EnergyElement::registerTrajectorySignallerCallback(gmx::Tra if (event == TrajectoryEvent::EnergyWritingStep && isMasterRank_) { return std::make_unique( - [this](Step step, Time){energyWritingStep_ = step; }); + [this](Step step, Time /*unused*/) { energyWritingStep_ = step; }); } return nullptr; } @@ -227,20 +217,17 @@ SignallerCallbackPtr EnergyElement::registerEnergyCallback(EnergySignallerEvent if (event == EnergySignallerEvent::EnergyCalculationStep && isMasterRank_) { return std::make_unique( - [this](Step step, Time) {energyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { energyCalculationStep_ = step; }); } if (event == EnergySignallerEvent::FreeEnergyCalculationStep && isMasterRank_) { return std::make_unique( - [this](Step step, Time){freeEnergyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { freeEnergyCalculationStep_ = step; }); } return nullptr; } -void EnergyElement::doStep( - Time time, - bool isEnergyCalculationStep, - bool isFreeEnergyCalculationStep) +void EnergyElement::doStep(Time time, bool isEnergyCalculationStep, bool isFreeEnergyCalculationStep) { enerd_->term[F_ETOT] = enerd_->term[F_EPOT] + enerd_->term[F_EKIN]; if (vRescaleThermostat_) @@ -259,33 +246,30 @@ void EnergyElement::doStep( } if (integratorHasConservedEnergyQuantity(inputrec_)) { - enerd_->term[F_ECONSERVED] = enerd_->term[F_ETOT] + - NPT_energy(inputrec_, &dummyLegacyState_, nullptr); + enerd_->term[F_ECONSERVED] = + enerd_->term[F_ETOT] + NPT_energy(inputrec_, &dummyLegacyState_, nullptr); } - energyOutput_->addDataAtEnergyStep( - isFreeEnergyCalculationStep, isEnergyCalculationStep, - time, mdAtoms_->mdatoms()->tmass, enerd_, &dummyLegacyState_, - inputrec_->fepvals, inputrec_->expandedvals, - statePropagatorData_->constPreviousBox(), - shakeVirial_, forceVirial_, totalVirial_, pressure_, - ekind_, muTot_, constr_); + energyOutput_->addDataAtEnergyStep(isFreeEnergyCalculationStep, isEnergyCalculationStep, time, + mdAtoms_->mdatoms()->tmass, enerd_, &dummyLegacyState_, + inputrec_->fepvals, inputrec_->expandedvals, + statePropagatorData_->constPreviousBox(), shakeVirial_, + forceVirial_, totalVirial_, pressure_, ekind_, muTot_, constr_); } -void EnergyElement::write(gmx_mdoutf *outf, Step step, Time time, bool writeTrajectory, bool writeLog) +void EnergyElement::write(gmx_mdoutf* outf, Step step, Time time, bool writeTrajectory, bool writeLog) { if (writeLog) { energyOutput_->printHeader(fplog_, step, time); } - bool do_dr = do_per_step(step, inputrec_->nstdisreout); - bool do_or = do_per_step(step, inputrec_->nstorireout); + bool do_dr = do_per_step(step, inputrec_->nstdisreout); + bool do_or = do_per_step(step, inputrec_->nstorireout); // energyOutput_->printAnnealingTemperatures(writeLog ? fplog_ : nullptr, groups_, &(inputrec_->opts)); - Awh *awh = nullptr; - energyOutput_->printStepToEnergyFile( - mdoutf_get_fp_ene(outf), writeTrajectory, do_dr, do_or, - writeLog ? fplog_ : nullptr, step, time, fcd_, awh); + Awh* awh = nullptr; + energyOutput_->printStepToEnergyFile(mdoutf_get_fp_ene(outf), writeTrajectory, do_dr, do_or, + writeLog ? fplog_ : nullptr, step, time, fcd_, awh); } void EnergyElement::addToForceVirial(const tensor virial, Step step) @@ -376,7 +360,7 @@ bool* EnergyElement::needToSumEkinhOld() return &needToSumEkinhOld_; } -void EnergyElement::writeCheckpoint(t_state gmx_unused *localState, t_state *globalState) +void EnergyElement::writeCheckpoint(t_state gmx_unused* localState, t_state* globalState) { if (isMasterRank_) { @@ -393,10 +377,9 @@ void EnergyElement::writeCheckpoint(t_state gmx_unused *localState, t_state *glo } } -void EnergyElement::initializeEnergyHistory( - StartingBehavior startingBehavior, - ObservablesHistory *observablesHistory, - EnergyOutput *energyOutput) +void EnergyElement::initializeEnergyHistory(StartingBehavior startingBehavior, + ObservablesHistory* observablesHistory, + EnergyOutput* energyOutput) { if (startingBehavior != StartingBehavior::NewSimulation) { @@ -438,21 +421,21 @@ void EnergyElement::initializeEnergyHistory( energyOutput->fillEnergyHistory(observablesHistory->energyHistory.get()); } -void EnergyElement::setVRescaleThermostat(const gmx::VRescaleThermostat *vRescaleThermostat) +void EnergyElement::setVRescaleThermostat(const gmx::VRescaleThermostat* vRescaleThermostat) { vRescaleThermostat_ = vRescaleThermostat; if (vRescaleThermostat_) { - dummyLegacyState_.flags |= (1u << estTHERM_INT); + dummyLegacyState_.flags |= (1U << estTHERM_INT); } } -void EnergyElement::setParrinelloRahamnBarostat(const gmx::ParrinelloRahmanBarostat *parrinelloRahmanBarostat) +void EnergyElement::setParrinelloRahamnBarostat(const gmx::ParrinelloRahmanBarostat* parrinelloRahmanBarostat) { parrinelloRahmanBarostat_ = parrinelloRahmanBarostat; if (parrinelloRahmanBarostat_) { - dummyLegacyState_.flags |= (1u << estBOX) | (1u << estBOXV); + dummyLegacyState_.flags |= (1U << estBOX) | (1U << estBOXV); } } diff --git a/src/gromacs/modularsimulator/energyelement.h b/src/gromacs/modularsimulator/energyelement.h index f2bf0e990c..a9440faae0 100644 --- a/src/gromacs/modularsimulator/energyelement.h +++ b/src/gromacs/modularsimulator/energyelement.h @@ -89,268 +89,256 @@ struct MdModulesNotifier; * dipole vector, and the legacy energy data structures. */ class EnergyElement final : - public ISimulatorElement, - public ITrajectoryWriterClient, - public ITrajectorySignallerClient, - public IEnergySignallerClient, - public ICheckpointHelperClient + public ISimulatorElement, + public ITrajectoryWriterClient, + public ITrajectorySignallerClient, + public IEnergySignallerClient, + public ICheckpointHelperClient { - public: - //! Constructor - EnergyElement( - StatePropagatorData *statePropagatorData, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - const gmx_mtop_t *globalTopology, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - gmx_enerdata_t *enerd, - gmx_ekindata_t *ekind, - const Constraints *constr, - FILE *fplog, - t_fcdata *fcd, - const MdModulesNotifier &mdModulesNotifier, - bool isMasterRank, - ObservablesHistory *observablesHistory, - StartingBehavior startingBehavior); - - /*! \brief Register run function for step / time - * - * This needs to be called when the energies are at a full time step. - * Positioning this element is the responsibility of the programmer. - * - * This is also the place at which the current state becomes the previous - * state. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! No element setup needed - void elementSetup() override {} - - /*! \brief Final output - * - * Prints the averages to log. - */ - void elementTeardown() override; - - /*! \brief Add contribution to force virial - * - * This automatically resets the tensor if the step is higher - * than the current step, starting the tensor calculation for - * a new step at zero. Otherwise, it adds the new contribution - * to the existing virial. - */ - void addToForceVirial(const tensor virial, Step step); - - /*! \brief Add contribution to constraint virial - * - * This automatically resets the tensor if the step is higher - * than the current step, starting the tensor calculation for - * a new step at zero. Otherwise, it adds the new contribution - * to the existing virial. - */ - void addToConstraintVirial(const tensor virial, Step step); - - /*! \brief Get pointer to force virial tensor - * - * Allows access to the raw pointer to the tensor. - */ - rvec* forceVirial(Step step); - - /*! \brief Get pointer to constraint virial tensor - * - * Allows access to the raw pointer to the tensor. - */ - rvec* constraintVirial(Step step); - - /*! \brief Get pointer to total virial tensor - * - * Allows access to the raw pointer to the tensor. - */ - rvec* totalVirial(Step step); - - /*! \brief Get pointer to pressure tensor - * - * Allows access to the raw pointer to the tensor. - */ - rvec* pressure(Step step); - - /*! \brief Get pointer to mu_tot - * - * Allows access to the raw pointer to the dipole vector. - */ - real* muTot(); - - /*! \brief Get pointer to energy structure - * - */ - gmx_enerdata_t* enerdata(); - - /*! \brief Get pointer to kinetic energy structure - * - */ - gmx_ekindata_t* ekindata(); - - /*! \brief Get pointer to needToSumEkinhOld - * - */ - bool* needToSumEkinhOld(); - - /*! \brief set vrescale thermostat - * - * This allows to set a pointer to the vrescale thermostat used to - * print the thermostat integral. - * TODO: This should be made obsolete my a more modular energy element - */ - void setVRescaleThermostat(const VRescaleThermostat* vRescaleThermostat); - - /*! \brief set Parrinello-Rahman barostat - * - * This allows to set a pointer to the Parrinello-Rahman barostat used to - * print the box velocities. - * TODO: This should be made obsolete my a more modular energy element - */ - void setParrinelloRahamnBarostat(const ParrinelloRahmanBarostat* parrinelloRahmanBarostat); - - /*! \brief Initialize energy history - * - * Kept as a static function to allow usage from legacy code - * \todo Make member function once legacy use is not needed anymore - */ - static void initializeEnergyHistory( - StartingBehavior startingBehavior, - ObservablesHistory *observablesHistory, - EnergyOutput *energyOutput); - - private: - /*! \brief Setup (needs file pointer) - * - * ITrajectoryWriterClient implementation. - * - * Initializes the EnergyOutput object, and does some logging output. - * - * @param mdoutf File pointer - */ - void trajectoryWriterSetup(gmx_mdoutf *mdoutf) override; - //! No trajectory writer teardown needed - void trajectoryWriterTeardown(gmx_mdoutf gmx_unused *outf) override {} - - //! ITrajectoryWriterClient implementation. - SignallerCallbackPtr - registerTrajectorySignallerCallback(TrajectoryEvent event) override; - //! ITrajectorySignallerClient implementation - ITrajectoryWriterCallbackPtr - registerTrajectoryWriterCallback(TrajectoryEvent event) override; - //! IEnergySignallerClient implementation - SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; - - /*! \brief Save data at energy steps - * - * @param time The current time - * @param isEnergyCalculationStep Whether the current step is an energy calculation step - * @param isFreeEnergyCalculationStep Whether the current step is a free energy calculation step - */ - void doStep( - Time time, - bool isEnergyCalculationStep, - bool isFreeEnergyCalculationStep); - - /*! \brief Write to energy trajectory - * - * This is only called by master - writes energy to trajectory and to log. - */ - void write( - gmx_mdoutf *outf, - Step step, Time time, - bool writeTrajectory, bool writeLog); - - //! ICheckpointHelperClient implementation - void writeCheckpoint(t_state *localState, t_state *globalState) override; - - /* - * Data owned by EnergyElement - */ - //! The energy output object - std::unique_ptr energyOutput_; - - //! Whether this is the master rank - const bool isMasterRank_; - //! The next communicated energy writing step - Step energyWritingStep_; - //! The next communicated energy calculation step - Step energyCalculationStep_; - //! The next communicated free energy calculation step - Step freeEnergyCalculationStep_; - - //! The force virial tensor - tensor forceVirial_; - //! The constraint virial tensor - tensor shakeVirial_; - //! The total virial tensor - tensor totalVirial_; - //! The pressure tensor - tensor pressure_; - //! The total dipole moment - rvec muTot_; - - //! The step number of the current force virial tensor - Step forceVirialStep_; - //! The step number of the current constraint virial tensor - Step shakeVirialStep_; - //! The step number of the current total virial tensor - Step totalVirialStep_; - //! The step number of the current pressure tensor - Step pressureStep_; - - //! Whether ekinh_old needs to be summed up (set by compute globals) - bool needToSumEkinhOld_; - - //! Describes how the simulation (re)starts - const StartingBehavior startingBehavior_; - - //! Legacy state object used to communicate with energy output - t_state dummyLegacyState_; - - /* - * Pointers to Simulator data - */ - //! Pointer to the state propagator data - StatePropagatorData *statePropagatorData_; - //! Pointer to the free energy perturbation element - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; - //! Pointer to the vrescale thermostat - const VRescaleThermostat *vRescaleThermostat_; - //! Pointer to the Parrinello-Rahman barostat - const ParrinelloRahmanBarostat *parrinelloRahmanBarostat_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Full system topology. - const gmx_mtop_t *top_global_; - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; - //! Energy data structure - gmx_enerdata_t *enerd_; - //! Kinetic energy data - gmx_ekindata_t *ekind_; - //! Handles constraints. - const Constraints *constr_; - //! Handles logging. - FILE *fplog_; - //! Helper struct for force calculations. - t_fcdata *fcd_; - //! Notification to MD modules - const MdModulesNotifier &mdModulesNotifier_; - //! Global topology groups - const SimulationGroups *groups_; - //! History of simulation observables. - ObservablesHistory *observablesHistory_; +public: + //! Constructor + EnergyElement(StatePropagatorData* statePropagatorData, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + const gmx_mtop_t* globalTopology, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + gmx_enerdata_t* enerd, + gmx_ekindata_t* ekind, + const Constraints* constr, + FILE* fplog, + t_fcdata* fcd, + const MdModulesNotifier& mdModulesNotifier, + bool isMasterRank, + ObservablesHistory* observablesHistory, + StartingBehavior startingBehavior); + + /*! \brief Register run function for step / time + * + * This needs to be called when the energies are at a full time step. + * Positioning this element is the responsibility of the programmer. + * + * This is also the place at which the current state becomes the previous + * state. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! No element setup needed + void elementSetup() override {} + + /*! \brief Final output + * + * Prints the averages to log. + */ + void elementTeardown() override; + + /*! \brief Add contribution to force virial + * + * This automatically resets the tensor if the step is higher + * than the current step, starting the tensor calculation for + * a new step at zero. Otherwise, it adds the new contribution + * to the existing virial. + */ + void addToForceVirial(const tensor virial, Step step); + + /*! \brief Add contribution to constraint virial + * + * This automatically resets the tensor if the step is higher + * than the current step, starting the tensor calculation for + * a new step at zero. Otherwise, it adds the new contribution + * to the existing virial. + */ + void addToConstraintVirial(const tensor virial, Step step); + + /*! \brief Get pointer to force virial tensor + * + * Allows access to the raw pointer to the tensor. + */ + rvec* forceVirial(Step step); + + /*! \brief Get pointer to constraint virial tensor + * + * Allows access to the raw pointer to the tensor. + */ + rvec* constraintVirial(Step step); + + /*! \brief Get pointer to total virial tensor + * + * Allows access to the raw pointer to the tensor. + */ + rvec* totalVirial(Step step); + + /*! \brief Get pointer to pressure tensor + * + * Allows access to the raw pointer to the tensor. + */ + rvec* pressure(Step step); + + /*! \brief Get pointer to mu_tot + * + * Allows access to the raw pointer to the dipole vector. + */ + real* muTot(); + + /*! \brief Get pointer to energy structure + * + */ + gmx_enerdata_t* enerdata(); + + /*! \brief Get pointer to kinetic energy structure + * + */ + gmx_ekindata_t* ekindata(); + + /*! \brief Get pointer to needToSumEkinhOld + * + */ + bool* needToSumEkinhOld(); + + /*! \brief set vrescale thermostat + * + * This allows to set a pointer to the vrescale thermostat used to + * print the thermostat integral. + * TODO: This should be made obsolete my a more modular energy element + */ + void setVRescaleThermostat(const VRescaleThermostat* vRescaleThermostat); + + /*! \brief set Parrinello-Rahman barostat + * + * This allows to set a pointer to the Parrinello-Rahman barostat used to + * print the box velocities. + * TODO: This should be made obsolete my a more modular energy element + */ + void setParrinelloRahamnBarostat(const ParrinelloRahmanBarostat* parrinelloRahmanBarostat); + + /*! \brief Initialize energy history + * + * Kept as a static function to allow usage from legacy code + * \todo Make member function once legacy use is not needed anymore + */ + static void initializeEnergyHistory(StartingBehavior startingBehavior, + ObservablesHistory* observablesHistory, + EnergyOutput* energyOutput); + +private: + /*! \brief Setup (needs file pointer) + * + * ITrajectoryWriterClient implementation. + * + * Initializes the EnergyOutput object, and does some logging output. + * + * @param mdoutf File pointer + */ + void trajectoryWriterSetup(gmx_mdoutf* mdoutf) override; + //! No trajectory writer teardown needed + void trajectoryWriterTeardown(gmx_mdoutf gmx_unused* outf) override {} + + //! ITrajectoryWriterClient implementation. + SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; + //! ITrajectorySignallerClient implementation + ITrajectoryWriterCallbackPtr registerTrajectoryWriterCallback(TrajectoryEvent event) override; + //! IEnergySignallerClient implementation + SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; + + /*! \brief Save data at energy steps + * + * @param time The current time + * @param isEnergyCalculationStep Whether the current step is an energy calculation step + * @param isFreeEnergyCalculationStep Whether the current step is a free energy calculation step + */ + void doStep(Time time, bool isEnergyCalculationStep, bool isFreeEnergyCalculationStep); + + /*! \brief Write to energy trajectory + * + * This is only called by master - writes energy to trajectory and to log. + */ + void write(gmx_mdoutf* outf, Step step, Time time, bool writeTrajectory, bool writeLog); + + //! ICheckpointHelperClient implementation + void writeCheckpoint(t_state* localState, t_state* globalState) override; + + /* + * Data owned by EnergyElement + */ + //! The energy output object + std::unique_ptr energyOutput_; + + //! Whether this is the master rank + const bool isMasterRank_; + //! The next communicated energy writing step + Step energyWritingStep_; + //! The next communicated energy calculation step + Step energyCalculationStep_; + //! The next communicated free energy calculation step + Step freeEnergyCalculationStep_; + + //! The force virial tensor + tensor forceVirial_; + //! The constraint virial tensor + tensor shakeVirial_; + //! The total virial tensor + tensor totalVirial_; + //! The pressure tensor + tensor pressure_; + //! The total dipole moment + rvec muTot_; + + //! The step number of the current force virial tensor + Step forceVirialStep_; + //! The step number of the current constraint virial tensor + Step shakeVirialStep_; + //! The step number of the current total virial tensor + Step totalVirialStep_; + //! The step number of the current pressure tensor + Step pressureStep_; + + //! Whether ekinh_old needs to be summed up (set by compute globals) + bool needToSumEkinhOld_; + + //! Describes how the simulation (re)starts + const StartingBehavior startingBehavior_; + + //! Legacy state object used to communicate with energy output + t_state dummyLegacyState_; + + /* + * Pointers to Simulator data + */ + //! Pointer to the state propagator data + StatePropagatorData* statePropagatorData_; + //! Pointer to the free energy perturbation element + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; + //! Pointer to the vrescale thermostat + const VRescaleThermostat* vRescaleThermostat_; + //! Pointer to the Parrinello-Rahman barostat + const ParrinelloRahmanBarostat* parrinelloRahmanBarostat_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Full system topology. + const gmx_mtop_t* top_global_; + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; + //! Energy data structure + gmx_enerdata_t* enerd_; + //! Kinetic energy data + gmx_ekindata_t* ekind_; + //! Handles constraints. + const Constraints* constr_; + //! Handles logging. + FILE* fplog_; + //! Helper struct for force calculations. + t_fcdata* fcd_; + //! Notification to MD modules + const MdModulesNotifier& mdModulesNotifier_; + //! Global topology groups + const SimulationGroups* groups_; + //! History of simulation observables. + ObservablesHistory* observablesHistory_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_ENERGYELEMENT_MICROSTATE_H diff --git a/src/gromacs/modularsimulator/forceelement.cpp b/src/gromacs/modularsimulator/forceelement.cpp index 85f2c7ffff..ea8951735f 100644 --- a/src/gromacs/modularsimulator/forceelement.cpp +++ b/src/gromacs/modularsimulator/forceelement.cpp @@ -60,24 +60,23 @@ struct t_graph; namespace gmx { -ForceElement::ForceElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isDynamicBox, - FILE *fplog, - const t_commrec *cr, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - t_forcerec *fr, - t_fcdata *fcd, - gmx_wallcycle *wcycle, - MdrunScheduleWorkload *runScheduleWork, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work, - gmx_enfrot *enforcedRotation) : +ForceElement::ForceElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isDynamicBox, + FILE* fplog, + const t_commrec* cr, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + t_forcerec* fr, + t_fcdata* fcd, + gmx_wallcycle* wcycle, + MdrunScheduleWorkload* runScheduleWork, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work, + gmx_enfrot* enforcedRotation) : nextNSStep_(-1), nextEnergyCalculationStep_(-1), nextVirialCalculationStep_(-1), @@ -106,66 +105,55 @@ ForceElement::ForceElement( lambda_.fill(0); } -void ForceElement::scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) +void ForceElement::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { - unsigned int flags = ( - GMX_FORCE_STATECHANGED | - GMX_FORCE_ALLFORCES | - (isDynamicBox_ ? GMX_FORCE_DYNAMICBOX : 0) | - (nextVirialCalculationStep_ == step ? GMX_FORCE_VIRIAL : 0) | - (nextEnergyCalculationStep_ == step ? GMX_FORCE_ENERGY : 0) | - (nextFreeEnergyCalculationStep_ == step ? GMX_FORCE_DHDL : 0) | - (nextNSStep_ == step ? GMX_FORCE_NS : 0)); - - (*registerRunFunction)( - std::make_unique( - [this, step, time, flags]() - {run(step, time, flags); })); + unsigned int flags = + (GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES | (isDynamicBox_ ? GMX_FORCE_DYNAMICBOX : 0) + | (nextVirialCalculationStep_ == step ? GMX_FORCE_VIRIAL : 0) + | (nextEnergyCalculationStep_ == step ? GMX_FORCE_ENERGY : 0) + | (nextFreeEnergyCalculationStep_ == step ? GMX_FORCE_DHDL : 0) + | (nextNSStep_ == step ? GMX_FORCE_NS : 0)); + + (*registerRunFunction)(std::make_unique( + [this, step, time, flags]() { run(step, time, flags); })); } void ForceElement::elementSetup() { GMX_ASSERT(localTopology_, "Setup called before local topology was set."); - } void ForceElement::run(Step step, Time time, unsigned int flags) { // Disabled functionality - Awh *awh = nullptr; - gmx_edsam *ed = nullptr; - gmx_multisim_t *ms = nullptr; - t_graph *graph = nullptr; + Awh* awh = nullptr; + gmx_edsam* ed = nullptr; + gmx_multisim_t* ms = nullptr; + t_graph* graph = nullptr; /* The coordinates (x) are shifted (to get whole molecules) * in do_force. * This is parallelized as well, and does communication too. * Check comments in sim_util.c */ - auto x = statePropagatorData_->positionsView(); - auto forces = statePropagatorData_->forcesView(); - auto box = statePropagatorData_->constBox(); - history_t *hist = nullptr; // disabled + auto x = statePropagatorData_->positionsView(); + auto forces = statePropagatorData_->forcesView(); + auto box = statePropagatorData_->constBox(); + history_t* hist = nullptr; // disabled - tensor force_vir = {{0}}; + tensor force_vir = { { 0 } }; // TODO: Make lambda const (needs some adjustments in lower force routines) - ArrayRef lambda = freeEnergyPerturbationElement_ ? - freeEnergyPerturbationElement_->lambdaView() : lambda_; - - do_force(fplog_, cr_, ms, inputrec_, awh, enforcedRotation_, imdSession_, - pull_work_, - step, nrnb_, wcycle_, localTopology_, - box, x, hist, - forces, force_vir, mdAtoms_->mdatoms(), energyElement_->enerdata(), fcd_, - lambda, graph, - fr_, runScheduleWork_, vsite_, energyElement_->muTot(), time, ed, - static_cast(flags), ddBalanceRegionHandler_); + ArrayRef lambda = + freeEnergyPerturbationElement_ ? freeEnergyPerturbationElement_->lambdaView() : lambda_; + + do_force(fplog_, cr_, ms, inputrec_, awh, enforcedRotation_, imdSession_, pull_work_, step, + nrnb_, wcycle_, localTopology_, box, x, hist, forces, force_vir, mdAtoms_->mdatoms(), + energyElement_->enerdata(), fcd_, lambda, graph, fr_, runScheduleWork_, vsite_, + energyElement_->muTot(), time, ed, static_cast(flags), ddBalanceRegionHandler_); energyElement_->addToForceVirial(force_vir, step); } -void ForceElement::setTopology(const gmx_localtop_t *top) +void ForceElement::setTopology(const gmx_localtop_t* top) { localTopology_ = top; } @@ -173,29 +161,26 @@ void ForceElement::setTopology(const gmx_localtop_t *top) SignallerCallbackPtr ForceElement::registerNSCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time) - {this->nextNSStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->nextNSStep_ = step; }); } -SignallerCallbackPtr ForceElement:: - registerEnergyCallback(EnergySignallerEvent event) +SignallerCallbackPtr ForceElement::registerEnergyCallback(EnergySignallerEvent event) { if (event == EnergySignallerEvent::EnergyCalculationStep) { return std::make_unique( - [this](Step step, Time) - {nextEnergyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextEnergyCalculationStep_ = step; }); } if (event == EnergySignallerEvent::VirialCalculationStep) { return std::make_unique( - [this](Step step, Time){nextVirialCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextVirialCalculationStep_ = step; }); } if (event == EnergySignallerEvent::FreeEnergyCalculationStep) { return std::make_unique( - [this](Step step, Time){nextFreeEnergyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextFreeEnergyCalculationStep_ = step; }); } return nullptr; } -} // namespace std +} // namespace gmx diff --git a/src/gromacs/modularsimulator/forceelement.h b/src/gromacs/modularsimulator/forceelement.h index c4fa6876e0..a244bc432c 100644 --- a/src/gromacs/modularsimulator/forceelement.h +++ b/src/gromacs/modularsimulator/forceelement.h @@ -74,118 +74,115 @@ class StatePropagatorData; * The force element manages the call to do_force(...) */ class ForceElement final : - public ISimulatorElement, - public ITopologyHolderClient, - public INeighborSearchSignallerClient, - public IEnergySignallerClient + public ISimulatorElement, + public ITopologyHolderClient, + public INeighborSearchSignallerClient, + public IEnergySignallerClient { - public: - //! Constructor - ForceElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isDynamicBox, - FILE *fplog, - const t_commrec *cr, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - t_forcerec *fr, - t_fcdata *fcd, - gmx_wallcycle *wcycle, - MdrunScheduleWorkload *runScheduleWork, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work, - gmx_enfrot *enforcedRotation); - - /*! \brief Register force calculation for step / time - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! Check that we got the local topology - void elementSetup() override; - //! No element teardown needed - void elementTeardown() override {} - - private: - //! ITopologyHolderClient implementation - void setTopology(const gmx_localtop_t *top) override; - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; - //! IEnergySignallerClient implementation - SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; - //! The actual do_force call - void run(Step step, Time time, unsigned int flags); - - //! The next NS step - Step nextNSStep_; - //! The next energy calculation step - Step nextEnergyCalculationStep_; - //! The next energy calculation step - Step nextVirialCalculationStep_; - //! The next free energy calculation step - Step nextFreeEnergyCalculationStep_; - - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - //! Pointer to the energy element - EnergyElement *energyElement_; - //! Pointer to the free energy perturbation element - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; - - //! The local topology - updated by Topology via Client system - const gmx_localtop_t *localTopology_; - - //! Whether we're having a dynamic box - const bool isDynamicBox_; - - //! DD / DLB helper object - const DDBalanceRegionHandler ddBalanceRegionHandler_; - - /* \brief The FEP lambda vector - * - * Used if FEP is off, since do_force - * requires lambda to be allocated anyway - */ - std::array lambda_; - - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - const t_commrec *cr_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; - //! Manages flop accounting. - t_nrnb *nrnb_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; - //! Parameters for force calculations. - t_forcerec *fr_; - //! Handles virtual sites. - gmx_vsite_t *vsite_; - //! The Interactive Molecular Dynamics session. - ImdSession *imdSession_; - //! The pull work object. - pull_t *pull_work_; - //! Helper struct for force calculations. - t_fcdata *fcd_; - //! Schedule of work for each MD step for this task. - MdrunScheduleWorkload *runScheduleWork_; - //! Handles enforced rotation. - gmx_enfrot *enforcedRotation_; +public: + //! Constructor + ForceElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isDynamicBox, + FILE* fplog, + const t_commrec* cr, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + t_forcerec* fr, + t_fcdata* fcd, + gmx_wallcycle* wcycle, + MdrunScheduleWorkload* runScheduleWork, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work, + gmx_enfrot* enforcedRotation); + + /*! \brief Register force calculation for step / time + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! Check that we got the local topology + void elementSetup() override; + //! No element teardown needed + void elementTeardown() override {} + +private: + //! ITopologyHolderClient implementation + void setTopology(const gmx_localtop_t* top) override; + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; + //! IEnergySignallerClient implementation + SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; + //! The actual do_force call + void run(Step step, Time time, unsigned int flags); + + //! The next NS step + Step nextNSStep_; + //! The next energy calculation step + Step nextEnergyCalculationStep_; + //! The next energy calculation step + Step nextVirialCalculationStep_; + //! The next free energy calculation step + Step nextFreeEnergyCalculationStep_; + + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + //! Pointer to the energy element + EnergyElement* energyElement_; + //! Pointer to the free energy perturbation element + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; + + //! The local topology - updated by Topology via Client system + const gmx_localtop_t* localTopology_; + + //! Whether we're having a dynamic box + const bool isDynamicBox_; + + //! DD / DLB helper object + const DDBalanceRegionHandler ddBalanceRegionHandler_; + + /* \brief The FEP lambda vector + * + * Used if FEP is off, since do_force + * requires lambda to be allocated anyway + */ + std::array lambda_; + + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + const t_commrec* cr_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; + //! Manages flop accounting. + t_nrnb* nrnb_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; + //! Parameters for force calculations. + t_forcerec* fr_; + //! Handles virtual sites. + gmx_vsite_t* vsite_; + //! The Interactive Molecular Dynamics session. + ImdSession* imdSession_; + //! The pull work object. + pull_t* pull_work_; + //! Helper struct for force calculations. + t_fcdata* fcd_; + //! Schedule of work for each MD step for this task. + MdrunScheduleWorkload* runScheduleWork_; + //! Handles enforced rotation. + gmx_enfrot* enforcedRotation_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_FORCEELEMENT_H diff --git a/src/gromacs/modularsimulator/freeenergyperturbationelement.cpp b/src/gromacs/modularsimulator/freeenergyperturbationelement.cpp index 1a30754dc6..e8f1d56bba 100644 --- a/src/gromacs/modularsimulator/freeenergyperturbationelement.cpp +++ b/src/gromacs/modularsimulator/freeenergyperturbationelement.cpp @@ -51,10 +51,9 @@ namespace gmx { -FreeEnergyPerturbationElement::FreeEnergyPerturbationElement( - FILE *fplog, - const t_inputrec *inputrec, - MDAtoms *mdAtoms) : +FreeEnergyPerturbationElement::FreeEnergyPerturbationElement(FILE* fplog, + const t_inputrec* inputrec, + MDAtoms* mdAtoms) : lambda_(), lambda0_(), currentFEPState_(0), @@ -65,33 +64,25 @@ FreeEnergyPerturbationElement::FreeEnergyPerturbationElement( { lambda_.fill(0); lambda0_.fill(0); - initialize_lambdas( - fplog_, *inputrec_, true, - ¤tFEPState_, lambda_, - lambda0_.data()); + initialize_lambdas(fplog_, *inputrec_, true, ¤tFEPState_, lambda_, lambda0_.data()); update_mdatoms(mdAtoms_->mdatoms(), lambda_[efptMASS]); } -void FreeEnergyPerturbationElement::scheduleTask( - Step step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +void FreeEnergyPerturbationElement::scheduleTask(Step step, + Time gmx_unused time, + const RegisterRunFunctionPtr& registerRunFunction) { if (lambdasChange_) { (*registerRunFunction)( - std::make_unique( - [this, step]() - {updateLambdas(step); })); + std::make_unique([this, step]() { updateLambdas(step); })); } } void FreeEnergyPerturbationElement::updateLambdas(Step step) { // at beginning of step (if lambdas change...) - setCurrentLambdasLocal( - step, inputrec_->fepvals, - lambda0_.data(), - lambda_, currentFEPState_); + setCurrentLambdasLocal(step, inputrec_->fepvals, lambda0_.data(), lambda_, currentFEPState_); update_mdatoms(mdAtoms_->mdatoms(), lambda_[efptMASS]); } @@ -110,12 +101,11 @@ int FreeEnergyPerturbationElement::currentFEPState() return currentFEPState_; } -void FreeEnergyPerturbationElement::writeCheckpoint( - t_state *localState, t_state gmx_unused *globalState) +void FreeEnergyPerturbationElement::writeCheckpoint(t_state* localState, t_state gmx_unused* globalState) { localState->fep_state = currentFEPState_; localState->lambda = lambda_; - localState->flags |= (1u<flags |= (1U << estLAMBDA) | (1U << estFEPSTATE); } -} +} // namespace gmx diff --git a/src/gromacs/modularsimulator/freeenergyperturbationelement.h b/src/gromacs/modularsimulator/freeenergyperturbationelement.h index f8863e85c0..f1566ffd76 100644 --- a/src/gromacs/modularsimulator/freeenergyperturbationelement.h +++ b/src/gromacs/modularsimulator/freeenergyperturbationelement.h @@ -65,59 +65,52 @@ class MDAtoms; * implement the checkpointing client interface to save its current * state for restart. */ -class FreeEnergyPerturbationElement final : - public ISimulatorElement, - public ICheckpointHelperClient +class FreeEnergyPerturbationElement final : public ISimulatorElement, public ICheckpointHelperClient { - public: - //! Constructor - FreeEnergyPerturbationElement( - FILE *fplog, - const t_inputrec *inputrec, - MDAtoms *mdAtoms); - - //! Get a view of the current lambda vector - ArrayRef lambdaView(); - //! Get a const view of the current lambda vector - ArrayRef constLambdaView(); - //! Get the current FEP state - int currentFEPState(); - - //! Update lambda and mdatoms - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! No setup needed - void elementSetup() override {}; - - //! No teardown needed - void elementTeardown() override {}; - - private: - //! ICheckpointHelperClient implementation - void writeCheckpoint(t_state *localState, t_state *globalState) override; - //! Update the lambda values - void updateLambdas(Step step); - - //! The lambda vector - std::array lambda_; - //! The starting lambda vector - std::array lambda0_; - //! The current free energy state - int currentFEPState_; - - //! Whether lambda values are non-static - const bool lambdasChange_; - - //! Handles logging. - FILE *fplog_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Atom parameters for this domain. - MDAtoms *mdAtoms_; +public: + //! Constructor + FreeEnergyPerturbationElement(FILE* fplog, const t_inputrec* inputrec, MDAtoms* mdAtoms); + + //! Get a view of the current lambda vector + ArrayRef lambdaView(); + //! Get a const view of the current lambda vector + ArrayRef constLambdaView(); + //! Get the current FEP state + int currentFEPState(); + + //! Update lambda and mdatoms + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! No setup needed + void elementSetup() override{}; + + //! No teardown needed + void elementTeardown() override{}; + +private: + //! ICheckpointHelperClient implementation + void writeCheckpoint(t_state* localState, t_state* globalState) override; + //! Update the lambda values + void updateLambdas(Step step); + + //! The lambda vector + std::array lambda_; + //! The starting lambda vector + std::array lambda0_; + //! The current free energy state + int currentFEPState_; + + //! Whether lambda values are non-static + const bool lambdasChange_; + + //! Handles logging. + FILE* fplog_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Atom parameters for this domain. + MDAtoms* mdAtoms_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_FREEENERGYPERTURBATIONELEMENT_H diff --git a/src/gromacs/modularsimulator/modularsimulator.cpp b/src/gromacs/modularsimulator/modularsimulator.cpp index 605267669d..72c6dfa76b 100644 --- a/src/gromacs/modularsimulator/modularsimulator.cpp +++ b/src/gromacs/modularsimulator/modularsimulator.cpp @@ -91,11 +91,10 @@ namespace gmx { void ModularSimulator::run() { - GMX_LOG(mdlog.info).asParagraph(). - appendText("Using the modular simulator."); + GMX_LOG(mdlog.info).asParagraph().appendText("Using the modular simulator."); constructElementsAndSignallers(); simulatorSetup(); - for (auto &signaller : signallerCallList_) + for (auto& signaller : signallerCallList_) { signaller->signallerSetup(); } @@ -104,7 +103,7 @@ void ModularSimulator::run() domDecHelper_->setup(); } - for (auto &element : elementsOwnershipList_) + for (auto& element : elementsOwnershipList_) { element->elementSetup(); } @@ -127,7 +126,7 @@ void ModularSimulator::run() } } - for (auto &element : elementsOwnershipList_) + for (auto& element : elementsOwnershipList_) { element->elementTeardown(); } @@ -146,21 +145,22 @@ void ModularSimulator::simulatorSetup() // turning it off is for convenience in benchmarking, which is // something that should not show up in the general user // interface. - GMX_LOG(mdlog.info).asParagraph(). - appendText("The -noconfout functionality is deprecated, and " - "may be removed in a future version."); + GMX_LOG(mdlog.info) + .asParagraph() + .appendText( + "The -noconfout functionality is deprecated, and " + "may be removed in a future version."); } if (MASTER(cr)) { char sbuf[STEPSTRSIZE], sbuf2[STEPSTRSIZE]; std::string timeString; - fprintf(stderr, "starting mdrun '%s'\n", - *(top_global->name)); + fprintf(stderr, "starting mdrun '%s'\n", *(top_global->name)); if (inputrec->nsteps >= 0) { - timeString = formatString( - "%8.1f", static_cast(inputrec->init_step+inputrec->nsteps)*inputrec->delta_t); + timeString = formatString("%8.1f", static_cast(inputrec->init_step + inputrec->nsteps) + * inputrec->delta_t); } else { @@ -169,15 +169,13 @@ void ModularSimulator::simulatorSetup() if (inputrec->init_step > 0) { fprintf(stderr, "%s steps, %s ps (continuing from step %s, %8.1f ps).\n", - gmx_step_str(inputrec->init_step+inputrec->nsteps, sbuf), - timeString.c_str(), - gmx_step_str(inputrec->init_step, sbuf2), - inputrec->init_step*inputrec->delta_t); + gmx_step_str(inputrec->init_step + inputrec->nsteps, sbuf), timeString.c_str(), + gmx_step_str(inputrec->init_step, sbuf2), inputrec->init_step * inputrec->delta_t); } else { - fprintf(stderr, "%s steps, %s ps.\n", - gmx_step_str(inputrec->nsteps, sbuf), timeString.c_str()); + fprintf(stderr, "%s steps, %s ps.\n", gmx_step_str(inputrec->nsteps, sbuf), + timeString.c_str()); } fprintf(fplog, "\n"); } @@ -189,12 +187,9 @@ void ModularSimulator::simulatorSetup() step_ = inputrec->init_step; } -void ModularSimulator::preStep( - Step step, Time gmx_unused time, - bool isNeighborSearchingStep) +void ModularSimulator::preStep(Step step, Time gmx_unused time, bool isNeighborSearchingStep) { - if (stopHandler_->stoppingAfterCurrentStep(isNeighborSearchingStep) && - step != signalHelper_->lastStep_) + if (stopHandler_->stoppingAfterCurrentStep(isNeighborSearchingStep) && step != signalHelper_->lastStep_) { /* * Stop handler wants to stop after the current step, which was @@ -234,13 +229,12 @@ void ModularSimulator::postStep(Step step, Time gmx_unused time) } } } - const bool do_verbose = mdrunOptions.verbose && - (step % mdrunOptions.verboseStepPrintInterval == 0 || - step == inputrec->init_step || step == signalHelper_->lastStep_); + const bool do_verbose = mdrunOptions.verbose + && (step % mdrunOptions.verboseStepPrintInterval == 0 + || step == inputrec->init_step || step == signalHelper_->lastStep_); // Print the remaining wall clock time for the run - if (MASTER(cr) && - (do_verbose || gmx_got_usr_signal()) && - !(pmeLoadBalanceHelper_ && pmeLoadBalanceHelper_->pmePrinting())) + if (MASTER(cr) && (do_verbose || gmx_got_usr_signal()) + && !(pmeLoadBalanceHelper_ && pmeLoadBalanceHelper_->pmePrinting())) { print_time(stderr, walltime_accounting, step, inputrec, cr); } @@ -252,10 +246,9 @@ void ModularSimulator::postStep(Step step, Time gmx_unused time) } resetHandler_->resetCounters( - step, step - inputrec->init_step, mdlog, fplog, cr, fr->nbv.get(), - nrnb, fr->pmedata, - pmeLoadBalanceHelper_ ? pmeLoadBalanceHelper_->loadBalancingObject() : nullptr, - wcycle, walltime_accounting); + step, step - inputrec->init_step, mdlog, fplog, cr, fr->nbv.get(), nrnb, fr->pmedata, + pmeLoadBalanceHelper_ ? pmeLoadBalanceHelper_->loadBalancingObject() : nullptr, wcycle, + walltime_accounting); } void ModularSimulator::simulatorTeardown() @@ -276,15 +269,14 @@ void ModularSimulator::simulatorTeardown() void ModularSimulator::populateTaskQueue() { auto registerRunFunction = std::make_unique( - [this](SimulatorRunFunctionPtr ptr) - {taskQueue_.push(std::move(ptr)); }); + [this](SimulatorRunFunctionPtr ptr) { taskQueue_.push(std::move(ptr)); }); Time startTime = inputrec->init_t; Time timeStep = inputrec->delta_t; - Time time = startTime + step_*timeStep; + Time time = startTime + step_ * timeStep; // Run an initial call to the signallers - for (auto &signaller : signallerCallList_) + for (auto& signaller : signallerCallList_) { signaller->signal(step_, time); } @@ -310,28 +302,25 @@ void ModularSimulator::populateTaskQueue() const bool isNSStep = step == signalHelper_->nextNSStep_; // register pre-step - (*registerRunFunction)( - std::make_unique( - [this, step, time, isNSStep](){preStep(step, time, isNSStep); })); + (*registerRunFunction)(std::make_unique( + [this, step, time, isNSStep]() { preStep(step, time, isNSStep); })); // register elements for step - for (auto &element : elementCallList_) + for (auto& element : elementCallList_) { element->scheduleTask(step_, time, registerRunFunction); } // register post-step (*registerRunFunction)( - std::make_unique( - [this, step, time](){postStep(step, time); })); + std::make_unique([this, step, time]() { postStep(step, time); })); // prepare next step step_++; - time = startTime + step_*timeStep; - for (auto &signaller : signallerCallList_) + time = startTime + step_ * timeStep; + for (auto& signaller : signallerCallList_) { signaller->signal(step_, time); } - } - while (step_ != signalHelper_->nextNSStep_ && step_ <= signalHelper_->lastStep_); + } while (step_ != signalHelper_->nextNSStep_ && step_ <= signalHelper_->lastStep_); } void ModularSimulator::constructElementsAndSignallers() @@ -367,41 +356,38 @@ void ModularSimulator::constructElementsAndSignallers() * Build data structures */ std::unique_ptr freeEnergyPerturbationElement = nullptr; - FreeEnergyPerturbationElement *freeEnergyPerturbationElementPtr = nullptr; + FreeEnergyPerturbationElement* freeEnergyPerturbationElementPtr = nullptr; if (inputrec->efep != efepNO) { - freeEnergyPerturbationElement = std::make_unique( - fplog, inputrec, mdAtoms); + freeEnergyPerturbationElement = + std::make_unique(fplog, inputrec, mdAtoms); freeEnergyPerturbationElementPtr = freeEnergyPerturbationElement.get(); } auto statePropagatorData = std::make_unique( - top_global->natoms, fplog, cr, state_global, - inputrec->nstxout, inputrec->nstvout, - inputrec->nstfout, inputrec->nstxout_compressed, - fr->nbv->useGpu(), freeEnergyPerturbationElementPtr, - inputrec, mdAtoms->mdatoms()); + top_global->natoms, fplog, cr, state_global, inputrec->nstxout, inputrec->nstvout, + inputrec->nstfout, inputrec->nstxout_compressed, fr->nbv->useGpu(), + freeEnergyPerturbationElementPtr, inputrec, mdAtoms->mdatoms()); auto statePropagatorDataPtr = compat::make_not_null(statePropagatorData.get()); auto energyElement = std::make_unique( - statePropagatorDataPtr, freeEnergyPerturbationElementPtr, - top_global, inputrec, mdAtoms, enerd, ekind, - constr, fplog, fcd, mdModulesNotifier, MASTER(cr), observablesHistory, startingBehavior); + statePropagatorDataPtr, freeEnergyPerturbationElementPtr, top_global, inputrec, mdAtoms, + enerd, ekind, constr, fplog, fcd, mdModulesNotifier, MASTER(cr), observablesHistory, + startingBehavior); auto energyElementPtr = compat::make_not_null(energyElement.get()); - topologyHolder_ = std::make_unique( - *top_global, cr, inputrec, fr, - mdAtoms, constr, vsite); + topologyHolder_ = + std::make_unique(*top_global, cr, inputrec, fr, mdAtoms, constr, vsite); /* * Build stop handler */ const bool simulationsShareState = false; - stopHandler_ = stopHandlerBuilder->getStopHandlerMD( - compat::not_null(&signals_[eglsSTOPCOND]), - simulationsShareState, MASTER(cr), inputrec->nstlist, mdrunOptions.reproducible, - nstglobalcomm_, mdrunOptions.maximumHoursToRun, inputrec->nstlist == 0, fplog, - stophandlerCurrentStep_, stophandlerIsNSStep_, walltime_accounting); + stopHandler_ = stopHandlerBuilder->getStopHandlerMD( + compat::not_null(&signals_[eglsSTOPCOND]), simulationsShareState, + MASTER(cr), inputrec->nstlist, mdrunOptions.reproducible, nstglobalcomm_, + mdrunOptions.maximumHoursToRun, inputrec->nstlist == 0, fplog, stophandlerCurrentStep_, + stophandlerIsNSStep_, walltime_accounting); /* * Create simulator builders @@ -432,21 +418,14 @@ void ModularSimulator::constructElementsAndSignallers() * have a full timestep state. */ // TODO: Make a CheckpointHelperBuilder - std::vector checkpointClients = { - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr - }; - CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback = nullptr; - auto integrator = buildIntegrator( - &neighborSearchSignallerBuilder, - &energySignallerBuilder, - &loggingSignallerBuilder, - &trajectoryElementBuilder, - &checkpointClients, - &checkBondedInteractionsCallback, - statePropagatorDataPtr, - energyElementPtr, - freeEnergyPerturbationElementPtr, - hasReadEkinState); + std::vector checkpointClients = { statePropagatorDataPtr, energyElementPtr, + freeEnergyPerturbationElementPtr }; + CheckBondedInteractionsCallbackPtr checkBondedInteractionsCallback = nullptr; + auto integrator = + buildIntegrator(&neighborSearchSignallerBuilder, &energySignallerBuilder, + &loggingSignallerBuilder, &trajectoryElementBuilder, &checkpointClients, + &checkBondedInteractionsCallback, statePropagatorDataPtr, + energyElementPtr, freeEnergyPerturbationElementPtr, hasReadEkinState); /* * Build infrastructure elements @@ -455,30 +434,29 @@ void ModularSimulator::constructElementsAndSignallers() if (PmeLoadBalanceHelper::doPmeLoadBalancing(mdrunOptions, inputrec, fr)) { pmeLoadBalanceHelper_ = std::make_unique( - mdrunOptions.verbose, statePropagatorDataPtr, fplog, - cr, mdlog, inputrec, wcycle, fr); - neighborSearchSignallerBuilder.registerSignallerClient(compat::make_not_null(pmeLoadBalanceHelper_.get())); + mdrunOptions.verbose, statePropagatorDataPtr, fplog, cr, mdlog, inputrec, wcycle, fr); + neighborSearchSignallerBuilder.registerSignallerClient( + compat::make_not_null(pmeLoadBalanceHelper_.get())); } if (DOMAINDECOMP(cr)) { - GMX_ASSERT( - checkBondedInteractionsCallback, - "Domain decomposition needs a callback for check the number of bonded interactions."); + GMX_ASSERT(checkBondedInteractionsCallback, + "Domain decomposition needs a callback for check the number of bonded " + "interactions."); domDecHelper_ = std::make_unique( - mdrunOptions.verbose, mdrunOptions.verboseStepPrintInterval, - statePropagatorDataPtr, topologyHolder_.get(), std::move(checkBondedInteractionsCallback), - nstglobalcomm_, fplog, cr, mdlog, constr, inputrec, mdAtoms, - nrnb, wcycle, fr, vsite, imdSession, pull_work); + mdrunOptions.verbose, mdrunOptions.verboseStepPrintInterval, statePropagatorDataPtr, + topologyHolder_.get(), std::move(checkBondedInteractionsCallback), nstglobalcomm_, fplog, + cr, mdlog, constr, inputrec, mdAtoms, nrnb, wcycle, fr, vsite, imdSession, pull_work); neighborSearchSignallerBuilder.registerSignallerClient(compat::make_not_null(domDecHelper_.get())); } const bool simulationsShareResetCounters = false; - resetHandler_ = std::make_unique( - compat::make_not_null(&signals_[eglsRESETCOUNTERS]), - simulationsShareResetCounters, inputrec->nsteps, MASTER(cr), - mdrunOptions.timingOptions.resetHalfway, mdrunOptions.maximumHoursToRun, - mdlog, wcycle, walltime_accounting); + resetHandler_ = std::make_unique( + compat::make_not_null(&signals_[eglsRESETCOUNTERS]), + simulationsShareResetCounters, inputrec->nsteps, MASTER(cr), + mdrunOptions.timingOptions.resetHalfway, mdrunOptions.maximumHoursToRun, mdlog, wcycle, + walltime_accounting); /* * Build signaller list @@ -488,44 +466,35 @@ void ModularSimulator::constructElementsAndSignallers() * maintained. */ auto energySignaller = energySignallerBuilder.build( - inputrec->nstcalcenergy, inputrec->fepvals->nstdhdl, inputrec->nstpcouple); + inputrec->nstcalcenergy, inputrec->fepvals->nstdhdl, inputrec->nstpcouple); trajectoryElementBuilder.registerSignallerClient(compat::make_not_null(energySignaller.get())); loggingSignallerBuilder.registerSignallerClient(compat::make_not_null(energySignaller.get())); auto trajectoryElement = trajectoryElementBuilder.build( - fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, - inputrec, top_global, oenv, wcycle, startingBehavior); + fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, + top_global, oenv, wcycle, startingBehavior); loggingSignallerBuilder.registerSignallerClient(compat::make_not_null(trajectoryElement.get())); // Add checkpoint helper here since we need a pointer to the trajectory element and // need to register it with the lastStepSignallerBuilder auto checkpointHandler = std::make_unique( - compat::make_not_null(&signals_[eglsCHKPT]), - simulationsShareState, inputrec->nstlist == 0, MASTER(cr), - mdrunOptions.writeConfout, mdrunOptions.checkpointOptions.period); + compat::make_not_null(&signals_[eglsCHKPT]), simulationsShareState, + inputrec->nstlist == 0, MASTER(cr), mdrunOptions.writeConfout, + mdrunOptions.checkpointOptions.period); checkpointHelper_ = std::make_unique( - std::move(checkpointClients), - std::move(checkpointHandler), - inputrec->init_step, trajectoryElement.get(), - top_global->natoms, fplog, cr, - observablesHistory, walltime_accounting, state_global, - mdrunOptions.writeConfout); + std::move(checkpointClients), std::move(checkpointHandler), inputrec->init_step, + trajectoryElement.get(), top_global->natoms, fplog, cr, observablesHistory, + walltime_accounting, state_global, mdrunOptions.writeConfout); lastStepSignallerBuilder.registerSignallerClient(compat::make_not_null(checkpointHelper_.get())); lastStepSignallerBuilder.registerSignallerClient(compat::make_not_null(trajectoryElement.get())); - auto loggingSignaller = loggingSignallerBuilder.build( - inputrec->nstlog, - inputrec->init_step, - inputrec->init_t); + auto loggingSignaller = + loggingSignallerBuilder.build(inputrec->nstlog, inputrec->init_step, inputrec->init_t); lastStepSignallerBuilder.registerSignallerClient(compat::make_not_null(loggingSignaller.get())); - auto lastStepSignaller = lastStepSignallerBuilder.build( - inputrec->nsteps, - inputrec->init_step, - stopHandler_.get()); + auto lastStepSignaller = + lastStepSignallerBuilder.build(inputrec->nsteps, inputrec->init_step, stopHandler_.get()); neighborSearchSignallerBuilder.registerSignallerClient(compat::make_not_null(lastStepSignaller.get())); auto neighborSearchSignaller = neighborSearchSignallerBuilder.build( - inputrec->nstlist, - inputrec->init_step, - inputrec->init_t); + inputrec->nstlist, inputrec->init_step, inputrec->init_t); addToCallListAndMove(std::move(neighborSearchSignaller), signallerCallList_, signallersOwnershipList_); addToCallListAndMove(std::move(lastStepSignaller), signallerCallList_, signallersOwnershipList_); @@ -545,7 +514,8 @@ void ModularSimulator::constructElementsAndSignallers() addToCallList(checkpointHelper_, elementCallList_); if (freeEnergyPerturbationElement) { - addToCallListAndMove(std::move(freeEnergyPerturbationElement), elementCallList_, elementsOwnershipList_); + addToCallListAndMove(std::move(freeEnergyPerturbationElement), elementCallList_, + elementsOwnershipList_); } addToCallListAndMove(std::move(integrator), elementCallList_, elementsOwnershipList_); addToCallListAndMove(std::move(trajectoryElement), elementCallList_, elementsOwnershipList_); @@ -556,26 +526,26 @@ void ModularSimulator::constructElementsAndSignallers() elementsOwnershipList_.emplace_back(std::move(energyElement)); } -std::unique_ptr ModularSimulator::buildForces( - SignallerBuilder *neighborSearchSignallerBuilder, - SignallerBuilder *energySignallerBuilder, - StatePropagatorData *statePropagatorDataPtr, - EnergyElement *energyElementPtr, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement) +std::unique_ptr +ModularSimulator::buildForces(SignallerBuilder* neighborSearchSignallerBuilder, + SignallerBuilder* energySignallerBuilder, + StatePropagatorData* statePropagatorDataPtr, + EnergyElement* energyElementPtr, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement) { const bool isVerbose = mdrunOptions.verbose; const bool isDynamicBox = inputrecDynamicBox(inputrec); // Check for polarizable models and flexible constraints - if (ShellFCElement::doShellsOrFlexConstraints( - &topologyHolder_->globalTopology(), constr ? constr->numFlexibleConstraints() : 0)) + if (ShellFCElement::doShellsOrFlexConstraints(&topologyHolder_->globalTopology(), + constr ? constr->numFlexibleConstraints() : 0)) { auto shellFCElement = std::make_unique( - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElement, - isVerbose, isDynamicBox, fplog, - cr, inputrec, mdAtoms, nrnb, fr, fcd, wcycle, runScheduleWork, - vsite, imdSession, pull_work, constr, &topologyHolder_->globalTopology(), enforcedRotation); + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElement, isVerbose, + isDynamicBox, fplog, cr, inputrec, mdAtoms, nrnb, fr, fcd, wcycle, runScheduleWork, vsite, + imdSession, pull_work, constr, &topologyHolder_->globalTopology(), enforcedRotation); topologyHolder_->registerClient(shellFCElement.get()); - neighborSearchSignallerBuilder->registerSignallerClient(compat::make_not_null(shellFCElement.get())); + neighborSearchSignallerBuilder->registerSignallerClient( + compat::make_not_null(shellFCElement.get())); energySignallerBuilder->registerSignallerClient(compat::make_not_null(shellFCElement.get())); // std::move *should* not be needed with c++-14, but clang-3.6 still requires it @@ -584,10 +554,9 @@ std::unique_ptr ModularSimulator::buildForces( else { auto forceElement = std::make_unique( - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElement, - isDynamicBox, fplog, - cr, inputrec, mdAtoms, nrnb, fr, fcd, wcycle, - runScheduleWork, vsite, imdSession, pull_work, enforcedRotation); + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElement, + isDynamicBox, fplog, cr, inputrec, mdAtoms, nrnb, fr, fcd, wcycle, runScheduleWork, + vsite, imdSession, pull_work, enforcedRotation); topologyHolder_->registerClient(forceElement.get()); neighborSearchSignallerBuilder->registerSignallerClient(compat::make_not_null(forceElement.get())); energySignallerBuilder->registerSignallerClient(compat::make_not_null(forceElement.get())); @@ -598,62 +567,57 @@ std::unique_ptr ModularSimulator::buildForces( } std::unique_ptr ModularSimulator::buildIntegrator( - SignallerBuilder *neighborSearchSignallerBuilder, - SignallerBuilder *energySignallerBuilder, - SignallerBuilder *loggingSignallerBuilder, - TrajectoryElementBuilder *trajectoryElementBuilder, - std::vector *checkpointClients, - CheckBondedInteractionsCallbackPtr *checkBondedInteractionsCallback, + SignallerBuilder* neighborSearchSignallerBuilder, + SignallerBuilder* energySignallerBuilder, + SignallerBuilder* loggingSignallerBuilder, + TrajectoryElementBuilder* trajectoryElementBuilder, + std::vector* checkpointClients, + CheckBondedInteractionsCallbackPtr* checkBondedInteractionsCallback, compat::not_null statePropagatorDataPtr, compat::not_null energyElementPtr, FreeEnergyPerturbationElement* freeEnergyPerturbationElementPtr, bool hasReadEkinState) { - auto forceElement = buildForces( - neighborSearchSignallerBuilder, - energySignallerBuilder, - statePropagatorDataPtr, - energyElementPtr, - freeEnergyPerturbationElementPtr); + auto forceElement = + buildForces(neighborSearchSignallerBuilder, energySignallerBuilder, + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr); // list of elements owned by the simulator composite object - std::vector< std::unique_ptr > elementsOwnershipList; + std::vector> elementsOwnershipList; // call list of the simulator composite object - std::vector< compat::not_null > elementCallList; + std::vector> elementCallList; std::function needToCheckNumberOfBondedInteractions; if (inputrec->eI == eiMD) { auto computeGlobalsElement = - std::make_unique< ComputeGlobalsElement >( - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - &signals_, nstglobalcomm_, fplog, mdlog, cr, - inputrec, mdAtoms, nrnb, wcycle, fr, - &topologyHolder_->globalTopology(), constr, hasReadEkinState); + std::make_unique>( + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + &signals_, nstglobalcomm_, fplog, mdlog, cr, inputrec, mdAtoms, nrnb, + wcycle, fr, &topologyHolder_->globalTopology(), constr, hasReadEkinState); topologyHolder_->registerClient(computeGlobalsElement.get()); energySignallerBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElement.get())); - trajectoryElementBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElement.get())); + trajectoryElementBuilder->registerSignallerClient( + compat::make_not_null(computeGlobalsElement.get())); - *checkBondedInteractionsCallback = computeGlobalsElement->getCheckNumberOfBondedInteractionsCallback(); + *checkBondedInteractionsCallback = + computeGlobalsElement->getCheckNumberOfBondedInteractionsCallback(); - auto propagator = std::make_unique< Propagator >( - inputrec->delta_t, statePropagatorDataPtr, mdAtoms, wcycle); + auto propagator = std::make_unique>( + inputrec->delta_t, statePropagatorDataPtr, mdAtoms, wcycle); addToCallListAndMove(std::move(forceElement), elementCallList, elementsOwnershipList); - addToCallList(statePropagatorDataPtr, elementCallList); // we have a full microstate at time t here! + addToCallList(statePropagatorDataPtr, elementCallList); // we have a full microstate at time t here! if (inputrec->etc == etcVRESCALE) { // TODO: With increased complexity of the propagator, this will need further development, // e.g. using propagators templated for velocity propagation policies and a builder propagator->setNumVelocityScalingVariables(inputrec->opts.ngtc); auto thermostat = std::make_unique( - inputrec->nsttcouple, -1, false, inputrec->ld_seed, - inputrec->opts.ngtc, inputrec->delta_t*inputrec->nsttcouple, - inputrec->opts.ref_t, inputrec->opts.tau_t, inputrec->opts.nrdf, - energyElementPtr, - propagator->viewOnVelocityScaling(), - propagator->velocityScalingCallback(), - state_global, cr, inputrec->bContinuation); + inputrec->nsttcouple, -1, false, inputrec->ld_seed, inputrec->opts.ngtc, + inputrec->delta_t * inputrec->nsttcouple, inputrec->opts.ref_t, inputrec->opts.tau_t, + inputrec->opts.nrdf, energyElementPtr, propagator->viewOnVelocityScaling(), + propagator->velocityScalingCallback(), state_global, cr, inputrec->bContinuation); checkpointClients->emplace_back(thermostat.get()); energyElementPtr->setVRescaleThermostat(thermostat.get()); addToCallListAndMove(std::move(thermostat), elementCallList, elementsOwnershipList); @@ -665,19 +629,19 @@ std::unique_ptr ModularSimulator::buildIntegrator( // Building the PR barostat here since it needs access to the propagator // and we want to be able to move the propagator object prBarostat = std::make_unique( - inputrec->nstpcouple, -1, inputrec->delta_t*inputrec->nstpcouple, inputrec->init_step, - propagator->viewOnPRScalingMatrix(), propagator->prScalingCallback(), - statePropagatorDataPtr, energyElementPtr, fplog, inputrec, mdAtoms, - state_global, cr, inputrec->bContinuation); + inputrec->nstpcouple, -1, inputrec->delta_t * inputrec->nstpcouple, + inputrec->init_step, propagator->viewOnPRScalingMatrix(), + propagator->prScalingCallback(), statePropagatorDataPtr, energyElementPtr, + fplog, inputrec, mdAtoms, state_global, cr, inputrec->bContinuation); energyElementPtr->setParrinelloRahamnBarostat(prBarostat.get()); checkpointClients->emplace_back(prBarostat.get()); } addToCallListAndMove(std::move(propagator), elementCallList, elementsOwnershipList); if (constr) { - auto constraintElement = std::make_unique< ConstraintsElement >( - constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); + auto constraintElement = std::make_unique>( + constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); auto constraintElementPtr = compat::make_not_null(constraintElement.get()); energySignallerBuilder->registerSignallerClient(constraintElementPtr); trajectoryElementBuilder->registerSignallerClient(constraintElementPtr); @@ -687,7 +651,7 @@ std::unique_ptr ModularSimulator::buildIntegrator( } addToCallListAndMove(std::move(computeGlobalsElement), elementCallList, elementsOwnershipList); - addToCallList(energyElementPtr, elementCallList); // we have the energies at time t here! + addToCallList(energyElementPtr, elementCallList); // we have the energies at time t here! if (prBarostat) { addToCallListAndMove(std::move(prBarostat), elementCallList, elementsOwnershipList); @@ -696,31 +660,35 @@ std::unique_ptr ModularSimulator::buildIntegrator( else if (inputrec->eI == eiVV) { auto computeGlobalsElementAtFullTimeStep = - std::make_unique< ComputeGlobalsElement >( - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - &signals_, nstglobalcomm_, fplog, mdlog, cr, - inputrec, mdAtoms, nrnb, wcycle, fr, - &topologyHolder_->globalTopology(), constr, hasReadEkinState); + std::make_unique>( + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + &signals_, nstglobalcomm_, fplog, mdlog, cr, inputrec, mdAtoms, nrnb, + wcycle, fr, &topologyHolder_->globalTopology(), constr, hasReadEkinState); topologyHolder_->registerClient(computeGlobalsElementAtFullTimeStep.get()); - energySignallerBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElementAtFullTimeStep.get())); - trajectoryElementBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElementAtFullTimeStep.get())); + energySignallerBuilder->registerSignallerClient( + compat::make_not_null(computeGlobalsElementAtFullTimeStep.get())); + trajectoryElementBuilder->registerSignallerClient( + compat::make_not_null(computeGlobalsElementAtFullTimeStep.get())); auto computeGlobalsElementAfterCoordinateUpdate = - std::make_unique >( - statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - &signals_, nstglobalcomm_, fplog, mdlog, cr, - inputrec, mdAtoms, nrnb, wcycle, fr, - &topologyHolder_->globalTopology(), constr, hasReadEkinState); + std::make_unique>( + statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + &signals_, nstglobalcomm_, fplog, mdlog, cr, inputrec, mdAtoms, nrnb, + wcycle, fr, &topologyHolder_->globalTopology(), constr, hasReadEkinState); topologyHolder_->registerClient(computeGlobalsElementAfterCoordinateUpdate.get()); - energySignallerBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElementAfterCoordinateUpdate.get())); - trajectoryElementBuilder->registerSignallerClient(compat::make_not_null(computeGlobalsElementAfterCoordinateUpdate.get())); + energySignallerBuilder->registerSignallerClient( + compat::make_not_null(computeGlobalsElementAfterCoordinateUpdate.get())); + trajectoryElementBuilder->registerSignallerClient( + compat::make_not_null(computeGlobalsElementAfterCoordinateUpdate.get())); - *checkBondedInteractionsCallback = computeGlobalsElementAfterCoordinateUpdate->getCheckNumberOfBondedInteractionsCallback(); + *checkBondedInteractionsCallback = + computeGlobalsElementAfterCoordinateUpdate->getCheckNumberOfBondedInteractionsCallback(); - auto propagatorVelocities = std::make_unique< Propagator >( - inputrec->delta_t * 0.5, statePropagatorDataPtr, mdAtoms, wcycle); - auto propagatorVelocitiesAndPositions = std::make_unique< Propagator >( - inputrec->delta_t, statePropagatorDataPtr, mdAtoms, wcycle); + auto propagatorVelocities = std::make_unique>( + inputrec->delta_t * 0.5, statePropagatorDataPtr, mdAtoms, wcycle); + auto propagatorVelocitiesAndPositions = + std::make_unique>( + inputrec->delta_t, statePropagatorDataPtr, mdAtoms, wcycle); addToCallListAndMove(std::move(forceElement), elementCallList, elementsOwnershipList); @@ -730,58 +698,64 @@ std::unique_ptr ModularSimulator::buildIntegrator( // Building the PR barostat here since it needs access to the propagator // and we want to be able to move the propagator object prBarostat = std::make_unique( - inputrec->nstpcouple, -1, inputrec->delta_t*inputrec->nstpcouple, inputrec->init_step, - propagatorVelocities->viewOnPRScalingMatrix(), propagatorVelocities->prScalingCallback(), - statePropagatorDataPtr, energyElementPtr, fplog, inputrec, mdAtoms, - state_global, cr, inputrec->bContinuation); + inputrec->nstpcouple, -1, inputrec->delta_t * inputrec->nstpcouple, + inputrec->init_step, propagatorVelocities->viewOnPRScalingMatrix(), + propagatorVelocities->prScalingCallback(), statePropagatorDataPtr, energyElementPtr, + fplog, inputrec, mdAtoms, state_global, cr, inputrec->bContinuation); energyElementPtr->setParrinelloRahamnBarostat(prBarostat.get()); checkpointClients->emplace_back(prBarostat.get()); } addToCallListAndMove(std::move(propagatorVelocities), elementCallList, elementsOwnershipList); if (constr) { - auto constraintElement = std::make_unique< ConstraintsElement >( - constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); + auto constraintElement = std::make_unique>( + constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); energySignallerBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); - trajectoryElementBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); - loggingSignallerBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); + trajectoryElementBuilder->registerSignallerClient( + compat::make_not_null(constraintElement.get())); + loggingSignallerBuilder->registerSignallerClient( + compat::make_not_null(constraintElement.get())); addToCallListAndMove(std::move(constraintElement), elementCallList, elementsOwnershipList); } - addToCallListAndMove(std::move(computeGlobalsElementAtFullTimeStep), elementCallList, elementsOwnershipList); - addToCallList(statePropagatorDataPtr, elementCallList); // we have a full microstate at time t here! + addToCallListAndMove(std::move(computeGlobalsElementAtFullTimeStep), elementCallList, + elementsOwnershipList); + addToCallList(statePropagatorDataPtr, elementCallList); // we have a full microstate at time t here! if (inputrec->etc == etcVRESCALE) { // TODO: With increased complexity of the propagator, this will need further development, // e.g. using propagators templated for velocity propagation policies and a builder propagatorVelocitiesAndPositions->setNumVelocityScalingVariables(inputrec->opts.ngtc); auto thermostat = std::make_unique( - inputrec->nsttcouple, 0, true, inputrec->ld_seed, - inputrec->opts.ngtc, inputrec->delta_t*inputrec->nsttcouple, - inputrec->opts.ref_t, inputrec->opts.tau_t, inputrec->opts.nrdf, - energyElementPtr, - propagatorVelocitiesAndPositions->viewOnVelocityScaling(), - propagatorVelocitiesAndPositions->velocityScalingCallback(), - state_global, cr, inputrec->bContinuation); + inputrec->nsttcouple, 0, true, inputrec->ld_seed, inputrec->opts.ngtc, + inputrec->delta_t * inputrec->nsttcouple, inputrec->opts.ref_t, + inputrec->opts.tau_t, inputrec->opts.nrdf, energyElementPtr, + propagatorVelocitiesAndPositions->viewOnVelocityScaling(), + propagatorVelocitiesAndPositions->velocityScalingCallback(), state_global, cr, + inputrec->bContinuation); checkpointClients->emplace_back(thermostat.get()); energyElementPtr->setVRescaleThermostat(thermostat.get()); addToCallListAndMove(std::move(thermostat), elementCallList, elementsOwnershipList); } - addToCallListAndMove(std::move(propagatorVelocitiesAndPositions), elementCallList, elementsOwnershipList); + addToCallListAndMove(std::move(propagatorVelocitiesAndPositions), elementCallList, + elementsOwnershipList); if (constr) { - auto constraintElement = std::make_unique< ConstraintsElement >( - constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, - MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); + auto constraintElement = std::make_unique>( + constr, statePropagatorDataPtr, energyElementPtr, freeEnergyPerturbationElementPtr, + MASTER(cr), fplog, inputrec, mdAtoms->mdatoms()); energySignallerBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); - trajectoryElementBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); - loggingSignallerBuilder->registerSignallerClient(compat::make_not_null(constraintElement.get())); + trajectoryElementBuilder->registerSignallerClient( + compat::make_not_null(constraintElement.get())); + loggingSignallerBuilder->registerSignallerClient( + compat::make_not_null(constraintElement.get())); addToCallListAndMove(std::move(constraintElement), elementCallList, elementsOwnershipList); } - addToCallListAndMove(std::move(computeGlobalsElementAfterCoordinateUpdate), elementCallList, elementsOwnershipList); - addToCallList(energyElementPtr, elementCallList); // we have the energies at time t here! + addToCallListAndMove(std::move(computeGlobalsElementAfterCoordinateUpdate), elementCallList, + elementsOwnershipList); + addToCallList(energyElementPtr, elementCallList); // we have the energies at time t here! if (prBarostat) { addToCallListAndMove(std::move(prBarostat), elementCallList, elementsOwnershipList); @@ -792,165 +766,195 @@ std::unique_ptr ModularSimulator::buildIntegrator( gmx_fatal(FARGS, "Integrator not implemented for the modular simulator."); } - auto integrator = std::make_unique( - std::move(elementCallList), std::move(elementsOwnershipList)); + auto integrator = std::make_unique(std::move(elementCallList), + std::move(elementsOwnershipList)); // std::move *should* not be needed with c++-14, but clang-3.6 still requires it return std::move(integrator); } -bool ModularSimulator::isInputCompatible( - bool exitOnFailure, - const t_inputrec *inputrec, - bool doRerun, - const gmx_vsite_t *vsite, - const gmx_multisim_t *ms, - const ReplicaExchangeParameters &replExParams, - const t_fcdata *fcd, - int nfile, - const t_filenm *fnm, - ObservablesHistory *observablesHistory, - const gmx_membed_t *membed) +bool ModularSimulator::isInputCompatible(bool exitOnFailure, + const t_inputrec* inputrec, + bool doRerun, + const gmx_vsite_t* vsite, + const gmx_multisim_t* ms, + const ReplicaExchangeParameters& replExParams, + const t_fcdata* fcd, + int nfile, + const t_filenm* fnm, + ObservablesHistory* observablesHistory, + const gmx_membed_t* membed) { - auto conditionalAssert = - [exitOnFailure](bool condition, const char* message) + auto conditionalAssert = [exitOnFailure](bool condition, const char* message) { + if (exitOnFailure) { - if (exitOnFailure) - { - GMX_RELEASE_ASSERT(condition, message); - } - return condition; - }; + GMX_RELEASE_ASSERT(condition, message); + } + return condition; + }; bool isInputCompatible = true; // GMX_USE_MODULAR_SIMULATOR allows to use modular simulator also for non-standard uses, // such as the leap-frog integrator - const auto modularSimulatorExplicitlyTurnedOn = - (getenv("GMX_USE_MODULAR_SIMULATOR") != nullptr); + const auto modularSimulatorExplicitlyTurnedOn = (getenv("GMX_USE_MODULAR_SIMULATOR") != nullptr); // GMX_USE_MODULAR_SIMULATOR allows to use disable modular simulator for all uses, // including the velocity-verlet integrator used by default - const auto modularSimulatorExplicitlyTurnedOff = - (getenv("GMX_DISABLE_MODULAR_SIMULATOR") != nullptr); + const auto modularSimulatorExplicitlyTurnedOff = (getenv("GMX_DISABLE_MODULAR_SIMULATOR") != nullptr); GMX_RELEASE_ASSERT( !(modularSimulatorExplicitlyTurnedOn && modularSimulatorExplicitlyTurnedOff), "Cannot have both GMX_USE_MODULAR_SIMULATOR=ON and GMX_DISABLE_MODULAR_SIMULATOR=ON. " - "Unset one of the two environment variables to explicitly chose which simulator to use, " + "Unset one of the two environment variables to explicitly chose which simulator to " + "use, " "or unset both to recover default behavior."); GMX_RELEASE_ASSERT( - !(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV && inputrec->epc == epcPARRINELLORAHMAN), - "Cannot use a Parrinello-Rahman barostat with md-vv and GMX_DISABLE_MODULAR_SIMULATOR=ON, " + !(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV + && inputrec->epc == epcPARRINELLORAHMAN), + "Cannot use a Parrinello-Rahman barostat with md-vv and " + "GMX_DISABLE_MODULAR_SIMULATOR=ON, " "as the Parrinello-Rahman barostat is not implemented in the legacy simulator. Unset " "GMX_DISABLE_MODULAR_SIMULATOR or use a different pressure control algorithm."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->eI == eiMD || inputrec->eI == eiVV, - "Only integrators md and md-vv are supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->eI != eiMD || modularSimulatorExplicitlyTurnedOn, - "Set GMX_USE_MODULAR_SIMULATOR=ON to use the modular simulator with integrator md."); - isInputCompatible = isInputCompatible && conditionalAssert( - !doRerun, - "Rerun is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->etc == etcNO || inputrec->etc == etcVRESCALE, - "Only v-rescale thermostat is supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN, - "Only Parrinello-Rahman barostat is supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !(inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec) || inputrecNvtTrotter(inputrec)), - "Legacy Trotter decomposition is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->efep == efepNO || inputrec->efep == efepYES || inputrec->efep == efepSLOWGROWTH, - "Expanded ensemble free energy calculation is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !inputrec->bPull, - "Pulling is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->opts.ngacc == 1 && inputrec->opts.acc[0][XX] == 0.0 && inputrec->opts.acc[0][YY] == 0.0 && - inputrec->opts.acc[0][ZZ] == 0.0 && inputrec->cos_accel == 0.0, - "Acceleration is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->opts.ngfrz == 1 && inputrec->opts.nFreeze[0][XX] == 0 && - inputrec->opts.nFreeze[0][YY] == 0 && inputrec->opts.nFreeze[0][ZZ] == 0, - "Freeze groups are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->deform[XX][XX] == 0.0 && inputrec->deform[XX][YY] == 0.0 && inputrec->deform[XX][ZZ] == 0.0 && - inputrec->deform[YY][XX] == 0.0 && inputrec->deform[YY][YY] == 0.0 && inputrec->deform[YY][ZZ] == 0.0 && - inputrec->deform[ZZ][XX] == 0.0 && inputrec->deform[ZZ][YY] == 0.0 && inputrec->deform[ZZ][ZZ] == 0.0, - "Deformation is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - vsite == nullptr, - "Virtual sites are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !inputrec->bDoAwh, - "AWH is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - ms == nullptr, - "Multi-sim are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - replExParams.exchangeInterval == 0, - "Replica exchange is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - fcd->disres.nsystems <= 1, - "Ensemble restraints are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !doSimulatedAnnealing(inputrec), - "Simulated annealing is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !inputrec->bSimTemp, - "Simulated tempering is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !inputrec->bExpanded, - "Expanded ensemble simulations are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !(opt2bSet("-ei", nfile, fnm) || observablesHistory->edsamHistory != nullptr), - "Essential dynamics is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->eSwapCoords == eswapNO, - "Ion / water position swapping is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !inputrec->bIMD, - "Interactive MD is not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - membed == nullptr, - "Membrane embedding is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + inputrec->eI == eiMD || inputrec->eI == eiVV, + "Only integrators md and md-vv are supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(inputrec->eI != eiMD || modularSimulatorExplicitlyTurnedOn, + "Set GMX_USE_MODULAR_SIMULATOR=ON to use the modular " + "simulator with integrator md."); + isInputCompatible = + isInputCompatible + && conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + inputrec->etc == etcNO || inputrec->etc == etcVRESCALE, + "Only v-rescale thermostat is supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN, + "Only Parrinello-Rahman barostat is supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + !(inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec) + || inputrecNvtTrotter(inputrec)), + "Legacy Trotter decomposition is not supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(inputrec->efep == efepNO || inputrec->efep == efepYES + || inputrec->efep == efepSLOWGROWTH, + "Expanded ensemble free energy calculation is not " + "supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(!inputrec->bPull, + "Pulling is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(inputrec->opts.ngacc == 1 && inputrec->opts.acc[0][XX] == 0.0 + && inputrec->opts.acc[0][YY] == 0.0 + && inputrec->opts.acc[0][ZZ] == 0.0 && inputrec->cos_accel == 0.0, + "Acceleration is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(inputrec->opts.ngfrz == 1 && inputrec->opts.nFreeze[0][XX] == 0 + && inputrec->opts.nFreeze[0][YY] == 0 + && inputrec->opts.nFreeze[0][ZZ] == 0, + "Freeze groups are not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + inputrec->deform[XX][XX] == 0.0 && inputrec->deform[XX][YY] == 0.0 + && inputrec->deform[XX][ZZ] == 0.0 && inputrec->deform[YY][XX] == 0.0 + && inputrec->deform[YY][YY] == 0.0 && inputrec->deform[YY][ZZ] == 0.0 + && inputrec->deform[ZZ][XX] == 0.0 && inputrec->deform[ZZ][YY] == 0.0 + && inputrec->deform[ZZ][ZZ] == 0.0, + "Deformation is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(vsite == nullptr, + "Virtual sites are not supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(!inputrec->bDoAwh, + "AWH is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(ms == nullptr, + "Multi-sim are not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(replExParams.exchangeInterval == 0, + "Replica exchange is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(fcd->disres.nsystems <= 1, + "Ensemble restraints are not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(!doSimulatedAnnealing(inputrec), + "Simulated annealing is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(!inputrec->bSimTemp, + "Simulated tempering is not supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(!inputrec->bExpanded, + "Expanded ensemble simulations are not supported by " + "the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + !(opt2bSet("-ei", nfile, fnm) || observablesHistory->edsamHistory != nullptr), + "Essential dynamics is not supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(inputrec->eSwapCoords == eswapNO, + "Ion / water position swapping is not supported by " + "the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(!inputrec->bIMD, + "Interactive MD is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert(membed == nullptr, + "Membrane embedding is not supported by the modular simulator."); // TODO: Change this to the boolean passed when we merge the user interface change for the GPU update. - isInputCompatible = isInputCompatible && conditionalAssert( - getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") == nullptr, - "Integration on the GPU is not supported by the modular simulator."); + isInputCompatible = + isInputCompatible + && conditionalAssert( + getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") == nullptr, + "Integration on the GPU is not supported by the modular simulator."); // Modular simulator is centered around NS updates // TODO: think how to handle nstlist == 0 - isInputCompatible = isInputCompatible && conditionalAssert( - inputrec->nstlist != 0, - "Simulations without neighbor list update are not supported by the modular simulator."); - isInputCompatible = isInputCompatible && conditionalAssert( - !GMX_FAHCORE, - "GMX_FAHCORE not supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(inputrec->nstlist != 0, + "Simulations without neighbor list update are not " + "supported by the modular simulator."); + isInputCompatible = isInputCompatible + && conditionalAssert(!GMX_FAHCORE, + "GMX_FAHCORE not supported by the modular simulator."); return isInputCompatible; } void ModularSimulator::checkInputForDisabledFunctionality() { - isInputCompatible( - true, - inputrec, doRerun, vsite, ms, replExParams, - fcd, nfile, fnm, observablesHistory, membed); + isInputCompatible(true, inputrec, doRerun, vsite, ms, replExParams, fcd, nfile, fnm, + observablesHistory, membed); } SignallerCallbackPtr ModularSimulator::SignalHelper::registerLastStepCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time){this->lastStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->lastStep_ = step; }); } SignallerCallbackPtr ModularSimulator::SignalHelper::registerNSCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time) - {this->nextNSStep_ = step; }); -} + [this](Step step, Time gmx_unused time) { this->nextNSStep_ = step; }); } +} // namespace gmx diff --git a/src/gromacs/modularsimulator/modularsimulator.h b/src/gromacs/modularsimulator/modularsimulator.h index a9c125cfe5..bae623d946 100644 --- a/src/gromacs/modularsimulator/modularsimulator.h +++ b/src/gromacs/modularsimulator/modularsimulator.h @@ -75,231 +75,221 @@ class TrajectoryElementBuilder; * for a predefined number of steps, then running the task list, and repeating * until the stop criterion is fulfilled. */ -class ModularSimulator final : - public ISimulator +class ModularSimulator final : public ISimulator { - public: - //! Run the simulator - void run() override; +public: + //! Run the simulator + void run() override; - //! Check for disabled functionality - static bool isInputCompatible( - bool exitOnFailure, - const t_inputrec *inputrec, - bool doRerun, - const gmx_vsite_t *vsite, - const gmx_multisim_t *ms, - const ReplicaExchangeParameters &replExParams, - const t_fcdata *fcd, - int nfile, - const t_filenm *fnm, - ObservablesHistory *observablesHistory, - const gmx_membed_t *membed); + //! Check for disabled functionality + static bool isInputCompatible(bool exitOnFailure, + const t_inputrec* inputrec, + bool doRerun, + const gmx_vsite_t* vsite, + const gmx_multisim_t* ms, + const ReplicaExchangeParameters& replExParams, + const t_fcdata* fcd, + int nfile, + const t_filenm* fnm, + ObservablesHistory* observablesHistory, + const gmx_membed_t* membed); - // Only builder can construct - friend class SimulatorBuilder; + // Only builder can construct + friend class SimulatorBuilder; - private: - //! Constructor - template - explicit ModularSimulator(Args && ... args); +private: + //! Constructor + template + explicit ModularSimulator(Args&&... args); - /*! \brief The initialisation - * - * This builds all signallers and elements, and is responsible to put - * them in the correct order. - */ - void constructElementsAndSignallers(); + /*! \brief The initialisation + * + * This builds all signallers and elements, and is responsible to put + * them in the correct order. + */ + void constructElementsAndSignallers(); - /*! \brief A function called once before the simulation run - * - * This function collects calls which need to be made once at the - * beginning of the simulation run. These are mainly printing information - * to the user and starting the wall time. - */ - void simulatorSetup(); + /*! \brief A function called once before the simulation run + * + * This function collects calls which need to be made once at the + * beginning of the simulation run. These are mainly printing information + * to the user and starting the wall time. + */ + void simulatorSetup(); - /*! \brief A function called once after the simulation run - * - * This function collects calls which need to be made once at the - * end of the simulation run. - */ - void simulatorTeardown(); + /*! \brief A function called once after the simulation run + * + * This function collects calls which need to be made once at the + * end of the simulation run. + */ + void simulatorTeardown(); - /*! \brief A function called before every step - * - * This function collects calls which need to be made before every - * simulation step. The need for this function could likely be - * eliminated by rewriting the stop and reset handler to fit the - * modular simulator approach. - */ - void preStep(Step step, Time time, bool isNeighborSearchingStep); + /*! \brief A function called before every step + * + * This function collects calls which need to be made before every + * simulation step. The need for this function could likely be + * eliminated by rewriting the stop and reset handler to fit the + * modular simulator approach. + */ + void preStep(Step step, Time time, bool isNeighborSearchingStep); - /*! \brief A function called after every step - * - * This function collects calls which need to be made after every - * simulation step. - */ - void postStep(Step step, Time time); + /*! \brief A function called after every step + * + * This function collects calls which need to be made after every + * simulation step. + */ + void postStep(Step step, Time time); - /*! \brief Build the integrator part of the simulator - * - * This includes the force calculation, state propagation, constraints, - * global computation, and the points during the process at which valid - * micro state / energy states are found. Currently, buildIntegrator - * knows about NVE md and md-vv algorithms. - */ - std::unique_ptr buildIntegrator( - SignallerBuilder *neighborSearchSignallerBuilder, - SignallerBuilder *energySignallerBuilder, - SignallerBuilder *loggingSignallerBuilder, - TrajectoryElementBuilder *trajectoryElementBuilder, - std::vector *checkpointClients, - CheckBondedInteractionsCallbackPtr *checkBondedInteractionsCallback, - compat::not_null statePropagatorDataPtr, - compat::not_null energyElementPtr, - FreeEnergyPerturbationElement *freeEnergyPerturbationElementPtr, - bool hasReadEkinState); + /*! \brief Build the integrator part of the simulator + * + * This includes the force calculation, state propagation, constraints, + * global computation, and the points during the process at which valid + * micro state / energy states are found. Currently, buildIntegrator + * knows about NVE md and md-vv algorithms. + */ + std::unique_ptr + buildIntegrator(SignallerBuilder* neighborSearchSignallerBuilder, + SignallerBuilder* energySignallerBuilder, + SignallerBuilder* loggingSignallerBuilder, + TrajectoryElementBuilder* trajectoryElementBuilder, + std::vector* checkpointClients, + CheckBondedInteractionsCallbackPtr* checkBondedInteractionsCallback, + compat::not_null statePropagatorDataPtr, + compat::not_null energyElementPtr, + FreeEnergyPerturbationElement* freeEnergyPerturbationElementPtr, + bool hasReadEkinState); - //! Build the force element - can be normal forces or shell / flex constraints - std::unique_ptr buildForces( - SignallerBuilder *neighborSearchSignallerBuilder, - SignallerBuilder *energySignallerBuilder, - StatePropagatorData *statePropagatorDataPtr, - EnergyElement *energyElementPtr, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement); + //! Build the force element - can be normal forces or shell / flex constraints + std::unique_ptr + buildForces(SignallerBuilder* neighborSearchSignallerBuilder, + SignallerBuilder* energySignallerBuilder, + StatePropagatorData* statePropagatorDataPtr, + EnergyElement* energyElementPtr, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement); - /*! \brief Add run functions to the task queue - * - * This function calls PME load balancing and domain decomposition first, - * and then queries the elements for all steps of the life time of the - * current neighbor list for their run functions. When the next step - * would be a neighbor-searching step, this function returns, such that - * the simulator can run the pre-computed task list before updating the - * neighbor list and re-filling the task list. - * - * TODO: In the current approach, unique pointers to tasks are created - * repeatedly. While preliminary measures do not seem to indicate - * performance problems, a pool allocator would be an obvious - * optimization possibility, as would reusing the task queue if - * the task queue is periodic around the rebuild point (i.e. the - * task queue is identical between rebuilds). - */ - void populateTaskQueue(); + /*! \brief Add run functions to the task queue + * + * This function calls PME load balancing and domain decomposition first, + * and then queries the elements for all steps of the life time of the + * current neighbor list for their run functions. When the next step + * would be a neighbor-searching step, this function returns, such that + * the simulator can run the pre-computed task list before updating the + * neighbor list and re-filling the task list. + * + * TODO: In the current approach, unique pointers to tasks are created + * repeatedly. While preliminary measures do not seem to indicate + * performance problems, a pool allocator would be an obvious + * optimization possibility, as would reusing the task queue if + * the task queue is periodic around the rebuild point (i.e. the + * task queue is identical between rebuilds). + */ + void populateTaskQueue(); - //! Check for disabled functionality (during construction time) - void checkInputForDisabledFunctionality(); + //! Check for disabled functionality (during construction time) + void checkInputForDisabledFunctionality(); - //! The run queue - std::queue taskQueue_; + //! The run queue + std::queue taskQueue_; - /* Note that the Simulator is owning the signallers and elements. - * The ownership list and the call list are kept separate, however, - * to allow to have elements more than once in the call lists - - * either as signaller AND element (such as the TrajectoryElement), - * or to have an element twice in the scheduling sequence (currently - * not used). - * - * For the elements, the setup and teardown is applied on the - * elementsOwnershipList_, to ensure that it is called only once per - * element. For the signallers, the setup is applied on the - * signallerCallList_ - this makes sure that both the elementSetup() - * and signallerSetup() of an object being both an element and a - * signaller is called. It is also not expected to run have a signaller - * more than once in the signallerCallList_, so we don't have to worry - * about calling the setup method twice. Consequently, this means that - * objects being both a signaller and an element should be stored in - * the elementsOwnershipList_. - */ - //! List of signalers (ownership) - std::vector< std::unique_ptr > signallersOwnershipList_; - //! List of signalers (calling sequence) - std::vector< compat::not_null > signallerCallList_; - //! List of schedulerElements (ownership) - std::vector< std::unique_ptr > elementsOwnershipList_; - //! List of schedulerElements (calling sequence) - std::vector< compat::not_null > elementCallList_; + /* Note that the Simulator is owning the signallers and elements. + * The ownership list and the call list are kept separate, however, + * to allow to have elements more than once in the call lists - + * either as signaller AND element (such as the TrajectoryElement), + * or to have an element twice in the scheduling sequence (currently + * not used). + * + * For the elements, the setup and teardown is applied on the + * elementsOwnershipList_, to ensure that it is called only once per + * element. For the signallers, the setup is applied on the + * signallerCallList_ - this makes sure that both the elementSetup() + * and signallerSetup() of an object being both an element and a + * signaller is called. It is also not expected to run have a signaller + * more than once in the signallerCallList_, so we don't have to worry + * about calling the setup method twice. Consequently, this means that + * objects being both a signaller and an element should be stored in + * the elementsOwnershipList_. + */ + //! List of signalers (ownership) + std::vector> signallersOwnershipList_; + //! List of signalers (calling sequence) + std::vector> signallerCallList_; + //! List of schedulerElements (ownership) + std::vector> elementsOwnershipList_; + //! List of schedulerElements (calling sequence) + std::vector> elementCallList_; - //! \cond - //! Helper function to add elements or signallers to the call list via raw pointer - template - static void addToCallList ( - compat::not_null element, - std::vector< compat::not_null > &callList); - //! Helper function to add elements or signallers to the call list via smart pointer - template - static void addToCallList( - std::unique_ptr &element, - std::vector< compat::not_null > &callList); - /*! \brief Helper function to add elements or signallers to the call list - * and move the ownership to the ownership list - */ - template - static void addToCallListAndMove( - std::unique_ptr element, - std::vector< compat::not_null > &callList, - std::vector< std::unique_ptr > &elementList); - //! \endcond + //! \cond + //! Helper function to add elements or signallers to the call list via raw pointer + template + static void addToCallList(compat::not_null element, std::vector>& callList); + //! Helper function to add elements or signallers to the call list via smart pointer + template + static void addToCallList(std::unique_ptr& element, std::vector>& callList); + /*! \brief Helper function to add elements or signallers to the call list + * and move the ownership to the ownership list + */ + template + static void addToCallListAndMove(std::unique_ptr element, + std::vector>& callList, + std::vector>& elementList); + //! \endcond - // Infrastructure elements - //! The domain decomposition element - std::unique_ptr domDecHelper_; - //! The PME load balancing element - std::unique_ptr pmeLoadBalanceHelper_; - //! The checkpoint helper - std::unique_ptr checkpointHelper_; - //! The stop handler - std::unique_ptr stopHandler_; - //! The reset handler - std::unique_ptr resetHandler_; - //! Signal vector (used by stop / reset / checkpointing signaller) - SimulationSignals signals_; - //! Compute globals communication period - int nstglobalcomm_; + // Infrastructure elements + //! The domain decomposition element + std::unique_ptr domDecHelper_; + //! The PME load balancing element + std::unique_ptr pmeLoadBalanceHelper_; + //! The checkpoint helper + std::unique_ptr checkpointHelper_; + //! The stop handler + std::unique_ptr stopHandler_; + //! The reset handler + std::unique_ptr resetHandler_; + //! Signal vector (used by stop / reset / checkpointing signaller) + SimulationSignals signals_; + //! Compute globals communication period + int nstglobalcomm_; - //! The topology - std::unique_ptr topologyHolder_; + //! The topology + std::unique_ptr topologyHolder_; - //! The current step - Step step_ = -1; + //! The current step + Step step_ = -1; - /*! \internal - * \brief Signal helper - * - * The simulator needs to know about the last step and the - * neighbor searching step, which are determined in signallers. - * This object can be registered to the signals and accessed by - * the methods of the simulator. - */ - class SignalHelper : - public ILastStepSignallerClient, - public INeighborSearchSignallerClient - { - public: - //! The last step - Step lastStep_ = std::numeric_limits::max(); - //! The next NS step - Step nextNSStep_ = -1; - //! ILastStepSignallerClient implementation - SignallerCallbackPtr registerLastStepCallback() override; - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; - }; - //! The signal helper object - std::unique_ptr signalHelper_; + /*! \internal + * \brief Signal helper + * + * The simulator needs to know about the last step and the + * neighbor searching step, which are determined in signallers. + * This object can be registered to the signals and accessed by + * the methods of the simulator. + */ + class SignalHelper : public ILastStepSignallerClient, public INeighborSearchSignallerClient + { + public: + //! The last step + Step lastStep_ = std::numeric_limits::max(); + //! The next NS step + Step nextNSStep_ = -1; + //! ILastStepSignallerClient implementation + SignallerCallbackPtr registerLastStepCallback() override; + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; + }; + //! The signal helper object + std::unique_ptr signalHelper_; - // TODO: This is a hack for stop handler - needs to go once StopHandler - // is adapted to the modular simulator - //! Whether this is a neighbor-searching step - bool stophandlerIsNSStep_ = false; - //! The current step - Step stophandlerCurrentStep_ = -1; + // TODO: This is a hack for stop handler - needs to go once StopHandler + // is adapted to the modular simulator + //! Whether this is a neighbor-searching step + bool stophandlerIsNSStep_ = false; + //! The current step + Step stophandlerCurrentStep_ = -1; }; //! Constructor implementation (here to avoid template-related linker problems) -template -ModularSimulator::ModularSimulator(Args && ... args) : - ISimulator(std::forward(args) ...) +template +ModularSimulator::ModularSimulator(Args&&... args) : ISimulator(std::forward(args)...) { nstglobalcomm_ = computeGlobalCommunicationPeriod(mdlog, inputrec, cr); signalHelper_ = std::make_unique(); @@ -307,33 +297,29 @@ ModularSimulator::ModularSimulator(Args && ... args) : } //! \cond -template -void ModularSimulator::addToCallList( - gmx::compat::not_null element, - std::vector < compat::not_null < T *>> &callList) +template +void ModularSimulator::addToCallList(gmx::compat::not_null element, + std::vector>& callList) { callList.emplace_back(element); } -template -void ModularSimulator::addToCallList( - std::unique_ptr &element, - std::vector < compat::not_null < T *>> &callList) +template +void ModularSimulator::addToCallList(std::unique_ptr& element, std::vector>& callList) { callList.emplace_back(compat::make_not_null(element.get())); } -template -void ModularSimulator::addToCallListAndMove( - std::unique_ptr element, - std::vector < compat::not_null < T *>> &callList, - std::vector < std::unique_ptr < T>> &elementList) +template +void ModularSimulator::addToCallListAndMove(std::unique_ptr element, + std::vector>& callList, + std::vector>& elementList) { callList.emplace_back(compat::make_not_null(element.get())); elementList.emplace_back(std::move(element)); } //! \endcond -} // namespace gmx +} // namespace gmx #endif // GROMACS_MODULARSIMULATOR_MODULARSIMULATOR_H diff --git a/src/gromacs/modularsimulator/modularsimulatorinterfaces.h b/src/gromacs/modularsimulator/modularsimulatorinterfaces.h index 0a3364e6db..a93b2070fb 100644 --- a/src/gromacs/modularsimulator/modularsimulatorinterfaces.h +++ b/src/gromacs/modularsimulator/modularsimulatorinterfaces.h @@ -65,7 +65,8 @@ class t_state; namespace gmx { -template class SignallerBuilder; +template +class SignallerBuilder; class NeighborSearchSignaller; class LastStepSignaller; class LoggingSignaller; @@ -104,19 +105,19 @@ typedef std::unique_ptr RegisterRunFunctionPtr; */ class ISimulatorElement { - public: - /*! \brief Query whether element wants to run at step / time - * - * Element can register one or more functions to be run at that step through - * the registration pointer. - */ - virtual void scheduleTask(Step, Time, const RegisterRunFunctionPtr&) = 0; - //! Method guaranteed to be called after construction, before simulator run - virtual void elementSetup() = 0; - //! Method guaranteed to be called after simulator run, before deconstruction - virtual void elementTeardown() = 0; - //! Standard virtual destructor - virtual ~ISimulatorElement() = default; +public: + /*! \brief Query whether element wants to run at step / time + * + * Element can register one or more functions to be run at that step through + * the registration pointer. + */ + virtual void scheduleTask(Step, Time, const RegisterRunFunctionPtr&) = 0; + //! Method guaranteed to be called after construction, before simulator run + virtual void elementSetup() = 0; + //! Method guaranteed to be called after simulator run, before deconstruction + virtual void elementTeardown() = 0; + //! Standard virtual destructor + virtual ~ISimulatorElement() = default; }; /*! \libinternal @@ -137,13 +138,13 @@ class ISimulatorElement */ class ISignaller { - public: - //! Function run before every step of scheduling - virtual void signal(Step, Time) = 0; - //! Method guaranteed to be called after construction, before simulator run - virtual void signallerSetup() = 0; - //! Standard virtual destructor - virtual ~ISignaller() = default; +public: + //! Function run before every step of scheduling + virtual void signal(Step, Time) = 0; + //! Method guaranteed to be called after construction, before simulator run + virtual void signallerSetup() = 0; + //! Standard virtual destructor + virtual ~ISignaller() = default; }; //! The function type that can be registered to signallers for callback @@ -159,18 +160,18 @@ typedef std::unique_ptr SignallerCallbackPtr; */ class INeighborSearchSignallerClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow builder of NeighborSearchSignaller to ask for callback registration - friend class SignallerBuilder; - //! @endcond - //! Standard virtual destructor - virtual ~INeighborSearchSignallerClient() = default; - - protected: - //! Return callback to NeighborSearchSignaller - virtual SignallerCallbackPtr registerNSCallback() = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow builder of NeighborSearchSignaller to ask for callback registration + friend class SignallerBuilder; + //! @endcond + //! Standard virtual destructor + virtual ~INeighborSearchSignallerClient() = default; + +protected: + //! Return callback to NeighborSearchSignaller + virtual SignallerCallbackPtr registerNSCallback() = 0; }; /*! \libinternal @@ -181,18 +182,18 @@ class INeighborSearchSignallerClient */ class ILastStepSignallerClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow builder of LastStepSignaller to ask for callback registration - friend class SignallerBuilder; - //! @endcond - //! Standard virtual destructor - virtual ~ILastStepSignallerClient() = default; - - protected: - //! Return callback to LastStepSignaller - virtual SignallerCallbackPtr registerLastStepCallback() = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow builder of LastStepSignaller to ask for callback registration + friend class SignallerBuilder; + //! @endcond + //! Standard virtual destructor + virtual ~ILastStepSignallerClient() = default; + +protected: + //! Return callback to LastStepSignaller + virtual SignallerCallbackPtr registerLastStepCallback() = 0; }; /*! \libinternal @@ -203,18 +204,18 @@ class ILastStepSignallerClient */ class ILoggingSignallerClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow builder of LoggingSignaller to ask for callback registration - friend class SignallerBuilder; - //! @endcond - //! Standard virtual destructor - virtual ~ILoggingSignallerClient() = default; - - protected: - //! Return callback to LoggingSignaller - virtual SignallerCallbackPtr registerLoggingCallback() = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow builder of LoggingSignaller to ask for callback registration + friend class SignallerBuilder; + //! @endcond + //! Standard virtual destructor + virtual ~ILoggingSignallerClient() = default; + +protected: + //! Return callback to LoggingSignaller + virtual SignallerCallbackPtr registerLoggingCallback() = 0; }; //! The energy events signalled by the EnergySignaller @@ -233,18 +234,18 @@ enum class EnergySignallerEvent */ class IEnergySignallerClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow builder of EnergySignaller to ask for callback registration - friend class SignallerBuilder; - //! @endcond - //! Standard virtual destructor - virtual ~IEnergySignallerClient() = default; - - protected: - //! Return callback to EnergySignaller - virtual SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent) = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow builder of EnergySignaller to ask for callback registration + friend class SignallerBuilder; + //! @endcond + //! Standard virtual destructor + virtual ~IEnergySignallerClient() = default; + +protected: + //! Return callback to EnergySignaller + virtual SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent) = 0; }; //! The trajectory writing events @@ -262,19 +263,18 @@ enum class TrajectoryEvent */ class ITrajectorySignallerClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow builder of TrajectoryElement to ask for callback registration - friend class TrajectoryElementBuilder; - //! @endcond - //! Standard virtual destructor - virtual ~ITrajectorySignallerClient() = default; - - protected: - //! Return callback to TrajectoryElement - virtual SignallerCallbackPtr - registerTrajectorySignallerCallback(TrajectoryEvent) = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow builder of TrajectoryElement to ask for callback registration + friend class TrajectoryElementBuilder; + //! @endcond + //! Standard virtual destructor + virtual ~ITrajectorySignallerClient() = default; + +protected: + //! Return callback to TrajectoryElement + virtual SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent) = 0; }; /* Trajectory writing clients are handed a pointer to the output file handler, @@ -301,24 +301,23 @@ typedef std::unique_ptr ITrajectoryWriterCallbackPtr; */ class ITrajectoryWriterClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow TrajectoryElement to ask for callback registration - friend class TrajectoryElement; - //! @endcond - //! Standard virtual destructor - virtual ~ITrajectoryWriterClient() = default; - - protected: - //! Setup method with valid output pointer. - virtual void trajectoryWriterSetup(gmx_mdoutf *outf) = 0; - //! Teardown method with valid output pointer. - virtual void trajectoryWriterTeardown(gmx_mdoutf *outf) = 0; - - //! Return callback to TrajectoryElement - virtual ITrajectoryWriterCallbackPtr - registerTrajectoryWriterCallback(TrajectoryEvent) = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow TrajectoryElement to ask for callback registration + friend class TrajectoryElement; + //! @endcond + //! Standard virtual destructor + virtual ~ITrajectoryWriterClient() = default; + +protected: + //! Setup method with valid output pointer. + virtual void trajectoryWriterSetup(gmx_mdoutf* outf) = 0; + //! Teardown method with valid output pointer. + virtual void trajectoryWriterTeardown(gmx_mdoutf* outf) = 0; + + //! Return callback to TrajectoryElement + virtual ITrajectoryWriterCallbackPtr registerTrajectoryWriterCallback(TrajectoryEvent) = 0; }; /*! \libinternal @@ -327,18 +326,18 @@ class ITrajectoryWriterClient */ class ITopologyHolderClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow TopologyHolder to set new topology - friend class TopologyHolder; - //! @endcond - //! Standard virtual destructor - virtual ~ITopologyHolderClient() = default; - - protected: - //! Pass pointer to new local topology - virtual void setTopology(const gmx_localtop_t*) = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow TopologyHolder to set new topology + friend class TopologyHolder; + //! @endcond + //! Standard virtual destructor + virtual ~ITopologyHolderClient() = default; + +protected: + //! Pass pointer to new local topology + virtual void setTopology(const gmx_localtop_t*) = 0; }; /*! \libinternal @@ -354,20 +353,20 @@ class ITopologyHolderClient */ class ICheckpointHelperClient { - public: - //! @cond - // (doxygen doesn't like these...) - //! Allow CheckpointHelper to interact - friend class CheckpointHelper; - //! @endcond - //! Standard virtual destructor - virtual ~ICheckpointHelperClient() = default; - - protected: - //! Write checkpoint - virtual void writeCheckpoint(t_state* localState, t_state* globalState) = 0; +public: + //! @cond + // (doxygen doesn't like these...) + //! Allow CheckpointHelper to interact + friend class CheckpointHelper; + //! @endcond + //! Standard virtual destructor + virtual ~ICheckpointHelperClient() = default; + +protected: + //! Write checkpoint + virtual void writeCheckpoint(t_state* localState, t_state* globalState) = 0; }; //! /} -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_MODULARSIMULATORINTERFACES_H diff --git a/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp b/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp index f0d1014fbe..97211394ab 100644 --- a/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp +++ b/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp @@ -59,21 +59,20 @@ namespace gmx { -ParrinelloRahmanBarostat::ParrinelloRahmanBarostat( - int nstpcouple, - int offset, - real couplingTimeStep, - Step initStep, - ArrayRef scalingTensor, - PropagatorCallbackPtr propagatorCallback, - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FILE *fplog, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - const t_state *globalState, - t_commrec *cr, - bool isRestart) : +ParrinelloRahmanBarostat::ParrinelloRahmanBarostat(int nstpcouple, + int offset, + real couplingTimeStep, + Step initStep, + ArrayRef scalingTensor, + PropagatorCallbackPtr propagatorCallback, + StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FILE* fplog, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + const t_state* globalState, + t_commrec* cr, + bool isRestart) : nstpcouple_(nstpcouple), offset_(offset), couplingTimeStep_(couplingTimeStep), @@ -108,9 +107,9 @@ ParrinelloRahmanBarostat::ParrinelloRahmanBarostat( } } -void ParrinelloRahmanBarostat::scheduleTask( - gmx::Step step, gmx::Time gmx_unused time, - const gmx::RegisterRunFunctionPtr ®isterRunFunction) +void ParrinelloRahmanBarostat::scheduleTask(gmx::Step step, + gmx::Time gmx_unused time, + const gmx::RegisterRunFunctionPtr& registerRunFunction) { const bool scaleOnNextStep = do_per_step(step + nstpcouple_ + offset_ + 1, nstpcouple_); const bool scaleOnThisStep = do_per_step(step + nstpcouple_ + offset_, nstpcouple_); @@ -118,26 +117,22 @@ void ParrinelloRahmanBarostat::scheduleTask( if (scaleOnThisStep) { (*registerRunFunction)( - std::make_unique( - [this](){ scaleBoxAndPositions(); })); + std::make_unique([this]() { scaleBoxAndPositions(); })); } if (scaleOnNextStep) { - (*registerRunFunction)( - std::make_unique( - [this, step](){ integrateBoxVelocityEquations(step); })); + (*registerRunFunction)(std::make_unique( + [this, step]() { integrateBoxVelocityEquations(step); })); // let propagator know that it will have to scale on next step - (*propagatorCallback_)(step+1); + (*propagatorCallback_)(step + 1); } } void ParrinelloRahmanBarostat::integrateBoxVelocityEquations(Step step) { auto box = statePropagatorData_->constBox(); - parrinellorahman_pcoupl( - fplog_, step, inputrec_, couplingTimeStep_, energyElement_->pressure(step), - box, boxRel_, boxVelocity_, - scalingTensor_.data(), mu_, isInitStep_); + parrinellorahman_pcoupl(fplog_, step, inputrec_, couplingTimeStep_, energyElement_->pressure(step), + box, boxRel_, boxVelocity_, scalingTensor_.data(), mu_, isInitStep_); // multiply matrix by the coupling time step to avoid having the propagator needing to know about that msmul(scalingTensor_.data(), couplingTimeStep_, scalingTensor_.data()); } @@ -150,7 +145,7 @@ void ParrinelloRahmanBarostat::scaleBoxAndPositions() { for (int m = 0; m <= i; m++) { - box[i][m] += couplingTimeStep_*boxVelocity_[i][m]; + box[i][m] += couplingTimeStep_ * boxVelocity_[i][m]; } } preserve_box_shape(inputrec_, boxRel_, box); @@ -178,7 +173,7 @@ void ParrinelloRahmanBarostat::elementSetup() if (scaleOnInitStep) { integrateBoxVelocityEquations(initStep_); - (*propagatorCallback_)(initStep_+1); + (*propagatorCallback_)(initStep_ + 1); } isInitStep_ = false; } @@ -188,12 +183,12 @@ const rvec* ParrinelloRahmanBarostat::boxVelocities() const return boxVelocity_; } -void ParrinelloRahmanBarostat::writeCheckpoint(t_state *localState, t_state gmx_unused *globalState) +void ParrinelloRahmanBarostat::writeCheckpoint(t_state* localState, t_state gmx_unused* globalState) { copy_mat(boxVelocity_, localState->boxv); copy_mat(boxRel_, localState->box_rel); - localState->flags |= (1u << estBOXV) | (1u << estBOX_REL); + localState->flags |= (1U << estBOXV) | (1U << estBOX_REL); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/parrinellorahmanbarostat.h b/src/gromacs/modularsimulator/parrinellorahmanbarostat.h index e66aba52a3..d73dbdbdc3 100644 --- a/src/gromacs/modularsimulator/parrinellorahmanbarostat.h +++ b/src/gromacs/modularsimulator/parrinellorahmanbarostat.h @@ -66,93 +66,88 @@ class StatePropagatorData; * scaling factor, and * * scales the box and the positions of the system. */ -class ParrinelloRahmanBarostat final : - public ISimulatorElement, - public ICheckpointHelperClient +class ParrinelloRahmanBarostat final : public ISimulatorElement, public ICheckpointHelperClient { - public: - //! Constructor - ParrinelloRahmanBarostat( - int nstpcouple, - int offset, - real couplingTimeStep, - Step initStep, - ArrayRef scalingTensor, - PropagatorCallbackPtr propagatorCallback, - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FILE *fplog, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - const t_state *globalState, - t_commrec *cr, - bool isRestart); - - /*! \brief Register run function for step / time - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! Fix relative box shape - void elementSetup() override; - //! No element teardown needed - void elementTeardown() override {} - - //! Getter for the box velocities - const rvec* boxVelocities() const; - - private: - //! The frequency at which the barostat is applied - const int nstpcouple_; - //! If != 0, offset the step at which the barostat is applied - const int offset_; - //! The coupling time step - simulation time step x nstcouple_ - const real couplingTimeStep_; - //! The first step of the simulation - const Step initStep_; - - //! Whether this is the first step - bool isInitStep_; - - //! View on the velocity scaling tensor (owned by the propagator) - ArrayRef scalingTensor_; - //! Callback to let propagator know that we updated lambda - PropagatorCallbackPtr propagatorCallback_; - - //! Relative change in box before - after barostatting - matrix mu_; - //! Relative box shape - tensor boxRel_; - //! Box velocity - tensor boxVelocity_; - - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - //! Pointer to the energy element - EnergyElement *energyElement_; - - //! Integrate the PR box vector equations of motion - does not alter state - void integrateBoxVelocityEquations(Step step); - //! Scale box and positions - void scaleBoxAndPositions(); - - //! ICheckpointHelperClient implementation - void writeCheckpoint(t_state *localState, t_state *globalState) override; - - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; +public: + //! Constructor + ParrinelloRahmanBarostat(int nstpcouple, + int offset, + real couplingTimeStep, + Step initStep, + ArrayRef scalingTensor, + PropagatorCallbackPtr propagatorCallback, + StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FILE* fplog, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + const t_state* globalState, + t_commrec* cr, + bool isRestart); + + /*! \brief Register run function for step / time + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! Fix relative box shape + void elementSetup() override; + //! No element teardown needed + void elementTeardown() override {} + + //! Getter for the box velocities + const rvec* boxVelocities() const; + +private: + //! The frequency at which the barostat is applied + const int nstpcouple_; + //! If != 0, offset the step at which the barostat is applied + const int offset_; + //! The coupling time step - simulation time step x nstcouple_ + const real couplingTimeStep_; + //! The first step of the simulation + const Step initStep_; + + //! Whether this is the first step + bool isInitStep_; + + //! View on the velocity scaling tensor (owned by the propagator) + ArrayRef scalingTensor_; + //! Callback to let propagator know that we updated lambda + PropagatorCallbackPtr propagatorCallback_; + + //! Relative change in box before - after barostatting + matrix mu_; + //! Relative box shape + tensor boxRel_; + //! Box velocity + tensor boxVelocity_; + + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + //! Pointer to the energy element + EnergyElement* energyElement_; + + //! Integrate the PR box vector equations of motion - does not alter state + void integrateBoxVelocityEquations(Step step); + //! Scale box and positions + void scaleBoxAndPositions(); + + //! ICheckpointHelperClient implementation + void writeCheckpoint(t_state* localState, t_state* globalState) override; + + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_PARRINELLORAHMANBAROSTAT_H diff --git a/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp b/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp index 75d9238103..718fc2ccbf 100644 --- a/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp +++ b/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp @@ -55,24 +55,22 @@ namespace gmx { -bool PmeLoadBalanceHelper::doPmeLoadBalancing( - const MdrunOptions &mdrunOptions, - const t_inputrec *inputrec, - const t_forcerec *fr) +bool PmeLoadBalanceHelper::doPmeLoadBalancing(const MdrunOptions& mdrunOptions, + const t_inputrec* inputrec, + const t_forcerec* fr) { - return (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && - !mdrunOptions.reproducible && inputrec->cutoff_scheme != ecutsGROUP); + return (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && !mdrunOptions.reproducible + && inputrec->cutoff_scheme != ecutsGROUP); } -PmeLoadBalanceHelper::PmeLoadBalanceHelper( - bool isVerbose, - StatePropagatorData *statePropagatorData, - FILE *fplog, - t_commrec *cr, - const MDLogger &mdlog, - const t_inputrec *inputrec, - gmx_wallcycle *wcycle, - t_forcerec *fr) : +PmeLoadBalanceHelper::PmeLoadBalanceHelper(bool isVerbose, + StatePropagatorData* statePropagatorData, + FILE* fplog, + t_commrec* cr, + const MDLogger& mdlog, + const t_inputrec* inputrec, + gmx_wallcycle* wcycle, + t_forcerec* fr) : pme_loadbal_(nullptr), nextNSStep_(-1), isVerbose_(isVerbose), @@ -84,16 +82,16 @@ PmeLoadBalanceHelper::PmeLoadBalanceHelper( inputrec_(inputrec), wcycle_(wcycle), fr_(fr) -{} +{ +} void PmeLoadBalanceHelper::setup() { auto box = statePropagatorData_->constBox(); GMX_RELEASE_ASSERT(box[0][0] != 0 && box[1][1] != 0 && box[2][2] != 0, "PmeLoadBalanceHelper cannot be initialized with zero box."); - pme_loadbal_init(&pme_loadbal_, cr_, mdlog_, *inputrec_, box, - *fr_->ic, *fr_->nbv, fr_->pmedata, fr_->nbv->useGpu(), - &bPMETunePrinting_); + pme_loadbal_init(&pme_loadbal_, cr_, mdlog_, *inputrec_, box, *fr_->ic, *fr_->nbv, fr_->pmedata, + fr_->nbv->useGpu(), &bPMETunePrinting_); } void PmeLoadBalanceHelper::run(gmx::Step step, gmx::Time gmx_unused time) @@ -104,15 +102,10 @@ void PmeLoadBalanceHelper::run(gmx::Step step, gmx::Time gmx_unused time) } // PME grid + cut-off optimization with GPUs or PME nodes - pme_loadbal_do(pme_loadbal_, cr_, - (isVerbose_ && MASTER(cr_)) ? stderr : nullptr, - fplog_, mdlog_, - *inputrec_, fr_, - statePropagatorData_->constBox(), - statePropagatorData_->constPositionsView().paddedArrayRef(), - wcycle_, - step, step - inputrec_->init_step, - &bPMETunePrinting_); + pme_loadbal_do(pme_loadbal_, cr_, (isVerbose_ && MASTER(cr_)) ? stderr : nullptr, fplog_, + mdlog_, *inputrec_, fr_, statePropagatorData_->constBox(), + statePropagatorData_->constPositionsView().paddedArrayRef(), wcycle_, step, + step - inputrec_->init_step, &bPMETunePrinting_); } void PmeLoadBalanceHelper::teardown() @@ -133,8 +126,7 @@ const pme_load_balancing_t* PmeLoadBalanceHelper::loadBalancingObject() SignallerCallbackPtr PmeLoadBalanceHelper::registerNSCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time) - {nextNSStep_ = step; }); + [this](Step step, Time gmx_unused time) { nextNSStep_ = step; }); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/pmeloadbalancehelper.h b/src/gromacs/modularsimulator/pmeloadbalancehelper.h index 393af05376..39ffa1d039 100644 --- a/src/gromacs/modularsimulator/pmeloadbalancehelper.h +++ b/src/gromacs/modularsimulator/pmeloadbalancehelper.h @@ -69,71 +69,68 @@ class StatePropagatorData; * steps. This allows elements to be aware of any changes before * deciding what functionality they need to run. */ -class PmeLoadBalanceHelper final : - public INeighborSearchSignallerClient +class PmeLoadBalanceHelper final : public INeighborSearchSignallerClient { - public: - //! Constructor - PmeLoadBalanceHelper( - bool isVerbose, - StatePropagatorData *statePropagatorData, - FILE *fplog, - t_commrec *cr, - const MDLogger &mdlog, - const t_inputrec *inputrec, - gmx_wallcycle *wcycle, - t_forcerec *fr); +public: + //! Constructor + PmeLoadBalanceHelper(bool isVerbose, + StatePropagatorData* statePropagatorData, + FILE* fplog, + t_commrec* cr, + const MDLogger& mdlog, + const t_inputrec* inputrec, + gmx_wallcycle* wcycle, + t_forcerec* fr); - //! Initialize the load balancing object - void setup(); - //! Do load balancing - void run(Step step, Time time); - //! Final printout and deconstruction of the load balancing object - void teardown(); - //! Whether PME load balancing printing is active \todo Check this! - bool pmePrinting(); + //! Initialize the load balancing object + void setup(); + //! Do load balancing + void run(Step step, Time time); + //! Final printout and deconstruction of the load balancing object + void teardown(); + //! Whether PME load balancing printing is active \todo Check this! + bool pmePrinting(); - //! Whether we're doing PME load balancing - static bool doPmeLoadBalancing( - const MdrunOptions &mdrunOptions, - const t_inputrec *inputrec, - const t_forcerec *fr); + //! Whether we're doing PME load balancing + static bool doPmeLoadBalancing(const MdrunOptions& mdrunOptions, + const t_inputrec* inputrec, + const t_forcerec* fr); - //! Direct access to the load balancing object - used by reset counter - const pme_load_balancing_t* loadBalancingObject(); + //! Direct access to the load balancing object - used by reset counter + const pme_load_balancing_t* loadBalancingObject(); - private: - //! The PME load balancing object - used by reset counter - pme_load_balancing_t *pme_loadbal_; +private: + //! The PME load balancing object - used by reset counter + pme_load_balancing_t* pme_loadbal_; - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; - //! The next NS step - Step nextNSStep_; - //! Whether we're being verbose - const bool isVerbose_; - //! Whether PME load balancing printing is active \todo Check this! - bool bPMETunePrinting_; + //! The next NS step + Step nextNSStep_; + //! Whether we're being verbose + const bool isVerbose_; + //! Whether PME load balancing printing is active \todo Check this! + bool bPMETunePrinting_; - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - t_commrec *cr_; - //! Handles logging. - const MDLogger &mdlog_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; - //! Parameters for force calculations. - t_forcerec *fr_; + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + t_commrec* cr_; + //! Handles logging. + const MDLogger& mdlog_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; + //! Parameters for force calculations. + t_forcerec* fr_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_PMELOADBALANCEHELPER_H diff --git a/src/gromacs/modularsimulator/propagator.cpp b/src/gromacs/modularsimulator/propagator.cpp index 218cd78584..f35c225701 100644 --- a/src/gromacs/modularsimulator/propagator.cpp +++ b/src/gromacs/modularsimulator/propagator.cpp @@ -57,81 +57,76 @@ namespace gmx { //! Update velocities -template -static void inline -updateVelocities(int a, - real dt, - real lambda, - const rvec * gmx_restrict invMassPerDim, - rvec * gmx_restrict v, - const rvec * gmx_restrict f, - const rvec diagPR, - const matrix matrixPR) +template +static void inline updateVelocities(int a, + real dt, + real lambda, + const rvec* gmx_restrict invMassPerDim, + rvec* gmx_restrict v, + const rvec* gmx_restrict f, + const rvec diagPR, + const matrix matrixPR) { for (int d = 0; d < DIM; d++) { // TODO: Extract this into policy classes - if (numVelocityScalingValues != NumVelocityScalingValues::None && - parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::No) + if (numVelocityScalingValues != NumVelocityScalingValues::None + && parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::No) { v[a][d] *= lambda; } - if (numVelocityScalingValues != NumVelocityScalingValues::None && - parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Diagonal) + if (numVelocityScalingValues != NumVelocityScalingValues::None + && parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Diagonal) { v[a][d] *= (lambda - diagPR[d]); } - if (numVelocityScalingValues != NumVelocityScalingValues::None && - parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Full) + if (numVelocityScalingValues != NumVelocityScalingValues::None + && parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Full) { - v[a][d] = lambda*v[a][d] - iprod(matrixPR[d], v[a]); + v[a][d] = lambda * v[a][d] - iprod(matrixPR[d], v[a]); } - if (numVelocityScalingValues == NumVelocityScalingValues::None && - parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Diagonal) + if (numVelocityScalingValues == NumVelocityScalingValues::None + && parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Diagonal) { - v[a][d] *= (1-diagPR[d]); + v[a][d] *= (1 - diagPR[d]); } - if (numVelocityScalingValues == NumVelocityScalingValues::None && - parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Full) + if (numVelocityScalingValues == NumVelocityScalingValues::None + && parrinelloRahmanVelocityScaling == ParrinelloRahmanVelocityScaling::Full) { v[a][d] -= iprod(matrixPR[d], v[a]); } - v[a][d] += f[a][d]*invMassPerDim[a][d]*dt; + v[a][d] += f[a][d] * invMassPerDim[a][d] * dt; } } //! Update positions -static void inline -updatePositions(int a, - real dt, - const rvec * gmx_restrict x, - rvec * gmx_restrict xprime, - const rvec * gmx_restrict v) +static void inline updatePositions(int a, + real dt, + const rvec* gmx_restrict x, + rvec* gmx_restrict xprime, + const rvec* gmx_restrict v) { for (int d = 0; d < DIM; d++) { - xprime[a][d] = x[a][d] + v[a][d]*dt; + xprime[a][d] = x[a][d] + v[a][d] * dt; } } //! Propagation (position only) -template <> -template +template<> +template void Propagator::run() { wallcycle_start(wcycle_, ewcUPDATE); auto xp = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); - auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); - auto v = as_rvec_array(statePropagatorData_->constVelocitiesView().paddedArrayRef().data()); + auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); + auto v = as_rvec_array(statePropagatorData_->constVelocitiesView().paddedArrayRef().data()); - int nth = gmx_omp_nthreads_get(emntUpdate); - int homenr = mdAtoms_->mdatoms()->homenr; + int nth = gmx_omp_nthreads_get(emntUpdate); + int homenr = mdAtoms_->mdatoms()->homenr; - #pragma omp parallel for num_threads(nth) schedule(static) default(none) \ - shared(nth, homenr, x, xp, v) +#pragma omp parallel for num_threads(nth) schedule(static) default(none) shared(nth, homenr, x, xp, v) for (int th = 0; th < nth; th++) { try @@ -150,20 +145,20 @@ void Propagator::run() } //! Propagation (velocity only) -template <> -template +template<> +template void Propagator::run() { wallcycle_start(wcycle_, ewcUPDATE); - auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); - auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); - auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; + auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); + auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; - const real lambda = (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; + const real lambda = + (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; - bool doDiagonalScaling = false; + bool doDiagonalScaling = false; if (parrinelloRahmanVelocityScaling != ParrinelloRahmanVelocityScaling::No) { // TODO: Could we know in advance whether the matrix is diagonal? @@ -176,13 +171,13 @@ void Propagator::run() } } - int nth = gmx_omp_nthreads_get(emntUpdate); - int homenr = mdAtoms_->mdatoms()->homenr; + int nth = gmx_omp_nthreads_get(emntUpdate); + int homenr = mdAtoms_->mdatoms()->homenr; - // lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... - // https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing - #pragma omp parallel for num_threads(nth) schedule(static) default(none) \ - shared(nth, homenr, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) +// lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... +// https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing +#pragma omp parallel for num_threads(nth) schedule(static) default(none) \ + shared(nth, homenr, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) for (int th = 0; th < nth; th++) { try @@ -196,15 +191,13 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( + updateVelocities( a, timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( + updateVelocities( a, timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } @@ -214,15 +207,13 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( + updateVelocities( a, timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( + updateVelocities( a, timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } @@ -230,15 +221,13 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( + updateVelocities( a, timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( + updateVelocities( a, timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } @@ -251,22 +240,22 @@ void Propagator::run() } //! Propagation (leapfrog case - position and velocity) -template <> -template +template<> +template void Propagator::run() { wallcycle_start(wcycle_, ewcUPDATE); - auto xp = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); - auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); - auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); - auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); - auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; + auto xp = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); + auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); + auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); + auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; - const real lambda = (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; + const real lambda = + (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; - bool doDiagonalScaling = false; + bool doDiagonalScaling = false; if (parrinelloRahmanVelocityScaling != ParrinelloRahmanVelocityScaling::No) { // TODO: Could we know in advance whether the matrix is diagonal? @@ -279,13 +268,13 @@ void Propagator::run() } } - int nth = gmx_omp_nthreads_get(emntUpdate); - int homenr = mdAtoms_->mdatoms()->homenr; + int nth = gmx_omp_nthreads_get(emntUpdate); + int homenr = mdAtoms_->mdatoms()->homenr; - // lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... - // https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing - #pragma omp parallel for num_threads(nth) schedule(static) default(none) \ - shared(nth, homenr, x, xp, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) +// lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... +// https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing +#pragma omp parallel for num_threads(nth) schedule(static) default(none) \ + shared(nth, homenr, x, xp, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) for (int th = 0; th < nth; th++) { try @@ -315,15 +304,13 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( + updateVelocities( a, timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( + updateVelocities( a, timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } @@ -331,15 +318,13 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( + updateVelocities( a, timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( + updateVelocities( a, timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } @@ -353,25 +338,25 @@ void Propagator::run() } //! Propagation (velocity verlet stage 2 - velocity and position) -template <> -template +template<> +template void Propagator::run() { wallcycle_start(wcycle_, ewcUPDATE); - auto xp = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); - auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); - auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); - auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); - auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; + auto xp = as_rvec_array(statePropagatorData_->positionsView().paddedArrayRef().data()); + auto x = as_rvec_array(statePropagatorData_->constPreviousPositionsView().paddedArrayRef().data()); + auto v = as_rvec_array(statePropagatorData_->velocitiesView().paddedArrayRef().data()); + auto f = as_rvec_array(statePropagatorData_->constForcesView().paddedArrayRef().data()); + auto invMassPerDim = mdAtoms_->mdatoms()->invMassPerDim; - int nth = gmx_omp_nthreads_get(emntUpdate); - int homenr = mdAtoms_->mdatoms()->homenr; + int nth = gmx_omp_nthreads_get(emntUpdate); + int homenr = mdAtoms_->mdatoms()->homenr; - const real lambda = (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; + const real lambda = + (numVelocityScalingValues == NumVelocityScalingValues::Single) ? velocityScaling_[0] : 1.0; - bool doDiagonalScaling = false; + bool doDiagonalScaling = false; if (parrinelloRahmanVelocityScaling != ParrinelloRahmanVelocityScaling::No) { // TODO: Could we know in advance whether the matrix is diagonal? @@ -384,10 +369,10 @@ void Propagator::run() } } - // lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... - // https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing - #pragma omp parallel for num_threads(nth) schedule(static) default(none) \ - shared(nth, homenr, x, xp, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) +// lambda could be shared, but gcc-8 & gcc-9 don't agree how to write that... +// https://www.gnu.org/software/gcc/gcc-9/porting_to.html -> OpenMP data sharing +#pragma omp parallel for num_threads(nth) schedule(static) default(none) \ + shared(nth, homenr, x, xp, v, f, invMassPerDim, doDiagonalScaling) firstprivate(lambda) for (int th = 0; th < nth; th++) { try @@ -401,16 +386,14 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( - a, 0.5*timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], + updateVelocities( + a, 0.5 * timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( - a, 0.5*timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); + updateVelocities( + a, 0.5 * timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } else @@ -419,32 +402,28 @@ void Propagator::run() { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( - a, 0.5*timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], + updateVelocities( + a, 0.5 * timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( - a, 0.5*timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); + updateVelocities( + a, 0.5 * timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } else { if (numVelocityScalingValues == NumVelocityScalingValues::Multiple) { - updateVelocities( - a, 0.5*timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], + updateVelocities( + a, 0.5 * timestep_, velocityScaling_[mdAtoms_->mdatoms()->cTC[a]], invMassPerDim, v, f, diagPR, matrixPR); } else { - updateVelocities( - a, 0.5*timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); + updateVelocities( + a, 0.5 * timestep_, lambda, invMassPerDim, v, f, diagPR, matrixPR); } } } @@ -456,12 +435,11 @@ void Propagator::run() wallcycle_stop(wcycle_, ewcUPDATE); } -template -Propagator::Propagator( - double timestep, - StatePropagatorData *statePropagatorData, - const MDAtoms *mdAtoms, - gmx_wallcycle *wcycle) : +template +Propagator::Propagator(double timestep, + StatePropagatorData* statePropagatorData, + const MDAtoms* mdAtoms, + gmx_wallcycle* wcycle) : timestep_(timestep), statePropagatorData_(statePropagatorData), doSingleVelocityScaling(false), @@ -475,13 +453,13 @@ Propagator::Propagator( clear_mat(matrixPR); } -template -void Propagator::scheduleTask( - Step gmx_unused step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +template +void Propagator::scheduleTask(Step gmx_unused step, + Time gmx_unused time, + const RegisterRunFunctionPtr& registerRunFunction) { - const bool doSingleVScalingThisStep = (doSingleVelocityScaling && (step == scalingStepVelocity_)); - const bool doGroupVScalingThisStep = (doGroupVelocityScaling && (step == scalingStepVelocity_)); + const bool doSingleVScalingThisStep = (doSingleVelocityScaling && (step == scalingStepVelocity_)); + const bool doGroupVScalingThisStep = (doGroupVelocityScaling && (step == scalingStepVelocity_)); const bool doParrinelloRahmanThisStep = (step == scalingStepPR_); @@ -489,56 +467,50 @@ void Propagator::scheduleTask( { if (doParrinelloRahmanThisStep) { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } else { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } } else if (doGroupVScalingThisStep) { if (doParrinelloRahmanThisStep) { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } else { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } } else { if (doParrinelloRahmanThisStep) { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } else { - (*registerRunFunction)( - std::make_unique( - [this](){run(); })); + (*registerRunFunction)(std::make_unique([this]() { + run(); + })); } } } -template +template void Propagator::setNumVelocityScalingVariables(int numVelocityScalingVariables) { if (algorithm == IntegrationStep::PositionsOnly) @@ -553,36 +525,35 @@ void Propagator::setNumVelocityScalingVariables(int numVelocityScalin doGroupVelocityScaling = numVelocityScalingVariables > 1; } -template +template ArrayRef Propagator::viewOnVelocityScaling() { if (algorithm == IntegrationStep::PositionsOnly) { gmx_fatal(FARGS, "Velocity scaling not implemented for IntegrationStep::PositionsOnly."); } - GMX_ASSERT(!velocityScaling_.empty(), - "Number of velocity scaling variables not set."); + GMX_ASSERT(!velocityScaling_.empty(), "Number of velocity scaling variables not set."); return velocityScaling_; } -template -std::unique_ptr< std::function > Propagator::velocityScalingCallback() +template +std::unique_ptr> Propagator::velocityScalingCallback() { if (algorithm == IntegrationStep::PositionsOnly) { gmx_fatal(FARGS, "Velocity scaling not implemented for IntegrationStep::PositionsOnly."); } - return std::make_unique( - [this](Step step){scalingStepVelocity_ = step; }); + return std::make_unique([this](Step step) { scalingStepVelocity_ = step; }); } -template +template ArrayRef Propagator::viewOnPRScalingMatrix() { - GMX_RELEASE_ASSERT(algorithm != IntegrationStep::PositionsOnly, - "Parrinello-Rahman scaling not implemented for IntegrationStep::PositionsOnly."); + GMX_RELEASE_ASSERT( + algorithm != IntegrationStep::PositionsOnly, + "Parrinello-Rahman scaling not implemented for IntegrationStep::PositionsOnly."); clear_mat(matrixPR); // gcc-5 needs this to be explicit (all other tested compilers would be ok @@ -590,14 +561,14 @@ ArrayRef Propagator::viewOnPRScalingMatrix() return ArrayRef(matrixPR); } -template +template PropagatorCallbackPtr Propagator::prScalingCallback() { - GMX_RELEASE_ASSERT(algorithm != IntegrationStep::PositionsOnly, - "Parrinello-Rahman scaling not implemented for IntegrationStep::PositionsOnly."); + GMX_RELEASE_ASSERT( + algorithm != IntegrationStep::PositionsOnly, + "Parrinello-Rahman scaling not implemented for IntegrationStep::PositionsOnly."); - return std::make_unique( - [this](Step step){scalingStepPR_ = step; }); + return std::make_unique([this](Step step) { scalingStepPR_ = step; }); } //! Explicit template initialization @@ -608,4 +579,4 @@ template class Propagator; template class Propagator; //! @} -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/propagator.h b/src/gromacs/modularsimulator/propagator.h index d404550664..01a22d57f7 100644 --- a/src/gromacs/modularsimulator/propagator.h +++ b/src/gromacs/modularsimulator/propagator.h @@ -119,81 +119,76 @@ typedef std::unique_ptr PropagatorCallbackPtr; * * @tparam algorithm The integration types */ -template -class Propagator final : - public ISimulatorElement +template +class Propagator final : public ISimulatorElement { - public: - //! Constructor - Propagator( - double timestep, - StatePropagatorData *statePropagatorData, - const MDAtoms *mdAtoms, - gmx_wallcycle *wcycle); - - /*! \brief Register run function for step / time - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! No element setup needed - void elementSetup() override {} - //! No element teardown needed - void elementTeardown() override {} - - //! Set the number of velocity scaling variables - void setNumVelocityScalingVariables(int numVelocityScalingVariables); - //! Get view on the velocity scaling vector - ArrayRef viewOnVelocityScaling(); - //! Get velocity scaling callback - PropagatorCallbackPtr velocityScalingCallback(); - - //! Get view on the full PR scaling matrix - ArrayRef viewOnPRScalingMatrix(); - //! Get PR scaling callback - PropagatorCallbackPtr prScalingCallback(); - - private: - //! The actual propagation - template - void run(); - - //! The time step - const real timestep_; - - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - - //! Whether we're doing single-value velocity scaling - bool doSingleVelocityScaling; - //! Wether we're doing group-wise velocity scaling - bool doGroupVelocityScaling; - //! The vector of velocity scaling values - std::vector velocityScaling_; - //! The next velocity scaling step - Step scalingStepVelocity_; - - //! The diagonal of the PR scaling matrix - rvec diagPR; - //! The full PR scaling matrix - matrix matrixPR; - //! The next PR scaling step - Step scalingStepPR_; - - // Access to ISimulator data - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; +public: + //! Constructor + Propagator(double timestep, + StatePropagatorData* statePropagatorData, + const MDAtoms* mdAtoms, + gmx_wallcycle* wcycle); + + /*! \brief Register run function for step / time + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! No element setup needed + void elementSetup() override {} + //! No element teardown needed + void elementTeardown() override {} + + //! Set the number of velocity scaling variables + void setNumVelocityScalingVariables(int numVelocityScalingVariables); + //! Get view on the velocity scaling vector + ArrayRef viewOnVelocityScaling(); + //! Get velocity scaling callback + PropagatorCallbackPtr velocityScalingCallback(); + + //! Get view on the full PR scaling matrix + ArrayRef viewOnPRScalingMatrix(); + //! Get PR scaling callback + PropagatorCallbackPtr prScalingCallback(); + +private: + //! The actual propagation + template + void run(); + + //! The time step + const real timestep_; + + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + + //! Whether we're doing single-value velocity scaling + bool doSingleVelocityScaling; + //! Wether we're doing group-wise velocity scaling + bool doGroupVelocityScaling; + //! The vector of velocity scaling values + std::vector velocityScaling_; + //! The next velocity scaling step + Step scalingStepVelocity_; + + //! The diagonal of the PR scaling matrix + rvec diagPR; + //! The full PR scaling matrix + matrix matrixPR; + //! The next PR scaling step + Step scalingStepPR_; + + // Access to ISimulator data + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; }; //! \} -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_PROPAGATOR_H diff --git a/src/gromacs/modularsimulator/shellfcelement.cpp b/src/gromacs/modularsimulator/shellfcelement.cpp index e95f23c9e6..c18c0c91ab 100644 --- a/src/gromacs/modularsimulator/shellfcelement.cpp +++ b/src/gromacs/modularsimulator/shellfcelement.cpp @@ -65,8 +65,7 @@ struct t_graph; namespace gmx { -bool ShellFCElement::doShellsOrFlexConstraints( - const gmx_mtop_t *mtop, int nflexcon) +bool ShellFCElement::doShellsOrFlexConstraints(const gmx_mtop_t* mtop, int nflexcon) { if (nflexcon != 0) { @@ -76,27 +75,26 @@ bool ShellFCElement::doShellsOrFlexConstraints( return n[eptShell] != 0; } -ShellFCElement::ShellFCElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isVerbose, - bool isDynamicBox, - FILE *fplog, - const t_commrec *cr, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - t_forcerec *fr, - t_fcdata *fcd, - gmx_wallcycle *wcycle, - MdrunScheduleWorkload *runScheduleWork, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work, - Constraints *constr, - const gmx_mtop_t *globalTopology, - gmx_enfrot *enforcedRotation) : +ShellFCElement::ShellFCElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isVerbose, + bool isDynamicBox, + FILE* fplog, + const t_commrec* cr, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + t_forcerec* fr, + t_fcdata* fcd, + gmx_wallcycle* wcycle, + MdrunScheduleWorkload* runScheduleWork, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work, + Constraints* constr, + const gmx_mtop_t* globalTopology, + gmx_enfrot* enforcedRotation) : nextNSStep_(-1), nextEnergyCalculationStep_(-1), nextVirialCalculationStep_(-1), @@ -126,10 +124,8 @@ ShellFCElement::ShellFCElement( { lambda_.fill(0); - shellfc_ = init_shell_flexcon( - fplog, globalTopology, - constr_ ? constr_->numFlexibleConstraints() : 0, - inputrec->nstcalcenergy, DOMAINDECOMP(cr)); + shellfc_ = init_shell_flexcon(fplog, globalTopology, constr_ ? constr_->numFlexibleConstraints() : 0, + inputrec->nstcalcenergy, DOMAINDECOMP(cr)); GMX_ASSERT(shellfc_, "ShellFCElement built, but init_shell_flexcon returned a nullptr"); @@ -141,58 +137,46 @@ ShellFCElement::ShellFCElement( } } -void ShellFCElement::scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) +void ShellFCElement::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { - unsigned int flags = ( - GMX_FORCE_STATECHANGED | - GMX_FORCE_ALLFORCES | - (isDynamicBox_ ? GMX_FORCE_DYNAMICBOX : 0) | - (nextVirialCalculationStep_ == step ? GMX_FORCE_VIRIAL : 0) | - (nextEnergyCalculationStep_ == step ? GMX_FORCE_ENERGY : 0) | - (nextFreeEnergyCalculationStep_ == step ? GMX_FORCE_DHDL : 0)); - - (*registerRunFunction)( - std::make_unique( - [this, step, time, flags]() - {run(step, time, flags); })); + unsigned int flags = + (GMX_FORCE_STATECHANGED | GMX_FORCE_ALLFORCES | (isDynamicBox_ ? GMX_FORCE_DYNAMICBOX : 0) + | (nextVirialCalculationStep_ == step ? GMX_FORCE_VIRIAL : 0) + | (nextEnergyCalculationStep_ == step ? GMX_FORCE_ENERGY : 0) + | (nextFreeEnergyCalculationStep_ == step ? GMX_FORCE_DHDL : 0)); + + (*registerRunFunction)(std::make_unique( + [this, step, time, flags]() { run(step, time, flags); })); nSteps_++; } void ShellFCElement::elementSetup() { GMX_ASSERT(localTopology_, "Setup called before local topology was set."); - } void ShellFCElement::run(Step step, Time time, unsigned int flags) { // Disabled functionality - gmx_multisim_t *ms = nullptr; - t_graph *graph = nullptr; + gmx_multisim_t* ms = nullptr; + t_graph* graph = nullptr; - auto x = statePropagatorData_->positionsView(); - auto v = statePropagatorData_->velocitiesView(); - auto forces = statePropagatorData_->forcesView(); - auto box = statePropagatorData_->constBox(); - history_t *hist = nullptr; // disabled + auto x = statePropagatorData_->positionsView(); + auto v = statePropagatorData_->velocitiesView(); + auto forces = statePropagatorData_->forcesView(); + auto box = statePropagatorData_->constBox(); + history_t* hist = nullptr; // disabled - tensor force_vir = {{0}}; + tensor force_vir = { { 0 } }; // TODO: Make lambda const (needs some adjustments in lower force routines) - ArrayRef lambda = freeEnergyPerturbationElement_ ? - freeEnergyPerturbationElement_->lambdaView() : lambda_; - relax_shell_flexcon(fplog_, cr_, ms, isVerbose_, - enforcedRotation_, step, - inputrec_, imdSession_, pull_work_, step == nextNSStep_, - static_cast(flags), localTopology_, - constr_, energyElement_->enerdata(), fcd_, - statePropagatorData_->localNumAtoms(), - x, v, box, lambda, hist, forces, force_vir, - mdAtoms_->mdatoms(), nrnb_, wcycle_, graph, - shellfc_, fr_, runScheduleWork_, time, - energyElement_->muTot(), vsite_, - ddBalanceRegionHandler_); + ArrayRef lambda = + freeEnergyPerturbationElement_ ? freeEnergyPerturbationElement_->lambdaView() : lambda_; + relax_shell_flexcon( + fplog_, cr_, ms, isVerbose_, enforcedRotation_, step, inputrec_, imdSession_, + pull_work_, step == nextNSStep_, static_cast(flags), localTopology_, constr_, + energyElement_->enerdata(), fcd_, statePropagatorData_->localNumAtoms(), x, v, box, + lambda, hist, forces, force_vir, mdAtoms_->mdatoms(), nrnb_, wcycle_, graph, shellfc_, + fr_, runScheduleWork_, time, energyElement_->muTot(), vsite_, ddBalanceRegionHandler_); energyElement_->addToForceVirial(force_vir, step); } @@ -201,7 +185,7 @@ void ShellFCElement::elementTeardown() done_shellfc(fplog_, shellfc_, nSteps_); } -void ShellFCElement::setTopology(const gmx_localtop_t *top) +void ShellFCElement::setTopology(const gmx_localtop_t* top) { localTopology_ = top; } @@ -209,29 +193,26 @@ void ShellFCElement::setTopology(const gmx_localtop_t *top) SignallerCallbackPtr ShellFCElement::registerNSCallback() { return std::make_unique( - [this](Step step, Time gmx_unused time) - {this->nextNSStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->nextNSStep_ = step; }); } -SignallerCallbackPtr ShellFCElement:: - registerEnergyCallback(EnergySignallerEvent event) +SignallerCallbackPtr ShellFCElement::registerEnergyCallback(EnergySignallerEvent event) { if (event == EnergySignallerEvent::EnergyCalculationStep) { return std::make_unique( - [this](Step step, Time) - {nextEnergyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextEnergyCalculationStep_ = step; }); } if (event == EnergySignallerEvent::VirialCalculationStep) { return std::make_unique( - [this](Step step, Time){nextVirialCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextVirialCalculationStep_ = step; }); } if (event == EnergySignallerEvent::FreeEnergyCalculationStep) { return std::make_unique( - [this](Step step, Time){nextFreeEnergyCalculationStep_ = step; }); + [this](Step step, Time /*unused*/) { nextFreeEnergyCalculationStep_ = step; }); } return nullptr; } -} // namespace std +} // namespace gmx diff --git a/src/gromacs/modularsimulator/shellfcelement.h b/src/gromacs/modularsimulator/shellfcelement.h index 3a1dec8fe9..e3338b1216 100644 --- a/src/gromacs/modularsimulator/shellfcelement.h +++ b/src/gromacs/modularsimulator/shellfcelement.h @@ -75,133 +75,130 @@ class StatePropagatorData; * The ShellFCElement manages the call to relax_shell_flexcon(...) */ class ShellFCElement final : - public ISimulatorElement, - public ITopologyHolderClient, - public INeighborSearchSignallerClient, - public IEnergySignallerClient + public ISimulatorElement, + public ITopologyHolderClient, + public INeighborSearchSignallerClient, + public IEnergySignallerClient { - public: - //! Constructor - ShellFCElement( - StatePropagatorData *statePropagatorData, - EnergyElement *energyElement, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - bool isVerbose, - bool isDynamicBox, - FILE *fplog, - const t_commrec *cr, - const t_inputrec *inputrec, - const MDAtoms *mdAtoms, - t_nrnb *nrnb, - t_forcerec *fr, - t_fcdata *fcd, - gmx_wallcycle *wcycle, - MdrunScheduleWorkload *runScheduleWork, - gmx_vsite_t *vsite, - ImdSession *imdSession, - pull_t *pull_work, - Constraints *constr, - const gmx_mtop_t *globalTopology, - gmx_enfrot *enforcedRotation); - - /*! \brief Register shell / flex constraint calculation for step / time - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! Check that we got the local topology - void elementSetup() override; - //! Print some final output - void elementTeardown() override; - - //! Whether either shells or flexible constraints are used - static bool doShellsOrFlexConstraints(const gmx_mtop_t *mtop, int nflexcon); - - private: - //! ITopologyHolderClient implementation - void setTopology(const gmx_localtop_t *top) override; - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; - //! IEnergySignallerClient implementation - SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; - //! The actual do_force call - void run(Step step, Time time, unsigned int flags); - - //! The shell / FC helper struct - gmx_shellfc_t *shellfc_; - - //! The next NS step - Step nextNSStep_; - //! The next energy calculation step - Step nextEnergyCalculationStep_; - //! The next energy calculation step - Step nextVirialCalculationStep_; - //! The next free energy calculation step - Step nextFreeEnergyCalculationStep_; - - //! Pointer to the micro state - StatePropagatorData *statePropagatorData_; - //! Pointer to the energy element - EnergyElement *energyElement_; - //! The free energy perturbation element - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; - - //! The local topology - updated by Topology via Client system - const gmx_localtop_t *localTopology_; - - //! Whether we're having a dynamic box - const bool isDynamicBox_; - //! Whether we're being verbose - const bool isVerbose_; - //! The number of shell relaxation steps we did - Step nSteps_; - - //! DD / DLB helper object - const DDBalanceRegionHandler ddBalanceRegionHandler_; - - /* \brief The FEP lambda vector - * - * Used if FEP is off, since do_force - * requires lambda to be allocated anyway - */ - std::array lambda_; - - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - const t_commrec *cr_; - //! Contains user input mdp options. - const t_inputrec *inputrec_; - //! Atom parameters for this domain. - const MDAtoms *mdAtoms_; - //! Manages flop accounting. - t_nrnb *nrnb_; - //! Manages wall cycle accounting. - gmx_wallcycle *wcycle_; - //! Parameters for force calculations. - t_forcerec *fr_; - //! Handles virtual sites. - gmx_vsite_t *vsite_; - //! The Interactive Molecular Dynamics session. - ImdSession *imdSession_; - //! The pull work object. - pull_t *pull_work_; - //! Helper struct for force calculations. - t_fcdata *fcd_; - //! Schedule of work for each MD step for this task. - MdrunScheduleWorkload *runScheduleWork_; - //! Handles constraints. - Constraints *constr_; - //! Handles enforced rotation. - gmx_enfrot *enforcedRotation_; +public: + //! Constructor + ShellFCElement(StatePropagatorData* statePropagatorData, + EnergyElement* energyElement, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + bool isVerbose, + bool isDynamicBox, + FILE* fplog, + const t_commrec* cr, + const t_inputrec* inputrec, + const MDAtoms* mdAtoms, + t_nrnb* nrnb, + t_forcerec* fr, + t_fcdata* fcd, + gmx_wallcycle* wcycle, + MdrunScheduleWorkload* runScheduleWork, + gmx_vsite_t* vsite, + ImdSession* imdSession, + pull_t* pull_work, + Constraints* constr, + const gmx_mtop_t* globalTopology, + gmx_enfrot* enforcedRotation); + + /*! \brief Register shell / flex constraint calculation for step / time + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! Check that we got the local topology + void elementSetup() override; + //! Print some final output + void elementTeardown() override; + + //! Whether either shells or flexible constraints are used + static bool doShellsOrFlexConstraints(const gmx_mtop_t* mtop, int nflexcon); + +private: + //! ITopologyHolderClient implementation + void setTopology(const gmx_localtop_t* top) override; + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; + //! IEnergySignallerClient implementation + SignallerCallbackPtr registerEnergyCallback(EnergySignallerEvent event) override; + //! The actual do_force call + void run(Step step, Time time, unsigned int flags); + + //! The shell / FC helper struct + gmx_shellfc_t* shellfc_; + + //! The next NS step + Step nextNSStep_; + //! The next energy calculation step + Step nextEnergyCalculationStep_; + //! The next energy calculation step + Step nextVirialCalculationStep_; + //! The next free energy calculation step + Step nextFreeEnergyCalculationStep_; + + //! Pointer to the micro state + StatePropagatorData* statePropagatorData_; + //! Pointer to the energy element + EnergyElement* energyElement_; + //! The free energy perturbation element + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; + + //! The local topology - updated by Topology via Client system + const gmx_localtop_t* localTopology_; + + //! Whether we're having a dynamic box + const bool isDynamicBox_; + //! Whether we're being verbose + const bool isVerbose_; + //! The number of shell relaxation steps we did + Step nSteps_; + + //! DD / DLB helper object + const DDBalanceRegionHandler ddBalanceRegionHandler_; + + /* \brief The FEP lambda vector + * + * Used if FEP is off, since do_force + * requires lambda to be allocated anyway + */ + std::array lambda_; + + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + const t_commrec* cr_; + //! Contains user input mdp options. + const t_inputrec* inputrec_; + //! Atom parameters for this domain. + const MDAtoms* mdAtoms_; + //! Manages flop accounting. + t_nrnb* nrnb_; + //! Manages wall cycle accounting. + gmx_wallcycle* wcycle_; + //! Parameters for force calculations. + t_forcerec* fr_; + //! Handles virtual sites. + gmx_vsite_t* vsite_; + //! The Interactive Molecular Dynamics session. + ImdSession* imdSession_; + //! The pull work object. + pull_t* pull_work_; + //! Helper struct for force calculations. + t_fcdata* fcd_; + //! Schedule of work for each MD step for this task. + MdrunScheduleWorkload* runScheduleWork_; + //! Handles constraints. + Constraints* constr_; + //! Handles enforced rotation. + gmx_enfrot* enforcedRotation_; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_SHELLFCELEMENT_H diff --git a/src/gromacs/modularsimulator/signallers.cpp b/src/gromacs/modularsimulator/signallers.cpp index 691b281dd7..8e1a1a0575 100644 --- a/src/gromacs/modularsimulator/signallers.cpp +++ b/src/gromacs/modularsimulator/signallers.cpp @@ -52,24 +52,24 @@ namespace gmx { //! Helper function to call all callbacks in a list -static inline void runAllCallbacks( - std::vector &callbacks, - Step step, Time time) +static inline void runAllCallbacks(std::vector& callbacks, Step step, Time time) { - for (const auto &callback : callbacks) + for (const auto& callback : callbacks) { (*callback)(step, time); } } -NeighborSearchSignaller::NeighborSearchSignaller( - std::vector callbacks, - Step nstlist, Step initStep, Time initTime) : +NeighborSearchSignaller::NeighborSearchSignaller(std::vector callbacks, + Step nstlist, + Step initStep, + Time initTime) : callbacks_(std::move(callbacks)), nstlist_(nstlist), initStep_(initStep), initTime_(initTime) -{} +{ +} void NeighborSearchSignaller::signal(Step step, Time time) { @@ -80,17 +80,18 @@ void NeighborSearchSignaller::signal(Step step, Time time) } } -LastStepSignaller::LastStepSignaller( - std::vector callbacks, - gmx::Step nsteps, gmx::Step initStep, - StopHandler* stopHandler) : +LastStepSignaller::LastStepSignaller(std::vector callbacks, + gmx::Step nsteps, + gmx::Step initStep, + StopHandler* stopHandler) : callbacks_(std::move(callbacks)), stopStep_(initStep + nsteps), signalledStopCondition_(false), stopHandler_(stopHandler), nextNSStep_(-1), nsStepRegistrationDone_(false) -{} +{ +} void LastStepSignaller::signal(Step step, Time time) { @@ -98,7 +99,7 @@ void LastStepSignaller::signal(Step step, Time time) { return; } - bool isNSStep = (step == nextNSStep_); + bool isNSStep = (step == nextNSStep_); signalledStopCondition_ = stopHandler_->stoppingAfterCurrentStep(isNSStep); if (step == stopStep_ || signalledStopCondition_) { @@ -108,31 +109,29 @@ void LastStepSignaller::signal(Step step, Time time) void LastStepSignaller::signallerSetup() { - GMX_ASSERT( - nsStepRegistrationDone_, - "LastStepSignaller needs to be registered to NeighborSearchSignaller."); + GMX_ASSERT(nsStepRegistrationDone_, + "LastStepSignaller needs to be registered to NeighborSearchSignaller."); } SignallerCallbackPtr LastStepSignaller::registerNSCallback() { nsStepRegistrationDone_ = true; return std::make_unique( - [this](Step step, Time gmx_unused time) - {this->nextNSStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->nextNSStep_ = step; }); } -LoggingSignaller::LoggingSignaller( - std::vector callbacks, - Step nstlog, - Step initStep, - Time initTime) : +LoggingSignaller::LoggingSignaller(std::vector callbacks, + Step nstlog, + Step initStep, + Time initTime) : callbacks_(std::move(callbacks)), nstlog_(nstlog), initStep_(initStep), initTime_(initTime), lastStep_(-1), lastStepRegistrationDone_(false) -{} +{ +} void LoggingSignaller::signal(Step step, Time time) { @@ -144,25 +143,23 @@ void LoggingSignaller::signal(Step step, Time time) void LoggingSignaller::signallerSetup() { - GMX_ASSERT( - lastStepRegistrationDone_, - "LoggingSignaller needs to be registered to LastStepSignaller."); + GMX_ASSERT(lastStepRegistrationDone_, + "LoggingSignaller needs to be registered to LastStepSignaller."); } SignallerCallbackPtr LoggingSignaller::registerLastStepCallback() { lastStepRegistrationDone_ = true; return std::make_unique( - [this](Step step, Time gmx_unused time){this->lastStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->lastStep_ = step; }); } -EnergySignaller::EnergySignaller( - std::vector calculateEnergyCallbacks, - std::vector calculateVirialCallbacks, - std::vector calculateFreeEnergyCallbacks, - int nstcalcenergy, - int nstcalcfreeenergy, - int nstcalcvirial) : +EnergySignaller::EnergySignaller(std::vector calculateEnergyCallbacks, + std::vector calculateVirialCallbacks, + std::vector calculateFreeEnergyCallbacks, + int nstcalcenergy, + int nstcalcfreeenergy, + int nstcalcvirial) : calculateEnergyCallbacks_(std::move(calculateEnergyCallbacks)), calculateVirialCallbacks_(std::move(calculateVirialCallbacks)), calculateFreeEnergyCallbacks_(std::move(calculateFreeEnergyCallbacks)), @@ -173,11 +170,10 @@ EnergySignaller::EnergySignaller( trajectoryRegistrationDone_(false), loggingStep_(-1), loggingRegistrationDone_(false) -{} +{ +} -void EnergySignaller::signal( - Step step, - Time time) +void EnergySignaller::signal(Step step, Time time) { bool calculateEnergy = do_per_step(step, nstcalcenergy_); bool calculateFreeEnergy = do_per_step(step, nstcalcfreeenergy_); @@ -200,12 +196,10 @@ void EnergySignaller::signal( void EnergySignaller::signallerSetup() { - GMX_ASSERT( - loggingRegistrationDone_, - "EnergySignaller needs to be registered to LoggingSignaller."); - GMX_ASSERT( - trajectoryRegistrationDone_, - "EnergySignaller needs to be registered to TrajectoryElement."); + GMX_ASSERT(loggingRegistrationDone_, + "EnergySignaller needs to be registered to LoggingSignaller."); + GMX_ASSERT(trajectoryRegistrationDone_, + "EnergySignaller needs to be registered to TrajectoryElement."); } SignallerCallbackPtr EnergySignaller::registerTrajectorySignallerCallback(TrajectoryEvent event) @@ -214,7 +208,7 @@ SignallerCallbackPtr EnergySignaller::registerTrajectorySignallerCallback(Trajec { trajectoryRegistrationDone_ = true; return std::make_unique( - [this](Step step, Time gmx_unused time){this->energyWritingStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->energyWritingStep_ = step; }); } return nullptr; } @@ -223,7 +217,7 @@ SignallerCallbackPtr EnergySignaller::registerLoggingCallback() { loggingRegistrationDone_ = true; return std::make_unique( - [this](Step step, Time gmx_unused time){this->loggingStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->loggingStep_ = step; }); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/signallers.h b/src/gromacs/modularsimulator/signallers.h index 89db70b0a5..4fd9fd549f 100644 --- a/src/gromacs/modularsimulator/signallers.h +++ b/src/gromacs/modularsimulator/signallers.h @@ -62,36 +62,32 @@ class TrajectoryElement; * * @tparam Signaller The signaller to be built */ -template +template class SignallerBuilder final { - public: - //! Allows clients to register to the signaller - void registerSignallerClient( - compat::not_null client); - - //! Build the signaller - template - std::unique_ptr build(Args && ... args); - - private: - //! List of signaller clients - std::vector signallerClients_; - - //! Helper function to get the callbacks from the clients - template - std::vector buildCallbackVector(Args && ... args); - - /*! \brief Get a callback from a single client - * - * This is in a separate function, as the exact call depends on the - * specific signaller / client. - */ - template - SignallerCallbackPtr getSignallerCallback( - typename Signaller::Client *client, - Args && ... args); - +public: + //! Allows clients to register to the signaller + void registerSignallerClient(compat::not_null client); + + //! Build the signaller + template + std::unique_ptr build(Args&&... args); + +private: + //! List of signaller clients + std::vector signallerClients_; + + //! Helper function to get the callbacks from the clients + template + std::vector buildCallbackVector(Args&&... args); + + /*! \brief Get a callback from a single client + * + * This is in a separate function, as the exact call depends on the + * specific signaller / client. + */ + template + SignallerCallbackPtr getSignallerCallback(typename Signaller::Client* client, Args&&... args); }; /*! \libinternal @@ -101,48 +97,45 @@ class SignallerBuilder final * This element informs its clients via callbacks * when a neighbor-searching step is happening. */ -class NeighborSearchSignaller final : - public ISignaller +class NeighborSearchSignaller final : public ISignaller { - public: - /*! \brief Run the signaller at a specific step / time - * - * Informs callbacks if step % nstlist_ == 0 - * - * @param step The current time step - * @param time The current time - */ - void signal(Step step, Time time) override; - - //! Do nothing at setup time - void signallerSetup() override {}; - - //! Allow builder to construct - friend class SignallerBuilder; - //! Define client type - typedef INeighborSearchSignallerClient Client; - - private: - /*! \brief Constructor - * - * @param callbacks A vector of pointers to callbacks - * @param nstlist The frequency at which neighbor search is performed - * @param initStep The first step of the simulation - * @param initTime The start time of the simulation - */ - NeighborSearchSignaller( - std::vector callbacks, - Step nstlist, Step initStep, Time initTime); - - //! Client callbacks - std::vector callbacks_; - - //! The NS frequency - const Step nstlist_; - //! The initial step of the simulation - const Step initStep_; - //! The initial time of the simulation - const Time initTime_; +public: + /*! \brief Run the signaller at a specific step / time + * + * Informs callbacks if step % nstlist_ == 0 + * + * @param step The current time step + * @param time The current time + */ + void signal(Step step, Time time) override; + + //! Do nothing at setup time + void signallerSetup() override{}; + + //! Allow builder to construct + friend class SignallerBuilder; + //! Define client type + typedef INeighborSearchSignallerClient Client; + +private: + /*! \brief Constructor + * + * @param callbacks A vector of pointers to callbacks + * @param nstlist The frequency at which neighbor search is performed + * @param initStep The first step of the simulation + * @param initTime The start time of the simulation + */ + NeighborSearchSignaller(std::vector callbacks, Step nstlist, Step initStep, Time initTime); + + //! Client callbacks + std::vector callbacks_; + + //! The NS frequency + const Step nstlist_; + //! The initial step of the simulation + const Step initStep_; + //! The initial time of the simulation + const Time initTime_; }; /*! \libinternal @@ -152,57 +145,55 @@ class NeighborSearchSignaller final : * This element informs its clients via callbacks * when the last step is happening. */ -class LastStepSignaller final : - public ISignaller, - public INeighborSearchSignallerClient +class LastStepSignaller final : public ISignaller, public INeighborSearchSignallerClient { - public: - /*! \brief Run the signaller at a specific step / time - * - * Informs callbacks if this is the last step - * - * @param step The current time step - * @param time The current time - */ - void signal(Step step, Time time) override; - - //! Check that necessary registration was done - void signallerSetup() override; - - //! Allow builder to construct - friend class SignallerBuilder; - //! Define client type - typedef ILastStepSignallerClient Client; - - private: - /*! \brief Constructor - * - * @param callbacks A vector of pointers to callbacks - * @param nsteps The total number of steps for the simulation - * @param initStep The first step of the simulation - * @param stopHandler A pointer to the stop handler (LastStepSignaller takes ownership) - */ - LastStepSignaller( - std::vector callbacks, - Step nsteps, Step initStep, - StopHandler* stopHandler); - - //! Client callbacks - std::vector callbacks_; - - //! The last step of the simulation - const Step stopStep_; - //! Whether we signalled last step due to stop condition - bool signalledStopCondition_; - //! A pointer to the stop handler communicating signal and time-related stops - StopHandler *stopHandler_; - - //! INeighborSearchSignallerClient implementation - SignallerCallbackPtr registerNSCallback() override; - //! The next NS step (notified by NS signaller) - Step nextNSStep_; - //! Whether we registered to the NS signaller - bool nsStepRegistrationDone_; +public: + /*! \brief Run the signaller at a specific step / time + * + * Informs callbacks if this is the last step + * + * @param step The current time step + * @param time The current time + */ + void signal(Step step, Time time) override; + + //! Check that necessary registration was done + void signallerSetup() override; + + //! Allow builder to construct + friend class SignallerBuilder; + //! Define client type + typedef ILastStepSignallerClient Client; + +private: + /*! \brief Constructor + * + * @param callbacks A vector of pointers to callbacks + * @param nsteps The total number of steps for the simulation + * @param initStep The first step of the simulation + * @param stopHandler A pointer to the stop handler (LastStepSignaller takes ownership) + */ + LastStepSignaller(std::vector callbacks, + Step nsteps, + Step initStep, + StopHandler* stopHandler); + + //! Client callbacks + std::vector callbacks_; + + //! The last step of the simulation + const Step stopStep_; + //! Whether we signalled last step due to stop condition + bool signalledStopCondition_; + //! A pointer to the stop handler communicating signal and time-related stops + StopHandler* stopHandler_; + + //! INeighborSearchSignallerClient implementation + SignallerCallbackPtr registerNSCallback() override; + //! The next NS step (notified by NS signaller) + Step nextNSStep_; + //! Whether we registered to the NS signaller + bool nsStepRegistrationDone_; }; /*! \libinternal @@ -212,58 +203,52 @@ class LastStepSignaller final : * This element informs its clients via callbacks * when a logging step is happening. */ -class LoggingSignaller final : - public ISignaller, - public ILastStepSignallerClient +class LoggingSignaller final : public ISignaller, public ILastStepSignallerClient { - public: - /*! \brief Run the signaller at a specific step / time - * - * Informs callbacks if step % nstlog_ == 0 - * - * @param step The current time step - * @param time The current time - */ - void signal(Step step, Time time) override; - - //! Check that necessary registration was done - void signallerSetup() override; - - //! Allow builder to construct - friend class SignallerBuilder; - //! Define client type - typedef ILoggingSignallerClient Client; - - private: - /*! \brief Constructor - * - * @param callbacks A vector of pointers to callbacks - * @param nstlog The logging frequency - * @param initStep The first step of the simulation - * @param initTime The start time of the simulation - */ - LoggingSignaller( - std::vector callbacks, - Step nstlog, - Step initStep, - Time initTime); - - //! Client callbacks - std::vector callbacks_; - - //! The logging frequency - const Step nstlog_; - //! The initial step of the simulation - const Step initStep_; - //! The initial time of the simulation - const Time initTime_; - - //! ILastStepSignallerClient implementation - SignallerCallbackPtr registerLastStepCallback() override; - //! The last step (notified by signaller) - Step lastStep_; - //! Whether we registered to the last step signaller - bool lastStepRegistrationDone_; +public: + /*! \brief Run the signaller at a specific step / time + * + * Informs callbacks if step % nstlog_ == 0 + * + * @param step The current time step + * @param time The current time + */ + void signal(Step step, Time time) override; + + //! Check that necessary registration was done + void signallerSetup() override; + + //! Allow builder to construct + friend class SignallerBuilder; + //! Define client type + typedef ILoggingSignallerClient Client; + +private: + /*! \brief Constructor + * + * @param callbacks A vector of pointers to callbacks + * @param nstlog The logging frequency + * @param initStep The first step of the simulation + * @param initTime The start time of the simulation + */ + LoggingSignaller(std::vector callbacks, Step nstlog, Step initStep, Time initTime); + + //! Client callbacks + std::vector callbacks_; + + //! The logging frequency + const Step nstlog_; + //! The initial step of the simulation + const Step initStep_; + //! The initial time of the simulation + const Time initTime_; + + //! ILastStepSignallerClient implementation + SignallerCallbackPtr registerLastStepCallback() override; + //! The last step (notified by signaller) + Step lastStep_; + //! Whether we registered to the last step signaller + bool lastStepRegistrationDone_; }; /*! \libinternal @@ -276,80 +261,75 @@ class LoggingSignaller final : * - virial calculation step * - free energy calculation step */ -class EnergySignaller final : - public ISignaller, - public ITrajectorySignallerClient, - public ILoggingSignallerClient +class EnergySignaller final : public ISignaller, public ITrajectorySignallerClient, public ILoggingSignallerClient { - public: - /*! \brief Run the signaller at a specific step / time - * - * Informs callbacks of energy / virial / free energy special steps - * - * @param step The current time step - * @param time The current time - */ - void signal(Step step, Time time) override; - - //! Check that necessary registration was done - void signallerSetup() override; - - //! Allow builder to construct - friend class SignallerBuilder; - //! Define client type - typedef IEnergySignallerClient Client; - - private: - /*! \brief Constructor - * - * @param calculateEnergyCallbacks A vector of pointers to callbacks (energy steps) - * @param calculateVirialCallbacks A vector of pointers to callbacks (virial steps) - * @param calculateFreeEnergyCallbacks A vector of pointers to callbacks (free energy steps) - * @param nstcalcenergy The energy calculation frequency - * @param nstcalcfreeenergy The free energy calculation frequency - * @param nstcalcvirial The free energy calculation frequency - */ - EnergySignaller( - std::vector calculateEnergyCallbacks, - std::vector calculateVirialCallbacks, - std::vector calculateFreeEnergyCallbacks, - int nstcalcenergy, - int nstcalcfreeenergy, - int nstcalcvirial); - - //! Client callbacks - //! { - std::vector calculateEnergyCallbacks_; - std::vector calculateVirialCallbacks_; - std::vector calculateFreeEnergyCallbacks_; - //! } - - //! The energy calculation frequency - const int nstcalcenergy_; - //! The free energy calculation frequency - const int nstcalcfreeenergy_; - //! The virial calculation frequency - const int nstcalcvirial_; - - //! ITrajectorySignallerClient implementation - SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; - //! The energy writing step (notified by signaller) - Step energyWritingStep_; - //! Whether we registered to the trajectory signaller - bool trajectoryRegistrationDone_; - - //! ILoggingSignallerClient implementation - SignallerCallbackPtr registerLoggingCallback() override; - //! The next logging step (notified by signaller) - Step loggingStep_; - //! Whether we registered to the logging signaller - bool loggingRegistrationDone_; +public: + /*! \brief Run the signaller at a specific step / time + * + * Informs callbacks of energy / virial / free energy special steps + * + * @param step The current time step + * @param time The current time + */ + void signal(Step step, Time time) override; + + //! Check that necessary registration was done + void signallerSetup() override; + + //! Allow builder to construct + friend class SignallerBuilder; + //! Define client type + typedef IEnergySignallerClient Client; + +private: + /*! \brief Constructor + * + * @param calculateEnergyCallbacks A vector of pointers to callbacks (energy steps) + * @param calculateVirialCallbacks A vector of pointers to callbacks (virial steps) + * @param calculateFreeEnergyCallbacks A vector of pointers to callbacks (free energy steps) + * @param nstcalcenergy The energy calculation frequency + * @param nstcalcfreeenergy The free energy calculation frequency + * @param nstcalcvirial The free energy calculation frequency + */ + EnergySignaller(std::vector calculateEnergyCallbacks, + std::vector calculateVirialCallbacks, + std::vector calculateFreeEnergyCallbacks, + int nstcalcenergy, + int nstcalcfreeenergy, + int nstcalcvirial); + + //! Client callbacks + //! { + std::vector calculateEnergyCallbacks_; + std::vector calculateVirialCallbacks_; + std::vector calculateFreeEnergyCallbacks_; + //! } + + //! The energy calculation frequency + const int nstcalcenergy_; + //! The free energy calculation frequency + const int nstcalcfreeenergy_; + //! The virial calculation frequency + const int nstcalcvirial_; + + //! ITrajectorySignallerClient implementation + SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; + //! The energy writing step (notified by signaller) + Step energyWritingStep_; + //! Whether we registered to the trajectory signaller + bool trajectoryRegistrationDone_; + + //! ILoggingSignallerClient implementation + SignallerCallbackPtr registerLoggingCallback() override; + //! The next logging step (notified by signaller) + Step loggingStep_; + //! Whether we registered to the logging signaller + bool loggingRegistrationDone_; }; //! Allows clients to register to the signaller -template -void SignallerBuilder::registerSignallerClient( - compat::not_null client) +template +void SignallerBuilder::registerSignallerClient(compat::not_null client) { signallerClients_.emplace_back(client); } @@ -358,48 +338,43 @@ void SignallerBuilder::registerSignallerClient( * * General version - for NeighborSearchSignaller, LastStepSignaller, LoggingSignaller */ -template -template -std::unique_ptr SignallerBuilder::build(Args && ... args) +template +template +std::unique_ptr SignallerBuilder::build(Args&&... args) { auto callbacks = buildCallbackVector(); // NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor - return std::unique_ptr( - new Signaller( - std::move(callbacks), - std::forward(args) ...)); + return std::unique_ptr(new Signaller(std::move(callbacks), std::forward(args)...)); } /*! \brief Build the signaller * * Specialized version - EnergySignaller has a significantly different build process */ -template <> -template -std::unique_ptr SignallerBuilder::build(Args && ... args) +template<> +template +std::unique_ptr SignallerBuilder::build(Args&&... args) { - auto calculateEnergyCallbacks = buildCallbackVector(EnergySignallerEvent::EnergyCalculationStep); - auto calculateVirialCallbacks = buildCallbackVector(EnergySignallerEvent::VirialCalculationStep); - auto calculateFreeEnergyCallbacks = buildCallbackVector(EnergySignallerEvent::FreeEnergyCalculationStep); + auto calculateEnergyCallbacks = buildCallbackVector(EnergySignallerEvent::EnergyCalculationStep); + auto calculateVirialCallbacks = buildCallbackVector(EnergySignallerEvent::VirialCalculationStep); + auto calculateFreeEnergyCallbacks = + buildCallbackVector(EnergySignallerEvent::FreeEnergyCalculationStep); // NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor - return std::unique_ptr( - new EnergySignaller( - std::move(calculateEnergyCallbacks), - std::move(calculateVirialCallbacks), - std::move(calculateFreeEnergyCallbacks), - std::forward(args) ...)); + return std::unique_ptr(new EnergySignaller( + std::move(calculateEnergyCallbacks), std::move(calculateVirialCallbacks), + std::move(calculateFreeEnergyCallbacks), std::forward(args)...)); } //! Helper function to get the callbacks from the clients -template -template -std::vector SignallerBuilder::buildCallbackVector(Args && ... args) +template +template +std::vector SignallerBuilder::buildCallbackVector(Args&&... args) { std::vector callbacks; // Allow clients to register their callbacks - for (auto &client : signallerClients_) + for (auto& client : signallerClients_) { - if (auto callback = getSignallerCallback(client, std::forward(args) ...)) // don't register nullptr + if (auto callback = getSignallerCallback(client, std::forward(args)...)) // don't register nullptr { callbacks.emplace_back(std::move(callback)); } @@ -408,41 +383,44 @@ std::vector SignallerBuilder::buildCallbackVect } //! Get a callback from a single client - NeighborSearchSignaller -template <> -template +template<> +template SignallerCallbackPtr SignallerBuilder::getSignallerCallback( - typename NeighborSearchSignaller::Client *client, Args && ... args) + typename NeighborSearchSignaller::Client* client, + Args&&... args) { - return client->registerNSCallback(std::forward(args) ...); + return client->registerNSCallback(std::forward(args)...); } //! Get a callback from a single client - LastStepSignaller -template <> -template -SignallerCallbackPtr SignallerBuilder::getSignallerCallback( - typename LastStepSignaller::Client *client, Args && ... args) +template<> +template +SignallerCallbackPtr +SignallerBuilder::getSignallerCallback(typename LastStepSignaller::Client* client, + Args&&... args) { - return client->registerLastStepCallback(std::forward(args) ...); + return client->registerLastStepCallback(std::forward(args)...); } //! Get a callback from a single client - LoggingSignaller -template <> -template -SignallerCallbackPtr SignallerBuilder::getSignallerCallback( - typename LoggingSignaller::Client *client, Args && ... args) +template<> +template +SignallerCallbackPtr +SignallerBuilder::getSignallerCallback(typename LoggingSignaller::Client* client, + Args&&... args) { - return client->registerLoggingCallback(std::forward(args) ...); + return client->registerLoggingCallback(std::forward(args)...); } //! Get a callback from a single client - EnergySignaller -template <> -template -SignallerCallbackPtr SignallerBuilder::getSignallerCallback( - typename EnergySignaller::Client *client, Args && ... args) +template<> +template +SignallerCallbackPtr SignallerBuilder::getSignallerCallback(typename EnergySignaller::Client* client, + Args&&... args) { - return client->registerEnergyCallback(std::forward(args) ...); + return client->registerEnergyCallback(std::forward(args)...); } -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_SIGNALLERS_H diff --git a/src/gromacs/modularsimulator/statepropagatordata.cpp b/src/gromacs/modularsimulator/statepropagatordata.cpp index 517be62be0..c59f6d1e8b 100644 --- a/src/gromacs/modularsimulator/statepropagatordata.cpp +++ b/src/gromacs/modularsimulator/statepropagatordata.cpp @@ -59,19 +59,18 @@ namespace gmx { -StatePropagatorData::StatePropagatorData( - int numAtoms, - FILE *fplog, - const t_commrec *cr, - t_state *globalState, - int nstxout, - int nstvout, - int nstfout, - int nstxout_compressed, - bool useGPU, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - const t_inputrec *inputrec, - const t_mdatoms *mdatoms) : +StatePropagatorData::StatePropagatorData(int numAtoms, + FILE* fplog, + const t_commrec* cr, + t_state* globalState, + int nstxout, + int nstvout, + int nstfout, + int nstxout_compressed, + bool useGPU, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + const t_inputrec* inputrec, + const t_mdatoms* mdatoms) : totalNumAtoms_(numAtoms), nstxout_(nstxout), nstvout_(nstvout), @@ -97,7 +96,7 @@ StatePropagatorData::StatePropagatorData( { auto localState = std::make_unique(); dd_init_local_state(cr->dd, globalState, localState.get()); - stateHasVelocities = static_cast(localState->flags) & (1u << estV); + stateHasVelocities = ((static_cast(localState->flags) & (1U << estV)) != 0u); setLocalState(std::move(localState)); } else @@ -108,7 +107,7 @@ StatePropagatorData::StatePropagatorData( x_ = globalState->x; v_ = globalState->v; copy_mat(globalState->box, box_); - stateHasVelocities = static_cast(globalState->flags) & (1u << estV); + stateHasVelocities = ((static_cast(globalState->flags) & (1U << estV)) != 0u); previousX_.resizeWithPadding(localNAtoms_); ddpCount_ = globalState->ddp_count; copyPosition(); @@ -126,8 +125,7 @@ StatePropagatorData::StatePropagatorData( // Set the velocities of vsites, shells and frozen atoms to zero for (int i = 0; i < mdatoms->homenr; i++) { - if (mdatoms->ptype[i] == eptVSite || - mdatoms->ptype[i] == eptShell) + if (mdatoms->ptype[i] == eptVSite || mdatoms->ptype[i] == eptShell) { clear_rvec(v[i]); } @@ -217,8 +215,8 @@ int StatePropagatorData::localNumAtoms() std::unique_ptr StatePropagatorData::localState() { - auto state = std::make_unique(); - state->flags = (1u << estX) | (1u << estV) | (1u << estBOX); + auto state = std::make_unique(); + state->flags = (1U << estX) | (1U << estV) | (1U << estBOX); state_change_natoms(state.get(), localNAtoms_); state->x = x_; state->v = v_; @@ -241,11 +239,11 @@ void StatePropagatorData::setLocalState(std::unique_ptr state) if (vvResetVelocities_) { - /* DomDec runs twice early in the simulation, once at setup time, and once before the first step. - * Every time DD runs, it sets a new local state here. We are saving a backup during setup time - * (ok for non-DD cases), so we need to update our backup to the DD state before the first step - * here to avoid resetting to an earlier DD state. This is done before any propagation that needs - * to be reset, so it's not very safe but correct for now. + /* DomDec runs twice early in the simulation, once at setup time, and once before the first + * step. Every time DD runs, it sets a new local state here. We are saving a backup during + * setup time (ok for non-DD cases), so we need to update our backup to the DD state before + * the first step here to avoid resetting to an earlier DD state. This is done before any + * propagation that needs to be reset, so it's not very safe but correct for now. * TODO: Get rid of this once input is assumed to be at half steps */ velocityBackup_ = v_; @@ -266,7 +264,7 @@ void StatePropagatorData::copyPosition() { int nth = gmx_omp_nthreads_get(emntUpdate); - #pragma omp parallel for num_threads(nth) schedule(static) default(none) shared(nth) +#pragma omp parallel for num_threads(nth) schedule(static) default(none) shared(nth) for (int th = 0; th < nth; th++) { int start_th, end_th; @@ -290,67 +288,53 @@ void StatePropagatorData::copyPosition(int start, int end) } } -void StatePropagatorData::scheduleTask( - Step step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +void StatePropagatorData::scheduleTask(Step step, Time gmx_unused time, const RegisterRunFunctionPtr& registerRunFunction) { if (vvResetVelocities_) { vvResetVelocities_ = false; - (*registerRunFunction)( - std::make_unique( - [this](){resetVelocities(); })); + (*registerRunFunction)(std::make_unique([this]() { resetVelocities(); })); } // copy x -> previousX - (*registerRunFunction)( - std::make_unique( - [this](){copyPosition(); })); + (*registerRunFunction)(std::make_unique([this]() { copyPosition(); })); // if it's a write out step, keep a copy for writeout if (step == writeOutStep_) { - (*registerRunFunction)( - std::make_unique( - [this](){saveState(); })); + (*registerRunFunction)(std::make_unique([this]() { saveState(); })); } } void StatePropagatorData::saveState() { - GMX_ASSERT( - !localStateBackup_, - "Save state called again before previous state was written."); + GMX_ASSERT(!localStateBackup_, "Save state called again before previous state was written."); localStateBackup_ = localState(); if (freeEnergyPerturbationElement_) { localStateBackup_->fep_state = freeEnergyPerturbationElement_->currentFEPState(); for (unsigned long i = 0; i < localStateBackup_->lambda.size(); ++i) { - localStateBackup_->lambda[i] = - freeEnergyPerturbationElement_->constLambdaView()[i]; + localStateBackup_->lambda[i] = freeEnergyPerturbationElement_->constLambdaView()[i]; } - localStateBackup_->flags |= (1u<flags |= (1U << estLAMBDA) | (1U << estFEPSTATE); } } -SignallerCallbackPtr -StatePropagatorData::registerTrajectorySignallerCallback(TrajectoryEvent event) +SignallerCallbackPtr StatePropagatorData::registerTrajectorySignallerCallback(TrajectoryEvent event) { if (event == TrajectoryEvent::StateWritingStep) { return std::make_unique( - [this](Step step, Time){this->writeOutStep_ = step; }); + [this](Step step, Time /*unused*/) { this->writeOutStep_ = step; }); } return nullptr; } -ITrajectoryWriterCallbackPtr -StatePropagatorData::registerTrajectoryWriterCallback(TrajectoryEvent event) +ITrajectoryWriterCallbackPtr StatePropagatorData::registerTrajectoryWriterCallback(TrajectoryEvent event) { if (event == TrajectoryEvent::StateWritingStep) { return std::make_unique( - [this](gmx_mdoutf *outf, Step step, Time time, bool writeTrajectory, bool gmx_unused writeLog) - { + [this](gmx_mdoutf* outf, Step step, Time time, bool writeTrajectory, bool gmx_unused writeLog) { if (writeTrajectory) { write(outf, step, time); @@ -403,11 +387,11 @@ void StatePropagatorData::write(gmx_mdoutf_t outf, Step currentStep, Time curren GMX_ASSERT(localStateBackup_, "Trajectory writing called, but no state saved."); // TODO: This is only used for CPT - needs to be filled when we turn CPT back on - ObservablesHistory *observablesHistory = nullptr; + ObservablesHistory* observablesHistory = nullptr; - mdoutf_write_to_trajectory_files( - fplog_, cr_, outf, static_cast(mdof_flags), totalNumAtoms_, - currentStep, currentTime, localStateBackup_.get(), globalState_, observablesHistory, f_); + mdoutf_write_to_trajectory_files(fplog_, cr_, outf, static_cast(mdof_flags), + totalNumAtoms_, currentStep, currentTime, + localStateBackup_.get(), globalState_, observablesHistory, f_); localStateBackup_.reset(); } @@ -428,14 +412,14 @@ void StatePropagatorData::resetVelocities() v_ = velocityBackup_; } -void StatePropagatorData::writeCheckpoint(t_state *localState, t_state gmx_unused *globalState) +void StatePropagatorData::writeCheckpoint(t_state* localState, t_state gmx_unused* globalState) { state_change_natoms(localState, localNAtoms_); localState->x = x_; localState->v = v_; copy_mat(box_, localState->box); localState->ddp_count = ddpCount_; - localState->flags |= (1u << estX) | (1u << estV) | (1u << estBOX); + localState->flags |= (1U << estX) | (1U << estV) | (1U << estBOX); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/statepropagatordata.h b/src/gromacs/modularsimulator/statepropagatordata.h index 07c21fcb3c..eed831f0e7 100644 --- a/src/gromacs/modularsimulator/statepropagatordata.h +++ b/src/gromacs/modularsimulator/statepropagatordata.h @@ -97,181 +97,176 @@ class FreeEnergyPerturbationElement; * constraining are using this. */ class StatePropagatorData final : - public ISimulatorElement, - public ITrajectoryWriterClient, - public ITrajectorySignallerClient, - public ICheckpointHelperClient + public ISimulatorElement, + public ITrajectoryWriterClient, + public ITrajectorySignallerClient, + public ICheckpointHelperClient { - public: - //! Constructor - StatePropagatorData( - int numAtoms, - FILE *fplog, - const t_commrec *cr, - t_state *globalState, - int nstxout, - int nstvout, - int nstfout, - int nstxout_compressed, - bool useGPU, - FreeEnergyPerturbationElement *freeEnergyPerturbationElement, - const t_inputrec *inputrec, - const t_mdatoms *mdatoms); +public: + //! Constructor + StatePropagatorData(int numAtoms, + FILE* fplog, + const t_commrec* cr, + t_state* globalState, + int nstxout, + int nstvout, + int nstfout, + int nstxout_compressed, + bool useGPU, + FreeEnergyPerturbationElement* freeEnergyPerturbationElement, + const t_inputrec* inputrec, + const t_mdatoms* mdatoms); - // Allow access to state - //! Get write access to position vector - ArrayRefWithPadding positionsView(); - //! Get read access to position vector - ArrayRefWithPadding constPositionsView() const; - //! Get write access to previous position vector - ArrayRefWithPadding previousPositionsView(); - //! Get read access to previous position vector - ArrayRefWithPadding constPreviousPositionsView() const; - //! Get write access to velocity vector - ArrayRefWithPadding velocitiesView(); - //! Get read access to velocity vector - ArrayRefWithPadding constVelocitiesView() const; - //! Get write access to force vector - ArrayRefWithPadding forcesView(); - //! Get read access to force vector - ArrayRefWithPadding constForcesView() const; - //! Get pointer to box - rvec* box(); - //! Get const pointer to box - const rvec* constBox(); - //! Get pointer to previous box - rvec* previousBox(); - //! Get const pointer to previous box - const rvec* constPreviousBox(); - //! Get the local number of atoms - int localNumAtoms(); + // Allow access to state + //! Get write access to position vector + ArrayRefWithPadding positionsView(); + //! Get read access to position vector + ArrayRefWithPadding constPositionsView() const; + //! Get write access to previous position vector + ArrayRefWithPadding previousPositionsView(); + //! Get read access to previous position vector + ArrayRefWithPadding constPreviousPositionsView() const; + //! Get write access to velocity vector + ArrayRefWithPadding velocitiesView(); + //! Get read access to velocity vector + ArrayRefWithPadding constVelocitiesView() const; + //! Get write access to force vector + ArrayRefWithPadding forcesView(); + //! Get read access to force vector + ArrayRefWithPadding constForcesView() const; + //! Get pointer to box + rvec* box(); + //! Get const pointer to box + const rvec* constBox(); + //! Get pointer to previous box + rvec* previousBox(); + //! Get const pointer to previous box + const rvec* constPreviousBox(); + //! Get the local number of atoms + int localNumAtoms(); - /*! \brief Register run function for step / time - * - * This needs to be called during the integration part of the simulator, - * at the moment at which the state is at a full time step. Positioning - * this element is the responsibility of the programmer writing the - * integration algorithm! If the current step is a trajectory writing - * step, StatePropagatorData will save a backup for later writeout. - * - * This is also the place at which the current state becomes the previous - * state. - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; + /*! \brief Register run function for step / time + * + * This needs to be called during the integration part of the simulator, + * at the moment at which the state is at a full time step. Positioning + * this element is the responsibility of the programmer writing the + * integration algorithm! If the current step is a trajectory writing + * step, StatePropagatorData will save a backup for later writeout. + * + * This is also the place at which the current state becomes the previous + * state. + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; - /*! \brief Backup starting velocities - * - * This is only needed for vv, where the first (velocity) half step is only - * used to compute the constraint virial, but the velocities need to be reset - * after. - * TODO: There must be a more elegant solution to this! - */ - void elementSetup() override; + /*! \brief Backup starting velocities + * + * This is only needed for vv, where the first (velocity) half step is only + * used to compute the constraint virial, but the velocities need to be reset + * after. + * TODO: There must be a more elegant solution to this! + */ + void elementSetup() override; - //! No element teardown needed - void elementTeardown() override {} + //! No element teardown needed + void elementTeardown() override {} - //! @cond - // (doxygen doesn't like these) - // Classes which need access to legacy state - friend class DomDecHelper; - //! @endcond + //! @cond + // (doxygen doesn't like these) + // Classes which need access to legacy state + friend class DomDecHelper; + //! @endcond - private: - //! The total number of atoms in the system - int totalNumAtoms_; - //! The position writeout frequency - int nstxout_; - //! The velocity writeout frequency - int nstvout_; - //! The force writeout frequency - int nstfout_; - //! The compressed position writeout frequency - int nstxout_compressed_; +private: + //! The total number of atoms in the system + int totalNumAtoms_; + //! The position writeout frequency + int nstxout_; + //! The velocity writeout frequency + int nstvout_; + //! The force writeout frequency + int nstfout_; + //! The compressed position writeout frequency + int nstxout_compressed_; - //! The local number of atoms - int localNAtoms_; - //! The position vector - PaddedHostVector x_; - //! The position vector of the previous step - PaddedHostVector previousX_; - //! The velocity vector - PaddedHostVector v_; - //! The force vector - PaddedHostVector f_; - //! The box matrix - matrix box_; - //! The box matrix of the previous step - matrix previousBox_; - //! The DD partitioning count for legacy t_state compatibility - int ddpCount_; + //! The local number of atoms + int localNAtoms_; + //! The position vector + PaddedHostVector x_; + //! The position vector of the previous step + PaddedHostVector previousX_; + //! The velocity vector + PaddedHostVector v_; + //! The force vector + PaddedHostVector f_; + //! The box matrix + matrix box_; + //! The box matrix of the previous step + matrix previousBox_; + //! The DD partitioning count for legacy t_state compatibility + int ddpCount_; - //! Move x_ to previousX_ - void copyPosition(); - //! OMP helper to move x_ to previousX_ - void copyPosition(int start, int end); + //! Move x_ to previousX_ + void copyPosition(); + //! OMP helper to move x_ to previousX_ + void copyPosition(int start, int end); - // Access to legacy state - //! Get a deep copy of the current state in legacy format - std::unique_ptr localState(); - //! Update the current state with a state in legacy format - void setLocalState(std::unique_ptr state); - //! Get a pointer to the global state - t_state *globalState(); - //! Get a force pointer - PaddedHostVector *forcePointer(); + // Access to legacy state + //! Get a deep copy of the current state in legacy format + std::unique_ptr localState(); + //! Update the current state with a state in legacy format + void setLocalState(std::unique_ptr state); + //! Get a pointer to the global state + t_state* globalState(); + //! Get a force pointer + PaddedHostVector* forcePointer(); - //! Pointer to keep a backup of the state for later writeout - std::unique_ptr localStateBackup_; - //! Step at which next writeout occurs - Step writeOutStep_; - //! Backup current state - void saveState(); + //! Pointer to keep a backup of the state for later writeout + std::unique_ptr localStateBackup_; + //! Step at which next writeout occurs + Step writeOutStep_; + //! Backup current state + void saveState(); - //! ITrajectorySignallerClient implementation - SignallerCallbackPtr - registerTrajectorySignallerCallback(TrajectoryEvent event) override; + //! ITrajectorySignallerClient implementation + SignallerCallbackPtr registerTrajectorySignallerCallback(TrajectoryEvent event) override; - //! ITrajectoryWriterClient implementation - ITrajectoryWriterCallbackPtr - registerTrajectoryWriterCallback(TrajectoryEvent event) override; + //! ITrajectoryWriterClient implementation + ITrajectoryWriterCallbackPtr registerTrajectoryWriterCallback(TrajectoryEvent event) override; - //! ICheckpointHelperClient implementation - void writeCheckpoint(t_state *localState, t_state *globalState) override; + //! ICheckpointHelperClient implementation + void writeCheckpoint(t_state* localState, t_state* globalState) override; - //! Callback writing the state to file - void write(gmx_mdoutf *outf, Step step, Time time); + //! Callback writing the state to file + void write(gmx_mdoutf* outf, Step step, Time time); - //! Whether we're doing VV and need to reset velocities after the first half step - bool vvResetVelocities_; - //! Velocities backup for VV - PaddedHostVector velocityBackup_; - //! Function resetting the velocities - void resetVelocities(); + //! Whether we're doing VV and need to reset velocities after the first half step + bool vvResetVelocities_; + //! Velocities backup for VV + PaddedHostVector velocityBackup_; + //! Function resetting the velocities + void resetVelocities(); - //! Pointer to the free energy perturbation element (for trajectory writing only) - FreeEnergyPerturbationElement *freeEnergyPerturbationElement_; + //! Pointer to the free energy perturbation element (for trajectory writing only) + FreeEnergyPerturbationElement* freeEnergyPerturbationElement_; - // Access to ISimulator data - //! Handles logging. - FILE *fplog_; - //! Handles communication. - const t_commrec *cr_; - //! Full simulation state (only non-nullptr on master rank). - t_state *globalState_; + // Access to ISimulator data + //! Handles logging. + FILE* fplog_; + //! Handles communication. + const t_commrec* cr_; + //! Full simulation state (only non-nullptr on master rank). + t_state* globalState_; - //! No trajectory writer setup needed - void trajectoryWriterSetup(gmx_mdoutf gmx_unused *outf) override {} - //! No trajectory writer teardown needed - void trajectoryWriterTeardown(gmx_mdoutf gmx_unused *outf) override {} + //! No trajectory writer setup needed + void trajectoryWriterSetup(gmx_mdoutf gmx_unused* outf) override {} + //! No trajectory writer teardown needed + void trajectoryWriterTeardown(gmx_mdoutf gmx_unused* outf) override {} }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_STATEPROPAGATORDATA_H diff --git a/src/gromacs/modularsimulator/topologyholder.cpp b/src/gromacs/modularsimulator/topologyholder.cpp index 8f2a8402f7..2c7662c1f3 100644 --- a/src/gromacs/modularsimulator/topologyholder.cpp +++ b/src/gromacs/modularsimulator/topologyholder.cpp @@ -50,14 +50,13 @@ namespace gmx { -TopologyHolder::TopologyHolder( - const gmx_mtop_t &globalTopology, - const t_commrec *cr, - const t_inputrec *inputrec, - t_forcerec *fr, - MDAtoms *mdAtoms, - Constraints *constr, - gmx_vsite_t *vsite) : +TopologyHolder::TopologyHolder(const gmx_mtop_t& globalTopology, + const t_commrec* cr, + const t_inputrec* inputrec, + t_forcerec* fr, + MDAtoms* mdAtoms, + Constraints* constr, + gmx_vsite_t* vsite) : globalTopology_(globalTopology), localTopology_(std::make_unique()) { @@ -70,30 +69,29 @@ TopologyHolder::TopologyHolder( // Generate and initialize new topology // Note that most of the data needed for the constructor is used here - // this function should probably be simplified sooner or later. - mdAlgorithmsSetupAtomData( - cr, inputrec, globalTopology, localTopology_.get(), - fr, nullptr, mdAtoms, constr, vsite, nullptr); + mdAlgorithmsSetupAtomData(cr, inputrec, globalTopology, localTopology_.get(), fr, nullptr, + mdAtoms, constr, vsite, nullptr); } } -const gmx_mtop_t &TopologyHolder::globalTopology() const +const gmx_mtop_t& TopologyHolder::globalTopology() const { return globalTopology_; } void TopologyHolder::updateLocalTopology() { - for (auto &client : clients_) + for (auto& client : clients_) { client->setTopology(localTopology_.get()); } } -void TopologyHolder::registerClient(ITopologyHolderClient *client) +void TopologyHolder::registerClient(ITopologyHolderClient* client) { // Register client clients_.emplace_back(client); // Send copy of current topology client->setTopology(localTopology_.get()); } -} +} // namespace gmx diff --git a/src/gromacs/modularsimulator/topologyholder.h b/src/gromacs/modularsimulator/topologyholder.h index 7a59d85d73..37170225b9 100644 --- a/src/gromacs/modularsimulator/topologyholder.h +++ b/src/gromacs/modularsimulator/topologyholder.h @@ -68,39 +68,38 @@ class MDAtoms; */ class TopologyHolder final { - public: - //! Constructor - TopologyHolder( - const gmx_mtop_t &globalTopology, - const t_commrec *cr, - const t_inputrec *inputrec, - t_forcerec *fr, - MDAtoms *mdAtoms, - Constraints *constr, - gmx_vsite_t *vsite); +public: + //! Constructor + TopologyHolder(const gmx_mtop_t& globalTopology, + const t_commrec* cr, + const t_inputrec* inputrec, + t_forcerec* fr, + MDAtoms* mdAtoms, + Constraints* constr, + gmx_vsite_t* vsite); - //! Get global topology - const gmx_mtop_t &globalTopology() const; + //! Get global topology + const gmx_mtop_t& globalTopology() const; - //! Register topology client - void registerClient(ITopologyHolderClient *client); + //! Register topology client + void registerClient(ITopologyHolderClient* client); - //! Allow domdec to update local topology - friend class DomDecHelper; + //! Allow domdec to update local topology + friend class DomDecHelper; - private: - //! Constant reference to the global topolgy - const gmx_mtop_t &globalTopology_; - //! Pointer to the currently valid local topology - std::unique_ptr localTopology_; +private: + //! Constant reference to the global topolgy + const gmx_mtop_t& globalTopology_; + //! Pointer to the currently valid local topology + std::unique_ptr localTopology_; - //! List of clients to be updated if local topology changes - std::vector clients_; + //! List of clients to be updated if local topology changes + std::vector clients_; - //! Update local topology - void updateLocalTopology(); + //! Update local topology + void updateLocalTopology(); }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_TOPOLOGYHOLDER_H diff --git a/src/gromacs/modularsimulator/trajectoryelement.cpp b/src/gromacs/modularsimulator/trajectoryelement.cpp index fc83f57ceb..60998cdf06 100644 --- a/src/gromacs/modularsimulator/trajectoryelement.cpp +++ b/src/gromacs/modularsimulator/trajectoryelement.cpp @@ -49,24 +49,24 @@ namespace gmx { -TrajectoryElement::TrajectoryElement( - std::vector signalEnergyCallbacks, - std::vector signalStateCallbacks, - std::vector writerClients, - FILE *fplog, int nfile, const t_filenm fnm[], - const MdrunOptions &mdrunOptions, - const t_commrec *cr, - gmx::IMDOutputProvider *outputProvider, - const MdModulesNotifier &mdModulesNotifier, - const t_inputrec *inputrec, gmx_mtop_t *top_global, - const gmx_output_env_t *oenv, gmx_wallcycle *wcycle, - StartingBehavior startingBehavior) : +TrajectoryElement::TrajectoryElement(std::vector signalEnergyCallbacks, + std::vector signalStateCallbacks, + std::vector writerClients, + FILE* fplog, + int nfile, + const t_filenm fnm[], + const MdrunOptions& mdrunOptions, + const t_commrec* cr, + gmx::IMDOutputProvider* outputProvider, + const MdModulesNotifier& mdModulesNotifier, + const t_inputrec* inputrec, + gmx_mtop_t* top_global, + const gmx_output_env_t* oenv, + gmx_wallcycle* wcycle, + StartingBehavior startingBehavior) : writeEnergyStep_(-1), writeStateStep_(-1), - outf_(init_mdoutf( - fplog, nfile, fnm, mdrunOptions, cr, - outputProvider, mdModulesNotifier, inputrec, top_global, oenv, wcycle, - startingBehavior)), + outf_(init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, inputrec, top_global, oenv, wcycle, startingBehavior)), nstxout_(inputrec->nstxout), nstvout_(inputrec->nstvout), nstfout_(inputrec->nstfout), @@ -81,28 +81,24 @@ TrajectoryElement::TrajectoryElement( lastStep_(-1), lastStepRegistrationDone_(false), writerClients_(std::move(writerClients)) -{} +{ +} void TrajectoryElement::signallerSetup() { - GMX_ASSERT( - lastStepRegistrationDone_, - "TrajectoryElement needs to be registered to LastStepSignaller."); + GMX_ASSERT(lastStepRegistrationDone_, + "TrajectoryElement needs to be registered to LastStepSignaller."); } void TrajectoryElement::signal(Step step, Time time) { - if (do_per_step(step, nstxout_) || - do_per_step(step, nstvout_) || - do_per_step(step, nstfout_) || - do_per_step(step, nstxoutCompressed_) || - do_per_step(step, tngBoxOut_) || - do_per_step(step, tngLambdaOut_) || - do_per_step(step, tngBoxOutCompressed_) || - do_per_step(step, tngLambdaOutCompressed_)) + if (do_per_step(step, nstxout_) || do_per_step(step, nstvout_) || do_per_step(step, nstfout_) + || do_per_step(step, nstxoutCompressed_) || do_per_step(step, tngBoxOut_) + || do_per_step(step, tngLambdaOut_) || do_per_step(step, tngBoxOutCompressed_) + || do_per_step(step, tngLambdaOutCompressed_)) { writeStateStep_ = step; - for (const auto &callback : signalStateCallbacks_) + for (const auto& callback : signalStateCallbacks_) { (*callback)(step, time); } @@ -111,7 +107,7 @@ void TrajectoryElement::signal(Step step, Time time) if (do_per_step(step, nstenergy_) || step == lastStep_) { writeEnergyStep_ = step; - for (const auto &callback : signalEnergyCallbacks_) + for (const auto& callback : signalEnergyCallbacks_) { (*callback)(step, time); } @@ -120,16 +116,14 @@ void TrajectoryElement::signal(Step step, Time time) void TrajectoryElement::elementSetup() { - for (auto &client : writerClients_) + for (auto& client : writerClients_) { - auto callback = client->registerTrajectoryWriterCallback( - TrajectoryEvent::StateWritingStep); + auto callback = client->registerTrajectoryWriterCallback(TrajectoryEvent::StateWritingStep); if (callback) { runStateCallbacks_.emplace_back(std::move(callback)); } - callback = client->registerTrajectoryWriterCallback( - TrajectoryEvent::EnergyWritingStep); + callback = client->registerTrajectoryWriterCallback(TrajectoryEvent::EnergyWritingStep); if (callback) { runEnergyCallbacks_.emplace_back(std::move(callback)); @@ -138,8 +132,7 @@ void TrajectoryElement::elementSetup() } } -void TrajectoryElement::scheduleTask( - Step step, Time time, const RegisterRunFunctionPtr ®isterRunFunction) +void TrajectoryElement::scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) { const bool writeEnergyThisStep = writeEnergyStep_ == step; const bool writeStateThisStep = writeStateStep_ == step; @@ -147,16 +140,15 @@ void TrajectoryElement::scheduleTask( if (writeEnergyThisStep || writeStateThisStep || writeLogThisStep) { (*registerRunFunction)(std::make_unique( - [this, step, time, writeStateThisStep, - writeEnergyThisStep, writeLogThisStep]() - {write(step, time, writeStateThisStep, - writeEnergyThisStep, writeLogThisStep); })); + [this, step, time, writeStateThisStep, writeEnergyThisStep, writeLogThisStep]() { + write(step, time, writeStateThisStep, writeEnergyThisStep, writeLogThisStep); + })); } } void TrajectoryElement::elementTeardown() { - for (auto &client : writerClients_) + for (auto& client : writerClients_) { client->trajectoryWriterTeardown(outf_); } @@ -164,19 +156,18 @@ void TrajectoryElement::elementTeardown() done_mdoutf(outf_); } -void TrajectoryElement::write( - Step step, Time time, bool writeState, bool writeEnergy, bool writeLog) +void TrajectoryElement::write(Step step, Time time, bool writeState, bool writeEnergy, bool writeLog) { if (writeState || writeLog) { - for (auto &callback : runStateCallbacks_) + for (auto& callback : runStateCallbacks_) { (*callback)(outf_, step, time, writeState, writeLog); } } if (writeEnergy || writeLog) { - for (auto &callback : runEnergyCallbacks_) + for (auto& callback : runEnergyCallbacks_) { (*callback)(outf_, step, time, writeEnergy, writeLog); } @@ -187,25 +178,23 @@ SignallerCallbackPtr TrajectoryElement::registerLastStepCallback() { lastStepRegistrationDone_ = true; return std::make_unique( - [this](Step step, Time gmx_unused time){this->lastStep_ = step; }); + [this](Step step, Time gmx_unused time) { this->lastStep_ = step; }); } SignallerCallbackPtr TrajectoryElement::registerLoggingCallback() { return std::make_unique( - [this](Step step, Time){logWritingStep_ = step; }); + [this](Step step, Time /*unused*/) { logWritingStep_ = step; }); } -void TrajectoryElementBuilder::registerSignallerClient( - compat::not_null client) +void TrajectoryElementBuilder::registerSignallerClient(compat::not_null client) { signallerClients_.emplace_back(client); } -void TrajectoryElementBuilder::registerWriterClient( - compat::not_null client) +void TrajectoryElementBuilder::registerWriterClient(compat::not_null client) { writerClients_.emplace_back(client); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/trajectoryelement.h b/src/gromacs/modularsimulator/trajectoryelement.h index d949e59740..d33656a85b 100644 --- a/src/gromacs/modularsimulator/trajectoryelement.h +++ b/src/gromacs/modularsimulator/trajectoryelement.h @@ -78,145 +78,146 @@ enum class StartingBehavior; * write their part of the trajectory. */ class TrajectoryElement final : - public ISimulatorElement, - public ISignaller, - public ILastStepSignallerClient, - public ILoggingSignallerClient + public ISimulatorElement, + public ISignaller, + public ILastStepSignallerClient, + public ILoggingSignallerClient { - public: - friend class TrajectoryElementBuilder; - - /* - * Methods for the signaller part of the element - */ - - /*! \brief Prepare signaller - * - * Check that necessary registration was done - */ - void signallerSetup() override; - - /*! \brief Run the signaller at a specific step / time - * - * Informs clients when energy or state will be written. - * - * @param step The current time step - * @param time The current time - */ - void signal(Step step, Time time) override; - - /* - * Methods for the trajectory writing part of the element - */ - - /*! \brief Prepare trajectory writer - * - * During setup, the trajectory writer will query the writer clients for - * their callbacks. It will also call the setup methods of the different - * clients. To be run before the main simulator run, but after all clients - * were registered. - */ - void elementSetup() override; - - /*! \brief Register run function for step / time - * - * Registers a trajectory writing function if the current step / time is - * either a state or energy writing step, as defined by the signaller - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - /*! \brief Teardown trajectory writer - * - * During teardown, the trajectory writer will call the teardown - * methods of the clients and perform some additional clean-up. - * To be run after the main simulator run. - */ - void elementTeardown() override; - - //! @cond - // (doxygen doesn't like these...) - //! Allow CheckpointHelper to use outf_ (TODO: Can we improve this?) - friend class CheckpointHelper; - //! @endcond - - private: - //! Constructor - TrajectoryElement( - std::vector signalEnergyCallbacks, - std::vector signalStateCallbacks, - std::vector writerClients, - FILE *fplog, int nfile, const t_filenm fnm[], - const MdrunOptions &mdrunOptions, - const t_commrec *cr, - IMDOutputProvider *outputProvider, - const MdModulesNotifier &mdModulesNotifier, - const t_inputrec *inputrec, gmx_mtop_t *top_global, - const gmx_output_env_t *oenv, gmx_wallcycle *wcycle, - StartingBehavior startingBehavior); - - //! The next energy writing step - Step writeEnergyStep_; - //! The next state writing step - Step writeStateStep_; - //! The next communicated log writing step - Step logWritingStep_; - - //! The output object - gmx_mdoutf *outf_; - - //! ILoggingSignallerClient implementation - SignallerCallbackPtr registerLoggingCallback() override; - - /* - * Signaller - */ - //! Output frequencies - //! { - const int nstxout_; - const int nstvout_; - const int nstfout_; - const int nstxoutCompressed_; - const int tngBoxOut_; - const int tngLambdaOut_; - const int tngBoxOutCompressed_; - const int tngLambdaOutCompressed_; - const int nstenergy_; - //! } - - //! Callbacks to signal events - //! { - std::vector signalEnergyCallbacks_; - std::vector signalStateCallbacks_; - //! } - - /* - * Last step client - */ - Step lastStep_; - bool lastStepRegistrationDone_; - //! ILastStepSignallerClient implementation - SignallerCallbackPtr registerLastStepCallback() override; - - /* - * Trajectory writing - */ - //! The trajectory writing clients - std::vector writerClients_; - - //! Callbacks to write trajectory - //! { - std::vector runStateCallbacks_; - std::vector runEnergyCallbacks_; - //! } - - //! The writing function - calls the clients to get their contributions - void write(Step step, Time time, bool writeState, bool writeEnergy, bool writeLog); +public: + friend class TrajectoryElementBuilder; + + /* + * Methods for the signaller part of the element + */ + + /*! \brief Prepare signaller + * + * Check that necessary registration was done + */ + void signallerSetup() override; + + /*! \brief Run the signaller at a specific step / time + * + * Informs clients when energy or state will be written. + * + * @param step The current time step + * @param time The current time + */ + void signal(Step step, Time time) override; + + /* + * Methods for the trajectory writing part of the element + */ + + /*! \brief Prepare trajectory writer + * + * During setup, the trajectory writer will query the writer clients for + * their callbacks. It will also call the setup methods of the different + * clients. To be run before the main simulator run, but after all clients + * were registered. + */ + void elementSetup() override; + + /*! \brief Register run function for step / time + * + * Registers a trajectory writing function if the current step / time is + * either a state or energy writing step, as defined by the signaller + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + /*! \brief Teardown trajectory writer + * + * During teardown, the trajectory writer will call the teardown + * methods of the clients and perform some additional clean-up. + * To be run after the main simulator run. + */ + void elementTeardown() override; + + //! @cond + // (doxygen doesn't like these...) + //! Allow CheckpointHelper to use outf_ (TODO: Can we improve this?) + friend class CheckpointHelper; + //! @endcond + +private: + //! Constructor + TrajectoryElement(std::vector signalEnergyCallbacks, + std::vector signalStateCallbacks, + std::vector writerClients, + FILE* fplog, + int nfile, + const t_filenm fnm[], + const MdrunOptions& mdrunOptions, + const t_commrec* cr, + IMDOutputProvider* outputProvider, + const MdModulesNotifier& mdModulesNotifier, + const t_inputrec* inputrec, + gmx_mtop_t* top_global, + const gmx_output_env_t* oenv, + gmx_wallcycle* wcycle, + StartingBehavior startingBehavior); + + //! The next energy writing step + Step writeEnergyStep_; + //! The next state writing step + Step writeStateStep_; + //! The next communicated log writing step + Step logWritingStep_; + + //! The output object + gmx_mdoutf* outf_; + + //! ILoggingSignallerClient implementation + SignallerCallbackPtr registerLoggingCallback() override; + + /* + * Signaller + */ + //! Output frequencies + //! { + const int nstxout_; + const int nstvout_; + const int nstfout_; + const int nstxoutCompressed_; + const int tngBoxOut_; + const int tngLambdaOut_; + const int tngBoxOutCompressed_; + const int tngLambdaOutCompressed_; + const int nstenergy_; + //! } + + //! Callbacks to signal events + //! { + std::vector signalEnergyCallbacks_; + std::vector signalStateCallbacks_; + //! } + + /* + * Last step client + */ + Step lastStep_; + bool lastStepRegistrationDone_; + //! ILastStepSignallerClient implementation + SignallerCallbackPtr registerLastStepCallback() override; + + /* + * Trajectory writing + */ + //! The trajectory writing clients + std::vector writerClients_; + + //! Callbacks to write trajectory + //! { + std::vector runStateCallbacks_; + std::vector runEnergyCallbacks_; + //! } + + //! The writing function - calls the clients to get their contributions + void write(Step step, Time time, bool writeState, bool writeEnergy, bool writeLog); }; /*! \libinternal @@ -229,53 +230,50 @@ class TrajectoryElement final : */ class TrajectoryElementBuilder final { - public: - //! Allows clients to register to the signaller - void registerSignallerClient( - compat::not_null client); - - //! Allows clients to register as trajectory writers - void registerWriterClient( - compat::not_null client); - - //! Build the TrajectoryElement - template - std::unique_ptr build(Args && ... args); - - private: - //! List of signaller clients - std::vector signallerClients_; - //! List of writer clients - std::vector writerClients_; +public: + //! Allows clients to register to the signaller + void registerSignallerClient(compat::not_null client); + + //! Allows clients to register as trajectory writers + void registerWriterClient(compat::not_null client); + + //! Build the TrajectoryElement + template + std::unique_ptr build(Args&&... args); + +private: + //! List of signaller clients + std::vector signallerClients_; + //! List of writer clients + std::vector writerClients_; }; -template -std::unique_ptr TrajectoryElementBuilder::build(Args && ... args) +template +std::unique_ptr TrajectoryElementBuilder::build(Args&&... args) { std::vector signalEnergyCallbacks; std::vector signalStateCallbacks; // Allow clients to register their callbacks - for (auto &client : signallerClients_) + for (auto& client : signallerClients_) { // don't register nullptr - if (auto energyCallback = client->registerTrajectorySignallerCallback(TrajectoryEvent::EnergyWritingStep)) + if (auto energyCallback = + client->registerTrajectorySignallerCallback(TrajectoryEvent::EnergyWritingStep)) { signalEnergyCallbacks.emplace_back(std::move(energyCallback)); } - if (auto stateCallback = client->registerTrajectorySignallerCallback(TrajectoryEvent::StateWritingStep)) + if (auto stateCallback = + client->registerTrajectorySignallerCallback(TrajectoryEvent::StateWritingStep)) { signalStateCallbacks.emplace_back(std::move(stateCallback)); } } // NOLINTNEXTLINE(modernize-make-unique): make_unique does not work with private constructor return std::unique_ptr( - new TrajectoryElement( - std::move(signalEnergyCallbacks), - std::move(signalStateCallbacks), - std::move(writerClients_), - std::forward(args) ...)); + new TrajectoryElement(std::move(signalEnergyCallbacks), std::move(signalStateCallbacks), + std::move(writerClients_), std::forward(args)...)); } -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_TRAJECTORYELEMENT_H diff --git a/src/gromacs/modularsimulator/vrescalethermostat.cpp b/src/gromacs/modularsimulator/vrescalethermostat.cpp index 6955ee6f4b..be1c4bcff8 100644 --- a/src/gromacs/modularsimulator/vrescalethermostat.cpp +++ b/src/gromacs/modularsimulator/vrescalethermostat.cpp @@ -56,22 +56,21 @@ namespace gmx { -VRescaleThermostat::VRescaleThermostat( - int nstcouple, - int offset, - bool useFullStepKE, - int64_t seed, - int numTemperatureGroups, - double couplingTimeStep, - const real *referenceTemperature, - const real *couplingTime, - const real *numDegreesOfFreedom, - EnergyElement *energyElement, - ArrayRef lambdaView, - PropagatorCallbackPtr propagatorCallback, - const t_state *globalState, - t_commrec *cr, - bool isRestart) : +VRescaleThermostat::VRescaleThermostat(int nstcouple, + int offset, + bool useFullStepKE, + int64_t seed, + int numTemperatureGroups, + double couplingTimeStep, + const real* referenceTemperature, + const real* couplingTime, + const real* numDegreesOfFreedom, + EnergyElement* energyElement, + ArrayRef lambdaView, + PropagatorCallbackPtr propagatorCallback, + const t_state* globalState, + t_commrec* cr, + bool isRestart) : nstcouple_(nstcouple), offset_(offset), useFullStepKE_(useFullStepKE), @@ -99,14 +98,12 @@ VRescaleThermostat::VRescaleThermostat( } if (DOMAINDECOMP(cr)) { - dd_bcast(cr->dd, int(thermostatIntegral_.size()*sizeof(double)), thermostatIntegral_.data()); + dd_bcast(cr->dd, int(thermostatIntegral_.size() * sizeof(double)), thermostatIntegral_.data()); } } } -void VRescaleThermostat::scheduleTask( - Step step, Time gmx_unused time, - const RegisterRunFunctionPtr ®isterRunFunction) +void VRescaleThermostat::scheduleTask(Step step, Time gmx_unused time, const RegisterRunFunctionPtr& registerRunFunction) { /* The thermostat will need a valid kinetic energy when it is running. * Currently, computeGlobalCommunicationPeriod() is making sure this @@ -120,9 +117,7 @@ void VRescaleThermostat::scheduleTask( { // do T-coupling this step (*registerRunFunction)( - std::make_unique( - [this, step]() - {setLambda(step); })); + std::make_unique([this, step]() { setLambda(step); })); // Let propagator know that we want to do T-coupling (*propagatorCallback_)(step); @@ -150,10 +145,9 @@ void VRescaleThermostat::setLambda(Step step) { referenceKineticEnergy = 0.5 * referenceTemperature_[i] * BOLTZ * numDegreesOfFreedom_[i]; - newKineticEnergy = vrescale_resamplekin( - currentKineticEnergy, referenceKineticEnergy, - numDegreesOfFreedom_[i], couplingTime_[i]/couplingTimeStep_, - step, seed_); + newKineticEnergy = vrescale_resamplekin(currentKineticEnergy, referenceKineticEnergy, + numDegreesOfFreedom_[i], + couplingTime_[i] / couplingTimeStep_, step, seed_); // Analytically newKineticEnergy >= 0, but we check for rounding errors if (newKineticEnergy <= 0) @@ -169,8 +163,8 @@ void VRescaleThermostat::setLambda(Step step) if (debug) { - fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", - i, referenceKineticEnergy, currentKineticEnergy, newKineticEnergy, lambda_[i]); + fprintf(debug, "TC: group %d: Ekr %g, Ek %g, Ek_new %g, Lambda: %g\n", i, + referenceKineticEnergy, currentKineticEnergy, newKineticEnergy, lambda_[i]); } } else @@ -180,15 +174,15 @@ void VRescaleThermostat::setLambda(Step step) } } -void VRescaleThermostat::writeCheckpoint(t_state *localState, t_state gmx_unused *globalState) +void VRescaleThermostat::writeCheckpoint(t_state* localState, t_state gmx_unused* globalState) { localState->therm_integral = thermostatIntegral_; - localState->flags |= (1u << estTHERM_INT); + localState->flags |= (1U << estTHERM_INT); } -const std::vector &VRescaleThermostat::thermostatIntegral() const +const std::vector& VRescaleThermostat::thermostatIntegral() const { return thermostatIntegral_; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/modularsimulator/vrescalethermostat.h b/src/gromacs/modularsimulator/vrescalethermostat.h index a299f00c87..7ae9be1e64 100644 --- a/src/gromacs/modularsimulator/vrescalethermostat.h +++ b/src/gromacs/modularsimulator/vrescalethermostat.h @@ -60,86 +60,80 @@ namespace gmx * This element takes a callback to the propagator and updates the velocity * scaling factor according to the v-rescale thermostat. */ -class VRescaleThermostat final : - public ISimulatorElement, - public ICheckpointHelperClient +class VRescaleThermostat final : public ISimulatorElement, public ICheckpointHelperClient { - public: - //! Constructor - VRescaleThermostat( - int nstcouple, - int offset, - bool useFullStepKE, - int64_t seed, - int numTemperatureGroups, - double couplingTimeStep, - const real *referenceTemperature, - const real *couplingTime, - const real *numDegreesOfFreedom, - EnergyElement *energyElement, - ArrayRef lambdaView, - PropagatorCallbackPtr propagatorCallback, - const t_state *globalState, - t_commrec *cr, - bool isRestart); - - /*! \brief Register run function for step / time - * - * @param step The step number - * @param time The time - * @param registerRunFunction Function allowing to register a run function - */ - void scheduleTask( - Step step, Time time, - const RegisterRunFunctionPtr ®isterRunFunction) override; - - //! No element setup needed - void elementSetup() override {} - //! No element teardown needed - void elementTeardown() override {} - - //! Getter for the thermostatIntegral - const std::vector &thermostatIntegral() const; - - private: - //! The frequency at which the thermostat is applied - const int nstcouple_; - //! If != 0, offset the step at which the thermostat is applied - const int offset_; - //! Whether we're using full step kinetic energy - const bool useFullStepKE_; - //! The random seed - const int64_t seed_; - - //! The number of temperature groups - const int numTemperatureGroups_; - //! The coupling time step - simulation time step x nstcouple_ - const double couplingTimeStep_; - //! Coupling temperature per group - const std::vector referenceTemperature_; - //! Coupling time per group - const std::vector couplingTime_; - //! Number of degrees of freedom per group - const std::vector numDegreesOfFreedom_; - //! Work exerted by thermostat - std::vector thermostatIntegral_; - - //! Pointer to the energy element (for ekindata) - EnergyElement *energyElement_; - - //! View on the scaling factor of the propagator - ArrayRef lambda_; - //! Callback to let propagator know that we updated lambda - PropagatorCallbackPtr propagatorCallback_; - - //! Set new lambda value (at T-coupling steps) - void setLambda(Step step); - - //! ICheckpointHelperClient implementation - void writeCheckpoint(t_state *localState, t_state *globalState) override; - +public: + //! Constructor + VRescaleThermostat(int nstcouple, + int offset, + bool useFullStepKE, + int64_t seed, + int numTemperatureGroups, + double couplingTimeStep, + const real* referenceTemperature, + const real* couplingTime, + const real* numDegreesOfFreedom, + EnergyElement* energyElement, + ArrayRef lambdaView, + PropagatorCallbackPtr propagatorCallback, + const t_state* globalState, + t_commrec* cr, + bool isRestart); + + /*! \brief Register run function for step / time + * + * @param step The step number + * @param time The time + * @param registerRunFunction Function allowing to register a run function + */ + void scheduleTask(Step step, Time time, const RegisterRunFunctionPtr& registerRunFunction) override; + + //! No element setup needed + void elementSetup() override {} + //! No element teardown needed + void elementTeardown() override {} + + //! Getter for the thermostatIntegral + const std::vector& thermostatIntegral() const; + +private: + //! The frequency at which the thermostat is applied + const int nstcouple_; + //! If != 0, offset the step at which the thermostat is applied + const int offset_; + //! Whether we're using full step kinetic energy + const bool useFullStepKE_; + //! The random seed + const int64_t seed_; + + //! The number of temperature groups + const int numTemperatureGroups_; + //! The coupling time step - simulation time step x nstcouple_ + const double couplingTimeStep_; + //! Coupling temperature per group + const std::vector referenceTemperature_; + //! Coupling time per group + const std::vector couplingTime_; + //! Number of degrees of freedom per group + const std::vector numDegreesOfFreedom_; + //! Work exerted by thermostat + std::vector thermostatIntegral_; + + //! Pointer to the energy element (for ekindata) + EnergyElement* energyElement_; + + //! View on the scaling factor of the propagator + ArrayRef lambda_; + //! Callback to let propagator know that we updated lambda + PropagatorCallbackPtr propagatorCallback_; + + //! Set new lambda value (at T-coupling steps) + void setLambda(Step step); + + //! ICheckpointHelperClient implementation + void writeCheckpoint(t_state* localState, t_state* globalState) override; }; -} // namespace gmx +} // namespace gmx #endif // GMX_MODULARSIMULATOR_VRESCALETHERMOSTAT_H diff --git a/src/gromacs/nbnxm/atomdata.cpp b/src/gromacs/nbnxm/atomdata.cpp index bfd01537c5..c4a15ba974 100644 --- a/src/gromacs/nbnxm/atomdata.cpp +++ b/src/gromacs/nbnxm/atomdata.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2012-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,18 +75,19 @@ void nbnxn_atomdata_t::resizeCoordinateBuffer(int numAtoms) { numAtoms_ = numAtoms; - x_.resize(numAtoms*xstride); + x_.resize(numAtoms * xstride); } void nbnxn_atomdata_t::resizeForceBuffers() { /* Force buffers need padding up to a multiple of the buffer flag size */ - const int paddedSize = (numAtoms() + NBNXN_BUFFERFLAG_SIZE - 1)/NBNXN_BUFFERFLAG_SIZE*NBNXN_BUFFERFLAG_SIZE; + const int paddedSize = + (numAtoms() + NBNXN_BUFFERFLAG_SIZE - 1) / NBNXN_BUFFERFLAG_SIZE * NBNXN_BUFFERFLAG_SIZE; /* Should we let each thread allocate it's own data instead? */ - for (nbnxn_atomdata_output_t &outBuffer : out) + for (nbnxn_atomdata_output_t& outBuffer : out) { - outBuffer.f.resize(paddedSize*fstride); + outBuffer.f.resize(paddedSize * fstride); } } @@ -94,26 +96,26 @@ nbnxn_atomdata_output_t::nbnxn_atomdata_output_t(Nbnxm::KernelType kernelType, int numEnergyGroups, int simdEnergyBufferStride, gmx::PinningPolicy pinningPolicy) : - f({}, {pinningPolicy}), - fshift({}, {pinningPolicy}), - Vvdw({}, {pinningPolicy}), - Vc({}, {pinningPolicy}) + f({}, { pinningPolicy }), + fshift({}, { pinningPolicy }), + Vvdw({}, { pinningPolicy }), + Vc({}, { pinningPolicy }) { - fshift.resize(SHIFTS*DIM); - Vvdw.resize(numEnergyGroups*numEnergyGroups); - Vc.resize(numEnergyGroups*numEnergyGroups); + fshift.resize(SHIFTS * DIM); + Vvdw.resize(numEnergyGroups * numEnergyGroups); + Vc.resize(numEnergyGroups * numEnergyGroups); if (Nbnxm::kernelTypeIsSimd(kernelType)) { - int cj_size = Nbnxm::JClusterSizePerKernelType[kernelType]; - int numElements = numEnergyGroups*numEnergyGroups*simdEnergyBufferStride*(cj_size/2)*cj_size; + int cj_size = Nbnxm::JClusterSizePerKernelType[kernelType]; + int numElements = + numEnergyGroups * numEnergyGroups * simdEnergyBufferStride * (cj_size / 2) * cj_size; VSvdw.resize(numElements); VSc.resize(numElements); } } -static void copy_int_to_nbat_int(const int *a, int na, int na_round, - const int *in, int fill, int *innb) +static void copy_int_to_nbat_int(const int* a, int na, int na_round, const int* in, int fill, int* innb) { int i, j; @@ -129,9 +131,7 @@ static void copy_int_to_nbat_int(const int *a, int na, int na_round, } } -void copy_rvec_to_nbat_real(const int *a, int na, int na_round, - const rvec *x, int nbatFormat, - real *xnb, int a0) +void copy_rvec_to_nbat_real(const int* a, int na, int na_round, const rvec* x, int nbatFormat, real* xnb, int a0) { /* We complete partially filled cells, can only be the last one in each * column, with coordinates farAway. The actual coordinate value does @@ -145,12 +145,12 @@ void copy_rvec_to_nbat_real(const int *a, int na, int na_round, */ const real farAway = -1000000; - int i, j, c; + int i, j, c; switch (nbatFormat) { case nbatXYZ: - j = a0*STRIDE_XYZ; + j = a0 * STRIDE_XYZ; for (i = 0; i < na; i++) { xnb[j++] = x[a[i]][XX]; @@ -166,7 +166,7 @@ void copy_rvec_to_nbat_real(const int *a, int na, int na_round, } break; case nbatXYZQ: - j = a0*STRIDE_XYZQ; + j = a0 * STRIDE_XYZQ; for (i = 0; i < na; i++) { xnb[j++] = x[a[i]][XX]; @@ -185,32 +185,32 @@ void copy_rvec_to_nbat_real(const int *a, int na, int na_round, break; case nbatX4: j = atom_to_x_index(a0); - c = a0 & (c_packX4-1); + c = a0 & (c_packX4 - 1); for (i = 0; i < na; i++) { - xnb[j+XX*c_packX4] = x[a[i]][XX]; - xnb[j+YY*c_packX4] = x[a[i]][YY]; - xnb[j+ZZ*c_packX4] = x[a[i]][ZZ]; + xnb[j + XX * c_packX4] = x[a[i]][XX]; + xnb[j + YY * c_packX4] = x[a[i]][YY]; + xnb[j + ZZ * c_packX4] = x[a[i]][ZZ]; j++; c++; if (c == c_packX4) { - j += (DIM-1)*c_packX4; - c = 0; + j += (DIM - 1) * c_packX4; + c = 0; } } /* Complete the partially filled last cell with zeros */ for (; i < na_round; i++) { - xnb[j+XX*c_packX4] = farAway; - xnb[j+YY*c_packX4] = farAway; - xnb[j+ZZ*c_packX4] = farAway; + xnb[j + XX * c_packX4] = farAway; + xnb[j + YY * c_packX4] = farAway; + xnb[j + ZZ * c_packX4] = farAway; j++; c++; if (c == c_packX4) { - j += (DIM-1)*c_packX4; - c = 0; + j += (DIM - 1) * c_packX4; + c = 0; } } break; @@ -219,41 +219,40 @@ void copy_rvec_to_nbat_real(const int *a, int na, int na_round, c = a0 & (c_packX8 - 1); for (i = 0; i < na; i++) { - xnb[j+XX*c_packX8] = x[a[i]][XX]; - xnb[j+YY*c_packX8] = x[a[i]][YY]; - xnb[j+ZZ*c_packX8] = x[a[i]][ZZ]; + xnb[j + XX * c_packX8] = x[a[i]][XX]; + xnb[j + YY * c_packX8] = x[a[i]][YY]; + xnb[j + ZZ * c_packX8] = x[a[i]][ZZ]; j++; c++; if (c == c_packX8) { - j += (DIM-1)*c_packX8; - c = 0; + j += (DIM - 1) * c_packX8; + c = 0; } } /* Complete the partially filled last cell with zeros */ for (; i < na_round; i++) { - xnb[j+XX*c_packX8] = farAway; - xnb[j+YY*c_packX8] = farAway; - xnb[j+ZZ*c_packX8] = farAway; + xnb[j + XX * c_packX8] = farAway; + xnb[j + YY * c_packX8] = farAway; + xnb[j + ZZ * c_packX8] = farAway; j++; c++; if (c == c_packX8) { - j += (DIM-1)*c_packX8; - c = 0; + j += (DIM - 1) * c_packX8; + c = 0; } } break; - default: - gmx_incons("Unsupported nbnxn_atomdata_t format"); + default: gmx_incons("Unsupported nbnxn_atomdata_t format"); } } /* Stores the LJ parameter data in a format convenient for different kernels */ -static void set_lj_parameter_data(nbnxn_atomdata_t::Params *params, gmx_bool bSIMD) +static void set_lj_parameter_data(nbnxn_atomdata_t::Params* params, gmx_bool bSIMD) { - int nt = params->numTypes; + int nt = params->numTypes; if (bSIMD) { @@ -265,18 +264,20 @@ static void set_lj_parameter_data(nbnxn_atomdata_t::Params *params, gmx_bool bSI * when it might not be used, but introducing the conditional code is not * really worth it. */ - params->nbfp_aligned.resize(nt*nt*c_simdBestPairAlignment); + params->nbfp_aligned.resize(nt * nt * c_simdBestPairAlignment); for (int i = 0; i < nt; i++) { for (int j = 0; j < nt; j++) { - params->nbfp_aligned[(i*nt+j)*c_simdBestPairAlignment+0] = params->nbfp[(i*nt+j)*2+0]; - params->nbfp_aligned[(i*nt+j)*c_simdBestPairAlignment+1] = params->nbfp[(i*nt+j)*2+1]; + params->nbfp_aligned[(i * nt + j) * c_simdBestPairAlignment + 0] = + params->nbfp[(i * nt + j) * 2 + 0]; + params->nbfp_aligned[(i * nt + j) * c_simdBestPairAlignment + 1] = + params->nbfp[(i * nt + j) * 2 + 1]; if (c_simdBestPairAlignment > 2) { - params->nbfp_aligned[(i*nt+j)*c_simdBestPairAlignment+2] = 0; - params->nbfp_aligned[(i*nt+j)*c_simdBestPairAlignment+3] = 0; + params->nbfp_aligned[(i * nt + j) * c_simdBestPairAlignment + 2] = 0; + params->nbfp_aligned[(i * nt + j) * c_simdBestPairAlignment + 3] = 0; } } } @@ -287,7 +288,7 @@ static void set_lj_parameter_data(nbnxn_atomdata_t::Params *params, gmx_bool bSI * and with LJ-PME kernels. We then only need parameters per atom type, * not per pair of atom types. */ - params->nbfp_comb.resize(nt*2); + params->nbfp_comb.resize(nt * 2); switch (params->comb_rule) { case ljcrGEOM: @@ -296,36 +297,35 @@ static void set_lj_parameter_data(nbnxn_atomdata_t::Params *params, gmx_bool bSI for (int i = 0; i < nt; i++) { /* Store the sqrt of the diagonal from the nbfp matrix */ - params->nbfp_comb[i*2 ] = std::sqrt(params->nbfp[(i*nt+i)*2 ]); - params->nbfp_comb[i*2+1] = std::sqrt(params->nbfp[(i*nt+i)*2+1]); + params->nbfp_comb[i * 2] = std::sqrt(params->nbfp[(i * nt + i) * 2]); + params->nbfp_comb[i * 2 + 1] = std::sqrt(params->nbfp[(i * nt + i) * 2 + 1]); } break; case ljcrLB: for (int i = 0; i < nt; i++) { /* Get 6*C6 and 12*C12 from the diagonal of the nbfp matrix */ - const real c6 = params->nbfp[(i*nt+i)*2 ]; - const real c12 = params->nbfp[(i*nt+i)*2+1]; + const real c6 = params->nbfp[(i * nt + i) * 2]; + const real c12 = params->nbfp[(i * nt + i) * 2 + 1]; if (c6 > 0 && c12 > 0) { /* We store 0.5*2^1/6*sigma and sqrt(4*3*eps), * so we get 6*C6 and 12*C12 after combining. */ - params->nbfp_comb[i*2 ] = 0.5*gmx::sixthroot(c12/c6); - params->nbfp_comb[i*2+1] = std::sqrt(c6*c6/c12); + params->nbfp_comb[i * 2] = 0.5 * gmx::sixthroot(c12 / c6); + params->nbfp_comb[i * 2 + 1] = std::sqrt(c6 * c6 / c12); } else { - params->nbfp_comb[i*2 ] = 0; - params->nbfp_comb[i*2+1] = 0; + params->nbfp_comb[i * 2] = 0; + params->nbfp_comb[i * 2 + 1] = 0; } } break; case ljcrNONE: /* We always store the full matrix (see code above) */ break; - default: - gmx_incons("Unknown combination rule"); + default: gmx_incons("Unknown combination rule"); } } @@ -347,12 +347,12 @@ nbnxn_atomdata_t::SimdMasks::SimdMasks() } diagonal_2xnn_j_minus_i.resize(simd_width); - for (int j = 0; j < simd_width/2; j++) + for (int j = 0; j < simd_width / 2; j++) { /* The j-cluster size is half the SIMD width */ - diagonal_2xnn_j_minus_i[j] = j - 0.5; + diagonal_2xnn_j_minus_i[j] = j - 0.5; /* The next half of the SIMD width is for i + 1 */ - diagonal_2xnn_j_minus_i[simd_width/2 + j] = j - 1 - 0.5; + diagonal_2xnn_j_minus_i[simd_width / 2 + j] = j - 1 - 0.5; } /* We use up to 32 bits for exclusion masking. @@ -362,21 +362,21 @@ nbnxn_atomdata_t::SimdMasks::SimdMasks() * In single precision this means the real and integer SIMD registers * are of equal size. */ - const int simd_excl_size = c_nbnxnCpuIClusterSize*simd_width; -#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL + const int simd_excl_size = c_nbnxnCpuIClusterSize * simd_width; +# if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL exclusion_filter64.resize(simd_excl_size); -#else +# else exclusion_filter.resize(simd_excl_size); -#endif +# endif for (int j = 0; j < simd_excl_size; j++) { /* Set the consecutive bits for masking pair exclusions */ -#if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL +# if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL exclusion_filter64[j] = (1U << j); -#else - exclusion_filter[j] = (1U << j); -#endif +# else + exclusion_filter[j] = (1U << j); +# endif } if (!GMX_SIMD_HAVE_LOGICAL && !GMX_SIMD_HAVE_INT32_LOGICAL) // NOLINT(misc-redundant-expression) @@ -394,7 +394,7 @@ nbnxn_atomdata_t::SimdMasks::SimdMasks() // Matching code exists in set_ci_top_excls() to generate indices into this array. // Those indices are used in the kernels. - const int simd_excl_size = c_nbnxnCpuIClusterSize*c_nbnxnCpuIClusterSize; + const int simd_excl_size = c_nbnxnCpuIClusterSize * c_nbnxnCpuIClusterSize; const real simdFalse = 0.0; const real simdTrue = 1.0; @@ -413,14 +413,14 @@ nbnxn_atomdata_t::SimdMasks::SimdMasks() nbnxn_atomdata_t::Params::Params(gmx::PinningPolicy pinningPolicy) : numTypes(0), - nbfp({}, {pinningPolicy}), - nbfp_comb({}, {pinningPolicy}), - type({}, {pinningPolicy}), - lj_comb({}, {pinningPolicy}), - q({}, {pinningPolicy}), + nbfp({}, { pinningPolicy }), + nbfp_comb({}, { pinningPolicy }), + type({}, { pinningPolicy }), + lj_comb({}, { pinningPolicy }), + q({}, { pinningPolicy }), nenergrp(0), neg_2log(0), - energrp({}, {pinningPolicy}) + energrp({}, { pinningPolicy }) { } @@ -428,8 +428,8 @@ nbnxn_atomdata_t::nbnxn_atomdata_t(gmx::PinningPolicy pinningPolicy) : params_(pinningPolicy), numAtoms_(0), natoms_local(0), - shift_vec({}, {pinningPolicy}), - x_({}, {pinningPolicy}), + shift_vec({}, { pinningPolicy }), + x_({}, { pinningPolicy }), simdMasks(), bUseBufferFlags(FALSE), bUseTreeReduce(FALSE) @@ -437,15 +437,16 @@ nbnxn_atomdata_t::nbnxn_atomdata_t(gmx::PinningPolicy pinningPolicy) : } /* Initializes an nbnxn_atomdata_t::Params data structure */ -static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, - nbnxn_atomdata_t::Params *params, - const Nbnxm::KernelType kernelType, - int enbnxninitcombrule, - int ntype, const real *nbfp, - int n_energygroups) +static void nbnxn_atomdata_params_init(const gmx::MDLogger& mdlog, + nbnxn_atomdata_t::Params* params, + const Nbnxm::KernelType kernelType, + int enbnxninitcombrule, + int ntype, + const real* nbfp, + int n_energygroups) { real c6, c12, tol; - char *ptr; + char* ptr; gmx_bool simple, bCombGeom, bCombLB, bSIMD; if (debug) @@ -453,8 +454,8 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, fprintf(debug, "There are %d atom types in the system, adding one for nbnxn_atomdata_t\n", ntype); } params->numTypes = ntype + 1; - params->nbfp.resize(params->numTypes*params->numTypes*2); - params->nbfp_comb.resize(params->numTypes*2); + params->nbfp.resize(params->numTypes * params->numTypes * 2); + params->nbfp_comb.resize(params->numTypes * 2); /* A tolerance of 1e-5 seems reasonable for (possibly hand-typed) * force-field floating point parameters. @@ -476,17 +477,17 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, */ for (int i = 0; i < ntype; i++) { - c6 = nbfp[(i*ntype+i)*2 ]/6.0; - c12 = nbfp[(i*ntype+i)*2 + 1]/12.0; + c6 = nbfp[(i * ntype + i) * 2] / 6.0; + c12 = nbfp[(i * ntype + i) * 2 + 1] / 12.0; if (c6 > 0 && c12 > 0) { - params->nbfp_comb[i*2 ] = gmx::sixthroot(c12/c6); - params->nbfp_comb[i*2 + 1] = 0.25*c6*c6/c12; + params->nbfp_comb[i * 2] = gmx::sixthroot(c12 / c6); + params->nbfp_comb[i * 2 + 1] = 0.25 * c6 * c6 / c12; } else if (c6 == 0 && c12 == 0) { - params->nbfp_comb[i*2 ] = 0; - params->nbfp_comb[i*2 + 1] = 0; + params->nbfp_comb[i * 2] = 0; + params->nbfp_comb[i * 2 + 1] = 0; } else { @@ -504,32 +505,41 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, /* fr->nbfp has been updated, so that array too now stores c6/c12 including * the 6.0/12.0 prefactors to save 2 flops in the most common case (force-only). */ - c6 = nbfp[(i*ntype+j)*2 ]; - c12 = nbfp[(i*ntype+j)*2 + 1]; - params->nbfp[(i*params->numTypes+j)*2 ] = c6; - params->nbfp[(i*params->numTypes+j)*2 + 1] = c12; + c6 = nbfp[(i * ntype + j) * 2]; + c12 = nbfp[(i * ntype + j) * 2 + 1]; + params->nbfp[(i * params->numTypes + j) * 2] = c6; + params->nbfp[(i * params->numTypes + j) * 2 + 1] = c12; /* Compare 6*C6 and 12*C12 for geometric cobination rule */ - bCombGeom = bCombGeom && - gmx_within_tol(c6*c6, nbfp[(i*ntype+i)*2 ]*nbfp[(j*ntype+j)*2 ], tol) && - gmx_within_tol(c12*c12, nbfp[(i*ntype+i)*2 + 1]*nbfp[(j*ntype+j)*2 + 1], tol); + bCombGeom = + bCombGeom + && gmx_within_tol(c6 * c6, + nbfp[(i * ntype + i) * 2] * nbfp[(j * ntype + j) * 2], tol) + && gmx_within_tol(c12 * c12, + nbfp[(i * ntype + i) * 2 + 1] * nbfp[(j * ntype + j) * 2 + 1], + tol); /* Compare C6 and C12 for Lorentz-Berthelot combination rule */ - c6 /= 6.0; - c12 /= 12.0; - bCombLB = bCombLB && - ((c6 == 0 && c12 == 0 && - (params->nbfp_comb[i*2 + 1] == 0 || params->nbfp_comb[j*2 + 1] == 0)) || - (c6 > 0 && c12 > 0 && - gmx_within_tol(gmx::sixthroot(c12/c6), - 0.5*(params->nbfp_comb[i*2]+params->nbfp_comb[j*2]), tol) && - gmx_within_tol(0.25*c6*c6/c12, std::sqrt(params->nbfp_comb[i*2 + 1]*params->nbfp_comb[j*2 + 1]), tol))); + c6 /= 6.0; + c12 /= 12.0; + bCombLB = + bCombLB + && ((c6 == 0 && c12 == 0 + && (params->nbfp_comb[i * 2 + 1] == 0 || params->nbfp_comb[j * 2 + 1] == 0)) + || (c6 > 0 && c12 > 0 + && gmx_within_tol( + gmx::sixthroot(c12 / c6), + 0.5 * (params->nbfp_comb[i * 2] + params->nbfp_comb[j * 2]), tol) + && gmx_within_tol(0.25 * c6 * c6 / c12, + std::sqrt(params->nbfp_comb[i * 2 + 1] + * params->nbfp_comb[j * 2 + 1]), + tol))); } else { /* Add zero parameters for the additional dummy atom type */ - params->nbfp[(i*params->numTypes + j)*2 ] = 0; - params->nbfp[(i*params->numTypes + j)*2+1] = 0; + params->nbfp[(i * params->numTypes + j) * 2] = 0; + params->nbfp[(i * params->numTypes + j) * 2 + 1] = 0; } } } @@ -570,25 +580,21 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, } else { - mesg = gmx::formatString("Using %s Lennard-Jones combination rule", - params->comb_rule == ljcrGEOM ? "geometric" : "Lorentz-Berthelot"); + mesg = gmx::formatString( + "Using %s Lennard-Jones combination rule", + params->comb_rule == ljcrGEOM ? "geometric" : "Lorentz-Berthelot"); } GMX_LOG(mdlog.info).asParagraph().appendText(mesg); } break; - case enbnxninitcombruleGEOM: - params->comb_rule = ljcrGEOM; - break; - case enbnxninitcombruleLB: - params->comb_rule = ljcrLB; - break; + case enbnxninitcombruleGEOM: params->comb_rule = ljcrGEOM; break; + case enbnxninitcombruleLB: params->comb_rule = ljcrLB; break; case enbnxninitcombruleNONE: params->comb_rule = ljcrNONE; params->nbfp_comb.clear(); break; - default: - gmx_incons("Unknown enbnxninitcombrule"); + default: gmx_incons("Unknown enbnxninitcombrule"); } bSIMD = Nbnxm::kernelTypeIsSimd(kernelType); @@ -607,23 +613,24 @@ static void nbnxn_atomdata_params_init(const gmx::MDLogger &mdlog, gmx_fatal(FARGS, "With NxN kernels not more than 64 energy groups are supported\n"); } params->neg_2log = 1; - while (params->nenergrp > (1<neg_2log)) + while (params->nenergrp > (1 << params->neg_2log)) { params->neg_2log++; } } /* Initializes an nbnxn_atomdata_t data structure */ -void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, - nbnxn_atomdata_t *nbat, +void nbnxn_atomdata_init(const gmx::MDLogger& mdlog, + nbnxn_atomdata_t* nbat, const Nbnxm::KernelType kernelType, - int enbnxninitcombrule, - int ntype, const real *nbfp, - int n_energygroups, - int nout) + int enbnxninitcombrule, + int ntype, + const real* nbfp, + int n_energygroups, + int nout) { - nbnxn_atomdata_params_init(mdlog, &nbat->paramsDeprecated(), kernelType, - enbnxninitcombrule, ntype, nbfp, n_energygroups); + nbnxn_atomdata_params_init(mdlog, &nbat->paramsDeprecated(), kernelType, enbnxninitcombrule, + ntype, nbfp, n_energygroups); const bool simple = Nbnxm::kernelTypeUsesSimplePairlist(kernelType); const bool bSIMD = Nbnxm::kernelTypeIsSimd(kernelType); @@ -634,18 +641,12 @@ void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, if (bSIMD) { - pack_x = std::max(c_nbnxnCpuIClusterSize, - Nbnxm::JClusterSizePerKernelType[kernelType]); + pack_x = std::max(c_nbnxnCpuIClusterSize, Nbnxm::JClusterSizePerKernelType[kernelType]); switch (pack_x) { - case 4: - nbat->XFormat = nbatX4; - break; - case 8: - nbat->XFormat = nbatX8; - break; - default: - gmx_incons("Unsupported packing width"); + case 4: nbat->XFormat = nbatX4; break; + case 8: nbat->XFormat = nbatX8; break; + default: gmx_incons("Unsupported packing width"); } } else @@ -669,7 +670,7 @@ void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, /* Initialize the output data structures */ for (int i = 0; i < nout; i++) { - const auto &pinningPolicy = nbat->params().type.get_allocator().pinningPolicy(); + const auto& pinningPolicy = nbat->params().type.get_allocator().pinningPolicy(); nbat->out.emplace_back(kernelType, nbat->params().nenergrp, 1 << nbat->params().neg_2log, pinningPolicy); } @@ -677,9 +678,9 @@ void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, nbat->buffer_flags.flag = nullptr; nbat->buffer_flags.flag_nalloc = 0; - const int nth = gmx_omp_nthreads_get(emntNonbonded); + const int nth = gmx_omp_nthreads_get(emntNonbonded); - const char *ptr = getenv("GMX_USE_TREEREDUCE"); + const char* ptr = getenv("GMX_USE_TREEREDUCE"); if (ptr != nullptr) { nbat->bUseTreeReduce = (strtol(ptr, nullptr, 10) != 0); @@ -703,9 +704,7 @@ void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, } template -static void copy_lj_to_nbat_lj_comb(gmx::ArrayRef ljparam_type, - const int *type, int na, - real *ljparam_at) +static void copy_lj_to_nbat_lj_comb(gmx::ArrayRef ljparam_type, const int* type, int na, real* ljparam_at) { /* The LJ params follow the combination rule: * copy the params for the type array to the atom array. @@ -714,21 +713,21 @@ static void copy_lj_to_nbat_lj_comb(gmx::ArrayRef ljparam_type, { for (int k = 0; k < packSize; k++) { - int i = is + k; - ljparam_at[is*2 + k] = ljparam_type[type[i]*2 ]; - ljparam_at[is*2 + packSize + k] = ljparam_type[type[i]*2 + 1]; + int i = is + k; + ljparam_at[is * 2 + k] = ljparam_type[type[i] * 2]; + ljparam_at[is * 2 + packSize + k] = ljparam_type[type[i] * 2 + 1]; } } } /* Sets the atom type in nbnxn_atomdata_t */ -static void nbnxn_atomdata_set_atomtypes(nbnxn_atomdata_t::Params *params, - const Nbnxm::GridSet &gridSet, - const int *type) +static void nbnxn_atomdata_set_atomtypes(nbnxn_atomdata_t::Params* params, + const Nbnxm::GridSet& gridSet, + const int* type) { params->type.resize(gridSet.numGridAtomsTotal()); - for (const Nbnxm::Grid &grid : gridSet.grids()) + for (const Nbnxm::Grid& grid : gridSet.grids()) { /* Loop over all columns and copy and fill */ for (int i = 0; i < grid.numColumns(); i++) @@ -736,23 +735,22 @@ static void nbnxn_atomdata_set_atomtypes(nbnxn_atomdata_t::Params *params, const int numAtoms = grid.paddedNumAtomsInColumn(i); const int atomOffset = grid.firstAtomInColumn(i); - copy_int_to_nbat_int(gridSet.atomIndices().data() + atomOffset, - grid.numAtomsInColumn(i), numAtoms, - type, params->numTypes - 1, params->type.data() + atomOffset); + copy_int_to_nbat_int(gridSet.atomIndices().data() + atomOffset, grid.numAtomsInColumn(i), + numAtoms, type, params->numTypes - 1, params->type.data() + atomOffset); } } } /* Sets the LJ combination rule parameters in nbnxn_atomdata_t */ -static void nbnxn_atomdata_set_ljcombparams(nbnxn_atomdata_t::Params *params, +static void nbnxn_atomdata_set_ljcombparams(nbnxn_atomdata_t::Params* params, const int XFormat, - const Nbnxm::GridSet &gridSet) + const Nbnxm::GridSet& gridSet) { - params->lj_comb.resize(gridSet.numGridAtomsTotal()*2); + params->lj_comb.resize(gridSet.numGridAtomsTotal() * 2); if (params->comb_rule != ljcrNONE) { - for (const Nbnxm::Grid &grid : gridSet.grids()) + for (const Nbnxm::Grid& grid : gridSet.grids()) { /* Loop over all columns and copy and fill */ for (int i = 0; i < grid.numColumns(); i++) @@ -763,23 +761,19 @@ static void nbnxn_atomdata_set_ljcombparams(nbnxn_atomdata_t::Params *params, if (XFormat == nbatX4) { copy_lj_to_nbat_lj_comb(params->nbfp_comb, - params->type.data() + atomOffset, - numAtoms, - params->lj_comb.data() + atomOffset*2); + params->type.data() + atomOffset, numAtoms, + params->lj_comb.data() + atomOffset * 2); } else if (XFormat == nbatX8) { copy_lj_to_nbat_lj_comb(params->nbfp_comb, - params->type.data() + atomOffset, - numAtoms, - params->lj_comb.data() + atomOffset*2); + params->type.data() + atomOffset, numAtoms, + params->lj_comb.data() + atomOffset * 2); } else if (XFormat == nbatXYZQ) { - copy_lj_to_nbat_lj_comb<1>(params->nbfp_comb, - params->type.data() + atomOffset, - numAtoms, - params->lj_comb.data() + atomOffset*2); + copy_lj_to_nbat_lj_comb<1>(params->nbfp_comb, params->type.data() + atomOffset, + numAtoms, params->lj_comb.data() + atomOffset * 2); } } } @@ -787,16 +781,14 @@ static void nbnxn_atomdata_set_ljcombparams(nbnxn_atomdata_t::Params *params, } /* Sets the charges in nbnxn_atomdata_t *nbat */ -static void nbnxn_atomdata_set_charges(nbnxn_atomdata_t *nbat, - const Nbnxm::GridSet &gridSet, - const real *charge) +static void nbnxn_atomdata_set_charges(nbnxn_atomdata_t* nbat, const Nbnxm::GridSet& gridSet, const real* charge) { if (nbat->XFormat != nbatXYZQ) { nbat->paramsDeprecated().q.resize(nbat->numAtoms()); } - for (const Nbnxm::Grid &grid : gridSet.grids()) + for (const Nbnxm::Grid& grid : gridSet.grids()) { /* Loop over all columns and copy and fill */ for (int cxy = 0; cxy < grid.numColumns(); cxy++) @@ -807,7 +799,7 @@ static void nbnxn_atomdata_set_charges(nbnxn_atomdata_t *nbat, if (nbat->XFormat == nbatXYZQ) { - real *q = nbat->x().data() + atomOffset*STRIDE_XYZQ + ZZ + 1; + real* q = nbat->x().data() + atomOffset * STRIDE_XYZQ + ZZ + 1; int i; for (i = 0; i < numAtoms; i++) { @@ -823,7 +815,7 @@ static void nbnxn_atomdata_set_charges(nbnxn_atomdata_t *nbat, } else { - real *q = nbat->paramsDeprecated().q.data() + atomOffset; + real* q = nbat->paramsDeprecated().q.data() + atomOffset; int i; for (i = 0; i < numAtoms; i++) { @@ -847,11 +839,10 @@ static void nbnxn_atomdata_set_charges(nbnxn_atomdata_t *nbat, * All perturbed interactions are calculated in the free energy kernel, * using the original charge and LJ data, not nbnxn_atomdata_t. */ -static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t *nbat, - const Nbnxm::GridSet &gridSet) +static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t* nbat, const Nbnxm::GridSet& gridSet) { - nbnxn_atomdata_t::Params ¶ms = nbat->paramsDeprecated(); - real *q; + nbnxn_atomdata_t::Params& params = nbat->paramsDeprecated(); + real* q; int stride_q; if (nbat->XFormat == nbatXYZQ) @@ -865,7 +856,7 @@ static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t *nbat, stride_q = 1; } - for (const Nbnxm::Grid &grid : gridSet.grids()) + for (const Nbnxm::Grid& grid : gridSet.grids()) { int nsubc; if (grid.geometry().isSimple) @@ -880,7 +871,7 @@ static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t *nbat, int c_offset = grid.firstAtomInColumn(0); /* Loop over all columns and copy and fill */ - for (int c = 0; c < grid.numCells()*nsubc; c++) + for (int c = 0; c < grid.numCells() * nsubc; c++) { /* Does this cluster contain perturbed particles? */ if (grid.clusterIsPerturbed(c)) @@ -891,10 +882,10 @@ static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t *nbat, /* Is this a perturbed particle? */ if (grid.atomIsPerturbed(c, i)) { - int ind = c_offset + c*numAtomsPerCluster + i; + int ind = c_offset + c * numAtomsPerCluster + i; /* Set atom type and charge to non-interacting */ - params.type[ind] = params.numTypes - 1; - q[ind*stride_q] = 0; + params.type[ind] = params.numTypes - 1; + q[ind * stride_q] = 0; } } } @@ -903,9 +894,8 @@ static void nbnxn_atomdata_mask_fep(nbnxn_atomdata_t *nbat, } /* Copies the energy group indices to a reordered and packed array */ -static void copy_egp_to_nbat_egps(const int *a, int na, int na_round, - int na_c, int bit_shift, - const int *in, int *innb) +static void +copy_egp_to_nbat_egps(const int* a, int na, int na_round, int na_c, int bit_shift, const int* in, int* innb) { int i; int comb; @@ -917,10 +907,10 @@ static void copy_egp_to_nbat_egps(const int *a, int na, int na_round, comb = 0; for (int sa = 0; sa < na_c; sa++) { - int at = a[i+sa]; + int at = a[i + sa]; if (at >= 0) { - comb |= (GET_CGINFO_GID(in[at]) << (sa*bit_shift)); + comb |= (GET_CGINFO_GID(in[at]) << (sa * bit_shift)); } } innb[j++] = comb; @@ -933,9 +923,9 @@ static void copy_egp_to_nbat_egps(const int *a, int na, int na_round, } /* Set the energy group indices for atoms in nbnxn_atomdata_t */ -static void nbnxn_atomdata_set_energygroups(nbnxn_atomdata_t::Params *params, - const Nbnxm::GridSet &gridSet, - const int *atinfo) +static void nbnxn_atomdata_set_energygroups(nbnxn_atomdata_t::Params* params, + const Nbnxm::GridSet& gridSet, + const int* atinfo) { if (params->nenergrp == 1) { @@ -944,7 +934,7 @@ static void nbnxn_atomdata_set_energygroups(nbnxn_atomdata_t::Params *params, params->energrp.resize(gridSet.numGridAtomsTotal()); - for (const Nbnxm::Grid &grid : gridSet.grids()) + for (const Nbnxm::Grid& grid : gridSet.grids()) { /* Loop over all columns and copy and fill */ for (int i = 0; i < grid.numColumns(); i++) @@ -952,22 +942,20 @@ static void nbnxn_atomdata_set_energygroups(nbnxn_atomdata_t::Params *params, const int numAtoms = grid.paddedNumAtomsInColumn(i); const int atomOffset = grid.firstAtomInColumn(i); - copy_egp_to_nbat_egps(gridSet.atomIndices().data() + atomOffset, - grid.numAtomsInColumn(i), numAtoms, - c_nbnxnCpuIClusterSize, params->neg_2log, - atinfo, + copy_egp_to_nbat_egps(gridSet.atomIndices().data() + atomOffset, grid.numAtomsInColumn(i), + numAtoms, c_nbnxnCpuIClusterSize, params->neg_2log, atinfo, params->energrp.data() + grid.atomToCluster(atomOffset)); } } } /* Sets all required atom parameter data in nbnxn_atomdata_t */ -void nbnxn_atomdata_set(nbnxn_atomdata_t *nbat, - const Nbnxm::GridSet &gridSet, - const t_mdatoms *mdatoms, - const int *atinfo) +void nbnxn_atomdata_set(nbnxn_atomdata_t* nbat, + const Nbnxm::GridSet& gridSet, + const t_mdatoms* mdatoms, + const int* atinfo) { - nbnxn_atomdata_t::Params ¶ms = nbat->paramsDeprecated(); + nbnxn_atomdata_t::Params& params = nbat->paramsDeprecated(); nbnxn_atomdata_set_atomtypes(¶ms, gridSet, mdatoms->typeA); @@ -985,9 +973,7 @@ void nbnxn_atomdata_set(nbnxn_atomdata_t *nbat, } /* Copies the shift vector array to nbnxn_atomdata_t */ -void nbnxn_atomdata_copy_shiftvec(gmx_bool bDynamicBox, - rvec *shift_vec, - nbnxn_atomdata_t *nbat) +void nbnxn_atomdata_copy_shiftvec(gmx_bool bDynamicBox, rvec* shift_vec, nbnxn_atomdata_t* nbat) { int i; @@ -1000,10 +986,10 @@ void nbnxn_atomdata_copy_shiftvec(gmx_bool bDynamicBox, // This is slightly different from nbnxn_get_atom_range(...) at the end of the file // TODO: Combine if possible -static void getAtomRanges(const Nbnxm::GridSet &gridSet, - const gmx::AtomLocality locality, - int *gridBegin, - int *gridEnd) +static void getAtomRanges(const Nbnxm::GridSet& gridSet, + const gmx::AtomLocality locality, + int* gridBegin, + int* gridEnd) { switch (locality) { @@ -1026,11 +1012,11 @@ static void getAtomRanges(const Nbnxm::GridSet &gridSet, } /* Copies (and reorders) the coordinates to nbnxn_atomdata_t */ -void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet &gridSet, - const gmx::AtomLocality locality, - bool fillLocal, - const rvec *coordinates, - nbnxn_atomdata_t *nbat) +void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet& gridSet, + const gmx::AtomLocality locality, + bool fillLocal, + const rvec* coordinates, + nbnxn_atomdata_t* nbat) { int gridBegin = 0; @@ -1050,18 +1036,18 @@ void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet &gridSet, { for (int g = gridBegin; g < gridEnd; g++) { - const Nbnxm::Grid &grid = gridSet.grids()[g]; - const int numCellsXY = grid.numColumns(); + const Nbnxm::Grid& grid = gridSet.grids()[g]; + const int numCellsXY = grid.numColumns(); - const int cxy0 = (numCellsXY* th + nth - 1)/nth; - const int cxy1 = (numCellsXY*(th + 1) + nth - 1)/nth; + const int cxy0 = (numCellsXY * th + nth - 1) / nth; + const int cxy1 = (numCellsXY * (th + 1) + nth - 1) / nth; for (int cxy = cxy0; cxy < cxy1; cxy++) { const int na = grid.numAtomsInColumn(cxy); const int ash = grid.firstAtomInColumn(cxy); - int na_fill; + int na_fill; if (g == 0 && fillLocal) { na_fill = grid.paddedNumAtomsInColumn(cxy); @@ -1074,23 +1060,22 @@ void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet &gridSet, */ na_fill = na; } - copy_rvec_to_nbat_real(gridSet.atomIndices().data() + ash, - na, na_fill, coordinates, - nbat->XFormat, nbat->x().data(), ash); + copy_rvec_to_nbat_real(gridSet.atomIndices().data() + ash, na, na_fill, + coordinates, nbat->XFormat, nbat->x().data(), ash); } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* Copies (and reorders) the coordinates to nbnxn_atomdata_t on the GPU*/ -void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet &gridSet, - const gmx::AtomLocality locality, - bool fillLocal, - gmx_nbnxn_gpu_t *gpu_nbv, - DeviceBuffer d_x, - GpuEventSynchronizer *xReadyOnDevice) +void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet& gridSet, + const gmx::AtomLocality locality, + bool fillLocal, + gmx_nbnxn_gpu_t* gpu_nbv, + DeviceBuffer d_x, + GpuEventSynchronizer* xReadyOnDevice) { int gridBegin = 0; @@ -1099,20 +1084,12 @@ void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet &gridSet, for (int g = gridBegin; g < gridEnd; g++) { - nbnxn_gpu_x_to_nbat_x(gridSet.grids()[g], - fillLocal && g == 0, - gpu_nbv, - d_x, - xReadyOnDevice, - locality, - g, - gridSet.numColumnsMax()); + nbnxn_gpu_x_to_nbat_x(gridSet.grids()[g], fillLocal && g == 0, gpu_nbv, d_x, xReadyOnDevice, + locality, g, gridSet.numColumnsMax()); } } -static void -nbnxn_atomdata_clear_reals(gmx::ArrayRef dest, - int i0, int i1) +static void nbnxn_atomdata_clear_reals(gmx::ArrayRef dest, int i0, int i1) { for (int i = i0; i < i1; i++) { @@ -1120,12 +1097,12 @@ nbnxn_atomdata_clear_reals(gmx::ArrayRef dest, } } -gmx_unused static void -nbnxn_atomdata_reduce_reals(real * gmx_restrict dest, - gmx_bool bDestSet, - const real ** gmx_restrict src, - int nsrc, - int i0, int i1) +gmx_unused static void nbnxn_atomdata_reduce_reals(real* gmx_restrict dest, + gmx_bool bDestSet, + const real** gmx_restrict src, + int nsrc, + int i0, + int i1) { if (bDestSet) { @@ -1152,43 +1129,43 @@ nbnxn_atomdata_reduce_reals(real * gmx_restrict dest, } } -gmx_unused static void -nbnxn_atomdata_reduce_reals_simd(real gmx_unused * gmx_restrict dest, - gmx_bool gmx_unused bDestSet, - const gmx_unused real ** gmx_restrict src, - int gmx_unused nsrc, - int gmx_unused i0, int gmx_unused i1) +gmx_unused static void nbnxn_atomdata_reduce_reals_simd(real gmx_unused* gmx_restrict dest, + gmx_bool gmx_unused bDestSet, + const gmx_unused real** gmx_restrict src, + int gmx_unused nsrc, + int gmx_unused i0, + int gmx_unused i1) { #if GMX_SIMD -/* The SIMD width here is actually independent of that in the kernels, - * but we use the same width for simplicity (usually optimal anyhow). - */ + /* The SIMD width here is actually independent of that in the kernels, + * but we use the same width for simplicity (usually optimal anyhow). + */ SimdReal dest_SSE, src_SSE; if (bDestSet) { for (int i = i0; i < i1; i += GMX_SIMD_REAL_WIDTH) { - dest_SSE = load(dest+i); + dest_SSE = load(dest + i); for (int s = 0; s < nsrc; s++) { - src_SSE = load(src[s]+i); + src_SSE = load(src[s] + i); dest_SSE = dest_SSE + src_SSE; } - store(dest+i, dest_SSE); + store(dest + i, dest_SSE); } } else { for (int i = i0; i < i1; i += GMX_SIMD_REAL_WIDTH) { - dest_SSE = load(src[0]+i); + dest_SSE = load(src[0] + i); for (int s = 1; s < nsrc; s++) { - src_SSE = load(src[s]+i); + src_SSE = load(src[s] + i); dest_SSE = dest_SSE + src_SSE; } - store(dest+i, dest_SSE); + store(dest + i, dest_SSE); } } #endif @@ -1198,17 +1175,16 @@ nbnxn_atomdata_reduce_reals_simd(real gmx_unused * gmx_restrict dest, * * Note: Adding restrict to f makes this function 50% slower with gcc 7.3 */ -static void -nbnxn_atomdata_add_nbat_f_to_f_part(const Nbnxm::GridSet &gridSet, - const nbnxn_atomdata_t &nbat, - const nbnxn_atomdata_output_t &out, - const int a0, - const int a1, - rvec * f) +static void nbnxn_atomdata_add_nbat_f_to_f_part(const Nbnxm::GridSet& gridSet, + const nbnxn_atomdata_t& nbat, + const nbnxn_atomdata_output_t& out, + const int a0, + const int a1, + rvec* f) { - gmx::ArrayRef cell = gridSet.cells(); + gmx::ArrayRef cell = gridSet.cells(); // Note: Using ArrayRef instead makes this code 25% slower with gcc 7.3 - const real *fnb = out.f.data(); + const real* fnb = out.f.data(); /* Loop over all columns and copy and fill */ switch (nbat.FFormat) @@ -1217,7 +1193,7 @@ nbnxn_atomdata_add_nbat_f_to_f_part(const Nbnxm::GridSet &gridSet, case nbatXYZQ: for (int a = a0; a < a1; a++) { - int i = cell[a]*nbat.fstride; + int i = cell[a] * nbat.fstride; f[a][XX] += fnb[i]; f[a][YY] += fnb[i + 1]; @@ -1229,9 +1205,9 @@ nbnxn_atomdata_add_nbat_f_to_f_part(const Nbnxm::GridSet &gridSet, { int i = atom_to_x_index(cell[a]); - f[a][XX] += fnb[i + XX*c_packX4]; - f[a][YY] += fnb[i + YY*c_packX4]; - f[a][ZZ] += fnb[i + ZZ*c_packX4]; + f[a][XX] += fnb[i + XX * c_packX4]; + f[a][YY] += fnb[i + YY * c_packX4]; + f[a][ZZ] += fnb[i + ZZ * c_packX4]; } break; case nbatX8: @@ -1239,13 +1215,12 @@ nbnxn_atomdata_add_nbat_f_to_f_part(const Nbnxm::GridSet &gridSet, { int i = atom_to_x_index(cell[a]); - f[a][XX] += fnb[i + XX*c_packX8]; - f[a][YY] += fnb[i + YY*c_packX8]; - f[a][ZZ] += fnb[i + ZZ*c_packX8]; + f[a][XX] += fnb[i + XX * c_packX8]; + f[a][YY] += fnb[i + YY * c_packX8]; + f[a][ZZ] += fnb[i + ZZ * c_packX8]; } break; - default: - gmx_incons("Unsupported nbnxn_atomdata_t format"); + default: gmx_incons("Unsupported nbnxn_atomdata_t format"); } } @@ -1255,33 +1230,32 @@ static inline unsigned char reverse_bits(unsigned char b) return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; } -static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t *nbat, - int nth) +static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t* nbat, int nth) { - const nbnxn_buffer_flags_t *flags = &nbat->buffer_flags; + const nbnxn_buffer_flags_t* flags = &nbat->buffer_flags; - int next_pow2 = 1<<(gmx::log2I(nth-1)+1); + int next_pow2 = 1 << (gmx::log2I(nth - 1) + 1); - const int numOutputBuffers = nbat->out.size(); + const int numOutputBuffers = nbat->out.size(); GMX_ASSERT(numOutputBuffers == nth, "tree-reduce currently only works for numOutputBuffers==nth"); - memset(nbat->syncStep, 0, sizeof(*(nbat->syncStep))*nth); + memset(nbat->syncStep, 0, sizeof(*(nbat->syncStep)) * nth); #pragma omp parallel num_threads(nth) { try { - int b0, b1, b; - int i0, i1; - int group_size, th; + int b0, b1, b; + int i0, i1; + int group_size, th; th = gmx_omp_get_thread_num(); - for (group_size = 2; group_size < 2*next_pow2; group_size *= 2) + for (group_size = 2; group_size < 2 * next_pow2; group_size *= 2) { int index[2], group_pos, partner_pos, wu; - int partner_th = th ^ (group_size/2); + int partner_th = th ^ (group_size / 2); if (group_size > 2) { @@ -1289,33 +1263,35 @@ static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t *nbat, /* wait on partner thread - replaces full barrier */ int sync_th, sync_group_size; - tMPI_Atomic_memory_barrier(); /* gurantee data is saved before marking work as done */ - tMPI_Atomic_set(&(nbat->syncStep[th]), group_size/2); /* mark previous step as completed */ + tMPI_Atomic_memory_barrier(); /* gurantee data is saved before marking work as done */ + tMPI_Atomic_set(&(nbat->syncStep[th]), group_size / 2); /* mark previous step as completed */ /* find thread to sync with. Equal to partner_th unless nth is not a power of two. */ - for (sync_th = partner_th, sync_group_size = group_size; sync_th >= nth && sync_group_size > 2; sync_group_size /= 2) + for (sync_th = partner_th, sync_group_size = group_size; + sync_th >= nth && sync_group_size > 2; sync_group_size /= 2) { - sync_th &= ~(sync_group_size/4); + sync_th &= ~(sync_group_size / 4); } if (sync_th < nth) /* otherwise nothing to sync index[1] will be >=nout */ { /* wait on the thread which computed input data in previous step */ - while (tMPI_Atomic_get(static_cast(&(nbat->syncStep[sync_th]))) < group_size/2) + while (tMPI_Atomic_get(static_cast(&(nbat->syncStep[sync_th]))) + < group_size / 2) { gmx_pause(); } /* guarantee that no later load happens before wait loop is finisehd */ tMPI_Atomic_memory_barrier(); } -#else /* TMPI_ATOMICS */ -#pragma omp barrier +#else /* TMPI_ATOMICS */ +# pragma omp barrier #endif } /* Calculate buffers to sum (result goes into first buffer) */ group_pos = th % group_size; index[0] = th - group_pos; - index[1] = index[0] + group_size/2; + index[1] = index[0] + group_size / 2; /* If no second buffer, nothing to do */ if (index[1] >= numOutputBuffers && group_size > 2) @@ -1324,13 +1300,13 @@ static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t *nbat, } #if NBNXN_BUFFERFLAG_MAX_THREADS > 256 -#error reverse_bits assumes max 256 threads +# error reverse_bits assumes max 256 threads #endif /* Position is permuted so that one of the 2 vectors being added was computed on the same thread in the previous step. This improves locality and enables to sync with just a single thread between steps (=the levels in the btree). The permutation which allows this corresponds to reversing the bits of the group position. */ - group_pos = reverse_bits(group_pos)/(256/group_size); + group_pos = reverse_bits(group_pos) / (256 / group_size); partner_pos = group_pos ^ 1; @@ -1350,63 +1326,60 @@ static void nbnxn_atomdata_add_nbat_f_to_f_treereduce(nbnxn_atomdata_t *nbat, } /* Calculate the cell-block range for our thread */ - b0 = (flags->nflag* group_pos )/group_size; - b1 = (flags->nflag*(group_pos+1))/group_size; + b0 = (flags->nflag * group_pos) / group_size; + b1 = (flags->nflag * (group_pos + 1)) / group_size; for (b = b0; b < b1; b++) { - i0 = b *NBNXN_BUFFERFLAG_SIZE*nbat->fstride; - i1 = (b+1)*NBNXN_BUFFERFLAG_SIZE*nbat->fstride; + i0 = b * NBNXN_BUFFERFLAG_SIZE * nbat->fstride; + i1 = (b + 1) * NBNXN_BUFFERFLAG_SIZE * nbat->fstride; if (bitmask_is_set(flags->flag[b], index[1]) || group_size > 2) { - const real *fIndex1 = nbat->out[index[1]].f.data(); + const real* fIndex1 = nbat->out[index[1]].f.data(); #if GMX_SIMD nbnxn_atomdata_reduce_reals_simd #else nbnxn_atomdata_reduce_reals #endif - (nbat->out[index[0]].f.data(), - bitmask_is_set(flags->flag[b], index[0]) || group_size > 2, - &fIndex1, 1, i0, i1); - + (nbat->out[index[0]].f.data(), + bitmask_is_set(flags->flag[b], index[0]) || group_size > 2, + &fIndex1, 1, i0, i1); } else if (!bitmask_is_set(flags->flag[b], index[0])) { - nbnxn_atomdata_clear_reals(nbat->out[index[0]].f, - i0, i1); + nbnxn_atomdata_clear_reals(nbat->out[index[0]].f, i0, i1); } } } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } -static void nbnxn_atomdata_add_nbat_f_to_f_stdreduce(nbnxn_atomdata_t *nbat, - int nth) +static void nbnxn_atomdata_add_nbat_f_to_f_stdreduce(nbnxn_atomdata_t* nbat, int nth) { #pragma omp parallel for num_threads(nth) schedule(static) for (int th = 0; th < nth; th++) { try { - const nbnxn_buffer_flags_t *flags; + const nbnxn_buffer_flags_t* flags; int nfptr; - const real *fptr[NBNXN_BUFFERFLAG_MAX_THREADS]; + const real* fptr[NBNXN_BUFFERFLAG_MAX_THREADS]; flags = &nbat->buffer_flags; /* Calculate the cell-block range for our thread */ - int b0 = (flags->nflag* th )/nth; - int b1 = (flags->nflag*(th+1))/nth; + int b0 = (flags->nflag * th) / nth; + int b1 = (flags->nflag * (th + 1)) / nth; for (int b = b0; b < b1; b++) { - int i0 = b *NBNXN_BUFFERFLAG_SIZE*nbat->fstride; - int i1 = (b+1)*NBNXN_BUFFERFLAG_SIZE*nbat->fstride; + int i0 = b * NBNXN_BUFFERFLAG_SIZE * nbat->fstride; + int i1 = (b + 1) * NBNXN_BUFFERFLAG_SIZE * nbat->fstride; nfptr = 0; for (gmx::index out = 1; out < gmx::ssize(nbat->out); out++) @@ -1423,28 +1396,21 @@ static void nbnxn_atomdata_add_nbat_f_to_f_stdreduce(nbnxn_atomdata_t *nbat, #else nbnxn_atomdata_reduce_reals #endif - (nbat->out[0].f.data(), - bitmask_is_set(flags->flag[b], 0), - fptr, nfptr, - i0, i1); + (nbat->out[0].f.data(), bitmask_is_set(flags->flag[b], 0), fptr, nfptr, i0, i1); } else if (!bitmask_is_set(flags->flag[b], 0)) { - nbnxn_atomdata_clear_reals(nbat->out[0].f, - i0, i1); + nbnxn_atomdata_clear_reals(nbat->out[0].f, i0, i1); } } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* Add the force array(s) from nbnxn_atomdata_t to f */ -void reduceForces(nbnxn_atomdata_t *nbat, - const gmx::AtomLocality locality, - const Nbnxm::GridSet &gridSet, - rvec *f) +void reduceForces(nbnxn_atomdata_t* nbat, const gmx::AtomLocality locality, const Nbnxm::GridSet& gridSet, rvec* f) { int a0 = 0; int na = 0; @@ -1483,25 +1449,22 @@ void reduceForces(nbnxn_atomdata_t *nbat, { try { - nbnxn_atomdata_add_nbat_f_to_f_part(gridSet, *nbat, - nbat->out[0], - a0 + ((th + 0)*na)/nth, - a0 + ((th + 1)*na)/nth, - f); + nbnxn_atomdata_add_nbat_f_to_f_part(gridSet, *nbat, nbat->out[0], a0 + ((th + 0) * na) / nth, + a0 + ((th + 1) * na) / nth, f); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } /* Add the force array(s) from nbnxn_atomdata_t to f */ -void reduceForcesGpu(const gmx::AtomLocality locality, - DeviceBuffer totalForcesDevice, - const Nbnxm::GridSet &gridSet, - void *pmeForcesDevice, - gmx::ArrayRef dependencyList, - gmx_nbnxn_gpu_t *gpu_nbv, - bool useGpuFPmeReduction, - bool accumulateForce) +void reduceForcesGpu(const gmx::AtomLocality locality, + DeviceBuffer totalForcesDevice, + const Nbnxm::GridSet& gridSet, + void* pmeForcesDevice, + gmx::ArrayRef dependencyList, + gmx_nbnxn_gpu_t* gpu_nbv, + bool useGpuFPmeReduction, + bool accumulateForce) { int atomsStart = 0; int numAtoms = 0; @@ -1514,18 +1477,11 @@ void reduceForcesGpu(const gmx::AtomLocality locality, return; } - Nbnxm::nbnxn_gpu_add_nbat_f_to_f(locality, - totalForcesDevice, - gpu_nbv, - pmeForcesDevice, - dependencyList, - atomsStart, numAtoms, - useGpuFPmeReduction, - accumulateForce); + Nbnxm::nbnxn_gpu_add_nbat_f_to_f(locality, totalForcesDevice, gpu_nbv, pmeForcesDevice, dependencyList, + atomsStart, numAtoms, useGpuFPmeReduction, accumulateForce); } -void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t &nbat, - gmx::ArrayRef fshift) +void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t& nbat, gmx::ArrayRef fshift) { gmx::ArrayRef outputBuffers = nbat.out; @@ -1533,20 +1489,20 @@ void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t &nbat, { rvec sum; clear_rvec(sum); - for (const nbnxn_atomdata_output_t &out : outputBuffers) + for (const nbnxn_atomdata_output_t& out : outputBuffers) { - sum[XX] += out.fshift[s*DIM+XX]; - sum[YY] += out.fshift[s*DIM+YY]; - sum[ZZ] += out.fshift[s*DIM+ZZ]; + sum[XX] += out.fshift[s * DIM + XX]; + sum[YY] += out.fshift[s * DIM + YY]; + sum[ZZ] += out.fshift[s * DIM + ZZ]; } fshift[s] += sum; } } -void nbnxn_get_atom_range(const gmx::AtomLocality atomLocality, - const Nbnxm::GridSet &gridSet, - int *atomStart, - int *nAtoms) +void nbnxn_get_atom_range(const gmx::AtomLocality atomLocality, + const Nbnxm::GridSet& gridSet, + int* atomStart, + int* nAtoms) { switch (atomLocality) diff --git a/src/gromacs/nbnxm/atomdata.h b/src/gromacs/nbnxm/atomdata.h index d44d8ed9ef..1b1e3b763a 100644 --- a/src/gromacs/nbnxm/atomdata.h +++ b/src/gromacs/nbnxm/atomdata.h @@ -64,33 +64,38 @@ namespace Nbnxm { class GridSet; enum class KernelType; -} +} // namespace Nbnxm /* Convenience type for vector with aligned memory */ template -using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; +using AlignedVector = std::vector>; -enum { - nbatXYZ, nbatXYZQ, nbatX4, nbatX8 +enum +{ + nbatXYZ, + nbatXYZQ, + nbatX4, + nbatX8 }; //! Stride for coordinate/force arrays with xyz coordinate storage -static constexpr int STRIDE_XYZ = 3; +static constexpr int STRIDE_XYZ = 3; //! Stride for coordinate/force arrays with xyzq coordinate storage static constexpr int STRIDE_XYZQ = 4; //! Size of packs of x, y or z with SIMD 4-grouped packed coordinates/forces -static constexpr int c_packX4 = 4; +static constexpr int c_packX4 = 4; //! Size of packs of x, y or z with SIMD 8-grouped packed coordinates/forces -static constexpr int c_packX8 = 8; +static constexpr int c_packX8 = 8; //! Stridefor a pack of 4 coordinates/forces -static constexpr int STRIDE_P4 = DIM*c_packX4; +static constexpr int STRIDE_P4 = DIM * c_packX4; //! Stridefor a pack of 8 coordinates/forces -static constexpr int STRIDE_P8 = DIM*c_packX8; +static constexpr int STRIDE_P8 = DIM * c_packX8; //! Returns the index in a coordinate array corresponding to atom a -template static inline int atom_to_x_index(int a) +template +static inline int atom_to_x_index(int a) { - return DIM*(a & ~(packSize - 1)) + (a & (packSize - 1)); + return DIM * (a & ~(packSize - 1)) + (a & (packSize - 1)); } // Struct that holds force and energy output buffers @@ -123,26 +128,31 @@ struct nbnxn_atomdata_output_t * Currently the block size is NBNXN_BUFFERFLAG_SIZE*3*sizeof(real)=192 bytes. */ #if GMX_DOUBLE -#define NBNXN_BUFFERFLAG_SIZE 8 +# define NBNXN_BUFFERFLAG_SIZE 8 #else -#define NBNXN_BUFFERFLAG_SIZE 16 +# define NBNXN_BUFFERFLAG_SIZE 16 #endif /* We store the reduction flags as gmx_bitmask_t. * This limits the number of flags to BITMASK_SIZE. */ -#define NBNXN_BUFFERFLAG_MAX_THREADS (BITMASK_SIZE) +#define NBNXN_BUFFERFLAG_MAX_THREADS (BITMASK_SIZE) /* Flags for telling if threads write to force output buffers */ -typedef struct { - int nflag; /* The number of flag blocks */ - gmx_bitmask_t *flag; /* Bit i is set when thread i writes to a cell-block */ - int flag_nalloc; /* Allocation size of cxy_flag */ +typedef struct +{ + int nflag; /* The number of flag blocks */ + gmx_bitmask_t* flag; /* Bit i is set when thread i writes to a cell-block */ + int flag_nalloc; /* Allocation size of cxy_flag */ } nbnxn_buffer_flags_t; /* LJ combination rules: geometric, Lorentz-Berthelot, none */ -enum { - ljcrGEOM, ljcrLB, ljcrNONE, ljcrNR +enum +{ + ljcrGEOM, + ljcrLB, + ljcrNONE, + ljcrNR }; /* Struct that stores atom related data for the nbnxn module @@ -151,7 +161,7 @@ enum { * in this struct would not initialize during resize(). */ struct nbnxn_atomdata_t -{ //NOLINT(clang-analyzer-optin.performance.Padding) +{ //NOLINT(clang-analyzer-optin.performance.Padding) struct Params { /* Constructor @@ -161,27 +171,27 @@ struct nbnxn_atomdata_t Params(gmx::PinningPolicy pinningPolicy); // The number of different atom types - int numTypes; + int numTypes; // Lennard-Jone 6*C6 and 12*C12 parameters, size numTypes*2*2 gmx::HostVector nbfp; // Combination rule, see enum defined above - int comb_rule; + int comb_rule; // LJ parameters per atom type, size numTypes*2 gmx::HostVector nbfp_comb; // As nbfp, but with a stride for the present SIMD architecture - AlignedVector nbfp_aligned; + AlignedVector nbfp_aligned; // Atom types per atom - gmx::HostVector type; + gmx::HostVector type; // LJ parameters per atom for fast SIMD loading gmx::HostVector lj_comb; // Charges per atom, not set with format nbatXYZQ gmx::HostVector q; // The number of energy groups - int nenergrp; + int nenergrp; // 2log(nenergrp) - int neg_2log; + int neg_2log; // The energy groups, one int entry per cluster, only set when needed - gmx::HostVector energrp; + gmx::HostVector energrp; }; // Diagonal and topology exclusion helper data for all SIMD kernels @@ -190,15 +200,15 @@ struct nbnxn_atomdata_t SimdMasks(); // Helper data for setting up diagonal exclusion masks in the SIMD 4xN kernels - AlignedVector diagonal_4xn_j_minus_i; + AlignedVector diagonal_4xn_j_minus_i; // Helper data for setting up diaginal exclusion masks in the SIMD 2xNN kernels - AlignedVector diagonal_2xnn_j_minus_i; + AlignedVector diagonal_2xnn_j_minus_i; // Filters for topology exclusion masks for the SIMD kernels AlignedVector exclusion_filter; // Filters for topology exclusion masks for double SIMD kernels without SIMD int32 logical support AlignedVector exclusion_filter64; // Array of masks needed for exclusions - AlignedVector interaction_array; + AlignedVector interaction_array; }; /* Constructor @@ -208,34 +218,19 @@ struct nbnxn_atomdata_t nbnxn_atomdata_t(gmx::PinningPolicy pinningPolicy); /* Returns a const reference to the parameters */ - const Params ¶ms() const - { - return params_; - } + const Params& params() const { return params_; } /* Returns a non-const reference to the parameters */ - Params ¶msDeprecated() - { - return params_; - } + Params& paramsDeprecated() { return params_; } /* Returns the current total number of atoms stored */ - int numAtoms() const - { - return numAtoms_; - } + int numAtoms() const { return numAtoms_; } /* Return the coordinate buffer, and q with xFormat==nbatXYZQ */ - gmx::ArrayRef x() const - { - return x_; - } + gmx::ArrayRef x() const { return x_; } /* Return the coordinate buffer, and q with xFormat==nbatXYZQ */ - gmx::ArrayRef x() - { - return x_; - } + gmx::ArrayRef x() { return x_; } /* Resizes the coordinate buffer and sets the number of atoms */ void resizeCoordinateBuffer(int numAtoms); @@ -243,45 +238,48 @@ struct nbnxn_atomdata_t /* Resizes the force buffers for the current number of atoms */ void resizeForceBuffers(); - private: - // The LJ and charge parameters - Params params_; - // The total number of atoms currently stored - int numAtoms_; - public: - int natoms_local; /* Number of local atoms */ - int XFormat; /* The format of x (and q), enum */ - int FFormat; /* The format of f, enum */ - gmx_bool bDynamicBox; /* Do we need to update shift_vec every step? */ - gmx::HostVector shift_vec; /* Shift vectors, copied from t_forcerec */ - int xstride; /* stride for a coordinate in x (usually 3 or 4) */ - int fstride; /* stride for a coordinate in f (usually 3 or 4) */ - private: - gmx::HostVector x_; /* x and possibly q, size natoms*xstride */ - - public: - // Masks for handling exclusions in the SIMD kernels - const SimdMasks simdMasks; - - /* Output data */ - std::vector out; /* Output data structures, 1 per thread */ - - /* Reduction related data */ - gmx_bool bUseBufferFlags; /* Use the flags or operate on all atoms */ - nbnxn_buffer_flags_t buffer_flags; /* Flags for buffer zeroing+reduc. */ - gmx_bool bUseTreeReduce; /* Use tree for force reduction */ - tMPI_Atomic *syncStep; /* Synchronization step for tree reduce */ +private: + // The LJ and charge parameters + Params params_; + // The total number of atoms currently stored + int numAtoms_; + +public: + int natoms_local; /* Number of local atoms */ + int XFormat; /* The format of x (and q), enum */ + int FFormat; /* The format of f, enum */ + gmx_bool bDynamicBox; /* Do we need to update shift_vec every step? */ + gmx::HostVector shift_vec; /* Shift vectors, copied from t_forcerec */ + int xstride; /* stride for a coordinate in x (usually 3 or 4) */ + int fstride; /* stride for a coordinate in f (usually 3 or 4) */ +private: + gmx::HostVector x_; /* x and possibly q, size natoms*xstride */ + +public: + // Masks for handling exclusions in the SIMD kernels + const SimdMasks simdMasks; + + /* Output data */ + std::vector out; /* Output data structures, 1 per thread */ + + /* Reduction related data */ + gmx_bool bUseBufferFlags; /* Use the flags or operate on all atoms */ + nbnxn_buffer_flags_t buffer_flags; /* Flags for buffer zeroing+reduc. */ + gmx_bool bUseTreeReduce; /* Use tree for force reduction */ + tMPI_Atomic* syncStep; /* Synchronization step for tree reduce */ }; /* Copy na rvec elements from x to xnb using nbatFormat, start dest a0, * and fills up to na_round with coordinates that are far away. */ -void copy_rvec_to_nbat_real(const int *a, int na, int na_round, - const rvec *x, int nbatFormat, - real *xnb, int a0); +void copy_rvec_to_nbat_real(const int* a, int na, int na_round, const rvec* x, int nbatFormat, real* xnb, int a0); -enum { - enbnxninitcombruleDETECT, enbnxninitcombruleGEOM, enbnxninitcombruleLB, enbnxninitcombruleNONE +enum +{ + enbnxninitcombruleDETECT, + enbnxninitcombruleGEOM, + enbnxninitcombruleLB, + enbnxninitcombruleNONE }; /* Initialize the non-bonded atom data structure. @@ -290,23 +288,22 @@ enum { * to the atom data structure. * enbnxninitcombrule sets what combination rule data gets stored in nbat. */ -void nbnxn_atomdata_init(const gmx::MDLogger &mdlog, - nbnxn_atomdata_t *nbat, - Nbnxm::KernelType kernelType, - int enbnxninitcombrule, - int ntype, const real *nbfp, - int n_energygroups, - int nout); - -void nbnxn_atomdata_set(nbnxn_atomdata_t *nbat, - const Nbnxm::GridSet &gridSet, - const t_mdatoms *mdatoms, - const int *atinfo); +void nbnxn_atomdata_init(const gmx::MDLogger& mdlog, + nbnxn_atomdata_t* nbat, + Nbnxm::KernelType kernelType, + int enbnxninitcombrule, + int ntype, + const real* nbfp, + int n_energygroups, + int nout); + +void nbnxn_atomdata_set(nbnxn_atomdata_t* nbat, + const Nbnxm::GridSet& gridSet, + const t_mdatoms* mdatoms, + const int* atinfo); /* Copy the shift vectors to nbat */ -void nbnxn_atomdata_copy_shiftvec(gmx_bool dynamic_box, - rvec *shift_vec, - nbnxn_atomdata_t *nbat); +void nbnxn_atomdata_copy_shiftvec(gmx_bool dynamic_box, rvec* shift_vec, nbnxn_atomdata_t* nbat); /*! \brief Transform coordinates to xbat layout * @@ -318,11 +315,11 @@ void nbnxn_atomdata_copy_shiftvec(gmx_bool dynamic_box, * \param[in] coordinates Coordinates in plain rvec format. * \param[in,out] nbat Data in NBNXM format, used for mapping formats and to locate the output buffer. */ -void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet &gridSet, - gmx::AtomLocality locality, - bool fillLocal, - const rvec *coordinates, - nbnxn_atomdata_t *nbat); +void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet& gridSet, + gmx::AtomLocality locality, + bool fillLocal, + const rvec* coordinates, + nbnxn_atomdata_t* nbat); /*! \brief Transform coordinates to xbat layout on GPU * @@ -336,12 +333,12 @@ void nbnxn_atomdata_copy_x_to_nbat_x(const Nbnxm::GridSet &gridSet, * \param[in] d_x Coordinates to be copied (in plain rvec format). * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory. */ -void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet &gridSet, - gmx::AtomLocality locality, - bool fillLocal, - gmx_nbnxn_gpu_t *gpu_nbv, - DeviceBuffer d_x, - GpuEventSynchronizer *xReadyOnDevice); +void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet& gridSet, + gmx::AtomLocality locality, + bool fillLocal, + gmx_nbnxn_gpu_t* gpu_nbv, + DeviceBuffer d_x, + GpuEventSynchronizer* xReadyOnDevice); /*! \brief Add the computed forces to \p f, an internal reduction might be performed as well * @@ -350,10 +347,7 @@ void nbnxn_atomdata_x_to_nbat_x_gpu(const Nbnxm::GridSet &gridSet, * \param[in] gridSet The grids data. * \param[out] totalForce Buffer to accumulate resulting force */ -void reduceForces(nbnxn_atomdata_t *nbat, - gmx::AtomLocality locality, - const Nbnxm::GridSet &gridSet, - rvec *totalForce); +void reduceForces(nbnxn_atomdata_t* nbat, gmx::AtomLocality locality, const Nbnxm::GridSet& gridSet, rvec* totalForce); /*! \brief Reduce forces on the GPU * @@ -366,22 +360,21 @@ void reduceForces(nbnxn_atomdata_t *nbat, * \param[in] useGpuFPmeReduction Whether PME forces should be added. * \param[in] accumulateForce Whether there are usefull data already in the total force buffer. */ -void reduceForcesGpu(gmx::AtomLocality locality, - DeviceBuffer totalForcesDevice, - const Nbnxm::GridSet &gridSet, - void *pmeForcesDevice, - gmx::ArrayRef dependencyList, - gmx_nbnxn_gpu_t *gpu_nbv, - bool useGpuFPmeReduction, - bool accumulateForce); +void reduceForcesGpu(gmx::AtomLocality locality, + DeviceBuffer totalForcesDevice, + const Nbnxm::GridSet& gridSet, + void* pmeForcesDevice, + gmx::ArrayRef dependencyList, + gmx_nbnxn_gpu_t* gpu_nbv, + bool useGpuFPmeReduction, + bool accumulateForce); /* Add the fshift force stored in nbat to fshift */ -void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t &nbat, - gmx::ArrayRef fshift); +void nbnxn_atomdata_add_nbat_fshift_to_fshift(const nbnxn_atomdata_t& nbat, gmx::ArrayRef fshift); /* Get the atom start index and number of atoms for a given locality */ -void nbnxn_get_atom_range(gmx::AtomLocality atomLocality, - const Nbnxm::GridSet &gridSet, - int *atomStart, - int *nAtoms); +void nbnxn_get_atom_range(gmx::AtomLocality atomLocality, + const Nbnxm::GridSet& gridSet, + int* atomStart, + int* nAtoms); #endif diff --git a/src/gromacs/nbnxm/benchmark/bench_coords.h b/src/gromacs/nbnxm/benchmark/bench_coords.h index bf1a16ce48..3410bcc1d7 100644 --- a/src/gromacs/nbnxm/benchmark/bench_coords.h +++ b/src/gromacs/nbnxm/benchmark/bench_coords.h @@ -46,3014 +46,1508 @@ #include "gromacs/math/vec.h" //! A cubic simulation box matching coordinates1000 defined below -static const matrix box1000 = -{ - { 3.107360, 0.0, 0.0 }, - { 0.0, 3.107360, 0.0 }, - { 0.0, 0.0, 3.107360 } -}; +static const matrix box1000 = { { 3.107360, 0.0, 0.0 }, { 0.0, 3.107360, 0.0 }, { 0.0, 0.0, 3.107360 } }; //! Coordinates of 1000 SPC/E molecules equilibrated at 300 K, 1 bar, LJ cut-off 1 nm -static const std::vector coordinates1000 = -{ - { 3.058441, 1.962230, 1.989683 }, - { 2.975840, 1.980085, 1.936221 }, - { 3.122664, 2.038002, 1.978114 }, - { 2.511969, 0.591980, 0.611700 }, - { 2.600885, 0.614626, 0.651463 }, - { 2.439189, 0.625060, 0.671774 }, - { 3.037115, 1.103423, 0.510358 }, - { 3.075596, 1.113280, 0.602129 }, - { 3.094188, 1.041190, 0.456788 }, - { 0.625031, 2.325809, 2.735173 }, - { 0.572419, 2.273776, 2.802438 }, - { 0.697119, 2.267854, 2.697168 }, - { 1.631749, 0.888913, 1.089352 }, - { 1.722932, 0.929772, 1.085316 }, - { 1.639399, 0.792924, 1.116324 }, - { 0.135367, 0.404389, 0.014781 }, - { 0.123013, 0.353549, -0.070440 }, - { 0.065358, 0.475464, 0.021644 }, - { 2.133195, 1.942149, 1.063163 }, - { 2.103670, 1.932198, 1.158185 }, - { 2.057370, 1.977206, 1.008194 }, - { 0.974812, 1.273100, 2.779850 }, - { 0.977014, 1.306597, 2.874047 }, - { 0.914936, 1.331539, 2.725080 }, - { 3.039257, 2.275091, 2.297507 }, - { 3.077036, 2.367559, 2.292780 }, - { 2.939914, 2.279080, 2.286772 }, - { 3.066429, 1.655573, 0.946745 }, - { 2.988511, 1.717413, 0.956967 }, - { 3.146125, 1.694443, 0.992980 }, - { 2.402943, 1.159655, 1.041159 }, - { 2.457788, 1.113902, 0.971169 }, - { 2.463494, 1.202601, 1.108161 }, - { 0.198771, 2.872936, 2.409695 }, - { 0.230047, 2.782781, 2.439593 }, - { 0.105151, 2.887969, 2.441464 }, - { 0.368974, 0.573758, 2.697072 }, - { 0.309036, 0.494602, 2.708979 }, - { 0.372528, 0.598619, 2.600277 }, - { 0.780393, 2.245371, 0.386869 }, - { 0.696219, 2.230132, 0.335076 }, - { 0.803298, 2.342700, 0.385368 }, - { 1.288811, 0.315362, 0.649111 }, - { 1.337870, 0.256502, 0.713366 }, - { 1.213238, 0.264277, 0.608136 }, - { 2.939084, 1.486800, 0.541567 }, - { 2.999762, 1.475771, 0.462849 }, - { 2.860697, 1.543197, 0.515590 }, - { 1.700513, 1.987843, 0.690324 }, - { 1.683709, 2.077665, 0.649708 }, - { 1.624542, 1.963847, 0.750761 }, - { 2.002822, 0.880025, 2.162986 }, - { 1.904598, 0.881033, 2.144248 }, - { 2.021988, 0.936233, 2.243442 }, - { 1.419121, 1.568915, 3.023597 }, - { 1.499351, 1.625145, 3.043628 }, - { 1.448466, 1.476567, 2.998884 }, - { 1.659223, 2.063895, 0.003451 }, - { 1.721702, 2.003487, 0.052920 }, - { 1.585788, 2.009680, -0.037391 }, - { 0.932668, 0.985297, 2.066137 }, - { 0.841309, 1.019847, 2.087582 }, - { 0.925293, 0.909652, 2.001149 }, - { 2.544425, 2.069147, 0.358217 }, - { 2.569305, 2.158265, 0.396151 }, - { 2.491877, 2.017600, 0.425905 }, - { 2.643055, 0.627143, 1.977899 }, - { 2.728804, 0.579992, 1.957311 }, - { 2.593018, 0.643929, 1.892961 }, - { 2.525198, 2.511291, 0.851458 }, - { 2.548718, 2.560892, 0.935043 }, - { 2.585276, 2.431939, 0.841761 }, - { 1.593863, 1.272151, 1.144316 }, - { 1.641930, 1.220443, 1.073494 }, - { 1.595331, 1.220620, 1.230004 }, - { 0.241304, 1.026247, 1.527110 }, - { 0.314388, 1.092000, 1.545424 }, - { 0.153979, 1.074500, 1.520328 }, - { 0.670527, 2.411080, 0.740280 }, - { 0.743415, 2.366956, 0.792629 }, - { 0.616596, 2.341413, 0.692972 }, - { 0.506075, 0.784227, 0.136559 }, - { 0.468598, 0.695519, 0.109607 }, - { 0.557918, 0.823051, 0.060368 }, - { 2.820775, 2.815071, 1.889172 }, - { 2.815770, 2.751934, 1.811786 }, - { 2.765318, 2.896000, 1.869805 }, - { 0.987299, 2.128997, 0.524538 }, - { 1.040313, 2.207735, 0.556000 }, - { 0.919566, 2.159089, 0.457407 }, - { 0.229879, 0.835755, 1.940027 }, - { 0.167288, 0.879689, 2.004464 }, - { 0.180058, 0.767698, 1.886303 }, - { 0.378771, 0.998110, 0.493601 }, - { 0.339751, 0.957631, 0.576299 }, - { 0.466309, 0.954303, 0.473154 }, - { 2.123415, 1.896470, 2.510045 }, - { 2.077036, 1.955502, 2.443983 }, - { 2.089467, 1.802874, 2.500702 }, - { 1.588236, 2.328677, 1.511384 }, - { 1.576339, 2.284743, 1.600425 }, - { 1.526922, 2.407382, 1.504588 }, - { 0.580119, 2.671499, 1.778415 }, - { 0.516760, 2.699374, 1.706245 }, - { 0.573680, 2.735504, 1.854978 }, - { 0.236329, 1.658599, 0.482922 }, - { 0.173161, 1.716011, 0.535014 }, - { 0.216351, 1.562272, 0.500868 }, - { 2.866907, 2.172310, 0.976553 }, - { 2.911961, 2.101637, 0.922006 }, - { 2.932579, 2.244494, 0.998384 }, - { 2.765681, 2.315028, 2.427439 }, - { 2.832893, 2.283105, 2.494248 }, - { 2.712988, 2.237172, 2.393353 }, - { 0.705927, 2.118901, 1.945963 }, - { 0.721405, 2.171561, 1.862373 }, - { 0.770568, 2.148338, 2.016355 }, - { 1.781326, 0.167158, 0.154133 }, - { 1.802628, 0.096981, 0.222114 }, - { 1.746708, 0.123639, 0.071021 }, - { 0.126723, 1.501790, 2.733301 }, - { 0.156993, 1.595659, 2.716802 }, - { 0.203411, 1.439118, 2.719470 }, - { 0.870069, 0.129573, 0.216301 }, - { 0.862810, 0.197557, 0.143326 }, - { 0.959244, 0.084607, 0.211220 }, - { 1.070536, 0.743136, 0.182829 }, - { 1.013762, 0.666505, 0.152757 }, - { 1.166809, 0.716182, 0.180608 }, - { 0.440991, 3.021278, 2.594643 }, - { 0.439645, 3.047789, 2.498230 }, - { 0.532720, 2.990050, 2.619351 }, - { 2.742220, 2.873495, 2.785948 }, - { 2.707374, 2.780469, 2.774456 }, - { 2.683663, 2.937420, 2.736102 }, - { 0.713098, 1.865958, 0.712284 }, - { 0.624328, 1.911507, 0.705575 }, - { 0.712267, 1.802542, 0.789600 }, - { 0.314657, 0.447043, 0.721110 }, - { 0.350251, 0.534830, 0.689071 }, - { 0.357799, 0.372848, 0.669789 }, - { 2.969682, 2.658620, 2.862492 }, - { 2.984106, 2.745657, 2.909572 }, - { 2.871682, 2.639454, 2.857144 }, - { 1.198561, 2.913779, 2.614820 }, - { 1.150109, 2.838385, 2.659182 }, - { 1.132291, 2.976540, 2.573961 }, - { 2.641875, 1.268461, 1.491413 }, - { 2.633864, 1.233835, 1.584884 }, - { 2.682652, 1.359754, 1.493064 }, - { 0.568633, 0.009039, 1.190356 }, - { 0.651953, 0.059866, 1.212135 }, - { 0.490931, 0.071934, 1.187777 }, - { 2.645675, 1.030926, 1.996264 }, - { 2.656484, 1.127034, 2.021689 }, - { 2.689366, 0.973100, 2.065165 }, - { 0.077218, 2.967854, 2.133322 }, - { 0.044197, 3.062070, 2.127588 }, - { 0.131490, 2.956560, 2.216550 }, - { 0.408365, 1.237271, 1.580670 }, - { 0.474287, 1.284063, 1.639532 }, - { 0.359054, 1.304681, 1.525676 }, - { 0.226492, 1.945573, 0.076363 }, - { 0.261322, 1.853437, 0.059106 }, - { 0.171768, 1.975692, -0.001728 }, - { 0.468126, 2.450245, 2.524287 }, - { 0.486194, 2.415823, 2.616421 }, - { 0.526489, 2.402303, 2.458749 }, - { 1.434546, 2.964952, 2.504450 }, - { 1.477884, 3.052850, 2.524343 }, - { 1.336295, 2.971528, 2.521873 }, - { 1.464730, 0.522293, 0.985985 }, - { 1.526258, 0.561016, 0.917320 }, - { 1.461514, 0.422887, 0.975592 }, - { 1.630397, 2.791382, 2.590973 }, - { 1.601935, 2.722126, 2.657257 }, - { 1.554965, 2.854999, 2.574763 }, - { 1.972387, 0.963775, 2.902179 }, - { 2.029530, 1.043059, 2.923363 }, - { 1.969130, 0.950549, 2.803111 }, - { 2.337723, 0.321846, 0.882555 }, - { 2.314325, 0.235026, 0.926315 }, - { 2.435069, 0.340610, 0.895658 }, - { 0.734798, 1.529859, 3.053034 }, - { 0.713380, 1.615060, 3.100805 }, - { 0.672452, 1.457908, 3.083628 }, - { 0.032173, 0.527923, 2.239826 }, - { 0.027814, 0.477786, 2.326239 }, - { -0.054207, 0.517106, 2.190617 }, - { 0.022851, 1.802543, 0.630916 }, - { -0.015108, 1.813262, 0.539024 }, - { -0.037014, 1.847556, 0.697172 }, - { 1.010410, 0.509648, 2.039333 }, - { 1.003466, 0.551298, 2.129981 }, - { 1.093583, 0.454356, 2.034335 }, - { 2.898570, 2.091456, 1.807118 }, - { 2.854734, 2.046376, 1.729360 }, - { 2.829335, 2.138791, 1.861577 }, - { 1.961915, 1.375020, 2.801540 }, - { 1.948970, 1.298617, 2.738333 }, - { 1.941740, 1.460950, 2.754540 }, - { 0.290337, 0.199516, 2.503690 }, - { 0.291054, 0.257287, 2.422069 }, - { 0.327554, 0.250724, 2.581102 }, - { 2.077703, 0.143438, 0.468608 }, - { 2.065651, 0.217401, 0.402395 }, - { 2.171157, 0.145407, 0.504141 }, - { 0.990673, 2.712908, 0.856622 }, - { 0.895723, 2.743789, 0.851057 }, - { 1.037275, 2.761569, 0.930516 }, - { 0.078677, 1.380516, 1.009080 }, - { 0.029933, 1.464352, 1.033485 }, - { 0.162256, 1.403821, 0.959367 }, - { 1.836054, 2.642598, 1.704376 }, - { 1.795981, 2.597778, 1.624468 }, - { 1.913014, 2.588291, 1.737959 }, - { 0.257482, 0.992506, 1.247093 }, - { 0.281524, 1.086213, 1.221773 }, - { 0.267620, 0.981034, 1.345914 }, - { 1.986510, 2.050284, 0.848145 }, - { 1.991489, 2.078718, 0.752402 }, - { 1.906061, 1.992431, 0.861596 }, - { 0.384118, 3.016757, 0.633530 }, - { 0.365374, 2.938621, 0.574004 }, - { 0.379431, 2.987730, 0.729109 }, - { 1.061282, 2.803301, 1.113124 }, - { 1.140678, 2.799514, 1.173803 }, - { 0.982344, 2.762423, 1.158925 }, - { 0.893588, 0.623562, 1.159613 }, - { 0.935464, 0.532797, 1.156770 }, - { 0.961163, 0.692300, 1.132990 }, - { 0.064641, 1.597101, 1.338713 }, - { 0.089583, 1.650727, 1.258077 }, - { 0.000262, 1.525261, 1.312362 }, - { 1.744692, 2.999075, 2.729173 }, - { 1.711603, 2.931172, 2.663642 }, - { 1.732436, 2.964397, 2.822163 }, - { 1.010117, 1.010223, 2.690790 }, - { 1.003234, 1.103514, 2.726136 }, - { 1.005616, 0.945370, 2.766776 }, - { 2.119029, 2.091893, 2.142070 }, - { 2.053933, 2.055051, 2.208442 }, - { 2.069727, 2.144103, 2.072475 }, - { 0.476711, 0.278280, 2.980274 }, - { 0.398589, 0.239525, 2.931336 }, - { 0.546481, 0.207756, 2.992862 }, - { 1.017548, 1.173820, 0.262341 }, - { 0.930974, 1.150575, 0.306663 }, - { 1.038587, 1.270192, 0.278769 }, - { 3.006009, 2.653507, 0.115338 }, - { 3.070976, 2.729519, 0.116520 }, - { 2.913460, 2.688961, 0.102011 }, - { 0.321159, 1.479760, 1.402806 }, - { 0.401871, 1.536967, 1.417403 }, - { 0.240644, 1.537977, 1.391482 }, - { 1.629104, 2.275881, 0.958820 }, - { 1.558865, 2.324456, 1.010849 }, - { 1.624176, 2.178136, 0.979354 }, - { 3.066126, 2.858316, 1.644953 }, - { 3.084059, 2.953924, 1.668140 }, - { 3.146678, 2.803116, 1.666501 }, - { 1.051189, 2.076017, 1.920453 }, - { 1.125807, 2.103292, 1.859722 }, - { 0.969998, 2.130757, 1.900170 }, - { 1.516509, 0.100229, 0.350171 }, - { 1.560545, 0.020237, 0.309401 }, - { 1.431952, 0.120519, 0.300791 }, - { 0.493363, 2.189335, 1.269427 }, - { 0.521529, 2.285282, 1.270284 }, - { 0.404068, 2.180412, 1.313548 }, - { 2.807439, 1.983481, 1.563125 }, - { 2.768178, 2.068799, 1.528782 }, - { 2.841332, 1.929104, 1.486351 }, - { 2.853076, 0.830733, 1.400601 }, - { 2.899426, 0.745984, 1.374732 }, - { 2.909799, 0.908954, 1.374833 }, - { 2.959505, 0.005017, 0.423243 }, - { 2.864585, 0.013417, 0.453569 }, - { 3.007911, 0.090678, 0.441104 }, - { 2.807480, 1.919990, 2.908606 }, - { 2.827273, 1.955044, 2.817067 }, - { 2.804816, 1.820055, 2.906175 }, - { 0.082000, 0.549511, 1.184398 }, - { 0.156887, 0.615066, 1.174679 }, - { 0.106704, 0.463752, 1.139285 }, - { 0.629631, 0.003336, 1.945927 }, - { 0.544066, -0.015054, 1.897548 }, - { 0.670653, 0.087312, 1.910356 }, - { 1.183012, 0.907457, 0.474085 }, - { 1.250390, 0.969782, 0.434387 }, - { 1.156401, 0.839314, 0.405907 }, - { 3.032287, 0.465330, 0.292632 }, - { 3.062801, 0.530277, 0.222984 }, - { 3.089603, 0.474409, 0.374072 }, - { 2.243416, 0.013336, 2.312642 }, - { 2.250096, 0.111913, 2.328068 }, - { 2.159889, -0.021479, 2.355200 }, - { 1.164546, 0.173416, 1.168458 }, - { 1.104884, 0.099010, 1.138385 }, - { 1.206309, 0.149320, 1.256066 }, - { 2.607532, 1.124091, 1.724250 }, - { 2.622452, 1.052768, 1.655763 }, - { 2.656772, 1.100643, 1.808069 }, - { 2.551467, 1.338625, 1.208755 }, - { 2.583643, 1.301105, 1.295686 }, - { 2.619725, 1.402104, 1.172543 }, - { 2.136262, 1.322655, 0.114168 }, - { 2.208042, 1.328919, 0.183511 }, - { 2.092568, 1.411940, 0.103260 }, - { 0.941991, 1.920726, 2.868290 }, - { 0.939600, 1.894556, 2.964776 }, - { 0.851093, 1.908966, 2.828299 }, - { 0.004144, 1.775721, 2.412374 }, - { -0.041340, 1.699791, 2.365836 }, - { -0.012548, 1.860487, 2.362015 }, - { 0.867448, 0.363037, 0.498578 }, - { 0.800322, 0.437082, 0.501957 }, - { 0.953402, 0.397657, 0.460984 }, - { 0.890184, 0.676760, 1.539212 }, - { 0.935641, 0.621324, 1.608930 }, - { 0.824962, 0.738580, 1.583080 }, - { 2.539177, 1.282032, 3.012743 }, - { 2.501141, 1.363299, 2.968595 }, - { 2.610318, 1.309461, 3.077447 }, - { 1.604518, 1.894267, 1.505941 }, - { 1.686555, 1.935396, 1.545670 }, - { 1.617543, 1.795488, 1.497399 }, - { 2.913814, 2.506912, 1.298808 }, - { 2.839748, 2.479654, 1.237398 }, - { 2.888555, 2.485341, 1.393130 }, - { 2.479043, 2.811393, 0.464821 }, - { 2.461245, 2.785192, 0.369970 }, - { 2.480291, 2.729592, 0.522328 }, - { 0.000418, 2.908271, 0.684488 }, - { 0.052322, 2.991863, 0.666647 }, - { 0.048874, 2.852730, 0.752070 }, - { 2.420592, 0.017713, 1.710805 }, - { 2.390744, 0.098744, 1.761235 }, - { 2.369678, 0.011235, 1.624981 }, - { 2.926354, 2.206255, 0.118647 }, - { 3.026107, 2.212509, 0.115431 }, - { 2.891067, 2.188804, 0.026722 }, - { 3.083248, 0.397414, 1.498830 }, - { 3.094998, 0.418032, 1.595973 }, - { 3.110143, 0.302695, 1.481366 }, - { 1.151128, 1.570859, 1.066268 }, - { 1.137265, 1.624490, 0.983012 }, - { 1.236225, 1.518892, 1.058662 }, - { 2.100275, 0.308399, 0.082371 }, - { 2.063669, 0.215716, 0.074010 }, - { 2.068801, 0.349058, 0.168139 }, - { 2.089025, 0.726449, 2.710428 }, - { 2.158632, 0.687899, 2.649858 }, - { 2.125094, 0.731738, 2.803546 }, - { 1.069548, 0.219822, 2.643919 }, - { 1.155804, 0.212609, 2.593841 }, - { 1.069971, 0.303144, 2.699212 }, - { 0.215623, 1.771402, 2.733978 }, - { 0.116525, 1.780547, 2.724178 }, - { 0.259711, 1.857516, 2.708670 }, - { 0.076321, 2.814589, 0.017922 }, - { 0.153935, 2.798606, -0.043074 }, - { -0.004197, 2.838785, -0.036221 }, - { 0.827608, 0.266569, 2.523361 }, - { 0.924521, 0.255060, 2.545165 }, - { 0.782806, 0.317778, 2.596643 }, - { 1.774364, 1.200772, 0.922419 }, - { 1.847724, 1.268283, 0.914643 }, - { 1.699914, 1.225138, 0.860262 }, - { 1.843738, 0.863281, 1.426679 }, - { 1.835180, 0.960574, 1.448143 }, - { 1.909114, 0.820935, 1.489391 }, - { 2.190590, 2.093015, 0.489172 }, - { 2.114286, 2.129196, 0.542731 }, - { 2.168165, 2.097687, 0.391831 }, - { 2.856985, 2.708571, 2.421630 }, - { 2.826059, 2.637500, 2.358445 }, - { 2.940505, 2.678308, 2.467548 }, - { 0.701585, 1.132874, 1.532032 }, - { 0.713505, 1.046958, 1.581796 }, - { 0.636137, 1.190763, 1.580667 }, - { 1.112152, 1.761410, 2.730896 }, - { 1.032952, 1.800466, 2.777823 }, - { 1.183341, 1.740039, 2.797795 }, - { 2.362848, 0.400039, 0.467593 }, - { 2.413963, 0.451503, 0.536431 }, - { 2.364750, 0.449557, 0.380735 }, - { 1.923021, 2.539071, 1.210065 }, - { 2.005782, 2.500150, 1.250510 }, - { 1.911843, 2.504236, 1.116997 }, - { 2.843027, 2.693089, 1.659378 }, - { 2.914984, 2.761898, 1.668726 }, - { 2.770508, 2.728503, 1.600329 }, - { 0.128262, 0.810566, 1.667570 }, - { 0.116881, 0.757626, 1.583499 }, - { 0.142354, 0.906881, 1.644662 }, - { 1.002980, 0.859088, 2.952428 }, - { 0.921072, 0.801826, 2.948964 }, - { 0.978573, 0.950206, 2.985621 }, - { 0.665071, 1.176651, 0.745782 }, - { 0.572750, 1.214473, 0.752595 }, - { 0.662264, 1.078374, 0.764052 }, - { 1.604419, 2.998470, 1.830186 }, - { 1.578196, 3.085323, 1.872245 }, - { 1.699378, 3.003726, 1.799281 }, - { 0.766206, 2.635236, 2.266948 }, - { 0.669570, 2.646575, 2.290034 }, - { 0.821969, 2.650297, 2.348579 }, - { 0.413167, 1.864376, 1.358930 }, - { 0.436077, 1.767159, 1.354041 }, - { 0.368949, 1.883842, 1.446484 }, - { 2.520023, 2.005269, 2.712810 }, - { 2.491840, 2.040054, 2.802229 }, - { 2.615839, 2.028833, 2.696563 }, - { 0.653971, 0.523083, 2.191540 }, - { 0.655081, 0.426122, 2.215980 }, - { 0.648901, 0.532338, 2.092098 }, - { 2.064821, 2.995576, 1.899338 }, - { 2.000715, 2.961996, 1.968351 }, - { 2.148348, 3.027455, 1.944135 }, - { 0.974837, 3.040805, 0.756885 }, - { 0.947137, 2.957808, 0.708467 }, - { 0.934946, 3.120620, 0.711736 }, - { 2.444642, 2.518796, 2.408258 }, - { 2.440402, 2.457240, 2.486953 }, - { 2.370887, 2.586034, 2.414519 }, - { 2.321767, 1.107241, 2.328455 }, - { 2.385756, 1.168742, 2.374533 }, - { 2.229778, 1.121331, 2.365052 }, - { 1.605816, 0.704012, 0.201441 }, - { 1.679042, 0.692486, 0.134321 }, - { 1.642942, 0.745578, 0.284471 }, - { 1.552828, 1.036090, 1.319262 }, - { 1.570254, 0.975950, 1.241290 }, - { 1.462357, 1.016354, 1.357017 }, - { 3.106174, 0.095841, 1.468391 }, - { 3.169836, 0.054846, 1.403072 }, - { 3.016178, 0.105234, 1.425817 }, - { 1.471106, 2.572710, 1.544631 }, - { 1.503995, 2.624378, 1.465582 }, - { 1.425647, 2.634814, 1.608479 }, - { 2.479549, 1.837065, 1.139527 }, - { 2.433902, 1.811477, 1.224742 }, - { 2.578245, 1.842147, 1.154804 }, - { 2.285594, 0.997748, 2.811664 }, - { 2.337996, 0.950786, 2.882718 }, - { 2.230949, 1.070507, 2.853138 }, - { 2.069438, 2.790248, 2.236690 }, - { 2.128149, 2.745234, 2.169408 }, - { 2.071366, 2.738737, 2.322380 }, - { 2.405399, 0.905125, 1.347911 }, - { 2.447368, 0.898610, 1.438443 }, - { 2.346844, 0.986097, 1.344063 }, - { 2.196427, 0.438752, 2.136470 }, - { 2.192188, 0.376343, 2.214491 }, - { 2.290922, 0.445799, 2.104517 }, - { 2.889807, 0.531760, 1.366584 }, - { 2.900943, 0.497848, 1.273171 }, - { 2.958704, 0.489830, 1.425704 }, - { 1.841082, 3.042295, 1.732903 }, - { 1.861475, 3.126049, 1.682215 }, - { 1.919077, 3.018546, 1.790806 }, - { 1.326290, 2.104904, 0.154356 }, - { 1.358661, 2.045197, 0.080959 }, - { 1.312102, 2.050989, 0.237373 }, - { 3.049543, 1.131760, 2.722415 }, - { 2.996461, 1.169327, 2.646448 }, - { 3.132666, 1.088896, 2.687015 }, - { 1.908184, 0.043121, 0.967115 }, - { 1.972116, 0.062905, 1.041420 }, - { 1.957530, 0.041801, 0.880148 }, - { 2.401901, 0.513585, 1.491280 }, - { 2.427890, 0.425841, 1.450961 }, - { 2.344707, 0.564272, 1.426784 }, - { 2.448317, 1.127002, 0.327588 }, - { 2.418437, 1.074801, 0.407477 }, - { 2.405026, 1.217141, 0.328569 }, - { 0.576997, 2.600784, 2.855002 }, - { 0.517158, 2.664093, 2.805898 }, - { 0.581336, 2.513933, 2.805624 }, - { 2.875255, 1.238762, 1.338781 }, - { 2.892585, 1.147209, 1.302481 }, - { 2.795469, 1.236189, 1.399010 }, - { 1.623443, 1.734577, 3.063192 }, - { 1.708509, 1.682883, 3.053623 }, - { 1.635767, 1.806728, 3.131327 }, - { 2.710919, 0.916881, 2.856473 }, - { 2.766298, 0.905953, 2.773928 }, - { 2.730606, 1.005542, 2.898326 }, - { 0.413553, 0.398427, 1.586956 }, - { 0.433660, 0.488295, 1.547974 }, - { 0.453389, 0.327300, 1.529042 }, - { 1.497303, 1.793333, 2.176276 }, - { 1.451349, 1.745062, 2.250829 }, - { 1.487507, 1.740990, 2.091634 }, - { 1.518297, 0.712931, 1.713533 }, - { 1.511776, 0.670016, 1.803621 }, - { 1.431340, 0.702497, 1.665266 }, - { 1.551914, 1.629915, 1.465708 }, - { 1.627901, 1.578363, 1.505312 }, - { 1.466468, 1.602561, 1.509874 }, - { 0.817285, 0.341999, 1.337646 }, - { 0.812267, 0.250486, 1.297643 }, - { 0.849200, 0.406874, 1.268563 }, - { 0.483208, 1.585241, 2.340546 }, - { 0.455791, 1.506492, 2.285348 }, - { 0.401919, 1.636533, 2.368138 }, - { 0.072505, 1.709287, 2.006497 }, - { 0.160460, 1.755185, 1.993951 }, - { -0.001476, 1.775956, 1.997443 }, - { 2.582320, 0.685754, 2.244482 }, - { 2.650091, 0.637094, 2.299612 }, - { 2.587629, 0.654280, 2.149712 }, - { 1.501209, 2.306496, 0.101764 }, - { 1.573483, 2.238069, 0.092060 }, - { 1.424723, 2.267188, 0.152802 }, - { 2.481658, 1.039356, 2.585797 }, - { 2.460124, 0.963544, 2.524242 }, - { 2.416564, 1.040181, 2.661705 }, - { 0.007444, 0.131285, 3.075162 }, - { 0.021151, 0.050319, 3.132229 }, - { -0.077919, 0.121895, 3.023929 }, - { 2.384391, 2.087250, 2.954037 }, - { 2.285605, 2.102203, 2.958238 }, - { 2.419802, 2.072319, 3.046358 }, - { 2.522700, 1.616950, 0.785956 }, - { 2.585893, 1.539614, 0.791042 }, - { 2.445543, 1.593127, 0.726971 }, - { 0.874549, 0.343416, 0.840602 }, - { 0.833294, 0.425210, 0.800506 }, - { 0.845368, 0.262750, 0.789208 }, - { 1.590202, 0.346154, 1.432877 }, - { 1.615997, 0.442727, 1.435750 }, - { 1.615345, 0.302353, 1.519186 }, - { 0.200720, 2.166011, 1.669131 }, - { 0.203419, 2.079517, 1.619016 }, - { 0.270766, 2.165386, 1.740497 }, - { 2.718568, 1.424756, 0.815413 }, - { 2.672368, 1.357349, 0.757778 }, - { 2.816407, 1.424830, 0.794736 }, - { 0.046991, 1.844195, 1.458743 }, - { 0.084611, 1.875306, 1.546017 }, - { 0.077274, 1.750582, 1.440864 }, - { 2.572122, 0.480250, 0.179410 }, - { 2.648033, 0.542352, 0.159896 }, - { 2.607804, 0.388536, 0.197167 }, - { 2.983852, 2.126827, 0.529426 }, - { 2.919768, 2.105563, 0.455662 }, - { 3.074677, 2.143297, 0.490962 }, - { 2.481990, 1.585232, 2.950477 }, - { 2.481605, 1.594815, 2.850938 }, - { 2.550736, 1.646421, 2.989590 }, - { 1.937349, 2.315709, 2.488461 }, - { 1.866975, 2.245603, 2.476944 }, - { 1.894483, 2.401770, 2.515955 }, - { 2.198232, 2.608651, 1.779312 }, - { 2.176557, 2.685274, 1.718822 }, - { 2.121877, 2.544080, 1.779987 }, - { 2.767491, 1.663955, 0.469798 }, - { 2.721891, 1.697642, 0.552174 }, - { 2.698811, 1.638682, 0.401649 }, - { 0.406640, 1.422145, 1.928232 }, - { 0.397242, 1.448410, 2.024263 }, - { 0.347679, 1.343646, 1.909219 }, - { 1.896401, 2.791342, 1.136750 }, - { 1.924382, 2.698789, 1.162263 }, - { 1.819455, 2.786541, 1.073062 }, - { 1.769318, 1.881876, 2.175327 }, - { 1.682986, 1.831440, 2.177071 }, - { 1.835406, 1.832880, 2.118478 }, - { 2.282848, 0.667216, 1.278688 }, - { 2.328695, 0.755760, 1.286297 }, - { 2.184749, 0.681493, 1.265545 }, - { 0.082448, 2.196028, 2.545991 }, - { 0.127614, 2.276112, 2.506664 }, - { 0.023481, 2.153839, 2.477121 }, - { 1.173007, 2.545388, 1.465317 }, - { 1.261847, 2.555552, 1.510086 }, - { 1.100823, 2.576852, 1.526958 }, - { 0.971281, 0.476352, 1.707317 }, - { 0.987809, 0.486035, 1.805465 }, - { 1.034678, 0.408994, 1.669323 }, - { 1.729149, 0.592677, 2.083464 }, - { 1.809754, 0.606881, 2.026009 }, - { 1.710765, 0.494708, 2.091470 }, - { 0.139730, 0.213097, 1.878174 }, - { 0.232551, 0.235783, 1.848687 }, - { 0.142086, 0.178372, 1.971921 }, - { 3.067644, 0.529023, 2.833107 }, - { 3.055445, 0.610258, 2.890134 }, - { 2.990385, 0.466966, 2.846527 }, - { 1.629882, 2.760517, 1.057234 }, - { 1.570178, 2.835637, 1.085385 }, - { 1.576395, 2.676331, 1.050029 }, - { 0.046460, 2.403684, 1.395527 }, - { 0.000167, 2.351222, 1.466974 }, - { -0.017278, 2.469978, 1.356251 }, - { 0.979941, 2.502884, 1.685655 }, - { 0.890348, 2.484811, 1.726232 }, - { 1.050479, 2.455007, 1.737925 }, - { 0.380089, 0.272073, 1.817507 }, - { 0.405127, 0.180000, 1.787580 }, - { 0.383922, 0.334644, 1.739596 }, - { 1.475603, 1.663110, 1.902010 }, - { 1.562825, 1.673352, 1.854183 }, - { 1.453838, 1.565942, 1.911209 }, - { 1.235365, 1.009114, 1.796560 }, - { 1.195125, 0.917615, 1.799501 }, - { 1.169665, 1.075583, 1.832132 }, - { 3.102696, 0.787487, 2.857110 }, - { 3.043825, 0.822299, 2.784156 }, - { 3.198383, 0.805056, 2.833971 }, - { 2.096222, 2.284527, 2.693411 }, - { 2.058902, 2.270396, 2.601719 }, - { 2.088818, 2.381204, 2.717880 }, - { 2.356806, 0.691401, 2.545193 }, - { 2.386469, 0.605803, 2.502849 }, - { 2.396691, 0.768628, 2.495743 }, - { 1.891409, 0.166304, 1.584899 }, - { 1.959147, 0.204771, 1.522195 }, - { 1.859632, 0.237563, 1.647447 }, - { 2.518043, 2.459156, 3.101591 }, - { 2.428358, 2.472460, 3.059407 }, - { 2.508114, 2.457102, 3.201075 }, - { 0.320428, 1.244524, 0.006551 }, - { 0.286081, 1.304244, 0.079034 }, - { 0.246629, 1.224461, -0.057879 }, - { 2.048229, 0.089071, 0.726703 }, - { 2.014095, 0.080462, 0.633104 }, - { 2.088850, 0.179593, 0.739177 }, - { 2.034245, 2.982632, 1.329181 }, - { 2.031245, 2.911409, 1.259050 }, - { 1.953036, 2.975792, 1.387133 }, - { 0.538485, 2.084337, 1.023997 }, - { 0.627754, 2.089723, 0.979252 }, - { 0.548110, 2.108365, 1.120589 }, - { 2.212275, 0.056864, 2.952055 }, - { 2.213052, 0.078465, 2.854419 }, - { 2.274182, 0.118766, 3.000384 }, - { 1.700132, 0.240342, 0.949202 }, - { 1.694106, 0.245036, 1.048910 }, - { 1.789110, 0.203045, 0.922903 }, - { 1.557351, 1.014863, 0.118569 }, - { 1.498333, 0.953216, 0.066447 }, - { 1.652146, 1.003249, 0.088924 }, - { 1.370467, 1.107947, 0.345641 }, - { 1.433625, 1.162976, 0.400256 }, - { 1.402511, 1.104544, 0.250976 }, - { 0.051230, 0.959064, 0.306681 }, - { 0.137569, 0.966428, 0.256769 }, - { -0.023371, 0.993105, 0.249444 }, - { 1.061472, 0.435716, 0.312109 }, - { 1.001351, 0.476028, 0.243114 }, - { 1.147227, 0.407409, 0.269158 }, - { 1.159078, 1.784237, 1.666312 }, - { 1.243340, 1.831701, 1.691750 }, - { 1.103225, 1.769421, 1.747927 }, - { 2.346733, 2.132205, 2.314271 }, - { 2.250042, 2.143686, 2.291489 }, - { 2.363438, 2.166195, 2.406822 }, - { 1.831914, 0.624811, 2.621164 }, - { 1.918548, 0.648796, 2.664973 }, - { 1.841155, 0.633610, 2.521981 }, - { 2.313396, 0.217101, 1.823930 }, - { 2.375730, 0.273528, 1.878065 }, - { 2.246887, 0.275793, 1.777758 }, - { 0.682445, 0.914361, 0.800937 }, - { 0.644296, 0.833146, 0.845083 }, - { 0.733038, 0.887148, 0.719084 }, - { 1.290598, 2.697603, 1.716289 }, - { 1.300953, 2.723287, 1.812378 }, - { 1.220298, 2.754714, 1.673908 }, - { 2.699916, 0.577677, 1.036050 }, - { 2.781543, 0.527541, 1.064746 }, - { 2.676811, 0.646124, 1.105196 }, - { 2.379672, 1.923759, 2.151954 }, - { 2.363378, 2.011183, 2.197688 }, - { 2.414151, 1.940385, 2.059570 }, - { 2.918502, 2.910934, 1.384671 }, - { 2.835120, 2.891595, 1.436376 }, - { 2.996449, 2.914455, 1.447216 }, - { 3.076292, 0.830083, 0.821021 }, - { 3.048771, 0.918554, 0.858645 }, - { 3.145879, 0.844013, 0.750568 }, - { 0.218858, 2.069650, 1.317117 }, - { 0.146551, 2.023580, 1.368588 }, - { 0.283616, 2.001745, 1.282544 }, - { 0.020619, 0.874374, 2.443902 }, - { -0.012722, 0.782671, 2.465787 }, - { 0.091966, 0.900318, 2.508991 }, - { 2.521324, 1.753594, 2.320911 }, - { 2.464712, 1.785120, 2.244745 }, - { 2.490042, 1.796457, 2.405670 }, - { 2.057530, 3.102252, 2.695123 }, - { 1.972974, 3.145551, 2.726356 }, - { 2.053180, 3.088109, 2.596224 }, - { 2.032116, 0.595488, 1.461278 }, - { 2.063105, 0.673032, 1.516293 }, - { 2.016531, 0.625497, 1.367169 }, - { 1.491030, 0.686757, 2.193506 }, - { 1.571887, 0.657781, 2.142296 }, - { 1.456372, 0.772463, 2.155382 }, - { 1.455156, 0.193460, 2.956994 }, - { 1.455369, 0.291350, 2.977428 }, - { 1.407622, 0.177574, 2.870460 }, - { 3.024817, 1.123669, 2.374621 }, - { 3.033344, 1.024199, 2.380361 }, - { 2.959151, 1.155498, 2.442993 }, - { 2.168128, 2.952341, 0.763788 }, - { 2.136058, 3.040271, 0.728577 }, - { 2.161865, 2.883290, 0.691728 }, - { 0.030132, 2.537830, 0.817716 }, - { 0.028067, 2.528831, 0.718143 }, - { -0.043010, 2.599343, 0.847151 }, - { 1.305384, 0.363666, 0.213584 }, - { 1.332245, 0.277124, 0.171289 }, - { 1.357434, 0.377131, 0.297902 }, - { 2.632164, 0.136342, 0.656899 }, - { 2.641994, 0.192049, 0.574437 }, - { 2.718966, 0.090940, 0.677000 }, - { 0.466417, 1.949597, 0.605141 }, - { 0.461019, 1.914586, 0.511626 }, - { 0.392703, 1.909972, 0.659877 }, - { 0.398048, 0.367850, 2.287718 }, - { 0.479261, 0.318780, 2.319286 }, - { 0.398678, 0.460705, 2.324835 }, - { 1.741551, 1.439929, 1.553944 }, - { 1.803090, 1.434375, 1.475318 }, - { 1.675412, 1.365036, 1.549864 }, - { 1.050770, 2.232698, 1.500930 }, - { 1.090450, 2.316498, 1.538386 }, - { 1.118122, 2.186993, 1.442837 }, - { 1.717596, 2.258860, 0.597207 }, - { 1.699232, 2.267105, 0.499254 }, - { 1.691849, 2.343831, 0.643217 }, - { 2.212399, 2.773996, 0.555699 }, - { 2.267986, 2.695320, 0.582536 }, - { 2.270206, 2.841640, 0.510064 }, - { 0.833825, 0.137371, 0.654410 }, - { 0.765034, 0.067362, 0.635268 }, - { 0.827607, 0.209855, 0.585798 }, - { 1.484024, 2.431415, 1.172574 }, - { 1.387432, 2.405719, 1.169462 }, - { 1.492573, 2.524800, 1.207303 }, - { 1.092009, 1.304918, 0.645060 }, - { 1.037350, 1.229798, 0.608053 }, - { 1.147515, 1.271401, 0.721189 }, - { 2.926792, 1.120965, 0.145719 }, - { 2.857706, 1.056880, 0.179192 }, - { 2.991043, 1.072650, 0.086242 }, - { 0.854119, 2.974997, 1.408124 }, - { 0.869941, 2.893842, 1.351878 }, - { 0.813268, 2.947735, 1.495233 }, - { 0.395941, 1.628557, 1.722443 }, - { 0.405298, 1.574434, 1.806008 }, - { 0.467522, 1.602497, 1.657659 }, - { 0.691627, 3.086008, 2.208135 }, - { 0.612388, 3.045434, 2.253686 }, - { 0.675996, 3.087823, 2.109380 }, - { 1.902204, 2.035316, 0.346277 }, - { 1.910733, 2.004423, 0.441003 }, - { 1.831359, 2.105646, 0.340402 }, - { 1.645593, 0.569489, 3.018336 }, - { 1.729209, 0.620777, 3.037777 }, - { 1.619165, 0.516928, 3.099199 }, - { 2.037092, 0.324540, 1.440475 }, - { 2.007342, 0.418695, 1.456280 }, - { 2.112294, 0.323963, 1.374562 }, - { 1.709332, 0.025492, 1.460518 }, - { 1.782128, 0.081685, 1.499798 }, - { 1.731019, -0.071218, 1.473815 }, - { 1.822994, 1.386993, 1.285320 }, - { 1.852887, 1.448187, 1.212095 }, - { 1.740161, 1.338800, 1.256753 }, - { 2.640290, 2.907177, 2.258028 }, - { 2.588012, 2.895568, 2.173575 }, - { 2.737965, 2.909498, 2.236716 }, - { 2.830221, 1.201105, 2.554194 }, - { 2.789919, 1.238195, 2.470528 }, - { 2.775225, 1.229030, 2.632907 }, - { 0.312595, 1.269209, 1.183354 }, - { 0.399686, 1.257023, 1.230964 }, - { 0.276338, 1.360314, 1.202979 }, - { 1.219074, 1.304704, 1.406725 }, - { 1.187584, 1.394406, 1.437740 }, - { 1.171917, 1.233162, 1.458280 }, - { 0.088165, 1.132162, 2.948754 }, - { 0.041748, 1.067558, 3.009349 }, - { 0.029670, 1.152032, 2.870119 }, - { 2.146272, 1.433617, 2.390542 }, - { 2.138419, 1.336790, 2.414267 }, - { 2.230608, 1.448556, 2.338924 }, - { 1.126390, 2.619047, 0.229842 }, - { 1.067299, 2.650958, 0.155748 }, - { 1.172580, 2.697254, 0.271677 }, - { 0.772610, 0.713337, 2.611108 }, - { 0.748713, 0.722431, 2.514432 }, - { 0.849110, 0.774120, 2.632397 }, - { 2.447981, 2.453893, 0.248781 }, - { 2.367628, 2.396337, 0.233596 }, - { 2.503037, 2.415403, 0.322858 }, - { 0.263845, 2.493355, 0.144281 }, - { 0.335474, 2.526864, 0.083072 }, - { 0.263751, 2.547567, 0.228310 }, - { 2.711082, 1.281642, 2.333081 }, - { 2.719674, 1.381229, 2.336037 }, - { 2.715094, 1.250643, 2.238091 }, - { 2.676279, 0.650773, 2.902170 }, - { 2.580775, 0.630422, 2.880608 }, - { 2.692490, 0.748955, 2.892301 }, - { 2.877642, 0.476823, 2.154497 }, - { 2.817917, 0.409468, 2.110950 }, - { 2.850465, 0.488665, 2.250002 }, - { 1.876275, 1.779603, 0.923386 }, - { 1.813814, 1.729332, 0.863624 }, - { 1.843092, 1.775125, 1.017613 }, - { 1.999578, 2.412161, 1.792502 }, - { 2.001027, 2.333447, 1.854162 }, - { 1.945209, 2.390079, 1.711530 }, - { 1.345610, 0.547217, 1.984605 }, - { 1.382190, 0.579678, 2.071830 }, - { 1.346384, 0.447229, 1.983274 }, - { 0.367515, 3.057362, 1.507738 }, - { 0.302379, 3.058892, 1.431877 }, - { 0.427117, 3.137462, 1.502119 }, - { 3.011322, 0.923958, 3.084858 }, - { 3.042668, 0.880246, 3.000557 }, - { 2.945836, 0.864150, 3.131061 }, - { 2.392270, 1.829070, 2.562705 }, - { 2.428474, 1.901010, 2.621983 }, - { 2.295803, 1.847105, 2.543500 }, - { 1.842649, 0.637906, 1.017004 }, - { 1.801396, 0.602764, 0.932961 }, - { 1.785666, 0.612644, 1.095201 }, - { 0.617497, 0.921076, 3.039116 }, - { 0.658644, 0.998296, 3.087530 }, - { 0.598462, 0.947354, 2.944527 }, - { 3.000423, 0.591953, 0.667713 }, - { 3.020428, 0.676659, 0.716955 }, - { 3.082706, 0.560794, 0.620188 }, - { 1.169441, 1.042230, 2.178946 }, - { 1.245754, 0.989978, 2.140921 }, - { 1.083286, 1.006290, 2.143090 }, - { 2.036610, 2.690183, 0.260508 }, - { 2.009603, 2.593929, 0.262906 }, - { 2.055502, 2.721831, 0.353467 }, - { 0.678618, 0.253853, 2.315954 }, - { 0.675382, 0.155406, 2.298699 }, - { 0.739093, 0.272140, 2.393467 }, - { 1.005798, 2.653579, 3.072247 }, - { 0.962132, 2.738055, 3.041310 }, - { 1.102456, 2.654701, 3.046633 }, - { 1.212983, 0.709212, 2.939614 }, - { 1.130614, 0.765585, 2.945729 }, - { 1.252068, 0.717137, 2.847911 }, - { 1.489914, 2.604836, 0.398980 }, - { 1.495513, 2.508495, 0.372768 }, - { 1.561823, 2.625570, 0.465306 }, - { 0.270020, 3.000161, 0.139979 }, - { 0.272046, 2.929216, 0.069533 }, - { 0.175190, 3.025624, 0.158928 }, - { 0.116325, 2.146527, 0.405128 }, - { 0.197633, 2.090927, 0.387876 }, - { 0.062843, 2.154374, 0.320996 }, - { 2.194390, 2.363083, 1.040172 }, - { 2.203799, 2.458153, 1.069720 }, - { 2.099466, 2.333825, 1.051723 }, - { 2.614382, 2.672006, 2.545183 }, - { 2.702055, 2.682635, 2.498273 }, - { 2.547538, 2.632268, 2.482312 }, - { 1.172490, 1.978854, 0.953816 }, - { 1.153736, 1.956987, 0.858056 }, - { 1.208445, 1.897823, 1.000089 }, - { 0.312017, 1.290869, 2.693676 }, - { 0.400078, 1.306245, 2.738496 }, - { 0.308832, 1.197685, 2.657527 }, - { 1.098510, 0.153188, 0.479180 }, - { 1.082395, 0.060457, 0.445397 }, - { 1.013706, 0.205890, 0.473643 }, - { 1.784232, 1.875739, 2.847711 }, - { 1.880468, 1.867252, 2.821892 }, - { 1.756731, 1.795507, 2.900688 }, - { 0.350440, 0.678473, 0.534561 }, - { 0.304420, 0.661506, 0.447417 }, - { 0.444709, 0.645498, 0.529451 }, - { 1.169279, 2.747161, 2.285225 }, - { 1.268213, 2.761560, 2.283046 }, - { 1.142212, 2.689916, 2.207827 }, - { 0.570823, 2.828304, 0.432263 }, - { 0.477361, 2.806398, 0.460280 }, - { 0.630151, 2.749729, 0.449758 }, - { 2.444623, 1.342698, 1.778805 }, - { 2.396114, 1.374737, 1.697438 }, - { 2.502313, 1.264669, 1.754654 }, - { 1.238327, 1.673449, 0.435189 }, - { 1.219243, 1.771146, 0.425637 }, - { 1.289703, 1.641577, 0.355536 }, - { 0.153594, 2.293098, 1.181422 }, - { 0.090310, 2.342888, 1.240718 }, - { 0.168866, 2.201468, 1.218445 }, - { 0.632666, 0.899307, 0.356243 }, - { 0.723101, 0.856637, 0.355391 }, - { 0.581983, 0.871642, 0.274598 }, - { 1.171387, 1.540110, 0.022861 }, - { 1.256436, 1.556098, -0.027249 }, - { 1.158655, 1.612352, 0.090824 }, - { 1.775234, 2.639426, 1.417896 }, - { 1.845711, 2.597737, 1.360493 }, - { 1.690109, 2.646981, 1.365967 }, - { 2.286208, 0.014645, 1.462383 }, - { 2.206073, 0.018088, 1.402662 }, - { 2.347516, 0.090501, 1.440309 }, - { 1.855339, 2.566208, 2.578398 }, - { 1.790876, 2.631256, 2.618564 }, - { 1.937501, 2.561317, 2.635191 }, - { 1.365327, 2.886261, 0.999166 }, - { 1.387151, 2.932093, 1.085324 }, - { 1.306889, 2.945537, 0.943747 }, - { 1.928061, 0.624805, 1.853047 }, - { 2.014539, 0.628321, 1.903139 }, - { 1.890842, 0.717205, 1.844269 }, - { 1.819535, 1.163727, 2.634753 }, - { 1.795091, 1.160180, 2.731654 }, - { 1.776597, 1.087246, 2.586722 }, - { 0.437791, 0.196657, 0.571311 }, - { 0.395955, 0.125509, 0.627771 }, - { 0.517613, 0.159163, 0.524167 }, - { 0.990439, 3.084440, 1.049646 }, - { 0.979541, 3.092549, 0.950573 }, - { 0.982817, 2.988350, 1.076266 }, - { 0.135630, 1.424594, 2.366009 }, - { 0.186875, 1.452547, 2.447204 }, - { 0.038302, 1.419049, 2.388291 }, - { 0.774298, 0.700782, 3.014136 }, - { 0.720206, 0.631836, 2.965965 }, - { 0.718205, 0.782026, 3.030041 }, - { 0.336274, 0.174819, 1.183050 }, - { 0.314277, 0.220780, 1.097005 }, - { 0.375410, 0.240907, 1.247087 }, - { 2.624106, 1.198353, 2.749908 }, - { 2.560306, 1.194010, 2.826790 }, - { 2.597145, 1.131696, 2.680410 }, - { 1.093957, 0.845871, 2.479553 }, - { 1.188103, 0.816901, 2.462315 }, - { 1.093910, 0.922684, 2.543582 }, - { 1.144358, 2.465872, 2.785667 }, - { 1.125932, 2.423311, 2.697072 }, - { 1.162905, 2.394834, 2.853561 }, - { 0.649380, 2.048907, 1.653051 }, - { 0.724093, 2.114135, 1.665825 }, - { 0.641274, 2.026088, 1.556027 }, - { 2.643681, 3.013983, 1.808290 }, - { 2.566518, 3.046667, 1.753722 }, - { 2.715972, 3.083077, 1.808537 }, - { 1.812965, 0.376719, 1.762352 }, - { 1.801808, 0.339809, 1.854619 }, - { 1.843189, 0.471878, 1.767946 }, - { 0.234547, 1.903456, 0.762488 }, - { 0.157170, 1.852394, 0.724997 }, - { 0.206290, 1.997433, 0.781722 }, - { 1.299412, 0.664482, 1.563116 }, - { 1.311728, 0.569449, 1.534531 }, - { 1.233073, 0.709042, 1.503004 }, - { 0.471100, 2.414620, 0.417294 }, - { 0.391412, 2.471872, 0.436584 }, - { 0.481394, 2.346350, 0.489635 }, - { 1.105199, 0.810713, 1.415766 }, - { 1.028862, 0.771144, 1.466826 }, - { 1.075099, 0.833553, 1.323179 }, - { 0.357194, 1.129205, 2.166708 }, - { 0.381063, 1.108356, 2.071863 }, - { 0.258268, 1.120957, 2.178772 }, - { 2.141714, 2.142842, 1.486301 }, - { 2.214417, 2.177650, 1.427118 }, - { 2.173165, 2.142784, 1.581227 }, - { 1.702656, 2.224459, 0.331437 }, - { 1.603028, 2.232063, 0.335497 }, - { 1.732962, 2.233784, 0.236598 }, - { 1.658323, 0.033785, 3.067776 }, - { 1.664949, -0.057469, 3.027418 }, - { 1.645833, 0.101485, 2.995245 }, - { 1.569246, 2.399663, 2.180838 }, - { 1.632507, 2.472664, 2.206702 }, - { 1.618676, 2.312866, 2.176035 }, - { 1.419905, 1.952344, 3.057437 }, - { 1.445836, 1.856069, 3.049776 }, - { 1.336568, 1.968723, 3.004648 }, - { 0.928720, 2.693943, 2.063425 }, - { 1.010503, 2.637688, 2.075549 }, - { 0.868058, 2.681946, 2.142014 }, - { 1.634044, 1.676942, 0.314676 }, - { 1.598932, 1.702735, 0.404686 }, - { 1.693576, 1.597106, 0.323743 }, - { 0.830401, 2.033807, 0.958468 }, - { 0.877584, 2.009187, 0.873806 }, - { 0.842339, 1.960779, 1.025731 }, - { 1.967128, 2.547359, 2.082619 }, - { 1.876900, 2.575384, 2.115383 }, - { 1.998137, 2.610913, 2.011912 }, - { 1.914760, 2.240130, 2.014567 }, - { 1.821780, 2.210964, 2.037023 }, - { 1.919160, 2.340032, 2.014097 }, - { 1.204308, 0.740440, 1.830255 }, - { 1.256133, 0.732237, 1.745127 }, - { 1.232956, 0.668707, 1.893766 }, - { 2.380670, 2.109764, 1.022198 }, - { 2.326708, 2.025893, 1.029529 }, - { 2.321764, 2.184785, 0.992169 }, - { 2.366020, 1.001282, 0.597718 }, - { 2.285764, 1.010658, 0.656634 }, - { 2.447119, 0.985657, 0.654100 }, - { 0.691093, 0.752276, 2.340281 }, - { 0.672345, 0.665438, 2.294371 }, - { 0.638224, 0.825117, 2.296702 }, - { 0.414470, 0.458922, 2.024676 }, - { 0.426859, 0.408179, 1.939402 }, - { 0.398400, 0.394716, 2.099639 }, - { 0.167761, 2.702213, 0.308317 }, - { 0.164799, 2.726732, 0.211415 }, - { 0.075331, 2.705407, 0.346351 }, - { 1.577121, 1.524739, 1.021991 }, - { 1.589557, 1.439621, 1.072984 }, - { 1.597070, 1.602521, 1.081588 }, - { 1.464515, 1.174865, 1.762501 }, - { 1.478245, 1.202376, 1.667345 }, - { 1.399154, 1.099275, 1.766248 }, - { 2.156436, 2.877467, 1.024294 }, - { 2.161692, 2.918408, 0.933211 }, - { 2.067570, 2.833082, 1.035814 }, - { 2.271721, 2.343209, 1.882211 }, - { 2.257455, 2.432253, 1.838994 }, - { 2.291592, 2.356109, 1.979364 }, - { 0.807058, 1.819083, 1.176660 }, - { 0.777268, 1.875932, 1.253347 }, - { 0.730406, 1.763369, 1.144717 }, - { 0.521151, 2.636134, 0.772735 }, - { 0.427182, 2.604330, 0.760148 }, - { 0.582650, 2.557415, 0.777345 }, - { 2.865336, 0.074459, 1.821400 }, - { 2.952667, 0.047840, 1.780599 }, - { 2.830128, 0.155624, 1.774788 }, - { 1.032809, 2.928064, 1.935884 }, - { 1.018040, 2.848521, 1.994662 }, - { 1.035481, 2.898836, 1.840289 }, - { 0.603364, 2.018313, 2.974977 }, - { 0.686166, 2.053333, 3.018767 }, - { 0.559972, 1.950936, 3.034789 }, - { 2.496931, 1.651761, 1.499709 }, - { 2.426104, 1.589820, 1.533574 }, - { 2.465513, 1.695407, 1.415400 }, - { 1.992895, 1.432951, 0.877265 }, - { 2.091252, 1.415249, 0.880807 }, - { 1.970437, 1.479332, 0.791565 }, - { 1.349627, 0.944871, 0.891822 }, - { 1.294930, 0.866245, 0.920567 }, - { 1.430409, 0.952441, 0.950277 }, - { 0.688705, 1.806392, 1.795933 }, - { 0.675348, 1.802183, 1.894948 }, - { 0.661166, 1.896480, 1.762382 }, - { 2.765604, 1.268705, 0.455509 }, - { 2.832068, 1.330161, 0.498002 }, - { 2.804218, 1.176637, 0.449819 }, - { 1.087520, 0.313048, 1.525021 }, - { 1.171839, 0.329995, 1.474000 }, - { 1.010104, 0.311057, 1.461754 }, - { 2.264949, 1.629745, 1.089892 }, - { 2.266355, 1.729527, 1.083429 }, - { 2.294268, 1.590285, 1.002810 }, - { 1.678565, 0.632669, 1.470373 }, - { 1.624608, 0.654483, 1.551692 }, - { 1.740148, 0.708734, 1.449838 }, - { 2.043401, 0.809955, 1.606486 }, - { 1.981133, 0.814050, 1.684626 }, - { 2.114947, 0.878990, 1.617221 }, - { 1.188958, 2.411149, 1.184279 }, - { 1.117315, 2.345728, 1.160041 }, - { 1.172674, 2.445693, 1.276699 }, - { 2.032803, 1.248583, 1.710235 }, - { 2.108155, 1.185674, 1.691144 }, - { 2.065892, 1.323986, 1.766976 }, - { 0.653339, 1.578073, 0.294654 }, - { 0.578773, 1.637336, 0.325114 }, - { 0.691682, 1.613835, 0.209501 }, - { 0.009546, 0.004266, 0.204101 }, - { -0.040074, -0.018504, 0.287883 }, - { 0.072281, 0.080040, 0.222063 }, - { 0.301904, 1.858297, 1.612515 }, - { 0.355925, 1.926715, 1.661512 }, - { 0.316285, 1.768475, 1.654050 }, - { 0.210458, 0.733536, 2.307309 }, - { 0.180804, 0.654013, 2.254425 }, - { 0.130306, 0.783770, 2.339748 }, - { 0.468404, 1.026549, 2.487707 }, - { 0.469169, 0.997854, 2.391915 }, - { 0.528829, 1.105369, 2.499377 }, - { 1.253251, 2.170940, 2.427798 }, - { 1.218924, 2.125540, 2.345576 }, - { 1.292201, 2.102762, 2.489723 }, - { 1.591250, 2.288296, 1.789703 }, - { 1.535539, 2.354383, 1.839990 }, - { 1.577205, 2.196951, 1.827900 }, - { 2.946891, 1.547805, 0.043940 }, - { 2.976856, 1.626139, 0.098401 }, - { 3.024835, 1.510346, -0.006275 }, - { 1.371900, 2.628764, 0.835498 }, - { 1.372210, 2.716646, 0.883213 }, - { 1.304040, 2.568374, 0.877306 }, - { 0.280736, 1.464804, 0.831929 }, - { 0.228581, 1.472811, 0.746984 }, - { 0.347573, 1.539004, 0.837130 }, - { 0.464336, 1.777354, 0.380566 }, - { 0.389430, 1.725765, 0.422129 }, - { 0.427185, 1.855411, 0.330296 }, - { 1.262352, 0.703325, 0.972513 }, - { 1.191673, 0.644211, 0.933656 }, - { 1.344104, 0.649143, 0.992027 }, - { 1.863906, 2.737826, 0.051729 }, - { 1.794894, 2.699801, 0.113303 }, - { 1.945526, 2.762192, 0.104117 }, - { 1.934621, 0.339861, 2.346475 }, - { 1.953277, 0.266858, 2.280729 }, - { 1.887904, 0.301739, 2.426251 }, - { 2.302869, 1.427632, 1.252785 }, - { 2.397274, 1.397143, 1.240212 }, - { 2.280683, 1.496666, 1.183922 }, - { 1.499814, 2.033362, 1.994311 }, - { 1.554854, 1.968437, 1.941819 }, - { 1.450097, 1.984557, 2.066049 }, - { 2.083899, 1.448550, 1.427712 }, - { 2.155069, 1.430052, 1.359942 }, - { 1.994861, 1.452375, 1.382351 }, - { 1.166293, 0.405665, 2.411606 }, - { 1.219526, 0.442955, 2.487604 }, - { 1.089623, 0.466645, 2.391527 }, - { 1.884977, 2.484835, 0.910720 }, - { 1.800940, 2.508832, 0.862120 }, - { 1.960852, 2.539311, 0.875009 }, - { 1.112780, 1.256626, 2.318798 }, - { 1.124735, 1.166291, 2.277606 }, - { 1.015258, 1.277965, 2.324623 }, - { 1.261958, 0.079632, 1.408891 }, - { 1.210228, -0.005830, 1.413406 }, - { 1.296352, 0.102628, 1.499931 }, - { 2.585863, 2.434800, 1.911444 }, - { 2.534322, 2.378065, 1.975667 }, - { 2.671546, 2.463898, 1.954008 }, - { 1.730110, 2.631838, 2.128379 }, - { 1.705843, 2.703561, 2.193702 }, - { 1.699136, 2.658108, 2.036998 }, - { 0.786013, 0.466280, 2.703562 }, - { 0.791829, 0.555341, 2.658458 }, - { 0.709772, 0.466601, 2.768271 }, - { 2.124892, 1.358270, 0.553264 }, - { 2.034419, 1.400658, 0.549024 }, - { 2.119175, 1.272546, 0.604438 }, - { 1.937050, 2.839942, 0.507969 }, - { 1.875834, 2.818483, 0.584074 }, - { 2.028851, 2.805971, 0.528431 }, - { 0.694033, 3.048894, 0.117965 }, - { 0.742816, 3.121531, 0.166381 }, - { 0.609109, 3.027780, 0.166360 }, - { 1.831965, 2.250876, 0.092662 }, - { 1.865896, 2.301798, 0.013570 }, - { 1.773638, 2.175866, 0.061491 }, - { 0.423245, 1.234308, 0.866709 }, - { 0.360637, 1.303337, 0.830443 }, - { 0.397879, 1.212525, 0.960954 }, - { 0.694900, 2.540850, 0.372187 }, - { 0.602805, 2.502432, 0.365669 }, - { 0.720059, 2.582155, 0.284660 }, - { 1.613218, 1.068730, 0.571353 }, - { 1.538921, 1.001994, 0.566242 }, - { 1.695532, 1.030236, 0.529608 }, - { 0.351434, 0.972531, 0.811903 }, - { 0.260612, 0.979713, 0.853132 }, - { 0.394644, 1.062703, 0.810529 }, - { 0.654466, 0.668950, 0.939867 }, - { 0.702533, 0.633043, 0.859865 }, - { 0.710634, 0.655200, 1.021452 }, - { 0.603028, 1.706677, 1.011611 }, - { 0.580653, 1.621617, 0.964026 }, - { 0.523907, 1.767799, 1.009608 }, - { 1.984519, 2.241066, 0.609025 }, - { 2.023379, 2.331592, 0.626204 }, - { 1.884845, 2.247855, 0.604676 }, - { 2.409340, 0.321441, 3.077053 }, - { 2.478278, 0.391544, 3.095303 }, - { 2.325876, 0.364808, 3.043095 }, - { 0.107482, 0.226784, 2.149938 }, - { 0.116209, 0.319603, 2.186110 }, - { 0.058157, 0.169871, 2.215724 }, - { 2.516283, 2.299608, 1.651831 }, - { 2.498891, 2.206877, 1.684975 }, - { 2.522873, 2.362117, 1.729607 }, - { 0.166350, 0.223961, 0.204554 }, - { 0.252719, 0.174404, 0.195355 }, - { 0.155959, 0.287342, 0.127907 }, - { 1.790683, 2.102293, 2.508842 }, - { 1.772161, 2.115965, 2.606156 }, - { 1.727524, 2.033989, 2.472162 }, - { 0.804515, 2.449580, 1.058470 }, - { 0.834701, 2.389681, 1.132638 }, - { 0.826442, 2.407366, 0.970509 }, - { 0.893496, 1.408646, 1.094836 }, - { 0.884226, 1.374665, 1.001245 }, - { 0.977331, 1.462610, 1.102556 }, - { 1.324336, 0.283014, 1.983930 }, - { 1.249350, 0.246218, 1.928948 }, - { 1.311952, 0.256118, 2.079446 }, - { 2.246377, 2.623759, 1.150493 }, - { 2.254787, 2.651518, 1.246195 }, - { 2.233979, 2.704806, 1.093243 }, - { 2.622015, 2.142252, 1.121850 }, - { 2.689193, 2.164431, 1.051174 }, - { 2.532526, 2.128120, 1.079520 }, - { 2.868567, 0.744064, 0.453349 }, - { 2.910325, 0.673469, 0.510556 }, - { 2.806360, 0.701325, 0.387747 }, - { 3.007500, 2.824869, 0.443635 }, - { 3.007007, 2.870315, 0.532711 }, - { 2.943592, 2.871184, 0.382230 }, - { 0.618477, 0.645863, 0.479989 }, - { 0.594221, 0.568779, 0.421086 }, - { 0.609509, 0.731187, 0.428613 }, - { 0.315716, 2.761151, 1.152915 }, - { 0.333548, 2.715008, 1.239822 }, - { 0.223414, 2.799613, 1.153918 }, - { 2.418530, 2.718375, 0.233422 }, - { 2.423642, 2.619487, 0.219456 }, - { 2.380935, 2.761708, 0.151514 }, - { 1.098775, 2.225525, 0.111034 }, - { 1.066019, 2.283329, 0.185771 }, - { 1.184183, 2.181157, 0.138180 }, - { 0.073228, 2.893589, 1.127852 }, - { -0.000546, 2.826243, 1.132538 }, - { 0.059832, 2.952201, 1.047945 }, - { 2.174281, 0.457878, 2.973554 }, - { 2.121013, 0.408744, 3.042462 }, - { 2.172823, 0.555783, 2.993862 }, - { 1.661179, 0.921490, 2.630975 }, - { 1.665185, 0.927948, 2.730685 }, - { 1.665678, 0.825419, 2.603585 }, - { 2.933824, 1.488535, 1.260173 }, - { 2.909874, 1.400289, 1.300658 }, - { 2.862083, 1.516509, 1.196371 }, - { 0.456309, 2.283995, 2.966447 }, - { 0.466757, 2.196379, 3.013504 }, - { 0.361327, 2.294986, 2.937162 }, - { 0.384923, 0.707170, 1.649992 }, - { 0.418731, 0.700554, 1.556113 }, - { 0.288802, 0.734733, 1.648941 }, - { 1.510475, 2.724715, 1.326010 }, - { 1.413124, 2.746983, 1.331212 }, - { 1.562660, 2.807736, 1.306410 }, - { 2.250746, 0.876319, 0.084095 }, - { 2.321093, 0.946839, 0.075252 }, - { 2.215587, 0.875860, 0.177709 }, - { 0.977551, 0.759542, 0.731438 }, - { 1.009700, 0.844792, 0.772656 }, - { 1.044178, 0.686987, 0.748662 }, - { 1.871166, 1.469743, 1.990566 }, - { 1.831271, 1.463875, 2.082075 }, - { 1.849894, 1.386424, 1.939522 }, - { 2.976639, 2.909585, 2.965670 }, - { 2.896178, 2.903513, 2.906601 }, - { 2.955625, 2.966962, 3.044830 }, - { 0.219237, 0.614174, 0.309084 }, - { 0.158141, 0.621804, 0.230286 }, - { 0.312225, 0.595369, 0.277468 }, - { 0.981300, 0.603983, 2.324795 }, - { 0.882565, 0.588395, 2.321892 }, - { 1.001037, 0.681675, 2.384581 }, - { 0.755745, 1.121905, 0.406068 }, - { 0.691338, 1.191344, 0.438159 }, - { 0.709373, 1.033485, 0.400449 }, - { 1.727780, 0.415657, 0.225759 }, - { 1.724835, 0.315869, 0.219966 }, - { 1.637306, 0.450294, 0.250552 }, - { 2.250400, 1.714328, 1.807288 }, - { 2.201134, 1.794153, 1.841942 }, - { 2.313622, 1.681184, 1.877320 }, - { 1.251501, 3.006716, 0.790040 }, - { 1.153176, 3.024619, 0.786643 }, - { 1.270862, 2.918652, 0.746798 }, - { 1.408456, 0.117617, 0.777739 }, - { 1.355175, 0.033350, 0.785506 }, - { 1.406323, 0.166559, 0.864918 }, - { 0.191205, 1.398354, 0.571156 }, - { 0.243639, 1.328404, 0.522600 }, - { 0.109777, 1.356822, 0.611709 }, - { 0.168897, 1.033560, 0.985840 }, - { 0.226152, 0.997522, 1.059481 }, - { 0.076618, 1.050336, 1.020529 }, - { 0.899943, 2.296334, 1.263741 }, - { 0.941794, 2.238530, 1.193690 }, - { 0.936440, 2.271641, 1.353508 }, - { 3.025877, 1.802499, 0.139230 }, - { 3.014528, 1.810825, 0.238234 }, - { 3.120663, 1.822856, 0.114713 }, - { 2.165556, 2.121814, 1.756587 }, - { 2.133566, 2.054018, 1.822771 }, - { 2.183626, 2.208257, 1.803504 }, - { 2.014080, 0.353870, 1.050143 }, - { 1.947732, 0.401211, 1.108082 }, - { 2.045383, 0.270858, 1.096285 }, - { 1.032910, 0.439954, 2.784389 }, - { 1.039158, 0.468637, 2.879983 }, - { 0.940927, 0.458674, 2.749913 }, - { 2.768091, 0.500326, 2.411384 }, - { 2.832257, 0.519231, 2.485716 }, - { 2.693746, 0.442723, 2.445366 }, - { 2.006408, 0.715128, 1.227328 }, - { 1.975360, 0.677657, 1.139967 }, - { 1.940802, 0.783386, 1.259525 }, - { 2.487491, 2.094551, 1.399436 }, - { 2.575522, 2.109672, 1.354471 }, - { 2.418647, 2.154795, 1.359050 }, - { 1.382277, 0.933263, 2.057272 }, - { 1.464198, 0.988093, 2.040457 }, - { 1.331486, 0.922156, 1.971851 }, - { 0.814603, 1.428325, 2.639752 }, - { 0.800255, 1.459433, 2.545803 }, - { 0.763166, 1.486824, 2.702459 }, - { 1.261287, 0.211828, 2.224595 }, - { 1.241577, 0.276306, 2.298447 }, - { 1.224565, 0.121861, 2.248203 }, - { 1.619485, 2.689898, 0.188250 }, - { 1.588224, 2.651442, 0.275106 }, - { 1.626511, 2.789316, 0.196419 }, - { 0.418282, 2.348942, 1.783532 }, - { 0.446726, 2.334551, 1.688749 }, - { 0.340773, 2.412083, 1.785854 }, - { 0.074372, 0.645818, 1.465995 }, - { 0.111170, 0.656995, 1.373686 }, - { 0.051180, 0.549745, 1.481229 }, - { 3.103577, 0.430002, 1.792040 }, - { 3.127296, 0.345212, 1.839453 }, - { 3.185557, 0.486255, 1.781320 }, - { 0.656926, 1.071854, 1.113254 }, - { 0.740429, 1.082080, 1.059192 }, - { 0.603347, 0.995283, 1.077673 }, - { 1.082612, 2.167030, 1.119109 }, - { 1.112438, 2.118508, 1.036914 }, - { 1.121778, 2.122971, 1.199885 }, - { 1.685950, 2.668299, 0.595540 }, - { 1.654574, 2.595554, 0.656563 }, - { 1.701733, 2.751685, 0.648433 }, - { 1.877991, 1.451300, 0.501414 }, - { 1.860443, 1.441725, 0.403432 }, - { 1.791928, 1.469157, 0.549104 }, - { 1.193680, 2.367192, 1.806688 }, - { 1.230655, 2.274677, 1.798090 }, - { 1.267246, 2.430350, 1.831166 }, - { 1.262868, 3.023321, 2.111573 }, - { 1.218133, 3.027728, 2.200900 }, - { 1.198796, 2.986934, 2.043964 }, - { 2.363530, 1.819884, 0.872829 }, - { 2.421597, 1.755189, 0.823403 }, - { 2.406757, 1.843780, 0.959779 }, - { 2.828612, 2.346733, 0.601532 }, - { 2.871731, 2.429490, 0.565585 }, - { 2.896460, 2.273475, 0.606992 }, - { 1.479757, 1.908335, 0.805231 }, - { 1.432019, 1.821825, 0.820629 }, - { 1.493505, 1.954847, 0.892682 }, - { 2.447036, 2.469183, 1.388989 }, - { 2.484687, 2.415866, 1.464750 }, - { 2.421583, 2.560194, 1.421687 }, - { 0.390387, 2.304647, 0.871009 }, - { 0.343645, 2.374860, 0.924723 }, - { 0.452494, 2.253251, 0.930179 }, - { 1.331260, 0.646907, 0.168446 }, - { 1.335624, 0.547157, 0.173994 }, - { 1.421037, 0.685440, 0.189784 }, - { 2.828654, 2.172696, 2.960263 }, - { 2.739741, 2.218000, 2.953789 }, - { 2.815353, 2.073702, 2.965085 }, - { 1.031085, 0.986172, 0.843095 }, - { 1.020895, 1.030502, 0.754039 }, - { 0.995655, 1.046452, 0.914586 }, - { 1.724838, 0.391131, 2.659596 }, - { 1.768809, 0.480924, 2.657695 }, - { 1.633320, 0.399657, 2.698991 }, - { 2.588704, 2.692304, 1.035174 }, - { 2.627025, 2.632110, 1.105232 }, - { 2.527773, 2.758929, 1.078168 }, - { 2.699075, 0.688808, 0.769271 }, - { 2.672432, 0.666009, 0.862921 }, - { 2.792721, 0.657848, 0.752781 }, - { 0.703772, 1.603296, 2.794425 }, - { 0.701323, 1.570932, 2.889011 }, - { 0.695426, 1.702938, 2.793061 }, - { 0.199272, 0.353715, 0.976004 }, - { 0.232097, 0.405137, 0.896767 }, - { 0.126936, 0.290899, 0.947342 }, - { 2.546014, 0.024049, 2.369379 }, - { 2.611304, -0.035563, 2.322648 }, - { 2.454932, 0.010881, 2.330253 }, - { 0.022823, 1.201578, 0.748523 }, - { 0.089773, 1.186154, 0.821185 }, - { -0.020197, 1.290949, 0.761256 }, - { 0.132073, 0.862795, 0.586868 }, - { 0.119996, 0.867413, 0.487708 }, - { 0.214518, 0.810293, 0.607998 }, - { 2.092458, 0.359644, 0.786490 }, - { 2.040730, 0.360242, 0.872069 }, - { 2.190376, 0.358194, 0.806735 }, - { 0.421056, 2.015500, 1.793066 }, - { 0.440920, 2.024396, 1.890669 }, - { 0.503559, 2.035681, 1.740283 }, - { 0.385087, 0.729295, 0.920073 }, - { 0.370596, 0.804357, 0.855608 }, - { 0.481900, 0.704266, 0.920879 }, - { 0.660259, 0.556115, 1.874230 }, - { 0.674878, 0.507989, 1.787800 }, - { 0.637897, 0.651811, 1.855729 }, - { 1.502447, 0.450094, 2.831928 }, - { 1.420294, 0.484380, 2.786374 }, - { 1.548974, 0.525641, 2.878058 }, - { 0.029169, 0.014635, 1.731543 }, - { 0.026633, 0.054837, 1.640016 }, - { 0.060547, 0.083210, 1.797215 }, - { 1.945071, 1.895363, 0.577451 }, - { 1.862520, 1.917282, 0.629461 }, - { 2.002888, 1.833848, 0.631051 }, - { 2.310390, 0.609079, 0.805817 }, - { 2.224057, 0.654864, 0.827042 }, - { 2.298969, 0.510214, 0.815575 }, - { 0.263679, 0.742484, 1.174274 }, - { 0.318844, 0.741293, 1.090875 }, - { 0.258625, 0.835913, 1.209567 }, - { 2.214362, 2.795311, 3.028770 }, - { 2.276577, 2.856483, 2.979910 }, - { 2.193373, 2.833914, 3.118600 }, - { 2.862483, 0.087396, 2.967400 }, - { 2.775054, 0.134739, 2.956690 }, - { 2.852752, 0.014295, 3.034940 }, - { 1.911967, 1.618076, 2.687047 }, - { 1.939990, 1.699615, 2.737705 }, - { 1.934376, 1.629614, 2.590276 }, - { 3.089770, 0.624647, 0.091657 }, - { 3.155308, 0.685544, 0.046978 }, - { 2.997098, 0.648104, 0.062301 }, - { 0.073286, 1.189907, 2.156408 }, - { 0.052831, 1.175998, 2.253300 }, - { 0.036866, 1.278274, 2.127000 }, - { 1.751887, 1.440179, 0.260930 }, - { 1.798183, 1.408672, 0.178081 }, - { 1.701865, 1.364040, 0.302169 }, - { 0.173609, 2.179533, 0.758562 }, - { 0.240866, 2.219671, 0.820734 }, - { 0.176312, 2.227662, 0.670948 }, - { 0.142457, 1.714121, 2.988510 }, - { 0.117949, 1.619062, 3.007567 }, - { 0.171225, 1.722647, 2.893118 }, - { 1.307838, 1.001512, 1.411174 }, - { 1.271228, 0.912830, 1.439374 }, - { 1.232705, 1.066537, 1.399913 }, - { 2.169500, 1.727567, 2.182432 }, - { 2.214494, 1.641325, 2.205624 }, - { 2.236708, 1.801605, 2.183625 }, - { 1.262072, 0.462936, 1.175858 }, - { 1.169844, 0.436656, 1.147514 }, - { 1.323387, 0.459730, 1.096926 }, - { 1.423067, 0.881474, 0.640908 }, - { 1.410777, 0.897237, 0.738890 }, - { 1.333599, 0.874747, 0.596747 }, - { 1.354799, 1.797455, 1.110787 }, - { 1.284755, 1.765934, 1.174821 }, - { 1.443784, 1.760881, 1.138063 }, - { 2.129596, 0.681632, 2.008767 }, - { 2.164107, 0.608978, 2.068185 }, - { 2.111495, 0.763493, 2.063275 }, - { 2.448219, 0.769518, 0.357171 }, - { 2.453654, 0.740682, 0.452769 }, - { 2.364799, 0.732847, 0.315983 }, - { 0.882298, 0.543308, 0.139417 }, - { 0.841711, 0.611831, 0.078942 }, - { 0.885374, 0.455061, 0.092482 }, - { 0.800295, 1.861557, 2.511300 }, - { 0.895248, 1.830847, 2.504910 }, - { 0.776153, 1.875477, 2.607338 }, - { 0.764847, 2.617533, 0.120170 }, - { 0.750496, 2.712191, 0.091292 }, - { 0.847962, 2.581897, 0.077486 }, - { 2.224452, 2.284036, 0.208382 }, - { 2.184583, 2.300793, 0.118217 }, - { 2.231256, 2.185503, 0.224032 }, - { 0.079359, 0.002159, 0.962802 }, - { 0.088958, 0.015986, 0.864229 }, - { 0.027587, 0.078089, 1.002228 }, - { 2.203527, 0.302158, 2.750022 }, - { 2.118676, 0.267117, 2.710368 }, - { 2.181990, 0.363004, 2.826402 }, - { 2.170179, 2.922779, 0.174290 }, - { 2.139623, 2.835094, 0.211408 }, - { 2.214502, 2.975912, 0.246487 }, - { 0.890672, 0.080190, 2.804656 }, - { 0.938414, 0.126680, 2.730094 }, - { 0.956701, 0.052889, 2.874619 }, - { 2.895087, 1.762880, 1.373604 }, - { 2.900573, 1.663669, 1.362331 }, - { 2.987003, 1.800097, 1.386500 }, - { 1.853496, 2.074764, 1.508729 }, - { 1.948479, 2.059296, 1.481547 }, - { 1.801303, 2.107900, 1.430129 }, - { 2.582175, 2.315870, 2.888700 }, - { 2.529120, 2.231314, 2.882752 }, - { 2.555198, 2.366456, 2.970634 }, - { 2.750479, 0.538398, 1.610168 }, - { 2.766143, 0.560952, 1.514012 }, - { 2.664507, 0.579511, 1.640473 }, - { 1.377553, 1.621616, 0.224361 }, - { 1.362069, 1.531830, 0.183145 }, - { 1.471939, 1.627547, 0.256858 }, - { 0.701605, 1.997351, 0.173637 }, - { 0.647573, 2.049848, 0.239400 }, - { 0.768452, 2.057483, 0.129870 }, - { 0.732393, 2.885926, 1.675034 }, - { 0.681248, 2.960743, 1.717302 }, - { 0.678998, 2.801575, 1.680869 }, - { 1.333051, 1.944054, 2.636380 }, - { 1.270422, 1.992525, 2.697439 }, - { 1.304905, 1.848392, 2.628856 }, - { 0.350047, 1.397444, 2.193652 }, - { 0.381158, 1.302587, 2.187811 }, - { 0.269866, 1.402622, 2.253185 }, - { 2.655774, 2.801154, 1.477291 }, - { 2.607340, 2.769915, 1.559012 }, - { 2.612048, 2.883978, 1.442246 }, - { 0.830586, 2.382898, 2.380660 }, - { 0.751782, 2.323648, 2.363947 }, - { 0.821711, 2.466316, 2.326230 }, - { 0.386076, 2.773589, 2.748805 }, - { 0.415232, 2.861381, 2.710824 }, - { 0.309400, 2.737978, 2.695395 }, - { 0.288028, 1.761089, 2.267276 }, - { 0.195585, 1.734450, 2.294565 }, - { 0.306586, 1.727296, 2.175006 }, - { 2.845222, 3.049689, 0.710560 }, - { 2.938507, 3.015530, 0.699111 }, - { 2.796410, 2.992019, 0.776069 }, - { 2.095486, 2.468157, 1.419021 }, - { 2.014126, 2.429148, 1.462136 }, - { 2.161124, 2.395254, 1.399606 }, - { 0.990751, 0.380958, 1.088061 }, - { 0.962957, 0.355990, 0.995302 }, - { 1.050039, 0.309627, 1.125433 }, - { 1.490762, 3.006773, 1.217981 }, - { 1.443078, 3.092111, 1.239049 }, - { 1.589527, 3.021852, 1.222217 }, - { 1.054051, 1.680650, 2.482261 }, - { 0.992890, 1.601710, 2.487543 }, - { 1.097855, 1.694879, 2.571023 }, - { 1.617761, 2.709729, 1.856625 }, - { 1.685809, 2.664639, 1.798863 }, - { 1.625149, 2.808851, 1.845661 }, - { 0.831548, 0.104590, 1.240112 }, - { 0.854610, 0.030748, 1.303480 }, - { 0.870357, 0.084640, 1.150135 }, - { 2.460575, 2.913002, 2.033870 }, - { 2.387432, 2.978945, 2.016501 }, - { 2.544679, 2.944073, 1.989585 }, - { 0.968554, 1.072304, 0.587917 }, - { 1.021416, 0.999670, 0.543986 }, - { 0.886242, 1.090771, 0.534217 }, - { 1.747197, 0.995358, 2.249228 }, - { 1.834103, 1.034204, 2.279860 }, - { 1.689613, 0.975781, 2.328606 }, - { 2.113166, 1.198713, 2.946735 }, - { 2.164920, 1.232009, 3.025557 }, - { 2.082168, 1.276428, 2.891968 }, - { 0.386328, 0.003613, 1.788966 }, - { 0.370117, -0.024061, 1.694249 }, - { 0.331931, -0.053732, 1.850224 }, - { 1.113078, 2.990990, 0.400315 }, - { 1.033021, 2.934960, 0.421561 }, - { 1.196169, 2.937301, 0.414924 }, - { 3.004892, 0.215602, 0.988293 }, - { 2.941095, 0.159722, 1.041278 }, - { 2.959599, 0.248333, 0.905364 }, - { 1.180028, 0.462930, 3.027119 }, - { 1.194383, 0.448931, 3.125088 }, - { 1.205635, 0.556462, 3.002706 }, - { 1.274036, 0.501724, 2.672057 }, - { 1.301730, 0.596901, 2.685261 }, - { 1.191003, 0.483553, 2.724738 }, - { 2.947187, 2.426754, 0.273837 }, - { 2.910177, 2.352895, 0.217490 }, - { 2.962008, 2.507751, 0.217092 }, - { 0.414034, 1.604272, 2.862308 }, - { 0.369433, 1.665968, 2.797468 }, - { 0.511529, 1.598227, 2.840903 }, - { 0.857555, 1.198856, 1.337218 }, - { 0.815665, 1.254240, 1.265260 }, - { 0.790251, 1.181020, 1.408996 }, - { 1.402725, 1.861893, 1.683336 }, - { 1.478004, 1.884592, 1.621549 }, - { 1.438488, 1.812987, 1.762893 }, - { 1.143436, 2.070677, 2.177391 }, - { 1.126093, 1.974251, 2.197423 }, - { 1.140420, 2.085246, 2.078504 }, - { 1.140117, 2.529814, 2.107822 }, - { 1.195065, 2.512471, 2.026092 }, - { 1.179853, 2.481181, 2.185642 }, - { 1.977009, 0.352605, 0.334132 }, - { 1.906708, 0.390859, 0.274179 }, - { 1.962216, 0.384824, 0.427636 }, - { 2.130115, 1.470625, 1.830714 }, - { 2.130574, 1.426674, 1.920537 }, - { 2.139711, 1.569528, 1.841947 }, - { 0.730700, 0.203115, 1.799955 }, - { 0.694439, 0.296295, 1.801601 }, - { 0.830605, 0.206164, 1.803080 }, - { 1.903507, 2.950766, 2.105392 }, - { 1.961982, 2.880427, 2.145802 }, - { 1.809765, 2.939068, 2.138189 }, - { 1.362461, 0.776317, 2.440580 }, - { 1.373552, 0.711877, 2.364919 }, - { 1.401240, 0.864848, 2.414921 }, - { 1.393736, 0.230352, 1.027233 }, - { 1.474875, 0.215232, 1.083694 }, - { 1.312059, 0.203810, 1.078462 }, - { 0.883267, 2.290109, 0.853754 }, - { 0.964497, 2.279289, 0.796442 }, - { 0.862588, 2.203355, 0.898988 }, - { 1.860047, 2.351311, 1.532016 }, - { 1.892853, 2.257751, 1.518966 }, - { 1.760116, 2.352393, 1.528474 }, - { 0.907781, 1.468871, 0.302742 }, - { 0.943288, 1.506453, 0.388339 }, - { 0.808771, 1.482381, 0.298937 }, - { 0.634389, 0.172523, 0.350440 }, - { 0.731006, 0.157177, 0.329712 }, - { 0.579360, 0.100624, 0.307988 }, - { 0.948849, 0.786484, 1.870334 }, - { 1.046390, 0.765851, 1.862583 }, - { 0.902713, 0.711892, 1.918370 }, - { 0.928507, 1.428757, 1.800533 }, - { 0.964649, 1.337409, 1.819219 }, - { 0.981629, 1.471275, 1.727250 }, - { 0.520126, 0.449796, 0.329923 }, - { 0.480298, 0.444788, 0.238333 }, - { 0.545807, 0.358005, 0.360171 }, - { 0.173019, 1.766946, 1.124286 }, - { 0.119940, 1.845672, 1.155670 }, - { 0.266447, 1.795893, 1.103473 }, - { 0.294915, 2.483116, 1.059922 }, - { 0.237058, 2.412428, 1.100614 }, - { 0.279515, 2.569983, 1.107008 }, - { 1.967528, 1.701598, 0.384068 }, - { 1.937630, 1.618064, 0.430200 }, - { 1.953844, 1.779905, 0.444737 }, - { 2.602165, 1.306857, 2.049074 }, - { 2.675314, 1.367643, 2.018182 }, - { 2.530699, 1.302540, 1.979261 }, - { 0.466325, 2.360293, 2.055629 }, - { 0.431952, 2.347197, 1.962640 }, - { 0.560285, 2.394324, 2.051953 }, - { 2.050154, 1.584414, 0.148513 }, - { 2.040061, 1.624411, 0.239608 }, - { 2.068395, 1.656922, 0.082106 }, - { 1.556378, 1.957320, 2.428697 }, - { 1.476038, 1.941088, 2.485985 }, - { 1.529396, 1.956406, 2.332410 }, - { 0.682812, 1.205529, 2.526461 }, - { 0.723788, 1.287438, 2.566610 }, - { 0.754192, 1.137731, 2.508900 }, - { 1.535311, 0.251227, 2.208550 }, - { 1.556668, 0.315254, 2.282337 }, - { 1.437096, 0.253450, 2.189872 }, - { 2.668479, 2.280105, 0.800170 }, - { 2.710946, 2.318387, 0.718127 }, - { 2.739255, 2.259010, 0.867592 }, - { 1.542641, 3.084046, 2.220568 }, - { 1.544509, 3.183810, 2.213954 }, - { 1.458575, 3.049445, 2.178907 }, - { 1.457762, 1.374257, 2.244142 }, - { 1.499569, 1.291727, 2.206182 }, - { 1.369735, 1.390552, 2.199582 }, - { 2.519020, 1.910788, 1.891775 }, - { 2.505169, 1.980275, 1.821208 }, - { 2.518774, 1.820060, 1.849722 }, - { 1.153670, 2.497971, 0.920991 }, - { 1.071685, 2.549851, 0.896764 }, - { 1.150536, 2.474089, 1.018047 }, - { 2.586281, 3.065417, 2.640789 }, - { 2.568059, 3.047493, 2.544111 }, - { 2.503036, 3.049598, 2.693891 }, - { 2.306781, 1.384101, 0.311448 }, - { 2.360460, 1.468263, 0.305517 }, - { 2.263250, 1.378589, 0.401307 }, - { 2.141848, 2.022213, 0.235023 }, - { 2.188715, 1.934828, 0.222090 }, - { 2.046005, 2.005531, 0.258168 }, - { 0.201078, 1.356753, 0.228828 }, - { 0.104294, 1.337330, 0.244812 }, - { 0.255501, 1.318727, 0.303609 }, - { 0.457343, 0.726277, 2.048767 }, - { 0.460321, 0.628162, 2.067859 }, - { 0.365421, 0.751595, 2.018612 }, - { 2.860924, 1.577827, 1.715642 }, - { 2.807984, 1.661584, 1.729132 }, - { 2.834381, 1.510187, 1.784347 }, - { 3.020626, 2.542969, 0.500236 }, - { 2.999224, 2.640062, 0.489514 }, - { 3.013950, 2.497365, 0.411491 }, - { 2.449280, 0.880812, 2.387606 }, - { 2.481825, 0.817972, 2.316952 }, - { 2.399173, 0.956029, 2.344807 }, - { 0.839472, 2.578596, 0.606320 }, - { 0.789949, 2.578031, 0.519445 }, - { 0.782640, 2.537078, 0.677358 }, - { 1.243451, 2.095390, 1.335077 }, - { 1.341417, 2.115228, 1.338089 }, - { 1.228127, 1.999442, 1.358721 }, - { 0.679730, 2.838689, 2.009180 }, - { 0.764800, 2.786702, 2.001406 }, - { 0.699085, 2.936157, 1.997983 }, - { 0.738842, 1.537655, 0.650196 }, - { 0.761227, 1.584947, 0.564976 }, - { 0.790684, 1.578252, 0.725458 }, - { 2.835650, 0.699534, 0.020790 }, - { 2.777710, 0.692381, 0.101980 }, - { 2.780032, 0.685783, -0.061170 }, - { 1.845371, 0.433166, 1.258526 }, - { 1.842422, 0.520378, 1.307367 }, - { 1.791587, 0.365195, 1.308398 }, - { 3.094758, 1.053543, 1.958825 }, - { 3.137912, 1.085383, 2.043228 }, - { 3.044658, 0.968902, 1.976876 }, - { 1.893173, 3.056022, 0.347448 }, - { 1.915403, 2.979650, 0.408054 }, - { 1.943785, 3.137299, 0.376303 }, - { 0.227549, 2.726489, 1.743416 }, - { 0.256351, 2.780895, 1.822222 }, - { 0.292572, 2.739273, 1.668526 }, - { 1.149302, 2.387237, 0.343532 }, - { 1.166208, 2.474303, 0.297339 }, - { 1.104012, 2.404185, 0.431062 }, - { 0.998224, 1.657693, 1.298714 }, - { 1.056918, 1.616397, 1.229074 }, - { 0.929567, 1.715405, 1.254493 }, - { 1.580309, 1.703216, 2.655682 }, - { 1.649980, 1.643679, 2.695698 }, - { 1.618097, 1.794935, 2.643051 }, - { 2.081265, 2.616518, 0.762181 }, - { 2.163416, 2.561470, 0.777047 }, - { 2.033529, 2.583809, 0.680625 }, - { 1.576754, 0.079976, 2.599135 }, - { 1.624151, 0.042940, 2.679022 }, - { 1.635391, 0.071299, 2.518597 }, - { 1.820339, 2.087323, 1.807897 }, - { 1.862842, 2.081803, 1.717547 }, - { 1.876202, 2.144950, 1.867550 }, - { 1.288347, 2.784119, 0.352047 }, - { 1.348111, 2.713677, 0.313756 }, - { 1.267249, 2.761808, 0.447216 }, - { 2.053319, 2.806163, 2.812877 }, - { 2.012843, 2.896631, 2.799563 }, - { 2.079198, 2.795015, 2.908825 }, - { 3.103936, 1.939383, 3.010709 }, - { 3.140987, 1.850879, 2.982526 }, - { 3.004767, 1.932147, 3.021340 }, - { 1.747635, 1.880408, 0.182510 }, - { 1.711340, 1.800658, 0.230703 }, - { 1.811848, 1.928874, 0.241905 }, - { 0.357312, 1.249510, 0.396746 }, - { 0.434813, 1.308092, 0.420447 }, - { 0.370178, 1.159100, 0.437496 }, - { 1.162175, 1.003437, 0.132788 }, - { 1.128159, 0.910792, 0.148908 }, - { 1.118065, 1.066691, 0.196452 }, - { 1.720024, 2.350807, 2.796146 }, - { 1.816624, 2.332488, 2.777905 }, - { 1.666584, 2.268039, 2.779012 }, - { 1.819804, 2.881982, 1.499877 }, - { 1.801703, 2.787241, 1.473482 }, - { 1.853012, 2.884553, 1.594167 }, - { 1.641302, 0.985935, 1.700102 }, - { 1.578200, 1.054423, 1.736539 }, - { 1.590234, 0.903900, 1.674370 }, - { 1.407558, 2.105852, 0.622137 }, - { 1.439669, 2.037089, 0.687256 }, - { 1.376226, 2.186770, 0.671844 }, - { 0.742039, 2.449685, 1.807591 }, - { 0.664816, 2.508741, 1.784159 }, - { 0.750599, 2.443898, 1.907056 }, - { 1.055383, 2.338027, 2.575278 }, - { 0.980287, 2.357568, 2.512201 }, - { 1.137644, 2.315308, 2.523153 }, - { 0.383084, 1.881983, 0.997049 }, - { 0.439661, 1.963523, 1.009305 }, - { 0.342804, 1.882808, 0.905524 }, - { 1.624121, 1.460397, 0.585692 }, - { 1.610918, 1.374878, 0.635814 }, - { 1.536897, 1.490047, 0.546797 }, - { 3.073791, 2.284139, 1.733887 }, - { 3.159350, 2.238214, 1.710000 }, - { 3.006778, 2.216259, 1.763913 }, - { 2.276815, 2.539086, 2.980504 }, - { 2.243982, 2.631874, 2.998179 }, - { 2.215148, 2.473147, 3.023507 }, - { 0.287152, 0.812484, 2.829435 }, - { 0.364868, 0.874562, 2.839761 }, - { 0.320299, 0.721354, 2.805011 }, - { 2.947925, 2.745224, 1.175244 }, - { 2.937136, 2.657265, 1.221578 }, - { 2.932797, 2.819397, 1.240584 }, - { 2.432782, 0.445198, 2.008265 }, - { 2.528164, 0.421749, 2.027040 }, - { 2.426765, 0.541315, 1.981331 }, - { 2.135631, 2.846586, 1.674159 }, - { 2.112821, 2.924476, 1.615739 }, - { 2.142838, 2.877115, 1.769111 }, - { 1.992697, 1.542239, 1.123538 }, - { 1.994674, 1.495622, 1.035090 }, - { 2.085254, 1.571023, 1.148125 }, - { 3.007302, 1.002020, 1.263169 }, - { 3.005399, 1.045505, 1.173139 }, - { 3.102123, 0.991726, 1.293219 }, - { 3.042117, 1.830594, 2.657699 }, - { 3.091667, 1.816789, 2.571943 }, - { 2.974763, 1.757611, 2.669402 }, - { 1.465297, 1.281842, 2.950841 }, - { 1.411305, 1.229250, 3.016560 }, - { 1.408774, 1.303931, 2.871359 }, - { 2.612090, 0.891093, 1.547955 }, - { 2.695821, 0.887163, 1.493423 }, - { 2.616686, 0.823002, 1.621047 }, - { 0.812006, 2.707695, 1.208838 }, - { 0.735158, 2.770254, 1.195395 }, - { 0.808964, 2.635761, 1.139439 }, - { 0.318130, 2.780547, 0.516632 }, - { 0.265551, 2.753112, 0.436116 }, - { 0.291856, 2.723669, 0.594571 }, - { 1.554664, 1.776211, 0.557025 }, - { 1.585392, 1.801147, 0.648862 }, - { 1.479411, 1.836105, 0.529645 }, - { 1.313118, 1.325875, 1.106502 }, - { 1.406876, 1.305721, 1.134843 }, - { 1.255307, 1.336157, 1.187448 }, - { 0.563695, 1.495837, 0.858004 }, - { 0.647750, 1.477497, 0.807031 }, - { 0.516021, 1.409745, 0.875762 }, - { 0.189938, 2.083492, 2.220667 }, - { 0.179488, 2.169607, 2.170918 }, - { 0.228533, 2.014250, 2.159708 }, - { 1.219512, 1.960655, 0.459886 }, - { 1.126082, 1.995943, 0.454832 }, - { 1.269108, 2.007934, 0.532721 }, - { 2.373176, 2.965076, 2.821447 }, - { 2.364244, 2.875424, 2.778057 }, - { 2.284076, 3.010455, 2.822850 }, - { 0.688102, 2.932363, 2.635048 }, - { 0.749140, 3.002946, 2.599097 }, - { 0.736401, 2.878551, 2.704123 }, - { 3.043730, 1.315443, 0.326532 }, - { 3.042042, 1.258753, 0.408893 }, - { 2.996829, 1.267695, 0.252232 }, - { 1.964500, 2.004276, 2.335286 }, - { 1.904133, 1.953017, 2.274227 }, - { 1.911536, 2.040095, 2.412175 }, - { 0.450798, 1.904655, 2.606229 }, - { 0.475742, 1.954537, 2.523226 }, - { 0.376490, 1.952627, 2.652888 }, - { 2.112788, 1.128108, 0.683552 }, - { 2.130045, 1.121204, 0.781809 }, - { 2.060726, 1.048319, 0.653164 }, - { 0.770271, 0.564206, 0.707533 }, - { 0.849217, 0.624301, 0.695042 }, - { 0.701429, 0.584713, 0.637961 }, - { 1.907848, 1.027415, 1.090399 }, - { 1.926364, 1.073308, 1.177296 }, - { 1.854230, 1.087899, 1.031520 }, - { 2.006840, 0.879452, 0.615825 }, - { 1.950347, 0.812869, 0.567089 }, - { 2.048772, 0.835710, 0.695376 }, - { 1.044237, 2.729692, 2.739900 }, - { 0.957432, 2.739064, 2.788657 }, - { 1.087096, 2.642769, 2.764545 }, - { 2.024470, 0.868120, 2.448789 }, - { 1.977539, 0.792888, 2.402554 }, - { 2.038713, 0.844474, 2.544904 }, - { 2.346306, 0.847486, 1.854141 }, - { 2.428596, 0.887883, 1.894097 }, - { 2.273015, 0.846975, 1.922172 }, - { 2.451466, 1.066926, 0.052602 }, - { 2.454208, 1.089762, 0.149921 }, - { 2.461859, 1.150367, -0.001524 }, - { 1.586928, 0.171622, 1.225782 }, - { 1.643190, 0.092301, 1.249084 }, - { 1.585595, 0.235339, 1.302842 }, - { 2.158334, 2.595841, 2.438041 }, - { 2.126742, 2.586688, 2.532477 }, - { 2.120427, 2.521555, 2.382862 }, - { 0.268769, 2.384647, 1.524956 }, - { 0.178764, 2.396688, 1.483075 }, - { 0.264809, 2.310261, 1.591672 }, - { 2.964697, 0.609294, 2.578384 }, - { 3.014589, 0.539796, 2.526607 }, - { 2.991249, 0.604578, 2.674679 }, - { 2.804129, 2.035185, 2.658896 }, - { 2.831947, 2.130885, 2.667122 }, - { 2.859608, 1.990245, 2.588878 }, - { 2.269440, 0.004664, 2.015026 }, - { 2.292795, 0.086003, 1.961748 }, - { 2.266981, 0.028052, 2.112221 }, - { 0.978350, 1.814540, 1.887908 }, - { 1.016409, 1.901488, 1.919396 }, - { 0.900506, 1.832099, 1.827642 }, - { 1.043390, 1.175341, 1.906444 }, - { 1.099585, 1.238650, 1.959679 }, - { 0.975010, 1.133260, 1.966055 }, - { 2.016893, 0.274093, 2.004319 }, - { 2.071563, 0.340099, 2.055840 }, - { 2.024768, 0.293409, 1.906518 }, - { 0.200210, 1.231970, 1.834713 }, - { 0.114839, 1.184264, 1.855594 }, - { 0.188948, 1.285302, 1.750875 }, - { 2.729975, 1.523368, 1.494243 }, - { 2.786119, 1.553298, 1.571393 }, - { 2.644035, 1.574497, 1.493741 }, - { 0.654823, 2.344026, 0.041906 }, - { 0.585582, 2.332462, -0.029311 }, - { 0.740286, 2.375393, 0.000528 }, - { 3.021982, 2.593565, 2.621302 }, - { 2.989764, 2.499790, 2.634267 }, - { 3.017212, 2.642770, 2.708228 }, - { 2.487491, 2.587543, 0.588152 }, - { 2.540926, 2.508060, 0.559391 }, - { 2.491371, 2.596063, 0.687713 }, - { 0.858188, 2.209867, 1.713786 }, - { 0.822392, 2.294693, 1.752813 }, - { 0.919970, 2.231431, 1.638169 }, - { 2.596792, 1.253523, 0.653627 }, - { 2.639966, 1.236539, 0.565041 }, - { 2.592499, 1.168156, 0.705531 }, - { 1.557444, 1.249902, 0.754581 }, - { 1.590664, 1.171004, 0.702893 }, - { 1.458703, 1.241710, 0.768116 }, - { 0.474497, 2.224022, 0.619046 }, - { 0.446543, 2.260459, 0.707877 }, - { 0.480869, 2.124369, 0.624402 }, - { 0.761041, 1.590794, 2.432924 }, - { 0.791242, 1.685785, 2.440954 }, - { 0.663172, 1.588543, 2.412513 }, - { 0.836284, 1.482214, 2.190881 }, - { 0.850232, 1.384275, 2.205489 }, - { 0.787473, 1.520964, 2.269085 }, - { 2.454650, 0.391488, 2.726185 }, - { 2.367849, 0.341863, 2.724489 }, - { 2.440428, 0.482185, 2.765830 }, - { 2.354491, 0.123748, 1.086280 }, - { 2.373650, 0.056337, 1.014945 }, - { 2.440302, 0.152735, 1.128663 }, - { 2.992918, 1.513766, 2.387696 }, - { 2.906224, 1.543682, 2.347829 }, - { 2.987283, 1.518885, 2.487406 }, - { 1.227082, 2.282968, 2.976912 }, - { 1.164560, 2.261041, 3.051813 }, - { 1.316651, 2.307128, 3.014247 }, - { 1.518608, 0.153309, 1.856854 }, - { 1.447277, 0.199556, 1.909514 }, - { 1.606102, 0.199449, 1.871548 }, - { 2.587957, 0.288841, 2.468338 }, - { 2.578525, 0.296796, 2.567574 }, - { 2.606517, 0.193603, 2.444146 }, - { 0.144688, 1.415405, 1.610001 }, - { 0.207284, 1.450562, 1.540389 }, - { 0.085255, 1.489291, 1.641759 }, - { 2.748672, 1.594337, 2.271072 }, - { 2.673511, 1.622680, 2.330631 }, - { 2.718247, 1.596183, 2.175830 }, - { 0.410163, 0.619010, 2.435827 }, - { 0.345484, 0.681869, 2.392637 }, - { 0.503603, 0.646896, 2.413665 }, - { 0.534691, 0.343823, 1.325729 }, - { 0.632028, 0.338918, 1.348121 }, - { 0.500601, 0.435795, 1.345198 }, - { 2.461049, 0.820135, 0.965838 }, - { 2.536165, 0.820911, 1.031846 }, - { 2.421632, 0.728344, 0.961273 }, - { 0.531212, 2.220300, 0.236689 }, - { 0.502904, 2.296693, 0.294679 }, - { 0.574186, 2.255658, 0.153605 }, - { 1.655506, 2.833838, 2.317040 }, - { 1.668580, 2.830497, 2.416125 }, - { 1.602969, 2.915483, 2.293083 }, - { 1.288110, 2.656172, 2.952423 }, - { 1.277223, 2.634069, 2.855505 }, - { 1.368445, 2.608857, 2.988584 }, - { 2.348524, 2.179906, 2.595979 }, - { 2.372646, 2.102011, 2.653862 }, - { 2.259984, 2.216541, 2.624589 }, - { 1.695517, 0.551448, 0.805462 }, - { 1.699774, 0.609314, 0.724017 }, - { 1.704642, 0.455524, 0.778714 }, - { 2.106596, 1.916632, 1.923212 }, - { 2.155546, 1.961234, 1.998142 }, - { 2.032239, 1.861051, 1.960386 }, - { 2.447050, 2.038526, 1.664823 }, - { 2.350761, 2.065299, 1.668234 }, - { 2.484148, 2.058980, 1.574239 }, - { 2.449344, 1.569436, 1.950703 }, - { 2.437787, 1.493630, 1.886517 }, - { 2.546473, 1.580996, 1.971496 }, - { 2.112171, 0.408380, 1.794677 }, - { 2.158942, 0.496119, 1.805372 }, - { 2.078496, 0.399767, 1.700912 }, - { 2.692511, 0.417154, 0.512240 }, - { 2.679476, 0.365314, 0.427725 }, - { 2.621964, 0.487674, 0.519306 }, - { 0.435488, 2.780530, 1.586002 }, - { 0.420283, 2.877527, 1.567019 }, - { 0.435612, 2.729368, 1.500080 }, - { 1.115003, 1.717126, 0.837236 }, - { 1.203147, 1.677245, 0.811938 }, - { 1.068973, 1.751023, 0.755185 }, - { 1.856343, 0.616824, 2.343989 }, - { 1.796548, 0.622851, 2.264063 }, - { 1.904818, 0.529366, 2.342835 }, - { 2.604397, 0.261200, 2.905175 }, - { 2.528620, 0.244919, 2.968362 }, - { 2.569499, 0.303156, 2.821379 }, - { 2.983071, 1.836011, 0.408545 }, - { 2.941255, 1.922312, 0.380198 }, - { 2.911503, 1.771495, 0.435298 }, - { 0.284846, 1.004775, 0.159867 }, - { 0.340818, 1.016814, 0.241856 }, - { 0.297717, 1.083015, 0.098934 }, - { 0.192126, 0.793038, 0.011385 }, - { 0.230558, 0.870973, 0.060874 }, - { 0.241567, 0.780506, -0.074630 }, - { 2.563812, 1.647993, 2.692657 }, - { 2.622485, 1.725166, 2.717190 }, - { 2.503455, 1.674583, 2.617490 }, - { 2.529260, 2.046808, 0.776094 }, - { 2.471748, 2.053308, 0.857642 }, - { 2.544468, 2.138278, 0.738651 }, - { 1.521366, 2.552599, 3.064763 }, - { 1.526632, 2.463583, 3.110023 }, - { 1.534993, 2.625151, 3.132221 }, - { 0.511749, 0.923074, 2.208753 }, - { 0.447660, 0.998092, 2.192473 }, - { 0.496390, 0.850876, 2.141288 }, - { 2.117688, 1.781807, 0.783134 }, - { 2.208797, 1.813138, 0.809922 }, - { 2.055770, 1.788578, 0.861366 }, - { 1.652780, 2.093001, 2.754505 }, - { 1.554431, 2.085575, 2.771006 }, - { 1.698800, 2.011709, 2.790196 }, - { 1.737177, 1.179170, 2.904903 }, - { 1.737840, 1.107564, 2.974704 }, - { 1.642971, 1.207781, 2.887392 }, - { 2.608930, 0.790629, 1.194068 }, - { 2.528547, 0.828235, 1.240158 }, - { 2.684912, 0.785017, 1.258839 }, - { 1.698150, 0.265894, 0.685113 }, - { 1.679547, 0.256862, 0.782952 }, - { 1.680976, 0.178467, 0.639707 }, - { 1.062092, 1.101304, 1.495332 }, - { 1.047507, 1.009579, 1.532398 }, - { 0.976651, 1.135380, 1.456105 }, - { 2.481560, 2.004994, 0.118148 }, - { 2.554321, 1.938467, 0.101419 }, - { 2.482028, 2.031356, 0.214610 }, - { 1.923369, 2.539567, 0.556425 }, - { 1.838167, 2.585092, 0.530578 }, - { 1.973136, 2.512668, 0.473965 }, - { 2.710513, 1.598229, 2.008108 }, - { 2.724888, 1.696756, 2.017366 }, - { 2.797808, 1.553485, 1.988678 }, - { 2.942739, 0.227199, 0.186899 }, - { 3.020717, 0.170557, 0.160232 }, - { 2.975626, 0.309638, 0.232967 }, - { 1.274750, 0.014932, 2.831151 }, - { 1.277539, -0.019282, 2.737227 }, - { 1.311231, -0.054613, 2.893059 }, - { 0.138548, 2.393702, 0.543185 }, - { 0.060579, 2.445383, 0.507829 }, - { 0.146433, 2.307200, 0.493635 }, - { 0.194759, 3.076992, 1.308021 }, - { 0.227728, 3.149223, 1.247228 }, - { 0.123684, 3.024177, 1.261557 }, - { 1.133502, 0.030873, 0.173195 }, - { 1.148695, -0.014224, 0.261146 }, - { 1.211249, 0.090184, 0.152275 }, - { 2.722824, 2.558867, 2.789907 }, - { 2.702571, 2.600501, 2.701270 }, - { 2.696187, 2.462493, 2.788332 }, - { 1.307419, 2.352714, 2.242314 }, - { 1.405996, 2.369378, 2.240105 }, - { 1.287675, 2.277863, 2.305619 }, - { 2.808640, 0.090952, 2.094578 }, - { 2.837316, 0.064602, 2.002473 }, - { 2.873024, 0.053768, 2.161452 }, - { 2.610557, 2.119816, 2.296930 }, - { 2.516683, 2.088381, 2.311053 }, - { 2.673361, 2.042581, 2.306444 }, - { 2.067765, 0.663952, 0.224417 }, - { 2.149722, 0.619553, 0.188201 }, - { 2.062731, 0.649171, 0.323191 }, - { 2.410587, 1.939136, 0.539274 }, - { 2.329640, 1.983980, 0.501371 }, - { 2.433478, 1.980572, 0.627359 }, - { 0.266830, 2.589002, 0.694311 }, - { 0.229373, 2.506770, 0.651476 }, - { 0.213318, 2.611497, 0.775739 }, - { 2.665478, 0.247924, 0.257674 }, - { 2.758689, 0.235464, 0.223669 }, - { 2.619919, 0.159088, 0.263375 }, - { 1.391624, 1.635214, 0.824559 }, - { 1.443687, 1.587036, 0.895045 }, - { 1.373363, 1.573131, 0.748321 }, - { 0.915468, 0.823852, 0.413096 }, - { 0.943532, 0.769916, 0.492490 }, - { 0.954097, 0.783595, 0.330107 }, - { 2.422248, 2.909883, 1.103557 }, - { 2.418386, 2.919563, 1.203012 }, - { 2.330025, 2.917723, 1.065696 }, - { 1.408309, 2.936097, 0.154872 }, - { 1.501433, 2.955528, 0.185701 }, - { 1.357769, 2.890516, 0.228139 }, - { 1.601230, 0.015841, 0.607280 }, - { 1.583071, 0.049227, 0.514783 }, - { 1.529356, 0.047873, 0.668990 }, - { 2.387127, 2.249286, 0.604177 }, - { 2.339117, 2.308859, 0.668568 }, - { 2.320551, 2.194928, 0.553061 }, - { 0.006317, 0.397187, 2.468096 }, - { 0.086350, 0.369685, 2.521373 }, - { -0.067122, 0.330651, 2.481501 }, - { 2.414588, 0.649050, 2.818040 }, - { 2.413447, 0.726390, 2.881421 }, - { 2.379346, 0.678284, 2.729139 }, - { 1.620984, 0.646636, 0.554546 }, - { 1.555752, 0.571955, 0.541602 }, - { 1.571288, 0.732489, 0.567183 }, - { 1.388431, 1.496548, 2.555467 }, - { 1.346007, 1.491565, 2.645885 }, - { 1.459663, 1.566733, 2.555890 }, - { 0.135346, 0.027221, 0.692454 }, - { 0.110535, 0.085136, 0.614799 }, - { 0.229755, -0.004019, 0.681917 }, - { 0.356113, 1.759265, 2.006375 }, - { 0.428524, 1.828103, 2.010617 }, - { 0.357217, 1.715211, 1.916609 }, - { 2.784840, 1.337893, 0.048133 }, - { 2.833571, 1.258874, 0.085296 }, - { 2.850191, 1.410781, 0.027721 }, - { 2.732356, 2.248891, 1.483486 }, - { 2.798089, 2.308929, 1.529034 }, - { 2.645377, 2.251207, 1.532774 }, - { 1.609259, 2.461869, 0.761605 }, - { 1.515557, 2.495474, 0.771124 }, - { 1.626281, 2.390800, 0.829865 }, - { 3.034595, 2.376378, 1.030368 }, - { 3.108631, 2.326860, 1.075828 }, - { 3.072930, 2.450813, 0.975689 }, - { 3.001063, 2.956280, 2.449605 }, - { 2.932654, 2.883470, 2.445274 }, - { 3.020729, 2.977897, 2.545239 }, - { 0.973131, 1.398826, 3.027256 }, - { 1.048479, 1.453925, 3.063128 }, - { 0.886059, 1.441609, 3.051508 }, - { 1.075531, 2.444457, 0.635589 }, - { 1.139902, 2.479480, 0.703631 }, - { 0.990821, 2.497460, 0.639456 }, - { 1.866464, 1.096888, 1.554833 }, - { 1.941039, 1.123887, 1.615740 }, - { 1.789922, 1.062351, 1.609132 }, - { 1.591678, 1.105215, 2.043568 }, - { 1.653395, 1.145689, 1.976092 }, - { 1.645280, 1.060640, 2.115260 }, - { 2.619927, 0.227980, 1.174340 }, - { 2.633047, 0.294780, 1.101090 }, - { 2.665581, 0.142407, 1.149987 }, - { 1.916667, 0.415190, 0.590627 }, - { 1.825708, 0.378396, 0.609931 }, - { 1.983344, 0.373288, 0.652258 }, - { 1.200849, 1.841071, 1.389818 }, - { 1.114525, 1.790768, 1.394038 }, - { 1.256145, 1.819190, 1.470215 }, - { 2.221784, 1.766977, 3.004150 }, - { 2.225336, 1.794523, 3.100216 }, - { 2.288916, 1.694712, 2.987690 }, - { 1.120165, 3.008868, 2.322689 }, - { 1.029789, 3.031427, 2.359063 }, - { 1.133909, 2.909893, 2.326577 }, - { 0.405986, 1.997015, 2.356493 }, - { 0.366114, 1.907130, 2.338302 }, - { 0.345189, 2.068190, 2.321310 }, - { 2.326232, 0.162329, 0.556844 }, - { 2.317494, 0.256924, 0.525610 }, - { 2.412060, 0.151587, 0.607026 }, - { 1.349474, 2.909042, 3.002070 }, - { 1.354029, 2.915883, 3.101732 }, - { 1.313151, 2.819469, 2.976431 }, - { 1.677748, 2.890286, 2.981716 }, - { 1.584536, 2.854118, 2.979874 }, - { 1.739825, 2.820638, 3.017710 }, - { 2.146479, 1.045232, 0.950271 }, - { 2.062776, 1.035080, 1.004035 }, - { 2.225747, 1.042585, 1.011178 }, - { 0.038713, 0.203819, 0.461963 }, - { 0.080467, 0.204316, 0.371099 }, - { 0.022739, 0.297910, 0.491824 }, - { 1.344154, 0.934719, 3.048288 }, - { 1.298501, 0.975815, 3.127199 }, - { 1.292224, 0.854988, 3.017525 }, - { 1.876736, 0.670754, 0.506472 }, - { 1.922832, 0.582605, 0.516712 }, - { 1.777974, 0.657982, 0.515576 }, - { 1.547024, 1.257100, 1.494394 }, - { 1.462871, 1.279845, 1.445394 }, - { 1.595454, 1.184510, 1.445555 }, - { 0.837046, 1.662106, 0.882764 }, - { 0.927946, 1.694579, 0.908893 }, - { 0.770410, 1.690515, 0.951702 }, - { 2.905724, 1.433934, 1.956678 }, - { 2.901017, 1.350620, 1.901572 }, - { 2.982411, 1.427385, 2.020522 }, - { 1.082721, 1.574084, 1.538980 }, - { 1.118780, 1.653944, 1.587168 }, - { 1.041923, 1.603015, 1.452386 }, - { 0.973517, 1.950813, 0.715403 }, - { 0.983211, 2.013477, 0.638077 }, - { 0.883009, 1.908370, 0.712770 }, - { 2.047444, 1.846347, 2.788275 }, - { 2.105859, 1.796484, 2.852317 }, - { 2.098174, 1.864406, 2.704012 }, - { 1.472286, 0.407694, 0.463299 }, - { 1.403985, 0.383358, 0.532166 }, - { 1.548848, 0.343549, 0.468160 }, - { 1.523722, 2.012941, 1.058531 }, - { 1.538378, 2.080087, 1.131171 }, - { 1.463127, 1.940637, 1.091702 }, - { 2.094622, 0.765399, 0.870291 }, - { 2.123104, 0.847060, 0.920494 }, - { 2.004127, 0.736782, 0.901781 }, - { 1.360037, 1.461451, 1.615762 }, - { 1.375715, 1.426828, 1.708258 }, - { 1.267388, 1.498526, 1.609306 }, - { 1.754323, 2.881247, 0.755875 }, - { 1.740556, 2.861699, 0.852975 }, - { 1.710649, 2.968212, 0.732860 }, - { 2.597326, 2.339246, 0.463067 }, - { 2.688913, 2.333021, 0.502729 }, - { 2.530638, 2.300986, 0.527011 }, - { 2.404012, 2.888762, 1.379749 }, - { 2.377619, 2.981254, 1.407111 }, - { 2.362718, 2.822465, 1.442195 }, - { 2.682210, 0.752891, 0.246149 }, - { 2.588032, 0.751670, 0.279748 }, - { 2.719633, 0.845183, 0.255187 }, - { 1.147989, 0.504369, 0.806579 }, - { 1.188565, 0.445977, 0.736266 }, - { 1.068069, 0.458769, 0.845737 }, - { 0.882417, 2.859277, 0.450074 }, - { 0.828696, 2.842740, 0.532782 }, - { 0.820924, 2.879784, 0.373929 }, - { 2.310841, 1.485608, 2.189112 }, - { 2.390981, 1.454864, 2.240419 }, - { 2.338739, 1.513314, 2.097166 }, - { 0.048620, 1.439459, 2.985076 }, - { 0.078551, 1.439376, 2.889661 }, - { 0.058812, 1.347612, 3.023289 }, - { 2.685128, 3.096664, 1.076209 }, - { 2.634155, 3.017488, 1.109867 }, - { 2.636042, 3.137695, 0.999352 }, - { 2.955404, 1.555187, 2.648529 }, - { 2.871594, 1.525579, 2.694345 }, - { 3.034353, 1.532617, 2.705606 }, - { 0.064303, 2.480490, 2.970512 }, - { 0.081989, 2.494919, 3.067872 }, - { -0.018484, 2.529915, 2.943987 }, - { 2.482995, 0.044725, 0.867955 }, - { 2.455494, -0.036642, 0.816739 }, - { 2.538862, 0.103589, 0.809526 }, - { 2.017835, 2.999311, 2.452181 }, - { 2.056715, 2.908900, 2.434452 }, - { 1.920387, 2.998675, 2.429744 }, - { 0.869423, 2.167004, 3.082747 }, - { 0.954671, 2.177259, 3.134008 }, - { 0.864372, 2.237510, 3.012012 }, - { 1.589117, 0.399666, 2.413510 }, - { 1.674099, 0.378754, 2.461891 }, - { 1.570287, 0.497660, 2.420041 }, - { 0.440864, 0.611366, 1.385214 }, - { 0.366708, 0.650546, 1.330755 }, - { 0.527868, 0.625182, 1.337891 }, - { 2.713192, 1.529373, 1.085268 }, - { 2.693629, 1.627372, 1.088945 }, - { 2.710758, 1.498439, 0.990204 }, - { 2.066839, 1.149465, 2.402028 }, - { 1.978751, 1.170214, 2.359483 }, - { 2.063437, 1.058285, 2.442951 }, - { 0.718140, 1.556839, 1.676953 }, - { 0.794749, 1.522176, 1.731078 }, - { 0.701074, 1.652454, 1.700755 }, - { 1.851286, 1.748633, 1.205296 }, - { 1.906319, 1.667628, 1.185058 }, - { 1.903282, 1.810358, 1.264343 }, - { 0.690798, 2.820113, 0.892873 }, - { 0.624258, 2.764246, 0.843363 }, - { 0.659978, 2.832952, 0.987135 }, - { 0.700392, 2.971775, 0.643684 }, - { 0.629248, 2.966450, 0.573611 }, - { 0.667850, 2.928206, 0.727605 }, - { 0.224944, 2.412756, 2.411288 }, - { 0.179940, 2.480028, 2.352558 }, - { 0.321229, 2.437351, 2.422438 }, - { 0.931960, 1.088532, 1.085458 }, - { 0.948257, 1.069581, 1.182284 }, - { 0.943490, 1.186361, 1.068238 }, - { 0.665315, 1.482798, 1.205282 }, - { 0.623395, 1.392477, 1.196078 }, - { 0.754802, 1.482720, 1.160649 }, - { 2.090545, 2.389004, 2.282603 }, - { 2.040173, 2.355573, 2.362259 }, - { 2.025895, 2.417626, 2.211884 }, - { 0.586392, 2.277950, 2.330457 }, - { 0.544270, 2.318000, 2.249084 }, - { 0.583852, 2.178214, 2.323650 }, - { 0.397428, 2.598797, 1.378318 }, - { 0.467494, 2.548450, 1.327762 }, - { 0.332320, 2.534269, 1.418282 }, - { 0.769337, 0.909264, 1.677104 }, - { 0.851592, 0.904461, 1.733770 }, - { 0.689510, 0.924296, 1.735428 }, - { 2.809384, 0.362243, 1.792651 }, - { 2.906450, 0.384960, 1.800543 }, - { 2.770939, 0.407692, 1.712300 }, - { 2.165909, 0.965344, 0.397730 }, - { 2.089549, 0.933174, 0.453714 }, - { 2.248087, 0.972319, 0.454283 }, - { 3.029223, 1.963090, 2.255361 }, - { 3.063521, 2.056860, 2.260912 }, - { 3.032822, 1.931843, 2.160436 }, - { 2.290786, 0.279773, 2.425314 }, - { 2.272727, 0.248542, 2.518580 }, - { 2.389205, 0.277242, 2.407783 }, - { 2.887936, 0.900624, 2.678907 }, - { 2.848443, 0.883810, 2.588588 }, - { 2.939101, 0.986531, 2.677450 }, - { 2.724532, 1.007735, 0.316482 }, - { 2.638163, 1.056986, 0.305776 }, - { 2.737244, 0.983237, 0.412598 }, - { 2.046399, 1.071255, 1.952165 }, - { 2.071263, 1.164937, 1.976772 }, - { 2.077369, 1.008654, 2.023734 }, - { 0.170790, 2.227231, 2.943018 }, - { 0.126575, 2.314910, 2.961923 }, - { 0.105750, 2.152970, 2.958991 }, - { 1.361693, 2.771602, 1.982177 }, - { 1.454761, 2.773405, 1.945637 }, - { 1.342410, 2.858072, 2.028557 }, - { 2.982726, 0.757058, 1.738590 }, - { 3.078254, 0.782233, 1.723078 }, - { 2.946703, 0.711262, 1.657319 }, - { 2.418788, 0.252780, 1.386757 }, - { 2.352642, 0.300740, 1.329098 }, - { 2.499443, 0.229291, 1.332506 }, - { 1.608286, 2.595250, 2.794006 }, - { 1.645863, 2.503744, 2.779360 }, - { 1.562406, 2.598627, 2.882796 }, - { 1.508130, 0.999554, 2.425027 }, - { 1.547857, 0.994937, 2.516681 }, - { 1.431312, 1.063578, 2.425178 }, - { 0.403062, 0.456581, 0.079987 }, - { 0.443234, 0.406243, 0.003487 }, - { 0.303384, 0.455265, 0.072083 }, - { 2.772199, 1.911678, 2.353951 }, - { 2.729955, 1.826940, 2.321781 }, - { 2.870697, 1.908343, 2.337011 }, - { 0.267947, 2.608428, 2.130318 }, - { 0.325039, 2.689867, 2.140717 }, - { 0.324975, 2.531033, 2.102786 }, - { 0.271482, 2.897455, 1.935251 }, - { 0.186640, 2.909345, 1.986831 }, - { 0.341018, 2.856649, 1.994408 }, - { 0.420612, 1.093519, 1.906373 }, - { 0.340253, 1.144399, 1.875491 }, - { 0.424876, 1.005758, 1.858624 }, - { 0.317469, 2.961369, 0.908774 }, - { 0.344220, 2.899485, 0.982631 }, - { 0.236408, 3.013052, 0.936305 }, - { 1.331593, 1.232370, 2.476098 }, - { 1.246807, 1.247953, 2.425416 }, - { 1.387810, 1.315023, 2.473236 }, - { 1.653708, 2.990313, 0.221008 }, - { 1.729954, 2.996775, 0.285388 }, - { 1.680305, 3.031054, 0.133642 }, - { 0.590628, 1.387522, 0.466964 }, - { 0.630802, 1.407555, 0.556321 }, - { 0.620713, 1.456152, 0.400747 }, - { 2.905997, 0.221663, 2.459906 }, - { 2.819336, 0.267701, 2.440662 }, - { 2.896627, 0.166170, 2.542566 }, - { 3.093628, 2.977978, 2.705256 }, - { 3.167925, 3.044386, 2.696902 }, - { 3.071771, 2.964390, 2.801887 }, - { 2.165292, 1.291783, 2.041764 }, - { 2.234435, 1.220242, 2.031709 }, - { 2.185992, 1.347037, 2.122501 }, - { 2.252015, 0.402395, 1.221932 }, - { 2.285112, 0.496702, 1.225218 }, - { 2.179675, 0.394827, 1.153306 }, - { 2.104356, 0.137080, 1.189404 }, - { 2.195319, 0.128762, 1.148705 }, - { 2.079462, 0.050753, 1.233312 }, - { 2.148437, 0.707200, 3.015197 }, - { 2.198806, 0.754869, 3.087243 }, - { 2.051558, 0.731376, 3.020663 }, - { 1.850478, 1.598817, 3.013910 }, - { 1.874091, 1.567314, 3.105834 }, - { 1.850247, 1.521043, 2.951052 }, - { 1.984243, 1.101537, 0.205597 }, - { 2.056039, 1.050969, 0.253432 }, - { 2.016996, 1.193515, 0.183984 }, - { 0.819823, 2.184803, 2.627983 }, - { 0.910067, 2.222214, 2.649346 }, - { 0.818973, 2.151619, 2.533653 }, - { 0.680880, 0.100328, 2.990090 }, - { 0.748260, 0.091873, 2.916685 }, - { 0.673872, 0.013431, 3.039078 }, - { 2.347672, 1.066007, 2.070294 }, - { 2.435627, 1.018893, 2.063654 }, - { 2.327837, 1.086215, 2.166201 }, - { 1.111822, 1.814359, 2.252410 }, - { 1.077790, 1.776269, 2.338381 }, - { 1.095407, 1.749261, 2.178296 }, - { 2.873311, 1.875343, 0.918630 }, - { 2.944104, 1.911954, 0.858231 }, - { 2.784531, 1.880520, 0.872899 }, - { 2.101428, 2.550539, 2.746625 }, - { 2.078013, 2.646820, 2.760104 }, - { 2.189270, 2.531164, 2.790308 }, - { 2.827466, 0.083838, 2.684289 }, - { 2.743385, 0.029836, 2.680525 }, - { 2.855318, 0.095556, 2.779614 }, - { 2.643409, 2.459431, 1.183392 }, - { 2.631575, 2.376139, 1.129333 }, - { 2.581379, 2.457376, 1.261802 }, - { 0.210477, 1.616716, 0.215712 }, - { 0.227327, 1.627602, 0.313679 }, - { 0.191301, 1.520642, 0.195659 }, - { 2.595851, 3.085082, 0.245145 }, - { 2.533216, 3.108680, 0.170849 }, - { 2.632559, 2.993318, 0.229920 }, - { 0.948067, 1.831565, 0.021233 }, - { 0.912134, 1.907261, 0.075814 }, - { 0.938805, 1.746188, 0.072468 }, - { 1.953344, 2.247947, 1.017599 }, - { 1.909073, 2.312925, 0.955810 }, - { 1.960324, 2.158811, 0.972811 }, - { 1.222649, 2.766274, 0.625820 }, - { 1.132619, 2.728772, 0.647918 }, - { 1.292364, 2.720128, 0.680687 }, - { 1.697084, 1.491664, 2.240765 }, - { 1.608414, 1.453049, 2.215338 }, - { 1.683516, 1.566071, 2.306182 }, - { 1.267412, 1.311498, 2.741722 }, - { 1.282870, 1.251771, 2.663022 }, - { 1.169226, 1.326331, 2.753535 }, - { 0.703434, 0.631065, 1.342521 }, - { 0.757236, 0.648969, 1.424891 }, - { 0.755720, 0.658720, 1.261889 }, - { 0.536418, 0.871703, 1.821272 }, - { 0.506921, 0.828597, 1.906547 }, - { 0.501439, 0.819320, 1.743603 }, - { 2.033586, 1.894688, 1.361921 }, - { 2.053905, 1.813031, 1.415951 }, - { 2.102318, 1.964908, 1.380502 }, - { 1.353145, 0.749155, 2.700183 }, - { 1.340584, 0.768015, 2.602784 }, - { 1.423395, 0.809983, 2.737126 }, - { 1.757646, 3.040187, 1.185496 }, - { 1.805834, 2.953766, 1.199967 }, - { 1.789142, 3.082058, 1.100321 }, - { 2.692199, 2.835351, 0.825364 }, - { 2.663609, 2.776601, 0.901068 }, - { 2.611627, 2.876881, 0.783133 }, - { 2.753498, 2.840923, 0.324355 }, - { 2.736860, 2.782748, 0.244738 }, - { 2.680602, 2.827267, 0.391435 }, - { 0.196329, 2.621545, 2.569990 }, - { 0.219355, 2.524588, 2.578307 }, - { 0.108105, 2.638733, 2.613821 }, - { 2.345007, 1.825788, 1.374116 }, - { 2.272672, 1.793851, 1.435333 }, - { 2.379912, 1.913637, 1.406738 }, - { 0.596710, 0.509863, 2.871939 }, - { 0.526640, 0.561688, 2.822905 }, - { 0.556514, 0.426024, 2.908751 }, - { 2.937274, 0.823236, 1.996167 }, - { 2.937670, 0.813596, 1.896634 }, - { 2.911096, 0.736251, 2.037979 }, - { 0.579374, 1.320692, 0.011389 }, - { 0.634136, 1.240102, 0.033891 }, - { 0.484056, 1.293558, -0.001960 }, - { 2.278243, 2.412097, 0.787639 }, - { 2.368768, 2.449098, 0.808522 }, - { 2.240378, 2.368551, 0.869309 }, - { 0.391627, 1.711143, 0.025375 }, - { 0.332230, 1.678111, 0.098730 }, - { 0.390472, 1.645887, -0.050389 }, - { 0.153753, 2.467941, 1.820145 }, - { 0.065625, 2.429276, 1.792973 }, - { 0.150971, 2.567416, 1.810297 }, - { 2.843451, 0.422126, 2.906952 }, - { 2.775335, 0.354829, 2.935786 }, - { 2.799691, 0.511419, 2.896375 }, - { 1.970457, 1.649264, 2.404565 }, - { 2.013029, 1.699928, 2.329594 }, - { 1.985128, 1.551262, 2.391131 }, - { 1.342607, 1.643091, 2.334386 }, - { 1.344545, 1.563513, 2.394914 }, - { 1.248079, 1.673291, 2.322043 }, - { 0.748739, 1.133236, 0.071356 }, - { 0.842917, 1.127034, 0.038310 }, - { 0.747734, 1.124634, 0.170981 }, - { 1.378131, 1.410352, 1.877753 }, - { 1.319542, 1.407747, 1.958750 }, - { 1.424860, 1.322530, 1.867574 }, - { 2.379939, 1.693036, 0.436722 }, - { 2.413363, 1.778852, 0.475690 }, - { 2.340060, 1.636823, 0.509177 }, - { 0.560335, 1.301357, 2.831908 }, - { 0.656147, 1.325504, 2.816512 }, - { 0.537359, 1.315835, 2.928149 }, - { 2.308699, 2.450235, 2.131759 }, - { 2.320931, 2.549287, 2.125504 }, - { 2.229118, 2.430013, 2.188837 }, - { 1.398964, 0.129485, 0.101708 }, - { 1.406581, 0.030972, 0.117107 }, - { 1.430994, 0.151393, 0.009545 }, - { 2.738661, 1.810796, 1.150217 }, - { 2.785875, 1.826236, 1.063428 }, - { 2.803245, 1.821952, 1.225745 }, - { 1.834855, 1.243843, 2.347878 }, - { 1.784425, 1.296402, 2.279364 }, - { 1.812100, 1.277635, 2.439203 }, - { 2.675870, 1.821318, 0.707845 }, - { 2.624071, 1.899672, 0.742160 }, - { 2.626939, 1.736877, 0.729653 }, - { 2.769887, 2.202680, 2.007300 }, - { 2.822160, 2.284730, 2.030436 }, - { 2.675095, 2.214055, 2.037049 }, - { 1.998308, 2.423041, 0.279446 }, - { 1.928540, 2.367313, 0.234427 }, - { 2.088992, 2.387066, 0.257485 }, - { 2.612892, 0.331665, 0.870959 }, - { 2.614312, 0.422865, 0.911954 }, - { 2.693229, 0.320122, 0.812541 }, - { 1.438447, 2.473494, 1.915666 }, - { 1.459389, 2.449059, 2.010347 }, - { 1.449352, 2.572151, 1.903508 }, - { 0.869607, 0.994845, 2.380191 }, - { 0.960289, 0.969060, 2.413537 }, - { 0.816006, 0.912361, 2.362208 }, - { 2.262026, 1.572083, 0.674023 }, - { 2.207234, 1.647739, 0.709715 }, - { 2.201615, 1.503071, 0.634175 }, - { 0.029213, 2.539434, 2.193714 }, - { 0.114704, 2.573874, 2.154917 }, - { -0.041214, 2.610128, 2.187201 }, - { 2.804363, 0.979878, 0.585511 }, - { 2.878881, 1.037113, 0.551286 }, - { 2.815526, 0.886603, 0.551230 }, - { 1.145669, 0.191337, 1.809638 }, - { 1.136214, 0.202391, 1.710702 }, - { 1.055125, 0.181165, 1.850847 }, - { 1.799933, 2.204886, 1.265283 }, - { 1.721729, 2.267174, 1.263213 }, - { 1.858550, 2.222334, 1.186166 }, - { 2.768473, 1.887750, 2.008596 }, - { 2.685808, 1.884735, 1.952404 }, - { 2.781906, 1.980614, 2.043174 }, - { 0.566042, 0.942291, 2.780672 }, - { 0.542564, 1.003858, 2.705451 }, - { 0.618895, 0.865111, 2.745320 }, - { 1.440484, 2.308258, 0.440554 }, - { 1.345608, 2.311138, 0.409085 }, - { 1.451129, 2.234898, 0.507674 }, - { 2.099174, 2.113051, 2.937382 }, - { 2.064708, 2.019650, 2.927986 }, - { 2.084658, 2.162707, 2.851804 }, - { 0.640344, 1.990762, 1.382271 }, - { 0.613247, 2.082472, 1.353029 }, - { 0.567632, 1.925826, 1.359992 }, - { 1.005877, 1.535225, 0.537525 }, - { 1.087595, 1.584022, 0.506849 }, - { 1.032672, 1.459432, 0.597003 }, - { 1.001243, 2.787001, 1.696773 }, - { 0.992437, 2.688644, 1.712534 }, - { 0.910309, 2.828442, 1.693079 }, - { 0.987802, 1.110389, 3.055721 }, - { 1.065605, 1.081580, 3.111549 }, - { 0.999141, 1.206273, 3.029689 }, - { 0.559374, 1.591763, 1.450101 }, - { 0.607457, 1.568462, 1.534631 }, - { 0.618799, 1.573391, 1.371800 }, - { 1.478474, 0.101704, 1.588815 }, - { 1.486885, 0.115724, 1.687469 }, - { 1.567854, 0.077935, 1.550783 }, - { 1.197401, 2.030470, 2.891763 }, - { 1.204490, 2.130070, 2.886325 }, - { 1.101431, 2.004405, 2.902264 }, - { 2.593369, 2.916082, 3.009380 }, - { 2.501069, 2.936721, 2.976903 }, - { 2.647562, 2.878580, 2.934170 }, - { 1.874216, 0.910326, 1.799684 }, - { 1.928068, 0.986814, 1.835033 }, - { 1.784798, 0.943563, 1.769689 }, - { 1.120926, 0.186051, 2.975514 }, - { 1.169400, 0.130500, 2.907954 }, - { 1.157365, 0.279169, 2.974435 }, - { 1.743099, 0.329782, 2.034890 }, - { 1.692066, 0.296574, 2.114217 }, - { 1.836555, 0.294352, 2.038158 }, - { 1.657390, 1.879589, 1.841187 }, - { 1.717444, 1.958116, 1.826119 }, - { 1.702586, 1.796398, 1.808989 }, - { 1.300228, 2.270635, 0.841357 }, - { 1.295869, 2.196579, 0.908414 }, - { 1.228832, 2.337792, 0.861172 }, - { 1.948942, 0.107632, 2.195505 }, - { 1.962856, 0.009021, 2.186429 }, - { 1.980313, 0.153514, 2.112374 }, - { 0.592938, 2.832478, 1.152267 }, - { 0.595325, 2.932350, 1.156722 }, - { 0.497900, 2.801368, 1.152355 }, - { 3.028118, 1.151776, 1.025723 }, - { 3.094740, 1.221061, 1.053310 }, - { 2.957975, 1.193980, 0.968288 }, - { 1.833976, 0.982234, 0.013196 }, - { 1.883561, 1.039306, 0.078648 }, - { 1.885634, 0.976953, -0.072265 }, - { 1.798332, 1.244152, 1.851843 }, - { 1.884876, 1.234745, 1.802633 }, - { 1.723244, 1.251207, 1.786177 }, - { 2.873589, 1.201986, 1.817110 }, - { 2.927328, 1.201648, 1.732778 }, - { 2.906900, 1.130124, 1.878153 }, - { 0.577414, 0.140788, 1.536999 }, - { 0.611632, 0.171898, 1.625663 }, - { 0.652564, 0.138931, 1.471052 }, - { 0.479143, 3.039990, 0.297688 }, - { 0.403226, 3.001126, 0.245475 }, - { 0.521000, 2.968592, 0.353815 }, - { 2.581915, 1.009475, 0.768424 }, - { 2.672051, 0.990541, 0.729474 }, - { 2.554187, 0.933238, 0.826898 }, - { 2.285805, 1.798154, 0.177273 }, - { 2.371693, 1.842169, 0.151083 }, - { 2.293527, 1.762829, 0.270507 }, - { 0.216147, 3.103959, 2.689932 }, - { 0.206578, 3.176040, 2.621282 }, - { 0.297853, 3.049780, 2.670213 }, - { 0.686871, 1.890136, 2.775596 }, - { 0.662080, 1.936036, 2.860911 }, - { 0.605159, 1.878210, 2.719196 }, - { 1.069007, 2.995313, 3.029030 }, - { 1.073078, 3.066635, 3.099005 }, - { 1.160823, 2.978560, 2.993125 }, - { 2.694476, 1.837937, 0.085521 }, - { 2.644472, 1.755175, 0.111019 }, - { 2.791382, 1.826384, 0.107334 }, - { 1.563852, 0.853418, 2.911395 }, - { 1.602637, 0.770872, 2.952407 }, - { 1.488071, 0.886218, 2.967798 }, - { 0.460347, 2.801415, 2.155280 }, - { 0.542405, 2.813267, 2.099369 }, - { 0.486605, 2.790770, 2.251182 }, - { 1.067116, 0.828584, 1.118327 }, - { 1.017197, 0.895557, 1.063347 }, - { 1.147577, 0.797335, 1.067835 }, - { 2.248599, 1.379134, 0.873790 }, - { 2.293116, 1.393911, 0.785473 }, - { 2.293247, 1.303346, 0.921359 }, - { 0.023727, 1.461944, 2.107485 }, - { 0.039466, 1.452465, 2.205783 }, - { 0.056943, 1.551156, 2.076858 }, - { 0.890338, 1.285968, 0.873042 }, - { 0.805316, 1.245775, 0.839044 }, - { 0.933413, 1.339340, 0.800269 }, - { 2.648945, 1.437668, 0.287452 }, - { 2.699407, 1.401270, 0.209165 }, - { 2.675734, 1.388361, 0.370224 }, - { 0.390508, 3.056364, 2.334304 }, - { 0.374435, 3.116324, 2.255905 }, - { 0.317691, 2.988021, 2.339484 }, - { 2.941599, 2.289971, 2.678662 }, - { 3.039241, 2.269131, 2.673033 }, - { 2.912219, 2.286466, 2.774185 }, - { 1.199353, 2.918159, 1.497088 }, - { 1.269711, 2.966859, 1.548839 }, - { 1.118937, 2.904431, 1.554922 }, - { 2.948856, 0.470312, 1.096935 }, - { 2.985099, 0.380752, 1.071136 }, - { 3.024561, 0.531828, 1.118947 }, - { 2.489230, 1.274888, 2.457981 }, - { 2.575071, 1.260972, 2.408608 }, - { 2.489590, 1.220024, 2.541587 }, - { 1.644334, 1.202727, 0.331251 }, - { 1.631770, 1.123611, 0.271394 }, - { 1.635932, 1.174006, 0.426668 }, - { 0.669309, 2.003121, 2.315451 }, - { 0.730467, 1.954706, 2.378027 }, - { 0.574977, 1.974480, 2.332215 }, - { 2.284317, 1.482399, 1.602583 }, - { 2.203780, 1.434499, 1.567663 }, - { 2.260654, 1.530045, 1.687259 }, - { 0.527517, 2.701255, 2.395590 }, - { 0.572355, 2.743476, 2.474374 }, - { 0.501162, 2.607549, 2.418497 }, - { 2.691990, 1.782137, 1.668582 }, - { 2.622890, 1.751930, 1.602910 }, - { 2.728574, 1.870738, 1.640094 }, - { 1.221627, 1.403014, 2.134535 }, - { 1.177639, 1.339731, 2.198256 }, - { 1.151914, 1.458799, 2.089499 }, - { 1.276239, 1.209683, 0.830184 }, - { 1.274310, 1.109869, 0.824392 }, - { 1.270617, 1.237626, 0.926036 }, - { 0.816251, 2.909087, 3.046489 }, - { 0.901923, 2.953749, 3.020687 }, - { 0.771765, 2.961669, 3.118989 }, - { 0.533906, 1.223529, 1.303916 }, - { 0.569896, 1.156711, 1.238800 }, - { 0.578958, 1.211478, 1.392376 }, - { 1.683346, 2.144673, 2.139148 }, - { 1.741238, 2.072530, 2.177146 }, - { 1.613641, 2.103882, 2.080179 }, - { 2.875850, 0.044009, 1.250278 }, - { 2.911148, -0.036725, 1.297565 }, - { 2.805482, 0.016229, 1.184882 }, - { 1.784021, 0.926724, 0.326634 }, - { 1.855064, 0.984494, 0.286440 }, - { 1.826414, 0.857633, 0.385195 }, - { 1.704426, 1.630143, 0.792940 }, - { 1.672037, 1.613072, 0.699884 }, - { 1.668404, 1.559794, 0.854205 }, - { 0.766134, 2.421196, 2.059355 }, - { 0.809315, 2.345348, 2.108166 }, - { 0.752692, 2.497881, 2.122115 }, - { 0.871077, 2.182524, 2.154052 }, - { 0.810919, 2.153015, 2.228283 }, - { 0.962738, 2.145297, 2.168630 }, - { 1.865873, 1.349151, 0.032304 }, - { 1.827492, 1.323421, -0.056380 }, - { 1.964725, 1.334066, 0.031487 }, - { 2.222735, 1.008374, 1.670202 }, - { 2.286023, 1.057572, 1.610417 }, - { 2.274593, 0.951644, 1.734173 }, - { 1.293692, 2.083151, 1.808644 }, - { 1.358039, 2.082571, 1.885189 }, - { 1.324981, 2.019323, 1.738309 }, - { 2.875127, 0.361920, 0.728630 }, - { 2.927991, 0.446531, 0.735430 }, - { 2.818555, 0.364492, 0.646210 }, - { 0.560226, 1.918473, 2.025234 }, - { 0.614082, 1.999690, 2.002796 }, - { 0.606294, 1.866823, 2.097414 }, - { 0.116601, 2.287058, 2.040205 }, - { 0.135431, 2.341154, 1.958235 }, - { 0.072215, 2.344766, 2.108759 }, - { 1.731207, 1.627822, 1.774748 }, - { 1.743176, 1.560404, 1.701867 }, - { 1.758793, 1.587726, 1.862106 }, - { 2.955634, 2.730964, 0.905002 }, - { 2.874554, 2.771880, 0.863146 }, - { 2.949333, 2.738789, 1.004496 }, - { 1.501594, 2.091653, 1.371834 }, - { 1.538751, 2.009640, 1.415345 }, - { 1.538425, 2.172932, 1.416971 }, - { 2.833318, 2.065374, 0.326849 }, - { 2.735733, 2.046780, 0.338315 }, - { 2.849821, 2.101427, 0.235046 }, - { 1.050436, 1.606848, 2.061210 }, - { 1.034856, 1.671504, 1.986532 }, - { 0.963136, 1.567431, 2.089933 }, - { 2.852918, 2.103729, 1.290104 }, - { 2.826100, 2.168810, 1.361134 }, - { 2.787516, 2.107990, 1.214576 }, - { 2.693916, 0.326078, 2.033253 }, - { 2.731292, 0.332854, 1.940748 }, - { 2.723277, 0.240009, 2.074847 }, - { 0.212220, 0.175849, 2.885870 }, - { 0.212176, 0.100251, 2.820410 }, - { 0.153710, 0.152683, 2.963587 }, - { 1.629055, 0.636815, 1.189020 }, - { 1.552820, 0.586142, 1.148765 }, - { 1.622687, 0.632959, 1.288743 }, - { 1.339579, 0.227037, 2.582705 }, - { 1.429690, 0.183681, 2.583158 }, - { 1.350244, 0.326169, 2.590398 }, - { 0.877764, 3.073416, 2.428342 }, - { 0.876731, 3.168795, 2.458370 }, - { 0.830020, 3.065500, 2.340833 }, - { 0.012970, 1.608793, 1.734893 }, - { -0.086547, 1.600180, 1.730197 }, - { 0.041121, 1.618498, 1.830357 }, - { 2.089223, 2.356806, 3.093349 }, - { 2.080570, 2.263474, 3.058502 }, - { 2.007413, 2.409067, 3.069351 }, - { 2.470659, 0.854329, 2.975580 }, - { 2.544938, 0.892503, 2.920576 }, - { 2.460200, 0.907998, 3.059307 }, - { 2.511084, 0.660490, 1.700075 }, - { 2.478100, 0.600190, 1.627439 }, - { 2.435588, 0.717009, 1.733330 }, - { 3.043270, 2.024359, 0.777765 }, - { 3.006095, 2.041482, 0.686524 }, - { 3.131200, 2.071035, 0.787233 }, - { 2.406380, 2.833836, 2.437090 }, - { 2.498902, 2.800394, 2.455016 }, - { 2.410718, 2.912515, 2.375521 }, - { 2.734020, 1.466940, 2.755877 }, - { 2.700045, 1.377356, 2.784519 }, - { 2.659075, 1.519847, 2.716075 }, - { 0.855259, 2.409014, 2.948572 }, - { 0.811121, 2.434356, 2.862493 }, - { 0.919369, 2.480852, 2.975574 }, - { 1.958775, 1.734897, 2.027947 }, - { 1.918280, 1.644707, 2.012915 }, - { 2.045688, 1.724766, 2.076356 }, - { 2.982304, 2.766292, 2.104076 }, - { 3.060064, 2.827760, 2.117309 }, - { 2.923938, 2.801635, 2.030972 }, - { 0.495257, 2.600207, 0.002865 }, - { 0.574514, 2.584488, 0.061783 }, - { 0.523212, 2.594076, -0.092952 }, - { 0.620427, 1.316333, 1.773186 }, - { 0.550082, 1.344964, 1.838239 }, - { 0.654246, 1.396176, 1.723373 }, - { 1.851595, 2.477959, 3.036031 }, - { 1.794908, 2.470350, 2.954003 }, - { 1.842133, 2.569694, 3.074699 }, - { 2.162743, 1.730778, 1.542545 }, - { 2.114802, 1.643183, 1.547900 }, - { 2.217777, 1.743755, 1.625025 }, - { 2.529501, 2.719916, 1.696654 }, - { 2.503803, 2.782004, 1.770713 }, - { 2.570790, 2.637380, 1.735165 }, - { 2.307523, 3.038538, 0.375298 }, - { 2.404434, 3.016431, 0.364365 }, - { 2.297896, 3.116554, 0.437110 }, - { 2.247696, 2.677393, 1.478840 }, - { 2.181267, 2.606604, 1.454839 }, - { 2.208496, 2.737719, 1.548296 }, - { 2.405993, 0.100579, 0.117782 }, - { 2.319176, 0.078530, 0.162242 }, - { 2.399747, 0.190952, 0.075429 }, - { 2.845756, 2.478670, 2.035563 }, - { 2.813879, 2.492950, 2.129265 }, - { 2.929733, 2.530863, 2.020603 }, - { 2.412509, 2.437882, 2.677793 }, - { 2.409318, 2.340578, 2.654949 }, - { 2.447902, 2.449183, 2.770635 }, - { 2.743492, 0.946496, 2.446978 }, - { 2.763913, 0.946953, 2.349087 }, - { 2.644497, 0.941931, 2.460358 }, - { 0.252801, 2.064296, 2.729654 }, - { 0.205969, 2.116614, 2.658453 }, - { 0.233709, 2.105034, 2.818962 }, - { 3.063191, 1.922158, 1.214172 }, - { 2.986959, 1.986712, 1.218799 }, - { 3.100113, 1.907543, 1.305950 }, - { 2.880231, 3.025379, 0.083855 }, - { 2.795332, 3.002985, 0.131716 }, - { 2.945707, 3.064380, 0.148600 }, - { 2.779395, 1.653453, 2.946437 }, - { 2.784444, 1.581315, 2.877367 }, - { 2.816726, 1.619581, 3.032803 }, - { 2.054265, 0.038926, 0.074381 }, - { 2.065626, -0.041658, 0.132494 }, - { 2.100034, 0.023588, -0.013197 }, - { 2.355414, 2.720144, 2.698744 }, - { 2.344450, 2.753016, 2.604939 }, - { 2.357313, 2.620162, 2.699021 }, - { 0.361217, 2.018670, 0.301548 }, - { 0.303415, 2.006261, 0.220894 }, - { 0.429552, 2.089293, 0.283039 }, - { 0.332342, 0.090876, 2.109455 }, - { 0.263449, 0.156985, 2.139177 }, - { 0.390810, 0.132649, 2.039909 }, - { 3.034524, 0.068387, 2.292232 }, - { 2.993148, 0.137518, 2.351469 }, - { 3.043613, -0.017534, 2.342580 }, - { 0.237543, 0.583210, 1.838098 }, - { 0.311681, 0.597860, 1.772608 }, - { 0.276038, 0.559019, 1.927165 }, - { 2.503589, 2.263025, 2.095976 }, - { 2.420729, 2.315682, 2.114991 }, - { 2.540302, 2.226586, 2.181559 }, - { 2.262877, 2.698771, 2.033787 }, - { 2.333674, 2.768746, 2.024233 }, - { 2.248342, 2.653808, 1.945656 }, - { 0.964111, 2.685023, 2.452276 }, - { 0.990834, 2.666914, 2.546923 }, - { 1.040843, 2.726435, 2.403315 }, - { 0.794322, 2.734946, 2.845067 }, - { 0.803437, 2.799933, 2.920523 }, - { 0.710474, 2.681741, 2.856841 }, - { 2.896233, 2.435937, 1.571472 }, - { 2.949992, 2.393141, 1.644124 }, - { 2.879950, 2.531950, 1.594195 }, - { 0.707918, 0.439981, 1.637015 }, - { 0.805572, 0.456561, 1.650751 }, - { 0.687875, 0.438135, 1.539061 }, - { 2.429562, 2.935991, 0.705919 }, - { 2.331154, 2.931808, 0.723196 }, - { 2.451272, 2.883147, 0.623845 }, - { 0.890410, 0.316803, 3.083332 }, - { 0.973293, 0.305226, 3.028592 }, - { 0.829674, 0.238704, 3.068783 }, - { 0.544859, 2.440687, 1.202416 }, - { 0.638042, 2.463712, 1.174367 }, - { 0.480239, 2.473483, 1.133506 }, - { 2.821353, 0.977632, 2.194345 }, - { 2.890551, 1.047090, 2.214022 }, - { 2.854392, 0.917286, 2.121772 }, - { 0.710748, 1.170876, 2.004677 }, - { 0.643095, 1.116736, 1.954758 }, - { 0.730699, 1.254545, 1.953672 }, - { 1.323921, 1.479145, 0.621735 }, - { 1.286777, 1.537103, 0.549201 }, - { 1.253285, 1.415737, 0.653197 }, - { 2.698551, 2.717451, 0.063376 }, - { 2.639217, 2.637232, 0.056723 }, - { 2.661341, 2.791201, 0.007017 }, - { 0.840228, 1.225083, 2.251827 }, - { 0.854567, 1.147753, 2.313588 }, - { 0.765601, 1.203942, 2.188709 }, - { 1.592481, 1.743693, 1.226737 }, - { 1.565173, 1.689101, 1.305946 }, - { 1.691904, 1.754410, 1.226317 }, - { 1.258602, 2.759789, 1.297767 }, - { 1.231534, 2.833672, 1.359482 }, - { 1.236972, 2.671656, 1.339776 }, - { 1.283405, 3.025043, 1.772125 }, - { 1.383297, 3.021171, 1.774669 }, - { 1.252723, 3.114943, 1.803376 }, - { 2.541767, 1.632310, 0.149237 }, - { 2.449338, 1.608351, 0.119526 }, - { 2.572917, 1.566396, 0.217683 }, - { 1.328386, 0.424321, 1.433167 }, - { 1.399835, 0.355967, 1.418246 }, - { 1.300864, 0.463486, 1.345368 }, - { 0.236768, 0.950959, 2.590976 }, - { 0.330331, 0.962132, 2.557492 }, - { 0.238410, 0.905038, 2.679794 }, - { 0.313513, 2.796867, 3.012214 }, - { 0.323708, 2.795983, 2.912740 }, - { 0.375929, 2.730056, 3.052716 }, - { 0.112414, 2.245971, 0.123348 }, - { 0.177492, 2.170582, 0.114330 }, - { 0.162248, 2.331534, 0.137334 }, - { 2.701271, 2.514977, 2.263225 }, - { 2.611569, 2.555932, 2.279852 }, - { 2.714556, 2.437557, 2.325108 }, - { 1.770655, 0.024603, 2.384955 }, - { 1.699905, 0.005690, 2.316861 }, - { 1.847949, 0.070276, 2.340914 }, - { 0.009882, 1.194905, 1.519823 }, - { -0.077604, 1.217861, 1.477170 }, - { 0.058135, 1.279012, 1.544271 }, - { 2.362329, 1.189368, 1.500885 }, - { 2.448073, 1.222733, 1.461709 }, - { 2.288210, 1.252204, 1.477265 }, - { 1.943393, 1.163287, 1.318490 }, - { 1.904684, 1.254202, 1.303121 }, - { 1.923693, 1.134053, 1.412070 }, - { 0.095808, 0.472131, 0.518367 }, - { 0.157246, 0.463382, 0.596782 }, - { 0.143525, 0.518364, 0.443630 }, - { 0.157283, 0.392476, 2.732502 }, - { 0.071212, 0.434916, 2.760620 }, - { 0.167245, 0.303987, 2.778005 }, - { 2.308432, 0.518593, 0.204206 }, - { 2.407431, 0.531838, 0.199337 }, - { 2.285893, 0.425193, 0.176483 }, - { 0.944487, 0.067090, 1.962743 }, - { 0.979830, -0.021319, 1.932171 }, - { 0.921300, 0.061935, 2.059881 }, - { 0.672079, 1.749103, 0.099972 }, - { 0.679855, 1.844222, 0.129836 }, - { 0.575510, 1.724947, 0.090434 }, - { 1.825839, 0.707532, 0.059138 }, - { 1.820204, 0.806882, 0.049239 }, - { 1.897469, 0.684609, 0.125044 }, - { 2.985048, 1.441246, 0.798920 }, - { 3.015628, 1.520955, 0.850991 }, - { 2.984317, 1.463406, 0.701409 }, - { 2.308448, 2.258307, 1.299501 }, - { 2.290653, 2.254337, 1.201177 }, - { 2.344603, 2.348475, 1.323219 } +static const std::vector coordinates1000 = { + { 3.058441, 1.962230, 1.989683 }, { 2.975840, 1.980085, 1.936221 }, + { 3.122664, 2.038002, 1.978114 }, { 2.511969, 0.591980, 0.611700 }, + { 2.600885, 0.614626, 0.651463 }, { 2.439189, 0.625060, 0.671774 }, + { 3.037115, 1.103423, 0.510358 }, { 3.075596, 1.113280, 0.602129 }, + { 3.094188, 1.041190, 0.456788 }, { 0.625031, 2.325809, 2.735173 }, + { 0.572419, 2.273776, 2.802438 }, { 0.697119, 2.267854, 2.697168 }, + { 1.631749, 0.888913, 1.089352 }, { 1.722932, 0.929772, 1.085316 }, + { 1.639399, 0.792924, 1.116324 }, { 0.135367, 0.404389, 0.014781 }, + { 0.123013, 0.353549, -0.070440 }, { 0.065358, 0.475464, 0.021644 }, + { 2.133195, 1.942149, 1.063163 }, { 2.103670, 1.932198, 1.158185 }, + { 2.057370, 1.977206, 1.008194 }, { 0.974812, 1.273100, 2.779850 }, + { 0.977014, 1.306597, 2.874047 }, { 0.914936, 1.331539, 2.725080 }, + { 3.039257, 2.275091, 2.297507 }, { 3.077036, 2.367559, 2.292780 }, + { 2.939914, 2.279080, 2.286772 }, { 3.066429, 1.655573, 0.946745 }, + { 2.988511, 1.717413, 0.956967 }, { 3.146125, 1.694443, 0.992980 }, + { 2.402943, 1.159655, 1.041159 }, { 2.457788, 1.113902, 0.971169 }, + { 2.463494, 1.202601, 1.108161 }, { 0.198771, 2.872936, 2.409695 }, + { 0.230047, 2.782781, 2.439593 }, { 0.105151, 2.887969, 2.441464 }, + { 0.368974, 0.573758, 2.697072 }, { 0.309036, 0.494602, 2.708979 }, + { 0.372528, 0.598619, 2.600277 }, { 0.780393, 2.245371, 0.386869 }, + { 0.696219, 2.230132, 0.335076 }, { 0.803298, 2.342700, 0.385368 }, + { 1.288811, 0.315362, 0.649111 }, { 1.337870, 0.256502, 0.713366 }, + { 1.213238, 0.264277, 0.608136 }, { 2.939084, 1.486800, 0.541567 }, + { 2.999762, 1.475771, 0.462849 }, { 2.860697, 1.543197, 0.515590 }, + { 1.700513, 1.987843, 0.690324 }, { 1.683709, 2.077665, 0.649708 }, + { 1.624542, 1.963847, 0.750761 }, { 2.002822, 0.880025, 2.162986 }, + { 1.904598, 0.881033, 2.144248 }, { 2.021988, 0.936233, 2.243442 }, + { 1.419121, 1.568915, 3.023597 }, { 1.499351, 1.625145, 3.043628 }, + { 1.448466, 1.476567, 2.998884 }, { 1.659223, 2.063895, 0.003451 }, + { 1.721702, 2.003487, 0.052920 }, { 1.585788, 2.009680, -0.037391 }, + { 0.932668, 0.985297, 2.066137 }, { 0.841309, 1.019847, 2.087582 }, + { 0.925293, 0.909652, 2.001149 }, { 2.544425, 2.069147, 0.358217 }, + { 2.569305, 2.158265, 0.396151 }, { 2.491877, 2.017600, 0.425905 }, + { 2.643055, 0.627143, 1.977899 }, { 2.728804, 0.579992, 1.957311 }, + { 2.593018, 0.643929, 1.892961 }, { 2.525198, 2.511291, 0.851458 }, + { 2.548718, 2.560892, 0.935043 }, { 2.585276, 2.431939, 0.841761 }, + { 1.593863, 1.272151, 1.144316 }, { 1.641930, 1.220443, 1.073494 }, + { 1.595331, 1.220620, 1.230004 }, { 0.241304, 1.026247, 1.527110 }, + { 0.314388, 1.092000, 1.545424 }, { 0.153979, 1.074500, 1.520328 }, + { 0.670527, 2.411080, 0.740280 }, { 0.743415, 2.366956, 0.792629 }, + { 0.616596, 2.341413, 0.692972 }, { 0.506075, 0.784227, 0.136559 }, + { 0.468598, 0.695519, 0.109607 }, { 0.557918, 0.823051, 0.060368 }, + { 2.820775, 2.815071, 1.889172 }, { 2.815770, 2.751934, 1.811786 }, + { 2.765318, 2.896000, 1.869805 }, { 0.987299, 2.128997, 0.524538 }, + { 1.040313, 2.207735, 0.556000 }, { 0.919566, 2.159089, 0.457407 }, + { 0.229879, 0.835755, 1.940027 }, { 0.167288, 0.879689, 2.004464 }, + { 0.180058, 0.767698, 1.886303 }, { 0.378771, 0.998110, 0.493601 }, + { 0.339751, 0.957631, 0.576299 }, { 0.466309, 0.954303, 0.473154 }, + { 2.123415, 1.896470, 2.510045 }, { 2.077036, 1.955502, 2.443983 }, + { 2.089467, 1.802874, 2.500702 }, { 1.588236, 2.328677, 1.511384 }, + { 1.576339, 2.284743, 1.600425 }, { 1.526922, 2.407382, 1.504588 }, + { 0.580119, 2.671499, 1.778415 }, { 0.516760, 2.699374, 1.706245 }, + { 0.573680, 2.735504, 1.854978 }, { 0.236329, 1.658599, 0.482922 }, + { 0.173161, 1.716011, 0.535014 }, { 0.216351, 1.562272, 0.500868 }, + { 2.866907, 2.172310, 0.976553 }, { 2.911961, 2.101637, 0.922006 }, + { 2.932579, 2.244494, 0.998384 }, { 2.765681, 2.315028, 2.427439 }, + { 2.832893, 2.283105, 2.494248 }, { 2.712988, 2.237172, 2.393353 }, + { 0.705927, 2.118901, 1.945963 }, { 0.721405, 2.171561, 1.862373 }, + { 0.770568, 2.148338, 2.016355 }, { 1.781326, 0.167158, 0.154133 }, + { 1.802628, 0.096981, 0.222114 }, { 1.746708, 0.123639, 0.071021 }, + { 0.126723, 1.501790, 2.733301 }, { 0.156993, 1.595659, 2.716802 }, + { 0.203411, 1.439118, 2.719470 }, { 0.870069, 0.129573, 0.216301 }, + { 0.862810, 0.197557, 0.143326 }, { 0.959244, 0.084607, 0.211220 }, + { 1.070536, 0.743136, 0.182829 }, { 1.013762, 0.666505, 0.152757 }, + { 1.166809, 0.716182, 0.180608 }, { 0.440991, 3.021278, 2.594643 }, + { 0.439645, 3.047789, 2.498230 }, { 0.532720, 2.990050, 2.619351 }, + { 2.742220, 2.873495, 2.785948 }, { 2.707374, 2.780469, 2.774456 }, + { 2.683663, 2.937420, 2.736102 }, { 0.713098, 1.865958, 0.712284 }, + { 0.624328, 1.911507, 0.705575 }, { 0.712267, 1.802542, 0.789600 }, + { 0.314657, 0.447043, 0.721110 }, { 0.350251, 0.534830, 0.689071 }, + { 0.357799, 0.372848, 0.669789 }, { 2.969682, 2.658620, 2.862492 }, + { 2.984106, 2.745657, 2.909572 }, { 2.871682, 2.639454, 2.857144 }, + { 1.198561, 2.913779, 2.614820 }, { 1.150109, 2.838385, 2.659182 }, + { 1.132291, 2.976540, 2.573961 }, { 2.641875, 1.268461, 1.491413 }, + { 2.633864, 1.233835, 1.584884 }, { 2.682652, 1.359754, 1.493064 }, + { 0.568633, 0.009039, 1.190356 }, { 0.651953, 0.059866, 1.212135 }, + { 0.490931, 0.071934, 1.187777 }, { 2.645675, 1.030926, 1.996264 }, + { 2.656484, 1.127034, 2.021689 }, { 2.689366, 0.973100, 2.065165 }, + { 0.077218, 2.967854, 2.133322 }, { 0.044197, 3.062070, 2.127588 }, + { 0.131490, 2.956560, 2.216550 }, { 0.408365, 1.237271, 1.580670 }, + { 0.474287, 1.284063, 1.639532 }, { 0.359054, 1.304681, 1.525676 }, + { 0.226492, 1.945573, 0.076363 }, { 0.261322, 1.853437, 0.059106 }, + { 0.171768, 1.975692, -0.001728 }, { 0.468126, 2.450245, 2.524287 }, + { 0.486194, 2.415823, 2.616421 }, { 0.526489, 2.402303, 2.458749 }, + { 1.434546, 2.964952, 2.504450 }, { 1.477884, 3.052850, 2.524343 }, + { 1.336295, 2.971528, 2.521873 }, { 1.464730, 0.522293, 0.985985 }, + { 1.526258, 0.561016, 0.917320 }, { 1.461514, 0.422887, 0.975592 }, + { 1.630397, 2.791382, 2.590973 }, { 1.601935, 2.722126, 2.657257 }, + { 1.554965, 2.854999, 2.574763 }, { 1.972387, 0.963775, 2.902179 }, + { 2.029530, 1.043059, 2.923363 }, { 1.969130, 0.950549, 2.803111 }, + { 2.337723, 0.321846, 0.882555 }, { 2.314325, 0.235026, 0.926315 }, + { 2.435069, 0.340610, 0.895658 }, { 0.734798, 1.529859, 3.053034 }, + { 0.713380, 1.615060, 3.100805 }, { 0.672452, 1.457908, 3.083628 }, + { 0.032173, 0.527923, 2.239826 }, { 0.027814, 0.477786, 2.326239 }, + { -0.054207, 0.517106, 2.190617 }, { 0.022851, 1.802543, 0.630916 }, + { -0.015108, 1.813262, 0.539024 }, { -0.037014, 1.847556, 0.697172 }, + { 1.010410, 0.509648, 2.039333 }, { 1.003466, 0.551298, 2.129981 }, + { 1.093583, 0.454356, 2.034335 }, { 2.898570, 2.091456, 1.807118 }, + { 2.854734, 2.046376, 1.729360 }, { 2.829335, 2.138791, 1.861577 }, + { 1.961915, 1.375020, 2.801540 }, { 1.948970, 1.298617, 2.738333 }, + { 1.941740, 1.460950, 2.754540 }, { 0.290337, 0.199516, 2.503690 }, + { 0.291054, 0.257287, 2.422069 }, { 0.327554, 0.250724, 2.581102 }, + { 2.077703, 0.143438, 0.468608 }, { 2.065651, 0.217401, 0.402395 }, + { 2.171157, 0.145407, 0.504141 }, { 0.990673, 2.712908, 0.856622 }, + { 0.895723, 2.743789, 0.851057 }, { 1.037275, 2.761569, 0.930516 }, + { 0.078677, 1.380516, 1.009080 }, { 0.029933, 1.464352, 1.033485 }, + { 0.162256, 1.403821, 0.959367 }, { 1.836054, 2.642598, 1.704376 }, + { 1.795981, 2.597778, 1.624468 }, { 1.913014, 2.588291, 1.737959 }, + { 0.257482, 0.992506, 1.247093 }, { 0.281524, 1.086213, 1.221773 }, + { 0.267620, 0.981034, 1.345914 }, { 1.986510, 2.050284, 0.848145 }, + { 1.991489, 2.078718, 0.752402 }, { 1.906061, 1.992431, 0.861596 }, + { 0.384118, 3.016757, 0.633530 }, { 0.365374, 2.938621, 0.574004 }, + { 0.379431, 2.987730, 0.729109 }, { 1.061282, 2.803301, 1.113124 }, + { 1.140678, 2.799514, 1.173803 }, { 0.982344, 2.762423, 1.158925 }, + { 0.893588, 0.623562, 1.159613 }, { 0.935464, 0.532797, 1.156770 }, + { 0.961163, 0.692300, 1.132990 }, { 0.064641, 1.597101, 1.338713 }, + { 0.089583, 1.650727, 1.258077 }, { 0.000262, 1.525261, 1.312362 }, + { 1.744692, 2.999075, 2.729173 }, { 1.711603, 2.931172, 2.663642 }, + { 1.732436, 2.964397, 2.822163 }, { 1.010117, 1.010223, 2.690790 }, + { 1.003234, 1.103514, 2.726136 }, { 1.005616, 0.945370, 2.766776 }, + { 2.119029, 2.091893, 2.142070 }, { 2.053933, 2.055051, 2.208442 }, + { 2.069727, 2.144103, 2.072475 }, { 0.476711, 0.278280, 2.980274 }, + { 0.398589, 0.239525, 2.931336 }, { 0.546481, 0.207756, 2.992862 }, + { 1.017548, 1.173820, 0.262341 }, { 0.930974, 1.150575, 0.306663 }, + { 1.038587, 1.270192, 0.278769 }, { 3.006009, 2.653507, 0.115338 }, + { 3.070976, 2.729519, 0.116520 }, { 2.913460, 2.688961, 0.102011 }, + { 0.321159, 1.479760, 1.402806 }, { 0.401871, 1.536967, 1.417403 }, + { 0.240644, 1.537977, 1.391482 }, { 1.629104, 2.275881, 0.958820 }, + { 1.558865, 2.324456, 1.010849 }, { 1.624176, 2.178136, 0.979354 }, + { 3.066126, 2.858316, 1.644953 }, { 3.084059, 2.953924, 1.668140 }, + { 3.146678, 2.803116, 1.666501 }, { 1.051189, 2.076017, 1.920453 }, + { 1.125807, 2.103292, 1.859722 }, { 0.969998, 2.130757, 1.900170 }, + { 1.516509, 0.100229, 0.350171 }, { 1.560545, 0.020237, 0.309401 }, + { 1.431952, 0.120519, 0.300791 }, { 0.493363, 2.189335, 1.269427 }, + { 0.521529, 2.285282, 1.270284 }, { 0.404068, 2.180412, 1.313548 }, + { 2.807439, 1.983481, 1.563125 }, { 2.768178, 2.068799, 1.528782 }, + { 2.841332, 1.929104, 1.486351 }, { 2.853076, 0.830733, 1.400601 }, + { 2.899426, 0.745984, 1.374732 }, { 2.909799, 0.908954, 1.374833 }, + { 2.959505, 0.005017, 0.423243 }, { 2.864585, 0.013417, 0.453569 }, + { 3.007911, 0.090678, 0.441104 }, { 2.807480, 1.919990, 2.908606 }, + { 2.827273, 1.955044, 2.817067 }, { 2.804816, 1.820055, 2.906175 }, + { 0.082000, 0.549511, 1.184398 }, { 0.156887, 0.615066, 1.174679 }, + { 0.106704, 0.463752, 1.139285 }, { 0.629631, 0.003336, 1.945927 }, + { 0.544066, -0.015054, 1.897548 }, { 0.670653, 0.087312, 1.910356 }, + { 1.183012, 0.907457, 0.474085 }, { 1.250390, 0.969782, 0.434387 }, + { 1.156401, 0.839314, 0.405907 }, { 3.032287, 0.465330, 0.292632 }, + { 3.062801, 0.530277, 0.222984 }, { 3.089603, 0.474409, 0.374072 }, + { 2.243416, 0.013336, 2.312642 }, { 2.250096, 0.111913, 2.328068 }, + { 2.159889, -0.021479, 2.355200 }, { 1.164546, 0.173416, 1.168458 }, + { 1.104884, 0.099010, 1.138385 }, { 1.206309, 0.149320, 1.256066 }, + { 2.607532, 1.124091, 1.724250 }, { 2.622452, 1.052768, 1.655763 }, + { 2.656772, 1.100643, 1.808069 }, { 2.551467, 1.338625, 1.208755 }, + { 2.583643, 1.301105, 1.295686 }, { 2.619725, 1.402104, 1.172543 }, + { 2.136262, 1.322655, 0.114168 }, { 2.208042, 1.328919, 0.183511 }, + { 2.092568, 1.411940, 0.103260 }, { 0.941991, 1.920726, 2.868290 }, + { 0.939600, 1.894556, 2.964776 }, { 0.851093, 1.908966, 2.828299 }, + { 0.004144, 1.775721, 2.412374 }, { -0.041340, 1.699791, 2.365836 }, + { -0.012548, 1.860487, 2.362015 }, { 0.867448, 0.363037, 0.498578 }, + { 0.800322, 0.437082, 0.501957 }, { 0.953402, 0.397657, 0.460984 }, + { 0.890184, 0.676760, 1.539212 }, { 0.935641, 0.621324, 1.608930 }, + { 0.824962, 0.738580, 1.583080 }, { 2.539177, 1.282032, 3.012743 }, + { 2.501141, 1.363299, 2.968595 }, { 2.610318, 1.309461, 3.077447 }, + { 1.604518, 1.894267, 1.505941 }, { 1.686555, 1.935396, 1.545670 }, + { 1.617543, 1.795488, 1.497399 }, { 2.913814, 2.506912, 1.298808 }, + { 2.839748, 2.479654, 1.237398 }, { 2.888555, 2.485341, 1.393130 }, + { 2.479043, 2.811393, 0.464821 }, { 2.461245, 2.785192, 0.369970 }, + { 2.480291, 2.729592, 0.522328 }, { 0.000418, 2.908271, 0.684488 }, + { 0.052322, 2.991863, 0.666647 }, { 0.048874, 2.852730, 0.752070 }, + { 2.420592, 0.017713, 1.710805 }, { 2.390744, 0.098744, 1.761235 }, + { 2.369678, 0.011235, 1.624981 }, { 2.926354, 2.206255, 0.118647 }, + { 3.026107, 2.212509, 0.115431 }, { 2.891067, 2.188804, 0.026722 }, + { 3.083248, 0.397414, 1.498830 }, { 3.094998, 0.418032, 1.595973 }, + { 3.110143, 0.302695, 1.481366 }, { 1.151128, 1.570859, 1.066268 }, + { 1.137265, 1.624490, 0.983012 }, { 1.236225, 1.518892, 1.058662 }, + { 2.100275, 0.308399, 0.082371 }, { 2.063669, 0.215716, 0.074010 }, + { 2.068801, 0.349058, 0.168139 }, { 2.089025, 0.726449, 2.710428 }, + { 2.158632, 0.687899, 2.649858 }, { 2.125094, 0.731738, 2.803546 }, + { 1.069548, 0.219822, 2.643919 }, { 1.155804, 0.212609, 2.593841 }, + { 1.069971, 0.303144, 2.699212 }, { 0.215623, 1.771402, 2.733978 }, + { 0.116525, 1.780547, 2.724178 }, { 0.259711, 1.857516, 2.708670 }, + { 0.076321, 2.814589, 0.017922 }, { 0.153935, 2.798606, -0.043074 }, + { -0.004197, 2.838785, -0.036221 }, { 0.827608, 0.266569, 2.523361 }, + { 0.924521, 0.255060, 2.545165 }, { 0.782806, 0.317778, 2.596643 }, + { 1.774364, 1.200772, 0.922419 }, { 1.847724, 1.268283, 0.914643 }, + { 1.699914, 1.225138, 0.860262 }, { 1.843738, 0.863281, 1.426679 }, + { 1.835180, 0.960574, 1.448143 }, { 1.909114, 0.820935, 1.489391 }, + { 2.190590, 2.093015, 0.489172 }, { 2.114286, 2.129196, 0.542731 }, + { 2.168165, 2.097687, 0.391831 }, { 2.856985, 2.708571, 2.421630 }, + { 2.826059, 2.637500, 2.358445 }, { 2.940505, 2.678308, 2.467548 }, + { 0.701585, 1.132874, 1.532032 }, { 0.713505, 1.046958, 1.581796 }, + { 0.636137, 1.190763, 1.580667 }, { 1.112152, 1.761410, 2.730896 }, + { 1.032952, 1.800466, 2.777823 }, { 1.183341, 1.740039, 2.797795 }, + { 2.362848, 0.400039, 0.467593 }, { 2.413963, 0.451503, 0.536431 }, + { 2.364750, 0.449557, 0.380735 }, { 1.923021, 2.539071, 1.210065 }, + { 2.005782, 2.500150, 1.250510 }, { 1.911843, 2.504236, 1.116997 }, + { 2.843027, 2.693089, 1.659378 }, { 2.914984, 2.761898, 1.668726 }, + { 2.770508, 2.728503, 1.600329 }, { 0.128262, 0.810566, 1.667570 }, + { 0.116881, 0.757626, 1.583499 }, { 0.142354, 0.906881, 1.644662 }, + { 1.002980, 0.859088, 2.952428 }, { 0.921072, 0.801826, 2.948964 }, + { 0.978573, 0.950206, 2.985621 }, { 0.665071, 1.176651, 0.745782 }, + { 0.572750, 1.214473, 0.752595 }, { 0.662264, 1.078374, 0.764052 }, + { 1.604419, 2.998470, 1.830186 }, { 1.578196, 3.085323, 1.872245 }, + { 1.699378, 3.003726, 1.799281 }, { 0.766206, 2.635236, 2.266948 }, + { 0.669570, 2.646575, 2.290034 }, { 0.821969, 2.650297, 2.348579 }, + { 0.413167, 1.864376, 1.358930 }, { 0.436077, 1.767159, 1.354041 }, + { 0.368949, 1.883842, 1.446484 }, { 2.520023, 2.005269, 2.712810 }, + { 2.491840, 2.040054, 2.802229 }, { 2.615839, 2.028833, 2.696563 }, + { 0.653971, 0.523083, 2.191540 }, { 0.655081, 0.426122, 2.215980 }, + { 0.648901, 0.532338, 2.092098 }, { 2.064821, 2.995576, 1.899338 }, + { 2.000715, 2.961996, 1.968351 }, { 2.148348, 3.027455, 1.944135 }, + { 0.974837, 3.040805, 0.756885 }, { 0.947137, 2.957808, 0.708467 }, + { 0.934946, 3.120620, 0.711736 }, { 2.444642, 2.518796, 2.408258 }, + { 2.440402, 2.457240, 2.486953 }, { 2.370887, 2.586034, 2.414519 }, + { 2.321767, 1.107241, 2.328455 }, { 2.385756, 1.168742, 2.374533 }, + { 2.229778, 1.121331, 2.365052 }, { 1.605816, 0.704012, 0.201441 }, + { 1.679042, 0.692486, 0.134321 }, { 1.642942, 0.745578, 0.284471 }, + { 1.552828, 1.036090, 1.319262 }, { 1.570254, 0.975950, 1.241290 }, + { 1.462357, 1.016354, 1.357017 }, { 3.106174, 0.095841, 1.468391 }, + { 3.169836, 0.054846, 1.403072 }, { 3.016178, 0.105234, 1.425817 }, + { 1.471106, 2.572710, 1.544631 }, { 1.503995, 2.624378, 1.465582 }, + { 1.425647, 2.634814, 1.608479 }, { 2.479549, 1.837065, 1.139527 }, + { 2.433902, 1.811477, 1.224742 }, { 2.578245, 1.842147, 1.154804 }, + { 2.285594, 0.997748, 2.811664 }, { 2.337996, 0.950786, 2.882718 }, + { 2.230949, 1.070507, 2.853138 }, { 2.069438, 2.790248, 2.236690 }, + { 2.128149, 2.745234, 2.169408 }, { 2.071366, 2.738737, 2.322380 }, + { 2.405399, 0.905125, 1.347911 }, { 2.447368, 0.898610, 1.438443 }, + { 2.346844, 0.986097, 1.344063 }, { 2.196427, 0.438752, 2.136470 }, + { 2.192188, 0.376343, 2.214491 }, { 2.290922, 0.445799, 2.104517 }, + { 2.889807, 0.531760, 1.366584 }, { 2.900943, 0.497848, 1.273171 }, + { 2.958704, 0.489830, 1.425704 }, { 1.841082, 3.042295, 1.732903 }, + { 1.861475, 3.126049, 1.682215 }, { 1.919077, 3.018546, 1.790806 }, + { 1.326290, 2.104904, 0.154356 }, { 1.358661, 2.045197, 0.080959 }, + { 1.312102, 2.050989, 0.237373 }, { 3.049543, 1.131760, 2.722415 }, + { 2.996461, 1.169327, 2.646448 }, { 3.132666, 1.088896, 2.687015 }, + { 1.908184, 0.043121, 0.967115 }, { 1.972116, 0.062905, 1.041420 }, + { 1.957530, 0.041801, 0.880148 }, { 2.401901, 0.513585, 1.491280 }, + { 2.427890, 0.425841, 1.450961 }, { 2.344707, 0.564272, 1.426784 }, + { 2.448317, 1.127002, 0.327588 }, { 2.418437, 1.074801, 0.407477 }, + { 2.405026, 1.217141, 0.328569 }, { 0.576997, 2.600784, 2.855002 }, + { 0.517158, 2.664093, 2.805898 }, { 0.581336, 2.513933, 2.805624 }, + { 2.875255, 1.238762, 1.338781 }, { 2.892585, 1.147209, 1.302481 }, + { 2.795469, 1.236189, 1.399010 }, { 1.623443, 1.734577, 3.063192 }, + { 1.708509, 1.682883, 3.053623 }, { 1.635767, 1.806728, 3.131327 }, + { 2.710919, 0.916881, 2.856473 }, { 2.766298, 0.905953, 2.773928 }, + { 2.730606, 1.005542, 2.898326 }, { 0.413553, 0.398427, 1.586956 }, + { 0.433660, 0.488295, 1.547974 }, { 0.453389, 0.327300, 1.529042 }, + { 1.497303, 1.793333, 2.176276 }, { 1.451349, 1.745062, 2.250829 }, + { 1.487507, 1.740990, 2.091634 }, { 1.518297, 0.712931, 1.713533 }, + { 1.511776, 0.670016, 1.803621 }, { 1.431340, 0.702497, 1.665266 }, + { 1.551914, 1.629915, 1.465708 }, { 1.627901, 1.578363, 1.505312 }, + { 1.466468, 1.602561, 1.509874 }, { 0.817285, 0.341999, 1.337646 }, + { 0.812267, 0.250486, 1.297643 }, { 0.849200, 0.406874, 1.268563 }, + { 0.483208, 1.585241, 2.340546 }, { 0.455791, 1.506492, 2.285348 }, + { 0.401919, 1.636533, 2.368138 }, { 0.072505, 1.709287, 2.006497 }, + { 0.160460, 1.755185, 1.993951 }, { -0.001476, 1.775956, 1.997443 }, + { 2.582320, 0.685754, 2.244482 }, { 2.650091, 0.637094, 2.299612 }, + { 2.587629, 0.654280, 2.149712 }, { 1.501209, 2.306496, 0.101764 }, + { 1.573483, 2.238069, 0.092060 }, { 1.424723, 2.267188, 0.152802 }, + { 2.481658, 1.039356, 2.585797 }, { 2.460124, 0.963544, 2.524242 }, + { 2.416564, 1.040181, 2.661705 }, { 0.007444, 0.131285, 3.075162 }, + { 0.021151, 0.050319, 3.132229 }, { -0.077919, 0.121895, 3.023929 }, + { 2.384391, 2.087250, 2.954037 }, { 2.285605, 2.102203, 2.958238 }, + { 2.419802, 2.072319, 3.046358 }, { 2.522700, 1.616950, 0.785956 }, + { 2.585893, 1.539614, 0.791042 }, { 2.445543, 1.593127, 0.726971 }, + { 0.874549, 0.343416, 0.840602 }, { 0.833294, 0.425210, 0.800506 }, + { 0.845368, 0.262750, 0.789208 }, { 1.590202, 0.346154, 1.432877 }, + { 1.615997, 0.442727, 1.435750 }, { 1.615345, 0.302353, 1.519186 }, + { 0.200720, 2.166011, 1.669131 }, { 0.203419, 2.079517, 1.619016 }, + { 0.270766, 2.165386, 1.740497 }, { 2.718568, 1.424756, 0.815413 }, + { 2.672368, 1.357349, 0.757778 }, { 2.816407, 1.424830, 0.794736 }, + { 0.046991, 1.844195, 1.458743 }, { 0.084611, 1.875306, 1.546017 }, + { 0.077274, 1.750582, 1.440864 }, { 2.572122, 0.480250, 0.179410 }, + { 2.648033, 0.542352, 0.159896 }, { 2.607804, 0.388536, 0.197167 }, + { 2.983852, 2.126827, 0.529426 }, { 2.919768, 2.105563, 0.455662 }, + { 3.074677, 2.143297, 0.490962 }, { 2.481990, 1.585232, 2.950477 }, + { 2.481605, 1.594815, 2.850938 }, { 2.550736, 1.646421, 2.989590 }, + { 1.937349, 2.315709, 2.488461 }, { 1.866975, 2.245603, 2.476944 }, + { 1.894483, 2.401770, 2.515955 }, { 2.198232, 2.608651, 1.779312 }, + { 2.176557, 2.685274, 1.718822 }, { 2.121877, 2.544080, 1.779987 }, + { 2.767491, 1.663955, 0.469798 }, { 2.721891, 1.697642, 0.552174 }, + { 2.698811, 1.638682, 0.401649 }, { 0.406640, 1.422145, 1.928232 }, + { 0.397242, 1.448410, 2.024263 }, { 0.347679, 1.343646, 1.909219 }, + { 1.896401, 2.791342, 1.136750 }, { 1.924382, 2.698789, 1.162263 }, + { 1.819455, 2.786541, 1.073062 }, { 1.769318, 1.881876, 2.175327 }, + { 1.682986, 1.831440, 2.177071 }, { 1.835406, 1.832880, 2.118478 }, + { 2.282848, 0.667216, 1.278688 }, { 2.328695, 0.755760, 1.286297 }, + { 2.184749, 0.681493, 1.265545 }, { 0.082448, 2.196028, 2.545991 }, + { 0.127614, 2.276112, 2.506664 }, { 0.023481, 2.153839, 2.477121 }, + { 1.173007, 2.545388, 1.465317 }, { 1.261847, 2.555552, 1.510086 }, + { 1.100823, 2.576852, 1.526958 }, { 0.971281, 0.476352, 1.707317 }, + { 0.987809, 0.486035, 1.805465 }, { 1.034678, 0.408994, 1.669323 }, + { 1.729149, 0.592677, 2.083464 }, { 1.809754, 0.606881, 2.026009 }, + { 1.710765, 0.494708, 2.091470 }, { 0.139730, 0.213097, 1.878174 }, + { 0.232551, 0.235783, 1.848687 }, { 0.142086, 0.178372, 1.971921 }, + { 3.067644, 0.529023, 2.833107 }, { 3.055445, 0.610258, 2.890134 }, + { 2.990385, 0.466966, 2.846527 }, { 1.629882, 2.760517, 1.057234 }, + { 1.570178, 2.835637, 1.085385 }, { 1.576395, 2.676331, 1.050029 }, + { 0.046460, 2.403684, 1.395527 }, { 0.000167, 2.351222, 1.466974 }, + { -0.017278, 2.469978, 1.356251 }, { 0.979941, 2.502884, 1.685655 }, + { 0.890348, 2.484811, 1.726232 }, { 1.050479, 2.455007, 1.737925 }, + { 0.380089, 0.272073, 1.817507 }, { 0.405127, 0.180000, 1.787580 }, + { 0.383922, 0.334644, 1.739596 }, { 1.475603, 1.663110, 1.902010 }, + { 1.562825, 1.673352, 1.854183 }, { 1.453838, 1.565942, 1.911209 }, + { 1.235365, 1.009114, 1.796560 }, { 1.195125, 0.917615, 1.799501 }, + { 1.169665, 1.075583, 1.832132 }, { 3.102696, 0.787487, 2.857110 }, + { 3.043825, 0.822299, 2.784156 }, { 3.198383, 0.805056, 2.833971 }, + { 2.096222, 2.284527, 2.693411 }, { 2.058902, 2.270396, 2.601719 }, + { 2.088818, 2.381204, 2.717880 }, { 2.356806, 0.691401, 2.545193 }, + { 2.386469, 0.605803, 2.502849 }, { 2.396691, 0.768628, 2.495743 }, + { 1.891409, 0.166304, 1.584899 }, { 1.959147, 0.204771, 1.522195 }, + { 1.859632, 0.237563, 1.647447 }, { 2.518043, 2.459156, 3.101591 }, + { 2.428358, 2.472460, 3.059407 }, { 2.508114, 2.457102, 3.201075 }, + { 0.320428, 1.244524, 0.006551 }, { 0.286081, 1.304244, 0.079034 }, + { 0.246629, 1.224461, -0.057879 }, { 2.048229, 0.089071, 0.726703 }, + { 2.014095, 0.080462, 0.633104 }, { 2.088850, 0.179593, 0.739177 }, + { 2.034245, 2.982632, 1.329181 }, { 2.031245, 2.911409, 1.259050 }, + { 1.953036, 2.975792, 1.387133 }, { 0.538485, 2.084337, 1.023997 }, + { 0.627754, 2.089723, 0.979252 }, { 0.548110, 2.108365, 1.120589 }, + { 2.212275, 0.056864, 2.952055 }, { 2.213052, 0.078465, 2.854419 }, + { 2.274182, 0.118766, 3.000384 }, { 1.700132, 0.240342, 0.949202 }, + { 1.694106, 0.245036, 1.048910 }, { 1.789110, 0.203045, 0.922903 }, + { 1.557351, 1.014863, 0.118569 }, { 1.498333, 0.953216, 0.066447 }, + { 1.652146, 1.003249, 0.088924 }, { 1.370467, 1.107947, 0.345641 }, + { 1.433625, 1.162976, 0.400256 }, { 1.402511, 1.104544, 0.250976 }, + { 0.051230, 0.959064, 0.306681 }, { 0.137569, 0.966428, 0.256769 }, + { -0.023371, 0.993105, 0.249444 }, { 1.061472, 0.435716, 0.312109 }, + { 1.001351, 0.476028, 0.243114 }, { 1.147227, 0.407409, 0.269158 }, + { 1.159078, 1.784237, 1.666312 }, { 1.243340, 1.831701, 1.691750 }, + { 1.103225, 1.769421, 1.747927 }, { 2.346733, 2.132205, 2.314271 }, + { 2.250042, 2.143686, 2.291489 }, { 2.363438, 2.166195, 2.406822 }, + { 1.831914, 0.624811, 2.621164 }, { 1.918548, 0.648796, 2.664973 }, + { 1.841155, 0.633610, 2.521981 }, { 2.313396, 0.217101, 1.823930 }, + { 2.375730, 0.273528, 1.878065 }, { 2.246887, 0.275793, 1.777758 }, + { 0.682445, 0.914361, 0.800937 }, { 0.644296, 0.833146, 0.845083 }, + { 0.733038, 0.887148, 0.719084 }, { 1.290598, 2.697603, 1.716289 }, + { 1.300953, 2.723287, 1.812378 }, { 1.220298, 2.754714, 1.673908 }, + { 2.699916, 0.577677, 1.036050 }, { 2.781543, 0.527541, 1.064746 }, + { 2.676811, 0.646124, 1.105196 }, { 2.379672, 1.923759, 2.151954 }, + { 2.363378, 2.011183, 2.197688 }, { 2.414151, 1.940385, 2.059570 }, + { 2.918502, 2.910934, 1.384671 }, { 2.835120, 2.891595, 1.436376 }, + { 2.996449, 2.914455, 1.447216 }, { 3.076292, 0.830083, 0.821021 }, + { 3.048771, 0.918554, 0.858645 }, { 3.145879, 0.844013, 0.750568 }, + { 0.218858, 2.069650, 1.317117 }, { 0.146551, 2.023580, 1.368588 }, + { 0.283616, 2.001745, 1.282544 }, { 0.020619, 0.874374, 2.443902 }, + { -0.012722, 0.782671, 2.465787 }, { 0.091966, 0.900318, 2.508991 }, + { 2.521324, 1.753594, 2.320911 }, { 2.464712, 1.785120, 2.244745 }, + { 2.490042, 1.796457, 2.405670 }, { 2.057530, 3.102252, 2.695123 }, + { 1.972974, 3.145551, 2.726356 }, { 2.053180, 3.088109, 2.596224 }, + { 2.032116, 0.595488, 1.461278 }, { 2.063105, 0.673032, 1.516293 }, + { 2.016531, 0.625497, 1.367169 }, { 1.491030, 0.686757, 2.193506 }, + { 1.571887, 0.657781, 2.142296 }, { 1.456372, 0.772463, 2.155382 }, + { 1.455156, 0.193460, 2.956994 }, { 1.455369, 0.291350, 2.977428 }, + { 1.407622, 0.177574, 2.870460 }, { 3.024817, 1.123669, 2.374621 }, + { 3.033344, 1.024199, 2.380361 }, { 2.959151, 1.155498, 2.442993 }, + { 2.168128, 2.952341, 0.763788 }, { 2.136058, 3.040271, 0.728577 }, + { 2.161865, 2.883290, 0.691728 }, { 0.030132, 2.537830, 0.817716 }, + { 0.028067, 2.528831, 0.718143 }, { -0.043010, 2.599343, 0.847151 }, + { 1.305384, 0.363666, 0.213584 }, { 1.332245, 0.277124, 0.171289 }, + { 1.357434, 0.377131, 0.297902 }, { 2.632164, 0.136342, 0.656899 }, + { 2.641994, 0.192049, 0.574437 }, { 2.718966, 0.090940, 0.677000 }, + { 0.466417, 1.949597, 0.605141 }, { 0.461019, 1.914586, 0.511626 }, + { 0.392703, 1.909972, 0.659877 }, { 0.398048, 0.367850, 2.287718 }, + { 0.479261, 0.318780, 2.319286 }, { 0.398678, 0.460705, 2.324835 }, + { 1.741551, 1.439929, 1.553944 }, { 1.803090, 1.434375, 1.475318 }, + { 1.675412, 1.365036, 1.549864 }, { 1.050770, 2.232698, 1.500930 }, + { 1.090450, 2.316498, 1.538386 }, { 1.118122, 2.186993, 1.442837 }, + { 1.717596, 2.258860, 0.597207 }, { 1.699232, 2.267105, 0.499254 }, + { 1.691849, 2.343831, 0.643217 }, { 2.212399, 2.773996, 0.555699 }, + { 2.267986, 2.695320, 0.582536 }, { 2.270206, 2.841640, 0.510064 }, + { 0.833825, 0.137371, 0.654410 }, { 0.765034, 0.067362, 0.635268 }, + { 0.827607, 0.209855, 0.585798 }, { 1.484024, 2.431415, 1.172574 }, + { 1.387432, 2.405719, 1.169462 }, { 1.492573, 2.524800, 1.207303 }, + { 1.092009, 1.304918, 0.645060 }, { 1.037350, 1.229798, 0.608053 }, + { 1.147515, 1.271401, 0.721189 }, { 2.926792, 1.120965, 0.145719 }, + { 2.857706, 1.056880, 0.179192 }, { 2.991043, 1.072650, 0.086242 }, + { 0.854119, 2.974997, 1.408124 }, { 0.869941, 2.893842, 1.351878 }, + { 0.813268, 2.947735, 1.495233 }, { 0.395941, 1.628557, 1.722443 }, + { 0.405298, 1.574434, 1.806008 }, { 0.467522, 1.602497, 1.657659 }, + { 0.691627, 3.086008, 2.208135 }, { 0.612388, 3.045434, 2.253686 }, + { 0.675996, 3.087823, 2.109380 }, { 1.902204, 2.035316, 0.346277 }, + { 1.910733, 2.004423, 0.441003 }, { 1.831359, 2.105646, 0.340402 }, + { 1.645593, 0.569489, 3.018336 }, { 1.729209, 0.620777, 3.037777 }, + { 1.619165, 0.516928, 3.099199 }, { 2.037092, 0.324540, 1.440475 }, + { 2.007342, 0.418695, 1.456280 }, { 2.112294, 0.323963, 1.374562 }, + { 1.709332, 0.025492, 1.460518 }, { 1.782128, 0.081685, 1.499798 }, + { 1.731019, -0.071218, 1.473815 }, { 1.822994, 1.386993, 1.285320 }, + { 1.852887, 1.448187, 1.212095 }, { 1.740161, 1.338800, 1.256753 }, + { 2.640290, 2.907177, 2.258028 }, { 2.588012, 2.895568, 2.173575 }, + { 2.737965, 2.909498, 2.236716 }, { 2.830221, 1.201105, 2.554194 }, + { 2.789919, 1.238195, 2.470528 }, { 2.775225, 1.229030, 2.632907 }, + { 0.312595, 1.269209, 1.183354 }, { 0.399686, 1.257023, 1.230964 }, + { 0.276338, 1.360314, 1.202979 }, { 1.219074, 1.304704, 1.406725 }, + { 1.187584, 1.394406, 1.437740 }, { 1.171917, 1.233162, 1.458280 }, + { 0.088165, 1.132162, 2.948754 }, { 0.041748, 1.067558, 3.009349 }, + { 0.029670, 1.152032, 2.870119 }, { 2.146272, 1.433617, 2.390542 }, + { 2.138419, 1.336790, 2.414267 }, { 2.230608, 1.448556, 2.338924 }, + { 1.126390, 2.619047, 0.229842 }, { 1.067299, 2.650958, 0.155748 }, + { 1.172580, 2.697254, 0.271677 }, { 0.772610, 0.713337, 2.611108 }, + { 0.748713, 0.722431, 2.514432 }, { 0.849110, 0.774120, 2.632397 }, + { 2.447981, 2.453893, 0.248781 }, { 2.367628, 2.396337, 0.233596 }, + { 2.503037, 2.415403, 0.322858 }, { 0.263845, 2.493355, 0.144281 }, + { 0.335474, 2.526864, 0.083072 }, { 0.263751, 2.547567, 0.228310 }, + { 2.711082, 1.281642, 2.333081 }, { 2.719674, 1.381229, 2.336037 }, + { 2.715094, 1.250643, 2.238091 }, { 2.676279, 0.650773, 2.902170 }, + { 2.580775, 0.630422, 2.880608 }, { 2.692490, 0.748955, 2.892301 }, + { 2.877642, 0.476823, 2.154497 }, { 2.817917, 0.409468, 2.110950 }, + { 2.850465, 0.488665, 2.250002 }, { 1.876275, 1.779603, 0.923386 }, + { 1.813814, 1.729332, 0.863624 }, { 1.843092, 1.775125, 1.017613 }, + { 1.999578, 2.412161, 1.792502 }, { 2.001027, 2.333447, 1.854162 }, + { 1.945209, 2.390079, 1.711530 }, { 1.345610, 0.547217, 1.984605 }, + { 1.382190, 0.579678, 2.071830 }, { 1.346384, 0.447229, 1.983274 }, + { 0.367515, 3.057362, 1.507738 }, { 0.302379, 3.058892, 1.431877 }, + { 0.427117, 3.137462, 1.502119 }, { 3.011322, 0.923958, 3.084858 }, + { 3.042668, 0.880246, 3.000557 }, { 2.945836, 0.864150, 3.131061 }, + { 2.392270, 1.829070, 2.562705 }, { 2.428474, 1.901010, 2.621983 }, + { 2.295803, 1.847105, 2.543500 }, { 1.842649, 0.637906, 1.017004 }, + { 1.801396, 0.602764, 0.932961 }, { 1.785666, 0.612644, 1.095201 }, + { 0.617497, 0.921076, 3.039116 }, { 0.658644, 0.998296, 3.087530 }, + { 0.598462, 0.947354, 2.944527 }, { 3.000423, 0.591953, 0.667713 }, + { 3.020428, 0.676659, 0.716955 }, { 3.082706, 0.560794, 0.620188 }, + { 1.169441, 1.042230, 2.178946 }, { 1.245754, 0.989978, 2.140921 }, + { 1.083286, 1.006290, 2.143090 }, { 2.036610, 2.690183, 0.260508 }, + { 2.009603, 2.593929, 0.262906 }, { 2.055502, 2.721831, 0.353467 }, + { 0.678618, 0.253853, 2.315954 }, { 0.675382, 0.155406, 2.298699 }, + { 0.739093, 0.272140, 2.393467 }, { 1.005798, 2.653579, 3.072247 }, + { 0.962132, 2.738055, 3.041310 }, { 1.102456, 2.654701, 3.046633 }, + { 1.212983, 0.709212, 2.939614 }, { 1.130614, 0.765585, 2.945729 }, + { 1.252068, 0.717137, 2.847911 }, { 1.489914, 2.604836, 0.398980 }, + { 1.495513, 2.508495, 0.372768 }, { 1.561823, 2.625570, 0.465306 }, + { 0.270020, 3.000161, 0.139979 }, { 0.272046, 2.929216, 0.069533 }, + { 0.175190, 3.025624, 0.158928 }, { 0.116325, 2.146527, 0.405128 }, + { 0.197633, 2.090927, 0.387876 }, { 0.062843, 2.154374, 0.320996 }, + { 2.194390, 2.363083, 1.040172 }, { 2.203799, 2.458153, 1.069720 }, + { 2.099466, 2.333825, 1.051723 }, { 2.614382, 2.672006, 2.545183 }, + { 2.702055, 2.682635, 2.498273 }, { 2.547538, 2.632268, 2.482312 }, + { 1.172490, 1.978854, 0.953816 }, { 1.153736, 1.956987, 0.858056 }, + { 1.208445, 1.897823, 1.000089 }, { 0.312017, 1.290869, 2.693676 }, + { 0.400078, 1.306245, 2.738496 }, { 0.308832, 1.197685, 2.657527 }, + { 1.098510, 0.153188, 0.479180 }, { 1.082395, 0.060457, 0.445397 }, + { 1.013706, 0.205890, 0.473643 }, { 1.784232, 1.875739, 2.847711 }, + { 1.880468, 1.867252, 2.821892 }, { 1.756731, 1.795507, 2.900688 }, + { 0.350440, 0.678473, 0.534561 }, { 0.304420, 0.661506, 0.447417 }, + { 0.444709, 0.645498, 0.529451 }, { 1.169279, 2.747161, 2.285225 }, + { 1.268213, 2.761560, 2.283046 }, { 1.142212, 2.689916, 2.207827 }, + { 0.570823, 2.828304, 0.432263 }, { 0.477361, 2.806398, 0.460280 }, + { 0.630151, 2.749729, 0.449758 }, { 2.444623, 1.342698, 1.778805 }, + { 2.396114, 1.374737, 1.697438 }, { 2.502313, 1.264669, 1.754654 }, + { 1.238327, 1.673449, 0.435189 }, { 1.219243, 1.771146, 0.425637 }, + { 1.289703, 1.641577, 0.355536 }, { 0.153594, 2.293098, 1.181422 }, + { 0.090310, 2.342888, 1.240718 }, { 0.168866, 2.201468, 1.218445 }, + { 0.632666, 0.899307, 0.356243 }, { 0.723101, 0.856637, 0.355391 }, + { 0.581983, 0.871642, 0.274598 }, { 1.171387, 1.540110, 0.022861 }, + { 1.256436, 1.556098, -0.027249 }, { 1.158655, 1.612352, 0.090824 }, + { 1.775234, 2.639426, 1.417896 }, { 1.845711, 2.597737, 1.360493 }, + { 1.690109, 2.646981, 1.365967 }, { 2.286208, 0.014645, 1.462383 }, + { 2.206073, 0.018088, 1.402662 }, { 2.347516, 0.090501, 1.440309 }, + { 1.855339, 2.566208, 2.578398 }, { 1.790876, 2.631256, 2.618564 }, + { 1.937501, 2.561317, 2.635191 }, { 1.365327, 2.886261, 0.999166 }, + { 1.387151, 2.932093, 1.085324 }, { 1.306889, 2.945537, 0.943747 }, + { 1.928061, 0.624805, 1.853047 }, { 2.014539, 0.628321, 1.903139 }, + { 1.890842, 0.717205, 1.844269 }, { 1.819535, 1.163727, 2.634753 }, + { 1.795091, 1.160180, 2.731654 }, { 1.776597, 1.087246, 2.586722 }, + { 0.437791, 0.196657, 0.571311 }, { 0.395955, 0.125509, 0.627771 }, + { 0.517613, 0.159163, 0.524167 }, { 0.990439, 3.084440, 1.049646 }, + { 0.979541, 3.092549, 0.950573 }, { 0.982817, 2.988350, 1.076266 }, + { 0.135630, 1.424594, 2.366009 }, { 0.186875, 1.452547, 2.447204 }, + { 0.038302, 1.419049, 2.388291 }, { 0.774298, 0.700782, 3.014136 }, + { 0.720206, 0.631836, 2.965965 }, { 0.718205, 0.782026, 3.030041 }, + { 0.336274, 0.174819, 1.183050 }, { 0.314277, 0.220780, 1.097005 }, + { 0.375410, 0.240907, 1.247087 }, { 2.624106, 1.198353, 2.749908 }, + { 2.560306, 1.194010, 2.826790 }, { 2.597145, 1.131696, 2.680410 }, + { 1.093957, 0.845871, 2.479553 }, { 1.188103, 0.816901, 2.462315 }, + { 1.093910, 0.922684, 2.543582 }, { 1.144358, 2.465872, 2.785667 }, + { 1.125932, 2.423311, 2.697072 }, { 1.162905, 2.394834, 2.853561 }, + { 0.649380, 2.048907, 1.653051 }, { 0.724093, 2.114135, 1.665825 }, + { 0.641274, 2.026088, 1.556027 }, { 2.643681, 3.013983, 1.808290 }, + { 2.566518, 3.046667, 1.753722 }, { 2.715972, 3.083077, 1.808537 }, + { 1.812965, 0.376719, 1.762352 }, { 1.801808, 0.339809, 1.854619 }, + { 1.843189, 0.471878, 1.767946 }, { 0.234547, 1.903456, 0.762488 }, + { 0.157170, 1.852394, 0.724997 }, { 0.206290, 1.997433, 0.781722 }, + { 1.299412, 0.664482, 1.563116 }, { 1.311728, 0.569449, 1.534531 }, + { 1.233073, 0.709042, 1.503004 }, { 0.471100, 2.414620, 0.417294 }, + { 0.391412, 2.471872, 0.436584 }, { 0.481394, 2.346350, 0.489635 }, + { 1.105199, 0.810713, 1.415766 }, { 1.028862, 0.771144, 1.466826 }, + { 1.075099, 0.833553, 1.323179 }, { 0.357194, 1.129205, 2.166708 }, + { 0.381063, 1.108356, 2.071863 }, { 0.258268, 1.120957, 2.178772 }, + { 2.141714, 2.142842, 1.486301 }, { 2.214417, 2.177650, 1.427118 }, + { 2.173165, 2.142784, 1.581227 }, { 1.702656, 2.224459, 0.331437 }, + { 1.603028, 2.232063, 0.335497 }, { 1.732962, 2.233784, 0.236598 }, + { 1.658323, 0.033785, 3.067776 }, { 1.664949, -0.057469, 3.027418 }, + { 1.645833, 0.101485, 2.995245 }, { 1.569246, 2.399663, 2.180838 }, + { 1.632507, 2.472664, 2.206702 }, { 1.618676, 2.312866, 2.176035 }, + { 1.419905, 1.952344, 3.057437 }, { 1.445836, 1.856069, 3.049776 }, + { 1.336568, 1.968723, 3.004648 }, { 0.928720, 2.693943, 2.063425 }, + { 1.010503, 2.637688, 2.075549 }, { 0.868058, 2.681946, 2.142014 }, + { 1.634044, 1.676942, 0.314676 }, { 1.598932, 1.702735, 0.404686 }, + { 1.693576, 1.597106, 0.323743 }, { 0.830401, 2.033807, 0.958468 }, + { 0.877584, 2.009187, 0.873806 }, { 0.842339, 1.960779, 1.025731 }, + { 1.967128, 2.547359, 2.082619 }, { 1.876900, 2.575384, 2.115383 }, + { 1.998137, 2.610913, 2.011912 }, { 1.914760, 2.240130, 2.014567 }, + { 1.821780, 2.210964, 2.037023 }, { 1.919160, 2.340032, 2.014097 }, + { 1.204308, 0.740440, 1.830255 }, { 1.256133, 0.732237, 1.745127 }, + { 1.232956, 0.668707, 1.893766 }, { 2.380670, 2.109764, 1.022198 }, + { 2.326708, 2.025893, 1.029529 }, { 2.321764, 2.184785, 0.992169 }, + { 2.366020, 1.001282, 0.597718 }, { 2.285764, 1.010658, 0.656634 }, + { 2.447119, 0.985657, 0.654100 }, { 0.691093, 0.752276, 2.340281 }, + { 0.672345, 0.665438, 2.294371 }, { 0.638224, 0.825117, 2.296702 }, + { 0.414470, 0.458922, 2.024676 }, { 0.426859, 0.408179, 1.939402 }, + { 0.398400, 0.394716, 2.099639 }, { 0.167761, 2.702213, 0.308317 }, + { 0.164799, 2.726732, 0.211415 }, { 0.075331, 2.705407, 0.346351 }, + { 1.577121, 1.524739, 1.021991 }, { 1.589557, 1.439621, 1.072984 }, + { 1.597070, 1.602521, 1.081588 }, { 1.464515, 1.174865, 1.762501 }, + { 1.478245, 1.202376, 1.667345 }, { 1.399154, 1.099275, 1.766248 }, + { 2.156436, 2.877467, 1.024294 }, { 2.161692, 2.918408, 0.933211 }, + { 2.067570, 2.833082, 1.035814 }, { 2.271721, 2.343209, 1.882211 }, + { 2.257455, 2.432253, 1.838994 }, { 2.291592, 2.356109, 1.979364 }, + { 0.807058, 1.819083, 1.176660 }, { 0.777268, 1.875932, 1.253347 }, + { 0.730406, 1.763369, 1.144717 }, { 0.521151, 2.636134, 0.772735 }, + { 0.427182, 2.604330, 0.760148 }, { 0.582650, 2.557415, 0.777345 }, + { 2.865336, 0.074459, 1.821400 }, { 2.952667, 0.047840, 1.780599 }, + { 2.830128, 0.155624, 1.774788 }, { 1.032809, 2.928064, 1.935884 }, + { 1.018040, 2.848521, 1.994662 }, { 1.035481, 2.898836, 1.840289 }, + { 0.603364, 2.018313, 2.974977 }, { 0.686166, 2.053333, 3.018767 }, + { 0.559972, 1.950936, 3.034789 }, { 2.496931, 1.651761, 1.499709 }, + { 2.426104, 1.589820, 1.533574 }, { 2.465513, 1.695407, 1.415400 }, + { 1.992895, 1.432951, 0.877265 }, { 2.091252, 1.415249, 0.880807 }, + { 1.970437, 1.479332, 0.791565 }, { 1.349627, 0.944871, 0.891822 }, + { 1.294930, 0.866245, 0.920567 }, { 1.430409, 0.952441, 0.950277 }, + { 0.688705, 1.806392, 1.795933 }, { 0.675348, 1.802183, 1.894948 }, + { 0.661166, 1.896480, 1.762382 }, { 2.765604, 1.268705, 0.455509 }, + { 2.832068, 1.330161, 0.498002 }, { 2.804218, 1.176637, 0.449819 }, + { 1.087520, 0.313048, 1.525021 }, { 1.171839, 0.329995, 1.474000 }, + { 1.010104, 0.311057, 1.461754 }, { 2.264949, 1.629745, 1.089892 }, + { 2.266355, 1.729527, 1.083429 }, { 2.294268, 1.590285, 1.002810 }, + { 1.678565, 0.632669, 1.470373 }, { 1.624608, 0.654483, 1.551692 }, + { 1.740148, 0.708734, 1.449838 }, { 2.043401, 0.809955, 1.606486 }, + { 1.981133, 0.814050, 1.684626 }, { 2.114947, 0.878990, 1.617221 }, + { 1.188958, 2.411149, 1.184279 }, { 1.117315, 2.345728, 1.160041 }, + { 1.172674, 2.445693, 1.276699 }, { 2.032803, 1.248583, 1.710235 }, + { 2.108155, 1.185674, 1.691144 }, { 2.065892, 1.323986, 1.766976 }, + { 0.653339, 1.578073, 0.294654 }, { 0.578773, 1.637336, 0.325114 }, + { 0.691682, 1.613835, 0.209501 }, { 0.009546, 0.004266, 0.204101 }, + { -0.040074, -0.018504, 0.287883 }, { 0.072281, 0.080040, 0.222063 }, + { 0.301904, 1.858297, 1.612515 }, { 0.355925, 1.926715, 1.661512 }, + { 0.316285, 1.768475, 1.654050 }, { 0.210458, 0.733536, 2.307309 }, + { 0.180804, 0.654013, 2.254425 }, { 0.130306, 0.783770, 2.339748 }, + { 0.468404, 1.026549, 2.487707 }, { 0.469169, 0.997854, 2.391915 }, + { 0.528829, 1.105369, 2.499377 }, { 1.253251, 2.170940, 2.427798 }, + { 1.218924, 2.125540, 2.345576 }, { 1.292201, 2.102762, 2.489723 }, + { 1.591250, 2.288296, 1.789703 }, { 1.535539, 2.354383, 1.839990 }, + { 1.577205, 2.196951, 1.827900 }, { 2.946891, 1.547805, 0.043940 }, + { 2.976856, 1.626139, 0.098401 }, { 3.024835, 1.510346, -0.006275 }, + { 1.371900, 2.628764, 0.835498 }, { 1.372210, 2.716646, 0.883213 }, + { 1.304040, 2.568374, 0.877306 }, { 0.280736, 1.464804, 0.831929 }, + { 0.228581, 1.472811, 0.746984 }, { 0.347573, 1.539004, 0.837130 }, + { 0.464336, 1.777354, 0.380566 }, { 0.389430, 1.725765, 0.422129 }, + { 0.427185, 1.855411, 0.330296 }, { 1.262352, 0.703325, 0.972513 }, + { 1.191673, 0.644211, 0.933656 }, { 1.344104, 0.649143, 0.992027 }, + { 1.863906, 2.737826, 0.051729 }, { 1.794894, 2.699801, 0.113303 }, + { 1.945526, 2.762192, 0.104117 }, { 1.934621, 0.339861, 2.346475 }, + { 1.953277, 0.266858, 2.280729 }, { 1.887904, 0.301739, 2.426251 }, + { 2.302869, 1.427632, 1.252785 }, { 2.397274, 1.397143, 1.240212 }, + { 2.280683, 1.496666, 1.183922 }, { 1.499814, 2.033362, 1.994311 }, + { 1.554854, 1.968437, 1.941819 }, { 1.450097, 1.984557, 2.066049 }, + { 2.083899, 1.448550, 1.427712 }, { 2.155069, 1.430052, 1.359942 }, + { 1.994861, 1.452375, 1.382351 }, { 1.166293, 0.405665, 2.411606 }, + { 1.219526, 0.442955, 2.487604 }, { 1.089623, 0.466645, 2.391527 }, + { 1.884977, 2.484835, 0.910720 }, { 1.800940, 2.508832, 0.862120 }, + { 1.960852, 2.539311, 0.875009 }, { 1.112780, 1.256626, 2.318798 }, + { 1.124735, 1.166291, 2.277606 }, { 1.015258, 1.277965, 2.324623 }, + { 1.261958, 0.079632, 1.408891 }, { 1.210228, -0.005830, 1.413406 }, + { 1.296352, 0.102628, 1.499931 }, { 2.585863, 2.434800, 1.911444 }, + { 2.534322, 2.378065, 1.975667 }, { 2.671546, 2.463898, 1.954008 }, + { 1.730110, 2.631838, 2.128379 }, { 1.705843, 2.703561, 2.193702 }, + { 1.699136, 2.658108, 2.036998 }, { 0.786013, 0.466280, 2.703562 }, + { 0.791829, 0.555341, 2.658458 }, { 0.709772, 0.466601, 2.768271 }, + { 2.124892, 1.358270, 0.553264 }, { 2.034419, 1.400658, 0.549024 }, + { 2.119175, 1.272546, 0.604438 }, { 1.937050, 2.839942, 0.507969 }, + { 1.875834, 2.818483, 0.584074 }, { 2.028851, 2.805971, 0.528431 }, + { 0.694033, 3.048894, 0.117965 }, { 0.742816, 3.121531, 0.166381 }, + { 0.609109, 3.027780, 0.166360 }, { 1.831965, 2.250876, 0.092662 }, + { 1.865896, 2.301798, 0.013570 }, { 1.773638, 2.175866, 0.061491 }, + { 0.423245, 1.234308, 0.866709 }, { 0.360637, 1.303337, 0.830443 }, + { 0.397879, 1.212525, 0.960954 }, { 0.694900, 2.540850, 0.372187 }, + { 0.602805, 2.502432, 0.365669 }, { 0.720059, 2.582155, 0.284660 }, + { 1.613218, 1.068730, 0.571353 }, { 1.538921, 1.001994, 0.566242 }, + { 1.695532, 1.030236, 0.529608 }, { 0.351434, 0.972531, 0.811903 }, + { 0.260612, 0.979713, 0.853132 }, { 0.394644, 1.062703, 0.810529 }, + { 0.654466, 0.668950, 0.939867 }, { 0.702533, 0.633043, 0.859865 }, + { 0.710634, 0.655200, 1.021452 }, { 0.603028, 1.706677, 1.011611 }, + { 0.580653, 1.621617, 0.964026 }, { 0.523907, 1.767799, 1.009608 }, + { 1.984519, 2.241066, 0.609025 }, { 2.023379, 2.331592, 0.626204 }, + { 1.884845, 2.247855, 0.604676 }, { 2.409340, 0.321441, 3.077053 }, + { 2.478278, 0.391544, 3.095303 }, { 2.325876, 0.364808, 3.043095 }, + { 0.107482, 0.226784, 2.149938 }, { 0.116209, 0.319603, 2.186110 }, + { 0.058157, 0.169871, 2.215724 }, { 2.516283, 2.299608, 1.651831 }, + { 2.498891, 2.206877, 1.684975 }, { 2.522873, 2.362117, 1.729607 }, + { 0.166350, 0.223961, 0.204554 }, { 0.252719, 0.174404, 0.195355 }, + { 0.155959, 0.287342, 0.127907 }, { 1.790683, 2.102293, 2.508842 }, + { 1.772161, 2.115965, 2.606156 }, { 1.727524, 2.033989, 2.472162 }, + { 0.804515, 2.449580, 1.058470 }, { 0.834701, 2.389681, 1.132638 }, + { 0.826442, 2.407366, 0.970509 }, { 0.893496, 1.408646, 1.094836 }, + { 0.884226, 1.374665, 1.001245 }, { 0.977331, 1.462610, 1.102556 }, + { 1.324336, 0.283014, 1.983930 }, { 1.249350, 0.246218, 1.928948 }, + { 1.311952, 0.256118, 2.079446 }, { 2.246377, 2.623759, 1.150493 }, + { 2.254787, 2.651518, 1.246195 }, { 2.233979, 2.704806, 1.093243 }, + { 2.622015, 2.142252, 1.121850 }, { 2.689193, 2.164431, 1.051174 }, + { 2.532526, 2.128120, 1.079520 }, { 2.868567, 0.744064, 0.453349 }, + { 2.910325, 0.673469, 0.510556 }, { 2.806360, 0.701325, 0.387747 }, + { 3.007500, 2.824869, 0.443635 }, { 3.007007, 2.870315, 0.532711 }, + { 2.943592, 2.871184, 0.382230 }, { 0.618477, 0.645863, 0.479989 }, + { 0.594221, 0.568779, 0.421086 }, { 0.609509, 0.731187, 0.428613 }, + { 0.315716, 2.761151, 1.152915 }, { 0.333548, 2.715008, 1.239822 }, + { 0.223414, 2.799613, 1.153918 }, { 2.418530, 2.718375, 0.233422 }, + { 2.423642, 2.619487, 0.219456 }, { 2.380935, 2.761708, 0.151514 }, + { 1.098775, 2.225525, 0.111034 }, { 1.066019, 2.283329, 0.185771 }, + { 1.184183, 2.181157, 0.138180 }, { 0.073228, 2.893589, 1.127852 }, + { -0.000546, 2.826243, 1.132538 }, { 0.059832, 2.952201, 1.047945 }, + { 2.174281, 0.457878, 2.973554 }, { 2.121013, 0.408744, 3.042462 }, + { 2.172823, 0.555783, 2.993862 }, { 1.661179, 0.921490, 2.630975 }, + { 1.665185, 0.927948, 2.730685 }, { 1.665678, 0.825419, 2.603585 }, + { 2.933824, 1.488535, 1.260173 }, { 2.909874, 1.400289, 1.300658 }, + { 2.862083, 1.516509, 1.196371 }, { 0.456309, 2.283995, 2.966447 }, + { 0.466757, 2.196379, 3.013504 }, { 0.361327, 2.294986, 2.937162 }, + { 0.384923, 0.707170, 1.649992 }, { 0.418731, 0.700554, 1.556113 }, + { 0.288802, 0.734733, 1.648941 }, { 1.510475, 2.724715, 1.326010 }, + { 1.413124, 2.746983, 1.331212 }, { 1.562660, 2.807736, 1.306410 }, + { 2.250746, 0.876319, 0.084095 }, { 2.321093, 0.946839, 0.075252 }, + { 2.215587, 0.875860, 0.177709 }, { 0.977551, 0.759542, 0.731438 }, + { 1.009700, 0.844792, 0.772656 }, { 1.044178, 0.686987, 0.748662 }, + { 1.871166, 1.469743, 1.990566 }, { 1.831271, 1.463875, 2.082075 }, + { 1.849894, 1.386424, 1.939522 }, { 2.976639, 2.909585, 2.965670 }, + { 2.896178, 2.903513, 2.906601 }, { 2.955625, 2.966962, 3.044830 }, + { 0.219237, 0.614174, 0.309084 }, { 0.158141, 0.621804, 0.230286 }, + { 0.312225, 0.595369, 0.277468 }, { 0.981300, 0.603983, 2.324795 }, + { 0.882565, 0.588395, 2.321892 }, { 1.001037, 0.681675, 2.384581 }, + { 0.755745, 1.121905, 0.406068 }, { 0.691338, 1.191344, 0.438159 }, + { 0.709373, 1.033485, 0.400449 }, { 1.727780, 0.415657, 0.225759 }, + { 1.724835, 0.315869, 0.219966 }, { 1.637306, 0.450294, 0.250552 }, + { 2.250400, 1.714328, 1.807288 }, { 2.201134, 1.794153, 1.841942 }, + { 2.313622, 1.681184, 1.877320 }, { 1.251501, 3.006716, 0.790040 }, + { 1.153176, 3.024619, 0.786643 }, { 1.270862, 2.918652, 0.746798 }, + { 1.408456, 0.117617, 0.777739 }, { 1.355175, 0.033350, 0.785506 }, + { 1.406323, 0.166559, 0.864918 }, { 0.191205, 1.398354, 0.571156 }, + { 0.243639, 1.328404, 0.522600 }, { 0.109777, 1.356822, 0.611709 }, + { 0.168897, 1.033560, 0.985840 }, { 0.226152, 0.997522, 1.059481 }, + { 0.076618, 1.050336, 1.020529 }, { 0.899943, 2.296334, 1.263741 }, + { 0.941794, 2.238530, 1.193690 }, { 0.936440, 2.271641, 1.353508 }, + { 3.025877, 1.802499, 0.139230 }, { 3.014528, 1.810825, 0.238234 }, + { 3.120663, 1.822856, 0.114713 }, { 2.165556, 2.121814, 1.756587 }, + { 2.133566, 2.054018, 1.822771 }, { 2.183626, 2.208257, 1.803504 }, + { 2.014080, 0.353870, 1.050143 }, { 1.947732, 0.401211, 1.108082 }, + { 2.045383, 0.270858, 1.096285 }, { 1.032910, 0.439954, 2.784389 }, + { 1.039158, 0.468637, 2.879983 }, { 0.940927, 0.458674, 2.749913 }, + { 2.768091, 0.500326, 2.411384 }, { 2.832257, 0.519231, 2.485716 }, + { 2.693746, 0.442723, 2.445366 }, { 2.006408, 0.715128, 1.227328 }, + { 1.975360, 0.677657, 1.139967 }, { 1.940802, 0.783386, 1.259525 }, + { 2.487491, 2.094551, 1.399436 }, { 2.575522, 2.109672, 1.354471 }, + { 2.418647, 2.154795, 1.359050 }, { 1.382277, 0.933263, 2.057272 }, + { 1.464198, 0.988093, 2.040457 }, { 1.331486, 0.922156, 1.971851 }, + { 0.814603, 1.428325, 2.639752 }, { 0.800255, 1.459433, 2.545803 }, + { 0.763166, 1.486824, 2.702459 }, { 1.261287, 0.211828, 2.224595 }, + { 1.241577, 0.276306, 2.298447 }, { 1.224565, 0.121861, 2.248203 }, + { 1.619485, 2.689898, 0.188250 }, { 1.588224, 2.651442, 0.275106 }, + { 1.626511, 2.789316, 0.196419 }, { 0.418282, 2.348942, 1.783532 }, + { 0.446726, 2.334551, 1.688749 }, { 0.340773, 2.412083, 1.785854 }, + { 0.074372, 0.645818, 1.465995 }, { 0.111170, 0.656995, 1.373686 }, + { 0.051180, 0.549745, 1.481229 }, { 3.103577, 0.430002, 1.792040 }, + { 3.127296, 0.345212, 1.839453 }, { 3.185557, 0.486255, 1.781320 }, + { 0.656926, 1.071854, 1.113254 }, { 0.740429, 1.082080, 1.059192 }, + { 0.603347, 0.995283, 1.077673 }, { 1.082612, 2.167030, 1.119109 }, + { 1.112438, 2.118508, 1.036914 }, { 1.121778, 2.122971, 1.199885 }, + { 1.685950, 2.668299, 0.595540 }, { 1.654574, 2.595554, 0.656563 }, + { 1.701733, 2.751685, 0.648433 }, { 1.877991, 1.451300, 0.501414 }, + { 1.860443, 1.441725, 0.403432 }, { 1.791928, 1.469157, 0.549104 }, + { 1.193680, 2.367192, 1.806688 }, { 1.230655, 2.274677, 1.798090 }, + { 1.267246, 2.430350, 1.831166 }, { 1.262868, 3.023321, 2.111573 }, + { 1.218133, 3.027728, 2.200900 }, { 1.198796, 2.986934, 2.043964 }, + { 2.363530, 1.819884, 0.872829 }, { 2.421597, 1.755189, 0.823403 }, + { 2.406757, 1.843780, 0.959779 }, { 2.828612, 2.346733, 0.601532 }, + { 2.871731, 2.429490, 0.565585 }, { 2.896460, 2.273475, 0.606992 }, + { 1.479757, 1.908335, 0.805231 }, { 1.432019, 1.821825, 0.820629 }, + { 1.493505, 1.954847, 0.892682 }, { 2.447036, 2.469183, 1.388989 }, + { 2.484687, 2.415866, 1.464750 }, { 2.421583, 2.560194, 1.421687 }, + { 0.390387, 2.304647, 0.871009 }, { 0.343645, 2.374860, 0.924723 }, + { 0.452494, 2.253251, 0.930179 }, { 1.331260, 0.646907, 0.168446 }, + { 1.335624, 0.547157, 0.173994 }, { 1.421037, 0.685440, 0.189784 }, + { 2.828654, 2.172696, 2.960263 }, { 2.739741, 2.218000, 2.953789 }, + { 2.815353, 2.073702, 2.965085 }, { 1.031085, 0.986172, 0.843095 }, + { 1.020895, 1.030502, 0.754039 }, { 0.995655, 1.046452, 0.914586 }, + { 1.724838, 0.391131, 2.659596 }, { 1.768809, 0.480924, 2.657695 }, + { 1.633320, 0.399657, 2.698991 }, { 2.588704, 2.692304, 1.035174 }, + { 2.627025, 2.632110, 1.105232 }, { 2.527773, 2.758929, 1.078168 }, + { 2.699075, 0.688808, 0.769271 }, { 2.672432, 0.666009, 0.862921 }, + { 2.792721, 0.657848, 0.752781 }, { 0.703772, 1.603296, 2.794425 }, + { 0.701323, 1.570932, 2.889011 }, { 0.695426, 1.702938, 2.793061 }, + { 0.199272, 0.353715, 0.976004 }, { 0.232097, 0.405137, 0.896767 }, + { 0.126936, 0.290899, 0.947342 }, { 2.546014, 0.024049, 2.369379 }, + { 2.611304, -0.035563, 2.322648 }, { 2.454932, 0.010881, 2.330253 }, + { 0.022823, 1.201578, 0.748523 }, { 0.089773, 1.186154, 0.821185 }, + { -0.020197, 1.290949, 0.761256 }, { 0.132073, 0.862795, 0.586868 }, + { 0.119996, 0.867413, 0.487708 }, { 0.214518, 0.810293, 0.607998 }, + { 2.092458, 0.359644, 0.786490 }, { 2.040730, 0.360242, 0.872069 }, + { 2.190376, 0.358194, 0.806735 }, { 0.421056, 2.015500, 1.793066 }, + { 0.440920, 2.024396, 1.890669 }, { 0.503559, 2.035681, 1.740283 }, + { 0.385087, 0.729295, 0.920073 }, { 0.370596, 0.804357, 0.855608 }, + { 0.481900, 0.704266, 0.920879 }, { 0.660259, 0.556115, 1.874230 }, + { 0.674878, 0.507989, 1.787800 }, { 0.637897, 0.651811, 1.855729 }, + { 1.502447, 0.450094, 2.831928 }, { 1.420294, 0.484380, 2.786374 }, + { 1.548974, 0.525641, 2.878058 }, { 0.029169, 0.014635, 1.731543 }, + { 0.026633, 0.054837, 1.640016 }, { 0.060547, 0.083210, 1.797215 }, + { 1.945071, 1.895363, 0.577451 }, { 1.862520, 1.917282, 0.629461 }, + { 2.002888, 1.833848, 0.631051 }, { 2.310390, 0.609079, 0.805817 }, + { 2.224057, 0.654864, 0.827042 }, { 2.298969, 0.510214, 0.815575 }, + { 0.263679, 0.742484, 1.174274 }, { 0.318844, 0.741293, 1.090875 }, + { 0.258625, 0.835913, 1.209567 }, { 2.214362, 2.795311, 3.028770 }, + { 2.276577, 2.856483, 2.979910 }, { 2.193373, 2.833914, 3.118600 }, + { 2.862483, 0.087396, 2.967400 }, { 2.775054, 0.134739, 2.956690 }, + { 2.852752, 0.014295, 3.034940 }, { 1.911967, 1.618076, 2.687047 }, + { 1.939990, 1.699615, 2.737705 }, { 1.934376, 1.629614, 2.590276 }, + { 3.089770, 0.624647, 0.091657 }, { 3.155308, 0.685544, 0.046978 }, + { 2.997098, 0.648104, 0.062301 }, { 0.073286, 1.189907, 2.156408 }, + { 0.052831, 1.175998, 2.253300 }, { 0.036866, 1.278274, 2.127000 }, + { 1.751887, 1.440179, 0.260930 }, { 1.798183, 1.408672, 0.178081 }, + { 1.701865, 1.364040, 0.302169 }, { 0.173609, 2.179533, 0.758562 }, + { 0.240866, 2.219671, 0.820734 }, { 0.176312, 2.227662, 0.670948 }, + { 0.142457, 1.714121, 2.988510 }, { 0.117949, 1.619062, 3.007567 }, + { 0.171225, 1.722647, 2.893118 }, { 1.307838, 1.001512, 1.411174 }, + { 1.271228, 0.912830, 1.439374 }, { 1.232705, 1.066537, 1.399913 }, + { 2.169500, 1.727567, 2.182432 }, { 2.214494, 1.641325, 2.205624 }, + { 2.236708, 1.801605, 2.183625 }, { 1.262072, 0.462936, 1.175858 }, + { 1.169844, 0.436656, 1.147514 }, { 1.323387, 0.459730, 1.096926 }, + { 1.423067, 0.881474, 0.640908 }, { 1.410777, 0.897237, 0.738890 }, + { 1.333599, 0.874747, 0.596747 }, { 1.354799, 1.797455, 1.110787 }, + { 1.284755, 1.765934, 1.174821 }, { 1.443784, 1.760881, 1.138063 }, + { 2.129596, 0.681632, 2.008767 }, { 2.164107, 0.608978, 2.068185 }, + { 2.111495, 0.763493, 2.063275 }, { 2.448219, 0.769518, 0.357171 }, + { 2.453654, 0.740682, 0.452769 }, { 2.364799, 0.732847, 0.315983 }, + { 0.882298, 0.543308, 0.139417 }, { 0.841711, 0.611831, 0.078942 }, + { 0.885374, 0.455061, 0.092482 }, { 0.800295, 1.861557, 2.511300 }, + { 0.895248, 1.830847, 2.504910 }, { 0.776153, 1.875477, 2.607338 }, + { 0.764847, 2.617533, 0.120170 }, { 0.750496, 2.712191, 0.091292 }, + { 0.847962, 2.581897, 0.077486 }, { 2.224452, 2.284036, 0.208382 }, + { 2.184583, 2.300793, 0.118217 }, { 2.231256, 2.185503, 0.224032 }, + { 0.079359, 0.002159, 0.962802 }, { 0.088958, 0.015986, 0.864229 }, + { 0.027587, 0.078089, 1.002228 }, { 2.203527, 0.302158, 2.750022 }, + { 2.118676, 0.267117, 2.710368 }, { 2.181990, 0.363004, 2.826402 }, + { 2.170179, 2.922779, 0.174290 }, { 2.139623, 2.835094, 0.211408 }, + { 2.214502, 2.975912, 0.246487 }, { 0.890672, 0.080190, 2.804656 }, + { 0.938414, 0.126680, 2.730094 }, { 0.956701, 0.052889, 2.874619 }, + { 2.895087, 1.762880, 1.373604 }, { 2.900573, 1.663669, 1.362331 }, + { 2.987003, 1.800097, 1.386500 }, { 1.853496, 2.074764, 1.508729 }, + { 1.948479, 2.059296, 1.481547 }, { 1.801303, 2.107900, 1.430129 }, + { 2.582175, 2.315870, 2.888700 }, { 2.529120, 2.231314, 2.882752 }, + { 2.555198, 2.366456, 2.970634 }, { 2.750479, 0.538398, 1.610168 }, + { 2.766143, 0.560952, 1.514012 }, { 2.664507, 0.579511, 1.640473 }, + { 1.377553, 1.621616, 0.224361 }, { 1.362069, 1.531830, 0.183145 }, + { 1.471939, 1.627547, 0.256858 }, { 0.701605, 1.997351, 0.173637 }, + { 0.647573, 2.049848, 0.239400 }, { 0.768452, 2.057483, 0.129870 }, + { 0.732393, 2.885926, 1.675034 }, { 0.681248, 2.960743, 1.717302 }, + { 0.678998, 2.801575, 1.680869 }, { 1.333051, 1.944054, 2.636380 }, + { 1.270422, 1.992525, 2.697439 }, { 1.304905, 1.848392, 2.628856 }, + { 0.350047, 1.397444, 2.193652 }, { 0.381158, 1.302587, 2.187811 }, + { 0.269866, 1.402622, 2.253185 }, { 2.655774, 2.801154, 1.477291 }, + { 2.607340, 2.769915, 1.559012 }, { 2.612048, 2.883978, 1.442246 }, + { 0.830586, 2.382898, 2.380660 }, { 0.751782, 2.323648, 2.363947 }, + { 0.821711, 2.466316, 2.326230 }, { 0.386076, 2.773589, 2.748805 }, + { 0.415232, 2.861381, 2.710824 }, { 0.309400, 2.737978, 2.695395 }, + { 0.288028, 1.761089, 2.267276 }, { 0.195585, 1.734450, 2.294565 }, + { 0.306586, 1.727296, 2.175006 }, { 2.845222, 3.049689, 0.710560 }, + { 2.938507, 3.015530, 0.699111 }, { 2.796410, 2.992019, 0.776069 }, + { 2.095486, 2.468157, 1.419021 }, { 2.014126, 2.429148, 1.462136 }, + { 2.161124, 2.395254, 1.399606 }, { 0.990751, 0.380958, 1.088061 }, + { 0.962957, 0.355990, 0.995302 }, { 1.050039, 0.309627, 1.125433 }, + { 1.490762, 3.006773, 1.217981 }, { 1.443078, 3.092111, 1.239049 }, + { 1.589527, 3.021852, 1.222217 }, { 1.054051, 1.680650, 2.482261 }, + { 0.992890, 1.601710, 2.487543 }, { 1.097855, 1.694879, 2.571023 }, + { 1.617761, 2.709729, 1.856625 }, { 1.685809, 2.664639, 1.798863 }, + { 1.625149, 2.808851, 1.845661 }, { 0.831548, 0.104590, 1.240112 }, + { 0.854610, 0.030748, 1.303480 }, { 0.870357, 0.084640, 1.150135 }, + { 2.460575, 2.913002, 2.033870 }, { 2.387432, 2.978945, 2.016501 }, + { 2.544679, 2.944073, 1.989585 }, { 0.968554, 1.072304, 0.587917 }, + { 1.021416, 0.999670, 0.543986 }, { 0.886242, 1.090771, 0.534217 }, + { 1.747197, 0.995358, 2.249228 }, { 1.834103, 1.034204, 2.279860 }, + { 1.689613, 0.975781, 2.328606 }, { 2.113166, 1.198713, 2.946735 }, + { 2.164920, 1.232009, 3.025557 }, { 2.082168, 1.276428, 2.891968 }, + { 0.386328, 0.003613, 1.788966 }, { 0.370117, -0.024061, 1.694249 }, + { 0.331931, -0.053732, 1.850224 }, { 1.113078, 2.990990, 0.400315 }, + { 1.033021, 2.934960, 0.421561 }, { 1.196169, 2.937301, 0.414924 }, + { 3.004892, 0.215602, 0.988293 }, { 2.941095, 0.159722, 1.041278 }, + { 2.959599, 0.248333, 0.905364 }, { 1.180028, 0.462930, 3.027119 }, + { 1.194383, 0.448931, 3.125088 }, { 1.205635, 0.556462, 3.002706 }, + { 1.274036, 0.501724, 2.672057 }, { 1.301730, 0.596901, 2.685261 }, + { 1.191003, 0.483553, 2.724738 }, { 2.947187, 2.426754, 0.273837 }, + { 2.910177, 2.352895, 0.217490 }, { 2.962008, 2.507751, 0.217092 }, + { 0.414034, 1.604272, 2.862308 }, { 0.369433, 1.665968, 2.797468 }, + { 0.511529, 1.598227, 2.840903 }, { 0.857555, 1.198856, 1.337218 }, + { 0.815665, 1.254240, 1.265260 }, { 0.790251, 1.181020, 1.408996 }, + { 1.402725, 1.861893, 1.683336 }, { 1.478004, 1.884592, 1.621549 }, + { 1.438488, 1.812987, 1.762893 }, { 1.143436, 2.070677, 2.177391 }, + { 1.126093, 1.974251, 2.197423 }, { 1.140420, 2.085246, 2.078504 }, + { 1.140117, 2.529814, 2.107822 }, { 1.195065, 2.512471, 2.026092 }, + { 1.179853, 2.481181, 2.185642 }, { 1.977009, 0.352605, 0.334132 }, + { 1.906708, 0.390859, 0.274179 }, { 1.962216, 0.384824, 0.427636 }, + { 2.130115, 1.470625, 1.830714 }, { 2.130574, 1.426674, 1.920537 }, + { 2.139711, 1.569528, 1.841947 }, { 0.730700, 0.203115, 1.799955 }, + { 0.694439, 0.296295, 1.801601 }, { 0.830605, 0.206164, 1.803080 }, + { 1.903507, 2.950766, 2.105392 }, { 1.961982, 2.880427, 2.145802 }, + { 1.809765, 2.939068, 2.138189 }, { 1.362461, 0.776317, 2.440580 }, + { 1.373552, 0.711877, 2.364919 }, { 1.401240, 0.864848, 2.414921 }, + { 1.393736, 0.230352, 1.027233 }, { 1.474875, 0.215232, 1.083694 }, + { 1.312059, 0.203810, 1.078462 }, { 0.883267, 2.290109, 0.853754 }, + { 0.964497, 2.279289, 0.796442 }, { 0.862588, 2.203355, 0.898988 }, + { 1.860047, 2.351311, 1.532016 }, { 1.892853, 2.257751, 1.518966 }, + { 1.760116, 2.352393, 1.528474 }, { 0.907781, 1.468871, 0.302742 }, + { 0.943288, 1.506453, 0.388339 }, { 0.808771, 1.482381, 0.298937 }, + { 0.634389, 0.172523, 0.350440 }, { 0.731006, 0.157177, 0.329712 }, + { 0.579360, 0.100624, 0.307988 }, { 0.948849, 0.786484, 1.870334 }, + { 1.046390, 0.765851, 1.862583 }, { 0.902713, 0.711892, 1.918370 }, + { 0.928507, 1.428757, 1.800533 }, { 0.964649, 1.337409, 1.819219 }, + { 0.981629, 1.471275, 1.727250 }, { 0.520126, 0.449796, 0.329923 }, + { 0.480298, 0.444788, 0.238333 }, { 0.545807, 0.358005, 0.360171 }, + { 0.173019, 1.766946, 1.124286 }, { 0.119940, 1.845672, 1.155670 }, + { 0.266447, 1.795893, 1.103473 }, { 0.294915, 2.483116, 1.059922 }, + { 0.237058, 2.412428, 1.100614 }, { 0.279515, 2.569983, 1.107008 }, + { 1.967528, 1.701598, 0.384068 }, { 1.937630, 1.618064, 0.430200 }, + { 1.953844, 1.779905, 0.444737 }, { 2.602165, 1.306857, 2.049074 }, + { 2.675314, 1.367643, 2.018182 }, { 2.530699, 1.302540, 1.979261 }, + { 0.466325, 2.360293, 2.055629 }, { 0.431952, 2.347197, 1.962640 }, + { 0.560285, 2.394324, 2.051953 }, { 2.050154, 1.584414, 0.148513 }, + { 2.040061, 1.624411, 0.239608 }, { 2.068395, 1.656922, 0.082106 }, + { 1.556378, 1.957320, 2.428697 }, { 1.476038, 1.941088, 2.485985 }, + { 1.529396, 1.956406, 2.332410 }, { 0.682812, 1.205529, 2.526461 }, + { 0.723788, 1.287438, 2.566610 }, { 0.754192, 1.137731, 2.508900 }, + { 1.535311, 0.251227, 2.208550 }, { 1.556668, 0.315254, 2.282337 }, + { 1.437096, 0.253450, 2.189872 }, { 2.668479, 2.280105, 0.800170 }, + { 2.710946, 2.318387, 0.718127 }, { 2.739255, 2.259010, 0.867592 }, + { 1.542641, 3.084046, 2.220568 }, { 1.544509, 3.183810, 2.213954 }, + { 1.458575, 3.049445, 2.178907 }, { 1.457762, 1.374257, 2.244142 }, + { 1.499569, 1.291727, 2.206182 }, { 1.369735, 1.390552, 2.199582 }, + { 2.519020, 1.910788, 1.891775 }, { 2.505169, 1.980275, 1.821208 }, + { 2.518774, 1.820060, 1.849722 }, { 1.153670, 2.497971, 0.920991 }, + { 1.071685, 2.549851, 0.896764 }, { 1.150536, 2.474089, 1.018047 }, + { 2.586281, 3.065417, 2.640789 }, { 2.568059, 3.047493, 2.544111 }, + { 2.503036, 3.049598, 2.693891 }, { 2.306781, 1.384101, 0.311448 }, + { 2.360460, 1.468263, 0.305517 }, { 2.263250, 1.378589, 0.401307 }, + { 2.141848, 2.022213, 0.235023 }, { 2.188715, 1.934828, 0.222090 }, + { 2.046005, 2.005531, 0.258168 }, { 0.201078, 1.356753, 0.228828 }, + { 0.104294, 1.337330, 0.244812 }, { 0.255501, 1.318727, 0.303609 }, + { 0.457343, 0.726277, 2.048767 }, { 0.460321, 0.628162, 2.067859 }, + { 0.365421, 0.751595, 2.018612 }, { 2.860924, 1.577827, 1.715642 }, + { 2.807984, 1.661584, 1.729132 }, { 2.834381, 1.510187, 1.784347 }, + { 3.020626, 2.542969, 0.500236 }, { 2.999224, 2.640062, 0.489514 }, + { 3.013950, 2.497365, 0.411491 }, { 2.449280, 0.880812, 2.387606 }, + { 2.481825, 0.817972, 2.316952 }, { 2.399173, 0.956029, 2.344807 }, + { 0.839472, 2.578596, 0.606320 }, { 0.789949, 2.578031, 0.519445 }, + { 0.782640, 2.537078, 0.677358 }, { 1.243451, 2.095390, 1.335077 }, + { 1.341417, 2.115228, 1.338089 }, { 1.228127, 1.999442, 1.358721 }, + { 0.679730, 2.838689, 2.009180 }, { 0.764800, 2.786702, 2.001406 }, + { 0.699085, 2.936157, 1.997983 }, { 0.738842, 1.537655, 0.650196 }, + { 0.761227, 1.584947, 0.564976 }, { 0.790684, 1.578252, 0.725458 }, + { 2.835650, 0.699534, 0.020790 }, { 2.777710, 0.692381, 0.101980 }, + { 2.780032, 0.685783, -0.061170 }, { 1.845371, 0.433166, 1.258526 }, + { 1.842422, 0.520378, 1.307367 }, { 1.791587, 0.365195, 1.308398 }, + { 3.094758, 1.053543, 1.958825 }, { 3.137912, 1.085383, 2.043228 }, + { 3.044658, 0.968902, 1.976876 }, { 1.893173, 3.056022, 0.347448 }, + { 1.915403, 2.979650, 0.408054 }, { 1.943785, 3.137299, 0.376303 }, + { 0.227549, 2.726489, 1.743416 }, { 0.256351, 2.780895, 1.822222 }, + { 0.292572, 2.739273, 1.668526 }, { 1.149302, 2.387237, 0.343532 }, + { 1.166208, 2.474303, 0.297339 }, { 1.104012, 2.404185, 0.431062 }, + { 0.998224, 1.657693, 1.298714 }, { 1.056918, 1.616397, 1.229074 }, + { 0.929567, 1.715405, 1.254493 }, { 1.580309, 1.703216, 2.655682 }, + { 1.649980, 1.643679, 2.695698 }, { 1.618097, 1.794935, 2.643051 }, + { 2.081265, 2.616518, 0.762181 }, { 2.163416, 2.561470, 0.777047 }, + { 2.033529, 2.583809, 0.680625 }, { 1.576754, 0.079976, 2.599135 }, + { 1.624151, 0.042940, 2.679022 }, { 1.635391, 0.071299, 2.518597 }, + { 1.820339, 2.087323, 1.807897 }, { 1.862842, 2.081803, 1.717547 }, + { 1.876202, 2.144950, 1.867550 }, { 1.288347, 2.784119, 0.352047 }, + { 1.348111, 2.713677, 0.313756 }, { 1.267249, 2.761808, 0.447216 }, + { 2.053319, 2.806163, 2.812877 }, { 2.012843, 2.896631, 2.799563 }, + { 2.079198, 2.795015, 2.908825 }, { 3.103936, 1.939383, 3.010709 }, + { 3.140987, 1.850879, 2.982526 }, { 3.004767, 1.932147, 3.021340 }, + { 1.747635, 1.880408, 0.182510 }, { 1.711340, 1.800658, 0.230703 }, + { 1.811848, 1.928874, 0.241905 }, { 0.357312, 1.249510, 0.396746 }, + { 0.434813, 1.308092, 0.420447 }, { 0.370178, 1.159100, 0.437496 }, + { 1.162175, 1.003437, 0.132788 }, { 1.128159, 0.910792, 0.148908 }, + { 1.118065, 1.066691, 0.196452 }, { 1.720024, 2.350807, 2.796146 }, + { 1.816624, 2.332488, 2.777905 }, { 1.666584, 2.268039, 2.779012 }, + { 1.819804, 2.881982, 1.499877 }, { 1.801703, 2.787241, 1.473482 }, + { 1.853012, 2.884553, 1.594167 }, { 1.641302, 0.985935, 1.700102 }, + { 1.578200, 1.054423, 1.736539 }, { 1.590234, 0.903900, 1.674370 }, + { 1.407558, 2.105852, 0.622137 }, { 1.439669, 2.037089, 0.687256 }, + { 1.376226, 2.186770, 0.671844 }, { 0.742039, 2.449685, 1.807591 }, + { 0.664816, 2.508741, 1.784159 }, { 0.750599, 2.443898, 1.907056 }, + { 1.055383, 2.338027, 2.575278 }, { 0.980287, 2.357568, 2.512201 }, + { 1.137644, 2.315308, 2.523153 }, { 0.383084, 1.881983, 0.997049 }, + { 0.439661, 1.963523, 1.009305 }, { 0.342804, 1.882808, 0.905524 }, + { 1.624121, 1.460397, 0.585692 }, { 1.610918, 1.374878, 0.635814 }, + { 1.536897, 1.490047, 0.546797 }, { 3.073791, 2.284139, 1.733887 }, + { 3.159350, 2.238214, 1.710000 }, { 3.006778, 2.216259, 1.763913 }, + { 2.276815, 2.539086, 2.980504 }, { 2.243982, 2.631874, 2.998179 }, + { 2.215148, 2.473147, 3.023507 }, { 0.287152, 0.812484, 2.829435 }, + { 0.364868, 0.874562, 2.839761 }, { 0.320299, 0.721354, 2.805011 }, + { 2.947925, 2.745224, 1.175244 }, { 2.937136, 2.657265, 1.221578 }, + { 2.932797, 2.819397, 1.240584 }, { 2.432782, 0.445198, 2.008265 }, + { 2.528164, 0.421749, 2.027040 }, { 2.426765, 0.541315, 1.981331 }, + { 2.135631, 2.846586, 1.674159 }, { 2.112821, 2.924476, 1.615739 }, + { 2.142838, 2.877115, 1.769111 }, { 1.992697, 1.542239, 1.123538 }, + { 1.994674, 1.495622, 1.035090 }, { 2.085254, 1.571023, 1.148125 }, + { 3.007302, 1.002020, 1.263169 }, { 3.005399, 1.045505, 1.173139 }, + { 3.102123, 0.991726, 1.293219 }, { 3.042117, 1.830594, 2.657699 }, + { 3.091667, 1.816789, 2.571943 }, { 2.974763, 1.757611, 2.669402 }, + { 1.465297, 1.281842, 2.950841 }, { 1.411305, 1.229250, 3.016560 }, + { 1.408774, 1.303931, 2.871359 }, { 2.612090, 0.891093, 1.547955 }, + { 2.695821, 0.887163, 1.493423 }, { 2.616686, 0.823002, 1.621047 }, + { 0.812006, 2.707695, 1.208838 }, { 0.735158, 2.770254, 1.195395 }, + { 0.808964, 2.635761, 1.139439 }, { 0.318130, 2.780547, 0.516632 }, + { 0.265551, 2.753112, 0.436116 }, { 0.291856, 2.723669, 0.594571 }, + { 1.554664, 1.776211, 0.557025 }, { 1.585392, 1.801147, 0.648862 }, + { 1.479411, 1.836105, 0.529645 }, { 1.313118, 1.325875, 1.106502 }, + { 1.406876, 1.305721, 1.134843 }, { 1.255307, 1.336157, 1.187448 }, + { 0.563695, 1.495837, 0.858004 }, { 0.647750, 1.477497, 0.807031 }, + { 0.516021, 1.409745, 0.875762 }, { 0.189938, 2.083492, 2.220667 }, + { 0.179488, 2.169607, 2.170918 }, { 0.228533, 2.014250, 2.159708 }, + { 1.219512, 1.960655, 0.459886 }, { 1.126082, 1.995943, 0.454832 }, + { 1.269108, 2.007934, 0.532721 }, { 2.373176, 2.965076, 2.821447 }, + { 2.364244, 2.875424, 2.778057 }, { 2.284076, 3.010455, 2.822850 }, + { 0.688102, 2.932363, 2.635048 }, { 0.749140, 3.002946, 2.599097 }, + { 0.736401, 2.878551, 2.704123 }, { 3.043730, 1.315443, 0.326532 }, + { 3.042042, 1.258753, 0.408893 }, { 2.996829, 1.267695, 0.252232 }, + { 1.964500, 2.004276, 2.335286 }, { 1.904133, 1.953017, 2.274227 }, + { 1.911536, 2.040095, 2.412175 }, { 0.450798, 1.904655, 2.606229 }, + { 0.475742, 1.954537, 2.523226 }, { 0.376490, 1.952627, 2.652888 }, + { 2.112788, 1.128108, 0.683552 }, { 2.130045, 1.121204, 0.781809 }, + { 2.060726, 1.048319, 0.653164 }, { 0.770271, 0.564206, 0.707533 }, + { 0.849217, 0.624301, 0.695042 }, { 0.701429, 0.584713, 0.637961 }, + { 1.907848, 1.027415, 1.090399 }, { 1.926364, 1.073308, 1.177296 }, + { 1.854230, 1.087899, 1.031520 }, { 2.006840, 0.879452, 0.615825 }, + { 1.950347, 0.812869, 0.567089 }, { 2.048772, 0.835710, 0.695376 }, + { 1.044237, 2.729692, 2.739900 }, { 0.957432, 2.739064, 2.788657 }, + { 1.087096, 2.642769, 2.764545 }, { 2.024470, 0.868120, 2.448789 }, + { 1.977539, 0.792888, 2.402554 }, { 2.038713, 0.844474, 2.544904 }, + { 2.346306, 0.847486, 1.854141 }, { 2.428596, 0.887883, 1.894097 }, + { 2.273015, 0.846975, 1.922172 }, { 2.451466, 1.066926, 0.052602 }, + { 2.454208, 1.089762, 0.149921 }, { 2.461859, 1.150367, -0.001524 }, + { 1.586928, 0.171622, 1.225782 }, { 1.643190, 0.092301, 1.249084 }, + { 1.585595, 0.235339, 1.302842 }, { 2.158334, 2.595841, 2.438041 }, + { 2.126742, 2.586688, 2.532477 }, { 2.120427, 2.521555, 2.382862 }, + { 0.268769, 2.384647, 1.524956 }, { 0.178764, 2.396688, 1.483075 }, + { 0.264809, 2.310261, 1.591672 }, { 2.964697, 0.609294, 2.578384 }, + { 3.014589, 0.539796, 2.526607 }, { 2.991249, 0.604578, 2.674679 }, + { 2.804129, 2.035185, 2.658896 }, { 2.831947, 2.130885, 2.667122 }, + { 2.859608, 1.990245, 2.588878 }, { 2.269440, 0.004664, 2.015026 }, + { 2.292795, 0.086003, 1.961748 }, { 2.266981, 0.028052, 2.112221 }, + { 0.978350, 1.814540, 1.887908 }, { 1.016409, 1.901488, 1.919396 }, + { 0.900506, 1.832099, 1.827642 }, { 1.043390, 1.175341, 1.906444 }, + { 1.099585, 1.238650, 1.959679 }, { 0.975010, 1.133260, 1.966055 }, + { 2.016893, 0.274093, 2.004319 }, { 2.071563, 0.340099, 2.055840 }, + { 2.024768, 0.293409, 1.906518 }, { 0.200210, 1.231970, 1.834713 }, + { 0.114839, 1.184264, 1.855594 }, { 0.188948, 1.285302, 1.750875 }, + { 2.729975, 1.523368, 1.494243 }, { 2.786119, 1.553298, 1.571393 }, + { 2.644035, 1.574497, 1.493741 }, { 0.654823, 2.344026, 0.041906 }, + { 0.585582, 2.332462, -0.029311 }, { 0.740286, 2.375393, 0.000528 }, + { 3.021982, 2.593565, 2.621302 }, { 2.989764, 2.499790, 2.634267 }, + { 3.017212, 2.642770, 2.708228 }, { 2.487491, 2.587543, 0.588152 }, + { 2.540926, 2.508060, 0.559391 }, { 2.491371, 2.596063, 0.687713 }, + { 0.858188, 2.209867, 1.713786 }, { 0.822392, 2.294693, 1.752813 }, + { 0.919970, 2.231431, 1.638169 }, { 2.596792, 1.253523, 0.653627 }, + { 2.639966, 1.236539, 0.565041 }, { 2.592499, 1.168156, 0.705531 }, + { 1.557444, 1.249902, 0.754581 }, { 1.590664, 1.171004, 0.702893 }, + { 1.458703, 1.241710, 0.768116 }, { 0.474497, 2.224022, 0.619046 }, + { 0.446543, 2.260459, 0.707877 }, { 0.480869, 2.124369, 0.624402 }, + { 0.761041, 1.590794, 2.432924 }, { 0.791242, 1.685785, 2.440954 }, + { 0.663172, 1.588543, 2.412513 }, { 0.836284, 1.482214, 2.190881 }, + { 0.850232, 1.384275, 2.205489 }, { 0.787473, 1.520964, 2.269085 }, + { 2.454650, 0.391488, 2.726185 }, { 2.367849, 0.341863, 2.724489 }, + { 2.440428, 0.482185, 2.765830 }, { 2.354491, 0.123748, 1.086280 }, + { 2.373650, 0.056337, 1.014945 }, { 2.440302, 0.152735, 1.128663 }, + { 2.992918, 1.513766, 2.387696 }, { 2.906224, 1.543682, 2.347829 }, + { 2.987283, 1.518885, 2.487406 }, { 1.227082, 2.282968, 2.976912 }, + { 1.164560, 2.261041, 3.051813 }, { 1.316651, 2.307128, 3.014247 }, + { 1.518608, 0.153309, 1.856854 }, { 1.447277, 0.199556, 1.909514 }, + { 1.606102, 0.199449, 1.871548 }, { 2.587957, 0.288841, 2.468338 }, + { 2.578525, 0.296796, 2.567574 }, { 2.606517, 0.193603, 2.444146 }, + { 0.144688, 1.415405, 1.610001 }, { 0.207284, 1.450562, 1.540389 }, + { 0.085255, 1.489291, 1.641759 }, { 2.748672, 1.594337, 2.271072 }, + { 2.673511, 1.622680, 2.330631 }, { 2.718247, 1.596183, 2.175830 }, + { 0.410163, 0.619010, 2.435827 }, { 0.345484, 0.681869, 2.392637 }, + { 0.503603, 0.646896, 2.413665 }, { 0.534691, 0.343823, 1.325729 }, + { 0.632028, 0.338918, 1.348121 }, { 0.500601, 0.435795, 1.345198 }, + { 2.461049, 0.820135, 0.965838 }, { 2.536165, 0.820911, 1.031846 }, + { 2.421632, 0.728344, 0.961273 }, { 0.531212, 2.220300, 0.236689 }, + { 0.502904, 2.296693, 0.294679 }, { 0.574186, 2.255658, 0.153605 }, + { 1.655506, 2.833838, 2.317040 }, { 1.668580, 2.830497, 2.416125 }, + { 1.602969, 2.915483, 2.293083 }, { 1.288110, 2.656172, 2.952423 }, + { 1.277223, 2.634069, 2.855505 }, { 1.368445, 2.608857, 2.988584 }, + { 2.348524, 2.179906, 2.595979 }, { 2.372646, 2.102011, 2.653862 }, + { 2.259984, 2.216541, 2.624589 }, { 1.695517, 0.551448, 0.805462 }, + { 1.699774, 0.609314, 0.724017 }, { 1.704642, 0.455524, 0.778714 }, + { 2.106596, 1.916632, 1.923212 }, { 2.155546, 1.961234, 1.998142 }, + { 2.032239, 1.861051, 1.960386 }, { 2.447050, 2.038526, 1.664823 }, + { 2.350761, 2.065299, 1.668234 }, { 2.484148, 2.058980, 1.574239 }, + { 2.449344, 1.569436, 1.950703 }, { 2.437787, 1.493630, 1.886517 }, + { 2.546473, 1.580996, 1.971496 }, { 2.112171, 0.408380, 1.794677 }, + { 2.158942, 0.496119, 1.805372 }, { 2.078496, 0.399767, 1.700912 }, + { 2.692511, 0.417154, 0.512240 }, { 2.679476, 0.365314, 0.427725 }, + { 2.621964, 0.487674, 0.519306 }, { 0.435488, 2.780530, 1.586002 }, + { 0.420283, 2.877527, 1.567019 }, { 0.435612, 2.729368, 1.500080 }, + { 1.115003, 1.717126, 0.837236 }, { 1.203147, 1.677245, 0.811938 }, + { 1.068973, 1.751023, 0.755185 }, { 1.856343, 0.616824, 2.343989 }, + { 1.796548, 0.622851, 2.264063 }, { 1.904818, 0.529366, 2.342835 }, + { 2.604397, 0.261200, 2.905175 }, { 2.528620, 0.244919, 2.968362 }, + { 2.569499, 0.303156, 2.821379 }, { 2.983071, 1.836011, 0.408545 }, + { 2.941255, 1.922312, 0.380198 }, { 2.911503, 1.771495, 0.435298 }, + { 0.284846, 1.004775, 0.159867 }, { 0.340818, 1.016814, 0.241856 }, + { 0.297717, 1.083015, 0.098934 }, { 0.192126, 0.793038, 0.011385 }, + { 0.230558, 0.870973, 0.060874 }, { 0.241567, 0.780506, -0.074630 }, + { 2.563812, 1.647993, 2.692657 }, { 2.622485, 1.725166, 2.717190 }, + { 2.503455, 1.674583, 2.617490 }, { 2.529260, 2.046808, 0.776094 }, + { 2.471748, 2.053308, 0.857642 }, { 2.544468, 2.138278, 0.738651 }, + { 1.521366, 2.552599, 3.064763 }, { 1.526632, 2.463583, 3.110023 }, + { 1.534993, 2.625151, 3.132221 }, { 0.511749, 0.923074, 2.208753 }, + { 0.447660, 0.998092, 2.192473 }, { 0.496390, 0.850876, 2.141288 }, + { 2.117688, 1.781807, 0.783134 }, { 2.208797, 1.813138, 0.809922 }, + { 2.055770, 1.788578, 0.861366 }, { 1.652780, 2.093001, 2.754505 }, + { 1.554431, 2.085575, 2.771006 }, { 1.698800, 2.011709, 2.790196 }, + { 1.737177, 1.179170, 2.904903 }, { 1.737840, 1.107564, 2.974704 }, + { 1.642971, 1.207781, 2.887392 }, { 2.608930, 0.790629, 1.194068 }, + { 2.528547, 0.828235, 1.240158 }, { 2.684912, 0.785017, 1.258839 }, + { 1.698150, 0.265894, 0.685113 }, { 1.679547, 0.256862, 0.782952 }, + { 1.680976, 0.178467, 0.639707 }, { 1.062092, 1.101304, 1.495332 }, + { 1.047507, 1.009579, 1.532398 }, { 0.976651, 1.135380, 1.456105 }, + { 2.481560, 2.004994, 0.118148 }, { 2.554321, 1.938467, 0.101419 }, + { 2.482028, 2.031356, 0.214610 }, { 1.923369, 2.539567, 0.556425 }, + { 1.838167, 2.585092, 0.530578 }, { 1.973136, 2.512668, 0.473965 }, + { 2.710513, 1.598229, 2.008108 }, { 2.724888, 1.696756, 2.017366 }, + { 2.797808, 1.553485, 1.988678 }, { 2.942739, 0.227199, 0.186899 }, + { 3.020717, 0.170557, 0.160232 }, { 2.975626, 0.309638, 0.232967 }, + { 1.274750, 0.014932, 2.831151 }, { 1.277539, -0.019282, 2.737227 }, + { 1.311231, -0.054613, 2.893059 }, { 0.138548, 2.393702, 0.543185 }, + { 0.060579, 2.445383, 0.507829 }, { 0.146433, 2.307200, 0.493635 }, + { 0.194759, 3.076992, 1.308021 }, { 0.227728, 3.149223, 1.247228 }, + { 0.123684, 3.024177, 1.261557 }, { 1.133502, 0.030873, 0.173195 }, + { 1.148695, -0.014224, 0.261146 }, { 1.211249, 0.090184, 0.152275 }, + { 2.722824, 2.558867, 2.789907 }, { 2.702571, 2.600501, 2.701270 }, + { 2.696187, 2.462493, 2.788332 }, { 1.307419, 2.352714, 2.242314 }, + { 1.405996, 2.369378, 2.240105 }, { 1.287675, 2.277863, 2.305619 }, + { 2.808640, 0.090952, 2.094578 }, { 2.837316, 0.064602, 2.002473 }, + { 2.873024, 0.053768, 2.161452 }, { 2.610557, 2.119816, 2.296930 }, + { 2.516683, 2.088381, 2.311053 }, { 2.673361, 2.042581, 2.306444 }, + { 2.067765, 0.663952, 0.224417 }, { 2.149722, 0.619553, 0.188201 }, + { 2.062731, 0.649171, 0.323191 }, { 2.410587, 1.939136, 0.539274 }, + { 2.329640, 1.983980, 0.501371 }, { 2.433478, 1.980572, 0.627359 }, + { 0.266830, 2.589002, 0.694311 }, { 0.229373, 2.506770, 0.651476 }, + { 0.213318, 2.611497, 0.775739 }, { 2.665478, 0.247924, 0.257674 }, + { 2.758689, 0.235464, 0.223669 }, { 2.619919, 0.159088, 0.263375 }, + { 1.391624, 1.635214, 0.824559 }, { 1.443687, 1.587036, 0.895045 }, + { 1.373363, 1.573131, 0.748321 }, { 0.915468, 0.823852, 0.413096 }, + { 0.943532, 0.769916, 0.492490 }, { 0.954097, 0.783595, 0.330107 }, + { 2.422248, 2.909883, 1.103557 }, { 2.418386, 2.919563, 1.203012 }, + { 2.330025, 2.917723, 1.065696 }, { 1.408309, 2.936097, 0.154872 }, + { 1.501433, 2.955528, 0.185701 }, { 1.357769, 2.890516, 0.228139 }, + { 1.601230, 0.015841, 0.607280 }, { 1.583071, 0.049227, 0.514783 }, + { 1.529356, 0.047873, 0.668990 }, { 2.387127, 2.249286, 0.604177 }, + { 2.339117, 2.308859, 0.668568 }, { 2.320551, 2.194928, 0.553061 }, + { 0.006317, 0.397187, 2.468096 }, { 0.086350, 0.369685, 2.521373 }, + { -0.067122, 0.330651, 2.481501 }, { 2.414588, 0.649050, 2.818040 }, + { 2.413447, 0.726390, 2.881421 }, { 2.379346, 0.678284, 2.729139 }, + { 1.620984, 0.646636, 0.554546 }, { 1.555752, 0.571955, 0.541602 }, + { 1.571288, 0.732489, 0.567183 }, { 1.388431, 1.496548, 2.555467 }, + { 1.346007, 1.491565, 2.645885 }, { 1.459663, 1.566733, 2.555890 }, + { 0.135346, 0.027221, 0.692454 }, { 0.110535, 0.085136, 0.614799 }, + { 0.229755, -0.004019, 0.681917 }, { 0.356113, 1.759265, 2.006375 }, + { 0.428524, 1.828103, 2.010617 }, { 0.357217, 1.715211, 1.916609 }, + { 2.784840, 1.337893, 0.048133 }, { 2.833571, 1.258874, 0.085296 }, + { 2.850191, 1.410781, 0.027721 }, { 2.732356, 2.248891, 1.483486 }, + { 2.798089, 2.308929, 1.529034 }, { 2.645377, 2.251207, 1.532774 }, + { 1.609259, 2.461869, 0.761605 }, { 1.515557, 2.495474, 0.771124 }, + { 1.626281, 2.390800, 0.829865 }, { 3.034595, 2.376378, 1.030368 }, + { 3.108631, 2.326860, 1.075828 }, { 3.072930, 2.450813, 0.975689 }, + { 3.001063, 2.956280, 2.449605 }, { 2.932654, 2.883470, 2.445274 }, + { 3.020729, 2.977897, 2.545239 }, { 0.973131, 1.398826, 3.027256 }, + { 1.048479, 1.453925, 3.063128 }, { 0.886059, 1.441609, 3.051508 }, + { 1.075531, 2.444457, 0.635589 }, { 1.139902, 2.479480, 0.703631 }, + { 0.990821, 2.497460, 0.639456 }, { 1.866464, 1.096888, 1.554833 }, + { 1.941039, 1.123887, 1.615740 }, { 1.789922, 1.062351, 1.609132 }, + { 1.591678, 1.105215, 2.043568 }, { 1.653395, 1.145689, 1.976092 }, + { 1.645280, 1.060640, 2.115260 }, { 2.619927, 0.227980, 1.174340 }, + { 2.633047, 0.294780, 1.101090 }, { 2.665581, 0.142407, 1.149987 }, + { 1.916667, 0.415190, 0.590627 }, { 1.825708, 0.378396, 0.609931 }, + { 1.983344, 0.373288, 0.652258 }, { 1.200849, 1.841071, 1.389818 }, + { 1.114525, 1.790768, 1.394038 }, { 1.256145, 1.819190, 1.470215 }, + { 2.221784, 1.766977, 3.004150 }, { 2.225336, 1.794523, 3.100216 }, + { 2.288916, 1.694712, 2.987690 }, { 1.120165, 3.008868, 2.322689 }, + { 1.029789, 3.031427, 2.359063 }, { 1.133909, 2.909893, 2.326577 }, + { 0.405986, 1.997015, 2.356493 }, { 0.366114, 1.907130, 2.338302 }, + { 0.345189, 2.068190, 2.321310 }, { 2.326232, 0.162329, 0.556844 }, + { 2.317494, 0.256924, 0.525610 }, { 2.412060, 0.151587, 0.607026 }, + { 1.349474, 2.909042, 3.002070 }, { 1.354029, 2.915883, 3.101732 }, + { 1.313151, 2.819469, 2.976431 }, { 1.677748, 2.890286, 2.981716 }, + { 1.584536, 2.854118, 2.979874 }, { 1.739825, 2.820638, 3.017710 }, + { 2.146479, 1.045232, 0.950271 }, { 2.062776, 1.035080, 1.004035 }, + { 2.225747, 1.042585, 1.011178 }, { 0.038713, 0.203819, 0.461963 }, + { 0.080467, 0.204316, 0.371099 }, { 0.022739, 0.297910, 0.491824 }, + { 1.344154, 0.934719, 3.048288 }, { 1.298501, 0.975815, 3.127199 }, + { 1.292224, 0.854988, 3.017525 }, { 1.876736, 0.670754, 0.506472 }, + { 1.922832, 0.582605, 0.516712 }, { 1.777974, 0.657982, 0.515576 }, + { 1.547024, 1.257100, 1.494394 }, { 1.462871, 1.279845, 1.445394 }, + { 1.595454, 1.184510, 1.445555 }, { 0.837046, 1.662106, 0.882764 }, + { 0.927946, 1.694579, 0.908893 }, { 0.770410, 1.690515, 0.951702 }, + { 2.905724, 1.433934, 1.956678 }, { 2.901017, 1.350620, 1.901572 }, + { 2.982411, 1.427385, 2.020522 }, { 1.082721, 1.574084, 1.538980 }, + { 1.118780, 1.653944, 1.587168 }, { 1.041923, 1.603015, 1.452386 }, + { 0.973517, 1.950813, 0.715403 }, { 0.983211, 2.013477, 0.638077 }, + { 0.883009, 1.908370, 0.712770 }, { 2.047444, 1.846347, 2.788275 }, + { 2.105859, 1.796484, 2.852317 }, { 2.098174, 1.864406, 2.704012 }, + { 1.472286, 0.407694, 0.463299 }, { 1.403985, 0.383358, 0.532166 }, + { 1.548848, 0.343549, 0.468160 }, { 1.523722, 2.012941, 1.058531 }, + { 1.538378, 2.080087, 1.131171 }, { 1.463127, 1.940637, 1.091702 }, + { 2.094622, 0.765399, 0.870291 }, { 2.123104, 0.847060, 0.920494 }, + { 2.004127, 0.736782, 0.901781 }, { 1.360037, 1.461451, 1.615762 }, + { 1.375715, 1.426828, 1.708258 }, { 1.267388, 1.498526, 1.609306 }, + { 1.754323, 2.881247, 0.755875 }, { 1.740556, 2.861699, 0.852975 }, + { 1.710649, 2.968212, 0.732860 }, { 2.597326, 2.339246, 0.463067 }, + { 2.688913, 2.333021, 0.502729 }, { 2.530638, 2.300986, 0.527011 }, + { 2.404012, 2.888762, 1.379749 }, { 2.377619, 2.981254, 1.407111 }, + { 2.362718, 2.822465, 1.442195 }, { 2.682210, 0.752891, 0.246149 }, + { 2.588032, 0.751670, 0.279748 }, { 2.719633, 0.845183, 0.255187 }, + { 1.147989, 0.504369, 0.806579 }, { 1.188565, 0.445977, 0.736266 }, + { 1.068069, 0.458769, 0.845737 }, { 0.882417, 2.859277, 0.450074 }, + { 0.828696, 2.842740, 0.532782 }, { 0.820924, 2.879784, 0.373929 }, + { 2.310841, 1.485608, 2.189112 }, { 2.390981, 1.454864, 2.240419 }, + { 2.338739, 1.513314, 2.097166 }, { 0.048620, 1.439459, 2.985076 }, + { 0.078551, 1.439376, 2.889661 }, { 0.058812, 1.347612, 3.023289 }, + { 2.685128, 3.096664, 1.076209 }, { 2.634155, 3.017488, 1.109867 }, + { 2.636042, 3.137695, 0.999352 }, { 2.955404, 1.555187, 2.648529 }, + { 2.871594, 1.525579, 2.694345 }, { 3.034353, 1.532617, 2.705606 }, + { 0.064303, 2.480490, 2.970512 }, { 0.081989, 2.494919, 3.067872 }, + { -0.018484, 2.529915, 2.943987 }, { 2.482995, 0.044725, 0.867955 }, + { 2.455494, -0.036642, 0.816739 }, { 2.538862, 0.103589, 0.809526 }, + { 2.017835, 2.999311, 2.452181 }, { 2.056715, 2.908900, 2.434452 }, + { 1.920387, 2.998675, 2.429744 }, { 0.869423, 2.167004, 3.082747 }, + { 0.954671, 2.177259, 3.134008 }, { 0.864372, 2.237510, 3.012012 }, + { 1.589117, 0.399666, 2.413510 }, { 1.674099, 0.378754, 2.461891 }, + { 1.570287, 0.497660, 2.420041 }, { 0.440864, 0.611366, 1.385214 }, + { 0.366708, 0.650546, 1.330755 }, { 0.527868, 0.625182, 1.337891 }, + { 2.713192, 1.529373, 1.085268 }, { 2.693629, 1.627372, 1.088945 }, + { 2.710758, 1.498439, 0.990204 }, { 2.066839, 1.149465, 2.402028 }, + { 1.978751, 1.170214, 2.359483 }, { 2.063437, 1.058285, 2.442951 }, + { 0.718140, 1.556839, 1.676953 }, { 0.794749, 1.522176, 1.731078 }, + { 0.701074, 1.652454, 1.700755 }, { 1.851286, 1.748633, 1.205296 }, + { 1.906319, 1.667628, 1.185058 }, { 1.903282, 1.810358, 1.264343 }, + { 0.690798, 2.820113, 0.892873 }, { 0.624258, 2.764246, 0.843363 }, + { 0.659978, 2.832952, 0.987135 }, { 0.700392, 2.971775, 0.643684 }, + { 0.629248, 2.966450, 0.573611 }, { 0.667850, 2.928206, 0.727605 }, + { 0.224944, 2.412756, 2.411288 }, { 0.179940, 2.480028, 2.352558 }, + { 0.321229, 2.437351, 2.422438 }, { 0.931960, 1.088532, 1.085458 }, + { 0.948257, 1.069581, 1.182284 }, { 0.943490, 1.186361, 1.068238 }, + { 0.665315, 1.482798, 1.205282 }, { 0.623395, 1.392477, 1.196078 }, + { 0.754802, 1.482720, 1.160649 }, { 2.090545, 2.389004, 2.282603 }, + { 2.040173, 2.355573, 2.362259 }, { 2.025895, 2.417626, 2.211884 }, + { 0.586392, 2.277950, 2.330457 }, { 0.544270, 2.318000, 2.249084 }, + { 0.583852, 2.178214, 2.323650 }, { 0.397428, 2.598797, 1.378318 }, + { 0.467494, 2.548450, 1.327762 }, { 0.332320, 2.534269, 1.418282 }, + { 0.769337, 0.909264, 1.677104 }, { 0.851592, 0.904461, 1.733770 }, + { 0.689510, 0.924296, 1.735428 }, { 2.809384, 0.362243, 1.792651 }, + { 2.906450, 0.384960, 1.800543 }, { 2.770939, 0.407692, 1.712300 }, + { 2.165909, 0.965344, 0.397730 }, { 2.089549, 0.933174, 0.453714 }, + { 2.248087, 0.972319, 0.454283 }, { 3.029223, 1.963090, 2.255361 }, + { 3.063521, 2.056860, 2.260912 }, { 3.032822, 1.931843, 2.160436 }, + { 2.290786, 0.279773, 2.425314 }, { 2.272727, 0.248542, 2.518580 }, + { 2.389205, 0.277242, 2.407783 }, { 2.887936, 0.900624, 2.678907 }, + { 2.848443, 0.883810, 2.588588 }, { 2.939101, 0.986531, 2.677450 }, + { 2.724532, 1.007735, 0.316482 }, { 2.638163, 1.056986, 0.305776 }, + { 2.737244, 0.983237, 0.412598 }, { 2.046399, 1.071255, 1.952165 }, + { 2.071263, 1.164937, 1.976772 }, { 2.077369, 1.008654, 2.023734 }, + { 0.170790, 2.227231, 2.943018 }, { 0.126575, 2.314910, 2.961923 }, + { 0.105750, 2.152970, 2.958991 }, { 1.361693, 2.771602, 1.982177 }, + { 1.454761, 2.773405, 1.945637 }, { 1.342410, 2.858072, 2.028557 }, + { 2.982726, 0.757058, 1.738590 }, { 3.078254, 0.782233, 1.723078 }, + { 2.946703, 0.711262, 1.657319 }, { 2.418788, 0.252780, 1.386757 }, + { 2.352642, 0.300740, 1.329098 }, { 2.499443, 0.229291, 1.332506 }, + { 1.608286, 2.595250, 2.794006 }, { 1.645863, 2.503744, 2.779360 }, + { 1.562406, 2.598627, 2.882796 }, { 1.508130, 0.999554, 2.425027 }, + { 1.547857, 0.994937, 2.516681 }, { 1.431312, 1.063578, 2.425178 }, + { 0.403062, 0.456581, 0.079987 }, { 0.443234, 0.406243, 0.003487 }, + { 0.303384, 0.455265, 0.072083 }, { 2.772199, 1.911678, 2.353951 }, + { 2.729955, 1.826940, 2.321781 }, { 2.870697, 1.908343, 2.337011 }, + { 0.267947, 2.608428, 2.130318 }, { 0.325039, 2.689867, 2.140717 }, + { 0.324975, 2.531033, 2.102786 }, { 0.271482, 2.897455, 1.935251 }, + { 0.186640, 2.909345, 1.986831 }, { 0.341018, 2.856649, 1.994408 }, + { 0.420612, 1.093519, 1.906373 }, { 0.340253, 1.144399, 1.875491 }, + { 0.424876, 1.005758, 1.858624 }, { 0.317469, 2.961369, 0.908774 }, + { 0.344220, 2.899485, 0.982631 }, { 0.236408, 3.013052, 0.936305 }, + { 1.331593, 1.232370, 2.476098 }, { 1.246807, 1.247953, 2.425416 }, + { 1.387810, 1.315023, 2.473236 }, { 1.653708, 2.990313, 0.221008 }, + { 1.729954, 2.996775, 0.285388 }, { 1.680305, 3.031054, 0.133642 }, + { 0.590628, 1.387522, 0.466964 }, { 0.630802, 1.407555, 0.556321 }, + { 0.620713, 1.456152, 0.400747 }, { 2.905997, 0.221663, 2.459906 }, + { 2.819336, 0.267701, 2.440662 }, { 2.896627, 0.166170, 2.542566 }, + { 3.093628, 2.977978, 2.705256 }, { 3.167925, 3.044386, 2.696902 }, + { 3.071771, 2.964390, 2.801887 }, { 2.165292, 1.291783, 2.041764 }, + { 2.234435, 1.220242, 2.031709 }, { 2.185992, 1.347037, 2.122501 }, + { 2.252015, 0.402395, 1.221932 }, { 2.285112, 0.496702, 1.225218 }, + { 2.179675, 0.394827, 1.153306 }, { 2.104356, 0.137080, 1.189404 }, + { 2.195319, 0.128762, 1.148705 }, { 2.079462, 0.050753, 1.233312 }, + { 2.148437, 0.707200, 3.015197 }, { 2.198806, 0.754869, 3.087243 }, + { 2.051558, 0.731376, 3.020663 }, { 1.850478, 1.598817, 3.013910 }, + { 1.874091, 1.567314, 3.105834 }, { 1.850247, 1.521043, 2.951052 }, + { 1.984243, 1.101537, 0.205597 }, { 2.056039, 1.050969, 0.253432 }, + { 2.016996, 1.193515, 0.183984 }, { 0.819823, 2.184803, 2.627983 }, + { 0.910067, 2.222214, 2.649346 }, { 0.818973, 2.151619, 2.533653 }, + { 0.680880, 0.100328, 2.990090 }, { 0.748260, 0.091873, 2.916685 }, + { 0.673872, 0.013431, 3.039078 }, { 2.347672, 1.066007, 2.070294 }, + { 2.435627, 1.018893, 2.063654 }, { 2.327837, 1.086215, 2.166201 }, + { 1.111822, 1.814359, 2.252410 }, { 1.077790, 1.776269, 2.338381 }, + { 1.095407, 1.749261, 2.178296 }, { 2.873311, 1.875343, 0.918630 }, + { 2.944104, 1.911954, 0.858231 }, { 2.784531, 1.880520, 0.872899 }, + { 2.101428, 2.550539, 2.746625 }, { 2.078013, 2.646820, 2.760104 }, + { 2.189270, 2.531164, 2.790308 }, { 2.827466, 0.083838, 2.684289 }, + { 2.743385, 0.029836, 2.680525 }, { 2.855318, 0.095556, 2.779614 }, + { 2.643409, 2.459431, 1.183392 }, { 2.631575, 2.376139, 1.129333 }, + { 2.581379, 2.457376, 1.261802 }, { 0.210477, 1.616716, 0.215712 }, + { 0.227327, 1.627602, 0.313679 }, { 0.191301, 1.520642, 0.195659 }, + { 2.595851, 3.085082, 0.245145 }, { 2.533216, 3.108680, 0.170849 }, + { 2.632559, 2.993318, 0.229920 }, { 0.948067, 1.831565, 0.021233 }, + { 0.912134, 1.907261, 0.075814 }, { 0.938805, 1.746188, 0.072468 }, + { 1.953344, 2.247947, 1.017599 }, { 1.909073, 2.312925, 0.955810 }, + { 1.960324, 2.158811, 0.972811 }, { 1.222649, 2.766274, 0.625820 }, + { 1.132619, 2.728772, 0.647918 }, { 1.292364, 2.720128, 0.680687 }, + { 1.697084, 1.491664, 2.240765 }, { 1.608414, 1.453049, 2.215338 }, + { 1.683516, 1.566071, 2.306182 }, { 1.267412, 1.311498, 2.741722 }, + { 1.282870, 1.251771, 2.663022 }, { 1.169226, 1.326331, 2.753535 }, + { 0.703434, 0.631065, 1.342521 }, { 0.757236, 0.648969, 1.424891 }, + { 0.755720, 0.658720, 1.261889 }, { 0.536418, 0.871703, 1.821272 }, + { 0.506921, 0.828597, 1.906547 }, { 0.501439, 0.819320, 1.743603 }, + { 2.033586, 1.894688, 1.361921 }, { 2.053905, 1.813031, 1.415951 }, + { 2.102318, 1.964908, 1.380502 }, { 1.353145, 0.749155, 2.700183 }, + { 1.340584, 0.768015, 2.602784 }, { 1.423395, 0.809983, 2.737126 }, + { 1.757646, 3.040187, 1.185496 }, { 1.805834, 2.953766, 1.199967 }, + { 1.789142, 3.082058, 1.100321 }, { 2.692199, 2.835351, 0.825364 }, + { 2.663609, 2.776601, 0.901068 }, { 2.611627, 2.876881, 0.783133 }, + { 2.753498, 2.840923, 0.324355 }, { 2.736860, 2.782748, 0.244738 }, + { 2.680602, 2.827267, 0.391435 }, { 0.196329, 2.621545, 2.569990 }, + { 0.219355, 2.524588, 2.578307 }, { 0.108105, 2.638733, 2.613821 }, + { 2.345007, 1.825788, 1.374116 }, { 2.272672, 1.793851, 1.435333 }, + { 2.379912, 1.913637, 1.406738 }, { 0.596710, 0.509863, 2.871939 }, + { 0.526640, 0.561688, 2.822905 }, { 0.556514, 0.426024, 2.908751 }, + { 2.937274, 0.823236, 1.996167 }, { 2.937670, 0.813596, 1.896634 }, + { 2.911096, 0.736251, 2.037979 }, { 0.579374, 1.320692, 0.011389 }, + { 0.634136, 1.240102, 0.033891 }, { 0.484056, 1.293558, -0.001960 }, + { 2.278243, 2.412097, 0.787639 }, { 2.368768, 2.449098, 0.808522 }, + { 2.240378, 2.368551, 0.869309 }, { 0.391627, 1.711143, 0.025375 }, + { 0.332230, 1.678111, 0.098730 }, { 0.390472, 1.645887, -0.050389 }, + { 0.153753, 2.467941, 1.820145 }, { 0.065625, 2.429276, 1.792973 }, + { 0.150971, 2.567416, 1.810297 }, { 2.843451, 0.422126, 2.906952 }, + { 2.775335, 0.354829, 2.935786 }, { 2.799691, 0.511419, 2.896375 }, + { 1.970457, 1.649264, 2.404565 }, { 2.013029, 1.699928, 2.329594 }, + { 1.985128, 1.551262, 2.391131 }, { 1.342607, 1.643091, 2.334386 }, + { 1.344545, 1.563513, 2.394914 }, { 1.248079, 1.673291, 2.322043 }, + { 0.748739, 1.133236, 0.071356 }, { 0.842917, 1.127034, 0.038310 }, + { 0.747734, 1.124634, 0.170981 }, { 1.378131, 1.410352, 1.877753 }, + { 1.319542, 1.407747, 1.958750 }, { 1.424860, 1.322530, 1.867574 }, + { 2.379939, 1.693036, 0.436722 }, { 2.413363, 1.778852, 0.475690 }, + { 2.340060, 1.636823, 0.509177 }, { 0.560335, 1.301357, 2.831908 }, + { 0.656147, 1.325504, 2.816512 }, { 0.537359, 1.315835, 2.928149 }, + { 2.308699, 2.450235, 2.131759 }, { 2.320931, 2.549287, 2.125504 }, + { 2.229118, 2.430013, 2.188837 }, { 1.398964, 0.129485, 0.101708 }, + { 1.406581, 0.030972, 0.117107 }, { 1.430994, 0.151393, 0.009545 }, + { 2.738661, 1.810796, 1.150217 }, { 2.785875, 1.826236, 1.063428 }, + { 2.803245, 1.821952, 1.225745 }, { 1.834855, 1.243843, 2.347878 }, + { 1.784425, 1.296402, 2.279364 }, { 1.812100, 1.277635, 2.439203 }, + { 2.675870, 1.821318, 0.707845 }, { 2.624071, 1.899672, 0.742160 }, + { 2.626939, 1.736877, 0.729653 }, { 2.769887, 2.202680, 2.007300 }, + { 2.822160, 2.284730, 2.030436 }, { 2.675095, 2.214055, 2.037049 }, + { 1.998308, 2.423041, 0.279446 }, { 1.928540, 2.367313, 0.234427 }, + { 2.088992, 2.387066, 0.257485 }, { 2.612892, 0.331665, 0.870959 }, + { 2.614312, 0.422865, 0.911954 }, { 2.693229, 0.320122, 0.812541 }, + { 1.438447, 2.473494, 1.915666 }, { 1.459389, 2.449059, 2.010347 }, + { 1.449352, 2.572151, 1.903508 }, { 0.869607, 0.994845, 2.380191 }, + { 0.960289, 0.969060, 2.413537 }, { 0.816006, 0.912361, 2.362208 }, + { 2.262026, 1.572083, 0.674023 }, { 2.207234, 1.647739, 0.709715 }, + { 2.201615, 1.503071, 0.634175 }, { 0.029213, 2.539434, 2.193714 }, + { 0.114704, 2.573874, 2.154917 }, { -0.041214, 2.610128, 2.187201 }, + { 2.804363, 0.979878, 0.585511 }, { 2.878881, 1.037113, 0.551286 }, + { 2.815526, 0.886603, 0.551230 }, { 1.145669, 0.191337, 1.809638 }, + { 1.136214, 0.202391, 1.710702 }, { 1.055125, 0.181165, 1.850847 }, + { 1.799933, 2.204886, 1.265283 }, { 1.721729, 2.267174, 1.263213 }, + { 1.858550, 2.222334, 1.186166 }, { 2.768473, 1.887750, 2.008596 }, + { 2.685808, 1.884735, 1.952404 }, { 2.781906, 1.980614, 2.043174 }, + { 0.566042, 0.942291, 2.780672 }, { 0.542564, 1.003858, 2.705451 }, + { 0.618895, 0.865111, 2.745320 }, { 1.440484, 2.308258, 0.440554 }, + { 1.345608, 2.311138, 0.409085 }, { 1.451129, 2.234898, 0.507674 }, + { 2.099174, 2.113051, 2.937382 }, { 2.064708, 2.019650, 2.927986 }, + { 2.084658, 2.162707, 2.851804 }, { 0.640344, 1.990762, 1.382271 }, + { 0.613247, 2.082472, 1.353029 }, { 0.567632, 1.925826, 1.359992 }, + { 1.005877, 1.535225, 0.537525 }, { 1.087595, 1.584022, 0.506849 }, + { 1.032672, 1.459432, 0.597003 }, { 1.001243, 2.787001, 1.696773 }, + { 0.992437, 2.688644, 1.712534 }, { 0.910309, 2.828442, 1.693079 }, + { 0.987802, 1.110389, 3.055721 }, { 1.065605, 1.081580, 3.111549 }, + { 0.999141, 1.206273, 3.029689 }, { 0.559374, 1.591763, 1.450101 }, + { 0.607457, 1.568462, 1.534631 }, { 0.618799, 1.573391, 1.371800 }, + { 1.478474, 0.101704, 1.588815 }, { 1.486885, 0.115724, 1.687469 }, + { 1.567854, 0.077935, 1.550783 }, { 1.197401, 2.030470, 2.891763 }, + { 1.204490, 2.130070, 2.886325 }, { 1.101431, 2.004405, 2.902264 }, + { 2.593369, 2.916082, 3.009380 }, { 2.501069, 2.936721, 2.976903 }, + { 2.647562, 2.878580, 2.934170 }, { 1.874216, 0.910326, 1.799684 }, + { 1.928068, 0.986814, 1.835033 }, { 1.784798, 0.943563, 1.769689 }, + { 1.120926, 0.186051, 2.975514 }, { 1.169400, 0.130500, 2.907954 }, + { 1.157365, 0.279169, 2.974435 }, { 1.743099, 0.329782, 2.034890 }, + { 1.692066, 0.296574, 2.114217 }, { 1.836555, 0.294352, 2.038158 }, + { 1.657390, 1.879589, 1.841187 }, { 1.717444, 1.958116, 1.826119 }, + { 1.702586, 1.796398, 1.808989 }, { 1.300228, 2.270635, 0.841357 }, + { 1.295869, 2.196579, 0.908414 }, { 1.228832, 2.337792, 0.861172 }, + { 1.948942, 0.107632, 2.195505 }, { 1.962856, 0.009021, 2.186429 }, + { 1.980313, 0.153514, 2.112374 }, { 0.592938, 2.832478, 1.152267 }, + { 0.595325, 2.932350, 1.156722 }, { 0.497900, 2.801368, 1.152355 }, + { 3.028118, 1.151776, 1.025723 }, { 3.094740, 1.221061, 1.053310 }, + { 2.957975, 1.193980, 0.968288 }, { 1.833976, 0.982234, 0.013196 }, + { 1.883561, 1.039306, 0.078648 }, { 1.885634, 0.976953, -0.072265 }, + { 1.798332, 1.244152, 1.851843 }, { 1.884876, 1.234745, 1.802633 }, + { 1.723244, 1.251207, 1.786177 }, { 2.873589, 1.201986, 1.817110 }, + { 2.927328, 1.201648, 1.732778 }, { 2.906900, 1.130124, 1.878153 }, + { 0.577414, 0.140788, 1.536999 }, { 0.611632, 0.171898, 1.625663 }, + { 0.652564, 0.138931, 1.471052 }, { 0.479143, 3.039990, 0.297688 }, + { 0.403226, 3.001126, 0.245475 }, { 0.521000, 2.968592, 0.353815 }, + { 2.581915, 1.009475, 0.768424 }, { 2.672051, 0.990541, 0.729474 }, + { 2.554187, 0.933238, 0.826898 }, { 2.285805, 1.798154, 0.177273 }, + { 2.371693, 1.842169, 0.151083 }, { 2.293527, 1.762829, 0.270507 }, + { 0.216147, 3.103959, 2.689932 }, { 0.206578, 3.176040, 2.621282 }, + { 0.297853, 3.049780, 2.670213 }, { 0.686871, 1.890136, 2.775596 }, + { 0.662080, 1.936036, 2.860911 }, { 0.605159, 1.878210, 2.719196 }, + { 1.069007, 2.995313, 3.029030 }, { 1.073078, 3.066635, 3.099005 }, + { 1.160823, 2.978560, 2.993125 }, { 2.694476, 1.837937, 0.085521 }, + { 2.644472, 1.755175, 0.111019 }, { 2.791382, 1.826384, 0.107334 }, + { 1.563852, 0.853418, 2.911395 }, { 1.602637, 0.770872, 2.952407 }, + { 1.488071, 0.886218, 2.967798 }, { 0.460347, 2.801415, 2.155280 }, + { 0.542405, 2.813267, 2.099369 }, { 0.486605, 2.790770, 2.251182 }, + { 1.067116, 0.828584, 1.118327 }, { 1.017197, 0.895557, 1.063347 }, + { 1.147577, 0.797335, 1.067835 }, { 2.248599, 1.379134, 0.873790 }, + { 2.293116, 1.393911, 0.785473 }, { 2.293247, 1.303346, 0.921359 }, + { 0.023727, 1.461944, 2.107485 }, { 0.039466, 1.452465, 2.205783 }, + { 0.056943, 1.551156, 2.076858 }, { 0.890338, 1.285968, 0.873042 }, + { 0.805316, 1.245775, 0.839044 }, { 0.933413, 1.339340, 0.800269 }, + { 2.648945, 1.437668, 0.287452 }, { 2.699407, 1.401270, 0.209165 }, + { 2.675734, 1.388361, 0.370224 }, { 0.390508, 3.056364, 2.334304 }, + { 0.374435, 3.116324, 2.255905 }, { 0.317691, 2.988021, 2.339484 }, + { 2.941599, 2.289971, 2.678662 }, { 3.039241, 2.269131, 2.673033 }, + { 2.912219, 2.286466, 2.774185 }, { 1.199353, 2.918159, 1.497088 }, + { 1.269711, 2.966859, 1.548839 }, { 1.118937, 2.904431, 1.554922 }, + { 2.948856, 0.470312, 1.096935 }, { 2.985099, 0.380752, 1.071136 }, + { 3.024561, 0.531828, 1.118947 }, { 2.489230, 1.274888, 2.457981 }, + { 2.575071, 1.260972, 2.408608 }, { 2.489590, 1.220024, 2.541587 }, + { 1.644334, 1.202727, 0.331251 }, { 1.631770, 1.123611, 0.271394 }, + { 1.635932, 1.174006, 0.426668 }, { 0.669309, 2.003121, 2.315451 }, + { 0.730467, 1.954706, 2.378027 }, { 0.574977, 1.974480, 2.332215 }, + { 2.284317, 1.482399, 1.602583 }, { 2.203780, 1.434499, 1.567663 }, + { 2.260654, 1.530045, 1.687259 }, { 0.527517, 2.701255, 2.395590 }, + { 0.572355, 2.743476, 2.474374 }, { 0.501162, 2.607549, 2.418497 }, + { 2.691990, 1.782137, 1.668582 }, { 2.622890, 1.751930, 1.602910 }, + { 2.728574, 1.870738, 1.640094 }, { 1.221627, 1.403014, 2.134535 }, + { 1.177639, 1.339731, 2.198256 }, { 1.151914, 1.458799, 2.089499 }, + { 1.276239, 1.209683, 0.830184 }, { 1.274310, 1.109869, 0.824392 }, + { 1.270617, 1.237626, 0.926036 }, { 0.816251, 2.909087, 3.046489 }, + { 0.901923, 2.953749, 3.020687 }, { 0.771765, 2.961669, 3.118989 }, + { 0.533906, 1.223529, 1.303916 }, { 0.569896, 1.156711, 1.238800 }, + { 0.578958, 1.211478, 1.392376 }, { 1.683346, 2.144673, 2.139148 }, + { 1.741238, 2.072530, 2.177146 }, { 1.613641, 2.103882, 2.080179 }, + { 2.875850, 0.044009, 1.250278 }, { 2.911148, -0.036725, 1.297565 }, + { 2.805482, 0.016229, 1.184882 }, { 1.784021, 0.926724, 0.326634 }, + { 1.855064, 0.984494, 0.286440 }, { 1.826414, 0.857633, 0.385195 }, + { 1.704426, 1.630143, 0.792940 }, { 1.672037, 1.613072, 0.699884 }, + { 1.668404, 1.559794, 0.854205 }, { 0.766134, 2.421196, 2.059355 }, + { 0.809315, 2.345348, 2.108166 }, { 0.752692, 2.497881, 2.122115 }, + { 0.871077, 2.182524, 2.154052 }, { 0.810919, 2.153015, 2.228283 }, + { 0.962738, 2.145297, 2.168630 }, { 1.865873, 1.349151, 0.032304 }, + { 1.827492, 1.323421, -0.056380 }, { 1.964725, 1.334066, 0.031487 }, + { 2.222735, 1.008374, 1.670202 }, { 2.286023, 1.057572, 1.610417 }, + { 2.274593, 0.951644, 1.734173 }, { 1.293692, 2.083151, 1.808644 }, + { 1.358039, 2.082571, 1.885189 }, { 1.324981, 2.019323, 1.738309 }, + { 2.875127, 0.361920, 0.728630 }, { 2.927991, 0.446531, 0.735430 }, + { 2.818555, 0.364492, 0.646210 }, { 0.560226, 1.918473, 2.025234 }, + { 0.614082, 1.999690, 2.002796 }, { 0.606294, 1.866823, 2.097414 }, + { 0.116601, 2.287058, 2.040205 }, { 0.135431, 2.341154, 1.958235 }, + { 0.072215, 2.344766, 2.108759 }, { 1.731207, 1.627822, 1.774748 }, + { 1.743176, 1.560404, 1.701867 }, { 1.758793, 1.587726, 1.862106 }, + { 2.955634, 2.730964, 0.905002 }, { 2.874554, 2.771880, 0.863146 }, + { 2.949333, 2.738789, 1.004496 }, { 1.501594, 2.091653, 1.371834 }, + { 1.538751, 2.009640, 1.415345 }, { 1.538425, 2.172932, 1.416971 }, + { 2.833318, 2.065374, 0.326849 }, { 2.735733, 2.046780, 0.338315 }, + { 2.849821, 2.101427, 0.235046 }, { 1.050436, 1.606848, 2.061210 }, + { 1.034856, 1.671504, 1.986532 }, { 0.963136, 1.567431, 2.089933 }, + { 2.852918, 2.103729, 1.290104 }, { 2.826100, 2.168810, 1.361134 }, + { 2.787516, 2.107990, 1.214576 }, { 2.693916, 0.326078, 2.033253 }, + { 2.731292, 0.332854, 1.940748 }, { 2.723277, 0.240009, 2.074847 }, + { 0.212220, 0.175849, 2.885870 }, { 0.212176, 0.100251, 2.820410 }, + { 0.153710, 0.152683, 2.963587 }, { 1.629055, 0.636815, 1.189020 }, + { 1.552820, 0.586142, 1.148765 }, { 1.622687, 0.632959, 1.288743 }, + { 1.339579, 0.227037, 2.582705 }, { 1.429690, 0.183681, 2.583158 }, + { 1.350244, 0.326169, 2.590398 }, { 0.877764, 3.073416, 2.428342 }, + { 0.876731, 3.168795, 2.458370 }, { 0.830020, 3.065500, 2.340833 }, + { 0.012970, 1.608793, 1.734893 }, { -0.086547, 1.600180, 1.730197 }, + { 0.041121, 1.618498, 1.830357 }, { 2.089223, 2.356806, 3.093349 }, + { 2.080570, 2.263474, 3.058502 }, { 2.007413, 2.409067, 3.069351 }, + { 2.470659, 0.854329, 2.975580 }, { 2.544938, 0.892503, 2.920576 }, + { 2.460200, 0.907998, 3.059307 }, { 2.511084, 0.660490, 1.700075 }, + { 2.478100, 0.600190, 1.627439 }, { 2.435588, 0.717009, 1.733330 }, + { 3.043270, 2.024359, 0.777765 }, { 3.006095, 2.041482, 0.686524 }, + { 3.131200, 2.071035, 0.787233 }, { 2.406380, 2.833836, 2.437090 }, + { 2.498902, 2.800394, 2.455016 }, { 2.410718, 2.912515, 2.375521 }, + { 2.734020, 1.466940, 2.755877 }, { 2.700045, 1.377356, 2.784519 }, + { 2.659075, 1.519847, 2.716075 }, { 0.855259, 2.409014, 2.948572 }, + { 0.811121, 2.434356, 2.862493 }, { 0.919369, 2.480852, 2.975574 }, + { 1.958775, 1.734897, 2.027947 }, { 1.918280, 1.644707, 2.012915 }, + { 2.045688, 1.724766, 2.076356 }, { 2.982304, 2.766292, 2.104076 }, + { 3.060064, 2.827760, 2.117309 }, { 2.923938, 2.801635, 2.030972 }, + { 0.495257, 2.600207, 0.002865 }, { 0.574514, 2.584488, 0.061783 }, + { 0.523212, 2.594076, -0.092952 }, { 0.620427, 1.316333, 1.773186 }, + { 0.550082, 1.344964, 1.838239 }, { 0.654246, 1.396176, 1.723373 }, + { 1.851595, 2.477959, 3.036031 }, { 1.794908, 2.470350, 2.954003 }, + { 1.842133, 2.569694, 3.074699 }, { 2.162743, 1.730778, 1.542545 }, + { 2.114802, 1.643183, 1.547900 }, { 2.217777, 1.743755, 1.625025 }, + { 2.529501, 2.719916, 1.696654 }, { 2.503803, 2.782004, 1.770713 }, + { 2.570790, 2.637380, 1.735165 }, { 2.307523, 3.038538, 0.375298 }, + { 2.404434, 3.016431, 0.364365 }, { 2.297896, 3.116554, 0.437110 }, + { 2.247696, 2.677393, 1.478840 }, { 2.181267, 2.606604, 1.454839 }, + { 2.208496, 2.737719, 1.548296 }, { 2.405993, 0.100579, 0.117782 }, + { 2.319176, 0.078530, 0.162242 }, { 2.399747, 0.190952, 0.075429 }, + { 2.845756, 2.478670, 2.035563 }, { 2.813879, 2.492950, 2.129265 }, + { 2.929733, 2.530863, 2.020603 }, { 2.412509, 2.437882, 2.677793 }, + { 2.409318, 2.340578, 2.654949 }, { 2.447902, 2.449183, 2.770635 }, + { 2.743492, 0.946496, 2.446978 }, { 2.763913, 0.946953, 2.349087 }, + { 2.644497, 0.941931, 2.460358 }, { 0.252801, 2.064296, 2.729654 }, + { 0.205969, 2.116614, 2.658453 }, { 0.233709, 2.105034, 2.818962 }, + { 3.063191, 1.922158, 1.214172 }, { 2.986959, 1.986712, 1.218799 }, + { 3.100113, 1.907543, 1.305950 }, { 2.880231, 3.025379, 0.083855 }, + { 2.795332, 3.002985, 0.131716 }, { 2.945707, 3.064380, 0.148600 }, + { 2.779395, 1.653453, 2.946437 }, { 2.784444, 1.581315, 2.877367 }, + { 2.816726, 1.619581, 3.032803 }, { 2.054265, 0.038926, 0.074381 }, + { 2.065626, -0.041658, 0.132494 }, { 2.100034, 0.023588, -0.013197 }, + { 2.355414, 2.720144, 2.698744 }, { 2.344450, 2.753016, 2.604939 }, + { 2.357313, 2.620162, 2.699021 }, { 0.361217, 2.018670, 0.301548 }, + { 0.303415, 2.006261, 0.220894 }, { 0.429552, 2.089293, 0.283039 }, + { 0.332342, 0.090876, 2.109455 }, { 0.263449, 0.156985, 2.139177 }, + { 0.390810, 0.132649, 2.039909 }, { 3.034524, 0.068387, 2.292232 }, + { 2.993148, 0.137518, 2.351469 }, { 3.043613, -0.017534, 2.342580 }, + { 0.237543, 0.583210, 1.838098 }, { 0.311681, 0.597860, 1.772608 }, + { 0.276038, 0.559019, 1.927165 }, { 2.503589, 2.263025, 2.095976 }, + { 2.420729, 2.315682, 2.114991 }, { 2.540302, 2.226586, 2.181559 }, + { 2.262877, 2.698771, 2.033787 }, { 2.333674, 2.768746, 2.024233 }, + { 2.248342, 2.653808, 1.945656 }, { 0.964111, 2.685023, 2.452276 }, + { 0.990834, 2.666914, 2.546923 }, { 1.040843, 2.726435, 2.403315 }, + { 0.794322, 2.734946, 2.845067 }, { 0.803437, 2.799933, 2.920523 }, + { 0.710474, 2.681741, 2.856841 }, { 2.896233, 2.435937, 1.571472 }, + { 2.949992, 2.393141, 1.644124 }, { 2.879950, 2.531950, 1.594195 }, + { 0.707918, 0.439981, 1.637015 }, { 0.805572, 0.456561, 1.650751 }, + { 0.687875, 0.438135, 1.539061 }, { 2.429562, 2.935991, 0.705919 }, + { 2.331154, 2.931808, 0.723196 }, { 2.451272, 2.883147, 0.623845 }, + { 0.890410, 0.316803, 3.083332 }, { 0.973293, 0.305226, 3.028592 }, + { 0.829674, 0.238704, 3.068783 }, { 0.544859, 2.440687, 1.202416 }, + { 0.638042, 2.463712, 1.174367 }, { 0.480239, 2.473483, 1.133506 }, + { 2.821353, 0.977632, 2.194345 }, { 2.890551, 1.047090, 2.214022 }, + { 2.854392, 0.917286, 2.121772 }, { 0.710748, 1.170876, 2.004677 }, + { 0.643095, 1.116736, 1.954758 }, { 0.730699, 1.254545, 1.953672 }, + { 1.323921, 1.479145, 0.621735 }, { 1.286777, 1.537103, 0.549201 }, + { 1.253285, 1.415737, 0.653197 }, { 2.698551, 2.717451, 0.063376 }, + { 2.639217, 2.637232, 0.056723 }, { 2.661341, 2.791201, 0.007017 }, + { 0.840228, 1.225083, 2.251827 }, { 0.854567, 1.147753, 2.313588 }, + { 0.765601, 1.203942, 2.188709 }, { 1.592481, 1.743693, 1.226737 }, + { 1.565173, 1.689101, 1.305946 }, { 1.691904, 1.754410, 1.226317 }, + { 1.258602, 2.759789, 1.297767 }, { 1.231534, 2.833672, 1.359482 }, + { 1.236972, 2.671656, 1.339776 }, { 1.283405, 3.025043, 1.772125 }, + { 1.383297, 3.021171, 1.774669 }, { 1.252723, 3.114943, 1.803376 }, + { 2.541767, 1.632310, 0.149237 }, { 2.449338, 1.608351, 0.119526 }, + { 2.572917, 1.566396, 0.217683 }, { 1.328386, 0.424321, 1.433167 }, + { 1.399835, 0.355967, 1.418246 }, { 1.300864, 0.463486, 1.345368 }, + { 0.236768, 0.950959, 2.590976 }, { 0.330331, 0.962132, 2.557492 }, + { 0.238410, 0.905038, 2.679794 }, { 0.313513, 2.796867, 3.012214 }, + { 0.323708, 2.795983, 2.912740 }, { 0.375929, 2.730056, 3.052716 }, + { 0.112414, 2.245971, 0.123348 }, { 0.177492, 2.170582, 0.114330 }, + { 0.162248, 2.331534, 0.137334 }, { 2.701271, 2.514977, 2.263225 }, + { 2.611569, 2.555932, 2.279852 }, { 2.714556, 2.437557, 2.325108 }, + { 1.770655, 0.024603, 2.384955 }, { 1.699905, 0.005690, 2.316861 }, + { 1.847949, 0.070276, 2.340914 }, { 0.009882, 1.194905, 1.519823 }, + { -0.077604, 1.217861, 1.477170 }, { 0.058135, 1.279012, 1.544271 }, + { 2.362329, 1.189368, 1.500885 }, { 2.448073, 1.222733, 1.461709 }, + { 2.288210, 1.252204, 1.477265 }, { 1.943393, 1.163287, 1.318490 }, + { 1.904684, 1.254202, 1.303121 }, { 1.923693, 1.134053, 1.412070 }, + { 0.095808, 0.472131, 0.518367 }, { 0.157246, 0.463382, 0.596782 }, + { 0.143525, 0.518364, 0.443630 }, { 0.157283, 0.392476, 2.732502 }, + { 0.071212, 0.434916, 2.760620 }, { 0.167245, 0.303987, 2.778005 }, + { 2.308432, 0.518593, 0.204206 }, { 2.407431, 0.531838, 0.199337 }, + { 2.285893, 0.425193, 0.176483 }, { 0.944487, 0.067090, 1.962743 }, + { 0.979830, -0.021319, 1.932171 }, { 0.921300, 0.061935, 2.059881 }, + { 0.672079, 1.749103, 0.099972 }, { 0.679855, 1.844222, 0.129836 }, + { 0.575510, 1.724947, 0.090434 }, { 1.825839, 0.707532, 0.059138 }, + { 1.820204, 0.806882, 0.049239 }, { 1.897469, 0.684609, 0.125044 }, + { 2.985048, 1.441246, 0.798920 }, { 3.015628, 1.520955, 0.850991 }, + { 2.984317, 1.463406, 0.701409 }, { 2.308448, 2.258307, 1.299501 }, + { 2.290653, 2.254337, 1.201177 }, { 2.344603, 2.348475, 1.323219 } }; diff --git a/src/gromacs/nbnxm/benchmark/bench_setup.cpp b/src/gromacs/nbnxm/benchmark/bench_setup.cpp index 448321201f..ecfe6af14d 100644 --- a/src/gromacs/nbnxm/benchmark/bench_setup.cpp +++ b/src/gromacs/nbnxm/benchmark/bench_setup.cpp @@ -80,10 +80,11 @@ namespace Nbnxm * * Returns an error string when the kernel is not available. */ -static gmx::compat::optional checkKernelSetup(const KernelBenchOptions &options) +static gmx::compat::optional checkKernelSetup(const KernelBenchOptions& options) { - GMX_RELEASE_ASSERT(options.nbnxmSimd < BenchMarkKernels::Count && - options.nbnxmSimd != BenchMarkKernels::SimdAuto, "Need a valid kernel SIMD type"); + GMX_RELEASE_ASSERT(options.nbnxmSimd < BenchMarkKernels::Count + && options.nbnxmSimd != BenchMarkKernels::SimdAuto, + "Need a valid kernel SIMD type"); // Check SIMD support if ((options.nbnxmSimd != BenchMarkKernels::SimdNo && !GMX_SIMD) @@ -93,7 +94,7 @@ static gmx::compat::optional checkKernelSetup(const KernelBenchOpti #ifndef GMX_NBNXN_SIMD_2XNN || options.nbnxmSimd == BenchMarkKernels::Simd2XMM #endif - ) + ) { return "the requested SIMD kernel was not set up at configuration time"; } @@ -102,7 +103,7 @@ static gmx::compat::optional checkKernelSetup(const KernelBenchOpti } //! Helper to translate between the different enumeration values. -static KernelType translateBenchmarkEnum(const BenchMarkKernels &kernel) +static KernelType translateBenchmarkEnum(const BenchMarkKernels& kernel) { int kernelInt = static_cast(kernel); return static_cast(kernelInt); @@ -110,15 +111,15 @@ static KernelType translateBenchmarkEnum(const BenchMarkKernels &kernel) /*! \brief Returns the kernel setup */ -static KernelSetup getKernelSetup(const KernelBenchOptions &options) +static KernelSetup getKernelSetup(const KernelBenchOptions& options) { auto messageWhenInvalid = checkKernelSetup(options); GMX_RELEASE_ASSERT(!messageWhenInvalid, "Need valid options"); KernelSetup kernelSetup; - //The int enum options.nbnxnSimd is set up to match KernelType + 1 - kernelSetup.kernelType = translateBenchmarkEnum(options.nbnxmSimd); + // The int enum options.nbnxnSimd is set up to match KernelType + 1 + kernelSetup.kernelType = translateBenchmarkEnum(options.nbnxmSimd); // The plain-C kernel does not support analytical ewald correction if (kernelSetup.kernelType == KernelType::Cpu4x4_PlainC) { @@ -126,21 +127,22 @@ static KernelSetup getKernelSetup(const KernelBenchOptions &options) } else { - kernelSetup.ewaldExclusionType = options.useTabulatedEwaldCorr ? EwaldExclusionType::Table : EwaldExclusionType::Analytical; + kernelSetup.ewaldExclusionType = options.useTabulatedEwaldCorr ? EwaldExclusionType::Table + : EwaldExclusionType::Analytical; } return kernelSetup; } //! Return an interaction constants struct with members used in the benchmark set appropriately -static interaction_const_t setupInteractionConst(const KernelBenchOptions &options) +static interaction_const_t setupInteractionConst(const KernelBenchOptions& options) { interaction_const_t ic; - ic.vdwtype = evdwCUT; - ic.vdw_modifier = eintmodPOTSHIFT; - ic.rvdw = options.pairlistCutoff; + ic.vdwtype = evdwCUT; + ic.vdw_modifier = eintmodPOTSHIFT; + ic.rvdw = options.pairlistCutoff; ic.eeltype = (options.coulombType == BenchMarkCoulomb::Pme ? eelPME : eelRF); ic.coulomb_modifier = eintmodPOTSHIFT; @@ -148,8 +150,8 @@ static interaction_const_t setupInteractionConst(const KernelBenchOptions &optio // Reaction-field with epsilon_rf=inf // TODO: Replace by calc_rffac() after refactoring that - ic.k_rf = 0.5*std::pow(ic.rcoulomb, -3); - ic.c_rf = 1/ic.rcoulomb + ic.k_rf*ic.rcoulomb*ic.rcoulomb; + ic.k_rf = 0.5 * std::pow(ic.rcoulomb, -3); + ic.c_rf = 1 / ic.rcoulomb + ic.k_rf * ic.rcoulomb * ic.rcoulomb; if (EEL_PME_EWALD(ic.eeltype)) { @@ -164,57 +166,46 @@ static interaction_const_t setupInteractionConst(const KernelBenchOptions &optio } //! Sets up and returns a Nbnxm object for the given benchmark options and system -static std::unique_ptr -setupNbnxmForBenchInstance(const KernelBenchOptions &options, - const gmx::BenchmarkSystem &system) +static std::unique_ptr setupNbnxmForBenchInstance(const KernelBenchOptions& options, + const gmx::BenchmarkSystem& system) { - const auto pinPolicy = (options.useGpu ? gmx::PinningPolicy::PinnedIfSupported : gmx::PinningPolicy::CannotBePinned); - const int numThreads = options.numThreads; + const auto pinPolicy = (options.useGpu ? gmx::PinningPolicy::PinnedIfSupported + : gmx::PinningPolicy::CannotBePinned); + const int numThreads = options.numThreads; // Note: the options and Nbnxm combination rule enums values should match - const int combinationRule = static_cast(options.ljCombinationRule); + const int combinationRule = static_cast(options.ljCombinationRule); - auto messageWhenInvalid = checkKernelSetup(options); + auto messageWhenInvalid = checkKernelSetup(options); if (messageWhenInvalid) { - gmx_fatal(FARGS, "Requested kernel is unavailable because %s.", - messageWhenInvalid->c_str()); + gmx_fatal(FARGS, "Requested kernel is unavailable because %s.", messageWhenInvalid->c_str()); } Nbnxm::KernelSetup kernelSetup = getKernelSetup(options); - PairlistParams pairlistParams(kernelSetup.kernelType, false, options.pairlistCutoff, false); + PairlistParams pairlistParams(kernelSetup.kernelType, false, options.pairlistCutoff, false); - GridSet gridSet(epbcXYZ, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy); + GridSet gridSet(epbcXYZ, false, nullptr, nullptr, pairlistParams.pairlistType, false, + numThreads, pinPolicy); - auto pairlistSets = std::make_unique(pairlistParams, false, 0); + auto pairlistSets = std::make_unique(pairlistParams, false, 0); - auto pairSearch = std::make_unique(epbcXYZ, false, nullptr, nullptr, - pairlistParams.pairlistType, - false, numThreads, pinPolicy); + auto pairSearch = std::make_unique( + epbcXYZ, false, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy); - auto atomData = std::make_unique(pinPolicy); + auto atomData = std::make_unique(pinPolicy); // Put everything together - auto nbv = std::make_unique(std::move(pairlistSets), - std::move(pairSearch), - std::move(atomData), - kernelSetup, - nullptr, - nullptr); - - nbnxn_atomdata_init(gmx::MDLogger(), - nbv->nbat.get(), kernelSetup.kernelType, - combinationRule, system.numAtomTypes, system.nonbondedParameters.data(), - 1, numThreads); + auto nbv = std::make_unique(std::move(pairlistSets), std::move(pairSearch), + std::move(atomData), kernelSetup, nullptr, nullptr); + + nbnxn_atomdata_init(gmx::MDLogger(), nbv->nbat.get(), kernelSetup.kernelType, combinationRule, + system.numAtomTypes, system.nonbondedParameters.data(), 1, numThreads); t_nrnb nrnb; GMX_RELEASE_ASSERT(!TRICLINIC(system.box), "Only rectangular unit-cells are supported here"); - const rvec lowerCorner = { 0, 0, 0 }; - const rvec upperCorner = { - system.box[XX][XX], - system.box[YY][YY], - system.box[ZZ][ZZ] - }; + const rvec lowerCorner = { 0, 0, 0 }; + const rvec upperCorner = { system.box[XX][XX], system.box[YY][YY], system.box[ZZ][ZZ] }; gmx::ArrayRef atomInfo; if (options.useHalfLJOptimization) @@ -226,30 +217,26 @@ setupNbnxmForBenchInstance(const KernelBenchOptions &options, atomInfo = system.atomInfoAllVdw; } - const real atomDensity = system.coordinates.size()/det(system.box); + const real atomDensity = system.coordinates.size() / det(system.box); - nbnxn_put_on_grid(nbv.get(), - system.box, 0, lowerCorner, upperCorner, - nullptr, { 0, int(system.coordinates.size()) }, atomDensity, - atomInfo, system.coordinates, - 0, nullptr); + nbnxn_put_on_grid(nbv.get(), system.box, 0, lowerCorner, upperCorner, nullptr, + { 0, int(system.coordinates.size()) }, atomDensity, atomInfo, + system.coordinates, 0, nullptr); - nbv->constructPairlist(gmx::InteractionLocality::Local, - &system.excls, 0, &nrnb); + nbv->constructPairlist(gmx::InteractionLocality::Local, &system.excls, 0, &nrnb); t_mdatoms mdatoms; // We only use (read) the atom type and charge from mdatoms - mdatoms.typeA = const_cast(system.atomTypes.data()); - mdatoms.chargeA = const_cast(system.charges.data()); + mdatoms.typeA = const_cast(system.atomTypes.data()); + mdatoms.chargeA = const_cast(system.charges.data()); nbv->setAtomProperties(mdatoms, atomInfo); return nbv; } //! Add the options instance to the list for all requested kernel SIMD types -static void -expandSimdOptionAndPushBack(const KernelBenchOptions &options, - std::vector *optionsList) +static void expandSimdOptionAndPushBack(const KernelBenchOptions& options, + std::vector* optionsList) { if (options.nbnxmSimd == BenchMarkKernels::SimdAuto) { @@ -257,12 +244,12 @@ expandSimdOptionAndPushBack(const KernelBenchOptions &options, #ifdef GMX_NBNXN_SIMD_4XN optionsList->push_back(options); optionsList->back().nbnxmSimd = BenchMarkKernels::Simd4XM; - addedInstance = true; + addedInstance = true; #endif #ifdef GMX_NBNXN_SIMD_2XNN optionsList->push_back(options); optionsList->back().nbnxmSimd = BenchMarkKernels::Simd2XMM; - addedInstance = true; + addedInstance = true; #endif if (!addedInstance) { @@ -280,25 +267,26 @@ expandSimdOptionAndPushBack(const KernelBenchOptions &options, // // When \p doWarmup is true runs the warmup iterations instead // of the normal ones and does not print any results -static void setupAndRunInstance(const gmx::BenchmarkSystem &system, - const KernelBenchOptions &options, +static void setupAndRunInstance(const gmx::BenchmarkSystem& system, + const KernelBenchOptions& options, const bool doWarmup) { // Generate an, accurate, estimate of the number of non-zero pair interactions - const real atomDensity = system.coordinates.size()/det(system.box); - const real numPairsWithinCutoff = atomDensity*4.0/3.0*M_PI*std::pow(options.pairlistCutoff, 3); - const real numUsefulPairs = system.coordinates.size()*0.5*(numPairsWithinCutoff + 1); + const real atomDensity = system.coordinates.size() / det(system.box); + const real numPairsWithinCutoff = + atomDensity * 4.0 / 3.0 * M_PI * std::pow(options.pairlistCutoff, 3); + const real numUsefulPairs = system.coordinates.size() * 0.5 * (numPairsWithinCutoff + 1); std::unique_ptr nbv = setupNbnxmForBenchInstance(options, system); // We set the interaction cut-off to the pairlist cut-off - interaction_const_t ic = setupInteractionConst(options); + interaction_const_t ic = setupInteractionConst(options); - t_nrnb nrnb = { 0 }; + t_nrnb nrnb = { 0 }; - gmx_enerdata_t enerd(1, 0); + gmx_enerdata_t enerd(1, 0); - gmx::StepWorkload stepWork; + gmx::StepWorkload stepWork; stepWork.computeForces = true; if (options.computeVirialAndEnergy) { @@ -306,39 +294,36 @@ static void setupAndRunInstance(const gmx::BenchmarkSystem &system, stepWork.computeEnergy = true; } - const gmx::EnumerationArray kernelNames = { "auto", "no", "4xM", "2xMM" }; + const gmx::EnumerationArray kernelNames = { "auto", "no", "4xM", + "2xMM" }; - const gmx::EnumerationArray combruleNames = { "geom.", "LB", "none" }; + const gmx::EnumerationArray combruleNames = { "geom.", "LB", + "none" }; if (!doWarmup) { fprintf(stdout, "%-7s %-4s %-5s %-4s ", options.coulombType == BenchMarkCoulomb::Pme ? "Ewald" : "RF", options.useHalfLJOptimization ? "half" : "all", - combruleNames[options.ljCombinationRule].c_str(), - kernelNames[options.nbnxmSimd].c_str()); + combruleNames[options.ljCombinationRule].c_str(), kernelNames[options.nbnxmSimd].c_str()); } // Run pre-iteration to avoid cache misses for (int iter = 0; iter < options.numPreIterations; iter++) { - nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, - ic, stepWork, enbvClearFYes, system.forceRec, - &enerd, - &nrnb); + nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, ic, stepWork, enbvClearFYes, + system.forceRec, &enerd, &nrnb); } - const int numIterations = (doWarmup ? options.numWarmupIterations : options.numIterations); - const PairlistSet &pairlistSet = nbv->pairlistSets().pairlistSet(gmx::InteractionLocality::Local); - const gmx::index numPairs = pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_ + pairlistSet.natpair_q_; - gmx_cycles_t cycles = gmx_cycles_read(); + const int numIterations = (doWarmup ? options.numWarmupIterations : options.numIterations); + const PairlistSet& pairlistSet = nbv->pairlistSets().pairlistSet(gmx::InteractionLocality::Local); + const gmx::index numPairs = pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_ + pairlistSet.natpair_q_; + gmx_cycles_t cycles = gmx_cycles_read(); for (int iter = 0; iter < numIterations; iter++) { // Run the kernel without force clearing - nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, - ic, stepWork, enbvClearFNo, system.forceRec, - &enerd, - &nrnb); + nbv->dispatchNonbondedKernel(gmx::InteractionLocality::Local, ic, stepWork, enbvClearFNo, + system.forceRec, &enerd, &nrnb); } cycles = gmx_cycles_read() - cycles; if (!doWarmup) @@ -346,25 +331,20 @@ static void setupAndRunInstance(const gmx::BenchmarkSystem &system, const double dCycles = static_cast(cycles); if (options.cyclesPerPair) { - fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", - cycles*1e-6, - dCycles/options.numIterations*1e-6, - dCycles/(options.numIterations*numPairs), - dCycles/(options.numIterations*numUsefulPairs)); + fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", cycles * 1e-6, + dCycles / options.numIterations * 1e-6, dCycles / (options.numIterations * numPairs), + dCycles / (options.numIterations * numUsefulPairs)); } else { - fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", - dCycles*1e-6, - dCycles/options.numIterations*1e-6, - options.numIterations*numPairs/dCycles, - options.numIterations*numUsefulPairs/dCycles); + fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n", dCycles * 1e-6, + dCycles / options.numIterations * 1e-6, options.numIterations * numPairs / dCycles, + options.numIterations * numUsefulPairs / dCycles); } } } -void bench(const int sizeFactor, - const KernelBenchOptions &options) +void bench(const int sizeFactor, const KernelBenchOptions& options) { // We don't want to call gmx_omp_nthreads_init(), so we init what we need gmx_omp_nthreads_set(emntPairsearch, options.numThreads); @@ -372,12 +352,12 @@ void bench(const int sizeFactor, const gmx::BenchmarkSystem system(sizeFactor); - real minBoxSize = norm(system.box[XX]); + real minBoxSize = norm(system.box[XX]); for (int dim = YY; dim < DIM; dim++) { minBoxSize = std::min(minBoxSize, norm(system.box[dim])); } - if (options.pairlistCutoff > 0.5*minBoxSize) + if (options.pairlistCutoff > 0.5 * minBoxSize) { gmx_fatal(FARGS, "The cut-off should be shorter than half the box size"); } @@ -385,7 +365,7 @@ void bench(const int sizeFactor, std::vector optionsList; if (options.doAll) { - KernelBenchOptions opt = options; + KernelBenchOptions opt = options; gmx::EnumerationWrapper coulombIter; for (auto coulombType : coulombIter) { @@ -424,12 +404,13 @@ void bench(const int sizeFactor, fprintf(stdout, "Cut-off radius: %g nm\n", options.pairlistCutoff); fprintf(stdout, "Number of threads: %d\n", options.numThreads); fprintf(stdout, "Number of iterations: %d\n", options.numIterations); - fprintf(stdout, "Compute energies: %s\n", - options.computeVirialAndEnergy ? "yes" : "no"); + fprintf(stdout, "Compute energies: %s\n", options.computeVirialAndEnergy ? "yes" : "no"); if (options.coulombType != BenchMarkCoulomb::ReactionField) { fprintf(stdout, "Ewald excl. corr.: %s\n", - options.nbnxmSimd == BenchMarkKernels::SimdNo || options.useTabulatedEwaldCorr ? "table" : "analytical"); + options.nbnxmSimd == BenchMarkKernels::SimdNo || options.useTabulatedEwaldCorr + ? "table" + : "analytical"); } printf("\n"); @@ -442,7 +423,7 @@ void bench(const int sizeFactor, options.cyclesPerPair ? "cycles/pair" : "pairs/cycle"); fprintf(stdout, " total useful\n"); - for (const auto &optionsInstance : optionsList) + for (const auto& optionsInstance : optionsList) { setupAndRunInstance(system, optionsInstance, false); } diff --git a/src/gromacs/nbnxm/benchmark/bench_setup.h b/src/gromacs/nbnxm/benchmark/bench_setup.h index f3355bf5e3..2e33352376 100644 --- a/src/gromacs/nbnxm/benchmark/bench_setup.h +++ b/src/gromacs/nbnxm/benchmark/bench_setup.h @@ -84,35 +84,35 @@ enum class BenchMarkCoulomb : int struct KernelBenchOptions { //! Whether to use a GPU, currently GPUs are not supported - bool useGpu = false; + bool useGpu = false; //! The number of OpenMP threads to use - int numThreads = 1; + int numThreads = 1; //! The SIMD type for the kernel - BenchMarkKernels nbnxmSimd = BenchMarkKernels::SimdAuto; + BenchMarkKernels nbnxmSimd = BenchMarkKernels::SimdAuto; //! The LJ combination rule BenchMarkCombRule ljCombinationRule = BenchMarkCombRule::RuleGeom; //! Use i-cluster half-LJ optimization for clusters with <= half LJ - bool useHalfLJOptimization = false; + bool useHalfLJOptimization = false; //! The pairlist and interaction cut-off - real pairlistCutoff = 1.0; + real pairlistCutoff = 1.0; //! The Coulomb Ewald coefficient - real ewaldcoeff_q = 0; + real ewaldcoeff_q = 0; //! Whether to compute energies (shift forces for virial are always computed on CPU) - bool computeVirialAndEnergy = false; + bool computeVirialAndEnergy = false; //! The Coulomb interaction function - BenchMarkCoulomb coulombType = BenchMarkCoulomb::Pme; + BenchMarkCoulomb coulombType = BenchMarkCoulomb::Pme; //! Whether to use tabulated PME grid correction instead of analytical, not applicable with simd=no - bool useTabulatedEwaldCorr = false; + bool useTabulatedEwaldCorr = false; //! Whether to run all combinations of Coulomb type, combination rule and SIMD - bool doAll = false; + bool doAll = false; //! Number of iterations to run before running each kernel benchmark, currently always 1 - int numPreIterations = 1; + int numPreIterations = 1; //! The number of iterations for each kernel - int numIterations = 100; + int numIterations = 100; //! The number of (untimed) iterations to run at startup to warm up the CPU - int numWarmupIterations = 0; + int numWarmupIterations = 0; //! Print cycles/pair instead of pairs/cycle - bool cyclesPerPair = false; + bool cyclesPerPair = false; }; /*! \brief @@ -126,8 +126,7 @@ struct KernelBenchOptions * \param[in] sizeFactor How much should the system size be increased. * \param[in] options How the benchmark will be run. */ -void bench(int sizeFactor, - const KernelBenchOptions &options); +void bench(int sizeFactor, const KernelBenchOptions& options); } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/benchmark/bench_system.cpp b/src/gromacs/nbnxm/benchmark/bench_system.cpp index 7eb9681b7e..ffe0a899ff 100644 --- a/src/gromacs/nbnxm/benchmark/bench_system.cpp +++ b/src/gromacs/nbnxm/benchmark/bench_system.cpp @@ -65,34 +65,30 @@ namespace // A 3-site water model //! The number of atoms in a molecule -constexpr int numAtomsInMolecule = 3; +constexpr int numAtomsInMolecule = 3; //! The atom type of the oxygen atom -constexpr int typeOxygen = 0; +constexpr int typeOxygen = 0; //! The atom type of the hydrogen atom -constexpr int typeHydrogen = 1; +constexpr int typeHydrogen = 1; //! The charge of the oxygen atom -constexpr real chargeOxygen = -0.8476; +constexpr real chargeOxygen = -0.8476; //! The charge of the hydrogen atom -constexpr real chargeHydrogen = 0.4238; +constexpr real chargeHydrogen = 0.4238; //! The LJ C6 parameter of the Oxygen atom -constexpr real c6Oxygen = 0.0026173456; +constexpr real c6Oxygen = 0.0026173456; //! The LJ C12 parameter of the Oxygen atom -constexpr real c12Oxygen = 2.634129e-06; +constexpr real c12Oxygen = 2.634129e-06; // Note that the hydrogen has LJ parameters all zero -} // namespace +} // namespace //! Generates coordinates and a box for the base system scaled by \p multiplicationFactor // // The parameter \p multiplicationFactor should be a power of 2. // A fatal error is generated when this is not the case. -static void -generateCoordinates(int multiplicationFactor, - std::vector *coordinates, - matrix box) +static void generateCoordinates(int multiplicationFactor, std::vector* coordinates, matrix box) { - if (multiplicationFactor < 1 || - (multiplicationFactor & (multiplicationFactor - 1)) != 0) + if (multiplicationFactor < 1 || (multiplicationFactor & (multiplicationFactor - 1)) != 0) { gmx_fatal(FARGS, "The size factor has to be a power of 2"); } @@ -107,10 +103,10 @@ generateCoordinates(int multiplicationFactor, ivec factors = { 1, 1, 1 }; - int dim = 0; + int dim = 0; while (multiplicationFactor > 1) { - factors[dim] *= 2; + factors[dim] *= 2; multiplicationFactor /= 2; dim++; if (dim == DIM) @@ -118,24 +114,24 @@ generateCoordinates(int multiplicationFactor, dim = 0; } } - printf("Stacking a box of %zu atoms %d x %d x %d times\n", - coordinates1000.size(), factors[XX], factors[YY], factors[ZZ]); + printf("Stacking a box of %zu atoms %d x %d x %d times\n", coordinates1000.size(), factors[XX], + factors[YY], factors[ZZ]); - coordinates->resize(factors[XX]*factors[YY]*factors[ZZ]*coordinates1000.size()); + coordinates->resize(factors[XX] * factors[YY] * factors[ZZ] * coordinates1000.size()); int i = 0; gmx::RVec shift; for (int x = 0; x < factors[XX]; x++) { - shift[XX] = x*box1000[XX][XX]; + shift[XX] = x * box1000[XX][XX]; for (int y = 0; y < factors[YY]; y++) { - shift[YY] = y*box1000[YY][YY]; + shift[YY] = y * box1000[YY][YY]; for (int z = 0; z < factors[ZZ]; z++) { - shift[ZZ] = z*box1000[ZZ][ZZ]; + shift[ZZ] = z * box1000[ZZ][ZZ]; - for (const gmx::RVec &coordOrig : coordinates1000) + for (const gmx::RVec& coordOrig : coordinates1000) { (*coordinates)[i] = coordOrig + shift; i++; @@ -148,7 +144,7 @@ generateCoordinates(int multiplicationFactor, { for (int d2 = 0; d2 < DIM; d2++) { - box[d1][d2] = factors[d1]*box1000[d1][d2]; + box[d1][d2] = factors[d1] * box1000[d1][d2]; } } } @@ -156,7 +152,7 @@ generateCoordinates(int multiplicationFactor, BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor) { numAtomTypes = 2; - nonbondedParameters.resize(numAtomTypes*numAtomTypes*2, 0); + nonbondedParameters.resize(numAtomTypes * numAtomTypes * 2, 0); nonbondedParameters[0] = c6Oxygen; nonbondedParameters[1] = c12Oxygen; @@ -164,14 +160,15 @@ BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor) put_atoms_in_box(epbcXYZ, box, coordinates); int numAtoms = coordinates.size(); - GMX_RELEASE_ASSERT(numAtoms % numAtomsInMolecule == 0, "Coordinates should match whole molecules"); + GMX_RELEASE_ASSERT(numAtoms % numAtomsInMolecule == 0, + "Coordinates should match whole molecules"); atomTypes.resize(numAtoms); charges.resize(numAtoms); atomInfoAllVdw.resize(numAtoms); atomInfoOxygenVdw.resize(numAtoms); snew(excls.index, numAtoms + 1); - snew(excls.a, numAtoms*numAtomsInMolecule); + snew(excls.a, numAtoms * numAtomsInMolecule); excls.index[0] = 0; for (int a = 0; a < numAtoms; a++) @@ -197,9 +194,9 @@ BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor) const int firstAtomInMolecule = a - (a % numAtomsInMolecule); for (int aj = 0; aj < numAtomsInMolecule; aj++) { - excls.a[a*numAtomsInMolecule + aj] = firstAtomInMolecule + aj; + excls.a[a * numAtomsInMolecule + aj] = firstAtomInMolecule + aj; } - excls.index[a + 1] = (a + 1)*numAtomsInMolecule; + excls.index[a + 1] = (a + 1) * numAtomsInMolecule; } forceRec.ntype = numAtomTypes; diff --git a/src/gromacs/nbnxm/benchmark/bench_system.h b/src/gromacs/nbnxm/benchmark/bench_system.h index 1801f77298..512368ddda 100644 --- a/src/gromacs/nbnxm/benchmark/bench_system.h +++ b/src/gromacs/nbnxm/benchmark/bench_system.h @@ -68,25 +68,25 @@ struct BenchmarkSystem BenchmarkSystem(int multiplicationFactor); //! Number of different atom types in test system. - int numAtomTypes; + int numAtomTypes; //! Storage for parameters for short range interactions. - std::vector nonbondedParameters; + std::vector nonbondedParameters; //! Storage for atom type parameters. - std::vector atomTypes; + std::vector atomTypes; //! Storage for atom partial charges. - std::vector charges; + std::vector charges; //! Atom info where all atoms are marked to have Van der Waals interactions - std::vector atomInfoAllVdw; + std::vector atomInfoAllVdw; //! Atom info where only oxygen atoms are marked to have Van der Waals interactions - std::vector atomInfoOxygenVdw; + std::vector atomInfoOxygenVdw; //! Information about exclusions. - t_blocka excls; + t_blocka excls; //! Storage for atom positions. std::vector coordinates; //! System simulation box. - matrix box; + matrix box; //! Forcerec with only the entries used in the benchmark set - t_forcerec forceRec; + t_forcerec forceRec; }; } // namespace gmx diff --git a/src/gromacs/nbnxm/boundingboxes.h b/src/gromacs/nbnxm/boundingboxes.h index 6ebba22700..945fbc5961 100644 --- a/src/gromacs/nbnxm/boundingboxes.h +++ b/src/gromacs/nbnxm/boundingboxes.h @@ -61,49 +61,49 @@ static constexpr int c_numBoundingBoxBounds1D = 2; * we only need to check for single precision support here. * This uses less (cache-)memory and SIMD is faster, at least on x86. */ -#if GMX_SIMD4_HAVE_FLOAT -# define NBNXN_SEARCH_BB_SIMD4 1 -#else -# define NBNXN_SEARCH_BB_SIMD4 0 -#endif +# if GMX_SIMD4_HAVE_FLOAT +# define NBNXN_SEARCH_BB_SIMD4 1 +# else +# define NBNXN_SEARCH_BB_SIMD4 0 +# endif -#if NBNXN_SEARCH_BB_SIMD4 +# if NBNXN_SEARCH_BB_SIMD4 /* Always use 4-wide SIMD for bounding box calculations */ -# if !GMX_DOUBLE +# if !GMX_DOUBLE /* Single precision BBs + coordinates, we can also load coordinates with SIMD */ -# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 1 -# else -# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 0 -# endif +# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 1 +# else +# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 0 +# endif /* Store bounding boxes corners as quadruplets: xxxxyyyyzzzz * * The packed bounding box coordinate stride is always set to 4. * With AVX we could use 8, but that turns out not to be faster. */ -# define NBNXN_BBXXXX 1 +# define NBNXN_BBXXXX 1 //! The number of bounding boxes in a pack, also the size of a pack along one dimension static constexpr int c_packedBoundingBoxesDimSize = GMX_SIMD4_WIDTH; //! Total number of corners (floats) in a pack of bounding boxes -static constexpr int c_packedBoundingBoxesSize = - c_packedBoundingBoxesDimSize*DIM*Nbnxm::c_numBoundingBoxBounds1D; +static constexpr int c_packedBoundingBoxesSize = + c_packedBoundingBoxesDimSize * DIM * Nbnxm::c_numBoundingBoxBounds1D; //! Returns the starting index of the bounding box pack that contains the given cluster static constexpr inline int packedBoundingBoxesIndex(int clusterIndex) { - return (clusterIndex/c_packedBoundingBoxesDimSize)*c_packedBoundingBoxesSize; + return (clusterIndex / c_packedBoundingBoxesDimSize) * c_packedBoundingBoxesSize; } -#else /* NBNXN_SEARCH_BB_SIMD4 */ +# else /* NBNXN_SEARCH_BB_SIMD4 */ -# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 0 -# define NBNXN_BBXXXX 0 +# define NBNXN_SEARCH_SIMD4_FLOAT_X_BB 0 +# define NBNXN_BBXXXX 0 -#endif /* NBNXN_SEARCH_BB_SIMD4 */ +# endif /* NBNXN_SEARCH_BB_SIMD4 */ #endif // !DOXYGEN diff --git a/src/gromacs/nbnxm/clusterdistancekerneltype.h b/src/gromacs/nbnxm/clusterdistancekerneltype.h index 0726ab1ac6..43ce747dad 100644 --- a/src/gromacs/nbnxm/clusterdistancekerneltype.h +++ b/src/gromacs/nbnxm/clusterdistancekerneltype.h @@ -61,9 +61,8 @@ enum class ClusterDistanceKernelType : int }; //! Return the cluster distance kernel type given the pairlist type and atomdata -static inline ClusterDistanceKernelType -getClusterDistanceKernelType(const PairlistType pairlistType, - const nbnxn_atomdata_t &atomdata) +static inline ClusterDistanceKernelType getClusterDistanceKernelType(const PairlistType pairlistType, + const nbnxn_atomdata_t& atomdata) { if (pairlistType == PairlistType::HierarchicalNxN) { @@ -88,7 +87,8 @@ getClusterDistanceKernelType(const PairlistType pairlistType, #elif GMX_SIMD && GMX_SIMD_REAL_WIDTH == 8 return ClusterDistanceKernelType::CpuSimd_2xMM; #else - GMX_RELEASE_ASSERT(false, "Expect 4-wide or 8-wide SIMD with 4x4 list and nbat SIMD layout"); + GMX_RELEASE_ASSERT(false, + "Expect 4-wide or 8-wide SIMD with 4x4 list and nbat SIMD layout"); #endif } else @@ -99,7 +99,8 @@ getClusterDistanceKernelType(const PairlistType pairlistType, #elif GMX_SIMD && GMX_SIMD_REAL_WIDTH == 16 return ClusterDistanceKernelType::CpuSimd_2xMM; #else - GMX_RELEASE_ASSERT(false, "Expect 8-wide or 16-wide SIMD with 4x4 list and nbat SIMD layout"); + GMX_RELEASE_ASSERT(false, + "Expect 8-wide or 16-wide SIMD with 4x4 list and nbat SIMD layout"); #endif } diff --git a/src/gromacs/nbnxm/constants.h b/src/gromacs/nbnxm/constants.h index cb547c525a..f38f1b1681 100644 --- a/src/gromacs/nbnxm/constants.h +++ b/src/gromacs/nbnxm/constants.h @@ -43,20 +43,20 @@ // Some double precision SIMD architectures use single precision in the first // step, so although the double precision criterion would allow smaller rsq, // we need to stay in single precision with some margin for the N-R iterations. -#define NBNXN_MIN_RSQ 1.0e-36 +# define NBNXN_MIN_RSQ 1.0e-36 #else // The worst intermediate value we might evaluate is r^-12, which // means we should ensure r^2 stays above pow(GMX_FLOAT_MAX,-1.0/6.0)*1.01 (some margin) -#define NBNXN_MIN_RSQ 3.82e-07f // r > 6.2e-4 +# define NBNXN_MIN_RSQ 3.82e-07f // r > 6.2e-4 #endif /* The number of clusters in a super-cluster, used for GPU */ -#define c_nbnxnGpuNumClusterPerSupercluster 8 +#define c_nbnxnGpuNumClusterPerSupercluster 8 /* With GPU kernels we group cluster pairs in 4 to optimize memory usage * of integers containing 32 bits. */ -#define c_nbnxnGpuJgroupSize (32/c_nbnxnGpuNumClusterPerSupercluster) +#define c_nbnxnGpuJgroupSize (32 / c_nbnxnGpuNumClusterPerSupercluster) #endif diff --git a/src/gromacs/nbnxm/cuda/nbnxm_buffer_ops_kernels.cuh b/src/gromacs/nbnxm/cuda/nbnxm_buffer_ops_kernels.cuh index 3c8f7b1cb3..6d3c393626 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_buffer_ops_kernels.cuh +++ b/src/gromacs/nbnxm/cuda/nbnxm_buffer_ops_kernels.cuh @@ -62,26 +62,26 @@ * \param[in] cellOffset first cell * \param[in] numAtomsPerCell number of atoms per cell */ -__global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColumns, - float * __restrict__ xnb, - bool setFillerCoords, - const rvec * __restrict__ x, - const int * __restrict__ a, - const int * __restrict__ cxy_na, - const int * __restrict__ cxy_ind, - int cellOffset, - int numAtomsPerCell); - - -__global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColumns, - float * __restrict__ xnb, - bool setFillerCoords, - const rvec * __restrict__ x, - const int * __restrict__ a, - const int * __restrict__ cxy_na, - const int * __restrict__ cxy_ind, - int cellOffset, - int numAtomsPerCell) +__global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColumns, + float* __restrict__ xnb, + bool setFillerCoords, + const rvec* __restrict__ x, + const int* __restrict__ a, + const int* __restrict__ cxy_na, + const int* __restrict__ cxy_ind, + int cellOffset, + int numAtomsPerCell); + + +__global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColumns, + float* __restrict__ xnb, + bool setFillerCoords, + const rvec* __restrict__ x, + const int* __restrict__ a, + const int* __restrict__ cxy_na, + const int* __restrict__ cxy_ind, + int cellOffset, + int numAtomsPerCell) { @@ -94,13 +94,12 @@ __global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColu { int na = cxy_na[cxy]; - int a0 = (cellOffset + cxy_ind[cxy])*numAtomsPerCell; + int a0 = (cellOffset + cxy_ind[cxy]) * numAtomsPerCell; int na_round; if (setFillerCoords) { // TODO: This can be done more efficiently - na_round = - (cxy_ind[cxy+1] - cxy_ind[cxy])*numAtomsPerCell; + na_round = (cxy_ind[cxy + 1] - cxy_ind[cxy]) * numAtomsPerCell; } else { @@ -114,19 +113,19 @@ __global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColu /* map parallelism within a cell to x component of CUDA block index linearized * with threads within a block */ int i, j0; - i = blockIdx.x*blockDim.x+threadIdx.x; + i = blockIdx.x * blockDim.x + threadIdx.x; - j0 = a0*STRIDE_XYZQ; + j0 = a0 * STRIDE_XYZQ; // destination address where x shoud be stored in nbnxm layout - float3 *x_dest = (float3 *)&xnb[j0 + 4*i]; + float3* x_dest = (float3*)&xnb[j0 + 4 * i]; /* perform conversion of each element */ if (i < na_round) { if (i < na) { - *x_dest = *((float3 *)x[a[a0 + i]]); + *x_dest = *((float3*)x[a[a0 + i]]); } else { @@ -134,7 +133,6 @@ __global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColu } } } - } /*! \brief CUDA kernel to sum up the force components @@ -149,38 +147,36 @@ __global__ void nbnxn_gpu_x_to_nbat_x_kernel(int numColu * \param[in] atomStart Start atom index. * \param[in] numAtoms Number of atoms. */ -template -__global__ void -nbnxn_gpu_add_nbat_f_to_f_kernel(const float3 *__restrict__ d_fNB, - const float3 *__restrict__ d_fPme, - float3 *d_fTotal, - const int *__restrict__ d_cell, - const int atomStart, - const int numAtoms); -template -__global__ void -nbnxn_gpu_add_nbat_f_to_f_kernel(const float3 *__restrict__ d_fNB, - const float3 *__restrict__ d_fPme, - float3 *d_fTotal, - const int *__restrict__ d_cell, - const int atomStart, - const int numAtoms) +template +__global__ void nbnxn_gpu_add_nbat_f_to_f_kernel(const float3* __restrict__ d_fNB, + const float3* __restrict__ d_fPme, + float3* d_fTotal, + const int* __restrict__ d_cell, + const int atomStart, + const int numAtoms); +template +__global__ void nbnxn_gpu_add_nbat_f_to_f_kernel(const float3* __restrict__ d_fNB, + const float3* __restrict__ d_fPme, + float3* d_fTotal, + const int* __restrict__ d_cell, + const int atomStart, + const int numAtoms) { /* map particle-level parallelism to 1D CUDA thread and block index */ - int threadIndex = blockIdx.x*blockDim.x+threadIdx.x; + int threadIndex = blockIdx.x * blockDim.x + threadIdx.x; /* perform addition for each particle*/ if (threadIndex < numAtoms) { - int i = d_cell[atomStart+threadIndex]; - float3 *fDest = (float3 *)&d_fTotal[atomStart+threadIndex]; + int i = d_cell[atomStart + threadIndex]; + float3* fDest = (float3*)&d_fTotal[atomStart + threadIndex]; float3 temp; if (accumulateForce) { - temp = *fDest; + temp = *fDest; temp += d_fNB[i]; } else @@ -189,10 +185,9 @@ nbnxn_gpu_add_nbat_f_to_f_kernel(const float3 *__restrict__ d_fNB, } if (addPmeForce) { - temp += d_fPme[atomStart+threadIndex]; + temp += d_fPme[atomStart + threadIndex]; } *fDest = temp; - } return; } diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda.cu b/src/gromacs/nbnxm/cuda/nbnxm_cuda.cu index 8ded53f7d1..c59a4a8285 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda.cu +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda.cu @@ -47,7 +47,7 @@ #include "gromacs/nbnxm/nbnxm_gpu.h" #if defined(_MSVC) -#include +# include #endif @@ -104,30 +104,27 @@ /* Now generate the function definitions if we are using a single compilation unit. */ #if GMX_CUDA_NB_SINGLE_COMPILATION_UNIT -#include "nbnxm_cuda_kernel_F_noprune.cu" -#include "nbnxm_cuda_kernel_F_prune.cu" -#include "nbnxm_cuda_kernel_VF_noprune.cu" -#include "nbnxm_cuda_kernel_VF_prune.cu" -#include "nbnxm_cuda_kernel_pruneonly.cu" +# include "nbnxm_cuda_kernel_F_noprune.cu" +# include "nbnxm_cuda_kernel_F_prune.cu" +# include "nbnxm_cuda_kernel_VF_noprune.cu" +# include "nbnxm_cuda_kernel_VF_prune.cu" +# include "nbnxm_cuda_kernel_pruneonly.cu" #endif /* GMX_CUDA_NB_SINGLE_COMPILATION_UNIT */ namespace Nbnxm { //! Number of CUDA threads in a block -//TODO Optimize this through experimentation +// TODO Optimize this through experimentation constexpr static int c_bufOpsThreadsPerBlock = 128; /*! Nonbonded kernel function pointer type */ -typedef void (*nbnxn_cu_kfunc_ptr_t)(const cu_atomdata_t, - const cu_nbparam_t, - const cu_plist_t, - bool); +typedef void (*nbnxn_cu_kfunc_ptr_t)(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, bool); /*********************************/ /*! Returns the number of blocks to be used for the nonbonded GPU kernel. */ -static inline int calc_nb_kernel_nblock(int nwork_units, const gmx_device_info_t *dinfo) +static inline int calc_nb_kernel_nblock(int nwork_units, const gmx_device_info_t* dinfo) { int max_grid_x_size; @@ -141,9 +138,11 @@ static inline int calc_nb_kernel_nblock(int nwork_units, const gmx_device_info_t /* do we exceed the grid x dimension limit? */ if (nwork_units > max_grid_x_size) { - gmx_fatal(FARGS, "Watch out, the input system is too large to simulate!\n" + gmx_fatal(FARGS, + "Watch out, the input system is too large to simulate!\n" "The number of nonbonded work units (=number of super-clusters) exceeds the" - "maximum grid size in x dimension (%d > %d)!", nwork_units, max_grid_x_size); + "maximum grid size in x dimension (%d > %d)!", + nwork_units, max_grid_x_size); } return nwork_units; @@ -162,55 +161,129 @@ static inline int calc_nb_kernel_nblock(int nwork_units, const gmx_device_info_t */ /*! Force-only kernel function pointers. */ -static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_noprune_ptr[eelCuNR][evdwCuNR] = -{ - { nbnxn_kernel_ElecCut_VdwLJ_F_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_cuda, nbnxn_kernel_ElecCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_cuda }, - { nbnxn_kernel_ElecRF_VdwLJ_F_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecRF_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_cuda, nbnxn_kernel_ElecRF_VdwLJPsw_F_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_cuda }, - { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_cuda }, - { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_cuda }, - { nbnxn_kernel_ElecEw_VdwLJ_F_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecEw_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_cuda, nbnxn_kernel_ElecEw_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_cuda }, - { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_cuda } +static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_noprune_ptr[eelCuNR][evdwCuNR] = { + { nbnxn_kernel_ElecCut_VdwLJ_F_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_cuda }, + { nbnxn_kernel_ElecRF_VdwLJ_F_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecRF_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecRF_VdwLJPsw_F_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_cuda }, + { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_cuda }, + { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_cuda }, + { nbnxn_kernel_ElecEw_VdwLJ_F_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecEw_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecEw_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_cuda }, + { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_cuda } }; /*! Force + energy kernel function pointers. */ -static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_noprune_ptr[eelCuNR][evdwCuNR] = -{ - { nbnxn_kernel_ElecCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_cuda }, - { nbnxn_kernel_ElecRF_VdwLJ_VF_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecRF_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecRF_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_cuda }, - { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_cuda }, - { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_cuda }, - { nbnxn_kernel_ElecEw_VdwLJ_VF_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecEw_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecEw_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_cuda }, - { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_cuda } +static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_noprune_ptr[eelCuNR][evdwCuNR] = { + { nbnxn_kernel_ElecCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_cuda }, + { nbnxn_kernel_ElecRF_VdwLJ_VF_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecRF_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecRF_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_cuda }, + { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_cuda }, + { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_cuda }, + { nbnxn_kernel_ElecEw_VdwLJ_VF_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecEw_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecEw_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_cuda }, + { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_cuda } }; /*! Force + pruning kernel function pointers. */ -static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_prune_ptr[eelCuNR][evdwCuNR] = -{ - { nbnxn_kernel_ElecCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_cuda }, - { nbnxn_kernel_ElecRF_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_cuda }, - { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_prune_cuda }, - { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_cuda }, - { nbnxn_kernel_ElecEw_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_cuda }, - { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_prune_cuda } +static const nbnxn_cu_kfunc_ptr_t nb_kfunc_noener_prune_ptr[eelCuNR][evdwCuNR] = { + { nbnxn_kernel_ElecCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_cuda }, + { nbnxn_kernel_ElecRF_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_cuda }, + { nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_prune_cuda }, + { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_cuda }, + { nbnxn_kernel_ElecEw_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_cuda }, + { nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_prune_cuda } }; /*! Force + energy + pruning kernel function pointers. */ -static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_prune_ptr[eelCuNR][evdwCuNR] = -{ - { nbnxn_kernel_ElecCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_prune_cuda }, - { nbnxn_kernel_ElecRF_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_cuda }, - { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_prune_cuda }, - { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_prune_cuda }, - { nbnxn_kernel_ElecEw_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_cuda }, - { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_prune_cuda } +static const nbnxn_cu_kfunc_ptr_t nb_kfunc_ener_prune_ptr[eelCuNR][evdwCuNR] = { + { nbnxn_kernel_ElecCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_prune_cuda }, + { nbnxn_kernel_ElecRF_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_cuda }, + { nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_prune_cuda }, + { nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_prune_cuda }, + { nbnxn_kernel_ElecEw_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_cuda, nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_cuda }, + { nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_cuda, nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_prune_cuda, + nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_prune_cuda } }; /*! Return a pointer to the kernel version to be executed at the current step. */ -static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(int eeltype, - int evdwtype, - bool bDoEne, - bool bDoPrune, - const gmx_device_info_t gmx_unused *devInfo) +static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(int eeltype, + int evdwtype, + bool bDoEne, + bool bDoPrune, + const gmx_device_info_t gmx_unused* devInfo) { nbnxn_cu_kfunc_ptr_t res; @@ -220,8 +293,11 @@ static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(int "The VdW type requested is not implemented in the CUDA kernels."); /* assert assumptions made by the kernels */ - GMX_ASSERT(c_nbnxnGpuClusterSize*c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit == devInfo->prop.warpSize, - "The CUDA kernels require the cluster_size_i*cluster_size_j/nbnxn_gpu_clusterpair_split to match the warp size of the architecture targeted."); + GMX_ASSERT(c_nbnxnGpuClusterSize * c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit + == devInfo->prop.warpSize, + "The CUDA kernels require the " + "cluster_size_i*cluster_size_j/nbnxn_gpu_clusterpair_split to match the warp size " + "of the architecture targeted."); if (bDoEne) { @@ -250,7 +326,9 @@ static inline nbnxn_cu_kfunc_ptr_t select_nbnxn_kernel(int } /*! \brief Calculates the amount of shared memory required by the nonbonded kernel in use. */ -static inline int calc_shmem_required_nonbonded(const int num_threads_z, const gmx_device_info_t gmx_unused *dinfo, const cu_nbparam_t *nbp) +static inline int calc_shmem_required_nonbonded(const int num_threads_z, + const gmx_device_info_t gmx_unused* dinfo, + const cu_nbparam_t* nbp) { int shmem; @@ -259,12 +337,11 @@ static inline int calc_shmem_required_nonbonded(const int num_threads_z, const g /* size of shmem (force-buffers/xq/atom type preloading) */ /* NOTE: with the default kernel on sm3.0 we need shmem only for pre-loading */ /* i-atom x+q in shared memory */ - shmem = c_numClPerSupercl * c_clSize * sizeof(float4); + shmem = c_numClPerSupercl * c_clSize * sizeof(float4); /* cj in shared memory, for each warp separately */ shmem += num_threads_z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(int); - if (nbp->vdwtype == evdwCuCUTCOMBGEOM || - nbp->vdwtype == evdwCuCUTCOMBLB) + if (nbp->vdwtype == evdwCuCUTCOMBGEOM || nbp->vdwtype == evdwCuCUTCOMBLB) { /* i-atom LJ combination parameters in shared memory */ shmem += c_numClPerSupercl * c_clSize * sizeof(float2); @@ -285,10 +362,9 @@ static inline int calc_shmem_required_nonbonded(const int num_threads_z, const g * the local, this function records the event if called with the local stream as * argument and inserts in the GPU stream a wait on the event on the nonlocal. */ -void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_cuda_t *nb, - const InteractionLocality interactionLocality) +void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_cuda_t* nb, const InteractionLocality interactionLocality) { - cudaStream_t stream = nb->stream[interactionLocality]; + cudaStream_t stream = nb->stream[interactionLocality]; /* When we get here all misc operations issued in the local stream as well as the local xq H2D are done, @@ -312,9 +388,7 @@ void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_cuda_t *nb, } /*! \brief Launch asynchronously the xq buffer host to device copy. */ -void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t *nb, - const nbnxn_atomdata_t *nbatom, - const AtomLocality atomLocality) +void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t* nb, const nbnxn_atomdata_t* nbatom, const AtomLocality atomLocality) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); @@ -323,14 +397,14 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t *nb, const InteractionLocality iloc = gpuAtomToInteractionLocality(atomLocality); - int adat_begin, adat_len; /* local/nonlocal offset and length used for xq and f */ + int adat_begin, adat_len; /* local/nonlocal offset and length used for xq and f */ - cu_atomdata_t *adat = nb->atdat; - cu_plist_t *plist = nb->plist[iloc]; - cu_timers_t *t = nb->timers; - cudaStream_t stream = nb->stream[iloc]; + cu_atomdata_t* adat = nb->atdat; + cu_plist_t* plist = nb->plist[iloc]; + cu_timers_t* t = nb->timers; + cudaStream_t stream = nb->stream[iloc]; - bool bDoTime = nb->bDoTime; + bool bDoTime = nb->bDoTime; /* Don't launch the non-local H2D copy if there is no dependent work to do: neither non-local nor other (e.g. bonded) work @@ -351,13 +425,13 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t *nb, /* calculate the atom data index range based on locality */ if (atomLocality == AtomLocality::Local) { - adat_begin = 0; - adat_len = adat->natoms_local; + adat_begin = 0; + adat_len = adat->natoms_local; } else { - adat_begin = adat->natoms_local; - adat_len = adat->natoms - adat->natoms_local; + adat_begin = adat->natoms_local; + adat_len = adat->natoms - adat->natoms_local; } /* HtoD x, q */ @@ -367,7 +441,8 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t *nb, t->xf[atomLocality].nb_h2d.openTimingRegion(stream); } - cu_copy_H2D_async(adat->xq + adat_begin, static_cast(nbatom->x().data() + adat_begin * 4), + cu_copy_H2D_async(adat->xq + adat_begin, + static_cast(nbatom->x().data() + adat_begin * 4), adat_len * sizeof(*adat->xq), stream); if (bDoTime) @@ -401,17 +476,15 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_cuda_t *nb, the local x+q H2D (and all preceding) tasks are complete and synchronize with this event in the non-local stream before launching the non-bonded kernel. */ -void gpu_launch_kernel(gmx_nbnxn_cuda_t *nb, - const gmx::StepWorkload &stepWork, - const InteractionLocality iloc) +void gpu_launch_kernel(gmx_nbnxn_cuda_t* nb, const gmx::StepWorkload& stepWork, const InteractionLocality iloc) { - cu_atomdata_t *adat = nb->atdat; - cu_nbparam_t *nbp = nb->nbparam; - cu_plist_t *plist = nb->plist[iloc]; - cu_timers_t *t = nb->timers; - cudaStream_t stream = nb->stream[iloc]; + cu_atomdata_t* adat = nb->atdat; + cu_nbparam_t* nbp = nb->nbparam; + cu_plist_t* plist = nb->plist[iloc]; + cu_timers_t* t = nb->timers; + cudaStream_t stream = nb->stream[iloc]; - bool bDoTime = nb->bDoTime; + bool bDoTime = nb->bDoTime; /* Don't launch the non-local kernel if there is no work to do. Doing the same for the local kernel is more complicated, since the @@ -460,7 +533,7 @@ void gpu_launch_kernel(gmx_nbnxn_cuda_t *nb, { num_threads_z = 2; } - int nblock = calc_nb_kernel_nblock(plist->nsci, nb->dev_info); + int nblock = calc_nb_kernel_nblock(plist->nsci, nb->dev_info); KernelLaunchConfig config; @@ -473,22 +546,21 @@ void gpu_launch_kernel(gmx_nbnxn_cuda_t *nb, if (debug) { - fprintf(debug, "Non-bonded GPU launch configuration:\n\tThread block: %zux%zux%zu\n\t" + fprintf(debug, + "Non-bonded GPU launch configuration:\n\tThread block: %zux%zux%zu\n\t" "\tGrid: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n" "\tShMem: %zu\n", - config.blockSize[0], config.blockSize[1], config.blockSize[2], - config.gridSize[0], config.gridSize[1], plist->nsci*c_numClPerSupercl, - c_numClPerSupercl, plist->na_c, + config.blockSize[0], config.blockSize[1], config.blockSize[2], config.gridSize[0], + config.gridSize[1], plist->nsci * c_numClPerSupercl, c_numClPerSupercl, plist->na_c, config.sharedMemorySize); } - auto *timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr; - const auto kernel = select_nbnxn_kernel(nbp->eeltype, - nbp->vdwtype, - stepWork.computeEnergy, - (plist->haveFreshList && !nb->timers->interaction[iloc].didPrune), - nb->dev_info); - const auto kernelArgs = prepareGpuKernelArguments(kernel, config, adat, nbp, plist, &stepWork.computeVirial); + auto* timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr; + const auto kernel = select_nbnxn_kernel( + nbp->eeltype, nbp->vdwtype, stepWork.computeEnergy, + (plist->haveFreshList && !nb->timers->interaction[iloc].didPrune), nb->dev_info); + const auto kernelArgs = + prepareGpuKernelArguments(kernel, config, adat, nbp, plist, &stepWork.computeVirial); launchGpuKernel(kernel, config, timingEvent, "k_calc_nb", kernelArgs); if (bDoTime) @@ -509,24 +581,22 @@ static inline int calc_shmem_required_prune(const int num_threads_z) int shmem; /* i-atom x in shared memory */ - shmem = c_numClPerSupercl * c_clSize * sizeof(float4); + shmem = c_numClPerSupercl * c_clSize * sizeof(float4); /* cj in shared memory, for each warp separately */ shmem += num_threads_z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(int); return shmem; } -void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, - const InteractionLocality iloc, - const int numParts) +void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t* nb, const InteractionLocality iloc, const int numParts) { - cu_atomdata_t *adat = nb->atdat; - cu_nbparam_t *nbp = nb->nbparam; - cu_plist_t *plist = nb->plist[iloc]; - cu_timers_t *t = nb->timers; - cudaStream_t stream = nb->stream[iloc]; + cu_atomdata_t* adat = nb->atdat; + cu_nbparam_t* nbp = nb->nbparam; + cu_plist_t* plist = nb->plist[iloc]; + cu_timers_t* t = nb->timers; + cudaStream_t stream = nb->stream[iloc]; - bool bDoTime = nb->bDoTime; + bool bDoTime = nb->bDoTime; if (plist->haveFreshList) { @@ -544,7 +614,8 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, } else { - GMX_ASSERT(numParts == plist->rollingPruningNumParts, "It is not allowed to change numParts in between list generation steps"); + GMX_ASSERT(numParts == plist->rollingPruningNumParts, + "It is not allowed to change numParts in between list generation steps"); } } @@ -560,7 +631,7 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, } /* Compute the number of list entries to prune in this pass */ - int numSciInPart = (plist->nsci - part)/numParts; + int numSciInPart = (plist->nsci - part) / numParts; /* Don't launch the kernel if there is no work to do (not allowed with CUDA) */ if (numSciInPart <= 0) @@ -570,7 +641,7 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, return; } - GpuRegionTimer *timer = nullptr; + GpuRegionTimer* timer = nullptr; if (bDoTime) { timer = &(plist->haveFreshList ? t->interaction[iloc].prune_k : t->interaction[iloc].rollingPrune_k); @@ -587,8 +658,8 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, * and j-cluster concurrency, in x, y, and z, respectively. * - The 1D block-grid contains as many blocks as super-clusters. */ - int num_threads_z = c_cudaPruneKernelJ4Concurrency; - int nblock = calc_nb_kernel_nblock(numSciInPart, nb->dev_info); + int num_threads_z = c_cudaPruneKernelJ4Concurrency; + int nblock = calc_nb_kernel_nblock(numSciInPart, nb->dev_info); KernelLaunchConfig config; config.blockSize[0] = c_clSize; config.blockSize[1] = c_clSize; @@ -599,26 +670,27 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, if (debug) { - fprintf(debug, "Pruning GPU kernel launch configuration:\n\tThread block: %zux%zux%zu\n\t" + fprintf(debug, + "Pruning GPU kernel launch configuration:\n\tThread block: %zux%zux%zu\n\t" "\tGrid: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n" "\tShMem: %zu\n", - config.blockSize[0], config.blockSize[1], config.blockSize[2], - config.gridSize[0], config.gridSize[1], numSciInPart*c_numClPerSupercl, - c_numClPerSupercl, plist->na_c, - config.sharedMemorySize); + config.blockSize[0], config.blockSize[1], config.blockSize[2], config.gridSize[0], + config.gridSize[1], numSciInPart * c_numClPerSupercl, c_numClPerSupercl, + plist->na_c, config.sharedMemorySize); } - auto *timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr; + auto* timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr; constexpr char kernelName[] = "k_pruneonly"; - const auto kernel = plist->haveFreshList ? nbnxn_kernel_prune_cuda : nbnxn_kernel_prune_cuda; - const auto kernelArgs = prepareGpuKernelArguments(kernel, config, adat, nbp, plist, &numParts, &part); + const auto kernel = + plist->haveFreshList ? nbnxn_kernel_prune_cuda : nbnxn_kernel_prune_cuda; + const auto kernelArgs = prepareGpuKernelArguments(kernel, config, adat, nbp, plist, &numParts, &part); launchGpuKernel(kernel, config, timingEvent, kernelName, kernelArgs); /* TODO: consider a more elegant way to track which kernel has been called (combined or separate 1st pass prune, rolling prune). */ if (plist->haveFreshList) { - plist->haveFreshList = false; + plist->haveFreshList = false; /* Mark that pruning has been done */ nb->timers->interaction[iloc].didPrune = true; } @@ -640,9 +712,9 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_cuda_t *nb, } } -void gpu_launch_cpyback(gmx_nbnxn_cuda_t *nb, - nbnxn_atomdata_t *nbatom, - const gmx::StepWorkload &stepWork, +void gpu_launch_cpyback(gmx_nbnxn_cuda_t* nb, + nbnxn_atomdata_t* nbatom, + const gmx::StepWorkload& stepWork, const AtomLocality atomLocality) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); @@ -654,10 +726,10 @@ void gpu_launch_cpyback(gmx_nbnxn_cuda_t *nb, const InteractionLocality iloc = gpuAtomToInteractionLocality(atomLocality); /* extract the data */ - cu_atomdata_t *adat = nb->atdat; - cu_timers_t *t = nb->timers; - bool bDoTime = nb->bDoTime; - cudaStream_t stream = nb->stream[iloc]; + cu_atomdata_t* adat = nb->atdat; + cu_timers_t* t = nb->timers; + bool bDoTime = nb->bDoTime; + cudaStream_t stream = nb->stream[iloc]; /* don't launch non-local copy-back if there was no non-local work to do */ if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(*nb, iloc)) @@ -687,7 +759,7 @@ void gpu_launch_cpyback(gmx_nbnxn_cuda_t *nb, if (!stepWork.useGpuFBufferOps) { cu_copy_D2H_async(nbatom->out[0].f.data() + adat_begin * 3, adat->f + adat_begin, - (adat_len)*sizeof(*adat->f), stream); + (adat_len) * sizeof(*adat->f), stream); } /* After the non-local D2H is launched the nonlocal_done event can be @@ -706,17 +778,14 @@ void gpu_launch_cpyback(gmx_nbnxn_cuda_t *nb, /* DtoH fshift when virial is needed */ if (stepWork.computeVirial) { - cu_copy_D2H_async(nb->nbst.fshift, adat->fshift, - SHIFTS * sizeof(*nb->nbst.fshift), stream); + cu_copy_D2H_async(nb->nbst.fshift, adat->fshift, SHIFTS * sizeof(*nb->nbst.fshift), stream); } /* DtoH energies */ if (stepWork.computeEnergy) { - cu_copy_D2H_async(nb->nbst.e_lj, adat->e_lj, - sizeof(*nb->nbst.e_lj), stream); - cu_copy_D2H_async(nb->nbst.e_el, adat->e_el, - sizeof(*nb->nbst.e_el), stream); + cu_copy_D2H_async(nb->nbst.e_lj, adat->e_lj, sizeof(*nb->nbst.e_lj), stream); + cu_copy_D2H_async(nb->nbst.e_el, adat->e_el, sizeof(*nb->nbst.e_el), stream); } } @@ -745,25 +814,25 @@ void cuda_set_cacheconfig() } /* X buffer operations on GPU: performs conversion from rvec to nb format. */ -void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid &grid, - bool setFillerCoords, - gmx_nbnxn_gpu_t *nb, - DeviceBuffer d_x, - GpuEventSynchronizer *xReadyOnDevice, - const Nbnxm::AtomLocality locality, - int gridId, - int numColumnsMax) +void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid& grid, + bool setFillerCoords, + gmx_nbnxn_gpu_t* nb, + DeviceBuffer d_x, + GpuEventSynchronizer* xReadyOnDevice, + const Nbnxm::AtomLocality locality, + int gridId, + int numColumnsMax) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); - cu_atomdata_t *adat = nb->atdat; + cu_atomdata_t* adat = nb->atdat; - const int numColumns = grid.numColumns(); - const int cellOffset = grid.cellOffset(); - const int numAtomsPerCell = grid.numAtomsPerCell(); - Nbnxm::InteractionLocality interactionLoc = gpuAtomToInteractionLocality(locality); + const int numColumns = grid.numColumns(); + const int cellOffset = grid.cellOffset(); + const int numAtomsPerCell = grid.numAtomsPerCell(); + Nbnxm::InteractionLocality interactionLoc = gpuAtomToInteractionLocality(locality); - cudaStream_t stream = nb->stream[interactionLoc]; + cudaStream_t stream = nb->stream[interactionLoc]; int numAtoms = grid.srcAtomEnd() - grid.srcAtomBegin(); // avoid empty kernel launch, skip to inserting stream dependency @@ -777,31 +846,26 @@ void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid &grid, xReadyOnDevice->enqueueWaitEvent(stream); KernelLaunchConfig config; - config.blockSize[0] = c_bufOpsThreadsPerBlock; - config.blockSize[1] = 1; - config.blockSize[2] = 1; - config.gridSize[0] = (grid.numCellsColumnMax()*numAtomsPerCell + c_bufOpsThreadsPerBlock - 1)/c_bufOpsThreadsPerBlock; - config.gridSize[1] = numColumns; - config.gridSize[2] = 1; - GMX_ASSERT(config.gridSize[0] > 0, "Can not have empty grid, early return above avoids this"); + config.blockSize[0] = c_bufOpsThreadsPerBlock; + config.blockSize[1] = 1; + config.blockSize[2] = 1; + config.gridSize[0] = (grid.numCellsColumnMax() * numAtomsPerCell + c_bufOpsThreadsPerBlock - 1) + / c_bufOpsThreadsPerBlock; + config.gridSize[1] = numColumns; + config.gridSize[2] = 1; + GMX_ASSERT(config.gridSize[0] > 0, + "Can not have empty grid, early return above avoids this"); config.sharedMemorySize = 0; config.stream = stream; - auto kernelFn = nbnxn_gpu_x_to_nbat_x_kernel; - float *xqPtr = &(adat->xq->x); - const int *d_atomIndices = nb->atomIndices; - const int *d_cxy_na = &nb->cxy_na[numColumnsMax*gridId]; - const int *d_cxy_ind = &nb->cxy_ind[numColumnsMax*gridId]; - const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, - &numColumns, - &xqPtr, - &setFillerCoords, - &d_x, - &d_atomIndices, - &d_cxy_na, - &d_cxy_ind, - &cellOffset, - &numAtomsPerCell); + auto kernelFn = nbnxn_gpu_x_to_nbat_x_kernel; + float* xqPtr = &(adat->xq->x); + const int* d_atomIndices = nb->atomIndices; + const int* d_cxy_na = &nb->cxy_na[numColumnsMax * gridId]; + const int* d_cxy_ind = &nb->cxy_ind[numColumnsMax * gridId]; + const auto kernelArgs = prepareGpuKernelArguments( + kernelFn, config, &numColumns, &xqPtr, &setFillerCoords, &d_x, &d_atomIndices, + &d_cxy_na, &d_cxy_ind, &cellOffset, &numAtomsPerCell); launchGpuKernel(kernelFn, config, nullptr, "XbufferOps", kernelArgs); } @@ -812,28 +876,28 @@ void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid &grid, } /* F buffer operations on GPU: performs force summations and conversion from nb to rvec format. */ -void nbnxn_gpu_add_nbat_f_to_f(const AtomLocality atomLocality, - DeviceBuffer totalForcesDevice, - gmx_nbnxn_gpu_t *nb, - void *pmeForcesDevice, - gmx::ArrayRef dependencyList, - int atomStart, - int numAtoms, - bool useGpuFPmeReduction, - bool accumulateForce) +void nbnxn_gpu_add_nbat_f_to_f(const AtomLocality atomLocality, + DeviceBuffer totalForcesDevice, + gmx_nbnxn_gpu_t* nb, + void* pmeForcesDevice, + gmx::ArrayRef dependencyList, + int atomStart, + int numAtoms, + bool useGpuFPmeReduction, + bool accumulateForce) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); GMX_ASSERT(numAtoms != 0, "Cannot call function with no atoms"); GMX_ASSERT(totalForcesDevice, "Need a valid totalForcesDevice pointer"); - const InteractionLocality iLocality = gpuAtomToInteractionLocality(atomLocality); - cudaStream_t stream = nb->stream[iLocality]; - cu_atomdata_t *adat = nb->atdat; + const InteractionLocality iLocality = gpuAtomToInteractionLocality(atomLocality); + cudaStream_t stream = nb->stream[iLocality]; + cu_atomdata_t* adat = nb->atdat; - size_t gmx_used_in_debug numDependency = - static_cast((useGpuFPmeReduction == true)) + - static_cast((accumulateForce == true)); - GMX_ASSERT(numDependency >= dependencyList.size(), "Mismatching number of dependencies and call signature"); + size_t gmx_used_in_debug numDependency = static_cast((useGpuFPmeReduction == true)) + + static_cast((accumulateForce == true)); + GMX_ASSERT(numDependency >= dependencyList.size(), + "Mismatching number of dependencies and call signature"); // Enqueue wait on all dependencies passed for (auto const synchronizer : dependencyList) @@ -844,58 +908,52 @@ void nbnxn_gpu_add_nbat_f_to_f(const AtomLocality atomL /* launch kernel */ KernelLaunchConfig config; - config.blockSize[0] = c_bufOpsThreadsPerBlock; - config.blockSize[1] = 1; - config.blockSize[2] = 1; - config.gridSize[0] = ((numAtoms+1)+c_bufOpsThreadsPerBlock-1)/c_bufOpsThreadsPerBlock; - config.gridSize[1] = 1; - config.gridSize[2] = 1; + config.blockSize[0] = c_bufOpsThreadsPerBlock; + config.blockSize[1] = 1; + config.blockSize[2] = 1; + config.gridSize[0] = ((numAtoms + 1) + c_bufOpsThreadsPerBlock - 1) / c_bufOpsThreadsPerBlock; + config.gridSize[1] = 1; + config.gridSize[2] = 1; config.sharedMemorySize = 0; config.stream = stream; - auto kernelFn = accumulateForce ? - nbnxn_gpu_add_nbat_f_to_f_kernel : - nbnxn_gpu_add_nbat_f_to_f_kernel; + auto kernelFn = accumulateForce ? nbnxn_gpu_add_nbat_f_to_f_kernel + : nbnxn_gpu_add_nbat_f_to_f_kernel; if (useGpuFPmeReduction) { GMX_ASSERT(pmeForcesDevice, "Need a valid pmeForcesDevice pointer"); - kernelFn = accumulateForce ? - nbnxn_gpu_add_nbat_f_to_f_kernel : - nbnxn_gpu_add_nbat_f_to_f_kernel; + kernelFn = accumulateForce ? nbnxn_gpu_add_nbat_f_to_f_kernel + : nbnxn_gpu_add_nbat_f_to_f_kernel; } - const float3 *d_fNB = adat->f; - const float3 *d_fPme = (float3*) pmeForcesDevice; - float3 *d_fTotal = (float3*) totalForcesDevice; - const int *d_cell = nb->cell; + const float3* d_fNB = adat->f; + const float3* d_fPme = (float3*)pmeForcesDevice; + float3* d_fTotal = (float3*)totalForcesDevice; + const int* d_cell = nb->cell; - const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, - &d_fNB, - &d_fPme, - &d_fTotal, - &d_cell, - &atomStart, - &numAtoms); + const auto kernelArgs = prepareGpuKernelArguments(kernelFn, config, &d_fNB, &d_fPme, &d_fTotal, + &d_cell, &atomStart, &numAtoms); launchGpuKernel(kernelFn, config, nullptr, "FbufferOps", kernelArgs); if (atomLocality == AtomLocality::Local) { - GMX_ASSERT(nb->localFReductionDone != nullptr, "localFReductionDone has to be a valid pointer"); + GMX_ASSERT(nb->localFReductionDone != nullptr, + "localFReductionDone has to be a valid pointer"); nb->localFReductionDone->markEvent(stream); } } -void nbnxn_wait_nonlocal_x_copy_D2H_done(gmx_nbnxn_cuda_t *nb) +void nbnxn_wait_nonlocal_x_copy_D2H_done(gmx_nbnxn_cuda_t* nb) { nb->xNonLocalCopyD2HDone->waitForEvent(); } -void nbnxn_stream_local_wait_for_nonlocal(gmx_nbnxn_cuda_t *nb) +void nbnxn_stream_local_wait_for_nonlocal(gmx_nbnxn_cuda_t* nb) { - cudaStream_t localStream = nb->stream[InteractionLocality::Local]; - cudaStream_t nonLocalStream = nb->stream[InteractionLocality::NonLocal]; + cudaStream_t localStream = nb->stream[InteractionLocality::Local]; + cudaStream_t nonLocalStream = nb->stream[InteractionLocality::NonLocal]; GpuEventSynchronizer event; event.markEvent(nonLocalStream); diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu b/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu index e082725134..d5d0474bbe 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu @@ -88,20 +88,19 @@ namespace Nbnxm static unsigned int gpu_min_ci_balanced_factor = 44; /* Fw. decl. */ -static void nbnxn_cuda_clear_e_fshift(gmx_nbnxn_cuda_t *nb); +static void nbnxn_cuda_clear_e_fshift(gmx_nbnxn_cuda_t* nb); /* Fw. decl, */ -static void nbnxn_cuda_free_nbparam_table(cu_nbparam_t *nbparam); +static void nbnxn_cuda_free_nbparam_table(cu_nbparam_t* nbparam); /*! \brief Return whether combination rules are used. * * \param[in] pointer to nonbonded paramter struct * \return true if combination rules are used in this run, false otherwise */ -static inline bool useLjCombRule(const cu_nbparam_t *nbparam) +static inline bool useLjCombRule(const cu_nbparam_t* nbparam) { - return (nbparam->vdwtype == evdwCuCUTCOMBGEOM || - nbparam->vdwtype == evdwCuCUTCOMBLB); + return (nbparam->vdwtype == evdwCuCUTCOMBGEOM || nbparam->vdwtype == evdwCuCUTCOMBLB); } /*! \brief Initialized the Ewald Coulomb correction GPU table. @@ -110,8 +109,7 @@ static inline bool useLjCombRule(const cu_nbparam_t *nbparam) and the table GPU array. If called with an already allocated table, it just re-uploads the table. */ -static void init_ewald_coulomb_force_table(const EwaldCorrectionTables &tables, - cu_nbparam_t *nbp) +static void init_ewald_coulomb_force_table(const EwaldCorrectionTables& tables, cu_nbparam_t* nbp) { if (nbp->coulomb_tab != nullptr) { @@ -119,23 +117,23 @@ static void init_ewald_coulomb_force_table(const EwaldCorrectionTables &tables, } nbp->coulomb_tab_scale = tables.scale; - initParamLookupTable(nbp->coulomb_tab, nbp->coulomb_tab_texobj, - tables.tableF.data(), tables.tableF.size()); + initParamLookupTable(nbp->coulomb_tab, nbp->coulomb_tab_texobj, tables.tableF.data(), + tables.tableF.size()); } /*! Initializes the atomdata structure first time, it only gets filled at pair-search. */ -static void init_atomdata_first(cu_atomdata_t *ad, int ntypes) +static void init_atomdata_first(cu_atomdata_t* ad, int ntypes) { cudaError_t stat; - ad->ntypes = ntypes; - stat = cudaMalloc((void**)&ad->shift_vec, SHIFTS*sizeof(*ad->shift_vec)); + ad->ntypes = ntypes; + stat = cudaMalloc((void**)&ad->shift_vec, SHIFTS * sizeof(*ad->shift_vec)); CU_RET_ERR(stat, "cudaMalloc failed on ad->shift_vec"); ad->bShiftVecUploaded = false; - stat = cudaMalloc((void**)&ad->fshift, SHIFTS*sizeof(*ad->fshift)); + stat = cudaMalloc((void**)&ad->fshift, SHIFTS * sizeof(*ad->fshift)); CU_RET_ERR(stat, "cudaMalloc failed on ad->fshift"); stat = cudaMalloc((void**)&ad->e_lj, sizeof(*ad->e_lj)); @@ -155,7 +153,7 @@ static void init_atomdata_first(cu_atomdata_t *ad, int ntypes) /*! Selects the Ewald kernel type, analytical on SM 3.0 and later, tabulated on earlier GPUs, single or twin cut-off. */ -static int pick_ewald_kernel_type(const interaction_const_t &ic) +static int pick_ewald_kernel_type(const interaction_const_t& ic) { bool bTwinCut = (ic.rcoulomb != ic.rvdw); bool bUseAnalyticalEwald, bForceAnalyticalEwald, bForceTabulatedEwald; @@ -168,8 +166,9 @@ static int pick_ewald_kernel_type(const interaction_const_t &ic) if (bForceAnalyticalEwald && bForceTabulatedEwald) { - gmx_incons("Both analytical and tabulated Ewald CUDA non-bonded kernels " - "requested through environment variables."); + gmx_incons( + "Both analytical and tabulated Ewald CUDA non-bonded kernels " + "requested through environment variables."); } /* By default use analytical Ewald. */ @@ -206,9 +205,7 @@ static int pick_ewald_kernel_type(const interaction_const_t &ic) } /*! Copies all parameters related to the cut-off from ic to nbp */ -static void set_cutoff_parameters(cu_nbparam_t *nbp, - const interaction_const_t *ic, - const PairlistParams &listParams) +static void set_cutoff_parameters(cu_nbparam_t* nbp, const interaction_const_t* ic, const PairlistParams& listParams) { nbp->ewald_beta = ic->ewaldcoeff_q; nbp->sh_ewald = ic->sh_ewald; @@ -221,24 +218,24 @@ static void set_cutoff_parameters(cu_nbparam_t *nbp, nbp->rlistInner_sq = listParams.rlistInner * listParams.rlistInner; nbp->useDynamicPruning = listParams.useDynamicPruning; - nbp->sh_lj_ewald = ic->sh_lj_ewald; - nbp->ewaldcoeff_lj = ic->ewaldcoeff_lj; + nbp->sh_lj_ewald = ic->sh_lj_ewald; + nbp->ewaldcoeff_lj = ic->ewaldcoeff_lj; - nbp->rvdw_switch = ic->rvdw_switch; - nbp->dispersion_shift = ic->dispersion_shift; - nbp->repulsion_shift = ic->repulsion_shift; - nbp->vdw_switch = ic->vdw_switch; + nbp->rvdw_switch = ic->rvdw_switch; + nbp->dispersion_shift = ic->dispersion_shift; + nbp->repulsion_shift = ic->repulsion_shift; + nbp->vdw_switch = ic->vdw_switch; } /*! Initializes the nonbonded parameter data structure. */ -static void init_nbparam(cu_nbparam_t *nbp, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t::Params &nbatParams) +static void init_nbparam(cu_nbparam_t* nbp, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t::Params& nbatParams) { - int ntypes; + int ntypes; - ntypes = nbatParams.numTypes; + ntypes = nbatParams.numTypes; set_cutoff_parameters(nbp, ic, listParams); @@ -259,27 +256,21 @@ static void init_nbparam(cu_nbparam_t *nbp, case eintmodPOTSHIFT: switch (nbatParams.comb_rule) { - case ljcrNONE: - nbp->vdwtype = evdwCuCUT; - break; - case ljcrGEOM: - nbp->vdwtype = evdwCuCUTCOMBGEOM; - break; - case ljcrLB: - nbp->vdwtype = evdwCuCUTCOMBLB; - break; + case ljcrNONE: nbp->vdwtype = evdwCuCUT; break; + case ljcrGEOM: nbp->vdwtype = evdwCuCUTCOMBGEOM; break; + case ljcrLB: nbp->vdwtype = evdwCuCUTCOMBLB; break; default: - gmx_incons("The requested LJ combination rule is not implemented in the CUDA GPU accelerated kernels!"); + gmx_incons( + "The requested LJ combination rule is not implemented in the CUDA " + "GPU accelerated kernels!"); } break; - case eintmodFORCESWITCH: - nbp->vdwtype = evdwCuFSWITCH; - break; - case eintmodPOTSWITCH: - nbp->vdwtype = evdwCuPSWITCH; - break; + case eintmodFORCESWITCH: nbp->vdwtype = evdwCuFSWITCH; break; + case eintmodPOTSWITCH: nbp->vdwtype = evdwCuPSWITCH; break; default: - gmx_incons("The requested VdW interaction modifier is not implemented in the CUDA GPU accelerated kernels!"); + gmx_incons( + "The requested VdW interaction modifier is not implemented in the CUDA GPU " + "accelerated kernels!"); } } else if (ic->vdwtype == evdwPME) @@ -297,7 +288,8 @@ static void init_nbparam(cu_nbparam_t *nbp, } else { - gmx_incons("The requested VdW type is not implemented in the CUDA GPU accelerated kernels!"); + gmx_incons( + "The requested VdW type is not implemented in the CUDA GPU accelerated kernels!"); } if (ic->eeltype == eelCUT) @@ -315,7 +307,9 @@ static void init_nbparam(cu_nbparam_t *nbp, else { /* Shouldn't happen, as this is checked when choosing Verlet-scheme */ - gmx_incons("The requested electrostatics type is not implemented in the CUDA GPU accelerated kernels!"); + gmx_incons( + "The requested electrostatics type is not implemented in the CUDA GPU accelerated " + "kernels!"); } /* generate table for PME */ @@ -329,62 +323,59 @@ static void init_nbparam(cu_nbparam_t *nbp, /* set up LJ parameter lookup table */ if (!useLjCombRule(nbp)) { - initParamLookupTable(nbp->nbfp, nbp->nbfp_texobj, - nbatParams.nbfp.data(), 2*ntypes*ntypes); + initParamLookupTable(nbp->nbfp, nbp->nbfp_texobj, nbatParams.nbfp.data(), 2 * ntypes * ntypes); } /* set up LJ-PME parameter lookup table */ if (ic->vdwtype == evdwPME) { - initParamLookupTable(nbp->nbfp_comb, nbp->nbfp_comb_texobj, - nbatParams.nbfp_comb.data(), 2*ntypes); + initParamLookupTable(nbp->nbfp_comb, nbp->nbfp_comb_texobj, nbatParams.nbfp_comb.data(), 2 * ntypes); } } /*! Re-generate the GPU Ewald force table, resets rlist, and update the * electrostatic type switching to twin cut-off (or back) if needed. */ -void gpu_pme_loadbal_update_param(const nonbonded_verlet_t *nbv, - const interaction_const_t *ic) +void gpu_pme_loadbal_update_param(const nonbonded_verlet_t* nbv, const interaction_const_t* ic) { if (!nbv || !nbv->useGpu()) { return; } - cu_nbparam_t *nbp = nbv->gpu_nbv->nbparam; + cu_nbparam_t* nbp = nbv->gpu_nbv->nbparam; set_cutoff_parameters(nbp, ic, nbv->pairlistSets().params()); - nbp->eeltype = pick_ewald_kernel_type(*ic); + nbp->eeltype = pick_ewald_kernel_type(*ic); GMX_RELEASE_ASSERT(ic->coulombEwaldTables, "Need valid Coulomb Ewald correction tables"); init_ewald_coulomb_force_table(*ic->coulombEwaldTables, nbp); } /*! Initializes the pair list data structure. */ -static void init_plist(cu_plist_t *pl) +static void init_plist(cu_plist_t* pl) { /* initialize to nullptr pointers to data that is not allocated here and will need reallocation in nbnxn_gpu_init_pairlist */ - pl->sci = nullptr; - pl->cj4 = nullptr; - pl->imask = nullptr; - pl->excl = nullptr; + pl->sci = nullptr; + pl->cj4 = nullptr; + pl->imask = nullptr; + pl->excl = nullptr; /* size -1 indicates that the respective array hasn't been initialized yet */ - pl->na_c = -1; - pl->nsci = -1; - pl->sci_nalloc = -1; - pl->ncj4 = -1; - pl->cj4_nalloc = -1; - pl->nimask = -1; - pl->imask_nalloc = -1; - pl->nexcl = -1; - pl->excl_nalloc = -1; - pl->haveFreshList = false; + pl->na_c = -1; + pl->nsci = -1; + pl->sci_nalloc = -1; + pl->ncj4 = -1; + pl->cj4_nalloc = -1; + pl->nimask = -1; + pl->imask_nalloc = -1; + pl->nexcl = -1; + pl->excl_nalloc = -1; + pl->haveFreshList = false; } /*! Initializes the timings data structure. */ -static void init_timings(gmx_wallclock_gpu_nbnxn_t *t) +static void init_timings(gmx_wallclock_gpu_nbnxn_t* t) { int i, j; @@ -408,10 +399,10 @@ static void init_timings(gmx_wallclock_gpu_nbnxn_t *t) } /*! Initializes simulation constant data. */ -static void cuda_init_const(gmx_nbnxn_cuda_t *nb, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t::Params &nbatParams) +static void cuda_init_const(gmx_nbnxn_cuda_t* nb, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t::Params& nbatParams) { init_atomdata_first(nb->atdat, nbatParams.numTypes); init_nbparam(nb->nbparam, ic, listParams, nbatParams); @@ -420,17 +411,16 @@ static void cuda_init_const(gmx_nbnxn_cuda_t *nb, nbnxn_cuda_clear_e_fshift(nb); } -gmx_nbnxn_cuda_t * -gpu_init(const gmx_device_info_t *deviceInfo, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t *nbat, - int /*rank*/, - gmx_bool bLocalAndNonlocal) +gmx_nbnxn_cuda_t* gpu_init(const gmx_device_info_t* deviceInfo, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t* nbat, + int /*rank*/, + gmx_bool bLocalAndNonlocal) { - cudaError_t stat; + cudaError_t stat; - gmx_nbnxn_cuda_t *nb; + gmx_nbnxn_cuda_t* nb; snew(nb, 1); snew(nb->atdat, 1); snew(nb->nbparam, 1); @@ -471,9 +461,9 @@ gpu_init(const gmx_device_info_t *deviceInfo, CU_RET_ERR(stat, "cudaDeviceGetStreamPriorityRange failed"); stat = cudaStreamCreateWithPriority(&nb->stream[InteractionLocality::NonLocal], - cudaStreamDefault, - highest_priority); - CU_RET_ERR(stat, "cudaStreamCreateWithPriority on stream[InteractionLocality::NonLocal] failed"); + cudaStreamDefault, highest_priority); + CU_RET_ERR(stat, + "cudaStreamCreateWithPriority on stream[InteractionLocality::NonLocal] failed"); } /* init events for sychronization (timing disabled for performance reasons!) */ @@ -501,14 +491,14 @@ gpu_init(const gmx_device_info_t *deviceInfo, cuda_init_const(nb, ic, listParams, nbat->params()); - nb->atomIndicesSize = 0; - nb->atomIndicesSize_alloc = 0; - nb->ncxy_na = 0; - nb->ncxy_na_alloc = 0; - nb->ncxy_ind = 0; - nb->ncxy_ind_alloc = 0; - nb->ncell = 0; - nb->ncell_alloc = 0; + nb->atomIndicesSize = 0; + nb->atomIndicesSize_alloc = 0; + nb->ncxy_na = 0; + nb->ncxy_na_alloc = 0; + nb->ncxy_ind = 0; + nb->ncxy_ind_alloc = 0; + nb->ncell = 0; + nb->ncell_alloc = 0; if (debug) { @@ -518,14 +508,12 @@ gpu_init(const gmx_device_info_t *deviceInfo, return nb; } -void gpu_init_pairlist(gmx_nbnxn_cuda_t *nb, - const NbnxnPairlistGpu *h_plist, - const InteractionLocality iloc) +void gpu_init_pairlist(gmx_nbnxn_cuda_t* nb, const NbnxnPairlistGpu* h_plist, const InteractionLocality iloc) { - char sbuf[STRLEN]; - bool bDoTime = (nb->bDoTime && !h_plist->sci.empty()); - cudaStream_t stream = nb->stream[iloc]; - cu_plist_t *d_plist = nb->plist[iloc]; + char sbuf[STRLEN]; + bool bDoTime = (nb->bDoTime && !h_plist->sci.empty()); + cudaStream_t stream = nb->stream[iloc]; + cu_plist_t* d_plist = nb->plist[iloc]; if (d_plist->na_c < 0) { @@ -541,7 +529,7 @@ void gpu_init_pairlist(gmx_nbnxn_cuda_t *nb, } } - gpu_timers_t::Interaction &iTimers = nb->timers->interaction[iloc]; + gpu_timers_t::Interaction& iTimers = nb->timers->interaction[iloc]; if (bDoTime) { @@ -551,26 +539,21 @@ void gpu_init_pairlist(gmx_nbnxn_cuda_t *nb, DeviceContext context = nullptr; - reallocateDeviceBuffer(&d_plist->sci, h_plist->sci.size(), - &d_plist->nsci, &d_plist->sci_nalloc, context); - copyToDeviceBuffer(&d_plist->sci, h_plist->sci.data(), 0, h_plist->sci.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->sci, h_plist->sci.size(), &d_plist->nsci, &d_plist->sci_nalloc, context); + copyToDeviceBuffer(&d_plist->sci, h_plist->sci.data(), 0, h_plist->sci.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); - reallocateDeviceBuffer(&d_plist->cj4, h_plist->cj4.size(), - &d_plist->ncj4, &d_plist->cj4_nalloc, context); - copyToDeviceBuffer(&d_plist->cj4, h_plist->cj4.data(), 0, h_plist->cj4.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->cj4, h_plist->cj4.size(), &d_plist->ncj4, &d_plist->cj4_nalloc, context); + copyToDeviceBuffer(&d_plist->cj4, h_plist->cj4.data(), 0, h_plist->cj4.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); - reallocateDeviceBuffer(&d_plist->imask, h_plist->cj4.size()*c_nbnxnGpuClusterpairSplit, + reallocateDeviceBuffer(&d_plist->imask, h_plist->cj4.size() * c_nbnxnGpuClusterpairSplit, &d_plist->nimask, &d_plist->imask_nalloc, context); - reallocateDeviceBuffer(&d_plist->excl, h_plist->excl.size(), - &d_plist->nexcl, &d_plist->excl_nalloc, context); - copyToDeviceBuffer(&d_plist->excl, h_plist->excl.data(), 0, h_plist->excl.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->excl, h_plist->excl.size(), &d_plist->nexcl, + &d_plist->excl_nalloc, context); + copyToDeviceBuffer(&d_plist->excl, h_plist->excl.data(), 0, h_plist->excl.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); if (bDoTime) { @@ -581,38 +564,36 @@ void gpu_init_pairlist(gmx_nbnxn_cuda_t *nb, d_plist->haveFreshList = true; } -void gpu_upload_shiftvec(gmx_nbnxn_cuda_t *nb, - const nbnxn_atomdata_t *nbatom) +void gpu_upload_shiftvec(gmx_nbnxn_cuda_t* nb, const nbnxn_atomdata_t* nbatom) { - cu_atomdata_t *adat = nb->atdat; - cudaStream_t ls = nb->stream[InteractionLocality::Local]; + cu_atomdata_t* adat = nb->atdat; + cudaStream_t ls = nb->stream[InteractionLocality::Local]; /* only if we have a dynamic box */ if (nbatom->bDynamicBox || !adat->bShiftVecUploaded) { - cu_copy_H2D_async(adat->shift_vec, nbatom->shift_vec.data(), - SHIFTS * sizeof(*adat->shift_vec), ls); + cu_copy_H2D_async(adat->shift_vec, nbatom->shift_vec.data(), SHIFTS * sizeof(*adat->shift_vec), ls); adat->bShiftVecUploaded = true; } } /*! Clears the first natoms_clear elements of the GPU nonbonded force output array. */ -static void nbnxn_cuda_clear_f(gmx_nbnxn_cuda_t *nb, int natoms_clear) +static void nbnxn_cuda_clear_f(gmx_nbnxn_cuda_t* nb, int natoms_clear) { cudaError_t stat; - cu_atomdata_t *adat = nb->atdat; - cudaStream_t ls = nb->stream[InteractionLocality::Local]; + cu_atomdata_t* adat = nb->atdat; + cudaStream_t ls = nb->stream[InteractionLocality::Local]; stat = cudaMemsetAsync(adat->f, 0, natoms_clear * sizeof(*adat->f), ls); CU_RET_ERR(stat, "cudaMemsetAsync on f falied"); } /*! Clears nonbonded shift force output array and energy outputs on the GPU. */ -static void nbnxn_cuda_clear_e_fshift(gmx_nbnxn_cuda_t *nb) +static void nbnxn_cuda_clear_e_fshift(gmx_nbnxn_cuda_t* nb) { cudaError_t stat; - cu_atomdata_t *adat = nb->atdat; - cudaStream_t ls = nb->stream[InteractionLocality::Local]; + cu_atomdata_t* adat = nb->atdat; + cudaStream_t ls = nb->stream[InteractionLocality::Local]; stat = cudaMemsetAsync(adat->fshift, 0, SHIFTS * sizeof(*adat->fshift), ls); CU_RET_ERR(stat, "cudaMemsetAsync on fshift falied"); @@ -622,8 +603,7 @@ static void nbnxn_cuda_clear_e_fshift(gmx_nbnxn_cuda_t *nb) CU_RET_ERR(stat, "cudaMemsetAsync on e_el falied"); } -void gpu_clear_outputs(gmx_nbnxn_cuda_t *nb, - bool computeVirial) +void gpu_clear_outputs(gmx_nbnxn_cuda_t* nb, bool computeVirial) { nbnxn_cuda_clear_f(nb, nb->atdat->natoms); /* clear shift force array and energies if the outputs were @@ -634,16 +614,15 @@ void gpu_clear_outputs(gmx_nbnxn_cuda_t *nb, } } -void gpu_init_atomdata(gmx_nbnxn_cuda_t *nb, - const nbnxn_atomdata_t *nbat) +void gpu_init_atomdata(gmx_nbnxn_cuda_t* nb, const nbnxn_atomdata_t* nbat) { cudaError_t stat; int nalloc, natoms; bool realloced; - bool bDoTime = nb->bDoTime; - cu_timers_t *timers = nb->timers; - cu_atomdata_t *d_atdat = nb->atdat; - cudaStream_t ls = nb->stream[InteractionLocality::Local]; + bool bDoTime = nb->bDoTime; + cu_timers_t* timers = nb->timers; + cu_atomdata_t* d_atdat = nb->atdat; + cudaStream_t ls = nb->stream[InteractionLocality::Local]; natoms = nbat->numAtoms(); realloced = false; @@ -669,18 +648,18 @@ void gpu_init_atomdata(gmx_nbnxn_cuda_t *nb, freeDeviceBuffer(&d_atdat->lj_comb); } - stat = cudaMalloc((void **)&d_atdat->f, nalloc*sizeof(*d_atdat->f)); + stat = cudaMalloc((void**)&d_atdat->f, nalloc * sizeof(*d_atdat->f)); CU_RET_ERR(stat, "cudaMalloc failed on d_atdat->f"); - stat = cudaMalloc((void **)&d_atdat->xq, nalloc*sizeof(*d_atdat->xq)); + stat = cudaMalloc((void**)&d_atdat->xq, nalloc * sizeof(*d_atdat->xq)); CU_RET_ERR(stat, "cudaMalloc failed on d_atdat->xq"); if (useLjCombRule(nb->nbparam)) { - stat = cudaMalloc((void **)&d_atdat->lj_comb, nalloc*sizeof(*d_atdat->lj_comb)); + stat = cudaMalloc((void**)&d_atdat->lj_comb, nalloc * sizeof(*d_atdat->lj_comb)); CU_RET_ERR(stat, "cudaMalloc failed on d_atdat->lj_comb"); } else { - stat = cudaMalloc((void **)&d_atdat->atom_types, nalloc*sizeof(*d_atdat->atom_types)); + stat = cudaMalloc((void**)&d_atdat->atom_types, nalloc * sizeof(*d_atdat->atom_types)); CU_RET_ERR(stat, "cudaMalloc failed on d_atdat->atom_types"); } @@ -700,12 +679,12 @@ void gpu_init_atomdata(gmx_nbnxn_cuda_t *nb, if (useLjCombRule(nb->nbparam)) { cu_copy_H2D_async(d_atdat->lj_comb, nbat->params().lj_comb.data(), - natoms*sizeof(*d_atdat->lj_comb), ls); + natoms * sizeof(*d_atdat->lj_comb), ls); } else { cu_copy_H2D_async(d_atdat->atom_types, nbat->params().type.data(), - natoms*sizeof(*d_atdat->atom_types), ls); + natoms * sizeof(*d_atdat->atom_types), ls); } if (bDoTime) @@ -714,7 +693,7 @@ void gpu_init_atomdata(gmx_nbnxn_cuda_t *nb, } } -static void nbnxn_cuda_free_nbparam_table(cu_nbparam_t *nbparam) +static void nbnxn_cuda_free_nbparam_table(cu_nbparam_t* nbparam) { if (nbparam->eeltype == eelCuEWALD_TAB || nbparam->eeltype == eelCuEWALD_TAB_TWIN) { @@ -722,19 +701,19 @@ static void nbnxn_cuda_free_nbparam_table(cu_nbparam_t *nbparam) } } -void gpu_free(gmx_nbnxn_cuda_t *nb) +void gpu_free(gmx_nbnxn_cuda_t* nb) { - cudaError_t stat; - cu_atomdata_t *atdat; - cu_nbparam_t *nbparam; + cudaError_t stat; + cu_atomdata_t* atdat; + cu_nbparam_t* nbparam; if (nb == nullptr) { return; } - atdat = nb->atdat; - nbparam = nb->nbparam; + atdat = nb->atdat; + nbparam = nb->nbparam; nbnxn_cuda_free_nbparam_table(nbparam); @@ -757,7 +736,6 @@ void gpu_free(gmx_nbnxn_cuda_t *nb) if (!useLjCombRule(nb->nbparam)) { destroyParamLookupTable(nbparam->nbfp, nbparam->nbfp_texobj); - } if (nbparam->vdwtype == evdwCuEWALDGEOM || nbparam->vdwtype == evdwCuEWALDLB) @@ -781,7 +759,7 @@ void gpu_free(gmx_nbnxn_cuda_t *nb) freeDeviceBuffer(&atdat->lj_comb); /* Free plist */ - auto *plist = nb->plist[InteractionLocality::Local]; + auto* plist = nb->plist[InteractionLocality::Local]; freeDeviceBuffer(&plist->sci); freeDeviceBuffer(&plist->cj4); freeDeviceBuffer(&plist->imask); @@ -789,7 +767,7 @@ void gpu_free(gmx_nbnxn_cuda_t *nb) sfree(plist); if (nb->bUseTwoStreams) { - auto *plist_nl = nb->plist[InteractionLocality::NonLocal]; + auto* plist_nl = nb->plist[InteractionLocality::NonLocal]; freeDeviceBuffer(&plist_nl->sci); freeDeviceBuffer(&plist_nl->cj4); freeDeviceBuffer(&plist_nl->imask); @@ -819,7 +797,7 @@ void gpu_free(gmx_nbnxn_cuda_t *nb) } //! This function is documented in the header file -gmx_wallclock_gpu_nbnxn_t *gpu_get_timings(gmx_nbnxn_cuda_t *nb) +gmx_wallclock_gpu_nbnxn_t* gpu_get_timings(gmx_nbnxn_cuda_t* nb) { return (nb != nullptr && nb->bDoTime) ? nb->timings : nullptr; } @@ -832,74 +810,70 @@ void gpu_reset_timings(nonbonded_verlet_t* nbv) } } -int gpu_min_ci_balanced(gmx_nbnxn_cuda_t *nb) +int gpu_min_ci_balanced(gmx_nbnxn_cuda_t* nb) { - return nb != nullptr ? - gpu_min_ci_balanced_factor*nb->dev_info->prop.multiProcessorCount : 0; - + return nb != nullptr ? gpu_min_ci_balanced_factor * nb->dev_info->prop.multiProcessorCount : 0; } -gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_cuda_t *nb) +gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_cuda_t* nb) { - return ((nb->nbparam->eeltype == eelCuEWALD_ANA) || - (nb->nbparam->eeltype == eelCuEWALD_ANA_TWIN)); + return ((nb->nbparam->eeltype == eelCuEWALD_ANA) || (nb->nbparam->eeltype == eelCuEWALD_ANA_TWIN)); } -void *gpu_get_command_stream(gmx_nbnxn_gpu_t *nb, - const InteractionLocality iloc) +void* gpu_get_command_stream(gmx_nbnxn_gpu_t* nb, const InteractionLocality iloc) { assert(nb); - return static_cast(&nb->stream[iloc]); + return static_cast(&nb->stream[iloc]); } -void *gpu_get_xq(gmx_nbnxn_gpu_t *nb) +void* gpu_get_xq(gmx_nbnxn_gpu_t* nb) { assert(nb); - return static_cast(nb->atdat->xq); + return static_cast(nb->atdat->xq); } -void *gpu_get_f(gmx_nbnxn_gpu_t *nb) +void* gpu_get_f(gmx_nbnxn_gpu_t* nb) { assert(nb); - return static_cast(nb->atdat->f); + return static_cast(nb->atdat->f); } -rvec *gpu_get_fshift(gmx_nbnxn_gpu_t *nb) +rvec* gpu_get_fshift(gmx_nbnxn_gpu_t* nb) { assert(nb); - return reinterpret_cast(nb->atdat->fshift); + return reinterpret_cast(nb->atdat->fshift); } /* Initialization for X buffer operations on GPU. */ /* TODO Remove explicit pinning from host arrays from here and manage in a more natural way*/ -void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet &gridSet, - gmx_nbnxn_gpu_t *gpu_nbv) +void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet& gridSet, gmx_nbnxn_gpu_t* gpu_nbv) { - cudaStream_t stream = gpu_nbv->stream[InteractionLocality::Local]; - bool bDoTime = gpu_nbv->bDoTime; - const int maxNumColumns = gridSet.numColumnsMax(); + cudaStream_t stream = gpu_nbv->stream[InteractionLocality::Local]; + bool bDoTime = gpu_nbv->bDoTime; + const int maxNumColumns = gridSet.numColumnsMax(); - reallocateDeviceBuffer(&gpu_nbv->cxy_na, maxNumColumns*gridSet.grids().size(), + reallocateDeviceBuffer(&gpu_nbv->cxy_na, maxNumColumns * gridSet.grids().size(), &gpu_nbv->ncxy_na, &gpu_nbv->ncxy_na_alloc, nullptr); - reallocateDeviceBuffer(&gpu_nbv->cxy_ind, maxNumColumns*gridSet.grids().size(), + reallocateDeviceBuffer(&gpu_nbv->cxy_ind, maxNumColumns * gridSet.grids().size(), &gpu_nbv->ncxy_ind, &gpu_nbv->ncxy_ind_alloc, nullptr); for (unsigned int g = 0; g < gridSet.grids().size(); g++) { - const Nbnxm::Grid &grid = gridSet.grids()[g]; + const Nbnxm::Grid& grid = gridSet.grids()[g]; - const int numColumns = grid.numColumns(); - const int *atomIndices = gridSet.atomIndices().data(); - const int atomIndicesSize = gridSet.atomIndices().size(); - const int *cxy_na = grid.cxy_na().data(); - const int *cxy_ind = grid.cxy_ind().data(); + const int numColumns = grid.numColumns(); + const int* atomIndices = gridSet.atomIndices().data(); + const int atomIndicesSize = gridSet.atomIndices().size(); + const int* cxy_na = grid.cxy_na().data(); + const int* cxy_ind = grid.cxy_ind().data(); - reallocateDeviceBuffer(&gpu_nbv->atomIndices, atomIndicesSize, &gpu_nbv->atomIndicesSize, &gpu_nbv->atomIndicesSize_alloc, nullptr); + reallocateDeviceBuffer(&gpu_nbv->atomIndices, atomIndicesSize, &gpu_nbv->atomIndicesSize, + &gpu_nbv->atomIndicesSize_alloc, nullptr); if (atomIndicesSize > 0) { @@ -909,13 +883,13 @@ void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet &gridSet, gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(stream); } - copyToDeviceBuffer(&gpu_nbv->atomIndices, atomIndices, 0, atomIndicesSize, stream, GpuApiCallBehavior::Async, nullptr); + copyToDeviceBuffer(&gpu_nbv->atomIndices, atomIndices, 0, atomIndicesSize, stream, + GpuApiCallBehavior::Async, nullptr); if (bDoTime) { gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(stream); } - } if (numColumns > 0) @@ -925,7 +899,7 @@ void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet &gridSet, gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(stream); } - int* destPtr = &gpu_nbv->cxy_na[maxNumColumns*g]; + int* destPtr = &gpu_nbv->cxy_na[maxNumColumns * g]; copyToDeviceBuffer(&destPtr, cxy_na, 0, numColumns, stream, GpuApiCallBehavior::Async, nullptr); if (bDoTime) @@ -938,14 +912,13 @@ void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet &gridSet, gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.openTimingRegion(stream); } - destPtr = &gpu_nbv->cxy_ind[maxNumColumns*g]; + destPtr = &gpu_nbv->cxy_ind[maxNumColumns * g]; copyToDeviceBuffer(&destPtr, cxy_ind, 0, numColumns, stream, GpuApiCallBehavior::Async, nullptr); if (bDoTime) { gpu_nbv->timers->xf[AtomLocality::Local].nb_h2d.closeTimingRegion(stream); } - } } @@ -962,13 +935,13 @@ void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet &gridSet, } /* Initialization for F buffer operations on GPU. */ -void nbnxn_gpu_init_add_nbat_f_to_f(const int *cell, - gmx_nbnxn_gpu_t *gpu_nbv, +void nbnxn_gpu_init_add_nbat_f_to_f(const int* cell, + gmx_nbnxn_gpu_t* gpu_nbv, int natoms_total, GpuEventSynchronizer* const localReductionDone) { - cudaStream_t stream = gpu_nbv->stream[InteractionLocality::Local]; + cudaStream_t stream = gpu_nbv->stream[InteractionLocality::Local]; GMX_ASSERT(localReductionDone, "localReductionDone should be a valid pointer"); gpu_nbv->localFReductionDone = localReductionDone; diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel.cuh b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel.cuh index 7110a8a405..2201009170 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel.cuh +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel.cuh @@ -56,26 +56,27 @@ #if defined EL_EWALD_ANA || defined EL_EWALD_TAB /* Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define EL_EWALD_ANY +# define EL_EWALD_ANY #endif -#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD || (defined EL_CUTOFF && defined CALC_ENERGIES) +#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD \ + || (defined EL_CUTOFF && defined CALC_ENERGIES) /* Macro to control the calculation of exclusion forces in the kernel * We do that with Ewald (elec/vdw) and RF. Cut-off only has exclusion * energy terms. * * Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define EXCLUSION_FORCES +# define EXCLUSION_FORCES #endif #if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB /* Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define LJ_EWALD +# define LJ_EWALD #endif #if defined LJ_COMB_GEOM || defined LJ_COMB_LB -#define LJ_COMB +# define LJ_COMB #endif /* @@ -129,13 +130,13 @@ * Note: convenience macros, need to be undef-ed at the end of the file. */ #if GMX_PTX_ARCH == 370 - #define NTHREAD_Z (2) - #define MIN_BLOCKS_PER_MP (16) +# define NTHREAD_Z (2) +# define MIN_BLOCKS_PER_MP (16) #else - #define NTHREAD_Z (1) - #define MIN_BLOCKS_PER_MP (16) +# define NTHREAD_Z (1) +# define MIN_BLOCKS_PER_MP (16) #endif /* GMX_PTX_ARCH == 370 */ -#define THREADS_PER_BLOCK (c_clSize*c_clSize*NTHREAD_Z) +#define THREADS_PER_BLOCK (c_clSize * c_clSize * NTHREAD_Z) #if GMX_PTX_ARCH >= 350 /**@}*/ @@ -144,108 +145,101 @@ __launch_bounds__(THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP) __launch_bounds__(THREADS_PER_BLOCK) #endif /* GMX_PTX_ARCH >= 350 */ #ifdef PRUNE_NBL -#ifdef CALC_ENERGIES -__global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_prune_cuda) +# ifdef CALC_ENERGIES + __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_prune_cuda) +# else + __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_prune_cuda) +# endif /* CALC_ENERGIES */ #else -__global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_prune_cuda) -#endif /* CALC_ENERGIES */ -#else -#ifdef CALC_ENERGIES -__global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_cuda) -#else -__global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) -#endif /* CALC_ENERGIES */ -#endif /* PRUNE_NBL */ -(const cu_atomdata_t atdat, - const cu_nbparam_t nbparam, - const cu_plist_t plist, - bool bCalcFshift) +# ifdef CALC_ENERGIES + __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_cuda) +# else + __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) +# endif /* CALC_ENERGIES */ +#endif /* PRUNE_NBL */ + (const cu_atomdata_t atdat, const cu_nbparam_t nbparam, const cu_plist_t plist, bool bCalcFshift) #ifdef FUNCTION_DECLARATION_ONLY -; /* Only do function declaration, omit the function body. */ + ; /* Only do function declaration, omit the function body. */ #else { /* convenience variables */ - const nbnxn_sci_t *pl_sci = plist.sci; -#ifndef PRUNE_NBL + const nbnxn_sci_t* pl_sci = plist.sci; +# ifndef PRUNE_NBL const -#endif - nbnxn_cj4_t *pl_cj4 = plist.cj4; - const nbnxn_excl_t *excl = plist.excl; -#ifndef LJ_COMB - const int *atom_types = atdat.atom_types; - int ntypes = atdat.ntypes; -#else - const float2 *lj_comb = atdat.lj_comb; - float2 ljcp_i, ljcp_j; -#endif - const float4 *xq = atdat.xq; - float3 *f = atdat.f; - const float3 *shift_vec = atdat.shift_vec; - float rcoulomb_sq = nbparam.rcoulomb_sq; -#ifdef VDW_CUTOFF_CHECK - float rvdw_sq = nbparam.rvdw_sq; - float vdw_in_range; -#endif -#ifdef LJ_EWALD - float lje_coeff2, lje_coeff6_6; -#endif -#ifdef EL_RF - float two_k_rf = nbparam.two_k_rf; -#endif -#ifdef EL_EWALD_ANA - float beta2 = nbparam.ewald_beta*nbparam.ewald_beta; - float beta3 = nbparam.ewald_beta*nbparam.ewald_beta*nbparam.ewald_beta; -#endif -#ifdef PRUNE_NBL - float rlist_sq = nbparam.rlistOuter_sq; -#endif - -#ifdef CALC_ENERGIES -#ifdef EL_EWALD_ANY - float beta = nbparam.ewald_beta; - float ewald_shift = nbparam.sh_ewald; -#else - float c_rf = nbparam.c_rf; -#endif /* EL_EWALD_ANY */ - float *e_lj = atdat.e_lj; - float *e_el = atdat.e_el; -#endif /* CALC_ENERGIES */ +# endif + nbnxn_cj4_t* pl_cj4 = plist.cj4; + const nbnxn_excl_t* excl = plist.excl; +# ifndef LJ_COMB + const int* atom_types = atdat.atom_types; + int ntypes = atdat.ntypes; +# else + const float2* lj_comb = atdat.lj_comb; + float2 ljcp_i, ljcp_j; +# endif + const float4* xq = atdat.xq; + float3* f = atdat.f; + const float3* shift_vec = atdat.shift_vec; + float rcoulomb_sq = nbparam.rcoulomb_sq; +# ifdef VDW_CUTOFF_CHECK + float rvdw_sq = nbparam.rvdw_sq; + float vdw_in_range; +# endif +# ifdef LJ_EWALD + float lje_coeff2, lje_coeff6_6; +# endif +# ifdef EL_RF + float two_k_rf = nbparam.two_k_rf; +# endif +# ifdef EL_EWALD_ANA + float beta2 = nbparam.ewald_beta * nbparam.ewald_beta; + float beta3 = nbparam.ewald_beta * nbparam.ewald_beta * nbparam.ewald_beta; +# endif +# ifdef PRUNE_NBL + float rlist_sq = nbparam.rlistOuter_sq; +# endif + +# ifdef CALC_ENERGIES +# ifdef EL_EWALD_ANY + float beta = nbparam.ewald_beta; + float ewald_shift = nbparam.sh_ewald; +# else + float c_rf = nbparam.c_rf; +# endif /* EL_EWALD_ANY */ + float* e_lj = atdat.e_lj; + float* e_el = atdat.e_el; +# endif /* CALC_ENERGIES */ /* thread/block/warp id-s */ - unsigned int tidxi = threadIdx.x; - unsigned int tidxj = threadIdx.y; - unsigned int tidx = threadIdx.y * blockDim.x + threadIdx.x; -#if NTHREAD_Z == 1 - unsigned int tidxz = 0; -#else - unsigned int tidxz = threadIdx.z; -#endif - unsigned int bidx = blockIdx.x; - unsigned int widx = tidx / warp_size; /* warp index */ - - int sci, ci, cj, - ai, aj, - cij4_start, cij4_end; -#ifndef LJ_COMB + unsigned int tidxi = threadIdx.x; + unsigned int tidxj = threadIdx.y; + unsigned int tidx = threadIdx.y * blockDim.x + threadIdx.x; +# if NTHREAD_Z == 1 + unsigned int tidxz = 0; +# else + unsigned int tidxz = threadIdx.z; +# endif + unsigned int bidx = blockIdx.x; + unsigned int widx = tidx / warp_size; /* warp index */ + + int sci, ci, cj, ai, aj, cij4_start, cij4_end; +# ifndef LJ_COMB int typei, typej; -#endif +# endif int i, jm, j4, wexcl_idx; - float qi, qj_f, - r2, inv_r, inv_r2; -#if !defined LJ_COMB_LB || defined CALC_ENERGIES + float qi, qj_f, r2, inv_r, inv_r2; +# if !defined LJ_COMB_LB || defined CALC_ENERGIES float inv_r6, c6, c12; -#endif -#ifdef LJ_COMB_LB +# endif +# ifdef LJ_COMB_LB float sigma, epsilon; -#endif - float int_bit, - F_invr; -#ifdef CALC_ENERGIES +# endif + float int_bit, F_invr; +# ifdef CALC_ENERGIES float E_lj, E_el; -#endif -#if defined CALC_ENERGIES || defined LJ_POT_SWITCH +# endif +# if defined CALC_ENERGIES || defined LJ_POT_SWITCH float E_lj_p; -#endif +# endif unsigned int wexcl, imask, mask_ji; float4 xqbuf; float3 xi, xj, rv, f_ij, fcj_buf; @@ -260,35 +254,36 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) * sm_nextSlotPtr should always be updated to point to the "next slot", * that is past the last point where data has been stored. */ - extern __shared__ char sm_dynamicShmem[]; - char *sm_nextSlotPtr = sm_dynamicShmem; - static_assert(sizeof(char) == 1, "The shared memory offset calculation assumes that char is 1 byte"); + extern __shared__ char sm_dynamicShmem[]; + char* sm_nextSlotPtr = sm_dynamicShmem; + static_assert(sizeof(char) == 1, + "The shared memory offset calculation assumes that char is 1 byte"); /* shmem buffer for i x+q pre-loading */ - float4 *xqib = (float4 *)sm_nextSlotPtr; + float4* xqib = (float4*)sm_nextSlotPtr; sm_nextSlotPtr += (c_numClPerSupercl * c_clSize * sizeof(*xqib)); /* shmem buffer for cj, for each warp separately */ - int *cjs = (int *)(sm_nextSlotPtr); + int* cjs = (int*)(sm_nextSlotPtr); /* the cjs buffer's use expects a base pointer offset for pairs of warps in the j-concurrent execution */ - cjs += tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize; + cjs += tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize; sm_nextSlotPtr += (NTHREAD_Z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(*cjs)); -#ifndef LJ_COMB +# ifndef LJ_COMB /* shmem buffer for i atom-type pre-loading */ - int *atib = (int *)sm_nextSlotPtr; + int* atib = (int*)sm_nextSlotPtr; sm_nextSlotPtr += (c_numClPerSupercl * c_clSize * sizeof(*atib)); -#else +# else /* shmem buffer for i-atom LJ combination rule parameters */ - float2 *ljcpib = (float2 *)sm_nextSlotPtr; + float2* ljcpib = (float2*)sm_nextSlotPtr; sm_nextSlotPtr += (c_numClPerSupercl * c_clSize * sizeof(*ljcpib)); -#endif +# endif /*********************************************************************/ - nb_sci = pl_sci[bidx]; /* my i super-cluster's index = current bidx */ - sci = nb_sci.sci; /* super-cluster */ - cij4_start = nb_sci.cj4_ind_start; /* first ...*/ - cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ + nb_sci = pl_sci[bidx]; /* my i super-cluster's index = current bidx */ + sci = nb_sci.sci; /* super-cluster */ + cij4_start = nb_sci.cj4_ind_start; /* first ...*/ + cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ if (tidxz == 0) { @@ -296,18 +291,18 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) ci = sci * c_numClPerSupercl + tidxj; ai = ci * c_clSize + tidxi; - float *shiftptr = (float *)&shift_vec[nb_sci.shift]; - xqbuf = xq[ai] + make_float4(LDG(shiftptr), LDG(shiftptr + 1), LDG(shiftptr + 2), 0.0f); + float* shiftptr = (float*)&shift_vec[nb_sci.shift]; + xqbuf = xq[ai] + make_float4(LDG(shiftptr), LDG(shiftptr + 1), LDG(shiftptr + 2), 0.0f); xqbuf.w *= nbparam.epsfac; xqib[tidxj * c_clSize + tidxi] = xqbuf; -#ifndef LJ_COMB +# ifndef LJ_COMB /* Pre-load the i-atom types into shared memory */ atib[tidxj * c_clSize + tidxi] = atom_types[ai]; -#else +# else /* Pre-load the LJ combination parameters into shared memory */ ljcpib[tidxj * c_clSize + tidxi] = lj_comb[ai]; -#endif +# endif } __syncthreads(); @@ -316,60 +311,63 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) fci_buf[i] = make_float3(0.0f); } -#ifdef LJ_EWALD +# ifdef LJ_EWALD /* TODO: we are trading registers with flops by keeping lje_coeff-s, try re-calculating it later */ - lje_coeff2 = nbparam.ewaldcoeff_lj*nbparam.ewaldcoeff_lj; - lje_coeff6_6 = lje_coeff2*lje_coeff2*lje_coeff2*c_oneSixth; -#endif + lje_coeff2 = nbparam.ewaldcoeff_lj * nbparam.ewaldcoeff_lj; + lje_coeff6_6 = lje_coeff2 * lje_coeff2 * lje_coeff2 * c_oneSixth; +# endif -#ifdef CALC_ENERGIES - E_lj = 0.0f; - E_el = 0.0f; +# ifdef CALC_ENERGIES + E_lj = 0.0f; + E_el = 0.0f; -#ifdef EXCLUSION_FORCES /* Ewald or RF */ - if (nb_sci.shift == CENTRAL && pl_cj4[cij4_start].cj[0] == sci*c_numClPerSupercl) +# ifdef EXCLUSION_FORCES /* Ewald or RF */ + if (nb_sci.shift == CENTRAL && pl_cj4[cij4_start].cj[0] == sci * c_numClPerSupercl) { /* we have the diagonal: add the charge and LJ self interaction energy term */ for (i = 0; i < c_numClPerSupercl; i++) { -#if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF - qi = xqib[i * c_clSize + tidxi].w; - E_el += qi*qi; -#endif - -#ifdef LJ_EWALD - #if DISABLE_CUDA_TEXTURES - E_lj += LDG(&nbparam.nbfp[atom_types[(sci*c_numClPerSupercl + i)*c_clSize + tidxi]*(ntypes + 1)*2]); - #else - E_lj += tex1Dfetch(nbparam.nbfp_texobj, atom_types[(sci*c_numClPerSupercl + i)*c_clSize + tidxi]*(ntypes + 1)*2); - #endif -#endif +# if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF + qi = xqib[i * c_clSize + tidxi].w; + E_el += qi * qi; +# endif + +# ifdef LJ_EWALD +# if DISABLE_CUDA_TEXTURES + E_lj += LDG( + &nbparam.nbfp[atom_types[(sci * c_numClPerSupercl + i) * c_clSize + tidxi] * (ntypes + 1) * 2]); +# else + E_lj += tex1Dfetch( + nbparam.nbfp_texobj, + atom_types[(sci * c_numClPerSupercl + i) * c_clSize + tidxi] * (ntypes + 1) * 2); +# endif +# endif } /* divide the self term(s) equally over the j-threads, then multiply with the coefficients. */ -#ifdef LJ_EWALD - E_lj /= c_clSize*NTHREAD_Z; - E_lj *= 0.5f*c_oneSixth*lje_coeff6_6; -#endif +# ifdef LJ_EWALD + E_lj /= c_clSize * NTHREAD_Z; + E_lj *= 0.5f * c_oneSixth * lje_coeff6_6; +# endif -#if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF +# if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF /* Correct for epsfac^2 due to adding qi^2 */ - E_el /= nbparam.epsfac*c_clSize*NTHREAD_Z; -#if defined EL_RF || defined EL_CUTOFF - E_el *= -0.5f*c_rf; -#else - E_el *= -beta*M_FLOAT_1_SQRTPI; /* last factor 1/sqrt(pi) */ -#endif -#endif /* EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF */ + E_el /= nbparam.epsfac * c_clSize * NTHREAD_Z; +# if defined EL_RF || defined EL_CUTOFF + E_el *= -0.5f * c_rf; +# else + E_el *= -beta * M_FLOAT_1_SQRTPI; /* last factor 1/sqrt(pi) */ +# endif +# endif /* EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF */ } -#endif /* EXCLUSION_FORCES */ +# endif /* EXCLUSION_FORCES */ -#endif /* CALC_ENERGIES */ +# endif /* CALC_ENERGIES */ -#ifdef EXCLUSION_FORCES +# ifdef EXCLUSION_FORCES const int nonSelfInteraction = !(nb_sci.shift == CENTRAL & tidxj <= tidxi); -#endif +# endif /* loop over the j clusters = seen by any of the atoms in the current super-cluster; * The loop stride NTHREAD_Z ensures that consecutive warps-pairs are assigned @@ -377,18 +375,18 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) */ for (j4 = cij4_start + tidxz; j4 < cij4_end; j4 += NTHREAD_Z) { - wexcl_idx = pl_cj4[j4].imei[widx].excl_ind; - imask = pl_cj4[j4].imei[widx].imask; - wexcl = excl[wexcl_idx].pair[(tidx) & (warp_size - 1)]; + wexcl_idx = pl_cj4[j4].imei[widx].excl_ind; + imask = pl_cj4[j4].imei[widx].imask; + wexcl = excl[wexcl_idx].pair[(tidx) & (warp_size - 1)]; -#ifndef PRUNE_NBL +# ifndef PRUNE_NBL if (imask) -#endif +# endif { /* Pre-load cj into shared memory on both warps separately */ if ((tidxj == 0 | tidxj == 4) & (tidxi < c_nbnxnGpuJgroupSize)) { - cjs[tidxi + tidxj * c_nbnxnGpuJgroupSize/c_splitClSize] = pl_cj4[j4].cj[tidxi]; + cjs[tidxi + tidxj * c_nbnxnGpuJgroupSize / c_splitClSize] = pl_cj4[j4].cj[tidxi]; } __syncwarp(c_fullWarpMask); @@ -402,39 +400,39 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) { mask_ji = (1U << (jm * c_numClPerSupercl)); - cj = cjs[jm + (tidxj & 4) * c_nbnxnGpuJgroupSize/c_splitClSize]; - aj = cj * c_clSize + tidxj; + cj = cjs[jm + (tidxj & 4) * c_nbnxnGpuJgroupSize / c_splitClSize]; + aj = cj * c_clSize + tidxj; /* load j atom data */ - xqbuf = xq[aj]; - xj = make_float3(xqbuf.x, xqbuf.y, xqbuf.z); - qj_f = xqbuf.w; -#ifndef LJ_COMB - typej = atom_types[aj]; -#else - ljcp_j = lj_comb[aj]; -#endif + xqbuf = xq[aj]; + xj = make_float3(xqbuf.x, xqbuf.y, xqbuf.z); + qj_f = xqbuf.w; +# ifndef LJ_COMB + typej = atom_types[aj]; +# else + ljcp_j = lj_comb[aj]; +# endif fcj_buf = make_float3(0.0f); -#if !defined PRUNE_NBL -#pragma unroll 8 -#endif +# if !defined PRUNE_NBL +# pragma unroll 8 +# endif for (i = 0; i < c_numClPerSupercl; i++) { if (imask & mask_ji) { - ci = sci * c_numClPerSupercl + i; /* i cluster index */ + ci = sci * c_numClPerSupercl + i; /* i cluster index */ /* all threads load an atom from i cluster ci into shmem! */ - xqbuf = xqib[i * c_clSize + tidxi]; - xi = make_float3(xqbuf.x, xqbuf.y, xqbuf.z); + xqbuf = xqib[i * c_clSize + tidxi]; + xi = make_float3(xqbuf.x, xqbuf.y, xqbuf.z); /* distance between i and j atoms */ - rv = xi - xj; - r2 = norm2(rv); + rv = xi - xj; + r2 = norm2(rv); -#ifdef PRUNE_NBL +# ifdef PRUNE_NBL /* If _none_ of the atoms pairs are in cutoff range, the bit corresponding to the current cluster-pair in imask gets set to 0. */ @@ -442,149 +440,158 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) { imask &= ~mask_ji; } -#endif +# endif int_bit = (wexcl & mask_ji) ? 1.0f : 0.0f; /* cutoff & exclusion check */ -#ifdef EXCLUSION_FORCES +# ifdef EXCLUSION_FORCES if ((r2 < rcoulomb_sq) * (nonSelfInteraction | (ci != cj))) -#else +# else if ((r2 < rcoulomb_sq) * int_bit) -#endif +# endif { /* load the rest of the i-atom parameters */ - qi = xqbuf.w; + qi = xqbuf.w; -#ifndef LJ_COMB +# ifndef LJ_COMB /* LJ 6*C6 and 12*C12 */ - typei = atib[i * c_clSize + tidxi]; + typei = atib[i * c_clSize + tidxi]; fetch_nbfp_c6_c12(c6, c12, nbparam, ntypes * typei + typej); -#else - ljcp_i = ljcpib[i * c_clSize + tidxi]; -#ifdef LJ_COMB_GEOM - c6 = ljcp_i.x * ljcp_j.x; - c12 = ljcp_i.y * ljcp_j.y; -#else +# else + ljcp_i = ljcpib[i * c_clSize + tidxi]; +# ifdef LJ_COMB_GEOM + c6 = ljcp_i.x * ljcp_j.x; + c12 = ljcp_i.y * ljcp_j.y; +# else /* LJ 2^(1/6)*sigma and 12*epsilon */ sigma = ljcp_i.x + ljcp_j.x; epsilon = ljcp_i.y * ljcp_j.y; -#if defined CALC_ENERGIES || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH +# if defined CALC_ENERGIES || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH convert_sigma_epsilon_to_c6_c12(sigma, epsilon, &c6, &c12); -#endif -#endif /* LJ_COMB_GEOM */ -#endif /* LJ_COMB */ +# endif +# endif /* LJ_COMB_GEOM */ +# endif /* LJ_COMB */ // Ensure distance do not become so small that r^-12 overflows - r2 = max(r2, NBNXN_MIN_RSQ); + r2 = max(r2, NBNXN_MIN_RSQ); - inv_r = rsqrt(r2); - inv_r2 = inv_r * inv_r; -#if !defined LJ_COMB_LB || defined CALC_ENERGIES - inv_r6 = inv_r2 * inv_r2 * inv_r2; -#ifdef EXCLUSION_FORCES + inv_r = rsqrt(r2); + inv_r2 = inv_r * inv_r; +# if !defined LJ_COMB_LB || defined CALC_ENERGIES + inv_r6 = inv_r2 * inv_r2 * inv_r2; +# ifdef EXCLUSION_FORCES /* We could mask inv_r2, but with Ewald * masking both inv_r6 and F_invr is faster */ - inv_r6 *= int_bit; -#endif /* EXCLUSION_FORCES */ - - F_invr = inv_r6 * (c12 * inv_r6 - c6) * inv_r2; -#if defined CALC_ENERGIES || defined LJ_POT_SWITCH - E_lj_p = int_bit * (c12 * (inv_r6 * inv_r6 + nbparam.repulsion_shift.cpot)*c_oneTwelveth - - c6 * (inv_r6 + nbparam.dispersion_shift.cpot)*c_oneSixth); -#endif -#else /* !LJ_COMB_LB || CALC_ENERGIES */ - float sig_r = sigma*inv_r; - float sig_r2 = sig_r*sig_r; - float sig_r6 = sig_r2*sig_r2*sig_r2; -#ifdef EXCLUSION_FORCES + inv_r6 *= int_bit; +# endif /* EXCLUSION_FORCES */ + + F_invr = inv_r6 * (c12 * inv_r6 - c6) * inv_r2; +# if defined CALC_ENERGIES || defined LJ_POT_SWITCH + E_lj_p = int_bit + * (c12 * (inv_r6 * inv_r6 + nbparam.repulsion_shift.cpot) * c_oneTwelveth + - c6 * (inv_r6 + nbparam.dispersion_shift.cpot) * c_oneSixth); +# endif +# else /* !LJ_COMB_LB || CALC_ENERGIES */ + float sig_r = sigma * inv_r; + float sig_r2 = sig_r * sig_r; + float sig_r6 = sig_r2 * sig_r2 * sig_r2; +# ifdef EXCLUSION_FORCES sig_r6 *= int_bit; -#endif /* EXCLUSION_FORCES */ +# endif /* EXCLUSION_FORCES */ - F_invr = epsilon * sig_r6 * (sig_r6 - 1.0f) * inv_r2; -#endif /* !LJ_COMB_LB || CALC_ENERGIES */ + F_invr = epsilon * sig_r6 * (sig_r6 - 1.0f) * inv_r2; +# endif /* !LJ_COMB_LB || CALC_ENERGIES */ -#ifdef LJ_FORCE_SWITCH -#ifdef CALC_ENERGIES +# ifdef LJ_FORCE_SWITCH +# ifdef CALC_ENERGIES calculate_force_switch_F_E(nbparam, c6, c12, inv_r, r2, &F_invr, &E_lj_p); -#else +# else calculate_force_switch_F(nbparam, c6, c12, inv_r, r2, &F_invr); -#endif /* CALC_ENERGIES */ -#endif /* LJ_FORCE_SWITCH */ - - -#ifdef LJ_EWALD -#ifdef LJ_EWALD_COMB_GEOM -#ifdef CALC_ENERGIES - calculate_lj_ewald_comb_geom_F_E(nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, int_bit, &F_invr, &E_lj_p); -#else - calculate_lj_ewald_comb_geom_F(nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, &F_invr); -#endif /* CALC_ENERGIES */ -#elif defined LJ_EWALD_COMB_LB - calculate_lj_ewald_comb_LB_F_E(nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, -#ifdef CALC_ENERGIES +# endif /* CALC_ENERGIES */ +# endif /* LJ_FORCE_SWITCH */ + + +# ifdef LJ_EWALD +# ifdef LJ_EWALD_COMB_GEOM +# ifdef CALC_ENERGIES + calculate_lj_ewald_comb_geom_F_E(nbparam, typei, typej, r2, inv_r2, + lje_coeff2, lje_coeff6_6, int_bit, + &F_invr, &E_lj_p); +# else + calculate_lj_ewald_comb_geom_F(nbparam, typei, typej, r2, inv_r2, + lje_coeff2, lje_coeff6_6, &F_invr); +# endif /* CALC_ENERGIES */ +# elif defined LJ_EWALD_COMB_LB + calculate_lj_ewald_comb_LB_F_E(nbparam, typei, typej, r2, inv_r2, + lje_coeff2, lje_coeff6_6, +# ifdef CALC_ENERGIES int_bit, &F_invr, &E_lj_p -#else +# else 0, &F_invr, nullptr -#endif /* CALC_ENERGIES */ - ); -#endif /* LJ_EWALD_COMB_GEOM */ -#endif /* LJ_EWALD */ +# endif /* CALC_ENERGIES */ + ); +# endif /* LJ_EWALD_COMB_GEOM */ +# endif /* LJ_EWALD */ -#ifdef LJ_POT_SWITCH -#ifdef CALC_ENERGIES +# ifdef LJ_POT_SWITCH +# ifdef CALC_ENERGIES calculate_potential_switch_F_E(nbparam, inv_r, r2, &F_invr, &E_lj_p); -#else +# else calculate_potential_switch_F(nbparam, inv_r, r2, &F_invr, &E_lj_p); -#endif /* CALC_ENERGIES */ -#endif /* LJ_POT_SWITCH */ +# endif /* CALC_ENERGIES */ +# endif /* LJ_POT_SWITCH */ -#ifdef VDW_CUTOFF_CHECK +# ifdef VDW_CUTOFF_CHECK /* Separate VDW cut-off check to enable twin-range cut-offs * (rvdw < rcoulomb <= rlist) */ - vdw_in_range = (r2 < rvdw_sq) ? 1.0f : 0.0f; - F_invr *= vdw_in_range; -#ifdef CALC_ENERGIES - E_lj_p *= vdw_in_range; -#endif -#endif /* VDW_CUTOFF_CHECK */ - -#ifdef CALC_ENERGIES - E_lj += E_lj_p; -#endif - - -#ifdef EL_CUTOFF -#ifdef EXCLUSION_FORCES - F_invr += qi * qj_f * int_bit * inv_r2 * inv_r; -#else - F_invr += qi * qj_f * inv_r2 * inv_r; -#endif -#endif -#ifdef EL_RF - F_invr += qi * qj_f * (int_bit*inv_r2 * inv_r - two_k_rf); -#endif -#if defined EL_EWALD_ANA - F_invr += qi * qj_f * (int_bit*inv_r2*inv_r + pmecorrF(beta2*r2)*beta3); -#elif defined EL_EWALD_TAB - F_invr += qi * qj_f * (int_bit*inv_r2 - - interpolate_coulomb_force_r(nbparam, r2 * inv_r)) * inv_r; -#endif /* EL_EWALD_ANA/TAB */ - -#ifdef CALC_ENERGIES -#ifdef EL_CUTOFF - E_el += qi * qj_f * (int_bit*inv_r - c_rf); -#endif -#ifdef EL_RF - E_el += qi * qj_f * (int_bit*inv_r + 0.5f * two_k_rf * r2 - c_rf); -#endif -#ifdef EL_EWALD_ANY + vdw_in_range = (r2 < rvdw_sq) ? 1.0f : 0.0f; + F_invr *= vdw_in_range; +# ifdef CALC_ENERGIES + E_lj_p *= vdw_in_range; +# endif +# endif /* VDW_CUTOFF_CHECK */ + +# ifdef CALC_ENERGIES + E_lj += E_lj_p; +# endif + + +# ifdef EL_CUTOFF +# ifdef EXCLUSION_FORCES + F_invr += qi * qj_f * int_bit * inv_r2 * inv_r; +# else + F_invr += qi * qj_f * inv_r2 * inv_r; +# endif +# endif +# ifdef EL_RF + F_invr += qi * qj_f * (int_bit * inv_r2 * inv_r - two_k_rf); +# endif +# if defined EL_EWALD_ANA + F_invr += qi * qj_f + * (int_bit * inv_r2 * inv_r + pmecorrF(beta2 * r2) * beta3); +# elif defined EL_EWALD_TAB + F_invr += qi * qj_f + * (int_bit * inv_r2 + - interpolate_coulomb_force_r(nbparam, r2 * inv_r)) + * inv_r; +# endif /* EL_EWALD_ANA/TAB */ + +# ifdef CALC_ENERGIES +# ifdef EL_CUTOFF + E_el += qi * qj_f * (int_bit * inv_r - c_rf); +# endif +# ifdef EL_RF + E_el += qi * qj_f * (int_bit * inv_r + 0.5f * two_k_rf * r2 - c_rf); +# endif +# ifdef EL_EWALD_ANY /* 1.0f - erff is faster than erfcf */ - E_el += qi * qj_f * (inv_r * (int_bit - erff(r2 * inv_r * beta)) - int_bit * ewald_shift); -#endif /* EL_EWALD_ANY */ -#endif - f_ij = rv * F_invr; + E_el += qi * qj_f + * (inv_r * (int_bit - erff(r2 * inv_r * beta)) - int_bit * ewald_shift); +# endif /* EL_EWALD_ANY */ +# endif + f_ij = rv * F_invr; /* accumulate j forces in registers */ fcj_buf -= f_ij; @@ -602,11 +609,11 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) reduce_force_j_warp_shfl(fcj_buf, f, tidxi, aj, c_fullWarpMask); } } -#ifdef PRUNE_NBL +# ifdef PRUNE_NBL /* Update the imask with the new one which does not contain the out of range clusters anymore. */ pl_cj4[j4].imei[widx].imask = imask; -#endif +# endif } // avoid shared memory WAR hazards between loop iterations __syncwarp(c_fullWarpMask); @@ -623,10 +630,8 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) /* reduce i forces */ for (i = 0; i < c_numClPerSupercl; i++) { - ai = (sci * c_numClPerSupercl + i) * c_clSize + tidxi; - reduce_force_i_warp_shfl(fci_buf[i], f, - &fshift_buf, bCalcFshift, - tidxj, ai, c_fullWarpMask); + ai = (sci * c_numClPerSupercl + i) * c_clSize + tidxi; + reduce_force_i_warp_shfl(fci_buf[i], f, &fshift_buf, bCalcFshift, tidxj, ai, c_fullWarpMask); } /* add up local shift forces into global mem, tidxj indexes x,y,z */ @@ -635,10 +640,10 @@ __global__ void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_cuda) atomicAdd(&(atdat.fshift[nb_sci.shift].x) + (tidxj & 3), fshift_buf); } -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES /* reduce the energies over warps and store into global memory */ reduce_energy_warp_shfl(E_lj, E_el, e_lj, e_el, tidx, c_fullWarpMask); -#endif +# endif } #endif /* FUNCTION_DECLARATION_ONLY */ diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cu b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cu index db718b2053..945b1912fc 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cu +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cu @@ -38,6 +38,8 @@ #ifndef FUNCTION_DECLARATION_ONLY /* Instantiate external template functions */ -template __global__ void nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); -template __global__ void nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); +template __global__ void +nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); +template __global__ void +nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); #endif diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cuh b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cuh index 99801a70d1..8570e55c0b 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cuh +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_pruneonly.cuh @@ -81,10 +81,10 @@ * are not split (much), but the rolling chunks are small; * - with large inputs NTHREAD_Z=1 is 2-3% faster (on CC>=5.0) */ -#define NTHREAD_Z (GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY) -#define THREADS_PER_BLOCK (c_clSize*c_clSize*NTHREAD_Z) +#define NTHREAD_Z (GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY) +#define THREADS_PER_BLOCK (c_clSize * c_clSize * NTHREAD_Z) // we want 100% occupancy, so max threads/block -#define MIN_BLOCKS_PER_MP (GMX_CUDA_MAX_THREADS_PER_MP/THREADS_PER_BLOCK) +#define MIN_BLOCKS_PER_MP (GMX_CUDA_MAX_THREADS_PER_MP / THREADS_PER_BLOCK) /**@}*/ /*! \brief Nonbonded list pruning kernel. @@ -101,74 +101,72 @@ * * Each thread calculates an i-j atom distance.. */ -template -__launch_bounds__(THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP) -__global__ void nbnxn_kernel_prune_cuda(const cu_atomdata_t atdat, - const cu_nbparam_t nbparam, - const cu_plist_t plist, - int numParts, - int part) +template +__launch_bounds__(THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP) __global__ + void nbnxn_kernel_prune_cuda(const cu_atomdata_t atdat, + const cu_nbparam_t nbparam, + const cu_plist_t plist, + int numParts, + int part) #ifdef FUNCTION_DECLARATION_ONLY -; /* Only do function declaration, omit the function body. */ + ; /* Only do function declaration, omit the function body. */ // Add extern declarations so each translation unit understands that // there will be a definition provided. -extern template -__global__ void -nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, - const cu_plist_t, int, int); -extern template -__global__ void -nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, - const cu_plist_t, int, int); +extern template __global__ void +nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); +extern template __global__ void +nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, const cu_plist_t, int, int); #else { /* convenience variables */ - const nbnxn_sci_t *pl_sci = plist.sci; - nbnxn_cj4_t *pl_cj4 = plist.cj4; - const float4 *xq = atdat.xq; - const float3 *shift_vec = atdat.shift_vec; + const nbnxn_sci_t* pl_sci = plist.sci; + nbnxn_cj4_t* pl_cj4 = plist.cj4; + const float4* xq = atdat.xq; + const float3* shift_vec = atdat.shift_vec; - float rlistOuter_sq = nbparam.rlistOuter_sq; - float rlistInner_sq = nbparam.rlistInner_sq; + float rlistOuter_sq = nbparam.rlistOuter_sq; + float rlistInner_sq = nbparam.rlistInner_sq; /* thread/block/warp id-s */ - unsigned int tidxi = threadIdx.x; - unsigned int tidxj = threadIdx.y; -#if NTHREAD_Z == 1 - unsigned int tidxz = 0; -#else - unsigned int tidxz = threadIdx.z; -#endif - unsigned int bidx = blockIdx.x; - unsigned int widx = (threadIdx.y * c_clSize) / warp_size; /* warp index */ + unsigned int tidxi = threadIdx.x; + unsigned int tidxj = threadIdx.y; +# if NTHREAD_Z == 1 + unsigned int tidxz = 0; +# else + unsigned int tidxz = threadIdx.z; +# endif + unsigned int bidx = blockIdx.x; + unsigned int widx = (threadIdx.y * c_clSize) / warp_size; /* warp index */ /********************************************************************* * Set up shared memory pointers. * sm_nextSlotPtr should always be updated to point to the "next slot", * that is past the last point where data has been stored. */ - extern __shared__ char sm_dynamicShmem[]; - char *sm_nextSlotPtr = sm_dynamicShmem; - static_assert(sizeof(char) == 1, "The shared memory offset calculation assumes that char is 1 byte"); + extern __shared__ char sm_dynamicShmem[]; + char* sm_nextSlotPtr = sm_dynamicShmem; + static_assert(sizeof(char) == 1, + "The shared memory offset calculation assumes that char is 1 byte"); /* shmem buffer for i x+q pre-loading */ - float4 *xib = (float4 *)sm_nextSlotPtr; + float4* xib = (float4*)sm_nextSlotPtr; sm_nextSlotPtr += (c_numClPerSupercl * c_clSize * sizeof(*xib)); /* shmem buffer for cj, for each warp separately */ - int *cjs = (int *)(sm_nextSlotPtr); + int* cjs = (int*)(sm_nextSlotPtr); /* the cjs buffer's use expects a base pointer offset for pairs of warps in the j-concurrent execution */ - cjs += tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize; + cjs += tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize; sm_nextSlotPtr += (NTHREAD_Z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(*cjs)); /*********************************************************************/ - nbnxn_sci_t nb_sci = pl_sci[bidx*numParts + part]; /* my i super-cluster's index = sciOffset + current bidx * numParts + part */ - int sci = nb_sci.sci; /* super-cluster */ - int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ - int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ + nbnxn_sci_t nb_sci = + pl_sci[bidx * numParts + part]; /* my i super-cluster's index = sciOffset + current bidx * numParts + part */ + int sci = nb_sci.sci; /* super-cluster */ + int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ + int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ if (tidxz == 0) { @@ -178,8 +176,8 @@ nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, /* We don't need q, but using float4 in shmem avoids bank conflicts. (but it also wastes L2 bandwidth). */ - float4 tmp = xq[ai]; - float4 xi = tmp + shift_vec[nb_sci.shift]; + float4 tmp = xq[ai]; + float4 xi = tmp + shift_vec[nb_sci.shift]; xib[tidxj * c_clSize + tidxi] = xi; } __syncthreads(); @@ -203,7 +201,7 @@ nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, else { /* Read the mask from the "warp-pruned" by rlistOuter mask array */ - imaskFull = plist.imask[j4*c_nbnxnGpuClusterpairSplit + widx]; + imaskFull = plist.imask[j4 * c_nbnxnGpuClusterpairSplit + widx]; /* Read the old rolling pruned mask, use as a base for new */ imaskNew = pl_cj4[j4].imei[widx].imask; /* We only need to check pairs with different mask */ @@ -215,25 +213,25 @@ nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, /* Pre-load cj into shared memory on both warps separately */ if ((tidxj == 0 || tidxj == 4) && tidxi < c_nbnxnGpuJgroupSize) { - cjs[tidxi + tidxj * c_nbnxnGpuJgroupSize/c_splitClSize] = pl_cj4[j4].cj[tidxi]; + cjs[tidxi + tidxj * c_nbnxnGpuJgroupSize / c_splitClSize] = pl_cj4[j4].cj[tidxi]; } __syncwarp(c_fullWarpMask); -#pragma unroll 4 +# pragma unroll 4 for (int jm = 0; jm < c_nbnxnGpuJgroupSize; jm++) { if (imaskCheck & (superClInteractionMask << (jm * c_numClPerSupercl))) { unsigned int mask_ji = (1U << (jm * c_numClPerSupercl)); - int cj = cjs[jm + (tidxj & 4) * c_nbnxnGpuJgroupSize/c_splitClSize]; - int aj = cj * c_clSize + tidxj; + int cj = cjs[jm + (tidxj & 4) * c_nbnxnGpuJgroupSize / c_splitClSize]; + int aj = cj * c_clSize + tidxj; /* load j atom data */ - float4 tmp = xq[aj]; - float3 xj = make_float3(tmp.x, tmp.y, tmp.z); + float4 tmp = xq[aj]; + float3 xj = make_float3(tmp.x, tmp.y, tmp.z); -#pragma unroll 8 +# pragma unroll 8 for (int i = 0; i < c_numClPerSupercl; i++) { if (imaskCheck & mask_ji) @@ -270,7 +268,7 @@ nbnxn_kernel_prune_cuda(const cu_atomdata_t, const cu_nbparam_t, if (haveFreshList) { /* copy the list pruned to rlistOuter to a separate buffer */ - plist.imask[j4*c_nbnxnGpuClusterpairSplit + widx] = imaskFull; + plist.imask[j4 * c_nbnxnGpuClusterpairSplit + widx] = imaskFull; } /* update the imask with only the pairs up to rlistInner */ plist.cj4[j4].imei[widx].imask = imaskNew; diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh index e152de7fe9..e3724d2a1d 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernel_utils.cuh @@ -56,47 +56,39 @@ #include "nbnxm_cuda_types.h" #ifndef NBNXM_CUDA_KERNEL_UTILS_CUH -#define NBNXM_CUDA_KERNEL_UTILS_CUH +# define NBNXM_CUDA_KERNEL_UTILS_CUH /*! \brief Log of the i and j cluster size. * change this together with c_clSize !*/ -static const int __device__ c_clSizeLog2 = 3; +static const int __device__ c_clSizeLog2 = 3; /*! \brief Square of cluster size. */ -static const int __device__ c_clSizeSq = c_clSize*c_clSize; +static const int __device__ c_clSizeSq = c_clSize * c_clSize; /*! \brief j-cluster size after split (4 in the current implementation). */ -static const int __device__ c_splitClSize = c_clSize/c_nbnxnGpuClusterpairSplit; +static const int __device__ c_splitClSize = c_clSize / c_nbnxnGpuClusterpairSplit; /*! \brief Stride in the force accumualation buffer */ -static const int __device__ c_fbufStride = c_clSizeSq; +static const int __device__ c_fbufStride = c_clSizeSq; /*! \brief i-cluster interaction mask for a super-cluster with all c_numClPerSupercl=8 bits set */ -static const unsigned __device__ superClInteractionMask = ((1U << c_numClPerSupercl) - 1U); +static const unsigned __device__ superClInteractionMask = ((1U << c_numClPerSupercl) - 1U); -static const float __device__ c_oneSixth = 0.16666667f; -static const float __device__ c_oneTwelveth = 0.08333333f; +static const float __device__ c_oneSixth = 0.16666667f; +static const float __device__ c_oneTwelveth = 0.08333333f; /*! Convert LJ sigma,epsilon parameters to C6,C12. */ -static __forceinline__ __device__ -void convert_sigma_epsilon_to_c6_c12(const float sigma, - const float epsilon, - float *c6, - float *c12) +static __forceinline__ __device__ void + convert_sigma_epsilon_to_c6_c12(const float sigma, const float epsilon, float* c6, float* c12) { float sigma2, sigma6; sigma2 = sigma * sigma; - sigma6 = sigma2 *sigma2 * sigma2; + sigma6 = sigma2 * sigma2 * sigma2; *c6 = epsilon * sigma6; *c12 = *c6 * sigma6; } /*! Apply force switch, force + energy version. */ -static __forceinline__ __device__ -void calculate_force_switch_F(const cu_nbparam_t nbparam, - float c6, - float c12, - float inv_r, - float r2, - float *F_invr) +static __forceinline__ __device__ void + calculate_force_switch_F(const cu_nbparam_t nbparam, float c6, float c12, float inv_r, float r2, float* F_invr) { float r, r_switch; @@ -106,24 +98,22 @@ void calculate_force_switch_F(const cu_nbparam_t nbparam, float repu_shift_V2 = nbparam.repulsion_shift.c2; float repu_shift_V3 = nbparam.repulsion_shift.c3; - r = r2 * inv_r; - r_switch = r - nbparam.rvdw_switch; - r_switch = r_switch >= 0.0f ? r_switch : 0.0f; + r = r2 * inv_r; + r_switch = r - nbparam.rvdw_switch; + r_switch = r_switch >= 0.0f ? r_switch : 0.0f; - *F_invr += - -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r + - c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r; + *F_invr += -c6 * (disp_shift_V2 + disp_shift_V3 * r_switch) * r_switch * r_switch * inv_r + + c12 * (repu_shift_V2 + repu_shift_V3 * r_switch) * r_switch * r_switch * inv_r; } /*! Apply force switch, force-only version. */ -static __forceinline__ __device__ -void calculate_force_switch_F_E(const cu_nbparam_t nbparam, - float c6, - float c12, - float inv_r, - float r2, - float *F_invr, - float *E_lj) +static __forceinline__ __device__ void calculate_force_switch_F_E(const cu_nbparam_t nbparam, + float c6, + float c12, + float inv_r, + float r2, + float* F_invr, + float* E_lj) { float r, r_switch; @@ -133,30 +123,24 @@ void calculate_force_switch_F_E(const cu_nbparam_t nbparam, float repu_shift_V2 = nbparam.repulsion_shift.c2; float repu_shift_V3 = nbparam.repulsion_shift.c3; - float disp_shift_F2 = nbparam.dispersion_shift.c2/3; - float disp_shift_F3 = nbparam.dispersion_shift.c3/4; - float repu_shift_F2 = nbparam.repulsion_shift.c2/3; - float repu_shift_F3 = nbparam.repulsion_shift.c3/4; - - r = r2 * inv_r; - r_switch = r - nbparam.rvdw_switch; - r_switch = r_switch >= 0.0f ? r_switch : 0.0f; - - *F_invr += - -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r + - c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r; - *E_lj += - c6*(disp_shift_F2 + disp_shift_F3*r_switch)*r_switch*r_switch*r_switch - - c12*(repu_shift_F2 + repu_shift_F3*r_switch)*r_switch*r_switch*r_switch; + float disp_shift_F2 = nbparam.dispersion_shift.c2 / 3; + float disp_shift_F3 = nbparam.dispersion_shift.c3 / 4; + float repu_shift_F2 = nbparam.repulsion_shift.c2 / 3; + float repu_shift_F3 = nbparam.repulsion_shift.c3 / 4; + + r = r2 * inv_r; + r_switch = r - nbparam.rvdw_switch; + r_switch = r_switch >= 0.0f ? r_switch : 0.0f; + + *F_invr += -c6 * (disp_shift_V2 + disp_shift_V3 * r_switch) * r_switch * r_switch * inv_r + + c12 * (repu_shift_V2 + repu_shift_V3 * r_switch) * r_switch * r_switch * inv_r; + *E_lj += c6 * (disp_shift_F2 + disp_shift_F3 * r_switch) * r_switch * r_switch * r_switch + - c12 * (repu_shift_F2 + repu_shift_F3 * r_switch) * r_switch * r_switch * r_switch; } /*! Apply potential switch, force-only version. */ -static __forceinline__ __device__ -void calculate_potential_switch_F(const cu_nbparam_t nbparam, - float inv_r, - float r2, - float *F_invr, - float *E_lj) +static __forceinline__ __device__ void + calculate_potential_switch_F(const cu_nbparam_t nbparam, float inv_r, float r2, float* F_invr, float* E_lj) { float r, r_switch; float sw, dsw; @@ -165,9 +149,9 @@ void calculate_potential_switch_F(const cu_nbparam_t nbparam, float switch_V3 = nbparam.vdw_switch.c3; float switch_V4 = nbparam.vdw_switch.c4; float switch_V5 = nbparam.vdw_switch.c5; - float switch_F2 = 3*nbparam.vdw_switch.c3; - float switch_F3 = 4*nbparam.vdw_switch.c4; - float switch_F4 = 5*nbparam.vdw_switch.c5; + float switch_F2 = 3 * nbparam.vdw_switch.c3; + float switch_F3 = 4 * nbparam.vdw_switch.c4; + float switch_F4 = 5 * nbparam.vdw_switch.c5; r = r2 * inv_r; r_switch = r - nbparam.rvdw_switch; @@ -175,20 +159,16 @@ void calculate_potential_switch_F(const cu_nbparam_t nbparam, /* Unlike in the F+E kernel, conditional is faster here */ if (r_switch > 0.0f) { - sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5*r_switch)*r_switch)*r_switch*r_switch*r_switch; - dsw = (switch_F2 + (switch_F3 + switch_F4*r_switch)*r_switch)*r_switch*r_switch; + sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5 * r_switch) * r_switch) * r_switch * r_switch * r_switch; + dsw = (switch_F2 + (switch_F3 + switch_F4 * r_switch) * r_switch) * r_switch * r_switch; - *F_invr = (*F_invr)*sw - inv_r*(*E_lj)*dsw; + *F_invr = (*F_invr) * sw - inv_r * (*E_lj) * dsw; } } /*! Apply potential switch, force + energy version. */ -static __forceinline__ __device__ -void calculate_potential_switch_F_E(const cu_nbparam_t nbparam, - float inv_r, - float r2, - float *F_invr, - float *E_lj) +static __forceinline__ __device__ void + calculate_potential_switch_F_E(const cu_nbparam_t nbparam, float inv_r, float r2, float* F_invr, float* E_lj) { float r, r_switch; float sw, dsw; @@ -197,20 +177,20 @@ void calculate_potential_switch_F_E(const cu_nbparam_t nbparam, float switch_V3 = nbparam.vdw_switch.c3; float switch_V4 = nbparam.vdw_switch.c4; float switch_V5 = nbparam.vdw_switch.c5; - float switch_F2 = 3*nbparam.vdw_switch.c3; - float switch_F3 = 4*nbparam.vdw_switch.c4; - float switch_F4 = 5*nbparam.vdw_switch.c5; + float switch_F2 = 3 * nbparam.vdw_switch.c3; + float switch_F3 = 4 * nbparam.vdw_switch.c4; + float switch_F4 = 5 * nbparam.vdw_switch.c5; r = r2 * inv_r; r_switch = r - nbparam.rvdw_switch; r_switch = r_switch >= 0.0f ? r_switch : 0.0f; /* Unlike in the F-only kernel, masking is faster here */ - sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5*r_switch)*r_switch)*r_switch*r_switch*r_switch; - dsw = (switch_F2 + (switch_F3 + switch_F4*r_switch)*r_switch)*r_switch*r_switch; + sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5 * r_switch) * r_switch) * r_switch * r_switch * r_switch; + dsw = (switch_F2 + (switch_F3 + switch_F4 * r_switch) * r_switch) * r_switch * r_switch; - *F_invr = (*F_invr)*sw - inv_r*(*E_lj)*dsw; - *E_lj *= sw; + *F_invr = (*F_invr) * sw - inv_r * (*E_lj) * dsw; + *E_lj *= sw; } @@ -219,78 +199,74 @@ void calculate_potential_switch_F_E(const cu_nbparam_t nbparam, * Depending on what is supported, it fetches parameters either * using direct load, texture objects, or texrefs. */ -static __forceinline__ __device__ -float calculate_lj_ewald_c6grid(const cu_nbparam_t nbparam, - int typei, - int typej) +static __forceinline__ __device__ float calculate_lj_ewald_c6grid(const cu_nbparam_t nbparam, int typei, int typej) { -#if DISABLE_CUDA_TEXTURES - return LDG(&nbparam.nbfp_comb[2*typei]) * LDG(&nbparam.nbfp_comb[2*typej]); -#else - return tex1Dfetch(nbparam.nbfp_comb_texobj, 2*typei) * tex1Dfetch(nbparam.nbfp_comb_texobj, 2*typej); -#endif /* DISABLE_CUDA_TEXTURES */ +# if DISABLE_CUDA_TEXTURES + return LDG(&nbparam.nbfp_comb[2 * typei]) * LDG(&nbparam.nbfp_comb[2 * typej]); +# else + return tex1Dfetch(nbparam.nbfp_comb_texobj, 2 * typei) + * tex1Dfetch(nbparam.nbfp_comb_texobj, 2 * typej); +# endif /* DISABLE_CUDA_TEXTURES */ } /*! Calculate LJ-PME grid force contribution with * geometric combination rule. */ -static __forceinline__ __device__ -void calculate_lj_ewald_comb_geom_F(const cu_nbparam_t nbparam, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float *F_invr) +static __forceinline__ __device__ void calculate_lj_ewald_comb_geom_F(const cu_nbparam_t nbparam, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float* F_invr) { float c6grid, inv_r6_nm, cr2, expmcr2, poly; c6grid = calculate_lj_ewald_c6grid(nbparam, typei, typej); /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = expf(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; } /*! Calculate LJ-PME grid force + energy contribution with * geometric combination rule. */ -static __forceinline__ __device__ -void calculate_lj_ewald_comb_geom_F_E(const cu_nbparam_t nbparam, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float int_bit, - float *F_invr, - float *E_lj) +static __forceinline__ __device__ void calculate_lj_ewald_comb_geom_F_E(const cu_nbparam_t nbparam, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float int_bit, + float* F_invr, + float* E_lj) { float c6grid, inv_r6_nm, cr2, expmcr2, poly, sh_mask; c6grid = calculate_lj_ewald_c6grid(nbparam, typei, typej); /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = expf(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; /* Shift should be applied only to real LJ pairs */ - sh_mask = nbparam.sh_lj_ewald*int_bit; - *E_lj += c_oneSixth*c6grid*(inv_r6_nm*(1.0f - expmcr2*poly) + sh_mask); + sh_mask = nbparam.sh_lj_ewald * int_bit; + *E_lj += c_oneSixth * c6grid * (inv_r6_nm * (1.0f - expmcr2 * poly) + sh_mask); } /*! Fetch per-type LJ parameters. @@ -298,21 +274,19 @@ void calculate_lj_ewald_comb_geom_F_E(const cu_nbparam_t nbparam, * Depending on what is supported, it fetches parameters either * using direct load, texture objects, or texrefs. */ -static __forceinline__ __device__ -float2 fetch_nbfp_comb_c6_c12(const cu_nbparam_t nbparam, - int type) +static __forceinline__ __device__ float2 fetch_nbfp_comb_c6_c12(const cu_nbparam_t nbparam, int type) { float2 c6c12; -#if DISABLE_CUDA_TEXTURES +# if DISABLE_CUDA_TEXTURES /* Force an 8-byte fetch to save a memory instruction. */ - float2 *nbfp_comb = (float2 *)nbparam.nbfp_comb; - c6c12 = LDG(&nbfp_comb[type]); -#else + float2* nbfp_comb = (float2*)nbparam.nbfp_comb; + c6c12 = LDG(&nbfp_comb[type]); +# else /* NOTE: as we always do 8-byte aligned loads, we could fetch float2 here too just as above. */ - c6c12.x = tex1Dfetch(nbparam.nbfp_comb_texobj, 2*type); - c6c12.y = tex1Dfetch(nbparam.nbfp_comb_texobj, 2*type + 1); -#endif /* DISABLE_CUDA_TEXTURES */ + c6c12.x = tex1Dfetch(nbparam.nbfp_comb_texobj, 2 * type); + c6c12.y = tex1Dfetch(nbparam.nbfp_comb_texobj, 2 * type + 1); +# endif /* DISABLE_CUDA_TEXTURES */ return c6c12; } @@ -323,17 +297,16 @@ float2 fetch_nbfp_comb_c6_c12(const cu_nbparam_t nbparam, * We use a single F+E kernel with conditional because the performance impact * of this is pretty small and LB on the CPU is anyway very slow. */ -static __forceinline__ __device__ -void calculate_lj_ewald_comb_LB_F_E(const cu_nbparam_t nbparam, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float int_bit, - float *F_invr, - float *E_lj) +static __forceinline__ __device__ void calculate_lj_ewald_comb_LB_F_E(const cu_nbparam_t nbparam, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float int_bit, + float* F_invr, + float* E_lj) { float c6grid, inv_r6_nm, cr2, expmcr2, poly; float sigma, sigma2, epsilon; @@ -345,25 +318,25 @@ void calculate_lj_ewald_comb_LB_F_E(const cu_nbparam_t nbparam, sigma = c6c12_i.x + c6c12_j.x; epsilon = c6c12_i.y * c6c12_j.y; - sigma2 = sigma*sigma; - c6grid = epsilon*sigma2*sigma2*sigma2; + sigma2 = sigma * sigma; + c6grid = epsilon * sigma2 * sigma2 * sigma2; /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = expf(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; if (E_lj != nullptr) { float sh_mask; /* Shift should be applied only to real LJ pairs */ - sh_mask = nbparam.sh_lj_ewald*int_bit; - *E_lj += c_oneSixth*c6grid*(inv_r6_nm*(1.0f - expmcr2*poly) + sh_mask); + sh_mask = nbparam.sh_lj_ewald * int_bit; + *E_lj += c_oneSixth * c6grid * (inv_r6_nm * (1.0f - expmcr2 * poly) + sh_mask); } } @@ -373,20 +346,18 @@ void calculate_lj_ewald_comb_LB_F_E(const cu_nbparam_t nbparam, * Depending on what is supported, it fetches parameters either * using direct load, texture objects, or texrefs. */ -static __forceinline__ __device__ -float2 fetch_coulomb_force_r(const cu_nbparam_t nbparam, - int index) +static __forceinline__ __device__ float2 fetch_coulomb_force_r(const cu_nbparam_t nbparam, int index) { float2 d; -#if DISABLE_CUDA_TEXTURES +# if DISABLE_CUDA_TEXTURES /* Can't do 8-byte fetch because some of the addresses will be misaligned. */ d.x = LDG(&nbparam.coulomb_tab[index]); d.y = LDG(&nbparam.coulomb_tab[index + 1]); -#else - d.x = tex1Dfetch(nbparam.coulomb_tab_texobj, index); - d.y = tex1Dfetch(nbparam.coulomb_tab_texobj, index + 1); -#endif // DISABLE_CUDA_TEXTURES +# else + d.x = tex1Dfetch(nbparam.coulomb_tab_texobj, index); + d.y = tex1Dfetch(nbparam.coulomb_tab_texobj, index + 1); +# endif // DISABLE_CUDA_TEXTURES return d; } @@ -398,22 +369,19 @@ float2 fetch_coulomb_force_r(const cu_nbparam_t nbparam, * fma(t, d1, fnms(t, d0, d0) * but input modifiers are designed for this and are fast. */ -template -__forceinline__ __host__ __device__ -T lerp(T d0, T d1, T t) +template +__forceinline__ __host__ __device__ T lerp(T d0, T d1, T t) { return fma(t, d1, fma(-t, d0, d0)); } /*! Interpolate Ewald coulomb force correction using the F*r table. */ -static __forceinline__ __device__ -float interpolate_coulomb_force_r(const cu_nbparam_t nbparam, - float r) +static __forceinline__ __device__ float interpolate_coulomb_force_r(const cu_nbparam_t nbparam, float r) { - float normalized = nbparam.coulomb_tab_scale * r; - int index = (int) normalized; - float fraction = normalized - index; + float normalized = nbparam.coulomb_tab_scale * r; + int index = (int)normalized; + float fraction = normalized - index; float2 d01 = fetch_coulomb_force_r(nbparam, index); @@ -425,31 +393,26 @@ float interpolate_coulomb_force_r(const cu_nbparam_t nbparam, * Depending on what is supported, it fetches parameters either * using direct load, texture objects, or texrefs. */ -static __forceinline__ __device__ -void fetch_nbfp_c6_c12(float &c6, - float &c12, - const cu_nbparam_t nbparam, - int baseIndex) +static __forceinline__ __device__ void fetch_nbfp_c6_c12(float& c6, float& c12, const cu_nbparam_t nbparam, int baseIndex) { -#if DISABLE_CUDA_TEXTURES +# if DISABLE_CUDA_TEXTURES /* Force an 8-byte fetch to save a memory instruction. */ - float2 *nbfp = (float2 *)nbparam.nbfp; + float2* nbfp = (float2*)nbparam.nbfp; float2 c6c12; c6c12 = LDG(&nbfp[baseIndex]); c6 = c6c12.x; c12 = c6c12.y; -#else +# else /* NOTE: as we always do 8-byte aligned loads, we could fetch float2 here too just as above. */ - c6 = tex1Dfetch(nbparam.nbfp_texobj, 2*baseIndex); - c12 = tex1Dfetch(nbparam.nbfp_texobj, 2*baseIndex + 1); -#endif // DISABLE_CUDA_TEXTURES + c6 = tex1Dfetch(nbparam.nbfp_texobj, 2 * baseIndex); + c12 = tex1Dfetch(nbparam.nbfp_texobj, 2 * baseIndex + 1); +# endif // DISABLE_CUDA_TEXTURES } /*! Calculate analytical Ewald correction term. */ -static __forceinline__ __device__ -float pmecorrF(float z2) +static __forceinline__ __device__ float pmecorrF(float z2) { const float FN6 = -1.7357322914161492954e-8f; const float FN5 = 1.4703624142580877519e-6f; @@ -465,34 +428,33 @@ float pmecorrF(float z2) const float FD1 = 0.50736591960530292870f; const float FD0 = 1.0f; - float z4; - float polyFN0, polyFN1, polyFD0, polyFD1; + float z4; + float polyFN0, polyFN1, polyFD0, polyFD1; - z4 = z2*z2; + z4 = z2 * z2; - polyFD0 = FD4*z4 + FD2; - polyFD1 = FD3*z4 + FD1; - polyFD0 = polyFD0*z4 + FD0; - polyFD0 = polyFD1*z2 + polyFD0; + polyFD0 = FD4 * z4 + FD2; + polyFD1 = FD3 * z4 + FD1; + polyFD0 = polyFD0 * z4 + FD0; + polyFD0 = polyFD1 * z2 + polyFD0; - polyFD0 = 1.0f/polyFD0; + polyFD0 = 1.0f / polyFD0; - polyFN0 = FN6*z4 + FN4; - polyFN1 = FN5*z4 + FN3; - polyFN0 = polyFN0*z4 + FN2; - polyFN1 = polyFN1*z4 + FN1; - polyFN0 = polyFN0*z4 + FN0; - polyFN0 = polyFN1*z2 + polyFN0; + polyFN0 = FN6 * z4 + FN4; + polyFN1 = FN5 * z4 + FN3; + polyFN0 = polyFN0 * z4 + FN2; + polyFN1 = polyFN1 * z4 + FN1; + polyFN0 = polyFN0 * z4 + FN0; + polyFN0 = polyFN1 * z2 + polyFN0; - return polyFN0*polyFD0; + return polyFN0 * polyFD0; } /*! Final j-force reduction; this generic implementation works with * arbitrary array sizes. */ -static __forceinline__ __device__ -void reduce_force_j_generic(float *f_buf, float3 *fout, - int tidxi, int tidxj, int aidx) +static __forceinline__ __device__ void + reduce_force_j_generic(float* f_buf, float3* fout, int tidxi, int tidxj, int aidx) { if (tidxi < 3) { @@ -502,20 +464,18 @@ void reduce_force_j_generic(float *f_buf, float3 *fout, f += f_buf[c_fbufStride * tidxi + j]; } - atomicAdd((&fout[aidx].x)+tidxi, f); + atomicAdd((&fout[aidx].x) + tidxi, f); } } /*! Final j-force reduction; this implementation only with power of two * array sizes. */ -static __forceinline__ __device__ -void reduce_force_j_warp_shfl(float3 f, float3 *fout, - int tidxi, int aidx, - const unsigned int activemask) +static __forceinline__ __device__ void + reduce_force_j_warp_shfl(float3 f, float3* fout, int tidxi, int aidx, const unsigned int activemask) { f.x += __shfl_down_sync(activemask, f.x, 1); - f.y += __shfl_up_sync (activemask, f.y, 1); + f.y += __shfl_up_sync(activemask, f.y, 1); f.z += __shfl_down_sync(activemask, f.z, 1); if (tidxi & 1) @@ -524,7 +484,7 @@ void reduce_force_j_warp_shfl(float3 f, float3 *fout, } f.x += __shfl_down_sync(activemask, f.x, 2); - f.z += __shfl_up_sync (activemask, f.z, 2); + f.z += __shfl_up_sync(activemask, f.z, 2); if (tidxi & 2) { @@ -543,10 +503,13 @@ void reduce_force_j_warp_shfl(float3 f, float3 *fout, * arbitrary array sizes. * TODO: add the tidxi < 3 trick */ -static __forceinline__ __device__ -void reduce_force_i_generic(float *f_buf, float3 *fout, - float *fshift_buf, bool bCalcFshift, - int tidxi, int tidxj, int aidx) +static __forceinline__ __device__ void reduce_force_i_generic(float* f_buf, + float3* fout, + float* fshift_buf, + bool bCalcFshift, + int tidxi, + int tidxj, + int aidx) { if (tidxj < 3) { @@ -568,13 +531,16 @@ void reduce_force_i_generic(float *f_buf, float3 *fout, /*! Final i-force reduction; this implementation works only with power of two * array sizes. */ -static __forceinline__ __device__ -void reduce_force_i_pow2(volatile float *f_buf, float3 *fout, - float *fshift_buf, bool bCalcFshift, - int tidxi, int tidxj, int aidx) +static __forceinline__ __device__ void reduce_force_i_pow2(volatile float* f_buf, + float3* fout, + float* fshift_buf, + bool bCalcFshift, + int tidxi, + int tidxj, + int aidx) { - int i, j; - float f; + int i, j; + float f; assert(c_clSize == 1 << c_clSizeLog2); @@ -582,16 +548,18 @@ void reduce_force_i_pow2(volatile float *f_buf, float3 *fout, * every step by using c_clSize * i threads. * Can't just use i as loop variable because than nvcc refuses to unroll. */ - i = c_clSize/2; -#pragma unroll 5 + i = c_clSize / 2; +# pragma unroll 5 for (j = c_clSizeLog2 - 1; j > 0; j--) { if (tidxj < i) { - f_buf[ tidxj * c_clSize + tidxi] += f_buf[ (tidxj + i) * c_clSize + tidxi]; - f_buf[ c_fbufStride + tidxj * c_clSize + tidxi] += f_buf[ c_fbufStride + (tidxj + i) * c_clSize + tidxi]; - f_buf[2 * c_fbufStride + tidxj * c_clSize + tidxi] += f_buf[2 * c_fbufStride + (tidxj + i) * c_clSize + tidxi]; + f_buf[tidxj * c_clSize + tidxi] += f_buf[(tidxj + i) * c_clSize + tidxi]; + f_buf[c_fbufStride + tidxj * c_clSize + tidxi] += + f_buf[c_fbufStride + (tidxj + i) * c_clSize + tidxi]; + f_buf[2 * c_fbufStride + tidxj * c_clSize + tidxi] += + f_buf[2 * c_fbufStride + (tidxj + i) * c_clSize + tidxi]; } i >>= 1; } @@ -600,8 +568,7 @@ void reduce_force_i_pow2(volatile float *f_buf, float3 *fout, if (tidxj < 3) { /* tidxj*c_fbufStride selects x, y or z */ - f = f_buf[tidxj * c_fbufStride + tidxi] + - f_buf[tidxj * c_fbufStride + i * c_clSize + tidxi]; + f = f_buf[tidxj * c_fbufStride + tidxi] + f_buf[tidxj * c_fbufStride + i * c_clSize + tidxi]; atomicAdd(&(fout[aidx].x) + tidxj, f); @@ -610,16 +577,13 @@ void reduce_force_i_pow2(volatile float *f_buf, float3 *fout, *fshift_buf += f; } } - } /*! Final i-force reduction wrapper; calls the generic or pow2 reduction depending * on whether the size of the array to be reduced is power of two or not. */ -static __forceinline__ __device__ -void reduce_force_i(float *f_buf, float3 *f, - float *fshift_buf, bool bCalcFshift, - int tidxi, int tidxj, int ai) +static __forceinline__ __device__ void + reduce_force_i(float* f_buf, float3* f, float* fshift_buf, bool bCalcFshift, int tidxi, int tidxj, int ai) { if ((c_clSize & (c_clSize - 1))) { @@ -634,14 +598,16 @@ void reduce_force_i(float *f_buf, float3 *f, /*! Final i-force reduction; this implementation works only with power of two * array sizes. */ -static __forceinline__ __device__ -void reduce_force_i_warp_shfl(float3 fin, float3 *fout, - float *fshift_buf, bool bCalcFshift, - int tidxj, int aidx, - const unsigned int activemask) +static __forceinline__ __device__ void reduce_force_i_warp_shfl(float3 fin, + float3* fout, + float* fshift_buf, + bool bCalcFshift, + int tidxj, + int aidx, + const unsigned int activemask) { fin.x += __shfl_down_sync(activemask, fin.x, c_clSize); - fin.y += __shfl_up_sync (activemask, fin.y, c_clSize); + fin.y += __shfl_up_sync(activemask, fin.y, c_clSize); fin.z += __shfl_down_sync(activemask, fin.z, c_clSize); if (tidxj & 1) @@ -649,8 +615,8 @@ void reduce_force_i_warp_shfl(float3 fin, float3 *fout, fin.x = fin.y; } - fin.x += __shfl_down_sync(activemask, fin.x, 2*c_clSize); - fin.z += __shfl_up_sync (activemask, fin.z, 2*c_clSize); + fin.x += __shfl_down_sync(activemask, fin.x, 2 * c_clSize); + fin.z += __shfl_up_sync(activemask, fin.z, 2 * c_clSize); if (tidxj & 2) { @@ -672,22 +638,20 @@ void reduce_force_i_warp_shfl(float3 fin, float3 *fout, /*! Energy reduction; this implementation works only with power of two * array sizes. */ -static __forceinline__ __device__ -void reduce_energy_pow2(volatile float *buf, - float *e_lj, float *e_el, - unsigned int tidx) +static __forceinline__ __device__ void + reduce_energy_pow2(volatile float* buf, float* e_lj, float* e_el, unsigned int tidx) { - float e1, e2; + float e1, e2; - unsigned int i = warp_size/2; + unsigned int i = warp_size / 2; /* Can't just use i as loop variable because than nvcc refuses to unroll. */ -#pragma unroll 10 +# pragma unroll 10 for (int j = warp_size_log2 - 1; j > 0; j--) { if (tidx < i) { - buf[ tidx] += buf[ tidx + i]; + buf[tidx] += buf[tidx + i]; buf[c_fbufStride + tidx] += buf[c_fbufStride + tidx + i]; } i >>= 1; @@ -698,7 +662,7 @@ void reduce_energy_pow2(volatile float *buf, /* last reduction step, writing to global mem */ if (tidx == 0) { - e1 = buf[ tidx] + buf[ tidx + i]; + e1 = buf[tidx] + buf[tidx + i]; e2 = buf[c_fbufStride + tidx] + buf[c_fbufStride + tidx + i]; atomicAdd(e_lj, e1); @@ -709,21 +673,18 @@ void reduce_energy_pow2(volatile float *buf, /*! Energy reduction; this implementation works only with power of two * array sizes. */ -static __forceinline__ __device__ -void reduce_energy_warp_shfl(float E_lj, float E_el, - float *e_lj, float *e_el, - int tidx, - const unsigned int activemask) +static __forceinline__ __device__ void + reduce_energy_warp_shfl(float E_lj, float E_el, float* e_lj, float* e_el, int tidx, const unsigned int activemask) { int i, sh; sh = 1; -#pragma unroll 5 +# pragma unroll 5 for (i = 0; i < 5; i++) { E_lj += __shfl_down_sync(activemask, E_lj, sh); E_el += __shfl_down_sync(activemask, E_el, sh); - sh += sh; + sh += sh; } /* The first thread in the warp writes the reduced energies */ diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernels.cuh b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernels.cuh index 5bc27a0e98..58647c3181 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernels.cuh +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_kernels.cuh @@ -57,42 +57,42 @@ #define EL_CUTOFF /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecCut_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecCut_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -105,42 +105,42 @@ #define EL_RF /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecRF_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecRF_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -153,42 +153,42 @@ #define EL_EWALD_ANA /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEw_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEw_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -202,42 +202,42 @@ #define VDW_CUTOFF_CHECK /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwTwinCut_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwTwinCut_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -250,42 +250,42 @@ #define EL_EWALD_TAB /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTab_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTab_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -298,42 +298,42 @@ #define VDW_CUTOFF_CHECK /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJ ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJ##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJEwCombGeom ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJEwCombGeom##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJEwCombLB ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJEwCombLB##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJFsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJFsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, ...) x ## _ElecEwQSTabTwinCut_VdwLJPsw ## __VA_ARGS__ +#define NB_KERNEL_FUNC_NAME(x, ...) x##_ElecEwQSTabTwinCut_VdwLJPsw##__VA_ARGS__ #include "nbnxm_cuda_kernel.cuh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h b/src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h index 6c5043ea8b..d65d308c48 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_types.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2012, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2013-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,7 +62,7 @@ * The GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY macro allows compile-time override. */ #ifndef GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY -#define GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY 4 +# define GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY 4 #endif /*! \brief Default for the prune kernel's j4 processing concurrency. * @@ -75,7 +75,7 @@ const int c_cudaPruneKernelJ4Concurrency = GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY /*! \brief number of clusters per supercluster. */ static const int c_numClPerSupercl = c_nbnxnGpuNumClusterPerSupercluster; /*! \brief cluster size = number of atoms per cluster. */ -static const int c_clSize = c_nbnxnGpuClusterSize; +static const int c_clSize = c_nbnxnGpuClusterSize; /*! \brief Electrostatic CUDA kernel flavors. * @@ -91,8 +91,15 @@ static const int c_clSize = c_nbnxnGpuClusterSize; * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table * should match the order of enumerated types below. */ -enum eelCu { - eelCuCUT, eelCuRF, eelCuEWALD_TAB, eelCuEWALD_TAB_TWIN, eelCuEWALD_ANA, eelCuEWALD_ANA_TWIN, eelCuNR +enum eelCu +{ + eelCuCUT, + eelCuRF, + eelCuEWALD_TAB, + eelCuEWALD_TAB_TWIN, + eelCuEWALD_ANA, + eelCuEWALD_ANA_TWIN, + eelCuNR }; /*! \brief VdW CUDA kernel flavors. @@ -104,16 +111,24 @@ enum eelCu { * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table * should match the order of enumerated types below. */ -enum evdwCu { - evdwCuCUT, evdwCuCUTCOMBGEOM, evdwCuCUTCOMBLB, evdwCuFSWITCH, evdwCuPSWITCH, evdwCuEWALDGEOM, evdwCuEWALDLB, evdwCuNR +enum evdwCu +{ + evdwCuCUT, + evdwCuCUTCOMBGEOM, + evdwCuCUTCOMBLB, + evdwCuFSWITCH, + evdwCuPSWITCH, + evdwCuEWALDGEOM, + evdwCuEWALDLB, + evdwCuNR }; /* All structs prefixed with "cu_" hold data used in GPU calculations and * are passed to the kernels, except cu_timers_t. */ /*! \cond */ -typedef struct cu_atomdata cu_atomdata_t; -typedef struct cu_nbparam cu_nbparam_t; -typedef struct nb_staging nb_staging_t; +typedef struct cu_atomdata cu_atomdata_t; +typedef struct cu_nbparam cu_nbparam_t; +typedef struct nb_staging nb_staging_t; /*! \endcond */ @@ -125,9 +140,9 @@ typedef struct nb_staging nb_staging_t; */ struct nb_staging { - float *e_lj; /**< LJ energy */ - float *e_el; /**< electrostatic energy */ - float3 *fshift; /**< shift forces */ + float* e_lj; /**< LJ energy */ + float* e_el; /**< electrostatic energy */ + float3* fshift; /**< shift forces */ }; /** \internal @@ -135,24 +150,24 @@ struct nb_staging */ struct cu_atomdata { - int natoms; /**< number of atoms */ - int natoms_local; /**< number of local atoms */ - int nalloc; /**< allocation size for the atom data (xq, f) */ + int natoms; /**< number of atoms */ + int natoms_local; /**< number of local atoms */ + int nalloc; /**< allocation size for the atom data (xq, f) */ - float4 *xq; /**< atom coordinates + charges, size natoms */ - float3 *f; /**< force output array, size natoms */ + float4* xq; /**< atom coordinates + charges, size natoms */ + float3* f; /**< force output array, size natoms */ - float *e_lj; /**< LJ energy output, size 1 */ - float *e_el; /**< Electrostatics energy input, size 1 */ + float* e_lj; /**< LJ energy output, size 1 */ + float* e_el; /**< Electrostatics energy input, size 1 */ - float3 *fshift; /**< shift forces */ + float3* fshift; /**< shift forces */ - int ntypes; /**< number of atom types */ - int *atom_types; /**< atom type indices, size natoms */ - float2 *lj_comb; /**< sqrt(c6),sqrt(c12) size natoms */ + int ntypes; /**< number of atom types */ + int* atom_types; /**< atom type indices, size natoms */ + float2* lj_comb; /**< sqrt(c6),sqrt(c12) size natoms */ - float3 *shift_vec; /**< shifts */ - bool bShiftVecUploaded; /**< true if the shift vector has been uploaded */ + float3* shift_vec; /**< shifts */ + bool bShiftVecUploaded; /**< true if the shift vector has been uploaded */ }; /** \internal @@ -161,39 +176,39 @@ struct cu_atomdata struct cu_nbparam { - int eeltype; /**< type of electrostatics, takes values from #eelCu */ - int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ + int eeltype; /**< type of electrostatics, takes values from #eelCu */ + int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ - float epsfac; /**< charge multiplication factor */ - float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ - float two_k_rf; /**< Reaction-field electrostatics constant */ - float ewald_beta; /**< Ewald/PME parameter */ - float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ - float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ - float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ + float epsfac; /**< charge multiplication factor */ + float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ + float two_k_rf; /**< Reaction-field electrostatics constant */ + float ewald_beta; /**< Ewald/PME parameter */ + float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ + float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ + float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ - float rcoulomb_sq; /**< Coulomb cut-off squared */ + float rcoulomb_sq; /**< Coulomb cut-off squared */ - float rvdw_sq; /**< VdW cut-off squared */ - float rvdw_switch; /**< VdW switched cut-off */ - float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ - float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ - bool useDynamicPruning; /**< True if we use dynamic pair-list pruning */ + float rvdw_sq; /**< VdW cut-off squared */ + float rvdw_switch; /**< VdW switched cut-off */ + float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ + float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ + bool useDynamicPruning; /**< True if we use dynamic pair-list pruning */ - shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ - shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ - switch_consts_t vdw_switch; /**< VdW switch constants */ + shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ + shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ + switch_consts_t vdw_switch; /**< VdW switch constants */ /* LJ non-bonded parameters - accessed through texture memory */ - float *nbfp; /**< nonbonded parameter table with C6/C12 pairs per atom type-pair, 2*ntype^2 elements */ - cudaTextureObject_t nbfp_texobj; /**< texture object bound to nbfp */ - float *nbfp_comb; /**< nonbonded parameter table per atom type, 2*ntype elements */ - cudaTextureObject_t nbfp_comb_texobj; /**< texture object bound to nbfp_texobj */ + float* nbfp; /**< nonbonded parameter table with C6/C12 pairs per atom type-pair, 2*ntype^2 elements */ + cudaTextureObject_t nbfp_texobj; /**< texture object bound to nbfp */ + float* nbfp_comb; /**< nonbonded parameter table per atom type, 2*ntype elements */ + cudaTextureObject_t nbfp_comb_texobj; /**< texture object bound to nbfp_texobj */ /* Ewald Coulomb force table data - accessed through texture memory */ - float coulomb_tab_scale; /**< table scale/spacing */ - float *coulomb_tab; /**< pointer to the table in the device memory */ - cudaTextureObject_t coulomb_tab_texobj; /**< texture object bound to coulomb_tab */ + float coulomb_tab_scale; /**< table scale/spacing */ + float* coulomb_tab; /**< pointer to the table in the device memory */ + cudaTextureObject_t coulomb_tab_texobj; /**< texture object bound to coulomb_tab */ }; /** \internal @@ -214,53 +229,53 @@ class GpuEventSynchronizer; struct gmx_nbnxn_cuda_t { //! CUDA device information - const gmx_device_info_t *dev_info; + const gmx_device_info_t* dev_info; //! true if doing both local/non-local NB work on GPU - bool bUseTwoStreams; + bool bUseTwoStreams; //! atom data - cu_atomdata_t *atdat; + cu_atomdata_t* atdat; //! f buf ops cell index mapping - int *cell; + int* cell; //! number of indices in cell buffer - int ncell; + int ncell; //! number of indices allocated in cell buffer - int ncell_alloc; + int ncell_alloc; //! array of atom indices - int *atomIndices; + int* atomIndices; //! size of atom indices - int atomIndicesSize; + int atomIndicesSize; //! size of atom indices allocated in device buffer - int atomIndicesSize_alloc; + int atomIndicesSize_alloc; //! x buf ops num of atoms - int *cxy_na; + int* cxy_na; //! number of elements in cxy_na - int ncxy_na; + int ncxy_na; //! number of elements allocated allocated in device buffer - int ncxy_na_alloc; + int ncxy_na_alloc; //! x buf ops cell index mapping - int *cxy_ind; + int* cxy_ind; //! number of elements in cxy_ind - int ncxy_ind; + int ncxy_ind; //! number of elements allocated allocated in device buffer - int ncxy_ind_alloc; + int ncxy_ind_alloc; //! parameters required for the non-bonded calc. - cu_nbparam_t *nbparam; + cu_nbparam_t* nbparam; //! pair-list data structures (local and non-local) - gmx::EnumerationArray plist; + gmx::EnumerationArray plist; //! staging area where fshift/energies get downloaded - nb_staging_t nbst; + nb_staging_t nbst; //! local and non-local GPU streams gmx::EnumerationArray stream; /** events used for synchronization */ - cudaEvent_t nonlocal_done; /**< event triggered when the non-local non-bonded kernel - is done (and the local transfer can proceed) */ - cudaEvent_t misc_ops_and_local_H2D_done; /**< event triggered when the tasks issued in - the local stream that need to precede the - non-local force or buffer operation calculations are done - (e.g. f buffer 0-ing, local x/q H2D, buffer op - initialization in local stream that is required also - by nonlocal stream ) */ + cudaEvent_t nonlocal_done; /**< event triggered when the non-local non-bonded kernel + is done (and the local transfer can proceed) */ + cudaEvent_t misc_ops_and_local_H2D_done; /**< event triggered when the tasks issued in + the local stream that need to precede the + non-local force or buffer operation calculations are + done (e.g. f buffer 0-ing, local x/q H2D, buffer op + initialization in local stream that is required also + by nonlocal stream ) */ //! True if there has been local/nonlocal GPU work, either bonded or nonbonded, scheduled // to be executed in the current domain. As long as bonded work is not split up into @@ -271,9 +286,9 @@ struct gmx_nbnxn_cuda_t * * \note That the synchronizer is managed outside of this module in StatePropagatorDataGpu. */ - GpuEventSynchronizer *localFReductionDone; + GpuEventSynchronizer* localFReductionDone; - GpuEventSynchronizer *xNonLocalCopyD2HDone; /**< event triggered when + GpuEventSynchronizer* xNonLocalCopyD2HDone; /**< event triggered when non-local coordinate buffer has been copied from device to host*/ @@ -282,11 +297,11 @@ struct gmx_nbnxn_cuda_t * Timer init/uninit is still done even with timing off so only the condition * setting bDoTime needs to be change if this CUDA "feature" gets fixed. */ //! True if event-based timing is enabled. - bool bDoTime; + bool bDoTime; //! CUDA event-based timers. - cu_timers_t *timers; + cu_timers_t* timers; //! Timing data. TODO: deprecate this and query timers for accumulated data instead - gmx_wallclock_gpu_nbnxn_t *timings; + gmx_wallclock_gpu_nbnxn_t* timings; }; -#endif /* NBNXN_CUDA_TYPES_H */ +#endif /* NBNXN_CUDA_TYPES_H */ diff --git a/src/gromacs/nbnxm/gpu_common.h b/src/gromacs/nbnxm/gpu_common.h index 7dc72ce5e8..d209f0319a 100644 --- a/src/gromacs/nbnxm/gpu_common.h +++ b/src/gromacs/nbnxm/gpu_common.h @@ -48,11 +48,11 @@ #include #if GMX_GPU == GMX_GPU_CUDA -#include "cuda/nbnxm_cuda_types.h" +# include "cuda/nbnxm_cuda_types.h" #endif #if GMX_GPU == GMX_GPU_OPENCL -#include "opencl/nbnxm_ocl_types.h" +# include "opencl/nbnxm_ocl_types.h" #endif #include "gromacs/gpu_utils/gpu_utils.h" @@ -84,14 +84,13 @@ namespace Nbnxm * * \param[in] atomLocality atom locality specifier */ -static inline void -validateGpuAtomLocality(const AtomLocality atomLocality) +static inline void validateGpuAtomLocality(const AtomLocality atomLocality) { - std::string str = gmx::formatString("Invalid atom locality passed (%d); valid here is only " - "local (%d) or nonlocal (%d)", - static_cast(atomLocality), - static_cast(AtomLocality::Local), - static_cast(AtomLocality::NonLocal)); + std::string str = gmx::formatString( + "Invalid atom locality passed (%d); valid here is only " + "local (%d) or nonlocal (%d)", + static_cast(atomLocality), static_cast(AtomLocality::Local), + static_cast(AtomLocality::NonLocal)); GMX_ASSERT(atomLocality == AtomLocality::Local || atomLocality == AtomLocality::NonLocal, str.c_str()); } @@ -104,8 +103,7 @@ validateGpuAtomLocality(const AtomLocality atomLocality) * \param[in] atomLocality Atom locality specifier * \returns Interaction locality corresponding to the atom locality passed. */ -static inline InteractionLocality -gpuAtomToInteractionLocality(const AtomLocality atomLocality) +static inline InteractionLocality gpuAtomToInteractionLocality(const AtomLocality atomLocality) { validateGpuAtomLocality(atomLocality); @@ -126,18 +124,17 @@ gpuAtomToInteractionLocality(const AtomLocality atomLocality) //NOLINTNEXTLINE(misc-definitions-in-headers) -void setupGpuShortRangeWork(gmx_nbnxn_gpu_t *nb, - const gmx::GpuBonded *gpuBonded, - const gmx::InteractionLocality iLocality) +void setupGpuShortRangeWork(gmx_nbnxn_gpu_t* nb, + const gmx::GpuBonded* gpuBonded, + const gmx::InteractionLocality iLocality) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); // There is short-range work if the pair list for the provided // interaction locality contains entries or if there is any // bonded work (as this is not split into local/nonlocal). - nb->haveWork[iLocality] = - ((nb->plist[iLocality]->nsci != 0) || - (gpuBonded != nullptr && gpuBonded->haveInteractions())); + nb->haveWork[iLocality] = ((nb->plist[iLocality]->nsci != 0) + || (gpuBonded != nullptr && gpuBonded->haveInteractions())); } /*! \brief Returns true if there is GPU short-range work for the given interaction locality. @@ -149,16 +146,13 @@ void setupGpuShortRangeWork(gmx_nbnxn_gpu_t *nb, * \param[inout] nb Pointer to the nonbonded GPU data structure * \param[in] iLocality Interaction locality identifier */ -static bool -haveGpuShortRangeWork(const gmx_nbnxn_gpu_t &nb, - const gmx::InteractionLocality iLocality) +static bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t& nb, const gmx::InteractionLocality iLocality) { return nb.haveWork[iLocality]; } //NOLINTNEXTLINE(misc-definitions-in-headers) -bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t *nb, - const gmx::AtomLocality aLocality) +bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t* nb, const gmx::AtomLocality aLocality) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); @@ -166,7 +160,6 @@ bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t *nb, } - /*! \brief Calculate atom range and return start index and length. * * \param[in] atomData Atom descriptor data structure @@ -174,12 +167,11 @@ bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t *nb, * \param[out] atomRangeBegin Starting index of the atom range in the atom data array. * \param[out] atomRangeLen Atom range length in the atom data array. */ -template -static inline void -getGpuAtomRange(const AtomDataT *atomData, - const AtomLocality atomLocality, - int *atomRangeBegin, - int *atomRangeLen) +template +static inline void getGpuAtomRange(const AtomDataT* atomData, + const AtomLocality atomLocality, + int* atomRangeBegin, + int* atomRangeLen) { assert(atomData); validateGpuAtomLocality(atomLocality); @@ -187,13 +179,13 @@ getGpuAtomRange(const AtomDataT *atomData, /* calculate the atom data index range based on locality */ if (atomLocality == AtomLocality::Local) { - *atomRangeBegin = 0; - *atomRangeLen = atomData->natoms_local; + *atomRangeBegin = 0; + *atomRangeLen = atomData->natoms_local; } else { - *atomRangeBegin = atomData->natoms_local; - *atomRangeLen = atomData->natoms - atomData->natoms_local; + *atomRangeBegin = atomData->natoms_local; + *atomRangeLen = atomData->natoms - atomData->natoms_local; } } @@ -211,16 +203,15 @@ getGpuAtomRange(const AtomDataT *atomData, * \param[inout] timings GPU task timing data * \param[in] iloc interaction locality */ -template -static void countPruneKernelTime(GpuTimers *timers, - gmx_wallclock_gpu_nbnxn_t *timings, +template +static void countPruneKernelTime(GpuTimers* timers, + gmx_wallclock_gpu_nbnxn_t* timings, const InteractionLocality iloc) { - gpu_timers_t::Interaction &iTimers = timers->interaction[iloc]; + gpu_timers_t::Interaction& iTimers = timers->interaction[iloc]; // We might have not done any pruning (e.g. if we skipped with empty domains). - if (!iTimers.didPrune && - !iTimers.didRollingPrune) + if (!iTimers.didPrune && !iTimers.didRollingPrune) { return; } @@ -256,15 +247,14 @@ static void countPruneKernelTime(GpuTimers *timers, * \param[out] e_el Variable to accumulate electrostatic energy into * \param[out] fshift Pointer to the array of shift forces to accumulate into */ -template -static inline void -gpu_reduce_staged_outputs(const StagingData &nbst, - const InteractionLocality iLocality, - const bool reduceEnergies, - const bool reduceFshift, - real *e_lj, - real *e_el, - rvec *fshift) +template +static inline void gpu_reduce_staged_outputs(const StagingData& nbst, + const InteractionLocality iLocality, + const bool reduceEnergies, + const bool reduceFshift, + real* e_lj, + real* e_el, + rvec* fshift) { /* add up energies and shift forces (only once at local F wait) */ if (iLocality == InteractionLocality::Local) @@ -306,14 +296,13 @@ gpu_reduce_staged_outputs(const StagingData &nbst, * \param[in] doTiming True if timing is enabled. * */ -template -static inline void -gpu_accumulate_timings(gmx_wallclock_gpu_nbnxn_t *timings, - GpuTimers *timers, - const GpuPairlist *plist, - AtomLocality atomLocality, - const gmx::StepWorkload &stepWork, - bool doTiming) +template +static inline void gpu_accumulate_timings(gmx_wallclock_gpu_nbnxn_t* timings, + GpuTimers* timers, + const GpuPairlist* plist, + AtomLocality atomLocality, + const gmx::StepWorkload& stepWork, + bool doTiming) { /* timing data accumulation */ if (!doTiming) @@ -334,7 +323,7 @@ gpu_accumulate_timings(gmx_wallclock_gpu_nbnxn_t *timings, /* kernel timings */ timings->ktime[plist->haveFreshList ? 1 : 0][didEnergyKernels ? 1 : 0].t += - timers->interaction[iLocality].nb_k.getLastRangeTime(); + timers->interaction[iLocality].nb_k.getLastRangeTime(); /* X/q H2D and F D2H timings */ timings->nb_h2d_t += timers->xf[atomLocality].nb_h2d.getLastRangeTime(); @@ -373,14 +362,14 @@ gpu_accumulate_timings(gmx_wallclock_gpu_nbnxn_t *timings, * \todo Move into shared source file with gmx_compile_cpp_as_cuda */ //NOLINTNEXTLINE(misc-definitions-in-headers) -bool gpu_try_finish_task(gmx_nbnxn_gpu_t *nb, - const gmx::StepWorkload &stepWork, - const AtomLocality aloc, - real *e_lj, - real *e_el, - gmx::ArrayRef shiftForces, - GpuTaskCompletion completionKind, - gmx_wallcycle *wcycle) +bool gpu_try_finish_task(gmx_nbnxn_gpu_t* nb, + const gmx::StepWorkload& stepWork, + const AtomLocality aloc, + real* e_lj, + real* e_el, + gmx::ArrayRef shiftForces, + GpuTaskCompletion completionKind, + gmx_wallcycle* wcycle) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); @@ -395,8 +384,8 @@ bool gpu_try_finish_task(gmx_nbnxn_gpu_t *nb, // (Note that useGpuFBufferOps and computeVirial are mutually exclusive // in current code as virial steps do CPU reduction.) const bool haveResultToWaitFor = - (!stepWork.useGpuFBufferOps || - (aloc == AtomLocality::Local && (stepWork.computeEnergy || stepWork.computeVirial))); + (!stepWork.useGpuFBufferOps + || (aloc == AtomLocality::Local && (stepWork.computeEnergy || stepWork.computeVirial))); // We skip when during the non-local phase there was actually no work to do. // This is consistent with nbnxn_gpu_launch_kernel but it also considers possible @@ -442,7 +431,8 @@ bool gpu_try_finish_task(gmx_nbnxn_gpu_t *nb, } /* Always reset both pruning flags (doesn't hurt doing it even when timing is off). */ - nb->timers->interaction[iLocality].didPrune = nb->timers->interaction[iLocality].didRollingPrune = false; + nb->timers->interaction[iLocality].didPrune = + nb->timers->interaction[iLocality].didRollingPrune = false; /* Turn off initial list pruning (doesn't hurt if this is not pair-search step). */ nb->plist[iLocality]->haveFreshList = false; @@ -468,20 +458,20 @@ bool gpu_try_finish_task(gmx_nbnxn_gpu_t *nb, * \return The number of cycles the gpu wait took */ //NOLINTNEXTLINE(misc-definitions-in-headers) TODO: move into source file -float gpu_wait_finish_task(gmx_nbnxn_gpu_t *nb, - const gmx::StepWorkload &stepWork, +float gpu_wait_finish_task(gmx_nbnxn_gpu_t* nb, + const gmx::StepWorkload& stepWork, AtomLocality aloc, - real *e_lj, - real *e_el, + real* e_lj, + real* e_el, gmx::ArrayRef shiftForces, - gmx_wallcycle *wcycle) + gmx_wallcycle* wcycle) { - auto cycleCounter = - (gpuAtomToInteractionLocality(aloc) == InteractionLocality::Local) ? ewcWAIT_GPU_NB_L : ewcWAIT_GPU_NB_NL; + auto cycleCounter = (gpuAtomToInteractionLocality(aloc) == InteractionLocality::Local) + ? ewcWAIT_GPU_NB_L + : ewcWAIT_GPU_NB_NL; wallcycle_start(wcycle, cycleCounter); - gpu_try_finish_task(nb, stepWork, aloc, e_lj, e_el, shiftForces, - GpuTaskCompletion::Wait, wcycle); + gpu_try_finish_task(nb, stepWork, aloc, e_lj, e_el, shiftForces, GpuTaskCompletion::Wait, wcycle); float waitTime = wallcycle_stop(wcycle, cycleCounter); return waitTime; diff --git a/src/gromacs/nbnxm/gpu_common_utils.h b/src/gromacs/nbnxm/gpu_common_utils.h index 77d3b08e96..4c3333d82a 100644 --- a/src/gromacs/nbnxm/gpu_common_utils.h +++ b/src/gromacs/nbnxm/gpu_common_utils.h @@ -47,11 +47,11 @@ #include "gromacs/nbnxm/nbnxm.h" #if GMX_GPU == GMX_GPU_CUDA -#include "cuda/nbnxm_cuda_types.h" +# include "cuda/nbnxm_cuda_types.h" #endif #if GMX_GPU == GMX_GPU_OPENCL -#include "opencl/nbnxm_ocl_types.h" +# include "opencl/nbnxm_ocl_types.h" #endif namespace Nbnxm @@ -64,12 +64,10 @@ namespace Nbnxm * local part of the force array also depends on the non-local kernel. * The skip of the local kernel is taken care of separately. */ -static inline bool canSkipNonbondedWork(const gmx_nbnxn_gpu_t &nb, - InteractionLocality iloc) +static inline bool canSkipNonbondedWork(const gmx_nbnxn_gpu_t& nb, InteractionLocality iloc) { assert(nb.plist[iloc]); - return (iloc == InteractionLocality::NonLocal && - nb.plist[iloc]->nsci == 0); + return (iloc == InteractionLocality::NonLocal && nb.plist[iloc]->nsci == 0); } } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/gpu_data_mgmt.h b/src/gromacs/nbnxm/gpu_data_mgmt.h index 2237c3f0f6..c93c536bec 100644 --- a/src/gromacs/nbnxm/gpu_data_mgmt.h +++ b/src/gromacs/nbnxm/gpu_data_mgmt.h @@ -64,88 +64,86 @@ namespace Nbnxm /** Initializes the data structures related to GPU nonbonded calculations. */ GPU_FUNC_QUALIFIER -gmx_nbnxn_gpu_t * -gpu_init(const gmx_device_info_t gmx_unused *deviceInfo, - const interaction_const_t gmx_unused *ic, - const PairlistParams gmx_unused &listParams, - const nbnxn_atomdata_t gmx_unused *nbat, - int gmx_unused rank, - /* true if both local and non-local are done on GPU */ - gmx_bool gmx_unused bLocalAndNonlocal) GPU_FUNC_TERM_WITH_RETURN(nullptr); +gmx_nbnxn_gpu_t* gpu_init(const gmx_device_info_t gmx_unused* deviceInfo, + const interaction_const_t gmx_unused* ic, + const PairlistParams gmx_unused& listParams, + const nbnxn_atomdata_t gmx_unused* nbat, + int gmx_unused rank, + /* true if both local and non-local are done on GPU */ + gmx_bool gmx_unused bLocalAndNonlocal) GPU_FUNC_TERM_WITH_RETURN(nullptr); /** Initializes pair-list data for GPU, called at every pair search step. */ GPU_FUNC_QUALIFIER -void gpu_init_pairlist(gmx_nbnxn_gpu_t gmx_unused *nb, - const struct NbnxnPairlistGpu gmx_unused *h_nblist, - gmx::InteractionLocality gmx_unused iloc) GPU_FUNC_TERM; +void gpu_init_pairlist(gmx_nbnxn_gpu_t gmx_unused* nb, + const struct NbnxnPairlistGpu gmx_unused* h_nblist, + gmx::InteractionLocality gmx_unused iloc) GPU_FUNC_TERM; /** Initializes atom-data on the GPU, called at every pair search step. */ GPU_FUNC_QUALIFIER -void gpu_init_atomdata(gmx_nbnxn_gpu_t gmx_unused *nb, - const nbnxn_atomdata_t gmx_unused *nbat) GPU_FUNC_TERM; +void gpu_init_atomdata(gmx_nbnxn_gpu_t gmx_unused* nb, const nbnxn_atomdata_t gmx_unused* nbat) GPU_FUNC_TERM; /*! \brief Re-generate the GPU Ewald force table, resets rlist, and update the * electrostatic type switching to twin cut-off (or back) if needed. */ GPU_FUNC_QUALIFIER -void gpu_pme_loadbal_update_param(const struct nonbonded_verlet_t gmx_unused *nbv, - const interaction_const_t gmx_unused *ic) GPU_FUNC_TERM; +void gpu_pme_loadbal_update_param(const struct nonbonded_verlet_t gmx_unused* nbv, + const interaction_const_t gmx_unused* ic) GPU_FUNC_TERM; /** Uploads shift vector to the GPU if the box is dynamic (otherwise just returns). */ GPU_FUNC_QUALIFIER -void gpu_upload_shiftvec(gmx_nbnxn_gpu_t gmx_unused *nb, - const nbnxn_atomdata_t gmx_unused *nbatom) GPU_FUNC_TERM; +void gpu_upload_shiftvec(gmx_nbnxn_gpu_t gmx_unused* nb, const nbnxn_atomdata_t gmx_unused* nbatom) GPU_FUNC_TERM; /** Clears GPU outputs: nonbonded force, shift force and energy. */ GPU_FUNC_QUALIFIER -void gpu_clear_outputs(gmx_nbnxn_gpu_t gmx_unused *nb, - bool gmx_unused computeVirial) GPU_FUNC_TERM; +void gpu_clear_outputs(gmx_nbnxn_gpu_t gmx_unused* nb, bool gmx_unused computeVirial) GPU_FUNC_TERM; /** Frees all GPU resources used for the nonbonded calculations. */ GPU_FUNC_QUALIFIER -void gpu_free(gmx_nbnxn_gpu_t gmx_unused *nb) GPU_FUNC_TERM; +void gpu_free(gmx_nbnxn_gpu_t gmx_unused* nb) GPU_FUNC_TERM; /** Returns the GPU timings structure or NULL if GPU is not used or timing is off. */ GPU_FUNC_QUALIFIER -struct gmx_wallclock_gpu_nbnxn_t *gpu_get_timings(gmx_nbnxn_gpu_t gmx_unused *nb) GPU_FUNC_TERM_WITH_RETURN(nullptr); +struct gmx_wallclock_gpu_nbnxn_t* gpu_get_timings(gmx_nbnxn_gpu_t gmx_unused* nb) + GPU_FUNC_TERM_WITH_RETURN(nullptr); /** Resets nonbonded GPU timings. */ GPU_FUNC_QUALIFIER -void gpu_reset_timings(struct nonbonded_verlet_t gmx_unused *nbv) GPU_FUNC_TERM; +void gpu_reset_timings(struct nonbonded_verlet_t gmx_unused* nbv) GPU_FUNC_TERM; /** Calculates the minimum size of proximity lists to improve SM load balance * with GPU non-bonded kernels. */ GPU_FUNC_QUALIFIER -int gpu_min_ci_balanced(gmx_nbnxn_gpu_t gmx_unused *nb) GPU_FUNC_TERM_WITH_RETURN(-1); +int gpu_min_ci_balanced(gmx_nbnxn_gpu_t gmx_unused* nb) GPU_FUNC_TERM_WITH_RETURN(-1); /** Returns if analytical Ewald GPU kernels are used. */ GPU_FUNC_QUALIFIER -gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_gpu_t gmx_unused *nb) GPU_FUNC_TERM_WITH_RETURN(FALSE); +gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_gpu_t gmx_unused* nb) + GPU_FUNC_TERM_WITH_RETURN(FALSE); /** Returns an opaque pointer to the GPU command stream * Note: CUDA only. */ CUDA_FUNC_QUALIFIER -void *gpu_get_command_stream(gmx_nbnxn_gpu_t gmx_unused *nb, - gmx::InteractionLocality gmx_unused iloc) CUDA_FUNC_TERM_WITH_RETURN(nullptr); +void* gpu_get_command_stream(gmx_nbnxn_gpu_t gmx_unused* nb, gmx::InteractionLocality gmx_unused iloc) + CUDA_FUNC_TERM_WITH_RETURN(nullptr); /** Returns an opaque pointer to the GPU coordinate+charge array * Note: CUDA only. */ CUDA_FUNC_QUALIFIER -void *gpu_get_xq(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); +void* gpu_get_xq(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); /** Returns an opaque pointer to the GPU force array * Note: CUDA only. */ CUDA_FUNC_QUALIFIER -void *gpu_get_f(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); +void* gpu_get_f(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); /** Returns an opaque pointer to the GPU shift force array * Note: CUDA only. */ CUDA_FUNC_QUALIFIER -rvec *gpu_get_fshift(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); +rvec* gpu_get_fshift(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM_WITH_RETURN(nullptr); } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/gpu_jit_support.h b/src/gromacs/nbnxm/gpu_jit_support.h index 8aca815097..b784d37ce8 100644 --- a/src/gromacs/nbnxm/gpu_jit_support.h +++ b/src/gromacs/nbnxm/gpu_jit_support.h @@ -49,7 +49,6 @@ #include "gpu_types.h" /*! \brief Handles any JIT compilation of nbnxn kernels for the selected device */ -OPENCL_FUNC_QUALIFIER void - nbnxn_gpu_compile_kernels(gmx_nbnxn_gpu_t gmx_unused *nb) OPENCL_FUNC_TERM; +OPENCL_FUNC_QUALIFIER void nbnxn_gpu_compile_kernels(gmx_nbnxn_gpu_t gmx_unused* nb) OPENCL_FUNC_TERM; #endif diff --git a/src/gromacs/nbnxm/gpu_types.h b/src/gromacs/nbnxm/gpu_types.h index d875d58a15..daded17a0b 100644 --- a/src/gromacs/nbnxm/gpu_types.h +++ b/src/gromacs/nbnxm/gpu_types.h @@ -45,19 +45,19 @@ #ifndef DOXYGEN -#if GMX_GPU == GMX_GPU_OPENCL +# if GMX_GPU == GMX_GPU_OPENCL struct gmx_nbnxn_ocl_t; using gmx_nbnxn_gpu_t = gmx_nbnxn_ocl_t; -#endif +# endif -#if GMX_GPU == GMX_GPU_CUDA +# if GMX_GPU == GMX_GPU_CUDA struct gmx_nbnxn_cuda_t; using gmx_nbnxn_gpu_t = gmx_nbnxn_cuda_t; -#endif +# endif -#if GMX_GPU == GMX_GPU_NONE +# if GMX_GPU == GMX_GPU_NONE using gmx_nbnxn_gpu_t = int; -#endif +# endif #endif // !DOXYGEN diff --git a/src/gromacs/nbnxm/gpu_types_common.h b/src/gromacs/nbnxm/gpu_types_common.h index c818d534e8..0ec0c6e965 100644 --- a/src/gromacs/nbnxm/gpu_types_common.h +++ b/src/gromacs/nbnxm/gpu_types_common.h @@ -50,11 +50,11 @@ #include "pairlist.h" #if GMX_GPU == GMX_GPU_OPENCL -#include "gromacs/gpu_utils/gpuregiontimer_ocl.h" +# include "gromacs/gpu_utils/gpuregiontimer_ocl.h" #endif #if GMX_GPU == GMX_GPU_CUDA -#include "gromacs/gpu_utils/gpuregiontimer.cuh" +# include "gromacs/gpu_utils/gpuregiontimer.cuh" #endif namespace Nbnxm @@ -85,34 +85,35 @@ struct gpu_timers_t */ struct Interaction { - GpuRegionTimer pl_h2d; /**< timer for pair-list H2D transfers (l/nl, every PS step) */ - bool didPairlistH2D = false; /**< true when a pair-list transfer has been done at this step */ - GpuRegionTimer nb_k; /**< timer for non-bonded kernels (l/nl, every step) */ - GpuRegionTimer prune_k; /**< timer for the 1st pass list pruning kernel (l/nl, every PS step) */ - bool didPrune = false; /**< true when we timed pruning and the timings need to be accounted for */ - GpuRegionTimer rollingPrune_k; /**< timer for rolling pruning kernels (l/nl, frequency depends on chunk size) */ - bool didRollingPrune = false; /**< true when we timed rolling pruning (at the previous step) and the timings need to be accounted for */ + GpuRegionTimer pl_h2d; /**< timer for pair-list H2D transfers (l/nl, every PS step) */ + bool didPairlistH2D = false; /**< true when a pair-list transfer has been done at this step */ + GpuRegionTimer nb_k; /**< timer for non-bonded kernels (l/nl, every step) */ + GpuRegionTimer prune_k; /**< timer for the 1st pass list pruning kernel (l/nl, every PS step) */ + bool didPrune = false; /**< true when we timed pruning and the timings need to be accounted for */ + GpuRegionTimer rollingPrune_k; /**< timer for rolling pruning kernels (l/nl, frequency depends on chunk size) */ + bool didRollingPrune = + false; /**< true when we timed rolling pruning (at the previous step) and the timings need to be accounted for */ }; //! timer for atom data transfer (every PS step) - GpuRegionTimer atdat; + GpuRegionTimer atdat; //! timers for coordinate/force transfers (every step) - gmx::EnumerationArray xf; + gmx::EnumerationArray xf; //! timers for interaction related transfers gmx::EnumerationArray interaction; }; struct gpu_plist { - int na_c; /**< number of atoms per cluster */ + int na_c; /**< number of atoms per cluster */ - int nsci; /**< size of sci, # of i clusters in the list */ - int sci_nalloc; /**< allocation size of sci */ - DeviceBuffer sci; /**< list of i-cluster ("super-clusters") */ + int nsci; /**< size of sci, # of i clusters in the list */ + int sci_nalloc; /**< allocation size of sci */ + DeviceBuffer sci; /**< list of i-cluster ("super-clusters") */ - int ncj4; /**< total # of 4*j clusters */ - int cj4_nalloc; /**< allocation size of cj4 */ - DeviceBuffer cj4; /**< 4*j cluster list, contains j cluster number + int ncj4; /**< total # of 4*j clusters */ + int cj4_nalloc; /**< allocation size of cj4 */ + DeviceBuffer cj4; /**< 4*j cluster list, contains j cluster number and index into the i cluster list */ int nimask; /**< # of 4*j clusters * # of warps */ int imask_nalloc; /**< allocation size of imask */ @@ -122,9 +123,9 @@ struct gpu_plist int excl_nalloc; /**< allocation size of excl */ /* parameter+variables for normal and rolling pruning */ - bool haveFreshList; /**< true after search, indictes that initial pruning with outer prunning is needed */ - int rollingPruningNumParts; /**< the number of parts/steps over which one cyle of roling pruning takes places */ - int rollingPruningPart; /**< the next part to which the roling pruning needs to be applied */ + bool haveFreshList; /**< true after search, indictes that initial pruning with outer prunning is needed */ + int rollingPruningNumParts; /**< the number of parts/steps over which one cyle of roling pruning takes places */ + int rollingPruningPart; /**< the next part to which the roling pruning needs to be applied */ }; } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/grid.cpp b/src/gromacs/nbnxm/grid.cpp index 5c1bcaa248..8843dc6634 100644 --- a/src/gromacs/nbnxm/grid.cpp +++ b/src/gromacs/nbnxm/grid.cpp @@ -72,22 +72,19 @@ Grid::Geometry::Geometry(const PairlistType pairlistType) : isSimple(pairlistType != PairlistType::HierarchicalNxN), numAtomsICluster(IClusterSizePerListType[pairlistType]), numAtomsJCluster(JClusterSizePerListType[pairlistType]), - numAtomsPerCell((isSimple ? 1 : c_gpuNumClusterPerCell)*numAtomsICluster), + numAtomsPerCell((isSimple ? 1 : c_gpuNumClusterPerCell) * numAtomsICluster), numAtomsICluster2Log(get_2log(numAtomsICluster)) { } -Grid::Grid(const PairlistType pairlistType, - const bool &haveFep) : +Grid::Grid(const PairlistType pairlistType, const bool& haveFep) : geometry_(pairlistType), haveFep_(haveFep) { } /*! \brief Returns the atom density (> 0) of a rectangular grid */ -static real gridAtomDensity(int numAtoms, - const rvec lowerCorner, - const rvec upperCorner) +static real gridAtomDensity(int numAtoms, const rvec lowerCorner, const rvec upperCorner) { rvec size; @@ -99,17 +96,17 @@ static real gridAtomDensity(int numAtoms, rvec_sub(upperCorner, lowerCorner, size); - return static_cast(numAtoms)/(size[XX]*size[YY]*size[ZZ]); + return static_cast(numAtoms) / (size[XX] * size[YY] * size[ZZ]); } -void Grid::setDimensions(const int ddZone, - const int numAtoms, - gmx::RVec lowerCorner, - gmx::RVec upperCorner, - real atomDensity, - const real maxAtomGroupRadius, - const bool haveFep, - gmx::PinningPolicy pinningPolicy) +void Grid::setDimensions(const int ddZone, + const int numAtoms, + gmx::RVec lowerCorner, + gmx::RVec upperCorner, + real atomDensity, + const real maxAtomGroupRadius, + const bool haveFep, + gmx::PinningPolicy pinningPolicy) { /* We allow passing lowerCorner=upperCorner, in which case we need to * create a finite sized bounding box to avoid division by zero. @@ -119,12 +116,13 @@ void Grid::setDimensions(const int ddZone, constexpr real c_minimumGridSize = 1e-10; for (int d = 0; d < DIM; d++) { - GMX_ASSERT(upperCorner[d] >= lowerCorner[d], "Upper corner should be larger than the lower corner"); + GMX_ASSERT(upperCorner[d] >= lowerCorner[d], + "Upper corner should be larger than the lower corner"); if (upperCorner[d] - lowerCorner[d] < c_minimumGridSize) { /* Ensure we apply a correction to the bounding box */ - real correction = std::max(std::abs(lowerCorner[d])*GMX_REAL_EPS, - 0.5_real*c_minimumGridSize); + real correction = + std::max(std::abs(lowerCorner[d]) * GMX_REAL_EPS, 0.5_real * c_minimumGridSize); lowerCorner[d] -= correction; upperCorner[d] += correction; } @@ -154,27 +152,26 @@ void Grid::setDimensions(const int ddZone, /* To minimize the zero interactions, we should make * the largest of the i/j cell cubic. */ - int numAtomsInCell = std::max(geometry_.numAtomsICluster, - geometry_.numAtomsJCluster); + int numAtomsInCell = std::max(geometry_.numAtomsICluster, geometry_.numAtomsJCluster); /* Approximately cubic cells */ - real tlen = std::cbrt(numAtomsInCell/atomDensity); + real tlen = std::cbrt(numAtomsInCell / atomDensity); tlen_x = tlen; tlen_y = tlen; } else { /* Approximately cubic sub cells */ - real tlen = std::cbrt(geometry_.numAtomsICluster/atomDensity); - tlen_x = tlen*c_gpuNumClusterPerCellX; - tlen_y = tlen*c_gpuNumClusterPerCellY; + real tlen = std::cbrt(geometry_.numAtomsICluster / atomDensity); + tlen_x = tlen * c_gpuNumClusterPerCellX; + tlen_y = tlen * c_gpuNumClusterPerCellY; } /* We round ncx and ncy down, because we get less cell pairs * in the pairlist when the fixed cell dimensions (x,y) are * larger than the variable one (z) than the other way around. */ - dimensions_.numCells[XX] = std::max(1, static_cast(size[XX]/tlen_x)); - dimensions_.numCells[YY] = std::max(1, static_cast(size[YY]/tlen_y)); + dimensions_.numCells[XX] = std::max(1, static_cast(size[XX] / tlen_x)); + dimensions_.numCells[YY] = std::max(1, static_cast(size[YY] / tlen_y)); } else { @@ -184,8 +181,8 @@ void Grid::setDimensions(const int ddZone, for (int d = 0; d < DIM - 1; d++) { - dimensions_.cellSize[d] = size[d]/dimensions_.numCells[d]; - dimensions_.invCellSize[d] = 1/dimensions_.cellSize[d]; + dimensions_.cellSize[d] = size[d] / dimensions_.numCells[d]; + dimensions_.invCellSize[d] = 1 / dimensions_.cellSize[d]; } if (ddZone > 0) @@ -210,11 +207,12 @@ void Grid::setDimensions(const int ddZone, int maxNumCells; if (geometry_.numAtomsJCluster <= geometry_.numAtomsICluster) { - maxNumCells = numAtoms/geometry_.numAtomsPerCell + numColumns(); + maxNumCells = numAtoms / geometry_.numAtomsPerCell + numColumns(); } else { - maxNumCells = numAtoms/geometry_.numAtomsPerCell + numColumns()*geometry_.numAtomsJCluster/geometry_.numAtomsICluster; + maxNumCells = numAtoms / geometry_.numAtomsPerCell + + numColumns() * geometry_.numAtomsJCluster / geometry_.numAtomsICluster; } if (!geometry_.isSimple) @@ -233,9 +231,9 @@ void Grid::setDimensions(const int ddZone, else { #if NBNXN_BBXXXX - pbb_.resize(packedBoundingBoxesIndex(maxNumCells*c_gpuNumClusterPerCell)); + pbb_.resize(packedBoundingBoxesIndex(maxNumCells * c_gpuNumClusterPerCell)); #else - bb_.resize(maxNumCells*c_gpuNumClusterPerCell); + bb_.resize(maxNumCells * c_gpuNumClusterPerCell); #endif } @@ -247,19 +245,19 @@ void Grid::setDimensions(const int ddZone, { GMX_ASSERT(geometry_.isSimple, "Only CPU lists should have different i/j cluster sizes"); - bbjStorage_.resize(maxNumCells*geometry_.numAtomsICluster/geometry_.numAtomsJCluster); + bbjStorage_.resize(maxNumCells * geometry_.numAtomsICluster / geometry_.numAtomsJCluster); bbj_ = bbjStorage_; } flags_.resize(maxNumCells); if (haveFep) { - fep_.resize(maxNumCells*geometry_.numAtomsPerCell/geometry_.numAtomsICluster); + fep_.resize(maxNumCells * geometry_.numAtomsPerCell / geometry_.numAtomsICluster); } copy_rvec(lowerCorner, dimensions_.lowerCorner); copy_rvec(upperCorner, dimensions_.upperCorner); - copy_rvec(size, dimensions_.gridSize); + copy_rvec(size, dimensions_.gridSize); } /* We need to sort paricles in grid columns on z-coordinate. @@ -274,7 +272,7 @@ void Grid::setDimensions(const int ddZone, * as it can be expensive to detect imhomogeneous particle distributions. */ /*! \brief Ratio of grid cells to atoms */ -static constexpr int c_sortGridRatio = 4; +static constexpr int c_sortGridRatio = 4; /*! \brief Maximum ratio of holes used, in the worst case all particles * end up in the last hole and we need num. atoms extra holes at the end. */ @@ -290,13 +288,17 @@ static constexpr int c_sortGridMaxSizeFactor = c_sortGridRatio + 1; * sort should have a size of at least n_per_h*c_sortGridRatio + n, * or easier, allocate at least n*c_sortGridMaxSizeFactor elements. */ -static void sort_atoms(int dim, gmx_bool Backwards, +static void sort_atoms(int dim, + gmx_bool Backwards, int gmx_unused dd_zone, - bool gmx_unused relevantAtomsAreWithinGridBounds, - int *a, int n, + bool gmx_unused relevantAtomsAreWithinGridBounds, + int* a, + int n, gmx::ArrayRef x, - real h0, real invh, int n_per_h, - gmx::ArrayRef sort) + real h0, + real invh, + int n_per_h, + gmx::ArrayRef sort) { if (n <= 1) { @@ -307,12 +309,12 @@ static void sort_atoms(int dim, gmx_bool Backwards, GMX_ASSERT(n <= n_per_h, "We require n <= n_per_h"); /* Transform the inverse range height into the inverse hole height */ - invh *= n_per_h*c_sortGridRatio; + invh *= n_per_h * c_sortGridRatio; /* Set nsort to the maximum possible number of holes used. * In worst case all n elements end up in the last bin. */ - int nsort = n_per_h*c_sortGridRatio + n; + int nsort = n_per_h * c_sortGridRatio + n; /* Determine the index range used, so we can limit it for the second pass */ int zi_min = INT_MAX; @@ -325,16 +327,14 @@ static void sort_atoms(int dim, gmx_bool Backwards, * This code assumes particles are less than 1/SORT_GRID_OVERSIZE * times the box height out of the box. */ - int zi = static_cast((x[a[i]][dim] - h0)*invh); + int zi = static_cast((x[a[i]][dim] - h0) * invh); #ifndef NDEBUG /* As we can have rounding effect, we use > iso >= here */ - if (relevantAtomsAreWithinGridBounds && - (zi < 0 || (dd_zone == 0 && zi > n_per_h*c_sortGridRatio))) + if (relevantAtomsAreWithinGridBounds && (zi < 0 || (dd_zone == 0 && zi > n_per_h * c_sortGridRatio))) { - gmx_fatal(FARGS, "(int)((x[%d][%c]=%f - %f)*%f) = %d, not in 0 - %d*%d\n", - a[i], 'x'+dim, x[a[i]][dim], h0, invh, zi, - n_per_h, c_sortGridRatio); + gmx_fatal(FARGS, "(int)((x[%d][%c]=%f - %f)*%f) = %d, not in 0 - %d*%d\n", a[i], + 'x' + dim, x[a[i]][dim], h0, invh, zi, n_per_h, c_sortGridRatio); } #endif if (zi < 0) @@ -346,9 +346,9 @@ static void sort_atoms(int dim, gmx_bool Backwards, * can be far beyond the grid size, which is set by the non-bonded * cut-off distance. We sort such particles into the last cell. */ - if (zi > n_per_h*c_sortGridRatio) + if (zi > n_per_h * c_sortGridRatio) { - zi = n_per_h*c_sortGridRatio; + zi = n_per_h * c_sortGridRatio; } /* Ideally this particle should go in sort cell zi, @@ -369,9 +369,9 @@ static void sort_atoms(int dim, gmx_bool Backwards, * well-defined output order, independent of input order * to ensure binary reproducibility after restarts. */ - while (sort[zi] >= 0 && ( x[a[i]][dim] > x[sort[zi]][dim] || - (x[a[i]][dim] == x[sort[zi]][dim] && - a[i] > sort[zi]))) + while (sort[zi] >= 0 + && (x[a[i]][dim] > x[sort[zi]][dim] + || (x[a[i]][dim] == x[sort[zi]][dim] && a[i] > sort[zi]))) { zi++; } @@ -429,12 +429,12 @@ static void sort_atoms(int dim, gmx_bool Backwards, //! Returns double up to one least significant float bit smaller than x static double R2F_D(const float x) { - return static_cast(x >= 0 ? (1 - GMX_FLOAT_EPS)*x : (1 + GMX_FLOAT_EPS)*x); + return static_cast(x >= 0 ? (1 - GMX_FLOAT_EPS) * x : (1 + GMX_FLOAT_EPS) * x); } //! Returns double up to one least significant float bit larger than x static double R2F_U(const float x) { - return static_cast(x >= 0 ? (1 + GMX_FLOAT_EPS)*x : (1 - GMX_FLOAT_EPS)*x); + return static_cast(x >= 0 ? (1 + GMX_FLOAT_EPS) * x : (1 - GMX_FLOAT_EPS) * x); } #else //! Returns x @@ -450,28 +450,27 @@ static float R2F_U(const float x) #endif //! Computes the bounding box for na coordinates in order x,y,z, bb order xyz0 -static void calc_bounding_box(int na, int stride, const real *x, - BoundingBox *bb) +static void calc_bounding_box(int na, int stride, const real* x, BoundingBox* bb) { int i; real xl, xh, yl, yh, zl, zh; i = 0; - xl = x[i+XX]; - xh = x[i+XX]; - yl = x[i+YY]; - yh = x[i+YY]; - zl = x[i+ZZ]; - zh = x[i+ZZ]; + xl = x[i + XX]; + xh = x[i + XX]; + yl = x[i + YY]; + yh = x[i + YY]; + zl = x[i + ZZ]; + zh = x[i + ZZ]; i += stride; for (int j = 1; j < na; j++) { - xl = std::min(xl, x[i+XX]); - xh = std::max(xh, x[i+XX]); - yl = std::min(yl, x[i+YY]); - yh = std::max(yh, x[i+YY]); - zl = std::min(zl, x[i+ZZ]); - zh = std::max(zh, x[i+ZZ]); + xl = std::min(xl, x[i + XX]); + xh = std::max(xh, x[i + XX]); + yl = std::min(yl, x[i + YY]); + yh = std::max(yh, x[i + YY]); + zl = std::min(zl, x[i + ZZ]); + zh = std::max(zh, x[i + ZZ]); i += stride; } /* Note: possible double to float conversion here */ @@ -484,25 +483,24 @@ static void calc_bounding_box(int na, int stride, const real *x, } /*! \brief Computes the bounding box for na packed coordinates, bb order xyz0 */ -static void calc_bounding_box_x_x4(int na, const real *x, - BoundingBox *bb) +static void calc_bounding_box_x_x4(int na, const real* x, BoundingBox* bb) { real xl, xh, yl, yh, zl, zh; - xl = x[XX*c_packX4]; - xh = x[XX*c_packX4]; - yl = x[YY*c_packX4]; - yh = x[YY*c_packX4]; - zl = x[ZZ*c_packX4]; - zh = x[ZZ*c_packX4]; + xl = x[XX * c_packX4]; + xh = x[XX * c_packX4]; + yl = x[YY * c_packX4]; + yh = x[YY * c_packX4]; + zl = x[ZZ * c_packX4]; + zh = x[ZZ * c_packX4]; for (int j = 1; j < na; j++) { - xl = std::min(xl, x[j+XX*c_packX4]); - xh = std::max(xh, x[j+XX*c_packX4]); - yl = std::min(yl, x[j+YY*c_packX4]); - yh = std::max(yh, x[j+YY*c_packX4]); - zl = std::min(zl, x[j+ZZ*c_packX4]); - zh = std::max(zh, x[j+ZZ*c_packX4]); + xl = std::min(xl, x[j + XX * c_packX4]); + xh = std::max(xh, x[j + XX * c_packX4]); + yl = std::min(yl, x[j + YY * c_packX4]); + yh = std::max(yh, x[j + YY * c_packX4]); + zl = std::min(zl, x[j + ZZ * c_packX4]); + zh = std::max(zh, x[j + ZZ * c_packX4]); } /* Note: possible double to float conversion here */ bb->lower.x = R2F_D(xl); @@ -514,25 +512,24 @@ static void calc_bounding_box_x_x4(int na, const real *x, } /*! \brief Computes the bounding box for na coordinates, bb order xyz0 */ -static void calc_bounding_box_x_x8(int na, const real *x, - BoundingBox *bb) +static void calc_bounding_box_x_x8(int na, const real* x, BoundingBox* bb) { real xl, xh, yl, yh, zl, zh; - xl = x[XX*c_packX8]; - xh = x[XX*c_packX8]; - yl = x[YY*c_packX8]; - yh = x[YY*c_packX8]; - zl = x[ZZ*c_packX8]; - zh = x[ZZ*c_packX8]; + xl = x[XX * c_packX8]; + xh = x[XX * c_packX8]; + yl = x[YY * c_packX8]; + yh = x[YY * c_packX8]; + zl = x[ZZ * c_packX8]; + zh = x[ZZ * c_packX8]; for (int j = 1; j < na; j++) { - xl = std::min(xl, x[j+XX*c_packX8]); - xh = std::max(xh, x[j+XX*c_packX8]); - yl = std::min(yl, x[j+YY*c_packX8]); - yh = std::max(yh, x[j+YY*c_packX8]); - zl = std::min(zl, x[j+ZZ*c_packX8]); - zh = std::max(zh, x[j+ZZ*c_packX8]); + xl = std::min(xl, x[j + XX * c_packX8]); + xh = std::max(xh, x[j + XX * c_packX8]); + yl = std::min(yl, x[j + YY * c_packX8]); + yh = std::max(yh, x[j + YY * c_packX8]); + zl = std::min(zl, x[j + ZZ * c_packX8]); + zh = std::max(zh, x[j + ZZ * c_packX8]); } /* Note: possible double to float conversion here */ bb->lower.x = R2F_D(xl); @@ -544,9 +541,7 @@ static void calc_bounding_box_x_x8(int na, const real *x, } /*! \brief Computes the bounding box for na packed coordinates, bb order xyz0 */ -gmx_unused static void calc_bounding_box_x_x4_halves(int na, const real *x, - BoundingBox *bb, - BoundingBox *bbj) +gmx_unused static void calc_bounding_box_x_x4_halves(int na, const real* x, BoundingBox* bb, BoundingBox* bbj) { // TODO: During SIMDv2 transition only some archs use namespace (remove when done) using namespace gmx; @@ -555,7 +550,7 @@ gmx_unused static void calc_bounding_box_x_x4_halves(int na, const real *x, if (na > 2) { - calc_bounding_box_x_x4(std::min(na-2, 2), x+(c_packX4>>1), bbj+1); + calc_bounding_box_x_x4(std::min(na - 2, 2), x + (c_packX4 >> 1), bbj + 1); } else { @@ -571,16 +566,12 @@ gmx_unused static void calc_bounding_box_x_x4_halves(int na, const real *x, } #if NBNXN_SEARCH_BB_SIMD4 - store4(bb->lower.ptr(), - min(load4(bbj[0].lower.ptr()), load4(bbj[1].lower.ptr()))); - store4(bb->upper.ptr(), - max(load4(bbj[0].upper.ptr()), load4(bbj[1].upper.ptr()))); + store4(bb->lower.ptr(), min(load4(bbj[0].lower.ptr()), load4(bbj[1].lower.ptr()))); + store4(bb->upper.ptr(), max(load4(bbj[0].upper.ptr()), load4(bbj[1].upper.ptr()))); #else { - bb->lower = BoundingBox::Corner::min(bbj[0].lower, - bbj[1].lower); - bb->upper = BoundingBox::Corner::max(bbj[0].upper, - bbj[1].upper); + bb->lower = BoundingBox::Corner::min(bbj[0].lower, bbj[1].lower); + bb->upper = BoundingBox::Corner::max(bbj[0].upper, bbj[1].upper); } #endif } @@ -588,36 +579,36 @@ gmx_unused static void calc_bounding_box_x_x4_halves(int na, const real *x, #if NBNXN_BBXXXX /*! \brief Computes the bounding box for na coordinates in order xyz, bb order xxxxyyyyzzzz */ -static void calc_bounding_box_xxxx(int na, int stride, const real *x, float *bb) +static void calc_bounding_box_xxxx(int na, int stride, const real* x, float* bb) { int i; real xl, xh, yl, yh, zl, zh; i = 0; - xl = x[i+XX]; - xh = x[i+XX]; - yl = x[i+YY]; - yh = x[i+YY]; - zl = x[i+ZZ]; - zh = x[i+ZZ]; + xl = x[i + XX]; + xh = x[i + XX]; + yl = x[i + YY]; + yh = x[i + YY]; + zl = x[i + ZZ]; + zh = x[i + ZZ]; i += stride; for (int j = 1; j < na; j++) { - xl = std::min(xl, x[i+XX]); - xh = std::max(xh, x[i+XX]); - yl = std::min(yl, x[i+YY]); - yh = std::max(yh, x[i+YY]); - zl = std::min(zl, x[i+ZZ]); - zh = std::max(zh, x[i+ZZ]); + xl = std::min(xl, x[i + XX]); + xh = std::max(xh, x[i + XX]); + yl = std::min(yl, x[i + YY]); + yh = std::max(yh, x[i + YY]); + zl = std::min(zl, x[i + ZZ]); + zh = std::max(zh, x[i + ZZ]); i += stride; } /* Note: possible double to float conversion here */ - bb[0*c_packedBoundingBoxesDimSize] = R2F_D(xl); - bb[1*c_packedBoundingBoxesDimSize] = R2F_D(yl); - bb[2*c_packedBoundingBoxesDimSize] = R2F_D(zl); - bb[3*c_packedBoundingBoxesDimSize] = R2F_U(xh); - bb[4*c_packedBoundingBoxesDimSize] = R2F_U(yh); - bb[5*c_packedBoundingBoxesDimSize] = R2F_U(zh); + bb[0 * c_packedBoundingBoxesDimSize] = R2F_D(xl); + bb[1 * c_packedBoundingBoxesDimSize] = R2F_D(yl); + bb[2 * c_packedBoundingBoxesDimSize] = R2F_D(zl); + bb[3 * c_packedBoundingBoxesDimSize] = R2F_U(xh); + bb[4 * c_packedBoundingBoxesDimSize] = R2F_U(yh); + bb[5 * c_packedBoundingBoxesDimSize] = R2F_U(zh); } #endif /* NBNXN_BBXXXX */ @@ -625,13 +616,12 @@ static void calc_bounding_box_xxxx(int na, int stride, const real *x, float *bb) #if NBNXN_SEARCH_SIMD4_FLOAT_X_BB /*! \brief Computes the bounding box for na coordinates in order xyz?, bb order xyz0 */ -static void calc_bounding_box_simd4(int na, const float *x, - BoundingBox *bb) +static void calc_bounding_box_simd4(int na, const float* x, BoundingBox* bb) { // TODO: During SIMDv2 transition only some archs use namespace (remove when done) using namespace gmx; - static_assert(sizeof(BoundingBox::Corner) == GMX_SIMD4_WIDTH*sizeof(float), + static_assert(sizeof(BoundingBox::Corner) == GMX_SIMD4_WIDTH * sizeof(float), "The Corner struct should hold exactly 4 floats"); Simd4Float bb_0_S = load4(x); @@ -639,7 +629,7 @@ static void calc_bounding_box_simd4(int na, const float *x, for (int i = 1; i < na; i++) { - Simd4Float x_S = load4(x + i*GMX_SIMD4_WIDTH); + Simd4Float x_S = load4(x + i * GMX_SIMD4_WIDTH); bb_0_S = min(bb_0_S, x_S); bb_1_S = max(bb_1_S, x_S); } @@ -648,32 +638,30 @@ static void calc_bounding_box_simd4(int na, const float *x, store4(bb->upper.ptr(), bb_1_S); } -#if NBNXN_BBXXXX +# if NBNXN_BBXXXX /*! \brief Computes the bounding box for na coordinates in order xyz?, bb order xxxxyyyyzzzz */ -static void calc_bounding_box_xxxx_simd4(int na, const float *x, - BoundingBox *bb_work_aligned, - real *bb) +static void calc_bounding_box_xxxx_simd4(int na, const float* x, BoundingBox* bb_work_aligned, real* bb) { calc_bounding_box_simd4(na, x, bb_work_aligned); - bb[0*c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.x; - bb[1*c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.y; - bb[2*c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.z; - bb[3*c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.x; - bb[4*c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.y; - bb[5*c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.z; + bb[0 * c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.x; + bb[1 * c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.y; + bb[2 * c_packedBoundingBoxesDimSize] = bb_work_aligned->lower.z; + bb[3 * c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.x; + bb[4 * c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.y; + bb[5 * c_packedBoundingBoxesDimSize] = bb_work_aligned->upper.z; } -#endif /* NBNXN_BBXXXX */ +# endif /* NBNXN_BBXXXX */ #endif /* NBNXN_SEARCH_SIMD4_FLOAT_X_BB */ /*! \brief Combines pairs of consecutive bounding boxes */ -static void combine_bounding_box_pairs(const Grid &grid, - gmx::ArrayRef bb, - gmx::ArrayRef bbj) +static void combine_bounding_box_pairs(const Grid& grid, + gmx::ArrayRef bb, + gmx::ArrayRef bbj) { // TODO: During SIMDv2 transition only some archs use namespace (remove when done) using namespace gmx; @@ -690,59 +678,52 @@ static void combine_bounding_box_pairs(const Grid &grid, #if NBNXN_SEARCH_BB_SIMD4 Simd4Float min_S, max_S; - min_S = min(load4(bb[c2*2+0].lower.ptr()), - load4(bb[c2*2+1].lower.ptr())); - max_S = max(load4(bb[c2*2+0].upper.ptr()), - load4(bb[c2*2+1].upper.ptr())); + min_S = min(load4(bb[c2 * 2 + 0].lower.ptr()), load4(bb[c2 * 2 + 1].lower.ptr())); + max_S = max(load4(bb[c2 * 2 + 0].upper.ptr()), load4(bb[c2 * 2 + 1].upper.ptr())); store4(bbj[c2].lower.ptr(), min_S); store4(bbj[c2].upper.ptr(), max_S); #else - bbj[c2].lower = BoundingBox::Corner::min(bb[c2*2 + 0].lower, - bb[c2*2 + 1].lower); - bbj[c2].upper = BoundingBox::Corner::max(bb[c2*2 + 0].upper, - bb[c2*2 + 1].upper); + bbj[c2].lower = BoundingBox::Corner::min(bb[c2 * 2 + 0].lower, bb[c2 * 2 + 1].lower); + bbj[c2].upper = BoundingBox::Corner::max(bb[c2 * 2 + 0].upper, bb[c2 * 2 + 1].upper); #endif } if (((grid.numAtomsInColumn(i) + 3) >> 2) & 1) { /* The bb count in this column is odd: duplicate the last bb */ - bbj[c2].lower = bb[c2*2].lower; - bbj[c2].upper = bb[c2*2].upper; + bbj[c2].lower = bb[c2 * 2].lower; + bbj[c2].upper = bb[c2 * 2].upper; } } } /*! \brief Prints the average bb size, used for debug output */ -static void print_bbsizes_simple(FILE *fp, - const Grid &grid) +static void print_bbsizes_simple(FILE* fp, const Grid& grid) { dvec ba = { 0 }; for (int c = 0; c < grid.numCells(); c++) { - const BoundingBox &bb = grid.iBoundingBoxes()[c]; + const BoundingBox& bb = grid.iBoundingBoxes()[c]; ba[XX] += bb.upper.x - bb.lower.x; ba[YY] += bb.upper.y - bb.lower.y; ba[ZZ] += bb.upper.z - bb.lower.z; } - dsvmul(1.0/grid.numCells(), ba, ba); + dsvmul(1.0 / grid.numCells(), ba, ba); - const Grid::Dimensions &dims = grid.dimensions(); - real avgCellSizeZ = (dims.atomDensity > 0 ? grid.geometry().numAtomsICluster/(dims.atomDensity*dims.cellSize[XX]*dims.cellSize[YY]) : 0.0); + const Grid::Dimensions& dims = grid.dimensions(); + real avgCellSizeZ = + (dims.atomDensity > 0 ? grid.geometry().numAtomsICluster + / (dims.atomDensity * dims.cellSize[XX] * dims.cellSize[YY]) + : 0.0); fprintf(fp, "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n", - dims.cellSize[XX], - dims.cellSize[YY], - avgCellSizeZ, - ba[XX], ba[YY], ba[ZZ], - ba[XX]*dims.invCellSize[XX], - ba[YY]*dims.invCellSize[YY], - dims.atomDensity > 0 ? ba[ZZ]/avgCellSizeZ : 0.0); + dims.cellSize[XX], dims.cellSize[YY], avgCellSizeZ, ba[XX], ba[YY], ba[ZZ], + ba[XX] * dims.invCellSize[XX], ba[YY] * dims.invCellSize[YY], + dims.atomDensity > 0 ? ba[ZZ] / avgCellSizeZ : 0.0); } /*! \brief Prints the average bb size, used for debug output */ -static void print_bbsizes_supersub(FILE *fp, - const Grid &grid) +static void print_bbsizes_supersub(FILE* fp, const Grid& grid) { int ns; dvec ba; @@ -754,22 +735,22 @@ static void print_bbsizes_supersub(FILE *fp, #if NBNXN_BBXXXX for (int s = 0; s < grid.numClustersPerCell()[c]; s += c_packedBoundingBoxesDimSize) { - int cs_w = (c*c_gpuNumClusterPerCell + s)/c_packedBoundingBoxesDimSize; - auto boundingBoxes = grid.packedBoundingBoxes().subArray(cs_w*c_packedBoundingBoxesSize, c_packedBoundingBoxesSize); + int cs_w = (c * c_gpuNumClusterPerCell + s) / c_packedBoundingBoxesDimSize; + auto boundingBoxes = grid.packedBoundingBoxes().subArray( + cs_w * c_packedBoundingBoxesSize, c_packedBoundingBoxesSize); for (int i = 0; i < c_packedBoundingBoxesDimSize; i++) { for (int d = 0; d < DIM; d++) { - ba[d] += - boundingBoxes[(DIM + d)*c_packedBoundingBoxesDimSize + i] - - boundingBoxes[(0 + d)*c_packedBoundingBoxesDimSize + i]; + ba[d] += boundingBoxes[(DIM + d) * c_packedBoundingBoxesDimSize + i] + - boundingBoxes[(0 + d) * c_packedBoundingBoxesDimSize + i]; } } } #else for (int s = 0; s < grid.numClustersPerCell()[c]; s++) { - const BoundingBox &bb = grid.iBoundingBoxes()[c*c_gpuNumClusterPerCell + s]; + const BoundingBox& bb = grid.iBoundingBoxes()[c * c_gpuNumClusterPerCell + s]; ba[XX] += bb.upper.x - bb.lower.x; ba[YY] += bb.upper.y - bb.lower.y; ba[ZZ] += bb.upper.z - bb.lower.z; @@ -777,38 +758,40 @@ static void print_bbsizes_supersub(FILE *fp, #endif ns += grid.numClustersPerCell()[c]; } - dsvmul(1.0/ns, ba, ba); + dsvmul(1.0 / ns, ba, ba); - const Grid::Dimensions &dims = grid.dimensions(); + const Grid::Dimensions& dims = grid.dimensions(); const real avgClusterSizeZ = - (dims.atomDensity > 0 ? grid.geometry().numAtomsPerCell/(dims.atomDensity*dims.cellSize[XX]*dims.cellSize[YY]*c_gpuNumClusterPerCellZ) : 0.0); + (dims.atomDensity > 0 ? grid.geometry().numAtomsPerCell + / (dims.atomDensity * dims.cellSize[XX] + * dims.cellSize[YY] * c_gpuNumClusterPerCellZ) + : 0.0); fprintf(fp, "ns bb: grid %4.2f %4.2f %4.2f abs %4.2f %4.2f %4.2f rel %4.2f %4.2f %4.2f\n", - dims.cellSize[XX]/c_gpuNumClusterPerCellX, - dims.cellSize[YY]/c_gpuNumClusterPerCellY, - avgClusterSizeZ, - ba[XX], ba[YY], ba[ZZ], - ba[XX]*c_gpuNumClusterPerCellX*dims.invCellSize[XX], - ba[YY]*c_gpuNumClusterPerCellY*dims.invCellSize[YY], - dims.atomDensity > 0 ? ba[ZZ]/avgClusterSizeZ : 0.0); + dims.cellSize[XX] / c_gpuNumClusterPerCellX, + dims.cellSize[YY] / c_gpuNumClusterPerCellY, avgClusterSizeZ, ba[XX], ba[YY], ba[ZZ], + ba[XX] * c_gpuNumClusterPerCellX * dims.invCellSize[XX], + ba[YY] * c_gpuNumClusterPerCellY * dims.invCellSize[YY], + dims.atomDensity > 0 ? ba[ZZ] / avgClusterSizeZ : 0.0); } /*!\brief Set non-bonded interaction flags for the current cluster. * * Sorts atoms on LJ coefficients: !=0 first, ==0 at the end. */ -static void sort_cluster_on_flag(int numAtomsInCluster, - int atomStart, - int atomEnd, - const int *atinfo, - gmx::ArrayRef order, - int *flags) +static void sort_cluster_on_flag(int numAtomsInCluster, + int atomStart, + int atomEnd, + const int* atinfo, + gmx::ArrayRef order, + int* flags) { constexpr int c_maxNumAtomsInCluster = 8; int sort1[c_maxNumAtomsInCluster]; int sort2[c_maxNumAtomsInCluster]; - GMX_ASSERT(numAtomsInCluster <= c_maxNumAtomsInCluster, "Need to increase c_maxNumAtomsInCluster to support larger clusters"); + GMX_ASSERT(numAtomsInCluster <= c_maxNumAtomsInCluster, + "Need to increase c_maxNumAtomsInCluster to support larger clusters"); *flags = 0; @@ -816,10 +799,10 @@ static void sort_cluster_on_flag(int numAtomsInCluster, for (int s = atomStart; s < atomEnd; s += numAtomsInCluster) { /* Make lists for this (sub-)cell on atoms with and without LJ */ - int n1 = 0; - int n2 = 0; - gmx_bool haveQ = FALSE; - int a_lj_max = -1; + int n1 = 0; + int n2 = 0; + gmx_bool haveQ = FALSE; + int a_lj_max = -1; for (int a = s; a < std::min(s + numAtomsInCluster, atomEnd); a++) { haveQ = haveQ || GET_CGINFO_HAS_Q(atinfo[order[a]]); @@ -840,17 +823,17 @@ static void sort_cluster_on_flag(int numAtomsInCluster, { *flags |= NBNXN_CI_DO_LJ(subc); - if (2*n1 <= numAtomsInCluster) + if (2 * n1 <= numAtomsInCluster) { /* Only sort when strictly necessary. Ordering particles * Ordering particles can lead to less accurate summation * due to rounding, both for LJ and Coulomb interactions. */ - if (2*(a_lj_max - s) >= numAtomsInCluster) + if (2 * (a_lj_max - s) >= numAtomsInCluster) { for (int i = 0; i < n1; i++) { - order[atomStart + i] = sort1[i]; + order[atomStart + i] = sort1[i]; } for (int j = 0; j < n2; j++) { @@ -873,18 +856,18 @@ static void sort_cluster_on_flag(int numAtomsInCluster, * * Potentially sorts atoms and sets the interaction flags. */ -void Grid::fillCell(GridSetData *gridSetData, - nbnxn_atomdata_t *nbat, - int atomStart, - int atomEnd, - const int *atinfo, - gmx::ArrayRef x, - BoundingBox gmx_unused *bb_work_aligned) +void Grid::fillCell(GridSetData* gridSetData, + nbnxn_atomdata_t* nbat, + int atomStart, + int atomEnd, + const int* atinfo, + gmx::ArrayRef x, + BoundingBox gmx_unused* bb_work_aligned) { - const int numAtoms = atomEnd - atomStart; + const int numAtoms = atomEnd - atomStart; - const gmx::ArrayRef &cells = gridSetData->cells; - const gmx::ArrayRef &atomIndices = gridSetData->atomIndices; + const gmx::ArrayRef& cells = gridSetData->cells; + const gmx::ArrayRef& atomIndices = gridSetData->atomIndices; if (geometry_.isSimple) { @@ -901,7 +884,8 @@ void Grid::fillCell(GridSetData *gridSetData, /* Set the fep flag for perturbed atoms in this (sub-)cell */ /* The grid-local cluster/(sub-)cell index */ - int cell = atomToCluster(atomStart) - cellOffset_*(geometry_.isSimple ? 1 : c_gpuNumClusterPerCell); + int cell = atomToCluster(atomStart) + - cellOffset_ * (geometry_.isSimple ? 1 : c_gpuNumClusterPerCell); fep_[cell] = 0; for (int at = atomStart; at < atomEnd; at++) { @@ -919,20 +903,20 @@ void Grid::fillCell(GridSetData *gridSetData, } copy_rvec_to_nbat_real(atomIndices.data() + atomStart, numAtoms, geometry_.numAtomsICluster, - as_rvec_array(x.data()), - nbat->XFormat, nbat->x().data(), atomStart); + as_rvec_array(x.data()), nbat->XFormat, nbat->x().data(), atomStart); if (nbat->XFormat == nbatX4) { /* Store the bounding boxes as xyz.xyz. */ - size_t offset = atomToCluster(atomStart - cellOffset_*geometry_.numAtomsICluster); - BoundingBox *bb_ptr = bb_.data() + offset; + size_t offset = atomToCluster(atomStart - cellOffset_ * geometry_.numAtomsICluster); + BoundingBox* bb_ptr = bb_.data() + offset; #if GMX_SIMD && GMX_SIMD_REAL_WIDTH == 2 - if (2*geometry_.numAtomsJCluster == geometry_.numAtomsICluster) + if (2 * geometry_.numAtomsJCluster == geometry_.numAtomsICluster) { - calc_bounding_box_x_x4_halves(numAtoms, nbat->x().data() + atom_to_x_index(atomStart), bb_ptr, - bbj_.data() + offset*2); + calc_bounding_box_x_x4_halves(numAtoms, + nbat->x().data() + atom_to_x_index(atomStart), + bb_ptr, bbj_.data() + offset * 2); } else #endif @@ -943,8 +927,8 @@ void Grid::fillCell(GridSetData *gridSetData, else if (nbat->XFormat == nbatX8) { /* Store the bounding boxes as xyz.xyz. */ - size_t offset = atomToCluster(atomStart - cellOffset_*geometry_.numAtomsICluster); - BoundingBox *bb_ptr = bb_.data() + offset; + size_t offset = atomToCluster(atomStart - cellOffset_ * geometry_.numAtomsICluster); + BoundingBox* bb_ptr = bb_.data() + offset; calc_bounding_box_x_x8(numAtoms, nbat->x().data() + atom_to_x_index(atomStart), bb_ptr); } @@ -954,75 +938,69 @@ void Grid::fillCell(GridSetData *gridSetData, /* Store the bounding boxes in a format convenient * for SIMD4 calculations: xxxxyyyyzzzz... */ - const int clusterIndex = ((atomStart - cellOffset_*geometry_.numAtomsPerCell) >> geometry_.numAtomsICluster2Log); - float *pbb_ptr = - pbb_.data() + - packedBoundingBoxesIndex(clusterIndex) + - (clusterIndex & (c_packedBoundingBoxesDimSize - 1)); + const int clusterIndex = ((atomStart - cellOffset_ * geometry_.numAtomsPerCell) + >> geometry_.numAtomsICluster2Log); + float* pbb_ptr = pbb_.data() + packedBoundingBoxesIndex(clusterIndex) + + (clusterIndex & (c_packedBoundingBoxesDimSize - 1)); -#if NBNXN_SEARCH_SIMD4_FLOAT_X_BB +# if NBNXN_SEARCH_SIMD4_FLOAT_X_BB if (nbat->XFormat == nbatXYZQ) { GMX_ASSERT(bb_work_aligned != nullptr, "Must have valid aligned work structure"); - calc_bounding_box_xxxx_simd4(numAtoms, nbat->x().data() + atomStart*nbat->xstride, + calc_bounding_box_xxxx_simd4(numAtoms, nbat->x().data() + atomStart * nbat->xstride, bb_work_aligned, pbb_ptr); } else -#endif +# endif { - calc_bounding_box_xxxx(numAtoms, nbat->xstride, nbat->x().data() + atomStart*nbat->xstride, - pbb_ptr); + calc_bounding_box_xxxx(numAtoms, nbat->xstride, + nbat->x().data() + atomStart * nbat->xstride, pbb_ptr); } if (gmx_debug_at) { fprintf(debug, "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n", - atomToCluster(atomStart), - pbb_ptr[0*c_packedBoundingBoxesDimSize], pbb_ptr[3*c_packedBoundingBoxesDimSize], - pbb_ptr[1*c_packedBoundingBoxesDimSize], pbb_ptr[4*c_packedBoundingBoxesDimSize], - pbb_ptr[2*c_packedBoundingBoxesDimSize], pbb_ptr[5*c_packedBoundingBoxesDimSize]); + atomToCluster(atomStart), pbb_ptr[0 * c_packedBoundingBoxesDimSize], + pbb_ptr[3 * c_packedBoundingBoxesDimSize], pbb_ptr[1 * c_packedBoundingBoxesDimSize], + pbb_ptr[4 * c_packedBoundingBoxesDimSize], pbb_ptr[2 * c_packedBoundingBoxesDimSize], + pbb_ptr[5 * c_packedBoundingBoxesDimSize]); } } #endif else { /* Store the bounding boxes as xyz.xyz. */ - BoundingBox *bb_ptr = bb_.data() + atomToCluster(atomStart - cellOffset_*geometry_.numAtomsPerCell); + BoundingBox* bb_ptr = + bb_.data() + atomToCluster(atomStart - cellOffset_ * geometry_.numAtomsPerCell); - calc_bounding_box(numAtoms, nbat->xstride, nbat->x().data() + atomStart*nbat->xstride, - bb_ptr); + calc_bounding_box(numAtoms, nbat->xstride, nbat->x().data() + atomStart * nbat->xstride, bb_ptr); if (gmx_debug_at) { - int bbo = atomToCluster(atomStart - cellOffset_*geometry_.numAtomsPerCell); + int bbo = atomToCluster(atomStart - cellOffset_ * geometry_.numAtomsPerCell); fprintf(debug, "cell %4d bb %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n", - atomToCluster(atomStart), - bb_[bbo].lower.x, - bb_[bbo].lower.y, - bb_[bbo].lower.z, - bb_[bbo].upper.x, - bb_[bbo].upper.y, - bb_[bbo].upper.z); + atomToCluster(atomStart), bb_[bbo].lower.x, bb_[bbo].lower.y, bb_[bbo].lower.z, + bb_[bbo].upper.x, bb_[bbo].upper.y, bb_[bbo].upper.z); } } } -void Grid::sortColumnsCpuGeometry(GridSetData *gridSetData, +void Grid::sortColumnsCpuGeometry(GridSetData* gridSetData, int dd_zone, - const int *atinfo, + const int* atinfo, gmx::ArrayRef x, - nbnxn_atomdata_t *nbat, + nbnxn_atomdata_t* nbat, const gmx::Range columnRange, gmx::ArrayRef sort_work) { if (debug) { - fprintf(debug, "cell_offset %d sorting columns %d - %d\n", - cellOffset_, *columnRange.begin(), *columnRange.end()); + fprintf(debug, "cell_offset %d sorting columns %d - %d\n", cellOffset_, + *columnRange.begin(), *columnRange.end()); } const bool relevantAtomsAreWithinGridBounds = (dimensions_.maxAtomGroupRadius == 0); - const int numAtomsPerCell = geometry_.numAtomsPerCell; + const int numAtomsPerCell = geometry_.numAtomsPerCell; /* Sort the atoms within each x,y column in 3 dimensions */ for (int cxy : columnRange) @@ -1032,26 +1010,21 @@ void Grid::sortColumnsCpuGeometry(GridSetData *gridSetData, const int atomOffset = firstAtomInColumn(cxy); /* Sort the atoms within each x,y column on z coordinate */ - sort_atoms(ZZ, FALSE, dd_zone, - relevantAtomsAreWithinGridBounds, - gridSetData->atomIndices.data() + atomOffset, numAtoms, x, - dimensions_.lowerCorner[ZZ], - 1.0/dimensions_.gridSize[ZZ], numCellsZ*numAtomsPerCell, - sort_work); + sort_atoms(ZZ, FALSE, dd_zone, relevantAtomsAreWithinGridBounds, + gridSetData->atomIndices.data() + atomOffset, numAtoms, x, dimensions_.lowerCorner[ZZ], + 1.0 / dimensions_.gridSize[ZZ], numCellsZ * numAtomsPerCell, sort_work); /* Fill the ncz cells in this column */ const int firstCell = firstCellInColumn(cxy); int cellFilled = firstCell; for (int cellZ = 0; cellZ < numCellsZ; cellZ++) { - const int cell = firstCell + cellZ; + const int cell = firstCell + cellZ; - const int atomOffsetCell = atomOffset + cellZ*numAtomsPerCell; - const int numAtomsCell = std::min(numAtomsPerCell, numAtoms - (atomOffsetCell - atomOffset)); + const int atomOffsetCell = atomOffset + cellZ * numAtomsPerCell; + const int numAtomsCell = std::min(numAtomsPerCell, numAtoms - (atomOffsetCell - atomOffset)); - fillCell(gridSetData, nbat, - atomOffsetCell, atomOffsetCell + numAtomsCell, atinfo, x, - nullptr); + fillCell(gridSetData, nbat, atomOffsetCell, atomOffsetCell + numAtomsCell, atinfo, x, nullptr); /* This copy to bbcz is not really necessary. * But it allows to use the same grid search code @@ -1066,7 +1039,7 @@ void Grid::sortColumnsCpuGeometry(GridSetData *gridSetData, } /* Set the unused atom indices to -1 */ - for (int ind = numAtoms; ind < numCellsZ*numAtomsPerCell; ind++) + for (int ind = numAtoms; ind < numCellsZ * numAtomsPerCell; ind++) { gridSetData->atomIndices[atomOffset + ind] = -1; } @@ -1074,72 +1047,72 @@ void Grid::sortColumnsCpuGeometry(GridSetData *gridSetData, } /* Spatially sort the atoms within one grid column */ -void Grid::sortColumnsGpuGeometry(GridSetData *gridSetData, +void Grid::sortColumnsGpuGeometry(GridSetData* gridSetData, int dd_zone, - const int *atinfo, + const int* atinfo, gmx::ArrayRef x, - nbnxn_atomdata_t *nbat, + nbnxn_atomdata_t* nbat, const gmx::Range columnRange, gmx::ArrayRef sort_work) { BoundingBox bb_work_array[2]; - BoundingBox *bb_work_aligned = reinterpret_cast((reinterpret_cast(bb_work_array + 1)) & (~(static_cast(15)))); + BoundingBox* bb_work_aligned = reinterpret_cast( + (reinterpret_cast(bb_work_array + 1)) & (~(static_cast(15)))); if (debug) { - fprintf(debug, "cell_offset %d sorting columns %d - %d\n", - cellOffset_, *columnRange.begin(), *columnRange.end()); + fprintf(debug, "cell_offset %d sorting columns %d - %d\n", cellOffset_, + *columnRange.begin(), *columnRange.end()); } const bool relevantAtomsAreWithinGridBounds = (dimensions_.maxAtomGroupRadius == 0); - const int numAtomsPerCell = geometry_.numAtomsPerCell; + const int numAtomsPerCell = geometry_.numAtomsPerCell; - const int subdiv_x = geometry_.numAtomsICluster; - const int subdiv_y = c_gpuNumClusterPerCellX*subdiv_x; - const int subdiv_z = c_gpuNumClusterPerCellY*subdiv_y; + const int subdiv_x = geometry_.numAtomsICluster; + const int subdiv_y = c_gpuNumClusterPerCellX * subdiv_x; + const int subdiv_z = c_gpuNumClusterPerCellY * subdiv_y; /* Extract the atom index array that will be filled here */ - const gmx::ArrayRef &atomIndices = gridSetData->atomIndices; + const gmx::ArrayRef& atomIndices = gridSetData->atomIndices; /* Sort the atoms within each x,y column in 3 dimensions. * Loop over all columns on the x/y grid. */ for (int cxy : columnRange) { - const int gridX = cxy/dimensions_.numCells[YY]; - const int gridY = cxy - gridX*dimensions_.numCells[YY]; + const int gridX = cxy / dimensions_.numCells[YY]; + const int gridY = cxy - gridX * dimensions_.numCells[YY]; const int numAtomsInColumn = cxy_na_[cxy]; const int numCellsInColumn = cxy_ind_[cxy + 1] - cxy_ind_[cxy]; const int atomOffset = firstAtomInColumn(cxy); /* Sort the atoms within each x,y column on z coordinate */ - sort_atoms(ZZ, FALSE, dd_zone, - relevantAtomsAreWithinGridBounds, - atomIndices.data() + atomOffset, numAtomsInColumn, x, - dimensions_.lowerCorner[ZZ], - 1.0/dimensions_.gridSize[ZZ], numCellsInColumn*numAtomsPerCell, - sort_work); + sort_atoms(ZZ, FALSE, dd_zone, relevantAtomsAreWithinGridBounds, + atomIndices.data() + atomOffset, numAtomsInColumn, x, dimensions_.lowerCorner[ZZ], + 1.0 / dimensions_.gridSize[ZZ], numCellsInColumn * numAtomsPerCell, sort_work); /* This loop goes over the cells and clusters along z at once */ - for (int sub_z = 0; sub_z < numCellsInColumn*c_gpuNumClusterPerCellZ; sub_z++) + for (int sub_z = 0; sub_z < numCellsInColumn * c_gpuNumClusterPerCellZ; sub_z++) { - const int atomOffsetZ = atomOffset + sub_z*subdiv_z; - const int numAtomsZ = std::min(subdiv_z, numAtomsInColumn - (atomOffsetZ - atomOffset)); - int cz = -1; + const int atomOffsetZ = atomOffset + sub_z * subdiv_z; + const int numAtomsZ = std::min(subdiv_z, numAtomsInColumn - (atomOffsetZ - atomOffset)); + int cz = -1; /* We have already sorted on z */ if (sub_z % c_gpuNumClusterPerCellZ == 0) { - cz = sub_z/c_gpuNumClusterPerCellZ; + cz = sub_z / c_gpuNumClusterPerCellZ; const int cell = cxy_ind_[cxy] + cz; /* The number of atoms in this cell/super-cluster */ - const int numAtoms = std::min(numAtomsPerCell, numAtomsInColumn - (atomOffsetZ - atomOffset)); + const int numAtoms = + std::min(numAtomsPerCell, numAtomsInColumn - (atomOffsetZ - atomOffset)); - numClusters_[cell] = std::min(c_gpuNumClusterPerCell, - (numAtoms + geometry_.numAtomsICluster - 1)/ geometry_.numAtomsICluster); + numClusters_[cell] = + std::min(c_gpuNumClusterPerCell, (numAtoms + geometry_.numAtomsICluster - 1) + / geometry_.numAtomsICluster); /* Store the z-boundaries of the bounding box of the cell */ bbcz_[cell].lower = x[atomIndices[atomOffsetZ]][ZZ]; @@ -1149,44 +1122,40 @@ void Grid::sortColumnsGpuGeometry(GridSetData *gridSetData, if (c_gpuNumClusterPerCellY > 1) { /* Sort the atoms along y */ - sort_atoms(YY, (sub_z & 1) != 0, dd_zone, - relevantAtomsAreWithinGridBounds, + sort_atoms(YY, (sub_z & 1) != 0, dd_zone, relevantAtomsAreWithinGridBounds, atomIndices.data() + atomOffsetZ, numAtomsZ, x, - dimensions_.lowerCorner[YY] + gridY*dimensions_.cellSize[YY], - dimensions_.invCellSize[YY], subdiv_z, - sort_work); + dimensions_.lowerCorner[YY] + gridY * dimensions_.cellSize[YY], + dimensions_.invCellSize[YY], subdiv_z, sort_work); } for (int sub_y = 0; sub_y < c_gpuNumClusterPerCellY; sub_y++) { - const int atomOffsetY = atomOffsetZ + sub_y*subdiv_y; - const int numAtomsY = std::min(subdiv_y, numAtomsInColumn - (atomOffsetY - atomOffset)); + const int atomOffsetY = atomOffsetZ + sub_y * subdiv_y; + const int numAtomsY = std::min(subdiv_y, numAtomsInColumn - (atomOffsetY - atomOffset)); if (c_gpuNumClusterPerCellX > 1) { /* Sort the atoms along x */ - sort_atoms(XX, ((cz*c_gpuNumClusterPerCellY + sub_y) & 1) != 0, dd_zone, - relevantAtomsAreWithinGridBounds, - atomIndices.data() + atomOffsetY, numAtomsY, x, - dimensions_.lowerCorner[XX] + gridX*dimensions_.cellSize[XX], - dimensions_.invCellSize[XX], subdiv_y, - sort_work); + sort_atoms(XX, ((cz * c_gpuNumClusterPerCellY + sub_y) & 1) != 0, dd_zone, + relevantAtomsAreWithinGridBounds, atomIndices.data() + atomOffsetY, numAtomsY, + x, dimensions_.lowerCorner[XX] + gridX * dimensions_.cellSize[XX], + dimensions_.invCellSize[XX], subdiv_y, sort_work); } for (int sub_x = 0; sub_x < c_gpuNumClusterPerCellX; sub_x++) { - const int atomOffsetX = atomOffsetY + sub_x*subdiv_x; - const int numAtomsX = std::min(subdiv_x, numAtomsInColumn - (atomOffsetX - atomOffset)); + const int atomOffsetX = atomOffsetY + sub_x * subdiv_x; + const int numAtomsX = + std::min(subdiv_x, numAtomsInColumn - (atomOffsetX - atomOffset)); - fillCell(gridSetData, nbat, - atomOffsetX, atomOffsetX + numAtomsX, atinfo, x, + fillCell(gridSetData, nbat, atomOffsetX, atomOffsetX + numAtomsX, atinfo, x, bb_work_aligned); } } } /* Set the unused atom indices to -1 */ - for (int ind = numAtomsInColumn; ind < numCellsInColumn*numAtomsPerCell; ind++) + for (int ind = numAtomsInColumn; ind < numCellsInColumn * numAtomsPerCell; ind++) { atomIndices[atomOffset + ind] = -1; } @@ -1194,27 +1163,24 @@ void Grid::sortColumnsGpuGeometry(GridSetData *gridSetData, } /*! \brief Sets the cell index in the cell array for atom \p atomIndex and increments the atom count for the grid column */ -static void setCellAndAtomCount(gmx::ArrayRef cell, - int cellIndex, - gmx::ArrayRef cxy_na, - int atomIndex) +static void setCellAndAtomCount(gmx::ArrayRef cell, int cellIndex, gmx::ArrayRef cxy_na, int atomIndex) { - cell[atomIndex] = cellIndex; + cell[atomIndex] = cellIndex; cxy_na[cellIndex] += 1; } -void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, - const gmx::UpdateGroupsCog *updateGroupsCog, - const gmx::Range atomRange, - gmx::ArrayRef x, - const int dd_zone, - const int *move, - const int thread, - const int nthread, - gmx::ArrayRef cell, - gmx::ArrayRef cxy_na) +void Grid::calcColumnIndices(const Grid::Dimensions& gridDims, + const gmx::UpdateGroupsCog* updateGroupsCog, + const gmx::Range atomRange, + gmx::ArrayRef x, + const int dd_zone, + const int* move, + const int thread, + const int nthread, + gmx::ArrayRef cell, + gmx::ArrayRef cxy_na) { - const int numColumns = gridDims.numCells[XX]*gridDims.numCells[YY]; + const int numColumns = gridDims.numCells[XX] * gridDims.numCells[YY]; /* We add one extra cell for particles which moved during DD */ for (int i = 0; i < numColumns; i++) @@ -1222,8 +1188,8 @@ void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, cxy_na[i] = 0; } - int taskAtomStart = *atomRange.begin() + static_cast((thread + 0)*atomRange.size())/nthread; - int taskAtomEnd = *atomRange.begin() + static_cast((thread + 1)*atomRange.size())/nthread; + int taskAtomStart = *atomRange.begin() + static_cast((thread + 0) * atomRange.size()) / nthread; + int taskAtomEnd = *atomRange.begin() + static_cast((thread + 1) * atomRange.size()) / nthread; if (dd_zone == 0) { @@ -1233,29 +1199,26 @@ void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, if (move == nullptr || move[i] >= 0) { - const gmx::RVec &coord = (updateGroupsCog ? updateGroupsCog->cogForAtom(i) : x[i]); + const gmx::RVec& coord = (updateGroupsCog ? updateGroupsCog->cogForAtom(i) : x[i]); /* We need to be careful with rounding, * particles might be a few bits outside the local zone. * The int cast takes care of the lower bound, * we will explicitly take care of the upper bound. */ - int cx = static_cast((coord[XX] - gridDims.lowerCorner[XX])*gridDims.invCellSize[XX]); - int cy = static_cast((coord[YY] - gridDims.lowerCorner[YY])*gridDims.invCellSize[YY]); + int cx = static_cast((coord[XX] - gridDims.lowerCorner[XX]) + * gridDims.invCellSize[XX]); + int cy = static_cast((coord[YY] - gridDims.lowerCorner[YY]) + * gridDims.invCellSize[YY]); #ifndef NDEBUG - if (cx < 0 || cx > gridDims.numCells[XX] || - cy < 0 || cy > gridDims.numCells[YY]) + if (cx < 0 || cx > gridDims.numCells[XX] || cy < 0 || cy > gridDims.numCells[YY]) { gmx_fatal(FARGS, "grid cell cx %d cy %d out of range (max %d %d)\n" "atom %f %f %f, grid->c0 %f %f", - cx, cy, - gridDims.numCells[XX], - gridDims.numCells[YY], - x[i][XX], x[i][YY], x[i][ZZ], - gridDims.lowerCorner[XX], - gridDims.lowerCorner[YY]); + cx, cy, gridDims.numCells[XX], gridDims.numCells[YY], x[i][XX], + x[i][YY], x[i][ZZ], gridDims.lowerCorner[XX], gridDims.lowerCorner[YY]); } #endif /* Take care of potential rouding issues */ @@ -1265,7 +1228,7 @@ void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, /* For the moment cell will contain only the, grid local, * x and y indices, not z. */ - setCellAndAtomCount(cell, cx*gridDims.numCells[YY] + cy, cxy_na, i); + setCellAndAtomCount(cell, cx * gridDims.numCells[YY] + cy, cxy_na, i); } else { @@ -1281,8 +1244,8 @@ void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, /* Non-home zone */ for (int i = taskAtomStart; i < taskAtomEnd; i++) { - int cx = static_cast((x[i][XX] - gridDims.lowerCorner[XX])*gridDims.invCellSize[XX]); - int cy = static_cast((x[i][YY] - gridDims.lowerCorner[YY])*gridDims.invCellSize[YY]); + int cx = static_cast((x[i][XX] - gridDims.lowerCorner[XX]) * gridDims.invCellSize[XX]); + int cy = static_cast((x[i][YY] - gridDims.lowerCorner[YY]) * gridDims.invCellSize[YY]); /* For non-home zones there could be particles outside * the non-bonded cut-off range, which have been communicated @@ -1298,16 +1261,16 @@ void Grid::calcColumnIndices(const Grid::Dimensions &gridDims, /* For the moment cell will contain only the, grid local, * x and y indices, not z. */ - setCellAndAtomCount(cell, cx*gridDims.numCells[YY] + cy, cxy_na, i); + setCellAndAtomCount(cell, cx * gridDims.numCells[YY] + cy, cxy_na, i); } } } /*! \brief Resizes grid and atom data which depend on the number of cells */ -static void resizeForNumberOfCells(const int numNbnxnAtoms, - const int numAtomsMoved, - GridSetData *gridSetData, - nbnxn_atomdata_t *nbat) +static void resizeForNumberOfCells(const int numNbnxnAtoms, + const int numAtomsMoved, + GridSetData* gridSetData, + nbnxn_atomdata_t* nbat) { /* Note: gridSetData->cellIndices was already resized before */ @@ -1320,17 +1283,17 @@ static void resizeForNumberOfCells(const int numNbnxnAtoms, nbat->resizeCoordinateBuffer(numNbnxnAtoms); } -void Grid::setCellIndices(int ddZone, - int cellOffset, - GridSetData *gridSetData, - gmx::ArrayRef gridWork, - const gmx::Range atomRange, - const int *atinfo, - gmx::ArrayRef x, - const int numAtomsMoved, - nbnxn_atomdata_t *nbat) +void Grid::setCellIndices(int ddZone, + int cellOffset, + GridSetData* gridSetData, + gmx::ArrayRef gridWork, + const gmx::Range atomRange, + const int* atinfo, + gmx::ArrayRef x, + const int numAtomsMoved, + nbnxn_atomdata_t* nbat) { - cellOffset_ = cellOffset; + cellOffset_ = cellOffset; srcAtomBegin_ = *atomRange.begin(); srcAtomEnd_ = *atomRange.end(); @@ -1340,9 +1303,9 @@ void Grid::setCellIndices(int ddZone, const int numAtomsPerCell = geometry_.numAtomsPerCell; /* Make the cell index as a function of x and y */ - int ncz_max = 0; - int ncz = 0; - cxy_ind_[0] = 0; + int ncz_max = 0; + int ncz = 0; + cxy_ind_[0] = 0; for (int i = 0; i < numColumns() + 1; i++) { /* We set ncz_max at the beginning of the loop iso at the end @@ -1358,13 +1321,13 @@ void Grid::setCellIndices(int ddZone, { cxy_na_i += gridWork[thread].numAtomsPerColumn[i]; } - ncz = (cxy_na_i + numAtomsPerCell - 1)/numAtomsPerCell; + ncz = (cxy_na_i + numAtomsPerCell - 1) / numAtomsPerCell; if (nbat->XFormat == nbatX8) { /* Make the number of cell a multiple of 2 */ ncz = (ncz + 1) & ~1; } - cxy_ind_[i+1] = cxy_ind_[i] + ncz; + cxy_ind_[i + 1] = cxy_ind_[i] + ncz; /* Clear cxy_na_, so we can reuse the array below */ cxy_na_[i] = 0; } @@ -1377,10 +1340,8 @@ void Grid::setCellIndices(int ddZone, if (debug) { fprintf(debug, "ns na_sc %d na_c %d super-cells: %d x %d y %d z %.1f maxz %d\n", - numAtomsPerCell, geometry_.numAtomsICluster, numCellsTotal_, - dimensions_.numCells[XX], dimensions_.numCells[YY], - numCellsTotal_/(static_cast(numColumns())), - ncz_max); + numAtomsPerCell, geometry_.numAtomsICluster, numCellsTotal_, dimensions_.numCells[XX], + dimensions_.numCells[YY], numCellsTotal_ / (static_cast(numColumns())), ncz_max); if (gmx_debug_at) { int i = 0; @@ -1397,10 +1358,10 @@ void Grid::setCellIndices(int ddZone, } /* Make sure the work array for sorting is large enough */ - const int worstCaseSortBufferSize = ncz_max*numAtomsPerCell*c_sortGridMaxSizeFactor; + const int worstCaseSortBufferSize = ncz_max * numAtomsPerCell * c_sortGridMaxSizeFactor; if (worstCaseSortBufferSize > gmx::index(gridWork[0].sortBuffer.size())) { - for (GridWork &work : gridWork) + for (GridWork& work : gridWork) { /* Elements not in use should be -1 */ work.sortBuffer.resize(worstCaseSortBufferSize, -1); @@ -1415,15 +1376,15 @@ void Grid::setCellIndices(int ddZone, for (int i : atomRange) { /* At this point nbs->cell contains the local grid x,y indices */ - const int cxy = cells[i]; + const int cxy = cells[i]; atomIndices[firstAtomInColumn(cxy) + cxy_na_[cxy]++] = i; } if (ddZone == 0) { /* Set the cell indices for the moved particles */ - int n0 = numCellsTotal_*numAtomsPerCell; - int n1 = numCellsTotal_*numAtomsPerCell + cxy_na_[numColumns()]; + int n0 = numCellsTotal_ * numAtomsPerCell; + int n1 = numCellsTotal_ * numAtomsPerCell + cxy_na_[numColumns()]; for (int i = n0; i < n1; i++) { cells[atomIndices[i]] = i; @@ -1436,24 +1397,20 @@ void Grid::setCellIndices(int ddZone, { try { - gmx::Range columnRange(((thread + 0)*numColumns())/nthread, - ((thread + 1)*numColumns())/nthread); + gmx::Range columnRange(((thread + 0) * numColumns()) / nthread, + ((thread + 1) * numColumns()) / nthread); if (geometry_.isSimple) { - sortColumnsCpuGeometry(gridSetData, ddZone, - atinfo, x, nbat, - columnRange, + sortColumnsCpuGeometry(gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer); } else { - sortColumnsGpuGeometry(gridSetData, ddZone, - atinfo, x, nbat, - columnRange, + sortColumnsGpuGeometry(gridSetData, ddZone, atinfo, x, nbat, columnRange, gridWork[thread].sortBuffer); } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (geometry_.isSimple && nbat->XFormat == nbatX8) @@ -1478,9 +1435,8 @@ void Grid::setCellIndices(int ddZone, } else { - fprintf(debug, "ns non-zero sub-cells: %d average atoms %.2f\n", - numClustersTotal_, - atomRange.size()/static_cast(numClustersTotal_)); + fprintf(debug, "ns non-zero sub-cells: %d average atoms %.2f\n", numClustersTotal_, + atomRange.size() / static_cast(numClustersTotal_)); print_bbsizes_supersub(debug, *this); } diff --git a/src/gromacs/nbnxm/grid.h b/src/gromacs/nbnxm/grid.h index 008d0d3944..a8326a3bec 100644 --- a/src/gromacs/nbnxm/grid.h +++ b/src/gromacs/nbnxm/grid.h @@ -91,14 +91,13 @@ struct BoundingBox struct Corner { //! Returns a corner with the minimum coordinates along each dimension - static Corner min(const Corner &c1, - const Corner &c2) + static Corner min(const Corner& c1, const Corner& c2) { Corner cMin; - cMin.x = std::min(c1.x, c2.x); - cMin.y = std::min(c1.y, c2.y); - cMin.z = std::min(c1.z, c2.z); + cMin.x = std::min(c1.x, c2.x); + cMin.y = std::min(c1.y, c2.y); + cMin.z = std::min(c1.z, c2.z); /* This value of the padding is irrelevant, as long as it * is initialized. We use min to allow auto-vectorization. */ @@ -108,8 +107,7 @@ struct BoundingBox } //! Returns a corner with the maximum coordinates along each dimension - static Corner max(const Corner &c1, - const Corner &c2) + static Corner max(const Corner& c1, const Corner& c2) { Corner cMax; @@ -122,16 +120,10 @@ struct BoundingBox } //! Returns a pointer for SIMD loading of a Corner object - const float *ptr() const - { - return &x; - } + const float* ptr() const { return &x; } //! Returns a pointer for SIMD storing of a Corner object - float *ptr() - { - return &x; - } + float* ptr() { return &x; } float x; //!< x coordinate float y; //!< y coordinate @@ -181,345 +173,274 @@ namespace Nbnxm */ class Grid { - public: - /*! \internal - * \brief The cluster and cell geometry of a grid - */ - struct Geometry - { - //! Constructs the cluster/cell geometry given the type of pairlist - Geometry(PairlistType pairlistType); - - bool isSimple; //!< Is this grid simple (CPU) or hierarchical (GPU) - int numAtomsICluster; //!< Number of atoms per cluster - int numAtomsJCluster; //!< Number of atoms for list j-clusters - int numAtomsPerCell; //!< Number of atoms per cell - int numAtomsICluster2Log; //!< 2log of na_c - }; - - // The physical dimensions of a grid - struct Dimensions - { - //! The lower corner of the (local) grid - rvec lowerCorner; - //! The upper corner of the (local) grid - rvec upperCorner; - //! The physical grid size: upperCorner - lowerCorner - rvec gridSize; - //! An estimate for the atom number density of the region targeted by the grid - real atomDensity; - //! The maximum distance an atom can be outside of a cell and outside of the grid - real maxAtomGroupRadius; - //! Size of cell along dimension x and y - real cellSize[DIM - 1]; - //! 1/size of a cell along dimensions x and y - real invCellSize[DIM - 1]; - //! The number of grid cells along dimensions x and y - int numCells[DIM - 1]; - }; - - //! Constructs a grid given the type of pairlist - Grid(PairlistType pairlistType, - const bool &haveFep); - - //! Returns the geometry of the grid cells - const Geometry &geometry() const - { - return geometry_; - } - - //! Returns the dimensions of the grid - const Dimensions &dimensions() const - { - return dimensions_; - } +public: + /*! \internal + * \brief The cluster and cell geometry of a grid + */ + struct Geometry + { + //! Constructs the cluster/cell geometry given the type of pairlist + Geometry(PairlistType pairlistType); + + bool isSimple; //!< Is this grid simple (CPU) or hierarchical (GPU) + int numAtomsICluster; //!< Number of atoms per cluster + int numAtomsJCluster; //!< Number of atoms for list j-clusters + int numAtomsPerCell; //!< Number of atoms per cell + int numAtomsICluster2Log; //!< 2log of na_c + }; - //! Returns the total number of grid columns - int numColumns() const - { - return dimensions_.numCells[XX]*dimensions_.numCells[YY]; - } + // The physical dimensions of a grid + struct Dimensions + { + //! The lower corner of the (local) grid + rvec lowerCorner; + //! The upper corner of the (local) grid + rvec upperCorner; + //! The physical grid size: upperCorner - lowerCorner + rvec gridSize; + //! An estimate for the atom number density of the region targeted by the grid + real atomDensity; + //! The maximum distance an atom can be outside of a cell and outside of the grid + real maxAtomGroupRadius; + //! Size of cell along dimension x and y + real cellSize[DIM - 1]; + //! 1/size of a cell along dimensions x and y + real invCellSize[DIM - 1]; + //! The number of grid cells along dimensions x and y + int numCells[DIM - 1]; + }; - //! Returns the total number of grid cells - int numCells() const - { - return numCellsTotal_; - } + //! Constructs a grid given the type of pairlist + Grid(PairlistType pairlistType, const bool& haveFep); - //! Returns the cell offset of (the first cell of) this grid in the list of cells combined over all grids - int cellOffset() const - { - return cellOffset_; - } + //! Returns the geometry of the grid cells + const Geometry& geometry() const { return geometry_; } - //! Returns the maximum number of grid cells in a column - int numCellsColumnMax() const - { - return numCellsColumnMax_; - } + //! Returns the dimensions of the grid + const Dimensions& dimensions() const { return dimensions_; } - //! Returns the start of the source atom range mapped to this grid - int srcAtomBegin() const - { - return srcAtomBegin_; - } + //! Returns the total number of grid columns + int numColumns() const { return dimensions_.numCells[XX] * dimensions_.numCells[YY]; } - //! Returns the end of the source atom range mapped to this grid - int srcAtomEnd() const - { - return srcAtomEnd_; - } + //! Returns the total number of grid cells + int numCells() const { return numCellsTotal_; } - //! Returns the first cell index in the grid, starting at 0 in this grid - int firstCellInColumn(int columnIndex) const - { - return cxy_ind_[columnIndex]; - } + //! Returns the cell offset of (the first cell of) this grid in the list of cells combined over all grids + int cellOffset() const { return cellOffset_; } - //! Returns the number of cells in the column - int numCellsInColumn(int columnIndex) const - { - return cxy_ind_[columnIndex + 1] - cxy_ind_[columnIndex]; - } + //! Returns the maximum number of grid cells in a column + int numCellsColumnMax() const { return numCellsColumnMax_; } - //! Returns the index of the first atom in the column - int firstAtomInColumn(int columnIndex) const - { - return (cellOffset_ + cxy_ind_[columnIndex])*geometry_.numAtomsPerCell; - } + //! Returns the start of the source atom range mapped to this grid + int srcAtomBegin() const { return srcAtomBegin_; } - //! Returns the number of real atoms in the column - int numAtomsInColumn(int columnIndex) const - { - return cxy_na_[columnIndex]; - } + //! Returns the end of the source atom range mapped to this grid + int srcAtomEnd() const { return srcAtomEnd_; } - /*! \brief Returns a view of the number of non-filler, atoms for each grid column - * - * \todo Needs a useful name. */ - gmx::ArrayRef cxy_na() const - { - return cxy_na_; - } - /*! \brief Returns a view of the grid-local cell index for each grid column - * - * \todo Needs a useful name. */ - gmx::ArrayRef cxy_ind() const - { - return cxy_ind_; - } + //! Returns the first cell index in the grid, starting at 0 in this grid + int firstCellInColumn(int columnIndex) const { return cxy_ind_[columnIndex]; } - //! Returns the number of real atoms in the column - int numAtomsPerCell() const - { - return geometry_.numAtomsPerCell; - } + //! Returns the number of cells in the column + int numCellsInColumn(int columnIndex) const + { + return cxy_ind_[columnIndex + 1] - cxy_ind_[columnIndex]; + } - //! Returns the number of atoms in the column including padding - int paddedNumAtomsInColumn(int columnIndex) const - { - return numCellsInColumn(columnIndex)*geometry_.numAtomsPerCell; - } + //! Returns the index of the first atom in the column + int firstAtomInColumn(int columnIndex) const + { + return (cellOffset_ + cxy_ind_[columnIndex]) * geometry_.numAtomsPerCell; + } + + //! Returns the number of real atoms in the column + int numAtomsInColumn(int columnIndex) const { return cxy_na_[columnIndex]; } + + /*! \brief Returns a view of the number of non-filler, atoms for each grid column + * + * \todo Needs a useful name. */ + gmx::ArrayRef cxy_na() const { return cxy_na_; } + /*! \brief Returns a view of the grid-local cell index for each grid column + * + * \todo Needs a useful name. */ + gmx::ArrayRef cxy_ind() const { return cxy_ind_; } + + //! Returns the number of real atoms in the column + int numAtomsPerCell() const { return geometry_.numAtomsPerCell; } + + //! Returns the number of atoms in the column including padding + int paddedNumAtomsInColumn(int columnIndex) const + { + return numCellsInColumn(columnIndex) * geometry_.numAtomsPerCell; + } - //! Returns the end of the atom index range on the grid, including padding - int atomIndexEnd() const - { - return (cellOffset_ + numCellsTotal_)*geometry_.numAtomsPerCell; - } + //! Returns the end of the atom index range on the grid, including padding + int atomIndexEnd() const { return (cellOffset_ + numCellsTotal_) * geometry_.numAtomsPerCell; } - //! Returns whether any atom in the cluster is perturbed - bool clusterIsPerturbed(int clusterIndex) const - { - return fep_[clusterIndex] != 0U; - } + //! Returns whether any atom in the cluster is perturbed + bool clusterIsPerturbed(int clusterIndex) const { return fep_[clusterIndex] != 0U; } - //! Returns whether the given atom in the cluster is perturbed - bool atomIsPerturbed(int clusterIndex, - int atomIndexInCluster) const - { - return (fep_[clusterIndex] & (1 << atomIndexInCluster)) != 0U; - } + //! Returns whether the given atom in the cluster is perturbed + bool atomIsPerturbed(int clusterIndex, int atomIndexInCluster) const + { + return (fep_[clusterIndex] & (1 << atomIndexInCluster)) != 0U; + } - //! Returns the free-energy perturbation bits for the cluster - unsigned int fepBits(int clusterIndex) const - { - return fep_[clusterIndex]; - } + //! Returns the free-energy perturbation bits for the cluster + unsigned int fepBits(int clusterIndex) const { return fep_[clusterIndex]; } - //! Returns the i-bounding boxes for all clusters on the grid - gmx::ArrayRef iBoundingBoxes() const - { - return bb_; - } + //! Returns the i-bounding boxes for all clusters on the grid + gmx::ArrayRef iBoundingBoxes() const { return bb_; } - //! Returns the j-bounding boxes for all clusters on the grid - gmx::ArrayRef jBoundingBoxes() const - { - return bbj_; - } + //! Returns the j-bounding boxes for all clusters on the grid + gmx::ArrayRef jBoundingBoxes() const { return bbj_; } - //! Returns the packed bounding boxes for all clusters on the grid, empty with a CPU list - gmx::ArrayRef packedBoundingBoxes() const - { - return pbb_; - } + //! Returns the packed bounding boxes for all clusters on the grid, empty with a CPU list + gmx::ArrayRef packedBoundingBoxes() const { return pbb_; } - //! Returns the bounding boxes along z for all cells on the grid - gmx::ArrayRef zBoundingBoxes() const - { - return bbcz_; - } + //! Returns the bounding boxes along z for all cells on the grid + gmx::ArrayRef zBoundingBoxes() const { return bbcz_; } - //! Returns the flags for all clusters on the grid - gmx::ArrayRef clusterFlags() const - { - return flags_; - } + //! Returns the flags for all clusters on the grid + gmx::ArrayRef clusterFlags() const { return flags_; } - //! Returns the number of clusters for all cells on the grid, empty with a CPU geometry - gmx::ArrayRef numClustersPerCell() const - { - return numClusters_; - } + //! Returns the number of clusters for all cells on the grid, empty with a CPU geometry + gmx::ArrayRef numClustersPerCell() const { return numClusters_; } - //! Returns the cluster index for an atom - int atomToCluster(int atomIndex) const - { - return (atomIndex >> geometry_.numAtomsICluster2Log); - } + //! Returns the cluster index for an atom + int atomToCluster(int atomIndex) const { return (atomIndex >> geometry_.numAtomsICluster2Log); } - //! Returns the total number of clusters on the grid - int numClusters() const + //! Returns the total number of clusters on the grid + int numClusters() const + { + if (geometry_.isSimple) { - if (geometry_.isSimple) - { - return numCellsTotal_; - } - else - { - return numClustersTotal_; - } + return numCellsTotal_; } - - //! Sets the grid dimensions - void setDimensions(int ddZone, - int numAtoms, - gmx::RVec lowerCorner, - gmx::RVec upperCorner, - real atomDensity, - real maxAtomGroupRadius, - bool haveFep, - gmx::PinningPolicy pinningPolicy); - - //! Sets the cell indices using indices in \p gridSetData and \p gridWork - void setCellIndices(int ddZone, - int cellOffset, - GridSetData *gridSetData, - gmx::ArrayRef gridWork, - gmx::Range atomRange, - const int *atinfo, - gmx::ArrayRef x, - int numAtomsMoved, - nbnxn_atomdata_t *nbat); - - //! Determine in which grid columns atoms should go, store cells and atom counts in \p cell and \p cxy_na - static void calcColumnIndices(const Grid::Dimensions &gridDims, - const gmx::UpdateGroupsCog *updateGroupsCog, - gmx::Range atomRange, - gmx::ArrayRef x, - int dd_zone, - const int *move, - int thread, - int nthread, - gmx::ArrayRef cell, - gmx::ArrayRef cxy_na); - - private: - /*! \brief Fill a pair search cell with atoms - * - * Potentially sorts atoms and sets the interaction flags. - */ - void fillCell(GridSetData *gridSetData, - nbnxn_atomdata_t *nbat, - int atomStart, - int atomEnd, - const int *atinfo, - gmx::ArrayRef x, - BoundingBox gmx_unused *bb_work_aligned); - - //! Spatially sort the atoms within the given column range, for CPU geometry - void sortColumnsCpuGeometry(GridSetData *gridSetData, - int dd_zone, - const int *atinfo, - gmx::ArrayRef x, - nbnxn_atomdata_t *nbat, - gmx::Range columnRange, - gmx::ArrayRef sort_work); - - //! Spatially sort the atoms within the given column range, for GPU geometry - void sortColumnsGpuGeometry(GridSetData *gridSetData, - int dd_zone, - const int *atinfo, - gmx::ArrayRef x, - nbnxn_atomdata_t *nbat, - gmx::Range columnRange, - gmx::ArrayRef sort_work); - - /* Data members */ - //! The geometry of the grid clusters and cells - Geometry geometry_; - //! The physical dimensions of the grid - Dimensions dimensions_; - - //! The total number of cells in this grid - int numCellsTotal_; - //! Index in nbs->cell corresponding to cell 0 - int cellOffset_; - //! The maximum number of cells in a column - int numCellsColumnMax_; - - //! The start of the source atom range mapped to this grid - int srcAtomBegin_; - //! The end of the source atom range mapped to this grid - int srcAtomEnd_; - - /* Grid data */ - /*! \brief The number of, non-filler, atoms for each grid column. - * - * \todo Needs a useful name. */ - gmx::HostVector cxy_na_; - /*! \brief The grid-local cell index for each grid column - * - * \todo Needs a useful name. */ - gmx::HostVector cxy_ind_; - - //! The number of cluster for each cell - std::vector numClusters_; - - /* Bounding boxes */ - //! Bounding boxes in z for the cells - std::vector bbcz_; - //! 3D bounding boxes for the sub cells - std::vector < BoundingBox, gmx::AlignedAllocator < BoundingBox>> bb_; - //! 3D j-bounding boxes for the case where the i- and j-cluster sizes are different - std::vector < BoundingBox, gmx::AlignedAllocator < BoundingBox>> bbjStorage_; - //! 3D j-bounding boxes - gmx::ArrayRef bbj_; - //! 3D bounding boxes in packed xxxx format per cell - std::vector < float, gmx::AlignedAllocator < float>> pbb_; - - //! Tells whether we have perturbed interactions, authorative source is in GridSet (never modified) - const bool &haveFep_; - - /* Bit-flag information */ - //! Flags for properties of clusters in each cell - std::vector flags_; - //! Signal bits for atoms in each cell that tell whether an atom is perturbed - std::vector fep_; - - /* Statistics */ - //! Total number of clusters, used for printing - int numClustersTotal_; + else + { + return numClustersTotal_; + } + } + + //! Sets the grid dimensions + void setDimensions(int ddZone, + int numAtoms, + gmx::RVec lowerCorner, + gmx::RVec upperCorner, + real atomDensity, + real maxAtomGroupRadius, + bool haveFep, + gmx::PinningPolicy pinningPolicy); + + //! Sets the cell indices using indices in \p gridSetData and \p gridWork + void setCellIndices(int ddZone, + int cellOffset, + GridSetData* gridSetData, + gmx::ArrayRef gridWork, + gmx::Range atomRange, + const int* atinfo, + gmx::ArrayRef x, + int numAtomsMoved, + nbnxn_atomdata_t* nbat); + + //! Determine in which grid columns atoms should go, store cells and atom counts in \p cell and \p cxy_na + static void calcColumnIndices(const Grid::Dimensions& gridDims, + const gmx::UpdateGroupsCog* updateGroupsCog, + gmx::Range atomRange, + gmx::ArrayRef x, + int dd_zone, + const int* move, + int thread, + int nthread, + gmx::ArrayRef cell, + gmx::ArrayRef cxy_na); + +private: + /*! \brief Fill a pair search cell with atoms + * + * Potentially sorts atoms and sets the interaction flags. + */ + void fillCell(GridSetData* gridSetData, + nbnxn_atomdata_t* nbat, + int atomStart, + int atomEnd, + const int* atinfo, + gmx::ArrayRef x, + BoundingBox gmx_unused* bb_work_aligned); + + //! Spatially sort the atoms within the given column range, for CPU geometry + void sortColumnsCpuGeometry(GridSetData* gridSetData, + int dd_zone, + const int* atinfo, + gmx::ArrayRef x, + nbnxn_atomdata_t* nbat, + gmx::Range columnRange, + gmx::ArrayRef sort_work); + + //! Spatially sort the atoms within the given column range, for GPU geometry + void sortColumnsGpuGeometry(GridSetData* gridSetData, + int dd_zone, + const int* atinfo, + gmx::ArrayRef x, + nbnxn_atomdata_t* nbat, + gmx::Range columnRange, + gmx::ArrayRef sort_work); + + /* Data members */ + //! The geometry of the grid clusters and cells + Geometry geometry_; + //! The physical dimensions of the grid + Dimensions dimensions_; + + //! The total number of cells in this grid + int numCellsTotal_; + //! Index in nbs->cell corresponding to cell 0 + int cellOffset_; + //! The maximum number of cells in a column + int numCellsColumnMax_; + + //! The start of the source atom range mapped to this grid + int srcAtomBegin_; + //! The end of the source atom range mapped to this grid + int srcAtomEnd_; + + /* Grid data */ + /*! \brief The number of, non-filler, atoms for each grid column. + * + * \todo Needs a useful name. */ + gmx::HostVector cxy_na_; + /*! \brief The grid-local cell index for each grid column + * + * \todo Needs a useful name. */ + gmx::HostVector cxy_ind_; + + //! The number of cluster for each cell + std::vector numClusters_; + + /* Bounding boxes */ + //! Bounding boxes in z for the cells + std::vector bbcz_; + //! 3D bounding boxes for the sub cells + std::vector> bb_; + //! 3D j-bounding boxes for the case where the i- and j-cluster sizes are different + std::vector> bbjStorage_; + //! 3D j-bounding boxes + gmx::ArrayRef bbj_; + //! 3D bounding boxes in packed xxxx format per cell + std::vector> pbb_; + + //! Tells whether we have perturbed interactions, authorative source is in GridSet (never modified) + const bool& haveFep_; + + /* Bit-flag information */ + //! Flags for properties of clusters in each cell + std::vector flags_; + //! Signal bits for atoms in each cell that tell whether an atom is perturbed + std::vector fep_; + + /* Statistics */ + //! Total number of clusters, used for printing + int numClustersTotal_; }; } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/gridset.cpp b/src/gromacs/nbnxm/gridset.cpp index f5241a5905..f171317019 100644 --- a/src/gromacs/nbnxm/gridset.cpp +++ b/src/gromacs/nbnxm/gridset.cpp @@ -56,7 +56,7 @@ namespace Nbnxm { //! Returns the number of search grids -static int numGrids(const GridSet::DomainSetup &domainSetup) +static int numGrids(const GridSet::DomainSetup& domainSetup) { int numGrids; if (domainSetup.doTestParticleInsertion) @@ -80,8 +80,8 @@ static int numGrids(const GridSet::DomainSetup &domainSetup) GridSet::DomainSetup::DomainSetup(const int ePBC, const bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *ddZones) : + const ivec* numDDCells, + const gmx_domdec_zones_t* ddZones) : ePBC(ePBC), doTestParticleInsertion(doTestParticleInsertion), haveMultipleDomains(numDDCells != nullptr), @@ -95,8 +95,8 @@ GridSet::DomainSetup::DomainSetup(const int ePBC, GridSet::GridSet(const int ePBC, const bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *ddZones, + const ivec* numDDCells, + const gmx_domdec_zones_t* ddZones, const PairlistType pairlistType, const bool haveFep, const int numThreads, @@ -116,13 +116,13 @@ GridSet::GridSet(const int ePBC, void GridSet::setLocalAtomOrder() { /* Set the atom order for the home cell (index 0) */ - const Nbnxm::Grid &grid = grids_[0]; + const Nbnxm::Grid& grid = grids_[0]; - int atomIndex = 0; + int atomIndex = 0; for (int cxy = 0; cxy < grid.numColumns(); cxy++) { const int numAtoms = grid.numAtomsInColumn(cxy); - int cellIndex = grid.firstCellInColumn(cxy)*grid.geometry().numAtomsPerCell; + int cellIndex = grid.firstCellInColumn(cxy) * grid.geometry().numAtomsPerCell; for (int i = 0; i < numAtoms; i++) { gridSetData_.atomIndices[cellIndex] = atomIndex; @@ -133,35 +133,35 @@ void GridSet::setLocalAtomOrder() } } -void GridSet::putOnGrid(const matrix box, - const int gridIndex, - const rvec lowerCorner, - const rvec upperCorner, - const gmx::UpdateGroupsCog *updateGroupsCog, - const gmx::Range atomRange, - real atomDensity, - gmx::ArrayRef atomInfo, - gmx::ArrayRef x, - const int numAtomsMoved, - const int *move, - nbnxn_atomdata_t *nbat) +void GridSet::putOnGrid(const matrix box, + const int gridIndex, + const rvec lowerCorner, + const rvec upperCorner, + const gmx::UpdateGroupsCog* updateGroupsCog, + const gmx::Range atomRange, + real atomDensity, + gmx::ArrayRef atomInfo, + gmx::ArrayRef x, + const int numAtomsMoved, + const int* move, + nbnxn_atomdata_t* nbat) { - Nbnxm::Grid &grid = grids_[gridIndex]; + Nbnxm::Grid& grid = grids_[gridIndex]; - int cellOffset; + int cellOffset; if (gridIndex == 0) { cellOffset = 0; } else { - const Nbnxm::Grid &previousGrid = grids_[gridIndex - 1]; - cellOffset = previousGrid.atomIndexEnd()/previousGrid.geometry().numAtomsPerCell; + const Nbnxm::Grid& previousGrid = grids_[gridIndex - 1]; + cellOffset = previousGrid.atomIndexEnd() / previousGrid.geometry().numAtomsPerCell; } const int n = atomRange.size(); - real maxAtomGroupRadius; + real maxAtomGroupRadius; if (gridIndex == 0) { copy_mat(box, box_); @@ -176,15 +176,14 @@ void GridSet::putOnGrid(const matrix box, if (debug) { - fprintf(debug, "natoms_local = %5d atom_density = %5.1f\n", - numRealAtomsLocal_, atomDensity); + fprintf(debug, "natoms_local = %5d atom_density = %5.1f\n", numRealAtomsLocal_, atomDensity); } } else { - const Nbnxm::Grid::Dimensions &dimsGrid0 = grids_[0].dimensions(); - atomDensity = dimsGrid0.atomDensity; - maxAtomGroupRadius = dimsGrid0.maxAtomGroupRadius; + const Nbnxm::Grid::Dimensions& dimsGrid0 = grids_[0].dimensions(); + atomDensity = dimsGrid0.atomDensity; + maxAtomGroupRadius = dimsGrid0.maxAtomGroupRadius; numRealAtomsTotal_ = std::max(numRealAtomsTotal_, *atomRange.end()); } @@ -194,15 +193,11 @@ void GridSet::putOnGrid(const matrix box, */ const int ddZone = (domainSetup_.doTestParticleInsertion ? 0 : gridIndex); // grid data used in GPU transfers inherits the gridset pinning policy - auto pinPolicy = gridSetData_.cells.get_allocator().pinningPolicy(); - grid.setDimensions(ddZone, n - numAtomsMoved, - lowerCorner, upperCorner, - atomDensity, - maxAtomGroupRadius, - haveFep_, - pinPolicy); - - for (GridWork &work : gridWork_) + auto pinPolicy = gridSetData_.cells.get_allocator().pinningPolicy(); + grid.setDimensions(ddZone, n - numAtomsMoved, lowerCorner, upperCorner, atomDensity, + maxAtomGroupRadius, haveFep_, pinPolicy); + + for (GridWork& work : gridWork_) { work.numAtomsPerColumn.resize(grid.numColumns() + 1); } @@ -218,19 +213,15 @@ void GridSet::putOnGrid(const matrix box, { try { - Grid::calcColumnIndices(grid.dimensions(), - updateGroupsCog, - atomRange, x, - ddZone, move, thread, nthread, - gridSetData_.cells, - gridWork_[thread].numAtomsPerColumn); + Grid::calcColumnIndices(grid.dimensions(), updateGroupsCog, atomRange, x, ddZone, move, thread, + nthread, gridSetData_.cells, gridWork_[thread].numAtomsPerColumn); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Copy the already computed cell indices to the grid and sort, when needed */ - grid.setCellIndices(ddZone, cellOffset, &gridSetData_, gridWork_, - atomRange, atomInfo.data(), x, numAtomsMoved, nbat); + grid.setCellIndices(ddZone, cellOffset, &gridSetData_, gridWork_, atomRange, atomInfo.data(), x, + numAtomsMoved, nbat); if (gridIndex == 0) { diff --git a/src/gromacs/nbnxm/gridset.h b/src/gromacs/nbnxm/gridset.h index 34aa5df17a..3980a37c68 100644 --- a/src/gromacs/nbnxm/gridset.h +++ b/src/gromacs/nbnxm/gridset.h @@ -83,153 +83,119 @@ namespace Nbnxm */ class GridSet { - public: - /*! \internal - * \brief Description of the domain setup: PBC and the connections between domains - */ - struct DomainSetup - { - //! Constructor, without DD \p numDDCells and \p ddZones should be nullptr - DomainSetup(int ePBC, - bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *ddZones); - - //! The type of PBC - int ePBC; - //! Tells whether we are doing test-particle insertion - bool doTestParticleInsertion; - //! Are there multiple domains? - bool haveMultipleDomains; - //! Are there multiple domains along each dimension? - std::array haveMultipleDomainsPerDim; - //! The domain decomposition zone setup - const gmx_domdec_zones_t *zones; - }; - - //! Constructs a grid set for 1 or multiple DD zones, when numDDCells!=nullptr - GridSet(int ePBC, - bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *ddZones, - PairlistType pairlistType, - bool haveFep, - int numThreads, - gmx::PinningPolicy pinningPolicy); - - //! Puts the atoms on the grid with index \p gridIndex and copies the coordinates to \p nbat - void putOnGrid(const matrix box, - int gridIndex, - const rvec lowerCorner, - const rvec upperCorner, - const gmx::UpdateGroupsCog *updateGroupsCog, - gmx::Range atomRange, - real atomDensity, - gmx::ArrayRef atomInfo, - gmx::ArrayRef x, - int numAtomsMoved, - const int *move, - nbnxn_atomdata_t *nbat); - - //! Returns the domain setup - DomainSetup domainSetup() const - { - return domainSetup_; - } - - //! Returns the total number of atoms in the grid set, including padding - int numGridAtomsTotal() const - { - return grids_.back().atomIndexEnd(); - } - - //! Returns the number of local real atoms, i.e. without padded atoms - int numRealAtomsLocal() const - { - return numRealAtomsLocal_; - } - - //! Returns the number of total real atoms, i.e. without padded atoms - int numRealAtomsTotal() const - { - return numRealAtomsTotal_; - } - - //! Returns the atom order on the grid for the local atoms - gmx::ArrayRef getLocalAtomorder() const - { - /* Return the atom order for the home cell (index 0) */ - const int numIndices = grids_[0].atomIndexEnd() - grids_[0].firstAtomInColumn(0); - - return gmx::constArrayRefFromArray(atomIndices().data(), numIndices); - } - - //! Sets the order of the local atoms to the order grid atom ordering - void setLocalAtomOrder(); - - //! Returns the list of grids - gmx::ArrayRef grids() const - { - return grids_; - } - - //! Returns the grid atom indices covering all grids - gmx::ArrayRef cells() const - { - return gridSetData_.cells; - } - - //! Returns the grid atom indices covering all grids - gmx::ArrayRef atomIndices() const - { - return gridSetData_.atomIndices; - } - - //! Returns whether we have perturbed non-bonded interactions - bool haveFep() const - { - return haveFep_; - } - - //! Returns the unit cell in \p box - void getBox(matrix box) const - { - copy_mat(box_, box); - } - - //! Returns the maximum number of columns across all grids - int numColumnsMax() const - { - return numColumnsMax_; - } - - //! Sets the maximum number of columns across all grids - void setNumColumnsMax(int numColumnsMax) - { - numColumnsMax_ = numColumnsMax; - } - - private: - /* Data members */ - //! The domain setup - DomainSetup domainSetup_; - //! The search grids - std::vector grids_; - //! The cell and atom index data which runs over all grids - GridSetData gridSetData_; - //! Tells whether we have perturbed non-bonded interactions - bool haveFep_; - //! The periodic unit-cell - matrix box_; - //! The number of local real atoms, i.e. without padded atoms, local atoms: 0 to numAtomsLocal_ - int numRealAtomsLocal_; - //! The total number of real atoms, i.e. without padded atoms - int numRealAtomsTotal_; - //! Working data for constructing a single grid, one entry per thread - std::vector gridWork_; - //! Maximum number of columns across all grids - int numColumnsMax_; - +public: + /*! \internal + * \brief Description of the domain setup: PBC and the connections between domains + */ + struct DomainSetup + { + //! Constructor, without DD \p numDDCells and \p ddZones should be nullptr + DomainSetup(int ePBC, + bool doTestParticleInsertion, + const ivec* numDDCells, + const gmx_domdec_zones_t* ddZones); + + //! The type of PBC + int ePBC; + //! Tells whether we are doing test-particle insertion + bool doTestParticleInsertion; + //! Are there multiple domains? + bool haveMultipleDomains; + //! Are there multiple domains along each dimension? + std::array haveMultipleDomainsPerDim; + //! The domain decomposition zone setup + const gmx_domdec_zones_t* zones; + }; + + //! Constructs a grid set for 1 or multiple DD zones, when numDDCells!=nullptr + GridSet(int ePBC, + bool doTestParticleInsertion, + const ivec* numDDCells, + const gmx_domdec_zones_t* ddZones, + PairlistType pairlistType, + bool haveFep, + int numThreads, + gmx::PinningPolicy pinningPolicy); + + //! Puts the atoms on the grid with index \p gridIndex and copies the coordinates to \p nbat + void putOnGrid(const matrix box, + int gridIndex, + const rvec lowerCorner, + const rvec upperCorner, + const gmx::UpdateGroupsCog* updateGroupsCog, + gmx::Range atomRange, + real atomDensity, + gmx::ArrayRef atomInfo, + gmx::ArrayRef x, + int numAtomsMoved, + const int* move, + nbnxn_atomdata_t* nbat); + + //! Returns the domain setup + DomainSetup domainSetup() const { return domainSetup_; } + + //! Returns the total number of atoms in the grid set, including padding + int numGridAtomsTotal() const { return grids_.back().atomIndexEnd(); } + + //! Returns the number of local real atoms, i.e. without padded atoms + int numRealAtomsLocal() const { return numRealAtomsLocal_; } + + //! Returns the number of total real atoms, i.e. without padded atoms + int numRealAtomsTotal() const { return numRealAtomsTotal_; } + + //! Returns the atom order on the grid for the local atoms + gmx::ArrayRef getLocalAtomorder() const + { + /* Return the atom order for the home cell (index 0) */ + const int numIndices = grids_[0].atomIndexEnd() - grids_[0].firstAtomInColumn(0); + + return gmx::constArrayRefFromArray(atomIndices().data(), numIndices); + } + + //! Sets the order of the local atoms to the order grid atom ordering + void setLocalAtomOrder(); + + //! Returns the list of grids + gmx::ArrayRef grids() const { return grids_; } + + //! Returns the grid atom indices covering all grids + gmx::ArrayRef cells() const { return gridSetData_.cells; } + + //! Returns the grid atom indices covering all grids + gmx::ArrayRef atomIndices() const { return gridSetData_.atomIndices; } + + //! Returns whether we have perturbed non-bonded interactions + bool haveFep() const { return haveFep_; } + + //! Returns the unit cell in \p box + void getBox(matrix box) const { copy_mat(box_, box); } + + //! Returns the maximum number of columns across all grids + int numColumnsMax() const { return numColumnsMax_; } + + //! Sets the maximum number of columns across all grids + void setNumColumnsMax(int numColumnsMax) { numColumnsMax_ = numColumnsMax; } + +private: + /* Data members */ + //! The domain setup + DomainSetup domainSetup_; + //! The search grids + std::vector grids_; + //! The cell and atom index data which runs over all grids + GridSetData gridSetData_; + //! Tells whether we have perturbed non-bonded interactions + bool haveFep_; + //! The periodic unit-cell + matrix box_; + //! The number of local real atoms, i.e. without padded atoms, local atoms: 0 to numAtomsLocal_ + int numRealAtomsLocal_; + //! The total number of real atoms, i.e. without padded atoms + int numRealAtomsTotal_; + //! Working data for constructing a single grid, one entry per thread + std::vector gridWork_; + //! Maximum number of columns across all grids + int numColumnsMax_; }; } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/kernel_common.cpp b/src/gromacs/nbnxm/kernel_common.cpp index 9c0dc97d8d..50fc7d163d 100644 --- a/src/gromacs/nbnxm/kernel_common.cpp +++ b/src/gromacs/nbnxm/kernel_common.cpp @@ -50,10 +50,9 @@ #include "gromacs/utility/gmxassert.h" //! Clears all elements of buffer -static void -clearBufferAll(gmx::ArrayRef buffer) +static void clearBufferAll(gmx::ArrayRef buffer) { - for (real &elem : buffer) + for (real& elem : buffer) { elem = 0; } @@ -64,30 +63,25 @@ clearBufferAll(gmx::ArrayRef buffer) * Only elements with flags in \p nbat set for index \p outputIndex * are cleared. */ -template -static void -clearBufferFlagged(const nbnxn_atomdata_t &nbat, - int outputIndex, - gmx::ArrayRef buffer) +template +static void clearBufferFlagged(const nbnxn_atomdata_t& nbat, int outputIndex, gmx::ArrayRef buffer) { - const nbnxn_buffer_flags_t &flags = nbat.buffer_flags; + const nbnxn_buffer_flags_t& flags = nbat.buffer_flags; gmx_bitmask_t our_flag; bitmask_init_bit(&our_flag, outputIndex); - constexpr size_t numComponentsPerBlock = NBNXN_BUFFERFLAG_SIZE*numComponentsPerElement; + constexpr size_t numComponentsPerBlock = NBNXN_BUFFERFLAG_SIZE * numComponentsPerElement; for (int b = 0; b < flags.nflag; b++) { if (!bitmask_is_disjoint(flags.flag[b], our_flag)) { - clearBufferAll(buffer.subArray(b*numComponentsPerBlock, numComponentsPerBlock)); + clearBufferAll(buffer.subArray(b * numComponentsPerBlock, numComponentsPerBlock)); } } } -void -clearForceBuffer(nbnxn_atomdata_t *nbat, - int outputIndex) +void clearForceBuffer(nbnxn_atomdata_t* nbat, int outputIndex) { if (nbat->bUseBufferFlags) { @@ -101,22 +95,17 @@ clearForceBuffer(nbnxn_atomdata_t *nbat, } } -void -clear_fshift(real *fshift) +void clear_fshift(real* fshift) { int i; - for (i = 0; i < SHIFTS*DIM; i++) + for (i = 0; i < SHIFTS * DIM; i++) { fshift[i] = 0; } } -void -reduce_energies_over_lists(const nbnxn_atomdata_t *nbat, - int nlist, - real *Vvdw, - real *Vc) +void reduce_energies_over_lists(const nbnxn_atomdata_t* nbat, int nlist, real* Vvdw, real* Vc) { const int nenergrp = nbat->params().nenergrp; @@ -125,18 +114,18 @@ reduce_energies_over_lists(const nbnxn_atomdata_t *nbat, for (int i = 0; i < nenergrp; i++) { /* Reduce the diagonal terms */ - int ind = i*nenergrp + i; + int ind = i * nenergrp + i; Vvdw[ind] += nbat->out[nb].Vvdw[ind]; - Vc[ind] += nbat->out[nb].Vc[ind]; + Vc[ind] += nbat->out[nb].Vc[ind]; /* Reduce the off-diagonal terms */ for (int j = i + 1; j < nenergrp; j++) { /* The output should contain only one off-diagonal part */ - int ind = i*nenergrp + j; - int indr = j*nenergrp + i; + int ind = i * nenergrp + j; + int indr = j * nenergrp + i; Vvdw[ind] += nbat->out[nb].Vvdw[ind] + nbat->out[nb].Vvdw[indr]; - Vc[ind] += nbat->out[nb].Vc[ind] + nbat->out[nb].Vc[indr]; + Vc[ind] += nbat->out[nb].Vc[ind] + nbat->out[nb].Vc[indr]; } } } diff --git a/src/gromacs/nbnxm/kernel_common.h b/src/gromacs/nbnxm/kernel_common.h index 16b3890a40..80492f006d 100644 --- a/src/gromacs/nbnxm/kernel_common.h +++ b/src/gromacs/nbnxm/kernel_common.h @@ -58,32 +58,38 @@ struct interaction_const_t; /*! \brief Pair-interaction kernel type that also calculates energies. */ -typedef void (nbk_func_ener)(const NbnxnPairlistCpu *nbl, - const nbnxn_atomdata_t *nbat, - const interaction_const_t *ic, - const rvec *shift_vec, - nbnxn_atomdata_output_t *out); +typedef void(nbk_func_ener)(const NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const interaction_const_t* ic, + const rvec* shift_vec, + nbnxn_atomdata_output_t* out); /*! \brief Pointer to \p nbk_func_ener. */ -typedef nbk_func_ener *p_nbk_func_ener; +typedef nbk_func_ener* p_nbk_func_ener; /*! \brief Pair-interaction kernel type that does not calculates energies. */ -typedef void (nbk_func_noener)(const NbnxnPairlistCpu *nbl, - const nbnxn_atomdata_t *nbat, - const interaction_const_t *ic, - const rvec *shift_vec, - nbnxn_atomdata_output_t *out); +typedef void(nbk_func_noener)(const NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const interaction_const_t* ic, + const rvec* shift_vec, + nbnxn_atomdata_output_t* out); /*! \brief Pointer to \p nbk_func_noener. */ -typedef nbk_func_noener *p_nbk_func_noener; +typedef nbk_func_noener* p_nbk_func_noener; /*! \brief Kinds of electrostatic treatments in SIMD Verlet kernels */ -enum { - coulktRF, coulktTAB, coulktTAB_TWIN, coulktEWALD, coulktEWALD_TWIN, coulktNR +enum +{ + coulktRF, + coulktTAB, + coulktTAB_TWIN, + coulktEWALD, + coulktEWALD_TWIN, + coulktNR }; /*! \brief Kinds of Van der Waals treatments in SIMD Verlet kernels @@ -95,8 +101,17 @@ enum { * These two numbers differ, because currently only the reference kernels * support LB combination rules for the LJ-Ewald grid part. */ -enum { - vdwktLJCUT_COMBGEOM, vdwktLJCUT_COMBLB, vdwktLJCUT_COMBNONE, vdwktLJFORCESWITCH, vdwktLJPOTSWITCH, vdwktLJEWALDCOMBGEOM, vdwktLJEWALDCOMBLB, vdwktNR = vdwktLJEWALDCOMBLB, vdwktNR_ref +enum +{ + vdwktLJCUT_COMBGEOM, + vdwktLJCUT_COMBLB, + vdwktLJCUT_COMBNONE, + vdwktLJFORCESWITCH, + vdwktLJPOTSWITCH, + vdwktLJEWALDCOMBGEOM, + vdwktLJEWALDCOMBLB, + vdwktNR = vdwktLJEWALDCOMBLB, + vdwktNR_ref }; /*! \brief Clears the force buffer. @@ -107,21 +122,14 @@ enum { * \param[in,out] nbat The Nbnxm atom data * \param[in] outputIndex The index of the output object to clear */ -void -clearForceBuffer(nbnxn_atomdata_t *nbat, - int outputIndex); +void clearForceBuffer(nbnxn_atomdata_t* nbat, int outputIndex); /*! \brief Clears the shift forces. */ -void -clear_fshift(real *fshift); +void clear_fshift(real* fshift); /*! \brief Reduces the collected energy terms over the pair-lists/threads. */ -void -reduce_energies_over_lists(const nbnxn_atomdata_t *nbat, - int nlist, - real *Vvdw, - real *Vc); +void reduce_energies_over_lists(const nbnxn_atomdata_t* nbat, int nlist, real* Vvdw, real* Vc); #endif diff --git a/src/gromacs/nbnxm/kerneldispatch.cpp b/src/gromacs/nbnxm/kerneldispatch.cpp index d4bf56f906..1dd8af848f 100644 --- a/src/gromacs/nbnxm/kerneldispatch.cpp +++ b/src/gromacs/nbnxm/kerneldispatch.cpp @@ -65,10 +65,10 @@ #define INCLUDE_KERNELFUNCTION_TABLES #include "kernels_reference/kernel_ref.h" #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernels_simd_2xmm/kernels.h" +# include "kernels_simd_2xmm/kernels.h" #endif #ifdef GMX_NBNXN_SIMD_4XN -#include "kernels_simd_4xm/kernels.h" +# include "kernels_simd_4xm/kernels.h" #endif #undef INCLUDE_FUNCTION_TABLES @@ -76,7 +76,7 @@ * * \param[in,out] out nbnxn kernel output struct */ -static void clearGroupEnergies(nbnxn_atomdata_output_t *out) +static void clearGroupEnergies(nbnxn_atomdata_output_t* out) { std::fill(out->Vvdw.begin(), out->Vvdw.end(), 0.0_real); std::fill(out->Vc.begin(), out->Vc.end(), 0.0_real); @@ -95,19 +95,17 @@ static void clearGroupEnergies(nbnxn_atomdata_output_t *out) * \param[in] numGroups_2log Log2 of numGroups, rounded up * \param[in,out] out Struct with energy buffers */ -template static void -reduceGroupEnergySimdBuffers(int numGroups, - int numGroups_2log, - nbnxn_atomdata_output_t *out) +template +static void reduceGroupEnergySimdBuffers(int numGroups, int numGroups_2log, nbnxn_atomdata_output_t* out) { - const int unrollj_half = unrollj/2; + const int unrollj_half = unrollj / 2; /* Energies are stored in SIMD registers with size 2^numGroups_2log */ - const int numGroupsStorage = (1 << numGroups_2log); + const int numGroupsStorage = (1 << numGroups_2log); - const real * gmx_restrict vVdwSimd = out->VSvdw.data(); - const real * gmx_restrict vCoulombSimd = out->VSc.data(); - real * gmx_restrict vVdw = out->Vvdw.data(); - real * gmx_restrict vCoulomb = out->Vc.data(); + const real* gmx_restrict vVdwSimd = out->VSvdw.data(); + const real* gmx_restrict vCoulombSimd = out->VSc.data(); + real* gmx_restrict vVdw = out->Vvdw.data(); + real* gmx_restrict vCoulomb = out->Vc.data(); /* The size of the SIMD energy group buffer array is: * numGroups*numGroups*numGroupsStorage*unrollj_half*simd_width @@ -118,14 +116,14 @@ reduceGroupEnergySimdBuffers(int numGroups, { for (int j0 = 0; j0 < numGroups; j0++) { - int c = ((i*numGroups + j1)*numGroupsStorage + j0)*unrollj_half*unrollj; + int c = ((i * numGroups + j1) * numGroupsStorage + j0) * unrollj_half * unrollj; for (int s = 0; s < unrollj_half; s++) { - vVdw [i*numGroups + j0] += vVdwSimd [c + 0]; - vVdw [i*numGroups + j1] += vVdwSimd [c + 1]; - vCoulomb[i*numGroups + j0] += vCoulombSimd[c + 0]; - vCoulomb[i*numGroups + j1] += vCoulombSimd[c + 1]; - c += unrollj + 2; + vVdw[i * numGroups + j0] += vVdwSimd[c + 0]; + vVdw[i * numGroups + j1] += vVdwSimd[c + 1]; + vCoulomb[i * numGroups + j0] += vCoulombSimd[c + 0]; + vCoulomb[i * numGroups + j1] += vCoulombSimd[c + 1]; + c += unrollj + 2; } } } @@ -149,20 +147,19 @@ reduceGroupEnergySimdBuffers(int numGroups, * \param[out] vVdw Output buffer for Van der Waals energies * \param[in] wcycle Pointer to cycle counting data structure. */ -static void -nbnxn_kernel_cpu(const PairlistSet &pairlistSet, - const Nbnxm::KernelSetup &kernelSetup, - nbnxn_atomdata_t *nbat, - const interaction_const_t &ic, - rvec *shiftVectors, - const gmx::StepWorkload &stepWork, - int clearF, - real *vCoulomb, - real *vVdw, - gmx_wallcycle *wcycle) +static void nbnxn_kernel_cpu(const PairlistSet& pairlistSet, + const Nbnxm::KernelSetup& kernelSetup, + nbnxn_atomdata_t* nbat, + const interaction_const_t& ic, + rvec* shiftVectors, + const gmx::StepWorkload& stepWork, + int clearF, + real* vCoulomb, + real* vVdw, + gmx_wallcycle* wcycle) { - int coulkt; + int coulkt; if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT) { coulkt = coulktRF; @@ -193,7 +190,7 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, } } - const nbnxn_atomdata_t::Params &nbatParams = nbat->params(); + const nbnxn_atomdata_t::Params& nbatParams = nbat->params(); int vdwkt = 0; if (ic.vdwtype == evdwCUT) @@ -205,20 +202,14 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, switch (nbatParams.comb_rule) { case ljcrGEOM: vdwkt = vdwktLJCUT_COMBGEOM; break; - case ljcrLB: vdwkt = vdwktLJCUT_COMBLB; break; + case ljcrLB: vdwkt = vdwktLJCUT_COMBLB; break; case ljcrNONE: vdwkt = vdwktLJCUT_COMBNONE; break; - default: - GMX_RELEASE_ASSERT(false, "Unknown combination rule"); + default: GMX_RELEASE_ASSERT(false, "Unknown combination rule"); } break; - case eintmodFORCESWITCH: - vdwkt = vdwktLJFORCESWITCH; - break; - case eintmodPOTSWITCH: - vdwkt = vdwktLJPOTSWITCH; - break; - default: - GMX_RELEASE_ASSERT(false, "Unsupported VdW interaction modifier"); + case eintmodFORCESWITCH: vdwkt = vdwktLJFORCESWITCH; break; + case eintmodPOTSWITCH: vdwkt = vdwktLJPOTSWITCH; break; + default: GMX_RELEASE_ASSERT(false, "Unsupported VdW interaction modifier"); } } else if (ic.vdwtype == evdwPME) @@ -231,7 +222,9 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, { vdwkt = vdwktLJEWALDCOMBLB; /* At setup we (should have) selected the C reference kernel */ - GMX_RELEASE_ASSERT(kernelSetup.kernelType == Nbnxm::KernelType::Cpu4x4_PlainC, "Only the C reference nbnxn SIMD kernel supports LJ-PME with LB combination rules"); + GMX_RELEASE_ASSERT(kernelSetup.kernelType == Nbnxm::KernelType::Cpu4x4_PlainC, + "Only the C reference nbnxn SIMD kernel supports LJ-PME with LB " + "combination rules"); } } else @@ -241,14 +234,14 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, gmx::ArrayRef pairlists = pairlistSet.cpuLists(); - int gmx_unused nthreads = gmx_omp_nthreads_get(emntNonbonded); + int gmx_unused nthreads = gmx_omp_nthreads_get(emntNonbonded); wallcycle_sub_start(wcycle, ewcsNONBONDED_CLEAR); #pragma omp parallel for schedule(static) num_threads(nthreads) for (gmx::index nb = 0; nb < pairlists.ssize(); nb++) { // Presently, the kernels do not call C++ code that can throw, // so no need for a try/catch pair in this OpenMP region. - nbnxn_atomdata_output_t *out = &nbat->out[nb]; + nbnxn_atomdata_output_t* out = &nbat->out[nb]; if (clearF == enbvClearFYes) { @@ -264,7 +257,7 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, } // TODO: Change to reference - const NbnxnPairlistCpu *pairlist = &pairlists[nb]; + const NbnxnPairlistCpu* pairlist = &pairlists[nb]; if (!stepWork.computeEnergy) { @@ -272,29 +265,19 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, switch (kernelSetup.kernelType) { case Nbnxm::KernelType::Cpu4x4_PlainC: - nbnxn_kernel_noener_ref[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxn_kernel_noener_ref[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #ifdef GMX_NBNXN_SIMD_2XNN case Nbnxm::KernelType::Cpu4xN_Simd_2xNN: - nbnxm_kernel_noener_simd_2xmm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxm_kernel_noener_simd_2xmm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif #ifdef GMX_NBNXN_SIMD_4XN case Nbnxm::KernelType::Cpu4xN_Simd_4xN: - nbnxm_kernel_noener_simd_4xm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxm_kernel_noener_simd_4xm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif - default: - GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); + default: GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); } } else if (out->Vvdw.size() == 1) @@ -306,29 +289,19 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, switch (kernelSetup.kernelType) { case Nbnxm::KernelType::Cpu4x4_PlainC: - nbnxn_kernel_ener_ref[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxn_kernel_ener_ref[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #ifdef GMX_NBNXN_SIMD_2XNN case Nbnxm::KernelType::Cpu4xN_Simd_2xNN: - nbnxm_kernel_ener_simd_2xmm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxm_kernel_ener_simd_2xmm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif #ifdef GMX_NBNXN_SIMD_4XN case Nbnxm::KernelType::Cpu4xN_Simd_4xN: - nbnxm_kernel_ener_simd_4xm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxm_kernel_ener_simd_4xm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif - default: - GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); + default: GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); } } else @@ -342,31 +315,21 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, { case Nbnxm::KernelType::Cpu4x4_PlainC: unrollj = c_nbnxnCpuIClusterSize; - nbnxn_kernel_energrp_ref[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxn_kernel_energrp_ref[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #ifdef GMX_NBNXN_SIMD_2XNN case Nbnxm::KernelType::Cpu4xN_Simd_2xNN: - unrollj = GMX_SIMD_REAL_WIDTH/2; - nbnxm_kernel_energrp_simd_2xmm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + unrollj = GMX_SIMD_REAL_WIDTH / 2; + nbnxm_kernel_energrp_simd_2xmm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif #ifdef GMX_NBNXN_SIMD_4XN case Nbnxm::KernelType::Cpu4xN_Simd_4xN: unrollj = GMX_SIMD_REAL_WIDTH; - nbnxm_kernel_energrp_simd_4xm[coulkt][vdwkt](pairlist, nbat, - &ic, - shiftVectors, - out); + nbnxm_kernel_energrp_simd_4xm[coulkt][vdwkt](pairlist, nbat, &ic, shiftVectors, out); break; #endif - default: - GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); + default: GMX_RELEASE_ASSERT(false, "Unsupported kernel architecture"); } if (kernelSetup.kernelType != Nbnxm::KernelType::Cpu4x4_PlainC) @@ -374,22 +337,15 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, switch (unrollj) { case 2: - reduceGroupEnergySimdBuffers<2>(nbatParams.nenergrp, - nbatParams.neg_2log, - out); + reduceGroupEnergySimdBuffers<2>(nbatParams.nenergrp, nbatParams.neg_2log, out); break; case 4: - reduceGroupEnergySimdBuffers<4>(nbatParams.nenergrp, - nbatParams.neg_2log, - out); + reduceGroupEnergySimdBuffers<4>(nbatParams.nenergrp, nbatParams.neg_2log, out); break; case 8: - reduceGroupEnergySimdBuffers<8>(nbatParams.nenergrp, - nbatParams.neg_2log, - out); + reduceGroupEnergySimdBuffers<8>(nbatParams.nenergrp, nbatParams.neg_2log, out); break; - default: - GMX_RELEASE_ASSERT(false, "Unsupported j-unroll size"); + default: GMX_RELEASE_ASSERT(false, "Unsupported j-unroll size"); } } } @@ -402,21 +358,21 @@ nbnxn_kernel_cpu(const PairlistSet &pairlistSet, } } -static void accountFlops(t_nrnb *nrnb, - const PairlistSet &pairlistSet, - const nonbonded_verlet_t &nbv, - const interaction_const_t &ic, - const gmx::StepWorkload &stepWork) +static void accountFlops(t_nrnb* nrnb, + const PairlistSet& pairlistSet, + const nonbonded_verlet_t& nbv, + const interaction_const_t& ic, + const gmx::StepWorkload& stepWork) { const bool usingGpuKernels = nbv.useGpu(); - int enr_nbnxn_kernel_ljc; + int enr_nbnxn_kernel_ljc; if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT) { enr_nbnxn_kernel_ljc = eNR_NBNXN_LJ_RF; } - else if ((!usingGpuKernels && nbv.kernelSetup().ewaldExclusionType == Nbnxm::EwaldExclusionType::Analytical) || - (usingGpuKernels && Nbnxm::gpu_is_kernel_ewald_analytical(nbv.gpu_nbv))) + else if ((!usingGpuKernels && nbv.kernelSetup().ewaldExclusionType == Nbnxm::EwaldExclusionType::Analytical) + || (usingGpuKernels && Nbnxm::gpu_is_kernel_ewald_analytical(nbv.gpu_nbv))) { enr_nbnxn_kernel_ljc = eNR_NBNXN_LJ_EWALD; } @@ -429,16 +385,13 @@ static void accountFlops(t_nrnb *nrnb, { /* In eNR_??? the nbnxn F+E kernels are always the F kernel + 1 */ enr_nbnxn_kernel_ljc += 1; - enr_nbnxn_kernel_lj += 1; + enr_nbnxn_kernel_lj += 1; } - inc_nrnb(nrnb, enr_nbnxn_kernel_ljc, - pairlistSet.natpair_ljq_); - inc_nrnb(nrnb, enr_nbnxn_kernel_lj, - pairlistSet.natpair_lj_); + inc_nrnb(nrnb, enr_nbnxn_kernel_ljc, pairlistSet.natpair_ljq_); + inc_nrnb(nrnb, enr_nbnxn_kernel_lj, pairlistSet.natpair_lj_); /* The Coulomb-only kernels are offset -eNR_NBNXN_LJ_RF+eNR_NBNXN_RF */ - inc_nrnb(nrnb, enr_nbnxn_kernel_ljc-eNR_NBNXN_LJ_RF+eNR_NBNXN_RF, - pairlistSet.natpair_q_); + inc_nrnb(nrnb, enr_nbnxn_kernel_ljc - eNR_NBNXN_LJ_RF + eNR_NBNXN_RF, pairlistSet.natpair_q_); if (ic.vdw_modifier == eintmodFORCESWITCH) { @@ -460,33 +413,24 @@ static void accountFlops(t_nrnb *nrnb, } } -void -nonbonded_verlet_t::dispatchNonbondedKernel(gmx::InteractionLocality iLocality, - const interaction_const_t &ic, - const gmx::StepWorkload &stepWork, - int clearF, - const t_forcerec &fr, - gmx_enerdata_t *enerd, - t_nrnb *nrnb) +void nonbonded_verlet_t::dispatchNonbondedKernel(gmx::InteractionLocality iLocality, + const interaction_const_t& ic, + const gmx::StepWorkload& stepWork, + int clearF, + const t_forcerec& fr, + gmx_enerdata_t* enerd, + t_nrnb* nrnb) { - const PairlistSet &pairlistSet = pairlistSets().pairlistSet(iLocality); + const PairlistSet& pairlistSet = pairlistSets().pairlistSet(iLocality); switch (kernelSetup().kernelType) { case Nbnxm::KernelType::Cpu4x4_PlainC: case Nbnxm::KernelType::Cpu4xN_Simd_4xN: case Nbnxm::KernelType::Cpu4xN_Simd_2xNN: - nbnxn_kernel_cpu(pairlistSet, - kernelSetup(), - nbat.get(), - ic, - fr.shift_vec, - stepWork, - clearF, - enerd->grpp.ener[egCOULSR].data(), - fr.bBHAM ? - enerd->grpp.ener[egBHAMSR].data() : - enerd->grpp.ener[egLJSR].data(), + nbnxn_kernel_cpu(pairlistSet, kernelSetup(), nbat.get(), ic, fr.shift_vec, stepWork, + clearF, enerd->grpp.ener[egCOULSR].data(), + fr.bBHAM ? enerd->grpp.ener[egBHAMSR].data() : enerd->grpp.ener[egLJSR].data(), wcycle_); break; @@ -495,38 +439,28 @@ nonbonded_verlet_t::dispatchNonbondedKernel(gmx::InteractionLocality iLocality break; case Nbnxm::KernelType::Cpu8x8x8_PlainC: - nbnxn_kernel_gpu_ref(pairlistSet.gpuList(), - nbat.get(), &ic, - fr.shift_vec, - stepWork, - clearF, - nbat->out[0].f, - nbat->out[0].fshift.data(), - enerd->grpp.ener[egCOULSR].data(), - fr.bBHAM ? - enerd->grpp.ener[egBHAMSR].data() : - enerd->grpp.ener[egLJSR].data()); + nbnxn_kernel_gpu_ref( + pairlistSet.gpuList(), nbat.get(), &ic, fr.shift_vec, stepWork, clearF, + nbat->out[0].f, nbat->out[0].fshift.data(), enerd->grpp.ener[egCOULSR].data(), + fr.bBHAM ? enerd->grpp.ener[egBHAMSR].data() : enerd->grpp.ener[egLJSR].data()); break; - default: - GMX_RELEASE_ASSERT(false, "Invalid nonbonded kernel type passed!"); - + default: GMX_RELEASE_ASSERT(false, "Invalid nonbonded kernel type passed!"); } accountFlops(nrnb, pairlistSet, *this, ic, stepWork); } -void -nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocality, - const t_forcerec *fr, - rvec x[], - gmx::ForceWithShiftForces *forceWithShiftForces, - const t_mdatoms &mdatoms, - t_lambda *fepvals, - real *lambda, - gmx_enerdata_t *enerd, - const gmx::StepWorkload &stepWork, - t_nrnb *nrnb) +void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocality, + const t_forcerec* fr, + rvec x[], + gmx::ForceWithShiftForces* forceWithShiftForces, + const t_mdatoms& mdatoms, + t_lambda* fepvals, + real* lambda, + gmx_enerdata_t* enerd, + const gmx::StepWorkload& stepWork, + t_nrnb* nrnb) { const auto nbl_fep = pairlistSets().pairlistSet(iLocality).fepLists(); @@ -555,14 +489,15 @@ nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocali nb_kernel_data_t kernel_data; real dvdl_nb[efptNR] = { 0 }; - kernel_data.flags = donb_flags; - kernel_data.lambda = lambda; - kernel_data.dvdl = dvdl_nb; + kernel_data.flags = donb_flags; + kernel_data.lambda = lambda; + kernel_data.dvdl = dvdl_nb; kernel_data.energygrp_elec = enerd->grpp.ener[egCOULSR].data(); kernel_data.energygrp_vdw = enerd->grpp.ener[egLJSR].data(); - GMX_ASSERT(gmx_omp_nthreads_get(emntNonbonded) == nbl_fep.ssize(), "Number of lists should be same as number of NB threads"); + GMX_ASSERT(gmx_omp_nthreads_get(emntNonbonded) == nbl_fep.ssize(), + "Number of lists should be same as number of NB threads"); wallcycle_sub_start(wcycle_, ewcsNONBONDED_FEP); #pragma omp parallel for schedule(static) num_threads(nbl_fep.ssize()) @@ -570,21 +505,20 @@ nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocali { try { - gmx_nb_free_energy_kernel(nbl_fep[th].get(), - x, forceWithShiftForces, - fr, &mdatoms, &kernel_data, nrnb); + gmx_nb_free_energy_kernel(nbl_fep[th].get(), x, forceWithShiftForces, fr, &mdatoms, + &kernel_data, nrnb); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } if (fepvals->sc_alpha != 0) { - enerd->dvdl_nonlin[efptVDW] += dvdl_nb[efptVDW]; + enerd->dvdl_nonlin[efptVDW] += dvdl_nb[efptVDW]; enerd->dvdl_nonlin[efptCOUL] += dvdl_nb[efptCOUL]; } else { - enerd->dvdl_lin[efptVDW] += dvdl_nb[efptVDW]; + enerd->dvdl_lin[efptVDW] += dvdl_nb[efptVDW]; enerd->dvdl_lin[efptCOUL] += dvdl_nb[efptCOUL]; } @@ -594,7 +528,8 @@ nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocali if (fepvals->n_lambda > 0 && stepWork.computeDhdl && fepvals->sc_alpha != 0) { real lam_i[efptNR]; - kernel_data.flags = (donb_flags & ~(GMX_NONBONDED_DO_FORCE | GMX_NONBONDED_DO_SHIFTFORCE)) | GMX_NONBONDED_DO_FOREIGNLAMBDA; + kernel_data.flags = (donb_flags & ~(GMX_NONBONDED_DO_FORCE | GMX_NONBONDED_DO_SHIFTFORCE)) + | GMX_NONBONDED_DO_FOREIGNLAMBDA; kernel_data.lambda = lam_i; kernel_data.energygrp_elec = enerd->foreign_grpp.ener[egCOULSR].data(); kernel_data.energygrp_vdw = enerd->foreign_grpp.ener[egLJSR].data(); @@ -604,7 +539,7 @@ nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocali { for (int j = 0; j < efptNR; j++) { - lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i-1]); + lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]); } reset_foreign_enerdata(enerd); #pragma omp parallel for schedule(static) num_threads(nbl_fep.ssize()) @@ -612,11 +547,10 @@ nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality iLocali { try { - gmx_nb_free_energy_kernel(nbl_fep[th].get(), - x, forceWithShiftForces, - fr, &mdatoms, &kernel_data, nrnb); + gmx_nb_free_energy_kernel(nbl_fep[th].get(), x, forceWithShiftForces, fr, + &mdatoms, &kernel_data, nrnb); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } sum_epot(&(enerd->foreign_grpp), enerd->foreign_term); diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.cpp b/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.cpp index d9489ec746..3820a719fa 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.cpp +++ b/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.cpp @@ -54,20 +54,19 @@ static const int c_numClPerSupercl = c_nbnxnGpuNumClusterPerSupercluster; static const int c_clSize = c_nbnxnGpuClusterSize; -void -nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, - const nbnxn_atomdata_t *nbat, - const interaction_const_t *iconst, - rvec *shift_vec, - const gmx::StepWorkload &stepWork, - int clearF, - gmx::ArrayRef f, - real * fshift, - real * Vc, - real * Vvdw) +void nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu* nbl, + const nbnxn_atomdata_t* nbat, + const interaction_const_t* iconst, + rvec* shift_vec, + const gmx::StepWorkload& stepWork, + int clearF, + gmx::ArrayRef f, + real* fshift, + real* Vc, + real* Vvdw) { gmx_bool bEwald; - const real *Ftab = nullptr; + const real* Ftab = nullptr; real rcut2, rvdw2, rlist2; int ntype; real facel; @@ -95,19 +94,22 @@ nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, real int_bit; real fexcl; real c6, c12; - const nbnxn_excl_t *excl[2]; + const nbnxn_excl_t* excl[2]; - int npair_tot, npair; - int nhwu, nhwu_pruned; + int npair_tot, npair; + int nhwu, nhwu_pruned; if (nbl->na_ci != c_clSize) { - gmx_fatal(FARGS, "The neighborlist cluster size in the GPU reference kernel is %d, expected it to be %d", nbl->na_ci, c_clSize); + gmx_fatal(FARGS, + "The neighborlist cluster size in the GPU reference kernel is %d, expected it to " + "be %d", + nbl->na_ci, c_clSize); } if (clearF == enbvClearFYes) { - for (real &elem : f) + for (real& elem : f) { elem = 0; } @@ -119,123 +121,124 @@ nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, Ftab = iconst->coulombEwaldTables->tableF.data(); } - rcut2 = iconst->rcoulomb*iconst->rcoulomb; - rvdw2 = iconst->rvdw*iconst->rvdw; + rcut2 = iconst->rcoulomb * iconst->rcoulomb; + rvdw2 = iconst->rvdw * iconst->rvdw; - rlist2 = nbl->rlist*nbl->rlist; + rlist2 = nbl->rlist * nbl->rlist; - const int *type = nbat->params().type.data(); + const int* type = nbat->params().type.data(); facel = iconst->epsfac; - const real *shiftvec = shift_vec[0]; - const real *vdwparam = nbat->params().nbfp.data(); + const real* shiftvec = shift_vec[0]; + const real* vdwparam = nbat->params().nbfp.data(); ntype = nbat->params().numTypes; - const real *x = nbat->x().data(); + const real* x = nbat->x().data(); npair_tot = 0; nhwu = 0; nhwu_pruned = 0; - for (const nbnxn_sci_t &nbln : nbl->sci) + for (const nbnxn_sci_t& nbln : nbl->sci) { - ish3 = 3*nbln.shift; - shX = shiftvec[ish3]; - shY = shiftvec[ish3+1]; - shZ = shiftvec[ish3+2]; - cj4_ind0 = nbln.cj4_ind_start; - cj4_ind1 = nbln.cj4_ind_end; - sci = nbln.sci; - vctot = 0; - Vvdwtot = 0; - - if (nbln.shift == CENTRAL && - nbl->cj4[cj4_ind0].cj[0] == sci*c_numClPerSupercl) + ish3 = 3 * nbln.shift; + shX = shiftvec[ish3]; + shY = shiftvec[ish3 + 1]; + shZ = shiftvec[ish3 + 2]; + cj4_ind0 = nbln.cj4_ind_start; + cj4_ind1 = nbln.cj4_ind_end; + sci = nbln.sci; + vctot = 0; + Vvdwtot = 0; + + if (nbln.shift == CENTRAL && nbl->cj4[cj4_ind0].cj[0] == sci * c_numClPerSupercl) { /* we have the diagonal: * add the charge self interaction energy term */ for (im = 0; im < c_numClPerSupercl; im++) { - ci = sci*c_numClPerSupercl + im; + ci = sci * c_numClPerSupercl + im; for (ic = 0; ic < c_clSize; ic++) { - ia = ci*c_clSize + ic; - iq = x[ia*nbat->xstride+3]; - vctot += iq*iq; + ia = ci * c_clSize + ic; + iq = x[ia * nbat->xstride + 3]; + vctot += iq * iq; } } if (!bEwald) { - vctot *= -facel*0.5*iconst->c_rf; + vctot *= -facel * 0.5 * iconst->c_rf; } else { /* last factor 1/sqrt(pi) */ - vctot *= -facel*iconst->ewaldcoeff_q*M_1_SQRTPI; + vctot *= -facel * iconst->ewaldcoeff_q * M_1_SQRTPI; } } for (cj4_ind = cj4_ind0; (cj4_ind < cj4_ind1); cj4_ind++) { - excl[0] = &nbl->excl[nbl->cj4[cj4_ind].imei[0].excl_ind]; - excl[1] = &nbl->excl[nbl->cj4[cj4_ind].imei[1].excl_ind]; + excl[0] = &nbl->excl[nbl->cj4[cj4_ind].imei[0].excl_ind]; + excl[1] = &nbl->excl[nbl->cj4[cj4_ind].imei[1].excl_ind]; for (jm = 0; jm < c_nbnxnGpuJgroupSize; jm++) { - cj = nbl->cj4[cj4_ind].cj[jm]; + cj = nbl->cj4[cj4_ind].cj[jm]; for (im = 0; im < c_numClPerSupercl; im++) { /* We're only using the first imask, * but here imei[1].imask is identical. */ - if ((nbl->cj4[cj4_ind].imei[0].imask >> (jm*c_numClPerSupercl + im)) & 1) + if ((nbl->cj4[cj4_ind].imei[0].imask >> (jm * c_numClPerSupercl + im)) & 1) { gmx_bool within_rlist; - ci = sci*c_numClPerSupercl + im; + ci = sci * c_numClPerSupercl + im; - within_rlist = FALSE; - npair = 0; + within_rlist = FALSE; + npair = 0; for (ic = 0; ic < c_clSize; ic++) { - ia = ci*c_clSize + ic; + ia = ci * c_clSize + ic; - is = ia*nbat->xstride; - ifs = ia*nbat->fstride; - ix = shX + x[is+0]; - iy = shY + x[is+1]; - iz = shZ + x[is+2]; - iq = facel*x[is+3]; - nti = ntype*2*type[ia]; + is = ia * nbat->xstride; + ifs = ia * nbat->fstride; + ix = shX + x[is + 0]; + iy = shY + x[is + 1]; + iz = shZ + x[is + 2]; + iq = facel * x[is + 3]; + nti = ntype * 2 * type[ia]; - fix = 0; - fiy = 0; - fiz = 0; + fix = 0; + fiy = 0; + fiz = 0; for (jc = 0; jc < c_clSize; jc++) { - ja = cj*c_clSize + jc; + ja = cj * c_clSize + jc; - if (nbln.shift == CENTRAL && - ci == cj && ja <= ia) + if (nbln.shift == CENTRAL && ci == cj && ja <= ia) { continue; } - constexpr int clusterPerSplit = c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit; - int_bit = static_cast((excl[jc/clusterPerSplit]->pair[(jc & (clusterPerSplit - 1))*c_clSize + ic] - >> (jm*c_numClPerSupercl + im)) & 1); - - js = ja*nbat->xstride; - jfs = ja*nbat->fstride; - jx = x[js+0]; - jy = x[js+1]; - jz = x[js+2]; - dx = ix - jx; - dy = iy - jy; - dz = iz - jz; - rsq = dx*dx + dy*dy + dz*dz; + constexpr int clusterPerSplit = + c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit; + int_bit = static_cast( + (excl[jc / clusterPerSplit]->pair[(jc & (clusterPerSplit - 1)) * c_clSize + ic] + >> (jm * c_numClPerSupercl + im)) + & 1); + + js = ja * nbat->xstride; + jfs = ja * nbat->fstride; + jx = x[js + 0]; + jy = x[js + 1]; + jz = x[js + 2]; + dx = ix - jx; + dy = iy - jy; + dz = iz - jz; + rsq = dx * dx + dy * dy + dz * dz; if (rsq < rlist2) { within_rlist = TRUE; @@ -245,90 +248,94 @@ nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, continue; } - if (type[ia] != ntype-1 && type[ja] != ntype-1) + if (type[ia] != ntype - 1 && type[ja] != ntype - 1) { npair++; } // Ensure distance do not become so small that r^-12 overflows - rsq = std::max(rsq, NBNXN_MIN_RSQ); + rsq = std::max(rsq, NBNXN_MIN_RSQ); - rinv = gmx::invsqrt(rsq); - rinvsq = rinv*rinv; + rinv = gmx::invsqrt(rsq); + rinvsq = rinv * rinv; - qq = iq*x[js+3]; + qq = iq * x[js + 3]; if (!bEwald) { /* Reaction-field */ - krsq = iconst->k_rf*rsq; - fscal = qq*(int_bit*rinv - 2*krsq)*rinvsq; + krsq = iconst->k_rf * rsq; + fscal = qq * (int_bit * rinv - 2 * krsq) * rinvsq; if (stepWork.computeEnergy) { - vcoul = qq*(int_bit*rinv + krsq - iconst->c_rf); + vcoul = qq * (int_bit * rinv + krsq - iconst->c_rf); } } else { - r = rsq*rinv; - rt = r*iconst->coulombEwaldTables->scale; - n0 = static_cast(rt); - eps = rt - static_cast(n0); + r = rsq * rinv; + rt = r * iconst->coulombEwaldTables->scale; + n0 = static_cast(rt); + eps = rt - static_cast(n0); - fexcl = (1 - eps)*Ftab[n0] + eps*Ftab[n0+1]; + fexcl = (1 - eps) * Ftab[n0] + eps * Ftab[n0 + 1]; - fscal = qq*(int_bit*rinvsq - fexcl)*rinv; + fscal = qq * (int_bit * rinvsq - fexcl) * rinv; if (stepWork.computeEnergy) { - vcoul = qq*((int_bit - std::erf(iconst->ewaldcoeff_q*r))*rinv - int_bit*iconst->sh_ewald); + vcoul = qq + * ((int_bit - std::erf(iconst->ewaldcoeff_q * r)) * rinv + - int_bit * iconst->sh_ewald); } } if (rsq < rvdw2) { - tj = nti + 2*type[ja]; + tj = nti + 2 * type[ja]; /* Vanilla Lennard-Jones cutoff */ - c6 = vdwparam[tj]; - c12 = vdwparam[tj+1]; + c6 = vdwparam[tj]; + c12 = vdwparam[tj + 1]; - rinvsix = int_bit*rinvsq*rinvsq*rinvsq; - Vvdw_disp = c6*rinvsix; - Vvdw_rep = c12*rinvsix*rinvsix; - fscal += (Vvdw_rep - Vvdw_disp)*rinvsq; + rinvsix = int_bit * rinvsq * rinvsq * rinvsq; + Vvdw_disp = c6 * rinvsix; + Vvdw_rep = c12 * rinvsix * rinvsix; + fscal += (Vvdw_rep - Vvdw_disp) * rinvsq; if (stepWork.computeEnergy) { - vctot += vcoul; + vctot += vcoul; Vvdwtot += - (Vvdw_rep + int_bit*c12*iconst->repulsion_shift.cpot)/12 - - (Vvdw_disp + int_bit*c6*iconst->dispersion_shift.cpot)/6; + (Vvdw_rep + int_bit * c12 * iconst->repulsion_shift.cpot) / 12 + - (Vvdw_disp + + int_bit * c6 * iconst->dispersion_shift.cpot) + / 6; } } - tx = fscal*dx; - ty = fscal*dy; - tz = fscal*dz; - fix = fix + tx; - fiy = fiy + ty; - fiz = fiz + tz; - f[jfs+0] -= tx; - f[jfs+1] -= ty; - f[jfs+2] -= tz; + tx = fscal * dx; + ty = fscal * dy; + tz = fscal * dz; + fix = fix + tx; + fiy = fiy + ty; + fiz = fiz + tz; + f[jfs + 0] -= tx; + f[jfs + 1] -= ty; + f[jfs + 2] -= tz; } - f[ifs+0] += fix; - f[ifs+1] += fiy; - f[ifs+2] += fiz; - fshift[ish3] = fshift[ish3] + fix; - fshift[ish3+1] = fshift[ish3+1] + fiy; - fshift[ish3+2] = fshift[ish3+2] + fiz; + f[ifs + 0] += fix; + f[ifs + 1] += fiy; + f[ifs + 2] += fiz; + fshift[ish3] = fshift[ish3] + fix; + fshift[ish3 + 1] = fshift[ish3 + 1] + fiy; + fshift[ish3 + 2] = fshift[ish3 + 2] + fiz; /* Count in half work-units. * In CUDA one work-unit is 2 warps. */ - if ((ic+1) % (c_clSize/c_nbnxnGpuClusterpairSplit) == 0) + if ((ic + 1) % (c_clSize / c_nbnxnGpuClusterpairSplit) == 0) { npair_tot += npair; @@ -349,24 +356,22 @@ nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, if (stepWork.computeEnergy) { - ggid = 0; - Vc[ggid] = Vc[ggid] + vctot; - Vvdw[ggid] = Vvdw[ggid] + Vvdwtot; + ggid = 0; + Vc[ggid] = Vc[ggid] + vctot; + Vvdw[ggid] = Vvdw[ggid] + Vvdwtot; } } if (debug) { fprintf(debug, "number of half %dx%d atom pairs: %d after pruning: %d fraction %4.2f\n", - nbl->na_ci, nbl->na_ci, - nhwu, nhwu_pruned, nhwu_pruned/static_cast(nhwu)); + nbl->na_ci, nbl->na_ci, nhwu, nhwu_pruned, nhwu_pruned / static_cast(nhwu)); fprintf(debug, "generic kernel pair interactions: %d\n", - nhwu*nbl->na_ci/2*nbl->na_ci); + nhwu * nbl->na_ci / 2 * nbl->na_ci); fprintf(debug, "generic kernel post-prune pair interactions: %d\n", - nhwu_pruned*nbl->na_ci/2*nbl->na_ci); - fprintf(debug, "generic kernel non-zero pair interactions: %d\n", - npair_tot); + nhwu_pruned * nbl->na_ci / 2 * nbl->na_ci); + fprintf(debug, "generic kernel non-zero pair interactions: %d\n", npair_tot); fprintf(debug, "ratio non-zero/post-prune pair interactions: %4.2f\n", - npair_tot/static_cast(nhwu_pruned*gmx::exactDiv(nbl->na_ci, 2)*nbl->na_ci)); + npair_tot / static_cast(nhwu_pruned * gmx::exactDiv(nbl->na_ci, 2) * nbl->na_ci)); } } diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.h b/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.h index c508f1e34c..1351694087 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.h +++ b/src/gromacs/nbnxm/kernels_reference/kernel_gpu_ref.h @@ -50,16 +50,15 @@ class StepWorkload; } /* Reference (slow) kernel for nb n vs n GPU type pair lists */ -void -nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu *nbl, - const nbnxn_atomdata_t *nbat, - const interaction_const_t *iconst, - rvec *shift_vec, - const gmx::StepWorkload &stepWork, - int clearF, - gmx::ArrayRef f, - real * fshift, - real * Vc, - real * Vvdw); +void nbnxn_kernel_gpu_ref(const NbnxnPairlistGpu* nbl, + const nbnxn_atomdata_t* nbat, + const interaction_const_t* iconst, + rvec* shift_vec, + const gmx::StepWorkload& stepWork, + int clearF, + gmx::ArrayRef f, + real* fshift, + real* Vc, + real* Vvdw); #endif diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_ref.h b/src/gromacs/nbnxm/kernels_reference/kernel_ref.h index 1fa3848da1..e713e7a88e 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_ref.h +++ b/src/gromacs/nbnxm/kernels_reference/kernel_ref.h @@ -53,37 +53,37 @@ nbk_func_noener nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref; nbk_func_noener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref; nbk_func_noener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJ_VF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJ_VF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref; -nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref; +nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref; #ifdef INCLUDE_KERNELFUNCTION_TABLES @@ -93,124 +93,58 @@ nbk_func_ener nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref; * For the C reference kernels, unlike the SIMD kernels, there is not much * advantage in using combination rules, so we (re-)use the same kernel. */ -static p_nbk_func_noener nbnxn_kernel_noener_ref[coulktNR][vdwktNR_ref] = -{ - { - nbnxn_kernel_ElecRF_VdwLJ_F_ref, - nbnxn_kernel_ElecRF_VdwLJ_F_ref, - nbnxn_kernel_ElecRF_VdwLJ_F_ref, - nbnxn_kernel_ElecRF_VdwLJFsw_F_ref, - nbnxn_kernel_ElecRF_VdwLJPsw_F_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_ref - }, - { - nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJFsw_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJPsw_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_F_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref - } +static p_nbk_func_noener nbnxn_kernel_noener_ref[coulktNR][vdwktNR_ref] = { + { nbnxn_kernel_ElecRF_VdwLJ_F_ref, nbnxn_kernel_ElecRF_VdwLJ_F_ref, nbnxn_kernel_ElecRF_VdwLJ_F_ref, + nbnxn_kernel_ElecRF_VdwLJFsw_F_ref, nbnxn_kernel_ElecRF_VdwLJPsw_F_ref, + nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_ref, nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_ref }, + { nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, nbnxn_kernel_ElecQSTab_VdwLJ_F_ref, + nbnxn_kernel_ElecQSTab_VdwLJFsw_F_ref, nbnxn_kernel_ElecQSTab_VdwLJPsw_F_ref, + nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_F_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_F_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_F_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_F_ref } }; -static p_nbk_func_ener nbnxn_kernel_ener_ref[coulktNR][vdwktNR_ref] = -{ - { - nbnxn_kernel_ElecRF_VdwLJ_VF_ref, - nbnxn_kernel_ElecRF_VdwLJ_VF_ref, - nbnxn_kernel_ElecRF_VdwLJ_VF_ref, - nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref, - nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref - }, - { - nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref - } +static p_nbk_func_ener nbnxn_kernel_ener_ref[coulktNR][vdwktNR_ref] = { + { nbnxn_kernel_ElecRF_VdwLJ_VF_ref, nbnxn_kernel_ElecRF_VdwLJ_VF_ref, nbnxn_kernel_ElecRF_VdwLJ_VF_ref, + nbnxn_kernel_ElecRF_VdwLJFsw_VF_ref, nbnxn_kernel_ElecRF_VdwLJPsw_VF_ref, + nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_ref, nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_ref }, + { nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, + nbnxn_kernel_ElecQSTab_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJFsw_VF_ref, + nbnxn_kernel_ElecQSTab_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VF_ref, + nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VF_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VF_ref } }; -static p_nbk_func_ener nbnxn_kernel_energrp_ref[coulktNR][vdwktNR_ref] = -{ - { - nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref, - nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref - }, - { - nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref, - nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref - }, - { - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref, - nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref - } +static p_nbk_func_ener nbnxn_kernel_energrp_ref[coulktNR][vdwktNR_ref] = { + { nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, + nbnxn_kernel_ElecRF_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJFsw_VgrpF_ref, + nbnxn_kernel_ElecRF_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_ref, + nbnxn_kernel_ElecRF_VdwLJEwCombLB_VgrpF_ref }, + { nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, + nbnxn_kernel_ElecQSTab_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJFsw_VgrpF_ref, + nbnxn_kernel_ElecQSTab_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_ref, + nbnxn_kernel_ElecQSTab_VdwLJEwCombLB_VgrpF_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref }, + { nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJFsw_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJPsw_VgrpF_ref, nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_ref, + nbnxn_kernel_ElecQSTabTwinCut_VdwLJEwCombLB_VgrpF_ref } }; #endif /* INCLUDE_KERNELFUNCTION_TABLES */ diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_ref_inner.h b/src/gromacs/nbnxm/kernels_reference/kernel_ref_inner.h index dc679f72f5..4181367941 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_ref_inner.h +++ b/src/gromacs/nbnxm/kernels_reference/kernel_ref_inner.h @@ -37,7 +37,7 @@ * forces and energies on excluded atom pairs here in the non-bonded loops. */ #if defined CHECK_EXCLS && (defined CALC_COULOMB || defined LJ_EWALD) -#define EXCL_FORCES +# define EXCL_FORCES #endif { @@ -58,34 +58,34 @@ int type_i_off; int j; - ai = ci*UNROLLI + i; + ai = ci * UNROLLI + i; - type_i_off = type[ai]*ntype2; + type_i_off = type[ai] * ntype2; for (j = 0; j < UNROLLJ; j++) { - int aj; - real dx, dy, dz; - real rsq, rinv; - real rinvsq, rinvsix; - real c6, c12; - real FrLJ6 = 0, FrLJ12 = 0, frLJ = 0; - real VLJ gmx_unused; + int aj; + real dx, dy, dz; + real rsq, rinv; + real rinvsq, rinvsix; + real c6, c12; + real FrLJ6 = 0, FrLJ12 = 0, frLJ = 0; + real VLJ gmx_unused; #if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - real r, rsw; + real r, rsw; #endif #ifdef CALC_COULOMB real qq; real fcoul; -#ifdef CALC_COUL_TAB +# ifdef CALC_COUL_TAB real rs, frac; int ri; real fexcl; -#endif -#ifdef CALC_ENERGIES +# endif +# ifdef CALC_ENERGIES real vcoul; -#endif +# endif #endif real fscal; real fx, fy, fz; @@ -100,26 +100,26 @@ /* A multiply mask used to zero an interaction * when that interaction should be excluded * (e.g. because of bonding). */ - real interact = static_cast((l_cj[cjind].excl>>(i*UNROLLI + j)) & 1); -#ifndef EXCL_FORCES + real interact = static_cast((l_cj[cjind].excl >> (i * UNROLLI + j)) & 1); +# ifndef EXCL_FORCES skipmask = interact; -#else +# else skipmask = (cj == ci_sh && j <= i) ? 0.0 : 1.0; -#endif +# endif #else constexpr real interact = 1.0; - skipmask = interact; + skipmask = interact; #endif VLJ = 0; - aj = cj*UNROLLJ + j; + aj = cj * UNROLLJ + j; - dx = xi[i*XI_STRIDE+XX] - x[aj*X_STRIDE+XX]; - dy = xi[i*XI_STRIDE+YY] - x[aj*X_STRIDE+YY]; - dz = xi[i*XI_STRIDE+ZZ] - x[aj*X_STRIDE+ZZ]; + dx = xi[i * XI_STRIDE + XX] - x[aj * X_STRIDE + XX]; + dy = xi[i * XI_STRIDE + YY] - x[aj * X_STRIDE + YY]; + dz = xi[i * XI_STRIDE + ZZ] - x[aj * X_STRIDE + ZZ]; - rsq = dx*dx + dy*dy + dz*dz; + rsq = dx * dx + dy * dy + dz * dz; /* Prepare to enforce the cut-off. */ skipmask = (rsq >= rcut2) ? 0 : skipmask; @@ -142,43 +142,43 @@ * the Coulomb table during lookup. */ rinv = rinv * skipmask; - rinvsq = rinv*rinv; + rinvsq = rinv * rinv; #ifdef HALF_LJ - if (i < UNROLLI/2) + if (i < UNROLLI / 2) #endif { - c6 = nbfp[type_i_off+type[aj]*2 ]; - c12 = nbfp[type_i_off+type[aj]*2+1]; + c6 = nbfp[type_i_off + type[aj] * 2]; + c12 = nbfp[type_i_off + type[aj] * 2 + 1]; #if defined LJ_CUT || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - rinvsix = interact*rinvsq*rinvsq*rinvsq; - FrLJ6 = c6*rinvsix; - FrLJ12 = c12*rinvsix*rinvsix; + rinvsix = interact * rinvsq * rinvsq * rinvsq; + FrLJ6 = c6 * rinvsix; + FrLJ12 = c12 * rinvsix * rinvsix; frLJ = FrLJ12 - FrLJ6; /* 7 flops for r^-2 + LJ force */ -#if defined CALC_ENERGIES || defined LJ_POT_SWITCH - VLJ = (FrLJ12 + c12*ic->repulsion_shift.cpot)/12 - - (FrLJ6 + c6*ic->dispersion_shift.cpot)/6; +# if defined CALC_ENERGIES || defined LJ_POT_SWITCH + VLJ = (FrLJ12 + c12 * ic->repulsion_shift.cpot) / 12 + - (FrLJ6 + c6 * ic->dispersion_shift.cpot) / 6; /* 7 flops for LJ energy */ -#endif +# endif #endif #if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH /* Force or potential switching from ic->rvdw_switch */ - r = rsq*rinv; - rsw = r - ic->rvdw_switch; - rsw = (rsw >= 0.0 ? rsw : 0.0); + r = rsq * rinv; + rsw = r - ic->rvdw_switch; + rsw = (rsw >= 0.0 ? rsw : 0.0); #endif #ifdef LJ_FORCE_SWITCH - frLJ += - -c6*(ic->dispersion_shift.c2 + ic->dispersion_shift.c3*rsw)*rsw*rsw*r - + c12*(ic->repulsion_shift.c2 + ic->repulsion_shift.c3*rsw)*rsw*rsw*r; -#if defined CALC_ENERGIES - VLJ += - -c6*(-ic->dispersion_shift.c2/3 - ic->dispersion_shift.c3/4*rsw)*rsw*rsw*rsw - + c12*(-ic->repulsion_shift.c2/3 - ic->repulsion_shift.c3/4*rsw)*rsw*rsw*rsw; -#endif + frLJ += -c6 * (ic->dispersion_shift.c2 + ic->dispersion_shift.c3 * rsw) * rsw * rsw * r + + c12 * (ic->repulsion_shift.c2 + ic->repulsion_shift.c3 * rsw) * rsw * rsw * r; +# if defined CALC_ENERGIES + VLJ += -c6 * (-ic->dispersion_shift.c2 / 3 - ic->dispersion_shift.c3 / 4 * rsw) + * rsw * rsw * rsw + + c12 * (-ic->repulsion_shift.c2 / 3 - ic->repulsion_shift.c3 / 4 * rsw) + * rsw * rsw * rsw; +# endif #endif #if defined CALC_ENERGIES || defined LJ_POT_SWITCH @@ -186,69 +186,69 @@ * but before potential switching. */ /* Need to zero the interaction if there should be exclusion. */ - VLJ = VLJ * interact; + VLJ = VLJ * interact; #endif #ifdef LJ_POT_SWITCH { real sw, dsw; - sw = 1.0 + (swV3 + (swV4+ swV5*rsw)*rsw)*rsw*rsw*rsw; - dsw = (swF2 + (swF3 + swF4*rsw)*rsw)*rsw*rsw; + sw = 1.0 + (swV3 + (swV4 + swV5 * rsw) * rsw) * rsw * rsw * rsw; + dsw = (swF2 + (swF3 + swF4 * rsw) * rsw) * rsw * rsw; - frLJ = frLJ*sw - r*VLJ*dsw; - VLJ *= sw; + frLJ = frLJ * sw - r * VLJ * dsw; + VLJ *= sw; } #endif #ifdef LJ_EWALD { - real c6grid, rinvsix_nm, cr2, expmcr2, poly; -#ifdef CALC_ENERGIES - real sh_mask; -#endif - -#ifdef LJ_EWALD_COMB_GEOM - c6grid = ljc[type[ai]*2]*ljc[type[aj]*2]; -#elif defined LJ_EWALD_COMB_LB + real c6grid, rinvsix_nm, cr2, expmcr2, poly; +# ifdef CALC_ENERGIES + real sh_mask; +# endif + +# ifdef LJ_EWALD_COMB_GEOM + c6grid = ljc[type[ai] * 2] * ljc[type[aj] * 2]; +# elif defined LJ_EWALD_COMB_LB { real sigma, sigma2, epsilon; /* These sigma and epsilon are scaled to give 6*C6 */ - sigma = ljc[type[ai]*2] + ljc[type[aj]*2]; - epsilon = ljc[type[ai]*2+1]*ljc[type[aj]*2+1]; + sigma = ljc[type[ai] * 2] + ljc[type[aj] * 2]; + epsilon = ljc[type[ai] * 2 + 1] * ljc[type[aj] * 2 + 1]; - sigma2 = sigma*sigma; - c6grid = epsilon*sigma2*sigma2*sigma2; + sigma2 = sigma * sigma; + c6grid = epsilon * sigma2 * sigma2 * sigma2; } -#else -#error "No LJ Ewald combination rule defined" -#endif +# else +# error "No LJ Ewald combination rule defined" +# endif -#ifdef CHECK_EXCLS +# ifdef CHECK_EXCLS /* Recalculate rinvsix without exclusion mask */ - rinvsix_nm = rinvsq*rinvsq*rinvsq; -#else - rinvsix_nm = rinvsix; -#endif - cr2 = lje_coeff2*rsq; -#if GMX_DOUBLE - expmcr2 = exp(-cr2); -#else - expmcr2 = expf(-cr2); -#endif - poly = 1 + cr2 + 0.5*cr2*cr2; + rinvsix_nm = rinvsq * rinvsq * rinvsq; +# else + rinvsix_nm = rinvsix; +# endif + cr2 = lje_coeff2 * rsq; +# if GMX_DOUBLE + expmcr2 = exp(-cr2); +# else + expmcr2 = expf(-cr2); +# endif + poly = 1 + cr2 + 0.5 * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - frLJ += c6grid*(rinvsix_nm - expmcr2*(rinvsix_nm*poly + lje_coeff6_6)); -#ifdef CALC_ENERGIES + frLJ += c6grid * (rinvsix_nm - expmcr2 * (rinvsix_nm * poly + lje_coeff6_6)); +# ifdef CALC_ENERGIES /* Shift should only be applied to real LJ pairs */ - sh_mask = lje_vc*interact; + sh_mask = lje_vc * interact; - VLJ += c6grid/6*(rinvsix_nm*(1 - expmcr2*poly) + sh_mask); -#endif + VLJ += c6grid / 6 * (rinvsix_nm * (1 - expmcr2 * poly) + sh_mask); +# endif } -#endif /* LJ_EWALD */ +#endif /* LJ_EWALD */ #ifdef VDW_CUTOFF_CHECK /* Mask for VdW cut-off shorter than Coulomb cut-off */ @@ -256,27 +256,27 @@ real skipmask_rvdw; skipmask_rvdw = (rsq < rvdw2) ? 1.0 : 0.0; - frLJ *= skipmask_rvdw; -#ifdef CALC_ENERGIES - VLJ *= skipmask_rvdw; -#endif + frLJ *= skipmask_rvdw; +# ifdef CALC_ENERGIES + VLJ *= skipmask_rvdw; +# endif } #else -#if defined CALC_ENERGIES +# if defined CALC_ENERGIES /* Need to zero the interaction if r >= rcut */ - VLJ = VLJ * skipmask; + VLJ = VLJ * skipmask; /* 1 more flop for LJ energy */ -#endif -#endif /* VDW_CUTOFF_CHECK */ +# endif +#endif /* VDW_CUTOFF_CHECK */ #ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS - Vvdw[egp_sh_i[i] + ((egp_cj >> (nbatParams.neg_2log*j)) & egp_mask)] += VLJ; -#else +# ifdef ENERGY_GROUPS + Vvdw[egp_sh_i[i] + ((egp_cj >> (nbatParams.neg_2log * j)) & egp_mask)] += VLJ; +# else Vvdw_ci += VLJ; /* 1 flop for LJ energy addition */ -#endif +# endif #endif } @@ -292,82 +292,82 @@ * advance. */ qq = skipmask * qi[i] * q[aj]; -#ifdef CALC_COUL_RF - fcoul = qq*(interact*rinv*rinvsq - k_rf2); +# ifdef CALC_COUL_RF + fcoul = qq * (interact * rinv * rinvsq - k_rf2); /* 4 flops for RF force */ -#ifdef CALC_ENERGIES - vcoul = qq*(interact*rinv + k_rf*rsq - c_rf); +# ifdef CALC_ENERGIES + vcoul = qq * (interact * rinv + k_rf * rsq - c_rf); /* 4 flops for RF energy */ -#endif -#endif - -#ifdef CALC_COUL_TAB - rs = rsq*rinv*tab_coul_scale; - ri = int(rs); - frac = rs - static_cast(ri); -#if !GMX_DOUBLE +# endif +# endif + +# ifdef CALC_COUL_TAB + rs = rsq * rinv * tab_coul_scale; + ri = int(rs); + frac = rs - static_cast(ri); +# if !GMX_DOUBLE /* fexcl = F_i + frac * (F_(i+1)-F_i) */ - fexcl = tab_coul_FDV0[ri*4] + frac*tab_coul_FDV0[ri*4+1]; -#else + fexcl = tab_coul_FDV0[ri * 4] + frac * tab_coul_FDV0[ri * 4 + 1]; +# else /* fexcl = (1-frac) * F_i + frac * F_(i+1) */ - fexcl = (1 - frac)*tab_coul_F[ri] + frac*tab_coul_F[ri+1]; -#endif - fcoul = interact*rinvsq - fexcl; + fexcl = (1 - frac) * tab_coul_F[ri] + frac * tab_coul_F[ri + 1]; +# endif + fcoul = interact * rinvsq - fexcl; /* 7 flops for float 1/r-table force */ -#ifdef CALC_ENERGIES -#if !GMX_DOUBLE - vcoul = qq*(interact*(rinv - ic->sh_ewald) - -(tab_coul_FDV0[ri*4+2] - -halfsp*frac*(tab_coul_FDV0[ri*4] + fexcl))); +# ifdef CALC_ENERGIES +# if !GMX_DOUBLE + vcoul = qq + * (interact * (rinv - ic->sh_ewald) + - (tab_coul_FDV0[ri * 4 + 2] - halfsp * frac * (tab_coul_FDV0[ri * 4] + fexcl))); /* 7 flops for float 1/r-table energy (8 with excls) */ -#else - vcoul = qq*(interact*(rinv - ic->sh_ewald) - -(tab_coul_V[ri] - -halfsp*frac*(tab_coul_F[ri] + fexcl))); -#endif -#endif - fcoul *= qq*rinv; -#endif - -#ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS - Vc[egp_sh_i[i] + ((egp_cj >> (nbatParams.neg_2log*j)) & egp_mask)] += vcoul; -#else +# else + vcoul = qq + * (interact * (rinv - ic->sh_ewald) + - (tab_coul_V[ri] - halfsp * frac * (tab_coul_F[ri] + fexcl))); +# endif +# endif + fcoul *= qq * rinv; +# endif + +# ifdef CALC_ENERGIES +# ifdef ENERGY_GROUPS + Vc[egp_sh_i[i] + ((egp_cj >> (nbatParams.neg_2log * j)) & egp_mask)] += vcoul; +# else Vc_ci += vcoul; /* 1 flop for Coulomb energy addition */ -#endif -#endif +# endif +# endif #endif #ifdef CALC_COULOMB -#ifdef HALF_LJ - if (i < UNROLLI/2) -#endif +# ifdef HALF_LJ + if (i < UNROLLI / 2) +# endif { - fscal = frLJ*rinvsq + fcoul; + fscal = frLJ * rinvsq + fcoul; /* 2 flops for scalar LJ+Coulomb force */ } -#ifdef HALF_LJ +# ifdef HALF_LJ else { fscal = fcoul; } -#endif +# endif #else - fscal = frLJ*rinvsq; + fscal = frLJ * rinvsq; #endif - fx = fscal*dx; - fy = fscal*dy; - fz = fscal*dz; + fx = fscal * dx; + fy = fscal * dy; + fz = fscal * dz; /* Increment i-atom force */ - fi[i*FI_STRIDE+XX] += fx; - fi[i*FI_STRIDE+YY] += fy; - fi[i*FI_STRIDE+ZZ] += fz; + fi[i * FI_STRIDE + XX] += fx; + fi[i * FI_STRIDE + YY] += fy; + fi[i * FI_STRIDE + ZZ] += fz; /* Decrement j-atom force */ - f[aj*F_STRIDE+XX] -= fx; - f[aj*F_STRIDE+YY] -= fy; - f[aj*F_STRIDE+ZZ] -= fz; + f[aj * F_STRIDE + XX] -= fx; + f[aj * F_STRIDE + YY] -= fy; + f[aj * F_STRIDE + ZZ] -= fz; /* 9 flops for force addition */ } } diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_ref_outer.h b/src/gromacs/nbnxm/kernels_reference/kernel_ref_outer.h index c72d85f2ac..a166ab79e8 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_ref_outer.h +++ b/src/gromacs/nbnxm/kernels_reference/kernel_ref_outer.h @@ -33,17 +33,17 @@ * the research papers on the package. Check out http://www.gromacs.org. */ -#define UNROLLI 4 -#define UNROLLJ 4 +#define UNROLLI 4 +#define UNROLLJ 4 static_assert(UNROLLI == c_nbnxnCpuIClusterSize, "UNROLLI should match the i-cluster size"); /* We could use nbat->xstride and nbat->fstride, but macros might be faster */ -#define X_STRIDE 3 -#define F_STRIDE 3 +#define X_STRIDE 3 +#define F_STRIDE 3 /* Local i-atom buffer strides */ -#define XI_STRIDE 3 -#define FI_STRIDE 3 +#define XI_STRIDE 3 +#define FI_STRIDE 3 /* All functionality defines are set here, except for: @@ -55,112 +55,112 @@ static_assert(UNROLLI == c_nbnxnCpuIClusterSize, "UNROLLI should match the i-clu #define CALC_SHIFTFORCES #ifdef CALC_COUL_RF -#define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel ## _ElecRF ## ljt ## feg ## _ref +# define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel##_ElecRF##ljt##feg##_ref #endif #ifdef CALC_COUL_TAB -#ifndef VDW_CUTOFF_CHECK -#define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel ## _ElecQSTab ## ljt ## feg ## _ref -#else -#define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel ## _ElecQSTabTwinCut ## ljt ## feg ## _ref -#endif +# ifndef VDW_CUTOFF_CHECK +# define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel##_ElecQSTab##ljt##feg##_ref +# else +# define NBK_FUNC_NAME2(ljt, feg) nbnxn_kernel##_ElecQSTabTwinCut##ljt##feg##_ref +# endif #endif #if defined LJ_CUT && !defined LJ_EWALD -#define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJ, feg) +# define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJ, feg) #elif defined LJ_FORCE_SWITCH -#define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJFsw, feg) +# define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJFsw, feg) #elif defined LJ_POT_SWITCH -#define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJPsw, feg) +# define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJPsw, feg) #elif defined LJ_EWALD -#ifdef LJ_EWALD_COMB_GEOM -#define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJEwCombGeom, feg) -#else -#define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJEwCombLB, feg) -#endif +# ifdef LJ_EWALD_COMB_GEOM +# define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJEwCombGeom, feg) +# else +# define NBK_FUNC_NAME(feg) NBK_FUNC_NAME2(_VdwLJEwCombLB, feg) +# endif #else -#error "No VdW type defined" +# error "No VdW type defined" #endif void #ifndef CALC_ENERGIES -NBK_FUNC_NAME(_F) // NOLINT(misc-definitions-in-headers) -#else -#ifndef ENERGY_GROUPS -NBK_FUNC_NAME(_VF) // NOLINT(misc-definitions-in-headers) + NBK_FUNC_NAME(_F) // NOLINT(misc-definitions-in-headers) #else -NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) -#endif +# ifndef ENERGY_GROUPS + NBK_FUNC_NAME(_VF) // NOLINT(misc-definitions-in-headers) +# else + NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) +# endif #endif #undef NBK_FUNC_NAME #undef NBK_FUNC_NAME2 -(const NbnxnPairlistCpu *nbl, - const nbnxn_atomdata_t *nbat, - const interaction_const_t *ic, - const rvec *shift_vec, - nbnxn_atomdata_output_t *out) + (const NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const interaction_const_t* ic, + const rvec* shift_vec, + nbnxn_atomdata_output_t* out) { /* Unpack pointers for output */ - real *f = out->f.data(); + real* f = out->f.data(); #ifdef CALC_SHIFTFORCES - real *fshift = out->fshift.data(); + real* fshift = out->fshift.data(); #endif #ifdef CALC_ENERGIES - real *Vvdw = out->Vvdw.data(); - real *Vc = out->Vc.data(); + real* Vvdw = out->Vvdw.data(); + real* Vc = out->Vc.data(); #endif - const nbnxn_cj_t *l_cj; - real rcut2; + const nbnxn_cj_t* l_cj; + real rcut2; #ifdef VDW_CUTOFF_CHECK - real rvdw2; + real rvdw2; #endif - int ntype2; - real facel; - int ci, ci_sh; - int ish, ishf; - gmx_bool do_LJ, half_LJ, do_coul; - int cjind0, cjind1, cjind; + int ntype2; + real facel; + int ci, ci_sh; + int ish, ishf; + gmx_bool do_LJ, half_LJ, do_coul; + int cjind0, cjind1, cjind; - real xi[UNROLLI*XI_STRIDE]; - real fi[UNROLLI*FI_STRIDE]; - real qi[UNROLLI]; + real xi[UNROLLI * XI_STRIDE]; + real fi[UNROLLI * FI_STRIDE]; + real qi[UNROLLI]; #ifdef CALC_ENERGIES -#ifndef ENERGY_GROUPS +# ifndef ENERGY_GROUPS - real Vvdw_ci, Vc_ci; -#else - int egp_mask; - int egp_sh_i[UNROLLI]; -#endif + real Vvdw_ci, Vc_ci; +# else + int egp_mask; + int egp_sh_i[UNROLLI]; +# endif #endif #ifdef LJ_POT_SWITCH - real swV3, swV4, swV5; - real swF2, swF3, swF4; + real swV3, swV4, swV5; + real swF2, swF3, swF4; #endif #ifdef LJ_EWALD - real lje_coeff2, lje_coeff6_6; -#ifdef CALC_ENERGIES - real lje_vc; -#endif + real lje_coeff2, lje_coeff6_6; +# ifdef CALC_ENERGIES + real lje_vc; +# endif #endif #ifdef CALC_COUL_RF - real k_rf2; -#ifdef CALC_ENERGIES - real k_rf, c_rf; -#endif + real k_rf2; +# ifdef CALC_ENERGIES + real k_rf, c_rf; +# endif #endif #ifdef CALC_COUL_TAB -#ifdef CALC_ENERGIES - real halfsp; -#endif -#if !GMX_DOUBLE - const real *tab_coul_FDV0; -#else - const real *tab_coul_F; - const real gmx_unused *tab_coul_V; -#endif +# ifdef CALC_ENERGIES + real halfsp; +# endif +# if !GMX_DOUBLE + const real* tab_coul_FDV0; +# else + const real* tab_coul_F; + const real gmx_unused* tab_coul_V; +# endif #endif #ifdef COUNT_PAIRS @@ -171,42 +171,42 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) swV3 = ic->vdw_switch.c3; swV4 = ic->vdw_switch.c4; swV5 = ic->vdw_switch.c5; - swF2 = 3*ic->vdw_switch.c3; - swF3 = 4*ic->vdw_switch.c4; - swF4 = 5*ic->vdw_switch.c5; + swF2 = 3 * ic->vdw_switch.c3; + swF3 = 4 * ic->vdw_switch.c4; + swF4 = 5 * ic->vdw_switch.c5; #endif - const nbnxn_atomdata_t::Params &nbatParams = nbat->params(); + const nbnxn_atomdata_t::Params& nbatParams = nbat->params(); #ifdef LJ_EWALD - lje_coeff2 = ic->ewaldcoeff_lj*ic->ewaldcoeff_lj; - lje_coeff6_6 = lje_coeff2*lje_coeff2*lje_coeff2/6.0; -#ifdef CALC_ENERGIES - lje_vc = ic->sh_lj_ewald; -#endif + lje_coeff2 = ic->ewaldcoeff_lj * ic->ewaldcoeff_lj; + lje_coeff6_6 = lje_coeff2 * lje_coeff2 * lje_coeff2 / 6.0; +# ifdef CALC_ENERGIES + lje_vc = ic->sh_lj_ewald; +# endif - const real *ljc = nbatParams.nbfp_comb.data(); + const real* ljc = nbatParams.nbfp_comb.data(); #endif #ifdef CALC_COUL_RF - k_rf2 = 2*ic->k_rf; -#ifdef CALC_ENERGIES + k_rf2 = 2 * ic->k_rf; +# ifdef CALC_ENERGIES k_rf = ic->k_rf; c_rf = ic->c_rf; -#endif +# endif #endif #ifdef CALC_COUL_TAB const real tab_coul_scale = ic->coulombEwaldTables->scale; -#ifdef CALC_ENERGIES - halfsp = 0.5/tab_coul_scale; -#endif +# ifdef CALC_ENERGIES + halfsp = 0.5 / tab_coul_scale; +# endif -#if !GMX_DOUBLE +# if !GMX_DOUBLE tab_coul_FDV0 = ic->coulombEwaldTables->tableFDV0.data(); -#else - tab_coul_F = ic->coulombEwaldTables->tableF.data(); - tab_coul_V = ic->coulombEwaldTables->tableV.data(); -#endif +# else + tab_coul_F = ic->coulombEwaldTables->tableF.data(); + tab_coul_V = ic->coulombEwaldTables->tableV.data(); +# endif #endif #ifdef ENERGY_GROUPS @@ -214,33 +214,33 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) #endif - rcut2 = ic->rcoulomb*ic->rcoulomb; + rcut2 = ic->rcoulomb * ic->rcoulomb; #ifdef VDW_CUTOFF_CHECK - rvdw2 = ic->rvdw*ic->rvdw; + rvdw2 = ic->rvdw * ic->rvdw; #endif - ntype2 = nbatParams.numTypes*2; - const real *nbfp = nbatParams.nbfp.data(); - const real *q = nbatParams.q.data(); - const int *type = nbatParams.type.data(); + ntype2 = nbatParams.numTypes * 2; + const real* nbfp = nbatParams.nbfp.data(); + const real* q = nbatParams.q.data(); + const int* type = nbatParams.type.data(); facel = ic->epsfac; - const real *shiftvec = shift_vec[0]; - const real *x = nbat->x().data(); + const real* shiftvec = shift_vec[0]; + const real* x = nbat->x().data(); l_cj = nbl->cj.data(); - for (const nbnxn_ci_t &ciEntry : nbl->ci) + for (const nbnxn_ci_t& ciEntry : nbl->ci) { int i, d; - ish = (ciEntry.shift & NBNXN_CI_SHIFT); + ish = (ciEntry.shift & NBNXN_CI_SHIFT); /* x, f and fshift are assumed to be stored with stride 3 */ - ishf = ish*DIM; - cjind0 = ciEntry.cj_ind_start; - cjind1 = ciEntry.cj_ind_end; + ishf = ish * DIM; + cjind0 = ciEntry.cj_ind_start; + cjind1 = ciEntry.cj_ind_end; /* Currently only works super-cells equal to sub-cells */ - ci = ciEntry.ci; - ci_sh = (ish == CENTRAL ? ci : -1); + ci = ciEntry.ci; + ci_sh = (ish == CENTRAL ? ci : -1); /* We have 5 LJ/C combinations, but use only three inner loops, * as the other combinations are unlikely and/or not much faster: @@ -253,32 +253,33 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) half_LJ = (((ciEntry.shift & NBNXN_CI_HALF_LJ(0)) != 0) || !do_LJ) && do_coul; #ifdef CALC_ENERGIES -#ifdef LJ_EWALD +# ifdef LJ_EWALD gmx_bool do_self = TRUE; -#else +# else gmx_bool do_self = do_coul; -#endif +# endif -#ifndef ENERGY_GROUPS +# ifndef ENERGY_GROUPS Vvdw_ci = 0; Vc_ci = 0; -#else +# else for (i = 0; i < UNROLLI; i++) { - egp_sh_i[i] = ((nbatParams.energrp[ci] >> (i*nbatParams.neg_2log)) & egp_mask)*nbatParams.nenergrp; + egp_sh_i[i] = ((nbatParams.energrp[ci] >> (i * nbatParams.neg_2log)) & egp_mask) + * nbatParams.nenergrp; } -#endif +# endif #endif for (i = 0; i < UNROLLI; i++) { for (d = 0; d < DIM; d++) { - xi[i*XI_STRIDE+d] = x[(ci*UNROLLI+i)*X_STRIDE+d] + shiftvec[ishf+d]; - fi[i*FI_STRIDE+d] = 0; + xi[i * XI_STRIDE + d] = x[(ci * UNROLLI + i) * X_STRIDE + d] + shiftvec[ishf + d]; + fi[i * FI_STRIDE + d] = 0; } - qi[i] = facel*q[ci*UNROLLI+i]; + qi[i] = facel * q[ci * UNROLLI + i]; } #ifdef CALC_ENERGIES @@ -286,38 +287,42 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) { real Vc_sub_self; -#ifdef CALC_COUL_RF - Vc_sub_self = 0.5*c_rf; -#endif -#ifdef CALC_COUL_TAB -#if GMX_DOUBLE - Vc_sub_self = 0.5*tab_coul_V[0]; -#else - Vc_sub_self = 0.5*tab_coul_FDV0[2]; -#endif -#endif +# ifdef CALC_COUL_RF + Vc_sub_self = 0.5 * c_rf; +# endif +# ifdef CALC_COUL_TAB +# if GMX_DOUBLE + Vc_sub_self = 0.5 * tab_coul_V[0]; +# else + Vc_sub_self = 0.5 * tab_coul_FDV0[2]; +# endif +# endif if (l_cj[ciEntry.cj_ind_start].cj == ci_sh) { for (i = 0; i < UNROLLI; i++) { int egp_ind; -#ifdef ENERGY_GROUPS - egp_ind = egp_sh_i[i] + ((nbatParams.energrp[ci] >> (i*nbatParams.neg_2log)) & egp_mask); -#else +# ifdef ENERGY_GROUPS + egp_ind = egp_sh_i[i] + + ((nbatParams.energrp[ci] >> (i * nbatParams.neg_2log)) & egp_mask); +# else egp_ind = 0; -#endif +# endif /* Coulomb self interaction */ - Vc[egp_ind] -= qi[i]*q[ci*UNROLLI+i]*Vc_sub_self; + Vc[egp_ind] -= qi[i] * q[ci * UNROLLI + i] * Vc_sub_self; -#ifdef LJ_EWALD +# ifdef LJ_EWALD /* LJ Ewald self interaction */ - Vvdw[egp_ind] += 0.5*nbatParams.nbfp[nbatParams.type[ci*UNROLLI+i]*(nbatParams.numTypes + 1)*2]/6*lje_coeff6_6; -#endif + Vvdw[egp_ind] += + 0.5 + * nbatParams.nbfp[nbatParams.type[ci * UNROLLI + i] * (nbatParams.numTypes + 1) * 2] + / 6 * lje_coeff6_6; +# endif } } } -#endif /* CALC_ENERGIES */ +#endif /* CALC_ENERGIES */ cjind = cjind0; while (cjind < cjind1 && nbl->cj[cjind].excl != 0xffff) @@ -372,7 +377,7 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) { for (d = 0; d < DIM; d++) { - f[(ci*UNROLLI+i)*F_STRIDE+d] += fi[i*FI_STRIDE+d]; + f[(ci * UNROLLI + i) * F_STRIDE + d] += fi[i * FI_STRIDE + d]; } } #ifdef CALC_SHIFTFORCES @@ -383,17 +388,17 @@ NBK_FUNC_NAME(_VgrpF) // NOLINT(misc-definitions-in-headers) { for (d = 0; d < DIM; d++) { - fshift[ishf+d] += fi[i*FI_STRIDE+d]; + fshift[ishf + d] += fi[i * FI_STRIDE + d]; } } } #endif #ifdef CALC_ENERGIES -#ifndef ENERGY_GROUPS +# ifndef ENERGY_GROUPS *Vvdw += Vvdw_ci; - *Vc += Vc_ci; -#endif + *Vc += Vc_ci; +# endif #endif } diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.cpp b/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.cpp index 77360e90fc..245529cd47 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.cpp +++ b/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.cpp @@ -42,34 +42,33 @@ #include "gromacs/utility/gmxassert.h" /* Prune a single NbnxnPairlistCpu entry with distance rlistInner */ -void -nbnxn_kernel_prune_ref(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner) +void nbnxn_kernel_prune_ref(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner) { /* We avoid push_back() for efficiency reasons and resize after filling */ nbl->ci.resize(nbl->ciOuter.size()); nbl->cj.resize(nbl->cjOuter.size()); - const nbnxn_ci_t * gmx_restrict ciOuter = nbl->ciOuter.data(); - nbnxn_ci_t * gmx_restrict ciInner = nbl->ci.data(); + const nbnxn_ci_t* gmx_restrict ciOuter = nbl->ciOuter.data(); + nbnxn_ci_t* gmx_restrict ciInner = nbl->ci.data(); - const nbnxn_cj_t * gmx_restrict cjOuter = nbl->cjOuter.data(); - nbnxn_cj_t * gmx_restrict cjInner = nbl->cj.data(); + const nbnxn_cj_t* gmx_restrict cjOuter = nbl->cjOuter.data(); + nbnxn_cj_t* gmx_restrict cjInner = nbl->cj.data(); - const real * gmx_restrict shiftvec = shift_vec[0]; - const real * gmx_restrict x = nbat->x().data(); + const real* gmx_restrict shiftvec = shift_vec[0]; + const real* gmx_restrict x = nbat->x().data(); - const real rlist2 = rlistInner*rlistInner; + const real rlist2 = rlistInner * rlistInner; /* Use compile time constants to speed up the code */ - constexpr int c_xStride = 3; + constexpr int c_xStride = 3; GMX_ASSERT(c_xStride == nbat->xstride, "xStride should match nbat->xstride"); constexpr int c_xiStride = 3; - constexpr int c_iUnroll = c_nbnxnCpuIClusterSize; - constexpr int c_jUnroll = c_nbnxnCpuIClusterSize; + constexpr int c_iUnroll = c_nbnxnCpuIClusterSize; + constexpr int c_jUnroll = c_nbnxnCpuIClusterSize; /* Initialize the new list as empty and add pairs that are in range */ int nciInner = 0; @@ -77,7 +76,7 @@ nbnxn_kernel_prune_ref(NbnxnPairlistCpu * nbl, const int nciOuter = nbl->ciOuter.size(); for (int ciIndex = 0; ciIndex < nciOuter; ciIndex++) { - const nbnxn_ci_t * gmx_restrict ciEntry = &ciOuter[ciIndex]; + const nbnxn_ci_t* gmx_restrict ciEntry = &ciOuter[ciIndex]; /* Copy the original list entry to the pruned entry */ ciInner[nciInner].ci = ciEntry->ci; @@ -89,32 +88,33 @@ nbnxn_kernel_prune_ref(NbnxnPairlistCpu * nbl, int ci = ciEntry->ci; /* Load i atom coordinates */ - real xi[c_iUnroll*c_xiStride]; + real xi[c_iUnroll * c_xiStride]; for (int i = 0; i < c_iUnroll; i++) { for (int d = 0; d < DIM; d++) { - xi[i*c_xiStride + d] = x[(ci*c_iUnroll + i)*c_xStride + d] + shiftvec[ish*DIM + d]; + xi[i * c_xiStride + d] = + x[(ci * c_iUnroll + i) * c_xStride + d] + shiftvec[ish * DIM + d]; } } for (int cjind = ciEntry->cj_ind_start; cjind < ciEntry->cj_ind_end; cjind++) { /* j-cluster index */ - int cj = cjOuter[cjind].cj; + int cj = cjOuter[cjind].cj; bool isInRange = false; for (int i = 0; i < c_iUnroll && !isInRange; i++) { for (int j = 0; j < c_jUnroll; j++) { - int aj = cj*c_jUnroll + j; + int aj = cj * c_jUnroll + j; - real dx = xi[i*c_xiStride + XX] - x[aj*c_xStride + XX]; - real dy = xi[i*c_xiStride + YY] - x[aj*c_xStride + YY]; - real dz = xi[i*c_xiStride + ZZ] - x[aj*c_xStride + ZZ]; + real dx = xi[i * c_xiStride + XX] - x[aj * c_xStride + XX]; + real dy = xi[i * c_xiStride + YY] - x[aj * c_xStride + YY]; + real dz = xi[i * c_xiStride + ZZ] - x[aj * c_xStride + ZZ]; - real rsq = dx*dx + dy*dy + dz*dz; + real rsq = dx * dx + dy * dy + dz * dz; if (rsq < rlist2) { diff --git a/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.h b/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.h index 99ed0aad25..1df5dc065d 100644 --- a/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.h +++ b/src/gromacs/nbnxm/kernels_reference/kernel_ref_prune.h @@ -54,8 +54,7 @@ struct NbnxnPairlistCpu; * Reads a cluster pairlist \p nbl->ciOuter, \p nbl->cjOuter and writes * all cluster pairs within \p rlistInner to \p nbl->ci, \p nbl->cj. */ -void -nbnxn_kernel_prune_ref(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner); +void nbnxn_kernel_prune_ref(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner); diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp index 5c31698d4e..330f4f2fef 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp index 099bca66f7..78c9fecbfb 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp index 3803ed0b5d..ca1f18a47a 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp index b1d19a5773..919cb56a83 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp index e2519030b8..63f4c984e4 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp index 7a31512b03..29cdc2d9bd 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp index ab8bf8040d..e47f4e368e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp @@ -59,32 +59,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp index 7fa0320f4d..8d2845e02e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp @@ -59,32 +59,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp index 88c5f39e56..c3c2e8f708 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp @@ -60,32 +60,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp index ed6dafc43c..8fb7e03b84 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp index 2a7917b77d..2381cd4880 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp index bfb086f41e..3529c04a6b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp index c0dffe53e4..e9ad052931 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp index 657b03471f..fd7f78c97b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp index b1044f6ec5..c064fc49cb 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_F.cpp index 6b3fd93397..e5eaf912e2 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp index da9c054153..f3ba03bd7a 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp index 50300428a1..bd0099cb70 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_F.cpp index b6323323ef..76aa8e0e17 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VF.cpp index a97371bd92..aa77668421 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp index c2f21bede4..70fbaebfd8 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_F.cpp index 021a85bcbb..7834d5a441 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VF.cpp index aa0245727a..a562cbb7e4 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp index f74e7433ad..792c1d2704 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp index c3c0816b8c..c0fbdcfef3 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp index 17958821a7..7071144e63 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp index d590ea066a..5b46da9e0e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_F.cpp index 5e14ff7bbe..c6961c0a8d 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VF.cpp index 732646f5b4..8a652c7437 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp index 8e777a8320..b98a5960f9 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_F.cpp index 2c320ec859..bbc3b6c729 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VF.cpp index cccdfc3a34..ec367b7f0c 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp index bcdb0c1db4..b78e5feb89 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_F.cpp index 6db73c6f5a..fead71100f 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VF.cpp index 2a74fb38dc..54cf1461b2 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VgrpF.cpp index bac6a86676..618f1ec0cb 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecEw_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp index e72c95c2e0..0f91bc8ded 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp index bef740b5a8..dd55ce07fd 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp index 64272eafc5..79bef2945a 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp index c767d799b1..2a83d141d1 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp index 7fb5f93ef0..fb4c35c622 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp index 136fd24d4f..7da90fd4fa 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp index ca251ee586..9e8c460151 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp @@ -59,32 +59,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp index c26946ed8a..57cc21fe11 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp @@ -59,32 +59,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp index c350fbf0b7..cbc620ba6b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp @@ -60,32 +60,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp index 77788e08da..9c4341f9e5 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp index dccb70c6e3..081e506cc0 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp index a956a04f0c..1fbf92bf63 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp index 3c7f67039b..088b1c5912 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp index 836e7e660b..1796d3c32d 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp index 4ac50a3c7f..67f80433b5 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp index 527889957c..613f27de0c 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp index d2a9400d45..bb2f98280f 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp index 43b688df54..eb977badcc 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp index a607976942..f0b207e91a 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp index b33b4cf338..d5fb009deb 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp index 3185749bfc..f4230af753 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_F.cpp index f2258ecbf4..01d22582c3 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp index 0d22200922..f321d0bcc3 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp index 57f5a21772..e05d1bfa7d 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp index 50e242022f..4e5e76f05a 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp index e38e5ce8dd..6ae3aefcc1 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp index d69c2350d0..bdf058d96d 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_F.cpp index 492025318f..c197301bda 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VF.cpp index cb675bfe07..e3ce9703be 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp index 1202bff8b0..2f8ccfb73e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_F.cpp index 7c329247d0..0df5cb32da 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VF.cpp index 532ff54c75..2ae6bbe7e5 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp index 4d63e2f322..e94c44e0ef 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_F.cpp index d588630056..ca21547879 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VF.cpp index df813fd2e7..8a60d7f1f0 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp index 303e1f529b..9388c34d63 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_F.cpp index a743150246..602abcbc40 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VF.cpp index e8f402a7b4..fe3c767607 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp index 68854bb568..2b96258d76 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_F.cpp index 703f3dde71..82d8a0ee83 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VF.cpp index dc3c782d68..55fe11fda1 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp index d723ea8ace..b77347ccf5 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp index c473a78bb0..f60e814056 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp index c7d60f5fa3..55172712d2 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp index 96e03a2739..4af57dcc23 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_F.cpp index 3c2f1c0893..27f6135d94 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VF.cpp index 8d9b89a773..25340bc0ce 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp index 109fd0d5bf..536483a19e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_F.cpp index 6ff8191c8b..3a84b49636 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VF.cpp index baaf19abca..4746763b28 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp index a34e228761..9c2d1fa240 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_F.cpp index db7683699e..ebc6bcbe0b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_F_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VF.cpp index 3876f74830..6e9632c81b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VgrpF.cpp index 86f7a27499..ca45e9749e 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_ElecRF_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_2XNN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_2XNN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_2XNN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_2XNN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_2XNN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_2XNN */ diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h index d503825654..9694949fa9 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_common.h @@ -37,7 +37,7 @@ #include "gromacs/simd/simd_math.h" #include "gromacs/simd/vector_operations.h" #ifdef CALC_COUL_EWALD -#include "gromacs/math/utilities.h" +# include "gromacs/math/utilities.h" #endif #include "config.h" @@ -45,80 +45,77 @@ #include #if !GMX_SIMD_HAVE_HSIMD_UTIL_REAL -#error "Half-simd utility operations are required for the 2xNN kernels" +# error "Half-simd utility operations are required for the 2xNN kernels" #endif #ifndef GMX_SIMD_J_UNROLL_SIZE -#error "Need to define GMX_SIMD_J_UNROLL_SIZE before including the 2xnn kernel common header file" +# error "Need to define GMX_SIMD_J_UNROLL_SIZE before including the 2xnn kernel common header file" #endif -#define UNROLLI 4 -#define UNROLLJ (GMX_SIMD_REAL_WIDTH/GMX_SIMD_J_UNROLL_SIZE) +#define UNROLLI 4 +#define UNROLLJ (GMX_SIMD_REAL_WIDTH / GMX_SIMD_J_UNROLL_SIZE) static_assert(UNROLLI == c_nbnxnCpuIClusterSize, "UNROLLI should match the i-cluster size"); /* The stride of all the atom data arrays is equal to half the SIMD width */ -#define STRIDE UNROLLJ +#define STRIDE UNROLLJ #if !defined GMX_NBNXN_SIMD_2XNN && !defined GMX_NBNXN_SIMD_4XN -#error "Must define an NBNxN kernel flavour before including NBNxN kernel utility functions" +# error "Must define an NBNxN kernel flavour before including NBNxN kernel utility functions" #endif // We use the FDV0 tables for width==4 (when we can load it in one go), or if we don't have any unaligned loads #if GMX_SIMD_REAL_WIDTH == 4 || !GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL -#define TAB_FDV0 +# define TAB_FDV0 #endif #if defined UNROLLJ /* As add_ener_grp, but for two groups of UNROLLJ/2 stored in * a single SIMD register. */ -static inline void -add_ener_grp_halves(gmx::SimdReal e_S, real *v0, real *v1, const int *offset_jj) +static inline void add_ener_grp_halves(gmx::SimdReal e_S, real* v0, real* v1, const int* offset_jj) { - for (int jj = 0; jj < (UNROLLJ/2); jj++) + for (int jj = 0; jj < (UNROLLJ / 2); jj++) { - incrDualHsimd(v0+offset_jj[jj]+jj*GMX_SIMD_REAL_WIDTH/2, - v1+offset_jj[jj]+jj*GMX_SIMD_REAL_WIDTH/2, e_S); + incrDualHsimd(v0 + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH / 2, + v1 + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH / 2, e_S); } } #endif #if GMX_SIMD_HAVE_INT32_LOGICAL -typedef gmx::SimdInt32 SimdBitMask; +typedef gmx::SimdInt32 SimdBitMask; #else -typedef gmx::SimdReal SimdBitMask; +typedef gmx::SimdReal SimdBitMask; #endif -static inline void gmx_simdcall -gmx_load_simd_2xnn_interactions(int excl, - SimdBitMask filter_S0, - SimdBitMask filter_S2, - gmx::SimdBool *interact_S0, - gmx::SimdBool *interact_S2) +static inline void gmx_simdcall gmx_load_simd_2xnn_interactions(int excl, + SimdBitMask filter_S0, + SimdBitMask filter_S2, + gmx::SimdBool* interact_S0, + gmx::SimdBool* interact_S2) { using namespace gmx; #if GMX_SIMD_HAVE_INT32_LOGICAL SimdInt32 mask_pr_S(excl); - *interact_S0 = cvtIB2B( testBits( mask_pr_S & filter_S0 ) ); - *interact_S2 = cvtIB2B( testBits( mask_pr_S & filter_S2 ) ); + *interact_S0 = cvtIB2B(testBits(mask_pr_S & filter_S0)); + *interact_S2 = cvtIB2B(testBits(mask_pr_S & filter_S2)); #elif GMX_SIMD_HAVE_LOGICAL - union - { -#if GMX_DOUBLE + union { +# if GMX_DOUBLE std::int64_t i; -#else +# else std::int32_t i; -#endif +# endif real r; } conv; conv.i = excl; - SimdReal mask_pr_S(conv.r); + SimdReal mask_pr_S(conv.r); - *interact_S0 = testBits( mask_pr_S & filter_S0 ); - *interact_S2 = testBits( mask_pr_S & filter_S2 ); + *interact_S0 = testBits(mask_pr_S & filter_S0); + *interact_S2 = testBits(mask_pr_S & filter_S2); #endif } diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h index d4a11e64d3..f109430c01 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_inner.h @@ -59,232 +59,231 @@ * contributions. */ #if defined CHECK_EXCLS && (defined CALC_COULOMB || defined LJ_EWALD_GEOM) -#define EXCL_FORCES +# define EXCL_FORCES #endif { - int cj, aj, ajx, ajy, ajz; + int cj, aj, ajx, ajy, ajz; #ifdef ENERGY_GROUPS /* Energy group indices for two atoms packed into one int */ - int egp_jj[UNROLLJ/2]; + int egp_jj[UNROLLJ / 2]; #endif #ifdef CHECK_EXCLS /* Interaction (non-exclusion) mask of all 1's or 0's */ - SimdBool interact_S0; - SimdBool interact_S2; + SimdBool interact_S0; + SimdBool interact_S2; #endif - SimdReal jx_S, jy_S, jz_S; - SimdReal dx_S0, dy_S0, dz_S0; - SimdReal dx_S2, dy_S2, dz_S2; - SimdReal tx_S0, ty_S0, tz_S0; - SimdReal tx_S2, ty_S2, tz_S2; - SimdReal rsq_S0, rinv_S0, rinvsq_S0; - SimdReal rsq_S2, rinv_S2, rinvsq_S2; + SimdReal jx_S, jy_S, jz_S; + SimdReal dx_S0, dy_S0, dz_S0; + SimdReal dx_S2, dy_S2, dz_S2; + SimdReal tx_S0, ty_S0, tz_S0; + SimdReal tx_S2, ty_S2, tz_S2; + SimdReal rsq_S0, rinv_S0, rinvsq_S0; + SimdReal rsq_S2, rinv_S2, rinvsq_S2; /* wco: within cut-off, mask of all 1's or 0's */ - SimdBool wco_S0; - SimdBool wco_S2; + SimdBool wco_S0; + SimdBool wco_S2; #ifdef VDW_CUTOFF_CHECK - SimdBool wco_vdw_S0; -#ifndef HALF_LJ - SimdBool wco_vdw_S2; -#endif + SimdBool wco_vdw_S0; +# ifndef HALF_LJ + SimdBool wco_vdw_S2; +# endif #endif #if (defined CALC_COULOMB && defined CALC_COUL_TAB) || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - SimdReal r_S0; -#if (defined CALC_COULOMB && defined CALC_COUL_TAB) || !defined HALF_LJ - SimdReal r_S2; -#endif + SimdReal r_S0; +# if (defined CALC_COULOMB && defined CALC_COUL_TAB) || !defined HALF_LJ + SimdReal r_S2; +# endif #endif #if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - SimdReal rsw_S0, rsw2_S0; -#ifndef HALF_LJ - SimdReal rsw_S2, rsw2_S2; -#endif + SimdReal rsw_S0, rsw2_S0; +# ifndef HALF_LJ + SimdReal rsw_S2, rsw2_S2; +# endif #endif #ifdef CALC_COULOMB -#ifdef CHECK_EXCLS +# ifdef CHECK_EXCLS /* 1/r masked with the interaction mask */ - SimdReal rinv_ex_S0; - SimdReal rinv_ex_S2; -#endif - SimdReal jq_S; - SimdReal qq_S0; - SimdReal qq_S2; -#ifdef CALC_COUL_TAB + SimdReal rinv_ex_S0; + SimdReal rinv_ex_S2; +# endif + SimdReal jq_S; + SimdReal qq_S0; + SimdReal qq_S2; +# ifdef CALC_COUL_TAB /* The force (PME mesh force) we need to subtract from 1/r^2 */ - SimdReal fsub_S0; - SimdReal fsub_S2; -#endif -#ifdef CALC_COUL_EWALD - SimdReal brsq_S0, brsq_S2; - SimdReal ewcorr_S0, ewcorr_S2; -#endif + SimdReal fsub_S0; + SimdReal fsub_S2; +# endif +# ifdef CALC_COUL_EWALD + SimdReal brsq_S0, brsq_S2; + SimdReal ewcorr_S0, ewcorr_S2; +# endif /* frcoul = (1/r - fsub)*r */ - SimdReal frcoul_S0; - SimdReal frcoul_S2; -#ifdef CALC_COUL_TAB + SimdReal frcoul_S0; + SimdReal frcoul_S2; +# ifdef CALC_COUL_TAB /* For tables: r, rs=r/sp, rf=floor(rs), frac=rs-rf */ - SimdReal rs_S0, rf_S0, frac_S0; - SimdReal rs_S2, rf_S2, frac_S2; + SimdReal rs_S0, rf_S0, frac_S0; + SimdReal rs_S2, rf_S2, frac_S2; /* Table index: rs truncated to an int */ - SimdInt32 ti_S0, ti_S2; + SimdInt32 ti_S0, ti_S2; /* Linear force table values */ - SimdReal ctab0_S0, ctab1_S0; - SimdReal ctab0_S2, ctab1_S2; -#ifdef CALC_ENERGIES + SimdReal ctab0_S0, ctab1_S0; + SimdReal ctab0_S2, ctab1_S2; +# ifdef CALC_ENERGIES /* Quadratic energy table value */ - SimdReal ctabv_S0, dum_S0; - SimdReal ctabv_S2, dum_S2; -#endif -#endif -#if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) + SimdReal ctabv_S0, dum_S0; + SimdReal ctabv_S2, dum_S2; +# endif +# endif +# if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) /* The potential (PME mesh) we need to subtract from 1/r */ - SimdReal vc_sub_S0; - SimdReal vc_sub_S2; -#endif -#ifdef CALC_ENERGIES + SimdReal vc_sub_S0; + SimdReal vc_sub_S2; +# endif +# ifdef CALC_ENERGIES /* Electrostatic potential */ - SimdReal vcoul_S0; - SimdReal vcoul_S2; -#endif + SimdReal vcoul_S0; + SimdReal vcoul_S2; +# endif #endif /* The force times 1/r */ - SimdReal fscal_S0; - SimdReal fscal_S2; + SimdReal fscal_S0; + SimdReal fscal_S2; #ifdef CALC_LJ -#ifdef LJ_COMB_LB +# ifdef LJ_COMB_LB /* LJ sigma_j/2 and sqrt(epsilon_j) */ - SimdReal hsig_j_S, seps_j_S; + SimdReal hsig_j_S, seps_j_S; /* LJ sigma_ij and epsilon_ij */ - SimdReal sig_S0, eps_S0; -#ifndef HALF_LJ - SimdReal sig_S2, eps_S2; -#endif -#ifdef CALC_ENERGIES - SimdReal sig2_S0, sig6_S0; -#ifndef HALF_LJ - SimdReal sig2_S2, sig6_S2; -#endif -#endif /* LJ_COMB_LB */ -#endif /* CALC_LJ */ - -#ifdef LJ_COMB_GEOM - SimdReal c6s_j_S, c12s_j_S; -#endif - -#if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM + SimdReal sig_S0, eps_S0; +# ifndef HALF_LJ + SimdReal sig_S2, eps_S2; +# endif +# ifdef CALC_ENERGIES + SimdReal sig2_S0, sig6_S0; +# ifndef HALF_LJ + SimdReal sig2_S2, sig6_S2; +# endif +# endif /* LJ_COMB_LB */ +# endif /* CALC_LJ */ + +# ifdef LJ_COMB_GEOM + SimdReal c6s_j_S, c12s_j_S; +# endif + +# if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM /* Index for loading LJ parameters, complicated when interleaving */ - int aj2; -#endif + int aj2; +# endif /* Intermediate variables for LJ calculation */ -#ifndef LJ_COMB_LB - SimdReal rinvsix_S0; -#ifndef HALF_LJ - SimdReal rinvsix_S2; -#endif -#endif -#ifdef LJ_COMB_LB - SimdReal sir_S0, sir2_S0, sir6_S0; -#ifndef HALF_LJ - SimdReal sir_S2, sir2_S2, sir6_S2; -#endif -#endif - - SimdReal FrLJ6_S0, FrLJ12_S0, frLJ_S0; -#ifndef HALF_LJ - SimdReal FrLJ6_S2, FrLJ12_S2, frLJ_S2; -#endif +# ifndef LJ_COMB_LB + SimdReal rinvsix_S0; +# ifndef HALF_LJ + SimdReal rinvsix_S2; +# endif +# endif +# ifdef LJ_COMB_LB + SimdReal sir_S0, sir2_S0, sir6_S0; +# ifndef HALF_LJ + SimdReal sir_S2, sir2_S2, sir6_S2; +# endif +# endif + + SimdReal FrLJ6_S0, FrLJ12_S0, frLJ_S0; +# ifndef HALF_LJ + SimdReal FrLJ6_S2, FrLJ12_S2, frLJ_S2; +# endif #endif /* CALC_LJ */ /* j-cluster index */ - cj = l_cj[cjind].cj; + cj = l_cj[cjind].cj; /* Atom indices (of the first atom in the cluster) */ - aj = cj*UNROLLJ; + aj = cj * UNROLLJ; #if defined CALC_LJ && (defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM) - aj2 = aj*2; + aj2 = aj * 2; #endif - ajx = aj*DIM; - ajy = ajx + STRIDE; - ajz = ajy + STRIDE; + ajx = aj * DIM; + ajy = ajx + STRIDE; + ajz = ajy + STRIDE; #ifdef CHECK_EXCLS - gmx_load_simd_2xnn_interactions(static_cast(l_cj[cjind].excl), - filter_S0, filter_S2, + gmx_load_simd_2xnn_interactions(static_cast(l_cj[cjind].excl), filter_S0, filter_S2, &interact_S0, &interact_S2); #endif /* CHECK_EXCLS */ /* load j atom coordinates */ - jx_S = loadDuplicateHsimd(x+ajx); - jy_S = loadDuplicateHsimd(x+ajy); - jz_S = loadDuplicateHsimd(x+ajz); + jx_S = loadDuplicateHsimd(x + ajx); + jy_S = loadDuplicateHsimd(x + ajy); + jz_S = loadDuplicateHsimd(x + ajz); /* Calculate distance */ - dx_S0 = ix_S0 - jx_S; - dy_S0 = iy_S0 - jy_S; - dz_S0 = iz_S0 - jz_S; - dx_S2 = ix_S2 - jx_S; - dy_S2 = iy_S2 - jy_S; - dz_S2 = iz_S2 - jz_S; + dx_S0 = ix_S0 - jx_S; + dy_S0 = iy_S0 - jy_S; + dz_S0 = iz_S0 - jz_S; + dx_S2 = ix_S2 - jx_S; + dy_S2 = iy_S2 - jy_S; + dz_S2 = iz_S2 - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); /* Do the cut-off check */ - wco_S0 = (rsq_S0 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); #ifdef CHECK_EXCLS -#ifdef EXCL_FORCES +# ifdef EXCL_FORCES /* Only remove the (sub-)diagonal to avoid double counting */ -#if UNROLLJ == UNROLLI +# if UNROLLJ == UNROLLI if (cj == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask_S0; - wco_S2 = wco_S2 && diagonal_mask_S2; + wco_S0 = wco_S0 && diagonal_mask_S0; + wco_S2 = wco_S2 && diagonal_mask_S2; } -#else -#if UNROLLJ == 2*UNROLLI - if (cj*2 == ci_sh) +# else +# if UNROLLJ == 2 * UNROLLI + if (cj * 2 == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask0_S0; - wco_S2 = wco_S2 && diagonal_mask0_S2; + wco_S0 = wco_S0 && diagonal_mask0_S0; + wco_S2 = wco_S2 && diagonal_mask0_S2; } - else if (cj*2 + 1 == ci_sh) + else if (cj * 2 + 1 == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask1_S0; - wco_S2 = wco_S2 && diagonal_mask1_S2; + wco_S0 = wco_S0 && diagonal_mask1_S0; + wco_S2 = wco_S2 && diagonal_mask1_S2; } -#else -#error "only UNROLLJ == UNROLLI*(1 or 2) currently supported in 2xnn kernels" -#endif -#endif -#else /* EXCL_FORCES */ - /* No exclusion forces: remove all excluded atom pairs from the list */ - wco_S0 = wco_S0 && interact_S0; - wco_S2 = wco_S2 && interact_S2; -#endif +# else +# error "only UNROLLJ == UNROLLI*(1 or 2) currently supported in 2xnn kernels" +# endif +# endif +# else /* EXCL_FORCES */ + /* No exclusion forces: remove all excluded atom pairs from the list */ + wco_S0 = wco_S0 && interact_S0; + wco_S2 = wco_S2 && interact_S2; +# endif #endif #ifdef COUNT_PAIRS { - int i, j; - alignas(GMX_SIMD_ALIGNMENT) real tmp[GMX_SIMD_REAL_WIDTH]; + int i, j; + alignas(GMX_SIMD_ALIGNMENT) real tmp[GMX_SIMD_REAL_WIDTH]; for (i = 0; i < UNROLLI; i += 2) { store(tmp, rc2_S - (i == 0 ? rsq_S0 : rsq_S2)); - for (j = 0; j < 2*UNROLLJ; j++) + for (j = 0; j < 2 * UNROLLJ; j++) { if (tmp[j] >= 0) { @@ -297,63 +296,63 @@ // Ensure the distances do not fall below the limit where r^-12 overflows. // This should never happen for normal interactions. - rsq_S0 = max(rsq_S0, minRsq_S); - rsq_S2 = max(rsq_S2, minRsq_S); + rsq_S0 = max(rsq_S0, minRsq_S); + rsq_S2 = max(rsq_S2, minRsq_S); /* Calculate 1/r */ - rinv_S0 = invsqrt(rsq_S0); - rinv_S2 = invsqrt(rsq_S2); + rinv_S0 = invsqrt(rsq_S0); + rinv_S2 = invsqrt(rsq_S2); #ifdef CALC_COULOMB /* Load parameters for j atom */ - jq_S = loadDuplicateHsimd(q+aj); - qq_S0 = iq_S0 * jq_S; - qq_S2 = iq_S2 * jq_S; + jq_S = loadDuplicateHsimd(q + aj); + qq_S0 = iq_S0 * jq_S; + qq_S2 = iq_S2 * jq_S; #endif #ifdef CALC_LJ -#if !defined LJ_COMB_GEOM && !defined LJ_COMB_LB && !defined FIX_LJ_C - SimdReal c6_S0, c12_S0; - gatherLoadTransposeHsimd(nbfp0, nbfp1, type+aj, &c6_S0, &c12_S0); -#ifndef HALF_LJ +# if !defined LJ_COMB_GEOM && !defined LJ_COMB_LB && !defined FIX_LJ_C + SimdReal c6_S0, c12_S0; + gatherLoadTransposeHsimd(nbfp0, nbfp1, type + aj, &c6_S0, &c12_S0); +# ifndef HALF_LJ SimdReal c6_S2, c12_S2; - gatherLoadTransposeHsimd(nbfp2, nbfp3, type+aj, &c6_S2, &c12_S2); -#endif -#endif /* not defined any LJ rule */ - -#ifdef LJ_COMB_GEOM - c6s_j_S = loadDuplicateHsimd(ljc+aj2); - c12s_j_S = loadDuplicateHsimd(ljc+aj2+STRIDE); - SimdReal c6_S0 = c6s_S0 * c6s_j_S; -#ifndef HALF_LJ - SimdReal c6_S2 = c6s_S2 * c6s_j_S; -#endif - SimdReal c12_S0 = c12s_S0 * c12s_j_S; -#ifndef HALF_LJ - SimdReal c12_S2 = c12s_S2 * c12s_j_S; -#endif -#endif /* LJ_COMB_GEOM */ - -#ifdef LJ_COMB_LB - hsig_j_S = loadDuplicateHsimd(ljc+aj2); - seps_j_S = loadDuplicateHsimd(ljc+aj2+STRIDE); - - sig_S0 = hsig_i_S0 + hsig_j_S; - eps_S0 = seps_i_S0 * seps_j_S; -#ifndef HALF_LJ - sig_S2 = hsig_i_S2 + hsig_j_S; - eps_S2 = seps_i_S2 * seps_j_S; -#endif -#endif /* LJ_COMB_LB */ + gatherLoadTransposeHsimd(nbfp2, nbfp3, type + aj, &c6_S2, &c12_S2); +# endif +# endif /* not defined any LJ rule */ + +# ifdef LJ_COMB_GEOM + c6s_j_S = loadDuplicateHsimd(ljc + aj2); + c12s_j_S = loadDuplicateHsimd(ljc + aj2 + STRIDE); + SimdReal c6_S0 = c6s_S0 * c6s_j_S; +# ifndef HALF_LJ + SimdReal c6_S2 = c6s_S2 * c6s_j_S; +# endif + SimdReal c12_S0 = c12s_S0 * c12s_j_S; +# ifndef HALF_LJ + SimdReal c12_S2 = c12s_S2 * c12s_j_S; +# endif +# endif /* LJ_COMB_GEOM */ + +# ifdef LJ_COMB_LB + hsig_j_S = loadDuplicateHsimd(ljc + aj2); + seps_j_S = loadDuplicateHsimd(ljc + aj2 + STRIDE); + + sig_S0 = hsig_i_S0 + hsig_j_S; + eps_S0 = seps_i_S0 * seps_j_S; +# ifndef HALF_LJ + sig_S2 = hsig_i_S2 + hsig_j_S; + eps_S2 = seps_i_S2 * seps_j_S; +# endif +# endif /* LJ_COMB_LB */ #endif /* CALC_LJ */ /* Set rinv to zero for r beyond the cut-off */ - rinv_S0 = selectByMask(rinv_S0, wco_S0); - rinv_S2 = selectByMask(rinv_S2, wco_S2); + rinv_S0 = selectByMask(rinv_S0, wco_S0); + rinv_S2 = selectByMask(rinv_S2, wco_S2); - rinvsq_S0 = rinv_S0 * rinv_S0; - rinvsq_S2 = rinv_S2 * rinv_S2; + rinvsq_S0 = rinv_S0 * rinv_S0; + rinvsq_S2 = rinv_S2 * rinv_S2; #ifdef CALC_COULOMB /* Note that here we calculate force*r, not the usual force/r. @@ -362,536 +361,548 @@ * masked with the cut-off check. */ -#ifdef EXCL_FORCES +# ifdef EXCL_FORCES /* Only add 1/r for non-excluded atom pairs */ - rinv_ex_S0 = selectByMask(rinv_S0, interact_S0); - rinv_ex_S2 = selectByMask(rinv_S2, interact_S2); -#else + rinv_ex_S0 = selectByMask(rinv_S0, interact_S0); + rinv_ex_S2 = selectByMask(rinv_S2, interact_S2); +# else /* No exclusion forces, we always need 1/r */ -#define rinv_ex_S0 rinv_S0 -#define rinv_ex_S2 rinv_S2 -#endif +# define rinv_ex_S0 rinv_S0 +# define rinv_ex_S2 rinv_S2 +# endif -#ifdef CALC_COUL_RF +# ifdef CALC_COUL_RF /* Electrostatic interactions */ - frcoul_S0 = qq_S0 * fma(rsq_S0, mrc_3_S, rinv_ex_S0); - frcoul_S2 = qq_S2 * fma(rsq_S2, mrc_3_S, rinv_ex_S2); + frcoul_S0 = qq_S0 * fma(rsq_S0, mrc_3_S, rinv_ex_S0); + frcoul_S2 = qq_S2 * fma(rsq_S2, mrc_3_S, rinv_ex_S2); -#ifdef CALC_ENERGIES - vcoul_S0 = qq_S0 * (rinv_ex_S0 + fma(rsq_S0, hrc_3_S, moh_rc_S)); - vcoul_S2 = qq_S2 * (rinv_ex_S2 + fma(rsq_S2, hrc_3_S, moh_rc_S)); -#endif -#endif +# ifdef CALC_ENERGIES + vcoul_S0 = qq_S0 * (rinv_ex_S0 + fma(rsq_S0, hrc_3_S, moh_rc_S)); + vcoul_S2 = qq_S2 * (rinv_ex_S2 + fma(rsq_S2, hrc_3_S, moh_rc_S)); +# endif +# endif -#ifdef CALC_COUL_EWALD +# ifdef CALC_COUL_EWALD /* We need to mask (or limit) rsq for the cut-off, * as large distances can cause an overflow in gmx_pmecorrF/V. */ - brsq_S0 = beta2_S * selectByMask(rsq_S0, wco_S0); - brsq_S2 = beta2_S * selectByMask(rsq_S2, wco_S2); - ewcorr_S0 = beta_S * pmeForceCorrection(brsq_S0); - ewcorr_S2 = beta_S * pmeForceCorrection(brsq_S2); - frcoul_S0 = qq_S0 * fma(ewcorr_S0, brsq_S0, rinv_ex_S0); - frcoul_S2 = qq_S2 * fma(ewcorr_S2, brsq_S2, rinv_ex_S2); + brsq_S0 = beta2_S * selectByMask(rsq_S0, wco_S0); + brsq_S2 = beta2_S * selectByMask(rsq_S2, wco_S2); + ewcorr_S0 = beta_S * pmeForceCorrection(brsq_S0); + ewcorr_S2 = beta_S * pmeForceCorrection(brsq_S2); + frcoul_S0 = qq_S0 * fma(ewcorr_S0, brsq_S0, rinv_ex_S0); + frcoul_S2 = qq_S2 * fma(ewcorr_S2, brsq_S2, rinv_ex_S2); -#ifdef CALC_ENERGIES - vc_sub_S0 = beta_S * pmePotentialCorrection(brsq_S0); - vc_sub_S2 = beta_S * pmePotentialCorrection(brsq_S2); -#endif +# ifdef CALC_ENERGIES + vc_sub_S0 = beta_S * pmePotentialCorrection(brsq_S0); + vc_sub_S2 = beta_S * pmePotentialCorrection(brsq_S2); +# endif -#endif /* CALC_COUL_EWALD */ +# endif /* CALC_COUL_EWALD */ -#ifdef CALC_COUL_TAB +# ifdef CALC_COUL_TAB /* Electrostatic interactions */ - r_S0 = rsq_S0 * rinv_S0; - r_S2 = rsq_S2 * rinv_S2; + r_S0 = rsq_S0 * rinv_S0; + r_S2 = rsq_S2 * rinv_S2; /* Convert r to scaled table units */ - rs_S0 = r_S0 * invtsp_S; - rs_S2 = r_S2 * invtsp_S; + rs_S0 = r_S0 * invtsp_S; + rs_S2 = r_S2 * invtsp_S; /* Truncate scaled r to an int */ - ti_S0 = cvttR2I(rs_S0); - ti_S2 = cvttR2I(rs_S2); + ti_S0 = cvttR2I(rs_S0); + ti_S2 = cvttR2I(rs_S2); - rf_S0 = trunc(rs_S0); - rf_S2 = trunc(rs_S2); + rf_S0 = trunc(rs_S0); + rf_S2 = trunc(rs_S2); - frac_S0 = rs_S0 - rf_S0; - frac_S2 = rs_S2 - rf_S2; + frac_S0 = rs_S0 - rf_S0; + frac_S2 = rs_S2 - rf_S2; /* Load and interpolate table forces and possibly energies. * Force and energy can be combined in one table, stride 4: FDV0 * or in two separate tables with stride 1: F and V * Currently single precision uses FDV0, double F and V. */ -#ifndef CALC_ENERGIES -#ifdef TAB_FDV0 +# ifndef CALC_ENERGIES +# ifdef TAB_FDV0 gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2); -#else +# else gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2); - ctab1_S0 = ctab1_S0 - ctab0_S0; - ctab1_S2 = ctab1_S2 - ctab0_S2; -#endif -#else -#ifdef TAB_FDV0 + ctab1_S0 = ctab1_S0 - ctab0_S0; + ctab1_S2 = ctab1_S2 - ctab0_S2; +# endif +# else +# ifdef TAB_FDV0 gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0, &ctabv_S0, &dum_S0); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2, &ctabv_S2, &dum_S2); -#else +# else gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_V, ti_S0, &ctabv_S0, &dum_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2); gatherLoadUBySimdIntTranspose<1>(tab_coul_V, ti_S2, &ctabv_S2, &dum_S2); ctab1_S0 = ctab1_S0 - ctab0_S0; ctab1_S2 = ctab1_S2 - ctab0_S2; -#endif -#endif - fsub_S0 = fma(frac_S0, ctab1_S0, ctab0_S0); - fsub_S2 = fma(frac_S2, ctab1_S2, ctab0_S2); - frcoul_S0 = qq_S0 * fnma(fsub_S0, r_S0, rinv_ex_S0); - frcoul_S2 = qq_S2 * fnma(fsub_S2, r_S2, rinv_ex_S2); - -#ifdef CALC_ENERGIES - vc_sub_S0 = fma((mhalfsp_S * frac_S0), (ctab0_S0 + fsub_S0), ctabv_S0); - vc_sub_S2 = fma((mhalfsp_S * frac_S2), (ctab0_S2 + fsub_S2), ctabv_S2); -#endif -#endif /* CALC_COUL_TAB */ - -#if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) -#ifndef NO_SHIFT_EWALD +# endif +# endif + fsub_S0 = fma(frac_S0, ctab1_S0, ctab0_S0); + fsub_S2 = fma(frac_S2, ctab1_S2, ctab0_S2); + frcoul_S0 = qq_S0 * fnma(fsub_S0, r_S0, rinv_ex_S0); + frcoul_S2 = qq_S2 * fnma(fsub_S2, r_S2, rinv_ex_S2); + +# ifdef CALC_ENERGIES + vc_sub_S0 = fma((mhalfsp_S * frac_S0), (ctab0_S0 + fsub_S0), ctabv_S0); + vc_sub_S2 = fma((mhalfsp_S * frac_S2), (ctab0_S2 + fsub_S2), ctabv_S2); +# endif +# endif /* CALC_COUL_TAB */ + +# if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) +# ifndef NO_SHIFT_EWALD /* Add Ewald potential shift to vc_sub for convenience */ -#ifdef CHECK_EXCLS - vc_sub_S0 = vc_sub_S0 + selectByMask(sh_ewald_S, interact_S0); - vc_sub_S2 = vc_sub_S2 + selectByMask(sh_ewald_S, interact_S2); -#else - vc_sub_S0 = vc_sub_S0 + sh_ewald_S; - vc_sub_S2 = vc_sub_S2 + sh_ewald_S; -#endif -#endif +# ifdef CHECK_EXCLS + vc_sub_S0 = vc_sub_S0 + selectByMask(sh_ewald_S, interact_S0); + vc_sub_S2 = vc_sub_S2 + selectByMask(sh_ewald_S, interact_S2); +# else + vc_sub_S0 = vc_sub_S0 + sh_ewald_S; + vc_sub_S2 = vc_sub_S2 + sh_ewald_S; +# endif +# endif - vcoul_S0 = qq_S0 * (rinv_ex_S0 - vc_sub_S0); - vcoul_S2 = qq_S2 * (rinv_ex_S2 - vc_sub_S2); + vcoul_S0 = qq_S0 * (rinv_ex_S0 - vc_sub_S0); + vcoul_S2 = qq_S2 * (rinv_ex_S2 - vc_sub_S2); -#endif +# endif -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES /* Mask energy for cut-off and diagonal */ - vcoul_S0 = selectByMask(vcoul_S0, wco_S0); - vcoul_S2 = selectByMask(vcoul_S2, wco_S2); -#endif + vcoul_S0 = selectByMask(vcoul_S0, wco_S0); + vcoul_S2 = selectByMask(vcoul_S2, wco_S2); +# endif #endif /* CALC_COULOMB */ #ifdef CALC_LJ /* Lennard-Jones interaction */ -#ifdef VDW_CUTOFF_CHECK - wco_vdw_S0 = (rsq_S0 < rcvdw2_S); -#ifndef HALF_LJ - wco_vdw_S2 = (rsq_S2 < rcvdw2_S); -#endif -#else +# ifdef VDW_CUTOFF_CHECK + wco_vdw_S0 = (rsq_S0 < rcvdw2_S); +# ifndef HALF_LJ + wco_vdw_S2 = (rsq_S2 < rcvdw2_S); +# endif +# else /* Same cut-off for Coulomb and VdW, reuse the registers */ -#define wco_vdw_S0 wco_S0 -#define wco_vdw_S2 wco_S2 -#endif - -#ifndef LJ_COMB_LB - rinvsix_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; -#ifdef EXCL_FORCES - rinvsix_S0 = selectByMask(rinvsix_S0, interact_S0); -#endif -#ifndef HALF_LJ - rinvsix_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; -#ifdef EXCL_FORCES - rinvsix_S2 = selectByMask(rinvsix_S2, interact_S2); -#endif -#endif - -#if defined LJ_CUT || defined LJ_POT_SWITCH +# define wco_vdw_S0 wco_S0 +# define wco_vdw_S2 wco_S2 +# endif + +# ifndef LJ_COMB_LB + rinvsix_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; +# ifdef EXCL_FORCES + rinvsix_S0 = selectByMask(rinvsix_S0, interact_S0); +# endif +# ifndef HALF_LJ + rinvsix_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; +# ifdef EXCL_FORCES + rinvsix_S2 = selectByMask(rinvsix_S2, interact_S2); +# endif +# endif + +# if defined LJ_CUT || defined LJ_POT_SWITCH /* We have plain LJ or LJ-PME with simple C6/6 C12/12 coefficients */ - FrLJ6_S0 = c6_S0 * rinvsix_S0; -#ifndef HALF_LJ - FrLJ6_S2 = c6_S2 * rinvsix_S2; -#endif - FrLJ12_S0 = c12_S0 * rinvsix_S0 * rinvsix_S0; -#ifndef HALF_LJ - FrLJ12_S2 = c12_S2 * rinvsix_S2 * rinvsix_S2; -#endif -#endif - -#if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH + FrLJ6_S0 = c6_S0 * rinvsix_S0; +# ifndef HALF_LJ + FrLJ6_S2 = c6_S2 * rinvsix_S2; +# endif + FrLJ12_S0 = c12_S0 * rinvsix_S0 * rinvsix_S0; +# ifndef HALF_LJ + FrLJ12_S2 = c12_S2 * rinvsix_S2 * rinvsix_S2; +# endif +# endif + +# if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH /* We switch the LJ force */ - r_S0 = rsq_S0 * rinv_S0; - rsw_S0 = max(r_S0 - rswitch_S, zero_S); - rsw2_S0 = rsw_S0 * rsw_S0; -#ifndef HALF_LJ - r_S2 = rsq_S2 * rinv_S2; - rsw_S2 = max(r_S2 - rswitch_S, zero_S); - rsw2_S2 = rsw_S2 * rsw_S2; -#endif -#endif - -#ifdef LJ_FORCE_SWITCH - -#define add_fr_switch(fr, rsw, rsw2_r, c2, c3) fma(fma(c3, rsw, c2), rsw2_r, fr) + r_S0 = rsq_S0 * rinv_S0; + rsw_S0 = max(r_S0 - rswitch_S, zero_S); + rsw2_S0 = rsw_S0 * rsw_S0; +# ifndef HALF_LJ + r_S2 = rsq_S2 * rinv_S2; + rsw_S2 = max(r_S2 - rswitch_S, zero_S); + rsw2_S2 = rsw_S2 * rsw_S2; +# endif +# endif + +# ifdef LJ_FORCE_SWITCH + +# define add_fr_switch(fr, rsw, rsw2_r, c2, c3) fma(fma(c3, rsw, c2), rsw2_r, fr) SimdReal rsw2_r_S0 = rsw2_S0 * r_S0; - FrLJ6_S0 = c6_S0 * add_fr_switch(rinvsix_S0, rsw_S0, rsw2_r_S0, p6_fc2_S, p6_fc3_S); -#ifndef HALF_LJ + FrLJ6_S0 = c6_S0 * add_fr_switch(rinvsix_S0, rsw_S0, rsw2_r_S0, p6_fc2_S, p6_fc3_S); +# ifndef HALF_LJ SimdReal rsw2_r_S2 = rsw2_S2 * r_S2; - FrLJ6_S2 = c6_S2 * add_fr_switch(rinvsix_S2, rsw_S2, rsw2_r_S2, p6_fc2_S, p6_fc3_S); -#endif - FrLJ12_S0 = c12_S0 * add_fr_switch(rinvsix_S0 * rinvsix_S0, rsw_S0, rsw2_r_S0, p12_fc2_S, p12_fc3_S); -#ifndef HALF_LJ - FrLJ12_S2 = c12_S2 * add_fr_switch(rinvsix_S2 * rinvsix_S2, rsw_S2, rsw2_r_S2, p12_fc2_S, p12_fc3_S); -#endif -#undef add_fr_switch -#endif /* LJ_FORCE_SWITCH */ - -#endif /* not LJ_COMB_LB */ - -#ifdef LJ_COMB_LB - sir_S0 = sig_S0 * rinv_S0; -#ifndef HALF_LJ - sir_S2 = sig_S2 * rinv_S2; -#endif - sir2_S0 = sir_S0 * sir_S0; -#ifndef HALF_LJ - sir2_S2 = sir_S2 * sir_S2; -#endif - sir6_S0 = sir2_S0 * sir2_S0 * sir2_S0; -#ifdef EXCL_FORCES - sir6_S0 = selectByMask(sir6_S0, interact_S0); -#endif -#ifndef HALF_LJ - sir6_S2 = sir2_S2 * sir2_S2 * sir2_S2; -#ifdef EXCL_FORCES - sir6_S2 = selectByMask(sir6_S2, interact_S2); -#endif -#endif -#ifdef VDW_CUTOFF_CHECK - sir6_S0 = selectByMask(sir6_S0, wco_vdw_S0); -#ifndef HALF_LJ - sir6_S2 = selectByMask(sir6_S2, wco_vdw_S2); -#endif -#endif - FrLJ6_S0 = eps_S0 * sir6_S0; -#ifndef HALF_LJ - FrLJ6_S2 = eps_S2 * sir6_S2; -#endif - FrLJ12_S0 = FrLJ6_S0 * sir6_S0; -#ifndef HALF_LJ - FrLJ12_S2 = FrLJ6_S2 * sir6_S2; -#endif -#if defined CALC_ENERGIES + FrLJ6_S2 = c6_S2 * add_fr_switch(rinvsix_S2, rsw_S2, rsw2_r_S2, p6_fc2_S, p6_fc3_S); +# endif + FrLJ12_S0 = c12_S0 * add_fr_switch(rinvsix_S0 * rinvsix_S0, rsw_S0, rsw2_r_S0, p12_fc2_S, p12_fc3_S); +# ifndef HALF_LJ + FrLJ12_S2 = c12_S2 * add_fr_switch(rinvsix_S2 * rinvsix_S2, rsw_S2, rsw2_r_S2, p12_fc2_S, p12_fc3_S); +# endif +# undef add_fr_switch +# endif /* LJ_FORCE_SWITCH */ + +# endif /* not LJ_COMB_LB */ + +# ifdef LJ_COMB_LB + sir_S0 = sig_S0 * rinv_S0; +# ifndef HALF_LJ + sir_S2 = sig_S2 * rinv_S2; +# endif + sir2_S0 = sir_S0 * sir_S0; +# ifndef HALF_LJ + sir2_S2 = sir_S2 * sir_S2; +# endif + sir6_S0 = sir2_S0 * sir2_S0 * sir2_S0; +# ifdef EXCL_FORCES + sir6_S0 = selectByMask(sir6_S0, interact_S0); +# endif +# ifndef HALF_LJ + sir6_S2 = sir2_S2 * sir2_S2 * sir2_S2; +# ifdef EXCL_FORCES + sir6_S2 = selectByMask(sir6_S2, interact_S2); +# endif +# endif +# ifdef VDW_CUTOFF_CHECK + sir6_S0 = selectByMask(sir6_S0, wco_vdw_S0); +# ifndef HALF_LJ + sir6_S2 = selectByMask(sir6_S2, wco_vdw_S2); +# endif +# endif + FrLJ6_S0 = eps_S0 * sir6_S0; +# ifndef HALF_LJ + FrLJ6_S2 = eps_S2 * sir6_S2; +# endif + FrLJ12_S0 = FrLJ6_S0 * sir6_S0; +# ifndef HALF_LJ + FrLJ12_S2 = FrLJ6_S2 * sir6_S2; +# endif +# if defined CALC_ENERGIES /* We need C6 and C12 to calculate the LJ potential shift */ - sig2_S0 = sig_S0 * sig_S0; -#ifndef HALF_LJ - sig2_S2 = sig_S2 * sig_S2; -#endif - sig6_S0 = sig2_S0 * sig2_S0 * sig2_S0; -#ifndef HALF_LJ - sig6_S2 = sig2_S2 * sig2_S2 * sig2_S2; -#endif - SimdReal c6_S0 = eps_S0 * sig6_S0; -#ifndef HALF_LJ - SimdReal c6_S2 = eps_S2 * sig6_S2; -#endif + sig2_S0 = sig_S0 * sig_S0; +# ifndef HALF_LJ + sig2_S2 = sig_S2 * sig_S2; +# endif + sig6_S0 = sig2_S0 * sig2_S0 * sig2_S0; +# ifndef HALF_LJ + sig6_S2 = sig2_S2 * sig2_S2 * sig2_S2; +# endif + SimdReal c6_S0 = eps_S0 * sig6_S0; +# ifndef HALF_LJ + SimdReal c6_S2 = eps_S2 * sig6_S2; +# endif SimdReal c12_S0 = c6_S0 * sig6_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal c12_S2 = c6_S2 * sig6_S2; -#endif -#endif -#endif /* LJ_COMB_LB */ +# endif +# endif +# endif /* LJ_COMB_LB */ /* Determine the total scalar LJ force*r */ - frLJ_S0 = FrLJ12_S0 - FrLJ6_S0; -#ifndef HALF_LJ - frLJ_S2 = FrLJ12_S2 - FrLJ6_S2; -#endif + frLJ_S0 = FrLJ12_S0 - FrLJ6_S0; +# ifndef HALF_LJ + frLJ_S2 = FrLJ12_S2 - FrLJ6_S2; +# endif -#if (defined LJ_CUT || defined LJ_FORCE_SWITCH) && defined CALC_ENERGIES +# if (defined LJ_CUT || defined LJ_FORCE_SWITCH) && defined CALC_ENERGIES -#ifdef LJ_CUT +# ifdef LJ_CUT /* Calculate the LJ energies, with constant potential shift */ - SimdReal VLJ6_S0 = sixth_S * fma(c6_S0, p6_cpot_S, FrLJ6_S0); -#ifndef HALF_LJ - SimdReal VLJ6_S2 = sixth_S * fma(c6_S2, p6_cpot_S, FrLJ6_S2); -#endif + SimdReal VLJ6_S0 = sixth_S * fma(c6_S0, p6_cpot_S, FrLJ6_S0); +# ifndef HALF_LJ + SimdReal VLJ6_S2 = sixth_S * fma(c6_S2, p6_cpot_S, FrLJ6_S2); +# endif SimdReal VLJ12_S0 = twelveth_S * fma(c12_S0, p12_cpot_S, FrLJ12_S0); -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal VLJ12_S2 = twelveth_S * fma(c12_S2, p12_cpot_S, FrLJ12_S2); -#endif -#endif /* LJ_CUT */ - -#ifdef LJ_FORCE_SWITCH -#define v_fswitch_pr(rsw, rsw2, c0, c3, c4) fma(fma(c4, rsw, c3), (rsw2) * (rsw), c0) - - SimdReal VLJ6_S0 = c6_S0 * fma(sixth_S, rinvsix_S0, v_fswitch_pr(rsw_S0, rsw2_S0, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); -#ifndef HALF_LJ - SimdReal VLJ6_S2 = c6_S2 * fma(sixth_S, rinvsix_S2, v_fswitch_pr(rsw_S2, rsw2_S2, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); -#endif - SimdReal VLJ12_S0 = c12_S0 * fma(twelveth_S, rinvsix_S0 * rinvsix_S0, v_fswitch_pr(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); -#ifndef HALF_LJ - SimdReal VLJ12_S2 = c12_S2 * fma(twelveth_S, rinvsix_S2 * rinvsix_S2, v_fswitch_pr(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); -#endif -#undef v_fswitch_pr -#endif /* LJ_FORCE_SWITCH */ +# endif +# endif /* LJ_CUT */ + +# ifdef LJ_FORCE_SWITCH +# define v_fswitch_pr(rsw, rsw2, c0, c3, c4) fma(fma(c4, rsw, c3), (rsw2) * (rsw), c0) + + SimdReal VLJ6_S0 = + c6_S0 * fma(sixth_S, rinvsix_S0, v_fswitch_pr(rsw_S0, rsw2_S0, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); +# ifndef HALF_LJ + SimdReal VLJ6_S2 = + c6_S2 * fma(sixth_S, rinvsix_S2, v_fswitch_pr(rsw_S2, rsw2_S2, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); +# endif + SimdReal VLJ12_S0 = c12_S0 + * fma(twelveth_S, rinvsix_S0 * rinvsix_S0, + v_fswitch_pr(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); +# ifndef HALF_LJ + SimdReal VLJ12_S2 = c12_S2 + * fma(twelveth_S, rinvsix_S2 * rinvsix_S2, + v_fswitch_pr(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); +# endif +# undef v_fswitch_pr +# endif /* LJ_FORCE_SWITCH */ /* Add up the repulsion and dispersion */ - SimdReal VLJ_S0 = VLJ12_S0 - VLJ6_S0; -#ifndef HALF_LJ - SimdReal VLJ_S2 = VLJ12_S2 - VLJ6_S2; -#endif + SimdReal VLJ_S0 = VLJ12_S0 - VLJ6_S0; +# ifndef HALF_LJ + SimdReal VLJ_S2 = VLJ12_S2 - VLJ6_S2; +# endif -#endif /* (LJ_CUT || LJ_FORCE_SWITCH) && CALC_ENERGIES */ +# endif /* (LJ_CUT || LJ_FORCE_SWITCH) && CALC_ENERGIES */ -#ifdef LJ_POT_SWITCH +# ifdef LJ_POT_SWITCH /* We always need the potential, since it is needed for the force */ SimdReal VLJ_S0 = fnma(sixth_S, FrLJ6_S0, twelveth_S * FrLJ12_S0); -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal VLJ_S2 = fnma(sixth_S, FrLJ6_S2, twelveth_S * FrLJ12_S2); -#endif +# endif { SimdReal sw_S0, dsw_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal sw_S2, dsw_S2; -#endif +# endif -#define switch_pr(rsw, rsw2, c3, c4, c5) fma(fma(fma(c5, rsw, c4), rsw, c3), (rsw2) * (rsw), one_S) -#define dswitch_pr(rsw, rsw2, c2, c3, c4) fma(fma(c4, rsw, c3), rsw, c2)*(rsw2) +# define switch_pr(rsw, rsw2, c3, c4, c5) \ + fma(fma(fma(c5, rsw, c4), rsw, c3), (rsw2) * (rsw), one_S) +# define dswitch_pr(rsw, rsw2, c2, c3, c4) fma(fma(c4, rsw, c3), rsw, c2) * (rsw2) sw_S0 = switch_pr(rsw_S0, rsw2_S0, swV3_S, swV4_S, swV5_S); dsw_S0 = dswitch_pr(rsw_S0, rsw2_S0, swF2_S, swF3_S, swF4_S); -#ifndef HALF_LJ +# ifndef HALF_LJ sw_S2 = switch_pr(rsw_S2, rsw2_S2, swV3_S, swV4_S, swV5_S); dsw_S2 = dswitch_pr(rsw_S2, rsw2_S2, swF2_S, swF3_S, swF4_S); -#endif +# endif frLJ_S0 = fnma(dsw_S0 * VLJ_S0, r_S0, sw_S0 * frLJ_S0); -#ifndef HALF_LJ +# ifndef HALF_LJ frLJ_S2 = fnma(dsw_S2 * VLJ_S2, r_S2, sw_S2 * frLJ_S2); -#endif -#ifdef CALC_ENERGIES - VLJ_S0 = sw_S0 * VLJ_S0; -#ifndef HALF_LJ - VLJ_S2 = sw_S2 * VLJ_S2; -#endif -#endif - -#undef switch_pr -#undef dswitch_pr +# endif +# ifdef CALC_ENERGIES + VLJ_S0 = sw_S0 * VLJ_S0; +# ifndef HALF_LJ + VLJ_S2 = sw_S2 * VLJ_S2; +# endif +# endif + +# undef switch_pr +# undef dswitch_pr } -#endif /* LJ_POT_SWITCH */ +# endif /* LJ_POT_SWITCH */ -#if defined CALC_ENERGIES && defined CHECK_EXCLS +# if defined CALC_ENERGIES && defined CHECK_EXCLS /* The potential shift should be removed for excluded pairs */ - VLJ_S0 = selectByMask(VLJ_S0, interact_S0); -#ifndef HALF_LJ - VLJ_S2 = selectByMask(VLJ_S2, interact_S2); -#endif -#endif + VLJ_S0 = selectByMask(VLJ_S0, interact_S0); +# ifndef HALF_LJ + VLJ_S2 = selectByMask(VLJ_S2, interact_S2); +# endif +# endif -#ifdef LJ_EWALD_GEOM +# ifdef LJ_EWALD_GEOM { SimdReal c6s_j_S; SimdReal c6grid_S0, rinvsix_nm_S0, cr2_S0, expmcr2_S0, poly_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal c6grid_S2, rinvsix_nm_S2, cr2_S2, expmcr2_S2, poly_S2; -#endif -#ifdef CALC_ENERGIES +# endif +# ifdef CALC_ENERGIES SimdReal sh_mask_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal sh_mask_S2; -#endif -#endif +# endif +# endif /* Determine C6 for the grid using the geometric combination rule */ - c6s_j_S = loadDuplicateHsimd(ljc+aj2); - c6grid_S0 = c6s_S0 * c6s_j_S; -#ifndef HALF_LJ - c6grid_S2 = c6s_S2 * c6s_j_S; -#endif + c6s_j_S = loadDuplicateHsimd(ljc + aj2); + c6grid_S0 = c6s_S0 * c6s_j_S; +# ifndef HALF_LJ + c6grid_S2 = c6s_S2 * c6s_j_S; +# endif -#ifdef CHECK_EXCLS +# ifdef CHECK_EXCLS /* Recalculate rinvsix without exclusion mask (compiler might optimize) */ rinvsix_nm_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ rinvsix_nm_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; -#endif -#else +# endif +# else /* We didn't use a mask, so we can copy */ rinvsix_nm_S0 = rinvsix_S0; -#ifndef HALF_LJ +# ifndef HALF_LJ rinvsix_nm_S2 = rinvsix_S2; -#endif -#endif +# endif +# endif /* Mask for the cut-off to avoid overflow of cr2^2 */ - cr2_S0 = lje_c2_S * selectByMask(rsq_S0, wco_vdw_S0); -#ifndef HALF_LJ - cr2_S2 = lje_c2_S * selectByMask(rsq_S2, wco_vdw_S2); -#endif + cr2_S0 = lje_c2_S * selectByMask(rsq_S0, wco_vdw_S0); +# ifndef HALF_LJ + cr2_S2 = lje_c2_S * selectByMask(rsq_S2, wco_vdw_S2); +# endif // Unsafe version of our exp() should be fine, since these arguments should never // be smaller than -127 for any reasonable choice of cutoff or ewald coefficients. - expmcr2_S0 = exp( -cr2_S0); -#ifndef HALF_LJ - expmcr2_S2 = exp( -cr2_S2); -#endif + expmcr2_S0 = exp(-cr2_S0); +# ifndef HALF_LJ + expmcr2_S2 = exp(-cr2_S2); +# endif /* 1 + cr2 + 1/2*cr2^2 */ - poly_S0 = fma(fma(half_S, cr2_S0, one_S), cr2_S0, one_S); -#ifndef HALF_LJ - poly_S2 = fma(fma(half_S, cr2_S2, one_S), cr2_S2, one_S); -#endif + poly_S0 = fma(fma(half_S, cr2_S0, one_S), cr2_S0, one_S); +# ifndef HALF_LJ + poly_S2 = fma(fma(half_S, cr2_S2, one_S), cr2_S2, one_S); +# endif /* We calculate LJ F*r = (6*C6)*(r^-6 - F_mesh/6), we use: * r^-6*cexp*(1 + cr2 + cr2^2/2 + cr2^3/6) = cexp*(r^-6*poly + c^6/6) */ - frLJ_S0 = fma(c6grid_S0, fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0); -#ifndef HALF_LJ - frLJ_S2 = fma(c6grid_S2, fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2); -#endif - -#ifdef CALC_ENERGIES -#ifdef CHECK_EXCLS - sh_mask_S0 = selectByMask(lje_vc_S, interact_S0); -#ifndef HALF_LJ - sh_mask_S2 = selectByMask(lje_vc_S, interact_S2); -#endif -#else - sh_mask_S0 = lje_vc_S; -#ifndef HALF_LJ - sh_mask_S2 = lje_vc_S; -#endif -#endif - - VLJ_S0 = fma(sixth_S * c6grid_S0, fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0); -#ifndef HALF_LJ - VLJ_S2 = fma(sixth_S * c6grid_S2, fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2); -#endif -#endif /* CALC_ENERGIES */ + frLJ_S0 = fma(c6grid_S0, + fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0); +# ifndef HALF_LJ + frLJ_S2 = fma(c6grid_S2, + fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2); +# endif + +# ifdef CALC_ENERGIES +# ifdef CHECK_EXCLS + sh_mask_S0 = selectByMask(lje_vc_S, interact_S0); +# ifndef HALF_LJ + sh_mask_S2 = selectByMask(lje_vc_S, interact_S2); +# endif +# else + sh_mask_S0 = lje_vc_S; +# ifndef HALF_LJ + sh_mask_S2 = lje_vc_S; +# endif +# endif + + VLJ_S0 = fma(sixth_S * c6grid_S0, + fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0); +# ifndef HALF_LJ + VLJ_S2 = fma(sixth_S * c6grid_S2, + fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2); +# endif +# endif /* CALC_ENERGIES */ } -#endif /* LJ_EWALD_GEOM */ +# endif /* LJ_EWALD_GEOM */ -#if defined VDW_CUTOFF_CHECK +# if defined VDW_CUTOFF_CHECK /* frLJ is multiplied later by rinvsq, which is masked for the Coulomb * cut-off, but if the VdW cut-off is shorter, we need to mask with that. */ - frLJ_S0 = selectByMask(frLJ_S0, wco_vdw_S0); -#ifndef HALF_LJ - frLJ_S2 = selectByMask(frLJ_S2, wco_vdw_S2); -#endif -#endif + frLJ_S0 = selectByMask(frLJ_S0, wco_vdw_S0); +# ifndef HALF_LJ + frLJ_S2 = selectByMask(frLJ_S2, wco_vdw_S2); +# endif +# endif -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES /* The potential shift should be removed for pairs beyond cut-off */ - VLJ_S0 = selectByMask(VLJ_S0, wco_vdw_S0); -#ifndef HALF_LJ - VLJ_S2 = selectByMask(VLJ_S2, wco_vdw_S2); -#endif -#endif + VLJ_S0 = selectByMask(VLJ_S0, wco_vdw_S0); +# ifndef HALF_LJ + VLJ_S2 = selectByMask(VLJ_S2, wco_vdw_S2); +# endif +# endif #endif /* CALC_LJ */ #ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS +# ifdef ENERGY_GROUPS /* Extract the group pair index per j pair. * Energy groups are stored per i-cluster, so things get * complicated when the i- and j-cluster size don't match. */ { int egps_j; -#if UNROLLJ == 2 +# if UNROLLJ == 2 egps_j = nbatParams.energrp[cj >> 1]; - egp_jj[0] = ((egps_j >> ((cj & 1)*egps_jshift)) & egps_jmask)*egps_jstride; -#else + egp_jj[0] = ((egps_j >> ((cj & 1) * egps_jshift)) & egps_jmask) * egps_jstride; +# else /* We assume UNROLLI <= UNROLLJ */ int jdi; - for (jdi = 0; jdi < UNROLLJ/UNROLLI; jdi++) + for (jdi = 0; jdi < UNROLLJ / UNROLLI; jdi++) { int jj; - egps_j = nbatParams.energrp[cj*(UNROLLJ/UNROLLI) + jdi]; - for (jj = 0; jj < (UNROLLI/2); jj++) + egps_j = nbatParams.energrp[cj * (UNROLLJ / UNROLLI) + jdi]; + for (jj = 0; jj < (UNROLLI / 2); jj++) { - egp_jj[jdi*(UNROLLI/2)+jj] = ((egps_j >> (jj*egps_jshift)) & egps_jmask)*egps_jstride; + egp_jj[jdi * (UNROLLI / 2) + jj] = + ((egps_j >> (jj * egps_jshift)) & egps_jmask) * egps_jstride; } } -#endif +# endif } -#endif +# endif -#ifdef CALC_COULOMB -#ifndef ENERGY_GROUPS - vctot_S = vctot_S + vcoul_S0 + vcoul_S2; -#else +# ifdef CALC_COULOMB +# ifndef ENERGY_GROUPS + vctot_S = vctot_S + vcoul_S0 + vcoul_S2; +# else add_ener_grp_halves(vcoul_S0, vctp[0], vctp[1], egp_jj); add_ener_grp_halves(vcoul_S2, vctp[2], vctp[3], egp_jj); -#endif -#endif - -#ifdef CALC_LJ -#ifndef ENERGY_GROUPS - Vvdwtot_S = Vvdwtot_S + VLJ_S0 -#ifndef HALF_LJ - + VLJ_S2 -#endif - ; -#else +# endif +# endif + +# ifdef CALC_LJ +# ifndef ENERGY_GROUPS + Vvdwtot_S = Vvdwtot_S + VLJ_S0 +# ifndef HALF_LJ + + VLJ_S2 +# endif + ; +# else add_ener_grp_halves(VLJ_S0, vvdwtp[0], vvdwtp[1], egp_jj); -#ifndef HALF_LJ +# ifndef HALF_LJ add_ener_grp_halves(VLJ_S2, vvdwtp[2], vvdwtp[3], egp_jj); -#endif -#endif -#endif /* CALC_LJ */ -#endif /* CALC_ENERGIES */ +# endif +# endif +# endif /* CALC_LJ */ +#endif /* CALC_ENERGIES */ #ifdef CALC_LJ -#ifdef CALC_COULOMB - fscal_S0 = rinvsq_S0 * (frcoul_S0 + frLJ_S0); +# ifdef CALC_COULOMB + fscal_S0 = rinvsq_S0 * (frcoul_S0 + frLJ_S0); +# else + fscal_S0 = rinvsq_S0 * frLJ_S0; +# endif #else - fscal_S0 = rinvsq_S0 * frLJ_S0; -#endif -#else - fscal_S0 = rinvsq_S0 * frcoul_S0; + fscal_S0 = rinvsq_S0 * frcoul_S0; #endif /* CALC_LJ */ #if defined CALC_LJ && !defined HALF_LJ -#ifdef CALC_COULOMB - fscal_S2 = rinvsq_S2 * (frcoul_S2 + frLJ_S2); -#else - fscal_S2 = rinvsq_S2 * frLJ_S2; -#endif +# ifdef CALC_COULOMB + fscal_S2 = rinvsq_S2 * (frcoul_S2 + frLJ_S2); +# else + fscal_S2 = rinvsq_S2 * frLJ_S2; +# endif #else /* Atom 2 and 3 don't have LJ, so only add Coulomb forces */ - fscal_S2 = rinvsq_S2 * frcoul_S2; + fscal_S2 = rinvsq_S2 * frcoul_S2; #endif /* Calculate temporary vectorial force */ - tx_S0 = fscal_S0 * dx_S0; - tx_S2 = fscal_S2 * dx_S2; - ty_S0 = fscal_S0 * dy_S0; - ty_S2 = fscal_S2 * dy_S2; - tz_S0 = fscal_S0 * dz_S0; - tz_S2 = fscal_S2 * dz_S2; + tx_S0 = fscal_S0 * dx_S0; + tx_S2 = fscal_S2 * dx_S2; + ty_S0 = fscal_S0 * dy_S0; + ty_S2 = fscal_S2 * dy_S2; + tz_S0 = fscal_S0 * dz_S0; + tz_S2 = fscal_S2 * dz_S2; /* Increment i atom force */ - fix_S0 = fix_S0 + tx_S0; - fix_S2 = fix_S2 + tx_S2; - fiy_S0 = fiy_S0 + ty_S0; - fiy_S2 = fiy_S2 + ty_S2; - fiz_S0 = fiz_S0 + tz_S0; - fiz_S2 = fiz_S2 + tz_S2; + fix_S0 = fix_S0 + tx_S0; + fix_S2 = fix_S2 + tx_S2; + fiy_S0 = fiy_S0 + ty_S0; + fiy_S2 = fiy_S2 + ty_S2; + fiz_S0 = fiz_S0 + tz_S0; + fiz_S2 = fiz_S2 + tz_S2; /* Decrement j atom force */ - decrHsimd(f+ajx, tx_S0 + tx_S2); - decrHsimd(f+ajy, ty_S0 + ty_S2); - decrHsimd(f+ajz, tz_S0 + tz_S2); + decrHsimd(f + ajx, tx_S0 + tx_S2); + decrHsimd(f + ajy, ty_S0 + ty_S2); + decrHsimd(f + ajz, tz_S0 + tz_S2); } -#undef rinv_ex_S0 -#undef rinv_ex_S2 +#undef rinv_ex_S0 +#undef rinv_ex_S2 -#undef wco_vdw_S0 -#undef wco_vdw_S2 +#undef wco_vdw_S0 +#undef wco_vdw_S2 -#undef EXCL_FORCES +#undef EXCL_FORCES diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h index c69a9caea4..e17c121123 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_outer.h @@ -38,75 +38,75 @@ using namespace gmx; /* Unpack pointers for output */ - real *f = out->f.data(); - real *fshift = out->fshift.data(); + real* f = out->f.data(); + real* fshift = out->fshift.data(); #ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS - real *Vvdw = out->VSvdw.data(); - real *Vc = out->VSc.data(); -#else - real *Vvdw = out->Vvdw.data(); - real *Vc = out->Vc.data(); -#endif +# ifdef ENERGY_GROUPS + real* Vvdw = out->VSvdw.data(); + real* Vc = out->VSc.data(); +# else + real* Vvdw = out->Vvdw.data(); + real* Vc = out->Vc.data(); +# endif #endif - const nbnxn_cj_t *l_cj; - int ci, ci_sh; - int ish, ish3; - gmx_bool do_LJ, half_LJ, do_coul; - int cjind0, cjind1, cjind; + const nbnxn_cj_t* l_cj; + int ci, ci_sh; + int ish, ish3; + gmx_bool do_LJ, half_LJ, do_coul; + int cjind0, cjind1, cjind; #ifdef ENERGY_GROUPS - int Vstride_i; - int egps_ishift, egps_imask; - int egps_jshift, egps_jmask, egps_jstride; - int egps_i; - real *vvdwtp[UNROLLI]; - real *vctp[UNROLLI]; -#endif - - SimdReal shX_S; - SimdReal shY_S; - SimdReal shZ_S; - SimdReal ix_S0, iy_S0, iz_S0; - SimdReal ix_S2, iy_S2, iz_S2; - SimdReal fix_S0, fiy_S0, fiz_S0; - SimdReal fix_S2, fiy_S2, fiz_S2; - - SimdReal diagonal_jmi_S; + int Vstride_i; + int egps_ishift, egps_imask; + int egps_jshift, egps_jmask, egps_jstride; + int egps_i; + real* vvdwtp[UNROLLI]; + real* vctp[UNROLLI]; +#endif + + SimdReal shX_S; + SimdReal shY_S; + SimdReal shZ_S; + SimdReal ix_S0, iy_S0, iz_S0; + SimdReal ix_S2, iy_S2, iz_S2; + SimdReal fix_S0, fiy_S0, fiz_S0; + SimdReal fix_S2, fiy_S2, fiz_S2; + + SimdReal diagonal_jmi_S; #if UNROLLI == UNROLLJ - SimdBool diagonal_mask_S0, diagonal_mask_S2; + SimdBool diagonal_mask_S0, diagonal_mask_S2; #else - SimdBool diagonal_mask0_S0, diagonal_mask0_S2; - SimdBool diagonal_mask1_S0, diagonal_mask1_S2; + SimdBool diagonal_mask0_S0, diagonal_mask0_S2; + SimdBool diagonal_mask1_S0, diagonal_mask1_S2; #endif - SimdBitMask filter_S0, filter_S2; + SimdBitMask filter_S0, filter_S2; - SimdReal zero_S(0.0); + SimdReal zero_S(0.0); - SimdReal one_S(1.0); - SimdReal iq_S0 = setZero(); - SimdReal iq_S2 = setZero(); + SimdReal one_S(1.0); + SimdReal iq_S0 = setZero(); + SimdReal iq_S2 = setZero(); #ifdef CALC_COUL_RF - SimdReal mrc_3_S; -#ifdef CALC_ENERGIES - SimdReal hrc_3_S, moh_rc_S; -#endif + SimdReal mrc_3_S; +# ifdef CALC_ENERGIES + SimdReal hrc_3_S, moh_rc_S; +# endif #endif #ifdef CALC_COUL_TAB /* Coulomb table variables */ - SimdReal invtsp_S; - const real *tab_coul_F; -#if defined CALC_ENERGIES && !defined TAB_FDV0 - const real *tab_coul_V; -#endif + SimdReal invtsp_S; + const real* tab_coul_F; +# if defined CALC_ENERGIES && !defined TAB_FDV0 + const real* tab_coul_V; +# endif -#ifdef CALC_ENERGIES - SimdReal mhalfsp_S; -#endif +# ifdef CALC_ENERGIES + SimdReal mhalfsp_S; +# endif #endif #ifdef CALC_COUL_EWALD @@ -114,46 +114,46 @@ #endif #if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) - SimdReal sh_ewald_S; + SimdReal sh_ewald_S; #endif #if defined LJ_CUT && defined CALC_ENERGIES - SimdReal p6_cpot_S, p12_cpot_S; + SimdReal p6_cpot_S, p12_cpot_S; #endif #ifdef LJ_POT_SWITCH - SimdReal rswitch_S; - SimdReal swV3_S, swV4_S, swV5_S; - SimdReal swF2_S, swF3_S, swF4_S; + SimdReal rswitch_S; + SimdReal swV3_S, swV4_S, swV5_S; + SimdReal swF2_S, swF3_S, swF4_S; #endif #ifdef LJ_FORCE_SWITCH - SimdReal rswitch_S; - SimdReal p6_fc2_S, p6_fc3_S; - SimdReal p12_fc2_S, p12_fc3_S; -#ifdef CALC_ENERGIES - SimdReal p6_vc3_S, p6_vc4_S; - SimdReal p12_vc3_S, p12_vc4_S; - SimdReal p6_6cpot_S, p12_12cpot_S; -#endif + SimdReal rswitch_S; + SimdReal p6_fc2_S, p6_fc3_S; + SimdReal p12_fc2_S, p12_fc3_S; +# ifdef CALC_ENERGIES + SimdReal p6_vc3_S, p6_vc4_S; + SimdReal p12_vc3_S, p12_vc4_S; + SimdReal p6_6cpot_S, p12_12cpot_S; +# endif #endif #ifdef LJ_EWALD_GEOM - real lj_ewaldcoeff2, lj_ewaldcoeff6_6; - SimdReal mone_S, half_S, lje_c2_S, lje_c6_6_S; + real lj_ewaldcoeff2, lj_ewaldcoeff6_6; + SimdReal mone_S, half_S, lje_c2_S, lje_c6_6_S; #endif #ifdef LJ_COMB_LB - SimdReal hsig_i_S0, seps_i_S0; - SimdReal hsig_i_S2, seps_i_S2; + SimdReal hsig_i_S0, seps_i_S0; + SimdReal hsig_i_S2, seps_i_S2; #else -#ifdef FIX_LJ_C - alignas(GMX_SIMD_ALIGNMENT) real pvdw_c6[2*UNROLLI*UNROLLJ]; - real *pvdw_c12 = pvdw_c6 + UNROLLI*UNROLLJ; -#endif +# ifdef FIX_LJ_C + alignas(GMX_SIMD_ALIGNMENT) real pvdw_c6[2 * UNROLLI * UNROLLJ]; + real* pvdw_c12 = pvdw_c6 + UNROLLI * UNROLLJ; +# endif #endif /* LJ_COMB_LB */ - SimdReal minRsq_S; - SimdReal rc2_S; + SimdReal minRsq_S; + SimdReal rc2_S; #ifdef VDW_CUTOFF_CHECK - SimdReal rcvdw2_S; + SimdReal rcvdw2_S; #endif int ninner; @@ -162,46 +162,46 @@ int npair = 0; #endif - const nbnxn_atomdata_t::Params &nbatParams = nbat->params(); + const nbnxn_atomdata_t::Params& nbatParams = nbat->params(); #if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM - const real * gmx_restrict ljc = nbatParams.lj_comb.data(); + const real* gmx_restrict ljc = nbatParams.lj_comb.data(); #endif #if !(defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined FIX_LJ_C) /* No combination rule used */ - const real * gmx_restrict nbfp_ptr = nbatParams.nbfp_aligned.data(); - const int * gmx_restrict type = nbatParams.type.data(); + const real* gmx_restrict nbfp_ptr = nbatParams.nbfp_aligned.data(); + const int* gmx_restrict type = nbatParams.type.data(); #endif /* Load j-i for the first i */ - diagonal_jmi_S = load(nbat->simdMasks.diagonal_2xnn_j_minus_i.data()); + diagonal_jmi_S = load(nbat->simdMasks.diagonal_2xnn_j_minus_i.data()); /* Generate all the diagonal masks as comparison results */ #if UNROLLI == UNROLLJ - diagonal_mask_S0 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask_S2 = (zero_S < diagonal_jmi_S); + diagonal_mask_S0 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask_S2 = (zero_S < diagonal_jmi_S); #else -#if 2*UNROLLI == UNROLLJ - diagonal_mask0_S0 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask0_S2 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask1_S0 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask1_S2 = (zero_S < diagonal_jmi_S); -#endif +# if 2 * UNROLLI == UNROLLJ + diagonal_mask0_S0 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask0_S2 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask1_S0 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask1_S2 = (zero_S < diagonal_jmi_S); +# endif #endif /* Load masks for topology exclusion masking. filter_stride is static const, so the conditional will be optimized away. */ #if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL - const std::uint64_t * gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter64.data(); + const std::uint64_t* gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter64.data(); #else - const std::uint32_t * gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter.data(); + const std::uint32_t* gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter.data(); #endif /* Here we cast the exclusion filters from unsigned * to int * or real *. @@ -209,41 +209,41 @@ * matter, as long as both filter and mask data are treated the same way. */ #if GMX_SIMD_HAVE_INT32_LOGICAL - filter_S0 = load(reinterpret_cast(exclusion_filter + 0*UNROLLJ)); - filter_S2 = load(reinterpret_cast(exclusion_filter + 2*UNROLLJ)); + filter_S0 = load(reinterpret_cast(exclusion_filter + 0 * UNROLLJ)); + filter_S2 = load(reinterpret_cast(exclusion_filter + 2 * UNROLLJ)); #else - filter_S0 = load(reinterpret_cast(exclusion_filter + 0*UNROLLJ)); - filter_S2 = load(reinterpret_cast(exclusion_filter + 2*UNROLLJ)); + filter_S0 = load(reinterpret_cast(exclusion_filter + 0 * UNROLLJ)); + filter_S2 = load(reinterpret_cast(exclusion_filter + 2 * UNROLLJ)); #endif #ifdef CALC_COUL_RF /* Reaction-field constants */ - mrc_3_S = SimdReal(-2*ic->k_rf); -#ifdef CALC_ENERGIES + mrc_3_S = SimdReal(-2 * ic->k_rf); +# ifdef CALC_ENERGIES hrc_3_S = SimdReal(ic->k_rf); moh_rc_S = SimdReal(-ic->c_rf); -#endif +# endif #endif #ifdef CALC_COUL_TAB - invtsp_S = SimdReal(ic->coulombEwaldTables->scale); -#ifdef CALC_ENERGIES - mhalfsp_S = SimdReal(-0.5_real/ic->coulombEwaldTables->scale); -#endif + invtsp_S = SimdReal(ic->coulombEwaldTables->scale); +# ifdef CALC_ENERGIES + mhalfsp_S = SimdReal(-0.5_real / ic->coulombEwaldTables->scale); +# endif -#ifdef TAB_FDV0 +# ifdef TAB_FDV0 tab_coul_F = ic->coulombEwaldTables->tableFDV0.data(); -#else +# else tab_coul_F = ic->coulombEwaldTables->tableF.data(); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES tab_coul_V = ic->coulombEwaldTables->tableV.data(); -#endif -#endif +# endif +# endif #endif /* CALC_COUL_TAB */ #ifdef CALC_COUL_EWALD - beta2_S = SimdReal(ic->ewaldcoeff_q*ic->ewaldcoeff_q); + beta2_S = SimdReal(ic->ewaldcoeff_q * ic->ewaldcoeff_q); beta_S = SimdReal(ic->ewaldcoeff_q); #endif @@ -253,23 +253,23 @@ /* LJ function constants */ #if defined CALC_ENERGIES || defined LJ_POT_SWITCH - SimdReal sixth_S = SimdReal(1.0/6.0); - SimdReal twelveth_S = SimdReal(1.0/12.0); + SimdReal sixth_S = SimdReal(1.0 / 6.0); + SimdReal twelveth_S = SimdReal(1.0 / 12.0); #endif #if defined LJ_CUT && defined CALC_ENERGIES /* We shift the potential by cpot, which can be zero */ - p6_cpot_S = SimdReal(ic->dispersion_shift.cpot); - p12_cpot_S = SimdReal(ic->repulsion_shift.cpot); + p6_cpot_S = SimdReal(ic->dispersion_shift.cpot); + p12_cpot_S = SimdReal(ic->repulsion_shift.cpot); #endif #ifdef LJ_POT_SWITCH rswitch_S = SimdReal(ic->rvdw_switch); swV3_S = SimdReal(ic->vdw_switch.c3); swV4_S = SimdReal(ic->vdw_switch.c4); swV5_S = SimdReal(ic->vdw_switch.c5); - swF2_S = SimdReal(3*ic->vdw_switch.c3); - swF3_S = SimdReal(4*ic->vdw_switch.c4); - swF4_S = SimdReal(5*ic->vdw_switch.c5); + swF2_S = SimdReal(3 * ic->vdw_switch.c3); + swF3_S = SimdReal(4 * ic->vdw_switch.c4); + swF4_S = SimdReal(5 * ic->vdw_switch.c5); #endif #ifdef LJ_FORCE_SWITCH rswitch_S = SimdReal(ic->rvdw_switch); @@ -277,110 +277,110 @@ p6_fc3_S = SimdReal(ic->dispersion_shift.c3); p12_fc2_S = SimdReal(ic->repulsion_shift.c2); p12_fc3_S = SimdReal(ic->repulsion_shift.c3); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES { - SimdReal mthird_S = SimdReal(-1.0/3.0); - SimdReal mfourth_S = SimdReal(-1.0/4.0); + SimdReal mthird_S = SimdReal(-1.0 / 3.0); + SimdReal mfourth_S = SimdReal(-1.0 / 4.0); p6_vc3_S = mthird_S * p6_fc2_S; p6_vc4_S = mfourth_S * p6_fc3_S; - p6_6cpot_S = SimdReal(ic->dispersion_shift.cpot/6); + p6_6cpot_S = SimdReal(ic->dispersion_shift.cpot / 6); p12_vc3_S = mthird_S * p12_fc2_S; p12_vc4_S = mfourth_S * p12_fc3_S; - p12_12cpot_S = SimdReal(ic->repulsion_shift.cpot/12); + p12_12cpot_S = SimdReal(ic->repulsion_shift.cpot / 12); } -#endif +# endif #endif #ifdef LJ_EWALD_GEOM mone_S = SimdReal(-1.0); half_S = SimdReal(0.5); - lj_ewaldcoeff2 = ic->ewaldcoeff_lj*ic->ewaldcoeff_lj; - lj_ewaldcoeff6_6 = lj_ewaldcoeff2*lj_ewaldcoeff2*lj_ewaldcoeff2/6; + lj_ewaldcoeff2 = ic->ewaldcoeff_lj * ic->ewaldcoeff_lj; + lj_ewaldcoeff6_6 = lj_ewaldcoeff2 * lj_ewaldcoeff2 * lj_ewaldcoeff2 / 6; lje_c2_S = SimdReal(lj_ewaldcoeff2); lje_c6_6_S = SimdReal(lj_ewaldcoeff6_6); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES /* Determine the grid potential at the cut-off */ SimdReal lje_vc_S = SimdReal(ic->sh_lj_ewald); -#endif +# endif #endif /* The kernel either supports rcoulomb = rvdw or rcoulomb >= rvdw */ - rc2_S = SimdReal(ic->rcoulomb*ic->rcoulomb); + rc2_S = SimdReal(ic->rcoulomb * ic->rcoulomb); #ifdef VDW_CUTOFF_CHECK - rcvdw2_S = SimdReal(ic->rvdw*ic->rvdw); + rcvdw2_S = SimdReal(ic->rvdw * ic->rvdw); #endif - minRsq_S = SimdReal(NBNXN_MIN_RSQ); + minRsq_S = SimdReal(NBNXN_MIN_RSQ); - const real * gmx_restrict q = nbatParams.q.data(); - const real facel = ic->epsfac; - const real * gmx_restrict shiftvec = shift_vec[0]; - const real * gmx_restrict x = nbat->x().data(); + const real* gmx_restrict q = nbatParams.q.data(); + const real facel = ic->epsfac; + const real* gmx_restrict shiftvec = shift_vec[0]; + const real* gmx_restrict x = nbat->x().data(); #ifdef FIX_LJ_C for (jp = 0; jp < UNROLLJ; jp++) { - pvdw_c6 [0*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [1*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [2*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [3*UNROLLJ+jp] = nbat->nbfp[0*2]; - - pvdw_c12[0*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[1*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[2*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[3*UNROLLJ+jp] = nbat->nbfp[0*2+1]; + pvdw_c6[0 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[1 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[2 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[3 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + + pvdw_c12[0 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[1 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[2 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[3 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; } - SimdReal c6_S0 = load(pvdw_c6 +0*UNROLLJ); - SimdReal c6_S1 = load(pvdw_c6 +1*UNROLLJ); - SimdReal c6_S2 = load(pvdw_c6 +2*UNROLLJ); - SimdReal c6_S3 = load(pvdw_c6 +3*UNROLLJ); - - SimdReal c12_S0 = load(pvdw_c12+0*UNROLLJ); - SimdReal c12_S1 = load(pvdw_c12+1*UNROLLJ); - SimdReal c12_S2 = load(pvdw_c12+2*UNROLLJ); - SimdReal c12_S3 = load(pvdw_c12+3*UNROLLJ); + SimdReal c6_S0 = load(pvdw_c6 + 0 * UNROLLJ); + SimdReal c6_S1 = load(pvdw_c6 + 1 * UNROLLJ); + SimdReal c6_S2 = load(pvdw_c6 + 2 * UNROLLJ); + SimdReal c6_S3 = load(pvdw_c6 + 3 * UNROLLJ); + + SimdReal c12_S0 = load(pvdw_c12 + 0 * UNROLLJ); + SimdReal c12_S1 = load(pvdw_c12 + 1 * UNROLLJ); + SimdReal c12_S2 = load(pvdw_c12 + 2 * UNROLLJ); + SimdReal c12_S3 = load(pvdw_c12 + 3 * UNROLLJ); #endif /* FIX_LJ_C */ #ifdef ENERGY_GROUPS egps_ishift = nbatParams.neg_2log; - egps_imask = (1<>1)*UNROLLJ; + egps_imask = (1 << egps_ishift) - 1; + egps_jshift = 2 * nbatParams.neg_2log; + egps_jmask = (1 << egps_jshift) - 1; + egps_jstride = (UNROLLJ >> 1) * UNROLLJ; /* Major division is over i-particle energy groups, determine the stride */ - Vstride_i = nbatParams.nenergrp*(1 << nbatParams.neg_2log)*egps_jstride; + Vstride_i = nbatParams.nenergrp * (1 << nbatParams.neg_2log) * egps_jstride; #endif l_cj = nbl->cj.data(); ninner = 0; - for (const nbnxn_ci_t &ciEntry : nbl->ci) + for (const nbnxn_ci_t& ciEntry : nbl->ci) { - ish = (ciEntry.shift & NBNXN_CI_SHIFT); - ish3 = ish*3; - cjind0 = ciEntry.cj_ind_start; - cjind1 = ciEntry.cj_ind_end; - ci = ciEntry.ci; - ci_sh = (ish == CENTRAL ? ci : -1); + ish = (ciEntry.shift & NBNXN_CI_SHIFT); + ish3 = ish * 3; + cjind0 = ciEntry.cj_ind_start; + cjind1 = ciEntry.cj_ind_end; + ci = ciEntry.ci; + ci_sh = (ish == CENTRAL ? ci : -1); shX_S = SimdReal(shiftvec[ish3]); - shY_S = SimdReal(shiftvec[ish3+1]); - shZ_S = SimdReal(shiftvec[ish3+2]); + shY_S = SimdReal(shiftvec[ish3 + 1]); + shZ_S = SimdReal(shiftvec[ish3 + 2]); #if UNROLLJ <= 4 - int sci = ci*STRIDE; - int scix = sci*DIM; -#if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM - int sci2 = sci*2; -#endif + int sci = ci * STRIDE; + int scix = sci * DIM; +# if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM + int sci2 = sci * 2; +# endif #else - int sci = (ci>>1)*STRIDE; - int scix = sci*DIM + (ci & 1)*(STRIDE>>1); -#if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM - int sci2 = sci*2 + (ci & 1)*(STRIDE>>1); -#endif - sci += (ci & 1)*(STRIDE>>1); + int sci = (ci >> 1) * STRIDE; + int scix = sci * DIM + (ci & 1) * (STRIDE >> 1); +# if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM + int sci2 = sci * 2 + (ci & 1) * (STRIDE >> 1); +# endif + sci += (ci & 1) * (STRIDE >> 1); #endif /* We have 5 LJ/C combinations, but use only three inner loops, @@ -400,149 +400,150 @@ for (ia = 0; ia < UNROLLI; ia++) { - egp_ia = (egps_i >> (ia*egps_ishift)) & egps_imask; - vvdwtp[ia] = Vvdw + egp_ia*Vstride_i; - vctp[ia] = Vc + egp_ia*Vstride_i; + egp_ia = (egps_i >> (ia * egps_ishift)) & egps_imask; + vvdwtp[ia] = Vvdw + egp_ia * Vstride_i; + vctp[ia] = Vc + egp_ia * Vstride_i; } } #endif #ifdef CALC_ENERGIES -#ifdef LJ_EWALD_GEOM +# ifdef LJ_EWALD_GEOM gmx_bool do_self = TRUE; -#else +# else gmx_bool do_self = do_coul; -#endif -#if UNROLLJ == 4 +# endif +# if UNROLLJ == 4 if (do_self && l_cj[ciEntry.cj_ind_start].cj == ci_sh) -#endif -#if UNROLLJ == 8 - if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh>>1)) -#endif - { - if (do_coul) +# endif +# if UNROLLJ == 8 + if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh >> 1)) +# endif { - real Vc_sub_self; - int ia; - -#ifdef CALC_COUL_RF - Vc_sub_self = 0.5*ic->c_rf; -#endif -#ifdef CALC_COUL_TAB -#ifdef TAB_FDV0 - Vc_sub_self = 0.5*tab_coul_F[2]; -#else - Vc_sub_self = 0.5*tab_coul_V[0]; -#endif -#endif -#ifdef CALC_COUL_EWALD - /* beta/sqrt(pi) */ - Vc_sub_self = 0.5*ic->ewaldcoeff_q*M_2_SQRTPI; -#endif - - for (ia = 0; ia < UNROLLI; ia++) + if (do_coul) { - real qi; - - qi = q[sci+ia]; -#ifdef ENERGY_GROUPS - vctp[ia][((egps_i>>(ia*egps_ishift)) & egps_imask)*egps_jstride] -#else + real Vc_sub_self; + int ia; + +# ifdef CALC_COUL_RF + Vc_sub_self = 0.5 * ic->c_rf; +# endif +# ifdef CALC_COUL_TAB +# ifdef TAB_FDV0 + Vc_sub_self = 0.5 * tab_coul_F[2]; +# else + Vc_sub_self = 0.5 * tab_coul_V[0]; +# endif +# endif +# ifdef CALC_COUL_EWALD + /* beta/sqrt(pi) */ + Vc_sub_self = 0.5 * ic->ewaldcoeff_q * M_2_SQRTPI; +# endif + + for (ia = 0; ia < UNROLLI; ia++) + { + real qi; + + qi = q[sci + ia]; +# ifdef ENERGY_GROUPS + vctp[ia][((egps_i >> (ia * egps_ishift)) & egps_imask) * egps_jstride] +# else Vc[0] -#endif - -= facel*qi*qi*Vc_sub_self; +# endif + -= facel * qi * qi * Vc_sub_self; + } } - } - -#ifdef LJ_EWALD_GEOM - { - int ia; - for (ia = 0; ia < UNROLLI; ia++) +# ifdef LJ_EWALD_GEOM { - real c6_i; - - c6_i = nbatParams.nbfp[nbatParams.type[sci+ia]*(nbatParams.numTypes + 1)*2]/6; -#ifdef ENERGY_GROUPS - vvdwtp[ia][((egps_i>>(ia*egps_ishift)) & egps_imask)*egps_jstride] -#else - Vvdw[0] -#endif - += 0.5*c6_i*lj_ewaldcoeff6_6; + int ia; + + for (ia = 0; ia < UNROLLI; ia++) + { + real c6_i; + + c6_i = nbatParams.nbfp[nbatParams.type[sci + ia] * (nbatParams.numTypes + 1) * 2] + / 6; +# ifdef ENERGY_GROUPS + vvdwtp[ia][((egps_i >> (ia * egps_ishift)) & egps_imask) * egps_jstride] +# else + Vvdw[0] +# endif + += 0.5 * c6_i * lj_ewaldcoeff6_6; + } } +# endif /* LJ_EWALD */ } -#endif /* LJ_EWALD */ - } #endif /* Load i atom data */ - int sciy = scix + STRIDE; - int sciz = sciy + STRIDE; - ix_S0 = loadU1DualHsimd(x+scix); - ix_S2 = loadU1DualHsimd(x+scix+2); - iy_S0 = loadU1DualHsimd(x+sciy); - iy_S2 = loadU1DualHsimd(x+sciy+2); - iz_S0 = loadU1DualHsimd(x+sciz); - iz_S2 = loadU1DualHsimd(x+sciz+2); - ix_S0 = ix_S0 + shX_S; - ix_S2 = ix_S2 + shX_S; - iy_S0 = iy_S0 + shY_S; - iy_S2 = iy_S2 + shY_S; - iz_S0 = iz_S0 + shZ_S; - iz_S2 = iz_S2 + shZ_S; + int sciy = scix + STRIDE; + int sciz = sciy + STRIDE; + ix_S0 = loadU1DualHsimd(x + scix); + ix_S2 = loadU1DualHsimd(x + scix + 2); + iy_S0 = loadU1DualHsimd(x + sciy); + iy_S2 = loadU1DualHsimd(x + sciy + 2); + iz_S0 = loadU1DualHsimd(x + sciz); + iz_S2 = loadU1DualHsimd(x + sciz + 2); + ix_S0 = ix_S0 + shX_S; + ix_S2 = ix_S2 + shX_S; + iy_S0 = iy_S0 + shY_S; + iy_S2 = iy_S2 + shY_S; + iz_S0 = iz_S0 + shZ_S; + iz_S2 = iz_S2 + shZ_S; if (do_coul) { SimdReal facel_S; - facel_S = SimdReal(facel); + facel_S = SimdReal(facel); - iq_S0 = loadU1DualHsimd(q+sci); - iq_S2 = loadU1DualHsimd(q+sci+2); - iq_S0 = facel_S * iq_S0; - iq_S2 = facel_S * iq_S2; + iq_S0 = loadU1DualHsimd(q + sci); + iq_S2 = loadU1DualHsimd(q + sci + 2); + iq_S0 = facel_S * iq_S0; + iq_S2 = facel_S * iq_S2; } #ifdef LJ_COMB_LB - hsig_i_S0 = loadU1DualHsimd(ljc+sci2); - hsig_i_S2 = loadU1DualHsimd(ljc+sci2+2); - seps_i_S0 = loadU1DualHsimd(ljc+sci2+STRIDE); - seps_i_S2 = loadU1DualHsimd(ljc+sci2+STRIDE+2); + hsig_i_S0 = loadU1DualHsimd(ljc + sci2); + hsig_i_S2 = loadU1DualHsimd(ljc + sci2 + 2); + seps_i_S0 = loadU1DualHsimd(ljc + sci2 + STRIDE); + seps_i_S2 = loadU1DualHsimd(ljc + sci2 + STRIDE + 2); #else -#ifdef LJ_COMB_GEOM - SimdReal c6s_S0, c12s_S0; - SimdReal c6s_S2, c12s_S2; +# ifdef LJ_COMB_GEOM + SimdReal c6s_S0, c12s_S0; + SimdReal c6s_S2, c12s_S2; - c6s_S0 = loadU1DualHsimd(ljc+sci2); + c6s_S0 = loadU1DualHsimd(ljc + sci2); if (!half_LJ) { - c6s_S2 = loadU1DualHsimd(ljc+sci2+2); + c6s_S2 = loadU1DualHsimd(ljc + sci2 + 2); } - c12s_S0 = loadU1DualHsimd(ljc+sci2+STRIDE); + c12s_S0 = loadU1DualHsimd(ljc + sci2 + STRIDE); if (!half_LJ) { - c12s_S2 = loadU1DualHsimd(ljc+sci2+STRIDE+2); + c12s_S2 = loadU1DualHsimd(ljc + sci2 + STRIDE + 2); } -#elif !defined LJ_COMB_LB && !defined FIX_LJ_C - const int numTypes = nbatParams.numTypes; - const real *nbfp0 = nbfp_ptr + type[sci ]*numTypes*c_simdBestPairAlignment; - const real *nbfp1 = nbfp_ptr + type[sci+1]*numTypes*c_simdBestPairAlignment; - const real *nbfp2 = nullptr, *nbfp3 = nullptr; +# elif !defined LJ_COMB_LB && !defined FIX_LJ_C + const int numTypes = nbatParams.numTypes; + const real* nbfp0 = nbfp_ptr + type[sci] * numTypes * c_simdBestPairAlignment; + const real* nbfp1 = nbfp_ptr + type[sci + 1] * numTypes * c_simdBestPairAlignment; + const real *nbfp2 = nullptr, *nbfp3 = nullptr; if (!half_LJ) { - nbfp2 = nbfp_ptr + type[sci+2]*numTypes*c_simdBestPairAlignment; - nbfp3 = nbfp_ptr + type[sci+3]*numTypes*c_simdBestPairAlignment; + nbfp2 = nbfp_ptr + type[sci + 2] * numTypes * c_simdBestPairAlignment; + nbfp3 = nbfp_ptr + type[sci + 3] * numTypes * c_simdBestPairAlignment; } -#endif +# endif #endif #ifdef LJ_EWALD_GEOM /* We need the geometrically combined C6 for the PME grid correction */ SimdReal c6s_S0, c6s_S2; - c6s_S0 = loadU1DualHsimd(ljc+sci2); + c6s_S0 = loadU1DualHsimd(ljc + sci2); if (!half_LJ) { - c6s_S2 = loadU1DualHsimd(ljc+sci2+2); + c6s_S2 = loadU1DualHsimd(ljc + sci2 + 2); } #endif @@ -553,12 +554,12 @@ #endif /* Clear i atom forces */ - fix_S0 = setZero(); - fix_S2 = setZero(); - fiy_S0 = setZero(); - fiy_S2 = setZero(); - fiz_S0 = setZero(); - fiz_S2 = setZero(); + fix_S0 = setZero(); + fix_S2 = setZero(); + fiy_S0 = setZero(); + fiy_S2 = setZero(); + fiz_S0 = setZero(); + fiz_S2 = setZero(); cjind = cjind0; @@ -619,14 +620,14 @@ ninner += cjind1 - cjind0; /* Add accumulated i-forces to the force array */ - real fShiftX = reduceIncr4ReturnSumHsimd(f+scix, fix_S0, fix_S2); - real fShiftY = reduceIncr4ReturnSumHsimd(f+sciy, fiy_S0, fiy_S2); - real fShiftZ = reduceIncr4ReturnSumHsimd(f+sciz, fiz_S0, fiz_S2); + real fShiftX = reduceIncr4ReturnSumHsimd(f + scix, fix_S0, fix_S2); + real fShiftY = reduceIncr4ReturnSumHsimd(f + sciy, fiy_S0, fiy_S2); + real fShiftZ = reduceIncr4ReturnSumHsimd(f + sciz, fiz_S0, fiz_S2); #ifdef CALC_SHIFTFORCES - fshift[ish3+0] += fShiftX; - fshift[ish3+1] += fShiftY; - fshift[ish3+2] += fShiftZ; + fshift[ish3 + 0] += fShiftX; + fshift[ish3 + 1] += fShiftY; + fshift[ish3 + 2] += fShiftZ; #endif #ifdef CALC_ENERGIES diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.cpp b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.cpp index 1dc9024565..3787909e12 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.cpp +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.cpp @@ -43,16 +43,15 @@ #include "gromacs/utility/gmxassert.h" #ifdef GMX_NBNXN_SIMD_2XNN -#define GMX_SIMD_J_UNROLL_SIZE 2 -#include "kernel_common.h" +# define GMX_SIMD_J_UNROLL_SIZE 2 +# include "kernel_common.h" #endif /* Prune a single nbnxn_pairtlist_t entry with distance rlistInner */ -void -nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner) +void nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner) { #ifdef GMX_NBNXN_SIMD_2XNN using namespace gmx; @@ -61,16 +60,16 @@ nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, nbl->ci.resize(nbl->ciOuter.size()); nbl->cj.resize(nbl->cjOuter.size()); - const nbnxn_ci_t * gmx_restrict ciOuter = nbl->ciOuter.data(); - nbnxn_ci_t * gmx_restrict ciInner = nbl->ci.data(); + const nbnxn_ci_t* gmx_restrict ciOuter = nbl->ciOuter.data(); + nbnxn_ci_t* gmx_restrict ciInner = nbl->ci.data(); - const nbnxn_cj_t * gmx_restrict cjOuter = nbl->cjOuter.data(); - nbnxn_cj_t * gmx_restrict cjInner = nbl->cj.data(); + const nbnxn_cj_t* gmx_restrict cjOuter = nbl->cjOuter.data(); + nbnxn_cj_t* gmx_restrict cjInner = nbl->cj.data(); - const real * gmx_restrict shiftvec = shift_vec[0]; - const real * gmx_restrict x = nbat->x().data(); + const real* gmx_restrict shiftvec = shift_vec[0]; + const real* gmx_restrict x = nbat->x().data(); - const SimdReal rlist2_S(rlistInner*rlistInner); + const SimdReal rlist2_S(rlistInner * rlistInner); /* Initialize the new list count as empty and add pairs that are in range */ int nciInner = 0; @@ -78,7 +77,7 @@ nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, const int nciOuter = nbl->ciOuter.size(); for (int i = 0; i < nciOuter; i++) { - const nbnxn_ci_t * gmx_restrict ciEntry = &ciOuter[i]; + const nbnxn_ci_t* gmx_restrict ciEntry = &ciOuter[i]; /* Copy the original list entry to the pruned entry */ ciInner[nciInner].ci = ciEntry->ci; @@ -86,57 +85,57 @@ nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, ciInner[nciInner].cj_ind_start = ncjInner; /* Extract shift data */ - int ish = (ciEntry->shift & NBNXN_CI_SHIFT); - int ish3 = ish*3; - int ci = ciEntry->ci; - - SimdReal shX_S = SimdReal(shiftvec[ish3 ]); - SimdReal shY_S = SimdReal(shiftvec[ish3 + 1]); - SimdReal shZ_S = SimdReal(shiftvec[ish3 + 2]); - -#if UNROLLJ <= 4 - int scix = ci*STRIDE*DIM; -#else - int scix = (ci >> 1)*STRIDE*DIM + (ci & 1)*(STRIDE >> 1); -#endif + int ish = (ciEntry->shift & NBNXN_CI_SHIFT); + int ish3 = ish * 3; + int ci = ciEntry->ci; + + SimdReal shX_S = SimdReal(shiftvec[ish3]); + SimdReal shY_S = SimdReal(shiftvec[ish3 + 1]); + SimdReal shZ_S = SimdReal(shiftvec[ish3 + 2]); + +# if UNROLLJ <= 4 + int scix = ci * STRIDE * DIM; +# else + int scix = (ci >> 1) * STRIDE * DIM + (ci & 1) * (STRIDE >> 1); +# endif /* Load i atom data */ - int sciy = scix + STRIDE; - int sciz = sciy + STRIDE; - SimdReal ix_S0 = loadU1DualHsimd(x + scix ) + shX_S; - SimdReal ix_S2 = loadU1DualHsimd(x + scix + 2) + shX_S; - SimdReal iy_S0 = loadU1DualHsimd(x + sciy ) + shY_S; - SimdReal iy_S2 = loadU1DualHsimd(x + sciy + 2) + shY_S; - SimdReal iz_S0 = loadU1DualHsimd(x + sciz ) + shZ_S; - SimdReal iz_S2 = loadU1DualHsimd(x + sciz + 2) + shZ_S; + int sciy = scix + STRIDE; + int sciz = sciy + STRIDE; + SimdReal ix_S0 = loadU1DualHsimd(x + scix) + shX_S; + SimdReal ix_S2 = loadU1DualHsimd(x + scix + 2) + shX_S; + SimdReal iy_S0 = loadU1DualHsimd(x + sciy) + shY_S; + SimdReal iy_S2 = loadU1DualHsimd(x + sciy + 2) + shY_S; + SimdReal iz_S0 = loadU1DualHsimd(x + sciz) + shZ_S; + SimdReal iz_S2 = loadU1DualHsimd(x + sciz + 2) + shZ_S; for (int cjind = ciEntry->cj_ind_start; cjind < ciEntry->cj_ind_end; cjind++) { /* j-cluster index */ - int cj = cjOuter[cjind].cj; + int cj = cjOuter[cjind].cj; /* Atom indices (of the first atom in the cluster) */ -#if UNROLLJ == STRIDE - int aj = cj*UNROLLJ; - int ajx = aj*DIM; -#else - int ajx = (cj >> 1)*DIM*STRIDE + (cj & 1)*UNROLLJ; -#endif - int ajy = ajx + STRIDE; - int ajz = ajy + STRIDE; +# if UNROLLJ == STRIDE + int aj = cj * UNROLLJ; + int ajx = aj * DIM; +# else + int ajx = (cj >> 1) * DIM * STRIDE + (cj & 1) * UNROLLJ; +# endif + int ajy = ajx + STRIDE; + int ajz = ajy + STRIDE; /* load j atom coordinates */ - SimdReal jx_S = loadDuplicateHsimd(x + ajx); - SimdReal jy_S = loadDuplicateHsimd(x + ajy); - SimdReal jz_S = loadDuplicateHsimd(x + ajz); + SimdReal jx_S = loadDuplicateHsimd(x + ajx); + SimdReal jy_S = loadDuplicateHsimd(x + ajy); + SimdReal jz_S = loadDuplicateHsimd(x + ajz); /* Calculate distance */ - SimdReal dx_S0 = ix_S0 - jx_S; - SimdReal dy_S0 = iy_S0 - jy_S; - SimdReal dz_S0 = iz_S0 - jz_S; - SimdReal dx_S2 = ix_S2 - jx_S; - SimdReal dy_S2 = iy_S2 - jy_S; - SimdReal dz_S2 = iz_S2 - jz_S; + SimdReal dx_S0 = ix_S0 - jx_S; + SimdReal dy_S0 = iy_S0 - jy_S; + SimdReal dz_S0 = iz_S0 - jz_S; + SimdReal dx_S2 = ix_S2 - jx_S; + SimdReal dy_S2 = iy_S2 - jy_S; + SimdReal dz_S2 = iz_S2 - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ SimdReal rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); @@ -146,7 +145,7 @@ nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, SimdBool wco_S0 = (rsq_S0 < rlist2_S); SimdBool wco_S2 = (rsq_S2 < rlist2_S); - wco_S0 = wco_S0 || wco_S2; + wco_S0 = wco_S0 || wco_S2; /* Putting the assignment inside the conditional is slower */ cjInner[ncjInner] = cjOuter[cjind]; @@ -166,7 +165,7 @@ nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, nbl->ci.resize(nciInner); nbl->cj.resize(ncjInner); -#else /* GMX_NBNXN_SIMD_2XNN */ +#else /* GMX_NBNXN_SIMD_2XNN */ GMX_RELEASE_ASSERT(false, "2xNN kernel called without 2xNN support"); diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.h b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.h index a228123285..ce2b878030 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.h +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernel_prune.h @@ -54,8 +54,7 @@ struct NbnxnPairlistCpu; * Reads a cluster pairlist \p nbl->ciOuter, \p nbl->cjOuter and writes * all cluster pairs within \p rlistInner to \p nbl->ci, \p nbl->cj. */ -void -nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner); +void nbnxn_kernel_prune_2xnn(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner); diff --git a/src/gromacs/nbnxm/kernels_simd_2xmm/kernels.h b/src/gromacs/nbnxm/kernels_simd_2xmm/kernels.h index 52ba3fc0df..4f18775a4b 100644 --- a/src/gromacs/nbnxm/kernels_simd_2xmm/kernels.h +++ b/src/gromacs/nbnxm/kernels_simd_2xmm/kernels.h @@ -42,99 +42,98 @@ /* Declare all the different kernel functions. */ -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJ_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJ_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJ_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJ_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm; - -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm; #ifdef INCLUDE_KERNELFUNCTION_TABLES @@ -143,135 +142,132 @@ nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm; * The minor index of the array goes over both the LJ combination rules, * which is only supported by plain cut-off, and the LJ switch/PME functions. */ -static p_nbk_func_noener nbnxm_kernel_noener_simd_2xmm[coulktNR][vdwktNR] = -{ +static p_nbk_func_noener nbnxm_kernel_noener_simd_2xmm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm, - nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm, - nbnxm_kernel_ElecRF_VdwLJ_F_2xmm, - nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm, - nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombLB_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJ_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJFSw_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJPSw_F_2xmm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_2xmm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJ_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_F_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_2xmm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_2xmm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm, - nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm, - nbnxm_kernel_ElecEw_VdwLJ_F_2xmm, - nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm, - nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombLB_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJ_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJFSw_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJPSw_F_2xmm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_2xmm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_2xmm, }, }; -static p_nbk_func_ener nbnxm_kernel_ener_simd_2xmm[coulktNR][vdwktNR] = -{ +static p_nbk_func_ener nbnxm_kernel_ener_simd_2xmm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm, - nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm, - nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm, - nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm, - nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombLB_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJ_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJFSw_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJPSw_VF_2xmm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_2xmm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJ_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_2xmm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_2xmm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm, - nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm, - nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm, - nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm, - nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombLB_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJ_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJFSw_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJPSw_VF_2xmm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_2xmm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_2xmm, }, }; -static p_nbk_func_ener nbnxm_kernel_energrp_simd_2xmm[coulktNR][vdwktNR] = -{ +static p_nbk_func_ener nbnxm_kernel_energrp_simd_2xmm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm, - nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm, - nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm, - nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm, - nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJ_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_2xmm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_2xmm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_2xmm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_2xmm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_2xmm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_2xmm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm, - nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm, - nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm, - nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm, - nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJ_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_2xmm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_2xmm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_2xmm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_2xmm, }, }; diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp index 56f1e44ae7..9d567634b8 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp index ffc0b34081..47309f9d74 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp index bec89c4b04..1623f74445 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp index 69d71d51f8..7eda1fb96b 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp index 40cb3d8978..30822dcb95 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp index ef64e7e0b0..1856badbbd 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp index aefe586cd7..1779714775 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_F.cpp @@ -59,32 +59,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp index 6e0969e1c6..596c865657 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF.cpp @@ -59,32 +59,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp index 52604e9c0c..c4a549bc54 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF.cpp @@ -60,32 +60,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp index d9c0de482c..44ed5f0157 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp index 0521bdba6c..b99c1f74fd 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp index bfc9f0eaa8..4a5135107c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJFSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp index aa607fa69d..86501c0740 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp index 33de743c76..dfc7fcd07c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp index 5cf3e42984..a7a0eda0b0 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJPSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_F.cpp index 1fa321b188..2c18836dc1 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp index c0239f5e5c..7b45b4a92c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp index a9fbb7bfd6..1b9bd967f0 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEwTwinCut_VdwLJ_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_F.cpp index f79a8b4ec2..9aa22053ba 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VF.cpp index ca9f25d6e5..5be187ac52 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp index ef045e2b37..07edbc0f2d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_F.cpp index cd2b5b55d8..0791798449 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VF.cpp index 4592c0888f..58c2ed4798 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp index 1c8a545131..9f108b9655 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp index 3d8ce55d0e..30d8119073 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp index 09f6bf8838..af1b5b4834 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp index 935e5abf52..16d5cafdee 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_F.cpp index 1844fe305d..ad3557cca9 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VF.cpp index af339d9eb5..703a2a7f6a 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp index 92e4320554..f7dc53976a 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_F.cpp index 73d27bc5e7..0aaeab0c53 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VF.cpp index 46d71ab0be..4e10299853 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp index a8b471acd2..a1ab611c68 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_F.cpp index d98a3070f3..52a57f3d56 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VF.cpp index f56f84ac16..ff42fe93da 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VgrpF.cpp index c678781073..997afc048d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecEw_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp index 9da9e06358..0f28465cca 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp index e52981e755..246c659767 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp index d2096a3a40..f314b480e7 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp index 2cd9431c68..79933ae073 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp index 4b2ec4f101..2e59cc99ad 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp index 2e72c533d1..3795d623a1 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp index 4b8ee4d3f6..7b1f7813f3 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F.cpp @@ -59,32 +59,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp index dc1a1b329e..249dc5bbec 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF.cpp @@ -59,32 +59,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp index 995d645030..dbc41bad4e 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF.cpp @@ -60,32 +60,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp index 1c208163c6..6876cec386 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp index 3cca2781e7..2f3793cb60 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp index dc1532155e..a5505bde8d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp index 5f18a79d02..0a1e2902fb 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp index 156a9637bf..6b26a6c197 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp index 0aaab4dcbf..846d648897 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp index 4372f4eee6..35a415d277 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp index 60b4030f2d..b343c9ba9f 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp index 698900695b..5d4b1aa3c9 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTabTwinCut_VdwLJ_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp index d6bd1c18db..5221aa1c5d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp index 19fac05b23..59e849a561 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp index 6df4d69625..23f683ea15 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_F.cpp index 4b2b6b7582..f0d9798122 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp index b9310d5381..a5cbe27842 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp index 4946c77b66..407d75cbe0 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp index 6efe19d96d..56e9a56952 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp index b117989e3e..b3e8a6e101 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp index 77a76c69be..8b9ff68506 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_F.cpp index 92f4a0e6fb..ea1edebca8 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VF.cpp index ec53a50c73..e2c15d9a7c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp index 71714182b9..059b670425 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_F.cpp index bbd30f5979..720456c15d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VF.cpp index 38aabeb1e4..0f86de77dd 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp index d116aacc11..73a40d20de 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_F.cpp index 87f945393f..1ec1bbd4f4 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VF.cpp index c9a7da6779..661e228130 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp index 170607e108..07616eaecc 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecQSTab_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_F.cpp index 303c1c7fee..976e975e9d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VF.cpp index 4cfcdb74df..46c1615166 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp index 6798cc2133..7858dfa138 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombGeom_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_F.cpp index 15c19aef02..cd0eafd840 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VF.cpp index 7b943bc3d8..6932661498 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp index 0e3204140b..d99f31087b 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJCombLB_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp index ceeeb64967..da911b0b35 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_F.cpp @@ -58,32 +58,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp index d3fc817bba..c8462ae377 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VF.cpp @@ -58,32 +58,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp index 8bff4e688f..84dffde13d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJEwCombGeom_VgrpF.cpp @@ -59,32 +59,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_F.cpp index 7f81b50a86..1031df717d 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VF.cpp index 2d9aa86a0a..1a92e1be36 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp index 1816abf2d9..73b1c27c64 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJFSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_F.cpp index f2a83db3b5..27235fad5c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VF.cpp index 720144261f..be74b2cd19 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp index 0fa843ae5f..e3ea24e89c 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJPSw_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_F.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_F.cpp index f2a47c6c2c..5750843b96 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_F.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_F.cpp @@ -57,32 +57,30 @@ /* Will not calculate energies */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_F_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VF.cpp index 2efd7e5360..504eb64690 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VF.cpp @@ -57,32 +57,30 @@ #define CALC_ENERGIES #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_VF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VgrpF.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VgrpF.cpp index 954585210b..5362d939d4 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VgrpF.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_ElecRF_VdwLJ_VgrpF.cpp @@ -58,32 +58,30 @@ #define ENERGY_GROUPS #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_common.h" +# include "kernel_common.h" #endif /* GMX_NBNXN_SIMD_4XN */ #ifdef CALC_ENERGIES -void -nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) -#else /* CALC_ENERGIES */ -void -nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused *nbl, - const nbnxn_atomdata_t gmx_unused *nbat, - const interaction_const_t gmx_unused *ic, - const rvec gmx_unused *shift_vec, - nbnxn_atomdata_output_t gmx_unused *out) +void nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) +#else /* CALC_ENERGIES */ +void nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm(const NbnxnPairlistCpu gmx_unused* nbl, + const nbnxn_atomdata_t gmx_unused* nbat, + const interaction_const_t gmx_unused* ic, + const rvec gmx_unused* shift_vec, + nbnxn_atomdata_output_t gmx_unused* out) #endif /* CALC_ENERGIES */ #ifdef GMX_NBNXN_SIMD_4XN -#include "kernel_outer.h" -#else /* GMX_NBNXN_SIMD_4XN */ +# include "kernel_outer.h" +#else /* GMX_NBNXN_SIMD_4XN */ { -/* No need to call gmx_incons() here, because the only function - * that calls this one is also compiled conditionally. When - * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and - * instead call gmx_incons(). - */ + /* No need to call gmx_incons() here, because the only function + * that calls this one is also compiled conditionally. When + * GMX_NBNXN_SIMD_4XN is not defined, it will call no kernel functions and + * instead call gmx_incons(). + */ } #endif /* GMX_NBNXN_SIMD_4XN */ diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h index 364260a6f8..3d83a4ae9b 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_common.h @@ -38,41 +38,41 @@ #include "gromacs/simd/vector_operations.h" #include "gromacs/utility/basedefinitions.h" #ifdef CALC_COUL_EWALD -#include "gromacs/math/utilities.h" +# include "gromacs/math/utilities.h" #endif #include "config.h" #ifndef GMX_SIMD_J_UNROLL_SIZE -#error "Need to define GMX_SIMD_J_UNROLL_SIZE before including the 4xn kernel common header file" +# error "Need to define GMX_SIMD_J_UNROLL_SIZE before including the 4xn kernel common header file" #endif -#define UNROLLI 4 -#define UNROLLJ (GMX_SIMD_REAL_WIDTH/GMX_SIMD_J_UNROLL_SIZE) +#define UNROLLI 4 +#define UNROLLJ (GMX_SIMD_REAL_WIDTH / GMX_SIMD_J_UNROLL_SIZE) static_assert(UNROLLI == c_nbnxnCpuIClusterSize, "UNROLLI should match the i-cluster size"); /* The stride of all the atom data arrays is max(UNROLLI,unrollj) */ #if GMX_SIMD_REAL_WIDTH >= UNROLLI -#define STRIDE (GMX_SIMD_REAL_WIDTH/GMX_SIMD_J_UNROLL_SIZE) +# define STRIDE (GMX_SIMD_REAL_WIDTH / GMX_SIMD_J_UNROLL_SIZE) #else -#define STRIDE (UNROLLI) +# define STRIDE (UNROLLI) #endif #if !defined GMX_NBNXN_SIMD_2XNN && !defined GMX_NBNXN_SIMD_4XN -#error "Must define an NBNxN kernel flavour before including NBNxN kernel utility functions" +# error "Must define an NBNxN kernel flavour before including NBNxN kernel utility functions" #endif // We use the FDV0 tables for width==4 (when we can load it in one go), or if we don't have any unaligned loads #if GMX_SIMD_REAL_WIDTH == 4 || !GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL -#define TAB_FDV0 +# define TAB_FDV0 #endif #ifdef UNROLLJ /* Add energy register to possibly multiple terms in the energy array */ -static inline void add_ener_grp(gmx::SimdReal e_S, real *v, const int *offset_jj) +static inline void add_ener_grp(gmx::SimdReal e_S, real* v, const int* offset_jj) { using namespace gmx; int jj; @@ -81,68 +81,70 @@ static inline void add_ener_grp(gmx::SimdReal e_S, real *v, const int *offset_jj * the rapidly increases number of combinations of energy groups. * We add to a temporary buffer for 1 i-group vs 2 j-groups. */ - for (jj = 0; jj < (UNROLLJ/2); jj++) + for (jj = 0; jj < (UNROLLJ / 2); jj++) { SimdReal v_S; - v_S = load(v+offset_jj[jj]+jj*GMX_SIMD_REAL_WIDTH); - store(v+offset_jj[jj]+jj*GMX_SIMD_REAL_WIDTH, v_S + e_S); + v_S = load(v + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH); + store(v + offset_jj[jj] + jj * GMX_SIMD_REAL_WIDTH, v_S + e_S); } } #endif #if GMX_SIMD_HAVE_INT32_LOGICAL -typedef gmx::SimdInt32 SimdBitMask; +typedef gmx::SimdInt32 SimdBitMask; #else -typedef gmx::SimdReal SimdBitMask; +typedef gmx::SimdReal SimdBitMask; #endif -static inline void gmx_simdcall -gmx_load_simd_4xn_interactions(int excl, - SimdBitMask gmx_unused filter_S0, - SimdBitMask gmx_unused filter_S1, - SimdBitMask gmx_unused filter_S2, - SimdBitMask gmx_unused filter_S3, - const real gmx_unused *simd_interaction_array, - gmx::SimdBool *interact_S0, - gmx::SimdBool *interact_S1, - gmx::SimdBool *interact_S2, - gmx::SimdBool *interact_S3) +static inline void gmx_simdcall gmx_load_simd_4xn_interactions(int excl, + SimdBitMask gmx_unused filter_S0, + SimdBitMask gmx_unused filter_S1, + SimdBitMask gmx_unused filter_S2, + SimdBitMask gmx_unused filter_S3, + const real gmx_unused* simd_interaction_array, + gmx::SimdBool* interact_S0, + gmx::SimdBool* interact_S1, + gmx::SimdBool* interact_S2, + gmx::SimdBool* interact_S3) { using namespace gmx; #if GMX_SIMD_HAVE_INT32_LOGICAL /* Load integer interaction mask */ SimdInt32 mask_pr_S(excl); - *interact_S0 = cvtIB2B(testBits( mask_pr_S & filter_S0 )); - *interact_S1 = cvtIB2B(testBits( mask_pr_S & filter_S1 )); - *interact_S2 = cvtIB2B(testBits( mask_pr_S & filter_S2 )); - *interact_S3 = cvtIB2B(testBits( mask_pr_S & filter_S3 )); + *interact_S0 = cvtIB2B(testBits(mask_pr_S & filter_S0)); + *interact_S1 = cvtIB2B(testBits(mask_pr_S & filter_S1)); + *interact_S2 = cvtIB2B(testBits(mask_pr_S & filter_S2)); + *interact_S3 = cvtIB2B(testBits(mask_pr_S & filter_S3)); #elif GMX_SIMD_HAVE_LOGICAL - union - { -#if GMX_DOUBLE + union { +# if GMX_DOUBLE std::int64_t i; -#else +# else std::int32_t i; -#endif +# endif real r; } conv; conv.i = excl; - SimdReal mask_pr_S(conv.r); + SimdReal mask_pr_S(conv.r); - *interact_S0 = testBits( mask_pr_S & filter_S0 ); - *interact_S1 = testBits( mask_pr_S & filter_S1 ); - *interact_S2 = testBits( mask_pr_S & filter_S2 ); - *interact_S3 = testBits( mask_pr_S & filter_S3 ); + *interact_S0 = testBits(mask_pr_S & filter_S0); + *interact_S1 = testBits(mask_pr_S & filter_S1); + *interact_S2 = testBits(mask_pr_S & filter_S2); + *interact_S3 = testBits(mask_pr_S & filter_S3); #else // Neither real or integer bitwise logical operations supported. // Load masks from memory instead. - SimdReal zero = setZero(); - *interact_S0 = ( zero < load( simd_interaction_array + GMX_SIMD_REAL_WIDTH*((excl >> (0 * UNROLLJ)) & 0xF) ) ); - *interact_S1 = ( zero < load( simd_interaction_array + GMX_SIMD_REAL_WIDTH*((excl >> (1 * UNROLLJ)) & 0xF) ) ); - *interact_S2 = ( zero < load( simd_interaction_array + GMX_SIMD_REAL_WIDTH*((excl >> (2 * UNROLLJ)) & 0xF) ) ); - *interact_S3 = ( zero < load( simd_interaction_array + GMX_SIMD_REAL_WIDTH*((excl >> (3 * UNROLLJ)) & 0xF) ) ); + SimdReal zero = setZero(); + *interact_S0 = (zero < load(simd_interaction_array + + GMX_SIMD_REAL_WIDTH * ((excl >> (0 * UNROLLJ)) & 0xF))); + *interact_S1 = (zero < load(simd_interaction_array + + GMX_SIMD_REAL_WIDTH * ((excl >> (1 * UNROLLJ)) & 0xF))); + *interact_S2 = (zero < load(simd_interaction_array + + GMX_SIMD_REAL_WIDTH * ((excl >> (2 * UNROLLJ)) & 0xF))); + *interact_S3 = (zero < load(simd_interaction_array + + GMX_SIMD_REAL_WIDTH * ((excl >> (3 * UNROLLJ)) & 0xF))); #endif } diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h index 11867ab8a3..8294692c4f 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_inner.h @@ -51,319 +51,316 @@ * separately to as then it is easier to separate the energy and virial * contributions. */ -#if defined CHECK_EXCLS && (defined CALC_COULOMB || defined LJ_EWALD_GEOM) -#define EXCL_FORCES -#endif +# if defined CHECK_EXCLS && (defined CALC_COULOMB || defined LJ_EWALD_GEOM) +# define EXCL_FORCES +# endif { - int cj, ajx, ajy, ajz; + int cj, ajx, ajy, ajz; int gmx_unused aj; -#ifdef ENERGY_GROUPS +# ifdef ENERGY_GROUPS /* Energy group indices for two atoms packed into one int */ - int egp_jj[UNROLLJ/2]; -#endif + int egp_jj[UNROLLJ / 2]; +# endif -#ifdef CHECK_EXCLS +# ifdef CHECK_EXCLS /* Interaction (non-exclusion) mask of all 1's or 0's */ - SimdBool interact_S0; - SimdBool interact_S1; - SimdBool interact_S2; - SimdBool interact_S3; -#endif - - SimdReal jx_S, jy_S, jz_S; - SimdReal dx_S0, dy_S0, dz_S0; - SimdReal dx_S1, dy_S1, dz_S1; - SimdReal dx_S2, dy_S2, dz_S2; - SimdReal dx_S3, dy_S3, dz_S3; - SimdReal tx_S0, ty_S0, tz_S0; - SimdReal tx_S1, ty_S1, tz_S1; - SimdReal tx_S2, ty_S2, tz_S2; - SimdReal tx_S3, ty_S3, tz_S3; - SimdReal rsq_S0, rinv_S0, rinvsq_S0; - SimdReal rsq_S1, rinv_S1, rinvsq_S1; - SimdReal rsq_S2, rinv_S2, rinvsq_S2; - SimdReal rsq_S3, rinv_S3, rinvsq_S3; + SimdBool interact_S0; + SimdBool interact_S1; + SimdBool interact_S2; + SimdBool interact_S3; +# endif + + SimdReal jx_S, jy_S, jz_S; + SimdReal dx_S0, dy_S0, dz_S0; + SimdReal dx_S1, dy_S1, dz_S1; + SimdReal dx_S2, dy_S2, dz_S2; + SimdReal dx_S3, dy_S3, dz_S3; + SimdReal tx_S0, ty_S0, tz_S0; + SimdReal tx_S1, ty_S1, tz_S1; + SimdReal tx_S2, ty_S2, tz_S2; + SimdReal tx_S3, ty_S3, tz_S3; + SimdReal rsq_S0, rinv_S0, rinvsq_S0; + SimdReal rsq_S1, rinv_S1, rinvsq_S1; + SimdReal rsq_S2, rinv_S2, rinvsq_S2; + SimdReal rsq_S3, rinv_S3, rinvsq_S3; /* wco: within cut-off, mask of all 1's or 0's */ - SimdBool wco_S0; - SimdBool wco_S1; - SimdBool wco_S2; - SimdBool wco_S3; - -#ifdef VDW_CUTOFF_CHECK - SimdBool wco_vdw_S0; - SimdBool wco_vdw_S1; -#ifndef HALF_LJ - SimdBool wco_vdw_S2; - SimdBool wco_vdw_S3; -#endif -#endif - -#if (defined CALC_COULOMB && defined CALC_COUL_TAB) || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - SimdReal r_S0; - SimdReal r_S1; -#if (defined CALC_COULOMB && defined CALC_COUL_TAB) || !defined HALF_LJ + SimdBool wco_S0; + SimdBool wco_S1; + SimdBool wco_S2; + SimdBool wco_S3; + +# ifdef VDW_CUTOFF_CHECK + SimdBool wco_vdw_S0; + SimdBool wco_vdw_S1; +# ifndef HALF_LJ + SimdBool wco_vdw_S2; + SimdBool wco_vdw_S3; +# endif +# endif + +# if (defined CALC_COULOMB && defined CALC_COUL_TAB) || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH + SimdReal r_S0; + SimdReal r_S1; +# if (defined CALC_COULOMB && defined CALC_COUL_TAB) || !defined HALF_LJ SimdReal r_S2; SimdReal r_S3; -#endif -#endif - -#if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH - SimdReal rsw_S0, rsw2_S0; - SimdReal rsw_S1, rsw2_S1; -#ifndef HALF_LJ - SimdReal rsw_S2, rsw2_S2; - SimdReal rsw_S3, rsw2_S3; -#endif -#endif - -#ifdef CALC_COULOMB -#ifdef CHECK_EXCLS +# endif +# endif + +# if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH + SimdReal rsw_S0, rsw2_S0; + SimdReal rsw_S1, rsw2_S1; +# ifndef HALF_LJ + SimdReal rsw_S2, rsw2_S2; + SimdReal rsw_S3, rsw2_S3; +# endif +# endif + +# ifdef CALC_COULOMB +# ifdef CHECK_EXCLS /* 1/r masked with the interaction mask */ - SimdReal rinv_ex_S0; - SimdReal rinv_ex_S1; - SimdReal rinv_ex_S2; - SimdReal rinv_ex_S3; -#endif - SimdReal jq_S; - SimdReal qq_S0; - SimdReal qq_S1; - SimdReal qq_S2; - SimdReal qq_S3; -#ifdef CALC_COUL_TAB + SimdReal rinv_ex_S0; + SimdReal rinv_ex_S1; + SimdReal rinv_ex_S2; + SimdReal rinv_ex_S3; +# endif + SimdReal jq_S; + SimdReal qq_S0; + SimdReal qq_S1; + SimdReal qq_S2; + SimdReal qq_S3; +# ifdef CALC_COUL_TAB /* The force (PME mesh force) we need to subtract from 1/r^2 */ - SimdReal fsub_S0; - SimdReal fsub_S1; - SimdReal fsub_S2; - SimdReal fsub_S3; -#endif -#ifdef CALC_COUL_EWALD - SimdReal brsq_S0, brsq_S1, brsq_S2, brsq_S3; - SimdReal ewcorr_S0, ewcorr_S1, ewcorr_S2, ewcorr_S3; -#endif + SimdReal fsub_S0; + SimdReal fsub_S1; + SimdReal fsub_S2; + SimdReal fsub_S3; +# endif +# ifdef CALC_COUL_EWALD + SimdReal brsq_S0, brsq_S1, brsq_S2, brsq_S3; + SimdReal ewcorr_S0, ewcorr_S1, ewcorr_S2, ewcorr_S3; +# endif /* frcoul = (1/r - fsub)*r */ - SimdReal frcoul_S0; - SimdReal frcoul_S1; - SimdReal frcoul_S2; - SimdReal frcoul_S3; -#ifdef CALC_COUL_TAB + SimdReal frcoul_S0; + SimdReal frcoul_S1; + SimdReal frcoul_S2; + SimdReal frcoul_S3; +# ifdef CALC_COUL_TAB /* For tables: r, rs=r/sp, rf=floor(rs), frac=rs-rf */ - SimdReal rs_S0, rf_S0, frac_S0; - SimdReal rs_S1, rf_S1, frac_S1; - SimdReal rs_S2, rf_S2, frac_S2; - SimdReal rs_S3, rf_S3, frac_S3; + SimdReal rs_S0, rf_S0, frac_S0; + SimdReal rs_S1, rf_S1, frac_S1; + SimdReal rs_S2, rf_S2, frac_S2; + SimdReal rs_S3, rf_S3, frac_S3; /* Table index: rs truncated to an int */ - SimdInt32 ti_S0, ti_S1, ti_S2, ti_S3; + SimdInt32 ti_S0, ti_S1, ti_S2, ti_S3; /* Linear force table values */ - SimdReal ctab0_S0, ctab1_S0; - SimdReal ctab0_S1, ctab1_S1; - SimdReal ctab0_S2, ctab1_S2; - SimdReal ctab0_S3, ctab1_S3; -#ifdef CALC_ENERGIES + SimdReal ctab0_S0, ctab1_S0; + SimdReal ctab0_S1, ctab1_S1; + SimdReal ctab0_S2, ctab1_S2; + SimdReal ctab0_S3, ctab1_S3; +# ifdef CALC_ENERGIES /* Quadratic energy table value */ - SimdReal ctabv_S0, dum_S0; - SimdReal ctabv_S1, dum_S1; - SimdReal ctabv_S2, dum_S2; - SimdReal ctabv_S3, dum_S3; -#endif -#endif -#if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) + SimdReal ctabv_S0, dum_S0; + SimdReal ctabv_S1, dum_S1; + SimdReal ctabv_S2, dum_S2; + SimdReal ctabv_S3, dum_S3; +# endif +# endif +# if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) /* The potential (PME mesh) we need to subtract from 1/r */ - SimdReal vc_sub_S0; - SimdReal vc_sub_S1; - SimdReal vc_sub_S2; - SimdReal vc_sub_S3; -#endif -#ifdef CALC_ENERGIES + SimdReal vc_sub_S0; + SimdReal vc_sub_S1; + SimdReal vc_sub_S2; + SimdReal vc_sub_S3; +# endif +# ifdef CALC_ENERGIES /* Electrostatic potential */ - SimdReal vcoul_S0; - SimdReal vcoul_S1; - SimdReal vcoul_S2; - SimdReal vcoul_S3; -#endif -#endif + SimdReal vcoul_S0; + SimdReal vcoul_S1; + SimdReal vcoul_S2; + SimdReal vcoul_S3; +# endif +# endif /* The force times 1/r */ - SimdReal fscal_S0; - SimdReal fscal_S1; - SimdReal fscal_S2; - SimdReal fscal_S3; + SimdReal fscal_S0; + SimdReal fscal_S1; + SimdReal fscal_S2; + SimdReal fscal_S3; -#ifdef CALC_LJ -#ifdef LJ_COMB_LB +# ifdef CALC_LJ +# ifdef LJ_COMB_LB /* LJ sigma_j/2 and sqrt(epsilon_j) */ - SimdReal hsig_j_S, seps_j_S; + SimdReal hsig_j_S, seps_j_S; /* LJ sigma_ij and epsilon_ij */ - SimdReal sig_S0, eps_S0; - SimdReal sig_S1, eps_S1; -#ifndef HALF_LJ - SimdReal sig_S2, eps_S2; - SimdReal sig_S3, eps_S3; -#endif -#ifdef CALC_ENERGIES - SimdReal sig2_S0, sig6_S0; - SimdReal sig2_S1, sig6_S1; -#ifndef HALF_LJ - SimdReal sig2_S2, sig6_S2; - SimdReal sig2_S3, sig6_S3; -#endif -#endif /* LJ_COMB_LB */ -#endif /* CALC_LJ */ - -#ifdef LJ_COMB_GEOM - SimdReal c6s_j_S, c12s_j_S; -#endif - -#if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM + SimdReal sig_S0, eps_S0; + SimdReal sig_S1, eps_S1; +# ifndef HALF_LJ + SimdReal sig_S2, eps_S2; + SimdReal sig_S3, eps_S3; +# endif +# ifdef CALC_ENERGIES + SimdReal sig2_S0, sig6_S0; + SimdReal sig2_S1, sig6_S1; +# ifndef HALF_LJ + SimdReal sig2_S2, sig6_S2; + SimdReal sig2_S3, sig6_S3; +# endif +# endif /* LJ_COMB_LB */ +# endif /* CALC_LJ */ + +# ifdef LJ_COMB_GEOM + SimdReal c6s_j_S, c12s_j_S; +# endif + +# if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM /* Index for loading LJ parameters, complicated when interleaving */ - int aj2; -#endif + int aj2; +# endif /* Intermediate variables for LJ calculation */ -#ifndef LJ_COMB_LB - SimdReal rinvsix_S0; - SimdReal rinvsix_S1; -#ifndef HALF_LJ - SimdReal rinvsix_S2; - SimdReal rinvsix_S3; -#endif -#endif -#ifdef LJ_COMB_LB - SimdReal sir_S0, sir2_S0, sir6_S0; - SimdReal sir_S1, sir2_S1, sir6_S1; -#ifndef HALF_LJ - SimdReal sir_S2, sir2_S2, sir6_S2; - SimdReal sir_S3, sir2_S3, sir6_S3; -#endif -#endif - - SimdReal FrLJ6_S0, FrLJ12_S0, frLJ_S0; - SimdReal FrLJ6_S1, FrLJ12_S1, frLJ_S1; -#ifndef HALF_LJ - SimdReal FrLJ6_S2, FrLJ12_S2, frLJ_S2; - SimdReal FrLJ6_S3, FrLJ12_S3, frLJ_S3; -#endif -#endif /* CALC_LJ */ +# ifndef LJ_COMB_LB + SimdReal rinvsix_S0; + SimdReal rinvsix_S1; +# ifndef HALF_LJ + SimdReal rinvsix_S2; + SimdReal rinvsix_S3; +# endif +# endif +# ifdef LJ_COMB_LB + SimdReal sir_S0, sir2_S0, sir6_S0; + SimdReal sir_S1, sir2_S1, sir6_S1; +# ifndef HALF_LJ + SimdReal sir_S2, sir2_S2, sir6_S2; + SimdReal sir_S3, sir2_S3, sir6_S3; +# endif +# endif + + SimdReal FrLJ6_S0, FrLJ12_S0, frLJ_S0; + SimdReal FrLJ6_S1, FrLJ12_S1, frLJ_S1; +# ifndef HALF_LJ + SimdReal FrLJ6_S2, FrLJ12_S2, frLJ_S2; + SimdReal FrLJ6_S3, FrLJ12_S3, frLJ_S3; +# endif +# endif /* CALC_LJ */ /* j-cluster index */ - cj = l_cj[cjind].cj; + cj = l_cj[cjind].cj; /* Atom indices (of the first atom in the cluster) */ - aj = cj*UNROLLJ; -#if defined CALC_LJ && (defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM) -#if UNROLLJ == STRIDE - aj2 = aj*2; -#else - aj2 = (cj>>1)*2*STRIDE + (cj & 1)*UNROLLJ; -#endif -#endif -#if UNROLLJ == STRIDE - ajx = aj*DIM; -#else - ajx = (cj>>1)*DIM*STRIDE + (cj & 1)*UNROLLJ; -#endif - ajy = ajx + STRIDE; - ajz = ajy + STRIDE; - -#ifdef CHECK_EXCLS - gmx_load_simd_4xn_interactions(static_cast(l_cj[cjind].excl), - filter_S0, filter_S1, - filter_S2, filter_S3, - nbat->simdMasks.interaction_array.data(), - &interact_S0, &interact_S1, - &interact_S2, &interact_S3); -#endif /* CHECK_EXCLS */ + aj = cj * UNROLLJ; +# if defined CALC_LJ && (defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM) +# if UNROLLJ == STRIDE + aj2 = aj * 2; +# else + aj2 = (cj >> 1) * 2 * STRIDE + (cj & 1) * UNROLLJ; +# endif +# endif +# if UNROLLJ == STRIDE + ajx = aj * DIM; +# else + ajx = (cj >> 1) * DIM * STRIDE + (cj & 1) * UNROLLJ; +# endif + ajy = ajx + STRIDE; + ajz = ajy + STRIDE; + +# ifdef CHECK_EXCLS + gmx_load_simd_4xn_interactions(static_cast(l_cj[cjind].excl), filter_S0, filter_S1, + filter_S2, filter_S3, nbat->simdMasks.interaction_array.data(), + &interact_S0, &interact_S1, &interact_S2, &interact_S3); +# endif /* CHECK_EXCLS */ /* load j atom coordinates */ - jx_S = load(x+ajx); - jy_S = load(x+ajy); - jz_S = load(x+ajz); + jx_S = load(x + ajx); + jy_S = load(x + ajy); + jz_S = load(x + ajz); /* Calculate distance */ - dx_S0 = ix_S0 - jx_S; - dy_S0 = iy_S0 - jy_S; - dz_S0 = iz_S0 - jz_S; - dx_S1 = ix_S1 - jx_S; - dy_S1 = iy_S1 - jy_S; - dz_S1 = iz_S1 - jz_S; - dx_S2 = ix_S2 - jx_S; - dy_S2 = iy_S2 - jy_S; - dz_S2 = iz_S2 - jz_S; - dx_S3 = ix_S3 - jx_S; - dy_S3 = iy_S3 - jy_S; - dz_S3 = iz_S3 - jz_S; + dx_S0 = ix_S0 - jx_S; + dy_S0 = iy_S0 - jy_S; + dz_S0 = iz_S0 - jz_S; + dx_S1 = ix_S1 - jx_S; + dy_S1 = iy_S1 - jy_S; + dz_S1 = iz_S1 - jz_S; + dx_S2 = ix_S2 - jx_S; + dy_S2 = iy_S2 - jy_S; + dz_S2 = iz_S2 - jz_S; + dx_S3 = ix_S3 - jx_S; + dy_S3 = iy_S3 - jy_S; + dz_S3 = iz_S3 - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); - rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); /* Do the cut-off check */ - wco_S0 = (rsq_S0 < rc2_S); - wco_S1 = (rsq_S1 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); - wco_S3 = (rsq_S3 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S1 = (rsq_S1 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); + wco_S3 = (rsq_S3 < rc2_S); -#ifdef CHECK_EXCLS -#ifdef EXCL_FORCES +# ifdef CHECK_EXCLS +# ifdef EXCL_FORCES /* Only remove the (sub-)diagonal to avoid double counting */ -#if UNROLLJ == UNROLLI +# if UNROLLJ == UNROLLI if (cj == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask_S0; - wco_S1 = wco_S1 && diagonal_mask_S1; - wco_S2 = wco_S2 && diagonal_mask_S2; - wco_S3 = wco_S3 && diagonal_mask_S3; + wco_S0 = wco_S0 && diagonal_mask_S0; + wco_S1 = wco_S1 && diagonal_mask_S1; + wco_S2 = wco_S2 && diagonal_mask_S2; + wco_S3 = wco_S3 && diagonal_mask_S3; } -#else -#if UNROLLJ < UNROLLI - if (cj == ci_sh*2) +# else +# if UNROLLJ < UNROLLI + if (cj == ci_sh * 2) { - wco_S0 = wco_S0 && diagonal_mask0_S0; - wco_S1 = wco_S1 && diagonal_mask0_S1; - wco_S2 = wco_S2 && diagonal_mask0_S2; - wco_S3 = wco_S3 && diagonal_mask0_S3; + wco_S0 = wco_S0 && diagonal_mask0_S0; + wco_S1 = wco_S1 && diagonal_mask0_S1; + wco_S2 = wco_S2 && diagonal_mask0_S2; + wco_S3 = wco_S3 && diagonal_mask0_S3; } - if (cj == ci_sh*2 + 1) + if (cj == ci_sh * 2 + 1) { - wco_S0 = wco_S0 && diagonal_mask1_S0; - wco_S1 = wco_S1 && diagonal_mask1_S1; - wco_S2 = wco_S2 && diagonal_mask1_S2; - wco_S3 = wco_S3 && diagonal_mask1_S3; + wco_S0 = wco_S0 && diagonal_mask1_S0; + wco_S1 = wco_S1 && diagonal_mask1_S1; + wco_S2 = wco_S2 && diagonal_mask1_S2; + wco_S3 = wco_S3 && diagonal_mask1_S3; } -#else - if (cj*2 == ci_sh) +# else + if (cj * 2 == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask0_S0; - wco_S1 = wco_S1 && diagonal_mask0_S1; - wco_S2 = wco_S2 && diagonal_mask0_S2; - wco_S3 = wco_S3 && diagonal_mask0_S3; + wco_S0 = wco_S0 && diagonal_mask0_S0; + wco_S1 = wco_S1 && diagonal_mask0_S1; + wco_S2 = wco_S2 && diagonal_mask0_S2; + wco_S3 = wco_S3 && diagonal_mask0_S3; } - else if (cj*2 + 1 == ci_sh) + else if (cj * 2 + 1 == ci_sh) { - wco_S0 = wco_S0 && diagonal_mask1_S0; - wco_S1 = wco_S1 && diagonal_mask1_S1; - wco_S2 = wco_S2 && diagonal_mask1_S2; - wco_S3 = wco_S3 && diagonal_mask1_S3; + wco_S0 = wco_S0 && diagonal_mask1_S0; + wco_S1 = wco_S1 && diagonal_mask1_S1; + wco_S2 = wco_S2 && diagonal_mask1_S2; + wco_S3 = wco_S3 && diagonal_mask1_S3; } -#endif -#endif -#else /* EXCL_FORCES */ - /* No exclusion forces: remove all excluded atom pairs from the list */ - wco_S0 = wco_S0 && interact_S0; - wco_S1 = wco_S1 && interact_S1; - wco_S2 = wco_S2 && interact_S2; - wco_S3 = wco_S3 && interact_S3; -#endif -#endif - -#ifdef COUNT_PAIRS +# endif +# endif +# else /* EXCL_FORCES */ + /* No exclusion forces: remove all excluded atom pairs from the list */ + wco_S0 = wco_S0 && interact_S0; + wco_S1 = wco_S1 && interact_S1; + wco_S2 = wco_S2 && interact_S2; + wco_S3 = wco_S3 && interact_S3; +# endif +# endif + +# ifdef COUNT_PAIRS { - int i, j; - alignas(GMX_SIMD_ALIGNMENT) real tmp[2*GMX_SIMD_REAL_WIDTH]; + int i, j; + alignas(GMX_SIMD_ALIGNMENT) real tmp[2 * GMX_SIMD_REAL_WIDTH]; for (i = 0; i < UNROLLI; i++) { @@ -377,210 +374,210 @@ } } } -#endif +# endif // Ensure the distances do not fall below the limit where r^-12 overflows. // This should never happen for normal interactions. - rsq_S0 = max(rsq_S0, minRsq_S); - rsq_S1 = max(rsq_S1, minRsq_S); - rsq_S2 = max(rsq_S2, minRsq_S); - rsq_S3 = max(rsq_S3, minRsq_S); + rsq_S0 = max(rsq_S0, minRsq_S); + rsq_S1 = max(rsq_S1, minRsq_S); + rsq_S2 = max(rsq_S2, minRsq_S); + rsq_S3 = max(rsq_S3, minRsq_S); /* Calculate 1/r */ -#if !GMX_DOUBLE - rinv_S0 = invsqrt(rsq_S0); - rinv_S1 = invsqrt(rsq_S1); - rinv_S2 = invsqrt(rsq_S2); - rinv_S3 = invsqrt(rsq_S3); -#else +# if !GMX_DOUBLE + rinv_S0 = invsqrt(rsq_S0); + rinv_S1 = invsqrt(rsq_S1); + rinv_S2 = invsqrt(rsq_S2); + rinv_S3 = invsqrt(rsq_S3); +# else invsqrtPair(rsq_S0, rsq_S1, &rinv_S0, &rinv_S1); invsqrtPair(rsq_S2, rsq_S3, &rinv_S2, &rinv_S3); -#endif +# endif -#ifdef CALC_COULOMB +# ifdef CALC_COULOMB /* Load parameters for j atom */ - jq_S = load(q+aj); - qq_S0 = iq_S0 * jq_S; - qq_S1 = iq_S1 * jq_S; - qq_S2 = iq_S2 * jq_S; - qq_S3 = iq_S3 * jq_S; -#endif - -#ifdef CALC_LJ -#if !defined LJ_COMB_GEOM && !defined LJ_COMB_LB && !defined FIX_LJ_C + jq_S = load(q + aj); + qq_S0 = iq_S0 * jq_S; + qq_S1 = iq_S1 * jq_S; + qq_S2 = iq_S2 * jq_S; + qq_S3 = iq_S3 * jq_S; +# endif + +# ifdef CALC_LJ +# if !defined LJ_COMB_GEOM && !defined LJ_COMB_LB && !defined FIX_LJ_C SimdReal c6_S0, c6_S1, c12_S0, c12_S1; - gatherLoadTranspose(nbfp0, type+aj, &c6_S0, &c12_S0); - gatherLoadTranspose(nbfp1, type+aj, &c6_S1, &c12_S1); -#ifndef HALF_LJ + gatherLoadTranspose(nbfp0, type + aj, &c6_S0, &c12_S0); + gatherLoadTranspose(nbfp1, type + aj, &c6_S1, &c12_S1); +# ifndef HALF_LJ SimdReal c6_S2, c6_S3, c12_S2, c12_S3; - gatherLoadTranspose(nbfp2, type+aj, &c6_S2, &c12_S2); - gatherLoadTranspose(nbfp3, type+aj, &c6_S3, &c12_S3); -#endif -#endif /* not defined any LJ rule */ - -#ifdef LJ_COMB_GEOM - c6s_j_S = load(ljc+aj2+0); - c12s_j_S = load(ljc+aj2+STRIDE); - SimdReal c6_S0 = c6s_S0 * c6s_j_S; - SimdReal c6_S1 = c6s_S1 * c6s_j_S; -#ifndef HALF_LJ - SimdReal c6_S2 = c6s_S2 * c6s_j_S; - SimdReal c6_S3 = c6s_S3 * c6s_j_S; -#endif + gatherLoadTranspose(nbfp2, type + aj, &c6_S2, &c12_S2); + gatherLoadTranspose(nbfp3, type + aj, &c6_S3, &c12_S3); +# endif +# endif /* not defined any LJ rule */ + +# ifdef LJ_COMB_GEOM + c6s_j_S = load(ljc + aj2 + 0); + c12s_j_S = load(ljc + aj2 + STRIDE); + SimdReal c6_S0 = c6s_S0 * c6s_j_S; + SimdReal c6_S1 = c6s_S1 * c6s_j_S; +# ifndef HALF_LJ + SimdReal c6_S2 = c6s_S2 * c6s_j_S; + SimdReal c6_S3 = c6s_S3 * c6s_j_S; +# endif SimdReal c12_S0 = c12s_S0 * c12s_j_S; SimdReal c12_S1 = c12s_S1 * c12s_j_S; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal c12_S2 = c12s_S2 * c12s_j_S; SimdReal c12_S3 = c12s_S3 * c12s_j_S; -#endif -#endif /* LJ_COMB_GEOM */ - -#ifdef LJ_COMB_LB - hsig_j_S = load(ljc+aj2+0); - seps_j_S = load(ljc+aj2+STRIDE); - - sig_S0 = hsig_i_S0 + hsig_j_S; - sig_S1 = hsig_i_S1 + hsig_j_S; - eps_S0 = seps_i_S0 * seps_j_S; - eps_S1 = seps_i_S1 * seps_j_S; -#ifndef HALF_LJ - sig_S2 = hsig_i_S2 + hsig_j_S; - sig_S3 = hsig_i_S3 + hsig_j_S; - eps_S2 = seps_i_S2 * seps_j_S; - eps_S3 = seps_i_S3 * seps_j_S; -#endif -#endif /* LJ_COMB_LB */ - -#endif /* CALC_LJ */ +# endif +# endif /* LJ_COMB_GEOM */ + +# ifdef LJ_COMB_LB + hsig_j_S = load(ljc + aj2 + 0); + seps_j_S = load(ljc + aj2 + STRIDE); + + sig_S0 = hsig_i_S0 + hsig_j_S; + sig_S1 = hsig_i_S1 + hsig_j_S; + eps_S0 = seps_i_S0 * seps_j_S; + eps_S1 = seps_i_S1 * seps_j_S; +# ifndef HALF_LJ + sig_S2 = hsig_i_S2 + hsig_j_S; + sig_S3 = hsig_i_S3 + hsig_j_S; + eps_S2 = seps_i_S2 * seps_j_S; + eps_S3 = seps_i_S3 * seps_j_S; +# endif +# endif /* LJ_COMB_LB */ + +# endif /* CALC_LJ */ /* Set rinv to zero for r beyond the cut-off */ - rinv_S0 = selectByMask(rinv_S0, wco_S0); - rinv_S1 = selectByMask(rinv_S1, wco_S1); - rinv_S2 = selectByMask(rinv_S2, wco_S2); - rinv_S3 = selectByMask(rinv_S3, wco_S3); + rinv_S0 = selectByMask(rinv_S0, wco_S0); + rinv_S1 = selectByMask(rinv_S1, wco_S1); + rinv_S2 = selectByMask(rinv_S2, wco_S2); + rinv_S3 = selectByMask(rinv_S3, wco_S3); - rinvsq_S0 = rinv_S0 * rinv_S0; - rinvsq_S1 = rinv_S1 * rinv_S1; - rinvsq_S2 = rinv_S2 * rinv_S2; - rinvsq_S3 = rinv_S3 * rinv_S3; + rinvsq_S0 = rinv_S0 * rinv_S0; + rinvsq_S1 = rinv_S1 * rinv_S1; + rinvsq_S2 = rinv_S2 * rinv_S2; + rinvsq_S3 = rinv_S3 * rinv_S3; -#ifdef CALC_COULOMB +# ifdef CALC_COULOMB /* Note that here we calculate force*r, not the usual force/r. * This allows avoiding masking the reaction-field contribution, * as frcoul is later multiplied by rinvsq which has been * masked with the cut-off check. */ -#ifdef EXCL_FORCES +# ifdef EXCL_FORCES /* Only add 1/r for non-excluded atom pairs */ - rinv_ex_S0 = selectByMask(rinv_S0, interact_S0); - rinv_ex_S1 = selectByMask(rinv_S1, interact_S1); - rinv_ex_S2 = selectByMask(rinv_S2, interact_S2); - rinv_ex_S3 = selectByMask(rinv_S3, interact_S3); -#else + rinv_ex_S0 = selectByMask(rinv_S0, interact_S0); + rinv_ex_S1 = selectByMask(rinv_S1, interact_S1); + rinv_ex_S2 = selectByMask(rinv_S2, interact_S2); + rinv_ex_S3 = selectByMask(rinv_S3, interact_S3); +# else /* No exclusion forces, we always need 1/r */ -#define rinv_ex_S0 rinv_S0 -#define rinv_ex_S1 rinv_S1 -#define rinv_ex_S2 rinv_S2 -#define rinv_ex_S3 rinv_S3 -#endif +# define rinv_ex_S0 rinv_S0 +# define rinv_ex_S1 rinv_S1 +# define rinv_ex_S2 rinv_S2 +# define rinv_ex_S3 rinv_S3 +# endif -#ifdef CALC_COUL_RF +# ifdef CALC_COUL_RF /* Electrostatic interactions */ - frcoul_S0 = qq_S0 * fma(rsq_S0, mrc_3_S, rinv_ex_S0); - frcoul_S1 = qq_S1 * fma(rsq_S1, mrc_3_S, rinv_ex_S1); - frcoul_S2 = qq_S2 * fma(rsq_S2, mrc_3_S, rinv_ex_S2); - frcoul_S3 = qq_S3 * fma(rsq_S3, mrc_3_S, rinv_ex_S3); - -#ifdef CALC_ENERGIES - vcoul_S0 = qq_S0 * (rinv_ex_S0 + fma(rsq_S0, hrc_3_S, moh_rc_S)); - vcoul_S1 = qq_S1 * (rinv_ex_S1 + fma(rsq_S1, hrc_3_S, moh_rc_S)); - vcoul_S2 = qq_S2 * (rinv_ex_S2 + fma(rsq_S2, hrc_3_S, moh_rc_S)); - vcoul_S3 = qq_S3 * (rinv_ex_S3 + fma(rsq_S3, hrc_3_S, moh_rc_S)); -#endif -#endif - -#ifdef CALC_COUL_EWALD + frcoul_S0 = qq_S0 * fma(rsq_S0, mrc_3_S, rinv_ex_S0); + frcoul_S1 = qq_S1 * fma(rsq_S1, mrc_3_S, rinv_ex_S1); + frcoul_S2 = qq_S2 * fma(rsq_S2, mrc_3_S, rinv_ex_S2); + frcoul_S3 = qq_S3 * fma(rsq_S3, mrc_3_S, rinv_ex_S3); + +# ifdef CALC_ENERGIES + vcoul_S0 = qq_S0 * (rinv_ex_S0 + fma(rsq_S0, hrc_3_S, moh_rc_S)); + vcoul_S1 = qq_S1 * (rinv_ex_S1 + fma(rsq_S1, hrc_3_S, moh_rc_S)); + vcoul_S2 = qq_S2 * (rinv_ex_S2 + fma(rsq_S2, hrc_3_S, moh_rc_S)); + vcoul_S3 = qq_S3 * (rinv_ex_S3 + fma(rsq_S3, hrc_3_S, moh_rc_S)); +# endif +# endif + +# ifdef CALC_COUL_EWALD /* We need to mask (or limit) rsq for the cut-off, * as large distances can cause an overflow in gmx_pmecorrF/V. */ - brsq_S0 = beta2_S * selectByMask(rsq_S0, wco_S0); - brsq_S1 = beta2_S * selectByMask(rsq_S1, wco_S1); - brsq_S2 = beta2_S * selectByMask(rsq_S2, wco_S2); - brsq_S3 = beta2_S * selectByMask(rsq_S3, wco_S3); - ewcorr_S0 = beta_S * pmeForceCorrection(brsq_S0); - ewcorr_S1 = beta_S * pmeForceCorrection(brsq_S1); - ewcorr_S2 = beta_S * pmeForceCorrection(brsq_S2); - ewcorr_S3 = beta_S * pmeForceCorrection(brsq_S3); - frcoul_S0 = qq_S0 * fma(ewcorr_S0, brsq_S0, rinv_ex_S0); - frcoul_S1 = qq_S1 * fma(ewcorr_S1, brsq_S1, rinv_ex_S1); - frcoul_S2 = qq_S2 * fma(ewcorr_S2, brsq_S2, rinv_ex_S2); - frcoul_S3 = qq_S3 * fma(ewcorr_S3, brsq_S3, rinv_ex_S3); - -#ifdef CALC_ENERGIES - vc_sub_S0 = beta_S * pmePotentialCorrection(brsq_S0); - vc_sub_S1 = beta_S * pmePotentialCorrection(brsq_S1); - vc_sub_S2 = beta_S * pmePotentialCorrection(brsq_S2); - vc_sub_S3 = beta_S * pmePotentialCorrection(brsq_S3); -#endif - -#endif /* CALC_COUL_EWALD */ - -#ifdef CALC_COUL_TAB + brsq_S0 = beta2_S * selectByMask(rsq_S0, wco_S0); + brsq_S1 = beta2_S * selectByMask(rsq_S1, wco_S1); + brsq_S2 = beta2_S * selectByMask(rsq_S2, wco_S2); + brsq_S3 = beta2_S * selectByMask(rsq_S3, wco_S3); + ewcorr_S0 = beta_S * pmeForceCorrection(brsq_S0); + ewcorr_S1 = beta_S * pmeForceCorrection(brsq_S1); + ewcorr_S2 = beta_S * pmeForceCorrection(brsq_S2); + ewcorr_S3 = beta_S * pmeForceCorrection(brsq_S3); + frcoul_S0 = qq_S0 * fma(ewcorr_S0, brsq_S0, rinv_ex_S0); + frcoul_S1 = qq_S1 * fma(ewcorr_S1, brsq_S1, rinv_ex_S1); + frcoul_S2 = qq_S2 * fma(ewcorr_S2, brsq_S2, rinv_ex_S2); + frcoul_S3 = qq_S3 * fma(ewcorr_S3, brsq_S3, rinv_ex_S3); + +# ifdef CALC_ENERGIES + vc_sub_S0 = beta_S * pmePotentialCorrection(brsq_S0); + vc_sub_S1 = beta_S * pmePotentialCorrection(brsq_S1); + vc_sub_S2 = beta_S * pmePotentialCorrection(brsq_S2); + vc_sub_S3 = beta_S * pmePotentialCorrection(brsq_S3); +# endif + +# endif /* CALC_COUL_EWALD */ + +# ifdef CALC_COUL_TAB /* Electrostatic interactions */ - r_S0 = rsq_S0 * rinv_S0; - r_S1 = rsq_S1 * rinv_S1; - r_S2 = rsq_S2 * rinv_S2; - r_S3 = rsq_S3 * rinv_S3; + r_S0 = rsq_S0 * rinv_S0; + r_S1 = rsq_S1 * rinv_S1; + r_S2 = rsq_S2 * rinv_S2; + r_S3 = rsq_S3 * rinv_S3; /* Convert r to scaled table units */ - rs_S0 = r_S0 * invtsp_S; - rs_S1 = r_S1 * invtsp_S; - rs_S2 = r_S2 * invtsp_S; - rs_S3 = r_S3 * invtsp_S; + rs_S0 = r_S0 * invtsp_S; + rs_S1 = r_S1 * invtsp_S; + rs_S2 = r_S2 * invtsp_S; + rs_S3 = r_S3 * invtsp_S; /* Truncate scaled r to an int */ - ti_S0 = cvttR2I(rs_S0); - ti_S1 = cvttR2I(rs_S1); - ti_S2 = cvttR2I(rs_S2); - ti_S3 = cvttR2I(rs_S3); + ti_S0 = cvttR2I(rs_S0); + ti_S1 = cvttR2I(rs_S1); + ti_S2 = cvttR2I(rs_S2); + ti_S3 = cvttR2I(rs_S3); - rf_S0 = trunc(rs_S0); - rf_S1 = trunc(rs_S1); - rf_S2 = trunc(rs_S2); - rf_S3 = trunc(rs_S3); + rf_S0 = trunc(rs_S0); + rf_S1 = trunc(rs_S1); + rf_S2 = trunc(rs_S2); + rf_S3 = trunc(rs_S3); - frac_S0 = rs_S0 - rf_S0; - frac_S1 = rs_S1 - rf_S1; - frac_S2 = rs_S2 - rf_S2; - frac_S3 = rs_S3 - rf_S3; + frac_S0 = rs_S0 - rf_S0; + frac_S1 = rs_S1 - rf_S1; + frac_S2 = rs_S2 - rf_S2; + frac_S3 = rs_S3 - rf_S3; /* Load and interpolate table forces and possibly energies. * Force and energy can be combined in one table, stride 4: FDV0 * or in two separate tables with stride 1: F and V * Currently single precision uses FDV0, double F and V. */ -#ifndef CALC_ENERGIES -#ifdef TAB_FDV0 +# ifndef CALC_ENERGIES +# ifdef TAB_FDV0 gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S1, &ctab0_S1, &ctab1_S1); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S3, &ctab0_S3, &ctab1_S3); -#else +# else gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S1, &ctab0_S1, &ctab1_S1); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S3, &ctab0_S3, &ctab1_S3); - ctab1_S0 = ctab1_S0 - ctab0_S0; - ctab1_S1 = ctab1_S1 - ctab0_S1; - ctab1_S2 = ctab1_S2 - ctab0_S2; - ctab1_S3 = ctab1_S3 - ctab0_S3; -#endif -#else -#ifdef TAB_FDV0 + ctab1_S0 = ctab1_S0 - ctab0_S0; + ctab1_S1 = ctab1_S1 - ctab0_S1; + ctab1_S2 = ctab1_S2 - ctab0_S2; + ctab1_S3 = ctab1_S3 - ctab0_S3; +# endif +# else +# ifdef TAB_FDV0 gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0, &ctabv_S0, &dum_S0); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S1, &ctab0_S1, &ctab1_S1, &ctabv_S1, &dum_S1); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S2, &ctab0_S2, &ctab1_S2, &ctabv_S2, &dum_S2); gatherLoadBySimdIntTranspose<4>(tab_coul_F, ti_S3, &ctab0_S3, &ctab1_S3, &ctabv_S3, &dum_S3); -#else +# else gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S0, &ctab0_S0, &ctab1_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_V, ti_S0, &ctabv_S0, &dum_S0); gatherLoadUBySimdIntTranspose<1>(tab_coul_F, ti_S1, &ctab0_S1, &ctab1_S1); @@ -593,600 +590,624 @@ ctab1_S1 = ctab1_S1 - ctab0_S1; ctab1_S2 = ctab1_S2 - ctab0_S2; ctab1_S3 = ctab1_S3 - ctab0_S3; -#endif -#endif - fsub_S0 = fma(frac_S0, ctab1_S0, ctab0_S0); - fsub_S1 = fma(frac_S1, ctab1_S1, ctab0_S1); - fsub_S2 = fma(frac_S2, ctab1_S2, ctab0_S2); - fsub_S3 = fma(frac_S3, ctab1_S3, ctab0_S3); - frcoul_S0 = qq_S0 * fnma(fsub_S0, r_S0, rinv_ex_S0); - frcoul_S1 = qq_S1 * fnma(fsub_S1, r_S1, rinv_ex_S1); - frcoul_S2 = qq_S2 * fnma(fsub_S2, r_S2, rinv_ex_S2); - frcoul_S3 = qq_S3 * fnma(fsub_S3, r_S3, rinv_ex_S3); - -#ifdef CALC_ENERGIES - vc_sub_S0 = fma((mhalfsp_S * frac_S0), (ctab0_S0 + fsub_S0), ctabv_S0); - vc_sub_S1 = fma((mhalfsp_S * frac_S1), (ctab0_S1 + fsub_S1), ctabv_S1); - vc_sub_S2 = fma((mhalfsp_S * frac_S2), (ctab0_S2 + fsub_S2), ctabv_S2); - vc_sub_S3 = fma((mhalfsp_S * frac_S3), (ctab0_S3 + fsub_S3), ctabv_S3); -#endif -#endif /* CALC_COUL_TAB */ - -#if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) -#ifndef NO_SHIFT_EWALD +# endif +# endif + fsub_S0 = fma(frac_S0, ctab1_S0, ctab0_S0); + fsub_S1 = fma(frac_S1, ctab1_S1, ctab0_S1); + fsub_S2 = fma(frac_S2, ctab1_S2, ctab0_S2); + fsub_S3 = fma(frac_S3, ctab1_S3, ctab0_S3); + frcoul_S0 = qq_S0 * fnma(fsub_S0, r_S0, rinv_ex_S0); + frcoul_S1 = qq_S1 * fnma(fsub_S1, r_S1, rinv_ex_S1); + frcoul_S2 = qq_S2 * fnma(fsub_S2, r_S2, rinv_ex_S2); + frcoul_S3 = qq_S3 * fnma(fsub_S3, r_S3, rinv_ex_S3); + +# ifdef CALC_ENERGIES + vc_sub_S0 = fma((mhalfsp_S * frac_S0), (ctab0_S0 + fsub_S0), ctabv_S0); + vc_sub_S1 = fma((mhalfsp_S * frac_S1), (ctab0_S1 + fsub_S1), ctabv_S1); + vc_sub_S2 = fma((mhalfsp_S * frac_S2), (ctab0_S2 + fsub_S2), ctabv_S2); + vc_sub_S3 = fma((mhalfsp_S * frac_S3), (ctab0_S3 + fsub_S3), ctabv_S3); +# endif +# endif /* CALC_COUL_TAB */ + +# if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) +# ifndef NO_SHIFT_EWALD /* Add Ewald potential shift to vc_sub for convenience */ -#ifdef CHECK_EXCLS - vc_sub_S0 = vc_sub_S0 + selectByMask(sh_ewald_S, interact_S0); - vc_sub_S1 = vc_sub_S1 + selectByMask(sh_ewald_S, interact_S1); - vc_sub_S2 = vc_sub_S2 + selectByMask(sh_ewald_S, interact_S2); - vc_sub_S3 = vc_sub_S3 + selectByMask(sh_ewald_S, interact_S3); -#else - vc_sub_S0 = vc_sub_S0 + sh_ewald_S; - vc_sub_S1 = vc_sub_S1 + sh_ewald_S; - vc_sub_S2 = vc_sub_S2 + sh_ewald_S; - vc_sub_S3 = vc_sub_S3 + sh_ewald_S; -#endif -#endif - - vcoul_S0 = qq_S0 * (rinv_ex_S0 - vc_sub_S0); - vcoul_S1 = qq_S1 * (rinv_ex_S1 - vc_sub_S1); - vcoul_S2 = qq_S2 * (rinv_ex_S2 - vc_sub_S2); - vcoul_S3 = qq_S3 * (rinv_ex_S3 - vc_sub_S3); - -#endif - -#ifdef CALC_ENERGIES +# ifdef CHECK_EXCLS + vc_sub_S0 = vc_sub_S0 + selectByMask(sh_ewald_S, interact_S0); + vc_sub_S1 = vc_sub_S1 + selectByMask(sh_ewald_S, interact_S1); + vc_sub_S2 = vc_sub_S2 + selectByMask(sh_ewald_S, interact_S2); + vc_sub_S3 = vc_sub_S3 + selectByMask(sh_ewald_S, interact_S3); +# else + vc_sub_S0 = vc_sub_S0 + sh_ewald_S; + vc_sub_S1 = vc_sub_S1 + sh_ewald_S; + vc_sub_S2 = vc_sub_S2 + sh_ewald_S; + vc_sub_S3 = vc_sub_S3 + sh_ewald_S; +# endif +# endif + + vcoul_S0 = qq_S0 * (rinv_ex_S0 - vc_sub_S0); + vcoul_S1 = qq_S1 * (rinv_ex_S1 - vc_sub_S1); + vcoul_S2 = qq_S2 * (rinv_ex_S2 - vc_sub_S2); + vcoul_S3 = qq_S3 * (rinv_ex_S3 - vc_sub_S3); + +# endif + +# ifdef CALC_ENERGIES /* Mask energy for cut-off and diagonal */ - vcoul_S0 = selectByMask(vcoul_S0, wco_S0); - vcoul_S1 = selectByMask(vcoul_S1, wco_S1); - vcoul_S2 = selectByMask(vcoul_S2, wco_S2); - vcoul_S3 = selectByMask(vcoul_S3, wco_S3); -#endif + vcoul_S0 = selectByMask(vcoul_S0, wco_S0); + vcoul_S1 = selectByMask(vcoul_S1, wco_S1); + vcoul_S2 = selectByMask(vcoul_S2, wco_S2); + vcoul_S3 = selectByMask(vcoul_S3, wco_S3); +# endif -#endif /* CALC_COULOMB */ +# endif /* CALC_COULOMB */ -#ifdef CALC_LJ +# ifdef CALC_LJ /* Lennard-Jones interaction */ -#ifdef VDW_CUTOFF_CHECK - wco_vdw_S0 = (rsq_S0 < rcvdw2_S); - wco_vdw_S1 = (rsq_S1 < rcvdw2_S); -#ifndef HALF_LJ - wco_vdw_S2 = (rsq_S2 < rcvdw2_S); - wco_vdw_S3 = (rsq_S3 < rcvdw2_S); -#endif -#else +# ifdef VDW_CUTOFF_CHECK + wco_vdw_S0 = (rsq_S0 < rcvdw2_S); + wco_vdw_S1 = (rsq_S1 < rcvdw2_S); +# ifndef HALF_LJ + wco_vdw_S2 = (rsq_S2 < rcvdw2_S); + wco_vdw_S3 = (rsq_S3 < rcvdw2_S); +# endif +# else /* Same cut-off for Coulomb and VdW, reuse the registers */ -#define wco_vdw_S0 wco_S0 -#define wco_vdw_S1 wco_S1 -#define wco_vdw_S2 wco_S2 -#define wco_vdw_S3 wco_S3 -#endif - -#ifndef LJ_COMB_LB - rinvsix_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; - rinvsix_S1 = rinvsq_S1 * rinvsq_S1 * rinvsq_S1; -#ifdef EXCL_FORCES - rinvsix_S0 = selectByMask(rinvsix_S0, interact_S0); - rinvsix_S1 = selectByMask(rinvsix_S1, interact_S1); -#endif -#ifndef HALF_LJ - rinvsix_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; - rinvsix_S3 = rinvsq_S3 * rinvsq_S3 * rinvsq_S3; -#ifdef EXCL_FORCES - rinvsix_S2 = selectByMask(rinvsix_S2, interact_S2); - rinvsix_S3 = selectByMask(rinvsix_S3, interact_S3); -#endif -#endif - -#if defined LJ_CUT || defined LJ_POT_SWITCH +# define wco_vdw_S0 wco_S0 +# define wco_vdw_S1 wco_S1 +# define wco_vdw_S2 wco_S2 +# define wco_vdw_S3 wco_S3 +# endif + +# ifndef LJ_COMB_LB + rinvsix_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; + rinvsix_S1 = rinvsq_S1 * rinvsq_S1 * rinvsq_S1; +# ifdef EXCL_FORCES + rinvsix_S0 = selectByMask(rinvsix_S0, interact_S0); + rinvsix_S1 = selectByMask(rinvsix_S1, interact_S1); +# endif +# ifndef HALF_LJ + rinvsix_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; + rinvsix_S3 = rinvsq_S3 * rinvsq_S3 * rinvsq_S3; +# ifdef EXCL_FORCES + rinvsix_S2 = selectByMask(rinvsix_S2, interact_S2); + rinvsix_S3 = selectByMask(rinvsix_S3, interact_S3); +# endif +# endif + +# if defined LJ_CUT || defined LJ_POT_SWITCH /* We have plain LJ or LJ-PME with simple C6/6 C12/12 coefficients */ - FrLJ6_S0 = c6_S0 * rinvsix_S0; - FrLJ6_S1 = c6_S1 * rinvsix_S1; -#ifndef HALF_LJ - FrLJ6_S2 = c6_S2 * rinvsix_S2; - FrLJ6_S3 = c6_S3 * rinvsix_S3; -#endif - FrLJ12_S0 = c12_S0 * rinvsix_S0 * rinvsix_S0; - FrLJ12_S1 = c12_S1 * rinvsix_S1 * rinvsix_S1; -#ifndef HALF_LJ - FrLJ12_S2 = c12_S2 * rinvsix_S2 * rinvsix_S2; - FrLJ12_S3 = c12_S3 * rinvsix_S3 * rinvsix_S3; -#endif -#endif - -#if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH + FrLJ6_S0 = c6_S0 * rinvsix_S0; + FrLJ6_S1 = c6_S1 * rinvsix_S1; +# ifndef HALF_LJ + FrLJ6_S2 = c6_S2 * rinvsix_S2; + FrLJ6_S3 = c6_S3 * rinvsix_S3; +# endif + FrLJ12_S0 = c12_S0 * rinvsix_S0 * rinvsix_S0; + FrLJ12_S1 = c12_S1 * rinvsix_S1 * rinvsix_S1; +# ifndef HALF_LJ + FrLJ12_S2 = c12_S2 * rinvsix_S2 * rinvsix_S2; + FrLJ12_S3 = c12_S3 * rinvsix_S3 * rinvsix_S3; +# endif +# endif + +# if defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH /* We switch the LJ force */ - r_S0 = rsq_S0 * rinv_S0; - rsw_S0 = max(r_S0 - rswitch_S, zero_S); - rsw2_S0 = rsw_S0 * rsw_S0; - r_S1 = rsq_S1 * rinv_S1; - rsw_S1 = max(r_S1 - rswitch_S, zero_S); - rsw2_S1 = rsw_S1 * rsw_S1; -#ifndef HALF_LJ - r_S2 = rsq_S2 * rinv_S2; - rsw_S2 = max(r_S2 - rswitch_S, zero_S); - rsw2_S2 = rsw_S2 * rsw_S2; - r_S3 = rsq_S3 * rinv_S3; - rsw_S3 = max(r_S3 - rswitch_S, zero_S); - rsw2_S3 = rsw_S3 * rsw_S3; -#endif -#endif - -#ifdef LJ_FORCE_SWITCH - -#define gmx_add_fr_switch(fr, rsw, rsw2_r, c2, c3) fma(fma(c3, rsw, c2), rsw2_r, (fr)) + r_S0 = rsq_S0 * rinv_S0; + rsw_S0 = max(r_S0 - rswitch_S, zero_S); + rsw2_S0 = rsw_S0 * rsw_S0; + r_S1 = rsq_S1 * rinv_S1; + rsw_S1 = max(r_S1 - rswitch_S, zero_S); + rsw2_S1 = rsw_S1 * rsw_S1; +# ifndef HALF_LJ + r_S2 = rsq_S2 * rinv_S2; + rsw_S2 = max(r_S2 - rswitch_S, zero_S); + rsw2_S2 = rsw_S2 * rsw_S2; + r_S3 = rsq_S3 * rinv_S3; + rsw_S3 = max(r_S3 - rswitch_S, zero_S); + rsw2_S3 = rsw_S3 * rsw_S3; +# endif +# endif + +# ifdef LJ_FORCE_SWITCH + +# define gmx_add_fr_switch(fr, rsw, rsw2_r, c2, c3) \ + fma(fma(c3, rsw, c2), rsw2_r, (fr)) SimdReal rsw2_r_S0 = rsw2_S0 * r_S0; SimdReal rsw2_r_S1 = rsw2_S1 * r_S1; - FrLJ6_S0 = c6_S0 * gmx_add_fr_switch(rinvsix_S0, rsw_S0, rsw2_r_S0, p6_fc2_S, p6_fc3_S); - FrLJ6_S1 = c6_S1 * gmx_add_fr_switch(rinvsix_S1, rsw_S1, rsw2_r_S1, p6_fc2_S, p6_fc3_S); -#ifndef HALF_LJ + FrLJ6_S0 = c6_S0 * gmx_add_fr_switch(rinvsix_S0, rsw_S0, rsw2_r_S0, p6_fc2_S, p6_fc3_S); + FrLJ6_S1 = c6_S1 * gmx_add_fr_switch(rinvsix_S1, rsw_S1, rsw2_r_S1, p6_fc2_S, p6_fc3_S); +# ifndef HALF_LJ SimdReal rsw2_r_S2 = rsw2_S2 * r_S2; SimdReal rsw2_r_S3 = rsw2_S3 * r_S3; - FrLJ6_S2 = c6_S2 * gmx_add_fr_switch(rinvsix_S2, rsw_S2, rsw2_r_S2, p6_fc2_S, p6_fc3_S); - FrLJ6_S3 = c6_S3 * gmx_add_fr_switch(rinvsix_S3, rsw_S3, rsw2_r_S3, p6_fc2_S, p6_fc3_S); -#endif - FrLJ12_S0 = c12_S0 * gmx_add_fr_switch((rinvsix_S0 * rinvsix_S0), rsw_S0, rsw2_r_S0, p12_fc2_S, p12_fc3_S); - FrLJ12_S1 = c12_S1 * gmx_add_fr_switch((rinvsix_S1 * rinvsix_S1), rsw_S1, rsw2_r_S1, p12_fc2_S, p12_fc3_S); -#ifndef HALF_LJ - FrLJ12_S2 = c12_S2 * gmx_add_fr_switch((rinvsix_S2 * rinvsix_S2), rsw_S2, rsw2_r_S2, p12_fc2_S, p12_fc3_S); - FrLJ12_S3 = c12_S3 * gmx_add_fr_switch((rinvsix_S3 * rinvsix_S3), rsw_S3, rsw2_r_S3, p12_fc2_S, p12_fc3_S); -#endif -#undef gmx_add_fr_switch -#endif /* LJ_FORCE_SWITCH */ - -#endif /* not LJ_COMB_LB */ - -#ifdef LJ_COMB_LB - sir_S0 = sig_S0 * rinv_S0; - sir_S1 = sig_S1 * rinv_S1; -#ifndef HALF_LJ - sir_S2 = sig_S2 * rinv_S2; - sir_S3 = sig_S3 * rinv_S3; -#endif - sir2_S0 = sir_S0 * sir_S0; - sir2_S1 = sir_S1 * sir_S1; -#ifndef HALF_LJ - sir2_S2 = sir_S2 * sir_S2; - sir2_S3 = sir_S3 * sir_S3; -#endif - sir6_S0 = sir2_S0 * sir2_S0 * sir2_S0; - sir6_S1 = sir2_S1 * sir2_S1 * sir2_S1; -#ifdef EXCL_FORCES - sir6_S0 = selectByMask(sir6_S0, interact_S0); - sir6_S1 = selectByMask(sir6_S1, interact_S1); -#endif -#ifndef HALF_LJ - sir6_S2 = sir2_S2 * sir2_S2 * sir2_S2; - sir6_S3 = sir2_S3 * sir2_S3 * sir2_S3; -#ifdef EXCL_FORCES - sir6_S2 = selectByMask(sir6_S2, interact_S2); - sir6_S3 = selectByMask(sir6_S3, interact_S3); -#endif -#endif -#ifdef VDW_CUTOFF_CHECK - sir6_S0 = selectByMask(sir6_S0, wco_vdw_S0); - sir6_S1 = selectByMask(sir6_S1, wco_vdw_S1); -#ifndef HALF_LJ - sir6_S2 = selectByMask(sir6_S2, wco_vdw_S2); - sir6_S3 = selectByMask(sir6_S3, wco_vdw_S3); -#endif -#endif - FrLJ6_S0 = eps_S0 * sir6_S0; - FrLJ6_S1 = eps_S1 * sir6_S1; -#ifndef HALF_LJ - FrLJ6_S2 = eps_S2 * sir6_S2; - FrLJ6_S3 = eps_S3 * sir6_S3; -#endif - FrLJ12_S0 = FrLJ6_S0 * sir6_S0; - FrLJ12_S1 = FrLJ6_S1 * sir6_S1; -#ifndef HALF_LJ - FrLJ12_S2 = FrLJ6_S2 * sir6_S2; - FrLJ12_S3 = FrLJ6_S3 * sir6_S3; -#endif -#if defined CALC_ENERGIES + FrLJ6_S2 = c6_S2 * gmx_add_fr_switch(rinvsix_S2, rsw_S2, rsw2_r_S2, p6_fc2_S, p6_fc3_S); + FrLJ6_S3 = c6_S3 * gmx_add_fr_switch(rinvsix_S3, rsw_S3, rsw2_r_S3, p6_fc2_S, p6_fc3_S); +# endif + FrLJ12_S0 = c12_S0 * gmx_add_fr_switch((rinvsix_S0 * rinvsix_S0), rsw_S0, rsw2_r_S0, p12_fc2_S, p12_fc3_S); + FrLJ12_S1 = c12_S1 * gmx_add_fr_switch((rinvsix_S1 * rinvsix_S1), rsw_S1, rsw2_r_S1, p12_fc2_S, p12_fc3_S); +# ifndef HALF_LJ + FrLJ12_S2 = c12_S2 * gmx_add_fr_switch((rinvsix_S2 * rinvsix_S2), rsw_S2, rsw2_r_S2, p12_fc2_S, p12_fc3_S); + FrLJ12_S3 = c12_S3 * gmx_add_fr_switch((rinvsix_S3 * rinvsix_S3), rsw_S3, rsw2_r_S3, p12_fc2_S, p12_fc3_S); +# endif +# undef gmx_add_fr_switch +# endif /* LJ_FORCE_SWITCH */ + +# endif /* not LJ_COMB_LB */ + +# ifdef LJ_COMB_LB + sir_S0 = sig_S0 * rinv_S0; + sir_S1 = sig_S1 * rinv_S1; +# ifndef HALF_LJ + sir_S2 = sig_S2 * rinv_S2; + sir_S3 = sig_S3 * rinv_S3; +# endif + sir2_S0 = sir_S0 * sir_S0; + sir2_S1 = sir_S1 * sir_S1; +# ifndef HALF_LJ + sir2_S2 = sir_S2 * sir_S2; + sir2_S3 = sir_S3 * sir_S3; +# endif + sir6_S0 = sir2_S0 * sir2_S0 * sir2_S0; + sir6_S1 = sir2_S1 * sir2_S1 * sir2_S1; +# ifdef EXCL_FORCES + sir6_S0 = selectByMask(sir6_S0, interact_S0); + sir6_S1 = selectByMask(sir6_S1, interact_S1); +# endif +# ifndef HALF_LJ + sir6_S2 = sir2_S2 * sir2_S2 * sir2_S2; + sir6_S3 = sir2_S3 * sir2_S3 * sir2_S3; +# ifdef EXCL_FORCES + sir6_S2 = selectByMask(sir6_S2, interact_S2); + sir6_S3 = selectByMask(sir6_S3, interact_S3); +# endif +# endif +# ifdef VDW_CUTOFF_CHECK + sir6_S0 = selectByMask(sir6_S0, wco_vdw_S0); + sir6_S1 = selectByMask(sir6_S1, wco_vdw_S1); +# ifndef HALF_LJ + sir6_S2 = selectByMask(sir6_S2, wco_vdw_S2); + sir6_S3 = selectByMask(sir6_S3, wco_vdw_S3); +# endif +# endif + FrLJ6_S0 = eps_S0 * sir6_S0; + FrLJ6_S1 = eps_S1 * sir6_S1; +# ifndef HALF_LJ + FrLJ6_S2 = eps_S2 * sir6_S2; + FrLJ6_S3 = eps_S3 * sir6_S3; +# endif + FrLJ12_S0 = FrLJ6_S0 * sir6_S0; + FrLJ12_S1 = FrLJ6_S1 * sir6_S1; +# ifndef HALF_LJ + FrLJ12_S2 = FrLJ6_S2 * sir6_S2; + FrLJ12_S3 = FrLJ6_S3 * sir6_S3; +# endif +# if defined CALC_ENERGIES /* We need C6 and C12 to calculate the LJ potential shift */ - sig2_S0 = sig_S0 * sig_S0; - sig2_S1 = sig_S1 * sig_S1; -#ifndef HALF_LJ - sig2_S2 = sig_S2 * sig_S2; - sig2_S3 = sig_S3 * sig_S3; -#endif - sig6_S0 = sig2_S0 * sig2_S0 * sig2_S0; - sig6_S1 = sig2_S1 * sig2_S1 * sig2_S1; -#ifndef HALF_LJ - sig6_S2 = sig2_S2 * sig2_S2 * sig2_S2; - sig6_S3 = sig2_S3 * sig2_S3 * sig2_S3; -#endif - SimdReal c6_S0 = eps_S0 * sig6_S0; - SimdReal c6_S1 = eps_S1 * sig6_S1; -#ifndef HALF_LJ - SimdReal c6_S2 = eps_S2 * sig6_S2; - SimdReal c6_S3 = eps_S3 * sig6_S3; -#endif + sig2_S0 = sig_S0 * sig_S0; + sig2_S1 = sig_S1 * sig_S1; +# ifndef HALF_LJ + sig2_S2 = sig_S2 * sig_S2; + sig2_S3 = sig_S3 * sig_S3; +# endif + sig6_S0 = sig2_S0 * sig2_S0 * sig2_S0; + sig6_S1 = sig2_S1 * sig2_S1 * sig2_S1; +# ifndef HALF_LJ + sig6_S2 = sig2_S2 * sig2_S2 * sig2_S2; + sig6_S3 = sig2_S3 * sig2_S3 * sig2_S3; +# endif + SimdReal c6_S0 = eps_S0 * sig6_S0; + SimdReal c6_S1 = eps_S1 * sig6_S1; +# ifndef HALF_LJ + SimdReal c6_S2 = eps_S2 * sig6_S2; + SimdReal c6_S3 = eps_S3 * sig6_S3; +# endif SimdReal c12_S0 = c6_S0 * sig6_S0; SimdReal c12_S1 = c6_S1 * sig6_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal c12_S2 = c6_S2 * sig6_S2; SimdReal c12_S3 = c6_S3 * sig6_S3; -#endif -#endif -#endif /* LJ_COMB_LB */ +# endif +# endif +# endif /* LJ_COMB_LB */ /* Determine the total scalar LJ force*r */ - frLJ_S0 = FrLJ12_S0 - FrLJ6_S0; - frLJ_S1 = FrLJ12_S1 - FrLJ6_S1; -#ifndef HALF_LJ - frLJ_S2 = FrLJ12_S2 - FrLJ6_S2; - frLJ_S3 = FrLJ12_S3 - FrLJ6_S3; -#endif + frLJ_S0 = FrLJ12_S0 - FrLJ6_S0; + frLJ_S1 = FrLJ12_S1 - FrLJ6_S1; +# ifndef HALF_LJ + frLJ_S2 = FrLJ12_S2 - FrLJ6_S2; + frLJ_S3 = FrLJ12_S3 - FrLJ6_S3; +# endif -#if (defined LJ_CUT || defined LJ_FORCE_SWITCH) && defined CALC_ENERGIES +# if (defined LJ_CUT || defined LJ_FORCE_SWITCH) && defined CALC_ENERGIES -#ifdef LJ_CUT +# ifdef LJ_CUT /* Calculate the LJ energies, with constant potential shift */ - SimdReal VLJ6_S0 = sixth_S * fma(c6_S0, p6_cpot_S, FrLJ6_S0); - SimdReal VLJ6_S1 = sixth_S * fma(c6_S1, p6_cpot_S, FrLJ6_S1); -#ifndef HALF_LJ - SimdReal VLJ6_S2 = sixth_S * fma(c6_S2, p6_cpot_S, FrLJ6_S2); - SimdReal VLJ6_S3 = sixth_S * fma(c6_S3, p6_cpot_S, FrLJ6_S3); -#endif + SimdReal VLJ6_S0 = sixth_S * fma(c6_S0, p6_cpot_S, FrLJ6_S0); + SimdReal VLJ6_S1 = sixth_S * fma(c6_S1, p6_cpot_S, FrLJ6_S1); +# ifndef HALF_LJ + SimdReal VLJ6_S2 = sixth_S * fma(c6_S2, p6_cpot_S, FrLJ6_S2); + SimdReal VLJ6_S3 = sixth_S * fma(c6_S3, p6_cpot_S, FrLJ6_S3); +# endif SimdReal VLJ12_S0 = twelveth_S * fma(c12_S0, p12_cpot_S, FrLJ12_S0); SimdReal VLJ12_S1 = twelveth_S * fma(c12_S1, p12_cpot_S, FrLJ12_S1); -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal VLJ12_S2 = twelveth_S * fma(c12_S2, p12_cpot_S, FrLJ12_S2); SimdReal VLJ12_S3 = twelveth_S * fma(c12_S3, p12_cpot_S, FrLJ12_S3); -#endif -#endif /* LJ_CUT */ - -#ifdef LJ_FORCE_SWITCH -#define v_fswitch_r(rsw, rsw2, c0, c3, c4) fma(fma((c4), (rsw), (c3)), ((rsw2) * (rsw)), (c0)) - - SimdReal VLJ6_S0 = c6_S0 * fma(sixth_S, rinvsix_S0, v_fswitch_r(rsw_S0, rsw2_S0, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); - SimdReal VLJ6_S1 = c6_S1 * fma(sixth_S, rinvsix_S1, v_fswitch_r(rsw_S1, rsw2_S1, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); -#ifndef HALF_LJ - SimdReal VLJ6_S2 = c6_S2 * fma(sixth_S, rinvsix_S2, v_fswitch_r(rsw_S2, rsw2_S2, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); - SimdReal VLJ6_S3 = c6_S3 * fma(sixth_S, rinvsix_S3, v_fswitch_r(rsw_S3, rsw2_S3, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); -#endif - SimdReal VLJ12_S0 = c12_S0 * fma(twelveth_S, rinvsix_S0 * rinvsix_S0, v_fswitch_r(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); - SimdReal VLJ12_S1 = c12_S1 * fma(twelveth_S, rinvsix_S1 * rinvsix_S1, v_fswitch_r(rsw_S1, rsw2_S1, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); -#ifndef HALF_LJ - SimdReal VLJ12_S2 = c12_S2 * fma(twelveth_S, rinvsix_S2 * rinvsix_S2, v_fswitch_r(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); - SimdReal VLJ12_S3 = c12_S3 * fma(twelveth_S, rinvsix_S3 * rinvsix_S3, v_fswitch_r(rsw_S3, rsw2_S3, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); -#endif -#undef v_fswitch_r -#endif /* LJ_FORCE_SWITCH */ +# endif +# endif /* LJ_CUT */ + +# ifdef LJ_FORCE_SWITCH +# define v_fswitch_r(rsw, rsw2, c0, c3, c4) \ + fma(fma((c4), (rsw), (c3)), ((rsw2) * (rsw)), (c0)) + + SimdReal VLJ6_S0 = + c6_S0 * fma(sixth_S, rinvsix_S0, v_fswitch_r(rsw_S0, rsw2_S0, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); + SimdReal VLJ6_S1 = + c6_S1 * fma(sixth_S, rinvsix_S1, v_fswitch_r(rsw_S1, rsw2_S1, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); +# ifndef HALF_LJ + SimdReal VLJ6_S2 = + c6_S2 * fma(sixth_S, rinvsix_S2, v_fswitch_r(rsw_S2, rsw2_S2, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); + SimdReal VLJ6_S3 = + c6_S3 * fma(sixth_S, rinvsix_S3, v_fswitch_r(rsw_S3, rsw2_S3, p6_6cpot_S, p6_vc3_S, p6_vc4_S)); +# endif + SimdReal VLJ12_S0 = c12_S0 + * fma(twelveth_S, rinvsix_S0 * rinvsix_S0, + v_fswitch_r(rsw_S0, rsw2_S0, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); + SimdReal VLJ12_S1 = c12_S1 + * fma(twelveth_S, rinvsix_S1 * rinvsix_S1, + v_fswitch_r(rsw_S1, rsw2_S1, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); +# ifndef HALF_LJ + SimdReal VLJ12_S2 = c12_S2 + * fma(twelveth_S, rinvsix_S2 * rinvsix_S2, + v_fswitch_r(rsw_S2, rsw2_S2, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); + SimdReal VLJ12_S3 = c12_S3 + * fma(twelveth_S, rinvsix_S3 * rinvsix_S3, + v_fswitch_r(rsw_S3, rsw2_S3, p12_12cpot_S, p12_vc3_S, p12_vc4_S)); +# endif +# undef v_fswitch_r +# endif /* LJ_FORCE_SWITCH */ /* Add up the repulsion and dispersion */ SimdReal VLJ_S0 = VLJ12_S0 - VLJ6_S0; SimdReal VLJ_S1 = VLJ12_S1 - VLJ6_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal VLJ_S2 = VLJ12_S2 - VLJ6_S2; SimdReal VLJ_S3 = VLJ12_S3 - VLJ6_S3; -#endif +# endif -#endif /* (LJ_CUT || LJ_FORCE_SWITCH) && CALC_ENERGIES */ +# endif /* (LJ_CUT || LJ_FORCE_SWITCH) && CALC_ENERGIES */ -#ifdef LJ_POT_SWITCH +# ifdef LJ_POT_SWITCH /* We always need the potential, since it is needed for the force */ SimdReal VLJ_S0 = fnma(sixth_S, FrLJ6_S0, twelveth_S * FrLJ12_S0); SimdReal VLJ_S1 = fnma(sixth_S, FrLJ6_S1, twelveth_S * FrLJ12_S1); -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal VLJ_S2 = fnma(sixth_S, FrLJ6_S2, twelveth_S * FrLJ12_S2); SimdReal VLJ_S3 = fnma(sixth_S, FrLJ6_S3, twelveth_S * FrLJ12_S3); -#endif +# endif { SimdReal sw_S0, dsw_S0; SimdReal sw_S1, dsw_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal sw_S2, dsw_S2; SimdReal sw_S3, dsw_S3; -#endif +# endif -#define switch_r(rsw, rsw2, c3, c4, c5) fma(fma(fma(c5, rsw, c4), rsw, c3), ((rsw2) * (rsw)), one_S) -#define dswitch_r(rsw, rsw2, c2, c3, c4) (fma(fma(c4, rsw, c3), rsw, c2) * (rsw2)) +# define switch_r(rsw, rsw2, c3, c4, c5) \ + fma(fma(fma(c5, rsw, c4), rsw, c3), ((rsw2) * (rsw)), one_S) +# define dswitch_r(rsw, rsw2, c2, c3, c4) (fma(fma(c4, rsw, c3), rsw, c2) * (rsw2)) sw_S0 = switch_r(rsw_S0, rsw2_S0, swV3_S, swV4_S, swV5_S); dsw_S0 = dswitch_r(rsw_S0, rsw2_S0, swF2_S, swF3_S, swF4_S); sw_S1 = switch_r(rsw_S1, rsw2_S1, swV3_S, swV4_S, swV5_S); dsw_S1 = dswitch_r(rsw_S1, rsw2_S1, swF2_S, swF3_S, swF4_S); -#ifndef HALF_LJ +# ifndef HALF_LJ sw_S2 = switch_r(rsw_S2, rsw2_S2, swV3_S, swV4_S, swV5_S); dsw_S2 = dswitch_r(rsw_S2, rsw2_S2, swF2_S, swF3_S, swF4_S); sw_S3 = switch_r(rsw_S3, rsw2_S3, swV3_S, swV4_S, swV5_S); dsw_S3 = dswitch_r(rsw_S3, rsw2_S3, swF2_S, swF3_S, swF4_S); -#endif +# endif frLJ_S0 = fnma(dsw_S0 * VLJ_S0, r_S0, sw_S0 * frLJ_S0); frLJ_S1 = fnma(dsw_S1 * VLJ_S1, r_S1, sw_S1 * frLJ_S1); -#ifndef HALF_LJ +# ifndef HALF_LJ frLJ_S2 = fnma(dsw_S2 * VLJ_S2, r_S2, sw_S2 * frLJ_S2); frLJ_S3 = fnma(dsw_S3 * VLJ_S3, r_S3, sw_S3 * frLJ_S3); -#endif -#ifdef CALC_ENERGIES - VLJ_S0 = sw_S0 * VLJ_S0; - VLJ_S1 = sw_S1 * VLJ_S1; -#ifndef HALF_LJ - VLJ_S2 = sw_S2 * VLJ_S2; - VLJ_S3 = sw_S3 * VLJ_S3; -#endif -#endif - -#undef switch_r -#undef dswitch_r +# endif +# ifdef CALC_ENERGIES + VLJ_S0 = sw_S0 * VLJ_S0; + VLJ_S1 = sw_S1 * VLJ_S1; +# ifndef HALF_LJ + VLJ_S2 = sw_S2 * VLJ_S2; + VLJ_S3 = sw_S3 * VLJ_S3; +# endif +# endif + +# undef switch_r +# undef dswitch_r } -#endif /* LJ_POT_SWITCH */ +# endif /* LJ_POT_SWITCH */ -#if defined CALC_ENERGIES && defined CHECK_EXCLS +# if defined CALC_ENERGIES && defined CHECK_EXCLS /* The potential shift should be removed for excluded pairs */ - VLJ_S0 = selectByMask(VLJ_S0, interact_S0); - VLJ_S1 = selectByMask(VLJ_S1, interact_S1); -#ifndef HALF_LJ - VLJ_S2 = selectByMask(VLJ_S2, interact_S2); - VLJ_S3 = selectByMask(VLJ_S3, interact_S3); -#endif -#endif - -#ifdef LJ_EWALD_GEOM + VLJ_S0 = selectByMask(VLJ_S0, interact_S0); + VLJ_S1 = selectByMask(VLJ_S1, interact_S1); +# ifndef HALF_LJ + VLJ_S2 = selectByMask(VLJ_S2, interact_S2); + VLJ_S3 = selectByMask(VLJ_S3, interact_S3); +# endif +# endif + +# ifdef LJ_EWALD_GEOM { SimdReal c6s_j_S; SimdReal c6grid_S0, rinvsix_nm_S0, cr2_S0, expmcr2_S0, poly_S0; SimdReal c6grid_S1, rinvsix_nm_S1, cr2_S1, expmcr2_S1, poly_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal c6grid_S2, rinvsix_nm_S2, cr2_S2, expmcr2_S2, poly_S2; SimdReal c6grid_S3, rinvsix_nm_S3, cr2_S3, expmcr2_S3, poly_S3; -#endif -#ifdef CALC_ENERGIES +# endif +# ifdef CALC_ENERGIES SimdReal sh_mask_S0; SimdReal sh_mask_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ SimdReal sh_mask_S2; SimdReal sh_mask_S3; -#endif -#endif +# endif +# endif /* Determine C6 for the grid using the geometric combination rule */ - c6s_j_S = load(ljc+aj2+0); - c6grid_S0 = c6s_S0 * c6s_j_S; - c6grid_S1 = c6s_S1 * c6s_j_S; -#ifndef HALF_LJ - c6grid_S2 = c6s_S2 * c6s_j_S; - c6grid_S3 = c6s_S3 * c6s_j_S; -#endif - -#ifdef CHECK_EXCLS + c6s_j_S = load(ljc + aj2 + 0); + c6grid_S0 = c6s_S0 * c6s_j_S; + c6grid_S1 = c6s_S1 * c6s_j_S; +# ifndef HALF_LJ + c6grid_S2 = c6s_S2 * c6s_j_S; + c6grid_S3 = c6s_S3 * c6s_j_S; +# endif + +# ifdef CHECK_EXCLS /* Recalculate rinvsix without exclusion mask (compiler might optimize) */ rinvsix_nm_S0 = rinvsq_S0 * rinvsq_S0 * rinvsq_S0; rinvsix_nm_S1 = rinvsq_S1 * rinvsq_S1 * rinvsq_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ rinvsix_nm_S2 = rinvsq_S2 * rinvsq_S2 * rinvsq_S2; rinvsix_nm_S3 = rinvsq_S3 * rinvsq_S3 * rinvsq_S3; -#endif -#else +# endif +# else /* We didn't use a mask, so we can copy */ rinvsix_nm_S0 = rinvsix_S0; rinvsix_nm_S1 = rinvsix_S1; -#ifndef HALF_LJ +# ifndef HALF_LJ rinvsix_nm_S2 = rinvsix_S2; rinvsix_nm_S3 = rinvsix_S3; -#endif -#endif +# endif +# endif /* Mask for the cut-off to avoid overflow of cr2^2 */ - cr2_S0 = lje_c2_S * selectByMask(rsq_S0, wco_vdw_S0); - cr2_S1 = lje_c2_S * selectByMask(rsq_S1, wco_vdw_S1); -#ifndef HALF_LJ - cr2_S2 = lje_c2_S * selectByMask(rsq_S2, wco_vdw_S2); - cr2_S3 = lje_c2_S * selectByMask(rsq_S3, wco_vdw_S3); -#endif + cr2_S0 = lje_c2_S * selectByMask(rsq_S0, wco_vdw_S0); + cr2_S1 = lje_c2_S * selectByMask(rsq_S1, wco_vdw_S1); +# ifndef HALF_LJ + cr2_S2 = lje_c2_S * selectByMask(rsq_S2, wco_vdw_S2); + cr2_S3 = lje_c2_S * selectByMask(rsq_S3, wco_vdw_S3); +# endif // Unsafe version of our exp() should be fine, since these arguments should never // be smaller than -127 for any reasonable choice of cutoff or ewald coefficients. - expmcr2_S0 = exp( -cr2_S0 ); - expmcr2_S1 = exp( -cr2_S1 ); -#ifndef HALF_LJ - expmcr2_S2 = exp( -cr2_S2 ); - expmcr2_S3 = exp( -cr2_S3 ); -#endif + expmcr2_S0 = exp(-cr2_S0); + expmcr2_S1 = exp(-cr2_S1); +# ifndef HALF_LJ + expmcr2_S2 = exp(-cr2_S2); + expmcr2_S3 = exp(-cr2_S3); +# endif /* 1 + cr2 + 1/2*cr2^2 */ - poly_S0 = fma(fma(half_S, cr2_S0, one_S), cr2_S0, one_S); - poly_S1 = fma(fma(half_S, cr2_S1, one_S), cr2_S1, one_S); -#ifndef HALF_LJ - poly_S2 = fma(fma(half_S, cr2_S2, one_S), cr2_S2, one_S); - poly_S3 = fma(fma(half_S, cr2_S3, one_S), cr2_S3, one_S); -#endif + poly_S0 = fma(fma(half_S, cr2_S0, one_S), cr2_S0, one_S); + poly_S1 = fma(fma(half_S, cr2_S1, one_S), cr2_S1, one_S); +# ifndef HALF_LJ + poly_S2 = fma(fma(half_S, cr2_S2, one_S), cr2_S2, one_S); + poly_S3 = fma(fma(half_S, cr2_S3, one_S), cr2_S3, one_S); +# endif /* We calculate LJ F*r = (6*C6)*(r^-6 - F_mesh/6), we use: * r^-6*cexp*(1 + cr2 + cr2^2/2 + cr2^3/6) = cexp*(r^-6*poly + c^6/6) */ - frLJ_S0 = fma(c6grid_S0, fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0); - frLJ_S1 = fma(c6grid_S1, fnma(expmcr2_S1, fma(rinvsix_nm_S1, poly_S1, lje_c6_6_S), rinvsix_nm_S1), frLJ_S1); -#ifndef HALF_LJ - frLJ_S2 = fma(c6grid_S2, fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2); - frLJ_S3 = fma(c6grid_S3, fnma(expmcr2_S3, fma(rinvsix_nm_S3, poly_S3, lje_c6_6_S), rinvsix_nm_S3), frLJ_S3); -#endif - -#ifdef CALC_ENERGIES -#ifdef CHECK_EXCLS - sh_mask_S0 = selectByMask(lje_vc_S, interact_S0); - sh_mask_S1 = selectByMask(lje_vc_S, interact_S1); -#ifndef HALF_LJ - sh_mask_S2 = selectByMask(lje_vc_S, interact_S2); - sh_mask_S3 = selectByMask(lje_vc_S, interact_S3); -#endif -#else - sh_mask_S0 = lje_vc_S; - sh_mask_S1 = lje_vc_S; -#ifndef HALF_LJ - sh_mask_S2 = lje_vc_S; - sh_mask_S3 = lje_vc_S; -#endif -#endif - - VLJ_S0 = fma(sixth_S * c6grid_S0, fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0); - VLJ_S1 = fma(sixth_S * c6grid_S1, fma(rinvsix_nm_S1, fnma(expmcr2_S1, poly_S1, one_S), sh_mask_S1), VLJ_S1); -#ifndef HALF_LJ - VLJ_S2 = fma(sixth_S * c6grid_S2, fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2); - VLJ_S3 = fma(sixth_S * c6grid_S3, fma(rinvsix_nm_S3, fnma(expmcr2_S3, poly_S3, one_S), sh_mask_S3), VLJ_S3); -#endif -#endif /* CALC_ENERGIES */ + frLJ_S0 = fma(c6grid_S0, + fnma(expmcr2_S0, fma(rinvsix_nm_S0, poly_S0, lje_c6_6_S), rinvsix_nm_S0), frLJ_S0); + frLJ_S1 = fma(c6grid_S1, + fnma(expmcr2_S1, fma(rinvsix_nm_S1, poly_S1, lje_c6_6_S), rinvsix_nm_S1), frLJ_S1); +# ifndef HALF_LJ + frLJ_S2 = fma(c6grid_S2, + fnma(expmcr2_S2, fma(rinvsix_nm_S2, poly_S2, lje_c6_6_S), rinvsix_nm_S2), frLJ_S2); + frLJ_S3 = fma(c6grid_S3, + fnma(expmcr2_S3, fma(rinvsix_nm_S3, poly_S3, lje_c6_6_S), rinvsix_nm_S3), frLJ_S3); +# endif + +# ifdef CALC_ENERGIES +# ifdef CHECK_EXCLS + sh_mask_S0 = selectByMask(lje_vc_S, interact_S0); + sh_mask_S1 = selectByMask(lje_vc_S, interact_S1); +# ifndef HALF_LJ + sh_mask_S2 = selectByMask(lje_vc_S, interact_S2); + sh_mask_S3 = selectByMask(lje_vc_S, interact_S3); +# endif +# else + sh_mask_S0 = lje_vc_S; + sh_mask_S1 = lje_vc_S; +# ifndef HALF_LJ + sh_mask_S2 = lje_vc_S; + sh_mask_S3 = lje_vc_S; +# endif +# endif + + VLJ_S0 = fma(sixth_S * c6grid_S0, + fma(rinvsix_nm_S0, fnma(expmcr2_S0, poly_S0, one_S), sh_mask_S0), VLJ_S0); + VLJ_S1 = fma(sixth_S * c6grid_S1, + fma(rinvsix_nm_S1, fnma(expmcr2_S1, poly_S1, one_S), sh_mask_S1), VLJ_S1); +# ifndef HALF_LJ + VLJ_S2 = fma(sixth_S * c6grid_S2, + fma(rinvsix_nm_S2, fnma(expmcr2_S2, poly_S2, one_S), sh_mask_S2), VLJ_S2); + VLJ_S3 = fma(sixth_S * c6grid_S3, + fma(rinvsix_nm_S3, fnma(expmcr2_S3, poly_S3, one_S), sh_mask_S3), VLJ_S3); +# endif +# endif /* CALC_ENERGIES */ } -#endif /* LJ_EWALD_GEOM */ +# endif /* LJ_EWALD_GEOM */ -#if defined VDW_CUTOFF_CHECK +# if defined VDW_CUTOFF_CHECK /* frLJ is multiplied later by rinvsq, which is masked for the Coulomb * cut-off, but if the VdW cut-off is shorter, we need to mask with that. */ - frLJ_S0 = selectByMask(frLJ_S0, wco_vdw_S0); - frLJ_S1 = selectByMask(frLJ_S1, wco_vdw_S1); -#ifndef HALF_LJ - frLJ_S2 = selectByMask(frLJ_S2, wco_vdw_S2); - frLJ_S3 = selectByMask(frLJ_S3, wco_vdw_S3); -#endif -#endif - -#ifdef CALC_ENERGIES + frLJ_S0 = selectByMask(frLJ_S0, wco_vdw_S0); + frLJ_S1 = selectByMask(frLJ_S1, wco_vdw_S1); +# ifndef HALF_LJ + frLJ_S2 = selectByMask(frLJ_S2, wco_vdw_S2); + frLJ_S3 = selectByMask(frLJ_S3, wco_vdw_S3); +# endif +# endif + +# ifdef CALC_ENERGIES /* The potential shift should be removed for pairs beyond cut-off */ - VLJ_S0 = selectByMask(VLJ_S0, wco_vdw_S0); - VLJ_S1 = selectByMask(VLJ_S1, wco_vdw_S1); -#ifndef HALF_LJ - VLJ_S2 = selectByMask(VLJ_S2, wco_vdw_S2); - VLJ_S3 = selectByMask(VLJ_S3, wco_vdw_S3); -#endif -#endif - -#endif /* CALC_LJ */ - -#ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS + VLJ_S0 = selectByMask(VLJ_S0, wco_vdw_S0); + VLJ_S1 = selectByMask(VLJ_S1, wco_vdw_S1); +# ifndef HALF_LJ + VLJ_S2 = selectByMask(VLJ_S2, wco_vdw_S2); + VLJ_S3 = selectByMask(VLJ_S3, wco_vdw_S3); +# endif +# endif + +# endif /* CALC_LJ */ + +# ifdef CALC_ENERGIES +# ifdef ENERGY_GROUPS /* Extract the group pair index per j pair. * Energy groups are stored per i-cluster, so things get * complicated when the i- and j-cluster size don't match. */ { int egps_j; -#if UNROLLJ == 2 +# if UNROLLJ == 2 egps_j = nbatParams.energrp[cj >> 1]; - egp_jj[0] = ((egps_j >> ((cj & 1)*egps_jshift)) & egps_jmask)*egps_jstride; -#else + egp_jj[0] = ((egps_j >> ((cj & 1) * egps_jshift)) & egps_jmask) * egps_jstride; +# else /* We assume UNROLLI <= UNROLLJ */ int jdi; - for (jdi = 0; jdi < UNROLLJ/UNROLLI; jdi++) + for (jdi = 0; jdi < UNROLLJ / UNROLLI; jdi++) { int jj; - egps_j = nbatParams.energrp[cj*(UNROLLJ/UNROLLI) + jdi]; - for (jj = 0; jj < (UNROLLI/2); jj++) + egps_j = nbatParams.energrp[cj * (UNROLLJ / UNROLLI) + jdi]; + for (jj = 0; jj < (UNROLLI / 2); jj++) { - egp_jj[jdi*(UNROLLI/2)+jj] = ((egps_j >> (jj*egps_jshift)) & egps_jmask)*egps_jstride; + egp_jj[jdi * (UNROLLI / 2) + jj] = + ((egps_j >> (jj * egps_jshift)) & egps_jmask) * egps_jstride; } } -#endif +# endif } -#endif +# endif -#ifdef CALC_COULOMB -#ifndef ENERGY_GROUPS - vctot_S = vctot_S + vcoul_S0 + vcoul_S1 + vcoul_S2 + vcoul_S3; -#else +# ifdef CALC_COULOMB +# ifndef ENERGY_GROUPS + vctot_S = vctot_S + vcoul_S0 + vcoul_S1 + vcoul_S2 + vcoul_S3; +# else add_ener_grp(vcoul_S0, vctp[0], egp_jj); add_ener_grp(vcoul_S1, vctp[1], egp_jj); add_ener_grp(vcoul_S2, vctp[2], egp_jj); add_ener_grp(vcoul_S3, vctp[3], egp_jj); -#endif -#endif - -#ifdef CALC_LJ - -#ifndef ENERGY_GROUPS -#ifndef HALF_LJ - Vvdwtot_S = Vvdwtot_S + VLJ_S0 + VLJ_S1 + VLJ_S2 + VLJ_S3; -#else - Vvdwtot_S = Vvdwtot_S + VLJ_S0 + VLJ_S1; -#endif -#else +# endif +# endif + +# ifdef CALC_LJ + +# ifndef ENERGY_GROUPS +# ifndef HALF_LJ + Vvdwtot_S = Vvdwtot_S + VLJ_S0 + VLJ_S1 + VLJ_S2 + VLJ_S3; +# else + Vvdwtot_S = Vvdwtot_S + VLJ_S0 + VLJ_S1; +# endif +# else add_ener_grp(VLJ_S0, vvdwtp[0], egp_jj); add_ener_grp(VLJ_S1, vvdwtp[1], egp_jj); -#ifndef HALF_LJ +# ifndef HALF_LJ add_ener_grp(VLJ_S2, vvdwtp[2], egp_jj); add_ener_grp(VLJ_S3, vvdwtp[3], egp_jj); -#endif -#endif -#endif /* CALC_LJ */ -#endif /* CALC_ENERGIES */ - -#ifdef CALC_LJ -#ifdef CALC_COULOMB - fscal_S0 = rinvsq_S0 * (frcoul_S0 + frLJ_S0); -#else - fscal_S0 = rinvsq_S0 * frLJ_S0; -#endif -#ifdef CALC_COULOMB - fscal_S1 = rinvsq_S1 * (frcoul_S1 + frLJ_S1); -#else - fscal_S1 = rinvsq_S1 * frLJ_S1; -#endif -#else - fscal_S0 = rinvsq_S0 * frcoul_S0; - fscal_S1 = rinvsq_S1 * frcoul_S1; -#endif /* CALC_LJ */ -#if defined CALC_LJ && !defined HALF_LJ -#ifdef CALC_COULOMB - fscal_S2 = rinvsq_S2 * (frcoul_S2 + frLJ_S2); - fscal_S3 = rinvsq_S3 * (frcoul_S3 + frLJ_S3); -#else - fscal_S2 = rinvsq_S2 * frLJ_S2; - fscal_S3 = rinvsq_S3 * frLJ_S3; -#endif -#else +# endif +# endif +# endif /* CALC_LJ */ +# endif /* CALC_ENERGIES */ + +# ifdef CALC_LJ +# ifdef CALC_COULOMB + fscal_S0 = rinvsq_S0 * (frcoul_S0 + frLJ_S0); +# else + fscal_S0 = rinvsq_S0 * frLJ_S0; +# endif +# ifdef CALC_COULOMB + fscal_S1 = rinvsq_S1 * (frcoul_S1 + frLJ_S1); +# else + fscal_S1 = rinvsq_S1 * frLJ_S1; +# endif +# else + fscal_S0 = rinvsq_S0 * frcoul_S0; + fscal_S1 = rinvsq_S1 * frcoul_S1; +# endif /* CALC_LJ */ +# if defined CALC_LJ && !defined HALF_LJ +# ifdef CALC_COULOMB + fscal_S2 = rinvsq_S2 * (frcoul_S2 + frLJ_S2); + fscal_S3 = rinvsq_S3 * (frcoul_S3 + frLJ_S3); +# else + fscal_S2 = rinvsq_S2 * frLJ_S2; + fscal_S3 = rinvsq_S3 * frLJ_S3; +# endif +# else /* Atom 2 and 3 don't have LJ, so only add Coulomb forces */ - fscal_S2 = rinvsq_S2 * frcoul_S2; - fscal_S3 = rinvsq_S3 * frcoul_S3; -#endif + fscal_S2 = rinvsq_S2 * frcoul_S2; + fscal_S3 = rinvsq_S3 * frcoul_S3; +# endif /* Calculate temporary vectorial force */ - tx_S0 = fscal_S0 * dx_S0; - tx_S1 = fscal_S1 * dx_S1; - tx_S2 = fscal_S2 * dx_S2; - tx_S3 = fscal_S3 * dx_S3; - ty_S0 = fscal_S0 * dy_S0; - ty_S1 = fscal_S1 * dy_S1; - ty_S2 = fscal_S2 * dy_S2; - ty_S3 = fscal_S3 * dy_S3; - tz_S0 = fscal_S0 * dz_S0; - tz_S1 = fscal_S1 * dz_S1; - tz_S2 = fscal_S2 * dz_S2; - tz_S3 = fscal_S3 * dz_S3; + tx_S0 = fscal_S0 * dx_S0; + tx_S1 = fscal_S1 * dx_S1; + tx_S2 = fscal_S2 * dx_S2; + tx_S3 = fscal_S3 * dx_S3; + ty_S0 = fscal_S0 * dy_S0; + ty_S1 = fscal_S1 * dy_S1; + ty_S2 = fscal_S2 * dy_S2; + ty_S3 = fscal_S3 * dy_S3; + tz_S0 = fscal_S0 * dz_S0; + tz_S1 = fscal_S1 * dz_S1; + tz_S2 = fscal_S2 * dz_S2; + tz_S3 = fscal_S3 * dz_S3; /* Increment i atom force */ - fix_S0 = fix_S0 + tx_S0; - fix_S1 = fix_S1 + tx_S1; - fix_S2 = fix_S2 + tx_S2; - fix_S3 = fix_S3 + tx_S3; - fiy_S0 = fiy_S0 + ty_S0; - fiy_S1 = fiy_S1 + ty_S1; - fiy_S2 = fiy_S2 + ty_S2; - fiy_S3 = fiy_S3 + ty_S3; - fiz_S0 = fiz_S0 + tz_S0; - fiz_S1 = fiz_S1 + tz_S1; - fiz_S2 = fiz_S2 + tz_S2; - fiz_S3 = fiz_S3 + tz_S3; + fix_S0 = fix_S0 + tx_S0; + fix_S1 = fix_S1 + tx_S1; + fix_S2 = fix_S2 + tx_S2; + fix_S3 = fix_S3 + tx_S3; + fiy_S0 = fiy_S0 + ty_S0; + fiy_S1 = fiy_S1 + ty_S1; + fiy_S2 = fiy_S2 + ty_S2; + fiy_S3 = fiy_S3 + ty_S3; + fiz_S0 = fiz_S0 + tz_S0; + fiz_S1 = fiz_S1 + tz_S1; + fiz_S2 = fiz_S2 + tz_S2; + fiz_S3 = fiz_S3 + tz_S3; /* Decrement j atom force */ - store(f+ajx, load(f+ajx) - (tx_S0 + tx_S1 + tx_S2 + tx_S3)); - store(f+ajy, load(f+ajy) - (ty_S0 + ty_S1 + ty_S2 + ty_S3)); - store(f+ajz, load(f+ajz) - (tz_S0 + tz_S1 + tz_S2 + tz_S3)); + store(f + ajx, load(f + ajx) - (tx_S0 + tx_S1 + tx_S2 + tx_S3)); + store(f + ajy, load(f + ajy) - (ty_S0 + ty_S1 + ty_S2 + ty_S3)); + store(f + ajz, load(f + ajz) - (tz_S0 + tz_S1 + tz_S2 + tz_S3)); } -#undef rinv_ex_S0 -#undef rinv_ex_S1 -#undef rinv_ex_S2 -#undef rinv_ex_S3 +# undef rinv_ex_S0 +# undef rinv_ex_S1 +# undef rinv_ex_S2 +# undef rinv_ex_S3 -#undef wco_vdw_S0 -#undef wco_vdw_S1 -#undef wco_vdw_S2 -#undef wco_vdw_S3 +# undef wco_vdw_S0 +# undef wco_vdw_S1 +# undef wco_vdw_S2 +# undef wco_vdw_S3 -#undef EXCL_FORCES +# undef EXCL_FORCES #endif // !DOXYGEN diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h index be3eeeba1f..03f2d544b6 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_outer.h @@ -38,80 +38,80 @@ using namespace gmx; /* Unpack pointers for output */ - real *f = out->f.data(); - real *fshift = out->fshift.data(); + real* f = out->f.data(); + real* fshift = out->fshift.data(); #ifdef CALC_ENERGIES -#ifdef ENERGY_GROUPS - real *Vvdw = out->VSvdw.data(); - real *Vc = out->VSc.data(); -#else - real *Vvdw = out->Vvdw.data(); - real *Vc = out->Vc.data(); -#endif +# ifdef ENERGY_GROUPS + real* Vvdw = out->VSvdw.data(); + real* Vc = out->VSc.data(); +# else + real* Vvdw = out->Vvdw.data(); + real* Vc = out->Vc.data(); +# endif #endif - const nbnxn_cj_t *l_cj; - int ci, ci_sh; - int ish, ish3; - gmx_bool do_LJ, half_LJ, do_coul; - int cjind0, cjind1, cjind; + const nbnxn_cj_t* l_cj; + int ci, ci_sh; + int ish, ish3; + gmx_bool do_LJ, half_LJ, do_coul; + int cjind0, cjind1, cjind; #ifdef ENERGY_GROUPS - int Vstride_i; - int egps_ishift, egps_imask; - int egps_jshift, egps_jmask, egps_jstride; - int egps_i; - real *vvdwtp[UNROLLI]; - real *vctp[UNROLLI]; -#endif - - SimdReal shX_S; - SimdReal shY_S; - SimdReal shZ_S; - SimdReal ix_S0, iy_S0, iz_S0; - SimdReal ix_S1, iy_S1, iz_S1; - SimdReal ix_S2, iy_S2, iz_S2; - SimdReal ix_S3, iy_S3, iz_S3; - SimdReal fix_S0, fiy_S0, fiz_S0; - SimdReal fix_S1, fiy_S1, fiz_S1; - SimdReal fix_S2, fiy_S2, fiz_S2; - SimdReal fix_S3, fiy_S3, fiz_S3; - - SimdReal diagonal_jmi_S; + int Vstride_i; + int egps_ishift, egps_imask; + int egps_jshift, egps_jmask, egps_jstride; + int egps_i; + real* vvdwtp[UNROLLI]; + real* vctp[UNROLLI]; +#endif + + SimdReal shX_S; + SimdReal shY_S; + SimdReal shZ_S; + SimdReal ix_S0, iy_S0, iz_S0; + SimdReal ix_S1, iy_S1, iz_S1; + SimdReal ix_S2, iy_S2, iz_S2; + SimdReal ix_S3, iy_S3, iz_S3; + SimdReal fix_S0, fiy_S0, fiz_S0; + SimdReal fix_S1, fiy_S1, fiz_S1; + SimdReal fix_S2, fiy_S2, fiz_S2; + SimdReal fix_S3, fiy_S3, fiz_S3; + + SimdReal diagonal_jmi_S; #if UNROLLI == UNROLLJ - SimdBool diagonal_mask_S0, diagonal_mask_S1, diagonal_mask_S2, diagonal_mask_S3; + SimdBool diagonal_mask_S0, diagonal_mask_S1, diagonal_mask_S2, diagonal_mask_S3; #else - SimdBool diagonal_mask0_S0, diagonal_mask0_S1, diagonal_mask0_S2, diagonal_mask0_S3; - SimdBool diagonal_mask1_S0, diagonal_mask1_S1, diagonal_mask1_S2, diagonal_mask1_S3; + SimdBool diagonal_mask0_S0, diagonal_mask0_S1, diagonal_mask0_S2, diagonal_mask0_S3; + SimdBool diagonal_mask1_S0, diagonal_mask1_S1, diagonal_mask1_S2, diagonal_mask1_S3; #endif - SimdBitMask filter_S0, filter_S1, filter_S2, filter_S3; + SimdBitMask filter_S0, filter_S1, filter_S2, filter_S3; - SimdReal zero_S(0.0); + SimdReal zero_S(0.0); - SimdReal one_S(1.0); - SimdReal iq_S0 = setZero(); - SimdReal iq_S1 = setZero(); - SimdReal iq_S2 = setZero(); - SimdReal iq_S3 = setZero(); + SimdReal one_S(1.0); + SimdReal iq_S0 = setZero(); + SimdReal iq_S1 = setZero(); + SimdReal iq_S2 = setZero(); + SimdReal iq_S3 = setZero(); #ifdef CALC_COUL_RF - SimdReal mrc_3_S; -#ifdef CALC_ENERGIES - SimdReal hrc_3_S, moh_rc_S; -#endif + SimdReal mrc_3_S; +# ifdef CALC_ENERGIES + SimdReal hrc_3_S, moh_rc_S; +# endif #endif #ifdef CALC_COUL_TAB /* Coulomb table variables */ - SimdReal invtsp_S; - const real * tab_coul_F; -#if defined CALC_ENERGIES && !defined TAB_FDV0 - const real gmx_unused *tab_coul_V; -#endif -#ifdef CALC_ENERGIES - SimdReal mhalfsp_S; -#endif + SimdReal invtsp_S; + const real* tab_coul_F; +# if defined CALC_ENERGIES && !defined TAB_FDV0 + const real gmx_unused* tab_coul_V; +# endif +# ifdef CALC_ENERGIES + SimdReal mhalfsp_S; +# endif #endif #ifdef CALC_COUL_EWALD @@ -119,43 +119,43 @@ #endif #if defined CALC_ENERGIES && (defined CALC_COUL_EWALD || defined CALC_COUL_TAB) - SimdReal sh_ewald_S; + SimdReal sh_ewald_S; #endif #if defined LJ_CUT && defined CALC_ENERGIES - SimdReal p6_cpot_S, p12_cpot_S; + SimdReal p6_cpot_S, p12_cpot_S; #endif #ifdef LJ_POT_SWITCH - SimdReal rswitch_S; - SimdReal swV3_S, swV4_S, swV5_S; - SimdReal swF2_S, swF3_S, swF4_S; + SimdReal rswitch_S; + SimdReal swV3_S, swV4_S, swV5_S; + SimdReal swF2_S, swF3_S, swF4_S; #endif #ifdef LJ_FORCE_SWITCH - SimdReal rswitch_S; - SimdReal p6_fc2_S, p6_fc3_S; - SimdReal p12_fc2_S, p12_fc3_S; -#ifdef CALC_ENERGIES - SimdReal p6_vc3_S, p6_vc4_S; - SimdReal p12_vc3_S, p12_vc4_S; - SimdReal p6_6cpot_S, p12_12cpot_S; -#endif + SimdReal rswitch_S; + SimdReal p6_fc2_S, p6_fc3_S; + SimdReal p12_fc2_S, p12_fc3_S; +# ifdef CALC_ENERGIES + SimdReal p6_vc3_S, p6_vc4_S; + SimdReal p12_vc3_S, p12_vc4_S; + SimdReal p6_6cpot_S, p12_12cpot_S; +# endif #endif #ifdef LJ_EWALD_GEOM - real lj_ewaldcoeff2, lj_ewaldcoeff6_6; - SimdReal mone_S, half_S, lje_c2_S, lje_c6_6_S; + real lj_ewaldcoeff2, lj_ewaldcoeff6_6; + SimdReal mone_S, half_S, lje_c2_S, lje_c6_6_S; #endif #ifdef LJ_COMB_LB - SimdReal hsig_i_S0, seps_i_S0; - SimdReal hsig_i_S1, seps_i_S1; - SimdReal hsig_i_S2, seps_i_S2; - SimdReal hsig_i_S3, seps_i_S3; + SimdReal hsig_i_S0, seps_i_S0; + SimdReal hsig_i_S1, seps_i_S1; + SimdReal hsig_i_S2, seps_i_S2; + SimdReal hsig_i_S3, seps_i_S3; #endif /* LJ_COMB_LB */ - SimdReal minRsq_S; - SimdReal rc2_S; + SimdReal minRsq_S; + SimdReal rc2_S; #ifdef VDW_CUTOFF_CHECK - SimdReal rcvdw2_S; + SimdReal rcvdw2_S; #endif int ninner; @@ -164,30 +164,30 @@ int npair = 0; #endif - const nbnxn_atomdata_t::Params &nbatParams = nbat->params(); + const nbnxn_atomdata_t::Params& nbatParams = nbat->params(); #if defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined LJ_EWALD_GEOM - const real * gmx_restrict ljc = nbatParams.lj_comb.data(); + const real* gmx_restrict ljc = nbatParams.lj_comb.data(); #endif #if !(defined LJ_COMB_GEOM || defined LJ_COMB_LB || defined FIX_LJ_C) /* No combination rule used */ - const real * gmx_restrict nbfp_ptr = nbatParams.nbfp_aligned.data(); - const int * gmx_restrict type = nbatParams.type.data(); + const real* gmx_restrict nbfp_ptr = nbatParams.nbfp_aligned.data(); + const int* gmx_restrict type = nbatParams.type.data(); #endif /* Load j-i for the first i */ - diagonal_jmi_S = load(nbat->simdMasks.diagonal_4xn_j_minus_i.data()); + diagonal_jmi_S = load(nbat->simdMasks.diagonal_4xn_j_minus_i.data()); /* Generate all the diagonal masks as comparison results */ #if UNROLLI == UNROLLJ - diagonal_mask_S0 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask_S1 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask_S2 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask_S3 = (zero_S < diagonal_jmi_S); + diagonal_mask_S0 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask_S1 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask_S2 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask_S3 = (zero_S < diagonal_jmi_S); #else -#if UNROLLI == 2*UNROLLJ || 2*UNROLLI == UNROLLJ +# if UNROLLI == 2 * UNROLLJ || 2 * UNROLLI == UNROLLJ diagonal_mask0_S0 = (zero_S < diagonal_jmi_S); diagonal_jmi_S = diagonal_jmi_S - one_S; diagonal_mask0_S1 = (zero_S < diagonal_jmi_S); @@ -197,25 +197,25 @@ diagonal_mask0_S3 = (zero_S < diagonal_jmi_S); diagonal_jmi_S = diagonal_jmi_S - one_S; -#if UNROLLI == 2*UNROLLJ +# if UNROLLI == 2 * UNROLLJ /* Load j-i for the second half of the j-cluster */ - diagonal_jmi_S = load(nbat->simdMasks.diagonal_4xn_j_minus_i.data() + UNROLLJ); -#endif + diagonal_jmi_S = load(nbat->simdMasks.diagonal_4xn_j_minus_i.data() + UNROLLJ); +# endif - diagonal_mask1_S0 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask1_S1 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask1_S2 = (zero_S < diagonal_jmi_S); - diagonal_jmi_S = diagonal_jmi_S - one_S; - diagonal_mask1_S3 = (zero_S < diagonal_jmi_S); -#endif + diagonal_mask1_S0 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask1_S1 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask1_S2 = (zero_S < diagonal_jmi_S); + diagonal_jmi_S = diagonal_jmi_S - one_S; + diagonal_mask1_S3 = (zero_S < diagonal_jmi_S); +# endif #endif #if GMX_DOUBLE && !GMX_SIMD_HAVE_INT32_LOGICAL - const std::uint64_t * gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter64.data(); + const std::uint64_t* gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter64.data(); #else - const std::uint32_t * gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter.data(); + const std::uint32_t* gmx_restrict exclusion_filter = nbat->simdMasks.exclusion_filter.data(); #endif /* Here we cast the exclusion filters from unsigned * to int * or real *. @@ -223,45 +223,45 @@ * matter, as long as both filter and mask data are treated the same way. */ #if GMX_SIMD_HAVE_INT32_LOGICAL - filter_S0 = load(reinterpret_cast(exclusion_filter + 0*UNROLLJ)); - filter_S1 = load(reinterpret_cast(exclusion_filter + 1*UNROLLJ)); - filter_S2 = load(reinterpret_cast(exclusion_filter + 2*UNROLLJ)); - filter_S3 = load(reinterpret_cast(exclusion_filter + 3*UNROLLJ)); + filter_S0 = load(reinterpret_cast(exclusion_filter + 0 * UNROLLJ)); + filter_S1 = load(reinterpret_cast(exclusion_filter + 1 * UNROLLJ)); + filter_S2 = load(reinterpret_cast(exclusion_filter + 2 * UNROLLJ)); + filter_S3 = load(reinterpret_cast(exclusion_filter + 3 * UNROLLJ)); #else - filter_S0 = load(reinterpret_cast(exclusion_filter + 0*UNROLLJ)); - filter_S1 = load(reinterpret_cast(exclusion_filter + 1*UNROLLJ)); - filter_S2 = load(reinterpret_cast(exclusion_filter + 2*UNROLLJ)); - filter_S3 = load(reinterpret_cast(exclusion_filter + 3*UNROLLJ)); + filter_S0 = load(reinterpret_cast(exclusion_filter + 0 * UNROLLJ)); + filter_S1 = load(reinterpret_cast(exclusion_filter + 1 * UNROLLJ)); + filter_S2 = load(reinterpret_cast(exclusion_filter + 2 * UNROLLJ)); + filter_S3 = load(reinterpret_cast(exclusion_filter + 3 * UNROLLJ)); #endif #ifdef CALC_COUL_RF /* Reaction-field constants */ - mrc_3_S = SimdReal(-2*ic->k_rf); -#ifdef CALC_ENERGIES + mrc_3_S = SimdReal(-2 * ic->k_rf); +# ifdef CALC_ENERGIES hrc_3_S = SimdReal(ic->k_rf); moh_rc_S = SimdReal(-ic->c_rf); -#endif +# endif #endif #ifdef CALC_COUL_TAB - invtsp_S = SimdReal(ic->coulombEwaldTables->scale); -#ifdef CALC_ENERGIES - mhalfsp_S = SimdReal(-0.5_real/ic->coulombEwaldTables->scale); -#endif + invtsp_S = SimdReal(ic->coulombEwaldTables->scale); +# ifdef CALC_ENERGIES + mhalfsp_S = SimdReal(-0.5_real / ic->coulombEwaldTables->scale); +# endif -#ifdef TAB_FDV0 +# ifdef TAB_FDV0 tab_coul_F = ic->coulombEwaldTables->tableFDV0.data(); -#else +# else tab_coul_F = ic->coulombEwaldTables->tableF.data(); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES tab_coul_V = ic->coulombEwaldTables->tableV.data(); -#endif -#endif +# endif +# endif #endif /* CALC_COUL_TAB */ #ifdef CALC_COUL_EWALD - beta2_S = SimdReal(ic->ewaldcoeff_q*ic->ewaldcoeff_q); + beta2_S = SimdReal(ic->ewaldcoeff_q * ic->ewaldcoeff_q); beta_S = SimdReal(ic->ewaldcoeff_q); #endif @@ -271,23 +271,23 @@ /* LJ function constants */ #if defined CALC_ENERGIES || defined LJ_POT_SWITCH - SimdReal sixth_S(1.0/6.0); - SimdReal twelveth_S(1.0/12.0); + SimdReal sixth_S(1.0 / 6.0); + SimdReal twelveth_S(1.0 / 12.0); #endif #if defined LJ_CUT && defined CALC_ENERGIES /* We shift the potential by cpot, which can be zero */ - p6_cpot_S = SimdReal(ic->dispersion_shift.cpot); - p12_cpot_S = SimdReal(ic->repulsion_shift.cpot); + p6_cpot_S = SimdReal(ic->dispersion_shift.cpot); + p12_cpot_S = SimdReal(ic->repulsion_shift.cpot); #endif #ifdef LJ_POT_SWITCH rswitch_S = SimdReal(ic->rvdw_switch); swV3_S = SimdReal(ic->vdw_switch.c3); swV4_S = SimdReal(ic->vdw_switch.c4); swV5_S = SimdReal(ic->vdw_switch.c5); - swF2_S = SimdReal(3*ic->vdw_switch.c3); - swF3_S = SimdReal(4*ic->vdw_switch.c4); - swF4_S = SimdReal(5*ic->vdw_switch.c5); + swF2_S = SimdReal(3 * ic->vdw_switch.c3); + swF3_S = SimdReal(4 * ic->vdw_switch.c4); + swF4_S = SimdReal(5 * ic->vdw_switch.c5); #endif #ifdef LJ_FORCE_SWITCH rswitch_S = SimdReal(ic->rvdw_switch); @@ -295,113 +295,113 @@ p6_fc3_S = SimdReal(ic->dispersion_shift.c3); p12_fc2_S = SimdReal(ic->repulsion_shift.c2); p12_fc3_S = SimdReal(ic->repulsion_shift.c3); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES { - SimdReal mthird_S(-1.0/3.0); - SimdReal mfourth_S(-1.0/4.0); + SimdReal mthird_S(-1.0 / 3.0); + SimdReal mfourth_S(-1.0 / 4.0); p6_vc3_S = mthird_S * p6_fc2_S; p6_vc4_S = mfourth_S * p6_fc3_S; - p6_6cpot_S = SimdReal(ic->dispersion_shift.cpot/6); + p6_6cpot_S = SimdReal(ic->dispersion_shift.cpot / 6); p12_vc3_S = mthird_S * p12_fc2_S; p12_vc4_S = mfourth_S * p12_fc3_S; - p12_12cpot_S = SimdReal(ic->repulsion_shift.cpot/12); + p12_12cpot_S = SimdReal(ic->repulsion_shift.cpot / 12); } -#endif +# endif #endif #ifdef LJ_EWALD_GEOM mone_S = SimdReal(-1.0); half_S = SimdReal(0.5); - lj_ewaldcoeff2 = ic->ewaldcoeff_lj*ic->ewaldcoeff_lj; - lj_ewaldcoeff6_6 = lj_ewaldcoeff2*lj_ewaldcoeff2*lj_ewaldcoeff2/6; + lj_ewaldcoeff2 = ic->ewaldcoeff_lj * ic->ewaldcoeff_lj; + lj_ewaldcoeff6_6 = lj_ewaldcoeff2 * lj_ewaldcoeff2 * lj_ewaldcoeff2 / 6; lje_c2_S = SimdReal(lj_ewaldcoeff2); lje_c6_6_S = SimdReal(lj_ewaldcoeff6_6); -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES /* Determine the grid potential at the cut-off */ SimdReal lje_vc_S(ic->sh_lj_ewald); -#endif +# endif #endif /* The kernel either supports rcoulomb = rvdw or rcoulomb >= rvdw */ - rc2_S = SimdReal(ic->rcoulomb*ic->rcoulomb); + rc2_S = SimdReal(ic->rcoulomb * ic->rcoulomb); #ifdef VDW_CUTOFF_CHECK - rcvdw2_S = SimdReal(ic->rvdw*ic->rvdw); + rcvdw2_S = SimdReal(ic->rvdw * ic->rvdw); #endif - minRsq_S = SimdReal(NBNXN_MIN_RSQ); + minRsq_S = SimdReal(NBNXN_MIN_RSQ); - const real * gmx_restrict q = nbatParams.q.data(); - const real facel = ic->epsfac; - const real * gmx_restrict shiftvec = shift_vec[0]; - const real * gmx_restrict x = nbat->x().data(); + const real* gmx_restrict q = nbatParams.q.data(); + const real facel = ic->epsfac; + const real* gmx_restrict shiftvec = shift_vec[0]; + const real* gmx_restrict x = nbat->x().data(); #ifdef FIX_LJ_C - alignas(GMX_SIMD_ALIGNMENT) real pvdw_c6[2*UNROLLI*UNROLLJ]; - real *pvdw_c12 = pvdw_c6 + UNROLLI*UNROLLJ; + alignas(GMX_SIMD_ALIGNMENT) real pvdw_c6[2 * UNROLLI * UNROLLJ]; + real* pvdw_c12 = pvdw_c6 + UNROLLI * UNROLLJ; for (int jp = 0; jp < UNROLLJ; jp++) { - pvdw_c6 [0*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [1*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [2*UNROLLJ+jp] = nbat->nbfp[0*2]; - pvdw_c6 [3*UNROLLJ+jp] = nbat->nbfp[0*2]; - - pvdw_c12[0*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[1*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[2*UNROLLJ+jp] = nbat->nbfp[0*2+1]; - pvdw_c12[3*UNROLLJ+jp] = nbat->nbfp[0*2+1]; + pvdw_c6[0 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[1 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[2 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + pvdw_c6[3 * UNROLLJ + jp] = nbat->nbfp[0 * 2]; + + pvdw_c12[0 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[1 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[2 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; + pvdw_c12[3 * UNROLLJ + jp] = nbat->nbfp[0 * 2 + 1]; } - SimdReal c6_S0 = load(pvdw_c6 +0*UNROLLJ); - SimdReal c6_S1 = load(pvdw_c6 +1*UNROLLJ); - SimdReal c6_S2 = load(pvdw_c6 +2*UNROLLJ); - SimdReal c6_S3 = load(pvdw_c6 +3*UNROLLJ); - - SimdReal c12_S0 = load(pvdw_c12+0*UNROLLJ); - SimdReal c12_S1 = load(pvdw_c12+1*UNROLLJ); - SimdReal c12_S2 = load(pvdw_c12+2*UNROLLJ); - SimdReal c12_S3 = load(pvdw_c12+3*UNROLLJ); + SimdReal c6_S0 = load(pvdw_c6 + 0 * UNROLLJ); + SimdReal c6_S1 = load(pvdw_c6 + 1 * UNROLLJ); + SimdReal c6_S2 = load(pvdw_c6 + 2 * UNROLLJ); + SimdReal c6_S3 = load(pvdw_c6 + 3 * UNROLLJ); + + SimdReal c12_S0 = load(pvdw_c12 + 0 * UNROLLJ); + SimdReal c12_S1 = load(pvdw_c12 + 1 * UNROLLJ); + SimdReal c12_S2 = load(pvdw_c12 + 2 * UNROLLJ); + SimdReal c12_S3 = load(pvdw_c12 + 3 * UNROLLJ); #endif /* FIX_LJ_C */ #ifdef ENERGY_GROUPS egps_ishift = nbatParams.neg_2log; - egps_imask = (1<>1)*UNROLLJ; + egps_imask = (1 << egps_ishift) - 1; + egps_jshift = 2 * nbatParams.neg_2log; + egps_jmask = (1 << egps_jshift) - 1; + egps_jstride = (UNROLLJ >> 1) * UNROLLJ; /* Major division is over i-particle energy groups, determine the stride */ - Vstride_i = nbatParams.nenergrp*(1 << nbatParams.neg_2log)*egps_jstride; + Vstride_i = nbatParams.nenergrp * (1 << nbatParams.neg_2log) * egps_jstride; #endif l_cj = nbl->cj.data(); ninner = 0; - for (const nbnxn_ci_t &ciEntry : nbl->ci) + for (const nbnxn_ci_t& ciEntry : nbl->ci) { - ish = (ciEntry.shift & NBNXN_CI_SHIFT); - ish3 = ish*3; - cjind0 = ciEntry.cj_ind_start; - cjind1 = ciEntry.cj_ind_end; - ci = ciEntry.ci; - ci_sh = (ish == CENTRAL ? ci : -1); + ish = (ciEntry.shift & NBNXN_CI_SHIFT); + ish3 = ish * 3; + cjind0 = ciEntry.cj_ind_start; + cjind1 = ciEntry.cj_ind_end; + ci = ciEntry.ci; + ci_sh = (ish == CENTRAL ? ci : -1); shX_S = SimdReal(shiftvec[ish3]); - shY_S = SimdReal(shiftvec[ish3+1]); - shZ_S = SimdReal(shiftvec[ish3+2]); + shY_S = SimdReal(shiftvec[ish3 + 1]); + shZ_S = SimdReal(shiftvec[ish3 + 2]); #if UNROLLJ <= 4 - int sci = ci*STRIDE; - int scix = sci*DIM; -#if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM - int sci2 = sci*2; -#endif + int sci = ci * STRIDE; + int scix = sci * DIM; +# if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM + int sci2 = sci * 2; +# endif #else - int sci = (ci>>1)*STRIDE; - int scix = sci*DIM + (ci & 1)*(STRIDE>>1); -#if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM - int sci2 = sci*2 + (ci & 1)*(STRIDE>>1); -#endif - sci += (ci & 1)*(STRIDE>>1); + int sci = (ci >> 1) * STRIDE; + int scix = sci * DIM + (ci & 1) * (STRIDE >> 1); +# if defined LJ_COMB_LB || defined LJ_COMB_GEOM || defined LJ_EWALD_GEOM + int sci2 = sci * 2 + (ci & 1) * (STRIDE >> 1); +# endif + sci += (ci & 1) * (STRIDE >> 1); #endif /* We have 5 LJ/C combinations, but use only three inner loops, @@ -421,166 +421,167 @@ for (ia = 0; ia < UNROLLI; ia++) { - egp_ia = (egps_i >> (ia*egps_ishift)) & egps_imask; - vvdwtp[ia] = Vvdw + egp_ia*Vstride_i; - vctp[ia] = Vc + egp_ia*Vstride_i; + egp_ia = (egps_i >> (ia * egps_ishift)) & egps_imask; + vvdwtp[ia] = Vvdw + egp_ia * Vstride_i; + vctp[ia] = Vc + egp_ia * Vstride_i; } } #endif #ifdef CALC_ENERGIES -#ifdef LJ_EWALD_GEOM +# ifdef LJ_EWALD_GEOM gmx_bool do_self = TRUE; -#else +# else gmx_bool do_self = do_coul; -#endif -#if UNROLLJ == 4 +# endif +# if UNROLLJ == 4 if (do_self && l_cj[ciEntry.cj_ind_start].cj == ci_sh) -#endif -#if UNROLLJ == 2 - if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh<<1)) -#endif -#if UNROLLJ == 8 - if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh>>1)) -#endif - { - if (do_coul) - { - real Vc_sub_self; - int ia; - -#ifdef CALC_COUL_RF - Vc_sub_self = 0.5*ic->c_rf; -#endif -#ifdef CALC_COUL_TAB -#ifdef TAB_FDV0 - Vc_sub_self = 0.5*tab_coul_F[2]; -#else - Vc_sub_self = 0.5*tab_coul_V[0]; -#endif -#endif -#ifdef CALC_COUL_EWALD - /* beta/sqrt(pi) */ - Vc_sub_self = 0.5*ic->ewaldcoeff_q*M_2_SQRTPI; -#endif - - for (ia = 0; ia < UNROLLI; ia++) +# endif +# if UNROLLJ == 2 + if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh << 1)) +# endif +# if UNROLLJ == 8 + if (do_self && l_cj[ciEntry.cj_ind_start].cj == (ci_sh >> 1)) +# endif { - real qi; - - qi = q[sci+ia]; -#ifdef ENERGY_GROUPS - vctp[ia][((egps_i>>(ia*egps_ishift)) & egps_imask)*egps_jstride] -#else + if (do_coul) + { + real Vc_sub_self; + int ia; + +# ifdef CALC_COUL_RF + Vc_sub_self = 0.5 * ic->c_rf; +# endif +# ifdef CALC_COUL_TAB +# ifdef TAB_FDV0 + Vc_sub_self = 0.5 * tab_coul_F[2]; +# else + Vc_sub_self = 0.5 * tab_coul_V[0]; +# endif +# endif +# ifdef CALC_COUL_EWALD + /* beta/sqrt(pi) */ + Vc_sub_self = 0.5 * ic->ewaldcoeff_q * M_2_SQRTPI; +# endif + + for (ia = 0; ia < UNROLLI; ia++) + { + real qi; + + qi = q[sci + ia]; +# ifdef ENERGY_GROUPS + vctp[ia][((egps_i >> (ia * egps_ishift)) & egps_imask) * egps_jstride] +# else Vc[0] -#endif - -= facel*qi*qi*Vc_sub_self; +# endif + -= facel * qi * qi * Vc_sub_self; + } + } + +# ifdef LJ_EWALD_GEOM + { + int ia; + + for (ia = 0; ia < UNROLLI; ia++) + { + real c6_i; + + c6_i = nbatParams.nbfp[nbatParams.type[sci + ia] * (nbatParams.numTypes + 1) * 2] + / 6; +# ifdef ENERGY_GROUPS + vvdwtp[ia][((egps_i >> (ia * egps_ishift)) & egps_imask) * egps_jstride] +# else + Vvdw[0] +# endif + += 0.5 * c6_i * lj_ewaldcoeff6_6; + } + } +# endif /* LJ_EWALD_GEOM */ } - } - -#ifdef LJ_EWALD_GEOM - { - int ia; - - for (ia = 0; ia < UNROLLI; ia++) - { - real c6_i; - - c6_i = nbatParams.nbfp[nbatParams.type[sci+ia]*(nbatParams.numTypes + 1)*2]/6; -#ifdef ENERGY_GROUPS - vvdwtp[ia][((egps_i>>(ia*egps_ishift)) & egps_imask)*egps_jstride] -#else - Vvdw[0] -#endif - += 0.5*c6_i*lj_ewaldcoeff6_6; - } - } -#endif /* LJ_EWALD_GEOM */ - } #endif /* Load i atom data */ - int sciy = scix + STRIDE; - int sciz = sciy + STRIDE; - ix_S0 = SimdReal(x[scix]) + shX_S; - ix_S1 = SimdReal(x[scix+1]) + shX_S; - ix_S2 = SimdReal(x[scix+2]) + shX_S; - ix_S3 = SimdReal(x[scix+3]) + shX_S; - iy_S0 = SimdReal(x[sciy]) + shY_S; - iy_S1 = SimdReal(x[sciy+1]) + shY_S; - iy_S2 = SimdReal(x[sciy+2]) + shY_S; - iy_S3 = SimdReal(x[sciy+3]) + shY_S; - iz_S0 = SimdReal(x[sciz]) + shZ_S; - iz_S1 = SimdReal(x[sciz+1]) + shZ_S; - iz_S2 = SimdReal(x[sciz+2]) + shZ_S; - iz_S3 = SimdReal(x[sciz+3]) + shZ_S; + int sciy = scix + STRIDE; + int sciz = sciy + STRIDE; + ix_S0 = SimdReal(x[scix]) + shX_S; + ix_S1 = SimdReal(x[scix + 1]) + shX_S; + ix_S2 = SimdReal(x[scix + 2]) + shX_S; + ix_S3 = SimdReal(x[scix + 3]) + shX_S; + iy_S0 = SimdReal(x[sciy]) + shY_S; + iy_S1 = SimdReal(x[sciy + 1]) + shY_S; + iy_S2 = SimdReal(x[sciy + 2]) + shY_S; + iy_S3 = SimdReal(x[sciy + 3]) + shY_S; + iz_S0 = SimdReal(x[sciz]) + shZ_S; + iz_S1 = SimdReal(x[sciz + 1]) + shZ_S; + iz_S2 = SimdReal(x[sciz + 2]) + shZ_S; + iz_S3 = SimdReal(x[sciz + 3]) + shZ_S; if (do_coul) { - iq_S0 = SimdReal(facel*q[sci]); - iq_S1 = SimdReal(facel*q[sci+1]); - iq_S2 = SimdReal(facel*q[sci+2]); - iq_S3 = SimdReal(facel*q[sci+3]); + iq_S0 = SimdReal(facel * q[sci]); + iq_S1 = SimdReal(facel * q[sci + 1]); + iq_S2 = SimdReal(facel * q[sci + 2]); + iq_S3 = SimdReal(facel * q[sci + 3]); } #ifdef LJ_COMB_LB - hsig_i_S0 = SimdReal(ljc[sci2+0]); - hsig_i_S1 = SimdReal(ljc[sci2+1]); - hsig_i_S2 = SimdReal(ljc[sci2+2]); - hsig_i_S3 = SimdReal(ljc[sci2+3]); - seps_i_S0 = SimdReal(ljc[sci2+STRIDE+0]); - seps_i_S1 = SimdReal(ljc[sci2+STRIDE+1]); - seps_i_S2 = SimdReal(ljc[sci2+STRIDE+2]); - seps_i_S3 = SimdReal(ljc[sci2+STRIDE+3]); + hsig_i_S0 = SimdReal(ljc[sci2 + 0]); + hsig_i_S1 = SimdReal(ljc[sci2 + 1]); + hsig_i_S2 = SimdReal(ljc[sci2 + 2]); + hsig_i_S3 = SimdReal(ljc[sci2 + 3]); + seps_i_S0 = SimdReal(ljc[sci2 + STRIDE + 0]); + seps_i_S1 = SimdReal(ljc[sci2 + STRIDE + 1]); + seps_i_S2 = SimdReal(ljc[sci2 + STRIDE + 2]); + seps_i_S3 = SimdReal(ljc[sci2 + STRIDE + 3]); #else -#ifdef LJ_COMB_GEOM - SimdReal c6s_S0 = SimdReal(ljc[sci2+0]); - SimdReal c6s_S1 = SimdReal(ljc[sci2+1]); +# ifdef LJ_COMB_GEOM + SimdReal c6s_S0 = SimdReal(ljc[sci2 + 0]); + SimdReal c6s_S1 = SimdReal(ljc[sci2 + 1]); SimdReal c6s_S2, c6s_S3; if (!half_LJ) { - c6s_S2 = SimdReal(ljc[sci2+2]); - c6s_S3 = SimdReal(ljc[sci2+3]); + c6s_S2 = SimdReal(ljc[sci2 + 2]); + c6s_S3 = SimdReal(ljc[sci2 + 3]); } else { - c6s_S2 = setZero(); - c6s_S3 = setZero(); + c6s_S2 = setZero(); + c6s_S3 = setZero(); } - SimdReal c12s_S0 = SimdReal(ljc[sci2+STRIDE+0]); - SimdReal c12s_S1 = SimdReal(ljc[sci2+STRIDE+1]); + SimdReal c12s_S0 = SimdReal(ljc[sci2 + STRIDE + 0]); + SimdReal c12s_S1 = SimdReal(ljc[sci2 + STRIDE + 1]); SimdReal c12s_S2, c12s_S3; if (!half_LJ) { - c12s_S2 = SimdReal(ljc[sci2+STRIDE+2]); - c12s_S3 = SimdReal(ljc[sci2+STRIDE+3]); + c12s_S2 = SimdReal(ljc[sci2 + STRIDE + 2]); + c12s_S3 = SimdReal(ljc[sci2 + STRIDE + 3]); } else { - c12s_S2 = setZero(); - c12s_S3 = setZero(); + c12s_S2 = setZero(); + c12s_S3 = setZero(); } -#else - const int numTypes = nbatParams.numTypes; - const real *nbfp0 = nbfp_ptr + type[sci ]*numTypes*c_simdBestPairAlignment; - const real *nbfp1 = nbfp_ptr + type[sci+1]*numTypes*c_simdBestPairAlignment; - const real *nbfp2 = nullptr, *nbfp3 = nullptr; +# else + const int numTypes = nbatParams.numTypes; + const real* nbfp0 = nbfp_ptr + type[sci] * numTypes * c_simdBestPairAlignment; + const real* nbfp1 = nbfp_ptr + type[sci + 1] * numTypes * c_simdBestPairAlignment; + const real *nbfp2 = nullptr, *nbfp3 = nullptr; if (!half_LJ) { - nbfp2 = nbfp_ptr + type[sci+2]*numTypes*c_simdBestPairAlignment; - nbfp3 = nbfp_ptr + type[sci+3]*numTypes*c_simdBestPairAlignment; + nbfp2 = nbfp_ptr + type[sci + 2] * numTypes * c_simdBestPairAlignment; + nbfp3 = nbfp_ptr + type[sci + 3] * numTypes * c_simdBestPairAlignment; } -#endif +# endif #endif #ifdef LJ_EWALD_GEOM /* We need the geometrically combined C6 for the PME grid correction */ - SimdReal c6s_S0 = SimdReal(ljc[sci2+0]); - SimdReal c6s_S1 = SimdReal(ljc[sci2+1]); + SimdReal c6s_S0 = SimdReal(ljc[sci2 + 0]); + SimdReal c6s_S1 = SimdReal(ljc[sci2 + 1]); SimdReal c6s_S2, c6s_S3; if (!half_LJ) { - c6s_S2 = SimdReal(ljc[sci2+2]); - c6s_S3 = SimdReal(ljc[sci2+3]); + c6s_S2 = SimdReal(ljc[sci2 + 2]); + c6s_S3 = SimdReal(ljc[sci2 + 3]); } #endif @@ -591,18 +592,18 @@ #endif /* Clear i atom forces */ - fix_S0 = setZero(); - fix_S1 = setZero(); - fix_S2 = setZero(); - fix_S3 = setZero(); - fiy_S0 = setZero(); - fiy_S1 = setZero(); - fiy_S2 = setZero(); - fiy_S3 = setZero(); - fiz_S0 = setZero(); - fiz_S1 = setZero(); - fiz_S2 = setZero(); - fiz_S3 = setZero(); + fix_S0 = setZero(); + fix_S1 = setZero(); + fix_S2 = setZero(); + fix_S3 = setZero(); + fiy_S0 = setZero(); + fiy_S1 = setZero(); + fiy_S2 = setZero(); + fiy_S3 = setZero(); + fiz_S0 = setZero(); + fiz_S1 = setZero(); + fiz_S2 = setZero(); + fiz_S3 = setZero(); cjind = cjind0; @@ -663,15 +664,15 @@ ninner += cjind1 - cjind0; /* Add accumulated i-forces to the force array */ - real fShiftX = reduceIncr4ReturnSum(f+scix, fix_S0, fix_S1, fix_S2, fix_S3); - real fShiftY = reduceIncr4ReturnSum(f+sciy, fiy_S0, fiy_S1, fiy_S2, fiy_S3); - real fShiftZ = reduceIncr4ReturnSum(f+sciz, fiz_S0, fiz_S1, fiz_S2, fiz_S3); + real fShiftX = reduceIncr4ReturnSum(f + scix, fix_S0, fix_S1, fix_S2, fix_S3); + real fShiftY = reduceIncr4ReturnSum(f + sciy, fiy_S0, fiy_S1, fiy_S2, fiy_S3); + real fShiftZ = reduceIncr4ReturnSum(f + sciz, fiz_S0, fiz_S1, fiz_S2, fiz_S3); #ifdef CALC_SHIFTFORCES - fshift[ish3+0] += fShiftX; - fshift[ish3+1] += fShiftY; - fshift[ish3+2] += fShiftZ; + fshift[ish3 + 0] += fShiftX; + fshift[ish3 + 1] += fShiftY; + fshift[ish3 + 2] += fShiftZ; #endif #ifdef CALC_ENERGIES diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.cpp b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.cpp index c162aee5dd..d48a526f83 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.cpp +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.cpp @@ -43,16 +43,15 @@ #include "gromacs/utility/gmxassert.h" #ifdef GMX_NBNXN_SIMD_4XN -#define GMX_SIMD_J_UNROLL_SIZE 1 -#include "kernel_common.h" +# define GMX_SIMD_J_UNROLL_SIZE 1 +# include "kernel_common.h" #endif /* Prune a single nbnxn_pairtlist_t entry with distance rlistInner */ -void -nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner) +void nbnxn_kernel_prune_4xn(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner) { #ifdef GMX_NBNXN_SIMD_4XN using namespace gmx; @@ -61,16 +60,16 @@ nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, nbl->ci.resize(nbl->ciOuter.size()); nbl->cj.resize(nbl->cjOuter.size()); - const nbnxn_ci_t * gmx_restrict ciOuter = nbl->ciOuter.data(); - nbnxn_ci_t * gmx_restrict ciInner = nbl->ci.data(); + const nbnxn_ci_t* gmx_restrict ciOuter = nbl->ciOuter.data(); + nbnxn_ci_t* gmx_restrict ciInner = nbl->ci.data(); - const nbnxn_cj_t * gmx_restrict cjOuter = nbl->cjOuter.data(); - nbnxn_cj_t * gmx_restrict cjInner = nbl->cj.data(); + const nbnxn_cj_t* gmx_restrict cjOuter = nbl->cjOuter.data(); + nbnxn_cj_t* gmx_restrict cjInner = nbl->cj.data(); - const real * gmx_restrict shiftvec = shift_vec[0]; - const real * gmx_restrict x = nbat->x().data(); + const real* gmx_restrict shiftvec = shift_vec[0]; + const real* gmx_restrict x = nbat->x().data(); - const SimdReal rlist2_S(rlistInner*rlistInner); + const SimdReal rlist2_S(rlistInner * rlistInner); /* Initialize the new list count as empty and add pairs that are in range */ int nciInner = 0; @@ -78,7 +77,7 @@ nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, const int nciOuter = nbl->ciOuter.size(); for (int i = 0; i < nciOuter; i++) { - const nbnxn_ci_t * gmx_restrict ciEntry = &ciOuter[i]; + const nbnxn_ci_t* gmx_restrict ciEntry = &ciOuter[i]; /* Copy the original list entry to the pruned entry */ ciInner[nciInner].ci = ciEntry->ci; @@ -86,69 +85,69 @@ nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, ciInner[nciInner].cj_ind_start = ncjInner; /* Extract shift data */ - int ish = (ciEntry->shift & NBNXN_CI_SHIFT); - int ish3 = ish*3; - int ci = ciEntry->ci; - - SimdReal shX_S = SimdReal(shiftvec[ish3 ]); - SimdReal shY_S = SimdReal(shiftvec[ish3 + 1]); - SimdReal shZ_S = SimdReal(shiftvec[ish3 + 2]); - -#if UNROLLJ <= 4 - int scix = ci*STRIDE*DIM; -#else - int scix = (ci >> 1)*STRIDE*DIM + (ci & 1)*(STRIDE >> 1); -#endif + int ish = (ciEntry->shift & NBNXN_CI_SHIFT); + int ish3 = ish * 3; + int ci = ciEntry->ci; + + SimdReal shX_S = SimdReal(shiftvec[ish3]); + SimdReal shY_S = SimdReal(shiftvec[ish3 + 1]); + SimdReal shZ_S = SimdReal(shiftvec[ish3 + 2]); + +# if UNROLLJ <= 4 + int scix = ci * STRIDE * DIM; +# else + int scix = (ci >> 1) * STRIDE * DIM + (ci & 1) * (STRIDE >> 1); +# endif /* Load i atom data */ - int sciy = scix + STRIDE; - int sciz = sciy + STRIDE; - SimdReal ix_S0 = SimdReal(x[scix ]) + shX_S; - SimdReal ix_S1 = SimdReal(x[scix + 1]) + shX_S; - SimdReal ix_S2 = SimdReal(x[scix + 2]) + shX_S; - SimdReal ix_S3 = SimdReal(x[scix + 3]) + shX_S; - SimdReal iy_S0 = SimdReal(x[sciy ]) + shY_S; - SimdReal iy_S1 = SimdReal(x[sciy + 1]) + shY_S; - SimdReal iy_S2 = SimdReal(x[sciy + 2]) + shY_S; - SimdReal iy_S3 = SimdReal(x[sciy + 3]) + shY_S; - SimdReal iz_S0 = SimdReal(x[sciz ]) + shZ_S; - SimdReal iz_S1 = SimdReal(x[sciz + 1]) + shZ_S; - SimdReal iz_S2 = SimdReal(x[sciz + 2]) + shZ_S; - SimdReal iz_S3 = SimdReal(x[sciz + 3]) + shZ_S; + int sciy = scix + STRIDE; + int sciz = sciy + STRIDE; + SimdReal ix_S0 = SimdReal(x[scix]) + shX_S; + SimdReal ix_S1 = SimdReal(x[scix + 1]) + shX_S; + SimdReal ix_S2 = SimdReal(x[scix + 2]) + shX_S; + SimdReal ix_S3 = SimdReal(x[scix + 3]) + shX_S; + SimdReal iy_S0 = SimdReal(x[sciy]) + shY_S; + SimdReal iy_S1 = SimdReal(x[sciy + 1]) + shY_S; + SimdReal iy_S2 = SimdReal(x[sciy + 2]) + shY_S; + SimdReal iy_S3 = SimdReal(x[sciy + 3]) + shY_S; + SimdReal iz_S0 = SimdReal(x[sciz]) + shZ_S; + SimdReal iz_S1 = SimdReal(x[sciz + 1]) + shZ_S; + SimdReal iz_S2 = SimdReal(x[sciz + 2]) + shZ_S; + SimdReal iz_S3 = SimdReal(x[sciz + 3]) + shZ_S; for (int cjind = ciEntry->cj_ind_start; cjind < ciEntry->cj_ind_end; cjind++) { /* j-cluster index */ - int cj = cjOuter[cjind].cj; + int cj = cjOuter[cjind].cj; /* Atom indices (of the first atom in the cluster) */ -#if UNROLLJ == STRIDE - int aj = cj*UNROLLJ; - int ajx = aj*DIM; -#else - int ajx = (cj >> 1)*DIM*STRIDE + (cj & 1)*UNROLLJ; -#endif - int ajy = ajx + STRIDE; - int ajz = ajy + STRIDE; +# if UNROLLJ == STRIDE + int aj = cj * UNROLLJ; + int ajx = aj * DIM; +# else + int ajx = (cj >> 1) * DIM * STRIDE + (cj & 1) * UNROLLJ; +# endif + int ajy = ajx + STRIDE; + int ajz = ajy + STRIDE; /* load j atom coordinates */ - SimdReal jx_S = load(x + ajx); - SimdReal jy_S = load(x + ajy); - SimdReal jz_S = load(x + ajz); + SimdReal jx_S = load(x + ajx); + SimdReal jy_S = load(x + ajy); + SimdReal jz_S = load(x + ajz); /* Calculate distance */ - SimdReal dx_S0 = ix_S0 - jx_S; - SimdReal dy_S0 = iy_S0 - jy_S; - SimdReal dz_S0 = iz_S0 - jz_S; - SimdReal dx_S1 = ix_S1 - jx_S; - SimdReal dy_S1 = iy_S1 - jy_S; - SimdReal dz_S1 = iz_S1 - jz_S; - SimdReal dx_S2 = ix_S2 - jx_S; - SimdReal dy_S2 = iy_S2 - jy_S; - SimdReal dz_S2 = iz_S2 - jz_S; - SimdReal dx_S3 = ix_S3 - jx_S; - SimdReal dy_S3 = iy_S3 - jy_S; - SimdReal dz_S3 = iz_S3 - jz_S; + SimdReal dx_S0 = ix_S0 - jx_S; + SimdReal dy_S0 = iy_S0 - jy_S; + SimdReal dz_S0 = iz_S0 - jz_S; + SimdReal dx_S1 = ix_S1 - jx_S; + SimdReal dy_S1 = iy_S1 - jy_S; + SimdReal dz_S1 = iz_S1 - jz_S; + SimdReal dx_S2 = ix_S2 - jx_S; + SimdReal dy_S2 = iy_S2 - jy_S; + SimdReal dz_S2 = iz_S2 - jz_S; + SimdReal dx_S3 = ix_S3 - jx_S; + SimdReal dy_S3 = iy_S3 - jy_S; + SimdReal dz_S3 = iz_S3 - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ SimdReal rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); @@ -162,9 +161,9 @@ nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, SimdBool wco_S2 = (rsq_S2 < rlist2_S); SimdBool wco_S3 = (rsq_S3 < rlist2_S); - wco_S0 = wco_S0 || wco_S1; - wco_S2 = wco_S2 || wco_S3; - wco_S0 = wco_S0 || wco_S2; + wco_S0 = wco_S0 || wco_S1; + wco_S2 = wco_S2 || wco_S3; + wco_S0 = wco_S0 || wco_S2; /* Putting the assignment inside the conditional is slower */ cjInner[ncjInner] = cjOuter[cjind]; @@ -184,7 +183,7 @@ nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, nbl->ci.resize(nciInner); nbl->cj.resize(ncjInner); -#else /* GMX_NBNXN_SIMD_4XN */ +#else /* GMX_NBNXN_SIMD_4XN */ GMX_RELEASE_ASSERT(false, "4xN kernel called without 4xN support"); diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.h b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.h index 4e0ad9f956..ca6113dde9 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.h +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernel_prune.h @@ -54,8 +54,7 @@ struct NbnxnPairlistCpu; * Reads a cluster pairlist \p nbl->ciOuter, \p nbl->cjOuter and writes * all cluster pairs within \p rlistInner to \p nbl->ci, \p nbl->cj. */ -void -nbnxn_kernel_prune_4xn(NbnxnPairlistCpu * nbl, - const nbnxn_atomdata_t * nbat, - const rvec * gmx_restrict shift_vec, - real rlistInner); +void nbnxn_kernel_prune_4xn(NbnxnPairlistCpu* nbl, + const nbnxn_atomdata_t* nbat, + const rvec* gmx_restrict shift_vec, + real rlistInner); diff --git a/src/gromacs/nbnxm/kernels_simd_4xm/kernels.h b/src/gromacs/nbnxm/kernels_simd_4xm/kernels.h index afe1cff7bc..d95df1c768 100644 --- a/src/gromacs/nbnxm/kernels_simd_4xm/kernels.h +++ b/src/gromacs/nbnxm/kernels_simd_4xm/kernels.h @@ -42,99 +42,98 @@ /* Declare all the different kernel functions. */ -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJ_F_4xm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJ_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm; -nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJ_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJ_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm; +nbk_func_noener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm; - -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm; -nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm; +nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm; #ifdef INCLUDE_KERNELFUNCTION_TABLES @@ -143,135 +142,132 @@ nbk_func_ener nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm; * The minor index of the array goes over both the LJ combination rules, * which is only supported by plain cut-off, and the LJ switch/PME functions. */ -static p_nbk_func_noener nbnxm_kernel_noener_simd_4xm[coulktNR][vdwktNR] = -{ +static p_nbk_func_noener nbnxm_kernel_noener_simd_4xm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm, - nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm, - nbnxm_kernel_ElecRF_VdwLJ_F_4xm, - nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm, - nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_F_4xm, + nbnxm_kernel_ElecRF_VdwLJCombLB_F_4xm, + nbnxm_kernel_ElecRF_VdwLJ_F_4xm, + nbnxm_kernel_ElecRF_VdwLJFSw_F_4xm, + nbnxm_kernel_ElecRF_VdwLJPSw_F_4xm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_F_4xm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm, - nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJ_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_F_4xm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_F_4xm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_F_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_F_4xm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm, - nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm, - nbnxm_kernel_ElecEw_VdwLJ_F_4xm, - nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm, - nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_F_4xm, + nbnxm_kernel_ElecEw_VdwLJCombLB_F_4xm, + nbnxm_kernel_ElecEw_VdwLJ_F_4xm, + nbnxm_kernel_ElecEw_VdwLJFSw_F_4xm, + nbnxm_kernel_ElecEw_VdwLJPSw_F_4xm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_F_4xm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_F_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_4xm, }, }; -static p_nbk_func_ener nbnxm_kernel_ener_simd_4xm[coulktNR][vdwktNR] = -{ +static p_nbk_func_ener nbnxm_kernel_ener_simd_4xm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm, - nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm, - nbnxm_kernel_ElecRF_VdwLJ_VF_4xm, - nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm, - nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJCombLB_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJ_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJFSw_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJPSw_VF_4xm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VF_4xm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJ_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_VF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VF_4xm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VF_4xm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm, - nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm, - nbnxm_kernel_ElecEw_VdwLJ_VF_4xm, - nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm, - nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJCombLB_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJ_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJFSw_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJPSw_VF_4xm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VF_4xm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_4xm, }, }; -static p_nbk_func_ener nbnxm_kernel_energrp_simd_4xm[coulktNR][vdwktNR] = -{ +static p_nbk_func_ener nbnxm_kernel_energrp_simd_4xm[coulktNR][vdwktNR] = { { - nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm, - nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm, - nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm, - nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm, - nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm, - nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJCombLB_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJ_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJFSw_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJPSw_VgrpF_4xm, + nbnxm_kernel_ElecRF_VdwLJEwCombGeom_VgrpF_4xm, }, { - nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm, - nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJCombLB_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJ_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJFSw_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJPSw_VgrpF_4xm, + nbnxm_kernel_ElecQSTab_VdwLJEwCombGeom_VgrpF_4xm, }, { - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm, - nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJCombLB_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJ_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJFSw_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJPSw_VgrpF_4xm, + nbnxm_kernel_ElecQSTabTwinCut_VdwLJEwCombGeom_VgrpF_4xm, }, { - nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm, - nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm, - nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm, - nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm, - nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm, - nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJCombLB_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJ_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJFSw_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJPSw_VgrpF_4xm, + nbnxm_kernel_ElecEw_VdwLJEwCombGeom_VgrpF_4xm, }, { - nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm, - nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombGeom_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJCombLB_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJ_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJFSw_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJPSw_VgrpF_4xm, + nbnxm_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VgrpF_4xm, }, }; diff --git a/src/gromacs/nbnxm/nbnxm.cpp b/src/gromacs/nbnxm/nbnxm.cpp index 12f564b884..8cf4523d08 100644 --- a/src/gromacs/nbnxm/nbnxm.cpp +++ b/src/gromacs/nbnxm/nbnxm.cpp @@ -54,28 +54,27 @@ /*! \cond INTERNAL */ -void nbnxn_put_on_grid(nonbonded_verlet_t *nb_verlet, - const matrix box, - int gridIndex, - const rvec lowerCorner, - const rvec upperCorner, - const gmx::UpdateGroupsCog *updateGroupsCog, - gmx::Range atomRange, - real atomDensity, - gmx::ArrayRef atomInfo, - gmx::ArrayRef x, - int numAtomsMoved, - const int *move) +void nbnxn_put_on_grid(nonbonded_verlet_t* nb_verlet, + const matrix box, + int gridIndex, + const rvec lowerCorner, + const rvec upperCorner, + const gmx::UpdateGroupsCog* updateGroupsCog, + gmx::Range atomRange, + real atomDensity, + gmx::ArrayRef atomInfo, + gmx::ArrayRef x, + int numAtomsMoved, + const int* move) { - nb_verlet->pairSearch_->putOnGrid(box, gridIndex, lowerCorner, upperCorner, - updateGroupsCog, atomRange, atomDensity, - atomInfo, x, numAtomsMoved, move, + nb_verlet->pairSearch_->putOnGrid(box, gridIndex, lowerCorner, upperCorner, updateGroupsCog, + atomRange, atomDensity, atomInfo, x, numAtomsMoved, move, nb_verlet->nbat.get()); } /* Calls nbnxn_put_on_grid for all non-local domains */ -void nbnxn_put_on_grid_nonlocal(nonbonded_verlet_t *nbv, - const struct gmx_domdec_zones_t *zones, +void nbnxn_put_on_grid_nonlocal(nonbonded_verlet_t* nbv, + const struct gmx_domdec_zones_t* zones, gmx::ArrayRef atomInfo, gmx::ArrayRef x) { @@ -88,14 +87,9 @@ void nbnxn_put_on_grid_nonlocal(nonbonded_verlet_t *nbv, c1[d] = zones->size[zone].bb_x1[d]; } - nbnxn_put_on_grid(nbv, nullptr, - zone, c0, c1, - nullptr, - { zones->cg_range[zone], zones->cg_range[zone+1] }, - -1, - atomInfo, - x, - 0, nullptr); + nbnxn_put_on_grid(nbv, nullptr, zone, c0, c1, nullptr, + { zones->cg_range[zone], zones->cg_range[zone + 1] }, -1, atomInfo, x, 0, + nullptr); } } @@ -112,9 +106,9 @@ bool nonbonded_verlet_t::isDynamicPruningStepGpu(int64_t step) const gmx::ArrayRef nonbonded_verlet_t::getLocalAtomOrder() const { /* Return the atom order for the home cell (index 0) */ - const Nbnxm::Grid &grid = pairSearch_->gridSet().grids()[0]; + const Nbnxm::Grid& grid = pairSearch_->gridSet().grids()[0]; - const int numIndices = grid.atomIndexEnd() - grid.firstAtomInColumn(0); + const int numIndices = grid.atomIndexEnd() - grid.firstAtomInColumn(0); return gmx::constArrayRefFromArray(pairSearch_->gridSet().atomIndices().data(), numIndices); } @@ -124,39 +118,34 @@ void nonbonded_verlet_t::setLocalAtomOrder() pairSearch_->setLocalAtomOrder(); } -void nonbonded_verlet_t::setAtomProperties(const t_mdatoms &mdatoms, - gmx::ArrayRef atomInfo) +void nonbonded_verlet_t::setAtomProperties(const t_mdatoms& mdatoms, gmx::ArrayRef atomInfo) { nbnxn_atomdata_set(nbat.get(), pairSearch_->gridSet(), &mdatoms, atomInfo.data()); } -void nonbonded_verlet_t::convertCoordinates(const gmx::AtomLocality locality, - const bool fillLocal, - gmx::ArrayRef coordinates) +void nonbonded_verlet_t::convertCoordinates(const gmx::AtomLocality locality, + const bool fillLocal, + gmx::ArrayRef coordinates) { wallcycle_start(wcycle_, ewcNB_XF_BUF_OPS); wallcycle_sub_start(wcycle_, ewcsNB_X_BUF_OPS); nbnxn_atomdata_copy_x_to_nbat_x(pairSearch_->gridSet(), locality, fillLocal, - as_rvec_array(coordinates.data()), - nbat.get()); + as_rvec_array(coordinates.data()), nbat.get()); wallcycle_sub_stop(wcycle_, ewcsNB_X_BUF_OPS); wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS); } -void nonbonded_verlet_t::convertCoordinatesGpu(const gmx::AtomLocality locality, - const bool fillLocal, - DeviceBuffer d_x, - GpuEventSynchronizer *xReadyOnDevice) +void nonbonded_verlet_t::convertCoordinatesGpu(const gmx::AtomLocality locality, + const bool fillLocal, + DeviceBuffer d_x, + GpuEventSynchronizer* xReadyOnDevice) { wallcycle_start(wcycle_, ewcNB_XF_BUF_OPS); wallcycle_sub_start(wcycle_, ewcsNB_X_BUF_OPS); - nbnxn_atomdata_x_to_nbat_x_gpu(pairSearch_->gridSet(), locality, fillLocal, - gpu_nbv, - d_x, - xReadyOnDevice); + nbnxn_atomdata_x_to_nbat_x_gpu(pairSearch_->gridSet(), locality, fillLocal, gpu_nbv, d_x, xReadyOnDevice); wallcycle_sub_stop(wcycle_, ewcsNB_X_BUF_OPS); wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS); @@ -167,9 +156,8 @@ gmx::ArrayRef nonbonded_verlet_t::getGridIndices() const return pairSearch_->gridSet().cells(); } -void -nonbonded_verlet_t::atomdata_add_nbat_f_to_f(const gmx::AtomLocality locality, - gmx::ArrayRef force) +void nonbonded_verlet_t::atomdata_add_nbat_f_to_f(const gmx::AtomLocality locality, + gmx::ArrayRef force) { /* Skip the reduction if there was no short-range GPU work to do @@ -188,17 +176,17 @@ nonbonded_verlet_t::atomdata_add_nbat_f_to_f(const gmx::AtomLocality locality, wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS); } -void -nonbonded_verlet_t::atomdata_add_nbat_f_to_f_gpu(const gmx::AtomLocality locality, - DeviceBuffer totalForcesDevice, - void *forcesPmeDevice, - gmx::ArrayRef dependencyList, - bool useGpuFPmeReduction, - bool accumulateForce) +void nonbonded_verlet_t::atomdata_add_nbat_f_to_f_gpu(const gmx::AtomLocality locality, + DeviceBuffer totalForcesDevice, + void* forcesPmeDevice, + gmx::ArrayRef dependencyList, + bool useGpuFPmeReduction, + bool accumulateForce) { GMX_ASSERT((useGpuFPmeReduction == (forcesPmeDevice != nullptr)), - "GPU PME force reduction is only valid when a non-null GPU PME force pointer is available"); + "GPU PME force reduction is only valid when a non-null GPU PME force pointer is " + "available"); /* Skip the reduction if there was no short-range GPU work to do * (either NB or both NB and bonded work). */ @@ -210,25 +198,23 @@ nonbonded_verlet_t::atomdata_add_nbat_f_to_f_gpu(const gmx::AtomLocality wallcycle_start(wcycle_, ewcNB_XF_BUF_OPS); wallcycle_sub_start(wcycle_, ewcsNB_F_BUF_OPS); - reduceForcesGpu(locality, totalForcesDevice, pairSearch_->gridSet(), forcesPmeDevice, dependencyList, gpu_nbv, useGpuFPmeReduction, accumulateForce); + reduceForcesGpu(locality, totalForcesDevice, pairSearch_->gridSet(), forcesPmeDevice, + dependencyList, gpu_nbv, useGpuFPmeReduction, accumulateForce); wallcycle_sub_stop(wcycle_, ewcsNB_F_BUF_OPS); wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS); } -void -nonbonded_verlet_t::atomdata_init_add_nbat_f_to_f_gpu(GpuEventSynchronizer* const localReductionDone) +void nonbonded_verlet_t::atomdata_init_add_nbat_f_to_f_gpu(GpuEventSynchronizer* const localReductionDone) { wallcycle_start(wcycle_, ewcNB_XF_BUF_OPS); wallcycle_sub_start(wcycle_, ewcsNB_F_BUF_OPS); - const Nbnxm::GridSet &gridSet = pairSearch_->gridSet(); + const Nbnxm::GridSet& gridSet = pairSearch_->gridSet(); - Nbnxm::nbnxn_gpu_init_add_nbat_f_to_f(gridSet.cells().data(), - gpu_nbv, - gridSet.numRealAtomsTotal(), - localReductionDone); + Nbnxm::nbnxn_gpu_init_add_nbat_f_to_f(gridSet.cells().data(), gpu_nbv, + gridSet.numRealAtomsTotal(), localReductionDone); wallcycle_sub_stop(wcycle_, ewcsNB_F_BUF_OPS); wallcycle_stop(wcycle_, ewcNB_XF_BUF_OPS); @@ -244,14 +230,12 @@ real nonbonded_verlet_t::pairlistOuterRadius() const return pairlistSets_->params().rlistOuter; } -void nonbonded_verlet_t::changePairlistRadii(real rlistOuter, - real rlistInner) +void nonbonded_verlet_t::changePairlistRadii(real rlistOuter, real rlistInner) { pairlistSets_->changePairlistRadii(rlistOuter, rlistInner); } -void -nonbonded_verlet_t::atomdata_init_copy_x_to_nbat_x_gpu() +void nonbonded_verlet_t::atomdata_init_copy_x_to_nbat_x_gpu() { Nbnxm::nbnxn_gpu_init_x_to_nbat_x(pairSearch_->gridSet(), gpu_nbv); } diff --git a/src/gromacs/nbnxm/nbnxm.h b/src/gromacs/nbnxm/nbnxm.h index c42ee24fce..4574167c18 100644 --- a/src/gromacs/nbnxm/nbnxm.h +++ b/src/gromacs/nbnxm/nbnxm.h @@ -155,7 +155,7 @@ namespace gmx class ForceWithShiftForces; class MDLogger; class UpdateGroupsCog; -} +} // namespace gmx namespace Nbnxm { @@ -190,7 +190,7 @@ enum class EwaldExclusionType : int struct KernelSetup { //! The non-bonded type, also affects the pairlist construction kernel - KernelType kernelType = KernelType::NotSet; + KernelType kernelType = KernelType::NotSet; //! Ewald exclusion computation handling type, currently only used for CPU EwaldExclusionType ewaldExclusionType = EwaldExclusionType::NotSet; }; @@ -200,246 +200,226 @@ struct KernelSetup * \param [in] kernelType nonbonded kernel type, takes values from the nbnxn_kernel_type enum * \returns a string identifying the kernel corresponding to the type passed as argument */ -const char *lookup_kernel_name(Nbnxm::KernelType kernelType); +const char* lookup_kernel_name(Nbnxm::KernelType kernelType); } // namespace Nbnxm /*! \brief Flag to tell the nonbonded kernels whether to clear the force output buffers */ -enum { - enbvClearFNo, enbvClearFYes +enum +{ + enbvClearFNo, + enbvClearFYes }; /*! \libinternal * \brief Top-level non-bonded data structure for the Verlet-type cut-off scheme. */ struct nonbonded_verlet_t { - public: - //! Constructs an object from its components - nonbonded_verlet_t(std::unique_ptr pairlistSets, - std::unique_ptr pairSearch, - std::unique_ptr nbat, - const Nbnxm::KernelSetup &kernelSetup, - gmx_nbnxn_gpu_t *gpu_nbv, - gmx_wallcycle *wcycle); - - ~nonbonded_verlet_t(); - - //! Returns whether a GPU is use for the non-bonded calculations - bool useGpu() const - { - return kernelSetup_.kernelType == Nbnxm::KernelType::Gpu8x8x8; - } - - //! Returns whether a GPU is emulated for the non-bonded calculations - bool emulateGpu() const - { - return kernelSetup_.kernelType == Nbnxm::KernelType::Cpu8x8x8_PlainC; - } - - //! Return whether the pairlist is of simple, CPU type - bool pairlistIsSimple() const - { - return !useGpu() && !emulateGpu(); - } - - //! Initialize the pair list sets, TODO this should be private - void initPairlistSets(bool haveMultipleDomains); - - //! Returns the order of the local atoms on the grid - gmx::ArrayRef getLocalAtomOrder() const; - - //! Sets the order of the local atoms to the order grid atom ordering - void setLocalAtomOrder(); - - //! Returns the index position of the atoms on the search grid - gmx::ArrayRef getGridIndices() const; - - //! Constructs the pairlist for the given locality - void constructPairlist(gmx::InteractionLocality iLocality, - const t_blocka *excl, - int64_t step, - t_nrnb *nrnb); - - //! Updates all the atom properties in Nbnxm - void setAtomProperties(const t_mdatoms &mdatoms, - gmx::ArrayRef atomInfo); - - /*!\brief Convert the coordinates to NBNXM format for the given locality. - * - * The API function for the transformation of the coordinates from one layout to another. - * - * \param[in] locality Whether coordinates for local or non-local atoms should be transformed. - * \param[in] fillLocal If the coordinates for filler particles should be zeroed. - * \param[in] coordinates Coordinates in plain rvec format to be transformed. - */ - void convertCoordinates(gmx::AtomLocality locality, - bool fillLocal, - gmx::ArrayRef coordinates); - - /*!\brief Convert the coordinates to NBNXM format on the GPU for the given locality - * - * The API function for the transformation of the coordinates from one layout to another in the GPU memory. - * - * \param[in] locality Whether coordinates for local or non-local atoms should be transformed. - * \param[in] fillLocal If the coordinates for filler particles should be zeroed. - * \param[in] d_x GPU coordinates buffer in plain rvec format to be transformed. - * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory. - */ - void convertCoordinatesGpu(gmx::AtomLocality locality, - bool fillLocal, - DeviceBuffer d_x, - GpuEventSynchronizer *xReadyOnDevice); - - //! Init for GPU version of setup coordinates in Nbnxm - void atomdata_init_copy_x_to_nbat_x_gpu(); - - //! Sync the nonlocal GPU stream with dependent tasks in the local queue. - void insertNonlocalGpuDependency(gmx::InteractionLocality interactionLocality); - - //! Returns a reference to the pairlist sets - const PairlistSets &pairlistSets() const - { - return *pairlistSets_; - } - - //! Returns whether step is a dynamic list pruning step, for CPU lists - bool isDynamicPruningStepCpu(int64_t step) const; - - //! Returns whether step is a dynamic list pruning step, for GPU lists - bool isDynamicPruningStepGpu(int64_t step) const; - - //! Dispatches the dynamic pruning kernel for the given locality, for CPU lists - void dispatchPruneKernelCpu(gmx::InteractionLocality iLocality, - const rvec *shift_vec); - - //! Dispatches the dynamic pruning kernel for GPU lists - void dispatchPruneKernelGpu(int64_t step); - - //! \brief Executes the non-bonded kernel of the GPU or launches it on the GPU - void dispatchNonbondedKernel(gmx::InteractionLocality iLocality, - const interaction_const_t &ic, - const gmx::StepWorkload &stepWork, - int clearF, - const t_forcerec &fr, - gmx_enerdata_t *enerd, - t_nrnb *nrnb); - - //! Executes the non-bonded free-energy kernel, always runs on the CPU - void dispatchFreeEnergyKernel(gmx::InteractionLocality iLocality, - const t_forcerec *fr, - rvec x[], - gmx::ForceWithShiftForces *forceWithShiftForces, - const t_mdatoms &mdatoms, - t_lambda *fepvals, - real *lambda, - gmx_enerdata_t *enerd, - const gmx::StepWorkload &stepWork, - t_nrnb *nrnb); - - /*! \brief Add the forces stored in nbat to f, zeros the forces in nbat - * \param [in] locality Local or non-local - * \param [inout] force Force to be added to - */ - void atomdata_add_nbat_f_to_f(gmx::AtomLocality locality, - gmx::ArrayRef force); - - /*! \brief Add the forces stored in nbat to total force using GPU buffer opse - * - * \param [in] locality Local or non-local - * \param [in,out] totalForcesDevice Force to be added to - * \param [in] forcesPmeDevice Device buffer with PME forces - * \param[in] dependencyList List of synchronizers that represent the dependencies the reduction task needs to sync on. - * \param [in] useGpuFPmeReduction Whether PME forces should be added - * \param [in] accumulateForce If the total force buffer already contains data - */ - void atomdata_add_nbat_f_to_f_gpu(gmx::AtomLocality locality, - DeviceBuffer totalForcesDevice, - void *forcesPmeDevice, - gmx::ArrayRef dependencyList, - bool useGpuFPmeReduction, - bool accumulateForce); - - /*! \brief Outer body of function to perform initialization for F buffer operations on GPU. - * - * \param localReductionDone Pointer to an event synchronizer that marks the completion of the local f buffer ops kernel. - */ - void atomdata_init_add_nbat_f_to_f_gpu(GpuEventSynchronizer* localReductionDone); - - /*! \brief Wait for non-local copy of coordinate buffer from device to host */ - void wait_nonlocal_x_copy_D2H_done(); - - /*! \brief return GPU pointer to f in rvec format */ - void* get_gpu_frvec(); - - /*! \brief Ensure local stream waits for non-local stream */ - void stream_local_wait_for_nonlocal(); - - //! Return the kernel setup - const Nbnxm::KernelSetup &kernelSetup() const - { - return kernelSetup_; - } - - //! Returns the outer radius for the pair list - real pairlistInnerRadius() const; - - //! Returns the outer radius for the pair list - real pairlistOuterRadius() const; - - //! Changes the pair-list outer and inner radius - void changePairlistRadii(real rlistOuter, - real rlistInner); - - //! Set up internal flags that indicate what type of short-range work there is. - void setupGpuShortRangeWork(const gmx::GpuBonded *gpuBonded, - const gmx::InteractionLocality iLocality) - { - if (useGpu() && !emulateGpu()) - { - Nbnxm::setupGpuShortRangeWork(gpu_nbv, gpuBonded, iLocality); - } - } - - //! Returns true if there is GPU short-range work for the given atom locality. - bool haveGpuShortRangeWork(const gmx::AtomLocality aLocality) +public: + //! Constructs an object from its components + nonbonded_verlet_t(std::unique_ptr pairlistSets, + std::unique_ptr pairSearch, + std::unique_ptr nbat, + const Nbnxm::KernelSetup& kernelSetup, + gmx_nbnxn_gpu_t* gpu_nbv, + gmx_wallcycle* wcycle); + + ~nonbonded_verlet_t(); + + //! Returns whether a GPU is use for the non-bonded calculations + bool useGpu() const { return kernelSetup_.kernelType == Nbnxm::KernelType::Gpu8x8x8; } + + //! Returns whether a GPU is emulated for the non-bonded calculations + bool emulateGpu() const + { + return kernelSetup_.kernelType == Nbnxm::KernelType::Cpu8x8x8_PlainC; + } + + //! Return whether the pairlist is of simple, CPU type + bool pairlistIsSimple() const { return !useGpu() && !emulateGpu(); } + + //! Initialize the pair list sets, TODO this should be private + void initPairlistSets(bool haveMultipleDomains); + + //! Returns the order of the local atoms on the grid + gmx::ArrayRef getLocalAtomOrder() const; + + //! Sets the order of the local atoms to the order grid atom ordering + void setLocalAtomOrder(); + + //! Returns the index position of the atoms on the search grid + gmx::ArrayRef getGridIndices() const; + + //! Constructs the pairlist for the given locality + void constructPairlist(gmx::InteractionLocality iLocality, const t_blocka* excl, int64_t step, t_nrnb* nrnb); + + //! Updates all the atom properties in Nbnxm + void setAtomProperties(const t_mdatoms& mdatoms, gmx::ArrayRef atomInfo); + + /*!\brief Convert the coordinates to NBNXM format for the given locality. + * + * The API function for the transformation of the coordinates from one layout to another. + * + * \param[in] locality Whether coordinates for local or non-local atoms should be + * transformed. \param[in] fillLocal If the coordinates for filler particles should be + * zeroed. \param[in] coordinates Coordinates in plain rvec format to be transformed. + */ + void convertCoordinates(gmx::AtomLocality locality, bool fillLocal, gmx::ArrayRef coordinates); + + /*!\brief Convert the coordinates to NBNXM format on the GPU for the given locality + * + * The API function for the transformation of the coordinates from one layout to another in the GPU memory. + * + * \param[in] locality Whether coordinates for local or non-local atoms should be transformed. + * \param[in] fillLocal If the coordinates for filler particles should be zeroed. + * \param[in] d_x GPU coordinates buffer in plain rvec format to be transformed. + * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory. + */ + void convertCoordinatesGpu(gmx::AtomLocality locality, + bool fillLocal, + DeviceBuffer d_x, + GpuEventSynchronizer* xReadyOnDevice); + + //! Init for GPU version of setup coordinates in Nbnxm + void atomdata_init_copy_x_to_nbat_x_gpu(); + + //! Sync the nonlocal GPU stream with dependent tasks in the local queue. + void insertNonlocalGpuDependency(gmx::InteractionLocality interactionLocality); + + //! Returns a reference to the pairlist sets + const PairlistSets& pairlistSets() const { return *pairlistSets_; } + + //! Returns whether step is a dynamic list pruning step, for CPU lists + bool isDynamicPruningStepCpu(int64_t step) const; + + //! Returns whether step is a dynamic list pruning step, for GPU lists + bool isDynamicPruningStepGpu(int64_t step) const; + + //! Dispatches the dynamic pruning kernel for the given locality, for CPU lists + void dispatchPruneKernelCpu(gmx::InteractionLocality iLocality, const rvec* shift_vec); + + //! Dispatches the dynamic pruning kernel for GPU lists + void dispatchPruneKernelGpu(int64_t step); + + //! \brief Executes the non-bonded kernel of the GPU or launches it on the GPU + void dispatchNonbondedKernel(gmx::InteractionLocality iLocality, + const interaction_const_t& ic, + const gmx::StepWorkload& stepWork, + int clearF, + const t_forcerec& fr, + gmx_enerdata_t* enerd, + t_nrnb* nrnb); + + //! Executes the non-bonded free-energy kernel, always runs on the CPU + void dispatchFreeEnergyKernel(gmx::InteractionLocality iLocality, + const t_forcerec* fr, + rvec x[], + gmx::ForceWithShiftForces* forceWithShiftForces, + const t_mdatoms& mdatoms, + t_lambda* fepvals, + real* lambda, + gmx_enerdata_t* enerd, + const gmx::StepWorkload& stepWork, + t_nrnb* nrnb); + + /*! \brief Add the forces stored in nbat to f, zeros the forces in nbat + * \param [in] locality Local or non-local + * \param [inout] force Force to be added to + */ + void atomdata_add_nbat_f_to_f(gmx::AtomLocality locality, gmx::ArrayRef force); + + /*! \brief Add the forces stored in nbat to total force using GPU buffer opse + * + * \param [in] locality Local or non-local + * \param [in,out] totalForcesDevice Force to be added to + * \param [in] forcesPmeDevice Device buffer with PME forces + * \param[in] dependencyList List of synchronizers that represent the dependencies the reduction task needs to sync on. + * \param [in] useGpuFPmeReduction Whether PME forces should be added + * \param [in] accumulateForce If the total force buffer already contains data + */ + void atomdata_add_nbat_f_to_f_gpu(gmx::AtomLocality locality, + DeviceBuffer totalForcesDevice, + void* forcesPmeDevice, + gmx::ArrayRef dependencyList, + bool useGpuFPmeReduction, + bool accumulateForce); + + /*! \brief Outer body of function to perform initialization for F buffer operations on GPU. + * + * \param localReductionDone Pointer to an event synchronizer that marks the completion of the local f buffer ops kernel. + */ + void atomdata_init_add_nbat_f_to_f_gpu(GpuEventSynchronizer* localReductionDone); + + /*! \brief Wait for non-local copy of coordinate buffer from device to host */ + void wait_nonlocal_x_copy_D2H_done(); + + /*! \brief return GPU pointer to f in rvec format */ + void* get_gpu_frvec(); + + /*! \brief Ensure local stream waits for non-local stream */ + void stream_local_wait_for_nonlocal(); + + //! Return the kernel setup + const Nbnxm::KernelSetup& kernelSetup() const { return kernelSetup_; } + + //! Returns the outer radius for the pair list + real pairlistInnerRadius() const; + + //! Returns the outer radius for the pair list + real pairlistOuterRadius() const; + + //! Changes the pair-list outer and inner radius + void changePairlistRadii(real rlistOuter, real rlistInner); + + //! Set up internal flags that indicate what type of short-range work there is. + void setupGpuShortRangeWork(const gmx::GpuBonded* gpuBonded, const gmx::InteractionLocality iLocality) + { + if (useGpu() && !emulateGpu()) { - return ((useGpu() && !emulateGpu()) && - Nbnxm::haveGpuShortRangeWork(gpu_nbv, aLocality)); + Nbnxm::setupGpuShortRangeWork(gpu_nbv, gpuBonded, iLocality); } - - // TODO: Make all data members private - public: - //! All data related to the pair lists - std::unique_ptr pairlistSets_; - //! Working data for constructing the pairlists - std::unique_ptr pairSearch_; - //! Atom data - std::unique_ptr nbat; - private: - //! The non-bonded setup, also affects the pairlist construction kernel - Nbnxm::KernelSetup kernelSetup_; - //! \brief Pointer to wallcycle structure. - gmx_wallcycle *wcycle_; - public: - //! GPU Nbnxm data, only used with a physical GPU (TODO: use unique_ptr) - gmx_nbnxn_gpu_t *gpu_nbv; + } + + //! Returns true if there is GPU short-range work for the given atom locality. + bool haveGpuShortRangeWork(const gmx::AtomLocality aLocality) + { + return ((useGpu() && !emulateGpu()) && Nbnxm::haveGpuShortRangeWork(gpu_nbv, aLocality)); + } + + // TODO: Make all data members private +public: + //! All data related to the pair lists + std::unique_ptr pairlistSets_; + //! Working data for constructing the pairlists + std::unique_ptr pairSearch_; + //! Atom data + std::unique_ptr nbat; + +private: + //! The non-bonded setup, also affects the pairlist construction kernel + Nbnxm::KernelSetup kernelSetup_; + //! \brief Pointer to wallcycle structure. + gmx_wallcycle* wcycle_; + +public: + //! GPU Nbnxm data, only used with a physical GPU (TODO: use unique_ptr) + gmx_nbnxn_gpu_t* gpu_nbv; }; namespace Nbnxm { /*! \brief Creates an Nbnxm object */ -std::unique_ptr -init_nb_verlet(const gmx::MDLogger &mdlog, - gmx_bool bFEP_NonBonded, - const t_inputrec *ir, - const t_forcerec *fr, - const t_commrec *cr, - const gmx_hw_info_t &hardwareInfo, - const gmx_device_info_t *deviceInfo, - const gmx_mtop_t *mtop, - matrix box, - gmx_wallcycle *wcycle); +std::unique_ptr init_nb_verlet(const gmx::MDLogger& mdlog, + gmx_bool bFEP_NonBonded, + const t_inputrec* ir, + const t_forcerec* fr, + const t_commrec* cr, + const gmx_hw_info_t& hardwareInfo, + const gmx_device_info_t* deviceInfo, + const gmx_mtop_t* mtop, + matrix box, + gmx_wallcycle* wcycle); } // namespace Nbnxm @@ -470,26 +450,26 @@ init_nb_verlet(const gmx::MDLogger &mdlog, * \param[in] numAtomsMoved The number of atoms that will move to another domain, pass 0 without DD * \param[in] move Move flags for atoms, pass nullptr without DD */ -void nbnxn_put_on_grid(nonbonded_verlet_t *nb_verlet, - const matrix box, - int gridIndex, - const rvec lowerCorner, - const rvec upperCorner, - const gmx::UpdateGroupsCog *updateGroupsCog, - gmx::Range atomRange, - real atomDensity, - gmx::ArrayRef atomInfo, - gmx::ArrayRef x, - int numAtomsMoved, - const int *move); +void nbnxn_put_on_grid(nonbonded_verlet_t* nb_verlet, + const matrix box, + int gridIndex, + const rvec lowerCorner, + const rvec upperCorner, + const gmx::UpdateGroupsCog* updateGroupsCog, + gmx::Range atomRange, + real atomDensity, + gmx::ArrayRef atomInfo, + gmx::ArrayRef x, + int numAtomsMoved, + const int* move); /*! \brief As nbnxn_put_on_grid, but for the non-local atoms * * with domain decomposition. Should be called after calling * nbnxn_search_put_on_grid for the local atoms / home zone. */ -void nbnxn_put_on_grid_nonlocal(nonbonded_verlet_t *nb_verlet, - const struct gmx_domdec_zones_t *zones, +void nbnxn_put_on_grid_nonlocal(nonbonded_verlet_t* nb_verlet, + const struct gmx_domdec_zones_t* zones, gmx::ArrayRef atomInfo, gmx::ArrayRef x); diff --git a/src/gromacs/nbnxm/nbnxm_geometry.cpp b/src/gromacs/nbnxm/nbnxm_geometry.cpp index ff1f6ee1d1..5a999e355c 100644 --- a/src/gromacs/nbnxm/nbnxm_geometry.cpp +++ b/src/gromacs/nbnxm/nbnxm_geometry.cpp @@ -46,28 +46,25 @@ /* Clusters at the cut-off only increase rlist by 60% of their size */ static constexpr real c_nbnxnRlistIncreaseOutsideFactor = 0.6; -real nbnxn_get_rlist_effective_inc(const int jClusterSize, - const real atomDensity) +real nbnxn_get_rlist_effective_inc(const int jClusterSize, const real atomDensity) { /* We should get this from the setup, but currently it's the same for * all setups, including GPUs. */ - const real iClusterSize = c_nbnxnCpuIClusterSize; + const real iClusterSize = c_nbnxnCpuIClusterSize; - const real iVolumeIncrease = (iClusterSize - 1)/atomDensity; - const real jVolumeIncrease = (jClusterSize - 1)/atomDensity; + const real iVolumeIncrease = (iClusterSize - 1) / atomDensity; + const real jVolumeIncrease = (jClusterSize - 1) / atomDensity; - return c_nbnxnRlistIncreaseOutsideFactor*std::cbrt(iVolumeIncrease + - jVolumeIncrease); + return c_nbnxnRlistIncreaseOutsideFactor * std::cbrt(iVolumeIncrease + jVolumeIncrease); } -real nbnxn_get_rlist_effective_inc(const int clusterSize, - const gmx::RVec &averageClusterBoundingBox) +real nbnxn_get_rlist_effective_inc(const int clusterSize, const gmx::RVec& averageClusterBoundingBox) { /* The average length of the diagonal of a sub cell */ - const real diagonal = std::sqrt(norm2(averageClusterBoundingBox)); + const real diagonal = std::sqrt(norm2(averageClusterBoundingBox)); - const real volumeRatio = (clusterSize - 1.0_real)/clusterSize; + const real volumeRatio = (clusterSize - 1.0_real) / clusterSize; - return c_nbnxnRlistIncreaseOutsideFactor*gmx::square(volumeRatio)*0.5_real*diagonal; + return c_nbnxnRlistIncreaseOutsideFactor * gmx::square(volumeRatio) * 0.5_real * diagonal; } diff --git a/src/gromacs/nbnxm/nbnxm_geometry.h b/src/gromacs/nbnxm/nbnxm_geometry.h index 5c0e217ffd..80a049ba1d 100644 --- a/src/gromacs/nbnxm/nbnxm_geometry.h +++ b/src/gromacs/nbnxm/nbnxm_geometry.h @@ -68,44 +68,32 @@ namespace Nbnxm { /* The nbnxn i-cluster size in atoms for each nbnxn kernel type */ -static constexpr gmx::EnumerationArray IClusterSizePerKernelType = -{ { - 0, - c_nbnxnCpuIClusterSize, - c_nbnxnCpuIClusterSize, - c_nbnxnCpuIClusterSize, - c_nbnxnGpuClusterSize, - c_nbnxnGpuClusterSize - } }; +static constexpr gmx::EnumerationArray IClusterSizePerKernelType = { + { 0, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, + c_nbnxnGpuClusterSize, c_nbnxnGpuClusterSize } +}; /* The nbnxn j-cluster size in atoms for each nbnxn kernel type */ -static constexpr gmx::EnumerationArray JClusterSizePerKernelType = -{ { - 0, - c_nbnxnCpuIClusterSize, +static constexpr gmx::EnumerationArray JClusterSizePerKernelType = { + { 0, c_nbnxnCpuIClusterSize, #if GMX_SIMD - GMX_SIMD_REAL_WIDTH, - GMX_SIMD_REAL_WIDTH/2, + GMX_SIMD_REAL_WIDTH, GMX_SIMD_REAL_WIDTH / 2, #else - 0, - 0, + 0, 0, #endif - c_nbnxnGpuClusterSize, - c_nbnxnGpuClusterSize - } }; + c_nbnxnGpuClusterSize, c_nbnxnGpuClusterSize } +}; /* Returns whether the pair-list corresponding to nb_kernel_type is simple */ static inline bool kernelTypeUsesSimplePairlist(const KernelType kernelType) { - return (kernelType == KernelType::Cpu4x4_PlainC || - kernelType == KernelType::Cpu4xN_Simd_4xN || - kernelType == KernelType::Cpu4xN_Simd_2xNN); + return (kernelType == KernelType::Cpu4x4_PlainC || kernelType == KernelType::Cpu4xN_Simd_4xN + || kernelType == KernelType::Cpu4xN_Simd_2xNN); } static inline bool kernelTypeIsSimd(const KernelType kernelType) { - return (kernelType == KernelType::Cpu4xN_Simd_4xN || - kernelType == KernelType::Cpu4xN_Simd_2xNN); + return (kernelType == KernelType::Cpu4xN_Simd_4xN || kernelType == KernelType::Cpu4xN_Simd_2xNN); } } // namespace Nbnxm @@ -119,15 +107,13 @@ static inline bool kernelTypeIsSimd(const KernelType kernelType) * the physical dimensions of the clusters, use the next function * for more accurate results */ -real nbnxn_get_rlist_effective_inc(int jClusterSize, - real atomDensity); +real nbnxn_get_rlist_effective_inc(int jClusterSize, real atomDensity); /* Returns the effective list radius of the pair-list * * Due to the cluster size the effective pair-list is longer than * that of a simple atom pair-list. This function gives the extra distance. */ -real nbnxn_get_rlist_effective_inc(int clusterSize, - const gmx::RVec &averageClusterBoundingBox); +real nbnxn_get_rlist_effective_inc(int clusterSize, const gmx::RVec& averageClusterBoundingBox); #endif diff --git a/src/gromacs/nbnxm/nbnxm_gpu.h b/src/gromacs/nbnxm/nbnxm_gpu.h index 34c1ef4865..ecae0d39d2 100644 --- a/src/gromacs/nbnxm/nbnxm_gpu.h +++ b/src/gromacs/nbnxm/nbnxm_gpu.h @@ -61,7 +61,7 @@ namespace gmx { class GpuBonded; class StepWorkload; -} +} // namespace gmx namespace Nbnxm { @@ -79,9 +79,9 @@ class Grid; * \param [in] aloc Atom locality flag. */ GPU_FUNC_QUALIFIER -void gpu_copy_xq_to_gpu(gmx_nbnxn_gpu_t gmx_unused *nb, - const struct nbnxn_atomdata_t gmx_unused *nbdata, - gmx::AtomLocality gmx_unused aloc) GPU_FUNC_TERM; +void gpu_copy_xq_to_gpu(gmx_nbnxn_gpu_t gmx_unused* nb, + const struct nbnxn_atomdata_t gmx_unused* nbdata, + gmx::AtomLocality gmx_unused aloc) GPU_FUNC_TERM; /*! \brief * Launch asynchronously the nonbonded force calculations. @@ -94,8 +94,8 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_gpu_t gmx_unused *nb, * */ GPU_FUNC_QUALIFIER -void gpu_launch_kernel(gmx_nbnxn_gpu_t gmx_unused *nb, - const gmx::StepWorkload gmx_unused &stepWork, +void gpu_launch_kernel(gmx_nbnxn_gpu_t gmx_unused* nb, + const gmx::StepWorkload gmx_unused& stepWork, gmx::InteractionLocality gmx_unused iloc) GPU_FUNC_TERM; /*! \brief @@ -134,19 +134,19 @@ void gpu_launch_kernel(gmx_nbnxn_gpu_t gmx_unused *nb, * \param [in] numParts Number of parts the pair list is split into in the rolling kernel. */ GPU_FUNC_QUALIFIER -void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t gmx_unused *nb, - gmx::InteractionLocality gmx_unused iloc, - int gmx_unused numParts) GPU_FUNC_TERM; +void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t gmx_unused* nb, + gmx::InteractionLocality gmx_unused iloc, + int gmx_unused numParts) GPU_FUNC_TERM; /*! \brief * Launch asynchronously the download of short-range forces from the GPU * (and energies/shift forces if required). */ GPU_FUNC_QUALIFIER -void gpu_launch_cpyback(gmx_nbnxn_gpu_t gmx_unused *nb, - nbnxn_atomdata_t gmx_unused *nbatom, - const gmx::StepWorkload gmx_unused &stepWork, - gmx::AtomLocality gmx_unused aloc) GPU_FUNC_TERM; +void gpu_launch_cpyback(gmx_nbnxn_gpu_t gmx_unused* nb, + nbnxn_atomdata_t gmx_unused* nbatom, + const gmx::StepWorkload gmx_unused& stepWork, + gmx::AtomLocality gmx_unused aloc) GPU_FUNC_TERM; /*! \brief Attempts to complete nonbonded GPU task. * @@ -186,14 +186,14 @@ void gpu_launch_cpyback(gmx_nbnxn_gpu_t gmx_unused *nb, * \returns True if the nonbonded tasks associated with \p aloc locality have completed */ GPU_FUNC_QUALIFIER -bool gpu_try_finish_task(gmx_nbnxn_gpu_t gmx_unused *nb, - const gmx::StepWorkload gmx_unused &stepWork, - gmx::AtomLocality gmx_unused aloc, - real gmx_unused *e_lj, - real gmx_unused *e_el, - gmx::ArrayRef gmx_unused shiftForces, - GpuTaskCompletion gmx_unused completionKind, - gmx_wallcycle gmx_unused *wcycle) GPU_FUNC_TERM_WITH_RETURN(false); +bool gpu_try_finish_task(gmx_nbnxn_gpu_t gmx_unused* nb, + const gmx::StepWorkload gmx_unused& stepWork, + gmx::AtomLocality gmx_unused aloc, + real gmx_unused* e_lj, + real gmx_unused* e_el, + gmx::ArrayRef gmx_unused shiftForces, + GpuTaskCompletion gmx_unused completionKind, + gmx_wallcycle gmx_unused* wcycle) GPU_FUNC_TERM_WITH_RETURN(false); /*! \brief Completes the nonbonded GPU task blocking until GPU tasks and data * transfers to finish. @@ -210,23 +210,24 @@ bool gpu_try_finish_task(gmx_nbnxn_gpu_t gmx_unused *nb, * \param[out] shiftForces Shift forces buffer to accumulate into * \param[out] wcycle Pointer to wallcycle data structure */ GPU_FUNC_QUALIFIER -float gpu_wait_finish_task(gmx_nbnxn_gpu_t gmx_unused *nb, - const gmx::StepWorkload gmx_unused &stepWork, - gmx::AtomLocality gmx_unused aloc, - real gmx_unused *e_lj, - real gmx_unused *e_el, - gmx::ArrayRef gmx_unused shiftForces, - gmx_wallcycle gmx_unused *wcycle) GPU_FUNC_TERM_WITH_RETURN(0.0); +float gpu_wait_finish_task(gmx_nbnxn_gpu_t gmx_unused* nb, + const gmx::StepWorkload gmx_unused& stepWork, + gmx::AtomLocality gmx_unused aloc, + real gmx_unused* e_lj, + real gmx_unused* e_el, + gmx::ArrayRef gmx_unused shiftForces, + gmx_wallcycle gmx_unused* wcycle) GPU_FUNC_TERM_WITH_RETURN(0.0); /*! \brief Selects the Ewald kernel type, analytical or tabulated, single or twin cut-off. */ GPU_FUNC_QUALIFIER -int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t gmx_unused &ic) GPU_FUNC_TERM_WITH_RETURN(-1); +int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t gmx_unused& ic) + GPU_FUNC_TERM_WITH_RETURN(-1); /*! \brief Initialization for X buffer operations on GPU. * Called on the NS step and performs (re-)allocations and memory copies. !*/ CUDA_FUNC_QUALIFIER -void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet gmx_unused &gridSet, - gmx_nbnxn_gpu_t gmx_unused *gpu_nbv) CUDA_FUNC_TERM; +void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet gmx_unused& gridSet, + gmx_nbnxn_gpu_t gmx_unused* gpu_nbv) CUDA_FUNC_TERM; /*! \brief X buffer operations on GPU: performs conversion from rvec to nb format. * @@ -234,28 +235,28 @@ void nbnxn_gpu_init_x_to_nbat_x(const Nbnxm::GridSet gmx_unused &gridSet, * \param[in] setFillerCoords If the filler coordinates are used. * \param[in,out] gpu_nbv The nonbonded data GPU structure. * \param[in] d_x Device-side coordinates in plain rvec format. - * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in the device memory. - * \param[in] locality Copy coordinates for local or non-local atoms. + * \param[in] xReadyOnDevice Event synchronizer indicating that the coordinates are ready in + * the device memory. \param[in] locality Copy coordinates for local or non-local atoms. * \param[in] gridId Index of the grid being converted. * \param[in] numColumnsMax Maximum number of columns in the grid. */ CUDA_FUNC_QUALIFIER -void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid gmx_unused &grid, - bool gmx_unused setFillerCoords, - gmx_nbnxn_gpu_t gmx_unused *gpu_nbv, - DeviceBuffer gmx_unused d_x, - GpuEventSynchronizer gmx_unused *xReadyOnDevice, - gmx::AtomLocality gmx_unused locality, - int gmx_unused gridId, - int gmx_unused numColumnsMax) CUDA_FUNC_TERM; +void nbnxn_gpu_x_to_nbat_x(const Nbnxm::Grid gmx_unused& grid, + bool gmx_unused setFillerCoords, + gmx_nbnxn_gpu_t gmx_unused* gpu_nbv, + DeviceBuffer gmx_unused d_x, + GpuEventSynchronizer gmx_unused* xReadyOnDevice, + gmx::AtomLocality gmx_unused locality, + int gmx_unused gridId, + int gmx_unused numColumnsMax) CUDA_FUNC_TERM; /*! \brief Sync the nonlocal stream with dependent tasks in the local queue. * \param[in] nb The nonbonded data GPU structure * \param[in] interactionLocality Local or NonLocal sync point */ CUDA_FUNC_QUALIFIER -void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_gpu_t gmx_unused *nb, - gmx::InteractionLocality gmx_unused interactionLocality) CUDA_FUNC_TERM; +void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_gpu_t gmx_unused* nb, + gmx::InteractionLocality gmx_unused interactionLocality) CUDA_FUNC_TERM; /*! \brief Set up internal flags that indicate what type of short-range work there is. * @@ -270,9 +271,9 @@ void nbnxnInsertNonlocalGpuDependency(const gmx_nbnxn_gpu_t gmx_unused *nb, * \param[in] iLocality Interaction locality identifier */ GPU_FUNC_QUALIFIER -void setupGpuShortRangeWork(gmx_nbnxn_gpu_t gmx_unused *nb, - const gmx::GpuBonded gmx_unused *gpuBonded, - gmx::InteractionLocality gmx_unused iLocality) GPU_FUNC_TERM; +void setupGpuShortRangeWork(gmx_nbnxn_gpu_t gmx_unused* nb, + const gmx::GpuBonded gmx_unused* gpuBonded, + gmx::InteractionLocality gmx_unused iLocality) GPU_FUNC_TERM; /*! \brief Returns true if there is GPU short-range work for the given atom locality. * @@ -284,15 +285,15 @@ void setupGpuShortRangeWork(gmx_nbnxn_gpu_t gmx_unused *nb, * \param[in] aLocality Atom locality identifier */ GPU_FUNC_QUALIFIER -bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t gmx_unused *nb, - gmx::AtomLocality gmx_unused aLocality) GPU_FUNC_TERM_WITH_RETURN(false); +bool haveGpuShortRangeWork(const gmx_nbnxn_gpu_t gmx_unused* nb, gmx::AtomLocality gmx_unused aLocality) + GPU_FUNC_TERM_WITH_RETURN(false); /*! \brief Initialization for F buffer operations on GPU */ CUDA_FUNC_QUALIFIER -void nbnxn_gpu_init_add_nbat_f_to_f(const int gmx_unused *cell, - gmx_nbnxn_gpu_t gmx_unused *gpu_nbv, - int gmx_unused natoms_total, - GpuEventSynchronizer gmx_unused *localReductionDone) CUDA_FUNC_TERM; +void nbnxn_gpu_init_add_nbat_f_to_f(const int gmx_unused* cell, + gmx_nbnxn_gpu_t gmx_unused* gpu_nbv, + int gmx_unused natoms_total, + GpuEventSynchronizer gmx_unused* localReductionDone) CUDA_FUNC_TERM; /*! \brief Force buffer operations on GPU. * @@ -311,33 +312,33 @@ void nbnxn_gpu_init_add_nbat_f_to_f(const int gmx_unused *cell * */ CUDA_FUNC_QUALIFIER -void nbnxn_gpu_add_nbat_f_to_f(gmx::AtomLocality gmx_unused atomLocality, - DeviceBuffer gmx_unused totalForcesDevice, - gmx_nbnxn_gpu_t gmx_unused *gpu_nbv, - void gmx_unused *pmeForcesDevice, - gmx::ArrayRef gmx_unused dependencyList, - int gmx_unused atomStart, - int gmx_unused numAtoms, - bool gmx_unused useGpuFPmeReduction, - bool gmx_unused accumulateForce) CUDA_FUNC_TERM; +void nbnxn_gpu_add_nbat_f_to_f(gmx::AtomLocality gmx_unused atomLocality, + DeviceBuffer gmx_unused totalForcesDevice, + gmx_nbnxn_gpu_t gmx_unused* gpu_nbv, + void gmx_unused* pmeForcesDevice, + gmx::ArrayRef gmx_unused dependencyList, + int gmx_unused atomStart, + int gmx_unused numAtoms, + bool gmx_unused useGpuFPmeReduction, + bool gmx_unused accumulateForce) CUDA_FUNC_TERM; /*! \brief sync CPU thread on coordinate copy to device * \param[in] nb The nonbonded data GPU structure */ CUDA_FUNC_QUALIFIER -void nbnxn_wait_x_on_device(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM; +void nbnxn_wait_x_on_device(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM; /*! \brief Wait for non-local copy of coordinate buffer from device to host * \param[in] nb The nonbonded data GPU structure */ CUDA_FUNC_QUALIFIER -void nbnxn_wait_nonlocal_x_copy_D2H_done(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM; +void nbnxn_wait_nonlocal_x_copy_D2H_done(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM; /*! \brief Ensure local stream waits for non-local stream * \param[in] nb The nonbonded data GPU structure */ CUDA_FUNC_QUALIFIER -void nbnxn_stream_local_wait_for_nonlocal(gmx_nbnxn_gpu_t gmx_unused *nb) CUDA_FUNC_TERM; +void nbnxn_stream_local_wait_for_nonlocal(gmx_nbnxn_gpu_t gmx_unused* nb) CUDA_FUNC_TERM; } // namespace Nbnxm #endif diff --git a/src/gromacs/nbnxm/nbnxm_setup.cpp b/src/gromacs/nbnxm/nbnxm_setup.cpp index 05a976dbfc..89a3477639 100644 --- a/src/gromacs/nbnxm/nbnxm_setup.cpp +++ b/src/gromacs/nbnxm/nbnxm_setup.cpp @@ -82,15 +82,18 @@ enum class NonbondedResource : int * If the return value is FALSE and fplog/cr != NULL, prints a fallback * message to fplog/stderr. */ -static gmx_bool nbnxn_simd_supported(const gmx::MDLogger &mdlog, - const t_inputrec *ir) +static gmx_bool nbnxn_simd_supported(const gmx::MDLogger& mdlog, const t_inputrec* ir) { if (ir->vdwtype == evdwPME && ir->ljpme_combination_rule == eljpmeLB) { /* LJ PME with LB combination rule does 7 mesh operations. * This so slow that we don't compile SIMD non-bonded kernels * for that. */ - GMX_LOG(mdlog.warning).asParagraph().appendText("LJ-PME with Lorentz-Berthelot is not supported with SIMD kernels, falling back to plain C kernels"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "LJ-PME with Lorentz-Berthelot is not supported with SIMD kernels, falling " + "back to plain C kernels"); return FALSE; } @@ -98,9 +101,8 @@ static gmx_bool nbnxn_simd_supported(const gmx::MDLogger &mdlog, } /*! \brief Returns the most suitable CPU kernel type and Ewald handling */ -static KernelSetup -pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, - const gmx_hw_info_t gmx_unused &hardwareInfo) +static KernelSetup pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused* ir, + const gmx_hw_info_t gmx_unused& hardwareInfo) { KernelSetup kernelSetup; @@ -137,8 +139,7 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, */ kernelSetup.kernelType = KernelType::Cpu4xN_Simd_4xN; - if (!GMX_SIMD_HAVE_FMA && (EEL_PME_EWALD(ir->coulombtype) || - EVDW_PME(ir->vdwtype))) + if (!GMX_SIMD_HAVE_FMA && (EEL_PME_EWALD(ir->coulombtype) || EVDW_PME(ir->vdwtype))) { /* We have Ewald kernels without FMA (Intel Sandy/Ivy Bridge). * There are enough instructions to make 2x(4+4) efficient. @@ -151,7 +152,7 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, /* One 256-bit FMA per cycle makes 2xNN faster */ kernelSetup.kernelType = KernelType::Cpu4xN_Simd_2xNN; } -#endif /* GMX_NBNXN_SIMD_2XNN && GMX_NBNXN_SIMD_4XN */ +#endif /* GMX_NBNXN_SIMD_2XNN && GMX_NBNXN_SIMD_4XN */ if (getenv("GMX_NBNXN_SIMD_4XN") != nullptr) @@ -159,7 +160,9 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, #ifdef GMX_NBNXN_SIMD_4XN kernelSetup.kernelType = KernelType::Cpu4xN_Simd_4xN; #else - gmx_fatal(FARGS, "SIMD 4xN kernels requested, but GROMACS has been compiled without support for these kernels"); + gmx_fatal(FARGS, + "SIMD 4xN kernels requested, but GROMACS has been compiled without support " + "for these kernels"); #endif } if (getenv("GMX_NBNXN_SIMD_2XNN") != nullptr) @@ -167,7 +170,9 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, #ifdef GMX_NBNXN_SIMD_2XNN kernelSetup.kernelType = KernelType::Cpu4xN_Simd_2xNN; #else - gmx_fatal(FARGS, "SIMD 2x(N+N) kernels requested, but GROMACS has been compiled without support for these kernels"); + gmx_fatal(FARGS, + "SIMD 2x(N+N) kernels requested, but GROMACS has been compiled without " + "support for these kernels"); #endif } @@ -182,10 +187,9 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, */ if ( #if GMX_SIMD - (GMX_SIMD_REAL_WIDTH >= 8 || - (GMX_SIMD_REAL_WIDTH >= 4 && GMX_SIMD_HAVE_FMA && !GMX_DOUBLE)) && + (GMX_SIMD_REAL_WIDTH >= 8 || (GMX_SIMD_REAL_WIDTH >= 4 && GMX_SIMD_HAVE_FMA && !GMX_DOUBLE)) && #endif - !hardwareInfo.haveAmdZen1Cpu) + !hardwareInfo.haveAmdZen1Cpu) { kernelSetup.ewaldExclusionType = EwaldExclusionType::Analytical; } @@ -201,23 +205,18 @@ pick_nbnxn_kernel_cpu(const t_inputrec gmx_unused *ir, { kernelSetup.ewaldExclusionType = EwaldExclusionType::Analytical; } - } return kernelSetup; } -const char *lookup_kernel_name(const KernelType kernelType) +const char* lookup_kernel_name(const KernelType kernelType) { - const char *returnvalue = nullptr; + const char* returnvalue = nullptr; switch (kernelType) { - case KernelType::NotSet: - returnvalue = "not set"; - break; - case KernelType::Cpu4x4_PlainC: - returnvalue = "plain C"; - break; + case KernelType::NotSet: returnvalue = "not set"; break; + case KernelType::Cpu4x4_PlainC: returnvalue = "plain C"; break; case KernelType::Cpu4xN_Simd_4xN: case KernelType::Cpu4xN_Simd_2xNN: #if GMX_SIMD @@ -226,23 +225,21 @@ const char *lookup_kernel_name(const KernelType kernelType) returnvalue = "not available"; #endif // GMX_SIMD break; - case KernelType::Gpu8x8x8: returnvalue = "GPU"; break; + case KernelType::Gpu8x8x8: returnvalue = "GPU"; break; case KernelType::Cpu8x8x8_PlainC: returnvalue = "plain C"; break; - default: - gmx_fatal(FARGS, "Illegal kernel type selected"); + default: gmx_fatal(FARGS, "Illegal kernel type selected"); } return returnvalue; }; /*! \brief Returns the most suitable kernel type and Ewald handling */ -static KernelSetup -pick_nbnxn_kernel(const gmx::MDLogger &mdlog, - gmx_bool use_simd_kernels, - const gmx_hw_info_t &hardwareInfo, - const NonbondedResource &nonbondedResource, - const t_inputrec *ir, - gmx_bool bDoNonbonded) +static KernelSetup pick_nbnxn_kernel(const gmx::MDLogger& mdlog, + gmx_bool use_simd_kernels, + const gmx_hw_info_t& hardwareInfo, + const NonbondedResource& nonbondedResource, + const t_inputrec* ir, + gmx_bool bDoNonbonded) { KernelSetup kernelSetup; @@ -253,7 +250,9 @@ pick_nbnxn_kernel(const gmx::MDLogger &mdlog, if (bDoNonbonded) { - GMX_LOG(mdlog.warning).asParagraph().appendText("Emulating a GPU run on the CPU (slow)"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText("Emulating a GPU run on the CPU (slow)"); } } else if (nonbondedResource == NonbondedResource::Gpu) @@ -263,8 +262,7 @@ pick_nbnxn_kernel(const gmx::MDLogger &mdlog, } else { - if (use_simd_kernels && - nbnxn_simd_supported(mdlog, ir)) + if (use_simd_kernels && nbnxn_simd_supported(mdlog, ir)) { kernelSetup = pick_nbnxn_kernel_cpu(ir, hardwareInfo); } @@ -277,24 +275,27 @@ pick_nbnxn_kernel(const gmx::MDLogger &mdlog, if (bDoNonbonded) { - GMX_LOG(mdlog.info).asParagraph().appendTextFormatted( - "Using %s %dx%d nonbonded short-range kernels", - lookup_kernel_name(kernelSetup.kernelType), - IClusterSizePerKernelType[kernelSetup.kernelType], - JClusterSizePerKernelType[kernelSetup.kernelType]); - - if (KernelType::Cpu4x4_PlainC == kernelSetup.kernelType || - KernelType::Cpu8x8x8_PlainC == kernelSetup.kernelType) + GMX_LOG(mdlog.info) + .asParagraph() + .appendTextFormatted("Using %s %dx%d nonbonded short-range kernels", + lookup_kernel_name(kernelSetup.kernelType), + IClusterSizePerKernelType[kernelSetup.kernelType], + JClusterSizePerKernelType[kernelSetup.kernelType]); + + if (KernelType::Cpu4x4_PlainC == kernelSetup.kernelType + || KernelType::Cpu8x8x8_PlainC == kernelSetup.kernelType) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "WARNING: Using the slow %s kernels. This should\n" - "not happen during routine usage on supported platforms.", - lookup_kernel_name(kernelSetup.kernelType)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "WARNING: Using the slow %s kernels. This should\n" + "not happen during routine usage on supported platforms.", + lookup_kernel_name(kernelSetup.kernelType)); } } - GMX_RELEASE_ASSERT(kernelSetup.kernelType != KernelType::NotSet && - kernelSetup.ewaldExclusionType != EwaldExclusionType::NotSet, + GMX_RELEASE_ASSERT(kernelSetup.kernelType != KernelType::NotSet + && kernelSetup.ewaldExclusionType != EwaldExclusionType::NotSet, "All kernel setup parameters should be set here"); return kernelSetup; @@ -302,19 +303,17 @@ pick_nbnxn_kernel(const gmx::MDLogger &mdlog, } // namespace Nbnxm -PairlistSets::PairlistSets(const PairlistParams &pairlistParams, +PairlistSets::PairlistSets(const PairlistParams& pairlistParams, const bool haveMultipleDomains, const int minimumIlistCountForGpuBalancing) : params_(pairlistParams), minimumIlistCountForGpuBalancing_(minimumIlistCountForGpuBalancing) { - localSet_ = std::make_unique(gmx::InteractionLocality::Local, - params_); + localSet_ = std::make_unique(gmx::InteractionLocality::Local, params_); if (haveMultipleDomains) { - nonlocalSet_ = std::make_unique(gmx::InteractionLocality::NonLocal, - params_); + nonlocalSet_ = std::make_unique(gmx::InteractionLocality::NonLocal, params_); } } @@ -322,18 +321,19 @@ namespace Nbnxm { /*! \brief Gets and returns the minimum i-list count for balacing based on the GPU used or env.var. when set */ -static int getMinimumIlistCountForGpuBalancing(gmx_nbnxn_gpu_t *nbnxmGpu) +static int getMinimumIlistCountForGpuBalancing(gmx_nbnxn_gpu_t* nbnxmGpu) { int minimumIlistCount; - if (const char *env = getenv("GMX_NB_MIN_CI")) + if (const char* env = getenv("GMX_NB_MIN_CI")) { - char *end; + char* end; minimumIlistCount = strtol(env, &end, 10); if (!end || (*end != 0) || minimumIlistCount < 0) { - gmx_fatal(FARGS, "Invalid value passed in GMX_NB_MIN_CI=%s, non-negative integer required", env); + gmx_fatal(FARGS, + "Invalid value passed in GMX_NB_MIN_CI=%s, non-negative integer required", env); } if (debug) @@ -347,7 +347,9 @@ static int getMinimumIlistCountForGpuBalancing(gmx_nbnxn_gpu_t *nbnxmGpu) minimumIlistCount = gpu_min_ci_balanced(nbnxmGpu); if (debug) { - fprintf(debug, "Neighbor-list balancing parameter: %d (auto-adjusted to the number of GPU multi-processors)\n", + fprintf(debug, + "Neighbor-list balancing parameter: %d (auto-adjusted to the number of GPU " + "multi-processors)\n", minimumIlistCount); } } @@ -355,22 +357,22 @@ static int getMinimumIlistCountForGpuBalancing(gmx_nbnxn_gpu_t *nbnxmGpu) return minimumIlistCount; } -std::unique_ptr -init_nb_verlet(const gmx::MDLogger &mdlog, - gmx_bool bFEP_NonBonded, - const t_inputrec *ir, - const t_forcerec *fr, - const t_commrec *cr, - const gmx_hw_info_t &hardwareInfo, - const gmx_device_info_t *deviceInfo, - const gmx_mtop_t *mtop, - matrix box, - gmx_wallcycle *wcycle) +std::unique_ptr init_nb_verlet(const gmx::MDLogger& mdlog, + gmx_bool bFEP_NonBonded, + const t_inputrec* ir, + const t_forcerec* fr, + const t_commrec* cr, + const gmx_hw_info_t& hardwareInfo, + const gmx_device_info_t* deviceInfo, + const gmx_mtop_t* mtop, + matrix box, + gmx_wallcycle* wcycle) { - const bool emulateGpu = (getenv("GMX_EMULATE_GPU") != nullptr); - const bool useGpu = deviceInfo != nullptr; + const bool emulateGpu = (getenv("GMX_EMULATE_GPU") != nullptr); + const bool useGpu = deviceInfo != nullptr; - GMX_RELEASE_ASSERT(!(emulateGpu && useGpu), "When GPU emulation is active, there cannot be a GPU assignment"); + GMX_RELEASE_ASSERT(!(emulateGpu && useGpu), + "When GPU emulation is active, there cannot be a GPU assignment"); NonbondedResource nonbondedResource; if (useGpu) @@ -386,26 +388,20 @@ init_nb_verlet(const gmx::MDLogger &mdlog, nonbondedResource = NonbondedResource::Cpu; } - Nbnxm::KernelSetup kernelSetup = - pick_nbnxn_kernel(mdlog, fr->use_simd_kernels, hardwareInfo, - nonbondedResource, ir, - fr->bNonbonded); + Nbnxm::KernelSetup kernelSetup = pick_nbnxn_kernel(mdlog, fr->use_simd_kernels, hardwareInfo, + nonbondedResource, ir, fr->bNonbonded); - const bool haveMultipleDomains = (DOMAINDECOMP(cr) && cr->dd->nnodes > 1); + const bool haveMultipleDomains = (DOMAINDECOMP(cr) && cr->dd->nnodes > 1); - PairlistParams pairlistParams(kernelSetup.kernelType, - bFEP_NonBonded, - ir->rlist, - havePPDomainDecomposition(cr)); + PairlistParams pairlistParams(kernelSetup.kernelType, bFEP_NonBonded, ir->rlist, + havePPDomainDecomposition(cr)); - setupDynamicPairlistPruning(mdlog, ir, mtop, box, fr->ic, - &pairlistParams); + setupDynamicPairlistPruning(mdlog, ir, mtop, box, fr->ic, &pairlistParams); - int enbnxninitcombrule; - if (fr->ic->vdwtype == evdwCUT && - (fr->ic->vdw_modifier == eintmodNONE || - fr->ic->vdw_modifier == eintmodPOTSHIFT) && - getenv("GMX_NO_LJ_COMB_RULE") == nullptr) + int enbnxninitcombrule; + if (fr->ic->vdwtype == evdwCUT + && (fr->ic->vdw_modifier == eintmodNONE || fr->ic->vdw_modifier == eintmodPOTSHIFT) + && getenv("GMX_NO_LJ_COMB_RULE") == nullptr) { /* Plain LJ cut-off: we can optimize with combination rules */ enbnxninitcombrule = enbnxninitcombruleDETECT; @@ -430,9 +426,9 @@ init_nb_verlet(const gmx::MDLogger &mdlog, auto pinPolicy = (useGpu ? gmx::PinningPolicy::PinnedIfSupported : gmx::PinningPolicy::CannotBePinned); - auto nbat = std::make_unique(pinPolicy); + auto nbat = std::make_unique(pinPolicy); - int mimimumNumEnergyGroupNonbonded = ir->opts.ngener; + int mimimumNumEnergyGroupNonbonded = ir->opts.ngener; if (ir->opts.ngener - ir->nwall == 1) { /* We have only one non-wall energy group, we do not need energy group @@ -441,61 +437,41 @@ init_nb_verlet(const gmx::MDLogger &mdlog, */ mimimumNumEnergyGroupNonbonded = 1; } - nbnxn_atomdata_init(mdlog, - nbat.get(), - kernelSetup.kernelType, - enbnxninitcombrule, - fr->ntype, fr->nbfp, - mimimumNumEnergyGroupNonbonded, + nbnxn_atomdata_init(mdlog, nbat.get(), kernelSetup.kernelType, enbnxninitcombrule, fr->ntype, + fr->nbfp, mimimumNumEnergyGroupNonbonded, (useGpu || emulateGpu) ? 1 : gmx_omp_nthreads_get(emntNonbonded)); - gmx_nbnxn_gpu_t *gpu_nbv = nullptr; + gmx_nbnxn_gpu_t* gpu_nbv = nullptr; int minimumIlistCountForGpuBalancing = 0; if (useGpu) { /* init the NxN GPU data; the last argument tells whether we'll have * both local and non-local NB calculation on GPU */ - gpu_nbv = gpu_init(deviceInfo, - fr->ic, - pairlistParams, - nbat.get(), - cr->nodeid, - haveMultipleDomains); + gpu_nbv = gpu_init(deviceInfo, fr->ic, pairlistParams, nbat.get(), cr->nodeid, haveMultipleDomains); minimumIlistCountForGpuBalancing = getMinimumIlistCountForGpuBalancing(gpu_nbv); } - auto pairlistSets = - std::make_unique(pairlistParams, - haveMultipleDomains, - minimumIlistCountForGpuBalancing); - - auto pairSearch = - std::make_unique(ir->ePBC, - EI_TPI(ir->eI), - DOMAINDECOMP(cr) ? &cr->dd->nc : nullptr, - DOMAINDECOMP(cr) ? domdec_zones(cr->dd) : nullptr, - pairlistParams.pairlistType, - bFEP_NonBonded, - gmx_omp_nthreads_get(emntPairsearch), - pinPolicy); - - return std::make_unique(std::move(pairlistSets), - std::move(pairSearch), - std::move(nbat), - kernelSetup, - gpu_nbv, - wcycle); + auto pairlistSets = std::make_unique(pairlistParams, haveMultipleDomains, + minimumIlistCountForGpuBalancing); + + auto pairSearch = std::make_unique( + ir->ePBC, EI_TPI(ir->eI), DOMAINDECOMP(cr) ? &cr->dd->nc : nullptr, + DOMAINDECOMP(cr) ? domdec_zones(cr->dd) : nullptr, pairlistParams.pairlistType, + bFEP_NonBonded, gmx_omp_nthreads_get(emntPairsearch), pinPolicy); + + return std::make_unique(std::move(pairlistSets), std::move(pairSearch), + std::move(nbat), kernelSetup, gpu_nbv, wcycle); } } // namespace Nbnxm -nonbonded_verlet_t::nonbonded_verlet_t(std::unique_ptr pairlistSets, - std::unique_ptr pairSearch, - std::unique_ptr nbat_in, - const Nbnxm::KernelSetup &kernelSetup, - gmx_nbnxn_gpu_t *gpu_nbv_ptr, - gmx_wallcycle *wcycle) : +nonbonded_verlet_t::nonbonded_verlet_t(std::unique_ptr pairlistSets, + std::unique_ptr pairSearch, + std::unique_ptr nbat_in, + const Nbnxm::KernelSetup& kernelSetup, + gmx_nbnxn_gpu_t* gpu_nbv_ptr, + gmx_wallcycle* wcycle) : pairlistSets_(std::move(pairlistSets)), pairSearch_(std::move(pairSearch)), nbat(std::move(nbat_in)), diff --git a/src/gromacs/nbnxm/nbnxm_simd.h b/src/gromacs/nbnxm/nbnxm_simd.h index 640cc4554f..79c92f59fc 100644 --- a/src/gromacs/nbnxm/nbnxm_simd.h +++ b/src/gromacs/nbnxm/nbnxm_simd.h @@ -46,16 +46,16 @@ * 8-way SIMD: 4x4 setup, works with AVX-256 in single precision * 16-way SIMD: 4x8 setup, works with Intel MIC in single precision */ -#if GMX_SIMD_REAL_WIDTH == 2 || GMX_SIMD_REAL_WIDTH == 4 || GMX_SIMD_REAL_WIDTH == 8 -#define GMX_NBNXN_SIMD_4XN -#endif -#if GMX_SIMD_REAL_WIDTH == 8 || GMX_SIMD_REAL_WIDTH == 16 -#define GMX_NBNXN_SIMD_2XNN -#endif +# if GMX_SIMD_REAL_WIDTH == 2 || GMX_SIMD_REAL_WIDTH == 4 || GMX_SIMD_REAL_WIDTH == 8 +# define GMX_NBNXN_SIMD_4XN +# endif +# if GMX_SIMD_REAL_WIDTH == 8 || GMX_SIMD_REAL_WIDTH == 16 +# define GMX_NBNXN_SIMD_2XNN +# endif -#if !(defined GMX_NBNXN_SIMD_4XN || defined GMX_NBNXN_SIMD_2XNN) -#error "No SIMD kernel type defined" -#endif +# if !(defined GMX_NBNXN_SIMD_4XN || defined GMX_NBNXN_SIMD_2XNN) +# error "No SIMD kernel type defined" +# endif #endif // GMX_SIMD diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp b/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp index a182226e3c..08829331c6 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl.cpp @@ -64,7 +64,7 @@ #include #if defined(_MSVC) -#include +# include #endif #include "thread_mpi/atomic.h" @@ -101,7 +101,9 @@ static const int c_clSize = c_nbnxnGpuClusterSize; /*! \brief Validates the input global work size parameter. */ -static inline void validate_global_work_size(const KernelLaunchConfig &config, int work_dim, const gmx_device_info_t *dinfo) +static inline void validate_global_work_size(const KernelLaunchConfig& config, + int work_dim, + const gmx_device_info_t* dinfo) { cl_uint device_size_t_size_bits; cl_uint host_size_t_size_bits; @@ -139,10 +141,12 @@ static inline void validate_global_work_size(const KernelLaunchConfig &config, i { if (global_work_size[i] > device_limit) { - gmx_fatal(FARGS, "Watch out, the input system is too large to simulate!\n" - "The number of nonbonded work units (=number of super-clusters) exceeds the" - "device capabilities. Global work size limit exceeded (%zu > %zu)!", - global_work_size[i], device_limit); + gmx_fatal( + FARGS, + "Watch out, the input system is too large to simulate!\n" + "The number of nonbonded work units (=number of super-clusters) exceeds the" + "device capabilities. Global work size limit exceeded (%zu > %zu)!", + global_work_size[i], device_limit); } } } @@ -157,47 +161,157 @@ static inline void validate_global_work_size(const KernelLaunchConfig &config, i */ /*! \brief Force-only kernel function names. */ -static const char* nb_kfunc_noener_noprune_ptr[eelOclNR][evdwOclNR] = -{ - { "nbnxn_kernel_ElecCut_VdwLJ_F_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecCut_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_opencl" }, - { "nbnxn_kernel_ElecRF_VdwLJ_F_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecRF_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_opencl" }, - { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_opencl" }, - { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_opencl" }, - { "nbnxn_kernel_ElecEw_VdwLJ_F_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecEw_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_opencl" }, - { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_opencl" } +static const char* nb_kfunc_noener_noprune_ptr[eelOclNR][evdwOclNR] = { + { "nbnxn_kernel_ElecCut_VdwLJ_F_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_F_opencl", + "nbnxn_kernel_ElecCut_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_opencl" }, + { "nbnxn_kernel_ElecRF_VdwLJ_F_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecRF_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_F_opencl", + "nbnxn_kernel_ElecRF_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_opencl" }, + { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_opencl" }, + { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_opencl" }, + { "nbnxn_kernel_ElecEw_VdwLJ_F_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecEw_VdwLJCombLB_F_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_F_opencl", + "nbnxn_kernel_ElecEw_VdwLJPsw_F_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_opencl" }, + { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_opencl" } }; /*! \brief Force + energy kernel function pointers. */ -static const char* nb_kfunc_ener_noprune_ptr[eelOclNR][evdwOclNR] = -{ - { "nbnxn_kernel_ElecCut_VdwLJ_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_opencl" }, - { "nbnxn_kernel_ElecRF_VdwLJ_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_opencl" }, - { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_opencl" }, - { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_opencl" }, - { "nbnxn_kernel_ElecEw_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_opencl" }, - { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_opencl" } +static const char* nb_kfunc_ener_noprune_ptr[eelOclNR][evdwOclNR] = { + { "nbnxn_kernel_ElecCut_VdwLJ_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_VF_opencl", + "nbnxn_kernel_ElecCut_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_opencl" }, + { "nbnxn_kernel_ElecRF_VdwLJ_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_VF_opencl", + "nbnxn_kernel_ElecRF_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_opencl" }, + { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_opencl" }, + { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_opencl" }, + { "nbnxn_kernel_ElecEw_VdwLJ_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_VF_opencl", + "nbnxn_kernel_ElecEw_VdwLJPsw_VF_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_opencl" }, + { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_opencl" } }; /*! \brief Force + pruning kernel function pointers. */ -static const char* nb_kfunc_noener_prune_ptr[eelOclNR][evdwOclNR] = -{ - { "nbnxn_kernel_ElecCut_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_opencl" }, - { "nbnxn_kernel_ElecRF_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_opencl" }, - { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_prune_opencl" }, - { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_opencl" }, - { "nbnxn_kernel_ElecEw_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_opencl" }, - { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_prune_opencl" } +static const char* nb_kfunc_noener_prune_ptr[eelOclNR][evdwOclNR] = { + { "nbnxn_kernel_ElecCut_VdwLJ_F_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombLB_F_prune_opencl" }, + { "nbnxn_kernel_ElecRF_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombLB_F_prune_opencl" }, + { "nbnxn_kernel_ElecEwQSTab_VdwLJ_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_F_prune_opencl" }, + { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_F_prune_opencl" }, + { "nbnxn_kernel_ElecEw_VdwLJ_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJFsw_F_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombLB_F_prune_opencl" }, + { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_F_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_F_prune_opencl" } }; /*! \brief Force + energy + pruning kernel function pointers. */ -static const char* nb_kfunc_ener_prune_ptr[eelOclNR][evdwOclNR] = -{ - { "nbnxn_kernel_ElecCut_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_prune_opencl" }, - { "nbnxn_kernel_ElecRF_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_opencl" }, - { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_prune_opencl" }, - { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_prune_opencl" }, - { "nbnxn_kernel_ElecEw_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_opencl" }, - { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_prune_opencl", "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_prune_opencl" } +static const char* nb_kfunc_ener_prune_ptr[eelOclNR][evdwOclNR] = { + { "nbnxn_kernel_ElecCut_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJFsw_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecCut_VdwLJEwCombLB_VF_prune_opencl" }, + { "nbnxn_kernel_ElecRF_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecRF_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecRF_VdwLJEwCombLB_VF_prune_opencl" }, + { "nbnxn_kernel_ElecEwQSTab_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJFsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTab_VdwLJEwCombLB_VF_prune_opencl" }, + { "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJFsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwQSTabTwinCut_VdwLJEwCombLB_VF_prune_opencl" }, + { "nbnxn_kernel_ElecEw_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJFsw_VF_prune_opencl", "nbnxn_kernel_ElecEw_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEw_VdwLJEwCombLB_VF_prune_opencl" }, + { "nbnxn_kernel_ElecEwTwinCut_VdwLJ_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJCombLB_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJFsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJPsw_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombGeom_VF_prune_opencl", + "nbnxn_kernel_ElecEwTwinCut_VdwLJEwCombLB_VF_prune_opencl" } }; /*! \brief Return a pointer to the prune kernel version to be executed at the current invocation. @@ -205,10 +319,9 @@ static const char* nb_kfunc_ener_prune_ptr[eelOclNR][evdwOclNR] = * \param[in] kernel_pruneonly array of prune kernel objects * \param[in] firstPrunePass true if the first pruning pass is being executed */ -static inline cl_kernel selectPruneKernel(cl_kernel kernel_pruneonly[], - bool firstPrunePass) +static inline cl_kernel selectPruneKernel(cl_kernel kernel_pruneonly[], bool firstPrunePass) { - cl_kernel *kernelPtr; + cl_kernel* kernelPtr; if (firstPrunePass) { @@ -227,17 +340,13 @@ static inline cl_kernel selectPruneKernel(cl_kernel kernel_pruneonly[], * OpenCL kernel objects are cached in nb. If the requested kernel is not * found in the cache, it will be created and the cache will be updated. */ -static inline cl_kernel select_nbnxn_kernel(gmx_nbnxn_ocl_t *nb, - int eeltype, - int evdwtype, - bool bDoEne, - bool bDoPrune) +static inline cl_kernel select_nbnxn_kernel(gmx_nbnxn_ocl_t* nb, int eeltype, int evdwtype, bool bDoEne, bool bDoPrune) { const char* kernel_name_to_run; - cl_kernel *kernel_ptr; + cl_kernel* kernel_ptr; cl_int cl_error; - assert(eeltype < eelOclNR); + assert(eeltype < eelOclNR); assert(evdwtype < evdwOclNR); if (bDoEne) @@ -279,25 +388,24 @@ static inline cl_kernel select_nbnxn_kernel(gmx_nbnxn_ocl_t *nb, /*! \brief Calculates the amount of shared memory required by the nonbonded kernel in use. */ -static inline int calc_shmem_required_nonbonded(int vdwType, - bool bPrefetchLjParam) +static inline int calc_shmem_required_nonbonded(int vdwType, bool bPrefetchLjParam) { int shmem; /* size of shmem (force-buffers/xq/atom type preloading) */ /* NOTE: with the default kernel on sm3.0 we need shmem only for pre-loading */ /* i-atom x+q in shared memory */ - shmem = c_numClPerSupercl * c_clSize * sizeof(float) * 4; /* xqib */ + shmem = c_numClPerSupercl * c_clSize * sizeof(float) * 4; /* xqib */ /* cj in shared memory, for both warps separately * TODO: in the "nowarp kernels we load cj only once so the factor 2 is not needed. */ - shmem += 2 * c_nbnxnGpuJgroupSize * sizeof(int); /* cjs */ + shmem += 2 * c_nbnxnGpuJgroupSize * sizeof(int); /* cjs */ if (bPrefetchLjParam) { if (useLjCombRule(vdwType)) { /* i-atom LJ combination parameters in shared memory */ - shmem += c_numClPerSupercl * c_clSize * 2*sizeof(float); /* atib abused for ljcp, float2 */ + shmem += c_numClPerSupercl * c_clSize * 2 * sizeof(float); /* atib abused for ljcp, float2 */ } else { @@ -306,9 +414,9 @@ static inline int calc_shmem_required_nonbonded(int vdwType, } } /* force reduction buffers in shared memory */ - shmem += c_clSize * c_clSize * 3 * sizeof(float); /* f_buf */ + shmem += c_clSize * c_clSize * 3 * sizeof(float); /* f_buf */ /* Warp vote. In fact it must be * number of warps in block.. */ - shmem += sizeof(cl_uint) * 2; /* warp_any */ + shmem += sizeof(cl_uint) * 2; /* warp_any */ return shmem; } @@ -320,8 +428,7 @@ static inline int calc_shmem_required_nonbonded(int vdwType, * * This function is called before the launch of both nbnxn and prune kernels. */ -static void fillin_ocl_structures(cl_nbparam_t *nbp, - cl_nbparam_params_t *nbparams_params) +static void fillin_ocl_structures(cl_nbparam_t* nbp, cl_nbparam_params_t* nbparams_params) { nbparams_params->coulomb_tab_scale = nbp->coulomb_tab_scale; nbparams_params->c_rf = nbp->c_rf; @@ -348,7 +455,7 @@ static void fillin_ocl_structures(cl_nbparam_t *nbp, * Then it releases the event and sets it to 0. * Don't use this function when more than one wait will be issued for the event. * Equivalent to Cuda Stream Sync. */ -static void sync_ocl_event(cl_command_queue stream, cl_event *ocl_event) +static void sync_ocl_event(cl_command_queue stream, cl_event* ocl_event) { cl_int gmx_unused cl_error; @@ -363,23 +470,21 @@ static void sync_ocl_event(cl_command_queue stream, cl_event *ocl_event) } /*! \brief Launch asynchronously the xq buffer host to device copy. */ -void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t *nb, - const nbnxn_atomdata_t *nbatom, - const AtomLocality atomLocality) +void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t* nb, const nbnxn_atomdata_t* nbatom, const AtomLocality atomLocality) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); const InteractionLocality iloc = gpuAtomToInteractionLocality(atomLocality); /* local/nonlocal offset and length used for xq and f */ - int adat_begin, adat_len; + int adat_begin, adat_len; - cl_atomdata_t *adat = nb->atdat; - cl_plist_t *plist = nb->plist[iloc]; - cl_timers_t *t = nb->timers; - cl_command_queue stream = nb->stream[iloc]; + cl_atomdata_t* adat = nb->atdat; + cl_plist_t* plist = nb->plist[iloc]; + cl_timers_t* t = nb->timers; + cl_command_queue stream = nb->stream[iloc]; - bool bDoTime = (nb->bDoTime) != 0; + bool bDoTime = (nb->bDoTime) != 0; /* Don't launch the non-local H2D copy if there is no dependent work to do: neither non-local nor other (e.g. bonded) work @@ -400,13 +505,13 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t *nb, /* calculate the atom data index range based on locality */ if (atomLocality == AtomLocality::Local) { - adat_begin = 0; - adat_len = adat->natoms_local; + adat_begin = 0; + adat_len = adat->natoms_local; } else { - adat_begin = adat->natoms_local; - adat_len = adat->natoms - adat->natoms_local; + adat_begin = adat->natoms_local; + adat_len = adat->natoms - adat->natoms_local; } /* beginning of timed HtoD section */ @@ -416,8 +521,9 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t *nb, } /* HtoD x, q */ - ocl_copy_H2D_async(adat->xq, nbatom->x().data() + adat_begin * 4, adat_begin*sizeof(float)*4, - adat_len * sizeof(float) * 4, stream, bDoTime ? t->xf[atomLocality].nb_h2d.fetchNextEvent() : nullptr); + ocl_copy_H2D_async(adat->xq, nbatom->x().data() + adat_begin * 4, + adat_begin * sizeof(float) * 4, adat_len * sizeof(float) * 4, stream, + bDoTime ? t->xf[atomLocality].nb_h2d.fetchNextEvent() : nullptr); if (bDoTime) { @@ -431,7 +537,8 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t *nb, { if (iloc == InteractionLocality::Local) { - cl_int gmx_used_in_debug cl_error = clEnqueueMarkerWithWaitList(stream, 0, nullptr, &(nb->misc_ops_and_local_H2D_done)); + cl_int gmx_used_in_debug cl_error = clEnqueueMarkerWithWaitList( + stream, 0, nullptr, &(nb->misc_ops_and_local_H2D_done)); assert(CL_SUCCESS == cl_error); /* Based on the v1.2 section 5.13 of the OpenCL spec, a flush is needed @@ -467,19 +574,17 @@ void gpu_copy_xq_to_gpu(gmx_nbnxn_ocl_t *nb, misc_ops_done event to record the point in time when the above operations are finished and synchronize with this event in the non-local stream. */ -void gpu_launch_kernel(gmx_nbnxn_ocl_t *nb, - const gmx::StepWorkload &stepWork, - const Nbnxm::InteractionLocality iloc) +void gpu_launch_kernel(gmx_nbnxn_ocl_t* nb, const gmx::StepWorkload& stepWork, const Nbnxm::InteractionLocality iloc) { - cl_atomdata_t *adat = nb->atdat; - cl_nbparam_t *nbp = nb->nbparam; - cl_plist_t *plist = nb->plist[iloc]; - cl_timers_t *t = nb->timers; - cl_command_queue stream = nb->stream[iloc]; + cl_atomdata_t* adat = nb->atdat; + cl_nbparam_t* nbp = nb->nbparam; + cl_plist_t* plist = nb->plist[iloc]; + cl_timers_t* t = nb->timers; + cl_command_queue stream = nb->stream[iloc]; - bool bDoTime = (nb->bDoTime) != 0; + bool bDoTime = (nb->bDoTime) != 0; - cl_nbparam_params_t nbparams_params; + cl_nbparam_params_t nbparams_params; /* Don't launch the non-local kernel if there is no work to do. Doing the same for the local kernel is more complicated, since the @@ -532,22 +637,21 @@ void gpu_launch_kernel(gmx_nbnxn_ocl_t *nb, if (debug) { - fprintf(debug, "Non-bonded GPU launch configuration:\n\tLocal work size: %zux%zux%zu\n\t" + fprintf(debug, + "Non-bonded GPU launch configuration:\n\tLocal work size: %zux%zux%zu\n\t" "Global work size : %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n", config.blockSize[0], config.blockSize[1], config.blockSize[2], - config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1], plist->nsci*c_numClPerSupercl, - c_numClPerSupercl, plist->na_c); + config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1], + plist->nsci * c_numClPerSupercl, c_numClPerSupercl, plist->na_c); } fillin_ocl_structures(nbp, &nbparams_params); - auto *timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr; + auto* timingEvent = bDoTime ? t->interaction[iloc].nb_k.fetchNextEvent() : nullptr; constexpr char kernelName[] = "k_calc_nb"; - const auto kernel = select_nbnxn_kernel(nb, - nbp->eeltype, - nbp->vdwtype, - stepWork.computeEnergy, - (plist->haveFreshList && !nb->timers->interaction[iloc].didPrune)); + const auto kernel = + select_nbnxn_kernel(nb, nbp->eeltype, nbp->vdwtype, stepWork.computeEnergy, + (plist->haveFreshList && !nb->timers->interaction[iloc].didPrune)); // The OpenCL kernel takes int as second to last argument because bool is @@ -555,22 +659,20 @@ void gpu_launch_kernel(gmx_nbnxn_ocl_t *nb, const int computeFshift = static_cast(stepWork.computeVirial); if (useLjCombRule(nb->nbparam->vdwtype)) { - const auto kernelArgs = prepareGpuKernelArguments(kernel, config, - &nbparams_params, &adat->xq, &adat->f, &adat->e_lj, &adat->e_el, &adat->fshift, - &adat->lj_comb, - &adat->shift_vec, &nbp->nbfp_climg2d, &nbp->nbfp_comb_climg2d, &nbp->coulomb_tab_climg2d, - &plist->sci, &plist->cj4, &plist->excl, &computeFshift); + const auto kernelArgs = prepareGpuKernelArguments( + kernel, config, &nbparams_params, &adat->xq, &adat->f, &adat->e_lj, &adat->e_el, + &adat->fshift, &adat->lj_comb, &adat->shift_vec, &nbp->nbfp_climg2d, &nbp->nbfp_comb_climg2d, + &nbp->coulomb_tab_climg2d, &plist->sci, &plist->cj4, &plist->excl, &computeFshift); launchGpuKernel(kernel, config, timingEvent, kernelName, kernelArgs); } else { - const auto kernelArgs = prepareGpuKernelArguments(kernel, config, - &adat->ntypes, - &nbparams_params, &adat->xq, &adat->f, &adat->e_lj, &adat->e_el, &adat->fshift, - &adat->atom_types, - &adat->shift_vec, &nbp->nbfp_climg2d, &nbp->nbfp_comb_climg2d, &nbp->coulomb_tab_climg2d, - &plist->sci, &plist->cj4, &plist->excl, &computeFshift); + const auto kernelArgs = prepareGpuKernelArguments( + kernel, config, &adat->ntypes, &nbparams_params, &adat->xq, &adat->f, &adat->e_lj, + &adat->e_el, &adat->fshift, &adat->atom_types, &adat->shift_vec, &nbp->nbfp_climg2d, + &nbp->nbfp_comb_climg2d, &nbp->coulomb_tab_climg2d, &plist->sci, &plist->cj4, + &plist->excl, &computeFshift); launchGpuKernel(kernel, config, timingEvent, kernelName, kernelArgs); } @@ -586,22 +688,22 @@ void gpu_launch_kernel(gmx_nbnxn_ocl_t *nb, * Note that for the sake of simplicity we use the CUDA terminology "shared memory" * for OpenCL local memory. * - * \param[in] num_threads_z cj4 concurrency equal to the number of threads/work items in the 3-rd dimension. - * \returns the amount of local memory in bytes required by the pruning kernel + * \param[in] num_threads_z cj4 concurrency equal to the number of threads/work items in the 3-rd + * dimension. \returns the amount of local memory in bytes required by the pruning kernel */ static inline int calc_shmem_required_prune(const int num_threads_z) { int shmem; /* i-atom x in shared memory (for convenience we load all 4 components including q) */ - shmem = c_numClPerSupercl * c_clSize * sizeof(float)*4; + shmem = c_numClPerSupercl * c_clSize * sizeof(float) * 4; /* cj in shared memory, for each warp separately * Note: only need to load once per wavefront, but to keep the code simple, * for now we load twice on AMD. */ shmem += num_threads_z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize * sizeof(int); /* Warp vote, requires one uint per warp/32 threads per block. */ - shmem += sizeof(cl_uint) * 2*num_threads_z; + shmem += sizeof(cl_uint) * 2 * num_threads_z; return shmem; } @@ -610,16 +712,14 @@ static inline int calc_shmem_required_prune(const int num_threads_z) * Launch the pairlist prune only kernel for the given locality. * \p numParts tells in how many parts, i.e. calls the list will be pruned. */ -void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, - const InteractionLocality iloc, - const int numParts) +void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t* nb, const InteractionLocality iloc, const int numParts) { - cl_atomdata_t *adat = nb->atdat; - cl_nbparam_t *nbp = nb->nbparam; - cl_plist_t *plist = nb->plist[iloc]; - cl_timers_t *t = nb->timers; - cl_command_queue stream = nb->stream[iloc]; - bool bDoTime = nb->bDoTime == CL_TRUE; + cl_atomdata_t* adat = nb->atdat; + cl_nbparam_t* nbp = nb->nbparam; + cl_plist_t* plist = nb->plist[iloc]; + cl_timers_t* t = nb->timers; + cl_command_queue stream = nb->stream[iloc]; + bool bDoTime = nb->bDoTime == CL_TRUE; if (plist->haveFreshList) { @@ -637,7 +737,8 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, } else { - GMX_ASSERT(numParts == plist->rollingPruningNumParts, "It is not allowed to change numParts in between list generation steps"); + GMX_ASSERT(numParts == plist->rollingPruningNumParts, + "It is not allowed to change numParts in between list generation steps"); } } @@ -653,7 +754,7 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, } /* Compute the number of list entries to prune in this pass */ - int numSciInPart = (plist->nsci - part)/numParts; + int numSciInPart = (plist->nsci - part) / numParts; /* Don't launch the kernel if there is no work to do. */ if (numSciInPart <= 0) @@ -663,7 +764,7 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, return; } - GpuRegionTimer *timer = nullptr; + GpuRegionTimer* timer = nullptr; if (bDoTime) { timer = &(plist->haveFreshList ? t->interaction[iloc].prune_k : t->interaction[iloc].rollingPrune_k); @@ -680,7 +781,7 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, * and j-cluster concurrency, in x, y, and z, respectively. * - The 1D block-grid contains as many blocks as super-clusters. */ - int num_threads_z = getOclPruneKernelJ4Concurrency(nb->dev_info->vendor_e); + int num_threads_z = getOclPruneKernelJ4Concurrency(nb->dev_info->vendor_e); /* kernel launch config */ KernelLaunchConfig config; @@ -695,28 +796,29 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, if (debug) { - fprintf(debug, "Pruning GPU kernel launch configuration:\n\tLocal work size: %zux%zux%zu\n\t" + fprintf(debug, + "Pruning GPU kernel launch configuration:\n\tLocal work size: %zux%zux%zu\n\t" "\tGlobal work size: %zux%zu\n\t#Super-clusters/clusters: %d/%d (%d)\n" "\tShMem: %zu\n", config.blockSize[0], config.blockSize[1], config.blockSize[2], - config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1], plist->nsci*c_numClPerSupercl, - c_numClPerSupercl, plist->na_c, config.sharedMemorySize); + config.blockSize[0] * config.gridSize[0], config.blockSize[1] * config.gridSize[1], + plist->nsci * c_numClPerSupercl, c_numClPerSupercl, plist->na_c, config.sharedMemorySize); } - cl_nbparam_params_t nbparams_params; + cl_nbparam_params_t nbparams_params; fillin_ocl_structures(nbp, &nbparams_params); - auto *timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr; + auto* timingEvent = bDoTime ? timer->fetchNextEvent() : nullptr; constexpr char kernelName[] = "k_pruneonly"; const auto pruneKernel = selectPruneKernel(nb->kernel_pruneonly, plist->haveFreshList); - const auto kernelArgs = prepareGpuKernelArguments(pruneKernel, config, - &nbparams_params, &adat->xq, &adat->shift_vec, - &plist->sci, &plist->cj4, &plist->imask, &numParts, &part); + const auto kernelArgs = prepareGpuKernelArguments(pruneKernel, config, &nbparams_params, + &adat->xq, &adat->shift_vec, &plist->sci, + &plist->cj4, &plist->imask, &numParts, &part); launchGpuKernel(pruneKernel, config, timingEvent, kernelName, kernelArgs); if (plist->haveFreshList) { - plist->haveFreshList = false; + plist->haveFreshList = false; /* Mark that pruning has been done */ nb->timers->interaction[iloc].didPrune = true; } @@ -736,10 +838,10 @@ void gpu_launch_kernel_pruneonly(gmx_nbnxn_gpu_t *nb, * Launch asynchronously the download of nonbonded forces from the GPU * (and energies/shift forces if required). */ -void gpu_launch_cpyback(gmx_nbnxn_ocl_t *nb, - struct nbnxn_atomdata_t *nbatom, - const gmx::StepWorkload &stepWork, - const AtomLocality aloc) +void gpu_launch_cpyback(gmx_nbnxn_ocl_t* nb, + struct nbnxn_atomdata_t* nbatom, + const gmx::StepWorkload& stepWork, + const AtomLocality aloc) { GMX_ASSERT(nb, "Need a valid nbnxn_gpu object"); @@ -749,10 +851,10 @@ void gpu_launch_cpyback(gmx_nbnxn_ocl_t *nb, /* determine interaction locality from atom locality */ const InteractionLocality iloc = gpuAtomToInteractionLocality(aloc); - cl_atomdata_t *adat = nb->atdat; - cl_timers_t *t = nb->timers; - bool bDoTime = nb->bDoTime == CL_TRUE; - cl_command_queue stream = nb->stream[iloc]; + cl_atomdata_t* adat = nb->atdat; + cl_timers_t* t = nb->timers; + bool bDoTime = nb->bDoTime == CL_TRUE; + cl_command_queue stream = nb->stream[iloc]; /* don't launch non-local copy-back if there was no non-local work to do */ if ((iloc == InteractionLocality::NonLocal) && !haveGpuShortRangeWork(*nb, iloc)) @@ -785,8 +887,9 @@ void gpu_launch_cpyback(gmx_nbnxn_ocl_t *nb, } /* DtoH f */ - ocl_copy_D2H_async(nbatom->out[0].f.data() + adat_begin * 3, adat->f, adat_begin*3*sizeof(float), - (adat_len)* adat->f_elem_size, stream, bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); + ocl_copy_D2H_async(nbatom->out[0].f.data() + adat_begin * 3, adat->f, + adat_begin * 3 * sizeof(float), (adat_len)*adat->f_elem_size, stream, + bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); /* kick off work */ cl_error = clFlush(stream); @@ -809,18 +912,18 @@ void gpu_launch_cpyback(gmx_nbnxn_ocl_t *nb, /* DtoH fshift when virial is needed */ if (stepWork.computeVirial) { - ocl_copy_D2H_async(nb->nbst.fshift, adat->fshift, 0, - SHIFTS * adat->fshift_elem_size, stream, bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); + ocl_copy_D2H_async(nb->nbst.fshift, adat->fshift, 0, SHIFTS * adat->fshift_elem_size, + stream, bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); } /* DtoH energies */ if (stepWork.computeEnergy) { - ocl_copy_D2H_async(nb->nbst.e_lj, adat->e_lj, 0, - sizeof(float), stream, bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); + ocl_copy_D2H_async(nb->nbst.e_lj, adat->e_lj, 0, sizeof(float), stream, + bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); - ocl_copy_D2H_async(nb->nbst.e_el, adat->e_el, 0, - sizeof(float), stream, bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); + ocl_copy_D2H_async(nb->nbst.e_el, adat->e_el, 0, sizeof(float), stream, + bDoTime ? t->xf[aloc].nb_d2h.fetchNextEvent() : nullptr); } } @@ -832,7 +935,7 @@ void gpu_launch_cpyback(gmx_nbnxn_ocl_t *nb, /*! \brief Selects the Ewald kernel type, analytical or tabulated, single or twin cut-off. */ -int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t &ic) +int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t& ic) { bool bTwinCut = (ic.rcoulomb != ic.rvdw); bool bUseAnalyticalEwald, bForceAnalyticalEwald, bForceTabulatedEwald; @@ -845,8 +948,9 @@ int nbnxn_gpu_pick_ewald_kernel_type(const interaction_const_t &ic) if (bForceAnalyticalEwald && bForceTabulatedEwald) { - gmx_incons("Both analytical and tabulated Ewald OpenCL non-bonded kernels " - "requested through environment variables."); + gmx_incons( + "Both analytical and tabulated Ewald OpenCL non-bonded kernels " + "requested through environment variables."); } /* OpenCL: By default, use analytical Ewald diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_consts.h b/src/gromacs/nbnxm/opencl/nbnxm_ocl_consts.h index a49596223f..2d3d29110c 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_consts.h +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_consts.h @@ -43,8 +43,8 @@ * \ingroup module_nbnxm */ /*! @{ */ -#define GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY_DEFAULT 4 -//The following has to match getOclPruneKernelJ4Concurrency +#define GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY_DEFAULT 4 +// The following has to match getOclPruneKernelJ4Concurrency #define GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY_DEFAULT /*! @} */ #endif diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp b/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp index 35d5fea8d9..ced508feda 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp @@ -85,10 +85,10 @@ namespace Nbnxm /*! \brief Copies of values from cl_driver_diagnostics_intel.h, * which isn't guaranteed to be available. */ /**@{*/ -#define CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL 0x4106 -#define CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL 0x1 -#define CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL 0x2 -#define CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL 0x4 +#define CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL 0x4106 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL 0x1 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL 0x2 +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL 0x4 /**@}*/ /*! \brief This parameter should be determined heuristically from the @@ -107,8 +107,7 @@ static unsigned int gpu_min_ci_balanced_factor = 50; * Full doc in nbnxn_ocl_internal.h */ bool useLjCombRule(int vdwType) { - return (vdwType == evdwOclCUTCOMBGEOM || - vdwType == evdwOclCUTCOMBLB); + return (vdwType == evdwOclCUTCOMBGEOM || vdwType == evdwOclCUTCOMBLB); } /*! \brief Tabulates the Ewald Coulomb force and initializes the size/scale @@ -117,13 +116,13 @@ bool useLjCombRule(int vdwType) * If called with an already allocated table, it just re-uploads the * table. */ -static void init_ewald_coulomb_force_table(const EwaldCorrectionTables &tables, - cl_nbparam_t *nbp, - const gmx_device_runtime_data_t *runData) +static void init_ewald_coulomb_force_table(const EwaldCorrectionTables& tables, + cl_nbparam_t* nbp, + const gmx_device_runtime_data_t* runData) { - cl_mem coul_tab; + cl_mem coul_tab; - cl_int cl_error; + cl_int cl_error; if (nbp->coulomb_tab_climg2d != nullptr) { @@ -142,24 +141,25 @@ static void init_ewald_coulomb_force_table(const EwaldCorrectionTables &tabl &array_format, tabsize, 1, 0, ftmp, &cl_error); */ - coul_tab = clCreateBuffer(runData->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, - tables.tableF.size()*sizeof(cl_float), const_cast(tables.tableF.data()), &cl_error); + coul_tab = clCreateBuffer( + runData->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, + tables.tableF.size() * sizeof(cl_float), const_cast(tables.tableF.data()), &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); - nbp->coulomb_tab_climg2d = coul_tab; - nbp->coulomb_tab_scale = tables.scale; + nbp->coulomb_tab_climg2d = coul_tab; + nbp->coulomb_tab_scale = tables.scale; } /*! \brief Initializes the atomdata structure first time, it only gets filled at pair-search. */ -static void init_atomdata_first(cl_atomdata_t *ad, int ntypes, gmx_device_runtime_data_t *runData) +static void init_atomdata_first(cl_atomdata_t* ad, int ntypes, gmx_device_runtime_data_t* runData) { cl_int cl_error; - ad->ntypes = ntypes; + ad->ntypes = ntypes; /* An element of the shift_vec device buffer has the same size as one element of the host side shift_vec buffer. */ @@ -202,9 +202,7 @@ static void init_atomdata_first(cl_atomdata_t *ad, int ntypes, gmx_device_runtim /*! \brief Copies all parameters related to the cut-off from ic to nbp */ -static void set_cutoff_parameters(cl_nbparam_t *nbp, - const interaction_const_t *ic, - const PairlistParams &listParams) +static void set_cutoff_parameters(cl_nbparam_t* nbp, const interaction_const_t* ic, const PairlistParams& listParams) { nbp->ewald_beta = ic->ewaldcoeff_q; nbp->sh_ewald = ic->sh_ewald; @@ -217,13 +215,13 @@ static void set_cutoff_parameters(cl_nbparam_t *nbp, nbp->rlistInner_sq = listParams.rlistInner * listParams.rlistInner; nbp->useDynamicPruning = listParams.useDynamicPruning; - nbp->sh_lj_ewald = ic->sh_lj_ewald; - nbp->ewaldcoeff_lj = ic->ewaldcoeff_lj; + nbp->sh_lj_ewald = ic->sh_lj_ewald; + nbp->ewaldcoeff_lj = ic->ewaldcoeff_lj; - nbp->rvdw_switch = ic->rvdw_switch; - nbp->dispersion_shift = ic->dispersion_shift; - nbp->repulsion_shift = ic->repulsion_shift; - nbp->vdw_switch = ic->vdw_switch; + nbp->rvdw_switch = ic->rvdw_switch; + nbp->dispersion_shift = ic->dispersion_shift; + nbp->repulsion_shift = ic->repulsion_shift; + nbp->vdw_switch = ic->vdw_switch; } /*! \brief Returns the kinds of electrostatics and Vdw OpenCL @@ -231,11 +229,10 @@ static void set_cutoff_parameters(cl_nbparam_t *nbp, * * Respectively, these values are from enum eelOcl and enum * evdwOcl. */ -static void -map_interaction_types_to_gpu_kernel_flavors(const interaction_const_t *ic, - int combRule, - int *gpu_eeltype, - int *gpu_vdwtype) +static void map_interaction_types_to_gpu_kernel_flavors(const interaction_const_t* ic, + int combRule, + int* gpu_eeltype, + int* gpu_vdwtype) { if (ic->vdwtype == evdwCUT) { @@ -245,27 +242,21 @@ map_interaction_types_to_gpu_kernel_flavors(const interaction_const_t *ic, case eintmodPOTSHIFT: switch (combRule) { - case ljcrNONE: - *gpu_vdwtype = evdwOclCUT; - break; - case ljcrGEOM: - *gpu_vdwtype = evdwOclCUTCOMBGEOM; - break; - case ljcrLB: - *gpu_vdwtype = evdwOclCUTCOMBLB; - break; + case ljcrNONE: *gpu_vdwtype = evdwOclCUT; break; + case ljcrGEOM: *gpu_vdwtype = evdwOclCUTCOMBGEOM; break; + case ljcrLB: *gpu_vdwtype = evdwOclCUTCOMBLB; break; default: - gmx_incons("The requested LJ combination rule is not implemented in the OpenCL GPU accelerated kernels!"); + gmx_incons( + "The requested LJ combination rule is not implemented in the " + "OpenCL GPU accelerated kernels!"); } break; - case eintmodFORCESWITCH: - *gpu_vdwtype = evdwOclFSWITCH; - break; - case eintmodPOTSWITCH: - *gpu_vdwtype = evdwOclPSWITCH; - break; + case eintmodFORCESWITCH: *gpu_vdwtype = evdwOclFSWITCH; break; + case eintmodPOTSWITCH: *gpu_vdwtype = evdwOclPSWITCH; break; default: - gmx_incons("The requested VdW interaction modifier is not implemented in the GPU accelerated kernels!"); + gmx_incons( + "The requested VdW interaction modifier is not implemented in the GPU " + "accelerated kernels!"); } } else if (ic->vdwtype == evdwPME) @@ -299,26 +290,25 @@ map_interaction_types_to_gpu_kernel_flavors(const interaction_const_t *ic, else { /* Shouldn't happen, as this is checked when choosing Verlet-scheme */ - gmx_incons("The requested electrostatics type is not implemented in the GPU accelerated kernels!"); + gmx_incons( + "The requested electrostatics type is not implemented in the GPU accelerated " + "kernels!"); } } /*! \brief Initializes the nonbonded parameter data structure. */ -static void init_nbparam(cl_nbparam_t *nbp, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t::Params &nbatParams, - const gmx_device_runtime_data_t *runData) +static void init_nbparam(cl_nbparam_t* nbp, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t::Params& nbatParams, + const gmx_device_runtime_data_t* runData) { cl_int cl_error; set_cutoff_parameters(nbp, ic, listParams); - map_interaction_types_to_gpu_kernel_flavors(ic, - nbatParams.comb_rule, - &(nbp->eeltype), - &(nbp->vdwtype)); + map_interaction_types_to_gpu_kernel_flavors(ic, nbatParams.comb_rule, &(nbp->eeltype), &(nbp->vdwtype)); if (ic->vdwtype == evdwPME) { @@ -340,8 +330,8 @@ static void init_nbparam(cl_nbparam_t *nbp, } else // TODO: improvement needed. - // The image2d is created here even if eeltype is not eelCuEWALD_TAB or eelCuEWALD_TAB_TWIN because the OpenCL kernels - // don't accept nullptr values for image2D parameters. + // The image2d is created here even if eeltype is not eelCuEWALD_TAB or eelCuEWALD_TAB_TWIN + // because the OpenCL kernels don't accept nullptr values for image2D parameters. { /* Switched from using textures to using buffers */ // TODO: decide which alternative is most efficient - textures or buffers. @@ -355,13 +345,14 @@ static void init_nbparam(cl_nbparam_t *nbp, &array_format, 1, 1, 0, nullptr, &cl_error); */ - nbp->coulomb_tab_climg2d = clCreateBuffer(runData->context, CL_MEM_READ_ONLY, sizeof(cl_float), nullptr, &cl_error); + nbp->coulomb_tab_climg2d = clCreateBuffer(runData->context, CL_MEM_READ_ONLY, + sizeof(cl_float), nullptr, &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); } - const int nnbfp = 2*nbatParams.numTypes*nbatParams.numTypes; - const int nnbfp_comb = 2*nbatParams.numTypes; + const int nnbfp = 2 * nbatParams.numTypes * nbatParams.numTypes; + const int nnbfp_comb = 2 * nbatParams.numTypes; { /* Switched from using textures to using buffers */ @@ -372,16 +363,13 @@ static void init_nbparam(cl_nbparam_t *nbp, array_format.image_channel_data_type = CL_FLOAT; array_format.image_channel_order = CL_R; - nbp->nbfp_climg2d = clCreateImage2D(runData->context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - &array_format, nnbfp, 1, 0, nbat->nbfp, &cl_error); + nbp->nbfp_climg2d = clCreateImage2D(runData->context, CL_MEM_READ_ONLY | + CL_MEM_COPY_HOST_PTR, &array_format, nnbfp, 1, 0, nbat->nbfp, &cl_error); */ - nbp->nbfp_climg2d = - clCreateBuffer(runData->context, - CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, - nnbfp*sizeof(cl_float), - const_cast(nbatParams.nbfp.data()), - &cl_error); + nbp->nbfp_climg2d = clCreateBuffer( + runData->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, + nnbfp * sizeof(cl_float), const_cast(nbatParams.nbfp.data()), &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); @@ -389,14 +377,12 @@ static void init_nbparam(cl_nbparam_t *nbp, { /* Switched from using textures to using buffers */ // TODO: decide which alternative is most efficient - textures or buffers. - /* nbp->nbfp_comb_climg2d = clCreateImage2D(runData->context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, - &array_format, nnbfp_comb, 1, 0, nbat->nbfp_comb, &cl_error);*/ - nbp->nbfp_comb_climg2d = - clCreateBuffer(runData->context, - CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, - nnbfp_comb*sizeof(cl_float), - const_cast(nbatParams.nbfp_comb.data()), - &cl_error); + /* nbp->nbfp_comb_climg2d = clCreateImage2D(runData->context, CL_MEM_READ_WRITE | + CL_MEM_COPY_HOST_PTR, &array_format, nnbfp_comb, 1, 0, nbat->nbfp_comb, &cl_error);*/ + nbp->nbfp_comb_climg2d = clCreateBuffer( + runData->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, + nnbfp_comb * sizeof(cl_float), const_cast(nbatParams.nbfp_comb.data()), + &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); } @@ -409,7 +395,8 @@ static void init_nbparam(cl_nbparam_t *nbp, // TODO: decide which alternative is most efficient - textures or buffers. /* nbp->nbfp_comb_climg2d = clCreateImage2D(runData->context, CL_MEM_READ_WRITE, &array_format, 1, 1, 0, nullptr, &cl_error);*/ - nbp->nbfp_comb_climg2d = clCreateBuffer(runData->context, CL_MEM_READ_ONLY, sizeof(cl_float), nullptr, &cl_error); + nbp->nbfp_comb_climg2d = clCreateBuffer(runData->context, CL_MEM_READ_ONLY, + sizeof(cl_float), nullptr, &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); } @@ -417,15 +404,14 @@ static void init_nbparam(cl_nbparam_t *nbp, } //! This function is documented in the header file -void gpu_pme_loadbal_update_param(const nonbonded_verlet_t *nbv, - const interaction_const_t *ic) +void gpu_pme_loadbal_update_param(const nonbonded_verlet_t* nbv, const interaction_const_t* ic) { if (!nbv || !nbv->useGpu()) { return; } - gmx_nbnxn_ocl_t *nb = nbv->gpu_nbv; - cl_nbparam_t *nbp = nb->nbparam; + gmx_nbnxn_ocl_t* nb = nbv->gpu_nbv; + cl_nbparam_t* nbp = nb->nbparam; set_cutoff_parameters(nbp, ic, nbv->pairlistSets().params()); @@ -437,31 +423,31 @@ void gpu_pme_loadbal_update_param(const nonbonded_verlet_t *nbv, /*! \brief Initializes the pair list data structure. */ -static void init_plist(cl_plist_t *pl) +static void init_plist(cl_plist_t* pl) { /* initialize to nullptr pointers to data that is not allocated here and will need reallocation in nbnxn_gpu_init_pairlist */ - pl->sci = nullptr; - pl->cj4 = nullptr; - pl->imask = nullptr; - pl->excl = nullptr; + pl->sci = nullptr; + pl->cj4 = nullptr; + pl->imask = nullptr; + pl->excl = nullptr; /* size -1 indicates that the respective array hasn't been initialized yet */ - pl->na_c = -1; - pl->nsci = -1; - pl->sci_nalloc = -1; - pl->ncj4 = -1; - pl->cj4_nalloc = -1; - pl->nimask = -1; - pl->imask_nalloc = -1; - pl->nexcl = -1; - pl->excl_nalloc = -1; - pl->haveFreshList = false; + pl->na_c = -1; + pl->nsci = -1; + pl->sci_nalloc = -1; + pl->ncj4 = -1; + pl->cj4_nalloc = -1; + pl->nimask = -1; + pl->imask_nalloc = -1; + pl->nexcl = -1; + pl->excl_nalloc = -1; + pl->haveFreshList = false; } /*! \brief Initializes the timings data structure. */ -static void init_timings(gmx_wallclock_gpu_nbnxn_t *t) +static void init_timings(gmx_wallclock_gpu_nbnxn_t* t) { int i, j; @@ -487,12 +473,14 @@ static void init_timings(gmx_wallclock_gpu_nbnxn_t *t) //! OpenCL notification callback function -static void CL_CALLBACK -ocl_notify_fn(const char *pErrInfo, const void gmx_unused *private_info, size_t gmx_unused cb, void gmx_unused *user_data) +static void CL_CALLBACK ocl_notify_fn(const char* pErrInfo, + const void gmx_unused* private_info, + size_t gmx_unused cb, + void gmx_unused* user_data) { if (pErrInfo != nullptr) { - printf("%s\n", pErrInfo ); // Print error/hint + printf("%s\n", pErrInfo); // Print error/hint } } @@ -504,30 +492,30 @@ ocl_notify_fn(const char *pErrInfo, const void gmx_unused *private_info, size_t * \param[in] devInfo device info struct * \param[in] rank MPI rank (for error reporting) */ -static void -nbnxn_gpu_create_context(gmx_device_runtime_data_t *runtimeData, - const gmx_device_info_t *devInfo, - int rank) +static void nbnxn_gpu_create_context(gmx_device_runtime_data_t* runtimeData, + const gmx_device_info_t* devInfo, + int rank) { - cl_context_properties context_properties[5]; - cl_platform_id platform_id; - cl_device_id device_id; - cl_context context; - cl_int cl_error; + cl_context_properties context_properties[5]; + cl_platform_id platform_id; + cl_device_id device_id; + cl_context context; + cl_int cl_error; assert(runtimeData != nullptr); assert(devInfo != nullptr); - platform_id = devInfo->ocl_gpu_id.ocl_platform_id; - device_id = devInfo->ocl_gpu_id.ocl_device_id; + platform_id = devInfo->ocl_gpu_id.ocl_platform_id; + device_id = devInfo->ocl_gpu_id.ocl_device_id; - int i = 0; + int i = 0; context_properties[i++] = CL_CONTEXT_PLATFORM; context_properties[i++] = reinterpret_cast(platform_id); if (getenv("GMX_OCL_SHOW_DIAGNOSTICS")) { context_properties[i++] = CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL; - context_properties[i++] = CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL | CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL; + context_properties[i++] = + CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL | CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL; } context_properties[i++] = 0; /* Terminates the list of properties */ @@ -535,17 +523,14 @@ nbnxn_gpu_create_context(gmx_device_runtime_data_t *runtimeData, if (CL_SUCCESS != cl_error) { gmx_fatal(FARGS, "On rank %d failed to create context for GPU #%s:\n OpenCL error %d: %s", - rank, - devInfo->device_name, - cl_error, ocl_get_error_string(cl_error).c_str()); + rank, devInfo->device_name, cl_error, ocl_get_error_string(cl_error).c_str()); } runtimeData->context = context; } /*! \brief Initializes the OpenCL kernel pointers of the nbnxn_ocl_ptr_t input data structure. */ -static cl_kernel nbnxn_gpu_create_kernel(gmx_nbnxn_ocl_t *nb, - const char *kernel_name) +static cl_kernel nbnxn_gpu_create_kernel(gmx_nbnxn_ocl_t* nb, const char* kernel_name) { cl_kernel kernel; cl_int cl_error; @@ -553,10 +538,8 @@ static cl_kernel nbnxn_gpu_create_kernel(gmx_nbnxn_ocl_t *nb, kernel = clCreateKernel(nb->dev_rundata->program, kernel_name, &cl_error); if (CL_SUCCESS != cl_error) { - gmx_fatal(FARGS, "Failed to create kernel '%s' for GPU #%s: OpenCL error %d", - kernel_name, - nb->dev_info->device_name, - cl_error); + gmx_fatal(FARGS, "Failed to create kernel '%s' for GPU #%s: OpenCL error %d", kernel_name, + nb->dev_info->device_name, cl_error); } return kernel; @@ -564,40 +547,40 @@ static cl_kernel nbnxn_gpu_create_kernel(gmx_nbnxn_ocl_t *nb, /*! \brief Clears nonbonded shift force output array and energy outputs on the GPU. */ -static void -nbnxn_ocl_clear_e_fshift(gmx_nbnxn_ocl_t *nb) +static void nbnxn_ocl_clear_e_fshift(gmx_nbnxn_ocl_t* nb) { - cl_int cl_error; - cl_atomdata_t * adat = nb->atdat; - cl_command_queue ls = nb->stream[InteractionLocality::Local]; + cl_int cl_error; + cl_atomdata_t* adat = nb->atdat; + cl_command_queue ls = nb->stream[InteractionLocality::Local]; - size_t local_work_size[3] = {1, 1, 1}; - size_t global_work_size[3] = {1, 1, 1}; + size_t local_work_size[3] = { 1, 1, 1 }; + size_t global_work_size[3] = { 1, 1, 1 }; - cl_int shifts = SHIFTS*3; + cl_int shifts = SHIFTS * 3; - cl_int arg_no; + cl_int arg_no; - cl_kernel zero_e_fshift = nb->kernel_zero_e_fshift; + cl_kernel zero_e_fshift = nb->kernel_zero_e_fshift; - local_work_size[0] = 64; + local_work_size[0] = 64; // Round the total number of threads up from the array size - global_work_size[0] = ((shifts + local_work_size[0] - 1)/local_work_size[0])*local_work_size[0]; + global_work_size[0] = ((shifts + local_work_size[0] - 1) / local_work_size[0]) * local_work_size[0]; - arg_no = 0; - cl_error = clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_mem), &(adat->fshift)); + arg_no = 0; + cl_error = clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_mem), &(adat->fshift)); cl_error |= clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_mem), &(adat->e_lj)); cl_error |= clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_mem), &(adat->e_el)); cl_error |= clSetKernelArg(zero_e_fshift, arg_no++, sizeof(cl_uint), &shifts); GMX_ASSERT(cl_error == CL_SUCCESS, ocl_get_error_string(cl_error).c_str()); - cl_error = clEnqueueNDRangeKernel(ls, zero_e_fshift, 3, nullptr, global_work_size, local_work_size, 0, nullptr, nullptr); + cl_error = clEnqueueNDRangeKernel(ls, zero_e_fshift, 3, nullptr, global_work_size, + local_work_size, 0, nullptr, nullptr); GMX_ASSERT(cl_error == CL_SUCCESS, ocl_get_error_string(cl_error).c_str()); } /*! \brief Initializes the OpenCL kernel pointers of the nbnxn_ocl_ptr_t input data structure. */ -static void nbnxn_gpu_init_kernels(gmx_nbnxn_ocl_t *nb) +static void nbnxn_gpu_init_kernels(gmx_nbnxn_ocl_t* nb) { /* Init to 0 main kernel arrays */ /* They will be later on initialized in select_nbnxn_kernel */ @@ -613,8 +596,9 @@ static void nbnxn_gpu_init_kernels(gmx_nbnxn_ocl_t *nb) * TODO: we could avoid creating kernels if dynamic pruning is turned off, * but ATM that depends on force flags not passed into the initialization. */ - nb->kernel_pruneonly[epruneFirst] = nbnxn_gpu_create_kernel(nb, "nbnxn_kernel_prune_opencl"); - nb->kernel_pruneonly[epruneRolling] = nbnxn_gpu_create_kernel(nb, "nbnxn_kernel_prune_rolling_opencl"); + nb->kernel_pruneonly[epruneFirst] = nbnxn_gpu_create_kernel(nb, "nbnxn_kernel_prune_opencl"); + nb->kernel_pruneonly[epruneRolling] = + nbnxn_gpu_create_kernel(nb, "nbnxn_kernel_prune_rolling_opencl"); /* Init auxiliary kernels */ nb->kernel_zero_e_fshift = nbnxn_gpu_create_kernel(nb, "zero_e_fshift"); @@ -625,10 +609,10 @@ static void nbnxn_gpu_init_kernels(gmx_nbnxn_ocl_t *nb) * Initializes members of the atomdata and nbparam structs and * clears e/fshift output buffers. */ -static void nbnxn_ocl_init_const(gmx_nbnxn_ocl_t *nb, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t::Params &nbatParams) +static void nbnxn_ocl_init_const(gmx_nbnxn_ocl_t* nb, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t::Params& nbatParams) { init_atomdata_first(nb->atdat, nbatParams.numTypes, nb->dev_rundata); init_nbparam(nb->nbparam, ic, listParams, nbatParams, nb->dev_rundata); @@ -636,15 +620,14 @@ static void nbnxn_ocl_init_const(gmx_nbnxn_ocl_t *nb, //! This function is documented in the header file -gmx_nbnxn_ocl_t * -gpu_init(const gmx_device_info_t *deviceInfo, - const interaction_const_t *ic, - const PairlistParams &listParams, - const nbnxn_atomdata_t *nbat, - const int rank, - const gmx_bool bLocalAndNonlocal) +gmx_nbnxn_ocl_t* gpu_init(const gmx_device_info_t* deviceInfo, + const interaction_const_t* ic, + const PairlistParams& listParams, + const nbnxn_atomdata_t* nbat, + const int rank, + const gmx_bool bLocalAndNonlocal) { - gmx_nbnxn_ocl_t *nb; + gmx_nbnxn_ocl_t* nb; cl_int cl_error; cl_command_queue_properties queue_properties; @@ -691,14 +674,12 @@ gpu_init(const gmx_device_info_t *deviceInfo, nbnxn_gpu_create_context(nb->dev_rundata, nb->dev_info, rank); /* local/non-local GPU streams */ - nb->stream[InteractionLocality::Local] = - clCreateCommandQueue(nb->dev_rundata->context, nb->dev_info->ocl_gpu_id.ocl_device_id, queue_properties, &cl_error); + nb->stream[InteractionLocality::Local] = clCreateCommandQueue( + nb->dev_rundata->context, nb->dev_info->ocl_gpu_id.ocl_device_id, queue_properties, &cl_error); if (CL_SUCCESS != cl_error) { - gmx_fatal(FARGS, "On rank %d failed to create context for GPU #%s: OpenCL error %d", - rank, - nb->dev_info->device_name, - cl_error); + gmx_fatal(FARGS, "On rank %d failed to create context for GPU #%s: OpenCL error %d", rank, + nb->dev_info->device_name, cl_error); } if (nb->bUseTwoStreams) @@ -706,13 +687,12 @@ gpu_init(const gmx_device_info_t *deviceInfo, init_plist(nb->plist[InteractionLocality::NonLocal]); nb->stream[InteractionLocality::NonLocal] = - clCreateCommandQueue(nb->dev_rundata->context, nb->dev_info->ocl_gpu_id.ocl_device_id, queue_properties, &cl_error); + clCreateCommandQueue(nb->dev_rundata->context, nb->dev_info->ocl_gpu_id.ocl_device_id, + queue_properties, &cl_error); if (CL_SUCCESS != cl_error) { gmx_fatal(FARGS, "On rank %d failed to create context for GPU #%s: OpenCL error %d", - rank, - nb->dev_info->device_name, - cl_error); + rank, nb->dev_info->device_name, cl_error); } } @@ -726,10 +706,10 @@ gpu_init(const gmx_device_info_t *deviceInfo, /* Enable LJ param manual prefetch for AMD or Intel or if we request through env. var. * TODO: decide about NVIDIA */ - nb->bPrefetchLjParam = - (getenv("GMX_OCL_DISABLE_I_PREFETCH") == nullptr) && - ((nb->dev_info->vendor_e == OCL_VENDOR_AMD) || (nb->dev_info->vendor_e == OCL_VENDOR_INTEL) - || (getenv("GMX_OCL_ENABLE_I_PREFETCH") != nullptr)); + nb->bPrefetchLjParam = (getenv("GMX_OCL_DISABLE_I_PREFETCH") == nullptr) + && ((nb->dev_info->vendor_e == OCL_VENDOR_AMD) + || (nb->dev_info->vendor_e == OCL_VENDOR_INTEL) + || (getenv("GMX_OCL_ENABLE_I_PREFETCH") != nullptr)); /* NOTE: in CUDA we pick L1 cache configuration for the nbnxn kernels here, * but sadly this is not supported in OpenCL (yet?). Consider adding it if @@ -751,7 +731,7 @@ gpu_init(const gmx_device_info_t *deviceInfo, /*! \brief Clears the first natoms_clear elements of the GPU nonbonded force output array. */ -static void nbnxn_ocl_clear_f(gmx_nbnxn_ocl_t *nb, int natoms_clear) +static void nbnxn_ocl_clear_f(gmx_nbnxn_ocl_t* nb, int natoms_clear) { if (natoms_clear == 0) { @@ -760,19 +740,18 @@ static void nbnxn_ocl_clear_f(gmx_nbnxn_ocl_t *nb, int natoms_clear) cl_int gmx_used_in_debug cl_error; - cl_atomdata_t *atomData = nb->atdat; - cl_command_queue ls = nb->stream[InteractionLocality::Local]; - cl_float value = 0.0F; + cl_atomdata_t* atomData = nb->atdat; + cl_command_queue ls = nb->stream[InteractionLocality::Local]; + cl_float value = 0.0F; - cl_error = clEnqueueFillBuffer(ls, atomData->f, &value, sizeof(cl_float), - 0, natoms_clear*sizeof(rvec), 0, nullptr, nullptr); - GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clEnqueueFillBuffer failed: " + - ocl_get_error_string(cl_error)).c_str()); + cl_error = clEnqueueFillBuffer(ls, atomData->f, &value, sizeof(cl_float), 0, + natoms_clear * sizeof(rvec), 0, nullptr, nullptr); + GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, + ("clEnqueueFillBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); } //! This function is documented in the header file -void gpu_clear_outputs(gmx_nbnxn_ocl_t *nb, - bool computeVirial) +void gpu_clear_outputs(gmx_nbnxn_ocl_t* nb, bool computeVirial) { nbnxn_ocl_clear_f(nb, nb->atdat->natoms); /* clear shift force array and energies if the outputs were @@ -789,17 +768,15 @@ void gpu_clear_outputs(gmx_nbnxn_ocl_t *nb, } //! This function is documented in the header file -void gpu_init_pairlist(gmx_nbnxn_ocl_t *nb, - const NbnxnPairlistGpu *h_plist, - const InteractionLocality iloc) +void gpu_init_pairlist(gmx_nbnxn_ocl_t* nb, const NbnxnPairlistGpu* h_plist, const InteractionLocality iloc) { - char sbuf[STRLEN]; + char sbuf[STRLEN]; // Timing accumulation should happen only if there was work to do // because getLastRangeTime() gets skipped with empty lists later // which leads to the counter not being reset. - bool bDoTime = ((nb->bDoTime == CL_TRUE) && !h_plist->sci.empty()); - cl_command_queue stream = nb->stream[iloc]; - cl_plist_t *d_plist = nb->plist[iloc]; + bool bDoTime = ((nb->bDoTime == CL_TRUE) && !h_plist->sci.empty()); + cl_command_queue stream = nb->stream[iloc]; + cl_plist_t* d_plist = nb->plist[iloc]; if (d_plist->na_c < 0) { @@ -815,7 +792,7 @@ void gpu_init_pairlist(gmx_nbnxn_ocl_t *nb, } } - gpu_timers_t::Interaction &iTimers = nb->timers->interaction[iloc]; + gpu_timers_t::Interaction& iTimers = nb->timers->interaction[iloc]; if (bDoTime) { @@ -826,26 +803,21 @@ void gpu_init_pairlist(gmx_nbnxn_ocl_t *nb, // TODO most of this function is same in CUDA and OpenCL, move into the header DeviceContext context = nb->dev_rundata->context; - reallocateDeviceBuffer(&d_plist->sci, h_plist->sci.size(), - &d_plist->nsci, &d_plist->sci_nalloc, context); - copyToDeviceBuffer(&d_plist->sci, h_plist->sci.data(), 0, h_plist->sci.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->sci, h_plist->sci.size(), &d_plist->nsci, &d_plist->sci_nalloc, context); + copyToDeviceBuffer(&d_plist->sci, h_plist->sci.data(), 0, h_plist->sci.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); - reallocateDeviceBuffer(&d_plist->cj4, h_plist->cj4.size(), - &d_plist->ncj4, &d_plist->cj4_nalloc, context); - copyToDeviceBuffer(&d_plist->cj4, h_plist->cj4.data(), 0, h_plist->cj4.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->cj4, h_plist->cj4.size(), &d_plist->ncj4, &d_plist->cj4_nalloc, context); + copyToDeviceBuffer(&d_plist->cj4, h_plist->cj4.data(), 0, h_plist->cj4.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); - reallocateDeviceBuffer(&d_plist->imask, h_plist->cj4.size()*c_nbnxnGpuClusterpairSplit, + reallocateDeviceBuffer(&d_plist->imask, h_plist->cj4.size() * c_nbnxnGpuClusterpairSplit, &d_plist->nimask, &d_plist->imask_nalloc, context); - reallocateDeviceBuffer(&d_plist->excl, h_plist->excl.size(), - &d_plist->nexcl, &d_plist->excl_nalloc, context); - copyToDeviceBuffer(&d_plist->excl, h_plist->excl.data(), 0, h_plist->excl.size(), - stream, GpuApiCallBehavior::Async, - bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); + reallocateDeviceBuffer(&d_plist->excl, h_plist->excl.size(), &d_plist->nexcl, + &d_plist->excl_nalloc, context); + copyToDeviceBuffer(&d_plist->excl, h_plist->excl.data(), 0, h_plist->excl.size(), stream, + GpuApiCallBehavior::Async, bDoTime ? iTimers.pl_h2d.fetchNextEvent() : nullptr); if (bDoTime) { @@ -857,11 +829,10 @@ void gpu_init_pairlist(gmx_nbnxn_ocl_t *nb, } //! This function is documented in the header file -void gpu_upload_shiftvec(gmx_nbnxn_ocl_t *nb, - const nbnxn_atomdata_t *nbatom) +void gpu_upload_shiftvec(gmx_nbnxn_ocl_t* nb, const nbnxn_atomdata_t* nbatom) { - cl_atomdata_t *adat = nb->atdat; - cl_command_queue ls = nb->stream[InteractionLocality::Local]; + cl_atomdata_t* adat = nb->atdat; + cl_command_queue ls = nb->stream[InteractionLocality::Local]; /* only if we have a dynamic box */ if (nbatom->bDynamicBox || !adat->bShiftVecUploaded) @@ -873,15 +844,14 @@ void gpu_upload_shiftvec(gmx_nbnxn_ocl_t *nb, } //! This function is documented in the header file -void gpu_init_atomdata(gmx_nbnxn_ocl_t *nb, - const nbnxn_atomdata_t *nbat) +void gpu_init_atomdata(gmx_nbnxn_ocl_t* nb, const nbnxn_atomdata_t* nbat) { cl_int cl_error; int nalloc, natoms; bool realloced; bool bDoTime = nb->bDoTime == CL_TRUE; - cl_timers_t *timers = nb->timers; - cl_atomdata_t *d_atdat = nb->atdat; + cl_timers_t* timers = nb->timers; + cl_atomdata_t* d_atdat = nb->atdat; cl_command_queue ls = nb->stream[InteractionLocality::Local]; natoms = nbat->numAtoms(); @@ -922,14 +892,16 @@ void gpu_init_atomdata(gmx_nbnxn_ocl_t *nb, if (useLjCombRule(nb->nbparam->vdwtype)) { - d_atdat->lj_comb = clCreateBuffer(nb->dev_rundata->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, + d_atdat->lj_comb = clCreateBuffer(nb->dev_rundata->context, + CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, nalloc * sizeof(cl_float2), nullptr, &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); } else { - d_atdat->atom_types = clCreateBuffer(nb->dev_rundata->context, CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, + d_atdat->atom_types = clCreateBuffer(nb->dev_rundata->context, + CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, nalloc * sizeof(int), nullptr, &cl_error); GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clCreateBuffer failed: " + ocl_get_error_string(cl_error)).c_str()); @@ -950,14 +922,13 @@ void gpu_init_atomdata(gmx_nbnxn_ocl_t *nb, if (useLjCombRule(nb->nbparam->vdwtype)) { - ocl_copy_H2D_async(d_atdat->lj_comb, nbat->params().lj_comb.data(), 0, - natoms*sizeof(cl_float2), ls, bDoTime ? timers->atdat.fetchNextEvent() : nullptr); + ocl_copy_H2D_async(d_atdat->lj_comb, nbat->params().lj_comb.data(), 0, natoms * sizeof(cl_float2), + ls, bDoTime ? timers->atdat.fetchNextEvent() : nullptr); } else { - ocl_copy_H2D_async(d_atdat->atom_types, nbat->params().type.data(), 0, - natoms*sizeof(int), ls, bDoTime ? timers->atdat.fetchNextEvent() : nullptr); - + ocl_copy_H2D_async(d_atdat->atom_types, nbat->params().type.data(), 0, natoms * sizeof(int), + ls, bDoTime ? timers->atdat.fetchNextEvent() : nullptr); } if (bDoTime) @@ -972,7 +943,7 @@ void gpu_init_atomdata(gmx_nbnxn_ocl_t *nb, } /*! \brief Releases an OpenCL kernel pointer */ -static void free_kernel(cl_kernel *kernel_ptr) +static void free_kernel(cl_kernel* kernel_ptr) { cl_int gmx_unused cl_error; @@ -981,14 +952,15 @@ static void free_kernel(cl_kernel *kernel_ptr) if (*kernel_ptr) { cl_error = clReleaseKernel(*kernel_ptr); - GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clReleaseKernel failed: " + ocl_get_error_string(cl_error)).c_str()); + GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, + ("clReleaseKernel failed: " + ocl_get_error_string(cl_error)).c_str()); *kernel_ptr = nullptr; } } /*! \brief Releases a list of OpenCL kernel pointers */ -static void free_kernels(cl_kernel *kernels, int count) +static void free_kernels(cl_kernel* kernels, int count) { int i; @@ -1005,7 +977,7 @@ static void free_kernels(cl_kernel *kernels, int count) * * \param runData [in] porinter to the structure with runtime data. */ -static void free_gpu_device_runtime_data(gmx_device_runtime_data_t *runData) +static void free_gpu_device_runtime_data(gmx_device_runtime_data_t* runData) { if (runData == nullptr) { @@ -1016,22 +988,23 @@ static void free_gpu_device_runtime_data(gmx_device_runtime_data_t *runData) if (runData->context) { - cl_error = clReleaseContext(runData->context); - GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clReleaseContext failed: " + ocl_get_error_string(cl_error)).c_str()); + cl_error = clReleaseContext(runData->context); + GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, + ("clReleaseContext failed: " + ocl_get_error_string(cl_error)).c_str()); runData->context = nullptr; } if (runData->program) { - cl_error = clReleaseProgram(runData->program); - GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, ("clReleaseProgram failed: " + ocl_get_error_string(cl_error)).c_str()); + cl_error = clReleaseProgram(runData->program); + GMX_RELEASE_ASSERT(cl_error == CL_SUCCESS, + ("clReleaseProgram failed: " + ocl_get_error_string(cl_error)).c_str()); runData->program = nullptr; } - } //! This function is documented in the header file -void gpu_free(gmx_nbnxn_ocl_t *nb) +void gpu_free(gmx_nbnxn_ocl_t* nb) { if (nb == nullptr) { @@ -1071,7 +1044,7 @@ void gpu_free(gmx_nbnxn_ocl_t *nb) sfree(nb->nbparam); /* Free plist */ - auto *plist = nb->plist[InteractionLocality::Local]; + auto* plist = nb->plist[InteractionLocality::Local]; freeDeviceBuffer(&plist->sci); freeDeviceBuffer(&plist->cj4); freeDeviceBuffer(&plist->imask); @@ -1079,7 +1052,7 @@ void gpu_free(gmx_nbnxn_ocl_t *nb) sfree(plist); if (nb->bUseTwoStreams) { - auto *plist_nl = nb->plist[InteractionLocality::NonLocal]; + auto* plist_nl = nb->plist[InteractionLocality::NonLocal]; freeDeviceBuffer(&plist_nl->sci); freeDeviceBuffer(&plist_nl->cj4); freeDeviceBuffer(&plist_nl->imask); @@ -1132,7 +1105,7 @@ void gpu_free(gmx_nbnxn_ocl_t *nb) } //! This function is documented in the header file -gmx_wallclock_gpu_nbnxn_t *gpu_get_timings(gmx_nbnxn_ocl_t *nb) +gmx_wallclock_gpu_nbnxn_t* gpu_get_timings(gmx_nbnxn_ocl_t* nb) { return (nb != nullptr && nb->bDoTime) ? nb->timings : nullptr; } @@ -1147,17 +1120,15 @@ void gpu_reset_timings(nonbonded_verlet_t* nbv) } //! This function is documented in the header file -int gpu_min_ci_balanced(gmx_nbnxn_ocl_t *nb) +int gpu_min_ci_balanced(gmx_nbnxn_ocl_t* nb) { - return nb != nullptr ? - gpu_min_ci_balanced_factor * nb->dev_info->compute_units : 0; + return nb != nullptr ? gpu_min_ci_balanced_factor * nb->dev_info->compute_units : 0; } //! This function is documented in the header file -gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_ocl_t *nb) +gmx_bool gpu_is_kernel_ewald_analytical(const gmx_nbnxn_ocl_t* nb) { - return ((nb->nbparam->eeltype == eelOclEWALD_ANA) || - (nb->nbparam->eeltype == eelOclEWALD_ANA_TWIN)); + return ((nb->nbparam->eeltype == eelOclEWALD_ANA) || (nb->nbparam->eeltype == eelOclEWALD_ANA_TWIN)); } } // namespace Nbnxm diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_internal.h b/src/gromacs/nbnxm/opencl/nbnxm_ocl_internal.h index c735ab5d48..7b53305073 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_internal.h +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_internal.h @@ -44,18 +44,18 @@ #include "nbnxm_ocl_types.h" #ifndef NBNXN_OCL_INTERNAL_H -#define NBNXN_OCL_INTERNAL_H +# define NBNXN_OCL_INTERNAL_H namespace Nbnxm { /*! \brief Returns true if LJ combination rules are used in the non-bonded kernels. * - * \param[in] vdwType The VdW interaction/implementation type as defined by evdwOcl in nbnxn_ocl_types.h. - * \returns True if combination rules are used by the run + * \param[in] vdwType The VdW interaction/implementation type as defined by evdwOcl in + * nbnxn_ocl_types.h. \returns True if combination rules are used by the run */ bool useLjCombRule(int vdwType); -} // namespace Nbnxm +} // namespace Nbnxm #endif /* NBNXN_OCL_INTERNAL_H */ diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_jit_support.cpp b/src/gromacs/nbnxm/opencl/nbnxm_ocl_jit_support.cpp index fdafcad3ea..9e45e80d3c 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_jit_support.cpp +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_jit_support.cpp @@ -75,8 +75,7 @@ * not available to the user. FastGen takes care of generating both * single- and twin-cutoff versions because PME tuning might need both. */ -static const char * kernel_electrostatic_family_definitions[] = -{ +static const char* kernel_electrostatic_family_definitions[] = { " -DEL_CUTOFF -DEELNAME=_ElecCut", " -DEL_RF -DEELNAME=_ElecRF", " -DEL_EWALD_TAB -DEELNAME=_ElecEwQSTab", @@ -87,8 +86,7 @@ static const char * kernel_electrostatic_family_definitions[] = /*! \brief Array of the defines needed to generate a specific vdw flavour */ -static const char * kernel_VdW_family_definitions[] = -{ +static const char* kernel_VdW_family_definitions[] = { " -DVDWNAME=_VdwLJ", " -DLJ_COMB_GEOM -DVDWNAME=_VdwLJCombGeom", " -DLJ_COMB_LB -DVDWNAME=_VdwLJCombLB", @@ -129,17 +127,13 @@ static const char * kernel_VdW_family_definitions[] = * * \throws std::bad_alloc if out of memory */ -static std::string -makeDefinesForKernelTypes(bool bFastGen, - int eeltype, - int vdwtype) +static std::string makeDefinesForKernelTypes(bool bFastGen, int eeltype, int vdwtype) { std::string defines_for_kernel_types; if (bFastGen) { - bool bIsEwaldSingleCutoff = (eeltype == eelOclEWALD_TAB || - eeltype == eelOclEWALD_ANA); + bool bIsEwaldSingleCutoff = (eeltype == eelOclEWALD_TAB || eeltype == eelOclEWALD_ANA); if (bIsEwaldSingleCutoff) { @@ -172,11 +166,10 @@ makeDefinesForKernelTypes(bool bFastGen, * * Does not throw */ -void -nbnxn_gpu_compile_kernels(gmx_nbnxn_ocl_t *nb) +void nbnxn_gpu_compile_kernels(gmx_nbnxn_ocl_t* nb) { - gmx_bool bFastGen = TRUE; - cl_program program = nullptr; + gmx_bool bFastGen = TRUE; + cl_program program = nullptr; if (getenv("GMX_OCL_NOFASTGEN") != nullptr) { @@ -187,9 +180,8 @@ nbnxn_gpu_compile_kernels(gmx_nbnxn_ocl_t *nb) handling. */ try { - std::string extraDefines = makeDefinesForKernelTypes(bFastGen, - nb->nbparam->eeltype, - nb->nbparam->vdwtype); + std::string extraDefines = + makeDefinesForKernelTypes(bFastGen, nb->nbparam->eeltype, nb->nbparam->vdwtype); /* Here we pass macros and static const int variables defined * in include files outside the opencl as macros, to avoid @@ -197,24 +189,20 @@ nbnxn_gpu_compile_kernels(gmx_nbnxn_ocl_t *nb) * at runtime. This is particularly a problem for headers that * depend on config.h, such as pairlist.h. */ extraDefines += gmx::formatString( - " -DNBNXN_GPU_CLUSTER_SIZE=%d " - "%s", - c_nbnxnGpuClusterSize, /* Defined in nbnxn_pairlist.h */ - (nb->bPrefetchLjParam) ? "-DIATYPE_SHMEM" : "" - ); + " -DNBNXN_GPU_CLUSTER_SIZE=%d " + "%s", + c_nbnxnGpuClusterSize, /* Defined in nbnxn_pairlist.h */ + (nb->bPrefetchLjParam) ? "-DIATYPE_SHMEM" : ""); try { /* TODO when we have a proper MPI-aware logging module, the log output here should be written there */ - program = gmx::ocl::compileProgram(stderr, - "gromacs/nbnxm/opencl", - "nbnxm_ocl_kernels.cl", - extraDefines, - nb->dev_rundata->context, - nb->dev_info->ocl_gpu_id.ocl_device_id, - nb->dev_info->vendor_e); + program = gmx::ocl::compileProgram( + stderr, "gromacs/nbnxm/opencl", "nbnxm_ocl_kernels.cl", extraDefines, + nb->dev_rundata->context, nb->dev_info->ocl_gpu_id.ocl_device_id, + nb->dev_info->vendor_e); } - catch (gmx::GromacsException &e) + catch (gmx::GromacsException& e) { e.prependContext(gmx::formatString("Failed to compile NBNXN kernels for GPU #%s\n", nb->dev_info->device_name)); diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel.clh index c42b0c30e5..abaff9bc5c 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel.clh @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2012-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,27 +53,28 @@ #if defined EL_EWALD_ANA || defined EL_EWALD_TAB /* Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define EL_EWALD_ANY +# define EL_EWALD_ANY #endif -#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD || (defined EL_CUTOFF && defined CALC_ENERGIES) +#if defined EL_EWALD_ANY || defined EL_RF || defined LJ_EWALD \ + || (defined EL_CUTOFF && defined CALC_ENERGIES) /* Macro to control the calculation of exclusion forces in the kernel * We do that with Ewald (elec/vdw) and RF. Cut-off only has exclusion * energy terms. * * Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define EXCLUSION_FORCES +# define EXCLUSION_FORCES #endif #if defined LJ_EWALD_COMB_GEOM || defined LJ_EWALD_COMB_LB /* Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define LJ_EWALD +# define LJ_EWALD #endif #if defined LJ_COMB_GEOM || defined LJ_COMB_LB /* Note: convenience macro, needs to be undef-ed at the end of the file. */ -#define LJ_COMB +# define LJ_COMB #endif /* @@ -88,91 +90,92 @@ */ /* NOTE: - NB_KERNEL_FUNC_NAME differs from the CUDA equivalent as it is not a variadic macro due to OpenCL not having a support for them, this version only takes exactly 2 arguments. - Thus if more strings need to be appended a new macro must be written or it must be directly appended here. + NB_KERNEL_FUNC_NAME differs from the CUDA equivalent as it is not a variadic macro due to OpenCL + not having a support for them, this version only takes exactly 2 arguments. Thus if more strings + need to be appended a new macro must be written or it must be directly appended here. */ __attribute__((reqd_work_group_size(CL_SIZE, CL_SIZE, 1))) #ifdef cl_intel_required_subgroup_size __attribute__((intel_reqd_sub_group_size(SUBGROUP_SIZE))) #endif #ifdef PRUNE_NBL - #ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_prune_opencl) - #else +# else __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_prune_opencl) - #endif +# endif #else - #ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _VF_opencl) - #else +# else __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) - #endif +# endif #endif -( + ( #ifndef LJ_COMB - int ntypes, /* IN */ -#endif - cl_nbparam_params_t nbparam_params, /* IN */ - const __global float4 *restrict xq, /* IN */ - __global float *restrict f, /* OUT stores float3 values */ - __global float *restrict gmx_unused e_lj, /* OUT */ - __global float *restrict gmx_unused e_el, /* OUT */ - __global float *restrict fshift, /* OUT stores float3 values */ + int ntypes, /* IN */ +#endif + cl_nbparam_params_t nbparam_params, /* IN */ + const __global float4* restrict xq, /* IN */ + __global float* restrict f, /* OUT stores float3 values */ + __global float* restrict gmx_unused e_lj, /* OUT */ + __global float* restrict gmx_unused e_el, /* OUT */ + __global float* restrict fshift, /* OUT stores float3 values */ #ifdef LJ_COMB - const __global float2 *restrict lj_comb, /* IN stores float2 values */ + const __global float2* restrict lj_comb, /* IN stores float2 values */ #else - const __global int *restrict atom_types, /* IN */ + const __global int* restrict atom_types, /* IN */ #endif - const __global float *restrict shift_vec, /* IN stores float3 values */ - __constant const float* gmx_unused nbfp_climg2d, /* IN */ - __constant const float* gmx_unused nbfp_comb_climg2d, /* IN */ - __constant const float* gmx_unused coulomb_tab_climg2d, /* IN */ - const __global nbnxn_sci_t* pl_sci, /* IN */ + const __global float* restrict shift_vec, /* IN stores float3 values */ + __constant const float* gmx_unused nbfp_climg2d, /* IN */ + __constant const float* gmx_unused nbfp_comb_climg2d, /* IN */ + __constant const float* gmx_unused coulomb_tab_climg2d, /* IN */ + const __global nbnxn_sci_t* pl_sci, /* IN */ #ifndef PRUNE_NBL - const + const #endif - __global nbnxn_cj4_t* pl_cj4, /* OUT / IN */ - const __global nbnxn_excl_t* excl, /* IN */ - int bCalcFshift, /* IN */ - __local float4 *xqib /* Pointer to dyn alloc'ed shmem */ -) + __global nbnxn_cj4_t* pl_cj4, /* OUT / IN */ + const __global nbnxn_excl_t* excl, /* IN */ + int bCalcFshift, /* IN */ + __local float4* xqib /* Pointer to dyn alloc'ed shmem */ + ) { /* convenience variables */ - const cl_nbparam_params_t *const nbparam = &nbparam_params; + const cl_nbparam_params_t* const nbparam = &nbparam_params; - const float rcoulomb_sq = nbparam->rcoulomb_sq; + const float rcoulomb_sq = nbparam->rcoulomb_sq; #ifdef VDW_CUTOFF_CHECK - const float rvdw_sq = nbparam_params.rvdw_sq; + const float rvdw_sq = nbparam_params.rvdw_sq; #endif #ifdef EL_RF - const float two_k_rf = nbparam->two_k_rf; + const float two_k_rf = nbparam->two_k_rf; #endif #ifdef EL_EWALD_TAB - const float coulomb_tab_scale = nbparam->coulomb_tab_scale; + const float coulomb_tab_scale = nbparam->coulomb_tab_scale; #endif #ifdef EL_EWALD_ANA - const float beta2 = nbparam->ewald_beta*nbparam->ewald_beta; - const float beta3 = nbparam->ewald_beta*nbparam->ewald_beta*nbparam->ewald_beta; + const float beta2 = nbparam->ewald_beta * nbparam->ewald_beta; + const float beta3 = nbparam->ewald_beta * nbparam->ewald_beta * nbparam->ewald_beta; #endif #ifdef PRUNE_NBL - const float rlist_sq = nbparam->rlistOuter_sq; + const float rlist_sq = nbparam->rlistOuter_sq; #endif #ifdef CALC_ENERGIES -#ifdef EL_EWALD_ANY - const float beta = nbparam->ewald_beta; - const float ewald_shift = nbparam->sh_ewald; -#else - const float gmx_unused c_rf = nbparam->c_rf; -#endif /* EL_EWALD_ANY */ -#endif /* CALC_ENERGIES */ +# ifdef EL_EWALD_ANY + const float beta = nbparam->ewald_beta; + const float ewald_shift = nbparam->sh_ewald; +# else + const float gmx_unused c_rf = nbparam->c_rf; +# endif /* EL_EWALD_ANY */ +#endif /* CALC_ENERGIES */ /* thread/block/warp id-s */ - const unsigned int tidxi = get_local_id(0); - const unsigned int tidxj = get_local_id(1); - const unsigned int tidx = get_local_id(1) * get_local_size(0) + get_local_id(0); - const unsigned int bidx = get_group_id(0); - const unsigned int widx = tidx / WARP_SIZE; /* warp index */ + const unsigned int tidxi = get_local_id(0); + const unsigned int tidxj = get_local_id(1); + const unsigned int tidx = get_local_id(1) * get_local_size(0) + get_local_id(0); + const unsigned int bidx = get_group_id(0); + const unsigned int widx = tidx / WARP_SIZE; /* warp index */ /*! i-cluster interaction mask for a super-cluster with all NCL_PER_SUPERCL=8 bits set */ const unsigned superClInteractionMask = ((1U << NCL_PER_SUPERCL) - 1U); @@ -181,62 +184,64 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) CjType cjs = 0; #if USE_CJ_PREFETCH /* shmem buffer for cj, for both warps separately */ - cjs = (__local int *)(LOCAL_OFFSET); - #undef LOCAL_OFFSET - #define LOCAL_OFFSET (cjs + 2 * c_nbnxnGpuJgroupSize) -#endif //USE_CJ_PREFETCH + cjs = (__local int*)(LOCAL_OFFSET); +# undef LOCAL_OFFSET +# define LOCAL_OFFSET (cjs + 2 * c_nbnxnGpuJgroupSize) +#endif // USE_CJ_PREFETCH #ifdef IATYPE_SHMEM -#ifndef LJ_COMB +# ifndef LJ_COMB /* shmem buffer for i atom-type pre-loading */ - __local int *atib = (__local int *)(LOCAL_OFFSET); //NOLINT(google-readability-casting) - #undef LOCAL_OFFSET - #define LOCAL_OFFSET (atib + NCL_PER_SUPERCL * CL_SIZE) -#else - __local float2 *ljcpib = (__local float2 *)(LOCAL_OFFSET); - #undef LOCAL_OFFSET - #define LOCAL_OFFSET (ljcpib + NCL_PER_SUPERCL * CL_SIZE) -#endif + __local int* atib = (__local int*)(LOCAL_OFFSET); //NOLINT(google-readability-casting) +# undef LOCAL_OFFSET +# define LOCAL_OFFSET (atib + NCL_PER_SUPERCL * CL_SIZE) +# else + __local float2* ljcpib = (__local float2*)(LOCAL_OFFSET); +# undef LOCAL_OFFSET +# define LOCAL_OFFSET (ljcpib + NCL_PER_SUPERCL * CL_SIZE) +# endif #endif #if !REDUCE_SHUFFLE /* shmem j force buffer */ - __local float *f_buf = (__local float *)(LOCAL_OFFSET); - #undef LOCAL_OFFSET - #define LOCAL_OFFSET (f_buf + CL_SIZE * CL_SIZE * 3) + __local float* f_buf = (__local float*)(LOCAL_OFFSET); +# undef LOCAL_OFFSET +# define LOCAL_OFFSET (f_buf + CL_SIZE * CL_SIZE * 3) #else - __local float *f_buf = 0; + __local float* f_buf = 0; #endif #if !USE_SUBGROUP_ANY /* Local buffer used to implement __any warp vote function from CUDA. volatile is used to avoid compiler optimizations for AMD builds. */ - volatile __local uint *warp_any = (__local uint*)(LOCAL_OFFSET); + volatile __local uint* warp_any = (__local uint*)(LOCAL_OFFSET); #else - __local uint gmx_unused *warp_any = 0; + __local uint gmx_unused* warp_any = 0; #endif #undef LOCAL_OFFSET - const nbnxn_sci_t nb_sci = pl_sci[bidx]; /* my i super-cluster's index = current bidx */ - const int sci = nb_sci.sci; /* super-cluster */ - const int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ - const int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ + const nbnxn_sci_t nb_sci = pl_sci[bidx]; /* my i super-cluster's index = current bidx */ + const int sci = nb_sci.sci; /* super-cluster */ + const int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ + const int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ for (int i = 0; i < NCL_PER_SUPERCL; i += CL_SIZE) { /* Pre-load i-atom x and q into shared memory */ - const int ci = sci * NCL_PER_SUPERCL + tidxj+i; + const int ci = sci * NCL_PER_SUPERCL + tidxj + i; const int ai = ci * CL_SIZE + tidxi; - float4 xqbuf = xq[ai] + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1], shift_vec[3 * nb_sci.shift + 2], 0.0f); + float4 xqbuf = xq[ai] + + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1], + shift_vec[3 * nb_sci.shift + 2], 0.0f); xqbuf.w *= nbparam->epsfac; xqib[(tidxj + i) * CL_SIZE + tidxi] = xqbuf; #ifdef IATYPE_SHMEM -#ifndef LJ_COMB +# ifndef LJ_COMB /* Pre-load the i-atom types into shared memory */ - atib[(tidxj + i) * CL_SIZE + tidxi] = atom_types[ai]; -#else + atib[(tidxj + i) * CL_SIZE + tidxi] = atom_types[ai]; +# else ljcpib[(tidxj + i) * CL_SIZE + tidxi] = lj_comb[ai]; -#endif +# endif #endif } #if !USE_SUBGROUP_ANY @@ -256,8 +261,8 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) #ifdef LJ_EWALD /* TODO: we are trading registers with flops by keeping lje_coeff-s, try re-calculating it later */ - const float lje_coeff2 = nbparam->ewaldcoeff_lj*nbparam->ewaldcoeff_lj; - const float lje_coeff6_6 = lje_coeff2*lje_coeff2*lje_coeff2*ONE_SIXTH_F; + const float lje_coeff2 = nbparam->ewaldcoeff_lj * nbparam->ewaldcoeff_lj; + const float lje_coeff6_6 = lje_coeff2 * lje_coeff2 * lje_coeff2 * ONE_SIXTH_F; #endif /* LJ_EWALD */ @@ -265,51 +270,51 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) float E_lj = 0.0f; float E_el = 0.0f; -#if defined EXCLUSION_FORCES /* Ewald or RF */ - if (nb_sci.shift == CENTRAL && pl_cj4[cij4_start].cj[0] == sci*NCL_PER_SUPERCL) +# if defined EXCLUSION_FORCES /* Ewald or RF */ + if (nb_sci.shift == CENTRAL && pl_cj4[cij4_start].cj[0] == sci * NCL_PER_SUPERCL) { /* we have the diagonal: add the charge and LJ self interaction energy term */ for (int i = 0; i < NCL_PER_SUPERCL; i++) { -#if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF +# if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF const float qi = xqib[i * CL_SIZE + tidxi].w; - E_el += qi*qi; -#endif -#if defined LJ_EWALD - E_lj += nbfp_climg2d[atom_types[(sci*NCL_PER_SUPERCL + i)*CL_SIZE + tidxi]*(ntypes + 1)*2]; -#endif /* LJ_EWALD */ + E_el += qi * qi; +# endif +# if defined LJ_EWALD + E_lj += nbfp_climg2d[atom_types[(sci * NCL_PER_SUPERCL + i) * CL_SIZE + tidxi] * (ntypes + 1) * 2]; +# endif /* LJ_EWALD */ } /* divide the self term(s) equally over the j-threads, then multiply with the coefficients. */ -#ifdef LJ_EWALD +# ifdef LJ_EWALD E_lj /= CL_SIZE; - E_lj *= 0.5f*ONE_SIXTH_F*lje_coeff6_6; -#endif /* LJ_EWALD */ + E_lj *= 0.5f * ONE_SIXTH_F * lje_coeff6_6; +# endif /* LJ_EWALD */ -#if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF +# if defined EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF /* Correct for epsfac^2 due to adding qi^2 */ - E_el /= nbparam->epsfac*CL_SIZE; -#if defined EL_RF || defined EL_CUTOFF - E_el *= -0.5f*c_rf; -#else - E_el *= -beta*M_FLOAT_1_SQRTPI; /* last factor 1/sqrt(pi) */ -#endif -#endif /* EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF */ + E_el /= nbparam->epsfac * CL_SIZE; +# if defined EL_RF || defined EL_CUTOFF + E_el *= -0.5f * c_rf; +# else + E_el *= -beta * M_FLOAT_1_SQRTPI; /* last factor 1/sqrt(pi) */ +# endif +# endif /* EL_EWALD_ANY || defined EL_RF || defined EL_CUTOFF */ } -#endif /* EXCLUSION_FORCES */ +# endif /* EXCLUSION_FORCES */ -#endif /* CALC_ENERGIES */ +#endif /* CALC_ENERGIES */ #ifdef EXCLUSION_FORCES - const int nonSelfInteraction = !(nb_sci.shift == CENTRAL & tidxj <= tidxi); + const int nonSelfInteraction = !(nb_sci.shift == CENTRAL & tidxj <= tidxi); #endif /* loop over the j clusters = seen by any of the atoms in the current super-cluster */ for (int j4 = cij4_start; j4 < cij4_end; j4++) { - const int wexcl_idx = pl_cj4[j4].imei[widx].excl_ind; - unsigned int imask = pl_cj4[j4].imei[widx].imask; - const unsigned int wexcl = excl[wexcl_idx].pair[(tidx) & (WARP_SIZE - 1)]; + const int wexcl_idx = pl_cj4[j4].imei[widx].excl_ind; + unsigned int imask = pl_cj4[j4].imei[widx].imask; + const unsigned int wexcl = excl[wexcl_idx].pair[(tidx) & (WARP_SIZE - 1)]; preloadCj4(&cjs, pl_cj4[j4].cj, tidxi, tidxj, imask != 0u); @@ -325,7 +330,7 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) * TODO: check loop unrolling with NVIDIA OpenCL */ #if !defined PRUNE_NBL && !defined _NVIDIA_SOURCE_ -#pragma unroll 4 +# pragma unroll 4 #endif for (int jm = 0; jm < c_nbnxnGpuJgroupSize; jm++) { @@ -333,23 +338,23 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) { unsigned int mask_ji = (1U << (jm * NCL_PER_SUPERCL)); - const int cj = loadCj(cjs, pl_cj4[j4].cj, jm, tidxi, tidxj); - const int aj = cj * CL_SIZE + tidxj; + const int cj = loadCj(cjs, pl_cj4[j4].cj, jm, tidxi, tidxj); + const int aj = cj * CL_SIZE + tidxj; /* load j atom data */ const float4 xjqbuf = xq[aj]; const float3 xj = (float3)(xjqbuf.xyz); const float qj_f = xjqbuf.w; #ifndef LJ_COMB - const int typej = atom_types[aj]; + const int typej = atom_types[aj]; #else - const float2 ljcp_j = lj_comb[aj]; + const float2 ljcp_j = lj_comb[aj]; #endif float3 fcj_buf = (float3)(0.0f); #if !defined PRUNE_NBL -#pragma unroll 8 +# pragma unroll 8 #endif for (int i = 0; i < NCL_PER_SUPERCL; i++) { @@ -358,12 +363,12 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) const int gmx_unused ci = sci * NCL_PER_SUPERCL + i; /* i cluster index */ /* all threads load an atom from i cluster ci into shmem! */ - const float4 xiqbuf = xqib[i * CL_SIZE + tidxi]; - const float3 xi = (float3)(xiqbuf.xyz); + const float4 xiqbuf = xqib[i * CL_SIZE + tidxi]; + const float3 xi = (float3)(xiqbuf.xyz); /* distance between i and j atoms */ - const float3 rv = xi - xj; - float r2 = norm2(rv); + const float3 rv = xi - xj; + float r2 = norm2(rv); #ifdef PRUNE_NBL if (!gmx_sub_group_any(warp_any, widx, r2 < rlist_sq)) @@ -384,151 +389,161 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) /* load the rest of the i-atom parameters */ const float qi = xiqbuf.w; #ifdef IATYPE_SHMEM -#ifndef LJ_COMB - const int typei = atib[i * CL_SIZE + tidxi]; -#else - const float2 ljcp_i = ljcpib[i * CL_SIZE + tidxi]; -#endif -#else /* IATYPE_SHMEM */ - const int ai = ci * CL_SIZE + tidxi; /* i atom index */ - -#ifndef LJ_COMB - const int typei = atom_types[ai]; -#else +# ifndef LJ_COMB + const int typei = atib[i * CL_SIZE + tidxi]; +# else + const float2 ljcp_i = ljcpib[i * CL_SIZE + tidxi]; +# endif +#else /* IATYPE_SHMEM */ + const int ai = ci * CL_SIZE + tidxi; /* i atom index */ + +# ifndef LJ_COMB + const int typei = atom_types[ai]; +# else const float2 ljcp_i = lj_comb[ai]; -#endif +# endif #endif /* IATYPE_SHMEM */ /* LJ 6*C6 and 12*C12 */ #ifndef LJ_COMB const float c6 = nbfp_climg2d[2 * (ntypes * typei + typej)]; - const float c12 = nbfp_climg2d[2 * (ntypes * typei + typej)+1]; -#else /* LJ_COMB */ -#ifdef LJ_COMB_GEOM - const float c6 = ljcp_i.x * ljcp_j.x; - const float c12 = ljcp_i.y * ljcp_j.y; -#else + const float c12 = nbfp_climg2d[2 * (ntypes * typei + typej) + 1]; +#else /* LJ_COMB */ +# ifdef LJ_COMB_GEOM + const float c6 = ljcp_i.x * ljcp_j.x; + const float c12 = ljcp_i.y * ljcp_j.y; +# else /* LJ 2^(1/6)*sigma and 12*epsilon */ const float sigma = ljcp_i.x + ljcp_j.x; const float epsilon = ljcp_i.y * ljcp_j.y; -#if defined CALC_ENERGIES || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH +# if defined CALC_ENERGIES || defined LJ_FORCE_SWITCH || defined LJ_POT_SWITCH float c6, c12; convert_sigma_epsilon_to_c6_c12(sigma, epsilon, &c6, &c12); -#endif -#endif /* LJ_COMB_GEOM */ -#endif /* LJ_COMB */ +# endif +# endif /* LJ_COMB_GEOM */ +#endif /* LJ_COMB */ // Ensure distance do not become so small that r^-12 overflows - r2 = max(r2, NBNXN_MIN_RSQ); + r2 = max(r2, NBNXN_MIN_RSQ); - const float inv_r = rsqrt(r2); - const float inv_r2 = inv_r * inv_r; + const float inv_r = rsqrt(r2); + const float inv_r2 = inv_r * inv_r; #if !defined LJ_COMB_LB || defined CALC_ENERGIES - float inv_r6 = inv_r2 * inv_r2 * inv_r2; -#if defined EXCLUSION_FORCES + float inv_r6 = inv_r2 * inv_r2 * inv_r2; +# if defined EXCLUSION_FORCES /* We could mask inv_r2, but with Ewald * masking both inv_r6 and F_invr is faster */ - inv_r6 *= int_bit; -#endif /* EXCLUSION_FORCES */ - - float F_invr = inv_r6 * (c12 * inv_r6 - c6) * inv_r2; -#if defined CALC_ENERGIES || defined LJ_POT_SWITCH - float E_lj_p = int_bit * (c12 * (inv_r6 * inv_r6 + nbparam->repulsion_shift.cpot)*ONE_TWELVETH_F - - c6 * (inv_r6 + nbparam->dispersion_shift.cpot)*ONE_SIXTH_F); - -#endif -#else /* ! LJ_COMB_LB || CALC_ENERGIES */ - const float sig_r = sigma*inv_r; - const float sig_r2 = sig_r*sig_r; - float sig_r6 = sig_r2*sig_r2*sig_r2; -#if defined EXCLUSION_FORCES + inv_r6 *= int_bit; +# endif /* EXCLUSION_FORCES */ + + float F_invr = inv_r6 * (c12 * inv_r6 - c6) * inv_r2; +# if defined CALC_ENERGIES || defined LJ_POT_SWITCH + float E_lj_p = + int_bit + * (c12 * (inv_r6 * inv_r6 + nbparam->repulsion_shift.cpot) * ONE_TWELVETH_F + - c6 * (inv_r6 + nbparam->dispersion_shift.cpot) * ONE_SIXTH_F); + +# endif +#else /* ! LJ_COMB_LB || CALC_ENERGIES */ + const float sig_r = sigma * inv_r; + const float sig_r2 = sig_r * sig_r; + float sig_r6 = sig_r2 * sig_r2 * sig_r2; +# if defined EXCLUSION_FORCES sig_r6 *= int_bit; -#endif /* EXCLUSION_FORCES */ +# endif /* EXCLUSION_FORCES */ - float F_invr = epsilon * sig_r6 * (sig_r6 - 1.0f) * inv_r2; -#endif /* ! LJ_COMB_LB || CALC_ENERGIES */ + float F_invr = epsilon * sig_r6 * (sig_r6 - 1.0f) * inv_r2; +#endif /* ! LJ_COMB_LB || CALC_ENERGIES */ #ifdef LJ_FORCE_SWITCH -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES calculate_force_switch_F_E(nbparam, c6, c12, inv_r, r2, &F_invr, &E_lj_p); -#else +# else calculate_force_switch_F(nbparam, c6, c12, inv_r, r2, &F_invr); -#endif /* CALC_ENERGIES */ -#endif /* LJ_FORCE_SWITCH */ +# endif /* CALC_ENERGIES */ +#endif /* LJ_FORCE_SWITCH */ #ifdef LJ_EWALD -#ifdef LJ_EWALD_COMB_GEOM -#ifdef CALC_ENERGIES - calculate_lj_ewald_comb_geom_F_E(nbfp_comb_climg2d, nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, int_bit, &F_invr, &E_lj_p); -#else - calculate_lj_ewald_comb_geom_F(nbfp_comb_climg2d, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, &F_invr); -#endif /* CALC_ENERGIES */ -#elif defined LJ_EWALD_COMB_LB - calculate_lj_ewald_comb_LB_F_E(nbfp_comb_climg2d, nbparam, typei, typej, r2, inv_r2, lje_coeff2, lje_coeff6_6, -#ifdef CALC_ENERGIES +# ifdef LJ_EWALD_COMB_GEOM +# ifdef CALC_ENERGIES + calculate_lj_ewald_comb_geom_F_E( + nbfp_comb_climg2d, nbparam, typei, typej, r2, inv_r2, + lje_coeff2, lje_coeff6_6, int_bit, &F_invr, &E_lj_p); +# else + calculate_lj_ewald_comb_geom_F(nbfp_comb_climg2d, typei, typej, r2, inv_r2, + lje_coeff2, lje_coeff6_6, &F_invr); +# endif /* CALC_ENERGIES */ +# elif defined LJ_EWALD_COMB_LB + calculate_lj_ewald_comb_LB_F_E(nbfp_comb_climg2d, nbparam, typei, typej, + r2, inv_r2, lje_coeff2, lje_coeff6_6, +# ifdef CALC_ENERGIES int_bit, true, &F_invr, &E_lj_p -#else +# else 0, false, &F_invr, 0 -#endif /* CALC_ENERGIES */ - ); -#endif /* LJ_EWALD_COMB_GEOM */ -#endif /* LJ_EWALD */ +# endif /* CALC_ENERGIES */ + ); +# endif /* LJ_EWALD_COMB_GEOM */ +#endif /* LJ_EWALD */ #ifdef LJ_POT_SWITCH -#ifdef CALC_ENERGIES +# ifdef CALC_ENERGIES calculate_potential_switch_F_E(nbparam, inv_r, r2, &F_invr, &E_lj_p); -#else +# else calculate_potential_switch_F(nbparam, inv_r, r2, &F_invr, &E_lj_p); -#endif /* CALC_ENERGIES */ -#endif /* LJ_POT_SWITCH */ +# endif /* CALC_ENERGIES */ +#endif /* LJ_POT_SWITCH */ #ifdef VDW_CUTOFF_CHECK /* Separate VDW cut-off check to enable twin-range cut-offs * (rvdw < rcoulomb <= rlist) */ - const float vdw_in_range = (r2 < rvdw_sq) ? 1.0f : 0.0f; - F_invr *= vdw_in_range; -#ifdef CALC_ENERGIES - E_lj_p *= vdw_in_range; -#endif -#endif /* VDW_CUTOFF_CHECK */ + const float vdw_in_range = (r2 < rvdw_sq) ? 1.0f : 0.0f; + F_invr *= vdw_in_range; +# ifdef CALC_ENERGIES + E_lj_p *= vdw_in_range; +# endif +#endif /* VDW_CUTOFF_CHECK */ #ifdef CALC_ENERGIES - E_lj += E_lj_p; + E_lj += E_lj_p; #endif #ifdef EL_CUTOFF -#ifdef EXCLUSION_FORCES - F_invr += qi * qj_f * int_bit * inv_r2 * inv_r; -#else - F_invr += qi * qj_f * inv_r2 * inv_r; -#endif +# ifdef EXCLUSION_FORCES + F_invr += qi * qj_f * int_bit * inv_r2 * inv_r; +# else + F_invr += qi * qj_f * inv_r2 * inv_r; +# endif #endif #ifdef EL_RF - F_invr += qi * qj_f * (int_bit*inv_r2 * inv_r - two_k_rf); + F_invr += qi * qj_f * (int_bit * inv_r2 * inv_r - two_k_rf); #endif #if defined EL_EWALD_ANA - F_invr += qi * qj_f * (int_bit*inv_r2*inv_r + pmecorrF(beta2*r2)*beta3); + F_invr += qi * qj_f + * (int_bit * inv_r2 * inv_r + pmecorrF(beta2 * r2) * beta3); #elif defined EL_EWALD_TAB - F_invr += qi * qj_f * (int_bit*inv_r2 - - interpolate_coulomb_force_r(coulomb_tab_climg2d, r2 * inv_r, coulomb_tab_scale) - ) * inv_r; -#endif /* EL_EWALD_ANA/TAB */ + F_invr += qi * qj_f + * (int_bit * inv_r2 + - interpolate_coulomb_force_r(coulomb_tab_climg2d, r2 * inv_r, + coulomb_tab_scale)) + * inv_r; +#endif /* EL_EWALD_ANA/TAB */ #ifdef CALC_ENERGIES -#ifdef EL_CUTOFF - E_el += qi * qj_f * (int_bit*inv_r - c_rf); -#endif -#ifdef EL_RF - E_el += qi * qj_f * (int_bit*inv_r + 0.5f * two_k_rf * r2 - c_rf); -#endif -#ifdef EL_EWALD_ANY +# ifdef EL_CUTOFF + E_el += qi * qj_f * (int_bit * inv_r - c_rf); +# endif +# ifdef EL_RF + E_el += qi * qj_f * (int_bit * inv_r + 0.5f * two_k_rf * r2 - c_rf); +# endif +# ifdef EL_EWALD_ANY /* 1.0f - erff is faster than erfcf */ - E_el += qi * qj_f * (inv_r * (int_bit - erf(r2 * inv_r * beta)) - int_bit * ewald_shift); -#endif /* EL_EWALD_ANY */ + E_el += qi * qj_f + * (inv_r * (int_bit - erf(r2 * inv_r * beta)) - int_bit * ewald_shift); +# endif /* EL_EWALD_ANY */ #endif const float3 f_ij = rv * F_invr; @@ -563,8 +578,7 @@ __kernel void NB_KERNEL_FUNC_NAME(nbnxn_kernel, _F_opencl) bCalcFshift = 0; } /* reduce i forces */ - reduce_force_i_and_shift(f_buf, fci_buf, f, bCalcFshift != 0, tidxi, tidxj, sci, - nb_sci.shift, fshift); + reduce_force_i_and_shift(f_buf, fci_buf, f, bCalcFshift != 0, tidxi, tidxj, sci, nb_sci.shift, fshift); #ifdef CALC_ENERGIES reduce_energy(f_buf, E_lj, E_el, e_lj, e_el, tidx); diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_pruneonly.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_pruneonly.clh index 6b1debe105..96a40b60d6 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_pruneonly.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_pruneonly.clh @@ -57,52 +57,52 @@ __attribute__((reqd_work_group_size(CL_SIZE, CL_SIZE, NTHREAD_Z))) #ifdef HAVE_FRESH_LIST -__kernel void nbnxn_kernel_prune_opencl +__kernel void +nbnxn_kernel_prune_opencl #else -__kernel void nbnxn_kernel_prune_rolling_opencl +__kernel void +nbnxn_kernel_prune_rolling_opencl #endif -( - cl_nbparam_params_t nbparam_params, - const __global float4 *restrict xq, - const __global float *restrict shift_vec, - const __global nbnxn_sci_t *pl_sci, - __global nbnxn_cj4_t *pl_cj4, + (cl_nbparam_params_t nbparam_params, + const __global float4* restrict xq, + const __global float* restrict shift_vec, + const __global nbnxn_sci_t* pl_sci, + __global nbnxn_cj4_t* pl_cj4, #if !defined HAVE_FRESH_LIST - const + const #endif - __global unsigned int *restrict prePrunedImask, - int numParts, - int part, - __local float4 *xib -) + __global unsigned int* restrict prePrunedImask, + int numParts, + int part, + __local float4* xib) { /* convenience variables */ - const cl_nbparam_params_t *const nbparam = &nbparam_params; + const cl_nbparam_params_t* const nbparam = &nbparam_params; - const float rlistOuter_sq = nbparam->rlistOuter_sq; - const float rlistInner_sq = nbparam->rlistInner_sq; + const float rlistOuter_sq = nbparam->rlistOuter_sq; + const float rlistInner_sq = nbparam->rlistInner_sq; /* thread/block/warp id-s */ - const unsigned int tidxi = get_local_id(0); - const unsigned int tidxj = get_local_id(1); - const unsigned int tidx = get_local_id(1) * get_local_size(0) + get_local_id(0); + const unsigned int tidxi = get_local_id(0); + const unsigned int tidxj = get_local_id(1); + const unsigned int tidx = get_local_id(1) * get_local_size(0) + get_local_id(0); #if NTHREAD_Z == 1 - const unsigned int tidxz = 0; + const unsigned int tidxz = 0; #else - const unsigned int tidxz = get_local_id(2); + const unsigned int tidxz = get_local_id(2); #endif - const unsigned int bidx = get_group_id(0); - const unsigned int widx = tidx / WARP_SIZE; + const unsigned int bidx = get_group_id(0); + const unsigned int widx = tidx / WARP_SIZE; #ifdef HAVE_FRESH_LIST const bool haveFreshList = true; #else - const bool haveFreshList = false; + const bool haveFreshList = false; #endif // TODO move these consts to utils and unify their use with the nonbonded kernels - const int c_numClPerSupercl = NCL_PER_SUPERCL; - const int c_clSize = CL_SIZE; + const int c_numClPerSupercl = NCL_PER_SUPERCL; + const int c_clSize = CL_SIZE; // TODO pass this value at compile-time as a macro const int c_nbnxnGpuClusterpairSplit = 2; @@ -110,47 +110,52 @@ __kernel void nbnxn_kernel_prune_rolling_opencl /*! i-cluster interaction mask for a super-cluster with all c_numClPerSupercl=8 bits set */ const unsigned superClInteractionMask = ((1U << c_numClPerSupercl) - 1U); - #define LOCAL_OFFSET (xib + c_numClPerSupercl * c_clSize) +#define LOCAL_OFFSET (xib + c_numClPerSupercl * c_clSize) /* shmem buffer for i cj pre-loading */ CjType cjs = 0; #if USE_CJ_PREFETCH - cjs = (((__local int *)(LOCAL_OFFSET)) + tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize); - #undef LOCAL_OFFSET - /* Offset calculated using xib because cjs depends on on tidxz! */ - #define LOCAL_OFFSET (((__local int *)(xib + c_numClPerSupercl * c_clSize)) + (NTHREAD_Z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize)) + cjs = (((__local int*)(LOCAL_OFFSET)) + tidxz * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize); +# undef LOCAL_OFFSET +/* Offset calculated using xib because cjs depends on on tidxz! */ +# define LOCAL_OFFSET \ + (((__local int*)(xib + c_numClPerSupercl * c_clSize)) \ + + (NTHREAD_Z * c_nbnxnGpuClusterpairSplit * c_nbnxnGpuJgroupSize)) #endif #if !USE_SUBGROUP_ANY /* Local buffer used to implement __any warp vote function from CUDA. volatile is used to avoid compiler optimizations for AMD builds. */ - volatile __local uint *const warp_any = (__local uint*)(LOCAL_OFFSET); - const unsigned int warpVoteSlot = NTHREAD_Z*tidxz + widx; + volatile __local uint* const warp_any = (__local uint*)(LOCAL_OFFSET); + const unsigned int warpVoteSlot = NTHREAD_Z * tidxz + widx; /* Initialise warp vote.*/ if (tidx == 0 || tidx == 32) { warp_any[warpVoteSlot] = 0; } #else - __local uint *const warp_any = 0; + __local uint* const warp_any = 0; const unsigned int warpVoteSlot = 0; #endif - #undef LOCAL_OFFSET +#undef LOCAL_OFFSET - const nbnxn_sci_t nb_sci = pl_sci[bidx*numParts + part]; /* my i super-cluster's index = sciOffset + current bidx * numParts + part */ - const int sci = nb_sci.sci; /* super-cluster */ - const int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ - const int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ + const nbnxn_sci_t nb_sci = + pl_sci[bidx * numParts + part]; /* my i super-cluster's index = sciOffset + current bidx * numParts + part */ + const int sci = nb_sci.sci; /* super-cluster */ + const int cij4_start = nb_sci.cj4_ind_start; /* first ...*/ + const int cij4_end = nb_sci.cj4_ind_end; /* and last index of j clusters */ if (tidxz == 0) { for (int i = 0; i < NCL_PER_SUPERCL; i += CL_SIZE) { /* Pre-load i-atom x and q into shared memory */ - const int ci = sci * c_numClPerSupercl + tidxj+i; + const int ci = sci * c_numClPerSupercl + tidxj + i; const int ai = ci * c_clSize + tidxi; /* We don't need q, but using float4 in shmem avoids bank conflicts */ const float4 tmp = xq[ai]; - const float4 xi = tmp + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1], shift_vec[3 * nb_sci.shift + 2], 0.0f); + const float4 xi = tmp + + (float4)(shift_vec[3 * nb_sci.shift], shift_vec[3 * nb_sci.shift + 1], + shift_vec[3 * nb_sci.shift + 2], 0.0f); xib[(tidxj + i) * c_clSize + tidxi] = xi; } } @@ -165,7 +170,7 @@ __kernel void nbnxn_kernel_prune_rolling_opencl if (haveFreshList) { /* Read the mask from the list transferred from the CPU */ - imaskFull = pl_cj4[j4].imei[widx].imask; + imaskFull = pl_cj4[j4].imei[widx].imask; /* We attempt to prune all pairs present in the original list */ imaskCheck = imaskFull; imaskNew = 0; @@ -173,9 +178,9 @@ __kernel void nbnxn_kernel_prune_rolling_opencl else { /* Read the mask from the "warp-pruned" by rlistOuter mask array */ - imaskFull = prePrunedImask[j4*c_nbnxnGpuClusterpairSplit + widx]; + imaskFull = prePrunedImask[j4 * c_nbnxnGpuClusterpairSplit + widx]; /* Read the old rolling pruned mask, use as a base for new */ - imaskNew = pl_cj4[j4].imei[widx].imask; + imaskNew = pl_cj4[j4].imei[widx].imask; /* We only need to check pairs with different mask */ imaskCheck = (imaskNew ^ imaskFull); } @@ -189,14 +194,14 @@ __kernel void nbnxn_kernel_prune_rolling_opencl { if (imaskCheck & (superClInteractionMask << (jm * c_numClPerSupercl))) { - unsigned int mask_ji = (1U << (jm * c_numClPerSupercl)); + unsigned int mask_ji = (1U << (jm * c_numClPerSupercl)); - const int cj = loadCj(cjs, pl_cj4[j4].cj, jm, tidxi, tidxj); - const int aj = cj * c_clSize + tidxj; + const int cj = loadCj(cjs, pl_cj4[j4].cj, jm, tidxi, tidxj); + const int aj = cj * c_clSize + tidxj; /* load j atom data */ - const float4 tmp = xq[aj]; - const float3 xj = (float3)(tmp.xyz); + const float4 tmp = xq[aj]; + const float3 xj = (float3)(tmp.xyz); #pragma unroll 8 for (int i = 0; i < c_numClPerSupercl; i++) @@ -237,7 +242,7 @@ __kernel void nbnxn_kernel_prune_rolling_opencl #ifdef HAVE_FRESH_LIST { /* copy the list pruned to rlistOuter to a separate buffer */ - prePrunedImask[j4*c_nbnxnGpuClusterpairSplit + widx] = imaskFull; + prePrunedImask[j4 * c_nbnxnGpuClusterpairSplit + widx] = imaskFull; } #endif /* update the imask with only the pairs up to rlistInner */ diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_utils.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_utils.clh index c63c10d957..73b81efb51 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_utils.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernel_utils.clh @@ -42,38 +42,39 @@ #include "nbnxm_ocl_consts.h" -#define CL_SIZE (NBNXN_GPU_CLUSTER_SIZE) -#define NCL_PER_SUPERCL c_nbnxnGpuNumClusterPerSupercluster +#define CL_SIZE (NBNXN_GPU_CLUSTER_SIZE) +#define NCL_PER_SUPERCL c_nbnxnGpuNumClusterPerSupercluster -#define WARP_SIZE (CL_SIZE*CL_SIZE/2) //Currently only c_nbnxnGpuClusterpairSplit=2 supported +#define WARP_SIZE (CL_SIZE * CL_SIZE / 2) // Currently only c_nbnxnGpuClusterpairSplit=2 supported #if defined _NVIDIA_SOURCE_ || defined _AMD_SOURCE_ /* Currently we enable CJ prefetch for AMD/NVIDIA and disable it for other vendors * Note that this should precede the kernel_utils include. */ -#define USE_CJ_PREFETCH 1 +# define USE_CJ_PREFETCH 1 #else -#define USE_CJ_PREFETCH 0 +# define USE_CJ_PREFETCH 0 #endif -#if defined cl_intel_subgroups || defined cl_khr_subgroups || (defined __OPENCL_VERSION__ && __OPENCL_VERSION__ >= 210) -#define HAVE_SUBGROUP 1 +#if defined cl_intel_subgroups || defined cl_khr_subgroups \ + || (defined __OPENCL_VERSION__ && __OPENCL_VERSION__ >= 210) +# define HAVE_SUBGROUP 1 #else -#define HAVE_SUBGROUP 0 +# define HAVE_SUBGROUP 0 #endif #ifdef cl_intel_subgroups -#define HAVE_INTEL_SUBGROUP 1 +# define HAVE_INTEL_SUBGROUP 1 #else -#define HAVE_INTEL_SUBGROUP 0 +# define HAVE_INTEL_SUBGROUP 0 #endif #if defined _INTEL_SOURCE_ -#define SUBGROUP_SIZE 8 +# define SUBGROUP_SIZE 8 #elif defined _AMD_SOURCE_ -#define SUBGROUP_SIZE 64 +# define SUBGROUP_SIZE 64 #else -#define SUBGROUP_SIZE 32 +# define SUBGROUP_SIZE 32 #endif #define REDUCE_SHUFFLE (HAVE_INTEL_SUBGROUP && CL_SIZE == 4 && SUBGROUP_SIZE == WARP_SIZE) @@ -86,36 +87,37 @@ //------------------- #ifndef NBNXN_OPENCL_KERNEL_UTILS_CLH -#define NBNXN_OPENCL_KERNEL_UTILS_CLH - -#if CL_SIZE == 8 -#define WARP_SIZE_LOG2 (5) -#define CL_SIZE_LOG2 (3) -#elif CL_SIZE == 4 -#define WARP_SIZE_LOG2 (3) -#define CL_SIZE_LOG2 (2) -#else -#error unsupported CL_SIZE -#endif +# define NBNXN_OPENCL_KERNEL_UTILS_CLH + +# if CL_SIZE == 8 +# define WARP_SIZE_LOG2 (5) +# define CL_SIZE_LOG2 (3) +# elif CL_SIZE == 4 +# define WARP_SIZE_LOG2 (3) +# define CL_SIZE_LOG2 (2) +# else +# error unsupported CL_SIZE +# endif -#define CL_SIZE_SQ (CL_SIZE * CL_SIZE) -#define FBUF_STRIDE (CL_SIZE_SQ) +# define CL_SIZE_SQ (CL_SIZE * CL_SIZE) +# define FBUF_STRIDE (CL_SIZE_SQ) -#define ONE_SIXTH_F 0.16666667f -#define ONE_TWELVETH_F 0.08333333f +# define ONE_SIXTH_F 0.16666667f +# define ONE_TWELVETH_F 0.08333333f -#ifdef __GNUC__ +# ifdef __GNUC__ /* GCC, clang, and some ICC pretending to be GCC */ -# define gmx_unused __attribute__ ((unused)) -#else -# define gmx_unused -#endif +# define gmx_unused __attribute__((unused)) +# else +# define gmx_unused +# endif // Data structures shared between OpenCL device code and OpenCL host code // TODO: review, improve // Replaced real by float for now, to avoid including any other header -typedef struct { +typedef struct +{ float c2; float c3; float cpot; @@ -128,7 +130,8 @@ typedef struct { * force = force*dsw - potential*sw * potential *= sw */ -typedef struct { +typedef struct +{ float c3; float c4; float c5; @@ -139,99 +142,101 @@ typedef struct { typedef struct cl_nbparam_params { - int eeltype; /**< type of electrostatics, takes values from #eelCu */ - int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ + int eeltype; /**< type of electrostatics, takes values from #eelCu */ + int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ - float epsfac; /**< charge multiplication factor */ - float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ - float two_k_rf; /**< Reaction-field electrostatics constant */ - float ewald_beta; /**< Ewald/PME parameter */ - float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ - float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ - float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ + float epsfac; /**< charge multiplication factor */ + float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ + float two_k_rf; /**< Reaction-field electrostatics constant */ + float ewald_beta; /**< Ewald/PME parameter */ + float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ + float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ + float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ - float rcoulomb_sq; /**< Coulomb cut-off squared */ + float rcoulomb_sq; /**< Coulomb cut-off squared */ - float rvdw_sq; /**< VdW cut-off squared */ - float rvdw_switch; /**< VdW switched cut-off */ - float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ - float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared XXX: this is only needed in the pruning kernels, but for now we also pass it to the nonbondeds */ + float rvdw_sq; /**< VdW cut-off squared */ + float rvdw_switch; /**< VdW switched cut-off */ + float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ + float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared XXX: this is only needed in the pruning kernels, but for now we also pass it to the nonbondeds */ shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ switch_consts_t vdw_switch; /**< VdW switch constants */ /* Ewald Coulomb force table data - accessed through texture memory */ - float coulomb_tab_scale; /**< table scale/spacing */ -}cl_nbparam_params_t; - -typedef struct { - int sci; /* i-super-cluster */ - int shift; /* Shift vector index plus possible flags */ - int cj4_ind_start; /* Start index into cj4 */ - int cj4_ind_end; /* End index into cj4 */ + float coulomb_tab_scale; /**< table scale/spacing */ +} cl_nbparam_params_t; + +typedef struct +{ + int sci; /* i-super-cluster */ + int shift; /* Shift vector index plus possible flags */ + int cj4_ind_start; /* Start index into cj4 */ + int cj4_ind_end; /* End index into cj4 */ } nbnxn_sci_t; -typedef struct { +typedef struct +{ unsigned int imask; /* The i-cluster interactions mask for 1 warp */ int excl_ind; /* Index into the exclusion array for 1 warp */ } nbnxn_im_ei_t; -typedef struct { +typedef struct +{ int cj[4]; /* The 4 j-clusters */ nbnxn_im_ei_t imei[2]; /* The i-cluster mask data for 2 warps */ } nbnxn_cj4_t; -typedef struct { - unsigned int pair[CL_SIZE*CL_SIZE/2]; /* Topology exclusion interaction bits for one warp, - * each unsigned has bitS for 4*8 i clusters - */ +typedef struct +{ + unsigned int pair[CL_SIZE * CL_SIZE / 2]; /* Topology exclusion interaction bits for one warp, + * each unsigned has bitS for 4*8 i clusters + */ } nbnxn_excl_t; /*! i-cluster interaction mask for a super-cluster with all NCL_PER_SUPERCL bits set */ __constant unsigned supercl_interaction_mask = ((1U << NCL_PER_SUPERCL) - 1U); -gmx_opencl_inline -void preloadCj4Generic(__local int *sm_cjPreload, - const __global int *gm_cj, - int tidxi, - int tidxj, - bool gmx_unused iMaskCond) +gmx_opencl_inline void preloadCj4Generic(__local int* sm_cjPreload, + const __global int* gm_cj, + int tidxi, + int tidxj, + bool gmx_unused iMaskCond) { /* Pre-load cj into shared memory */ -#if defined _AMD_SOURCE_ //TODO: fix by setting c_nbnxnGpuClusterpairSplit properly +# if defined _AMD_SOURCE_ // TODO: fix by setting c_nbnxnGpuClusterpairSplit properly if (tidxj == 0 & tidxi < c_nbnxnGpuJgroupSize) { sm_cjPreload[tidxi] = gm_cj[tidxi]; } -#else +# else const int c_clSize = CL_SIZE; const int c_nbnxnGpuClusterpairSplit = 2; - const int c_splitClSize = c_clSize/c_nbnxnGpuClusterpairSplit; + const int c_splitClSize = c_clSize / c_nbnxnGpuClusterpairSplit; if ((tidxj == 0 | tidxj == c_splitClSize) & (tidxi < c_nbnxnGpuJgroupSize)) { - sm_cjPreload[tidxi + tidxj * c_nbnxnGpuJgroupSize/c_splitClSize] = gm_cj[tidxi]; + sm_cjPreload[tidxi + tidxj * c_nbnxnGpuJgroupSize / c_splitClSize] = gm_cj[tidxi]; } -#endif +# endif } -#if USE_SUBGROUP_PRELOAD -gmx_opencl_inline -int preloadCj4Subgroup(const __global int *gm_cj) +# if USE_SUBGROUP_PRELOAD +gmx_opencl_inline int preloadCj4Subgroup(const __global int* gm_cj) { - //loads subgroup-size # of elements (8) instead of the 4 required - //equivalent to *cjs = *gm_cj - return intel_sub_group_block_read((const __global uint *)gm_cj); + // loads subgroup-size # of elements (8) instead of the 4 required + // equivalent to *cjs = *gm_cj + return intel_sub_group_block_read((const __global uint*)gm_cj); } -#endif //USE_SUBGROUP_PRELOAD +# endif // USE_SUBGROUP_PRELOAD -#if USE_SUBGROUP_PRELOAD +# if USE_SUBGROUP_PRELOAD typedef size_t CjType; -#else +# else typedef __local int* CjType; -#endif +# endif /*! \brief Preload cj4 * @@ -242,36 +247,31 @@ typedef __local int* CjType; * It is the caller's responsibility to make sure that data is consumed only when * it's ready. This function does not call a barrier. */ -gmx_opencl_inline -void preloadCj4(CjType gmx_unused *cjs, - const __global int gmx_unused *gm_cj, - int gmx_unused tidxi, - int gmx_unused tidxj, - bool gmx_unused iMaskCond) -{ -#if USE_SUBGROUP_PRELOAD +gmx_opencl_inline void preloadCj4(CjType gmx_unused* cjs, + const __global int gmx_unused* gm_cj, + int gmx_unused tidxi, + int gmx_unused tidxj, + bool gmx_unused iMaskCond) +{ +# if USE_SUBGROUP_PRELOAD *cjs = preloadCj4Subgroup(gm_cj); -#elif USE_CJ_PREFETCH +# elif USE_CJ_PREFETCH preloadCj4Generic(*cjs, gm_cj, tidxi, tidxj, iMaskCond); -#else - //nothing to do -#endif +# else + // nothing to do +# endif } -gmx_opencl_inline -int loadCjPreload(__local int * sm_cjPreload, - int jm, - int gmx_unused tidxi, - int gmx_unused tidxj) +gmx_opencl_inline int loadCjPreload(__local int* sm_cjPreload, int jm, int gmx_unused tidxi, int gmx_unused tidxj) { -#if defined _AMD_SOURCE_ - int warpLoadOffset = 0; //TODO: fix by setting c_nbnxnGpuClusterpairSplit properly -#else - const int c_clSize = CL_SIZE; +# if defined _AMD_SOURCE_ + int warpLoadOffset = 0; // TODO: fix by setting c_nbnxnGpuClusterpairSplit properly +# else + const int c_clSize = CL_SIZE; const int c_nbnxnGpuClusterpairSplit = 2; - const int c_splitClSize = c_clSize/c_nbnxnGpuClusterpairSplit; - int warpLoadOffset = (tidxj & c_splitClSize) * c_nbnxnGpuJgroupSize/c_splitClSize; -#endif + const int c_splitClSize = c_clSize / c_nbnxnGpuClusterpairSplit; + int warpLoadOffset = (tidxj & c_splitClSize) * c_nbnxnGpuJgroupSize / c_splitClSize; +# endif return sm_cjPreload[jm + warpLoadOffset]; } @@ -279,43 +279,37 @@ int loadCjPreload(__local int * sm_cjPreload, * * If cj4 preloading is enabled, it loads from the local memory, otherwise from global. */ -gmx_opencl_inline -int loadCj(CjType cjs, const __global int gmx_unused* gm_cj, - int jm, int gmx_unused tidxi, int gmx_unused tidxj) +gmx_opencl_inline int +loadCj(CjType cjs, const __global int gmx_unused* gm_cj, int jm, int gmx_unused tidxi, int gmx_unused tidxj) { -#if USE_SUBGROUP_PRELOAD +# if USE_SUBGROUP_PRELOAD return sub_group_broadcast(cjs, jm); -#elif USE_CJ_PREFETCH +# elif USE_CJ_PREFETCH return loadCjPreload(cjs, jm, tidxi, tidxj); -#else +# else return gm_cj[jm]; -#endif +# endif } /*! Convert LJ sigma,epsilon parameters to C6,C12. */ -gmx_opencl_inline -void convert_sigma_epsilon_to_c6_c12(const float sigma, - const float epsilon, - float *c6, - float *c12) +gmx_opencl_inline void convert_sigma_epsilon_to_c6_c12(const float sigma, const float epsilon, float* c6, float* c12) { float sigma2, sigma6; sigma2 = sigma * sigma; - sigma6 = sigma2 *sigma2 * sigma2; + sigma6 = sigma2 * sigma2 * sigma2; *c6 = epsilon * sigma6; *c12 = *c6 * sigma6; } /*! Apply force switch, force + energy version. */ -gmx_opencl_inline -void calculate_force_switch_F(const cl_nbparam_params_t *nbparam, - float c6, - float c12, - float inv_r, - float r2, - float *F_invr) +gmx_opencl_inline void calculate_force_switch_F(const cl_nbparam_params_t* nbparam, + float c6, + float c12, + float inv_r, + float r2, + float* F_invr) { float r, r_switch; @@ -325,24 +319,22 @@ void calculate_force_switch_F(const cl_nbparam_params_t *nbparam, float repu_shift_V2 = nbparam->repulsion_shift.c2; float repu_shift_V3 = nbparam->repulsion_shift.c3; - r = r2 * inv_r; - r_switch = r - nbparam->rvdw_switch; - r_switch = r_switch >= 0.0f ? r_switch : 0.0f; + r = r2 * inv_r; + r_switch = r - nbparam->rvdw_switch; + r_switch = r_switch >= 0.0f ? r_switch : 0.0f; - *F_invr += - -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r + - c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r; + *F_invr += -c6 * (disp_shift_V2 + disp_shift_V3 * r_switch) * r_switch * r_switch * inv_r + + c12 * (repu_shift_V2 + repu_shift_V3 * r_switch) * r_switch * r_switch * inv_r; } /*! Apply force switch, force-only version. */ -gmx_opencl_inline -void calculate_force_switch_F_E(const cl_nbparam_params_t *nbparam, - float c6, - float c12, - float inv_r, - float r2, - float *F_invr, - float *E_lj) +gmx_opencl_inline void calculate_force_switch_F_E(const cl_nbparam_params_t* nbparam, + float c6, + float c12, + float inv_r, + float r2, + float* F_invr, + float* E_lj) { float r, r_switch; @@ -352,30 +344,27 @@ void calculate_force_switch_F_E(const cl_nbparam_params_t *nbparam, float repu_shift_V2 = nbparam->repulsion_shift.c2; float repu_shift_V3 = nbparam->repulsion_shift.c3; - float disp_shift_F2 = nbparam->dispersion_shift.c2/3; - float disp_shift_F3 = nbparam->dispersion_shift.c3/4; - float repu_shift_F2 = nbparam->repulsion_shift.c2/3; - float repu_shift_F3 = nbparam->repulsion_shift.c3/4; - - r = r2 * inv_r; - r_switch = r - nbparam->rvdw_switch; - r_switch = r_switch >= 0.0f ? r_switch : 0.0f; - - *F_invr += - -c6*(disp_shift_V2 + disp_shift_V3*r_switch)*r_switch*r_switch*inv_r + - c12*(repu_shift_V2 + repu_shift_V3*r_switch)*r_switch*r_switch*inv_r; - *E_lj += - c6*(disp_shift_F2 + disp_shift_F3*r_switch)*r_switch*r_switch*r_switch - - c12*(repu_shift_F2 + repu_shift_F3*r_switch)*r_switch*r_switch*r_switch; + float disp_shift_F2 = nbparam->dispersion_shift.c2 / 3; + float disp_shift_F3 = nbparam->dispersion_shift.c3 / 4; + float repu_shift_F2 = nbparam->repulsion_shift.c2 / 3; + float repu_shift_F3 = nbparam->repulsion_shift.c3 / 4; + + r = r2 * inv_r; + r_switch = r - nbparam->rvdw_switch; + r_switch = r_switch >= 0.0f ? r_switch : 0.0f; + + *F_invr += -c6 * (disp_shift_V2 + disp_shift_V3 * r_switch) * r_switch * r_switch * inv_r + + c12 * (repu_shift_V2 + repu_shift_V3 * r_switch) * r_switch * r_switch * inv_r; + *E_lj += c6 * (disp_shift_F2 + disp_shift_F3 * r_switch) * r_switch * r_switch * r_switch + - c12 * (repu_shift_F2 + repu_shift_F3 * r_switch) * r_switch * r_switch * r_switch; } /*! Apply potential switch, force-only version. */ -gmx_opencl_inline -void calculate_potential_switch_F(const cl_nbparam_params_t *nbparam, - float inv_r, - float r2, - float *F_invr, - const float *E_lj) +gmx_opencl_inline void calculate_potential_switch_F(const cl_nbparam_params_t* nbparam, + float inv_r, + float r2, + float* F_invr, + const float* E_lj) { float r, r_switch; float sw, dsw; @@ -394,20 +383,19 @@ void calculate_potential_switch_F(const cl_nbparam_params_t *nbparam, /* Unlike in the F+E kernel, conditional is faster here */ if (r_switch > 0.0f) { - sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5*r_switch)*r_switch)*r_switch*r_switch*r_switch; - dsw = (switch_F2 + (switch_F3 + switch_F4*r_switch)*r_switch)*r_switch*r_switch; + sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5 * r_switch) * r_switch) * r_switch * r_switch * r_switch; + dsw = (switch_F2 + (switch_F3 + switch_F4 * r_switch) * r_switch) * r_switch * r_switch; - *F_invr = (*F_invr)*sw - inv_r*(*E_lj)*dsw; + *F_invr = (*F_invr) * sw - inv_r * (*E_lj) * dsw; } } /*! Apply potential switch, force + energy version. */ -gmx_opencl_inline -void calculate_potential_switch_F_E(const cl_nbparam_params_t *nbparam, - float inv_r, - float r2, - float *F_invr, - float *E_lj) +gmx_opencl_inline void calculate_potential_switch_F_E(const cl_nbparam_params_t* nbparam, + float inv_r, + float r2, + float* F_invr, + float* E_lj) { float r, r_switch; float sw, dsw; @@ -425,72 +413,70 @@ void calculate_potential_switch_F_E(const cl_nbparam_params_t *nbparam, r_switch = r_switch >= 0.0f ? r_switch : 0.0f; /* Unlike in the F-only kernel, masking is faster here */ - sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5*r_switch)*r_switch)*r_switch*r_switch*r_switch; - dsw = (switch_F2 + (switch_F3 + switch_F4*r_switch)*r_switch)*r_switch*r_switch; + sw = 1.0f + (switch_V3 + (switch_V4 + switch_V5 * r_switch) * r_switch) * r_switch * r_switch * r_switch; + dsw = (switch_F2 + (switch_F3 + switch_F4 * r_switch) * r_switch) * r_switch * r_switch; - *F_invr = (*F_invr)*sw - inv_r*(*E_lj)*dsw; - *E_lj *= sw; + *F_invr = (*F_invr) * sw - inv_r * (*E_lj) * dsw; + *E_lj *= sw; } /*! Calculate LJ-PME grid force contribution with * geometric combination rule. */ -gmx_opencl_inline -void calculate_lj_ewald_comb_geom_F(__constant const float *nbfp_comb_climg2d, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float *F_invr) +gmx_opencl_inline void calculate_lj_ewald_comb_geom_F(__constant const float* nbfp_comb_climg2d, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float* F_invr) { float c6grid, inv_r6_nm, cr2, expmcr2, poly; - c6grid = nbfp_comb_climg2d[2*typei]*nbfp_comb_climg2d[2*typej]; + c6grid = nbfp_comb_climg2d[2 * typei] * nbfp_comb_climg2d[2 * typej]; /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = exp(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; } /*! Calculate LJ-PME grid force + energy contribution with * geometric combination rule. */ -gmx_opencl_inline -void calculate_lj_ewald_comb_geom_F_E(__constant const float *nbfp_comb_climg2d, - const cl_nbparam_params_t *nbparam, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float int_bit, - float *F_invr, - float *E_lj) +gmx_opencl_inline void calculate_lj_ewald_comb_geom_F_E(__constant const float* nbfp_comb_climg2d, + const cl_nbparam_params_t* nbparam, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float int_bit, + float* F_invr, + float* E_lj) { float c6grid, inv_r6_nm, cr2, expmcr2, poly, sh_mask; - c6grid = nbfp_comb_climg2d[2*typei]*nbfp_comb_climg2d[2*typej]; + c6grid = nbfp_comb_climg2d[2 * typei] * nbfp_comb_climg2d[2 * typej]; /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = exp(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; /* Shift should be applied only to real LJ pairs */ - sh_mask = nbparam->sh_lj_ewald*int_bit; - *E_lj += ONE_SIXTH_F*c6grid*(inv_r6_nm*(1.0f - expmcr2*poly) + sh_mask); + sh_mask = nbparam->sh_lj_ewald * int_bit; + *E_lj += ONE_SIXTH_F * c6grid * (inv_r6_nm * (1.0f - expmcr2 * poly) + sh_mask); } /*! Calculate LJ-PME grid force + energy contribution (if E_lj != NULL) with @@ -498,70 +484,66 @@ void calculate_lj_ewald_comb_geom_F_E(__constant const float *nbfp_comb_climg * We use a single F+E kernel with conditional because the performance impact * of this is pretty small and LB on the CPU is anyway very slow. */ -gmx_opencl_inline -void calculate_lj_ewald_comb_LB_F_E(__constant const float *nbfp_comb_climg2d, - const cl_nbparam_params_t *nbparam, - int typei, - int typej, - float r2, - float inv_r2, - float lje_coeff2, - float lje_coeff6_6, - float int_bit, - bool with_E_lj, - float *F_invr, - float *E_lj) +gmx_opencl_inline void calculate_lj_ewald_comb_LB_F_E(__constant const float* nbfp_comb_climg2d, + const cl_nbparam_params_t* nbparam, + int typei, + int typej, + float r2, + float inv_r2, + float lje_coeff2, + float lje_coeff6_6, + float int_bit, + bool with_E_lj, + float* F_invr, + float* E_lj) { float c6grid, inv_r6_nm, cr2, expmcr2, poly; float sigma, sigma2, epsilon; /* sigma and epsilon are scaled to give 6*C6 */ - sigma = nbfp_comb_climg2d[2*typei] + nbfp_comb_climg2d[2*typej]; + sigma = nbfp_comb_climg2d[2 * typei] + nbfp_comb_climg2d[2 * typej]; - epsilon = nbfp_comb_climg2d[2*typei+1]*nbfp_comb_climg2d[2*typej+1]; + epsilon = nbfp_comb_climg2d[2 * typei + 1] * nbfp_comb_climg2d[2 * typej + 1]; - sigma2 = sigma*sigma; - c6grid = epsilon*sigma2*sigma2*sigma2; + sigma2 = sigma * sigma; + c6grid = epsilon * sigma2 * sigma2 * sigma2; /* Recalculate inv_r6 without exclusion mask */ - inv_r6_nm = inv_r2*inv_r2*inv_r2; - cr2 = lje_coeff2*r2; + inv_r6_nm = inv_r2 * inv_r2 * inv_r2; + cr2 = lje_coeff2 * r2; expmcr2 = exp(-cr2); - poly = 1.0f + cr2 + 0.5f*cr2*cr2; + poly = 1.0f + cr2 + 0.5f * cr2 * cr2; /* Subtract the grid force from the total LJ force */ - *F_invr += c6grid*(inv_r6_nm - expmcr2*(inv_r6_nm*poly + lje_coeff6_6))*inv_r2; + *F_invr += c6grid * (inv_r6_nm - expmcr2 * (inv_r6_nm * poly + lje_coeff6_6)) * inv_r2; if (with_E_lj) { float sh_mask; /* Shift should be applied only to real LJ pairs */ - sh_mask = nbparam->sh_lj_ewald*int_bit; - *E_lj += ONE_SIXTH_F*c6grid*(inv_r6_nm*(1.0f - expmcr2*poly) + sh_mask); + sh_mask = nbparam->sh_lj_ewald * int_bit; + *E_lj += ONE_SIXTH_F * c6grid * (inv_r6_nm * (1.0f - expmcr2 * poly) + sh_mask); } } /*! Interpolate Ewald coulomb force using the table through the tex_nbfp texture. * Original idea: from the OpenMM project */ -gmx_opencl_inline float -interpolate_coulomb_force_r(__constant const float *coulomb_tab_climg2d, - float r, - float scale) -{ - float normalized = scale * r; - int index = (int) normalized; - float fract2 = normalized - index; - float fract1 = 1.0f - fract2; - - return fract1*coulomb_tab_climg2d[index] + - fract2*coulomb_tab_climg2d[index + 1]; +gmx_opencl_inline float interpolate_coulomb_force_r(__constant const float* coulomb_tab_climg2d, + float r, + float scale) +{ + float normalized = scale * r; + int index = (int)normalized; + float fract2 = normalized - index; + float fract1 = 1.0f - fract2; + + return fract1 * coulomb_tab_climg2d[index] + fract2 * coulomb_tab_climg2d[index + 1]; } /*! Calculate analytical Ewald correction term. */ -gmx_opencl_inline -float pmecorrF(float z2) +gmx_opencl_inline float pmecorrF(float z2) { const float FN6 = -1.7357322914161492954e-8f; const float FN5 = 1.4703624142580877519e-6f; @@ -577,44 +559,43 @@ float pmecorrF(float z2) const float FD1 = 0.50736591960530292870f; const float FD0 = 1.0f; - float z4; - float polyFN0, polyFN1, polyFD0, polyFD1; + float z4; + float polyFN0, polyFN1, polyFD0, polyFD1; - z4 = z2*z2; + z4 = z2 * z2; - polyFD0 = FD4*z4 + FD2; - polyFD1 = FD3*z4 + FD1; - polyFD0 = polyFD0*z4 + FD0; - polyFD0 = polyFD1*z2 + polyFD0; + polyFD0 = FD4 * z4 + FD2; + polyFD1 = FD3 * z4 + FD1; + polyFD0 = polyFD0 * z4 + FD0; + polyFD0 = polyFD1 * z2 + polyFD0; - polyFD0 = 1.0f/polyFD0; + polyFD0 = 1.0f / polyFD0; - polyFN0 = FN6*z4 + FN4; - polyFN1 = FN5*z4 + FN3; - polyFN0 = polyFN0*z4 + FN2; - polyFN1 = polyFN1*z4 + FN1; - polyFN0 = polyFN0*z4 + FN0; - polyFN0 = polyFN1*z2 + polyFN0; + polyFN0 = FN6 * z4 + FN4; + polyFN1 = FN5 * z4 + FN3; + polyFN0 = polyFN0 * z4 + FN2; + polyFN1 = polyFN1 * z4 + FN1; + polyFN0 = polyFN0 * z4 + FN0; + polyFN0 = polyFN1 * z2 + polyFN0; - return polyFN0*polyFD0; + return polyFN0 * polyFD0; } -#if REDUCE_SHUFFLE -gmx_opencl_inline -void reduce_force_j_shfl(float3 fin, __global float *fout, - int gmx_unused tidxi, int gmx_unused tidxj, int aidx) +# if REDUCE_SHUFFLE +gmx_opencl_inline void +reduce_force_j_shfl(float3 fin, __global float* fout, int gmx_unused tidxi, int gmx_unused tidxj, int aidx) { /* Only does reduction over 4 elements in cluster. Needs to be changed * for CL_SIZE>4. See CUDA code for required code */ fin.x += intel_sub_group_shuffle_down(fin.x, fin.x, 1); - fin.y += intel_sub_group_shuffle_up (fin.y, fin.y, 1); + fin.y += intel_sub_group_shuffle_up(fin.y, fin.y, 1); fin.z += intel_sub_group_shuffle_down(fin.z, fin.z, 1); if ((tidxi & 1) == 1) { fin.x = fin.y; } fin.x += intel_sub_group_shuffle_down(fin.x, fin.x, 2); - fin.z += intel_sub_group_shuffle_up (fin.z, fin.z, 2); + fin.z += intel_sub_group_shuffle_up(fin.z, fin.z, 2); if (tidxi == 2) { fin.x = fin.z; @@ -624,15 +605,14 @@ void reduce_force_j_shfl(float3 fin, __global float *fout, atomicAdd_g_f(&fout[3 * aidx + tidxi], fin.x); } } -#endif +# endif -gmx_opencl_inline -void reduce_force_j_generic(__local float *f_buf, float3 fcj_buf, __global float *fout, - int tidxi, int tidxj, int aidx) +gmx_opencl_inline void +reduce_force_j_generic(__local float* f_buf, float3 fcj_buf, __global float* fout, int tidxi, int tidxj, int aidx) { - int tidx = tidxi + tidxj*CL_SIZE; - f_buf[ tidx] = fcj_buf.x; - f_buf[ FBUF_STRIDE + tidx] = fcj_buf.y; + int tidx = tidxi + tidxj * CL_SIZE; + f_buf[tidx] = fcj_buf.x; + f_buf[FBUF_STRIDE + tidx] = fcj_buf.y; f_buf[2 * FBUF_STRIDE + tidx] = fcj_buf.z; /* Split the reduction between the first 3 column threads @@ -654,22 +634,29 @@ void reduce_force_j_generic(__local float *f_buf, float3 fcj_buf, __global float /*! Final j-force reduction */ -gmx_opencl_inline -void reduce_force_j(__local float gmx_unused *f_buf, float3 fcj_buf, __global float *fout, - int tidxi, int tidxj, int aidx) +gmx_opencl_inline void reduce_force_j(__local float gmx_unused* f_buf, + float3 fcj_buf, + __global float* fout, + int tidxi, + int tidxj, + int aidx) { -#if REDUCE_SHUFFLE +# if REDUCE_SHUFFLE reduce_force_j_shfl(fcj_buf, fout, tidxi, tidxj, aidx); -#else +# else reduce_force_j_generic(f_buf, fcj_buf, fout, tidxi, tidxj, aidx); -#endif +# endif } -#if REDUCE_SHUFFLE -gmx_opencl_inline -void reduce_force_i_and_shift_shfl(float3* fci_buf, __global float *fout, - bool bCalcFshift, int tidxi, int tidxj, - int sci, int shift, __global float *fshift) +# if REDUCE_SHUFFLE +gmx_opencl_inline void reduce_force_i_and_shift_shfl(float3* fci_buf, + __global float* fout, + bool bCalcFshift, + int tidxi, + int tidxj, + int sci, + int shift, + __global float* fshift) { /* Only does reduction over 4 elements in cluster (2 per warp). Needs to be changed * for CL_SIZE>4.*/ @@ -679,7 +666,7 @@ void reduce_force_i_and_shift_shfl(float3* fci_buf, __global float *fout, int aidx = (sci * NCL_PER_SUPERCL + ci_offset) * CL_SIZE + tidxi; float3 fin = fci_buf[ci_offset]; fin.x += intel_sub_group_shuffle_down(fin.x, fin.x, CL_SIZE); - fin.y += intel_sub_group_shuffle_up (fin.y, fin.y, CL_SIZE); + fin.y += intel_sub_group_shuffle_up(fin.y, fin.y, CL_SIZE); fin.z += intel_sub_group_shuffle_down(fin.z, fin.z, CL_SIZE); if (tidxj & 1) @@ -687,7 +674,7 @@ void reduce_force_i_and_shift_shfl(float3* fci_buf, __global float *fout, fin.x = fin.y; } /* Threads 0,1 and 2,3 increment x,y for their warp */ - atomicAdd_g_f(&fout[3*aidx + (tidxj & 1)], fin.x); + atomicAdd_g_f(&fout[3 * aidx + (tidxj & 1)], fin.x); if (bCalcFshift) { fshift_buf[0] += fin.x; @@ -695,7 +682,7 @@ void reduce_force_i_and_shift_shfl(float3* fci_buf, __global float *fout, /* Threads 0 and 2 increment z for their warp */ if ((tidxj & 1) == 0) { - atomicAdd_g_f(&fout[3*aidx+2], fin.z); + atomicAdd_g_f(&fout[3 * aidx + 2], fin.z); if (bCalcFshift) { fshift_buf[1] += fin.z; @@ -705,52 +692,57 @@ void reduce_force_i_and_shift_shfl(float3* fci_buf, __global float *fout, /* add up local shift forces into global mem */ if (bCalcFshift) { - //Threads 0,1 and 2,3 update x,y - atomicAdd_g_f(&(fshift[3 * shift + (tidxj&1)]), fshift_buf[0]); - //Threads 0 and 2 update z + // Threads 0,1 and 2,3 update x,y + atomicAdd_g_f(&(fshift[3 * shift + (tidxj & 1)]), fshift_buf[0]); + // Threads 0 and 2 update z if ((tidxj & 1) == 0) { atomicAdd_g_f(&(fshift[3 * shift + 2]), fshift_buf[1]); } } } -#endif +# endif /*! Final i-force reduction; this implementation works only with power of two * array sizes. */ -gmx_opencl_inline -void reduce_force_i_and_shift_pow2(volatile __local float *f_buf, float3* fci_buf, - __global float *fout, - bool bCalcFshift, - int tidxi, int tidxj, - int sci, int shift, __global float *fshift) +gmx_opencl_inline void reduce_force_i_and_shift_pow2(volatile __local float* f_buf, + float3* fci_buf, + __global float* fout, + bool bCalcFshift, + int tidxi, + int tidxj, + int sci, + int shift, + __global float* fshift) { float fshift_buf = 0; for (int ci_offset = 0; ci_offset < NCL_PER_SUPERCL; ci_offset++) { int aidx = (sci * NCL_PER_SUPERCL + ci_offset) * CL_SIZE + tidxi; - int tidx = tidxi + tidxj*CL_SIZE; + int tidx = tidxi + tidxj * CL_SIZE; /* store i forces in shmem */ - f_buf[ tidx] = fci_buf[ci_offset].x; - f_buf[ FBUF_STRIDE + tidx] = fci_buf[ci_offset].y; + f_buf[tidx] = fci_buf[ci_offset].x; + f_buf[FBUF_STRIDE + tidx] = fci_buf[ci_offset].y; f_buf[2 * FBUF_STRIDE + tidx] = fci_buf[ci_offset].z; barrier(CLK_LOCAL_MEM_FENCE); - int i, j; + int i, j; /* Reduce the initial CL_SIZE values for each i atom to half * every step by using CL_SIZE * i threads. * Can't just use i as loop variable because than nvcc refuses to unroll. */ - i = CL_SIZE/2; + i = CL_SIZE / 2; for (j = CL_SIZE_LOG2 - 1; j > 0; j--) { if (tidxj < i) { - f_buf[ tidxj * CL_SIZE + tidxi] += f_buf[ (tidxj + i) * CL_SIZE + tidxi]; - f_buf[ FBUF_STRIDE + tidxj * CL_SIZE + tidxi] += f_buf[ FBUF_STRIDE + (tidxj + i) * CL_SIZE + tidxi]; - f_buf[2 * FBUF_STRIDE + tidxj * CL_SIZE + tidxi] += f_buf[2 * FBUF_STRIDE + (tidxj + i) * CL_SIZE + tidxi]; + f_buf[tidxj * CL_SIZE + tidxi] += f_buf[(tidxj + i) * CL_SIZE + tidxi]; + f_buf[FBUF_STRIDE + tidxj * CL_SIZE + tidxi] += + f_buf[FBUF_STRIDE + (tidxj + i) * CL_SIZE + tidxi]; + f_buf[2 * FBUF_STRIDE + tidxj * CL_SIZE + tidxi] += + f_buf[2 * FBUF_STRIDE + (tidxj + i) * CL_SIZE + tidxi]; } i >>= 1; } @@ -794,28 +786,30 @@ void reduce_force_i_and_shift_pow2(volatile __local float *f_buf, float3* fci_bu /*! Final i-force reduction */ -gmx_opencl_inline -void reduce_force_i_and_shift(__local float gmx_unused *f_buf, float3* fci_buf, __global float *f, - bool bCalcFshift, int tidxi, int tidxj, int sci, - int shift, __global float *fshift) -{ -#if REDUCE_SHUFFLE - reduce_force_i_and_shift_shfl(fci_buf, f, bCalcFshift, tidxi, tidxj, - sci, shift, fshift); -#else - reduce_force_i_and_shift_pow2(f_buf, fci_buf, f, bCalcFshift, tidxi, tidxj, - sci, shift, fshift); -#endif +gmx_opencl_inline void reduce_force_i_and_shift(__local float gmx_unused* f_buf, + float3* fci_buf, + __global float* f, + bool bCalcFshift, + int tidxi, + int tidxj, + int sci, + int shift, + __global float* fshift) +{ +# if REDUCE_SHUFFLE + reduce_force_i_and_shift_shfl(fci_buf, f, bCalcFshift, tidxi, tidxj, sci, shift, fshift); +# else + reduce_force_i_and_shift_pow2(f_buf, fci_buf, f, bCalcFshift, tidxi, tidxj, sci, shift, fshift); +# endif } - -#if REDUCE_SHUFFLE -gmx_opencl_inline -void reduce_energy_shfl(float E_lj, float E_el, - volatile __global float *e_lj, - volatile __global float *e_el, - unsigned int tidx) +# if REDUCE_SHUFFLE +gmx_opencl_inline void reduce_energy_shfl(float E_lj, + float E_el, + volatile __global float* e_lj, + volatile __global float* e_el, + unsigned int tidx) { E_lj = sub_group_reduce_add(E_lj); E_el = sub_group_reduce_add(E_el); @@ -830,27 +824,26 @@ void reduce_energy_shfl(float E_lj, float E_el, atomicAdd_g_f(e_el, E_el); } } -#endif +# endif /*! Energy reduction; this implementation works only with power of two * array sizes. */ -gmx_opencl_inline -void reduce_energy_pow2(volatile __local float *buf, - volatile __global float *e_lj, - volatile __global float *e_el, - unsigned int tidx) +gmx_opencl_inline void reduce_energy_pow2(volatile __local float* buf, + volatile __global float* e_lj, + volatile __global float* e_el, + unsigned int tidx) { - int j; + int j; - unsigned int i = WARP_SIZE/2; + unsigned int i = WARP_SIZE / 2; /* Can't just use i as loop variable because than nvcc refuses to unroll. */ for (j = WARP_SIZE_LOG2 - 1; j > 0; j--) { if (tidx < i) { - buf[ tidx] += buf[ tidx + i]; + buf[tidx] += buf[tidx + i]; buf[FBUF_STRIDE + tidx] += buf[FBUF_STRIDE + tidx + i]; } i >>= 1; @@ -859,7 +852,7 @@ void reduce_energy_pow2(volatile __local float *buf, /* last reduction step, writing to global mem */ if (tidx == 0) { - float e1 = buf[ tidx] + buf[ tidx + i]; + float e1 = buf[tidx] + buf[tidx + i]; float e2 = buf[FBUF_STRIDE + tidx] + buf[FBUF_STRIDE + tidx + i]; atomicAdd_g_f(e_lj, e1); @@ -867,25 +860,24 @@ void reduce_energy_pow2(volatile __local float *buf, } } -gmx_opencl_inline -void reduce_energy(volatile __local float gmx_unused *buf, - float E_lj, float E_el, - volatile __global float *e_lj, - volatile __global float *e_el, - unsigned int tidx) +gmx_opencl_inline void reduce_energy(volatile __local float gmx_unused* buf, + float E_lj, + float E_el, + volatile __global float* e_lj, + volatile __global float* e_el, + unsigned int tidx) { -#if REDUCE_SHUFFLE +# if REDUCE_SHUFFLE reduce_energy_shfl(E_lj, E_el, e_lj, e_el, tidx); -#else +# else /* flush the energies to shmem and reduce them */ - buf[ tidx] = E_lj; + buf[tidx] = E_lj; buf[FBUF_STRIDE + tidx] = E_el; reduce_energy_pow2(buf + (tidx & WARP_SIZE), e_lj, e_el, tidx & ~WARP_SIZE); -#endif +# endif } -gmx_opencl_inline -bool gmx_sub_group_any_localmem(volatile __local uint *warp_any, int widx, bool pred) +gmx_opencl_inline bool gmx_sub_group_any_localmem(volatile __local uint* warp_any, int widx, bool pred) { if (pred) { @@ -900,14 +892,15 @@ bool gmx_sub_group_any_localmem(volatile __local uint *warp_any, int widx, bool } //! Returns a true if predicate is true for any work item in warp -gmx_opencl_inline -bool gmx_sub_group_any(volatile __local uint gmx_unused *warp_any, int gmx_unused widx, bool pred) +gmx_opencl_inline bool gmx_sub_group_any(volatile __local uint gmx_unused* warp_any, + int gmx_unused widx, + bool pred) { -#if USE_SUBGROUP_ANY +# if USE_SUBGROUP_ANY return sub_group_any(pred); -#else +# else return gmx_sub_group_any_localmem(warp_any, widx, pred); -#endif +# endif } #endif /* NBNXN_OPENCL_KERNEL_UTILS_CLH */ diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.cl b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.cl index 528754b17b..b60d18a848 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.cl +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.cl @@ -35,8 +35,7 @@ /* Auxiliary kernels */ /* Very few data */ -__kernel void -zero_e_fshift(__global float *fshift, __global float *e_lj, __global float *e_el, const unsigned int Nbuf) +__kernel void zero_e_fshift(__global float* fshift, __global float* e_lj, __global float* e_el, const unsigned int Nbuf) { unsigned int tidx = get_global_id(0); if (tidx < Nbuf) @@ -45,8 +44,8 @@ zero_e_fshift(__global float *fshift, __global float *e_lj, __global float *e_el } if (tidx == 0) { - *e_lj = 0.0f; - *e_el = 0.0f; + *e_lj = 0.0f; + *e_el = 0.0f; } } @@ -57,11 +56,11 @@ zero_e_fshift(__global float *fshift, __global float *e_lj, __global float *e_el #include "nbnxm_ocl_kernel_pruneonly.clh" #if defined GMX_OCL_FASTGEN - #define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels_fastgen.clh" +# define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels_fastgen.clh" #elif defined GMX_OCL_FASTGEN_ADD_TWINCUT - #define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels_fastgen_add_twincut.clh" +# define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels_fastgen_add_twincut.clh" #else - #define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels.clh" +# define FLAVOR_LEVEL_GENERATOR "nbnxm_ocl_kernels.clh" #endif /* Top-level kernel generation: will generate through multiple inclusion the diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.clh index 5730d24374..6b35a5d0e0 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels.clh @@ -53,42 +53,42 @@ #define EL_CUTOFF /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecCut_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecCut_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -101,42 +101,42 @@ #define EL_RF /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecRF_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecRF_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -149,42 +149,42 @@ #define EL_EWALD_ANA /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEw_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEw_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -198,42 +198,42 @@ #define VDW_CUTOFF_CHECK /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwTwinCut_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwTwinCut_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -246,42 +246,42 @@ #define EL_EWALD_TAB /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTab_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTab_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME @@ -294,42 +294,42 @@ #define VDW_CUTOFF_CHECK /* cut-off + V shift LJ */ -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwinCut_VdwLJ ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwinCut_VdwLJ##y #include "nbnxm_ocl_kernel.clh" #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w geometric combination rules */ #define LJ_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwin_VdwLJCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwin_VdwLJCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* cut-off + V shift LJ w LB combination rules */ #define LJ_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwin_VdwLJCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwin_VdwLJCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_COMB_LB #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w geometric combination rules */ #define LJ_EWALD_COMB_GEOM -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwinCut_VdwLJEwCombGeom ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwinCut_VdwLJEwCombGeom##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_GEOM #undef NB_KERNEL_FUNC_NAME /* LJ-Ewald w LB combination rules */ #define LJ_EWALD_COMB_LB -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwinCut_VdwLJEwCombLB ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwinCut_VdwLJEwCombLB##y #include "nbnxm_ocl_kernel.clh" #undef LJ_EWALD_COMB_LB #undef NB_KERNEL_FUNC_NAME /* F switch LJ */ #define LJ_FORCE_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwinCut_VdwLJFsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwinCut_VdwLJFsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_FORCE_SWITCH #undef NB_KERNEL_FUNC_NAME /* V switch LJ */ #define LJ_POT_SWITCH -#define NB_KERNEL_FUNC_NAME(x, y) x ## _ElecEwQSTabTwinCut_VdwLJPsw ## y +#define NB_KERNEL_FUNC_NAME(x, y) x##_ElecEwQSTabTwinCut_VdwLJPsw##y #include "nbnxm_ocl_kernel.clh" #undef LJ_POT_SWITCH #undef NB_KERNEL_FUNC_NAME diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen.clh index a5b30ec045..9d9b12e788 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen.clh @@ -48,9 +48,9 @@ #include "nbnxm_ocl_kernel_utils.clh" -#define NB_INDIRECT_1(x, eel, vdw, y) x ## eel ## vdw ## y +#define NB_INDIRECT_1(x, eel, vdw, y) x##eel##vdw##y #define NB_INDIRECT_2(x, eel, vdw, y) NB_INDIRECT_1(x, eel, vdw, y) -#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2(x, EELNAME, VDWNAME, y) +#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2(x, EELNAME, VDWNAME, y) #include "nbnxm_ocl_kernel.clh" diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen_add_twincut.clh b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen_add_twincut.clh index ac072959b6..4687630913 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen_add_twincut.clh +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_kernels_fastgen_add_twincut.clh @@ -50,9 +50,9 @@ /* Define the single-cutoff version of the kernel */ -#define NB_INDIRECT_1(x, eel, vdw, y) x ## eel ## vdw ## y +#define NB_INDIRECT_1(x, eel, vdw, y) x##eel##vdw##y #define NB_INDIRECT_2(x, eel, vdw, y) NB_INDIRECT_1(x, eel, vdw, y) -#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2(x, EELNAME, VDWNAME, y) +#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2(x, EELNAME, VDWNAME, y) #include "nbnxm_ocl_kernel.clh" @@ -60,9 +60,9 @@ /* Define the twin-cutoff version of the kernel */ -#define NB_INDIRECT_1_TWINCUT(x, eel, vdw, y) x ## eel ## TwinCut ## vdw ## y +#define NB_INDIRECT_1_TWINCUT(x, eel, vdw, y) x##eel##TwinCut##vdw##y #define NB_INDIRECT_2_TWINCUT(x, eel, vdw, y) NB_INDIRECT_1_TWINCUT(x, eel, vdw, y) -#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2_TWINCUT(x, EELNAME, VDWNAME, y) +#define NB_KERNEL_FUNC_NAME(x, y) NB_INDIRECT_2_TWINCUT(x, EELNAME, VDWNAME, y) #define VDW_CUTOFF_CHECK diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_types.h b/src/gromacs/nbnxm/opencl/nbnxm_ocl_types.h index 55d93e74f5..f12193e11f 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_types.h +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_types.h @@ -71,7 +71,7 @@ * Initialized using macros that can be overridden at compile-time (using #GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY). */ /*! @{ */ -const int c_oclPruneKernelJ4ConcurrencyDEFAULT = GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY_DEFAULT; +const int c_oclPruneKernelJ4ConcurrencyDEFAULT = GMX_NBNXN_PRUNE_KERNEL_J4_CONCURRENCY_DEFAULT; /*! @} */ /*! \brief Returns the j4 processing concurrency parameter for the vendor \p vendorId @@ -100,8 +100,15 @@ static inline int getOclPruneKernelJ4Concurrency(int vendorId) * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table * should match the order of enumerated types below. */ -enum eelOcl { - eelOclCUT, eelOclRF, eelOclEWALD_TAB, eelOclEWALD_TAB_TWIN, eelOclEWALD_ANA, eelOclEWALD_ANA_TWIN, eelOclNR +enum eelOcl +{ + eelOclCUT, + eelOclRF, + eelOclEWALD_TAB, + eelOclEWALD_TAB_TWIN, + eelOclEWALD_ANA, + eelOclEWALD_ANA_TWIN, + eelOclNR }; /*! \brief VdW OpenCL kernel flavors. @@ -113,8 +120,16 @@ enum eelOcl { * nbnxn_cuda.cu by the nb_*_kfunc_ptr function pointer table * should match the order of enumerated types below. */ -enum evdwOcl { - evdwOclCUT, evdwOclCUTCOMBGEOM, evdwOclCUTCOMBLB, evdwOclFSWITCH, evdwOclPSWITCH, evdwOclEWALDGEOM, evdwOclEWALDLB, evdwOclNR +enum evdwOcl +{ + evdwOclCUT, + evdwOclCUTCOMBGEOM, + evdwOclCUTCOMBLB, + evdwOclFSWITCH, + evdwOclPSWITCH, + evdwOclEWALDGEOM, + evdwOclEWALDLB, + evdwOclNR }; /*! \brief Pruning kernel flavors. @@ -122,8 +137,11 @@ enum evdwOcl { * The values correspond to the first call of the pruning post-list generation * and the rolling pruning, respectively. */ -enum ePruneKind { - epruneFirst, epruneRolling, ePruneNR +enum ePruneKind +{ + epruneFirst, + epruneRolling, + ePruneNR }; /*! \internal @@ -134,9 +152,9 @@ enum ePruneKind { */ typedef struct cl_nb_staging { - float *e_lj; /**< LJ energy */ - float *e_el; /**< electrostatic energy */ - float (*fshift)[3]; /**< float3 buffer with shift forces */ + float* e_lj; /**< LJ energy */ + float* e_el; /**< electrostatic energy */ + float (*fshift)[3]; /**< float3 buffer with shift forces */ } cl_nb_staging_t; /*! \internal @@ -144,29 +162,29 @@ typedef struct cl_nb_staging */ typedef struct cl_atomdata { - int natoms; /**< number of atoms */ - int natoms_local; /**< number of local atoms */ - int nalloc; /**< allocation size for the atom data (xq, f) */ + int natoms; /**< number of atoms */ + int natoms_local; /**< number of local atoms */ + int nalloc; /**< allocation size for the atom data (xq, f) */ - cl_mem xq; /**< float4 buffer with atom coordinates + charges, size natoms */ + cl_mem xq; /**< float4 buffer with atom coordinates + charges, size natoms */ - cl_mem f; /**< float3 buffer with force output array, size natoms */ - size_t f_elem_size; /**< Size in bytes for one element of f buffer */ + cl_mem f; /**< float3 buffer with force output array, size natoms */ + size_t f_elem_size; /**< Size in bytes for one element of f buffer */ - cl_mem e_lj; /**< LJ energy output, size 1 */ - cl_mem e_el; /**< Electrostatics energy input, size 1 */ + cl_mem e_lj; /**< LJ energy output, size 1 */ + cl_mem e_el; /**< Electrostatics energy input, size 1 */ - cl_mem fshift; /**< float3 buffer with shift forces */ - size_t fshift_elem_size; /**< Size in bytes for one element of fshift buffer */ + cl_mem fshift; /**< float3 buffer with shift forces */ + size_t fshift_elem_size; /**< Size in bytes for one element of fshift buffer */ - int ntypes; /**< number of atom types */ - cl_mem atom_types; /**< int buffer with atom type indices, size natoms */ - cl_mem lj_comb; /**< float2 buffer with sqrt(c6),sqrt(c12), size natoms */ + int ntypes; /**< number of atom types */ + cl_mem atom_types; /**< int buffer with atom type indices, size natoms */ + cl_mem lj_comb; /**< float2 buffer with sqrt(c6),sqrt(c12), size natoms */ - cl_mem shift_vec; /**< float3 buffer with shifts values */ - size_t shift_vec_elem_size; /**< Size in bytes for one element of shift_vec buffer */ + cl_mem shift_vec; /**< float3 buffer with shifts values */ + size_t shift_vec_elem_size; /**< Size in bytes for one element of shift_vec buffer */ - cl_bool bShiftVecUploaded; /**< true if the shift vector has been uploaded */ + cl_bool bShiftVecUploaded; /**< true if the shift vector has been uploaded */ } cl_atomdata_t; /*! \internal @@ -175,36 +193,36 @@ typedef struct cl_atomdata typedef struct cl_nbparam { - int eeltype; /**< type of electrostatics, takes values from #eelOcl */ - int vdwtype; /**< type of VdW impl., takes values from #evdwOcl */ + int eeltype; /**< type of electrostatics, takes values from #eelOcl */ + int vdwtype; /**< type of VdW impl., takes values from #evdwOcl */ - float epsfac; /**< charge multiplication factor */ - float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ - float two_k_rf; /**< Reaction-field electrostatics constant */ - float ewald_beta; /**< Ewald/PME parameter */ - float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ - float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ - float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ + float epsfac; /**< charge multiplication factor */ + float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ + float two_k_rf; /**< Reaction-field electrostatics constant */ + float ewald_beta; /**< Ewald/PME parameter */ + float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ + float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ + float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ - float rcoulomb_sq; /**< Coulomb cut-off squared */ + float rcoulomb_sq; /**< Coulomb cut-off squared */ - float rvdw_sq; /**< VdW cut-off squared */ - float rvdw_switch; /**< VdW switched cut-off */ - float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ - float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ - bool useDynamicPruning; /**< True if we use dynamic pair-list pruning */ + float rvdw_sq; /**< VdW cut-off squared */ + float rvdw_switch; /**< VdW switched cut-off */ + float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ + float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ + bool useDynamicPruning; /**< True if we use dynamic pair-list pruning */ - shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ - shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ - switch_consts_t vdw_switch; /**< VdW switch constants */ + shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ + shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ + switch_consts_t vdw_switch; /**< VdW switch constants */ /* LJ non-bonded parameters - accessed through texture memory */ - cl_mem nbfp_climg2d; /**< nonbonded parameter table with C6/C12 pairs per atom type-pair, 2*ntype^2 elements */ - cl_mem nbfp_comb_climg2d; /**< nonbonded parameter table per atom type, 2*ntype elements */ + cl_mem nbfp_climg2d; /**< nonbonded parameter table with C6/C12 pairs per atom type-pair, 2*ntype^2 elements */ + cl_mem nbfp_comb_climg2d; /**< nonbonded parameter table per atom type, 2*ntype elements */ /* Ewald Coulomb force table data - accessed through texture memory */ - float coulomb_tab_scale; /**< table scale/spacing */ - cl_mem coulomb_tab_climg2d; /**< pointer to the table in the device memory */ + float coulomb_tab_scale; /**< table scale/spacing */ + cl_mem coulomb_tab_climg2d; /**< pointer to the table in the device memory */ } cl_nbparam_t; /*! \internal @@ -215,30 +233,30 @@ typedef struct cl_nbparam typedef struct cl_nbparam_params { - int eeltype; /**< type of electrostatics, takes values from #eelCu */ - int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ + int eeltype; /**< type of electrostatics, takes values from #eelCu */ + int vdwtype; /**< type of VdW impl., takes values from #evdwCu */ - float epsfac; /**< charge multiplication factor */ - float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ - float two_k_rf; /**< Reaction-field electrostatics constant */ - float ewald_beta; /**< Ewald/PME parameter */ - float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ - float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ - float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ + float epsfac; /**< charge multiplication factor */ + float c_rf; /**< Reaction-field/plain cutoff electrostatics const. */ + float two_k_rf; /**< Reaction-field electrostatics constant */ + float ewald_beta; /**< Ewald/PME parameter */ + float sh_ewald; /**< Ewald/PME correction term substracted from the direct-space potential */ + float sh_lj_ewald; /**< LJ-Ewald/PME correction term added to the correction potential */ + float ewaldcoeff_lj; /**< LJ-Ewald/PME coefficient */ - float rcoulomb_sq; /**< Coulomb cut-off squared */ + float rcoulomb_sq; /**< Coulomb cut-off squared */ - float rvdw_sq; /**< VdW cut-off squared */ - float rvdw_switch; /**< VdW switched cut-off */ - float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ - float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ + float rvdw_sq; /**< VdW cut-off squared */ + float rvdw_switch; /**< VdW switched cut-off */ + float rlistOuter_sq; /**< Full, outer pair-list cut-off squared */ + float rlistInner_sq; /**< Inner, dynamic pruned pair-list cut-off squared */ shift_consts_t dispersion_shift; /**< VdW shift dispersion constants */ shift_consts_t repulsion_shift; /**< VdW shift repulsion constants */ switch_consts_t vdw_switch; /**< VdW switch constants */ /* Ewald Coulomb force table data - accessed through texture memory */ - float coulomb_tab_scale; /**< table scale/spacing */ + float coulomb_tab_scale; /**< table scale/spacing */ } cl_nbparam_params_t; @@ -257,46 +275,46 @@ typedef struct Nbnxm::gpu_timers_t cl_timers_t; */ struct gmx_nbnxn_ocl_t { - const gmx_device_info_t *dev_info; /**< OpenCL device information */ - struct gmx_device_runtime_data_t *dev_rundata; /**< OpenCL runtime data (context, kernels) */ + const gmx_device_info_t* dev_info; /**< OpenCL device information */ + struct gmx_device_runtime_data_t* dev_rundata; /**< OpenCL runtime data (context, kernels) */ /**< Pointers to non-bonded kernel functions * organized similar with nb_kfunc_xxx arrays in nbnxn_ocl.cpp */ ///@{ - cl_kernel kernel_noener_noprune_ptr[eelOclNR][evdwOclNR]; - cl_kernel kernel_ener_noprune_ptr[eelOclNR][evdwOclNR]; - cl_kernel kernel_noener_prune_ptr[eelOclNR][evdwOclNR]; - cl_kernel kernel_ener_prune_ptr[eelOclNR][evdwOclNR]; + cl_kernel kernel_noener_noprune_ptr[eelOclNR][evdwOclNR]; + cl_kernel kernel_ener_noprune_ptr[eelOclNR][evdwOclNR]; + cl_kernel kernel_noener_prune_ptr[eelOclNR][evdwOclNR]; + cl_kernel kernel_ener_prune_ptr[eelOclNR][evdwOclNR]; ///@} - cl_kernel kernel_pruneonly[ePruneNR]; /**< prune kernels, ePruneKind defined the kernel kinds */ + cl_kernel kernel_pruneonly[ePruneNR]; /**< prune kernels, ePruneKind defined the kernel kinds */ - bool bPrefetchLjParam; /**< true if prefetching fg i-atom LJ parameters should be used in the kernels */ + bool bPrefetchLjParam; /**< true if prefetching fg i-atom LJ parameters should be used in the kernels */ /**< auxiliary kernels implementing memset-like functions */ ///@{ - cl_kernel kernel_memset_f; - cl_kernel kernel_memset_f2; - cl_kernel kernel_memset_f3; - cl_kernel kernel_zero_e_fshift; + cl_kernel kernel_memset_f; + cl_kernel kernel_memset_f2; + cl_kernel kernel_memset_f3; + cl_kernel kernel_zero_e_fshift; ///@} - cl_bool bUseTwoStreams; /**< true if doing both local/non-local NB work on GPU */ - cl_bool bNonLocalStreamActive; /**< true indicates that the nonlocal_done event was enqueued */ + cl_bool bUseTwoStreams; /**< true if doing both local/non-local NB work on GPU */ + cl_bool bNonLocalStreamActive; /**< true indicates that the nonlocal_done event was enqueued */ - cl_atomdata_t *atdat; /**< atom data */ - cl_nbparam_t *nbparam; /**< parameters required for the non-bonded calc. */ - gmx::EnumerationArray plist; /**< pair-list data structures (local and non-local) */ - cl_nb_staging_t nbst; /**< staging area where fshift/energies get downloaded */ + cl_atomdata_t* atdat; /**< atom data */ + cl_nbparam_t* nbparam; /**< parameters required for the non-bonded calc. */ + gmx::EnumerationArray plist; /**< pair-list data structures (local and non-local) */ + cl_nb_staging_t nbst; /**< staging area where fshift/energies get downloaded */ - gmx::EnumerationArray stream; /**< local and non-local GPU queues */ + gmx::EnumerationArray stream; /**< local and non-local GPU queues */ /** events used for synchronization */ - cl_event nonlocal_done; /**< event triggered when the non-local non-bonded kernel - is done (and the local transfer can proceed) */ - cl_event misc_ops_and_local_H2D_done; /**< event triggered when the tasks issued in - the local stream that need to precede the - non-local force calculations are done - (e.g. f buffer 0-ing, local x/q H2D) */ + cl_event nonlocal_done; /**< event triggered when the non-local non-bonded kernel + is done (and the local transfer can proceed) */ + cl_event misc_ops_and_local_H2D_done; /**< event triggered when the tasks issued in + the local stream that need to precede the + non-local force calculations are done + (e.g. f buffer 0-ing, local x/q H2D) */ //! True if there has been local/nonlocal GPU work, either bonded or nonbonded, scheduled // to be executed in the current domain. As long as bonded work is not split up into @@ -304,9 +322,9 @@ struct gmx_nbnxn_ocl_t gmx::EnumerationArray haveWork; - cl_bool bDoTime; /**< True if event-based timing is enabled. */ - cl_timers_t *timers; /**< OpenCL event-based timers. */ - struct gmx_wallclock_gpu_nbnxn_t *timings; /**< Timing data. TODO: deprecate this and query timers for accumulated data instead */ + cl_bool bDoTime; /**< True if event-based timing is enabled. */ + cl_timers_t* timers; /**< OpenCL event-based timers. */ + struct gmx_wallclock_gpu_nbnxn_t* timings; /**< Timing data. TODO: deprecate this and query timers for accumulated data instead */ }; -#endif /* NBNXN_OPENCL_TYPES_H */ +#endif /* NBNXN_OPENCL_TYPES_H */ diff --git a/src/gromacs/nbnxm/pairlist.cpp b/src/gromacs/nbnxm/pairlist.cpp index 2971d14cfa..6174905d57 100644 --- a/src/gromacs/nbnxm/pairlist.cpp +++ b/src/gromacs/nbnxm/pairlist.cpp @@ -75,12 +75,12 @@ #include "pairlistwork.h" #include "pairsearch.h" -using namespace gmx; // TODO: Remove when this file is moved into gmx namespace +using namespace gmx; // TODO: Remove when this file is moved into gmx namespace using BoundingBox = Nbnxm::BoundingBox; // TODO: Remove when refactoring this file using BoundingBox1D = Nbnxm::BoundingBox1D; // TODO: Remove when refactoring this file -using Grid = Nbnxm::Grid; // TODO: Remove when refactoring this file +using Grid = Nbnxm::Grid; // TODO: Remove when refactoring this file // Convience alias for partial Nbnxn namespace usage using InteractionLocality = gmx::InteractionLocality; @@ -102,29 +102,35 @@ enum class NbnxnLayout #if GMX_SIMD /* Returns the j-cluster size */ -template +template static constexpr int jClusterSize() { - static_assert(layout == NbnxnLayout::NoSimd4x4 || layout == NbnxnLayout::Simd4xN || layout == NbnxnLayout::Simd2xNN, "Currently jClusterSize only supports CPU layouts"); + static_assert(layout == NbnxnLayout::NoSimd4x4 || layout == NbnxnLayout::Simd4xN + || layout == NbnxnLayout::Simd2xNN, + "Currently jClusterSize only supports CPU layouts"); - return layout == NbnxnLayout::Simd4xN ? GMX_SIMD_REAL_WIDTH : (layout == NbnxnLayout::Simd2xNN ? GMX_SIMD_REAL_WIDTH/2 : c_nbnxnCpuIClusterSize); + return layout == NbnxnLayout::Simd4xN + ? GMX_SIMD_REAL_WIDTH + : (layout == NbnxnLayout::Simd2xNN ? GMX_SIMD_REAL_WIDTH / 2 : c_nbnxnCpuIClusterSize); } /*! \brief Returns the j-cluster index given the i-cluster index. * * \tparam jClusterSize The number of atoms in a j-cluster - * \tparam jSubClusterIndex The j-sub-cluster index (0/1), used when size(j-cluster) < size(i-cluster) - * \param[in] ci The i-cluster index + * \tparam jSubClusterIndex The j-sub-cluster index (0/1), used when size(j-cluster) < + * size(i-cluster) \param[in] ci The i-cluster index */ -template +template static inline int cjFromCi(int ci) { - static_assert(jClusterSize == c_nbnxnCpuIClusterSize/2 || jClusterSize == c_nbnxnCpuIClusterSize || jClusterSize == c_nbnxnCpuIClusterSize*2, "Only j-cluster sizes 2, 4 and 8 are currently implemented"); + static_assert(jClusterSize == c_nbnxnCpuIClusterSize / 2 || jClusterSize == c_nbnxnCpuIClusterSize + || jClusterSize == c_nbnxnCpuIClusterSize * 2, + "Only j-cluster sizes 2, 4 and 8 are currently implemented"); static_assert(jSubClusterIndex == 0 || jSubClusterIndex == 1, "Only sub-cluster indices 0 and 1 are supported"); - if (jClusterSize == c_nbnxnCpuIClusterSize/2) + if (jClusterSize == c_nbnxnCpuIClusterSize / 2) { if (jSubClusterIndex == 0) { @@ -148,10 +154,10 @@ static inline int cjFromCi(int ci) /*! \brief Returns the j-cluster index given the i-cluster index. * * \tparam layout The pair-list layout - * \tparam jSubClusterIndex The j-sub-cluster index (0/1), used when size(j-cluster) < size(i-cluster) - * \param[in] ci The i-cluster index + * \tparam jSubClusterIndex The j-sub-cluster index (0/1), used when size(j-cluster) < + * size(i-cluster) \param[in] ci The i-cluster index */ -template +template static inline int cjFromCi(int ci) { constexpr int clusterSize = jClusterSize(); @@ -160,79 +166,81 @@ static inline int cjFromCi(int ci) } /* Returns the nbnxn coordinate data index given the i-cluster index */ -template +template static inline int xIndexFromCi(int ci) { constexpr int clusterSize = jClusterSize(); - static_assert(clusterSize == c_nbnxnCpuIClusterSize/2 || clusterSize == c_nbnxnCpuIClusterSize || clusterSize == c_nbnxnCpuIClusterSize*2, "Only j-cluster sizes 2, 4 and 8 are currently implemented"); + static_assert(clusterSize == c_nbnxnCpuIClusterSize / 2 || clusterSize == c_nbnxnCpuIClusterSize + || clusterSize == c_nbnxnCpuIClusterSize * 2, + "Only j-cluster sizes 2, 4 and 8 are currently implemented"); if (clusterSize <= c_nbnxnCpuIClusterSize) { /* Coordinates are stored packed in groups of 4 */ - return ci*STRIDE_P4; + return ci * STRIDE_P4; } else { /* Coordinates packed in 8, i-cluster size is half the packing width */ - return (ci >> 1)*STRIDE_P8 + (ci & 1)*(c_packX8 >> 1); + return (ci >> 1) * STRIDE_P8 + (ci & 1) * (c_packX8 >> 1); } } /* Returns the nbnxn coordinate data index given the j-cluster index */ -template +template static inline int xIndexFromCj(int cj) { constexpr int clusterSize = jClusterSize(); - static_assert(clusterSize == c_nbnxnCpuIClusterSize/2 || clusterSize == c_nbnxnCpuIClusterSize || clusterSize == c_nbnxnCpuIClusterSize*2, "Only j-cluster sizes 2, 4 and 8 are currently implemented"); + static_assert(clusterSize == c_nbnxnCpuIClusterSize / 2 || clusterSize == c_nbnxnCpuIClusterSize + || clusterSize == c_nbnxnCpuIClusterSize * 2, + "Only j-cluster sizes 2, 4 and 8 are currently implemented"); - if (clusterSize == c_nbnxnCpuIClusterSize/2) + if (clusterSize == c_nbnxnCpuIClusterSize / 2) { /* Coordinates are stored packed in groups of 4 */ - return (cj >> 1)*STRIDE_P4 + (cj & 1)*(c_packX4 >> 1); + return (cj >> 1) * STRIDE_P4 + (cj & 1) * (c_packX4 >> 1); } else if (clusterSize == c_nbnxnCpuIClusterSize) { /* Coordinates are stored packed in groups of 4 */ - return cj*STRIDE_P4; + return cj * STRIDE_P4; } else { /* Coordinates are stored packed in groups of 8 */ - return cj*STRIDE_P8; + return cj * STRIDE_P8; } } -#endif //GMX_SIMD +#endif // GMX_SIMD -void nbnxn_init_pairlist_fep(t_nblist *nl) +void nbnxn_init_pairlist_fep(t_nblist* nl) { - nl->type = GMX_NBLIST_INTERACTION_FREE_ENERGY; - nl->igeometry = GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE; + nl->type = GMX_NBLIST_INTERACTION_FREE_ENERGY; + nl->igeometry = GMX_NBLIST_GEOMETRY_PARTICLE_PARTICLE; /* The interaction functions are set in the free energy kernel fuction */ - nl->ivdw = -1; - nl->ivdwmod = -1; - nl->ielec = -1; - nl->ielecmod = -1; - - nl->maxnri = 0; - nl->maxnrj = 0; - nl->nri = 0; - nl->nrj = 0; - nl->iinr = nullptr; - nl->gid = nullptr; - nl->shift = nullptr; - nl->jindex = nullptr; - nl->jjnr = nullptr; - nl->excl_fep = nullptr; - + nl->ivdw = -1; + nl->ivdwmod = -1; + nl->ielec = -1; + nl->ielecmod = -1; + + nl->maxnri = 0; + nl->maxnrj = 0; + nl->nri = 0; + nl->nrj = 0; + nl->iinr = nullptr; + nl->gid = nullptr; + nl->shift = nullptr; + nl->jindex = nullptr; + nl->jjnr = nullptr; + nl->excl_fep = nullptr; } -static void init_buffer_flags(nbnxn_buffer_flags_t *flags, - int natoms) +static void init_buffer_flags(nbnxn_buffer_flags_t* flags, int natoms) { - flags->nflag = (natoms + NBNXN_BUFFERFLAG_SIZE - 1)/NBNXN_BUFFERFLAG_SIZE; + flags->nflag = (natoms + NBNXN_BUFFERFLAG_SIZE - 1) / NBNXN_BUFFERFLAG_SIZE; if (flags->nflag > flags->flag_nalloc) { flags->flag_nalloc = over_alloc_large(flags->nflag); @@ -252,12 +260,9 @@ static void init_buffer_flags(nbnxn_buffer_flags_t *flags, * assigned to (when atom groups instead of individual atoms are assigned * to cells), this distance returned can be larger than the input. */ -static real -listRangeForBoundingBoxToGridCell(real rlist, - const Grid::Dimensions &gridDims) +static real listRangeForBoundingBoxToGridCell(real rlist, const Grid::Dimensions& gridDims) { return rlist + gridDims.maxAtomGroupRadius; - } /* Returns the pair-list cutoff between a grid cells given an atom-to-atom pair-list cutoff * @@ -267,10 +272,9 @@ listRangeForBoundingBoxToGridCell(real rlist, * assigned to (when atom groups instead of individual atoms are assigned * to cells), this distance returned can be larger than the input. */ -static real -listRangeForGridCellToGridCell(real rlist, - const Grid::Dimensions &iGridDims, - const Grid::Dimensions &jGridDims) +static real listRangeForGridCellToGridCell(real rlist, + const Grid::Dimensions& iGridDims, + const Grid::Dimensions& jGridDims) { return rlist + iGridDims.maxAtomGroupRadius + jGridDims.maxAtomGroupRadius; } @@ -279,23 +283,25 @@ listRangeForGridCellToGridCell(real rlist, * the bounding box b0 - b1 sees. */ template -static void get_cell_range(real b0, real b1, - const Grid::Dimensions &jGridDims, - real d2, real rlist, int *cf, int *cl) +static void +get_cell_range(real b0, real b1, const Grid::Dimensions& jGridDims, real d2, real rlist, int* cf, int* cl) { real listRangeBBToCell2 = gmx::square(listRangeForBoundingBoxToGridCell(rlist, jGridDims)); - real distanceInCells = (b0 - jGridDims.lowerCorner[dim])*jGridDims.invCellSize[dim]; + real distanceInCells = (b0 - jGridDims.lowerCorner[dim]) * jGridDims.invCellSize[dim]; *cf = std::max(static_cast(distanceInCells), 0); - while (*cf > 0 && - d2 + gmx::square((b0 - jGridDims.lowerCorner[dim]) - (*cf - 1 + 1)*jGridDims.cellSize[dim]) < listRangeBBToCell2) + while (*cf > 0 + && d2 + gmx::square((b0 - jGridDims.lowerCorner[dim]) - (*cf - 1 + 1) * jGridDims.cellSize[dim]) + < listRangeBBToCell2) { (*cf)--; } - *cl = std::min(static_cast((b1 - jGridDims.lowerCorner[dim])*jGridDims.invCellSize[dim]), jGridDims.numCells[dim] - 1); - while (*cl < jGridDims.numCells[dim] - 1 && - d2 + gmx::square((*cl + 1)*jGridDims.cellSize[dim] - (b1 - jGridDims.lowerCorner[dim])) < listRangeBBToCell2) + *cl = std::min(static_cast((b1 - jGridDims.lowerCorner[dim]) * jGridDims.invCellSize[dim]), + jGridDims.numCells[dim] - 1); + while (*cl < jGridDims.numCells[dim] - 1 + && d2 + gmx::square((*cl + 1) * jGridDims.cellSize[dim] - (b1 - jGridDims.lowerCorner[dim])) + < listRangeBBToCell2) { (*cl)++; } @@ -341,26 +347,25 @@ static void get_cell_range(real b0, real b1, * \param[in] bb_i First bounding box * \param[in] bb_j Second bounding box */ -static float clusterBoundingBoxDistance2(const BoundingBox &bb_i, - const BoundingBox &bb_j) +static float clusterBoundingBoxDistance2(const BoundingBox& bb_i, const BoundingBox& bb_j) { - float dl = bb_i.lower.x - bb_j.upper.x; - float dh = bb_j.lower.x - bb_i.upper.x; - float dm = std::max(dl, dh); - float dm0 = std::max(dm, 0.0F); - float d2 = dm0*dm0; - - dl = bb_i.lower.y - bb_j.upper.y; - dh = bb_j.lower.y - bb_i.upper.y; - dm = std::max(dl, dh); - dm0 = std::max(dm, 0.0F); - d2 += dm0*dm0; - - dl = bb_i.lower.z - bb_j.upper.z; - dh = bb_j.lower.z - bb_i.upper.z; - dm = std::max(dl, dh); - dm0 = std::max(dm, 0.0F); - d2 += dm0*dm0; + float dl = bb_i.lower.x - bb_j.upper.x; + float dh = bb_j.lower.x - bb_i.upper.x; + float dm = std::max(dl, dh); + float dm0 = std::max(dm, 0.0F); + float d2 = dm0 * dm0; + + dl = bb_i.lower.y - bb_j.upper.y; + dh = bb_j.lower.y - bb_i.upper.y; + dm = std::max(dl, dh); + dm0 = std::max(dm, 0.0F); + d2 += dm0 * dm0; + + dl = bb_i.lower.z - bb_j.upper.z; + dh = bb_j.lower.z - bb_i.upper.z; + dm = std::max(dl, dh); + dm0 = std::max(dm, 0.0F); + d2 += dm0 * dm0; return d2; } @@ -372,8 +377,7 @@ static float clusterBoundingBoxDistance2(const BoundingBox &bb_i, * \param[in] bb_i First bounding box, should be aligned for 4-wide SIMD * \param[in] bb_j Second bounding box, should be aligned for 4-wide SIMD */ -static float clusterBoundingBoxDistance2(const BoundingBox &bb_i, - const BoundingBox &bb_j) +static float clusterBoundingBoxDistance2(const BoundingBox& bb_i, const BoundingBox& bb_j) { // TODO: During SIMDv2 transition only some archs use namespace (remove when done) using namespace gmx; @@ -383,39 +387,38 @@ static float clusterBoundingBoxDistance2(const BoundingBox &bb_i, const Simd4Float bb_j_S0 = load4(bb_j.lower.ptr()); const Simd4Float bb_j_S1 = load4(bb_j.upper.ptr()); - const Simd4Float dl_S = bb_i_S0 - bb_j_S1; - const Simd4Float dh_S = bb_j_S0 - bb_i_S1; + const Simd4Float dl_S = bb_i_S0 - bb_j_S1; + const Simd4Float dh_S = bb_j_S0 - bb_i_S1; - const Simd4Float dm_S = max(dl_S, dh_S); - const Simd4Float dm0_S = max(dm_S, simd4SetZeroF()); + const Simd4Float dm_S = max(dl_S, dh_S); + const Simd4Float dm0_S = max(dm_S, simd4SetZeroF()); return dotProduct(dm0_S, dm0_S); } /* Calculate bb bounding distances of bb_i[si,...,si+3] and store them in d2 */ -template -static inline void gmx_simdcall -clusterBoundingBoxDistance2_xxxx_simd4_inner(const float *bb_i, - float *d2, - const Simd4Float xj_l, - const Simd4Float yj_l, - const Simd4Float zj_l, - const Simd4Float xj_h, - const Simd4Float yj_h, - const Simd4Float zj_h) +template +static inline void gmx_simdcall clusterBoundingBoxDistance2_xxxx_simd4_inner(const float* bb_i, + float* d2, + const Simd4Float xj_l, + const Simd4Float yj_l, + const Simd4Float zj_l, + const Simd4Float xj_h, + const Simd4Float yj_h, + const Simd4Float zj_h) { - constexpr int stride = c_packedBoundingBoxesDimSize; + constexpr int stride = c_packedBoundingBoxesDimSize; - const int shi = boundingBoxStart*Nbnxm::c_numBoundingBoxBounds1D*DIM; + const int shi = boundingBoxStart * Nbnxm::c_numBoundingBoxBounds1D * DIM; const Simd4Float zero = setZero(); - const Simd4Float xi_l = load4(bb_i + shi + 0*stride); - const Simd4Float yi_l = load4(bb_i + shi + 1*stride); - const Simd4Float zi_l = load4(bb_i + shi + 2*stride); - const Simd4Float xi_h = load4(bb_i + shi + 3*stride); - const Simd4Float yi_h = load4(bb_i + shi + 4*stride); - const Simd4Float zi_h = load4(bb_i + shi + 5*stride); + const Simd4Float xi_l = load4(bb_i + shi + 0 * stride); + const Simd4Float yi_l = load4(bb_i + shi + 1 * stride); + const Simd4Float zi_l = load4(bb_i + shi + 2 * stride); + const Simd4Float xi_h = load4(bb_i + shi + 3 * stride); + const Simd4Float yi_h = load4(bb_i + shi + 4 * stride); + const Simd4Float zi_h = load4(bb_i + shi + 5 * stride); const Simd4Float dx_0 = xi_l - xj_h; const Simd4Float dy_0 = yi_l - yj_h; @@ -425,54 +428,46 @@ clusterBoundingBoxDistance2_xxxx_simd4_inner(const float *bb_i, const Simd4Float dy_1 = yj_l - yi_h; const Simd4Float dz_1 = zj_l - zi_h; - const Simd4Float mx = max(dx_0, dx_1); - const Simd4Float my = max(dy_0, dy_1); - const Simd4Float mz = max(dz_0, dz_1); + const Simd4Float mx = max(dx_0, dx_1); + const Simd4Float my = max(dy_0, dy_1); + const Simd4Float mz = max(dz_0, dz_1); - const Simd4Float m0x = max(mx, zero); - const Simd4Float m0y = max(my, zero); - const Simd4Float m0z = max(mz, zero); + const Simd4Float m0x = max(mx, zero); + const Simd4Float m0y = max(my, zero); + const Simd4Float m0z = max(mz, zero); - const Simd4Float d2x = m0x * m0x; - const Simd4Float d2y = m0y * m0y; - const Simd4Float d2z = m0z * m0z; + const Simd4Float d2x = m0x * m0x; + const Simd4Float d2y = m0y * m0y; + const Simd4Float d2z = m0z * m0z; - const Simd4Float d2s = d2x + d2y; - const Simd4Float d2t = d2s + d2z; + const Simd4Float d2s = d2x + d2y; + const Simd4Float d2t = d2s + d2z; store4(d2 + boundingBoxStart, d2t); } /* 4-wide SIMD code for nsi bb distances for bb format xxxxyyyyzzzz */ -static void -clusterBoundingBoxDistance2_xxxx_simd4(const float *bb_j, - const int nsi, - const float *bb_i, - float *d2) +static void clusterBoundingBoxDistance2_xxxx_simd4(const float* bb_j, const int nsi, const float* bb_i, float* d2) { - constexpr int stride = c_packedBoundingBoxesDimSize; + constexpr int stride = c_packedBoundingBoxesDimSize; // TODO: During SIMDv2 transition only some archs use namespace (remove when done) using namespace gmx; - const Simd4Float xj_l = Simd4Float(bb_j[0*stride]); - const Simd4Float yj_l = Simd4Float(bb_j[1*stride]); - const Simd4Float zj_l = Simd4Float(bb_j[2*stride]); - const Simd4Float xj_h = Simd4Float(bb_j[3*stride]); - const Simd4Float yj_h = Simd4Float(bb_j[4*stride]); - const Simd4Float zj_h = Simd4Float(bb_j[5*stride]); + const Simd4Float xj_l = Simd4Float(bb_j[0 * stride]); + const Simd4Float yj_l = Simd4Float(bb_j[1 * stride]); + const Simd4Float zj_l = Simd4Float(bb_j[2 * stride]); + const Simd4Float xj_h = Simd4Float(bb_j[3 * stride]); + const Simd4Float yj_h = Simd4Float(bb_j[4 * stride]); + const Simd4Float zj_h = Simd4Float(bb_j[5 * stride]); /* Here we "loop" over si (0,stride) from 0 to nsi with step stride. * But as we know the number of iterations is 1 or 2, we unroll manually. */ - clusterBoundingBoxDistance2_xxxx_simd4_inner<0>(bb_i, d2, - xj_l, yj_l, zj_l, - xj_h, yj_h, zj_h); + clusterBoundingBoxDistance2_xxxx_simd4_inner<0>(bb_i, d2, xj_l, yj_l, zj_l, xj_h, yj_h, zj_h); if (stride < nsi) { - clusterBoundingBoxDistance2_xxxx_simd4_inner(bb_i, d2, - xj_l, yj_l, zj_l, - xj_h, yj_h, zj_h); + clusterBoundingBoxDistance2_xxxx_simd4_inner(bb_i, d2, xj_l, yj_l, zj_l, xj_h, yj_h, zj_h); } } @@ -481,10 +476,7 @@ clusterBoundingBoxDistance2_xxxx_simd4(const float *bb_j, /* Returns if any atom pair from two clusters is within distance sqrt(rlist2) */ static inline gmx_bool -clusterpair_in_range(const NbnxnPairlistGpuWork &work, - int si, - int csj, int stride, const real *x_j, - real rlist2) +clusterpair_in_range(const NbnxnPairlistGpuWork& work, int si, int csj, int stride, const real* x_j, real rlist2) { #if !GMX_SIMD4_HAVE_REAL @@ -492,16 +484,17 @@ clusterpair_in_range(const NbnxnPairlistGpuWork &work, * All coordinates are stored as xyzxyz... */ - const real *x_i = work.iSuperClusterData.x.data(); + const real* x_i = work.iSuperClusterData.x.data(); for (int i = 0; i < c_nbnxnGpuClusterSize; i++) { - int i0 = (si*c_nbnxnGpuClusterSize + i)*DIM; + int i0 = (si * c_nbnxnGpuClusterSize + i) * DIM; for (int j = 0; j < c_nbnxnGpuClusterSize; j++) { - int j0 = (csj*c_nbnxnGpuClusterSize + j)*stride; + int j0 = (csj * c_nbnxnGpuClusterSize + j) * stride; - real d2 = gmx::square(x_i[i0 ] - x_j[j0 ]) + gmx::square(x_i[i0+1] - x_j[j0+1]) + gmx::square(x_i[i0+2] - x_j[j0+2]); + real d2 = gmx::square(x_i[i0] - x_j[j0]) + gmx::square(x_i[i0 + 1] - x_j[j0 + 1]) + + gmx::square(x_i[i0 + 2] - x_j[j0 + 2]); if (d2 < rlist2) { @@ -521,26 +514,26 @@ clusterpair_in_range(const NbnxnPairlistGpuWork &work, static_assert(c_nbnxnGpuClusterSize == 8 || c_nbnxnGpuClusterSize == 4, "A cluster is hard-coded to 4/8 atoms."); - Simd4Real rc2_S = Simd4Real(rlist2); + Simd4Real rc2_S = Simd4Real(rlist2); - const real *x_i = work.iSuperClusterData.xSimd.data(); + const real* x_i = work.iSuperClusterData.xSimd.data(); - int dim_stride = c_nbnxnGpuClusterSize*DIM; - Simd4Real ix_S0 = load4(x_i + si*dim_stride + 0*GMX_SIMD4_WIDTH); - Simd4Real iy_S0 = load4(x_i + si*dim_stride + 1*GMX_SIMD4_WIDTH); - Simd4Real iz_S0 = load4(x_i + si*dim_stride + 2*GMX_SIMD4_WIDTH); + int dim_stride = c_nbnxnGpuClusterSize * DIM; + Simd4Real ix_S0 = load4(x_i + si * dim_stride + 0 * GMX_SIMD4_WIDTH); + Simd4Real iy_S0 = load4(x_i + si * dim_stride + 1 * GMX_SIMD4_WIDTH); + Simd4Real iz_S0 = load4(x_i + si * dim_stride + 2 * GMX_SIMD4_WIDTH); - Simd4Real ix_S1, iy_S1, iz_S1; + Simd4Real ix_S1, iy_S1, iz_S1; if (c_nbnxnGpuClusterSize == 8) { - ix_S1 = load4(x_i + si*dim_stride + 3*GMX_SIMD4_WIDTH); - iy_S1 = load4(x_i + si*dim_stride + 4*GMX_SIMD4_WIDTH); - iz_S1 = load4(x_i + si*dim_stride + 5*GMX_SIMD4_WIDTH); + ix_S1 = load4(x_i + si * dim_stride + 3 * GMX_SIMD4_WIDTH); + iy_S1 = load4(x_i + si * dim_stride + 4 * GMX_SIMD4_WIDTH); + iz_S1 = load4(x_i + si * dim_stride + 5 * GMX_SIMD4_WIDTH); } /* We loop from the outer to the inner particles to maximize * the chance that we find a pair in range quickly and return. */ - int j0 = csj*c_nbnxnGpuClusterSize; + int j0 = csj * c_nbnxnGpuClusterSize; int j1 = j0 + c_nbnxnGpuClusterSize - 1; while (j0 < j1) { @@ -563,52 +556,52 @@ clusterpair_in_range(const NbnxnPairlistGpuWork &work, Simd4Bool wco_S3; Simd4Bool wco_any_S01, wco_any_S23, wco_any_S; - jx0_S = Simd4Real(x_j[j0*stride+0]); - jy0_S = Simd4Real(x_j[j0*stride+1]); - jz0_S = Simd4Real(x_j[j0*stride+2]); + jx0_S = Simd4Real(x_j[j0 * stride + 0]); + jy0_S = Simd4Real(x_j[j0 * stride + 1]); + jz0_S = Simd4Real(x_j[j0 * stride + 2]); - jx1_S = Simd4Real(x_j[j1*stride+0]); - jy1_S = Simd4Real(x_j[j1*stride+1]); - jz1_S = Simd4Real(x_j[j1*stride+2]); + jx1_S = Simd4Real(x_j[j1 * stride + 0]); + jy1_S = Simd4Real(x_j[j1 * stride + 1]); + jz1_S = Simd4Real(x_j[j1 * stride + 2]); /* Calculate distance */ - dx_S0 = ix_S0 - jx0_S; - dy_S0 = iy_S0 - jy0_S; - dz_S0 = iz_S0 - jz0_S; - dx_S2 = ix_S0 - jx1_S; - dy_S2 = iy_S0 - jy1_S; - dz_S2 = iz_S0 - jz1_S; + dx_S0 = ix_S0 - jx0_S; + dy_S0 = iy_S0 - jy0_S; + dz_S0 = iz_S0 - jz0_S; + dx_S2 = ix_S0 - jx1_S; + dy_S2 = iy_S0 - jy1_S; + dz_S2 = iz_S0 - jz1_S; if (c_nbnxnGpuClusterSize == 8) { - dx_S1 = ix_S1 - jx0_S; - dy_S1 = iy_S1 - jy0_S; - dz_S1 = iz_S1 - jz0_S; - dx_S3 = ix_S1 - jx1_S; - dy_S3 = iy_S1 - jy1_S; - dz_S3 = iz_S1 - jz1_S; + dx_S1 = ix_S1 - jx0_S; + dy_S1 = iy_S1 - jy0_S; + dz_S1 = iz_S1 - jz0_S; + dx_S3 = ix_S1 - jx1_S; + dy_S3 = iy_S1 - jy1_S; + dz_S3 = iz_S1 - jz1_S; } /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); if (c_nbnxnGpuClusterSize == 8) { - rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); - rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); + rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); + rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); } - wco_S0 = (rsq_S0 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); if (c_nbnxnGpuClusterSize == 8) { - wco_S1 = (rsq_S1 < rc2_S); - wco_S3 = (rsq_S3 < rc2_S); + wco_S1 = (rsq_S1 < rc2_S); + wco_S3 = (rsq_S3 < rc2_S); } if (c_nbnxnGpuClusterSize == 8) { - wco_any_S01 = wco_S0 || wco_S1; - wco_any_S23 = wco_S2 || wco_S3; - wco_any_S = wco_any_S01 || wco_any_S23; + wco_any_S01 = wco_S0 || wco_S1; + wco_any_S23 = wco_S2 || wco_S3; + wco_any_S = wco_any_S01 || wco_any_S23; } else { @@ -630,23 +623,21 @@ clusterpair_in_range(const NbnxnPairlistGpuWork &work, } /* Returns the j-cluster index for index cjIndex in a cj list */ -static inline int nblCj(gmx::ArrayRef cjList, - int cjIndex) +static inline int nblCj(gmx::ArrayRef cjList, int cjIndex) { return cjList[cjIndex].cj; } /* Returns the j-cluster index for index cjIndex in a cj4 list */ -static inline int nblCj(gmx::ArrayRef cj4List, - int cjIndex) +static inline int nblCj(gmx::ArrayRef cj4List, int cjIndex) { - return cj4List[cjIndex/c_nbnxnGpuJgroupSize].cj[cjIndex & (c_nbnxnGpuJgroupSize - 1)]; + return cj4List[cjIndex / c_nbnxnGpuJgroupSize].cj[cjIndex & (c_nbnxnGpuJgroupSize - 1)]; } /* Returns the i-interaction mask of the j sub-cell for index cj_ind */ -static unsigned int nbl_imask0(const NbnxnPairlistGpu *nbl, int cj_ind) +static unsigned int nbl_imask0(const NbnxnPairlistGpu* nbl, int cj_ind) { - return nbl->cj4[cj_ind/c_nbnxnGpuJgroupSize].imei[0].imask; + return nbl->cj4[cj_ind / c_nbnxnGpuJgroupSize].imei[0].imask; } NbnxnPairlistCpu::NbnxnPairlistCpu() : @@ -662,45 +653,47 @@ NbnxnPairlistCpu::NbnxnPairlistCpu() : NbnxnPairlistGpu::NbnxnPairlistGpu(gmx::PinningPolicy pinningPolicy) : na_ci(c_nbnxnGpuClusterSize), na_cj(c_nbnxnGpuClusterSize), - na_sc(c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize), + na_sc(c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize), rlist(0), - sci({}, {pinningPolicy}), - cj4({}, {pinningPolicy}), - excl({}, {pinningPolicy}), + sci({}, { pinningPolicy }), + cj4({}, { pinningPolicy }), + excl({}, { pinningPolicy }), nci_tot(0), work(std::make_unique()) { static_assert(c_nbnxnGpuNumClusterPerSupercluster == c_gpuNumClusterPerCell, "The search code assumes that the a super-cluster matches a search grid cell"); - static_assert(sizeof(cj4[0].imei[0].imask)*8 >= c_nbnxnGpuJgroupSize*c_gpuNumClusterPerCell, - "The i super-cluster cluster interaction mask does not contain a sufficient number of bits"); + static_assert(sizeof(cj4[0].imei[0].imask) * 8 >= c_nbnxnGpuJgroupSize * c_gpuNumClusterPerCell, + "The i super-cluster cluster interaction mask does not contain a sufficient " + "number of bits"); - static_assert(sizeof(excl[0])*8 >= c_nbnxnGpuJgroupSize*c_gpuNumClusterPerCell, "The GPU exclusion mask does not contain a sufficient number of bits"); + static_assert(sizeof(excl[0]) * 8 >= c_nbnxnGpuJgroupSize * c_gpuNumClusterPerCell, + "The GPU exclusion mask does not contain a sufficient number of bits"); // We always want a first entry without any exclusions excl.resize(1); } // TODO: Move to pairlistset.cpp -PairlistSet::PairlistSet(const InteractionLocality locality, - const PairlistParams &pairlistParams) : +PairlistSet::PairlistSet(const InteractionLocality locality, const PairlistParams& pairlistParams) : locality_(locality), params_(pairlistParams) { - isCpuType_ = - (params_.pairlistType == PairlistType::Simple4x2 || - params_.pairlistType == PairlistType::Simple4x4 || - params_.pairlistType == PairlistType::Simple4x8); + isCpuType_ = (params_.pairlistType == PairlistType::Simple4x2 + || params_.pairlistType == PairlistType::Simple4x4 + || params_.pairlistType == PairlistType::Simple4x8); // Currently GPU lists are always combined combineLists_ = !isCpuType_; const int numLists = gmx_omp_nthreads_get(emntNonbonded); - if (!combineLists_ && - numLists > NBNXN_BUFFERFLAG_MAX_THREADS) + if (!combineLists_ && numLists > NBNXN_BUFFERFLAG_MAX_THREADS) { - gmx_fatal(FARGS, "%d OpenMP threads were requested. Since the non-bonded force buffer reduction is prohibitively slow with more than %d threads, we do not allow this. Use %d or less OpenMP threads.", + gmx_fatal(FARGS, + "%d OpenMP threads were requested. Since the non-bonded force buffer reduction " + "is prohibitively slow with more than %d threads, we do not allow this. Use %d " + "or less OpenMP threads.", numLists, NBNXN_BUFFERFLAG_MAX_THREADS, NBNXN_BUFFERFLAG_MAX_THREADS); } @@ -742,49 +735,47 @@ PairlistSet::PairlistSet(const InteractionLocality locality, fepLists_[i] = std::make_unique(); nbnxn_init_pairlist_fep(fepLists_[i].get()); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } } /* Print statistics of a pair list, used for debug output */ -static void print_nblist_statistics(FILE *fp, - const NbnxnPairlistCpu &nbl, - const Nbnxm::GridSet &gridSet, +static void print_nblist_statistics(FILE* fp, + const NbnxnPairlistCpu& nbl, + const Nbnxm::GridSet& gridSet, const real rl) { - const Grid &grid = gridSet.grids()[0]; - const Grid::Dimensions &dims = grid.dimensions(); - - fprintf(fp, "nbl nci %zu ncj %d\n", - nbl.ci.size(), nbl.ncjInUse); - const int numAtomsJCluster = grid.geometry().numAtomsJCluster; - const double numAtomsPerCell = nbl.ncjInUse/static_cast(grid.numCells())*numAtomsJCluster; - fprintf(fp, "nbl na_cj %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", - nbl.na_cj, rl, nbl.ncjInUse, nbl.ncjInUse/static_cast(grid.numCells()), - numAtomsPerCell, - numAtomsPerCell/(0.5*4.0/3.0*M_PI*rl*rl*rl*grid.numCells()*numAtomsJCluster/(dims.gridSize[XX]*dims.gridSize[YY]*dims.gridSize[ZZ]))); + const Grid& grid = gridSet.grids()[0]; + const Grid::Dimensions& dims = grid.dimensions(); + + fprintf(fp, "nbl nci %zu ncj %d\n", nbl.ci.size(), nbl.ncjInUse); + const int numAtomsJCluster = grid.geometry().numAtomsJCluster; + const double numAtomsPerCell = nbl.ncjInUse / static_cast(grid.numCells()) * numAtomsJCluster; + fprintf(fp, "nbl na_cj %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", nbl.na_cj, rl, + nbl.ncjInUse, nbl.ncjInUse / static_cast(grid.numCells()), numAtomsPerCell, + numAtomsPerCell + / (0.5 * 4.0 / 3.0 * M_PI * rl * rl * rl * grid.numCells() * numAtomsJCluster + / (dims.gridSize[XX] * dims.gridSize[YY] * dims.gridSize[ZZ]))); fprintf(fp, "nbl average j cell list length %.1f\n", - 0.25*nbl.ncjInUse/std::max(static_cast(nbl.ci.size()), 1.0)); + 0.25 * nbl.ncjInUse / std::max(static_cast(nbl.ci.size()), 1.0)); int cs[SHIFTS] = { 0 }; int npexcl = 0; - for (const nbnxn_ci_t &ciEntry : nbl.ci) + for (const nbnxn_ci_t& ciEntry : nbl.ci) { - cs[ciEntry.shift & NBNXN_CI_SHIFT] += - ciEntry.cj_ind_end - ciEntry.cj_ind_start; + cs[ciEntry.shift & NBNXN_CI_SHIFT] += ciEntry.cj_ind_end - ciEntry.cj_ind_start; int j = ciEntry.cj_ind_start; - while (j < ciEntry.cj_ind_end && - nbl.cj[j].excl != NBNXN_INTERACTION_MASK_ALL) + while (j < ciEntry.cj_ind_end && nbl.cj[j].excl != NBNXN_INTERACTION_MASK_ALL) { npexcl++; j++; } } - fprintf(fp, "nbl cell pairs, total: %zu excl: %d %.1f%%\n", - nbl.cj.size(), npexcl, 100*npexcl/std::max(static_cast(nbl.cj.size()), 1.0)); + fprintf(fp, "nbl cell pairs, total: %zu excl: %d %.1f%%\n", nbl.cj.size(), npexcl, + 100 * npexcl / std::max(static_cast(nbl.cj.size()), 1.0)); for (int s = 0; s < SHIFTS; s++) { if (cs[s] > 0) @@ -795,28 +786,29 @@ static void print_nblist_statistics(FILE *fp, } /* Print statistics of a pair lists, used for debug output */ -static void print_nblist_statistics(FILE *fp, - const NbnxnPairlistGpu &nbl, - const Nbnxm::GridSet &gridSet, +static void print_nblist_statistics(FILE* fp, + const NbnxnPairlistGpu& nbl, + const Nbnxm::GridSet& gridSet, const real rl) { - const Grid &grid = gridSet.grids()[0]; - const Grid::Dimensions &dims = grid.dimensions(); - - fprintf(fp, "nbl nsci %zu ncj4 %zu nsi %d excl4 %zu\n", - nbl.sci.size(), nbl.cj4.size(), nbl.nci_tot, nbl.excl.size()); - const int numAtomsCluster = grid.geometry().numAtomsICluster; - const double numAtomsPerCell = nbl.nci_tot/static_cast(grid.numClusters())*numAtomsCluster; - fprintf(fp, "nbl na_c %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", - nbl.na_ci, rl, nbl.nci_tot, nbl.nci_tot/static_cast(grid.numClusters()), - numAtomsPerCell, - numAtomsPerCell/(0.5*4.0/3.0*M_PI*rl*rl*rl*grid.numClusters()*numAtomsCluster/(dims.gridSize[XX]*dims.gridSize[YY]*dims.gridSize[ZZ]))); - - double sum_nsp = 0; - double sum_nsp2 = 0; - int nsp_max = 0; + const Grid& grid = gridSet.grids()[0]; + const Grid::Dimensions& dims = grid.dimensions(); + + fprintf(fp, "nbl nsci %zu ncj4 %zu nsi %d excl4 %zu\n", nbl.sci.size(), nbl.cj4.size(), + nbl.nci_tot, nbl.excl.size()); + const int numAtomsCluster = grid.geometry().numAtomsICluster; + const double numAtomsPerCell = nbl.nci_tot / static_cast(grid.numClusters()) * numAtomsCluster; + fprintf(fp, "nbl na_c %d rl %g ncp %d per cell %.1f atoms %.1f ratio %.2f\n", nbl.na_ci, rl, + nbl.nci_tot, nbl.nci_tot / static_cast(grid.numClusters()), numAtomsPerCell, + numAtomsPerCell + / (0.5 * 4.0 / 3.0 * M_PI * rl * rl * rl * grid.numClusters() * numAtomsCluster + / (dims.gridSize[XX] * dims.gridSize[YY] * dims.gridSize[ZZ]))); + + double sum_nsp = 0; + double sum_nsp2 = 0; + int nsp_max = 0; int c[c_gpuNumClusterPerCell + 1] = { 0 }; - for (const nbnxn_sci_t &sci : nbl.sci) + for (const nbnxn_sci_t& sci : nbl.sci) { int nsp = 0; for (int j4 = sci.cj4_ind_start; j4 < sci.cj4_ind_end; j4++) @@ -826,7 +818,7 @@ static void print_nblist_statistics(FILE *fp, int b = 0; for (int si = 0; si < c_gpuNumClusterPerCell; si++) { - if (nbl.cj4[j4].imei[0].imask & (1U << (j*c_gpuNumClusterPerCell + si))) + if (nbl.cj4[j4].imei[0].imask & (1U << (j * c_gpuNumClusterPerCell + si))) { b++; } @@ -835,24 +827,24 @@ static void print_nblist_statistics(FILE *fp, c[b]++; } } - sum_nsp += nsp; - sum_nsp2 += nsp*nsp; - nsp_max = std::max(nsp_max, nsp); + sum_nsp += nsp; + sum_nsp2 += nsp * nsp; + nsp_max = std::max(nsp_max, nsp); } if (!nbl.sci.empty()) { - sum_nsp /= nbl.sci.size(); + sum_nsp /= nbl.sci.size(); sum_nsp2 /= nbl.sci.size(); } - fprintf(fp, "nbl #cluster-pairs: av %.1f stddev %.1f max %d\n", - sum_nsp, std::sqrt(sum_nsp2 - sum_nsp*sum_nsp), nsp_max); + fprintf(fp, "nbl #cluster-pairs: av %.1f stddev %.1f max %d\n", sum_nsp, + std::sqrt(sum_nsp2 - sum_nsp * sum_nsp), nsp_max); if (!nbl.cj4.empty()) { for (int b = 0; b <= c_gpuNumClusterPerCell; b++) { - fprintf(fp, "nbl j-list #i-subcell %d %7d %4.1f\n", - b, c[b], 100.0*c[b]/size_t {nbl.cj4.size()*c_nbnxnGpuJgroupSize}); + fprintf(fp, "nbl j-list #i-subcell %d %7d %4.1f\n", b, c[b], + 100.0 * c[b] / size_t{ nbl.cj4.size() * c_nbnxnGpuJgroupSize }); } } } @@ -862,9 +854,7 @@ static void print_nblist_statistics(FILE *fp, * the default all-interaction mask at call time, so the returned mask * can be modified when needed. */ -static nbnxn_excl_t &get_exclusion_mask(NbnxnPairlistGpu *nbl, - int cj4, - int warp) +static nbnxn_excl_t& get_exclusion_mask(NbnxnPairlistGpu* nbl, int cj4, int warp) { if (nbl->cj4[cj4].imei[warp].excl_ind == 0) { @@ -886,28 +876,27 @@ static nbnxn_excl_t &get_exclusion_mask(NbnxnPairlistGpu *nbl, * \param[in] jOffsetInGroup The j-entry offset in \p nbl->cj4[cj4Index] * \param[in] iClusterInCell The i-cluster index in the cell */ -static void -setSelfAndNewtonExclusionsGpu(NbnxnPairlistGpu *nbl, - const int cj4Index, - const int jOffsetInGroup, - const int iClusterInCell) +static void setSelfAndNewtonExclusionsGpu(NbnxnPairlistGpu* nbl, + const int cj4Index, + const int jOffsetInGroup, + const int iClusterInCell) { - constexpr int numJatomsPerPart = c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit; + constexpr int numJatomsPerPart = c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit; /* The exclusions are stored separately for each part of the split */ for (int part = 0; part < c_nbnxnGpuClusterpairSplit; part++) { - const int jOffset = part*numJatomsPerPart; + const int jOffset = part * numJatomsPerPart; /* Make a new exclusion mask entry for each part, if we don't already have one yet */ - nbnxn_excl_t &excl = get_exclusion_mask(nbl, cj4Index, part); + nbnxn_excl_t& excl = get_exclusion_mask(nbl, cj4Index, part); /* Set all bits with j-index <= i-index */ for (int jIndexInPart = 0; jIndexInPart < numJatomsPerPart; jIndexInPart++) { for (int i = jOffset + jIndexInPart; i < c_nbnxnGpuClusterSize; i++) { - excl.pair[jIndexInPart*c_nbnxnGpuClusterSize + i] &= - ~(1U << (jOffsetInGroup*c_gpuNumClusterPerCell + iClusterInCell)); + excl.pair[jIndexInPart * c_nbnxnGpuClusterSize + i] &= + ~(1U << (jOffsetInGroup * c_gpuNumClusterPerCell + iClusterInCell)); } } } @@ -922,9 +911,9 @@ static unsigned int get_imask(gmx_bool rdiag, int ci, int cj) /* Returns a diagonal or off-diagonal interaction mask for cj-size=2 */ gmx_unused static unsigned int get_imask_simd_j2(gmx_bool rdiag, int ci, int cj) { - return (rdiag && ci*2 == cj ? NBNXN_INTERACTION_MASK_DIAG_J2_0 : - (rdiag && ci*2+1 == cj ? NBNXN_INTERACTION_MASK_DIAG_J2_1 : - NBNXN_INTERACTION_MASK_ALL)); + return (rdiag && ci * 2 == cj ? NBNXN_INTERACTION_MASK_DIAG_J2_0 + : (rdiag && ci * 2 + 1 == cj ? NBNXN_INTERACTION_MASK_DIAG_J2_1 + : NBNXN_INTERACTION_MASK_ALL)); } /* Returns a diagonal or off-diagonal interaction mask for cj-size=4 */ @@ -936,25 +925,25 @@ gmx_unused static unsigned int get_imask_simd_j4(gmx_bool rdiag, int ci, int cj) /* Returns a diagonal or off-diagonal interaction mask for cj-size=8 */ gmx_unused static unsigned int get_imask_simd_j8(gmx_bool rdiag, int ci, int cj) { - return (rdiag && ci == cj*2 ? NBNXN_INTERACTION_MASK_DIAG_J8_0 : - (rdiag && ci == cj*2+1 ? NBNXN_INTERACTION_MASK_DIAG_J8_1 : - NBNXN_INTERACTION_MASK_ALL)); + return (rdiag && ci == cj * 2 ? NBNXN_INTERACTION_MASK_DIAG_J8_0 + : (rdiag && ci == cj * 2 + 1 ? NBNXN_INTERACTION_MASK_DIAG_J8_1 + : NBNXN_INTERACTION_MASK_ALL)); } #if GMX_SIMD -#if GMX_SIMD_REAL_WIDTH == 2 -#define get_imask_simd_4xn get_imask_simd_j2 -#endif -#if GMX_SIMD_REAL_WIDTH == 4 -#define get_imask_simd_4xn get_imask_simd_j4 -#endif -#if GMX_SIMD_REAL_WIDTH == 8 -#define get_imask_simd_4xn get_imask_simd_j8 -#define get_imask_simd_2xnn get_imask_simd_j4 -#endif -#if GMX_SIMD_REAL_WIDTH == 16 -#define get_imask_simd_2xnn get_imask_simd_j8 -#endif +# if GMX_SIMD_REAL_WIDTH == 2 +# define get_imask_simd_4xn get_imask_simd_j2 +# endif +# if GMX_SIMD_REAL_WIDTH == 4 +# define get_imask_simd_4xn get_imask_simd_j4 +# endif +# if GMX_SIMD_REAL_WIDTH == 8 +# define get_imask_simd_4xn get_imask_simd_j8 +# define get_imask_simd_2xnn get_imask_simd_j4 +# endif +# if GMX_SIMD_REAL_WIDTH == 16 +# define get_imask_simd_2xnn get_imask_simd_j8 +# endif #endif /* Plain C code for checking and adding cluster-pairs to the list. @@ -970,27 +959,26 @@ gmx_unused static unsigned int get_imask_simd_j8(gmx_bool rdiag, int ci, int cj) * \param[in] rbb2 The squared cut-off for putting cluster-pairs in the list based on bounding box distance only * \param[in,out] numDistanceChecks The number of distance checks performed */ -static void -makeClusterListSimple(const Grid &jGrid, - NbnxnPairlistCpu * nbl, - int icluster, - int jclusterFirst, - int jclusterLast, - bool excludeSubDiagonal, - const real * gmx_restrict x_j, - real rlist2, - float rbb2, - int * gmx_restrict numDistanceChecks) +static void makeClusterListSimple(const Grid& jGrid, + NbnxnPairlistCpu* nbl, + int icluster, + int jclusterFirst, + int jclusterLast, + bool excludeSubDiagonal, + const real* gmx_restrict x_j, + real rlist2, + float rbb2, + int* gmx_restrict numDistanceChecks) { - const BoundingBox * gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); - const real * gmx_restrict x_ci = nbl->work->iClusterData.x.data(); + const BoundingBox* gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); + const real* gmx_restrict x_ci = nbl->work->iClusterData.x.data(); - gmx_bool InRange; + gmx_bool InRange; InRange = FALSE; while (!InRange && jclusterFirst <= jclusterLast) { - real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); + real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -1009,13 +997,18 @@ makeClusterListSimple(const Grid &jGrid, { for (int j = 0; j < c_nbnxnCpuIClusterSize; j++) { - InRange = InRange || - (gmx::square(x_ci[i*STRIDE_XYZ+XX] - x_j[(cjf_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+XX]) + - gmx::square(x_ci[i*STRIDE_XYZ+YY] - x_j[(cjf_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+YY]) + - gmx::square(x_ci[i*STRIDE_XYZ+ZZ] - x_j[(cjf_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+ZZ]) < rlist2); + InRange = + InRange + || (gmx::square(x_ci[i * STRIDE_XYZ + XX] + - x_j[(cjf_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + XX]) + + gmx::square(x_ci[i * STRIDE_XYZ + YY] + - x_j[(cjf_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + YY]) + + gmx::square(x_ci[i * STRIDE_XYZ + ZZ] + - x_j[(cjf_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + ZZ]) + < rlist2); } } - *numDistanceChecks += c_nbnxnCpuIClusterSize*c_nbnxnCpuIClusterSize; + *numDistanceChecks += c_nbnxnCpuIClusterSize * c_nbnxnCpuIClusterSize; } if (!InRange) { @@ -1030,7 +1023,7 @@ makeClusterListSimple(const Grid &jGrid, InRange = FALSE; while (!InRange && jclusterLast > jclusterFirst) { - real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); + real d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -1049,13 +1042,18 @@ makeClusterListSimple(const Grid &jGrid, { for (int j = 0; j < c_nbnxnCpuIClusterSize; j++) { - InRange = InRange || - (gmx::square(x_ci[i*STRIDE_XYZ+XX] - x_j[(cjl_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+XX]) + - gmx::square(x_ci[i*STRIDE_XYZ+YY] - x_j[(cjl_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+YY]) + - gmx::square(x_ci[i*STRIDE_XYZ+ZZ] - x_j[(cjl_gl*c_nbnxnCpuIClusterSize+j)*STRIDE_XYZ+ZZ]) < rlist2); + InRange = + InRange + || (gmx::square(x_ci[i * STRIDE_XYZ + XX] + - x_j[(cjl_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + XX]) + + gmx::square(x_ci[i * STRIDE_XYZ + YY] + - x_j[(cjl_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + YY]) + + gmx::square(x_ci[i * STRIDE_XYZ + ZZ] + - x_j[(cjl_gl * c_nbnxnCpuIClusterSize + j) * STRIDE_XYZ + ZZ]) + < rlist2); } } - *numDistanceChecks += c_nbnxnCpuIClusterSize*c_nbnxnCpuIClusterSize; + *numDistanceChecks += c_nbnxnCpuIClusterSize * c_nbnxnCpuIClusterSize; } if (!InRange) { @@ -1079,33 +1077,33 @@ makeClusterListSimple(const Grid &jGrid, } #ifdef GMX_NBNXN_SIMD_4XN -#include "pairlist_simd_4xm.h" +# include "pairlist_simd_4xm.h" #endif #ifdef GMX_NBNXN_SIMD_2XNN -#include "pairlist_simd_2xmm.h" +# include "pairlist_simd_2xmm.h" #endif /* Plain C or SIMD4 code for making a pair list of super-cell sci vs scj. * Checks bounding box distances and possibly atom pair distances. */ -static void make_cluster_list_supersub(const Grid &iGrid, - const Grid &jGrid, - NbnxnPairlistGpu *nbl, - const int sci, - const int scj, - const bool excludeSubDiagonal, - const int stride, - const real *x, - const real rlist2, - const float rbb2, - int *numDistanceChecks) +static void make_cluster_list_supersub(const Grid& iGrid, + const Grid& jGrid, + NbnxnPairlistGpu* nbl, + const int sci, + const int scj, + const bool excludeSubDiagonal, + const int stride, + const real* x, + const real rlist2, + const float rbb2, + int* numDistanceChecks) { - NbnxnPairlistGpuWork &work = *nbl->work; + NbnxnPairlistGpuWork& work = *nbl->work; #if NBNXN_BBXXXX - const float *pbb_ci = work.iSuperClusterData.bbPacked.data(); + const float* pbb_ci = work.iSuperClusterData.bbPacked.data(); #else - const BoundingBox *bb_ci = work.iSuperClusterData.bb.data(); + const BoundingBox* bb_ci = work.iSuperClusterData.bb.data(); #endif assert(c_nbnxnGpuClusterSize == iGrid.geometry().numAtomsICluster); @@ -1120,20 +1118,20 @@ static void make_cluster_list_supersub(const Grid &iGrid, #define PRUNE_LIST_CPU_ALL 0 #if PRUNE_LIST_CPU_ONE - int ci_last = -1; + int ci_last = -1; #endif - float *d2l = work.distanceBuffer.data(); + float* d2l = work.distanceBuffer.data(); for (int subc = 0; subc < jGrid.numClustersPerCell()[scj]; subc++) { - const int cj4_ind = work.cj_ind/c_nbnxnGpuJgroupSize; - const int cj_offset = work.cj_ind - cj4_ind*c_nbnxnGpuJgroupSize; - const int cj = scj*c_gpuNumClusterPerCell + subc; + const int cj4_ind = work.cj_ind / c_nbnxnGpuJgroupSize; + const int cj_offset = work.cj_ind - cj4_ind * c_nbnxnGpuJgroupSize; + const int cj = scj * c_gpuNumClusterPerCell + subc; - const int cj_gl = jGrid.cellOffset()*c_gpuNumClusterPerCell + cj; + const int cj_gl = jGrid.cellOffset() * c_gpuNumClusterPerCell + cj; - int ci1; + int ci1; if (excludeSubDiagonal && sci == scj) { ci1 = subc + 1; @@ -1146,9 +1144,9 @@ static void make_cluster_list_supersub(const Grid &iGrid, #if NBNXN_BBXXXX /* Determine all ci1 bb distances in one call with SIMD4 */ const int offset = packedBoundingBoxesIndex(cj) + (cj & (c_packedBoundingBoxesDimSize - 1)); - clusterBoundingBoxDistance2_xxxx_simd4(jGrid.packedBoundingBoxes().data() + offset, - ci1, pbb_ci, d2l); - *numDistanceChecks += c_nbnxnGpuClusterSize*2; + clusterBoundingBoxDistance2_xxxx_simd4(jGrid.packedBoundingBoxes().data() + offset, ci1, + pbb_ci, d2l); + *numDistanceChecks += c_nbnxnGpuClusterSize * 2; #endif int npair = 0; @@ -1163,7 +1161,7 @@ static void make_cluster_list_supersub(const Grid &iGrid, #if !NBNXN_BBXXXX /* Determine the bb distance between ci and cj */ - d2l[ci] = clusterBoundingBoxDistance2(bb_ci[ci], jGrid.jBoundingBoxes()[cj]); + d2l[ci] = clusterBoundingBoxDistance2(bb_ci[ci], jGrid.jBoundingBoxes()[cj]); *numDistanceChecks += 2; #endif float d2 = d2l[ci]; @@ -1174,10 +1172,8 @@ static void make_cluster_list_supersub(const Grid &iGrid, * or within the cut-off and there is at least one atom pair * within the cut-off. This check is very costly. */ - *numDistanceChecks += c_nbnxnGpuClusterSize*c_nbnxnGpuClusterSize; - if (d2 < rbb2 || - (d2 < rlist2 && - clusterpair_in_range(work, ci, cj_gl, stride, x, rlist2))) + *numDistanceChecks += c_nbnxnGpuClusterSize * c_nbnxnGpuClusterSize; + if (d2 < rbb2 || (d2 < rlist2 && clusterpair_in_range(work, ci, cj_gl, stride, x, rlist2))) #else /* Check if the distance between the two bounding boxes * in within the pair-list cut-off. @@ -1186,7 +1182,7 @@ static void make_cluster_list_supersub(const Grid &iGrid, #endif { /* Flag this i-subcell to be taken into account */ - imask |= (1U << (cj_offset*c_gpuNumClusterPerCell + ci)); + imask |= (1U << (cj_offset * c_gpuNumClusterPerCell + ci)); #if PRUNE_LIST_CPU_ONE ci_last = ci; @@ -1200,10 +1196,10 @@ static void make_cluster_list_supersub(const Grid &iGrid, /* If we only found 1 pair, check if any atoms are actually * within the cut-off, so we could get rid of it. */ - if (npair == 1 && d2l[ci_last] >= rbb2 && - !clusterpair_in_range(work, ci_last, cj_gl, stride, x, rlist2)) + if (npair == 1 && d2l[ci_last] >= rbb2 + && !clusterpair_in_range(work, ci_last, cj_gl, stride, x, rlist2)) { - imask &= ~(1U << (cj_offset*c_gpuNumClusterPerCell + ci_last)); + imask &= ~(1U << (cj_offset * c_gpuNumClusterPerCell + ci_last)); npair--; } #endif @@ -1215,7 +1211,7 @@ static void make_cluster_list_supersub(const Grid &iGrid, { nbl->cj4.resize(nbl->cj4.size() + 1); } - nbnxn_cj4_t *cj4 = &nbl->cj4[cj4_ind]; + nbnxn_cj4_t* cj4 = &nbl->cj4[cj4_ind]; cj4->cj[cj_offset] = cj_gl; @@ -1241,23 +1237,23 @@ static void make_cluster_list_supersub(const Grid &iGrid, /* Increase the closing index in i super-cell list */ nbl->sci.back().cj4_ind_end = - (nbl->work->cj_ind + c_nbnxnGpuJgroupSize - 1)/c_nbnxnGpuJgroupSize; + (nbl->work->cj_ind + c_nbnxnGpuJgroupSize - 1) / c_nbnxnGpuJgroupSize; } } } /* Returns how many contiguous j-clusters we have starting in the i-list */ -template +template static int numContiguousJClusters(const int cjIndexStart, const int cjIndexEnd, gmx::ArrayRef cjList) { const int firstJCluster = nblCj(cjList, cjIndexStart); - int numContiguous = 0; + int numContiguous = 0; - while (cjIndexStart + numContiguous < cjIndexEnd && - nblCj(cjList, cjIndexStart + numContiguous) == firstJCluster + numContiguous) + while (cjIndexStart + numContiguous < cjIndexEnd + && nblCj(cjList, cjIndexStart + numContiguous) == firstJCluster + numContiguous) { numContiguous++; } @@ -1271,30 +1267,26 @@ static int numContiguousJClusters(const int cjIndexStart, struct JListRanges { /*! \brief Constructs a j-list range from \p cjList with the given index range */ - template - JListRanges(int cjIndexStart, - int cjIndexEnd, - gmx::ArrayRef cjList); + template + JListRanges(int cjIndexStart, int cjIndexEnd, gmx::ArrayRef cjList); int cjIndexStart; //!< The start index in the j-list int cjIndexEnd; //!< The end index in the j-list int cjFirst; //!< The j-cluster with index cjIndexStart int cjLast; //!< The j-cluster with index cjIndexEnd-1 - int numDirect; //!< Up to cjIndexStart+numDirect the j-clusters are cjFirst + the index offset + int numDirect; //!< Up to cjIndexStart+numDirect the j-clusters are cjFirst + the index offset }; #ifndef DOXYGEN -template -JListRanges::JListRanges(int cjIndexStart, - int cjIndexEnd, - gmx::ArrayRef cjList) : +template +JListRanges::JListRanges(int cjIndexStart, int cjIndexEnd, gmx::ArrayRef cjList) : cjIndexStart(cjIndexStart), cjIndexEnd(cjIndexEnd) { GMX_ASSERT(cjIndexEnd > cjIndexStart, "JListRanges should only be called with non-empty lists"); - cjFirst = nblCj(cjList, cjIndexStart); - cjLast = nblCj(cjList, cjIndexEnd - 1); + cjFirst = nblCj(cjList, cjIndexStart); + cjLast = nblCj(cjList, cjIndexEnd - 1); /* Determine how many contiguous j-cells we have starting * from the first i-cell. This number can be used to directly @@ -1309,11 +1301,10 @@ JListRanges::JListRanges(int cjIndexStart, * Note: This code is executed very often and therefore performance is * important. It should be inlined and fully optimized. */ -template -static inline int -findJClusterInJList(int jCluster, - const JListRanges &ranges, - gmx::ArrayRef cjList) +template +static inline int findJClusterInJList(int jCluster, + const JListRanges& ranges, + gmx::ArrayRef cjList) { int index; @@ -1325,9 +1316,9 @@ findJClusterInJList(int jCluster, else { /* Search for jCluster using bisection */ - index = -1; - int rangeStart = ranges.cjIndexStart + ranges.numDirect; - int rangeEnd = ranges.cjIndexEnd; + index = -1; + int rangeStart = ranges.cjIndexStart + ranges.numDirect; + int rangeEnd = ranges.cjIndexEnd; int rangeMiddle; while (index == -1 && rangeStart < rangeEnd) { @@ -1337,11 +1328,11 @@ findJClusterInJList(int jCluster, if (jCluster == clusterMiddle) { - index = rangeMiddle; + index = rangeMiddle; } else if (jCluster < clusterMiddle) { - rangeEnd = rangeMiddle; + rangeEnd = rangeMiddle; } else { @@ -1356,13 +1347,13 @@ findJClusterInJList(int jCluster, // TODO: Get rid of the two functions below by renaming sci to ci (or something better) /* Return the i-entry in the list we are currently operating on */ -static nbnxn_ci_t *getOpenIEntry(NbnxnPairlistCpu *nbl) +static nbnxn_ci_t* getOpenIEntry(NbnxnPairlistCpu* nbl) { return &nbl->ci.back(); } /* Return the i-entry in the list we are currently operating on */ -static nbnxn_sci_t *getOpenIEntry(NbnxnPairlistGpu *nbl) +static nbnxn_sci_t* getOpenIEntry(NbnxnPairlistGpu* nbl) { return &nbl->sci.back(); } @@ -1372,13 +1363,12 @@ static nbnxn_sci_t *getOpenIEntry(NbnxnPairlistGpu *nbl) * Set all atom-pair exclusions from the topology stored in exclusions * as masks in the pair-list for simple list entry iEntry. */ -static void -setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, - NbnxnPairlistCpu *nbl, - gmx_bool diagRemoved, - int na_cj_2log, - const nbnxn_ci_t &iEntry, - const t_blocka &exclusions) +static void setExclusionsForIEntry(const Nbnxm::GridSet& gridSet, + NbnxnPairlistCpu* nbl, + gmx_bool diagRemoved, + int na_cj_2log, + const nbnxn_ci_t& iEntry, + const t_blocka& exclusions) { if (iEntry.cj_ind_end == iEntry.cj_ind_start) { @@ -1386,9 +1376,9 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, return; } - const JListRanges ranges(iEntry.cj_ind_start, iEntry.cj_ind_end, gmx::makeConstArrayRef(nbl->cj)); + const JListRanges ranges(iEntry.cj_ind_start, iEntry.cj_ind_end, gmx::makeConstArrayRef(nbl->cj)); - const int iCluster = iEntry.ci; + const int iCluster = iEntry.ci; gmx::ArrayRef cell = gridSet.cells(); gmx::ArrayRef atomIndices = gridSet.atomIndices(); @@ -1396,12 +1386,13 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, /* Loop over the atoms in the i-cluster */ for (int i = 0; i < nbl->na_ci; i++) { - const int iIndex = iCluster*nbl->na_ci + i; + const int iIndex = iCluster * nbl->na_ci + i; const int iAtom = atomIndices[iIndex]; if (iAtom >= 0) { /* Loop over the topology-based exclusions for this i-atom */ - for (int exclIndex = exclusions.index[iAtom]; exclIndex < exclusions.index[iAtom + 1]; exclIndex++) + for (int exclIndex = exclusions.index[iAtom]; exclIndex < exclusions.index[iAtom + 1]; + exclIndex++) { const int jAtom = exclusions.a[exclIndex]; @@ -1428,15 +1419,14 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, if (jCluster >= ranges.cjFirst && jCluster <= ranges.cjLast) { const int index = - findJClusterInJList(jCluster, ranges, - gmx::makeConstArrayRef(nbl->cj)); + findJClusterInJList(jCluster, ranges, gmx::makeConstArrayRef(nbl->cj)); if (index >= 0) { /* We found an exclusion, clear the corresponding * interaction bit. */ - const int innerJ = jIndex - (jCluster << na_cj_2log); + const int innerJ = jIndex - (jCluster << na_cj_2log); nbl->cj[index].excl &= ~(1U << ((i << na_cj_2log) + innerJ)); } @@ -1447,7 +1437,7 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, } /* Add a new i-entry to the FEP list and copy the i-properties */ -static inline void fep_list_new_nri_copy(t_nblist *nlist) +static inline void fep_list_new_nri_copy(t_nblist* nlist) { /* Add a new i-entry */ nlist->nri++; @@ -1455,24 +1445,25 @@ static inline void fep_list_new_nri_copy(t_nblist *nlist) assert(nlist->nri < nlist->maxnri); /* Duplicate the last i-entry, except for jindex, which continues */ - nlist->iinr[nlist->nri] = nlist->iinr[nlist->nri-1]; - nlist->shift[nlist->nri] = nlist->shift[nlist->nri-1]; - nlist->gid[nlist->nri] = nlist->gid[nlist->nri-1]; + nlist->iinr[nlist->nri] = nlist->iinr[nlist->nri - 1]; + nlist->shift[nlist->nri] = nlist->shift[nlist->nri - 1]; + nlist->gid[nlist->nri] = nlist->gid[nlist->nri - 1]; nlist->jindex[nlist->nri] = nlist->nrj; } /* Rellocate FEP list for size nl->maxnri, TODO: replace by C++ */ -static void reallocate_nblist(t_nblist *nl) +static void reallocate_nblist(t_nblist* nl) { if (gmx_debug_at) { - fprintf(debug, "reallocating neigborlist (ielec=%d, ivdw=%d, igeometry=%d, type=%d), maxnri=%d\n", + fprintf(debug, + "reallocating neigborlist (ielec=%d, ivdw=%d, igeometry=%d, type=%d), maxnri=%d\n", nl->ielec, nl->ivdw, nl->igeometry, nl->type, nl->maxnri); } - srenew(nl->iinr, nl->maxnri); - srenew(nl->gid, nl->maxnri); - srenew(nl->shift, nl->maxnri); - srenew(nl->jindex, nl->maxnri+1); + srenew(nl->iinr, nl->maxnri); + srenew(nl->gid, nl->maxnri); + srenew(nl->shift, nl->maxnri); + srenew(nl->jindex, nl->maxnri + 1); } /* For load balancing of the free-energy lists over threads, we set @@ -1489,18 +1480,18 @@ const int max_nrj_fep = 40; * LJ parameters have been zeroed in the nbnxn data structure. * Simultaneously make a group pair list for the perturbed pairs. */ -static void make_fep_list(gmx::ArrayRef atomIndices, - const nbnxn_atomdata_t *nbat, - NbnxnPairlistCpu *nbl, - gmx_bool bDiagRemoved, - nbnxn_ci_t *nbl_ci, - real gmx_unused shx, - real gmx_unused shy, - real gmx_unused shz, - real gmx_unused rlist_fep2, - const Grid &iGrid, - const Grid &jGrid, - t_nblist *nlist) +static void make_fep_list(gmx::ArrayRef atomIndices, + const nbnxn_atomdata_t* nbat, + NbnxnPairlistCpu* nbl, + gmx_bool bDiagRemoved, + nbnxn_ci_t* nbl_ci, + real gmx_unused shx, + real gmx_unused shy, + real gmx_unused shz, + real gmx_unused rlist_fep2, + const Grid& iGrid, + const Grid& jGrid, + t_nblist* nlist) { int ci, cj_ind_start, cj_ind_end, cja, cjr; int nri_max; @@ -1526,7 +1517,7 @@ static void make_fep_list(gmx::ArrayRef atomIndices, * and create #atom-pair lists, which means we need the size * of a cluster pair (na_ci*na_cj) times the number of cj's. */ - nri_max = nbl->na_ci*nbl->na_cj*(cj_ind_end - cj_ind_start); + nri_max = nbl->na_ci * nbl->na_cj * (cj_ind_end - cj_ind_start); if (nlist->nri + nri_max > nlist->maxnri) { nlist->maxnri = over_alloc_large(nlist->nri + nri_max); @@ -1535,17 +1526,19 @@ static void make_fep_list(gmx::ArrayRef atomIndices, const int numAtomsJCluster = jGrid.geometry().numAtomsJCluster; - const nbnxn_atomdata_t::Params &nbatParams = nbat->params(); + const nbnxn_atomdata_t::Params& nbatParams = nbat->params(); const int ngid = nbatParams.nenergrp; /* TODO: Consider adding a check in grompp and changing this to an assert */ - const int numBitsInEnergyGroupIdsForAtomsInJCluster = sizeof(gid_cj)*8; - if (ngid*numAtomsJCluster > numBitsInEnergyGroupIdsForAtomsInJCluster) + const int numBitsInEnergyGroupIdsForAtomsInJCluster = sizeof(gid_cj) * 8; + if (ngid * numAtomsJCluster > numBitsInEnergyGroupIdsForAtomsInJCluster) { - gmx_fatal(FARGS, "The Verlet scheme with %dx%d kernels and free-energy only supports up to %zu energy groups", + gmx_fatal(FARGS, + "The Verlet scheme with %dx%d kernels and free-energy only supports up to %zu " + "energy groups", iGrid.geometry().numAtomsICluster, numAtomsJCluster, - (sizeof(gid_cj)*8)/numAtomsJCluster); + (sizeof(gid_cj) * 8) / numAtomsJCluster); } egp_shift = nbatParams.neg_2log; @@ -1555,31 +1548,31 @@ static void make_fep_list(gmx::ArrayRef atomIndices, bFEP_i_all = TRUE; for (int i = 0; i < nbl->na_ci; i++) { - ind_i = ci*nbl->na_ci + i; + ind_i = ci * nbl->na_ci + i; ai = atomIndices[ind_i]; if (ai >= 0) { - nri = nlist->nri; - nlist->jindex[nri+1] = nlist->jindex[nri]; - nlist->iinr[nri] = ai; + nri = nlist->nri; + nlist->jindex[nri + 1] = nlist->jindex[nri]; + nlist->iinr[nri] = ai; /* The actual energy group pair index is set later */ - nlist->gid[nri] = 0; - nlist->shift[nri] = nbl_ci->shift & NBNXN_CI_SHIFT; + nlist->gid[nri] = 0; + nlist->shift[nri] = nbl_ci->shift & NBNXN_CI_SHIFT; bFEP_i = iGrid.atomIsPerturbed(ci - iGrid.cellOffset(), i); bFEP_i_all = bFEP_i_all && bFEP_i; - if (nlist->nrj + (cj_ind_end - cj_ind_start)*nbl->na_cj > nlist->maxnrj) + if (nlist->nrj + (cj_ind_end - cj_ind_start) * nbl->na_cj > nlist->maxnrj) { - nlist->maxnrj = over_alloc_small(nlist->nrj + (cj_ind_end - cj_ind_start)*nbl->na_cj); - srenew(nlist->jjnr, nlist->maxnrj); + nlist->maxnrj = over_alloc_small(nlist->nrj + (cj_ind_end - cj_ind_start) * nbl->na_cj); + srenew(nlist->jjnr, nlist->maxnrj); srenew(nlist->excl_fep, nlist->maxnrj); } if (ngid > 1) { - gid_i = (nbatParams.energrp[ci] >> (egp_shift*i)) & egp_mask; + gid_i = (nbatParams.energrp[ci] >> (egp_shift * i)) & egp_mask; } for (int cj_ind = cj_ind_start; cj_ind < cj_ind_end; cj_ind++) @@ -1597,24 +1590,29 @@ static void make_fep_list(gmx::ArrayRef atomIndices, gid_cj = nbatParams.energrp[cja]; } } - else if (2*numAtomsJCluster == jGrid.geometry().numAtomsICluster) + else if (2 * numAtomsJCluster == jGrid.geometry().numAtomsICluster) { - cjr = cja - jGrid.cellOffset()*2; + cjr = cja - jGrid.cellOffset() * 2; /* Extract half of the ci fep/energrp mask */ - fep_cj = (jGrid.fepBits(cjr >> 1) >> ((cjr & 1)*numAtomsJCluster)) & ((1 << numAtomsJCluster) - 1); + fep_cj = (jGrid.fepBits(cjr >> 1) >> ((cjr & 1) * numAtomsJCluster)) + & ((1 << numAtomsJCluster) - 1); if (ngid > 1) { - gid_cj = nbatParams.energrp[cja >> 1] >> ((cja & 1)*numAtomsJCluster*egp_shift) & ((1 << (numAtomsJCluster*egp_shift)) - 1); + gid_cj = nbatParams.energrp[cja >> 1] >> ((cja & 1) * numAtomsJCluster * egp_shift) + & ((1 << (numAtomsJCluster * egp_shift)) - 1); } } else { - cjr = cja - (jGrid.cellOffset() >> 1); + cjr = cja - (jGrid.cellOffset() >> 1); /* Combine two ci fep masks/energrp */ - fep_cj = jGrid.fepBits(cjr*2) + (jGrid.fepBits(cjr*2 + 1) << jGrid.geometry().numAtomsICluster); + fep_cj = jGrid.fepBits(cjr * 2) + + (jGrid.fepBits(cjr * 2 + 1) << jGrid.geometry().numAtomsICluster); if (ngid > 1) { - gid_cj = nbatParams.energrp[cja*2] + (nbatParams.energrp[cja*2+1] << (jGrid.geometry().numAtomsICluster*egp_shift)); + gid_cj = nbatParams.energrp[cja * 2] + + (nbatParams.energrp[cja * 2 + 1] + << (jGrid.geometry().numAtomsICluster * egp_shift)); } } @@ -1623,19 +1621,16 @@ static void make_fep_list(gmx::ArrayRef atomIndices, for (int j = 0; j < nbl->na_cj; j++) { /* Is this interaction perturbed and not excluded? */ - ind_j = cja*nbl->na_cj + j; + ind_j = cja * nbl->na_cj + j; aj = atomIndices[ind_j]; - if (aj >= 0 && - (bFEP_i || (fep_cj & (1 << j))) && - (!bDiagRemoved || ind_j >= ind_i)) + if (aj >= 0 && (bFEP_i || (fep_cj & (1 << j))) && (!bDiagRemoved || ind_j >= ind_i)) { if (ngid > 1) { - gid_j = (gid_cj >> (j*egp_shift)) & egp_mask; + gid_j = (gid_cj >> (j * egp_shift)) & egp_mask; gid = GID(gid_i, gid_j, ngid); - if (nlist->nrj > nlist->jindex[nri] && - nlist->gid[nri] != gid) + if (nlist->nrj > nlist->jindex[nri] && nlist->gid[nri] != gid) { /* Energy group pair changed: new list */ fep_list_new_nri_copy(nlist); @@ -1651,8 +1646,9 @@ static void make_fep_list(gmx::ArrayRef atomIndices, } /* Add it to the FEP list */ - nlist->jjnr[nlist->nrj] = aj; - nlist->excl_fep[nlist->nrj] = (nbl->cj[cj_ind].excl >> (i*nbl->na_cj + j)) & 1; + nlist->jjnr[nlist->nrj] = aj; + nlist->excl_fep[nlist->nrj] = + (nbl->cj[cj_ind].excl >> (i * nbl->na_cj + j)) & 1; nlist->nrj++; /* Exclude it from the normal list. @@ -1660,7 +1656,7 @@ static void make_fep_list(gmx::ArrayRef atomIndices, * but we need to avoid 0/0, as perturbed atoms * can be on top of each other. */ - nbl->cj[cj_ind].excl &= ~(1U << (i*nbl->na_cj + j)); + nbl->cj[cj_ind].excl &= ~(1U << (i * nbl->na_cj + j)); } } } @@ -1679,7 +1675,7 @@ static void make_fep_list(gmx::ArrayRef atomIndices, { /* All interactions are perturbed, we can skip this entry */ nbl_ci->cj_ind_end = cj_ind_start; - nbl->ncjInUse -= cj_ind_end - cj_ind_start; + nbl->ncjInUse -= cj_ind_end - cj_ind_start; } } @@ -1692,28 +1688,28 @@ static inline int cj_mod_cj4(int cj) /* Convert a j-cluster to a cj4 group */ static inline int cj_to_cj4(int cj) { - return cj/c_nbnxnGpuJgroupSize; + return cj / c_nbnxnGpuJgroupSize; } /* Return the index of an j-atom within a warp */ static inline int a_mod_wj(int a) { - return a & (c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit - 1); + return a & (c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit - 1); } /* As make_fep_list above, but for super/sub lists. */ -static void make_fep_list(gmx::ArrayRef atomIndices, - const nbnxn_atomdata_t *nbat, - NbnxnPairlistGpu *nbl, - gmx_bool bDiagRemoved, - const nbnxn_sci_t *nbl_sci, - real shx, - real shy, - real shz, - real rlist_fep2, - const Grid &iGrid, - const Grid &jGrid, - t_nblist *nlist) +static void make_fep_list(gmx::ArrayRef atomIndices, + const nbnxn_atomdata_t* nbat, + NbnxnPairlistGpu* nbl, + gmx_bool bDiagRemoved, + const nbnxn_sci_t* nbl_sci, + real shx, + real shy, + real shz, + real rlist_fep2, + const Grid& iGrid, + const Grid& jGrid, + t_nblist* nlist) { int nri_max; int c_abs; @@ -1721,16 +1717,16 @@ static void make_fep_list(gmx::ArrayRef atomIndices, int nri; gmx_bool bFEP_i; real xi, yi, zi; - const nbnxn_cj4_t *cj4; + const nbnxn_cj4_t* cj4; - const int numJClusterGroups = nbl_sci->numJClusterGroups(); + const int numJClusterGroups = nbl_sci->numJClusterGroups(); if (numJClusterGroups == 0) { /* Empty list */ return; } - const int sci = nbl_sci->sci; + const int sci = nbl_sci->sci; const int cj4_ind_start = nbl_sci->cj4_ind_start; const int cj4_ind_end = nbl_sci->cj4_ind_end; @@ -1742,7 +1738,7 @@ static void make_fep_list(gmx::ArrayRef atomIndices, * So for each of the na_sc i-atoms, we need max one FEP list * for each max_nrj_fep j-atoms. */ - nri_max = nbl->na_sc*nbl->na_cj*(1 + (numJClusterGroups*c_nbnxnGpuJgroupSize)/max_nrj_fep); + nri_max = nbl->na_sc * nbl->na_cj * (1 + (numJClusterGroups * c_nbnxnGpuJgroupSize) / max_nrj_fep); if (nlist->nri + nri_max > nlist->maxnri) { nlist->maxnri = over_alloc_large(nlist->nri + nri_max); @@ -1752,32 +1748,32 @@ static void make_fep_list(gmx::ArrayRef atomIndices, /* Loop over the atoms in the i super-cluster */ for (int c = 0; c < c_gpuNumClusterPerCell; c++) { - c_abs = sci*c_gpuNumClusterPerCell + c; + c_abs = sci * c_gpuNumClusterPerCell + c; for (int i = 0; i < nbl->na_ci; i++) { - ind_i = c_abs*nbl->na_ci + i; + ind_i = c_abs * nbl->na_ci + i; ai = atomIndices[ind_i]; if (ai >= 0) { - nri = nlist->nri; - nlist->jindex[nri+1] = nlist->jindex[nri]; - nlist->iinr[nri] = ai; + nri = nlist->nri; + nlist->jindex[nri + 1] = nlist->jindex[nri]; + nlist->iinr[nri] = ai; /* With GPUs, energy groups are not supported */ - nlist->gid[nri] = 0; - nlist->shift[nri] = nbl_sci->shift & NBNXN_CI_SHIFT; + nlist->gid[nri] = 0; + nlist->shift[nri] = nbl_sci->shift & NBNXN_CI_SHIFT; - bFEP_i = iGrid.atomIsPerturbed(c_abs - iGrid.cellOffset()*c_gpuNumClusterPerCell, i); + bFEP_i = iGrid.atomIsPerturbed(c_abs - iGrid.cellOffset() * c_gpuNumClusterPerCell, i); - xi = nbat->x()[ind_i*nbat->xstride+XX] + shx; - yi = nbat->x()[ind_i*nbat->xstride+YY] + shy; - zi = nbat->x()[ind_i*nbat->xstride+ZZ] + shz; + xi = nbat->x()[ind_i * nbat->xstride + XX] + shx; + yi = nbat->x()[ind_i * nbat->xstride + YY] + shy; + zi = nbat->x()[ind_i * nbat->xstride + ZZ] + shz; - const int nrjMax = nlist->nrj + numJClusterGroups*c_nbnxnGpuJgroupSize*nbl->na_cj; + const int nrjMax = nlist->nrj + numJClusterGroups * c_nbnxnGpuJgroupSize * nbl->na_cj; if (nrjMax > nlist->maxnrj) { nlist->maxnrj = over_alloc_small(nrjMax); - srenew(nlist->jjnr, nlist->maxnrj); + srenew(nlist->jjnr, nlist->maxnrj); srenew(nlist->excl_fep, nlist->maxnrj); } @@ -1787,40 +1783,38 @@ static void make_fep_list(gmx::ArrayRef atomIndices, for (int gcj = 0; gcj < c_nbnxnGpuJgroupSize; gcj++) { - if ((cj4->imei[0].imask & (1U << (gcj*c_gpuNumClusterPerCell + c))) == 0) + if ((cj4->imei[0].imask & (1U << (gcj * c_gpuNumClusterPerCell + c))) == 0) { /* Skip this ci for this cj */ continue; } - const int cjr = - cj4->cj[gcj] - jGrid.cellOffset()*c_gpuNumClusterPerCell; + const int cjr = cj4->cj[gcj] - jGrid.cellOffset() * c_gpuNumClusterPerCell; if (bFEP_i || jGrid.clusterIsPerturbed(cjr)) { for (int j = 0; j < nbl->na_cj; j++) { /* Is this interaction perturbed and not excluded? */ - ind_j = (jGrid.cellOffset()*c_gpuNumClusterPerCell + cjr)*nbl->na_cj + j; - aj = atomIndices[ind_j]; - if (aj >= 0 && - (bFEP_i || jGrid.atomIsPerturbed(cjr, j)) && - (!bDiagRemoved || ind_j >= ind_i)) + ind_j = (jGrid.cellOffset() * c_gpuNumClusterPerCell + cjr) * nbl->na_cj + j; + aj = atomIndices[ind_j]; + if (aj >= 0 && (bFEP_i || jGrid.atomIsPerturbed(cjr, j)) + && (!bDiagRemoved || ind_j >= ind_i)) { - int excl_pair; - unsigned int excl_bit; - real dx, dy, dz; + int excl_pair; + unsigned int excl_bit; + real dx, dy, dz; - const int jHalf = j/(c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit); - nbnxn_excl_t &excl = - get_exclusion_mask(nbl, cj4_ind, jHalf); + const int jHalf = + j / (c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit); + nbnxn_excl_t& excl = get_exclusion_mask(nbl, cj4_ind, jHalf); - excl_pair = a_mod_wj(j)*nbl->na_ci + i; - excl_bit = (1U << (gcj*c_gpuNumClusterPerCell + c)); + excl_pair = a_mod_wj(j) * nbl->na_ci + i; + excl_bit = (1U << (gcj * c_gpuNumClusterPerCell + c)); - dx = nbat->x()[ind_j*nbat->xstride+XX] - xi; - dy = nbat->x()[ind_j*nbat->xstride+YY] - yi; - dz = nbat->x()[ind_j*nbat->xstride+ZZ] - zi; + dx = nbat->x()[ind_j * nbat->xstride + XX] - xi; + dy = nbat->x()[ind_j * nbat->xstride + YY] - yi; + dz = nbat->x()[ind_j * nbat->xstride + ZZ] - zi; /* The unpruned GPU list has more than 2/3 * of the atom pairs beyond rlist. Using @@ -1829,7 +1823,7 @@ static void make_fep_list(gmx::ArrayRef atomIndices, * relative to the fast GPU kernels. * So we prune the FEP list here. */ - if (dx*dx + dy*dy + dz*dz < rlist_fep2) + if (dx * dx + dy * dy + dz * dz < rlist_fep2) { if (nlist->nrj - nlist->jindex[nri] >= max_nrj_fep) { @@ -1838,8 +1832,9 @@ static void make_fep_list(gmx::ArrayRef atomIndices, } /* Add it to the FEP list */ - nlist->jjnr[nlist->nrj] = aj; - nlist->excl_fep[nlist->nrj] = (excl.pair[excl_pair] & excl_bit) ? 1 : 0; + nlist->jjnr[nlist->nrj] = aj; + nlist->excl_fep[nlist->nrj] = + (excl.pair[excl_pair] & excl_bit) ? 1 : 0; nlist->nrj++; } @@ -1878,13 +1873,12 @@ static void make_fep_list(gmx::ArrayRef atomIndices, * Sets all atom-pair exclusions from the topology stored in exclusions * as masks in the pair-list for i-super-cluster list entry iEntry. */ -static void -setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, - NbnxnPairlistGpu *nbl, - gmx_bool diagRemoved, - int gmx_unused na_cj_2log, - const nbnxn_sci_t &iEntry, - const t_blocka &exclusions) +static void setExclusionsForIEntry(const Nbnxm::GridSet& gridSet, + NbnxnPairlistGpu* nbl, + gmx_bool diagRemoved, + int gmx_unused na_cj_2log, + const nbnxn_sci_t& iEntry, + const t_blocka& exclusions) { if (iEntry.numJClusterGroups() == 0) { @@ -1896,30 +1890,30 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, * Note that here we can not use cj4_ind_end, since the last cj4 * can be only partially filled, so we use cj_ind. */ - const JListRanges ranges(iEntry.cj4_ind_start*c_nbnxnGpuJgroupSize, - nbl->work->cj_ind, + const JListRanges ranges(iEntry.cj4_ind_start * c_nbnxnGpuJgroupSize, nbl->work->cj_ind, gmx::makeConstArrayRef(nbl->cj4)); GMX_ASSERT(nbl->na_ci == c_nbnxnGpuClusterSize, "na_ci should match the GPU cluster size"); - constexpr int c_clusterSize = c_nbnxnGpuClusterSize; - constexpr int c_superClusterSize = c_nbnxnGpuNumClusterPerSupercluster*c_nbnxnGpuClusterSize; + constexpr int c_clusterSize = c_nbnxnGpuClusterSize; + constexpr int c_superClusterSize = c_nbnxnGpuNumClusterPerSupercluster * c_nbnxnGpuClusterSize; - const int iSuperCluster = iEntry.sci; + const int iSuperCluster = iEntry.sci; - gmx::ArrayRef atomIndices = gridSet.atomIndices(); - gmx::ArrayRef cell = gridSet.cells(); + gmx::ArrayRef atomIndices = gridSet.atomIndices(); + gmx::ArrayRef cell = gridSet.cells(); /* Loop over the atoms in the i super-cluster */ for (int i = 0; i < c_superClusterSize; i++) { - const int iIndex = iSuperCluster*c_superClusterSize + i; + const int iIndex = iSuperCluster * c_superClusterSize + i; const int iAtom = atomIndices[iIndex]; if (iAtom >= 0) { - const int iCluster = i/c_clusterSize; + const int iCluster = i / c_clusterSize; /* Loop over the topology-based exclusions for this i-atom */ - for (int exclIndex = exclusions.index[iAtom]; exclIndex < exclusions.index[iAtom + 1]; exclIndex++) + for (int exclIndex = exclusions.index[iAtom]; exclIndex < exclusions.index[iAtom + 1]; + exclIndex++) { const int jAtom = exclusions.a[exclIndex]; @@ -1941,39 +1935,39 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, * Either of these changes triggers peeling of the exclIndex * loop, which apparently leads to far less efficient code. */ - if (diagRemoved && jIndex <= iSuperCluster*nbl->na_sc + i) + if (diagRemoved && jIndex <= iSuperCluster * nbl->na_sc + i) { continue; } - const int jCluster = jIndex/c_clusterSize; + const int jCluster = jIndex / c_clusterSize; /* Check whether the cluster is in our list? */ if (jCluster >= ranges.cjFirst && jCluster <= ranges.cjLast) { const int index = - findJClusterInJList(jCluster, ranges, - gmx::makeConstArrayRef(nbl->cj4)); + findJClusterInJList(jCluster, ranges, gmx::makeConstArrayRef(nbl->cj4)); if (index >= 0) { /* We found an exclusion, clear the corresponding * interaction bit. */ - const unsigned int pairMask = (1U << (cj_mod_cj4(index)*c_gpuNumClusterPerCell + iCluster)); + const unsigned int pairMask = + (1U << (cj_mod_cj4(index) * c_gpuNumClusterPerCell + iCluster)); /* Check if the i-cluster interacts with the j-cluster */ if (nbl_imask0(nbl, index) & pairMask) { - const int innerI = (i & (c_clusterSize - 1)); + const int innerI = (i & (c_clusterSize - 1)); const int innerJ = (jIndex & (c_clusterSize - 1)); /* Determine which j-half (CUDA warp) we are in */ - const int jHalf = innerJ/(c_clusterSize/c_nbnxnGpuClusterpairSplit); + const int jHalf = innerJ / (c_clusterSize / c_nbnxnGpuClusterpairSplit); - nbnxn_excl_t &interactionMask = - get_exclusion_mask(nbl, cj_to_cj4(index), jHalf); + nbnxn_excl_t& interactionMask = + get_exclusion_mask(nbl, cj_to_cj4(index), jHalf); - interactionMask.pair[a_mod_wj(innerJ)*c_clusterSize + innerI] &= ~pairMask; + interactionMask.pair[a_mod_wj(innerJ) * c_clusterSize + innerI] &= ~pairMask; } } } @@ -1983,20 +1977,20 @@ setExclusionsForIEntry(const Nbnxm::GridSet &gridSet, } /* Make a new ci entry at the back of nbl->ci */ -static void addNewIEntry(NbnxnPairlistCpu *nbl, int ci, int shift, int flags) +static void addNewIEntry(NbnxnPairlistCpu* nbl, int ci, int shift, int flags) { nbnxn_ci_t ciEntry; - ciEntry.ci = ci; - ciEntry.shift = shift; + ciEntry.ci = ci; + ciEntry.shift = shift; /* Store the interaction flags along with the shift */ - ciEntry.shift |= flags; - ciEntry.cj_ind_start = nbl->cj.size(); - ciEntry.cj_ind_end = nbl->cj.size(); + ciEntry.shift |= flags; + ciEntry.cj_ind_start = nbl->cj.size(); + ciEntry.cj_ind_end = nbl->cj.size(); nbl->ci.push_back(ciEntry); } /* Make a new sci entry at index nbl->nsci */ -static void addNewIEntry(NbnxnPairlistGpu *nbl, int sci, int shift, int gmx_unused flags) +static void addNewIEntry(NbnxnPairlistGpu* nbl, int sci, int shift, int gmx_unused flags) { nbnxn_sci_t sciEntry; sciEntry.sci = sci; @@ -2010,8 +2004,7 @@ static void addNewIEntry(NbnxnPairlistGpu *nbl, int sci, int shift, int gmx_unus /* Sort the simple j-list cj on exclusions. * Entries with exclusions will all be sorted to the beginning of the list. */ -static void sort_cj_excl(nbnxn_cj_t *cj, int ncj, - NbnxnPairlistCpuWork *work) +static void sort_cj_excl(nbnxn_cj_t* cj, int ncj, NbnxnPairlistCpuWork* work) { work->cj.resize(ncj); @@ -2025,8 +2018,7 @@ static void sort_cj_excl(nbnxn_cj_t *cj, int ncj, } } /* Check if there are exclusions at all or not just the first entry */ - if (!((jnew == 0) || - (jnew == 1 && cj[0].excl != NBNXN_INTERACTION_MASK_ALL))) + if (!((jnew == 0) || (jnew == 1 && cj[0].excl != NBNXN_INTERACTION_MASK_ALL))) { for (int j = 0; j < ncj; j++) { @@ -2043,14 +2035,14 @@ static void sort_cj_excl(nbnxn_cj_t *cj, int ncj, } /* Close this simple list i entry */ -static void closeIEntry(NbnxnPairlistCpu *nbl, - int gmx_unused sp_max_av, - gmx_bool gmx_unused progBal, - float gmx_unused nsp_tot_est, - int gmx_unused thread, - int gmx_unused nthread) +static void closeIEntry(NbnxnPairlistCpu* nbl, + int gmx_unused sp_max_av, + gmx_bool gmx_unused progBal, + float gmx_unused nsp_tot_est, + int gmx_unused thread, + int gmx_unused nthread) { - nbnxn_ci_t &ciEntry = nbl->ci.back(); + nbnxn_ci_t& ciEntry = nbl->ci.back(); /* All content of the new ci entry have already been filled correctly, * we only need to sort and increase counts or remove the entry when empty. @@ -2067,8 +2059,7 @@ static void closeIEntry(NbnxnPairlistCpu *nbl, { nbl->work->ncj_noq += jlen; } - else if ((ciEntry.shift & NBNXN_CI_HALF_LJ(0)) || - !(ciEntry.shift & NBNXN_CI_DO_LJ(0))) + else if ((ciEntry.shift & NBNXN_CI_HALF_LJ(0)) || !(ciEntry.shift & NBNXN_CI_DO_LJ(0))) { nbl->work->ncj_hlj += jlen; } @@ -2088,10 +2079,12 @@ static void closeIEntry(NbnxnPairlistCpu *nbl, * As the lists get concatenated later, this estimate depends * both on nthread and our own thread index. */ -static void split_sci_entry(NbnxnPairlistGpu *nbl, - int nsp_target_av, - gmx_bool progBal, float nsp_tot_est, - int thread, int nthread) +static void split_sci_entry(NbnxnPairlistGpu* nbl, + int nsp_target_av, + gmx_bool progBal, + float nsp_tot_est, + int thread, + int nthread) { int nsp_max; @@ -2102,7 +2095,7 @@ static void split_sci_entry(NbnxnPairlistGpu *nbl, /* Estimate the total numbers of ci's of the nblist combined * over all threads using the target number of ci's. */ - nsp_est = (nsp_tot_est*thread)/nthread + nbl->nci_tot; + nsp_est = (nsp_tot_est * thread) / nthread + nbl->nci_tot; /* The first ci blocks should be larger, to avoid overhead. * The last ci blocks should be smaller, to improve load balancing. @@ -2110,7 +2103,7 @@ static void split_sci_entry(NbnxnPairlistGpu *nbl, * and ensures that the total number of blocks end up equal to * that of equally sized blocks of size nsp_target_av. */ - nsp_max = static_cast(nsp_target_av*(nsp_tot_est*1.5/(nsp_est + nsp_tot_est))); + nsp_max = static_cast(nsp_target_av * (nsp_tot_est * 1.5 / (nsp_est + nsp_tot_est))); } else { @@ -2121,20 +2114,20 @@ static void split_sci_entry(NbnxnPairlistGpu *nbl, const int cj4_end = nbl->sci.back().cj4_ind_end; const int j4len = cj4_end - cj4_start; - if (j4len > 1 && j4len*c_gpuNumClusterPerCell*c_nbnxnGpuJgroupSize > nsp_max) + if (j4len > 1 && j4len * c_gpuNumClusterPerCell * c_nbnxnGpuJgroupSize > nsp_max) { /* Modify the last ci entry and process the cj4's again */ - int nsp = 0; - int nsp_sci = 0; - int nsp_cj4_e = 0; - int nsp_cj4 = 0; + int nsp = 0; + int nsp_sci = 0; + int nsp_cj4_e = 0; + int nsp_cj4 = 0; for (int cj4 = cj4_start; cj4 < cj4_end; cj4++) { int nsp_cj4_p = nsp_cj4; /* Count the number of cluster pairs in this cj4 group */ - nsp_cj4 = 0; - for (int p = 0; p < c_gpuNumClusterPerCell*c_nbnxnGpuJgroupSize; p++) + nsp_cj4 = 0; + for (int p = 0; p < c_gpuNumClusterPerCell * c_nbnxnGpuJgroupSize; p++) { nsp_cj4 += (nbl->cj4[cj4].imei[0].imask >> p) & 1; } @@ -2153,9 +2146,9 @@ static void split_sci_entry(NbnxnPairlistGpu *nbl, sciNew.cj4_ind_start = cj4; nbl->sci.push_back(sciNew); - nsp_sci = nsp; - nsp_cj4_e = nsp_cj4_p; - nsp = 0; + nsp_sci = nsp; + nsp_cj4_e = nsp_cj4_p; + nsp = 0; } nsp += nsp_cj4; } @@ -2176,12 +2169,9 @@ static void split_sci_entry(NbnxnPairlistGpu *nbl, } /* Clost this super/sub list i entry */ -static void closeIEntry(NbnxnPairlistGpu *nbl, - int nsp_max_av, - gmx_bool progBal, float nsp_tot_est, - int thread, int nthread) +static void closeIEntry(NbnxnPairlistGpu* nbl, int nsp_max_av, gmx_bool progBal, float nsp_tot_est, int thread, int nthread) { - nbnxn_sci_t &sciEntry = *getOpenIEntry(nbl); + nbnxn_sci_t& sciEntry = *getOpenIEntry(nbl); /* All content of the new ci entry have already been filled correctly, * we only need to, potentially, split or remove the entry when empty. @@ -2192,14 +2182,13 @@ static void closeIEntry(NbnxnPairlistGpu *nbl, /* We can only have complete blocks of 4 j-entries in a list, * so round the count up before closing. */ - int ncj4 = (nbl->work->cj_ind + c_nbnxnGpuJgroupSize - 1)/c_nbnxnGpuJgroupSize; - nbl->work->cj_ind = ncj4*c_nbnxnGpuJgroupSize; + int ncj4 = (nbl->work->cj_ind + c_nbnxnGpuJgroupSize - 1) / c_nbnxnGpuJgroupSize; + nbl->work->cj_ind = ncj4 * c_nbnxnGpuJgroupSize; if (nsp_max_av > 0) { /* Measure the size of the new entry and potentially split it */ - split_sci_entry(nbl, nsp_max_av, progBal, nsp_tot_est, - thread, nthread); + split_sci_entry(nbl, nsp_max_av, progBal, nsp_tot_est, thread, nthread); } } else @@ -2210,23 +2199,21 @@ static void closeIEntry(NbnxnPairlistGpu *nbl, } /* Syncs the working array before adding another grid pair to the GPU list */ -static void sync_work(NbnxnPairlistCpu gmx_unused *nbl) -{ -} +static void sync_work(NbnxnPairlistCpu gmx_unused* nbl) {} /* Syncs the working array before adding another grid pair to the GPU list */ -static void sync_work(NbnxnPairlistGpu *nbl) +static void sync_work(NbnxnPairlistGpu* nbl) { - nbl->work->cj_ind = nbl->cj4.size()*c_nbnxnGpuJgroupSize; + nbl->work->cj_ind = nbl->cj4.size() * c_nbnxnGpuJgroupSize; } /* Clears an NbnxnPairlistCpu data structure */ -static void clear_pairlist(NbnxnPairlistCpu *nbl) +static void clear_pairlist(NbnxnPairlistCpu* nbl) { nbl->ci.clear(); nbl->cj.clear(); - nbl->ncjInUse = 0; - nbl->nci_tot = 0; + nbl->ncjInUse = 0; + nbl->nci_tot = 0; nbl->ciOuter.clear(); nbl->cjOuter.clear(); @@ -2235,7 +2222,7 @@ static void clear_pairlist(NbnxnPairlistCpu *nbl) } /* Clears an NbnxnPairlistGpu data structure */ -static void clear_pairlist(NbnxnPairlistGpu *nbl) +static void clear_pairlist(NbnxnPairlistGpu* nbl) { nbl->sci.clear(); nbl->cj4.clear(); @@ -2244,7 +2231,7 @@ static void clear_pairlist(NbnxnPairlistGpu *nbl) } /* Clears an atom-atom-style pair list */ -static void clear_pairlist_fep(t_nblist *nl) +static void clear_pairlist_fep(t_nblist* nl) { nl->nri = 0; nl->nrj = 0; @@ -2256,10 +2243,8 @@ static void clear_pairlist_fep(t_nblist *nl) } /* Sets a simple list i-cell bounding box, including PBC shift */ -static inline void set_icell_bb_simple(gmx::ArrayRef bb, - int ci, - real shx, real shy, real shz, - BoundingBox *bb_ci) +static inline void +set_icell_bb_simple(gmx::ArrayRef bb, int ci, real shx, real shy, real shz, BoundingBox* bb_ci) { bb_ci->lower.x = bb[ci].lower.x + shx; bb_ci->lower.y = bb[ci].lower.y + shy; @@ -2270,35 +2255,28 @@ static inline void set_icell_bb_simple(gmx::ArrayRef bb, } /* Sets a simple list i-cell bounding box, including PBC shift */ -static inline void set_icell_bb(const Grid &iGrid, - int ci, - real shx, real shy, real shz, - NbnxnPairlistCpuWork *work) +static inline void set_icell_bb(const Grid& iGrid, int ci, real shx, real shy, real shz, NbnxnPairlistCpuWork* work) { - set_icell_bb_simple(iGrid.iBoundingBoxes(), ci, shx, shy, shz, - &work->iClusterData.bb[0]); + set_icell_bb_simple(iGrid.iBoundingBoxes(), ci, shx, shy, shz, &work->iClusterData.bb[0]); } #if NBNXN_BBXXXX /* Sets a super-cell and sub cell bounding boxes, including PBC shift */ -static void set_icell_bbxxxx_supersub(gmx::ArrayRef bb, - int ci, - real shx, real shy, real shz, - float *bb_ci) +static void set_icell_bbxxxx_supersub(gmx::ArrayRef bb, int ci, real shx, real shy, real shz, float* bb_ci) { constexpr int cellBBStride = packedBoundingBoxesIndex(c_gpuNumClusterPerCell); constexpr int pbbStride = c_packedBoundingBoxesDimSize; - const int ia = ci*cellBBStride; + const int ia = ci * cellBBStride; for (int m = 0; m < cellBBStride; m += c_packedBoundingBoxesSize) { for (int i = 0; i < pbbStride; i++) { - bb_ci[m + 0*pbbStride + i] = bb[ia + m + 0*pbbStride + i] + shx; - bb_ci[m + 1*pbbStride + i] = bb[ia + m + 1*pbbStride + i] + shy; - bb_ci[m + 2*pbbStride + i] = bb[ia + m + 2*pbbStride + i] + shz; - bb_ci[m + 3*pbbStride + i] = bb[ia + m + 3*pbbStride + i] + shx; - bb_ci[m + 4*pbbStride + i] = bb[ia + m + 4*pbbStride + i] + shy; - bb_ci[m + 5*pbbStride + i] = bb[ia + m + 5*pbbStride + i] + shz; + bb_ci[m + 0 * pbbStride + i] = bb[ia + m + 0 * pbbStride + i] + shx; + bb_ci[m + 1 * pbbStride + i] = bb[ia + m + 1 * pbbStride + i] + shy; + bb_ci[m + 2 * pbbStride + i] = bb[ia + m + 2 * pbbStride + i] + shz; + bb_ci[m + 3 * pbbStride + i] = bb[ia + m + 3 * pbbStride + i] + shx; + bb_ci[m + 4 * pbbStride + i] = bb[ia + m + 4 * pbbStride + i] + shy; + bb_ci[m + 5 * pbbStride + i] = bb[ia + m + 5 * pbbStride + i] + shz; } } } @@ -2306,112 +2284,115 @@ static void set_icell_bbxxxx_supersub(gmx::ArrayRef bb, /* Sets a super-cell and sub cell bounding boxes, including PBC shift */ gmx_unused static void set_icell_bb_supersub(gmx::ArrayRef bb, - int ci, - real shx, real shy, real shz, - BoundingBox *bb_ci) + int ci, + real shx, + real shy, + real shz, + BoundingBox* bb_ci) { for (int i = 0; i < c_gpuNumClusterPerCell; i++) { - set_icell_bb_simple(bb, ci*c_gpuNumClusterPerCell+i, - shx, shy, shz, - &bb_ci[i]); + set_icell_bb_simple(bb, ci * c_gpuNumClusterPerCell + i, shx, shy, shz, &bb_ci[i]); } } /* Sets a super-cell and sub cell bounding boxes, including PBC shift */ -gmx_unused static void set_icell_bb(const Grid &iGrid, - int ci, - real shx, real shy, real shz, - NbnxnPairlistGpuWork *work) +gmx_unused static void set_icell_bb(const Grid& iGrid, int ci, real shx, real shy, real shz, NbnxnPairlistGpuWork* work) { #if NBNXN_BBXXXX set_icell_bbxxxx_supersub(iGrid.packedBoundingBoxes(), ci, shx, shy, shz, work->iSuperClusterData.bbPacked.data()); #else - set_icell_bb_supersub(iGrid.iBoundingBoxes(), ci, shx, shy, shz, - work->iSuperClusterData.bb.data()); + set_icell_bb_supersub(iGrid.iBoundingBoxes(), ci, shx, shy, shz, work->iSuperClusterData.bb.data()); #endif } /* Copies PBC shifted i-cell atom coordinates x,y,z to working array */ -static void icell_set_x_simple(int ci, - real shx, real shy, real shz, - int stride, const real *x, - NbnxnPairlistCpuWork::IClusterData *iClusterData) +static void icell_set_x_simple(int ci, + real shx, + real shy, + real shz, + int stride, + const real* x, + NbnxnPairlistCpuWork::IClusterData* iClusterData) { - const int ia = ci*c_nbnxnCpuIClusterSize; + const int ia = ci * c_nbnxnCpuIClusterSize; for (int i = 0; i < c_nbnxnCpuIClusterSize; i++) { - iClusterData->x[i*STRIDE_XYZ+XX] = x[(ia+i)*stride+XX] + shx; - iClusterData->x[i*STRIDE_XYZ+YY] = x[(ia+i)*stride+YY] + shy; - iClusterData->x[i*STRIDE_XYZ+ZZ] = x[(ia+i)*stride+ZZ] + shz; + iClusterData->x[i * STRIDE_XYZ + XX] = x[(ia + i) * stride + XX] + shx; + iClusterData->x[i * STRIDE_XYZ + YY] = x[(ia + i) * stride + YY] + shy; + iClusterData->x[i * STRIDE_XYZ + ZZ] = x[(ia + i) * stride + ZZ] + shz; } } -static void icell_set_x(int ci, - real shx, real shy, real shz, - int stride, const real *x, +static void icell_set_x(int ci, + real shx, + real shy, + real shz, + int stride, + const real* x, const ClusterDistanceKernelType kernelType, - NbnxnPairlistCpuWork *work) + NbnxnPairlistCpuWork* work) { switch (kernelType) { #if GMX_SIMD -#ifdef GMX_NBNXN_SIMD_4XN +# ifdef GMX_NBNXN_SIMD_4XN case ClusterDistanceKernelType::CpuSimd_4xM: icell_set_x_simd_4xn(ci, shx, shy, shz, stride, x, work); break; -#endif -#ifdef GMX_NBNXN_SIMD_2XNN +# endif +# ifdef GMX_NBNXN_SIMD_2XNN case ClusterDistanceKernelType::CpuSimd_2xMM: icell_set_x_simd_2xnn(ci, shx, shy, shz, stride, x, work); break; -#endif +# endif #endif case ClusterDistanceKernelType::CpuPlainC: icell_set_x_simple(ci, shx, shy, shz, stride, x, &work->iClusterData); break; - default: - GMX_ASSERT(false, "Unhandled case"); - break; + default: GMX_ASSERT(false, "Unhandled case"); break; } } /* Copies PBC shifted super-cell atom coordinates x,y,z to working array */ -static void icell_set_x(int ci, - real shx, real shy, real shz, - int stride, const real *x, +static void icell_set_x(int ci, + real shx, + real shy, + real shz, + int stride, + const real* x, ClusterDistanceKernelType gmx_unused kernelType, - NbnxnPairlistGpuWork *work) + NbnxnPairlistGpuWork* work) { #if !GMX_SIMD4_HAVE_REAL - real * x_ci = work->iSuperClusterData.x.data(); + real* x_ci = work->iSuperClusterData.x.data(); - int ia = ci*c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize; - for (int i = 0; i < c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize; i++) + int ia = ci * c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize; + for (int i = 0; i < c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize; i++) { - x_ci[i*DIM + XX] = x[(ia+i)*stride + XX] + shx; - x_ci[i*DIM + YY] = x[(ia+i)*stride + YY] + shy; - x_ci[i*DIM + ZZ] = x[(ia+i)*stride + ZZ] + shz; + x_ci[i * DIM + XX] = x[(ia + i) * stride + XX] + shx; + x_ci[i * DIM + YY] = x[(ia + i) * stride + YY] + shy; + x_ci[i * DIM + ZZ] = x[(ia + i) * stride + ZZ] + shz; } #else /* !GMX_SIMD4_HAVE_REAL */ - real * x_ci = work->iSuperClusterData.xSimd.data(); + real* x_ci = work->iSuperClusterData.xSimd.data(); for (int si = 0; si < c_gpuNumClusterPerCell; si++) { for (int i = 0; i < c_nbnxnGpuClusterSize; i += GMX_SIMD4_WIDTH) { - int io = si*c_nbnxnGpuClusterSize + i; - int ia = ci*c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize + io; + int io = si * c_nbnxnGpuClusterSize + i; + int ia = ci * c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize + io; for (int j = 0; j < GMX_SIMD4_WIDTH; j++) { - x_ci[io*DIM + j + XX*GMX_SIMD4_WIDTH] = x[(ia + j)*stride + XX] + shx; - x_ci[io*DIM + j + YY*GMX_SIMD4_WIDTH] = x[(ia + j)*stride + YY] + shy; - x_ci[io*DIM + j + ZZ*GMX_SIMD4_WIDTH] = x[(ia + j)*stride + ZZ] + shz; + x_ci[io * DIM + j + XX * GMX_SIMD4_WIDTH] = x[(ia + j) * stride + XX] + shx; + x_ci[io * DIM + j + YY * GMX_SIMD4_WIDTH] = x[(ia + j) * stride + YY] + shy; + x_ci[io * DIM + j + ZZ * GMX_SIMD4_WIDTH] = x[(ia + j) * stride + ZZ] + shz; } } } @@ -2419,9 +2400,9 @@ static void icell_set_x(int ci, #endif /* !GMX_SIMD4_HAVE_REAL */ } -static real minimum_subgrid_size_xy(const Grid &grid) +static real minimum_subgrid_size_xy(const Grid& grid) { - const Grid::Dimensions &dims = grid.dimensions(); + const Grid::Dimensions& dims = grid.dimensions(); if (grid.geometry().isSimple) { @@ -2429,13 +2410,12 @@ static real minimum_subgrid_size_xy(const Grid &grid) } else { - return std::min(dims.cellSize[XX]/c_gpuNumClusterPerCellX, - dims.cellSize[YY]/c_gpuNumClusterPerCellY); + return std::min(dims.cellSize[XX] / c_gpuNumClusterPerCellX, + dims.cellSize[YY] / c_gpuNumClusterPerCellY); } } -static real effective_buffer_1x1_vs_MxN(const Grid &iGrid, - const Grid &jGrid) +static real effective_buffer_1x1_vs_MxN(const Grid& iGrid, const Grid& jGrid) { const real eff_1x1_buffer_fac_overest = 0.1; @@ -2456,12 +2436,11 @@ static real effective_buffer_1x1_vs_MxN(const Grid &iGrid, * Smaller tolerances or using RF lead to a smaller effective buffer, * so 10% gives a safe overestimate. */ - return eff_1x1_buffer_fac_overest*(minimum_subgrid_size_xy(iGrid) + - minimum_subgrid_size_xy(jGrid)); + return eff_1x1_buffer_fac_overest * (minimum_subgrid_size_xy(iGrid) + minimum_subgrid_size_xy(jGrid)); } /* Estimates the interaction volume^2 for non-local interactions */ -static real nonlocal_vol2(const struct gmx_domdec_zones_t *zones, const rvec ls, real r) +static real nonlocal_vol2(const struct gmx_domdec_zones_t* zones, const rvec ls, real r) { real cl, ca, za; real vold_est; @@ -2487,20 +2466,20 @@ static real nonlocal_vol2(const struct gmx_domdec_zones_t *zones, const rvec ls, { if (zones->shift[z][d] == 0) { - cl += 0.5*ls[d]; + cl += 0.5 * ls[d]; ca *= ls[d]; za *= zones->size[z].x1[d] - zones->size[z].x0[d]; } } /* 4 octants of a sphere */ - vold_est = 0.25*M_PI*r*r*r*r; + vold_est = 0.25 * M_PI * r * r * r * r; /* 4 quarter pie slices on the edges */ - vold_est += 4*cl*M_PI/6.0*r*r*r; + vold_est += 4 * cl * M_PI / 6.0 * r * r * r; /* One rectangular volume on a face */ - vold_est += ca*0.5*r*r; + vold_est += ca * 0.5 * r * r; - vol2_est_tot += vold_est*za; + vol2_est_tot += vold_est * za; } } @@ -2508,20 +2487,20 @@ static real nonlocal_vol2(const struct gmx_domdec_zones_t *zones, const rvec ls, } /* Estimates the average size of a full j-list for super/sub setup */ -static void get_nsubpair_target(const Nbnxm::GridSet &gridSet, - const InteractionLocality iloc, - const real rlist, - const int min_ci_balanced, - int *nsubpair_target, - float *nsubpair_tot_est) +static void get_nsubpair_target(const Nbnxm::GridSet& gridSet, + const InteractionLocality iloc, + const real rlist, + const int min_ci_balanced, + int* nsubpair_target, + float* nsubpair_tot_est) { /* The target value of 36 seems to be the optimum for Kepler. * Maxwell is less sensitive to the exact value. */ - const int nsubpair_target_min = 36; - real r_eff_sup, vol_est, nsp_est, nsp_est_nl; + const int nsubpair_target_min = 36; + real r_eff_sup, vol_est, nsp_est, nsp_est_nl; - const Grid &grid = gridSet.grids()[0]; + const Grid& grid = gridSet.grids()[0]; /* We don't need to balance list sizes if: * - We didn't request balancing. @@ -2540,42 +2519,40 @@ static void get_nsubpair_target(const Nbnxm::GridSet &gridSet, gmx::RVec ls; const int numAtomsCluster = grid.geometry().numAtomsICluster; - const Grid::Dimensions &dims = grid.dimensions(); + const Grid::Dimensions& dims = grid.dimensions(); - ls[XX] = dims.cellSize[XX]/c_gpuNumClusterPerCellX; - ls[YY] = dims.cellSize[YY]/c_gpuNumClusterPerCellY; - ls[ZZ] = numAtomsCluster/(dims.atomDensity*ls[XX]*ls[YY]); + ls[XX] = dims.cellSize[XX] / c_gpuNumClusterPerCellX; + ls[YY] = dims.cellSize[YY] / c_gpuNumClusterPerCellY; + ls[ZZ] = numAtomsCluster / (dims.atomDensity * ls[XX] * ls[YY]); /* The formulas below are a heuristic estimate of the average nsj per si*/ r_eff_sup = rlist + nbnxn_get_rlist_effective_inc(numAtomsCluster, ls); - if (!gridSet.domainSetup().haveMultipleDomains || - gridSet.domainSetup().zones->n == 1) + if (!gridSet.domainSetup().haveMultipleDomains || gridSet.domainSetup().zones->n == 1) { nsp_est_nl = 0; } else { - nsp_est_nl = - gmx::square(dims.atomDensity/numAtomsCluster)* - nonlocal_vol2(gridSet.domainSetup().zones, ls, r_eff_sup); + nsp_est_nl = gmx::square(dims.atomDensity / numAtomsCluster) + * nonlocal_vol2(gridSet.domainSetup().zones, ls, r_eff_sup); } if (iloc == InteractionLocality::Local) { /* Sub-cell interacts with itself */ - vol_est = ls[XX]*ls[YY]*ls[ZZ]; + vol_est = ls[XX] * ls[YY] * ls[ZZ]; /* 6/2 rectangular volume on the faces */ - vol_est += (ls[XX]*ls[YY] + ls[XX]*ls[ZZ] + ls[YY]*ls[ZZ])*r_eff_sup; + vol_est += (ls[XX] * ls[YY] + ls[XX] * ls[ZZ] + ls[YY] * ls[ZZ]) * r_eff_sup; /* 12/2 quarter pie slices on the edges */ - vol_est += 2*(ls[XX] + ls[YY] + ls[ZZ])*0.25*M_PI*gmx::square(r_eff_sup); + vol_est += 2 * (ls[XX] + ls[YY] + ls[ZZ]) * 0.25 * M_PI * gmx::square(r_eff_sup); /* 4 octants of a sphere */ - vol_est += 0.5*4.0/3.0*M_PI*gmx::power3(r_eff_sup); + vol_est += 0.5 * 4.0 / 3.0 * M_PI * gmx::power3(r_eff_sup); /* Estimate the number of cluster pairs as the local number of * clusters times the volume they interact with times the density. */ - nsp_est = grid.numClusters()*vol_est*dims.atomDensity/numAtomsCluster; + nsp_est = grid.numClusters() * vol_est * dims.atomDensity / numAtomsCluster; /* Subtract the non-local pair count */ nsp_est -= nsp_est_nl; @@ -2589,12 +2566,11 @@ static void get_nsubpair_target(const Nbnxm::GridSet &gridSet, * groups of atoms we'll anyhow be limited by nsubpair_target_min, * so this overestimation will not matter. */ - nsp_est = std::max(nsp_est, grid.numClusters()*14._real); + nsp_est = std::max(nsp_est, grid.numClusters() * 14._real); if (debug) { - fprintf(debug, "nsp_est local %5.1f non-local %5.1f\n", - nsp_est, nsp_est_nl); + fprintf(debug, "nsp_est local %5.1f non-local %5.1f\n", nsp_est, nsp_est_nl); } } else @@ -2606,81 +2582,67 @@ static void get_nsubpair_target(const Nbnxm::GridSet &gridSet, * Since there is overhead, we shouldn't make the lists too small * (and we can't chop up j-groups) so we use a minimum target size of 36. */ - *nsubpair_target = std::max(nsubpair_target_min, - roundToInt(nsp_est/min_ci_balanced)); + *nsubpair_target = std::max(nsubpair_target_min, roundToInt(nsp_est / min_ci_balanced)); *nsubpair_tot_est = nsp_est; if (debug) { - fprintf(debug, "nbl nsp estimate %.1f, nsubpair_target %d\n", - nsp_est, *nsubpair_target); + fprintf(debug, "nbl nsp estimate %.1f, nsubpair_target %d\n", nsp_est, *nsubpair_target); } } /* Debug list print function */ -static void print_nblist_ci_cj(FILE *fp, - const NbnxnPairlistCpu &nbl) +static void print_nblist_ci_cj(FILE* fp, const NbnxnPairlistCpu& nbl) { - for (const nbnxn_ci_t &ciEntry : nbl.ci) + for (const nbnxn_ci_t& ciEntry : nbl.ci) { - fprintf(fp, "ci %4d shift %2d ncj %3d\n", - ciEntry.ci, ciEntry.shift, + fprintf(fp, "ci %4d shift %2d ncj %3d\n", ciEntry.ci, ciEntry.shift, ciEntry.cj_ind_end - ciEntry.cj_ind_start); for (int j = ciEntry.cj_ind_start; j < ciEntry.cj_ind_end; j++) { - fprintf(fp, " cj %5d imask %x\n", - nbl.cj[j].cj, - nbl.cj[j].excl); + fprintf(fp, " cj %5d imask %x\n", nbl.cj[j].cj, nbl.cj[j].excl); } } } /* Debug list print function */ -static void print_nblist_sci_cj(FILE *fp, - const NbnxnPairlistGpu &nbl) +static void print_nblist_sci_cj(FILE* fp, const NbnxnPairlistGpu& nbl) { - for (const nbnxn_sci_t &sci : nbl.sci) + for (const nbnxn_sci_t& sci : nbl.sci) { - fprintf(fp, "ci %4d shift %2d ncj4 %2d\n", - sci.sci, sci.shift, - sci.numJClusterGroups()); + fprintf(fp, "ci %4d shift %2d ncj4 %2d\n", sci.sci, sci.shift, sci.numJClusterGroups()); int ncp = 0; for (int j4 = sci.cj4_ind_start; j4 < sci.cj4_ind_end; j4++) { for (int j = 0; j < c_nbnxnGpuJgroupSize; j++) { - fprintf(fp, " sj %5d imask %x\n", - nbl.cj4[j4].cj[j], - nbl.cj4[j4].imei[0].imask); + fprintf(fp, " sj %5d imask %x\n", nbl.cj4[j4].cj[j], nbl.cj4[j4].imei[0].imask); for (int si = 0; si < c_gpuNumClusterPerCell; si++) { - if (nbl.cj4[j4].imei[0].imask & (1U << (j*c_gpuNumClusterPerCell + si))) + if (nbl.cj4[j4].imei[0].imask & (1U << (j * c_gpuNumClusterPerCell + si))) { ncp++; } } } } - fprintf(fp, "ci %4d shift %2d ncj4 %2d ncp %3d\n", - sci.sci, sci.shift, - sci.numJClusterGroups(), - ncp); + fprintf(fp, "ci %4d shift %2d ncj4 %2d ncp %3d\n", sci.sci, sci.shift, + sci.numJClusterGroups(), ncp); } } /* Combine pair lists *nbl generated on multiple threads nblc */ -static void combine_nblists(gmx::ArrayRef nbls, - NbnxnPairlistGpu *nblc) +static void combine_nblists(gmx::ArrayRef nbls, NbnxnPairlistGpu* nblc) { int nsci = nblc->sci.size(); int ncj4 = nblc->cj4.size(); int nexcl = nblc->excl.size(); - for (auto &nbl : nbls) + for (auto& nbl : nbls) { - nsci += nbl.sci.size(); - ncj4 += nbl.cj4.size(); + nsci += nbl.sci.size(); + ncj4 += nbl.cj4.size(); nexcl += nbl.excl.size(); } @@ -2709,23 +2671,23 @@ static void combine_nblists(gmx::ArrayRef nbls, for (gmx::index i = n; i < nbls.ssize(); i++) { - sci_offset -= nbls[i].sci.size(); - cj4_offset -= nbls[i].cj4.size(); + sci_offset -= nbls[i].sci.size(); + cj4_offset -= nbls[i].cj4.size(); excl_offset -= nbls[i].excl.size(); } - const NbnxnPairlistGpu &nbli = nbls[n]; + const NbnxnPairlistGpu& nbli = nbls[n]; for (size_t i = 0; i < nbli.sci.size(); i++) { - nblc->sci[sci_offset + i] = nbli.sci[i]; + nblc->sci[sci_offset + i] = nbli.sci[i]; nblc->sci[sci_offset + i].cj4_ind_start += cj4_offset; - nblc->sci[sci_offset + i].cj4_ind_end += cj4_offset; + nblc->sci[sci_offset + i].cj4_ind_end += cj4_offset; } for (size_t j4 = 0; j4 < nbli.cj4.size(); j4++) { - nblc->cj4[cj4_offset + j4] = nbli.cj4[j4]; + nblc->cj4[cj4_offset + j4] = nbli.cj4[j4]; nblc->cj4[cj4_offset + j4].imei[0].excl_ind += excl_offset; nblc->cj4[cj4_offset + j4].imei[1].excl_ind += excl_offset; } @@ -2735,17 +2697,17 @@ static void combine_nblists(gmx::ArrayRef nbls, nblc->excl[excl_offset + j4] = nbli.excl[j4]; } } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } - for (auto &nbl : nbls) + for (auto& nbl : nbls) { nblc->nci_tot += nbl.nci_tot; } } -static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLists, - gmx::ArrayRef work) +static void balance_fep_lists(gmx::ArrayRef> fepLists, + gmx::ArrayRef work) { const int numLists = fepLists.ssize(); @@ -2758,13 +2720,13 @@ static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLi /* Count the total i-lists and pairs */ int nri_tot = 0; int nrj_tot = 0; - for (const auto &list : fepLists) + for (const auto& list : fepLists) { nri_tot += list->nri; nrj_tot += list->nrj; } - const int nrj_target = (nrj_tot + numLists - 1)/numLists; + const int nrj_target = (nrj_tot + numLists - 1) / numLists; GMX_ASSERT(gmx_omp_nthreads_get(emntNonbonded) == numLists, "We should have as many work objects as FEP lists"); @@ -2774,7 +2736,7 @@ static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLi { try { - t_nblist *nbl = work[th].nbl_fep.get(); + t_nblist* nbl = work[th].nbl_fep.get(); /* Note that here we allocate for the total size, instead of * a per-thread esimate (which is hard to obtain). @@ -2793,28 +2755,28 @@ static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLi clear_pairlist_fep(nbl); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } /* Loop over the source lists and assign and copy i-entries */ int th_dest = 0; - t_nblist *nbld = work[th_dest].nbl_fep.get(); + t_nblist* nbld = work[th_dest].nbl_fep.get(); for (int th = 0; th < numLists; th++) { - const t_nblist *nbls = fepLists[th].get(); + const t_nblist* nbls = fepLists[th].get(); for (int i = 0; i < nbls->nri; i++) { int nrj; /* The number of pairs in this i-entry */ - nrj = nbls->jindex[i+1] - nbls->jindex[i]; + nrj = nbls->jindex[i + 1] - nbls->jindex[i]; /* Decide if list th_dest is too large and we should procede * to the next destination list. */ - if (th_dest + 1 < numLists && nbld->nrj > 0 && - nbld->nrj + nrj - nrj_target > nrj_target - nbld->nrj) + if (th_dest + 1 < numLists && nbld->nrj > 0 + && nbld->nrj + nrj - nrj_target > nrj_target - nbld->nrj) { th_dest++; nbld = work[th_dest].nbl_fep.get(); @@ -2824,7 +2786,7 @@ static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLi nbld->gid[nbld->nri] = nbls->gid[i]; nbld->shift[nbld->nri] = nbls->shift[i]; - for (int j = nbls->jindex[i]; j < nbls->jindex[i+1]; j++) + for (int j = nbls->jindex[i]; j < nbls->jindex[i + 1]; j++) { nbld->jjnr[nbld->nrj] = nbls->jjnr[j]; nbld->excl_fep[nbld->nrj] = nbls->excl_fep[j]; @@ -2842,19 +2804,13 @@ static void balance_fep_lists(gmx::ArrayRef < std::unique_ptr < t_nblist>> fepLi if (debug) { - fprintf(debug, "nbl_fep[%d] nri %4d nrj %4d\n", - th, - fepLists[th]->nri, - fepLists[th]->nrj); + fprintf(debug, "nbl_fep[%d] nri %4d nrj %4d\n", th, fepLists[th]->nri, fepLists[th]->nrj); } } } /* Returns the next ci to be processes by our thread */ -static gmx_bool next_ci(const Grid &grid, - int nth, int ci_block, - int *ci_x, int *ci_y, - int *ci_b, int *ci) +static gmx_bool next_ci(const Grid& grid, int nth, int ci_block, int* ci_x, int* ci_y, int* ci_b, int* ci) { (*ci_b)++; (*ci)++; @@ -2862,8 +2818,8 @@ static gmx_bool next_ci(const Grid &grid, if (*ci_b == ci_block) { /* Jump to the next block assigned to this task */ - *ci += (nth - 1)*ci_block; - *ci_b = 0; + *ci += (nth - 1) * ci_block; + *ci_b = 0; } if (*ci >= grid.numCells()) @@ -2871,13 +2827,13 @@ static gmx_bool next_ci(const Grid &grid, return FALSE; } - while (*ci >= grid.firstCellInColumn(*ci_x*grid.dimensions().numCells[YY] + *ci_y + 1)) + while (*ci >= grid.firstCellInColumn(*ci_x * grid.dimensions().numCells[YY] + *ci_y + 1)) { *ci_y += 1; if (*ci_y == grid.dimensions().numCells[YY]) { *ci_x += 1; - *ci_y = 0; + *ci_y = 0; } } @@ -2887,8 +2843,8 @@ static gmx_bool next_ci(const Grid &grid, /* Returns the distance^2 for which we put cell pairs in the list * without checking atom pair distances. This is usually < rlist^2. */ -static float boundingbox_only_distance2(const Grid::Dimensions &iGridDims, - const Grid::Dimensions &jGridDims, +static float boundingbox_only_distance2(const Grid::Dimensions& iGridDims, + const Grid::Dimensions& jGridDims, real rlist, gmx_bool simple) { @@ -2908,27 +2864,25 @@ static float boundingbox_only_distance2(const Grid::Dimensions &iGridDims, real bbx, bby; real rbb2; - bbx = 0.5*(iGridDims.cellSize[XX] + jGridDims.cellSize[XX]); - bby = 0.5*(iGridDims.cellSize[YY] + jGridDims.cellSize[YY]); + bbx = 0.5 * (iGridDims.cellSize[XX] + jGridDims.cellSize[XX]); + bby = 0.5 * (iGridDims.cellSize[YY] + jGridDims.cellSize[YY]); if (!simple) { bbx /= c_gpuNumClusterPerCellX; bby /= c_gpuNumClusterPerCellY; } - rbb2 = std::max(0.0, rlist - 0.5*std::sqrt(bbx*bbx + bby*bby)); + rbb2 = std::max(0.0, rlist - 0.5 * std::sqrt(bbx * bbx + bby * bby)); rbb2 = rbb2 * rbb2; #if !GMX_DOUBLE return rbb2; #else - return (float)((1+GMX_FLOAT_EPS)*rbb2); + return (float)((1 + GMX_FLOAT_EPS) * rbb2); #endif } -static int get_ci_block_size(const Grid &iGrid, - const bool haveMultipleDomains, - const int numLists) +static int get_ci_block_size(const Grid& iGrid, const bool haveMultipleDomains, const int numLists) { const int ci_block_enum = 5; const int ci_block_denom = 11; @@ -2948,25 +2902,26 @@ static int get_ci_block_size(const Grid &iGrid, */ GMX_ASSERT(iGrid.dimensions().numCells[XX] > 0, "Grid can't be empty"); GMX_ASSERT(numLists > 0, "We need at least one list"); - ci_block = (iGrid.numCells()*ci_block_enum)/(ci_block_denom*iGrid.dimensions().numCells[XX]*numLists); + ci_block = (iGrid.numCells() * ci_block_enum) + / (ci_block_denom * iGrid.dimensions().numCells[XX] * numLists); const int numAtomsPerCell = iGrid.geometry().numAtomsPerCell; /* Ensure the blocks are not too small: avoids cache invalidation */ - if (ci_block*numAtomsPerCell < ci_block_min_atoms) + if (ci_block * numAtomsPerCell < ci_block_min_atoms) { - ci_block = (ci_block_min_atoms + numAtomsPerCell - 1)/numAtomsPerCell; + ci_block = (ci_block_min_atoms + numAtomsPerCell - 1) / numAtomsPerCell; } /* Without domain decomposition * or with less than 3 blocks per task, divide in nth blocks. */ - if (!haveMultipleDomains || numLists*3*ci_block > iGrid.numCells()) + if (!haveMultipleDomains || numLists * 3 * ci_block > iGrid.numCells()) { - ci_block = (iGrid.numCells() + numLists - 1)/numLists; + ci_block = (iGrid.numCells() + numLists - 1) / numLists; } - if (ci_block > 1 && (numLists - 1)*ci_block >= iGrid.numCells()) + if (ci_block > 1 && (numLists - 1) * ci_block >= iGrid.numCells()) { /* Some threads have no work. Although reducing the block size * does not decrease the block count on the first few threads, @@ -2996,114 +2951,92 @@ static int getBufferFlagShift(int numAtomsPerCluster) return bufferFlagShift; } -static bool pairlistIsSimple(const NbnxnPairlistCpu gmx_unused &pairlist) +static bool pairlistIsSimple(const NbnxnPairlistCpu gmx_unused& pairlist) { return true; } -static bool pairlistIsSimple(const NbnxnPairlistGpu gmx_unused &pairlist) +static bool pairlistIsSimple(const NbnxnPairlistGpu gmx_unused& pairlist) { return false; } -static void -makeClusterListWrapper(NbnxnPairlistCpu *nbl, - const Grid gmx_unused &iGrid, - const int ci, - const Grid &jGrid, - const int firstCell, - const int lastCell, - const bool excludeSubDiagonal, - const nbnxn_atomdata_t *nbat, - const real rlist2, - const real rbb2, - const ClusterDistanceKernelType kernelType, - int *numDistanceChecks) +static void makeClusterListWrapper(NbnxnPairlistCpu* nbl, + const Grid gmx_unused& iGrid, + const int ci, + const Grid& jGrid, + const int firstCell, + const int lastCell, + const bool excludeSubDiagonal, + const nbnxn_atomdata_t* nbat, + const real rlist2, + const real rbb2, + const ClusterDistanceKernelType kernelType, + int* numDistanceChecks) { switch (kernelType) { case ClusterDistanceKernelType::CpuPlainC: - makeClusterListSimple(jGrid, - nbl, ci, firstCell, lastCell, - excludeSubDiagonal, - nbat->x().data(), - rlist2, rbb2, - numDistanceChecks); + makeClusterListSimple(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, + nbat->x().data(), rlist2, rbb2, numDistanceChecks); break; #ifdef GMX_NBNXN_SIMD_4XN case ClusterDistanceKernelType::CpuSimd_4xM: - makeClusterListSimd4xn(jGrid, - nbl, ci, firstCell, lastCell, - excludeSubDiagonal, - nbat->x().data(), - rlist2, rbb2, - numDistanceChecks); + makeClusterListSimd4xn(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, + nbat->x().data(), rlist2, rbb2, numDistanceChecks); break; #endif #ifdef GMX_NBNXN_SIMD_2XNN case ClusterDistanceKernelType::CpuSimd_2xMM: - makeClusterListSimd2xnn(jGrid, - nbl, ci, firstCell, lastCell, - excludeSubDiagonal, - nbat->x().data(), - rlist2, rbb2, - numDistanceChecks); + makeClusterListSimd2xnn(jGrid, nbl, ci, firstCell, lastCell, excludeSubDiagonal, + nbat->x().data(), rlist2, rbb2, numDistanceChecks); break; #endif - default: - GMX_ASSERT(false, "Unhandled kernel type"); + default: GMX_ASSERT(false, "Unhandled kernel type"); } } -static void -makeClusterListWrapper(NbnxnPairlistGpu *nbl, - const Grid &gmx_unused iGrid, - const int ci, - const Grid &jGrid, - const int firstCell, - const int lastCell, - const bool excludeSubDiagonal, - const nbnxn_atomdata_t *nbat, - const real rlist2, - const real rbb2, - ClusterDistanceKernelType gmx_unused kernelType, - int *numDistanceChecks) +static void makeClusterListWrapper(NbnxnPairlistGpu* nbl, + const Grid& gmx_unused iGrid, + const int ci, + const Grid& jGrid, + const int firstCell, + const int lastCell, + const bool excludeSubDiagonal, + const nbnxn_atomdata_t* nbat, + const real rlist2, + const real rbb2, + ClusterDistanceKernelType gmx_unused kernelType, + int* numDistanceChecks) { for (int cj = firstCell; cj <= lastCell; cj++) { - make_cluster_list_supersub(iGrid, jGrid, - nbl, ci, cj, - excludeSubDiagonal, - nbat->xstride, nbat->x().data(), - rlist2, rbb2, - numDistanceChecks); + make_cluster_list_supersub(iGrid, jGrid, nbl, ci, cj, excludeSubDiagonal, nbat->xstride, + nbat->x().data(), rlist2, rbb2, numDistanceChecks); } } -static int getNumSimpleJClustersInList(const NbnxnPairlistCpu &nbl) +static int getNumSimpleJClustersInList(const NbnxnPairlistCpu& nbl) { return nbl.cj.size(); } -static int getNumSimpleJClustersInList(const gmx_unused NbnxnPairlistGpu &nbl) +static int getNumSimpleJClustersInList(const gmx_unused NbnxnPairlistGpu& nbl) { return 0; } -static void incrementNumSimpleJClustersInList(NbnxnPairlistCpu *nbl, - int ncj_old_j) +static void incrementNumSimpleJClustersInList(NbnxnPairlistCpu* nbl, int ncj_old_j) { nbl->ncjInUse += nbl->cj.size(); nbl->ncjInUse -= ncj_old_j; } -static void incrementNumSimpleJClustersInList(NbnxnPairlistGpu gmx_unused *nbl, - int gmx_unused ncj_old_j) +static void incrementNumSimpleJClustersInList(NbnxnPairlistGpu gmx_unused* nbl, int gmx_unused ncj_old_j) { } -static void checkListSizeConsistency(const NbnxnPairlistCpu &nbl, - const bool haveFreeEnergy) +static void checkListSizeConsistency(const NbnxnPairlistCpu& nbl, const bool haveFreeEnergy) { GMX_RELEASE_ASSERT(static_cast(nbl.ncjInUse) == nbl.cj.size() || haveFreeEnergy, "Without free-energy all cj pair-list entries should be in use. " @@ -3111,17 +3044,16 @@ static void checkListSizeConsistency(const NbnxnPairlistCpu &nbl, "this check is only here to catch bugs"); } -static void checkListSizeConsistency(const NbnxnPairlistGpu gmx_unused &nbl, - bool gmx_unused haveFreeEnergy) +static void checkListSizeConsistency(const NbnxnPairlistGpu gmx_unused& nbl, bool gmx_unused haveFreeEnergy) { /* We currently can not check consistency here */ } /* Set the buffer flags for newly added entries in the list */ -static void setBufferFlags(const NbnxnPairlistCpu &nbl, +static void setBufferFlags(const NbnxnPairlistCpu& nbl, const int ncj_old_j, const int gridj_flag_shift, - gmx_bitmask_t *gridj_flag, + gmx_bitmask_t* gridj_flag, const int th) { if (gmx::ssize(nbl.cj) > ncj_old_j) @@ -3135,51 +3067,52 @@ static void setBufferFlags(const NbnxnPairlistCpu &nbl, } } -static void setBufferFlags(const NbnxnPairlistGpu gmx_unused &nbl, - int gmx_unused ncj_old_j, - int gmx_unused gridj_flag_shift, - gmx_bitmask_t gmx_unused *gridj_flag, - int gmx_unused th) +static void setBufferFlags(const NbnxnPairlistGpu gmx_unused& nbl, + int gmx_unused ncj_old_j, + int gmx_unused gridj_flag_shift, + gmx_bitmask_t gmx_unused* gridj_flag, + int gmx_unused th) { GMX_ASSERT(false, "This function should never be called"); } /* Generates the part of pair-list nbl assigned to our thread */ -template -static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, - const Grid &iGrid, - const Grid &jGrid, - PairsearchWork *work, - const nbnxn_atomdata_t *nbat, - const t_blocka &exclusions, - real rlist, - const PairlistType pairlistType, - int ci_block, - gmx_bool bFBufferFlag, - int nsubpair_max, - gmx_bool progBal, - float nsubpair_tot_est, - int th, int nth, - T *nbl, - t_nblist *nbl_fep) +template +static void nbnxn_make_pairlist_part(const Nbnxm::GridSet& gridSet, + const Grid& iGrid, + const Grid& jGrid, + PairsearchWork* work, + const nbnxn_atomdata_t* nbat, + const t_blocka& exclusions, + real rlist, + const PairlistType pairlistType, + int ci_block, + gmx_bool bFBufferFlag, + int nsubpair_max, + gmx_bool progBal, + float nsubpair_tot_est, + int th, + int nth, + T* nbl, + t_nblist* nbl_fep) { - int na_cj_2log; - matrix box; - real rl_fep2 = 0; - float rbb2; - int ci_b, ci, ci_x, ci_y, ci_xy; - ivec shp; - real bx0, bx1, by0, by1, bz0, bz1; - real bz1_frac; - real d2cx, d2z, d2z_cx, d2z_cy, d2zx, d2zxy, d2xy; - int cxf, cxl, cyf, cyf_x, cyl; - int numDistanceChecks; - int gridi_flag_shift = 0, gridj_flag_shift = 0; - gmx_bitmask_t *gridj_flag = nullptr; - int ncj_old_i, ncj_old_j; - - if (jGrid.geometry().isSimple != pairlistIsSimple(*nbl) || - iGrid.geometry().isSimple != pairlistIsSimple(*nbl)) + int na_cj_2log; + matrix box; + real rl_fep2 = 0; + float rbb2; + int ci_b, ci, ci_x, ci_y, ci_xy; + ivec shp; + real bx0, bx1, by0, by1, bz0, bz1; + real bz1_frac; + real d2cx, d2z, d2z_cx, d2z_cy, d2zx, d2zxy, d2xy; + int cxf, cxl, cyf, cyf_x, cyl; + int numDistanceChecks; + int gridi_flag_shift = 0, gridj_flag_shift = 0; + gmx_bitmask_t* gridj_flag = nullptr; + int ncj_old_i, ncj_old_j; + + if (jGrid.geometry().isSimple != pairlistIsSimple(*nbl) + || iGrid.geometry().isSimple != pairlistIsSimple(*nbl)) { gmx_incons("Grid incompatible with pair-list"); } @@ -3190,7 +3123,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, nbl->na_cj = JClusterSizePerListType[pairlistType]; na_cj_2log = get_2log(nbl->na_cj); - nbl->rlist = rlist; + nbl->rlist = rlist; if (bFBufferFlag) { @@ -3198,18 +3131,17 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, gridi_flag_shift = getBufferFlagShift(nbl->na_ci); gridj_flag_shift = getBufferFlagShift(nbl->na_cj); - gridj_flag = work->buffer_flags.flag; + gridj_flag = work->buffer_flags.flag; } gridSet.getBox(box); - const bool haveFep = gridSet.haveFep(); + const bool haveFep = gridSet.haveFep(); - const real rlist2 = nbl->rlist*nbl->rlist; + const real rlist2 = nbl->rlist * nbl->rlist; // Select the cluster pair distance kernel type - const ClusterDistanceKernelType kernelType = - getClusterDistanceKernelType(pairlistType, *nbat); + const ClusterDistanceKernelType kernelType = getClusterDistanceKernelType(pairlistType, *nbat); if (haveFep && !pairlistIsSimple(*nbl)) { @@ -3225,11 +3157,11 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, { fprintf(debug, "nbl_fep atom-pair rlist %f\n", rl_fep2); } - rl_fep2 = rl_fep2*rl_fep2; + rl_fep2 = rl_fep2 * rl_fep2; } - const Grid::Dimensions &iGridDims = iGrid.dimensions(); - const Grid::Dimensions &jGridDims = jGrid.dimensions(); + const Grid::Dimensions& iGridDims = iGrid.dimensions(); + const Grid::Dimensions& jGridDims = jGrid.dimensions(); rbb2 = boundingbox_only_distance2(iGridDims, jGridDims, nbl->rlist, pairlistIsSimple(*nbl)); @@ -3246,17 +3178,16 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, /* Check if we need periodicity shifts. * Without PBC or with domain decomposition we don't need them. */ - if (d >= ePBC2npbcdim(gridSet.domainSetup().ePBC) || - gridSet.domainSetup().haveMultipleDomainsPerDim[d]) + if (d >= ePBC2npbcdim(gridSet.domainSetup().ePBC) + || gridSet.domainSetup().haveMultipleDomainsPerDim[d]) { shp[d] = 0; } else { const real listRangeCellToCell = - listRangeForGridCellToGridCell(rlist, iGrid.dimensions(), jGrid.dimensions()); - if (d == XX && - box[XX][XX] - fabs(box[YY][XX]) - fabs(box[ZZ][XX]) < listRangeCellToCell) + listRangeForGridCellToGridCell(rlist, iGrid.dimensions(), jGrid.dimensions()); + if (d == XX && box[XX][XX] - fabs(box[YY][XX]) - fabs(box[ZZ][XX]) < listRangeCellToCell) { shp[d] = 2; } @@ -3266,13 +3197,13 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } } } - const bool bSimple = pairlistIsSimple(*nbl); + const bool bSimple = pairlistIsSimple(*nbl); gmx::ArrayRef bb_i; #if NBNXN_BBXXXX - gmx::ArrayRef pbb_i; + gmx::ArrayRef pbb_i; if (bSimple) { - bb_i = iGrid.iBoundingBoxes(); + bb_i = iGrid.iBoundingBoxes(); } else { @@ -3280,7 +3211,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } #else /* We use the normal bounding box format for both grid types */ - bb_i = iGrid.iBoundingBoxes(); + bb_i = iGrid.iBoundingBoxes(); #endif gmx::ArrayRef bbcz_i = iGrid.zBoundingBoxes(); gmx::ArrayRef flags_i = iGrid.clusterFlags(); @@ -3289,19 +3220,20 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, if (debug) { - fprintf(debug, "nbl nc_i %d col.av. %.1f ci_block %d\n", - iGrid.numCells(), iGrid.numCells()/static_cast(iGrid.numColumns()), ci_block); + fprintf(debug, "nbl nc_i %d col.av. %.1f ci_block %d\n", iGrid.numCells(), + iGrid.numCells() / static_cast(iGrid.numColumns()), ci_block); } numDistanceChecks = 0; - const real listRangeBBToJCell2 = gmx::square(listRangeForBoundingBoxToGridCell(rlist, jGrid.dimensions())); + const real listRangeBBToJCell2 = + gmx::square(listRangeForBoundingBoxToGridCell(rlist, jGrid.dimensions())); /* Initially ci_b and ci to 1 before where we want them to start, * as they will both be incremented in next_ci. */ ci_b = -1; - ci = th*ci_block - 1; + ci = th * ci_block - 1; ci_x = 0; ci_y = 0; while (next_ci(iGrid, nth, ci_block, &ci_x, &ci_y, &ci_b, &ci)) @@ -3321,7 +3253,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } else { - bx1 = iGridDims.lowerCorner[XX] + (real(ci_x)+1)*iGridDims.cellSize[XX]; + bx1 = iGridDims.lowerCorner[XX] + (real(ci_x) + 1) * iGridDims.cellSize[XX]; } if (bx1 < jGridDims.lowerCorner[XX]) { @@ -3334,12 +3266,12 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } } - ci_xy = ci_x*iGridDims.numCells[YY] + ci_y; + ci_xy = ci_x * iGridDims.numCells[YY] + ci_y; /* Loop over shift vectors in three dimensions */ for (int tz = -shp[ZZ]; tz <= shp[ZZ]; tz++) { - const real shz = real(tz)*box[ZZ][ZZ]; + const real shz = real(tz) * box[ZZ][ZZ]; bz0 = bbcz_i[ci].lower + shz; bz1 = bbcz_i[ci].upper + shz; @@ -3364,7 +3296,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, continue; } - bz1_frac = bz1/real(iGrid.numCellsInColumn(ci_xy)); + bz1_frac = bz1 / real(iGrid.numCellsInColumn(ci_xy)); if (bz1_frac < 0) { bz1_frac = 0; @@ -3373,7 +3305,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, for (int ty = -shp[YY]; ty <= shp[YY]; ty++) { - const real shy = real(ty)*box[YY][YY] + real(tz)*box[ZZ][YY]; + const real shy = real(ty) * box[YY][YY] + real(tz) * box[ZZ][YY]; if (bSimple) { @@ -3382,14 +3314,11 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } else { - by0 = iGridDims.lowerCorner[YY] + (real(ci_y) )*iGridDims.cellSize[YY] + shy; - by1 = iGridDims.lowerCorner[YY] + (real(ci_y) + 1)*iGridDims.cellSize[YY] + shy; + by0 = iGridDims.lowerCorner[YY] + (real(ci_y)) * iGridDims.cellSize[YY] + shy; + by1 = iGridDims.lowerCorner[YY] + (real(ci_y) + 1) * iGridDims.cellSize[YY] + shy; } - get_cell_range(by0, by1, - jGridDims, - d2z_cx, rlist, - &cyf, &cyl); + get_cell_range(by0, by1, jGridDims, d2z_cx, rlist, &cyf, &cyl); if (cyf > cyl) { @@ -3408,7 +3337,7 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, for (int tx = -shp[XX]; tx <= shp[XX]; tx++) { - const int shift = XYZ2IS(tx, ty, tz); + const int shift = XYZ2IS(tx, ty, tz); const bool excludeSubDiagonal = (isIntraGridList && shift == CENTRAL); @@ -3417,7 +3346,8 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, continue; } - const real shx = real(tx)*box[XX][XX] + real(ty)*box[YY][XX] + real(tz)*box[ZZ][XX]; + const real shx = + real(tx) * box[XX][XX] + real(ty) * box[YY][XX] + real(tz) * box[ZZ][XX]; if (bSimple) { @@ -3426,24 +3356,20 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } else { - bx0 = iGridDims.lowerCorner[XX] + (real(ci_x) )*iGridDims.cellSize[XX] + shx; - bx1 = iGridDims.lowerCorner[XX] + (real(ci_x)+1)*iGridDims.cellSize[XX] + shx; + bx0 = iGridDims.lowerCorner[XX] + (real(ci_x)) * iGridDims.cellSize[XX] + shx; + bx1 = iGridDims.lowerCorner[XX] + (real(ci_x) + 1) * iGridDims.cellSize[XX] + shx; } - get_cell_range(bx0, bx1, - jGridDims, - d2z_cy, rlist, - &cxf, &cxl); + get_cell_range(bx0, bx1, jGridDims, d2z_cy, rlist, &cxf, &cxl); if (cxf > cxl) { continue; } - addNewIEntry(nbl, cell0_i+ci, shift, flags_i[ci]); + addNewIEntry(nbl, cell0_i + ci, shift, flags_i[ci]); - if ((!c_pbcShiftBackward || excludeSubDiagonal) && - cxf < ci_x) + if ((!c_pbcShiftBackward || excludeSubDiagonal) && cxf < ci_x) { /* Leave the pairs with i > j. * x is the major index, so skip half of it. @@ -3451,31 +3377,28 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, cxf = ci_x; } - set_icell_bb(iGrid, ci, shx, shy, shz, - nbl->work.get()); + set_icell_bb(iGrid, ci, shx, shy, shz, nbl->work.get()); - icell_set_x(cell0_i+ci, shx, shy, shz, - nbat->xstride, nbat->x().data(), - kernelType, - nbl->work.get()); + icell_set_x(cell0_i + ci, shx, shy, shz, nbat->xstride, nbat->x().data(), + kernelType, nbl->work.get()); for (int cx = cxf; cx <= cxl; cx++) { const real cx_real = cx; - d2zx = d2z; - if (jGridDims.lowerCorner[XX] + cx_real*jGridDims.cellSize[XX] > bx1) + d2zx = d2z; + if (jGridDims.lowerCorner[XX] + cx_real * jGridDims.cellSize[XX] > bx1) { - d2zx += gmx::square(jGridDims.lowerCorner[XX] + cx_real*jGridDims.cellSize[XX] - bx1); + d2zx += gmx::square(jGridDims.lowerCorner[XX] + + cx_real * jGridDims.cellSize[XX] - bx1); } - else if (jGridDims.lowerCorner[XX] + (cx_real+1)*jGridDims.cellSize[XX] < bx0) + else if (jGridDims.lowerCorner[XX] + (cx_real + 1) * jGridDims.cellSize[XX] < bx0) { - d2zx += gmx::square(jGridDims.lowerCorner[XX] + (cx_real+1)*jGridDims.cellSize[XX] - bx0); + d2zx += gmx::square(jGridDims.lowerCorner[XX] + + (cx_real + 1) * jGridDims.cellSize[XX] - bx0); } - if (isIntraGridList && - cx == 0 && - (!c_pbcShiftBackward || shift == CENTRAL) && - cyf < ci_y) + if (isIntraGridList && cx == 0 && (!c_pbcShiftBackward || shift == CENTRAL) + && cyf < ci_y) { /* Leave the pairs with i > j. * Skip half of y when i and j have the same x. @@ -3489,18 +3412,22 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, for (int cy = cyf_x; cy <= cyl; cy++) { - const int columnStart = jGrid.firstCellInColumn(cx*jGridDims.numCells[YY] + cy); - const int columnEnd = jGrid.firstCellInColumn(cx*jGridDims.numCells[YY] + cy + 1); + const int columnStart = + jGrid.firstCellInColumn(cx * jGridDims.numCells[YY] + cy); + const int columnEnd = + jGrid.firstCellInColumn(cx * jGridDims.numCells[YY] + cy + 1); const real cy_real = cy; - d2zxy = d2zx; - if (jGridDims.lowerCorner[YY] + cy_real*jGridDims.cellSize[YY] > by1) + d2zxy = d2zx; + if (jGridDims.lowerCorner[YY] + cy_real * jGridDims.cellSize[YY] > by1) { - d2zxy += gmx::square(jGridDims.lowerCorner[YY] + cy_real*jGridDims.cellSize[YY] - by1); + d2zxy += gmx::square(jGridDims.lowerCorner[YY] + + cy_real * jGridDims.cellSize[YY] - by1); } - else if (jGridDims.lowerCorner[YY] + (cy_real + 1)*jGridDims.cellSize[YY] < by0) + else if (jGridDims.lowerCorner[YY] + (cy_real + 1) * jGridDims.cellSize[YY] < by0) { - d2zxy += gmx::square(jGridDims.lowerCorner[YY] + (cy_real + 1)*jGridDims.cellSize[YY] - by0); + d2zxy += gmx::square(jGridDims.lowerCorner[YY] + + (cy_real + 1) * jGridDims.cellSize[YY] - by0); } if (columnStart < columnEnd && d2zxy < listRangeBBToJCell2) { @@ -3517,7 +3444,10 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, * but we do not do this because it would * complicate this code even more. */ - int midCell = columnStart + static_cast(bz1_frac*static_cast(columnEnd - columnStart)); + int midCell = + columnStart + + static_cast(bz1_frac + * static_cast(columnEnd - columnStart)); if (midCell >= columnEnd) { midCell = columnEnd - 1; @@ -3532,9 +3462,9 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, * if it is within range. */ int downTestCell = midCell; - while (downTestCell >= columnStart && - (bbcz_j[downTestCell].upper >= bz0 || - d2xy + gmx::square(bbcz_j[downTestCell].upper - bz0) < rlist2)) + while (downTestCell >= columnStart + && (bbcz_j[downTestCell].upper >= bz0 + || d2xy + gmx::square(bbcz_j[downTestCell].upper - bz0) < rlist2)) { downTestCell--; } @@ -3547,9 +3477,9 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, * if it is within range. */ int upTestCell = midCell + 1; - while (upTestCell < columnEnd && - (bbcz_j[upTestCell].lower <= bz1 || - d2xy + gmx::square(bbcz_j[upTestCell].lower - bz1) < rlist2)) + while (upTestCell < columnEnd + && (bbcz_j[upTestCell].lower <= bz1 + || d2xy + gmx::square(bbcz_j[upTestCell].lower - bz1) < rlist2)) { upTestCell++; } @@ -3565,13 +3495,13 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, lastCell = -1; for (int k = columnStart; k < columnEnd; k++) { - if (d2xy + gmx::square(bbcz_j[k*NNBSBB_D + 1] - bz0) < rlist2 && - k < firstCell) + if (d2xy + gmx::square(bbcz_j[k * NNBSBB_D + 1] - bz0) < rlist2 + && k < firstCell) { firstCell = k; } - if (d2xy + gmx::square(bbcz_j[k*NNBSBB_D] - bz1) < rlist2 && - k > lastCell) + if (d2xy + gmx::square(bbcz_j[k * NNBSBB_D] - bz1) < rlist2 + && k > lastCell) { lastCell = k; } @@ -3592,24 +3522,20 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, if (firstCell <= lastCell) { - GMX_ASSERT(firstCell >= columnStart && lastCell < columnEnd, "The range should reside within the current grid column"); + GMX_ASSERT(firstCell >= columnStart && lastCell < columnEnd, + "The range should reside within the current grid " + "column"); /* For f buffer flags with simple lists */ ncj_old_j = getNumSimpleJClustersInList(*nbl); - makeClusterListWrapper(nbl, - iGrid, ci, - jGrid, firstCell, lastCell, - excludeSubDiagonal, - nbat, - rlist2, rbb2, - kernelType, - &numDistanceChecks); + makeClusterListWrapper(nbl, iGrid, ci, jGrid, firstCell, lastCell, + excludeSubDiagonal, nbat, rlist2, rbb2, + kernelType, &numDistanceChecks); if (bFBufferFlag) { - setBufferFlags(*nbl, ncj_old_j, gridj_flag_shift, - gridj_flag, th); + setBufferFlags(*nbl, ncj_old_j, gridj_flag_shift, gridj_flag, th); } incrementNumSimpleJClustersInList(nbl, ncj_old_j); @@ -3619,28 +3545,17 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } /* Set the exclusions for this ci list */ - setExclusionsForIEntry(gridSet, - nbl, - excludeSubDiagonal, - na_cj_2log, - *getOpenIEntry(nbl), - exclusions); + setExclusionsForIEntry(gridSet, nbl, excludeSubDiagonal, na_cj_2log, + *getOpenIEntry(nbl), exclusions); if (haveFep) { - make_fep_list(gridSet.atomIndices(), nbat, nbl, - excludeSubDiagonal, - getOpenIEntry(nbl), - shx, shy, shz, - rl_fep2, - iGrid, jGrid, nbl_fep); + make_fep_list(gridSet.atomIndices(), nbat, nbl, excludeSubDiagonal, + getOpenIEntry(nbl), shx, shy, shz, rl_fep2, iGrid, jGrid, nbl_fep); } /* Close this ci list */ - closeIEntry(nbl, - nsubpair_max, - progBal, nsubpair_tot_est, - th, nth); + closeIEntry(nbl, nsubpair_max, progBal, nsubpair_tot_est, th, nth); } } } @@ -3668,13 +3583,13 @@ static void nbnxn_make_pairlist_part(const Nbnxm::GridSet &gridSet, } } -static void reduce_buffer_flags(gmx::ArrayRef searchWork, - int nsrc, - const nbnxn_buffer_flags_t *dest) +static void reduce_buffer_flags(gmx::ArrayRef searchWork, + int nsrc, + const nbnxn_buffer_flags_t* dest) { for (int s = 0; s < nsrc; s++) { - gmx_bitmask_t * flag = searchWork[s].buffer_flags.flag; + gmx_bitmask_t* flag = searchWork[s].buffer_flags.flag; for (int b = 0; b < dest->nflag; b++) { @@ -3683,7 +3598,7 @@ static void reduce_buffer_flags(gmx::ArrayRef searchWork, } } -static void print_reduction_cost(const nbnxn_buffer_flags_t *flags, int nout) +static void print_reduction_cost(const nbnxn_buffer_flags_t* flags, int nout) { int nelem, nkeep, ncopy, nred, out; gmx_bitmask_t mask_0; @@ -3723,12 +3638,11 @@ static void print_reduction_cost(const nbnxn_buffer_flags_t *flags, int nout) } } - fprintf(debug, "nbnxn reduction: #flag %d #list %d elem %4.2f, keep %4.2f copy %4.2f red %4.2f\n", - flags->nflag, nout, - nelem/static_cast(flags->nflag), - nkeep/static_cast(flags->nflag), - ncopy/static_cast(flags->nflag), - nred/static_cast(flags->nflag)); + fprintf(debug, + "nbnxn reduction: #flag %d #list %d elem %4.2f, keep %4.2f copy %4.2f red %4.2f\n", + flags->nflag, nout, nelem / static_cast(flags->nflag), + nkeep / static_cast(flags->nflag), ncopy / static_cast(flags->nflag), + nred / static_cast(flags->nflag)); } /* Copies the list entries from src to dest when cjStart <= *cjGlobal < cjEnd. @@ -3736,11 +3650,13 @@ static void print_reduction_cost(const nbnxn_buffer_flags_t *flags, int nout) * When setFlags==true, flag bit t is set in flag for all i and j clusters. */ template -static void copySelectedListRange(const nbnxn_ci_t * gmx_restrict srcCi, - const NbnxnPairlistCpu * gmx_restrict src, - NbnxnPairlistCpu * gmx_restrict dest, - gmx_bitmask_t *flag, - int iFlagShift, int jFlagShift, int t) +static void copySelectedListRange(const nbnxn_ci_t* gmx_restrict srcCi, + const NbnxnPairlistCpu* gmx_restrict src, + NbnxnPairlistCpu* gmx_restrict dest, + gmx_bitmask_t* flag, + int iFlagShift, + int jFlagShift, + int t) { const int ncj = srcCi->cj_ind_end - srcCi->cj_ind_start; @@ -3771,8 +3687,8 @@ static void copySelectedListRange(const nbnxn_ci_t * gmx_restrict srcCi, #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ == 7 /* Avoid gcc 7 avx512 loop vectorization bug (actually only needed with -mavx512f) */ -#pragma GCC push_options -#pragma GCC optimize ("no-tree-vectorize") +# pragma GCC push_options +# pragma GCC optimize("no-tree-vectorize") #endif /* Returns the number of cluster pairs that are in use summed over all lists */ @@ -3783,7 +3699,7 @@ static int countClusterpairs(gmx::ArrayRef pairlists) * loop vectorization to avoid this bug. */ int ncjTotal = 0; - for (const auto &pairlist : pairlists) + for (const auto& pairlist : pairlists) { ncjTotal += pairlist.ncjInUse; } @@ -3791,7 +3707,7 @@ static int countClusterpairs(gmx::ArrayRef pairlists) } #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && __GNUC__ == 7 -#pragma GCC pop_options +# pragma GCC pop_options #endif /* This routine re-balances the pairlists such that all are nearly equally @@ -3808,17 +3724,17 @@ static void rebalanceSimpleLists(gmx::ArrayRef srcSet, { const int ncjTotal = countClusterpairs(srcSet); const int numLists = srcSet.ssize(); - const int ncjTarget = (ncjTotal + numLists - 1)/numLists; + const int ncjTarget = (ncjTotal + numLists - 1) / numLists; #pragma omp parallel num_threads(numLists) { - int t = gmx_omp_get_thread_num(); + int t = gmx_omp_get_thread_num(); - int cjStart = ncjTarget* t; - int cjEnd = ncjTarget*(t + 1); + int cjStart = ncjTarget * t; + int cjEnd = ncjTarget * (t + 1); /* The destination pair-list for task/thread t */ - NbnxnPairlistCpu &dest = destSet[t]; + NbnxnPairlistCpu& dest = destSet[t]; clear_pairlist(&dest); dest.na_cj = srcSet[0].na_cj; @@ -3826,21 +3742,21 @@ static void rebalanceSimpleLists(gmx::ArrayRef srcSet, /* Note that the flags in the work struct (still) contain flags * for all entries that are present in srcSet->nbl[t]. */ - gmx_bitmask_t *flag = searchWork[t].buffer_flags.flag; + gmx_bitmask_t* flag = searchWork[t].buffer_flags.flag; - int iFlagShift = getBufferFlagShift(dest.na_ci); - int jFlagShift = getBufferFlagShift(dest.na_cj); + int iFlagShift = getBufferFlagShift(dest.na_ci); + int jFlagShift = getBufferFlagShift(dest.na_cj); - int cjGlobal = 0; + int cjGlobal = 0; for (int s = 0; s < numLists && cjGlobal < cjEnd; s++) { - const NbnxnPairlistCpu *src = &srcSet[s]; + const NbnxnPairlistCpu* src = &srcSet[s]; if (cjGlobal + src->ncjInUse > cjStart) { for (gmx::index i = 0; i < gmx::ssize(src->ci) && cjGlobal < cjEnd; i++) { - const nbnxn_ci_t *srcCi = &src->ci[i]; + const nbnxn_ci_t* srcCi = &src->ci[i]; int ncj = srcCi->cj_ind_end - srcCi->cj_ind_start; if (cjGlobal >= cjStart) { @@ -3849,17 +3765,12 @@ static void rebalanceSimpleLists(gmx::ArrayRef srcSet, */ if (s != t) { - copySelectedListRange - - (srcCi, src, &dest, - flag, iFlagShift, jFlagShift, t); + copySelectedListRange(srcCi, src, &dest, flag, iFlagShift, jFlagShift, t); } else { - copySelectedListRange - - (srcCi, src, - &dest, flag, iFlagShift, jFlagShift, t); + copySelectedListRange(srcCi, src, &dest, flag, iFlagShift, + jFlagShift, t); } } cjGlobal += ncj; @@ -3876,7 +3787,8 @@ static void rebalanceSimpleLists(gmx::ArrayRef srcSet, #ifndef NDEBUG const int ncjTotalNew = countClusterpairs(destSet); - GMX_RELEASE_ASSERT(ncjTotalNew == ncjTotal, "The total size of the lists before and after rebalancing should match"); + GMX_RELEASE_ASSERT(ncjTotalNew == ncjTotal, + "The total size of the lists before and after rebalancing should match"); #endif } @@ -3888,7 +3800,7 @@ static bool checkRebalanceSimpleLists(gmx::ArrayRef list int ncjTotal = 0; for (int s = 0; s < numLists; s++) { - ncjMax = std::max(ncjMax, lists[s].ncjInUse); + ncjMax = std::max(ncjMax, lists[s].ncjInUse); ncjTotal += lists[s].ncjInUse; } if (debug) @@ -3902,7 +3814,7 @@ static bool checkRebalanceSimpleLists(gmx::ArrayRef list */ const real rebalanceTolerance = 1.03; - return real(numLists*ncjMax) > real(ncjTotal)*rebalanceTolerance; + return real(numLists * ncjMax) > real(ncjTotal) * rebalanceTolerance; } /* Perform a count (linear) sort to sort the smaller lists to the end. @@ -3915,7 +3827,7 @@ static bool checkRebalanceSimpleLists(gmx::ArrayRef list * better load balancing than using a list sorted on exact load. * This function swaps the pointer in the pair list to avoid a copy operation. */ -static void sort_sci(NbnxnPairlistGpu *nbl) +static void sort_sci(NbnxnPairlistGpu* nbl) { if (nbl->cj4.size() <= nbl->sci.size()) { @@ -3923,20 +3835,20 @@ static void sort_sci(NbnxnPairlistGpu *nbl) return; } - NbnxnPairlistGpuWork &work = *nbl->work; + NbnxnPairlistGpuWork& work = *nbl->work; /* We will distinguish differences up to double the average */ - const int m = static_cast((2*ssize(nbl->cj4))/ssize(nbl->sci)); + const int m = static_cast((2 * ssize(nbl->cj4)) / ssize(nbl->sci)); /* Resize work.sci_sort so we can sort into it */ work.sci_sort.resize(nbl->sci.size()); - std::vector &sort = work.sortBuffer; + std::vector& sort = work.sortBuffer; /* Set up m + 1 entries in sort, initialized at 0 */ sort.clear(); sort.resize(m + 1, 0); /* Count the entries of each size */ - for (const nbnxn_sci_t &sci : nbl->sci) + for (const nbnxn_sci_t& sci : nbl->sci) { int i = std::min(m, sci.numJClusterGroups()); sort[i]++; @@ -3953,9 +3865,9 @@ static void sort_sci(NbnxnPairlistGpu *nbl) /* Sort entries directly into place */ gmx::ArrayRef sci_sort = work.sci_sort; - for (const nbnxn_sci_t &sci : nbl->sci) + for (const nbnxn_sci_t& sci : nbl->sci) { - int i = std::min(m, sci.numJClusterGroups()); + int i = std::min(m, sci.numJClusterGroups()); sci_sort[sort[i]++] = sci; } @@ -3964,52 +3876,40 @@ static void sort_sci(NbnxnPairlistGpu *nbl) } /* Returns the i-zone range for pairlist construction for the give locality */ -static Range -getIZoneRange(const Nbnxm::GridSet::DomainSetup &domainSetup, - const InteractionLocality locality) +static Range getIZoneRange(const Nbnxm::GridSet::DomainSetup& domainSetup, + const InteractionLocality locality) { if (domainSetup.doTestParticleInsertion) { /* With TPI we do grid 1, the inserted molecule, versus grid 0, the rest */ - return { - 1, 2 - }; + return { 1, 2 }; } else if (locality == InteractionLocality::Local) { /* Local: only zone (grid) 0 vs 0 */ - return { - 0, 1 - }; + return { 0, 1 }; } else { /* Non-local: we need all i-zones */ - return { - 0, int(domainSetup.zones->iZones.size()) - }; + return { 0, int(domainSetup.zones->iZones.size()) }; } } /* Returns the j-zone range for pairlist construction for the give locality and i-zone */ -static Range -getJZoneRange(const gmx_domdec_zones_t &ddZones, - const InteractionLocality locality, - const int iZone) +static Range getJZoneRange(const gmx_domdec_zones_t& ddZones, + const InteractionLocality locality, + const int iZone) { if (locality == InteractionLocality::Local) { /* Local: zone 0 vs 0 or with TPI 1 vs 0 */ - return { - 0, 1 - }; + return { 0, 1 }; } else if (iZone == 0) { /* Non-local: we need to avoid the local (zone 0 vs 0) interactions */ - return { - 1, *ddZones.iZones[iZone].jZoneRange.end() - }; + return { 1, *ddZones.iZones[iZone].jZoneRange.end() }; } else { @@ -4021,24 +3921,23 @@ getJZoneRange(const gmx_domdec_zones_t &ddZones, //! Prepares CPU lists produced by the search for dynamic pruning static void prepareListsForDynamicPruning(gmx::ArrayRef lists); -void -PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, - gmx::ArrayRef searchWork, - nbnxn_atomdata_t *nbat, - const t_blocka *excl, - const int minimumIlistCountForGpuBalancing, - t_nrnb *nrnb, - SearchCycleCounting *searchCycleCounting) +void PairlistSet::constructPairlists(const Nbnxm::GridSet& gridSet, + gmx::ArrayRef searchWork, + nbnxn_atomdata_t* nbat, + const t_blocka* excl, + const int minimumIlistCountForGpuBalancing, + t_nrnb* nrnb, + SearchCycleCounting* searchCycleCounting) { - const real rlist = params_.rlistOuter; + const real rlist = params_.rlistOuter; - int nsubpair_target; - float nsubpair_tot_est; - int ci_block; - gmx_bool progBal; - int np_tot, np_noq, np_hlj, nap; + int nsubpair_target; + float nsubpair_tot_est; + int ci_block; + gmx_bool progBal; + int np_tot, np_noq, np_hlj, nap; - const int numLists = (isCpuType_ ? cpuLists_.size() : gpuLists_.size()); + const int numLists = (isCpuType_ ? cpuLists_.size() : gpuLists_.size()); if (debug) { @@ -4081,19 +3980,19 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, } } - const gmx_domdec_zones_t &ddZones = *gridSet.domainSetup().zones; + const gmx_domdec_zones_t& ddZones = *gridSet.domainSetup().zones; const auto iZoneRange = getIZoneRange(gridSet.domainSetup(), locality_); for (const int iZone : iZoneRange) { - const Grid &iGrid = gridSet.grids()[iZone]; + const Grid& iGrid = gridSet.grids()[iZone]; const auto jZoneRange = getJZoneRange(ddZones, locality_, iZone); for (int jZone : jZoneRange) { - const Grid &jGrid = gridSet.grids()[jZone]; + const Grid& jGrid = gridSet.grids()[jZone]; if (debug) { @@ -4129,45 +4028,31 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, clear_pairlist(&gpuLists_[th]); } - PairsearchWork &work = searchWork[th]; + PairsearchWork& work = searchWork[th]; work.cycleCounter.start(); - t_nblist *fepListPtr = (fepLists_.empty() ? nullptr : fepLists_[th].get()); + t_nblist* fepListPtr = (fepLists_.empty() ? nullptr : fepLists_[th].get()); /* Divide the i cells equally over the pairlists */ if (isCpuType_) { - nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, - &work, nbat, *excl, - rlist, - params_.pairlistType, - ci_block, - nbat->bUseBufferFlags, - nsubpair_target, - progBal, nsubpair_tot_est, - th, numLists, - &cpuLists_[th], - fepListPtr); + nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, &work, nbat, *excl, rlist, + params_.pairlistType, ci_block, nbat->bUseBufferFlags, + nsubpair_target, progBal, nsubpair_tot_est, th, + numLists, &cpuLists_[th], fepListPtr); } else { - nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, - &work, nbat, *excl, - rlist, - params_.pairlistType, - ci_block, - nbat->bUseBufferFlags, - nsubpair_target, - progBal, nsubpair_tot_est, - th, numLists, - &gpuLists_[th], - fepListPtr); + nbnxn_make_pairlist_part(gridSet, iGrid, jGrid, &work, nbat, *excl, rlist, + params_.pairlistType, ci_block, nbat->bUseBufferFlags, + nsubpair_target, progBal, nsubpair_tot_est, th, + numLists, &gpuLists_[th], fepListPtr); } work.cycleCounter.stop(); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } searchCycleCounting->stop(enbsCCsearch); @@ -4180,29 +4065,29 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, if (isCpuType_) { - const NbnxnPairlistCpu &nbl = cpuLists_[th]; + const NbnxnPairlistCpu& nbl = cpuLists_[th]; np_tot += nbl.cj.size(); np_noq += nbl.work->ncj_noq; np_hlj += nbl.work->ncj_hlj; } else { - const NbnxnPairlistGpu &nbl = gpuLists_[th]; + const NbnxnPairlistGpu& nbl = gpuLists_[th]; /* This count ignores potential subsequent pair pruning */ np_tot += nbl.nci_tot; } } if (isCpuType_) { - nap = cpuLists_[0].na_ci*cpuLists_[0].na_cj; + nap = cpuLists_[0].na_ci * cpuLists_[0].na_cj; } else { - nap = gmx::square(gpuLists_[0].na_ci); + nap = gmx::square(gpuLists_[0].na_ci); } - natpair_ljq_ = (np_tot - np_noq)*nap - np_hlj*nap/2; - natpair_lj_ = np_noq*nap; - natpair_q_ = np_hlj*nap/2; + natpair_ljq_ = (np_tot - np_noq) * nap - np_hlj * nap / 2; + natpair_lj_ = np_noq * nap; + natpair_q_ = np_hlj * nap / 2; if (combineLists_ && numLists > 1) { @@ -4210,8 +4095,7 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, searchCycleCounting->start(enbsCCcombine); - combine_nblists(gmx::constArrayRefFromArray(&gpuLists_[1], numLists - 1), - &gpuLists_[0]); + combine_nblists(gmx::constArrayRefFromArray(&gpuLists_[1], numLists - 1), &gpuLists_[0]); searchCycleCounting->stop(enbsCCcombine); } @@ -4244,7 +4128,7 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, { sort_sci(&gpuLists_[th]); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } } @@ -4275,7 +4159,7 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, { if (isCpuType_ && cpuLists_.size() > 1) { - for (auto &cpuList : cpuLists_) + for (auto& cpuList : cpuLists_) { print_nblist_statistics(debug, cpuList, gridSet, rlist); } @@ -4292,7 +4176,7 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, { if (isCpuType_) { - for (auto &cpuList : cpuLists_) + for (auto& cpuList : cpuLists_) { print_nblist_ci_cj(debug, cpuList); } @@ -4315,17 +4199,16 @@ PairlistSet::constructPairlists(const Nbnxm::GridSet &gridSet, } } -void -PairlistSets::construct(const InteractionLocality iLocality, - PairSearch *pairSearch, - nbnxn_atomdata_t *nbat, - const t_blocka *excl, - const int64_t step, - t_nrnb *nrnb) +void PairlistSets::construct(const InteractionLocality iLocality, + PairSearch* pairSearch, + nbnxn_atomdata_t* nbat, + const t_blocka* excl, + const int64_t step, + t_nrnb* nrnb) { - pairlistSet(iLocality).constructPairlists(pairSearch->gridSet(), pairSearch->work(), - nbat, excl, minimumIlistCountForGpuBalancing_, - nrnb, &pairSearch->cycleCounting_); + pairlistSet(iLocality).constructPairlists(pairSearch->gridSet(), pairSearch->work(), nbat, excl, + minimumIlistCountForGpuBalancing_, nrnb, + &pairSearch->cycleCounting_); if (iLocality == InteractionLocality::Local) { @@ -4342,22 +4225,20 @@ PairlistSets::construct(const InteractionLocality iLocality, { pairSearch->cycleCounting_.searchCount_++; } - if (pairSearch->cycleCounting_.recordCycles_ && - (!pairSearch->gridSet().domainSetup().haveMultipleDomains || iLocality == InteractionLocality::NonLocal) && - pairSearch->cycleCounting_.searchCount_ % 100 == 0) + if (pairSearch->cycleCounting_.recordCycles_ + && (!pairSearch->gridSet().domainSetup().haveMultipleDomains || iLocality == InteractionLocality::NonLocal) + && pairSearch->cycleCounting_.searchCount_ % 100 == 0) { pairSearch->cycleCounting_.printCycles(stderr, pairSearch->work()); } } -void -nonbonded_verlet_t::constructPairlist(const InteractionLocality iLocality, - const t_blocka *excl, - int64_t step, - t_nrnb *nrnb) +void nonbonded_verlet_t::constructPairlist(const InteractionLocality iLocality, + const t_blocka* excl, + int64_t step, + t_nrnb* nrnb) { - pairlistSets_->construct(iLocality, pairSearch_.get(), nbat.get(), excl, - step, nrnb); + pairlistSets_->construct(iLocality, pairSearch_.get(), nbat.get(), excl, step, nrnb); if (useGpu()) { @@ -4365,9 +4246,7 @@ nonbonded_verlet_t::constructPairlist(const InteractionLocality iLocality, * * NOTE: The launch overhead is currently not timed separately */ - Nbnxm::gpu_init_pairlist(gpu_nbv, - pairlistSets().pairlistSet(iLocality).gpuList(), - iLocality); + Nbnxm::gpu_init_pairlist(gpu_nbv, pairlistSets().pairlistSet(iLocality).gpuList(), iLocality); } } @@ -4378,7 +4257,7 @@ static void prepareListsForDynamicPruning(gmx::ArrayRef lists) * swapping several pointers. */ - for (auto &list : lists) + for (auto& list : lists) { /* The search produced a list in ci/cj. * Swap the list pointers so we get the outer list is ciOuter,cjOuter diff --git a/src/gromacs/nbnxm/pairlist.h b/src/gromacs/nbnxm/pairlist.h index 136a2f6c29..d59e488e44 100644 --- a/src/gromacs/nbnxm/pairlist.h +++ b/src/gromacs/nbnxm/pairlist.h @@ -58,18 +58,19 @@ struct NbnxnPairlistGpuWork; /* Convenience type for vector with aligned memory */ template -using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; +using AlignedVector = std::vector>; /* Convenience type for vector that avoids initialization at resize() */ template -using FastVector = std::vector < T, gmx::DefaultInitializationAllocator < T>>; +using FastVector = std::vector>; /* A buffer data structure of 64 bytes * to be placed at the beginning and end of structs * to avoid cache invalidation of the real contents * of the struct by writes to neighboring memory. */ -typedef struct { +typedef struct +{ int dummy[16]; } gmx_cache_protect_t; @@ -82,8 +83,8 @@ typedef struct { */ struct nbnxn_cj_t { - int cj; /* The j-cluster */ - unsigned int excl; /* The exclusion (interaction) bits */ + int cj; /* The j-cluster */ + unsigned int excl; /* The exclusion (interaction) bits */ }; /* In nbnxn_ci_t the integer shift contains the shift in the lower 7 bits. @@ -94,19 +95,19 @@ struct nbnxn_cj_t * shift & NBNXN_CI_HALF_LJ(subc) => we can skip LJ for the second half of i * !(shift & NBNXN_CI_DO_COUL(subc)) => we can skip Coulomb for all pairs */ -#define NBNXN_CI_SHIFT 127 -#define NBNXN_CI_DO_LJ(subc) (1<<(7+3*(subc))) -#define NBNXN_CI_HALF_LJ(subc) (1<<(8+3*(subc))) -#define NBNXN_CI_DO_COUL(subc) (1<<(9+3*(subc))) +#define NBNXN_CI_SHIFT 127 +#define NBNXN_CI_DO_LJ(subc) (1 << (7 + 3 * (subc))) +#define NBNXN_CI_HALF_LJ(subc) (1 << (8 + 3 * (subc))) +#define NBNXN_CI_DO_COUL(subc) (1 << (9 + 3 * (subc))) /* Cluster-pair Interaction masks * Bit i*j-cluster-size + j tells if atom i and j interact. */ // TODO: Rename according to convention when moving into Nbnxn namespace /* All interaction mask is the same for all kernels */ -constexpr unsigned int NBNXN_INTERACTION_MASK_ALL = 0xffffffffU; +constexpr unsigned int NBNXN_INTERACTION_MASK_ALL = 0xffffffffU; /* 4x4 kernel diagonal mask */ -constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG = 0x08ceU; +constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG = 0x08ceU; /* 4x2 kernel diagonal masks */ constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_0 = 0x0002U; constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J2_1 = 0x002fU; @@ -117,38 +118,37 @@ constexpr unsigned int NBNXN_INTERACTION_MASK_DIAG_J8_1 = 0x0080c0e0U; /* Simple pair-list i-unit */ struct nbnxn_ci_t { - int ci; /* i-cluster */ - int shift; /* Shift vector index plus possible flags, see above */ - int cj_ind_start; /* Start index into cj */ - int cj_ind_end; /* End index into cj */ + int ci; /* i-cluster */ + int shift; /* Shift vector index plus possible flags, see above */ + int cj_ind_start; /* Start index into cj */ + int cj_ind_end; /* End index into cj */ }; /* Grouped pair-list i-unit */ -typedef struct { +typedef struct +{ /* Returns the number of j-cluster groups in this entry */ - int numJClusterGroups() const - { - return cj4_ind_end - cj4_ind_start; - } + int numJClusterGroups() const { return cj4_ind_end - cj4_ind_start; } - int sci; /* i-super-cluster */ - int shift; /* Shift vector index plus possible flags */ - int cj4_ind_start; /* Start index into cj4 */ - int cj4_ind_end; /* End index into cj4 */ + int sci; /* i-super-cluster */ + int shift; /* Shift vector index plus possible flags */ + int cj4_ind_start; /* Start index into cj4 */ + int cj4_ind_end; /* End index into cj4 */ } nbnxn_sci_t; /* Interaction data for a j-group for one warp */ struct nbnxn_im_ei_t { // The i-cluster interactions mask for 1 warp - unsigned int imask = 0U; + unsigned int imask = 0U; // Index into the exclusion array for 1 warp, default index 0 which means no exclusions - int excl_ind = 0; + int excl_ind = 0; }; -typedef struct { +typedef struct +{ int cj[c_nbnxnGpuJgroupSize]; /* The 4 j-clusters */ - nbnxn_im_ei_t imei[c_nbnxnGpuClusterpairSplit]; /* The i-cluster mask data for 2 warps */ + nbnxn_im_ei_t imei[c_nbnxnGpuClusterpairSplit]; /* The i-cluster mask data for 2 warps */ } nbnxn_cj4_t; /* Struct for storing the atom-pair interaction bits for a cluster pair in a GPU pairlist */ @@ -157,7 +157,7 @@ struct nbnxn_excl_t /* Constructor, sets no exclusions, so all atom pairs interacting */ nbnxn_excl_t() { - for (unsigned int &pairEntry : pair) + for (unsigned int& pairEntry : pair) { pairEntry = NBNXN_INTERACTION_MASK_ALL; } @@ -172,24 +172,24 @@ struct NbnxnPairlistCpu { NbnxnPairlistCpu(); - gmx_cache_protect_t cp0; + gmx_cache_protect_t cp0; - int na_ci; /* The number of atoms per i-cluster */ - int na_cj; /* The number of atoms per j-cluster */ - real rlist; /* The radius for constructing the list */ - FastVector ci; /* The i-cluster list */ - FastVector ciOuter; /* The outer, unpruned i-cluster list */ + int na_ci; /* The number of atoms per i-cluster */ + int na_cj; /* The number of atoms per j-cluster */ + real rlist; /* The radius for constructing the list */ + FastVector ci; /* The i-cluster list */ + FastVector ciOuter; /* The outer, unpruned i-cluster list */ - FastVector cj; /* The j-cluster list, size ncj */ - FastVector cjOuter; /* The outer, unpruned j-cluster list */ - int ncjInUse; /* The number of j-clusters that are used by ci entries in this list, will be <= cj.size() */ + FastVector cj; /* The j-cluster list, size ncj */ + FastVector cjOuter; /* The outer, unpruned j-cluster list */ + int ncjInUse; /* The number of j-clusters that are used by ci entries in this list, will be <= cj.size() */ - int nci_tot; /* The total number of i clusters */ + int nci_tot; /* The total number of i clusters */ /* Working data storage for list construction */ std::unique_ptr work; - gmx_cache_protect_t cp1; + gmx_cache_protect_t cp1; }; /* Cluster pairlist type, with extra hierarchies, for on the GPU @@ -206,28 +206,28 @@ struct NbnxnPairlistGpu */ NbnxnPairlistGpu(gmx::PinningPolicy pinningPolicy); - gmx_cache_protect_t cp0; + gmx_cache_protect_t cp0; - int na_ci; /* The number of atoms per i-cluster */ - int na_cj; /* The number of atoms per j-cluster */ - int na_sc; /* The number of atoms per super cluster */ - real rlist; /* The radius for constructing the list */ + int na_ci; /* The number of atoms per i-cluster */ + int na_cj; /* The number of atoms per j-cluster */ + int na_sc; /* The number of atoms per super cluster */ + real rlist; /* The radius for constructing the list */ // The i-super-cluster list, indexes into cj4; - gmx::HostVector sci; + gmx::HostVector sci; // The list of 4*j-cluster groups - gmx::HostVector cj4; + gmx::HostVector cj4; // Atom interaction bits (non-exclusions) - gmx::HostVector excl; + gmx::HostVector excl; // The total number of i-clusters - int nci_tot; + int nci_tot; /* Working data storage for list construction */ std::unique_ptr work; - gmx_cache_protect_t cp1; + gmx_cache_protect_t cp1; }; //! Initializes a free-energy pair-list -void nbnxn_init_pairlist_fep(t_nblist *nl); +void nbnxn_init_pairlist_fep(t_nblist* nl); #endif diff --git a/src/gromacs/nbnxm/pairlist_simd_2xmm.h b/src/gromacs/nbnxm/pairlist_simd_2xmm.h index d79a72b216..fb6302028b 100644 --- a/src/gromacs/nbnxm/pairlist_simd_2xmm.h +++ b/src/gromacs/nbnxm/pairlist_simd_2xmm.h @@ -37,23 +37,31 @@ static constexpr int c_xStride2xNN = c_nbnxnCpuIClusterSize; /* Copies PBC shifted i-cell packed atom coordinates to working array */ -static inline void -icell_set_x_simd_2xnn(int ci, - real shx, real shy, real shz, - int gmx_unused stride, const real *x, - NbnxnPairlistCpuWork *work) +static inline void icell_set_x_simd_2xnn(int ci, + real shx, + real shy, + real shz, + int gmx_unused stride, + const real* x, + NbnxnPairlistCpuWork* work) { int ia; - real *x_ci_simd = work->iClusterData.xSimd.data(); + real* x_ci_simd = work->iClusterData.xSimd.data(); ia = xIndexFromCi(ci); - store(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 0*c_xStride2xNN + 0) + SimdReal(shx) ); - store(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 1*c_xStride2xNN + 0) + SimdReal(shy) ); - store(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 2*c_xStride2xNN + 0) + SimdReal(shz) ); - store(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 0*c_xStride2xNN + 2) + SimdReal(shx) ); - store(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 1*c_xStride2xNN + 2) + SimdReal(shy) ); - store(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH, loadU1DualHsimd(x + ia + 2*c_xStride2xNN + 2) + SimdReal(shz) ); + store(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 0 * c_xStride2xNN + 0) + SimdReal(shx)); + store(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 1 * c_xStride2xNN + 0) + SimdReal(shy)); + store(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 2 * c_xStride2xNN + 0) + SimdReal(shz)); + store(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 0 * c_xStride2xNN + 2) + SimdReal(shx)); + store(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 1 * c_xStride2xNN + 2) + SimdReal(shy)); + store(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH, + loadU1DualHsimd(x + ia + 2 * c_xStride2xNN + 2) + SimdReal(shz)); } /* SIMD code for checking and adding cluster-pairs to the list using coordinates in packed format. @@ -72,50 +80,51 @@ icell_set_x_simd_2xnn(int ci, * \param[in] rbb2 The squared cut-off for putting cluster-pairs in the list based on bounding box distance only * \param[in,out] numDistanceChecks The number of distance checks performed */ -static inline void -makeClusterListSimd2xnn(const Grid &jGrid, - NbnxnPairlistCpu * nbl, - int icluster, - int firstCell, - int lastCell, - bool excludeSubDiagonal, - const real * gmx_restrict x_j, - real rlist2, - float rbb2, - int * gmx_restrict numDistanceChecks) +static inline void makeClusterListSimd2xnn(const Grid& jGrid, + NbnxnPairlistCpu* nbl, + int icluster, + int firstCell, + int lastCell, + bool excludeSubDiagonal, + const real* gmx_restrict x_j, + real rlist2, + float rbb2, + int* gmx_restrict numDistanceChecks) { using namespace gmx; - const real * gmx_restrict x_ci_simd = nbl->work->iClusterData.xSimd.data(); - const BoundingBox * gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); + const real* gmx_restrict x_ci_simd = nbl->work->iClusterData.xSimd.data(); + const BoundingBox* gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); - SimdReal jx_S, jy_S, jz_S; + SimdReal jx_S, jy_S, jz_S; - SimdReal dx_S0, dy_S0, dz_S0; - SimdReal dx_S2, dy_S2, dz_S2; + SimdReal dx_S0, dy_S0, dz_S0; + SimdReal dx_S2, dy_S2, dz_S2; - SimdReal rsq_S0; - SimdReal rsq_S2; + SimdReal rsq_S0; + SimdReal rsq_S2; - SimdBool wco_S0; - SimdBool wco_S2; - SimdBool wco_any_S; + SimdBool wco_S0; + SimdBool wco_S2; + SimdBool wco_any_S; - SimdReal rc2_S; + SimdReal rc2_S; - gmx_bool InRange; - float d2; - int xind_f, xind_l; + gmx_bool InRange; + float d2; + int xind_f, xind_l; int jclusterFirst = cjFromCi(firstCell); int jclusterLast = cjFromCi(lastCell); - GMX_ASSERT(jclusterLast >= jclusterFirst, "We should have a non-empty j-cluster range, since the calling code should have ensured a non-empty cell range"); + GMX_ASSERT(jclusterLast >= jclusterFirst, + "We should have a non-empty j-cluster range, since the calling code should have " + "ensured a non-empty cell range"); - rc2_S = SimdReal(rlist2); + rc2_S = SimdReal(rlist2); InRange = FALSE; while (!InRange && jclusterFirst <= jclusterLast) { - d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); + d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -129,32 +138,33 @@ makeClusterListSimd2xnn(const Grid &jGrid, } else if (d2 < rlist2) { - xind_f = xIndexFromCj(cjFromCi(jGrid.cellOffset()) + jclusterFirst); + xind_f = xIndexFromCj( + cjFromCi(jGrid.cellOffset()) + jclusterFirst); - jx_S = loadDuplicateHsimd(x_j + xind_f + 0*c_xStride2xNN); - jy_S = loadDuplicateHsimd(x_j + xind_f + 1*c_xStride2xNN); - jz_S = loadDuplicateHsimd(x_j + xind_f + 2*c_xStride2xNN); + jx_S = loadDuplicateHsimd(x_j + xind_f + 0 * c_xStride2xNN); + jy_S = loadDuplicateHsimd(x_j + xind_f + 1 * c_xStride2xNN); + jz_S = loadDuplicateHsimd(x_j + xind_f + 2 * c_xStride2xNN); /* Calculate distance */ - dx_S0 = load(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S0 = load(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S0 = load(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S2 = load(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S2 = load(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S2 = load(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S0 = load(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S0 = load(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S0 = load(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S2 = load(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S2 = load(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S2 = load(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH) - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); - wco_S0 = (rsq_S0 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); - wco_any_S = wco_S0 || wco_S2; + wco_any_S = wco_S0 || wco_S2; - InRange = anyTrue(wco_any_S); + InRange = anyTrue(wco_any_S); - *numDistanceChecks += 2*GMX_SIMD_REAL_WIDTH; + *numDistanceChecks += 2 * GMX_SIMD_REAL_WIDTH; } if (!InRange) { @@ -169,7 +179,7 @@ makeClusterListSimd2xnn(const Grid &jGrid, InRange = FALSE; while (!InRange && jclusterLast > jclusterFirst) { - d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); + d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -183,32 +193,33 @@ makeClusterListSimd2xnn(const Grid &jGrid, } else if (d2 < rlist2) { - xind_l = xIndexFromCj(cjFromCi(jGrid.cellOffset()) + jclusterLast); + xind_l = xIndexFromCj( + cjFromCi(jGrid.cellOffset()) + jclusterLast); - jx_S = loadDuplicateHsimd(x_j + xind_l + 0*c_xStride2xNN); - jy_S = loadDuplicateHsimd(x_j + xind_l + 1*c_xStride2xNN); - jz_S = loadDuplicateHsimd(x_j + xind_l + 2*c_xStride2xNN); + jx_S = loadDuplicateHsimd(x_j + xind_l + 0 * c_xStride2xNN); + jy_S = loadDuplicateHsimd(x_j + xind_l + 1 * c_xStride2xNN); + jz_S = loadDuplicateHsimd(x_j + xind_l + 2 * c_xStride2xNN); /* Calculate distance */ - dx_S0 = load(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S0 = load(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S0 = load(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S2 = load(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S2 = load(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S2 = load(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S0 = load(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S0 = load(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S0 = load(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S2 = load(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S2 = load(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S2 = load(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH) - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); - wco_S0 = (rsq_S0 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); - wco_any_S = wco_S0 || wco_S2; + wco_any_S = wco_S0 || wco_S2; - InRange = anyTrue(wco_any_S); + InRange = anyTrue(wco_any_S); - *numDistanceChecks += 2*GMX_SIMD_REAL_WIDTH; + *numDistanceChecks += 2 * GMX_SIMD_REAL_WIDTH; } if (!InRange) { diff --git a/src/gromacs/nbnxm/pairlist_simd_4xm.h b/src/gromacs/nbnxm/pairlist_simd_4xm.h index e87d327c00..1cadfff932 100644 --- a/src/gromacs/nbnxm/pairlist_simd_4xm.h +++ b/src/gromacs/nbnxm/pairlist_simd_4xm.h @@ -34,32 +34,35 @@ */ /* Stride of the packed x coordinate array */ -static constexpr int c_xStride4xN = (GMX_SIMD_REAL_WIDTH > c_nbnxnCpuIClusterSize ? GMX_SIMD_REAL_WIDTH : c_nbnxnCpuIClusterSize); +static constexpr int c_xStride4xN = + (GMX_SIMD_REAL_WIDTH > c_nbnxnCpuIClusterSize ? GMX_SIMD_REAL_WIDTH : c_nbnxnCpuIClusterSize); /* Copies PBC shifted i-cell packed atom coordinates to working array */ -static inline void -icell_set_x_simd_4xn(int ci, - real shx, real shy, real shz, - int gmx_unused stride, const real *x, - NbnxnPairlistCpuWork *work) +static inline void icell_set_x_simd_4xn(int ci, + real shx, + real shy, + real shz, + int gmx_unused stride, + const real* x, + NbnxnPairlistCpuWork* work) { - int ia; - real *x_ci_simd = work->iClusterData.xSimd.data(); + int ia; + real* x_ci_simd = work->iClusterData.xSimd.data(); ia = xIndexFromCi(ci); - store(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0*c_xStride4xN ] + shx) ); - store(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1*c_xStride4xN ] + shy) ); - store(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2*c_xStride4xN ] + shz) ); - store(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0*c_xStride4xN + 1] + shx) ); - store(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1*c_xStride4xN + 1] + shy) ); - store(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2*c_xStride4xN + 1] + shz) ); - store(x_ci_simd + 6*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0*c_xStride4xN + 2] + shx) ); - store(x_ci_simd + 7*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1*c_xStride4xN + 2] + shy) ); - store(x_ci_simd + 8*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2*c_xStride4xN + 2] + shz) ); - store(x_ci_simd + 9*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0*c_xStride4xN + 3] + shx) ); - store(x_ci_simd + 10*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1*c_xStride4xN + 3] + shy) ); - store(x_ci_simd + 11*GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2*c_xStride4xN + 3] + shz) ); + store(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0 * c_xStride4xN] + shx)); + store(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1 * c_xStride4xN] + shy)); + store(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2 * c_xStride4xN] + shz)); + store(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0 * c_xStride4xN + 1] + shx)); + store(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1 * c_xStride4xN + 1] + shy)); + store(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2 * c_xStride4xN + 1] + shz)); + store(x_ci_simd + 6 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0 * c_xStride4xN + 2] + shx)); + store(x_ci_simd + 7 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1 * c_xStride4xN + 2] + shy)); + store(x_ci_simd + 8 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2 * c_xStride4xN + 2] + shz)); + store(x_ci_simd + 9 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 0 * c_xStride4xN + 3] + shx)); + store(x_ci_simd + 10 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 1 * c_xStride4xN + 3] + shy)); + store(x_ci_simd + 11 * GMX_SIMD_REAL_WIDTH, SimdReal(x[ia + 2 * c_xStride4xN + 3] + shz)); } /* SIMD code for checking and adding cluster-pairs to the list using coordinates in packed format. @@ -78,57 +81,58 @@ icell_set_x_simd_4xn(int ci, * \param[in] rbb2 The squared cut-off for putting cluster-pairs in the list based on bounding box distance only * \param[in,out] numDistanceChecks The number of distance checks performed */ -static inline void -makeClusterListSimd4xn(const Grid &jGrid, - NbnxnPairlistCpu * nbl, - int icluster, - int firstCell, - int lastCell, - bool excludeSubDiagonal, - const real * gmx_restrict x_j, - real rlist2, - float rbb2, - int * gmx_restrict numDistanceChecks) +static inline void makeClusterListSimd4xn(const Grid& jGrid, + NbnxnPairlistCpu* nbl, + int icluster, + int firstCell, + int lastCell, + bool excludeSubDiagonal, + const real* gmx_restrict x_j, + real rlist2, + float rbb2, + int* gmx_restrict numDistanceChecks) { using namespace gmx; - const real * gmx_restrict x_ci_simd = nbl->work->iClusterData.xSimd.data(); - const BoundingBox * gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); + const real* gmx_restrict x_ci_simd = nbl->work->iClusterData.xSimd.data(); + const BoundingBox* gmx_restrict bb_ci = nbl->work->iClusterData.bb.data(); - SimdReal jx_S, jy_S, jz_S; + SimdReal jx_S, jy_S, jz_S; - SimdReal dx_S0, dy_S0, dz_S0; - SimdReal dx_S1, dy_S1, dz_S1; - SimdReal dx_S2, dy_S2, dz_S2; - SimdReal dx_S3, dy_S3, dz_S3; + SimdReal dx_S0, dy_S0, dz_S0; + SimdReal dx_S1, dy_S1, dz_S1; + SimdReal dx_S2, dy_S2, dz_S2; + SimdReal dx_S3, dy_S3, dz_S3; - SimdReal rsq_S0; - SimdReal rsq_S1; - SimdReal rsq_S2; - SimdReal rsq_S3; + SimdReal rsq_S0; + SimdReal rsq_S1; + SimdReal rsq_S2; + SimdReal rsq_S3; - SimdBool wco_S0; - SimdBool wco_S1; - SimdBool wco_S2; - SimdBool wco_S3; - SimdBool wco_any_S01, wco_any_S23, wco_any_S; + SimdBool wco_S0; + SimdBool wco_S1; + SimdBool wco_S2; + SimdBool wco_S3; + SimdBool wco_any_S01, wco_any_S23, wco_any_S; - SimdReal rc2_S; + SimdReal rc2_S; - gmx_bool InRange; - float d2; - int xind_f, xind_l; + gmx_bool InRange; + float d2; + int xind_f, xind_l; /* Convert the j-range from i-cluster size indexing to j-cluster indexing */ int jclusterFirst = cjFromCi(firstCell); int jclusterLast = cjFromCi(lastCell); - GMX_ASSERT(jclusterLast >= jclusterFirst, "We should have a non-empty j-cluster range, since the calling code should have ensured a non-empty cell range"); + GMX_ASSERT(jclusterLast >= jclusterFirst, + "We should have a non-empty j-cluster range, since the calling code should have " + "ensured a non-empty cell range"); - rc2_S = SimdReal(rlist2); + rc2_S = SimdReal(rlist2); InRange = FALSE; while (!InRange && jclusterFirst <= jclusterLast) { - d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); + d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterFirst]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -142,45 +146,46 @@ makeClusterListSimd4xn(const Grid &jGrid, } else if (d2 < rlist2) { - xind_f = xIndexFromCj(cjFromCi(jGrid.cellOffset()) + jclusterFirst); + xind_f = xIndexFromCj( + cjFromCi(jGrid.cellOffset()) + jclusterFirst); - jx_S = load(x_j + xind_f + 0*c_xStride4xN); - jy_S = load(x_j + xind_f + 1*c_xStride4xN); - jz_S = load(x_j + xind_f + 2*c_xStride4xN); + jx_S = load(x_j + xind_f + 0 * c_xStride4xN); + jy_S = load(x_j + xind_f + 1 * c_xStride4xN); + jz_S = load(x_j + xind_f + 2 * c_xStride4xN); /* Calculate distance */ - dx_S0 = load(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S0 = load(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S0 = load(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S1 = load(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S1 = load(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S1 = load(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S2 = load(x_ci_simd + 6*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S2 = load(x_ci_simd + 7*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S2 = load(x_ci_simd + 8*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S3 = load(x_ci_simd + 9*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S3 = load(x_ci_simd + 10*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S3 = load(x_ci_simd + 11*GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S0 = load(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S0 = load(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S0 = load(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S1 = load(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S1 = load(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S1 = load(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S2 = load(x_ci_simd + 6 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S2 = load(x_ci_simd + 7 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S2 = load(x_ci_simd + 8 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S3 = load(x_ci_simd + 9 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S3 = load(x_ci_simd + 10 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S3 = load(x_ci_simd + 11 * GMX_SIMD_REAL_WIDTH) - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); - rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); - wco_S0 = (rsq_S0 < rc2_S); - wco_S1 = (rsq_S1 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); - wco_S3 = (rsq_S3 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S1 = (rsq_S1 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); + wco_S3 = (rsq_S3 < rc2_S); - wco_any_S01 = wco_S0 || wco_S1; - wco_any_S23 = wco_S2 || wco_S3; - wco_any_S = wco_any_S01 || wco_any_S23; + wco_any_S01 = wco_S0 || wco_S1; + wco_any_S23 = wco_S2 || wco_S3; + wco_any_S = wco_any_S01 || wco_any_S23; - InRange = anyTrue(wco_any_S); + InRange = anyTrue(wco_any_S); - *numDistanceChecks += 4*GMX_SIMD_REAL_WIDTH; + *numDistanceChecks += 4 * GMX_SIMD_REAL_WIDTH; } if (!InRange) { @@ -195,7 +200,7 @@ makeClusterListSimd4xn(const Grid &jGrid, InRange = FALSE; while (!InRange && jclusterLast > jclusterFirst) { - d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); + d2 = clusterBoundingBoxDistance2(bb_ci[0], jGrid.jBoundingBoxes()[jclusterLast]); *numDistanceChecks += 2; /* Check if the distance is within the distance where @@ -209,44 +214,45 @@ makeClusterListSimd4xn(const Grid &jGrid, } else if (d2 < rlist2) { - xind_l = xIndexFromCj(cjFromCi(jGrid.cellOffset()) + jclusterLast); + xind_l = xIndexFromCj( + cjFromCi(jGrid.cellOffset()) + jclusterLast); - jx_S = load(x_j +xind_l + 0*c_xStride4xN); - jy_S = load(x_j +xind_l + 1*c_xStride4xN); - jz_S = load(x_j +xind_l + 2*c_xStride4xN); + jx_S = load(x_j + xind_l + 0 * c_xStride4xN); + jy_S = load(x_j + xind_l + 1 * c_xStride4xN); + jz_S = load(x_j + xind_l + 2 * c_xStride4xN); /* Calculate distance */ - dx_S0 = load(x_ci_simd + 0*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S0 = load(x_ci_simd + 1*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S0 = load(x_ci_simd + 2*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S1 = load(x_ci_simd + 3*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S1 = load(x_ci_simd + 4*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S1 = load(x_ci_simd + 5*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S2 = load(x_ci_simd + 6*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S2 = load(x_ci_simd + 7*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S2 = load(x_ci_simd + 8*GMX_SIMD_REAL_WIDTH) - jz_S; - dx_S3 = load(x_ci_simd + 9*GMX_SIMD_REAL_WIDTH) - jx_S; - dy_S3 = load(x_ci_simd + 10*GMX_SIMD_REAL_WIDTH) - jy_S; - dz_S3 = load(x_ci_simd + 11*GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S0 = load(x_ci_simd + 0 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S0 = load(x_ci_simd + 1 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S0 = load(x_ci_simd + 2 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S1 = load(x_ci_simd + 3 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S1 = load(x_ci_simd + 4 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S1 = load(x_ci_simd + 5 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S2 = load(x_ci_simd + 6 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S2 = load(x_ci_simd + 7 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S2 = load(x_ci_simd + 8 * GMX_SIMD_REAL_WIDTH) - jz_S; + dx_S3 = load(x_ci_simd + 9 * GMX_SIMD_REAL_WIDTH) - jx_S; + dy_S3 = load(x_ci_simd + 10 * GMX_SIMD_REAL_WIDTH) - jy_S; + dz_S3 = load(x_ci_simd + 11 * GMX_SIMD_REAL_WIDTH) - jz_S; /* rsq = dx*dx+dy*dy+dz*dz */ - rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); - rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); - rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); - rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); + rsq_S0 = norm2(dx_S0, dy_S0, dz_S0); + rsq_S1 = norm2(dx_S1, dy_S1, dz_S1); + rsq_S2 = norm2(dx_S2, dy_S2, dz_S2); + rsq_S3 = norm2(dx_S3, dy_S3, dz_S3); - wco_S0 = (rsq_S0 < rc2_S); - wco_S1 = (rsq_S1 < rc2_S); - wco_S2 = (rsq_S2 < rc2_S); - wco_S3 = (rsq_S3 < rc2_S); + wco_S0 = (rsq_S0 < rc2_S); + wco_S1 = (rsq_S1 < rc2_S); + wco_S2 = (rsq_S2 < rc2_S); + wco_S3 = (rsq_S3 < rc2_S); - wco_any_S01 = wco_S0 || wco_S1; - wco_any_S23 = wco_S2 || wco_S3; - wco_any_S = wco_any_S01 || wco_any_S23; + wco_any_S01 = wco_S0 || wco_S1; + wco_any_S23 = wco_S2 || wco_S3; + wco_any_S = wco_any_S01 || wco_any_S23; - InRange = anyTrue(wco_any_S); + InRange = anyTrue(wco_any_S); - *numDistanceChecks += 4*GMX_SIMD_REAL_WIDTH; + *numDistanceChecks += 4 * GMX_SIMD_REAL_WIDTH; } if (!InRange) { diff --git a/src/gromacs/nbnxm/pairlist_tuning.cpp b/src/gromacs/nbnxm/pairlist_tuning.cpp index d8a8859be8..c997ba8709 100644 --- a/src/gromacs/nbnxm/pairlist_tuning.cpp +++ b/src/gromacs/nbnxm/pairlist_tuning.cpp @@ -76,13 +76,10 @@ * * \param [in] ir The input parameter record */ -static bool supportsDynamicPairlistGenerationInterval(const t_inputrec &ir) +static bool supportsDynamicPairlistGenerationInterval(const t_inputrec& ir) { - return - ir.cutoff_scheme == ecutsVERLET && - EI_DYNAMICS(ir.eI) && - !(EI_MD(ir.eI) && ir.etc == etcNO) && - ir.verletbuf_tol > 0; + return ir.cutoff_scheme == ecutsVERLET && EI_DYNAMICS(ir.eI) + && !(EI_MD(ir.eI) && ir.etc == etcNO) && ir.verletbuf_tol > 0; } /*! \brief Cost of non-bonded kernels @@ -90,11 +87,11 @@ static bool supportsDynamicPairlistGenerationInterval(const t_inputrec &ir) * We determine the extra cost of the non-bonded kernels compared to * a reference nstlist value of 10 (which is the default in grompp). */ -static const int nbnxnReferenceNstlist = 10; +static const int nbnxnReferenceNstlist = 10; //! The values to try when switching -const int nstlist_try[] = { 20, 25, 40, 50, 80, 100 }; +const int nstlist_try[] = { 20, 25, 40, 50, 80, 100 }; //! Number of elements in the neighborsearch list trials. -#define NNSTL (sizeof(nstlist_try)/sizeof(nstlist_try[0])) +#define NNSTL (sizeof(nstlist_try) / sizeof(nstlist_try[0])) /* Increase nstlist until the size of the pair-list increased by * \p c_nbnxnListSizeFactor??? or more, but never more than * \p c_nbnxnListSizeFactor??? + \p c_nbnxnListSizeFactorMargin. @@ -113,22 +110,24 @@ const int nstlist_try[] = { 20, 25, 40, 50, 80, 100 }; */ // CPU: pair-search is a factor ~1.5 slower than the non-bonded kernel. //! Target pair-list size increase ratio for CPU -static const float c_nbnxnListSizeFactorCpu = 1.25; +static const float c_nbnxnListSizeFactorCpu = 1.25; // Intel KNL: pair-search is a factor ~2-3 slower than the non-bonded kernel. //! Target pair-list size increase ratio for Intel KNL -static const float c_nbnxnListSizeFactorIntelXeonPhi = 1.4; +static const float c_nbnxnListSizeFactorIntelXeonPhi = 1.4; // GPU: pair-search is a factor 1.5-3 slower than the non-bonded kernel. //! Target pair-list size increase ratio for GPU -static const float c_nbnxnListSizeFactorGPU = 1.4; +static const float c_nbnxnListSizeFactorGPU = 1.4; //! Never increase the size of the pair-list more than the factor above plus this margin -static const float c_nbnxnListSizeFactorMargin = 0.1; - -void increaseNstlist(FILE *fp, t_commrec *cr, - t_inputrec *ir, int nstlist_cmdline, - const gmx_mtop_t *mtop, - const matrix box, - bool useOrEmulateGpuForNonbondeds, - const gmx::CpuInfo &cpuinfo) +static const float c_nbnxnListSizeFactorMargin = 0.1; + +void increaseNstlist(FILE* fp, + t_commrec* cr, + t_inputrec* ir, + int nstlist_cmdline, + const gmx_mtop_t* mtop, + const matrix box, + bool useOrEmulateGpuForNonbondeds, + const gmx::CpuInfo& cpuinfo) { if (!EI_DYNAMICS(ir->eI)) { @@ -136,18 +135,22 @@ void increaseNstlist(FILE *fp, t_commrec *cr, return; } - float listfac_ok, listfac_max; - int nstlist_orig, nstlist_prev; - real rlist_inc, rlist_ok, rlist_max; - real rlist_new, rlist_prev; - size_t nstlist_ind = 0; - gmx_bool bBox, bDD, bCont; - const char *nstl_gpu = "\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe optimum depends on your CPU and GPU resources.\nYou might want to try several nstlist values.\n"; - const char *nve_err = "Can not increase nstlist because an NVE ensemble is used"; - const char *vbd_err = "Can not increase nstlist because verlet-buffer-tolerance is not set or used"; - const char *box_err = "Can not increase nstlist because the box is too small"; - const char *dd_err = "Can not increase nstlist because of domain decomposition limitations"; - char buf[STRLEN]; + float listfac_ok, listfac_max; + int nstlist_orig, nstlist_prev; + real rlist_inc, rlist_ok, rlist_max; + real rlist_new, rlist_prev; + size_t nstlist_ind = 0; + gmx_bool bBox, bDD, bCont; + const char* nstl_gpu = + "\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe " + "optimum depends on your CPU and GPU resources.\nYou might want to try several " + "nstlist values.\n"; + const char* nve_err = "Can not increase nstlist because an NVE ensemble is used"; + const char* vbd_err = + "Can not increase nstlist because verlet-buffer-tolerance is not set or used"; + const char* box_err = "Can not increase nstlist because the box is too small"; + const char* dd_err = "Can not increase nstlist because of domain decomposition limitations"; + char buf[STRLEN]; if (nstlist_cmdline <= 0) { @@ -160,10 +163,8 @@ void increaseNstlist(FILE *fp, t_commrec *cr, } /* With a GPU and fixed nstlist suggest tuning nstlist */ - if (fp != nullptr && - useOrEmulateGpuForNonbondeds && - ir->nstlist < nstlist_try[0] && - !supportsDynamicPairlistGenerationInterval(*ir)) + if (fp != nullptr && useOrEmulateGpuForNonbondeds && ir->nstlist < nstlist_try[0] + && !supportsDynamicPairlistGenerationInterval(*ir)) { fprintf(fp, nstl_gpu, ir->nstlist); } @@ -196,7 +197,9 @@ void increaseNstlist(FILE *fp, t_commrec *cr, if (ir->verletbuf_tol == 0 && useOrEmulateGpuForNonbondeds) { - gmx_fatal(FARGS, "You are using an old tpr file with a GPU, please generate a new tpr file with an up to date version of grompp"); + gmx_fatal(FARGS, + "You are using an old tpr file with a GPU, please generate a new tpr file with " + "an up to date version of grompp"); } if (ir->verletbuf_tol < 0) @@ -213,34 +216,36 @@ void increaseNstlist(FILE *fp, t_commrec *cr, return; } - GMX_RELEASE_ASSERT(supportsDynamicPairlistGenerationInterval(*ir), "In all cases that do not support dynamic nstlist, we should have returned with an appropriate message above"); + GMX_RELEASE_ASSERT(supportsDynamicPairlistGenerationInterval(*ir), + "In all cases that do not support dynamic nstlist, we should have returned " + "with an appropriate message above"); if (useOrEmulateGpuForNonbondeds) { - listfac_ok = c_nbnxnListSizeFactorGPU; + listfac_ok = c_nbnxnListSizeFactorGPU; } else if (cpuinfo.brandString().find("Xeon Phi") != std::string::npos) { - listfac_ok = c_nbnxnListSizeFactorIntelXeonPhi; + listfac_ok = c_nbnxnListSizeFactorIntelXeonPhi; } else { - listfac_ok = c_nbnxnListSizeFactorCpu; + listfac_ok = c_nbnxnListSizeFactorCpu; } - listfac_max = listfac_ok + c_nbnxnListSizeFactorMargin; + listfac_max = listfac_ok + c_nbnxnListSizeFactorMargin; - nstlist_orig = ir->nstlist; + nstlist_orig = ir->nstlist; if (nstlist_cmdline > 0) { if (fp) { - sprintf(buf, "Getting nstlist=%d from command line option", - nstlist_cmdline); + sprintf(buf, "Getting nstlist=%d from command line option", nstlist_cmdline); } ir->nstlist = nstlist_cmdline; } - ListSetupType listType = (useOrEmulateGpuForNonbondeds ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); + ListSetupType listType = + (useOrEmulateGpuForNonbondeds ? ListSetupType::Gpu : ListSetupType::CpuSimdWhenSupported); VerletbufListSetup listSetup = verletbufGetSafeListSetup(listType); /* Allow rlist to make the list a given factor larger than the list @@ -249,19 +254,17 @@ void increaseNstlist(FILE *fp, t_commrec *cr, nstlist_prev = ir->nstlist; ir->nstlist = nbnxnReferenceNstlist; const real rlistWithReferenceNstlist = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, - -1, listSetup); - ir->nstlist = nstlist_prev; + calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup); + ir->nstlist = nstlist_prev; /* Determine the pair list size increase due to zero interactions */ - rlist_inc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, - mtop->natoms/det(box)); - rlist_ok = (rlistWithReferenceNstlist + rlist_inc)*std::cbrt(listfac_ok) - rlist_inc; - rlist_max = (rlistWithReferenceNstlist + rlist_inc)*std::cbrt(listfac_max) - rlist_inc; + rlist_inc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, mtop->natoms / det(box)); + rlist_ok = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_ok) - rlist_inc; + rlist_max = (rlistWithReferenceNstlist + rlist_inc) * std::cbrt(listfac_max) - rlist_inc; if (debug) { - fprintf(debug, "nstlist tuning: rlist_inc %.3f rlist_ok %.3f rlist_max %.3f\n", - rlist_inc, rlist_ok, rlist_max); + fprintf(debug, "nstlist tuning: rlist_inc %.3f rlist_ok %.3f rlist_max %.3f\n", rlist_inc, + rlist_ok, rlist_max); } nstlist_prev = nstlist_orig; @@ -274,8 +277,7 @@ void increaseNstlist(FILE *fp, t_commrec *cr, } /* Set the pair-list buffer size in ir */ - rlist_new = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup); + rlist_new = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, -1, listSetup); /* Does rlist fit in the box? */ bBox = (gmx::square(rlist_new) < max_cutoff2(ir->ePBC, box)); @@ -285,15 +287,17 @@ void increaseNstlist(FILE *fp, t_commrec *cr, /* Check if rlist fits in the domain decomposition */ if (inputrec2nboundeddim(ir) < DIM) { - gmx_incons("Changing nstlist with domain decomposition and unbounded dimensions is not implemented yet"); + gmx_incons( + "Changing nstlist with domain decomposition and unbounded dimensions is " + "not implemented yet"); } bDD = change_dd_cutoff(cr, box, gmx::ArrayRef(), rlist_new); } if (debug) { - fprintf(debug, "nstlist %d rlist %.3f bBox %s bDD %s\n", - ir->nstlist, rlist_new, gmx::boolToString(bBox), gmx::boolToString(bDD)); + fprintf(debug, "nstlist %d rlist %.3f bBox %s bDD %s\n", ir->nstlist, rlist_new, + gmx::boolToString(bBox), gmx::boolToString(bDD)); } bCont = FALSE; @@ -305,7 +309,7 @@ void increaseNstlist(FILE *fp, t_commrec *cr, /* Increase nstlist */ nstlist_prev = ir->nstlist; rlist_prev = rlist_new; - bCont = (nstlist_ind+1 < NNSTL && rlist_new < rlist_ok); + bCont = (nstlist_ind + 1 < NNSTL && rlist_new < rlist_ok); } else { @@ -318,8 +322,7 @@ void increaseNstlist(FILE *fp, t_commrec *cr, } nstlist_ind++; - } - while (bCont); + } while (bCont); if (!bBox || !bDD) { @@ -332,9 +335,8 @@ void increaseNstlist(FILE *fp, t_commrec *cr, } else if (ir->nstlist != nstlist_orig || rlist_new != ir->rlist) { - sprintf(buf, "Changing nstlist from %d to %d, rlist from %g to %g", - nstlist_orig, ir->nstlist, - ir->rlist, rlist_new); + sprintf(buf, "Changing nstlist from %d to %d, rlist from %g to %g", nstlist_orig, + ir->nstlist, ir->rlist, rlist_new); if (MASTER(cr)) { fprintf(stderr, "%s\n\n", buf); @@ -343,7 +345,7 @@ void increaseNstlist(FILE *fp, t_commrec *cr, { fprintf(fp, "%s\n\n", buf); } - ir->rlist = rlist_new; + ir->rlist = rlist_new; } } @@ -378,15 +380,14 @@ static const int c_nbnxnDynamicListPruningMinLifetime = 4; * \param[in] ic The nonbonded interactions constants * \param[in,out] listParams The list setup parameters */ -static void -setDynamicPairlistPruningParameters(const t_inputrec *ir, - const gmx_mtop_t *mtop, - const matrix box, - const bool useGpuList, - const VerletbufListSetup &listSetup, - const bool userSetNstlistPrune, - const interaction_const_t *ic, - PairlistParams *listParams) +static void setDynamicPairlistPruningParameters(const t_inputrec* ir, + const gmx_mtop_t* mtop, + const matrix box, + const bool useGpuList, + const VerletbufListSetup& listSetup, + const bool userSetNstlistPrune, + const interaction_const_t* ic, + PairlistParams* listParams) { listParams->lifetime = ir->nstlist - 1; @@ -405,20 +406,16 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, */ int listLifetime = tunedNstlistPrune - (useGpuList ? 0 : 1); listParams->nstlistPrune = tunedNstlistPrune; - listParams->rlistInner = - calcVerletBufferSize(*mtop, det(box), *ir, - tunedNstlistPrune, listLifetime, - -1, listSetup); + listParams->rlistInner = calcVerletBufferSize(*mtop, det(box), *ir, tunedNstlistPrune, + listLifetime, -1, listSetup); /* On the GPU we apply the dynamic pruning in a rolling fashion * every c_nbnxnGpuRollingListPruningInterval steps, * so keep nstlistPrune a multiple of the interval. */ tunedNstlistPrune += useGpuList ? c_nbnxnGpuRollingListPruningInterval : 1; - } - while (!userSetNstlistPrune && - tunedNstlistPrune < ir->nstlist && - listParams->rlistInner == interactionCutoff); + } while (!userSetNstlistPrune && tunedNstlistPrune < ir->nstlist + && listParams->rlistInner == interactionCutoff); if (userSetNstlistPrune) { @@ -427,8 +424,7 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, else { /* Determine the pair list size increase due to zero interactions */ - real rlistInc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, - mtop->natoms/det(box)); + real rlistInc = nbnxn_get_rlist_effective_inc(listSetup.cluster_size_j, mtop->natoms / det(box)); /* Dynamic pruning is only useful when the inner list is smaller than * the outer. The factor 0.99 ensures at least 3% list size reduction. @@ -440,15 +436,15 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, * Note that in such cases the first sub-condition is likely also false. */ listParams->useDynamicPruning = - (listParams->rlistInner + rlistInc < 0.99*(listParams->rlistOuter + rlistInc) && - listParams->nstlistPrune < listParams->lifetime); + (listParams->rlistInner + rlistInc < 0.99 * (listParams->rlistOuter + rlistInc) + && listParams->nstlistPrune < listParams->lifetime); } if (!listParams->useDynamicPruning) { /* These parameters should not be used, but set them to useful values */ - listParams->nstlistPrune = -1; - listParams->rlistInner = listParams->rlistOuter; + listParams->nstlistPrune = -1; + listParams->rlistInner = listParams->rlistOuter; } } @@ -460,7 +456,7 @@ setDynamicPairlistPruningParameters(const t_inputrec *ir, * \param[in] rList List cut-off radius * \param[in] interactionCutoff The interaction cut-off, use for printing the list buffer size */ -static std::string formatListSetup(const std::string &listName, +static std::string formatListSetup(const std::string& listName, int nstList, int nstListForSpacing, real rList, @@ -473,7 +469,8 @@ static std::string formatListSetup(const std::string &listName, } listSetup += "updated every "; // Make the shortest int format string that fits nstListForSpacing - std::string nstListFormat = "%" + gmx::formatString("%zu", gmx::formatString("%d", nstListForSpacing).size()) + "d"; + std::string nstListFormat = + "%" + gmx::formatString("%zu", gmx::formatString("%d", nstListForSpacing).size()) + "d"; listSetup += gmx::formatString(nstListFormat.c_str(), nstList); listSetup += gmx::formatString(" steps, buffer %.3f nm, rlist %.3f nm\n", rList - interactionCutoff, rList); @@ -481,58 +478,58 @@ static std::string formatListSetup(const std::string &listName, return listSetup; } -void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, - const t_inputrec *ir, - const gmx_mtop_t *mtop, +void setupDynamicPairlistPruning(const gmx::MDLogger& mdlog, + const t_inputrec* ir, + const gmx_mtop_t* mtop, matrix box, - const interaction_const_t *ic, - PairlistParams *listParams) + const interaction_const_t* ic, + PairlistParams* listParams) { GMX_RELEASE_ASSERT(listParams->rlistOuter > 0, "With the nbnxn setup rlist should be > 0"); /* Initialize the parameters to no dynamic list pruning */ listParams->useDynamicPruning = false; - const VerletbufListSetup ls = - { - IClusterSizePerListType[listParams->pairlistType], - JClusterSizePerListType[listParams->pairlistType] - }; + const VerletbufListSetup ls = { IClusterSizePerListType[listParams->pairlistType], + JClusterSizePerListType[listParams->pairlistType] }; /* Currently emulation mode does not support dual pair-lists */ - const bool useGpuList = (listParams->pairlistType == PairlistType::HierarchicalNxN); + const bool useGpuList = (listParams->pairlistType == PairlistType::HierarchicalNxN); - if (supportsDynamicPairlistGenerationInterval(*ir) && - getenv("GMX_DISABLE_DYNAMICPRUNING") == nullptr) + if (supportsDynamicPairlistGenerationInterval(*ir) && getenv("GMX_DISABLE_DYNAMICPRUNING") == nullptr) { /* Note that nstlistPrune can have any value independently of nstlist. * Actually applying rolling pruning is only useful when * nstlistPrune < nstlist -1 */ - char *env = getenv("GMX_NSTLIST_DYNAMICPRUNING"); + char* env = getenv("GMX_NSTLIST_DYNAMICPRUNING"); bool userSetNstlistPrune = (env != nullptr); if (userSetNstlistPrune) { - char *end; + char* end; listParams->nstlistPrune = strtol(env, &end, 10); - if (!end || (*end != 0) || - !(listParams->nstlistPrune > 0 && listParams->nstlistPrune < ir->nstlist)) + if (!end || (*end != 0) + || !(listParams->nstlistPrune > 0 && listParams->nstlistPrune < ir->nstlist)) { - gmx_fatal(FARGS, "Invalid value passed in GMX_NSTLIST_DYNAMICPRUNING=%s, should be > 0 and < nstlist", env); + gmx_fatal(FARGS, + "Invalid value passed in GMX_NSTLIST_DYNAMICPRUNING=%s, should be > 0 " + "and < nstlist", + env); } } else { static_assert(c_nbnxnDynamicListPruningMinLifetime % c_nbnxnGpuRollingListPruningInterval == 0, - "c_nbnxnDynamicListPruningMinLifetime sets the starting value for nstlistPrune, which should be divisible by the rolling pruning interval for efficiency reasons."); + "c_nbnxnDynamicListPruningMinLifetime sets the starting value for " + "nstlistPrune, which should be divisible by the rolling pruning interval " + "for efficiency reasons."); // TODO: Use auto-tuning to determine nstlistPrune listParams->nstlistPrune = c_nbnxnDynamicListPruningMinLifetime; } - setDynamicPairlistPruningParameters(ir, mtop, box, useGpuList, ls, - userSetNstlistPrune, ic, + setDynamicPairlistPruningParameters(ir, mtop, box, useGpuList, ls, userSetNstlistPrune, ic, listParams); if (listParams->useDynamicPruning && useGpuList) @@ -541,11 +538,12 @@ void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, * rolling pruning interval slightly shorter than nstlistTune, * thus giving correct results, but a slightly lower efficiency. */ - GMX_RELEASE_ASSERT(listParams->nstlistPrune >= c_nbnxnGpuRollingListPruningInterval, - ( "With dynamic list pruning on GPUs pruning frequency must be at least as large as the rolling pruning interval (" + - std::to_string(c_nbnxnGpuRollingListPruningInterval) + - ").").c_str() ); - listParams->numRollingPruningParts = listParams->nstlistPrune/c_nbnxnGpuRollingListPruningInterval; + GMX_RELEASE_ASSERT(listParams->nstlistPrune >= c_nbnxnGpuRollingListPruningInterval, ("With dynamic list pruning on GPUs pruning frequency must be at least as large as the rolling pruning interval (" + + std::to_string(c_nbnxnGpuRollingListPruningInterval) + + ").") + .c_str()); + listParams->numRollingPruningParts = + listParams->nstlistPrune / c_nbnxnGpuRollingListPruningInterval; } else { @@ -555,42 +553,42 @@ void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, std::string mesg; - const real interactionCutoff = std::max(ic->rcoulomb, ic->rvdw); + const real interactionCutoff = std::max(ic->rcoulomb, ic->rvdw); if (listParams->useDynamicPruning) { - mesg += gmx::formatString("Using a dual %dx%d pair-list setup updated with dynamic%s pruning:\n", - ls.cluster_size_i, ls.cluster_size_j, - listParams->numRollingPruningParts > 1 ? ", rolling" : ""); + mesg += gmx::formatString( + "Using a dual %dx%d pair-list setup updated with dynamic%s pruning:\n", ls.cluster_size_i, + ls.cluster_size_j, listParams->numRollingPruningParts > 1 ? ", rolling" : ""); mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, listParams->rlistOuter, interactionCutoff); - mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, listParams->rlistInner, interactionCutoff); + mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, + listParams->rlistInner, interactionCutoff); } else { - mesg += gmx::formatString("Using a %dx%d pair-list setup:\n", - ls.cluster_size_i, ls.cluster_size_j); + mesg += gmx::formatString("Using a %dx%d pair-list setup:\n", ls.cluster_size_i, ls.cluster_size_j); mesg += formatListSetup("", ir->nstlist, ir->nstlist, listParams->rlistOuter, interactionCutoff); } if (supportsDynamicPairlistGenerationInterval(*ir)) { const VerletbufListSetup listSetup1x1 = { 1, 1 }; - const real rlistOuter = - calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, ir->nstlist - 1, - -1, listSetup1x1); - real rlistInner = rlistOuter; + const real rlistOuter = calcVerletBufferSize(*mtop, det(box), *ir, ir->nstlist, + ir->nstlist - 1, -1, listSetup1x1); + real rlistInner = rlistOuter; if (listParams->useDynamicPruning) { int listLifeTime = listParams->nstlistPrune - (useGpuList ? 0 : 1); - rlistInner = - calcVerletBufferSize(*mtop, det(box), *ir, listParams->nstlistPrune, listLifeTime, - -1, listSetup1x1); + rlistInner = calcVerletBufferSize(*mtop, det(box), *ir, listParams->nstlistPrune, + listLifeTime, -1, listSetup1x1); } - mesg += gmx::formatString("At tolerance %g kJ/mol/ps per atom, equivalent classical 1x1 list would be:\n", - ir->verletbuf_tol); + mesg += gmx::formatString( + "At tolerance %g kJ/mol/ps per atom, equivalent classical 1x1 list would be:\n", + ir->verletbuf_tol); if (listParams->useDynamicPruning) { mesg += formatListSetup("outer", ir->nstlist, ir->nstlist, rlistOuter, interactionCutoff); - mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, rlistInner, interactionCutoff); + mesg += formatListSetup("inner", listParams->nstlistPrune, ir->nstlist, rlistInner, + interactionCutoff); } else { diff --git a/src/gromacs/nbnxm/pairlist_tuning.h b/src/gromacs/nbnxm/pairlist_tuning.h index bde3474bc3..88a550a1a1 100644 --- a/src/gromacs/nbnxm/pairlist_tuning.h +++ b/src/gromacs/nbnxm/pairlist_tuning.h @@ -54,7 +54,7 @@ namespace gmx { class CpuInfo; class MDLogger; -} +} // namespace gmx struct gmx_mtop_t; struct interaction_const_t; @@ -73,12 +73,14 @@ struct t_inputrec; * \param[in] useOrEmulateGpuForNonbondeds Tells if we are using a GPU for non-bondeds * \param[in] cpuinfo Information about the CPU(s) */ -void increaseNstlist(FILE *fplog, t_commrec *cr, - t_inputrec *ir, int nstlistOnCmdline, - const gmx_mtop_t *mtop, - const matrix box, - bool useOrEmulateGpuForNonbondeds, - const gmx::CpuInfo &cpuinfo); +void increaseNstlist(FILE* fplog, + t_commrec* cr, + t_inputrec* ir, + int nstlistOnCmdline, + const gmx_mtop_t* mtop, + const matrix box, + bool useOrEmulateGpuForNonbondeds, + const gmx::CpuInfo& cpuinfo); /*! \brief Set up the dynamic pairlist pruning * @@ -89,11 +91,11 @@ void increaseNstlist(FILE *fplog, t_commrec *cr, * \param[in] ic The nonbonded interactions constants * \param[in,out] listParams The list setup parameters */ -void setupDynamicPairlistPruning(const gmx::MDLogger &mdlog, - const t_inputrec *ir, - const gmx_mtop_t *mtop, +void setupDynamicPairlistPruning(const gmx::MDLogger& mdlog, + const t_inputrec* ir, + const gmx_mtop_t* mtop, matrix box, - const interaction_const_t *ic, - PairlistParams *listParams); + const interaction_const_t* ic, + PairlistParams* listParams); #endif /* NBNXM_PAIRLIST_TUNING_H */ diff --git a/src/gromacs/nbnxm/pairlistparams.cpp b/src/gromacs/nbnxm/pairlistparams.cpp index 6deada0692..26f6fec3f9 100644 --- a/src/gromacs/nbnxm/pairlistparams.cpp +++ b/src/gromacs/nbnxm/pairlistparams.cpp @@ -72,17 +72,10 @@ PairlistParams::PairlistParams(const Nbnxm::KernelType kernelType, { switch (Nbnxm::JClusterSizePerKernelType[kernelType]) { - case 2: - pairlistType = PairlistType::Simple4x2; - break; - case 4: - pairlistType = PairlistType::Simple4x4; - break; - case 8: - pairlistType = PairlistType::Simple4x8; - break; - default: - GMX_RELEASE_ASSERT(false, "Kernel type does not have a pairlist type"); + case 2: pairlistType = PairlistType::Simple4x2; break; + case 4: pairlistType = PairlistType::Simple4x4; break; + case 8: pairlistType = PairlistType::Simple4x8; break; + default: GMX_RELEASE_ASSERT(false, "Kernel type does not have a pairlist type"); } } } diff --git a/src/gromacs/nbnxm/pairlistparams.h b/src/gromacs/nbnxm/pairlistparams.h index 9858360168..01755808f5 100644 --- a/src/gromacs/nbnxm/pairlistparams.h +++ b/src/gromacs/nbnxm/pairlistparams.h @@ -73,7 +73,8 @@ static constexpr int c_gpuNumClusterPerCellY = 2; //! The number of clusters along X in a pair-search grid cell for GPU lists static constexpr int c_gpuNumClusterPerCellX = 2; //! The number of clusters in a pair-search grid cell for GPU lists -static constexpr int c_gpuNumClusterPerCell = c_gpuNumClusterPerCellZ*c_gpuNumClusterPerCellY*c_gpuNumClusterPerCellX; +static constexpr int c_gpuNumClusterPerCell = + c_gpuNumClusterPerCellZ * c_gpuNumClusterPerCellY * c_gpuNumClusterPerCellX; /*! \brief The number of sub-parts used for data storage for a GPU cluster pair @@ -84,7 +85,8 @@ static constexpr int c_gpuNumClusterPerCell = c_gpuNumClusterPerCellZ*c_gpuNumC static constexpr int c_nbnxnGpuClusterpairSplit = 2; //! The fixed size of the exclusion mask array for a half GPU cluster pair -static constexpr int c_nbnxnGpuExclSize = c_nbnxnGpuClusterSize*c_nbnxnGpuClusterSize/c_nbnxnGpuClusterpairSplit; +static constexpr int c_nbnxnGpuExclSize = + c_nbnxnGpuClusterSize * c_nbnxnGpuClusterSize / c_nbnxnGpuClusterpairSplit; //! The available pair list types enum class PairlistType : int @@ -97,21 +99,13 @@ enum class PairlistType : int }; //! Gives the i-cluster size for each pairlist type -static constexpr gmx::EnumerationArray IClusterSizePerListType = -{ { - c_nbnxnCpuIClusterSize, - c_nbnxnCpuIClusterSize, - c_nbnxnCpuIClusterSize, - c_nbnxnGpuClusterSize - } }; +static constexpr gmx::EnumerationArray IClusterSizePerListType = { + { c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnCpuIClusterSize, c_nbnxnGpuClusterSize } +}; //! Gives the j-cluster size for each pairlist type -static constexpr gmx::EnumerationArray JClusterSizePerListType = -{ { - 2, - 4, - 8, - c_nbnxnGpuClusterSize - } }; +static constexpr gmx::EnumerationArray JClusterSizePerListType = { + { 2, 4, 8, c_nbnxnGpuClusterSize } +}; /*! \internal * \brief The setup for generating and pruning the nbnxn pair list. @@ -122,10 +116,7 @@ struct PairlistParams { /*! \brief Constructor producing a struct with dynamic pruning disabled */ - PairlistParams(Nbnxm::KernelType kernelType, - bool haveFep, - real rlist, - bool haveMultipleDomains); + PairlistParams(Nbnxm::KernelType kernelType, bool haveFep, real rlist, bool haveMultipleDomains); PairlistType pairlistType; //!< The type of cluster-pair list bool haveFep; //!< Tells whether we have perturbed interactions diff --git a/src/gromacs/nbnxm/pairlistset.h b/src/gromacs/nbnxm/pairlistset.h index 8197f131d5..d0e930330c 100644 --- a/src/gromacs/nbnxm/pairlistset.h +++ b/src/gromacs/nbnxm/pairlistset.h @@ -75,83 +75,72 @@ class GridSet; */ class PairlistSet { - public: - //! Constructor: initializes the pairlist set as empty - PairlistSet(gmx::InteractionLocality locality, - const PairlistParams &listParams); - - ~PairlistSet(); - - //! Constructs the pairlists in the set using the coordinates in \p nbat - void constructPairlists(const Nbnxm::GridSet &gridSet, - gmx::ArrayRef searchWork, - nbnxn_atomdata_t *nbat, - const t_blocka *excl, - int minimumIlistCountForGpuBalancing, - t_nrnb *nrnb, - SearchCycleCounting *searchCycleCounting); - - //! Dispatch the kernel for dynamic pairlist pruning - void dispatchPruneKernel(const nbnxn_atomdata_t *nbat, - const rvec *shift_vec); - - //! Returns the locality - gmx::InteractionLocality locality() const +public: + //! Constructor: initializes the pairlist set as empty + PairlistSet(gmx::InteractionLocality locality, const PairlistParams& listParams); + + ~PairlistSet(); + + //! Constructs the pairlists in the set using the coordinates in \p nbat + void constructPairlists(const Nbnxm::GridSet& gridSet, + gmx::ArrayRef searchWork, + nbnxn_atomdata_t* nbat, + const t_blocka* excl, + int minimumIlistCountForGpuBalancing, + t_nrnb* nrnb, + SearchCycleCounting* searchCycleCounting); + + //! Dispatch the kernel for dynamic pairlist pruning + void dispatchPruneKernel(const nbnxn_atomdata_t* nbat, const rvec* shift_vec); + + //! Returns the locality + gmx::InteractionLocality locality() const { return locality_; } + + //! Returns the lists of CPU pairlists + gmx::ArrayRef cpuLists() const { return cpuLists_; } + + //! Returns a pointer to the GPU pairlist, nullptr when not present + const NbnxnPairlistGpu* gpuList() const + { + if (!gpuLists_.empty()) { - return locality_; + return &gpuLists_[0]; } - - //! Returns the lists of CPU pairlists - gmx::ArrayRef cpuLists() const - { - return cpuLists_; - } - - //! Returns a pointer to the GPU pairlist, nullptr when not present - const NbnxnPairlistGpu *gpuList() const + else { - if (!gpuLists_.empty()) - { - return &gpuLists_[0]; - } - else - { - return nullptr; - } + return nullptr; } - - //! Returns the lists of free-energy pairlists, empty when nonbonded interactions are not perturbed - gmx::ArrayRef < const std::unique_ptr < t_nblist>> fepLists() const - { - return fepLists_; - } - - private: - //! The locality of the pairlist set - gmx::InteractionLocality locality_; - //! List of pairlists in CPU layout - std::vector cpuLists_; - //! List of working list for rebalancing CPU lists - std::vector cpuListsWork_; - //! List of pairlists in GPU layout - std::vector gpuLists_; - //! Pairlist parameters describing setup and ranges - const PairlistParams ¶ms_; - //! Tells whether multiple lists get merged into one (the first) after creation - bool combineLists_; - //! Tells whether the lists is of CPU type, otherwise GPU type - gmx_bool isCpuType_; - //! Lists for perturbed interactions in simple atom-atom layout - std::vector < std::unique_ptr < t_nblist>> fepLists_; - - public: - /* Pair counts for flop counting */ - //! Total number of atom pairs for LJ+Q kernel - int natpair_ljq_; - //! Total number of atom pairs for LJ kernel - int natpair_lj_; - //! Total number of atom pairs for Q kernel - int natpair_q_; + } + + //! Returns the lists of free-energy pairlists, empty when nonbonded interactions are not perturbed + gmx::ArrayRef> fepLists() const { return fepLists_; } + +private: + //! The locality of the pairlist set + gmx::InteractionLocality locality_; + //! List of pairlists in CPU layout + std::vector cpuLists_; + //! List of working list for rebalancing CPU lists + std::vector cpuListsWork_; + //! List of pairlists in GPU layout + std::vector gpuLists_; + //! Pairlist parameters describing setup and ranges + const PairlistParams& params_; + //! Tells whether multiple lists get merged into one (the first) after creation + bool combineLists_; + //! Tells whether the lists is of CPU type, otherwise GPU type + gmx_bool isCpuType_; + //! Lists for perturbed interactions in simple atom-atom layout + std::vector> fepLists_; + +public: + /* Pair counts for flop counting */ + //! Total number of atom pairs for LJ+Q kernel + int natpair_ljq_; + //! Total number of atom pairs for LJ kernel + int natpair_lj_; + //! Total number of atom pairs for Q kernel + int natpair_q_; }; #endif diff --git a/src/gromacs/nbnxm/pairlistsets.h b/src/gromacs/nbnxm/pairlistsets.h index 404c6d16b8..2349159a1d 100644 --- a/src/gromacs/nbnxm/pairlistsets.h +++ b/src/gromacs/nbnxm/pairlistsets.h @@ -63,101 +63,94 @@ struct t_nrnb; class PairlistSets { - public: - PairlistSets(const PairlistParams &pairlistParams, - bool haveMultipleDomains, - int minimumIlistCountForGpuBalancing); - - //! Construct the pairlist set for the given locality - void construct(gmx::InteractionLocality iLocality, - PairSearch *pairSearch, - nbnxn_atomdata_t *nbat, - const t_blocka *excl, - int64_t step, - t_nrnb *nrnb); - - //! Dispatches the dynamic pruning kernel for the given locality - void dispatchPruneKernel(gmx::InteractionLocality iLocality, - const nbnxn_atomdata_t *nbat, - const rvec *shift_vec); - - //! Returns the pair list parameters - const PairlistParams ¶ms() const +public: + PairlistSets(const PairlistParams& pairlistParams, + bool haveMultipleDomains, + int minimumIlistCountForGpuBalancing); + + //! Construct the pairlist set for the given locality + void construct(gmx::InteractionLocality iLocality, + PairSearch* pairSearch, + nbnxn_atomdata_t* nbat, + const t_blocka* excl, + int64_t step, + t_nrnb* nrnb); + + //! Dispatches the dynamic pruning kernel for the given locality + void dispatchPruneKernel(gmx::InteractionLocality iLocality, + const nbnxn_atomdata_t* nbat, + const rvec* shift_vec); + + //! Returns the pair list parameters + const PairlistParams& params() const { return params_; } + + //! Returns the number of steps performed with the current pair list + int numStepsWithPairlist(int64_t step) const + { + return static_cast(step - outerListCreationStep_); + } + + //! Returns whether step is a dynamic list pruning step, for CPU lists + bool isDynamicPruningStepCpu(int64_t step) const + { + return (params_.useDynamicPruning && numStepsWithPairlist(step) % params_.nstlistPrune == 0); + } + + //! Returns whether step is a dynamic list pruning step, for GPU lists + bool isDynamicPruningStepGpu(int64_t step) const + { + const int age = numStepsWithPairlist(step); + + return (params_.useDynamicPruning && age > 0 && age < params_.lifetime + && (params_.haveMultipleDomains || age % 2 == 0)); + } + + //! Changes the pair-list outer and inner radius + void changePairlistRadii(real rlistOuter, real rlistInner) + { + params_.rlistOuter = rlistOuter; + params_.rlistInner = rlistInner; + } + + //! Returns the pair-list set for the given locality + const PairlistSet& pairlistSet(gmx::InteractionLocality iLocality) const + { + if (iLocality == gmx::InteractionLocality::Local) { - return params_; + return *localSet_; } - - //! Returns the number of steps performed with the current pair list - int numStepsWithPairlist(int64_t step) const + else { - return static_cast(step - outerListCreationStep_); + GMX_ASSERT(nonlocalSet_, "Need a non-local set when requesting access"); + return *nonlocalSet_; } + } - //! Returns whether step is a dynamic list pruning step, for CPU lists - bool isDynamicPruningStepCpu(int64_t step) const +private: + //! Returns the pair-list set for the given locality + PairlistSet& pairlistSet(gmx::InteractionLocality iLocality) + { + if (iLocality == gmx::InteractionLocality::Local) { - return (params_.useDynamicPruning && - numStepsWithPairlist(step) % params_.nstlistPrune == 0); + return *localSet_; } - - //! Returns whether step is a dynamic list pruning step, for GPU lists - bool isDynamicPruningStepGpu(int64_t step) const + else { - const int age = numStepsWithPairlist(step); - - return (params_.useDynamicPruning && - age > 0 && - age < params_.lifetime && - (params_.haveMultipleDomains || age % 2 == 0)); + GMX_ASSERT(nonlocalSet_, "Need a non-local set when requesting access"); + return *nonlocalSet_; } - - //! Changes the pair-list outer and inner radius - void changePairlistRadii(real rlistOuter, - real rlistInner) - { - params_.rlistOuter = rlistOuter; - params_.rlistInner = rlistInner; - } - - //! Returns the pair-list set for the given locality - const PairlistSet &pairlistSet(gmx::InteractionLocality iLocality) const - { - if (iLocality == gmx::InteractionLocality::Local) - { - return *localSet_; - } - else - { - GMX_ASSERT(nonlocalSet_, "Need a non-local set when requesting access"); - return *nonlocalSet_; - } - } - - private: - //! Returns the pair-list set for the given locality - PairlistSet &pairlistSet(gmx::InteractionLocality iLocality) - { - if (iLocality == gmx::InteractionLocality::Local) - { - return *localSet_; - } - else - { - GMX_ASSERT(nonlocalSet_, "Need a non-local set when requesting access"); - return *nonlocalSet_; - } - } - - //! Parameters for the search and list pruning setup - PairlistParams params_; - //! Pair list balancing parameter for use with GPU - int minimumIlistCountForGpuBalancing_; - //! Local pairlist set - std::unique_ptr localSet_; - //! Non-local pairlist set - std::unique_ptr nonlocalSet_; - //! MD step at with the outer lists in pairlistSets_ were created - int64_t outerListCreationStep_; + } + + //! Parameters for the search and list pruning setup + PairlistParams params_; + //! Pair list balancing parameter for use with GPU + int minimumIlistCountForGpuBalancing_; + //! Local pairlist set + std::unique_ptr localSet_; + //! Non-local pairlist set + std::unique_ptr nonlocalSet_; + //! MD step at with the outer lists in pairlistSets_ were created + int64_t outerListCreationStep_; }; #endif diff --git a/src/gromacs/nbnxm/pairlistwork.h b/src/gromacs/nbnxm/pairlistwork.h index 5cd0c01fe4..3f6aec3516 100644 --- a/src/gromacs/nbnxm/pairlistwork.h +++ b/src/gromacs/nbnxm/pairlistwork.h @@ -62,36 +62,36 @@ struct NbnxnPairlistCpuWork { IClusterData() : bb(1), - x(c_nbnxnCpuIClusterSize*DIM), - xSimd(c_nbnxnCpuIClusterSize*DIM*GMX_REAL_MAX_SIMD_WIDTH) + x(c_nbnxnCpuIClusterSize * DIM), + xSimd(c_nbnxnCpuIClusterSize * DIM * GMX_REAL_MAX_SIMD_WIDTH) { } // The bounding boxes, pbc shifted, for each cluster AlignedVector bb; // The coordinates, pbc shifted, for each atom - std::vector x; + std::vector x; // Aligned list for storing 4*DIM*GMX_SIMD_REAL_WIDTH reals - AlignedVector xSimd; + AlignedVector xSimd; }; // Protect data from cache pollution between threads - gmx_cache_protect_t cp0; + gmx_cache_protect_t cp0; // Work data for generating an IEntry in the pairlist - IClusterData iClusterData; + IClusterData iClusterData; // The current cj_ind index for the current list - int cj_ind; + int cj_ind; // Temporary j-cluster list, used for sorting on exclusions - std::vector cj; + std::vector cj; // Nr. of cluster pairs without Coulomb for flop counting - int ncj_noq; + int ncj_noq; // Nr. of cluster pairs with 1/2 LJ for flop count - int ncj_hlj; + int ncj_hlj; // Protect data from cache pollution between threads - gmx_cache_protect_t cp1; + gmx_cache_protect_t cp1; }; /* Working data for the actual i-supercell during pair search */ @@ -102,47 +102,47 @@ struct NbnxnPairlistGpuWork ISuperClusterData() : bb(c_gpuNumClusterPerCell), #if NBNXN_SEARCH_BB_SIMD4 - bbPacked(c_gpuNumClusterPerCell/c_packedBoundingBoxesDimSize*c_packedBoundingBoxesSize), + bbPacked(c_gpuNumClusterPerCell / c_packedBoundingBoxesDimSize * c_packedBoundingBoxesSize), #endif - x(c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize*DIM), - xSimd(c_gpuNumClusterPerCell*c_nbnxnGpuClusterSize*DIM) + x(c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize * DIM), + xSimd(c_gpuNumClusterPerCell * c_nbnxnGpuClusterSize * DIM) { } // The bounding boxes, pbc shifted, for each cluster AlignedVector bb; // As bb, but in packed xxxx format - AlignedVector bbPacked; + AlignedVector bbPacked; // The coordinates, pbc shifted, for each atom - AlignedVector x; + AlignedVector x; // Aligned coordinate list used for 4*DIM*GMX_SIMD_REAL_WIDTH floats - AlignedVector xSimd; + AlignedVector xSimd; }; NbnxnPairlistGpuWork() : distanceBuffer(c_gpuNumClusterPerCell), - sci_sort({}, {gmx::PinningPolicy::PinnedIfSupported}) + sci_sort({}, { gmx::PinningPolicy::PinnedIfSupported }) { } // Protect data from cache pollution between threads - gmx_cache_protect_t cp0; + gmx_cache_protect_t cp0; // Work data for generating an i-entry in the pairlist - ISuperClusterData iSuperClusterData; + ISuperClusterData iSuperClusterData; // The current j-cluster index for the current list - int cj_ind; + int cj_ind; // Bounding box distance work array - AlignedVector distanceBuffer; + AlignedVector distanceBuffer; // Buffer for sorting list entries - std::vector sortBuffer; + std::vector sortBuffer; // Second sci array, for sorting gmx::HostVector sci_sort; // Protect data from cache pollution between threads - gmx_cache_protect_t cp1; + gmx_cache_protect_t cp1; }; #endif diff --git a/src/gromacs/nbnxm/pairsearch.cpp b/src/gromacs/nbnxm/pairsearch.cpp index 5988ccbf22..fee162cbdc 100644 --- a/src/gromacs/nbnxm/pairsearch.cpp +++ b/src/gromacs/nbnxm/pairsearch.cpp @@ -50,34 +50,29 @@ #include "pairlist.h" -void SearchCycleCounting::printCycles(FILE *fp, - gmx::ArrayRef work) const +void SearchCycleCounting::printCycles(FILE* fp, gmx::ArrayRef work) const { fprintf(fp, "\n"); - fprintf(fp, "ns %4d grid %4.1f search %4.1f", - cc_[enbsCCgrid].count(), - cc_[enbsCCgrid].averageMCycles(), - cc_[enbsCCsearch].averageMCycles()); + fprintf(fp, "ns %4d grid %4.1f search %4.1f", cc_[enbsCCgrid].count(), + cc_[enbsCCgrid].averageMCycles(), cc_[enbsCCsearch].averageMCycles()); if (work.size() > 1) { if (cc_[enbsCCcombine].count() > 0) { - fprintf(fp, " comb %5.2f", - cc_[enbsCCcombine].averageMCycles()); + fprintf(fp, " comb %5.2f", cc_[enbsCCcombine].averageMCycles()); } fprintf(fp, " s. th"); - for (const PairsearchWork &workEntry : work) + for (const PairsearchWork& workEntry : work) { - fprintf(fp, " %4.1f", - workEntry.cycleCounter.averageMCycles()); + fprintf(fp, " %4.1f", workEntry.cycleCounter.averageMCycles()); } } fprintf(fp, "\n"); } /*! \brief Frees the contents of a legacy t_nblist struct */ -static void free_nblist(t_nblist *nl) +static void free_nblist(t_nblist* nl) { sfree(nl->iinr); sfree(nl->gid); @@ -90,12 +85,11 @@ static void free_nblist(t_nblist *nl) #ifndef DOXYGEN PairsearchWork::PairsearchWork() : - cp0({{0}} - ), - buffer_flags({0, nullptr, 0}), + cp0({ { 0 } }), + buffer_flags({ 0, nullptr, 0 }), ndistc(0), nbl_fep(new t_nblist), - cp1({{0}}) + cp1({ { 0 } }) { nbnxn_init_pairlist_fep(nbl_fep.get()); } @@ -111,8 +105,8 @@ PairsearchWork::~PairsearchWork() PairSearch::PairSearch(const int ePBC, const bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *ddZones, + const ivec* numDDCells, + const gmx_domdec_zones_t* ddZones, const PairlistType pairlistType, const bool haveFep, const int maxNumThreads, diff --git a/src/gromacs/nbnxm/pairsearch.h b/src/gromacs/nbnxm/pairsearch.h index d19eb8a918..668f8c8093 100644 --- a/src/gromacs/nbnxm/pairsearch.h +++ b/src/gromacs/nbnxm/pairsearch.h @@ -69,51 +69,49 @@ struct PairsearchWork; /*! \brief Convenience declaration for an std::vector with aligned memory */ -template -using AlignedVector = std::vector < T, gmx::AlignedAllocator < T>>; +template +using AlignedVector = std::vector>; /* Local cycle count struct for profiling */ class nbnxn_cycle_t { - public: - void start() - { - start_ = gmx_cycles_read(); - } +public: + void start() { start_ = gmx_cycles_read(); } - void stop() - { - cycles_ += gmx_cycles_read() - start_; - count_++; - } + void stop() + { + cycles_ += gmx_cycles_read() - start_; + count_++; + } - int count() const + int count() const { return count_; } + + double averageMCycles() const + { + if (count_ > 0) { - return count_; + return static_cast(cycles_) * 1e-6 / count_; } - - double averageMCycles() const + else { - if (count_ > 0) - { - return static_cast(cycles_)*1e-6/count_; - } - else - { - return 0; - } + return 0; } + } - private: - int count_ = 0; - gmx_cycles_t cycles_ = 0; - gmx_cycles_t start_ = 0; +private: + int count_ = 0; + gmx_cycles_t cycles_ = 0; + gmx_cycles_t start_ = 0; }; //! Local cycle count enum for profiling different parts of search -enum { - enbsCCgrid, enbsCCsearch, enbsCCcombine, enbsCCnr +enum +{ + enbsCCgrid, + enbsCCsearch, + enbsCCcombine, + enbsCCnr }; /*! \internal @@ -122,25 +120,18 @@ enum { struct SearchCycleCounting { //! Start a pair search cycle counter - void start(const int enbsCC) - { - cc_[enbsCC].start(); - } + void start(const int enbsCC) { cc_[enbsCC].start(); } //! Stop a pair search cycle counter - void stop(const int enbsCC) - { - cc_[enbsCC].stop(); - } + void stop(const int enbsCC) { cc_[enbsCC].stop(); } //! Print the cycle counts to \p fp - void printCycles(FILE *fp, - gmx::ArrayRef work) const; + void printCycles(FILE* fp, gmx::ArrayRef work) const; //! Tells whether we record cycles - bool recordCycles_ = false; + bool recordCycles_ = false; //! The number of times pairsearching has been performed, local+non-local count as 1 - int searchCount_ = 0; + int searchCount_ = 0; //! The set of cycle counters nbnxn_cycle_t cc_[enbsCCnr]; }; @@ -154,99 +145,86 @@ struct PairsearchWork ~PairsearchWork(); - gmx_cache_protect_t cp0; /* Buffer to avoid cache polution */ + gmx_cache_protect_t cp0; /* Buffer to avoid cache polution */ - std::vector sortBuffer; /* Temporary buffer for sorting atoms within a grid column */ + std::vector sortBuffer; /* Temporary buffer for sorting atoms within a grid column */ - nbnxn_buffer_flags_t buffer_flags; /* Flags for force buffer access */ + nbnxn_buffer_flags_t buffer_flags; /* Flags for force buffer access */ - int ndistc; /* Number of distance checks for flop counting */ + int ndistc; /* Number of distance checks for flop counting */ - std::unique_ptr nbl_fep; /* Temporary FEP list for load balancing */ + std::unique_ptr nbl_fep; /* Temporary FEP list for load balancing */ - nbnxn_cycle_t cycleCounter; /* Counter for thread-local cycles */ + nbnxn_cycle_t cycleCounter; /* Counter for thread-local cycles */ - gmx_cache_protect_t cp1; /* Buffer to avoid cache polution */ + gmx_cache_protect_t cp1; /* Buffer to avoid cache polution */ }; /* Main pair-search struct, contains the grid(s), not the pair-list(s) */ class PairSearch { - public: - //! Puts the atoms in \p ddZone on the grid and copies the coordinates to \p nbat - void putOnGrid(const matrix box, - int ddZone, - const rvec lowerCorner, - const rvec upperCorner, - const gmx::UpdateGroupsCog *updateGroupsCog, - gmx::Range atomRange, - real atomDensity, - gmx::ArrayRef atomInfo, - gmx::ArrayRef x, - int numAtomsMoved, - const int *move, - nbnxn_atomdata_t *nbat) - { - cycleCounting_.start(enbsCCgrid); - - gridSet_.putOnGrid(box, ddZone, lowerCorner, upperCorner, - updateGroupsCog, atomRange, atomDensity, - atomInfo, x, numAtomsMoved, move, nbat); - - cycleCounting_.stop(enbsCCgrid); - } - - /* \brief Constructor - * - * \param[in] ePBC The periodic boundary conditions - * \param[in] numDDCells The number of domain decomposition cells per dimension, without DD nullptr should be passed - * \param[in] zones The domain decomposition zone setup, without DD nullptr should be passed - * \param[in] haveFep Tells whether non-bonded interactions are perturbed - * \param[in] maxNumThreads The maximum number of threads used in the search - */ - PairSearch(int ePBC, - bool doTestParticleInsertion, - const ivec *numDDCells, - const gmx_domdec_zones_t *zones, - PairlistType pairlistType, - bool haveFep, - int maxNumthreads, - gmx::PinningPolicy pinningPolicy); - - //! Sets the order of the local atoms to the order grid atom ordering - void setLocalAtomOrder() - { - gridSet_.setLocalAtomOrder(); - } - - //! Returns the set of search grids - const Nbnxm::GridSet &gridSet() const - { - return gridSet_; - } - - //! Returns the list of thread-local work objects - gmx::ArrayRef work() const - { - return work_; - } +public: + //! Puts the atoms in \p ddZone on the grid and copies the coordinates to \p nbat + void putOnGrid(const matrix box, + int ddZone, + const rvec lowerCorner, + const rvec upperCorner, + const gmx::UpdateGroupsCog* updateGroupsCog, + gmx::Range atomRange, + real atomDensity, + gmx::ArrayRef atomInfo, + gmx::ArrayRef x, + int numAtomsMoved, + const int* move, + nbnxn_atomdata_t* nbat) + { + cycleCounting_.start(enbsCCgrid); - //! Returns the list of thread-local work objects - gmx::ArrayRef work() - { - return work_; - } + gridSet_.putOnGrid(box, ddZone, lowerCorner, upperCorner, updateGroupsCog, atomRange, + atomDensity, atomInfo, x, numAtomsMoved, move, nbat); - private: - //! The set of search grids - Nbnxm::GridSet gridSet_; - //! Work objects, one entry for each thread - std::vector work_; + cycleCounting_.stop(enbsCCgrid); + } - public: - //! Cycle counting for measuring components of the search - SearchCycleCounting cycleCounting_; + /* \brief Constructor + * + * \param[in] ePBC The periodic boundary conditions + * \param[in] numDDCells The number of domain decomposition cells per dimension, without DD nullptr should be passed + * \param[in] zones The domain decomposition zone setup, without DD nullptr should be passed + * \param[in] haveFep Tells whether non-bonded interactions are perturbed + * \param[in] maxNumThreads The maximum number of threads used in the search + */ + PairSearch(int ePBC, + bool doTestParticleInsertion, + const ivec* numDDCells, + const gmx_domdec_zones_t* zones, + PairlistType pairlistType, + bool haveFep, + int maxNumthreads, + gmx::PinningPolicy pinningPolicy); + + //! Sets the order of the local atoms to the order grid atom ordering + void setLocalAtomOrder() { gridSet_.setLocalAtomOrder(); } + + //! Returns the set of search grids + const Nbnxm::GridSet& gridSet() const { return gridSet_; } + + //! Returns the list of thread-local work objects + gmx::ArrayRef work() const { return work_; } + + //! Returns the list of thread-local work objects + gmx::ArrayRef work() { return work_; } + +private: + //! The set of search grids + Nbnxm::GridSet gridSet_; + //! Work objects, one entry for each thread + std::vector work_; + +public: + //! Cycle counting for measuring components of the search + SearchCycleCounting cycleCounting_; }; #endif diff --git a/src/gromacs/nbnxm/prunekerneldispatch.cpp b/src/gromacs/nbnxm/prunekerneldispatch.cpp index b371054068..141b1ea903 100644 --- a/src/gromacs/nbnxm/prunekerneldispatch.cpp +++ b/src/gromacs/nbnxm/prunekerneldispatch.cpp @@ -47,17 +47,14 @@ #include "kernels_simd_2xmm/kernel_prune.h" #include "kernels_simd_4xm/kernel_prune.h" -void -PairlistSets::dispatchPruneKernel(const gmx::InteractionLocality iLocality, - const nbnxn_atomdata_t *nbat, - const rvec *shift_vec) +void PairlistSets::dispatchPruneKernel(const gmx::InteractionLocality iLocality, + const nbnxn_atomdata_t* nbat, + const rvec* shift_vec) { pairlistSet(iLocality).dispatchPruneKernel(nbat, shift_vec); } -void -PairlistSet::dispatchPruneKernel(const nbnxn_atomdata_t *nbat, - const rvec *shift_vec) +void PairlistSet::dispatchPruneKernel(const nbnxn_atomdata_t* nbat, const rvec* shift_vec) { const real rlistInner = params_.rlistInner; @@ -70,7 +67,7 @@ PairlistSet::dispatchPruneKernel(const nbnxn_atomdata_t *nbat, #pragma omp parallel for schedule(static) num_threads(nthreads) for (int i = 0; i < nthreads; i++) { - NbnxnPairlistCpu *nbl = &cpuLists_[i]; + NbnxnPairlistCpu* nbl = &cpuLists_[i]; switch (getClusterDistanceKernelType(params_.pairlistType, *nbat)) { @@ -83,15 +80,12 @@ PairlistSet::dispatchPruneKernel(const nbnxn_atomdata_t *nbat, case ClusterDistanceKernelType::CpuPlainC: nbnxn_kernel_prune_ref(nbl, nbat, shift_vec, rlistInner); break; - default: - GMX_RELEASE_ASSERT(false, "kernel type not handled (yet)"); + default: GMX_RELEASE_ASSERT(false, "kernel type not handled (yet)"); } } } -void -nonbonded_verlet_t::dispatchPruneKernelCpu(const gmx::InteractionLocality iLocality, - const rvec *shift_vec) +void nonbonded_verlet_t::dispatchPruneKernelCpu(const gmx::InteractionLocality iLocality, const rvec* shift_vec) { pairlistSets_->dispatchPruneKernel(iLocality, nbat.get(), shift_vec); } @@ -103,9 +97,9 @@ void nonbonded_verlet_t::dispatchPruneKernelGpu(int64_t step) const bool stepIsEven = (pairlistSets().numStepsWithPairlist(step) % 2 == 0); - Nbnxm::gpu_launch_kernel_pruneonly(gpu_nbv, - stepIsEven ? gmx::InteractionLocality::Local : gmx::InteractionLocality::NonLocal, - pairlistSets().params().numRollingPruningParts); + Nbnxm::gpu_launch_kernel_pruneonly( + gpu_nbv, stepIsEven ? gmx::InteractionLocality::Local : gmx::InteractionLocality::NonLocal, + pairlistSets().params().numRollingPruningParts); wallcycle_sub_stop(wcycle_, ewcsLAUNCH_GPU_NONBONDED); wallcycle_stop(wcycle_, ewcLAUNCH_GPU); diff --git a/src/gromacs/onlinehelp/helpformat.cpp b/src/gromacs/onlinehelp/helpformat.cpp index 4d9ce48aeb..f348952c99 100644 --- a/src/gromacs/onlinehelp/helpformat.cpp +++ b/src/gromacs/onlinehelp/helpformat.cpp @@ -65,148 +65,148 @@ namespace gmx */ class TextTableFormatter::Impl { - public: - /*! \internal \brief - * Manages a single column for TextTableFormatter. - * - * \ingroup module_onlinehelp - */ - struct ColumnData +public: + /*! \internal \brief + * Manages a single column for TextTableFormatter. + * + * \ingroup module_onlinehelp + */ + struct ColumnData + { + //! Initializes a text table column with given values. + ColumnData(const char* title, int width, bool bWrap) : + title_(title != nullptr ? title : ""), + width_(width), + bWrap_(bWrap), + firstLine_(0), + nextLineIndex_(0), + nextLineOffset_(0) { - //! Initializes a text table column with given values. - ColumnData(const char *title, int width, bool bWrap) - : title_(title != nullptr ? title : ""), - width_(width), bWrap_(bWrap), firstLine_(0), - nextLineIndex_(0), nextLineOffset_(0) - { - GMX_ASSERT(width >= 0, "Negative width not possible"); - GMX_ASSERT(title_.length() <= static_cast(width), - "Title too long for column width"); - } + GMX_ASSERT(width >= 0, "Negative width not possible"); + GMX_ASSERT(title_.length() <= static_cast(width), + "Title too long for column width"); + } - //! Returns the title of the column. - const std::string &title() const { return title_; } - //! Returns the width of the column. - int width() const { return width_; } - /*! \brief - * Returns the first line offset for the current row. - * - * Note that the return value may be outside the printed lines if - * there is no text. - */ - int firstLine() const { return firstLine_; } + //! Returns the title of the column. + const std::string& title() const { return title_; } + //! Returns the width of the column. + int width() const { return width_; } + /*! \brief + * Returns the first line offset for the current row. + * + * Note that the return value may be outside the printed lines if + * there is no text. + */ + int firstLine() const { return firstLine_; } - /*! \brief - * Resets the formatting state. - * - * After this call, textForNextLine() and hasLinesRemaining() can - * be used to format the lines for the column. - */ - void startFormatting() - { - nextLineIndex_ = (!lines_.empty() ? -firstLine_ : 0); - nextLineOffset_ = 0; - } - //! Whether there are lines remaining for textForNextLine(). - bool hasLinesRemaining() const + /*! \brief + * Resets the formatting state. + * + * After this call, textForNextLine() and hasLinesRemaining() can + * be used to format the lines for the column. + */ + void startFormatting() + { + nextLineIndex_ = (!lines_.empty() ? -firstLine_ : 0); + nextLineOffset_ = 0; + } + //! Whether there are lines remaining for textForNextLine(). + bool hasLinesRemaining() const { return nextLineIndex_ < ssize(lines_); } + /*! \brief + * Returns the text for the next line. + * + * \param[in] columnWidth Width to wrap the text to. + * \returns Text for the next line, or empty string if there is + * no text for this column. + */ + std::string textForNextLine(int columnWidth) + { + if (nextLineIndex_ < 0 || !hasLinesRemaining()) { - return nextLineIndex_ < ssize(lines_); + ++nextLineIndex_; + return std::string(); } - /*! \brief - * Returns the text for the next line. - * - * \param[in] columnWidth Width to wrap the text to. - * \returns Text for the next line, or empty string if there is - * no text for this column. - */ - std::string textForNextLine(int columnWidth) + if (bWrap_) { - if (nextLineIndex_ < 0 || !hasLinesRemaining()) + TextLineWrapperSettings settings; + settings.setLineLength(columnWidth); + TextLineWrapper wrapper(settings); + const std::string& currentLine = lines_[nextLineIndex_]; + const size_t prevOffset = nextLineOffset_; + const size_t nextOffset = wrapper.findNextLine(currentLine, prevOffset); + if (nextOffset >= currentLine.size()) { ++nextLineIndex_; - return std::string(); - } - if (bWrap_) - { - TextLineWrapperSettings settings; - settings.setLineLength(columnWidth); - TextLineWrapper wrapper(settings); - const std::string ¤tLine = lines_[nextLineIndex_]; - const size_t prevOffset = nextLineOffset_; - const size_t nextOffset - = wrapper.findNextLine(currentLine, prevOffset); - if (nextOffset >= currentLine.size()) - { - ++nextLineIndex_; - nextLineOffset_ = 0; - } - else - { - nextLineOffset_ = nextOffset; - } - return wrapper.formatLine(currentLine, prevOffset, nextOffset); + nextLineOffset_ = 0; } else { - return lines_[nextLineIndex_++]; + nextLineOffset_ = nextOffset; } + return wrapper.formatLine(currentLine, prevOffset, nextOffset); + } + else + { + return lines_[nextLineIndex_++]; } + } - //! Statit data: title of the column. - std::string title_; - //! Static data: width of the column. - int width_; - //! Static data: whether to automatically wrap input text. - bool bWrap_; - //! First line offset for the current row. - int firstLine_; - //! Text lines for the current row. - std::vector lines_; - //! Formatting state: index in `lines_` for the next line. - int nextLineIndex_; - //! Formatting state: offset within line `nextLineIndex_` for the next line. - size_t nextLineOffset_; - }; + //! Statit data: title of the column. + std::string title_; + //! Static data: width of the column. + int width_; + //! Static data: whether to automatically wrap input text. + bool bWrap_; + //! First line offset for the current row. + int firstLine_; + //! Text lines for the current row. + std::vector lines_; + //! Formatting state: index in `lines_` for the next line. + int nextLineIndex_; + //! Formatting state: offset within line `nextLineIndex_` for the next line. + size_t nextLineOffset_; + }; - //! Container type for column data. - typedef std::vector ColumnList; + //! Container type for column data. + typedef std::vector ColumnList; - //! Initializes data for an empty formatter. - Impl(); + //! Initializes data for an empty formatter. + Impl(); - /*! \brief - * Convenience method for checked access to data for a column. - * - * \param[in] index Zero-based column index. - * \returns \c columns_[index] - */ - ColumnData &columnData(int index) - { - GMX_ASSERT(index >= 0 && index < ssize(columns_), - "Invalid column index"); - return columns_[index]; - } - //! \copydoc columnData() - const ColumnData &columnData(int index) const - { - return const_cast(this)->columnData(index); - } + /*! \brief + * Convenience method for checked access to data for a column. + * + * \param[in] index Zero-based column index. + * \returns \c columns_[index] + */ + ColumnData& columnData(int index) + { + GMX_ASSERT(index >= 0 && index < ssize(columns_), "Invalid column index"); + return columns_[index]; + } + //! \copydoc columnData() + const ColumnData& columnData(int index) const + { + return const_cast(this)->columnData(index); + } - //! Container for column data. - ColumnList columns_; - //! Indentation before the first column. - int firstColumnIndent_; - //! Indentation before the last column if folded. - int foldLastColumnToNextLineIndent_; - //! If true, no output has yet been produced. - bool bFirstRow_; - //! If true, a header will be printed before the first row. - bool bPrintHeader_; + //! Container for column data. + ColumnList columns_; + //! Indentation before the first column. + int firstColumnIndent_; + //! Indentation before the last column if folded. + int foldLastColumnToNextLineIndent_; + //! If true, no output has yet been produced. + bool bFirstRow_; + //! If true, a header will be printed before the first row. + bool bPrintHeader_; }; -TextTableFormatter::Impl::Impl() - : firstColumnIndent_(0), foldLastColumnToNextLineIndent_(-1), - bFirstRow_(true), bPrintHeader_(false) +TextTableFormatter::Impl::Impl() : + firstColumnIndent_(0), + foldLastColumnToNextLineIndent_(-1), + bFirstRow_(true), + bPrintHeader_(false) { } @@ -214,16 +214,11 @@ TextTableFormatter::Impl::Impl() * TextTableFormatter */ -TextTableFormatter::TextTableFormatter() - : impl_(new Impl) -{ -} +TextTableFormatter::TextTableFormatter() : impl_(new Impl) {} -TextTableFormatter::~TextTableFormatter() -{ -} +TextTableFormatter::~TextTableFormatter() {} -void TextTableFormatter::addColumn(const char *title, int width, bool bWrap) +void TextTableFormatter::addColumn(const char* title, int width, bool bWrap) { if (title != nullptr && title[0] != '\0') { @@ -258,32 +253,32 @@ void TextTableFormatter::clear() } } -void TextTableFormatter::addColumnLine(int index, const std::string &text) +void TextTableFormatter::addColumnLine(int index, const std::string& text) { - Impl::ColumnData &column = impl_->columnData(index); + Impl::ColumnData& column = impl_->columnData(index); TextLineWrapper wrapper; std::vector lines(wrapper.wrapToVector(text)); column.lines_.insert(column.lines_.end(), lines.begin(), lines.end()); } -void TextTableFormatter::addColumnHelpTextBlock( - int index, const HelpWriterContext &context, const std::string &text) +void TextTableFormatter::addColumnHelpTextBlock(int index, + const HelpWriterContext& context, + const std::string& text) { - Impl::ColumnData &column = impl_->columnData(index); + Impl::ColumnData& column = impl_->columnData(index); TextLineWrapperSettings settings; // TODO: If in the future, there is actually a coupling between the markup // and the wrapping, this must be postponed into formatRow(), where we do // the actual line wrapping. - std::vector lines( - context.substituteMarkupAndWrapToVector(settings, text)); + std::vector lines(context.substituteMarkupAndWrapToVector(settings, text)); column.lines_.insert(column.lines_.end(), lines.begin(), lines.end()); } void TextTableFormatter::setColumnFirstLineOffset(int index, int firstLine) { GMX_ASSERT(firstLine >= 0, "Invalid first line"); - Impl::ColumnData &column = impl_->columnData(index); - column.firstLine_ = firstLine; + Impl::ColumnData& column = impl_->columnData(index); + column.firstLine_ = firstLine; } std::string TextTableFormatter::formatRow() @@ -295,9 +290,7 @@ std::string TextTableFormatter::formatRow() { size_t totalWidth = 0; result.append(impl_->firstColumnIndent_, ' '); - for (column = impl_->columns_.begin(); - column != impl_->columns_.end(); - ++column) + for (column = impl_->columns_.begin(); column != impl_->columns_.end(); ++column) { std::string title(column->title()); if (column != impl_->columns_.end() - 1) @@ -307,8 +300,7 @@ std::string TextTableFormatter::formatRow() } else { - totalWidth += std::min(column->width(), - static_cast(title.length() + 13)); + totalWidth += std::min(column->width(), static_cast(title.length() + 13)); } result.append(title); } @@ -323,9 +315,7 @@ std::string TextTableFormatter::formatRow() std::vector columnLines; int currentWidth = 0; bool bFoldLastColumn = false; - for (column = impl_->columns_.begin(); - column != impl_->columns_.end(); - ++column) + for (column = impl_->columns_.begin(); column != impl_->columns_.end(); ++column) { // Format the column into columnLines. column->startFormatting(); @@ -349,12 +339,11 @@ std::string TextTableFormatter::formatRow() } columnLines.push_back(column->textForNextLine(columnWidth)); } - if (column == impl_->columns_.end() - 1 - && impl_->foldLastColumnToNextLineIndent_ >= 0 + if (column == impl_->columns_.end() - 1 && impl_->foldLastColumnToNextLineIndent_ >= 0 && columnLines.size() >= lines.size() + column->lines_.size()) { bFoldLastColumn = true; - currentWidth += column->width(); + currentWidth += column->width(); break; } // Add columnLines into lines. @@ -389,8 +378,7 @@ std::string TextTableFormatter::formatRow() if (bFoldLastColumn) { Impl::ColumnList::reference lastColumn = impl_->columns_.back(); - const int totalIndent - = impl_->firstColumnIndent_ + impl_->foldLastColumnToNextLineIndent_; + const int totalIndent = impl_->firstColumnIndent_ + impl_->foldLastColumnToNextLineIndent_; lastColumn.startFormatting(); currentWidth -= impl_->foldLastColumnToNextLineIndent_; while (lastColumn.hasLinesRemaining()) diff --git a/src/gromacs/onlinehelp/helpformat.h b/src/gromacs/onlinehelp/helpformat.h index bf99fdd7c4..8ce680719b 100644 --- a/src/gromacs/onlinehelp/helpformat.h +++ b/src/gromacs/onlinehelp/helpformat.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -103,132 +103,131 @@ class HelpWriterContext; */ class TextTableFormatter { - public: - //! Constructs an empty formatter. - TextTableFormatter(); - ~TextTableFormatter(); +public: + //! Constructs an empty formatter. + TextTableFormatter(); + ~TextTableFormatter(); - /*! \brief - * Adds a column to the table. - * - * \param[in] title Title string for the column (used for header). - * \param[in] width Width of the column (must be > 0). - * \param[in] bWrap Whether text that exceeds \p width is - * automatically wrapped. - * - * The length of \p title must not exceed \p width. - */ - void addColumn(const char *title, int width, bool bWrap); - /*! \brief - * Sets amount on indentation before the first column. - * - * \param[in] indent Number of spaces to use for indenting. - * - * Does not throw. - */ - void setFirstColumnIndent(int indent); - /*! \brief - * Enables folding the last column to separate lines if it overflows. - * - * \param[in] indent Number of spaces to use for indenting the lines. - * - * If called with `indent >= 0`, the last column for each row is - * treated specially: if it contains more lines than the other columns, - * and if the text would fit more compactly as separate lines after the - * row, then the whole last column is written after the row with the - * given \p indent. The column text then spans the whole space - * reserved for the table, making long text fit into a smaller amount - * of vertical space. - * If not called, the last column is not treates specially. - * - * Does not throw. - */ - void setFoldLastColumnToNextLine(int indent); + /*! \brief + * Adds a column to the table. + * + * \param[in] title Title string for the column (used for header). + * \param[in] width Width of the column (must be > 0). + * \param[in] bWrap Whether text that exceeds \p width is + * automatically wrapped. + * + * The length of \p title must not exceed \p width. + */ + void addColumn(const char* title, int width, bool bWrap); + /*! \brief + * Sets amount on indentation before the first column. + * + * \param[in] indent Number of spaces to use for indenting. + * + * Does not throw. + */ + void setFirstColumnIndent(int indent); + /*! \brief + * Enables folding the last column to separate lines if it overflows. + * + * \param[in] indent Number of spaces to use for indenting the lines. + * + * If called with `indent >= 0`, the last column for each row is + * treated specially: if it contains more lines than the other columns, + * and if the text would fit more compactly as separate lines after the + * row, then the whole last column is written after the row with the + * given \p indent. The column text then spans the whole space + * reserved for the table, making long text fit into a smaller amount + * of vertical space. + * If not called, the last column is not treates specially. + * + * Does not throw. + */ + void setFoldLastColumnToNextLine(int indent); - /*! \brief - * Whether formatRow() has been successfully called. - * - * This method can be used to determine after-the-fact whether anything - * was written in the table. - * - * Does not throw. - */ - bool didOutput() const; + /*! \brief + * Whether formatRow() has been successfully called. + * + * This method can be used to determine after-the-fact whether anything + * was written in the table. + * + * Does not throw. + */ + bool didOutput() const; - /*! \brief - * Removes all text from all columns and resets the line offsets. - * - * Removes all text added using addColumnLine() and resets line offsets - * set with setColumnFirstLineOffset() to zero. - * Should be called before starting to add data for a row. - * - * Does not throw. - */ - void clear(); - /*! \brief - * Adds text to be printed in a column. - * - * \param[in] index Zero-based column index. - * \param[in] text Text to add. - * - * Can be called multiple times. Additional calls append \p text as - * additional lines. Any calls with \p text empty have no effect. - * To add an empty line, use "\n" as \p text. - * - * If \p text contains newlines, the text is automatically splitted to - * multiple lines. The same happens if automatic wrapping is on for - * the column and the text contains lines that are longer than what - * fits the column. - */ - void addColumnLine(int index, const std::string &text); - /*! \brief - * Adds text containing help markup to be printed in a column. - * - * \param[in] index Zero-based column index. - * \param[in] context Context to use for markup processing. - * \param[in] text Text to add. - * - * Works as addColumnLine(), except that it uses - * HelpWriterContext::substituteMarkupAndWrapToVector() to process - * markup in the input text instead of just wrapping it as plain text. - */ - void addColumnHelpTextBlock(int index, const HelpWriterContext &context, - const std::string &text); - /*! \brief - * Sets the first line to which text is printed for a column. - * - * \param[in] index Zero-based column index. - * \param[in] firstLine Zero-based line index from which to start the - * output. - * - * Can be called if there is no text for column \p index. - * Does not affect the output in this case. - * - * Does not throw. - */ - void setColumnFirstLineOffset(int index, int firstLine); - /*! \brief - * Formats the lines for the current row. - * - * \returns Current row formatted as a single string - * (contains newlines). - * - * Formats the data as set after the previous clear()/formatRow() using - * addColumnLine() and setColumnFirstLineOffset(). - * - * If this is the first line to be formatted, a header is also added to - * the beginning of the returned string if any column has a title. - * - * The return value always terminates with a newline. - * - * Calls clear() on successful return. - */ - std::string formatRow(); + /*! \brief + * Removes all text from all columns and resets the line offsets. + * + * Removes all text added using addColumnLine() and resets line offsets + * set with setColumnFirstLineOffset() to zero. + * Should be called before starting to add data for a row. + * + * Does not throw. + */ + void clear(); + /*! \brief + * Adds text to be printed in a column. + * + * \param[in] index Zero-based column index. + * \param[in] text Text to add. + * + * Can be called multiple times. Additional calls append \p text as + * additional lines. Any calls with \p text empty have no effect. + * To add an empty line, use "\n" as \p text. + * + * If \p text contains newlines, the text is automatically splitted to + * multiple lines. The same happens if automatic wrapping is on for + * the column and the text contains lines that are longer than what + * fits the column. + */ + void addColumnLine(int index, const std::string& text); + /*! \brief + * Adds text containing help markup to be printed in a column. + * + * \param[in] index Zero-based column index. + * \param[in] context Context to use for markup processing. + * \param[in] text Text to add. + * + * Works as addColumnLine(), except that it uses + * HelpWriterContext::substituteMarkupAndWrapToVector() to process + * markup in the input text instead of just wrapping it as plain text. + */ + void addColumnHelpTextBlock(int index, const HelpWriterContext& context, const std::string& text); + /*! \brief + * Sets the first line to which text is printed for a column. + * + * \param[in] index Zero-based column index. + * \param[in] firstLine Zero-based line index from which to start the + * output. + * + * Can be called if there is no text for column \p index. + * Does not affect the output in this case. + * + * Does not throw. + */ + void setColumnFirstLineOffset(int index, int firstLine); + /*! \brief + * Formats the lines for the current row. + * + * \returns Current row formatted as a single string + * (contains newlines). + * + * Formats the data as set after the previous clear()/formatRow() using + * addColumnLine() and setColumnFirstLineOffset(). + * + * If this is the first line to be formatted, a header is also added to + * the beginning of the returned string if any column has a title. + * + * The return value always terminates with a newline. + * + * Calls clear() on successful return. + */ + std::string formatRow(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/onlinehelp/helpmanager.cpp b/src/gromacs/onlinehelp/helpmanager.cpp index cc4c9d75f4..de9dfcedd8 100644 --- a/src/gromacs/onlinehelp/helpmanager.cpp +++ b/src/gromacs/onlinehelp/helpmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,35 +65,29 @@ namespace gmx */ class HelpManager::Impl { - public: - //! Container type for keeping the stack of active topics. - typedef std::vector TopicStack; - - //! Initializes a new manager with the given context. - explicit Impl(const HelpWriterContext &context) - : rootContext_(context) - { - } - - //! Whether the active topic is the root topic. - bool isAtRootTopic() const { return topicStack_.size() == 1; } - //! Returns the active topic. - const IHelpTopic ¤tTopic() const - { - return *topicStack_.back(); - } - //! Formats the active topic as a string, including its parent topics. - std::string currentTopicAsString() const; - - //! Context with which the manager was initialized. - const HelpWriterContext &rootContext_; - /*! \brief - * Stack of active topics. - * - * The first item is always the root topic, and each item is a subtopic - * of the preceding item. The last item is the currently active topic. - */ - TopicStack topicStack_; +public: + //! Container type for keeping the stack of active topics. + typedef std::vector TopicStack; + + //! Initializes a new manager with the given context. + explicit Impl(const HelpWriterContext& context) : rootContext_(context) {} + + //! Whether the active topic is the root topic. + bool isAtRootTopic() const { return topicStack_.size() == 1; } + //! Returns the active topic. + const IHelpTopic& currentTopic() const { return *topicStack_.back(); } + //! Formats the active topic as a string, including its parent topics. + std::string currentTopicAsString() const; + + //! Context with which the manager was initialized. + const HelpWriterContext& rootContext_; + /*! \brief + * Stack of active topics. + * + * The first item is always the root topic, and each item is a subtopic + * of the preceding item. The last item is the currently active topic. + */ + TopicStack topicStack_; }; std::string HelpManager::Impl::currentTopicAsString() const @@ -115,54 +109,48 @@ std::string HelpManager::Impl::currentTopicAsString() const * HelpManager */ -HelpManager::HelpManager(const IHelpTopic &rootTopic, - const HelpWriterContext &context) - : impl_(new Impl(context)) +HelpManager::HelpManager(const IHelpTopic& rootTopic, const HelpWriterContext& context) : + impl_(new Impl(context)) { impl_->topicStack_.push_back(&rootTopic); } -HelpManager::~HelpManager() -{ -} +HelpManager::~HelpManager() {} -void HelpManager::enterTopic(const char *name) +void HelpManager::enterTopic(const char* name) { - const IHelpTopic &topic = impl_->currentTopic(); + const IHelpTopic& topic = impl_->currentTopic(); if (!topic.hasSubTopics()) { - GMX_THROW(InvalidInputError( - formatString("Help topic '%s' has no subtopics", - impl_->currentTopicAsString().c_str()))); + GMX_THROW(InvalidInputError(formatString("Help topic '%s' has no subtopics", + impl_->currentTopicAsString().c_str()))); } - const IHelpTopic *newTopic = topic.findSubTopic(name); + const IHelpTopic* newTopic = topic.findSubTopic(name); if (newTopic == nullptr) { if (impl_->isAtRootTopic()) { - GMX_THROW(InvalidInputError( - formatString("No help available for '%s'", name))); + GMX_THROW(InvalidInputError(formatString("No help available for '%s'", name))); } else { - GMX_THROW(InvalidInputError( - formatString("Help topic '%s' has no subtopic '%s'", - impl_->currentTopicAsString().c_str(), name))); + GMX_THROW(InvalidInputError(formatString("Help topic '%s' has no subtopic '%s'", + impl_->currentTopicAsString().c_str(), name))); } } impl_->topicStack_.push_back(newTopic); } -void HelpManager::enterTopic(const std::string &name) +void HelpManager::enterTopic(const std::string& name) { enterTopic(name.c_str()); } void HelpManager::writeCurrentTopic() const { - const IHelpTopic &topic = impl_->currentTopic(); - const char *title = topic.title(); - HelpWriterContext context(impl_->rootContext_); + const IHelpTopic& topic = impl_->currentTopic(); + const char* title = topic.title(); + HelpWriterContext context(impl_->rootContext_); context.enterSubSection(title != nullptr ? title : ""); topic.writeHelp(context); } diff --git a/src/gromacs/onlinehelp/helpmanager.h b/src/gromacs/onlinehelp/helpmanager.h index b258f3cac8..7c68743224 100644 --- a/src/gromacs/onlinehelp/helpmanager.h +++ b/src/gromacs/onlinehelp/helpmanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,45 +61,44 @@ class IHelpTopic; */ class HelpManager { - public: - /*! \brief - * Creates a manager that uses a given root topic. - * - * \param[in] rootTopic Help topic that can be accessed through this - * manager. - * \param[in] context Context object for writing the help. - * \throws std::bad_alloc if out of memory. - * - * The provided topic and context objects must remain valid for the - * lifetime of this manager object. - */ - HelpManager(const IHelpTopic &rootTopic, - const HelpWriterContext &context); - ~HelpManager(); +public: + /*! \brief + * Creates a manager that uses a given root topic. + * + * \param[in] rootTopic Help topic that can be accessed through this + * manager. + * \param[in] context Context object for writing the help. + * \throws std::bad_alloc if out of memory. + * + * The provided topic and context objects must remain valid for the + * lifetime of this manager object. + */ + HelpManager(const IHelpTopic& rootTopic, const HelpWriterContext& context); + ~HelpManager(); - /*! \brief - * Enters a subtopic with the given name under the active topic. - * - * \param[in] name Subtopic name to enter. - * \throws std::bad_allod if out of memory. - * \throws InvalidInputError if topic with \p name is not found. - */ - void enterTopic(const char *name); - //! \copydoc enterTopic(const char *) - void enterTopic(const std::string &name); + /*! \brief + * Enters a subtopic with the given name under the active topic. + * + * \param[in] name Subtopic name to enter. + * \throws std::bad_allod if out of memory. + * \throws InvalidInputError if topic with \p name is not found. + */ + void enterTopic(const char* name); + //! \copydoc enterTopic(const char *) + void enterTopic(const std::string& name); - /*! \brief - * Writes out the help for the currently active topic. - * - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - void writeCurrentTopic() const; + /*! \brief + * Writes out the help for the currently active topic. + * + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + void writeCurrentTopic() const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/onlinehelp/helptopic.cpp b/src/gromacs/onlinehelp/helptopic.cpp index 6126171739..45b5054e9b 100644 --- a/src/gromacs/onlinehelp/helptopic.cpp +++ b/src/gromacs/onlinehelp/helptopic.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,13 +65,12 @@ bool AbstractSimpleHelpTopic::hasSubTopics() const return false; } -const IHelpTopic * -AbstractSimpleHelpTopic::findSubTopic(const char * /* name */) const +const IHelpTopic* AbstractSimpleHelpTopic::findSubTopic(const char* /* name */) const { return nullptr; } -void AbstractSimpleHelpTopic::writeHelp(const HelpWriterContext &context) const +void AbstractSimpleHelpTopic::writeHelp(const HelpWriterContext& context) const { context.writeTextBlock(helpText()); } @@ -87,46 +86,40 @@ void AbstractSimpleHelpTopic::writeHelp(const HelpWriterContext &context) const */ class AbstractCompositeHelpTopic::Impl { - public: - //! Container for subtopics. - typedef std::vector SubTopicList; - //! Container for mapping subtopic names to help topic objects. - typedef std::map SubTopicMap; - - /*! \brief - * Subtopics in the order they were added. - * - * Owns the contained subtopics. - */ - SubTopicList subTopics_; - /*! \brief - * Maps subtopic names to help topic objects. - * - * Points to objects in the \a subTopics_ map. - */ - SubTopicMap subTopicMap_; +public: + //! Container for subtopics. + typedef std::vector SubTopicList; + //! Container for mapping subtopic names to help topic objects. + typedef std::map SubTopicMap; + + /*! \brief + * Subtopics in the order they were added. + * + * Owns the contained subtopics. + */ + SubTopicList subTopics_; + /*! \brief + * Maps subtopic names to help topic objects. + * + * Points to objects in the \a subTopics_ map. + */ + SubTopicMap subTopicMap_; }; /******************************************************************** * AbstractCompositeHelpTopic */ -AbstractCompositeHelpTopic::AbstractCompositeHelpTopic() - : impl_(new Impl) -{ -} +AbstractCompositeHelpTopic::AbstractCompositeHelpTopic() : impl_(new Impl) {} -AbstractCompositeHelpTopic::~AbstractCompositeHelpTopic() -{ -} +AbstractCompositeHelpTopic::~AbstractCompositeHelpTopic() {} bool AbstractCompositeHelpTopic::hasSubTopics() const { return !impl_->subTopics_.empty(); } -const IHelpTopic * -AbstractCompositeHelpTopic::findSubTopic(const char *name) const +const IHelpTopic* AbstractCompositeHelpTopic::findSubTopic(const char* name) const { Impl::SubTopicMap::const_iterator topic = impl_->subTopicMap_.find(name); if (topic == impl_->subTopicMap_.end()) @@ -136,22 +129,21 @@ AbstractCompositeHelpTopic::findSubTopic(const char *name) const return topic->second; } -void AbstractCompositeHelpTopic::writeHelp(const HelpWriterContext &context) const +void AbstractCompositeHelpTopic::writeHelp(const HelpWriterContext& context) const { context.writeTextBlock(helpText()); writeSubTopicList(context, "\nAvailable subtopics:"); } -bool -AbstractCompositeHelpTopic::writeSubTopicList(const HelpWriterContext &context, - const std::string &title) const +bool AbstractCompositeHelpTopic::writeSubTopicList(const HelpWriterContext& context, + const std::string& title) const { if (context.outputFormat() != eHelpOutputFormat_Console) { Impl::SubTopicList::const_iterator topic; for (topic = impl_->subTopics_.begin(); topic != impl_->subTopics_.end(); ++topic) { - const char *const title = (*topic)->title(); + const char* const title = (*topic)->title(); if (!isNullOrEmpty(title)) { context.paragraphBreak(); @@ -162,11 +154,11 @@ AbstractCompositeHelpTopic::writeSubTopicList(const HelpWriterContext &context, } return true; } - int maxNameLength = 0; + int maxNameLength = 0; Impl::SubTopicMap::const_iterator topic; for (topic = impl_->subTopicMap_.begin(); topic != impl_->subTopicMap_.end(); ++topic) { - const char *const title = topic->second->title(); + const char* const title = topic->second->title(); if (!isNullOrEmpty(title)) { int nameLength = static_cast(topic->first.length()); @@ -180,7 +172,7 @@ AbstractCompositeHelpTopic::writeSubTopicList(const HelpWriterContext &context, { return false; } - TextWriter &file = context.outputFile(); + TextWriter& file = context.outputFile(); TextTableFormatter formatter; formatter.addColumn(nullptr, maxNameLength + 1, false); formatter.addColumn(nullptr, 72 - maxNameLength, true); @@ -188,8 +180,8 @@ AbstractCompositeHelpTopic::writeSubTopicList(const HelpWriterContext &context, file.writeLine(title); for (topic = impl_->subTopicMap_.begin(); topic != impl_->subTopicMap_.end(); ++topic) { - const char *const name = topic->first.c_str(); - const char *const title = topic->second->title(); + const char* const name = topic->first.c_str(); + const char* const title = topic->second->title(); if (!isNullOrEmpty(title)) { formatter.clear(); @@ -205,7 +197,7 @@ void AbstractCompositeHelpTopic::addSubTopic(HelpTopicPointer topic) { GMX_ASSERT(impl_->subTopicMap_.find(topic->name()) == impl_->subTopicMap_.end(), "Attempted to register a duplicate help topic name"); - const IHelpTopic *topicPtr = topic.get(); + const IHelpTopic* topicPtr = topic.get(); impl_->subTopics_.reserve(impl_->subTopics_.size() + 1); impl_->subTopicMap_.insert(std::make_pair(std::string(topicPtr->name()), topicPtr)); impl_->subTopics_.push_back(std::move(topic)); diff --git a/src/gromacs/onlinehelp/helptopic.h b/src/gromacs/onlinehelp/helptopic.h index c684020749..044a15c0d0 100644 --- a/src/gromacs/onlinehelp/helptopic.h +++ b/src/gromacs/onlinehelp/helptopic.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,24 +67,24 @@ namespace gmx */ class AbstractSimpleHelpTopic : public IHelpTopic { - public: - const char *name() const override = 0; - const char *title() const override = 0; +public: + const char* name() const override = 0; + const char* title() const override = 0; - bool hasSubTopics() const override; - const IHelpTopic *findSubTopic(const char *name) const override; + bool hasSubTopics() const override; + const IHelpTopic* findSubTopic(const char* name) const override; - void writeHelp(const HelpWriterContext &context) const override; + void writeHelp(const HelpWriterContext& context) const override; - protected: - /*! \brief - * Returns the help text for this topic. - * - * writeHelp() calls this method to obtain the actual text to format - * for the topic. Markup substitution etc. is done automatically by - * writeHelp(). - */ - virtual std::string helpText() const = 0; +protected: + /*! \brief + * Returns the help text for this topic. + * + * writeHelp() calls this method to obtain the actual text to format + * for the topic. Markup substitution etc. is done automatically by + * writeHelp(). + */ + virtual std::string helpText() const = 0; }; /*! \libinternal \brief @@ -105,78 +105,77 @@ class AbstractSimpleHelpTopic : public IHelpTopic */ class AbstractCompositeHelpTopic : public IHelpTopic { - public: - AbstractCompositeHelpTopic(); - ~AbstractCompositeHelpTopic() override; +public: + AbstractCompositeHelpTopic(); + ~AbstractCompositeHelpTopic() override; - const char *name() const override = 0; - const char *title() const override = 0; + const char* name() const override = 0; + const char* title() const override = 0; - bool hasSubTopics() const override; - const IHelpTopic *findSubTopic(const char *name) const override; + bool hasSubTopics() const override; + const IHelpTopic* findSubTopic(const char* name) const override; - void writeHelp(const HelpWriterContext &context) const override; + void writeHelp(const HelpWriterContext& context) const override; - /*! \brief - * Adds a given topic as a subtopic of this topic. - * - * \param topic Topis to add. - * \throws std::bad_alloc if out of memory. - * - * This topic takes ownership of the object. - * - * \see registerSubTopic() - */ - void addSubTopic(HelpTopicPointer topic); - /*! \brief - * Registers a subtopic of a certain type to this topic. - * - * \tparam Topic Type of topic to register. - * \throws std::bad_alloc if out of memory. - * - * \p Topic must be default-constructible and implement - * IHelpTopic. - * - * This method is provided as a convenient alternative to addSubTopic() - * for cases where each topic is implemented by a different type - * (which is a common case outside unit tests). - */ - template - void registerSubTopic() - { - addSubTopic(HelpTopicPointer(new Topic)); - } + /*! \brief + * Adds a given topic as a subtopic of this topic. + * + * \param topic Topis to add. + * \throws std::bad_alloc if out of memory. + * + * This topic takes ownership of the object. + * + * \see registerSubTopic() + */ + void addSubTopic(HelpTopicPointer topic); + /*! \brief + * Registers a subtopic of a certain type to this topic. + * + * \tparam Topic Type of topic to register. + * \throws std::bad_alloc if out of memory. + * + * \p Topic must be default-constructible and implement + * IHelpTopic. + * + * This method is provided as a convenient alternative to addSubTopic() + * for cases where each topic is implemented by a different type + * (which is a common case outside unit tests). + */ + template + void registerSubTopic() + { + addSubTopic(HelpTopicPointer(new Topic)); + } - protected: - //! \copydoc gmx::AbstractSimpleHelpTopic::helpText() - virtual std::string helpText() const = 0; +protected: + //! \copydoc gmx::AbstractSimpleHelpTopic::helpText() + virtual std::string helpText() const = 0; - /*! \brief - * Writes the list of subtopics. - * - * \param[in] context Context for writing the help. - * \param[in] title Title for the written list. - * \returns true if anything was printed. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * Subtopics with empty titles are skipped from the list. - * If there would be no subtopics in the list, \p title is not printed - * either. - * - * This method is provided for cases where helpText() does not provide - * the needed flexibility and the derived class needs to override - * writeHelp(). This method can then be called to print the same - * subtopic list that is printed by the default writeHelp() - * implementation. - */ - bool writeSubTopicList(const HelpWriterContext &context, - const std::string &title) const; + /*! \brief + * Writes the list of subtopics. + * + * \param[in] context Context for writing the help. + * \param[in] title Title for the written list. + * \returns true if anything was printed. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * Subtopics with empty titles are skipped from the list. + * If there would be no subtopics in the list, \p title is not printed + * either. + * + * This method is provided for cases where helpText() does not provide + * the needed flexibility and the derived class needs to override + * writeHelp(). This method can then be called to print the same + * subtopic list that is printed by the default writeHelp() + * implementation. + */ + bool writeSubTopicList(const HelpWriterContext& context, const std::string& title) const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \cond libapi */ @@ -185,8 +184,7 @@ class AbstractCompositeHelpTopic : public IHelpTopic * * \inlibraryapi */ -typedef std::unique_ptr - CompositeHelpTopicPointer; +typedef std::unique_ptr CompositeHelpTopicPointer; //! \endcond /*! \libinternal \brief @@ -220,24 +218,15 @@ typedef std::unique_ptr * \inlibraryapi * \ingroup module_onlinehelp */ -template +template class SimpleHelpTopic : public AbstractSimpleHelpTopic { - public: - const char *name() const override - { - return HelpText::name; - } - const char *title() const override - { - return HelpText::title; - } +public: + const char* name() const override { return HelpText::name; } + const char* title() const override { return HelpText::title; } - protected: - std::string helpText() const override - { - return joinStrings(HelpText::text, "\n"); - } +protected: + std::string helpText() const override { return joinStrings(HelpText::text, "\n"); } }; /*! \libinternal \brief @@ -253,28 +242,19 @@ class SimpleHelpTopic : public AbstractSimpleHelpTopic * \inlibraryapi * \ingroup module_onlinehelp */ -template +template class CompositeHelpTopic : public AbstractCompositeHelpTopic { - public: - // copydocs are needed with Doxygen 1.8.10, but not 1.8.5... - //! \copydoc gmx::AbstractCompositeHelpTopic::name() - const char *name() const override - { - return HelpText::name; - } - //! \copydoc gmx::AbstractCompositeHelpTopic::title() - const char *title() const override - { - return HelpText::title; - } +public: + // copydocs are needed with Doxygen 1.8.10, but not 1.8.5... + //! \copydoc gmx::AbstractCompositeHelpTopic::name() + const char* name() const override { return HelpText::name; } + //! \copydoc gmx::AbstractCompositeHelpTopic::title() + const char* title() const override { return HelpText::title; } - protected: - //! \copydoc gmx::AbstractCompositeHelpTopic::helpText() - std::string helpText() const override - { - return joinStrings(HelpText::text, "\n"); - } +protected: + //! \copydoc gmx::AbstractCompositeHelpTopic::helpText() + std::string helpText() const override { return joinStrings(HelpText::text, "\n"); } }; } // namespace gmx diff --git a/src/gromacs/onlinehelp/helpwritercontext.cpp b/src/gromacs/onlinehelp/helpwritercontext.cpp index 71ff04577e..3b022a1743 100644 --- a/src/gromacs/onlinehelp/helpwritercontext.cpp +++ b/src/gromacs/onlinehelp/helpwritercontext.cpp @@ -73,8 +73,8 @@ const char g_titleChars[] = "=-^*~+#'_."; struct t_sandr { - const char *search; - const char *replace; + const char* search; + const char* replace; }; /* The order of these arrays is significant. Text search and replace @@ -86,110 +86,41 @@ struct t_sandr //! List of replacements for console output. const t_sandr sandrTty[] = { - { "\\*", "*" }, - { "\\=", "=" }, - { "[REF]", "" }, - { "[ref]", "" }, - { "[TT]", "" }, - { "[tt]", "" }, - { "[BB]", "" }, - { "[bb]", "" }, - { "[IT]", "" }, - { "[it]", "" }, - { "[MATH]", "" }, - { "[math]", "" }, - { "[CHEVRON]", "<" }, - { "[chevron]", ">" }, - { "[MAG]", "|" }, - { "[mag]", "|" }, - { "[INT]", "integral" }, - { "[FROM]", " from " }, - { "[from]", "" }, - { "[TO]", " to " }, - { "[to]", " of" }, - { "[int]", "" }, - { "[SUM]", "sum" }, - { "[sum]", "" }, - { "[SUB]", "_" }, - { "[sub]", "" }, - { "[SQRT]", "sqrt(" }, - { "[sqrt]", ")" }, - { "[EXP]", "exp(" }, - { "[exp]", ")" }, - { "[LN]", "ln(" }, - { "[ln]", ")" }, - { "[LOG]", "log(" }, - { "[log]", ")" }, - { "[COS]", "cos(" }, - { "[cos]", ")" }, - { "[SIN]", "sin(" }, - { "[sin]", ")" }, - { "[TAN]", "tan(" }, - { "[tan]", ")" }, - { "[COSH]", "cosh(" }, - { "[cosh]", ")" }, - { "[SINH]", "sinh(" }, - { "[sinh]", ")" }, - { "[TANH]", "tanh(" }, - { "[tanh]", ")" }, - { "[PAR]", "\n\n" }, - { "[GRK]", "" }, + { "\\*", "*" }, { "\\=", "=" }, { "[REF]", "" }, { "[ref]", "" }, + { "[TT]", "" }, { "[tt]", "" }, { "[BB]", "" }, { "[bb]", "" }, + { "[IT]", "" }, { "[it]", "" }, { "[MATH]", "" }, { "[math]", "" }, + { "[CHEVRON]", "<" }, { "[chevron]", ">" }, { "[MAG]", "|" }, { "[mag]", "|" }, + { "[INT]", "integral" }, { "[FROM]", " from " }, { "[from]", "" }, { "[TO]", " to " }, + { "[to]", " of" }, { "[int]", "" }, { "[SUM]", "sum" }, { "[sum]", "" }, + { "[SUB]", "_" }, { "[sub]", "" }, { "[SQRT]", "sqrt(" }, { "[sqrt]", ")" }, + { "[EXP]", "exp(" }, { "[exp]", ")" }, { "[LN]", "ln(" }, { "[ln]", ")" }, + { "[LOG]", "log(" }, { "[log]", ")" }, { "[COS]", "cos(" }, { "[cos]", ")" }, + { "[SIN]", "sin(" }, { "[sin]", ")" }, { "[TAN]", "tan(" }, { "[tan]", ")" }, + { "[COSH]", "cosh(" }, { "[cosh]", ")" }, { "[SINH]", "sinh(" }, { "[sinh]", ")" }, + { "[TANH]", "tanh(" }, { "[tanh]", ")" }, { "[PAR]", "\n\n" }, { "[GRK]", "" }, { "[grk]", "" } }; //! List of replacements for reStructuredText output. const t_sandr sandrRst[] = { - { "[TT]", "``" }, - { "[tt]", "``" }, - { "[BB]", "**" }, - { "[bb]", "**" }, - { "[IT]", "*" }, - { "[it]", "*" }, - { "[MATH]", "" }, - { "[math]", "" }, - { "[CHEVRON]", "<" }, - { "[chevron]", ">" }, - { "[MAG]", "\\|" }, - { "[mag]", "\\|" }, - { "[INT]", "integral" }, - { "[FROM]", " from " }, - { "[from]", "" }, - { "[TO]", " to " }, - { "[to]", " of" }, - { "[int]", "" }, - { "[SUM]", "sum" }, - { "[sum]", "" }, - { "[SUB]", "_" }, - { "[sub]", "" }, - { "[SQRT]", "sqrt(" }, - { "[sqrt]", ")" }, - { "[EXP]", "exp(" }, - { "[exp]", ")" }, - { "[LN]", "ln(" }, - { "[ln]", ")" }, - { "[LOG]", "log(" }, - { "[log]", ")" }, - { "[COS]", "cos(" }, - { "[cos]", ")" }, - { "[SIN]", "sin(" }, - { "[sin]", ")" }, - { "[TAN]", "tan(" }, - { "[tan]", ")" }, - { "[COSH]", "cosh(" }, - { "[cosh]", ")" }, - { "[SINH]", "sinh(" }, - { "[sinh]", ")" }, - { "[TANH]", "tanh(" }, - { "[tanh]", ")" }, - { "[PAR]", "\n\n" }, - { "[GRK]", "" }, + { "[TT]", "``" }, { "[tt]", "``" }, { "[BB]", "**" }, { "[bb]", "**" }, + { "[IT]", "*" }, { "[it]", "*" }, { "[MATH]", "" }, { "[math]", "" }, + { "[CHEVRON]", "<" }, { "[chevron]", ">" }, { "[MAG]", "\\|" }, { "[mag]", "\\|" }, + { "[INT]", "integral" }, { "[FROM]", " from " }, { "[from]", "" }, { "[TO]", " to " }, + { "[to]", " of" }, { "[int]", "" }, { "[SUM]", "sum" }, { "[sum]", "" }, + { "[SUB]", "_" }, { "[sub]", "" }, { "[SQRT]", "sqrt(" }, { "[sqrt]", ")" }, + { "[EXP]", "exp(" }, { "[exp]", ")" }, { "[LN]", "ln(" }, { "[ln]", ")" }, + { "[LOG]", "log(" }, { "[log]", ")" }, { "[COS]", "cos(" }, { "[cos]", ")" }, + { "[SIN]", "sin(" }, { "[sin]", ")" }, { "[TAN]", "tan(" }, { "[tan]", ")" }, + { "[COSH]", "cosh(" }, { "[cosh]", ")" }, { "[SINH]", "sinh(" }, { "[sinh]", ")" }, + { "[TANH]", "tanh(" }, { "[tanh]", ")" }, { "[PAR]", "\n\n" }, { "[GRK]", "" }, { "[grk]", "" } }; /*! \brief * Replaces all entries from a list of replacements. */ -std::string repall(const std::string &s, int nsr, const t_sandr sa[]) +std::string repall(const std::string& s, int nsr, const t_sandr sa[]) { std::string result(s); for (int i = 0; i < nsr; ++i) @@ -202,8 +133,8 @@ std::string repall(const std::string &s, int nsr, const t_sandr sa[]) /*! \brief * Replaces all entries from a list of replacements. */ -template -std::string repall(const std::string &s, const t_sandr (&sa)[nsr]) +template +std::string repall(const std::string& s, const t_sandr (&sa)[nsr]) { return repall(s, nsr, sa); } @@ -216,19 +147,19 @@ std::string repall(const std::string &s, const t_sandr (&sa)[nsr]) */ class IWrapper { - public: - virtual ~IWrapper() {} - - /*! \brief - * Provides the wrapping settings. - * - * HelpWriterContext::Impl::processMarkup() may provide some default - * values for the settings if they are not set; this is the reason the - * return value is not const. - */ - virtual TextLineWrapperSettings &settings() = 0; - //! Appends the given string to output. - virtual void wrap(const std::string &text) = 0; +public: + virtual ~IWrapper() {} + + /*! \brief + * Provides the wrapping settings. + * + * HelpWriterContext::Impl::processMarkup() may provide some default + * values for the settings if they are not set; this is the reason the + * return value is not const. + */ + virtual TextLineWrapperSettings& settings() = 0; + //! Appends the given string to output. + virtual void wrap(const std::string& text) = 0; }; /*! \brief @@ -236,27 +167,18 @@ class IWrapper */ class WrapperToString : public IWrapper { - public: - //! Creates a wrapper with the given settings. - explicit WrapperToString(const TextLineWrapperSettings &settings) - : wrapper_(settings) - { - } +public: + //! Creates a wrapper with the given settings. + explicit WrapperToString(const TextLineWrapperSettings& settings) : wrapper_(settings) {} - TextLineWrapperSettings &settings() override - { - return wrapper_.settings(); - } - void wrap(const std::string &text) override - { - result_.append(wrapper_.wrapToString(text)); - } - //! Returns the result string. - const std::string &result() const { return result_; } + TextLineWrapperSettings& settings() override { return wrapper_.settings(); } + void wrap(const std::string& text) override { result_.append(wrapper_.wrapToString(text)); } + //! Returns the result string. + const std::string& result() const { return result_; } - private: - TextLineWrapper wrapper_; - std::string result_; +private: + TextLineWrapper wrapper_; + std::string result_; }; /*! \brief @@ -264,28 +186,22 @@ class WrapperToString : public IWrapper */ class WrapperToVector : public IWrapper { - public: - //! Creates a wrapper with the given settings. - explicit WrapperToVector(const TextLineWrapperSettings &settings) - : wrapper_(settings) - { - } +public: + //! Creates a wrapper with the given settings. + explicit WrapperToVector(const TextLineWrapperSettings& settings) : wrapper_(settings) {} - TextLineWrapperSettings &settings() override - { - return wrapper_.settings(); - } - void wrap(const std::string &text) override - { - const std::vector &lines = wrapper_.wrapToVector(text); - result_.insert(result_.end(), lines.begin(), lines.end()); - } - //! Returns a vector with the output lines. - const std::vector &result() const { return result_; } + TextLineWrapperSettings& settings() override { return wrapper_.settings(); } + void wrap(const std::string& text) override + { + const std::vector& lines = wrapper_.wrapToVector(text); + result_.insert(result_.end(), lines.begin(), lines.end()); + } + //! Returns a vector with the output lines. + const std::vector& result() const { return result_; } - private: - TextLineWrapper wrapper_; - std::vector result_; +private: + TextLineWrapper wrapper_; + std::vector result_; }; /*! \brief @@ -295,7 +211,7 @@ class WrapperToVector : public IWrapper * \returns \p text with all characters transformed to uppercase. * \throws std::bad_alloc if out of memory. */ -std::string toUpperCase(const std::string &text) +std::string toUpperCase(const std::string& text) { std::string result(text); std::transform(result.begin(), result.end(), result.begin(), toupper); @@ -310,7 +226,7 @@ std::string toUpperCase(const std::string &text) * with just two newlines. * \throws std::bad_alloc if out of memory. */ -std::string removeExtraNewlinesRst(const std::string &text) +std::string removeExtraNewlinesRst(const std::string& text) { // Start from 2, so that all newlines in the beginning get stripped off. int newlineCount = 2; @@ -342,7 +258,7 @@ std::string removeExtraNewlinesRst(const std::string &text) //! \} -} // namespace +} // namespace /******************************************************************** * HelpLinks::Impl @@ -355,59 +271,46 @@ std::string removeExtraNewlinesRst(const std::string &text) */ class HelpLinks::Impl { - public: - struct LinkItem +public: + struct LinkItem + { + LinkItem(const std::string& linkName, const std::string& replacement) : + linkName(linkName), + replacement(replacement) { - LinkItem(const std::string &linkName, - const std::string &replacement) - : linkName(linkName), replacement(replacement) - { - } - std::string linkName; - std::string replacement; - }; + } + std::string linkName; + std::string replacement; + }; - //! Shorthand for a list of links. - typedef std::vector LinkList; + //! Shorthand for a list of links. + typedef std::vector LinkList; - //! Initializes empty links with the given format. - explicit Impl(HelpOutputFormat format) : format_(format) - { - } + //! Initializes empty links with the given format. + explicit Impl(HelpOutputFormat format) : format_(format) {} - //! List of links. - LinkList links_; - //! Output format for which the links are formatted. - HelpOutputFormat format_; + //! List of links. + LinkList links_; + //! Output format for which the links are formatted. + HelpOutputFormat format_; }; /******************************************************************** * HelpLinks */ -HelpLinks::HelpLinks(HelpOutputFormat format) : impl_(new Impl(format)) -{ -} +HelpLinks::HelpLinks(HelpOutputFormat format) : impl_(new Impl(format)) {} -HelpLinks::~HelpLinks() -{ -} +HelpLinks::~HelpLinks() {} -void HelpLinks::addLink(const std::string &linkName, - const std::string &targetName, - const std::string &displayName) +void HelpLinks::addLink(const std::string& linkName, const std::string& targetName, const std::string& displayName) { std::string replacement; switch (impl_->format_) { - case eHelpOutputFormat_Console: - replacement = repall(displayName, sandrTty); - break; - case eHelpOutputFormat_Rst: - replacement = targetName; - break; - default: - GMX_RELEASE_ASSERT(false, "Output format not implemented for links"); + case eHelpOutputFormat_Console: replacement = repall(displayName, sandrTty); break; + case eHelpOutputFormat_Rst: replacement = targetName; break; + default: GMX_RELEASE_ASSERT(false, "Output format not implemented for links"); } impl_->links_.emplace_back(linkName, replacement); } @@ -423,127 +326,125 @@ void HelpLinks::addLink(const std::string &linkName, */ class HelpWriterContext::Impl { +public: + /*! \brief + * Shared, non-modifiable state for context objects. + * + * Contents of this structure are shared between all context objects + * that are created from a common parent. + * This state should not be modified after construction. + * + * \ingroup module_onlinehelp + */ + class SharedState + { public: + //! Initializes the state with the given parameters. + SharedState(TextWriter* writer, HelpOutputFormat format, const HelpLinks* links) : + file_(*writer), + format_(format), + links_(links) + { + } + /*! \brief - * Shared, non-modifiable state for context objects. + * Returns a formatter for formatting options lists for console + * output. * - * Contents of this structure are shared between all context objects - * that are created from a common parent. - * This state should not be modified after construction. - * - * \ingroup module_onlinehelp + * The formatter is lazily initialized on first access. */ - class SharedState - { - public: - //! Initializes the state with the given parameters. - SharedState(TextWriter *writer, HelpOutputFormat format, - const HelpLinks *links) - : file_(*writer), format_(format), links_(links) - { - } - - /*! \brief - * Returns a formatter for formatting options lists for console - * output. - * - * The formatter is lazily initialized on first access. - */ - TextTableFormatter &consoleOptionsFormatter() const - { - GMX_RELEASE_ASSERT(format_ == eHelpOutputFormat_Console, - "Accessing console formatter for non-console output"); - if (!consoleOptionsFormatter_) - { - consoleOptionsFormatter_ = std::make_unique(); - consoleOptionsFormatter_->setFirstColumnIndent(1); - consoleOptionsFormatter_->addColumn(nullptr, 7, false); - consoleOptionsFormatter_->addColumn(nullptr, 18, false); - consoleOptionsFormatter_->addColumn(nullptr, 16, false); - consoleOptionsFormatter_->addColumn(nullptr, 28, false); - } - return *consoleOptionsFormatter_; - } - - //! Writer for writing the help. - TextWriter &file_; - //! Output format for the help output. - HelpOutputFormat format_; - //! Links to use. - const HelpLinks *links_; - - private: - //! Formatter for console output options. - // Never releases ownership. - mutable std::unique_ptr consoleOptionsFormatter_; - - GMX_DISALLOW_COPY_AND_ASSIGN(SharedState); - }; - - struct ReplaceItem + TextTableFormatter& consoleOptionsFormatter() const { - ReplaceItem(const std::string &search, - const std::string &replace) - : search(search), replace(replace) + GMX_RELEASE_ASSERT(format_ == eHelpOutputFormat_Console, + "Accessing console formatter for non-console output"); + if (!consoleOptionsFormatter_) { + consoleOptionsFormatter_ = std::make_unique(); + consoleOptionsFormatter_->setFirstColumnIndent(1); + consoleOptionsFormatter_->addColumn(nullptr, 7, false); + consoleOptionsFormatter_->addColumn(nullptr, 18, false); + consoleOptionsFormatter_->addColumn(nullptr, 16, false); + consoleOptionsFormatter_->addColumn(nullptr, 28, false); } - std::string search; - std::string replace; - }; - - //! Smart pointer type for managing the shared state. - typedef std::shared_ptr StatePointer; - //! Shorthand for a list of markup/other replacements. - typedef std::vector ReplaceList; - - //! Initializes the context with the given state and section depth. - Impl(const StatePointer &state, int sectionDepth) - : state_(state), sectionDepth_(sectionDepth) - { + return *consoleOptionsFormatter_; } - //! Copies the context. - Impl(const Impl &) = default; - //! Adds a new replacement. - void addReplacement(const std::string &search, - const std::string &replace) + //! Writer for writing the help. + TextWriter& file_; + //! Output format for the help output. + HelpOutputFormat format_; + //! Links to use. + const HelpLinks* links_; + + private: + //! Formatter for console output options. + // Never releases ownership. + mutable std::unique_ptr consoleOptionsFormatter_; + + GMX_DISALLOW_COPY_AND_ASSIGN(SharedState); + }; + + struct ReplaceItem + { + ReplaceItem(const std::string& search, const std::string& replace) : + search(search), + replace(replace) { - replacements_.emplace_back(search, replace); } + std::string search; + std::string replace; + }; - //! Replaces links in a given string. - std::string replaceLinks(const std::string &input) const; + //! Smart pointer type for managing the shared state. + typedef std::shared_ptr StatePointer; + //! Shorthand for a list of markup/other replacements. + typedef std::vector ReplaceList; - /*! \brief - * Process markup and wrap lines within a block of text. - * - * \param[in] text Text to process. - * \param wrapper Object used to wrap the text. - * - * The \p wrapper should take care of either writing the text to output - * or providing an interface for the caller to retrieve the output. - */ - void processMarkup(const std::string &text, - IWrapper *wrapper) const; + //! Initializes the context with the given state and section depth. + Impl(const StatePointer& state, int sectionDepth) : state_(state), sectionDepth_(sectionDepth) + { + } + //! Copies the context. + Impl(const Impl&) = default; - //! Constant state shared by all child context objects. - StatePointer state_; - //! List of markup/other replacements. - ReplaceList replacements_; - //! Number of subsections above this context. - int sectionDepth_; + //! Adds a new replacement. + void addReplacement(const std::string& search, const std::string& replace) + { + replacements_.emplace_back(search, replace); + } - private: - GMX_DISALLOW_ASSIGN(Impl); + //! Replaces links in a given string. + std::string replaceLinks(const std::string& input) const; + + /*! \brief + * Process markup and wrap lines within a block of text. + * + * \param[in] text Text to process. + * \param wrapper Object used to wrap the text. + * + * The \p wrapper should take care of either writing the text to output + * or providing an interface for the caller to retrieve the output. + */ + void processMarkup(const std::string& text, IWrapper* wrapper) const; + + //! Constant state shared by all child context objects. + StatePointer state_; + //! List of markup/other replacements. + ReplaceList replacements_; + //! Number of subsections above this context. + int sectionDepth_; + +private: + GMX_DISALLOW_ASSIGN(Impl); }; -std::string HelpWriterContext::Impl::replaceLinks(const std::string &input) const +std::string HelpWriterContext::Impl::replaceLinks(const std::string& input) const { std::string result(input); if (state_->links_ != nullptr) { HelpLinks::Impl::LinkList::const_iterator link; - for (link = state_->links_->impl_->links_.begin(); + for (link = state_->links_->impl_->links_.begin(); link != state_->links_->impl_->links_.end(); ++link) { result = replaceAllWords(result, link->linkName, link->replacement); @@ -552,12 +453,10 @@ std::string HelpWriterContext::Impl::replaceLinks(const std::string &input) cons return result; } -void HelpWriterContext::Impl::processMarkup(const std::string &text, - IWrapper *wrapper) const +void HelpWriterContext::Impl::processMarkup(const std::string& text, IWrapper* wrapper) const { std::string result(text); - for (ReplaceList::const_iterator i = replacements_.begin(); - i != replacements_.end(); ++i) + for (ReplaceList::const_iterator i = replacements_.begin(); i != replacements_.end(); ++i) { result = replaceAll(result, i->search, i->replace); } @@ -565,11 +464,11 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text, { case eHelpOutputFormat_Console: { - const int baseFirstLineIndent = wrapper->settings().firstLineIndent(); - const int baseIndent = wrapper->settings().indent(); - result = repall(result, sandrTty); - result = replaceLinks(result); - std::string paragraph; + const int baseFirstLineIndent = wrapper->settings().firstLineIndent(); + const int baseIndent = wrapper->settings().indent(); + result = repall(result, sandrTty); + result = replaceLinks(result); + std::string paragraph; paragraph.reserve(result.length()); RstParagraphIterator iter(result); while (iter.nextParagraph()) @@ -593,8 +492,7 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text, wrapper->wrap(result); break; } - default: - GMX_THROW(InternalError("Invalid help output format")); + default: GMX_THROW(InternalError("Invalid help output format")); } } @@ -602,14 +500,13 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text, * HelpWriterContext */ -HelpWriterContext::HelpWriterContext(TextWriter *writer, HelpOutputFormat format) - : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(writer, format, nullptr)), 0)) +HelpWriterContext::HelpWriterContext(TextWriter* writer, HelpOutputFormat format) : + impl_(new Impl(Impl::StatePointer(new Impl::SharedState(writer, format, nullptr)), 0)) { } -HelpWriterContext::HelpWriterContext(TextWriter *writer, HelpOutputFormat format, - const HelpLinks *links) - : impl_(new Impl(Impl::StatePointer(new Impl::SharedState(writer, format, links)), 0)) +HelpWriterContext::HelpWriterContext(TextWriter* writer, HelpOutputFormat format, const HelpLinks* links) : + impl_(new Impl(Impl::StatePointer(new Impl::SharedState(writer, format, links)), 0)) { if (links != nullptr) { @@ -618,22 +515,15 @@ HelpWriterContext::HelpWriterContext(TextWriter *writer, HelpOutputFormat format } } -HelpWriterContext::HelpWriterContext(Impl *impl) - : impl_(impl) -{ -} +HelpWriterContext::HelpWriterContext(Impl* impl) : impl_(impl) {} -HelpWriterContext::HelpWriterContext(const HelpWriterContext &other) - : impl_(new Impl(*other.impl_)) +HelpWriterContext::HelpWriterContext(const HelpWriterContext& other) : impl_(new Impl(*other.impl_)) { } -HelpWriterContext::~HelpWriterContext() -{ -} +HelpWriterContext::~HelpWriterContext() {} -void HelpWriterContext::setReplacement(const std::string &search, - const std::string &replace) +void HelpWriterContext::setReplacement(const std::string& search, const std::string& replace) { impl_->addReplacement(search, replace); } @@ -643,12 +533,12 @@ HelpOutputFormat HelpWriterContext::outputFormat() const return impl_->state_->format_; } -TextWriter &HelpWriterContext::outputFile() const +TextWriter& HelpWriterContext::outputFile() const { return impl_->state_->file_; } -void HelpWriterContext::enterSubSection(const std::string &title) +void HelpWriterContext::enterSubSection(const std::string& title) { GMX_RELEASE_ASSERT(impl_->sectionDepth_ - 1 < static_cast(std::strlen(g_titleChars)), "Too deeply nested subsections"); @@ -656,50 +546,43 @@ void HelpWriterContext::enterSubSection(const std::string &title) ++impl_->sectionDepth_; } -std::string -HelpWriterContext::substituteMarkupAndWrapToString( - const TextLineWrapperSettings &settings, const std::string &text) const +std::string HelpWriterContext::substituteMarkupAndWrapToString(const TextLineWrapperSettings& settings, + const std::string& text) const { WrapperToString wrapper(settings); impl_->processMarkup(text, &wrapper); return wrapper.result(); } -std::vector -HelpWriterContext::substituteMarkupAndWrapToVector( - const TextLineWrapperSettings &settings, const std::string &text) const +std::vector HelpWriterContext::substituteMarkupAndWrapToVector(const TextLineWrapperSettings& settings, + const std::string& text) const { WrapperToVector wrapper(settings); impl_->processMarkup(text, &wrapper); return wrapper.result(); } -void HelpWriterContext::writeTitle(const std::string &title) const +void HelpWriterContext::writeTitle(const std::string& title) const { if (title.empty()) { return; } - TextWriter &file = outputFile(); + TextWriter& file = outputFile(); file.ensureEmptyLine(); switch (outputFormat()) { - case eHelpOutputFormat_Console: - file.writeLine(toUpperCase(title)); - break; + case eHelpOutputFormat_Console: file.writeLine(toUpperCase(title)); break; case eHelpOutputFormat_Rst: file.writeLine(title); - file.writeLine(std::string(title.length(), - g_titleChars[impl_->sectionDepth_])); + file.writeLine(std::string(title.length(), g_titleChars[impl_->sectionDepth_])); break; - default: - GMX_THROW(NotImplementedError( - "This output format is not implemented")); + default: GMX_THROW(NotImplementedError("This output format is not implemented")); } file.ensureEmptyLine(); } -void HelpWriterContext::writeTextBlock(const std::string &text) const +void HelpWriterContext::writeTextBlock(const std::string& text) const { TextLineWrapperSettings settings; if (outputFormat() == eHelpOutputFormat_Console) @@ -714,22 +597,20 @@ void HelpWriterContext::paragraphBreak() const outputFile().ensureEmptyLine(); } -void HelpWriterContext::writeOptionListStart() const -{ -} +void HelpWriterContext::writeOptionListStart() const {} -void HelpWriterContext::writeOptionItem(const std::string &name, - const std::string &value, - const std::string &defaultValue, - const std::string &info, - const std::string &description) const +void HelpWriterContext::writeOptionItem(const std::string& name, + const std::string& value, + const std::string& defaultValue, + const std::string& info, + const std::string& description) const { - TextWriter &file = outputFile(); + TextWriter& file = outputFile(); switch (outputFormat()) { case eHelpOutputFormat_Console: { - TextTableFormatter &formatter(impl_->state_->consoleOptionsFormatter()); + TextTableFormatter& formatter(impl_->state_->consoleOptionsFormatter()); formatter.clear(); formatter.addColumnLine(0, name); formatter.addColumnLine(1, value); @@ -744,8 +625,7 @@ void HelpWriterContext::writeOptionItem(const std::string &name, TextLineWrapperSettings settings; settings.setIndent(11); settings.setLineLength(78); - std::string formattedDescription - = substituteMarkupAndWrapToString(settings, description); + std::string formattedDescription = substituteMarkupAndWrapToString(settings, description); file.writeLine(formatter.formatRow()); file.writeLine(formattedDescription); break; @@ -771,14 +651,10 @@ void HelpWriterContext::writeOptionItem(const std::string &name, file.writeLine(substituteMarkupAndWrapToString(settings, description)); break; } - default: - GMX_THROW(NotImplementedError( - "This output format is not implemented")); + default: GMX_THROW(NotImplementedError("This output format is not implemented")); } } -void HelpWriterContext::writeOptionListEnd() const -{ -} +void HelpWriterContext::writeOptionListEnd() const {} } // namespace gmx diff --git a/src/gromacs/onlinehelp/helpwritercontext.h b/src/gromacs/onlinehelp/helpwritercontext.h index 140f258e3c..4ce7b4fff6 100644 --- a/src/gromacs/onlinehelp/helpwritercontext.h +++ b/src/gromacs/onlinehelp/helpwritercontext.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,10 +58,10 @@ class TextWriter; //! \libinternal Output format for help writing. enum HelpOutputFormat { - eHelpOutputFormat_Console, //!< Plain text directly on the console. - eHelpOutputFormat_Rst, //!< reStructuredText for online manual and man pages. - eHelpOutputFormat_Other, //!< Used for extensions in other modules. - eHelpOutputFormat_NR //!< Used for the number of output formats. + eHelpOutputFormat_Console, //!< Plain text directly on the console. + eHelpOutputFormat_Rst, //!< reStructuredText for online manual and man pages. + eHelpOutputFormat_Other, //!< Used for extensions in other modules. + eHelpOutputFormat_NR //!< Used for the number of output formats. }; //! \endcond @@ -83,35 +83,33 @@ enum HelpOutputFormat */ class HelpLinks { - public: - /*! \brief - * Initializes an empty links collection for the given output format. - */ - explicit HelpLinks(HelpOutputFormat format); - ~HelpLinks(); +public: + /*! \brief + * Initializes an empty links collection for the given output format. + */ + explicit HelpLinks(HelpOutputFormat format); + ~HelpLinks(); - /*! \brief - * Adds a link. - * - * \param[in] linkName Name of the link in input text. - * \param[in] targetName Hyperlink target. - * \param[in] displayName Text to show as the link. - * - * Any occurrence of \p linkName in the text passed to markup - * substitution methods in HelpWriterContext is made into a hyperlink - * to \p targetName if the markup format supports that. - */ - void addLink(const std::string &linkName, - const std::string &targetName, - const std::string &displayName); + /*! \brief + * Adds a link. + * + * \param[in] linkName Name of the link in input text. + * \param[in] targetName Hyperlink target. + * \param[in] displayName Text to show as the link. + * + * Any occurrence of \p linkName in the text passed to markup + * substitution methods in HelpWriterContext is made into a hyperlink + * to \p targetName if the markup format supports that. + */ + void addLink(const std::string& linkName, const std::string& targetName, const std::string& displayName); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - //! Allows the context to use the links. - friend class HelpWriterContext; + //! Allows the context to use the links. + friend class HelpWriterContext; }; /*! \libinternal \brief @@ -130,181 +128,178 @@ class HelpLinks */ class HelpWriterContext { - public: - /*! \brief - * Initializes a context with the given output writer and format. - * - * \throws std::bad_alloc if out of memory. - */ - HelpWriterContext(TextWriter *writer, HelpOutputFormat format); - /*! \brief - * Initializes a context with the given output writer, format and links. - * - * \throws std::bad_alloc if out of memory. - * - * A reference to \p links is stored until the HelpWriterContext - * is destructed. The caller is responsible for ensuring that the - * links object remains valid long enough. - */ - HelpWriterContext(TextWriter *writer, HelpOutputFormat format, - const HelpLinks *links); - //! Creates a copy of the context. - HelpWriterContext(const HelpWriterContext &other); - ~HelpWriterContext(); +public: + /*! \brief + * Initializes a context with the given output writer and format. + * + * \throws std::bad_alloc if out of memory. + */ + HelpWriterContext(TextWriter* writer, HelpOutputFormat format); + /*! \brief + * Initializes a context with the given output writer, format and links. + * + * \throws std::bad_alloc if out of memory. + * + * A reference to \p links is stored until the HelpWriterContext + * is destructed. The caller is responsible for ensuring that the + * links object remains valid long enough. + */ + HelpWriterContext(TextWriter* writer, HelpOutputFormat format, const HelpLinks* links); + //! Creates a copy of the context. + HelpWriterContext(const HelpWriterContext& other); + ~HelpWriterContext(); - /*! \brief - * Adds a string replacement for markup subsitution. - * - * \param[in] search Text to replace in input. - * \param[in] replace Text that each occurrence of \p search is - * replaced with. - * \throws std::bad_alloc if out of memory. - * - * \todo - * Improve semantics if the same \p search item is set multiple - * times. - */ - void setReplacement(const std::string &search, - const std::string &replace); + /*! \brief + * Adds a string replacement for markup subsitution. + * + * \param[in] search Text to replace in input. + * \param[in] replace Text that each occurrence of \p search is + * replaced with. + * \throws std::bad_alloc if out of memory. + * + * \todo + * Improve semantics if the same \p search item is set multiple + * times. + */ + void setReplacement(const std::string& search, const std::string& replace); - /*! \brief - * Returns the active output format. - * - * Does not throw. - */ - HelpOutputFormat outputFormat() const; - /*! \brief - * Returns the raw writer for writing the help. - * - * Using this writer directly should be avoided, as it requires one to - * have different code for each output format. - * Using other methods in this class should be preferred. - * - * Does not throw. - */ - TextWriter &outputFile() const; + /*! \brief + * Returns the active output format. + * + * Does not throw. + */ + HelpOutputFormat outputFormat() const; + /*! \brief + * Returns the raw writer for writing the help. + * + * Using this writer directly should be avoided, as it requires one to + * have different code for each output format. + * Using other methods in this class should be preferred. + * + * Does not throw. + */ + TextWriter& outputFile() const; - /*! \brief - * Creates a subsection in the output help. - * - * \param[in] title Title for the subsection. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * Writes \p title using writeTitle() and makes any further - * writeTitle() calls write headings one level deeper. - * - * Typical use for writing a subsection is to create a copy of the - * context for the parent section, and then call enterSubSection() on - * the copy. - * The whole subsection should be written out using the returned - * context before calling any further methods in the parent context. - * - * This method is only necessary if the subsection will contain further - * subsections. If there is only one level of subsections, it is - * possible to use writeTitle() directly. - */ - void enterSubSection(const std::string &title); + /*! \brief + * Creates a subsection in the output help. + * + * \param[in] title Title for the subsection. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * Writes \p title using writeTitle() and makes any further + * writeTitle() calls write headings one level deeper. + * + * Typical use for writing a subsection is to create a copy of the + * context for the parent section, and then call enterSubSection() on + * the copy. + * The whole subsection should be written out using the returned + * context before calling any further methods in the parent context. + * + * This method is only necessary if the subsection will contain further + * subsections. If there is only one level of subsections, it is + * possible to use writeTitle() directly. + */ + void enterSubSection(const std::string& title); - /*! \brief - * Substitutes markup used in help text and wraps lines. - * - * \param[in] settings Line wrapper settings. - * \param[in] text Text to substitute. - * \returns \p text with markup substituted and wrapped. - * \throws std::bad_alloc if out of memory. - * - * \see TextLineWrapper::wrapToString() - */ - std::string - substituteMarkupAndWrapToString(const TextLineWrapperSettings &settings, - const std::string &text) const; - /*! \brief - * Substitutes markup used in help text and wraps lines. - * - * \param[in] settings Line wrapper settings. - * \param[in] text Text to substitute. - * \returns \p text with markup substituted and wrapped as a list of - * lines. - * \throws std::bad_alloc if out of memory. - * - * \see TextLineWrapper::wrapToVector() - */ - std::vector - substituteMarkupAndWrapToVector(const TextLineWrapperSettings &settings, - const std::string &text) const; - /*! \brief - * Writes a title for the current help topic. - * - * \param[in] title Title to write. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - void writeTitle(const std::string &title) const; - /*! \brief - * Writes a formatted text block into the output. - * - * \param[in] text Text to format. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * Convenience function that calls substituteMarkupAndWrapToString() - * and writes the result directly to the output file. - */ - void writeTextBlock(const std::string &text) const; - /*! \brief - * Ensures a paragraph break (empty line) in the output. - * - * Calls at the beginning and end of output do not produce extra empty - * lines, and consencutive calls only result in a single empty line. - * This allows calling the method before and after all output that - * needs to appear separated as empty lines. - */ - void paragraphBreak() const; - /*! \brief - * Starts writing a list of options. - * - * Prints any necessary headers for a list of options formatted with - * writeOptionItem(). - */ - void writeOptionListStart() const; - /*! \brief - * Writes an entry for a single option into the output. - * - * \param[in] name Name of the option. - * \param[in] value Placeholder for option value. - * \param[in] defaultValue Default value for the option. - * \param[in] info Additional (brief) info/attributes for the - * option. - * \param[in] description Full description of the option. - */ - void writeOptionItem( - const std::string &name, const std::string &value, - const std::string &defaultValue, const std::string &info, - const std::string &description) const; - /*! \brief - * Finishes writing a list of options. - * - * Prints any necessary footers for a list of options formatted with - * writeOptionItem(). - */ - void writeOptionListEnd() const; + /*! \brief + * Substitutes markup used in help text and wraps lines. + * + * \param[in] settings Line wrapper settings. + * \param[in] text Text to substitute. + * \returns \p text with markup substituted and wrapped. + * \throws std::bad_alloc if out of memory. + * + * \see TextLineWrapper::wrapToString() + */ + std::string substituteMarkupAndWrapToString(const TextLineWrapperSettings& settings, + const std::string& text) const; + /*! \brief + * Substitutes markup used in help text and wraps lines. + * + * \param[in] settings Line wrapper settings. + * \param[in] text Text to substitute. + * \returns \p text with markup substituted and wrapped as a list of + * lines. + * \throws std::bad_alloc if out of memory. + * + * \see TextLineWrapper::wrapToVector() + */ + std::vector substituteMarkupAndWrapToVector(const TextLineWrapperSettings& settings, + const std::string& text) const; + /*! \brief + * Writes a title for the current help topic. + * + * \param[in] title Title to write. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + void writeTitle(const std::string& title) const; + /*! \brief + * Writes a formatted text block into the output. + * + * \param[in] text Text to format. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * Convenience function that calls substituteMarkupAndWrapToString() + * and writes the result directly to the output file. + */ + void writeTextBlock(const std::string& text) const; + /*! \brief + * Ensures a paragraph break (empty line) in the output. + * + * Calls at the beginning and end of output do not produce extra empty + * lines, and consencutive calls only result in a single empty line. + * This allows calling the method before and after all output that + * needs to appear separated as empty lines. + */ + void paragraphBreak() const; + /*! \brief + * Starts writing a list of options. + * + * Prints any necessary headers for a list of options formatted with + * writeOptionItem(). + */ + void writeOptionListStart() const; + /*! \brief + * Writes an entry for a single option into the output. + * + * \param[in] name Name of the option. + * \param[in] value Placeholder for option value. + * \param[in] defaultValue Default value for the option. + * \param[in] info Additional (brief) info/attributes for the + * option. + * \param[in] description Full description of the option. + */ + void writeOptionItem(const std::string& name, + const std::string& value, + const std::string& defaultValue, + const std::string& info, + const std::string& description) const; + /*! \brief + * Finishes writing a list of options. + * + * Prints any necessary footers for a list of options formatted with + * writeOptionItem(). + */ + void writeOptionListEnd() const; - private: - class Impl; +private: + class Impl; - /*! \brief - * Constructs a context object with the given implementation class. - * - * \param[in] impl Implementation object. - * - * Does not throw. - */ - explicit HelpWriterContext(Impl *impl); + /*! \brief + * Constructs a context object with the given implementation class. + * + * \param[in] impl Implementation object. + * + * Does not throw. + */ + explicit HelpWriterContext(Impl* impl); - PrivateImplPointer impl_; + PrivateImplPointer impl_; - GMX_DISALLOW_ASSIGN(HelpWriterContext); + GMX_DISALLOW_ASSIGN(HelpWriterContext); }; } // namespace gmx diff --git a/src/gromacs/onlinehelp/ihelptopic.h b/src/gromacs/onlinehelp/ihelptopic.h index 2c6aa8990b..aee449a837 100644 --- a/src/gromacs/onlinehelp/ihelptopic.h +++ b/src/gromacs/onlinehelp/ihelptopic.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,44 +65,44 @@ class HelpWriterContext; */ class IHelpTopic { - public: - virtual ~IHelpTopic() {} +public: + virtual ~IHelpTopic() {} - /*! \brief - * Returns the name of the topic. - * - * This should be a single lowercase word, used to identify the topic. - * It is not used for the root of the help topic tree. - */ - virtual const char *name() const = 0; - /*! \brief - * Returns a title for the topic. - * - * May return NULL, in which case the topic is omitted from normal - * subtopic lists and no title is printed by the methods provided in - * helptopic.h. - */ - virtual const char *title() const = 0; + /*! \brief + * Returns the name of the topic. + * + * This should be a single lowercase word, used to identify the topic. + * It is not used for the root of the help topic tree. + */ + virtual const char* name() const = 0; + /*! \brief + * Returns a title for the topic. + * + * May return NULL, in which case the topic is omitted from normal + * subtopic lists and no title is printed by the methods provided in + * helptopic.h. + */ + virtual const char* title() const = 0; - //! Returns whether the topic has any subtopics. - virtual bool hasSubTopics() const = 0; - /*! \brief - * Finds a subtopic by name. - * - * \param[in] name Name of subtopic to find. - * \returns Pointer to the found subtopic, or NULL if matching topic - * is not found. - */ - virtual const IHelpTopic *findSubTopic(const char *name) const = 0; + //! Returns whether the topic has any subtopics. + virtual bool hasSubTopics() const = 0; + /*! \brief + * Finds a subtopic by name. + * + * \param[in] name Name of subtopic to find. + * \returns Pointer to the found subtopic, or NULL if matching topic + * is not found. + */ + virtual const IHelpTopic* findSubTopic(const char* name) const = 0; - /*! \brief - * Prints the help text for this topic. - * - * \param[in] context Context object for writing the help. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - virtual void writeHelp(const HelpWriterContext &context) const = 0; + /*! \brief + * Prints the help text for this topic. + * + * \param[in] context Context object for writing the help. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + virtual void writeHelp(const HelpWriterContext& context) const = 0; }; //! Smart pointer type to manage a IHelpTopic object. diff --git a/src/gromacs/onlinehelp/rstparser.cpp b/src/gromacs/onlinehelp/rstparser.cpp index dc5edacbed..e4360c570b 100644 --- a/src/gromacs/onlinehelp/rstparser.cpp +++ b/src/gromacs/onlinehelp/rstparser.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +60,7 @@ namespace * * Does not throw. */ -int countLeadingSpace(const std::string &text, size_t start, size_t end) +int countLeadingSpace(const std::string& text, size_t start, size_t end) { for (size_t i = start; i < end; ++i) { @@ -77,13 +77,13 @@ int countLeadingSpace(const std::string &text, size_t start, size_t end) * * Does not throw. */ -bool startsListItem(const std::string &text, size_t index) +bool startsListItem(const std::string& text, size_t index) { if (text.length() <= index + 1) { return false; } - if (text[index] == '*' && std::isspace(text[index+1])) + if (text[index] == '*' && std::isspace(text[index + 1])) { return true; } @@ -93,8 +93,7 @@ bool startsListItem(const std::string &text, size_t index) { ++index; } - if (text.length() > index + 1 && text[index] == '.' - && std::isspace(text[index+1])) + if (text.length() > index + 1 && text[index] == '.' && std::isspace(text[index + 1])) { return true; } @@ -112,7 +111,7 @@ bool startsListItem(const std::string &text, size_t index) * * Does not throw. */ -bool startsTable(const std::string &text, size_t index) +bool startsTable(const std::string& text, size_t index) { if (text[index] == '=') { @@ -146,7 +145,7 @@ bool startsTable(const std::string &text, size_t index) * * Does not throw. */ -bool isTitleUnderline(const std::string &text, size_t index) +bool isTitleUnderline(const std::string& text, size_t index) { const char firstChar = text[index]; if (std::ispunct(firstChar)) @@ -164,16 +163,23 @@ bool isTitleUnderline(const std::string &text, size_t index) return false; } -} // namespace +} // namespace /******************************************************************** * RstParagraphIterator */ -RstParagraphIterator::RstParagraphIterator(const std::string &text) - : text_(text), begin_(0), end_(0), type_(eParagraphType_Normal), - breakSize_(0), firstLineIndent_(0), indent_(0), - nextBegin_(0), nextBreakSize_(0), literalIndent_(-1) +RstParagraphIterator::RstParagraphIterator(const std::string& text) : + text_(text), + begin_(0), + end_(0), + type_(eParagraphType_Normal), + breakSize_(0), + firstLineIndent_(0), + indent_(0), + nextBegin_(0), + nextBreakSize_(0), + literalIndent_(-1) { } @@ -309,7 +315,7 @@ bool RstParagraphIterator::nextParagraph() return true; } -void RstParagraphIterator::getParagraphText(std::string *result) const +void RstParagraphIterator::getParagraphText(std::string* result) const { result->clear(); result->reserve(end_ - begin_); diff --git a/src/gromacs/onlinehelp/rstparser.h b/src/gromacs/onlinehelp/rstparser.h index 3bf1b3c734..52eda481e1 100644 --- a/src/gromacs/onlinehelp/rstparser.h +++ b/src/gromacs/onlinehelp/rstparser.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,80 +66,80 @@ class TextLineWrapperSettings; */ class RstParagraphIterator { - public: - /*! \brief - * Initializes an iterator for given input text. - * - * Does not throw. - */ - explicit RstParagraphIterator(const std::string &text); +public: + /*! \brief + * Initializes an iterator for given input text. + * + * Does not throw. + */ + explicit RstParagraphIterator(const std::string& text); - /*! \brief - * Advances the iterator to the next paragraph. - * - * \returns `false` if there were no more paragraphs. - * - * Does not throw (except std::bad_alloc if std::string::compare() - * throws). - */ - bool nextParagraph(); + /*! \brief + * Advances the iterator to the next paragraph. + * + * \returns `false` if there were no more paragraphs. + * + * Does not throw (except std::bad_alloc if std::string::compare() + * throws). + */ + bool nextParagraph(); - //! Returns the indentation for first line of this paragraph. - int firstLineIndent() const { return firstLineIndent_; } - //! Returns the indentation for subsequent lines of this paragraph. - int indent() const { return indent_; } - /*! \brief - * Returns the text - * - * \param[out] result Variable to receive the paragraph text. - * \throws std::bad_alloc if out of memory. - * - * Indentation and internal line breaks have been stripped from the - * paragraph text (except for literal blocks etc.). For literal - * blocks, the common indentation has been stripped and is returned in - * indent() instead. - * - * Leading newlines are returned to indicate necessary separation from - * the preceding paragraph. - */ - void getParagraphText(std::string *result) const; + //! Returns the indentation for first line of this paragraph. + int firstLineIndent() const { return firstLineIndent_; } + //! Returns the indentation for subsequent lines of this paragraph. + int indent() const { return indent_; } + /*! \brief + * Returns the text + * + * \param[out] result Variable to receive the paragraph text. + * \throws std::bad_alloc if out of memory. + * + * Indentation and internal line breaks have been stripped from the + * paragraph text (except for literal blocks etc.). For literal + * blocks, the common indentation has been stripped and is returned in + * indent() instead. + * + * Leading newlines are returned to indicate necessary separation from + * the preceding paragraph. + */ + void getParagraphText(std::string* result) const; - private: - enum ParagraphType - { - eParagraphType_Normal, - eParagraphType_Literal, - eParagraphType_Title - }; +private: + enum ParagraphType + { + eParagraphType_Normal, + eParagraphType_Literal, + eParagraphType_Title + }; - //! The text to iterate over. - const std::string &text_; //NOLINT(google-runtime-member-string-references) + //! The text to iterate over. + const std::string& text_; //NOLINT(google-runtime-member-string-references) - //! Start of the current paragraph. - size_t begin_; - //! End of the current paragraph (C++-style iterator). - size_t end_; - //! Type of the current paragraph. - ParagraphType type_; - //! Number of newlines to print before the current paragraph. - int breakSize_; - //! Indentation of the first line of this paragraph. - int firstLineIndent_; - //! (Minimum) indentation of other lines in this paragraph. - int indent_; + //! Start of the current paragraph. + size_t begin_; + //! End of the current paragraph (C++-style iterator). + size_t end_; + //! Type of the current paragraph. + ParagraphType type_; + //! Number of newlines to print before the current paragraph. + int breakSize_; + //! Indentation of the first line of this paragraph. + int firstLineIndent_; + //! (Minimum) indentation of other lines in this paragraph. + int indent_; - //! Start of the next paragrah. - size_t nextBegin_; - //! Number of newlines to print after the current paragraph. - int nextBreakSize_; - /*! \brief - * Indentation of the preceding paragraph that contained `::`. - * - * If the next paragraph is not a literal block, the value is `-1`. - */ - int literalIndent_; + //! Start of the next paragrah. + size_t nextBegin_; + //! Number of newlines to print after the current paragraph. + int nextBreakSize_; + /*! \brief + * Indentation of the preceding paragraph that contained `::`. + * + * If the next paragraph is not a literal block, the value is `-1`. + */ + int literalIndent_; - GMX_DISALLOW_COPY_AND_ASSIGN(RstParagraphIterator); + GMX_DISALLOW_COPY_AND_ASSIGN(RstParagraphIterator); }; } // namespace gmx diff --git a/src/gromacs/onlinehelp/tests/helpformat.cpp b/src/gromacs/onlinehelp/tests/helpformat.cpp index f48ffbebbf..9c56c9065d 100644 --- a/src/gromacs/onlinehelp/tests/helpformat.cpp +++ b/src/gromacs/onlinehelp/tests/helpformat.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,10 +61,10 @@ const char g_wrapText2[] = "A quick brown fox jumps\nover the lazy dog"; class TextTableFormatterTest : public gmx::test::StringTestBase { - public: - void setupStandardColumns(); +public: + void setupStandardColumns(); - gmx::TextTableFormatter formatter_; + gmx::TextTableFormatter formatter_; }; void TextTableFormatterTest::setupStandardColumns() diff --git a/src/gromacs/onlinehelp/tests/helpmanager.cpp b/src/gromacs/onlinehelp/tests/helpmanager.cpp index 19a19fce27..ef9ca04bea 100644 --- a/src/gromacs/onlinehelp/tests/helpmanager.cpp +++ b/src/gromacs/onlinehelp/tests/helpmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,21 +65,21 @@ using gmx::test::MockHelpTopic; class HelpTestBase : public gmx::test::StringTestBase { - public: - HelpTestBase(); - - MockHelpTopic rootTopic_; - gmx::StringOutputStream helpFile_; - gmx::TextWriter writer_; - gmx::HelpWriterContext context_; - gmx::HelpManager manager_; +public: + HelpTestBase(); + + MockHelpTopic rootTopic_; + gmx::StringOutputStream helpFile_; + gmx::TextWriter writer_; + gmx::HelpWriterContext context_; + gmx::HelpManager manager_; }; -HelpTestBase::HelpTestBase() - : rootTopic_("", nullptr, "Root topic text"), - writer_(&helpFile_), - context_(&writer_, gmx::eHelpOutputFormat_Console), - manager_(rootTopic_, context_) +HelpTestBase::HelpTestBase() : + rootTopic_("", nullptr, "Root topic text"), + writer_(&helpFile_), + context_(&writer_, gmx::eHelpOutputFormat_Console), + manager_(rootTopic_, context_) { } @@ -99,10 +99,8 @@ TEST_F(HelpManagerTest, HandlesRootTopic) TEST_F(HelpManagerTest, HandlesSubTopics) { - MockHelpTopic &first = - rootTopic_.addSubTopic("first", "First topic", nullptr); - MockHelpTopic &firstSub = - first.addSubTopic("firstsub", "First subtopic", nullptr); + MockHelpTopic& first = rootTopic_.addSubTopic("first", "First topic", nullptr); + MockHelpTopic& firstSub = first.addSubTopic("firstsub", "First subtopic", nullptr); rootTopic_.addSubTopic("second", "Second topic", nullptr); using ::testing::_; @@ -114,8 +112,7 @@ TEST_F(HelpManagerTest, HandlesSubTopics) TEST_F(HelpManagerTest, HandlesInvalidTopics) { - MockHelpTopic &first = - rootTopic_.addSubTopic("first", "First topic", nullptr); + MockHelpTopic& first = rootTopic_.addSubTopic("first", "First topic", nullptr); first.addSubTopic("firstsub", "First subtopic", nullptr); rootTopic_.addSubTopic("second", "Second topic", nullptr); @@ -134,20 +131,17 @@ struct TestHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char TestHelpText::name[] = "testtopic"; const char TestHelpText::title[] = "Topic title"; -const char *const TestHelpText::text[] = { - "Test topic text.[PAR]", - "Another paragraph of text." -}; +const char* const TestHelpText::text[] = { "Test topic text.[PAR]", "Another paragraph of text." }; class HelpTopicFormattingTest : public HelpTestBase { - public: - void checkHelpFormatting(); +public: + void checkHelpFormatting(); }; void HelpTopicFormattingTest::checkHelpFormatting() @@ -161,8 +155,7 @@ void HelpTopicFormattingTest::checkHelpFormatting() TEST_F(HelpTopicFormattingTest, FormatsSimpleTopic) { - rootTopic_.addSubTopic(gmx::HelpTopicPointer( - new gmx::SimpleHelpTopic)); + rootTopic_.addSubTopic(gmx::HelpTopicPointer(new gmx::SimpleHelpTopic)); checkHelpFormatting(); } diff --git a/src/gromacs/onlinehelp/tests/helpwritercontext.cpp b/src/gromacs/onlinehelp/tests/helpwritercontext.cpp index 05fc10b133..eba2f1abf6 100644 --- a/src/gromacs/onlinehelp/tests/helpwritercontext.cpp +++ b/src/gromacs/onlinehelp/tests/helpwritercontext.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,138 +62,97 @@ namespace class HelpWriterContextTest : public gmx::test::StringTestBase { - public: - void testFormatting(const std::string &text, - gmx::HelpOutputFormat format, - const char *id) +public: + void testFormatting(const std::string& text, gmx::HelpOutputFormat format, const char* id) + { + gmx::HelpWriterContext context(nullptr, format); + std::string result = context.substituteMarkupAndWrapToString(settings_, text); + if (id == nullptr) { - gmx::HelpWriterContext context(nullptr, format); - std::string result - = context.substituteMarkupAndWrapToString(settings_, text); - if (id == nullptr) + switch (format) { - switch (format) - { - case gmx::eHelpOutputFormat_Console: - id = "Console"; - break; - case gmx::eHelpOutputFormat_Rst: - id = "reStructuredText"; - break; - default: - GMX_RELEASE_ASSERT(false, "Help output format testing not implemented"); - } + case gmx::eHelpOutputFormat_Console: id = "Console"; break; + case gmx::eHelpOutputFormat_Rst: id = "reStructuredText"; break; + default: GMX_RELEASE_ASSERT(false, "Help output format testing not implemented"); } - checkText(result, id); } - void testFormatting(const gmx::ArrayRef &text) - { - std::string testText = gmx::joinStrings(text, "\n"); - testFormatting(testText, gmx::eHelpOutputFormat_Console, nullptr); - testFormatting(testText, gmx::eHelpOutputFormat_Rst, nullptr); - } - - gmx::TextLineWrapperSettings settings_; + checkText(result, id); + } + void testFormatting(const gmx::ArrayRef& text) + { + std::string testText = gmx::joinStrings(text, "\n"); + testFormatting(testText, gmx::eHelpOutputFormat_Console, nullptr); + testFormatting(testText, gmx::eHelpOutputFormat_Rst, nullptr); + } + + gmx::TextLineWrapperSettings settings_; }; TEST_F(HelpWriterContextTest, FormatsParagraphs) { - const char *const text[] = { - "A quick", - "brown fox", - "jumps over a lazy dog.[PAR]", - "A quick brown fox", - "jumps over", - "a lazy dog." - }; + const char* const text[] = { "A quick", "brown fox", "jumps over a lazy dog.[PAR]", + "A quick brown fox", "jumps over", "a lazy dog." }; settings_.setLineLength(13); testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsRstStyleParagraphs) { - const char *const text[] = { - "A quick", - "brown fox", - "jumps over a lazy dog.", - "", - "A quick brown fox", - "jumps over", - "a lazy dog." - }; + const char* const text[] = { "A quick", "brown fox", "jumps over a lazy dog.", + "", "A quick brown fox", "jumps over", + "a lazy dog." }; settings_.setLineLength(13); testFormatting(text); } TEST_F(HelpWriterContextTest, CleansUpExtraWhitespace) { - const char *const text[] = { - "", - "A quick ", - "brown fox ", - "jumps over a lazy dog.", - "[PAR]", - "A quick brown fox", - "jumps over", - "a lazy dog.[PAR]" - }; + const char* const text[] = { "", "A quick ", + "brown fox ", "jumps over a lazy dog.", + "[PAR]", "A quick brown fox", + "jumps over", "a lazy dog.[PAR]" }; settings_.setLineLength(13); testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsLiteralText) { - const char *const text[] = { - "Sample paragraph::", - "", - " literal block", - " another line", - "", - "Normal paragraph", - "with wrapping" - }; + const char* const text[] = { "Sample paragraph::", "", " literal block", + " another line", "", "Normal paragraph", + "with wrapping" }; testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsLiteralTextAtBeginning) { - const char *const text[] = { - "::", - "", - " literal block", - " another line", - "", - "Normal paragraph" + const char* const text[] = { + "::", "", " literal block", " another line", "", "Normal paragraph" }; testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsLiteralTextWithIndentation) { - const char *const text[] = { - "Sample paragraph::", - "", - " literal block", - " another indented line", - "", - "Normal paragraph", - "with wrapping" - }; + const char* const text[] = { "Sample paragraph::", + "", + " literal block", + " another indented line", + "", + "Normal paragraph", + "with wrapping" }; testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsBulletList) { - const char *const text[] = { - "Sample list:", - "", - "* first item", - "* second item that", - " spans multiple lines", - "* third item that has a single long line", - "", - "Normal paragraph" - }; + const char* const text[] = { "Sample list:", + "", + "* first item", + "* second item that", + " spans multiple lines", + "* third item that has a single long line", + "", + "Normal paragraph" }; // Wrapping to rst with a fixed line length does not currently work // correctly, but it is not used, either. settings_.setLineLength(15); @@ -202,19 +161,17 @@ TEST_F(HelpWriterContextTest, FormatsBulletList) TEST_F(HelpWriterContextTest, FormatsEnumeratedList) { - const char *const text[] = { - "Sample list:", - "", - "1. first item", - "2. second item that", - " spans multiple lines", - "3. third item that has a single long line", - "", - "9. Item with extra indentation", - "10. Double digit item", - "", - "Normal paragraph" - }; + const char* const text[] = { "Sample list:", + "", + "1. first item", + "2. second item that", + " spans multiple lines", + "3. third item that has a single long line", + "", + "9. Item with extra indentation", + "10. Double digit item", + "", + "Normal paragraph" }; // Wrapping to rst with a fixed line length does not currently work // correctly, but it is not used, either. settings_.setLineLength(15); @@ -223,49 +180,38 @@ TEST_F(HelpWriterContextTest, FormatsEnumeratedList) TEST_F(HelpWriterContextTest, FormatsSimpleTable) { - const char *const text[] = { - "Simple table:", - "", - "============ =============", - "First column Second header", - "============ =============", - "text text", - "============ =============", - "", - "Normal paragraph", - "again." - }; + const char* const text[] = { "Simple table:", + "", + "============ =============", + "First column Second header", + "============ =============", + "text text", + "============ =============", + "", + "Normal paragraph", + "again." }; testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsGridTable) { - const char *const text[] = { - "Grid table:", - "", - "+--------------+---------------+", - "| First column | Second header |", - "+--------------+---------------+", - "| text | text |", - "+--------------+---------------+", - "", - "Normal paragraph", - "again." - }; + const char* const text[] = { "Grid table:", + "", + "+--------------+---------------+", + "| First column | Second header |", + "+--------------+---------------+", + "| text | text |", + "+--------------+---------------+", + "", + "Normal paragraph", + "again." }; testFormatting(text); } TEST_F(HelpWriterContextTest, FormatsTitles) { - const char *const text[] = { - "Title", - "=====", - "Some text without spacing", - "", - "Subtitle", - "++++++++", - "", - "More text", + const char* const text[] = { + "Title", "=====", "Some text without spacing", "", "Subtitle", "++++++++", "", "More text", }; testFormatting(text); } diff --git a/src/gromacs/onlinehelp/tests/mock_helptopic.cpp b/src/gromacs/onlinehelp/tests/mock_helptopic.cpp index 49decf9b1a..7ece420bdc 100644 --- a/src/gromacs/onlinehelp/tests/mock_helptopic.cpp +++ b/src/gromacs/onlinehelp/tests/mock_helptopic.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,38 +58,37 @@ namespace test */ // static -MockHelpTopic & -MockHelpTopic::addSubTopic(gmx::AbstractCompositeHelpTopic *parent, - const char *name, const char *title, - const char *text) +MockHelpTopic& MockHelpTopic::addSubTopic(gmx::AbstractCompositeHelpTopic* parent, + const char* name, + const char* title, + const char* text) { - MockHelpTopic *topic = new MockHelpTopic(name, title, text); + MockHelpTopic* topic = new MockHelpTopic(name, title, text); parent->addSubTopic(gmx::HelpTopicPointer(topic)); return *topic; } -MockHelpTopic::MockHelpTopic(const char *name, const char *title, const char *text) - : name_(name), title_(title), text_(text != nullptr ? text : "") +MockHelpTopic::MockHelpTopic(const char* name, const char* title, const char* text) : + name_(name), + title_(title), + text_(text != nullptr ? text : "") { if (!isNullOrEmpty(text)) { using ::testing::_; using ::testing::Invoke; - ON_CALL(*this, writeHelp(_)) - .WillByDefault(Invoke(this, &MockHelpTopic::writeHelpBase)); + ON_CALL(*this, writeHelp(_)).WillByDefault(Invoke(this, &MockHelpTopic::writeHelpBase)); } } -MockHelpTopic::~MockHelpTopic() -{ -} +MockHelpTopic::~MockHelpTopic() {} -const char *MockHelpTopic::name() const +const char* MockHelpTopic::name() const { return name_; } -const char *MockHelpTopic::title() const +const char* MockHelpTopic::title() const { return title_; } @@ -99,9 +98,7 @@ std::string MockHelpTopic::helpText() const return text_; } -MockHelpTopic & -MockHelpTopic::addSubTopic(const char *name, const char *title, - const char *text) +MockHelpTopic& MockHelpTopic::addSubTopic(const char* name, const char* title, const char* text) { return addSubTopic(this, name, title, text); } diff --git a/src/gromacs/onlinehelp/tests/mock_helptopic.h b/src/gromacs/onlinehelp/tests/mock_helptopic.h index 5151087245..e8a3f13013 100644 --- a/src/gromacs/onlinehelp/tests/mock_helptopic.h +++ b/src/gromacs/onlinehelp/tests/mock_helptopic.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,40 +55,40 @@ namespace test class MockHelpTopic : public AbstractCompositeHelpTopic { - public: - static MockHelpTopic &addSubTopic( - gmx::AbstractCompositeHelpTopic *parent, - const char *name, const char *title, const char *text); +public: + static MockHelpTopic& addSubTopic(gmx::AbstractCompositeHelpTopic* parent, + const char* name, + const char* title, + const char* text); - MockHelpTopic(const char *name, const char *title, const char *text); - ~MockHelpTopic() override; + MockHelpTopic(const char* name, const char* title, const char* text); + ~MockHelpTopic() override; - const char *name() const override; - const char *title() const override; + const char* name() const override; + const char* title() const override; - MOCK_CONST_METHOD1(writeHelp, void(const HelpWriterContext &context)); + MOCK_CONST_METHOD1(writeHelp, void(const HelpWriterContext& context)); - MockHelpTopic &addSubTopic(const char *name, const char *title, - const char *text); - using AbstractCompositeHelpTopic::addSubTopic; + MockHelpTopic& addSubTopic(const char* name, const char* title, const char* text); + using AbstractCompositeHelpTopic::addSubTopic; - /*! \brief - * Calls base class writeHelp() method. - * - * This provides the possibility for the mock to do the actual help - * writing. - */ - void writeHelpBase(const HelpWriterContext &context) - { - AbstractCompositeHelpTopic::writeHelp(context); - } + /*! \brief + * Calls base class writeHelp() method. + * + * This provides the possibility for the mock to do the actual help + * writing. + */ + void writeHelpBase(const HelpWriterContext& context) + { + AbstractCompositeHelpTopic::writeHelp(context); + } - private: - std::string helpText() const override; +private: + std::string helpText() const override; - const char *name_; - const char *title_; - const char *text_; + const char* name_; + const char* title_; + const char* text_; }; } // namespace test diff --git a/src/gromacs/options/abstractoption.cpp b/src/gromacs/options/abstractoption.cpp index 41eaa0102d..b2d060a1e6 100644 --- a/src/gromacs/options/abstractoption.cpp +++ b/src/gromacs/options/abstractoption.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,13 +59,13 @@ namespace gmx * AbstractOptionStorage */ -AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings, - OptionFlags staticFlags) - : flags_(settings.flags_ | staticFlags), - storeIsSet_(settings.storeIsSet_), - minValueCount_(settings.minValueCount_), - maxValueCount_(settings.maxValueCount_), - bInSet_(false), bSetValuesHadErrors_(false) +AbstractOptionStorage::AbstractOptionStorage(const AbstractOption& settings, OptionFlags staticFlags) : + flags_(settings.flags_ | staticFlags), + storeIsSet_(settings.storeIsSet_), + minValueCount_(settings.minValueCount_), + maxValueCount_(settings.maxValueCount_), + bInSet_(false), + bSetValuesHadErrors_(false) { // Check that user has not provided incorrect values for vectors. if (hasFlag(efOption_Vector) && (minValueCount_ > 1 || maxValueCount_ < 1)) @@ -74,7 +75,7 @@ AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings, if (settings.name_ != nullptr) { - name_ = settings.name_; + name_ = settings.name_; } if (settings.descr_ != nullptr) { @@ -87,13 +88,11 @@ AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings, setFlag(efOption_ClearOnNextSet); } -AbstractOptionStorage::~AbstractOptionStorage() -{ -} +AbstractOptionStorage::~AbstractOptionStorage() {} bool AbstractOptionStorage::isBoolean() const { - return dynamic_cast(this) != nullptr; + return dynamic_cast(this) != nullptr; } void AbstractOptionStorage::startSource() @@ -107,8 +106,7 @@ void AbstractOptionStorage::startSet() // The last condition takes care of the situation where multiple // sources are used, and a later source should be able to reassign // the value even though the option is already set. - if (isSet() && !hasFlag(efOption_MultipleTimes) - && !hasFlag(efOption_ClearOnNextSet)) + if (isSet() && !hasFlag(efOption_MultipleTimes) && !hasFlag(efOption_ClearOnNextSet)) { GMX_THROW(InvalidInputError("Option specified multiple times")); } @@ -117,14 +115,14 @@ void AbstractOptionStorage::startSet() bSetValuesHadErrors_ = false; } -void AbstractOptionStorage::appendValue(const Any &value) +void AbstractOptionStorage::appendValue(const Any& value) { GMX_RELEASE_ASSERT(bInSet_, "startSet() not called"); try { convertValue(value); } - catch (const std::exception &) + catch (const std::exception&) { bSetValuesHadErrors_ = true; throw; @@ -177,8 +175,7 @@ void AbstractOptionStorage::setMinValueCount(int count) "setMinValueCount() not supported with efOption_MultipleTimes"); GMX_RELEASE_ASSERT(count >= 0, "Invalid value count"); minValueCount_ = count; - if (isSet() && !hasFlag(efOption_DontCheckMinimumCount) - && valueCount() < minValueCount_) + if (isSet() && !hasFlag(efOption_DontCheckMinimumCount) && valueCount() < minValueCount_) { GMX_THROW(InvalidInputError("Too few values")); } @@ -201,15 +198,10 @@ void AbstractOptionStorage::setMaxValueCount(int count) */ /*! \cond libapi */ -OptionInfo::OptionInfo(AbstractOptionStorage *option) - : option_(*option) -{ -} +OptionInfo::OptionInfo(AbstractOptionStorage* option) : option_(*option) {} //! \endcond -OptionInfo::~OptionInfo() -{ -} +OptionInfo::~OptionInfo() {} bool OptionInfo::isSet() const { @@ -240,7 +232,7 @@ int OptionInfo::maxValueCount() const return option().maxValueCount(); } -const std::string &OptionInfo::name() const +const std::string& OptionInfo::name() const { return option().name(); } @@ -271,7 +263,7 @@ std::vector OptionInfo::defaultValuesAsStrings() const return option().defaultValuesAsStrings(); } -std::vector OptionInfo::normalizeValues(const std::vector &values) const +std::vector OptionInfo::normalizeValues(const std::vector& values) const { return option().normalizeValues(values); } diff --git a/src/gromacs/options/abstractoption.h b/src/gromacs/options/abstractoption.h index 97bc34e850..06883d6db9 100644 --- a/src/gromacs/options/abstractoption.h +++ b/src/gromacs/options/abstractoption.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,7 +66,8 @@ namespace gmx { class AbstractOptionStorage; -template class OptionStorageTemplate; +template +class OptionStorageTemplate; class OptionManagerContainer; class Any; @@ -94,113 +96,116 @@ class OptionSectionImpl; */ class AbstractOption { - public: - // Virtual only for completeness, in normal use should not be needed. - virtual ~AbstractOption() { } - - protected: - /*! \cond libapi */ - //! Initializes the name and default values for an option. - explicit AbstractOption(const char *name) - : minValueCount_(1), maxValueCount_(1), - name_(name), descr_(nullptr), storeIsSet_(nullptr) - { } - - /*! \brief - * Creates a default storage object for the option. - * - * \param[in] managers Manager container (unused if the option does - * not use a manager). - * \returns The created storage object. - * \throws APIError if invalid option settings have been provided. - * - * This method is called by Options::addOption() when initializing an - * option from the settings. - * - * Derived classes should implement the method to create an actual - * storage object and populate it with correct values. - * They should also throw APIError if they detect problems. - * - * Should only be called by Options::addOption(). - * - * The ownership of the return value is passed, but is not using a - * smart pointer to avoid introducing such a dependency in an installed - * header. The implementation will always consist of a single `new` - * call and returning that value, and the caller always immediately - * wraps the pointer in a smart pointer, so there is not exception - * safety issue. - */ - virtual AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const = 0; - - //! Sets the description for the option. - void setDescription(const char *descr) { descr_ = descr; } - //! Sets the storage location for whether the option is set. - void setStoreIsSet(bool *store) { storeIsSet_ = store; } - //! Sets a flag for the option. - void setFlag(OptionFlag flag) { flags_.set(flag); } - //! Clears a flag for the option. - void clearFlag(OptionFlag flag) { flags_.clear(flag); } - //! Sets or clears a flag for the option. - void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); } - //! Returns true if the option is vector-valued. - bool isVector() const { return hasFlag(efOption_Vector); } - /*! \brief - * Sets the option to be vector-valued. - * - * This method is provided for convenience to make management of value - * counts easier. In order to implement a vector-valued option, the - * class derived from AbstractOption should expose a method that calls - * this method, and the storage object derived from - * AbstractOptionStorage should check isVector(). - * If only a single value is provided, the storage object should fill - * the whole vector with that value. - * - * The length of the vector (the value of maxValueCount_) must be - * fixed. The default length is 3 elements. - */ - void setVector() +public: + // Virtual only for completeness, in normal use should not be needed. + virtual ~AbstractOption() {} + +protected: + /*! \cond libapi */ + //! Initializes the name and default values for an option. + explicit AbstractOption(const char* name) : + minValueCount_(1), + maxValueCount_(1), + name_(name), + descr_(nullptr), + storeIsSet_(nullptr) + { + } + + /*! \brief + * Creates a default storage object for the option. + * + * \param[in] managers Manager container (unused if the option does + * not use a manager). + * \returns The created storage object. + * \throws APIError if invalid option settings have been provided. + * + * This method is called by Options::addOption() when initializing an + * option from the settings. + * + * Derived classes should implement the method to create an actual + * storage object and populate it with correct values. + * They should also throw APIError if they detect problems. + * + * Should only be called by Options::addOption(). + * + * The ownership of the return value is passed, but is not using a + * smart pointer to avoid introducing such a dependency in an installed + * header. The implementation will always consist of a single `new` + * call and returning that value, and the caller always immediately + * wraps the pointer in a smart pointer, so there is not exception + * safety issue. + */ + virtual AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const = 0; + + //! Sets the description for the option. + void setDescription(const char* descr) { descr_ = descr; } + //! Sets the storage location for whether the option is set. + void setStoreIsSet(bool* store) { storeIsSet_ = store; } + //! Sets a flag for the option. + void setFlag(OptionFlag flag) { flags_.set(flag); } + //! Clears a flag for the option. + void clearFlag(OptionFlag flag) { flags_.clear(flag); } + //! Sets or clears a flag for the option. + void setFlag(OptionFlag flag, bool bSet) { flags_.set(flag, bSet); } + //! Returns true if the option is vector-valued. + bool isVector() const { return hasFlag(efOption_Vector); } + /*! \brief + * Sets the option to be vector-valued. + * + * This method is provided for convenience to make management of value + * counts easier. In order to implement a vector-valued option, the + * class derived from AbstractOption should expose a method that calls + * this method, and the storage object derived from + * AbstractOptionStorage should check isVector(). + * If only a single value is provided, the storage object should fill + * the whole vector with that value. + * + * The length of the vector (the value of maxValueCount_) must be + * fixed. The default length is 3 elements. + */ + void setVector() + { + setFlag(efOption_Vector); + minValueCount_ = 1; + if (maxValueCount_ == 1) { - setFlag(efOption_Vector); - minValueCount_ = 1; - if (maxValueCount_ == 1) - { - maxValueCount_ = 3; - } + maxValueCount_ = 3; } - //! Sets the required number of values for the option. - void setValueCount(int count) + } + //! Sets the required number of values for the option. + void setValueCount(int count) + { + if (!hasFlag(efOption_Vector)) { - if (!hasFlag(efOption_Vector)) - { - minValueCount_ = count; - } - maxValueCount_ = count; + minValueCount_ = count; } - - //! Minimum number of values required for the option. - int minValueCount_; - //! Maximum number of values allowed for the option. - int maxValueCount_; - //! \endcond - - private: - //! Returns true if a flag has been set. - bool hasFlag(OptionFlag flag) const { return flags_.test(flag); } - - const char *name_; - //! Pointer to description of the option. - const char *descr_; - OptionFlags flags_; - bool *storeIsSet_; - - /*! \brief - * Needed to initialize an AbstractOptionStorage object from this class - * without otherwise unnecessary accessors. - */ - friend class AbstractOptionStorage; - //! Needed to be able to call createStorage(). - friend class internal::OptionSectionImpl; + maxValueCount_ = count; + } + + //! Minimum number of values required for the option. + int minValueCount_; + //! Maximum number of values allowed for the option. + int maxValueCount_; + //! \endcond + +private: + //! Returns true if a flag has been set. + bool hasFlag(OptionFlag flag) const { return flags_.test(flag); } + + const char* name_; + //! Pointer to description of the option. + const char* descr_; + OptionFlags flags_; + bool* storeIsSet_; + + /*! \brief + * Needed to initialize an AbstractOptionStorage object from this class + * without otherwise unnecessary accessors. + */ + friend class AbstractOptionStorage; + //! Needed to be able to call createStorage(). + friend class internal::OptionSectionImpl; }; /*! \brief @@ -224,181 +229,225 @@ class AbstractOption * \inlibraryapi * \ingroup module_options */ -template +template class OptionTemplate : public AbstractOption { - public: - //! Type that stores a single option value. - typedef T ValueType; - //! Alias for the derived class type. - typedef U MyClass; - - /*! \brief - * Sets a description for the option. - * - * \param[in] descr Description to set. - * - * String in \p descr is copied when the option is created. - */ - MyClass &description(const char *descr) - { setDescription(descr); return me(); } - //! Hides the option from normal help output. - MyClass &hidden(bool bHidden = true) - { setFlag(efOption_Hidden, bHidden); return me(); } - /*! \brief - * Requires the option to be specified explicitly. - * - * Note that if you specify defaultValue() together with required(), - * the user is not required to explicitly provide the option. - * In this case, required() only affects possible help output. - */ - MyClass &required(bool bRequired = true) - { setFlag(efOption_Required, bRequired); return me(); } - //! Allows the option to be specified multiple times. - MyClass &allowMultiple(bool bMulti = true) - { setFlag(efOption_MultipleTimes, bMulti); return me(); } - //! Requires exactly \p count values for the option. - MyClass &valueCount(int count) { setValueCount(count); return me(); } - //! Allows any number of values for the option. - MyClass &multiValue(bool bMulti = true) - { if (bMulti) { maxValueCount_ = -1; } return me(); } - - /*! \brief - * Sets a default value for the option. - * - * \param[in] defaultValue Default value. - * - * If the option is never set, the default value is copied to the - * assigned storage. Note that if the option is not set and there - * is no default value, the storage is not altered, which can also be - * used to provide a default value. The latter method has to be used - * if the option can take multiple values. - * - * \p defaultValue is copied when the option is created. - */ - MyClass &defaultValue(const T &defaultValue) - { defaultValue_ = &defaultValue; return me(); } - /*! \brief - * Sets a default value for the option when it is set. - * - * \param[in] defaultValue Default value. - * - * This value is used if the option is set, but no value is provided. - * If the option is never set, the value set with defaultValue() is - * used. Can only be used for options that accept a single value. - * - * \p defaultValue is copied when the option is created. - */ - MyClass &defaultValueIfSet(const T &defaultValue) - { defaultValueIfSet_ = &defaultValue; return me(); } - /*! \brief - * Stores value(s) in memory pointed by \p store. - * - * \param[in] store Storage for option value(s). - * - * The caller is responsible for allocating enough memory such that - * the any allowed number of values fits into the array pointed by - * \p store. If there is no maximum allowed number or if the maximum - * is inconveniently large, storeVector() should be used. - * - * For information on when values are available in the storage, see - * storeVector(). - * - * The pointer provided should remain valid as long as the associated - * Options object exists. - */ - MyClass &store(T *store) - { store_ = store; return me(); } - /*! \brief - * Stores number of values in the value pointed by \p countptr. - * - * \param[in] countptr Storage for the number of values. - * - * For information on when values are available in the storage, see - * storeVector(). - * - * The pointers provided should remain valid as long as the associated - * Options object exists. - */ - MyClass &storeCount(int *countptr) - { countptr_ = countptr; return me(); } - /*! \brief - * Stores option values in the provided vector. - * - * \param[in] store Vector to store option values in. - * - * Values are added to the vector after each successful set of values - * is parsed. Note that for some options, the value may be changed - * later, and is only guaranteed to be correct after Options::finish() - * has been called. - * - * The pointer provided should remain valid as long as the associated - * Options object exists. - */ - MyClass &storeVector(std::vector *store) - { storeVector_ = store; return me(); } - /*! \brief - * Stores whether the option was explicitly set. - * - * \param[in] store Variable to store the flag in. - * - * The value is set to `false` on creation of the option, and to `true` - * as soon as a value is assigned to the option. A default value does - * not set the flag to `true`, but assignment that uses - * defaultValueIfSet() does. - * - * The pointer provided should remain valid as long as the associated - * Options object exists. - */ - MyClass &storeIsSet(bool *store) - { setStoreIsSet(store); return me(); } - - protected: - /*! \cond libapi */ - //! Alias for the template class for use in base classes. - typedef OptionTemplate MyBase; - - //! Initializes the name and default values for an option. - explicit OptionTemplate(const char *name) - : AbstractOption(name), - defaultValue_(nullptr), defaultValueIfSet_(nullptr), store_(nullptr), - countptr_(nullptr), storeVector_(nullptr) - { } - - /*! \brief - * Returns a pointer to user-specified default value, or NULL if there - * is none. - */ - const T *defaultValue() const { return defaultValue_; } - /*! \brief - * Returns a pointer to user-specified default value, or NULL if there - * is none. - */ - const T *defaultValueIfSet() const { return defaultValueIfSet_; } - /*! \brief - * Returns a pointer to the storage location, or NULL if none specified. - */ - T *store() const { return store_; } - /*! \brief - * Returns a pointer to the storage vector, or NULL if none specified. - */ - std::vector *storeVector() const { return storeVector_; } - //! Returns \p *this casted into MyClass to reduce typing. - MyClass &me() { return static_cast(*this); } - //! \endcond - - private: - const T *defaultValue_; - const T *defaultValueIfSet_; - T *store_; - int *countptr_; - std::vector *storeVector_; - - /*! \brief - * Needed to initialize storage from this class without otherwise - * unnecessary accessors. - */ - friend class OptionStorageTemplate; +public: + //! Type that stores a single option value. + typedef T ValueType; + //! Alias for the derived class type. + typedef U MyClass; + + /*! \brief + * Sets a description for the option. + * + * \param[in] descr Description to set. + * + * String in \p descr is copied when the option is created. + */ + MyClass& description(const char* descr) + { + setDescription(descr); + return me(); + } + //! Hides the option from normal help output. + MyClass& hidden(bool bHidden = true) + { + setFlag(efOption_Hidden, bHidden); + return me(); + } + /*! \brief + * Requires the option to be specified explicitly. + * + * Note that if you specify defaultValue() together with required(), + * the user is not required to explicitly provide the option. + * In this case, required() only affects possible help output. + */ + MyClass& required(bool bRequired = true) + { + setFlag(efOption_Required, bRequired); + return me(); + } + //! Allows the option to be specified multiple times. + MyClass& allowMultiple(bool bMulti = true) + { + setFlag(efOption_MultipleTimes, bMulti); + return me(); + } + //! Requires exactly \p count values for the option. + MyClass& valueCount(int count) + { + setValueCount(count); + return me(); + } + //! Allows any number of values for the option. + MyClass& multiValue(bool bMulti = true) + { + if (bMulti) + { + maxValueCount_ = -1; + } + return me(); + } + + /*! \brief + * Sets a default value for the option. + * + * \param[in] defaultValue Default value. + * + * If the option is never set, the default value is copied to the + * assigned storage. Note that if the option is not set and there + * is no default value, the storage is not altered, which can also be + * used to provide a default value. The latter method has to be used + * if the option can take multiple values. + * + * \p defaultValue is copied when the option is created. + */ + MyClass& defaultValue(const T& defaultValue) + { + defaultValue_ = &defaultValue; + return me(); + } + /*! \brief + * Sets a default value for the option when it is set. + * + * \param[in] defaultValue Default value. + * + * This value is used if the option is set, but no value is provided. + * If the option is never set, the value set with defaultValue() is + * used. Can only be used for options that accept a single value. + * + * \p defaultValue is copied when the option is created. + */ + MyClass& defaultValueIfSet(const T& defaultValue) + { + defaultValueIfSet_ = &defaultValue; + return me(); + } + /*! \brief + * Stores value(s) in memory pointed by \p store. + * + * \param[in] store Storage for option value(s). + * + * The caller is responsible for allocating enough memory such that + * the any allowed number of values fits into the array pointed by + * \p store. If there is no maximum allowed number or if the maximum + * is inconveniently large, storeVector() should be used. + * + * For information on when values are available in the storage, see + * storeVector(). + * + * The pointer provided should remain valid as long as the associated + * Options object exists. + */ + MyClass& store(T* store) + { + store_ = store; + return me(); + } + /*! \brief + * Stores number of values in the value pointed by \p countptr. + * + * \param[in] countptr Storage for the number of values. + * + * For information on when values are available in the storage, see + * storeVector(). + * + * The pointers provided should remain valid as long as the associated + * Options object exists. + */ + MyClass& storeCount(int* countptr) + { + countptr_ = countptr; + return me(); + } + /*! \brief + * Stores option values in the provided vector. + * + * \param[in] store Vector to store option values in. + * + * Values are added to the vector after each successful set of values + * is parsed. Note that for some options, the value may be changed + * later, and is only guaranteed to be correct after Options::finish() + * has been called. + * + * The pointer provided should remain valid as long as the associated + * Options object exists. + */ + MyClass& storeVector(std::vector* store) + { + storeVector_ = store; + return me(); + } + /*! \brief + * Stores whether the option was explicitly set. + * + * \param[in] store Variable to store the flag in. + * + * The value is set to `false` on creation of the option, and to `true` + * as soon as a value is assigned to the option. A default value does + * not set the flag to `true`, but assignment that uses + * defaultValueIfSet() does. + * + * The pointer provided should remain valid as long as the associated + * Options object exists. + */ + MyClass& storeIsSet(bool* store) + { + setStoreIsSet(store); + return me(); + } + +protected: + /*! \cond libapi */ + //! Alias for the template class for use in base classes. + typedef OptionTemplate MyBase; + + //! Initializes the name and default values for an option. + explicit OptionTemplate(const char* name) : + AbstractOption(name), + defaultValue_(nullptr), + defaultValueIfSet_(nullptr), + store_(nullptr), + countptr_(nullptr), + storeVector_(nullptr) + { + } + + /*! \brief + * Returns a pointer to user-specified default value, or NULL if there + * is none. + */ + const T* defaultValue() const { return defaultValue_; } + /*! \brief + * Returns a pointer to user-specified default value, or NULL if there + * is none. + */ + const T* defaultValueIfSet() const { return defaultValueIfSet_; } + /*! \brief + * Returns a pointer to the storage location, or NULL if none specified. + */ + T* store() const { return store_; } + /*! \brief + * Returns a pointer to the storage vector, or NULL if none specified. + */ + std::vector* storeVector() const { return storeVector_; } + //! Returns \p *this casted into MyClass to reduce typing. + MyClass& me() { return static_cast(*this); } + //! \endcond + +private: + const T* defaultValue_; + const T* defaultValueIfSet_; + T* store_; + int* countptr_; + std::vector* storeVector_; + + /*! \brief + * Needed to initialize storage from this class without otherwise + * unnecessary accessors. + */ + friend class OptionStorageTemplate; }; /*! \brief @@ -437,109 +486,109 @@ class OptionTemplate : public AbstractOption */ class OptionInfo { - public: - virtual ~OptionInfo(); - - /*! \brief - * Test whether the option is of a particular type. - * - * \tparam InfoType Option type to test for. Should be a class derived - * from OptionInfo. - */ - template - bool isType() const - { - return toType() != nullptr; - } - /*! \brief - * Convert the info object to a particular type if the type is correct. - * - * \tparam InfoType Option type to convert to. Should be a class - * derived from OptionInfo. - * \retval this converted to a pointer to \p InfoType, or NULL if the - * conversion is not possible. - */ - template - InfoType *toType() - { - return dynamic_cast(this); - } - //! \copydoc toType() - template - const InfoType *toType() const - { - return dynamic_cast(this); - } - - //! Returns true if the option has been set. - bool isSet() const; - //! Returns true if the option is a hidden option. - bool isHidden() const; - //! Returns true if the option is required. - bool isRequired() const; - //! Returns the minimum number of values that this option accepts. - int minValueCount() const; - //! Returns the maximum number of values that this option accepts. - int maxValueCount() const; - //! Returns the name of the option. - const std::string &name() const; - //! Returns the type of the option as a string. - std::string type() const; - //! Returns the description of the option. - std::string formatDescription() const; - - /*! \brief - * Returns the default value(s) of the option. - * - * The returned values should all be of the same type, but returning - * each as a separate any is currently simpler. - * - * Currently, this can only be called before option values have been - * assigned. - */ - std::vector defaultValues() const; - /*! \brief - * Returns the default value(s) of the option as strings. - * - * If there is no default value, but defaultValueIfSet() is set, that - * is returned instead. - * - * Currently, this can only be called before option values have been - * assigned. - */ - std::vector defaultValuesAsStrings() const; - /*! \brief - * Converts given values to native representation for this option. - * - * For example, strings are parsed to the type that is actually used to - * store the options. - * - * The return value only depends on the option type, not on the current - * value of the option, and the current value in the option is not - * changed. - */ - std::vector normalizeValues(const std::vector &values) const; - - protected: - /*! \cond libapi */ - /*! \brief - * Wraps a given option object. - * - * Does not throw. - */ - explicit OptionInfo(AbstractOptionStorage *option); - - //! Returns the wrapped option storage object. - AbstractOptionStorage &option() { return option_; } - //! Returns the wrapped option storage object. - const AbstractOptionStorage &option() const { return option_; } - //! \endcond - - private: - //! The wrapped option. - AbstractOptionStorage &option_; - - GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo); +public: + virtual ~OptionInfo(); + + /*! \brief + * Test whether the option is of a particular type. + * + * \tparam InfoType Option type to test for. Should be a class derived + * from OptionInfo. + */ + template + bool isType() const + { + return toType() != nullptr; + } + /*! \brief + * Convert the info object to a particular type if the type is correct. + * + * \tparam InfoType Option type to convert to. Should be a class + * derived from OptionInfo. + * \retval this converted to a pointer to \p InfoType, or NULL if the + * conversion is not possible. + */ + template + InfoType* toType() + { + return dynamic_cast(this); + } + //! \copydoc toType() + template + const InfoType* toType() const + { + return dynamic_cast(this); + } + + //! Returns true if the option has been set. + bool isSet() const; + //! Returns true if the option is a hidden option. + bool isHidden() const; + //! Returns true if the option is required. + bool isRequired() const; + //! Returns the minimum number of values that this option accepts. + int minValueCount() const; + //! Returns the maximum number of values that this option accepts. + int maxValueCount() const; + //! Returns the name of the option. + const std::string& name() const; + //! Returns the type of the option as a string. + std::string type() const; + //! Returns the description of the option. + std::string formatDescription() const; + + /*! \brief + * Returns the default value(s) of the option. + * + * The returned values should all be of the same type, but returning + * each as a separate any is currently simpler. + * + * Currently, this can only be called before option values have been + * assigned. + */ + std::vector defaultValues() const; + /*! \brief + * Returns the default value(s) of the option as strings. + * + * If there is no default value, but defaultValueIfSet() is set, that + * is returned instead. + * + * Currently, this can only be called before option values have been + * assigned. + */ + std::vector defaultValuesAsStrings() const; + /*! \brief + * Converts given values to native representation for this option. + * + * For example, strings are parsed to the type that is actually used to + * store the options. + * + * The return value only depends on the option type, not on the current + * value of the option, and the current value in the option is not + * changed. + */ + std::vector normalizeValues(const std::vector& values) const; + +protected: + /*! \cond libapi */ + /*! \brief + * Wraps a given option object. + * + * Does not throw. + */ + explicit OptionInfo(AbstractOptionStorage* option); + + //! Returns the wrapped option storage object. + AbstractOptionStorage& option() { return option_; } + //! Returns the wrapped option storage object. + const AbstractOptionStorage& option() const { return option_; } + //! \endcond + +private: + //! The wrapped option. + AbstractOptionStorage& option_; + + GMX_DISALLOW_COPY_AND_ASSIGN(OptionInfo); }; } // namespace gmx diff --git a/src/gromacs/options/abstractoptionstorage.h b/src/gromacs/options/abstractoptionstorage.h index 7067f72743..d82551aa89 100644 --- a/src/gromacs/options/abstractoptionstorage.h +++ b/src/gromacs/options/abstractoptionstorage.h @@ -87,246 +87,243 @@ class Any; */ class AbstractOptionStorage { - public: - virtual ~AbstractOptionStorage(); +public: + virtual ~AbstractOptionStorage(); - //! Returns true if the option has been set. - bool isSet() const { return hasFlag(efOption_Set); } - /*! \brief - * Returns true if the option is a boolean option. - * - * This is used to optionally support an alternative syntax where an - * option provided with no value sets the value to true and an - * option prefixed with "no" clears the value. - */ - bool isBoolean() const; - //! Returns true if the option is a hidden option. - bool isHidden() const { return hasFlag(efOption_Hidden); } - //! Returns true if the option is required. - bool isRequired() const { return hasFlag(efOption_Required); } - //! Returns true if the option is vector-valued. - bool isVector() const { return hasFlag(efOption_Vector); } - //! Returns the name of the option. - const std::string &name() const { return name_; } - //! Returns the description of the option set by the calling code. - const std::string &description() const { return descr_; } + //! Returns true if the option has been set. + bool isSet() const { return hasFlag(efOption_Set); } + /*! \brief + * Returns true if the option is a boolean option. + * + * This is used to optionally support an alternative syntax where an + * option provided with no value sets the value to true and an + * option prefixed with "no" clears the value. + */ + bool isBoolean() const; + //! Returns true if the option is a hidden option. + bool isHidden() const { return hasFlag(efOption_Hidden); } + //! Returns true if the option is required. + bool isRequired() const { return hasFlag(efOption_Required); } + //! Returns true if the option is vector-valued. + bool isVector() const { return hasFlag(efOption_Vector); } + //! Returns the name of the option. + const std::string& name() const { return name_; } + //! Returns the description of the option set by the calling code. + const std::string& description() const { return descr_; } - //! Returns true if defaultValueIfSet() value is specified. - bool defaultValueIfSetExists() const - { return hasFlag(efOption_DefaultValueIfSetExists); } - //! Returns the minimum number of values required in one set. - int minValueCount() const { return minValueCount_; } - //! Returns the maximum allowed number of values in one set (-1 = no limit). - int maxValueCount() const { return maxValueCount_; } + //! Returns true if defaultValueIfSet() value is specified. + bool defaultValueIfSetExists() const { return hasFlag(efOption_DefaultValueIfSetExists); } + //! Returns the minimum number of values required in one set. + int minValueCount() const { return minValueCount_; } + //! Returns the maximum allowed number of values in one set (-1 = no limit). + int maxValueCount() const { return maxValueCount_; } - /*! \brief - * Returns an option info object corresponding to this option. - */ - virtual OptionInfo &optionInfo() = 0; - /*! \brief - * Returns a short string describing the type of the option. - */ - virtual std::string typeString() const = 0; - /*! \brief - * Formats additional description for the option. - * - * If this method returns a non-empty string, it is appended to the - * plain description when printing help texts. - * The default implementation returns an empty string. - */ - virtual std::string formatExtraDescription() const - { return std::string(); } - /*! \brief - * Returns the number of option values added so far. - */ - virtual int valueCount() const = 0; - //! \copydoc OptionInfo::defaultValues() - virtual std::vector defaultValues() const = 0; - //! \copydoc OptionInfo::defaultValuesAsStrings() - virtual std::vector defaultValuesAsStrings() const = 0; - //! \copydoc OptionInfo::normalizeValues() - virtual std::vector normalizeValues(const std::vector &values) const = 0; + /*! \brief + * Returns an option info object corresponding to this option. + */ + virtual OptionInfo& optionInfo() = 0; + /*! \brief + * Returns a short string describing the type of the option. + */ + virtual std::string typeString() const = 0; + /*! \brief + * Formats additional description for the option. + * + * If this method returns a non-empty string, it is appended to the + * plain description when printing help texts. + * The default implementation returns an empty string. + */ + virtual std::string formatExtraDescription() const { return std::string(); } + /*! \brief + * Returns the number of option values added so far. + */ + virtual int valueCount() const = 0; + //! \copydoc OptionInfo::defaultValues() + virtual std::vector defaultValues() const = 0; + //! \copydoc OptionInfo::defaultValuesAsStrings() + virtual std::vector defaultValuesAsStrings() const = 0; + //! \copydoc OptionInfo::normalizeValues() + virtual std::vector normalizeValues(const std::vector& values) const = 0; - /*! \brief - * Starts adding values from a new source for the option. - * - * This marks the vurrent value of the option as a default value, - * causing next call to startSet() to clear it. This allows values - * from the new source to overwrite old values. - * - * This method does not throw. - */ - void startSource(); - /*! \brief - * Starts adding a new set of values for the option. - * - * \throws InvalidInputError if option is specified multiple times, - * but is not specified to accept it. - * - * If the parameter is specified multiple times, startSet() should be - * called before the values for each instance. - * - * Strong exception safety guarantee. - */ - void startSet(); - /*! \brief - * Adds a new value for the option. - * - * \param[in] value Value to convert. - * \throws InvalidInputError if value cannot be converted, or - * if there are too many values. - * - * This method should only be called between startSet() and - * finishSet(). - */ - void appendValue(const Any &value); - /*! \brief - * Performs validation and/or actions once a set of values has been - * added. - * - * \throws InvalidInputError if too few values have been provided, or - * if the valid values since previous startSet() are invalid as a - * set. - * - * If the parameter is specified multiple times, finishSet() should be - * called after the values for each instance. - */ - void finishSet(); - /*! \brief - * Performs validation and/or actions once all values have been added. - * - * \throws InvalidInputError if the option is required but not set, or - * if all valid values together are invalid as a set. - * - * This method should be called after all values have been provided - * with appendValue(). - */ - void finish(); + /*! \brief + * Starts adding values from a new source for the option. + * + * This marks the vurrent value of the option as a default value, + * causing next call to startSet() to clear it. This allows values + * from the new source to overwrite old values. + * + * This method does not throw. + */ + void startSource(); + /*! \brief + * Starts adding a new set of values for the option. + * + * \throws InvalidInputError if option is specified multiple times, + * but is not specified to accept it. + * + * If the parameter is specified multiple times, startSet() should be + * called before the values for each instance. + * + * Strong exception safety guarantee. + */ + void startSet(); + /*! \brief + * Adds a new value for the option. + * + * \param[in] value Value to convert. + * \throws InvalidInputError if value cannot be converted, or + * if there are too many values. + * + * This method should only be called between startSet() and + * finishSet(). + */ + void appendValue(const Any& value); + /*! \brief + * Performs validation and/or actions once a set of values has been + * added. + * + * \throws InvalidInputError if too few values have been provided, or + * if the valid values since previous startSet() are invalid as a + * set. + * + * If the parameter is specified multiple times, finishSet() should be + * called after the values for each instance. + */ + void finishSet(); + /*! \brief + * Performs validation and/or actions once all values have been added. + * + * \throws InvalidInputError if the option is required but not set, or + * if all valid values together are invalid as a set. + * + * This method should be called after all values have been provided + * with appendValue(). + */ + void finish(); - protected: - /*! \brief - * Initializes the storage object from the settings object. - * - * \param[in] settings Option settings. - * \param[in] staticFlags Option flags that are always set and specify - * generic behavior of the option. - * \throws APIError if invalid settings have been provided. - */ - AbstractOptionStorage(const AbstractOption &settings, - OptionFlags staticFlags); +protected: + /*! \brief + * Initializes the storage object from the settings object. + * + * \param[in] settings Option settings. + * \param[in] staticFlags Option flags that are always set and specify + * generic behavior of the option. + * \throws APIError if invalid settings have been provided. + */ + AbstractOptionStorage(const AbstractOption& settings, OptionFlags staticFlags); - //! Marks the option as set. - void markAsSet(); - //! Returns true if the given flag is set. - bool hasFlag(OptionFlag flag) const { return flags_.test(flag); } - //! Sets the given flag. - void setFlag(OptionFlag flag) { return flags_.set(flag); } - //! Clears the given flag. - void clearFlag(OptionFlag flag) { return flags_.clear(flag); } + //! Marks the option as set. + void markAsSet(); + //! Returns true if the given flag is set. + bool hasFlag(OptionFlag flag) const { return flags_.test(flag); } + //! Sets the given flag. + void setFlag(OptionFlag flag) { return flags_.set(flag); } + //! Clears the given flag. + void clearFlag(OptionFlag flag) { return flags_.clear(flag); } - /*! \brief - * Sets a new minimum number of values required in one set. - * - * \param[in] count New minimum number of values (must be > 0). - * \throws InvalidInputError if already provided values violate the limit. - * - * If values have already been provided, it is checked that there are - * enough. - * - * Cannot be called for options with ::efOption_MultipleTimes set, - * because it is impossible to check the requirement after the values - * have been set. - * If attempted, will assert. - */ - void setMinValueCount(int count); - /*! \brief - * Sets a new maximum number of values required in one set. - * - * \param[in] count New maximum number of values - * (must be > 0, or -1 for no limit). - * \throws InvalidInputError if already provided values violate the limit. - * - * If values have already been provided, it is checked that there are - * not too many. - * - * Cannot be called for options with ::efOption_MultipleTimes set, - * because it is impossible to check the requirement after the values - * have been set. - * If attempted, will assert. - */ - void setMaxValueCount(int count); + /*! \brief + * Sets a new minimum number of values required in one set. + * + * \param[in] count New minimum number of values (must be > 0). + * \throws InvalidInputError if already provided values violate the limit. + * + * If values have already been provided, it is checked that there are + * enough. + * + * Cannot be called for options with ::efOption_MultipleTimes set, + * because it is impossible to check the requirement after the values + * have been set. + * If attempted, will assert. + */ + void setMinValueCount(int count); + /*! \brief + * Sets a new maximum number of values required in one set. + * + * \param[in] count New maximum number of values + * (must be > 0, or -1 for no limit). + * \throws InvalidInputError if already provided values violate the limit. + * + * If values have already been provided, it is checked that there are + * not too many. + * + * Cannot be called for options with ::efOption_MultipleTimes set, + * because it is impossible to check the requirement after the values + * have been set. + * If attempted, will assert. + */ + void setMaxValueCount(int count); - /*! \brief - * Removes all values from temporary storage for a set. - * - * This function is always called before starting to add values to - * a set, allowing the storage to clear its internal buffers. - * - * Should not throw. - */ - virtual void clearSet() = 0; - /*! \brief - * Adds a new value. - * - * \param[in] value Value to convert. - * \throws InvalidInputError if \p value is not valid for this option - * or if there have been too many values in the set. - * - * This method may be called multiple times if the underlying - * option is defined to accept multiple values. - * - * \see OptionStorageTemplate::convertValue() - */ - virtual void convertValue(const Any &value) = 0; - /*! \brief - * Performs validation and/or actions once a set of values has been - * added. - * - * \throws InvalidInputError if the values in the set are not valid - * as a whole. - * - * This method may be called multiple times if the underlying option - * can be specified multiple times. - * This method is not currently called if one of the convertValue() - * calls throwed. - * - * \todo - * Improve the call semantics. - * - * \see OptionStorageTemplate::processSetValues() - */ - virtual void processSet() = 0; - /*! \brief - * Performs validation and/or actions once all values have been added. - * - * \throws InvalidInputError if all provided values are not valid as - * a set. - * - * This method is always called once. - * - * If the method throws, implementation should take care to leave the - * option in a consistent, meaningful state. However, currently none - * of the implementations actually throw in any situation where the - * option may be left in an inconsistent state. - */ - virtual void processAll() = 0; + /*! \brief + * Removes all values from temporary storage for a set. + * + * This function is always called before starting to add values to + * a set, allowing the storage to clear its internal buffers. + * + * Should not throw. + */ + virtual void clearSet() = 0; + /*! \brief + * Adds a new value. + * + * \param[in] value Value to convert. + * \throws InvalidInputError if \p value is not valid for this option + * or if there have been too many values in the set. + * + * This method may be called multiple times if the underlying + * option is defined to accept multiple values. + * + * \see OptionStorageTemplate::convertValue() + */ + virtual void convertValue(const Any& value) = 0; + /*! \brief + * Performs validation and/or actions once a set of values has been + * added. + * + * \throws InvalidInputError if the values in the set are not valid + * as a whole. + * + * This method may be called multiple times if the underlying option + * can be specified multiple times. + * This method is not currently called if one of the convertValue() + * calls throwed. + * + * \todo + * Improve the call semantics. + * + * \see OptionStorageTemplate::processSetValues() + */ + virtual void processSet() = 0; + /*! \brief + * Performs validation and/or actions once all values have been added. + * + * \throws InvalidInputError if all provided values are not valid as + * a set. + * + * This method is always called once. + * + * If the method throws, implementation should take care to leave the + * option in a consistent, meaningful state. However, currently none + * of the implementations actually throw in any situation where the + * option may be left in an inconsistent state. + */ + virtual void processAll() = 0; - private: - std::string name_; - std::string descr_; - //! Flags for the option. - OptionFlags flags_; - bool *storeIsSet_; - //! Minimum number of values required (in one set). - int minValueCount_; - //! Maximum allowed number of values (in one set), or -1 if no limit. - int maxValueCount_; - //! Whether we are currently assigning values to a set. - bool bInSet_; - //! Whether there were errors in set values. - bool bSetValuesHadErrors_; +private: + std::string name_; + std::string descr_; + //! Flags for the option. + OptionFlags flags_; + bool* storeIsSet_; + //! Minimum number of values required (in one set). + int minValueCount_; + //! Maximum allowed number of values (in one set), or -1 if no limit. + int maxValueCount_; + //! Whether we are currently assigning values to a set. + bool bInSet_; + //! Whether there were errors in set values. + bool bSetValuesHadErrors_; - GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionStorage); + GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionStorage); }; } // namespace gmx diff --git a/src/gromacs/options/abstractsection.cpp b/src/gromacs/options/abstractsection.cpp index 8f3fe770a7..f272b8163f 100644 --- a/src/gromacs/options/abstractsection.cpp +++ b/src/gromacs/options/abstractsection.cpp @@ -53,24 +53,22 @@ namespace gmx */ // static -IOptionSectionStorage * -AbstractOptionSectionHandle::getStorage(internal::OptionSectionImpl *section) +IOptionSectionStorage* AbstractOptionSectionHandle::getStorage(internal::OptionSectionImpl* section) { return section->storage_.get(); } -IOptionsContainer &AbstractOptionSectionHandle::addGroup() +IOptionsContainer& AbstractOptionSectionHandle::addGroup() { return section_->addGroup(); } -internal::OptionSectionImpl * -AbstractOptionSectionHandle::addSectionImpl(const AbstractOptionSection §ion) +internal::OptionSectionImpl* AbstractOptionSectionHandle::addSectionImpl(const AbstractOptionSection& section) { return section_->addSectionImpl(section); } -OptionInfo *AbstractOptionSectionHandle::addOptionImpl(const AbstractOption &settings) +OptionInfo* AbstractOptionSectionHandle::addOptionImpl(const AbstractOption& settings) { return section_->addOptionImpl(settings); } @@ -79,7 +77,7 @@ OptionInfo *AbstractOptionSectionHandle::addOptionImpl(const AbstractOption &set * AbstractOptionSectionInfo */ -const std::string &AbstractOptionSectionInfo::name() const +const std::string& AbstractOptionSectionInfo::name() const { return section_.name_; } diff --git a/src/gromacs/options/abstractsection.h b/src/gromacs/options/abstractsection.h index 6acae82c09..975176954d 100644 --- a/src/gromacs/options/abstractsection.h +++ b/src/gromacs/options/abstractsection.h @@ -69,23 +69,23 @@ class OptionSectionImpl; */ class AbstractOptionSection { - protected: - //! \cond libapi - //! Initializes option properties with the given name. - explicit AbstractOptionSection(const char *name) : name_(name) {} - virtual ~AbstractOptionSection() {} - /*! \brief - * Creates a storage object corresponding to this section. - * - * Similar to AbstractOption::createStorage(). - */ - virtual std::unique_ptr createStorage() const = 0; - //! \endcond - - private: - const char *name_; - - friend class internal::OptionSectionImpl; +protected: + //! \cond libapi + //! Initializes option properties with the given name. + explicit AbstractOptionSection(const char* name) : name_(name) {} + virtual ~AbstractOptionSection() {} + /*! \brief + * Creates a storage object corresponding to this section. + * + * Similar to AbstractOption::createStorage(). + */ + virtual std::unique_ptr createStorage() const = 0; + //! \endcond + +private: + const char* name_; + + friend class internal::OptionSectionImpl; }; /*! \brief @@ -98,76 +98,70 @@ class AbstractOptionSection */ class AbstractOptionSectionHandle : public IOptionsContainerWithSections { - public: - // From IOptionsContainer - //! \copydoc IOptionsContainer::addGroup() - IOptionsContainer &addGroup() override; - - protected: - //! \cond libapi - /*! \brief - * Returns the storage for a particular type of section. - * - * This is intended for use in derived class constructors, where the - * handle needs access to the actual storage. The handle should know - * the type of storage created for the section type it deals with, so - * the cast should always be successful. - */ - template - static StorageType *getStorage(internal::OptionSectionImpl *section) - { - IOptionSectionStorage *storage = getStorage(section); - StorageType *typedStorage - = dynamic_cast(storage); - GMX_ASSERT(typedStorage != nullptr, "Mismatching section storage type"); - return typedStorage; - } - - //! Wraps a given section storage object. - explicit AbstractOptionSectionHandle(internal::OptionSectionImpl *section) - : section_(section) - { - } - //! \endcond - - private: - // From IOptionsContainerWithSections - internal::OptionSectionImpl * - addSectionImpl(const AbstractOptionSection §ion) override; - // From IOptionsContainer - OptionInfo *addOptionImpl(const AbstractOption &settings) override; - - /*! \brief - * Implementation helper for the template method. - * - * This allows encapsulating the implementation within the source file. - */ - static IOptionSectionStorage *getStorage(internal::OptionSectionImpl *section); - - internal::OptionSectionImpl *section_; +public: + // From IOptionsContainer + //! \copydoc IOptionsContainer::addGroup() + IOptionsContainer& addGroup() override; + +protected: + //! \cond libapi + /*! \brief + * Returns the storage for a particular type of section. + * + * This is intended for use in derived class constructors, where the + * handle needs access to the actual storage. The handle should know + * the type of storage created for the section type it deals with, so + * the cast should always be successful. + */ + template + static StorageType* getStorage(internal::OptionSectionImpl* section) + { + IOptionSectionStorage* storage = getStorage(section); + StorageType* typedStorage = dynamic_cast(storage); + GMX_ASSERT(typedStorage != nullptr, "Mismatching section storage type"); + return typedStorage; + } + + //! Wraps a given section storage object. + explicit AbstractOptionSectionHandle(internal::OptionSectionImpl* section) : section_(section) + { + } + //! \endcond + +private: + // From IOptionsContainerWithSections + internal::OptionSectionImpl* addSectionImpl(const AbstractOptionSection& section) override; + // From IOptionsContainer + OptionInfo* addOptionImpl(const AbstractOption& settings) override; + + /*! \brief + * Implementation helper for the template method. + * + * This allows encapsulating the implementation within the source file. + */ + static IOptionSectionStorage* getStorage(internal::OptionSectionImpl* section); + + internal::OptionSectionImpl* section_; }; class AbstractOptionSectionInfo { - public: - //! Wraps a given section storage object. - explicit AbstractOptionSectionInfo(internal::OptionSectionImpl *section) - : section_(*section) - { - } +public: + //! Wraps a given section storage object. + explicit AbstractOptionSectionInfo(internal::OptionSectionImpl* section) : section_(*section) {} - //! Returns the name of the section. - const std::string &name() const; + //! Returns the name of the section. + const std::string& name() const; - //! Returns the wrapped section storage object. - internal::OptionSectionImpl §ion() { return section_; } - //! Returns the wrapped section storage object. - const internal::OptionSectionImpl §ion() const { return section_; } + //! Returns the wrapped section storage object. + internal::OptionSectionImpl& section() { return section_; } + //! Returns the wrapped section storage object. + const internal::OptionSectionImpl& section() const { return section_; } - private: - internal::OptionSectionImpl §ion_; +private: + internal::OptionSectionImpl& section_; - GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionSectionInfo); + GMX_DISALLOW_COPY_AND_ASSIGN(AbstractOptionSectionInfo); }; } // namespace gmx diff --git a/src/gromacs/options/basicoptions.cpp b/src/gromacs/options/basicoptions.cpp index 26d3d049e6..2ced2570e4 100644 --- a/src/gromacs/options/basicoptions.cpp +++ b/src/gromacs/options/basicoptions.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -77,17 +78,17 @@ namespace * * \ingroup module_options */ -template -void expandVector(size_t length, std::vector *values) +template +void expandVector(size_t length, std::vector* values) { if (length > 0 && !values->empty() && values->size() != length) { if (values->size() != 1) { - GMX_THROW(gmx::InvalidInputError(gmx::formatString( - "Expected 1 or %zu values, got %zu", length, values->size()))); + GMX_THROW(gmx::InvalidInputError( + gmx::formatString("Expected 1 or %zu values, got %zu", length, values->size()))); } - const ValueType &value = (*values)[0]; + const ValueType& value = (*values)[0]; values->resize(length, value); } } @@ -103,12 +104,11 @@ void expandVector(size_t length, std::vector *values) * * \ingroup module_options */ -std::vector::const_iterator -findEnumValue(const std::vector &allowedValues, - const std::string &value) +std::vector::const_iterator findEnumValue(const std::vector& allowedValues, + const std::string& value) { - std::vector::const_iterator i; - std::vector::const_iterator match = allowedValues.end(); + std::vector::const_iterator i; + std::vector::const_iterator match = allowedValues.end(); for (i = allowedValues.begin(); i != allowedValues.end(); ++i) { // TODO: Case independence. @@ -136,12 +136,12 @@ namespace gmx * BooleanOptionStorage */ -std::string BooleanOptionStorage::formatSingleValue(const bool &value) const +std::string BooleanOptionStorage::formatSingleValue(const bool& value) const { return value ? "yes" : "no"; } -void BooleanOptionStorage::initConverter(ConverterType *converter) +void BooleanOptionStorage::initConverter(ConverterType* converter) { converter->addConverter(&fromStdString); } @@ -150,14 +150,11 @@ void BooleanOptionStorage::initConverter(ConverterType *converter) * BooleanOptionInfo */ -BooleanOptionInfo::BooleanOptionInfo(BooleanOptionStorage *option) - : OptionInfo(option) -{ -} +BooleanOptionInfo::BooleanOptionInfo(BooleanOptionStorage* option) : OptionInfo(option) {} -const BooleanOptionStorage &BooleanOptionInfo::option() const +const BooleanOptionStorage& BooleanOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } bool BooleanOptionInfo::defaultValue() const @@ -169,8 +166,7 @@ bool BooleanOptionInfo::defaultValue() const * BooleanOption */ -AbstractOptionStorage * -BooleanOption::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* BooleanOption::createStorage(const OptionManagerContainer& /*managers*/) const { return new BooleanOptionStorage(*this); } @@ -180,17 +176,17 @@ BooleanOption::createStorage(const OptionManagerContainer & /*managers*/) const * IntegerOptionStorage */ -std::string IntegerOptionStorage::formatSingleValue(const int &value) const +std::string IntegerOptionStorage::formatSingleValue(const int& value) const { return toString(value); } -void IntegerOptionStorage::initConverter(ConverterType *converter) +void IntegerOptionStorage::initConverter(ConverterType* converter) { converter->addConverter(&fromStdString); } -void IntegerOptionStorage::processSetValues(ValueList *values) +void IntegerOptionStorage::processSetValues(ValueList* values) { if (isVector()) { @@ -202,17 +198,13 @@ void IntegerOptionStorage::processSetValues(ValueList *values) * IntegerOptionInfo */ -IntegerOptionInfo::IntegerOptionInfo(IntegerOptionStorage *option) - : OptionInfo(option) -{ -} +IntegerOptionInfo::IntegerOptionInfo(IntegerOptionStorage* option) : OptionInfo(option) {} /******************************************************************** * IntegerOption */ -AbstractOptionStorage * -IntegerOption::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* IntegerOption::createStorage(const OptionManagerContainer& /*managers*/) const { return new IntegerOptionStorage(*this); } @@ -222,12 +214,12 @@ IntegerOption::createStorage(const OptionManagerContainer & /*managers*/) const * Int64OptionStorage */ -std::string Int64OptionStorage::formatSingleValue(const int64_t &value) const +std::string Int64OptionStorage::formatSingleValue(const int64_t& value) const { return toString(value); } -void Int64OptionStorage::initConverter(ConverterType *converter) +void Int64OptionStorage::initConverter(ConverterType* converter) { converter->addConverter(&fromStdString); } @@ -236,17 +228,13 @@ void Int64OptionStorage::initConverter(ConverterType *converter) * Int64OptionInfo */ -Int64OptionInfo::Int64OptionInfo(Int64OptionStorage *option) - : OptionInfo(option) -{ -} +Int64OptionInfo::Int64OptionInfo(Int64OptionStorage* option) : OptionInfo(option) {} /******************************************************************** * Int64Option */ -AbstractOptionStorage * -Int64Option::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* Int64Option::createStorage(const OptionManagerContainer& /*managers*/) const { return new Int64OptionStorage(*this); } @@ -256,8 +244,11 @@ Int64Option::createStorage(const OptionManagerContainer & /*managers*/) const * DoubleOptionStorage */ -DoubleOptionStorage::DoubleOptionStorage(const DoubleOption &settings) - : MyBase(settings), info_(this), bTime_(settings.bTime_), factor_(1.0) +DoubleOptionStorage::DoubleOptionStorage(const DoubleOption& settings) : + MyBase(settings), + info_(this), + bTime_(settings.bTime_), + factor_(1.0) { } @@ -266,24 +257,24 @@ std::string DoubleOptionStorage::typeString() const return isVector() ? "vector" : (isTime() ? "time" : "real"); } -std::string DoubleOptionStorage::formatSingleValue(const double &value) const +std::string DoubleOptionStorage::formatSingleValue(const double& value) const { return toString(value / factor_); } -void DoubleOptionStorage::initConverter(ConverterType *converter) +void DoubleOptionStorage::initConverter(ConverterType* converter) { converter->addConverter(&fromStdString); converter->addCastConversion(); } -double DoubleOptionStorage::processValue(const double &value) const +double DoubleOptionStorage::processValue(const double& value) const { // TODO: Consider testing for overflow when scaling with factor_. return value * factor_; } -void DoubleOptionStorage::processSetValues(ValueList *values) +void DoubleOptionStorage::processSetValues(ValueList* values) { if (isVector()) { @@ -297,7 +288,7 @@ void DoubleOptionStorage::setScaleFactor(double factor) if (!hasFlag(efOption_HasDefaultValue)) { double scale = factor / factor_; - for (double &value : values()) + for (double& value : values()) { value *= scale; } @@ -309,19 +300,16 @@ void DoubleOptionStorage::setScaleFactor(double factor) * DoubleOptionInfo */ -DoubleOptionInfo::DoubleOptionInfo(DoubleOptionStorage *option) - : OptionInfo(option) -{ -} +DoubleOptionInfo::DoubleOptionInfo(DoubleOptionStorage* option) : OptionInfo(option) {} -DoubleOptionStorage &DoubleOptionInfo::option() +DoubleOptionStorage& DoubleOptionInfo::option() { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } -const DoubleOptionStorage &DoubleOptionInfo::option() const +const DoubleOptionStorage& DoubleOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } bool DoubleOptionInfo::isTime() const @@ -338,8 +326,7 @@ void DoubleOptionInfo::setScaleFactor(double factor) * DoubleOption */ -AbstractOptionStorage * -DoubleOption::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* DoubleOption::createStorage(const OptionManagerContainer& /*managers*/) const { return new DoubleOptionStorage(*this); } @@ -349,8 +336,11 @@ DoubleOption::createStorage(const OptionManagerContainer & /*managers*/) const * FloatOptionStorage */ -FloatOptionStorage::FloatOptionStorage(const FloatOption &settings) - : MyBase(settings), info_(this), bTime_(settings.bTime_), factor_(1.0) +FloatOptionStorage::FloatOptionStorage(const FloatOption& settings) : + MyBase(settings), + info_(this), + bTime_(settings.bTime_), + factor_(1.0) { } @@ -359,24 +349,24 @@ std::string FloatOptionStorage::typeString() const return isVector() ? "vector" : (isTime() ? "time" : "real"); } -std::string FloatOptionStorage::formatSingleValue(const float &value) const +std::string FloatOptionStorage::formatSingleValue(const float& value) const { return toString(value / factor_); } -void FloatOptionStorage::initConverter(ConverterType *converter) +void FloatOptionStorage::initConverter(ConverterType* converter) { converter->addConverter(&fromStdString); converter->addCastConversion(); } -float FloatOptionStorage::processValue(const float &value) const +float FloatOptionStorage::processValue(const float& value) const { // TODO: Consider testing for overflow when scaling with factor_. return value * factor_; } -void FloatOptionStorage::processSetValues(ValueList *values) +void FloatOptionStorage::processSetValues(ValueList* values) { if (isVector()) { @@ -390,7 +380,7 @@ void FloatOptionStorage::setScaleFactor(double factor) if (!hasFlag(efOption_HasDefaultValue)) { float scale = factor / factor_; - for (float &value : values()) + for (float& value : values()) { value *= scale; } @@ -402,19 +392,16 @@ void FloatOptionStorage::setScaleFactor(double factor) * FloatOptionInfo */ -FloatOptionInfo::FloatOptionInfo(FloatOptionStorage *option) - : OptionInfo(option) -{ -} +FloatOptionInfo::FloatOptionInfo(FloatOptionStorage* option) : OptionInfo(option) {} -FloatOptionStorage &FloatOptionInfo::option() +FloatOptionStorage& FloatOptionInfo::option() { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } -const FloatOptionStorage &FloatOptionInfo::option() const +const FloatOptionStorage& FloatOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } bool FloatOptionInfo::isTime() const @@ -431,8 +418,7 @@ void FloatOptionInfo::setScaleFactor(double factor) * FloatOption */ -AbstractOptionStorage * -FloatOption::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* FloatOption::createStorage(const OptionManagerContainer& /*managers*/) const { return new FloatOptionStorage(*this); } @@ -442,8 +428,9 @@ FloatOption::createStorage(const OptionManagerContainer & /*managers*/) const * StringOptionStorage */ -StringOptionStorage::StringOptionStorage(const StringOption &settings) - : MyBase(settings), info_(this) +StringOptionStorage::StringOptionStorage(const StringOption& settings) : + MyBase(settings), + info_(this) { if (settings.defaultEnumIndex_ >= 0 && settings.enumValues_ == nullptr) { @@ -474,7 +461,7 @@ StringOptionStorage::StringOptionStorage(const StringOption &settings) { GMX_THROW(APIError("Default enumeration index is out of range")); } - const std::string *defaultValue = settings.defaultValue(); + const std::string* defaultValue = settings.defaultValue(); if (defaultValue != nullptr && *defaultValue != allowed_[settings.defaultEnumIndex_]) { GMX_THROW(APIError("Conflicting default values")); @@ -495,16 +482,14 @@ std::string StringOptionStorage::formatExtraDescription() const return result; } -std::string StringOptionStorage::formatSingleValue(const std::string &value) const +std::string StringOptionStorage::formatSingleValue(const std::string& value) const { return value; } -void StringOptionStorage::initConverter(ConverterType * /*converter*/) -{ -} +void StringOptionStorage::initConverter(ConverterType* /*converter*/) {} -std::string StringOptionStorage::processValue(const std::string &value) const +std::string StringOptionStorage::processValue(const std::string& value) const { if (!allowed_.empty()) { @@ -517,14 +502,11 @@ std::string StringOptionStorage::processValue(const std::string &value) const * StringOptionInfo */ -StringOptionInfo::StringOptionInfo(StringOptionStorage *option) - : OptionInfo(option) -{ -} +StringOptionInfo::StringOptionInfo(StringOptionStorage* option) : OptionInfo(option) {} -const StringOptionStorage &StringOptionInfo::option() const +const StringOptionStorage& StringOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } bool StringOptionInfo::isEnumerated() const @@ -532,7 +514,7 @@ bool StringOptionInfo::isEnumerated() const return !allowedValues().empty(); } -const std::vector &StringOptionInfo::allowedValues() const +const std::vector& StringOptionInfo::allowedValues() const { return option().allowedValues(); } @@ -541,8 +523,7 @@ const std::vector &StringOptionInfo::allowedValues() const * StringOption */ -AbstractOptionStorage * -StringOption::createStorage(const OptionManagerContainer & /*managers*/) const +AbstractOptionStorage* StringOption::createStorage(const OptionManagerContainer& /*managers*/) const { return new StringOptionStorage(*this); } @@ -552,11 +533,14 @@ StringOption::createStorage(const OptionManagerContainer & /*managers*/) const * EnumOptionStorage */ -EnumOptionStorage::EnumOptionStorage(const AbstractOption &settings, - const char *const *enumValues, int count, - int defaultValue, int defaultValueIfSet, - StorePointer store) - : MyBase(settings, std::move(store)), info_(this) +EnumOptionStorage::EnumOptionStorage(const AbstractOption& settings, + const char* const* enumValues, + int count, + int defaultValue, + int defaultValueIfSet, + StorePointer store) : + MyBase(settings, std::move(store)), + info_(this) { if (enumValues == nullptr) { @@ -601,7 +585,7 @@ std::string EnumOptionStorage::formatExtraDescription() const return result; } -std::string EnumOptionStorage::formatSingleValue(const int &value) const +std::string EnumOptionStorage::formatSingleValue(const int& value) const { if (value < 0 || value >= ssize(allowed_)) { @@ -610,35 +594,30 @@ std::string EnumOptionStorage::formatSingleValue(const int &value) const return allowed_[value]; } -Any EnumOptionStorage::normalizeValue(const int &value) const +Any EnumOptionStorage::normalizeValue(const int& value) const { return Any::create(formatSingleValue(value)); } -void EnumOptionStorage::initConverter(ConverterType *converter) +void EnumOptionStorage::initConverter(ConverterType* converter) { - converter->addConverter( - [this] (const std::string &value) - { - return findEnumValue(this->allowed_, value) - this->allowed_.begin(); - }); + converter->addConverter([this](const std::string& value) { + return findEnumValue(this->allowed_, value) - this->allowed_.begin(); + }); } /******************************************************************** * EnumOptionInfo */ -EnumOptionInfo::EnumOptionInfo(EnumOptionStorage *option) - : OptionInfo(option) -{ -} +EnumOptionInfo::EnumOptionInfo(EnumOptionStorage* option) : OptionInfo(option) {} -const EnumOptionStorage &EnumOptionInfo::option() const +const EnumOptionStorage& EnumOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } -const std::vector &EnumOptionInfo::allowedValues() const +const std::vector& EnumOptionInfo::allowedValues() const { return option().allowedValues(); } @@ -651,14 +630,14 @@ namespace internal { //! \cond internal -AbstractOptionStorage * -createEnumOptionStorage(const AbstractOption &option, - const char *const *enumValues, int count, - int defaultValue, int defaultValueIfSet, - std::unique_ptr > store) -{ - return new EnumOptionStorage(option, enumValues, count, defaultValue, - defaultValueIfSet, move(store)); +AbstractOptionStorage* createEnumOptionStorage(const AbstractOption& option, + const char* const* enumValues, + int count, + int defaultValue, + int defaultValueIfSet, + std::unique_ptr> store) +{ + return new EnumOptionStorage(option, enumValues, count, defaultValue, defaultValueIfSet, move(store)); } //! \endcond diff --git a/src/gromacs/options/basicoptions.h b/src/gromacs/options/basicoptions.h index ef78abacba..75d8e2d454 100644 --- a/src/gromacs/options/basicoptions.h +++ b/src/gromacs/options/basicoptions.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -94,17 +95,16 @@ class EnumOptionStorage; */ class BooleanOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef BooleanOptionInfo InfoType; +public: + //! OptionInfo subclass corresponding to this option type. + typedef BooleanOptionInfo InfoType; - //! Initializes an option with the given name. - explicit BooleanOption(const char *name) : MyBase(name) {} + //! Initializes an option with the given name. + explicit BooleanOption(const char* name) : MyBase(name) {} - private: - //! Creates a BooleanOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; +private: + //! Creates a BooleanOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; }; /*! \brief @@ -127,33 +127,36 @@ class BooleanOption : public OptionTemplate */ class IntegerOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef IntegerOptionInfo InfoType; - - //! Initializes an option with the given name. - explicit IntegerOption(const char *name) : MyBase(name) {} - - /*! \brief - * Sets the option to return a vector value. - * - * A vector value returns a fixed number of values, the default being - * three (can be changed with valueCount()). However, it also accepts - * a single value, in which case the value is used to fill the whole - * vector. - */ - MyClass &vector() { setVector(); return me(); } - - private: - //! Creates an IntegerOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; - - /*! \brief - * Needed to initialize IntegerOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class IntegerOptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef IntegerOptionInfo InfoType; + + //! Initializes an option with the given name. + explicit IntegerOption(const char* name) : MyBase(name) {} + + /*! \brief + * Sets the option to return a vector value. + * + * A vector value returns a fixed number of values, the default being + * three (can be changed with valueCount()). However, it also accepts + * a single value, in which case the value is used to fill the whole + * vector. + */ + MyClass& vector() + { + setVector(); + return me(); + } + +private: + //! Creates an IntegerOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; + + /*! \brief + * Needed to initialize IntegerOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class IntegerOptionStorage; }; /*! \brief @@ -167,23 +170,22 @@ class IntegerOption : public OptionTemplate */ class Int64Option : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef Int64OptionInfo InfoType; - - //! Initializes an option with the given name. - explicit Int64Option(const char *name) : MyBase(name) {} - - private: - //! Creates an Int64OptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; - - /*! \brief - * Needed to initialize Int64OptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class Int64OptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef Int64OptionInfo InfoType; + + //! Initializes an option with the given name. + explicit Int64Option(const char* name) : MyBase(name) {} + +private: + //! Creates an Int64OptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; + + /*! \brief + * Needed to initialize Int64OptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class Int64OptionStorage; }; /*! \brief @@ -195,43 +197,48 @@ class Int64Option : public OptionTemplate */ class DoubleOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef DoubleOptionInfo InfoType; - - //! Initializes an option with the given name. - explicit DoubleOption(const char *name) : MyBase(name), bTime_(false) - { - } - - //! \copydoc IntegerOption::vector() - MyClass &vector() { setVector(); return me(); } - /*! \brief - * Marks this option as providing a time value whose unit can be changed. - * - * By itself, this option does nothing. It marks the option as a time - * value such that TimeUnitManager::scaleTimeOptions() can process it. - * In typical cases, \Gromacs scales the time options just before - * Options::finish() has been called, so the option value is only - * available after all option values have been processed. - * All values in the program are in ps (including any default value); - * user-provided values are scaled according to the time unit set in - * TimeUnitManager. - */ - MyClass &timeValue() { bTime_ = true; return me(); } - - private: - //! Creates a DoubleOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; - - bool bTime_; - - /*! \brief - * Needed to initialize DoubleOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class DoubleOptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef DoubleOptionInfo InfoType; + + //! Initializes an option with the given name. + explicit DoubleOption(const char* name) : MyBase(name), bTime_(false) {} + + //! \copydoc IntegerOption::vector() + MyClass& vector() + { + setVector(); + return me(); + } + /*! \brief + * Marks this option as providing a time value whose unit can be changed. + * + * By itself, this option does nothing. It marks the option as a time + * value such that TimeUnitManager::scaleTimeOptions() can process it. + * In typical cases, \Gromacs scales the time options just before + * Options::finish() has been called, so the option value is only + * available after all option values have been processed. + * All values in the program are in ps (including any default value); + * user-provided values are scaled according to the time unit set in + * TimeUnitManager. + */ + MyClass& timeValue() + { + bTime_ = true; + return me(); + } + +private: + //! Creates a DoubleOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; + + bool bTime_; + + /*! \brief + * Needed to initialize DoubleOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class DoubleOptionStorage; }; /*! \brief @@ -245,32 +252,37 @@ class DoubleOption : public OptionTemplate */ class FloatOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef FloatOptionInfo InfoType; - - //! Initializes an option with the given name. - explicit FloatOption(const char *name) : MyBase(name), bTime_(false) - { - } - - //! \copydoc IntegerOption::vector() - MyClass &vector() { setVector(); return me(); } - //! \copydoc DoubleOption::timeValue() - MyClass &timeValue() { bTime_ = true; return me(); } - - private: - //! Creates a FloatOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; - - bool bTime_; - - /*! \brief - * Needed to initialize FloatOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class FloatOptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef FloatOptionInfo InfoType; + + //! Initializes an option with the given name. + explicit FloatOption(const char* name) : MyBase(name), bTime_(false) {} + + //! \copydoc IntegerOption::vector() + MyClass& vector() + { + setVector(); + return me(); + } + //! \copydoc DoubleOption::timeValue() + MyClass& timeValue() + { + bTime_ = true; + return me(); + } + +private: + //! Creates a FloatOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; + + bool bTime_; + + /*! \brief + * Needed to initialize FloatOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class FloatOptionStorage; }; /*! \brief @@ -294,83 +306,82 @@ class FloatOption : public OptionTemplate */ class StringOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef StringOptionInfo InfoType; - - //! Initializes an option with the given name. - explicit StringOption(const char *name) - : MyBase(name), enumValues_(nullptr), enumValuesCount_(0), - defaultEnumIndex_(-1) - { - } - - /*! \brief - * Sets the option to only accept one of a fixed set of strings. - * - * \param[in] values Array of strings to accept. - * - * Also accepts prefixes of the strings; if a prefix matches more than - * one of the possible strings, the shortest one is used (in a tie, the - * first one is). - * - * The strings are copied once the option is created. - */ - template - MyClass &enumValue(const char *const (&values)[count]) - { - GMX_ASSERT(enumValues_ == nullptr, - "Multiple sets of enumerated values specified"); - enumValues_ = values; - enumValuesCount_ = count; - return me(); - } - /*! \brief - * Sets the option to only accept one of a fixed set of strings. - * - * \param[in] values Array of strings to accept, with a NULL pointer - * following the last string. - * - * Works otherwise as the array version, but accepts a pointer to - * an array of undetermined length. The end of the array is indicated - * by a NULL pointer in the array. - * - * \see enumValue() - */ - MyClass &enumValueFromNullTerminatedArray(const char *const *values) - { - GMX_ASSERT(enumValues_ == nullptr, - "Multiple sets of enumerated values specified"); - enumValues_ = values; - enumValuesCount_ = -1; - return me(); - } - /*! \brief - * Sets the default value using an index into the enumeration table. - * - * Cannot be specified without enumValue(). - */ - MyClass &defaultEnumIndex(int index) - { - GMX_ASSERT(index >= 0, "Invalid enumeration index"); - defaultEnumIndex_ = index; - return me(); - } - - private: - //! Creates a StringOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; - - const char *const *enumValues_; - int enumValuesCount_; - int defaultEnumIndex_; - - /*! \brief - * Needed to initialize StringOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class StringOptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef StringOptionInfo InfoType; + + //! Initializes an option with the given name. + explicit StringOption(const char* name) : + MyBase(name), + enumValues_(nullptr), + enumValuesCount_(0), + defaultEnumIndex_(-1) + { + } + + /*! \brief + * Sets the option to only accept one of a fixed set of strings. + * + * \param[in] values Array of strings to accept. + * + * Also accepts prefixes of the strings; if a prefix matches more than + * one of the possible strings, the shortest one is used (in a tie, the + * first one is). + * + * The strings are copied once the option is created. + */ + template + MyClass& enumValue(const char* const (&values)[count]) + { + GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified"); + enumValues_ = values; + enumValuesCount_ = count; + return me(); + } + /*! \brief + * Sets the option to only accept one of a fixed set of strings. + * + * \param[in] values Array of strings to accept, with a NULL pointer + * following the last string. + * + * Works otherwise as the array version, but accepts a pointer to + * an array of undetermined length. The end of the array is indicated + * by a NULL pointer in the array. + * + * \see enumValue() + */ + MyClass& enumValueFromNullTerminatedArray(const char* const* values) + { + GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified"); + enumValues_ = values; + enumValuesCount_ = -1; + return me(); + } + /*! \brief + * Sets the default value using an index into the enumeration table. + * + * Cannot be specified without enumValue(). + */ + MyClass& defaultEnumIndex(int index) + { + GMX_ASSERT(index >= 0, "Invalid enumeration index"); + defaultEnumIndex_ = index; + return me(); + } + +private: + //! Creates a StringOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; + + const char* const* enumValues_; + int enumValuesCount_; + int defaultEnumIndex_; + + /*! \brief + * Needed to initialize StringOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class StringOptionStorage; }; //! \} @@ -389,65 +400,66 @@ namespace internal * * \ingroup module_options */ -template +template class EnumIndexStore : public IOptionValueStore { - public: - //! Initializes the storage for the given actual enum variables. - EnumIndexStore(EnumType *store, std::vector *storeVector) - : store_(store), storeVector_(storeVector) +public: + //! Initializes the storage for the given actual enum variables. + EnumIndexStore(EnumType* store, std::vector* storeVector) : + store_(store), + storeVector_(storeVector) + { + if (storeVector_ != nullptr) { - if (storeVector_ != nullptr) - { - for (EnumType value : *storeVector_) - { - intStore_.push_back(static_cast(value)); - } - } - else if (store_ != nullptr) + for (EnumType value : *storeVector_) { - // TODO: Copy more than one value if that would make sense. - intStore_.push_back(static_cast(store_[0])); + intStore_.push_back(static_cast(value)); } } - - int valueCount() override { return ssize(intStore_); } - ArrayRef values() override { return intStore_; } - void clear() override + else if (store_ != nullptr) { - intStore_.clear(); - if (storeVector_ != nullptr) - { - storeVector_->clear(); - } + // TODO: Copy more than one value if that would make sense. + intStore_.push_back(static_cast(store_[0])); } - void reserve(size_t count) override + } + + int valueCount() override { return ssize(intStore_); } + ArrayRef values() override { return intStore_; } + void clear() override + { + intStore_.clear(); + if (storeVector_ != nullptr) { - intStore_.reserve(intStore_.size() + count); - if (storeVector_ != nullptr) - { - storeVector_->reserve(storeVector_->size() + count); - } + storeVector_->clear(); } - void append(const int &value) override + } + void reserve(size_t count) override + { + intStore_.reserve(intStore_.size() + count); + if (storeVector_ != nullptr) { - const size_t count = intStore_.size(); - intStore_.push_back(value); - if (store_ != nullptr) - { - store_[count] = static_cast(value); - } - if (storeVector_ != nullptr) - { - storeVector_->push_back(static_cast(value)); - } + storeVector_->reserve(storeVector_->size() + count); } + } + void append(const int& value) override + { + const size_t count = intStore_.size(); + intStore_.push_back(value); + if (store_ != nullptr) + { + store_[count] = static_cast(value); + } + if (storeVector_ != nullptr) + { + storeVector_->push_back(static_cast(value)); + } + } - private: - //! Stores the integer values for values(). - std::vector intStore_; - EnumType *store_; - std::vector *storeVector_; +private: + //! Stores the integer values for values(). + std::vector intStore_; + EnumType* store_; + std::vector* storeVector_; }; //! \cond internal @@ -461,14 +473,15 @@ class EnumIndexStore : public IOptionValueStore * * \ingroup module_options */ -AbstractOptionStorage * -createEnumOptionStorage(const AbstractOption &option, - const char *const *enumValues, int count, - int defaultValue, int defaultValueIfSet, - std::unique_ptr > store); +AbstractOptionStorage* createEnumOptionStorage(const AbstractOption& option, + const char* const* enumValues, + int count, + int defaultValue, + int defaultValueIfSet, + std::unique_ptr> store); //! \endcond -} // namespace internal +} // namespace internal //! \addtogroup module_options //! \{ @@ -503,93 +516,88 @@ createEnumOptionStorage(const AbstractOption &option, * * \inpublicapi */ -template -class EnumOption : public OptionTemplate > +template +class EnumOption : public OptionTemplate> { - public: - //! OptionInfo subclass corresponding to this option type. - typedef EnumOptionInfo InfoType; - - // This needs to be duplicated from OptionTemplate because this class - // is a template. - //! Short-hand for the base class. - typedef OptionTemplate > MyBase; - - //! Initializes an option with the given name. - explicit EnumOption(const char *name) - : MyBase(name), enumValues_(nullptr), enumValuesCount_(0) - { - } - - /*! \brief - * Sets the option to only accept one of a fixed set of strings. - * - * \param[in] values Array of strings to accept. - * - * Also accepts prefixes of the strings; if a prefix matches more than - * one of the possible strings, the shortest one is used (in a tie, the - * first one is). - * - * The strings are copied once the option is created. - */ - template - EnumOption &enumValue(const char *const (&values)[count]) - { - GMX_ASSERT(enumValues_ == nullptr, - "Multiple sets of enumerated values specified"); - enumValues_ = values; - enumValuesCount_ = count; - return MyBase::me(); - } - /*! \brief - * Sets the option to only accept one of a fixed set of strings. - * - * \param[in] values Array of strings to accept, with a NULL pointer - * following the last string. - * - * Works otherwise as the array version, but accepts a pointer to - * an array of undetermined length. The end of the array is indicated - * by a NULL pointer in the array. - * - * \see enumValue() - */ - EnumOption &enumValueFromNullTerminatedArray(const char *const *values) - { - GMX_ASSERT(enumValues_ == nullptr, - "Multiple sets of enumerated values specified"); - enumValues_ = values; - enumValuesCount_ = -1; - return MyBase::me(); - } - - private: - //! Helper function to convert default values for storate initialization. - static int convertToInt(const EnumType *defaultValue) - { - return defaultValue != nullptr ? static_cast(*defaultValue) : -1; - } - - //! Creates a EnumOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer & /*managers*/) const override - { - // TODO: Implement storeCount() if necessary. - return internal::createEnumOptionStorage( - *this, enumValues_, enumValuesCount_, - convertToInt(MyBase::defaultValue()), - convertToInt(MyBase::defaultValueIfSet()), - std::make_unique >( - MyBase::store(), MyBase::storeVector())); - } - - const char *const *enumValues_; - int enumValuesCount_; - - /*! \brief - * Needed to initialize EnumOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class EnumOptionStorage; +public: + //! OptionInfo subclass corresponding to this option type. + typedef EnumOptionInfo InfoType; + + // This needs to be duplicated from OptionTemplate because this class + // is a template. + //! Short-hand for the base class. + typedef OptionTemplate> MyBase; + + //! Initializes an option with the given name. + explicit EnumOption(const char* name) : MyBase(name), enumValues_(nullptr), enumValuesCount_(0) + { + } + + /*! \brief + * Sets the option to only accept one of a fixed set of strings. + * + * \param[in] values Array of strings to accept. + * + * Also accepts prefixes of the strings; if a prefix matches more than + * one of the possible strings, the shortest one is used (in a tie, the + * first one is). + * + * The strings are copied once the option is created. + */ + template + EnumOption& enumValue(const char* const (&values)[count]) + { + GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified"); + enumValues_ = values; + enumValuesCount_ = count; + return MyBase::me(); + } + /*! \brief + * Sets the option to only accept one of a fixed set of strings. + * + * \param[in] values Array of strings to accept, with a NULL pointer + * following the last string. + * + * Works otherwise as the array version, but accepts a pointer to + * an array of undetermined length. The end of the array is indicated + * by a NULL pointer in the array. + * + * \see enumValue() + */ + EnumOption& enumValueFromNullTerminatedArray(const char* const* values) + { + GMX_ASSERT(enumValues_ == nullptr, "Multiple sets of enumerated values specified"); + enumValues_ = values; + enumValuesCount_ = -1; + return MyBase::me(); + } + +private: + //! Helper function to convert default values for storate initialization. + static int convertToInt(const EnumType* defaultValue) + { + return defaultValue != nullptr ? static_cast(*defaultValue) : -1; + } + + //! Creates a EnumOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& /*managers*/) const override + { + // TODO: Implement storeCount() if necessary. + return internal::createEnumOptionStorage(*this, enumValues_, enumValuesCount_, + convertToInt(MyBase::defaultValue()), + convertToInt(MyBase::defaultValueIfSet()), + std::make_unique>( + MyBase::store(), MyBase::storeVector())); + } + + const char* const* enumValues_; + int enumValuesCount_; + + /*! \brief + * Needed to initialize EnumOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class EnumOptionStorage; }; //! Shorthand for an enumerated option that stores into an `int` variable. @@ -602,15 +610,15 @@ typedef EnumOption EnumIntOption; */ class BooleanOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit BooleanOptionInfo(BooleanOptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit BooleanOptionInfo(BooleanOptionStorage* option); - //! Returns the default value for this option. - bool defaultValue() const; + //! Returns the default value for this option. + bool defaultValue() const; - private: - const BooleanOptionStorage &option() const; +private: + const BooleanOptionStorage& option() const; }; /*! \brief @@ -620,9 +628,9 @@ class BooleanOptionInfo : public OptionInfo */ class IntegerOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit IntegerOptionInfo(IntegerOptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit IntegerOptionInfo(IntegerOptionStorage* option); }; /*! \brief @@ -632,9 +640,9 @@ class IntegerOptionInfo : public OptionInfo */ class Int64OptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit Int64OptionInfo(Int64OptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit Int64OptionInfo(Int64OptionStorage* option); }; /*! \brief @@ -644,26 +652,26 @@ class Int64OptionInfo : public OptionInfo */ class DoubleOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit DoubleOptionInfo(DoubleOptionStorage *option); - - //! Whether the option specifies a time value. - bool isTime() const; - - /*! \brief - * Sets a scale factor for user-provided values. - * - * Any user-provided value is scaled by the provided factor. - * Programmatically set default values are not scaled. - * If called multiple times, later calls override the previously set - * value. In other words, the scaling is not cumulative. - */ - void setScaleFactor(double factor); - - private: - DoubleOptionStorage &option(); - const DoubleOptionStorage &option() const; +public: + //! Creates an option info object for the given option. + explicit DoubleOptionInfo(DoubleOptionStorage* option); + + //! Whether the option specifies a time value. + bool isTime() const; + + /*! \brief + * Sets a scale factor for user-provided values. + * + * Any user-provided value is scaled by the provided factor. + * Programmatically set default values are not scaled. + * If called multiple times, later calls override the previously set + * value. In other words, the scaling is not cumulative. + */ + void setScaleFactor(double factor); + +private: + DoubleOptionStorage& option(); + const DoubleOptionStorage& option() const; }; /*! \brief @@ -673,19 +681,19 @@ class DoubleOptionInfo : public OptionInfo */ class FloatOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit FloatOptionInfo(FloatOptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit FloatOptionInfo(FloatOptionStorage* option); - //! Whether the option specifies a time value. - bool isTime() const; + //! Whether the option specifies a time value. + bool isTime() const; - //! \copydoc DoubleOptionInfo::setScaleFactor() - void setScaleFactor(double factor); + //! \copydoc DoubleOptionInfo::setScaleFactor() + void setScaleFactor(double factor); - private: - FloatOptionStorage &option(); - const FloatOptionStorage &option() const; +private: + FloatOptionStorage& option(); + const FloatOptionStorage& option() const; }; /*! \brief @@ -695,26 +703,26 @@ class FloatOptionInfo : public OptionInfo */ class StringOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit StringOptionInfo(StringOptionStorage *option); - - /*! \brief - * Whether this option accepts an enumerated set of values. - * - * Returns true if StringOption::enumValues() was used when creating - * this option. - */ - bool isEnumerated() const; - /*! \brief - * Returns the set of allowed values for this option. - * - * Returns an empty vector if isEnumerated() returns false. - */ - const std::vector &allowedValues() const; - - private: - const StringOptionStorage &option() const; +public: + //! Creates an option info object for the given option. + explicit StringOptionInfo(StringOptionStorage* option); + + /*! \brief + * Whether this option accepts an enumerated set of values. + * + * Returns true if StringOption::enumValues() was used when creating + * this option. + */ + bool isEnumerated() const; + /*! \brief + * Returns the set of allowed values for this option. + * + * Returns an empty vector if isEnumerated() returns false. + */ + const std::vector& allowedValues() const; + +private: + const StringOptionStorage& option() const; }; /*! \brief @@ -724,17 +732,17 @@ class StringOptionInfo : public OptionInfo */ class EnumOptionInfo : public OptionInfo { - public: - //! Creates an option info object for the given option. - explicit EnumOptionInfo(EnumOptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit EnumOptionInfo(EnumOptionStorage* option); - /*! \brief - * Returns the set of allowed values for this option. - */ - const std::vector &allowedValues() const; + /*! \brief + * Returns the set of allowed values for this option. + */ + const std::vector& allowedValues() const; - private: - const EnumOptionStorage &option() const; +private: + const EnumOptionStorage& option() const; }; /*! \typedef RealOption @@ -755,8 +763,8 @@ class EnumOptionInfo : public OptionInfo typedef DoubleOption RealOption; typedef DoubleOptionInfo RealOptionInfo; #else -typedef FloatOption RealOption; -typedef FloatOptionInfo RealOptionInfo; +typedef FloatOption RealOption; +typedef FloatOptionInfo RealOptionInfo; #endif //! \} diff --git a/src/gromacs/options/basicoptionstorage.h b/src/gromacs/options/basicoptionstorage.h index b1dfb5781e..8c0df59732 100644 --- a/src/gromacs/options/basicoptionstorage.h +++ b/src/gromacs/options/basicoptionstorage.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,28 +62,25 @@ namespace gmx */ class BooleanOptionStorage : public OptionStorageTemplateSimple { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Storage settings. - */ - explicit BooleanOptionStorage(const BooleanOption &settings) - : MyBase(settings), info_(this) - { - } - - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override { return "bool"; } - std::string formatSingleValue(const bool &value) const override; - - //! \copydoc BooleanOptionInfo::defaultValue() - bool defaultValue() const { return valueCount() > 0 && values()[0]; } - - private: - void initConverter(ConverterType *converter) override; - - BooleanOptionInfo info_; +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Storage settings. + */ + explicit BooleanOptionStorage(const BooleanOption& settings) : MyBase(settings), info_(this) {} + + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return "bool"; } + std::string formatSingleValue(const bool& value) const override; + + //! \copydoc BooleanOptionInfo::defaultValue() + bool defaultValue() const { return valueCount() > 0 && values()[0]; } + +private: + void initConverter(ConverterType* converter) override; + + BooleanOptionInfo info_; }; /*! \internal \brief @@ -90,23 +88,19 @@ class BooleanOptionStorage : public OptionStorageTemplateSimple */ class IntegerOptionStorage : public OptionStorageTemplateSimple { - public: - //! \copydoc BooleanOptionStorage::BooleanOptionStorage() - explicit IntegerOptionStorage(const IntegerOption &settings) - : MyBase(settings), info_(this) - { - } - - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override - { return isVector() ? "vector" : "int"; } - std::string formatSingleValue(const int &value) const override; - - private: - void initConverter(ConverterType *converter) override; - void processSetValues(ValueList *values) override; - - IntegerOptionInfo info_; +public: + //! \copydoc BooleanOptionStorage::BooleanOptionStorage() + explicit IntegerOptionStorage(const IntegerOption& settings) : MyBase(settings), info_(this) {} + + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return isVector() ? "vector" : "int"; } + std::string formatSingleValue(const int& value) const override; + +private: + void initConverter(ConverterType* converter) override; + void processSetValues(ValueList* values) override; + + IntegerOptionInfo info_; }; /*! \internal \brief @@ -114,21 +108,18 @@ class IntegerOptionStorage : public OptionStorageTemplateSimple */ class Int64OptionStorage : public OptionStorageTemplateSimple { - public: - //! \copydoc BooleanOptionStorage::BooleanOptionStorage() - explicit Int64OptionStorage(const Int64Option &settings) - : MyBase(settings), info_(this) - { - } +public: + //! \copydoc BooleanOptionStorage::BooleanOptionStorage() + explicit Int64OptionStorage(const Int64Option& settings) : MyBase(settings), info_(this) {} - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override { return "int"; } - std::string formatSingleValue(const int64_t &value) const override; + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return "int"; } + std::string formatSingleValue(const int64_t& value) const override; - private: - void initConverter(ConverterType *converter) override; +private: + void initConverter(ConverterType* converter) override; - Int64OptionInfo info_; + Int64OptionInfo info_; }; /*! \internal \brief @@ -136,27 +127,27 @@ class Int64OptionStorage : public OptionStorageTemplateSimple */ class DoubleOptionStorage : public OptionStorageTemplateSimple { - public: - //! \copydoc IntegerOptionStorage::IntegerOptionStorage() - explicit DoubleOptionStorage(const DoubleOption &settings); - - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override; - std::string formatSingleValue(const double &value) const override; - - //! \copydoc DoubleOptionInfo::isTime() - bool isTime() const { return bTime_; } - //! \copydoc DoubleOptionInfo::setScaleFactor() - void setScaleFactor(double factor); - - private: - void initConverter(ConverterType *converter) override; - double processValue(const double &value) const override; - void processSetValues(ValueList *values) override; - - DoubleOptionInfo info_; - bool bTime_; - double factor_; +public: + //! \copydoc IntegerOptionStorage::IntegerOptionStorage() + explicit DoubleOptionStorage(const DoubleOption& settings); + + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override; + std::string formatSingleValue(const double& value) const override; + + //! \copydoc DoubleOptionInfo::isTime() + bool isTime() const { return bTime_; } + //! \copydoc DoubleOptionInfo::setScaleFactor() + void setScaleFactor(double factor); + +private: + void initConverter(ConverterType* converter) override; + double processValue(const double& value) const override; + void processSetValues(ValueList* values) override; + + DoubleOptionInfo info_; + bool bTime_; + double factor_; }; /*! \internal \brief @@ -164,27 +155,27 @@ class DoubleOptionStorage : public OptionStorageTemplateSimple */ class FloatOptionStorage : public OptionStorageTemplateSimple { - public: - //! \copydoc IntegerOptionStorage::IntegerOptionStorage() - explicit FloatOptionStorage(const FloatOption &settings); - - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override; - std::string formatSingleValue(const float &value) const override; - - //! \copydoc DoubleOptionStorage::isTime() - bool isTime() const { return bTime_; } - //! \copydoc DoubleOptionStorage::setScaleFactor() - void setScaleFactor(double factor); - - private: - void initConverter(ConverterType *converter) override; - float processValue(const float &value) const override; - void processSetValues(ValueList *values) override; - - FloatOptionInfo info_; - bool bTime_; - double factor_; +public: + //! \copydoc IntegerOptionStorage::IntegerOptionStorage() + explicit FloatOptionStorage(const FloatOption& settings); + + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override; + std::string formatSingleValue(const float& value) const override; + + //! \copydoc DoubleOptionStorage::isTime() + bool isTime() const { return bTime_; } + //! \copydoc DoubleOptionStorage::setScaleFactor() + void setScaleFactor(double factor); + +private: + void initConverter(ConverterType* converter) override; + float processValue(const float& value) const override; + void processSetValues(ValueList* values) override; + + FloatOptionInfo info_; + bool bTime_; + double factor_; }; /*! \internal \brief @@ -192,25 +183,24 @@ class FloatOptionStorage : public OptionStorageTemplateSimple */ class StringOptionStorage : public OptionStorageTemplateSimple { - public: - //! \copydoc DoubleOptionStorage::DoubleOptionStorage() - explicit StringOptionStorage(const StringOption &settings); +public: + //! \copydoc DoubleOptionStorage::DoubleOptionStorage() + explicit StringOptionStorage(const StringOption& settings); - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override - { return allowed_.empty() ? "string" : "enum"; } - std::string formatExtraDescription() const override; - std::string formatSingleValue(const std::string &value) const override; + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return allowed_.empty() ? "string" : "enum"; } + std::string formatExtraDescription() const override; + std::string formatSingleValue(const std::string& value) const override; - //! \copydoc StringOptionInfo::allowedValues() - const ValueList &allowedValues() const { return allowed_; } + //! \copydoc StringOptionInfo::allowedValues() + const ValueList& allowedValues() const { return allowed_; } - private: - void initConverter(ConverterType *converter) override; - std::string processValue(const std::string &value) const override; +private: + void initConverter(ConverterType* converter) override; + std::string processValue(const std::string& value) const override; - StringOptionInfo info_; - ValueList allowed_; + StringOptionInfo info_; + ValueList allowed_; }; /*! \internal \brief @@ -218,42 +208,44 @@ class StringOptionStorage : public OptionStorageTemplateSimple */ class EnumOptionStorage : public OptionStorageTemplateSimple { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Basic storage settings. - * \param[in] enumValues Allowed values. - * \param[in] count Number of elements in \p enumValues, - * or -1 if \p enumValues is `NULL`-terminated. - * \param[in] defaultValue Default value, or -1 if no default. - * \param[in] defaultValueIfSet Default value if set, or -1 if none. - * \param[in] store Storage to convert the values to/from `int`. - * - * This constructor takes more parameters than other storage parameters - * because the front-end option type is a template, and as such cannot - * be passed here without exposing also this header as an installed - * header. - */ - EnumOptionStorage(const AbstractOption &settings, - const char *const *enumValues, int count, - int defaultValue, int defaultValueIfSet, - StorePointer store); - - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override { return "enum"; } - std::string formatExtraDescription() const override; - std::string formatSingleValue(const int &value) const override; - Any normalizeValue(const int &value) const override; - - //! \copydoc EnumOptionInfo::allowedValues() - const std::vector &allowedValues() const { return allowed_; } - - private: - void initConverter(ConverterType *converter) override; - - EnumOptionInfo info_; - std::vector allowed_; +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Basic storage settings. + * \param[in] enumValues Allowed values. + * \param[in] count Number of elements in \p enumValues, + * or -1 if \p enumValues is `NULL`-terminated. + * \param[in] defaultValue Default value, or -1 if no default. + * \param[in] defaultValueIfSet Default value if set, or -1 if none. + * \param[in] store Storage to convert the values to/from `int`. + * + * This constructor takes more parameters than other storage parameters + * because the front-end option type is a template, and as such cannot + * be passed here without exposing also this header as an installed + * header. + */ + EnumOptionStorage(const AbstractOption& settings, + const char* const* enumValues, + int count, + int defaultValue, + int defaultValueIfSet, + StorePointer store); + + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return "enum"; } + std::string formatExtraDescription() const override; + std::string formatSingleValue(const int& value) const override; + Any normalizeValue(const int& value) const override; + + //! \copydoc EnumOptionInfo::allowedValues() + const std::vector& allowedValues() const { return allowed_; } + +private: + void initConverter(ConverterType* converter) override; + + EnumOptionInfo info_; + std::vector allowed_; }; /*!\}*/ diff --git a/src/gromacs/options/behaviorcollection.cpp b/src/gromacs/options/behaviorcollection.cpp index 5cf1823796..8297ec5c6d 100644 --- a/src/gromacs/options/behaviorcollection.cpp +++ b/src/gromacs/options/behaviorcollection.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,20 +48,13 @@ namespace gmx { -IOptionsBehavior::~IOptionsBehavior() -{ -} +IOptionsBehavior::~IOptionsBehavior() {} -OptionsBehaviorCollection::OptionsBehaviorCollection(Options *options) - : options_(options) -{ -} +OptionsBehaviorCollection::OptionsBehaviorCollection(Options* options) : options_(options) {} -OptionsBehaviorCollection::~OptionsBehaviorCollection() -{ -} +OptionsBehaviorCollection::~OptionsBehaviorCollection() {} -void OptionsBehaviorCollection::addBehavior(const OptionsBehaviorPointer &behavior) +void OptionsBehaviorCollection::addBehavior(const OptionsBehaviorPointer& behavior) { behaviors_.reserve(behaviors_.size() + 1); behavior->initBehavior(options_); @@ -70,7 +63,7 @@ void OptionsBehaviorCollection::addBehavior(const OptionsBehaviorPointer &behavi void OptionsBehaviorCollection::optionsFinishing() { - for (const OptionsBehaviorPointer &behavior : behaviors_) + for (const OptionsBehaviorPointer& behavior : behaviors_) { behavior->optionsFinishing(options_); } @@ -78,7 +71,7 @@ void OptionsBehaviorCollection::optionsFinishing() void OptionsBehaviorCollection::optionsFinished() { - for (const OptionsBehaviorPointer &behavior : behaviors_) + for (const OptionsBehaviorPointer& behavior : behaviors_) { behavior->optionsFinished(); } diff --git a/src/gromacs/options/behaviorcollection.h b/src/gromacs/options/behaviorcollection.h index 2d22ad0857..204a584bda 100644 --- a/src/gromacs/options/behaviorcollection.h +++ b/src/gromacs/options/behaviorcollection.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,31 +71,31 @@ typedef std::shared_ptr OptionsBehaviorPointer; */ class OptionsBehaviorCollection { - public: - /*! \brief - * Constructs a container for storing behaviors associated with given - * Options. - * - * Caller needs to ensure that provided Options remains in existence - * while the container exists. - */ - explicit OptionsBehaviorCollection(Options *options); - ~OptionsBehaviorCollection(); +public: + /*! \brief + * Constructs a container for storing behaviors associated with given + * Options. + * + * Caller needs to ensure that provided Options remains in existence + * while the container exists. + */ + explicit OptionsBehaviorCollection(Options* options); + ~OptionsBehaviorCollection(); - //! Adds a behavior to the collection. - void addBehavior(const OptionsBehaviorPointer &behavior); - //! Calls IOptionsBehavior::optionsFinishing() on all behaviors. - void optionsFinishing(); - //! Calls IOptionsBehavior::optionsFinished() on all behaviors. - void optionsFinished(); + //! Adds a behavior to the collection. + void addBehavior(const OptionsBehaviorPointer& behavior); + //! Calls IOptionsBehavior::optionsFinishing() on all behaviors. + void optionsFinishing(); + //! Calls IOptionsBehavior::optionsFinished() on all behaviors. + void optionsFinished(); - private: - Options *options_; - std::vector behaviors_; +private: + Options* options_; + std::vector behaviors_; - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsBehaviorCollection); + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsBehaviorCollection); }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/options/filenameoption.cpp b/src/gromacs/options/filenameoption.cpp index 6906029acc..2577549bad 100644 --- a/src/gromacs/options/filenameoption.cpp +++ b/src/gromacs/options/filenameoption.cpp @@ -75,21 +75,14 @@ struct FileTypeMapping //! OptionFileType value to map. OptionFileType optionType; //! Corresponding file type from filetypes.h. - int fileType; + int fileType; }; //! Mappings from OptionFileType to file types in filetypes.h. -const FileTypeMapping c_fileTypeMapping[] = -{ - { eftTopology, efTPS }, - { eftRunInput, efTPR }, - { eftTrajectory, efTRX }, - { eftEnergy, efEDR }, - { eftPDB, efPDB }, - { eftIndex, efNDX }, - { eftPlot, efXVG }, - { eftGenericData, efDAT } -}; +const FileTypeMapping c_fileTypeMapping[] = { { eftTopology, efTPS }, { eftRunInput, efTPR }, + { eftTrajectory, efTRX }, { eftEnergy, efEDR }, + { eftPDB, efPDB }, { eftIndex, efNDX }, + { eftPlot, efXVG }, { eftGenericData, efDAT } }; /******************************************************************** * FileTypeHandler @@ -104,45 +97,47 @@ const FileTypeMapping c_fileTypeMapping[] = */ class FileTypeHandler { - public: - /*! \brief - * Returns a handler for a single file type. - * - * \param[in] fileType File type (from filetypes.h) to use. - */ - explicit FileTypeHandler(int fileType); - - //! Returns the number of acceptable extensions for this file type. - int extensionCount() const; - //! Returns the extension with the given index. - const char *extension(int i) const; - - //! Returns whether \p fileType (from filetypes.h) is accepted for this type. - bool isValidType(int fileType) const; - - private: - /*! \brief - * File type (from filetypes.h) represented by this handler. - * - * -1 represents an unknown file type. - */ - int fileType_; - //! Number of different extensions this type supports. - int extensionCount_; - /*! \brief - * List of simple file types that are included in this type. - * - * If `fileType_` represents a generic type in filetypes.h, i.e., a type - * that accepts multiple different types of files, then this is an - * array of `extensionCount_` elements, each element specifying one - * non-generic file type that this option accepts. - * `NULL` for single-extension types. - */ - const int *genericTypes_; +public: + /*! \brief + * Returns a handler for a single file type. + * + * \param[in] fileType File type (from filetypes.h) to use. + */ + explicit FileTypeHandler(int fileType); + + //! Returns the number of acceptable extensions for this file type. + int extensionCount() const; + //! Returns the extension with the given index. + const char* extension(int i) const; + + //! Returns whether \p fileType (from filetypes.h) is accepted for this type. + bool isValidType(int fileType) const; + +private: + /*! \brief + * File type (from filetypes.h) represented by this handler. + * + * -1 represents an unknown file type. + */ + int fileType_; + //! Number of different extensions this type supports. + int extensionCount_; + /*! \brief + * List of simple file types that are included in this type. + * + * If `fileType_` represents a generic type in filetypes.h, i.e., a type + * that accepts multiple different types of files, then this is an + * array of `extensionCount_` elements, each element specifying one + * non-generic file type that this option accepts. + * `NULL` for single-extension types. + */ + const int* genericTypes_; }; -FileTypeHandler::FileTypeHandler(int fileType) - : fileType_(fileType), extensionCount_(0), genericTypes_(nullptr) +FileTypeHandler::FileTypeHandler(int fileType) : + fileType_(fileType), + extensionCount_(0), + genericTypes_(nullptr) { if (fileType_ >= 0) { @@ -164,7 +159,7 @@ int FileTypeHandler::extensionCount() const return extensionCount_; } -const char *FileTypeHandler::extension(int i) const +const char* FileTypeHandler::extension(int i) const { GMX_ASSERT(i >= 0 && i < extensionCount_, "Invalid extension index"); if (genericTypes_ != nullptr) @@ -174,8 +169,7 @@ const char *FileTypeHandler::extension(int i) const return ftp2ext_with_dot(fileType_); } -bool -FileTypeHandler::isValidType(int fileType) const +bool FileTypeHandler::isValidType(int fileType) const { if (genericTypes_ != nullptr) { @@ -196,17 +190,22 @@ FileTypeHandler::isValidType(int fileType) const //! \} -} // namespace +} // namespace /******************************************************************** * FileNameOptionStorage */ -FileNameOptionStorage::FileNameOptionStorage(const FileNameOption &settings, - FileNameOptionManager *manager) - : MyBase(settings), info_(this), manager_(manager), fileType_(-1), - defaultExtension_(""), bRead_(settings.bRead_), bWrite_(settings.bWrite_), - bLibrary_(settings.bLibrary_), bAllowMissing_(settings.bAllowMissing_) +FileNameOptionStorage::FileNameOptionStorage(const FileNameOption& settings, FileNameOptionManager* manager) : + MyBase(settings), + info_(this), + manager_(manager), + fileType_(-1), + defaultExtension_(""), + bRead_(settings.bRead_), + bWrite_(settings.bWrite_), + bLibrary_(settings.bLibrary_), + bAllowMissing_(settings.bAllowMissing_) { GMX_RELEASE_ASSERT(!hasFlag(efOption_MultipleTimes), "allowMultiple() is not supported for file name options"); @@ -309,16 +308,14 @@ std::string FileNameOptionStorage::formatExtraDescription() const return result; } -std::string FileNameOptionStorage::formatSingleValue(const std::string &value) const +std::string FileNameOptionStorage::formatSingleValue(const std::string& value) const { return value; } -void FileNameOptionStorage::initConverter(ConverterType * /*converter*/) -{ -} +void FileNameOptionStorage::initConverter(ConverterType* /*converter*/) {} -std::string FileNameOptionStorage::processValue(const std::string &value) const +std::string FileNameOptionStorage::processValue(const std::string& value) const { if (manager_ != nullptr) { @@ -341,8 +338,7 @@ std::string FileNameOptionStorage::processValue(const std::string &value) const } else { - GMX_ASSERT(isValidType(fileType), - "Manager returned an invalid file name"); + GMX_ASSERT(isValidType(fileType), "Manager returned an invalid file name"); } } return processedValue; @@ -358,19 +354,19 @@ std::string FileNameOptionStorage::processValue(const std::string &value) const const int fileType = fn2ftp(value.c_str()); if (fileType == efNR) { - std::string message - = formatString("File '%s' cannot be used by GROMACS because it " - "does not have a recognizable extension.\n" - "The following extensions are possible for this option:\n %s", - value.c_str(), joinStrings(extensions(), ", ").c_str()); + std::string message = formatString( + "File '%s' cannot be used by GROMACS because it " + "does not have a recognizable extension.\n" + "The following extensions are possible for this option:\n %s", + value.c_str(), joinStrings(extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } else if (!isValidType(fileType)) { - std::string message - = formatString("File name '%s' cannot be used for this option.\n" - "Only the following extensions are possible:\n %s", - value.c_str(), joinStrings(extensions(), ", ").c_str()); + std::string message = formatString( + "File name '%s' cannot be used for this option.\n" + "Only the following extensions are possible:\n %s", + value.c_str(), joinStrings(extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } return value; @@ -381,17 +377,14 @@ void FileNameOptionStorage::processAll() if (manager_ != nullptr && hasFlag(efOption_HasDefaultValue)) { ArrayRef valueList = values(); - GMX_RELEASE_ASSERT(valueList.size() == 1, - "There should be only one default value"); + GMX_RELEASE_ASSERT(valueList.size() == 1, "There should be only one default value"); if (!valueList[0].empty()) { - const std::string &oldValue = valueList[0]; + const std::string& oldValue = valueList[0]; GMX_ASSERT(endsWith(oldValue, defaultExtension()), "Default value does not have the expected extension"); - const std::string prefix - = stripSuffixIfPresent(oldValue, defaultExtension()); - const std::string newValue - = manager_->completeDefaultFileName(prefix, info_); + const std::string prefix = stripSuffixIfPresent(oldValue, defaultExtension()); + const std::string newValue = manager_->completeDefaultFileName(prefix, info_); if (!newValue.empty() && newValue != oldValue) { GMX_ASSERT(isValidType(fn2ftp(newValue.c_str())), @@ -412,15 +405,15 @@ bool FileNameOptionStorage::isTrajectoryOption() const return fileType_ == efTRX; } -const char *FileNameOptionStorage::defaultExtension() const +const char* FileNameOptionStorage::defaultExtension() const { return defaultExtension_; } -std::vector FileNameOptionStorage::extensions() const +std::vector FileNameOptionStorage::extensions() const { - FileTypeHandler typeHandler(fileType_); - std::vector result; + FileTypeHandler typeHandler(fileType_); + std::vector result; result.reserve(typeHandler.extensionCount()); for (int i = 0; i < typeHandler.extensionCount(); ++i) { @@ -453,14 +446,11 @@ ArrayRef FileNameOptionStorage::fileTypes() const * FileNameOptionInfo */ -FileNameOptionInfo::FileNameOptionInfo(FileNameOptionStorage *option) - : OptionInfo(option) -{ -} +FileNameOptionInfo::FileNameOptionInfo(FileNameOptionStorage* option) : OptionInfo(option) {} -const FileNameOptionStorage &FileNameOptionInfo::option() const +const FileNameOptionStorage& FileNameOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } bool FileNameOptionInfo::isInputFile() const @@ -498,7 +488,7 @@ bool FileNameOptionInfo::isTrajectoryOption() const return option().isTrajectoryOption(); } -const char *FileNameOptionInfo::defaultExtension() const +const char* FileNameOptionInfo::defaultExtension() const { return option().defaultExtension(); } @@ -522,8 +512,7 @@ ArrayRef FileNameOptionInfo::fileTypes() const * FileNameOption */ -AbstractOptionStorage * -FileNameOption::createStorage(const OptionManagerContainer &managers) const +AbstractOptionStorage* FileNameOption::createStorage(const OptionManagerContainer& managers) const { return new FileNameOptionStorage(*this, managers.get()); } diff --git a/src/gromacs/options/filenameoption.h b/src/gromacs/options/filenameoption.h index d792dab42d..f56d93005a 100644 --- a/src/gromacs/options/filenameoption.h +++ b/src/gromacs/options/filenameoption.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,7 +52,8 @@ namespace gmx { -template class ArrayRef; +template +class ArrayRef; class FileNameOptionInfo; class FileNameOptionManager; class FileNameOptionStorage; @@ -67,155 +68,195 @@ class FileNameOptionStorage; */ class FileNameOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef FileNameOptionInfo InfoType; +public: + //! OptionInfo subclass corresponding to this option type. + typedef FileNameOptionInfo InfoType; - //! Initializes an option with the given name. - explicit FileNameOption(const char *name) - : MyBase(name), optionType_(eftUnknown), legacyType_(-1), - defaultBasename_(nullptr), defaultType_(-1), - bLegacyOptionalBehavior_(false), - bRead_(false), bWrite_(false), bLibrary_(false), - bAllowMissing_(false) - { - } + //! Initializes an option with the given name. + explicit FileNameOption(const char* name) : + MyBase(name), + optionType_(eftUnknown), + legacyType_(-1), + defaultBasename_(nullptr), + defaultType_(-1), + bLegacyOptionalBehavior_(false), + bRead_(false), + bWrite_(false), + bLibrary_(false), + bAllowMissing_(false) + { + } - /*! \brief - * Sets the type of the file this option accepts. - * - * Either this attribute or legacyType() must be provided. - */ - MyClass &filetype(OptionFileType type) - { optionType_ = type; return me(); } - /*! \brief - * Sets the type of the file from an enum in filetypes.h. - * - * New code should prefer filetype(), extending the enumeration if - * necessary. - */ - MyClass &legacyType(int type) - { legacyType_ = type; return me(); } - /*! \brief - * Changes the behavior of optional options to match old t_filenm. - * - * If this is not set, optional options return an empty string if not - * set. If this is set, a non-empty value is always returned. - * In the latter case, whether the option is set only affects the - * return value of OptionInfo::isSet() and Options::isSet(). - */ - MyClass &legacyOptionalBehavior() - { bLegacyOptionalBehavior_ = true; return me(); } - //! Tells that the file provided by this option is used for input only. - MyClass &inputFile() - { bRead_ = true; bWrite_ = false; return me(); } - //! Tells that the file provided by this option is used for output only. - MyClass &outputFile() - { bRead_ = false; bWrite_ = true; return me(); } - /*! \brief - * Tells that the file provided by this option is used for input and - * output both. - */ - MyClass &inputOutputFile() - { bRead_ = bWrite_ = true; return me(); } - /*! \brief - * Sets the read/write usage for this file from boolean flags. - */ - MyClass &readWriteFlags(bool bRead, bool bWrite) - { bRead_ = bRead; bWrite_ = bWrite; return me(); } - /*! \brief - * Tells that the file will be looked up in library directories in - * addition to working directory. - * - * \todo - * Currently, this flag only affects the help output. Callers must - * take care themselves to actually search the file in the library - * directories. It would be nicer to do this searching within the - * file name option implementation. - */ - MyClass &libraryFile(bool bLibrary = true) - { bLibrary_ = bLibrary; return me(); } - /*! \brief - * Tells that missing file names explicitly provided by the user are - * valid for this input option. - * - * If this method is not called, an error will be raised if the user - * explicitly provides a file name that does not name an existing file, - * or if the default value does not resolve to a valid file name for a - * required option that the user has not set. - * - * This method only has effect with input files, and only if a - * FileNameOptionManager is being used. - */ - MyClass &allowMissing(bool bAllow = true) - { bAllowMissing_ = bAllow; return me(); } - /*! \brief - * Sets a default basename for the file option. - * - * Use this method instead of defaultValue() or defaultValueIfSet() to - * set a default value for a file name option. No extension needs to - * be provided; it is automatically added based on filetype() or - * defaultType(). - * The behavior is also adjusted based on required(): if the option is - * required, the value given to defaultBasename() is treated as for - * both defaultValue() and defaultValueIfSet(), otherwise it is treated - * as for defaultValueIfSet(). - * - * For input files that accept multiple extensions, the extension is - * completed to the default extension on creation of the option or at - * time of parsing an option without a value. - * - * If FileNameOptionManager is used, the extension may change during - * Options::finish(), as this is the time when the default names are - * checked against the file system to provide an extension that matches - * an existing file if that is possible. - * - * If FileNameOptionManager is used, and - * FileNameOptionManager::addDefaultFileNameOption() is used, and the - * user provides a global default file name using that option, then the - * global default takes precedence over defaultBasename(). - */ - MyClass &defaultBasename(const char *basename) - { defaultBasename_ = basename; return me(); } - /*! \brief - * Sets a default type/extension for the file option. - * - * For options that accept multiple types of files (e.g., - * eftTrajectory), this method sets the default extension used - * for completing defaultBasename(), as well as the default extension - * used by FileNameOptionManager to complete various file names. - * - * The value should be one of the enumerated `ef*` values from - * filetypes.h, and be a valid type for the type specified with - * filetype(). - */ - MyClass &defaultType(int filetype) - { defaultType_ = filetype; return me(); } + /*! \brief + * Sets the type of the file this option accepts. + * + * Either this attribute or legacyType() must be provided. + */ + MyClass& filetype(OptionFileType type) + { + optionType_ = type; + return me(); + } + /*! \brief + * Sets the type of the file from an enum in filetypes.h. + * + * New code should prefer filetype(), extending the enumeration if + * necessary. + */ + MyClass& legacyType(int type) + { + legacyType_ = type; + return me(); + } + /*! \brief + * Changes the behavior of optional options to match old t_filenm. + * + * If this is not set, optional options return an empty string if not + * set. If this is set, a non-empty value is always returned. + * In the latter case, whether the option is set only affects the + * return value of OptionInfo::isSet() and Options::isSet(). + */ + MyClass& legacyOptionalBehavior() + { + bLegacyOptionalBehavior_ = true; + return me(); + } + //! Tells that the file provided by this option is used for input only. + MyClass& inputFile() + { + bRead_ = true; + bWrite_ = false; + return me(); + } + //! Tells that the file provided by this option is used for output only. + MyClass& outputFile() + { + bRead_ = false; + bWrite_ = true; + return me(); + } + /*! \brief + * Tells that the file provided by this option is used for input and + * output both. + */ + MyClass& inputOutputFile() + { + bRead_ = bWrite_ = true; + return me(); + } + /*! \brief + * Sets the read/write usage for this file from boolean flags. + */ + MyClass& readWriteFlags(bool bRead, bool bWrite) + { + bRead_ = bRead; + bWrite_ = bWrite; + return me(); + } + /*! \brief + * Tells that the file will be looked up in library directories in + * addition to working directory. + * + * \todo + * Currently, this flag only affects the help output. Callers must + * take care themselves to actually search the file in the library + * directories. It would be nicer to do this searching within the + * file name option implementation. + */ + MyClass& libraryFile(bool bLibrary = true) + { + bLibrary_ = bLibrary; + return me(); + } + /*! \brief + * Tells that missing file names explicitly provided by the user are + * valid for this input option. + * + * If this method is not called, an error will be raised if the user + * explicitly provides a file name that does not name an existing file, + * or if the default value does not resolve to a valid file name for a + * required option that the user has not set. + * + * This method only has effect with input files, and only if a + * FileNameOptionManager is being used. + */ + MyClass& allowMissing(bool bAllow = true) + { + bAllowMissing_ = bAllow; + return me(); + } + /*! \brief + * Sets a default basename for the file option. + * + * Use this method instead of defaultValue() or defaultValueIfSet() to + * set a default value for a file name option. No extension needs to + * be provided; it is automatically added based on filetype() or + * defaultType(). + * The behavior is also adjusted based on required(): if the option is + * required, the value given to defaultBasename() is treated as for + * both defaultValue() and defaultValueIfSet(), otherwise it is treated + * as for defaultValueIfSet(). + * + * For input files that accept multiple extensions, the extension is + * completed to the default extension on creation of the option or at + * time of parsing an option without a value. + * + * If FileNameOptionManager is used, the extension may change during + * Options::finish(), as this is the time when the default names are + * checked against the file system to provide an extension that matches + * an existing file if that is possible. + * + * If FileNameOptionManager is used, and + * FileNameOptionManager::addDefaultFileNameOption() is used, and the + * user provides a global default file name using that option, then the + * global default takes precedence over defaultBasename(). + */ + MyClass& defaultBasename(const char* basename) + { + defaultBasename_ = basename; + return me(); + } + /*! \brief + * Sets a default type/extension for the file option. + * + * For options that accept multiple types of files (e.g., + * eftTrajectory), this method sets the default extension used + * for completing defaultBasename(), as well as the default extension + * used by FileNameOptionManager to complete various file names. + * + * The value should be one of the enumerated `ef*` values from + * filetypes.h, and be a valid type for the type specified with + * filetype(). + */ + MyClass& defaultType(int filetype) + { + defaultType_ = filetype; + return me(); + } - private: - // Use defaultBasename() instead. - using MyBase::defaultValue; - using MyBase::defaultValueIfSet; +private: + // Use defaultBasename() instead. + using MyBase::defaultValue; + using MyBase::defaultValueIfSet; - //! Creates a FileNameOptionStorage object. - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; + //! Creates a FileNameOptionStorage object. + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; - OptionFileType optionType_; - int legacyType_; - const char *defaultBasename_; - int defaultType_; - bool bLegacyOptionalBehavior_; - bool bRead_; - bool bWrite_; - bool bLibrary_; - bool bAllowMissing_; + OptionFileType optionType_; + int legacyType_; + const char* defaultBasename_; + int defaultType_; + bool bLegacyOptionalBehavior_; + bool bRead_; + bool bWrite_; + bool bLibrary_; + bool bAllowMissing_; - /*! \brief - * Needed to initialize FileNameOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class FileNameOptionStorage; + /*! \brief + * Needed to initialize FileNameOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class FileNameOptionStorage; }; /*! \brief @@ -226,43 +267,43 @@ class FileNameOption : public OptionTemplate */ class FileNameOptionInfo : public OptionInfo { - public: - //! Shorthand for a list of extensions. - typedef std::vector ExtensionList; +public: + //! Shorthand for a list of extensions. + typedef std::vector ExtensionList; - //! Creates an option info object for the given option. - explicit FileNameOptionInfo(FileNameOptionStorage *option); + //! Creates an option info object for the given option. + explicit FileNameOptionInfo(FileNameOptionStorage* option); - //! Whether the option specifies an input file. - bool isInputFile() const; - //! Whether the option specifies an output file. - bool isOutputFile() const; - //! Whether the option specifies a file used for both input and output. - bool isInputOutputFile() const; - /*! \brief - * Whether the option specifies a library file. - * - * \see FileNameOption::libraryFile() - */ - bool isLibraryFile() const; - //! Whether the (input) option allows missing files to be provided. - bool allowMissing() const; + //! Whether the option specifies an input file. + bool isInputFile() const; + //! Whether the option specifies an output file. + bool isOutputFile() const; + //! Whether the option specifies a file used for both input and output. + bool isInputOutputFile() const; + /*! \brief + * Whether the option specifies a library file. + * + * \see FileNameOption::libraryFile() + */ + bool isLibraryFile() const; + //! Whether the (input) option allows missing files to be provided. + bool allowMissing() const; - //! Whether the option specifies directories. - bool isDirectoryOption() const; - //! Whether the option specifies a generic trajectory file. - bool isTrajectoryOption() const; - //! Returns the default extension for this option. - const char *defaultExtension() const; - //! Returns the list of extensions this option accepts. - ExtensionList extensions() const; - //! Returns whether \p fileType (from filetypes.h) is accepted for this option. - bool isValidType(int fileType) const; - //! Returns the list of file types this option accepts. - ArrayRef fileTypes() const; + //! Whether the option specifies directories. + bool isDirectoryOption() const; + //! Whether the option specifies a generic trajectory file. + bool isTrajectoryOption() const; + //! Returns the default extension for this option. + const char* defaultExtension() const; + //! Returns the list of extensions this option accepts. + ExtensionList extensions() const; + //! Returns whether \p fileType (from filetypes.h) is accepted for this option. + bool isValidType(int fileType) const; + //! Returns the list of file types this option accepts. + ArrayRef fileTypes() const; - private: - const FileNameOptionStorage &option() const; +private: + const FileNameOptionStorage& option() const; }; } // namespace gmx diff --git a/src/gromacs/options/filenameoptionmanager.cpp b/src/gromacs/options/filenameoptionmanager.cpp index 7c9fefa884..9d15b56c83 100644 --- a/src/gromacs/options/filenameoptionmanager.cpp +++ b/src/gromacs/options/filenameoptionmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,8 +64,7 @@ namespace { //! Extensions that are recognized as compressed files. -const char *const c_compressedExtensions[] = -{ ".gz", ".Z" }; +const char* const c_compressedExtensions[] = { ".gz", ".Z" }; /******************************************************************** * Helper functions @@ -79,9 +78,9 @@ const char *const c_compressedExtensions[] = * The first match is returned. * Returns an empty string if no existing file is found. */ -std::string findExistingExtension(const std::string &prefix, - const FileNameOptionInfo &option, - const IFileInputRedirector *redirector) +std::string findExistingExtension(const std::string& prefix, + const FileNameOptionInfo& option, + const IFileInputRedirector* redirector) { ArrayRef types = option.fileTypes(); ArrayRef::const_iterator i; @@ -96,7 +95,7 @@ std::string findExistingExtension(const std::string &prefix, return std::string(); } -} // namespace +} // namespace /******************************************************************** * FileNameOptionManager::Impl @@ -109,36 +108,26 @@ std::string findExistingExtension(const std::string &prefix, */ class FileNameOptionManager::Impl { - public: - Impl() - : redirector_(&defaultFileInputRedirector()), - bInputCheckingDisabled_(false) - { - } +public: + Impl() : redirector_(&defaultFileInputRedirector()), bInputCheckingDisabled_(false) {} - //! Redirector for file existence checks. - const IFileInputRedirector *redirector_; - //! Global default file name, if set. - std::string defaultFileName_; - //! Whether input option processing has been disabled. - bool bInputCheckingDisabled_; + //! Redirector for file existence checks. + const IFileInputRedirector* redirector_; + //! Global default file name, if set. + std::string defaultFileName_; + //! Whether input option processing has been disabled. + bool bInputCheckingDisabled_; }; /******************************************************************** * FileNameOptionManager */ -FileNameOptionManager::FileNameOptionManager() - : impl_(new Impl()) -{ -} +FileNameOptionManager::FileNameOptionManager() : impl_(new Impl()) {} -FileNameOptionManager::~FileNameOptionManager() -{ -} +FileNameOptionManager::~FileNameOptionManager() {} -void FileNameOptionManager::setInputRedirector( - const IFileInputRedirector *redirector) +void FileNameOptionManager::setInputRedirector(const IFileInputRedirector* redirector) { impl_->redirector_ = redirector; } @@ -148,31 +137,25 @@ void FileNameOptionManager::disableInputOptionChecking(bool bDisable) impl_->bInputCheckingDisabled_ = bDisable; } -void FileNameOptionManager::addDefaultFileNameOption( - IOptionsContainer *options, const char *name) +void FileNameOptionManager::addDefaultFileNameOption(IOptionsContainer* options, const char* name) { options->addOption( - StringOption(name).store(&impl_->defaultFileName_) - .description("Set the default filename for all file options")); + StringOption(name).store(&impl_->defaultFileName_).description("Set the default filename for all file options")); } -std::string FileNameOptionManager::completeFileName( - const std::string &value, const FileNameOptionInfo &option) +std::string FileNameOptionManager::completeFileName(const std::string& value, const FileNameOptionInfo& option) { const bool bAllowMissing = option.allowMissing(); - const bool bInput - = option.isInputFile() || option.isInputOutputFile(); + const bool bInput = option.isInputFile() || option.isInputOutputFile(); // Currently, directory options are simple, and don't need any // special processing. // TODO: Consider splitting them into a separate DirectoryOption. if (option.isDirectoryOption()) { - if (!impl_->bInputCheckingDisabled_ && bInput && !bAllowMissing - && !Directory::exists(value)) + if (!impl_->bInputCheckingDisabled_ && bInput && !bAllowMissing && !Directory::exists(value)) { - std::string message - = formatString("Directory '%s' does not exist or is not accessible.", - value.c_str()); + std::string message = + formatString("Directory '%s' does not exist or is not accessible.", value.c_str()); // TODO: Get actual errno value from the attempt to open the file // to provide better feedback to the user. GMX_THROW(InvalidInputError(message)); @@ -182,11 +165,10 @@ std::string FileNameOptionManager::completeFileName( const int fileType = fn2ftp(value.c_str()); if (bInput && !impl_->bInputCheckingDisabled_) { - if (fileType == efNR - && impl_->redirector_->fileExists(value, File::throwOnError)) + if (fileType == efNR && impl_->redirector_->fileExists(value, File::throwOnError)) { - ArrayRef compressedExtensions(c_compressedExtensions); - ArrayRef::const_iterator ext; + ArrayRef compressedExtensions(c_compressedExtensions); + ArrayRef::const_iterator ext; for (ext = compressedExtensions.begin(); ext != compressedExtensions.end(); ++ext) { if (endsWith(value, *ext)) @@ -210,8 +192,7 @@ std::string FileNameOptionManager::completeFileName( } else if (fileType == efNR) { - const std::string processedValue - = findExistingExtension(value, option, impl_->redirector_); + const std::string processedValue = findExistingExtension(value, option, impl_->redirector_); if (!processedValue.empty()) { return processedValue; @@ -227,10 +208,10 @@ std::string FileNameOptionManager::completeFileName( } else { - std::string message - = formatString("File '%s' does not exist or is not accessible.\n" - "The following extensions were tried to complete the file name:\n %s", - value.c_str(), joinStrings(option.extensions(), ", ").c_str()); + std::string message = formatString( + "File '%s' does not exist or is not accessible.\n" + "The following extensions were tried to complete the file name:\n %s", + value.c_str(), joinStrings(option.extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } } @@ -264,20 +245,18 @@ std::string FileNameOptionManager::completeFileName( return std::string(); } -std::string FileNameOptionManager::completeDefaultFileName( - const std::string &prefix, const FileNameOptionInfo &option) +std::string FileNameOptionManager::completeDefaultFileName(const std::string& prefix, + const FileNameOptionInfo& option) { if (option.isDirectoryOption()) { return std::string(); } - const bool bInput = option.isInputFile() || option.isInputOutputFile(); - const std::string realPrefix - = !impl_->defaultFileName_.empty() ? impl_->defaultFileName_ : prefix; + const bool bInput = option.isInputFile() || option.isInputOutputFile(); + const std::string realPrefix = !impl_->defaultFileName_.empty() ? impl_->defaultFileName_ : prefix; if (bInput && !impl_->bInputCheckingDisabled_) { - const std::string completedName - = findExistingExtension(realPrefix, option, impl_->redirector_); + const std::string completedName = findExistingExtension(realPrefix, option, impl_->redirector_); if (!completedName.empty()) { return completedName; @@ -293,20 +272,20 @@ std::string FileNameOptionManager::completeDefaultFileName( } else if (option.isSet()) { - std::string message - = formatString("No file name was provided, and the default file " - "'%s' does not exist or is not accessible.\n" - "The following extensions were tried to complete the file name:\n %s", - prefix.c_str(), joinStrings(option.extensions(), ", ").c_str()); + std::string message = formatString( + "No file name was provided, and the default file " + "'%s' does not exist or is not accessible.\n" + "The following extensions were tried to complete the file name:\n %s", + prefix.c_str(), joinStrings(option.extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } else if (option.isRequired()) { - std::string message - = formatString("Required option was not provided, and the default file " - "'%s' does not exist or is not accessible.\n" - "The following extensions were tried to complete the file name:\n %s", - prefix.c_str(), joinStrings(option.extensions(), ", ").c_str()); + std::string message = formatString( + "Required option was not provided, and the default file " + "'%s' does not exist or is not accessible.\n" + "The following extensions were tried to complete the file name:\n %s", + prefix.c_str(), joinStrings(option.extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } // We get here with the legacy optional behavior. diff --git a/src/gromacs/options/filenameoptionmanager.h b/src/gromacs/options/filenameoptionmanager.h index b1a42a8057..3fe2f075e9 100644 --- a/src/gromacs/options/filenameoptionmanager.h +++ b/src/gromacs/options/filenameoptionmanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -81,99 +81,97 @@ class IOptionsContainer; */ class FileNameOptionManager : public IOptionManager { - public: - FileNameOptionManager(); - ~FileNameOptionManager() override; +public: + FileNameOptionManager(); + ~FileNameOptionManager() override; - /*! \brief - * Redirects file existence checks. - * - * \param[in] redirector File redirector to use for existence checks. - * - * The manager checks for existence of various files on the file system - * to complete file extensions. This method can be used to redirect - * those checks to an alternative implementation. - * - * This is used for unit tests to more easily control the result of the - * checks and to keep the tests as fast as possible by avoiding real - * file system access. To keep implementation options open, behavior - * with `redirector == NULL` is undefined and should not be relied on. - * For tests, there should only be need to call this a single time, - * right after creating the manager. - */ - void setInputRedirector(const IFileInputRedirector *redirector); + /*! \brief + * Redirects file existence checks. + * + * \param[in] redirector File redirector to use for existence checks. + * + * The manager checks for existence of various files on the file system + * to complete file extensions. This method can be used to redirect + * those checks to an alternative implementation. + * + * This is used for unit tests to more easily control the result of the + * checks and to keep the tests as fast as possible by avoiding real + * file system access. To keep implementation options open, behavior + * with `redirector == NULL` is undefined and should not be relied on. + * For tests, there should only be need to call this a single time, + * right after creating the manager. + */ + void setInputRedirector(const IFileInputRedirector* redirector); - /*! \brief - * Disables special input file option handling. - * - * If disabled, this removes all file system calls from the file - * name option parsing. - * The values returned by FileNameOption for input and input/output - * files are handled with the same simple rule as for output files: - * the default extension is added if the file does not end in a - * recognized extension, and no other checking is done. - * - * This changes the following behavior: - * - Providing non-existent files does not trigger errors. - * - Extensions for input files are not completed to an existing file. - * - Compressed input files do not work. - */ - void disableInputOptionChecking(bool bDisable); + /*! \brief + * Disables special input file option handling. + * + * If disabled, this removes all file system calls from the file + * name option parsing. + * The values returned by FileNameOption for input and input/output + * files are handled with the same simple rule as for output files: + * the default extension is added if the file does not end in a + * recognized extension, and no other checking is done. + * + * This changes the following behavior: + * - Providing non-existent files does not trigger errors. + * - Extensions for input files are not completed to an existing file. + * - Compressed input files do not work. + */ + void disableInputOptionChecking(bool bDisable); - /*! \brief - * Adds an option for setting the default global file name. - * - * \param options Options to add the option to. - * \param[in] name Name of the option to add. - * - * If the user sets the option, it affects all file name options that - * would normally return a default value: the basename for the returned - * value is taken from the value of the default file name option, - * instead from an option-specific default - * (FileNameOption::defaultBaseName()). - */ - void addDefaultFileNameOption(IOptionsContainer *options, const char *name); + /*! \brief + * Adds an option for setting the default global file name. + * + * \param options Options to add the option to. + * \param[in] name Name of the option to add. + * + * If the user sets the option, it affects all file name options that + * would normally return a default value: the basename for the returned + * value is taken from the value of the default file name option, + * instead from an option-specific default + * (FileNameOption::defaultBaseName()). + */ + void addDefaultFileNameOption(IOptionsContainer* options, const char* name); - /*! \brief - * Completes file name option values. - * - * \param[in] value Value provided by the user. - * \param[in] option Option for which the value should be completed. - * \returns Value for the file name option. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if the value is not valid for this - * option. - * - * This method is called for each value that the user provides to - * a FileNameOption. The return value (if non-empty) is used as the - * value of the option instead of the user-provided one. - */ - std::string completeFileName(const std::string &value, - const FileNameOptionInfo &option); - /*! \brief - * Completes default values for file name options. - * - * \param[in] prefix Default prefix for the file name. - * \param[in] option Option for which the value should be completed. - * \returns Value for the file name option. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if the value is not valid for this - * option. - * - * This method is called for each FileNameOption that has a default - * value (either a standard default value, or if the user provided the - * option without an explicit value). \p prefix is the default value - * without the default extension for the option. - * If the return value is non-empty, it is used as the default value - * for the option instead of \p prefix + default extension. - */ - std::string completeDefaultFileName(const std::string &prefix, - const FileNameOptionInfo &option); + /*! \brief + * Completes file name option values. + * + * \param[in] value Value provided by the user. + * \param[in] option Option for which the value should be completed. + * \returns Value for the file name option. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if the value is not valid for this + * option. + * + * This method is called for each value that the user provides to + * a FileNameOption. The return value (if non-empty) is used as the + * value of the option instead of the user-provided one. + */ + std::string completeFileName(const std::string& value, const FileNameOptionInfo& option); + /*! \brief + * Completes default values for file name options. + * + * \param[in] prefix Default prefix for the file name. + * \param[in] option Option for which the value should be completed. + * \returns Value for the file name option. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if the value is not valid for this + * option. + * + * This method is called for each FileNameOption that has a default + * value (either a standard default value, or if the user provided the + * option without an explicit value). \p prefix is the default value + * without the default extension for the option. + * If the return value is non-empty, it is used as the default value + * for the option instead of \p prefix + default extension. + */ + std::string completeDefaultFileName(const std::string& prefix, const FileNameOptionInfo& option); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/options/filenameoptionstorage.h b/src/gromacs/options/filenameoptionstorage.h index 16fc4ef3c3..c32b97d927 100644 --- a/src/gromacs/options/filenameoptionstorage.h +++ b/src/gromacs/options/filenameoptionstorage.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,58 +60,57 @@ class FileNameOptionManager; */ class FileNameOptionStorage : public OptionStorageTemplateSimple { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Storage settings. - * \param manager Manager for this object (can be NULL). - */ - FileNameOptionStorage(const FileNameOption &settings, - FileNameOptionManager *manager); +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Storage settings. + * \param manager Manager for this object (can be NULL). + */ + FileNameOptionStorage(const FileNameOption& settings, FileNameOptionManager* manager); - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override; - std::string formatExtraDescription() const override; - std::string formatSingleValue(const std::string &value) const override; + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override; + std::string formatExtraDescription() const override; + std::string formatSingleValue(const std::string& value) const override; - //! \copydoc FileNameOptionInfo::isInputFile() - bool isInputFile() const { return bRead_ && !bWrite_; } - //! \copydoc FileNameOptionInfo::isOutputFile() - bool isOutputFile() const { return !bRead_ && bWrite_; } - //! \copydoc FileNameOptionInfo::isInputOutputFile() - bool isInputOutputFile() const { return bRead_ && bWrite_; } - //! \copydoc FileNameOptionInfo::isLibraryFile() - bool isLibraryFile() const { return bLibrary_; } - //! \copydoc FileNameOptionInfo::allowMissing() - bool allowMissing() const { return bAllowMissing_; } + //! \copydoc FileNameOptionInfo::isInputFile() + bool isInputFile() const { return bRead_ && !bWrite_; } + //! \copydoc FileNameOptionInfo::isOutputFile() + bool isOutputFile() const { return !bRead_ && bWrite_; } + //! \copydoc FileNameOptionInfo::isInputOutputFile() + bool isInputOutputFile() const { return bRead_ && bWrite_; } + //! \copydoc FileNameOptionInfo::isLibraryFile() + bool isLibraryFile() const { return bLibrary_; } + //! \copydoc FileNameOptionInfo::allowMissing() + bool allowMissing() const { return bAllowMissing_; } - //! \copydoc FileNameOptionInfo::isDirectoryOption() - bool isDirectoryOption() const; - //! \copydoc FileNameOptionInfo::isTrajectoryOption() - bool isTrajectoryOption() const; - //! \copydoc FileNameOptionInfo::defaultExtension() - const char *defaultExtension() const; - //! \copydoc FileNameOptionInfo::extensions() - std::vector extensions() const; - //! \copydoc FileNameOptionInfo::isValidType() - bool isValidType(int fileType) const; - //! \copydoc FileNameOptionInfo::fileTypes() - ArrayRef fileTypes() const; + //! \copydoc FileNameOptionInfo::isDirectoryOption() + bool isDirectoryOption() const; + //! \copydoc FileNameOptionInfo::isTrajectoryOption() + bool isTrajectoryOption() const; + //! \copydoc FileNameOptionInfo::defaultExtension() + const char* defaultExtension() const; + //! \copydoc FileNameOptionInfo::extensions() + std::vector extensions() const; + //! \copydoc FileNameOptionInfo::isValidType() + bool isValidType(int fileType) const; + //! \copydoc FileNameOptionInfo::fileTypes() + ArrayRef fileTypes() const; - private: - void initConverter(ConverterType *converter) override; - std::string processValue(const std::string &value) const override; - void processAll() override; +private: + void initConverter(ConverterType* converter) override; + std::string processValue(const std::string& value) const override; + void processAll() override; - FileNameOptionInfo info_; - FileNameOptionManager *manager_; - int fileType_; - const char *defaultExtension_; - bool bRead_; - bool bWrite_; - bool bLibrary_; - bool bAllowMissing_; + FileNameOptionInfo info_; + FileNameOptionManager* manager_; + int fileType_; + const char* defaultExtension_; + bool bRead_; + bool bWrite_; + bool bLibrary_; + bool bAllowMissing_; }; } // namespace gmx diff --git a/src/gromacs/options/ioptionsbehavior.h b/src/gromacs/options/ioptionsbehavior.h index 09bc9d20d0..d5d816c10b 100644 --- a/src/gromacs/options/ioptionsbehavior.h +++ b/src/gromacs/options/ioptionsbehavior.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,34 +68,34 @@ class Options; */ class IOptionsBehavior { - public: - virtual ~IOptionsBehavior(); +public: + virtual ~IOptionsBehavior(); - /*! \brief - * Called when the behavior is associated with an options object. - * - * This method can, e.g., use Options::addManager() to associate - * managers with the options object. - */ - virtual void initBehavior(Options *options) = 0; - /*! \brief - * Called when all option values have been assigned. - * - * This is called just before Options::finish(), and can, e.g., do - * operations that still influence the option values. - */ - virtual void optionsFinishing(Options *options) = 0; - /*! \brief - * Called when all option values have been processed. - * - * This is called after Options::finish() (and typically after - * higher-level optionsFinished() methods, such as that in - * ICommandLineOptionsModule). This can add behavior that performs - * tasks based on the option values provided. - */ - virtual void optionsFinished() = 0; + /*! \brief + * Called when the behavior is associated with an options object. + * + * This method can, e.g., use Options::addManager() to associate + * managers with the options object. + */ + virtual void initBehavior(Options* options) = 0; + /*! \brief + * Called when all option values have been assigned. + * + * This is called just before Options::finish(), and can, e.g., do + * operations that still influence the option values. + */ + virtual void optionsFinishing(Options* options) = 0; + /*! \brief + * Called when all option values have been processed. + * + * This is called after Options::finish() (and typically after + * higher-level optionsFinished() methods, such as that in + * ICommandLineOptionsModule). This can add behavior that performs + * tasks based on the option values provided. + */ + virtual void optionsFinished() = 0; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/options/ioptionscontainer.h b/src/gromacs/options/ioptionscontainer.h index d988f4c3fd..1217dacb53 100644 --- a/src/gromacs/options/ioptionscontainer.h +++ b/src/gromacs/options/ioptionscontainer.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,72 +79,71 @@ namespace gmx */ class IOptionsContainer { - public: - /*! \brief - * Creates a subgroup of options within the current options. - * - * To add options to the group, use the returned interface. - * - * Currently, this is only used to influence the order of options: - * all options in a group appear before options in a group added after - * it, no matter in which order the options are added to the groups. - * In the future, the groups could also be used to influence the help - * output. - */ - virtual IOptionsContainer &addGroup() = 0; - /*! \brief - * Adds a recognized option. - * - * \tparam OptionType Type of the options description object. - * \param[in] settings Option description. - * \returns OptionInfo object for the created option (never NULL). - * \throws APIError if invalid option settings are provided. - * - * The return value is a pointer for more convenient use in callers: - * often callers need to declare the variable that will hold the return - * value in wider scope than would be achieved by declaring it at the - * site where addOption() is called. - * The returned pointer must not be freed. - * - * See \link Options class documentation \endlink for example usage. - * - * \libinternal - * \p OptionType::InfoType must specify a type that derives from - * OptionInfo and matches the type that is returned by - * AbstractOptionStorage::optionInfo() for the storage object that - * corresponds to \p OptionType. - */ - template - typename OptionType::InfoType *addOption(const OptionType &settings) - { - OptionInfo *info - = addOptionImpl(static_cast(settings)); - GMX_ASSERT(info->isType(), - "Mismatching option info type declaration and implementation"); - return info->toType(); - } +public: + /*! \brief + * Creates a subgroup of options within the current options. + * + * To add options to the group, use the returned interface. + * + * Currently, this is only used to influence the order of options: + * all options in a group appear before options in a group added after + * it, no matter in which order the options are added to the groups. + * In the future, the groups could also be used to influence the help + * output. + */ + virtual IOptionsContainer& addGroup() = 0; + /*! \brief + * Adds a recognized option. + * + * \tparam OptionType Type of the options description object. + * \param[in] settings Option description. + * \returns OptionInfo object for the created option (never NULL). + * \throws APIError if invalid option settings are provided. + * + * The return value is a pointer for more convenient use in callers: + * often callers need to declare the variable that will hold the return + * value in wider scope than would be achieved by declaring it at the + * site where addOption() is called. + * The returned pointer must not be freed. + * + * See \link Options class documentation \endlink for example usage. + * + * \libinternal + * \p OptionType::InfoType must specify a type that derives from + * OptionInfo and matches the type that is returned by + * AbstractOptionStorage::optionInfo() for the storage object that + * corresponds to \p OptionType. + */ + template + typename OptionType::InfoType* addOption(const OptionType& settings) + { + OptionInfo* info = addOptionImpl(static_cast(settings)); + GMX_ASSERT(info->isType(), + "Mismatching option info type declaration and implementation"); + return info->toType(); + } - protected: - // Disallow deletion through the interface. - // (no need for the virtual, but some compilers warn otherwise) - virtual ~IOptionsContainer(); +protected: + // Disallow deletion through the interface. + // (no need for the virtual, but some compilers warn otherwise) + virtual ~IOptionsContainer(); - /*! \brief - * Adds a recognized option. - * - * \param[in] settings Option description. - * \returns OptionInfo object for the created option (never NULL). - * \throws APIError if invalid option settings are provided. - * - * This method provides the internal implementation, but the templated - * method is called from user code. See the templated method for more - * details. - */ - virtual OptionInfo *addOptionImpl(const AbstractOption &settings) = 0; + /*! \brief + * Adds a recognized option. + * + * \param[in] settings Option description. + * \returns OptionInfo object for the created option (never NULL). + * \throws APIError if invalid option settings are provided. + * + * This method provides the internal implementation, but the templated + * method is called from user code. See the templated method for more + * details. + */ + virtual OptionInfo* addOptionImpl(const AbstractOption& settings) = 0; - GMX_DEFAULT_CONSTRUCTORS(IOptionsContainer); + GMX_DEFAULT_CONSTRUCTORS(IOptionsContainer); }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/options/ioptionscontainerwithsections.h b/src/gromacs/options/ioptionscontainerwithsections.h index a9c04118ea..e7efcbd383 100644 --- a/src/gromacs/options/ioptionscontainerwithsections.h +++ b/src/gromacs/options/ioptionscontainerwithsections.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,46 +69,45 @@ class OptionSectionImpl; */ class IOptionsContainerWithSections : public IOptionsContainer { - public: - /*! \brief - * Adds a section to this collection. - * - * \tparam SectionType Type of the section description object. - * \param[in] section Section description. - * \returns AbstractOptionSectionHandle object for the created option. - * \throws APIError if invalid option settings are provided. - * - * Options can be added to the section through the returned handle. - * - * \internal - * \p SectionType::HandleType must specify a type that derives from - * AbstractinOptionSectionHandle and has a suitable constructor. - */ - template - typename SectionType::HandleType addSection(const SectionType §ion) - { - internal::OptionSectionImpl *storage - = addSectionImpl(static_cast(section)); - return typename SectionType::HandleType(storage); - } +public: + /*! \brief + * Adds a section to this collection. + * + * \tparam SectionType Type of the section description object. + * \param[in] section Section description. + * \returns AbstractOptionSectionHandle object for the created option. + * \throws APIError if invalid option settings are provided. + * + * Options can be added to the section through the returned handle. + * + * \internal + * \p SectionType::HandleType must specify a type that derives from + * AbstractinOptionSectionHandle and has a suitable constructor. + */ + template + typename SectionType::HandleType addSection(const SectionType& section) + { + internal::OptionSectionImpl* storage = + addSectionImpl(static_cast(section)); + return typename SectionType::HandleType(storage); + } - protected: - // Disallow deletion through the interface. - // (no need for the virtual, but some compilers warn otherwise) - ~IOptionsContainerWithSections() override; +protected: + // Disallow deletion through the interface. + // (no need for the virtual, but some compilers warn otherwise) + ~IOptionsContainerWithSections() override; - /*! \brief - * Adds a section to this container. - * - * \param[in] section Section description. - * \returns Pointer to the internal section representation object. - */ - virtual internal::OptionSectionImpl * - addSectionImpl(const AbstractOptionSection §ion) = 0; + /*! \brief + * Adds a section to this container. + * + * \param[in] section Section description. + * \returns Pointer to the internal section representation object. + */ + virtual internal::OptionSectionImpl* addSectionImpl(const AbstractOptionSection& section) = 0; - GMX_DEFAULT_CONSTRUCTORS(IOptionsContainerWithSections); + GMX_DEFAULT_CONSTRUCTORS(IOptionsContainerWithSections); }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/options/isectionstorage.h b/src/gromacs/options/isectionstorage.h index f2a8073e13..04a7cfceb6 100644 --- a/src/gromacs/options/isectionstorage.h +++ b/src/gromacs/options/isectionstorage.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,25 +53,25 @@ namespace gmx */ class IOptionSectionStorage { - public: - virtual ~IOptionSectionStorage(); +public: + virtual ~IOptionSectionStorage(); - /*! \brief - * Called once before the first call to startSection(). - * - * This is called once all options have been added to the section. - * The current implementation does not call this if startSection() is - * never called. - */ - virtual void initStorage() = 0; - /*! \brief - * Called when option assignment enters this section. - */ - virtual void startSection() = 0; - /*! \brief - * Called when option assignment leaves this section. - */ - virtual void finishSection() = 0; + /*! \brief + * Called once before the first call to startSection(). + * + * This is called once all options have been added to the section. + * The current implementation does not call this if startSection() is + * never called. + */ + virtual void initStorage() = 0; + /*! \brief + * Called when option assignment enters this section. + */ + virtual void startSection() = 0; + /*! \brief + * Called when option assignment leaves this section. + */ + virtual void finishSection() = 0; }; } // namespace gmx diff --git a/src/gromacs/options/ivaluestore.h b/src/gromacs/options/ivaluestore.h index 3476529dd9..e0ca86f03d 100644 --- a/src/gromacs/options/ivaluestore.h +++ b/src/gromacs/options/ivaluestore.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,8 @@ namespace gmx { -template class ArrayRef; +template +class ArrayRef; /*! \internal * \brief @@ -58,22 +59,22 @@ template class ArrayRef; * * \ingroup module_options */ -template +template class IOptionValueStore { - public: - virtual ~IOptionValueStore() {} +public: + virtual ~IOptionValueStore() {} - //! Returns the number of values stored so far. - virtual int valueCount() = 0; - //! Returns a reference to the actual values. - virtual ArrayRef values() = 0; - //! Removes all stored values. - virtual void clear() = 0; - //! Reserves memory for additional `count` entries. - virtual void reserve(size_t count) = 0; - //! Appends a value to the store. - virtual void append(const T &value) = 0; + //! Returns the number of values stored so far. + virtual int valueCount() = 0; + //! Returns a reference to the actual values. + virtual ArrayRef values() = 0; + //! Removes all stored values. + virtual void clear() = 0; + //! Reserves memory for additional `count` entries. + virtual void reserve(size_t count) = 0; + //! Appends a value to the store. + virtual void append(const T& value) = 0; }; } // namespace gmx diff --git a/src/gromacs/options/optionfiletype.h b/src/gromacs/options/optionfiletype.h index a769ac4136..99357478a1 100644 --- a/src/gromacs/options/optionfiletype.h +++ b/src/gromacs/options/optionfiletype.h @@ -51,7 +51,8 @@ namespace gmx * * \ingroup module_options */ -enum OptionFileType { +enum OptionFileType +{ eftUnknown, eftTopology, eftRunInput, diff --git a/src/gromacs/options/optionflags.h b/src/gromacs/options/optionflags.h index 9157ecba9d..6eb2ace8db 100644 --- a/src/gromacs/options/optionflags.h +++ b/src/gromacs/options/optionflags.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,34 +65,34 @@ namespace gmx enum OptionFlag { //! %Option has been set. - efOption_Set = 1<<0, + efOption_Set = 1 << 0, //! The current value of the option is a programmatic default value. - efOption_HasDefaultValue = 1<<1, + efOption_HasDefaultValue = 1 << 1, //! An explicit default value has been provided for the option. - efOption_ExplicitDefaultValue = 1<<2, + efOption_ExplicitDefaultValue = 1 << 2, /*! \brief * Next assignment to the option clears old values. * * This flag is set when a new option source starts, such that values * from the new source will overwrite old ones. */ - efOption_ClearOnNextSet = 1<<3, + efOption_ClearOnNextSet = 1 << 3, //! %Option is required to be set. - efOption_Required = 1<<4, + efOption_Required = 1 << 4, //! %Option can be specified multiple times. - efOption_MultipleTimes = 1<<5, + efOption_MultipleTimes = 1 << 5, //! %Option is hidden from standard help. - efOption_Hidden = 1<<6, + efOption_Hidden = 1 << 6, /*! \brief * %Option value is a vector, but a single value is also accepted. * * \see AbstractOption::setVector() */ - efOption_Vector = 1<<8, + efOption_Vector = 1 << 8, //! %Option has a defaultValueIfSet() specified. - efOption_DefaultValueIfSetExists = 1<<11, + efOption_DefaultValueIfSetExists = 1 << 11, //! %Option does not support default values. - efOption_NoDefaultValue = 1<<9, + efOption_NoDefaultValue = 1 << 9, /*! \brief * Storage object does its custom checking for minimum value count. * @@ -102,7 +102,7 @@ enum OptionFlag * This is useful to override the default check, which is done in * OptionStorageTemplate::processSet(). */ - efOption_DontCheckMinimumCount = 1<<10 + efOption_DontCheckMinimumCount = 1 << 10 }; //! \libinternal Holds a combination of ::OptionFlag values. diff --git a/src/gromacs/options/optionmanagercontainer.h b/src/gromacs/options/optionmanagercontainer.h index b700f481f1..0914a10173 100644 --- a/src/gromacs/options/optionmanagercontainer.h +++ b/src/gromacs/options/optionmanagercontainer.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,57 +66,52 @@ class IOptionManager; */ class OptionManagerContainer { - public: - OptionManagerContainer() - { - } +public: + OptionManagerContainer() {} - //! Returns `true` if there are no managers. - bool empty() const { return list_.empty(); } + //! Returns `true` if there are no managers. + bool empty() const { return list_.empty(); } - //! Adds a manager to the container. - void add(IOptionManager *manager) - { - list_.push_back(manager); - } - /*! \brief - * Retrieves a manager of a certain type. - * - * \tparam ManagerType Type of manager to retrieve - * (should derive from IOptionManager). - * \returns The manager, or `NULL` if there is none. - * - * This method is used in AbstractOption::createStorage() to retrieve - * a manager of a certain type for options that use a manager. - * - * The return value is `NULL` if there is no manager of the given type. - * The caller needs to handle this (either by asserting, or by handling - * the manager as optional). - */ - template - ManagerType *get() const + //! Adds a manager to the container. + void add(IOptionManager* manager) { list_.push_back(manager); } + /*! \brief + * Retrieves a manager of a certain type. + * + * \tparam ManagerType Type of manager to retrieve + * (should derive from IOptionManager). + * \returns The manager, or `NULL` if there is none. + * + * This method is used in AbstractOption::createStorage() to retrieve + * a manager of a certain type for options that use a manager. + * + * The return value is `NULL` if there is no manager of the given type. + * The caller needs to handle this (either by asserting, or by handling + * the manager as optional). + */ + template + ManagerType* get() const + { + ManagerType* result = nullptr; + for (ListType::const_iterator i = list_.begin(); i != list_.end(); ++i) { - ManagerType *result = nullptr; - for (ListType::const_iterator i = list_.begin(); i != list_.end(); ++i) + ManagerType* curr = dynamic_cast(*i); + if (curr != nullptr) { - ManagerType *curr = dynamic_cast(*i); - if (curr != nullptr) - { - GMX_RELEASE_ASSERT(result == nullptr, - "More than one applicable option manager is set"); - result = curr; - } + GMX_RELEASE_ASSERT(result == nullptr, + "More than one applicable option manager is set"); + result = curr; } - return result; } + return result; + } - private: - //! Shorthand for the internal container type. - typedef std::vector ListType; +private: + //! Shorthand for the internal container type. + typedef std::vector ListType; - ListType list_; + ListType list_; - GMX_DISALLOW_COPY_AND_ASSIGN(OptionManagerContainer); + GMX_DISALLOW_COPY_AND_ASSIGN(OptionManagerContainer); }; } // namespace gmx diff --git a/src/gromacs/options/options.cpp b/src/gromacs/options/options.cpp index 79fbb16c30..16e47937d2 100644 --- a/src/gromacs/options/options.cpp +++ b/src/gromacs/options/options.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,33 +64,25 @@ namespace gmx * IOptionManager */ -IOptionManager::~IOptionManager() -{ -} +IOptionManager::~IOptionManager() {} /******************************************************************** * IOptionsContainer */ -IOptionsContainer::~IOptionsContainer() -{ -} +IOptionsContainer::~IOptionsContainer() {} /******************************************************************** * IOptionsContainerWithSections */ -IOptionsContainerWithSections::~IOptionsContainerWithSections() -{ -} +IOptionsContainerWithSections::~IOptionsContainerWithSections() {} /******************************************************************** * IOptionSectionStorage */ -IOptionSectionStorage::~IOptionSectionStorage() -{ -} +IOptionSectionStorage::~IOptionSectionStorage() {} /******************************************************************** * OptionsImpl @@ -98,19 +91,15 @@ IOptionSectionStorage::~IOptionSectionStorage() namespace internal { -OptionsImpl::OptionsImpl() - : rootSection_(managers_, nullptr, "") -{ -} +OptionsImpl::OptionsImpl() : rootSection_(managers_, nullptr, "") {} /******************************************************************** * OptionSectionImpl */ -OptionSectionImpl * -OptionSectionImpl::addSectionImpl(const AbstractOptionSection §ion) +OptionSectionImpl* OptionSectionImpl::addSectionImpl(const AbstractOptionSection& section) { - const char *name = section.name_; + const char* name = section.name_; // Make sure that there are no duplicate sections. GMX_RELEASE_ASSERT(findSection(name) == nullptr, "Duplicate subsection name"); std::unique_ptr storage(section.createStorage()); @@ -118,19 +107,19 @@ OptionSectionImpl::addSectionImpl(const AbstractOptionSection §ion) return subsections_.back().get(); } -IOptionsContainer &OptionSectionImpl::addGroup() +IOptionsContainer& OptionSectionImpl::addGroup() { return rootGroup_.addGroup(); } -OptionInfo *OptionSectionImpl::addOptionImpl(const AbstractOption &settings) +OptionInfo* OptionSectionImpl::addOptionImpl(const AbstractOption& settings) { return rootGroup_.addOptionImpl(settings); } -OptionSectionImpl *OptionSectionImpl::findSection(const char *name) const +OptionSectionImpl* OptionSectionImpl::findSection(const char* name) const { - for (const auto §ion : subsections_) + for (const auto& section : subsections_) { if (section->name_ == name) { @@ -140,7 +129,7 @@ OptionSectionImpl *OptionSectionImpl::findSection(const char *name) const return nullptr; } -AbstractOptionStorage *OptionSectionImpl::findOption(const char *name) const +AbstractOptionStorage* OptionSectionImpl::findOption(const char* name) const { OptionMap::const_iterator i = optionMap_.find(name); if (i == optionMap_.end()) @@ -152,7 +141,7 @@ AbstractOptionStorage *OptionSectionImpl::findOption(const char *name) const void OptionSectionImpl::start() { - for (const auto &entry : optionMap_) + for (const auto& entry : optionMap_) { entry.second->startSource(); } @@ -170,15 +159,15 @@ void OptionSectionImpl::start() void OptionSectionImpl::finish() { // TODO: Consider how to customize these error messages based on context. - ExceptionInitializer errors("Invalid input values"); - for (const auto &entry : optionMap_) + ExceptionInitializer errors("Invalid input values"); + for (const auto& entry : optionMap_) { - AbstractOptionStorage &option = *entry.second; + AbstractOptionStorage& option = *entry.second; try { option.finish(); } - catch (UserInputError &ex) + catch (UserInputError& ex) { ex.prependContext("In option " + option.name()); errors.addCurrentExceptionAsNested(); @@ -199,31 +188,28 @@ void OptionSectionImpl::finish() * OptionSectionImpl::Group */ -IOptionsContainer &OptionSectionImpl::Group::addGroup() +IOptionsContainer& OptionSectionImpl::Group::addGroup() { subgroups_.emplace_back(parent_); return subgroups_.back(); } -OptionInfo *OptionSectionImpl::Group::addOptionImpl(const AbstractOption &settings) +OptionInfo* OptionSectionImpl::Group::addOptionImpl(const AbstractOption& settings) { - OptionSectionImpl::AbstractOptionStoragePointer - option(settings.createStorage(parent_->managers_)); + OptionSectionImpl::AbstractOptionStoragePointer option(settings.createStorage(parent_->managers_)); options_.reserve(options_.size() + 1); - auto insertionResult = - parent_->optionMap_.insert(std::make_pair(option->name(), - std::move(option))); + auto insertionResult = parent_->optionMap_.insert(std::make_pair(option->name(), std::move(option))); if (!insertionResult.second) { - const std::string &name = insertionResult.first->second->name(); + const std::string& name = insertionResult.first->second->name(); GMX_THROW(APIError("Duplicate option: " + name)); } - AbstractOptionStorage &insertedOption = *insertionResult.first->second; + AbstractOptionStorage& insertedOption = *insertionResult.first->second; options_.push_back(&insertedOption); return &insertedOption.optionInfo(); } -} // namespace internal +} // namespace internal using internal::OptionsImpl; @@ -231,17 +217,12 @@ using internal::OptionsImpl; * Options */ -Options::Options() - : impl_(new OptionsImpl) -{ -} +Options::Options() : impl_(new OptionsImpl) {} -Options::~Options() -{ -} +Options::~Options() {} -void Options::addManager(IOptionManager *manager) +void Options::addManager(IOptionManager* manager) { // This ensures that all options see the same set of managers. GMX_RELEASE_ASSERT(impl_->rootSection_.optionMap_.empty(), @@ -253,27 +234,27 @@ void Options::addManager(IOptionManager *manager) impl_->managers_.add(manager); } -internal::OptionSectionImpl *Options::addSectionImpl(const AbstractOptionSection §ion) +internal::OptionSectionImpl* Options::addSectionImpl(const AbstractOptionSection& section) { return impl_->rootSection_.addSectionImpl(section); } -IOptionsContainer &Options::addGroup() +IOptionsContainer& Options::addGroup() { return impl_->rootSection_.addGroup(); } -OptionInfo *Options::addOptionImpl(const AbstractOption &settings) +OptionInfo* Options::addOptionImpl(const AbstractOption& settings) { return impl_->rootSection_.addOptionImpl(settings); } -OptionSectionInfo &Options::rootSection() +OptionSectionInfo& Options::rootSection() { return impl_->rootSection_.info(); } -const OptionSectionInfo &Options::rootSection() const +const OptionSectionInfo& Options::rootSection() const { return impl_->rootSection_.info(); } diff --git a/src/gromacs/options/options.h b/src/gromacs/options/options.h index ae0a98c320..9ca066ec24 100644 --- a/src/gromacs/options/options.h +++ b/src/gromacs/options/options.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -81,8 +81,8 @@ class OptionsImpl; */ class IOptionManager { - protected: - virtual ~IOptionManager(); +protected: + virtual ~IOptionManager(); }; /*! \brief @@ -101,68 +101,67 @@ class IOptionManager */ class Options : public IOptionsContainerWithSections { - public: - //! Initializes an empty options root container. - Options(); - ~Options() override; - - /*! \brief - * Adds an option manager. - * - * \param manager Manager to add. - * \throws std::bad_alloc if out of memory. - * - * Option managers are used by some types of options that require - * interaction between different option instances (e.g., selection - * options), or need to support globally set properties (e.g., a global - * default file prefix). Option objects can retrieve the pointer to - * their manager when they are created, and the caller can alter the - * behavior of the options through the manager. - * See the individual managers for details. - * - * Caller is responsible for memory management of \p manager. - * The Options object (and its contained options) only stores a - * reference to the object. - * - * This method cannot be called after adding options or sections. - */ - void addManager(IOptionManager *manager); - - // From IOptionsContainer - IOptionsContainer &addGroup() override; - - //! Returns a handle to the root section. - OptionSectionInfo &rootSection(); - //! Returns a handle to the root section. - const OptionSectionInfo &rootSection() const; - - /*! \brief - * Notifies the collection that all option values are assigned. - * - * \throws InvalidInputError if invalid user input is detected. - * - * This function should be called after no more option values are - * to be assigned. Values in storage variables are guaranteed to be - * available only after this call, although in most cases, they are - * available already during assignment. - * - * If invalid option values, e.g., missing required option, is detected - * at this point, this function throws. The thrown exception contains - * information on all errors detected during the call. - */ - void finish(); - - private: - // From IOptionsContainerWithSections - internal::OptionSectionImpl * - addSectionImpl(const AbstractOptionSection §ion) override; - // From IOptionsContainer - OptionInfo *addOptionImpl(const AbstractOption &settings) override; - - PrivateImplPointer impl_; - - //! Needed to be able to extend the interface of this object. - friend class OptionsAssigner; +public: + //! Initializes an empty options root container. + Options(); + ~Options() override; + + /*! \brief + * Adds an option manager. + * + * \param manager Manager to add. + * \throws std::bad_alloc if out of memory. + * + * Option managers are used by some types of options that require + * interaction between different option instances (e.g., selection + * options), or need to support globally set properties (e.g., a global + * default file prefix). Option objects can retrieve the pointer to + * their manager when they are created, and the caller can alter the + * behavior of the options through the manager. + * See the individual managers for details. + * + * Caller is responsible for memory management of \p manager. + * The Options object (and its contained options) only stores a + * reference to the object. + * + * This method cannot be called after adding options or sections. + */ + void addManager(IOptionManager* manager); + + // From IOptionsContainer + IOptionsContainer& addGroup() override; + + //! Returns a handle to the root section. + OptionSectionInfo& rootSection(); + //! Returns a handle to the root section. + const OptionSectionInfo& rootSection() const; + + /*! \brief + * Notifies the collection that all option values are assigned. + * + * \throws InvalidInputError if invalid user input is detected. + * + * This function should be called after no more option values are + * to be assigned. Values in storage variables are guaranteed to be + * available only after this call, although in most cases, they are + * available already during assignment. + * + * If invalid option values, e.g., missing required option, is detected + * at this point, this function throws. The thrown exception contains + * information on all errors detected during the call. + */ + void finish(); + +private: + // From IOptionsContainerWithSections + internal::OptionSectionImpl* addSectionImpl(const AbstractOptionSection& section) override; + // From IOptionsContainer + OptionInfo* addOptionImpl(const AbstractOption& settings) override; + + PrivateImplPointer impl_; + + //! Needed to be able to extend the interface of this object. + friend class OptionsAssigner; }; } // namespace gmx diff --git a/src/gromacs/options/options_impl.h b/src/gromacs/options/options_impl.h index 2dd5a149c1..b72219faa0 100644 --- a/src/gromacs/options/options_impl.h +++ b/src/gromacs/options/options_impl.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -78,123 +79,126 @@ namespace internal */ class OptionSectionImpl : public IOptionsContainerWithSections { +public: + /*! \internal \brief + * Describes a group of options (see Options::addGroup()). + * + * \ingroup module_options + */ + class Group : public IOptionsContainer + { public: - /*! \internal \brief - * Describes a group of options (see Options::addGroup()). - * - * \ingroup module_options - */ - class Group : public IOptionsContainer - { - public: - //! Convenience typedef for list of options. - typedef std::vector OptionList; - //! Convenience typedef for list of subgroups. - typedef std::list SubgroupList; - - //! Creates a group within the given Options. - explicit Group(OptionSectionImpl *parent) : parent_(parent) {} - - // From IOptionsContainer - IOptionsContainer &addGroup() override; - OptionInfo *addOptionImpl(const AbstractOption &settings) override; - - //! Containing options object. - OptionSectionImpl *parent_; - /*! \brief - * List of options, in insertion order. - * - * Pointers in this container point to the objects managed by - * Impl::optionsMap_. - */ - OptionList options_; - //! List of groups, in insertion order. - SubgroupList subgroups_; - }; - - //! Smart pointer for managing an AbstractOptionStorage object. - typedef std::unique_ptr - AbstractOptionStoragePointer; - //! Convenience typedef for a map that contains all the options. - typedef std::map OptionMap; - //! Smart pointer for managing subsections. - typedef std::unique_ptr SectionPointer; - //! Convenience typedef for a container for subsections. - typedef std::vector SectionList; - - //! Creates storage for a new section. - OptionSectionImpl(const OptionManagerContainer &managers, - std::unique_ptr storage, - const char *name) - : managers_(managers), storage_(std::move(storage)), info_(this), - name_(name), rootGroup_(this), storageInitialized_(false) - { - } - - // From IOptionsContainerWithSections - OptionSectionImpl *addSectionImpl(const AbstractOptionSection §ion) override; + //! Convenience typedef for list of options. + typedef std::vector OptionList; + //! Convenience typedef for list of subgroups. + typedef std::list SubgroupList; - // From IOptionsContainer - IOptionsContainer &addGroup() override; - OptionInfo *addOptionImpl(const AbstractOption &settings) override; + //! Creates a group within the given Options. + explicit Group(OptionSectionImpl* parent) : parent_(parent) {} - //! Returns section info object for this section. - OptionSectionInfo &info() { return info_; } - //! Returns section info object for this section. - const OptionSectionInfo &info() const { return info_; } - - /*! \brief - * Finds a subsection by name. - * - * \param[in] name Name to search for. - * \returns Pointer to the found subsection, or NULL if not found. - * - * Does not throw. - */ - OptionSectionImpl *findSection(const char *name) const; - /*! \brief - * Finds an option by name. - * - * \param[in] name Name to search for. - * \returns Pointer to the found option, or NULL if not found. - * - * Does not throw. - */ - AbstractOptionStorage *findOption(const char *name) const; + // From IOptionsContainer + IOptionsContainer& addGroup() override; + OptionInfo* addOptionImpl(const AbstractOption& settings) override; + //! Containing options object. + OptionSectionImpl* parent_; /*! \brief - * Called when entering the section. + * List of options, in insertion order. * - * Calls AbstractOptionStorage::startSource() for all options. - */ - void start(); - /*! \brief - * Calls AbstractOptionStorage::finish() for all options. + * Pointers in this container point to the objects managed by + * Impl::optionsMap_. */ - void finish(); - - //! Reference to the option managers in the parent Options object. - const OptionManagerContainer &managers_; - //! Type-specific storage object for this section. - std::unique_ptr storage_; - //! Info object for this section. - OptionSectionInfo info_; - //! Name of this section (empty and unused for the root section). - std::string name_; - /*! \brief - * Group that contains all options (and subgroups). - * - * This is used to store the insertion order of options. - */ - Group rootGroup_; - //! Map from option names to options; owns the option storage objects. - OptionMap optionMap_; - //! List of subsections, in insertion order. - SectionList subsections_; - //! Whether initStorage() has been called for `storage_`. - bool storageInitialized_; - - GMX_DISALLOW_COPY_AND_ASSIGN(OptionSectionImpl); + OptionList options_; + //! List of groups, in insertion order. + SubgroupList subgroups_; + }; + + //! Smart pointer for managing an AbstractOptionStorage object. + typedef std::unique_ptr AbstractOptionStoragePointer; + //! Convenience typedef for a map that contains all the options. + typedef std::map OptionMap; + //! Smart pointer for managing subsections. + typedef std::unique_ptr SectionPointer; + //! Convenience typedef for a container for subsections. + typedef std::vector SectionList; + + //! Creates storage for a new section. + OptionSectionImpl(const OptionManagerContainer& managers, + std::unique_ptr storage, + const char* name) : + managers_(managers), + storage_(std::move(storage)), + info_(this), + name_(name), + rootGroup_(this), + storageInitialized_(false) + { + } + + // From IOptionsContainerWithSections + OptionSectionImpl* addSectionImpl(const AbstractOptionSection& section) override; + + // From IOptionsContainer + IOptionsContainer& addGroup() override; + OptionInfo* addOptionImpl(const AbstractOption& settings) override; + + //! Returns section info object for this section. + OptionSectionInfo& info() { return info_; } + //! Returns section info object for this section. + const OptionSectionInfo& info() const { return info_; } + + /*! \brief + * Finds a subsection by name. + * + * \param[in] name Name to search for. + * \returns Pointer to the found subsection, or NULL if not found. + * + * Does not throw. + */ + OptionSectionImpl* findSection(const char* name) const; + /*! \brief + * Finds an option by name. + * + * \param[in] name Name to search for. + * \returns Pointer to the found option, or NULL if not found. + * + * Does not throw. + */ + AbstractOptionStorage* findOption(const char* name) const; + + /*! \brief + * Called when entering the section. + * + * Calls AbstractOptionStorage::startSource() for all options. + */ + void start(); + /*! \brief + * Calls AbstractOptionStorage::finish() for all options. + */ + void finish(); + + //! Reference to the option managers in the parent Options object. + const OptionManagerContainer& managers_; + //! Type-specific storage object for this section. + std::unique_ptr storage_; + //! Info object for this section. + OptionSectionInfo info_; + //! Name of this section (empty and unused for the root section). + std::string name_; + /*! \brief + * Group that contains all options (and subgroups). + * + * This is used to store the insertion order of options. + */ + Group rootGroup_; + //! Map from option names to options; owns the option storage objects. + OptionMap optionMap_; + //! List of subsections, in insertion order. + SectionList subsections_; + //! Whether initStorage() has been called for `storage_`. + bool storageInitialized_; + + GMX_DISALLOW_COPY_AND_ASSIGN(OptionSectionImpl); }; /*! \internal @@ -208,13 +212,13 @@ class OptionSectionImpl : public IOptionsContainerWithSections */ class OptionsImpl { - public: - OptionsImpl(); +public: + OptionsImpl(); - //! Option managers set for this collection. - OptionManagerContainer managers_; - //! Root section for this collection. - OptionSectionImpl rootSection_; + //! Option managers set for this collection. + OptionManagerContainer managers_; + //! Root section for this collection. + OptionSectionImpl rootSection_; }; } // namespace internal diff --git a/src/gromacs/options/optionsassigner.cpp b/src/gromacs/options/optionsassigner.cpp index d2b9856e96..4b8a0f0792 100644 --- a/src/gromacs/options/optionsassigner.cpp +++ b/src/gromacs/options/optionsassigner.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,66 +68,68 @@ namespace gmx */ class OptionsAssigner::Impl { - public: - //! Shorthand for the internal type used to represent a section. - typedef internal::OptionSectionImpl Section; +public: + //! Shorthand for the internal type used to represent a section. + typedef internal::OptionSectionImpl Section; - //! Sets the option object to assign to. - explicit Impl(Options *options); + //! Sets the option object to assign to. + explicit Impl(Options* options); - //! Returns true if a subsection has been set. - bool inSection() const { return sectionStack_.size() > 1; } - //! Returns the Options object for the current section. - Section ¤tSection() const { return *sectionStack_.back(); } - /*! \brief - * Finds an option by the given name. - * - * \param[in] name Name of the option to look for. - * \returns Pointer to the found option, or NULL if none found. - * - * This function takes into account the flags specified, and may change - * the internal state of the assigner to match the option found. - * If no option is found, the internal state is not modified. - */ - AbstractOptionStorage *findOption(const char *name); + //! Returns true if a subsection has been set. + bool inSection() const { return sectionStack_.size() > 1; } + //! Returns the Options object for the current section. + Section& currentSection() const { return *sectionStack_.back(); } + /*! \brief + * Finds an option by the given name. + * + * \param[in] name Name of the option to look for. + * \returns Pointer to the found option, or NULL if none found. + * + * This function takes into account the flags specified, and may change + * the internal state of the assigner to match the option found. + * If no option is found, the internal state is not modified. + */ + AbstractOptionStorage* findOption(const char* name); - //! Options object to assign to. - Options &options_; - //! Recognize boolean option "name" also as "noname". - bool bAcceptBooleanNoPrefix_; - /*! \brief - * List of (sub)sections being assigned to. - * - * The first element always points to \a options_. - */ - std::vector
sectionStack_; - //! Current option being assigned to, or NULL if none. - AbstractOptionStorage *currentOption_; - /*! \brief - * Number of values assigned so far to the current option. - * - * Counts the number of attempted assignments, whether they have been - * successful or not. - */ - int currentValueCount_; - //! If true, a "no" prefix was given for the current boolean option. - bool reverseBoolean_; + //! Options object to assign to. + Options& options_; + //! Recognize boolean option "name" also as "noname". + bool bAcceptBooleanNoPrefix_; + /*! \brief + * List of (sub)sections being assigned to. + * + * The first element always points to \a options_. + */ + std::vector sectionStack_; + //! Current option being assigned to, or NULL if none. + AbstractOptionStorage* currentOption_; + /*! \brief + * Number of values assigned so far to the current option. + * + * Counts the number of attempted assignments, whether they have been + * successful or not. + */ + int currentValueCount_; + //! If true, a "no" prefix was given for the current boolean option. + bool reverseBoolean_; }; -OptionsAssigner::Impl::Impl(Options *options) - : options_(*options), bAcceptBooleanNoPrefix_(false), - currentOption_(nullptr), currentValueCount_(0), reverseBoolean_(false) +OptionsAssigner::Impl::Impl(Options* options) : + options_(*options), + bAcceptBooleanNoPrefix_(false), + currentOption_(nullptr), + currentValueCount_(0), + reverseBoolean_(false) { sectionStack_.push_back(&options_.impl_->rootSection_); } -AbstractOptionStorage * -OptionsAssigner::Impl::findOption(const char *name) +AbstractOptionStorage* OptionsAssigner::Impl::findOption(const char* name) { GMX_RELEASE_ASSERT(currentOption_ == nullptr, "Cannot search for another option while processing one"); - const Section §ion = currentSection(); - AbstractOptionStorage *option = section.findOption(name); + const Section& section = currentSection(); + AbstractOptionStorage* option = section.findOption(name); if (option == nullptr && bAcceptBooleanNoPrefix_) { if (name[0] == 'n' && name[1] == 'o') @@ -149,14 +152,9 @@ OptionsAssigner::Impl::findOption(const char *name) * OptionsAssigner */ -OptionsAssigner::OptionsAssigner(Options *options) - : impl_(new Impl(options)) -{ -} +OptionsAssigner::OptionsAssigner(Options* options) : impl_(new Impl(options)) {} -OptionsAssigner::~OptionsAssigner() -{ -} +OptionsAssigner::~OptionsAssigner() {} void OptionsAssigner::setAcceptBooleanNoPrefix(bool bEnabled) { @@ -168,9 +166,9 @@ void OptionsAssigner::start() impl_->options_.impl_->rootSection_.start(); } -void OptionsAssigner::startSection(const char *name) +void OptionsAssigner::startSection(const char* name) { - Impl::Section *section = impl_->currentSection().findSection(name); + Impl::Section* section = impl_->currentSection().findSection(name); if (section == nullptr) { GMX_THROW(InvalidInputError("Unknown subsection")); @@ -179,7 +177,7 @@ void OptionsAssigner::startSection(const char *name) section->start(); } -void OptionsAssigner::startOption(const char *name) +void OptionsAssigner::startOption(const char* name) { if (!tryStartOption(name)) { @@ -187,10 +185,10 @@ void OptionsAssigner::startOption(const char *name) } } -bool OptionsAssigner::tryStartOption(const char *name) +bool OptionsAssigner::tryStartOption(const char* name) { GMX_RELEASE_ASSERT(impl_->currentOption_ == nullptr, "finishOption() not called"); - AbstractOptionStorage *option = impl_->findOption(name); + AbstractOptionStorage* option = impl_->findOption(name); if (option == nullptr) { return false; @@ -201,14 +199,14 @@ bool OptionsAssigner::tryStartOption(const char *name) return true; } -void OptionsAssigner::appendValue(const std::string &value) +void OptionsAssigner::appendValue(const std::string& value) { appendValue(Any(value)); } -void OptionsAssigner::appendValue(const Any &value) +void OptionsAssigner::appendValue(const Any& value) { - AbstractOptionStorage *option = impl_->currentOption_; + AbstractOptionStorage* option = impl_->currentOption_; GMX_RELEASE_ASSERT(option != nullptr, "startOption() not called"); ++impl_->currentValueCount_; option->appendValue(value); @@ -216,9 +214,9 @@ void OptionsAssigner::appendValue(const Any &value) void OptionsAssigner::finishOption() { - AbstractOptionStorage *option = impl_->currentOption_; + AbstractOptionStorage* option = impl_->currentOption_; GMX_RELEASE_ASSERT(option != nullptr, "startOption() not called"); - bool bBoolReverseValue = false; + bool bBoolReverseValue = false; if (option->isBoolean()) { if (impl_->currentValueCount_ == 0) @@ -244,7 +242,7 @@ void OptionsAssigner::finishSection() { // Should only be called if we are in a subsection. GMX_RELEASE_ASSERT(impl_->inSection(), "startSection() not called"); - Impl::Section *section = impl_->sectionStack_.back(); + Impl::Section* section = impl_->sectionStack_.back(); section->finish(); impl_->sectionStack_.pop_back(); } diff --git a/src/gromacs/options/optionsassigner.h b/src/gromacs/options/optionsassigner.h index a07892fe04..df1ea44ff0 100644 --- a/src/gromacs/options/optionsassigner.h +++ b/src/gromacs/options/optionsassigner.h @@ -87,126 +87,126 @@ class Any; */ class OptionsAssigner { - public: - /*! \brief - * Creates an object that assigns to the given object. - */ - explicit OptionsAssigner(Options *options); - ~OptionsAssigner(); +public: + /*! \brief + * Creates an object that assigns to the given object. + */ + explicit OptionsAssigner(Options* options); + ~OptionsAssigner(); - /*! \brief - * Sets the assigner to recognize boolean options with a "no" prefix. - * - * With this option set, \c startOption("noname") is interpreted as - * \c startOption("name") followed by \c appendValue("no"), if there is - * no option by the name "noname", but there is a boolean option with - * name "name". - * - * By default, the prefix is not recognized. - * - * Can be set or cleared at any time, and will have effect on all - * subsequent calls of startOption(). - * - * Does not throw. - */ - void setAcceptBooleanNoPrefix(bool bEnabled); + /*! \brief + * Sets the assigner to recognize boolean options with a "no" prefix. + * + * With this option set, \c startOption("noname") is interpreted as + * \c startOption("name") followed by \c appendValue("no"), if there is + * no option by the name "noname", but there is a boolean option with + * name "name". + * + * By default, the prefix is not recognized. + * + * Can be set or cleared at any time, and will have effect on all + * subsequent calls of startOption(). + * + * Does not throw. + */ + void setAcceptBooleanNoPrefix(bool bEnabled); - /*! \brief - * Starts assigning values. - * - * Does not throw. - */ - void start(); - /*! \brief - * Starts assigning values to options in a subsection. - * - * \param[in] name Name of the subsection to start assigning to. - * \throws InvalidInputError if such a subsection is not found. - * - * Strong exception safety guarantee. - */ - void startSection(const char *name); - /*! \brief - * Starts assigning values for an option. - * - * \param[in] name Name of the option to start assigning to. - * \throws InvalidInputError if such an option is not found, or if the - * option is specified more than once but doesn't support it. - */ - void startOption(const char *name); - /*! \brief - * Starts assigning values for an option. - * - * \param[in] name Name of the option to start assigning to. - * \returns true if \p name is a valid option name. - * \throws InvalidInputError if the option is specified more than once - * but doesn't support it. - */ - bool tryStartOption(const char *name); - /*! \brief - * Appends a value to the value list of the current option. - * - * \param[in] value Value to assign. - * \throws InvalidInputError if the value cannot be converted or if - * there are too many values for an option. - * - * Basic exception safety guarantee: - * If this method throws, erroneous values are ignored, but it is - * possible to continue assigning values to the same option. However, - * if \p value would result in more than one value, and some of them - * can be converted, but some result in errors, it is currently - * possible that some values have been added to the option even if an - * exception is thrown. - * - * Strong exception safety guarantee if the option provides value - * conversion with the same guarantee. All options where a single - * input value always results in a single output value provide this. - * - * \internal - * This method provides the same exception safety guarantee as the - * OptionStorageTemplate::convertValue() method of the storage class - * implementing the option where the value is assigned to. - */ - void appendValue(const Any &value); - /*! \brief - * Appends a value to the value list of the current option. - * - * \param[in] value Value to assign. - * - * See appendValue(const Any &) for more details. - */ - void appendValue(const std::string &value); - /*! \brief - * Finish assigning values for the current option. - * - * \throws InvalidInputError if the set of values since startOption() - * is not valid. - * - * If this method throws, it returns to the state where the option was - * before startOption(), i.e., all values added with appendValue() - * since the last startOption() are discarded. - * - * Independent of whether the method throws, the option opened with - * startOption() will be closed after the call. - */ - void finishOption(); - /*! \brief - * Finish assigning values to a subsection. - * - * Does not throw. - */ - void finishSection(); - /*! \brief - * Finish assigning options through the object. - * - * Does not throw. - */ - void finish(); + /*! \brief + * Starts assigning values. + * + * Does not throw. + */ + void start(); + /*! \brief + * Starts assigning values to options in a subsection. + * + * \param[in] name Name of the subsection to start assigning to. + * \throws InvalidInputError if such a subsection is not found. + * + * Strong exception safety guarantee. + */ + void startSection(const char* name); + /*! \brief + * Starts assigning values for an option. + * + * \param[in] name Name of the option to start assigning to. + * \throws InvalidInputError if such an option is not found, or if the + * option is specified more than once but doesn't support it. + */ + void startOption(const char* name); + /*! \brief + * Starts assigning values for an option. + * + * \param[in] name Name of the option to start assigning to. + * \returns true if \p name is a valid option name. + * \throws InvalidInputError if the option is specified more than once + * but doesn't support it. + */ + bool tryStartOption(const char* name); + /*! \brief + * Appends a value to the value list of the current option. + * + * \param[in] value Value to assign. + * \throws InvalidInputError if the value cannot be converted or if + * there are too many values for an option. + * + * Basic exception safety guarantee: + * If this method throws, erroneous values are ignored, but it is + * possible to continue assigning values to the same option. However, + * if \p value would result in more than one value, and some of them + * can be converted, but some result in errors, it is currently + * possible that some values have been added to the option even if an + * exception is thrown. + * + * Strong exception safety guarantee if the option provides value + * conversion with the same guarantee. All options where a single + * input value always results in a single output value provide this. + * + * \internal + * This method provides the same exception safety guarantee as the + * OptionStorageTemplate::convertValue() method of the storage class + * implementing the option where the value is assigned to. + */ + void appendValue(const Any& value); + /*! \brief + * Appends a value to the value list of the current option. + * + * \param[in] value Value to assign. + * + * See appendValue(const Any &) for more details. + */ + void appendValue(const std::string& value); + /*! \brief + * Finish assigning values for the current option. + * + * \throws InvalidInputError if the set of values since startOption() + * is not valid. + * + * If this method throws, it returns to the state where the option was + * before startOption(), i.e., all values added with appendValue() + * since the last startOption() are discarded. + * + * Independent of whether the method throws, the option opened with + * startOption() will be closed after the call. + */ + void finishOption(); + /*! \brief + * Finish assigning values to a subsection. + * + * Does not throw. + */ + void finishSection(); + /*! \brief + * Finish assigning options through the object. + * + * Does not throw. + */ + void finish(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/options/optionsection.cpp b/src/gromacs/options/optionsection.cpp index 5d0afdeff7..a8f4a263e4 100644 --- a/src/gromacs/options/optionsection.cpp +++ b/src/gromacs/options/optionsection.cpp @@ -48,13 +48,13 @@ namespace class OptionSectionStorage : public IOptionSectionStorage { - public: - void initStorage() override {} - void startSection() override {} - void finishSection() override {} +public: + void initStorage() override {} + void startSection() override {} + void finishSection() override {} }; -} // namespace +} // namespace std::unique_ptr OptionSection::createStorage() const { diff --git a/src/gromacs/options/optionsection.h b/src/gromacs/options/optionsection.h index 2135626839..0af38875c7 100644 --- a/src/gromacs/options/optionsection.h +++ b/src/gromacs/options/optionsection.h @@ -64,15 +64,15 @@ class OptionSectionHandle; */ class OptionSection : public AbstractOptionSection { - public: - //! AbstractOptionSectionHandle corresponding to this option type. - typedef OptionSectionHandle HandleType; +public: + //! AbstractOptionSectionHandle corresponding to this option type. + typedef OptionSectionHandle HandleType; - //! Creates a section with the given name. - explicit OptionSection(const char *name) : AbstractOptionSection(name) {} + //! Creates a section with the given name. + explicit OptionSection(const char* name) : AbstractOptionSection(name) {} - private: - std::unique_ptr createStorage() const override; +private: + std::unique_ptr createStorage() const override; }; /*! \brief @@ -87,22 +87,22 @@ class OptionSection : public AbstractOptionSection */ class OptionSectionHandle : public AbstractOptionSectionHandle { - public: - //! Wraps a given section storage object. - explicit OptionSectionHandle(internal::OptionSectionImpl *section) - : AbstractOptionSectionHandle(section) - { - } +public: + //! Wraps a given section storage object. + explicit OptionSectionHandle(internal::OptionSectionImpl* section) : + AbstractOptionSectionHandle(section) + { + } }; class OptionSectionInfo : public AbstractOptionSectionInfo { - public: - //! Wraps a given section storage object. - explicit OptionSectionInfo(internal::OptionSectionImpl *section) - : AbstractOptionSectionInfo(section) - { - } +public: + //! Wraps a given section storage object. + explicit OptionSectionInfo(internal::OptionSectionImpl* section) : + AbstractOptionSectionInfo(section) + { + } }; } // namespace gmx diff --git a/src/gromacs/options/optionstoragetemplate.h b/src/gromacs/options/optionstoragetemplate.h index 4a28e2f151..692dd8c877 100644 --- a/src/gromacs/options/optionstoragetemplate.h +++ b/src/gromacs/options/optionstoragetemplate.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -85,201 +86,193 @@ class Options; * \inlibraryapi * \ingroup module_options */ -template +template class OptionStorageTemplate : public AbstractOptionStorage { - public: - //! Alias for the template class for use in base classes. - typedef OptionStorageTemplate MyBase; - //! Type of the container that contains the current values. - typedef std::vector ValueList; - - // No implementation in this class for the pure virtual methods, but - // the declarations are still included for clarity. - // The various copydoc calls are needed with Doxygen 1.8.10, although - // things work without with 1.8.5... - std::string typeString() const override = 0; - //! \copydoc gmx::AbstractOptionStorage::valueCount() - int valueCount() const override { return store_->valueCount(); } - //! \copydoc gmx::AbstractOptionStorage::defaultValues() - std::vector defaultValues() const override; - /*! \copydoc gmx::AbstractOptionStorage::defaultValuesAsStrings() - * - * OptionStorageTemplate implements handling of defaultValueIfSet() - * cases and composing the vector. - * Derived classes must implement formatSingleValue() to provide the - * actual formatting for a value of type \p T. - */ - std::vector defaultValuesAsStrings() const override; - - protected: - //! Smart pointer for managing the final storage interface. - typedef std::unique_ptr > StorePointer; - - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Option settings. - * \param[in] staticFlags Option flags that are always set and specify - * generic behavior of the option. - * \throws APIError if invalid settings have been provided. - */ - template - explicit OptionStorageTemplate(const OptionTemplate &settings, - OptionFlags staticFlags = OptionFlags()); - /*! \brief - * Initializes the storage from base option settings. - * - * \param[in] settings Option settings. - * \param[in] store Final storage location. - * \throws APIError if invalid settings have been provided. - * - * This constructor works for cases where there is no matching - * OptionTemplate (e.g., EnumOption). - */ - OptionStorageTemplate(const AbstractOption &settings, - StorePointer store); - - //! \copydoc gmx::AbstractOptionStorage::clearSet() - void clearSet() override; - /*! \copydoc gmx::AbstractOptionStorage::convertValue() - * - * Derived classes should call addValue() after they have converted - * \p value to the storage type. It is allowed to call addValue() - * more than once, or not at all. OptionsAssigner::appendValue() - * provides the same exception safety guarantee as this method, so it - * should be considered whether the implementation can be made strongly - * exception safe. - */ - void convertValue(const Any &value) override = 0; - /*! \brief - * Processes values for a set after all have been converted. - * - * \param[in,out] values Valid values in the set. - * \throws InvalidInputError if the values do not form a valid set. - * - * This method is called after all convertValue() calls for a set. - * \p values contains all values that were validly converted by - * convertValue(). The derived class may alter the values, but should - * in such a case ensure that a correct number of values is produced. - * If the derived class throws, all values in \p values are discarded. - */ - virtual void processSetValues(ValueList *values) - { - GMX_UNUSED_VALUE(values); - } - /*! \copydoc gmx::AbstractOptionStorage::processSet() - * - * OptionStorageTemplate implements transaction support for a set of - * values in this method (see the class description), and provides a - * more detailed processSetValues() method that can be overridden in - * subclasses to process the actual values. Derived classes should - * override that method instead of this one if set value processing is - * necessary. - */ - void processSet() override; - /*! \copydoc gmx::AbstractOptionStorage::processAll() - * - * The implementation in OptionStorageTemplate does nothing. - */ - void processAll() override - { - } - /*! \brief - * Formats a single value as a string. - * - * \param[in] value Value to format. - * \returns \p value formatted as a string. - * - * The derived class must provide this method to format values a - * strings. Called by defaultValuesAsStrings() to do the actual - * formatting. - */ - virtual std::string formatSingleValue(const T &value) const = 0; - - /*! \brief - * Adds a value to a temporary storage. - * - * \param[in] value Value to add. A copy is made. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if the maximum value count has been reached. - * - * Derived classes should call this function from the convertValue() - * implementation to add converted values to the storage. - * If the maximum value count has been reached, the value is discarded - * and an exception is thrown. - * - * If adding values outside convertValue() (e.g., to set a custom - * default value), derived classes should call clearSet() before adding - * values (unless in the constructor) and commitValues() once all - * values are added. - */ - void addValue(const T &value); - /*! \brief - * Commits values added with addValue(). - * - * \throws std::bad_alloc if out of memory. - * - * If this function succeeds, values added with addValue() since the - * previous clearSet() are added to the storage for the option. - * Only throws in out-of-memory conditions, and provides the strong - * exception safety guarantee as long as the copy constructor of `T` - * does not throw. - * - * See addValue() for cases where this method should be used in derived - * classes. - * - * Calls clearSet() if it is successful. - */ - void commitValues(); - - /*! \brief - * Sets the default value for the option. - * - * \param[in] value Default value to set. - * \throws std::bad_alloc if out of memory. - * - * This method can be used from the derived class constructor to - * programmatically set a default value. - */ - void setDefaultValue(const T &value); - /*! \brief - * Sets the default value if set for the option. - * - * \param[in] value Default value to set. - * \throws std::bad_alloc if out of memory. - * - * This method can be used from the derived class constructor to - * programmatically set a default value. - */ - void setDefaultValueIfSet(const T &value); - - /*! \brief - * Provides derived classes access to the current list of values. - * - * The non-const any should only be used from processAll() in - * derived classes if necessary. - */ - ArrayRef values() { return store_->values(); } - //! Provides derived classes access to the current list of values. - ArrayRef values() const { return store_->values(); } - - private: - //! Creates the internal storage object for final values.. - StorePointer createStore(ValueList *storeVector, - T *store, int *storeCount, - int initialCount); - - /*! \brief - * Vector for temporary storage of values before commitSet() is called. - */ - ValueList setValues_; - //! Final storage for option values. - const StorePointer store_; - // This never releases ownership. - std::unique_ptr defaultValueIfSet_; - - // Copy and assign disallowed by base. +public: + //! Alias for the template class for use in base classes. + typedef OptionStorageTemplate MyBase; + //! Type of the container that contains the current values. + typedef std::vector ValueList; + + // No implementation in this class for the pure virtual methods, but + // the declarations are still included for clarity. + // The various copydoc calls are needed with Doxygen 1.8.10, although + // things work without with 1.8.5... + std::string typeString() const override = 0; + //! \copydoc gmx::AbstractOptionStorage::valueCount() + int valueCount() const override { return store_->valueCount(); } + //! \copydoc gmx::AbstractOptionStorage::defaultValues() + std::vector defaultValues() const override; + /*! \copydoc gmx::AbstractOptionStorage::defaultValuesAsStrings() + * + * OptionStorageTemplate implements handling of defaultValueIfSet() + * cases and composing the vector. + * Derived classes must implement formatSingleValue() to provide the + * actual formatting for a value of type \p T. + */ + std::vector defaultValuesAsStrings() const override; + +protected: + //! Smart pointer for managing the final storage interface. + typedef std::unique_ptr> StorePointer; + + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Option settings. + * \param[in] staticFlags Option flags that are always set and specify + * generic behavior of the option. + * \throws APIError if invalid settings have been provided. + */ + template + explicit OptionStorageTemplate(const OptionTemplate& settings, + OptionFlags staticFlags = OptionFlags()); + /*! \brief + * Initializes the storage from base option settings. + * + * \param[in] settings Option settings. + * \param[in] store Final storage location. + * \throws APIError if invalid settings have been provided. + * + * This constructor works for cases where there is no matching + * OptionTemplate (e.g., EnumOption). + */ + OptionStorageTemplate(const AbstractOption& settings, StorePointer store); + + //! \copydoc gmx::AbstractOptionStorage::clearSet() + void clearSet() override; + /*! \copydoc gmx::AbstractOptionStorage::convertValue() + * + * Derived classes should call addValue() after they have converted + * \p value to the storage type. It is allowed to call addValue() + * more than once, or not at all. OptionsAssigner::appendValue() + * provides the same exception safety guarantee as this method, so it + * should be considered whether the implementation can be made strongly + * exception safe. + */ + void convertValue(const Any& value) override = 0; + /*! \brief + * Processes values for a set after all have been converted. + * + * \param[in,out] values Valid values in the set. + * \throws InvalidInputError if the values do not form a valid set. + * + * This method is called after all convertValue() calls for a set. + * \p values contains all values that were validly converted by + * convertValue(). The derived class may alter the values, but should + * in such a case ensure that a correct number of values is produced. + * If the derived class throws, all values in \p values are discarded. + */ + virtual void processSetValues(ValueList* values) { GMX_UNUSED_VALUE(values); } + /*! \copydoc gmx::AbstractOptionStorage::processSet() + * + * OptionStorageTemplate implements transaction support for a set of + * values in this method (see the class description), and provides a + * more detailed processSetValues() method that can be overridden in + * subclasses to process the actual values. Derived classes should + * override that method instead of this one if set value processing is + * necessary. + */ + void processSet() override; + /*! \copydoc gmx::AbstractOptionStorage::processAll() + * + * The implementation in OptionStorageTemplate does nothing. + */ + void processAll() override {} + /*! \brief + * Formats a single value as a string. + * + * \param[in] value Value to format. + * \returns \p value formatted as a string. + * + * The derived class must provide this method to format values a + * strings. Called by defaultValuesAsStrings() to do the actual + * formatting. + */ + virtual std::string formatSingleValue(const T& value) const = 0; + + /*! \brief + * Adds a value to a temporary storage. + * + * \param[in] value Value to add. A copy is made. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if the maximum value count has been reached. + * + * Derived classes should call this function from the convertValue() + * implementation to add converted values to the storage. + * If the maximum value count has been reached, the value is discarded + * and an exception is thrown. + * + * If adding values outside convertValue() (e.g., to set a custom + * default value), derived classes should call clearSet() before adding + * values (unless in the constructor) and commitValues() once all + * values are added. + */ + void addValue(const T& value); + /*! \brief + * Commits values added with addValue(). + * + * \throws std::bad_alloc if out of memory. + * + * If this function succeeds, values added with addValue() since the + * previous clearSet() are added to the storage for the option. + * Only throws in out-of-memory conditions, and provides the strong + * exception safety guarantee as long as the copy constructor of `T` + * does not throw. + * + * See addValue() for cases where this method should be used in derived + * classes. + * + * Calls clearSet() if it is successful. + */ + void commitValues(); + + /*! \brief + * Sets the default value for the option. + * + * \param[in] value Default value to set. + * \throws std::bad_alloc if out of memory. + * + * This method can be used from the derived class constructor to + * programmatically set a default value. + */ + void setDefaultValue(const T& value); + /*! \brief + * Sets the default value if set for the option. + * + * \param[in] value Default value to set. + * \throws std::bad_alloc if out of memory. + * + * This method can be used from the derived class constructor to + * programmatically set a default value. + */ + void setDefaultValueIfSet(const T& value); + + /*! \brief + * Provides derived classes access to the current list of values. + * + * The non-const any should only be used from processAll() in + * derived classes if necessary. + */ + ArrayRef values() { return store_->values(); } + //! Provides derived classes access to the current list of values. + ArrayRef values() const { return store_->values(); } + +private: + //! Creates the internal storage object for final values.. + StorePointer createStore(ValueList* storeVector, T* store, int* storeCount, int initialCount); + + /*! \brief + * Vector for temporary storage of values before commitSet() is called. + */ + ValueList setValues_; + //! Final storage for option values. + const StorePointer store_; + // This never releases ownership. + std::unique_ptr defaultValueIfSet_; + + // Copy and assign disallowed by base. }; @@ -302,93 +295,88 @@ class OptionStorageTemplate : public AbstractOptionStorage * \inlibraryapi * \ingroup module_options */ -template +template class OptionStorageTemplateSimple : public OptionStorageTemplate { - public: - //! Alias for the template class for use in base classes. - typedef OptionStorageTemplateSimple MyBase; - - protected: - //! Alias for the converter parameter type for initConverter(). - typedef OptionValueConverterSimple ConverterType; - - //! Initializes the storage. - template - explicit OptionStorageTemplateSimple(const OptionTemplate &settings, - OptionFlags staticFlags = OptionFlags()) - : OptionStorageTemplate(settings, staticFlags), initialized_(false) - { - } - //! Initializes the storage. - OptionStorageTemplateSimple(const AbstractOption &settings, - typename OptionStorageTemplate::StorePointer store) - : OptionStorageTemplate(settings, std::move(store)), initialized_(false) - { - } - - std::vector - normalizeValues(const std::vector &values) const override - { - const_cast(this)->ensureConverterInitialized(); - std::vector result; - result.reserve(values.size()); - for (const auto &value : values) - { - result.push_back(normalizeValue(converter_.convert(value))); - } - return result; - } +public: + //! Alias for the template class for use in base classes. + typedef OptionStorageTemplateSimple MyBase; + +protected: + //! Alias for the converter parameter type for initConverter(). + typedef OptionValueConverterSimple ConverterType; + + //! Initializes the storage. + template + explicit OptionStorageTemplateSimple(const OptionTemplate& settings, + OptionFlags staticFlags = OptionFlags()) : + OptionStorageTemplate(settings, staticFlags), + initialized_(false) + { + } + //! Initializes the storage. + OptionStorageTemplateSimple(const AbstractOption& settings, + typename OptionStorageTemplate::StorePointer store) : + OptionStorageTemplate(settings, std::move(store)), + initialized_(false) + { + } - /*! \brief - * Specifies how different types are converted. - * - * See OptionValueConverterSimple for more details. - */ - virtual void initConverter(ConverterType *converter) = 0; - /*! \brief - * Post-processes a value after conversion to the output type. - * - * \param[in] value Value after conversion. - * \returns Value to store for the option. - * - * The default implementation only provides an identity mapping. - */ - virtual T processValue(const T &value) const - { - return value; - } - /*! \brief - * Converts a single value to normalized type. - * - * \param[in] value Value after conversion. - * \returns Value to store for the option. - * - * This can be overridden to serialize a different type than `T` - * when using the option with KeyValueTreeObject. - */ - virtual Any normalizeValue(const T &value) const + std::vector normalizeValues(const std::vector& values) const override + { + const_cast(this)->ensureConverterInitialized(); + std::vector result; + result.reserve(values.size()); + for (const auto& value : values) { - return Any::create(processValue(value)); + result.push_back(normalizeValue(converter_.convert(value))); } + return result; + } - private: - void convertValue(const Any &any) override - { - ensureConverterInitialized(); - this->addValue(processValue(converter_.convert(any))); - } - void ensureConverterInitialized() + /*! \brief + * Specifies how different types are converted. + * + * See OptionValueConverterSimple for more details. + */ + virtual void initConverter(ConverterType* converter) = 0; + /*! \brief + * Post-processes a value after conversion to the output type. + * + * \param[in] value Value after conversion. + * \returns Value to store for the option. + * + * The default implementation only provides an identity mapping. + */ + virtual T processValue(const T& value) const { return value; } + /*! \brief + * Converts a single value to normalized type. + * + * \param[in] value Value after conversion. + * \returns Value to store for the option. + * + * This can be overridden to serialize a different type than `T` + * when using the option with KeyValueTreeObject. + */ + virtual Any normalizeValue(const T& value) const { return Any::create(processValue(value)); } + +private: + void convertValue(const Any& any) override + { + ensureConverterInitialized(); + this->addValue(processValue(converter_.convert(any))); + } + void ensureConverterInitialized() + { + if (!initialized_) { - if (!initialized_) - { - initConverter(&converter_); - initialized_ = true; - } + initConverter(&converter_); + initialized_ = true; } + } - ConverterType converter_; - bool initialized_; + ConverterType converter_; + bool initialized_; }; @@ -396,19 +384,18 @@ class OptionStorageTemplateSimple : public OptionStorageTemplate * OptionStorageTemplate implementation */ -template -template -OptionStorageTemplate::OptionStorageTemplate(const OptionTemplate &settings, - OptionFlags staticFlags) - : AbstractOptionStorage(settings, staticFlags), - store_(createStore(settings.storeVector_, - settings.store_, settings.countptr_, - (settings.isVector() ? - settings.maxValueCount_ : settings.minValueCount_))) +template +template +OptionStorageTemplate::OptionStorageTemplate(const OptionTemplate& settings, + OptionFlags staticFlags) : + AbstractOptionStorage(settings, staticFlags), + store_(createStore(settings.storeVector_, + settings.store_, + settings.countptr_, + (settings.isVector() ? settings.maxValueCount_ : settings.minValueCount_))) { if (hasFlag(efOption_NoDefaultValue) - && (settings.defaultValue_ != nullptr - || settings.defaultValueIfSet_ != nullptr)) + && (settings.defaultValue_ != nullptr || settings.defaultValueIfSet_ != nullptr)) { GMX_THROW(APIError("Option does not support default value, but one is set")); } @@ -427,19 +414,19 @@ OptionStorageTemplate::OptionStorageTemplate(const OptionTemplate &sett } -template -OptionStorageTemplate::OptionStorageTemplate(const AbstractOption &settings, - StorePointer store) - : AbstractOptionStorage(settings, OptionFlags()), store_(std::move(store)) +template +OptionStorageTemplate::OptionStorageTemplate(const AbstractOption& settings, StorePointer store) : + AbstractOptionStorage(settings, OptionFlags()), + store_(std::move(store)) { } -template -std::unique_ptr > OptionStorageTemplate::createStore( - ValueList *storeVector, T *store, - int *storeCount, // NOLINT(readability-non-const-parameter) passed non-const to OptionValueStorePlain - int initialCount) +template +std::unique_ptr> OptionStorageTemplate::createStore(ValueList* storeVector, + T* store, + int* storeCount, // NOLINT(readability-non-const-parameter) passed non-const to OptionValueStorePlain + int initialCount) { if (storeVector != nullptr) { @@ -457,7 +444,9 @@ std::unique_ptr > OptionStorageTemplate::createStore( } if (storeCount == nullptr && !isVector() && minValueCount() != maxValueCount()) { - GMX_THROW(APIError("Count storage is not set, although the number of produced values is not known")); + GMX_THROW( + APIError("Count storage is not set, although the number of produced values is " + "not known")); } if (hasFlag(efOption_NoDefaultValue)) { @@ -465,13 +454,12 @@ std::unique_ptr > OptionStorageTemplate::createStore( } return StorePointer(new OptionValueStorePlain(store, storeCount, initialCount)); } - GMX_RELEASE_ASSERT(storeCount == nullptr, - "Cannot specify count storage without value storage"); + GMX_RELEASE_ASSERT(storeCount == nullptr, "Cannot specify count storage without value storage"); return StorePointer(new OptionValueStoreNull()); } -template +template std::vector OptionStorageTemplate::defaultValues() const { std::vector result; @@ -479,9 +467,10 @@ std::vector OptionStorageTemplate::defaultValues() const { return result; } - GMX_RELEASE_ASSERT(hasFlag(efOption_HasDefaultValue), - "Current option implementation can only provide default values before assignment"); - for (const auto &value : values()) + GMX_RELEASE_ASSERT( + hasFlag(efOption_HasDefaultValue), + "Current option implementation can only provide default values before assignment"); + for (const auto& value : values()) { result.push_back(Any::create(value)); } @@ -489,7 +478,7 @@ std::vector OptionStorageTemplate::defaultValues() const } -template +template std::vector OptionStorageTemplate::defaultValuesAsStrings() const { std::vector result; @@ -497,9 +486,10 @@ std::vector OptionStorageTemplate::defaultValuesAsStrings() cons { return result; } - GMX_RELEASE_ASSERT(hasFlag(efOption_HasDefaultValue), - "Current option implementation can only provide default values before assignment"); - for (const auto &value : values()) + GMX_RELEASE_ASSERT( + hasFlag(efOption_HasDefaultValue), + "Current option implementation can only provide default values before assignment"); + for (const auto& value : values()) { result.push_back(formatSingleValue(value)); } @@ -515,14 +505,14 @@ std::vector OptionStorageTemplate::defaultValuesAsStrings() cons } -template +template void OptionStorageTemplate::clearSet() { setValues_.clear(); } -template +template void OptionStorageTemplate::processSet() { processSetValues(&setValues_); @@ -544,18 +534,17 @@ void OptionStorageTemplate::processSet() } -template -void OptionStorageTemplate::addValue(const T &value) +template +void OptionStorageTemplate::addValue(const T& value) { - if (maxValueCount() >= 0 - && setValues_.size() >= static_cast(maxValueCount())) + if (maxValueCount() >= 0 && setValues_.size() >= static_cast(maxValueCount())) { GMX_THROW(InvalidInputError("Too many values")); } setValues_.push_back(value); } -template +template void OptionStorageTemplate::commitValues() { if (hasFlag(efOption_ClearOnNextSet)) @@ -564,8 +553,10 @@ void OptionStorageTemplate::commitValues() } store_->reserve(setValues_.size()); // For bool the loop variable isn't a reference (it's its special reference type) + // clang-format off CLANG_DIAGNOSTIC_IGNORE(-Wrange-loop-analysis) - for (const auto &value : setValues_) + // clang-format on + for (const auto& value : setValues_) { store_->append(value); } @@ -573,8 +564,8 @@ void OptionStorageTemplate::commitValues() clearSet(); } -template -void OptionStorageTemplate::setDefaultValue(const T &value) +template +void OptionStorageTemplate::setDefaultValue(const T& value) { if (hasFlag(efOption_NoDefaultValue)) { @@ -589,8 +580,8 @@ void OptionStorageTemplate::setDefaultValue(const T &value) } -template -void OptionStorageTemplate::setDefaultValueIfSet(const T &value) +template +void OptionStorageTemplate::setDefaultValueIfSet(const T& value) { if (hasFlag(efOption_NoDefaultValue)) { diff --git a/src/gromacs/options/optionsvisitor.cpp b/src/gromacs/options/optionsvisitor.cpp index cb950a37fb..498dcf5cd0 100644 --- a/src/gromacs/options/optionsvisitor.cpp +++ b/src/gromacs/options/optionsvisitor.cpp @@ -56,55 +56,51 @@ namespace { //! Helper function to call visitOptions() and handle correct indirection. -void visitOption(OptionsVisitor *visitor, OptionInfo &optionInfo) //NOLINT(google-runtime-references) +void visitOption(OptionsVisitor* visitor, OptionInfo& optionInfo) //NOLINT(google-runtime-references) { visitor->visitOption(optionInfo); } //! Helper function to call visitOptions() and handle correct indirection. -void visitOption(OptionsModifyingVisitor *visitor, OptionInfo &optionInfo) //NOLINT(google-runtime-references) +void visitOption(OptionsModifyingVisitor* visitor, OptionInfo& optionInfo) //NOLINT(google-runtime-references) { visitor->visitOption(&optionInfo); } //! Helper function to recursively visit all options in a group. -template -void acceptOptionsGroup(const internal::OptionSectionImpl::Group &group, VisitorType *visitor) +template +void acceptOptionsGroup(const internal::OptionSectionImpl::Group& group, VisitorType* visitor) { - for (const auto &option : group.options_) + for (const auto& option : group.options_) { visitOption(visitor, option->optionInfo()); } - for (const auto &subgroup : group.subgroups_) + for (const auto& subgroup : group.subgroups_) { acceptOptionsGroup(subgroup, visitor); } } -} // namespace +} // namespace /******************************************************************** * OptionsIterator */ -OptionsIterator::OptionsIterator(const Options &options) - : section_(options.rootSection().section()) +OptionsIterator::OptionsIterator(const Options& options) : section_(options.rootSection().section()) { } -OptionsIterator::OptionsIterator(const OptionSectionInfo §ion) - : section_(section.section()) -{ -} +OptionsIterator::OptionsIterator(const OptionSectionInfo& section) : section_(section.section()) {} -void OptionsIterator::acceptSections(OptionsVisitor *visitor) const +void OptionsIterator::acceptSections(OptionsVisitor* visitor) const { - for (const auto §ion : section_.subsections_) + for (const auto& section : section_.subsections_) { visitor->visitSection(section->info()); } } -void OptionsIterator::acceptOptions(OptionsVisitor *visitor) const +void OptionsIterator::acceptOptions(OptionsVisitor* visitor) const { acceptOptionsGroup(section_.rootGroup_, visitor); } @@ -113,25 +109,25 @@ void OptionsIterator::acceptOptions(OptionsVisitor *visitor) const * OptionsModifyingIterator */ -OptionsModifyingIterator::OptionsModifyingIterator(Options *options) - : section_(options->rootSection().section()) +OptionsModifyingIterator::OptionsModifyingIterator(Options* options) : + section_(options->rootSection().section()) { } -OptionsModifyingIterator::OptionsModifyingIterator(OptionSectionInfo *section) - : section_(section->section()) +OptionsModifyingIterator::OptionsModifyingIterator(OptionSectionInfo* section) : + section_(section->section()) { } -void OptionsModifyingIterator::acceptSections(OptionsModifyingVisitor *visitor) const +void OptionsModifyingIterator::acceptSections(OptionsModifyingVisitor* visitor) const { - for (auto §ion : section_.subsections_) + for (auto& section : section_.subsections_) { visitor->visitSection(§ion->info()); } } -void OptionsModifyingIterator::acceptOptions(OptionsModifyingVisitor *visitor) const +void OptionsModifyingIterator::acceptOptions(OptionsModifyingVisitor* visitor) const { acceptOptionsGroup(section_.rootGroup_, visitor); } diff --git a/src/gromacs/options/optionsvisitor.h b/src/gromacs/options/optionsvisitor.h index 2b224449ba..d6ac5a5474 100644 --- a/src/gromacs/options/optionsvisitor.h +++ b/src/gromacs/options/optionsvisitor.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2014,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,13 +71,13 @@ class OptionSectionImpl; */ class OptionsVisitor { - public: - virtual ~OptionsVisitor() {} +public: + virtual ~OptionsVisitor() {} - //! Called for each section. - virtual void visitSection(const OptionSectionInfo §ion) = 0; - //! Called for each option. - virtual void visitOption(const OptionInfo &option) = 0; + //! Called for each section. + virtual void visitSection(const OptionSectionInfo& section) = 0; + //! Called for each option. + virtual void visitOption(const OptionInfo& option) = 0; }; /*! \libinternal \brief @@ -89,27 +89,27 @@ class OptionsVisitor * \inlibraryapi * \ingroup module_options */ -template +template class OptionsTypeVisitor : public OptionsVisitor { - public: - ~OptionsTypeVisitor() override {} +public: + ~OptionsTypeVisitor() override {} - void visitSection(const OptionSectionInfo §ion) override = 0; - /*! \brief - * Called for each option of type \p InfoType. - */ - virtual void visitOptionType(const InfoType &option) = 0; + void visitSection(const OptionSectionInfo& section) override = 0; + /*! \brief + * Called for each option of type \p InfoType. + */ + virtual void visitOptionType(const InfoType& option) = 0; - private: - void visitOption(const OptionInfo &option) override +private: + void visitOption(const OptionInfo& option) override + { + const InfoType* subtype = option.toType(); + if (subtype != NULL) { - const InfoType *subtype = option.toType(); - if (subtype != NULL) - { - visitOptionType(*subtype); - } + visitOptionType(*subtype); } + } }; /*! \libinternal \brief @@ -145,27 +145,27 @@ class OptionsTypeVisitor : public OptionsVisitor */ class OptionsIterator { - public: - /*! \brief - * Creates an object for visiting options in a Options object. - * - * The created iterator iterates over the "root" section in the Options - * object. - */ - explicit OptionsIterator(const Options &options); - //! Creates an object for visiting options in an options section. - explicit OptionsIterator(const OptionSectionInfo §ion); +public: + /*! \brief + * Creates an object for visiting options in a Options object. + * + * The created iterator iterates over the "root" section in the Options + * object. + */ + explicit OptionsIterator(const Options& options); + //! Creates an object for visiting options in an options section. + explicit OptionsIterator(const OptionSectionInfo& section); - //! Visits each section in the wrapped section. - void acceptSections(OptionsVisitor *visitor) const; - //! Visits each option in the wrapped section. - void acceptOptions(OptionsVisitor *visitor) const; + //! Visits each section in the wrapped section. + void acceptSections(OptionsVisitor* visitor) const; + //! Visits each option in the wrapped section. + void acceptOptions(OptionsVisitor* visitor) const; - private: - //! The wrapped section object. - const internal::OptionSectionImpl §ion_; +private: + //! The wrapped section object. + const internal::OptionSectionImpl& section_; - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator); + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsIterator); }; /*! \libinternal \brief @@ -179,13 +179,13 @@ class OptionsIterator */ class OptionsModifyingVisitor { - public: - virtual ~OptionsModifyingVisitor() {} +public: + virtual ~OptionsModifyingVisitor() {} - //! Called for each section. - virtual void visitSection(OptionSectionInfo *section) = 0; - //! Called for each option. - virtual void visitOption(OptionInfo *option) = 0; + //! Called for each section. + virtual void visitSection(OptionSectionInfo* section) = 0; + //! Called for each option. + virtual void visitOption(OptionInfo* option) = 0; }; /*! \libinternal \brief @@ -198,27 +198,27 @@ class OptionsModifyingVisitor * \inlibraryapi * \ingroup module_options */ -template +template class OptionsModifyingTypeVisitor : public OptionsModifyingVisitor { - public: - ~OptionsModifyingTypeVisitor() override {} +public: + ~OptionsModifyingTypeVisitor() override {} - void visitSection(OptionSectionInfo *section) override = 0; - /*! \brief - * Called for each option of type \p InfoType. - */ - virtual void visitOptionType(InfoType *option) = 0; + void visitSection(OptionSectionInfo* section) override = 0; + /*! \brief + * Called for each option of type \p InfoType. + */ + virtual void visitOptionType(InfoType* option) = 0; - private: - void visitOption(OptionInfo *option) override +private: + void visitOption(OptionInfo* option) override + { + InfoType* subtype = option->toType(); + if (subtype != nullptr) { - InfoType *subtype = option->toType(); - if (subtype != nullptr) - { - visitOptionType(subtype); - } + visitOptionType(subtype); } + } }; /*! \libinternal \brief @@ -234,27 +234,27 @@ class OptionsModifyingTypeVisitor : public OptionsModifyingVisitor */ class OptionsModifyingIterator { - public: - /*! \brief - * Creates an object for visiting options in a Options object. - * - * The created iterator iterates over the "root" section in the Options - * object. - */ - explicit OptionsModifyingIterator(Options *options); - //! Creates an object for visiting options in an options section. - explicit OptionsModifyingIterator(OptionSectionInfo *section); +public: + /*! \brief + * Creates an object for visiting options in a Options object. + * + * The created iterator iterates over the "root" section in the Options + * object. + */ + explicit OptionsModifyingIterator(Options* options); + //! Creates an object for visiting options in an options section. + explicit OptionsModifyingIterator(OptionSectionInfo* section); - //! Visits each section in the wrapped section. - void acceptSections(OptionsModifyingVisitor *visitor) const; - //! Visits each option in the wrapped section. - void acceptOptions(OptionsModifyingVisitor *visitor) const; + //! Visits each section in the wrapped section. + void acceptSections(OptionsModifyingVisitor* visitor) const; + //! Visits each option in the wrapped section. + void acceptOptions(OptionsModifyingVisitor* visitor) const; - private: - //! The wrapped section object. - internal::OptionSectionImpl §ion_; +private: + //! The wrapped section object. + internal::OptionSectionImpl& section_; - GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator); + GMX_DISALLOW_COPY_AND_ASSIGN(OptionsModifyingIterator); }; } // namespace gmx diff --git a/src/gromacs/options/repeatingsection.h b/src/gromacs/options/repeatingsection.h index 2a8e137fac..1521ea2b6c 100644 --- a/src/gromacs/options/repeatingsection.h +++ b/src/gromacs/options/repeatingsection.h @@ -55,8 +55,10 @@ namespace gmx { -template class RepeatingOptionSectionHandle; -template class RepeatingOptionSectionStorage; +template +class RepeatingOptionSectionHandle; +template +class RepeatingOptionSectionStorage; /*! \brief * Declares an option section that creates a structure for each instance. @@ -70,33 +72,34 @@ template class RepeatingOptionSectionStorage; * \inpublicapi * \ingroup module_options */ -template +template class RepeatingOptionSection : public AbstractOptionSection { - public: - //! AbstractOptionSectionHandle corresponding to this option type. - typedef RepeatingOptionSectionHandle HandleType; - - //! Creates a section with the given name. - explicit RepeatingOptionSection(const char *name) - : AbstractOptionSection(name), values_(nullptr) - { - } - - //! Specifies a vector to receive the section structures. - RepeatingOptionSection &storeVector(std::vector *values) - { - values_ = values; - return *this; - } - - private: - std::unique_ptr createStorage() const override; - - std::vector *values_; - - //! Allows accessing the properties when initializing the storage. - friend class RepeatingOptionSectionStorage; +public: + //! AbstractOptionSectionHandle corresponding to this option type. + typedef RepeatingOptionSectionHandle HandleType; + + //! Creates a section with the given name. + explicit RepeatingOptionSection(const char* name) : + AbstractOptionSection(name), + values_(nullptr) + { + } + + //! Specifies a vector to receive the section structures. + RepeatingOptionSection& storeVector(std::vector* values) + { + values_ = values; + return *this; + } + +private: + std::unique_ptr createStorage() const override; + + std::vector* values_; + + //! Allows accessing the properties when initializing the storage. + friend class RepeatingOptionSectionStorage; }; /*! \internal @@ -105,56 +108,48 @@ class RepeatingOptionSection : public AbstractOptionSection * * \ingroup module_options */ -template +template class RepeatingOptionSectionStorage : public IOptionSectionStorage { - public: - //! Initializes the storage for given section properties. - explicit RepeatingOptionSectionStorage(const RepeatingOptionSection §ion) - : store_(new OptionValueStoreVector(section.values_)), currentData_() - { - } - - void initStorage() override - { - defaultValues_ = currentData_; - } - void startSection() override - { - resetSection(); - } - void finishSection() override - { - store_->append(currentData_); - resetSection(); - } - - private: - void resetSection() - { - currentData_ = defaultValues_; - } - - //! Final storage location for the section structures. - const std::unique_ptr > store_; - T defaultValues_; - /*! \brief - * Stores the values for the current in-process section. - * - * Options within the section store their values to this structure, and - * they are then copied to the final storage when the section finishes. - */ - T currentData_; - - //! Allows binding option storage to the current section data structure. - friend class RepeatingOptionSectionHandle; +public: + //! Initializes the storage for given section properties. + explicit RepeatingOptionSectionStorage(const RepeatingOptionSection& section) : + store_(new OptionValueStoreVector(section.values_)), + currentData_() + { + } + + void initStorage() override { defaultValues_ = currentData_; } + void startSection() override { resetSection(); } + void finishSection() override + { + store_->append(currentData_); + resetSection(); + } + +private: + void resetSection() { currentData_ = defaultValues_; } + + //! Final storage location for the section structures. + const std::unique_ptr> store_; + T defaultValues_; + /*! \brief + * Stores the values for the current in-process section. + * + * Options within the section store their values to this structure, and + * they are then copied to the final storage when the section finishes. + */ + T currentData_; + + //! Allows binding option storage to the current section data structure. + friend class RepeatingOptionSectionHandle; }; -template +template std::unique_ptr RepeatingOptionSection::createStorage() const { - return std::make_unique >(*this); + return std::make_unique>(*this); } /*! \brief @@ -180,29 +175,26 @@ std::unique_ptr RepeatingOptionSection::createStorage( * \inpublicapi * \ingroup module_options */ -template +template class RepeatingOptionSectionHandle : public AbstractOptionSectionHandle { - public: - //! Wraps a given section storage object. - explicit RepeatingOptionSectionHandle(internal::OptionSectionImpl *section) - : AbstractOptionSectionHandle(section), - storage_(getStorage >(section)) - { - } - - /*! \brief - * Supports storing option values within the per-section data structure. - * - * See class documentation for an example. - */ - T &bind() - { - return storage_->currentData_; - } - - private: - RepeatingOptionSectionStorage *storage_; +public: + //! Wraps a given section storage object. + explicit RepeatingOptionSectionHandle(internal::OptionSectionImpl* section) : + AbstractOptionSectionHandle(section), + storage_(getStorage>(section)) + { + } + + /*! \brief + * Supports storing option values within the per-section data structure. + * + * See class documentation for an example. + */ + T& bind() { return storage_->currentData_; } + +private: + RepeatingOptionSectionStorage* storage_; }; } // namespace gmx diff --git a/src/gromacs/options/tests/abstractoptionstorage.cpp b/src/gromacs/options/tests/abstractoptionstorage.cpp index de0037b604..5f23659821 100644 --- a/src/gromacs/options/tests/abstractoptionstorage.cpp +++ b/src/gromacs/options/tests/abstractoptionstorage.cpp @@ -67,11 +67,11 @@ class MockOptionStorage; class MockOptionInfo : public gmx::OptionInfo { - public: - //! Creates an option info object for the given option. - explicit MockOptionInfo(MockOptionStorage *option); +public: + //! Creates an option info object for the given option. + explicit MockOptionInfo(MockOptionStorage* option); - MockOptionStorage &option(); + MockOptionStorage& option(); }; /*! \brief @@ -84,49 +84,39 @@ class MockOptionInfo : public gmx::OptionInfo */ class MockOptionStorage : public gmx::OptionStorageTemplate { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Storage settings. - */ - explicit MockOptionStorage(const MockOption &settings); - - /*! \brief - * Calls addValue("dummy") in the base class. - */ - void addDummyValue() - { - addValue("dummy"); - } - using MyBase::markAsSet; - using MyBase::addValue; - using MyBase::commitValues; - - gmx::OptionInfo &optionInfo() override { return info_; } - // These are not used. - std::string typeString() const override { return "mock"; } - std::string formatSingleValue(const std::string & /*value*/) const override - { - return ""; - } - std::vector - normalizeValues(const std::vector &values) const override - { - return values; - } - - void convertValue(const gmx::Any &value) override - { - convertValue(value.cast()); - } - - MOCK_METHOD1(convertValue, void(const std::string &value)); - MOCK_METHOD1(processSetValues, void(ValueList *values)); - MOCK_METHOD0(processAll, void()); - - private: - MockOptionInfo info_; +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Storage settings. + */ + explicit MockOptionStorage(const MockOption& settings); + + /*! \brief + * Calls addValue("dummy") in the base class. + */ + void addDummyValue() { addValue("dummy"); } + using MyBase::addValue; + using MyBase::commitValues; + using MyBase::markAsSet; + + gmx::OptionInfo& optionInfo() override { return info_; } + // These are not used. + std::string typeString() const override { return "mock"; } + std::string formatSingleValue(const std::string& /*value*/) const override { return ""; } + std::vector normalizeValues(const std::vector& values) const override + { + return values; + } + + void convertValue(const gmx::Any& value) override { convertValue(value.cast()); } + + MOCK_METHOD1(convertValue, void(const std::string& value)); + MOCK_METHOD1(processSetValues, void(ValueList* values)); + MOCK_METHOD0(processAll, void()); + +private: + MockOptionInfo info_; }; /*! \internal \brief @@ -136,42 +126,33 @@ class MockOptionStorage : public gmx::OptionStorageTemplate */ class MockOption : public gmx::OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef MockOptionInfo InfoType; - - //! Initializes an option with the given name. - explicit MockOption(const char *name) - : MyBase(name) - { - } - - private: - gmx::AbstractOptionStorage *createStorage( - const gmx::OptionManagerContainer & /*managers*/) const override - { - return new MockOptionStorage(*this); - } +public: + //! OptionInfo subclass corresponding to this option type. + typedef MockOptionInfo InfoType; + + //! Initializes an option with the given name. + explicit MockOption(const char* name) : MyBase(name) {} + +private: + gmx::AbstractOptionStorage* createStorage(const gmx::OptionManagerContainer& /*managers*/) const override + { + return new MockOptionStorage(*this); + } }; -MockOptionStorage::MockOptionStorage(const MockOption &settings) - : MyBase(settings), info_(this) +MockOptionStorage::MockOptionStorage(const MockOption& settings) : MyBase(settings), info_(this) { using ::testing::_; using ::testing::Invoke; using ::testing::WithArg; - ON_CALL(*this, convertValue(_)) - .WillByDefault(WithArg<0>(Invoke(this, &MockOptionStorage::addValue))); + ON_CALL(*this, convertValue(_)).WillByDefault(WithArg<0>(Invoke(this, &MockOptionStorage::addValue))); } -MockOptionInfo::MockOptionInfo(MockOptionStorage *option) - : gmx::OptionInfo(option) -{ -} +MockOptionInfo::MockOptionInfo(MockOptionStorage* option) : gmx::OptionInfo(option) {} -MockOptionStorage &MockOptionInfo::option() +MockOptionStorage& MockOptionInfo::option() { - return static_cast(gmx::OptionInfo::option()); + return static_cast(gmx::OptionInfo::option()); } /* @@ -180,19 +161,18 @@ MockOptionStorage &MockOptionInfo::option() */ TEST(AbstractOptionStorageTest, HandlesSetInFinish) { - gmx::Options options; - std::vector values; - MockOptionInfo *info = options.addOption( - MockOption("name").required().storeVector(&values)); - MockOptionStorage *mock = &info->option(); + gmx::Options options; + std::vector values; + MockOptionInfo* info = options.addOption(MockOption("name").required().storeVector(&values)); + MockOptionStorage* mock = &info->option(); { ::testing::InSequence dummy; using ::testing::DoAll; using ::testing::InvokeWithoutArgs; EXPECT_CALL(*mock, processAll()) - .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::markAsSet), - InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), - InvokeWithoutArgs(mock, &MockOptionStorage::commitValues))); + .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::markAsSet), + InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), + InvokeWithoutArgs(mock, &MockOptionStorage::commitValues))); } gmx::OptionsAssigner assigner(&options); @@ -210,19 +190,17 @@ TEST(AbstractOptionStorageTest, HandlesSetInFinish) */ TEST(AbstractOptionStorageTest, HandlesValueRemoval) { - gmx::Options options; - std::vector values; - MockOptionInfo *info = options.addOption( - MockOption("name").storeVector(&values).multiValue()); - MockOptionStorage *mock = &info->option(); + gmx::Options options; + std::vector values; + MockOptionInfo* info = options.addOption(MockOption("name").storeVector(&values).multiValue()); + MockOptionStorage* mock = &info->option(); { ::testing::InSequence dummy; using ::testing::ElementsAre; using ::testing::Pointee; using ::testing::Return; EXPECT_CALL(*mock, convertValue("a")); - EXPECT_CALL(*mock, convertValue("b")) - .WillOnce(Return()); + EXPECT_CALL(*mock, convertValue("b")).WillOnce(Return()); EXPECT_CALL(*mock, convertValue("c")); EXPECT_CALL(*mock, processSetValues(Pointee(ElementsAre("a", "c")))); EXPECT_CALL(*mock, processAll()); @@ -249,11 +227,10 @@ TEST(AbstractOptionStorageTest, HandlesValueRemoval) */ TEST(AbstractOptionStorageTest, HandlesValueAddition) { - gmx::Options options; - std::vector values; - MockOptionInfo *info = options.addOption( - MockOption("name").storeVector(&values).multiValue()); - MockOptionStorage *mock = &info->option(); + gmx::Options options; + std::vector values; + MockOptionInfo* info = options.addOption(MockOption("name").storeVector(&values).multiValue()); + MockOptionStorage* mock = &info->option(); { ::testing::InSequence dummy; using ::testing::DoAll; @@ -262,8 +239,8 @@ TEST(AbstractOptionStorageTest, HandlesValueAddition) using ::testing::Pointee; EXPECT_CALL(*mock, convertValue("a")); EXPECT_CALL(*mock, convertValue("b")) - .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), - InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue))); + .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), + InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue))); EXPECT_CALL(*mock, processSetValues(Pointee(ElementsAre("a", "dummy", "dummy")))); EXPECT_CALL(*mock, processAll()); } @@ -289,11 +266,10 @@ TEST(AbstractOptionStorageTest, HandlesValueAddition) */ TEST(AbstractOptionStorageTest, HandlesTooManyValueAddition) { - gmx::Options options; - std::vector values; - MockOptionInfo *info = options.addOption( - MockOption("name").storeVector(&values).valueCount(2)); - MockOptionStorage *mock = &info->option(); + gmx::Options options; + std::vector values; + MockOptionInfo* info = options.addOption(MockOption("name").storeVector(&values).valueCount(2)); + MockOptionStorage* mock = &info->option(); { ::testing::InSequence dummy; using ::testing::DoAll; @@ -302,8 +278,8 @@ TEST(AbstractOptionStorageTest, HandlesTooManyValueAddition) using ::testing::Pointee; EXPECT_CALL(*mock, convertValue("a")); EXPECT_CALL(*mock, convertValue("b")) - .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), - InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue))); + .WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue), + InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue))); EXPECT_CALL(*mock, processAll()); } @@ -325,19 +301,17 @@ TEST(AbstractOptionStorageTest, HandlesTooManyValueAddition) */ TEST(AbstractOptionStorageTest, AllowsEmptyValues) { - gmx::Options options; - std::vector values; - MockOptionInfo *info = options.addOption( - MockOption("name").storeVector(&values).valueCount(0)); - MockOptionStorage *mock = &info->option(); + gmx::Options options; + std::vector values; + MockOptionInfo* info = options.addOption(MockOption("name").storeVector(&values).valueCount(0)); + MockOptionStorage* mock = &info->option(); { ::testing::InSequence dummy; using ::testing::DoAll; using ::testing::ElementsAre; using ::testing::Pointee; using ::testing::Return; - EXPECT_CALL(*mock, convertValue("a")) - .WillOnce(Return()); + EXPECT_CALL(*mock, convertValue("a")).WillOnce(Return()); EXPECT_CALL(*mock, processSetValues(Pointee(ElementsAre()))); EXPECT_CALL(*mock, processAll()); } diff --git a/src/gromacs/options/tests/filenameoption.cpp b/src/gromacs/options/tests/filenameoption.cpp index 2d3cde55f5..6b411030bd 100644 --- a/src/gromacs/options/tests/filenameoption.cpp +++ b/src/gromacs/options/tests/filenameoption.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,12 +59,10 @@ using gmx::FileNameOption; TEST(FileNameOptionTest, HandlesRequiredDefaultValueWithoutExtension) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftGenericData).outputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).required().filetype(gmx::eftGenericData).outputFile().defaultBasename("testfile"))); EXPECT_EQ("testfile.dat", value); gmx::OptionsAssigner assigner(&options); @@ -77,12 +75,10 @@ TEST(FileNameOptionTest, HandlesRequiredDefaultValueWithoutExtension) TEST(FileNameOptionTest, HandlesRequiredOptionWithoutValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftGenericData).outputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).required().filetype(gmx::eftGenericData).outputFile().defaultBasename("testfile"))); EXPECT_EQ("testfile.dat", value); gmx::OptionsAssigner assigner(&options); @@ -97,12 +93,10 @@ TEST(FileNameOptionTest, HandlesRequiredOptionWithoutValue) TEST(FileNameOptionTest, HandlesOptionalUnsetOption) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).outputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).outputFile().defaultBasename("testfile"))); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options); @@ -115,12 +109,10 @@ TEST(FileNameOptionTest, HandlesOptionalUnsetOption) TEST(FileNameOptionTest, HandlesOptionalDefaultValueWithoutExtension) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).outputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).filetype(gmx::eftIndex).outputFile().defaultBasename("testfile"))); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options); @@ -135,13 +127,15 @@ TEST(FileNameOptionTest, HandlesOptionalDefaultValueWithoutExtension) TEST(FileNameOptionTest, HandlesRequiredCustomDefaultExtension) { - gmx::Options options; - std::string value; - ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftTrajectory).outputFile() - .defaultBasename("testfile") - .defaultType(efPDB))); + gmx::Options options; + std::string value; + ASSERT_NO_THROW_GMX(options.addOption(FileNameOption("f") + .store(&value) + .required() + .filetype(gmx::eftTrajectory) + .outputFile() + .defaultBasename("testfile") + .defaultType(efPDB))); EXPECT_EQ("testfile.pdb", value); gmx::OptionsAssigner assigner(&options); @@ -154,13 +148,14 @@ TEST(FileNameOptionTest, HandlesRequiredCustomDefaultExtension) TEST(FileNameOptionTest, HandlesOptionalCustomDefaultExtension) { - gmx::Options options; - std::string value; - ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).outputFile() - .defaultBasename("testfile") - .defaultType(efPDB))); + gmx::Options options; + std::string value; + ASSERT_NO_THROW_GMX(options.addOption(FileNameOption("f") + .store(&value) + .filetype(gmx::eftTrajectory) + .outputFile() + .defaultBasename("testfile") + .defaultType(efPDB))); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options); @@ -175,11 +170,10 @@ TEST(FileNameOptionTest, HandlesOptionalCustomDefaultExtension) TEST(FileNameOptionTest, GivesErrorOnUnknownFileSuffix) { - gmx::Options options; - std::string value; - ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).outputFile())); + gmx::Options options; + std::string value; + ASSERT_NO_THROW_GMX( + options.addOption(FileNameOption("f").store(&value).filetype(gmx::eftIndex).outputFile())); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options); @@ -195,11 +189,10 @@ TEST(FileNameOptionTest, GivesErrorOnUnknownFileSuffix) TEST(FileNameOptionTest, GivesErrorOnInvalidFileSuffix) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; ASSERT_NO_THROW_GMX(options.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).outputFile())); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).outputFile())); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options); diff --git a/src/gromacs/options/tests/filenameoptionmanager.cpp b/src/gromacs/options/tests/filenameoptionmanager.cpp index 9a67461c05..8a5c55b2da 100644 --- a/src/gromacs/options/tests/filenameoptionmanager.cpp +++ b/src/gromacs/options/tests/filenameoptionmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,21 +61,18 @@ using gmx::FileNameOption; class FileNameOptionManagerTest : public ::testing::Test { - public: - FileNameOptionManagerTest() - { - manager_.setInputRedirector(&redirector_); - options_.addManager(&manager_); - } - - void addExistingFile(const char *filename) - { - redirector_.addExistingFile(filename); - } - - gmx::test::TestFileInputRedirector redirector_; - gmx::FileNameOptionManager manager_; - gmx::Options options_; +public: + FileNameOptionManagerTest() + { + manager_.setInputRedirector(&redirector_); + options_.addManager(&manager_); + } + + void addExistingFile(const char* filename) { redirector_.addExistingFile(filename); } + + gmx::test::TestFileInputRedirector redirector_; + gmx::FileNameOptionManager manager_; + gmx::Options options_; }; /******************************************************************** @@ -86,8 +83,7 @@ TEST_F(FileNameOptionManagerTest, AddsMissingExtension) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).outputFile())); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).outputFile())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -104,9 +100,7 @@ TEST_F(FileNameOptionManagerTest, AddsMissingCustomDefaultExtension) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).outputFile() - .defaultType(efPDB))); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).outputFile().defaultType(efPDB))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -122,9 +116,8 @@ TEST_F(FileNameOptionManagerTest, AddsMissingCustomDefaultExtension) TEST_F(FileNameOptionManagerTest, GivesErrorOnMissingInputFile) { std::string value; - ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).inputFile())); + ASSERT_NO_THROW_GMX( + options_.addOption(FileNameOption("f").store(&value).filetype(gmx::eftIndex).inputFile())); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options_); @@ -142,8 +135,7 @@ TEST_F(FileNameOptionManagerTest, GivesErrorOnMissingGenericInputFile) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).inputFile())); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).inputFile())); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options_); @@ -161,9 +153,7 @@ TEST_F(FileNameOptionManagerTest, GivesErrorOnMissingDefaultInputFile) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).inputFile() - .defaultBasename("missing"))); + FileNameOption("f").store(&value).filetype(gmx::eftIndex).inputFile().defaultBasename("missing"))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -177,9 +167,7 @@ TEST_F(FileNameOptionManagerTest, GivesErrorOnMissingRequiredInputFile) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftIndex).inputFile() - .defaultBasename("missing"))); + FileNameOption("f").store(&value).required().filetype(gmx::eftIndex).inputFile().defaultBasename("missing"))); EXPECT_EQ("missing.ndx", value); gmx::OptionsAssigner assigner(&options_); @@ -192,9 +180,7 @@ TEST_F(FileNameOptionManagerTest, AcceptsMissingInputFileIfSpecified) { std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).inputFile() - .allowMissing())); + FileNameOption("f").store(&value).filetype(gmx::eftIndex).inputFile().allowMissing())); EXPECT_TRUE(value.empty()); gmx::OptionsAssigner assigner(&options_); @@ -211,11 +197,12 @@ TEST_F(FileNameOptionManagerTest, AcceptsMissingInputFileIfSpecified) TEST_F(FileNameOptionManagerTest, AcceptsMissingDefaultInputFileIfSpecified) { std::string value; - ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftIndex).inputFile() - .defaultBasename("missing") - .allowMissing())); + ASSERT_NO_THROW_GMX(options_.addOption(FileNameOption("f") + .store(&value) + .filetype(gmx::eftIndex) + .inputFile() + .defaultBasename("missing") + .allowMissing())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -230,11 +217,13 @@ TEST_F(FileNameOptionManagerTest, AcceptsMissingDefaultInputFileIfSpecified) TEST_F(FileNameOptionManagerTest, AcceptsMissingRequiredInputFileIfSpecified) { std::string value; - ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftIndex).inputFile() - .defaultBasename("missing") - .allowMissing())); + ASSERT_NO_THROW_GMX(options_.addOption(FileNameOption("f") + .store(&value) + .required() + .filetype(gmx::eftIndex) + .inputFile() + .defaultBasename("missing") + .allowMissing())); EXPECT_EQ("missing.ndx", value); gmx::OptionsAssigner assigner(&options_); @@ -251,8 +240,7 @@ TEST_F(FileNameOptionManagerTest, AddsMissingExtensionBasedOnExistingFile) std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).inputFile())); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).inputFile())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -265,16 +253,13 @@ TEST_F(FileNameOptionManagerTest, AddsMissingExtensionBasedOnExistingFile) EXPECT_EQ("testfile.trr", value); } -TEST_F(FileNameOptionManagerTest, - AddsMissingExtensionForRequiredDefaultNameBasedOnExistingFile) +TEST_F(FileNameOptionManagerTest, AddsMissingExtensionForRequiredDefaultNameBasedOnExistingFile) { addExistingFile("testfile.trr"); std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftTrajectory).inputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).required().filetype(gmx::eftTrajectory).inputFile().defaultBasename("testfile"))); EXPECT_EQ("testfile.xtc", value); gmx::OptionsAssigner assigner(&options_); @@ -287,16 +272,13 @@ TEST_F(FileNameOptionManagerTest, EXPECT_EQ("testfile.trr", value); } -TEST_F(FileNameOptionManagerTest, - AddsMissingExtensionForOptionalDefaultNameBasedOnExistingFile) +TEST_F(FileNameOptionManagerTest, AddsMissingExtensionForOptionalDefaultNameBasedOnExistingFile) { addExistingFile("testfile.trr"); std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).inputFile() - .defaultBasename("testfile"))); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).inputFile().defaultBasename("testfile"))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -308,16 +290,13 @@ TEST_F(FileNameOptionManagerTest, EXPECT_EQ("testfile.trr", value); } -TEST_F(FileNameOptionManagerTest, - AddsMissingExtensionForRequiredFromDefaultNameOptionBasedOnExistingFile) +TEST_F(FileNameOptionManagerTest, AddsMissingExtensionForRequiredFromDefaultNameOptionBasedOnExistingFile) { addExistingFile("testfile.trr"); std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftTrajectory).inputFile() - .defaultBasename("foo"))); + FileNameOption("f").store(&value).required().filetype(gmx::eftTrajectory).inputFile().defaultBasename("foo"))); ASSERT_NO_THROW_GMX(manager_.addDefaultFileNameOption(&options_, "deffnm")); EXPECT_EQ("foo.xtc", value); @@ -332,16 +311,13 @@ TEST_F(FileNameOptionManagerTest, EXPECT_EQ("testfile.trr", value); } -TEST_F(FileNameOptionManagerTest, - AddsMissingExtensionForOptionalFromDefaultNameOptionBasedOnExistingFile) +TEST_F(FileNameOptionManagerTest, AddsMissingExtensionForOptionalFromDefaultNameOptionBasedOnExistingFile) { addExistingFile("testfile.trr"); std::string value; ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value) - .filetype(gmx::eftTrajectory).inputFile() - .defaultBasename("foo"))); + FileNameOption("f").store(&value).filetype(gmx::eftTrajectory).inputFile().defaultBasename("foo"))); ASSERT_NO_THROW_GMX(manager_.addDefaultFileNameOption(&options_, "deffnm")); gmx::OptionsAssigner assigner(&options_); @@ -361,11 +337,13 @@ TEST_F(FileNameOptionManagerTest, DefaultNameOptionWorksWithoutInputChecking) { std::string value; ASSERT_NO_THROW_GMX(manager_.disableInputOptionChecking(true)); - ASSERT_NO_THROW_GMX(options_.addOption( - FileNameOption("f").store(&value).required() - .filetype(gmx::eftIndex).inputFile() - .defaultBasename("default") - .allowMissing())); + ASSERT_NO_THROW_GMX(options_.addOption(FileNameOption("f") + .store(&value) + .required() + .filetype(gmx::eftIndex) + .inputFile() + .defaultBasename("default") + .allowMissing())); ASSERT_NO_THROW_GMX(manager_.addDefaultFileNameOption(&options_, "deffnm")); EXPECT_EQ("default.ndx", value); diff --git a/src/gromacs/options/tests/option.cpp b/src/gromacs/options/tests/option.cpp index c9d85b2b9b..8ba0aa25e0 100644 --- a/src/gromacs/options/tests/option.cpp +++ b/src/gromacs/options/tests/option.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,9 +63,7 @@ TEST(OptionsTest, FailsOnNonsafeStorage) gmx::Options options; int value = -1; using gmx::IntegerOption; - ASSERT_THROW_GMX(options.addOption(IntegerOption("name").store(&value) - .multiValue()), - gmx::APIError); + ASSERT_THROW_GMX(options.addOption(IntegerOption("name").store(&value).multiValue()), gmx::APIError); } } // namespace diff --git a/src/gromacs/options/tests/optionsassigner.cpp b/src/gromacs/options/tests/optionsassigner.cpp index ad1df79761..9d6d7ca1dc 100644 --- a/src/gromacs/options/tests/optionsassigner.cpp +++ b/src/gromacs/options/tests/optionsassigner.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,8 +76,7 @@ TEST(OptionsAssignerTest, HandlesMissingRequiredParameter) gmx::Options options; int value = 0; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value).required())); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value).required())); EXPECT_THROW(options.finish(), gmx::InvalidInputError); } @@ -86,9 +86,7 @@ TEST(OptionsAssignerTest, HandlesRequiredParameterWithDefaultValue) gmx::Options options; int value = 0; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value).required() - .defaultValue(1))); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value).required().defaultValue(1))); EXPECT_NO_THROW(options.finish()); EXPECT_EQ(1, value); @@ -101,9 +99,7 @@ TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter) bool bIsSet = false; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption( - IntegerOption("p") - .storeVector(&values).storeIsSet(&bIsSet) - .multiValue())); + IntegerOption("p").storeVector(&values).storeIsSet(&bIsSet).multiValue())); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -126,9 +122,7 @@ TEST(OptionsAssignerTest, HandlesMultipleParameter) bool bIsSet = false; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption( - IntegerOption("p") - .storeVector(&values).storeIsSet(&bIsSet) - .allowMultiple())); + IntegerOption("p").storeVector(&values).storeIsSet(&bIsSet).allowMultiple())); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); @@ -190,8 +184,8 @@ TEST(OptionsAssignerTest, HandlesExtraValue) TEST(OptionsAssignerTest, HandlesGroups) { gmx::Options options; - gmx::IOptionsContainer &group1 = options.addGroup(); - gmx::IOptionsContainer &group2 = options.addGroup(); + gmx::IOptionsContainer& group1 = options.addGroup(); + gmx::IOptionsContainer& group2 = options.addGroup(); int value = 3; int value1 = 1; int value2 = 2; @@ -361,7 +355,7 @@ TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue) EXPECT_NO_THROW(assigner.finish()); EXPECT_TRUE(value); } - catch (const gmx::InvalidInputError &) + catch (const gmx::InvalidInputError&) { } } @@ -437,8 +431,7 @@ TEST(OptionsAssignerIntegerTest, HandlesOverflow) gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); ASSERT_NO_THROW(assigner.startOption("p")); - std::string overflowValue( - gmx::formatString("%d0000", std::numeric_limits::max())); + std::string overflowValue(gmx::formatString("%d0000", std::numeric_limits::max())); EXPECT_THROW(assigner.appendValue(overflowValue), gmx::InvalidInputError); EXPECT_NO_THROW(assigner.finishOption()); EXPECT_NO_THROW(assigner.finish()); @@ -452,8 +445,7 @@ TEST(OptionsAssignerIntegerTest, StoresDefaultValue) gmx::Options options; int value = -1; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value).defaultValue(2))); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value).defaultValue(2))); EXPECT_EQ(2, value); gmx::OptionsAssigner assigner(&options); @@ -469,8 +461,7 @@ TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet) gmx::Options options; int value = -1; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value).defaultValueIfSet(2))); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value).defaultValueIfSet(2))); EXPECT_EQ(-1, value); gmx::OptionsAssigner assigner(&options); @@ -488,8 +479,7 @@ TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet) gmx::Options options; int value = -1; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value).defaultValueIfSet(2))); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value).defaultValueIfSet(2))); EXPECT_EQ(-1, value); gmx::OptionsAssigner assigner(&options); @@ -505,9 +495,8 @@ TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues) gmx::Options options; int value = -1; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").store(&value) - .defaultValue(1).defaultValueIfSet(2))); + ASSERT_NO_THROW( + options.addOption(IntegerOption("p").store(&value).defaultValue(1).defaultValueIfSet(2))); EXPECT_EQ(1, value); gmx::OptionsAssigner assigner(&options); @@ -522,11 +511,10 @@ TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues) TEST(OptionsAssignerIntegerTest, StoresToVector) { - gmx::Options options; - std::vector values; + gmx::Options options; + std::vector values; using gmx::IntegerOption; - ASSERT_NO_THROW(options.addOption( - IntegerOption("p").storeVector(&values).multiValue())); + ASSERT_NO_THROW(options.addOption(IntegerOption("p").storeVector(&values).multiValue())); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -547,7 +535,7 @@ TEST(OptionsAssignerIntegerTest, StoresToVector) TEST(OptionsAssignerIntegerTest, HandlesVectors) { gmx::Options options; - int vec[3] = {0, 0, 0}; + int vec[3] = { 0, 0, 0 }; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector())); @@ -569,7 +557,7 @@ TEST(OptionsAssignerIntegerTest, HandlesVectors) TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue) { gmx::Options options; - int vec[3] = {0, 0, 0}; + int vec[3] = { 0, 0, 0 }; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector())); @@ -589,7 +577,7 @@ TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue) TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue) { gmx::Options options; - int vec[3] = {3, 2, 1}; + int vec[3] = { 3, 2, 1 }; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector())); @@ -602,8 +590,8 @@ TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue) TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValueWithInvalidAssignment) { - gmx::Options options; - int vec[3] = {3, 2, 1}; + gmx::Options options; + int vec[3] = { 3, 2, 1 }; using gmx::IntegerOption; ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector())); @@ -682,10 +670,10 @@ TEST(OptionsAssignerDoubleTest, HandlesEmptyValue) TEST(OptionsAssignerDoubleTest, HandlesPreSetScaleValue) { - gmx::Options options; - double value = 1.0; + gmx::Options options; + double value = 1.0; using gmx::DoubleOption; - gmx::DoubleOptionInfo *info = options.addOption(DoubleOption("p").store(&value)); + gmx::DoubleOptionInfo* info = options.addOption(DoubleOption("p").store(&value)); EXPECT_NO_THROW(info->setScaleFactor(10)); gmx::OptionsAssigner assigner(&options); @@ -701,12 +689,12 @@ TEST(OptionsAssignerDoubleTest, HandlesPreSetScaleValue) TEST(OptionsAssignerDoubleTest, HandlesPostSetScaleValue) { - gmx::Options options; - double value = 1.0; + gmx::Options options; + double value = 1.0; using gmx::DoubleOption; - gmx::DoubleOptionInfo *info = options.addOption(DoubleOption("p").store(&value)); + gmx::DoubleOptionInfo* info = options.addOption(DoubleOption("p").store(&value)); - gmx::OptionsAssigner assigner(&options); + gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); ASSERT_NO_THROW(assigner.startOption("p")); ASSERT_NO_THROW(assigner.appendValue("2.7")); @@ -724,12 +712,12 @@ TEST(OptionsAssignerDoubleTest, HandlesPostSetScaleValue) */ //! Set of allowed values for enum option tests. -const char *const c_allowed[] = { "none", "test", "value" }; +const char* const c_allowed[] = { "none", "test", "value" }; TEST(OptionsAssignerStringTest, StoresSingleValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value))); @@ -746,12 +734,10 @@ TEST(OptionsAssignerStringTest, StoresSingleValue) TEST(OptionsAssignerStringTest, HandlesEnumValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; - ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value).enumValue(c_allowed))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -766,13 +752,12 @@ TEST(OptionsAssignerStringTest, HandlesEnumValue) TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray) { - gmx::Options options; - std::string value; - const char * const allowed[] = { "none", "test", "value", nullptr }; + gmx::Options options; + std::string value; + const char* const allowed[] = { "none", "test", "value", nullptr }; using gmx::StringOption; ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValueFromNullTerminatedArray(allowed))); + StringOption("p").store(&value).enumValueFromNullTerminatedArray(allowed))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -787,12 +772,10 @@ TEST(OptionsAssignerStringTest, HandlesEnumValueFromNullTerminatedArray) TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; - ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value).enumValue(c_allowed))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -802,12 +785,10 @@ TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue) TEST(OptionsAssignerStringTest, CompletesEnumValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; - ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value).enumValue(c_allowed))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW(assigner.start()); @@ -822,12 +803,10 @@ TEST(OptionsAssignerStringTest, CompletesEnumValue) TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; - ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value).enumValue(c_allowed))); EXPECT_TRUE(value.empty()); ASSERT_NO_THROW(options.finish()); @@ -837,12 +816,11 @@ TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue) TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue) { - gmx::Options options; - std::string value; + gmx::Options options; + std::string value; using gmx::StringOption; ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed).defaultValue("test"))); + StringOption("p").store(&value).enumValue(c_allowed).defaultValue("test"))); EXPECT_EQ("test", value); gmx::OptionsAssigner assigner(&options); @@ -855,12 +833,10 @@ TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue) TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVariable) { - gmx::Options options; - std::string value("test"); + gmx::Options options; + std::string value("test"); using gmx::StringOption; - ASSERT_NO_THROW(options.addOption( - StringOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value).enumValue(c_allowed))); EXPECT_EQ("test", value); gmx::OptionsAssigner assigner(&options); @@ -879,8 +855,7 @@ TEST(OptionsAssignerStringTest, HandlesEnumDefaultValueFromVector) value.emplace_back("value"); using gmx::StringOption; ASSERT_NO_THROW(options.addOption( - StringOption("p").storeVector(&value).valueCount(2) - .enumValue(c_allowed))); + StringOption("p").storeVector(&value).valueCount(2).enumValue(c_allowed))); ASSERT_EQ(2U, value.size()); EXPECT_EQ("test", value[0]); EXPECT_EQ("value", value[1]); @@ -911,12 +886,10 @@ enum TestEnum TEST(OptionsAssignerEnumTest, StoresSingleValue) { - gmx::Options options; - TestEnum value = etestNone; + gmx::Options options; + TestEnum value = etestNone; using gmx::EnumOption; - ASSERT_NO_THROW(options.addOption( - EnumOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(EnumOption("p").store(&value).enumValue(c_allowed))); EXPECT_EQ(etestNone, value); gmx::OptionsAssigner assigner(&options); @@ -932,12 +905,11 @@ TEST(OptionsAssignerEnumTest, StoresSingleValue) TEST(OptionsAssignerEnumTest, StoresVectorValues) { - gmx::Options options; - std::vector values; + gmx::Options options; + std::vector values; using gmx::EnumOption; ASSERT_NO_THROW(options.addOption( - EnumOption("p").storeVector(&values) - .multiValue().enumValue(c_allowed))); + EnumOption("p").storeVector(&values).multiValue().enumValue(c_allowed))); EXPECT_TRUE(values.empty()); gmx::OptionsAssigner assigner(&options); @@ -956,12 +928,10 @@ TEST(OptionsAssignerEnumTest, StoresVectorValues) TEST(OptionsAssignerEnumTest, HandlesInitialValueOutOfRange) { - gmx::Options options; - TestEnum value = etestNR; + gmx::Options options; + TestEnum value = etestNR; using gmx::EnumOption; - ASSERT_NO_THROW(options.addOption( - EnumOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(EnumOption("p").store(&value).enumValue(c_allowed))); EXPECT_EQ(etestNR, value); gmx::OptionsAssigner assigner(&options); @@ -974,12 +944,11 @@ TEST(OptionsAssignerEnumTest, HandlesInitialValueOutOfRange) TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValue) { - gmx::Options options; - TestEnum value = etestNone; + gmx::Options options; + TestEnum value = etestNone; using gmx::EnumOption; ASSERT_NO_THROW(options.addOption( - EnumOption("p").store(&value) - .enumValue(c_allowed).defaultValue(etestTest))); + EnumOption("p").store(&value).enumValue(c_allowed).defaultValue(etestTest))); EXPECT_EQ(etestTest, value); gmx::OptionsAssigner assigner(&options); @@ -992,12 +961,10 @@ TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValue) TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVariable) { - gmx::Options options; - TestEnum value = etestTest; + gmx::Options options; + TestEnum value = etestTest; using gmx::EnumOption; - ASSERT_NO_THROW(options.addOption( - EnumOption("p").store(&value) - .enumValue(c_allowed))); + ASSERT_NO_THROW(options.addOption(EnumOption("p").store(&value).enumValue(c_allowed))); EXPECT_EQ(etestTest, value); gmx::OptionsAssigner assigner(&options); @@ -1010,14 +977,13 @@ TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVariable) TEST(OptionsAssignerEnumTest, HandlesEnumDefaultValueFromVector) { - gmx::Options options; - std::vector value; + gmx::Options options; + std::vector value; value.push_back(etestNone); value.push_back(etestTest); using gmx::EnumOption; ASSERT_NO_THROW(options.addOption( - EnumOption("p").storeVector(&value).valueCount(2) - .enumValue(c_allowed))); + EnumOption("p").storeVector(&value).valueCount(2).enumValue(c_allowed))); ASSERT_EQ(2U, value.size()); EXPECT_EQ(etestNone, value[0]); EXPECT_EQ(etestTest, value[1]); diff --git a/src/gromacs/options/tests/repeatingsection.cpp b/src/gromacs/options/tests/repeatingsection.cpp index 04060766d6..0182686e56 100644 --- a/src/gromacs/options/tests/repeatingsection.cpp +++ b/src/gromacs/options/tests/repeatingsection.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,9 +67,7 @@ TEST(RepeatingOptionSectionTest, HandlesNoInstance) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value))); @@ -85,12 +83,9 @@ TEST(RepeatingOptionSectionTest, HandlesNoInstanceWithRequiredOption) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; - ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value) - .required())); + ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value).required())); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); @@ -104,9 +99,7 @@ TEST(RepeatingOptionSectionTest, HandlesSingleInstance) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value))); @@ -128,12 +121,9 @@ TEST(RepeatingOptionSectionTest, HandlesDefaultValue) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; - ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value) - .defaultValue(3))); + ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value).defaultValue(3))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); @@ -150,9 +140,7 @@ TEST(RepeatingOptionSectionTest, HandlesTwoInstances) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value))); @@ -180,9 +168,7 @@ TEST(RepeatingOptionSectionTest, HandlesUnsetOptionWithImplicitDefault) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value))); @@ -207,12 +193,9 @@ TEST(RepeatingOptionSectionTest, HandlesUnsetOptionWithExplicitDefault) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); using gmx::IntegerOption; - ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value) - .defaultValue(1))); + ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value).defaultValue(1))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); @@ -233,7 +216,7 @@ TEST(RepeatingOptionSectionTest, HandlesUnsetOptionWithExplicitDefault) struct NestedSectionData { - int value {}; + int value{}; std::vector subsec; }; @@ -241,12 +224,9 @@ TEST(RepeatingOptionSectionTest, HandlesNestedSections) { std::vector values; gmx::Options options; - auto sec = options.addSection( - RepeatingOptionSection("section") - .storeVector(&values)); - auto subsec = sec.addSection( - RepeatingOptionSection("subsec") - .storeVector(&sec.bind().subsec)); + auto sec = options.addSection(RepeatingOptionSection("section").storeVector(&values)); + auto subsec = + sec.addSection(RepeatingOptionSection("subsec").storeVector(&sec.bind().subsec)); using gmx::IntegerOption; ASSERT_NO_THROW_GMX(sec.addOption(IntegerOption("p").store(&sec.bind().value))); ASSERT_NO_THROW_GMX(subsec.addOption(IntegerOption("p").store(&subsec.bind().value))); diff --git a/src/gromacs/options/tests/timeunitmanager.cpp b/src/gromacs/options/tests/timeunitmanager.cpp index 044f81ee7f..5d1adaf301 100644 --- a/src/gromacs/options/tests/timeunitmanager.cpp +++ b/src/gromacs/options/tests/timeunitmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,14 +70,14 @@ TEST(TimeUnitManagerTest, BasicOperations) TEST(TimeUnitBehaviorTest, ScalesAssignedOptionValue) { - gmx::TimeUnitBehavior behavior; + gmx::TimeUnitBehavior behavior; - gmx::Options options; - double value = 0.0; + gmx::Options options; + double value = 0.0; using gmx::DoubleOption; ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue())); - gmx::OptionsAssigner assigner(&options); + gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); ASSERT_NO_THROW_GMX(assigner.startOption("p")); ASSERT_NO_THROW_GMX(assigner.appendValue("1.5")); @@ -108,12 +108,12 @@ TEST(TimeUnitBehaviorTest, DoesNotScaleDefaultValues) { gmx::TimeUnitBehavior behavior; - gmx::Options options; - double value = 1.5, value2 = 0.0; + gmx::Options options; + double value = 1.5, value2 = 0.0; using gmx::DoubleOption; ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue())); - ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("q").store(&value2).timeValue() - .defaultValueIfSet(2.5))); + ASSERT_NO_THROW_GMX( + options.addOption(DoubleOption("q").store(&value2).timeValue().defaultValueIfSet(2.5))); gmx::OptionsAssigner assigner(&options); EXPECT_NO_THROW_GMX(assigner.start()); @@ -133,8 +133,8 @@ TEST(TimeUnitBehaviorTest, ScalesUserInputWithMultipleSources) { gmx::TimeUnitBehavior behavior; - gmx::Options options; - double value = 0.0; + gmx::Options options; + double value = 0.0; using gmx::DoubleOption; ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue())); @@ -159,8 +159,8 @@ TEST(TimeUnitBehaviorTest, TimeUnitOptionWorks) { gmx::TimeUnitBehavior behavior; - gmx::Options options; - double value = 0.0; + gmx::Options options; + double value = 0.0; using gmx::DoubleOption; ASSERT_NO_THROW_GMX(options.addOption(DoubleOption("p").store(&value).timeValue())); ASSERT_NO_THROW_GMX(behavior.addTimeUnitOption(&options, "tu")); diff --git a/src/gromacs/options/tests/treesupport.cpp b/src/gromacs/options/tests/treesupport.cpp index d9a6c66b5d..853646a642 100644 --- a/src/gromacs/options/tests/treesupport.cpp +++ b/src/gromacs/options/tests/treesupport.cpp @@ -73,21 +73,21 @@ namespace TEST(TreeValueSupportAssignTest, AssignsFromTree) { - int a0 = 0, a1 = 0; - std::string b1; + int a0 = 0, a1 = 0; + std::string b1; - gmx::Options options; + gmx::Options options; options.addOption(gmx::IntegerOption("a").store(&a0)); - auto sec = options.addSection(gmx::OptionSection("s")); + auto sec = options.addSection(gmx::OptionSection("s")); sec.addOption(gmx::IntegerOption("a").store(&a1)); sec.addOption(gmx::StringOption("b").store(&b1)); gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", 2); - auto obj = builder.rootObject().addObject("s"); + auto obj = builder.rootObject().addObject("s"); obj.addValue("a", 1); obj.addValue("b", "foo"); - gmx::KeyValueTreeObject tree = builder.build(); + gmx::KeyValueTreeObject tree = builder.build(); ASSERT_NO_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options, tree, nullptr)); EXPECT_NO_THROW_GMX(options.finish()); @@ -107,21 +107,21 @@ TEST(TreeValueSupportAssignTest, AssignsFromTreeWithArrays) std::vector a0; std::vector s; - gmx::Options options; + gmx::Options options; options.addOption(gmx::IntegerOption("a").storeVector(&a0).multiValue()); - auto sec = options.addSection(gmx::RepeatingOptionSection("s").storeVector(&s)); + auto sec = options.addSection(gmx::RepeatingOptionSection("s").storeVector(&s)); sec.addOption(gmx::IntegerOption("a").store(&sec.bind().a)); gmx::KeyValueTreeBuilder builder; auto array = builder.rootObject().addUniformArray("a"); array.addValue(1); array.addValue(2); - auto objArray = builder.rootObject().addObjectArray("s"); - auto obj1 = objArray.addObject(); + auto objArray = builder.rootObject().addObjectArray("s"); + auto obj1 = objArray.addObject(); obj1.addValue("a", 3); - auto obj2 = objArray.addObject(); + auto obj2 = objArray.addObject(); obj2.addValue("a", 4); - gmx::KeyValueTreeObject tree = builder.build(); + gmx::KeyValueTreeObject tree = builder.build(); ASSERT_NO_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options, tree, nullptr)); EXPECT_NO_THROW_GMX(options.finish()); @@ -136,19 +136,18 @@ TEST(TreeValueSupportAssignTest, AssignsFromTreeWithArrays) TEST(TreeValueSupportAssignErrorTest, HandlesInvalidValue) { - int a1 = 0; + int a1 = 0; - gmx::Options options; - auto sec = options.addSection(gmx::OptionSection("s")); + gmx::Options options; + auto sec = options.addSection(gmx::OptionSection("s")); sec.addOption(gmx::IntegerOption("a").store(&a1)); gmx::KeyValueTreeBuilder builder; auto obj = builder.rootObject().addObject("s"); obj.addValue("a", "foo"); - gmx::KeyValueTreeObject tree = builder.build(); + gmx::KeyValueTreeObject tree = builder.build(); - EXPECT_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options, tree, nullptr), - gmx::InvalidInputError); + EXPECT_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options, tree, nullptr), gmx::InvalidInputError); } /******************************************************************** @@ -157,19 +156,19 @@ TEST(TreeValueSupportAssignErrorTest, HandlesInvalidValue) class TreeValueSupportCheckTest : public ::testing::Test { - public: - TreeValueSupportCheckTest() - { - auto sec1 = options_.addSection(gmx::OptionSection("s")); - auto sec2 = options_.addSection(gmx::OptionSection("r")); - options_.addOption(gmx::IntegerOption("a")); - sec1.addOption(gmx::IntegerOption("a")); - sec1.addOption(gmx::IntegerOption("b")); - sec2.addOption(gmx::IntegerOption("b")); - } - - gmx::Options options_; - gmx::KeyValueTreeBuilder builder_; +public: + TreeValueSupportCheckTest() + { + auto sec1 = options_.addSection(gmx::OptionSection("s")); + auto sec2 = options_.addSection(gmx::OptionSection("r")); + options_.addOption(gmx::IntegerOption("a")); + sec1.addOption(gmx::IntegerOption("a")); + sec1.addOption(gmx::IntegerOption("b")); + sec2.addOption(gmx::IntegerOption("b")); + } + + gmx::Options options_; + gmx::KeyValueTreeBuilder builder_; }; TEST_F(TreeValueSupportCheckTest, HandlesEmpty) @@ -179,12 +178,12 @@ TEST_F(TreeValueSupportCheckTest, HandlesEmpty) TEST_F(TreeValueSupportCheckTest, HandlesMatchingTree) { - auto root = builder_.rootObject(); + auto root = builder_.rootObject(); root.addValue("a", 1); - auto obj1 = root.addObject("s"); + auto obj1 = root.addObject("s"); obj1.addValue("a", 1); obj1.addValue("b", 2); - auto obj2 = root.addObject("r"); + auto obj2 = root.addObject("r"); obj2.addValue("b", 3); EXPECT_NO_THROW_GMX(gmx::checkForUnknownOptionsInKeyValueTree(builder_.build(), options_)); @@ -192,9 +191,9 @@ TEST_F(TreeValueSupportCheckTest, HandlesMatchingTree) TEST_F(TreeValueSupportCheckTest, HandlesSmallerTree1) { - auto root = builder_.rootObject(); + auto root = builder_.rootObject(); root.addValue("a", 1); - auto obj1 = root.addObject("s"); + auto obj1 = root.addObject("s"); obj1.addValue("b", 2); EXPECT_NO_THROW_GMX(gmx::checkForUnknownOptionsInKeyValueTree(builder_.build(), options_)); @@ -202,8 +201,8 @@ TEST_F(TreeValueSupportCheckTest, HandlesSmallerTree1) TEST_F(TreeValueSupportCheckTest, HandlesSmallerTree2) { - auto root = builder_.rootObject(); - auto obj1 = root.addObject("s"); + auto root = builder_.rootObject(); + auto obj1 = root.addObject("s"); obj1.addValue("a", 1); obj1.addValue("b", 2); @@ -212,8 +211,8 @@ TEST_F(TreeValueSupportCheckTest, HandlesSmallerTree2) TEST_F(TreeValueSupportCheckTest, DetectsExtraValue) { - auto root = builder_.rootObject(); - auto obj2 = root.addObject("r"); + auto root = builder_.rootObject(); + auto obj2 = root.addObject("r"); obj2.addValue("a", 1); obj2.addValue("b", 3); @@ -227,19 +226,19 @@ TEST_F(TreeValueSupportCheckTest, DetectsExtraValue) class TreeValueSupportAdjustTest : public ::testing::Test { - public: - void runTest() - { - gmx::test::TestReferenceData refdata; - gmx::test::TestReferenceChecker checker(refdata.rootChecker()); - gmx::KeyValueTreeObject tree(builder_.build()); - checker.checkKeyValueTreeObject(tree, "Input"); - ASSERT_NO_THROW_GMX(tree = gmx::adjustKeyValueTreeFromOptions(tree, options_)); - checker.checkKeyValueTreeObject(tree, "Output"); - } - - gmx::Options options_; - gmx::KeyValueTreeBuilder builder_; +public: + void runTest() + { + gmx::test::TestReferenceData refdata; + gmx::test::TestReferenceChecker checker(refdata.rootChecker()); + gmx::KeyValueTreeObject tree(builder_.build()); + checker.checkKeyValueTreeObject(tree, "Input"); + ASSERT_NO_THROW_GMX(tree = gmx::adjustKeyValueTreeFromOptions(tree, options_)); + checker.checkKeyValueTreeObject(tree, "Output"); + } + + gmx::Options options_; + gmx::KeyValueTreeBuilder builder_; }; TEST_F(TreeValueSupportAdjustTest, FillsDefaultValues) @@ -250,7 +249,7 @@ TEST_F(TreeValueSupportAdjustTest, FillsDefaultValues) TEST_F(TreeValueSupportAdjustTest, FillsDefaultVectorValues) { - int v[3] = {1, 2, 3}; + int v[3] = { 1, 2, 3 }; options_.addOption(gmx::IntegerOption("a").store(v).vector()); runTest(); } @@ -300,67 +299,67 @@ TEST_F(TreeValueSupportAdjustTest, OrdersValues) class TreeValueSupportTest : public ::testing::Test { - public: - void runTest() +public: + void runTest() + { + gmx::test::TestReferenceData refdata; + gmx::test::TestReferenceChecker checker(refdata.rootChecker()); + gmx::KeyValueTreeObject tree(builder_.build()); + checker.checkKeyValueTreeObject(tree, "Input"); + // Check that adjustment works. + ASSERT_NO_THROW_GMX(tree = gmx::adjustKeyValueTreeFromOptions(tree, options_)); + checker.checkKeyValueTreeObject(tree, "Adjusted"); + // Check that assignment works. + ASSERT_NO_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options_, tree, nullptr)); + // Check that serialization works. { - gmx::test::TestReferenceData refdata; - gmx::test::TestReferenceChecker checker(refdata.rootChecker()); - gmx::KeyValueTreeObject tree(builder_.build()); - checker.checkKeyValueTreeObject(tree, "Input"); - // Check that adjustment works. - ASSERT_NO_THROW_GMX(tree = gmx::adjustKeyValueTreeFromOptions(tree, options_)); - checker.checkKeyValueTreeObject(tree, "Adjusted"); - // Check that assignment works. - ASSERT_NO_THROW_GMX(gmx::assignOptionsFromKeyValueTree(&options_, tree, nullptr)); - // Check that serialization works. - { - std::vector buffer = serializeTree(tree); - gmx::InMemoryDeserializer deserializer(buffer, false); - gmx::KeyValueTreeObject output - = gmx::deserializeKeyValueTree(&deserializer); - SCOPED_TRACE("After serialization/deserialization\n Buffer: " - + formatBuffer(buffer)); - checker.checkKeyValueTreeObject(output, "Adjusted"); - } - // Check that dumping works. - { - gmx::StringOutputStream stream; - gmx::TextWriter writer(&stream); - ASSERT_NO_THROW_GMX(gmx::dumpKeyValueTree(&writer, tree)); - checker.checkTextBlock(stream.toString(), "Dumped"); - } - // Check that comparison works. - { - gmx::StringOutputStream stream; - gmx::TextWriter writer(&stream); - ASSERT_NO_THROW_GMX(gmx::compareKeyValueTrees(&writer, tree, tree, 0.0, 0.0)); - checker.checkTextBlock(stream.toString(), "Compared"); - } - // Check that comparison works against an empty tree. - { - gmx::StringOutputStream stream; - gmx::TextWriter writer(&stream); - gmx::KeyValueTreeObject empty; - ASSERT_NO_THROW_GMX(gmx::compareKeyValueTrees(&writer, tree, empty, 0.0, 0.0)); - checker.checkTextBlock(stream.toString(), "ComparedAgainstEmpty"); - } + std::vector buffer = serializeTree(tree); + gmx::InMemoryDeserializer deserializer(buffer, false); + gmx::KeyValueTreeObject output = gmx::deserializeKeyValueTree(&deserializer); + SCOPED_TRACE("After serialization/deserialization\n Buffer: " + formatBuffer(buffer)); + checker.checkKeyValueTreeObject(output, "Adjusted"); } - - gmx::Options options_; - gmx::KeyValueTreeBuilder builder_; - - private: - std::vector serializeTree(const gmx::KeyValueTreeObject &tree) + // Check that dumping works. { - gmx::InMemorySerializer serializer; - gmx::serializeKeyValueTree(tree, &serializer); - return serializer.finishAndGetBuffer(); + gmx::StringOutputStream stream; + gmx::TextWriter writer(&stream); + ASSERT_NO_THROW_GMX(gmx::dumpKeyValueTree(&writer, tree)); + checker.checkTextBlock(stream.toString(), "Dumped"); } - - std::string formatBuffer(const std::vector &buffer) + // Check that comparison works. + { + gmx::StringOutputStream stream; + gmx::TextWriter writer(&stream); + ASSERT_NO_THROW_GMX(gmx::compareKeyValueTrees(&writer, tree, tree, 0.0, 0.0)); + checker.checkTextBlock(stream.toString(), "Compared"); + } + // Check that comparison works against an empty tree. { - return gmx::formatAndJoin(buffer, " ", [](char c) { return gmx::formatString("%02x", static_cast(c)); }); + gmx::StringOutputStream stream; + gmx::TextWriter writer(&stream); + gmx::KeyValueTreeObject empty; + ASSERT_NO_THROW_GMX(gmx::compareKeyValueTrees(&writer, tree, empty, 0.0, 0.0)); + checker.checkTextBlock(stream.toString(), "ComparedAgainstEmpty"); } + } + + gmx::Options options_; + gmx::KeyValueTreeBuilder builder_; + +private: + std::vector serializeTree(const gmx::KeyValueTreeObject& tree) + { + gmx::InMemorySerializer serializer; + gmx::serializeKeyValueTree(tree, &serializer); + return serializer.finishAndGetBuffer(); + } + + std::string formatBuffer(const std::vector& buffer) + { + return gmx::formatAndJoin(buffer, " ", [](char c) { + return gmx::formatString("%02x", static_cast(c)); + }); + } }; TEST_F(TreeValueSupportTest, SupportsBooleanOption) @@ -401,7 +400,7 @@ TEST_F(TreeValueSupportTest, SupportsDoubleOption) TEST_F(TreeValueSupportTest, SupportsEnumIntOption) { - const char *const values[] = {"foo", "bar"}; + const char* const values[] = { "foo", "bar" }; options_.addOption(gmx::EnumIntOption("a").enumValue(values).defaultValue(0)); runTest(); } @@ -409,14 +408,14 @@ TEST_F(TreeValueSupportTest, SupportsEnumIntOption) //! Enum for testing EnumOption. enum class TestEnum { - Foo, Bar + Foo, + Bar }; TEST_F(TreeValueSupportTest, SupportsEnumOption) { - const char *const values[] = {"foo", "bar"}; - options_.addOption(gmx::EnumOption("a").enumValue(values) - .defaultValue(TestEnum::Foo)); + const char* const values[] = { "foo", "bar" }; + options_.addOption(gmx::EnumOption("a").enumValue(values).defaultValue(TestEnum::Foo)); runTest(); } diff --git a/src/gromacs/options/timeunitmanager.cpp b/src/gromacs/options/timeunitmanager.cpp index 92291120e1..8ac822a2bb 100644 --- a/src/gromacs/options/timeunitmanager.cpp +++ b/src/gromacs/options/timeunitmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,53 +64,43 @@ namespace * * These must correspond to the TimeUnit enum in the header! */ -const char *const g_timeUnits[] = { - "fs", "ps", "ns", "us", "ms", "s" -}; +const char* const g_timeUnits[] = { "fs", "ps", "ns", "us", "ms", "s" }; /*! \brief * Scaling factors from each time unit to internal units (=picoseconds). * * These must correspond to the TimeUnit enum in the header! */ -const double g_timeScaleFactors[] = { - 1e-3, 1, 1e3, 1e6, 1e9, 1e12 -}; +const double g_timeScaleFactors[] = { 1e-3, 1, 1e3, 1e6, 1e9, 1e12 }; } // namespace namespace gmx { -TimeUnitManager::TimeUnitManager() - : timeUnit_(TimeUnit_Default) -{ -} +TimeUnitManager::TimeUnitManager() : timeUnit_(TimeUnit_Default) {} -TimeUnitManager::TimeUnitManager(TimeUnit unit) - : timeUnit_(unit) +TimeUnitManager::TimeUnitManager(TimeUnit unit) : timeUnit_(unit) { - GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, - "Invalid time unit"); + GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit"); } void TimeUnitManager::setTimeUnit(TimeUnit unit) { - GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, - "Invalid time unit"); + GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit"); timeUnit_ = unit; } -const char *TimeUnitManager::timeUnitAsString() const +const char* TimeUnitManager::timeUnitAsString() const { - GMX_RELEASE_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, - "Invalid time unit"); + GMX_RELEASE_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, "Invalid time unit"); return g_timeUnits[timeUnit_]; } double TimeUnitManager::timeScaleFactor() const { GMX_RELEASE_ASSERT(timeUnit_ >= 0 - && static_cast(timeUnit_) < sizeof(g_timeScaleFactors)/sizeof(g_timeScaleFactors[0]), + && static_cast(timeUnit_) + < sizeof(g_timeScaleFactors) / sizeof(g_timeScaleFactors[0]), "Time unit index has become out-of-range"); return g_timeScaleFactors[timeUnit_]; } @@ -124,15 +114,11 @@ double TimeUnitManager::inverseTimeScaleFactor() const * TimeUnitBehavior */ -TimeUnitBehavior::TimeUnitBehavior() - : timeUnit_(TimeUnit_Default), timeUnitStore_(nullptr) -{ -} +TimeUnitBehavior::TimeUnitBehavior() : timeUnit_(TimeUnit_Default), timeUnitStore_(nullptr) {} void TimeUnitBehavior::setTimeUnit(TimeUnit unit) { - GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, - "Invalid time unit"); + GMX_RELEASE_ASSERT(unit >= 0 && unit <= TimeUnit_s, "Invalid time unit"); timeUnit_ = unit; if (timeUnitStore_ != nullptr) { @@ -140,7 +126,7 @@ void TimeUnitBehavior::setTimeUnit(TimeUnit unit) } } -void TimeUnitBehavior::setTimeUnitStore(TimeUnit *store) +void TimeUnitBehavior::setTimeUnitStore(TimeUnit* store) { timeUnitStore_ = store; *store = timeUnit(); @@ -148,30 +134,29 @@ void TimeUnitBehavior::setTimeUnitStore(TimeUnit *store) void TimeUnitBehavior::setTimeUnitFromEnvironment() { - const char *const value = std::getenv("GMXTIMEUNIT"); + const char* const value = std::getenv("GMXTIMEUNIT"); if (value != nullptr) { - ArrayRef timeUnits(g_timeUnits); - ArrayRef::const_iterator i = - std::find(timeUnits.begin(), timeUnits.end(), std::string(value)); + ArrayRef timeUnits(g_timeUnits); + ArrayRef::const_iterator i = + std::find(timeUnits.begin(), timeUnits.end(), std::string(value)); if (i == timeUnits.end()) { std::string message = formatString( - "Time unit provided with environment variable GMXTIMEUNIT=%s " - "is not recognized as a valid time unit.\n" - "Possible values are: %s", - value, joinStrings(timeUnits, ", ").c_str()); + "Time unit provided with environment variable GMXTIMEUNIT=%s " + "is not recognized as a valid time unit.\n" + "Possible values are: %s", + value, joinStrings(timeUnits, ", ").c_str()); GMX_THROW(InvalidInputError(message)); } setTimeUnit(static_cast(i - timeUnits.begin())); } } -void TimeUnitBehavior::addTimeUnitOption(IOptionsContainer *options, const char *name) +void TimeUnitBehavior::addTimeUnitOption(IOptionsContainer* options, const char* name) { - options->addOption(EnumOption(name).enumValue(g_timeUnits) - .store(&timeUnit_) - .description("Unit for time values")); + options->addOption( + EnumOption(name).enumValue(g_timeUnits).store(&timeUnit_).description("Unit for time values")); } namespace @@ -185,35 +170,35 @@ namespace * * \ingroup module_options */ -template +template class TimeOptionScaler : public OptionsModifyingTypeVisitor { - public: - //! Initializes a scaler with the given factor. - explicit TimeOptionScaler(double factor) : factor_(factor) {} +public: + //! Initializes a scaler with the given factor. + explicit TimeOptionScaler(double factor) : factor_(factor) {} - void visitSection(OptionSectionInfo *section) override - { - OptionsModifyingIterator iterator(section); - iterator.acceptSections(this); - iterator.acceptOptions(this); - } + void visitSection(OptionSectionInfo* section) override + { + OptionsModifyingIterator iterator(section); + iterator.acceptSections(this); + iterator.acceptOptions(this); + } - void visitOptionType(FloatingPointOptionInfo *option) override + void visitOptionType(FloatingPointOptionInfo* option) override + { + if (option->isTime()) { - if (option->isTime()) - { - option->setScaleFactor(factor_); - } + option->setScaleFactor(factor_); } + } - private: - double factor_; +private: + double factor_; }; -} // namespace +} // namespace -void TimeUnitBehavior::optionsFinishing(Options *options) +void TimeUnitBehavior::optionsFinishing(Options* options) { double factor = TimeUnitManager(timeUnit()).timeScaleFactor(); TimeOptionScaler(factor).visitSection(&options->rootSection()); diff --git a/src/gromacs/options/timeunitmanager.h b/src/gromacs/options/timeunitmanager.h index 9e23bdea8b..5aa9742a50 100644 --- a/src/gromacs/options/timeunitmanager.h +++ b/src/gromacs/options/timeunitmanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,13 +65,13 @@ class Options; */ enum TimeUnit { - TimeUnit_fs, //!< Femtoseconds. - TimeUnit_ps, //!< Picoseconds. - TimeUnit_ns, //!< Nanoseconds. - TimeUnit_us, //!< Microseconds. - TimeUnit_ms, //!< Milliseconds. - TimeUnit_s, //!< Seconds. - TimeUnit_Default = TimeUnit_ps //!< Default time unit. + TimeUnit_fs, //!< Femtoseconds. + TimeUnit_ps, //!< Picoseconds. + TimeUnit_ns, //!< Nanoseconds. + TimeUnit_us, //!< Microseconds. + TimeUnit_ms, //!< Milliseconds. + TimeUnit_s, //!< Seconds. + TimeUnit_Default = TimeUnit_ps //!< Default time unit. }; /*! \brief @@ -96,33 +96,33 @@ enum TimeUnit */ class TimeUnitManager { - public: - //! Creates a time unit manager with the default (ps) time unit. - TimeUnitManager(); - //! Creates a time unit manager with the given time unit. - explicit TimeUnitManager(TimeUnit unit); - - //! Returns the currently selected time unit. - TimeUnit timeUnit() const - { - GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, - "Time unit index has become out-of-range"); - return timeUnit_; - } - //! Set a new time unit for the manager. - void setTimeUnit(TimeUnit unit); - - //! Returns a string constant corresponding to the current time unit. - const char *timeUnitAsString() const; - - //! Returns the scaling factor to convert times to ps. - double timeScaleFactor() const; - //! Returns the scaling factor to convert times from ps. - double inverseTimeScaleFactor() const; - - private: - //! Currently set time unit for this manager. - TimeUnit timeUnit_; +public: + //! Creates a time unit manager with the default (ps) time unit. + TimeUnitManager(); + //! Creates a time unit manager with the given time unit. + explicit TimeUnitManager(TimeUnit unit); + + //! Returns the currently selected time unit. + TimeUnit timeUnit() const + { + GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, + "Time unit index has become out-of-range"); + return timeUnit_; + } + //! Set a new time unit for the manager. + void setTimeUnit(TimeUnit unit); + + //! Returns a string constant corresponding to the current time unit. + const char* timeUnitAsString() const; + + //! Returns the scaling factor to convert times to ps. + double timeScaleFactor() const; + //! Returns the scaling factor to convert times from ps. + double inverseTimeScaleFactor() const; + +private: + //! Currently set time unit for this manager. + TimeUnit timeUnit_; }; /*! \brief @@ -140,58 +140,58 @@ class TimeUnitManager */ class TimeUnitBehavior : public IOptionsBehavior { - public: - TimeUnitBehavior(); - - //! Returns the current time unit. - TimeUnit timeUnit() const - { - GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, - "Time unit index has become out-of-range"); - return static_cast(timeUnit_); - } - //! Sets the time unit. - void setTimeUnit(TimeUnit unit); - - /*! \brief - * Sets a storage location for the selected time unit. - * - * \param[in] store Location that will receive the selected time unit. - * - * \p *store will be set to the time unit selected by the user (or - * programmatically). The value is guaranteed to be set once the - * options have been finished. - */ - void setTimeUnitStore(TimeUnit *store); - - /*! \brief - * Sets the default time unit from an environment variable. - * - * This should be called before addTimeUnitOption() for consistent - * behavior. - */ - void setTimeUnitFromEnvironment(); - /*! \brief - * Adds a common option for selecting the time unit. - * - * \param[in,out] options Options to which the common option is added. - * \param[in] name Name of the option to add. - * - * Adds an enum option to \p options to select the time unit for this - * behavior. - */ - void addTimeUnitOption(IOptionsContainer *options, const char *name); - - // From IOptionsBehavior - void initBehavior(Options * /*options*/) override {} - void optionsFinishing(Options *options) override; - void optionsFinished() override {} - - private: - TimeUnit timeUnit_; - TimeUnit *timeUnitStore_; - - GMX_DISALLOW_COPY_AND_ASSIGN(TimeUnitBehavior); +public: + TimeUnitBehavior(); + + //! Returns the current time unit. + TimeUnit timeUnit() const + { + GMX_ASSERT(timeUnit_ >= 0 && timeUnit_ <= TimeUnit_s, + "Time unit index has become out-of-range"); + return static_cast(timeUnit_); + } + //! Sets the time unit. + void setTimeUnit(TimeUnit unit); + + /*! \brief + * Sets a storage location for the selected time unit. + * + * \param[in] store Location that will receive the selected time unit. + * + * \p *store will be set to the time unit selected by the user (or + * programmatically). The value is guaranteed to be set once the + * options have been finished. + */ + void setTimeUnitStore(TimeUnit* store); + + /*! \brief + * Sets the default time unit from an environment variable. + * + * This should be called before addTimeUnitOption() for consistent + * behavior. + */ + void setTimeUnitFromEnvironment(); + /*! \brief + * Adds a common option for selecting the time unit. + * + * \param[in,out] options Options to which the common option is added. + * \param[in] name Name of the option to add. + * + * Adds an enum option to \p options to select the time unit for this + * behavior. + */ + void addTimeUnitOption(IOptionsContainer* options, const char* name); + + // From IOptionsBehavior + void initBehavior(Options* /*options*/) override {} + void optionsFinishing(Options* options) override; + void optionsFinished() override {} + +private: + TimeUnit timeUnit_; + TimeUnit* timeUnitStore_; + + GMX_DISALLOW_COPY_AND_ASSIGN(TimeUnitBehavior); }; } // namespace gmx diff --git a/src/gromacs/options/treesupport.cpp b/src/gromacs/options/treesupport.cpp index aeb94fbe37..d8d14b58ff 100644 --- a/src/gromacs/options/treesupport.cpp +++ b/src/gromacs/options/treesupport.cpp @@ -65,275 +65,265 @@ namespace class TreeAssignHelper { - public: - TreeAssignHelper(Options *options, IKeyValueTreeErrorHandler *errorHandler) - : assigner_(options), errorHandler_(errorHandler) +public: + TreeAssignHelper(Options* options, IKeyValueTreeErrorHandler* errorHandler) : + assigner_(options), + errorHandler_(errorHandler) + { + if (errorHandler_ == nullptr) { - if (errorHandler_ == nullptr) - { - errorHandler_ = defaultKeyValueTreeErrorHandler(); - } + errorHandler_ = defaultKeyValueTreeErrorHandler(); } + } - void assignAll(const KeyValueTreeObject &root) - { - assigner_.start(); - assignSubTree(root); - assigner_.finish(); - } + void assignAll(const KeyValueTreeObject& root) + { + assigner_.start(); + assignSubTree(root); + assigner_.finish(); + } - private: - void assignSubTree(const KeyValueTreeObject &tree) +private: + void assignSubTree(const KeyValueTreeObject& tree) + { + // TODO: Use the error handler also in other case. + for (const KeyValueTreeProperty& prop : tree.properties()) { - // TODO: Use the error handler also in other case. - for (const KeyValueTreeProperty &prop : tree.properties()) + context_.append(prop.key()); + if (prop.value().isArray()) { - context_.append(prop.key()); - if (prop.value().isArray()) - { - assignArray(prop.key(), prop.value().asArray()); - } - else if (prop.value().isObject()) + assignArray(prop.key(), prop.value().asArray()); + } + else if (prop.value().isObject()) + { + assigner_.startSection(prop.key().c_str()); + assignSubTree(prop.value().asObject()); + assigner_.finishSection(); + } + else + { + assigner_.startOption(prop.key().c_str()); + try { - assigner_.startSection(prop.key().c_str()); - assignSubTree(prop.value().asObject()); - assigner_.finishSection(); + assigner_.appendValue(prop.value().asAny()); } - else + catch (UserInputError& ex) { - assigner_.startOption(prop.key().c_str()); - try - { - assigner_.appendValue(prop.value().asAny()); - } - catch (UserInputError &ex) + if (!errorHandler_->onError(&ex, context_)) { - if (!errorHandler_->onError(&ex, context_)) - { - throw; - } + throw; } - assigner_.finishOption(); } - context_.pop_back(); + assigner_.finishOption(); } + context_.pop_back(); } + } - void assignArray(const std::string &key, - const KeyValueTreeArray &array) + void assignArray(const std::string& key, const KeyValueTreeArray& array) + { + if (array.isObjectArray()) { - if (array.isObjectArray()) + for (const KeyValueTreeValue& value : array.values()) { - for (const KeyValueTreeValue &value : array.values()) - { - assigner_.startSection(key.c_str()); - assignSubTree(value.asObject()); - assigner_.finishSection(); - } + assigner_.startSection(key.c_str()); + assignSubTree(value.asObject()); + assigner_.finishSection(); } - else + } + else + { + assigner_.startOption(key.c_str()); + for (const KeyValueTreeValue& value : array.values()) { - assigner_.startOption(key.c_str()); - for (const KeyValueTreeValue &value : array.values()) - { - assigner_.appendValue(value.asAny()); - } - assigner_.finishOption(); + assigner_.appendValue(value.asAny()); } + assigner_.finishOption(); } + } - OptionsAssigner assigner_; - IKeyValueTreeErrorHandler *errorHandler_; - KeyValueTreePath context_; + OptionsAssigner assigner_; + IKeyValueTreeErrorHandler* errorHandler_; + KeyValueTreePath context_; }; class TreeCheckHelper : private OptionsVisitor { - public: - TreeCheckHelper(const KeyValueTreeObject &root) - : currentObject_(&root), currentKnownNames_(nullptr) - { - } +public: + TreeCheckHelper(const KeyValueTreeObject& root) : + currentObject_(&root), + currentKnownNames_(nullptr) + { + } - bool hasUnknownPaths() const { return !unknownPaths_.empty(); } - const std::vector &unknownPaths() const - { - return unknownPaths_; - } + bool hasUnknownPaths() const { return !unknownPaths_.empty(); } + const std::vector& unknownPaths() const { return unknownPaths_; } - void processOptionSection(const OptionSectionInfo §ion) + void processOptionSection(const OptionSectionInfo& section) + { + OptionsIterator iterator(section); + std::set knownNames; + currentKnownNames_ = &knownNames; + iterator.acceptOptions(this); + iterator.acceptSections(this); + currentKnownNames_ = nullptr; + for (const auto& prop : currentObject_->properties()) { - OptionsIterator iterator(section); - std::set knownNames; - currentKnownNames_ = &knownNames; - iterator.acceptOptions(this); - iterator.acceptSections(this); - currentKnownNames_ = nullptr; - for (const auto &prop : currentObject_->properties()) + if (knownNames.count(prop.key()) == 0) { - if (knownNames.count(prop.key()) == 0) - { - unknownPaths_.push_back(currentPath_ + prop.key()); - } + unknownPaths_.push_back(currentPath_ + prop.key()); } } + } - private: - void visitSection(const OptionSectionInfo §ion) override +private: + void visitSection(const OptionSectionInfo& section) override + { + const std::string& name = section.name(); + if (currentObject_->keyExists(name)) { - const std::string &name = section.name(); - if (currentObject_->keyExists(name)) - { - currentKnownNames_->insert(name); - auto parentObject = currentObject_; - auto parentKnownNames = currentKnownNames_; - // TODO: Consider what to do with mismatching types. - currentObject_ = &(*currentObject_)[name].asObject(); - currentPath_.append(name); - processOptionSection(section); - currentPath_.pop_back(); - currentObject_ = parentObject; - currentKnownNames_ = parentKnownNames; - } + currentKnownNames_->insert(name); + auto parentObject = currentObject_; + auto parentKnownNames = currentKnownNames_; + // TODO: Consider what to do with mismatching types. + currentObject_ = &(*currentObject_)[name].asObject(); + currentPath_.append(name); + processOptionSection(section); + currentPath_.pop_back(); + currentObject_ = parentObject; + currentKnownNames_ = parentKnownNames; } - void visitOption(const OptionInfo &option) override + } + void visitOption(const OptionInfo& option) override + { + const std::string& name = option.name(); + if (currentObject_->keyExists(name)) { - const std::string &name = option.name(); - if (currentObject_->keyExists(name)) - { - currentKnownNames_->insert(name); - // TODO: Consider what to do with mismatching types. - } + currentKnownNames_->insert(name); + // TODO: Consider what to do with mismatching types. } + } - KeyValueTreePath currentPath_; - const KeyValueTreeObject *currentObject_; - std::set *currentKnownNames_; - std::vector unknownPaths_; - + KeyValueTreePath currentPath_; + const KeyValueTreeObject* currentObject_; + std::set* currentKnownNames_; + std::vector unknownPaths_; }; class TreeAdjustHelper : private OptionsVisitor { - public: - TreeAdjustHelper(const KeyValueTreeObject &root, - KeyValueTreeBuilder *builder) - : currentSourceObject_(&root), - currentObjectBuilder_(builder->rootObject()) - { - } +public: + TreeAdjustHelper(const KeyValueTreeObject& root, KeyValueTreeBuilder* builder) : + currentSourceObject_(&root), + currentObjectBuilder_(builder->rootObject()) + { + } - void processOptionSection(const OptionSectionInfo §ion) - { - OptionsIterator iterator(section); - iterator.acceptOptions(this); - iterator.acceptSections(this); - } + void processOptionSection(const OptionSectionInfo& section) + { + OptionsIterator iterator(section); + iterator.acceptOptions(this); + iterator.acceptSections(this); + } - private: - void visitSection(const OptionSectionInfo §ion) override - { - const std::string &name = section.name(); - auto parentBuilder = currentObjectBuilder_; - auto parentObject = currentSourceObject_; - currentObjectBuilder_ = currentObjectBuilder_.addObject(name); - currentSourceObject_ = - (currentSourceObject_ != nullptr && currentSourceObject_->keyExists(name) - ? &(*currentSourceObject_)[name].asObject() - : nullptr); - processOptionSection(section); - currentSourceObject_ = parentObject; - currentObjectBuilder_ = parentBuilder; - } - void visitOption(const OptionInfo &option) override +private: + void visitSection(const OptionSectionInfo& section) override + { + const std::string& name = section.name(); + auto parentBuilder = currentObjectBuilder_; + auto parentObject = currentSourceObject_; + currentObjectBuilder_ = currentObjectBuilder_.addObject(name); + currentSourceObject_ = (currentSourceObject_ != nullptr && currentSourceObject_->keyExists(name) + ? &(*currentSourceObject_)[name].asObject() + : nullptr); + processOptionSection(section); + currentSourceObject_ = parentObject; + currentObjectBuilder_ = parentBuilder; + } + void visitOption(const OptionInfo& option) override + { + const std::string& name = option.name(); + if (currentSourceObject_ == nullptr || !currentSourceObject_->keyExists(name)) { - const std::string &name = option.name(); - if (currentSourceObject_ == nullptr || !currentSourceObject_->keyExists(name)) + std::vector values = option.defaultValues(); + if (values.size() == 1) + { + currentObjectBuilder_.addRawValue(name, std::move(values[0])); + } + else if (values.size() > 1) { - std::vector values = option.defaultValues(); - if (values.size() == 1) + auto arrayBuilder = currentObjectBuilder_.addArray(name); + for (Any& value : values) { - currentObjectBuilder_.addRawValue(name, std::move(values[0])); + arrayBuilder.addRawValue(std::move(value)); } - else if (values.size() > 1) + } + } + else + { + const KeyValueTreeValue& value = (*currentSourceObject_)[name]; + GMX_RELEASE_ASSERT(!value.isObject(), "Value objects not supported in this context"); + std::vector values; + if (value.isArray()) + { + for (const auto& arrayValue : value.asArray().values()) { - auto arrayBuilder = currentObjectBuilder_.addArray(name); - for (Any &value : values) - { - arrayBuilder.addRawValue(std::move(value)); - } + GMX_RELEASE_ASSERT(!value.isObject() && !value.isArray(), + "Complex values not supported in this context"); + values.push_back(arrayValue.asAny()); } } else { - const KeyValueTreeValue &value = (*currentSourceObject_)[name]; - GMX_RELEASE_ASSERT(!value.isObject(), "Value objects not supported in this context"); - std::vector values; - if (value.isArray()) - { - for (const auto &arrayValue : value.asArray().values()) - { - GMX_RELEASE_ASSERT(!value.isObject() && !value.isArray(), - "Complex values not supported in this context"); - values.push_back(arrayValue.asAny()); - } - } - else - { - values.push_back(value.asAny()); - } - values = option.normalizeValues(values); - if (values.empty()) - { - } - else if (values.size() == 1) - { - currentObjectBuilder_.addRawValue(name, std::move(values[0])); - } - else + values.push_back(value.asAny()); + } + values = option.normalizeValues(values); + if (values.empty()) {} + else if (values.size() == 1) + { + currentObjectBuilder_.addRawValue(name, std::move(values[0])); + } + else + { + auto array = currentObjectBuilder_.addArray(name); + for (auto& arrayValue : values) { - auto array = currentObjectBuilder_.addArray(name); - for (auto &arrayValue : values) - { - array.addRawValue(std::move(arrayValue)); - } + array.addRawValue(std::move(arrayValue)); } } } + } - const KeyValueTreeObject *currentSourceObject_; - KeyValueTreeObjectBuilder currentObjectBuilder_; + const KeyValueTreeObject* currentSourceObject_; + KeyValueTreeObjectBuilder currentObjectBuilder_; }; -} // namespace +} // namespace //! \cond libapi -void assignOptionsFromKeyValueTree(Options *options, - const KeyValueTreeObject &tree, - IKeyValueTreeErrorHandler *errorHandler) +void assignOptionsFromKeyValueTree(Options* options, + const KeyValueTreeObject& tree, + IKeyValueTreeErrorHandler* errorHandler) { TreeAssignHelper helper(options, errorHandler); helper.assignAll(tree); } -void checkForUnknownOptionsInKeyValueTree(const KeyValueTreeObject &tree, - const Options &options) +void checkForUnknownOptionsInKeyValueTree(const KeyValueTreeObject& tree, const Options& options) { TreeCheckHelper helper(tree); helper.processOptionSection(options.rootSection()); if (helper.hasUnknownPaths()) { std::string paths(formatAndJoin(helper.unknownPaths(), "\n ", - [](const KeyValueTreePath &path) { return path.toString(); })); + [](const KeyValueTreePath& path) { return path.toString(); })); std::string message("Unknown input values:\n " + paths); GMX_THROW(InvalidInputError(message)); } } -KeyValueTreeObject -adjustKeyValueTreeFromOptions(const KeyValueTreeObject &tree, - const Options &options) +KeyValueTreeObject adjustKeyValueTreeFromOptions(const KeyValueTreeObject& tree, const Options& options) { KeyValueTreeBuilder builder; TreeAdjustHelper helper(tree, &builder); diff --git a/src/gromacs/options/treesupport.h b/src/gromacs/options/treesupport.h index 479e1f534e..142305cb7c 100644 --- a/src/gromacs/options/treesupport.h +++ b/src/gromacs/options/treesupport.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,9 +61,9 @@ class Options; * * \ingroup module_options */ -void assignOptionsFromKeyValueTree(Options *options, - const KeyValueTreeObject &tree, - IKeyValueTreeErrorHandler *errorHandler); +void assignOptionsFromKeyValueTree(Options* options, + const KeyValueTreeObject& tree, + IKeyValueTreeErrorHandler* errorHandler); /*! \libinternal \brief * Checks that a given KeyValueTreeObject can be assigned to given Options. * @@ -73,8 +73,7 @@ void assignOptionsFromKeyValueTree(Options *options, * * \ingroup module_options */ -void checkForUnknownOptionsInKeyValueTree(const KeyValueTreeObject &tree, - const Options &options); +void checkForUnknownOptionsInKeyValueTree(const KeyValueTreeObject& tree, const Options& options); /*! \libinternal \brief * Adjusts a KeyValueTreeObject to the structure of given Options. * @@ -95,9 +94,7 @@ void checkForUnknownOptionsInKeyValueTree(const KeyValueTreeObject &tree, * * \ingroup module_options */ -KeyValueTreeObject -adjustKeyValueTreeFromOptions(const KeyValueTreeObject &tree, - const Options &options); +KeyValueTreeObject adjustKeyValueTreeFromOptions(const KeyValueTreeObject& tree, const Options& options); //! \endcond diff --git a/src/gromacs/options/valueconverter.h b/src/gromacs/options/valueconverter.h index 03c7a72c12..1f64e41fc7 100644 --- a/src/gromacs/options/valueconverter.h +++ b/src/gromacs/options/valueconverter.h @@ -66,66 +66,62 @@ namespace gmx * \inlibraryapi * \ingroup module_options */ -template +template class OptionValueConverterSimple { - public: - /*! \brief - * Converts a Any value to the output type. - * - * \returns Converted value. - * \throws InvalidInputError If the input Any has a type that is - * not recognized by any conversion. - */ - OutType convert(const Any &value) const +public: + /*! \brief + * Converts a Any value to the output type. + * + * \returns Converted value. + * \throws InvalidInputError If the input Any has a type that is + * not recognized by any conversion. + */ + OutType convert(const Any& value) const + { + std::type_index type(value.type()); + auto iter = converters_.find(type); + if (iter == converters_.end()) { - std::type_index type(value.type()); - auto iter = converters_.find(type); - if (iter == converters_.end()) + if (value.isType()) { - if (value.isType()) - { - return value.cast(); - } - GMX_THROW(InvalidInputError("Invalid type of value")); + return value.cast(); } - return iter->second(value); + GMX_THROW(InvalidInputError("Invalid type of value")); } + return iter->second(value); + } - /*! \brief - * Adds a supported conversion. - * - * \tparam InType Type to convert from. - * \param func Function to convert from `InType` to `OutType`. - */ - template - void addConverter(std::function func) - { - converters_[std::type_index(typeid(InType))] = - [func] (const Any &value) - { - return func(value.cast()); - }; - } - /*! \brief - * Adds a supported conversion from a type that can be directly cast. - * - * \tparam InType Type to convert from with a simple cast. - */ - template - void addCastConversion() - { - converters_[std::type_index(typeid(InType))] = - [] (const Any &value) - { - return static_cast(value.cast()); - }; - } + /*! \brief + * Adds a supported conversion. + * + * \tparam InType Type to convert from. + * \param func Function to convert from `InType` to `OutType`. + */ + template + void addConverter(std::function func) + { + converters_[std::type_index(typeid(InType))] = [func](const Any& value) { + return func(value.cast()); + }; + } + /*! \brief + * Adds a supported conversion from a type that can be directly cast. + * + * \tparam InType Type to convert from with a simple cast. + */ + template + void addCastConversion() + { + converters_[std::type_index(typeid(InType))] = [](const Any& value) { + return static_cast(value.cast()); + }; + } - private: - typedef std::function ConversionFunction; +private: + typedef std::function ConversionFunction; - std::map converters_; + std::map converters_; }; } // namespace gmx diff --git a/src/gromacs/options/valuestore.h b/src/gromacs/options/valuestore.h index 2eaa48d1f3..1352f63e09 100644 --- a/src/gromacs/options/valuestore.h +++ b/src/gromacs/options/valuestore.h @@ -51,105 +51,96 @@ namespace gmx { -template +template class OptionValueStorePlain : public IOptionValueStore { - public: - OptionValueStorePlain(T *store, int *storeCount, int initialCount) - : count_(initialCount), store_(store), storeCount_(storeCount) +public: + OptionValueStorePlain(T* store, int* storeCount, int initialCount) : + count_(initialCount), + store_(store), + storeCount_(storeCount) + { + } + + int valueCount() override { return count_; } + ArrayRef values() override { return arrayRefFromArray(store_, count_); } + void clear() override + { + count_ = 0; + if (storeCount_ != nullptr) { + *storeCount_ = count_; } - - int valueCount() override { return count_; } - ArrayRef values() override { return arrayRefFromArray(store_, count_); } - void clear() override - { - count_ = 0; - if (storeCount_ != nullptr) - { - *storeCount_ = count_; - } - } - void reserve(size_t /*count*/) override + } + void reserve(size_t /*count*/) override {} + void append(const T& value) override + { + store_[count_] = value; + ++count_; + if (storeCount_ != nullptr) { + *storeCount_ = count_; } - void append(const T &value) override - { - store_[count_] = value; - ++count_; - if (storeCount_ != nullptr) - { - *storeCount_ = count_; - } - } + } - private: - int count_; - T *store_; - int *storeCount_; +private: + int count_; + T* store_; + int* storeCount_; }; -template +template class OptionValueStoreVector : public IOptionValueStore { - public: - explicit OptionValueStoreVector(std::vector *store) : store_(store) {} +public: + explicit OptionValueStoreVector(std::vector* store) : store_(store) {} - int valueCount() override { return static_cast(store_->size()); } - ArrayRef values() override { return *store_; } - void clear() override { store_->clear(); } - void reserve(size_t count) override - { - store_->reserve(store_->size() + count); - } - void append(const T &value) override - { - store_->push_back(value); - } + int valueCount() override { return static_cast(store_->size()); } + ArrayRef values() override { return *store_; } + void clear() override { store_->clear(); } + void reserve(size_t count) override { store_->reserve(store_->size() + count); } + void append(const T& value) override { store_->push_back(value); } - private: - std::vector *store_; +private: + std::vector* store_; }; // Specialization that works around std::vector specialities. -template <> +template<> class OptionValueStoreVector : public IOptionValueStore { - public: - explicit OptionValueStoreVector(std::vector *store) : store_(store) - { - } - - int valueCount() override { return static_cast(store_->size()); } - ArrayRef values() override - { - return arrayRefFromArray(reinterpret_cast(boolStore_.data()), - boolStore_.size()); - } - void clear() override - { - boolStore_.clear(); - store_->clear(); - } - void reserve(size_t count) override - { - boolStore_.reserve(boolStore_.size() + count); - store_->reserve(store_->size() + count); - } - void append(const bool &value) override - { - boolStore_.push_back({value}); - store_->push_back(value); - } - - private: - struct Bool - { - bool value; - }; - - std::vector boolStore_; - std::vector *store_; +public: + explicit OptionValueStoreVector(std::vector* store) : store_(store) {} + + int valueCount() override { return static_cast(store_->size()); } + ArrayRef values() override + { + return arrayRefFromArray(reinterpret_cast(boolStore_.data()), boolStore_.size()); + } + void clear() override + { + boolStore_.clear(); + store_->clear(); + } + void reserve(size_t count) override + { + boolStore_.reserve(boolStore_.size() + count); + store_->reserve(store_->size() + count); + } + void append(const bool& value) override + { + boolStore_.push_back({ value }); + store_->push_back(value); + } + +private: + struct Bool + { + bool value; + }; + + std::vector boolStore_; + std::vector* store_; }; /*! \internal @@ -161,21 +152,21 @@ class OptionValueStoreVector : public IOptionValueStore * * \ingroup module_options */ -template +template class OptionValueStoreNull : public IOptionValueStore { - public: - OptionValueStoreNull() : store_(&vector_) {} - - int valueCount() override { return store_.valueCount(); } - ArrayRef values() override { return store_.values(); } - void clear() override { store_.clear(); } - void reserve(size_t count) override { store_.reserve(count); } - void append(const T &value) override { store_.append(value); } - - private: - std::vector vector_; - OptionValueStoreVector store_; +public: + OptionValueStoreNull() : store_(&vector_) {} + + int valueCount() override { return store_.valueCount(); } + ArrayRef values() override { return store_.values(); } + void clear() override { store_.clear(); } + void reserve(size_t count) override { store_.reserve(count); } + void append(const T& value) override { store_.append(value); } + +private: + std::vector vector_; + OptionValueStoreVector store_; }; } // namespace gmx diff --git a/src/gromacs/pbcutil/boxutilities.cpp b/src/gromacs/pbcutil/boxutilities.cpp index 4ee39267ce..ef7b20c870 100644 --- a/src/gromacs/pbcutil/boxutilities.cpp +++ b/src/gromacs/pbcutil/boxutilities.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,8 +48,7 @@ #include "gromacs/math/vec.h" #include "gromacs/math/vectypes.h" -void do_box_rel(int ndim, const matrix deform, matrix box_rel, - matrix b, bool bInit) +void do_box_rel(int ndim, const matrix deform, matrix box_rel, matrix b, bool bInit) { for (int d = YY; d <= ZZ; ++d) { @@ -59,17 +58,16 @@ void do_box_rel(int ndim, const matrix deform, matrix box_rel, * or if deformation of another component might cause * changes in this component due to box corrections. */ - if (deform[d][d2] == 0 && - !(d == ZZ && d2 == XX && deform[d][YY] != 0 && - (b[YY][d2] != 0 || deform[YY][d2] != 0))) + if (deform[d][d2] == 0 + && !(d == ZZ && d2 == XX && deform[d][YY] != 0 && (b[YY][d2] != 0 || deform[YY][d2] != 0))) { if (bInit) { - box_rel[d][d2] = b[d][d2]/b[XX][XX]; + box_rel[d][d2] = b[d][d2] / b[XX][XX]; } else { - b[d][d2] = b[XX][XX]*box_rel[d][d2]; + b[d][d2] = b[XX][XX] * box_rel[d][d2]; } } } @@ -88,30 +86,24 @@ bool boxElementEqual(real element1, real element2) // Compare with a relative tolerance (for big boxes) and with // an absolute tolerance (small boxes are generally not specified with very // high number of decimals). - return gmx_within_tol(element1, element2, 10*GMX_REAL_EPS) - || std::fabs(element1 - element2) < 1e-3; + return gmx_within_tol(element1, element2, 10 * GMX_REAL_EPS) || std::fabs(element1 - element2) < 1e-3; } -} // namespace +} // namespace bool boxesAreEqual(const matrix box1, const matrix box2) { - return boxElementEqual(box1[XX][XX], box2[XX][XX]) - && boxElementEqual(box1[YY][XX], box2[YY][XX]) + return boxElementEqual(box1[XX][XX], box2[XX][XX]) && boxElementEqual(box1[YY][XX], box2[YY][XX]) && boxElementEqual(box1[YY][YY], box2[YY][YY]) - && boxElementEqual(box1[ZZ][XX], box2[ZZ][XX]) - && boxElementEqual(box1[ZZ][YY], box2[ZZ][YY]) + && boxElementEqual(box1[ZZ][XX], box2[ZZ][XX]) && boxElementEqual(box1[ZZ][YY], box2[ZZ][YY]) && boxElementEqual(box1[ZZ][ZZ], box2[ZZ][ZZ]); } bool boxIsZero(const matrix box) { - return boxElementEqual(box[XX][XX], 0.0) - && boxElementEqual(box[YY][XX], 0.0) - && boxElementEqual(box[YY][YY], 0.0) - && boxElementEqual(box[ZZ][XX], 0.0) - && boxElementEqual(box[ZZ][YY], 0.0) - && boxElementEqual(box[ZZ][ZZ], 0.0); + return boxElementEqual(box[XX][XX], 0.0) && boxElementEqual(box[YY][XX], 0.0) + && boxElementEqual(box[YY][YY], 0.0) && boxElementEqual(box[ZZ][XX], 0.0) + && boxElementEqual(box[ZZ][YY], 0.0) && boxElementEqual(box[ZZ][ZZ], 0.0); } } // namespace gmx diff --git a/src/gromacs/pbcutil/boxutilities.h b/src/gromacs/pbcutil/boxutilities.h index d60f6bfb99..a40d02e591 100644 --- a/src/gromacs/pbcutil/boxutilities.h +++ b/src/gromacs/pbcutil/boxutilities.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,8 +43,7 @@ * * Change box components to box[XX][XX]*box_rel to preserve the relative box shape */ -void do_box_rel(int ndim, const matrix deform, matrix box_rel, - matrix b, bool bInit); +void do_box_rel(int ndim, const matrix deform, matrix box_rel, matrix b, bool bInit); namespace gmx { diff --git a/src/gromacs/pbcutil/ishift.h b/src/gromacs/pbcutil/ishift.h index 464f3c0139..8374337437 100644 --- a/src/gromacs/pbcutil/ishift.h +++ b/src/gromacs/pbcutil/ishift.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,17 +40,17 @@ #define D_BOX_Z 1 #define D_BOX_Y 1 #define D_BOX_X 2 -#define N_BOX_Z (2*D_BOX_Z+1) -#define N_BOX_Y (2*D_BOX_Y+1) -#define N_BOX_X (2*D_BOX_X+1) -#define N_IVEC (N_BOX_Z*N_BOX_Y*N_BOX_X) -#define CENTRAL (N_IVEC/2) -#define SHIFTS N_IVEC +#define N_BOX_Z (2 * D_BOX_Z + 1) +#define N_BOX_Y (2 * D_BOX_Y + 1) +#define N_BOX_X (2 * D_BOX_X + 1) +#define N_IVEC (N_BOX_Z * N_BOX_Y * N_BOX_X) +#define CENTRAL (N_IVEC / 2) +#define SHIFTS N_IVEC -#define XYZ2IS(x, y, z) (N_BOX_X*(N_BOX_Y*((z)+D_BOX_Z)+(y)+D_BOX_Y)+(x)+D_BOX_X) -#define IVEC2IS(iv) (XYZ2IS((iv)[XX], (iv)[YY], (iv)[ZZ])) -#define IS2X(iv) (((iv) % N_BOX_X) - D_BOX_X) -#define IS2Y(iv) ((((iv) / N_BOX_X) % N_BOX_Y) - D_BOX_Y) -#define IS2Z(iv) ((iv) / (N_BOX_X*N_BOX_Y) - D_BOX_Z) +#define XYZ2IS(x, y, z) (N_BOX_X * (N_BOX_Y * ((z) + D_BOX_Z) + (y) + D_BOX_Y) + (x) + D_BOX_X) +#define IVEC2IS(iv) (XYZ2IS((iv)[XX], (iv)[YY], (iv)[ZZ])) +#define IS2X(iv) (((iv) % N_BOX_X) - D_BOX_X) +#define IS2Y(iv) ((((iv) / N_BOX_X) % N_BOX_Y) - D_BOX_Y) +#define IS2Z(iv) ((iv) / (N_BOX_X * N_BOX_Y) - D_BOX_Z) #endif diff --git a/src/gromacs/pbcutil/mshift.cpp b/src/gromacs/pbcutil/mshift.cpp index 1c5be20466..1941716347 100644 --- a/src/gromacs/pbcutil/mshift.cpp +++ b/src/gromacs/pbcutil/mshift.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,11 +65,11 @@ * ************************************************************/ -static void add_gbond(t_graph *g, int a0, int a1) +static void add_gbond(t_graph* g, int a0, int a1) { - int i; - int inda0, inda1; - gmx_bool bFound; + int i; + int inda0, inda1; + gmx_bool bFound; inda0 = a0 - g->at_start; inda1 = a1 - g->at_start; @@ -94,14 +94,12 @@ static void add_gbond(t_graph *g, int a0, int a1) * When a non-null part array is supplied with part indices for each atom, * edges are only added when atoms have a different part index. */ -template -static bool mk_igraph(t_graph *g, int ftype, const T &il, - int at_start, int at_end, - const int *part) +template +static bool mk_igraph(t_graph* g, int ftype, const T& il, int at_start, int at_end, const int* part) { - int i, j, np; - int end; - bool addedEdge = false; + int i, j, np; + int end; + bool addedEdge = false; end = il.size(); @@ -134,7 +132,7 @@ static bool mk_igraph(t_graph *g, int ftype, const T &il, /* Simply add this bond */ for (j = 1; j < np; j++) { - add_gbond(g, il.iatoms[i + j], il.iatoms[i + j+1]); + add_gbond(g, il.iatoms[i + j], il.iatoms[i + j + 1]); } addedEdge = true; } @@ -143,32 +141,33 @@ static bool mk_igraph(t_graph *g, int ftype, const T &il, /* Add this bond when it connects two unlinked parts of the graph */ for (j = 1; j < np; j++) { - if (part[il.iatoms[i + j]] != part[il.iatoms[i + j+1]]) + if (part[il.iatoms[i + j]] != part[il.iatoms[i + j + 1]]) { - add_gbond(g, il.iatoms[i + j], il.iatoms[i + j+1]); + add_gbond(g, il.iatoms[i + j], il.iatoms[i + j + 1]); addedEdge = true; } } } } - i += np+1; + i += np + 1; } return addedEdge; } -[[noreturn]] static void g_error(int line, const char *file) +[[noreturn]] static void g_error(int line, const char* file) { - gmx_fatal(FARGS, "Trying to print nonexistent graph (file %s, line %d)", - file, line); + gmx_fatal(FARGS, "Trying to print nonexistent graph (file %s, line %d)", file, line); } -#define GCHECK(g) if ((g) == NULL) g_error(__LINE__, __FILE__) +#define GCHECK(g) \ + if ((g) == NULL) \ + g_error(__LINE__, __FILE__) -void p_graph(FILE *log, const char *title, t_graph *g) +void p_graph(FILE* log, const char* title, t_graph* g) { int i, j; - const char *cc[egcolNR] = { "W", "G", "B" }; + const char* cc[egcolNR] = { "W", "G", "B" }; GCHECK(g); fprintf(log, "graph: %s\n", title); @@ -181,15 +180,12 @@ void p_graph(FILE *log, const char *title, t_graph *g) { if (g->nedge[i] > 0) { - fprintf(log, "%5d%7d%7d%7d %1s%5d", g->at_start+i+1, - g->ishift[g->at_start+i][XX], - g->ishift[g->at_start+i][YY], - g->ishift[g->at_start+i][ZZ], - (g->negc > 0) ? cc[g->egc[i]] : " ", - g->nedge[i]); + fprintf(log, "%5d%7d%7d%7d %1s%5d", g->at_start + i + 1, g->ishift[g->at_start + i][XX], + g->ishift[g->at_start + i][YY], g->ishift[g->at_start + i][ZZ], + (g->negc > 0) ? cc[g->egc[i]] : " ", g->nedge[i]); for (j = 0; (j < g->nedge[i]); j++) { - fprintf(log, " %5d", g->edge[i][j]+1); + fprintf(log, " %5d", g->edge[i][j] + 1); } fprintf(log, "\n"); } @@ -197,11 +193,10 @@ void p_graph(FILE *log, const char *title, t_graph *g) fflush(log); } -template -static void calc_1se(t_graph *g, int ftype, const T &il, - int nbond[], int at_start, int at_end) +template +static void calc_1se(t_graph* g, int ftype, const T& il, int nbond[], int at_start, int at_end) { - int k, nratoms, end, j; + int k, nratoms, end, j; end = il.size(); @@ -214,11 +209,11 @@ static void calc_1se(t_graph *g, int ftype, const T &il, const int iaa = il.iatoms[j + 1]; if (iaa >= at_start && iaa < at_end) { - nbond[iaa] += 2; + nbond[iaa] += 2; nbond[il.iatoms[j + 2]] += 1; nbond[il.iatoms[j + 3]] += 1; - g->at_start = std::min(g->at_start, iaa); - g->at_end = std::max(g->at_end, iaa+2+1); + g->at_start = std::min(g->at_start, iaa); + g->at_end = std::max(g->at_end, iaa + 2 + 1); } } else @@ -229,7 +224,7 @@ static void calc_1se(t_graph *g, int ftype, const T &il, if (iaa >= at_start && iaa < at_end) { g->at_start = std::min(g->at_start, iaa); - g->at_end = std::max(g->at_end, iaa+1); + g->at_end = std::max(g->at_end, iaa + 1); /* When making the graph we (might) link all atoms in an interaction * sequentially. Therefore the end atoms add 1 to the count, * the middle atoms 2. @@ -248,12 +243,10 @@ static void calc_1se(t_graph *g, int ftype, const T &il, } } -template -static int calc_start_end(FILE *fplog, t_graph *g, const T il[], - int at_start, int at_end, - int nbond[]) +template +static int calc_start_end(FILE* fplog, t_graph* g, const T il[], int at_start, int at_end, int nbond[]) { - int i, nnb, nbtot; + int i, nnb, nbtot; g->at_start = at_end; g->at_end = 0; @@ -284,7 +277,7 @@ static int calc_start_end(FILE *fplog, t_graph *g, const T il[], for (i = g->at_start; (i < g->at_end); i++) { nbtot += nbond[i]; - nnb = std::max(nnb, nbond[i]); + nnb = std::max(nnb, nbond[i]); } if (fplog) { @@ -295,10 +288,9 @@ static int calc_start_end(FILE *fplog, t_graph *g, const T il[], } - -static void compact_graph(FILE *fplog, t_graph *g) +static void compact_graph(FILE* fplog, t_graph* g) { - int i, j, n, max_nedge; + int i, j, n, max_nedge; max_nedge = 0; n = 0; @@ -314,18 +306,17 @@ static void compact_graph(FILE *fplog, t_graph *g) /* set pointers after srenew because edge[0] might move */ for (i = 1; i < g->nnodes; i++) { - g->edge[i] = g->edge[i-1] + g->nedge[i-1]; + g->edge[i] = g->edge[i - 1] + g->nedge[i - 1]; } if (fplog) { - fprintf(fplog, "Max number of graph edges per atom is %d\n", - max_nedge); + fprintf(fplog, "Max number of graph edges per atom is %d\n", max_nedge); fprintf(fplog, "Total number of graph edges is %d\n", n); } } -static gmx_bool determine_graph_parts(t_graph *g, int *part) +static gmx_bool determine_graph_parts(t_graph* g, int* part) { int i, e; int nchanged; @@ -368,34 +359,35 @@ static gmx_bool determine_graph_parts(t_graph *g, int *part) } if (debug) { - fprintf(debug, "graph part[] nchanged=%d, bMultiPart=%s\n", - nchanged, gmx::boolToString(bMultiPart)); + fprintf(debug, "graph part[] nchanged=%d, bMultiPart=%s\n", nchanged, + gmx::boolToString(bMultiPart)); } - } - while (nchanged > 0); + } while (nchanged > 0); return bMultiPart; } -template -static void -mk_graph_ilist(FILE *fplog, - const T *ilist, int at_start, int at_end, - gmx_bool bShakeOnly, gmx_bool bSettle, - t_graph *g) +template +static void mk_graph_ilist(FILE* fplog, + const T* ilist, + int at_start, + int at_end, + gmx_bool bShakeOnly, + gmx_bool bSettle, + t_graph* g) { - int *nbond; - int i, nbtot; - gmx_bool bMultiPart; + int* nbond; + int i, nbtot; + gmx_bool bMultiPart; /* The naming is somewhat confusing, but we need g->at0 and g->at1 * for shifthing coordinates to a new array (not in place) when * some atoms are not connected by the graph, which runs from * g->at_start (>= g->at0) to g->at_end (<= g->at1). */ - g->at0 = at_start; - g->at1 = at_end; - g->parts = t_graph::BondedParts::Single; + g->at0 = at_start; + g->at1 = at_end; + g->parts = t_graph::BondedParts::Single; snew(nbond, at_end); nbtot = calc_start_end(fplog, g, ilist, at_start, at_end, nbond); @@ -416,7 +408,7 @@ mk_graph_ilist(FILE *fplog, snew(g->edge[0], nbtot); for (i = 1; (i < g->nnodes); i++) { - g->edge[i] = g->edge[i-1] + nbond[g->at_start+i-1]; + g->edge[i] = g->edge[i - 1] + nbond[g->at_start + i - 1]; } if (!bShakeOnly) @@ -448,9 +440,8 @@ mk_graph_ilist(FILE *fplog, { if (!(interaction_function[i].flags & IF_CHEMBOND)) { - bool addedEdgeForType = - mk_igraph(g, i, ilist[i], at_start, at_end, nbond); - addedEdge = (addedEdge || addedEdgeForType); + bool addedEdgeForType = mk_igraph(g, i, ilist[i], at_start, at_end, nbond); + addedEdge = (addedEdge || addedEdgeForType); } } @@ -499,19 +490,14 @@ mk_graph_ilist(FILE *fplog, } } -void mk_graph_moltype(const gmx_moltype_t &moltype, - t_graph *g) +void mk_graph_moltype(const gmx_moltype_t& moltype, t_graph* g) { - mk_graph_ilist(nullptr, moltype.ilist.data(), 0, moltype.atoms.nr, - FALSE, FALSE, - g); + mk_graph_ilist(nullptr, moltype.ilist.data(), 0, moltype.atoms.nr, FALSE, FALSE, g); } -t_graph *mk_graph(FILE *fplog, - const t_idef *idef, int at_start, int at_end, - gmx_bool bShakeOnly, gmx_bool bSettle) +t_graph* mk_graph(FILE* fplog, const t_idef* idef, int at_start, int at_end, gmx_bool bShakeOnly, gmx_bool bSettle) { - t_graph *g; + t_graph* g; snew(g, 1); @@ -520,7 +506,7 @@ t_graph *mk_graph(FILE *fplog, return g; } -void done_graph(t_graph *g) +void done_graph(t_graph* g) { GCHECK(g); if (g->nnodes > 0) @@ -539,8 +525,13 @@ void done_graph(t_graph *g) * ************************************************************/ -static void mk_1shift_tric(int npbcdim, const matrix box, const rvec hbox, - const rvec xi, const rvec xj, const int *mi, int *mj) +static void mk_1shift_tric(int npbcdim, + const matrix box, + const rvec hbox, + const rvec xi, + const rvec xj, + const int* mi, + int* mj) { /* Calculate periodicity for triclinic box... */ int m, d; @@ -549,23 +540,23 @@ static void mk_1shift_tric(int npbcdim, const matrix box, const rvec hbox, rvec_sub(xi, xj, dx); mj[ZZ] = 0; - for (m = npbcdim-1; (m >= 0); m--) + for (m = npbcdim - 1; (m >= 0); m--) { /* If dx < hbox, then xj will be reduced by box, so that * xi - xj will be bigger */ if (dx[m] < -hbox[m]) { - mj[m] = mi[m]-1; - for (d = m-1; d >= 0; d--) + mj[m] = mi[m] - 1; + for (d = m - 1; d >= 0; d--) { dx[d] += box[m][d]; } } else if (dx[m] >= hbox[m]) { - mj[m] = mi[m]+1; - for (d = m-1; d >= 0; d--) + mj[m] = mi[m] + 1; + for (d = m - 1; d >= 0; d--) { dx[d] -= box[m][d]; } @@ -577,8 +568,7 @@ static void mk_1shift_tric(int npbcdim, const matrix box, const rvec hbox, } } -static void mk_1shift(int npbcdim, const rvec hbox, const rvec xi, const rvec xj, - const int *mi, int *mj) +static void mk_1shift(int npbcdim, const rvec hbox, const rvec xi, const rvec xj, const int* mi, int* mj) { /* Calculate periodicity for rectangular box... */ int m; @@ -594,11 +584,11 @@ static void mk_1shift(int npbcdim, const rvec hbox, const rvec xi, const rvec xj */ if (dx[m] < -hbox[m]) { - mj[m] = mi[m]-1; + mj[m] = mi[m] - 1; } else if (dx[m] >= hbox[m]) { - mj[m] = mi[m]+1; + mj[m] = mi[m] + 1; } else { @@ -607,21 +597,19 @@ static void mk_1shift(int npbcdim, const rvec hbox, const rvec xi, const rvec xj } } -static void mk_1shift_screw(const matrix box, const rvec hbox, - const rvec xi, const rvec xj, const int *mi, int *mj) +static void mk_1shift_screw(const matrix box, const rvec hbox, const rvec xi, const rvec xj, const int* mi, int* mj) { /* Calculate periodicity for rectangular box... */ int signi, m; rvec dx; - if ((mi[XX] > 0 && mi[XX] % 2 == 1) || - (mi[XX] < 0 && -mi[XX] % 2 == 1)) + if ((mi[XX] > 0 && mi[XX] % 2 == 1) || (mi[XX] < 0 && -mi[XX] % 2 == 1)) { signi = -1; } else { - signi = 1; + signi = 1; } rvec_sub(xi, xj, dx); @@ -642,7 +630,7 @@ static void mk_1shift_screw(const matrix box, const rvec hbox, { /* Rotate */ dx[YY] = xi[YY] - (box[YY][YY] + box[ZZ][YY] - xj[YY]); - dx[ZZ] = xi[ZZ] - (box[ZZ][ZZ] - xj[ZZ]); + dx[ZZ] = xi[ZZ] - (box[ZZ][ZZ] - xj[ZZ]); } for (m = 1; (m < DIM); m++) { @@ -664,18 +652,17 @@ static void mk_1shift_screw(const matrix box, const rvec hbox, } } -static int mk_grey(egCol egc[], t_graph *g, int *AtomI, - int npbcdim, const matrix box, const rvec x[], int *nerror) +static int mk_grey(egCol egc[], t_graph* g, int* AtomI, int npbcdim, const matrix box, const rvec x[], int* nerror) { - int m, j, ng, ai, aj, g0; - rvec dx, hbox; - gmx_bool bTriclinic; - ivec is_aj; - t_pbc pbc; + int m, j, ng, ai, aj, g0; + rvec dx, hbox; + gmx_bool bTriclinic; + ivec is_aj; + t_pbc pbc; for (m = 0; (m < DIM); m++) { - hbox[m] = box[m][m]*0.5; + hbox[m] = box[m][m] * 0.5; } bTriclinic = TRICLINIC(box); @@ -684,9 +671,9 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, ai = g0 + *AtomI; /* Loop over all the bonds */ - for (j = 0; (j < g->nedge[ai-g0]); j++) + for (j = 0; (j < g->nedge[ai - g0]); j++) { - aj = g->edge[ai-g0][j]; + aj = g->edge[ai - g0][j]; /* If there is a white one, make it grey and set pbc */ if (g->bScrewPBC) { @@ -701,32 +688,31 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, mk_1shift(npbcdim, hbox, x[ai], x[aj], g->ishift[ai], is_aj); } - if (egc[aj-g0] == egcolWhite) + if (egc[aj - g0] == egcolWhite) { if (aj - g0 < *AtomI) { *AtomI = aj - g0; } - egc[aj-g0] = egcolGrey; + egc[aj - g0] = egcolGrey; copy_ivec(is_aj, g->ishift[aj]); ng++; } - else if ((is_aj[XX] != g->ishift[aj][XX]) || - (is_aj[YY] != g->ishift[aj][YY]) || - (is_aj[ZZ] != g->ishift[aj][ZZ])) + else if ((is_aj[XX] != g->ishift[aj][XX]) || (is_aj[YY] != g->ishift[aj][YY]) + || (is_aj[ZZ] != g->ishift[aj][ZZ])) { if (gmx_debug_at) { set_pbc(&pbc, -1, box); pbc_dx(&pbc, x[ai], x[aj], dx); - fprintf(debug, "mk_grey: shifts for atom %d due to atom %d\n" + fprintf(debug, + "mk_grey: shifts for atom %d due to atom %d\n" "are (%d,%d,%d), should be (%d,%d,%d)\n" "dx = (%g,%g,%g)\n", - aj+1, ai+1, is_aj[XX], is_aj[YY], is_aj[ZZ], - g->ishift[aj][XX], g->ishift[aj][YY], g->ishift[aj][ZZ], - dx[XX], dx[YY], dx[ZZ]); + aj + 1, ai + 1, is_aj[XX], is_aj[YY], is_aj[ZZ], g->ishift[aj][XX], + g->ishift[aj][YY], g->ishift[aj][ZZ], dx[XX], dx[YY], dx[ZZ]); } (*nerror)++; } @@ -734,7 +720,7 @@ static int mk_grey(egCol egc[], t_graph *g, int *AtomI, return ng; } -static int first_colour(int fC, egCol Col, t_graph *g, const egCol egc[]) +static int first_colour(int fC, egCol Col, t_graph* g, const egCol egc[]) /* Return the first node with colour Col starting at fC. * return -1 if none found. */ @@ -753,10 +739,7 @@ static int first_colour(int fC, egCol Col, t_graph *g, const egCol egc[]) } /* Returns the maximum length of the graph edges for coordinates x */ -static real maxEdgeLength(const t_graph g, - int ePBC, - const matrix box, - const rvec x[]) +static real maxEdgeLength(const t_graph g, int ePBC, const matrix box, const rvec x[]) { t_pbc pbc; @@ -778,8 +761,7 @@ static real maxEdgeLength(const t_graph g, return std::sqrt(maxEdgeLength2); } -void mk_mshift(FILE *log, t_graph *g, int ePBC, - const matrix box, const rvec x[]) +void mk_mshift(FILE* log, t_graph* g, int ePBC, const matrix box, const rvec x[]) { static int nerror_tot = 0; int npbcdim; @@ -820,7 +802,7 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, g->negc = nnodes; srenew(g->egc, g->negc); } - memset(g->egc, 0, static_cast(nnodes*sizeof(g->egc[0]))); + memset(g->egc, 0, static_cast(nnodes * sizeof(g->egc[0]))); nW = g->nbound; nG = 0; @@ -853,8 +835,7 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, /* Initial value for the first grey */ fG = fW; #ifdef DEBUG2 - fprintf(log, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", - nW, nG, nB, nW+nG+nB); + fprintf(log, "Starting G loop (nW=%d, nG=%d, nB=%d, total %d)\n", nW, nG, nB, nW + nG + nB); #endif while (nG > 0) { @@ -888,19 +869,21 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, */ constexpr real c_relativeDistanceThreshold = 0.25; - int numPbcDimensions = ePBC2npbcdim(ePBC); + int numPbcDimensions = ePBC2npbcdim(ePBC); GMX_RELEASE_ASSERT(numPbcDimensions > 0, "Expect PBC with graph"); - real minBoxSize = norm(box[XX]); + real minBoxSize = norm(box[XX]); for (int d = 1; d < numPbcDimensions; d++) { minBoxSize = std::min(minBoxSize, norm(box[d])); } real maxDistance = maxEdgeLength(*g, ePBC, box, x); - if (maxDistance >= c_relativeDistanceThreshold*minBoxSize) + if (maxDistance >= c_relativeDistanceThreshold * minBoxSize) { - std::string mesg = gmx::formatString("There are inconsistent shifts over periodic boundaries in a molecule type consisting of %d atoms. The longest distance involved in such interactions is %.3f nm which is %s half the box length.", - g->at1 - g->at0, maxDistance, - maxDistance >= 0.5*minBoxSize ? "above" : "close to"); + std::string mesg = gmx::formatString( + "There are inconsistent shifts over periodic boundaries in a molecule type " + "consisting of %d atoms. The longest distance involved in such interactions is " + "%.3f nm which is %s half the box length.", + g->at1 - g->at0, maxDistance, maxDistance >= 0.5 * minBoxSize ? "above" : "close to"); switch (g->parts) { @@ -909,10 +892,14 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, * actually between the parts, but that would require * a lot of extra code. */ - mesg += " This molecule type consists of muliple parts, e.g. monomers, that are connected by interactions that are not chemical bonds, e.g. restraints. Such systems can not be treated. The only solution is increasing the box size."; + mesg += " This molecule type consists of muliple parts, e.g. monomers, that " + "are connected by interactions that are not chemical bonds, e.g. " + "restraints. Such systems can not be treated. The only solution is " + "increasing the box size."; break; default: - mesg += " Either you have excessively large distances between atoms in bonded interactions or your system is exploding."; + mesg += " Either you have excessively large distances between atoms in bonded " + "interactions or your system is exploding."; } gmx_fatal(FARGS, "%s", mesg.c_str()); } @@ -922,12 +909,10 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, nerror_tot++; if (nerror_tot <= 100) { - fprintf(stderr, "There were %d inconsistent shifts. Check your topology\n", - nerror); + fprintf(stderr, "There were %d inconsistent shifts. Check your topology\n", nerror); if (log) { - fprintf(log, "There were %d inconsistent shifts. Check your topology\n", - nerror); + fprintf(log, "There were %d inconsistent shifts. Check your topology\n", nerror); } } if (nerror_tot == 100) @@ -947,11 +932,11 @@ void mk_mshift(FILE *log, t_graph *g, int ePBC, * ************************************************************/ -void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]) +void shift_x(const t_graph* g, const matrix box, const rvec x[], rvec x_s[]) { - ivec *is; - int g0, g1; - int j, tx, ty, tz; + ivec* is; + int g0, g1; + int j, tx, ty, tz; GCHECK(g); g0 = g->at_start; @@ -971,19 +956,18 @@ void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]) ty = is[j][YY]; tz = is[j][ZZ]; - if ((tx > 0 && tx % 2 == 1) || - (tx < 0 && -tx %2 == 1)) + if ((tx > 0 && tx % 2 == 1) || (tx < 0 && -tx % 2 == 1)) { - x_s[j][XX] = x[j][XX] + tx*box[XX][XX]; + x_s[j][XX] = x[j][XX] + tx * box[XX][XX]; x_s[j][YY] = box[YY][YY] + box[ZZ][YY] - x[j][YY]; - x_s[j][ZZ] = box[ZZ][ZZ] - x[j][ZZ]; + x_s[j][ZZ] = box[ZZ][ZZ] - x[j][ZZ]; } else { x_s[j][XX] = x[j][XX]; } - x_s[j][YY] = x[j][YY] + ty*box[YY][YY] + tz*box[ZZ][YY]; - x_s[j][ZZ] = x[j][ZZ] + tz*box[ZZ][ZZ]; + x_s[j][YY] = x[j][YY] + ty * box[YY][YY] + tz * box[ZZ][YY]; + x_s[j][ZZ] = x[j][ZZ] + tz * box[ZZ][ZZ]; } } else if (TRICLINIC(box)) @@ -994,9 +978,9 @@ void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]) ty = is[j][YY]; tz = is[j][ZZ]; - x_s[j][XX] = x[j][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX]; - x_s[j][YY] = x[j][YY]+ty*box[YY][YY]+tz*box[ZZ][YY]; - x_s[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ]; + x_s[j][XX] = x[j][XX] + tx * box[XX][XX] + ty * box[YY][XX] + tz * box[ZZ][XX]; + x_s[j][YY] = x[j][YY] + ty * box[YY][YY] + tz * box[ZZ][YY]; + x_s[j][ZZ] = x[j][ZZ] + tz * box[ZZ][ZZ]; } } else @@ -1007,9 +991,9 @@ void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]) ty = is[j][YY]; tz = is[j][ZZ]; - x_s[j][XX] = x[j][XX]+tx*box[XX][XX]; - x_s[j][YY] = x[j][YY]+ty*box[YY][YY]; - x_s[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ]; + x_s[j][XX] = x[j][XX] + tx * box[XX][XX]; + x_s[j][YY] = x[j][YY] + ty * box[YY][YY]; + x_s[j][ZZ] = x[j][ZZ] + tz * box[ZZ][ZZ]; } } @@ -1019,11 +1003,11 @@ void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]) } } -void shift_self(const t_graph *g, const matrix box, rvec x[]) +void shift_self(const t_graph* g, const matrix box, rvec x[]) { - ivec *is; - int g0, g1; - int j, tx, ty, tz; + ivec* is; + int g0, g1; + int j, tx, ty, tz; if (g->bScrewPBC) { @@ -1035,7 +1019,7 @@ void shift_self(const t_graph *g, const matrix box, rvec x[]) is = g->ishift; #ifdef DEBUG - fprintf(stderr, "Shifting atoms %d to %d\n", g0, g0+gn); + fprintf(stderr, "Shifting atoms %d to %d\n", g0, g0 + gn); #endif if (TRICLINIC(box)) { @@ -1045,9 +1029,9 @@ void shift_self(const t_graph *g, const matrix box, rvec x[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x[j][XX]+tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX]; - x[j][YY] = x[j][YY]+ty*box[YY][YY]+tz*box[ZZ][YY]; - x[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ]; + x[j][XX] = x[j][XX] + tx * box[XX][XX] + ty * box[YY][XX] + tz * box[ZZ][XX]; + x[j][YY] = x[j][YY] + ty * box[YY][YY] + tz * box[ZZ][YY]; + x[j][ZZ] = x[j][ZZ] + tz * box[ZZ][ZZ]; } } else @@ -1058,18 +1042,18 @@ void shift_self(const t_graph *g, const matrix box, rvec x[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x[j][XX]+tx*box[XX][XX]; - x[j][YY] = x[j][YY]+ty*box[YY][YY]; - x[j][ZZ] = x[j][ZZ]+tz*box[ZZ][ZZ]; + x[j][XX] = x[j][XX] + tx * box[XX][XX]; + x[j][YY] = x[j][YY] + ty * box[YY][YY]; + x[j][ZZ] = x[j][ZZ] + tz * box[ZZ][ZZ]; } } } -void unshift_x(const t_graph *g, const matrix box, rvec x[], const rvec x_s[]) +void unshift_x(const t_graph* g, const matrix box, rvec x[], const rvec x_s[]) { - ivec *is; - int g0, g1; - int j, tx, ty, tz; + ivec* is; + int g0, g1; + int j, tx, ty, tz; if (g->bScrewPBC) { @@ -1093,9 +1077,9 @@ void unshift_x(const t_graph *g, const matrix box, rvec x[], const rvec x_s[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x_s[j][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX]; - x[j][YY] = x_s[j][YY]-ty*box[YY][YY]-tz*box[ZZ][YY]; - x[j][ZZ] = x_s[j][ZZ]-tz*box[ZZ][ZZ]; + x[j][XX] = x_s[j][XX] - tx * box[XX][XX] - ty * box[YY][XX] - tz * box[ZZ][XX]; + x[j][YY] = x_s[j][YY] - ty * box[YY][YY] - tz * box[ZZ][YY]; + x[j][ZZ] = x_s[j][ZZ] - tz * box[ZZ][ZZ]; } } else @@ -1106,9 +1090,9 @@ void unshift_x(const t_graph *g, const matrix box, rvec x[], const rvec x_s[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x_s[j][XX]-tx*box[XX][XX]; - x[j][YY] = x_s[j][YY]-ty*box[YY][YY]; - x[j][ZZ] = x_s[j][ZZ]-tz*box[ZZ][ZZ]; + x[j][XX] = x_s[j][XX] - tx * box[XX][XX]; + x[j][YY] = x_s[j][YY] - ty * box[YY][YY]; + x[j][ZZ] = x_s[j][ZZ] - tz * box[ZZ][ZZ]; } } @@ -1118,9 +1102,9 @@ void unshift_x(const t_graph *g, const matrix box, rvec x[], const rvec x_s[]) } } -void unshift_self(const t_graph *g, const matrix box, rvec x[]) +void unshift_self(const t_graph* g, const matrix box, rvec x[]) { - ivec *is; + ivec* is; int g0, g1; int j, tx, ty, tz; @@ -1141,9 +1125,9 @@ void unshift_self(const t_graph *g, const matrix box, rvec x[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x[j][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX]; - x[j][YY] = x[j][YY]-ty*box[YY][YY]-tz*box[ZZ][YY]; - x[j][ZZ] = x[j][ZZ]-tz*box[ZZ][ZZ]; + x[j][XX] = x[j][XX] - tx * box[XX][XX] - ty * box[YY][XX] - tz * box[ZZ][XX]; + x[j][YY] = x[j][YY] - ty * box[YY][YY] - tz * box[ZZ][YY]; + x[j][ZZ] = x[j][ZZ] - tz * box[ZZ][ZZ]; } } else @@ -1154,9 +1138,9 @@ void unshift_self(const t_graph *g, const matrix box, rvec x[]) ty = is[j][YY]; tz = is[j][ZZ]; - x[j][XX] = x[j][XX]-tx*box[XX][XX]; - x[j][YY] = x[j][YY]-ty*box[YY][YY]; - x[j][ZZ] = x[j][ZZ]-tz*box[ZZ][ZZ]; + x[j][XX] = x[j][XX] - tx * box[XX][XX]; + x[j][YY] = x[j][YY] - ty * box[YY][YY]; + x[j][ZZ] = x[j][ZZ] - tz * box[ZZ][ZZ]; } } } diff --git a/src/gromacs/pbcutil/mshift.h b/src/gromacs/pbcutil/mshift.h index f77c9ed5da..5990c37c77 100644 --- a/src/gromacs/pbcutil/mshift.h +++ b/src/gromacs/pbcutil/mshift.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,8 +46,12 @@ struct InteractionList; struct gmx_moltype_t; struct t_idef; -typedef enum { - egcolWhite, egcolGrey, egcolBlack, egcolNR +typedef enum +{ + egcolWhite, + egcolGrey, + egcolBlack, + egcolNR } egCol; struct t_graph @@ -59,29 +63,27 @@ struct t_graph { Single, /* All atoms are connected through chemical bonds */ MultipleDisconnected, /* There are multiple parts, e.g. monomers, that are all disconnected */ - MultipleConnected /* There are multiple parts, e.g. monomers, that are partially or fully connected between each other by interactions other than chemical bonds */ + MultipleConnected /* There are multiple parts, e.g. monomers, that are partially or fully connected between each other by interactions other than chemical bonds */ }; - int at0; /* The first atom the graph was constructed for */ - int at1; /* The last atom the graph was constructed for */ - int nnodes; /* The number of nodes, nnodes=at_end-at_start */ - int nbound; /* The number of nodes with edges */ - int at_start; /* The first connected atom in this graph */ - int at_end; /* The last+1 connected atom in this graph */ - int *nedge; /* For each node the number of edges */ - int **edge; /* For each node, the actual edges (bidirect.) */ - gmx_bool bScrewPBC; /* Screw boundary conditions */ - ivec *ishift; /* Shift for each particle */ - int negc; - egCol *egc; /* color of each node */ - BondedParts parts; /* How chemically bonded parts are connected */ + int at0; /* The first atom the graph was constructed for */ + int at1; /* The last atom the graph was constructed for */ + int nnodes; /* The number of nodes, nnodes=at_end-at_start */ + int nbound; /* The number of nodes with edges */ + int at_start; /* The first connected atom in this graph */ + int at_end; /* The last+1 connected atom in this graph */ + int* nedge; /* For each node the number of edges */ + int** edge; /* For each node, the actual edges (bidirect.) */ + gmx_bool bScrewPBC; /* Screw boundary conditions */ + ivec* ishift; /* Shift for each particle */ + int negc; + egCol* egc; /* color of each node */ + BondedParts parts; /* How chemically bonded parts are connected */ }; #define SHIFT_IVEC(g, i) ((g)->ishift[i]) -t_graph *mk_graph(FILE *fplog, - const struct t_idef *idef, int at_start, int at_end, - gmx_bool bShakeOnly, gmx_bool bSettle); +t_graph* mk_graph(FILE* fplog, const struct t_idef* idef, int at_start, int at_end, gmx_bool bShakeOnly, gmx_bool bSettle); /* Build a graph from an idef description. The graph can be used * to generate mol-shift indices. * at_start and at_end should coincide will molecule boundaries, @@ -90,31 +92,29 @@ t_graph *mk_graph(FILE *fplog, * If bSettle && bShakeOnly the settles are used too. */ -void mk_graph_moltype(const gmx_moltype_t &moltype, - t_graph *g); +void mk_graph_moltype(const gmx_moltype_t& moltype, t_graph* g); /* As mk_graph, but takes gmx_moltype_t iso t_idef and does not allocate g */ -void done_graph(t_graph *g); +void done_graph(t_graph* g); /* Free the memory in g */ -void p_graph(FILE *log, const char *title, t_graph *g); +void p_graph(FILE* log, const char* title, t_graph* g); /* Print a graph to log */ -void mk_mshift(FILE *log, t_graph *g, int ePBC, - const matrix box, const rvec x[]); +void mk_mshift(FILE* log, t_graph* g, int ePBC, const matrix box, const rvec x[]); /* Calculate the mshift codes, based on the connection graph in g. */ -void shift_x(const t_graph *g, const matrix box, const rvec x[], rvec x_s[]); +void shift_x(const t_graph* g, const matrix box, const rvec x[], rvec x_s[]); /* Add the shift vector to x, and store in x_s (may be same array as x) */ -void shift_self(const t_graph *g, const matrix box, rvec x[]); +void shift_self(const t_graph* g, const matrix box, rvec x[]); /* Id. but in place */ -void unshift_x(const t_graph *g, const matrix box, rvec x[], const rvec x_s[]); +void unshift_x(const t_graph* g, const matrix box, rvec x[], const rvec x_s[]); /* Subtract the shift vector from x_s, and store in x (may be same array) */ -void unshift_self(const t_graph *g, const matrix box, rvec x[]); +void unshift_self(const t_graph* g, const matrix box, rvec x[]); /* Id, but in place */ #endif diff --git a/src/gromacs/pbcutil/pbc.cpp b/src/gromacs/pbcutil/pbc.cpp index 7cab160d88..b60c20aa2d 100644 --- a/src/gromacs/pbcutil/pbc.cpp +++ b/src/gromacs/pbcutil/pbc.cpp @@ -62,22 +62,25 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -const char *epbc_names[epbcNR+1] = -{ - "xyz", "no", "xy", "screw", nullptr -}; +const char* epbc_names[epbcNR + 1] = { "xyz", "no", "xy", "screw", nullptr }; /* Skip 0 so we have more chance of detecting if we forgot to call set_pbc. */ -enum { - epbcdxRECTANGULAR = 1, epbcdxTRICLINIC, - epbcdx2D_RECT, epbcdx2D_TRIC, - epbcdx1D_RECT, epbcdx1D_TRIC, - epbcdxSCREW_RECT, epbcdxSCREW_TRIC, - epbcdxNOPBC, epbcdxUNSUPPORTED +enum +{ + epbcdxRECTANGULAR = 1, + epbcdxTRICLINIC, + epbcdx2D_RECT, + epbcdx2D_TRIC, + epbcdx1D_RECT, + epbcdx1D_TRIC, + epbcdxSCREW_RECT, + epbcdxSCREW_TRIC, + epbcdxNOPBC, + epbcdxUNSUPPORTED }; //! Margin factor for error message -#define BOX_MARGIN 1.0010 +#define BOX_MARGIN 1.0010 //! Margin correction if the box is too skewed #define BOX_MARGIN_CORRECT 1.0005 @@ -87,17 +90,17 @@ int ePBC2npbcdim(int ePBC) switch (ePBC) { - case epbcXYZ: npbcdim = 3; break; - case epbcXY: npbcdim = 2; break; + case epbcXYZ: npbcdim = 3; break; + case epbcXY: npbcdim = 2; break; case epbcSCREW: npbcdim = 3; break; - case epbcNONE: npbcdim = 0; break; + case epbcNONE: npbcdim = 0; break; default: gmx_fatal(FARGS, "Unknown ePBC=%d in ePBC2npbcdim", ePBC); } return npbcdim; } -void dump_pbc(FILE *fp, t_pbc *pbc) +void dump_pbc(FILE* fp, t_pbc* pbc) { rvec sum_box; @@ -117,9 +120,9 @@ void dump_pbc(FILE *fp, t_pbc *pbc) } } -const char *check_box(int ePBC, const matrix box) +const char* check_box(int ePBC, const matrix box) { - const char *ptr; + const char* ptr; if (ePBC == -1) { @@ -133,16 +136,17 @@ const char *check_box(int ePBC, const matrix box) if ((box[XX][YY] != 0) || (box[XX][ZZ] != 0) || (box[YY][ZZ] != 0)) { - ptr = "Only triclinic boxes with the first vector parallel to the x-axis and the second vector in the xy-plane are supported."; + ptr = "Only triclinic boxes with the first vector parallel to the x-axis and the second " + "vector in the xy-plane are supported."; } else if (ePBC == epbcSCREW && (box[YY][XX] != 0 || box[ZZ][XX] != 0)) { ptr = "The unit cell can not have off-diagonal x-components with screw pbc"; } - else if (std::fabs(box[YY][XX]) > BOX_MARGIN*0.5*box[XX][XX] || - (ePBC != epbcXY && - (std::fabs(box[ZZ][XX]) > BOX_MARGIN*0.5*box[XX][XX] || - std::fabs(box[ZZ][YY]) > BOX_MARGIN*0.5*box[YY][YY]))) + else if (std::fabs(box[YY][XX]) > BOX_MARGIN * 0.5 * box[XX][XX] + || (ePBC != epbcXY + && (std::fabs(box[ZZ][XX]) > BOX_MARGIN * 0.5 * box[XX][XX] + || std::fabs(box[ZZ][YY]) > BOX_MARGIN * 0.5 * box[YY][YY]))) { ptr = "Triclinic box is too skewed."; } @@ -159,13 +163,12 @@ void matrix_convert(matrix box, const rvec vec, const rvec angleInDegrees) rvec angle; svmul(DEG2RAD, angleInDegrees, angle); box[XX][XX] = vec[XX]; - box[YY][XX] = vec[YY]*cos(angle[ZZ]); - box[YY][YY] = vec[YY]*sin(angle[ZZ]); - box[ZZ][XX] = vec[ZZ]*cos(angle[YY]); - box[ZZ][YY] = vec[ZZ] - *(cos(angle[XX])-cos(angle[YY])*cos(angle[ZZ]))/sin(angle[ZZ]); - box[ZZ][ZZ] = std::sqrt(gmx::square(vec[ZZ]) - -box[ZZ][XX]*box[ZZ][XX]-box[ZZ][YY]*box[ZZ][YY]); + box[YY][XX] = vec[YY] * cos(angle[ZZ]); + box[YY][YY] = vec[YY] * sin(angle[ZZ]); + box[ZZ][XX] = vec[ZZ] * cos(angle[YY]); + box[ZZ][YY] = vec[ZZ] * (cos(angle[XX]) - cos(angle[YY]) * cos(angle[ZZ])) / sin(angle[ZZ]); + box[ZZ][ZZ] = + std::sqrt(gmx::square(vec[ZZ]) - box[ZZ][XX] * box[ZZ][XX] - box[ZZ][YY] * box[ZZ][YY]); } real max_cutoff2(int ePBC, const matrix box) @@ -196,7 +199,7 @@ real max_cutoff2(int ePBC, const matrix box) min_ss = std::min(box[XX][XX], std::min(box[YY][YY] - std::fabs(box[ZZ][YY]), box[ZZ][ZZ])); } - return std::min(min_hv2, min_ss*min_ss); + return std::min(min_hv2, min_ss * min_ss); } //! Set to true if warning has been printed @@ -222,7 +225,8 @@ int guess_ePBC(const matrix box) { if (!bWarnedGuess) { - fprintf(stderr, "WARNING: Unsupported box diagonal %f %f %f, " + fprintf(stderr, + "WARNING: Unsupported box diagonal %f %f %f, " "will not use periodic boundary conditions\n\n", box[XX][XX], box[YY][YY], box[ZZ][ZZ]); bWarnedGuess = TRUE; @@ -239,14 +243,14 @@ int guess_ePBC(const matrix box) } //! Check if the box still obeys the restrictions, if not, correct it -static int correct_box_elem(FILE *fplog, int step, tensor box, int v, int d) +static int correct_box_elem(FILE* fplog, int step, tensor box, int v, int d) { int shift, maxshift = 10; shift = 0; /* correct elem d of vector v with vector d */ - while (box[v][d] > BOX_MARGIN_CORRECT*0.5*box[d][d]) + while (box[v][d] > BOX_MARGIN_CORRECT * 0.5 * box[d][d]) { if (fplog) { @@ -261,12 +265,10 @@ static int correct_box_elem(FILE *fplog, int step, tensor box, int v, int d) } if (shift <= -maxshift) { - gmx_fatal(FARGS, - "Box was shifted at least %d times. Please see log-file.", - maxshift); + gmx_fatal(FARGS, "Box was shifted at least %d times. Please see log-file.", maxshift); } } - while (box[v][d] < -BOX_MARGIN_CORRECT*0.5*box[d][d]) + while (box[v][d] < -BOX_MARGIN_CORRECT * 0.5 * box[d][d]) { if (fplog) { @@ -281,16 +283,14 @@ static int correct_box_elem(FILE *fplog, int step, tensor box, int v, int d) } if (shift >= maxshift) { - gmx_fatal(FARGS, - "Box was shifted at least %d times. Please see log-file.", - maxshift); + gmx_fatal(FARGS, "Box was shifted at least %d times. Please see log-file.", maxshift); } } return shift; } -gmx_bool correct_box(FILE *fplog, int step, tensor box, t_graph *graph) +gmx_bool correct_box(FILE* fplog, int step, tensor box, t_graph* graph) { int zy, zx, yx, i; gmx_bool bCorrected; @@ -306,9 +306,9 @@ gmx_bool correct_box(FILE *fplog, int step, tensor box, t_graph *graph) /* correct the graph */ for (i = graph->at_start; i < graph->at_end; i++) { - graph->ishift[i][YY] -= graph->ishift[i][ZZ]*zy; - graph->ishift[i][XX] -= graph->ishift[i][ZZ]*zx; - graph->ishift[i][XX] -= graph->ishift[i][YY]*yx; + graph->ishift[i][YY] -= graph->ishift[i][ZZ] * zy; + graph->ishift[i][XX] -= graph->ishift[i][ZZ] * zx; + graph->ishift[i][XX] -= graph->ishift[i][YY] * yx; } } @@ -316,12 +316,11 @@ gmx_bool correct_box(FILE *fplog, int step, tensor box, t_graph *graph) } //! Do the real arithmetic for filling the pbc struct -static void low_set_pbc(t_pbc *pbc, int ePBC, - const ivec dd_pbc, const matrix box) +static void low_set_pbc(t_pbc* pbc, int ePBC, const ivec dd_pbc, const matrix box) { int order[3] = { 0, -1, 1 }; ivec bPBC; - const char *ptr; + const char* ptr; pbc->ePBC = ePBC; pbc->ndim_ePBC = ePBC2npbcdim(ePBC); @@ -334,23 +333,23 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, } copy_mat(box, pbc->box); - pbc->max_cutoff2 = 0; - pbc->dim = -1; - pbc->ntric_vec = 0; + pbc->max_cutoff2 = 0; + pbc->dim = -1; + pbc->ntric_vec = 0; for (int i = 0; (i < DIM); i++) { - pbc->fbox_diag[i] = box[i][i]; - pbc->hbox_diag[i] = pbc->fbox_diag[i]*0.5; + pbc->fbox_diag[i] = box[i][i]; + pbc->hbox_diag[i] = pbc->fbox_diag[i] * 0.5; pbc->mhbox_diag[i] = -pbc->hbox_diag[i]; } ptr = check_box(ePBC, box); if (ptr) { - fprintf(stderr, "Warning: %s\n", ptr); + fprintf(stderr, "Warning: %s\n", ptr); pr_rvecs(stderr, 0, " Box", box, DIM); - fprintf(stderr, " Can not fix pbc.\n\n"); + fprintf(stderr, " Can not fix pbc.\n\n"); pbc->ePBCDX = epbcdxUNSUPPORTED; } else @@ -444,15 +443,11 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, } } break; - default: - gmx_fatal(FARGS, "Incorrect number of pbc dimensions with DD: %d", - npbcdim); + default: gmx_fatal(FARGS, "Incorrect number of pbc dimensions with DD: %d", npbcdim); } pbc->max_cutoff2 = max_cutoff2(ePBC, box); - if (pbc->ePBCDX == epbcdxTRICLINIC || - pbc->ePBCDX == epbcdx2D_TRIC || - pbc->ePBCDX == epbcdxSCREW_TRIC) + if (pbc->ePBCDX == epbcdxTRICLINIC || pbc->ePBCDX == epbcdx2D_TRIC || pbc->ePBCDX == epbcdxSCREW_TRIC) { if (debug) { @@ -491,7 +486,7 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, for (int d = 0; d < DIM; d++) { - trial[d] = i*box[XX][d] + j*box[YY][d] + k*box[ZZ][d]; + trial[d] = i * box[XX][d] + j * box[YY][d] + k * box[ZZ][d]; /* Choose the vector within the brick around 0,0,0 that * will become the shortest due to shift try. */ @@ -504,7 +499,7 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, { if (trial[d] < 0) { - pos[d] = std::min( pbc->hbox_diag[d], -trial[d]); + pos[d] = std::min(pbc->hbox_diag[d], -trial[d]); } else { @@ -514,7 +509,7 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, d2old += gmx::square(pos[d]); d2new += gmx::square(pos[d] + trial[d]); } - if (BOX_MARGIN*d2new < d2old) + if (BOX_MARGIN * d2new < d2old) { /* Check if shifts with one box vector less do better */ gmx_bool bUse = TRUE; @@ -526,9 +521,9 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, real d2new_c = 0; for (int d = 0; d < DIM; d++) { - d2new_c += gmx::square(pos[d] + trial[d] - shift*box[dd][d]); + d2new_c += gmx::square(pos[d] + trial[d] - shift * box[dd][d]); } - if (d2new_c <= BOX_MARGIN*d2new) + if (d2new_c <= BOX_MARGIN * d2new) { bUse = FALSE; } @@ -539,8 +534,12 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, /* Accept this shift vector. */ if (pbc->ntric_vec >= MAX_NTRICVEC) { - fprintf(stderr, "\nWARNING: Found more than %d triclinic correction vectors, ignoring some.\n" - " There is probably something wrong with your box.\n", MAX_NTRICVEC); + fprintf(stderr, + "\nWARNING: Found more than %d triclinic " + "correction vectors, ignoring some.\n" + " There is probably something wrong with your " + "box.\n", + MAX_NTRICVEC); pr_rvecs(stderr, 0, " Box", box, DIM); } else @@ -553,10 +552,11 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, if (debug) { - fprintf(debug, " tricvec %2d = %2d %2d %2d %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n", - pbc->ntric_vec, i, j, k, - sqrt(d2old), sqrt(d2new), - trial[XX], trial[YY], trial[ZZ], + fprintf(debug, + " tricvec %2d = %2d %2d %2d %5.2f %5.2f " + "%5.2f %5.2f %5.2f %5.2f %5.2f %5.2f\n", + pbc->ntric_vec, i, j, k, sqrt(d2old), + sqrt(d2new), trial[XX], trial[YY], trial[ZZ], pos[XX], pos[YY], pos[ZZ]); } } @@ -570,7 +570,7 @@ static void low_set_pbc(t_pbc *pbc, int ePBC, } } -void set_pbc(t_pbc *pbc, int ePBC, const matrix box) +void set_pbc(t_pbc* pbc, int ePBC, const matrix box) { if (ePBC == -1) { @@ -580,9 +580,7 @@ void set_pbc(t_pbc *pbc, int ePBC, const matrix box) low_set_pbc(pbc, ePBC, nullptr, box); } -t_pbc *set_pbc_dd(t_pbc *pbc, int ePBC, - const ivec domdecCells, - gmx_bool bSingleDir, const matrix box) +t_pbc* set_pbc_dd(t_pbc* pbc, int ePBC, const ivec domdecCells, gmx_bool bSingleDir, const matrix box) { if (ePBC == epbcNONE) { @@ -608,8 +606,7 @@ t_pbc *set_pbc_dd(t_pbc *pbc, int ePBC, for (int i = 0; i < DIM; i++) { usePBC[i] = 0; - if (domdecCells[i] <= (bSingleDir ? 1 : 2) && - !(ePBC == epbcXY && i == ZZ)) + if (domdecCells[i] <= (bSingleDir ? 1 : 2) && !(ePBC == epbcXY && i == ZZ)) { usePBC[i] = 1; npbcdim++; @@ -629,7 +626,7 @@ t_pbc *set_pbc_dd(t_pbc *pbc, int ePBC, return (pbc->ePBC != epbcNONE ? pbc : nullptr); } -void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) +void pbc_dx(const t_pbc* pbc, const rvec x1, const rvec x2, rvec dx) { int i, j; rvec dx_start, trial; @@ -654,7 +651,7 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) } break; case epbcdxTRICLINIC: - for (i = DIM-1; i >= 0; i--) + for (i = DIM - 1; i >= 0; i--) { while (dx[i] > pbc->hbox_diag[i]) { @@ -712,7 +709,7 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) break; case epbcdx2D_TRIC: d2min = 0; - for (i = DIM-1; i >= 0; i--) + for (i = DIM - 1; i >= 0; i--) { if (i != pbc->dim) { @@ -730,7 +727,7 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) dx[j] += pbc->box[i][j]; } } - d2min += dx[i]*dx[i]; + d2min += dx[i] * dx[i]; } } if (d2min > pbc->max_cutoff2) @@ -749,7 +746,7 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) { if (j != pbc->dim) { - d2trial += trial[j]*trial[j]; + d2trial += trial[j] * trial[j]; } } if (d2trial < d2min) @@ -767,12 +764,12 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) while (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; - bRot = !bRot; + bRot = !bRot; } while (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[YY]; - bRot = !bRot; + bRot = !bRot; } if (bRot) { @@ -794,14 +791,12 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) } break; case epbcdxNOPBC: - case epbcdxUNSUPPORTED: - break; - default: - gmx_fatal(FARGS, "Internal error in pbc_dx, set_pbc has not been called"); + case epbcdxUNSUPPORTED: break; + default: gmx_fatal(FARGS, "Internal error in pbc_dx, set_pbc has not been called"); } } -int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) +int pbc_dx_aiuc(const t_pbc* pbc, const rvec x1, const rvec x2, rvec dx) { int i, j, is; rvec dx_start, trial; @@ -818,12 +813,12 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) { if (dx[i] > pbc->hbox_diag[i]) { - dx[i] -= pbc->fbox_diag[i]; + dx[i] -= pbc->fbox_diag[i]; ishift[i]--; } else if (dx[i] <= pbc->mhbox_diag[i]) { - dx[i] += pbc->fbox_diag[i]; + dx[i] += pbc->fbox_diag[i]; ishift[i]++; } } @@ -836,7 +831,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) * can cause unlimited displacements. * Also allowing multiple shifts would index fshift beyond bounds. */ - for (i = DIM-1; i >= 1; i--) + for (i = DIM - 1; i >= 1; i--) { if (dx[i] > pbc->hbox_diag[i]) { @@ -921,7 +916,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) break; case epbcdx2D_TRIC: d2min = 0; - for (i = DIM-1; i >= 1; i--) + for (i = DIM - 1; i >= 1; i--) { if (i != pbc->dim) { @@ -941,7 +936,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) } ishift[i]++; } - d2min += dx[i]*dx[i]; + d2min += dx[i] * dx[i]; } } if (pbc->dim != XX) @@ -967,7 +962,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) ishift[XX]++; } } - d2min += dx[XX]*dx[XX]; + d2min += dx[XX] * dx[XX]; } if (d2min > pbc->max_cutoff2) { @@ -985,7 +980,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) { if (j != pbc->dim) { - d2trial += trial[j]*trial[j]; + d2trial += trial[j] * trial[j]; } } if (d2trial < d2min) @@ -1058,10 +1053,10 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) } break; case epbcdxNOPBC: - case epbcdxUNSUPPORTED: - break; + case epbcdxUNSUPPORTED: break; default: - gmx_fatal(FARGS, "Internal error in pbc_dx_aiuc, set_pbc_dd or set_pbc has not been called"); + gmx_fatal(FARGS, + "Internal error in pbc_dx_aiuc, set_pbc_dd or set_pbc has not been called"); } is = IVEC2IS(ishift); @@ -1074,7 +1069,7 @@ int pbc_dx_aiuc(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx) } //! Compute distance vector in double precision -void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) +void pbc_dx_d(const t_pbc* pbc, const dvec x1, const dvec x2, dvec dx) { int i, j; dvec dx_start, trial; @@ -1105,7 +1100,7 @@ void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) case epbcdxTRICLINIC: case epbcdx2D_TRIC: d2min = 0; - for (i = DIM-1; i >= 0; i--) + for (i = DIM - 1; i >= 0; i--) { if (i != pbc->dim) { @@ -1123,7 +1118,7 @@ void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) dx[j] += pbc->box[i][j]; } } - d2min += dx[i]*dx[i]; + d2min += dx[i] * dx[i]; } } if (d2min > pbc->max_cutoff2) @@ -1144,7 +1139,7 @@ void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) { if (j != pbc->dim) { - d2trial += trial[j]*trial[j]; + d2trial += trial[j] * trial[j]; } } if (d2trial < d2min) @@ -1162,12 +1157,12 @@ void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) while (dx[XX] > pbc->hbox_diag[XX]) { dx[XX] -= pbc->fbox_diag[XX]; - bRot = !bRot; + bRot = !bRot; } while (dx[XX] <= pbc->mhbox_diag[XX]) { dx[XX] += pbc->fbox_diag[YY]; - bRot = !bRot; + bRot = !bRot; } if (bRot) { @@ -1189,10 +1184,8 @@ void pbc_dx_d(const t_pbc *pbc, const dvec x1, const dvec x2, dvec dx) } break; case epbcdxNOPBC: - case epbcdxUNSUPPORTED: - break; - default: - gmx_fatal(FARGS, "Internal error in pbc_dx, set_pbc has not been called"); + case epbcdxUNSUPPORTED: break; + default: gmx_fatal(FARGS, "Internal error in pbc_dx, set_pbc has not been called"); } } @@ -1206,7 +1199,7 @@ void calc_shifts(const matrix box, rvec shift_vec[]) { for (int d = 0; d < DIM; d++) { - shift_vec[n][d] = k*box[XX][d] + l*box[YY][d] + m*box[ZZ][d]; + shift_vec[n][d] = k * box[XX][d] + l * box[YY][d] + m * box[ZZ][d]; } } } @@ -1225,20 +1218,18 @@ void calc_box_center(int ecenter, const matrix box, rvec box_center) { for (d = 0; d < DIM; d++) { - box_center[d] += 0.5*box[m][d]; + box_center[d] += 0.5 * box[m][d]; } } break; case ecenterRECT: for (d = 0; d < DIM; d++) { - box_center[d] = 0.5*box[d][d]; + box_center[d] = 0.5 * box[d][d]; } break; - case ecenterZERO: - break; - default: - gmx_fatal(FARGS, "Unsupported value %d for ecenter", ecenter); + case ecenterZERO: break; + default: gmx_fatal(FARGS, "Unsupported value %d for ecenter", ecenter); } } @@ -1258,7 +1249,7 @@ void calc_triclinic_images(const matrix box, rvec img[]) /* Get the next 3 in the xy-plane as mirror images */ for (i = 0; i < 3; i++) { - svmul(-1, img[i], img[3+i]); + svmul(-1, img[i], img[3 + i]); } /* Calculate the first 4 out of xy-plane images */ @@ -1269,13 +1260,13 @@ void calc_triclinic_images(const matrix box, rvec img[]) } for (i = 0; i < 3; i++) { - rvec_add(img[6], img[i+1], img[7+i]); + rvec_add(img[6], img[i + 1], img[7 + i]); } /* Mirror the last 4 from the previous in opposite rotation */ for (i = 0; i < 4; i++) { - svmul(-1, img[6 + (2+i) % 4], img[10+i]); + svmul(-1, img[6 + (2 + i) % 4], img[10 + i]); } } @@ -1290,7 +1281,7 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) n = 0; for (i = 2; i <= 5; i += 3) { - tmp[0] = i-1; + tmp[0] = i - 1; if (i == 2) { tmp[1] = 8; @@ -1299,21 +1290,21 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) { tmp[1] = 6; } - tmp[2] = (i+1) % 6; - tmp[3] = tmp[1]+4; + tmp[2] = (i + 1) % 6; + tmp[3] = tmp[1] + 4; for (j = 0; j < 4; j++) { for (d = 0; d < DIM; d++) { - vert[n][d] = img[i][d]+img[tmp[j]][d]+img[tmp[(j+1)%4]][d]; + vert[n][d] = img[i][d] + img[tmp[j]][d] + img[tmp[(j + 1) % 4]][d]; } n++; } } for (i = 7; i <= 13; i += 6) { - tmp[0] = (i-7)/2; - tmp[1] = tmp[0]+1; + tmp[0] = (i - 7) / 2; + tmp[1] = tmp[0] + 1; if (i == 7) { tmp[2] = 8; @@ -1322,12 +1313,12 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) { tmp[2] = 10; } - tmp[3] = i-1; + tmp[3] = i - 1; for (j = 0; j < 4; j++) { for (d = 0; d < DIM; d++) { - vert[n][d] = img[i][d]+img[tmp[j]][d]+img[tmp[(j+1)%4]][d]; + vert[n][d] = img[i][d] + img[tmp[j]][d] + img[tmp[(j + 1) % 4]][d]; } n++; } @@ -1342,7 +1333,7 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) { tmp[0] = 0; } - tmp[1] = tmp[0]+1; + tmp[1] = tmp[0] + 1; if (i == 9) { tmp[2] = 6; @@ -1351,12 +1342,12 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) { tmp[2] = 12; } - tmp[3] = i-1; + tmp[3] = i - 1; for (j = 0; j < 4; j++) { for (d = 0; d < DIM; d++) { - vert[n][d] = img[i][d]+img[tmp[j]][d]+img[tmp[(j+1)%4]][d]; + vert[n][d] = img[i][d] + img[tmp[j]][d] + img[tmp[(j + 1) % 4]][d]; } n++; } @@ -1367,35 +1358,32 @@ void calc_compact_unitcell_vertices(int ecenter, const matrix box, rvec vert[]) { for (d = 0; d < DIM; d++) { - vert[i][d] = vert[i][d]*oneFourth+box_center[d]; + vert[i][d] = vert[i][d] * oneFourth + box_center[d]; } } } -int *compact_unitcell_edges() +int* compact_unitcell_edges() { /* this is an index in vert[] (see calc_box_vertices) */ /*static int edge[NCUCEDGE*2];*/ - int *edge; - static const int hexcon[24] = { - 0, 9, 1, 19, 2, 15, 3, 21, - 4, 17, 5, 11, 6, 23, 7, 13, - 8, 20, 10, 18, 12, 16, 14, 22 - }; + int* edge; + static const int hexcon[24] = { 0, 9, 1, 19, 2, 15, 3, 21, 4, 17, 5, 11, + 6, 23, 7, 13, 8, 20, 10, 18, 12, 16, 14, 22 }; int e, i, j; - snew(edge, NCUCEDGE*2); + snew(edge, NCUCEDGE * 2); e = 0; for (i = 0; i < 6; i++) { for (j = 0; j < 4; j++) { - edge[e++] = 4*i + j; - edge[e++] = 4*i + (j+1) % 4; + edge[e++] = 4 * i + j; + edge[e++] = 4 * i + (j + 1) % 4; } } - for (i = 0; i < 12*2; i++) + for (i = 0; i < 12 * 2; i++) { edge[e++] = hexcon[i]; } @@ -1425,7 +1413,7 @@ void put_atoms_in_box(int ePBC, const matrix box, gmx::ArrayRef x) { for (gmx::index i = 0; (i < x.ssize()); ++i) { - for (m = npbcdim-1; m >= 0; m--) + for (m = npbcdim - 1; m >= 0; m--) { while (x[i][m] < 0) { @@ -1471,28 +1459,27 @@ void put_atoms_in_box_omp(int ePBC, const matrix box, gmx::ArrayRef x try { size_t natoms = x.size(); - size_t offset = (natoms*t )/nth; - size_t len = (natoms*(t + 1))/nth - offset; + size_t offset = (natoms * t) / nth; + size_t len = (natoms * (t + 1)) / nth - offset; put_atoms_in_box(ePBC, box, x.subArray(offset, len)); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } } -void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, - gmx::ArrayRef x) +void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, gmx::ArrayRef x) { - rvec box_center, shift_center; - real shm01, shm02, shm12, shift; - int m, d; + rvec box_center, shift_center; + real shm01, shm02, shm12, shift; + int m, d; calc_box_center(ecenter, box, box_center); /* The product of matrix shm with a coordinate gives the shift vector which is required determine the periodic cell position */ - shm01 = box[1][0]/box[1][1]; - shm02 = (box[1][1]*box[2][0] - box[2][1]*box[1][0])/(box[1][1]*box[2][2]); - shm12 = box[2][1]/box[2][2]; + shm01 = box[1][0] / box[1][1]; + shm02 = (box[1][1] * box[2][0] - box[2][1] * box[1][0]) / (box[1][1] * box[2][2]); + shm12 = box[2][1] / box[2][2]; clear_rvec(shift_center); for (d = 0; d < DIM; d++) @@ -1502,31 +1489,31 @@ void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, svmul(0.5, shift_center, shift_center); rvec_sub(box_center, shift_center, shift_center); - shift_center[0] = shm01*shift_center[1] + shm02*shift_center[2]; - shift_center[1] = shm12*shift_center[2]; + shift_center[0] = shm01 * shift_center[1] + shm02 * shift_center[2]; + shift_center[1] = shm12 * shift_center[2]; shift_center[2] = 0; for (gmx::index i = 0; (i < x.ssize()); ++i) { - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { shift = shift_center[m]; if (m == 0) { - shift += shm01*x[i][1] + shm02*x[i][2]; + shift += shm01 * x[i][1] + shm02 * x[i][2]; } else if (m == 1) { - shift += shm12*x[i][2]; + shift += shm12 * x[i][2]; } - while (x[i][m]-shift < 0) + while (x[i][m] - shift < 0) { for (d = 0; d <= m; d++) { x[i][d] += box[m][d]; } } - while (x[i][m]-shift >= box[m][m]) + while (x[i][m] - shift >= box[m][m]) { for (d = 0; d <= m; d++) { @@ -1537,8 +1524,7 @@ void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, } } -void put_atoms_in_compact_unitcell(int ePBC, int ecenter, const matrix box, - gmx::ArrayRef x) +void put_atoms_in_compact_unitcell(int ePBC, int ecenter, const matrix box, gmx::ArrayRef x) { t_pbc pbc; rvec box_center, dx; @@ -1567,12 +1553,10 @@ void put_atoms_in_compact_unitcell(int ePBC, int ecenter, const matrix box, * \param[in,out] x The coordinates of the atoms * \param[in] bFirst Specifier for first-time PBC removal */ -static void low_do_pbc_mtop(FILE *fplog, int ePBC, const matrix box, - const gmx_mtop_t *mtop, rvec x[], - gmx_bool bFirst) +static void low_do_pbc_mtop(FILE* fplog, int ePBC, const matrix box, const gmx_mtop_t* mtop, rvec x[], gmx_bool bFirst) { - t_graph *graph; - int as, mol; + t_graph* graph; + int as, mol; if (bFirst && fplog) { @@ -1581,14 +1565,13 @@ static void low_do_pbc_mtop(FILE *fplog, int ePBC, const matrix box, snew(graph, 1); as = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const gmx_moltype_t &moltype = mtop->moltype[molb.type]; - if (moltype.atoms.nr == 1 || - (!bFirst && moltype.atoms.nr == 1)) + const gmx_moltype_t& moltype = mtop->moltype[molb.type]; + if (moltype.atoms.nr == 1 || (!bFirst && moltype.atoms.nr == 1)) { /* Just one atom or charge group in the molecule, no PBC required */ - as += molb.nmol*moltype.atoms.nr; + as += molb.nmol * moltype.atoms.nr; } else { @@ -1596,9 +1579,9 @@ static void low_do_pbc_mtop(FILE *fplog, int ePBC, const matrix box, for (mol = 0; mol < molb.nmol; mol++) { - mk_mshift(fplog, graph, ePBC, box, x+as); + mk_mshift(fplog, graph, ePBC, box, x + as); - shift_self(graph, box, x+as); + shift_self(graph, box, x + as); /* The molecule is whole now. * We don't need the second mk_mshift call as in do_pbc_first, * since we no longer need this graph. @@ -1612,14 +1595,12 @@ static void low_do_pbc_mtop(FILE *fplog, int ePBC, const matrix box, sfree(graph); } -void do_pbc_first_mtop(FILE *fplog, int ePBC, const matrix box, - const gmx_mtop_t *mtop, rvec x[]) +void do_pbc_first_mtop(FILE* fplog, int ePBC, const matrix box, const gmx_mtop_t* mtop, rvec x[]) { low_do_pbc_mtop(fplog, ePBC, box, mtop, x, TRUE); } -void do_pbc_mtop(int ePBC, const matrix box, - const gmx_mtop_t *mtop, rvec x[]) +void do_pbc_mtop(int ePBC, const matrix box, const gmx_mtop_t* mtop, rvec x[]) { low_do_pbc_mtop(nullptr, ePBC, box, mtop, x, FALSE); } diff --git a/src/gromacs/pbcutil/pbc.h b/src/gromacs/pbcutil/pbc.h index dc70f22994..5bc0ee5ed9 100644 --- a/src/gromacs/pbcutil/pbc.h +++ b/src/gromacs/pbcutil/pbc.h @@ -47,12 +47,17 @@ struct gmx_domdec_t; struct gmx_mtop_t; -enum { - epbcXYZ, epbcNONE, epbcXY, epbcSCREW, epbcNR +enum +{ + epbcXYZ, + epbcNONE, + epbcXY, + epbcSCREW, + epbcNR }; //! Strings corresponding to epbc enum values. -extern const char *epbc_names[epbcNR+1]; +extern const char* epbc_names[epbcNR + 1]; /* Maximum number of combinations of single triclinic box vectors * required to shift atoms that are within a brick of the size of @@ -61,34 +66,35 @@ extern const char *epbc_names[epbcNR+1]; #define MAX_NTRICVEC 12 /*! \brief Structure containing info on periodic boundary conditions */ -typedef struct t_pbc { +typedef struct t_pbc +{ //! The PBC type - int ePBC; + int ePBC; //! Number of dimensions in which PBC is exerted - int ndim_ePBC; + int ndim_ePBC; /*! \brief Determines how to compute distance vectors. * * Indicator of how to compute distance vectors, depending * on PBC type (depends on ePBC and dimensions with(out) DD) * and the box angles. */ - int ePBCDX; + int ePBCDX; /*! \brief Used for selecting which dimensions to use in PBC. * * In case of 1-D PBC this indicates which dimension is used, * in case of 2-D PBC this indicates the opposite */ - int dim; + int dim; //! The simulation box - matrix box; + matrix box; //! The lengths of the diagonal of the full box - rvec fbox_diag; + rvec fbox_diag; //! Halve of the above - rvec hbox_diag; + rvec hbox_diag; //! Negative of the above - rvec mhbox_diag; + rvec mhbox_diag; //! Maximum allowed cutoff squared for the box and PBC used - real max_cutoff2; + real max_cutoff2; /*! \brief Number of triclinic shift vectors. * * Number of triclinic shift vectors depends on the skewedness @@ -99,11 +105,11 @@ typedef struct t_pbc { * be tried. Because of the restrictions imposed on the unit-cell * by GROMACS, ntric_vec <= MAX_NTRICVEC = 12. */ - int ntric_vec; + int ntric_vec; //! The triclinic shift vectors in grid cells. Internal use only. - ivec tric_shift[MAX_NTRICVEC]; + ivec tric_shift[MAX_NTRICVEC]; //! The triclinic shift vectors in length units - rvec tric_vec[MAX_NTRICVEC]; + rvec tric_vec[MAX_NTRICVEC]; } t_pbc; #define TRICLINIC(box) ((box)[YY][XX] != 0 || (box)[ZZ][XX] != 0 || (box)[ZZ][YY] != 0) @@ -112,7 +118,8 @@ typedef struct t_pbc { #define NCUCVERT 24 #define NCUCEDGE 36 -enum { +enum +{ ecenterTRIC, /* 0.5*(a+b+c) */ ecenterRECT, /* (0.5*a[x],0.5*b[y],0.5*c[z]) */ ecenterZERO, /* (0,0,0) */ @@ -133,7 +140,7 @@ int ePBC2npbcdim(int ePBC); * \param[in] fp The file pointer to write to * \param[in] pbc The periodic boundary condition information structure */ -void dump_pbc(FILE *fp, t_pbc *pbc); +void dump_pbc(FILE* fp, t_pbc* pbc); /*! \brief Check the box for consistency * @@ -143,7 +150,7 @@ void dump_pbc(FILE *fp, t_pbc *pbc); * Otherwise returns a string with the problem. * When ePBC=-1, the type of pbc is guessed from the box matrix. */ -const char *check_box(int ePBC, const matrix box); +const char* check_box(int ePBC, const matrix box); /*! \brief Creates box matrix from edge lengths and angles. * @@ -182,7 +189,7 @@ int guess_ePBC(const matrix box); * \param[in] graph Information about molecular connectivity * \return TRUE when the box was corrected. */ -gmx_bool correct_box(FILE *fplog, int step, tensor box, struct t_graph *graph); +gmx_bool correct_box(FILE* fplog, int step, tensor box, struct t_graph* graph); /*! \brief Initiate the periodic boundary condition algorithms. * @@ -193,7 +200,7 @@ gmx_bool correct_box(FILE *fplog, int step, tensor box, struct t_graph *graph); * \param[in] ePBC The PBC identifier * \param[in] box The box tensor */ -void set_pbc(t_pbc *pbc, int ePBC, const matrix box); +void set_pbc(t_pbc* pbc, int ePBC, const matrix box); /*! \brief Initiate the periodic boundary condition algorithms. * @@ -213,9 +220,7 @@ void set_pbc(t_pbc *pbc, int ePBC, const matrix box); * \param[in] box The box tensor * \return the pbc structure when pbc operations are required, NULL otherwise. */ -t_pbc *set_pbc_dd(t_pbc *pbc, int ePBC, - const ivec domdecCells, gmx_bool bSingleDir, - const matrix box); +t_pbc* set_pbc_dd(t_pbc* pbc, int ePBC, const ivec domdecCells, gmx_bool bSingleDir, const matrix box); /*! \brief Compute distance with PBC * @@ -229,7 +234,7 @@ t_pbc *set_pbc_dd(t_pbc *pbc, int ePBC, * \param[in] x2 Coordinates for particle 2 * \param[out] dx Distance vector */ -void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx); +void pbc_dx(const t_pbc* pbc, const rvec x1, const rvec x2, rvec dx); /*! \brief Compute distance vector for simple PBC types * @@ -245,7 +250,7 @@ void pbc_dx(const t_pbc *pbc, const rvec x1, const rvec x2, rvec dx); * i.e. if 0<=ishift x * \param[in] box The simulation box * \param[in,out] x The coordinates of the atoms */ -void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, - gmx::ArrayRef x); +void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, gmx::ArrayRef x); /*! \brief Put atoms inside the unitcell * @@ -345,9 +348,7 @@ void put_atoms_in_triclinic_unitcell(int ecenter, const matrix box, * \param[in] box The simulation box * \param[in,out] x The coordinates of the atoms */ -void put_atoms_in_compact_unitcell(int ePBC, int ecenter, - const matrix box, - gmx::ArrayRef x); +void put_atoms_in_compact_unitcell(int ePBC, int ecenter, const matrix box, gmx::ArrayRef x); /*! \brief Make all molecules whole by shifting positions * @@ -357,8 +358,7 @@ void put_atoms_in_compact_unitcell(int ePBC, int ecenter, * \param[in] mtop System topology definition * \param[in,out] x The coordinates of the atoms */ -void do_pbc_first_mtop(FILE *fplog, int ePBC, const matrix box, - const gmx_mtop_t *mtop, rvec x[]); +void do_pbc_first_mtop(FILE* fplog, int ePBC, const matrix box, const gmx_mtop_t* mtop, rvec x[]); /*! \brief Make molecules consisting of multiple charge groups whole by shifting positions * @@ -367,7 +367,6 @@ void do_pbc_first_mtop(FILE *fplog, int ePBC, const matrix box, * \param[in] mtop System topology definition * \param[in,out] x The coordinates of the atoms */ -void do_pbc_mtop(int ePBC, const matrix box, - const gmx_mtop_t *mtop, rvec x[]); +void do_pbc_mtop(int ePBC, const matrix box, const gmx_mtop_t* mtop, rvec x[]); #endif diff --git a/src/gromacs/pbcutil/pbc_aiuc.h b/src/gromacs/pbcutil/pbc_aiuc.h index 72811bcdf9..e8888f65d6 100644 --- a/src/gromacs/pbcutil/pbc_aiuc.h +++ b/src/gromacs/pbcutil/pbc_aiuc.h @@ -96,10 +96,7 @@ struct PbcAiuc * \param[out] pbcAiuc Pointer to PbcAiuc structure to be initialized. * */ -static inline -void setPbcAiuc(int numPbcDim, - const matrix box, - PbcAiuc *pbcAiuc) +static inline void setPbcAiuc(int numPbcDim, const matrix box, PbcAiuc* pbcAiuc) { pbcAiuc->invBoxDiagZ = 0.0f; @@ -114,20 +111,20 @@ void setPbcAiuc(int numPbcDim, if (numPbcDim > ZZ) { - pbcAiuc->invBoxDiagZ = 1.0f/box[ZZ][ZZ]; + pbcAiuc->invBoxDiagZ = 1.0f / box[ZZ][ZZ]; pbcAiuc->boxZX = box[ZZ][XX]; pbcAiuc->boxZY = box[ZZ][YY]; pbcAiuc->boxZZ = box[ZZ][ZZ]; } if (numPbcDim > YY) { - pbcAiuc->invBoxDiagY = 1.0f/box[YY][YY]; + pbcAiuc->invBoxDiagY = 1.0f / box[YY][YY]; pbcAiuc->boxYX = box[YY][XX]; pbcAiuc->boxYY = box[YY][YY]; } if (numPbcDim > XX) { - pbcAiuc->invBoxDiagX = 1.0f/box[XX][XX]; + pbcAiuc->invBoxDiagX = 1.0f / box[XX][XX]; pbcAiuc->boxXX = box[XX][XX]; } } @@ -154,28 +151,24 @@ void setPbcAiuc(int numPbcDim, * \param[in] r2 Coordinates of the second point. * \param[out] dr Resulting distance. */ -static inline -void pbcDxAiuc(const PbcAiuc &pbcAiuc, - const rvec &r1, - const rvec &r2, - rvec dr) +static inline void pbcDxAiuc(const PbcAiuc& pbcAiuc, const rvec& r1, const rvec& r2, rvec dr) { dr[XX] = r1[XX] - r2[XX]; dr[YY] = r1[YY] - r2[YY]; dr[ZZ] = r1[ZZ] - r2[ZZ]; - float shz = rintf(dr[ZZ]*pbcAiuc.invBoxDiagZ); - dr[XX] -= shz*pbcAiuc.boxZX; - dr[YY] -= shz*pbcAiuc.boxZY; - dr[ZZ] -= shz*pbcAiuc.boxZZ; + float shz = rintf(dr[ZZ] * pbcAiuc.invBoxDiagZ); + dr[XX] -= shz * pbcAiuc.boxZX; + dr[YY] -= shz * pbcAiuc.boxZY; + dr[ZZ] -= shz * pbcAiuc.boxZZ; - float shy = rintf(dr[YY]*pbcAiuc.invBoxDiagY); - dr[XX] -= shy*pbcAiuc.boxYX; - dr[YY] -= shy*pbcAiuc.boxYY; + float shy = rintf(dr[YY] * pbcAiuc.invBoxDiagY); + dr[XX] -= shy * pbcAiuc.boxYX; + dr[YY] -= shy * pbcAiuc.boxYY; - float shx = rintf(dr[XX]*pbcAiuc.invBoxDiagX); - dr[XX] -= shx*pbcAiuc.boxXX; + float shx = rintf(dr[XX] * pbcAiuc.invBoxDiagX); + dr[XX] -= shx * pbcAiuc.boxXX; } -#endif //GMX_PBCUTIL_PBC_AIUC_H +#endif // GMX_PBCUTIL_PBC_AIUC_H diff --git a/src/gromacs/pbcutil/pbc_aiuc_cuda.cuh b/src/gromacs/pbcutil/pbc_aiuc_cuda.cuh index 6115964b1a..0444a9e3e6 100644 --- a/src/gromacs/pbcutil/pbc_aiuc_cuda.cuh +++ b/src/gromacs/pbcutil/pbc_aiuc_cuda.cuh @@ -81,28 +81,25 @@ * \param[in] r2 Coordinates of the second point. * \param[out] dr Resulting distance. */ -template -static __forceinline__ __device__ -int pbcDxAiuc(const PbcAiuc &pbcAiuc, - const float4 &r1, - const float4 &r2, - fvec dr) +template +static __forceinline__ __device__ int + pbcDxAiuc(const PbcAiuc& pbcAiuc, const float4& r1, const float4& r2, fvec dr) { dr[XX] = r1.x - r2.x; dr[YY] = r1.y - r2.y; dr[ZZ] = r1.z - r2.z; - float shz = rintf(dr[ZZ]*pbcAiuc.invBoxDiagZ); - dr[XX] -= shz*pbcAiuc.boxZX; - dr[YY] -= shz*pbcAiuc.boxZY; - dr[ZZ] -= shz*pbcAiuc.boxZZ; + float shz = rintf(dr[ZZ] * pbcAiuc.invBoxDiagZ); + dr[XX] -= shz * pbcAiuc.boxZX; + dr[YY] -= shz * pbcAiuc.boxZY; + dr[ZZ] -= shz * pbcAiuc.boxZZ; - float shy = rintf(dr[YY]*pbcAiuc.invBoxDiagY); - dr[XX] -= shy*pbcAiuc.boxYX; - dr[YY] -= shy*pbcAiuc.boxYY; + float shy = rintf(dr[YY] * pbcAiuc.invBoxDiagY); + dr[XX] -= shy * pbcAiuc.boxYX; + dr[YY] -= shy * pbcAiuc.boxYY; - float shx = rintf(dr[XX]*pbcAiuc.invBoxDiagX); - dr[XX] -= shx*pbcAiuc.boxXX; + float shx = rintf(dr[XX] * pbcAiuc.invBoxDiagX); + dr[XX] -= shx * pbcAiuc.boxXX; if (returnShift) { @@ -139,26 +136,25 @@ int pbcDxAiuc(const PbcAiuc &pbcAiuc, * \param[in] r2 Coordinates of the second point. * \returns dr Resulting distance. */ -static __forceinline__ __host__ __device__ -float3 pbcDxAiuc(const PbcAiuc &pbcAiuc, - const float3 &r1, - const float3 &r2) +static __forceinline__ __host__ __device__ float3 pbcDxAiuc(const PbcAiuc& pbcAiuc, + const float3& r1, + const float3& r2) { float3 dr = r1 - r2; - float shz = rintf(dr.z*pbcAiuc.invBoxDiagZ); - dr.x -= shz*pbcAiuc.boxZX; - dr.y -= shz*pbcAiuc.boxZY; - dr.z -= shz*pbcAiuc.boxZZ; + float shz = rintf(dr.z * pbcAiuc.invBoxDiagZ); + dr.x -= shz * pbcAiuc.boxZX; + dr.y -= shz * pbcAiuc.boxZY; + dr.z -= shz * pbcAiuc.boxZZ; - float shy = rintf(dr.y*pbcAiuc.invBoxDiagY); - dr.x -= shy*pbcAiuc.boxYX; - dr.y -= shy*pbcAiuc.boxYY; + float shy = rintf(dr.y * pbcAiuc.invBoxDiagY); + dr.x -= shy * pbcAiuc.boxYX; + dr.y -= shy * pbcAiuc.boxYY; - float shx = rintf(dr.x*pbcAiuc.invBoxDiagX); - dr.x -= shx*pbcAiuc.boxXX; + float shx = rintf(dr.x * pbcAiuc.invBoxDiagX); + dr.x -= shx * pbcAiuc.boxXX; return dr; } -#endif //GMX_PBCUTIL_PBC_AIUC_CUDA_CUH +#endif // GMX_PBCUTIL_PBC_AIUC_CUDA_CUH diff --git a/src/gromacs/pbcutil/pbc_simd.cpp b/src/gromacs/pbcutil/pbc_simd.cpp index 92700e830f..d27661821c 100644 --- a/src/gromacs/pbcutil/pbc_simd.cpp +++ b/src/gromacs/pbcutil/pbc_simd.cpp @@ -50,35 +50,34 @@ using namespace gmx; // TODO: Remove when this file is moved into gmx namespace -void set_pbc_simd(const t_pbc gmx_unused *pbc, - real gmx_unused *pbc_simd) +void set_pbc_simd(const t_pbc gmx_unused* pbc, real gmx_unused* pbc_simd) { #if GMX_SIMD_HAVE_REAL if (pbc != nullptr && pbc->ePBC != epbcNONE) { - rvec inv_box_diag = {0, 0, 0}; + rvec inv_box_diag = { 0, 0, 0 }; for (int d = 0; d < pbc->ndim_ePBC; d++) { - inv_box_diag[d] = 1.0/pbc->box[d][d]; + inv_box_diag[d] = 1.0 / pbc->box[d][d]; } - store(pbc_simd + 0*GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[ZZ])); - store(pbc_simd + 1*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][XX])); - store(pbc_simd + 2*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][YY])); - store(pbc_simd + 3*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][ZZ])); - store(pbc_simd + 4*GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[YY])); - store(pbc_simd + 5*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[YY][XX])); - store(pbc_simd + 6*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[YY][YY])); - store(pbc_simd + 7*GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[XX])); - store(pbc_simd + 8*GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[XX][XX])); + store(pbc_simd + 0 * GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[ZZ])); + store(pbc_simd + 1 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][XX])); + store(pbc_simd + 2 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][YY])); + store(pbc_simd + 3 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[ZZ][ZZ])); + store(pbc_simd + 4 * GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[YY])); + store(pbc_simd + 5 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[YY][XX])); + store(pbc_simd + 6 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[YY][YY])); + store(pbc_simd + 7 * GMX_SIMD_REAL_WIDTH, SimdReal(inv_box_diag[XX])); + store(pbc_simd + 8 * GMX_SIMD_REAL_WIDTH, SimdReal(pbc->box[XX][XX])); } else { /* Setting inv_box_diag to zero leads to no PBC being applied */ - for (int i = 0; i < (DIM + DIM*(DIM+1)/2); i++) + for (int i = 0; i < (DIM + DIM * (DIM + 1) / 2); i++) { - store(pbc_simd + i*GMX_SIMD_REAL_WIDTH, SimdReal(0)); + store(pbc_simd + i * GMX_SIMD_REAL_WIDTH, SimdReal(0)); } } #endif diff --git a/src/gromacs/pbcutil/pbc_simd.h b/src/gromacs/pbcutil/pbc_simd.h index e5e64d9d23..09ba1e7a42 100644 --- a/src/gromacs/pbcutil/pbc_simd.h +++ b/src/gromacs/pbcutil/pbc_simd.h @@ -65,8 +65,7 @@ struct gmx_domdec_t; * The order is inv_bzz, bzx, bzy, bzz, inv_byy, byx, byy, * inv_bxx, and bxx. */ -void set_pbc_simd(const t_pbc *pbc, - real *pbc_simd); +void set_pbc_simd(const t_pbc* pbc, real* pbc_simd); #if GMX_SIMD_HAVE_REAL @@ -81,27 +80,25 @@ void set_pbc_simd(const t_pbc *pbc, * without PBC. But on modern processors the overhead of this, often called, * routine should be low. On e.g. Intel Haswell/Broadwell it takes 8 cycles. */ -static inline void gmx_simdcall -pbc_correct_dx_simd(gmx::SimdReal *dx, - gmx::SimdReal *dy, - gmx::SimdReal *dz, - const real *pbc_simd) +static inline void gmx_simdcall pbc_correct_dx_simd(gmx::SimdReal* dx, + gmx::SimdReal* dy, + gmx::SimdReal* dz, + const real* pbc_simd) { using namespace gmx; SimdReal shz, shy, shx; - shz = round(*dz * load(pbc_simd+0*GMX_SIMD_REAL_WIDTH)); // load inv_bzz - *dx = *dx - shz * load(pbc_simd+1*GMX_SIMD_REAL_WIDTH); // load bzx - *dy = *dy - shz * load(pbc_simd+2*GMX_SIMD_REAL_WIDTH); // load bzy - *dz = *dz - shz * load(pbc_simd+3*GMX_SIMD_REAL_WIDTH); // load bzz + shz = round(*dz * load(pbc_simd + 0 * GMX_SIMD_REAL_WIDTH)); // load inv_bzz + *dx = *dx - shz * load(pbc_simd + 1 * GMX_SIMD_REAL_WIDTH); // load bzx + *dy = *dy - shz * load(pbc_simd + 2 * GMX_SIMD_REAL_WIDTH); // load bzy + *dz = *dz - shz * load(pbc_simd + 3 * GMX_SIMD_REAL_WIDTH); // load bzz - shy = round(*dy * load(pbc_simd+4*GMX_SIMD_REAL_WIDTH)); // load inv_byy - *dx = *dx - shy * load(pbc_simd+5*GMX_SIMD_REAL_WIDTH); // load byx - *dy = *dy - shy * load(pbc_simd+6*GMX_SIMD_REAL_WIDTH); // load byy - - shx = round(*dx * load(pbc_simd+7*GMX_SIMD_REAL_WIDTH)); // load inv_bxx - *dx = *dx - shx * load(pbc_simd+8*GMX_SIMD_REAL_WIDTH); // load bxx + shy = round(*dy * load(pbc_simd + 4 * GMX_SIMD_REAL_WIDTH)); // load inv_byy + *dx = *dx - shy * load(pbc_simd + 5 * GMX_SIMD_REAL_WIDTH); // load byx + *dy = *dy - shy * load(pbc_simd + 6 * GMX_SIMD_REAL_WIDTH); // load byy + shx = round(*dx * load(pbc_simd + 7 * GMX_SIMD_REAL_WIDTH)); // load inv_bxx + *dx = *dx - shx * load(pbc_simd + 8 * GMX_SIMD_REAL_WIDTH); // load bxx } /*! \brief Calculates the PBC corrected distance between SIMD coordinates. @@ -115,11 +112,10 @@ pbc_correct_dx_simd(gmx::SimdReal *dx, * when all atoms are in the unit-cell (aiuc). * This is the SIMD equivalent of the scalar version declared in pbc.h. */ -static inline void gmx_simdcall -pbc_dx_aiuc(const real *pbc_simd, - const gmx::SimdReal *x1, - const gmx::SimdReal *x2, - gmx::SimdReal *dx) +static inline void gmx_simdcall pbc_dx_aiuc(const real* pbc_simd, + const gmx::SimdReal* x1, + const gmx::SimdReal* x2, + gmx::SimdReal* dx) { for (int d = 0; d < DIM; d++) { diff --git a/src/gromacs/pbcutil/pbcenums.cpp b/src/gromacs/pbcutil/pbcenums.cpp index 3d18096b0a..eb230a6043 100644 --- a/src/gromacs/pbcutil/pbcenums.cpp +++ b/src/gromacs/pbcutil/pbcenums.cpp @@ -55,33 +55,25 @@ namespace gmx * Those names need to be in sync with the CenteringType enum class * and reflect the same fields there. */ -static EnumerationArray -c_centeringTypeShortNames - = { { - "Triclinic", - "Rectangular", - "Zero-Based" - } }; +static EnumerationArray c_centeringTypeShortNames = { + { "Triclinic", "Rectangular", "Zero-Based" } +}; /*! \brief Names for different centering types. * * Those names need to be in sync with the UnitCellType enum class * and reflect the same fields there. */ -static EnumerationArray -c_unitCellTypeShortNames - = { { - "Triclinic", - "Rectangular", - "Compact" - } }; +static EnumerationArray c_unitCellTypeShortNames = { + { "Triclinic", "Rectangular", "Compact" } +}; -const char *centerTypeNames(CenteringType type) +const char* centerTypeNames(CenteringType type) { return c_centeringTypeShortNames[type]; } -const char *unitCellTypeNames(UnitCellType type) +const char* unitCellTypeNames(UnitCellType type) { return c_unitCellTypeShortNames[type]; } diff --git a/src/gromacs/pbcutil/pbcenums.h b/src/gromacs/pbcutil/pbcenums.h index 68c68fdc48..d7e1a91f55 100644 --- a/src/gromacs/pbcutil/pbcenums.h +++ b/src/gromacs/pbcutil/pbcenums.h @@ -73,14 +73,14 @@ enum class UnitCellType * * \param[in] type Centering type to get a name for. */ -const char *centerTypeNames(CenteringType type); +const char* centerTypeNames(CenteringType type); /*! \brief * Get names for the different unit cell representation types. * * \param[in] type Unit cell type to get a name for. */ -const char *unitCellTypeNames(UnitCellType type); +const char* unitCellTypeNames(UnitCellType type); } // namespace gmx diff --git a/src/gromacs/pbcutil/pbcmethods.cpp b/src/gromacs/pbcutil/pbcmethods.cpp index 11af37418c..7cdd4e1ca7 100644 --- a/src/gromacs/pbcutil/pbcmethods.cpp +++ b/src/gromacs/pbcutil/pbcmethods.cpp @@ -44,20 +44,19 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, - rvec x[], const int index[], matrix box) +void calc_pbc_cluster(int ecenter, int nrefat, t_topology* top, int ePBC, rvec x[], const int index[], matrix box) { int m, i, j, j0, j1, jj, ai, aj; int imin, jmin; real fac, min_dist2; rvec dx, xtest, box_center; int nmol, imol_center; - int *molind; + int* molind; gmx_bool *bMol, *bTmp; - rvec *m_com, *m_shift; + rvec * m_com, *m_shift; t_pbc pbc; - int *cluster; - int *added; + int* cluster; + int* added; int ncluster, nadded; real tmp_r2; @@ -84,10 +83,10 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, bTmp[ai] = TRUE; /* Binary search assuming the molecules are sorted */ j0 = 0; - j1 = nmol-1; + j1 = nmol - 1; while (j0 < j1) { - if (ai < molind[j0+1]) + if (ai < molind[j0 + 1]) { j1 = j0; } @@ -97,8 +96,8 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, } else { - jj = (j0+j1)/2; - if (ai < molind[jj+1]) + jj = (j0 + j1) / 2; + if (ai < molind[jj + 1]) { j1 = jj; } @@ -113,28 +112,34 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, /* Double check whether all atoms in all molecules that are marked are part * of the cluster. Simultaneously compute the center of geometry. */ - min_dist2 = 10*gmx::square(trace(box)); + min_dist2 = 10 * gmx::square(trace(box)); imol_center = -1; ncluster = 0; for (i = 0; i < nmol; i++) { - for (j = molind[i]; j < molind[i+1]; j++) + for (j = molind[i]; j < molind[i + 1]; j++) { if (bMol[i] && !bTmp[j]) { - gmx_fatal(FARGS, "Molecule %d marked for clustering but not atom %d in it - check your index!", i+1, j+1); + gmx_fatal(FARGS, + "Molecule %d marked for clustering but not atom %d in it - check your " + "index!", + i + 1, j + 1); } else if (!bMol[i] && bTmp[j]) { - gmx_fatal(FARGS, "Atom %d marked for clustering but not molecule %d - this is an internal error...", j+1, i+1); + gmx_fatal(FARGS, + "Atom %d marked for clustering but not molecule %d - this is an internal " + "error...", + j + 1, i + 1); } else if (bMol[i]) { /* Make molecule whole, move 2nd and higher atom to same periodicity as 1st atom in molecule */ if (j > molind[i]) { - pbc_dx(&pbc, x[j], x[j-1], dx); - rvec_add(x[j-1], dx, x[j]); + pbc_dx(&pbc, x[j], x[j - 1], dx); + rvec_add(x[j - 1], dx, x[j]); } /* Compute center of geometry of molecule - m_com[i] was zeroed when we did snew() on it! */ rvec_inc(m_com[i], x[j]); @@ -143,7 +148,7 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, if (bMol[i]) { /* Normalize center of geometry */ - fac = 1.0/(molind[i+1]-molind[i]); + fac = 1.0 / (molind[i + 1] - molind[i]); for (m = 0; (m < DIM); m++) { m_com[i][m] *= fac; @@ -180,9 +185,9 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, while (nadded < ncluster) { /* Find min distance between cluster molecules and those remaining to be added */ - min_dist2 = 10*gmx::square(trace(box)); - imin = -1; - jmin = -1; + min_dist2 = 10 * gmx::square(trace(box)); + imin = -1; + jmin = -1; /* Loop over added mols */ for (i = 0; i < nadded; i++) { @@ -198,24 +203,24 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, tmp_r2 = iprod(dx, dx); if (tmp_r2 < min_dist2) { - min_dist2 = tmp_r2; - imin = ai; - jmin = aj; + min_dist2 = tmp_r2; + imin = ai; + jmin = aj; } } } } /* Add the best molecule */ - added[nadded++] = jmin; - bMol[jmin] = FALSE; + added[nadded++] = jmin; + bMol[jmin] = FALSE; /* Calculate the shift from the ai molecule */ pbc_dx(&pbc, m_com[jmin], m_com[imin], dx); rvec_add(m_com[imin], dx, xtest); rvec_sub(xtest, m_com[jmin], m_shift[jmin]); rvec_inc(m_com[jmin], m_shift[jmin]); - for (j = molind[jmin]; j < molind[jmin+1]; j++) + for (j = molind[jmin]; j < molind[jmin + 1]; j++) { rvec_inc(x[j], m_shift[jmin]); } @@ -232,53 +237,54 @@ void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, fprintf(stdout, "\n"); } -void put_molecule_com_in_box(int unitcell_enum, int ecenter, - t_block *mols, - int natoms, t_atom atom[], - int ePBC, matrix box, rvec x[]) +void put_molecule_com_in_box(int unitcell_enum, + int ecenter, + t_block* mols, + int natoms, + t_atom atom[], + int ePBC, + matrix box, + rvec x[]) { - int i, j; - int d; - rvec com, shift, box_center; - real m; - double mtot; - t_pbc pbc; + int i, j; + int d; + rvec com, shift, box_center; + real m; + double mtot; + t_pbc pbc; calc_box_center(ecenter, box, box_center); set_pbc(&pbc, ePBC, box); if (mols->nr <= 0) { - gmx_fatal(FARGS, "There are no molecule descriptions. I need a .tpr file for this pbc option."); + gmx_fatal(FARGS, + "There are no molecule descriptions. I need a .tpr file for this pbc option."); } for (i = 0; (i < mols->nr); i++) { /* calc COM */ clear_rvec(com); mtot = 0; - for (j = mols->index[i]; (j < mols->index[i+1] && j < natoms); j++) + for (j = mols->index[i]; (j < mols->index[i + 1] && j < natoms); j++) { m = atom[j].m; for (d = 0; d < DIM; d++) { - com[d] += m*x[j][d]; + com[d] += m * x[j][d]; } mtot += m; } /* calculate final COM */ - svmul(1.0/mtot, com, com); + svmul(1.0 / mtot, com, com); /* check if COM is outside box */ gmx::RVec newCom; copy_rvec(com, newCom); - auto newComArrayRef = gmx::arrayRefFromArray(&newCom, 1); + auto newComArrayRef = gmx::arrayRefFromArray(&newCom, 1); switch (unitcell_enum) { - case euRect: - put_atoms_in_box(ePBC, box, newComArrayRef); - break; - case euTric: - put_atoms_in_triclinic_unitcell(ecenter, box, newComArrayRef); - break; + case euRect: put_atoms_in_box(ePBC, box, newComArrayRef); break; + case euTric: put_atoms_in_triclinic_unitcell(ecenter, box, newComArrayRef); break; case euCompact: put_atoms_in_compact_unitcell(ePBC, ecenter, box, newComArrayRef); break; @@ -288,11 +294,12 @@ void put_molecule_com_in_box(int unitcell_enum, int ecenter, { if (debug) { - fprintf(debug, "\nShifting position of molecule %d " - "by %8.3f %8.3f %8.3f\n", i+1, - shift[XX], shift[YY], shift[ZZ]); + fprintf(debug, + "\nShifting position of molecule %d " + "by %8.3f %8.3f %8.3f\n", + i + 1, shift[XX], shift[YY], shift[ZZ]); } - for (j = mols->index[i]; (j < mols->index[i+1] && j < natoms); j++) + for (j = mols->index[i]; (j < mols->index[i + 1] && j < natoms); j++) { rvec_inc(x[j], shift); } @@ -300,9 +307,7 @@ void put_molecule_com_in_box(int unitcell_enum, int ecenter, } } -void put_residue_com_in_box(int unitcell_enum, int ecenter, - int natoms, t_atom atom[], - int ePBC, matrix box, rvec x[]) +void put_residue_com_in_box(int unitcell_enum, int ecenter, int natoms, t_atom atom[], int ePBC, matrix box, rvec x[]) { int i, j, res_start, res_end; int d, presnr; @@ -316,26 +321,22 @@ void put_residue_com_in_box(int unitcell_enum, int ecenter, res_start = 0; clear_rvec(com); mtot = 0; - for (i = 0; i < natoms+1; i++) + for (i = 0; i < natoms + 1; i++) { if (i == natoms || (presnr != atom[i].resind && presnr != NOTSET)) { /* calculate final COM */ res_end = i; - svmul(1.0/mtot, com, com); + svmul(1.0 / mtot, com, com); /* check if COM is outside box */ gmx::RVec newCom; copy_rvec(com, newCom); - auto newComArrayRef = gmx::arrayRefFromArray(&newCom, 1); + auto newComArrayRef = gmx::arrayRefFromArray(&newCom, 1); switch (unitcell_enum) { - case euRect: - put_atoms_in_box(ePBC, box, newComArrayRef); - break; - case euTric: - put_atoms_in_triclinic_unitcell(ecenter, box, newComArrayRef); - break; + case euRect: put_atoms_in_box(ePBC, box, newComArrayRef); break; + case euTric: put_atoms_in_triclinic_unitcell(ecenter, box, newComArrayRef); break; case euCompact: put_atoms_in_compact_unitcell(ePBC, ecenter, box, newComArrayRef); break; @@ -345,9 +346,11 @@ void put_residue_com_in_box(int unitcell_enum, int ecenter, { if (debug) { - fprintf(debug, "\nShifting position of residue %d (atoms %d-%d) " - "by %g,%g,%g\n", atom[res_start].resind+1, - res_start+1, res_end+1, shift[XX], shift[YY], shift[ZZ]); + fprintf(debug, + "\nShifting position of residue %d (atoms %d-%d) " + "by %g,%g,%g\n", + atom[res_start].resind + 1, res_start + 1, res_end + 1, shift[XX], + shift[YY], shift[ZZ]); } for (j = res_start; j < res_end; j++) { @@ -366,7 +369,7 @@ void put_residue_com_in_box(int unitcell_enum, int ecenter, m = atom[i].m; for (d = 0; d < DIM; d++) { - com[d] += m*x[i][d]; + com[d] += m * x[i][d]; } mtot += m; @@ -402,7 +405,7 @@ void center_x(int ecenter, rvec x[], matrix box, int n, int nc, const int ci[]) calc_box_center(ecenter, box, box_center); for (m = 0; m < DIM; m++) { - dx[m] = box_center[m]-(cmin[m]+cmax[m])*0.5; + dx[m] = box_center[m] - (cmin[m] + cmax[m]) * 0.5; } for (i = 0; i < n; i++) diff --git a/src/gromacs/pbcutil/pbcmethods.h b/src/gromacs/pbcutil/pbcmethods.h index 49356a84b5..ff796c5c9b 100644 --- a/src/gromacs/pbcutil/pbcmethods.h +++ b/src/gromacs/pbcutil/pbcmethods.h @@ -43,22 +43,28 @@ struct t_atom; #include "gromacs/math/vec.h" -enum { - euSel, euRect, euTric, euCompact, euNR +enum +{ + euSel, + euRect, + euTric, + euCompact, + euNR }; -void calc_pbc_cluster(int ecenter, int nrefat, t_topology *top, int ePBC, - rvec x[], const int index[], matrix box); +void calc_pbc_cluster(int ecenter, int nrefat, t_topology* top, int ePBC, rvec x[], const int index[], matrix box); -void put_molecule_com_in_box(int unitcell_enum, int ecenter, - t_block *mols, - int natoms, t_atom atom[], - int ePBC, matrix box, rvec x[]); +void put_molecule_com_in_box(int unitcell_enum, + int ecenter, + t_block* mols, + int natoms, + t_atom atom[], + int ePBC, + matrix box, + rvec x[]); -void put_residue_com_in_box(int unitcell_enum, int ecenter, - int natoms, t_atom atom[], - int ePBC, matrix box, rvec x[]); +void put_residue_com_in_box(int unitcell_enum, int ecenter, int natoms, t_atom atom[], int ePBC, matrix box, rvec x[]); void center_x(int ecenter, rvec x[], matrix box, int n, int nc, const int ci[]); diff --git a/src/gromacs/pbcutil/rmpbc.cpp b/src/gromacs/pbcutil/rmpbc.cpp index 20336c6c73..483dc71513 100644 --- a/src/gromacs/pbcutil/rmpbc.cpp +++ b/src/gromacs/pbcutil/rmpbc.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,28 +53,27 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int natoms; - t_graph *gr; + t_graph* gr; } rmpbc_graph_t; -struct gmx_rmpbc { - const t_idef *idef; +struct gmx_rmpbc +{ + const t_idef* idef; int natoms_init; int ePBC; int ngraph; - rmpbc_graph_t *graph; + rmpbc_graph_t* graph; }; -static t_graph *gmx_rmpbc_get_graph(gmx_rmpbc_t gpbc, int ePBC, int natoms) +static t_graph* gmx_rmpbc_get_graph(gmx_rmpbc_t gpbc, int ePBC, int natoms) { int i; - rmpbc_graph_t *gr; + rmpbc_graph_t* gr; - if (ePBC == epbcNONE - || nullptr == gpbc - || nullptr == gpbc->idef - || gpbc->idef->ntypes <= 0) + if (ePBC == epbcNONE || nullptr == gpbc || nullptr == gpbc->idef || gpbc->idef->ntypes <= 0) { return nullptr; } @@ -96,11 +95,13 @@ static t_graph *gmx_rmpbc_get_graph(gmx_rmpbc_t gpbc, int ePBC, int natoms) */ if (natoms > gpbc->natoms_init) { - gmx_fatal(FARGS, "Structure or trajectory file has more atoms (%d) than the topology (%d)", natoms, gpbc->natoms_init); + gmx_fatal(FARGS, + "Structure or trajectory file has more atoms (%d) than the topology (%d)", + natoms, gpbc->natoms_init); } gpbc->ngraph++; srenew(gpbc->graph, gpbc->ngraph); - gr = &gpbc->graph[gpbc->ngraph-1]; + gr = &gpbc->graph[gpbc->ngraph - 1]; gr->natoms = natoms; gr->gr = mk_graph(nullptr, gpbc->idef, 0, natoms, FALSE, FALSE); } @@ -108,7 +109,7 @@ static t_graph *gmx_rmpbc_get_graph(gmx_rmpbc_t gpbc, int ePBC, int natoms) return gr->gr; } -gmx_rmpbc_t gmx_rmpbc_init(const t_idef *idef, int ePBC, int natoms) +gmx_rmpbc_t gmx_rmpbc_init(const t_idef* idef, int ePBC, int natoms) { gmx_rmpbc_t gpbc; @@ -169,7 +170,7 @@ static int gmx_rmpbc_ePBC(gmx_rmpbc_t gpbc, const matrix box) void gmx_rmpbc(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[]) { int ePBC; - t_graph *gr; + t_graph* gr; ePBC = gmx_rmpbc_ePBC(gpbc, box); gr = gmx_rmpbc_get_graph(gpbc, ePBC, natoms); @@ -183,7 +184,7 @@ void gmx_rmpbc(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[]) void gmx_rmpbc_copy(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[], rvec x_s[]) { int ePBC; - t_graph *gr; + t_graph* gr; int i; ePBC = gmx_rmpbc_ePBC(gpbc, box); @@ -202,10 +203,10 @@ void gmx_rmpbc_copy(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[], rv } } -void gmx_rmpbc_trxfr(gmx_rmpbc_t gpbc, t_trxframe *fr) +void gmx_rmpbc_trxfr(gmx_rmpbc_t gpbc, t_trxframe* fr) { int ePBC; - t_graph *gr; + t_graph* gr; if (fr->bX && fr->bBox) { @@ -219,7 +220,7 @@ void gmx_rmpbc_trxfr(gmx_rmpbc_t gpbc, t_trxframe *fr) } } -void rm_gropbc(const t_atoms *atoms, rvec x[], const matrix box) +void rm_gropbc(const t_atoms* atoms, rvec x[], const matrix box) { real dist; int n, m, d; @@ -227,12 +228,12 @@ void rm_gropbc(const t_atoms *atoms, rvec x[], const matrix box) /* check periodic boundary */ for (n = 1; (n < atoms->nr); n++) { - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { - dist = x[n][m]-x[n-1][m]; - if (std::abs(dist) > 0.9*box[m][m]) + dist = x[n][m] - x[n - 1][m]; + if (std::abs(dist) > 0.9 * box[m][m]) { - if (dist > 0) + if (dist > 0) { for (d = 0; d <= m; d++) { diff --git a/src/gromacs/pbcutil/rmpbc.h b/src/gromacs/pbcutil/rmpbc.h index 256d22fdc5..0feb096495 100644 --- a/src/gromacs/pbcutil/rmpbc.h +++ b/src/gromacs/pbcutil/rmpbc.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,9 +43,9 @@ struct t_atoms; struct t_idef; struct t_trxframe; -typedef struct gmx_rmpbc *gmx_rmpbc_t; +typedef struct gmx_rmpbc* gmx_rmpbc_t; -gmx_rmpbc_t gmx_rmpbc_init(const t_idef *idef, int ePBC, int natoms); +gmx_rmpbc_t gmx_rmpbc_init(const t_idef* idef, int ePBC, int natoms); void gmx_rmpbc_done(gmx_rmpbc_t gpbc); @@ -57,14 +57,13 @@ void gmx_rmpbc(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[]); * When ePBC=-1, the type of pbc is guessed from the box matrix. */ -void gmx_rmpbc_copy(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[], - rvec x_s[]); +void gmx_rmpbc_copy(gmx_rmpbc_t gpbc, int natoms, const matrix box, rvec x[], rvec x_s[]); /* As gmx_rmpbc, but outputs in x_s and does not modify x. */ -void gmx_rmpbc_trxfr(gmx_rmpbc_t gpbc, struct t_trxframe *fr); +void gmx_rmpbc_trxfr(gmx_rmpbc_t gpbc, struct t_trxframe* fr); /* As gmx_rmpbc but operates on a t_trxframe data structure. */ -void rm_gropbc(const t_atoms *atoms, rvec x[], const matrix box); +void rm_gropbc(const t_atoms* atoms, rvec x[], const matrix box); /* Simple routine for use in analysis tools that just have a pdb or * similar file. */ diff --git a/src/gromacs/pbcutil/tests/pbc.cpp b/src/gromacs/pbcutil/tests/pbc.cpp index eba2aa744d..47e3cf5bbc 100644 --- a/src/gromacs/pbcutil/tests/pbc.cpp +++ b/src/gromacs/pbcutil/tests/pbc.cpp @@ -61,9 +61,7 @@ TEST(PbcTest, CalcShiftsWorks) // Choose box vector entries whose magnitudes will lead to unique // shift vector values when the largest box shift in any dimension // is two. - const matrix box = {{ 0.01, 1, -100 }, - { 300, -0.03, 3 }, - { -6, -600, 0.06 }}; + const matrix box = { { 0.01, 1, -100 }, { 300, -0.03, 3 }, { -6, -600, 0.06 } }; rvec shiftVectors[SHIFTS]; calc_shifts(box, shiftVectors); diff --git a/src/gromacs/pulling/output.cpp b/src/gromacs/pulling/output.cpp index 0306e3f9ad..fa07f8b684 100644 --- a/src/gromacs/pulling/output.cpp +++ b/src/gromacs/pulling/output.cpp @@ -58,8 +58,7 @@ #include "pull_internal.h" -static std::string append_before_extension(const std::string &pathname, - const std::string &to_append) +static std::string append_before_extension(const std::string& pathname, const std::string& to_append) { /* Appends to_append before last '.' in pathname */ size_t extPos = pathname.find_last_of('.'); @@ -69,21 +68,20 @@ static std::string append_before_extension(const std::string &pathname, } else { - return pathname.substr(0, extPos) + to_append + - pathname.substr(extPos, std::string::npos); + return pathname.substr(0, extPos) + to_append + pathname.substr(extPos, std::string::npos); } } -static void addToPullxHistory(pull_t *pull) +static void addToPullxHistory(pull_t* pull) { GMX_RELEASE_ASSERT(pull->coordForceHistory, "Pull history does not exist."); pull->coordForceHistory->numValuesInXSum++; for (size_t c = 0; c < pull->coord.size(); c++) { - const pull_coord_work_t &pcrd = pull->coord[c]; - PullCoordinateHistory &pcrdHistory = pull->coordForceHistory->pullCoordinateSums[c]; + const pull_coord_work_t& pcrd = pull->coord[c]; + PullCoordinateHistory& pcrdHistory = pull->coordForceHistory->pullCoordinateSums[c]; - pcrdHistory.value += pcrd.spatialData.value; + pcrdHistory.value += pcrd.spatialData.value; pcrdHistory.valueRef += pcrd.value_ref; for (int m = 0; m < DIM; m++) @@ -102,7 +100,7 @@ static void addToPullxHistory(pull_t *pull) } for (size_t g = 0; g < pull->group.size(); g++) { - PullGroupHistory &pgrpHistory = pull->coordForceHistory->pullGroupSums[g]; + PullGroupHistory& pgrpHistory = pull->coordForceHistory->pullGroupSums[g]; for (int m = 0; m < DIM; m++) { pgrpHistory.x[m] += pull->group[g].x[m]; @@ -110,31 +108,30 @@ static void addToPullxHistory(pull_t *pull) } } -static void addToPullfHistory(pull_t *pull) +static void addToPullfHistory(pull_t* pull) { GMX_RELEASE_ASSERT(pull->coordForceHistory, "Pull history does not exist."); pull->coordForceHistory->numValuesInFSum++; for (size_t c = 0; c < pull->coord.size(); c++) { - const pull_coord_work_t &pcrd = pull->coord[c];; - PullCoordinateHistory &pcrdHistory = pull->coordForceHistory->pullCoordinateSums[c]; + const pull_coord_work_t& pcrd = pull->coord[c]; + + PullCoordinateHistory& pcrdHistory = pull->coordForceHistory->pullCoordinateSums[c]; pcrdHistory.scalarForce += pcrd.scalarForce; } } -static void pullResetHistory(PullHistory *history, - bool resetXHistory, - bool resetFHistory) +static void pullResetHistory(PullHistory* history, bool resetXHistory, bool resetFHistory) { if (resetXHistory) { history->numValuesInXSum = 0; - for (PullCoordinateHistory &pcrdHistory : history->pullCoordinateSums) + for (PullCoordinateHistory& pcrdHistory : history->pullCoordinateSums) { - pcrdHistory.value = 0; - pcrdHistory.valueRef = 0; + pcrdHistory.value = 0; + pcrdHistory.valueRef = 0; clear_dvec(pcrdHistory.dr01); clear_dvec(pcrdHistory.dr23); @@ -142,7 +139,7 @@ static void pullResetHistory(PullHistory *history, clear_dvec(pcrdHistory.dynaX); } - for (PullGroupHistory &pgrpHistory : history->pullGroupSums) + for (PullGroupHistory& pgrpHistory : history->pullGroupSums) { clear_dvec(pgrpHistory.x); } @@ -150,15 +147,14 @@ static void pullResetHistory(PullHistory *history, if (resetFHistory) { history->numValuesInFSum = 0; - for (PullCoordinateHistory &pcrdHistory : history->pullCoordinateSums) + for (PullCoordinateHistory& pcrdHistory : history->pullCoordinateSums) { pcrdHistory.scalarForce = 0; } } } -static void pull_print_coord_dr_components(FILE *out, const ivec dim, const dvec dr, - const int numValuesInSum) +static void pull_print_coord_dr_components(FILE* out, const ivec dim, const dvec dr, const int numValuesInSum) { for (int m = 0; m < DIM; m++) { @@ -169,21 +165,21 @@ static void pull_print_coord_dr_components(FILE *out, const ivec dim, const dvec } } -template -static void pull_print_coord_dr(FILE *out, - const pull_params_t &pullParams, - const t_pull_coord &coordParams, - const T &pcrdData, +template +static void pull_print_coord_dr(FILE* out, + const pull_params_t& pullParams, + const t_pull_coord& coordParams, + const T& pcrdData, double referenceValue, const int numValuesInSum) { const double unit_factor = pull_conversion_factor_internal2userinput(&coordParams); - fprintf(out, "\t%g", pcrdData.value*unit_factor/numValuesInSum); + fprintf(out, "\t%g", pcrdData.value * unit_factor / numValuesInSum); if (pullParams.bPrintRefValue && coordParams.eType != epullEXTERNAL) { - fprintf(out, "\t%g", referenceValue*unit_factor/numValuesInSum); + fprintf(out, "\t%g", referenceValue * unit_factor / numValuesInSum); } if (pullParams.bPrintComp) @@ -200,29 +196,27 @@ static void pull_print_coord_dr(FILE *out, } } -static void pull_print_x(FILE *out, pull_t *pull, double t) +static void pull_print_x(FILE* out, pull_t* pull, double t) { fprintf(out, "%.4f", t); for (size_t c = 0; c < pull->coord.size(); c++) { - const pull_coord_work_t &pcrd = pull->coord[c]; + const pull_coord_work_t& pcrd = pull->coord[c]; int numValuesInSum = 1; - const PullCoordinateHistory *pcrdHistory = nullptr; + const PullCoordinateHistory* pcrdHistory = nullptr; if (pull->bXOutAverage) { pcrdHistory = &pull->coordForceHistory->pullCoordinateSums[c]; numValuesInSum = pull->coordForceHistory->numValuesInXSum; - pull_print_coord_dr(out, pull->params, pcrd.params, - *pcrdHistory, pcrdHistory->valueRef, + pull_print_coord_dr(out, pull->params, pcrd.params, *pcrdHistory, pcrdHistory->valueRef, numValuesInSum); } else { - pull_print_coord_dr(out, pull->params, pcrd.params, - pcrd.spatialData, pcrd.value_ref, + pull_print_coord_dr(out, pull->params, pcrd.params, pcrd.spatialData, pcrd.value_ref, numValuesInSum); } @@ -254,7 +248,9 @@ static void pull_print_x(FILE *out, pull_t *pull, double t) { if (pull->bXOutAverage) { - fprintf(out, "\t%g", pull->coordForceHistory->pullGroupSums[pcrd.params.group[0]].x[m] / numValuesInSum); + fprintf(out, "\t%g", + pull->coordForceHistory->pullGroupSums[pcrd.params.group[0]].x[m] + / numValuesInSum); } else { @@ -271,7 +267,9 @@ static void pull_print_x(FILE *out, pull_t *pull, double t) { if (pull->bXOutAverage) { - fprintf(out, "\t%g", pull->coordForceHistory->pullGroupSums[pcrd.params.group[g]].x[m] / numValuesInSum); + fprintf(out, "\t%g", + pull->coordForceHistory->pullGroupSums[pcrd.params.group[g]].x[m] + / numValuesInSum); } else { @@ -290,7 +288,7 @@ static void pull_print_x(FILE *out, pull_t *pull, double t) } } -static void pull_print_f(FILE *out, const pull_t *pull, double t) +static void pull_print_f(FILE* out, const pull_t* pull, double t) { fprintf(out, "%.4f", t); @@ -298,12 +296,14 @@ static void pull_print_f(FILE *out, const pull_t *pull, double t) { for (size_t c = 0; c < pull->coord.size(); c++) { - fprintf(out, "\t%g", pull->coordForceHistory->pullCoordinateSums[c].scalarForce / pull->coordForceHistory->numValuesInFSum); + fprintf(out, "\t%g", + pull->coordForceHistory->pullCoordinateSums[c].scalarForce + / pull->coordForceHistory->numValuesInFSum); } } else { - for (const pull_coord_work_t &coord : pull->coord) + for (const pull_coord_work_t& coord : pull->coord) { fprintf(out, "\t%g", coord.scalarForce); } @@ -316,9 +316,10 @@ static void pull_print_f(FILE *out, const pull_t *pull, double t) } } -void pull_print_output(struct pull_t *pull, int64_t step, double time) +void pull_print_output(struct pull_t* pull, int64_t step, double time) { - GMX_ASSERT(pull->numExternalPotentialsStillToBeAppliedThisStep == 0, "pull_print_output called before all external pull potentials have been applied"); + GMX_ASSERT(pull->numExternalPotentialsStillToBeAppliedThisStep == 0, + "pull_print_output called before all external pull potentials have been applied"); if (pull->params.nstxout != 0) { @@ -326,7 +327,8 @@ void pull_print_output(struct pull_t *pull, int64_t step, double time) * higher than) what should be in each average output. This can happen when * appending to a file from a checkpoint, which would otherwise include the * last value twice.*/ - if (pull->bXOutAverage && !pull->coord.empty() && pull->coordForceHistory->numValuesInXSum < pull->params.nstxout) + if (pull->bXOutAverage && !pull->coord.empty() + && pull->coordForceHistory->numValuesInXSum < pull->params.nstxout) { addToPullxHistory(pull); } @@ -342,7 +344,8 @@ void pull_print_output(struct pull_t *pull, int64_t step, double time) * higher than) what should be in each average output. This can happen when * appending to a file from a checkpoint, which would otherwise include the * last value twice.*/ - if (pull->bFOutAverage && !pull->coord.empty() && pull->coordForceHistory->numValuesInFSum < pull->params.nstfout) + if (pull->bFOutAverage && !pull->coord.empty() + && pull->coordForceHistory->numValuesInFSum < pull->params.nstfout) { addToPullfHistory(pull); } @@ -353,13 +356,16 @@ void pull_print_output(struct pull_t *pull, int64_t step, double time) } } -static void set_legend_for_coord_components(const pull_coord_work_t *pcrd, int coord_index, char **setname, int *nsets_ptr) +static void set_legend_for_coord_components(const pull_coord_work_t* pcrd, + int coord_index, + char** setname, + int* nsets_ptr) { /* Loop over the distance vectors and print their components. Each vector is made up of two consecutive groups. */ for (int g = 0; g < pcrd->params.ngroup; g += 2) { /* Loop over the components */ - for (int m = 0; m < DIM; m++) + for (int m = 0; m < DIM; m++) { if (pcrd->params.dim[m]) { @@ -367,8 +373,8 @@ static void set_legend_for_coord_components(const pull_coord_work_t *pcrd, int c if (g == 0 && pcrd->params.ngroup <= 2) { - /* For the simplest case we print a simplified legend without group indices, just the cooordinate index - and which dimensional component it is. */ + /* For the simplest case we print a simplified legend without group indices, + just the cooordinate index and which dimensional component it is. */ sprintf(legend, "%d d%c", coord_index + 1, 'X' + m); } else @@ -384,12 +390,13 @@ static void set_legend_for_coord_components(const pull_coord_work_t *pcrd, int c } } -static FILE *open_pull_out(const char *fn, struct pull_t *pull, - const gmx_output_env_t *oenv, - gmx_bool bCoord, - const bool restartWithAppending) +static FILE* open_pull_out(const char* fn, + struct pull_t* pull, + const gmx_output_env_t* oenv, + gmx_bool bCoord, + const bool restartWithAppending) { - FILE *fp; + FILE* fp; int nsets, m; char **setname, buf[50]; @@ -405,13 +412,11 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, sprintf(buf, "Position (nm%s)", pull->bAngle ? ", deg" : ""); if (pull->bXOutAverage) { - xvgr_header(fp, "Pull Average COM", "Time (ps)", buf, - exvggtXNY, oenv); + xvgr_header(fp, "Pull Average COM", "Time (ps)", buf, exvggtXNY, oenv); } else { - xvgr_header(fp, "Pull COM", "Time (ps)", buf, - exvggtXNY, oenv); + xvgr_header(fp, "Pull COM", "Time (ps)", buf, exvggtXNY, oenv); } } else @@ -419,13 +424,11 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, sprintf(buf, "Force (kJ/mol/nm%s)", pull->bAngle ? ", kJ/mol/rad" : ""); if (pull->bFOutAverage) { - xvgr_header(fp, "Pull Average force", "Time (ps)", buf, - exvggtXNY, oenv); + xvgr_header(fp, "Pull Average force", "Time (ps)", buf, exvggtXNY, oenv); } else { - xvgr_header(fp, "Pull force", "Time (ps)", buf, - exvggtXNY, oenv); + xvgr_header(fp, "Pull force", "Time (ps)", buf, exvggtXNY, oenv); } } @@ -434,7 +437,8 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, * the group COMs for all the groups (+ ngroups_max*DIM) * and the components of the distance vectors can be printed (+ (ngroups_max/2)*DIM). */ - snew(setname, pull->coord.size()*(1 + 1 + c_pullCoordNgroupMax*DIM + c_pullCoordNgroupMax/2*DIM)); + snew(setname, pull->coord.size() + * (1 + 1 + c_pullCoordNgroupMax * DIM + c_pullCoordNgroupMax / 2 * DIM)); nsets = 0; for (size_t c = 0; c < pull->coord.size(); c++) @@ -446,13 +450,12 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, */ /* The pull coord distance */ - sprintf(buf, "%zu", c+1); + sprintf(buf, "%zu", c + 1); setname[nsets] = gmx_strdup(buf); nsets++; - if (pull->params.bPrintRefValue && - pull->coord[c].params.eType != epullEXTERNAL) + if (pull->params.bPrintRefValue && pull->coord[c].params.eType != epullEXTERNAL) { - sprintf(buf, "%zu ref", c+1); + sprintf(buf, "%zu ref", c + 1); setname[nsets] = gmx_strdup(buf); nsets++; } @@ -470,7 +473,7 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, { if (pull->coord[c].params.dim[m]) { - sprintf(buf, "%zu g %d %c", c+1, g + 1, 'X'+m); + sprintf(buf, "%zu g %d %c", c + 1, g + 1, 'X' + m); setname[nsets] = gmx_strdup(buf); nsets++; } @@ -481,7 +484,7 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, else { /* For the pull force we always only use one scalar */ - sprintf(buf, "%zu", c+1); + sprintf(buf, "%zu", c + 1); setname[nsets] = gmx_strdup(buf); nsets++; } @@ -500,10 +503,10 @@ static FILE *open_pull_out(const char *fn, struct pull_t *pull, return fp; } -void init_pull_output_files(pull_t *pull, +void init_pull_output_files(pull_t* pull, int nfile, const t_filenm fnm[], - const gmx_output_env_t *oenv, + const gmx_output_env_t* oenv, const gmx::StartingBehavior startingBehavior) { /* Check for px and pf filename collision, if we are writing @@ -512,52 +515,44 @@ void init_pull_output_files(pull_t *pull, std::string px_appended, pf_appended; try { - px_filename = std::string(opt2fn("-px", nfile, fnm)); - pf_filename = std::string(opt2fn("-pf", nfile, fnm)); + px_filename = std::string(opt2fn("-px", nfile, fnm)); + pf_filename = std::string(opt2fn("-pf", nfile, fnm)); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR bool restartWithAppending = startingBehavior == gmx::StartingBehavior::RestartWithAppending; - if ((pull->params.nstxout != 0) && - (pull->params.nstfout != 0) && - (px_filename == pf_filename)) + if ((pull->params.nstxout != 0) && (pull->params.nstfout != 0) && (px_filename == pf_filename)) { if (!opt2bSet("-px", nfile, fnm) && !opt2bSet("-pf", nfile, fnm)) { /* We are writing both pull files but neither set directly. */ try { - px_appended = append_before_extension(px_filename, "_pullx"); - pf_appended = append_before_extension(pf_filename, "_pullf"); + px_appended = append_before_extension(px_filename, "_pullx"); + pf_appended = append_before_extension(pf_filename, "_pullf"); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; - pull->out_x = open_pull_out(px_appended.c_str(), pull, oenv, - TRUE, restartWithAppending); - pull->out_f = open_pull_out(pf_appended.c_str(), pull, oenv, - FALSE, restartWithAppending); + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR + pull->out_x = open_pull_out(px_appended.c_str(), pull, oenv, TRUE, restartWithAppending); + pull->out_f = open_pull_out(pf_appended.c_str(), pull, oenv, FALSE, restartWithAppending); return; } else { /* If at least one of -px and -pf is set but the filenames are identical: */ - gmx_fatal(FARGS, "Identical pull_x and pull_f output filenames %s", - px_filename.c_str()); + gmx_fatal(FARGS, "Identical pull_x and pull_f output filenames %s", px_filename.c_str()); } } if (pull->params.nstxout != 0) { - pull->out_x = open_pull_out(opt2fn("-px", nfile, fnm), pull, oenv, - TRUE, restartWithAppending); + pull->out_x = open_pull_out(opt2fn("-px", nfile, fnm), pull, oenv, TRUE, restartWithAppending); } if (pull->params.nstfout != 0) { - pull->out_f = open_pull_out(opt2fn("-pf", nfile, fnm), pull, oenv, - FALSE, restartWithAppending); + pull->out_f = open_pull_out(opt2fn("-pf", nfile, fnm), pull, oenv, FALSE, restartWithAppending); } } -void initPullHistory(pull_t *pull, - ObservablesHistory *observablesHistory) +void initPullHistory(pull_t* pull, ObservablesHistory* observablesHistory) { GMX_RELEASE_ASSERT(pull, "Need a valid pull object"); @@ -569,15 +564,15 @@ void initPullHistory(pull_t *pull, /* If pull->coordForceHistory is already set we are starting from a checkpoint. Do not reset it. */ if (observablesHistory->pullHistory == nullptr) { - observablesHistory->pullHistory = std::make_unique(); - pull->coordForceHistory = observablesHistory->pullHistory.get(); - pull->coordForceHistory->numValuesInXSum = 0; - pull->coordForceHistory->numValuesInFSum = 0; + observablesHistory->pullHistory = std::make_unique(); + pull->coordForceHistory = observablesHistory->pullHistory.get(); + pull->coordForceHistory->numValuesInXSum = 0; + pull->coordForceHistory->numValuesInFSum = 0; pull->coordForceHistory->pullCoordinateSums.resize(pull->coord.size()); pull->coordForceHistory->pullGroupSums.resize(pull->group.size()); } else { - pull->coordForceHistory = observablesHistory->pullHistory.get(); + pull->coordForceHistory = observablesHistory->pullHistory.get(); } } diff --git a/src/gromacs/pulling/output.h b/src/gromacs/pulling/output.h index 08bb4b999c..db4517bdef 100644 --- a/src/gromacs/pulling/output.h +++ b/src/gromacs/pulling/output.h @@ -71,10 +71,10 @@ enum class StartingBehavior; * \param oenv Output options. * \param startingBehavior Describes whether this is a restart appending to output files */ -void init_pull_output_files(pull_t *pull, +void init_pull_output_files(pull_t* pull, int nfile, const t_filenm fnm[], - const gmx_output_env_t *oenv, + const gmx_output_env_t* oenv, gmx::StartingBehavior startingBehavior); /*! \brief Print the pull output (x and/or f) @@ -83,13 +83,13 @@ void init_pull_output_files(pull_t *pull, * \param step Time step number. * \param time Time. */ -void pull_print_output(pull_t *pull, int64_t step, double time); +void pull_print_output(pull_t* pull, int64_t step, double time); /*! \brief Allocate and initialize pull work history (for average pull output) and set it in a pull work struct * * \param pull The pull work struct * \param observablesHistory Container of history data, e.g., pull history. */ -void initPullHistory(pull_t *pull, ObservablesHistory *observablesHistory); +void initPullHistory(pull_t* pull, ObservablesHistory* observablesHistory); #endif diff --git a/src/gromacs/pulling/pull.cpp b/src/gromacs/pulling/pull.cpp index c8a9855743..4e159aa760 100644 --- a/src/gromacs/pulling/pull.cpp +++ b/src/gromacs/pulling/pull.cpp @@ -86,7 +86,7 @@ namespace gmx extern template LocalAtomSet LocalAtomSetManager::add(ArrayRef globalAtomIndex); } // namespace gmx -static int groupPbcFromParams(const t_pull_group ¶ms, bool setPbcRefToPrevStepCOM) +static int groupPbcFromParams(const t_pull_group& params, bool setPbcRefToPrevStepCOM) { if (params.nat <= 1) { @@ -115,7 +115,7 @@ static int groupPbcFromParams(const t_pull_group ¶ms, bool setPbcRefToPrevSt * should not end before that of this object. * This will be fixed when the pointers are replacted by std::vector. */ -pull_group_work_t::pull_group_work_t(const t_pull_group ¶ms, +pull_group_work_t::pull_group_work_t(const t_pull_group& params, gmx::LocalAtomSet atomSet, bool bSetPbcRefToPrevStepCOM) : params(params), @@ -130,27 +130,23 @@ pull_group_work_t::pull_group_work_t(const t_pull_group ¶ms, clear_dvec(xp); }; -bool pull_coordinate_is_angletype(const t_pull_coord *pcrd) +bool pull_coordinate_is_angletype(const t_pull_coord* pcrd) { - return (pcrd->eGeom == epullgANGLE || - pcrd->eGeom == epullgDIHEDRAL || - pcrd->eGeom == epullgANGLEAXIS); + return (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgDIHEDRAL || pcrd->eGeom == epullgANGLEAXIS); } -static bool pull_coordinate_is_directional(const t_pull_coord *pcrd) +static bool pull_coordinate_is_directional(const t_pull_coord* pcrd) { - return (pcrd->eGeom == epullgDIR || - pcrd->eGeom == epullgDIRPBC || - pcrd->eGeom == epullgDIRRELATIVE || - pcrd->eGeom == epullgCYL); + return (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgDIRPBC + || pcrd->eGeom == epullgDIRRELATIVE || pcrd->eGeom == epullgCYL); } -const char *pull_coordinate_units(const t_pull_coord *pcrd) +const char* pull_coordinate_units(const t_pull_coord* pcrd) { - return pull_coordinate_is_angletype(pcrd) ? "deg" : "nm"; + return pull_coordinate_is_angletype(pcrd) ? "deg" : "nm"; } -double pull_conversion_factor_userinput2internal(const t_pull_coord *pcrd) +double pull_conversion_factor_userinput2internal(const t_pull_coord* pcrd) { if (pull_coordinate_is_angletype(pcrd)) { @@ -162,7 +158,7 @@ double pull_conversion_factor_userinput2internal(const t_pull_coord *pcrd) } } -double pull_conversion_factor_internal2userinput(const t_pull_coord *pcrd) +double pull_conversion_factor_internal2userinput(const t_pull_coord* pcrd) { if (pull_coordinate_is_angletype(pcrd)) { @@ -175,14 +171,17 @@ double pull_conversion_factor_internal2userinput(const t_pull_coord *pcrd) } /* Apply forces in a mass weighted fashion for part of the pull group */ -static void apply_forces_grp_part(const pull_group_work_t *pgrp, - int ind_start, int ind_end, - const t_mdatoms *md, - const dvec f_pull, int sign, rvec *f) +static void apply_forces_grp_part(const pull_group_work_t* pgrp, + int ind_start, + int ind_end, + const t_mdatoms* md, + const dvec f_pull, + int sign, + rvec* f) { double inv_wm = pgrp->mwscale; - auto localAtomIndices = pgrp->atomSet.localIndex(); + auto localAtomIndices = pgrp->atomSet.localIndex(); for (int i = ind_start; i < ind_end; i++) { int ii = localAtomIndices[i]; @@ -200,10 +199,12 @@ static void apply_forces_grp_part(const pull_group_work_t *pgrp, } /* Apply forces in a mass weighted fashion */ -static void apply_forces_grp(const pull_group_work_t *pgrp, - const t_mdatoms *md, - const dvec f_pull, int sign, rvec *f, - int nthreads) +static void apply_forces_grp(const pull_group_work_t* pgrp, + const t_mdatoms* md, + const dvec f_pull, + int sign, + rvec* f, + int nthreads) { auto localAtomIndices = pgrp->atomSet.localIndex(); @@ -215,7 +216,7 @@ static void apply_forces_grp(const pull_group_work_t *pgrp, */ for (int d = 0; d < DIM; d++) { - f[localAtomIndices[0]][d] += sign*f_pull[d]; + f[localAtomIndices[0]][d] += sign * f_pull[d]; } } else @@ -229,26 +230,27 @@ static void apply_forces_grp(const pull_group_work_t *pgrp, #pragma omp parallel for num_threads(nthreads) schedule(static) for (int th = 0; th < nthreads; th++) { - int ind_start = (localAtomIndices.size()*(th + 0))/nthreads; - int ind_end = (localAtomIndices.size()*(th + 1))/nthreads; - apply_forces_grp_part(pgrp, ind_start, ind_end, - md, f_pull, sign, f); + int ind_start = (localAtomIndices.size() * (th + 0)) / nthreads; + int ind_end = (localAtomIndices.size() * (th + 1)) / nthreads; + apply_forces_grp_part(pgrp, ind_start, ind_end, md, f_pull, sign, f); } } } } /* Apply forces in a mass weighted fashion to a cylinder group */ -static void apply_forces_cyl_grp(const pull_group_work_t *pgrp, - const double dv_corr, - const t_mdatoms *md, - const dvec f_pull, double f_scal, - int sign, rvec *f, +static void apply_forces_cyl_grp(const pull_group_work_t* pgrp, + const double dv_corr, + const t_mdatoms* md, + const dvec f_pull, + double f_scal, + int sign, + rvec* f, int gmx_unused nthreads) { double inv_wm = pgrp->mwscale; - auto localAtomIndices = pgrp->atomSet.localIndex(); + auto localAtomIndices = pgrp->atomSet.localIndex(); /* The cylinder group is always a slab in the system, thus large. * Therefore we always thread-parallelize this group. @@ -262,8 +264,8 @@ static void apply_forces_cyl_grp(const pull_group_work_t *pgrp, { continue; } - int ii = localAtomIndices[i]; - double mass = md->massT[ii]; + int ii = localAtomIndices[i]; + double mass = md->massT[ii]; /* The stored axial distance from the cylinder center (dv) needs * to be corrected for an offset (dv_corr), which was unknown when * we calculated dv. @@ -276,8 +278,7 @@ static void apply_forces_cyl_grp(const pull_group_work_t *pgrp, */ for (int m = 0; m < DIM; m++) { - f[ii][m] += sign*inv_wm*(mass*weight*f_pull[m] + - pgrp->mdw[i][m]*dv_com*f_scal); + f[ii][m] += sign * inv_wm * (mass * weight * f_pull[m] + pgrp->mdw[i][m] * dv_com * f_scal); } } } @@ -285,12 +286,12 @@ static void apply_forces_cyl_grp(const pull_group_work_t *pgrp, /* Apply torque forces in a mass weighted fashion to the groups that define * the pull vector direction for pull coordinate pcrd. */ -static void apply_forces_vec_torque(const struct pull_t *pull, - const pull_coord_work_t *pcrd, - const t_mdatoms *md, - rvec *f) +static void apply_forces_vec_torque(const struct pull_t* pull, + const pull_coord_work_t* pcrd, + const t_mdatoms* md, + rvec* f) { - const PullCoordSpatialData &spatialData = pcrd->spatialData; + const PullCoordSpatialData& spatialData = pcrd->spatialData; /* The component inpr along the pull vector is accounted for in the usual * way. Here we account for the component perpendicular to vec. @@ -298,7 +299,7 @@ static void apply_forces_vec_torque(const struct pull_t *pull, double inpr = 0; for (int m = 0; m < DIM; m++) { - inpr += spatialData.dr01[m]*spatialData.vec[m]; + inpr += spatialData.dr01[m] * spatialData.vec[m]; } /* The torque force works along the component of the distance vector * of between the two "usual" pull groups that is perpendicular to @@ -309,21 +310,20 @@ static void apply_forces_vec_torque(const struct pull_t *pull, dvec f_perp; for (int m = 0; m < DIM; m++) { - f_perp[m] = (spatialData.dr01[m] - inpr*spatialData.vec[m])/spatialData.vec_len*pcrd->scalarForce; + f_perp[m] = (spatialData.dr01[m] - inpr * spatialData.vec[m]) / spatialData.vec_len * pcrd->scalarForce; } /* Apply the force to the groups defining the vector using opposite signs */ - apply_forces_grp(&pull->group[pcrd->params.group[2]], md, - f_perp, -1, f, pull->nthreads); - apply_forces_grp(&pull->group[pcrd->params.group[3]], md, - f_perp, 1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd->params.group[2]], md, f_perp, -1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd->params.group[3]], md, f_perp, 1, f, pull->nthreads); } /* Apply forces in a mass weighted fashion */ -static void apply_forces_coord(struct pull_t * pull, int coord, - const PullCoordVectorForces &forces, - const t_mdatoms * md, - rvec *f) +static void apply_forces_coord(struct pull_t* pull, + int coord, + const PullCoordVectorForces& forces, + const t_mdatoms* md, + rvec* f) { /* Here it would be more efficient to use one large thread-parallel * region instead of potential parallel regions within apply_forces_grp. @@ -331,22 +331,20 @@ static void apply_forces_coord(struct pull_t * pull, int coord, * to data races. */ - const pull_coord_work_t &pcrd = pull->coord[coord]; + const pull_coord_work_t& pcrd = pull->coord[coord]; if (pcrd.params.eGeom == epullgCYL) { - apply_forces_cyl_grp(&pull->dyna[coord], pcrd.spatialData.cyl_dev, md, - forces.force01, pcrd.scalarForce, -1, f, - pull->nthreads); + apply_forces_cyl_grp(&pull->dyna[coord], pcrd.spatialData.cyl_dev, md, forces.force01, + pcrd.scalarForce, -1, f, pull->nthreads); /* Sum the force along the vector and the radial force */ dvec f_tot; for (int m = 0; m < DIM; m++) { - f_tot[m] = forces.force01[m] + pcrd.scalarForce*pcrd.spatialData.ffrad[m]; + f_tot[m] = forces.force01[m] + pcrd.scalarForce * pcrd.spatialData.ffrad[m]; } - apply_forces_grp(&pull->group[pcrd.params.group[1]], md, - f_tot, 1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[1]], md, f_tot, 1, f, pull->nthreads); } else { @@ -360,31 +358,24 @@ static void apply_forces_coord(struct pull_t * pull, int coord, if (pull->group[pcrd.params.group[0]].params.nat > 0) { - apply_forces_grp(&pull->group[pcrd.params.group[0]], md, - forces.force01, -1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[0]], md, forces.force01, -1, f, pull->nthreads); } - apply_forces_grp(&pull->group[pcrd.params.group[1]], md, - forces.force01, 1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[1]], md, forces.force01, 1, f, pull->nthreads); if (pcrd.params.ngroup >= 4) { - apply_forces_grp(&pull->group[pcrd.params.group[2]], md, - forces.force23, -1, f, pull->nthreads); - apply_forces_grp(&pull->group[pcrd.params.group[3]], md, - forces.force23, 1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[2]], md, forces.force23, -1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[3]], md, forces.force23, 1, f, pull->nthreads); } if (pcrd.params.ngroup >= 6) { - apply_forces_grp(&pull->group[pcrd.params.group[4]], md, - forces.force45, -1, f, pull->nthreads); - apply_forces_grp(&pull->group[pcrd.params.group[5]], md, - forces.force45, 1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[4]], md, forces.force45, -1, f, pull->nthreads); + apply_forces_grp(&pull->group[pcrd.params.group[5]], md, forces.force45, 1, f, pull->nthreads); } } } -real max_pull_distance2(const pull_coord_work_t *pcrd, - const t_pbc *pbc) +real max_pull_distance2(const pull_coord_work_t* pcrd, const t_pbc* pbc) { /* Note that this maximum distance calculation is more complex than * most other cases in GROMACS, since here we have to take care of @@ -444,19 +435,21 @@ real max_pull_distance2(const pull_coord_work_t *pcrd, } } - return 0.25*max_d2; + return 0.25 * max_d2; } /* This function returns the distance based on coordinates xg and xref. * Note that the pull coordinate struct pcrd is not modified. */ -static void low_get_pull_coord_dr(const struct pull_t *pull, - const pull_coord_work_t *pcrd, - const t_pbc *pbc, - dvec xg, dvec xref, double max_dist2, - dvec dr) +static void low_get_pull_coord_dr(const struct pull_t* pull, + const pull_coord_work_t* pcrd, + const t_pbc* pbc, + dvec xg, + dvec xref, + double max_dist2, + dvec dr) { - const pull_group_work_t *pgrp0 = &pull->group[pcrd->params.group[0]]; + const pull_group_work_t* pgrp0 = &pull->group[pcrd->params.group[0]]; /* Only the first group can be an absolute reference, in that case nat=0 */ if (pgrp0->params.nat == 0) @@ -470,12 +463,12 @@ static void low_get_pull_coord_dr(const struct pull_t *pull, dvec xrefr; copy_dvec(xref, xrefr); - dvec dref = {0, 0, 0}; + dvec dref = { 0, 0, 0 }; if (pcrd->params.eGeom == epullgDIRPBC) { for (int m = 0; m < DIM; m++) { - dref[m] = pcrd->value_ref*pcrd->spatialData.vec[m]; + dref[m] = pcrd->value_ref * pcrd->spatialData.vec[m]; } /* Add the reference position, so we use the correct periodic image */ dvec_inc(xrefr, dref); @@ -490,21 +483,22 @@ static void low_get_pull_coord_dr(const struct pull_t *pull, dr[m] *= pcrd->params.dim[m]; if (pcrd->params.dim[m] && !(directional && pcrd->spatialData.vec[m] == 0)) { - dr2 += dr[m]*dr[m]; + dr2 += dr[m] * dr[m]; } } /* Check if we are close to switching to another periodic image */ - if (max_dist2 > 0 && dr2 > 0.98*0.98*max_dist2) + if (max_dist2 > 0 && dr2 > 0.98 * 0.98 * max_dist2) { /* Note that technically there is no issue with switching periodic * image, as pbc_dx_d returns the distance to the closest periodic * image. However in all cases where periodic image switches occur, * the pull results will be useless in practice. */ - gmx_fatal(FARGS, "Distance between pull groups %d and %d (%f nm) is larger than 0.49 times the box size (%f).\n%s", - pcrd->params.group[0], pcrd->params.group[1], - sqrt(dr2), sqrt(0.98*0.98*max_dist2), - pcrd->params.eGeom == epullgDIR ? "You might want to consider using \"pull-geometry = direction-periodic\" instead.\n" : ""); + gmx_fatal(FARGS, + "Distance between pull groups %d and %d (%f nm) is larger than 0.49 times the " + "box size (%f).\n%s", + pcrd->params.group[0], pcrd->params.group[1], sqrt(dr2), + sqrt(0.98 * 0.98 * max_dist2), pcrd->params.eGeom == epullgDIR ? "You might want to consider using \"pull-geometry = direction-periodic\" instead.\n" : ""); } if (pcrd->params.eGeom == epullgDIRPBC) @@ -516,14 +510,12 @@ static void low_get_pull_coord_dr(const struct pull_t *pull, /* This function returns the distance based on the contents of the pull struct. * pull->coord[coord_ind].dr, and potentially vector, are updated. */ -static void get_pull_coord_dr(struct pull_t *pull, - int coord_ind, - const t_pbc *pbc) +static void get_pull_coord_dr(struct pull_t* pull, int coord_ind, const t_pbc* pbc) { - pull_coord_work_t *pcrd = &pull->coord[coord_ind]; - PullCoordSpatialData &spatialData = pcrd->spatialData; + pull_coord_work_t* pcrd = &pull->coord[coord_ind]; + PullCoordSpatialData& spatialData = pcrd->spatialData; - double md2; + double md2; if (pcrd->params.eGeom == epullgDIRPBC) { md2 = -1; @@ -536,11 +528,11 @@ static void get_pull_coord_dr(struct pull_t *pull, if (pcrd->params.eGeom == epullgDIRRELATIVE) { /* We need to determine the pull vector */ - dvec vec; - int m; + dvec vec; + int m; - const pull_group_work_t &pgrp2 = pull->group[pcrd->params.group[2]]; - const pull_group_work_t &pgrp3 = pull->group[pcrd->params.group[3]]; + const pull_group_work_t& pgrp2 = pull->group[pcrd->params.group[2]]; + const pull_group_work_t& pgrp3 = pull->group[pcrd->params.group[3]]; pbc_dx_d(pbc, pgrp3.x, pgrp2.x, vec); @@ -551,24 +543,21 @@ static void get_pull_coord_dr(struct pull_t *pull, spatialData.vec_len = dnorm(vec); for (m = 0; m < DIM; m++) { - spatialData.vec[m] = vec[m]/spatialData.vec_len; + spatialData.vec[m] = vec[m] / spatialData.vec_len; } if (debug) { fprintf(debug, "pull coord %d vector: %6.3f %6.3f %6.3f normalized: %6.3f %6.3f %6.3f\n", - coord_ind, - vec[XX], vec[YY], vec[ZZ], - spatialData.vec[XX], spatialData.vec[YY], spatialData.vec[ZZ]); + coord_ind, vec[XX], vec[YY], vec[ZZ], spatialData.vec[XX], spatialData.vec[YY], + spatialData.vec[ZZ]); } } - pull_group_work_t *pgrp0 = &pull->group[pcrd->params.group[0]]; - pull_group_work_t *pgrp1 = &pull->group[pcrd->params.group[1]]; + pull_group_work_t* pgrp0 = &pull->group[pcrd->params.group[0]]; + pull_group_work_t* pgrp1 = &pull->group[pcrd->params.group[1]]; - low_get_pull_coord_dr(pull, pcrd, pbc, - pgrp1->x, - pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pgrp0->x, - md2, + low_get_pull_coord_dr(pull, pcrd, pbc, pgrp1->x, + pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pgrp0->x, md2, spatialData.dr01); if (pcrd->params.ngroup >= 4) @@ -577,11 +566,7 @@ static void get_pull_coord_dr(struct pull_t *pull, pgrp2 = &pull->group[pcrd->params.group[2]]; pgrp3 = &pull->group[pcrd->params.group[3]]; - low_get_pull_coord_dr(pull, pcrd, pbc, - pgrp3->x, - pgrp2->x, - md2, - spatialData.dr23); + low_get_pull_coord_dr(pull, pcrd, pbc, pgrp3->x, pgrp2->x, md2, spatialData.dr23); } if (pcrd->params.ngroup >= 6) { @@ -589,11 +574,7 @@ static void get_pull_coord_dr(struct pull_t *pull, pgrp4 = &pull->group[pcrd->params.group[4]]; pgrp5 = &pull->group[pcrd->params.group[5]]; - low_get_pull_coord_dr(pull, pcrd, pbc, - pgrp5->x, - pgrp4->x, - md2, - spatialData.dr45); + low_get_pull_coord_dr(pull, pcrd, pbc, pgrp5->x, pgrp4->x, md2, spatialData.dr45); } } @@ -601,7 +582,7 @@ static void get_pull_coord_dr(struct pull_t *pull, * It is assumed that x is in [-3pi, 3pi) so that x * needs to be shifted by at most one period. */ -static void make_periodic_2pi(double *x) +static void make_periodic_2pi(double* x) { if (*x >= M_PI) { @@ -614,24 +595,29 @@ static void make_periodic_2pi(double *x) } /* This function should always be used to modify pcrd->value_ref */ -static void low_set_pull_coord_reference_value(pull_coord_work_t *pcrd, - int coord_ind, - double value_ref) +static void low_set_pull_coord_reference_value(pull_coord_work_t* pcrd, int coord_ind, double value_ref) { - GMX_ASSERT(pcrd->params.eType != epullEXTERNAL, "The pull coord reference value should not be used with type external-potential"); + GMX_ASSERT(pcrd->params.eType != epullEXTERNAL, + "The pull coord reference value should not be used with type external-potential"); if (pcrd->params.eGeom == epullgDIST) { if (value_ref < 0) { - gmx_fatal(FARGS, "Pull reference distance for coordinate %d (%f) needs to be non-negative", coord_ind + 1, value_ref); + gmx_fatal(FARGS, + "Pull reference distance for coordinate %d (%f) needs to be non-negative", + coord_ind + 1, value_ref); } } else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgANGLEAXIS) { if (value_ref < 0 || value_ref > M_PI) { - gmx_fatal(FARGS, "Pull reference angle for coordinate %d (%f) needs to be in the allowed interval [0,180] deg", coord_ind + 1, value_ref*pull_conversion_factor_internal2userinput(&pcrd->params)); + gmx_fatal(FARGS, + "Pull reference angle for coordinate %d (%f) needs to be in the allowed " + "interval [0,180] deg", + coord_ind + 1, + value_ref * pull_conversion_factor_internal2userinput(&pcrd->params)); } } else if (pcrd->params.eGeom == epullgDIHEDRAL) @@ -643,25 +629,26 @@ static void low_set_pull_coord_reference_value(pull_coord_work_t *pcrd, pcrd->value_ref = value_ref; } -static void update_pull_coord_reference_value(pull_coord_work_t *pcrd, int coord_ind, double t) +static void update_pull_coord_reference_value(pull_coord_work_t* pcrd, int coord_ind, double t) { /* With zero rate the reference value is set initially and doesn't change */ if (pcrd->params.rate != 0) { - double value_ref = (pcrd->params.init + pcrd->params.rate*t)*pull_conversion_factor_userinput2internal(&pcrd->params); + double value_ref = (pcrd->params.init + pcrd->params.rate * t) + * pull_conversion_factor_userinput2internal(&pcrd->params); low_set_pull_coord_reference_value(pcrd, coord_ind, value_ref); } } /* Returns the dihedral angle. Updates the plane normal vectors m, n. */ -static double get_dihedral_angle_coord(PullCoordSpatialData *spatialData) +static double get_dihedral_angle_coord(PullCoordSpatialData* spatialData) { double phi, sign; dvec dr32; /* store instead of dr23? */ dsvmul(-1, spatialData->dr23, dr32); - dcprod(spatialData->dr01, dr32, spatialData->planevec_m); /* Normal of first plane */ - dcprod(dr32, spatialData->dr45, spatialData->planevec_n); /* Normal of second plane */ + dcprod(spatialData->dr01, dr32, spatialData->planevec_m); /* Normal of first plane */ + dcprod(dr32, spatialData->dr45, spatialData->planevec_n); /* Normal of second plane */ phi = gmx_angle_between_dvecs(spatialData->planevec_m, spatialData->planevec_n); /* Note 1: the sign below is opposite of that in the bondeds or Bekker 1994 @@ -671,24 +658,22 @@ static double get_dihedral_angle_coord(PullCoordSpatialData *spatialData) * we get a positive sign below. Thus, the range of the dihedral angle is (-180, 180]. */ sign = (diprod(spatialData->dr01, spatialData->planevec_n) < 0.0) ? 1.0 : -1.0; - return sign*phi; + return sign * phi; } /* Calculates pull->coord[coord_ind].value. * This function also updates pull->coord[coord_ind].dr. */ -static void get_pull_coord_distance(struct pull_t *pull, - int coord_ind, - const t_pbc *pbc) +static void get_pull_coord_distance(struct pull_t* pull, int coord_ind, const t_pbc* pbc) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; int m; pcrd = &pull->coord[coord_ind]; get_pull_coord_dr(pull, coord_ind, pbc); - PullCoordSpatialData &spatialData = pcrd->spatialData; + PullCoordSpatialData& spatialData = pcrd->spatialData; switch (pcrd->params.eGeom) { @@ -704,32 +689,26 @@ static void get_pull_coord_distance(struct pull_t *pull, spatialData.value = 0; for (m = 0; m < DIM; m++) { - spatialData.value += spatialData.vec[m]*spatialData.dr01[m]; + spatialData.value += spatialData.vec[m] * spatialData.dr01[m]; } break; case epullgANGLE: spatialData.value = gmx_angle_between_dvecs(spatialData.dr01, spatialData.dr23); break; - case epullgDIHEDRAL: - spatialData.value = get_dihedral_angle_coord(&spatialData); - break; + case epullgDIHEDRAL: spatialData.value = get_dihedral_angle_coord(&spatialData); break; case epullgANGLEAXIS: spatialData.value = gmx_angle_between_dvecs(spatialData.dr01, spatialData.vec); break; - default: - gmx_incons("Unsupported pull type in get_pull_coord_distance"); + default: gmx_incons("Unsupported pull type in get_pull_coord_distance"); } } /* Returns the deviation from the reference value. * Updates pull->coord[coord_ind].dr, .value and .value_ref. */ -static double get_pull_coord_deviation(struct pull_t *pull, - int coord_ind, - const t_pbc *pbc, - double t) +static double get_pull_coord_deviation(struct pull_t* pull, int coord_ind, const t_pbc* pbc, double t) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; double dev = 0; pcrd = &pull->coord[coord_ind]; @@ -765,47 +744,43 @@ static double get_pull_coord_deviation(struct pull_t *pull, return dev; } -double get_pull_coord_value(struct pull_t *pull, - int coord_ind, - const t_pbc *pbc) +double get_pull_coord_value(struct pull_t* pull, int coord_ind, const t_pbc* pbc) { get_pull_coord_distance(pull, coord_ind, pbc); return pull->coord[coord_ind].spatialData.value; } -void clear_pull_forces(pull_t *pull) +void clear_pull_forces(pull_t* pull) { /* Zeroing the forces is only required for constraint pulling. * It can happen that multiple constraint steps need to be applied * and therefore the constraint forces need to be accumulated. */ - for (pull_coord_work_t &coord : pull->coord) + for (pull_coord_work_t& coord : pull->coord) { coord.scalarForce = 0; } } /* Apply constraint using SHAKE */ -static void do_constraint(struct pull_t *pull, t_pbc *pbc, - rvec *x, rvec *v, - gmx_bool bMaster, tensor vir, - double dt, double t) +static void +do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaster, tensor vir, double dt, double t) { - dvec *r_ij; /* x[i] com of i in prev. step. Obeys constr. -> r_ij[i] */ - dvec unc_ij; /* xp[i] com of i this step, before constr. -> unc_ij */ - dvec *rnew; /* current 'new' positions of the groups */ - double *dr_tot; /* the total update of the coords */ - dvec vec; - double inpr; - double lambda, rm, invdt = 0; - gmx_bool bConverged_all, bConverged = FALSE; - int niter = 0, ii, j, m, max_iter = 100; - double a; - dvec tmp, tmp3; - - snew(r_ij, pull->coord.size()); + dvec* r_ij; /* x[i] com of i in prev. step. Obeys constr. -> r_ij[i] */ + dvec unc_ij; /* xp[i] com of i this step, before constr. -> unc_ij */ + dvec* rnew; /* current 'new' positions of the groups */ + double* dr_tot; /* the total update of the coords */ + dvec vec; + double inpr; + double lambda, rm, invdt = 0; + gmx_bool bConverged_all, bConverged = FALSE; + int niter = 0, ii, j, m, max_iter = 100; + double a; + dvec tmp, tmp3; + + snew(r_ij, pull->coord.size()); snew(dr_tot, pull->coord.size()); snew(rnew, pull->group.size()); @@ -821,7 +796,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, /* Determine the constraint directions from the old positions */ for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; pcrd = &pull->coord[c]; @@ -836,25 +811,24 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, */ get_pull_coord_distance(pull, c, pbc); - const PullCoordSpatialData &spatialData = pcrd->spatialData; + const PullCoordSpatialData& spatialData = pcrd->spatialData; if (debug) { - fprintf(debug, "Pull coord %zu dr %f %f %f\n", - c, spatialData.dr01[XX], spatialData.dr01[YY], spatialData.dr01[ZZ]); + fprintf(debug, "Pull coord %zu dr %f %f %f\n", c, spatialData.dr01[XX], + spatialData.dr01[YY], spatialData.dr01[ZZ]); } - if (pcrd->params.eGeom == epullgDIR || - pcrd->params.eGeom == epullgDIRPBC) + if (pcrd->params.eGeom == epullgDIR || pcrd->params.eGeom == epullgDIRPBC) { /* Select the component along vec */ a = 0; for (m = 0; m < DIM; m++) { - a += spatialData.vec[m]*spatialData.dr01[m]; + a += spatialData.vec[m] * spatialData.dr01[m]; } for (m = 0; m < DIM; m++) { - r_ij[c][m] = a*spatialData.vec[m]; + r_ij[c][m] = a * spatialData.vec[m]; } } else @@ -864,7 +838,10 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, if (dnorm2(r_ij[c]) == 0) { - gmx_fatal(FARGS, "Distance for pull coordinate %zu is zero with constraint pulling, which is not allowed.", c + 1); + gmx_fatal(FARGS, + "Distance for pull coordinate %zu is zero with constraint pulling, which is " + "not allowed.", + c + 1); } } @@ -876,11 +853,11 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, /* loop over all constraints */ for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; pull_group_work_t *pgrp0, *pgrp1; dvec dr0, dr1; - pcrd = &pull->coord[c]; + pcrd = &pull->coord[c]; if (pcrd->params.eType != epullCONSTRAINT) { @@ -893,56 +870,56 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, pgrp1 = &pull->group[pcrd->params.group[1]]; /* Get the current difference vector */ - low_get_pull_coord_dr(pull, pcrd, pbc, - rnew[pcrd->params.group[1]], - rnew[pcrd->params.group[0]], - -1, unc_ij); + low_get_pull_coord_dr(pull, pcrd, pbc, rnew[pcrd->params.group[1]], + rnew[pcrd->params.group[0]], -1, unc_ij); if (debug) { fprintf(debug, "Pull coord %zu, iteration %d\n", c, niter); } - rm = 1.0/(pgrp0->invtm + pgrp1->invtm); + rm = 1.0 / (pgrp0->invtm + pgrp1->invtm); switch (pcrd->params.eGeom) { case epullgDIST: if (pcrd->value_ref <= 0) { - gmx_fatal(FARGS, "The pull constraint reference distance for group %zu is <= 0 (%f)", c, pcrd->value_ref); + gmx_fatal( + FARGS, + "The pull constraint reference distance for group %zu is <= 0 (%f)", + c, pcrd->value_ref); } { double q, c_a, c_b, c_c; c_a = diprod(r_ij[c], r_ij[c]); - c_b = diprod(unc_ij, r_ij[c])*2; + c_b = diprod(unc_ij, r_ij[c]) * 2; c_c = diprod(unc_ij, unc_ij) - gmx::square(pcrd->value_ref); if (c_b < 0) { - q = -0.5*(c_b - std::sqrt(c_b*c_b - 4*c_a*c_c)); - lambda = -q/c_a; + q = -0.5 * (c_b - std::sqrt(c_b * c_b - 4 * c_a * c_c)); + lambda = -q / c_a; } else { - q = -0.5*(c_b + std::sqrt(c_b*c_b - 4*c_a*c_c)); - lambda = -c_c/q; + q = -0.5 * (c_b + std::sqrt(c_b * c_b - 4 * c_a * c_c)); + lambda = -c_c / q; } if (debug) { - fprintf(debug, - "Pull ax^2+bx+c=0: a=%e b=%e c=%e lambda=%e\n", - c_a, c_b, c_c, lambda); + fprintf(debug, "Pull ax^2+bx+c=0: a=%e b=%e c=%e lambda=%e\n", c_a, c_b, + c_c, lambda); } } /* The position corrections dr due to the constraints */ - dsvmul(-lambda*rm*pgrp1->invtm, r_ij[c], dr1); - dsvmul( lambda*rm*pgrp0->invtm, r_ij[c], dr0); - dr_tot[c] += -lambda*dnorm(r_ij[c]); + dsvmul(-lambda * rm * pgrp1->invtm, r_ij[c], dr1); + dsvmul(lambda * rm * pgrp0->invtm, r_ij[c], dr0); + dr_tot[c] += -lambda * dnorm(r_ij[c]); break; case epullgDIR: case epullgDIRPBC: @@ -952,7 +929,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, for (m = 0; m < DIM; m++) { vec[m] = pcrd->spatialData.vec[m]; - a += unc_ij[m]*vec[m]; + a += unc_ij[m] * vec[m]; } /* Select only the component along the vector */ dsvmul(a, vec, unc_ij); @@ -963,12 +940,11 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, } /* The position corrections dr due to the constraints */ - dsvmul(-lambda*rm*pgrp1->invtm, vec, dr1); - dsvmul( lambda*rm*pgrp0->invtm, vec, dr0); + dsvmul(-lambda * rm * pgrp1->invtm, vec, dr1); + dsvmul(lambda * rm * pgrp0->invtm, vec, dr0); dr_tot[c] += -lambda; break; - default: - gmx_incons("Invalid enumeration value for eGeom"); + default: gmx_incons("Invalid enumeration value for eGeom"); } /* DEBUG */ @@ -980,18 +956,12 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, g1 = pcrd->params.group[1]; low_get_pull_coord_dr(pull, pcrd, pbc, rnew[g1], rnew[g0], -1, tmp); low_get_pull_coord_dr(pull, pcrd, pbc, dr1, dr0, -1, tmp3); - fprintf(debug, - "Pull cur %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", - rnew[g0][0], rnew[g0][1], rnew[g0][2], - rnew[g1][0], rnew[g1][1], rnew[g1][2], dnorm(tmp)); - fprintf(debug, - "Pull ref %8s %8s %8s %8s %8s %8s d: %8.5f\n", - "", "", "", "", "", "", pcrd->value_ref); - fprintf(debug, - "Pull cor %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", - dr0[0], dr0[1], dr0[2], - dr1[0], dr1[1], dr1[2], - dnorm(tmp3)); + fprintf(debug, "Pull cur %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", rnew[g0][0], + rnew[g0][1], rnew[g0][2], rnew[g1][0], rnew[g1][1], rnew[g1][2], dnorm(tmp)); + fprintf(debug, "Pull ref %8s %8s %8s %8s %8s %8s d: %8.5f\n", "", "", "", "", "", + "", pcrd->value_ref); + fprintf(debug, "Pull cor %8.5f %8.5f %8.5f j:%8.5f %8.5f %8.5f d: %8.5f\n", dr0[0], + dr0[1], dr0[2], dr1[0], dr1[1], dr1[2], dnorm(tmp3)); } /* END DEBUG */ /* Update the COMs with dr */ @@ -1000,23 +970,20 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, } /* Check if all constraints are fullfilled now */ - for (pull_coord_work_t &coord : pull->coord) + for (pull_coord_work_t& coord : pull->coord) { if (coord.params.eType != epullCONSTRAINT) { continue; } - low_get_pull_coord_dr(pull, &coord, pbc, - rnew[coord.params.group[1]], - rnew[coord.params.group[0]], - -1, unc_ij); + low_get_pull_coord_dr(pull, &coord, pbc, rnew[coord.params.group[1]], + rnew[coord.params.group[0]], -1, unc_ij); switch (coord.params.eGeom) { case epullgDIST: - bConverged = - fabs(dnorm(unc_ij) - coord.value_ref) < pull->params.constr_tol; + bConverged = fabs(dnorm(unc_ij) - coord.value_ref) < pull->params.constr_tol; break; case epullgDIR: case epullgDIRPBC: @@ -1027,8 +994,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, } inpr = diprod(unc_ij, vec); dsvmul(inpr, vec, unc_ij); - bConverged = - fabs(diprod(unc_ij, vec) - coord.value_ref) < pull->params.constr_tol; + bConverged = fabs(diprod(unc_ij, vec) - coord.value_ref) < pull->params.constr_tol; break; } @@ -1036,11 +1002,11 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, { if (debug) { - fprintf(debug, "Pull constraint not converged: " + fprintf(debug, + "Pull constraint not converged: " "groups %d %d," "d_ref = %f, current d = %f\n", - coord.params.group[0], coord.params.group[1], - coord.value_ref, dnorm(unc_ij)); + coord.params.group[0], coord.params.group[1], coord.value_ref, dnorm(unc_ij)); } bConverged_all = FALSE; @@ -1060,13 +1026,13 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, if (v) { - invdt = 1/dt; + invdt = 1 / dt; } /* update atoms in the groups */ for (size_t g = 0; g < pull->group.size(); g++) { - const pull_group_work_t *pgrp; + const pull_group_work_t* pgrp; dvec dr; pgrp = &pull->group[g]; @@ -1088,7 +1054,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, ii = localAtomIndices[j]; if (!pgrp->localWeights.empty()) { - dsvmul(pgrp->wscale*pgrp->localWeights[j], dr, tmp); + dsvmul(pgrp->wscale * pgrp->localWeights[j], dr, tmp); } for (m = 0; m < DIM; m++) { @@ -1098,7 +1064,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, { for (m = 0; m < DIM; m++) { - v[ii][m] += invdt*tmp[m]; + v[ii][m] += invdt * tmp[m]; } } } @@ -1107,7 +1073,7 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, /* calculate the constraint forces, used for output and virial only */ for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; pcrd = &pull->coord[c]; @@ -1117,7 +1083,10 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, } /* Accumulate the forces, in case we have multiple constraint steps */ - double force = dr_tot[c]/((pull->group[pcrd->params.group[0]].invtm + pull->group[pcrd->params.group[1]].invtm)*dt*dt); + double force = + dr_tot[c] + / ((pull->group[pcrd->params.group[0]].invtm + pull->group[pcrd->params.group[1]].invtm) + * dt * dt); pcrd->scalarForce += force; if (vir != nullptr && pcrd->params.eGeom != epullgDIRPBC && bMaster) @@ -1126,13 +1095,13 @@ static void do_constraint(struct pull_t *pull, t_pbc *pbc, /* Add the pull contribution to the virial */ /* We have already checked above that r_ij[c] != 0 */ - f_invr = pcrd->scalarForce/dnorm(r_ij[c]); + f_invr = pcrd->scalarForce / dnorm(r_ij[c]); for (j = 0; j < DIM; j++) { for (m = 0; m < DIM; m++) { - vir[j][m] -= 0.5*f_invr*r_ij[c][j]*r_ij[c][m]; + vir[j][m] -= 0.5 * f_invr * r_ij[c][j] * r_ij[c][m]; } } } @@ -1150,15 +1119,13 @@ static void add_virial_coord_dr(tensor vir, const dvec dr, const dvec f) { for (int m = 0; m < DIM; m++) { - vir[j][m] -= 0.5*f[j]*dr[m]; + vir[j][m] -= 0.5 * f[j] * dr[m]; } } } /* Adds the pull contribution to the virial */ -static void add_virial_coord(tensor vir, - const pull_coord_work_t &pcrd, - const PullCoordVectorForces &forces) +static void add_virial_coord(tensor vir, const pull_coord_work_t& pcrd, const PullCoordVectorForces& forces) { if (vir != nullptr && pcrd.params.eGeom != epullgDIRPBC) { @@ -1175,13 +1142,15 @@ static void add_virial_coord(tensor vir, } } -static void calc_pull_coord_scalar_force_and_potential(pull_coord_work_t *pcrd, - double dev, real lambda, - real *V, real *dVdl) +static void calc_pull_coord_scalar_force_and_potential(pull_coord_work_t* pcrd, + double dev, + real lambda, + real* V, + real* dVdl) { - real k, dkdl; + real k, dkdl; - k = (1.0 - lambda)*pcrd->params.k + lambda*pcrd->params.kB; + k = (1.0 - lambda) * pcrd->params.k + lambda * pcrd->params.kB; dkdl = pcrd->params.kB - pcrd->params.k; switch (pcrd->params.eType) @@ -1193,43 +1162,43 @@ static void calc_pull_coord_scalar_force_and_potential(pull_coord_work_t *pcrd, * potential is that a flat-bottom is zero above or below the reference value. */ - if ((pcrd->params.eType == epullFLATBOTTOM && dev < 0) || - (pcrd->params.eType == epullFLATBOTTOMHIGH && dev > 0)) + if ((pcrd->params.eType == epullFLATBOTTOM && dev < 0) + || (pcrd->params.eType == epullFLATBOTTOMHIGH && dev > 0)) { dev = 0; } - pcrd->scalarForce = -k*dev; - *V += 0.5* k*gmx::square(dev); - *dVdl += 0.5*dkdl*gmx::square(dev); + pcrd->scalarForce = -k * dev; + *V += 0.5 * k * gmx::square(dev); + *dVdl += 0.5 * dkdl * gmx::square(dev); break; case epullCONST_F: - pcrd->scalarForce = -k; - *V += k*pcrd->spatialData.value; - *dVdl += dkdl*pcrd->spatialData.value; + pcrd->scalarForce = -k; + *V += k * pcrd->spatialData.value; + *dVdl += dkdl * pcrd->spatialData.value; break; case epullEXTERNAL: - gmx_incons("the scalar pull force should not be calculated internally for pull type external"); - default: - gmx_incons("Unsupported pull type in do_pull_pot"); + gmx_incons( + "the scalar pull force should not be calculated internally for pull type " + "external"); + default: gmx_incons("Unsupported pull type in do_pull_pot"); } } -static PullCoordVectorForces -calculateVectorForces(const pull_coord_work_t &pcrd) +static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd) { - const t_pull_coord ¶ms = pcrd.params; - const PullCoordSpatialData &spatialData = pcrd.spatialData; + const t_pull_coord& params = pcrd.params; + const PullCoordSpatialData& spatialData = pcrd.spatialData; /* The geometry of the coordinate determines how the scalar force relates to the force on each group */ - PullCoordVectorForces forces; + PullCoordVectorForces forces; if (params.eGeom == epullgDIST) { - double invdr01 = spatialData.value > 0 ? 1./spatialData.value : 0.; + double invdr01 = spatialData.value > 0 ? 1. / spatialData.value : 0.; for (int m = 0; m < DIM; m++) { - forces.force01[m] = pcrd.scalarForce*spatialData.dr01[m]*invdr01; + forces.force01[m] = pcrd.scalarForce * spatialData.dr01[m] * invdr01; } } else if (params.eGeom == epullgANGLE) @@ -1253,9 +1222,9 @@ calculateVectorForces(const pull_coord_work_t &pcrd) * f23 = -dV/dtheta*(a*dr01/|dr01| - b*dr23*|dr23|)/|dr23|, */ double a = -gmx::invsqrt(1 - cos_theta2); /* comes from d/dx acos(x) */ - double b = a*cos_theta; - double invdr01 = 1./dnorm(spatialData.dr01); - double invdr23 = 1./dnorm(spatialData.dr23); + double b = a * cos_theta; + double invdr01 = 1. / dnorm(spatialData.dr01); + double invdr23 = 1. / dnorm(spatialData.dr23); dvec normalized_dr01, normalized_dr23; dsvmul(invdr01, spatialData.dr01, normalized_dr01); dsvmul(invdr23, spatialData.dr23, normalized_dr23); @@ -1263,8 +1232,10 @@ calculateVectorForces(const pull_coord_work_t &pcrd) for (int m = 0; m < DIM; m++) { /* Here, f_scal is -dV/dtheta */ - forces.force01[m] = pcrd.scalarForce*invdr01*(a*normalized_dr23[m] - b*normalized_dr01[m]); - forces.force23[m] = pcrd.scalarForce*invdr23*(a*normalized_dr01[m] - b*normalized_dr23[m]); + forces.force01[m] = + pcrd.scalarForce * invdr01 * (a * normalized_dr23[m] - b * normalized_dr01[m]); + forces.force23[m] = + pcrd.scalarForce * invdr23 * (a * normalized_dr01[m] - b * normalized_dr23[m]); } } else @@ -1289,14 +1260,15 @@ calculateVectorForces(const pull_coord_work_t &pcrd) double invdr01; dvec normalized_dr01; - invdr01 = 1./dnorm(spatialData.dr01); + invdr01 = 1. / dnorm(spatialData.dr01); dsvmul(invdr01, spatialData.dr01, normalized_dr01); - a = -gmx::invsqrt(1 - cos_theta2); /* comes from d/dx acos(x) */ - b = a*cos_theta; + a = -gmx::invsqrt(1 - cos_theta2); /* comes from d/dx acos(x) */ + b = a * cos_theta; for (int m = 0; m < DIM; m++) { - forces.force01[m] = pcrd.scalarForce*invdr01*(a*spatialData.vec[m] - b*normalized_dr01[m]); + forces.force01[m] = + pcrd.scalarForce * invdr01 * (a * spatialData.vec[m] - b * normalized_dr01[m]); } } else @@ -1319,30 +1291,31 @@ calculateVectorForces(const pull_coord_work_t &pcrd) n2 = diprod(spatialData.planevec_n, spatialData.planevec_n); dsvmul(-1, spatialData.dr23, dr32); sqrdist_32 = diprod(dr32, dr32); - tol = sqrdist_32*GMX_REAL_EPS; /* Avoid tiny angles */ + tol = sqrdist_32 * GMX_REAL_EPS; /* Avoid tiny angles */ if ((m2 > tol) && (n2 > tol)) { double a_01, a_23_01, a_23_45, a_45; double inv_dist_32, inv_sqrdist_32, dist_32; dvec u, v; inv_dist_32 = gmx::invsqrt(sqrdist_32); - inv_sqrdist_32 = inv_dist_32*inv_dist_32; - dist_32 = sqrdist_32*inv_dist_32; + inv_sqrdist_32 = inv_dist_32 * inv_dist_32; + dist_32 = sqrdist_32 * inv_dist_32; /* Forces on groups 0, 1 */ - a_01 = pcrd.scalarForce*dist_32/m2; /* scalarForce is -dV/dphi */ - dsvmul(-a_01, spatialData.planevec_m, forces.force01); /* added sign to get force on group 1, not 0 */ + a_01 = pcrd.scalarForce * dist_32 / m2; /* scalarForce is -dV/dphi */ + dsvmul(-a_01, spatialData.planevec_m, + forces.force01); /* added sign to get force on group 1, not 0 */ /* Forces on groups 4, 5 */ - a_45 = -pcrd.scalarForce*dist_32/n2; - dsvmul(a_45, spatialData.planevec_n, forces.force45); /* force on group 5 */ + a_45 = -pcrd.scalarForce * dist_32 / n2; + dsvmul(a_45, spatialData.planevec_n, forces.force45); /* force on group 5 */ /* Force on groups 2, 3 (defining the axis) */ - a_23_01 = -diprod(spatialData.dr01, dr32)*inv_sqrdist_32; - a_23_45 = -diprod(spatialData.dr45, dr32)*inv_sqrdist_32; + a_23_01 = -diprod(spatialData.dr01, dr32) * inv_sqrdist_32; + a_23_45 = -diprod(spatialData.dr45, dr32) * inv_sqrdist_32; dsvmul(-a_23_01, forces.force01, u); /* added sign to get force from group 0, not 1 */ dsvmul(a_23_45, forces.force45, v); - dvec_sub(u, v, forces.force23); /* force on group 3 */ + dvec_sub(u, v, forces.force23); /* force on group 3 */ } else { @@ -1356,7 +1329,7 @@ calculateVectorForces(const pull_coord_work_t &pcrd) { for (int m = 0; m < DIM; m++) { - forces.force01[m] = pcrd.scalarForce*spatialData.vec[m]; + forces.force01[m] = pcrd.scalarForce * spatialData.vec[m]; } } @@ -1373,32 +1346,39 @@ static gmx::Mutex registrationMutex; using Lock = gmx::lock_guard; -void register_external_pull_potential(struct pull_t *pull, - int coord_index, - const char *provider) +void register_external_pull_potential(struct pull_t* pull, int coord_index, const char* provider) { GMX_RELEASE_ASSERT(pull != nullptr, "register_external_pull_potential called before init_pull"); - GMX_RELEASE_ASSERT(provider != nullptr, "register_external_pull_potential called with NULL as provider name"); + GMX_RELEASE_ASSERT(provider != nullptr, + "register_external_pull_potential called with NULL as provider name"); if (coord_index < 0 || coord_index >= gmx::ssize(pull->coord)) { - gmx_fatal(FARGS, "Module '%s' attempted to register an external potential for pull coordinate %d which is out of the pull coordinate range %d - %zu\n", + gmx_fatal(FARGS, + "Module '%s' attempted to register an external potential for pull coordinate %d " + "which is out of the pull coordinate range %d - %zu\n", provider, coord_index + 1, 1, pull->coord.size()); } - pull_coord_work_t *pcrd = &pull->coord[coord_index]; + pull_coord_work_t* pcrd = &pull->coord[coord_index]; if (pcrd->params.eType != epullEXTERNAL) { - gmx_fatal(FARGS, "Module '%s' attempted to register an external potential for pull coordinate %d which of type '%s', whereas external potentials are only supported with type '%s'", - provider, coord_index + 1, epull_names[pcrd->params.eType], epull_names[epullEXTERNAL]); + gmx_fatal( + FARGS, + "Module '%s' attempted to register an external potential for pull coordinate %d " + "which of type '%s', whereas external potentials are only supported with type '%s'", + provider, coord_index + 1, epull_names[pcrd->params.eType], epull_names[epullEXTERNAL]); } - GMX_RELEASE_ASSERT(pcrd->params.externalPotentialProvider != nullptr, "The external potential provider string for a pull coordinate is NULL"); + GMX_RELEASE_ASSERT(pcrd->params.externalPotentialProvider != nullptr, + "The external potential provider string for a pull coordinate is NULL"); if (gmx_strcasecmp(provider, pcrd->params.externalPotentialProvider) != 0) { - gmx_fatal(FARGS, "Module '%s' attempted to register an external potential for pull coordinate %d which expects the external potential to be provided by a module named '%s'", + gmx_fatal(FARGS, + "Module '%s' attempted to register an external potential for pull coordinate %d " + "which expects the external potential to be provided by a module named '%s'", provider, coord_index + 1, pcrd->params.externalPotentialProvider); } @@ -1410,36 +1390,43 @@ void register_external_pull_potential(struct pull_t *pull, if (pcrd->bExternalPotentialProviderHasBeenRegistered) { - gmx_fatal(FARGS, "Module '%s' attempted to register an external potential for pull coordinate %d more than once", + gmx_fatal(FARGS, + "Module '%s' attempted to register an external potential for pull coordinate %d " + "more than once", provider, coord_index + 1); } pcrd->bExternalPotentialProviderHasBeenRegistered = true; pull->numUnregisteredExternalPotentials--; - GMX_RELEASE_ASSERT(pull->numUnregisteredExternalPotentials >= 0, "Negative unregistered potentials, the pull code is inconsistent"); + GMX_RELEASE_ASSERT(pull->numUnregisteredExternalPotentials >= 0, + "Negative unregistered potentials, the pull code is inconsistent"); } -static void check_external_potential_registration(const struct pull_t *pull) +static void check_external_potential_registration(const struct pull_t* pull) { if (pull->numUnregisteredExternalPotentials > 0) { size_t c; for (c = 0; c < pull->coord.size(); c++) { - if (pull->coord[c].params.eType == epullEXTERNAL && - !pull->coord[c].bExternalPotentialProviderHasBeenRegistered) + if (pull->coord[c].params.eType == epullEXTERNAL + && !pull->coord[c].bExternalPotentialProviderHasBeenRegistered) { break; } } - GMX_RELEASE_ASSERT(c < pull->coord.size(), "Internal inconsistency in the pull potential provider counting"); + GMX_RELEASE_ASSERT(c < pull->coord.size(), + "Internal inconsistency in the pull potential provider counting"); - gmx_fatal(FARGS, "No external provider for external pull potentials have been provided for %d pull coordinates. The first coordinate without provider is number %zu, which expects a module named '%s' to provide the external potential.", - pull->numUnregisteredExternalPotentials, - c + 1, pull->coord[c].params.externalPotentialProvider); + gmx_fatal(FARGS, + "No external provider for external pull potentials have been provided for %d " + "pull coordinates. The first coordinate without provider is number %zu, which " + "expects a module named '%s' to provide the external potential.", + pull->numUnregisteredExternalPotentials, c + 1, + pull->coord[c].params.externalPotentialProvider); } } @@ -1449,23 +1436,27 @@ static void check_external_potential_registration(const struct pull_t *pull) * potential energy is added either to the pull term or to a term * specific to the external module. */ -void apply_external_pull_coord_force(struct pull_t *pull, +void apply_external_pull_coord_force(struct pull_t* pull, int coord_index, double coord_force, - const t_mdatoms *mdatoms, - gmx::ForceWithVirial *forceWithVirial) + const t_mdatoms* mdatoms, + gmx::ForceWithVirial* forceWithVirial) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; - GMX_ASSERT(coord_index >= 0 && coord_index < gmx::ssize(pull->coord), "apply_external_pull_coord_force called with coord_index out of range"); + GMX_ASSERT(coord_index >= 0 && coord_index < gmx::ssize(pull->coord), + "apply_external_pull_coord_force called with coord_index out of range"); if (pull->comm.bParticipate) { pcrd = &pull->coord[coord_index]; - GMX_RELEASE_ASSERT(pcrd->params.eType == epullEXTERNAL, "The pull force can only be set externally on pull coordinates of external type"); + GMX_RELEASE_ASSERT( + pcrd->params.eType == epullEXTERNAL, + "The pull force can only be set externally on pull coordinates of external type"); - GMX_ASSERT(pcrd->bExternalPotentialProviderHasBeenRegistered, "apply_external_pull_coord_force called for an unregistered pull coordinate"); + GMX_ASSERT(pcrd->bExternalPotentialProviderHasBeenRegistered, + "apply_external_pull_coord_force called for an unregistered pull coordinate"); /* Set the force */ pcrd->scalarForce = coord_force; @@ -1491,12 +1482,16 @@ void apply_external_pull_coord_force(struct pull_t *pull, /* Calculate the pull potential and scalar force for a pull coordinate. * Returns the vector forces for the pull coordinate. */ -static PullCoordVectorForces -do_pull_pot_coord(struct pull_t *pull, int coord_ind, t_pbc *pbc, - double t, real lambda, - real *V, tensor vir, real *dVdl) +static PullCoordVectorForces do_pull_pot_coord(struct pull_t* pull, + int coord_ind, + t_pbc* pbc, + double t, + real lambda, + real* V, + tensor vir, + real* dVdl) { - pull_coord_work_t &pcrd = pull->coord[coord_ind]; + pull_coord_work_t& pcrd = pull->coord[coord_ind]; assert(pcrd.params.eType != epullCONSTRAINT); @@ -1511,9 +1506,15 @@ do_pull_pot_coord(struct pull_t *pull, int coord_ind, t_pbc *pbc, return pullCoordForces; } -real pull_potential(struct pull_t *pull, const t_mdatoms *md, t_pbc *pbc, - const t_commrec *cr, double t, real lambda, - const rvec *x, gmx::ForceWithVirial *force, real *dvdlambda) +real pull_potential(struct pull_t* pull, + const t_mdatoms* md, + t_pbc* pbc, + const t_commrec* cr, + double t, + real lambda, + const rvec* x, + gmx::ForceWithVirial* force, + real* dvdlambda) { real V = 0; @@ -1531,26 +1532,23 @@ real pull_potential(struct pull_t *pull, const t_mdatoms *md, t_pbc *pbc, pull_calc_coms(cr, pull, md, pbc, t, x, nullptr); - rvec *f = as_rvec_array(force->force_.data()); - matrix virial = { { 0 } }; - const bool computeVirial = (force->computeVirial_ && MASTER(cr)); + rvec* f = as_rvec_array(force->force_.data()); + matrix virial = { { 0 } }; + const bool computeVirial = (force->computeVirial_ && MASTER(cr)); for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; pcrd = &pull->coord[c]; - /* For external potential the force is assumed to be given by an external module by a call to - apply_pull_coord_external_force */ + /* For external potential the force is assumed to be given by an external module by a + call to apply_pull_coord_external_force */ if (pcrd->params.eType == epullCONSTRAINT || pcrd->params.eType == epullEXTERNAL) { continue; } - PullCoordVectorForces pullCoordForces = - do_pull_pot_coord(pull, c, pbc, t, lambda, - &V, - computeVirial ? virial : nullptr, - &dVdl); + PullCoordVectorForces pullCoordForces = do_pull_pot_coord( + pull, c, pbc, t, lambda, &V, computeVirial ? virial : nullptr, &dVdl); /* Distribute the force over the atoms in the pulled groups */ apply_forces_coord(pull, c, pullCoordForces, md, f); @@ -1563,17 +1561,24 @@ real pull_potential(struct pull_t *pull, const t_mdatoms *md, t_pbc *pbc, } } - GMX_ASSERT(pull->numExternalPotentialsStillToBeAppliedThisStep == 0, "Too few or too many external pull potentials have been applied the previous step"); + GMX_ASSERT(pull->numExternalPotentialsStillToBeAppliedThisStep == 0, + "Too few or too many external pull potentials have been applied the previous step"); /* All external pull potentials still need to be applied */ - pull->numExternalPotentialsStillToBeAppliedThisStep = - pull->numCoordinatesWithExternalPotential; + pull->numExternalPotentialsStillToBeAppliedThisStep = pull->numCoordinatesWithExternalPotential; return (MASTER(cr) ? V : 0.0); } -void pull_constraint(struct pull_t *pull, const t_mdatoms *md, t_pbc *pbc, - const t_commrec *cr, double dt, double t, - rvec *x, rvec *xp, rvec *v, tensor vir) +void pull_constraint(struct pull_t* pull, + const t_mdatoms* md, + t_pbc* pbc, + const t_commrec* cr, + double dt, + double t, + rvec* x, + rvec* xp, + rvec* v, + tensor vir) { assert(pull != nullptr); @@ -1585,11 +1590,11 @@ void pull_constraint(struct pull_t *pull, const t_mdatoms *md, t_pbc *pbc, } } -void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) +void dd_make_local_pull_groups(const t_commrec* cr, struct pull_t* pull) { - gmx_domdec_t *dd; - pull_comm_t *comm; - gmx_bool bMustParticipate; + gmx_domdec_t* dd; + pull_comm_t* comm; + gmx_bool bMustParticipate; dd = cr->dd; @@ -1600,7 +1605,7 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) */ bMustParticipate = (comm->bParticipateAll || comm->isMasterRank); - for (pull_group_work_t &group : pull->group) + for (pull_group_work_t& group : pull->group) { if (!group.globalWeights.empty()) { @@ -1611,12 +1616,14 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) } } - GMX_ASSERT(bMustParticipate || dd != nullptr, "Either all ranks (including this rank) participate, or we use DD and need to have access to dd here"); + GMX_ASSERT(bMustParticipate || dd != nullptr, + "Either all ranks (including this rank) participate, or we use DD and need to " + "have access to dd here"); /* We should participate if we have pull or pbc atoms */ - if (!bMustParticipate && - (group.atomSet.numAtomsLocal() > 0 || (group.epgrppbc == epgrppbcREFAT && - group.pbcAtomSet->numAtomsLocal() > 0))) + if (!bMustParticipate + && (group.atomSet.numAtomsLocal() > 0 + || (group.epgrppbc == epgrppbcREFAT && group.pbcAtomSet->numAtomsLocal() > 0))) { bMustParticipate = TRUE; } @@ -1628,9 +1635,9 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) * if they needed to participate up to 20 decompositions ago. * This avoids frequent rebuilds due to atoms jumping back and forth. */ - const int64_t history_count = 20; - gmx_bool bWillParticipate; - int count[2]; + const int64_t history_count = 20; + gmx_bool bWillParticipate; + int count[2]; /* Increase the decomposition counter for the current call */ comm->setup_count++; @@ -1641,14 +1648,13 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) } bWillParticipate = - bMustParticipate || - (comm->bParticipate && - comm->must_count >= comm->setup_count - history_count); + bMustParticipate + || (comm->bParticipate && comm->must_count >= comm->setup_count - history_count); if (debug && dd != nullptr) { - fprintf(debug, "Our DD rank (%3d) pull #atoms>0 or master: %s, will be part %s\n", - dd->rank, gmx::boolToString(bMustParticipate), gmx::boolToString(bWillParticipate)); + fprintf(debug, "Our DD rank (%3d) pull #atoms>0 or master: %s, will be part %s\n", dd->rank, + gmx::boolToString(bMustParticipate), gmx::boolToString(bWillParticipate)); } if (bWillParticipate) @@ -1672,12 +1678,11 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) /* If we are missing ranks or if we have 20% more ranks than needed * we make a new sub-communicator. */ - if (count[1] > 0 || 6*count[0] < 5*comm->nparticipate) + if (count[1] > 0 || 6 * count[0] < 5 * comm->nparticipate) { if (debug) { - fprintf(debug, "Creating new pull subcommunicator of size %d\n", - count[0]); + fprintf(debug, "Creating new pull subcommunicator of size %d\n", count[0]); } #if GMX_MPI @@ -1690,8 +1695,7 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) * to avoid this splitting as much as possible. */ assert(dd != nullptr); - MPI_Comm_split(dd->mpi_comm_all, bWillParticipate ? 0 : 1, dd->rank, - &comm->mpi_comm_com); + MPI_Comm_split(dd->mpi_comm_all, bWillParticipate ? 0 : 1, dd->rank, &comm->mpi_comm_com); #endif comm->bParticipate = bWillParticipate; @@ -1700,12 +1704,13 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) /* When we use the previous COM for PBC, we need to broadcast * the previous COM to ranks that have joined the communicator. */ - for (pull_group_work_t &group : pull->group) + for (pull_group_work_t& group : pull->group) { if (group.epgrppbc == epgrppbcPREVSTEPCOM) { GMX_ASSERT(comm->bParticipate || !MASTER(cr), - "The master rank has to participate, as it should pass an up to date prev. COM " + "The master rank has to participate, as it should pass an up to " + "date prev. COM " "to bcast here as well as to e.g. checkpointing"); gmx_bcast(sizeof(dvec), group.x_prev_step, cr); @@ -1718,24 +1723,26 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull) pull->bSetPBCatoms = TRUE; } -static void init_pull_group_index(FILE *fplog, const t_commrec *cr, - int g, pull_group_work_t *pg, - gmx_bool bConstraint, const ivec pulldim_con, - const gmx_mtop_t *mtop, - const t_inputrec *ir, real lambda) +static void init_pull_group_index(FILE* fplog, + const t_commrec* cr, + int g, + pull_group_work_t* pg, + gmx_bool bConstraint, + const ivec pulldim_con, + const gmx_mtop_t* mtop, + const t_inputrec* ir, + real lambda) { /* With EM and BD there are no masses in the integrator. * But we still want to have the correct mass-weighted COMs. * So we store the real masses in the weights. */ - const bool setWeights = (pg->params.nweight > 0 || - EI_ENERGY_MINIMIZATION(ir->eI) || - ir->eI == eiBD); + const bool setWeights = (pg->params.nweight > 0 || EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD); /* In parallel, store we need to extract localWeights from weights at DD time */ - std::vector &weights = ((cr && PAR(cr)) ? pg->globalWeights : pg->localWeights); + std::vector& weights = ((cr && PAR(cr)) ? pg->globalWeights : pg->localWeights); - const SimulationGroups &groups = mtop->groups; + const SimulationGroups& groups = mtop->groups; /* Count frozen dimensions and (weighted) mass */ int nfrozen = 0; @@ -1750,14 +1757,14 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, { for (int d = 0; d < DIM; d++) { - if (pulldim_con[d] == 1 && - ir->opts.nFreeze[getGroupType(groups, SimulationAtomGroupType::Freeze, ii)][d]) + if (pulldim_con[d] == 1 + && ir->opts.nFreeze[getGroupType(groups, SimulationAtomGroupType::Freeze, ii)][d]) { nfrozen++; } } } - const t_atom &atom = mtopGetAtomParameters(mtop, ii, &molb); + const t_atom& atom = mtopGetAtomParameters(mtop, ii, &molb); real m; if (ir->efep == efepNO) { @@ -1765,7 +1772,7 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, } else { - m = (1 - lambda)*atom.m + lambda*atom.mB; + m = (1 - lambda) * atom.m + lambda * atom.mB; } real w; if (pg->params.nweight > 0) @@ -1779,37 +1786,38 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, if (EI_ENERGY_MINIMIZATION(ir->eI)) { /* Move the mass to the weight */ - w *= m; - m = 1; + w *= m; + m = 1; } else if (ir->eI == eiBD) { real mbd; if (ir->bd_fric != 0.0F) { - mbd = ir->bd_fric*ir->delta_t; + mbd = ir->bd_fric * ir->delta_t; } else { if (groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling].empty()) { - mbd = ir->delta_t/ir->opts.tau_t[0]; + mbd = ir->delta_t / ir->opts.tau_t[0]; } else { - mbd = ir->delta_t/ir->opts.tau_t[groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ii]]; + mbd = ir->delta_t + / ir->opts.tau_t[groups.groupNumbers[SimulationAtomGroupType::TemperatureCoupling][ii]]; } } - w *= m/mbd; - m = mbd; + w *= m / mbd; + m = mbd; } if (setWeights) { weights.push_back(w); } - tmass += m; - wmass += m*w; - wwmass += m*w*w; + tmass += m; + wmass += m * w; + wwmass += m * w * w; } if (wmass == 0) @@ -1830,13 +1838,10 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, } if (fplog) { - fprintf(fplog, - "Pull group %d: %5d atoms, mass %9.3f", - g, pg->params.nat, tmass); - if (pg->params.weight || - EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD) + fprintf(fplog, "Pull group %d: %5d atoms, mass %9.3f", g, pg->params.nat, tmass); + if (pg->params.weight || EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD) { - fprintf(fplog, ", weighted mass %9.3f", wmass*wmass/wwmass); + fprintf(fplog, ", weighted mass %9.3f", wmass * wmass / wwmass); } if (pg->epgrppbc == epgrppbcCOS) { @@ -1848,14 +1853,14 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, if (nfrozen == 0) { /* A value != 0 signals not frozen, it is updated later */ - pg->invtm = -1.0; + pg->invtm = -1.0; } else { int ndim = 0; for (int d = 0; d < DIM; d++) { - ndim += pulldim_con[d]*pg->params.nat; + ndim += pulldim_con[d] * pg->params.nat; } if (fplog && nfrozen > 0 && nfrozen < ndim) { @@ -1870,37 +1875,43 @@ static void init_pull_group_index(FILE *fplog, const t_commrec *cr, } } -struct pull_t * -init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, - const gmx_mtop_t *mtop, const t_commrec *cr, gmx::LocalAtomSetManager *atomSets, - real lambda) +struct pull_t* init_pull(FILE* fplog, + const pull_params_t* pull_params, + const t_inputrec* ir, + const gmx_mtop_t* mtop, + const t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + real lambda) { - struct pull_t *pull; - pull_comm_t *comm; + struct pull_t* pull; + pull_comm_t* comm; pull = new pull_t; /* Copy the pull parameters */ - pull->params = *pull_params; + pull->params = *pull_params; /* Avoid pointer copies */ pull->params.group = nullptr; pull->params.coord = nullptr; for (int i = 0; i < pull_params->ngroup; ++i) { - pull->group.emplace_back(pull_params->group[i], atomSets->add({pull_params->group[i].ind, pull_params->group[i].ind+pull_params->group[i].nat}), + pull->group.emplace_back(pull_params->group[i], + atomSets->add({ pull_params->group[i].ind, + pull_params->group[i].ind + pull_params->group[i].nat }), pull_params->bSetPbcRefToPrevStepCOM); } if (cr != nullptr && DOMAINDECOMP(cr)) { /* Set up the global to local atom mapping for PBC atoms */ - for (pull_group_work_t &group : pull->group) + for (pull_group_work_t& group : pull->group) { if (group.epgrppbc == epgrppbcREFAT || group.epgrppbc == epgrppbcPREVSTEPCOM) { /* pbcAtomSet consists of a single atom */ - group.pbcAtomSet = std::make_unique(atomSets->add({&group.params.pbcatom, &group.params.pbcatom + 1})); + group.pbcAtomSet = std::make_unique( + atomSets->add({ &group.params.pbcatom, &group.params.pbcatom + 1 })); } } } @@ -1912,7 +1923,8 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, pull->bXOutAverage = pull_params->bXOutAverage; pull->bFOutAverage = pull_params->bFOutAverage; - GMX_RELEASE_ASSERT(pull->group[0].params.nat == 0, "pull group 0 is an absolute reference group and should not contain atoms"); + GMX_RELEASE_ASSERT(pull->group[0].params.nat == 0, + "pull group 0 is an absolute reference group and should not contain atoms"); pull->numCoordinatesWithExternalPotential = 0; @@ -1921,15 +1933,14 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, /* Construct a pull coordinate, copying all coordinate parameters */ pull->coord.emplace_back(pull_params->coord[c]); - pull_coord_work_t *pcrd = &pull->coord.back(); + pull_coord_work_t* pcrd = &pull->coord.back(); switch (pcrd->params.eGeom) { case epullgDIST: - case epullgDIRRELATIVE: /* Direction vector is determined at each step */ + case epullgDIRRELATIVE: /* Direction vector is determined at each step */ case epullgANGLE: - case epullgDIHEDRAL: - break; + case epullgDIHEDRAL: break; case epullgDIR: case epullgDIRPBC: case epullgCYL: @@ -1946,22 +1957,25 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, * the string corresponding to the geometry, which will result * in printing "UNDEFINED". */ - gmx_fatal(FARGS, "Pull geometry not supported for pull coordinate %d. The geometry enum %d in the input is larger than that supported by the code (up to %d). You are probably reading a tpr file generated with a newer version of Gromacs with an binary from an older version of Gromacs.", + gmx_fatal(FARGS, + "Pull geometry not supported for pull coordinate %d. The geometry enum " + "%d in the input is larger than that supported by the code (up to %d). " + "You are probably reading a tpr file generated with a newer version of " + "Gromacs with an binary from an older version of Gromacs.", c + 1, pcrd->params.eGeom, epullgNR - 1); } if (pcrd->params.eType == epullCONSTRAINT) { /* Check restrictions of the constraint pull code */ - if (pcrd->params.eGeom == epullgCYL || - pcrd->params.eGeom == epullgDIRRELATIVE || - pcrd->params.eGeom == epullgANGLE || - pcrd->params.eGeom == epullgDIHEDRAL || - pcrd->params.eGeom == epullgANGLEAXIS) + if (pcrd->params.eGeom == epullgCYL || pcrd->params.eGeom == epullgDIRRELATIVE + || pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgDIHEDRAL + || pcrd->params.eGeom == epullgANGLEAXIS) { - gmx_fatal(FARGS, "Pulling of type %s can not be combined with geometry %s. Consider using pull type %s.", - epull_names[pcrd->params.eType], - epullg_names[pcrd->params.eGeom], + gmx_fatal(FARGS, + "Pulling of type %s can not be combined with geometry %s. Consider using " + "pull type %s.", + epull_names[pcrd->params.eType], epullg_names[pcrd->params.eGeom], epull_names[epullUMBRELLA]); } @@ -1976,7 +1990,8 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, { pull->bCylinder = TRUE; } - else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgDIHEDRAL || pcrd->params.eGeom == epullgANGLEAXIS) + else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgDIHEDRAL + || pcrd->params.eGeom == epullgANGLEAXIS) { pull->bAngle = TRUE; } @@ -1988,8 +2003,7 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, for (int i = 0; i < pcrd->params.ngroup; i++) { int groupIndex = pcrd->params.group[i]; - if (groupIndex > 0 && - !(pcrd->params.eGeom == epullgCYL && i == 0)) + if (groupIndex > 0 && !(pcrd->params.eGeom == epullgCYL && i == 0)) { pull->group[groupIndex].needToCalcCom = true; } @@ -2001,7 +2015,9 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, /* Initialize the constant reference value */ if (pcrd->params.eType != epullEXTERNAL) { - low_set_pull_coord_reference_value(pcrd, c, pcrd->params.init*pull_conversion_factor_userinput2internal(&pcrd->params)); + low_set_pull_coord_reference_value( + pcrd, c, + pcrd->params.init * pull_conversion_factor_userinput2internal(&pcrd->params)); } else { @@ -2019,7 +2035,9 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, if (pcrd->params.eType == epullEXTERNAL) { - GMX_RELEASE_ASSERT(pcrd->params.rate == 0, "With an external potential, a pull coordinate should have rate = 0"); + GMX_RELEASE_ASSERT( + pcrd->params.rate == 0, + "With an external potential, a pull coordinate should have rate = 0"); /* This external potential needs to be registered later */ pull->numCoordinatesWithExternalPotential++; @@ -2027,16 +2045,15 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, pcrd->bExternalPotentialProviderHasBeenRegistered = false; } - pull->numUnregisteredExternalPotentials = - pull->numCoordinatesWithExternalPotential; + pull->numUnregisteredExternalPotentials = pull->numCoordinatesWithExternalPotential; pull->numExternalPotentialsStillToBeAppliedThisStep = 0; pull->ePBC = ir->ePBC; switch (pull->ePBC) { case epbcNONE: pull->npbcdim = 0; break; - case epbcXY: pull->npbcdim = 2; break; - default: pull->npbcdim = 3; break; + case epbcXY: pull->npbcdim = 2; break; + default: pull->npbcdim = 3; break; } if (fplog) @@ -2044,10 +2061,10 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, gmx_bool bAbs, bCos; bAbs = FALSE; - for (const pull_coord_work_t &coord : pull->coord) + for (const pull_coord_work_t& coord : pull->coord) { - if (pull->group[coord.params.group[0]].params.nat == 0 || - pull->group[coord.params.group[1]].params.nat == 0) + if (pull->group[coord.params.group[0]].params.nat == 0 + || pull->group[coord.params.group[1]].params.nat == 0) { bAbs = TRUE; } @@ -2064,10 +2081,10 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, } // Don't include the reference group 0 in output, so we report ngroup-1 int numRealGroups = pull->group.size() - 1; - GMX_RELEASE_ASSERT(numRealGroups > 0, "The reference absolute position pull group should always be present"); - fprintf(fplog, "with %zu pull coordinate%s and %d group%s\n", - pull->coord.size(), pull->coord.size() == 1 ? "" : "s", - numRealGroups, numRealGroups == 1 ? "" : "s"); + GMX_RELEASE_ASSERT(numRealGroups > 0, + "The reference absolute position pull group should always be present"); + fprintf(fplog, "with %zu pull coordinate%s and %d group%s\n", pull->coord.size(), + pull->coord.size() == 1 ? "" : "s", numRealGroups, numRealGroups == 1 ? "" : "s"); if (bAbs) { fprintf(fplog, "with an absolute reference\n"); @@ -2076,8 +2093,7 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, // Don't include the reference group 0 in loop for (size_t g = 1; g < pull->group.size(); g++) { - if (pull->group[g].params.nat > 1 && - pull->group[g].params.pbcatom < 0) + if (pull->group[g].params.nat > 1 && pull->group[g].params.pbcatom < 0) { /* We are using cosine weighting */ fprintf(fplog, "Cosine weighting is used for group %zu\n", g); @@ -2090,13 +2106,13 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, } } - pull->bRefAt = FALSE; - pull->cosdim = -1; + pull->bRefAt = FALSE; + pull->cosdim = -1; for (size_t g = 0; g < pull->group.size(); g++) { - pull_group_work_t *pgrp; + pull_group_work_t* pgrp; - pgrp = &pull->group[g]; + pgrp = &pull->group[g]; if (pgrp->params.nat > 0) { /* There is an issue when a group is used in multiple coordinates @@ -2117,7 +2133,7 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, bConstraint = FALSE; clear_ivec(pulldim); clear_ivec(pulldim_con); - for (const pull_coord_work_t &coord : pull->coord) + for (const pull_coord_work_t& coord : pull->coord) { gmx_bool bGroupUsed = FALSE; for (int gi = 0; gi < coord.params.ngroup; gi++) @@ -2151,13 +2167,13 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, */ switch (pgrp->epgrppbc) { - case epgrppbcREFAT: - pull->bRefAt = TRUE; - break; + case epgrppbcREFAT: pull->bRefAt = TRUE; break; case epgrppbcCOS: if (pgrp->params.weight != nullptr) { - gmx_fatal(FARGS, "Pull groups can not have relative weights and cosine weighting at same time"); + gmx_fatal(FARGS, + "Pull groups can not have relative weights and cosine weighting " + "at same time"); } for (int m = 0; m < DIM; m++) { @@ -2165,20 +2181,19 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, { if (pull->cosdim >= 0 && pull->cosdim != m) { - gmx_fatal(FARGS, "Can only use cosine weighting with pulling in one dimension (use mdp option pull-coord?-dim)"); + gmx_fatal(FARGS, + "Can only use cosine weighting with pulling in one " + "dimension (use mdp option pull-coord?-dim)"); } pull->cosdim = m; } } break; - case epgrppbcNONE: - break; + case epgrppbcNONE: break; } /* Set the indices */ - init_pull_group_index(fplog, cr, g, pgrp, - bConstraint, pulldim_con, - mtop, ir, lambda); + init_pull_group_index(fplog, cr, g, pgrp, bConstraint, pulldim_con, mtop, ir, lambda); } else { @@ -2193,17 +2208,20 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, /* If we use cylinder coordinates, do some initialising for them */ if (pull->bCylinder) { - for (const pull_coord_work_t &coord : pull->coord) + for (const pull_coord_work_t& coord : pull->coord) { if (coord.params.eGeom == epullgCYL) { if (pull->group[coord.params.group[0]].params.nat == 0) { - gmx_fatal(FARGS, "A cylinder pull group is not supported when using absolute reference!\n"); + gmx_fatal(FARGS, + "A cylinder pull group is not supported when using absolute " + "reference!\n"); } } - const auto &referenceGroup = pull->group[coord.params.group[0]]; - pull->dyna.emplace_back(referenceGroup.params, referenceGroup.atomSet, pull->params.bSetPbcRefToPrevStepCOM); + const auto& referenceGroup = pull->group[coord.params.group[0]]; + pull->dyna.emplace_back(referenceGroup.params, referenceGroup.atomSet, + pull->params.bSetPbcRefToPrevStepCOM); } } @@ -2218,24 +2236,23 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, * when we have an external pull potential, since then the external * potential provider expects each rank to have the coordinate. */ - comm->bParticipateAll = (cr == nullptr || !DOMAINDECOMP(cr) || - cr->dd->nnodes <= 32 || - pull->numCoordinatesWithExternalPotential > 0 || - getenv("GMX_PULL_PARTICIPATE_ALL") != nullptr); + comm->bParticipateAll = (cr == nullptr || !DOMAINDECOMP(cr) || cr->dd->nnodes <= 32 + || pull->numCoordinatesWithExternalPotential > 0 + || getenv("GMX_PULL_PARTICIPATE_ALL") != nullptr); /* This sub-commicator is not used with comm->bParticipateAll, * so we can always initialize it to NULL. */ - comm->mpi_comm_com = MPI_COMM_NULL; - comm->nparticipate = 0; - comm->isMasterRank = (cr == nullptr || MASTER(cr)); + comm->mpi_comm_com = MPI_COMM_NULL; + comm->nparticipate = 0; + comm->isMasterRank = (cr == nullptr || MASTER(cr)); #else /* No MPI: 1 rank: all ranks pull */ comm->bParticipateAll = TRUE; comm->isMasterRank = true; #endif - comm->bParticipate = comm->bParticipateAll; - comm->setup_count = 0; - comm->must_count = 0; + comm->bParticipate = comm->bParticipateAll; + comm->setup_count = 0; + comm->must_count = 0; if (!comm->bParticipateAll && fplog != nullptr) { @@ -2243,10 +2260,10 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, } comm->pbcAtomBuffer.resize(pull->group.size()); - comm->comBuffer.resize(pull->group.size()*c_comBufferStride); + comm->comBuffer.resize(pull->group.size() * c_comBufferStride); if (pull->bCylinder) { - comm->cylinderBuffer.resize(pull->coord.size()*c_cylinderBufferStride); + comm->cylinderBuffer.resize(pull->coord.size() * c_cylinderBufferStride); } /* We still need to initialize the PBC reference coordinates */ @@ -2258,7 +2275,7 @@ init_pull(FILE *fplog, const pull_params_t *pull_params, const t_inputrec *ir, return pull; } -static void destroy_pull(struct pull_t *pull) +static void destroy_pull(struct pull_t* pull) { #if GMX_MPI if (pull->comm.mpi_comm_com != MPI_COMM_NULL) @@ -2270,9 +2287,13 @@ static void destroy_pull(struct pull_t *pull) delete pull; } -void preparePrevStepPullCom(const t_inputrec *ir, pull_t *pull_work, - const t_mdatoms *md, t_state *state, const t_state *state_global, - const t_commrec *cr, bool startingFromCheckpoint) +void preparePrevStepPullCom(const t_inputrec* ir, + pull_t* pull_work, + const t_mdatoms* md, + t_state* state, + const t_state* state_global, + const t_commrec* cr, + bool startingFromCheckpoint) { if (!ir->pull || !ir->pull->bSetPbcRefToPrevStepCOM) { @@ -2301,7 +2322,7 @@ void preparePrevStepPullCom(const t_inputrec *ir, pull_t *pull_work, } } -void finish_pull(struct pull_t *pull) +void finish_pull(struct pull_t* pull) { check_external_potential_registration(pull); @@ -2317,12 +2338,12 @@ void finish_pull(struct pull_t *pull) destroy_pull(pull); } -gmx_bool pull_have_potential(const struct pull_t *pull) +gmx_bool pull_have_potential(const struct pull_t* pull) { return pull->bPotential; } -gmx_bool pull_have_constraint(const struct pull_t *pull) +gmx_bool pull_have_constraint(const struct pull_t* pull) { return pull->bConstraint; } diff --git a/src/gromacs/pulling/pull.h b/src/gromacs/pulling/pull.h index 2b19d5028c..20b8bf1d4c 100644 --- a/src/gromacs/pulling/pull.h +++ b/src/gromacs/pulling/pull.h @@ -74,35 +74,35 @@ namespace gmx { class ForceWithVirial; class LocalAtomSetManager; -} +} // namespace gmx /*! \brief Returns if the pull coordinate is an angle * * \param[in] pcrd The pull coordinate to query the type for. * \returns a boolean telling if the coordinate is of angle type. */ -bool pull_coordinate_is_angletype(const t_pull_coord *pcrd); +bool pull_coordinate_is_angletype(const t_pull_coord* pcrd); /*! \brief Returns the units of the pull coordinate. * * \param[in] pcrd The pull coordinate to query the units for. * \returns a string with the units of the coordinate. */ -const char *pull_coordinate_units(const t_pull_coord *pcrd); +const char* pull_coordinate_units(const t_pull_coord* pcrd); /*! \brief Returns the conversion factor from the pull coord init/rate unit to internal value unit. * * \param[in] pcrd The pull coordinate to get the conversion factor for. * \returns the conversion factor. */ -double pull_conversion_factor_userinput2internal(const t_pull_coord *pcrd); +double pull_conversion_factor_userinput2internal(const t_pull_coord* pcrd); /*! \brief Returns the conversion factor from the pull coord internal value unit to the init/rate unit. * * \param[in] pcrd The pull coordinate to get the conversion factor for. * \returns the conversion factor. */ -double pull_conversion_factor_internal2userinput(const t_pull_coord *pcrd); +double pull_conversion_factor_internal2userinput(const t_pull_coord* pcrd); /*! \brief Get the value for pull coord coord_ind. * @@ -111,9 +111,7 @@ double pull_conversion_factor_internal2userinput(const t_pull_coord *pcrd); * \param[in] pbc Information structure about periodicity. * \returns the value of the pull coordinate. */ -double get_pull_coord_value(struct pull_t *pull, - int coord_ind, - const struct t_pbc *pbc); +double get_pull_coord_value(struct pull_t* pull, int coord_ind, const struct t_pbc* pbc); /*! \brief Registers the provider of an external potential for a coordinate. * @@ -138,9 +136,7 @@ double get_pull_coord_value(struct pull_t *pull, * \param[in] coord_index The pull coordinate index to register the external potential for. * \param[in] provider Provider string, should match the potential-provider pull coordinate mdp option. */ -void register_external_pull_potential(struct pull_t *pull, - int coord_index, - const char *provider); +void register_external_pull_potential(struct pull_t* pull, int coord_index, const char* provider); /*! \brief Apply forces of an external potential to a pull coordinate. @@ -159,18 +155,18 @@ void register_external_pull_potential(struct pull_t *pull, * \param[in] mdatoms Atom properties, only masses are used. * \param[in,out] forceWithVirial Force and virial buffers. */ -void apply_external_pull_coord_force(struct pull_t *pull, +void apply_external_pull_coord_force(struct pull_t* pull, int coord_index, double coord_force, - const t_mdatoms *mdatoms, - gmx::ForceWithVirial *forceWithVirial); + const t_mdatoms* mdatoms, + gmx::ForceWithVirial* forceWithVirial); /*! \brief Set the all the pull forces to zero. * * \param pull The pull group. */ -void clear_pull_forces(struct pull_t *pull); +void clear_pull_forces(struct pull_t* pull); /*! \brief Determine the COM pull forces and add them to f, return the potential @@ -187,9 +183,15 @@ void clear_pull_forces(struct pull_t *pull); * * \returns The pull potential energy. */ -real pull_potential(struct pull_t *pull, const t_mdatoms *md, struct t_pbc *pbc, - const t_commrec *cr, double t, real lambda, - const rvec *x, gmx::ForceWithVirial *force, real *dvdlambda); +real pull_potential(struct pull_t* pull, + const t_mdatoms* md, + struct t_pbc* pbc, + const t_commrec* cr, + double t, + real lambda, + const rvec* x, + gmx::ForceWithVirial* force, + real* dvdlambda); /*! \brief Constrain the coordinates xp in the directions in x @@ -206,9 +208,16 @@ real pull_potential(struct pull_t *pull, const t_mdatoms *md, struct t_pbc *pbc, * \param[in,out] v Velocities, which may get a pull correction. * \param[in,out] vir The virial, which, if != NULL, gets a pull correction. */ -void pull_constraint(struct pull_t *pull, const t_mdatoms *md, struct t_pbc *pbc, - const t_commrec *cr, double dt, double t, - rvec *x, rvec *xp, rvec *v, tensor vir); +void pull_constraint(struct pull_t* pull, + const t_mdatoms* md, + struct t_pbc* pbc, + const t_commrec* cr, + double dt, + double t, + rvec* x, + rvec* xp, + rvec* v, + tensor vir); /*! \brief Make a selection of the home atoms for all pull groups. @@ -217,7 +226,7 @@ void pull_constraint(struct pull_t *pull, const t_mdatoms *md, struct t_pbc *pbc * \param cr Structure for communication info. * \param pull The pull group. */ -void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull); +void dd_make_local_pull_groups(const t_commrec* cr, struct pull_t* pull); /*! \brief Allocate, initialize and return a pull work struct. @@ -230,20 +239,20 @@ void dd_make_local_pull_groups(const t_commrec *cr, struct pull_t *pull); * \param atomSets The manager that handles the pull atom sets * \param lambda FEP lambda. */ -struct pull_t *init_pull(FILE *fplog, - const pull_params_t *pull_params, - const t_inputrec *ir, - const gmx_mtop_t *mtop, - const t_commrec *cr, - gmx::LocalAtomSetManager *atomSets, - real lambda); +struct pull_t* init_pull(FILE* fplog, + const pull_params_t* pull_params, + const t_inputrec* ir, + const gmx_mtop_t* mtop, + const t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + real lambda); /*! \brief Close the pull output files and delete pull. * * \param pull The pull data structure. */ -void finish_pull(struct pull_t *pull); +void finish_pull(struct pull_t* pull); /*! \brief Calculates centers of mass all pull groups. @@ -257,13 +266,13 @@ void finish_pull(struct pull_t *pull); * \param[in,out] xp Updated x, can be NULL. * */ -void pull_calc_coms(const t_commrec *cr, - pull_t *pull, - const t_mdatoms *md, - t_pbc *pbc, +void pull_calc_coms(const t_commrec* cr, + pull_t* pull, + const t_mdatoms* md, + t_pbc* pbc, double t, const rvec x[], - rvec *xp); + rvec* xp); /*! \brief Margin for checking pull group PBC distances compared to half the box size */ static constexpr real c_pullGroupPbcMargin = 0.9; @@ -288,10 +297,7 @@ static constexpr real c_pullGroupSmallGroupThreshold = 0.5; * \param[in] pbcMargin The minimum margin (as a fraction) to half the box size * \returns -1 when all groups obey PBC or the first group index that fails PBC */ -int pullCheckPbcWithinGroups(const pull_t &pull, - const rvec *x, - const t_pbc &pbc, - real pbcMargin); +int pullCheckPbcWithinGroups(const pull_t& pull, const rvec* x, const t_pbc& pbc, real pbcMargin); /*! \brief Checks whether a specific group that uses a reference atom is within PBC restrictions * @@ -313,9 +319,9 @@ int pullCheckPbcWithinGroups(const pull_t &pull, * \param[in] pbcMargin The minimum margin (as a fraction) to half the box size * \returns true if the group obeys PBC otherwise false */ -bool pullCheckPbcWithinGroup(const pull_t &pull, +bool pullCheckPbcWithinGroup(const pull_t& pull, gmx::ArrayRef x, - const t_pbc &pbc, + const t_pbc& pbc, int groupNr, real pbcMargin); @@ -323,14 +329,14 @@ bool pullCheckPbcWithinGroup(const pull_t &pull, * * \param[in] pull The pull data structure. */ -gmx_bool pull_have_potential(const struct pull_t *pull); +gmx_bool pull_have_potential(const struct pull_t* pull); /*! \brief Returns if we have pull coordinates with constraint pulling. * * \param[in] pull The pull data structure. */ -gmx_bool pull_have_constraint(const struct pull_t *pull); +gmx_bool pull_have_constraint(const struct pull_t* pull); /*! \brief Returns the maxing distance for pulling * @@ -343,15 +349,14 @@ gmx_bool pull_have_constraint(const struct pull_t *pull); * \param[in] pbc Information on periodic boundary conditions * \returns The maximume distance */ -real max_pull_distance2(const pull_coord_work_t *pcrd, - const t_pbc *pbc); +real max_pull_distance2(const pull_coord_work_t* pcrd, const t_pbc* pbc); /*! \brief Sets the previous step COM in pull to the current COM and updates the pull_com_prev_step in the state * * \param[in] pull The COM pull force calculation data structure * \param[in] state The local (to this rank) state. */ -void updatePrevStepPullCom(struct pull_t *pull, t_state *state); +void updatePrevStepPullCom(struct pull_t* pull, t_state* state); /*! \brief Allocates, initializes and communicates the previous step pull COM (if that option is set to true). * @@ -365,9 +370,13 @@ void updatePrevStepPullCom(struct pull_t *pull, t_state *state); * \param[in] cr Struct for communication info. * \param[in] startingFromCheckpoint Is the simulation starting from a checkpoint? */ -void preparePrevStepPullCom(const t_inputrec *ir, pull_t *pull_work, const t_mdatoms *md, - t_state *state, const t_state *state_global, const t_commrec *cr, - bool startingFromCheckpoint); +void preparePrevStepPullCom(const t_inputrec* ir, + pull_t* pull_work, + const t_mdatoms* md, + t_state* state, + const t_state* state_global, + const t_commrec* cr, + bool startingFromCheckpoint); /*! \brief Initializes the COM of the previous step (set to initial COM) * @@ -377,10 +386,6 @@ void preparePrevStepPullCom(const t_inputrec *ir, pull_t *pull_work, const t_mda * \param[in] pbc Information struct about periodicity. * \param[in] x The local positions. */ -void initPullComFromPrevStep(const t_commrec *cr, - pull_t *pull, - const t_mdatoms *md, - t_pbc *pbc, - const rvec x[]); +void initPullComFromPrevStep(const t_commrec* cr, pull_t* pull, const t_mdatoms* md, t_pbc* pbc, const rvec x[]); #endif diff --git a/src/gromacs/pulling/pull_internal.h b/src/gromacs/pulling/pull_internal.h index 9c34e0bc81..bab31a3234 100644 --- a/src/gromacs/pulling/pull_internal.h +++ b/src/gromacs/pulling/pull_internal.h @@ -71,8 +71,12 @@ static const int c_pullMaxNumLocalAtomsSingleThreaded = 1; class PullHistory; -enum { - epgrppbcNONE, epgrppbcREFAT, epgrppbcCOS, epgrppbcPREVSTEPCOM +enum +{ + epgrppbcNONE, + epgrppbcREFAT, + epgrppbcCOS, + epgrppbcPREVSTEPCOM }; /*! \internal @@ -86,55 +90,53 @@ struct pull_group_work_t * \param[in] atomSet The global to local atom set manager * \param[in] setPbcRefToPrevStepCOM Does this pull group use the COM from the previous step as reference position? */ - pull_group_work_t(const t_pull_group ¶ms, - gmx::LocalAtomSet atomSet, - bool setPbcRefToPrevStepCOM); + pull_group_work_t(const t_pull_group& params, gmx::LocalAtomSet atomSet, bool setPbcRefToPrevStepCOM); /* Data only modified at initialization */ - const t_pull_group params; /**< The pull group parameters */ - const int epgrppbc; /**< The type of pbc for this pull group, see enum above */ + const t_pull_group params; /**< The pull group parameters */ + const int epgrppbc; /**< The type of pbc for this pull group, see enum above */ bool needToCalcCom; /**< Do we need to calculate the COM? (Not for group 0 or if only used as cylinder group) */ std::vector globalWeights; /**< Weights per atom set by the user and/or mass/friction coefficients, if empty all weights are equal */ /* Data modified only at init or at domain decomposition */ - gmx::LocalAtomSet atomSet; /**< Global to local atom set mapper */ - std::vector localWeights; /**< Weights for the local atoms */ - std::unique_ptr pbcAtomSet; /**< Keeps index of the pbc reference atom. - The stored LocalAtomSet consists of exactly one atom when pbc reference atom is required. - When no pbc refence atom is used, this pointer shall be null. */ + gmx::LocalAtomSet atomSet; /**< Global to local atom set mapper */ + std::vector localWeights; /**< Weights for the local atoms */ + std::unique_ptr pbcAtomSet; /**< Keeps index of the pbc reference atom. + The stored LocalAtomSet consists of exactly one atom when pbc reference atom is required. + When no pbc refence atom is used, this pointer shall be null. */ /* Data, potentially, changed at every pull call */ - real mwscale; /**< mass*weight scaling factor 1/sum w m */ - real wscale; /**< scaling factor for the weights: sum w m/sum w w m */ - real invtm; /**< inverse total mass of the group: 1/wscale sum w m */ - std::vector < gmx::BasicVector < double>> mdw; /**< mass*gradient(weight) for atoms */ - std::vector dv; /**< distance to the other group(s) along vec */ - dvec x; /**< COM before update */ - dvec xp; /**< COM after update before constraining */ + real mwscale; /**< mass*weight scaling factor 1/sum w m */ + real wscale; /**< scaling factor for the weights: sum w m/sum w w m */ + real invtm; /**< inverse total mass of the group: 1/wscale sum w m */ + std::vector> mdw; /**< mass*gradient(weight) for atoms */ + std::vector dv; /**< distance to the other group(s) along vec */ + dvec x; /**< COM before update */ + dvec xp; /**< COM after update before constraining */ dvec x_prev_step; /**< center of mass of the previous step */ }; /* Struct describing the instantaneous spatial layout of a pull coordinate */ struct PullCoordSpatialData { - dvec dr01; /* The direction vector of group 1 relative to group 0 */ - dvec dr23; /* The direction vector of group 3 relative to group 2 */ - dvec dr45; /* The direction vector of group 5 relative to group 4 */ - dvec vec; /* The pull direction */ - double vec_len; /* Length of vec for direction-relative */ - dvec ffrad; /* conversion factor from vec to radial force */ - double cyl_dev; /* The deviation from the reference position */ - dvec planevec_m; /* Normal of plane for groups 0, 1, 2, 3 for geometry dihedral */ - dvec planevec_n; /* Normal of plane for groups 2, 3, 4, 5 for geometry dihedral */ - - double value; /* The current value of the coordinate, units of nm or rad */ + dvec dr01; /* The direction vector of group 1 relative to group 0 */ + dvec dr23; /* The direction vector of group 3 relative to group 2 */ + dvec dr45; /* The direction vector of group 5 relative to group 4 */ + dvec vec; /* The pull direction */ + double vec_len; /* Length of vec for direction-relative */ + dvec ffrad; /* conversion factor from vec to radial force */ + double cyl_dev; /* The deviation from the reference position */ + dvec planevec_m; /* Normal of plane for groups 0, 1, 2, 3 for geometry dihedral */ + dvec planevec_n; /* Normal of plane for groups 2, 3, 4, 5 for geometry dihedral */ + + double value; /* The current value of the coordinate, units of nm or rad */ }; /* Struct with parameters and force evaluation local data for a pull coordinate */ struct pull_coord_work_t { /* Constructor */ - pull_coord_work_t(const t_pull_coord ¶ms) : + pull_coord_work_t(const t_pull_coord& params) : params(params), value_ref(0), spatialData(), @@ -143,16 +145,16 @@ struct pull_coord_work_t { } - const t_pull_coord params; /* Pull coordinate parameters */ + const t_pull_coord params; /* Pull coordinate parameters */ - double value_ref; /* The reference value, usually init+rate*t, units of nm or rad */ + double value_ref; /* The reference value, usually init+rate*t, units of nm or rad */ - PullCoordSpatialData spatialData; /* Data defining the current geometry */ + PullCoordSpatialData spatialData; /* Data defining the current geometry */ - double scalarForce; /* Scalar force for this cooordinate */ + double scalarForce; /* Scalar force for this cooordinate */ /* For external-potential coordinates only, for checking if a provider has been registered */ - bool bExternalPotentialProviderHasBeenRegistered; + bool bExternalPotentialProviderHasBeenRegistered; }; /* Struct for storing vectorial forces for a pull coordinate */ @@ -167,25 +169,25 @@ struct PullCoordVectorForces struct ComSums { /* For normal weighting */ - double sum_wm; /* Sum of weight*mass */ - double sum_wwm; /* Sum of weight*weight*mass */ - dvec sum_wmx; /* Sum of weight*mass*x */ - dvec sum_wmxp; /* Sum of weight*mass*xp */ + double sum_wm; /* Sum of weight*mass */ + double sum_wwm; /* Sum of weight*weight*mass */ + dvec sum_wmx; /* Sum of weight*mass*x */ + dvec sum_wmxp; /* Sum of weight*mass*xp */ /* For cosine weighting */ - double sum_cm; /* Sum of cos(x)*mass */ - double sum_sm; /* Sum of sin(x)*mass */ - double sum_ccm; /* Sum of cos(x)*cos(x)*mass */ - double sum_csm; /* Sum of cos(x)*sin(x)*mass */ - double sum_ssm; /* Sum of sin(x)*sin(x)*mass */ - double sum_cmp; /* Sum of cos(xp)*sin(xp)*mass */ - double sum_smp; /* Sum of sin(xp)*sin(xp)*mass */ + double sum_cm; /* Sum of cos(x)*mass */ + double sum_sm; /* Sum of sin(x)*mass */ + double sum_ccm; /* Sum of cos(x)*cos(x)*mass */ + double sum_csm; /* Sum of cos(x)*sin(x)*mass */ + double sum_ssm; /* Sum of sin(x)*sin(x)*mass */ + double sum_cmp; /* Sum of cos(xp)*sin(xp)*mass */ + double sum_smp; /* Sum of sin(xp)*sin(xp)*mass */ /* Dummy data to ensure adjacent elements in an array are separated * by a cache line size, max 128 bytes. * TODO: Replace this by some automated mechanism. */ - int dummy[32]; + int dummy[32]; }; /*! \brief The normal COM buffer needs 3 elements per group */ @@ -196,21 +198,21 @@ static constexpr int c_cylinderBufferStride = 9; struct pull_comm_t { - gmx_bool bParticipateAll; /* Do all ranks always participate in pulling? */ - gmx_bool bParticipate; /* Does our rank participate in pulling? */ + gmx_bool bParticipateAll; /* Do all ranks always participate in pulling? */ + gmx_bool bParticipate; /* Does our rank participate in pulling? */ #if GMX_MPI - MPI_Comm mpi_comm_com; /* Communicator for pulling */ + MPI_Comm mpi_comm_com; /* Communicator for pulling */ #endif - int nparticipate; /* The number of ranks participating */ - bool isMasterRank; /* Tells whether our rank is the master rank and thus should add the pull virial */ + int nparticipate; /* The number of ranks participating */ + bool isMasterRank; /* Tells whether our rank is the master rank and thus should add the pull virial */ - int64_t setup_count; /* The number of decomposition calls */ - int64_t must_count; /* The last count our rank needed to be part */ + int64_t setup_count; /* The number of decomposition calls */ + int64_t must_count; /* The last count our rank needed to be part */ /* Buffers for parallel reductions */ - std::vector pbcAtomBuffer; /* COM calculation buffer */ - std::vector < gmx::BasicVector < double>> comBuffer; /* COM calculation buffer */ - std::vector cylinderBuffer; /* cylinder ref. groups calculation buffer */ + std::vector pbcAtomBuffer; /* COM calculation buffer */ + std::vector> comBuffer; /* COM calculation buffer */ + std::vector cylinderBuffer; /* cylinder ref. groups calculation buffer */ }; // The COM pull force calculation data structure @@ -218,47 +220,47 @@ struct pull_comm_t struct pull_t { /* Global parameters */ - pull_params_t params; /* The pull parameters, from inputrec */ + pull_params_t params; /* The pull parameters, from inputrec */ - gmx_bool bPotential; /* Are there coordinates with potential? */ - gmx_bool bConstraint; /* Are there constrained coordinates? */ - gmx_bool bAngle; /* Are there angle geometry coordinates? */ + gmx_bool bPotential; /* Are there coordinates with potential? */ + gmx_bool bConstraint; /* Are there constrained coordinates? */ + gmx_bool bAngle; /* Are there angle geometry coordinates? */ - int ePBC; /* the boundary conditions */ - int npbcdim; /* do pbc in dims 0 <= dim < npbcdim */ - gmx_bool bRefAt; /* do we need reference atoms for a group COM ? */ - int cosdim; /* dimension for cosine weighting, -1 if none */ - gmx_bool bCylinder; /* Is group 0 a cylinder group? */ + int ePBC; /* the boundary conditions */ + int npbcdim; /* do pbc in dims 0 <= dim < npbcdim */ + gmx_bool bRefAt; /* do we need reference atoms for a group COM ? */ + int cosdim; /* dimension for cosine weighting, -1 if none */ + gmx_bool bCylinder; /* Is group 0 a cylinder group? */ /* Parameters + dynamic data for groups */ - std::vector group; /* The pull group param and work data */ - std::vector dyna; /* Dynamic groups for geom=cylinder */ + std::vector group; /* The pull group param and work data */ + std::vector dyna; /* Dynamic groups for geom=cylinder */ /* Parameters + dynamic data for coordinates */ - std::vector coord; /* The pull group param and work data */ + std::vector coord; /* The pull group param and work data */ /* Global dynamic data */ - gmx_bool bSetPBCatoms; /* Do we need to set x_pbc for the groups? */ + gmx_bool bSetPBCatoms; /* Do we need to set x_pbc for the groups? */ - int nthreads; /* Number of threads used by the pull code */ - std::vector comSums; /* Work array for summing for COM, 1 entry per thread */ + int nthreads; /* Number of threads used by the pull code */ + std::vector comSums; /* Work array for summing for COM, 1 entry per thread */ - pull_comm_t comm; /* Communication parameters, communicator and buffers */ + pull_comm_t comm; /* Communication parameters, communicator and buffers */ - FILE *out_x; /* Output file for pull data */ - FILE *out_f; /* Output file for pull data */ + FILE* out_x; /* Output file for pull data */ + FILE* out_f; /* Output file for pull data */ - bool bXOutAverage; /* Output average pull coordinates */ - bool bFOutAverage; /* Output average pull forces */ + bool bXOutAverage; /* Output average pull coordinates */ + bool bFOutAverage; /* Output average pull forces */ - PullHistory *coordForceHistory; /* Pull coordinate and force history */ + PullHistory* coordForceHistory; /* Pull coordinate and force history */ /* The number of coordinates using an external potential */ - int numCoordinatesWithExternalPotential; + int numCoordinatesWithExternalPotential; /* Counter for checking external potential registration */ - int numUnregisteredExternalPotentials; + int numUnregisteredExternalPotentials; /* */ - int numExternalPotentialsStillToBeAppliedThisStep; + int numExternalPotentialsStillToBeAppliedThisStep; }; /*! \brief Copies the pull group COM of the previous step from the checkpoint state to the pull state @@ -266,14 +268,14 @@ struct pull_t * \param[in] pull The COM pull force calculation data structure * \param[in] state The global state container */ -void setPrevStepPullComFromState(struct pull_t *pull, const t_state *state); +void setPrevStepPullComFromState(struct pull_t* pull, const t_state* state); /*! \brief Resizes the vector, in the state container, containing the COMs from the previous step * * \param[in] state The global state container * \param[in] pull The COM pull force calculation data structure */ -void allocStatePrevStepPullCom(t_state *state, const pull_t *pull); +void allocStatePrevStepPullCom(t_state* state, const pull_t* pull); #endif diff --git a/src/gromacs/pulling/pull_rotation.cpp b/src/gromacs/pulling/pull_rotation.cpp index 742b22c6a9..5c831c0166 100644 --- a/src/gromacs/pulling/pull_rotation.cpp +++ b/src/gromacs/pulling/pull_rotation.cpp @@ -78,10 +78,10 @@ #include "gromacs/utility/pleasecite.h" #include "gromacs/utility/smalloc.h" -static char const *RotStr = {"Enforced rotation:"}; +static char const* RotStr = { "Enforced rotation:" }; /* Set the minimum weight for the determination of the slab centers */ -#define WEIGHT_MIN (10*GMX_FLOAT_MIN) +#define WEIGHT_MIN (10 * GMX_FLOAT_MIN) //! Helper structure for sorting positions along rotation vector struct sort_along_vec_t @@ -89,7 +89,7 @@ struct sort_along_vec_t //! Projection of xc on the rotation vector real xcproj; //! Index of xc - int ind; + int ind; //! Mass real m; //! Position @@ -103,17 +103,17 @@ struct sort_along_vec_t struct gmx_slabdata { //! Number of atoms belonging to this slab - int nat; + int nat; /*! \brief The positions belonging to this slab. * * In general, this should be all positions of the whole * rotation group, but we leave those away that have a small * enough weight. */ - rvec *x; + rvec* x; //! Same for reference - rvec *ref; + rvec* ref; //! The weight for each atom - real *weight; + real* weight; }; @@ -124,11 +124,11 @@ struct gmx_potfit * * The optimum fit is determined as the angle for with the * potential is minimal. */ - real *degangle; + real* degangle; //! Potential for the different angles - real *V; + real* V; //! Rotation matrix corresponding to the angles - matrix *rotmat; + matrix* rotmat; }; @@ -136,50 +136,50 @@ struct gmx_potfit struct gmx_enfrotgrp { //! Input parameters for this group - const t_rotgrp *rotg = nullptr; + const t_rotgrp* rotg = nullptr; //! Index of this group within the set of groups - int groupIndex; + int groupIndex; //! Rotation angle in degrees - real degangle; + real degangle; //! Rotation matrix - matrix rotmat; + matrix rotmat; //! The atoms subject to enforced rotation std::unique_ptr atomSet; //! The normalized rotation vector - rvec vec; + rvec vec; //! Rotation potential for this rotation group - real V; + real V; //! Array to store the forces on the local atoms resulting from enforced rotation potential - rvec *f_rot_loc; + rvec* f_rot_loc; /* Collective coordinates for the whole rotation group */ //! Length of each x_rotref vector after x_rotref has been put into origin - real *xc_ref_length; + real* xc_ref_length; //! Center of the rotation group positions, may be mass weighted - rvec xc_center; + rvec xc_center; //! Center of the rotation group reference positions - rvec xc_ref_center; + rvec xc_ref_center; //! Current (collective) positions - rvec *xc; + rvec* xc; //! Current (collective) shifts - ivec *xc_shifts; + ivec* xc_shifts; //! Extra shifts since last DD step - ivec *xc_eshifts; + ivec* xc_eshifts; //! Old (collective) positions - rvec *xc_old; + rvec* xc_old; //! Normalized form of the current positions - rvec *xc_norm; + rvec* xc_norm; //! Reference positions (sorted in the same order as xc when sorted) - rvec *xc_ref_sorted; + rvec* xc_ref_sorted; //! Where is a position found after sorting? - int *xc_sortind; + int* xc_sortind; //! Collective masses - real *mc; + real* mc; //! Collective masses sorted - real *mc_sorted; + real* mc_sorted; //! one over the total mass of the rotation group - real invmass; + real invmass; //! Torque in the direction of rotation vector real torque_v; @@ -187,53 +187,53 @@ struct gmx_enfrotgrp real angle_v; /* Fixed rotation only */ //! Weights for angle determination - real weight_v; + real weight_v; //! Local reference coords, correctly rotated - rvec *xr_loc; + rvec* xr_loc; //! Local current coords, correct PBC image - rvec *x_loc_pbc; + rvec* x_loc_pbc; //! Masses of the current local atoms - real *m_loc; + real* m_loc; /* Flexible rotation only */ //! For this many slabs memory is allocated - int nslabs_alloc; + int nslabs_alloc; //! Lowermost slab for that the calculation needs to be performed at a given time step - int slab_first; + int slab_first; //! Uppermost slab ... - int slab_last; + int slab_last; //! First slab for which ref. center is stored - int slab_first_ref; + int slab_first_ref; //! Last ... - int slab_last_ref; + int slab_last_ref; //! Slab buffer region around reference slabs - int slab_buffer; + int slab_buffer; //! First relevant atom for a slab - int *firstatom; + int* firstatom; //! Last relevant atom for a slab - int *lastatom; + int* lastatom; //! Gaussian-weighted slab center - rvec *slab_center; + rvec* slab_center; //! Gaussian-weighted slab center for the reference positions - rvec *slab_center_ref; + rvec* slab_center_ref; //! Sum of gaussian weights in a slab - real *slab_weights; + real* slab_weights; //! Torque T = r x f for each slab. torque_v = m.v = angular momentum in the direction of v - real *slab_torque_v; + real* slab_torque_v; //! min_gaussian from t_rotgrp is the minimum value the gaussian must have so that the force is actually evaluated. max_beta is just another way to put it - real max_beta; + real max_beta; //! Precalculated gaussians for a single atom - real *gn_atom; + real* gn_atom; //! Tells to which slab each precalculated gaussian belongs - int *gn_slabind; + int* gn_slabind; //! Inner sum of the flexible2 potential per slab; this is precalculated for optimization reasons - rvec *slab_innersumvec; + rvec* slab_innersumvec; //! Holds atom positions and gaussian weights of atoms belonging to a slab - gmx_slabdata *slab_data; + gmx_slabdata* slab_data; /* For potential fits with varying angle: */ //! Used for fit type 'potential' - gmx_potfit *PotAngleFit; + gmx_potfit* PotAngleFit; }; @@ -241,37 +241,37 @@ struct gmx_enfrotgrp struct gmx_enfrot { //! Input parameters. - const t_rot *rot = nullptr; + const t_rot* rot = nullptr; //! Output period for main rotation outfile - int nstrout; + int nstrout; //! Output period for per-slab data - int nstsout; + int nstsout; //! Output file for rotation data - FILE *out_rot = nullptr; + FILE* out_rot = nullptr; //! Output file for torque data - FILE *out_torque = nullptr; + FILE* out_torque = nullptr; //! Output file for slab angles for flexible type - FILE *out_angles = nullptr; + FILE* out_angles = nullptr; //! Output file for slab centers - FILE *out_slabs = nullptr; + FILE* out_slabs = nullptr; //! Allocation size of buf - int bufsize = 0; + int bufsize = 0; //! Coordinate buffer variable for sorting - rvec *xbuf = nullptr; + rvec* xbuf = nullptr; //! Masses buffer variable for sorting - real *mbuf = nullptr; + real* mbuf = nullptr; //! Buffer variable needed for position sorting - sort_along_vec_t *data = nullptr; + sort_along_vec_t* data = nullptr; //! MPI buffer - real *mpi_inbuf = nullptr; + real* mpi_inbuf = nullptr; //! MPI buffer - real *mpi_outbuf = nullptr; + real* mpi_outbuf = nullptr; //! Allocation size of in & outbuf - int mpi_bufsize = 0; + int mpi_bufsize = 0; //! If true, append output files - gmx_bool restartWithAppending = false; + gmx_bool restartWithAppending = false; //! Used to skip first output when appending to avoid duplicate entries in rotation outfiles - gmx_bool bOut = false; + gmx_bool bOut = false; //! Stores working data per group std::vector enfrotgrp; ~gmx_enfrot(); @@ -304,42 +304,51 @@ extern template LocalAtomSet LocalAtomSetManager::add(ArrayRefenforcedRotation_; } -} // namespace gmx +} // namespace gmx /* Activate output of forces for correctness checks */ /* #define PRINT_FORCES */ #ifdef PRINT_FORCES -#define PRINT_FORCE_J fprintf(stderr, "f%d = %15.8f %15.8f %15.8f\n", erg->xc_ref_ind[j], erg->f_rot_loc[j][XX], erg->f_rot_loc[j][YY], erg->f_rot_loc[j][ZZ]); -#define PRINT_POT_TAU if (MASTER(cr)) { \ - fprintf(stderr, "potential = %15.8f\n" "torque = %15.8f\n", erg->V, erg->torque_v); \ -} +# define PRINT_FORCE_J \ + fprintf(stderr, "f%d = %15.8f %15.8f %15.8f\n", erg->xc_ref_ind[j], erg->f_rot_loc[j][XX], \ + erg->f_rot_loc[j][YY], erg->f_rot_loc[j][ZZ]); +# define PRINT_POT_TAU \ + if (MASTER(cr)) \ + { \ + fprintf(stderr, \ + "potential = %15.8f\n" \ + "torque = %15.8f\n", \ + erg->V, erg->torque_v); \ + } #else -#define PRINT_FORCE_J -#define PRINT_POT_TAU +# define PRINT_FORCE_J +# define PRINT_POT_TAU #endif /* Shortcuts for often used queries */ -#define ISFLEX(rg) ( ((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) || ((rg)->eType == erotgFLEX2T) ) -#define ISCOLL(rg) ( ((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) || ((rg)->eType == erotgFLEX2T) || ((rg)->eType == erotgRMPF) || ((rg)->eType == erotgRM2PF) ) +#define ISFLEX(rg) \ + (((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) \ + || ((rg)->eType == erotgFLEX2T)) +#define ISCOLL(rg) \ + (((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) \ + || ((rg)->eType == erotgFLEX2T) || ((rg)->eType == erotgRMPF) || ((rg)->eType == erotgRM2PF)) /* Does any of the rotation groups use slab decomposition? */ -static gmx_bool HaveFlexibleGroups(const t_rot *rot) +static gmx_bool HaveFlexibleGroups(const t_rot* rot) { for (int g = 0; g < rot->ngrp; g++) { @@ -355,7 +364,7 @@ static gmx_bool HaveFlexibleGroups(const t_rot *rot) /* Is for any group the fit angle determined by finding the minimum of the * rotation potential? */ -static gmx_bool HavePotFitGroups(const t_rot *rot) +static gmx_bool HavePotFitGroups(const t_rot* rot) { for (int g = 0; g < rot->ngrp; g++) { @@ -399,12 +408,12 @@ static void free_square_matrix(double** mat, int dim) /* Return the angle for which the potential is minimal */ -static real get_fitangle(const gmx_enfrotgrp *erg) +static real get_fitangle(const gmx_enfrotgrp* erg) { - int i; - real fitangle = -999.9; - real pot_min = GMX_FLOAT_MAX; - gmx_potfit *fit; + int i; + real fitangle = -999.9; + real pot_min = GMX_FLOAT_MAX; + gmx_potfit* fit; fit = erg->PotAngleFit; @@ -423,40 +432,41 @@ static real get_fitangle(const gmx_enfrotgrp *erg) /* Reduce potential angle fit data for this group at this time step? */ -static inline gmx_bool bPotAngle(const gmx_enfrot *er, const t_rotgrp *rotg, int64_t step) +static inline gmx_bool bPotAngle(const gmx_enfrot* er, const t_rotgrp* rotg, int64_t step) { - return ( (erotgFitPOT == rotg->eFittype) && (do_per_step(step, er->nstsout) || do_per_step(step, er->nstrout)) ); + return ((erotgFitPOT == rotg->eFittype) + && (do_per_step(step, er->nstsout) || do_per_step(step, er->nstrout))); } /* Reduce slab torqe data for this group at this time step? */ -static inline gmx_bool bSlabTau(const gmx_enfrot *er, const t_rotgrp *rotg, int64_t step) +static inline gmx_bool bSlabTau(const gmx_enfrot* er, const t_rotgrp* rotg, int64_t step) { - return ( (ISFLEX(rotg)) && do_per_step(step, er->nstsout) ); + return ((ISFLEX(rotg)) && do_per_step(step, er->nstsout)); } /* Output rotation energy, torques, etc. for each rotation group */ -static void reduce_output(const t_commrec *cr, - gmx_enfrot *er, real t, int64_t step) +static void reduce_output(const t_commrec* cr, gmx_enfrot* er, real t, int64_t step) { - int i, islab, nslabs = 0; - int count; /* MPI element counter */ - real fitangle; - gmx_bool bFlex; + int i, islab, nslabs = 0; + int count; /* MPI element counter */ + real fitangle; + gmx_bool bFlex; /* Fill the MPI buffer with stuff to reduce. If items are added for reduction * here, the MPI buffer size has to be enlarged also in calc_mpi_bufsize() */ if (PAR(cr)) { count = 0; - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - const t_rotgrp *rotg = erg->rotg; + gmx_enfrotgrp* erg = &ergRef; + const t_rotgrp* rotg = erg->rotg; nslabs = erg->slab_last - erg->slab_first + 1; er->mpi_inbuf[count++] = erg->V; er->mpi_inbuf[count++] = erg->torque_v; er->mpi_inbuf[count++] = erg->angle_v; - er->mpi_inbuf[count++] = erg->weight_v; /* weights are not needed for flex types, but this is just a single value */ + er->mpi_inbuf[count++] = + erg->weight_v; /* weights are not needed for flex types, but this is just a single value */ if (bPotAngle(er, rotg, step)) { @@ -479,22 +489,23 @@ static void reduce_output(const t_commrec *cr, } #if GMX_MPI - MPI_Reduce(er->mpi_inbuf, er->mpi_outbuf, count, GMX_MPI_REAL, MPI_SUM, MASTERRANK(cr), cr->mpi_comm_mygroup); + MPI_Reduce(er->mpi_inbuf, er->mpi_outbuf, count, GMX_MPI_REAL, MPI_SUM, MASTERRANK(cr), + cr->mpi_comm_mygroup); #endif /* Copy back the reduced data from the buffer on the master */ if (MASTER(cr)) { count = 0; - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - const t_rotgrp *rotg = erg->rotg; - nslabs = erg->slab_last - erg->slab_first + 1; - erg->V = er->mpi_outbuf[count++]; - erg->torque_v = er->mpi_outbuf[count++]; - erg->angle_v = er->mpi_outbuf[count++]; - erg->weight_v = er->mpi_outbuf[count++]; + gmx_enfrotgrp* erg = &ergRef; + const t_rotgrp* rotg = erg->rotg; + nslabs = erg->slab_last - erg->slab_first + 1; + erg->V = er->mpi_outbuf[count++]; + erg->torque_v = er->mpi_outbuf[count++]; + erg->angle_v = er->mpi_outbuf[count++]; + erg->weight_v = er->mpi_outbuf[count++]; if (bPotAngle(er, rotg, step)) { @@ -518,14 +529,14 @@ static void reduce_output(const t_commrec *cr, if (MASTER(cr)) { /* Angle and torque for each rotation group */ - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - const t_rotgrp *rotg = erg->rotg; - bFlex = ISFLEX(rotg); + gmx_enfrotgrp* erg = &ergRef; + const t_rotgrp* rotg = erg->rotg; + bFlex = ISFLEX(rotg); /* Output to main rotation output file: */ - if (do_per_step(step, er->nstrout) ) + if (do_per_step(step, er->nstrout)) { if (erotgFitPOT == rotg->eFittype) { @@ -539,7 +550,7 @@ static void reduce_output(const t_commrec *cr, } else { - fitangle = (erg->angle_v/erg->weight_v)*180.0*M_1_PI; + fitangle = (erg->angle_v / erg->weight_v) * 180.0 * M_1_PI; } } fprintf(er->out_rot, "%12.4f", fitangle); @@ -547,7 +558,7 @@ static void reduce_output(const t_commrec *cr, fprintf(er->out_rot, "%12.3e", erg->V); } - if (do_per_step(step, er->nstsout) ) + if (do_per_step(step, er->nstsout)) { /* Output to torque log file: */ if (bFlex) @@ -555,7 +566,7 @@ static void reduce_output(const t_commrec *cr, fprintf(er->out_torque, "%12.3e%6d", t, erg->groupIndex); for (int i = erg->slab_first; i <= erg->slab_last; i++) { - islab = i - erg->slab_first; /* slab index */ + islab = i - erg->slab_first; /* slab index */ /* Only output if enough weight is in slab */ if (erg->slab_weights[islab] > rotg->min_gaussian) { @@ -578,7 +589,7 @@ static void reduce_output(const t_commrec *cr, } } } - if (do_per_step(step, er->nstrout) ) + if (do_per_step(step, er->nstrout)) { fprintf(er->out_rot, "\n"); } @@ -588,19 +599,18 @@ static void reduce_output(const t_commrec *cr, /* Add the forces from enforced rotation potential to the local forces. * Should be called after the SR forces have been evaluated */ -real add_rot_forces(gmx_enfrot *er, - rvec f[], const t_commrec *cr, int64_t step, real t) +real add_rot_forces(gmx_enfrot* er, rvec f[], const t_commrec* cr, int64_t step, real t) { - real Vrot = 0.0; /* If more than one rotation group is present, Vrot - assembles the local parts from all groups */ + real Vrot = 0.0; /* If more than one rotation group is present, Vrot + assembles the local parts from all groups */ /* Loop over enforced rotation groups (usually 1, though) * Apply the forces from rotation potentials */ - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - Vrot += erg->V; /* add the local parts from the nodes */ - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); + gmx_enfrotgrp* erg = &ergRef; + Vrot += erg->V; /* add the local parts from the nodes */ + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); for (gmx::index l = 0; l < localRotationGroupIndex.ssize(); l++) { /* Get the right index of the local force */ @@ -612,7 +622,7 @@ real add_rot_forces(gmx_enfrot *er, /* Reduce energy,torque, angles etc. to get the sum values (per rotation group) * on the master and output these values to file. */ - if ( (do_per_step(step, er->nstrout) || do_per_step(step, er->nstsout)) && er->bOut) + if ((do_per_step(step, er->nstrout) || do_per_step(step, er->nstsout)) && er->bOut) { reduce_output(cr, er, t, step); } @@ -628,7 +638,7 @@ real add_rot_forces(gmx_enfrot *er, /* The Gaussian norm is chosen such that the sum of the gaussian functions * over the slabs is approximately 1.0 everywhere */ -#define GAUSS_NORM 0.569917543430618 +#define GAUSS_NORM 0.569917543430618 /* Calculate the maximum beta that leads to a gaussian larger min_gaussian, @@ -651,48 +661,47 @@ static double calc_beta_max(real min_gaussian, real slab_dist) } /* Define the sigma value */ - sigma = 0.7*slab_dist; + sigma = 0.7 * slab_dist; /* Calculate the argument for the logarithm and check that the log() result is negative or 0 */ - arg = min_gaussian/GAUSS_NORM; + arg = min_gaussian / GAUSS_NORM; if (arg > 1.0) { gmx_fatal(FARGS, "min_gaussian of flexible rotation groups must be <%g", GAUSS_NORM); } - return std::sqrt(-2.0*sigma*sigma*log(min_gaussian/GAUSS_NORM)); + return std::sqrt(-2.0 * sigma * sigma * log(min_gaussian / GAUSS_NORM)); } -static inline real calc_beta(rvec curr_x, const gmx_enfrotgrp *erg, int n) +static inline real calc_beta(rvec curr_x, const gmx_enfrotgrp* erg, int n) { return iprod(curr_x, erg->vec) - erg->rotg->slab_dist * n; } -static inline real gaussian_weight(rvec curr_x, const gmx_enfrotgrp *erg, int n) +static inline real gaussian_weight(rvec curr_x, const gmx_enfrotgrp* erg, int n) { const real norm = GAUSS_NORM; real sigma; /* Define the sigma value */ - sigma = 0.7*erg->rotg->slab_dist; + sigma = 0.7 * erg->rotg->slab_dist; /* Calculate the Gaussian value of slab n for position curr_x */ - return norm * exp( -0.5 * gmx::square( calc_beta(curr_x, erg, n)/sigma ) ); + return norm * exp(-0.5 * gmx::square(calc_beta(curr_x, erg, n) / sigma)); } /* Returns the weight in a single slab, also calculates the Gaussian- and mass- * weighted sum of positions for that slab */ -static real get_slab_weight(int j, const gmx_enfrotgrp *erg, - rvec xc[], const real mc[], rvec *x_weighted_sum) +static real get_slab_weight(int j, const gmx_enfrotgrp* erg, rvec xc[], const real mc[], rvec* x_weighted_sum) { - rvec curr_x; /* The position of an atom */ - rvec curr_x_weighted; /* The gaussian-weighted position */ - real gaussian; /* A single gaussian weight */ - real wgauss; /* gaussian times current mass */ - real slabweight = 0.0; /* The sum of weights in the slab */ + rvec curr_x; /* The position of an atom */ + rvec curr_x_weighted; /* The gaussian-weighted position */ + real gaussian; /* A single gaussian weight */ + real wgauss; /* gaussian times current mass */ + real slabweight = 0.0; /* The sum of weights in the slab */ clear_rvec(*x_weighted_sum); @@ -705,35 +714,35 @@ static real get_slab_weight(int j, const gmx_enfrotgrp *erg, svmul(wgauss, curr_x, curr_x_weighted); rvec_add(*x_weighted_sum, curr_x_weighted, *x_weighted_sum); slabweight += wgauss; - } /* END of loop over rotation group atoms */ + } /* END of loop over rotation group atoms */ return slabweight; } -static void get_slab_centers( - gmx_enfrotgrp *erg, /* Enforced rotation group working data */ - rvec *xc, /* The rotation group positions; will - typically be enfrotgrp->xc, but at first call - it is enfrotgrp->xc_ref */ - real *mc, /* The masses of the rotation group atoms */ - real time, /* Used for output only */ - FILE *out_slabs, /* For outputting center per slab information */ - gmx_bool bOutStep, /* Is this an output step? */ - gmx_bool bReference) /* If this routine is called from - init_rot_group we need to store - the reference slab centers */ +static void get_slab_centers(gmx_enfrotgrp* erg, /* Enforced rotation group working data */ + rvec* xc, /* The rotation group positions; will + typically be enfrotgrp->xc, but at first call + it is enfrotgrp->xc_ref */ + real* mc, /* The masses of the rotation group atoms */ + real time, /* Used for output only */ + FILE* out_slabs, /* For outputting center per slab information */ + gmx_bool bOutStep, /* Is this an output step? */ + gmx_bool bReference) /* If this routine is called from + init_rot_group we need to store + the reference slab centers */ { /* Loop over slabs */ for (int j = erg->slab_first; j <= erg->slab_last; j++) { - int slabIndex = j - erg->slab_first; + int slabIndex = j - erg->slab_first; erg->slab_weights[slabIndex] = get_slab_weight(j, erg, xc, mc, &erg->slab_center[slabIndex]); /* We can do the calculations ONLY if there is weight in the slab! */ if (erg->slab_weights[slabIndex] > WEIGHT_MIN) { - svmul(1.0/erg->slab_weights[slabIndex], erg->slab_center[slabIndex], erg->slab_center[slabIndex]); + svmul(1.0 / erg->slab_weights[slabIndex], erg->slab_center[slabIndex], + erg->slab_center[slabIndex]); } else { @@ -750,24 +759,23 @@ static void get_slab_centers( } /* END of loop over slabs */ /* Output on the master */ - if ( (nullptr != out_slabs) && bOutStep) + if ((nullptr != out_slabs) && bOutStep) { fprintf(out_slabs, "%12.3e%6d", time, erg->groupIndex); for (int j = erg->slab_first; j <= erg->slab_last; j++) { int slabIndex = j - erg->slab_first; - fprintf(out_slabs, "%6d%12.3e%12.3e%12.3e", - j, erg->slab_center[slabIndex][XX], erg->slab_center[slabIndex][YY], erg->slab_center[slabIndex][ZZ]); + fprintf(out_slabs, "%6d%12.3e%12.3e%12.3e", j, erg->slab_center[slabIndex][XX], + erg->slab_center[slabIndex][YY], erg->slab_center[slabIndex][ZZ]); } fprintf(out_slabs, "\n"); } } -static void calc_rotmat( - const rvec vec, - real degangle, /* Angle alpha of rotation at time t in degrees */ - matrix rotmat) /* Rotation matrix */ +static void calc_rotmat(const rvec vec, + real degangle, /* Angle alpha of rotation at time t in degrees */ + matrix rotmat) /* Rotation matrix */ { real radangle; /* Rotation angle in radians */ real cosa; /* cosine alpha */ @@ -777,30 +785,30 @@ static void calc_rotmat( rvec rot_vec; /* Rotate around rot_vec ... */ - radangle = degangle * M_PI/180.0; - copy_rvec(vec, rot_vec ); + radangle = degangle * M_PI / 180.0; + copy_rvec(vec, rot_vec); /* Precompute some variables: */ cosa = cos(radangle); sina = sin(radangle); OMcosa = 1.0 - cosa; - dumxy = rot_vec[XX]*rot_vec[YY]*OMcosa; - dumxz = rot_vec[XX]*rot_vec[ZZ]*OMcosa; - dumyz = rot_vec[YY]*rot_vec[ZZ]*OMcosa; + dumxy = rot_vec[XX] * rot_vec[YY] * OMcosa; + dumxz = rot_vec[XX] * rot_vec[ZZ] * OMcosa; + dumyz = rot_vec[YY] * rot_vec[ZZ] * OMcosa; /* Construct the rotation matrix for this rotation group: */ /* 1st column: */ - rotmat[XX][XX] = cosa + rot_vec[XX]*rot_vec[XX]*OMcosa; - rotmat[YY][XX] = dumxy + rot_vec[ZZ]*sina; - rotmat[ZZ][XX] = dumxz - rot_vec[YY]*sina; + rotmat[XX][XX] = cosa + rot_vec[XX] * rot_vec[XX] * OMcosa; + rotmat[YY][XX] = dumxy + rot_vec[ZZ] * sina; + rotmat[ZZ][XX] = dumxz - rot_vec[YY] * sina; /* 2nd column: */ - rotmat[XX][YY] = dumxy - rot_vec[ZZ]*sina; - rotmat[YY][YY] = cosa + rot_vec[YY]*rot_vec[YY]*OMcosa; - rotmat[ZZ][YY] = dumyz + rot_vec[XX]*sina; + rotmat[XX][YY] = dumxy - rot_vec[ZZ] * sina; + rotmat[YY][YY] = cosa + rot_vec[YY] * rot_vec[YY] * OMcosa; + rotmat[ZZ][YY] = dumyz + rot_vec[XX] * sina; /* 3rd column: */ - rotmat[XX][ZZ] = dumxz + rot_vec[YY]*sina; - rotmat[YY][ZZ] = dumyz - rot_vec[XX]*sina; - rotmat[ZZ][ZZ] = cosa + rot_vec[ZZ]*rot_vec[ZZ]*OMcosa; + rotmat[XX][ZZ] = dumxz + rot_vec[YY] * sina; + rotmat[YY][ZZ] = dumyz - rot_vec[XX] * sina; + rotmat[ZZ][ZZ] = cosa + rot_vec[ZZ] * rot_vec[ZZ] * OMcosa; #ifdef PRINTMATRIX int iii, jjj; @@ -809,7 +817,7 @@ static void calc_rotmat( { for (jjj = 0; jjj < 3; jjj++) { - fprintf(stderr, " %10.8f ", rotmat[iii][jjj]); + fprintf(stderr, " %10.8f ", rotmat[iii][jjj]); } fprintf(stderr, "\n"); } @@ -819,9 +827,9 @@ static void calc_rotmat( /* Calculates torque on the rotation axis tau = position x force */ static inline real torque(const rvec rotvec, /* rotation vector; MUST be normalized! */ - rvec force, /* force */ - rvec x, /* position of atom on which the force acts */ - rvec pivot) /* pivot point of rotation axis */ + rvec force, /* force */ + rvec x, /* position of atom on which the force acts */ + rvec pivot) /* pivot point of rotation axis */ { rvec vectmp, tau; @@ -838,38 +846,37 @@ static inline real torque(const rvec rotvec, /* rotation vector; MUST be normali /* Right-aligned output of value with standard width */ -static void print_aligned(FILE *fp, char const *str) +static void print_aligned(FILE* fp, char const* str) { fprintf(fp, "%12s", str); } /* Right-aligned output of value with standard short width */ -static void print_aligned_short(FILE *fp, char const *str) +static void print_aligned_short(FILE* fp, char const* str) { fprintf(fp, "%6s", str); } -static FILE *open_output_file(const char *fn, int steps, const char what[]) +static FILE* open_output_file(const char* fn, int steps, const char what[]) { - FILE *fp; + FILE* fp; fp = gmx_ffopen(fn, "w"); - fprintf(fp, "# Output of %s is written in intervals of %d time step%s.\n#\n", - what, steps, steps > 1 ? "s" : ""); + fprintf(fp, "# Output of %s is written in intervals of %d time step%s.\n#\n", what, steps, + steps > 1 ? "s" : ""); return fp; } /* Open output file for slab center data. Call on master only */ -static FILE *open_slab_out(const char *fn, - gmx_enfrot *er) +static FILE* open_slab_out(const char* fn, gmx_enfrot* er) { - FILE *fp; + FILE* fp; if (er->restartWithAppending) { @@ -879,13 +886,13 @@ static FILE *open_slab_out(const char *fn, { fp = open_output_file(fn, er->nstsout, "gaussian weighted slab centers"); - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; + gmx_enfrotgrp* erg = &ergRef; if (ISFLEX(erg->rotg)) { - fprintf(fp, "# Rotation group %d (%s), slab distance %f nm, %s.\n", - erg->groupIndex, erotg_names[erg->rotg->eType], erg->rotg->slab_dist, + fprintf(fp, "# Rotation group %d (%s), slab distance %f nm, %s.\n", erg->groupIndex, + erotg_names[erg->rotg->eType], erg->rotg->slab_dist, erg->rotg->bMassW ? "centers of mass" : "geometrical centers"); } } @@ -912,7 +919,7 @@ static FILE *open_slab_out(const char *fn, /* Adds 'buf' to 'str' */ -static void add_to_string(char **str, char *buf) +static void add_to_string(char** str, char* buf) { int len; @@ -923,7 +930,7 @@ static void add_to_string(char **str, char *buf) } -static void add_to_string_aligned(char **str, char *buf) +static void add_to_string_aligned(char** str, char* buf) { char buf_aligned[STRLEN]; @@ -934,17 +941,15 @@ static void add_to_string_aligned(char **str, char *buf) /* Open output file and print some general information about the rotation groups. * Call on master only */ -static FILE *open_rot_out(const char *fn, - const gmx_output_env_t *oenv, - gmx_enfrot *er) -{ - FILE *fp; - int nsets; - const char **setname; - char buf[50], buf2[75]; - gmx_bool bFlex; - char *LegendStr = nullptr; - const t_rot *rot = er->rot; +static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfrot* er) +{ + FILE* fp; + int nsets; + const char** setname; + char buf[50], buf2[75]; + gmx_bool bFlex; + char* LegendStr = nullptr; + const t_rot* rot = er->rot; if (er->restartWithAppending) { @@ -952,28 +957,39 @@ static FILE *open_rot_out(const char *fn, } else { - fp = xvgropen(fn, "Rotation angles and energy", "Time (ps)", "angles (degrees) and energies (kJ/mol)", oenv); - fprintf(fp, "# Output of enforced rotation data is written in intervals of %d time step%s.\n#\n", er->nstrout, er->nstrout > 1 ? "s" : ""); - fprintf(fp, "# The scalar tau is the torque (kJ/mol) in the direction of the rotation vector v.\n"); + fp = xvgropen(fn, "Rotation angles and energy", "Time (ps)", + "angles (degrees) and energies (kJ/mol)", oenv); + fprintf(fp, + "# Output of enforced rotation data is written in intervals of %d time " + "step%s.\n#\n", + er->nstrout, er->nstrout > 1 ? "s" : ""); + fprintf(fp, + "# The scalar tau is the torque (kJ/mol) in the direction of the rotation vector " + "v.\n"); fprintf(fp, "# To obtain the vectorial torque, multiply tau with the group's rot-vec.\n"); - fprintf(fp, "# For flexible groups, tau(t,n) from all slabs n have been summed in a single value tau(t) here.\n"); + fprintf(fp, + "# For flexible groups, tau(t,n) from all slabs n have been summed in a single " + "value tau(t) here.\n"); fprintf(fp, "# The torques tau(t,n) are found in the rottorque.log (-rt) output file\n"); for (int g = 0; g < rot->ngrp; g++) { - const t_rotgrp *rotg = &rot->grp[g]; - const gmx_enfrotgrp *erg = &er->enfrotgrp[g]; - bFlex = ISFLEX(rotg); + const t_rotgrp* rotg = &rot->grp[g]; + const gmx_enfrotgrp* erg = &er->enfrotgrp[g]; + bFlex = ISFLEX(rotg); fprintf(fp, "#\n"); fprintf(fp, "# ROTATION GROUP %d, potential type '%s':\n", g, erotg_names[rotg->eType]); fprintf(fp, "# rot-massw%d %s\n", g, yesno_names[rotg->bMassW]); - fprintf(fp, "# rot-vec%d %12.5e %12.5e %12.5e\n", g, erg->vec[XX], erg->vec[YY], erg->vec[ZZ]); + fprintf(fp, "# rot-vec%d %12.5e %12.5e %12.5e\n", g, erg->vec[XX], + erg->vec[YY], erg->vec[ZZ]); fprintf(fp, "# rot-rate%d %12.5e degrees/ps\n", g, rotg->rate); fprintf(fp, "# rot-k%d %12.5e kJ/(mol*nm^2)\n", g, rotg->k); - if (rotg->eType == erotgISO || rotg->eType == erotgPM || rotg->eType == erotgRM || rotg->eType == erotgRM2) + if (rotg->eType == erotgISO || rotg->eType == erotgPM || rotg->eType == erotgRM + || rotg->eType == erotgRM2) { - fprintf(fp, "# rot-pivot%d %12.5e %12.5e %12.5e nm\n", g, rotg->pivot[XX], rotg->pivot[YY], rotg->pivot[ZZ]); + fprintf(fp, "# rot-pivot%d %12.5e %12.5e %12.5e nm\n", g, rotg->pivot[XX], + rotg->pivot[YY], rotg->pivot[ZZ]); } if (bFlex) @@ -983,28 +999,37 @@ static FILE *open_rot_out(const char *fn, } /* Output the centers of the rotation groups for the pivot-free potentials */ - if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF) || (rotg->eType == erotgRMPF) || (rotg->eType == erotgRM2PF - || (rotg->eType == erotgFLEXT) || (rotg->eType == erotgFLEX2T)) ) + if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF) || (rotg->eType == erotgRMPF) + || (rotg->eType == erotgRM2PF || (rotg->eType == erotgFLEXT) || (rotg->eType == erotgFLEX2T))) { fprintf(fp, "# ref. grp. %d center %12.5e %12.5e %12.5e\n", g, erg->xc_ref_center[XX], erg->xc_ref_center[YY], erg->xc_ref_center[ZZ]); - fprintf(fp, "# grp. %d init.center %12.5e %12.5e %12.5e\n", g, - erg->xc_center[XX], erg->xc_center[YY], erg->xc_center[ZZ]); + fprintf(fp, "# grp. %d init.center %12.5e %12.5e %12.5e\n", g, erg->xc_center[XX], + erg->xc_center[YY], erg->xc_center[ZZ]); } - if ( (rotg->eType == erotgRM2) || (rotg->eType == erotgFLEX2) || (rotg->eType == erotgFLEX2T) ) + if ((rotg->eType == erotgRM2) || (rotg->eType == erotgFLEX2) || (rotg->eType == erotgFLEX2T)) { fprintf(fp, "# rot-eps%d %12.5e nm^2\n", g, rotg->eps); } if (erotgFitPOT == rotg->eFittype) { fprintf(fp, "#\n"); - fprintf(fp, "# theta_fit%d is determined by first evaluating the potential for %d angles around theta_ref%d.\n", + fprintf(fp, + "# theta_fit%d is determined by first evaluating the potential for %d " + "angles around theta_ref%d.\n", g, rotg->PotAngle_nstep, g); - fprintf(fp, "# The fit angle is the one with the smallest potential. It is given as the deviation\n"); - fprintf(fp, "# from the reference angle, i.e. if theta_ref=X and theta_fit=Y, then the angle with\n"); - fprintf(fp, "# minimal value of the potential is X+Y. Angular resolution is %g degrees.\n", rotg->PotAngle_step); + fprintf(fp, + "# The fit angle is the one with the smallest potential. It is given as " + "the deviation\n"); + fprintf(fp, + "# from the reference angle, i.e. if theta_ref=X and theta_fit=Y, then the " + "angle with\n"); + fprintf(fp, + "# minimal value of the potential is X+Y. Angular resolution is %g " + "degrees.\n", + rotg->PotAngle_step); } } @@ -1015,7 +1040,7 @@ static FILE *open_rot_out(const char *fn, add_to_string_aligned(&LegendStr, buf); nsets = 0; - snew(setname, 4*rot->ngrp); + snew(setname, 4 * rot->ngrp); for (int g = 0; g < rot->ngrp; g++) { @@ -1028,8 +1053,8 @@ static FILE *open_rot_out(const char *fn, } for (int g = 0; g < rot->ngrp; g++) { - const t_rotgrp *rotg = &rot->grp[g]; - bFlex = ISFLEX(rotg); + const t_rotgrp* rotg = &rot->grp[g]; + bFlex = ISFLEX(rotg); /* For flexible axis rotation we use RMSD fitting to determine the * actual angle of the rotation group */ @@ -1078,12 +1103,11 @@ static FILE *open_rot_out(const char *fn, /* Call on master only */ -static FILE *open_angles_out(const char *fn, - gmx_enfrot *er) +static FILE* open_angles_out(const char* fn, gmx_enfrot* er) { - FILE *fp; + FILE* fp; char buf[100]; - const t_rot *rot = er->rot; + const t_rot* rot = er->rot; if (er->restartWithAppending) { @@ -1096,12 +1120,12 @@ static FILE *open_angles_out(const char *fn, fprintf(fp, "# All angles given in degrees, time in ps.\n"); for (int g = 0; g < rot->ngrp; g++) { - const t_rotgrp *rotg = &rot->grp[g]; - const gmx_enfrotgrp *erg = &er->enfrotgrp[g]; + const t_rotgrp* rotg = &rot->grp[g]; + const gmx_enfrotgrp* erg = &er->enfrotgrp[g]; /* Output for this group happens only if potential type is flexible or * if fit type is potential! */ - if (ISFLEX(rotg) || (erotgFitPOT == rotg->eFittype) ) + if (ISFLEX(rotg) || (erotgFitPOT == rotg->eFittype)) { if (ISFLEX(rotg)) { @@ -1112,15 +1136,20 @@ static FILE *open_angles_out(const char *fn, buf[0] = '\0'; } - fprintf(fp, "#\n# ROTATION GROUP %d '%s',%s fit type '%s'.\n", - g, erotg_names[rotg->eType], buf, erotg_fitnames[rotg->eFittype]); + fprintf(fp, "#\n# ROTATION GROUP %d '%s',%s fit type '%s'.\n", g, + erotg_names[rotg->eType], buf, erotg_fitnames[rotg->eFittype]); /* Special type of fitting using the potential minimum. This is * done for the whole group only, not for the individual slabs. */ if (erotgFitPOT == rotg->eFittype) { - fprintf(fp, "# To obtain theta_fit%d, the potential is evaluated for %d angles around theta_ref%d\n", g, rotg->PotAngle_nstep, g); - fprintf(fp, "# The fit angle in the rotation standard outfile is the one with minimal energy E(theta_fit) [kJ/mol].\n"); + fprintf(fp, + "# To obtain theta_fit%d, the potential is evaluated for %d angles " + "around theta_ref%d\n", + g, rotg->PotAngle_nstep, g); + fprintf(fp, + "# The fit angle in the rotation standard outfile is the one with " + "minimal energy E(theta_fit) [kJ/mol].\n"); fprintf(fp, "#\n"); } @@ -1162,11 +1191,10 @@ static FILE *open_angles_out(const char *fn, /* Open torque output file and write some information about it's structure. * Call on master only */ -static FILE *open_torque_out(const char *fn, - gmx_enfrot *er) +static FILE* open_torque_out(const char* fn, gmx_enfrot* er) { - FILE *fp; - const t_rot *rot = er->rot; + FILE* fp; + const t_rot* rot = er->rot; if (er->restartWithAppending) { @@ -1178,14 +1206,18 @@ static FILE *open_torque_out(const char *fn, for (int g = 0; g < rot->ngrp; g++) { - const t_rotgrp *rotg = &rot->grp[g]; - const gmx_enfrotgrp *erg = &er->enfrotgrp[g]; + const t_rotgrp* rotg = &rot->grp[g]; + const gmx_enfrotgrp* erg = &er->enfrotgrp[g]; if (ISFLEX(rotg)) { - fprintf(fp, "# Rotation group %d (%s), slab distance %f nm.\n", g, erotg_names[rotg->eType], rotg->slab_dist); - fprintf(fp, "# The scalar tau is the torque (kJ/mol) in the direction of the rotation vector.\n"); + fprintf(fp, "# Rotation group %d (%s), slab distance %f nm.\n", g, + erotg_names[rotg->eType], rotg->slab_dist); + fprintf(fp, + "# The scalar tau is the torque (kJ/mol) in the direction of the rotation " + "vector.\n"); fprintf(fp, "# To obtain the vectorial torque, multiply tau with\n"); - fprintf(fp, "# rot-vec%d %10.3e %10.3e %10.3e\n", g, erg->vec[XX], erg->vec[YY], erg->vec[ZZ]); + fprintf(fp, "# rot-vec%d %10.3e %10.3e %10.3e\n", g, erg->vec[XX], + erg->vec[YY], erg->vec[ZZ]); fprintf(fp, "#\n"); } } @@ -1215,9 +1247,9 @@ static void swap_val(double* vec, int i, int j) } -static void swap_col(double **mat, int i, int j) +static void swap_col(double** mat, int i, int j) { - double tmp[3] = {mat[0][j], mat[1][j], mat[2][j]}; + double tmp[3] = { mat[0][j], mat[1][j], mat[2][j] }; mat[0][j] = mat[0][i]; @@ -1231,10 +1263,7 @@ static void swap_col(double **mat, int i, int j) /* Eigenvectors are stored in columns of eigen_vec */ -static void diagonalize_symmetric( - double **matrix, - double **eigen_vec, - double eigenval[3]) +static void diagonalize_symmetric(double** matrix, double** eigen_vec, double eigenval[3]) { int n_rot; @@ -1260,24 +1289,23 @@ static void diagonalize_symmetric( } -static void align_with_z( - rvec* s, /* Structure to align */ - int natoms, - rvec axis) +static void align_with_z(rvec* s, /* Structure to align */ + int natoms, + rvec axis) { - int i, j, k; - rvec zet = {0.0, 0.0, 1.0}; - rvec rot_axis = {0.0, 0.0, 0.0}; - rvec *rotated_str = nullptr; - real ooanorm; - real angle; - matrix rotmat; + int i, j, k; + rvec zet = { 0.0, 0.0, 1.0 }; + rvec rot_axis = { 0.0, 0.0, 0.0 }; + rvec* rotated_str = nullptr; + real ooanorm; + real angle; + matrix rotmat; snew(rotated_str, natoms); /* Normalize the axis */ - ooanorm = 1.0/norm(axis); + ooanorm = 1.0 / norm(axis); svmul(ooanorm, axis, axis); /* Calculate the angle for the fitting procedure */ @@ -1289,7 +1317,7 @@ static void align_with_z( } /* Calculate the rotation matrix */ - calc_rotmat(rot_axis, angle*180.0/M_PI, rotmat); + calc_rotmat(rot_axis, angle * 180.0 / M_PI, rotmat); /* Apply the rotation matrix to s */ for (i = 0; i < natoms; i++) @@ -1298,7 +1326,7 @@ static void align_with_z( { for (k = 0; k < 3; k++) { - rotated_str[i][j] += rotmat[j][k]*s[i][k]; + rotated_str[i][j] += rotmat[j][k] * s[i][k]; } } } @@ -1357,18 +1385,17 @@ static void weigh_coords(rvec* str, real* weight, int natoms) } -static real opt_angle_analytic( - rvec * ref_s, - rvec * act_s, - real * weight, - int natoms, - const rvec ref_com, - const rvec act_com, - rvec axis) +static real opt_angle_analytic(rvec* ref_s, + rvec* act_s, + real* weight, + int natoms, + const rvec ref_com, + const rvec act_com, + rvec axis) { int i, j, k; - rvec *ref_s_1 = nullptr; - rvec *act_s_1 = nullptr; + rvec* ref_s_1 = nullptr; + rvec* act_s_1 = nullptr; rvec shift; double **Rmat, **RtR, **eigvec; double eigval[3]; @@ -1469,7 +1496,7 @@ static real opt_angle_analytic( { for (k = 0; k < 3; k++) { - V[i][j] += Rmat[i][k]*WS[k][j]; + V[i][j] += Rmat[i][k] * WS[k][j]; } } } @@ -1490,7 +1517,7 @@ static real opt_angle_analytic( { for (k = 0; k < 3; k++) { - rot_matrix[i][j] += eigvec[i][k]*V[j][k]; + rot_matrix[i][j] += eigvec[i][k] * V[j][k]; } } } @@ -1509,10 +1536,10 @@ static real opt_angle_analytic( } /* Determine the optimal rotation angle: */ - opt_angle = (-1.0)*acos(rot_matrix[0][0])*180.0/M_PI; + opt_angle = (-1.0) * acos(rot_matrix[0][0]) * 180.0 / M_PI; if (rot_matrix[0][1] < 0.0) { - opt_angle = (-1.0)*opt_angle; + opt_angle = (-1.0) * opt_angle; } /* Give back some memory */ @@ -1531,13 +1558,13 @@ static real opt_angle_analytic( /* Determine angle of the group by RMSD fit to the reference */ /* Not parallelized, call this routine only on the master */ -static real flex_fit_angle(gmx_enfrotgrp *erg) +static real flex_fit_angle(gmx_enfrotgrp* erg) { - rvec *fitcoords = nullptr; - rvec center; /* Center of positions passed to the fit routine */ - real fitangle; /* Angle of the rotation group derived by fitting */ - rvec coord; - real scal; + rvec* fitcoords = nullptr; + rvec center; /* Center of positions passed to the fit routine */ + real fitangle; /* Angle of the rotation group derived by fitting */ + rvec coord; + real scal; /* Get the center of the rotation group. * Note, again, erg->xc has been sorted in do_flexible */ @@ -1565,8 +1592,8 @@ static real flex_fit_angle(gmx_enfrotgrp *erg) /* From the point of view of the current positions, the reference has rotated * backwards. Since we output the angle relative to the fixed reference, * we need the minus sign. */ - fitangle = -opt_angle_analytic(erg->xc_ref_sorted, fitcoords, erg->mc_sorted, - erg->rotg->nat, erg->xc_ref_center, center, erg->vec); + fitangle = -opt_angle_analytic(erg->xc_ref_sorted, fitcoords, erg->mc_sorted, erg->rotg->nat, + erg->xc_ref_center, center, erg->vec); return fitangle; } @@ -1574,24 +1601,20 @@ static real flex_fit_angle(gmx_enfrotgrp *erg) /* Determine actual angle of each slab by RMSD fit to the reference */ /* Not parallelized, call this routine only on the master */ -static void flex_fit_angle_perslab( - gmx_enfrotgrp *erg, - double t, - real degangle, - FILE *fp) -{ - rvec curr_x, ref_x; - rvec act_center; /* Center of actual positions that are passed to the fit routine */ - rvec ref_center; /* Same for the reference positions */ - real fitangle; /* Angle of a slab derived from an RMSD fit to - * the reference structure at t=0 */ - gmx_slabdata *sd; - real OOm_av; /* 1/average_mass of a rotation group atom */ - real m_rel; /* Relative mass of a rotation group atom */ +static void flex_fit_angle_perslab(gmx_enfrotgrp* erg, double t, real degangle, FILE* fp) +{ + rvec curr_x, ref_x; + rvec act_center; /* Center of actual positions that are passed to the fit routine */ + rvec ref_center; /* Same for the reference positions */ + real fitangle; /* Angle of a slab derived from an RMSD fit to + * the reference structure at t=0 */ + gmx_slabdata* sd; + real OOm_av; /* 1/average_mass of a rotation group atom */ + real m_rel; /* Relative mass of a rotation group atom */ /* Average mass of a rotation group atom: */ - OOm_av = erg->invmass*erg->rotg->nat; + OOm_av = erg->invmass * erg->rotg->nat; /**********************************/ /* First collect the data we need */ @@ -1601,9 +1624,9 @@ static void flex_fit_angle_perslab( for (int n = erg->slab_first; n <= erg->slab_last; n++) { int slabIndex = n - erg->slab_first; /* slab index */ - sd = &(erg->slab_data[slabIndex]); - sd->nat = erg->lastatom[slabIndex]-erg->firstatom[slabIndex]+1; - int ind = 0; + sd = &(erg->slab_data[slabIndex]); + sd->nat = erg->lastatom[slabIndex] - erg->firstatom[slabIndex] + 1; + int ind = 0; /* Loop over the relevant atoms in the slab */ for (int l = erg->firstatom[slabIndex]; l <= erg->lastatom[slabIndex]; l++) @@ -1624,7 +1647,7 @@ static void flex_fit_angle_perslab( /* Maybe also mass-weighting was requested. If yes, additionally * multiply the weights with the relative mass of the atom. If not, * multiply with unity. */ - m_rel = erg->mc_sorted[l]*OOm_av; + m_rel = erg->mc_sorted[l] * OOm_av; /* Save the weight for this atom in this slab */ sd->weight[ind] = gaussian_weight(curr_x, erg, n) * m_rel; @@ -1647,7 +1670,7 @@ static void flex_fit_angle_perslab( for (int n = erg->slab_first; n <= erg->slab_last; n++) { int slabIndex = n - erg->slab_first; /* slab index */ - sd = &(erg->slab_data[slabIndex]); + sd = &(erg->slab_data[slabIndex]); if (sd->nat >= SLAB_MIN_ATOMS) { /* Get the center of the slabs reference and current positions */ @@ -1662,14 +1685,14 @@ static void flex_fit_angle_perslab( rvec_dec(sd->ref[i], ref_center); rvec_dec(sd->x[i], act_center); /* Normalize x_i such that it gets the same length as ref_i */ - svmul( norm(sd->ref[i])/norm(sd->x[i]), sd->x[i], sd->x[i] ); + svmul(norm(sd->ref[i]) / norm(sd->x[i]), sd->x[i], sd->x[i]); } /* We already subtracted the centers */ clear_rvec(ref_center); clear_rvec(act_center); } - fitangle = -opt_angle_analytic(sd->ref, sd->x, sd->weight, sd->nat, - ref_center, act_center, erg->vec); + fitangle = -opt_angle_analytic(sd->ref, sd->x, sd->weight, sd->nat, ref_center, + act_center, erg->vec); fprintf(fp, "%6d%6d%12.3f", n, sd->nat, fitangle); } } @@ -1691,25 +1714,24 @@ static inline void shift_single_coord(const matrix box, rvec x, const ivec is) if (TRICLINIC(box)) { - x[XX] += tx*box[XX][XX]+ty*box[YY][XX]+tz*box[ZZ][XX]; - x[YY] += ty*box[YY][YY]+tz*box[ZZ][YY]; - x[ZZ] += tz*box[ZZ][ZZ]; + x[XX] += tx * box[XX][XX] + ty * box[YY][XX] + tz * box[ZZ][XX]; + x[YY] += ty * box[YY][YY] + tz * box[ZZ][YY]; + x[ZZ] += tz * box[ZZ][ZZ]; } else { - x[XX] += tx*box[XX][XX]; - x[YY] += ty*box[YY][YY]; - x[ZZ] += tz*box[ZZ][ZZ]; + x[XX] += tx * box[XX][XX]; + x[YY] += ty * box[YY][YY]; + x[ZZ] += tz * box[ZZ][ZZ]; } } /* Determine the 'home' slab of this atom which is the * slab with the highest Gaussian weight of all */ -static inline int get_homeslab( - rvec curr_x, /* The position for which the home slab shall be determined */ - const rvec rotvec, /* The rotation vector */ - real slabdist) /* The slab distance */ +static inline int get_homeslab(rvec curr_x, /* The position for which the home slab shall be determined */ + const rvec rotvec, /* The rotation vector */ + real slabdist) /* The slab distance */ { real dist; @@ -1725,17 +1747,15 @@ static inline int get_homeslab( /* For a local atom determine the relevant slabs, i.e. slabs in * which the gaussian is larger than min_gaussian */ -static int get_single_atom_gaussians( - rvec curr_x, - gmx_enfrotgrp *erg) +static int get_single_atom_gaussians(rvec curr_x, gmx_enfrotgrp* erg) { /* Determine the 'home' slab of this atom: */ int homeslab = get_homeslab(curr_x, erg->vec, erg->rotg->slab_dist); /* First determine the weight in the atoms home slab: */ - real g = gaussian_weight(curr_x, erg, homeslab); - int count = 0; + real g = gaussian_weight(curr_x, erg, homeslab); + int count = 0; erg->gn_atom[count] = g; erg->gn_slabind[count] = homeslab; count++; @@ -1746,7 +1766,7 @@ static int get_single_atom_gaussians( while (g > erg->rotg->min_gaussian) { slab++; - g = gaussian_weight(curr_x, erg, slab); + g = gaussian_weight(curr_x, erg, slab); erg->gn_slabind[count] = slab; erg->gn_atom[count] = g; count++; @@ -1758,32 +1778,31 @@ static int get_single_atom_gaussians( do { slab--; - g = gaussian_weight(curr_x, erg, slab); + g = gaussian_weight(curr_x, erg, slab); erg->gn_slabind[count] = slab; erg->gn_atom[count] = g; count++; - } - while (g > erg->rotg->min_gaussian); + } while (g > erg->rotg->min_gaussian); count--; return count; } -static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) +static void flex2_precalc_inner_sum(const gmx_enfrotgrp* erg) { - rvec xi; /* positions in the i-sum */ - rvec xcn, ycn; /* the current and the reference slab centers */ - real gaussian_xi; - rvec yi0; - rvec rin; /* Helper variables */ - real fac, fac2; - rvec innersumvec; - real OOpsii, OOpsiistar; - real sin_rin; /* s_ii.r_ii */ - rvec s_in, tmpvec, tmpvec2; - real mi, wi; /* Mass-weighting of the positions */ - real N_M; /* N/M */ + rvec xi; /* positions in the i-sum */ + rvec xcn, ycn; /* the current and the reference slab centers */ + real gaussian_xi; + rvec yi0; + rvec rin; /* Helper variables */ + real fac, fac2; + rvec innersumvec; + real OOpsii, OOpsiistar; + real sin_rin; /* s_ii.r_ii */ + rvec s_in, tmpvec, tmpvec2; + real mi, wi; /* Mass-weighting of the positions */ + real N_M; /* N/M */ N_M = erg->rotg->nat * erg->invmass; @@ -1796,7 +1815,7 @@ static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) /* The current center of this slab is saved in xcn: */ copy_rvec(erg->slab_center[slabIndex], xcn); /* ... and the reference center in ycn: */ - copy_rvec(erg->slab_center_ref[slabIndex+erg->slab_buffer], ycn); + copy_rvec(erg->slab_center_ref[slabIndex + erg->slab_buffer], ycn); /*** D. Calculate the whole inner sum used for second and third sum */ /* For slab n, we need to loop over all atoms i again. Since we sorted @@ -1812,7 +1831,7 @@ static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) /* The i-weights */ gaussian_xi = gaussian_weight(xi, erg, n); mi = erg->mc_sorted[i]; /* need the sorted mass here */ - wi = N_M*mi; + wi = N_M * mi; /* Calculate rin */ copy_rvec(erg->xc_ref_sorted[i], yi0); /* Reference position yi0 */ @@ -1820,7 +1839,7 @@ static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) mvmul(erg->rotmat, tmpvec2, rin); /* rin = Omega.(yi0 - ycn) */ /* Calculate psi_i* and sin */ - rvec_sub(xi, xcn, tmpvec2); /* tmpvec2 = xi - xcn */ + rvec_sub(xi, xcn, tmpvec2); /* tmpvec2 = xi - xcn */ /* In rare cases, when an atom position coincides with a slab center * (tmpvec2 == 0) we cannot compute the vector product for s_in. @@ -1832,24 +1851,24 @@ static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) continue; } - cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x (xi - xcn) */ - OOpsiistar = norm2(tmpvec)+erg->rotg->eps; /* OOpsii* = 1/psii* = |v x (xi-xcn)|^2 + eps */ - OOpsii = norm(tmpvec); /* OOpsii = 1 / psii = |v x (xi - xcn)| */ + cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x (xi - xcn) */ + OOpsiistar = norm2(tmpvec) + erg->rotg->eps; /* OOpsii* = 1/psii* = |v x (xi-xcn)|^2 + eps */ + OOpsii = norm(tmpvec); /* OOpsii = 1 / psii = |v x (xi - xcn)| */ /* * v x (xi - xcn) */ - unitv(tmpvec, s_in); /* sin = ---------------- */ - /* |v x (xi - xcn)| */ + unitv(tmpvec, s_in); /* sin = ---------------- */ + /* |v x (xi - xcn)| */ sin_rin = iprod(s_in, rin); /* sin_rin = sin . rin */ /* Now the whole sum */ - fac = OOpsii/OOpsiistar; + fac = OOpsii / OOpsiistar; svmul(fac, rin, tmpvec); - fac2 = fac*fac*OOpsii; - svmul(fac2*sin_rin, s_in, tmpvec2); + fac2 = fac * fac * OOpsii; + svmul(fac2 * sin_rin, s_in, tmpvec2); rvec_dec(tmpvec, tmpvec2); - svmul(wi*gaussian_xi*sin_rin, tmpvec, tmpvec2); + svmul(wi * gaussian_xi * sin_rin, tmpvec, tmpvec2); rvec_inc(innersumvec, tmpvec2); } /* now we have the inner sum, used both for sum2 and sum3 */ @@ -1860,17 +1879,17 @@ static void flex2_precalc_inner_sum(const gmx_enfrotgrp *erg) } -static void flex_precalc_inner_sum(const gmx_enfrotgrp *erg) +static void flex_precalc_inner_sum(const gmx_enfrotgrp* erg) { - rvec xi; /* position */ - rvec xcn, ycn; /* the current and the reference slab centers */ - rvec qin, rin; /* q_i^n and r_i^n */ - real bin; - rvec tmpvec; - rvec innersumvec; /* Inner part of sum_n2 */ - real gaussian_xi; /* Gaussian weight gn(xi) */ - real mi, wi; /* Mass-weighting of the positions */ - real N_M; /* N/M */ + rvec xi; /* position */ + rvec xcn, ycn; /* the current and the reference slab centers */ + rvec qin, rin; /* q_i^n and r_i^n */ + real bin; + rvec tmpvec; + rvec innersumvec; /* Inner part of sum_n2 */ + real gaussian_xi; /* Gaussian weight gn(xi) */ + real mi, wi; /* Mass-weighting of the positions */ + real N_M; /* N/M */ N_M = erg->rotg->nat * erg->invmass; @@ -1882,7 +1901,7 @@ static void flex_precalc_inner_sum(const gmx_enfrotgrp *erg) /* The current center of this slab is saved in xcn: */ copy_rvec(erg->slab_center[slabIndex], xcn); /* ... and the reference center in ycn: */ - copy_rvec(erg->slab_center_ref[slabIndex+erg->slab_buffer], ycn); + copy_rvec(erg->slab_center_ref[slabIndex + erg->slab_buffer], ycn); /* For slab n, we need to loop over all atoms i again. Since we sorted * the atoms with respect to the rotation vector, we know that it is sufficient @@ -1897,7 +1916,7 @@ static void flex_precalc_inner_sum(const gmx_enfrotgrp *erg) /* The i-weights */ gaussian_xi = gaussian_weight(xi, erg, n); mi = erg->mc_sorted[i]; /* need the sorted mass here */ - wi = N_M*mi; + wi = N_M * mi; /* Calculate rin and qin */ rvec_sub(erg->xc_ref_sorted[i], ycn, tmpvec); /* tmpvec = yi0-ycn */ @@ -1912,18 +1931,18 @@ static void flex_precalc_inner_sum(const gmx_enfrotgrp *erg) continue; } - mvmul(erg->rotmat, tmpvec, rin); /* rin = Omega.(yi0 - ycn) */ - cprod(erg->vec, rin, tmpvec); /* tmpvec = v x Omega*(yi0-ycn) */ + mvmul(erg->rotmat, tmpvec, rin); /* rin = Omega.(yi0 - ycn) */ + cprod(erg->vec, rin, tmpvec); /* tmpvec = v x Omega*(yi0-ycn) */ /* * v x Omega*(yi0-ycn) */ - unitv(tmpvec, qin); /* qin = --------------------- */ - /* |v x Omega*(yi0-ycn)| */ + unitv(tmpvec, qin); /* qin = --------------------- */ + /* |v x Omega*(yi0-ycn)| */ /* Calculate bin */ - rvec_sub(xi, xcn, tmpvec); /* tmpvec = xi-xcn */ - bin = iprod(qin, tmpvec); /* bin = qin*(xi-xcn) */ + rvec_sub(xi, xcn, tmpvec); /* tmpvec = xi-xcn */ + bin = iprod(qin, tmpvec); /* bin = qin*(xi-xcn) */ - svmul(wi*gaussian_xi*bin, qin, tmpvec); + svmul(wi * gaussian_xi * bin, qin, tmpvec); /* Add this contribution to the inner sum: */ rvec_add(innersumvec, tmpvec, innersumvec); @@ -1934,40 +1953,39 @@ static void flex_precalc_inner_sum(const gmx_enfrotgrp *erg) } -static real do_flex2_lowlevel( - gmx_enfrotgrp *erg, - real sigma, /* The Gaussian width sigma */ - rvec x[], - gmx_bool bOutstepRot, - gmx_bool bOutstepSlab, - const matrix box) -{ - int count, ii, iigrp; - rvec xj; /* position in the i-sum */ - rvec yj0; /* the reference position in the j-sum */ - rvec xcn, ycn; /* the current and the reference slab centers */ - real V; /* This node's part of the rotation pot. energy */ - real gaussian_xj; /* Gaussian weight */ - real beta; - - real numerator, fit_numerator; - rvec rjn, fit_rjn; /* Helper variables */ - real fac, fac2; - - real OOpsij, OOpsijstar; - real OOsigma2; /* 1/(sigma^2) */ - real sjn_rjn; - real betasigpsi; - rvec sjn, tmpvec, tmpvec2, yj0_ycn; - rvec sum1vec_part, sum1vec, sum2vec_part, sum2vec, sum3vec, sum4vec, innersumvec; - real sum3, sum4; - real mj, wj; /* Mass-weighting of the positions */ - real N_M; /* N/M */ - real Wjn; /* g_n(x_j) m_j / Mjn */ - gmx_bool bCalcPotFit; +static real do_flex2_lowlevel(gmx_enfrotgrp* erg, + real sigma, /* The Gaussian width sigma */ + rvec x[], + gmx_bool bOutstepRot, + gmx_bool bOutstepSlab, + const matrix box) +{ + int count, ii, iigrp; + rvec xj; /* position in the i-sum */ + rvec yj0; /* the reference position in the j-sum */ + rvec xcn, ycn; /* the current and the reference slab centers */ + real V; /* This node's part of the rotation pot. energy */ + real gaussian_xj; /* Gaussian weight */ + real beta; + + real numerator, fit_numerator; + rvec rjn, fit_rjn; /* Helper variables */ + real fac, fac2; + + real OOpsij, OOpsijstar; + real OOsigma2; /* 1/(sigma^2) */ + real sjn_rjn; + real betasigpsi; + rvec sjn, tmpvec, tmpvec2, yj0_ycn; + rvec sum1vec_part, sum1vec, sum2vec_part, sum2vec, sum3vec, sum4vec, innersumvec; + real sum3, sum4; + real mj, wj; /* Mass-weighting of the positions */ + real N_M; /* N/M */ + real Wjn; /* g_n(x_j) m_j / Mjn */ + gmx_bool bCalcPotFit; /* To calculate the torque per slab */ - rvec slab_force; /* Single force from slab n on one atom */ + rvec slab_force; /* Single force from slab n on one atom */ rvec slab_sum1vec_part; real slab_sum3part, slab_sum4part; rvec slab_sum1vec, slab_sum2vec, slab_sum3vec, slab_sum4vec; @@ -1981,11 +1999,11 @@ static real do_flex2_lowlevel( /********************************************************/ /* Main loop over all local atoms of the rotation group */ /********************************************************/ - N_M = erg->rotg->nat * erg->invmass; - V = 0.0; - OOsigma2 = 1.0 / (sigma*sigma); - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + N_M = erg->rotg->nat * erg->invmass; + V = 0.0; + OOsigma2 = 1.0 / (sigma * sigma); + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (gmx::index j = 0; j < localRotationGroupIndex.ssize(); j++) { @@ -1994,8 +2012,8 @@ static real do_flex2_lowlevel( /* Position of this atom in the collective array */ iigrp = collectiveRotationGroupIndex[j]; /* Mass-weighting */ - mj = erg->mc[iigrp]; /* need the unsorted mass here */ - wj = N_M*mj; + mj = erg->mc[iigrp]; /* need the unsorted mass here */ + wj = N_M * mj; /* Current position of this atom: x[ii][XX/YY/ZZ] * Note that erg->xc_center contains the center of mass in case the flex2-t @@ -2032,15 +2050,15 @@ static real do_flex2_lowlevel( /* The current center of this slab is saved in xcn: */ copy_rvec(erg->slab_center[slabIndex], xcn); /* ... and the reference center in ycn: */ - copy_rvec(erg->slab_center_ref[slabIndex+erg->slab_buffer], ycn); + copy_rvec(erg->slab_center_ref[slabIndex + erg->slab_buffer], ycn); - rvec_sub(yj0, ycn, yj0_ycn); /* yj0_ycn = yj0 - ycn */ + rvec_sub(yj0, ycn, yj0_ycn); /* yj0_ycn = yj0 - ycn */ /* Rotate: */ - mvmul(erg->rotmat, yj0_ycn, rjn); /* rjn = Omega.(yj0 - ycn) */ + mvmul(erg->rotmat, yj0_ycn, rjn); /* rjn = Omega.(yj0 - ycn) */ /* Subtract the slab center from xj */ - rvec_sub(xj, xcn, tmpvec2); /* tmpvec2 = xj - xcn */ + rvec_sub(xj, xcn, tmpvec2); /* tmpvec2 = xj - xcn */ /* In rare cases, when an atom position coincides with a slab center * (tmpvec2 == 0) we cannot compute the vector product for sjn. @@ -2053,16 +2071,16 @@ static real do_flex2_lowlevel( } /* Calculate sjn */ - cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x (xj - xcn) */ + cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x (xj - xcn) */ - OOpsijstar = norm2(tmpvec)+erg->rotg->eps; /* OOpsij* = 1/psij* = |v x (xj-xcn)|^2 + eps */ + OOpsijstar = norm2(tmpvec) + erg->rotg->eps; /* OOpsij* = 1/psij* = |v x (xj-xcn)|^2 + eps */ numerator = gmx::square(iprod(tmpvec, rjn)); /*********************************/ /* Add to the rotation potential */ /*********************************/ - V += 0.5*erg->rotg->k*wj*gaussian_xj*numerator/OOpsijstar; + V += 0.5 * erg->rotg->k * wj * gaussian_xj * numerator / OOpsijstar; /* If requested, also calculate the potential for a set of angles * near the current reference angle */ @@ -2071,8 +2089,9 @@ static real do_flex2_lowlevel( for (int ifit = 0; ifit < erg->rotg->PotAngle_nstep; ifit++) { mvmul(erg->PotAngleFit->rotmat[ifit], yj0_ycn, fit_rjn); - fit_numerator = gmx::square(iprod(tmpvec, fit_rjn)); - erg->PotAngleFit->V[ifit] += 0.5*erg->rotg->k*wj*gaussian_xj*fit_numerator/OOpsijstar; + fit_numerator = gmx::square(iprod(tmpvec, fit_rjn)); + erg->PotAngleFit->V[ifit] += + 0.5 * erg->rotg->k * wj * gaussian_xj * fit_numerator / OOpsijstar; } } @@ -2080,40 +2099,41 @@ static real do_flex2_lowlevel( /* Now calculate the force on atom j */ /*************************************/ - OOpsij = norm(tmpvec); /* OOpsij = 1 / psij = |v x (xj - xcn)| */ + OOpsij = norm(tmpvec); /* OOpsij = 1 / psij = |v x (xj - xcn)| */ /* * v x (xj - xcn) */ - unitv(tmpvec, sjn); /* sjn = ---------------- */ - /* |v x (xj - xcn)| */ + unitv(tmpvec, sjn); /* sjn = ---------------- */ + /* |v x (xj - xcn)| */ - sjn_rjn = iprod(sjn, rjn); /* sjn_rjn = sjn . rjn */ + sjn_rjn = iprod(sjn, rjn); /* sjn_rjn = sjn . rjn */ /*** A. Calculate the first of the four sum terms: ****************/ - fac = OOpsij/OOpsijstar; + fac = OOpsij / OOpsijstar; svmul(fac, rjn, tmpvec); - fac2 = fac*fac*OOpsij; - svmul(fac2*sjn_rjn, sjn, tmpvec2); + fac2 = fac * fac * OOpsij; + svmul(fac2 * sjn_rjn, sjn, tmpvec2); rvec_dec(tmpvec, tmpvec2); - fac2 = wj*gaussian_xj; /* also needed for sum4 */ - svmul(fac2*sjn_rjn, tmpvec, slab_sum1vec_part); + fac2 = wj * gaussian_xj; /* also needed for sum4 */ + svmul(fac2 * sjn_rjn, tmpvec, slab_sum1vec_part); /********************/ /*** Add to sum1: ***/ /********************/ rvec_inc(sum1vec_part, slab_sum1vec_part); /* sum1 still needs to vector multiplied with v */ /*** B. Calculate the forth of the four sum terms: ****************/ - betasigpsi = beta*OOsigma2*OOpsij; /* this is also needed for sum3 */ + betasigpsi = beta * OOsigma2 * OOpsij; /* this is also needed for sum3 */ /********************/ /*** Add to sum4: ***/ /********************/ - slab_sum4part = fac2*betasigpsi*fac*sjn_rjn*sjn_rjn; /* Note that fac is still valid from above */ - sum4 += slab_sum4part; + slab_sum4part = fac2 * betasigpsi * fac * sjn_rjn + * sjn_rjn; /* Note that fac is still valid from above */ + sum4 += slab_sum4part; /*** C. Calculate Wjn for second and third sum */ /* Note that we can safely divide by slab_weights since we check in * get_slab_centers that it is non-zero. */ - Wjn = gaussian_xj*mj/erg->slab_weights[slabIndex]; + Wjn = gaussian_xj * mj / erg->slab_weights[slabIndex]; /* We already have precalculated the inner sum for slab n */ copy_rvec(erg->slab_innersumvec[slabIndex], innersumvec); @@ -2129,7 +2149,7 @@ static real do_flex2_lowlevel( /*** F. Calculate the third of the four sum terms: */ slab_sum3part = betasigpsi * iprod(sjn, innersumvec); - sum3 += slab_sum3part; /* still needs to be multiplied with v */ + sum3 += slab_sum3part; /* still needs to be multiplied with v */ /*** G. Calculate the torque on the local slab's axis: */ if (bOutstepRot) @@ -2146,7 +2166,9 @@ static real do_flex2_lowlevel( /* The force on atom ii from slab n only: */ for (int m = 0; m < DIM; m++) { - slab_force[m] = erg->rotg->k * (-slab_sum1vec[m] + slab_sum2vec[m] - slab_sum3vec[m] + 0.5*slab_sum4vec[m]); + slab_force[m] = erg->rotg->k + * (-slab_sum1vec[m] + slab_sum2vec[m] - slab_sum3vec[m] + + 0.5 * slab_sum4vec[m]); } erg->slab_torque_v[slabIndex] += torque(erg->vec, slab_force, xj, xcn); @@ -2154,23 +2176,28 @@ static real do_flex2_lowlevel( } /* END of loop over slabs */ /* Construct the four individual parts of the vector sum: */ - cprod(sum1vec_part, erg->vec, sum1vec); /* sum1vec = { } x v */ - cprod(sum2vec_part, erg->vec, sum2vec); /* sum2vec = { } x v */ - svmul(sum3, erg->vec, sum3vec); /* sum3vec = { } . v */ - svmul(sum4, erg->vec, sum4vec); /* sum4vec = { } . v */ + cprod(sum1vec_part, erg->vec, sum1vec); /* sum1vec = { } x v */ + cprod(sum2vec_part, erg->vec, sum2vec); /* sum2vec = { } x v */ + svmul(sum3, erg->vec, sum3vec); /* sum3vec = { } . v */ + svmul(sum4, erg->vec, sum4vec); /* sum4vec = { } . v */ /* Store the additional force so that it can be added to the force * array after the normal forces have been evaluated */ for (int m = 0; m < DIM; m++) { - erg->f_rot_loc[j][m] = erg->rotg->k * (-sum1vec[m] + sum2vec[m] - sum3vec[m] + 0.5*sum4vec[m]); + erg->f_rot_loc[j][m] = + erg->rotg->k * (-sum1vec[m] + sum2vec[m] - sum3vec[m] + 0.5 * sum4vec[m]); } #ifdef SUM_PARTS - fprintf(stderr, "sum1: %15.8f %15.8f %15.8f\n", -erg->rotg->k*sum1vec[XX], -erg->rotg->k*sum1vec[YY], -erg->rotg->k*sum1vec[ZZ]); - fprintf(stderr, "sum2: %15.8f %15.8f %15.8f\n", erg->rotg->k*sum2vec[XX], erg->rotg->k*sum2vec[YY], erg->rotg->k*sum2vec[ZZ]); - fprintf(stderr, "sum3: %15.8f %15.8f %15.8f\n", -erg->rotg->k*sum3vec[XX], -erg->rotg->k*sum3vec[YY], -erg->rotg->k*sum3vec[ZZ]); - fprintf(stderr, "sum4: %15.8f %15.8f %15.8f\n", 0.5*erg->rotg->k*sum4vec[XX], 0.5*erg->rotg->k*sum4vec[YY], 0.5*erg->rotg->k*sum4vec[ZZ]); + fprintf(stderr, "sum1: %15.8f %15.8f %15.8f\n", -erg->rotg->k * sum1vec[XX], + -erg->rotg->k * sum1vec[YY], -erg->rotg->k * sum1vec[ZZ]); + fprintf(stderr, "sum2: %15.8f %15.8f %15.8f\n", erg->rotg->k * sum2vec[XX], + erg->rotg->k * sum2vec[YY], erg->rotg->k * sum2vec[ZZ]); + fprintf(stderr, "sum3: %15.8f %15.8f %15.8f\n", -erg->rotg->k * sum3vec[XX], + -erg->rotg->k * sum3vec[YY], -erg->rotg->k * sum3vec[ZZ]); + fprintf(stderr, "sum4: %15.8f %15.8f %15.8f\n", 0.5 * erg->rotg->k * sum4vec[XX], + 0.5 * erg->rotg->k * sum4vec[YY], 0.5 * erg->rotg->k * sum4vec[ZZ]); #endif PRINT_FORCE_J @@ -2181,35 +2208,34 @@ static real do_flex2_lowlevel( } -static real do_flex_lowlevel( - gmx_enfrotgrp *erg, - real sigma, /* The Gaussian width sigma */ - rvec x[], - gmx_bool bOutstepRot, - gmx_bool bOutstepSlab, - const matrix box) -{ - int count, iigrp; - rvec xj, yj0; /* current and reference position */ - rvec xcn, ycn; /* the current and the reference slab centers */ - rvec yj0_ycn; /* yj0 - ycn */ - rvec xj_xcn; /* xj - xcn */ - rvec qjn, fit_qjn; /* q_i^n */ - rvec sum_n1, sum_n2; /* Two contributions to the rotation force */ - rvec innersumvec; /* Inner part of sum_n2 */ - rvec s_n; - rvec force_n; /* Single force from slab n on one atom */ - rvec force_n1, force_n2; /* First and second part of force_n */ - rvec tmpvec, tmpvec2, tmp_f; /* Helper variables */ - real V; /* The rotation potential energy */ - real OOsigma2; /* 1/(sigma^2) */ - real beta; /* beta_n(xj) */ - real bjn, fit_bjn; /* b_j^n */ - real gaussian_xj; /* Gaussian weight gn(xj) */ - real betan_xj_sigma2; - real mj, wj; /* Mass-weighting of the positions */ - real N_M; /* N/M */ - gmx_bool bCalcPotFit; +static real do_flex_lowlevel(gmx_enfrotgrp* erg, + real sigma, /* The Gaussian width sigma */ + rvec x[], + gmx_bool bOutstepRot, + gmx_bool bOutstepSlab, + const matrix box) +{ + int count, iigrp; + rvec xj, yj0; /* current and reference position */ + rvec xcn, ycn; /* the current and the reference slab centers */ + rvec yj0_ycn; /* yj0 - ycn */ + rvec xj_xcn; /* xj - xcn */ + rvec qjn, fit_qjn; /* q_i^n */ + rvec sum_n1, sum_n2; /* Two contributions to the rotation force */ + rvec innersumvec; /* Inner part of sum_n2 */ + rvec s_n; + rvec force_n; /* Single force from slab n on one atom */ + rvec force_n1, force_n2; /* First and second part of force_n */ + rvec tmpvec, tmpvec2, tmp_f; /* Helper variables */ + real V; /* The rotation potential energy */ + real OOsigma2; /* 1/(sigma^2) */ + real beta; /* beta_n(xj) */ + real bjn, fit_bjn; /* b_j^n */ + real gaussian_xj; /* Gaussian weight gn(xj) */ + real betan_xj_sigma2; + real mj, wj; /* Mass-weighting of the positions */ + real N_M; /* N/M */ + gmx_bool bCalcPotFit; /* Pre-calculate the inner sums, so that we do not have to calculate * them again for every atom */ @@ -2220,11 +2246,11 @@ static real do_flex_lowlevel( /********************************************************/ /* Main loop over all local atoms of the rotation group */ /********************************************************/ - OOsigma2 = 1.0/(sigma*sigma); - N_M = erg->rotg->nat * erg->invmass; - V = 0.0; - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + OOsigma2 = 1.0 / (sigma * sigma); + N_M = erg->rotg->nat * erg->invmass; + V = 0.0; + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (gmx::index j = 0; j < localRotationGroupIndex.ssize(); j++) { @@ -2233,8 +2259,8 @@ static real do_flex_lowlevel( /* Position of this atom in the collective array */ iigrp = collectiveRotationGroupIndex[j]; /* Mass-weighting */ - mj = erg->mc[iigrp]; /* need the unsorted mass here */ - wj = N_M*mj; + mj = erg->mc[iigrp]; /* need the unsorted mass here */ + wj = N_M * mj; /* Current position of this atom: x[ii][XX/YY/ZZ] * Note that erg->xc_center contains the center of mass in case the flex-t @@ -2270,7 +2296,7 @@ static real do_flex_lowlevel( /* The current center of this slab is saved in xcn: */ copy_rvec(erg->slab_center[slabIndex], xcn); /* ... and the reference center in ycn: */ - copy_rvec(erg->slab_center_ref[slabIndex+erg->slab_buffer], ycn); + copy_rvec(erg->slab_center_ref[slabIndex + erg->slab_buffer], ycn); rvec_sub(yj0, ycn, yj0_ycn); /* yj0_ycn = yj0 - ycn */ @@ -2288,21 +2314,21 @@ static real do_flex_lowlevel( mvmul(erg->rotmat, yj0_ycn, tmpvec2); /* tmpvec2= Omega.(yj0-ycn) */ /* Subtract the slab center from xj */ - rvec_sub(xj, xcn, xj_xcn); /* xj_xcn = xj - xcn */ + rvec_sub(xj, xcn, xj_xcn); /* xj_xcn = xj - xcn */ /* Calculate qjn */ cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec= v x Omega.(yj0-ycn) */ /* * v x Omega.(yj0-ycn) */ - unitv(tmpvec, qjn); /* qjn = --------------------- */ - /* |v x Omega.(yj0-ycn)| */ + unitv(tmpvec, qjn); /* qjn = --------------------- */ + /* |v x Omega.(yj0-ycn)| */ bjn = iprod(qjn, xj_xcn); /* bjn = qjn * (xj - xcn) */ /*********************************/ /* Add to the rotation potential */ /*********************************/ - V += 0.5*erg->rotg->k*wj*gaussian_xj*gmx::square(bjn); + V += 0.5 * erg->rotg->k * wj * gaussian_xj * gmx::square(bjn); /* If requested, also calculate the potential for a set of angles * near the current reference angle */ @@ -2313,43 +2339,44 @@ static real do_flex_lowlevel( /* As above calculate Omega.(yj0-ycn), now for the other angles */ mvmul(erg->PotAngleFit->rotmat[ifit], yj0_ycn, tmpvec2); /* tmpvec2= Omega.(yj0-ycn) */ /* As above calculate qjn */ - cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec= v x Omega.(yj0-ycn) */ - /* * v x Omega.(yj0-ycn) */ - unitv(tmpvec, fit_qjn); /* fit_qjn = --------------------- */ - /* |v x Omega.(yj0-ycn)| */ - fit_bjn = iprod(fit_qjn, xj_xcn); /* fit_bjn = fit_qjn * (xj - xcn) */ + cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec= v x Omega.(yj0-ycn) */ + /* * v x Omega.(yj0-ycn) */ + unitv(tmpvec, fit_qjn); /* fit_qjn = --------------------- */ + /* |v x Omega.(yj0-ycn)| */ + fit_bjn = iprod(fit_qjn, xj_xcn); /* fit_bjn = fit_qjn * (xj - xcn) */ /* Add to the rotation potential for this angle */ - erg->PotAngleFit->V[ifit] += 0.5*erg->rotg->k*wj*gaussian_xj*gmx::square(fit_bjn); + erg->PotAngleFit->V[ifit] += + 0.5 * erg->rotg->k * wj * gaussian_xj * gmx::square(fit_bjn); } } /****************************************************************/ /* sum_n1 will typically be the main contribution to the force: */ /****************************************************************/ - betan_xj_sigma2 = beta*OOsigma2; /* beta_n(xj)/sigma^2 */ + betan_xj_sigma2 = beta * OOsigma2; /* beta_n(xj)/sigma^2 */ /* The next lines calculate * qjn - (bjn*beta(xj)/(2sigma^2))v */ - svmul(bjn*0.5*betan_xj_sigma2, erg->vec, tmpvec2); + svmul(bjn * 0.5 * betan_xj_sigma2, erg->vec, tmpvec2); rvec_sub(qjn, tmpvec2, tmpvec); /* Multiply with gn(xj)*bjn: */ - svmul(gaussian_xj*bjn, tmpvec, tmpvec2); + svmul(gaussian_xj * bjn, tmpvec, tmpvec2); /* Sum over n: */ rvec_inc(sum_n1, tmpvec2); /* We already have precalculated the Sn term for slab n */ copy_rvec(erg->slab_innersumvec[slabIndex], s_n); - /* * beta_n(xj) */ - svmul(betan_xj_sigma2*iprod(s_n, xj_xcn), erg->vec, tmpvec); /* tmpvec = ---------- s_n (xj-xcn) */ - /* sigma^2 */ + /* * beta_n(xj) */ + svmul(betan_xj_sigma2 * iprod(s_n, xj_xcn), erg->vec, tmpvec); /* tmpvec = ---------- s_n (xj-xcn) */ + /* sigma^2 */ rvec_sub(s_n, tmpvec, innersumvec); /* We can safely divide by slab_weights since we check in get_slab_centers * that it is non-zero. */ - svmul(gaussian_xj/erg->slab_weights[slabIndex], innersumvec, innersumvec); + svmul(gaussian_xj / erg->slab_weights[slabIndex], innersumvec, innersumvec); rvec_add(sum_n2, innersumvec, sum_n2); @@ -2357,8 +2384,8 @@ static real do_flex_lowlevel( if (bOutstepRot) { /* The force on atom ii from slab n only: */ - svmul(-erg->rotg->k*wj, tmpvec2, force_n1); /* part 1 */ - svmul( erg->rotg->k*mj, innersumvec, force_n2); /* part 2 */ + svmul(-erg->rotg->k * wj, tmpvec2, force_n1); /* part 1 */ + svmul(erg->rotg->k * mj, innersumvec, force_n2); /* part 2 */ rvec_add(force_n1, force_n2, force_n); erg->slab_torque_v[slabIndex] += torque(erg->vec, force_n, xj, xcn); } @@ -2373,7 +2400,7 @@ static real do_flex_lowlevel( * array after the normal forces have been evaluated */ for (int m = 0; m < DIM; m++) { - erg->f_rot_loc[j][m] = erg->rotg->k*tmp_f[m]; + erg->f_rot_loc[j][m] = erg->rotg->k * tmp_f[m]; } PRINT_FORCE_J @@ -2383,31 +2410,28 @@ static real do_flex_lowlevel( return V; } -static void sort_collective_coordinates( - gmx_enfrotgrp *erg, - sort_along_vec_t *data) /* Buffer for sorting the positions */ +static void sort_collective_coordinates(gmx_enfrotgrp* erg, + sort_along_vec_t* data) /* Buffer for sorting the positions */ { /* The projection of the position vector on the rotation vector is * the relevant value for sorting. Fill the 'data' structure */ for (int i = 0; i < erg->rotg->nat; i++) { - data[i].xcproj = iprod(erg->xc[i], erg->vec); /* sort criterium */ + data[i].xcproj = iprod(erg->xc[i], erg->vec); /* sort criterium */ data[i].m = erg->mc[i]; data[i].ind = i; - copy_rvec(erg->xc[i], data[i].x ); + copy_rvec(erg->xc[i], data[i].x); copy_rvec(erg->rotg->x_ref[i], data[i].x_ref); } /* Sort the 'data' structure */ - std::sort(data, data+erg->rotg->nat, - [](const sort_along_vec_t &a, const sort_along_vec_t &b) - { - return a.xcproj < b.xcproj; - }); + std::sort(data, data + erg->rotg->nat, [](const sort_along_vec_t& a, const sort_along_vec_t& b) { + return a.xcproj < b.xcproj; + }); /* Copy back the sorted values */ for (int i = 0; i < erg->rotg->nat; i++) { - copy_rvec(data[i].x, erg->xc[i] ); + copy_rvec(data[i].x, erg->xc[i]); copy_rvec(data[i].x_ref, erg->xc_ref_sorted[i]); erg->mc_sorted[i] = data[i].m; erg->xc_sortind[i] = data[i].ind; @@ -2417,7 +2441,7 @@ static void sort_collective_coordinates( /* For each slab, get the first and the last index of the sorted atom * indices */ -static void get_firstlast_atom_per_slab(const gmx_enfrotgrp *erg) +static void get_firstlast_atom_per_slab(const gmx_enfrotgrp* erg) { real beta; @@ -2431,34 +2455,30 @@ static void get_firstlast_atom_per_slab(const gmx_enfrotgrp *erg) { beta = calc_beta(erg->xc[i], erg, n); i++; - } - while ((beta < -erg->max_beta) && (i < erg->rotg->nat)); + } while ((beta < -erg->max_beta) && (i < erg->rotg->nat)); i--; int slabIndex = n - erg->slab_first; /* slab index */ erg->firstatom[slabIndex] = i; /* Proceed to the next slab */ n++; - } - while (n <= erg->slab_last); + } while (n <= erg->slab_last); /* Find the last atom for each slab */ - n = erg->slab_last; /* start with last slab */ - i = erg->rotg->nat-1; /* start with the last atom */ + n = erg->slab_last; /* start with last slab */ + i = erg->rotg->nat - 1; /* start with the last atom */ do { - do /* move backward in position until a large enough beta is found */ + do /* move backward in position until a large enough beta is found */ { beta = calc_beta(erg->xc[i], erg, n); i--; - } - while ((beta > erg->max_beta) && (i > -1)); + } while ((beta > erg->max_beta) && (i > -1)); i++; int slabIndex = n - erg->slab_first; /* slab index */ erg->lastatom[slabIndex] = i; /* Proceed to the next slab */ n--; - } - while (n >= erg->slab_first); + } while (n >= erg->slab_first); } @@ -2474,28 +2494,26 @@ static void get_firstlast_atom_per_slab(const gmx_enfrotgrp *erg) * x_last * v - n*Delta_x >= -beta_max * */ -static inline int get_first_slab( - const gmx_enfrotgrp *erg, - rvec firstatom) /* First atom after sorting along the rotation vector v */ +static inline int get_first_slab(const gmx_enfrotgrp* erg, + rvec firstatom) /* First atom after sorting along the rotation vector v */ { /* Find the first slab for the first atom */ - return static_cast(ceil(static_cast((iprod(firstatom, erg->vec) - erg->max_beta)/erg->rotg->slab_dist))); + return static_cast(ceil( + static_cast((iprod(firstatom, erg->vec) - erg->max_beta) / erg->rotg->slab_dist))); } -static inline int get_last_slab( - const gmx_enfrotgrp *erg, - rvec lastatom) /* Last atom along v */ +static inline int get_last_slab(const gmx_enfrotgrp* erg, rvec lastatom) /* Last atom along v */ { /* Find the last slab for the last atom */ - return static_cast(floor(static_cast((iprod(lastatom, erg->vec) + erg->max_beta)/erg->rotg->slab_dist))); + return static_cast(floor( + static_cast((iprod(lastatom, erg->vec) + erg->max_beta) / erg->rotg->slab_dist))); } -static void get_firstlast_slab_check( - gmx_enfrotgrp *erg, /* The rotation group (data only accessible in this file) */ - rvec firstatom, /* First atom after sorting along the rotation vector v */ - rvec lastatom) /* Last atom along v */ +static void get_firstlast_slab_check(gmx_enfrotgrp* erg, /* The rotation group (data only accessible in this file) */ + rvec firstatom, /* First atom after sorting along the rotation vector v */ + rvec lastatom) /* Last atom along v */ { erg->slab_first = get_first_slab(erg, firstatom); erg->slab_last = get_last_slab(erg, lastatom); @@ -2506,35 +2524,34 @@ static void get_firstlast_slab_check( /* Check whether we have reference data to compare against */ if (erg->slab_first < erg->slab_first_ref) { - gmx_fatal(FARGS, "%s No reference data for first slab (n=%d), unable to proceed.", - RotStr, erg->slab_first); + gmx_fatal(FARGS, "%s No reference data for first slab (n=%d), unable to proceed.", RotStr, + erg->slab_first); } /* Check whether we have reference data to compare against */ if (erg->slab_last > erg->slab_last_ref) { - gmx_fatal(FARGS, "%s No reference data for last slab (n=%d), unable to proceed.", - RotStr, erg->slab_last); + gmx_fatal(FARGS, "%s No reference data for last slab (n=%d), unable to proceed.", RotStr, + erg->slab_last); } } /* Enforced rotation with a flexible axis */ -static void do_flexible( - gmx_bool bMaster, - gmx_enfrot *enfrot, /* Other rotation data */ - gmx_enfrotgrp *erg, - rvec x[], /* The local positions */ - const matrix box, - double t, /* Time in picoseconds */ - gmx_bool bOutstepRot, /* Output to main rotation output file */ - gmx_bool bOutstepSlab) /* Output per-slab data */ -{ - int nslabs; - real sigma; /* The Gaussian width sigma */ +static void do_flexible(gmx_bool bMaster, + gmx_enfrot* enfrot, /* Other rotation data */ + gmx_enfrotgrp* erg, + rvec x[], /* The local positions */ + const matrix box, + double t, /* Time in picoseconds */ + gmx_bool bOutstepRot, /* Output to main rotation output file */ + gmx_bool bOutstepSlab) /* Output per-slab data */ +{ + int nslabs; + real sigma; /* The Gaussian width sigma */ /* Define the sigma value */ - sigma = 0.7*erg->rotg->slab_dist; + sigma = 0.7 * erg->rotg->slab_dist; /* Sort the collective coordinates erg->xc along the rotation vector. This is * an optimization for the inner loop. */ @@ -2542,7 +2559,7 @@ static void do_flexible( /* Determine the first relevant slab for the first atom and the last * relevant slab for the last atom */ - get_firstlast_slab_check(erg, erg->xc[0], erg->xc[erg->rotg->nat-1]); + get_firstlast_slab_check(erg, erg->xc[0], erg->xc[erg->rotg->nat - 1]); /* Determine for each slab depending on the min_gaussian cutoff criterium, * a first and a last atom index inbetween stuff needs to be calculated */ @@ -2574,7 +2591,7 @@ static void do_flexible( /* Determine angle by RMSD fit to the reference - Let's hope this */ /* only happens once in a while, since this is not parallelized! */ - if (bMaster && (erotgFitPOT != erg->rotg->eFittype) ) + if (bMaster && (erotgFitPOT != erg->rotg->eFittype)) { if (bOutstepRot) { @@ -2599,13 +2616,13 @@ static void do_flexible( /* Calculate the angle between reference and actual rotation group atom, * both projected into a plane perpendicular to the rotation vector: */ -static void angle(const gmx_enfrotgrp *erg, +static void angle(const gmx_enfrotgrp* erg, rvec x_act, rvec x_ref, - real *alpha, - real *weight) /* atoms near the rotation axis should count less than atoms far away */ + real* alpha, + real* weight) /* atoms near the rotation axis should count less than atoms far away */ { - rvec xp, xrp; /* current and reference positions projected on a plane perpendicular to pg->vec */ + rvec xp, xrp; /* current and reference positions projected on a plane perpendicular to pg->vec */ rvec dum; @@ -2652,31 +2669,30 @@ static inline void project_onto_plane(rvec dr, const rvec v) /* Fixed rotation: The rotation reference group rotates around the v axis. */ /* The atoms of the actual rotation group are attached with imaginary */ /* springs to the reference atoms. */ -static void do_fixed( - gmx_enfrotgrp *erg, - gmx_bool bOutstepRot, /* Output to main rotation output file */ - gmx_bool bOutstepSlab) /* Output per-slab data */ -{ - rvec dr; - rvec tmp_f; /* Force */ - real alpha; /* a single angle between an actual and a reference position */ - real weight; /* single weight for a single angle */ - rvec xi_xc; /* xi - xc */ - gmx_bool bCalcPotFit; - rvec fit_xr_loc; +static void do_fixed(gmx_enfrotgrp* erg, + gmx_bool bOutstepRot, /* Output to main rotation output file */ + gmx_bool bOutstepSlab) /* Output per-slab data */ +{ + rvec dr; + rvec tmp_f; /* Force */ + real alpha; /* a single angle between an actual and a reference position */ + real weight; /* single weight for a single angle */ + rvec xi_xc; /* xi - xc */ + gmx_bool bCalcPotFit; + rvec fit_xr_loc; /* for mass weighting: */ - real wi; /* Mass-weighting of the positions */ - real N_M; /* N/M */ - real k_wi; /* k times wi */ + real wi; /* Mass-weighting of the positions */ + real N_M; /* N/M */ + real k_wi; /* k times wi */ - gmx_bool bProject; + gmx_bool bProject; bProject = (erg->rotg->eType == erotgPM) || (erg->rotg->eType == erotgPMPF); bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype); - N_M = erg->rotg->nat * erg->invmass; - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + N_M = erg->rotg->nat * erg->invmass; + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); /* Each process calculates the forces on its local atoms */ for (size_t j = 0; j < erg->atomSet->numAtomsLocal(); j++) { @@ -2692,16 +2708,16 @@ static void do_fixed( } /* Mass-weighting */ - wi = N_M*erg->m_loc[j]; + wi = N_M * erg->m_loc[j]; /* Store the additional force so that it can be added to the force * array after the normal forces have been evaluated */ - k_wi = erg->rotg->k*wi; + k_wi = erg->rotg->k * wi; for (int m = 0; m < DIM; m++) { - tmp_f[m] = k_wi*dr[m]; + tmp_f[m] = k_wi * dr[m]; erg->f_rot_loc[j][m] = tmp_f[m]; - erg->V += 0.5*k_wi*gmx::square(dr[m]); + erg->V += 0.5 * k_wi * gmx::square(dr[m]); } /* If requested, also calculate the potential for a set of angles @@ -2715,7 +2731,8 @@ static void do_fixed( /* Rotate with the alternative angle. Like rotate_local_reference(), * just for a single local atom */ - mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], fit_xr_loc); /* fit_xr_loc = Omega*(y_i-y_c) */ + mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], + fit_xr_loc); /* fit_xr_loc = Omega*(y_i-y_c) */ /* Calculate Omega*(y_i-y_c)-(x_i-x_c) */ rvec_sub(fit_xr_loc, xi_xc, dr); @@ -2726,7 +2743,7 @@ static void do_fixed( } /* Add to the rotation potential for this angle: */ - erg->PotAngleFit->V[ifit] += 0.5*k_wi*norm2(dr); + erg->PotAngleFit->V[ifit] += 0.5 * k_wi * norm2(dr); } } @@ -2736,8 +2753,8 @@ static void do_fixed( erg->torque_v += torque(erg->vec, tmp_f, erg->x_loc_pbc[j], erg->xc_center); /* Calculate the angle between reference and actual rotation group atom. */ - angle(erg, xi_xc, erg->xr_loc[j], &alpha, &weight); /* angle in rad, weighted */ - erg->angle_v += alpha * weight; + angle(erg, xi_xc, erg->xr_loc[j], &alpha, &weight); /* angle in rad, weighted */ + erg->angle_v += alpha * weight; erg->weight_v += weight; } /* If you want enforced rotation to contribute to the virial, @@ -2758,52 +2775,51 @@ static void do_fixed( /* Calculate the radial motion potential and forces */ -static void do_radial_motion( - gmx_enfrotgrp *erg, - gmx_bool bOutstepRot, /* Output to main rotation output file */ - gmx_bool bOutstepSlab) /* Output per-slab data */ -{ - rvec tmp_f; /* Force */ - real alpha; /* a single angle between an actual and a reference position */ - real weight; /* single weight for a single angle */ - rvec xj_u; /* xj - u */ - rvec tmpvec, fit_tmpvec; - real fac, fac2, sum = 0.0; - rvec pj; - gmx_bool bCalcPotFit; +static void do_radial_motion(gmx_enfrotgrp* erg, + gmx_bool bOutstepRot, /* Output to main rotation output file */ + gmx_bool bOutstepSlab) /* Output per-slab data */ +{ + rvec tmp_f; /* Force */ + real alpha; /* a single angle between an actual and a reference position */ + real weight; /* single weight for a single angle */ + rvec xj_u; /* xj - u */ + rvec tmpvec, fit_tmpvec; + real fac, fac2, sum = 0.0; + rvec pj; + gmx_bool bCalcPotFit; /* For mass weighting: */ - real wj; /* Mass-weighting of the positions */ - real N_M; /* N/M */ + real wj; /* Mass-weighting of the positions */ + real N_M; /* N/M */ bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype); - N_M = erg->rotg->nat * erg->invmass; - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + N_M = erg->rotg->nat * erg->invmass; + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); /* Each process calculates the forces on its local atoms */ for (size_t j = 0; j < erg->atomSet->numAtomsLocal(); j++) { /* Calculate (xj-u) */ - rvec_sub(erg->x_loc_pbc[j], erg->xc_center, xj_u); /* xj_u = xj-u */ + rvec_sub(erg->x_loc_pbc[j], erg->xc_center, xj_u); /* xj_u = xj-u */ /* Calculate Omega.(yj0-u) */ - cprod(erg->vec, erg->xr_loc[j], tmpvec); /* tmpvec = v x Omega.(yj0-u) */ + cprod(erg->vec, erg->xr_loc[j], tmpvec); /* tmpvec = v x Omega.(yj0-u) */ /* * v x Omega.(yj0-u) */ - unitv(tmpvec, pj); /* pj = --------------------- */ - /* | v x Omega.(yj0-u) | */ + unitv(tmpvec, pj); /* pj = --------------------- */ + /* | v x Omega.(yj0-u) | */ fac = iprod(pj, xj_u); /* fac = pj.(xj-u) */ - fac2 = fac*fac; + fac2 = fac * fac; /* Mass-weighting */ - wj = N_M*erg->m_loc[j]; + wj = N_M * erg->m_loc[j]; /* Store the additional force so that it can be added to the force * array after the normal forces have been evaluated */ - svmul(-erg->rotg->k*wj*fac, pj, tmp_f); + svmul(-erg->rotg->k * wj * fac, pj, tmp_f); copy_rvec(tmp_f, erg->f_rot_loc[j]); - sum += wj*fac2; + sum += wj * fac2; /* If requested, also calculate the potential for a set of angles * near the current reference angle */ @@ -2816,19 +2832,20 @@ static void do_radial_motion( /* Rotate with the alternative angle. Like rotate_local_reference(), * just for a single local atom */ - mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], fit_tmpvec); /* fit_tmpvec = Omega*(yj0-u) */ + mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[jj], + fit_tmpvec); /* fit_tmpvec = Omega*(yj0-u) */ /* Calculate Omega.(yj0-u) */ cprod(erg->vec, fit_tmpvec, tmpvec); /* tmpvec = v x Omega.(yj0-u) */ /* * v x Omega.(yj0-u) */ - unitv(tmpvec, pj); /* pj = --------------------- */ - /* | v x Omega.(yj0-u) | */ + unitv(tmpvec, pj); /* pj = --------------------- */ + /* | v x Omega.(yj0-u) | */ - fac = iprod(pj, xj_u); /* fac = pj.(xj-u) */ - fac2 = fac*fac; + fac = iprod(pj, xj_u); /* fac = pj.(xj-u) */ + fac2 = fac * fac; /* Add to the rotation potential for this angle: */ - erg->PotAngleFit->V[ifit] += 0.5*erg->rotg->k*wj*fac2; + erg->PotAngleFit->V[ifit] += 0.5 * erg->rotg->k * wj * fac2; } } @@ -2838,42 +2855,41 @@ static void do_radial_motion( erg->torque_v += torque(erg->vec, tmp_f, erg->x_loc_pbc[j], erg->xc_center); /* Calculate the angle between reference and actual rotation group atom. */ - angle(erg, xj_u, erg->xr_loc[j], &alpha, &weight); /* angle in rad, weighted */ - erg->angle_v += alpha * weight; + angle(erg, xj_u, erg->xr_loc[j], &alpha, &weight); /* angle in rad, weighted */ + erg->angle_v += alpha * weight; erg->weight_v += weight; } PRINT_FORCE_J } /* end of loop over local rotation group atoms */ - erg->V = 0.5*erg->rotg->k*sum; + erg->V = 0.5 * erg->rotg->k * sum; } /* Calculate the radial motion pivot-free potential and forces */ -static void do_radial_motion_pf( - gmx_enfrotgrp *erg, - rvec x[], /* The positions */ - const matrix box, /* The simulation box */ - gmx_bool bOutstepRot, /* Output to main rotation output file */ - gmx_bool bOutstepSlab) /* Output per-slab data */ -{ - rvec xj; /* Current position */ - rvec xj_xc; /* xj - xc */ - rvec yj0_yc0; /* yj0 - yc0 */ - rvec tmp_f; /* Force */ - real alpha; /* a single angle between an actual and a reference position */ - real weight; /* single weight for a single angle */ - rvec tmpvec, tmpvec2; - rvec innersumvec; /* Precalculation of the inner sum */ - rvec innersumveckM; - real fac, fac2, V = 0.0; - rvec qi, qj; - gmx_bool bCalcPotFit; +static void do_radial_motion_pf(gmx_enfrotgrp* erg, + rvec x[], /* The positions */ + const matrix box, /* The simulation box */ + gmx_bool bOutstepRot, /* Output to main rotation output file */ + gmx_bool bOutstepSlab) /* Output per-slab data */ +{ + rvec xj; /* Current position */ + rvec xj_xc; /* xj - xc */ + rvec yj0_yc0; /* yj0 - yc0 */ + rvec tmp_f; /* Force */ + real alpha; /* a single angle between an actual and a reference position */ + real weight; /* single weight for a single angle */ + rvec tmpvec, tmpvec2; + rvec innersumvec; /* Precalculation of the inner sum */ + rvec innersumveckM; + real fac, fac2, V = 0.0; + rvec qi, qj; + gmx_bool bCalcPotFit; /* For mass weighting: */ - real mj, wi, wj; /* Mass-weighting of the positions */ - real N_M; /* N/M */ + real mj, wi, wj; /* Mass-weighting of the positions */ + real N_M; /* N/M */ bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype); @@ -2887,29 +2903,29 @@ static void do_radial_motion_pf( for (int i = 0; i < erg->rotg->nat; i++) { /* Mass-weighting */ - wi = N_M*erg->mc[i]; + wi = N_M * erg->mc[i]; /* Calculate qi. Note that xc_ref_center has already been subtracted from * x_ref in init_rot_group.*/ mvmul(erg->rotmat, erg->rotg->x_ref[i], tmpvec); /* tmpvec = Omega.(yi0-yc0) */ - cprod(erg->vec, tmpvec, tmpvec2); /* tmpvec2 = v x Omega.(yi0-yc0) */ + cprod(erg->vec, tmpvec, tmpvec2); /* tmpvec2 = v x Omega.(yi0-yc0) */ /* * v x Omega.(yi0-yc0) */ - unitv(tmpvec2, qi); /* qi = ----------------------- */ - /* | v x Omega.(yi0-yc0) | */ + unitv(tmpvec2, qi); /* qi = ----------------------- */ + /* | v x Omega.(yi0-yc0) | */ rvec_sub(erg->xc[i], erg->xc_center, tmpvec); /* tmpvec = xi-xc */ - svmul(wi*iprod(qi, tmpvec), qi, tmpvec2); + svmul(wi * iprod(qi, tmpvec), qi, tmpvec2); rvec_inc(innersumvec, tmpvec2); } - svmul(erg->rotg->k*erg->invmass, innersumvec, innersumveckM); + svmul(erg->rotg->k * erg->invmass, innersumvec, innersumveckM); /* Each process calculates the forces on its local atoms */ - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (gmx::index j = 0; j < localRotationGroupIndex.ssize(); j++) { /* Local index of a rotation group atom */ @@ -2917,8 +2933,8 @@ static void do_radial_motion_pf( /* Position of this atom in the collective array */ int iigrp = collectiveRotationGroupIndex[j]; /* Mass-weighting */ - mj = erg->mc[iigrp]; /* need the unsorted mass here */ - wj = N_M*mj; + mj = erg->mc[iigrp]; /* need the unsorted mass here */ + wj = N_M * mj; /* Current position of this atom: x[ii][XX/YY/ZZ] */ copy_rvec(x[ii], xj); @@ -2928,30 +2944,30 @@ static void do_radial_motion_pf( /* The (unrotated) reference position is yj0. yc0 has already * been subtracted in init_rot_group */ - copy_rvec(erg->rotg->x_ref[iigrp], yj0_yc0); /* yj0_yc0 = yj0 - yc0 */ + copy_rvec(erg->rotg->x_ref[iigrp], yj0_yc0); /* yj0_yc0 = yj0 - yc0 */ /* Calculate Omega.(yj0-yc0) */ mvmul(erg->rotmat, yj0_yc0, tmpvec2); /* tmpvec2 = Omega.(yj0 - yc0) */ - cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x Omega.(yj0-yc0) */ + cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x Omega.(yj0-yc0) */ /* * v x Omega.(yj0-yc0) */ - unitv(tmpvec, qj); /* qj = ----------------------- */ - /* | v x Omega.(yj0-yc0) | */ + unitv(tmpvec, qj); /* qj = ----------------------- */ + /* | v x Omega.(yj0-yc0) | */ /* Calculate (xj-xc) */ rvec_sub(xj, erg->xc_center, xj_xc); /* xj_xc = xj-xc */ - fac = iprod(qj, xj_xc); /* fac = qj.(xj-xc) */ - fac2 = fac*fac; + fac = iprod(qj, xj_xc); /* fac = qj.(xj-xc) */ + fac2 = fac * fac; /* Store the additional force so that it can be added to the force * array after the normal forces have been evaluated */ - svmul(-erg->rotg->k*wj*fac, qj, tmp_f); /* part 1 of force */ - svmul(mj, innersumveckM, tmpvec); /* part 2 of force */ + svmul(-erg->rotg->k * wj * fac, qj, tmp_f); /* part 1 of force */ + svmul(mj, innersumveckM, tmpvec); /* part 2 of force */ rvec_inc(tmp_f, tmpvec); copy_rvec(tmp_f, erg->f_rot_loc[j]); - V += wj*fac2; + V += wj * fac2; /* If requested, also calculate the potential for a set of angles * near the current reference angle */ @@ -2966,14 +2982,14 @@ static void do_radial_motion_pf( /* Calculate Omega.(yj0-u) */ cprod(erg->vec, tmpvec2, tmpvec); /* tmpvec = v x Omega.(yj0-yc0) */ /* * v x Omega.(yj0-yc0) */ - unitv(tmpvec, qj); /* qj = ----------------------- */ - /* | v x Omega.(yj0-yc0) | */ + unitv(tmpvec, qj); /* qj = ----------------------- */ + /* | v x Omega.(yj0-yc0) | */ - fac = iprod(qj, xj_xc); /* fac = qj.(xj-xc) */ - fac2 = fac*fac; + fac = iprod(qj, xj_xc); /* fac = qj.(xj-xc) */ + fac2 = fac * fac; /* Add to the rotation potential for this angle: */ - erg->PotAngleFit->V[ifit] += 0.5*erg->rotg->k*wj*fac2; + erg->PotAngleFit->V[ifit] += 0.5 * erg->rotg->k * wj * fac2; } } @@ -2983,33 +2999,32 @@ static void do_radial_motion_pf( erg->torque_v += torque(erg->vec, tmp_f, xj, erg->xc_center); /* Calculate the angle between reference and actual rotation group atom. */ - angle(erg, xj_xc, yj0_yc0, &alpha, &weight); /* angle in rad, weighted */ - erg->angle_v += alpha * weight; + angle(erg, xj_xc, yj0_yc0, &alpha, &weight); /* angle in rad, weighted */ + erg->angle_v += alpha * weight; erg->weight_v += weight; } PRINT_FORCE_J } /* end of loop over local rotation group atoms */ - erg->V = 0.5*erg->rotg->k*V; + erg->V = 0.5 * erg->rotg->k * V; } /* Precalculate the inner sum for the radial motion 2 forces */ -static void radial_motion2_precalc_inner_sum(const gmx_enfrotgrp *erg, - rvec innersumvec) -{ - int i; - rvec xi_xc; /* xj - xc */ - rvec tmpvec, tmpvec2; - real fac; - rvec ri, si; - real siri; - rvec v_xi_xc; /* v x (xj - u) */ - real psii, psiistar; - real wi; /* Mass-weighting of the positions */ - real N_M; /* N/M */ - rvec sumvec; +static void radial_motion2_precalc_inner_sum(const gmx_enfrotgrp* erg, rvec innersumvec) +{ + int i; + rvec xi_xc; /* xj - xc */ + rvec tmpvec, tmpvec2; + real fac; + rvec ri, si; + real siri; + rvec v_xi_xc; /* v x (xj - u) */ + real psii, psiistar; + real wi; /* Mass-weighting of the positions */ + real N_M; /* N/M */ + rvec sumvec; N_M = erg->rotg->nat * erg->invmass; @@ -3018,7 +3033,7 @@ static void radial_motion2_precalc_inner_sum(const gmx_enfrotgrp *erg, for (i = 0; i < erg->rotg->nat; i++) { /* Mass-weighting */ - wi = N_M*erg->mc[i]; + wi = N_M * erg->mc[i]; rvec_sub(erg->xc[i], erg->xc_center, xi_xc); /* xi_xc = xi-xc */ @@ -3026,58 +3041,57 @@ static void radial_motion2_precalc_inner_sum(const gmx_enfrotgrp *erg, * x_ref in init_rot_group.*/ mvmul(erg->rotmat, erg->rotg->x_ref[i], ri); /* ri = Omega.(yi0-yc0) */ - cprod(erg->vec, xi_xc, v_xi_xc); /* v_xi_xc = v x (xi-u) */ + cprod(erg->vec, xi_xc, v_xi_xc); /* v_xi_xc = v x (xi-u) */ fac = norm2(v_xi_xc); /* * 1 */ - psiistar = 1.0/(fac + erg->rotg->eps); /* psiistar = --------------------- */ + psiistar = 1.0 / (fac + erg->rotg->eps); /* psiistar = --------------------- */ /* |v x (xi-xc)|^2 + eps */ - psii = gmx::invsqrt(fac); /* 1 */ - /* psii = ------------- */ - /* |v x (xi-xc)| */ + psii = gmx::invsqrt(fac); /* 1 */ + /* psii = ------------- */ + /* |v x (xi-xc)| */ - svmul(psii, v_xi_xc, si); /* si = psii * (v x (xi-xc) ) */ + svmul(psii, v_xi_xc, si); /* si = psii * (v x (xi-xc) ) */ - siri = iprod(si, ri); /* siri = si.ri */ + siri = iprod(si, ri); /* siri = si.ri */ - svmul(psiistar/psii, ri, tmpvec); - svmul(psiistar*psiistar/(psii*psii*psii) * siri, si, tmpvec2); + svmul(psiistar / psii, ri, tmpvec); + svmul(psiistar * psiistar / (psii * psii * psii) * siri, si, tmpvec2); rvec_dec(tmpvec, tmpvec2); cprod(tmpvec, erg->vec, tmpvec2); - svmul(wi*siri, tmpvec2, tmpvec); + svmul(wi * siri, tmpvec2, tmpvec); rvec_inc(sumvec, tmpvec); } - svmul(erg->rotg->k*erg->invmass, sumvec, innersumvec); + svmul(erg->rotg->k * erg->invmass, sumvec, innersumvec); } /* Calculate the radial motion 2 potential and forces */ -static void do_radial_motion2( - gmx_enfrotgrp *erg, - rvec x[], /* The positions */ - const matrix box, /* The simulation box */ - gmx_bool bOutstepRot, /* Output to main rotation output file */ - gmx_bool bOutstepSlab) /* Output per-slab data */ -{ - rvec xj; /* Position */ - real alpha; /* a single angle between an actual and a reference position */ - real weight; /* single weight for a single angle */ - rvec xj_u; /* xj - u */ - rvec yj0_yc0; /* yj0 -yc0 */ - rvec tmpvec, tmpvec2; - real fac, fit_fac, fac2, Vpart = 0.0; - rvec rj, fit_rj, sj; - real sjrj; - rvec v_xj_u; /* v x (xj - u) */ - real psij, psijstar; - real mj, wj; /* For mass-weighting of the positions */ - real N_M; /* N/M */ - gmx_bool bPF; - rvec innersumvec; - gmx_bool bCalcPotFit; +static void do_radial_motion2(gmx_enfrotgrp* erg, + rvec x[], /* The positions */ + const matrix box, /* The simulation box */ + gmx_bool bOutstepRot, /* Output to main rotation output file */ + gmx_bool bOutstepSlab) /* Output per-slab data */ +{ + rvec xj; /* Position */ + real alpha; /* a single angle between an actual and a reference position */ + real weight; /* single weight for a single angle */ + rvec xj_u; /* xj - u */ + rvec yj0_yc0; /* yj0 -yc0 */ + rvec tmpvec, tmpvec2; + real fac, fit_fac, fac2, Vpart = 0.0; + rvec rj, fit_rj, sj; + real sjrj; + rvec v_xj_u; /* v x (xj - u) */ + real psij, psijstar; + real mj, wj; /* For mass-weighting of the positions */ + real N_M; /* N/M */ + gmx_bool bPF; + rvec innersumvec; + gmx_bool bCalcPotFit; bPF = erg->rotg->eType == erotgRM2PF; bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype); @@ -3099,8 +3113,8 @@ static void do_radial_motion2( N_M = erg->rotg->nat * erg->invmass; /* Each process calculates the forces on its local atoms */ - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (gmx::index j = 0; j < localRotationGroupIndex.ssize(); j++) { if (bPF) @@ -3120,53 +3134,53 @@ static void do_radial_motion2( /* The (unrotated) reference position is yj0. yc0 has already * been subtracted in init_rot_group */ - copy_rvec(erg->rotg->x_ref[iigrp], yj0_yc0); /* yj0_yc0 = yj0 - yc0 */ + copy_rvec(erg->rotg->x_ref[iigrp], yj0_yc0); /* yj0_yc0 = yj0 - yc0 */ /* Calculate Omega.(yj0-yc0) */ - mvmul(erg->rotmat, yj0_yc0, rj); /* rj = Omega.(yj0-yc0) */ + mvmul(erg->rotmat, yj0_yc0, rj); /* rj = Omega.(yj0-yc0) */ } else { mj = erg->m_loc[j]; copy_rvec(erg->x_loc_pbc[j], xj); - copy_rvec(erg->xr_loc[j], rj); /* rj = Omega.(yj0-u) */ + copy_rvec(erg->xr_loc[j], rj); /* rj = Omega.(yj0-u) */ } /* Mass-weighting */ - wj = N_M*mj; + wj = N_M * mj; /* Calculate (xj-u) resp. (xj-xc) */ - rvec_sub(xj, erg->xc_center, xj_u); /* xj_u = xj-u */ + rvec_sub(xj, erg->xc_center, xj_u); /* xj_u = xj-u */ - cprod(erg->vec, xj_u, v_xj_u); /* v_xj_u = v x (xj-u) */ + cprod(erg->vec, xj_u, v_xj_u); /* v_xj_u = v x (xj-u) */ fac = norm2(v_xj_u); /* * 1 */ - psijstar = 1.0/(fac + erg->rotg->eps); /* psistar = -------------------- */ + psijstar = 1.0 / (fac + erg->rotg->eps); /* psistar = -------------------- */ /* * |v x (xj-u)|^2 + eps */ - psij = gmx::invsqrt(fac); /* 1 */ - /* psij = ------------ */ - /* |v x (xj-u)| */ + psij = gmx::invsqrt(fac); /* 1 */ + /* psij = ------------ */ + /* |v x (xj-u)| */ - svmul(psij, v_xj_u, sj); /* sj = psij * (v x (xj-u) ) */ + svmul(psij, v_xj_u, sj); /* sj = psij * (v x (xj-u) ) */ - fac = iprod(v_xj_u, rj); /* fac = (v x (xj-u)).rj */ - fac2 = fac*fac; + fac = iprod(v_xj_u, rj); /* fac = (v x (xj-u)).rj */ + fac2 = fac * fac; - sjrj = iprod(sj, rj); /* sjrj = sj.rj */ + sjrj = iprod(sj, rj); /* sjrj = sj.rj */ - svmul(psijstar/psij, rj, tmpvec); - svmul(psijstar*psijstar/(psij*psij*psij) * sjrj, sj, tmpvec2); + svmul(psijstar / psij, rj, tmpvec); + svmul(psijstar * psijstar / (psij * psij * psij) * sjrj, sj, tmpvec2); rvec_dec(tmpvec, tmpvec2); cprod(tmpvec, erg->vec, tmpvec2); /* Store the additional force so that it can be added to the force * array after the normal forces have been evaluated */ - svmul(-erg->rotg->k*wj*sjrj, tmpvec2, tmpvec); - svmul(mj, innersumvec, tmpvec2); /* This is != 0 only for the pivot-free variant */ + svmul(-erg->rotg->k * wj * sjrj, tmpvec2, tmpvec); + svmul(mj, innersumvec, tmpvec2); /* This is != 0 only for the pivot-free variant */ rvec_add(tmpvec2, tmpvec, erg->f_rot_loc[j]); - Vpart += wj*psijstar*fac2; + Vpart += wj * psijstar * fac2; /* If requested, also calculate the potential for a set of angles * near the current reference angle */ @@ -3184,11 +3198,12 @@ static void do_radial_motion2( int iigrp = collectiveRotationGroupIndex[j]; /* Rotate with the alternative angle. Like rotate_local_reference(), * just for a single local atom */ - mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[iigrp], fit_rj); /* fit_rj = Omega*(yj0-u) */ + mvmul(erg->PotAngleFit->rotmat[ifit], erg->rotg->x_ref[iigrp], + fit_rj); /* fit_rj = Omega*(yj0-u) */ } - fit_fac = iprod(v_xj_u, fit_rj); /* fac = (v x (xj-u)).fit_rj */ + fit_fac = iprod(v_xj_u, fit_rj); /* fac = (v x (xj-u)).fit_rj */ /* Add to the rotation potential for this angle: */ - erg->PotAngleFit->V[ifit] += 0.5*erg->rotg->k*wj*psijstar*fit_fac*fit_fac; + erg->PotAngleFit->V[ifit] += 0.5 * erg->rotg->k * wj * psijstar * fit_fac * fit_fac; } } @@ -3198,29 +3213,26 @@ static void do_radial_motion2( erg->torque_v += torque(erg->vec, erg->f_rot_loc[j], xj, erg->xc_center); /* Calculate the angle between reference and actual rotation group atom. */ - angle(erg, xj_u, rj, &alpha, &weight); /* angle in rad, weighted */ - erg->angle_v += alpha * weight; + angle(erg, xj_u, rj, &alpha, &weight); /* angle in rad, weighted */ + erg->angle_v += alpha * weight; erg->weight_v += weight; } PRINT_FORCE_J } /* end of loop over local rotation group atoms */ - erg->V = 0.5*erg->rotg->k*Vpart; + erg->V = 0.5 * erg->rotg->k * Vpart; } /* Determine the smallest and largest position vector (with respect to the * rotation vector) for the reference group */ -static void get_firstlast_atom_ref( - const gmx_enfrotgrp *erg, - int *firstindex, - int *lastindex) +static void get_firstlast_atom_ref(const gmx_enfrotgrp* erg, int* firstindex, int* lastindex) { - int i; - real xcproj; /* The projection of a reference position on the - rotation vector */ - real minproj, maxproj; /* Smallest and largest projection on v */ + int i; + real xcproj; /* The projection of a reference position on the + rotation vector */ + real minproj, maxproj; /* Smallest and largest projection on v */ /* Start with some value */ minproj = iprod(erg->rotg->x_ref[0], erg->vec); @@ -3230,7 +3242,7 @@ static void get_firstlast_atom_ref( * reference structure are situated in a plane perpendicular to the rotation * vector */ *firstindex = 0; - *lastindex = erg->rotg->nat-1; + *lastindex = erg->rotg->nat - 1; /* Loop over all atoms of the reference group, * project them on the rotation vector to find the extremes */ @@ -3252,10 +3264,7 @@ static void get_firstlast_atom_ref( /* Allocate memory for the slabs */ -static void allocate_slabs( - gmx_enfrotgrp *erg, - FILE *fplog, - gmx_bool bVerbose) +static void allocate_slabs(gmx_enfrotgrp* erg, FILE* fplog, gmx_bool bVerbose) { /* More slabs than are defined for the reference are never needed */ int nslabs = erg->slab_last_ref - erg->slab_first_ref + 1; @@ -3263,7 +3272,7 @@ static void allocate_slabs( /* Remember how many we allocated */ erg->nslabs_alloc = nslabs; - if ( (nullptr != fplog) && bVerbose) + if ((nullptr != fplog) && bVerbose) { fprintf(fplog, "%s allocating memory to store data for %d slabs (rotation group %d).\n", RotStr, nslabs, erg->groupIndex); @@ -3293,40 +3302,38 @@ static void allocate_slabs( * and last slab of the reference. We can never have more slabs in the real * simulation than calculated here for the reference. */ -static void get_firstlast_slab_ref(gmx_enfrotgrp *erg, - real mc[], int ref_firstindex, int ref_lastindex) +static void get_firstlast_slab_ref(gmx_enfrotgrp* erg, real mc[], int ref_firstindex, int ref_lastindex) { rvec dummy; - int first = get_first_slab(erg, erg->rotg->x_ref[ref_firstindex]); - int last = get_last_slab(erg, erg->rotg->x_ref[ref_lastindex ]); + int first = get_first_slab(erg, erg->rotg->x_ref[ref_firstindex]); + int last = get_last_slab(erg, erg->rotg->x_ref[ref_lastindex]); while (get_slab_weight(first, erg, erg->rotg->x_ref, mc, &dummy) > WEIGHT_MIN) { first--; } - erg->slab_first_ref = first+1; + erg->slab_first_ref = first + 1; while (get_slab_weight(last, erg, erg->rotg->x_ref, mc, &dummy) > WEIGHT_MIN) { last++; } - erg->slab_last_ref = last-1; + erg->slab_last_ref = last - 1; } /* Special version of copy_rvec: * During the copy procedure of xcurr to b, the correct PBC image is chosen * such that the copied vector ends up near its reference position xref */ -static inline void copy_correct_pbc_image( - const rvec xcurr, /* copy vector xcurr ... */ - rvec b, /* ... to b ... */ - const rvec xref, /* choosing the PBC image such that b ends up near xref */ - const matrix box, - int npbcdim) +static inline void copy_correct_pbc_image(const rvec xcurr, /* copy vector xcurr ... */ + rvec b, /* ... to b ... */ + const rvec xref, /* choosing the PBC image such that b ends up near xref */ + const matrix box, + int npbcdim) { - rvec dx; - int d, m; - ivec shift; + rvec dx; + int d, m; + ivec shift; /* Shortest PBC distance between the atom and its reference */ @@ -3334,9 +3341,9 @@ static inline void copy_correct_pbc_image( /* Determine the shift for this atom */ clear_ivec(shift); - for (m = npbcdim-1; m >= 0; m--) + for (m = npbcdim - 1; m >= 0; m--) { - while (dx[m] < -0.5*box[m][m]) + while (dx[m] < -0.5 * box[m][m]) { for (d = 0; d < DIM; d++) { @@ -3344,7 +3351,7 @@ static inline void copy_correct_pbc_image( } shift[m]++; } - while (dx[m] >= 0.5*box[m][m]) + while (dx[m] >= 0.5 * box[m][m]) { for (d = 0; d < DIM; d++) { @@ -3360,10 +3367,16 @@ static inline void copy_correct_pbc_image( } -static void init_rot_group(FILE *fplog, const t_commrec *cr, - gmx_enfrotgrp *erg, - rvec *x, gmx_mtop_t *mtop, gmx_bool bVerbose, FILE *out_slabs, const matrix box, - t_inputrec *ir, gmx_bool bOutputCenters) +static void init_rot_group(FILE* fplog, + const t_commrec* cr, + gmx_enfrotgrp* erg, + rvec* x, + gmx_mtop_t* mtop, + gmx_bool bVerbose, + FILE* out_slabs, + const matrix box, + t_inputrec* ir, + gmx_bool bOutputCenters) { rvec coord, xref, *xdum; gmx_bool bFlex, bColl; @@ -3371,7 +3384,7 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, real mass, totalmass; real start = 0.0; double t_start; - const t_rotgrp *rotg = erg->rotg; + const t_rotgrp* rotg = erg->rotg; /* Do we have a flexible axis? */ @@ -3412,10 +3425,10 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, snew(erg->PotAngleFit->rotmat, erg->rotg->PotAngle_nstep); /* Get the set of angles around the reference angle */ - start = -0.5 * (erg->rotg->PotAngle_nstep - 1)*erg->rotg->PotAngle_step; + start = -0.5 * (erg->rotg->PotAngle_nstep - 1) * erg->rotg->PotAngle_step; for (int i = 0; i < erg->rotg->PotAngle_nstep; i++) { - erg->PotAngleFit->degangle[i] = start + i*erg->rotg->PotAngle_step; + erg->PotAngleFit->degangle[i] = start + i * erg->rotg->PotAngle_step; } } else @@ -3449,15 +3462,16 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, erg->mc[i] = mass; totalmass += mass; } - erg->invmass = 1.0/totalmass; + erg->invmass = 1.0 / totalmass; /* Set xc_ref_center for any rotation potential */ - if ((erg->rotg->eType == erotgISO) || (erg->rotg->eType == erotgPM) || (erg->rotg->eType == erotgRM) || (erg->rotg->eType == erotgRM2)) + if ((erg->rotg->eType == erotgISO) || (erg->rotg->eType == erotgPM) + || (erg->rotg->eType == erotgRM) || (erg->rotg->eType == erotgRM2)) { /* Set the pivot point for the fixed, stationary-axis potentials. This * won't change during the simulation */ copy_rvec(erg->rotg->pivot, erg->xc_ref_center); - copy_rvec(erg->rotg->pivot, erg->xc_center ); + copy_rvec(erg->rotg->pivot, erg->xc_center); } else { @@ -3494,7 +3508,7 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, if (MASTER(cr)) { /* Calculate the rotation matrix for this angle: */ - t_start = ir->init_t + ir->init_step*ir->delta_t; + t_start = ir->init_t + ir->init_step * ir->delta_t; erg->degangle = erg->rotg->rate * t_start; calc_rotmat(erg->vec, erg->degangle, erg->rotmat); @@ -3514,12 +3528,12 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, #if GMX_MPI if (PAR(cr)) { - gmx_bcast(erg->rotg->nat*sizeof(erg->xc_old[0]), erg->xc_old, cr); + gmx_bcast(erg->rotg->nat * sizeof(erg->xc_old[0]), erg->xc_old, cr); } #endif } - if ( (erg->rotg->eType != erotgFLEX) && (erg->rotg->eType != erotgFLEX2) ) + if ((erg->rotg->eType != erotgFLEX) && (erg->rotg->eType != erotgFLEX2)) { /* Put the reference positions into origin: */ for (int i = 0; i < erg->rotg->nat; i++) @@ -3562,14 +3576,14 @@ static void init_rot_group(FILE *fplog, const t_commrec *cr, } /* Calculate the size of the MPI buffer needed in reduce_output() */ -static int calc_mpi_bufsize(const gmx_enfrot *er) +static int calc_mpi_bufsize(const gmx_enfrot* er) { int count_total = 0; for (int g = 0; g < er->rot->ngrp; g++) { - const t_rotgrp *rotg = &er->rot->grp[g]; - const gmx_enfrotgrp *erg = &er->enfrotgrp[g]; + const t_rotgrp* rotg = &er->rot->grp[g]; + const gmx_enfrotgrp* erg = &er->enfrotgrp[g]; /* Count the items that are transferred for this group: */ int count_group = 4; /* V, torque, angle, weight */ @@ -3594,14 +3608,20 @@ static int calc_mpi_bufsize(const gmx_enfrot *er) } -std::unique_ptr -init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], - const t_commrec *cr, gmx::LocalAtomSetManager * atomSets, const t_state *globalState, gmx_mtop_t *mtop, const gmx_output_env_t *oenv, - const gmx::MdrunOptions &mdrunOptions, - const gmx::StartingBehavior startingBehavior) +std::unique_ptr init_rot(FILE* fplog, + t_inputrec* ir, + int nfile, + const t_filenm fnm[], + const t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + const t_state* globalState, + gmx_mtop_t* mtop, + const gmx_output_env_t* oenv, + const gmx::MdrunOptions& mdrunOptions, + const gmx::StartingBehavior startingBehavior) { - int nat_max = 0; /* Size of biggest rotation group */ - rvec *x_pbc = nullptr; /* Space for the pbc-correct atom positions */ + int nat_max = 0; /* Size of biggest rotation group */ + rvec* x_pbc = nullptr; /* Space for the pbc-correct atom positions */ if (MASTER(cr) && mdrunOptions.verbose) { @@ -3609,7 +3629,7 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], } auto enforcedRotation = std::make_unique(); - gmx_enfrot *er = enforcedRotation->getLegacyEnfrot(); + gmx_enfrot* er = enforcedRotation->getLegacyEnfrot(); // TODO When this module implements IMdpOptions, the ownership will become more clear. er->rot = ir->rot; er->restartWithAppending = (startingBehavior == gmx::StartingBehavior::RestartWithAppending); @@ -3646,7 +3666,7 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], } er->out_slabs = nullptr; - if (MASTER(cr) && HaveFlexibleGroups(er->rot) ) + if (MASTER(cr) && HaveFlexibleGroups(er->rot)) { er->out_slabs = open_slab_out(opt2fn("-rs", nfile, fnm), er); } @@ -3667,11 +3687,12 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], /* Allocate space for the per-rotation-group data: */ er->enfrotgrp.resize(er->rot->ngrp); int groupIndex = 0; - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - erg->rotg = &er->rot->grp[groupIndex]; - erg->atomSet = std::make_unique(atomSets->add({erg->rotg->ind, erg->rotg->ind + erg->rotg->nat})); + gmx_enfrotgrp* erg = &ergRef; + erg->rotg = &er->rot->grp[groupIndex]; + erg->atomSet = std::make_unique( + atomSets->add({ erg->rotg->ind, erg->rotg->ind + erg->rotg->nat })); erg->groupIndex = groupIndex; if (nullptr != fplog) @@ -3683,7 +3704,8 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], { nat_max = std::max(nat_max, erg->rotg->nat); - init_rot_group(fplog, cr, erg, x_pbc, mtop, mdrunOptions.verbose, er->out_slabs, MASTER(cr) ? globalState->box : nullptr, ir, + init_rot_group(fplog, cr, erg, x_pbc, mtop, mdrunOptions.verbose, er->out_slabs, + MASTER(cr) ? globalState->box : nullptr, ir, !er->restartWithAppending); /* Do not output the reference centers * again if we are appending */ } @@ -3711,22 +3733,22 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], } /* Only do I/O on the MASTER */ - er->out_angles = nullptr; - er->out_rot = nullptr; - er->out_torque = nullptr; + er->out_angles = nullptr; + er->out_rot = nullptr; + er->out_torque = nullptr; if (MASTER(cr)) { er->out_rot = open_rot_out(opt2fn("-ro", nfile, fnm), oenv, er); if (er->nstsout > 0) { - if (HaveFlexibleGroups(er->rot) || HavePotFitGroups(er->rot) ) + if (HaveFlexibleGroups(er->rot) || HavePotFitGroups(er->rot)) { - er->out_angles = open_angles_out(opt2fn("-ra", nfile, fnm), er); + er->out_angles = open_angles_out(opt2fn("-ra", nfile, fnm), er); } - if (HaveFlexibleGroups(er->rot) ) + if (HaveFlexibleGroups(er->rot)) { - er->out_torque = open_torque_out(opt2fn("-rt", nfile, fnm), er); + er->out_torque = open_torque_out(opt2fn("-rt", nfile, fnm), er); } } @@ -3741,9 +3763,9 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], * Note that we already subtracted u or y_c from the reference positions * in init_rot_group(). */ -static void rotate_local_reference(gmx_enfrotgrp *erg) +static void rotate_local_reference(gmx_enfrotgrp* erg) { - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (size_t i = 0; i < erg->atomSet->numAtomsLocal(); i++) { /* Index of this rotation group atom with respect to the whole rotation group */ @@ -3757,11 +3779,9 @@ static void rotate_local_reference(gmx_enfrotgrp *erg) /* Select the PBC representation for each local x position and store that * for later usage. We assume the right PBC image of an x is the one nearest to * its rotated reference */ -static void choose_pbc_image(rvec x[], - gmx_enfrotgrp *erg, - const matrix box, int npbcdim) +static void choose_pbc_image(rvec x[], gmx_enfrotgrp* erg, const matrix box, int npbcdim) { - const auto &localRotationGroupIndex = erg->atomSet->localIndex(); + const auto& localRotationGroupIndex = erg->atomSet->localIndex(); for (gmx::index i = 0; i < localRotationGroupIndex.ssize(); i++) { /* Index of a rotation group atom */ @@ -3781,26 +3801,20 @@ static void choose_pbc_image(rvec x[], } -void do_rotation(const t_commrec *cr, - gmx_enfrot *er, - const matrix box, - rvec x[], - real t, - int64_t step, - gmx_bool bNS) +void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[], real t, int64_t step, gmx_bool bNS) { - gmx_bool outstep_slab, outstep_rot; - gmx_bool bColl; - rvec transvec; - gmx_potfit *fit = nullptr; /* For fit type 'potential' determine the fit - angle via the potential minimum */ + gmx_bool outstep_slab, outstep_rot; + gmx_bool bColl; + rvec transvec; + gmx_potfit* fit = nullptr; /* For fit type 'potential' determine the fit + angle via the potential minimum */ #ifdef TAKETIME double t0; #endif /* When to output in main rotation output file */ - outstep_rot = do_per_step(step, er->nstrout) && er->bOut; + outstep_rot = do_per_step(step, er->nstrout) && er->bOut; /* When to output per-slab data */ outstep_slab = do_per_step(step, er->nstsout) && er->bOut; @@ -3812,10 +3826,10 @@ void do_rotation(const t_commrec *cr, /**************************************************************************/ /* First do ALL the communication! */ - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - const t_rotgrp *rotg = erg->rotg; + gmx_enfrotgrp* erg = &ergRef; + const t_rotgrp* rotg = erg->rotg; /* Do we use a collective (global) set of coordinates? */ bColl = ISCOLL(rotg); @@ -3829,8 +3843,10 @@ void do_rotation(const t_commrec *cr, /* Transfer the rotation group's positions such that every node has * all of them. Every node contributes its local positions x and stores * it in the collective erg->xc array. */ - communicate_group_positions(cr, erg->xc, erg->xc_shifts, erg->xc_eshifts, bNS, - x, rotg->nat, erg->atomSet->numAtomsLocal(), erg->atomSet->localIndex().data(), erg->atomSet->collectiveIndex().data(), erg->xc_old, box); + communicate_group_positions(cr, erg->xc, erg->xc_shifts, erg->xc_eshifts, bNS, x, + rotg->nat, erg->atomSet->numAtomsLocal(), + erg->atomSet->localIndex().data(), + erg->atomSet->collectiveIndex().data(), erg->xc_old, box); } else { @@ -3838,7 +3854,7 @@ void do_rotation(const t_commrec *cr, * this array changes in DD/neighborsearching steps */ if (bNS) { - const auto &collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); + const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex(); for (gmx::index i = 0; i < collectiveRotationGroupIndex.ssize(); i++) { /* Index of local atom w.r.t. the collective rotation group */ @@ -3855,9 +3871,10 @@ void do_rotation(const t_commrec *cr, choose_pbc_image(x, erg, box, 3); /* Get the center of the rotation group */ - if ( (rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF) ) + if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF)) { - get_center_comm(cr, erg->x_loc_pbc, erg->m_loc, erg->atomSet->numAtomsLocal(), rotg->nat, erg->xc_center); + get_center_comm(cr, erg->x_loc_pbc, erg->m_loc, erg->atomSet->numAtomsLocal(), + rotg->nat, erg->xc_center); } } @@ -3874,10 +3891,10 @@ void do_rotation(const t_commrec *cr, t0 = MPI_Wtime(); #endif - for (auto &ergRef : er->enfrotgrp) + for (auto& ergRef : er->enfrotgrp) { - gmx_enfrotgrp *erg = &ergRef; - const t_rotgrp *rotg = erg->rotg; + gmx_enfrotgrp* erg = &ergRef; + const t_rotgrp* rotg = erg->rotg; if (outstep_rot && MASTER(cr)) { @@ -3885,7 +3902,7 @@ void do_rotation(const t_commrec *cr, } /* Calculate angles and rotation matrices for potential fitting: */ - if ( (outstep_rot || outstep_slab) && (erotgFitPOT == rotg->eFittype) ) + if ((outstep_rot || outstep_slab) && (erotgFitPOT == rotg->eFittype)) { fit = erg->PotAngleFit; for (int i = 0; i < rotg->PotAngle_nstep; i++) @@ -3908,19 +3925,11 @@ void do_rotation(const t_commrec *cr, case erotgISO: case erotgISOPF: case erotgPM: - case erotgPMPF: - do_fixed(erg, outstep_rot, outstep_slab); - break; - case erotgRM: - do_radial_motion(erg, outstep_rot, outstep_slab); - break; - case erotgRMPF: - do_radial_motion_pf(erg, x, box, outstep_rot, outstep_slab); - break; + case erotgPMPF: do_fixed(erg, outstep_rot, outstep_slab); break; + case erotgRM: do_radial_motion(erg, outstep_rot, outstep_slab); break; + case erotgRMPF: do_radial_motion_pf(erg, x, box, outstep_rot, outstep_slab); break; case erotgRM2: - case erotgRM2PF: - do_radial_motion2(erg, x, box, outstep_rot, outstep_slab); - break; + case erotgRM2PF: do_radial_motion2(erg, x, box, outstep_rot, outstep_slab); break; case erotgFLEXT: case erotgFLEX2T: /* Subtract the center of the rotation group from the collective positions array @@ -3937,15 +3946,14 @@ void do_rotation(const t_commrec *cr, clear_rvec(erg->xc_center); do_flexible(MASTER(cr), er, erg, x, box, t, outstep_rot, outstep_slab); break; - default: - gmx_fatal(FARGS, "No such rotation potential."); + default: gmx_fatal(FARGS, "No such rotation potential."); } } #ifdef TAKETIME if (MASTER(cr)) { - fprintf(stderr, "%s calculation (step %d) took %g seconds.\n", RotStr, step, MPI_Wtime()-t0); + fprintf(stderr, "%s calculation (step %d) took %g seconds.\n", RotStr, step, MPI_Wtime() - t0); } #endif } diff --git a/src/gromacs/pulling/pull_rotation.h b/src/gromacs/pulling/pull_rotation.h index f231546b4e..a0626386cd 100644 --- a/src/gromacs/pulling/pull_rotation.h +++ b/src/gromacs/pulling/pull_rotation.h @@ -74,22 +74,23 @@ struct MdrunOptions; class EnforcedRotation { - public: - EnforcedRotation(); - ~EnforcedRotation(); - - /*! \brief Getter for working data - * - * This is needed while the module is still under - * construction. */ - gmx_enfrot *getLegacyEnfrot(); - private: - class Impl; - - PrivateImplPointer impl_; +public: + EnforcedRotation(); + ~EnforcedRotation(); + + /*! \brief Getter for working data + * + * This is needed while the module is still under + * construction. */ + gmx_enfrot* getLegacyEnfrot(); + +private: + class Impl; + + PrivateImplPointer impl_; }; -} // namespace gmx +} // namespace gmx /*! \brief Initializes the enforced rotation groups. * @@ -111,11 +112,17 @@ class EnforcedRotation * \param startingBehavior Describes whether this is a restart appending to output files * \return An enforced rotation module. */ -std::unique_ptr -init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], - const t_commrec *cr, gmx::LocalAtomSetManager * atomSets, const t_state *globalState, gmx_mtop_t *mtop, const gmx_output_env_t *oenv, - const gmx::MdrunOptions &mdrunOptions, - gmx::StartingBehavior startingBehavior); +std::unique_ptr init_rot(FILE* fplog, + t_inputrec* ir, + int nfile, + const t_filenm fnm[], + const t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + const t_state* globalState, + gmx_mtop_t* mtop, + const gmx_output_env_t* oenv, + const gmx::MdrunOptions& mdrunOptions, + gmx::StartingBehavior startingBehavior); /*! \brief Calculates the enforced rotation potential(s). * @@ -132,13 +139,7 @@ init_rot(FILE *fplog, t_inputrec *ir, int nfile, const t_filenm fnm[], * \param bNS After domain decomposition / neighbor searching several * local arrays have to be updated (masses, shifts) */ -void do_rotation(const t_commrec *cr, - gmx_enfrot *er, - const matrix box, - rvec x[], - real t, - int64_t step, - gmx_bool bNS); +void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[], real t, int64_t step, gmx_bool bNS); /*! \brief Add the enforced rotation forces to the official force array. @@ -158,8 +159,7 @@ void do_rotation(const t_commrec *cr, * \param t Time, used for output. * \returns The potential energy of the rotation potentials. */ -real add_rot_forces(gmx_enfrot *er, - rvec f[], const t_commrec *cr, int64_t step, real t); +real add_rot_forces(gmx_enfrot* er, rvec f[], const t_commrec* cr, int64_t step, real t); #endif diff --git a/src/gromacs/pulling/pullutil.cpp b/src/gromacs/pulling/pullutil.cpp index 95ed32a279..87589994f0 100644 --- a/src/gromacs/pulling/pullutil.cpp +++ b/src/gromacs/pulling/pullutil.cpp @@ -64,13 +64,13 @@ #if GMX_MPI // Helper function to deduce MPI datatype from the type of data -gmx_unused static MPI_Datatype mpiDatatype(const float gmx_unused *data) +gmx_unused static MPI_Datatype mpiDatatype(const float gmx_unused* data) { return MPI_FLOAT; } // Helper function to deduce MPI datatype from the type of data -gmx_unused static MPI_Datatype mpiDatatype(const double gmx_unused *data) +gmx_unused static MPI_Datatype mpiDatatype(const double gmx_unused* data) { return MPI_DOUBLE; } @@ -79,24 +79,21 @@ gmx_unused static MPI_Datatype mpiDatatype(const double gmx_unused *data) #if !GMX_DOUBLE // Helper function; note that gmx_sum(d) should actually be templated -gmx_unused static void gmxAllReduce(int n, real *data, const t_commrec *cr) +gmx_unused static void gmxAllReduce(int n, real* data, const t_commrec* cr) { gmx_sum(n, data, cr); } #endif // Helper function; note that gmx_sum(d) should actually be templated -gmx_unused static void gmxAllReduce(int n, double *data, const t_commrec *cr) +gmx_unused static void gmxAllReduce(int n, double* data, const t_commrec* cr) { gmx_sumd(n, data, cr); } // Reduce data of n elements over all ranks currently participating in pull -template -static void pullAllReduce(const t_commrec *cr, - pull_comm_t *comm, - int n, - T *data) +template +static void pullAllReduce(const t_commrec* cr, pull_comm_t* comm, int n, T* data) { if (cr != nullptr && PAR(cr)) { @@ -109,21 +106,19 @@ static void pullAllReduce(const t_commrec *cr, { /* Separate branch because gmx_sum uses cr->mpi_comm_mygroup */ #if GMX_MPI -#if MPI_IN_PLACE_EXISTS - MPI_Allreduce(MPI_IN_PLACE, data, n, mpiDatatype(data), MPI_SUM, - comm->mpi_comm_com); -#else +# if MPI_IN_PLACE_EXISTS + MPI_Allreduce(MPI_IN_PLACE, data, n, mpiDatatype(data), MPI_SUM, comm->mpi_comm_com); +# else std::vector buf(n); - MPI_Allreduce(data, buf.data(), n, mpiDatatype(data), MPI_SUM, - comm->mpi_comm_com); + MPI_Allreduce(data, buf.data(), n, mpiDatatype(data), MPI_SUM, comm->mpi_comm_com); /* Copy the result from the buffer to the input/output data */ for (int i = 0; i < n; i++) { data[i] = buf[i]; } -#endif +# endif #else gmx_incons("comm->bParticipateAll=FALSE without GMX_MPI"); #endif @@ -134,9 +129,7 @@ static void pullAllReduce(const t_commrec *cr, /* Copies the coordinates of the PBC atom of pgrp to x_pbc. * When those coordinates are not available on this rank, clears x_pbc. */ -static void setPbcAtomCoords(const pull_group_work_t &pgrp, - const rvec *x, - rvec x_pbc) +static void setPbcAtomCoords(const pull_group_work_t& pgrp, const rvec* x, rvec x_pbc) { if (pgrp.pbcAtomSet != nullptr) { @@ -157,14 +150,12 @@ static void setPbcAtomCoords(const pull_group_work_t &pgrp, } } -static void pull_set_pbcatoms(const t_commrec *cr, struct pull_t *pull, - const rvec *x, - gmx::ArrayRef x_pbc) +static void pull_set_pbcatoms(const t_commrec* cr, struct pull_t* pull, const rvec* x, gmx::ArrayRef x_pbc) { int numPbcAtoms = 0; for (size_t g = 0; g < pull->group.size(); g++) { - const pull_group_work_t &group = pull->group[g]; + const pull_group_work_t& group = pull->group[g]; if (group.needToCalcCom && (group.epgrppbc == epgrppbcREFAT || group.epgrppbc == epgrppbcPREVSTEPCOM)) { setPbcAtomCoords(pull->group[g], x, x_pbc[g]); @@ -182,32 +173,28 @@ static void pull_set_pbcatoms(const t_commrec *cr, struct pull_t *pull, * This can be very expensive at high parallelization, so we only * do this after each DD repartitioning. */ - pullAllReduce(cr, &pull->comm, pull->group.size()*DIM, - static_cast(x_pbc[0])); + pullAllReduce(cr, &pull->comm, pull->group.size() * DIM, static_cast(x_pbc[0])); } } -static void make_cyl_refgrps(const t_commrec *cr, - pull_t *pull, - const t_mdatoms *md, - t_pbc *pbc, - double t, - const rvec *x) +static void +make_cyl_refgrps(const t_commrec* cr, pull_t* pull, const t_mdatoms* md, t_pbc* pbc, double t, const rvec* x) { - pull_comm_t *comm = &pull->comm; + pull_comm_t* comm = &pull->comm; - GMX_ASSERT(comm->cylinderBuffer.size() == pull->coord.size()*c_cylinderBufferStride, "cylinderBuffer should have the correct size"); + GMX_ASSERT(comm->cylinderBuffer.size() == pull->coord.size() * c_cylinderBufferStride, + "cylinderBuffer should have the correct size"); - double inv_cyl_r2 = 1.0/gmx::square(pull->params.cylinder_r); + double inv_cyl_r2 = 1.0 / gmx::square(pull->params.cylinder_r); /* loop over all groups to make a reference group for each*/ for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; double sum_a, wmass, wwmass; dvec radf_fac0, radf_fac1; - pcrd = &pull->coord[c]; + pcrd = &pull->coord[c]; sum_a = 0; wmass = 0; @@ -218,9 +205,9 @@ static void make_cyl_refgrps(const t_commrec *cr, if (pcrd->params.eGeom == epullgCYL) { /* pref will be the same group for all pull coordinates */ - const pull_group_work_t &pref = pull->group[pcrd->params.group[0]]; - const pull_group_work_t &pgrp = pull->group[pcrd->params.group[1]]; - pull_group_work_t &pdyna = pull->dyna[c]; + const pull_group_work_t& pref = pull->group[pcrd->params.group[0]]; + const pull_group_work_t& pgrp = pull->group[pcrd->params.group[1]]; + pull_group_work_t& pdyna = pull->dyna[c]; rvec direction; copy_dvec_to_rvec(pcrd->spatialData.vec, direction); @@ -233,12 +220,12 @@ static void make_cyl_refgrps(const t_commrec *cr, if (pcrd->params.rate != 0) { /* With rate=0, value_ref is set initially */ - pcrd->value_ref = pcrd->params.init + pcrd->params.rate*t; + pcrd->value_ref = pcrd->params.init + pcrd->params.rate * t; } rvec reference; for (int m = 0; m < DIM; m++) { - reference[m] = pgrp.x[m] - pcrd->spatialData.vec[m]*pcrd->value_ref; + reference[m] = pgrp.x[m] - pcrd->spatialData.vec[m] * pcrd->value_ref; } auto localAtomIndices = pref.atomSet.localIndex(); @@ -253,8 +240,8 @@ static void make_cyl_refgrps(const t_commrec *cr, /* loop over all atoms in the main ref group */ for (gmx::index indexInSet = 0; indexInSet < localAtomIndices.ssize(); indexInSet++) { - int atomIndex = localAtomIndices[indexInSet]; - rvec dx; + int atomIndex = localAtomIndices[indexInSet]; + rvec dx; pbc_dx_aiuc(pbc, x[atomIndex], reference, dx); double axialLocation = iprod(direction, dx); dvec radialLocation; @@ -262,29 +249,29 @@ static void make_cyl_refgrps(const t_commrec *cr, for (int m = 0; m < DIM; m++) { /* Determine the radial components */ - radialLocation[m] = dx[m] - axialLocation*direction[m]; - dr2 += gmx::square(radialLocation[m]); + radialLocation[m] = dx[m] - axialLocation * direction[m]; + dr2 += gmx::square(radialLocation[m]); } - double dr2_rel = dr2*inv_cyl_r2; + double dr2_rel = dr2 * inv_cyl_r2; if (dr2_rel < 1) { /* add atom to sum of COM and to weight array */ - double mass = md->massT[atomIndex]; + double mass = md->massT[atomIndex]; /* The radial weight function is 1-2x^2+x^4, * where x=r/cylinder_r. Since this function depends * on the radial component, we also get radial forces * on both groups. */ - double weight = 1 + (-2 + dr2_rel)*dr2_rel; - double dweight_r = (-4 + 4*dr2_rel)*inv_cyl_r2; - pdyna.localWeights[indexInSet] = weight; - sum_a += mass*weight*axialLocation; - wmass += mass*weight; - wwmass += mass*weight*weight; + double weight = 1 + (-2 + dr2_rel) * dr2_rel; + double dweight_r = (-4 + 4 * dr2_rel) * inv_cyl_r2; + pdyna.localWeights[indexInSet] = weight; + sum_a += mass * weight * axialLocation; + wmass += mass * weight; + wwmass += mass * weight * weight; dvec mdw; - dsvmul(mass*dweight_r, radialLocation, mdw); + dsvmul(mass * dweight_r, radialLocation, mdw); copy_dvec(mdw, pdyna.mdw[indexInSet]); /* Currently we only have the axial component of the * offset from the cylinder COM up to an unkown offset. @@ -295,7 +282,7 @@ static void make_cyl_refgrps(const t_commrec *cr, for (int m = 0; m < DIM; m++) { radf_fac0[m] += mdw[m]; - radf_fac1[m] += mdw[m]*axialLocation; + radf_fac1[m] += mdw[m] * axialLocation; } } else @@ -305,7 +292,8 @@ static void make_cyl_refgrps(const t_commrec *cr, } } - auto buffer = gmx::arrayRefFromArray(comm->cylinderBuffer.data() + c*c_cylinderBufferStride, c_cylinderBufferStride); + auto buffer = gmx::arrayRefFromArray( + comm->cylinderBuffer.data() + c * c_cylinderBufferStride, c_cylinderBufferStride); buffer[0] = wmass; buffer[1] = wwmass; @@ -323,31 +311,31 @@ static void make_cyl_refgrps(const t_commrec *cr, if (cr != nullptr && PAR(cr)) { /* Sum the contributions over the ranks */ - pullAllReduce(cr, comm, pull->coord.size()*c_cylinderBufferStride, - comm->cylinderBuffer.data()); + pullAllReduce(cr, comm, pull->coord.size() * c_cylinderBufferStride, comm->cylinderBuffer.data()); } for (size_t c = 0; c < pull->coord.size(); c++) { - pull_coord_work_t *pcrd; + pull_coord_work_t* pcrd; - pcrd = &pull->coord[c]; + pcrd = &pull->coord[c]; if (pcrd->params.eGeom == epullgCYL) { - pull_group_work_t *pdyna = &pull->dyna[c]; - pull_group_work_t *pgrp = &pull->group[pcrd->params.group[1]]; - PullCoordSpatialData &spatialData = pcrd->spatialData; - - auto buffer = gmx::constArrayRefFromArray(comm->cylinderBuffer.data() + c*c_cylinderBufferStride, c_cylinderBufferStride); - double wmass = buffer[0]; - double wwmass = buffer[1]; - pdyna->mwscale = 1.0/wmass; + pull_group_work_t* pdyna = &pull->dyna[c]; + pull_group_work_t* pgrp = &pull->group[pcrd->params.group[1]]; + PullCoordSpatialData& spatialData = pcrd->spatialData; + + auto buffer = gmx::constArrayRefFromArray( + comm->cylinderBuffer.data() + c * c_cylinderBufferStride, c_cylinderBufferStride); + double wmass = buffer[0]; + double wwmass = buffer[1]; + pdyna->mwscale = 1.0 / wmass; /* Cylinder pulling can't be used with constraints, but we set * wscale and invtm anyhow, in case someone would like to use them. */ - pdyna->wscale = wmass/wwmass; - pdyna->invtm = wwmass/(wmass*wmass); + pdyna->wscale = wmass / wwmass; + pdyna->invtm = wwmass / (wmass * wmass); /* We store the deviation of the COM from the reference location * used above, since we need it when we apply the radial forces @@ -356,9 +344,9 @@ static void make_cyl_refgrps(const t_commrec *cr, spatialData.cyl_dev = 0; for (int m = 0; m < DIM; m++) { - double reference = pgrp->x[m] - spatialData.vec[m]*pcrd->value_ref; - double dist = -spatialData.vec[m]*buffer[2]*pdyna->mwscale; - pdyna->x[m] = reference - dist; + double reference = pgrp->x[m] - spatialData.vec[m] * pcrd->value_ref; + double dist = -spatialData.vec[m] * buffer[2] * pdyna->mwscale; + pdyna->x[m] = reference - dist; spatialData.cyl_dev += dist; } /* Now we know the exact COM of the cylinder reference group, @@ -368,17 +356,15 @@ static void make_cyl_refgrps(const t_commrec *cr, */ for (int m = 0; m < DIM; m++) { - spatialData.ffrad[m] = (buffer[6 + m] + - buffer[3 + m]*spatialData.cyl_dev)/wmass; + spatialData.ffrad[m] = (buffer[6 + m] + buffer[3 + m] * spatialData.cyl_dev) / wmass; } if (debug) { - fprintf(debug, "Pull cylinder group %zu:%8.3f%8.3f%8.3f m:%8.3f\n", - c, pdyna->x[0], pdyna->x[1], - pdyna->x[2], 1.0/pdyna->invtm); - fprintf(debug, "ffrad %8.3f %8.3f %8.3f\n", - spatialData.ffrad[XX], spatialData.ffrad[YY], spatialData.ffrad[ZZ]); + fprintf(debug, "Pull cylinder group %zu:%8.3f%8.3f%8.3f m:%8.3f\n", c, pdyna->x[0], + pdyna->x[1], pdyna->x[2], 1.0 / pdyna->invtm); + fprintf(debug, "ffrad %8.3f %8.3f %8.3f\n", spatialData.ffrad[XX], + spatialData.ffrad[YY], spatialData.ffrad[ZZ]); } } } @@ -391,55 +377,57 @@ static double atan2_0_2pi(double y, double x) a = atan2(y, x); if (a < 0) { - a += 2.0*M_PI; + a += 2.0 * M_PI; } return a; } -static void sum_com_part(const pull_group_work_t *pgrp, - int ind_start, int ind_end, - const rvec *x, const rvec *xp, - const real *mass, - const t_pbc *pbc, - const rvec x_pbc, - ComSums *sum_com) +static void sum_com_part(const pull_group_work_t* pgrp, + int ind_start, + int ind_end, + const rvec* x, + const rvec* xp, + const real* mass, + const t_pbc* pbc, + const rvec x_pbc, + ComSums* sum_com) { double sum_wm = 0; double sum_wwm = 0; dvec sum_wmx = { 0, 0, 0 }; dvec sum_wmxp = { 0, 0, 0 }; - auto localAtomIndices = pgrp->atomSet.localIndex(); + auto localAtomIndices = pgrp->atomSet.localIndex(); for (int i = ind_start; i < ind_end; i++) { int ii = localAtomIndices[i]; real wm; if (pgrp->localWeights.empty()) { - wm = mass[ii]; + wm = mass[ii]; sum_wm += wm; } else { real w; - w = pgrp->localWeights[i]; - wm = w*mass[ii]; - sum_wm += wm; - sum_wwm += wm*w; + w = pgrp->localWeights[i]; + wm = w * mass[ii]; + sum_wm += wm; + sum_wwm += wm * w; } if (pgrp->epgrppbc == epgrppbcNONE) { /* Plain COM: sum the coordinates */ for (int d = 0; d < DIM; d++) { - sum_wmx[d] += wm*x[ii][d]; + sum_wmx[d] += wm * x[ii][d]; } if (xp) { for (int d = 0; d < DIM; d++) { - sum_wmxp[d] += wm*xp[ii][d]; + sum_wmxp[d] += wm * xp[ii][d]; } } } @@ -451,7 +439,7 @@ static void sum_com_part(const pull_group_work_t *pgrp, pbc_dx(pbc, x[ii], x_pbc, dx); for (int d = 0; d < DIM; d++) { - sum_wmx[d] += wm*dx[d]; + sum_wmx[d] += wm * dx[d]; } if (xp) { @@ -461,7 +449,7 @@ static void sum_com_part(const pull_group_work_t *pgrp, */ for (int d = 0; d < DIM; d++) { - sum_wmxp[d] += wm*(dx[d] + xp[ii][d] - x[ii][d]); + sum_wmxp[d] += wm * (dx[d] + xp[ii][d] - x[ii][d]); } } } @@ -476,12 +464,15 @@ static void sum_com_part(const pull_group_work_t *pgrp, } } -static void sum_com_part_cosweight(const pull_group_work_t *pgrp, - int ind_start, int ind_end, - int cosdim, real twopi_box, - const rvec *x, const rvec *xp, - const real *mass, - ComSums *sum_com) +static void sum_com_part_cosweight(const pull_group_work_t* pgrp, + int ind_start, + int ind_end, + int cosdim, + real twopi_box, + const rvec* x, + const rvec* xp, + const real* mass, + ComSums* sum_com) { /* Cosine weighting geometry */ double sum_cm = 0; @@ -492,27 +483,27 @@ static void sum_com_part_cosweight(const pull_group_work_t *pgrp, double sum_cmp = 0; double sum_smp = 0; - auto localAtomIndices = pgrp->atomSet.localIndex(); + auto localAtomIndices = pgrp->atomSet.localIndex(); for (int i = ind_start; i < ind_end; i++) { - int ii = localAtomIndices[i]; - real m = mass[ii]; + int ii = localAtomIndices[i]; + real m = mass[ii]; /* Determine cos and sin sums */ - real cw = std::cos(x[ii][cosdim]*twopi_box); - real sw = std::sin(x[ii][cosdim]*twopi_box); - sum_cm += static_cast(cw*m); - sum_sm += static_cast(sw*m); - sum_ccm += static_cast(cw*cw*m); - sum_csm += static_cast(cw*sw*m); - sum_ssm += static_cast(sw*sw*m); + real cw = std::cos(x[ii][cosdim] * twopi_box); + real sw = std::sin(x[ii][cosdim] * twopi_box); + sum_cm += static_cast(cw * m); + sum_sm += static_cast(sw * m); + sum_ccm += static_cast(cw * cw * m); + sum_csm += static_cast(cw * sw * m); + sum_ssm += static_cast(sw * sw * m); if (xp != nullptr) { - real cw = std::cos(xp[ii][cosdim]*twopi_box); - real sw = std::sin(xp[ii][cosdim]*twopi_box); - sum_cmp += static_cast(cw*m); - sum_smp += static_cast(sw*m); + real cw = std::cos(xp[ii][cosdim] * twopi_box); + real sw = std::sin(xp[ii][cosdim] * twopi_box); + sum_cmp += static_cast(cw * m); + sum_smp += static_cast(sw * m); } } @@ -526,20 +517,22 @@ static void sum_com_part_cosweight(const pull_group_work_t *pgrp, } /* calculates center of mass of selection index from all coordinates x */ -void pull_calc_coms(const t_commrec *cr, - pull_t *pull, - const t_mdatoms *md, - t_pbc *pbc, - double t, - const rvec x[], rvec *xp) +void pull_calc_coms(const t_commrec* cr, + pull_t* pull, + const t_mdatoms* md, + t_pbc* pbc, + double t, + const rvec x[], + rvec* xp) { real twopi_box = 0; - pull_comm_t *comm; + pull_comm_t* comm; comm = &pull->comm; - GMX_ASSERT(comm->pbcAtomBuffer.size() == pull->group.size(), "pbcAtomBuffer should have size number of groups"); - GMX_ASSERT(comm->comBuffer.size() == pull->group.size()*c_comBufferStride, + GMX_ASSERT(comm->pbcAtomBuffer.size() == pull->group.size(), + "pbcAtomBuffer should have size number of groups"); + GMX_ASSERT(comm->comBuffer.size() == pull->group.size() * c_comBufferStride, "comBuffer should have size #group*c_comBufferStride"); if (pull->bRefAt && pull->bSetPBCatoms) @@ -565,19 +558,19 @@ void pull_calc_coms(const t_commrec *cr, assert(pull->npbcdim <= DIM); - for (m = pull->cosdim+1; m < pull->npbcdim; m++) + for (m = pull->cosdim + 1; m < pull->npbcdim; m++) { if (pbc->box[m][pull->cosdim] != 0) { gmx_fatal(FARGS, "Can not do cosine weighting for trilinic dimensions"); } } - twopi_box = 2.0*M_PI/pbc->box[pull->cosdim][pull->cosdim]; + twopi_box = 2.0 * M_PI / pbc->box[pull->cosdim][pull->cosdim]; } for (size_t g = 0; g < pull->group.size(); g++) { - pull_group_work_t *pgrp = &pull->group[g]; + pull_group_work_t* pgrp = &pull->group[g]; /* Cosine-weighted COMs behave different from all other weighted COMs * in the sense that the weights depend on instantaneous coordinates, @@ -588,8 +581,8 @@ void pull_calc_coms(const t_commrec *cr, pgrp->localWeights.resize(pgrp->atomSet.localIndex().size()); } - auto comBuffer = - gmx::arrayRefFromArray(comm->comBuffer.data() + g*c_comBufferStride, c_comBufferStride); + auto comBuffer = gmx::arrayRefFromArray(comm->comBuffer.data() + g * c_comBufferStride, + c_comBufferStride); if (pgrp->needToCalcCom) { @@ -610,18 +603,19 @@ void pull_calc_coms(const t_commrec *cr, } /* The final sums should end up in comSums[0] */ - ComSums &comSumsTotal = pull->comSums[0]; + ComSums& comSumsTotal = pull->comSums[0]; /* If we have a single-atom group the mass is irrelevant, so * we can remove the mass factor to avoid division by zero. * Note that with constraint pulling the mass does matter, but * in that case a check group mass != 0 has been done before. */ - if (pgrp->params.nat == 1 && - pgrp->atomSet.numAtomsLocal() == 1 && - md->massT[pgrp->atomSet.localIndex()[0]] == 0) + if (pgrp->params.nat == 1 && pgrp->atomSet.numAtomsLocal() == 1 + && md->massT[pgrp->atomSet.localIndex()[0]] == 0) { - GMX_ASSERT(xp == nullptr, "We should not have groups with zero mass with constraints, i.e. xp!=NULL"); + GMX_ASSERT(xp == nullptr, + "We should not have groups with zero mass with constraints, i.e. " + "xp!=NULL"); /* Copy the single atom coordinate */ for (int d = 0; d < DIM; d++) @@ -634,28 +628,24 @@ void pull_calc_coms(const t_commrec *cr, } else if (pgrp->atomSet.numAtomsLocal() <= c_pullMaxNumLocalAtomsSingleThreaded) { - sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), - x, xp, md->massT, - pbc, x_pbc, - &comSumsTotal); + sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, xp, md->massT, pbc, + x_pbc, &comSumsTotal); } else { #pragma omp parallel for num_threads(pull->nthreads) schedule(static) for (int t = 0; t < pull->nthreads; t++) { - int ind_start = (pgrp->atomSet.numAtomsLocal()*(t + 0))/pull->nthreads; - int ind_end = (pgrp->atomSet.numAtomsLocal()*(t + 1))/pull->nthreads; - sum_com_part(pgrp, ind_start, ind_end, - x, xp, md->massT, - pbc, x_pbc, + int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads; + int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads; + sum_com_part(pgrp, ind_start, ind_end, x, xp, md->massT, pbc, x_pbc, &pull->comSums[t]); } /* Reduce the thread contributions to sum_com[0] */ for (int t = 1; t < pull->nthreads; t++) { - comSumsTotal.sum_wm += pull->comSums[t].sum_wm; + comSumsTotal.sum_wm += pull->comSums[t].sum_wm; comSumsTotal.sum_wwm += pull->comSums[t].sum_wwm; dvec_inc(comSumsTotal.sum_wmx, pull->comSums[t].sum_wmx); dvec_inc(comSumsTotal.sum_wmxp, pull->comSums[t].sum_wmxp); @@ -668,7 +658,7 @@ void pull_calc_coms(const t_commrec *cr, } /* Copy local sums to a buffer for global summing */ - copy_dvec(comSumsTotal.sum_wmx, comBuffer[0]); + copy_dvec(comSumsTotal.sum_wmx, comBuffer[0]); copy_dvec(comSumsTotal.sum_wmxp, comBuffer[1]); @@ -685,20 +675,18 @@ void pull_calc_coms(const t_commrec *cr, #pragma omp parallel for num_threads(pull->nthreads) schedule(static) for (int t = 0; t < pull->nthreads; t++) { - int ind_start = (pgrp->atomSet.numAtomsLocal()*(t + 0))/pull->nthreads; - int ind_end = (pgrp->atomSet.numAtomsLocal()*(t + 1))/pull->nthreads; - sum_com_part_cosweight(pgrp, ind_start, ind_end, - pull->cosdim, twopi_box, - x, xp, md->massT, - &pull->comSums[t]); + int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads; + int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads; + sum_com_part_cosweight(pgrp, ind_start, ind_end, pull->cosdim, twopi_box, x, xp, + md->massT, &pull->comSums[t]); } /* Reduce the thread contributions to comSums[0] */ - ComSums &comSumsTotal = pull->comSums[0]; + ComSums& comSumsTotal = pull->comSums[0]; for (int t = 1; t < pull->nthreads; t++) { - comSumsTotal.sum_cm += pull->comSums[t].sum_cm; - comSumsTotal.sum_sm += pull->comSums[t].sum_sm; + comSumsTotal.sum_cm += pull->comSums[t].sum_cm; + comSumsTotal.sum_sm += pull->comSums[t].sum_sm; comSumsTotal.sum_ccm += pull->comSums[t].sum_ccm; comSumsTotal.sum_csm += pull->comSums[t].sum_csm; comSumsTotal.sum_ssm += pull->comSums[t].sum_ssm; @@ -726,19 +714,22 @@ void pull_calc_coms(const t_commrec *cr, } } - pullAllReduce(cr, comm, pull->group.size()*c_comBufferStride*DIM, - static_cast(comm->comBuffer[0])); + pullAllReduce(cr, comm, pull->group.size() * c_comBufferStride * DIM, + static_cast(comm->comBuffer[0])); for (size_t g = 0; g < pull->group.size(); g++) { - pull_group_work_t *pgrp; + pull_group_work_t* pgrp; pgrp = &pull->group[g]; if (pgrp->needToCalcCom) { - GMX_ASSERT(pgrp->params.nat > 0, "Normal pull groups should have atoms, only group 0, which should have bCalcCom=FALSE has nat=0"); + GMX_ASSERT(pgrp->params.nat > 0, + "Normal pull groups should have atoms, only group 0, which should have " + "bCalcCom=FALSE has nat=0"); - const auto comBuffer = gmx::constArrayRefFromArray(comm->comBuffer.data() + g*c_comBufferStride, c_comBufferStride); + const auto comBuffer = gmx::constArrayRefFromArray( + comm->comBuffer.data() + g * c_comBufferStride, c_comBufferStride); if (pgrp->epgrppbc != epgrppbcCOS) { @@ -746,26 +737,26 @@ void pull_calc_coms(const t_commrec *cr, int m; /* Determine the inverse mass */ - wmass = comBuffer[2][0]; - wwmass = comBuffer[2][1]; - pgrp->mwscale = 1.0/wmass; + wmass = comBuffer[2][0]; + wwmass = comBuffer[2][1]; + pgrp->mwscale = 1.0 / wmass; /* invtm==0 signals a frozen group, so then we should keep it zero */ if (pgrp->invtm != 0) { - pgrp->wscale = wmass/wwmass; - pgrp->invtm = wwmass/(wmass*wmass); + pgrp->wscale = wmass / wwmass; + pgrp->invtm = wwmass / (wmass * wmass); } /* Divide by the total mass */ for (m = 0; m < DIM; m++) { - pgrp->x[m] = comBuffer[0][m]*pgrp->mwscale; + pgrp->x[m] = comBuffer[0][m] * pgrp->mwscale; if (xp) { - pgrp->xp[m] = comBuffer[1][m]*pgrp->mwscale; + pgrp->xp[m] = comBuffer[1][m] * pgrp->mwscale; } if (pgrp->epgrppbc == epgrppbcREFAT || pgrp->epgrppbc == epgrppbcPREVSTEPCOM) { - pgrp->x[m] += comm->pbcAtomBuffer[g][m]; + pgrp->x[m] += comm->pbcAtomBuffer[g][m]; if (xp) { pgrp->xp[m] += comm->pbcAtomBuffer[g][m]; @@ -781,36 +772,35 @@ void pull_calc_coms(const t_commrec *cr, /* Determine the optimal location of the cosine weight */ csw = comBuffer[0][0]; snw = comBuffer[0][1]; - pgrp->x[pull->cosdim] = atan2_0_2pi(snw, csw)/twopi_box; + pgrp->x[pull->cosdim] = atan2_0_2pi(snw, csw) / twopi_box; /* Set the weights for the local atoms */ - wmass = sqrt(csw*csw + snw*snw); - wwmass = (comBuffer[1][0]*csw*csw + - comBuffer[1][1]*csw*snw + - comBuffer[1][2]*snw*snw)/(wmass*wmass); - - pgrp->mwscale = 1.0/wmass; - pgrp->wscale = wmass/wwmass; - pgrp->invtm = wwmass/(wmass*wmass); + wmass = sqrt(csw * csw + snw * snw); + wwmass = (comBuffer[1][0] * csw * csw + comBuffer[1][1] * csw * snw + + comBuffer[1][2] * snw * snw) + / (wmass * wmass); + + pgrp->mwscale = 1.0 / wmass; + pgrp->wscale = wmass / wwmass; + pgrp->invtm = wwmass / (wmass * wmass); /* Set the weights for the local atoms */ csw *= pgrp->invtm; snw *= pgrp->invtm; for (size_t i = 0; i < pgrp->atomSet.numAtomsLocal(); i++) { - int ii = pgrp->atomSet.localIndex()[i]; - pgrp->localWeights[i] = csw*std::cos(twopi_box*x[ii][pull->cosdim]) + - snw*std::sin(twopi_box*x[ii][pull->cosdim]); + int ii = pgrp->atomSet.localIndex()[i]; + pgrp->localWeights[i] = csw * std::cos(twopi_box * x[ii][pull->cosdim]) + + snw * std::sin(twopi_box * x[ii][pull->cosdim]); } if (xp) { csw = comBuffer[2][0]; snw = comBuffer[2][1]; - pgrp->xp[pull->cosdim] = atan2_0_2pi(snw, csw)/twopi_box; + pgrp->xp[pull->cosdim] = atan2_0_2pi(snw, csw) / twopi_box; } } if (debug) { - fprintf(debug, "Pull group %zu wmass %f invtm %f\n", - g, 1.0/pgrp->mwscale, pgrp->invtm); + fprintf(debug, "Pull group %zu wmass %f invtm %f\n", g, 1.0 / pgrp->mwscale, pgrp->invtm); } } } @@ -825,11 +815,11 @@ void pull_calc_coms(const t_commrec *cr, using BoolVec = gmx::BasicVector; /* Returns whether the pull group obeys the PBC restrictions */ -static bool pullGroupObeysPbcRestrictions(const pull_group_work_t &group, - const BoolVec &dimUsed, - const rvec *x, - const t_pbc &pbc, - const gmx::RVec &x_pbc, +static bool pullGroupObeysPbcRestrictions(const pull_group_work_t& group, + const BoolVec& dimUsed, + const rvec* x, + const t_pbc& pbc, + const gmx::RVec& x_pbc, const real pbcMargin) { /* Determine which dimensions are relevant for PBC */ @@ -853,14 +843,14 @@ static bool pullGroupObeysPbcRestrictions(const pull_group_work_t &group, } } - rvec marginPerDim = {}; + rvec marginPerDim = {}; real marginDistance2 = 0; if (pbcIsRectangular) { /* Use margins for dimensions independently */ for (int d = 0; d < pbc.ndim_ePBC; d++) { - marginPerDim[d] = pbcMargin*pbc.hbox_diag[d]; + marginPerDim[d] = pbcMargin * pbc.hbox_diag[d]; } } else @@ -870,7 +860,7 @@ static bool pullGroupObeysPbcRestrictions(const pull_group_work_t &group, { if (dimUsesPbc[d]) { - marginDistance2 += pbcMargin*gmx::square(0.5)*norm2(pbc.box[d]); + marginDistance2 += pbcMargin * gmx::square(0.5) * norm2(pbc.box[d]); } } } @@ -886,8 +876,7 @@ static bool pullGroupObeysPbcRestrictions(const pull_group_work_t &group, { for (int d = 0; d < pbc.ndim_ePBC; d++) { - if (dimUsesPbc[d] && (dx[d] < -marginPerDim[d] || - dx[d] > marginPerDim[d])) + if (dimUsesPbc[d] && (dx[d] < -marginPerDim[d] || dx[d] > marginPerDim[d])) { atomIsTooFar = true; } @@ -914,10 +903,7 @@ static bool pullGroupObeysPbcRestrictions(const pull_group_work_t &group, return true; } -int pullCheckPbcWithinGroups(const pull_t &pull, - const rvec *x, - const t_pbc &pbc, - real pbcMargin) +int pullCheckPbcWithinGroups(const pull_t& pull, const rvec* x, const t_pbc& pbc, real pbcMargin) { if (pbc.ePBC == epbcNONE) { @@ -928,13 +914,12 @@ int pullCheckPbcWithinGroups(const pull_t &pull, std::vector dimUsed(pull.group.size(), { false, false, false }); for (size_t c = 0; c < pull.coord.size(); c++) { - const t_pull_coord &coordParams = pull.coord[c].params; + const t_pull_coord& coordParams = pull.coord[c].params; for (int groupIndex = 0; groupIndex < coordParams.ngroup; groupIndex++) { for (int d = 0; d < DIM; d++) { - if (coordParams.dim[d] && - !(coordParams.eGeom == epullgCYL && groupIndex == 0)) + if (coordParams.dim[d] && !(coordParams.eGeom == epullgCYL && groupIndex == 0)) { dimUsed[coordParams.group[groupIndex]][d] = true; } @@ -945,9 +930,9 @@ int pullCheckPbcWithinGroups(const pull_t &pull, /* Check PBC for every group that uses a PBC reference atom treatment */ for (size_t g = 0; g < pull.group.size(); g++) { - const pull_group_work_t &group = pull.group[g]; - if ((group.epgrppbc == epgrppbcREFAT || group.epgrppbc == epgrppbcPREVSTEPCOM) && - !pullGroupObeysPbcRestrictions(group, dimUsed[g], x, pbc, pull.comm.pbcAtomBuffer[g], pbcMargin)) + const pull_group_work_t& group = pull.group[g]; + if ((group.epgrppbc == epgrppbcREFAT || group.epgrppbc == epgrppbcPREVSTEPCOM) + && !pullGroupObeysPbcRestrictions(group, dimUsed[g], x, pbc, pull.comm.pbcAtomBuffer[g], pbcMargin)) { return g; } @@ -956,9 +941,9 @@ int pullCheckPbcWithinGroups(const pull_t &pull, return -1; } -bool pullCheckPbcWithinGroup(const pull_t &pull, +bool pullCheckPbcWithinGroup(const pull_t& pull, gmx::ArrayRef x, - const t_pbc &pbc, + const t_pbc& pbc, int groupNr, real pbcMargin) { @@ -969,7 +954,7 @@ bool pullCheckPbcWithinGroup(const pull_t &pull, GMX_ASSERT(groupNr < gmx::ssize(pull.group), "groupNr is out of range"); /* Check PBC if the group uses a PBC reference atom treatment. */ - const pull_group_work_t &group = pull.group[groupNr]; + const pull_group_work_t& group = pull.group[groupNr]; if (group.epgrppbc != epgrppbcREFAT && group.epgrppbc != epgrppbcPREVSTEPCOM) { return true; @@ -979,15 +964,14 @@ bool pullCheckPbcWithinGroup(const pull_t &pull, BoolVec dimUsed = { false, false, false }; for (size_t c = 0; c < pull.coord.size(); c++) { - const t_pull_coord &coordParams = pull.coord[c].params; + const t_pull_coord& coordParams = pull.coord[c].params; for (int groupIndex = 0; groupIndex < coordParams.ngroup; groupIndex++) { if (coordParams.group[groupIndex] == groupNr) { for (int d = 0; d < DIM; d++) { - if (coordParams.dim[d] && - !(coordParams.eGeom == epullgCYL && groupIndex == 0)) + if (coordParams.dim[d] && !(coordParams.eGeom == epullgCYL && groupIndex == 0)) { dimUsed[d] = true; } @@ -996,21 +980,22 @@ bool pullCheckPbcWithinGroup(const pull_t &pull, } } - return (pullGroupObeysPbcRestrictions(group, dimUsed, as_rvec_array(x.data()), pbc, pull.comm.pbcAtomBuffer[groupNr], pbcMargin)); + return (pullGroupObeysPbcRestrictions(group, dimUsed, as_rvec_array(x.data()), pbc, + pull.comm.pbcAtomBuffer[groupNr], pbcMargin)); } -void setPrevStepPullComFromState(struct pull_t *pull, const t_state *state) +void setPrevStepPullComFromState(struct pull_t* pull, const t_state* state) { for (size_t g = 0; g < pull->group.size(); g++) { for (int j = 0; j < DIM; j++) { - pull->group[g].x_prev_step[j] = state->pull_com_prev_step[g*DIM+j]; + pull->group[g].x_prev_step[j] = state->pull_com_prev_step[g * DIM + j]; } } } -void updatePrevStepPullCom(struct pull_t *pull, t_state *state) +void updatePrevStepPullCom(struct pull_t* pull, t_state* state) { for (size_t g = 0; g < pull->group.size(); g++) { @@ -1018,14 +1003,14 @@ void updatePrevStepPullCom(struct pull_t *pull, t_state *state) { for (int j = 0; j < DIM; j++) { - pull->group[g].x_prev_step[j] = pull->group[g].x[j]; - state->pull_com_prev_step[g*DIM+j] = pull->group[g].x[j]; + pull->group[g].x_prev_step[j] = pull->group[g].x[j]; + state->pull_com_prev_step[g * DIM + j] = pull->group[g].x[j]; } } } } -void allocStatePrevStepPullCom(t_state *state, const pull_t *pull) +void allocStatePrevStepPullCom(t_state* state, const pull_t* pull) { if (!pull) { @@ -1033,19 +1018,15 @@ void allocStatePrevStepPullCom(t_state *state, const pull_t *pull) return; } size_t ngroup = pull->group.size(); - if (state->pull_com_prev_step.size()/DIM != ngroup) + if (state->pull_com_prev_step.size() / DIM != ngroup) { state->pull_com_prev_step.resize(ngroup * DIM, NAN); } } -void initPullComFromPrevStep(const t_commrec *cr, - pull_t *pull, - const t_mdatoms *md, - t_pbc *pbc, - const rvec x[]) +void initPullComFromPrevStep(const t_commrec* cr, pull_t* pull, const t_mdatoms* md, t_pbc* pbc, const rvec x[]) { - pull_comm_t *comm = &pull->comm; + pull_comm_t* comm = &pull->comm; size_t ngroup = pull->group.size(); if (!comm->bParticipate) @@ -1053,21 +1034,23 @@ void initPullComFromPrevStep(const t_commrec *cr, return; } - GMX_ASSERT(comm->pbcAtomBuffer.size() == pull->group.size(), "pbcAtomBuffer should have size number of groups"); - GMX_ASSERT(comm->comBuffer.size() == pull->group.size()*c_comBufferStride, + GMX_ASSERT(comm->pbcAtomBuffer.size() == pull->group.size(), + "pbcAtomBuffer should have size number of groups"); + GMX_ASSERT(comm->comBuffer.size() == pull->group.size() * c_comBufferStride, "comBuffer should have size #group*c_comBufferStride"); pull_set_pbcatoms(cr, pull, x, comm->pbcAtomBuffer); for (size_t g = 0; g < ngroup; g++) { - pull_group_work_t *pgrp; + pull_group_work_t* pgrp; pgrp = &pull->group[g]; if (pgrp->needToCalcCom && pgrp->epgrppbc == epgrppbcPREVSTEPCOM) { - GMX_ASSERT(pgrp->params.nat > 1, "Groups with no atoms, or only one atom, should not " + GMX_ASSERT(pgrp->params.nat > 1, + "Groups with no atoms, or only one atom, should not " "use the COM from the previous step as reference."); rvec x_pbc = { 0, 0, 0 }; @@ -1086,32 +1069,28 @@ void initPullComFromPrevStep(const t_commrec *cr, /* The following is to a large extent similar to pull_calc_coms() */ /* The final sums should end up in sum_com[0] */ - ComSums &comSumsTotal = pull->comSums[0]; + ComSums& comSumsTotal = pull->comSums[0]; if (pgrp->atomSet.numAtomsLocal() <= c_pullMaxNumLocalAtomsSingleThreaded) { - sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), - x, nullptr, md->massT, - pbc, x_pbc, - &comSumsTotal); + sum_com_part(pgrp, 0, pgrp->atomSet.numAtomsLocal(), x, nullptr, md->massT, pbc, + x_pbc, &comSumsTotal); } else { #pragma omp parallel for num_threads(pull->nthreads) schedule(static) for (int t = 0; t < pull->nthreads; t++) { - int ind_start = (pgrp->atomSet.numAtomsLocal()*(t + 0))/pull->nthreads; - int ind_end = (pgrp->atomSet.numAtomsLocal()*(t + 1))/pull->nthreads; - sum_com_part(pgrp, ind_start, ind_end, - x, nullptr, md->massT, - pbc, x_pbc, + int ind_start = (pgrp->atomSet.numAtomsLocal() * (t + 0)) / pull->nthreads; + int ind_end = (pgrp->atomSet.numAtomsLocal() * (t + 1)) / pull->nthreads; + sum_com_part(pgrp, ind_start, ind_end, x, nullptr, md->massT, pbc, x_pbc, &pull->comSums[t]); } /* Reduce the thread contributions to sum_com[0] */ for (int t = 1; t < pull->nthreads; t++) { - comSumsTotal.sum_wm += pull->comSums[t].sum_wm; + comSumsTotal.sum_wm += pull->comSums[t].sum_wm; comSumsTotal.sum_wwm += pull->comSums[t].sum_wwm; dvec_inc(comSumsTotal.sum_wmx, pull->comSums[t].sum_wmx); dvec_inc(comSumsTotal.sum_wmxp, pull->comSums[t].sum_wmxp); @@ -1124,8 +1103,8 @@ void initPullComFromPrevStep(const t_commrec *cr, } /* Copy local sums to a buffer for global summing */ - auto localSums = - gmx::arrayRefFromArray(comm->comBuffer.data() + g*c_comBufferStride, c_comBufferStride); + auto localSums = gmx::arrayRefFromArray(comm->comBuffer.data() + g * c_comBufferStride, + c_comBufferStride); localSums[0] = comSumsTotal.sum_wmx; localSums[1] = comSumsTotal.sum_wmxp; @@ -1135,41 +1114,41 @@ void initPullComFromPrevStep(const t_commrec *cr, } } - pullAllReduce(cr, comm, ngroup*c_comBufferStride*DIM, static_cast(comm->comBuffer[0])); + pullAllReduce(cr, comm, ngroup * c_comBufferStride * DIM, static_cast(comm->comBuffer[0])); for (size_t g = 0; g < ngroup; g++) { - pull_group_work_t *pgrp; + pull_group_work_t* pgrp; pgrp = &pull->group[g]; if (pgrp->needToCalcCom) { if (pgrp->epgrppbc == epgrppbcPREVSTEPCOM) { - auto localSums = - gmx::arrayRefFromArray(comm->comBuffer.data() + g*c_comBufferStride, c_comBufferStride); + auto localSums = gmx::arrayRefFromArray( + comm->comBuffer.data() + g * c_comBufferStride, c_comBufferStride); double wmass, wwmass; /* Determine the inverse mass */ - wmass = localSums[2][0]; - wwmass = localSums[2][1]; - pgrp->mwscale = 1.0/wmass; + wmass = localSums[2][0]; + wwmass = localSums[2][1]; + pgrp->mwscale = 1.0 / wmass; /* invtm==0 signals a frozen group, so then we should keep it zero */ if (pgrp->invtm != 0) { - pgrp->wscale = wmass/wwmass; - pgrp->invtm = wwmass/(wmass*wmass); + pgrp->wscale = wmass / wwmass; + pgrp->invtm = wwmass / (wmass * wmass); } /* Divide by the total mass */ for (int m = 0; m < DIM; m++) { - pgrp->x[m] = localSums[0][m]*pgrp->mwscale; + pgrp->x[m] = localSums[0][m] * pgrp->mwscale; pgrp->x[m] += comm->pbcAtomBuffer[g][m]; } if (debug) { - fprintf(debug, "Pull group %zu wmass %f invtm %f\n", - g, 1.0/pgrp->mwscale, pgrp->invtm); + fprintf(debug, "Pull group %zu wmass %f invtm %f\n", g, 1.0 / pgrp->mwscale, + pgrp->invtm); fprintf(debug, "Initialising prev step COM of pull group %zu to", g); for (int m = 0; m < DIM; m++) { diff --git a/src/gromacs/pulling/tests/pull.cpp b/src/gromacs/pulling/tests/pull.cpp index ebf966ea08..416f02deb1 100644 --- a/src/gromacs/pulling/tests/pull.cpp +++ b/src/gromacs/pulling/tests/pull.cpp @@ -67,135 +67,131 @@ using gmx::test::defaultRealTolerance; class PullTest : public ::testing::Test { - protected: - PullTest() {} +protected: + PullTest() {} - void test(int epbc, matrix box) - { - t_pbc pbc; + void test(int epbc, matrix box) + { + t_pbc pbc; - // PBC stuff - set_pbc(&pbc, epbc, box); + // PBC stuff + set_pbc(&pbc, epbc, box); - GMX_ASSERT(pbc.ndim_ePBC >= 1 && pbc.ndim_ePBC <= DIM, "Tests only support PBC along at least x and at most x, y, and z"); + GMX_ASSERT(pbc.ndim_ePBC >= 1 && pbc.ndim_ePBC <= DIM, + "Tests only support PBC along at least x and at most x, y, and z"); - real boxSizeZSquared; - if (pbc.ndim_ePBC > ZZ) - { - boxSizeZSquared = gmx::square(box[ZZ][ZZ]); - } - else - { - boxSizeZSquared = GMX_REAL_MAX; - } + real boxSizeZSquared; + if (pbc.ndim_ePBC > ZZ) + { + boxSizeZSquared = gmx::square(box[ZZ][ZZ]); + } + else + { + boxSizeZSquared = GMX_REAL_MAX; + } + { + // Distance pulling in all 3 dimensions + t_pull_coord params; + params.eGeom = epullgDIST; + params.dim[XX] = 1; + params.dim[YY] = 1; + params.dim[ZZ] = 1; + pull_coord_work_t pcrd(params); + clear_dvec(pcrd.spatialData.vec); + + real minBoxSize2 = GMX_REAL_MAX; + for (int d = 0; d < pbc.ndim_ePBC; d++) { - // Distance pulling in all 3 dimensions - t_pull_coord params; - params.eGeom = epullgDIST; - params.dim[XX] = 1; - params.dim[YY] = 1; - params.dim[ZZ] = 1; - pull_coord_work_t pcrd(params); - clear_dvec(pcrd.spatialData.vec); - - real minBoxSize2 = GMX_REAL_MAX; - for (int d = 0; d < pbc.ndim_ePBC; d++) - { - minBoxSize2 = std::min(minBoxSize2, norm2(box[d])); - } - EXPECT_REAL_EQ_TOL(0.25*minBoxSize2, - max_pull_distance2(&pcrd, &pbc), - defaultRealTolerance()); + minBoxSize2 = std::min(minBoxSize2, norm2(box[d])); } + EXPECT_REAL_EQ_TOL(0.25 * minBoxSize2, max_pull_distance2(&pcrd, &pbc), + defaultRealTolerance()); + } - { - // Distance pulling along Z - t_pull_coord params; - params.eGeom = epullgDIST; - params.dim[XX] = 0; - params.dim[YY] = 0; - params.dim[ZZ] = 1; - pull_coord_work_t pcrd(params); - clear_dvec(pcrd.spatialData.vec); - EXPECT_REAL_EQ_TOL(0.25*boxSizeZSquared, - max_pull_distance2(&pcrd, &pbc), - defaultRealTolerance()); - } + { + // Distance pulling along Z + t_pull_coord params; + params.eGeom = epullgDIST; + params.dim[XX] = 0; + params.dim[YY] = 0; + params.dim[ZZ] = 1; + pull_coord_work_t pcrd(params); + clear_dvec(pcrd.spatialData.vec); + EXPECT_REAL_EQ_TOL(0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc), + defaultRealTolerance()); + } - { - // Directional pulling along Z - t_pull_coord params; - params.eGeom = epullgDIR; - params.dim[XX] = 1; - params.dim[YY] = 1; - params.dim[ZZ] = 1; - pull_coord_work_t pcrd(params); - clear_dvec(pcrd.spatialData.vec); - pcrd.spatialData.vec[ZZ] = 1; - EXPECT_REAL_EQ_TOL(0.25*boxSizeZSquared, - max_pull_distance2(&pcrd, &pbc), - defaultRealTolerance()); - } + { + // Directional pulling along Z + t_pull_coord params; + params.eGeom = epullgDIR; + params.dim[XX] = 1; + params.dim[YY] = 1; + params.dim[ZZ] = 1; + pull_coord_work_t pcrd(params); + clear_dvec(pcrd.spatialData.vec); + pcrd.spatialData.vec[ZZ] = 1; + EXPECT_REAL_EQ_TOL(0.25 * boxSizeZSquared, max_pull_distance2(&pcrd, &pbc), + defaultRealTolerance()); + } + { + // Directional pulling along X + t_pull_coord params; + params.eGeom = epullgDIR; + params.dim[XX] = 1; + params.dim[YY] = 1; + params.dim[ZZ] = 1; + pull_coord_work_t pcrd(params); + clear_dvec(pcrd.spatialData.vec); + pcrd.spatialData.vec[XX] = 1; + + real minDist2 = square(box[XX][XX]); + for (int d = XX + 1; d < DIM; d++) { - // Directional pulling along X - t_pull_coord params; - params.eGeom = epullgDIR; - params.dim[XX] = 1; - params.dim[YY] = 1; - params.dim[ZZ] = 1; - pull_coord_work_t pcrd(params); - clear_dvec(pcrd.spatialData.vec); - pcrd.spatialData.vec[XX] = 1; - - real minDist2 = square(box[XX][XX]); - for (int d = XX + 1; d < DIM; d++) - { - minDist2 -= square(box[d][XX]); - } - EXPECT_REAL_EQ_TOL(0.25*minDist2, - max_pull_distance2(&pcrd, &pbc), - defaultRealTolerance()); + minDist2 -= square(box[d][XX]); } + EXPECT_REAL_EQ_TOL(0.25 * minDist2, max_pull_distance2(&pcrd, &pbc), defaultRealTolerance()); } + } }; -TEST_F (PullTest, MaxPullDistanceXyzScrewBox) +TEST_F(PullTest, MaxPullDistanceXyzScrewBox) { matrix box = { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 0, 10 } }; test(epbcSCREW, box); } -TEST_F (PullTest, MaxPullDistanceXyzCubicBox) +TEST_F(PullTest, MaxPullDistanceXyzCubicBox) { matrix box = { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 0, 10 } }; test(epbcXYZ, box); } -TEST_F (PullTest, MaxPullDistanceXyzTricBox) +TEST_F(PullTest, MaxPullDistanceXyzTricBox) { matrix box = { { 10, 0, 0 }, { 3, 10, 0 }, { 3, 4, 10 } }; test(epbcXYZ, box); } -TEST_F (PullTest, MaxPullDistanceXyzLongBox) +TEST_F(PullTest, MaxPullDistanceXyzLongBox) { matrix box = { { 10, 0, 0 }, { 0, 10, 0 }, { 0, 0, 30 } }; test(epbcXYZ, box); } -TEST_F (PullTest, MaxPullDistanceXySkewedBox) +TEST_F(PullTest, MaxPullDistanceXySkewedBox) { matrix box = { { 10, 0, 0 }, { 5, 8, 0 }, { 0, 0, 0 } }; test(epbcXY, box); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/exponentialdistribution.h b/src/gromacs/random/exponentialdistribution.h index 7c7513b80f..7df6fa1d34 100644 --- a/src/gromacs/random/exponentialdistribution.h +++ b/src/gromacs/random/exponentialdistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -98,132 +98,117 @@ namespace gmx template class ExponentialDistribution { - public: - /*! \brief Type of values returned */ - typedef RealType result_type; - - /*! \brief Exponential distribution parameters */ - class param_type - { - /*! \brief The lambda/decay parameter */ - result_type lambda_; - - public: - /*! \brief Reference back to the distribution class */ - typedef ExponentialDistribution distribution_type; - - /*! \brief Construct parameter block - * - * \param lambda lambda/decay parameter - */ - explicit param_type(result_type lambda = 1.0) - : lambda_(lambda) {} - - /*! \brief Return lambda parameter */ - result_type lambda() const { return lambda_; } - - /*! \brief True if two parameter sets will return the same exponential distribution. - * - * \param x Instance to compare with. - */ - bool - operator==(const param_type &x) const - { - return lambda_ == x.lambda_; - } - - /*! \brief True if two parameter sets will return different exponential distributions - * - * \param x Instance to compare with. - */ - bool - operator!=(const param_type &x) const { return !operator==(x); } - }; +public: + /*! \brief Type of values returned */ + typedef RealType result_type; + + /*! \brief Exponential distribution parameters */ + class param_type + { + /*! \brief The lambda/decay parameter */ + result_type lambda_; public: + /*! \brief Reference back to the distribution class */ + typedef ExponentialDistribution distribution_type; - /*! \brief Construct new distribution with given floating-point parameter. + /*! \brief Construct parameter block * * \param lambda lambda/decay parameter - - */ - explicit ExponentialDistribution(result_type lambda = 1.0) - : param_(param_type(lambda)) {} - - /*! \brief Construct new distribution from parameter class - * - * \param param Parameter class as defined inside gmx::ExponentialDistribution. */ - explicit ExponentialDistribution(const param_type ¶m) : param_(param) {} + explicit param_type(result_type lambda = 1.0) : lambda_(lambda) {} - /*! \brief Flush all internal saved values */ - void - reset() {} + /*! \brief Return lambda parameter */ + result_type lambda() const { return lambda_; } - /*! \brief Return values from exponential distribution with internal parameters + /*! \brief True if two parameter sets will return the same exponential distribution. * - * \tparam Rng Random engine class - * - * \param g Random engine + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g) { return (*this)(g, param_); } + bool operator==(const param_type& x) const { return lambda_ == x.lambda_; } - /*! \brief Return value from exponential distribution with given parameters - * - * \tparam Rng Random engine class + /*! \brief True if two parameter sets will return different exponential distributions * - * \param g Random engine - * \param param Parameters to use + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g, const param_type ¶m) - { - return -std::log(result_type(1) - - generateCanonical::digits>(g)) / param.lambda(); - } - - /*! \brief Return the lambda parameter of the exponential distribution */ - result_type - lambda() const { return param_.lambda(); } - - /*! \brief Return the full parameter class of exponential distribution */ - param_type param() const { return param_; } - - /*! \brief Smallest value that can be returned from exponential distribution */ - result_type - min() const { return 0; } - - /*! \brief Largest value that can be returned from exponential distribution */ - result_type - max() const { return std::numeric_limits::infinity(); } - - /*! \brief True if two exponential distributions will produce the same values. - * - * \param x Instance to compare with. - */ - bool - operator==(const ExponentialDistribution &x) const - { return param_ == x.param_; } - - /*! \brief True if two exponential distributions will produce different values. - * - * \param x Instance to compare with. - */ - bool - operator!=(const ExponentialDistribution &x) const - { return !operator==(x); } - - private: - /*! \brief Internal value for parameters, can be overridden at generation time. */ - param_type param_; - - GMX_DISALLOW_COPY_AND_ASSIGN(ExponentialDistribution); + bool operator!=(const param_type& x) const { return !operator==(x); } + }; + +public: + /*! \brief Construct new distribution with given floating-point parameter. + * + * \param lambda lambda/decay parameter + + */ + explicit ExponentialDistribution(result_type lambda = 1.0) : param_(param_type(lambda)) {} + + /*! \brief Construct new distribution from parameter class + * + * \param param Parameter class as defined inside gmx::ExponentialDistribution. + */ + explicit ExponentialDistribution(const param_type& param) : param_(param) {} + + /*! \brief Flush all internal saved values */ + void reset() {} + + /*! \brief Return values from exponential distribution with internal parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return value from exponential distribution with given parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + * \param param Parameters to use + */ + template + result_type operator()(Rng& g, const param_type& param) + { + return -std::log(result_type(1) + - generateCanonical::digits>(g)) + / param.lambda(); + } + + /*! \brief Return the lambda parameter of the exponential distribution */ + result_type lambda() const { return param_.lambda(); } + + /*! \brief Return the full parameter class of exponential distribution */ + param_type param() const { return param_; } + + /*! \brief Smallest value that can be returned from exponential distribution */ + result_type min() const { return 0; } + + /*! \brief Largest value that can be returned from exponential distribution */ + result_type max() const { return std::numeric_limits::infinity(); } + + /*! \brief True if two exponential distributions will produce the same values. + * + * \param x Instance to compare with. + */ + bool operator==(const ExponentialDistribution& x) const { return param_ == x.param_; } + + /*! \brief True if two exponential distributions will produce different values. + * + * \param x Instance to compare with. + */ + bool operator!=(const ExponentialDistribution& x) const { return !operator==(x); } + +private: + /*! \brief Internal value for parameters, can be overridden at generation time. */ + param_type param_; + + GMX_DISALLOW_COPY_AND_ASSIGN(ExponentialDistribution); }; -} // namespace gmx +} // namespace gmx #endif // GMX_MATH_RANDOM_H diff --git a/src/gromacs/random/gammadistribution.h b/src/gromacs/random/gammadistribution.h index ac850cfeb8..24e7fd3b09 100644 --- a/src/gromacs/random/gammadistribution.h +++ b/src/gromacs/random/gammadistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -110,218 +110,211 @@ namespace gmx * The gamma distribution is defined as * * \f[ - * p(x|\alpha,\beta) = \frac{1}{\Gamma(\alpha)\beta^{alpha}} x^{\alpha - 1} e^{-\frac{x}{\beta}}, x\geq 0 - * \f] + * p(x|\alpha,\beta) = \frac{1}{\Gamma(\alpha)\beta^{alpha}} x^{\alpha - 1} + * e^{-\frac{x}{\beta}}, x\geq 0 \f] * * \tparam RealType Floating-point type, real by default in GROMACS. */ template class GammaDistribution { - public: - /*! \brief Type of values returned */ - typedef RealType result_type; - - /*! \brief Gamma distribution parameters */ - class param_type - { - /*! \brief First parameter of gamma distribution */ - result_type alpha_; - /*! \brief Second parameter of gamma distribution */ - result_type beta_; - - public: - /*! \brief Reference back to the distribution class */ - typedef GammaDistribution distribution_type; - - /*! \brief Construct parameter block - * - * \param alpha First parameter of gamma distribution - * \param beta Second parameter of gamma distribution - */ - explicit param_type(result_type alpha = 1.0, result_type beta = 1.0) - : alpha_(alpha), beta_(beta) {} - - /*! \brief Return first parameter */ - result_type alpha() const { return alpha_; } - /*! \brief Return second parameter */ - result_type beta() const { return beta_; } - - /*! \brief True if two parameter sets will return the same distribution. - * - * \param x Instance to compare with. - */ - bool - operator==(const param_type &x) const - { - return alpha_ == x.alpha_ && beta_ == x.beta_; - } - - /*! \brief True if two parameter sets will return different distributions - * - * \param x Instance to compare with. - */ - bool - operator!=(const param_type &x) const { return !operator==(x); } - }; +public: + /*! \brief Type of values returned */ + typedef RealType result_type; + + /*! \brief Gamma distribution parameters */ + class param_type + { + /*! \brief First parameter of gamma distribution */ + result_type alpha_; + /*! \brief Second parameter of gamma distribution */ + result_type beta_; public: + /*! \brief Reference back to the distribution class */ + typedef GammaDistribution distribution_type; - /*! \brief Construct new distribution with given floating-point parameters. + /*! \brief Construct parameter block * * \param alpha First parameter of gamma distribution * \param beta Second parameter of gamma distribution */ - explicit GammaDistribution(result_type alpha = 1.0, result_type beta = 1.0) - : param_(param_type(alpha, beta)) {} - - /*! \brief Construct new distribution from parameter class - * - * \param param Parameter class as defined inside gmx::GammaDistribution. - */ - explicit GammaDistribution(const param_type ¶m) : param_(param) {} + explicit param_type(result_type alpha = 1.0, result_type beta = 1.0) : + alpha_(alpha), + beta_(beta) + { + } - /*! \brief Flush all internal saved values */ - void - reset() {} + /*! \brief Return first parameter */ + result_type alpha() const { return alpha_; } + /*! \brief Return second parameter */ + result_type beta() const { return beta_; } - /*! \brief Return values from gamma distribution with internal parameters + /*! \brief True if two parameter sets will return the same distribution. * - * \tparam Rng Random engine class - * - * \param g Random engine + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g) { return (*this)(g, param_); } + bool operator==(const param_type& x) const + { + return alpha_ == x.alpha_ && beta_ == x.beta_; + } - /*! \brief Return value from gamma distribution with given parameters + /*! \brief True if two parameter sets will return different distributions * - * \tparam Rng Random engine class - * - * \param g Random engine - * \param param Parameters to use + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g, const param_type ¶m) + bool operator!=(const param_type& x) const { return !operator==(x); } + }; + +public: + /*! \brief Construct new distribution with given floating-point parameters. + * + * \param alpha First parameter of gamma distribution + * \param beta Second parameter of gamma distribution + */ + explicit GammaDistribution(result_type alpha = 1.0, result_type beta = 1.0) : + param_(param_type(alpha, beta)) + { + } + + /*! \brief Construct new distribution from parameter class + * + * \param param Parameter class as defined inside gmx::GammaDistribution. + */ + explicit GammaDistribution(const param_type& param) : param_(param) {} + + /*! \brief Flush all internal saved values */ + void reset() {} + + /*! \brief Return values from gamma distribution with internal parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return value from gamma distribution with given parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + * \param param Parameters to use + */ + template + result_type operator()(Rng& g, const param_type& param) + { + result_type alpha = param.alpha(); + UniformRealDistribution uniformDist(0, 1); + ExponentialDistribution expDist; + + result_type x; + + if (alpha == 1.0) { - result_type alpha = param.alpha(); - UniformRealDistribution uniformDist(0, 1); - ExponentialDistribution expDist; - - result_type x; + x = expDist(g); + } + else if (alpha > 1.0) + { + const result_type b = alpha - 1.0; + const result_type c = 3.0 * alpha - result_type(0.75); - if (alpha == 1.0) + while (true) { - x = expDist(g); - } - else if (alpha > 1.0) - { - const result_type b = alpha - 1.0; - const result_type c = 3.0 * alpha - result_type(0.75); + const result_type u = uniformDist(g); + const result_type v = uniformDist(g); + const result_type w = u * (1 - u); - while (true) + if (w != 0) { - const result_type u = uniformDist(g); - const result_type v = uniformDist(g); - const result_type w = u * (1 - u); + const result_type y = std::sqrt(c / w) * (u - result_type(0.5)); + x = b + y; - if (w != 0) + if (x >= 0) { - const result_type y = std::sqrt(c / w) * - (u - result_type(0.5)); - x = b + y; + const result_type z = 64 * w * w * w * v * v; - if (x >= 0) + if (z <= 1.0 - 2.0 * y * y / x) + { + break; + } + if (std::log(z) <= 2.0 * (b * std::log(x / b) - y)) { - const result_type z = 64 * w * w * w * v * v; - - if (z <= 1.0 - 2.0 * y * y / x) - { - break; - } - if (std::log(z) <= 2.0 * (b * std::log(x / b) - y)) - { - break; - } + break; } } } } - else // __a < 1 + } + else // __a < 1 + { + while (true) { - while (true) + const result_type u = uniformDist(g); + const result_type es = expDist(g); + + if (u <= 1.0 - alpha) { - const result_type u = uniformDist(g); - const result_type es = expDist(g); + x = std::pow(u, 1.0 / alpha); - if (u <= 1.0 - alpha) + if (x <= es) { - x = std::pow(u, 1.0 / alpha); - - if (x <= es) - { - break; - } + break; } - else - { - const result_type e = -std::log((1.0 - u)/alpha); - x = std::pow(1.0 - alpha + alpha * e, 1.0 / alpha); + } + else + { + const result_type e = -std::log((1.0 - u) / alpha); + x = std::pow(1.0 - alpha + alpha * e, 1.0 / alpha); - if (x <= e + es) - { - break; - } + if (x <= e + es) + { + break; } } } - return x * param.beta(); } + return x * param.beta(); + } - /*! \brief Return the first parameter of gamma distribution */ - result_type - alpha() const { return param_.alpha(); } + /*! \brief Return the first parameter of gamma distribution */ + result_type alpha() const { return param_.alpha(); } - /*! \brief Return the second parameter of gamma distribution */ - result_type - beta() const { return param_.beta(); } + /*! \brief Return the second parameter of gamma distribution */ + result_type beta() const { return param_.beta(); } - /*! \brief Return the full parameter class of gamma distribution */ - param_type param() const { return param_; } + /*! \brief Return the full parameter class of gamma distribution */ + param_type param() const { return param_; } - /*! \brief Smallest value that can be returned from gamma distribution */ - result_type - min() const { return 0; } + /*! \brief Smallest value that can be returned from gamma distribution */ + result_type min() const { return 0; } - /*! \brief Largest value that can be returned from gamma distribution */ - result_type - max() const { return std::numeric_limits::infinity(); } + /*! \brief Largest value that can be returned from gamma distribution */ + result_type max() const { return std::numeric_limits::infinity(); } - /*! \brief True if two gamma distributions will produce the same values. - * - * \param x Instance to compare with. - */ - bool - operator==(const GammaDistribution &x) const - { return param_ == x.param_; } + /*! \brief True if two gamma distributions will produce the same values. + * + * \param x Instance to compare with. + */ + bool operator==(const GammaDistribution& x) const { return param_ == x.param_; } - /*! \brief True if two gamma distributions will produce different values. - * - * \param x Instance to compare with. - */ - bool - operator!=(const GammaDistribution &x) const - { return !operator==(x); } + /*! \brief True if two gamma distributions will produce different values. + * + * \param x Instance to compare with. + */ + bool operator!=(const GammaDistribution& x) const { return !operator==(x); } - private: - /*! \brief Internal value for parameters, can be overridden at generation time. */ - param_type param_; +private: + /*! \brief Internal value for parameters, can be overridden at generation time. */ + param_type param_; - GMX_DISALLOW_COPY_AND_ASSIGN(GammaDistribution); + GMX_DISALLOW_COPY_AND_ASSIGN(GammaDistribution); }; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_GAMMADISTRIBUTION_H diff --git a/src/gromacs/random/normaldistribution.h b/src/gromacs/random/normaldistribution.h index 0ccaa3799e..5242e97d1c 100644 --- a/src/gromacs/random/normaldistribution.h +++ b/src/gromacs/random/normaldistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -103,177 +103,172 @@ namespace gmx template class NormalDistribution { - public: - /*! \brief Type of values returned */ - typedef RealType result_type; - - /*! \brief Normal distribution parameters */ - class param_type - { - /*! \brief Mean of normal distribution */ - result_type mean_; - /*! \brief Standard deviation of distribution */ - result_type stddev_; - - public: - /*! \brief Reference back to the distribution class */ - typedef NormalDistribution distribution_type; - - /*! \brief Construct parameter block - * - * \param mean Mean of normal distribution - * \param stddev Standard deviation of normal distribution - */ - explicit param_type(result_type mean = 0.0, result_type stddev = 1.0) - : mean_(mean), stddev_(stddev) {} - - /*! \brief Return first parameter */ - result_type mean() const { return mean_; } - /*! \brief Return second parameter */ - result_type stddev() const { return stddev_; } - - /*! \brief True if two parameter sets will return the same normal distribution. - * - * \param x Instance to compare with. - */ - bool - operator==(const param_type &x) const - { - return mean_ == x.mean_ && stddev_ == x.stddev_; - } - - /*! \brief True if two parameter sets will return different normal distributions - * - * \param x Instance to compare with. - */ - bool - operator!=(const param_type &x) const { return !operator==(x); } - }; +public: + /*! \brief Type of values returned */ + typedef RealType result_type; + + /*! \brief Normal distribution parameters */ + class param_type + { + /*! \brief Mean of normal distribution */ + result_type mean_; + /*! \brief Standard deviation of distribution */ + result_type stddev_; public: + /*! \brief Reference back to the distribution class */ + typedef NormalDistribution distribution_type; - /*! \brief Construct new distribution with given floating-point parameters. + /*! \brief Construct parameter block * * \param mean Mean of normal distribution * \param stddev Standard deviation of normal distribution */ - explicit NormalDistribution(result_type mean = 0.0, result_type stddev = 1.0) - : param_(param_type(mean, stddev)), hot_(false), saved_(0) {} - - /*! \brief Construct new distribution from parameter class - * - * \param param Parameter class as defined inside gmx::NormalDistribution. - */ - explicit NormalDistribution(const param_type ¶m) - : param_(param), hot_(false), saved_(0) {} + explicit param_type(result_type mean = 0.0, result_type stddev = 1.0) : + mean_(mean), + stddev_(stddev) + { + } - /*! \brief Flush all internal saved values */ - void - reset() { hot_ = false; } + /*! \brief Return first parameter */ + result_type mean() const { return mean_; } + /*! \brief Return second parameter */ + result_type stddev() const { return stddev_; } - /*! \brief Return values from normal distribution with internal parameters - * - * \tparam Rng Random engine class + /*! \brief True if two parameter sets will return the same normal distribution. * - * \param g Random engine + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g) { return (*this)(g, param_); } + bool operator==(const param_type& x) const + { + return mean_ == x.mean_ && stddev_ == x.stddev_; + } - /*! \brief Return value from normal distribution with given parameters + /*! \brief True if two parameter sets will return different normal distributions * - * \tparam Rng Random engine class - * - * \param g Random engine - * \param param Parameters to use + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g, const param_type ¶m) + bool operator!=(const param_type& x) const { return !operator==(x); } + }; + +public: + /*! \brief Construct new distribution with given floating-point parameters. + * + * \param mean Mean of normal distribution + * \param stddev Standard deviation of normal distribution + */ + explicit NormalDistribution(result_type mean = 0.0, result_type stddev = 1.0) : + param_(param_type(mean, stddev)), + hot_(false), + saved_(0) + { + } + + /*! \brief Construct new distribution from parameter class + * + * \param param Parameter class as defined inside gmx::NormalDistribution. + */ + explicit NormalDistribution(const param_type& param) : param_(param), hot_(false), saved_(0) {} + + /*! \brief Flush all internal saved values */ + void reset() { hot_ = false; } + + /*! \brief Return values from normal distribution with internal parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return value from normal distribution with given parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + * \param param Parameters to use + */ + template + result_type operator()(Rng& g, const param_type& param) + { + result_type result; + + if (hot_) + { + hot_ = false; + result = saved_; + } + else { - result_type result; + UniformRealDistribution uniformDist(-1.0, 1.0); + result_type u; + result_type v; + result_type s; - if (hot_) + do { - hot_ = false; - result = saved_; - } - else - { - UniformRealDistribution uniformDist(-1.0, 1.0); - result_type u; - result_type v; - result_type s; - - do - { - u = uniformDist(g); - v = uniformDist(g); - s = u * u + v * v; - } - while (s > 1.0 || s == 0.0); - - s = std::sqrt(-2.0 * std::log(s) / s); - saved_ = v * s; - hot_ = true; - result = u * s; - } - return result * param.stddev() + param.mean(); + u = uniformDist(g); + v = uniformDist(g); + s = u * u + v * v; + } while (s > 1.0 || s == 0.0); + + s = std::sqrt(-2.0 * std::log(s) / s); + saved_ = v * s; + hot_ = true; + result = u * s; } + return result * param.stddev() + param.mean(); + } - /*! \brief Return the mean of the normal distribution */ - result_type - mean() const { return param_.mean(); } - - /*! \brief Return the standard deviation of the normal distribution */ - result_type - stddev() const { return param_.stddev(); } + /*! \brief Return the mean of the normal distribution */ + result_type mean() const { return param_.mean(); } - /*! \brief Return the full parameter class of the normal distribution */ - param_type param() const { return param_; } + /*! \brief Return the standard deviation of the normal distribution */ + result_type stddev() const { return param_.stddev(); } - /*! \brief Smallest value that can be returned from normal distribution */ - result_type - min() const { return -std::numeric_limits::infinity(); } + /*! \brief Return the full parameter class of the normal distribution */ + param_type param() const { return param_; } - /*! \brief Largest value that can be returned from normal distribution */ - result_type - max() const { return std::numeric_limits::infinity(); } + /*! \brief Smallest value that can be returned from normal distribution */ + result_type min() const { return -std::numeric_limits::infinity(); } - /*! \brief True if two normal distributions will produce the same values. - * - * \param x Instance to compare with. - */ - bool - operator==(const NormalDistribution &x) const - { - /* Equal if: Params are identical, and saved-state is identical, - * and if we have something saved, it must be identical. - */ - return param_ == x.param_ && hot_ == x.hot_ && (!hot_ || saved_ == x.saved_); - } + /*! \brief Largest value that can be returned from normal distribution */ + result_type max() const { return std::numeric_limits::infinity(); } - /*! \brief True if two normal distributions will produce different values. - * - * \param x Instance to compare with. + /*! \brief True if two normal distributions will produce the same values. + * + * \param x Instance to compare with. + */ + bool operator==(const NormalDistribution& x) const + { + /* Equal if: Params are identical, and saved-state is identical, + * and if we have something saved, it must be identical. */ - bool - operator!=(const NormalDistribution &x) const - { return !operator==(x); } - - private: - /*! \brief Internal value for parameters, can be overridden at generation time. */ - param_type param_; - /*! \brief True if there is a saved result to return */ - bool hot_; - /*! \brief The saved result to return - only valid if hot_ is true */ - result_type saved_; - - GMX_DISALLOW_COPY_AND_ASSIGN(NormalDistribution); + return param_ == x.param_ && hot_ == x.hot_ && (!hot_ || saved_ == x.saved_); + } + + /*! \brief True if two normal distributions will produce different values. + * + * \param x Instance to compare with. + */ + bool operator!=(const NormalDistribution& x) const { return !operator==(x); } + +private: + /*! \brief Internal value for parameters, can be overridden at generation time. */ + param_type param_; + /*! \brief True if there is a saved result to return */ + bool hot_; + /*! \brief The saved result to return - only valid if hot_ is true */ + result_type saved_; + + GMX_DISALLOW_COPY_AND_ASSIGN(NormalDistribution); }; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_NORMALDISTRIBUTION_H diff --git a/src/gromacs/random/seed.cpp b/src/gromacs/random/seed.cpp index 94a3f83e4d..46a926b168 100644 --- a/src/gromacs/random/seed.cpp +++ b/src/gromacs/random/seed.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,13 +42,12 @@ namespace gmx { -uint64_t -makeRandomSeed() +uint64_t makeRandomSeed() { - std::random_device rd; - uint64_t result; - std::size_t deviceBits = std::numeric_limits::digits; - std::size_t resultBits = std::numeric_limits::digits; + std::random_device rd; + uint64_t result; + std::size_t deviceBits = std::numeric_limits::digits; + std::size_t resultBits = std::numeric_limits::digits; result = static_cast(rd()); @@ -60,4 +59,4 @@ makeRandomSeed() return result; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/seed.h b/src/gromacs/random/seed.h index 75facdf5dc..1baf028823 100644 --- a/src/gromacs/random/seed.h +++ b/src/gromacs/random/seed.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,8 +62,7 @@ namespace gmx * * \return 64-bit unsigned integer with random bits. */ -uint64_t -makeRandomSeed(); +uint64_t makeRandomSeed(); /*! \brief Random device * @@ -91,18 +90,18 @@ typedef std::random_device RandomDevice; */ enum class RandomDomain { - Other = 0x00000000, //!< Generic - stream uniqueness is not important - MaxwellVelocities = 0x00001000, //!< Veolcity assignment from Maxwell distribution - TestParticleInsertion = 0x00002000, //!< Test particle insertion - UpdateCoordinates = 0x00003000, //!< Particle integrators - UpdateConstraints = 0x00004000, //!< Second integrator step for constraints - Thermostat = 0x00005000, //!< Stochastic temperature coupling - Barostat = 0x00006000, //!< Stochastic pressure coupling - ReplicaExchange = 0x00007000, //!< Replica exchange metropolis moves - ExpandedEnsemble = 0x00008000, //!< Expanded ensemble lambda moves - AwhBiasing = 0x00009000 //!< AWH biasing reference value moves + Other = 0x00000000, //!< Generic - stream uniqueness is not important + MaxwellVelocities = 0x00001000, //!< Veolcity assignment from Maxwell distribution + TestParticleInsertion = 0x00002000, //!< Test particle insertion + UpdateCoordinates = 0x00003000, //!< Particle integrators + UpdateConstraints = 0x00004000, //!< Second integrator step for constraints + Thermostat = 0x00005000, //!< Stochastic temperature coupling + Barostat = 0x00006000, //!< Stochastic pressure coupling + ReplicaExchange = 0x00007000, //!< Replica exchange metropolis moves + ExpandedEnsemble = 0x00008000, //!< Expanded ensemble lambda moves + AwhBiasing = 0x00009000 //!< AWH biasing reference value moves }; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_SEED_H diff --git a/src/gromacs/random/tabulatednormaldistribution.cpp b/src/gromacs/random/tabulatednormaldistribution.cpp index e595975f34..aeb5ee7fa7 100644 --- a/src/gromacs/random/tabulatednormaldistribution.cpp +++ b/src/gromacs/random/tabulatednormaldistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,11 +48,11 @@ namespace gmx // the table in all files using it, unless the user has requested a different // precision or resolution. template<> -const std::array -TabulatedNormalDistribution<>::c_table_ = TabulatedNormalDistribution<>::makeTable(); +const std::array + TabulatedNormalDistribution<>::c_table_ = TabulatedNormalDistribution<>::makeTable(); #else // Avoid compiler warnings about no public symbols -void TabulatedNormalDistributionDummy(){} +void TabulatedNormalDistributionDummy() {} #endif -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tabulatednormaldistribution.h b/src/gromacs/random/tabulatednormaldistribution.h index f1abfe65f7..29b16faffd 100644 --- a/src/gromacs/random/tabulatednormaldistribution.h +++ b/src/gromacs/random/tabulatednormaldistribution.h @@ -67,7 +67,7 @@ namespace detail //! Number of bits that determines the resolution of the lookup table for the normal distribution. constexpr int c_TabulatedNormalDistributionDefaultBits = 14; -} +} // namespace detail /*! \brief Tabulated normal random distribution * @@ -107,265 +107,238 @@ constexpr int c_TabulatedNormalDistributionDefaultBits = 14; template class TabulatedNormalDistribution { - static_assert(tableBits <= 24, "Normal distribution table is limited to 24bits (64MB in single precision)"); + static_assert(tableBits <= 24, + "Normal distribution table is limited to 24bits (64MB in single precision)"); +public: + /*! \brief Type of normal distribution results */ + typedef RealType result_type; + + /*! \brief Normal distribution parameter class (mean and stddev) */ + class param_type + { public: - /*! \brief Type of normal distribution results */ - typedef RealType result_type; + /*! \brief The type of distribution the parameters describe */ + typedef TabulatedNormalDistribution distribution_type; - /*! \brief Normal distribution parameter class (mean and stddev) */ - class param_type - { - public: - /*! \brief The type of distribution the parameters describe */ - typedef TabulatedNormalDistribution distribution_type; - - /*! \brief Constructor. Default is classical distr. with mean 0, stddev 1. - * - * \param mean Expectation value. - * \param stddev Standard deviation. - * - */ - explicit param_type(result_type mean = 0.0, result_type stddev = 1.0) - : mean_(mean), stddev_(stddev) {} - - /*! \brief Return mean parameter of normal distribution */ - result_type - mean() const { return mean_; } - - /*! \brief Return standard deviation parameter of normal distribution */ - result_type - stddev() const { return stddev_; } - - /*! \brief True if two sets of normal distributions parameters are identical - * - * \param x Instance to compare with. - */ - bool - operator==(const param_type &x) const - { - return (mean_ == x.mean_ && stddev_ == x.stddev_); - } - - /*! \brief True if two sets of normal distributions parameters are different. - * - * \param x Instance to compare with. - */ - bool - operator!=(const param_type &x) const { return !operator==(x); } - - private: - /*! \brief Internal storage for mean of normal distribution */ - result_type mean_; - /*! \brief Internal storage for standard deviation of normal distribution */ - result_type stddev_; - }; - - /*! \brief Fill the table with values for the normal distribution + /*! \brief Constructor. Default is classical distr. with mean 0, stddev 1. * - * This routine returns a new a std::array with the table data. + * \param mean Expectation value. + * \param stddev Standard deviation. * - * This routine is used to help construct objects of this class, - * and is exposed only to permit testing. Normal code should not - * need to call this function. */ - static - std::array - makeTable() + explicit param_type(result_type mean = 0.0, result_type stddev = 1.0) : + mean_(mean), + stddev_(stddev) { - /* Fill the table with the integral of a gaussian distribution, which - * corresponds to the inverse error function. - * We avoid integrating a gaussian numerically, since that leads to - * some loss-of-precision which also accumulates so it is worse for - * larger indices in the table. */ - constexpr std::size_t tableSize = 1 << tableBits; - constexpr std::size_t halfSize = tableSize/2; - constexpr double invHalfSize = 1.0/halfSize; - - std::array table; - - // Fill in all but the extremal entries of the table - for (std::size_t i = 0; i < halfSize-1; i++) - { - double r = (i + 0.5) * invHalfSize; - double x = std::sqrt(2.0) * erfinv(r); - - table.at(halfSize-1-i) = -x; - table.at(halfSize+i) = x; - } - // We want to fill in the extremal table entries with - // values that make the total variance equal to 1, so - // measure the variance by summing the squares of the - // other values of the distribution, starting from the - // smallest values. - double sumOfSquares = 0; - for (std::size_t i = 1; i < halfSize; i++) - { - double value = table.at(i); - sumOfSquares += value * value; - } - double missingVariance = 1.0 - 2.0*sumOfSquares/tableSize; - GMX_RELEASE_ASSERT(missingVariance > 0, "Incorrect computation of tabulated normal distribution"); - double extremalValue = std::sqrt(0.5*missingVariance*tableSize); - table.at(0) = -extremalValue; - table.back() = extremalValue; - - return table; } - public: + /*! \brief Return mean parameter of normal distribution */ + result_type mean() const { return mean_; } - /*! \brief Construct new normal distribution with specified mean & stdddev. - * - * \param mean Mean value of tabulated normal distribution - * \param stddev Standard deviation of tabulated normal distribution - */ - explicit TabulatedNormalDistribution(result_type mean = 0.0, result_type stddev = 1.0 ) - : param_(param_type(mean, stddev)), savedRandomBits_(0), savedRandomBitsLeft_(0) - { - } + /*! \brief Return standard deviation parameter of normal distribution */ + result_type stddev() const { return stddev_; } - /*! \brief Construct new normal distribution from parameter type. + /*! \brief True if two sets of normal distributions parameters are identical * - * \param param Parameter class containing mean and standard deviation. + * \param x Instance to compare with. */ - explicit TabulatedNormalDistribution( const param_type ¶m ) - : param_(param), savedRandomBits_(0), savedRandomBitsLeft_(0) + bool operator==(const param_type& x) const { + return (mean_ == x.mean_ && stddev_ == x.stddev_); } - /*! \brief Smallest value that can be generated in normal distrubiton. + /*! \brief True if two sets of normal distributions parameters are different. * - * \note The smallest value is not -infinity with a table, but it - * depends on the table resolution. With 14 bits, this is roughly - * four standard deviations below the mean. + * \param x Instance to compare with. */ - result_type - min() const - { - return c_table_[0]; - } - - /*! \brief Largest value that can be generated in normal distribution. - * - * \note The largest value is not infinity with a table, but it - * depends on the table resolution. With 14 bits, this is roughly - * four standard deviations above the mean. - */ - result_type - max() const - { - return c_table_[c_table_.size()-1]; - } - - /*! \brief Mean of the present normal distribution */ - result_type - mean() const - { - return param_.mean(); - } - - /*! \brief Standard deviation of the present normal distribution */ - - result_type - stddev() const - { - return param_.stddev(); - } + bool operator!=(const param_type& x) const { return !operator==(x); } - /*! \brief The parameter class (mean & stddev) of the normal distribution */ - param_type - param() const + private: + /*! \brief Internal storage for mean of normal distribution */ + result_type mean_; + /*! \brief Internal storage for standard deviation of normal distribution */ + result_type stddev_; + }; + + /*! \brief Fill the table with values for the normal distribution + * + * This routine returns a new a std::array with the table data. + * + * This routine is used to help construct objects of this class, + * and is exposed only to permit testing. Normal code should not + * need to call this function. + */ + static std::array makeTable() + { + /* Fill the table with the integral of a gaussian distribution, which + * corresponds to the inverse error function. + * We avoid integrating a gaussian numerically, since that leads to + * some loss-of-precision which also accumulates so it is worse for + * larger indices in the table. */ + constexpr std::size_t tableSize = 1 << tableBits; + constexpr std::size_t halfSize = tableSize / 2; + constexpr double invHalfSize = 1.0 / halfSize; + + std::array table; + + // Fill in all but the extremal entries of the table + for (std::size_t i = 0; i < halfSize - 1; i++) { - return param_; - } + double r = (i + 0.5) * invHalfSize; + double x = std::sqrt(2.0) * erfinv(r); - /*! \brief Clear all internal saved random bits from the random engine */ - void - reset() - { - savedRandomBitsLeft_ = 0; + table.at(halfSize - 1 - i) = -x; + table.at(halfSize + i) = x; } - - /*! \brief Return normal distribution value specified by internal parameters. - * - * \tparam Rng Random engine type used to provide uniform random bits. - * \param g Random engine of class Rng. For normal GROMACS usage - * you likely want to use ThreeFry2x64. - */ - template - result_type - operator()(Rng &g) + // We want to fill in the extremal table entries with + // values that make the total variance equal to 1, so + // measure the variance by summing the squares of the + // other values of the distribution, starting from the + // smallest values. + double sumOfSquares = 0; + for (std::size_t i = 1; i < halfSize; i++) { - return (*this)(g, param_); + double value = table.at(i); + sumOfSquares += value * value; } - - /*! \brief Return normal distribution value specified by given parameters - * - * \tparam Rng Random engine type used to provide uniform random bits. - * \param g Random engine of class Rng. For normal GROMACS usage - * you likely want to use ThreeFry2x64. - * \param param Parameters used to specify normal distribution. - */ - template - result_type - operator()(Rng &g, const param_type ¶m) + double missingVariance = 1.0 - 2.0 * sumOfSquares / tableSize; + GMX_RELEASE_ASSERT(missingVariance > 0, + "Incorrect computation of tabulated normal distribution"); + double extremalValue = std::sqrt(0.5 * missingVariance * tableSize); + table.at(0) = -extremalValue; + table.back() = extremalValue; + + return table; + } + +public: + /*! \brief Construct new normal distribution with specified mean & stdddev. + * + * \param mean Mean value of tabulated normal distribution + * \param stddev Standard deviation of tabulated normal distribution + */ + explicit TabulatedNormalDistribution(result_type mean = 0.0, result_type stddev = 1.0) : + param_(param_type(mean, stddev)), + savedRandomBits_(0), + savedRandomBitsLeft_(0) + { + } + + /*! \brief Construct new normal distribution from parameter type. + * + * \param param Parameter class containing mean and standard deviation. + */ + explicit TabulatedNormalDistribution(const param_type& param) : + param_(param), + savedRandomBits_(0), + savedRandomBitsLeft_(0) + { + } + + /*! \brief Smallest value that can be generated in normal distrubiton. + * + * \note The smallest value is not -infinity with a table, but it + * depends on the table resolution. With 14 bits, this is roughly + * four standard deviations below the mean. + */ + result_type min() const { return c_table_[0]; } + + /*! \brief Largest value that can be generated in normal distribution. + * + * \note The largest value is not infinity with a table, but it + * depends on the table resolution. With 14 bits, this is roughly + * four standard deviations above the mean. + */ + result_type max() const { return c_table_[c_table_.size() - 1]; } + + /*! \brief Mean of the present normal distribution */ + result_type mean() const { return param_.mean(); } + + /*! \brief Standard deviation of the present normal distribution */ + + result_type stddev() const { return param_.stddev(); } + + /*! \brief The parameter class (mean & stddev) of the normal distribution */ + param_type param() const { return param_; } + + /*! \brief Clear all internal saved random bits from the random engine */ + void reset() { savedRandomBitsLeft_ = 0; } + + /*! \brief Return normal distribution value specified by internal parameters. + * + * \tparam Rng Random engine type used to provide uniform random bits. + * \param g Random engine of class Rng. For normal GROMACS usage + * you likely want to use ThreeFry2x64. + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return normal distribution value specified by given parameters + * + * \tparam Rng Random engine type used to provide uniform random bits. + * \param g Random engine of class Rng. For normal GROMACS usage + * you likely want to use ThreeFry2x64. + * \param param Parameters used to specify normal distribution. + */ + template + result_type operator()(Rng& g, const param_type& param) + { + if (savedRandomBitsLeft_ < tableBits) { - if (savedRandomBitsLeft_ < tableBits) - { - // We do not know whether the generator g returns 64 or 32 bits, - // since g is not known when we construct this class. - // To keep things simple, we always draw one random number, - // store it in our 64-bit value, and set the number of active bits. - // For tableBits up to 16 this will be as efficient both with 32 - // and 64 bit random engines when drawing multiple numbers - // (our default value is - // c_TabulatedNormalDistributionDefaultBits == 14). It - // also avoids drawing multiple 32-bit random numbers - // even if we just call this routine for a single - // result. - savedRandomBits_ = static_cast(g()); - savedRandomBitsLeft_ = std::numeric_limits::digits; - } - result_type value = c_table_[savedRandomBits_ & ( (1ULL << tableBits) - 1 ) ]; - savedRandomBits_ >>= tableBits; - savedRandomBitsLeft_ -= tableBits; - return param.mean() + value * param.stddev(); + // We do not know whether the generator g returns 64 or 32 bits, + // since g is not known when we construct this class. + // To keep things simple, we always draw one random number, + // store it in our 64-bit value, and set the number of active bits. + // For tableBits up to 16 this will be as efficient both with 32 + // and 64 bit random engines when drawing multiple numbers + // (our default value is + // c_TabulatedNormalDistributionDefaultBits == 14). It + // also avoids drawing multiple 32-bit random numbers + // even if we just call this routine for a single + // result. + savedRandomBits_ = static_cast(g()); + savedRandomBitsLeft_ = std::numeric_limits::digits; } - - /*!\brief Check if two tabulated normal distributions have identical states. - * - * \param x Instance to compare with. - */ - bool - operator==(const TabulatedNormalDistribution &x) const - { - return (param_ == x.param_ && - savedRandomBits_ == x.savedRandomBits_ && - savedRandomBitsLeft_ == x.savedRandomBitsLeft_); - } - - /*!\brief Check if two tabulated normal distributions have different states. - * - * \param x Instance to compare with. - */ - bool - operator!=(const TabulatedNormalDistribution &x) const - { - return !operator==(x); - } - - private: - /*! \brief Parameters of normal distribution (mean and stddev) */ - param_type param_; - /*! \brief Array with tabluated values of normal distribution */ - static const std::array c_table_; - /*! \brief Saved output from random engine, shifted tableBits right each time */ - uint64_t savedRandomBits_; - /*! \brief Number of valid bits remaining i savedRandomBits_ */ - unsigned int savedRandomBitsLeft_; - - GMX_DISALLOW_COPY_AND_ASSIGN(TabulatedNormalDistribution); + result_type value = c_table_[savedRandomBits_ & ((1ULL << tableBits) - 1)]; + savedRandomBits_ >>= tableBits; + savedRandomBitsLeft_ -= tableBits; + return param.mean() + value * param.stddev(); + } + + /*!\brief Check if two tabulated normal distributions have identical states. + * + * \param x Instance to compare with. + */ + bool operator==(const TabulatedNormalDistribution& x) const + { + return (param_ == x.param_ && savedRandomBits_ == x.savedRandomBits_ + && savedRandomBitsLeft_ == x.savedRandomBitsLeft_); + } + + /*!\brief Check if two tabulated normal distributions have different states. + * + * \param x Instance to compare with. + */ + bool operator!=(const TabulatedNormalDistribution& x) const + { + return !operator==(x); + } + +private: + /*! \brief Parameters of normal distribution (mean and stddev) */ + param_type param_; + /*! \brief Array with tabluated values of normal distribution */ + static const std::array c_table_; + /*! \brief Saved output from random engine, shifted tableBits right each time */ + uint64_t savedRandomBits_; + /*! \brief Number of valid bits remaining i savedRandomBits_ */ + unsigned int savedRandomBitsLeft_; + + GMX_DISALLOW_COPY_AND_ASSIGN(TabulatedNormalDistribution); }; // MSVC does not handle extern template class members correctly even in MSVC 2015, @@ -375,16 +348,17 @@ class TabulatedNormalDistribution #if !defined(_MSC_VER) && !defined(DOXYGEN) // Declaration of template specialization template<> -const std::array TabulatedNormalDistribution<>::c_table_; +const std::array TabulatedNormalDistribution<>::c_table_; -extern template -const std::array TabulatedNormalDistribution<>::c_table_; +extern template const std::array + TabulatedNormalDistribution<>::c_table_; #endif // Instantiation for all tables without specialization template -const std::array TabulatedNormalDistribution::c_table_ = TabulatedNormalDistribution::makeTable(); +const std::array TabulatedNormalDistribution::c_table_ = + TabulatedNormalDistribution::makeTable(); -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_TABULATEDNORMALDISTRIBUTION_H diff --git a/src/gromacs/random/tests/exponentialdistribution.cpp b/src/gromacs/random/tests/exponentialdistribution.cpp index f2a5202623..66fdba9c9b 100644 --- a/src/gromacs/random/tests/exponentialdistribution.cpp +++ b/src/gromacs/random/tests/exponentialdistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,12 +57,12 @@ namespace TEST(ExponentialDistributionTest, Output) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::ExponentialDistribution dist(5.0); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::ExponentialDistribution dist(5.0); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -72,9 +72,9 @@ TEST(ExponentialDistributionTest, Output) // The implementation of the exponential distribution both in GROMACS and all current C++ // standard libraries tested is fragile since it computes an intermediate value by subtracting - // a random number in [0,1) from 1.0. This should not affect the accuracy of the final distribution, - // but depending on the compiler optimization individual values will show a somewhat larger - // fluctuation compared to the other distributions. + // a random number in [0,1) from 1.0. This should not affect the accuracy of the final + // distribution, but depending on the compiler optimization individual values will show a + // somewhat larger fluctuation compared to the other distributions. checker.setDefaultTolerance(gmx::test::relativeToleranceAsFloatingPoint(1.0, 1e-6)); checker.checkSequence(result.begin(), result.end(), "ExponentialDistribution"); } @@ -82,10 +82,10 @@ TEST(ExponentialDistributionTest, Output) TEST(ExponentialDistributionTest, Logical) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::ExponentialDistribution distA(2.0); - gmx::ExponentialDistribution distB(2.0); - gmx::ExponentialDistribution distC(3.0); + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::ExponentialDistribution distA(2.0); + gmx::ExponentialDistribution distB(2.0); + gmx::ExponentialDistribution distC(3.0); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -94,10 +94,10 @@ TEST(ExponentialDistributionTest, Logical) TEST(ExponentialDistributionTest, Reset) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::ExponentialDistribution distA(2.0); - gmx::ExponentialDistribution distB(2.0); - gmx::ExponentialDistribution<>::result_type valA, valB; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::ExponentialDistribution distA(2.0); + gmx::ExponentialDistribution distB(2.0); + gmx::ExponentialDistribution<>::result_type valA, valB; valA = distA(rng); @@ -112,11 +112,11 @@ TEST(ExponentialDistributionTest, Reset) TEST(ExponentialDistributionTest, AltParam) { - gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); - gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); - gmx::ExponentialDistribution distA(2.0); - gmx::ExponentialDistribution distB; // default parameters - gmx::ExponentialDistribution::param_type paramA(2.0); + gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); + gmx::ExponentialDistribution distA(2.0); + gmx::ExponentialDistribution distB; // default parameters + gmx::ExponentialDistribution::param_type paramA(2.0); EXPECT_NE(distA(rngA), distB(rngB)); rngA.restart(); @@ -126,6 +126,6 @@ TEST(ExponentialDistributionTest, AltParam) EXPECT_REAL_EQ_TOL(distA(rngA), distB(rngB, paramA), gmx::test::ulpTolerance(0)); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/gammadistribution.cpp b/src/gromacs/random/tests/gammadistribution.cpp index 1c6fdd154a..4cfc90e16e 100644 --- a/src/gromacs/random/tests/gammadistribution.cpp +++ b/src/gromacs/random/tests/gammadistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,12 +57,12 @@ namespace TEST(GammaDistributionTest, Output) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::GammaDistribution dist(2.0, 5.0); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::GammaDistribution dist(2.0, 5.0); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -74,11 +74,11 @@ TEST(GammaDistributionTest, Output) TEST(GammaDistributionTest, Logical) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::GammaDistribution distA(2.0, 5.0); - gmx::GammaDistribution distB(2.0, 5.0); - gmx::GammaDistribution distC(3.0, 5.0); - gmx::GammaDistribution distD(2.0, 4.0); + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::GammaDistribution distA(2.0, 5.0); + gmx::GammaDistribution distB(2.0, 5.0); + gmx::GammaDistribution distC(3.0, 5.0); + gmx::GammaDistribution distD(2.0, 4.0); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -88,10 +88,10 @@ TEST(GammaDistributionTest, Logical) TEST(GammaDistributionTest, Reset) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::GammaDistribution distA(2.0, 5.0); - gmx::GammaDistribution distB(2.0, 5.0); - gmx::GammaDistribution<>::result_type valA, valB; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::GammaDistribution distA(2.0, 5.0); + gmx::GammaDistribution distB(2.0, 5.0); + gmx::GammaDistribution<>::result_type valA, valB; valA = distA(rng); @@ -106,11 +106,11 @@ TEST(GammaDistributionTest, Reset) TEST(GammaDistributionTest, AltParam) { - gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); - gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); - gmx::GammaDistribution distA(2.0, 5.0); - gmx::GammaDistribution distB; // default parameters - gmx::GammaDistribution::param_type paramA(2.0, 5.0); + gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); + gmx::GammaDistribution distA(2.0, 5.0); + gmx::GammaDistribution distB; // default parameters + gmx::GammaDistribution::param_type paramA(2.0, 5.0); EXPECT_NE(distA(rngA), distB(rngB)); rngA.restart(); @@ -120,6 +120,6 @@ TEST(GammaDistributionTest, AltParam) EXPECT_REAL_EQ_TOL(distA(rngA), distB(rngB, paramA), gmx::test::ulpTolerance(0)); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/normaldistribution.cpp b/src/gromacs/random/tests/normaldistribution.cpp index 97167966cb..b258c27295 100644 --- a/src/gromacs/random/tests/normaldistribution.cpp +++ b/src/gromacs/random/tests/normaldistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,12 +57,12 @@ namespace TEST(NormalDistributionTest, Output) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::NormalDistribution dist(2.0, 5.0); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::NormalDistribution dist(2.0, 5.0); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -75,11 +75,11 @@ TEST(NormalDistributionTest, Output) TEST(NormalDistributionTest, Logical) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::NormalDistribution distA(2.0, 5.0); - gmx::NormalDistribution distB(2.0, 5.0); - gmx::NormalDistribution distC(3.0, 5.0); - gmx::NormalDistribution distD(2.0, 4.0); + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::NormalDistribution distA(2.0, 5.0); + gmx::NormalDistribution distB(2.0, 5.0); + gmx::NormalDistribution distC(3.0, 5.0); + gmx::NormalDistribution distD(2.0, 4.0); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -89,10 +89,10 @@ TEST(NormalDistributionTest, Logical) TEST(NormalDistributionTest, Reset) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::NormalDistribution distA(2.0, 5.0); - gmx::NormalDistribution distB(2.0, 5.0); - gmx::NormalDistribution::result_type valA, valB; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::NormalDistribution distA(2.0, 5.0); + gmx::NormalDistribution distB(2.0, 5.0); + gmx::NormalDistribution::result_type valA, valB; valA = distA(rng); @@ -132,6 +132,6 @@ TEST(NormalDistributionTest, AltParam) EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0)); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/seed.cpp b/src/gromacs/random/tests/seed.cpp index e97ceb5ace..6853acbfab 100644 --- a/src/gromacs/random/tests/seed.cpp +++ b/src/gromacs/random/tests/seed.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,6 +66,6 @@ TEST(SeedTest, makeRandomSeed) EXPECT_NE(i0, i1); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/tabulatednormaldistribution.cpp b/src/gromacs/random/tests/tabulatednormaldistribution.cpp index 502c8dfb30..89ea15be3c 100644 --- a/src/gromacs/random/tests/tabulatednormaldistribution.cpp +++ b/src/gromacs/random/tests/tabulatednormaldistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,12 +57,12 @@ namespace TEST(TabulatedNormalDistributionTest, Output14) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution<> dist(2.0, 5.0); // Use default 14-bit resolution - std::vector result; + gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution<> dist(2.0, 5.0); // Use default 14-bit resolution + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -74,12 +74,12 @@ TEST(TabulatedNormalDistributionTest, Output14) TEST(TabulatedNormalDistributionTest, Output16) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution dist(2.0, 5.0); // Use larger 16-bit table - std::vector result; + gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution dist(2.0, 5.0); // Use larger 16-bit table + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -91,12 +91,12 @@ TEST(TabulatedNormalDistributionTest, Output16) TEST(TabulatedNormalDistributionTest, OutputDouble14) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution dist(2.0, 5.0); - std::vector result; + gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution dist(2.0, 5.0); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -108,11 +108,11 @@ TEST(TabulatedNormalDistributionTest, OutputDouble14) TEST(TabulatedNormalDistributionTest, Logical) { - gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); - gmx::TabulatedNormalDistribution<> distB(2.0, 5.0); - gmx::TabulatedNormalDistribution<> distC(3.0, 5.0); - gmx::TabulatedNormalDistribution<> distD(2.0, 4.0); + gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); + gmx::TabulatedNormalDistribution<> distB(2.0, 5.0); + gmx::TabulatedNormalDistribution<> distC(3.0, 5.0); + gmx::TabulatedNormalDistribution<> distD(2.0, 4.0); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -122,10 +122,10 @@ TEST(TabulatedNormalDistributionTest, Logical) TEST(TabulatedNormalDistributionTest, Reset) { - gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); - gmx::TabulatedNormalDistribution<> distB(2.0, 5.0); - gmx::TabulatedNormalDistribution<>::result_type valA, valB; + gmx::ThreeFry2x64<2> rng(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); + gmx::TabulatedNormalDistribution<> distB(2.0, 5.0); + gmx::TabulatedNormalDistribution<>::result_type valA, valB; valA = distA(rng); @@ -140,11 +140,11 @@ TEST(TabulatedNormalDistributionTest, Reset) TEST(TabulatedNormalDistributionTest, AltParam) { - gmx::ThreeFry2x64<2> rngA(123456, gmx::RandomDomain::Other); - gmx::ThreeFry2x64<2> rngB(123456, gmx::RandomDomain::Other); - gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); - gmx::TabulatedNormalDistribution<> distB; - gmx::TabulatedNormalDistribution<>::param_type paramA(2.0, 5.0); + gmx::ThreeFry2x64<2> rngA(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<2> rngB(123456, gmx::RandomDomain::Other); + gmx::TabulatedNormalDistribution<> distA(2.0, 5.0); + gmx::TabulatedNormalDistribution<> distB; + gmx::TabulatedNormalDistribution<>::param_type paramA(2.0, 5.0); EXPECT_NE(distA(rngA), distB(rngB)); rngA.restart(); @@ -164,11 +164,11 @@ TEST(TabulatedNormalDistributionTableTest, HasValidProperties) double sumOfSquares = 0.0; // accept errors of a few ULP since the exact value of the summation // below will depend on whether the compiler issues FMA instructions - auto tolerance = gmx::test::ulpTolerance(10); - for (size_t i = 0, iFromEnd = table.size()-1; i < halfSize; ++i, --iFromEnd) + auto tolerance = gmx::test::ulpTolerance(10); + for (size_t i = 0, iFromEnd = table.size() - 1; i < halfSize; ++i, --iFromEnd) { EXPECT_REAL_EQ_TOL(table.at(i), -table.at(iFromEnd), tolerance) - << "Table is not an odd-valued function for entries " << i << " and " << iFromEnd; + << "Table is not an odd-valued function for entries " << i << " and " << iFromEnd; // Add up the squares of the table values in order of ascending // magnitude (to minimize accumulation of round-off error). sumOfSquares += table.at(i) * table.at(i) + table.at(iFromEnd) * table.at(iFromEnd); @@ -178,6 +178,6 @@ TEST(TabulatedNormalDistributionTableTest, HasValidProperties) EXPECT_REAL_EQ_TOL(1.0, variance, tolerance) << "Table should have unit variance"; } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/threefry.cpp b/src/gromacs/random/tests/threefry.cpp index 7afd82665c..a31e6ead19 100644 --- a/src/gromacs/random/tests/threefry.cpp +++ b/src/gromacs/random/tests/threefry.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,18 +55,18 @@ namespace gmx namespace { -class ThreeFry2x64Test : public ::testing::TestWithParam > +class ThreeFry2x64Test : public ::testing::TestWithParam> { }; TEST_P(ThreeFry2x64Test, Default) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - const std::vector input = GetParam(); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + const std::vector input = GetParam(); + std::vector result; - gmx::ThreeFry2x64<0> rng(input[2], input[3]); + gmx::ThreeFry2x64<0> rng(input[2], input[3]); rng.restart(input[0], input[1]); result.push_back(rng()); @@ -77,12 +77,12 @@ TEST_P(ThreeFry2x64Test, Default) TEST_P(ThreeFry2x64Test, Fast) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - const std::vector input = GetParam(); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + const std::vector input = GetParam(); + std::vector result; - gmx::ThreeFry2x64Fast<0> rng(input[2], input[3]); + gmx::ThreeFry2x64Fast<0> rng(input[2], input[3]); rng.restart(input[0], input[1]); result.push_back(rng()); @@ -93,12 +93,12 @@ TEST_P(ThreeFry2x64Test, Fast) TEST_P(ThreeFry2x64Test, Using40Rounds) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - const std::vector input = GetParam(); - std::vector result; + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + const std::vector input = GetParam(); + std::vector result; - gmx::ThreeFry2x64General<40, 0> rng(input[2], input[3]); + gmx::ThreeFry2x64General<40, 0> rng(input[2], input[3]); rng.restart(input[0], input[1]); result.push_back(rng()); @@ -114,9 +114,7 @@ TEST_P(ThreeFry2x64Test, Using40Rounds) * The 2x64 flavors of ThreeFry64 will use the first four values, while * the 4x64 version uses all eight. */ -const std::vector bitsZero {{ - 0, 0, 0, 0 - }}; +const std::vector bitsZero{ { 0, 0, 0, 0 } }; /*! \brief Constant array of integers with all bits set to one. @@ -125,10 +123,8 @@ const std::vector bitsZero {{ * The 2x64 flavors of ThreeFry64 will use the first four values, while * the 4x64 version uses all eight. */ -const std::vector bitsOne {{ - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL - }}; +const std::vector bitsOne{ { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL } }; /*! \brief Constant array of integers with bitpattern from Pi. * @@ -136,15 +132,12 @@ const std::vector bitsOne {{ * The 2x64 flavors of ThreeFry64 will use the first four values, while * the 4x64 version uses all eight. */ -const std::vector bitsPi {{ - 0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL, - 0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL - }}; +const std::vector bitsPi{ { 0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL, + 0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL } }; // Test the known ansers for the ThreeFry random function when the argument // is (1) all zero, (2) all ones, (3) the bits of pi, for a bunch of different flavors of ThreeFry. -INSTANTIATE_TEST_CASE_P(KnownAnswersTest, ThreeFry2x64Test, - ::testing::Values(bitsZero, bitsOne, bitsPi)); +INSTANTIATE_TEST_CASE_P(KnownAnswersTest, ThreeFry2x64Test, ::testing::Values(bitsZero, bitsOne, bitsPi)); // ThreeFry2x64 tests @@ -154,9 +147,10 @@ TEST_F(ThreeFry2x64Test, Logical) gmx::ThreeFry2x64<10> rngB(123456, gmx::RandomDomain::Other); gmx::ThreeFry2x64<10> rngC(123456, gmx::RandomDomain::Other); - rngB(); // draw just once first, so block is the same, but index has changed + rngB(); // draw just once first, so block is the same, but index has changed EXPECT_NE(rngA, rngB); - rngC(); rngC(); // two draws: next block, but index is the same + rngC(); + rngC(); // two draws: next block, but index is the same EXPECT_NE(rngA, rngC); rngA(); EXPECT_EQ(rngA, rngB); @@ -166,13 +160,13 @@ TEST_F(ThreeFry2x64Test, Logical) TEST_F(ThreeFry2x64Test, InternalCounterSequence) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); // 66 bits of internal counter means the first four increments (giving 2*4=8 results) // correspond to incrementing word 0, and then we should carry over to word 1. - gmx::ThreeFry2x64<66> rngA(123456, gmx::RandomDomain::Other); - std::vector result; + gmx::ThreeFry2x64<66> rngA(123456, gmx::RandomDomain::Other); + std::vector result; result.reserve(16); for (int i = 0; i < 16; i++) @@ -182,14 +176,14 @@ TEST_F(ThreeFry2x64Test, InternalCounterSequence) checker.checkSequence(result.begin(), result.end(), "ThreeFry2x64InternalCounterSequence"); // Make sure nothing goes wrong with the internal counter sequence when we use a full 64-bit word - gmx::ThreeFry2x64<64> rngB(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<64> rngB(123456, gmx::RandomDomain::Other); for (int i = 0; i < 16; i++) { rngB(); } // Use every single bit for the internal counter - gmx::ThreeFry2x64<128> rngC(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<128> rngC(123456, gmx::RandomDomain::Other); for (int i = 0; i < 16; i++) { rngC(); @@ -244,6 +238,6 @@ TEST_F(ThreeFry2x64Test, ExhaustInternalCounter) EXPECT_THROW_GMX(rngA(), gmx::InternalError); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/uniformintdistribution.cpp b/src/gromacs/random/tests/uniformintdistribution.cpp index b718ada683..1584dac8f2 100644 --- a/src/gromacs/random/tests/uniformintdistribution.cpp +++ b/src/gromacs/random/tests/uniformintdistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,12 +57,12 @@ namespace TEST(UniformIntDistributionTest, Output) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformIntDistribution dist(1, 1000); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformIntDistribution dist(1, 1000); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -75,11 +75,11 @@ TEST(UniformIntDistributionTest, Output) TEST(UniformIntDistributionTest, Logical) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformIntDistribution distA(2, 5); - gmx::UniformIntDistribution distB(2, 5); - gmx::UniformIntDistribution distC(3, 5); - gmx::UniformIntDistribution distD(2, 4); + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformIntDistribution distA(2, 5); + gmx::UniformIntDistribution distB(2, 5); + gmx::UniformIntDistribution distC(3, 5); + gmx::UniformIntDistribution distD(2, 4); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -89,10 +89,10 @@ TEST(UniformIntDistributionTest, Logical) TEST(UniformIntDistributionTest, Reset) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformIntDistribution distA(2, 5); - gmx::UniformIntDistribution distB(2, 5); - gmx::UniformIntDistribution<>::result_type valA, valB; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformIntDistribution distA(2, 5); + gmx::UniformIntDistribution distB(2, 5); + gmx::UniformIntDistribution<>::result_type valA, valB; valA = distA(rng); @@ -107,11 +107,11 @@ TEST(UniformIntDistributionTest, Reset) TEST(UniformIntDistributionTest, AltParam) { - gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); - gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); - gmx::UniformIntDistribution distA(2, 5); - gmx::UniformIntDistribution distB; // default parameters - gmx::UniformIntDistribution::param_type paramA(2, 5); + gmx::ThreeFry2x64<8> rngA(123456, gmx::RandomDomain::Other); + gmx::ThreeFry2x64<8> rngB(123456, gmx::RandomDomain::Other); + gmx::UniformIntDistribution distA(2, 5); + gmx::UniformIntDistribution distB; // default parameters + gmx::UniformIntDistribution::param_type paramA(2, 5); EXPECT_NE(distA(rngA), distB(rngB)); rngA.restart(); @@ -122,6 +122,6 @@ TEST(UniformIntDistributionTest, AltParam) } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/tests/uniformrealdistribution.cpp b/src/gromacs/random/tests/uniformrealdistribution.cpp index 0214912b00..03c93a622c 100644 --- a/src/gromacs/random/tests/uniformrealdistribution.cpp +++ b/src/gromacs/random/tests/uniformrealdistribution.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,11 +57,11 @@ namespace TEST(UniformRealDistributionTest, GenerateCanonical) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -73,12 +73,12 @@ TEST(UniformRealDistributionTest, GenerateCanonical) TEST(UniformRealDistributionTest, Output) { - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformRealDistribution dist(1.0, 10.0); - std::vector result; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformRealDistribution dist(1.0, 10.0); + std::vector result; result.reserve(10); for (int i = 0; i < 10; i++) @@ -90,11 +90,11 @@ TEST(UniformRealDistributionTest, Output) TEST(UniformRealDistributionTest, Logical) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformRealDistribution distA(2.0, 5.0); - gmx::UniformRealDistribution distB(2.0, 5.0); - gmx::UniformRealDistribution distC(3.0, 5.0); - gmx::UniformRealDistribution distD(2.0, 4.0); + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformRealDistribution distA(2.0, 5.0); + gmx::UniformRealDistribution distB(2.0, 5.0); + gmx::UniformRealDistribution distC(3.0, 5.0); + gmx::UniformRealDistribution distD(2.0, 4.0); EXPECT_EQ(distA, distB); EXPECT_NE(distA, distC); @@ -104,10 +104,10 @@ TEST(UniformRealDistributionTest, Logical) TEST(UniformRealDistributionTest, Reset) { - gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); - gmx::UniformRealDistribution distA(2.0, 5.0); - gmx::UniformRealDistribution distB(2.0, 5.0); - gmx::UniformRealDistribution::result_type valA, valB; + gmx::ThreeFry2x64<8> rng(123456, gmx::RandomDomain::Other); + gmx::UniformRealDistribution distA(2.0, 5.0); + gmx::UniformRealDistribution distB(2.0, 5.0); + gmx::UniformRealDistribution::result_type valA, valB; valA = distA(rng); @@ -145,6 +145,6 @@ TEST(UniformRealDistributionTest, AltParam) EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0)); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/random/threefry.h b/src/gromacs/random/threefry.h index faadc66b94..4946a3092e 100644 --- a/src/gromacs/random/threefry.h +++ b/src/gromacs/random/threefry.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -97,8 +97,7 @@ namespace internal // Variable-bitfield counters used to increment internal counters as // part of std::arrays. -struct -highBitCounter +struct highBitCounter { /*! \brief Clear highBits higest bits of ctr, return false if they were non-zero. * @@ -112,33 +111,32 @@ highBitCounter * \param ctr Reference to counter to check and clear. */ template - static bool - checkAndClear(std::array * ctr) + static bool checkAndClear(std::array* ctr) { - const std::size_t bitsPerWord = std::numeric_limits::digits; - const std::size_t bitsTotal = bitsPerWord*words; + const std::size_t bitsPerWord = std::numeric_limits::digits; + const std::size_t bitsTotal = bitsPerWord * words; static_assert(highBits <= bitsTotal, "High bits do not fit in counter."); - const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; - const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; - const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; - const UIntType mask = lastWordOne-1; + const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; + const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; + const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; + const UIntType mask = lastWordOne - 1; - bool isClear = true; + bool isClear = true; - for (unsigned int i = words-1; i > lastWordIdx; --i) + for (unsigned int i = words - 1; i > lastWordIdx; --i) { if ((*ctr)[i]) { - isClear = false; - (*ctr)[i] = 0; + isClear = false; + (*ctr)[i] = 0; } } if (highBits > 0 && (*ctr)[lastWordIdx] >= lastWordOne) { - isClear = false; - (*ctr)[lastWordIdx] &= mask; + isClear = false; + (*ctr)[lastWordIdx] &= mask; } return isClear; } @@ -156,17 +154,16 @@ highBitCounter * of internal counter bits that fits in the total counter. */ template - static void - increment(std::array * ctr) + static void increment(std::array* ctr) { - const std::size_t bitsPerWord = std::numeric_limits::digits; - const std::size_t bitsTotal = bitsPerWord*words; + const std::size_t bitsPerWord = std::numeric_limits::digits; + const std::size_t bitsTotal = bitsPerWord * words; static_assert(highBits <= bitsTotal, "High bits do not fit in counter."); - const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; - const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; - const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; + const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; + const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; + const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; // For algorithm & efficiency reasons we need to store the internal counter in // the same array as the user-provided counter, so we use the higest bits, possibly @@ -204,15 +201,16 @@ highBitCounter if (lastWordIdx >= words) { - GMX_THROW(InternalError("Cannot increment random engine defined with 0 internal counter bits.")); + GMX_THROW(InternalError( + "Cannot increment random engine defined with 0 internal counter bits.")); } - for (unsigned int i = words-1; i > lastWordIdx; --i) + for (unsigned int i = words - 1; i > lastWordIdx; --i) { (*ctr)[i]++; if ((*ctr)[i]) { - return; // No carry means we are done + return; // No carry means we are done } } (*ctr)[lastWordIdx] += lastWordOne; @@ -236,28 +234,28 @@ highBitCounter * of internal counter bits that fits in the total counter. */ template - static void - increment(std::array * ctr, UIntType addend) + static void increment(std::array* ctr, UIntType addend) { - const std::size_t bitsPerWord = std::numeric_limits::digits; - const std::size_t bitsTotal = bitsPerWord*words; + const std::size_t bitsPerWord = std::numeric_limits::digits; + const std::size_t bitsTotal = bitsPerWord * words; static_assert(highBits <= bitsTotal, "High bits do not fit in counter."); - const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; - const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; - const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; - const UIntType lastWordMaxVal = (~static_cast(0)) >> lastWordLowBitIdx; + const std::size_t lastWordIdx = (bitsTotal - highBits) / bitsPerWord; + const std::size_t lastWordLowBitIdx = (bitsTotal - highBits) % bitsPerWord; + const UIntType lastWordOne = static_cast(1) << lastWordLowBitIdx; + const UIntType lastWordMaxVal = (~static_cast(0)) >> lastWordLowBitIdx; if (lastWordIdx >= words) { - GMX_THROW(InternalError("Cannot increment random engine defined with 0 internal counter bits.")); + GMX_THROW(InternalError( + "Cannot increment random engine defined with 0 internal counter bits.")); } - for (unsigned int i = words-1; i > lastWordIdx; --i) + for (unsigned int i = words - 1; i > lastWordIdx; --i) { (*ctr)[i] += addend; - addend = ((*ctr)[i] < addend); // 1 is the carry! + addend = ((*ctr)[i] < addend); // 1 is the carry! if (addend == 0) { return; @@ -278,7 +276,7 @@ highBitCounter } } }; -} // namespace internal +} // namespace internal /*! \brief General implementation class for ThreeFry counter-based random engines. * @@ -330,340 +328,447 @@ class ThreeFry2x64General // no reason to go lower than 13, and this might help catch some typos. // If we find a reason to use lower values in the future, or if you simply // want to test, this assert can safely be removed. - static_assert(rounds >= 13, "You should not use less than 13 encryption rounds for ThreeFry2x64."); - - public: - // result_type must be lower case to be compatible with C++11 standard library - - /*! \brief Integer type for output. */ - typedef uint64_t result_type; - /*! \brief Use array for counter & key states so it is allocated on the stack */ - typedef std::array counter_type; - - private: - - /*! \brief Rotate value left by specified number of bits - * - * \param i Value to rotate (result_type, which should be 64-bit). - * \param bits Number of bits to rotate i. - * - * \return Input value rotated 'bits' left. - */ - result_type - rotLeft(result_type i, unsigned int bits) - { - return (i << bits) | (i >> (std::numeric_limits::digits-bits)); - } - - /*! \brief Perform encryption step for ThreeFry2x64 algorithm - * - * It performs the encryption step of the standard ThreeFish symmetric-key - * tweakable block cipher, which is the core of the ThreeFry random - * engine. The number of encryption rounds is specified by the class - * template parameter 'rounds'. - * - * \param key Reference to key value - * \param ctr Counter value to use - * - * \return Newly encrypted 2x64 block, according to the class template parameters. - */ - counter_type - generateBlock(const counter_type &key, - const counter_type &ctr) - { - const unsigned int rotations[] = {16, 42, 12, 31, 16, 32, 24, 21}; - counter_type x = ctr; - - result_type ks[3] = { 0x0, 0x0, 0x1bd11bdaa9fc1a22 }; - - // This is actually a pretty simple routine that merely executes the - // for-block specified further down 'rounds' times. However, both - // clang and gcc have problems unrolling and replacing rotations[r%8] - // with constants, so we unroll the first 20 iterations manually. - - if (rounds > 0) - { - ks[0] = key[0]; ks[2] ^= key[0]; x[0] = x[0] + key[0]; - ks[1] = key[1]; ks[2] ^= key[1]; x[1] = x[1] + key[1]; - x[0] += x[1]; x[1] = rotLeft(x[1], 16); x[1] ^= x[0]; - } - if (rounds > 1) { x[0] += x[1]; x[1] = rotLeft(x[1], 42); x[1] ^= x[0]; } - if (rounds > 2) { x[0] += x[1]; x[1] = rotLeft(x[1], 12); x[1] ^= x[0]; } - if (rounds > 3) { x[0] += x[1]; x[1] = rotLeft(x[1], 31); x[1] ^= x[0]; x[0] += ks[1]; x[1] += ks[2] + 1; } - if (rounds > 4) { x[0] += x[1]; x[1] = rotLeft(x[1], 16); x[1] ^= x[0]; } - if (rounds > 5) { x[0] += x[1]; x[1] = rotLeft(x[1], 32); x[1] ^= x[0]; } - if (rounds > 6) { x[0] += x[1]; x[1] = rotLeft(x[1], 24); x[1] ^= x[0]; } - if (rounds > 7) { x[0] += x[1]; x[1] = rotLeft(x[1], 21); x[1] ^= x[0]; x[0] += ks[2]; x[1] += ks[0] + 2; } - if (rounds > 8) { x[0] += x[1]; x[1] = rotLeft(x[1], 16); x[1] ^= x[0]; } - if (rounds > 9) { x[0] += x[1]; x[1] = rotLeft(x[1], 42); x[1] ^= x[0]; } - if (rounds > 10) { x[0] += x[1]; x[1] = rotLeft(x[1], 12); x[1] ^= x[0]; } - if (rounds > 11) { x[0] += x[1]; x[1] = rotLeft(x[1], 31); x[1] ^= x[0]; x[0] += ks[0]; x[1] += ks[1] + 3; } - if (rounds > 12) { x[0] += x[1]; x[1] = rotLeft(x[1], 16); x[1] ^= x[0]; } - if (rounds > 13) { x[0] += x[1]; x[1] = rotLeft(x[1], 32); x[1] ^= x[0]; } - if (rounds > 14) { x[0] += x[1]; x[1] = rotLeft(x[1], 24); x[1] ^= x[0]; } - if (rounds > 15) { x[0] += x[1]; x[1] = rotLeft(x[1], 21); x[1] ^= x[0]; x[0] += ks[1]; x[1] += ks[2] + 4; } - if (rounds > 16) { x[0] += x[1]; x[1] = rotLeft(x[1], 16); x[1] ^= x[0]; } - if (rounds > 17) { x[0] += x[1]; x[1] = rotLeft(x[1], 42); x[1] ^= x[0]; } - if (rounds > 18) { x[0] += x[1]; x[1] = rotLeft(x[1], 12); x[1] ^= x[0]; } - if (rounds > 19) { x[0] += x[1]; x[1] = rotLeft(x[1], 31); x[1] ^= x[0]; x[0] += ks[2]; x[1] += ks[0] + 5; } - - for (unsigned int r = 20; r < rounds; r++) + static_assert(rounds >= 13, + "You should not use less than 13 encryption rounds for ThreeFry2x64."); + +public: + // result_type must be lower case to be compatible with C++11 standard library + + /*! \brief Integer type for output. */ + typedef uint64_t result_type; + /*! \brief Use array for counter & key states so it is allocated on the stack */ + typedef std::array counter_type; + +private: + /*! \brief Rotate value left by specified number of bits + * + * \param i Value to rotate (result_type, which should be 64-bit). + * \param bits Number of bits to rotate i. + * + * \return Input value rotated 'bits' left. + */ + result_type rotLeft(result_type i, unsigned int bits) + { + return (i << bits) | (i >> (std::numeric_limits::digits - bits)); + } + + /*! \brief Perform encryption step for ThreeFry2x64 algorithm + * + * It performs the encryption step of the standard ThreeFish symmetric-key + * tweakable block cipher, which is the core of the ThreeFry random + * engine. The number of encryption rounds is specified by the class + * template parameter 'rounds'. + * + * \param key Reference to key value + * \param ctr Counter value to use + * + * \return Newly encrypted 2x64 block, according to the class template parameters. + */ + counter_type generateBlock(const counter_type& key, const counter_type& ctr) + { + const unsigned int rotations[] = { 16, 42, 12, 31, 16, 32, 24, 21 }; + counter_type x = ctr; + + result_type ks[3] = { 0x0, 0x0, 0x1bd11bdaa9fc1a22 }; + + // This is actually a pretty simple routine that merely executes the + // for-block specified further down 'rounds' times. However, both + // clang and gcc have problems unrolling and replacing rotations[r%8] + // with constants, so we unroll the first 20 iterations manually. + + if (rounds > 0) + { + ks[0] = key[0]; + ks[2] ^= key[0]; + x[0] = x[0] + key[0]; + ks[1] = key[1]; + ks[2] ^= key[1]; + x[1] = x[1] + key[1]; + x[0] += x[1]; + x[1] = rotLeft(x[1], 16); + x[1] ^= x[0]; + } + if (rounds > 1) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 42); + x[1] ^= x[0]; + } + if (rounds > 2) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 12); + x[1] ^= x[0]; + } + if (rounds > 3) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 31); + x[1] ^= x[0]; + x[0] += ks[1]; + x[1] += ks[2] + 1; + } + if (rounds > 4) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 16); + x[1] ^= x[0]; + } + if (rounds > 5) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 32); + x[1] ^= x[0]; + } + if (rounds > 6) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 24); + x[1] ^= x[0]; + } + if (rounds > 7) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 21); + x[1] ^= x[0]; + x[0] += ks[2]; + x[1] += ks[0] + 2; + } + if (rounds > 8) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 16); + x[1] ^= x[0]; + } + if (rounds > 9) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 42); + x[1] ^= x[0]; + } + if (rounds > 10) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 12); + x[1] ^= x[0]; + } + if (rounds > 11) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 31); + x[1] ^= x[0]; + x[0] += ks[0]; + x[1] += ks[1] + 3; + } + if (rounds > 12) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 16); + x[1] ^= x[0]; + } + if (rounds > 13) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 32); + x[1] ^= x[0]; + } + if (rounds > 14) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 24); + x[1] ^= x[0]; + } + if (rounds > 15) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 21); + x[1] ^= x[0]; + x[0] += ks[1]; + x[1] += ks[2] + 4; + } + if (rounds > 16) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 16); + x[1] ^= x[0]; + } + if (rounds > 17) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 42); + x[1] ^= x[0]; + } + if (rounds > 18) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 12); + x[1] ^= x[0]; + } + if (rounds > 19) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], 31); + x[1] ^= x[0]; + x[0] += ks[2]; + x[1] += ks[0] + 5; + } + + for (unsigned int r = 20; r < rounds; r++) + { + x[0] += x[1]; + x[1] = rotLeft(x[1], rotations[r % 8]); + x[1] ^= x[0]; + if (((r + 1) & 3) == 0) { - x[0] += x[1]; - x[1] = rotLeft(x[1], rotations[r%8]); - x[1] ^= x[0]; - if (( (r + 1) & 3 ) == 0) - { - unsigned int r4 = (r + 1) >> 2; - x[0] += ks[ r4 % 3 ]; - x[1] += ks[ (r4 + 1) % 3 ] + r4; - } + unsigned int r4 = (r + 1) >> 2; + x[0] += ks[r4 % 3]; + x[1] += ks[(r4 + 1) % 3] + r4; } - return x; } + return x; + } - public: - //! \brief Smallest value that can be returned from random engine. +public: + //! \brief Smallest value that can be returned from random engine. #if !defined(_MSC_VER) - static constexpr + static constexpr #else - // Avoid constexpr bug in MSVC 2015, note that max() below does work - static + // Avoid constexpr bug in MSVC 2015, note that max() below does work + static #endif - result_type min() { return std::numeric_limits::min(); } - - //! \brief Largest value that can be returned from random engine. - static constexpr - result_type max() { return std::numeric_limits::max(); } - - /*! \brief Construct random engine with 2x64 key values - * - * This constructor takes two values, and should only be used with - * the 2x64 implementations. - * - * \param key0 Random seed in the form of a 64-bit unsigned value. - * \param domain Random domain. This is used to guarantee that different - * applications of a random engine inside the code get different - * streams of random numbers, without requiring the user - * to provide lots of random seeds. Pick a value from the - * RandomDomain class, or RandomDomain::Other if it is - * not important. In the latter case you might want to use - * \ref gmx::DefaultRandomEngine instead. - * - * \note The random domain is really another 64-bit seed value. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. - */ - //NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) - ThreeFry2x64General(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) - { - seed(key0, domain); - } - - /*! \brief Construct random engine from 2x64-bit unsigned integers - * - * This constructor assigns the raw 128 bit key data from unsigned integers. - * It is meant for the case when you want full control over the key, - * for instance to compare with reference values of the ThreeFry - * function during testing. - * - * \param key0 First word of key/random seed. - * \param key1 Second word of key/random seed. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. To test arbitrary values, use 0 internal counter bits. - */ - //NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) - ThreeFry2x64General(uint64_t key0, uint64_t key1) - { - seed(key0, key1); - } - - /*! \brief Seed 2x64 random engine with two 64-bit key values - * - * \param key0 First word of random seed, in the form of 64-bit unsigned values. - * \param domain Random domain. This is used to guarantee that different - * applications of a random engine inside the code get different - * streams of random numbers, without requiring the user - * to provide lots of random seeds. Pick a value from the - * RandomDomain class, or RandomDomain::Other if it is - * not important. In the latter case you might want to use - * \ref gmx::DefaultRandomEngine instead. - * - * \note The random domain is really another 64-bit seed value. - * - * Re-initialized the seed similar to the counter constructor. - * Same rules apply: The highest few bits of the last word are - * reserved to encode the number of internal counter bits, but - * to save the user the trouble of making sure these are zero - * when using e.g. a random device, we just ignore them. - */ - void - seed(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) - { - seed(key0, static_cast(domain)); - } - - /*! \brief Seed random engine from 2x64-bit unsigned integers - * - * This assigns the raw 128 bit key data from unsigned integers. - * It is meant for the case when you want full control over the key, - * for instance to compare with reference values of the ThreeFry - * function during testing. - * - * \param key0 First word of key/random seed. - * \param key1 Second word of key/random seed. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. To test arbitrary values, use 0 internal counter bits. - */ - void - seed(uint64_t key0, uint64_t key1) - { - const unsigned int internalCounterBitsBits = (internalCounterBits > 0) ? ( StaticLog2::value + 1 ) : 0; - - key_ = {{key0, key1}}; - - if (internalCounterBits > 0) - { - internal::highBitCounter::checkAndClear(&key_); - internal::highBitCounter::increment(&key_, internalCounterBits-1); - } - restart(0, 0); - } - - /*! \brief Restart 2x64 random engine counter from 2 64-bit values - * - * \param ctr0 First word of new counter, in the form of 64-bit unsigned values. - * \param ctr1 Second word of new counter - * - * Restarting the engine with a new counter is extremely fast with ThreeFry64, - * and basically just consists of storing the counter value, so you should - * use this liberally in your innermost loops to restart the engine with - * e.g. the current step and atom index as counter values. - * - * \throws InternalError if any of the highest bits that are reserved - * for the internal part of the counter are set. The number of - * reserved bits is to the last template parameter to the class. - */ - void - restart(uint64_t ctr0 = 0, uint64_t ctr1 = 0) - { - - counter_ = {{ctr0, ctr1}}; - if (!internal::highBitCounter::checkAndClear(&counter_)) - { - GMX_THROW(InternalError("High bits of counter are reserved for the internal stream counter.")); - } + result_type + min() + { + return std::numeric_limits::min(); + } + + //! \brief Largest value that can be returned from random engine. + static constexpr result_type max() { return std::numeric_limits::max(); } + + /*! \brief Construct random engine with 2x64 key values + * + * This constructor takes two values, and should only be used with + * the 2x64 implementations. + * + * \param key0 Random seed in the form of a 64-bit unsigned value. + * \param domain Random domain. This is used to guarantee that different + * applications of a random engine inside the code get different + * streams of random numbers, without requiring the user + * to provide lots of random seeds. Pick a value from the + * RandomDomain class, or RandomDomain::Other if it is + * not important. In the latter case you might want to use + * \ref gmx::DefaultRandomEngine instead. + * + * \note The random domain is really another 64-bit seed value. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. + */ + //NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) + ThreeFry2x64General(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) + { + seed(key0, domain); + } + + /*! \brief Construct random engine from 2x64-bit unsigned integers + * + * This constructor assigns the raw 128 bit key data from unsigned integers. + * It is meant for the case when you want full control over the key, + * for instance to compare with reference values of the ThreeFry + * function during testing. + * + * \param key0 First word of key/random seed. + * \param key1 Second word of key/random seed. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. To test arbitrary values, use 0 internal counter bits. + */ + //NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) + ThreeFry2x64General(uint64_t key0, uint64_t key1) { seed(key0, key1); } + + /*! \brief Seed 2x64 random engine with two 64-bit key values + * + * \param key0 First word of random seed, in the form of 64-bit unsigned values. + * \param domain Random domain. This is used to guarantee that different + * applications of a random engine inside the code get different + * streams of random numbers, without requiring the user + * to provide lots of random seeds. Pick a value from the + * RandomDomain class, or RandomDomain::Other if it is + * not important. In the latter case you might want to use + * \ref gmx::DefaultRandomEngine instead. + * + * \note The random domain is really another 64-bit seed value. + * + * Re-initialized the seed similar to the counter constructor. + * Same rules apply: The highest few bits of the last word are + * reserved to encode the number of internal counter bits, but + * to save the user the trouble of making sure these are zero + * when using e.g. a random device, we just ignore them. + */ + void seed(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) + { + seed(key0, static_cast(domain)); + } + + /*! \brief Seed random engine from 2x64-bit unsigned integers + * + * This assigns the raw 128 bit key data from unsigned integers. + * It is meant for the case when you want full control over the key, + * for instance to compare with reference values of the ThreeFry + * function during testing. + * + * \param key0 First word of key/random seed. + * \param key1 Second word of key/random seed. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. To test arbitrary values, use 0 internal counter bits. + */ + void seed(uint64_t key0, uint64_t key1) + { + const unsigned int internalCounterBitsBits = + (internalCounterBits > 0) ? (StaticLog2::value + 1) : 0; + + key_ = { { key0, key1 } }; + + if (internalCounterBits > 0) + { + internal::highBitCounter::checkAndClear(&key_); + internal::highBitCounter::increment( + &key_, internalCounterBits - 1); + } + restart(0, 0); + } + + /*! \brief Restart 2x64 random engine counter from 2 64-bit values + * + * \param ctr0 First word of new counter, in the form of 64-bit unsigned values. + * \param ctr1 Second word of new counter + * + * Restarting the engine with a new counter is extremely fast with ThreeFry64, + * and basically just consists of storing the counter value, so you should + * use this liberally in your innermost loops to restart the engine with + * e.g. the current step and atom index as counter values. + * + * \throws InternalError if any of the highest bits that are reserved + * for the internal part of the counter are set. The number of + * reserved bits is to the last template parameter to the class. + */ + void restart(uint64_t ctr0 = 0, uint64_t ctr1 = 0) + { + + counter_ = { { ctr0, ctr1 } }; + if (!internal::highBitCounter::checkAndClear(&counter_)) + { + GMX_THROW(InternalError( + "High bits of counter are reserved for the internal stream counter.")); + } + block_ = generateBlock(key_, counter_); + index_ = 0; + } + + /*! \brief Generate the next random number + * + * This will return the next stored 64-bit value if one is available, + * and otherwise generate a new block, update the internal counters, and + * return the first value while storing the others. + * + * \throws InternalError if the internal counter space is exhausted. + */ + result_type operator()() + { + if (index_ >= c_resultsPerCounter_) + { + internal::highBitCounter::increment(&counter_); block_ = generateBlock(key_, counter_); index_ = 0; } + return block_[index_++]; + } - /*! \brief Generate the next random number - * - * This will return the next stored 64-bit value if one is available, - * and otherwise generate a new block, update the internal counters, and - * return the first value while storing the others. - * - * \throws InternalError if the internal counter space is exhausted. - */ - result_type - operator()() + /*! \brief Skip next n random numbers + * + * Moves the internal random stream for the give key/counter value + * n positions forward. The count is based on the number of random values + * returned, such that skipping 5 values gives exactly the same result as + * drawing 5 values that are ignored. + * + * \param n Number of values to jump forward. + * + * \throws InternalError if the internal counter space is exhausted. + */ + void discard(uint64_t n) + { + index_ += n % c_resultsPerCounter_; + n /= c_resultsPerCounter_; + + if (index_ > c_resultsPerCounter_) { - if (index_ >= c_resultsPerCounter_) - { - internal::highBitCounter::increment(&counter_); - block_ = generateBlock(key_, counter_); - index_ = 0; - } - return block_[index_++]; - } - - /*! \brief Skip next n random numbers - * - * Moves the internal random stream for the give key/counter value - * n positions forward. The count is based on the number of random values - * returned, such that skipping 5 values gives exactly the same result as - * drawing 5 values that are ignored. - * - * \param n Number of values to jump forward. - * - * \throws InternalError if the internal counter space is exhausted. - */ - void - discard(uint64_t n) - { - index_ += n % c_resultsPerCounter_; - n /= c_resultsPerCounter_; - - if (index_ > c_resultsPerCounter_) - { - index_ -= c_resultsPerCounter_; - n++; - } + index_ -= c_resultsPerCounter_; + n++; + } - // Make sure the state is the same as if we came to this counter and - // index by natural generation. - if (index_ == 0 && n > 0) - { - index_ = c_resultsPerCounter_; - n--; - } - internal::highBitCounter::increment(&counter_, n); - block_ = generateBlock(key_, counter_); + // Make sure the state is the same as if we came to this counter and + // index by natural generation. + if (index_ == 0 && n > 0) + { + index_ = c_resultsPerCounter_; + n--; } + internal::highBitCounter::increment(&counter_, n); + block_ = generateBlock(key_, counter_); + } - /*! \brief Return true if two ThreeFry2x64 engines are identical - * - * \param x Instance to compare with. - * - * This routine should return true if the two engines will generate - * identical random streams when drawing. - */ - bool - operator==(const ThreeFry2x64General &x) const - { - // block_ is uniquely specified by key_ and counter_. - return (key_ == x.key_ && counter_ == x.counter_ && index_ == x.index_); - } - - /*! \brief Return true of two ThreeFry2x64 engines are not identical - * - * \param x Instance to compare with. - * - * This routine should return true if the two engines will generate - * different random streams when drawing. - */ - bool - operator!=(const ThreeFry2x64General &x) const { return !operator==(x); } - - private: - - /*! \brief Number of results returned for each invocation of the block generation */ - static const unsigned int c_resultsPerCounter_ = static_cast(sizeof(counter_type)/sizeof(result_type)); - - /*! \brief ThreeFry2x64 key, i.e. the random seed for this stream. - * - * The highest few bits of the key are replaced to encode the value of - * internalCounterBits, in order to make all streams unique. - */ - counter_type key_; - - /*! \brief ThreeFry2x64 total counter. - * - * The highest internalCounterBits are reserved for an internal counter - * so that the combination of a key and counter provides a stream that - * returns 2*2^internalCounterBits (ThreeFry2x64) random 64-bit values before - * the internal counter space is exhausted and an exception is thrown. - */ - counter_type counter_; - /*! \brief The present block encrypted from values of key and counter. */ - counter_type block_; - /*! \brief Index of the next value in block_ to return from random engine */ - unsigned int index_; - - GMX_DISALLOW_COPY_AND_ASSIGN(ThreeFry2x64General); + /*! \brief Return true if two ThreeFry2x64 engines are identical + * + * \param x Instance to compare with. + * + * This routine should return true if the two engines will generate + * identical random streams when drawing. + */ + bool operator==(const ThreeFry2x64General& x) const + { + // block_ is uniquely specified by key_ and counter_. + return (key_ == x.key_ && counter_ == x.counter_ && index_ == x.index_); + } + + /*! \brief Return true of two ThreeFry2x64 engines are not identical + * + * \param x Instance to compare with. + * + * This routine should return true if the two engines will generate + * different random streams when drawing. + */ + bool operator!=(const ThreeFry2x64General& x) const + { + return !operator==(x); + } + +private: + /*! \brief Number of results returned for each invocation of the block generation */ + static const unsigned int c_resultsPerCounter_ = + static_cast(sizeof(counter_type) / sizeof(result_type)); + + /*! \brief ThreeFry2x64 key, i.e. the random seed for this stream. + * + * The highest few bits of the key are replaced to encode the value of + * internalCounterBits, in order to make all streams unique. + */ + counter_type key_; + + /*! \brief ThreeFry2x64 total counter. + * + * The highest internalCounterBits are reserved for an internal counter + * so that the combination of a key and counter provides a stream that + * returns 2*2^internalCounterBits (ThreeFry2x64) random 64-bit values before + * the internal counter space is exhausted and an exception is thrown. + */ + counter_type counter_; + /*! \brief The present block encrypted from values of key and counter. */ + counter_type block_; + /*! \brief Index of the next value in block_ to return from random engine */ + unsigned int index_; + + GMX_DISALLOW_COPY_AND_ASSIGN(ThreeFry2x64General); }; @@ -679,39 +784,45 @@ class ThreeFry2x64General template class ThreeFry2x64 : public ThreeFry2x64General<20, internalCounterBits> { - public: - /*! \brief Construct ThreeFry random engine with 2x64 key values, 20 rounds. - * - * \param key0 Random seed in the form of a 64-bit unsigned value. - * \param domain Random domain. This is used to guarantee that different - * applications of a random engine inside the code get different - * streams of random numbers, without requiring the user - * to provide lots of random seeds. Pick a value from the - * RandomDomain class, or RandomDomain::Other if it is - * not important. In the latter case you might want to use - * \ref gmx::DefaultRandomEngine instead. - * - * \note The random domain is really another 64-bit seed value. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. - */ - ThreeFry2x64(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) : ThreeFry2x64General<20, internalCounterBits>(key0, domain) {} - - /*! \brief Construct random engine from 2x64-bit unsigned integers, 20 rounds - * - * This constructor assigns the raw 128 bit key data from unsigned integers. - * It is meant for the case when you want full control over the key, - * for instance to compare with reference values of the ThreeFry - * function during testing. - * - * \param key0 First word of key/random seed. - * \param key1 Second word of key/random seed. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. To test arbitrary values, use 0 internal counter bits. - */ - ThreeFry2x64(uint64_t key0, uint64_t key1) : ThreeFry2x64General<20, internalCounterBits>(key0, key1) {} +public: + /*! \brief Construct ThreeFry random engine with 2x64 key values, 20 rounds. + * + * \param key0 Random seed in the form of a 64-bit unsigned value. + * \param domain Random domain. This is used to guarantee that different + * applications of a random engine inside the code get different + * streams of random numbers, without requiring the user + * to provide lots of random seeds. Pick a value from the + * RandomDomain class, or RandomDomain::Other if it is + * not important. In the latter case you might want to use + * \ref gmx::DefaultRandomEngine instead. + * + * \note The random domain is really another 64-bit seed value. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. + */ + ThreeFry2x64(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) : + ThreeFry2x64General<20, internalCounterBits>(key0, domain) + { + } + + /*! \brief Construct random engine from 2x64-bit unsigned integers, 20 rounds + * + * This constructor assigns the raw 128 bit key data from unsigned integers. + * It is meant for the case when you want full control over the key, + * for instance to compare with reference values of the ThreeFry + * function during testing. + * + * \param key0 First word of key/random seed. + * \param key1 Second word of key/random seed. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. To test arbitrary values, use 0 internal counter bits. + */ + ThreeFry2x64(uint64_t key0, uint64_t key1) : + ThreeFry2x64General<20, internalCounterBits>(key0, key1) + { + } }; /*! \brief ThreeFry2x64 random engine with 13 iteractions. @@ -727,41 +838,46 @@ class ThreeFry2x64 : public ThreeFry2x64General<20, internalCounterBits> template class ThreeFry2x64Fast : public ThreeFry2x64General<13, internalCounterBits> { - public: - /*! \brief Construct ThreeFry random engine with 2x64 key values, 13 rounds. - * - * \param key0 Random seed in the form of a 64-bit unsigned value. - * \param domain Random domain. This is used to guarantee that different - * applications of a random engine inside the code get different - * streams of random numbers, without requiring the user - * to provide lots of random seeds. Pick a value from the - * RandomDomain class, or RandomDomain::Other if it is - * not important. In the latter case you might want to use - * \ref gmx::DefaultRandomEngine instead. - * - * \note The random domain is really another 64-bit seed value. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. - */ - ThreeFry2x64Fast(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) : ThreeFry2x64General<13, internalCounterBits>(key0, domain) {} - - /*! \brief Construct ThreeFry random engine from 2x64-bit unsigned integers, 13 rounds. - * - * This constructor assigns the raw 128 bit key data from unsigned integers. - * It is meant for the case when you want full control over the key, - * for instance to compare with reference values of the ThreeFry - * function during testing. - * - * \param key0 First word of key/random seed. - * \param key1 Second word of key/random seed. - * - * \throws InternalError if the high bits needed to encode the number of counter - * bits are nonzero. To test arbitrary values, use 0 internal counter bits. - */ - ThreeFry2x64Fast(uint64_t key0, uint64_t key1) : ThreeFry2x64General<13, internalCounterBits>(key0, key1) {} -}; +public: + /*! \brief Construct ThreeFry random engine with 2x64 key values, 13 rounds. + * + * \param key0 Random seed in the form of a 64-bit unsigned value. + * \param domain Random domain. This is used to guarantee that different + * applications of a random engine inside the code get different + * streams of random numbers, without requiring the user + * to provide lots of random seeds. Pick a value from the + * RandomDomain class, or RandomDomain::Other if it is + * not important. In the latter case you might want to use + * \ref gmx::DefaultRandomEngine instead. + * + * \note The random domain is really another 64-bit seed value. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. + */ + ThreeFry2x64Fast(uint64_t key0 = 0, RandomDomain domain = RandomDomain::Other) : + ThreeFry2x64General<13, internalCounterBits>(key0, domain) + { + } + /*! \brief Construct ThreeFry random engine from 2x64-bit unsigned integers, 13 rounds. + * + * This constructor assigns the raw 128 bit key data from unsigned integers. + * It is meant for the case when you want full control over the key, + * for instance to compare with reference values of the ThreeFry + * function during testing. + * + * \param key0 First word of key/random seed. + * \param key1 Second word of key/random seed. + * + * \throws InternalError if the high bits needed to encode the number of counter + * bits are nonzero. To test arbitrary values, use 0 internal counter bits. + */ + ThreeFry2x64Fast(uint64_t key0, uint64_t key1) : + ThreeFry2x64General<13, internalCounterBits>(key0, key1) + { + } +}; /*! \brief Default fast and accurate random engine in Gromacs @@ -770,8 +886,8 @@ class ThreeFry2x64Fast : public ThreeFry2x64General<13, internalCounterBits> * gmx::RandomDomain::Other stream, and can be initialized with a single * seed argument without having to remember empty template angle brackets. */ -typedef ThreeFry2x64Fast<> DefaultRandomEngine; +typedef ThreeFry2x64Fast<> DefaultRandomEngine; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_THREEFRY_H diff --git a/src/gromacs/random/uniformintdistribution.h b/src/gromacs/random/uniformintdistribution.h index ff96b3b24b..bde17a2dae 100644 --- a/src/gromacs/random/uniformintdistribution.h +++ b/src/gromacs/random/uniformintdistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,197 +71,195 @@ namespace gmx template class UniformIntDistribution { - public: - /*! \brief Type of values returned */ - typedef IntType result_type; - - /*! \brief Uniform int distribution parameters */ - class param_type - { - /*! \brief Lower end of range (inclusive) */ - result_type a_; - /*! \brief Upper end of range (inclusive) */ - result_type b_; - - public: - /*! \brief Reference back to the distribution class */ - typedef UniformIntDistribution distribution_type; - - /*! \brief Construct parameter block - * - * \param a Lower end of range (inclusive) - * \param b Upper end of range (inclusive) - */ - explicit param_type(result_type a = 0, result_type b = std::numeric_limits::max()) - : a_(a), b_(b) - { - GMX_RELEASE_ASSERT(a <= b, "The uniform integer distribution requires a<=b"); - } - - /*! \brief Return lower range */ - result_type a() const { return a_; } - /*! \brief Return upper range */ - result_type b() const { return b_; } - - /*! \brief True if two parameter sets will return the same uniform int distribution. - * - * \param x Instance to compare with. - */ - bool - operator==(const param_type &x) const - { - // rangeBits is a function of a & b, so it does not have to be tested - return a_ == x.a_ && b_ == x.b_; - } - - /*! \brief True if two parameter sets will return different uniform int distributions - * - * \param x Instance to compare with. - */ - bool - operator!=(const param_type &x) const { return !operator==(x); } - }; +public: + /*! \brief Type of values returned */ + typedef IntType result_type; + + /*! \brief Uniform int distribution parameters */ + class param_type + { + /*! \brief Lower end of range (inclusive) */ + result_type a_; + /*! \brief Upper end of range (inclusive) */ + result_type b_; public: + /*! \brief Reference back to the distribution class */ + typedef UniformIntDistribution distribution_type; - /*! \brief Construct new distribution with given integer parameters. + /*! \brief Construct parameter block * * \param a Lower end of range (inclusive) * \param b Upper end of range (inclusive) */ - explicit UniformIntDistribution(result_type a = 0, result_type b = std::numeric_limits::max()) - : param_(param_type(a, b)), savedRandomBits_(0), savedRandomBitsLeft_(0) {} - - /*! \brief Construct new distribution from parameter class - * - * \param param Parameter class as defined inside gmx::UniformIntDistribution. - */ - explicit UniformIntDistribution(const param_type ¶m) - : param_(param), savedRandomBits_(0), savedRandomBitsLeft_(0) {} + explicit param_type(result_type a = 0, result_type b = std::numeric_limits::max()) : + a_(a), + b_(b) + { + GMX_RELEASE_ASSERT(a <= b, "The uniform integer distribution requires a<=b"); + } - /*! \brief Flush all internal saved values */ - void - reset() { savedRandomBitsLeft_ = 0; } + /*! \brief Return lower range */ + result_type a() const { return a_; } + /*! \brief Return upper range */ + result_type b() const { return b_; } - /*! \brief Return values from uniform int distribution with internal parameters - * - * \tparam Rng Uniform random engine class + /*! \brief True if two parameter sets will return the same uniform int distribution. * - * \param g Random engine + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g) { return (*this)(g, param_); } + bool operator==(const param_type& x) const + { + // rangeBits is a function of a & b, so it does not have to be tested + return a_ == x.a_ && b_ == x.b_; + } - /*! \brief Return value from uniform int distribution with given parameters - * - * \tparam Rng Uniform random engine class + /*! \brief True if two parameter sets will return different uniform int distributions * - * \param g Random engine - * \param param Parameters to use + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g, const param_type ¶m) + bool operator!=(const param_type& x) const { return !operator==(x); } + }; + +public: + /*! \brief Construct new distribution with given integer parameters. + * + * \param a Lower end of range (inclusive) + * \param b Upper end of range (inclusive) + */ + explicit UniformIntDistribution(result_type a = 0, + result_type b = std::numeric_limits::max()) : + param_(param_type(a, b)), + savedRandomBits_(0), + savedRandomBitsLeft_(0) + { + } + + /*! \brief Construct new distribution from parameter class + * + * \param param Parameter class as defined inside gmx::UniformIntDistribution. + */ + explicit UniformIntDistribution(const param_type& param) : + param_(param), + savedRandomBits_(0), + savedRandomBitsLeft_(0) + { + } + + /*! \brief Flush all internal saved values */ + void reset() { savedRandomBitsLeft_ = 0; } + + /*! \brief Return values from uniform int distribution with internal parameters + * + * \tparam Rng Uniform random engine class + * + * \param g Random engine + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return value from uniform int distribution with given parameters + * + * \tparam Rng Uniform random engine class + * + * \param g Random engine + * \param param Parameters to use + */ + template + result_type operator()(Rng& g, const param_type& param) + { + static_assert(sizeof(typename Rng::result_type) >= sizeof(uint32_t), + "The random engine result_type should be 32 or 64 bits"); + + result_type range = param.b() - param.a(); + unsigned int rangeBits; + result_type result; + + if (range == 0) { - static_assert(sizeof(typename Rng::result_type) >= sizeof(uint32_t), - "The random engine result_type should be 32 or 64 bits"); - - result_type range = param.b() - param.a(); - unsigned int rangeBits; - result_type result; - - if (range == 0) - { - return param.a(); - } - else if (range == std::numeric_limits::max()) + return param.a(); + } + else if (range == std::numeric_limits::max()) + { + rangeBits = std::numeric_limits::digits; // Use all bits in type + } + else + { + if (sizeof(result_type) == sizeof(uint32_t)) { - rangeBits = std::numeric_limits::digits; // Use all bits in type + rangeBits = log2I(static_cast(range)); } else { - if (sizeof(result_type) == sizeof(uint32_t)) - { - rangeBits = log2I(static_cast(range)); - } - else - { - rangeBits = log2I(range); - } - rangeBits += ((range >> rangeBits) > 0); + rangeBits = log2I(range); } + rangeBits += ((range >> rangeBits) > 0); + } - do + do + { + if (savedRandomBitsLeft_ < rangeBits) { - if (savedRandomBitsLeft_ < rangeBits) + savedRandomBits_ = static_cast(g()); + savedRandomBitsLeft_ = std::numeric_limits::digits; + + if (sizeof(typename Rng::result_type) == sizeof(uint32_t)) { - savedRandomBits_ = static_cast(g()); - savedRandomBitsLeft_ = std::numeric_limits::digits; - - if (sizeof(typename Rng::result_type) == sizeof(uint32_t)) - { - savedRandomBits_ <<= std::numeric_limits::digits; - savedRandomBits_ |= g(); - savedRandomBitsLeft_ += std::numeric_limits::digits; - } + savedRandomBits_ <<= std::numeric_limits::digits; + savedRandomBits_ |= g(); + savedRandomBitsLeft_ += std::numeric_limits::digits; } - result = savedRandomBits_; - savedRandomBits_ >>= rangeBits; - result = result - (savedRandomBits_ << rangeBits); - savedRandomBitsLeft_ -= rangeBits; } - while (result > range); - - return result + param.a(); - } - - /*! \brief Return the lower range uniform int distribution */ - result_type - a() const { return param_.a(); } - - /*! \brief Return the upper range of the uniform int distribution */ - result_type - b() const { return param_.b(); } - - /*! \brief Return the full parameter class of the uniform int distribution */ - param_type param() const { return param_; } - - /*! \brief Smallest value that can be returned from uniform int distribution */ - result_type - min() const { return a(); } - - /*! \brief Largest value that can be returned from uniform int distribution */ - result_type - max() const { return b(); } - - /*! \brief True if two uniform int distributions will produce the same values. - * - * \param x Instance to compare with. - */ - bool - operator==(const UniformIntDistribution &x) const - { return param_ == x.param_; } - - /*! \brief True if two uniform int distributions will produce different values. - * - * \param x Instance to compare with. - */ - bool - operator!=(const UniformIntDistribution &x) const - { return !operator==(x); } - - private: - /*! \brief Internal value for parameters, can be overridden at generation time. */ - param_type param_; - /*! \brief Saved output from random engine, shifted tableBits right each time */ - uint64_t savedRandomBits_; - /*! \brief Number of valid bits remaining i savedRandomBits_ */ - unsigned int savedRandomBitsLeft_; - - GMX_DISALLOW_COPY_AND_ASSIGN(UniformIntDistribution); + result = savedRandomBits_; + savedRandomBits_ >>= rangeBits; + result = result - (savedRandomBits_ << rangeBits); + savedRandomBitsLeft_ -= rangeBits; + } while (result > range); + + return result + param.a(); + } + + /*! \brief Return the lower range uniform int distribution */ + result_type a() const { return param_.a(); } + + /*! \brief Return the upper range of the uniform int distribution */ + result_type b() const { return param_.b(); } + + /*! \brief Return the full parameter class of the uniform int distribution */ + param_type param() const { return param_; } + + /*! \brief Smallest value that can be returned from uniform int distribution */ + result_type min() const { return a(); } + + /*! \brief Largest value that can be returned from uniform int distribution */ + result_type max() const { return b(); } + + /*! \brief True if two uniform int distributions will produce the same values. + * + * \param x Instance to compare with. + */ + bool operator==(const UniformIntDistribution& x) const { return param_ == x.param_; } + + /*! \brief True if two uniform int distributions will produce different values. + * + * \param x Instance to compare with. + */ + bool operator!=(const UniformIntDistribution& x) const { return !operator==(x); } + +private: + /*! \brief Internal value for parameters, can be overridden at generation time. */ + param_type param_; + /*! \brief Saved output from random engine, shifted tableBits right each time */ + uint64_t savedRandomBits_; + /*! \brief Number of valid bits remaining i savedRandomBits_ */ + unsigned int savedRandomBitsLeft_; + + GMX_DISALLOW_COPY_AND_ASSIGN(UniformIntDistribution); }; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_UNIFORMINTDISTRIBUTION_H diff --git a/src/gromacs/random/uniformrealdistribution.h b/src/gromacs/random/uniformrealdistribution.h index f4a740a10c..a90e320f2f 100644 --- a/src/gromacs/random/uniformrealdistribution.h +++ b/src/gromacs/random/uniformrealdistribution.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -101,23 +101,22 @@ namespace gmx * */ template -RealType -generateCanonical(Rng &g) +RealType generateCanonical(Rng& g) { // No point in using more bits than fit in RealType - const uint64_t digits = std::numeric_limits::digits; - const uint64_t realBits = std::min(digits, static_cast(Bits)); - const uint64_t range = Rng::max() - Rng::min() + uint64_t(1); - uint64_t log2R = (range == 0) ? std::numeric_limits::digits : log2I(range); - uint64_t k = realBits / log2R + (realBits % log2R != 0) + (realBits == 0); - RealType r = Rng::max() - Rng::min() + RealType(1); - RealType s = g() - Rng::min(); - RealType base = r; - RealType result; + const uint64_t digits = std::numeric_limits::digits; + const uint64_t realBits = std::min(digits, static_cast(Bits)); + const uint64_t range = Rng::max() - Rng::min() + uint64_t(1); + uint64_t log2R = (range == 0) ? std::numeric_limits::digits : log2I(range); + uint64_t k = realBits / log2R + (realBits % log2R != 0) + (realBits == 0); + RealType r = Rng::max() - Rng::min() + RealType(1); + RealType s = g() - Rng::min(); + RealType base = r; + RealType result; for (uint64_t i = 1; i < k; ++i) { - s += RealType(g()-Rng::min()) * base; + s += RealType(g() - Rng::min()) * base; base *= r; } result = s / base; @@ -160,143 +159,130 @@ generateCanonical(Rng &g) template class UniformRealDistribution { - public: - /*! \brief Type of values returned */ - typedef RealType result_type; +public: + /*! \brief Type of values returned */ + typedef RealType result_type; - /*! \brief Uniform real distribution parameters */ - class param_type - { - /*! \brief Lower end of range (inclusive) */ - result_type a_; - /*! \brief Upper end of range (exclusive) */ - result_type b_; - - public: - /*! \brief Reference back to the distribution class */ - typedef UniformRealDistribution distribution_type; - - /*! \brief Construct parameter block - * - * \param a Lower end of range (inclusive) - * \param b Upper end of range (exclusive) - */ - explicit param_type(result_type a = 0.0, result_type b = 1.0) - : a_(a), b_(b) - { - GMX_RELEASE_ASSERT(a < b, "The uniform real distribution requires a - result_type - operator()(Rng &g) { return (*this)(g, param_); } + bool operator==(const param_type& x) const { return a_ == x.a_ && b_ == x.b_; } - /*! \brief Return value from uniform real distribution with given parameters + /*! \brief True if two parameter sets will return different uniform real distributions * - * \tparam Rng Random engine class - * - * \param g Random engine - * \param param Parameters to use + * \param x Instance to compare with. */ - template - result_type - operator()(Rng &g, const param_type ¶m) - { - result_type r = generateCanonical::digits>(g); - return ( param.b() - param.a() ) * r + param.a(); - } + bool operator!=(const param_type& x) const { return !operator==(x); } + }; + +public: + /*! \brief Construct new distribution with given floating-point parameters. + * + * \param a Lower end of range (inclusive) + * \param b Upper end of range (exclusive) + */ + explicit UniformRealDistribution(result_type a = 0.0, result_type b = 1.0) : + param_(param_type(a, b)) + { + } + + /*! \brief Construct new distribution from parameter class + * + * \param param Parameter class as defined inside gmx::UniformRealDistribution. + */ + explicit UniformRealDistribution(const param_type& param) : param_(param) {} + + /*! \brief Flush all internal saved values */ + void reset() {} + + /*! \brief Return values from uniform real distribution with internal parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + */ + template + result_type operator()(Rng& g) + { + return (*this)(g, param_); + } + + /*! \brief Return value from uniform real distribution with given parameters + * + * \tparam Rng Random engine class + * + * \param g Random engine + * \param param Parameters to use + */ + template + result_type operator()(Rng& g, const param_type& param) + { + result_type r = generateCanonical::digits>(g); + return (param.b() - param.a()) * r + param.a(); + } - /*! \brief Return the lower range uniform real distribution */ - result_type - a() const { return param_.a(); } + /*! \brief Return the lower range uniform real distribution */ + result_type a() const { return param_.a(); } - /*! \brief Return the upper range of the uniform real distribution */ - result_type - b() const { return param_.b(); } + /*! \brief Return the upper range of the uniform real distribution */ + result_type b() const { return param_.b(); } - /*! \brief Return the full parameter class of the uniform real distribution */ - param_type param() const { return param_; } + /*! \brief Return the full parameter class of the uniform real distribution */ + param_type param() const { return param_; } - /*! \brief Smallest value that can be returned from uniform real distribution */ - result_type - min() const { return a(); } + /*! \brief Smallest value that can be returned from uniform real distribution */ + result_type min() const { return a(); } - /*! \brief Largest value that can be returned from uniform real distribution */ - result_type - max() const { return b(); } + /*! \brief Largest value that can be returned from uniform real distribution */ + result_type max() const { return b(); } - /*! \brief True if two uniform real distributions will produce the same values. - * - * \param x Instance to compare with. - */ - bool - operator==(const UniformRealDistribution &x) const - { return param_ == x.param_; } + /*! \brief True if two uniform real distributions will produce the same values. + * + * \param x Instance to compare with. + */ + bool operator==(const UniformRealDistribution& x) const { return param_ == x.param_; } - /*! \brief True if two uniform real distributions will produce different values. - * - * \param x Instance to compare with. - */ - bool - operator!=(const UniformRealDistribution &x) const - { return !operator==(x); } + /*! \brief True if two uniform real distributions will produce different values. + * + * \param x Instance to compare with. + */ + bool operator!=(const UniformRealDistribution& x) const { return !operator==(x); } - private: - /*! \brief Internal value for parameters, can be overridden at generation time. */ - param_type param_; +private: + /*! \brief Internal value for parameters, can be overridden at generation time. */ + param_type param_; - GMX_DISALLOW_COPY_AND_ASSIGN(UniformRealDistribution); + GMX_DISALLOW_COPY_AND_ASSIGN(UniformRealDistribution); }; -} // namespace gmx +} // namespace gmx #endif // GMX_RANDOM_UNIFORMREALDISTRIBUTION_H diff --git a/src/gromacs/restraint/manager.cpp b/src/gromacs/restraint/manager.cpp index e80182c990..ad73da367e 100644 --- a/src/gromacs/restraint/manager.cpp +++ b/src/gromacs/restraint/manager.cpp @@ -61,48 +61,47 @@ namespace gmx */ class RestraintManager::Impl { - public: - - /*! - * \brief Implement Manager::addToSpec() - * - * \param restraint Handle to be added to the manager. - * \param name Identifying string for restraint. - */ - void add(std::shared_ptr<::gmx::IRestraintPotential> restraint, const std::string &name); - - /*! - * \brief Clear registered restraints and reset the manager. - */ - void clear() noexcept; - - /*! - * \brief The list of configured restraints. - * - * Clients can extend the life of a restraint implementation object that - * is being used by holding the shared_ptr handle. A RestraintManager::Impl is logically - * const when its owning Manager is logically const, but the Manager can still - * grant access to individual restraints. - */ - std::vector< std::shared_ptr<::gmx::IRestraintPotential> > restraint_; - - private: - //! Regulate initialization of the shared resource when (re)initialized. - static std::mutex initializationMutex_; - +public: + /*! + * \brief Implement Manager::addToSpec() + * + * \param restraint Handle to be added to the manager. + * \param name Identifying string for restraint. + */ + void add(std::shared_ptr<::gmx::IRestraintPotential> restraint, const std::string& name); + + /*! + * \brief Clear registered restraints and reset the manager. + */ + void clear() noexcept; + + /*! + * \brief The list of configured restraints. + * + * Clients can extend the life of a restraint implementation object that + * is being used by holding the shared_ptr handle. A RestraintManager::Impl is logically + * const when its owning Manager is logically const, but the Manager can still + * grant access to individual restraints. + */ + std::vector> restraint_; + +private: + //! Regulate initialization of the shared resource when (re)initialized. + static std::mutex initializationMutex_; }; // Initialize static members -std::mutex RestraintManager::Impl::initializationMutex_ {}; +std::mutex RestraintManager::Impl::initializationMutex_{}; -void RestraintManager::Impl::add(std::shared_ptr<::gmx::IRestraintPotential> restraint, const std::string &name) +void RestraintManager::Impl::add(std::shared_ptr<::gmx::IRestraintPotential> restraint, + const std::string& name) { (void)name; restraint_.emplace_back(std::move(restraint)); } -RestraintManager::RestraintManager() : instance_(std::make_shared()) {}; +RestraintManager::RestraintManager() : instance_(std::make_shared()){}; RestraintManager::~RestraintManager() = default; @@ -118,13 +117,12 @@ void RestraintManager::clear() noexcept instance_->clear(); } -void RestraintManager::addToSpec(std::shared_ptr puller, - const std::string &name) +void RestraintManager::addToSpec(std::shared_ptr puller, const std::string& name) { instance_->add(std::move(puller), name); } -std::vector< std::shared_ptr > RestraintManager::getRestraints() const +std::vector> RestraintManager::getRestraints() const { return instance_->restraint_; } diff --git a/src/gromacs/restraint/manager.h b/src/gromacs/restraint/manager.h index 30b6bab373..eda0e81863 100644 --- a/src/gromacs/restraint/manager.h +++ b/src/gromacs/restraint/manager.h @@ -76,67 +76,66 @@ namespace gmx */ class RestraintManager final { - public: - //! Create new restraint manager resources with empty set of restraints. - RestraintManager(); - - ~RestraintManager(); - - /*! - * \brief Client code can access the shared resource by copying or moving a handle. - * \{ - */ - RestraintManager(const RestraintManager &/* unused */) = default; - RestraintManager &operator=(const RestraintManager & /* unused */) = default; - RestraintManager(RestraintManager &&) noexcept = default; - RestraintManager &operator=(RestraintManager && /* unused */) noexcept = default; - /*! \} */ - - /*! - * \brief Clear registered restraints and reset the manager. - */ - void clear() noexcept; - - /*! - * \brief Get the number of currently managed restraints. - * - * \return number of restraints. - * - * \internal - * Only considers the IRestraintPotential objects - */ - unsigned long countRestraints() noexcept; - - /*! \brief Obtain the ability to create a restraint MDModule - * - * Though the name is reminiscent of the evolving idea of a work specification, the - * Spec here is just a list of restraint modules. - * - * \param restraint shared ownership of a restraint potential interface. - * \param name key by which to reference the restraint. - */ - void addToSpec(std::shared_ptr restraint, - const std::string &name); - - /*! - * \brief Get a copy of the current set of restraints to be applied. - * - * This function is to be used when launching a simulation to get the - * restraint handles to bind, so it is not performance sensitive. A new - * vector is returned with each call because it is unspecified whether - * the set of handles point to the same objects on all threads or between - * calls to getRestraints. - * - * \return a copy of the list of restraint potentials. - */ - std::vector< std::shared_ptr > getRestraints() const; - - private: - class Impl; - //! Ownership of the shared reference to the global manager. - std::shared_ptr instance_; +public: + //! Create new restraint manager resources with empty set of restraints. + RestraintManager(); + + ~RestraintManager(); + + /*! + * \brief Client code can access the shared resource by copying or moving a handle. + * \{ + */ + RestraintManager(const RestraintManager& /* unused */) = default; + RestraintManager& operator=(const RestraintManager& /* unused */) = default; + RestraintManager(RestraintManager&&) noexcept = default; + RestraintManager& operator=(RestraintManager&& /* unused */) noexcept = default; + /*! \} */ + + /*! + * \brief Clear registered restraints and reset the manager. + */ + void clear() noexcept; + + /*! + * \brief Get the number of currently managed restraints. + * + * \return number of restraints. + * + * \internal + * Only considers the IRestraintPotential objects + */ + unsigned long countRestraints() noexcept; + + /*! \brief Obtain the ability to create a restraint MDModule + * + * Though the name is reminiscent of the evolving idea of a work specification, the + * Spec here is just a list of restraint modules. + * + * \param restraint shared ownership of a restraint potential interface. + * \param name key by which to reference the restraint. + */ + void addToSpec(std::shared_ptr restraint, const std::string& name); + + /*! + * \brief Get a copy of the current set of restraints to be applied. + * + * This function is to be used when launching a simulation to get the + * restraint handles to bind, so it is not performance sensitive. A new + * vector is returned with each call because it is unspecified whether + * the set of handles point to the same objects on all threads or between + * calls to getRestraints. + * + * \return a copy of the list of restraint potentials. + */ + std::vector> getRestraints() const; + +private: + class Impl; + //! Ownership of the shared reference to the global manager. + std::shared_ptr instance_; }; -} // end namespace gmx +} // end namespace gmx -#endif //GROMACS_RESTRAINT_MANAGER_H +#endif // GROMACS_RESTRAINT_MANAGER_H diff --git a/src/gromacs/restraint/restraintmdmodule.cpp b/src/gromacs/restraint/restraintmdmodule.cpp index 32c0d01861..e1e7f65a88 100644 --- a/src/gromacs/restraint/restraintmdmodule.cpp +++ b/src/gromacs/restraint/restraintmdmodule.cpp @@ -48,12 +48,12 @@ namespace gmx { RestraintForceProvider::RestraintForceProvider(std::shared_ptr restraint, - const std::vector &sites) : - restraint_ {std::move(restraint)} + const std::vector& sites) : + restraint_{ std::move(restraint) } { GMX_ASSERT(restraint_, "Valid RestraintForceProviders wrap non-null restraints."); GMX_ASSERT(sites_.empty(), ""); - for (auto && site : sites) + for (auto&& site : sites) { sites_.emplace_back(site); } @@ -63,29 +63,24 @@ RestraintForceProvider::RestraintForceProvider(std::shared_ptr= 0, "number of home atoms must be non-negative."); - const auto &box = forceProviderInput.box_; + const auto& box = forceProviderInput.box_; GMX_ASSERT(check_box(-1, box) == nullptr, "Invalid box."); - t_pbc pbc {}; - set_pbc(&pbc, - -1, - box); - - const auto &x = forceProviderInput.x_; - const auto &cr = forceProviderInput.cr_; - const auto &t = forceProviderInput.t_; + t_pbc pbc{}; + set_pbc(&pbc, -1, box); + + const auto& x = forceProviderInput.x_; + const auto& cr = forceProviderInput.cr_; + const auto& t = forceProviderInput.t_; // Cooperatively get Cartesian coordinates for center of mass of each site - RVec r1 = sites_[0].centerOfMass(cr, - static_cast(mdatoms.homenr), - x, - t); + RVec r1 = sites_[0].centerOfMass(cr, static_cast(mdatoms.homenr), x, t); // r2 is to be constructed as // r2 = (site[N] - site[N-1]) + (site_{N-1} - site_{N-2}) + ... + (site_2 - site_1) + site_1 // where the minimum image convention is applied to each path but not to the overall sum. @@ -94,26 +89,17 @@ void RestraintForceProvider::calculateForces(const ForceProviderInput &forceProv // Cartesian coordinate system. Called code should not use r1 and r2 to attempt to identify // sites in the simulation. If we need that functionality, we should do it separately by // allowing called code to look up atoms by tag or global index. - RVec r2 = {r1[0], r1[1], r1[2]}; - rvec dr = {0, 0, 0}; + RVec r2 = { r1[0], r1[1], r1[2] }; + rvec dr = { 0, 0, 0 }; // Build r2 by following a path of difference vectors that are each presumed to be less than // a half-box apart, in case we are battling periodic boundary conditions along the lines of // a big molecule in a small box. for (size_t i = 0; i < sites_.size() - 1; ++i) { - RVec a = sites_[i].centerOfMass(cr, - static_cast(mdatoms.homenr), - x, - t); - RVec b = sites_[i + 1].centerOfMass(cr, - static_cast(mdatoms.homenr), - x, - t); + RVec a = sites_[i].centerOfMass(cr, static_cast(mdatoms.homenr), x, t); + RVec b = sites_[i + 1].centerOfMass(cr, static_cast(mdatoms.homenr), x, t); // dr = minimum_image_vector(b - a) - pbc_dx(&pbc, - b, - a, - dr); + pbc_dx(&pbc, b, a, dr); r2[0] += dr[0]; r2[1] += dr[1]; r2[2] += dr[2]; @@ -125,9 +111,7 @@ void RestraintForceProvider::calculateForces(const ForceProviderInput &forceProv // time step to avoid extraneous barriers. The code would be prettier with "futures"... if ((cr.dd == nullptr) || MASTER(&cr)) { - restraint_->update(RVec(r1), - r2, - t); + restraint_->update(RVec(r1), r2, t); } // All ranks wait for the update to finish. // tMPI ranks are depending on structures that may have just been updated. @@ -139,16 +123,14 @@ void RestraintForceProvider::calculateForces(const ForceProviderInput &forceProv } // Apply restraint on all thread ranks only after any updates have been made. - auto result = restraint_->evaluate(RVec(r1), - r2, - t); + auto result = restraint_->evaluate(RVec(r1), r2, t); // This can easily be generalized for pair restraints that apply to selections instead of // individual indices, or to restraints that aren't pair restraints. const int site1 = static_cast(sites_.front().index()); const int* aLocal = &site1; // Set forces using index `site1` if no domain decomposition, otherwise set with local index if available. - auto &force = forceProviderOutput->forceWithVirial_.force_; + auto& force = forceProviderOutput->forceWithVirial_.force_; if ((cr.dd == nullptr) || (aLocal = cr.dd->ga2la->findHome(site1))) { force[static_cast(*aLocal)] += result.force; @@ -170,9 +152,8 @@ void RestraintForceProvider::calculateForces(const ForceProviderInput &forceProv RestraintMDModuleImpl::~RestraintMDModuleImpl() = default; RestraintMDModuleImpl::RestraintMDModuleImpl(std::shared_ptr restraint, - const std::vector &sites) : - forceProvider_(std::make_unique(restraint, - sites)) + const std::vector& sites) : + forceProvider_(std::make_unique(restraint, sites)) { GMX_ASSERT(forceProvider_, "Class invariant implies non-null ForceProvider."); } @@ -215,19 +196,17 @@ void RestraintMDModule::initForceProviders(ForceProviders* forceProviders) impl_->initForceProviders(forceProviders); } -std::unique_ptr -RestraintMDModule::create(std::shared_ptr restraint, - const std::vector &sites) +std::unique_ptr RestraintMDModule::create(std::shared_ptr restraint, + const std::vector& sites) { - auto implementation = std::make_unique(std::move(restraint), - sites); - auto newModule = std::make_unique(std::move(implementation)); + auto implementation = std::make_unique(std::move(restraint), sites); + auto newModule = std::make_unique(std::move(implementation)); return newModule; } // private constructor to implement static create() method. RestraintMDModule::RestraintMDModule(std::unique_ptr restraint) : - impl_ {std::move(restraint)} + impl_{ std::move(restraint) } { } diff --git a/src/gromacs/restraint/restraintmdmodule.h b/src/gromacs/restraint/restraintmdmodule.h index d3ae03d78f..c6ec4b5615 100644 --- a/src/gromacs/restraint/restraintmdmodule.h +++ b/src/gromacs/restraint/restraintmdmodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,66 +62,66 @@ class RestraintMDModuleImpl; */ class RestraintMDModule final : public gmx::IMDModule { - public: - RestraintMDModule() = delete; +public: + RestraintMDModule() = delete; - /*! - * \brief Constructor used by static create() method. - */ - explicit RestraintMDModule(std::unique_ptr restraint); + /*! + * \brief Constructor used by static create() method. + */ + explicit RestraintMDModule(std::unique_ptr restraint); - ~RestraintMDModule() override; + ~RestraintMDModule() override; - /*! - * \brief Wrap a restraint potential as an MDModule - * - * \param restraint shared ownership of an object for calculating restraint forces. - * \return new wrapper object sharing ownership of restraint. - * - * Consumers of the interfaces provided by an IMDModule do not extend the lifetime - * of the interface objects returned by mdpOptionProvider(), outputProvider(), or - * registered via initForceProviders(). Calling code must keep this object alive - * as long as those interfaces are needed (probably the duration of an MD run). - * - * \param restraint handle to object to wrap - * \param sites list of sites for the framework to pass to the restraint - */ - static std::unique_ptr - create(std::shared_ptr restraint, const std::vector &sites); + /*! + * \brief Wrap a restraint potential as an MDModule + * + * \param restraint shared ownership of an object for calculating restraint forces. + * \return new wrapper object sharing ownership of restraint. + * + * Consumers of the interfaces provided by an IMDModule do not extend the lifetime + * of the interface objects returned by mdpOptionProvider(), outputProvider(), or + * registered via initForceProviders(). Calling code must keep this object alive + * as long as those interfaces are needed (probably the duration of an MD run). + * + * \param restraint handle to object to wrap + * \param sites list of sites for the framework to pass to the restraint + */ + static std::unique_ptr create(std::shared_ptr restraint, + const std::vector& sites); - /*! - * \brief Implement IMDModule interface - * - * Unused. - * - * \return nullptr. - */ - IMdpOptionProvider *mdpOptionProvider() override; + /*! + * \brief Implement IMDModule interface + * + * Unused. + * + * \return nullptr. + */ + IMdpOptionProvider* mdpOptionProvider() override; - /*! - * \brief Implement IMDModule interface - * - * Unused. - * - * \return nullptr. - */ - IMDOutputProvider *outputProvider() override; + /*! + * \brief Implement IMDModule interface + * + * Unused. + * + * \return nullptr. + */ + IMDOutputProvider* outputProvider() override; - /*! - * \brief Implement IMDModule interface. - * - * See gmx::IMDModule::initForceProviders() - * \param forceProviders manager in the force record. - */ - void initForceProviders(ForceProviders *forceProviders) override; + /*! + * \brief Implement IMDModule interface. + * + * See gmx::IMDModule::initForceProviders() + * \param forceProviders manager in the force record. + */ + void initForceProviders(ForceProviders* forceProviders) override; - private: - /*! - * \brief Private implementation opaque pointer. - */ - std::unique_ptr impl_; +private: + /*! + * \brief Private implementation opaque pointer. + */ + std::unique_ptr impl_; }; -} // end namespace gmx +} // end namespace gmx -#endif //GROMACS_RESTRAINTMDMODULE_H +#endif // GROMACS_RESTRAINTMDMODULE_H diff --git a/src/gromacs/restraint/restraintmdmodule_impl.h b/src/gromacs/restraint/restraintmdmodule_impl.h index 3895c3c19b..b1a62a9d69 100644 --- a/src/gromacs/restraint/restraintmdmodule_impl.h +++ b/src/gromacs/restraint/restraintmdmodule_impl.h @@ -80,127 +80,120 @@ namespace gmx */ class Site { - public: - /*! \brief Construct from global atom indices - * - * \param globalIndex Atom index in the global state (as input to the simulation) - */ - explicit Site(int globalIndex) : - index_(globalIndex), - r_(0, 0, 0) - {} +public: + /*! \brief Construct from global atom indices + * + * \param globalIndex Atom index in the global state (as input to the simulation) + */ + explicit Site(int globalIndex) : index_(globalIndex), r_(0, 0, 0) {} - /*! - * \brief Explicitly define copies. - * - * Implicit definition is not possible because of the mutex member, - * and a copy constructor is necessary to use Site in a std::vector. Really, we should make - * a copy point to the same implementation object to reuse its cache. + /*! + * \brief Explicitly define copies. + * + * Implicit definition is not possible because of the mutex member, + * and a copy constructor is necessary to use Site in a std::vector. Really, we should make + * a copy point to the same implementation object to reuse its cache. - */ - Site(const Site &site) : - index_(site.index_), - r_(site.r_) - {} + */ + Site(const Site& site) : index_(site.index_), r_(site.r_) {} - /*! \brief Disallow assignment. - * - * Assignment doesn't make sense because it implies that a site's meaning is fuzzy. - * If the definition of a site is changing, just make a new site. - * There's nothing to be gained by reusing one or by creating it uninitialized. - */ - Site &operator=(const Site &) = delete; + /*! \brief Disallow assignment. + * + * Assignment doesn't make sense because it implies that a site's meaning is fuzzy. + * If the definition of a site is changing, just make a new site. + * There's nothing to be gained by reusing one or by creating it uninitialized. + */ + Site& operator=(const Site&) = delete; - /*! - * \brief Get the global atom index of an atomic site. - * - * \return global index provided at construction. - * - */ - int index() const { return index_; } + /*! + * \brief Get the global atom index of an atomic site. + * + * \return global index provided at construction. + * + */ + int index() const { return index_; } - /*! - * \brief Get the position of this site at time t. - * - * \param cr Communications record. - * \param nx Number of locally available atoms (size of local atom data arrays) - * \param x Array of locally available atom coordinates. - * \param t the current time. - * \return position vector. - * - * \internal - * By providing the current time, we can cache results in order to use them once per timestep. - * In the long term, we would prefer to also allow client code to preregister interest in a - * position at a given time, or issue "futures". - */ - RVec centerOfMass(const t_commrec &cr, - size_t nx, - ArrayRef x, - double gmx_unused t) + /*! + * \brief Get the position of this site at time t. + * + * \param cr Communications record. + * \param nx Number of locally available atoms (size of local atom data arrays) + * \param x Array of locally available atom coordinates. + * \param t the current time. + * \return position vector. + * + * \internal + * By providing the current time, we can cache results in order to use them once per timestep. + * In the long term, we would prefer to also allow client code to preregister interest in a + * position at a given time, or issue "futures". + */ + RVec centerOfMass(const t_commrec& cr, size_t nx, ArrayRef x, double gmx_unused t) + { + // Center of mass to return for the site. Currently the only form of site + // implemented is as a global atomic coordinate. + gmx::RVec r = { 0, 0, 0 }; + if (DOMAINDECOMP(&cr)) // Domain decomposition { - // Center of mass to return for the site. Currently the only form of site - // implemented is as a global atomic coordinate. - gmx::RVec r = {0, 0, 0}; - if (DOMAINDECOMP(&cr)) // Domain decomposition + // Get global-to-local indexing structure + auto crossRef = cr.dd->ga2la; + GMX_ASSERT(crossRef, "Domain decomposition must provide global/local cross-reference."); + if (const auto localIndex = crossRef->findHome(index_)) { - // Get global-to-local indexing structure - auto crossRef = cr.dd->ga2la; - GMX_ASSERT(crossRef, "Domain decomposition must provide global/local cross-reference."); - if (const auto localIndex = crossRef->findHome(index_)) - { - GMX_ASSERT(localIndex, "Expect not to reach this point if findHome does not find index_."); - GMX_ASSERT(*localIndex < static_cast(nx), - "We assume that the local index cannot be larger than the number of atoms."); - GMX_ASSERT(*localIndex >= 0, "localIndex is a signed type, but is assumed >0."); - // If atom is local, get its location - copy_rvec(x[*localIndex], r); - } - else - { - // Nothing to contribute on this rank. Leave position == [0,0,0]. - } - // AllReduce across the ranks of the simulation to get the center-of-mass - // of the site locally available everywhere. For single-atom sites, this - // is trivial: exactly one rank should have a non-zero position. - // For future multi-atom selections, - // we will receive weighted center-of-mass contributions from - // each rank and combine to get the global center of mass. - // \todo use generalized "pull group" facility when available. - std::array buffer {{r[0], r[1], r[2]}}; - // This should be an all-reduce sum, which gmx_sumd appears to be. - gmx_sumd(3, buffer.data(), &cr); - r[0] = static_cast(buffer[0]); - r[1] = static_cast(buffer[1]); - r[2] = static_cast(buffer[2]); - - } // end domain decomposition branch + GMX_ASSERT(localIndex, + "Expect not to reach this point if findHome does not find index_."); + GMX_ASSERT(*localIndex < static_cast(nx), + "We assume that the local index cannot be larger than the number of " + "atoms."); + GMX_ASSERT(*localIndex >= 0, "localIndex is a signed type, but is assumed >0."); + // If atom is local, get its location + copy_rvec(x[*localIndex], r); + } else { - // No DD so all atoms are local. - copy_rvec(x[index_], r); - (void)nx; + // Nothing to contribute on this rank. Leave position == [0,0,0]. } - // Update cache and cache status. - copy_rvec(r, r_); + // AllReduce across the ranks of the simulation to get the center-of-mass + // of the site locally available everywhere. For single-atom sites, this + // is trivial: exactly one rank should have a non-zero position. + // For future multi-atom selections, + // we will receive weighted center-of-mass contributions from + // each rank and combine to get the global center of mass. + // \todo use generalized "pull group" facility when available. + std::array buffer{ { r[0], r[1], r[2] } }; + // This should be an all-reduce sum, which gmx_sumd appears to be. + gmx_sumd(3, buffer.data(), &cr); + r[0] = static_cast(buffer[0]); + r[1] = static_cast(buffer[1]); + r[2] = static_cast(buffer[2]); - return r_; + } // end domain decomposition branch + else + { + // No DD so all atoms are local. + copy_rvec(x[index_], r); + (void)nx; } + // Update cache and cache status. + copy_rvec(r, r_); - private: - /*! - * \brief Global index of the single-atom site. - * - * \todo This class should be a specialization of a more general Site data source. - * \todo use LocalAtomSet - */ - const int index_; + return r_; + } - /*! - * \brief Last known value of the center-of-mass. - * - * Updated with centerOfMass(). - */ - RVec r_; +private: + /*! + * \brief Global index of the single-atom site. + * + * \todo This class should be a specialization of a more general Site data source. + * \todo use LocalAtomSet + */ + const int index_; + + /*! + * \brief Last known value of the center-of-mass. + * + * Updated with centerOfMass(). + */ + RVec r_; }; /*! \internal @@ -208,62 +201,62 @@ class Site * * Adapter class from IForceProvider to IRestraintPotential. * Objects of this type are uniquely owned by instances of RestraintMDModuleImpl. The object will - * dispatch calls to IForceProvider->calculateForces() to the functor managed by RestraintMDModuleImpl. - * \ingroup module_restraint + * dispatch calls to IForceProvider->calculateForces() to the functor managed by + * RestraintMDModuleImpl. \ingroup module_restraint */ class RestraintForceProvider final : public gmx::IForceProvider { - public: - /*! - * \brief Can only be constructed when initialized from a restraint. - */ - RestraintForceProvider() = delete; +public: + /*! + * \brief Can only be constructed when initialized from a restraint. + */ + RestraintForceProvider() = delete; - ~RestraintForceProvider() = default; + ~RestraintForceProvider() = default; - /*! - * \brief RAII construction with an IRestraintPotential - * - * Note, this object must outlive the pointer that will be provided to ForceProviders. - * \param restraint handle to an object providing restraint potential calculation - * \param sites List of atomic site indices - */ - explicit RestraintForceProvider(std::shared_ptr restraint, - const std::vector &sites); + /*! + * \brief RAII construction with an IRestraintPotential + * + * Note, this object must outlive the pointer that will be provided to ForceProviders. + * \param restraint handle to an object providing restraint potential calculation + * \param sites List of atomic site indices + */ + explicit RestraintForceProvider(std::shared_ptr restraint, + const std::vector& sites); - /*! - * \brief Implement the IForceProvider interface. - * - * Update the force array with restraint contribution(s) for local atoms. - * - * RestraintForceProvider is implemented with the assumption that few - * restraints apply to many atoms. - * That is, the number of restraints affecting a large number of atoms is small, - * though there may be several restraints that apply to few atoms each. - * Under this assumption, it is considered computationally inexpensive to iterate - * over restraints in an outer loop and iterate over atoms within each restraint. - * This would be an invalid assumption if, say, several restraints applied - * to an entire membrane or the entire solvent group. - * - * If the assumption causes performance problems, we can look for a good - * way to reduce from several restraints in a single pass or a very - * lightweight way to determine whether a given restraint applies to a given atom. - * There is also the notion in the pulling code of a limited number of - * "pull groups" used by the "pull coordinates". - * The right optimization will depend on how the code is being used. - * - * Call the evaluator(s) for the restraints for the configured sites. - * Forces are applied to atoms in the first and last site listed. - * Intermediate sites are used as reference coordinates when the relevant - * vector between sites is on the order of half a box length or otherwise - * ambiguous in the case of periodic boundary conditions. - */ - void calculateForces(const ForceProviderInput &forceProviderInput, - ForceProviderOutput *forceProviderOutput) override; + /*! + * \brief Implement the IForceProvider interface. + * + * Update the force array with restraint contribution(s) for local atoms. + * + * RestraintForceProvider is implemented with the assumption that few + * restraints apply to many atoms. + * That is, the number of restraints affecting a large number of atoms is small, + * though there may be several restraints that apply to few atoms each. + * Under this assumption, it is considered computationally inexpensive to iterate + * over restraints in an outer loop and iterate over atoms within each restraint. + * This would be an invalid assumption if, say, several restraints applied + * to an entire membrane or the entire solvent group. + * + * If the assumption causes performance problems, we can look for a good + * way to reduce from several restraints in a single pass or a very + * lightweight way to determine whether a given restraint applies to a given atom. + * There is also the notion in the pulling code of a limited number of + * "pull groups" used by the "pull coordinates". + * The right optimization will depend on how the code is being used. + * + * Call the evaluator(s) for the restraints for the configured sites. + * Forces are applied to atoms in the first and last site listed. + * Intermediate sites are used as reference coordinates when the relevant + * vector between sites is on the order of half a box length or otherwise + * ambiguous in the case of periodic boundary conditions. + */ + void calculateForces(const ForceProviderInput& forceProviderInput, + ForceProviderOutput* forceProviderOutput) override; - private: - std::shared_ptr restraint_; - std::vector sites_; +private: + std::shared_ptr restraint_; + std::vector sites_; }; /*! \internal @@ -275,52 +268,52 @@ class RestraintForceProvider final : public gmx::IForceProvider */ class RestraintMDModuleImpl final { - public: - RestraintMDModuleImpl() = delete; - /*! - * \brief Wrap an object implementing IRestraintPotential - * - * \param restraint handle to restraint to wrap. - * \param sites list of sites for framework to process for restraint force calculator. - */ - RestraintMDModuleImpl(std::shared_ptr restraint, - const std::vector&sites); +public: + RestraintMDModuleImpl() = delete; + /*! + * \brief Wrap an object implementing IRestraintPotential + * + * \param restraint handle to restraint to wrap. + * \param sites list of sites for framework to process for restraint force calculator. + */ + RestraintMDModuleImpl(std::shared_ptr restraint, + const std::vector& sites); - /*! - * \brief Allow moves. - * - * \{ - */ - RestraintMDModuleImpl(RestraintMDModuleImpl &&) noexcept = default; - RestraintMDModuleImpl &operator=(RestraintMDModuleImpl &&) noexcept = default; - /*! \} */ + /*! + * \brief Allow moves. + * + * \{ + */ + RestraintMDModuleImpl(RestraintMDModuleImpl&&) noexcept = default; + RestraintMDModuleImpl& operator=(RestraintMDModuleImpl&&) noexcept = default; + /*! \} */ - ~RestraintMDModuleImpl(); + ~RestraintMDModuleImpl(); - /*! - * \brief Unused implementation of IMDModule aspect - */ - IMdpOptionProvider *mdpOptionProvider(); + /*! + * \brief Unused implementation of IMDModule aspect + */ + IMdpOptionProvider* mdpOptionProvider(); - /*! - * \brief Unused implementation of IMDModule aspect - */ - IMDOutputProvider *outputProvider(); + /*! + * \brief Unused implementation of IMDModule aspect + */ + IMDOutputProvider* outputProvider(); - /*! - * \brief Implement IMDModule interface. - * - * \param forceProviders force module manager in the force record that will call this. - * - * The calling code must ensure that this object stays alive as long as forceProviders needs - * the RestraintForceProvider, since forceProviders can't. Typically that is the duration of a do_md() call. - */ - void initForceProviders(ForceProviders *forceProviders); + /*! + * \brief Implement IMDModule interface. + * + * \param forceProviders force module manager in the force record that will call this. + * + * The calling code must ensure that this object stays alive as long as forceProviders needs + * the RestraintForceProvider, since forceProviders can't. Typically that is the duration of a do_md() call. + */ + void initForceProviders(ForceProviders* forceProviders); - //! handle to RestraintForceProvider implementation - std::unique_ptr forceProvider_; + //! handle to RestraintForceProvider implementation + std::unique_ptr forceProvider_; }; -} // end namespace gmx +} // end namespace gmx -#endif //GROMACS_RESTRAINTMDMODULE_IMPL_H +#endif // GROMACS_RESTRAINTMDMODULE_IMPL_H diff --git a/src/gromacs/restraint/restraintpotential.h b/src/gromacs/restraint/restraintpotential.h index eb6ababd80..72bf0dbe71 100644 --- a/src/gromacs/restraint/restraintpotential.h +++ b/src/gromacs/restraint/restraintpotential.h @@ -88,39 +88,32 @@ using Vector = ::gmx::RVec; */ class PotentialPointData { - public: - - - /*! - * \brief Initialize a new data structure. - */ - PotentialPointData() : - PotentialPointData {Vector(0., 0., 0.), real(0.0)} - {} - - /*! - * \brief Initialize from an argument list - * - * \param f Force vector. - * \param e Energy value. - * - * Note that if force was calculated as a scalar, it needs to be multiplied by a unit - * vector in the direction to which it should be applied. - */ - PotentialPointData(const Vector &f, const real e) : - force(f), - energy(e) - {} - - /*! - * \brief Force vector calculated for first position. - */ - Vector force; - - /*! - * \brief Potential energy calculated for this interaction. - */ - real energy; +public: + /*! + * \brief Initialize a new data structure. + */ + PotentialPointData() : PotentialPointData{ Vector(0., 0., 0.), real(0.0) } {} + + /*! + * \brief Initialize from an argument list + * + * \param f Force vector. + * \param e Energy value. + * + * Note that if force was calculated as a scalar, it needs to be multiplied by a unit + * vector in the direction to which it should be applied. + */ + PotentialPointData(const Vector& f, const real e) : force(f), energy(e) {} + + /*! + * \brief Force vector calculated for first position. + */ + Vector force; + + /*! + * \brief Potential energy calculated for this interaction. + */ + real energy; }; /*! @@ -153,84 +146,80 @@ class PotentialPointData * are specified by the user and then, during integration, GROMACS provides * the current positions of each pair for the restraint potential to be evaluated. * In such a case, the potential can be implemented by overriding evaluate(). - * \todo Template headers can help to build compatible calculation methods with different input requirements. - * For reference, see https://github.com/kassonlab/sample_restraint + * \todo Template headers can help to build compatible calculation methods with different input + * requirements. For reference, see https://github.com/kassonlab/sample_restraint * * \ingroup module_restraint */ class IRestraintPotential { - public: - virtual ~IRestraintPotential() = default; - - /*! - * \brief Calculate a force vector according to two input positions at a given time. - * - * If not overridden by derived class, returns a zero vector. - * \param r1 position of first site - * \param r2 position of second site - * \param t simulation time in picoseconds - * \return force vector and potential energy to be applied by calling code. - * - * \todo The virtual function call should be replaced by a (table of) function objects retrieved before the run. - */ - virtual PotentialPointData evaluate(Vector r1, - Vector r2, - double t) = 0; - - - /*! - * \brief Call-back hook for restraint implementations. - * - * An update function to be called on the simulation master rank/thread periodically - * by the Restraint framework. - * Receives the same input as the evaluate() method, but is only called on the master - * rank of a simulation to allow implementation code to be thread-safe without knowing - * anything about the domain decomposition. - * - * \param v position of the first site - * \param v0 position of the second site - * \param t simulation time - * - * \internal - * We give the definition here because we don't want plugins to have to link against - * libgromacs right now (complicated header maintenance and no API stability guarantees). - * But once we've had plugin restraints wrap themselves in a Restraint template, - * we can set update = 0 - * - * \todo: Provide gmxapi facility for plugin restraints to wrap themselves - * with a default implementation to let this class be pure virtual. - */ - virtual void update(gmx::Vector v, - gmx::Vector v0, - double t) - { - (void)v; - (void)v0; - (void)t; - } - - - /*! - * \brief Find out what sites this restraint is configured to act on. - * \return - */ - virtual std::vector sites() const = 0; - - /*! - * \brief Allow Session-mediated interaction with other resources or workflow elements. - * - * \param resources temporary access to the resources provided by the session for additional configuration. - * - * A module implements this method to receive a handle to resources configured for this particular workflow - * element. - * - * \internal - * \todo This should be more general than the RestraintPotential interface. - */ - virtual void bindSession(gmxapi::SessionResources* resources) { (void)resources; } +public: + virtual ~IRestraintPotential() = default; + + /*! + * \brief Calculate a force vector according to two input positions at a given time. + * + * If not overridden by derived class, returns a zero vector. + * \param r1 position of first site + * \param r2 position of second site + * \param t simulation time in picoseconds + * \return force vector and potential energy to be applied by calling code. + * + * \todo The virtual function call should be replaced by a (table of) function objects retrieved before the run. + */ + virtual PotentialPointData evaluate(Vector r1, Vector r2, double t) = 0; + + + /*! + * \brief Call-back hook for restraint implementations. + * + * An update function to be called on the simulation master rank/thread periodically + * by the Restraint framework. + * Receives the same input as the evaluate() method, but is only called on the master + * rank of a simulation to allow implementation code to be thread-safe without knowing + * anything about the domain decomposition. + * + * \param v position of the first site + * \param v0 position of the second site + * \param t simulation time + * + * \internal + * We give the definition here because we don't want plugins to have to link against + * libgromacs right now (complicated header maintenance and no API stability guarantees). + * But once we've had plugin restraints wrap themselves in a Restraint template, + * we can set update = 0 + * + * \todo: Provide gmxapi facility for plugin restraints to wrap themselves + * with a default implementation to let this class be pure virtual. + */ + virtual void update(gmx::Vector v, gmx::Vector v0, double t) + { + (void)v; + (void)v0; + (void)t; + } + + + /*! + * \brief Find out what sites this restraint is configured to act on. + * \return + */ + virtual std::vector sites() const = 0; + + /*! + * \brief Allow Session-mediated interaction with other resources or workflow elements. + * + * \param resources temporary access to the resources provided by the session for additional configuration. + * + * A module implements this method to receive a handle to resources configured for this particular workflow + * element. + * + * \internal + * \todo This should be more general than the RestraintPotential interface. + */ + virtual void bindSession(gmxapi::SessionResources* resources) { (void)resources; } }; -} // end namespace gmx +} // end namespace gmx -#endif //GMX_PULLING_PULLPOTENTIAL_H +#endif // GMX_PULLING_PULLPOTENTIAL_H diff --git a/src/gromacs/restraint/tests/manager.cpp b/src/gromacs/restraint/tests/manager.cpp index f37ba9aa22..1596a25be0 100644 --- a/src/gromacs/restraint/tests/manager.cpp +++ b/src/gromacs/restraint/tests/manager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,30 +44,23 @@ namespace class DummyRestraint : public gmx::IRestraintPotential { - public: - ~DummyRestraint() override = default; +public: + ~DummyRestraint() override = default; - gmx::PotentialPointData evaluate(gmx::Vector gmx_unused r1, - gmx::Vector gmx_unused r2, - double gmx_unused t) override - { - return {}; - } + gmx::PotentialPointData evaluate(gmx::Vector gmx_unused r1, + gmx::Vector gmx_unused r2, + double gmx_unused t) override + { + return {}; + } - void update(gmx::Vector gmx_unused v, - gmx::Vector gmx_unused v0, - double gmx_unused t) override - {} + void update(gmx::Vector gmx_unused v, gmx::Vector gmx_unused v0, double gmx_unused t) override + { + } - std::vector sites() const override - { - return std::vector(); - } + std::vector sites() const override { return std::vector(); } - void bindSession(gmxapi::SessionResources *session) override - { - (void)session; - } + void bindSession(gmxapi::SessionResources* session) override { (void)session; } }; TEST(RestraintManager, restraintList) diff --git a/src/gromacs/selection/centerofmass.cpp b/src/gromacs/selection/centerofmass.cpp index 8465459017..356482ccd1 100644 --- a/src/gromacs/selection/centerofmass.cpp +++ b/src/gromacs/selection/centerofmass.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +53,9 @@ #include "gromacs/topology/topology.h" #include "gromacs/utility/gmxassert.h" -void -gmx_calc_cog(const gmx_mtop_t * /* top */, rvec x[], int nrefat, const int index[], rvec xout) +void gmx_calc_cog(const gmx_mtop_t* /* top */, rvec x[], int nrefat, const int index[], rvec xout) { - int m, ai; + int m, ai; clear_rvec(xout); for (m = 0; m < nrefat; ++m) @@ -63,7 +63,7 @@ gmx_calc_cog(const gmx_mtop_t * /* top */, rvec x[], int nrefat, const int index ai = index[m]; rvec_inc(xout, x[ai]); } - svmul(1.0/nrefat, xout, xout); + svmul(1.0 / nrefat, xout, xout); } /*! @@ -76,8 +76,7 @@ gmx_calc_cog(const gmx_mtop_t * /* top */, rvec x[], int nrefat, const int index * Works exactly as gmx_calc_cog() with the exception that a center of * mass are calculated, and hence a topology with masses is required. */ -void -gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout) +void gmx_calc_com(const gmx_mtop_t* top, rvec x[], int nrefat, const int index[], rvec xout) { GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top), "No masses available while mass weighting was requested"); @@ -94,7 +93,7 @@ gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rve } mtot += mass; } - svmul(1.0/mtot, xout, xout); + svmul(1.0 / mtot, xout, xout); } /*! @@ -104,8 +103,7 @@ gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rve * \param[in] index Indices of atoms. * \param[out] fout Force on the COG position for the indexed atoms. */ -void -gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout) +void gmx_calc_cog_f(const gmx_mtop_t* top, rvec f[], int nrefat, const int index[], rvec fout) { GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top), "No masses available while mass weighting was requested"); @@ -125,8 +123,7 @@ gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], r svmul(mtot / nrefat, fout, fout); } -void -gmx_calc_com_f(const gmx_mtop_t * /* top */, rvec f[], int nrefat, const int index[], rvec fout) +void gmx_calc_com_f(const gmx_mtop_t* /* top */, rvec f[], int nrefat, const int index[], rvec fout) { clear_rvec(fout); for (int m = 0; m < nrefat; ++m) @@ -149,9 +146,7 @@ gmx_calc_com_f(const gmx_mtop_t * /* top */, rvec f[], int nrefat, const int ind * \p bMass. * Other parameters are passed unmodified to these functions. */ -void -gmx_calc_comg(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], - bool bMass, rvec xout) +void gmx_calc_comg(const gmx_mtop_t* top, rvec x[], int nrefat, const int index[], bool bMass, rvec xout) { if (bMass) { @@ -176,9 +171,7 @@ gmx_calc_comg(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], * \p bMass. * Other parameters are passed unmodified to these functions. */ -void -gmx_calc_comg_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], - bool bMass, rvec fout) +void gmx_calc_comg_f(const gmx_mtop_t* top, rvec f[], int nrefat, const int index[], bool bMass, rvec fout) { if (bMass) { @@ -201,14 +194,12 @@ gmx_calc_comg_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], * * Works exactly as gmx_calc_com_pbc(), but calculates the center of geometry. */ -void -gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], rvec xout) +void gmx_calc_cog_pbc(const gmx_mtop_t* top, rvec x[], const t_pbc* pbc, int nrefat, const int index[], rvec xout) { - const real tol = 1e-4; - bool bChanged; - int m, j, ai, iter; - rvec dx, xtest; + const real tol = 1e-4; + bool bChanged; + int m, j, ai, iter; + rvec dx, xtest; /* First simple calculation */ gmx_calc_cog(top, x, nrefat, index, xout); @@ -236,8 +227,7 @@ gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, } } iter++; - } - while (bChanged); + } while (bChanged); } } @@ -256,9 +246,7 @@ gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, * * Modified from src/tools/gmx_sorient.c in Gromacs distribution. */ -void -gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], rvec xout) +void gmx_calc_com_pbc(const gmx_mtop_t* top, rvec x[], const t_pbc* pbc, int nrefat, const int index[], rvec xout) { GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top), "No masses available while mass weighting was requested"); @@ -276,11 +264,11 @@ gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, } mtot += mass; } - svmul(1.0/mtot, xout, xout); + svmul(1.0 / mtot, xout, xout); /* Now check if any atom is more than half the box from the COM */ if (pbc) { - const real tol = 1e-4; + const real tol = 1e-4; bool bChanged; do { @@ -304,8 +292,7 @@ gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, } } } - } - while (bChanged); + } while (bChanged); } } @@ -323,9 +310,7 @@ gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, * \p bMass. * Other parameters are passed unmodified to these functions. */ -void -gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], bool bMass, rvec xout) +void gmx_calc_comg_pbc(const gmx_mtop_t* top, rvec x[], const t_pbc* pbc, int nrefat, const int index[], bool bMass, rvec xout) { if (bMass) { @@ -338,22 +323,20 @@ gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, } -void -gmx_calc_cog_block(const gmx_mtop_t * /* top */, rvec x[], const t_block *block, const int index[], - rvec xout[]) +void gmx_calc_cog_block(const gmx_mtop_t* /* top */, rvec x[], const t_block* block, const int index[], rvec xout[]) { - int b, i, ai; - rvec xb; + int b, i, ai; + rvec xb; for (b = 0; b < block->nr; ++b) { clear_rvec(xb); - for (i = block->index[b]; i < block->index[b+1]; ++i) + for (i = block->index[b]; i < block->index[b + 1]; ++i) { ai = index[i]; rvec_inc(xb, x[ai]); } - svmul(1.0/(block->index[b+1] - block->index[b]), xb, xout[b]); + svmul(1.0 / (block->index[b + 1] - block->index[b]), xb, xout[b]); } } @@ -367,9 +350,7 @@ gmx_calc_cog_block(const gmx_mtop_t * /* top */, rvec x[], const t_block *block, * Works exactly as gmx_calc_cog_block() with the exception that centers of * mass are calculated, and hence a topology with masses is required. */ -void -gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const int index[], - rvec xout[]) +void gmx_calc_com_block(const gmx_mtop_t* top, rvec x[], const t_block* block, const int index[], rvec xout[]) { GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top), "No masses available while mass weighting was requested"); @@ -379,7 +360,7 @@ gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const rvec xb; clear_rvec(xb); real mtot = 0; - for (int i = block->index[b]; i < block->index[b+1]; ++i) + for (int i = block->index[b]; i < block->index[b + 1]; ++i) { const int ai = index[i]; const real mass = mtopGetAtomMass(top, ai, &molb); @@ -389,7 +370,7 @@ gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const } mtot += mass; } - svmul(1.0/mtot, xb, xout[b]); + svmul(1.0 / mtot, xb, xout[b]); } } @@ -400,9 +381,7 @@ gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const * \param[in] index Indices of atoms. * \param[out] fout \p block->nr Forces on COG positions. */ -void -gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, const int index[], - rvec fout[]) +void gmx_calc_cog_f_block(const gmx_mtop_t* top, rvec f[], const t_block* block, const int index[], rvec fout[]) { GMX_RELEASE_ASSERT(gmx_mtop_has_masses(top), "No masses available while mass weighting was requested"); @@ -412,7 +391,7 @@ gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, cons rvec fb; clear_rvec(fb); real mtot = 0; - for (int i = block->index[b]; i < block->index[b+1]; ++i) + for (int i = block->index[b]; i < block->index[b + 1]; ++i) { const int ai = index[i]; const real mass = mtopGetAtomMass(top, ai, &molb); @@ -422,19 +401,21 @@ gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, cons } mtot += mass; } - svmul(mtot / (block->index[b+1] - block->index[b]), fb, fout[b]); + svmul(mtot / (block->index[b + 1] - block->index[b]), fb, fout[b]); } } -void -gmx_calc_com_f_block(const gmx_mtop_t * /* top */, rvec f[], const t_block *block, const int index[], - rvec fout[]) +void gmx_calc_com_f_block(const gmx_mtop_t* /* top */, + rvec f[], + const t_block* block, + const int index[], + rvec fout[]) { for (int b = 0; b < block->nr; ++b) { rvec fb; clear_rvec(fb); - for (int i = block->index[b]; i < block->index[b+1]; ++i) + for (int i = block->index[b]; i < block->index[b + 1]; ++i) { const int ai = index[i]; rvec_inc(fb, f[ai]); @@ -456,9 +437,12 @@ gmx_calc_com_f_block(const gmx_mtop_t * /* top */, rvec f[], const t_block *bloc * value of \p bMass. * Other parameters are passed unmodified to these functions. */ -void -gmx_calc_comg_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const int index[], - bool bMass, rvec xout[]) +void gmx_calc_comg_block(const gmx_mtop_t* top, + rvec x[], + const t_block* block, + const int index[], + bool bMass, + rvec xout[]) { if (bMass) { @@ -483,9 +467,12 @@ gmx_calc_comg_block(const gmx_mtop_t *top, rvec x[], const t_block *block, const * the value of \p bMass. * Other parameters are passed unmodified to these functions. */ -void -gmx_calc_comg_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, const int index[], - bool bMass, rvec fout[]) +void gmx_calc_comg_f_block(const gmx_mtop_t* top, + rvec f[], + const t_block* block, + const int index[], + bool bMass, + rvec fout[]) { if (bMass) { @@ -515,12 +502,10 @@ gmx_calc_comg_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, con * but if the layout of these structures is changed, this may lead to strange * crashes. */ -void -gmx_calc_comg_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block, - bool bMass, rvec xout[]) +void gmx_calc_comg_blocka(const gmx_mtop_t* top, rvec x[], const t_blocka* block, bool bMass, rvec xout[]) { /* TODO: It would probably be better to do this without the type cast */ - gmx_calc_comg_block(top, x, reinterpret_cast(block), block->a, bMass, xout); + gmx_calc_comg_block(top, x, reinterpret_cast(block), block->a, bMass, xout); } /*! @@ -541,10 +526,8 @@ gmx_calc_comg_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block, * but if the layout of these structures is changed, this may lead to strange * crashes. */ -void -gmx_calc_comg_f_blocka(const gmx_mtop_t *top, rvec f[], const t_blocka *block, - bool bMass, rvec fout[]) +void gmx_calc_comg_f_blocka(const gmx_mtop_t* top, rvec f[], const t_blocka* block, bool bMass, rvec fout[]) { /* TODO: It would probably be better to do this without the type cast */ - gmx_calc_comg_f_block(top, f, reinterpret_cast(block), block->a, bMass, fout); + gmx_calc_comg_f_block(top, f, reinterpret_cast(block), block->a, bMass, fout); } diff --git a/src/gromacs/selection/centerofmass.h b/src/gromacs/selection/centerofmass.h index 12b92b4b92..e44c864675 100644 --- a/src/gromacs/selection/centerofmass.h +++ b/src/gromacs/selection/centerofmass.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -90,14 +90,11 @@ struct t_pbc; * \param[in] index Indices of atoms. * \param[out] xout COG position for the indexed atoms. */ -void -gmx_calc_cog(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout); +void gmx_calc_cog(const gmx_mtop_t* top, rvec x[], int nrefat, const int index[], rvec xout); /** Calculate a single center of mass. */ -void -gmx_calc_com(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], rvec xout); +void gmx_calc_com(const gmx_mtop_t* top, rvec x[], int nrefat, const int index[], rvec xout); /** Calculate force on a single center of geometry. */ -void -gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout); +void gmx_calc_cog_f(const gmx_mtop_t* top, rvec f[], int nrefat, const int index[], rvec fout); /*! \brief * Calculate force on a single center of mass. * @@ -107,29 +104,24 @@ gmx_calc_cog_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], r * \param[in] index Indices of atoms. * \param[out] fout Force on the COM position for the indexed atoms. */ -void -gmx_calc_com_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], rvec fout); +void gmx_calc_com_f(const gmx_mtop_t* top, rvec f[], int nrefat, const int index[], rvec fout); /** Calculate a single center of mass/geometry. */ -void -gmx_calc_comg(const gmx_mtop_t *top, rvec x[], int nrefat, const int index[], - bool bMass, rvec xout); +void gmx_calc_comg(const gmx_mtop_t* top, rvec x[], int nrefat, const int index[], bool bMass, rvec xout); /** Calculate force on a single center of mass/geometry. */ -void -gmx_calc_comg_f(const gmx_mtop_t *top, rvec f[], int nrefat, const int index[], - bool bMass, rvec fout); +void gmx_calc_comg_f(const gmx_mtop_t* top, rvec f[], int nrefat, const int index[], bool bMass, rvec fout); /** Calculate a single center of geometry iteratively, taking PBC into account. */ -void -gmx_calc_cog_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], rvec xout); +void gmx_calc_cog_pbc(const gmx_mtop_t* top, rvec x[], const t_pbc* pbc, int nrefat, const int index[], rvec xout); /** Calculate a single center of mass iteratively, taking PBC into account. */ -void -gmx_calc_com_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], rvec xout); +void gmx_calc_com_pbc(const gmx_mtop_t* top, rvec x[], const t_pbc* pbc, int nrefat, const int index[], rvec xout); /** Calculate a single center of mass/geometry iteratively with PBC. */ -void -gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, - int nrefat, const int index[], bool bMass, rvec xout); +void gmx_calc_comg_pbc(const gmx_mtop_t* top, + rvec x[], + const t_pbc* pbc, + int nrefat, + const int index[], + bool bMass, + rvec xout); /*! \brief * Calculate centers of geometry for a blocked index. @@ -140,17 +132,11 @@ gmx_calc_comg_pbc(const gmx_mtop_t *top, rvec x[], const t_pbc *pbc, * \param[in] index Indices of atoms. * \param[out] xout \p block->nr COG positions. */ -void -gmx_calc_cog_block(const gmx_mtop_t *top, rvec x[], const t_block *block, - const int index[], rvec xout[]); +void gmx_calc_cog_block(const gmx_mtop_t* top, rvec x[], const t_block* block, const int index[], rvec xout[]); /** Calculate centers of mass for a blocked index. */ -void -gmx_calc_com_block(const gmx_mtop_t *top, rvec x[], const t_block *block, - const int index[], rvec xout[]); +void gmx_calc_com_block(const gmx_mtop_t* top, rvec x[], const t_block* block, const int index[], rvec xout[]); /** Calculate forces on centers of geometry for a blocked index. */ -void -gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, - const int index[], rvec fout[]); +void gmx_calc_cog_f_block(const gmx_mtop_t* top, rvec f[], const t_block* block, const int index[], rvec fout[]); /*! \brief * Calculate forces on centers of mass for a blocked index. * @@ -160,24 +146,24 @@ gmx_calc_cog_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, * \param[in] index Indices of atoms. * \param[out] fout \p block->nr Forces on COM positions. */ -void -gmx_calc_com_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, - const int index[], rvec fout[]); +void gmx_calc_com_f_block(const gmx_mtop_t* top, rvec f[], const t_block* block, const int index[], rvec fout[]); /** Calculate centers of mass/geometry for a blocked index. */ -void -gmx_calc_comg_block(const gmx_mtop_t *top, rvec x[], const t_block *block, - const int index[], bool bMass, rvec xout[]); +void gmx_calc_comg_block(const gmx_mtop_t* top, + rvec x[], + const t_block* block, + const int index[], + bool bMass, + rvec xout[]); /** Calculate forces on centers of mass/geometry for a blocked index. */ -void -gmx_calc_comg_f_block(const gmx_mtop_t *top, rvec f[], const t_block *block, - const int index[], bool bMass, rvec fout[]); +void gmx_calc_comg_f_block(const gmx_mtop_t* top, + rvec f[], + const t_block* block, + const int index[], + bool bMass, + rvec fout[]); /** Calculate centers of mass/geometry for a set of blocks; */ -void -gmx_calc_comg_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block, - bool bMass, rvec xout[]); +void gmx_calc_comg_blocka(const gmx_mtop_t* top, rvec x[], const t_blocka* block, bool bMass, rvec xout[]); /** Calculate forces on centers of mass/geometry for a set of blocks; */ -void -gmx_calc_comg_f_blocka(const gmx_mtop_t *top, rvec x[], const t_blocka *block, - bool bMass, rvec xout[]); +void gmx_calc_comg_f_blocka(const gmx_mtop_t* top, rvec x[], const t_blocka* block, bool bMass, rvec xout[]); #endif diff --git a/src/gromacs/selection/compiler.cpp b/src/gromacs/selection/compiler.cpp index 7d43e2f103..2547a7ba1e 100644 --- a/src/gromacs/selection/compiler.cpp +++ b/src/gromacs/selection/compiler.cpp @@ -294,10 +294,10 @@ #include "selelem.h" #include "selmethod.h" -using std::min; using gmx::SelectionLocation; using gmx::SelectionTreeElement; using gmx::SelectionTreeElementPointer; +using std::min; /*! \internal \brief * Compiler flags. @@ -311,22 +311,22 @@ enum * evaluate non-atom-valued selection method parameters, as well as * those that are used directly as values of selections. */ - SEL_CDATA_FULLEVAL = 1, + SEL_CDATA_FULLEVAL = 1, /*! \brief * Whether the whole subexpression should be treated as static. * * This flag is always false if \ref SEL_DYNAMIC is set for the element, * but it is also false for static elements within common subexpressions. */ - SEL_CDATA_STATIC = 2, + SEL_CDATA_STATIC = 2, /** Whether the subexpression will always be evaluated in the same group. */ - SEL_CDATA_STATICEVAL = 4, + SEL_CDATA_STATICEVAL = 4, /** Whether the compiler evaluation routine should return the maximal selection. */ - SEL_CDATA_EVALMAX = 8, + SEL_CDATA_EVALMAX = 8, /** Whether memory has been allocated for \p gmin and \p gmax. */ SEL_CDATA_MINMAXALLOC = 16, /** Whether to update \p gmin and \p gmax in static analysis. */ - SEL_CDATA_DOMINMAX = 256, + SEL_CDATA_DOMINMAX = 256, /** Whether the subexpression uses simple pass evaluation functions. */ SEL_CDATA_SIMPLESUBEXPR = 32, /*! \brief @@ -348,13 +348,13 @@ typedef struct t_compiler_data /** The real evaluation method. */ gmx::sel_evalfunc evaluate; /** Number of references to a \ref SEL_SUBEXPR element. */ - int refcount; + int refcount; /** Flags for specifying how to treat this element during compilation. */ - int flags; + int flags; /** Smallest selection that can be selected by the subexpression. */ - gmx_ana_index_t *gmin; + gmx_ana_index_t* gmin; /** Largest selection that can be selected by the subexpression. */ - gmx_ana_index_t *gmax; + gmx_ana_index_t* gmax; } t_compiler_data; @@ -365,10 +365,7 @@ typedef struct t_compiler_data /*! \brief * Helper method for printing out debug information about a min/max group. */ -static void -print_group_info(FILE *fp, const char *name, - const SelectionTreeElement &sel, - gmx_ana_index_t *g) +static void print_group_info(FILE* fp, const char* name, const SelectionTreeElement& sel, gmx_ana_index_t* g) { fprintf(fp, " %s=", name); if (!g) @@ -394,15 +391,13 @@ print_group_info(FILE *fp, const char *name, * \param[in] sel Selection element to print. * \param[in] level Indentation level, starting from zero. */ -void -_gmx_selelem_print_compiler_info(FILE *fp, const SelectionTreeElement &sel, - int level) +void _gmx_selelem_print_compiler_info(FILE* fp, const SelectionTreeElement& sel, int level) { if (!sel.cdata) { return; } - fprintf(fp, "%*c cdata: flg=", level*2+1, ' '); + fprintf(fp, "%*c cdata: flg=", level * 2 + 1, ' '); if (sel.cdata->flags & SEL_CDATA_FULLEVAL) { fprintf(fp, "F"); @@ -485,14 +480,11 @@ void SelectionTreeElement::freeCompilerData() * Allocation of POS_VALUE selection elements is a special case, and is * handled by alloc_selection_pos_data(). */ -static void -alloc_selection_data(const SelectionTreeElementPointer &sel, - int isize, bool bChildEval) +static void alloc_selection_data(const SelectionTreeElementPointer& sel, int isize, bool bChildEval) { - int nalloc; + int nalloc; - GMX_RELEASE_ASSERT(sel->v.type != POS_VALUE, - "Wrong allocation method called"); + GMX_RELEASE_ASSERT(sel->v.type != POS_VALUE, "Wrong allocation method called"); if (sel->mempool) { return; @@ -519,8 +511,7 @@ alloc_selection_data(const SelectionTreeElementPointer &sel, GMX_RELEASE_ASSERT(sel->child && sel->child->type == SEL_SUBEXPR, "Subexpression expected for subexpression reference"); child = sel->child->child; - GMX_RELEASE_ASSERT(child, - "Subexpression elements should always have a child element"); + GMX_RELEASE_ASSERT(child, "Subexpression elements should always have a child element"); } nalloc = child->v.nr; } @@ -544,15 +535,12 @@ alloc_selection_data(const SelectionTreeElementPointer &sel, * Allocation of POS_VALUE selection elements is a special case, and is * handled by this function instead of by alloc_selection_data(). */ -static void -alloc_selection_pos_data(const SelectionTreeElementPointer &sel) +static void alloc_selection_pos_data(const SelectionTreeElementPointer& sel) { int nalloc, isize; - GMX_RELEASE_ASSERT(sel->v.type == POS_VALUE, - "Wrong allocation method called"); - GMX_RELEASE_ASSERT(!(sel->flags & SEL_ATOMVAL), - "Per-atom evaluated positions not implemented"); + GMX_RELEASE_ASSERT(sel->v.type == POS_VALUE, "Wrong allocation method called"); + GMX_RELEASE_ASSERT(!(sel->flags & SEL_ATOMVAL), "Per-atom evaluated positions not implemented"); if (sel->mempool) { return; @@ -564,8 +552,7 @@ alloc_selection_pos_data(const SelectionTreeElementPointer &sel) GMX_RELEASE_ASSERT(sel->child && sel->child->type == SEL_SUBEXPR, "Subexpression expected for subexpression reference"); child = sel->child->child; - GMX_RELEASE_ASSERT(child, - "Subexpression elements should always have a child element"); + GMX_RELEASE_ASSERT(child, "Subexpression elements should always have a child element"); } nalloc = child->v.u.p->count(); isize = child->v.u.p->m.b.nra; @@ -590,9 +577,7 @@ alloc_selection_pos_data(const SelectionTreeElementPointer &sel) * \param sel Root of the selection subtree to process. * \param[in] eval The new evaluation function. */ -static void -set_evaluation_function(const SelectionTreeElementPointer &sel, - gmx::sel_evalfunc eval) +static void set_evaluation_function(const SelectionTreeElementPointer& sel, gmx::sel_evalfunc eval) { sel->evaluate = eval; if (sel->type != SEL_SUBEXPRREF) @@ -620,10 +605,10 @@ set_evaluation_function(const SelectionTreeElementPointer &sel, * \param[in] sel Selection that the element evaluates the positions * for, or NULL if the element is an internal element. */ -static void -init_pos_keyword_defaults(SelectionTreeElement *root, - const char *spost, const char *rpost, - const gmx::internal::SelectionData *sel) +static void init_pos_keyword_defaults(SelectionTreeElement* root, + const char* spost, + const char* rpost, + const gmx::internal::SelectionData* sel) { /* Selections use largest static group by default, while * reference positions use the whole residue/molecule. */ @@ -650,8 +635,8 @@ init_pos_keyword_defaults(SelectionTreeElement *root, _gmx_selelem_set_kwpos_flags(root, flags); } /* Change the defaults once we are no longer processing modifiers */ - if (root->type != SEL_ROOT && root->type != SEL_MODIFIER - && root->type != SEL_SUBEXPRREF && root->type != SEL_SUBEXPR) + if (root->type != SEL_ROOT && root->type != SEL_MODIFIER && root->type != SEL_SUBEXPRREF + && root->type != SEL_SUBEXPR) { sel = nullptr; } @@ -675,17 +660,16 @@ init_pos_keyword_defaults(SelectionTreeElement *root, * \param root First selection in the whole selection chain. * \returns The new first element for the chain. */ -static SelectionTreeElementPointer -reverse_selelem_chain(const SelectionTreeElementPointer &root) +static SelectionTreeElementPointer reverse_selelem_chain(const SelectionTreeElementPointer& root) { SelectionTreeElementPointer prev; SelectionTreeElementPointer item = root; while (item) { SelectionTreeElementPointer next = item->next; - item->next = prev; - prev = item; - item = next; + item->next = prev; + prev = item; + item = next; } return prev; } @@ -699,8 +683,7 @@ reverse_selelem_chain(const SelectionTreeElementPointer &root) * The elements are processed in reverse order to correctly detect * subexpressions only referred to by other subexpressions. */ -static SelectionTreeElementPointer -remove_unused_subexpressions(SelectionTreeElementPointer root) +static SelectionTreeElementPointer remove_unused_subexpressions(SelectionTreeElementPointer root) { if (!root) { @@ -743,8 +726,7 @@ remove_unused_subexpressions(SelectionTreeElementPointer root) * gmx::SelectionTreeElement::u::cgrp::name; the latter is freed by * _gmx_selelem_free(). */ -static void -create_subexpression_name(const SelectionTreeElementPointer &sel, int i) +static void create_subexpression_name(const SelectionTreeElementPointer& sel, int i) { std::string name(gmx::formatString("SubExpr %d", i)); sel->setName(name); @@ -763,9 +745,8 @@ create_subexpression_name(const SelectionTreeElementPointer &sel, int i) * that contain the subexpression as their children and returns the first * of these root elements. */ -static SelectionTreeElementPointer -extract_item_subselections(const SelectionTreeElementPointer &sel, - int *subexprn) +static SelectionTreeElementPointer extract_item_subselections(const SelectionTreeElementPointer& sel, + int* subexprn) { SelectionTreeElementPointer root; SelectionTreeElementPointer subexpr; @@ -808,8 +789,8 @@ extract_item_subselections(const SelectionTreeElementPointer &sel, child->child = subexpr->child; create_subexpression_name(subexpr->child, ++*subexprn); /* Set the flags for the created elements */ - subexpr->flags |= (child->flags & SEL_VALFLAGMASK); - subexpr->child->flags |= (child->flags & SEL_VALFLAGMASK); + subexpr->flags |= (child->flags & SEL_VALFLAGMASK); + subexpr->child->flags |= (child->flags & SEL_VALFLAGMASK); } if (child->type == SEL_SUBEXPRREF) { @@ -834,16 +815,14 @@ extract_item_subselections(const SelectionTreeElementPointer &sel, * and inserted into the selection chain before the expressions that * refer to them. */ -static SelectionTreeElementPointer -extract_subexpressions(SelectionTreeElementPointer sel) +static SelectionTreeElementPointer extract_subexpressions(SelectionTreeElementPointer sel) { SelectionTreeElementPointer root; - SelectionTreeElementPointer next = sel; - int subexprn = 0; + SelectionTreeElementPointer next = sel; + int subexprn = 0; while (next) { - SelectionTreeElementPointer item - = extract_item_subselections(next, &subexprn); + SelectionTreeElementPointer item = extract_item_subselections(next, &subexprn); if (item) { if (!root) @@ -883,8 +862,7 @@ extract_subexpressions(SelectionTreeElementPointer sel) * This function merges similar boolean operations (e.g., (A or B) or C becomes * a single OR operation with three operands). */ -static void -optimize_boolean_expressions(const SelectionTreeElementPointer &sel) +static void optimize_boolean_expressions(const SelectionTreeElementPointer& sel) { /* Do recursively for children */ if (sel->type != SEL_SUBEXPRREF) @@ -962,8 +940,7 @@ optimize_boolean_expressions(const SelectionTreeElementPointer &sel) * The relative order of static expressions does not change. * The same is true for the dynamic expressions. */ -static void -reorder_boolean_static_children(const SelectionTreeElementPointer &sel) +static void reorder_boolean_static_children(const SelectionTreeElementPointer& sel) { /* Do recursively for children */ if (sel->type != SEL_SUBEXPRREF) @@ -982,7 +959,7 @@ reorder_boolean_static_children(const SelectionTreeElementPointer &sel) // Add a dummy head element that precedes the first child. SelectionTreeElementPointer dummy( new SelectionTreeElement(SEL_BOOLEAN, SelectionLocation::createEmpty())); - dummy->next = sel->child; + dummy->next = sel->child; SelectionTreeElementPointer prev = dummy; SelectionTreeElementPointer child = dummy; while (child->next) @@ -1032,8 +1009,7 @@ reorder_boolean_static_children(const SelectionTreeElementPointer &sel) * Currently, this function only converts integer constants to reals * within arithmetic expressions. */ -static void -optimize_arithmetic_expressions(const SelectionTreeElementPointer &sel) +static void optimize_arithmetic_expressions(const SelectionTreeElementPointer& sel) { /* Do recursively for children. */ if (sel->type != SEL_SUBEXPRREF) @@ -1057,11 +1033,13 @@ optimize_arithmetic_expressions(const SelectionTreeElementPointer &sel) { if (child->v.type == INT_VALUE) { - real *r; + real* r; if (child->type != SEL_CONST) { - GMX_THROW(gmx::InconsistentInputError("Non-constant integer expressions not implemented in arithmetic evaluation")); + GMX_THROW( + gmx::InconsistentInputError("Non-constant integer expressions not " + "implemented in arithmetic evaluation")); } snew(r, 1); r[0] = child->v.u.i[0]; @@ -1090,8 +1068,7 @@ optimize_arithmetic_expressions(const SelectionTreeElementPointer &sel) * This function sets the evaluation function * (gmx::SelectionTreeElement::evaluate) for the selection elements. */ -static void -init_item_evalfunc(const SelectionTreeElementPointer &sel) +static void init_item_evalfunc(const SelectionTreeElementPointer& sel) { /* Process children. */ if (sel->type != SEL_SUBEXPRREF) @@ -1115,17 +1092,14 @@ init_item_evalfunc(const SelectionTreeElementPointer &sel) break; case SEL_EXPRESSION: - if (!(sel->flags & SEL_DYNAMIC) && sel->u.expr.method - && sel->u.expr.method->init_frame) + if (!(sel->flags & SEL_DYNAMIC) && sel->u.expr.method && sel->u.expr.method->init_frame) { sel->flags |= SEL_INITFRAME; } sel->evaluate = &_gmx_sel_evaluate_method; break; - case SEL_ARITHMETIC: - sel->evaluate = &_gmx_sel_evaluate_arithmetic; - break; + case SEL_ARITHMETIC: sel->evaluate = &_gmx_sel_evaluate_arithmetic; break; case SEL_MODIFIER: if (sel->v.type != NO_VALUE) @@ -1139,15 +1113,13 @@ init_item_evalfunc(const SelectionTreeElementPointer &sel) { case BOOL_NOT: sel->evaluate = &_gmx_sel_evaluate_not; break; case BOOL_AND: sel->evaluate = &_gmx_sel_evaluate_and; break; - case BOOL_OR: sel->evaluate = &_gmx_sel_evaluate_or; break; + case BOOL_OR: sel->evaluate = &_gmx_sel_evaluate_or; break; case BOOL_XOR: GMX_THROW(gmx::NotImplementedError("xor expressions not implemented")); } break; - case SEL_ROOT: - sel->evaluate = &_gmx_sel_evaluate_root; - break; + case SEL_ROOT: sel->evaluate = &_gmx_sel_evaluate_root; break; case SEL_SUBEXPR: if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) @@ -1163,12 +1135,11 @@ init_item_evalfunc(const SelectionTreeElementPointer &sel) case SEL_SUBEXPRREF: sel->evaluate = ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) - ? &_gmx_sel_evaluate_subexprref_simple - : &_gmx_sel_evaluate_subexprref); + ? &_gmx_sel_evaluate_subexprref_simple + : &_gmx_sel_evaluate_subexprref); break; - case SEL_GROUPREF: - GMX_THROW(gmx::APIError("Unresolved group reference in compilation")); + case SEL_GROUPREF: GMX_THROW(gmx::APIError("Unresolved group reference in compilation")); } sel->cdata->evaluate = sel->evaluate; } @@ -1179,9 +1150,7 @@ init_item_evalfunc(const SelectionTreeElementPointer &sel) * \param sel Root of the selection subtree to process. * \param[in] mempool Memory pool to use. */ -static void -setup_memory_pooling(const SelectionTreeElementPointer &sel, - gmx_sel_mempool_t *mempool) +static void setup_memory_pooling(const SelectionTreeElementPointer& sel, gmx_sel_mempool_t* mempool) { if (sel->type != SEL_SUBEXPRREF) { @@ -1189,14 +1158,11 @@ setup_memory_pooling(const SelectionTreeElementPointer &sel, while (child) { if ((sel->type == SEL_BOOLEAN && (child->flags & SEL_DYNAMIC)) - || (sel->type == SEL_ARITHMETIC && child->type != SEL_CONST - && !(child->flags & SEL_SINGLEVAL)) - || (sel->type == SEL_SUBEXPR - && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))) + || (sel->type == SEL_ARITHMETIC && child->type != SEL_CONST && !(child->flags & SEL_SINGLEVAL)) + || (sel->type == SEL_SUBEXPR && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR))) { child->mempool = mempool; - if (child->type == SEL_SUBEXPRREF - && (child->child->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) + if (child->type == SEL_SUBEXPRREF && (child->child->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) { child->child->child->mempool = mempool; } @@ -1215,11 +1181,9 @@ setup_memory_pooling(const SelectionTreeElementPointer &sel, * It also allocates memory for the \p sel->v.u.g or \p sel->v.u.p * structure if required. */ -static void -init_item_evaloutput(const SelectionTreeElementPointer &sel) +static void init_item_evaloutput(const SelectionTreeElementPointer& sel) { - GMX_ASSERT(!(sel->child == nullptr && - (sel->type == SEL_SUBEXPRREF || sel->type == SEL_SUBEXPR)), + GMX_ASSERT(!(sel->child == nullptr && (sel->type == SEL_SUBEXPRREF || sel->type == SEL_SUBEXPR)), "Subexpression elements should always have a child element"); /* Process children. */ @@ -1233,8 +1197,7 @@ init_item_evaloutput(const SelectionTreeElementPointer &sel) } } - if (sel->type == SEL_SUBEXPR - && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) + if (sel->type == SEL_SUBEXPR && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) && !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR)) { sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); @@ -1243,20 +1206,18 @@ init_item_evaloutput(const SelectionTreeElementPointer &sel) _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr); } } - else if (sel->type == SEL_SUBEXPR - && (sel->cdata->flags & SEL_CDATA_FULLEVAL)) + else if (sel->type == SEL_SUBEXPR && (sel->cdata->flags & SEL_CDATA_FULLEVAL)) { sel->evaluate = &_gmx_sel_evaluate_subexpr_staticeval; sel->cdata->evaluate = sel->evaluate; sel->child->mempool = nullptr; - sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); + sel->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); if (sel->v.type == GROUP_VALUE || sel->v.type == POS_VALUE) { _gmx_selvalue_setstore(&sel->v, sel->child->v.u.ptr); } } - else if (sel->type == SEL_SUBEXPRREF - && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) + else if (sel->type == SEL_SUBEXPRREF && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) { if (sel->v.u.ptr) { @@ -1294,8 +1255,7 @@ init_item_evaloutput(const SelectionTreeElementPointer &sel) * * \param sel Root of the selection subtree to process. */ -static void -init_item_compilerdata(const SelectionTreeElementPointer &sel) +static void init_item_compilerdata(const SelectionTreeElementPointer& sel) { /* Allocate the compiler data structure */ snew(sel->cdata, 1); @@ -1351,9 +1311,9 @@ init_item_compilerdata(const SelectionTreeElementPointer &sel) * for the children of this element. */ if (sel->type == SEL_BOOLEAN) { - bool bEvalMax; + bool bEvalMax; - bEvalMax = (sel->u.boolt == BOOL_AND); + bEvalMax = (sel->u.boolt == BOOL_AND); SelectionTreeElementPointer child = sel->child; while (child) { @@ -1368,14 +1328,13 @@ init_item_compilerdata(const SelectionTreeElementPointer &sel) child = child->next; } } - else if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER - || sel->type == SEL_SUBEXPR) + else if (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER || sel->type == SEL_SUBEXPR) { SelectionTreeElementPointer child = sel->child; while (child) { child->cdata->flags |= SEL_CDATA_EVALMAX; - child = child->next; + child = child->next; } } } @@ -1391,13 +1350,11 @@ init_item_compilerdata(const SelectionTreeElementPointer &sel) * * reorder_boolean_static_children() should have been called. */ -static void -init_item_staticeval(const SelectionTreeElementPointer &sel) +static void init_item_staticeval(const SelectionTreeElementPointer& sel) { /* Subexpressions with full evaluation should always have bStaticEval, * so don't do anything if a reference to them is encountered. */ - if (sel->type == SEL_SUBEXPRREF - && (sel->child->cdata->flags & SEL_CDATA_FULLEVAL)) + if (sel->type == SEL_SUBEXPRREF && (sel->child->cdata->flags & SEL_CDATA_FULLEVAL)) { return; } @@ -1408,8 +1365,7 @@ init_item_staticeval(const SelectionTreeElementPointer &sel) SelectionTreeElementPointer child = sel->child; while (child) { - if ((sel->type != SEL_EXPRESSION && sel->type != SEL_MODIFIER) - || (child->flags & SEL_ATOMVAL)) + if ((sel->type != SEL_EXPRESSION && sel->type != SEL_MODIFIER) || (child->flags & SEL_ATOMVAL)) { if (child->cdata->flags & SEL_CDATA_STATICEVAL) { @@ -1419,11 +1375,10 @@ init_item_staticeval(const SelectionTreeElementPointer &sel) } /* If an expression is evaluated for a dynamic group, then also * atom-valued parameters need to be evaluated every time. */ - if ((sel->flags & SEL_DYNAMIC) - && (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER) + if ((sel->flags & SEL_DYNAMIC) && (sel->type == SEL_EXPRESSION || sel->type == SEL_MODIFIER) && (child->flags & SEL_ATOMVAL)) { - child->flags |= SEL_DYNAMIC; + child->flags |= SEL_DYNAMIC; child->cdata->flags &= ~SEL_CDATA_STATIC; } child = child->next; @@ -1447,7 +1402,7 @@ init_item_staticeval(const SelectionTreeElementPointer &sel) while (child) { child->cdata->flags &= ~SEL_CDATA_STATICEVAL; - child = child->next; + child = child->next; } } @@ -1466,12 +1421,10 @@ init_item_staticeval(const SelectionTreeElementPointer &sel) * * \param sel Root of the selection subtree to process. */ -static void -init_item_subexpr_refcount(const SelectionTreeElementPointer &sel) +static void init_item_subexpr_refcount(const SelectionTreeElementPointer& sel) { // Reset the counter when the subexpression is first encountered. - if (sel->type == SEL_ROOT && sel->child->type == SEL_SUBEXPR - && sel->child->cdata) + if (sel->type == SEL_ROOT && sel->child->type == SEL_SUBEXPR && sel->child->cdata) { sel->child->cdata->refcount = 0; } @@ -1496,8 +1449,7 @@ init_item_subexpr_refcount(const SelectionTreeElementPointer &sel) * * \param sel Root of the selection subtree to process. */ -static void -init_item_subexpr_flags(const SelectionTreeElementPointer &sel) +static void init_item_subexpr_flags(const SelectionTreeElementPointer& sel) { if (sel->type == SEL_SUBEXPR) { @@ -1510,13 +1462,10 @@ init_item_subexpr_flags(const SelectionTreeElementPointer &sel) sel->cdata->flags |= SEL_CDATA_COMMONSUBEXPR; } } - else if (sel->type == SEL_SUBEXPRREF - && (sel->child->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) + else if (sel->type == SEL_SUBEXPRREF && (sel->child->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) { /* See similar condition in init_item_staticeval(). */ - if ((sel->flags & SEL_ATOMVAL) - && (sel->flags & SEL_DYNAMIC) - && !(sel->child->flags & SEL_DYNAMIC)) + if ((sel->flags & SEL_ATOMVAL) && (sel->flags & SEL_DYNAMIC) && !(sel->child->flags & SEL_DYNAMIC)) { sel->child->cdata->flags |= SEL_CDATA_STATICMULTIEVALSUBEXPR; } @@ -1539,8 +1488,7 @@ init_item_subexpr_flags(const SelectionTreeElementPointer &sel) { if (sel->type != SEL_EXPRESSION || (child->flags & SEL_ATOMVAL)) { - child->cdata->flags |= - (sel->cdata->flags & SEL_CDATA_COMMONSUBEXPR); + child->cdata->flags |= (sel->cdata->flags & SEL_CDATA_COMMONSUBEXPR); } init_item_subexpr_flags(child); } @@ -1554,8 +1502,7 @@ init_item_subexpr_flags(const SelectionTreeElementPointer &sel) * * \param sel Root of the selection subtree to process. */ -static void -init_item_minmax_groups(const SelectionTreeElementPointer &sel) +static void init_item_minmax_groups(const SelectionTreeElementPointer& sel) { /* Process children. */ if (sel->type != SEL_SUBEXPRREF) @@ -1571,8 +1518,7 @@ init_item_minmax_groups(const SelectionTreeElementPointer &sel) /* Initialize the minimum and maximum evaluation groups. */ if (sel->type != SEL_ROOT && sel->v.type != NO_VALUE) { - if (sel->v.type == GROUP_VALUE - && (sel->cdata->flags & SEL_CDATA_STATIC)) + if (sel->v.type == GROUP_VALUE && (sel->cdata->flags & SEL_CDATA_STATIC)) { sel->cdata->gmin = sel->v.u.g; sel->cdata->gmax = sel->v.u.g; @@ -1581,8 +1527,7 @@ init_item_minmax_groups(const SelectionTreeElementPointer &sel) && ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) || (sel->cdata->flags & SEL_CDATA_FULLEVAL))) { - GMX_ASSERT(sel->child, - "Subexpression elements should always have a child element"); + GMX_ASSERT(sel->child, "Subexpression elements should always have a child element"); sel->cdata->gmin = sel->child->cdata->gmin; sel->cdata->gmax = sel->child->cdata->gmax; } @@ -1610,14 +1555,12 @@ init_item_minmax_groups(const SelectionTreeElementPointer &sel) * elements corresponding to subexpressions that need full evaluation is set * to \c sc->gall. */ -static void -initialize_evalgrps(gmx_ana_selcollection_t *sc) +static void initialize_evalgrps(gmx_ana_selcollection_t* sc) { SelectionTreeElementPointer root = sc->root; while (root) { - GMX_RELEASE_ASSERT(root->child, - "Root elements should always have a child"); + GMX_RELEASE_ASSERT(root->child, "Root elements should always have a child"); if (root->child->type != SEL_SUBEXPR || (root->child->v.type != GROUP_VALUE && !(root->flags & SEL_ATOMVAL))) { @@ -1647,9 +1590,7 @@ initialize_evalgrps(gmx_ana_selcollection_t *sc) * Does not descend into parameters of methods unless the parameters * are evaluated for each atom. */ -static void -mark_subexpr_dynamic(const SelectionTreeElementPointer &sel, - bool bDynamic) +static void mark_subexpr_dynamic(const SelectionTreeElementPointer& sel, bool bDynamic) { if (!bDynamic && !(sel->flags & SEL_DYNAMIC)) { @@ -1683,12 +1624,11 @@ mark_subexpr_dynamic(const SelectionTreeElementPointer &sel, * pointer would be left at the root element, which is not traversed by this * function. Later compilation passes remove the stub elements. */ -static void -release_subexpr_memory(const SelectionTreeElementPointer &sel) +static void release_subexpr_memory(const SelectionTreeElementPointer& sel) { if (sel->type == SEL_SUBEXPRREF) { - const SelectionTreeElementPointer &subexpr = sel->child; + const SelectionTreeElementPointer& subexpr = sel->child; if (subexpr.use_count() == 2) { release_subexpr_memory(subexpr); @@ -1719,24 +1659,22 @@ release_subexpr_memory(const SelectionTreeElementPointer &sel) * The element type is changed to SEL_CONST and the children are * deleted. */ -static void -make_static(const SelectionTreeElementPointer &sel) +static void make_static(const SelectionTreeElementPointer& sel) { /* If this is a subexpression reference and the data is stored in the * child, we transfer data ownership before doing anything else. */ - if (sel->type == SEL_SUBEXPRREF - && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) + if (sel->type == SEL_SUBEXPRREF && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) { if (sel->child->child->flags & SEL_ALLOCDATA) { - sel->flags |= SEL_ALLOCDATA; + sel->flags |= SEL_ALLOCDATA; sel->child->child->flags &= ~SEL_ALLOCDATA; } if (sel->child->child->flags & SEL_ALLOCVAL) { - sel->flags |= SEL_ALLOCVAL; - sel->v.nalloc = sel->child->child->v.nalloc; - sel->child->child->flags &= ~SEL_ALLOCVAL; + sel->flags |= SEL_ALLOCVAL; + sel->v.nalloc = sel->child->child->v.nalloc; + sel->child->child->flags &= ~SEL_ALLOCVAL; sel->child->child->v.nalloc = -1; } } @@ -1766,10 +1704,7 @@ make_static(const SelectionTreeElementPointer &sel) * \param[in] g The evaluation group. * \returns 0 on success, a non-zero error code on error. */ -static void -process_const(gmx_sel_evaluate_t *data, - const SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +static void process_const(gmx_sel_evaluate_t* data, const SelectionTreeElementPointer& sel, gmx_ana_index_t* g) { if (sel->v.type == GROUP_VALUE) { @@ -1794,8 +1729,7 @@ process_const(gmx_sel_evaluate_t *data, * Also, if the \c sel->u.param does not have \ref SPAR_VARNUM or * \ref SPAR_ATOMVAL, the function returns immediately. */ -static void -store_param_val(const SelectionTreeElementPointer &sel) +static void store_param_val(const SelectionTreeElementPointer& sel) { /* Return immediately if there is no parameter. */ if (sel->type != SEL_SUBEXPRREF || !sel->u.param) @@ -1809,8 +1743,7 @@ store_param_val(const SelectionTreeElementPointer &sel) return; } - if (sel->v.type == INT_VALUE || sel->v.type == REAL_VALUE - || sel->v.type == STR_VALUE) + if (sel->v.type == INT_VALUE || sel->v.type == REAL_VALUE || sel->v.type == STR_VALUE) { _gmx_selvalue_setstore(&sel->u.param->val, sel->v.u.ptr); } @@ -1829,12 +1762,11 @@ store_param_val(const SelectionTreeElementPointer &sel) * If no \ref SPAR_ATOMVAL parameters are present, multiple initialization * is prevented by using \ref SEL_METHODINIT and \ref SEL_OUTINIT flags. */ -static void -init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int isize) +static void init_method(const SelectionTreeElementPointer& sel, const gmx_mtop_t* top, int isize) { /* Find out whether there are any atom-valued parameters */ - bool bAtomVal = false; - SelectionTreeElementPointer child = sel->child; + bool bAtomVal = false; + SelectionTreeElementPointer child = sel->child; while (child) { if (child->flags & SEL_ATOMVAL) @@ -1845,12 +1777,11 @@ init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int i } /* Initialize the method */ - if (sel->u.expr.method->init - && (bAtomVal || !(sel->flags & SEL_METHODINIT))) + if (sel->u.expr.method->init && (bAtomVal || !(sel->flags & SEL_METHODINIT))) { sel->flags |= SEL_METHODINIT; - sel->u.expr.method->init(top, sel->u.expr.method->nparams, - sel->u.expr.method->param, sel->u.expr.mdata); + sel->u.expr.method->init(top, sel->u.expr.method->nparams, sel->u.expr.method->param, + sel->u.expr.mdata); } if (bAtomVal || !(sel->flags & SEL_OUTINIT)) { @@ -1858,8 +1789,7 @@ init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int i if (sel->u.expr.method->outinit) { sel->u.expr.method->outinit(top, &sel->v, sel->u.expr.mdata); - if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE - && !(sel->flags & SEL_VARNUMVAL)) + if (sel->v.type != POS_VALUE && sel->v.type != GROUP_VALUE && !(sel->flags & SEL_VARNUMVAL)) { alloc_selection_data(sel, isize, true); } @@ -1876,12 +1806,13 @@ init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int i /* If the method is char-valued, pre-allocate the strings. */ if (sel->u.expr.method->flags & SMETH_CHARVAL) { - int i; + int i; /* A sanity check */ if (sel->v.type != STR_VALUE) { - GMX_THROW(gmx::InternalError("Char-valued selection method in non-string element")); + GMX_THROW(gmx::InternalError( + "Char-valued selection method in non-string element")); } sel->flags |= SEL_ALLOCDATA; for (i = 0; i < isize; ++i) @@ -1907,10 +1838,9 @@ init_method(const SelectionTreeElementPointer &sel, const gmx_mtop_t *top, int i * * reorder_item_static_children() should have been called. */ -static void -evaluate_boolean_static_part(gmx_sel_evaluate_t *data, - const SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +static void evaluate_boolean_static_part(gmx_sel_evaluate_t* data, + const SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { /* Find the last static subexpression */ SelectionTreeElementPointer child = sel->child; @@ -1930,17 +1860,17 @@ evaluate_boolean_static_part(gmx_sel_evaluate_t *data, child->next.reset(); sel->cdata->evaluate(data, sel, g); /* Replace the subexpressions with the result */ - child = std::make_shared(SEL_CONST, SelectionLocation::createEmpty()); - child->flags = SEL_FLAGSSET | SEL_SINGLEVAL | SEL_ALLOCVAL | SEL_ALLOCDATA; + child = std::make_shared(SEL_CONST, SelectionLocation::createEmpty()); + child->flags = SEL_FLAGSSET | SEL_SINGLEVAL | SEL_ALLOCVAL | SEL_ALLOCDATA; _gmx_selelem_set_vtype(child, GROUP_VALUE); - child->evaluate = nullptr; + child->evaluate = nullptr; _gmx_selvalue_reserve(&child->v, 1); gmx_ana_index_copy(child->v.u.g, sel->v.u.g, true); init_item_compilerdata(child); init_item_minmax_groups(child); child->cdata->flags &= ~SEL_CDATA_STATICEVAL; child->cdata->flags |= sel->cdata->flags & SEL_CDATA_STATICEVAL; - child->next = next; + child->next = next; // Frees the old static subexpressions. sel->child = child; } @@ -1956,9 +1886,7 @@ evaluate_boolean_static_part(gmx_sel_evaluate_t *data, * is also static, and will be made a constant later, so don't waste * time copying the group. */ child->evaluate = nullptr; - if (sel->u.boolt == BOOL_NOT - || ((sel->cdata->flags & SEL_CDATA_STATICEVAL) - && sel->u.boolt == BOOL_OR)) + if (sel->u.boolt == BOOL_NOT || ((sel->cdata->flags & SEL_CDATA_STATICEVAL) && sel->u.boolt == BOOL_OR)) { child->cdata->evaluate = nullptr; } @@ -2001,10 +1929,10 @@ evaluate_boolean_static_part(gmx_sel_evaluate_t *data, * reached shortly after this function returns), this should not be a major * problem. */ -static void -evaluate_boolean_minmax_grps(const SelectionTreeElementPointer &sel, - gmx_ana_index_t *g, - gmx_ana_index_t *gmin, gmx_ana_index_t *gmax) +static void evaluate_boolean_minmax_grps(const SelectionTreeElementPointer& sel, + gmx_ana_index_t* g, + gmx_ana_index_t* gmin, + gmx_ana_index_t* gmax) { SelectionTreeElementPointer child; @@ -2029,8 +1957,7 @@ evaluate_boolean_minmax_grps(const SelectionTreeElementPointer &sel, child = child->next; } /* Update the static part if other expressions limit it */ - if ((sel->child->cdata->flags & SEL_CDATA_STATIC) - && sel->child->v.u.g->isize > gmax->isize) + if ((sel->child->cdata->flags & SEL_CDATA_STATIC) && sel->child->v.u.g->isize > gmax->isize) { gmx_ana_index_copy(sel->child->v.u.g, gmax, false); gmx_ana_index_squeeze(sel->child->v.u.g); @@ -2059,8 +1986,7 @@ evaluate_boolean_minmax_grps(const SelectionTreeElementPointer &sel, } /* Update the static part if other expressions have static parts * that are not included. */ - if ((sel->child->cdata->flags & SEL_CDATA_STATIC) - && sel->child->v.u.g->isize < gmin->isize) + if ((sel->child->cdata->flags & SEL_CDATA_STATIC) && sel->child->v.u.g->isize < gmin->isize) { GMX_RELEASE_ASSERT(sel->child->type == SEL_CONST, "The first child should have already been evaluated " @@ -2105,12 +2031,9 @@ evaluate_boolean_minmax_grps(const SelectionTreeElementPointer &sel, * another pass is required for subexpressions that are referred to more than * once and whose evaluation group is not known in advance. */ -static void -analyze_static(gmx_sel_evaluate_t *data, - const SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +static void analyze_static(gmx_sel_evaluate_t* data, const SelectionTreeElementPointer& sel, gmx_ana_index_t* g) { - bool bDoMinMax; + bool bDoMinMax; if (sel->type != SEL_ROOT && g) { @@ -2127,9 +2050,7 @@ analyze_static(gmx_sel_evaluate_t *data, /* TODO: This switch is awfully long... */ switch (sel->type) { - case SEL_CONST: - process_const(data, sel, g); - break; + case SEL_CONST: process_const(data, sel, g); break; case SEL_EXPRESSION: case SEL_MODIFIER: @@ -2205,8 +2126,7 @@ analyze_static(gmx_sel_evaluate_t *data, } /* Evaluate minimal and maximal selections */ - evaluate_boolean_minmax_grps(sel, g, sel->cdata->gmin, - sel->cdata->gmax); + evaluate_boolean_minmax_grps(sel, g, sel->cdata->gmin, sel->cdata->gmax); } break; @@ -2225,13 +2145,11 @@ analyze_static(gmx_sel_evaluate_t *data, } break; - case SEL_ROOT: - sel->cdata->evaluate(data, sel, g); - break; + case SEL_ROOT: sel->cdata->evaluate(data, sel, g); break; case SEL_SUBEXPR: - if (((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) && - !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR)) + if (((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) + && !(sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR)) || (sel->cdata->flags & SEL_CDATA_FULLEVAL)) { sel->cdata->evaluate(data, sel, g); @@ -2261,15 +2179,11 @@ analyze_static(gmx_sel_evaluate_t *data, if (isize > 0 && bDoMinMax) { gmx_ana_index_reserve(sel->cdata->gmin, - sel->cdata->gmin->isize - + sel->child->cdata->gmin->isize); + sel->cdata->gmin->isize + sel->child->cdata->gmin->isize); gmx_ana_index_reserve(sel->cdata->gmax, - sel->cdata->gmax->isize - + sel->child->cdata->gmax->isize); - gmx_ana_index_merge(sel->cdata->gmin, sel->cdata->gmin, - sel->child->cdata->gmin); - gmx_ana_index_merge(sel->cdata->gmax, sel->cdata->gmax, - sel->child->cdata->gmax); + sel->cdata->gmax->isize + sel->child->cdata->gmax->isize); + gmx_ana_index_merge(sel->cdata->gmin, sel->cdata->gmin, sel->child->cdata->gmin); + gmx_ana_index_merge(sel->cdata->gmax, sel->cdata->gmax, sel->child->cdata->gmax); } } break; @@ -2291,8 +2205,7 @@ analyze_static(gmx_sel_evaluate_t *data, } } sel->cdata->evaluate(data, sel, g); - if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) - && (sel->child->child->flags & SEL_ALLOCVAL)) + if ((sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) && (sel->child->child->flags & SEL_ALLOCVAL)) { _gmx_selvalue_setstore(&sel->v, sel->child->child->v.u.ptr); } @@ -2314,14 +2227,10 @@ analyze_static(gmx_sel_evaluate_t *data, } else { - gmx_ana_index_reserve(sel->cdata->gmin, - min(g->isize, sel->child->cdata->gmin->isize)); - gmx_ana_index_reserve(sel->cdata->gmax, - min(g->isize, sel->child->cdata->gmax->isize)); - gmx_ana_index_intersection(sel->cdata->gmin, - sel->child->cdata->gmin, g); - gmx_ana_index_intersection(sel->cdata->gmax, - sel->child->cdata->gmax, g); + gmx_ana_index_reserve(sel->cdata->gmin, min(g->isize, sel->child->cdata->gmin->isize)); + gmx_ana_index_reserve(sel->cdata->gmax, min(g->isize, sel->child->cdata->gmax->isize)); + gmx_ana_index_intersection(sel->cdata->gmin, sel->child->cdata->gmin, g); + gmx_ana_index_intersection(sel->cdata->gmax, sel->child->cdata->gmax, g); } } break; @@ -2340,8 +2249,7 @@ analyze_static(gmx_sel_evaluate_t *data, /* Replace the result of the evaluation */ /* This is not necessary for subexpressions or for boolean negations * because the evaluation function already has done it properly. */ - if (sel->v.type == GROUP_VALUE && (sel->flags & SEL_DYNAMIC) - && sel->type != SEL_SUBEXPR + if (sel->v.type == GROUP_VALUE && (sel->flags & SEL_DYNAMIC) && sel->type != SEL_SUBEXPR && !(sel->type == SEL_BOOLEAN && sel->u.boolt == BOOL_NOT)) { if (sel->cdata->flags & SEL_CDATA_EVALMAX) @@ -2370,11 +2278,9 @@ analyze_static(gmx_sel_evaluate_t *data, * element, and either clears the evaluation function or initializes the * evaluation group. */ -static void -init_root_item(const SelectionTreeElementPointer &root, - gmx_ana_index_t *gall) +static void init_root_item(const SelectionTreeElementPointer& root, gmx_ana_index_t* gall) { - const SelectionTreeElementPointer &expr = root->child; + const SelectionTreeElementPointer& expr = root->child; /* Subexpressions with non-static evaluation group should not be * evaluated by the root, and neither should be single-reference * subexpressions that don't evaluate for all atoms. */ @@ -2395,8 +2301,7 @@ init_root_item(const SelectionTreeElementPointer &root, { /* Non-atom-valued non-group expressions don't care about the group, so * don't allocate any memory for it. */ - if ((expr->flags & SEL_VARNUMVAL) - || ((expr->flags & SEL_SINGLEVAL) && expr->v.type != GROUP_VALUE)) + if ((expr->flags & SEL_VARNUMVAL) || ((expr->flags & SEL_SINGLEVAL) && expr->v.type != GROUP_VALUE)) { gmx_ana_index_set(&root->u.cgrp, -1, nullptr, 0); } @@ -2435,7 +2340,7 @@ init_root_item(const SelectionTreeElementPointer &root, gmx_ana_index_t g; gmx_ana_index_set(&g, expr->v.u.p->m.mapb.nra, expr->v.u.p->m.mapb.a, 0); _gmx_selelem_set_vtype(root, GROUP_VALUE); - root->flags |= (SEL_ALLOCVAL | SEL_ALLOCDATA); + root->flags |= (SEL_ALLOCVAL | SEL_ALLOCDATA); _gmx_selvalue_reserve(&root->v, 1); gmx_ana_index_copy(root->v.u.g, &g, true); } @@ -2470,9 +2375,7 @@ init_root_item(const SelectionTreeElementPointer &root, * Position calculations are not considered here, but are analyzed through the * position calculation collection in the main compilation method. */ -static void -init_required_atoms(const SelectionTreeElementPointer &sel, - gmx_ana_index_t *requiredAtoms) +static void init_required_atoms(const SelectionTreeElementPointer& sel, gmx_ana_index_t* requiredAtoms) { // Process children. if (sel->type != SEL_SUBEXPRREF) @@ -2485,8 +2388,7 @@ init_required_atoms(const SelectionTreeElementPointer &sel, } } - if (sel->type == SEL_ROOT - || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE)) + if (sel->type == SEL_ROOT || (sel->type == SEL_CONST && sel->v.type == GROUP_VALUE)) { if (sel->u.cgrp.isize > 0) { @@ -2508,11 +2410,9 @@ init_required_atoms(const SelectionTreeElementPointer &sel, * Optimizes away some unnecessary evaluation of subexpressions that are only * referenced once. */ -static void -postprocess_item_subexpressions(const SelectionTreeElementPointer &sel) +static void postprocess_item_subexpressions(const SelectionTreeElementPointer& sel) { - GMX_ASSERT(!(sel->child == nullptr && - (sel->type == SEL_SUBEXPRREF || sel->type == SEL_SUBEXPR)), + GMX_ASSERT(!(sel->child == nullptr && (sel->type == SEL_SUBEXPRREF || sel->type == SEL_SUBEXPR)), "Subexpression elements should always have a child element"); /* Process children. */ @@ -2529,8 +2429,7 @@ postprocess_item_subexpressions(const SelectionTreeElementPointer &sel) /* Replace the evaluation function of statically evaluated subexpressions * for which the static group was not known in advance. */ if (sel->type == SEL_SUBEXPR && sel->cdata->refcount > 1 - && (sel->cdata->flags & SEL_CDATA_STATICEVAL) - && !(sel->cdata->flags & SEL_CDATA_FULLEVAL)) + && (sel->cdata->flags & SEL_CDATA_STATICEVAL) && !(sel->cdata->flags & SEL_CDATA_FULLEVAL)) { /* We need to free memory allocated for the group, because it is no * longer needed (and would be lost on next call to the evaluation @@ -2549,36 +2448,33 @@ postprocess_item_subexpressions(const SelectionTreeElementPointer &sel) /* Adjust memory allocation flags for subexpressions that are used only * once. This is not strictly necessary, but we do it to have the memory * managed consistently for all types of subexpressions. */ - if (sel->type == SEL_SUBEXPRREF - && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) + if (sel->type == SEL_SUBEXPRREF && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR)) { if (sel->child->child->flags & SEL_ALLOCVAL) { - sel->flags |= SEL_ALLOCVAL; - sel->flags |= (sel->child->child->flags & SEL_ALLOCDATA); - sel->v.nalloc = sel->child->child->v.nalloc; - sel->child->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); + sel->flags |= SEL_ALLOCVAL; + sel->flags |= (sel->child->child->flags & SEL_ALLOCDATA); + sel->v.nalloc = sel->child->child->v.nalloc; + sel->child->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); sel->child->child->v.nalloc = -1; } } /* Do the same for subexpressions that are evaluated at once for all atoms. */ - if (sel->type == SEL_SUBEXPR - && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) + if (sel->type == SEL_SUBEXPR && !(sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) && (sel->cdata->flags & SEL_CDATA_FULLEVAL)) { - sel->flags |= SEL_ALLOCVAL; - sel->flags |= (sel->child->flags & SEL_ALLOCDATA); - sel->v.nalloc = sel->child->v.nalloc; - sel->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); + sel->flags |= SEL_ALLOCVAL; + sel->flags |= (sel->child->flags & SEL_ALLOCDATA); + sel->v.nalloc = sel->child->v.nalloc; + sel->child->flags &= ~(SEL_ALLOCVAL | SEL_ALLOCDATA); sel->child->v.nalloc = -1; } /* For static subexpressions with a dynamic evaluation group, there is * no need to evaluate them again, as the SEL_SUBEXPRREF takes care of * everything during evaluation. */ - if (sel->type == SEL_SUBEXPR - && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) + if (sel->type == SEL_SUBEXPR && (sel->cdata->flags & SEL_CDATA_SIMPLESUBEXPR) && (sel->cdata->flags & SEL_CDATA_STATICMULTIEVALSUBEXPR)) { sel->evaluate = nullptr; @@ -2608,14 +2504,13 @@ postprocess_item_subexpressions(const SelectionTreeElementPointer &sel) * No calculation is initialized if \p type equals \ref POS_ATOM and * the method also defines the \c gmx_ana_selmethod_t::update method. */ -static void -init_item_comg(const SelectionTreeElementPointer &sel, - gmx::PositionCalculationCollection *pcc, - e_poscalc_t type, int flags) +static void init_item_comg(const SelectionTreeElementPointer& sel, + gmx::PositionCalculationCollection* pcc, + e_poscalc_t type, + int flags) { /* Initialize COM calculation for dynamic selections now that we know the maximal evaluation group */ - if (sel->type == SEL_EXPRESSION && sel->u.expr.method - && sel->u.expr.method->pupdate) + if (sel->type == SEL_EXPRESSION && sel->u.expr.method && sel->u.expr.method->pupdate) { if (!sel->u.expr.method->update || type != POS_ATOM) { @@ -2627,7 +2522,7 @@ init_item_comg(const SelectionTreeElementPointer &sel, } if (!sel->u.expr.pc) { - cflags |= flags; + cflags |= flags; sel->u.expr.pc = pcc->createCalculation(type, cflags); } else @@ -2664,8 +2559,7 @@ init_item_comg(const SelectionTreeElementPointer &sel, * * Frees the data allocated for the compilation process. */ -static void -free_item_compilerdata(const SelectionTreeElementPointer &sel) +static void free_item_compilerdata(const SelectionTreeElementPointer& sel) { /* Free compilation data */ sel->freeCompilerData(); @@ -2690,9 +2584,7 @@ free_item_compilerdata(const SelectionTreeElementPointer &sel) namespace gmx { -SelectionCompiler::SelectionCompiler() -{ -} +SelectionCompiler::SelectionCompiler() {} /*! * \param[in,out] coll Selection collection to be compiled. @@ -2707,23 +2599,20 @@ SelectionCompiler::SelectionCompiler() * The covered fraction information in \p sc is initialized to * \ref CFRAC_NONE. */ -void -SelectionCompiler::compile(SelectionCollection *coll) +void SelectionCompiler::compile(SelectionCollection* coll) { - gmx_ana_selcollection_t *sc = &coll->impl_->sc_; + gmx_ana_selcollection_t* sc = &coll->impl_->sc_; gmx_sel_evaluate_t evaldata; SelectionTreeElementPointer item; e_poscalc_t post; size_t i; int flags; - bool bDebug = (coll->impl_->debugLevel_ >= 2 - && coll->impl_->debugLevel_ != 3); + bool bDebug = (coll->impl_->debugLevel_ >= 2 && coll->impl_->debugLevel_ != 3); /* FIXME: Clean up the collection on exceptions */ sc->mempool = _gmx_sel_mempool_create(); - _gmx_sel_evaluate_init(&evaldata, sc->mempool, &sc->gall, - sc->top, nullptr, nullptr); + _gmx_sel_evaluate_init(&evaldata, sc->mempool, &sc->gall, sc->top, nullptr, nullptr); /* Clear the symbol table because it is not possible to parse anything * after compilation, and variable references in the symbol table can @@ -2736,11 +2625,9 @@ SelectionCompiler::compile(SelectionCollection *coll) */ for (i = 0; i < sc->sel.size(); ++i) { - gmx::internal::SelectionData &sel = *sc->sel[i]; - init_pos_keyword_defaults(&sel.rootElement(), - coll->impl_->spost_.c_str(), - coll->impl_->rpost_.c_str(), - &sel); + gmx::internal::SelectionData& sel = *sc->sel[i]; + init_pos_keyword_defaults(&sel.rootElement(), coll->impl_->spost_.c_str(), + coll->impl_->rpost_.c_str(), &sel); } /* Remove any unused variables. */ @@ -2894,8 +2781,7 @@ SelectionCompiler::compile(SelectionCollection *coll) // compilation. /* By default, use whole residues/molecules. */ flags = POS_COMPLWHOLE; - PositionCalculationCollection::typeFromEnum(coll->impl_->rpost_.c_str(), - &post, &flags); + PositionCalculationCollection::typeFromEnum(coll->impl_->rpost_.c_str(), &post, &flags); item = sc->root; while (item) { diff --git a/src/gromacs/selection/compiler.h b/src/gromacs/selection/compiler.h index 2988722351..08ff2c51a6 100644 --- a/src/gromacs/selection/compiler.h +++ b/src/gromacs/selection/compiler.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2013, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,12 +61,12 @@ class SelectionCollection; */ class SelectionCompiler { - public: - //! Creates a selection compiler. - SelectionCompiler(); +public: + //! Creates a selection compiler. + SelectionCompiler(); - //! Compiles the given selection collection. - void compile(SelectionCollection *coll); + //! Compiles the given selection collection. + void compile(SelectionCollection* coll); }; } // namespace gmx diff --git a/src/gromacs/selection/evaluate.cpp b/src/gromacs/selection/evaluate.cpp index 59a4aa27f3..a182c4988b 100644 --- a/src/gromacs/selection/evaluate.cpp +++ b/src/gromacs/selection/evaluate.cpp @@ -88,51 +88,50 @@ namespace */ class MempoolSelelemReserver { - public: - //! Constructs a reserver without initial reservation. - MempoolSelelemReserver() {} - /*! \brief - * Constructs a reserver with initial reservation. - * - * \param[in,out] sel Selection element for which to reserve. - * \param[in] count Number of values to reserve. - * - * \see reserve() - */ - MempoolSelelemReserver(const SelectionTreeElementPointer &sel, int count) - { - reserve(sel, count); - } - //! Frees any memory allocated using this reserver. - ~MempoolSelelemReserver() +public: + //! Constructs a reserver without initial reservation. + MempoolSelelemReserver() {} + /*! \brief + * Constructs a reserver with initial reservation. + * + * \param[in,out] sel Selection element for which to reserve. + * \param[in] count Number of values to reserve. + * + * \see reserve() + */ + MempoolSelelemReserver(const SelectionTreeElementPointer& sel, int count) + { + reserve(sel, count); + } + //! Frees any memory allocated using this reserver. + ~MempoolSelelemReserver() + { + if (sel_) { - if (sel_) - { - sel_->mempoolRelease(); - } + sel_->mempoolRelease(); } + } - /*! \brief - * Reserves memory for selection element values using this reserver. - * - * \param[in,out] sel Selection element for which to reserve. - * \param[in] count Number of values to reserve. - * - * Allocates space to store \p count output values in \p sel from the - * memory pool associated with \p sel, or from the heap if there is no - * memory pool. Type of values to allocate is automatically determined - * from \p sel. - */ - void reserve(const SelectionTreeElementPointer &sel, int count) - { - GMX_RELEASE_ASSERT(!sel_, - "Can only reserve one element with one instance"); - sel->mempoolReserve(count); - sel_ = sel; - } + /*! \brief + * Reserves memory for selection element values using this reserver. + * + * \param[in,out] sel Selection element for which to reserve. + * \param[in] count Number of values to reserve. + * + * Allocates space to store \p count output values in \p sel from the + * memory pool associated with \p sel, or from the heap if there is no + * memory pool. Type of values to allocate is automatically determined + * from \p sel. + */ + void reserve(const SelectionTreeElementPointer& sel, int count) + { + GMX_RELEASE_ASSERT(!sel_, "Can only reserve one element with one instance"); + sel->mempoolReserve(count); + sel_ = sel; + } - private: - SelectionTreeElementPointer sel_; +private: + SelectionTreeElementPointer sel_; }; /*! \brief @@ -145,44 +144,41 @@ class MempoolSelelemReserver */ class MempoolGroupReserver { - public: - /*! \brief - * Creates a reserver associated with a given memory pool. - * - * \param mp Memory pool from which to reserve memory. - */ - explicit MempoolGroupReserver(gmx_sel_mempool_t *mp) - : mp_(mp), g_(nullptr) +public: + /*! \brief + * Creates a reserver associated with a given memory pool. + * + * \param mp Memory pool from which to reserve memory. + */ + explicit MempoolGroupReserver(gmx_sel_mempool_t* mp) : mp_(mp), g_(nullptr) {} + //! Frees any memory allocated using this reserver. + ~MempoolGroupReserver() + { + if (g_ != nullptr) { + _gmx_sel_mempool_free_group(mp_, g_); } - //! Frees any memory allocated using this reserver. - ~MempoolGroupReserver() - { - if (g_ != nullptr) - { - _gmx_sel_mempool_free_group(mp_, g_); - } - } + } - /*! \brief - * Reserves memory for an index group using this reserver. - * - * \param[in,out] g Index group to reserve. - * \param[in] count Number of atoms to reserve space for. - * - * Allocates memory from the memory pool to store \p count atoms in - * \p g. - */ - void reserve(gmx_ana_index_t *g, int count) - { - GMX_RELEASE_ASSERT(g_ == nullptr, "Can only reserve one element with one instance"); - _gmx_sel_mempool_alloc_group(mp_, g, count); - g_ = g; - } + /*! \brief + * Reserves memory for an index group using this reserver. + * + * \param[in,out] g Index group to reserve. + * \param[in] count Number of atoms to reserve space for. + * + * Allocates memory from the memory pool to store \p count atoms in + * \p g. + */ + void reserve(gmx_ana_index_t* g, int count) + { + GMX_RELEASE_ASSERT(g_ == nullptr, "Can only reserve one element with one instance"); + _gmx_sel_mempool_alloc_group(mp_, g, count); + g_ = g; + } - private: - gmx_sel_mempool_t *mp_; - gmx_ana_index_t *g_; +private: + gmx_sel_mempool_t* mp_; + gmx_ana_index_t* g_; }; /*! \brief @@ -195,60 +191,53 @@ class MempoolGroupReserver */ class SelelemTemporaryValueAssigner { - public: - //! Constructs an assigner without an initial assignment. - SelelemTemporaryValueAssigner() - : old_ptr_(nullptr), old_nalloc_(0) - { - } - /*! \brief - * Constructs an assigner with an initial assignment. - * - * \param[in,out] sel Selection element for which to assign. - * \param[in] vsource Element to which \p sel values will point to. - * - * \see assign() - */ - SelelemTemporaryValueAssigner(const SelectionTreeElementPointer &sel, - const SelectionTreeElement &vsource) +public: + //! Constructs an assigner without an initial assignment. + SelelemTemporaryValueAssigner() : old_ptr_(nullptr), old_nalloc_(0) {} + /*! \brief + * Constructs an assigner with an initial assignment. + * + * \param[in,out] sel Selection element for which to assign. + * \param[in] vsource Element to which \p sel values will point to. + * + * \see assign() + */ + SelelemTemporaryValueAssigner(const SelectionTreeElementPointer& sel, const SelectionTreeElement& vsource) + { + assign(sel, vsource); + } + //! Undoes any temporary assignment done using this assigner. + ~SelelemTemporaryValueAssigner() + { + if (sel_) { - assign(sel, vsource); - } - //! Undoes any temporary assignment done using this assigner. - ~SelelemTemporaryValueAssigner() - { - if (sel_) - { - _gmx_selvalue_setstore_alloc(&sel_->v, old_ptr_, old_nalloc_); - } + _gmx_selvalue_setstore_alloc(&sel_->v, old_ptr_, old_nalloc_); } + } - /*! \brief - * Assigns a temporary value pointer. - * - * \param[in,out] sel Selection element for which to assign. - * \param[in] vsource Element to which \p sel values will point to. - * - * Assigns the value pointer in \p sel to point to the values in - * \p vsource, i.e., any access/modification to values in \p sel - * actually accesses values in \p vsource. - */ - void assign(const SelectionTreeElementPointer &sel, - const SelectionTreeElement &vsource) - { - GMX_RELEASE_ASSERT(!sel_, - "Can only assign one element with one instance"); - GMX_RELEASE_ASSERT(sel->v.type == vsource.v.type, - "Mismatching selection value types"); - _gmx_selvalue_getstore_and_release(&sel->v, &old_ptr_, &old_nalloc_); - _gmx_selvalue_setstore(&sel->v, vsource.v.u.ptr); - sel_ = sel; - } + /*! \brief + * Assigns a temporary value pointer. + * + * \param[in,out] sel Selection element for which to assign. + * \param[in] vsource Element to which \p sel values will point to. + * + * Assigns the value pointer in \p sel to point to the values in + * \p vsource, i.e., any access/modification to values in \p sel + * actually accesses values in \p vsource. + */ + void assign(const SelectionTreeElementPointer& sel, const SelectionTreeElement& vsource) + { + GMX_RELEASE_ASSERT(!sel_, "Can only assign one element with one instance"); + GMX_RELEASE_ASSERT(sel->v.type == vsource.v.type, "Mismatching selection value types"); + _gmx_selvalue_getstore_and_release(&sel->v, &old_ptr_, &old_nalloc_); + _gmx_selvalue_setstore(&sel->v, vsource.v.u.ptr); + sel_ = sel; + } - private: - SelectionTreeElementPointer sel_; - void *old_ptr_; - int old_nalloc_; +private: + SelectionTreeElementPointer sel_; + void* old_ptr_; + int old_nalloc_; }; /*! \brief @@ -267,8 +256,8 @@ class SelelemTemporaryValueAssigner * * Does not throw. */ -template -void expandValueForPositions(T value[], int *nr, gmx_ana_pos_t *pos) +template +void expandValueForPositions(T value[], int* nr, gmx_ana_pos_t* pos) { GMX_RELEASE_ASSERT(*nr == pos->count(), "Position update method did not return the correct number of values"); @@ -281,8 +270,7 @@ void expandValueForPositions(T value[], int *nr, gmx_ana_pos_t *pos) { const int atomCount = pos->m.mapb.index[i + 1] - pos->m.mapb.index[i]; outputIndex -= atomCount; - GMX_ASSERT(outputIndex >= i, - "In-place algorithm would overwrite data not yet used"); + GMX_ASSERT(outputIndex >= i, "In-place algorithm would overwrite data not yet used"); std::fill(&value[outputIndex], &value[outputIndex + atomCount], value[i]); } } @@ -293,8 +281,7 @@ void expandValueForPositions(T value[], int *nr, gmx_ana_pos_t *pos) * \param[in] fp File handle to receive the output. * \param[in] evalfunc Function pointer to print. */ -void -_gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc) +void _gmx_sel_print_evalfunc_name(FILE* fp, gmx::sel_evalfunc evalfunc) { if (!evalfunc) { @@ -366,10 +353,12 @@ _gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc) * \param[in] fr New frame for evaluation. * \param[in] pbc New PBC information for evaluation. */ -void -_gmx_sel_evaluate_init(gmx_sel_evaluate_t *data, - gmx_sel_mempool_t *mp, gmx_ana_index_t *gall, - const gmx_mtop_t *top, t_trxframe *fr, t_pbc *pbc) +void _gmx_sel_evaluate_init(gmx_sel_evaluate_t* data, + gmx_sel_mempool_t* mp, + gmx_ana_index_t* gall, + const gmx_mtop_t* top, + t_trxframe* fr, + t_pbc* pbc) { data->mp = mp; data->gall = gall; @@ -389,8 +378,7 @@ _gmx_sel_evaluate_init(gmx_sel_evaluate_t *data, * * The \ref SEL_EVALFRAME flag is cleared for all elements. */ -static void -init_frame_eval(SelectionTreeElementPointer sel) +static void init_frame_eval(SelectionTreeElementPointer sel) { while (sel) { @@ -413,9 +401,7 @@ init_frame_eval(SelectionTreeElementPointer sel) namespace gmx { -SelectionEvaluator::SelectionEvaluator() -{ -} +SelectionEvaluator::SelectionEvaluator() {} /*! * \param[in,out] coll The selection collection to evaluate. @@ -431,11 +417,9 @@ SelectionEvaluator::SelectionEvaluator() * This is the only function that user code should call if they want to * evaluate a selection for a new frame. */ -void -SelectionEvaluator::evaluate(SelectionCollection *coll, - t_trxframe *fr, t_pbc *pbc) +void SelectionEvaluator::evaluate(SelectionCollection* coll, t_trxframe* fr, t_pbc* pbc) { - gmx_ana_selcollection_t *sc = &coll->impl_->sc_; + gmx_ana_selcollection_t* sc = &coll->impl_->sc_; gmx_sel_evaluate_t data; _gmx_sel_evaluate_init(&data, sc->mempool, &sc->gall, sc->top, fr, pbc); @@ -444,8 +428,7 @@ SelectionEvaluator::evaluate(SelectionCollection *coll, while (sel) { /* Clear the evaluation group of subexpressions */ - if (sel->child && sel->child->type == SEL_SUBEXPR - && sel->child->evaluate != nullptr) + if (sel->child && sel->child->type == SEL_SUBEXPR && sel->child->evaluate != nullptr) { sel->child->u.cgrp.isize = 0; /* Not strictly necessary, because the value will be overwritten @@ -469,7 +452,7 @@ SelectionEvaluator::evaluate(SelectionCollection *coll, SelectionDataList::const_iterator isel; for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel) { - internal::SelectionData &sel = **isel; + internal::SelectionData& sel = **isel; sel.refreshMassesAndCharges(sc->top); sel.updateCoveredFractionForFrame(); } @@ -479,15 +462,14 @@ SelectionEvaluator::evaluate(SelectionCollection *coll, * \param[in,out] coll The selection collection to evaluate. * \param[in] nframes Total number of frames. */ -void -SelectionEvaluator::evaluateFinal(SelectionCollection *coll, int nframes) +void SelectionEvaluator::evaluateFinal(SelectionCollection* coll, int nframes) { - gmx_ana_selcollection_t *sc = &coll->impl_->sc_; + gmx_ana_selcollection_t* sc = &coll->impl_->sc_; SelectionDataList::const_iterator isel; for (isel = sc->sel.begin(); isel != sc->sel.end(); ++isel) { - internal::SelectionData &sel = **isel; + internal::SelectionData& sel = **isel; sel.restoreOriginalPositions(sc->top); sel.computeAverageCoveredFraction(nframes); } @@ -503,10 +485,9 @@ SelectionEvaluator::evaluateFinal(SelectionCollection *coll, int nframes) * * Evaluates each child of \p sel in \p g. */ -void -_gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_children(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { SelectionTreeElementPointer child = sel->child; while (child) @@ -519,24 +500,21 @@ _gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, } } -void -_gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t * /* g */) +void _gmx_sel_evaluate_root(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* /* g */) { if (sel->u.cgrp.isize == 0 || !sel->child->evaluate) { return; } - sel->child->evaluate(data, sel->child, - sel->u.cgrp.isize < 0 ? nullptr : &sel->u.cgrp); + sel->child->evaluate(data, sel->child, sel->u.cgrp.isize < 0 ? nullptr : &sel->u.cgrp); } -void -_gmx_sel_evaluate_static(gmx_sel_evaluate_t * /* data */, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_static(gmx_sel_evaluate_t* /* data */, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { if (sel->flags & SEL_UNSORTED) { @@ -569,10 +547,9 @@ _gmx_sel_evaluate_static(gmx_sel_evaluate_t * /* data */, * \ref SEL_SUBEXPR elements that are used only once, and hence do not need * full subexpression handling. */ -void -_gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { if (sel->child->evaluate) { @@ -597,10 +574,9 @@ _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, * \ref SEL_SUBEXPR elements that have a static evaluation group, and hence do * not need full subexpression handling. */ -void -_gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { if (sel->u.cgrp.isize == 0) { @@ -637,12 +613,11 @@ _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *dat * _gmx_sel_evaluate_subexpr_staticeval() can be used, so this should not be a * major problem. */ -void -_gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { - gmx_ana_index_t gmiss; + gmx_ana_index_t gmiss; MempoolGroupReserver gmissreserver(data->mp); if (sel->u.cgrp.isize == 0) @@ -652,7 +627,7 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, sel->child->evaluate(data, sel->child, g); } gmx_ana_index_copy(&sel->u.cgrp, g, false); - gmiss.isize = 0; + gmiss.isize = 0; } else { @@ -671,7 +646,7 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, } else { - int i, j, k; + int i, j, k; i = sel->u.cgrp.isize - 1; j = gmiss.isize - 1; @@ -725,11 +700,11 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, case POS_VALUE: /* TODO: Implement this */ - GMX_THROW(gmx::NotImplementedError("position subexpressions not implemented properly")); + GMX_THROW(gmx::NotImplementedError( + "position subexpressions not implemented properly")); case NO_VALUE: - case GROUP_VALUE: - GMX_THROW(gmx::InternalError("Invalid subexpression type")); + case GROUP_VALUE: GMX_THROW(gmx::InternalError("Invalid subexpression type")); } } gmx_ana_index_merge(&sel->u.cgrp, &sel->u.cgrp, &gmiss); @@ -750,16 +725,14 @@ _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, * \ref SEL_SUBEXPRREF elements for which the \ref SEL_SUBEXPR does not have * other references. */ -void -_gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { if (g) { _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr); - _gmx_selvalue_setstore_alloc(&sel->child->child->v, sel->v.u.ptr, - sel->child->child->v.nalloc); + _gmx_selvalue_setstore_alloc(&sel->child->child->v, sel->v.u.ptr, sel->child->child->v.nalloc); sel->child->evaluate(data, sel->child, g); } sel->v.nr = sel->child->v.nr; @@ -789,25 +762,24 @@ _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_SUBEXPRREF elements. */ -void -_gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { - int i, j; + int i, j; if (g != nullptr && sel->child->evaluate != nullptr) { sel->child->evaluate(data, sel->child, g); } - const SelectionTreeElementPointer &expr = sel->child; + const SelectionTreeElementPointer& expr = sel->child; switch (sel->v.type) { case INT_VALUE: if (!g) { sel->v.nr = expr->v.nr; - memcpy(sel->v.u.i, expr->v.u.i, sel->v.nr*sizeof(*sel->v.u.i)); + memcpy(sel->v.u.i, expr->v.u.i, sel->v.nr * sizeof(*sel->v.u.i)); } else { @@ -828,7 +800,7 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, if (!g) { sel->v.nr = expr->v.nr; - memcpy(sel->v.u.r, expr->v.u.r, sel->v.nr*sizeof(*sel->v.u.r)); + memcpy(sel->v.u.r, expr->v.u.r, sel->v.nr * sizeof(*sel->v.u.r)); } else { @@ -849,7 +821,7 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, if (!g) { sel->v.nr = expr->v.nr; - memcpy(sel->v.u.s, expr->v.u.s, sel->v.nr*sizeof(*sel->v.u.s)); + memcpy(sel->v.u.s, expr->v.u.s, sel->v.nr * sizeof(*sel->v.u.s)); } else { @@ -914,10 +886,9 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, * This function is not used as gmx::SelectionTreeElement::evaluate, * but is used internally. */ -void -_gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { SelectionTreeElementPointer child = sel->child; while (child) @@ -955,10 +926,9 @@ _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_EXPRESSION elements. */ -void -_gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_method(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { _gmx_sel_evaluate_method_params(data, sel, g); gmx::SelMethodEvalContext context(data->top, data->fr, data->pbc); @@ -969,20 +939,18 @@ _gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, } if (sel->u.expr.pc) { - gmx_ana_poscalc_update(sel->u.expr.pc, sel->u.expr.pos, g, - data->fr, data->pbc); - sel->u.expr.method->pupdate(context, sel->u.expr.pos, &sel->v, - sel->u.expr.mdata); + gmx_ana_poscalc_update(sel->u.expr.pc, sel->u.expr.pos, g, data->fr, data->pbc); + sel->u.expr.method->pupdate(context, sel->u.expr.pos, &sel->v, sel->u.expr.mdata); if ((sel->flags & SEL_ATOMVAL) && sel->v.nr < g->isize) { switch (sel->v.type) { case REAL_VALUE: - expandValueForPositions(sel->v.u.r, &sel->v.nr, - sel->u.expr.pos); + expandValueForPositions(sel->v.u.r, &sel->v.nr, sel->u.expr.pos); break; default: - GMX_RELEASE_ASSERT(false, "Unimplemented value type for position update method"); + GMX_RELEASE_ASSERT(false, + "Unimplemented value type for position update method"); } } } @@ -1007,10 +975,9 @@ _gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_MODIFIER elements. */ -void -_gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { _gmx_sel_evaluate_method_params(data, sel, g); gmx::SelMethodEvalContext context(data->top, data->fr, data->pbc); @@ -1044,10 +1011,9 @@ _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_BOOLEAN elements with \ref BOOL_NOT. */ -void -_gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_not(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { MempoolSelelemReserver reserver(sel->child, g->isize); sel->child->evaluate(data, sel->child, g); @@ -1079,10 +1045,9 @@ _gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_BOOLEAN elements with \ref BOOL_AND. */ -void -_gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_and(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { SelectionTreeElementPointer child = sel->child; /* Skip the first child if it does not have an evaluation function. */ @@ -1132,12 +1097,11 @@ _gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, * This function is used as gmx::SelectionTreeElement::evaluate for * \ref SEL_BOOLEAN elements with \ref BOOL_OR. */ -void -_gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_or(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { - gmx_ana_index_t tmp, tmp2; + gmx_ana_index_t tmp, tmp2; SelectionTreeElementPointer child = sel->child; if (child->evaluate) @@ -1159,9 +1123,9 @@ _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, gmx_ana_index_partition(&tmp, &tmp2, &tmp, child->v.u.g); } sel->v.u.g->isize += tmp.isize; - tmp.isize = tmp2.isize; - tmp.index = tmp2.index; - child = child->next; + tmp.isize = tmp2.isize; + tmp.index = tmp2.index; + child = child->next; } gmx_ana_index_sort(sel->v.u.g); } @@ -1177,19 +1141,18 @@ _gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, * \param[in] g Group for which \p sel should be evaluated. * \returns 0 on success, a non-zero error code on error. */ -void -_gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g) +void _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g) { - int n, i, i1, i2; - real lval, rval = 0., val = 0.; + int n, i, i1, i2; + real lval, rval = 0., val = 0.; - const SelectionTreeElementPointer &left = sel->child; - const SelectionTreeElementPointer &right = left->next; + const SelectionTreeElementPointer& left = sel->child; + const SelectionTreeElementPointer& right = left->next; - SelelemTemporaryValueAssigner assigner; - MempoolSelelemReserver reserver; + SelelemTemporaryValueAssigner assigner; + MempoolSelelemReserver reserver; if (left->mempool) { assigner.assign(left, *sel); @@ -1208,8 +1171,7 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, sel->v.nr = n; bool bArithNeg = (sel->u.arith.type == ARITH_NEG); - GMX_ASSERT(right || bArithNeg, - "Right operand cannot be null except for negations"); + GMX_ASSERT(right || bArithNeg, "Right operand cannot be null except for negations"); for (i = i1 = i2 = 0; i < n; ++i) { lval = left->v.u.r[i1]; @@ -1219,12 +1181,12 @@ _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, } switch (sel->u.arith.type) { - case ARITH_PLUS: val = lval + rval; break; - case ARITH_MINUS: val = lval - rval; break; - case ARITH_NEG: val = -lval; break; - case ARITH_MULT: val = lval * rval; break; - case ARITH_DIV: val = lval / rval; break; - case ARITH_EXP: val = pow(lval, rval); break; + case ARITH_PLUS: val = lval + rval; break; + case ARITH_MINUS: val = lval - rval; break; + case ARITH_NEG: val = -lval; break; + case ARITH_MULT: val = lval * rval; break; + case ARITH_DIV: val = lval / rval; break; + case ARITH_EXP: val = pow(lval, rval); break; } sel->v.u.r[i] = val; if (!(left->flags & SEL_SINGLEVAL)) diff --git a/src/gromacs/selection/evaluate.h b/src/gromacs/selection/evaluate.h index e2135e2ca2..61291f97e8 100644 --- a/src/gromacs/selection/evaluate.h +++ b/src/gromacs/selection/evaluate.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2016, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,35 +63,35 @@ struct t_trxframe; struct gmx_sel_evaluate_t { /** Memory pool for intermediate values. */ - gmx_sel_mempool_t *mp; + gmx_sel_mempool_t* mp; /** Index group that contains all the atoms. */ - gmx_ana_index_t *gall; + gmx_ana_index_t* gall; /** Topology information. */ - const gmx_mtop_t *top; + const gmx_mtop_t* top; /** Current frame. */ - t_trxframe *fr; + t_trxframe* fr; /** PBC data. */ - t_pbc *pbc; + t_pbc* pbc; }; /*! \name Utility functions */ /*@{*/ /** Initializes an evaluation data structure. */ -void -_gmx_sel_evaluate_init(gmx_sel_evaluate_t *data, - gmx_sel_mempool_t *mp, gmx_ana_index_t *gall, - const gmx_mtop_t *top, t_trxframe *fr, t_pbc *pbc); +void _gmx_sel_evaluate_init(gmx_sel_evaluate_t* data, + gmx_sel_mempool_t* mp, + gmx_ana_index_t* gall, + const gmx_mtop_t* top, + t_trxframe* fr, + t_pbc* pbc); /** Evaluates the children of a general selection element. */ -void -_gmx_sel_evaluate_children(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_children(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates the children of a \ref SEL_EXPRESSION element. */ -void -_gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*@}*/ /*! \name Misc. evaluation functions @@ -114,10 +114,9 @@ _gmx_sel_evaluate_method_params(gmx_sel_evaluate_t *data, * This function can be used as gmx::SelectionTreeElement::evaluate for * \ref SEL_ROOT elements. */ -void -_gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_root(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*! \brief * Evaluates a static group selection element. * @@ -131,45 +130,38 @@ _gmx_sel_evaluate_root(gmx_sel_evaluate_t *data, * This function can be used as gmx::SelectionTreeElement::evaluate for * \ref SEL_CONST elements with value type \ref GROUP_VALUE. */ -void -_gmx_sel_evaluate_static(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_static(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates an arithmetic expression element. */ -void -_gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_arithmetic(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*@}*/ /*! \name Subexpression evaluation functions */ /*@{*/ /** Evaluates a subexpression when there is only one reference. */ -void -_gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_subexpr_simple(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a subexpression when the evaluation group is static. */ -void -_gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_subexpr_staticeval(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a subexpression. */ -void -_gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a subexpression reference when there are no other references. */ -void -_gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a subexpression reference. */ -void -_gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*@}*/ /*! \name Method evaluation functions @@ -177,35 +169,30 @@ _gmx_sel_evaluate_subexprref(gmx_sel_evaluate_t *data, /*@{*/ /** Evaluates a method expression. */ -void -_gmx_sel_evaluate_method(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_method(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a modifier expression. */ -void -_gmx_sel_evaluate_modifier(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_modifier(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*@}*/ /*! \name Boolean evaluation functions */ /*@{*/ /** Evaluates a boolean NOT element. */ -void -_gmx_sel_evaluate_not(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_not(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a boolean AND element with short-circuiting. */ -void -_gmx_sel_evaluate_and(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_and(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /** Evaluates a boolean OR element with short-circuiting. */ -void -_gmx_sel_evaluate_or(gmx_sel_evaluate_t *data, - const gmx::SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +void _gmx_sel_evaluate_or(gmx_sel_evaluate_t* data, + const gmx::SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); /*@}*/ #endif diff --git a/src/gromacs/selection/indexutil.cpp b/src/gromacs/selection/indexutil.cpp index 5f5989a8bf..b79f2cfebc 100644 --- a/src/gromacs/selection/indexutil.cpp +++ b/src/gromacs/selection/indexutil.cpp @@ -65,40 +65,44 @@ namespace gmx { -IndexGroupsAndNames::IndexGroupsAndNames( - const t_blocka &indexGroup, ArrayRef groupNames) - : indexGroup_ {indexGroup} +IndexGroupsAndNames::IndexGroupsAndNames(const t_blocka& indexGroup, ArrayRef groupNames) : + indexGroup_{ indexGroup } { std::copy(groupNames.begin(), groupNames.end(), std::back_inserter(groupNames_)); GMX_ASSERT(indexGroup_.nr == ssize(groupNames), "Number of groups must match number of group names."); } -bool IndexGroupsAndNames::containsGroupName(const std::string &groupName) const +bool IndexGroupsAndNames::containsGroupName(const std::string& groupName) const { - return std::any_of(std::begin(groupNames_), std::end(groupNames_), - [&groupName](const std::string &name){return equalCaseInsensitive(groupName, name); }); + return std::any_of( + std::begin(groupNames_), std::end(groupNames_), + [&groupName](const std::string& name) { return equalCaseInsensitive(groupName, name); }); } -std::vector IndexGroupsAndNames::indices(const std::string &groupName) const +std::vector IndexGroupsAndNames::indices(const std::string& groupName) const { if (!containsGroupName(groupName)) { - GMX_THROW(InconsistentInputError(std::string("Group ") + groupName + - " referenced in the .mdp file was not found in the index file.\n" - "Group names must match either [moleculetype] names or custom index group\n" - "names, in which case you must supply an index file to the '-n' option\n" - "of grompp.")); - } - const auto groupNamePosition = std::find_if(std::begin(groupNames_), std::end(groupNames_), - [&groupName](const std::string &name){return equalCaseInsensitive(groupName, name); }); - const auto groupIndex = std::distance(std::begin(groupNames_), groupNamePosition); - const auto groupSize = indexGroup_.index[groupIndex+1] - indexGroup_.index[groupIndex]; + GMX_THROW( + InconsistentInputError( + std::string("Group ") + groupName + + " referenced in the .mdp file was not found in the index file.\n" + "Group names must match either [moleculetype] names or custom index " + "group\n" + "names, in which case you must supply an index file to the '-n' option\n" + "of grompp.")); + } + const auto groupNamePosition = std::find_if( + std::begin(groupNames_), std::end(groupNames_), + [&groupName](const std::string& name) { return equalCaseInsensitive(groupName, name); }); + const auto groupIndex = std::distance(std::begin(groupNames_), groupNamePosition); + const auto groupSize = indexGroup_.index[groupIndex + 1] - indexGroup_.index[groupIndex]; std::vector groupIndices(groupSize); const auto startingIndex = indexGroup_.index[groupIndex]; std::iota(std::begin(groupIndices), std::end(groupIndices), startingIndex); std::transform(std::begin(groupIndices), std::end(groupIndices), std::begin(groupIndices), - [blockLookup = indexGroup_.a](auto i){return blockLookup[i]; }); + [blockLookup = indexGroup_.a](auto i) { return blockLookup[i]; }); return groupIndices; } @@ -114,14 +118,10 @@ std::vector IndexGroupsAndNames::indices(const std::string &groupName) co struct gmx_ana_indexgrps_t { //! Initializes an empty set of groups. - explicit gmx_ana_indexgrps_t(int nr) - : g(nr) - { - names.reserve(nr); - } + explicit gmx_ana_indexgrps_t(int nr) : g(nr) { names.reserve(nr); } ~gmx_ana_indexgrps_t() { - for (auto &indexGrp : g) + for (auto& indexGrp : g) { gmx_ana_index_deinit(&indexGrp); } @@ -131,7 +131,7 @@ struct gmx_ana_indexgrps_t /** Array of index groups. */ std::vector g; /** Group names. */ - std::vector names; + std::vector names; }; /*! @@ -147,12 +147,10 @@ struct gmx_ana_indexgrps_t * topology (uses Gromacs routine analyse()). * If both are null, the index group structure is initialized empty. */ -void -gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, gmx_mtop_t *top, - const char *fnm) +void gmx_ana_indexgrps_init(gmx_ana_indexgrps_t** g, gmx_mtop_t* top, const char* fnm) { - t_blocka *block = nullptr; - char **names = nullptr; + t_blocka* block = nullptr; + char** names = nullptr; if (fnm) { @@ -177,13 +175,13 @@ gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, gmx_mtop_t *top, *g = new gmx_ana_indexgrps_t(block->nr); for (int i = 0; i < block->nr; ++i) { - gmx_ana_index_t *grp = &(*g)->g[i]; + gmx_ana_index_t* grp = &(*g)->g[i]; - grp->isize = block->index[i+1] - block->index[i]; + grp->isize = block->index[i + 1] - block->index[i]; snew(grp->index, grp->isize); for (int j = 0; j < grp->isize; ++j) { - grp->index[j] = block->a[block->index[i]+j]; + grp->index[j] = block->a[block->index[i] + j]; } grp->nalloc_index = grp->isize; (*g)->names.emplace_back(names[i]); @@ -214,8 +212,7 @@ gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, gmx_mtop_t *top, * * The pointer \p g is invalid after the call. */ -void -gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g) +void gmx_ana_indexgrps_free(gmx_ana_indexgrps_t* g) { delete g; } @@ -228,9 +225,7 @@ gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g) * \param[in] n Number of the group to extract. * \returns true if \p n is a valid group in \p src, false otherwise. */ -bool -gmx_ana_indexgrps_extract(gmx_ana_index_t *dest, std::string *destName, - gmx_ana_indexgrps_t *src, int n) +bool gmx_ana_indexgrps_extract(gmx_ana_index_t* dest, std::string* destName, gmx_ana_indexgrps_t* src, int n) { destName->clear(); if (n < 0 || n >= gmx::index(src->g.size())) @@ -257,12 +252,9 @@ gmx_ana_indexgrps_extract(gmx_ana_index_t *dest, std::string *destName, * Uses the Gromacs routine find_group() to find the actual group; * the comparison is case-insensitive. */ -bool -gmx_ana_indexgrps_find(gmx_ana_index_t *dest, std::string *destName, - gmx_ana_indexgrps_t *src, - const char *name) +bool gmx_ana_indexgrps_find(gmx_ana_index_t* dest, std::string* destName, gmx_ana_indexgrps_t* src, const char* name) { - const char **names; + const char** names; destName->clear(); snew(names, src->g.size()); @@ -270,8 +262,7 @@ gmx_ana_indexgrps_find(gmx_ana_index_t *dest, std::string *destName, { names[i] = src->names[i].c_str(); } - int n = find_group(const_cast(name), src->g.size(), - const_cast(names)); + int n = find_group(const_cast(name), src->g.size(), const_cast(names)); sfree(names); if (n < 0) { @@ -288,13 +279,11 @@ gmx_ana_indexgrps_find(gmx_ana_index_t *dest, std::string *destName, * \param[in] maxn Maximum number of indices to print * (-1 = print all, 0 = print only names). */ -void -gmx_ana_indexgrps_print(gmx::TextWriter *writer, gmx_ana_indexgrps_t *g, int maxn) +void gmx_ana_indexgrps_print(gmx::TextWriter* writer, gmx_ana_indexgrps_t* g, int maxn) { for (gmx::index i = 0; i < gmx::ssize(g->g); ++i) { - writer->writeString(gmx::formatString(" Group %2zd \"%s\" ", - i, g->names[i].c_str())); + writer->writeString(gmx::formatString(" Group %2zd \"%s\" ", i, g->names[i].c_str())); gmx_ana_index_dump(writer, &g->g[i], maxn); } } @@ -307,8 +296,7 @@ gmx_ana_indexgrps_print(gmx::TextWriter *writer, gmx_ana_indexgrps_t *g, int max * \param[in,out] g Index group structure. * \param[in] isize Maximum number of atoms to reserve space for. */ -void -gmx_ana_index_reserve(gmx_ana_index_t *g, int isize) +void gmx_ana_index_reserve(gmx_ana_index_t* g, int isize) { if (g->nalloc_index < isize) { @@ -323,8 +311,7 @@ gmx_ana_index_reserve(gmx_ana_index_t *g, int isize) * Resizes the memory allocated for holding the indices such that the * current contents fit. */ -void -gmx_ana_index_squeeze(gmx_ana_index_t *g) +void gmx_ana_index_squeeze(gmx_ana_index_t* g) { srenew(g->index, g->isize); g->nalloc_index = g->isize; @@ -335,8 +322,7 @@ gmx_ana_index_squeeze(gmx_ana_index_t *g) * * Any contents of \p g are discarded without freeing. */ -void -gmx_ana_index_clear(gmx_ana_index_t *g) +void gmx_ana_index_clear(gmx_ana_index_t* g) { g->isize = 0; g->index = nullptr; @@ -352,8 +338,7 @@ gmx_ana_index_clear(gmx_ana_index_t *g) * * No copy if \p index is made. */ -void -gmx_ana_index_set(gmx_ana_index_t *g, int isize, int *index, int nalloc) +void gmx_ana_index_set(gmx_ana_index_t* g, int isize, int* index, int nalloc) { g->isize = isize; g->index = index; @@ -364,10 +349,9 @@ gmx_ana_index_set(gmx_ana_index_t *g, int isize, int *index, int nalloc) * \param[out] g Output structure. * \param[in] natoms Number of atoms. */ -void -gmx_ana_index_init_simple(gmx_ana_index_t *g, int natoms) +void gmx_ana_index_init_simple(gmx_ana_index_t* g, int natoms) { - int i; + int i; g->isize = natoms; snew(g->index, natoms); @@ -383,8 +367,7 @@ gmx_ana_index_init_simple(gmx_ana_index_t *g, int natoms) * * The pointer \p g is not freed. */ -void -gmx_ana_index_deinit(gmx_ana_index_t *g) +void gmx_ana_index_deinit(gmx_ana_index_t* g) { if (g->nalloc_index > 0) { @@ -399,8 +382,7 @@ gmx_ana_index_deinit(gmx_ana_index_t *g) * \param[in] bAlloc If true, memory is allocated at \p dest; otherwise, * it is assumed that enough memory has been allocated for index. */ -void -gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc) +void gmx_ana_index_copy(gmx_ana_index_t* dest, gmx_ana_index_t* src, bool bAlloc) { dest->isize = src->isize; if (bAlloc) @@ -410,7 +392,7 @@ gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc) } if (dest->isize > 0) { - std::memcpy(dest->index, src->index, dest->isize*sizeof(*dest->index)); + std::memcpy(dest->index, src->index, dest->isize * sizeof(*dest->index)); } } @@ -419,8 +401,7 @@ gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc) * \param[in] g Index group to print. * \param[in] maxn Maximum number of indices to print (-1 = print all). */ -void -gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn) +void gmx_ana_index_dump(gmx::TextWriter* writer, gmx_ana_index_t* g, int maxn) { writer->writeString(gmx::formatString("(%d atoms)", g->isize)); if (maxn != 0) @@ -433,7 +414,7 @@ gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn) } for (int j = 0; j < n; ++j) { - writer->writeString(gmx::formatString(" %d", g->index[j]+1)); + writer->writeString(gmx::formatString(" %d", g->index[j] + 1)); } if (n < g->isize) { @@ -443,8 +424,7 @@ gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn) writer->ensureLineBreak(); } -int -gmx_ana_index_get_max_index(gmx_ana_index_t *g) +int gmx_ana_index_get_max_index(gmx_ana_index_t* g) { if (g->isize == 0) { @@ -461,14 +441,13 @@ gmx_ana_index_get_max_index(gmx_ana_index_t *g) * \returns true if the index group is sorted and has no duplicates, * false otherwise. */ -bool -gmx_ana_index_check_sorted(gmx_ana_index_t *g) +bool gmx_ana_index_check_sorted(gmx_ana_index_t* g) { - int i; + int i; - for (i = 0; i < g->isize-1; ++i) + for (i = 0; i < g->isize - 1; ++i) { - if (g->index[i+1] <= g->index[i]) + if (g->index[i + 1] <= g->index[i]) { return false; } @@ -476,8 +455,7 @@ gmx_ana_index_check_sorted(gmx_ana_index_t *g) return true; } -bool -gmx_ana_index_check_range(gmx_ana_index_t *g, int natoms) +bool gmx_ana_index_check_range(gmx_ana_index_t* g, int natoms) { for (int i = 0; i < g->isize; ++i) { @@ -496,19 +474,17 @@ gmx_ana_index_check_range(gmx_ana_index_t *g, int natoms) /*! * \param[in,out] g Index group to be sorted. */ -void -gmx_ana_index_sort(gmx_ana_index_t *g) +void gmx_ana_index_sort(gmx_ana_index_t* g) { - std::sort(g->index, g->index+g->isize); + std::sort(g->index, g->index + g->isize); } -void -gmx_ana_index_remove_duplicates(gmx_ana_index_t *g) +void gmx_ana_index_remove_duplicates(gmx_ana_index_t* g) { int j = 0; for (int i = 0; i < g->isize; ++i) { - if (i == 0 || g->index[i-1] != g->index[i]) + if (i == 0 || g->index[i - 1] != g->index[i]) { g->index[j] = g->index[i]; ++j; @@ -522,10 +498,9 @@ gmx_ana_index_remove_duplicates(gmx_ana_index_t *g) * \param[in] b Index group to check. * \returns true if \p a and \p b are equal, false otherwise. */ -bool -gmx_ana_index_equals(gmx_ana_index_t *a, gmx_ana_index_t *b) +bool gmx_ana_index_equals(gmx_ana_index_t* a, gmx_ana_index_t* b) { - int i; + int i; if (a->isize != b->isize) { @@ -550,10 +525,9 @@ gmx_ana_index_equals(gmx_ana_index_t *a, gmx_ana_index_t *b) * If the elements are not in the same order in both groups, the function * fails. However, the groups do not need to be sorted. */ -bool -gmx_ana_index_contains(gmx_ana_index_t *a, gmx_ana_index_t *b) +bool gmx_ana_index_contains(gmx_ana_index_t* a, gmx_ana_index_t* b) { - int i, j; + int i, j; for (i = j = 0; j < b->isize; ++i, ++j) { @@ -576,9 +550,7 @@ gmx_ana_index_contains(gmx_ana_index_t *a, gmx_ana_index_t *b) * * \p dest can be the same as \p a or \p b. */ -void -gmx_ana_index_intersection(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b) +void gmx_ana_index_intersection(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b) { int i, j, k; @@ -603,9 +575,7 @@ gmx_ana_index_intersection(gmx_ana_index_t *dest, * * \p dest can equal \p a, but not \p b. */ -void -gmx_ana_index_difference(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b) +void gmx_ana_index_difference(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b) { int i, j, k; @@ -628,8 +598,7 @@ gmx_ana_index_difference(gmx_ana_index_t *dest, * \param[in] b Second index group. * \returns Size of the difference \p a - \p b. */ -int -gmx_ana_index_difference_size(gmx_ana_index_t *a, gmx_ana_index_t *b) +int gmx_ana_index_difference_size(gmx_ana_index_t* a, gmx_ana_index_t* b) { int i, j, k; @@ -665,15 +634,13 @@ gmx_ana_index_difference_size(gmx_ana_index_t *a, gmx_ana_index_t *b) * The calculation can be performed in-place by setting \p dest1 equal to * \p src. */ -void -gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2, - gmx_ana_index_t *src, gmx_ana_index_t *g) +void gmx_ana_index_partition(gmx_ana_index_t* dest1, gmx_ana_index_t* dest2, gmx_ana_index_t* src, gmx_ana_index_t* g) { int i, j, k; dest2->index = dest1->index + g->isize; dest2->isize = src->isize - g->isize; - for (i = g->isize-1, j = src->isize-1, k = dest2->isize-1; i >= 0; --i, --j) + for (i = g->isize - 1, j = src->isize - 1, k = dest2->isize - 1; i >= 0; --i, --j) { while (j >= 0 && src->index[j] != g->index[i]) { @@ -697,9 +664,7 @@ gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2, * * \see gmx_ana_index_merge() */ -void -gmx_ana_index_union(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b) +void gmx_ana_index_union(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b) { int dsize; int i, j, k; @@ -725,9 +690,7 @@ gmx_ana_index_union(gmx_ana_index_t *dest, } } -void -gmx_ana_index_union_unsorted(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b) +void gmx_ana_index_union_unsorted(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b) { if (gmx_ana_index_check_sorted(b)) { @@ -754,9 +717,7 @@ gmx_ana_index_union_unsorted(gmx_ana_index_t *dest, * * \see gmx_ana_index_union() */ -void -gmx_ana_index_merge(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b) +void gmx_ana_index_merge(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b) { int i, j, k; @@ -795,16 +756,12 @@ gmx_ana_index_merge(gmx_ana_index_t *dest, * * \ingroup module_selection */ -static bool -next_group_index(int atomIndex, const gmx_mtop_t *top, - e_index_t type, int *id) +static bool next_group_index(int atomIndex, const gmx_mtop_t* top, e_index_t type, int* id) { int prev = *id; switch (type) { - case INDEX_ATOM: - *id = atomIndex; - break; + case INDEX_ATOM: *id = atomIndex; break; case INDEX_RES: { int resind, molb = 0; @@ -819,9 +776,7 @@ next_group_index(int atomIndex, const gmx_mtop_t *top, break; } case INDEX_UNKNOWN: - case INDEX_ALL: - *id = 0; - break; + case INDEX_ALL: *id = 0; break; } return prev != *id; } @@ -842,9 +797,7 @@ next_group_index(int atomIndex, const gmx_mtop_t *top, * \p m should have been initialized somehow (calloc() is enough). * \p g should be sorted. */ -void -gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, - e_index_t type, bool bComplete) +void gmx_ana_index_make_block(t_blocka* t, const gmx_mtop_t* top, gmx_ana_index_t* g, e_index_t type, bool bComplete) { if (type == INDEX_UNKNOWN) { @@ -888,13 +841,13 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, } else { - t->nra = g->isize; + t->nra = g->isize; if (t->nalloc_a < g->isize) { srenew(t->a, g->isize); t->nalloc_a = g->isize; } - std::memcpy(t->a, g->index, g->isize*sizeof(*(t->a))); + std::memcpy(t->a, g->index, g->isize * sizeof(*(t->a))); } /* Allocate memory for the block index. We don't know in advance @@ -906,7 +859,7 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, t->nalloc_index = g->isize + 1; } /* Clear counters */ - t->nr = 0; + t->nr = 0; int id = -1; int molb = 0; for (int i = 0; i < g->isize; ++i) @@ -926,27 +879,25 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, { case INDEX_RES: { - int molnr, atnr_mol; + int molnr, atnr_mol; mtopGetMolblockIndex(top, ai, &molb, &molnr, &atnr_mol); - const t_atoms &mol_atoms = top->moltype[top->molblock[molb].type].atoms; + const t_atoms& mol_atoms = top->moltype[top->molblock[molb].type].atoms; int last_atom = atnr_mol + 1; const int currentResid = mol_atoms.atom[atnr_mol].resind; - while (last_atom < mol_atoms.nr - && mol_atoms.atom[last_atom].resind == currentResid) + while (last_atom < mol_atoms.nr && mol_atoms.atom[last_atom].resind == currentResid) { ++last_atom; } int first_atom = atnr_mol - 1; - while (first_atom >= 0 - && mol_atoms.atom[first_atom].resind == currentResid) + while (first_atom >= 0 && mol_atoms.atom[first_atom].resind == currentResid) { --first_atom; } - const MoleculeBlockIndices &molBlock = top->moleculeBlockIndices[molb]; - int first_mol_atom = molBlock.globalAtomStart; - first_mol_atom += molnr*molBlock.numAtomsPerMolecule; - first_atom = first_mol_atom + first_atom + 1; - last_atom = first_mol_atom + last_atom - 1; + const MoleculeBlockIndices& molBlock = top->moleculeBlockIndices[molb]; + int first_mol_atom = molBlock.globalAtomStart; + first_mol_atom += molnr * molBlock.numAtomsPerMolecule; + first_atom = first_mol_atom + first_atom + 1; + last_atom = first_mol_atom + last_atom - 1; for (int j = first_atom; j <= last_atom; ++j) { t->a[t->nra++] = j; @@ -955,10 +906,12 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, } case INDEX_MOL: { - int molnr, atnr_mol; + int molnr, atnr_mol; mtopGetMolblockIndex(top, ai, &molb, &molnr, &atnr_mol); - const MoleculeBlockIndices &blockIndices = top->moleculeBlockIndices[molb]; - const int atomStart = blockIndices.globalAtomStart + (id - blockIndices.moleculeIndexStart)*blockIndices.numAtomsPerMolecule; + const MoleculeBlockIndices& blockIndices = top->moleculeBlockIndices[molb]; + const int atomStart = blockIndices.globalAtomStart + + (id - blockIndices.moleculeIndexStart) + * blockIndices.numAtomsPerMolecule; for (int j = 0; j < blockIndices.numAtomsPerMolecule; ++j) { t->a[t->nra++] = atomStart + j; @@ -980,8 +933,8 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, /* Set the end of the last block */ t->index[t->nr] = t->nra; /* Free any unnecessary memory */ - srenew(t->index, t->nr+1); - t->nalloc_index = t->nr+1; + srenew(t->index, t->nr + 1); + t->nalloc_index = t->nr + 1; if (bComplete) { srenew(t->a, t->nra); @@ -997,11 +950,9 @@ gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, * * The atoms in \p g are assumed to be sorted. */ -bool -gmx_ana_index_has_full_blocks(const gmx_ana_index_t *g, - const gmx::RangePartitioning *b) +bool gmx_ana_index_has_full_blocks(const gmx_ana_index_t* g, const gmx::RangePartitioning* b) { - int i, j, bi; + int i, j, bi; i = bi = 0; /* Each round in the loop matches one block */ @@ -1039,10 +990,9 @@ gmx_ana_index_has_full_blocks(const gmx_ana_index_t *g, * * The atoms in \p g and \p b->a are assumed to be in the same order. */ -bool -gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b) +bool gmx_ana_index_has_full_ablocks(gmx_ana_index_t* g, t_blocka* b) { - int i, j, bi; + int i, j, bi; i = bi = 0; /* Each round in the loop matches one block */ @@ -1054,12 +1004,12 @@ gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b) ++bi; } /* If not found, or if too large, return */ - if (bi == b->nr || i + b->index[bi+1] - b->index[bi] > g->isize) + if (bi == b->nr || i + b->index[bi + 1] - b->index[bi] > g->isize) { return false; } /* Check that the block matches the index */ - for (j = b->index[bi]; j < b->index[bi+1]; ++j, ++i) + for (j = b->index[bi]; j < b->index[bi + 1]; ++j, ++i) { if (b->a[j] != g->index[i]) { @@ -1080,18 +1030,16 @@ gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b) * \param[in,out] molb The molecule block of atom a * \returns true if atoms \p a and \p a + 1 are in different residues, false otherwise. */ -static bool is_at_residue_boundary(const gmx_mtop_t *top, int a, int *molb) +static bool is_at_residue_boundary(const gmx_mtop_t* top, int a, int* molb) { if (a == -1 || a + 1 == top->natoms) { return true; } int resindA; - mtopGetAtomAndResidueName(top, a, molb, - nullptr, nullptr, nullptr, &resindA); + mtopGetAtomAndResidueName(top, a, molb, nullptr, nullptr, nullptr, &resindA); int resindAPlusOne; - mtopGetAtomAndResidueName(top, a + 1, molb, - nullptr, nullptr, nullptr, &resindAPlusOne); + mtopGetAtomAndResidueName(top, a + 1, molb, nullptr, nullptr, nullptr, &resindAPlusOne); return resindAPlusOne != resindA; } @@ -1108,9 +1056,7 @@ static bool is_at_residue_boundary(const gmx_mtop_t *top, int a, int *molb) * If \p type is \ref INDEX_UNKNOWN or \ref INDEX_ALL, the return value is * always false. */ -bool -gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, - const gmx_mtop_t *top) +bool gmx_ana_index_has_complete_elems(gmx_ana_index_t* g, e_index_t type, const gmx_mtop_t* top) { if (g->isize == 0) { @@ -1121,11 +1067,9 @@ gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, switch (type) { case INDEX_UNKNOWN: - case INDEX_ALL: - return false; + case INDEX_ALL: return false; - case INDEX_ATOM: - return true; + case INDEX_ATOM: return true; case INDEX_RES: { @@ -1171,8 +1115,7 @@ gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, * * Any contents of \p m are discarded without freeing. */ -void -gmx_ana_indexmap_clear(gmx_ana_indexmap_t *m) +void gmx_ana_indexmap_clear(gmx_ana_indexmap_t* m) { m->type = INDEX_UNKNOWN; m->refid = nullptr; @@ -1198,22 +1141,21 @@ gmx_ana_indexmap_clear(gmx_ana_indexmap_t *m) * \param[in] nr Maximum number of blocks to reserve space for. * \param[in] isize Maximum number of atoms to reserve space for. */ -void -gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize) +void gmx_ana_indexmap_reserve(gmx_ana_indexmap_t* m, int nr, int isize) { if (m->mapb.nalloc_index < nr + 1) { - srenew(m->refid, nr); - srenew(m->mapid, nr); - srenew(m->orgid, nr); + srenew(m->refid, nr); + srenew(m->mapid, nr); + srenew(m->orgid, nr); srenew(m->mapb.index, nr + 1); - srenew(m->b.index, nr + 1); + srenew(m->b.index, nr + 1); m->mapb.nalloc_index = nr + 1; m->b.nalloc_index = nr + 1; } if (m->b.nalloc_a < isize) { - srenew(m->b.a, isize); + srenew(m->b.a, isize); m->b.nalloc_a = isize; } } @@ -1232,11 +1174,9 @@ gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize) * * \p m should have been initialized somehow (calloc() is enough). */ -void -gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, - const gmx_mtop_t *top, e_index_t type) +void gmx_ana_indexmap_init(gmx_ana_indexmap_t* m, gmx_ana_index_t* g, const gmx_mtop_t* top, e_index_t type) { - m->type = type; + m->type = type; gmx_ana_index_make_block(&m->b, top, g, type, false); gmx_ana_indexmap_reserve(m, m->b.nr, m->b.nra); int id = -1; @@ -1251,13 +1191,11 @@ gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, m->mapb.nr = m->b.nr; m->mapb.nra = m->b.nra; m->mapb.a = m->b.a; - std::memcpy(m->mapb.index, m->b.index, (m->b.nr+1)*sizeof(*(m->mapb.index))); - m->bStatic = true; + std::memcpy(m->mapb.index, m->b.index, (m->b.nr + 1) * sizeof(*(m->mapb.index))); + m->bStatic = true; } -int -gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top, - e_index_t type) +int gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t* m, const gmx_mtop_t* top, e_index_t type) { GMX_RELEASE_ASSERT(m->bStatic, "Changing original IDs is not supported after starting " @@ -1275,7 +1213,7 @@ gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top, const int ii = m->b.a[m->b.index[i]]; if (next_group_index(ii, top, type, &id)) { - for (int j = m->b.index[i] + 1; j < m->b.index[i+1]; ++j) + for (int j = m->b.index[i] + 1; j < m->b.index[i + 1]; ++j) { if (next_group_index(m->b.a[j], top, type, &id)) { @@ -1319,8 +1257,7 @@ gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top, * ugly way, but allows reducing memory usage of static selections by a * significant amount. */ -void -gmx_ana_indexmap_set_static(gmx_ana_indexmap_t *m, t_blocka *b) +void gmx_ana_indexmap_set_static(gmx_ana_indexmap_t* m, t_blocka* b) { sfree(m->mapid); sfree(m->mapb.index); @@ -1346,21 +1283,20 @@ gmx_ana_indexmap_set_static(gmx_ana_indexmap_t *m, t_blocka *b) * * \p dest should have been initialized somehow (calloc() is enough). */ -void -gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst) +void gmx_ana_indexmap_copy(gmx_ana_indexmap_t* dest, gmx_ana_indexmap_t* src, bool bFirst) { if (bFirst) { gmx_ana_indexmap_reserve(dest, src->b.nr, src->b.nra); - dest->type = src->type; - dest->b.nr = src->b.nr; - dest->b.nra = src->b.nra; - std::memcpy(dest->orgid, src->orgid, dest->b.nr*sizeof(*dest->orgid)); - std::memcpy(dest->b.index, src->b.index, (dest->b.nr+1)*sizeof(*dest->b.index)); - std::memcpy(dest->b.a, src->b.a, dest->b.nra*sizeof(*dest->b.a)); - } - dest->mapb.nr = src->mapb.nr; - dest->mapb.nra = src->mapb.nra; + dest->type = src->type; + dest->b.nr = src->b.nr; + dest->b.nra = src->b.nra; + std::memcpy(dest->orgid, src->orgid, dest->b.nr * sizeof(*dest->orgid)); + std::memcpy(dest->b.index, src->b.index, (dest->b.nr + 1) * sizeof(*dest->b.index)); + std::memcpy(dest->b.a, src->b.a, dest->b.nra * sizeof(*dest->b.a)); + } + dest->mapb.nr = src->mapb.nr; + dest->mapb.nra = src->mapb.nra; if (src->mapb.nalloc_a > 0) { if (bFirst) @@ -1368,15 +1304,15 @@ gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bF snew(dest->mapb.a, src->mapb.nalloc_a); dest->mapb.nalloc_a = src->mapb.nalloc_a; } - std::memcpy(dest->mapb.a, src->mapb.a, dest->mapb.nra*sizeof(*dest->mapb.a)); + std::memcpy(dest->mapb.a, src->mapb.a, dest->mapb.nra * sizeof(*dest->mapb.a)); } else { dest->mapb.a = src->mapb.a; } - std::memcpy(dest->refid, src->refid, dest->mapb.nr*sizeof(*dest->refid)); - std::memcpy(dest->mapid, src->mapid, dest->mapb.nr*sizeof(*dest->mapid)); - std::memcpy(dest->mapb.index, src->mapb.index, (dest->mapb.nr+1)*sizeof(*dest->mapb.index)); + std::memcpy(dest->refid, src->refid, dest->mapb.nr * sizeof(*dest->refid)); + std::memcpy(dest->mapid, src->mapid, dest->mapb.nr * sizeof(*dest->mapid)); + std::memcpy(dest->mapb.index, src->mapb.index, (dest->mapb.nr + 1) * sizeof(*dest->mapb.index)); dest->bStatic = src->bStatic; } @@ -1387,8 +1323,7 @@ gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bF * \param[in] isize Number of atoms in the \p index array. * \param[in] index List of atoms. */ -static void -set_atoms(gmx_ana_indexmap_t *m, int isize, int *index) +static void set_atoms(gmx_ana_indexmap_t* m, int isize, int* index) { m->mapb.nra = isize; if (m->mapb.nalloc_a == 0) @@ -1414,11 +1349,9 @@ set_atoms(gmx_ana_indexmap_t *m, int isize, int *index) * * \see gmx_ana_indexmap_t */ -void -gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, - bool bMaskOnly) +void gmx_ana_indexmap_update(gmx_ana_indexmap_t* m, gmx_ana_index_t* g, bool bMaskOnly) { - int i, j, bi, bj; + int i, j, bi, bj; /* Process the simple cases first */ if (m->type == INDEX_UNKNOWN && m->b.nra == 0) @@ -1477,7 +1410,7 @@ gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, ++j; } /* Mark blocks that did not contain any atoms */ - while (bj < m->b.nr && m->b.index[bj+1] <= j) + while (bj < m->b.nr && m->b.index[bj + 1] <= j) { m->refid[bj++] = -1; } @@ -1504,10 +1437,10 @@ gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, ++j; } /* If we have reached a new block, add it */ - if (m->b.index[bj+1] <= j) + if (m->b.index[bj + 1] <= j) { /* Skip any blocks in between */ - while (bj < m->b.nr && m->b.index[bj+1] <= j) + while (bj < m->b.nr && m->b.index[bj + 1] <= j) { ++bj; } @@ -1531,8 +1464,7 @@ gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, * the pointers set to NULL. * The pointer \p m is not freed. */ -void -gmx_ana_indexmap_deinit(gmx_ana_indexmap_t *m) +void gmx_ana_indexmap_deinit(gmx_ana_indexmap_t* m) { sfree(m->refid); if (m->mapid != m->orgid) diff --git a/src/gromacs/selection/indexutil.h b/src/gromacs/selection/indexutil.h index 03d1abc2f5..a191cc71c5 100644 --- a/src/gromacs/selection/indexutil.h +++ b/src/gromacs/selection/indexutil.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -84,37 +85,37 @@ class TextWriter; */ class IndexGroupsAndNames { - public: +public: + /*!\brief Construct from index group and group names + * \param[in] indexGroup + * \param[in] groupNames names of the index groups + */ + IndexGroupsAndNames(const t_blocka& indexGroup, ArrayRef groupNames); - /*!\brief Construct from index group and group names - * \param[in] indexGroup - * \param[in] groupNames names of the index groups - */ - IndexGroupsAndNames(const t_blocka &indexGroup, ArrayRef groupNames); + /*!\brief Return if a group name is contained in the groups. + * + * String comparison is case insensitive + * + * \param[in] groupName the group name to be queried + * \returns true if index group name is contained + */ + bool containsGroupName(const std::string& groupName) const; - /*!\brief Return if a group name is contained in the groups. - * - * String comparison is case insensitive - * - * \param[in] groupName the group name to be queried - * \returns true if index group name is contained - */ - bool containsGroupName(const std::string &groupName) const; + /*!\brief Return the integer indices of a group. + * + * If two index groups share a name, return the one found first. + * + * Indices may be empty. + * + * \param[in] groupName the name of the group whose indices shall be returned + * \returns atom indices of the selected index group + * \throws if groupName is not present as index group + */ + std::vector indices(const std::string& groupName) const; - /*!\brief Return the integer indices of a group. - * - * If two index groups share a name, return the one found first. - * - * Indices may be empty. - * - * \param[in] groupName the name of the group whose indices shall be returned - * \returns atom indices of the selected index group - * \throws if groupName is not present as index group - */ - std::vector indices(const std::string &groupName) const; - private: - const t_blocka &indexGroup_; - std::vector groupNames_; +private: + const t_blocka& indexGroup_; + std::vector groupNames_; }; } // namespace gmx @@ -144,11 +145,11 @@ typedef enum struct gmx_ana_index_t { /** Number of atoms. */ - int isize; + int isize; /** List of atoms. */ - int *index; + int* index; /** Number of items allocated for \p index. */ - int nalloc_index; + int nalloc_index; }; /*! \brief @@ -157,7 +158,7 @@ struct gmx_ana_index_t struct gmx_ana_indexmap_t { /** Type of the mapping. */ - e_index_t type; + e_index_t type; /*! \brief * Current reference IDs. * @@ -169,7 +170,7 @@ struct gmx_ana_indexmap_t * for blocks not present in the current group are set to -1, otherwise * they are removed completely and the \p nr field updated. */ - int *refid; + int* refid; /*! \brief * Current mapped IDs. * @@ -180,14 +181,14 @@ struct gmx_ana_indexmap_t * If \p bMaskOnly is provided to gmx_ana_indexmap_update(), this array * equals \p orgid. */ - int *mapid; + int* mapid; /*! \brief * Mapped block structure. * * A block structure that corresponds to the current index group. * \c mapb.nra and \c mapb.a correspond to the last mapped index group. */ - t_blocka mapb; + t_blocka mapb; /*! \brief * Customizable ID numbers for the original blocks. @@ -205,7 +206,7 @@ struct gmx_ana_indexmap_t * if the above are not appropriate. * The mapped values can be read through \p mapid. */ - int *orgid; + int* orgid; /*! \brief * Block data that defines the mapping (internal use only). @@ -216,7 +217,7 @@ struct gmx_ana_indexmap_t * gmx_ana_indexmap_update() unless \p bMaskOnly was specified or the * index group is identical to the one provided to gmx_ana_indexmap_init(). */ - t_blocka b; + t_blocka b; /*! \brief * true if the current reference IDs are for the whole group (internal use only). * @@ -224,7 +225,7 @@ struct gmx_ana_indexmap_t * gmx_ana_indexmap_update() does not take any time if the group is * actually static. */ - bool bStatic; + bool bStatic; }; @@ -232,61 +233,46 @@ struct gmx_ana_indexmap_t */ /*@{*/ /** Reads index groups from a file or constructs them from topology. */ -void -gmx_ana_indexgrps_init(gmx_ana_indexgrps_t **g, gmx_mtop_t *top, - const char *fnm); +void gmx_ana_indexgrps_init(gmx_ana_indexgrps_t** g, gmx_mtop_t* top, const char* fnm); /** Frees memory allocated for index groups. */ -void -gmx_ana_indexgrps_free(gmx_ana_indexgrps_t *g); +void gmx_ana_indexgrps_free(gmx_ana_indexgrps_t* g); /** Returns true if the index group structure is emtpy. */ -bool -gmx_ana_indexgrps_is_empty(gmx_ana_indexgrps_t *g); +bool gmx_ana_indexgrps_is_empty(gmx_ana_indexgrps_t* g); /** Returns a pointer to an index group. */ -gmx_ana_index_t * -gmx_ana_indexgrps_get_grp(gmx_ana_indexgrps_t *g, int n); +gmx_ana_index_t* gmx_ana_indexgrps_get_grp(gmx_ana_indexgrps_t* g, int n); /** Extracts a single index group. */ -bool -gmx_ana_indexgrps_extract(gmx_ana_index_t *dest, std::string *destName, - gmx_ana_indexgrps_t *src, int n); +bool gmx_ana_indexgrps_extract(gmx_ana_index_t* dest, std::string* destName, gmx_ana_indexgrps_t* src, int n); /** Finds and extracts a single index group by name. */ -bool -gmx_ana_indexgrps_find(gmx_ana_index_t *dest, std::string *destName, - gmx_ana_indexgrps_t *src, const char *name); +bool gmx_ana_indexgrps_find(gmx_ana_index_t* dest, + std::string* destName, + gmx_ana_indexgrps_t* src, + const char* name); /** Writes out a list of index groups. */ -void -gmx_ana_indexgrps_print(gmx::TextWriter *writer, gmx_ana_indexgrps_t *g, int maxn); +void gmx_ana_indexgrps_print(gmx::TextWriter* writer, gmx_ana_indexgrps_t* g, int maxn); /*@}*/ /*! \name Functions for handling gmx_ana_index_t */ /*@{*/ /** Reserves memory to store an index group of size \p isize. */ -void -gmx_ana_index_reserve(gmx_ana_index_t *g, int isize); +void gmx_ana_index_reserve(gmx_ana_index_t* g, int isize); /** Frees any memory not necessary to hold the current contents. */ -void -gmx_ana_index_squeeze(gmx_ana_index_t *g); +void gmx_ana_index_squeeze(gmx_ana_index_t* g); /** Initializes an empty index group. */ -void -gmx_ana_index_clear(gmx_ana_index_t *g); +void gmx_ana_index_clear(gmx_ana_index_t* g); /** Constructs a \c gmx_ana_index_t from given values. */ -void -gmx_ana_index_set(gmx_ana_index_t *g, int isize, int *index, int nalloc); +void gmx_ana_index_set(gmx_ana_index_t* g, int isize, int* index, int nalloc); /** Creates a simple index group from the first to the \p natoms'th atom. */ -void -gmx_ana_index_init_simple(gmx_ana_index_t *g, int natoms); +void gmx_ana_index_init_simple(gmx_ana_index_t* g, int natoms); /** Frees memory allocated for an index group. */ -void -gmx_ana_index_deinit(gmx_ana_index_t *g); +void gmx_ana_index_deinit(gmx_ana_index_t* g); /** Copies a \c gmx_ana_index_t. */ -void -gmx_ana_index_copy(gmx_ana_index_t *dest, gmx_ana_index_t *src, bool bAlloc); +void gmx_ana_index_copy(gmx_ana_index_t* dest, gmx_ana_index_t* src, bool bAlloc); /** Writes out the contents of a index group. */ -void -gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn); +void gmx_ana_index_dump(gmx::TextWriter* writer, gmx_ana_index_t* g, int maxn); /*! \brief * Returns maximum atom index that appears in an index group. @@ -294,11 +280,9 @@ gmx_ana_index_dump(gmx::TextWriter *writer, gmx_ana_index_t *g, int maxn); * \param[in] g Index group to query. * \returns Largest atom index that appears in \p g, or zero if \p g is empty. */ -int -gmx_ana_index_get_max_index(gmx_ana_index_t *g); +int gmx_ana_index_get_max_index(gmx_ana_index_t* g); /** Checks whether an index group is sorted. */ -bool -gmx_ana_index_check_sorted(gmx_ana_index_t *g); +bool gmx_ana_index_check_sorted(gmx_ana_index_t* g); /*! \brief * Checks whether an index group has atoms from a defined range. * @@ -307,45 +291,33 @@ gmx_ana_index_check_sorted(gmx_ana_index_t *g); * \returns true if all atoms in the index group are in the * range 0 to \p natoms (i.e., no atoms over \p natoms are referenced). */ -bool -gmx_ana_index_check_range(gmx_ana_index_t *g, int natoms); +bool gmx_ana_index_check_range(gmx_ana_index_t* g, int natoms); /*@}*/ /*! \name Functions for set operations on gmx_ana_index_t */ /*@{*/ /** Sorts the indices within an index group. */ -void -gmx_ana_index_sort(gmx_ana_index_t *g); +void gmx_ana_index_sort(gmx_ana_index_t* g); /*! \brief * Removes duplicates from a sorted index group. * * \param[in,out] g Index group to be processed. */ -void -gmx_ana_index_remove_duplicates(gmx_ana_index_t *g); +void gmx_ana_index_remove_duplicates(gmx_ana_index_t* g); /** Checks whether two index groups are equal. */ -bool -gmx_ana_index_equals(gmx_ana_index_t *a, gmx_ana_index_t *b); +bool gmx_ana_index_equals(gmx_ana_index_t* a, gmx_ana_index_t* b); /** Checks whether a sorted index group contains another sorted index group. */ -bool -gmx_ana_index_contains(gmx_ana_index_t *a, gmx_ana_index_t *b); +bool gmx_ana_index_contains(gmx_ana_index_t* a, gmx_ana_index_t* b); /** Calculates the intersection between two sorted index groups. */ -void -gmx_ana_index_intersection(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b); +void gmx_ana_index_intersection(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b); /** Calculates the set difference between two sorted index groups. */ -void -gmx_ana_index_difference(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b); +void gmx_ana_index_difference(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b); /** Calculates the size of the difference between two sorted index groups. */ -int -gmx_ana_index_difference_size(gmx_ana_index_t *a, gmx_ana_index_t *b); +int gmx_ana_index_difference_size(gmx_ana_index_t* a, gmx_ana_index_t* b); /** Calculates the union of two sorted index groups. */ -void -gmx_ana_index_union(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b); +void gmx_ana_index_union(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b); /*! \brief * Calculates the union of two index groups, where the second group may not be sorted. * @@ -356,47 +328,34 @@ gmx_ana_index_union(gmx_ana_index_t *dest, * \p a and \p b can have common items. * \p dest can equal \p a or \p b. */ -void -gmx_ana_index_union_unsorted(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b); +void gmx_ana_index_union_unsorted(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b); /** Merges two distinct sorted index groups. */ -void -gmx_ana_index_merge(gmx_ana_index_t *dest, - gmx_ana_index_t *a, gmx_ana_index_t *b); +void gmx_ana_index_merge(gmx_ana_index_t* dest, gmx_ana_index_t* a, gmx_ana_index_t* b); /** Calculates the intersection and the difference in one call. */ -void -gmx_ana_index_partition(gmx_ana_index_t *dest1, gmx_ana_index_t *dest2, - gmx_ana_index_t *src, gmx_ana_index_t *g); +void gmx_ana_index_partition(gmx_ana_index_t* dest1, + gmx_ana_index_t* dest2, + gmx_ana_index_t* src, + gmx_ana_index_t* g); /*@}*/ /*! \name Functions for handling gmx_ana_indexmap_t and related things */ /*@{*/ /** Partition a group based on topology information. */ -void -gmx_ana_index_make_block(t_blocka *t, const gmx_mtop_t *top, gmx_ana_index_t *g, - e_index_t type, bool bComplete); +void gmx_ana_index_make_block(t_blocka* t, const gmx_mtop_t* top, gmx_ana_index_t* g, e_index_t type, bool bComplete); /** Checks whether a group consists of full blocks. */ -bool -gmx_ana_index_has_full_blocks(const gmx_ana_index_t *g, const gmx::RangePartitioning *b); +bool gmx_ana_index_has_full_blocks(const gmx_ana_index_t* g, const gmx::RangePartitioning* b); /** Checks whether a group consists of full blocks. */ -bool -gmx_ana_index_has_full_ablocks(gmx_ana_index_t *g, t_blocka *b); +bool gmx_ana_index_has_full_ablocks(gmx_ana_index_t* g, t_blocka* b); /** Checks whether a group consists of full residues/molecules. */ -bool -gmx_ana_index_has_complete_elems(gmx_ana_index_t *g, e_index_t type, - const gmx_mtop_t *top); +bool gmx_ana_index_has_complete_elems(gmx_ana_index_t* g, e_index_t type, const gmx_mtop_t* top); /** Initializes an empty index group mapping. */ -void -gmx_ana_indexmap_clear(gmx_ana_indexmap_t *m); +void gmx_ana_indexmap_clear(gmx_ana_indexmap_t* m); /** Reserves memory for an index group mapping. */ -void -gmx_ana_indexmap_reserve(gmx_ana_indexmap_t *m, int nr, int isize); +void gmx_ana_indexmap_reserve(gmx_ana_indexmap_t* m, int nr, int isize); /** Initializes an index group mapping. */ -void -gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, - const gmx_mtop_t *top, e_index_t type); +void gmx_ana_indexmap_init(gmx_ana_indexmap_t* m, gmx_ana_index_t* g, const gmx_mtop_t* top, e_index_t type); /*! \brief * Initializes `orgid` entries based on topology grouping. * @@ -421,21 +380,15 @@ gmx_ana_indexmap_init(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, * * Strong exception safety guarantee. */ -int -gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t *m, const gmx_mtop_t *top, - e_index_t type); +int gmx_ana_indexmap_init_orgid_group(gmx_ana_indexmap_t* m, const gmx_mtop_t* top, e_index_t type); /** Sets an index group mapping to be static. */ -void -gmx_ana_indexmap_set_static(gmx_ana_indexmap_t *m, t_blocka *b); +void gmx_ana_indexmap_set_static(gmx_ana_indexmap_t* m, t_blocka* b); /** Frees memory allocated for index group mapping. */ -void -gmx_ana_indexmap_deinit(gmx_ana_indexmap_t *m); +void gmx_ana_indexmap_deinit(gmx_ana_indexmap_t* m); /** Makes a deep copy of an index group mapping. */ -void -gmx_ana_indexmap_copy(gmx_ana_indexmap_t *dest, gmx_ana_indexmap_t *src, bool bFirst); +void gmx_ana_indexmap_copy(gmx_ana_indexmap_t* dest, gmx_ana_indexmap_t* src, bool bFirst); /** Updates an index group mapping. */ -void -gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, bool bMaskOnly); +void gmx_ana_indexmap_update(gmx_ana_indexmap_t* m, gmx_ana_index_t* g, bool bMaskOnly); /*@}*/ #endif diff --git a/src/gromacs/selection/keywords.h b/src/gromacs/selection/keywords.h index 6726dbb03b..1b0db8cc45 100644 --- a/src/gromacs/selection/keywords.h +++ b/src/gromacs/selection/keywords.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2012,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,8 +62,7 @@ extern struct gmx_ana_selmethod_t sm_keyword_str; extern struct gmx_ana_selmethod_t sm_keyword_pos; /** Prints information about a comparison expression. */ -void -_gmx_selelem_print_compare_info(FILE *fp, void *data); +void _gmx_selelem_print_compare_info(FILE* fp, void* data); /*! \brief * Returns whether the selection element is a default position keyword. @@ -74,25 +73,20 @@ _gmx_selelem_print_compare_info(FILE *fp, void *data); * * This method only works before the selection has been compiled. */ -bool -_gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement &sel); +bool _gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement& sel); /** Sets the position type for position keyword evaluation. */ -void -_gmx_selelem_set_kwpos_type(gmx::SelectionTreeElement *sel, const char *type); +void _gmx_selelem_set_kwpos_type(gmx::SelectionTreeElement* sel, const char* type); /** Sets the flags for position keyword evaluation. */ -void -_gmx_selelem_set_kwpos_flags(gmx::SelectionTreeElement *sel, int flags); +void _gmx_selelem_set_kwpos_flags(gmx::SelectionTreeElement* sel, int flags); /** Sets the string match type for string keyword evaluation. */ -void -_gmx_selelem_set_kwstr_match_type(const gmx::SelectionTreeElementPointer &sel, - gmx::SelectionStringMatchType matchType); +void _gmx_selelem_set_kwstr_match_type(const gmx::SelectionTreeElementPointer& sel, + gmx::SelectionStringMatchType matchType); /** Does custom processing for parameters of the \c same selection method. */ -void -_gmx_selelem_custom_init_same(struct gmx_ana_selmethod_t **method, - const gmx::SelectionParserParameterListPointer ¶ms, - void *scanner); +void _gmx_selelem_custom_init_same(struct gmx_ana_selmethod_t** method, + const gmx::SelectionParserParameterListPointer& params, + void* scanner); /*! \brief * Initializes a selection element for evaluating a keyword in a given group. @@ -108,9 +102,8 @@ _gmx_selelem_custom_init_same(struct gmx_ana_selmethod_t **me * \p child should be a selection tree that evaluates to \ref GROUP_VALUE or * \ref POS_VALUE. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_keyword_evaluator(struct gmx_ana_selmethod_t *method, - const gmx::SelectionTreeElementPointer &child, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_keyword_evaluator(struct gmx_ana_selmethod_t* method, + const gmx::SelectionTreeElementPointer& child, + void* scanner); #endif diff --git a/src/gromacs/selection/mempool.cpp b/src/gromacs/selection/mempool.cpp index d7c7cd3759..2319478293 100644 --- a/src/gromacs/selection/mempool.cpp +++ b/src/gromacs/selection/mempool.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,9 +61,9 @@ typedef struct gmx_sel_mempool_block_t { //! Pointer to the start of the block (as returned to the user). - void *ptr; + void* ptr; //! Size of the block, including padding required to align next block. - size_t size; + size_t size; } gmx_sel_mempool_block_t; /*! \internal \brief @@ -72,30 +72,29 @@ typedef struct gmx_sel_mempool_block_t struct gmx_sel_mempool_t { //! Number of bytes currently allocated from the pool. - size_t currsize; + size_t currsize; //! Number of bytes free in the pool, or 0 if \a buffer is NULL. - size_t freesize; + size_t freesize; //! Memory area allocated for the pool, or NULL if not yet reserved. - char *buffer; + char* buffer; //! Pointer to the first free byte (aligned at ::ALIGN_STEP) in \a buffer. - char *freeptr; + char* freeptr; //! Number of blocks allocated from the pool. - int nblocks; + int nblocks; //! Array describing the allocated blocks. - gmx_sel_mempool_block_t *blockstack; + gmx_sel_mempool_block_t* blockstack; //! Number of elements allocated for the \a blockstack array. - int blockstack_nalloc; + int blockstack_nalloc; /*! \brief * Maximum number of bytes that have been reserved from the pool * simultaneously. */ - size_t maxsize; + size_t maxsize; }; -gmx_sel_mempool_t * -_gmx_sel_mempool_create() +gmx_sel_mempool_t* _gmx_sel_mempool_create() { - gmx_sel_mempool_t *mp; + gmx_sel_mempool_t* mp; snew(mp, 1); mp->currsize = 0; @@ -109,12 +108,11 @@ _gmx_sel_mempool_create() return mp; } -void -_gmx_sel_mempool_destroy(gmx_sel_mempool_t *mp) +void _gmx_sel_mempool_destroy(gmx_sel_mempool_t* mp) { if (!mp->buffer) { - int i; + int i; for (i = 0; i < mp->nblocks; ++i) { @@ -126,11 +124,10 @@ _gmx_sel_mempool_destroy(gmx_sel_mempool_t *mp) sfree(mp); } -void * -_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size) +void* _gmx_sel_mempool_alloc(gmx_sel_mempool_t* mp, size_t size) { - void *ptr = nullptr; - size_t size_walign; + void* ptr = nullptr; + size_t size_walign; size_walign = ((size + ALIGN_STEP - 1) / ALIGN_STEP) * ALIGN_STEP; if (mp->buffer) @@ -139,8 +136,8 @@ _gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size) { GMX_THROW(gmx::InternalError("Out of memory pool memory")); } - ptr = mp->freeptr; - mp->freeptr += size_walign; + ptr = mp->freeptr; + mp->freeptr += size_walign; mp->freesize -= size_walign; mp->currsize += size_walign; } @@ -170,8 +167,7 @@ _gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size) return ptr; } -void -_gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr) +void _gmx_sel_mempool_free(gmx_sel_mempool_t* mp, void* ptr) { int size; @@ -182,11 +178,11 @@ _gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr) GMX_RELEASE_ASSERT(mp->nblocks > 0 && mp->blockstack[mp->nblocks - 1].ptr == ptr, "Invalid order of memory pool free calls"); mp->nblocks--; - size = mp->blockstack[mp->nblocks].size; + size = mp->blockstack[mp->nblocks].size; mp->currsize -= size; if (mp->buffer) { - mp->freeptr = static_cast(ptr); + mp->freeptr = static_cast(ptr); mp->freesize += size; } else @@ -195,8 +191,7 @@ _gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr) } } -void -_gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size) +void _gmx_sel_mempool_reserve(gmx_sel_mempool_t* mp, size_t size) { GMX_RELEASE_ASSERT(mp->nblocks == 0, "Cannot reserve memory pool when there is something allocated"); @@ -205,7 +200,7 @@ _gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size) { size = mp->maxsize; } - mp->buffer = static_cast(malloc(size)); + mp->buffer = static_cast(malloc(size)); if (!mp->buffer) { throw std::bad_alloc(); @@ -214,16 +209,13 @@ _gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size) mp->freeptr = mp->buffer; } -void -_gmx_sel_mempool_alloc_group(gmx_sel_mempool_t *mp, gmx_ana_index_t *g, - int isize) +void _gmx_sel_mempool_alloc_group(gmx_sel_mempool_t* mp, gmx_ana_index_t* g, int isize) { - void *ptr = _gmx_sel_mempool_alloc(mp, sizeof(*g->index)*isize); - g->index = static_cast(ptr); + void* ptr = _gmx_sel_mempool_alloc(mp, sizeof(*g->index) * isize); + g->index = static_cast(ptr); } -void -_gmx_sel_mempool_free_group(gmx_sel_mempool_t *mp, gmx_ana_index_t *g) +void _gmx_sel_mempool_free_group(gmx_sel_mempool_t* mp, gmx_ana_index_t* g) { _gmx_sel_mempool_free(mp, g->index); g->index = nullptr; diff --git a/src/gromacs/selection/mempool.h b/src/gromacs/selection/mempool.h index d131eb9d06..258528e6cb 100644 --- a/src/gromacs/selection/mempool.h +++ b/src/gromacs/selection/mempool.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,28 +55,20 @@ struct gmx_ana_index_t; typedef struct gmx_sel_mempool_t gmx_sel_mempool_t; /** Create an empty memory pool. */ -gmx_sel_mempool_t * -_gmx_sel_mempool_create(); +gmx_sel_mempool_t* _gmx_sel_mempool_create(); /** Destroy a memory pool. */ -void -_gmx_sel_mempool_destroy(gmx_sel_mempool_t *mp); +void _gmx_sel_mempool_destroy(gmx_sel_mempool_t* mp); /** Allocate memory from a memory pool. */ -void * -_gmx_sel_mempool_alloc(gmx_sel_mempool_t *mp, size_t size); +void* _gmx_sel_mempool_alloc(gmx_sel_mempool_t* mp, size_t size); /** Release memory allocated from a memory pool. */ -void -_gmx_sel_mempool_free(gmx_sel_mempool_t *mp, void *ptr); +void _gmx_sel_mempool_free(gmx_sel_mempool_t* mp, void* ptr); /** Set the size of a memory pool. */ -void -_gmx_sel_mempool_reserve(gmx_sel_mempool_t *mp, size_t size); +void _gmx_sel_mempool_reserve(gmx_sel_mempool_t* mp, size_t size); /** Convenience function for allocating an index group from a memory pool. */ -void -_gmx_sel_mempool_alloc_group(gmx_sel_mempool_t *mp, struct gmx_ana_index_t *g, - int isize); +void _gmx_sel_mempool_alloc_group(gmx_sel_mempool_t* mp, struct gmx_ana_index_t* g, int isize); /** Convenience function for freeing an index group from a memory pool. */ -void -_gmx_sel_mempool_free_group(gmx_sel_mempool_t *mp, struct gmx_ana_index_t *g); +void _gmx_sel_mempool_free_group(gmx_sel_mempool_t* mp, struct gmx_ana_index_t* g); #endif diff --git a/src/gromacs/selection/nbsearch.cpp b/src/gromacs/selection/nbsearch.cpp index 4b751ad292..ddc8bd67d3 100644 --- a/src/gromacs/selection/nbsearch.cpp +++ b/src/gromacs/selection/nbsearch.cpp @@ -107,7 +107,7 @@ void computeBoundingBox(int posCount, const rvec x[], rvec origin, rvec size) rvec_sub(maxBound, origin, size); } -} // namespace +} // namespace namespace internal { @@ -118,295 +118,292 @@ namespace internal class AnalysisNeighborhoodSearchImpl { - public: - typedef AnalysisNeighborhoodPairSearch::ImplPointer - PairSearchImplPointer; - typedef std::vector PairSearchList; - typedef std::vector > CellList; - - explicit AnalysisNeighborhoodSearchImpl(real cutoff); - ~AnalysisNeighborhoodSearchImpl(); - - /*! \brief - * Initializes the search with a given box and reference positions. - * - * \param[in] mode Search mode to use. - * \param[in] bXY Whether to use 2D searching. - * \param[in] excls Exclusions. - * \param[in] pbc PBC information. - * \param[in] positions Set of reference positions. - */ - void init(AnalysisNeighborhood::SearchMode mode, - bool bXY, - const t_blocka *excls, - const t_pbc *pbc, - const AnalysisNeighborhoodPositions &positions); - PairSearchImplPointer getPairSearch(); - - real cutoffSquared() const { return cutoff2_; } - bool usesGridSearch() const { return bGrid_; } - - private: - /*! \brief - * Determines a suitable grid size and sets up the cells. - * - * \param[in] box Box vectors (should not have zero vectors). - * \param[in] bSingleCell If `true`, the corresponding dimension will - * be forced to use a single cell. - * \param[in] posCount Number of positions that will be put on the - * grid. - * \returns `false` if grid search is not suitable. - */ - bool initGridCells(const matrix box, bool bSingleCell[DIM], - int posCount); - /*! \brief - * Sets ua a search grid for a given box. - * - * \param[in] pbc Information about the box. - * \param[in] posCount Number of positions in \p x. - * \param[in] x Reference positions that will be put on the grid. - * \param[in] bForce If `true`, grid searching will be used if at all - * possible, even if a simple search might give better performance. - * \returns `false` if grid search is not suitable. - */ - bool initGrid(const t_pbc &pbc, int posCount, const rvec x[], bool bForce); - /*! \brief - * Maps a point into a grid cell. - * - * \param[in] x Point to map. - * \param[out] cell Fractional cell coordinates of \p x on the grid. - * \param[out] xout Coordinates to use. - * - * \p xout will be within the rectangular unit cell in dimensions where - * the grid is periodic. For other dimensions, both \p xout and - * \p cell can be outside the grid/unit cell. - */ - void mapPointToGridCell(const rvec x, rvec cell, rvec xout) const; - /*! \brief - * Calculates linear index of a grid cell. - * - * \param[in] cell Cell indices (must be within the grid). - * \returns Linear index of \p cell. - */ - int getGridCellIndex(const ivec cell) const; - /*! \brief - * Calculates linear index of a grid cell from fractional coordinates. - * - * \param[in] cell Cell indices (must be within the grid). - * \returns Linear index of \p cell. - */ - int getGridCellIndex(const rvec cell) const; - /*! \brief - * Adds an index into a grid cell. - * - * \param[in] cell Fractional cell coordinates into which \p i should - * be added. - * \param[in] i Index to add. - * - * \p cell should satisfy the conditions that \p mapPointToGridCell() - * produces. - */ - void addToGridCell(const rvec cell, int i); - /*! \brief - * Initializes a cell pair loop for a dimension. - * - * \param[in] centerCell Fractional cell coordiates of the particle - * for which pairs are being searched. - * \param[in,out] cell Current/initial cell to loop over. - * \param[in,out] upperBound Last cell to loop over. - * \param[in] dim Dimension to initialize in this call. - * - * Initializes `cell[dim]` and `upperBound[dim]` for looping over - * neighbors of a particle at position given by \p centerCell. - * If 'dim != ZZ`, `cell[d]` (`d > dim`) set the plane/row of cells - * for which the loop is initialized. The loop should then go from - * `cell[dim]` until `upperBound[dim]`, inclusive. - * `cell[d]` with `d < dim` or `upperBound[d]` with `d != dim` are not - * modified by this function. - * - * `cell` and `upperBound` may be outside the grid for periodic - * dimensions and need to be shifted separately: to simplify the - * looping, the range is always (roughly) symmetric around the value in - * `centerCell`. - */ - void initCellRange(const rvec centerCell, ivec cell, - ivec upperBound, int dim) const; - /*! \brief - * Computes the extent of the cutoff sphere on a particular cell edge. - * - * \param[in] centerCell Fractional cell coordiates of the particle - * for which pairs are being searched. - * \param[in] cell Current cell (for dimensions `>dim`). - * \param[in] dim Dimension to compute in this call. - * \returns Fractional extent of the cutoff sphere when looping - * over cells in dimension `dim`, for `cell[d]` (`d > dim`). - * - * Input parameters are as for initCellRange(), except that if `cell` - * is over a periodic boundary from `centerCell`, triclinic shifts - * should have been applied to `centerCell` X/Y components. - */ - real computeCutoffExtent(RVec centerCell, const ivec cell, int dim) const; - /*! \brief - * Advances cell pair loop to the next cell. - * - * \param[in] centerCell Fractional cell coordiates of the particle - * for which pairs are being searched. - * \param[in,out] cell Current (in)/next (out) cell in the loop. - * \param[in,out] upperBound Last cell in the loop for each dimension. - */ - bool nextCell(const rvec centerCell, ivec cell, ivec upperBound) const; - /*! \brief - * Calculates the index and shift of a grid cell during looping. - * - * \param[in] cell Unshifted cell index. - * \param[out] shift Shift to apply to get the periodic distance - * for distances between the cells. - * \returns Grid cell index corresponding to `cell`. - */ - int shiftCell(const ivec cell, rvec shift) const; - - //! Whether to try grid searching. - bool bTryGrid_; - //! The cutoff. - real cutoff_; - //! The cutoff squared. - real cutoff2_; - //! Whether to do searching in XY plane only. - bool bXY_; - - //! Number of reference points for the current frame. - int nref_; - //! Reference point positions. - const rvec *xref_; - //! Reference position exclusion IDs. - const int *refExclusionIds_; - //! Reference position indices (NULL if no indices). - const int *refIndices_; - //! Exclusions. - const t_blocka *excls_; - //! PBC data. - t_pbc pbc_; - - //! Whether grid searching is actually used for the current positions. - bool bGrid_; - //! false if the box is rectangular. - bool bTric_; - //! Whether the grid is periodic in a dimension. - bool bGridPBC_[DIM]; - //! Array for storing in-unit-cell reference positions. - std::vector xrefAlloc_; - //! Origin of the grid (zero for periodic dimensions). - rvec gridOrigin_; - //! Size of a single grid cell. - rvec cellSize_; - //! Inverse of \p cellSize_. Zero for dimensions where grid is not used. - rvec invCellSize_; - /*! \brief - * Shift in cell coordinates (for triclinic boxes) in X when crossing - * the Z periodic boundary. - */ - real cellShiftZX_; - /*! \brief - * Shift in cell coordinates (for triclinic boxes) in Y when crossing - * the Z periodic boundary. - */ - real cellShiftZY_; - /*! \brief - * Shift in cell coordinates (for triclinic boxes) in X when crossing - * the Y periodic boundary. - */ - real cellShiftYX_; - //! Number of cells along each dimension. - ivec ncelldim_; - //! Data structure to hold the grid cell contents. - CellList cells_; - - Mutex createPairSearchMutex_; - PairSearchList pairSearchList_; - - friend class AnalysisNeighborhoodPairSearchImpl; - - GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisNeighborhoodSearchImpl); +public: + typedef AnalysisNeighborhoodPairSearch::ImplPointer PairSearchImplPointer; + typedef std::vector PairSearchList; + typedef std::vector> CellList; + + explicit AnalysisNeighborhoodSearchImpl(real cutoff); + ~AnalysisNeighborhoodSearchImpl(); + + /*! \brief + * Initializes the search with a given box and reference positions. + * + * \param[in] mode Search mode to use. + * \param[in] bXY Whether to use 2D searching. + * \param[in] excls Exclusions. + * \param[in] pbc PBC information. + * \param[in] positions Set of reference positions. + */ + void init(AnalysisNeighborhood::SearchMode mode, + bool bXY, + const t_blocka* excls, + const t_pbc* pbc, + const AnalysisNeighborhoodPositions& positions); + PairSearchImplPointer getPairSearch(); + + real cutoffSquared() const { return cutoff2_; } + bool usesGridSearch() const { return bGrid_; } + +private: + /*! \brief + * Determines a suitable grid size and sets up the cells. + * + * \param[in] box Box vectors (should not have zero vectors). + * \param[in] bSingleCell If `true`, the corresponding dimension will + * be forced to use a single cell. + * \param[in] posCount Number of positions that will be put on the + * grid. + * \returns `false` if grid search is not suitable. + */ + bool initGridCells(const matrix box, bool bSingleCell[DIM], int posCount); + /*! \brief + * Sets ua a search grid for a given box. + * + * \param[in] pbc Information about the box. + * \param[in] posCount Number of positions in \p x. + * \param[in] x Reference positions that will be put on the grid. + * \param[in] bForce If `true`, grid searching will be used if at all + * possible, even if a simple search might give better performance. + * \returns `false` if grid search is not suitable. + */ + bool initGrid(const t_pbc& pbc, int posCount, const rvec x[], bool bForce); + /*! \brief + * Maps a point into a grid cell. + * + * \param[in] x Point to map. + * \param[out] cell Fractional cell coordinates of \p x on the grid. + * \param[out] xout Coordinates to use. + * + * \p xout will be within the rectangular unit cell in dimensions where + * the grid is periodic. For other dimensions, both \p xout and + * \p cell can be outside the grid/unit cell. + */ + void mapPointToGridCell(const rvec x, rvec cell, rvec xout) const; + /*! \brief + * Calculates linear index of a grid cell. + * + * \param[in] cell Cell indices (must be within the grid). + * \returns Linear index of \p cell. + */ + int getGridCellIndex(const ivec cell) const; + /*! \brief + * Calculates linear index of a grid cell from fractional coordinates. + * + * \param[in] cell Cell indices (must be within the grid). + * \returns Linear index of \p cell. + */ + int getGridCellIndex(const rvec cell) const; + /*! \brief + * Adds an index into a grid cell. + * + * \param[in] cell Fractional cell coordinates into which \p i should + * be added. + * \param[in] i Index to add. + * + * \p cell should satisfy the conditions that \p mapPointToGridCell() + * produces. + */ + void addToGridCell(const rvec cell, int i); + /*! \brief + * Initializes a cell pair loop for a dimension. + * + * \param[in] centerCell Fractional cell coordiates of the particle + * for which pairs are being searched. + * \param[in,out] cell Current/initial cell to loop over. + * \param[in,out] upperBound Last cell to loop over. + * \param[in] dim Dimension to initialize in this call. + * + * Initializes `cell[dim]` and `upperBound[dim]` for looping over + * neighbors of a particle at position given by \p centerCell. + * If 'dim != ZZ`, `cell[d]` (`d > dim`) set the plane/row of cells + * for which the loop is initialized. The loop should then go from + * `cell[dim]` until `upperBound[dim]`, inclusive. + * `cell[d]` with `d < dim` or `upperBound[d]` with `d != dim` are not + * modified by this function. + * + * `cell` and `upperBound` may be outside the grid for periodic + * dimensions and need to be shifted separately: to simplify the + * looping, the range is always (roughly) symmetric around the value in + * `centerCell`. + */ + void initCellRange(const rvec centerCell, ivec cell, ivec upperBound, int dim) const; + /*! \brief + * Computes the extent of the cutoff sphere on a particular cell edge. + * + * \param[in] centerCell Fractional cell coordiates of the particle + * for which pairs are being searched. + * \param[in] cell Current cell (for dimensions `>dim`). + * \param[in] dim Dimension to compute in this call. + * \returns Fractional extent of the cutoff sphere when looping + * over cells in dimension `dim`, for `cell[d]` (`d > dim`). + * + * Input parameters are as for initCellRange(), except that if `cell` + * is over a periodic boundary from `centerCell`, triclinic shifts + * should have been applied to `centerCell` X/Y components. + */ + real computeCutoffExtent(RVec centerCell, const ivec cell, int dim) const; + /*! \brief + * Advances cell pair loop to the next cell. + * + * \param[in] centerCell Fractional cell coordiates of the particle + * for which pairs are being searched. + * \param[in,out] cell Current (in)/next (out) cell in the loop. + * \param[in,out] upperBound Last cell in the loop for each dimension. + */ + bool nextCell(const rvec centerCell, ivec cell, ivec upperBound) const; + /*! \brief + * Calculates the index and shift of a grid cell during looping. + * + * \param[in] cell Unshifted cell index. + * \param[out] shift Shift to apply to get the periodic distance + * for distances between the cells. + * \returns Grid cell index corresponding to `cell`. + */ + int shiftCell(const ivec cell, rvec shift) const; + + //! Whether to try grid searching. + bool bTryGrid_; + //! The cutoff. + real cutoff_; + //! The cutoff squared. + real cutoff2_; + //! Whether to do searching in XY plane only. + bool bXY_; + + //! Number of reference points for the current frame. + int nref_; + //! Reference point positions. + const rvec* xref_; + //! Reference position exclusion IDs. + const int* refExclusionIds_; + //! Reference position indices (NULL if no indices). + const int* refIndices_; + //! Exclusions. + const t_blocka* excls_; + //! PBC data. + t_pbc pbc_; + + //! Whether grid searching is actually used for the current positions. + bool bGrid_; + //! false if the box is rectangular. + bool bTric_; + //! Whether the grid is periodic in a dimension. + bool bGridPBC_[DIM]; + //! Array for storing in-unit-cell reference positions. + std::vector xrefAlloc_; + //! Origin of the grid (zero for periodic dimensions). + rvec gridOrigin_; + //! Size of a single grid cell. + rvec cellSize_; + //! Inverse of \p cellSize_. Zero for dimensions where grid is not used. + rvec invCellSize_; + /*! \brief + * Shift in cell coordinates (for triclinic boxes) in X when crossing + * the Z periodic boundary. + */ + real cellShiftZX_; + /*! \brief + * Shift in cell coordinates (for triclinic boxes) in Y when crossing + * the Z periodic boundary. + */ + real cellShiftZY_; + /*! \brief + * Shift in cell coordinates (for triclinic boxes) in X when crossing + * the Y periodic boundary. + */ + real cellShiftYX_; + //! Number of cells along each dimension. + ivec ncelldim_; + //! Data structure to hold the grid cell contents. + CellList cells_; + + Mutex createPairSearchMutex_; + PairSearchList pairSearchList_; + + friend class AnalysisNeighborhoodPairSearchImpl; + + GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisNeighborhoodSearchImpl); }; class AnalysisNeighborhoodPairSearchImpl { - public: - explicit AnalysisNeighborhoodPairSearchImpl(const AnalysisNeighborhoodSearchImpl &search) - : search_(search) - { - selfSearchMode_ = false; - testPosCount_ = 0; - testPositions_ = nullptr; - testExclusionIds_ = nullptr; - testIndices_ = nullptr; - nexcl_ = 0; - excl_ = nullptr; - clear_rvec(xtest_); - clear_rvec(testcell_); - clear_ivec(currCell_); - clear_ivec(cellBound_); - reset(-1); - } +public: + explicit AnalysisNeighborhoodPairSearchImpl(const AnalysisNeighborhoodSearchImpl& search) : + search_(search) + { + selfSearchMode_ = false; + testPosCount_ = 0; + testPositions_ = nullptr; + testExclusionIds_ = nullptr; + testIndices_ = nullptr; + nexcl_ = 0; + excl_ = nullptr; + clear_rvec(xtest_); + clear_rvec(testcell_); + clear_ivec(currCell_); + clear_ivec(cellBound_); + reset(-1); + } - //! Initializes a search to find reference positions neighboring \p x. - void startSearch(const AnalysisNeighborhoodPositions &positions); - //! Initializes a search to find reference position pairs. - void startSelfSearch(); - //! Searches for the next neighbor. - template - bool searchNext(Action action); - //! Initializes a pair representing the pair found by searchNext(). - void initFoundPair(AnalysisNeighborhoodPair *pair) const; - //! Advances to the next test position, skipping any remaining pairs. - void nextTestPosition(); - - private: - //! Clears the loop indices. - void reset(int testIndex); - //! Checks whether a reference positiong should be excluded. - bool isExcluded(int j); - - //! Parent search object. - const AnalysisNeighborhoodSearchImpl &search_; - //! Whether we are searching for ref-ref pairs. - bool selfSearchMode_; - //! Number of test positions. - int testPosCount_; - //! Reference to the test positions. - const rvec *testPositions_; - //! Reference to the test exclusion indices. - const int *testExclusionIds_; - //! Reference to the test position indices. - const int *testIndices_; - //! Number of excluded reference positions for current test particle. - int nexcl_; - //! Exclusions for current test particle. - const int *excl_; - //! Index of the currently active test position in \p testPositions_. - int testIndex_; - //! Stores test position during a pair loop. - rvec xtest_; - //! Stores the previous returned position during a pair loop. - int previ_; - //! Stores the pair distance corresponding to previ_. - real prevr2_; - //! Stores the shortest distance vector corresponding to previ_. - rvec prevdx_; - //! Stores the current exclusion index during loops. - int exclind_; - //! Stores the fractional test particle cell location during loops. - rvec testcell_; - //! Stores the cell index corresponding to testcell_. - int testCellIndex_; - //! Stores the current cell during pair loops. - ivec currCell_; - //! Stores the current loop upper bounds for each dimension during pair loops. - ivec cellBound_; - //! Stores the index within the current cell during pair loops. - int prevcai_; - - GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisNeighborhoodPairSearchImpl); + //! Initializes a search to find reference positions neighboring \p x. + void startSearch(const AnalysisNeighborhoodPositions& positions); + //! Initializes a search to find reference position pairs. + void startSelfSearch(); + //! Searches for the next neighbor. + template + bool searchNext(Action action); + //! Initializes a pair representing the pair found by searchNext(). + void initFoundPair(AnalysisNeighborhoodPair* pair) const; + //! Advances to the next test position, skipping any remaining pairs. + void nextTestPosition(); + +private: + //! Clears the loop indices. + void reset(int testIndex); + //! Checks whether a reference positiong should be excluded. + bool isExcluded(int j); + + //! Parent search object. + const AnalysisNeighborhoodSearchImpl& search_; + //! Whether we are searching for ref-ref pairs. + bool selfSearchMode_; + //! Number of test positions. + int testPosCount_; + //! Reference to the test positions. + const rvec* testPositions_; + //! Reference to the test exclusion indices. + const int* testExclusionIds_; + //! Reference to the test position indices. + const int* testIndices_; + //! Number of excluded reference positions for current test particle. + int nexcl_; + //! Exclusions for current test particle. + const int* excl_; + //! Index of the currently active test position in \p testPositions_. + int testIndex_; + //! Stores test position during a pair loop. + rvec xtest_; + //! Stores the previous returned position during a pair loop. + int previ_; + //! Stores the pair distance corresponding to previ_. + real prevr2_; + //! Stores the shortest distance vector corresponding to previ_. + rvec prevdx_; + //! Stores the current exclusion index during loops. + int exclind_; + //! Stores the fractional test particle cell location during loops. + rvec testcell_; + //! Stores the cell index corresponding to testcell_. + int testCellIndex_; + //! Stores the current cell during pair loops. + ivec currCell_; + //! Stores the current loop upper bounds for each dimension during pair loops. + ivec cellBound_; + //! Stores the index within the current cell during pair loops. + int prevcai_; + + GMX_DISALLOW_COPY_AND_ASSIGN(AnalysisNeighborhoodPairSearchImpl); }; /******************************************************************** @@ -415,16 +412,16 @@ class AnalysisNeighborhoodPairSearchImpl AnalysisNeighborhoodSearchImpl::AnalysisNeighborhoodSearchImpl(real cutoff) { - bTryGrid_ = true; - cutoff_ = cutoff; + bTryGrid_ = true; + cutoff_ = cutoff; if (cutoff_ <= 0) { - cutoff_ = cutoff2_ = GMX_REAL_MAX; - bTryGrid_ = false; + cutoff_ = cutoff2_ = GMX_REAL_MAX; + bTryGrid_ = false; } else { - cutoff2_ = gmx::square(cutoff_); + cutoff2_ = gmx::square(cutoff_); } bXY_ = false; nref_ = 0; @@ -433,11 +430,11 @@ AnalysisNeighborhoodSearchImpl::AnalysisNeighborhoodSearchImpl(real cutoff) refIndices_ = nullptr; std::memset(&pbc_, 0, sizeof(pbc_)); - bGrid_ = false; - bTric_ = false; - bGridPBC_[XX] = true; - bGridPBC_[YY] = true; - bGridPBC_[ZZ] = true; + bGrid_ = false; + bTric_ = false; + bGridPBC_[XX] = true; + bGridPBC_[YY] = true; + bGridPBC_[ZZ] = true; clear_rvec(gridOrigin_); clear_rvec(cellSize_); @@ -450,13 +447,11 @@ AnalysisNeighborhoodSearchImpl::~AnalysisNeighborhoodSearchImpl() PairSearchList::const_iterator i; for (i = pairSearchList_.begin(); i != pairSearchList_.end(); ++i) { - GMX_RELEASE_ASSERT(i->unique(), - "Dangling AnalysisNeighborhoodPairSearch reference"); + GMX_RELEASE_ASSERT(i->unique(), "Dangling AnalysisNeighborhoodPairSearch reference"); } } -AnalysisNeighborhoodSearchImpl::PairSearchImplPointer -AnalysisNeighborhoodSearchImpl::getPairSearch() +AnalysisNeighborhoodSearchImpl::PairSearchImplPointer AnalysisNeighborhoodSearchImpl::getPairSearch() { lock_guard lock(createPairSearchMutex_); // TODO: Consider whether this needs to/can be faster, e.g., by keeping a @@ -474,8 +469,7 @@ AnalysisNeighborhoodSearchImpl::getPairSearch() return pairSearch; } -bool AnalysisNeighborhoodSearchImpl::initGridCells( - const matrix box, bool bSingleCell[DIM], int posCount) +bool AnalysisNeighborhoodSearchImpl::initGridCells(const matrix box, bool bSingleCell[DIM], int posCount) { // Determine the size of cubes where there are on average 10 positions. // The loop takes care of cases where some of the box edges are shorter @@ -515,7 +509,7 @@ bool AnalysisNeighborhoodSearchImpl::initGridCells( { break; } - targetsize = pow(volume * 10 / posCount, static_cast(1./dimCount)); + targetsize = pow(volume * 10 / posCount, static_cast(1. / dimCount)); prevDimCount = dimCount; } @@ -538,7 +532,7 @@ bool AnalysisNeighborhoodSearchImpl::initGridCells( } } totalCellCount *= cellCount; - ncelldim_[dd] = cellCount; + ncelldim_[dd] = cellCount; } if (totalCellCount <= 3) { @@ -558,8 +552,7 @@ bool AnalysisNeighborhoodSearchImpl::initGridCells( return true; } -bool AnalysisNeighborhoodSearchImpl::initGrid( - const t_pbc &pbc, int posCount, const rvec x[], bool bForce) +bool AnalysisNeighborhoodSearchImpl::initGrid(const t_pbc& pbc, int posCount, const rvec x[], bool bForce) { if (posCount == 0) { @@ -592,13 +585,13 @@ bool AnalysisNeighborhoodSearchImpl::initGrid( return false; } - bool bSingleCell[DIM] = {false, false, bXY_}; + bool bSingleCell[DIM] = { false, false, bXY_ }; matrix box; copy_mat(pbc.box, box); // TODO: In principle, we could use the bounding box for periodic // dimensions as well if the bounding box is sufficiently far from the box // edges. - rvec origin, boundingBoxSize; + rvec origin, boundingBoxSize; computeBoundingBox(posCount, x, origin, boundingBoxSize); clear_rvec(gridOrigin_); for (int dd = 0; dd < DIM; ++dd) @@ -639,7 +632,7 @@ bool AnalysisNeighborhoodSearchImpl::initGrid( // TODO: It could be better to avoid this when determining the cell // size, but this can still remain here as a fallback to avoid // incorrect results. - if (std::ceil(2*cutoff_*invCellSize_[dd]) >= ncelldim_[dd]) + if (std::ceil(2 * cutoff_ * invCellSize_[dd]) >= ncelldim_[dd]) { // Cutoff is too close to half the box size for grid searching // (it is not possible to find a single shift for every pair of @@ -657,9 +650,7 @@ bool AnalysisNeighborhoodSearchImpl::initGrid( return true; } -void AnalysisNeighborhoodSearchImpl::mapPointToGridCell(const rvec x, - rvec cell, - rvec xout) const +void AnalysisNeighborhoodSearchImpl::mapPointToGridCell(const rvec x, rvec cell, rvec xout) const { rvec xtmp; rvec_sub(x, gridOrigin_, xtmp); @@ -690,14 +681,10 @@ void AnalysisNeighborhoodSearchImpl::mapPointToGridCell(const rvec x, int AnalysisNeighborhoodSearchImpl::getGridCellIndex(const ivec cell) const { - GMX_ASSERT(cell[XX] >= 0 && cell[XX] < ncelldim_[XX], - "Grid cell X index out of range"); - GMX_ASSERT(cell[YY] >= 0 && cell[YY] < ncelldim_[YY], - "Grid cell Y index out of range"); - GMX_ASSERT(cell[ZZ] >= 0 && cell[ZZ] < ncelldim_[ZZ], - "Grid cell Z index out of range"); - return cell[XX] + cell[YY] * ncelldim_[XX] - + cell[ZZ] * ncelldim_[XX] * ncelldim_[YY]; + GMX_ASSERT(cell[XX] >= 0 && cell[XX] < ncelldim_[XX], "Grid cell X index out of range"); + GMX_ASSERT(cell[YY] >= 0 && cell[YY] < ncelldim_[YY], "Grid cell Y index out of range"); + GMX_ASSERT(cell[ZZ] >= 0 && cell[ZZ] < ncelldim_[ZZ], "Grid cell Z index out of range"); + return cell[XX] + cell[YY] * ncelldim_[XX] + cell[ZZ] * ncelldim_[XX] * ncelldim_[YY]; } int AnalysisNeighborhoodSearchImpl::getGridCellIndex(const rvec cell) const @@ -729,10 +716,9 @@ void AnalysisNeighborhoodSearchImpl::addToGridCell(const rvec cell, int i) cells_[ci].push_back(i); } -void AnalysisNeighborhoodSearchImpl::initCellRange( - const rvec centerCell, ivec currCell, ivec upperBound, int dim) const +void AnalysisNeighborhoodSearchImpl::initCellRange(const rvec centerCell, ivec currCell, ivec upperBound, int dim) const { - RVec shiftedCenter(centerCell); + RVec shiftedCenter(centerCell); // Shift the center to the cell coordinates of currCell, so that // computeCutoffExtent() can assume simple rectangular grid. if (bTric_) @@ -790,8 +776,7 @@ void AnalysisNeighborhoodSearchImpl::initCellRange( upperBound[dim] = static_cast(floor(endOffset)); } -real AnalysisNeighborhoodSearchImpl::computeCutoffExtent( - const RVec centerCell, const ivec cell, int dim) const +real AnalysisNeighborhoodSearchImpl::computeCutoffExtent(const RVec centerCell, const ivec cell, int dim) const { if (dim == ZZ) { @@ -810,7 +795,7 @@ real AnalysisNeighborhoodSearchImpl::computeCutoffExtent( { continue; } - dist2 += dimDist*dimDist*cellSize_[d]*cellSize_[d]; + dist2 += dimDist * dimDist * cellSize_[d] * cellSize_[d]; } if (dist2 >= cutoff2_) { @@ -819,13 +804,12 @@ real AnalysisNeighborhoodSearchImpl::computeCutoffExtent( return std::sqrt(cutoff2_ - dist2); } -bool AnalysisNeighborhoodSearchImpl::nextCell( - const rvec centerCell, ivec cell, ivec upperBound) const +bool AnalysisNeighborhoodSearchImpl::nextCell(const rvec centerCell, ivec cell, ivec upperBound) const { int dim = 0; while (dim < DIM) { -next: + next: ++cell[dim]; if (cell[dim] > upperBound[dim]) { @@ -876,12 +860,11 @@ int AnalysisNeighborhoodSearchImpl::shiftCell(const ivec cell, rvec shift) const return getGridCellIndex(shiftedCell); } -void AnalysisNeighborhoodSearchImpl::init( - AnalysisNeighborhood::SearchMode mode, - bool bXY, - const t_blocka *excls, - const t_pbc *pbc, - const AnalysisNeighborhoodPositions &positions) +void AnalysisNeighborhoodSearchImpl::init(AnalysisNeighborhood::SearchMode mode, + bool bXY, + const t_blocka* excls, + const t_pbc* pbc, + const AnalysisNeighborhoodPositions& positions) { GMX_RELEASE_ASSERT(positions.index_ == -1, "Individual indexed positions not supported as reference"); @@ -890,16 +873,18 @@ void AnalysisNeighborhoodSearchImpl::init( { if (pbc->ePBC != epbcXY && pbc->ePBC != epbcXYZ) { - std::string message = - formatString("Computations in the XY plane are not supported with PBC type '%s'", - epbc_names[pbc->ePBC]); + std::string message = formatString( + "Computations in the XY plane are not supported with PBC type '%s'", + epbc_names[pbc->ePBC]); GMX_THROW(NotImplementedError(message)); } - if (pbc->ePBC == epbcXYZ && - (std::fabs(pbc->box[ZZ][XX]) > GMX_REAL_EPS*pbc->box[ZZ][ZZ] || - std::fabs(pbc->box[ZZ][YY]) > GMX_REAL_EPS*pbc->box[ZZ][ZZ])) + if (pbc->ePBC == epbcXYZ + && (std::fabs(pbc->box[ZZ][XX]) > GMX_REAL_EPS * pbc->box[ZZ][ZZ] + || std::fabs(pbc->box[ZZ][YY]) > GMX_REAL_EPS * pbc->box[ZZ][ZZ])) { - GMX_THROW(NotImplementedError("Computations in the XY plane are not supported when the last box vector is not parallel to the Z axis")); + GMX_THROW( + NotImplementedError("Computations in the XY plane are not supported when the " + "last box vector is not parallel to the Z axis")); } // Use a single grid cell in Z direction. matrix box; @@ -976,12 +961,11 @@ void AnalysisNeighborhoodPairSearchImpl::reset(int testIndex) previ_ = -1; prevr2_ = 0.0; clear_rvec(prevdx_); - exclind_ = 0; - prevcai_ = -1; + exclind_ = 0; + prevcai_ = -1; if (testIndex_ >= 0 && testIndex_ < testPosCount_) { - const int index = - (testIndices_ != nullptr ? testIndices_[testIndex] : testIndex); + const int index = (testIndices_ != nullptr ? testIndices_[testIndex] : testIndex); if (search_.bGrid_) { search_.mapPointToGridCell(testPositions_[index], testcell_, xtest_); @@ -1003,12 +987,12 @@ void AnalysisNeighborhoodPairSearchImpl::reset(int testIndex) } if (search_.excls_ != nullptr) { - const int exclIndex = testExclusionIds_[index]; + const int exclIndex = testExclusionIds_[index]; if (exclIndex < search_.excls_->nr) { const int startIndex = search_.excls_->index[exclIndex]; - nexcl_ = search_.excls_->index[exclIndex + 1] - startIndex; - excl_ = &search_.excls_->a[startIndex]; + nexcl_ = search_.excls_->index[exclIndex + 1] - startIndex; + excl_ = &search_.excls_->a[startIndex]; } else { @@ -1032,8 +1016,7 @@ bool AnalysisNeighborhoodPairSearchImpl::isExcluded(int j) { if (exclind_ < nexcl_) { - const int index = - (search_.refIndices_ != nullptr ? search_.refIndices_[j] : j); + const int index = (search_.refIndices_ != nullptr ? search_.refIndices_[j] : j); const int refId = search_.refExclusionIds_[index]; while (exclind_ < nexcl_ && excl_[exclind_] < refId) { @@ -1048,8 +1031,7 @@ bool AnalysisNeighborhoodPairSearchImpl::isExcluded(int j) return false; } -void AnalysisNeighborhoodPairSearchImpl::startSearch( - const AnalysisNeighborhoodPositions &positions) +void AnalysisNeighborhoodPairSearchImpl::startSearch(const AnalysisNeighborhoodPositions& positions) { selfSearchMode_ = false; testPosCount_ = positions.count_; @@ -1083,7 +1065,7 @@ void AnalysisNeighborhoodPairSearchImpl::startSelfSearch() reset(0); } -template +template bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) { while (testIndex_ < testPosCount_) @@ -1095,7 +1077,7 @@ bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) do { rvec shift; - const int ci = search_.shiftCell(currCell_, shift); + const int ci = search_.shiftCell(currCell_, shift); if (selfSearchMode_ && ci > testCellIndex_) { continue; @@ -1112,13 +1094,10 @@ bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) { continue; } - rvec dx; + rvec dx; rvec_sub(search_.xref_[i], xtest_, dx); rvec_sub(dx, shift, dx); - const real r2 - = search_.bXY_ - ? dx[XX]*dx[XX] + dx[YY]*dx[YY] - : norm2(dx); + const real r2 = search_.bXY_ ? dx[XX] * dx[XX] + dx[YY] * dx[YY] : norm2(dx); if (r2 <= search_.cutoff2_) { if (action(i, r2, dx)) @@ -1133,8 +1112,7 @@ bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) } exclind_ = 0; cai = 0; - } - while (search_.nextCell(testcell_, currCell_, cellBound_)); + } while (search_.nextCell(testcell_, currCell_, cellBound_)); } else { @@ -1153,10 +1131,7 @@ bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) { rvec_sub(search_.xref_[i], xtest_, dx); } - const real r2 - = search_.bXY_ - ? dx[XX]*dx[XX] + dx[YY]*dx[YY] - : norm2(dx); + const real r2 = search_.bXY_ ? dx[XX] * dx[XX] + dx[YY] * dx[YY] : norm2(dx); if (r2 <= search_.cutoff2_) { if (action(i, r2, dx)) @@ -1174,8 +1149,7 @@ bool AnalysisNeighborhoodPairSearchImpl::searchNext(Action action) return false; } -void AnalysisNeighborhoodPairSearchImpl::initFoundPair( - AnalysisNeighborhoodPair *pair) const +void AnalysisNeighborhoodPairSearchImpl::initFoundPair(AnalysisNeighborhoodPair* pair) const { if (previ_ < 0) { @@ -1187,7 +1161,7 @@ void AnalysisNeighborhoodPairSearchImpl::initFoundPair( } } -} // namespace internal +} // namespace internal namespace { @@ -1218,46 +1192,49 @@ bool withinAction(int /*i*/, real /*r2*/, const rvec /* dx */) */ class MindistAction { - public: - /*! \brief - * Initializes the action with given output locations. - * - * \param[out] closestPoint Index of the closest reference location. - * \param[out] minDist2 Minimum distance squared. - * \param[out] dx Shortest distance vector. - * - * The constructor call does not modify the pointed values, but only - * stores the pointers for later use. - * See the class description for additional semantics. - */ - MindistAction(int *closestPoint, real *minDist2, rvec *dx) // NOLINT(readability-non-const-parameter) - : closestPoint_(*closestPoint), minDist2_(*minDist2), dx_(*dx) - { - } - //! Copies the action. - MindistAction(const MindistAction &) = default; +public: + /*! \brief + * Initializes the action with given output locations. + * + * \param[out] closestPoint Index of the closest reference location. + * \param[out] minDist2 Minimum distance squared. + * \param[out] dx Shortest distance vector. + * + * The constructor call does not modify the pointed values, but only + * stores the pointers for later use. + * See the class description for additional semantics. + */ + MindistAction(int* closestPoint, real* minDist2, rvec* dx) // NOLINT(readability-non-const-parameter) + : + closestPoint_(*closestPoint), + minDist2_(*minDist2), + dx_(*dx) + { + } + //! Copies the action. + MindistAction(const MindistAction&) = default; - //! Processes a neighbor to find the nearest point. - bool operator()(int i, real r2, const rvec dx) + //! Processes a neighbor to find the nearest point. + bool operator()(int i, real r2, const rvec dx) + { + if (r2 < minDist2_) { - if (r2 < minDist2_) - { - closestPoint_ = i; - minDist2_ = r2; - copy_rvec(dx, dx_); - } - return false; + closestPoint_ = i; + minDist2_ = r2; + copy_rvec(dx, dx_); } + return false; + } - private: - int &closestPoint_; - real &minDist2_; - rvec &dx_; +private: + int& closestPoint_; + real& minDist2_; + rvec& dx_; - GMX_DISALLOW_ASSIGN(MindistAction); + GMX_DISALLOW_ASSIGN(MindistAction); }; -} // namespace +} // namespace /******************************************************************** * AnalysisNeighborhood::Impl @@ -1265,36 +1242,31 @@ class MindistAction class AnalysisNeighborhood::Impl { - public: - typedef AnalysisNeighborhoodSearch::ImplPointer SearchImplPointer; - typedef std::vector SearchList; +public: + typedef AnalysisNeighborhoodSearch::ImplPointer SearchImplPointer; + typedef std::vector SearchList; - Impl() - : cutoff_(0), excls_(nullptr), mode_(eSearchMode_Automatic), bXY_(false) - { - } - ~Impl() + Impl() : cutoff_(0), excls_(nullptr), mode_(eSearchMode_Automatic), bXY_(false) {} + ~Impl() + { + SearchList::const_iterator i; + for (i = searchList_.begin(); i != searchList_.end(); ++i) { - SearchList::const_iterator i; - for (i = searchList_.begin(); i != searchList_.end(); ++i) - { - GMX_RELEASE_ASSERT(i->unique(), - "Dangling AnalysisNeighborhoodSearch reference"); - } + GMX_RELEASE_ASSERT(i->unique(), "Dangling AnalysisNeighborhoodSearch reference"); } + } - SearchImplPointer getSearch(); + SearchImplPointer getSearch(); - Mutex createSearchMutex_; - SearchList searchList_; - real cutoff_; - const t_blocka *excls_; - SearchMode mode_; - bool bXY_; + Mutex createSearchMutex_; + SearchList searchList_; + real cutoff_; + const t_blocka* excls_; + SearchMode mode_; + bool bXY_; }; -AnalysisNeighborhood::Impl::SearchImplPointer -AnalysisNeighborhood::Impl::getSearch() +AnalysisNeighborhood::Impl::SearchImplPointer AnalysisNeighborhood::Impl::getSearch() { lock_guard lock(createSearchMutex_); // TODO: Consider whether this needs to/can be faster, e.g., by keeping a @@ -1316,14 +1288,9 @@ AnalysisNeighborhood::Impl::getSearch() * AnalysisNeighborhood */ -AnalysisNeighborhood::AnalysisNeighborhood() - : impl_(new Impl) -{ -} +AnalysisNeighborhood::AnalysisNeighborhood() : impl_(new Impl) {} -AnalysisNeighborhood::~AnalysisNeighborhood() -{ -} +AnalysisNeighborhood::~AnalysisNeighborhood() {} void AnalysisNeighborhood::setCutoff(real cutoff) { @@ -1337,7 +1304,7 @@ void AnalysisNeighborhood::setXYMode(bool bXY) impl_->bXY_ = bXY; } -void AnalysisNeighborhood::setTopologyExclusions(const t_blocka *excls) +void AnalysisNeighborhood::setTopologyExclusions(const t_blocka* excls) { GMX_RELEASE_ASSERT(impl_->searchList_.empty(), "Changing the exclusions after initSearch() not currently supported"); @@ -1354,13 +1321,11 @@ AnalysisNeighborhood::SearchMode AnalysisNeighborhood::mode() const return impl_->mode_; } -AnalysisNeighborhoodSearch -AnalysisNeighborhood::initSearch(const t_pbc *pbc, - const AnalysisNeighborhoodPositions &positions) +AnalysisNeighborhoodSearch AnalysisNeighborhood::initSearch(const t_pbc* pbc, + const AnalysisNeighborhoodPositions& positions) { Impl::SearchImplPointer search(impl_->getSearch()); - search->init(mode(), impl_->bXY_, impl_->excls_, - pbc, positions); + search->init(mode(), impl_->bXY_, impl_->excls_, pbc, positions); return AnalysisNeighborhoodSearch(search); } @@ -1368,14 +1333,9 @@ AnalysisNeighborhood::initSearch(const t_pbc *pbc, * AnalysisNeighborhoodSearch */ -AnalysisNeighborhoodSearch::AnalysisNeighborhoodSearch() -{ -} +AnalysisNeighborhoodSearch::AnalysisNeighborhoodSearch() {} -AnalysisNeighborhoodSearch::AnalysisNeighborhoodSearch(const ImplPointer &impl) - : impl_(impl) -{ -} +AnalysisNeighborhoodSearch::AnalysisNeighborhoodSearch(const ImplPointer& impl) : impl_(impl) {} void AnalysisNeighborhoodSearch::reset() { @@ -1385,13 +1345,11 @@ void AnalysisNeighborhoodSearch::reset() AnalysisNeighborhood::SearchMode AnalysisNeighborhoodSearch::mode() const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); - return (impl_->usesGridSearch() - ? AnalysisNeighborhood::eSearchMode_Grid - : AnalysisNeighborhood::eSearchMode_Simple); + return (impl_->usesGridSearch() ? AnalysisNeighborhood::eSearchMode_Grid + : AnalysisNeighborhood::eSearchMode_Simple); } -bool AnalysisNeighborhoodSearch::isWithin( - const AnalysisNeighborhoodPositions &positions) const +bool AnalysisNeighborhoodSearch::isWithin(const AnalysisNeighborhoodPositions& positions) const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); internal::AnalysisNeighborhoodPairSearchImpl pairSearch(*impl_); @@ -1399,37 +1357,33 @@ bool AnalysisNeighborhoodSearch::isWithin( return pairSearch.searchNext(&withinAction); } -real AnalysisNeighborhoodSearch::minimumDistance( - const AnalysisNeighborhoodPositions &positions) const +real AnalysisNeighborhoodSearch::minimumDistance(const AnalysisNeighborhoodPositions& positions) const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); internal::AnalysisNeighborhoodPairSearchImpl pairSearch(*impl_); pairSearch.startSearch(positions); real minDist2 = impl_->cutoffSquared(); int closestPoint = -1; - rvec dx = {0.0, 0.0, 0.0}; + rvec dx = { 0.0, 0.0, 0.0 }; MindistAction action(&closestPoint, &minDist2, &dx); (void)pairSearch.searchNext(action); return std::sqrt(minDist2); } -AnalysisNeighborhoodPair -AnalysisNeighborhoodSearch::nearestPoint( - const AnalysisNeighborhoodPositions &positions) const +AnalysisNeighborhoodPair AnalysisNeighborhoodSearch::nearestPoint(const AnalysisNeighborhoodPositions& positions) const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); internal::AnalysisNeighborhoodPairSearchImpl pairSearch(*impl_); pairSearch.startSearch(positions); real minDist2 = impl_->cutoffSquared(); int closestPoint = -1; - rvec dx = {0.0, 0.0, 0.0}; + rvec dx = { 0.0, 0.0, 0.0 }; MindistAction action(&closestPoint, &minDist2, &dx); (void)pairSearch.searchNext(action); return AnalysisNeighborhoodPair(closestPoint, 0, minDist2, dx); } -AnalysisNeighborhoodPairSearch -AnalysisNeighborhoodSearch::startSelfPairSearch() const +AnalysisNeighborhoodPairSearch AnalysisNeighborhoodSearch::startSelfPairSearch() const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); Impl::PairSearchImplPointer pairSearch(impl_->getPairSearch()); @@ -1438,8 +1392,7 @@ AnalysisNeighborhoodSearch::startSelfPairSearch() const } AnalysisNeighborhoodPairSearch -AnalysisNeighborhoodSearch::startPairSearch( - const AnalysisNeighborhoodPositions &positions) const +AnalysisNeighborhoodSearch::startPairSearch(const AnalysisNeighborhoodPositions& positions) const { GMX_RELEASE_ASSERT(impl_, "Accessing an invalid search object"); Impl::PairSearchImplPointer pairSearch(impl_->getPairSearch()); @@ -1451,13 +1404,12 @@ AnalysisNeighborhoodSearch::startPairSearch( * AnalysisNeighborhoodPairSearch */ -AnalysisNeighborhoodPairSearch::AnalysisNeighborhoodPairSearch( - const ImplPointer &impl) - : impl_(impl) +AnalysisNeighborhoodPairSearch::AnalysisNeighborhoodPairSearch(const ImplPointer& impl) : + impl_(impl) { } -bool AnalysisNeighborhoodPairSearch::findNextPair(AnalysisNeighborhoodPair *pair) +bool AnalysisNeighborhoodPairSearch::findNextPair(AnalysisNeighborhoodPair* pair) { bool bFound = impl_->searchNext(&withinAction); impl_->initFoundPair(pair); diff --git a/src/gromacs/selection/nbsearch.h b/src/gromacs/selection/nbsearch.h index 7280d206bb..ffe93854b6 100644 --- a/src/gromacs/selection/nbsearch.h +++ b/src/gromacs/selection/nbsearch.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,7 +69,7 @@ namespace internal { class AnalysisNeighborhoodSearchImpl; class AnalysisNeighborhoodPairSearchImpl; -}; +}; // namespace internal class AnalysisNeighborhoodSearch; class AnalysisNeighborhoodPairSearch; @@ -98,97 +99,105 @@ class AnalysisNeighborhoodPairSearch; */ class AnalysisNeighborhoodPositions { - public: - /*! \brief - * Initializes positions from a single position vector. - * - * For positions initialized this way, AnalysisNeighborhoodPair always - * returns zero in the corresponding index. - * - * This constructor is not explicit to allow directly passing an rvec - * to methods that accept positions. - */ - AnalysisNeighborhoodPositions(const rvec &x) - : count_(1), index_(-1), x_(&x), exclusionIds_(nullptr), indices_(nullptr) - { - } - /*! \brief - * Initializes positions from an array of position vectors. - */ - AnalysisNeighborhoodPositions(const rvec x[], int count) - : count_(count), index_(-1), x_(x), exclusionIds_(nullptr), indices_(nullptr) - { - } - /*! \brief - * Initializes positions from a vector of position vectors. - */ - AnalysisNeighborhoodPositions(const std::vector &x) - : count_(ssize(x)), index_(-1), x_(as_rvec_array(x.data())), - exclusionIds_(nullptr), indices_(nullptr) - { - } - - /*! \brief - * Sets indices to use for mapping exclusions to these positions. - * - * The exclusion IDs can always be set, but they are ignored unless - * actual exclusions have been set with - * AnalysisNeighborhood::setTopologyExclusions(). - */ - AnalysisNeighborhoodPositions & - exclusionIds(ArrayRef ids) - { - GMX_ASSERT(ssize(ids) == count_, - "Exclusion id array should match the number of positions"); - exclusionIds_ = ids.data(); - return *this; - } - /*! \brief - * Sets indices that select a subset of all positions from the array. - * - * If called, selected positions from the array of positions passed to - * the constructor is used instead of the whole array. - * All returned indices from AnalysisNeighborhoodPair objects are - * indices to the \p indices array passed here. - */ - AnalysisNeighborhoodPositions & - indexed(ArrayRef indices) - { - count_ = ssize(indices); - indices_ = indices.data(); - return *this; - } - - /*! \brief - * Selects a single position to use from an array. - * - * If called, a single position from the array of positions passed to - * the constructor is used instead of the whole array. - * In contrast to the AnalysisNeighborhoodPositions(const rvec &) - * constructor, AnalysisNeighborhoodPair objects return \p index - * instead of zero. - * - * If used together with indexed(), \p index references the index array - * passed to indexed() instead of the position array. - */ - AnalysisNeighborhoodPositions &selectSingleFromArray(int index) - { - GMX_ASSERT(index >= 0 && index < count_, "Invalid position index"); - index_ = index; - return *this; - } - - private: - int count_; - int index_; - const rvec *x_; - const int *exclusionIds_; - const int *indices_; - - //! To access the positions for initialization. - friend class internal::AnalysisNeighborhoodSearchImpl; - //! To access the positions for initialization. - friend class internal::AnalysisNeighborhoodPairSearchImpl; +public: + /*! \brief + * Initializes positions from a single position vector. + * + * For positions initialized this way, AnalysisNeighborhoodPair always + * returns zero in the corresponding index. + * + * This constructor is not explicit to allow directly passing an rvec + * to methods that accept positions. + */ + AnalysisNeighborhoodPositions(const rvec& x) : + count_(1), + index_(-1), + x_(&x), + exclusionIds_(nullptr), + indices_(nullptr) + { + } + /*! \brief + * Initializes positions from an array of position vectors. + */ + AnalysisNeighborhoodPositions(const rvec x[], int count) : + count_(count), + index_(-1), + x_(x), + exclusionIds_(nullptr), + indices_(nullptr) + { + } + /*! \brief + * Initializes positions from a vector of position vectors. + */ + AnalysisNeighborhoodPositions(const std::vector& x) : + count_(ssize(x)), + index_(-1), + x_(as_rvec_array(x.data())), + exclusionIds_(nullptr), + indices_(nullptr) + { + } + + /*! \brief + * Sets indices to use for mapping exclusions to these positions. + * + * The exclusion IDs can always be set, but they are ignored unless + * actual exclusions have been set with + * AnalysisNeighborhood::setTopologyExclusions(). + */ + AnalysisNeighborhoodPositions& exclusionIds(ArrayRef ids) + { + GMX_ASSERT(ssize(ids) == count_, "Exclusion id array should match the number of positions"); + exclusionIds_ = ids.data(); + return *this; + } + /*! \brief + * Sets indices that select a subset of all positions from the array. + * + * If called, selected positions from the array of positions passed to + * the constructor is used instead of the whole array. + * All returned indices from AnalysisNeighborhoodPair objects are + * indices to the \p indices array passed here. + */ + AnalysisNeighborhoodPositions& indexed(ArrayRef indices) + { + count_ = ssize(indices); + indices_ = indices.data(); + return *this; + } + + /*! \brief + * Selects a single position to use from an array. + * + * If called, a single position from the array of positions passed to + * the constructor is used instead of the whole array. + * In contrast to the AnalysisNeighborhoodPositions(const rvec &) + * constructor, AnalysisNeighborhoodPair objects return \p index + * instead of zero. + * + * If used together with indexed(), \p index references the index array + * passed to indexed() instead of the position array. + */ + AnalysisNeighborhoodPositions& selectSingleFromArray(int index) + { + GMX_ASSERT(index >= 0 && index < count_, "Invalid position index"); + index_ = index; + return *this; + } + +private: + int count_; + int index_; + const rvec* x_; + const int* exclusionIds_; + const int* indices_; + + //! To access the positions for initialization. + friend class internal::AnalysisNeighborhoodSearchImpl; + //! To access the positions for initialization. + friend class internal::AnalysisNeighborhoodPairSearchImpl; }; /*! \brief @@ -218,98 +227,96 @@ class AnalysisNeighborhoodPositions */ class AnalysisNeighborhood { - public: - //! Searching algorithm to use. - enum SearchMode - { - //! Select algorithm based on heuristic efficiency considerations. - eSearchMode_Automatic, - //! Use a simple loop over all pairs. - eSearchMode_Simple, - //! Use grid-based searching whenever possible. - eSearchMode_Grid - }; - - //! Creates an uninitialized neighborhood search. - AnalysisNeighborhood(); - ~AnalysisNeighborhood(); - - /*! \brief - * Sets cutoff distance for the neighborhood searching. - * - * \param[in] cutoff Cutoff distance for the search - * (<=0 stands for no cutoff). - * - * Currently, can only be called before the first call to initSearch(). - * If this method is not called, no cutoff is used in the searches. - * - * Does not throw. - */ - void setCutoff(real cutoff); - /*! \brief - * Sets the search to only happen in the XY plane. - * - * Z component of the coordinates is not used in the searching, - * and returned distances are computed in the XY plane. - * Only boxes with the third box vector parallel to the Z axis are - * currently implemented. - * - * Does not throw. - */ - void setXYMode(bool bXY); - /*! \brief - * Sets atom exclusions from a topology. - * - * The \p excls structure specifies the exclusions from test positions - * to reference positions, i.e., a block starting at `excls->index[i]` - * specifies the exclusions for test position `i`, and the indices in - * `excls->a` are indices of the reference positions. If `excls->nr` - * is smaller than a test position id, then such test positions do not - * have any exclusions. - * It is assumed that the indices within a block of indices in - * `excls->a` is ascending. - * - * Does not throw. - * - * \see AnalysisNeighborhoodPositions::exclusionIds() - */ - void setTopologyExclusions(const t_blocka *excls); - /*! \brief - * Sets the algorithm to use for searching. - * - * \param[in] mode Search mode to use. - * - * Note that if \p mode is \ref eSearchMode_Grid, it is still only a - * suggestion: grid-based searching may not be possible with the - * provided input, in which case a simple search is still used. - * This is mainly useful for testing purposes to force a mode. - * - * Does not throw. - */ - void setMode(SearchMode mode); - //! Returns the currently active search mode. - SearchMode mode() const; - - /*! \brief - * Initializes neighborhood search for a set of positions. - * - * \param[in] pbc PBC information for the frame. - * \param[in] positions Set of reference positions to use. - * \returns Search object that can be used to find positions from - * \p x within the given cutoff. - * \throws std::bad_alloc if out of memory. - * - * Currently, the input positions cannot use - * AnalysisNeighborhoodPositions::selectSingleFromArray(). - */ - AnalysisNeighborhoodSearch - initSearch(const t_pbc *pbc, - const AnalysisNeighborhoodPositions &positions); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + //! Searching algorithm to use. + enum SearchMode + { + //! Select algorithm based on heuristic efficiency considerations. + eSearchMode_Automatic, + //! Use a simple loop over all pairs. + eSearchMode_Simple, + //! Use grid-based searching whenever possible. + eSearchMode_Grid + }; + + //! Creates an uninitialized neighborhood search. + AnalysisNeighborhood(); + ~AnalysisNeighborhood(); + + /*! \brief + * Sets cutoff distance for the neighborhood searching. + * + * \param[in] cutoff Cutoff distance for the search + * (<=0 stands for no cutoff). + * + * Currently, can only be called before the first call to initSearch(). + * If this method is not called, no cutoff is used in the searches. + * + * Does not throw. + */ + void setCutoff(real cutoff); + /*! \brief + * Sets the search to only happen in the XY plane. + * + * Z component of the coordinates is not used in the searching, + * and returned distances are computed in the XY plane. + * Only boxes with the third box vector parallel to the Z axis are + * currently implemented. + * + * Does not throw. + */ + void setXYMode(bool bXY); + /*! \brief + * Sets atom exclusions from a topology. + * + * The \p excls structure specifies the exclusions from test positions + * to reference positions, i.e., a block starting at `excls->index[i]` + * specifies the exclusions for test position `i`, and the indices in + * `excls->a` are indices of the reference positions. If `excls->nr` + * is smaller than a test position id, then such test positions do not + * have any exclusions. + * It is assumed that the indices within a block of indices in + * `excls->a` is ascending. + * + * Does not throw. + * + * \see AnalysisNeighborhoodPositions::exclusionIds() + */ + void setTopologyExclusions(const t_blocka* excls); + /*! \brief + * Sets the algorithm to use for searching. + * + * \param[in] mode Search mode to use. + * + * Note that if \p mode is \ref eSearchMode_Grid, it is still only a + * suggestion: grid-based searching may not be possible with the + * provided input, in which case a simple search is still used. + * This is mainly useful for testing purposes to force a mode. + * + * Does not throw. + */ + void setMode(SearchMode mode); + //! Returns the currently active search mode. + SearchMode mode() const; + + /*! \brief + * Initializes neighborhood search for a set of positions. + * + * \param[in] pbc PBC information for the frame. + * \param[in] positions Set of reference positions to use. + * \returns Search object that can be used to find positions from + * \p x within the given cutoff. + * \throws std::bad_alloc if out of memory. + * + * Currently, the input positions cannot use + * AnalysisNeighborhoodPositions::selectSingleFromArray(). + */ + AnalysisNeighborhoodSearch initSearch(const t_pbc* pbc, const AnalysisNeighborhoodPositions& positions); + +private: + class Impl; + + PrivateImplPointer impl_; }; /*! \brief @@ -322,73 +329,73 @@ class AnalysisNeighborhood */ class AnalysisNeighborhoodPair { - public: - //! Initializes an invalid pair. - AnalysisNeighborhoodPair() : refIndex_(-1), testIndex_(0), distance2_(0.0), dx_() - { - } - //! Initializes a pair object with the given data. - AnalysisNeighborhoodPair(int refIndex, int testIndex, real distance2, - const rvec dx) - : refIndex_(refIndex), testIndex_(testIndex), distance2_(distance2), dx_() - { - copy_rvec(dx, dx_); - } - - /*! \brief - * Whether this pair is valid. - * - * If isValid() returns false, other methods should not be called. - */ - bool isValid() const { return refIndex_ >= 0; } - - /*! \brief - * Returns the index of the reference position in the pair. - * - * This index is always the index into the position array provided to - * AnalysisNeighborhood::initSearch(). - */ - int refIndex() const - { - GMX_ASSERT(isValid(), "Accessing invalid object"); - return refIndex_; - } - /*! \brief - * Returns the index of the test position in the pair. - * - * The contents of this index depends on the context (method call) that - * produces the pair. - * If there was no array in the call, this index is zero. - */ - int testIndex() const - { - GMX_ASSERT(isValid(), "Accessing invalid object"); - return testIndex_; - } - /*! \brief - * Returns the squared distance between the pair of positions. - */ - real distance2() const - { - GMX_ASSERT(isValid(), "Accessing invalid object"); - return distance2_; - } - /*! \brief - * Returns the shortest vector between the pair of positions. - * - * The vector is from the test position to the reference position. - */ - const rvec &dx() const - { - GMX_ASSERT(isValid(), "Accessing invalid object"); - return dx_; - } - - private: - int refIndex_; - int testIndex_; - real distance2_; - rvec dx_; +public: + //! Initializes an invalid pair. + AnalysisNeighborhoodPair() : refIndex_(-1), testIndex_(0), distance2_(0.0), dx_() {} + //! Initializes a pair object with the given data. + AnalysisNeighborhoodPair(int refIndex, int testIndex, real distance2, const rvec dx) : + refIndex_(refIndex), + testIndex_(testIndex), + distance2_(distance2), + dx_() + { + copy_rvec(dx, dx_); + } + + /*! \brief + * Whether this pair is valid. + * + * If isValid() returns false, other methods should not be called. + */ + bool isValid() const { return refIndex_ >= 0; } + + /*! \brief + * Returns the index of the reference position in the pair. + * + * This index is always the index into the position array provided to + * AnalysisNeighborhood::initSearch(). + */ + int refIndex() const + { + GMX_ASSERT(isValid(), "Accessing invalid object"); + return refIndex_; + } + /*! \brief + * Returns the index of the test position in the pair. + * + * The contents of this index depends on the context (method call) that + * produces the pair. + * If there was no array in the call, this index is zero. + */ + int testIndex() const + { + GMX_ASSERT(isValid(), "Accessing invalid object"); + return testIndex_; + } + /*! \brief + * Returns the squared distance between the pair of positions. + */ + real distance2() const + { + GMX_ASSERT(isValid(), "Accessing invalid object"); + return distance2_; + } + /*! \brief + * Returns the shortest vector between the pair of positions. + * + * The vector is from the test position to the reference position. + */ + const rvec& dx() const + { + GMX_ASSERT(isValid(), "Accessing invalid object"); + return dx_; + } + +private: + int refIndex_; + int testIndex_; + real distance2_; + rvec dx_; }; /*! \brief @@ -422,118 +429,114 @@ class AnalysisNeighborhoodPair */ class AnalysisNeighborhoodSearch { - public: - /*! \brief - * Internal short-hand type for a pointer to the implementation class. - * - * shared_ptr is used here to automatically keep a reference count to - * track whether an implementation class is still used outside the - * AnalysisNeighborhood object. Ownership currently always stays with - * AnalysisNeighborhood; it always keeps one instance of the pointer. - */ - typedef std::shared_ptr - ImplPointer; - - /*! \brief - * Initializes an invalid search. - * - * Such an object cannot be used for searching. It needs to be - * assigned a value from AnalysisNeighborhood::initSearch() before it - * can be used. Provided to allow declaring a variable to hold the - * search before calling AnalysisNeighborhood::initSearch(). - */ - AnalysisNeighborhoodSearch(); - /*! \brief - * Internally initialize the search. - * - * Used to implement AnalysisNeighborhood::initSearch(). - * Cannot be called from user code. - */ - explicit AnalysisNeighborhoodSearch(const ImplPointer &impl); - - /*! \brief - * Clears this search. - * - * Equivalent to \c "*this = AnalysisNeighborhoodSearch();". - * Currently, this is necessary to avoid unnecessary memory allocation - * if the previous search variable is still in scope when you want to - * call AnalysisNeighborhood::initSearch() again. - */ - void reset(); - - /*! \brief - * Returns the searching algorithm that this search is using. - * - * The return value is never AnalysisNeighborhood::eSearchMode_Automatic. - */ - AnalysisNeighborhood::SearchMode mode() const; - - /*! \brief - * Checks whether a point is within a neighborhood. - * - * \param[in] positions Set of test positions to use. - * \returns true if any of the test positions is within the cutoff of - * any reference position. - */ - bool isWithin(const AnalysisNeighborhoodPositions &positions) const; - /*! \brief - * Calculates the minimum distance from the reference points. - * - * \param[in] positions Set of test positions to use. - * \returns The distance to the nearest reference position, or the - * cutoff value if there are no reference positions within the - * cutoff. - */ - real minimumDistance(const AnalysisNeighborhoodPositions &positions) const; - /*! \brief - * Finds the closest reference point. - * - * \param[in] positions Set of test positions to use. - * \returns The reference index identifies the reference position - * that is closest to the test positions. - * The test index identifies the test position that is closest to - * the provided test position. The returned pair is invalid if - * no reference position is within the cutoff. - */ - AnalysisNeighborhoodPair - nearestPoint(const AnalysisNeighborhoodPositions &positions) const; - - /*! \brief - * Starts a search to find all reference position pairs within a cutoff. - * - * \returns Initialized search object to loop through all reference - * position pairs within the configured cutoff. - * \throws std::bad_alloc if out of memory. - * - * This works as if the reference positions were passed to - * startPairSearch(), except that it only returns each pair once, - * instead of returning both i-j and j-i pairs, as startPairSearch() - * does. i-i pairs are not returned. Note that the order of ref/test - * indices in the returned pairs is not predictable. That is, one of - * i-j or j-i is always returned, but there is no control which one. - */ - AnalysisNeighborhoodPairSearch - startSelfPairSearch() const; - - /*! \brief - * Starts a search to find reference positions within a cutoff. - * - * \param[in] positions Set of test positions to use. - * \returns Initialized search object to loop through all reference - * positions within the configured cutoff. - * \throws std::bad_alloc if out of memory. - * - * If you want to pass the same positions here as you used for the - * reference positions, consider using startSelfPairSearch(). - * It can be up to 50% faster. - */ - AnalysisNeighborhoodPairSearch - startPairSearch(const AnalysisNeighborhoodPositions &positions) const; - - private: - typedef internal::AnalysisNeighborhoodSearchImpl Impl; - - ImplPointer impl_; +public: + /*! \brief + * Internal short-hand type for a pointer to the implementation class. + * + * shared_ptr is used here to automatically keep a reference count to + * track whether an implementation class is still used outside the + * AnalysisNeighborhood object. Ownership currently always stays with + * AnalysisNeighborhood; it always keeps one instance of the pointer. + */ + typedef std::shared_ptr ImplPointer; + + /*! \brief + * Initializes an invalid search. + * + * Such an object cannot be used for searching. It needs to be + * assigned a value from AnalysisNeighborhood::initSearch() before it + * can be used. Provided to allow declaring a variable to hold the + * search before calling AnalysisNeighborhood::initSearch(). + */ + AnalysisNeighborhoodSearch(); + /*! \brief + * Internally initialize the search. + * + * Used to implement AnalysisNeighborhood::initSearch(). + * Cannot be called from user code. + */ + explicit AnalysisNeighborhoodSearch(const ImplPointer& impl); + + /*! \brief + * Clears this search. + * + * Equivalent to \c "*this = AnalysisNeighborhoodSearch();". + * Currently, this is necessary to avoid unnecessary memory allocation + * if the previous search variable is still in scope when you want to + * call AnalysisNeighborhood::initSearch() again. + */ + void reset(); + + /*! \brief + * Returns the searching algorithm that this search is using. + * + * The return value is never AnalysisNeighborhood::eSearchMode_Automatic. + */ + AnalysisNeighborhood::SearchMode mode() const; + + /*! \brief + * Checks whether a point is within a neighborhood. + * + * \param[in] positions Set of test positions to use. + * \returns true if any of the test positions is within the cutoff of + * any reference position. + */ + bool isWithin(const AnalysisNeighborhoodPositions& positions) const; + /*! \brief + * Calculates the minimum distance from the reference points. + * + * \param[in] positions Set of test positions to use. + * \returns The distance to the nearest reference position, or the + * cutoff value if there are no reference positions within the + * cutoff. + */ + real minimumDistance(const AnalysisNeighborhoodPositions& positions) const; + /*! \brief + * Finds the closest reference point. + * + * \param[in] positions Set of test positions to use. + * \returns The reference index identifies the reference position + * that is closest to the test positions. + * The test index identifies the test position that is closest to + * the provided test position. The returned pair is invalid if + * no reference position is within the cutoff. + */ + AnalysisNeighborhoodPair nearestPoint(const AnalysisNeighborhoodPositions& positions) const; + + /*! \brief + * Starts a search to find all reference position pairs within a cutoff. + * + * \returns Initialized search object to loop through all reference + * position pairs within the configured cutoff. + * \throws std::bad_alloc if out of memory. + * + * This works as if the reference positions were passed to + * startPairSearch(), except that it only returns each pair once, + * instead of returning both i-j and j-i pairs, as startPairSearch() + * does. i-i pairs are not returned. Note that the order of ref/test + * indices in the returned pairs is not predictable. That is, one of + * i-j or j-i is always returned, but there is no control which one. + */ + AnalysisNeighborhoodPairSearch startSelfPairSearch() const; + + /*! \brief + * Starts a search to find reference positions within a cutoff. + * + * \param[in] positions Set of test positions to use. + * \returns Initialized search object to loop through all reference + * positions within the configured cutoff. + * \throws std::bad_alloc if out of memory. + * + * If you want to pass the same positions here as you used for the + * reference positions, consider using startSelfPairSearch(). + * It can be up to 50% faster. + */ + AnalysisNeighborhoodPairSearch startPairSearch(const AnalysisNeighborhoodPositions& positions) const; + +private: + typedef internal::AnalysisNeighborhoodSearchImpl Impl; + + ImplPointer impl_; }; /*! \brief @@ -569,52 +572,51 @@ class AnalysisNeighborhoodSearch */ class AnalysisNeighborhoodPairSearch { - public: - /*! \brief - * Internal short-hand type for a pointer to the implementation class. - * - * See AnalysisNeighborhoodSearch::ImplPointer for rationale of using - * shared_ptr and ownership semantics. - */ - typedef std::shared_ptr - ImplPointer; - - /*! \brief - * Internally initialize the search. - * - * Used to implement AnalysisNeighborhoodSearch::startPairSearch(). - * Cannot be called from user code. - */ - explicit AnalysisNeighborhoodPairSearch(const ImplPointer &impl); - - /*! \brief - * Finds the next pair within the cutoff. - * - * \param[out] pair Information about the found pair. - * \returns false if there were no more pairs. - * - * If the method returns false, \p pair will be invalid. - * - * \see AnalysisNeighborhoodPair - * \see AnalysisNeighborhoodSearch::startPairSearch() - */ - bool findNextPair(AnalysisNeighborhoodPair *pair); - /*! \brief - * Skip remaining pairs for a test position in the search. - * - * When called after findNextPair(), makes subsequent calls to - * findNextPair() skip any pairs that have the same test position as - * that previously returned. - * This is useful if the caller wants to search whether any reference - * position within the cutoff satisfies some condition. This method - * can be used to skip remaining pairs after the first such position - * has been found if the remaining pairs would not have an effect on - * the outcome. - */ - void skipRemainingPairsForTestPosition(); - - private: - ImplPointer impl_; +public: + /*! \brief + * Internal short-hand type for a pointer to the implementation class. + * + * See AnalysisNeighborhoodSearch::ImplPointer for rationale of using + * shared_ptr and ownership semantics. + */ + typedef std::shared_ptr ImplPointer; + + /*! \brief + * Internally initialize the search. + * + * Used to implement AnalysisNeighborhoodSearch::startPairSearch(). + * Cannot be called from user code. + */ + explicit AnalysisNeighborhoodPairSearch(const ImplPointer& impl); + + /*! \brief + * Finds the next pair within the cutoff. + * + * \param[out] pair Information about the found pair. + * \returns false if there were no more pairs. + * + * If the method returns false, \p pair will be invalid. + * + * \see AnalysisNeighborhoodPair + * \see AnalysisNeighborhoodSearch::startPairSearch() + */ + bool findNextPair(AnalysisNeighborhoodPair* pair); + /*! \brief + * Skip remaining pairs for a test position in the search. + * + * When called after findNextPair(), makes subsequent calls to + * findNextPair() skip any pairs that have the same test position as + * that previously returned. + * This is useful if the caller wants to search whether any reference + * position within the cutoff satisfies some condition. This method + * can be used to skip remaining pairs after the first such position + * has been found if the remaining pairs would not have an effect on + * the outcome. + */ + void skipRemainingPairsForTestPosition(); + +private: + ImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/selection/params.cpp b/src/gromacs/selection/params.cpp index a898f41101..4f6e029095 100644 --- a/src/gromacs/selection/params.cpp +++ b/src/gromacs/selection/params.cpp @@ -72,10 +72,9 @@ using namespace gmx; * * The comparison is case-sensitive. */ -gmx_ana_selparam_t * -gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) +gmx_ana_selparam_t* gmx_ana_selparam_find(const char* name, int nparam, gmx_ana_selparam_t* param) { - int i; + int i; if (nparam == 0) { @@ -90,7 +89,7 @@ gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) /* Process the special case of a NULL parameter */ if (name == nullptr) { - return (i == 0) ? nullptr : ¶m[i-1]; + return (i == 0) ? nullptr : ¶m[i - 1]; } for (; i < nparam; ++i) { @@ -99,9 +98,8 @@ gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) return ¶m[i]; } /* Check for 'no' prefix on boolean parameters */ - if (param[i].val.type == NO_VALUE - && strlen(name) > 2 && name[0] == 'n' && name[1] == 'o' - && !strcmp(param[i].name, name+2)) + if (param[i].val.type == NO_VALUE && strlen(name) > 2 && name[0] == 'n' && name[1] == 'o' + && !strcmp(param[i].name, name + 2)) { return ¶m[i]; } @@ -117,9 +115,7 @@ gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param) * \param[in] errors Errors will be reported into this as nested exceptions. * \param[in] scanner Scanner data structure. */ -static void -convert_value(SelectionParserValue *value, e_selvalue_t type, - ExceptionInitializer *errors, void *scanner) +static void convert_value(SelectionParserValue* value, e_selvalue_t type, ExceptionInitializer* errors, void* scanner) { if (value->type == type || type == NO_VALUE) { @@ -133,11 +129,10 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, { try { - SelectionTreeElementPointer expr = - _gmx_sel_init_position(value->expr, nullptr, scanner); - *value = SelectionParserValue::createExpr(expr); + SelectionTreeElementPointer expr = _gmx_sel_init_position(value->expr, nullptr, scanner); + *value = SelectionParserValue::createExpr(expr); } - catch (UserInputError &ex) + catch (UserInputError& ex) { std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); std::string context(formatString("In '%s'", text.c_str())); @@ -152,8 +147,7 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, /* Integers to floating point are easy */ if (value->type == INT_VALUE && type == REAL_VALUE) { - *value = SelectionParserValue::createRealRange(value->u.i.i1, - value->u.i.i2, + *value = SelectionParserValue::createRealRange(value->u.i.i1, value->u.i.i2, value->location()); return; } @@ -170,10 +164,9 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, } } } - std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message( - formatString("Expression '%s' evaluates to a type is not valid in this context", - text.c_str())); + std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); + std::string message(formatString( + "Expression '%s' evaluates to a type is not valid in this context", text.c_str())); InvalidInputError ex(message); errors->addNested(ex); } @@ -185,8 +178,7 @@ convert_value(SelectionParserValue *value, e_selvalue_t type, * \param[in] type Type to convert to. * \param[in] scanner Scanner data structure. */ -static void -convert_values(SelectionParserValueList *values, e_selvalue_t type, void *scanner) +static void convert_values(SelectionParserValueList* values, e_selvalue_t type, void* scanner) { ExceptionInitializer errors(""); SelectionParserValueList::iterator value; @@ -210,12 +202,11 @@ convert_values(SelectionParserValueList *values, e_selvalue_t type, void *scanne * Puts \p child in the child list of \p root such that the list remains * in the same order as the corresponding parameters. */ -static void -place_child(const SelectionTreeElementPointer &root, - const SelectionTreeElementPointer &child, - gmx_ana_selparam_t *param) +static void place_child(const SelectionTreeElementPointer& root, + const SelectionTreeElementPointer& child, + gmx_ana_selparam_t* param) { - gmx_ana_selparam_t *ps; + gmx_ana_selparam_t* ps; int n; ps = root->u.expr.method->param; @@ -249,7 +240,7 @@ place_child(const SelectionTreeElementPointer &root, * secondarily based on length (longer ranges come first). */ template -static bool cmp_range(const std::array &a, const std::array &b) +static bool cmp_range(const std::array& a, const std::array& b) { return a[0] < b[0] || (a[0] == b[0] && a[1] > b[1]); } @@ -261,26 +252,24 @@ static bool cmp_range(const std::array &a, const std::array &b) * \param param Parameter to parse. * \param[in] scanner Scanner data structure. */ -static void -parse_values_range(const SelectionParserValueList &values, - gmx_ana_selparam_t *param, void *scanner) +static void parse_values_range(const SelectionParserValueList& values, gmx_ana_selparam_t* param, void* scanner) { - int i, j, n; + int i, j, n; param->flags &= ~SPAR_DYNAMIC; GMX_RELEASE_ASSERT(param->val.type == INT_VALUE || param->val.type == REAL_VALUE, "Invalid range parameter type"); - int *idata = nullptr; - real *rdata = nullptr; - sfree_guard dataGuard; + int* idata = nullptr; + real* rdata = nullptr; + sfree_guard dataGuard; if (param->val.type == INT_VALUE) { - snew(idata, values.size()*2); + snew(idata, values.size() * 2); dataGuard.reset(idata); } else { - snew(rdata, values.size()*2); + snew(rdata, values.size() * 2); dataGuard.reset(rdata); } i = 0; @@ -291,9 +280,10 @@ parse_values_range(const SelectionParserValueList &values, "Invalid range value type (should have been caught earlier)"); if (value->hasExpressionValue()) { - std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message("Only simple values or 'A to B' ranges are " - "supported in this context"); + std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); + std::string message( + "Only simple values or 'A to B' ranges are " + "supported in this context"); InvalidInputError ex(message); ex.prependContext(formatString("Invalid expression '%s'", text.c_str())); GMX_THROW(ex); @@ -303,10 +293,10 @@ parse_values_range(const SelectionParserValueList &values, int i1 = std::min(value->u.i.i1, value->u.i.i2); int i2 = std::max(value->u.i.i1, value->u.i.i2); /* Check if the new range overlaps or extends the previous one */ - if (i > 0 && i1 <= idata[i-1]+1 && i2 >= idata[i-2]-1) + if (i > 0 && i1 <= idata[i - 1] + 1 && i2 >= idata[i - 2] - 1) { - idata[i-2] = std::min(idata[i-2], i1); - idata[i-1] = std::max(idata[i-1], i2); + idata[i - 2] = std::min(idata[i - 2], i1); + idata[i - 1] = std::max(idata[i - 1], i2); } else { @@ -319,10 +309,10 @@ parse_values_range(const SelectionParserValueList &values, real r1 = std::min(value->u.r.r1, value->u.r.r2); real r2 = std::max(value->u.r.r1, value->u.r.r2); /* Check if the new range overlaps or extends the previous one */ - if (i > 0 && r1 <= rdata[i-1] && r2 >= rdata[i-2]) + if (i > 0 && r1 <= rdata[i - 1] && r2 >= rdata[i - 2]) { - rdata[i-2] = std::min(rdata[i-2], r1); - rdata[i-1] = std::max(rdata[i-1], r2); + rdata[i - 2] = std::min(rdata[i - 2], r1); + rdata[i - 1] = std::max(rdata[i - 1], r2); } else { @@ -331,56 +321,56 @@ parse_values_range(const SelectionParserValueList &values, } } } - n = i/2; + n = i / 2; /* Sort the ranges and merge consequent ones */ if (param->val.type == INT_VALUE) { const auto range_data = reinterpret_cast*>(idata); - sort(range_data, range_data+n, cmp_range); - for (i = j = 2; i < 2*n; i += 2) + sort(range_data, range_data + n, cmp_range); + for (i = j = 2; i < 2 * n; i += 2) { - if (idata[j-1]+1 >= idata[i]) + if (idata[j - 1] + 1 >= idata[i]) { - if (idata[i+1] > idata[j-1]) + if (idata[i + 1] > idata[j - 1]) { - idata[j-1] = idata[i+1]; + idata[j - 1] = idata[i + 1]; } } else { - idata[j] = idata[i]; - idata[j+1] = idata[i+1]; - j += 2; + idata[j] = idata[i]; + idata[j + 1] = idata[i + 1]; + j += 2; } } } else { const auto range_data = reinterpret_cast*>(rdata); - sort(range_data, range_data+n, cmp_range); - for (i = j = 2; i < 2*n; i += 2) + sort(range_data, range_data + n, cmp_range); + for (i = j = 2; i < 2 * n; i += 2) { - if (rdata[j-1] >= rdata[i]) + if (rdata[j - 1] >= rdata[i]) { - if (rdata[i+1] > rdata[j-1]) + if (rdata[i + 1] > rdata[j - 1]) { - rdata[j-1] = rdata[i+1]; + rdata[j - 1] = rdata[i + 1]; } } else { - rdata[j] = rdata[i]; - rdata[j+1] = rdata[i+1]; - j += 2; + rdata[j] = rdata[i]; + rdata[j + 1] = rdata[i + 1]; + j += 2; } } } - n = j/2; + n = j / 2; /* Store the values */ if (param->flags & SPAR_VARNUM) { (void)dataGuard.release(); - param->val.nr = n; + param->val.nr = n; if (param->val.type == INT_VALUE) { srenew(idata, j); @@ -396,18 +386,18 @@ parse_values_range(const SelectionParserValueList &values, { if (n != param->val.nr) { - GMX_ASSERT(n == 1, - "Range parameters with a fixed count > 1 do not make sense"); - GMX_THROW(InvalidInputError("Only one value or 'A to B' range is " - "supported in this context")); + GMX_ASSERT(n == 1, "Range parameters with a fixed count > 1 do not make sense"); + GMX_THROW( + InvalidInputError("Only one value or 'A to B' range is " + "supported in this context")); } if (param->val.type == INT_VALUE) { - memcpy(param->val.u.i, idata, 2*n*sizeof(int)); + memcpy(param->val.u.i, idata, 2 * n * sizeof(int)); } else { - memcpy(param->val.u.r, rdata, 2*n*sizeof(real)); + memcpy(param->val.u.r, rdata, 2 * n * sizeof(real)); } } if (param->nvalptr) @@ -428,13 +418,12 @@ parse_values_range(const SelectionParserValueList &values, * For integer ranges, the sequence of numbers from the first to second value * is stored, each as a separate value. */ -static void -parse_values_varnum(const SelectionParserValueList &values, - gmx_ana_selparam_t *param, - const SelectionTreeElementPointer &root, - void *scanner) +static void parse_values_varnum(const SelectionParserValueList& values, + gmx_ana_selparam_t* param, + const SelectionTreeElementPointer& root, + void* scanner) { - int i, j; + int i, j; param->flags &= ~SPAR_DYNAMIC; /* Compute number of values, considering also integer ranges. */ @@ -480,7 +469,7 @@ parse_values_varnum(const SelectionParserValueList &values, child->setName(param->name); child->flags &= ~SEL_ALLOCVAL; child->flags |= SEL_FLAGSSET | SEL_VARNUMVAL | SEL_ALLOCDATA; - child->v.nr = valueCount; + child->v.nr = valueCount; _gmx_selvalue_setstore(&child->v, param->val.u.s); /* Because the child is not group-valued, the u union is not used * for anything, so we can abuse it by storing the parameter value @@ -490,7 +479,7 @@ parse_values_varnum(const SelectionParserValueList &values, } param->val.nr = valueCount; - i = 0; + i = 0; SelectionParserValueList::const_iterator value; for (value = values.begin(); value != values.end(); ++value) { @@ -498,9 +487,10 @@ parse_values_varnum(const SelectionParserValueList &values, "Invalid value type (should have been caught earlier)"); if (value->hasExpressionValue()) { - std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message("Selection expressions are not supported in this " - "context when multiple values are provided"); + std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); + std::string message( + "Selection expressions are not supported in this " + "context when multiple values are provided"); InvalidInputError ex(message); ex.prependContext(formatString("Invalid expression '%s'", text.c_str())); GMX_THROW(ex); @@ -527,18 +517,15 @@ parse_values_varnum(const SelectionParserValueList &values, if (value->u.r.r1 != value->u.r.r2) { std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message - = formatString("Real range ('%s') is not supported in this context", - text.c_str()); + std::string message = formatString( + "Real range ('%s') is not supported in this context", text.c_str()); InvalidInputError ex(message); GMX_THROW(ex); } param->val.u.r[i++] = value->u.r.r1; break; - case STR_VALUE: - param->val.u.s[i++] = gmx_strdup(value->stringValue().c_str()); - break; - case POS_VALUE: copy_rvec(value->u.x, param->val.u.p->x[i++]); break; + case STR_VALUE: param->val.u.s[i++] = gmx_strdup(value->stringValue().c_str()); break; + case POS_VALUE: copy_rvec(value->u.x, param->val.u.p->x[i++]); break; default: /* Should not be reached */ GMX_RELEASE_ASSERT(false, "Variable-count value type not implemented"); } @@ -566,9 +553,10 @@ parse_values_varnum(const SelectionParserValueList &values, * If \p expr is already a \ref SEL_SUBEXPRREF, it is used as it is. * \ref SEL_ALLOCVAL is cleared for the returned element. */ -static SelectionTreeElementPointer -add_child(const SelectionTreeElementPointer &root, gmx_ana_selparam_t *param, - const SelectionTreeElementPointer &expr, void *scanner) +static SelectionTreeElementPointer add_child(const SelectionTreeElementPointer& root, + gmx_ana_selparam_t* param, + const SelectionTreeElementPointer& expr, + void* scanner) { GMX_RELEASE_ASSERT(root->type == SEL_EXPRESSION || root->type == SEL_MODIFIER, "Unsupported root element for selection parameter parser"); @@ -583,29 +571,29 @@ add_child(const SelectionTreeElementPointer &root, gmx_ana_selparam_t *param, // TODO: Initialize such that it includes the parameter. child = std::make_shared(SEL_SUBEXPRREF, expr->location()); _gmx_selelem_set_vtype(child, expr->v.type); - child->child = expr; + child->child = expr; } /* Setup the child element */ - child->flags &= ~SEL_ALLOCVAL; + child->flags &= ~SEL_ALLOCVAL; child->u.param = param; if (child->v.type != param->val.type) { // TODO: It would be nice to say what is the expected type. std::string text(_gmx_sel_lexer_get_text(scanner, expr->location())); - std::string message - = formatString("Expression '%s' is not valid in this context " - "(produces the wrong type of values)", - text.c_str()); + std::string message = formatString( + "Expression '%s' is not valid in this context " + "(produces the wrong type of values)", + text.c_str()); GMX_THROW(InvalidInputError(message)); } _gmx_selelem_update_flags(child); if ((child->flags & SEL_DYNAMIC) && !(param->flags & SPAR_DYNAMIC)) { std::string text(_gmx_sel_lexer_get_text(scanner, expr->location())); - std::string message - = formatString("Expression '%s' is dynamic, which is not " - "valid in this context", - text.c_str()); + std::string message = formatString( + "Expression '%s' is dynamic, which is not " + "valid in this context", + text.c_str()); GMX_THROW(InvalidInputError(message)); } if (!(child->flags & SEL_DYNAMIC)) @@ -625,17 +613,15 @@ add_child(const SelectionTreeElementPointer &root, gmx_ana_selparam_t *param, * \param root Selection element to which child expressions are added. * \param[in] scanner Scanner data structure. */ -static void -parse_values_varnum_expr(const SelectionParserValueList &values, - gmx_ana_selparam_t *param, - const SelectionTreeElementPointer &root, - void *scanner) +static void parse_values_varnum_expr(const SelectionParserValueList& values, + gmx_ana_selparam_t* param, + const SelectionTreeElementPointer& root, + void* scanner) { GMX_RELEASE_ASSERT(values.size() == 1 && values.front().hasExpressionValue(), "Called with an invalid type of value"); - SelectionTreeElementPointer child - = add_child(root, param, values.front().expr, scanner); + SelectionTreeElementPointer child = add_child(root, param, values.front().expr, scanner); /* Process single-valued expressions */ /* TODO: We should also handle SEL_SINGLEVAL expressions here */ @@ -655,13 +641,11 @@ parse_values_varnum_expr(const SelectionParserValueList &values, if (!(child->flags & SEL_VARNUMVAL)) { std::string text(_gmx_sel_lexer_get_text(scanner, values.front().location())); - std::string message - = formatString("Expression '%s' is invalid in this context", - text.c_str()); + std::string message = formatString("Expression '%s' is invalid in this context", text.c_str()); GMX_THROW(InvalidInputError(message)); } - child->flags |= SEL_ALLOCVAL; + child->flags |= SEL_ALLOCVAL; param->val.nr = -1; *param->nvalptr = param->val.nr; /* Rest of the initialization is done during compilation in @@ -681,27 +665,25 @@ parse_values_varnum_expr(const SelectionParserValueList &values, * as the value \p i of \p param. * This function is used internally by parse_values_std(). */ -static void -set_expr_value_store(const SelectionTreeElementPointer &sel, - gmx_ana_selparam_t *param, int i, void *scanner) +static void set_expr_value_store(const SelectionTreeElementPointer& sel, + gmx_ana_selparam_t* param, + int i, + void* scanner) { if (sel->v.type != GROUP_VALUE && !(sel->flags & SEL_SINGLEVAL)) { std::string text(_gmx_sel_lexer_get_text(scanner, sel->location())); - std::string message - = formatString("Expression '%s' is invalid in this context", - text.c_str()); + std::string message = formatString("Expression '%s' is invalid in this context", text.c_str()); GMX_THROW(InvalidInputError(message)); } switch (sel->v.type) { - case INT_VALUE: sel->v.u.i = ¶m->val.u.i[i]; break; - case REAL_VALUE: sel->v.u.r = ¶m->val.u.r[i]; break; - case STR_VALUE: sel->v.u.s = ¶m->val.u.s[i]; break; - case POS_VALUE: sel->v.u.p = ¶m->val.u.p[i]; break; + case INT_VALUE: sel->v.u.i = ¶m->val.u.i[i]; break; + case REAL_VALUE: sel->v.u.r = ¶m->val.u.r[i]; break; + case STR_VALUE: sel->v.u.s = ¶m->val.u.s[i]; break; + case POS_VALUE: sel->v.u.p = ¶m->val.u.p[i]; break; case GROUP_VALUE: sel->v.u.g = ¶m->val.u.g[i]; break; - default: /* Error */ - GMX_THROW(InternalError("Invalid value type")); + default: /* Error */ GMX_THROW(InternalError("Invalid value type")); } sel->v.nr = 1; sel->v.nalloc = -1; @@ -718,27 +700,26 @@ set_expr_value_store(const SelectionTreeElementPointer &sel, * For integer ranges, the sequence of numbers from the first to second value * is stored, each as a separate value. */ -static void -parse_values_std(const SelectionParserValueList &values, - gmx_ana_selparam_t *param, - const SelectionTreeElementPointer &root, void *scanner) +static void parse_values_std(const SelectionParserValueList& values, + gmx_ana_selparam_t* param, + const SelectionTreeElementPointer& root, + void* scanner) { - int i, j; - bool bDynamic; + int i, j; + bool bDynamic; /* Handle atom-valued parameters */ if (param->flags & SPAR_ATOMVAL) { if (values.size() > 1) { - GMX_THROW(InvalidInputError( - "Only a single value or a single expression is " - "supported in this context")); + GMX_THROW( + InvalidInputError("Only a single value or a single expression is " + "supported in this context")); } if (values.front().hasExpressionValue()) { - SelectionTreeElementPointer child - = add_child(root, param, values.front().expr, scanner); + SelectionTreeElementPointer child = add_child(root, param, values.front().expr, scanner); child->flags |= SEL_ALLOCVAL; if (child->v.type != GROUP_VALUE && (child->flags & SEL_ATOMVAL)) { @@ -752,15 +733,14 @@ parse_values_std(const SelectionParserValueList &values, } return; } - param->flags &= ~SPAR_ATOMVAL; - param->val.nr = 1; + param->flags &= ~SPAR_ATOMVAL; + param->val.nr = 1; if (param->nvalptr) { *param->nvalptr = 1; } param->nvalptr = nullptr; - if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE - || param->val.type == STR_VALUE) + if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE || param->val.type == STR_VALUE) { _gmx_selvalue_reserve(¶m->val, 1); } @@ -769,8 +749,7 @@ parse_values_std(const SelectionParserValueList &values, } /* If we reach here, proceed with normal parameter handling */ param->val.nr = 1; - if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE - || param->val.type == STR_VALUE) + if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE || param->val.type == STR_VALUE) { _gmx_selvalue_reserve(¶m->val, 1); } @@ -787,8 +766,7 @@ parse_values_std(const SelectionParserValueList &values, "Invalid value type (should have been caught earlier)"); if (value->hasExpressionValue()) { - SelectionTreeElementPointer child - = add_child(root, param, value->expr, scanner); + SelectionTreeElementPointer child = add_child(root, param, value->expr, scanner); set_expr_value_store(child, param, i, scanner); if (child->flags & SEL_DYNAMIC) { @@ -822,10 +800,10 @@ parse_values_std(const SelectionParserValueList &values, if (bTooManyValues) { std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message - = formatString("Range ('%s') produces more values than is " - "accepted in this context", - text.c_str()); + std::string message = formatString( + "Range ('%s') produces more values than is " + "accepted in this context", + text.c_str()); GMX_THROW(InvalidInputError(message)); } --i; @@ -835,38 +813,28 @@ parse_values_std(const SelectionParserValueList &values, if (value->u.r.r1 != value->u.r.r2) { std::string text(_gmx_sel_lexer_get_text(scanner, value->location())); - std::string message - = formatString("Real range ('%s') is not supported in this context", - text.c_str()); + std::string message = formatString( + "Real range ('%s') is not supported in this context", text.c_str()); GMX_THROW(InvalidInputError(message)); } param->val.u.r[i] = value->u.r.r1; break; - case STR_VALUE: - param->val.u.s[i] = gmx_strdup(value->stringValue().c_str()); - break; - case POS_VALUE: - gmx_ana_pos_init_const(¶m->val.u.p[i], value->u.x); - break; + case STR_VALUE: param->val.u.s[i] = gmx_strdup(value->stringValue().c_str()); break; + case POS_VALUE: gmx_ana_pos_init_const(¶m->val.u.p[i], value->u.x); break; case NO_VALUE: - case GROUP_VALUE: - GMX_THROW(InternalError("Invalid non-expression value type")); + case GROUP_VALUE: GMX_THROW(InternalError("Invalid non-expression value type")); } } ++i; } if (value != values.end()) { - std::string message - = formatString("Too many values provided, expected %d", - param->val.nr); + std::string message = formatString("Too many values provided, expected %d", param->val.nr); GMX_THROW(InvalidInputError(message)); } if (i < param->val.nr) { - std::string message - = formatString("Too few values provided, expected %d", - param->val.nr); + std::string message = formatString("Too few values provided, expected %d", param->val.nr); GMX_THROW(InvalidInputError(message)); } if (!bDynamic) @@ -888,19 +856,17 @@ parse_values_std(const SelectionParserValueList &values, * \param param Parameter to parse. * \param[in] scanner Scanner data structure. */ -static void -parse_values_bool(const std::string &name, - const SelectionParserValueList &values, - gmx_ana_selparam_t *param, void *scanner) +static void parse_values_bool(const std::string& name, + const SelectionParserValueList& values, + gmx_ana_selparam_t* param, + void* scanner) { GMX_UNUSED_VALUE(scanner); - GMX_ASSERT(param->val.type == NO_VALUE, - "Boolean parser called for non-boolean parameter"); + GMX_ASSERT(param->val.type == NO_VALUE, "Boolean parser called for non-boolean parameter"); if (values.size() > 1 || (!values.empty() && values.front().type != INT_VALUE)) { - std::string message - = formatString("'%s' only accepts yes/no/on/off/0/1 (and empty) as a value", - param->name); + std::string message = + formatString("'%s' only accepts yes/no/on/off/0/1 (and empty) as a value", param->name); GMX_THROW(InvalidInputError(message)); } @@ -913,9 +879,7 @@ parse_values_bool(const std::string &name, } if (bSetNo && !values.empty()) { - std::string message - = formatString("'no%s' cannot be followed by any value", - param->name); + std::string message = formatString("'no%s' cannot be followed by any value", param->name); GMX_THROW(InvalidInputError(message)); } if (!values.empty() && values.front().u.i.i1 == 0) @@ -934,31 +898,25 @@ parse_values_bool(const std::string &name, * \param[in] scanner Scanner data structure. * \returns true if the values were parsed successfully, false otherwise. */ -static void -parse_values_enum(const SelectionParserValueList &values, - gmx_ana_selparam_t *param, - void *scanner) +static void parse_values_enum(const SelectionParserValueList& values, gmx_ana_selparam_t* param, void* scanner) { - GMX_ASSERT(param->val.type == STR_VALUE, - "Enum parser called for non-string parameter"); + GMX_ASSERT(param->val.type == STR_VALUE, "Enum parser called for non-string parameter"); if (values.size() != 1) { - GMX_THROW(InvalidInputError( - "Only a single string value is supported in this context")); + GMX_THROW(InvalidInputError("Only a single string value is supported in this context")); } - const SelectionParserValue &value = values.front(); + const SelectionParserValue& value = values.front(); GMX_RELEASE_ASSERT(value.type == param->val.type, "Invalid value type (should have been caught earlier)"); if (value.hasExpressionValue()) { std::string text(_gmx_sel_lexer_get_text(scanner, value.location())); - std::string message - = formatString("Expression ('%s') is not supported in this context", - text.c_str()); + std::string message = + formatString("Expression ('%s') is not supported in this context", text.c_str()); GMX_THROW(InvalidInputError(message)); } - const std::string &svalue = value.stringValue(); + const std::string& svalue = value.stringValue(); int i = 1; int match = 0; while (param->val.u.s[i] != nullptr) @@ -968,8 +926,7 @@ parse_values_enum(const SelectionParserValueList &values, /* Check if there is a duplicate match */ if (match > 0) { - std::string message - = formatString("Value '%s' is ambiguous", svalue.c_str()); + std::string message = formatString("Value '%s' is ambiguous", svalue.c_str()); GMX_THROW(InvalidInputError(message)); } match = i; @@ -978,8 +935,7 @@ parse_values_enum(const SelectionParserValueList &values, } if (match == 0) { - std::string message - = formatString("Value '%s' is not recognized", svalue.c_str()); + std::string message = formatString("Value '%s' is not recognized", svalue.c_str()); GMX_THROW(InvalidInputError(message)); } param->val.u.s[0] = param->val.u.s[match]; @@ -990,17 +946,15 @@ parse_values_enum(const SelectionParserValueList &values, * * \param[in,out] values First element in the value list to process. */ -static void -convert_const_values(SelectionParserValueList *values) +static void convert_const_values(SelectionParserValueList* values) { SelectionParserValueList::iterator value; for (value = values->begin(); value != values->end(); ++value) { - if (value->hasExpressionValue() && value->expr->v.type != GROUP_VALUE && - value->expr->type == SEL_CONST) + if (value->hasExpressionValue() && value->expr->v.type != GROUP_VALUE && value->expr->type == SEL_CONST) { SelectionTreeElementPointer expr = value->expr; - const SelectionLocation &location = value->location(); + const SelectionLocation& location = value->location(); switch (expr->v.type) { case INT_VALUE: @@ -1015,9 +969,7 @@ convert_const_values(SelectionParserValueList *values) case POS_VALUE: *value = SelectionParserValue::createPosition(expr->v.u.p->x[0], location); break; - default: - GMX_RELEASE_ASSERT(false, - "Unsupported constant expression value type"); + default: GMX_RELEASE_ASSERT(false, "Unsupported constant expression value type"); } } } @@ -1037,51 +989,47 @@ convert_const_values(SelectionParserValueList *values) * The list \p pparams and any associated values are freed after the parameters * have been processed, no matter is there was an error or not. */ -void -_gmx_sel_parse_params(const gmx::SelectionParserParameterList &pparams, - int nparam, gmx_ana_selparam_t *params, - const gmx::SelectionTreeElementPointer &root, - void *scanner) +void _gmx_sel_parse_params(const gmx::SelectionParserParameterList& pparams, + int nparam, + gmx_ana_selparam_t* params, + const gmx::SelectionTreeElementPointer& root, + void* scanner) { ExceptionInitializer errors(""); /* Check that the value pointers of SPAR_VARNUM parameters are NULL and * that they are not NULL for other parameters */ for (int i = 0; i < nparam; ++i) { - if (params[i].val.type != POS_VALUE - && (params[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL))) + if (params[i].val.type != POS_VALUE && (params[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL))) { GMX_RELEASE_ASSERT(params[i].val.u.ptr == nullptr, "value pointer is not NULL " "although it should be for SPAR_VARNUM " "and SPAR_ATOMVAL parameters"); - GMX_RELEASE_ASSERT(!((params[i].flags & SPAR_VARNUM) - && (params[i].flags & SPAR_DYNAMIC)) - || params[i].nvalptr != nullptr, + GMX_RELEASE_ASSERT(!((params[i].flags & SPAR_VARNUM) && (params[i].flags & SPAR_DYNAMIC)) + || params[i].nvalptr != nullptr, "nvalptr is NULL but both " "SPAR_VARNUM and SPAR_DYNAMIC are specified"); } else { - GMX_RELEASE_ASSERT(params[i].val.u.ptr != nullptr, - "value pointer is NULL"); + GMX_RELEASE_ASSERT(params[i].val.u.ptr != nullptr, "value pointer is NULL"); } } /* Parse the parameters */ - int nullParamIndex = 0; + int nullParamIndex = 0; SelectionParserParameterList::const_iterator pparam; for (pparam = pparams.begin(); pparam != pparams.end(); ++pparam) { try { // Always assigned afterwards, but clang does not see that. - gmx_ana_selparam_t *oparam = nullptr; + gmx_ana_selparam_t* oparam = nullptr; /* Find the parameter and make some checks */ if (!pparam->name().empty()) { nullParamIndex = -1; - oparam - = gmx_ana_selparam_find(pparam->name().c_str(), nparam, params); + oparam = gmx_ana_selparam_find(pparam->name().c_str(), nparam, params); GMX_RELEASE_ASSERT(oparam != nullptr, "Inconsistent selection parameter"); } else if (nullParamIndex >= 0) @@ -1090,22 +1038,21 @@ _gmx_sel_parse_params(const gmx::SelectionParserParameterList &pparams, if (oparam->name != nullptr) { std::string text(_gmx_sel_lexer_get_text(scanner, pparam->location())); - std::string message - = formatString("Unexpected '%s'", text.c_str()); + std::string message = formatString("Unexpected '%s'", text.c_str()); GMX_THROW(InvalidInputError(message)); } ++nullParamIndex; } else { - GMX_RELEASE_ASSERT(false, "All NULL parameters should appear in " + GMX_RELEASE_ASSERT(false, + "All NULL parameters should appear in " "the beginning of the list"); } if (oparam->flags & SPAR_SET) { - std::string message - = formatString("'%s' appears multiple times", - pparam->name().c_str()); + std::string message = + formatString("'%s' appears multiple times", pparam->name().c_str()); GMX_THROW(InvalidInputError(message)); } oparam->flags |= SPAR_SET; @@ -1120,9 +1067,8 @@ _gmx_sel_parse_params(const gmx::SelectionParserParameterList &pparams, { text = _gmx_sel_lexer_get_text(scanner, pparam->location()); } - std::string message - = formatString("'%s' should be followed by a value/expression", - text.c_str()); + std::string message = + formatString("'%s' should be followed by a value/expression", text.c_str()); GMX_THROW(InvalidInputError(message)); } /* Process the values for the parameter */ @@ -1138,8 +1084,7 @@ _gmx_sel_parse_params(const gmx::SelectionParserParameterList &pparams, } else if (oparam->flags & SPAR_VARNUM) { - if (pparam->values().size() == 1 - && pparam->values().front().hasExpressionValue()) + if (pparam->values().size() == 1 && pparam->values().front().hasExpressionValue()) { parse_values_varnum_expr(pparam->values(), oparam, root, scanner); } @@ -1157,7 +1102,7 @@ _gmx_sel_parse_params(const gmx::SelectionParserParameterList &pparams, parse_values_std(pparam->values(), oparam, root, scanner); } } - catch (UserInputError &ex) + catch (UserInputError& ex) { if (!pparam->name().empty()) { diff --git a/src/gromacs/selection/parser_internal.h b/src/gromacs/selection/parser_internal.h index b8e489f6e3..e99aa03750 100644 --- a/src/gromacs/selection/parser_internal.h +++ b/src/gromacs/selection/parser_internal.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,8 +58,7 @@ #include "selelem.h" //! Error handler needed by Bison. -static void -yyerror(YYLTYPE *location, yyscan_t scanner, char const *s) +static void yyerror(YYLTYPE* location, yyscan_t scanner, char const* s) { try { @@ -73,26 +72,26 @@ yyerror(YYLTYPE *location, yyscan_t scanner, char const *s) } _gmx_sel_lexer_set_exception(scanner, std::make_exception_ptr(ex)); } - catch (const std::exception &) + catch (const std::exception&) { _gmx_sel_lexer_set_exception(scanner, std::current_exception()); } } //! Logic for computing the location of the output of Bison reduction. -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if ((N) != 0) \ - { \ - (Current).startIndex = YYRHSLOC(Rhs, 1).startIndex; \ - (Current).endIndex = YYRHSLOC(Rhs, N).endIndex; \ - } \ - else \ - { \ - (Current).startIndex = (Current).endIndex = \ - YYRHSLOC(Rhs, 0).endIndex; \ - } \ - _gmx_sel_lexer_set_current_location(scanner, (Current)); \ +#define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + { \ + if ((N) != 0) \ + { \ + (Current).startIndex = YYRHSLOC(Rhs, 1).startIndex; \ + (Current).endIndex = YYRHSLOC(Rhs, N).endIndex; \ + } \ + else \ + { \ + (Current).startIndex = (Current).endIndex = YYRHSLOC(Rhs, 0).endIndex; \ + } \ + _gmx_sel_lexer_set_current_location(scanner, (Current)); \ } while (0) /*! \brief @@ -122,28 +121,29 @@ yyerror(YYLTYPE *location, yyscan_t scanner, char const *s) */ //! Starts an action that may throw exceptions. #define BEGIN_ACTION \ - try { + try \ + { //! Finishes an action that may throw exceptions. -#define END_ACTION \ - } \ - catch (std::exception &ex) \ - { \ - if (_gmx_selparser_handle_exception(scanner, &ex)) \ - { \ - YYERROR; \ - } \ - else \ - { \ - YYABORT; \ - } \ +#define END_ACTION \ + } \ + catch (std::exception & ex) \ + { \ + if (_gmx_selparser_handle_exception(scanner, &ex)) \ + { \ + YYERROR; \ + } \ + else \ + { \ + YYABORT; \ + } \ } //! Finishes an action that may throw exceptions and does not support resuming. -#define END_ACTION_TOPLEVEL \ - } \ - catch (const std::exception &) \ - { \ +#define END_ACTION_TOPLEVEL \ + } \ + catch (const std::exception&) \ + { \ _gmx_sel_lexer_set_exception(scanner, std::current_exception()); \ - YYABORT; \ + YYABORT; \ } //!\} @@ -164,8 +164,8 @@ yyerror(YYLTYPE *location, yyscan_t scanner, char const *s) * Does not throw for smart pointer types. If used with types that may throw, * the order of operations should be such that it is exception-safe. */ -template static -ValueType get(ValueType *src) +template +static ValueType get(ValueType* src) { GMX_RELEASE_ASSERT(src != nullptr, "Semantic value pointers should be non-NULL"); const std::unique_ptr srcGuard(src); @@ -184,8 +184,8 @@ ValueType get(ValueType *src) * This should be the last statement before ::END_ACTION, except for a * possible ::CHECK_SEL. */ -template static -void set(ValueType * &dest, ValueType value) +template +static void set(ValueType*& dest, ValueType value) { dest = new ValueType(std::move(value)); } @@ -201,8 +201,8 @@ void set(ValueType * &dest, ValueType value) * This should be the last statement before ::END_ACTION, except for a * possible ::CHECK_SEL. */ -template static -void set_empty(ValueType * &dest) +template +static void set_empty(ValueType*& dest) { dest = new ValueType; } @@ -217,9 +217,10 @@ void set_empty(ValueType * &dest) * exceptions. */ #define CHECK_SEL(sel) \ - if (!*(sel)) { \ - delete (sel); \ - YYERROR; \ + if (!*(sel)) \ + { \ + delete (sel); \ + YYERROR; \ } #endif diff --git a/src/gromacs/selection/parsetree.cpp b/src/gromacs/selection/parsetree.cpp index dcbaa4ac1e..05ea9b6c6f 100644 --- a/src/gromacs/selection/parsetree.cpp +++ b/src/gromacs/selection/parsetree.cpp @@ -246,13 +246,12 @@ #include "symrec.h" using gmx::SelectionLocation; -using gmx::SelectionParserValue; -using gmx::SelectionParserValueList; -using gmx::SelectionParserValueListPointer; using gmx::SelectionParserParameter; using gmx::SelectionParserParameterList; using gmx::SelectionParserParameterListPointer; using gmx::SelectionParserValue; +using gmx::SelectionParserValueList; +using gmx::SelectionParserValueListPointer; using gmx::SelectionTreeElement; using gmx::SelectionTreeElementPointer; @@ -265,54 +264,46 @@ namespace * The returned string is used as the context for errors reported during * parsing. */ -std::string -formatCurrentErrorContext(yyscan_t scanner) +std::string formatCurrentErrorContext(yyscan_t scanner) { - return gmx::formatString( - "While parsing '%s'", - _gmx_sel_lexer_get_current_text(scanner).c_str()); + return gmx::formatString("While parsing '%s'", _gmx_sel_lexer_get_current_text(scanner).c_str()); } } // namespace -bool -_gmx_selparser_handle_exception(yyscan_t scanner, std::exception *ex) +bool _gmx_selparser_handle_exception(yyscan_t scanner, std::exception* ex) { try { - bool canContinue = false; - gmx::GromacsException *gromacsException - = dynamic_cast(ex); + bool canContinue = false; + gmx::GromacsException* gromacsException = dynamic_cast(ex); if (gromacsException != nullptr) { gromacsException->prependContext(formatCurrentErrorContext(scanner)); - canContinue = (dynamic_cast(ex) != nullptr); + canContinue = (dynamic_cast(ex) != nullptr); } _gmx_sel_lexer_set_exception(scanner, std::current_exception()); return canContinue; } - catch (const std::exception &) + catch (const std::exception&) { _gmx_sel_lexer_set_exception(scanner, std::current_exception()); return false; } } -bool -_gmx_selparser_handle_error(yyscan_t scanner) +bool _gmx_selparser_handle_error(yyscan_t scanner) { - std::string context(gmx::formatString("Invalid selection '%s'", - _gmx_sel_lexer_pselstr(scanner))); + std::string context(gmx::formatString("Invalid selection '%s'", _gmx_sel_lexer_pselstr(scanner))); // The only way to prepend context to the exception is to rethrow it. try { _gmx_sel_lexer_rethrow_exception_if_occurred(scanner); } - catch (gmx::UserInputError &ex) + catch (gmx::UserInputError& ex) { ex.prependContext(context); - gmx::TextWriter *statusWriter - = _gmx_sel_lexer_get_status_writer(scanner); + gmx::TextWriter* statusWriter = _gmx_sel_lexer_get_status_writer(scanner); if (statusWriter != nullptr) { gmx::formatExceptionMessageToWriter(statusWriter, ex); @@ -320,7 +311,7 @@ _gmx_selparser_handle_error(yyscan_t scanner) } throw; } - catch (gmx::GromacsException &ex) + catch (gmx::GromacsException& ex) { ex.prependContext(context); throw; @@ -336,16 +327,17 @@ namespace gmx * SelectionParserValue */ -SelectionParserValue::SelectionParserValue( - e_selvalue_t type, const SelectionLocation &location) - : type(type), location_(location) +SelectionParserValue::SelectionParserValue(e_selvalue_t type, const SelectionLocation& location) : + type(type), + location_(location) { memset(&u, 0, sizeof(u)); } -SelectionParserValue::SelectionParserValue( - const SelectionTreeElementPointer &expr) - : type(expr->v.type), expr(expr), location_(expr->location()) +SelectionParserValue::SelectionParserValue(const SelectionTreeElementPointer& expr) : + type(expr->v.type), + expr(expr), + location_(expr->location()) { memset(&u, 0, sizeof(u)); } @@ -354,13 +346,12 @@ SelectionParserValue::SelectionParserValue( * SelectionParserParameter */ -SelectionParserParameter::SelectionParserParameter( - const char *name, - SelectionParserValueListPointer values, - const SelectionLocation &location) - : name_(name != nullptr ? name : ""), - location_(location), - values_(values ? std::move(values) : std::make_unique()) +SelectionParserParameter::SelectionParserParameter(const char* name, + SelectionParserValueListPointer values, + const SelectionLocation& location) : + name_(name != nullptr ? name : ""), + location_(location), + values_(values ? std::move(values) : std::make_unique()) { } @@ -383,11 +374,10 @@ SelectionParserParameter::SelectionParserParameter( * is set for an element, the function returns immediately, and the recursive * operation does not descend beyond such elements. */ -void -_gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) +void _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer& sel) { - bool bUseChildType = false; - bool bOnlySingleChildren; + bool bUseChildType = false; + bool bOnlySingleChildren; /* Return if the flags have already been set */ if (sel->flags & SEL_FLAGSSET) @@ -399,7 +389,7 @@ _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) { case SEL_CONST: case SEL_GROUPREF: - sel->flags |= SEL_SINGLEVAL; + sel->flags |= SEL_SINGLEVAL; bUseChildType = false; break; @@ -424,7 +414,7 @@ _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) break; case SEL_ARITHMETIC: - sel->flags |= SEL_ATOMVAL; + sel->flags |= SEL_ATOMVAL; bUseChildType = false; break; @@ -436,18 +426,14 @@ _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) bUseChildType = false; break; - case SEL_ROOT: - bUseChildType = false; - break; + case SEL_ROOT: bUseChildType = false; break; case SEL_BOOLEAN: case SEL_SUBEXPR: - case SEL_SUBEXPRREF: - bUseChildType = true; - break; + case SEL_SUBEXPRREF: bUseChildType = true; break; } /* Loop through children to propagate their flags upwards */ - bOnlySingleChildren = true; + bOnlySingleChildren = true; SelectionTreeElementPointer child = sel->child; while (child) { @@ -458,8 +444,7 @@ _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) /* Propagate the type flag if necessary and check for problems */ if (bUseChildType) { - if ((sel->flags & SEL_VALTYPEMASK) - && !(sel->flags & child->flags & SEL_VALTYPEMASK)) + if ((sel->flags & SEL_VALTYPEMASK) && !(sel->flags & child->flags & SEL_VALTYPEMASK)) { // TODO: Recollect when this is triggered, and whether the type // is appropriate. @@ -499,20 +484,18 @@ _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel) * expressions with the same method to coexist peacefully. * Calls sel_datafunc() if one is specified for the method. */ -void -_gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel, - yyscan_t scanner) +void _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer& sel, yyscan_t scanner) { int nparams; - gmx_ana_selparam_t *orgparam; - gmx_ana_selparam_t *param; + gmx_ana_selparam_t* orgparam; + gmx_ana_selparam_t* param; int i; - void *mdata; + void* mdata; - nparams = sel->u.expr.method->nparams; - orgparam = sel->u.expr.method->param; + nparams = sel->u.expr.method->nparams; + orgparam = sel->u.expr.method->param; snew(param, nparams); - memcpy(param, orgparam, nparams*sizeof(gmx_ana_selparam_t)); + memcpy(param, orgparam, nparams * sizeof(gmx_ana_selparam_t)); for (i = 0; i < nparams; ++i) { param[i].flags &= ~SPAR_SET; @@ -532,9 +515,8 @@ _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel, { ++n; } - _gmx_selvalue_reserve(¶m[i].val, n+1); - memcpy(param[i].val.u.s, orgparam[i].val.u.s, - (n+1)*sizeof(param[i].val.u.s[0])); + _gmx_selvalue_reserve(¶m[i].val, n + 1); + memcpy(param[i].val.u.s, orgparam[i].val.u.s, (n + 1) * sizeof(param[i].val.u.s[0])); } } mdata = nullptr; @@ -544,7 +526,7 @@ _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel, } if (sel->u.expr.method->set_poscoll) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); sel->u.expr.method->set_poscoll(&sc->pcc, mdata); } @@ -561,10 +543,9 @@ _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel, * Makes a copy of \p method and stores it in \p sel->u.expr.method, * and calls _gmx_selelem_init_method_params(); */ -void -_gmx_selelem_set_method(const gmx::SelectionTreeElementPointer &sel, - gmx_ana_selmethod_t *method, - yyscan_t scanner) +void _gmx_selelem_set_method(const gmx::SelectionTreeElementPointer& sel, + gmx_ana_selmethod_t* method, + yyscan_t scanner) { _gmx_selelem_set_vtype(sel, method->type); sel->setName(method->name); @@ -581,10 +562,9 @@ _gmx_selelem_set_method(const gmx::SelectionTreeElementPointer &sel, * \param[in,out] sel Selection element to initialize. * \param[in] rpost Reference position type to use (NULL = default). */ -static void -set_refpos_type(gmx::PositionCalculationCollection *pcc, - const SelectionTreeElementPointer &sel, - const char *rpost) +static void set_refpos_type(gmx::PositionCalculationCollection* pcc, + const SelectionTreeElementPointer& sel, + const char* rpost) { if (!rpost) { @@ -594,38 +574,33 @@ set_refpos_type(gmx::PositionCalculationCollection *pcc, if (sel->u.expr.method->pupdate) { /* By default, use whole residues/molecules. */ - sel->u.expr.pc - = pcc->createCalculationFromEnum(rpost, POS_COMPLWHOLE); + sel->u.expr.pc = pcc->createCalculationFromEnum(rpost, POS_COMPLWHOLE); } else { - std::string message - = gmx::formatString("Position modifiers ('%s') is not applicable for '%s'", - rpost, sel->u.expr.method->name); + std::string message = gmx::formatString( + "Position modifiers ('%s') is not applicable for '%s'", rpost, sel->u.expr.method->name); GMX_THROW(gmx::InvalidInputError(message)); } } -gmx::SelectionTreeElementPointer -_gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left, - const gmx::SelectionTreeElementPointer &right, - char op, yyscan_t scanner) +gmx::SelectionTreeElementPointer _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer& left, + const gmx::SelectionTreeElementPointer& right, + char op, + yyscan_t scanner) { SelectionTreeElementPointer sel( - new SelectionTreeElement( - SEL_ARITHMETIC, _gmx_sel_lexer_get_current_location(scanner))); - sel->v.type = REAL_VALUE; + new SelectionTreeElement(SEL_ARITHMETIC, _gmx_sel_lexer_get_current_location(scanner))); + sel->v.type = REAL_VALUE; switch (op) { case '+': sel->u.arith.type = ARITH_PLUS; break; case '-': sel->u.arith.type = (right ? ARITH_MINUS : ARITH_NEG); break; case '*': sel->u.arith.type = ARITH_MULT; break; - case '/': sel->u.arith.type = ARITH_DIV; break; - case '^': sel->u.arith.type = ARITH_EXP; break; + case '/': sel->u.arith.type = ARITH_DIV; break; + case '^': sel->u.arith.type = ARITH_EXP; break; } - char buf[2] { - op, 0 - }; + char buf[2]{ op, 0 }; sel->setName(buf); sel->u.arith.opstr = gmx_strdup(buf); sel->child = left; @@ -643,33 +618,29 @@ _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left, * This function handles the creation of a gmx::SelectionTreeElement object for * comparison expressions. */ -SelectionTreeElementPointer -_gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left, - const gmx::SelectionTreeElementPointer &right, - const char *cmpop, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer& left, + const gmx::SelectionTreeElementPointer& right, + const char* cmpop, + yyscan_t scanner) { - SelectionTreeElementPointer sel( - new SelectionTreeElement( - SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); + SelectionTreeElementPointer sel( + new SelectionTreeElement(SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(sel, &sm_compare, scanner); SelectionParserParameterList params; - const char *name; + const char* name; // Create the parameter for the left expression. - name = left->v.type == INT_VALUE ? "int1" : "real1"; + name = left->v.type == INT_VALUE ? "int1" : "real1"; params.push_back(SelectionParserParameter::createFromExpression(name, left)); // Create the parameter for the right expression. - name = right->v.type == INT_VALUE ? "int2" : "real2"; + name = right->v.type == INT_VALUE ? "int2" : "real2"; params.push_back(SelectionParserParameter::createFromExpression(name, right)); // Create the parameter for the operator. // TODO: Consider whether a proper location is needed. SelectionLocation location(SelectionLocation::createEmpty()); - params.push_back( - SelectionParserParameter::create( - "op", SelectionParserValue::createString(cmpop, location), - location)); - _gmx_sel_parse_params(params, sel->u.expr.method->nparams, - sel->u.expr.method->param, sel, scanner); + params.push_back(SelectionParserParameter::create( + "op", SelectionParserValue::createString(cmpop, location), location)); + _gmx_sel_parse_params(params, sel->u.expr.method->nparams, sel->u.expr.method->param, sel, scanner); return sel; } @@ -688,22 +659,21 @@ _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left, * This function handles the creation of a gmx::SelectionTreeElement object for * selection methods that do not take parameters. */ -static SelectionTreeElementPointer -init_keyword_internal(gmx_ana_selmethod_t *method, - gmx::SelectionStringMatchType matchType, - SelectionParserValueListPointer args, - const char *rpost, yyscan_t scanner) +static SelectionTreeElementPointer init_keyword_internal(gmx_ana_selmethod_t* method, + gmx::SelectionStringMatchType matchType, + SelectionParserValueListPointer args, + const char* rpost, + yyscan_t scanner) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); if (method->nparams > 0) { // TODO: Would assert be better? - GMX_THROW(gmx::InternalError( - "Keyword initialization called with non-keyword method")); + GMX_THROW(gmx::InternalError("Keyword initialization called with non-keyword method")); } - const SelectionLocation &location = _gmx_sel_lexer_get_current_location(scanner); + const SelectionLocation& location = _gmx_sel_lexer_get_current_location(scanner); // TODO: If there are arguments, the location would be better as just the // location of the keyword itself. SelectionTreeElementPointer root(new SelectionTreeElement(SEL_EXPRESSION, location)); @@ -713,15 +683,13 @@ init_keyword_internal(gmx_ana_selmethod_t *method, /* Initialize the evaluation of keyword matching if values are provided */ if (args) { - gmx_ana_selmethod_t *kwmethod; + gmx_ana_selmethod_t* kwmethod; switch (method->type) { - case INT_VALUE: kwmethod = &sm_keyword_int; break; + case INT_VALUE: kwmethod = &sm_keyword_int; break; case REAL_VALUE: kwmethod = &sm_keyword_real; break; - case STR_VALUE: kwmethod = &sm_keyword_str; break; - default: - GMX_THROW(gmx::InternalError( - "Unknown type for keyword selection")); + case STR_VALUE: kwmethod = &sm_keyword_str; break; + default: GMX_THROW(gmx::InternalError("Unknown type for keyword selection")); } /* Initialize the selection element */ root = std::make_shared(SEL_EXPRESSION, location); @@ -731,12 +699,10 @@ init_keyword_internal(gmx_ana_selmethod_t *method, _gmx_selelem_set_kwstr_match_type(root, matchType); } SelectionParserParameterList params; - params.push_back( - SelectionParserParameter::createFromExpression(nullptr, child)); - params.push_back( - SelectionParserParameter::create(nullptr, std::move(args), location)); - _gmx_sel_parse_params(params, root->u.expr.method->nparams, - root->u.expr.method->param, root, scanner); + params.push_back(SelectionParserParameter::createFromExpression(nullptr, child)); + params.push_back(SelectionParserParameter::create(nullptr, std::move(args), location)); + _gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, + root, scanner); } set_refpos_type(&sc->pcc, child, rpost); @@ -753,13 +719,12 @@ init_keyword_internal(gmx_ana_selmethod_t *method, * This function handles the creation of a gmx::SelectionTreeElement object for * selection methods that do not take parameters. */ -SelectionTreeElementPointer -_gmx_sel_init_keyword(gmx_ana_selmethod_t *method, - gmx::SelectionParserValueListPointer args, - const char *rpost, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_keyword(gmx_ana_selmethod_t* method, + gmx::SelectionParserValueListPointer args, + const char* rpost, + yyscan_t scanner) { - return init_keyword_internal(method, gmx::eStringMatchType_Auto, std::move(args), - rpost, scanner); + return init_keyword_internal(method, gmx::eStringMatchType_Auto, std::move(args), rpost, scanner); } /*! @@ -773,11 +738,11 @@ _gmx_sel_init_keyword(gmx_ana_selmethod_t *method, * This function handles the creation of a gmx::SelectionTreeElement object for * keyword string matching. */ -SelectionTreeElementPointer -_gmx_sel_init_keyword_strmatch(gmx_ana_selmethod_t *method, - gmx::SelectionStringMatchType matchType, - gmx::SelectionParserValueListPointer args, - const char *rpost, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_keyword_strmatch(gmx_ana_selmethod_t* method, + gmx::SelectionStringMatchType matchType, + gmx::SelectionParserValueListPointer args, + const char* rpost, + yyscan_t scanner) { GMX_RELEASE_ASSERT(method->type == STR_VALUE, "String keyword method called for a non-string-valued method"); @@ -796,10 +761,10 @@ _gmx_sel_init_keyword_strmatch(gmx_ana_selmethod_t *method, * This function handles the creation of a gmx::SelectionTreeElement object for * expressions like "z of ...". */ -SelectionTreeElementPointer -_gmx_sel_init_keyword_of(gmx_ana_selmethod_t *method, - const gmx::SelectionTreeElementPointer &group, - const char *rpost, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_keyword_of(gmx_ana_selmethod_t* method, + const gmx::SelectionTreeElementPointer& group, + const char* rpost, + yyscan_t scanner) { // TODO Provide an error if rpost is provided. GMX_UNUSED_VALUE(rpost); @@ -821,23 +786,21 @@ _gmx_sel_init_keyword_of(gmx_ana_selmethod_t *method, * use of any keyword in \c "same KEYWORD as" without requiring special * handling somewhere else (or sacrificing the simple syntax). */ -SelectionTreeElementPointer -_gmx_sel_init_method(gmx_ana_selmethod_t *method, - gmx::SelectionParserParameterListPointer params, - const char *rpost, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_method(gmx_ana_selmethod_t* method, + gmx::SelectionParserParameterListPointer params, + const char* rpost, + yyscan_t scanner) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); _gmx_sel_finish_method(scanner); /* The "same" keyword needs some custom massaging of the parameters. */ _gmx_selelem_custom_init_same(&method, params, scanner); SelectionTreeElementPointer root( - new SelectionTreeElement( - SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(root, method, scanner); /* Process the parameters */ - _gmx_sel_parse_params(*params, root->u.expr.method->nparams, - root->u.expr.method->param, root, scanner); + _gmx_sel_parse_params(*params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner); set_refpos_type(&sc->pcc, root, rpost); return root; @@ -853,16 +816,14 @@ _gmx_sel_init_method(gmx_ana_selmethod_t *method, * This function handles the creation of a gmx::SelectionTreeElement object for * selection modifiers. */ -SelectionTreeElementPointer -_gmx_sel_init_modifier(gmx_ana_selmethod_t *method, - gmx::SelectionParserParameterListPointer params, - const gmx::SelectionTreeElementPointer &sel, - yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_modifier(gmx_ana_selmethod_t* method, + gmx::SelectionParserParameterListPointer params, + const gmx::SelectionTreeElementPointer& sel, + yyscan_t scanner) { _gmx_sel_finish_method(scanner); SelectionTreeElementPointer modifier( - new SelectionTreeElement( - SEL_MODIFIER, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_MODIFIER, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(modifier, method, scanner); SelectionTreeElementPointer root; if (method->type == NO_VALUE) @@ -877,13 +838,12 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, } else { - params->push_front( - SelectionParserParameter::createFromExpression(nullptr, sel)); + params->push_front(SelectionParserParameter::createFromExpression(nullptr, sel)); root = modifier; } /* Process the parameters */ - _gmx_sel_parse_params(*params, modifier->u.expr.method->nparams, - modifier->u.expr.method->param, modifier, scanner); + _gmx_sel_parse_params(*params, modifier->u.expr.method->nparams, modifier->u.expr.method->param, + modifier, scanner); return root; } @@ -897,21 +857,19 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, * This function handles the creation of a gmx::SelectionTreeElement object for * evaluation of reference positions. */ -SelectionTreeElementPointer -_gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr, - const char *type, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_position(const gmx::SelectionTreeElementPointer& expr, + const char* type, + yyscan_t scanner) { - SelectionTreeElementPointer root( - new SelectionTreeElement( - SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); + SelectionTreeElementPointer root( + new SelectionTreeElement(SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(root, &sm_keyword_pos, scanner); _gmx_selelem_set_kwpos_type(root.get(), type); /* Create the parameters for the parameter parser. */ SelectionParserParameterList params; params.push_back(SelectionParserParameter::createFromExpression(nullptr, expr)); /* Parse the parameters. */ - _gmx_sel_parse_params(params, root->u.expr.method->nparams, - root->u.expr.method->param, root, scanner); + _gmx_sel_parse_params(params, root->u.expr.method->nparams, root->u.expr.method->param, root, scanner); return root; } @@ -921,16 +879,12 @@ _gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr, * \param[in] scanner Scanner data structure. * \returns The creates selection element. */ -SelectionTreeElementPointer -_gmx_sel_init_const_position(real x, real y, real z, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_const_position(real x, real y, real z, yyscan_t scanner) { - rvec pos { - x, y, z - }; + rvec pos{ x, y, z }; SelectionTreeElementPointer sel( - new SelectionTreeElement( - SEL_CONST, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_CONST, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_vtype(sel, POS_VALUE); _gmx_selvalue_reserve(&sel->v, 1); gmx_ana_pos_init_const(sel->v.u.p, pos); @@ -945,13 +899,11 @@ _gmx_sel_init_const_position(real x, real y, real z, yyscan_t scanner) * See gmx_ana_indexgrps_find() for information on how \p name is matched * against the index groups. */ -SelectionTreeElementPointer -_gmx_sel_init_group_by_name(const char *name, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_group_by_name(const char* name, yyscan_t scanner) { SelectionTreeElementPointer sel( - new SelectionTreeElement( - SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_vtype(sel, GROUP_VALUE); sel->setName(gmx::formatString("group \"%s\"", name)); sel->u.gref.name = gmx_strdup(name); @@ -959,8 +911,8 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner) if (_gmx_sel_lexer_has_groups_set(scanner)) { - gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner); - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_indexgrps_t* grps = _gmx_sel_lexer_indexgrps(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); sel->resolveIndexGroupReference(grps, sc->gall.isize); } @@ -972,12 +924,10 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner) * \param[in] scanner Scanner data structure. * \returns The created selection element. */ -SelectionTreeElementPointer -_gmx_sel_init_group_by_id(int id, yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_group_by_id(int id, yyscan_t scanner) { SelectionTreeElementPointer sel( - new SelectionTreeElement( - SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_GROUPREF, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_vtype(sel, GROUP_VALUE); sel->setName(gmx::formatString("group %d", id)); sel->u.gref.name = nullptr; @@ -985,8 +935,8 @@ _gmx_sel_init_group_by_id(int id, yyscan_t scanner) if (_gmx_sel_lexer_has_groups_set(scanner)) { - gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner); - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_indexgrps_t* grps = _gmx_sel_lexer_indexgrps(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); sel->resolveIndexGroupReference(grps, sc->gall.isize); } @@ -1001,9 +951,8 @@ _gmx_sel_init_group_by_id(int id, yyscan_t scanner) * The reference count of \p sel is updated, but no other modifications are * made. */ -SelectionTreeElementPointer -_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel, - yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer& sel, + yyscan_t scanner) { SelectionTreeElementPointer ref; @@ -1013,8 +962,8 @@ _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel, } else { - ref = std::make_shared( - SEL_SUBEXPRREF, _gmx_sel_lexer_get_current_location(scanner)); + ref = std::make_shared(SEL_SUBEXPRREF, + _gmx_sel_lexer_get_current_location(scanner)); _gmx_selelem_set_vtype(ref, sel->v.type); ref->setName(sel->name()); ref->child = sel; @@ -1032,21 +981,18 @@ _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel, * This function handles the creation of root (\ref SEL_ROOT) * gmx::SelectionTreeElement objects for selections. */ -SelectionTreeElementPointer -_gmx_sel_init_selection(const char *name, - const gmx::SelectionTreeElementPointer &sel, - yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_init_selection(const char* name, + const gmx::SelectionTreeElementPointer& sel, + yyscan_t scanner) { if (sel->v.type != POS_VALUE) { /* FIXME: Better handling of this error */ - GMX_THROW(gmx::InternalError( - "Each selection must evaluate to a position")); + GMX_THROW(gmx::InternalError("Each selection must evaluate to a position")); } SelectionTreeElementPointer root( - new SelectionTreeElement( - SEL_ROOT, _gmx_sel_lexer_get_current_location(scanner))); + new SelectionTreeElement(SEL_ROOT, _gmx_sel_lexer_get_current_location(scanner))); root->child = sel; if (name) { @@ -1064,12 +1010,11 @@ _gmx_sel_init_selection(const char *name, root->fillNameIfMissing(_gmx_sel_lexer_pselstr(scanner)); /* Print out some information if the parser is interactive */ - gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner); + gmx::TextWriter* statusWriter = _gmx_sel_lexer_get_status_writer(scanner); if (statusWriter != nullptr) { - const std::string message - = gmx::formatString("Selection '%s' parsed", - _gmx_sel_lexer_pselstr(scanner)); + const std::string message = + gmx::formatString("Selection '%s' parsed", _gmx_sel_lexer_pselstr(scanner)); statusWriter->writeLine(message); } @@ -1087,14 +1032,13 @@ _gmx_sel_init_selection(const char *name, * for variable assignments. A \ref SEL_ROOT element and a \ref SEL_SUBEXPR * element are both created. */ -SelectionTreeElementPointer -_gmx_sel_assign_variable(const char *name, - const gmx::SelectionTreeElementPointer &expr, - yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_assign_variable(const char* name, + const gmx::SelectionTreeElementPointer& expr, + yyscan_t scanner) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); - const char *pselstr = _gmx_sel_lexer_pselstr(scanner); - SelectionTreeElementPointer root; + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); + const char* pselstr = _gmx_sel_lexer_pselstr(scanner); + SelectionTreeElementPointer root; _gmx_selelem_update_flags(expr); /* Check if this is a constant non-group value */ @@ -1119,7 +1063,7 @@ _gmx_sel_assign_variable(const char *name, root->child = std::make_shared(SEL_SUBEXPR, location); root->child->setName(name); _gmx_selelem_set_vtype(root->child, expr->v.type); - root->child->child = expr; + root->child->child = expr; /* Update flags */ _gmx_selelem_update_flags(root); gmx::ExceptionInitializer errors("Invalid index group reference(s)"); @@ -1134,11 +1078,10 @@ _gmx_sel_assign_variable(const char *name, srenew(sc->varstrs, sc->nvars + 1); sc->varstrs[sc->nvars] = gmx_strdup(pselstr); ++sc->nvars; - gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner); + gmx::TextWriter* statusWriter = _gmx_sel_lexer_get_status_writer(scanner); if (statusWriter != nullptr) { - const std::string message - = gmx::formatString("Variable '%s' parsed", pselstr); + const std::string message = gmx::formatString("Variable '%s' parsed", pselstr); statusWriter->writeLine(message); } return root; @@ -1154,12 +1097,11 @@ _gmx_sel_assign_variable(const char *name, * Appends \p sel after the last root element, and returns either \p sel * (if it was non-NULL) or the last element (if \p sel was NULL). */ -SelectionTreeElementPointer -_gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel, - gmx::SelectionTreeElementPointer last, - yyscan_t scanner) +SelectionTreeElementPointer _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer& sel, + gmx::SelectionTreeElementPointer last, + yyscan_t scanner) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); /* Append sel after last, or the last element of sc if last is NULL */ if (last) @@ -1190,8 +1132,7 @@ _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel, if (sel->child->type != SEL_SUBEXPR) { gmx::SelectionDataPointer selPtr( - new gmx::internal::SelectionData( - sel.get(), _gmx_sel_lexer_pselstr(scanner))); + new gmx::internal::SelectionData(sel.get(), _gmx_sel_lexer_pselstr(scanner))); sc->sel.push_back(std::move(selPtr)); } } @@ -1210,9 +1151,8 @@ _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel, * This is used to terminate interactive parsers when the correct number of * selections has been provided. */ -bool -_gmx_sel_parser_should_finish(yyscan_t scanner) +bool _gmx_sel_parser_should_finish(yyscan_t scanner) { - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); return gmx::ssize(sc->sel) == _gmx_sel_lexer_exp_selcount(scanner); } diff --git a/src/gromacs/selection/parsetree.h b/src/gromacs/selection/parsetree.h index 911e0b153a..d65ac8885d 100644 --- a/src/gromacs/selection/parsetree.h +++ b/src/gromacs/selection/parsetree.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,21 +80,19 @@ namespace gmx */ enum SelectionStringMatchType { - eStringMatchType_Auto, //!< Deduce from the string. - eStringMatchType_Exact, //!< Match as a literal string. - eStringMatchType_Wildcard, //!< Match using ? and * as wildcards. - eStringMatchType_RegularExpression //!< Match using regular expressions. + eStringMatchType_Auto, //!< Deduce from the string. + eStringMatchType_Exact, //!< Match as a literal string. + eStringMatchType_Wildcard, //!< Match using ? and * as wildcards. + eStringMatchType_RegularExpression //!< Match using regular expressions. }; /*! \endcond */ class SelectionParserValue; //! Container for a list of SelectionParserValue objects. -typedef std::list - SelectionParserValueList; +typedef std::list SelectionParserValueList; //! Smart pointer type for managing a SelectionParserValueList. -typedef std::unique_ptr - SelectionParserValueListPointer; +typedef std::unique_ptr SelectionParserValueListPointer; /*! \internal * \brief @@ -106,192 +105,184 @@ typedef std::unique_ptr */ class SelectionParserValue { - public: - //! Allocates and initializes an empty value list. - static SelectionParserValueListPointer createList() +public: + //! Allocates and initializes an empty value list. + static SelectionParserValueListPointer createList() + { + return std::make_unique(); + } + /*! \brief + * Allocates and initializes a value list with a single value. + * + * \param[in] value Initial value to put in the list. + * \returns Pointer to a new value list that contains \p value. + */ + static SelectionParserValueListPointer createList(const SelectionParserValue& value) + { + SelectionParserValueListPointer list(new SelectionParserValueList); + list->push_back(value); + return list; + } + /*! \brief + * Allocates and initializes an expression value. + * + * \param[in] expr Root of the expression tree to assign to the value. + * \returns The newly created value. + */ + static SelectionParserValue createExpr(const gmx::SelectionTreeElementPointer& expr) + { + return SelectionParserValue(expr); + } + /*! \brief + * Allocates and initializes a constant integer value. + * + * \param[in] value Integer value to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createInteger(int value, const SelectionLocation& location) + { + SelectionParserValue result(INT_VALUE, location); + result.u.i.i1 = result.u.i.i2 = value; + return result; + } + /*! \brief + * Allocates and initializes a constant integer range value. + * + * \param[in] from Beginning of the range to assign to the value. + * \param[in] to End of the range to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createIntegerRange(int from, int to, const SelectionLocation& location) + { + SelectionParserValue result(INT_VALUE, location); + result.u.i.i1 = from; + result.u.i.i2 = to; + return result; + } + /*! \brief + * Allocates and initializes a constant floating-point value. + * + * \param[in] value Floating-point value to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createReal(real value, const SelectionLocation& location) + { + SelectionParserValue result(REAL_VALUE, location); + result.u.r.r1 = result.u.r.r2 = value; + return result; + } + /*! \brief + * Allocates and initializes a constant floating-point range value. + * + * \param[in] from Beginning of the range to assign to the value. + * \param[in] to End of the range to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createRealRange(real from, real to, const SelectionLocation& location) + { + SelectionParserValue result(REAL_VALUE, location); + result.u.r.r1 = from; + result.u.r.r2 = to; + return result; + } + /*! \brief + * Allocates and initializes a constant string value. + * + * \param[in] value String to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createString(const char* value, const SelectionLocation& location) + { + SelectionParserValue result(STR_VALUE, location); + result.str = value; + return result; + } + /*! \brief + * Allocates and initializes a constant position value. + * + * \param[in] value Position vector to assign to the value. + * \param[in] location Location of the value. + * \returns The newly created value. + */ + static SelectionParserValue createPosition(rvec value, const SelectionLocation& location) + { + SelectionParserValue result(POS_VALUE, location); + copy_rvec(value, result.u.x); + return result; + } + + //! Returns the location of this value in the parsed selection text. + const SelectionLocation& location() const { return location_; } + //! Returns true if the value comes from expression evaluation. + bool hasExpressionValue() const { return static_cast(expr); } + + //! Returns the string value (\a type must be ::STR_VALUE). + const std::string& stringValue() const + { + GMX_ASSERT(type == STR_VALUE && !hasExpressionValue(), + "Attempted to retrieve string value from a non-string value"); + return str; + } + + // TODO: boost::any or similar could be nicer for the implementation. + //! Type of the value. + e_selvalue_t type; + //! Expression pointer if the value is the result of an expression. + gmx::SelectionTreeElementPointer expr; + //! String value for \a type ::STR_VALUE. + std::string str; + //! The actual value if \a expr is NULL and \a type is not ::STR_VALUE. + union { + //! The integer value/range (\a type ::INT_VALUE). + struct { - return std::make_unique(); - } - /*! \brief - * Allocates and initializes a value list with a single value. - * - * \param[in] value Initial value to put in the list. - * \returns Pointer to a new value list that contains \p value. - */ - static SelectionParserValueListPointer - createList(const SelectionParserValue &value) + //! Beginning of the range. + int i1; + //! End of the range; equals \a i1 for a single integer. + int i2; + } i; + //! The real value/range (\a type ::REAL_VALUE). + struct { - SelectionParserValueListPointer list(new SelectionParserValueList); - list->push_back(value); - return list; - } - /*! \brief - * Allocates and initializes an expression value. - * - * \param[in] expr Root of the expression tree to assign to the value. - * \returns The newly created value. - */ - static SelectionParserValue - createExpr(const gmx::SelectionTreeElementPointer &expr) - { - return SelectionParserValue(expr); - } - /*! \brief - * Allocates and initializes a constant integer value. - * - * \param[in] value Integer value to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createInteger(int value, const SelectionLocation &location) - { - SelectionParserValue result(INT_VALUE, location); - result.u.i.i1 = result.u.i.i2 = value; - return result; - } - /*! \brief - * Allocates and initializes a constant integer range value. - * - * \param[in] from Beginning of the range to assign to the value. - * \param[in] to End of the range to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createIntegerRange(int from, int to, const SelectionLocation &location) - { - SelectionParserValue result(INT_VALUE, location); - result.u.i.i1 = from; - result.u.i.i2 = to; - return result; - } - /*! \brief - * Allocates and initializes a constant floating-point value. - * - * \param[in] value Floating-point value to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createReal(real value, const SelectionLocation &location) - { - SelectionParserValue result(REAL_VALUE, location); - result.u.r.r1 = result.u.r.r2 = value; - return result; - } - /*! \brief - * Allocates and initializes a constant floating-point range value. - * - * \param[in] from Beginning of the range to assign to the value. - * \param[in] to End of the range to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createRealRange(real from, real to, const SelectionLocation &location) - { - SelectionParserValue result(REAL_VALUE, location); - result.u.r.r1 = from; - result.u.r.r2 = to; - return result; - } - /*! \brief - * Allocates and initializes a constant string value. - * - * \param[in] value String to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createString(const char *value, const SelectionLocation &location) - { - SelectionParserValue result(STR_VALUE, location); - result.str = value; - return result; - } - /*! \brief - * Allocates and initializes a constant position value. - * - * \param[in] value Position vector to assign to the value. - * \param[in] location Location of the value. - * \returns The newly created value. - */ - static SelectionParserValue - createPosition(rvec value, const SelectionLocation &location) - { - SelectionParserValue result(POS_VALUE, location); - copy_rvec(value, result.u.x); - return result; - } - - //! Returns the location of this value in the parsed selection text. - const SelectionLocation &location() const { return location_; } - //! Returns true if the value comes from expression evaluation. - bool hasExpressionValue() const { return static_cast(expr); } - - //! Returns the string value (\a type must be ::STR_VALUE). - const std::string &stringValue() const - { - GMX_ASSERT(type == STR_VALUE && !hasExpressionValue(), - "Attempted to retrieve string value from a non-string value"); - return str; - } - - // TODO: boost::any or similar could be nicer for the implementation. - //! Type of the value. - e_selvalue_t type; - //! Expression pointer if the value is the result of an expression. - gmx::SelectionTreeElementPointer expr; - //! String value for \a type ::STR_VALUE. - std::string str; - //! The actual value if \a expr is NULL and \a type is not ::STR_VALUE. - union { - //! The integer value/range (\a type ::INT_VALUE). - struct { - //! Beginning of the range. - int i1; - //! End of the range; equals \a i1 for a single integer. - int i2; - } i; - //! The real value/range (\a type ::REAL_VALUE). - struct { - //! Beginning of the range. - real r1; - //! End of the range; equals \a r1 for a single number. - real r2; - } r; - //! The position value (\a type ::POS_VALUE). - rvec x; - } u; - - private: - /*! \brief - * Initializes a new value. - * - * \param[in] type Type for the new value. - * \param[in] location Location for the value. - */ - SelectionParserValue(e_selvalue_t type, const SelectionLocation &location); - /*! \brief - * Initializes a new expression value. - * - * \param[in] expr Expression for the value. - */ - explicit SelectionParserValue(const gmx::SelectionTreeElementPointer &expr); - - //! Location of the value in the parsed text. - SelectionLocation location_; + //! Beginning of the range. + real r1; + //! End of the range; equals \a r1 for a single number. + real r2; + } r; + //! The position value (\a type ::POS_VALUE). + rvec x; + } u; + +private: + /*! \brief + * Initializes a new value. + * + * \param[in] type Type for the new value. + * \param[in] location Location for the value. + */ + SelectionParserValue(e_selvalue_t type, const SelectionLocation& location); + /*! \brief + * Initializes a new expression value. + * + * \param[in] expr Expression for the value. + */ + explicit SelectionParserValue(const gmx::SelectionTreeElementPointer& expr); + + //! Location of the value in the parsed text. + SelectionLocation location_; }; class SelectionParserParameter; //! Container for a list of SelectionParserParameter objects. -typedef std::list - SelectionParserParameterList; +typedef std::list SelectionParserParameterList; //! Smart pointer type for managing a SelectionParserParameterList. -typedef std::unique_ptr - SelectionParserParameterListPointer; +typedef std::unique_ptr SelectionParserParameterListPointer; /*! \internal \brief * Describes a parsed method parameter. @@ -300,127 +291,124 @@ typedef std::unique_ptr */ class SelectionParserParameter { - public: - // Default move constructor and assignment. Only needed for old compilers. - //! \cond - SelectionParserParameter(SelectionParserParameter &&o) noexcept - : name_(std::move(o.name_)), location_(o.location_), - values_(std::move(o.values_)) - { - } - - SelectionParserParameter &operator=(SelectionParserParameter &&o) noexcept - { - name_ = std::move(o.name_); - location_ = o.location_; - values_ = std::move(o.values_); - return *this; - } - //! \endcond - - //! Allocates and initializes an empty parameter list. - static SelectionParserParameterListPointer createList() - { - return std::make_unique(); - } - /*! \brief - * Allocates and initializes a parsed method parameter. - * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] values List of values for the parameter. - * \param[in] location Location of the parameter. - * \returns Pointer to the newly allocated parameter. - * \throws std::bad_alloc if out of memory. - */ - static SelectionParserParameter - create(const char *name, SelectionParserValueListPointer values, - const SelectionLocation &location) - { - return SelectionParserParameter(name, std::move(values), location); - } - //! \copydoc create(const char *, SelectionParserValueListPointer, const SelectionLocation &) - static SelectionParserParameter - create(const std::string &name, SelectionParserValueListPointer values, - const SelectionLocation &location) - { - return SelectionParserParameter(name.c_str(), std::move(values), location); - } - /*! \brief - * Allocates and initializes a parsed method parameter. - * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] value Value for the parameter. - * \param[in] location Location of the parameter. - * \returns Pointer to the newly allocated parameter. - * \throws std::bad_alloc if out of memory. - * - * This overload is a convenience wrapper for the case when creating - * parameters outside the actual Bison parser and only a single value - * is necessary. - */ - static SelectionParserParameter - create(const char *name, const SelectionParserValue &value, - const SelectionLocation &location) - { - return create(name, SelectionParserValue::createList(value), location); - } - /*! \brief - * Allocates and initializes a parsed method parameter. - * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] expr Expression value for the parameter. - * \returns Pointer to the newly allocated parameter. - * \throws std::bad_alloc if out of memory. - * - * This overload is a convenience wrapper for the case when creating - * parameters outside the actual Bison parser and only a single - * expression value is necessary. - */ - static SelectionParserParameter - createFromExpression(const char *name, - const SelectionTreeElementPointer &expr) - { - return create(name, SelectionParserValue::createExpr(expr), - expr->location()); - } - //! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &) - static SelectionParserParameter - createFromExpression(const std::string &name, - const SelectionTreeElementPointer &expr) - { - return create(name.c_str(), SelectionParserValue::createExpr(expr), - expr->location()); - } - - //! Returns the name of the parameter (may be empty). - const std::string &name() const { return name_; } - //! Returns the location of this parameter in the parsed selection text. - const SelectionLocation &location() const { return location_; } - //! Returns the values for the parameter. - const SelectionParserValueList &values() const { return *values_; } - - private: - /*! \brief - * Initializes a parsed method parameter. - * - * \param[in] name Name for the new parameter (can be NULL). - * \param[in] values List of values for the parameter. - * \param[in] location Location of the parameter. - * \throws std::bad_alloc if out of memory. - */ - SelectionParserParameter(const char *name, - SelectionParserValueListPointer values, - const SelectionLocation &location); - - //! Name of the parameter. - std::string name_; - //! Location of the parameter in the parsed text. - SelectionLocation location_; - - // TODO: Make private, there is only one direct user. - public: - //! Values for this parameter. - SelectionParserValueListPointer values_; +public: + // Default move constructor and assignment. Only needed for old compilers. + //! \cond + SelectionParserParameter(SelectionParserParameter&& o) noexcept : + name_(std::move(o.name_)), + location_(o.location_), + values_(std::move(o.values_)) + { + } + + SelectionParserParameter& operator=(SelectionParserParameter&& o) noexcept + { + name_ = std::move(o.name_); + location_ = o.location_; + values_ = std::move(o.values_); + return *this; + } + //! \endcond + + //! Allocates and initializes an empty parameter list. + static SelectionParserParameterListPointer createList() + { + return std::make_unique(); + } + /*! \brief + * Allocates and initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] values List of values for the parameter. + * \param[in] location Location of the parameter. + * \returns Pointer to the newly allocated parameter. + * \throws std::bad_alloc if out of memory. + */ + static SelectionParserParameter create(const char* name, + SelectionParserValueListPointer values, + const SelectionLocation& location) + { + return SelectionParserParameter(name, std::move(values), location); + } + //! \copydoc create(const char *, SelectionParserValueListPointer, const SelectionLocation &) + static SelectionParserParameter create(const std::string& name, + SelectionParserValueListPointer values, + const SelectionLocation& location) + { + return SelectionParserParameter(name.c_str(), std::move(values), location); + } + /*! \brief + * Allocates and initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] value Value for the parameter. + * \param[in] location Location of the parameter. + * \returns Pointer to the newly allocated parameter. + * \throws std::bad_alloc if out of memory. + * + * This overload is a convenience wrapper for the case when creating + * parameters outside the actual Bison parser and only a single value + * is necessary. + */ + static SelectionParserParameter create(const char* name, + const SelectionParserValue& value, + const SelectionLocation& location) + { + return create(name, SelectionParserValue::createList(value), location); + } + /*! \brief + * Allocates and initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] expr Expression value for the parameter. + * \returns Pointer to the newly allocated parameter. + * \throws std::bad_alloc if out of memory. + * + * This overload is a convenience wrapper for the case when creating + * parameters outside the actual Bison parser and only a single + * expression value is necessary. + */ + static SelectionParserParameter createFromExpression(const char* name, + const SelectionTreeElementPointer& expr) + { + return create(name, SelectionParserValue::createExpr(expr), expr->location()); + } + //! \copydoc createFromExpression(const char *, const SelectionTreeElementPointer &) + static SelectionParserParameter createFromExpression(const std::string& name, + const SelectionTreeElementPointer& expr) + { + return create(name.c_str(), SelectionParserValue::createExpr(expr), expr->location()); + } + + //! Returns the name of the parameter (may be empty). + const std::string& name() const { return name_; } + //! Returns the location of this parameter in the parsed selection text. + const SelectionLocation& location() const { return location_; } + //! Returns the values for the parameter. + const SelectionParserValueList& values() const { return *values_; } + +private: + /*! \brief + * Initializes a parsed method parameter. + * + * \param[in] name Name for the new parameter (can be NULL). + * \param[in] values List of values for the parameter. + * \param[in] location Location of the parameter. + * \throws std::bad_alloc if out of memory. + */ + SelectionParserParameter(const char* name, + SelectionParserValueListPointer values, + const SelectionLocation& location); + + //! Name of the parameter. + std::string name_; + //! Location of the parameter in the parsed text. + SelectionLocation location_; + + // TODO: Make private, there is only one direct user. +public: + //! Values for this parameter. + SelectionParserValueListPointer values_; }; } // namespace gmx @@ -442,8 +430,7 @@ class SelectionParserParameter * If this function returns false, then Bison immediately aborts the parsing * so that the caller can rethrow the exception. */ -bool -_gmx_selparser_handle_exception(void *scanner, std::exception *ex); +bool _gmx_selparser_handle_exception(void* scanner, std::exception* ex); /*! \brief * Handles errors in the selection parser. * @@ -465,26 +452,22 @@ _gmx_selparser_handle_exception(void *scanner, std::exception *ex); * Any exceptions thrown from this method are again caught by Bison and result * in termination of the parsing; the caller can then rethrow them. */ -bool -_gmx_selparser_handle_error(void *scanner); +bool _gmx_selparser_handle_error(void* scanner); /** Propagates the flags for selection elements. */ -void -_gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer &sel); +void _gmx_selelem_update_flags(const gmx::SelectionTreeElementPointer& sel); /** Initializes the method parameter data of \ref SEL_EXPRESSION and * \ref SEL_MODIFIER elements. */ -void -_gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer &sel, - void *scanner); +void _gmx_selelem_init_method_params(const gmx::SelectionTreeElementPointer& sel, void* scanner); /** Initializes the method for a \ref SEL_EXPRESSION selection element. */ -void -_gmx_selelem_set_method(const gmx::SelectionTreeElementPointer &sel, - struct gmx_ana_selmethod_t *method, void *scanner); +void _gmx_selelem_set_method(const gmx::SelectionTreeElementPointer& sel, + struct gmx_ana_selmethod_t* method, + void* scanner); /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T +# define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /** \brief Creates a gmx::SelectionTreeElement for arithmetic expression evaluation. @@ -498,86 +481,77 @@ typedef void* yyscan_t; * This function handles the creation of a gmx::SelectionTreeElement object for * arithmetic expressions. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer &left, - const gmx::SelectionTreeElementPointer &right, - char op, yyscan_t scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_arithmetic(const gmx::SelectionTreeElementPointer& left, + const gmx::SelectionTreeElementPointer& right, + char op, + yyscan_t scanner); /** Creates a gmx::SelectionTreeElement for comparsion expression evaluation. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer &left, - const gmx::SelectionTreeElementPointer &right, - const char *cmpop, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_comparison(const gmx::SelectionTreeElementPointer& left, + const gmx::SelectionTreeElementPointer& right, + const char* cmpop, + void* scanner); /** Creates a gmx::SelectionTreeElement for a keyword expression from the parsed data. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_keyword(struct gmx_ana_selmethod_t *method, - gmx::SelectionParserValueListPointer args, - const char *rpost, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_keyword(struct gmx_ana_selmethod_t* method, + gmx::SelectionParserValueListPointer args, + const char* rpost, + void* scanner); /** Creates a gmx::SelectionTreeElement for string-matching keyword expression. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_keyword_strmatch(struct gmx_ana_selmethod_t *method, - gmx::SelectionStringMatchType matchType, - gmx::SelectionParserValueListPointer args, - const char *rpost, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_keyword_strmatch(struct gmx_ana_selmethod_t* method, + gmx::SelectionStringMatchType matchType, + gmx::SelectionParserValueListPointer args, + const char* rpost, + void* scanner); /** Creates a gmx::SelectionTreeElement for "keyword of" expression. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_keyword_of(struct gmx_ana_selmethod_t *method, - const gmx::SelectionTreeElementPointer &group, - const char *rpost, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_keyword_of(struct gmx_ana_selmethod_t* method, + const gmx::SelectionTreeElementPointer& group, + const char* rpost, + void* scanner); /** Creates a gmx::SelectionTreeElement for a method expression from the parsed data. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_method(struct gmx_ana_selmethod_t *method, - gmx::SelectionParserParameterListPointer params, - const char *rpost, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_method(struct gmx_ana_selmethod_t* method, + gmx::SelectionParserParameterListPointer params, + const char* rpost, + void* scanner); /** Creates a gmx::SelectionTreeElement for a modifier expression from the parsed data. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_modifier(struct gmx_ana_selmethod_t *mod, - gmx::SelectionParserParameterListPointer params, - const gmx::SelectionTreeElementPointer &sel, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_modifier(struct gmx_ana_selmethod_t* mod, + gmx::SelectionParserParameterListPointer params, + const gmx::SelectionTreeElementPointer& sel, + void* scanner); /** Creates a gmx::SelectionTreeElement for evaluation of reference positions. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr, - const char *type, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_position(const gmx::SelectionTreeElementPointer& expr, + const char* type, + void* scanner); /** Creates a gmx::SelectionTreeElement for a constant position. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_const_position(real x, real y, real z, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_const_position(real x, real y, real z, void* scanner); /** Creates a gmx::SelectionTreeElement for a index group expression using group name. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_group_by_name(const char *name, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_group_by_name(const char* name, void* scanner); /** Creates a gmx::SelectionTreeElement for a index group expression using group index. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_group_by_id(int id, void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_group_by_id(int id, void* scanner); /** Creates a gmx::SelectionTreeElement for a variable reference */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer &sel, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_variable_ref(const gmx::SelectionTreeElementPointer& sel, + void* scanner); /** Creates a root gmx::SelectionTreeElement for a selection. */ -gmx::SelectionTreeElementPointer -_gmx_sel_init_selection(const char *name, - const gmx::SelectionTreeElementPointer &sel, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_init_selection(const char* name, + const gmx::SelectionTreeElementPointer& sel, + void* scanner); /** Creates a root gmx::SelectionTreeElement elements for a variable assignment. */ -gmx::SelectionTreeElementPointer -_gmx_sel_assign_variable(const char *name, - const gmx::SelectionTreeElementPointer &expr, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_assign_variable(const char* name, + const gmx::SelectionTreeElementPointer& expr, + void* scanner); /** Appends a root gmx::SelectionTreeElement to a selection collection. */ -gmx::SelectionTreeElementPointer -_gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel, - gmx::SelectionTreeElementPointer last, - void *scanner); +gmx::SelectionTreeElementPointer _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer& sel, + gmx::SelectionTreeElementPointer last, + void* scanner); /** Check whether the parser should finish. */ -bool -_gmx_sel_parser_should_finish(void *scanner); +bool _gmx_sel_parser_should_finish(void* scanner); /* In params.c */ /** Initializes an array of parameters based on input from the selection parser. */ -void -_gmx_sel_parse_params(const gmx::SelectionParserParameterList ¶ms, - int nparam, struct gmx_ana_selparam_t *param, - const gmx::SelectionTreeElementPointer &root, - void *scanner); +void _gmx_sel_parse_params(const gmx::SelectionParserParameterList& params, + int nparam, + struct gmx_ana_selparam_t* param, + const gmx::SelectionTreeElementPointer& root, + void* scanner); #endif diff --git a/src/gromacs/selection/poscalc.cpp b/src/gromacs/selection/poscalc.cpp index 6bd07e525f..3c46692603 100644 --- a/src/gromacs/selection/poscalc.cpp +++ b/src/gromacs/selection/poscalc.cpp @@ -89,79 +89,78 @@ namespace gmx */ class PositionCalculationCollection::Impl { - public: - Impl(); - ~Impl(); - - /*! \brief - * Inserts a position calculation structure into its collection. - * - * \param pc Data structure to insert. - * \param before Data structure before which to insert - * (NULL = insert at end). - * - * Inserts \p pc to its collection before \p before. - * If \p before is NULL, \p pc is appended to the list. - */ - void insertCalculation(gmx_ana_poscalc_t *pc, gmx_ana_poscalc_t *before); - /*! \brief - * Removes a position calculation structure from its collection. - * - * \param pc Data structure to remove. - * - * Removes \p pc from its collection. - */ - void removeCalculation(gmx_ana_poscalc_t *pc); +public: + Impl(); + ~Impl(); - /*! \copydoc PositionCalculationCollection::createCalculation() - * - * This method contains the actual implementation of the similarly - * named method in the parent class. - */ - gmx_ana_poscalc_t *createCalculation(e_poscalc_t type, int flags); - - /*! \brief - * Maps given topology indices into frame indices. - * - * Only one position calculation at a time needs to access this (and - * there are also other thread-unsafe constructs here), so a temporary - * array is used to avoid repeated memory allocation. - */ - ArrayRef getFrameIndices(int size, int index[]) + /*! \brief + * Inserts a position calculation structure into its collection. + * + * \param pc Data structure to insert. + * \param before Data structure before which to insert + * (NULL = insert at end). + * + * Inserts \p pc to its collection before \p before. + * If \p before is NULL, \p pc is appended to the list. + */ + void insertCalculation(gmx_ana_poscalc_t* pc, gmx_ana_poscalc_t* before); + /*! \brief + * Removes a position calculation structure from its collection. + * + * \param pc Data structure to remove. + * + * Removes \p pc from its collection. + */ + void removeCalculation(gmx_ana_poscalc_t* pc); + + /*! \copydoc PositionCalculationCollection::createCalculation() + * + * This method contains the actual implementation of the similarly + * named method in the parent class. + */ + gmx_ana_poscalc_t* createCalculation(e_poscalc_t type, int flags); + + /*! \brief + * Maps given topology indices into frame indices. + * + * Only one position calculation at a time needs to access this (and + * there are also other thread-unsafe constructs here), so a temporary + * array is used to avoid repeated memory allocation. + */ + ArrayRef getFrameIndices(int size, int index[]) + { + if (mapToFrameAtoms_.empty()) { - if (mapToFrameAtoms_.empty()) - { - return constArrayRefFromArray(index, size); - } - tmpFrameAtoms_.resize(size); - for (int i = 0; i < size; ++i) - { - const int ii = index[i]; - GMX_ASSERT(ii >= 0 && ii <= ssize(mapToFrameAtoms_) - && mapToFrameAtoms_[ii] != -1, - "Invalid input atom index"); - tmpFrameAtoms_[i] = mapToFrameAtoms_[ii]; - } - return tmpFrameAtoms_; + return constArrayRefFromArray(index, size); + } + tmpFrameAtoms_.resize(size); + for (int i = 0; i < size; ++i) + { + const int ii = index[i]; + GMX_ASSERT(ii >= 0 && ii <= ssize(mapToFrameAtoms_) && mapToFrameAtoms_[ii] != -1, + "Invalid input atom index"); + tmpFrameAtoms_[i] = mapToFrameAtoms_[ii]; } + return tmpFrameAtoms_; + } - /*! \brief - * Topology data. - * - * Can be NULL if none of the calculations require topology data or if - * setTopology() has not been called. - */ - const gmx_mtop_t *top_; - //! Pointer to the first data structure. - gmx_ana_poscalc_t *first_; - //! Pointer to the last data structure. - gmx_ana_poscalc_t *last_; - //! Whether the collection has been initialized for evaluation. - bool bInit_; - //! Mapping from topology atoms to frame atoms (one index for each topology atom). - std::vector mapToFrameAtoms_; - //! Working array for updating positions. - std::vector tmpFrameAtoms_; + /*! \brief + * Topology data. + * + * Can be NULL if none of the calculations require topology data or if + * setTopology() has not been called. + */ + const gmx_mtop_t* top_; + //! Pointer to the first data structure. + gmx_ana_poscalc_t* first_; + //! Pointer to the last data structure. + gmx_ana_poscalc_t* last_; + //! Whether the collection has been initialized for evaluation. + bool bInit_; + //! Mapping from topology atoms to frame atoms (one index for each topology atom). + std::vector mapToFrameAtoms_; + //! Working array for updating positions. + std::vector tmpFrameAtoms_; }; } // namespace gmx @@ -181,13 +180,13 @@ struct gmx_ana_poscalc_t * To provide a consistent interface to the user, the field \p itype * should be used when information should be given out. */ - e_poscalc_t type; + e_poscalc_t type; /*! \brief * Flags for calculation options. * * See \ref poscalc_flags "documentation of the flags". */ - int flags; + int flags; /*! \brief * Type for the created indices. @@ -195,27 +194,27 @@ struct gmx_ana_poscalc_t * This field always agrees with the type that the user requested, but * may differ from \p type. */ - e_index_t itype; + e_index_t itype; /*! \brief * Block data for the calculation. */ - t_blocka b; + t_blocka b; /*! \brief * Mapping from the blocks to the blocks of \p sbase. * * If \p sbase is NULL, this field is also. */ - int *baseid; + int* baseid; /*! \brief * Maximum evaluation group. */ - gmx_ana_index_t gmax; + gmx_ana_index_t gmax; /** Position storage for calculations that are used as a base. */ - gmx_ana_pos_t *p; + gmx_ana_pos_t* p; /** true if the positions have been evaluated for the current frame. */ - bool bEval; + bool bEval; /*! \brief * Base position data for this calculation. * @@ -223,28 +222,22 @@ struct gmx_ana_poscalc_t * already been calculated in \p sbase. * The structure pointed by \p sbase is always a static calculation. */ - gmx_ana_poscalc_t *sbase; + gmx_ana_poscalc_t* sbase; /** Next structure in the linked list of calculations. */ - gmx_ana_poscalc_t *next; + gmx_ana_poscalc_t* next; /** Previous structure in the linked list of calculations. */ - gmx_ana_poscalc_t *prev; + gmx_ana_poscalc_t* prev; /** Number of references to this structure. */ - int refcount; + int refcount; /** Collection this calculation belongs to. */ - gmx::PositionCalculationCollection::Impl *coll; + gmx::PositionCalculationCollection::Impl* coll; }; -const char * const gmx::PositionCalculationCollection::typeEnumValues[] = { - "atom", - "res_com", "res_cog", - "mol_com", "mol_cog", - "whole_res_com", "whole_res_cog", - "whole_mol_com", "whole_mol_cog", - "part_res_com", "part_res_cog", - "part_mol_com", "part_mol_cog", - "dyn_res_com", "dyn_res_cog", - "dyn_mol_com", "dyn_mol_cog", - nullptr, +const char* const gmx::PositionCalculationCollection::typeEnumValues[] = { + "atom", "res_com", "res_cog", "mol_com", "mol_cog", + "whole_res_com", "whole_res_cog", "whole_mol_com", "whole_mol_cog", "part_res_com", + "part_res_cog", "part_mol_com", "part_mol_cog", "dyn_res_com", "dyn_res_cog", + "dyn_mol_com", "dyn_mol_cog", nullptr, }; /*! \brief @@ -253,15 +246,14 @@ const char * const gmx::PositionCalculationCollection::typeEnumValues[] = { * \param [in] type \c e_poscalc_t value to convert. * \returns Corresponding \c e_indet_t. */ -static e_index_t -index_type_for_poscalc(e_poscalc_t type) +static e_index_t index_type_for_poscalc(e_poscalc_t type) { switch (type) { - case POS_ATOM: return INDEX_ATOM; - case POS_RES: return INDEX_RES; - case POS_MOL: return INDEX_MOL; - case POS_ALL: return INDEX_ALL; + case POS_ATOM: return INDEX_ATOM; + case POS_RES: return INDEX_RES; + case POS_MOL: return INDEX_MOL; + case POS_ALL: return INDEX_ALL; case POS_ALL_PBC: return INDEX_ALL; } return INDEX_UNKNOWN; @@ -274,8 +266,7 @@ namespace { //! Helper function for determining required topology information. -PositionCalculationCollection::RequiredTopologyInfo -requiredTopologyInfo(e_poscalc_t type, int flags) +PositionCalculationCollection::RequiredTopologyInfo requiredTopologyInfo(e_poscalc_t type, int flags) { if (type != POS_ATOM) { @@ -291,38 +282,36 @@ requiredTopologyInfo(e_poscalc_t type, int flags) return PositionCalculationCollection::RequiredTopologyInfo::None; } -} // namespace +} // namespace // static -void -PositionCalculationCollection::typeFromEnum(const char *post, - e_poscalc_t *type, int *flags) +void PositionCalculationCollection::typeFromEnum(const char* post, e_poscalc_t* type, int* flags) { if (post[0] == 'a') { - *type = POS_ATOM; + *type = POS_ATOM; *flags &= ~(POS_MASS | POS_COMPLMAX | POS_COMPLWHOLE); return; } /* Process the prefix */ - const char *ptr = post; + const char* ptr = post; if (post[0] == 'w') { *flags &= ~POS_COMPLMAX; *flags |= POS_COMPLWHOLE; - ptr = post + 6; + ptr = post + 6; } else if (post[0] == 'p') { *flags &= ~POS_COMPLWHOLE; *flags |= POS_COMPLMAX; - ptr = post + 5; + ptr = post + 5; } else if (post[0] == 'd') { *flags &= ~(POS_COMPLMAX | POS_COMPLWHOLE); - ptr = post + 4; + ptr = post + 4; } if (ptr[0] == 'r') @@ -357,11 +346,10 @@ PositionCalculationCollection::typeFromEnum(const char *post, // static PositionCalculationCollection::RequiredTopologyInfo -PositionCalculationCollection::requiredTopologyInfoForType(const char *post, - bool forces) +PositionCalculationCollection::requiredTopologyInfoForType(const char* post, bool forces) { - e_poscalc_t type; - int flags = (forces ? POS_FORCES : 0); + e_poscalc_t type; + int flags = (forces ? POS_FORCES : 0); PositionCalculationCollection::typeFromEnum(post, &type, &flags); return requiredTopologyInfo(type, flags); } @@ -370,8 +358,11 @@ PositionCalculationCollection::requiredTopologyInfoForType(const char *post, * PositionCalculationCollection::Impl */ -PositionCalculationCollection::Impl::Impl() - : top_(nullptr), first_(nullptr), last_(nullptr), bInit_(false) +PositionCalculationCollection::Impl::Impl() : + top_(nullptr), + first_(nullptr), + last_(nullptr), + bInit_(false) { } @@ -381,15 +372,12 @@ PositionCalculationCollection::Impl::~Impl() // correctly handled by this direction. while (last_ != nullptr) { - GMX_ASSERT(last_->refcount == 1, - "Dangling references to position calculations"); + GMX_ASSERT(last_->refcount == 1, "Dangling references to position calculations"); gmx_ana_poscalc_free(last_); } } -void -PositionCalculationCollection::Impl::insertCalculation(gmx_ana_poscalc_t *pc, - gmx_ana_poscalc_t *before) +void PositionCalculationCollection::Impl::insertCalculation(gmx_ana_poscalc_t* pc, gmx_ana_poscalc_t* before) { GMX_RELEASE_ASSERT(pc->coll == this, "Inconsistent collections"); if (before == nullptr) @@ -404,8 +392,8 @@ PositionCalculationCollection::Impl::insertCalculation(gmx_ana_poscalc_t *pc, } else { - pc->prev = before->prev; - pc->next = before; + pc->prev = before->prev; + pc->next = before; if (before->prev) { before->prev->next = pc; @@ -418,8 +406,7 @@ PositionCalculationCollection::Impl::insertCalculation(gmx_ana_poscalc_t *pc, } } -void -PositionCalculationCollection::Impl::removeCalculation(gmx_ana_poscalc_t *pc) +void PositionCalculationCollection::Impl::removeCalculation(gmx_ana_poscalc_t* pc) { GMX_RELEASE_ASSERT(pc->coll == this, "Inconsistent collections"); if (pc->prev != nullptr) @@ -441,14 +428,13 @@ PositionCalculationCollection::Impl::removeCalculation(gmx_ana_poscalc_t *pc) pc->prev = pc->next = nullptr; } -gmx_ana_poscalc_t * -PositionCalculationCollection::Impl::createCalculation(e_poscalc_t type, int flags) +gmx_ana_poscalc_t* PositionCalculationCollection::Impl::createCalculation(e_poscalc_t type, int flags) { - gmx_ana_poscalc_t *pc; + gmx_ana_poscalc_t* pc; snew(pc, 1); - pc->type = type; - pc->itype = index_type_for_poscalc(type); + pc->type = type; + pc->itype = index_type_for_poscalc(type); gmx_ana_poscalc_set_flags(pc, flags); pc->refcount = 1; pc->coll = this; @@ -461,25 +447,18 @@ PositionCalculationCollection::Impl::createCalculation(e_poscalc_t type, int fla * PositionCalculationCollection */ -PositionCalculationCollection::PositionCalculationCollection() - : impl_(new Impl) -{ -} +PositionCalculationCollection::PositionCalculationCollection() : impl_(new Impl) {} -PositionCalculationCollection::~PositionCalculationCollection() -{ -} +PositionCalculationCollection::~PositionCalculationCollection() {} -void -PositionCalculationCollection::setTopology(const gmx_mtop_t *top) +void PositionCalculationCollection::setTopology(const gmx_mtop_t* top) { impl_->top_ = top; } -void -PositionCalculationCollection::printTree(FILE *fp) const +void PositionCalculationCollection::printTree(FILE* fp) const { - gmx_ana_poscalc_t *pc; + gmx_ana_poscalc_t* pc; int i, j; fprintf(fp, "Position calculations:\n"); @@ -490,10 +469,10 @@ PositionCalculationCollection::printTree(FILE *fp) const fprintf(fp, "%2d ", i); switch (pc->type) { - case POS_ATOM: fprintf(fp, "ATOM"); break; - case POS_RES: fprintf(fp, "RES"); break; - case POS_MOL: fprintf(fp, "MOL"); break; - case POS_ALL: fprintf(fp, "ALL"); break; + case POS_ATOM: fprintf(fp, "ATOM"); break; + case POS_RES: fprintf(fp, "RES"); break; + case POS_MOL: fprintf(fp, "MOL"); break; + case POS_ALL: fprintf(fp, "ALL"); break; case POS_ALL_PBC: fprintf(fp, "ALL_PBC"); break; } if (pc->itype != index_type_for_poscalc(pc->type)) @@ -501,11 +480,11 @@ PositionCalculationCollection::printTree(FILE *fp) const fprintf(fp, " ("); switch (pc->itype) { - case INDEX_UNKNOWN: fprintf(fp, "???"); break; - case INDEX_ATOM: fprintf(fp, "ATOM"); break; - case INDEX_RES: fprintf(fp, "RES"); break; - case INDEX_MOL: fprintf(fp, "MOL"); break; - case INDEX_ALL: fprintf(fp, "ALL"); break; + case INDEX_UNKNOWN: fprintf(fp, "???"); break; + case INDEX_ATOM: fprintf(fp, "ATOM"); break; + case INDEX_RES: fprintf(fp, "RES"); break; + case INDEX_MOL: fprintf(fp, "MOL"); break; + case INDEX_ALL: fprintf(fp, "ALL"); break; } fprintf(fp, ")"); } @@ -587,7 +566,7 @@ PositionCalculationCollection::printTree(FILE *fp) const } if (pc->sbase) { - gmx_ana_poscalc_t *base; + gmx_ana_poscalc_t* base; fprintf(fp, " Base: "); j = 1; @@ -603,7 +582,7 @@ PositionCalculationCollection::printTree(FILE *fp) const fprintf(fp, " id:"); for (j = 0; j < pc->b.nr; ++j) { - fprintf(fp, " %d", pc->baseid[j]+1); + fprintf(fp, " %d", pc->baseid[j] + 1); } } fprintf(fp, "\n"); @@ -613,24 +592,22 @@ PositionCalculationCollection::printTree(FILE *fp) const } } -gmx_ana_poscalc_t * -PositionCalculationCollection::createCalculation(e_poscalc_t type, int flags) +gmx_ana_poscalc_t* PositionCalculationCollection::createCalculation(e_poscalc_t type, int flags) { return impl_->createCalculation(type, flags); } -gmx_ana_poscalc_t * -PositionCalculationCollection::createCalculationFromEnum(const char *post, int flags) +gmx_ana_poscalc_t* PositionCalculationCollection::createCalculationFromEnum(const char* post, int flags) { - e_poscalc_t type; - int cflags = flags; + e_poscalc_t type; + int cflags = flags; typeFromEnum(post, &type, &cflags); return impl_->createCalculation(type, cflags); } -void PositionCalculationCollection::getRequiredAtoms(gmx_ana_index_t *out) const +void PositionCalculationCollection::getRequiredAtoms(gmx_ana_index_t* out) const { - gmx_ana_poscalc_t *pc = impl_->first_; + gmx_ana_poscalc_t* pc = impl_->first_; while (pc) { // Calculations with a base just copy positions from the base, so @@ -651,7 +628,7 @@ void PositionCalculationCollection::initEvaluation() { return; } - gmx_ana_poscalc_t *pc = impl_->first_; + gmx_ana_poscalc_t* pc = impl_->first_; while (pc) { /* Initialize position storage for base calculations */ @@ -662,7 +639,7 @@ void PositionCalculationCollection::initEvaluation() /* Construct the mapping of the base positions */ if (pc->sbase) { - int bi, bj; + int bi, bj; snew(pc->baseid, pc->b.nr); for (bi = bj = 0; bi < pc->b.nr; ++bi, ++bj) @@ -693,14 +670,14 @@ void PositionCalculationCollection::initEvaluation() impl_->bInit_ = true; } -void PositionCalculationCollection::initFrame(const t_trxframe *fr) +void PositionCalculationCollection::initFrame(const t_trxframe* fr) { if (!impl_->bInit_) { initEvaluation(); } /* Clear the evaluation flags */ - gmx_ana_poscalc_t *pc = impl_->first_; + gmx_ana_poscalc_t* pc = impl_->first_; while (pc) { pc->bEval = false; @@ -733,21 +710,19 @@ void PositionCalculationCollection::initFrame(const t_trxframe *fr) * * \p bBase affects on how the \p pc->gmax field is initialized. */ -static void -set_poscalc_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g, bool bBase) +static void set_poscalc_maxindex(gmx_ana_poscalc_t* pc, gmx_ana_index_t* g, bool bBase) { - const gmx_mtop_t *top = pc->coll->top_; + const gmx_mtop_t* top = pc->coll->top_; gmx_ana_index_make_block(&pc->b, top, g, pc->itype, (pc->flags & POS_COMPLWHOLE) != 0); /* Set the type to POS_ATOM if the calculation in fact is such. */ if (pc->b.nr == pc->b.nra) { - pc->type = POS_ATOM; + pc->type = POS_ATOM; pc->flags &= ~(POS_MASS | POS_COMPLMAX | POS_COMPLWHOLE); } /* Set the POS_COMPLWHOLE flag if the calculation in fact always uses * complete residues and molecules. */ - if (!(pc->flags & POS_COMPLWHOLE) - && (!(pc->flags & POS_DYNAMIC) || (pc->flags & POS_COMPLMAX)) + if (!(pc->flags & POS_COMPLWHOLE) && (!(pc->flags & POS_DYNAMIC) || (pc->flags & POS_COMPLMAX)) && (pc->type == POS_RES || pc->type == POS_MOL) && gmx_ana_index_has_complete_elems(g, pc->itype, top)) { @@ -772,8 +747,7 @@ set_poscalc_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g, bool bBase) * \returns true if \p pc can use a base and gets some benefit out of it, * false otherwise. */ -static bool -can_use_base(gmx_ana_poscalc_t *pc) +static bool can_use_base(gmx_ana_poscalc_t* pc) { /* For atoms, it should be faster to do a simple copy, so don't use a * base. */ @@ -783,14 +757,13 @@ can_use_base(gmx_ana_poscalc_t *pc) } /* For dynamic selections that do not use completion, it is not possible * to use a base. */ - if ((pc->type == POS_RES || pc->type == POS_MOL) - && (pc->flags & POS_DYNAMIC) && !(pc->flags & (POS_COMPLMAX | POS_COMPLWHOLE))) + if ((pc->type == POS_RES || pc->type == POS_MOL) && (pc->flags & POS_DYNAMIC) + && !(pc->flags & (POS_COMPLMAX | POS_COMPLWHOLE))) { return false; } /* Dynamic calculations for a single position cannot use a base. */ - if ((pc->type == POS_ALL || pc->type == POS_ALL_PBC) - && (pc->flags & POS_DYNAMIC)) + if ((pc->type == POS_ALL || pc->type == POS_ALL_PBC) && (pc->flags & POS_DYNAMIC)) { return false; } @@ -809,11 +782,9 @@ can_use_base(gmx_ana_poscalc_t *pc) * \returns true if the two calculations should be merged to use a common * base, false otherwise. */ -static bool -should_merge(gmx_ana_poscalc_t *pc1, gmx_ana_poscalc_t *pc2, - gmx_ana_index_t *g1, gmx_ana_index_t *g) +static bool should_merge(gmx_ana_poscalc_t* pc1, gmx_ana_poscalc_t* pc2, gmx_ana_index_t* g1, gmx_ana_index_t* g) { - gmx_ana_index_t g2; + gmx_ana_index_t g2; /* Do not merge calculations with different mass weighting. */ if ((pc1->flags & POS_MASS) != (pc2->flags & POS_MASS)) @@ -834,15 +805,13 @@ should_merge(gmx_ana_poscalc_t *pc1, gmx_ana_poscalc_t *pc2, return false; } /* Full completion calculations always match if the type is correct. */ - if ((pc1->flags & POS_COMPLWHOLE) && (pc2->flags & POS_COMPLWHOLE) - && pc1->type == pc2->type) + if ((pc1->flags & POS_COMPLWHOLE) && (pc2->flags & POS_COMPLWHOLE) && pc1->type == pc2->type) { return true; } /* The calculations also match if the intersection consists of full * blocks. */ - if (gmx_ana_index_has_full_ablocks(g, &pc1->b) - && gmx_ana_index_has_full_ablocks(g, &pc2->b)) + if (gmx_ana_index_has_full_ablocks(g, &pc1->b) && gmx_ana_index_has_full_ablocks(g, &pc2->b)) { return true; } @@ -860,10 +829,9 @@ should_merge(gmx_ana_poscalc_t *pc1, gmx_ana_poscalc_t *pc2, * The newly created structure is set as the base (\c gmx_ana_poscalc_t::sbase) * of \p pc and inserted in the collection before \p pc. */ -static gmx_ana_poscalc_t * -create_simple_base(gmx_ana_poscalc_t *pc) +static gmx_ana_poscalc_t* create_simple_base(gmx_ana_poscalc_t* pc) { - gmx_ana_poscalc_t *base; + gmx_ana_poscalc_t* base; int flags; flags = pc->flags & ~(POS_DYNAMIC | POS_MASKONLY); @@ -891,12 +859,11 @@ create_simple_base(gmx_ana_poscalc_t *pc) * It is assumed that any overlap between \p base and \p pc is in complete * blocks, i.e., that the merge is possible. */ -static void -merge_to_base(gmx_ana_poscalc_t *base, gmx_ana_poscalc_t *pc) +static void merge_to_base(gmx_ana_poscalc_t* base, gmx_ana_poscalc_t* pc) { - gmx_ana_index_t gp, gb, g; - int isize, bnr; - int i, bi, bj, bo; + gmx_ana_index_t gp, gb, g; + int isize, bnr; + int i, bi, bj, bo; base->flags |= pc->flags & (POS_VELOCITIES | POS_FORCES); gmx_ana_index_set(&gp, pc->b.nra, pc->b.a, 0); @@ -916,7 +883,7 @@ merge_to_base(gmx_ana_poscalc_t *base, gmx_ana_poscalc_t *pc) { ++bi; } - i += pc->b.index[bi+1] - pc->b.index[bi]; + i += pc->b.index[bi + 1] - pc->b.index[bi]; ++bnr; ++bi; } @@ -924,31 +891,31 @@ merge_to_base(gmx_ana_poscalc_t *base, gmx_ana_poscalc_t *pc) gmx_ana_index_merge(&g, &gb, &g); /* Merge the blocks */ srenew(base->b.index, base->b.nr + bnr + 1); - i = g.isize - 1; - bi = base->b.nr - 1; - bj = pc->b.nr - 1; - bo = base->b.nr + bnr - 1; - base->b.index[bo+1] = i + 1; + i = g.isize - 1; + bi = base->b.nr - 1; + bj = pc->b.nr - 1; + bo = base->b.nr + bnr - 1; + base->b.index[bo + 1] = i + 1; while (bo >= 0) { - if (bi < 0 || base->b.a[base->b.index[bi+1]-1] != g.index[i]) + if (bi < 0 || base->b.a[base->b.index[bi + 1] - 1] != g.index[i]) { - i -= pc->b.index[bj+1] - pc->b.index[bj]; + i -= pc->b.index[bj + 1] - pc->b.index[bj]; --bj; } else { - if (bj >= 0 && pc->b.a[pc->b.index[bj+1]-1] == g.index[i]) + if (bj >= 0 && pc->b.a[pc->b.index[bj + 1] - 1] == g.index[i]) { --bj; } - i -= base->b.index[bi+1] - base->b.index[bi]; + i -= base->b.index[bi + 1] - base->b.index[bi]; --bi; } base->b.index[bo] = i + 1; --bo; } - base->b.nr += bnr; + base->b.nr += bnr; base->b.nalloc_index += bnr; sfree(base->b.a); base->b.nra = g.isize; @@ -970,10 +937,9 @@ merge_to_base(gmx_ana_poscalc_t *base, gmx_ana_poscalc_t *pc) * It is assumed that any overlap between \p tbase and \p mbase is in complete * blocks, i.e., that the merge is possible. */ -static void -merge_bases(gmx_ana_poscalc_t *tbase, gmx_ana_poscalc_t *mbase) +static void merge_bases(gmx_ana_poscalc_t* tbase, gmx_ana_poscalc_t* mbase) { - gmx_ana_poscalc_t *pc; + gmx_ana_poscalc_t* pc; merge_to_base(tbase, mbase); mbase->coll->removeCalculation(mbase); @@ -998,8 +964,7 @@ merge_bases(gmx_ana_poscalc_t *tbase, gmx_ana_poscalc_t *mbase) * * \param[in,out] pc Position calculation to setup the base for. */ -static void -setup_base(gmx_ana_poscalc_t *pc) +static void setup_base(gmx_ana_poscalc_t* pc) { gmx_ana_poscalc_t *base, *pbase, *next; gmx_ana_index_t gp, g; @@ -1024,8 +989,7 @@ setup_base(gmx_ana_poscalc_t *pc) * If the above conditions are met, check whether we should do a * merge. */ - if (base != pc && !base->sbase && can_use_base(base) - && should_merge(pbase, base, &gp, &g)) + if (base != pc && !base->sbase && can_use_base(base) && should_merge(pbase, base, &gp, &g)) { /* Check whether this is the first base found */ if (pbase == pc) @@ -1071,8 +1035,7 @@ setup_base(gmx_ana_poscalc_t *pc) gmx_ana_index_deinit(&g); /* If no base was found, create one if one is required */ - if (!pc->sbase && (pc->flags & POS_DYNAMIC) - && (pc->flags & (POS_COMPLMAX | POS_COMPLWHOLE))) + if (!pc->sbase && (pc->flags & POS_DYNAMIC) && (pc->flags & (POS_COMPLMAX | POS_COMPLWHOLE))) { create_simple_base(pc); } @@ -1090,8 +1053,7 @@ setup_base(gmx_ana_poscalc_t *pc) * If calculation type is not \ref POS_RES or \ref POS_MOL, * \ref POS_COMPLMAX and \ref POS_COMPLWHOLE are automatically cleared. */ -void -gmx_ana_poscalc_set_flags(gmx_ana_poscalc_t *pc, int flags) +void gmx_ana_poscalc_set_flags(gmx_ana_poscalc_t* pc, int flags) { if (pc->type == POS_ATOM) { @@ -1118,8 +1080,7 @@ gmx_ana_poscalc_set_flags(gmx_ana_poscalc_t *pc, int flags) * The topology should have been set for the collection of which \p pc is * a member. */ -void -gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g) +void gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t* pc, gmx_ana_index_t* g) { set_poscalc_maxindex(pc, g, false); setup_base(pc); @@ -1134,8 +1095,7 @@ gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g) * The \c p->g pointer is initialized to point to an internal group that * contains the maximum index group set with gmx_ana_poscalc_set_maxindex(). */ -void -gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p) +void gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t* pc, gmx_ana_pos_t* p) { gmx_ana_indexmap_init(&p->m, &pc->gmax, pc->coll->top_, pc->itype); /* Only do the static optimization when there is no completion */ @@ -1159,8 +1119,7 @@ gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p) * * The \p pc pointer is invalid after the call. */ -void -gmx_ana_poscalc_free(gmx_ana_poscalc_t *pc) +void gmx_ana_poscalc_free(gmx_ana_poscalc_t* pc) { if (!pc) { @@ -1195,8 +1154,7 @@ gmx_ana_poscalc_free(gmx_ana_poscalc_t *pc) sfree(pc); } -gmx::PositionCalculationCollection::RequiredTopologyInfo -gmx_ana_poscalc_required_topology_info(gmx_ana_poscalc_t *pc) +gmx::PositionCalculationCollection::RequiredTopologyInfo gmx_ana_poscalc_required_topology_info(gmx_ana_poscalc_t* pc) { return gmx::requiredTopologyInfo(pc->type, pc->flags); } @@ -1212,11 +1170,13 @@ gmx_ana_poscalc_required_topology_info(gmx_ana_poscalc_t *pc) * gmx_ana_poscalc_init_frame() should be called for each frame before calling * this function. */ -void -gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, - gmx_ana_index_t *g, t_trxframe *fr, const t_pbc *pbc) +void gmx_ana_poscalc_update(gmx_ana_poscalc_t* pc, + gmx_ana_pos_t* p, + gmx_ana_index_t* g, + t_trxframe* fr, + const t_pbc* pbc) { - int i, bi, bj; + int i, bi, bj; if (pc->bEval && !(pc->flags & POS_MASKONLY)) { @@ -1331,7 +1291,7 @@ gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, } } gmx::ArrayRef index = pc->coll->getFrameIndices(pc->b.nra, pc->b.a); - const gmx_mtop_t *top = pc->coll->top_; + const gmx_mtop_t* top = pc->coll->top_; const bool bMass = (pc->flags & POS_MASS) != 0; switch (pc->type) { @@ -1379,16 +1339,16 @@ gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, break; default: // TODO: It would probably be better to do this without the type casts. - gmx_calc_comg_block(top, fr->x, reinterpret_cast(&pc->b), - index.data(), bMass, p->x); + gmx_calc_comg_block(top, fr->x, reinterpret_cast(&pc->b), index.data(), + bMass, p->x); if (p->v && fr->bV) { - gmx_calc_comg_block(top, fr->v, reinterpret_cast(&pc->b), + gmx_calc_comg_block(top, fr->v, reinterpret_cast(&pc->b), index.data(), bMass, p->v); } if (p->f && fr->bF) { - gmx_calc_comg_f_block(top, fr->f, reinterpret_cast(&pc->b), + gmx_calc_comg_f_block(top, fr->f, reinterpret_cast(&pc->b), index.data(), bMass, p->f); } break; diff --git a/src/gromacs/selection/poscalc.h b/src/gromacs/selection/poscalc.h index e37628dea0..224a4be226 100644 --- a/src/gromacs/selection/poscalc.h +++ b/src/gromacs/selection/poscalc.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2009-2016, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,7 +69,7 @@ * Without the flag, center-of-geometry positions are calculated. * Does not have any effect if the calculation type is \ref POS_ATOM. */ -#define POS_MASS 1 +#define POS_MASS 1 /*! \brief * Calculate positions for the same atoms in residues/molecules. * @@ -81,7 +82,7 @@ * Has no effect unless \ref POS_DYNAMIC is set or if the calculation type * is not \ref POS_RES of \ref POS_MOL. */ -#define POS_COMPLMAX 2 +#define POS_COMPLMAX 2 /*! \brief * Calculate positions for whole residues/molecules. * @@ -91,39 +92,39 @@ * * Has no effect unless the calculation type is \ref POS_RES or \ref POS_MOL. */ -#define POS_COMPLWHOLE 4 +#define POS_COMPLWHOLE 4 /*! \brief * Enable handling of changing calculation groups. * * Can be used for static calculations as well, but implies a small * performance penalty. */ -#define POS_DYNAMIC 16 +#define POS_DYNAMIC 16 /*! \brief * Update \c gmx_ana_pos_t::m dynamically for an otherwise static * calculation. * * Has effect only if \ref POS_DYNAMIC is not set. */ -#define POS_MASKONLY 32 +#define POS_MASKONLY 32 /*! \brief * Calculate velocities of the positions. */ -#define POS_VELOCITIES 64 +#define POS_VELOCITIES 64 /*! \brief * Calculate forces on the positions. */ -#define POS_FORCES 128 +#define POS_FORCES 128 /*@}*/ /** Specifies the type of positions to be calculated. */ typedef enum { - POS_ATOM, /**< Copy atomic coordinates. */ - POS_RES, /**< Calculate center for each residue. */ - POS_MOL, /**< Calculate center for each molecule. */ - POS_ALL, /**< Calculate center for the whole group. */ - POS_ALL_PBC /**< Calculate center for the whole group with PBC. */ + POS_ATOM, /**< Copy atomic coordinates. */ + POS_RES, /**< Calculate center for each residue. */ + POS_MOL, /**< Calculate center for each molecule. */ + POS_ALL, /**< Calculate center for the whole group. */ + POS_ALL_PBC /**< Calculate center for the whole group with PBC. */ } e_poscalc_t; /** Data structure for position calculation. */ @@ -177,190 +178,186 @@ namespace gmx */ class PositionCalculationCollection { - public: - //! Describes what topology information is needed for position calculation. - enum class RequiredTopologyInfo - { - None, //!< No topology is needed. - Topology, //!< Topology is needed (residue/molecule info). - TopologyAndMasses //!< Masses are needed. - }; +public: + //! Describes what topology information is needed for position calculation. + enum class RequiredTopologyInfo + { + None, //!< No topology is needed. + Topology, //!< Topology is needed (residue/molecule info). + TopologyAndMasses //!< Masses are needed. + }; - /*! \brief - * Array of strings acceptable for position calculation type enum. - * - * This array contains the acceptable values for typeFromEnum() and - * createCalculationFromEnum(). - * The array contains a NULL pointer after the last item to indicate - * the end of the list. - */ - static const char * const typeEnumValues[]; + /*! \brief + * Array of strings acceptable for position calculation type enum. + * + * This array contains the acceptable values for typeFromEnum() and + * createCalculationFromEnum(). + * The array contains a NULL pointer after the last item to indicate + * the end of the list. + */ + static const char* const typeEnumValues[]; - /*! \brief - * Converts a string to parameters for createCalculationFromEnum(). - * - * \param[in] post String (typically an enum argument). - * Allowed values: 'atom', 'res_com', 'res_cog', 'mol_com', 'mol_cog', - * or one of the last four prepended by 'whole_', 'part_', or 'dyn_'. - * \param[out] type \c e_poscalc_t corresponding to \p post. - * \param[in,out] flags Flags corresponding to \p post. - * On input, the flags should contain the default flags. - * On exit, the flags \ref POS_MASS, \ref POS_COMPLMAX and - * \ref POS_COMPLWHOLE have been set according to \p post - * (the completion flags are left at the default values if no - * completion prefix is given). - * \throws InternalError if post is not recognized. - * - * \attention - * Checking is not complete, and other values than those listed above - * may be accepted for \p post, but the results are undefined. - * - * \see typeEnumValues - */ - static void typeFromEnum(const char *post, e_poscalc_t *type, int *flags); - /*! \brief - * Returns what information is needed for position evaluation. - * - * \param[in] post Position type (see typeFromEnum()). - * \param[in] forces Whether forces are needed. - * \returns What topology information is required for initializing - * and/or evaluating the positions. - */ - static RequiredTopologyInfo requiredTopologyInfoForType(const char *post, bool forces); + /*! \brief + * Converts a string to parameters for createCalculationFromEnum(). + * + * \param[in] post String (typically an enum argument). + * Allowed values: 'atom', 'res_com', 'res_cog', 'mol_com', 'mol_cog', + * or one of the last four prepended by 'whole_', 'part_', or 'dyn_'. + * \param[out] type \c e_poscalc_t corresponding to \p post. + * \param[in,out] flags Flags corresponding to \p post. + * On input, the flags should contain the default flags. + * On exit, the flags \ref POS_MASS, \ref POS_COMPLMAX and + * \ref POS_COMPLWHOLE have been set according to \p post + * (the completion flags are left at the default values if no + * completion prefix is given). + * \throws InternalError if post is not recognized. + * + * \attention + * Checking is not complete, and other values than those listed above + * may be accepted for \p post, but the results are undefined. + * + * \see typeEnumValues + */ + static void typeFromEnum(const char* post, e_poscalc_t* type, int* flags); + /*! \brief + * Returns what information is needed for position evaluation. + * + * \param[in] post Position type (see typeFromEnum()). + * \param[in] forces Whether forces are needed. + * \returns What topology information is required for initializing + * and/or evaluating the positions. + */ + static RequiredTopologyInfo requiredTopologyInfoForType(const char* post, bool forces); - /*! \brief - * Creates a new position calculation collection object. - * - * \throws std::bad_alloc if out of memory. - */ - PositionCalculationCollection(); - /*! \brief - * Destroys a position calculation collection and its calculations. - * - * Any calculations in the collection are also freed, even if - * references to them are left. - */ - ~PositionCalculationCollection(); + /*! \brief + * Creates a new position calculation collection object. + * + * \throws std::bad_alloc if out of memory. + */ + PositionCalculationCollection(); + /*! \brief + * Destroys a position calculation collection and its calculations. + * + * Any calculations in the collection are also freed, even if + * references to them are left. + */ + ~PositionCalculationCollection(); - /*! \brief - * Sets the topology used for the calculations. - * - * \param[in] top Topology data structure. - * - * This function should be called to set the topology before using - * gmx_ana_poscalc_set_maxindex() for any calculation that requires - * topology information. - * - * Does not throw. - */ - void setTopology(const gmx_mtop_t *top); - /*! \brief - * Prints information about calculations. - * - * \param[in] fp File handle to receive the output. - * - * The output is very technical, making this function mainly useful for - * debugging purposes. - * - * Does not throw. - */ - void printTree(FILE *fp) const; + /*! \brief + * Sets the topology used for the calculations. + * + * \param[in] top Topology data structure. + * + * This function should be called to set the topology before using + * gmx_ana_poscalc_set_maxindex() for any calculation that requires + * topology information. + * + * Does not throw. + */ + void setTopology(const gmx_mtop_t* top); + /*! \brief + * Prints information about calculations. + * + * \param[in] fp File handle to receive the output. + * + * The output is very technical, making this function mainly useful for + * debugging purposes. + * + * Does not throw. + */ + void printTree(FILE* fp) const; - /*! \brief - * Creates a new position calculation. - * - * \param[in] type Type of calculation. - * \param[in] flags Flags for setting calculation options - * (see \ref poscalc_flags "documentation of the flags"). - * - * Does not throw currently, but may throw std::bad_alloc in the - * future. - */ - gmx_ana_poscalc_t *createCalculation(e_poscalc_t type, int flags); - /*! \brief - * Creates a new position calculation based on an enum value. - * - * \param[in] post One of the strings acceptable for - * typeFromEnum(). - * \param[in] flags Flags for setting calculation options - * (see \ref poscalc_flags "documentation of the flags"). - * \throws InternalError if post is not recognized. - * - * This is a convenience wrapper for createCalculation(). - * \p flags sets the default calculation options if not overridden by - * \p post; see typeFromEnum(). - * - * May also throw std::bad_alloc in the future. - * - * \see createCalculation(), typeFromEnum() - */ - gmx_ana_poscalc_t *createCalculationFromEnum(const char *post, int flags); + /*! \brief + * Creates a new position calculation. + * + * \param[in] type Type of calculation. + * \param[in] flags Flags for setting calculation options + * (see \ref poscalc_flags "documentation of the flags"). + * + * Does not throw currently, but may throw std::bad_alloc in the + * future. + */ + gmx_ana_poscalc_t* createCalculation(e_poscalc_t type, int flags); + /*! \brief + * Creates a new position calculation based on an enum value. + * + * \param[in] post One of the strings acceptable for + * typeFromEnum(). + * \param[in] flags Flags for setting calculation options + * (see \ref poscalc_flags "documentation of the flags"). + * \throws InternalError if post is not recognized. + * + * This is a convenience wrapper for createCalculation(). + * \p flags sets the default calculation options if not overridden by + * \p post; see typeFromEnum(). + * + * May also throw std::bad_alloc in the future. + * + * \see createCalculation(), typeFromEnum() + */ + gmx_ana_poscalc_t* createCalculationFromEnum(const char* post, int flags); - /*! \brief - * Computes the atoms required to evaluate this collection. - * - * \param[out] out Maximal group of atoms required to evaluate the - * positions. - * - * Does not throw. - */ - void getRequiredAtoms(gmx_ana_index_t *out) const; + /*! \brief + * Computes the atoms required to evaluate this collection. + * + * \param[out] out Maximal group of atoms required to evaluate the + * positions. + * + * Does not throw. + */ + void getRequiredAtoms(gmx_ana_index_t* out) const; - /*! \brief - * Initializes evaluation for a position calculation collection. - * - * This function does some final initialization of the data structures - * in the collection to prepare them for evaluation. - * After this function has been called, it is no longer possible to add - * new calculations to the collection. - * - * Multiple calls to the function are ignored. - * - * Does not throw currently, but may throw std::bad_alloc in the - * future. - */ - void initEvaluation(); - /*! \brief - * Initializes a position calculation collection for a new frame. - * - * \param[in] fr Frame to initialize evaluation for. - * - * Should be called for each frame before calling - * gmx_ana_poscalc_update(). - * - * This function calls initEvaluation() automatically if it has not - * been called earlier. - * - * Does not currently throw, but may throw std::bad_alloc in the - * future. - */ - void initFrame(const t_trxframe *fr); + /*! \brief + * Initializes evaluation for a position calculation collection. + * + * This function does some final initialization of the data structures + * in the collection to prepare them for evaluation. + * After this function has been called, it is no longer possible to add + * new calculations to the collection. + * + * Multiple calls to the function are ignored. + * + * Does not throw currently, but may throw std::bad_alloc in the + * future. + */ + void initEvaluation(); + /*! \brief + * Initializes a position calculation collection for a new frame. + * + * \param[in] fr Frame to initialize evaluation for. + * + * Should be called for each frame before calling + * gmx_ana_poscalc_update(). + * + * This function calls initEvaluation() automatically if it has not + * been called earlier. + * + * Does not currently throw, but may throw std::bad_alloc in the + * future. + */ + void initFrame(const t_trxframe* fr); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed to access the implementation class from the C code. - */ - friend struct ::gmx_ana_poscalc_t; + /*! \brief + * Needed to access the implementation class from the C code. + */ + friend struct ::gmx_ana_poscalc_t; }; } // namespace gmx /** Sets the flags for position calculation. */ -void -gmx_ana_poscalc_set_flags(gmx_ana_poscalc_t *pc, int flags); +void gmx_ana_poscalc_set_flags(gmx_ana_poscalc_t* pc, int flags); /** Sets the maximum possible input index group for position calculation. */ -void -gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t *pc, gmx_ana_index_t *g); +void gmx_ana_poscalc_set_maxindex(gmx_ana_poscalc_t* pc, gmx_ana_index_t* g); /** Initializes positions for position calculation output. */ -void -gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p); +void gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t* pc, gmx_ana_pos_t* p); /** Frees the memory allocated for position calculation. */ -void -gmx_ana_poscalc_free(gmx_ana_poscalc_t *pc); +void gmx_ana_poscalc_free(gmx_ana_poscalc_t* pc); /*! \brief * Returns true if the position calculation requires topology information. * @@ -369,12 +366,13 @@ gmx_ana_poscalc_free(gmx_ana_poscalc_t *pc); * and/or evaluation. */ gmx::PositionCalculationCollection::RequiredTopologyInfo -gmx_ana_poscalc_required_topology_info(gmx_ana_poscalc_t *pc); +gmx_ana_poscalc_required_topology_info(gmx_ana_poscalc_t* pc); /** Updates a single COM/COG structure for a frame. */ -void -gmx_ana_poscalc_update(gmx_ana_poscalc_t *pc, - gmx_ana_pos_t *p, gmx_ana_index_t *g, - t_trxframe *fr, const t_pbc *pbc); +void gmx_ana_poscalc_update(gmx_ana_poscalc_t* pc, + gmx_ana_pos_t* p, + gmx_ana_index_t* g, + t_trxframe* fr, + const t_pbc* pbc); #endif diff --git a/src/gromacs/selection/position.cpp b/src/gromacs/selection/position.cpp index 196c982e5c..39f601f94a 100644 --- a/src/gromacs/selection/position.cpp +++ b/src/gromacs/selection/position.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,8 +76,7 @@ gmx_ana_pos_t::~gmx_ana_pos_t() * Ensures that enough memory is allocated in \p pos to calculate \p n * positions from \p isize atoms. */ -void -gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize) +void gmx_ana_pos_reserve(gmx_ana_pos_t* pos, int n, int isize) { GMX_RELEASE_ASSERT(n >= 0, "Invalid position allocation count"); // Always reserve at least one entry to make NULL checks against pos->x @@ -111,11 +111,9 @@ gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize) * Currently, this function can only be called after gmx_ana_pos_reserve() * has been called at least once with a \p n >= 0. */ -void -gmx_ana_pos_reserve_velocities(gmx_ana_pos_t *pos) +void gmx_ana_pos_reserve_velocities(gmx_ana_pos_t* pos) { - GMX_RELEASE_ASSERT(pos->nalloc_x > 0, - "No memory reserved yet for positions"); + GMX_RELEASE_ASSERT(pos->nalloc_x > 0, "No memory reserved yet for positions"); if (!pos->v) { snew(pos->v, pos->nalloc_x); @@ -128,11 +126,9 @@ gmx_ana_pos_reserve_velocities(gmx_ana_pos_t *pos) * Currently, this function can only be called after gmx_ana_pos_reserve() * has been called at least once with a \p n >= 0. */ -void -gmx_ana_pos_reserve_forces(gmx_ana_pos_t *pos) +void gmx_ana_pos_reserve_forces(gmx_ana_pos_t* pos) { - GMX_RELEASE_ASSERT(pos->nalloc_x > 0, - "No memory reserved yet for positions"); + GMX_RELEASE_ASSERT(pos->nalloc_x > 0, "No memory reserved yet for positions"); if (!pos->f) { snew(pos->f, pos->nalloc_x); @@ -152,9 +148,7 @@ gmx_ana_pos_reserve_forces(gmx_ana_pos_t *pos) * This method needs to be called instead of gmx_ana_pos_reserve() if the * intent is to use gmx_ana_pos_append_init()/gmx_ana_pos_append(). */ -void -gmx_ana_pos_reserve_for_append(gmx_ana_pos_t *pos, int n, int isize, - bool bVelocities, bool bForces) +void gmx_ana_pos_reserve_for_append(gmx_ana_pos_t* pos, int n, int isize, bool bVelocities, bool bForces) { gmx_ana_pos_reserve(pos, n, isize); snew(pos->m.mapb.a, isize); @@ -173,8 +167,7 @@ gmx_ana_pos_reserve_for_append(gmx_ana_pos_t *pos, int n, int isize, * \param[out] pos Position data structure to initialize. * \param[in] x Position vector to use. */ -void -gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x) +void gmx_ana_pos_init_const(gmx_ana_pos_t* pos, const rvec x) { snew(pos->x, 1); snew(pos->v, 1); @@ -195,8 +188,7 @@ gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x) * * \p dest should have been initialized somehow (calloc() is enough). */ -void -gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst) +void gmx_ana_pos_copy(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, bool bFirst) { if (bFirst) { @@ -210,16 +202,16 @@ gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst) gmx_ana_pos_reserve_forces(dest); } } - memcpy(dest->x, src->x, src->count()*sizeof(*dest->x)); + memcpy(dest->x, src->x, src->count() * sizeof(*dest->x)); if (dest->v) { GMX_ASSERT(src->v, "src velocities should be non-null if dest velocities are allocated"); - memcpy(dest->v, src->v, src->count()*sizeof(*dest->v)); + memcpy(dest->v, src->v, src->count() * sizeof(*dest->v)); } if (dest->f) { GMX_ASSERT(src->f, "src forces should be non-null if dest forces are allocated"); - memcpy(dest->f, src->f, src->count()*sizeof(*dest->f)); + memcpy(dest->f, src->f, src->count() * sizeof(*dest->f)); } gmx_ana_indexmap_copy(&dest->m, &src->m, bFirst); } @@ -228,8 +220,7 @@ gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst) * \param[in,out] pos Position data structure. * \param[in] nr Number of positions. */ -void -gmx_ana_pos_set_nr(gmx_ana_pos_t *pos, int nr) +void gmx_ana_pos_set_nr(gmx_ana_pos_t* pos, int nr) { // TODO: This puts the mapping in a somewhat inconsistent state. pos->m.mapb.nr = nr; @@ -240,8 +231,7 @@ gmx_ana_pos_set_nr(gmx_ana_pos_t *pos, int nr) * * Sets the number of positions to 0. */ -void -gmx_ana_pos_empty_init(gmx_ana_pos_t *pos) +void gmx_ana_pos_empty_init(gmx_ana_pos_t* pos) { pos->m.mapb.nr = 0; pos->m.mapb.nra = 0; @@ -253,7 +243,7 @@ gmx_ana_pos_empty_init(gmx_ana_pos_t *pos) pos->m.b.index[0] = 0; /* This function should only be used to construct all the possible * positions, so the result should always be static. */ - pos->m.bStatic = true; + pos->m.bStatic = true; } /*! @@ -261,8 +251,7 @@ gmx_ana_pos_empty_init(gmx_ana_pos_t *pos) * * Sets the number of positions to 0. */ -void -gmx_ana_pos_empty(gmx_ana_pos_t *pos) +void gmx_ana_pos_empty(gmx_ana_pos_t* pos) { pos->m.mapb.nr = 0; pos->m.mapb.nra = 0; @@ -272,7 +261,7 @@ gmx_ana_pos_empty(gmx_ana_pos_t *pos) * should be false. This makes it possible to update the flag in * gmx_ana_pos_append(), and just make a simple check in * gmx_ana_pos_append_finish(). */ - pos->m.bStatic = true; + pos->m.bStatic = true; } /*! @@ -280,10 +269,9 @@ gmx_ana_pos_empty(gmx_ana_pos_t *pos) * \param[in] src Data structure from which the position is copied. * \param[in] i Index in \p from to copy. */ -void -gmx_ana_pos_append_init(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i) +void gmx_ana_pos_append_init(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, int i) { - int j, k; + int j, k; j = dest->count(); copy_rvec(src->x[i], dest->x[j]); @@ -312,13 +300,13 @@ gmx_ana_pos_append_init(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i) dest->m.refid[j] = j; dest->m.mapid[j] = src->m.mapid[i]; dest->m.orgid[j] = src->m.orgid[i]; - for (k = src->m.mapb.index[i]; k < src->m.mapb.index[i+1]; ++k) + for (k = src->m.mapb.index[i]; k < src->m.mapb.index[i + 1]; ++k) { dest->m.mapb.a[dest->m.mapb.nra++] = src->m.mapb.a[k]; dest->m.b.a[dest->m.b.nra++] = src->m.b.a[k]; } - dest->m.mapb.index[j+1] = dest->m.mapb.nra; - dest->m.b.index[j+1] = dest->m.mapb.nra; + dest->m.mapb.index[j + 1] = dest->m.mapb.nra; + dest->m.b.index[j + 1] = dest->m.mapb.nra; dest->m.mapb.nr++; dest->m.b.nr++; } @@ -330,10 +318,9 @@ gmx_ana_pos_append_init(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i) * \param[in] refid Reference ID in \p out * (all negative values are treated as -1). */ -void -gmx_ana_pos_append(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i, int refid) +void gmx_ana_pos_append(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, int i, int refid) { - for (int k = src->m.mapb.index[i]; k < src->m.mapb.index[i+1]; ++k) + for (int k = src->m.mapb.index[i]; k < src->m.mapb.index[i + 1]; ++k) { dest->m.mapb.a[dest->m.mapb.nra++] = src->m.mapb.a[k]; } @@ -379,7 +366,7 @@ gmx_ana_pos_append(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i, int refid) * handle user customization. */ dest->m.mapid[j] = dest->m.orgid[refid]; } - dest->m.mapb.index[j+1] = dest->m.mapb.nra; + dest->m.mapb.index[j + 1] = dest->m.mapb.nra; dest->m.mapb.nr++; } @@ -390,8 +377,7 @@ gmx_ana_pos_append(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i, int refid) * is not consistent before this function is called. This function should be * called after any gmx_ana_pos_append() calls have been made. */ -void -gmx_ana_pos_append_finish(gmx_ana_pos_t *pos) +void gmx_ana_pos_append_finish(gmx_ana_pos_t* pos) { if (pos->m.mapb.nr != pos->m.b.nr) { @@ -404,10 +390,9 @@ gmx_ana_pos_append_finish(gmx_ana_pos_t *pos) * \param[in] src Data structure from which the position is copied. * \param[in] i Index in \p src to copy. */ -void -gmx_ana_pos_add_to_group(gmx_ana_index_t *g, gmx_ana_pos_t *src, int i) +void gmx_ana_pos_add_to_group(gmx_ana_index_t* g, gmx_ana_pos_t* src, int i) { - for (int k = src->m.mapb.index[i]; k < src->m.mapb.index[i+1]; ++k) + for (int k = src->m.mapb.index[i]; k < src->m.mapb.index[i + 1]; ++k) { g->index[g->isize++] = src->m.mapb.a[k]; } diff --git a/src/gromacs/selection/position.h b/src/gromacs/selection/position.h index e8e662d1ec..f95b6766cf 100644 --- a/src/gromacs/selection/position.h +++ b/src/gromacs/selection/position.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,68 +59,55 @@ struct gmx_ana_pos_t /*! \brief * Array of positions. */ - rvec *x; + rvec* x; /*! \brief * Velocities (can be NULL). */ - rvec *v; + rvec* v; /*! \brief * Forces (can be NULL). */ - rvec *f; + rvec* f; /*! \brief * Mapping of the current positions to the original group. * * \see gmx_ana_indexmap_t */ - gmx_ana_indexmap_t m; + gmx_ana_indexmap_t m; /*! \brief * Number of elements allocated for \c x. */ - int nalloc_x; + int nalloc_x; }; /** Ensures that enough memory has been allocated to store positions. */ -void -gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize); +void gmx_ana_pos_reserve(gmx_ana_pos_t* pos, int n, int isize); /** Request memory allocation for velocities. */ -void -gmx_ana_pos_reserve_velocities(gmx_ana_pos_t *pos); +void gmx_ana_pos_reserve_velocities(gmx_ana_pos_t* pos); /** Request memory allocation for forces. */ -void -gmx_ana_pos_reserve_forces(gmx_ana_pos_t *pos); +void gmx_ana_pos_reserve_forces(gmx_ana_pos_t* pos); /** Reserves memory for use with gmx_ana_pos_append_init(). */ -void -gmx_ana_pos_reserve_for_append(gmx_ana_pos_t *pos, int n, int isize, - bool bVelocities, bool bForces); +void gmx_ana_pos_reserve_for_append(gmx_ana_pos_t* pos, int n, int isize, bool bVelocities, bool bForces); /** Initializes a \c gmx_ana_pos_t to represent a constant position. */ -void -gmx_ana_pos_init_const(gmx_ana_pos_t *pos, const rvec x); +void gmx_ana_pos_init_const(gmx_ana_pos_t* pos, const rvec x); /** Copies the evaluated positions to a preallocated data structure. */ -void -gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst); +void gmx_ana_pos_copy(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, bool bFirst); /** Sets the number of positions in a position structure. */ -void -gmx_ana_pos_set_nr(gmx_ana_pos_t *pos, int n); +void gmx_ana_pos_set_nr(gmx_ana_pos_t* pos, int n); /** Empties a position data structure with full initialization. */ -void -gmx_ana_pos_empty_init(gmx_ana_pos_t *pos); +void gmx_ana_pos_empty_init(gmx_ana_pos_t* pos); /** Empties a position data structure. */ -void -gmx_ana_pos_empty(gmx_ana_pos_t *pos); +void gmx_ana_pos_empty(gmx_ana_pos_t* pos); /** Appends a position to a preallocated data structure with full * initialization. */ -void -gmx_ana_pos_append_init(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i); +void gmx_ana_pos_append_init(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, int i); /** Appends a position to a preallocated data structure. */ -void -gmx_ana_pos_append(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, int i, int refid); +void gmx_ana_pos_append(gmx_ana_pos_t* dest, gmx_ana_pos_t* src, int i, int refid); /** Updates position data structure state after appends. */ -void -gmx_ana_pos_append_finish(gmx_ana_pos_t *pos); +void gmx_ana_pos_append_finish(gmx_ana_pos_t* pos); void /** Appends atoms from a position into a preallocated index group. */ -gmx_ana_pos_add_to_group(gmx_ana_index_t *g, gmx_ana_pos_t *src, int i); +gmx_ana_pos_add_to_group(gmx_ana_index_t* g, gmx_ana_pos_t* src, int i); #endif diff --git a/src/gromacs/selection/scanner.h b/src/gromacs/selection/scanner.h index 3b29c0cabe..0220dbd076 100644 --- a/src/gromacs/selection/scanner.h +++ b/src/gromacs/selection/scanner.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,96 +59,77 @@ struct gmx_ana_indexgrps_t; struct gmx_ana_selcollection_t; #ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void *yyscan_t; +# define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; #endif /** Initializes the selection scanner. */ -void -_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc, - gmx::TextWriter *statusWriter, int maxnr, bool bGroups, - struct gmx_ana_indexgrps_t *grps); +void _gmx_sel_init_lexer(yyscan_t* scannerp, + struct gmx_ana_selcollection_t* sc, + gmx::TextWriter* statusWriter, + int maxnr, + bool bGroups, + struct gmx_ana_indexgrps_t* grps); /** Frees memory allocated for the selection scanner. */ -void -_gmx_sel_free_lexer(yyscan_t scanner); +void _gmx_sel_free_lexer(yyscan_t scanner); /** Stores an exception that is caught during parsing. */ -void -_gmx_sel_lexer_set_exception(yyscan_t scanner, - const std::exception_ptr &ex); +void _gmx_sel_lexer_set_exception(yyscan_t scanner, const std::exception_ptr& ex); /** Rethrows and clears the stored exception if one is present. */ // TODO: The semantics is a bit confusing, need to be thought more, // but easier to do as part of larger refactoring of the parsing. -void -_gmx_sel_lexer_rethrow_exception_if_occurred(yyscan_t scanner); +void _gmx_sel_lexer_rethrow_exception_if_occurred(yyscan_t scanner); /** Returns writer for status output (if not NULL, the scanner is interactive). */ -gmx::TextWriter * -_gmx_sel_lexer_get_status_writer(yyscan_t scanner); +gmx::TextWriter* _gmx_sel_lexer_get_status_writer(yyscan_t scanner); /** Returns the selection collection for the scanner. */ -struct gmx_ana_selcollection_t * -_gmx_sel_lexer_selcollection(yyscan_t scanner); +struct gmx_ana_selcollection_t* _gmx_sel_lexer_selcollection(yyscan_t scanner); /** Returns true if the external index groups for the scanner are set. */ -bool -_gmx_sel_lexer_has_groups_set(yyscan_t scanner); +bool _gmx_sel_lexer_has_groups_set(yyscan_t scanner); /** Returns the external index groups for the scanner. */ -struct gmx_ana_indexgrps_t * -_gmx_sel_lexer_indexgrps(yyscan_t scanner); +struct gmx_ana_indexgrps_t* _gmx_sel_lexer_indexgrps(yyscan_t scanner); /** Returns the number of selections after which the parser should stop. */ -int -_gmx_sel_lexer_exp_selcount(yyscan_t scanner); +int _gmx_sel_lexer_exp_selcount(yyscan_t scanner); /** Returns a pretty string of the current selection. */ -const char * -_gmx_sel_lexer_pselstr(yyscan_t scanner); +const char* _gmx_sel_lexer_pselstr(yyscan_t scanner); /*! \brief * Sets the current parser context location. * * This location is set while Bison reductions are being processed, and * identifies the location of the current rule/reduction. */ -void -_gmx_sel_lexer_set_current_location(yyscan_t scanner, - const gmx::SelectionLocation &location); +void _gmx_sel_lexer_set_current_location(yyscan_t scanner, const gmx::SelectionLocation& location); /*! \brief * Returns the current parser context location. * * This returns the location last set with * _gmx_sel_lexer_set_current_location(). */ -const gmx::SelectionLocation & -_gmx_sel_lexer_get_current_location(yyscan_t scanner); +const gmx::SelectionLocation& _gmx_sel_lexer_get_current_location(yyscan_t scanner); /*! \brief * Returns the selection text for the current parser context. * * This returns the selection text that corresponds to the position set last * with _gmx_sel_lexer_set_current_location(). */ -std::string -_gmx_sel_lexer_get_current_text(yyscan_t scanner); +std::string _gmx_sel_lexer_get_current_text(yyscan_t scanner); /*! \brief * Returns the selection text at the given location. */ -std::string -_gmx_sel_lexer_get_text(yyscan_t scanner, - const gmx::SelectionLocation &location); +std::string _gmx_sel_lexer_get_text(yyscan_t scanner, const gmx::SelectionLocation& location); /** Clears the current selection string. */ -void -_gmx_sel_lexer_clear_pselstr(yyscan_t scanner); +void _gmx_sel_lexer_clear_pselstr(yyscan_t scanner); /** Clears the method stack in the scanner in error situations. */ -void -_gmx_sel_lexer_clear_method_stack(yyscan_t scanner); +void _gmx_sel_lexer_clear_method_stack(yyscan_t scanner); /** Notifies the scanner that a complete method expression has been parsed. */ -void -_gmx_sel_finish_method(yyscan_t scanner); +void _gmx_sel_finish_method(yyscan_t scanner); /** Initializes the scanner to scan a file. */ -void -_gmx_sel_set_lex_input_file(yyscan_t scanner, FILE *fp); +void _gmx_sel_set_lex_input_file(yyscan_t scanner, FILE* fp); /** Initializes the scanner to scan a string. */ -void -_gmx_sel_set_lex_input_str(yyscan_t scanner, const char *str); +void _gmx_sel_set_lex_input_str(yyscan_t scanner, const char* str); /** The scanning function generated by Flex. */ -#define YY_DECL int _gmx_sel_yylex(YYSTYPE *yylval, YYLTYPE *yylloc, yyscan_t yyscanner) +#define YY_DECL int _gmx_sel_yylex(YYSTYPE* yylval, YYLTYPE* yylloc, yyscan_t yyscanner) YY_DECL; #endif diff --git a/src/gromacs/selection/scanner_internal.cpp b/src/gromacs/selection/scanner_internal.cpp index bfe3901505..b1c345ee06 100644 --- a/src/gromacs/selection/scanner_internal.cpp +++ b/src/gromacs/selection/scanner_internal.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -84,8 +85,7 @@ /*! \brief * Handles initialization of method parameter token. */ -static int -init_param_token(YYSTYPE *yylval, gmx_ana_selparam_t *param, bool bBoolNo) +static int init_param_token(YYSTYPE* yylval, gmx_ana_selparam_t* param, bool bBoolNo) { if (bBoolNo) { @@ -94,7 +94,7 @@ init_param_token(YYSTYPE *yylval, gmx_ana_selparam_t *param, bool bBoolNo) snew(yylval->str, strlen(param->name) + 3); yylval->str[0] = 'n'; yylval->str[1] = 'o'; - strcpy(yylval->str+2, param->name); + strcpy(yylval->str + 2, param->name); } else { @@ -106,12 +106,13 @@ init_param_token(YYSTYPE *yylval, gmx_ana_selparam_t *param, bool bBoolNo) /*! \brief * Processes a selection method token. */ -static int -init_method_token(YYSTYPE *yylval, YYLTYPE *yylloc, - const gmx::SelectionParserSymbol *symbol, - bool bPosMod, gmx_sel_lexer_t *state) +static int init_method_token(YYSTYPE* yylval, + YYLTYPE* yylloc, + const gmx::SelectionParserSymbol* symbol, + bool bPosMod, + gmx_sel_lexer_t* state) { - gmx_ana_selmethod_t *method = symbol->methodValue(); + gmx_ana_selmethod_t* method = symbol->methodValue(); /* If the previous token was not KEYWORD_POS, return EMPTY_POSMOD * before the actual method to work around a limitation in Bison. */ if (!bPosMod && method->type != POS_VALUE) @@ -128,13 +129,10 @@ init_method_token(YYSTYPE *yylval, YYLTYPE *yylloc, switch (method->type) { case INT_VALUE: - case REAL_VALUE: - state->bMatchOf = true; - return KEYWORD_NUMERIC; - case STR_VALUE: return KEYWORD_STR; + case REAL_VALUE: state->bMatchOf = true; return KEYWORD_NUMERIC; + case STR_VALUE: return KEYWORD_STR; case GROUP_VALUE: return KEYWORD_GROUP; - default: - GMX_THROW(gmx::InternalError("Unsupported keyword type")); + default: GMX_THROW(gmx::InternalError("Unsupported keyword type")); } } else @@ -169,24 +167,20 @@ init_method_token(YYSTYPE *yylval, YYLTYPE *yylloc, } switch (method->type) { - case INT_VALUE: return METHOD_NUMERIC; - case REAL_VALUE: return METHOD_NUMERIC; - case POS_VALUE: return METHOD_POS; + case INT_VALUE: return METHOD_NUMERIC; + case REAL_VALUE: return METHOD_NUMERIC; + case POS_VALUE: return METHOD_POS; case GROUP_VALUE: return METHOD_GROUP; - default: - --state->msp; - GMX_THROW(gmx::InternalError("Unsupported method type")); + default: --state->msp; GMX_THROW(gmx::InternalError("Unsupported method type")); } } } -int -_gmx_sel_lexer_process_pending(YYSTYPE *yylval, YYLTYPE *yylloc, - gmx_sel_lexer_t *state) +int _gmx_sel_lexer_process_pending(YYSTYPE* yylval, YYLTYPE* yylloc, gmx_sel_lexer_t* state) { if (state->nextparam) { - gmx_ana_selparam_t *param = state->nextparam; + gmx_ana_selparam_t* param = state->nextparam; bool bBoolNo = state->bBoolNo; if (state->neom > 0) @@ -206,27 +200,24 @@ _gmx_sel_lexer_process_pending(YYSTYPE *yylval, YYLTYPE *yylloc, } if (state->nextMethodSymbol) { - const gmx::SelectionParserSymbol *symbol = state->nextMethodSymbol; - state->nextMethodSymbol = nullptr; + const gmx::SelectionParserSymbol* symbol = state->nextMethodSymbol; + state->nextMethodSymbol = nullptr; return init_method_token(yylval, yylloc, symbol, true, state); } return 0; } -int -_gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc, - char *yytext, size_t yyleng, - gmx_sel_lexer_t *state) +int _gmx_sel_lexer_process_identifier(YYSTYPE* yylval, YYLTYPE* yylloc, char* yytext, size_t yyleng, gmx_sel_lexer_t* state) { /* Check if the identifier matches with a parameter name */ if (state->msp >= 0) { - gmx_ana_selparam_t *param = nullptr; + gmx_ana_selparam_t* param = nullptr; bool bBoolNo = false; int sp = state->msp; while (!param && sp >= 0) { - int i; + int i; for (i = 0; i < state->mstack[sp]->nparams; ++i) { /* Skip NULL parameters and too long parameters */ @@ -241,9 +232,9 @@ _gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc, break; } /* Check separately for a 'no' prefix on boolean parameters */ - if (state->mstack[sp]->param[i].val.type == NO_VALUE - && yyleng > 2 && yytext[0] == 'n' && yytext[1] == 'o' - && !strncmp(state->mstack[sp]->param[i].name, yytext+2, yyleng-2)) + if (state->mstack[sp]->param[i].val.type == NO_VALUE && yyleng > 2 + && yytext[0] == 'n' && yytext[1] == 'o' + && !strncmp(state->mstack[sp]->param[i].name, yytext + 2, yyleng - 2)) { param = &state->mstack[sp]->param[i]; bBoolNo = true; @@ -274,8 +265,7 @@ _gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc, } /* Check if the identifier matches with a symbol */ - const gmx::SelectionParserSymbol *symbol - = state->sc->symtab->findSymbol(std::string(yytext, yyleng)); + const gmx::SelectionParserSymbol* symbol = state->sc->symtab->findSymbol(std::string(yytext, yyleng)); /* If there is no match, return the token as a string */ if (!symbol) { @@ -294,40 +284,31 @@ _gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc, if (symtype == gmx::SelectionParserSymbol::ReservedSymbol) { GMX_THROW(gmx::InternalError(gmx::formatString( - "Mismatch between tokenizer and reserved symbol table (for '%s')", - symbol->name().c_str()))); + "Mismatch between tokenizer and reserved symbol table (for '%s')", symbol->name().c_str()))); } /* For variable symbols, return the type of the variable value */ if (symtype == gmx::SelectionParserSymbol::VariableSymbol) { - const gmx::SelectionTreeElementPointer &var = symbol->variableValue(); + const gmx::SelectionTreeElementPointer& var = symbol->variableValue(); /* Return simple tokens for constant variables */ if (var->type == SEL_CONST) { switch (var->v.type) { - case INT_VALUE: - yylval->i = var->v.u.i[0]; - return TOK_INT; - case REAL_VALUE: - yylval->r = var->v.u.r[0]; - return TOK_REAL; - case POS_VALUE: - break; - default: - GMX_THROW(gmx::InternalError("Unsupported variable type")); + case INT_VALUE: yylval->i = var->v.u.i[0]; return TOK_INT; + case REAL_VALUE: yylval->r = var->v.u.r[0]; return TOK_REAL; + case POS_VALUE: break; + default: GMX_THROW(gmx::InternalError("Unsupported variable type")); } } yylval->sel = new gmx::SelectionTreeElementPointer(var); switch (var->v.type) { - case INT_VALUE: return VARIABLE_NUMERIC; - case REAL_VALUE: return VARIABLE_NUMERIC; - case POS_VALUE: return VARIABLE_POS; + case INT_VALUE: return VARIABLE_NUMERIC; + case REAL_VALUE: return VARIABLE_NUMERIC; + case POS_VALUE: return VARIABLE_POS; case GROUP_VALUE: return VARIABLE_GROUP; - default: - delete yylval->sel; - GMX_THROW(gmx::InternalError("Unsupported variable type")); + default: delete yylval->sel; GMX_THROW(gmx::InternalError("Unsupported variable type")); } /* This position should not be reached. */ } @@ -344,16 +325,13 @@ _gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc, return INVALID; } -void -_gmx_sel_lexer_add_token(YYLTYPE *yylloc, const char *str, int len, - gmx_sel_lexer_t *state) +void _gmx_sel_lexer_add_token(YYLTYPE* yylloc, const char* str, int len, gmx_sel_lexer_t* state) { yylloc->startIndex = yylloc->endIndex = state->pselstr.size(); /* Do nothing if the string is empty, or if it is a space and there is * no other text yet, or if there already is a space. */ if (!str || len == 0 || strlen(str) == 0 - || (str[0] == ' ' && str[1] == 0 - && (state->pselstr.empty() || state->pselstr.back() == ' '))) + || (str[0] == ' ' && str[1] == 0 && (state->pselstr.empty() || state->pselstr.back() == ' '))) { return; } @@ -366,10 +344,12 @@ _gmx_sel_lexer_add_token(YYLTYPE *yylloc, const char *str, int len, yylloc->endIndex = state->pselstr.size(); } -void -_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc, - gmx::TextWriter *statusWriter, int maxnr, - bool bGroups, struct gmx_ana_indexgrps_t *grps) +void _gmx_sel_init_lexer(yyscan_t* scannerp, + struct gmx_ana_selcollection_t* sc, + gmx::TextWriter* statusWriter, + int maxnr, + bool bGroups, + struct gmx_ana_indexgrps_t* grps) { int rc = _gmx_sel_yylex_init(scannerp); if (rc != 0) @@ -378,12 +358,12 @@ _gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc, GMX_THROW(gmx::InternalError("Lexer initialization failed")); } - gmx_sel_lexer_t *state = new gmx_sel_lexer_t; + gmx_sel_lexer_t* state = new gmx_sel_lexer_t; - state->sc = sc; - state->bGroups = bGroups; - state->grps = grps; - state->nexpsel = (maxnr > 0 ? gmx::ssize(sc->sel) + maxnr : -1); + state->sc = sc; + state->bGroups = bGroups; + state->grps = grps; + state->nexpsel = (maxnr > 0 ? gmx::ssize(sc->sel) + maxnr : -1); state->statusWriter = statusWriter; @@ -406,10 +386,9 @@ _gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc, _gmx_sel_yyset_extra(state, *scannerp); } -void -_gmx_sel_free_lexer(yyscan_t scanner) +void _gmx_sel_free_lexer(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); sfree(state->mstack); if (state->bBuffer) @@ -420,95 +399,80 @@ _gmx_sel_free_lexer(yyscan_t scanner) _gmx_sel_yylex_destroy(scanner); } -void -_gmx_sel_lexer_set_exception(yyscan_t scanner, - const std::exception_ptr &ex) +void _gmx_sel_lexer_set_exception(yyscan_t scanner, const std::exception_ptr& ex) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); - state->exception = ex; + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); + state->exception = ex; } -void -_gmx_sel_lexer_rethrow_exception_if_occurred(yyscan_t scanner) +void _gmx_sel_lexer_rethrow_exception_if_occurred(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); if (state->exception) { std::exception_ptr ex = state->exception; - state->exception = std::exception_ptr(); + state->exception = std::exception_ptr(); std::rethrow_exception(ex); } } -gmx::TextWriter * -_gmx_sel_lexer_get_status_writer(yyscan_t scanner) +gmx::TextWriter* _gmx_sel_lexer_get_status_writer(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->statusWriter; } -struct gmx_ana_selcollection_t * -_gmx_sel_lexer_selcollection(yyscan_t scanner) +struct gmx_ana_selcollection_t* _gmx_sel_lexer_selcollection(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->sc; } -bool -_gmx_sel_lexer_has_groups_set(yyscan_t scanner) +bool _gmx_sel_lexer_has_groups_set(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->bGroups; } -struct gmx_ana_indexgrps_t * -_gmx_sel_lexer_indexgrps(yyscan_t scanner) +struct gmx_ana_indexgrps_t* _gmx_sel_lexer_indexgrps(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->grps; } -int -_gmx_sel_lexer_exp_selcount(yyscan_t scanner) +int _gmx_sel_lexer_exp_selcount(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->nexpsel; } -const char * -_gmx_sel_lexer_pselstr(yyscan_t scanner) +const char* _gmx_sel_lexer_pselstr(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->pselstr.c_str(); } -void -_gmx_sel_lexer_set_current_location(yyscan_t scanner, - const gmx::SelectionLocation &location) +void _gmx_sel_lexer_set_current_location(yyscan_t scanner, const gmx::SelectionLocation& location) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); state->currentLocation = location; } -const gmx::SelectionLocation & -_gmx_sel_lexer_get_current_location(yyscan_t scanner) +const gmx::SelectionLocation& _gmx_sel_lexer_get_current_location(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return state->currentLocation; } -std::string -_gmx_sel_lexer_get_current_text(yyscan_t scanner) +std::string _gmx_sel_lexer_get_current_text(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); return _gmx_sel_lexer_get_text(scanner, state->currentLocation); } -std::string -_gmx_sel_lexer_get_text(yyscan_t scanner, - const gmx::SelectionLocation &location) +std::string _gmx_sel_lexer_get_text(yyscan_t scanner, const gmx::SelectionLocation& location) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); const int startIndex = location.startIndex; const int endIndex = location.endIndex; if (startIndex >= endIndex) @@ -518,25 +482,22 @@ _gmx_sel_lexer_get_text(yyscan_t scanner, return state->pselstr.substr(startIndex, endIndex - startIndex); } -void -_gmx_sel_lexer_clear_pselstr(yyscan_t scanner) +void _gmx_sel_lexer_clear_pselstr(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); state->pselstr.clear(); } -void -_gmx_sel_lexer_clear_method_stack(yyscan_t scanner) +void _gmx_sel_lexer_clear_method_stack(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); state->msp = -1; } -void -_gmx_sel_finish_method(yyscan_t scanner) +void _gmx_sel_finish_method(yyscan_t scanner) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); if (state->msp >= 0) { @@ -544,20 +505,18 @@ _gmx_sel_finish_method(yyscan_t scanner) } } -void -_gmx_sel_set_lex_input_file(yyscan_t scanner, FILE *fp) +void _gmx_sel_set_lex_input_file(yyscan_t scanner, FILE* fp) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); state->bBuffer = true; state->buffer = _gmx_sel_yy_create_buffer(fp, YY_BUF_SIZE, scanner); _gmx_sel_yy_switch_to_buffer(state->buffer, scanner); } -void -_gmx_sel_set_lex_input_str(yyscan_t scanner, const char *str) +void _gmx_sel_set_lex_input_str(yyscan_t scanner, const char* str) { - gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner); + gmx_sel_lexer_t* state = _gmx_sel_yyget_extra(scanner); if (state->bBuffer) { diff --git a/src/gromacs/selection/scanner_internal.h b/src/gromacs/selection/scanner_internal.h index 6ee5a051b4..3cae7ac609 100644 --- a/src/gromacs/selection/scanner_internal.h +++ b/src/gromacs/selection/scanner_internal.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,21 +51,21 @@ namespace gmx { class SelectionParserSymbol; class TextWriter; -} +} // namespace gmx /* These need to be defined before including scanner_flex.h, because it * uses YY_EXTRA_TYPE. But we also need to include it before defining * gmx_sel_lexer_t; hence the forward declaration. */ struct gmx_sel_lexer_t; -#define YY_EXTRA_TYPE struct gmx_sel_lexer_t * +#define YY_EXTRA_TYPE struct gmx_sel_lexer_t* /* We cannot include scanner_flex.h from the scanner itself, because it * seems to break everything. */ /* And we need to define YY_NO_UNISTD_H here as well, otherwise unistd.h * gets included in other files than scanner.cpp... */ #ifndef FLEX_SCANNER -#define YY_NO_UNISTD_H -#include "scanner_flex.h" +# define YY_NO_UNISTD_H +# include "scanner_flex.h" #endif /*! \internal \brief @@ -73,76 +74,76 @@ struct gmx_sel_lexer_t; typedef struct gmx_sel_lexer_t { //! Selection collection to put parsed selections in. - struct gmx_ana_selcollection_t *sc; + struct gmx_ana_selcollection_t* sc; //! Stores an exception that occurred during parsing. - std::exception_ptr exception; + std::exception_ptr exception; //! Whether external index groups have been set. - bool bGroups; + bool bGroups; //! External index groups for resolving \c group keywords. - struct gmx_ana_indexgrps_t *grps; + struct gmx_ana_indexgrps_t* grps; //! Number of selections at which the parser should stop. - int nexpsel; + int nexpsel; //! Writer to use for status output (if not NULL, parser is interactive). - gmx::TextWriter *statusWriter; + gmx::TextWriter* statusWriter; //! Pretty-printed version of the string parsed since last clear. - std::string pselstr; + std::string pselstr; /*! \brief * Position of the result of the current Bison action. * * This identifies the part of \a pselstr that corresponds to the * subselection that is currently being reduced by Bison. */ - gmx::SelectionLocation currentLocation; + gmx::SelectionLocation currentLocation; //! Stack of methods in which parameters should be looked up. - struct gmx_ana_selmethod_t **mstack; + struct gmx_ana_selmethod_t** mstack; //! Index of the top of the stack in \a mstack. - int msp; + int msp; //! Number of elements allocated for \a mstack. - int mstack_alloc; + int mstack_alloc; //! Number of END_OF_METHOD tokens to return before \a nextparam. - int neom; + int neom; //! Parameter symbol to return before resuming scanning. - struct gmx_ana_selparam_t *nextparam; + struct gmx_ana_selparam_t* nextparam; //! Whether \a nextparam was a boolean parameter with a 'no' prefix. - bool bBoolNo; + bool bBoolNo; /*! \brief * Method symbol to return before resuming scanning * * Only used when \p nextparam is NULL. */ - const gmx::SelectionParserSymbol *nextMethodSymbol; + const gmx::SelectionParserSymbol* nextMethodSymbol; //! Used to track whether the previous token was a position modifier. - int prev_pos_kw; + int prev_pos_kw; //! Whether the 'of' keyword is acceptable as the next token. - bool bMatchOf; + bool bMatchOf; //! Whether boolean values (yes/no/on/off) are acceptable as the next token. - bool bMatchBool; + bool bMatchBool; //! Whether the next token starts a new selection. - bool bCmdStart; + bool bCmdStart; //! Whether an external buffer is set for the scanner. - bool bBuffer; + bool bBuffer; //! The current buffer for the scanner. - YY_BUFFER_STATE buffer; + YY_BUFFER_STATE buffer; } gmx_sel_lexer_t; /* Because Flex defines yylval, yytext, and yyleng as macros, * and this file is included from scanner.l, * we cannot have them here as parameter names... */ /** Internal function for cases where several tokens need to be returned. */ -int -_gmx_sel_lexer_process_pending(YYSTYPE * /*yylval*/, YYLTYPE *, gmx_sel_lexer_t *state); +int _gmx_sel_lexer_process_pending(YYSTYPE* /*yylval*/, YYLTYPE*, gmx_sel_lexer_t* state); /** Internal function that processes identifier tokens. */ -int - _gmx_sel_lexer_process_identifier(YYSTYPE * /*yylval*/, YYLTYPE *, char * /*yytext*/, size_t /*yyleng*/, - gmx_sel_lexer_t *state); +int _gmx_sel_lexer_process_identifier(YYSTYPE* /*yylval*/, + YYLTYPE*, + char* /*yytext*/, + size_t /*yyleng*/, + gmx_sel_lexer_t* state); /** Internal function to add a token to the pretty-printed selection text. */ -void -_gmx_sel_lexer_add_token(YYLTYPE *, const char *str, int len, gmx_sel_lexer_t *state); +void _gmx_sel_lexer_add_token(YYLTYPE*, const char* str, int len, gmx_sel_lexer_t* state); #endif diff --git a/src/gromacs/selection/selection.cpp b/src/gromacs/selection/selection.cpp index a3b1010e03..720c61e49e 100644 --- a/src/gromacs/selection/selection.cpp +++ b/src/gromacs/selection/selection.cpp @@ -67,12 +67,15 @@ namespace internal * SelectionData */ -SelectionData::SelectionData(SelectionTreeElement *elem, - const char *selstr) - : name_(elem->name()), selectionText_(selstr), - rootElement_(*elem), coveredFractionType_(CFRAC_NONE), - coveredFraction_(1.0), averageCoveredFraction_(1.0), - bDynamic_(false), bDynamicCoveredFraction_(false) +SelectionData::SelectionData(SelectionTreeElement* elem, const char* selstr) : + name_(elem->name()), + selectionText_(selstr), + rootElement_(*elem), + coveredFractionType_(CFRAC_NONE), + coveredFraction_(1.0), + averageCoveredFraction_(1.0), + bDynamic_(false), + bDynamicCoveredFraction_(false) { if (elem->child->type == SEL_CONST) { @@ -82,7 +85,7 @@ SelectionData::SelectionData(SelectionTreeElement *elem, else { SelectionTreeElementPointer child = elem->child; - child->flags &= ~SEL_ALLOCVAL; + child->flags &= ~SEL_ALLOCVAL; _gmx_selvalue_setstore(&child->v, &rawPositions_); /* We should also skip any modifiers to determine the dynamic * status. */ @@ -121,13 +124,10 @@ SelectionData::SelectionData(SelectionTreeElement *elem, } -SelectionData::~SelectionData() -{ -} +SelectionData::~SelectionData() {} -bool -SelectionData::initCoveredFraction(e_coverfrac_t type) +bool SelectionData::initCoveredFraction(e_coverfrac_t type) { coveredFractionType_ = type; if (type == CFRAC_NONE) @@ -161,9 +161,10 @@ namespace * * Does not throw if enough space has been reserved for the output vectors. */ -void computeMassesAndCharges(const gmx_mtop_t *top, const gmx_ana_pos_t &pos, - std::vector *masses, - std::vector *charges) +void computeMassesAndCharges(const gmx_mtop_t* top, + const gmx_ana_pos_t& pos, + std::vector* masses, + std::vector* charges) { GMX_ASSERT(top != nullptr, "Should not have been called with NULL topology"); masses->clear(); @@ -173,40 +174,36 @@ void computeMassesAndCharges(const gmx_mtop_t *top, const gmx_ana_pos_t &pos, { real mass = 0.0; real charge = 0.0; - for (int i = pos.m.mapb.index[b]; i < pos.m.mapb.index[b+1]; ++i) + for (int i = pos.m.mapb.index[b]; i < pos.m.mapb.index[b + 1]; ++i) { - const int index = pos.m.mapb.a[i]; - const t_atom &atom = mtopGetAtomParameters(top, index, &molb); - mass += atom.m; - charge += atom.q; + const int index = pos.m.mapb.a[i]; + const t_atom& atom = mtopGetAtomParameters(top, index, &molb); + mass += atom.m; + charge += atom.q; } masses->push_back(mass); charges->push_back(charge); } } -} // namespace +} // namespace -bool -SelectionData::hasSortedAtomIndices() const +bool SelectionData::hasSortedAtomIndices() const { gmx_ana_index_t g; gmx_ana_index_set(&g, rawPositions_.m.mapb.nra, rawPositions_.m.mapb.a, -1); return gmx_ana_index_check_sorted(&g); } -void -SelectionData::refreshName() +void SelectionData::refreshName() { rootElement_.fillNameIfMissing(selectionText_.c_str()); name_ = rootElement_.name(); } -void -SelectionData::initializeMassesAndCharges(const gmx_mtop_t *top) +void SelectionData::initializeMassesAndCharges(const gmx_mtop_t* top) { - GMX_ASSERT(posMass_.empty() && posCharge_.empty(), - "Should not be called more than once"); + GMX_ASSERT(posMass_.empty() && posCharge_.empty(), "Should not be called more than once"); posMass_.reserve(posCount()); posCharge_.reserve(posCount()); if (top == nullptr) @@ -221,8 +218,7 @@ SelectionData::initializeMassesAndCharges(const gmx_mtop_t *top) } -void -SelectionData::refreshMassesAndCharges(const gmx_mtop_t *top) +void SelectionData::refreshMassesAndCharges(const gmx_mtop_t* top) { if (top != nullptr && isDynamic() && !hasFlag(efSelection_DynamicMask)) { @@ -231,20 +227,18 @@ SelectionData::refreshMassesAndCharges(const gmx_mtop_t *top) } -void -SelectionData::updateCoveredFractionForFrame() +void SelectionData::updateCoveredFractionForFrame() { if (isCoveredFractionDynamic()) { - real cfrac = _gmx_selelem_estimate_coverfrac(rootElement()); - coveredFraction_ = cfrac; + real cfrac = _gmx_selelem_estimate_coverfrac(rootElement()); + coveredFraction_ = cfrac; averageCoveredFraction_ += cfrac; } } -void -SelectionData::computeAverageCoveredFraction(int nframes) +void SelectionData::computeAverageCoveredFraction(int nframes) { if (isCoveredFractionDynamic() && nframes > 0) { @@ -253,19 +247,17 @@ SelectionData::computeAverageCoveredFraction(int nframes) } -void -SelectionData::restoreOriginalPositions(const gmx_mtop_t *top) +void SelectionData::restoreOriginalPositions(const gmx_mtop_t* top) { if (isDynamic()) { - gmx_ana_pos_t &p = rawPositions_; - gmx_ana_indexmap_update(&p.m, rootElement().v.u.g, - hasFlag(gmx::efSelection_DynamicMask)); + gmx_ana_pos_t& p = rawPositions_; + gmx_ana_indexmap_update(&p.m, rootElement().v.u.g, hasFlag(gmx::efSelection_DynamicMask)); refreshMassesAndCharges(top); } } -} // namespace internal +} // namespace internal /******************************************************************** * Selection @@ -273,8 +265,7 @@ SelectionData::restoreOriginalPositions(const gmx_mtop_t *top) Selection::operator AnalysisNeighborhoodPositions() const { - AnalysisNeighborhoodPositions pos(data().rawPositions_.x, - data().rawPositions_.count()); + AnalysisNeighborhoodPositions pos(data().rawPositions_.x, data().rawPositions_.count()); if (hasOnlyAtoms()) { pos.exclusionIds(atomIndices()); @@ -283,56 +274,50 @@ Selection::operator AnalysisNeighborhoodPositions() const } -void -Selection::setOriginalId(int i, int id) +void Selection::setOriginalId(int i, int id) { data().rawPositions_.m.mapid[i] = id; data().rawPositions_.m.orgid[i] = id; } -int -Selection::initOriginalIdsToGroup(const gmx_mtop_t *top, e_index_t type) +int Selection::initOriginalIdsToGroup(const gmx_mtop_t* top, e_index_t type) { try { return gmx_ana_indexmap_init_orgid_group(&data().rawPositions_.m, top, type); } - catch (const InconsistentInputError &) + catch (const InconsistentInputError&) { GMX_ASSERT(type == INDEX_RES || type == INDEX_MOL, "Expected that only grouping by residue/molecule would fail"); - std::string message = - formatString("Cannot group selection '%s' into %s, because some " - "positions have atoms from more than one such group.", - name(), type == INDEX_MOL ? "molecules" : "residues"); + std::string message = formatString( + "Cannot group selection '%s' into %s, because some " + "positions have atoms from more than one such group.", + name(), type == INDEX_MOL ? "molecules" : "residues"); GMX_THROW(InconsistentInputError(message)); } } -void -Selection::printInfo(FILE *fp) const +void Selection::printInfo(FILE* fp) const { - fprintf(fp, "\"%s\" (%d position%s, %d atom%s%s)", name(), - posCount(), posCount() == 1 ? "" : "s", - atomCount(), atomCount() == 1 ? "" : "s", - isDynamic() ? ", dynamic" : ""); + fprintf(fp, "\"%s\" (%d position%s, %d atom%s%s)", name(), posCount(), posCount() == 1 ? "" : "s", + atomCount(), atomCount() == 1 ? "" : "s", isDynamic() ? ", dynamic" : ""); fprintf(fp, "\n"); } -void -Selection::printDebugInfo(FILE *fp, int nmaxind) const +void Selection::printDebugInfo(FILE* fp, int nmaxind) const { - const gmx_ana_pos_t &p = data().rawPositions_; + const gmx_ana_pos_t& p = data().rawPositions_; fprintf(fp, " "); printInfo(fp); fprintf(fp, " Group "); gmx_ana_index_t g; gmx_ana_index_set(&g, p.m.mapb.nra, p.m.mapb.a, 0); - TextWriter writer(fp); + TextWriter writer(fp); gmx_ana_index_dump(&writer, &g, nmaxind); fprintf(fp, " Block (size=%d):", p.m.mapb.nr); @@ -407,8 +392,7 @@ Selection::printDebugInfo(FILE *fp, int nmaxind) const SelectionPosition::operator AnalysisNeighborhoodPositions() const { - AnalysisNeighborhoodPositions pos(sel_->rawPositions_.x, - sel_->rawPositions_.count()); + AnalysisNeighborhoodPositions pos(sel_->rawPositions_.x, sel_->rawPositions_.count()); if (sel_->hasOnlyAtoms()) { // TODO: Move atomIndices() such that it can be reused here as well. diff --git a/src/gromacs/selection/selection.h b/src/gromacs/selection/selection.h index da551eb801..21f3cd5146 100644 --- a/src/gromacs/selection/selection.h +++ b/src/gromacs/selection/selection.h @@ -85,147 +85,147 @@ namespace internal */ class SelectionData { - public: - /*! \brief - * Creates a new selection object. - * - * \param[in] elem Root of the evaluation tree for this selection. - * \param[in] selstr String that was parsed to produce this selection. - * \throws std::bad_alloc if out of memory. - */ - SelectionData(SelectionTreeElement *elem, const char *selstr); - ~SelectionData(); - - //! Returns the name for this selection. - const char *name() const { return name_.c_str(); } - //! Returns the string that was parsed to produce this selection. - const char *selectionText() const { return selectionText_.c_str(); } - //! Returns true if the size of the selection (posCount()) is dynamic. - bool isDynamic() const { return bDynamic_; } - //! Returns the type of positions in the selection. - e_index_t type() const { return rawPositions_.m.type; } - //! Returns true if the selection only contains positions with a single atom each. - bool hasOnlyAtoms() const { return type() == INDEX_ATOM; } - //! Returns `true` if the atom indices in the selection are in ascending order. - bool hasSortedAtomIndices() const; - - //! Number of positions in the selection. - int posCount() const { return rawPositions_.count(); } - //! Returns the root of the evaluation tree for this selection. - SelectionTreeElement &rootElement() { return rootElement_; } - - //! Returns whether the covered fraction can change between frames. - bool isCoveredFractionDynamic() const { return bDynamicCoveredFraction_; } - - //! Returns true if the given flag is set. - bool hasFlag(SelectionFlag flag) const { return flags_.test(flag); } - //! Sets the flags for this selection. - void setFlags(SelectionFlags flags) { flags_ = flags; } - - //! \copydoc Selection::initCoveredFraction() - bool initCoveredFraction(e_coverfrac_t type); - - /*! \brief - * Updates the name of the selection if missing. - * - * \throws std::bad_alloc if out of memory. - * - * If selections get their value from a group reference that cannot be - * resolved during parsing, the name is final only after group - * references have been resolved. - * - * This function is called by SelectionCollection::setIndexGroups(). - */ - void refreshName(); - /*! \brief - * Computes total masses and charges for all selection positions. - * - * \param[in] top Topology information. - * \throws std::bad_alloc if out of memory. - * - * For dynamic selections, the values need to be updated after each - * evaluation with refreshMassesAndCharges(). - * This is done by SelectionEvaluator. - * - * This function is called by SelectionCompiler. - * - * Strong exception safety guarantee. - */ - void initializeMassesAndCharges(const gmx_mtop_t *top); - /*! \brief - * Updates masses and charges after dynamic selection has been - * evaluated. - * - * \param[in] top Topology information. - * - * Called by SelectionEvaluator. - */ - void refreshMassesAndCharges(const gmx_mtop_t *top); - /*! \brief - * Updates the covered fraction after a selection has been evaluated. - * - * Called by SelectionEvaluator. - */ - void updateCoveredFractionForFrame(); - /*! \brief - * Computes average covered fraction after all frames have been evaluated. - * - * \param[in] nframes Number of frames that have been evaluated. - * - * \p nframes should be equal to the number of calls to - * updateCoveredFractionForFrame(). - * Called by SelectionEvaluator::evaluateFinal(). - */ - void computeAverageCoveredFraction(int nframes); - /*! \brief - * Restores position information to state it was in after compilation. - * - * \param[in] top Topology information. - * - * Depends on SelectionCompiler storing the original atoms in the - * \a rootElement_ object. - * Called by SelectionEvaluator::evaluateFinal(). - */ - void restoreOriginalPositions(const gmx_mtop_t *top); - - private: - //! Name of the selection. - std::string name_; - //! The actual selection string. - std::string selectionText_; - //! Low-level representation of selected positions. - gmx_ana_pos_t rawPositions_; - //! Total masses for the current positions. - std::vector posMass_; - //! Total charges for the current positions. - std::vector posCharge_; - SelectionFlags flags_; - //! Root of the selection evaluation tree. - SelectionTreeElement &rootElement_; - //! Type of the covered fraction. - e_coverfrac_t coveredFractionType_; - //! Covered fraction of the selection for the current frame. - real coveredFraction_; - //! The average covered fraction (over the trajectory). - real averageCoveredFraction_; - //! true if the value can change as a function of time. - bool bDynamic_; - //! true if the covered fraction depends on the frame. - bool bDynamicCoveredFraction_; - - /*! \brief - * Needed to wrap access to information. - */ - friend class gmx::Selection; - /*! \brief - * Needed for proper access to position information. - */ - friend class gmx::SelectionPosition; - - GMX_DISALLOW_COPY_AND_ASSIGN(SelectionData); +public: + /*! \brief + * Creates a new selection object. + * + * \param[in] elem Root of the evaluation tree for this selection. + * \param[in] selstr String that was parsed to produce this selection. + * \throws std::bad_alloc if out of memory. + */ + SelectionData(SelectionTreeElement* elem, const char* selstr); + ~SelectionData(); + + //! Returns the name for this selection. + const char* name() const { return name_.c_str(); } + //! Returns the string that was parsed to produce this selection. + const char* selectionText() const { return selectionText_.c_str(); } + //! Returns true if the size of the selection (posCount()) is dynamic. + bool isDynamic() const { return bDynamic_; } + //! Returns the type of positions in the selection. + e_index_t type() const { return rawPositions_.m.type; } + //! Returns true if the selection only contains positions with a single atom each. + bool hasOnlyAtoms() const { return type() == INDEX_ATOM; } + //! Returns `true` if the atom indices in the selection are in ascending order. + bool hasSortedAtomIndices() const; + + //! Number of positions in the selection. + int posCount() const { return rawPositions_.count(); } + //! Returns the root of the evaluation tree for this selection. + SelectionTreeElement& rootElement() { return rootElement_; } + + //! Returns whether the covered fraction can change between frames. + bool isCoveredFractionDynamic() const { return bDynamicCoveredFraction_; } + + //! Returns true if the given flag is set. + bool hasFlag(SelectionFlag flag) const { return flags_.test(flag); } + //! Sets the flags for this selection. + void setFlags(SelectionFlags flags) { flags_ = flags; } + + //! \copydoc Selection::initCoveredFraction() + bool initCoveredFraction(e_coverfrac_t type); + + /*! \brief + * Updates the name of the selection if missing. + * + * \throws std::bad_alloc if out of memory. + * + * If selections get their value from a group reference that cannot be + * resolved during parsing, the name is final only after group + * references have been resolved. + * + * This function is called by SelectionCollection::setIndexGroups(). + */ + void refreshName(); + /*! \brief + * Computes total masses and charges for all selection positions. + * + * \param[in] top Topology information. + * \throws std::bad_alloc if out of memory. + * + * For dynamic selections, the values need to be updated after each + * evaluation with refreshMassesAndCharges(). + * This is done by SelectionEvaluator. + * + * This function is called by SelectionCompiler. + * + * Strong exception safety guarantee. + */ + void initializeMassesAndCharges(const gmx_mtop_t* top); + /*! \brief + * Updates masses and charges after dynamic selection has been + * evaluated. + * + * \param[in] top Topology information. + * + * Called by SelectionEvaluator. + */ + void refreshMassesAndCharges(const gmx_mtop_t* top); + /*! \brief + * Updates the covered fraction after a selection has been evaluated. + * + * Called by SelectionEvaluator. + */ + void updateCoveredFractionForFrame(); + /*! \brief + * Computes average covered fraction after all frames have been evaluated. + * + * \param[in] nframes Number of frames that have been evaluated. + * + * \p nframes should be equal to the number of calls to + * updateCoveredFractionForFrame(). + * Called by SelectionEvaluator::evaluateFinal(). + */ + void computeAverageCoveredFraction(int nframes); + /*! \brief + * Restores position information to state it was in after compilation. + * + * \param[in] top Topology information. + * + * Depends on SelectionCompiler storing the original atoms in the + * \a rootElement_ object. + * Called by SelectionEvaluator::evaluateFinal(). + */ + void restoreOriginalPositions(const gmx_mtop_t* top); + +private: + //! Name of the selection. + std::string name_; + //! The actual selection string. + std::string selectionText_; + //! Low-level representation of selected positions. + gmx_ana_pos_t rawPositions_; + //! Total masses for the current positions. + std::vector posMass_; + //! Total charges for the current positions. + std::vector posCharge_; + SelectionFlags flags_; + //! Root of the selection evaluation tree. + SelectionTreeElement& rootElement_; + //! Type of the covered fraction. + e_coverfrac_t coveredFractionType_; + //! Covered fraction of the selection for the current frame. + real coveredFraction_; + //! The average covered fraction (over the trajectory). + real averageCoveredFraction_; + //! true if the value can change as a function of time. + bool bDynamic_; + //! true if the covered fraction depends on the frame. + bool bDynamicCoveredFraction_; + + /*! \brief + * Needed to wrap access to information. + */ + friend class gmx::Selection; + /*! \brief + * Needed for proper access to position information. + */ + friend class gmx::SelectionPosition; + + GMX_DISALLOW_COPY_AND_ASSIGN(SelectionData); }; -} // namespace internal +} // namespace internal /*! \brief * Provides access to a single selection. @@ -287,298 +287,283 @@ class SelectionData */ class Selection { - public: - /*! \brief - * Creates a selection wrapper that has no associated selection. - * - * Any attempt to call methods in the object before a selection is - * assigned results in undefined behavior. - * isValid() returns `false` for the selection until it is initialized. - */ - Selection() : sel_(nullptr) {} - /*! \brief - * Creates a new selection object. - * - * \param sel Selection data to wrap. - * - * Only for internal use by the selection module. - */ - explicit Selection(internal::SelectionData *sel) : sel_(sel) {} - - //! Returns whether the selection object is initialized. - bool isValid() const { return sel_ != nullptr; } - - //! Returns whether two selection objects wrap the same selection. - bool operator==(const Selection &other) const - { - return sel_ == other.sel_; - } - //! Returns whether two selection objects wrap different selections. - bool operator!=(const Selection &other) const - { - return !operator==(other); - } - - //! Returns the name of the selection. - const char *name() const { return data().name(); } - //! Returns the string that was parsed to produce this selection. - const char *selectionText() const { return data().selectionText(); } - //! Returns true if the size of the selection (posCount()) is dynamic. - bool isDynamic() const { return data().isDynamic(); } - //! Returns the type of positions in the selection. - e_index_t type() const { return data().type(); } - //! Returns true if the selection only contains positions with a single atom each. - bool hasOnlyAtoms() const { return data().hasOnlyAtoms(); } - //! Returns `true` if the atom indices in the selection are in ascending order. - bool hasSortedAtomIndices() const { return data().hasSortedAtomIndices(); } - - //! Total number of atoms in the selection. - int atomCount() const - { - return data().rawPositions_.m.mapb.nra; - } - //! Returns atom indices of all atoms in the selection. - ArrayRef atomIndices() const - { - return constArrayRefFromArray(sel_->rawPositions_.m.mapb.a, - sel_->rawPositions_.m.mapb.nra); - } - //! Number of positions in the selection. - int posCount() const { return data().posCount(); } - //! Access a single position. - SelectionPosition position(int i) const; - //! Returns coordinates for this selection as a continuous array. - ArrayRef coordinates() const - { - return constArrayRefFromArray(data().rawPositions_.x, posCount()); - } - //! Returns whether velocities are available for this selection. - bool hasVelocities() const { return data().rawPositions_.v != nullptr; } - /*! \brief - * Returns velocities for this selection as a continuous array. - * - * Must not be called if hasVelocities() returns false. - */ - ArrayRef velocities() const - { - GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable"); - return constArrayRefFromArray(data().rawPositions_.v, posCount()); - } - //! Returns whether forces are available for this selection. - bool hasForces() const { return sel_->rawPositions_.f != nullptr; } - /*! \brief - * Returns forces for this selection as a continuous array. - * - * Must not be called if hasForces() returns false. - */ - ArrayRef forces() const - { - GMX_ASSERT(hasForces(), "Forces accessed, but unavailable"); - return constArrayRefFromArray(data().rawPositions_.f, posCount()); - } - //! Returns masses for this selection as a continuous array. - ArrayRef masses() const - { - // posMass_ may have more entries than posCount() in the case of - // dynamic selections that don't have a topology - // (and thus the masses and charges are fixed). - GMX_ASSERT(data().posMass_.size() >= static_cast(posCount()), - "Internal inconsistency"); - return makeArrayRef(data().posMass_).subArray(0, posCount()); - } - //! Returns charges for this selection as a continuous array. - ArrayRef charges() const - { - // posCharge_ may have more entries than posCount() in the case of - // dynamic selections that don't have a topology - // (and thus the masses and charges are fixed). - GMX_ASSERT(data().posCharge_.size() >= static_cast(posCount()), - "Internal inconsistency"); - return makeArrayRef(data().posCharge_).subArray(0, posCount()); - } - /*! \brief - * Returns reference IDs for this selection as a continuous array. - * - * \see SelectionPosition::refId() - */ - ArrayRef refIds() const - { - return constArrayRefFromArray(data().rawPositions_.m.refid, posCount()); - } - /*! \brief - * Returns mapped IDs for this selection as a continuous array. - * - * \see SelectionPosition::mappedId() - */ - ArrayRef mappedIds() const - { - return constArrayRefFromArray(data().rawPositions_.m.mapid, posCount()); - } - - //! Returns whether the covered fraction can change between frames. - bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); } - //! Returns the covered fraction for the current frame. - real coveredFraction() const { return data().coveredFraction_; } - - /*! \brief - * Allows passing a selection directly to neighborhood searching. - * - * When initialized this way, AnalysisNeighborhoodPair objects return - * indices that can be used to index the selection positions with - * position(). - * - * Works exactly like if AnalysisNeighborhoodPositions had a - * constructor taking a Selection object as a parameter. - * See AnalysisNeighborhoodPositions for rationale and additional - * discussion. - */ - operator AnalysisNeighborhoodPositions() const; - - /*! \brief - * Initializes information about covered fractions. - * - * \param[in] type Type of covered fraction required. - * \returns true if the covered fraction can be calculated for the - * selection. - */ - bool initCoveredFraction(e_coverfrac_t type) - { - return data().initCoveredFraction(type); - } - /*! \brief - * Sets whether this selection evaluates velocities for positions. - * - * \param[in] bEnabled If true, velocities are evaluated. - * - * If you request the evaluation, but then evaluate the selection for - * a frame that does not contain velocity information, results are - * undefined. - * - * \todo - * Implement it such that in the above case, hasVelocities() will - * return false for such frames. - * - * Does not throw. - */ - void setEvaluateVelocities(bool bEnabled) - { - data().flags_.set(efSelection_EvaluateVelocities, bEnabled); - } - /*! \brief - * Sets whether this selection evaluates forces for positions. - * - * \param[in] bEnabled If true, forces are evaluated. - * - * If you request the evaluation, but then evaluate the selection for - * a frame that does not contain force information, results are - * undefined. - * - * Does not throw. - */ - void setEvaluateForces(bool bEnabled) - { - data().flags_.set(efSelection_EvaluateForces, bEnabled); - } - - /*! \brief - * Sets the ID for the \p i'th position for use with - * SelectionPosition::mappedId(). - * - * \param[in] i Zero-based index - * \param[in] id Identifier to set. - * - * This method is not part of SelectionPosition because that interface - * only provides access to const data by design. - * - * This method can only be called after compilation, before the - * selection has been evaluated for any frame. - * - * \see SelectionPosition::mappedId() - */ - void setOriginalId(int i, int id); - /*! \brief - * Inits the IDs for use with SelectionPosition::mappedId() for - * grouping. - * - * \param[in] top Topology information - * (can be NULL if not required for \p type). - * \param[in] type Type of groups to generate. - * \returns Number of groups that were present in the selection. - * \throws InconsistentInputError if the selection positions cannot - * be assigned to groups of the given type. - * - * If `type == INDEX_ATOM`, the IDs are initialized to 0, 1, 2, ..., - * and the return value is the number of positions. - * If `type == INDEX_ALL`, all the IDs are initialized to 0, and the - * return value is one. - * If `type == INDEX_RES` or `type == INDEX_MOL`, the first position - * will get ID 0, and all following positions that belong to the same - * residue/molecule will get the same ID. The first position that - * belongs to a different residue/molecule will get ID 1, and so on. - * If some position contains atoms from multiple residues/molecules, - * i.e., the mapping is ambiguous, an exception is thrown. - * The return value is the number of residues/molecules that are - * present in the selection positions. - * - * This method is useful if the calling code needs to group the - * selection, e.g., for computing aggregate properties for each residue - * or molecule. It can then use this method to initialize the - * appropriate grouping, use the return value to allocate a - * sufficiently sized buffer to store the aggregated values, and then - * use SelectionPosition::mappedId() to identify the location where to - * aggregate to. - * - * \see setOriginalId() - * \see SelectionPosition::mappedId() - */ - int initOriginalIdsToGroup(const gmx_mtop_t *top, e_index_t type); - - /*! \brief - * Prints out one-line description of the selection. - * - * \param[in] fp Where to print the information. - * - * The output contains the name of the selection, the number of atoms - * and the number of positions, and indication of whether the selection - * is dynamic. - */ - void printInfo(FILE *fp) const; - /*! \brief - * Prints out extended information about the selection for debugging. - * - * \param[in] fp Where to print the information. - * \param[in] nmaxind Maximum number of values to print in lists - * (-1 = print all). - */ - void printDebugInfo(FILE *fp, int nmaxind) const; - - private: - internal::SelectionData &data() - { - GMX_ASSERT(sel_ != nullptr, - "Attempted to access uninitialized selection"); - return *sel_; - } - const internal::SelectionData &data() const - { - GMX_ASSERT(sel_ != nullptr, - "Attempted to access uninitialized selection"); - return *sel_; - } - - /*! \brief - * Pointer to internal data for the selection. - * - * The memory for this object is managed by a SelectionCollection - * object, and the \ref Selection class simply provides a public - * interface for accessing the data. - */ - internal::SelectionData *sel_; - - /*! \brief - * Needed to access the data to adjust flags. - */ - friend class SelectionOptionStorage; +public: + /*! \brief + * Creates a selection wrapper that has no associated selection. + * + * Any attempt to call methods in the object before a selection is + * assigned results in undefined behavior. + * isValid() returns `false` for the selection until it is initialized. + */ + Selection() : sel_(nullptr) {} + /*! \brief + * Creates a new selection object. + * + * \param sel Selection data to wrap. + * + * Only for internal use by the selection module. + */ + explicit Selection(internal::SelectionData* sel) : sel_(sel) {} + + //! Returns whether the selection object is initialized. + bool isValid() const { return sel_ != nullptr; } + + //! Returns whether two selection objects wrap the same selection. + bool operator==(const Selection& other) const { return sel_ == other.sel_; } + //! Returns whether two selection objects wrap different selections. + bool operator!=(const Selection& other) const { return !operator==(other); } + + //! Returns the name of the selection. + const char* name() const { return data().name(); } + //! Returns the string that was parsed to produce this selection. + const char* selectionText() const { return data().selectionText(); } + //! Returns true if the size of the selection (posCount()) is dynamic. + bool isDynamic() const { return data().isDynamic(); } + //! Returns the type of positions in the selection. + e_index_t type() const { return data().type(); } + //! Returns true if the selection only contains positions with a single atom each. + bool hasOnlyAtoms() const { return data().hasOnlyAtoms(); } + //! Returns `true` if the atom indices in the selection are in ascending order. + bool hasSortedAtomIndices() const { return data().hasSortedAtomIndices(); } + + //! Total number of atoms in the selection. + int atomCount() const { return data().rawPositions_.m.mapb.nra; } + //! Returns atom indices of all atoms in the selection. + ArrayRef atomIndices() const + { + return constArrayRefFromArray(sel_->rawPositions_.m.mapb.a, sel_->rawPositions_.m.mapb.nra); + } + //! Number of positions in the selection. + int posCount() const { return data().posCount(); } + //! Access a single position. + SelectionPosition position(int i) const; + //! Returns coordinates for this selection as a continuous array. + ArrayRef coordinates() const + { + return constArrayRefFromArray(data().rawPositions_.x, posCount()); + } + //! Returns whether velocities are available for this selection. + bool hasVelocities() const { return data().rawPositions_.v != nullptr; } + /*! \brief + * Returns velocities for this selection as a continuous array. + * + * Must not be called if hasVelocities() returns false. + */ + ArrayRef velocities() const + { + GMX_ASSERT(hasVelocities(), "Velocities accessed, but unavailable"); + return constArrayRefFromArray(data().rawPositions_.v, posCount()); + } + //! Returns whether forces are available for this selection. + bool hasForces() const { return sel_->rawPositions_.f != nullptr; } + /*! \brief + * Returns forces for this selection as a continuous array. + * + * Must not be called if hasForces() returns false. + */ + ArrayRef forces() const + { + GMX_ASSERT(hasForces(), "Forces accessed, but unavailable"); + return constArrayRefFromArray(data().rawPositions_.f, posCount()); + } + //! Returns masses for this selection as a continuous array. + ArrayRef masses() const + { + // posMass_ may have more entries than posCount() in the case of + // dynamic selections that don't have a topology + // (and thus the masses and charges are fixed). + GMX_ASSERT(data().posMass_.size() >= static_cast(posCount()), + "Internal inconsistency"); + return makeArrayRef(data().posMass_).subArray(0, posCount()); + } + //! Returns charges for this selection as a continuous array. + ArrayRef charges() const + { + // posCharge_ may have more entries than posCount() in the case of + // dynamic selections that don't have a topology + // (and thus the masses and charges are fixed). + GMX_ASSERT(data().posCharge_.size() >= static_cast(posCount()), + "Internal inconsistency"); + return makeArrayRef(data().posCharge_).subArray(0, posCount()); + } + /*! \brief + * Returns reference IDs for this selection as a continuous array. + * + * \see SelectionPosition::refId() + */ + ArrayRef refIds() const + { + return constArrayRefFromArray(data().rawPositions_.m.refid, posCount()); + } + /*! \brief + * Returns mapped IDs for this selection as a continuous array. + * + * \see SelectionPosition::mappedId() + */ + ArrayRef mappedIds() const + { + return constArrayRefFromArray(data().rawPositions_.m.mapid, posCount()); + } + + //! Returns whether the covered fraction can change between frames. + bool isCoveredFractionDynamic() const { return data().isCoveredFractionDynamic(); } + //! Returns the covered fraction for the current frame. + real coveredFraction() const { return data().coveredFraction_; } + + /*! \brief + * Allows passing a selection directly to neighborhood searching. + * + * When initialized this way, AnalysisNeighborhoodPair objects return + * indices that can be used to index the selection positions with + * position(). + * + * Works exactly like if AnalysisNeighborhoodPositions had a + * constructor taking a Selection object as a parameter. + * See AnalysisNeighborhoodPositions for rationale and additional + * discussion. + */ + operator AnalysisNeighborhoodPositions() const; + + /*! \brief + * Initializes information about covered fractions. + * + * \param[in] type Type of covered fraction required. + * \returns true if the covered fraction can be calculated for the + * selection. + */ + bool initCoveredFraction(e_coverfrac_t type) { return data().initCoveredFraction(type); } + /*! \brief + * Sets whether this selection evaluates velocities for positions. + * + * \param[in] bEnabled If true, velocities are evaluated. + * + * If you request the evaluation, but then evaluate the selection for + * a frame that does not contain velocity information, results are + * undefined. + * + * \todo + * Implement it such that in the above case, hasVelocities() will + * return false for such frames. + * + * Does not throw. + */ + void setEvaluateVelocities(bool bEnabled) + { + data().flags_.set(efSelection_EvaluateVelocities, bEnabled); + } + /*! \brief + * Sets whether this selection evaluates forces for positions. + * + * \param[in] bEnabled If true, forces are evaluated. + * + * If you request the evaluation, but then evaluate the selection for + * a frame that does not contain force information, results are + * undefined. + * + * Does not throw. + */ + void setEvaluateForces(bool bEnabled) + { + data().flags_.set(efSelection_EvaluateForces, bEnabled); + } + + /*! \brief + * Sets the ID for the \p i'th position for use with + * SelectionPosition::mappedId(). + * + * \param[in] i Zero-based index + * \param[in] id Identifier to set. + * + * This method is not part of SelectionPosition because that interface + * only provides access to const data by design. + * + * This method can only be called after compilation, before the + * selection has been evaluated for any frame. + * + * \see SelectionPosition::mappedId() + */ + void setOriginalId(int i, int id); + /*! \brief + * Inits the IDs for use with SelectionPosition::mappedId() for + * grouping. + * + * \param[in] top Topology information + * (can be NULL if not required for \p type). + * \param[in] type Type of groups to generate. + * \returns Number of groups that were present in the selection. + * \throws InconsistentInputError if the selection positions cannot + * be assigned to groups of the given type. + * + * If `type == INDEX_ATOM`, the IDs are initialized to 0, 1, 2, ..., + * and the return value is the number of positions. + * If `type == INDEX_ALL`, all the IDs are initialized to 0, and the + * return value is one. + * If `type == INDEX_RES` or `type == INDEX_MOL`, the first position + * will get ID 0, and all following positions that belong to the same + * residue/molecule will get the same ID. The first position that + * belongs to a different residue/molecule will get ID 1, and so on. + * If some position contains atoms from multiple residues/molecules, + * i.e., the mapping is ambiguous, an exception is thrown. + * The return value is the number of residues/molecules that are + * present in the selection positions. + * + * This method is useful if the calling code needs to group the + * selection, e.g., for computing aggregate properties for each residue + * or molecule. It can then use this method to initialize the + * appropriate grouping, use the return value to allocate a + * sufficiently sized buffer to store the aggregated values, and then + * use SelectionPosition::mappedId() to identify the location where to + * aggregate to. + * + * \see setOriginalId() + * \see SelectionPosition::mappedId() + */ + int initOriginalIdsToGroup(const gmx_mtop_t* top, e_index_t type); + + /*! \brief + * Prints out one-line description of the selection. + * + * \param[in] fp Where to print the information. + * + * The output contains the name of the selection, the number of atoms + * and the number of positions, and indication of whether the selection + * is dynamic. + */ + void printInfo(FILE* fp) const; + /*! \brief + * Prints out extended information about the selection for debugging. + * + * \param[in] fp Where to print the information. + * \param[in] nmaxind Maximum number of values to print in lists + * (-1 = print all). + */ + void printDebugInfo(FILE* fp, int nmaxind) const; + +private: + internal::SelectionData& data() + { + GMX_ASSERT(sel_ != nullptr, "Attempted to access uninitialized selection"); + return *sel_; + } + const internal::SelectionData& data() const + { + GMX_ASSERT(sel_ != nullptr, "Attempted to access uninitialized selection"); + return *sel_; + } + + /*! \brief + * Pointer to internal data for the selection. + * + * The memory for this object is managed by a SelectionCollection + * object, and the \ref Selection class simply provides a public + * interface for accessing the data. + */ + internal::SelectionData* sel_; + + /*! \brief + * Needed to access the data to adjust flags. + */ + friend class SelectionOptionStorage; }; /*! \brief @@ -606,178 +591,154 @@ class Selection */ class SelectionPosition { - public: - /*! \brief - * Constructs a wrapper object for given selection position. - * - * \param[in] sel Selection from which the position is wrapped. - * \param[in] index Zero-based index of the position to wrap. - * - * Asserts if \p index is out of range. - * - * Only for internal use of the library. To obtain a SelectionPosition - * object in other code, use Selection::position(). - */ - SelectionPosition(const internal::SelectionData &sel, int index) - : sel_(&sel), i_(index) +public: + /*! \brief + * Constructs a wrapper object for given selection position. + * + * \param[in] sel Selection from which the position is wrapped. + * \param[in] index Zero-based index of the position to wrap. + * + * Asserts if \p index is out of range. + * + * Only for internal use of the library. To obtain a SelectionPosition + * object in other code, use Selection::position(). + */ + SelectionPosition(const internal::SelectionData& sel, int index) : sel_(&sel), i_(index) + { + GMX_ASSERT(index >= 0 && index < sel.posCount(), "Invalid selection position index"); + } + + /*! \brief + * Returns type of this position. + * + * Currently always returns the same as Selection::type(). + */ + e_index_t type() const { return sel_->type(); } + //! Returns coordinates for this position. + const rvec& x() const { return sel_->rawPositions_.x[i_]; } + /*! \brief + * Returns velocity for this position. + * + * Must not be called if Selection::hasVelocities() returns false. + */ + const rvec& v() const + { + GMX_ASSERT(sel_->rawPositions_.v != nullptr, "Velocities accessed, but unavailable"); + return sel_->rawPositions_.v[i_]; + } + /*! \brief + * Returns force for this position. + * + * Must not be called if Selection::hasForces() returns false. + */ + const rvec& f() const + { + GMX_ASSERT(sel_->rawPositions_.f != nullptr, "Velocities accessed, but unavailable"); + return sel_->rawPositions_.f[i_]; + } + /*! \brief + * Returns total mass for this position. + * + * Returns the total mass of atoms that make up this position. + * If there are no atoms associated or masses are not available, + * returns unity. + */ + real mass() const { return sel_->posMass_[i_]; } + /*! \brief + * Returns total charge for this position. + * + * Returns the sum of charges of atoms that make up this position. + * If there are no atoms associated or charges are not available, + * returns zero. + */ + real charge() const { return sel_->posCharge_[i_]; } + //! Returns the number of atoms that make up this position. + int atomCount() const + { + return sel_->rawPositions_.m.mapb.index[i_ + 1] - sel_->rawPositions_.m.mapb.index[i_]; + } + //! Return atom indices that make up this position. + ArrayRef atomIndices() const + { + const int* atoms = sel_->rawPositions_.m.mapb.a; + if (atoms == nullptr) { - GMX_ASSERT(index >= 0 && index < sel.posCount(), - "Invalid selection position index"); + return ArrayRef(); } - - /*! \brief - * Returns type of this position. - * - * Currently always returns the same as Selection::type(). - */ - e_index_t type() const { return sel_->type(); } - //! Returns coordinates for this position. - const rvec &x() const - { - return sel_->rawPositions_.x[i_]; - } - /*! \brief - * Returns velocity for this position. - * - * Must not be called if Selection::hasVelocities() returns false. - */ - const rvec &v() const - { - GMX_ASSERT(sel_->rawPositions_.v != nullptr, - "Velocities accessed, but unavailable"); - return sel_->rawPositions_.v[i_]; - } - /*! \brief - * Returns force for this position. - * - * Must not be called if Selection::hasForces() returns false. - */ - const rvec &f() const - { - GMX_ASSERT(sel_->rawPositions_.f != nullptr, - "Velocities accessed, but unavailable"); - return sel_->rawPositions_.f[i_]; - } - /*! \brief - * Returns total mass for this position. - * - * Returns the total mass of atoms that make up this position. - * If there are no atoms associated or masses are not available, - * returns unity. - */ - real mass() const - { - return sel_->posMass_[i_]; - } - /*! \brief - * Returns total charge for this position. - * - * Returns the sum of charges of atoms that make up this position. - * If there are no atoms associated or charges are not available, - * returns zero. - */ - real charge() const - { - return sel_->posCharge_[i_]; - } - //! Returns the number of atoms that make up this position. - int atomCount() const - { - return sel_->rawPositions_.m.mapb.index[i_ + 1] - - sel_->rawPositions_.m.mapb.index[i_]; - } - //! Return atom indices that make up this position. - ArrayRef atomIndices() const - { - const int *atoms = sel_->rawPositions_.m.mapb.a; - if (atoms == nullptr) - { - return ArrayRef(); - } - const int first = sel_->rawPositions_.m.mapb.index[i_]; - return constArrayRefFromArray(&atoms[first], atomCount()); - } - /*! \brief - * Returns whether this position is selected in the current frame. - * - * The return value is equivalent to \c refid() == -1. Returns always - * true if SelectionOption::dynamicMask() has not been set. - * - * \see refId() - */ - bool selected() const - { - return refId() >= 0; - } - /*! \brief - * Returns reference ID for this position. - * - * For dynamic selections, this provides means to associate positions - * across frames. After compilation, these IDs are consequently - * numbered starting from zero. For each frame, the ID then reflects - * the location of the position in the original array of positions. - * If SelectionOption::dynamicMask() has been set for the parent - * selection, the IDs for positions not present in the current - * selection are set to -1, otherwise they are removed completely. - * - * Example: - * If a dynamic selection consists of at most three positions, after - * compilation refId() will return 0, 1, 2 for them, respectively. - * If for a particular frame, only the first and the third are present, - * refId() will return 0, 2. - * If SelectionOption::dynamicMask() has been set, all three positions - * can be accessed also for that frame and refId() will return 0, -1, - * 2. - */ - int refId() const - { - return sel_->rawPositions_.m.refid[i_]; - } - /*! \brief - * Returns mapped ID for this position. - * - * Returns ID of the position that corresponds to that set with - * Selection::setOriginalId(). - * - * If for an array \c id, \c setOriginalId(i, id[i]) has been called - * for each \c i, then it always holds that - * \c mappedId()==id[refId()]. - * - * Selection::setOriginalId() has not been called, the default values - * are dependent on type(): - * - ::INDEX_ATOM: atom indices - * - ::INDEX_RES: residue indices - * - ::INDEX_MOL: molecule indices - * . - * All the default values are zero-based. - */ - int mappedId() const - { - return sel_->rawPositions_.m.mapid[i_]; - } - - /*! \brief - * Allows passing a selection position directly to neighborhood searching. - * - * When initialized this way, AnalysisNeighborhoodPair objects return - * the index that can be used to access this position using - * Selection::position(). - * - * Works exactly like if AnalysisNeighborhoodPositions had a - * constructor taking a SelectionPosition object as a parameter. - * See AnalysisNeighborhoodPositions for rationale and additional - * discussion. - */ - operator AnalysisNeighborhoodPositions() const; - - private: - const internal::SelectionData *sel_; - int i_; + const int first = sel_->rawPositions_.m.mapb.index[i_]; + return constArrayRefFromArray(&atoms[first], atomCount()); + } + /*! \brief + * Returns whether this position is selected in the current frame. + * + * The return value is equivalent to \c refid() == -1. Returns always + * true if SelectionOption::dynamicMask() has not been set. + * + * \see refId() + */ + bool selected() const { return refId() >= 0; } + /*! \brief + * Returns reference ID for this position. + * + * For dynamic selections, this provides means to associate positions + * across frames. After compilation, these IDs are consequently + * numbered starting from zero. For each frame, the ID then reflects + * the location of the position in the original array of positions. + * If SelectionOption::dynamicMask() has been set for the parent + * selection, the IDs for positions not present in the current + * selection are set to -1, otherwise they are removed completely. + * + * Example: + * If a dynamic selection consists of at most three positions, after + * compilation refId() will return 0, 1, 2 for them, respectively. + * If for a particular frame, only the first and the third are present, + * refId() will return 0, 2. + * If SelectionOption::dynamicMask() has been set, all three positions + * can be accessed also for that frame and refId() will return 0, -1, + * 2. + */ + int refId() const { return sel_->rawPositions_.m.refid[i_]; } + /*! \brief + * Returns mapped ID for this position. + * + * Returns ID of the position that corresponds to that set with + * Selection::setOriginalId(). + * + * If for an array \c id, \c setOriginalId(i, id[i]) has been called + * for each \c i, then it always holds that + * \c mappedId()==id[refId()]. + * + * Selection::setOriginalId() has not been called, the default values + * are dependent on type(): + * - ::INDEX_ATOM: atom indices + * - ::INDEX_RES: residue indices + * - ::INDEX_MOL: molecule indices + * . + * All the default values are zero-based. + */ + int mappedId() const { return sel_->rawPositions_.m.mapid[i_]; } + + /*! \brief + * Allows passing a selection position directly to neighborhood searching. + * + * When initialized this way, AnalysisNeighborhoodPair objects return + * the index that can be used to access this position using + * Selection::position(). + * + * Works exactly like if AnalysisNeighborhoodPositions had a + * constructor taking a SelectionPosition object as a parameter. + * See AnalysisNeighborhoodPositions for rationale and additional + * discussion. + */ + operator AnalysisNeighborhoodPositions() const; + +private: + const internal::SelectionData* sel_; + int i_; }; -inline SelectionPosition -Selection::position(int i) const +inline SelectionPosition Selection::position(int i) const { return SelectionPosition(data(), i); } diff --git a/src/gromacs/selection/selectioncollection.cpp b/src/gromacs/selection/selectioncollection.cpp index bd45bcb90d..4b78f54362 100644 --- a/src/gromacs/selection/selectioncollection.cpp +++ b/src/gromacs/selection/selectioncollection.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -83,15 +84,14 @@ namespace gmx * SelectionCollection::Impl */ -SelectionCollection::Impl::Impl() - : debugLevel_(0), bExternalGroupsSet_(false), grps_(nullptr) +SelectionCollection::Impl::Impl() : debugLevel_(0), bExternalGroupsSet_(false), grps_(nullptr) { - sc_.nvars = 0; - sc_.varstrs = nullptr; - sc_.top = nullptr; + sc_.nvars = 0; + sc_.varstrs = nullptr; + sc_.top = nullptr; gmx_ana_index_clear(&sc_.gall); - sc_.mempool = nullptr; - sc_.symtab = std::make_unique(); + sc_.mempool = nullptr; + sc_.symtab = std::make_unique(); gmx_ana_index_clear(&requiredAtoms_); gmx_ana_selmethod_register_defaults(sc_.symtab.get()); } @@ -118,8 +118,7 @@ SelectionCollection::Impl::~Impl() } -void -SelectionCollection::Impl::clearSymbolTable() +void SelectionCollection::Impl::clearSymbolTable() { sc_.symtab.reset(); } @@ -138,8 +137,7 @@ namespace * * Handles line continuation, reading also the continuing line(s) in one call. */ -bool promptLine(TextInputStream *inputStream, TextWriter *statusWriter, - std::string *line) +bool promptLine(TextInputStream* inputStream, TextWriter* statusWriter, std::string* line) { if (statusWriter != nullptr) { @@ -184,10 +182,9 @@ bool promptLine(TextInputStream *inputStream, TextWriter *statusWriter, * \p parserState until there is no more input, or until enough input is given * (only in interactive mode). */ -int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate *parserState, - bool bInteractive) +int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate* parserState, bool bInteractive) { - int status = YYPUSH_MORE; + int status = YYPUSH_MORE; do { YYSTYPE value; @@ -198,8 +195,7 @@ int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate *parserState, break; } status = _gmx_sel_yypush_parse(parserState, token, &value, &location, scanner); - } - while (status == YYPUSH_MORE); + } while (status == YYPUSH_MORE); _gmx_sel_lexer_rethrow_exception_if_occurred(scanner); return status; } @@ -219,9 +215,13 @@ int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate *parserState, * * Prints the available index groups and currently provided selections. */ -void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc, - gmx_ana_indexgrps_t *grps, size_t firstSelection, - int maxCount, const std::string &context, bool bFirst) +void printCurrentStatus(TextWriter* writer, + gmx_ana_selcollection_t* sc, + gmx_ana_indexgrps_t* grps, + size_t firstSelection, + int maxCount, + const std::string& context, + bool bFirst) { if (grps != nullptr) { @@ -241,11 +241,10 @@ void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc, { writer->writeString(formatString("%d selections", maxCount)); } - writer->writeString(formatString("%s%s:\n", - context.empty() ? "" : " ", context.c_str())); - writer->writeString(formatString( - "(one per line, for status/groups, 'help' for help%s)\n", - maxCount < 0 ? ", Ctrl-D to end" : "")); + writer->writeString(formatString("%s%s:\n", context.empty() ? "" : " ", context.c_str())); + writer->writeString( + formatString("(one per line, for status/groups, 'help' for help%s)\n", + maxCount < 0 ? ", Ctrl-D to end" : "")); if (!bFirst && (sc->nvars > 0 || sc->sel.size() > firstSelection)) { writer->writeLine("Currently provided selections:"); @@ -255,18 +254,14 @@ void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc, } for (size_t i = firstSelection; i < sc->sel.size(); ++i) { - writer->writeString(formatString( - " %2d. %s\n", - static_cast(i - firstSelection + 1), - sc->sel[i]->selectionText())); + writer->writeString(formatString(" %2d. %s\n", static_cast(i - firstSelection + 1), + sc->sel[i]->selectionText())); } if (maxCount > 0) { - const int remaining - = maxCount - static_cast(sc->sel.size() - firstSelection); - writer->writeString(formatString( - "(%d more selection%s required)\n", - remaining, remaining > 1 ? "s" : "")); + const int remaining = maxCount - static_cast(sc->sel.size() - firstSelection); + writer->writeString(formatString("(%d more selection%s required)\n", remaining, + remaining > 1 ? "s" : "")); } } } @@ -281,8 +276,7 @@ void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc, * Initializes the selection help if not yet initialized, and finds the help * topic based on words on the input line. */ -void printHelp(TextWriter *writer, gmx_ana_selcollection_t *sc, - const std::string &line) +void printHelp(TextWriter* writer, gmx_ana_selcollection_t* sc, const std::string& line) { if (sc->rootHelp.get() == nullptr) { @@ -300,7 +294,7 @@ void printHelp(TextWriter *writer, gmx_ana_selcollection_t *sc, manager.enterTopic(*value); } } - catch (const InvalidInputError &ex) + catch (const InvalidInputError& ex) { writer->writeLine(ex.what()); return; @@ -327,20 +321,22 @@ void printHelp(TextWriter *writer, gmx_ana_selcollection_t *sc, * Used internally to implement parseInteractive(), parseFromFile() and * parseFromString(). */ -SelectionList runParser(yyscan_t scanner, TextInputStream *inputStream, - bool bInteractive, int maxnr, const std::string &context) +SelectionList runParser(yyscan_t scanner, + TextInputStream* inputStream, + bool bInteractive, + int maxnr, + const std::string& context) { std::shared_ptr scannerGuard(scanner, &_gmx_sel_free_lexer); - gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); - gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner); + gmx_ana_selcollection_t* sc = _gmx_sel_lexer_selcollection(scanner); + gmx_ana_indexgrps_t* grps = _gmx_sel_lexer_indexgrps(scanner); - size_t oldCount = sc->sel.size(); + size_t oldCount = sc->sel.size(); { - std::shared_ptr<_gmx_sel_yypstate> parserState( - _gmx_sel_yypstate_new(), &_gmx_sel_yypstate_delete); + std::shared_ptr<_gmx_sel_yypstate> parserState(_gmx_sel_yypstate_new(), &_gmx_sel_yypstate_delete); if (bInteractive) { - TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner); + TextWriter* statusWriter = _gmx_sel_lexer_get_status_writer(scanner); if (statusWriter != nullptr) { printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, true); @@ -357,8 +353,7 @@ SelectionList runParser(yyscan_t scanner, TextInputStream *inputStream, printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, false); continue; } - if (startsWith(line, "help") - && (line[4] == 0 || (std::isspace(line[4]) != 0))) + if (startsWith(line, "help") && (line[4] == 0 || (std::isspace(line[4]) != 0))) { printHelp(statusWriter, sc, line); continue; @@ -376,29 +371,24 @@ SelectionList runParser(yyscan_t scanner, TextInputStream *inputStream, } { YYLTYPE location; - status = _gmx_sel_yypush_parse(parserState.get(), 0, nullptr, - &location, scanner); + status = _gmx_sel_yypush_parse(parserState.get(), 0, nullptr, &location, scanner); } // TODO: Remove added selections from the collection if parsing failed? _gmx_sel_lexer_rethrow_exception_if_occurred(scanner); -early_termination: - GMX_RELEASE_ASSERT(status == 0, - "Parser errors should have resulted in an exception"); + early_termination: + GMX_RELEASE_ASSERT(status == 0, "Parser errors should have resulted in an exception"); } else { int status = runParserLoop(scanner, parserState.get(), false); - GMX_RELEASE_ASSERT(status == 0, - "Parser errors should have resulted in an exception"); + GMX_RELEASE_ASSERT(status == 0, "Parser errors should have resulted in an exception"); } } scannerGuard.reset(); int nr = sc->sel.size() - oldCount; if (maxnr > 0 && nr != maxnr) { - std::string message - = formatString("Too few selections provided; got %d, expected %d", - nr, maxnr); + std::string message = formatString("Too few selections provided; got %d, expected %d", nr, maxnr); GMX_THROW(InvalidInputError(message)); } @@ -426,9 +416,7 @@ early_termination: * the topology/maximum number of atoms set for the selection collection. * Any issues are reported to \p errors. */ -void checkExternalGroups(const SelectionTreeElementPointer &root, - int natoms, - ExceptionInitializer *errors) +void checkExternalGroups(const SelectionTreeElementPointer& root, int natoms, ExceptionInitializer* errors) { if (root->type == SEL_CONST && root->v.type == GROUP_VALUE) { @@ -436,7 +424,7 @@ void checkExternalGroups(const SelectionTreeElementPointer &root, { root->checkIndexGroup(natoms); } - catch (const UserInputError &) + catch (const UserInputError&) { errors->addCurrentExceptionAsNested(); } @@ -451,29 +439,29 @@ void checkExternalGroups(const SelectionTreeElementPointer &root, } //! Checks whether the given topology properties are available. -void checkTopologyProperties(const gmx_mtop_t *top, - const SelectionTopologyProperties &props) +void checkTopologyProperties(const gmx_mtop_t* top, const SelectionTopologyProperties& props) { if (top == nullptr) { if (props.hasAny()) { - GMX_THROW(InconsistentInputError("Selection requires topology information, but none provided")); + GMX_THROW(InconsistentInputError( + "Selection requires topology information, but none provided")); } return; } if (props.needsMasses && !gmx_mtop_has_masses(top)) { - GMX_THROW(InconsistentInputError("Selection requires mass information, but it is not available in the topology")); + GMX_THROW(InconsistentInputError( + "Selection requires mass information, but it is not available in the topology")); } } -} // namespace +} // namespace -void SelectionCollection::Impl::resolveExternalGroups( - const SelectionTreeElementPointer &root, - ExceptionInitializer *errors) +void SelectionCollection::Impl::resolveExternalGroups(const SelectionTreeElementPointer& root, + ExceptionInitializer* errors) { if (root->type == SEL_GROUPREF) @@ -482,7 +470,7 @@ void SelectionCollection::Impl::resolveExternalGroups( { root->resolveIndexGroupReference(grps_, sc_.gall.isize); } - catch (const UserInputError &) + catch (const UserInputError&) { errors->addCurrentExceptionAsNested(); } @@ -493,14 +481,14 @@ void SelectionCollection::Impl::resolveExternalGroups( { resolveExternalGroups(child, errors); root->flags |= (child->flags & SEL_UNSORTED); - child = child->next; + child = child->next; } } bool SelectionCollection::Impl::areForcesRequested() const { - for (const auto &sel : sc_.sel) + for (const auto& sel : sc_.sel) { if (sel->hasFlag(gmx::efSelection_EvaluateForces)) { @@ -512,16 +500,14 @@ bool SelectionCollection::Impl::areForcesRequested() const SelectionTopologyProperties -SelectionCollection::Impl::requiredTopologyPropertiesForPositionType( - const std::string &post, bool forces) const +SelectionCollection::Impl::requiredTopologyPropertiesForPositionType(const std::string& post, bool forces) const { SelectionTopologyProperties props; if (!post.empty()) { switch (PositionCalculationCollection::requiredTopologyInfoForType(post.c_str(), forces)) { - case PositionCalculationCollection::RequiredTopologyInfo::None: - break; + case PositionCalculationCollection::RequiredTopologyInfo::None: break; case PositionCalculationCollection::RequiredTopologyInfo::Topology: props.merge(SelectionTopologyProperties::topology()); break; @@ -538,35 +524,29 @@ SelectionCollection::Impl::requiredTopologyPropertiesForPositionType( * SelectionCollection */ -SelectionCollection::SelectionCollection() - : impl_(new Impl) -{ -} +SelectionCollection::SelectionCollection() : impl_(new Impl) {} -SelectionCollection::~SelectionCollection() -{ -} +SelectionCollection::~SelectionCollection() {} -void -SelectionCollection::initOptions(IOptionsContainer *options, - SelectionTypeOption selectionTypeOption) +void SelectionCollection::initOptions(IOptionsContainer* options, SelectionTypeOption selectionTypeOption) { - const char * const debug_levels[] - = { "no", "basic", "compile", "eval", "full" }; + const char* const debug_levels[] = { "no", "basic", "compile", "eval", "full" }; - const char *const *postypes = PositionCalculationCollection::typeEnumValues; + const char* const* postypes = PositionCalculationCollection::typeEnumValues; options->addOption(StringOption("selrpos") - .enumValueFromNullTerminatedArray(postypes) - .store(&impl_->rpost_).defaultValue(postypes[0]) - .description("Selection reference positions")); + .enumValueFromNullTerminatedArray(postypes) + .store(&impl_->rpost_) + .defaultValue(postypes[0]) + .description("Selection reference positions")); if (selectionTypeOption == IncludeSelectionTypeOption) { options->addOption(StringOption("seltype") - .enumValueFromNullTerminatedArray(postypes) - .store(&impl_->spost_).defaultValue(postypes[0]) - .description("Default selection output positions")); + .enumValueFromNullTerminatedArray(postypes) + .store(&impl_->spost_) + .defaultValue(postypes[0]) + .description("Default selection output positions")); } else { @@ -574,45 +554,43 @@ SelectionCollection::initOptions(IOptionsContainer *options, } GMX_RELEASE_ASSERT(impl_->debugLevel_ >= 0 && impl_->debugLevel_ <= 4, "Debug level out of range"); - options->addOption(EnumIntOption("seldebug").hidden(impl_->debugLevel_ == 0) - .enumValue(debug_levels).store(&impl_->debugLevel_) - .description("Print out selection trees for debugging")); + options->addOption(EnumIntOption("seldebug") + .hidden(impl_->debugLevel_ == 0) + .enumValue(debug_levels) + .store(&impl_->debugLevel_) + .description("Print out selection trees for debugging")); } -void -SelectionCollection::setReferencePosType(const char *type) +void SelectionCollection::setReferencePosType(const char* type) { GMX_RELEASE_ASSERT(type != nullptr, "Cannot assign NULL position type"); // Check that the type is valid, throw if it is not. - e_poscalc_t dummytype; - int dummyflags; + e_poscalc_t dummytype; + int dummyflags; PositionCalculationCollection::typeFromEnum(type, &dummytype, &dummyflags); impl_->rpost_ = type; } -void -SelectionCollection::setOutputPosType(const char *type) +void SelectionCollection::setOutputPosType(const char* type) { GMX_RELEASE_ASSERT(type != nullptr, "Cannot assign NULL position type"); // Check that the type is valid, throw if it is not. - e_poscalc_t dummytype; - int dummyflags; + e_poscalc_t dummytype; + int dummyflags; PositionCalculationCollection::typeFromEnum(type, &dummytype, &dummyflags); impl_->spost_ = type; } -void -SelectionCollection::setDebugLevel(int debugLevel) +void SelectionCollection::setDebugLevel(int debugLevel) { impl_->debugLevel_ = debugLevel; } -void -SelectionCollection::setTopology(gmx_mtop_t *top, int natoms) +void SelectionCollection::setTopology(gmx_mtop_t* top, int natoms) { GMX_RELEASE_ASSERT(natoms > 0 || top != nullptr, "The number of atoms must be given if there is no topology"); @@ -636,7 +614,7 @@ SelectionCollection::setTopology(gmx_mtop_t *top, int natoms) GMX_THROW(InconsistentInputError(errors)); } } - gmx_ana_selcollection_t *sc = &impl_->sc_; + gmx_ana_selcollection_t* sc = &impl_->sc_; // Do this first, as it allocates memory, while the others don't throw. gmx_ana_index_init_simple(&sc->gall, natoms); sc->top = top; @@ -644,8 +622,7 @@ SelectionCollection::setTopology(gmx_mtop_t *top, int natoms) } -void -SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t *grps) +void SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t* grps) { GMX_RELEASE_ASSERT(grps == nullptr || !impl_->bExternalGroupsSet_, "Can only set external groups once or clear them afterwards"); @@ -670,16 +647,14 @@ SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t *grps) } } -SelectionTopologyProperties -SelectionCollection::requiredTopologyProperties() const +SelectionTopologyProperties SelectionCollection::requiredTopologyProperties() const { SelectionTopologyProperties props; // These should not throw, because has been checked earlier. props.merge(impl_->requiredTopologyPropertiesForPositionType(impl_->rpost_, false)); const bool forcesRequested = impl_->areForcesRequested(); - props.merge(impl_->requiredTopologyPropertiesForPositionType(impl_->spost_, - forcesRequested)); + props.merge(impl_->requiredTopologyPropertiesForPositionType(impl_->spost_, forcesRequested)); SelectionTreeElementPointer sel = impl_->sc_.root; while (sel && !props.hasAll()) @@ -691,8 +666,7 @@ SelectionCollection::requiredTopologyProperties() const } -bool -SelectionCollection::requiresIndexGroups() const +bool SelectionCollection::requiresIndexGroups() const { SelectionTreeElementPointer sel = impl_->sc_.root; while (sel) @@ -707,20 +681,17 @@ SelectionCollection::requiresIndexGroups() const } -SelectionList -SelectionCollection::parseFromStdin(int count, bool bInteractive, - const std::string &context) +SelectionList SelectionCollection::parseFromStdin(int count, bool bInteractive, const std::string& context) { return parseInteractive(count, &StandardInputStream::instance(), - bInteractive ? &TextOutputFile::standardError() : nullptr, - context); + bInteractive ? &TextOutputFile::standardError() : nullptr, context); } namespace { //! Helper function to initialize status writer for interactive selection parsing. -std::unique_ptr initStatusWriter(TextOutputStream *statusStream) +std::unique_ptr initStatusWriter(TextOutputStream* statusStream) { std::unique_ptr statusWriter; if (statusStream != nullptr) @@ -731,26 +702,23 @@ std::unique_ptr initStatusWriter(TextOutputStream *statusStream) return statusWriter; } -} // namespace +} // namespace -SelectionList -SelectionCollection::parseInteractive(int count, - TextInputStream *inputStream, - TextOutputStream *statusStream, - const std::string &context) +SelectionList SelectionCollection::parseInteractive(int count, + TextInputStream* inputStream, + TextOutputStream* statusStream, + const std::string& context) { yyscan_t scanner; - const std::unique_ptr statusWriter( - initStatusWriter(statusStream)); - _gmx_sel_init_lexer(&scanner, &impl_->sc_, statusWriter.get(), - count, impl_->bExternalGroupsSet_, impl_->grps_); + const std::unique_ptr statusWriter(initStatusWriter(statusStream)); + _gmx_sel_init_lexer(&scanner, &impl_->sc_, statusWriter.get(), count, + impl_->bExternalGroupsSet_, impl_->grps_); return runParser(scanner, inputStream, true, count, context); } -SelectionList -SelectionCollection::parseFromFile(const std::string &filename) +SelectionList SelectionCollection::parseFromFile(const std::string& filename) { try @@ -758,37 +726,29 @@ SelectionCollection::parseFromFile(const std::string &filename) yyscan_t scanner; TextInputFile file(filename); // TODO: Exception-safe way of using the lexer. - _gmx_sel_init_lexer(&scanner, &impl_->sc_, nullptr, -1, - impl_->bExternalGroupsSet_, - impl_->grps_); + _gmx_sel_init_lexer(&scanner, &impl_->sc_, nullptr, -1, impl_->bExternalGroupsSet_, impl_->grps_); _gmx_sel_set_lex_input_file(scanner, file.handle()); return runParser(scanner, nullptr, false, -1, std::string()); } - catch (GromacsException &ex) + catch (GromacsException& ex) { - ex.prependContext(formatString( - "Error in parsing selections from file '%s'", - filename.c_str())); + ex.prependContext(formatString("Error in parsing selections from file '%s'", filename.c_str())); throw; } } -SelectionList -SelectionCollection::parseFromString(const std::string &str) +SelectionList SelectionCollection::parseFromString(const std::string& str) { yyscan_t scanner; - _gmx_sel_init_lexer(&scanner, &impl_->sc_, nullptr, -1, - impl_->bExternalGroupsSet_, - impl_->grps_); + _gmx_sel_init_lexer(&scanner, &impl_->sc_, nullptr, -1, impl_->bExternalGroupsSet_, impl_->grps_); _gmx_sel_set_lex_input_str(scanner, str.c_str()); return runParser(scanner, nullptr, false, -1, std::string()); } -void -SelectionCollection::compile() +void SelectionCollection::compile() { checkTopologyProperties(impl_->sc_.top, requiredTopologyProperties()); if (!impl_->bExternalGroupsSet_) @@ -823,15 +783,15 @@ SelectionCollection::compile() SelectionDataList::const_iterator iter; for (iter = impl_->sc_.sel.begin(); iter != impl_->sc_.sel.end(); ++iter) { - const internal::SelectionData &sel = **iter; + const internal::SelectionData& sel = **iter; if (sel.hasFlag(efSelection_OnlyAtoms)) { if (!sel.hasOnlyAtoms()) { std::string message = formatString( - "Selection '%s' does not evaluate to individual atoms. " - "This is not allowed in this context.", - sel.selectionText()); + "Selection '%s' does not evaluate to individual atoms. " + "This is not allowed in this context.", + sel.selectionText()); GMX_THROW(InvalidInputError(message)); } if (sel.hasFlag(efSelection_OnlySorted)) @@ -839,10 +799,10 @@ SelectionCollection::compile() if (!sel.hasSortedAtomIndices()) { const std::string message = formatString( - "Selection '%s' does not evaluate to atoms in an " - "ascending (sorted) order. " - "This is not allowed in this context.", - sel.selectionText()); + "Selection '%s' does not evaluate to atoms in an " + "ascending (sorted) order. " + "This is not allowed in this context.", + sel.selectionText()); GMX_THROW(InvalidInputError(message)); } } @@ -851,9 +811,8 @@ SelectionCollection::compile() { if (sel.posCount() == 0) { - std::string message = formatString( - "Selection '%s' never matches any atoms.", - sel.selectionText()); + std::string message = + formatString("Selection '%s' never matches any atoms.", sel.selectionText()); GMX_THROW(InvalidInputError(message)); } } @@ -863,8 +822,7 @@ SelectionCollection::compile() } -void -SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc) +void SelectionCollection::evaluate(t_trxframe* fr, t_pbc* pbc) { checkTopologyProperties(impl_->sc_.top, requiredTopologyProperties()); if (fr->bIndex) @@ -877,8 +835,8 @@ SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc) if (!gmx_ana_index_contains(&g, &impl_->requiredAtoms_)) { const std::string message = formatString( - "Trajectory does not contain all atoms required for " - "evaluating the provided selections."); + "Trajectory does not contain all atoms required for " + "evaluating the provided selections."); GMX_THROW(InconsistentInputError(message)); } } @@ -888,9 +846,10 @@ SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc) if (fr->natoms <= maxAtomIndex) { const std::string message = formatString( - "Trajectory has less atoms (%d) than what is required for " - "evaluating the provided selections (atoms up to index %d " - "are required).", fr->natoms, maxAtomIndex + 1); + "Trajectory has less atoms (%d) than what is required for " + "evaluating the provided selections (atoms up to index %d " + "are required).", + fr->natoms, maxAtomIndex + 1); GMX_THROW(InconsistentInputError(message)); } } @@ -907,16 +866,14 @@ SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc) } -void -SelectionCollection::evaluateFinal(int nframes) +void SelectionCollection::evaluateFinal(int nframes) { SelectionEvaluator evaluator; evaluator.evaluateFinal(this, nframes); } -void -SelectionCollection::printTree(FILE *fp, bool bValues) const +void SelectionCollection::printTree(FILE* fp, bool bValues) const { SelectionTreeElementPointer sel = impl_->sc_.root; while (sel) @@ -927,10 +884,9 @@ SelectionCollection::printTree(FILE *fp, bool bValues) const } -void -SelectionCollection::printXvgrInfo(FILE *out) const +void SelectionCollection::printXvgrInfo(FILE* out) const { - const gmx_ana_selcollection_t &sc = impl_->sc_; + const gmx_ana_selcollection_t& sc = impl_->sc_; std::fprintf(out, "# Selections:\n"); for (int i = 0; i < sc.nvars; ++i) { diff --git a/src/gromacs/selection/selectioncollection.h b/src/gromacs/selection/selectioncollection.h index 44bb7e7727..3545171137 100644 --- a/src/gromacs/selection/selectioncollection.h +++ b/src/gromacs/selection/selectioncollection.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -113,317 +113,316 @@ struct SelectionTopologyProperties; */ class SelectionCollection { - public: - //! Flag for initOptions() to select how to behave with -seltype option. - enum SelectionTypeOption - { - /*! \brief - * Add the option for the user to select default value for - * setOutputPosType(). - */ - IncludeSelectionTypeOption, - /*! \brief - * Do not add the option, selections will always select atoms by - * default. - */ - AlwaysAtomSelections - }; - +public: + //! Flag for initOptions() to select how to behave with -seltype option. + enum SelectionTypeOption + { /*! \brief - * Creates an empty selection collection. - * - * \throws std::bad_alloc if out of memory. + * Add the option for the user to select default value for + * setOutputPosType(). */ - SelectionCollection(); - ~SelectionCollection(); - + IncludeSelectionTypeOption, /*! \brief - * Initializes options for setting global properties on the collection. - * - * \param[in,out] options Options object to initialize. - * \param[in] selectionTypeOption - * Whether to add option to influence setOutputPosType(). - * \throws std::bad_alloc if out of memory. - * - * Adds options to \p options that can be used to set the default - * position types (see setReferencePosType() and setOutputPosType()) - * and debugging flags. + * Do not add the option, selections will always select atoms by + * default. */ - void initOptions(IOptionsContainer *options, SelectionTypeOption selectionTypeOption); + AlwaysAtomSelections + }; - /*! \brief - * Sets the default reference position handling for a selection - * collection. - * - * \param[in] type Default selection reference position type - * (one of the strings acceptable for - * PositionCalculationCollection::typeFromEnum()). - * \throws InternalError if \p type is invalid. - * - * Should be called before calling the parser functions, unless - * initOptions() has been called. In the latter case, can still be - * used to override the default value (before initOptions() is called) - * and/or the value provided through the Options object. - * - * Strong exception safety. - */ - void setReferencePosType(const char *type); - /*! \brief - * Sets the default reference position handling for a selection - * collection. - * - * \param[in] type Default selection output position type - * (one of the strings acceptable for - * PositionCalculationCollection::typeFromEnum()). - * \throws InternalError if \p type is invalid. - * - * Should be called before calling the parser functions, unless - * initOptions() has been called. In the latter case, can still be - * used to override the default value (before initOptions() is called) - * and/or the value provided through the Options object. - * - * Strong exception safety. - */ - void setOutputPosType(const char *type); - /*! \brief - * Sets the debugging level for the selection collection. - * - * \param[in] debugLevel Debug level to set (0 = no debug - * information). - * - * initOptions() creates debugging options that can also be used to set - * the debug level. These are normally hidden, but if this method is - * called before initOptions() with a non-zero \p debugLevel, they are - * made visible. - * - * Mostly useful for debugging tools. - * - * Does not throw. - */ - void setDebugLevel(int debugLevel); + /*! \brief + * Creates an empty selection collection. + * + * \throws std::bad_alloc if out of memory. + */ + SelectionCollection(); + ~SelectionCollection(); - /*! \brief - * Returns what topology information is required for evaluation. - * - * \returns What topology information is required for compiling and/or - * evaluating the selections in the collection. - * - * Before the parser functions have been called, the return value is - * based just on the position types set. - * After parser functions have been called, the return value also takes - * into account the selection keywords used. - * After the compiler has been called, the return value is final and - * also considers possible force evaluation requested for the - * selections. - * - * Does not throw. - */ - SelectionTopologyProperties requiredTopologyProperties() const; - /*! \brief - * Returns true if the collection requires external index groups. - * - * \returns true if any selection has an unresolved index group reference. - * - * The return value is `false` after setIndexGroups() has been called. - * - * Does not throw. - */ - bool requiresIndexGroups() const; - /*! \brief - * Sets the topology for the collection. - * - * \param[in] top Topology data. - * \param[in] natoms Number of atoms. If <=0, the number of - * atoms in the topology is used. - * - * Either the topology must be provided, or \p natoms must be > 0. - * - * \p natoms determines the largest atom index that can be selected by - * the selection: even if the topology contains more atoms, they will - * not be selected. - * - * Does not throw currently, but this is subject to change when more - * underlying code is converted to C++. - */ - void setTopology(gmx_mtop_t *top, int natoms); - /*! \brief - * Sets the external index groups to use for the selections. - * - * \param[in] grps Index groups to use for the selections. - * \throws std::bad_alloc if out of memory. - * \throws InconsistentInputError if a group reference cannot be resolved. - * - * Only the first call to this method can have a non-NULL \p grps. - * At this point, any selections that have already been provided are - * searched for references to external groups, and the references are - * replaced by the contents of the groups. If any referenced group - * cannot be found in \p grps (or if \p grps is NULL and there are any - * references), InconsistentInputError is thrown. - * - * The selection collection keeps a reference to \p grps until this - * method is called with a NULL \p grps. - * If this method is not called before compile(), it is automatically - * called as setIndexGroups(NULL). - */ - void setIndexGroups(gmx_ana_indexgrps_t *grps); - /*! \brief - * Parses selection(s) from standard input. - * - * \param[in] count Number of selections to parse - * (if -1, parse as many as provided by the user). - * \param[in] bInteractive Whether the parser should behave - * interactively. - * \param[in] context Context to print for interactive input. - * \returns Vector of parsed selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if there is a parsing error - * (an interactive parser only throws this if too few selections - * are provided and the user forced the end of input). - * - * The returned objects remain valid for the lifetime of - * the selection collection. - * Some information about the selections only becomes available once - * compile() has been called; see \ref Selection. - * - * The string provided to \p context should be such that it can replace - * the three dots in "Specify selections ...:". It can be empty. - */ - SelectionList parseFromStdin(int count, bool bInteractive, - const std::string &context); - /*! \brief - * Parses selection(s) interactively using provided streams. - * - * \param[in] count Number of selections to parse - * (if -1, parse as many as provided by the user). - * \param[in] inputStream Stream to use for input. - * \param[in] outputStream Stream to use for output - * (if NULL, the parser runs non-interactively and does not - * produce any status messages). - * \param[in] context Context to print for interactive input. - * \returns Vector of parsed selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if there is a parsing error - * (an interactive parser only throws this if too few selections - * are provided and the user forced the end of input). - * - * Works the same as parseFromStdin(), except that the caller can - * provide streams to use instead of `stdin` and `stderr`. - * - * Mainly usable for unit testing interactive input. - */ - SelectionList parseInteractive(int count, - TextInputStream *inputStream, - TextOutputStream *outputStream, - const std::string &context); - /*! \brief - * Parses selection(s) from a file. - * - * \param[in] filename Name of the file to parse selections from. - * \returns Vector of parsed selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if there is a parsing error. - * - * The returned objects remain valid for the lifetime of - * the selection collection. - * Some information about the selections only becomes available once - * compile() has been called; see \ref Selection. - */ - SelectionList parseFromFile(const std::string &filename); - /*! \brief - * Parses selection(s) from a string. - * - * \param[in] str String to parse selections from. - * \returns Vector of parsed selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if there is a parsing error. - * - * The returned objects remain valid for the lifetime of - * the selection collection. - * Some information about the selections only becomes available once - * compile() has been called; see \ref Selection. - */ - SelectionList parseFromString(const std::string &str); - /*! \brief - * Prepares the selections for evaluation and performs optimizations. - * - * \throws InconsistentInputError if topology is required but not set. - * \throws InvalidInputError if setIndexGroups() has not been called - * and there are index group references. - * \throws unspecified if compilation fails (TODO: list/reduce these). - * - * Before compilation, selections should have been added to the - * collection using the parseFrom*() functions. - * The compiled selection collection can be passed to evaluate() to - * evaluate the selection for a frame. - * Before the compiled selection is evaluated, the selections indicate - * the maximal set of atoms/positions to which they can be evaluated; - * see \ref Selection. - * - * If an error occurs, the collection is cleared. - * - * The covered fraction information is initialized to ::CFRAC_NONE for - * all selections. - */ - void compile(); - /*! \brief - * Evaluates selections in the collection. - * - * \param[in] fr Frame for which the evaluation should be carried out. - * \param[in] pbc PBC data, or NULL if no PBC should be used. - * \throws unspeficied Multiple possible exceptions to indicate - * evaluation failure (TODO: enumerate). - */ - void evaluate(t_trxframe *fr, t_pbc *pbc); - /*! \brief - * Evaluates the largest possible index groups from dynamic selections. - * - * \param[in] nframes Total number of frames. - * - * This method restores the selections to the state they were after - * compile(). - * - * \p nframes should equal the number of times evaluate() has been - * called. - * - * Does not throw. - */ - void evaluateFinal(int nframes); + /*! \brief + * Initializes options for setting global properties on the collection. + * + * \param[in,out] options Options object to initialize. + * \param[in] selectionTypeOption + * Whether to add option to influence setOutputPosType(). + * \throws std::bad_alloc if out of memory. + * + * Adds options to \p options that can be used to set the default + * position types (see setReferencePosType() and setOutputPosType()) + * and debugging flags. + */ + void initOptions(IOptionsContainer* options, SelectionTypeOption selectionTypeOption); - /*! \brief - * Prints a human-readable version of the internal selection element - * tree. - * - * \param[in] fp File handle to receive the output. - * \param[in] bValues If true, the evaluated values of selection - * elements are printed as well. - * - * The output is very techical, and intended for debugging purposes. - * - * Does not throw. - */ - void printTree(FILE *fp, bool bValues) const; - /*! \brief - * Prints the selection strings into an XVGR file as comments. - * - * \param[in] fp Output file. - * - * Does not throw. - */ - void printXvgrInfo(FILE *fp) const; + /*! \brief + * Sets the default reference position handling for a selection + * collection. + * + * \param[in] type Default selection reference position type + * (one of the strings acceptable for + * PositionCalculationCollection::typeFromEnum()). + * \throws InternalError if \p type is invalid. + * + * Should be called before calling the parser functions, unless + * initOptions() has been called. In the latter case, can still be + * used to override the default value (before initOptions() is called) + * and/or the value provided through the Options object. + * + * Strong exception safety. + */ + void setReferencePosType(const char* type); + /*! \brief + * Sets the default reference position handling for a selection + * collection. + * + * \param[in] type Default selection output position type + * (one of the strings acceptable for + * PositionCalculationCollection::typeFromEnum()). + * \throws InternalError if \p type is invalid. + * + * Should be called before calling the parser functions, unless + * initOptions() has been called. In the latter case, can still be + * used to override the default value (before initOptions() is called) + * and/or the value provided through the Options object. + * + * Strong exception safety. + */ + void setOutputPosType(const char* type); + /*! \brief + * Sets the debugging level for the selection collection. + * + * \param[in] debugLevel Debug level to set (0 = no debug + * information). + * + * initOptions() creates debugging options that can also be used to set + * the debug level. These are normally hidden, but if this method is + * called before initOptions() with a non-zero \p debugLevel, they are + * made visible. + * + * Mostly useful for debugging tools. + * + * Does not throw. + */ + void setDebugLevel(int debugLevel); - private: - class Impl; + /*! \brief + * Returns what topology information is required for evaluation. + * + * \returns What topology information is required for compiling and/or + * evaluating the selections in the collection. + * + * Before the parser functions have been called, the return value is + * based just on the position types set. + * After parser functions have been called, the return value also takes + * into account the selection keywords used. + * After the compiler has been called, the return value is final and + * also considers possible force evaluation requested for the + * selections. + * + * Does not throw. + */ + SelectionTopologyProperties requiredTopologyProperties() const; + /*! \brief + * Returns true if the collection requires external index groups. + * + * \returns true if any selection has an unresolved index group reference. + * + * The return value is `false` after setIndexGroups() has been called. + * + * Does not throw. + */ + bool requiresIndexGroups() const; + /*! \brief + * Sets the topology for the collection. + * + * \param[in] top Topology data. + * \param[in] natoms Number of atoms. If <=0, the number of + * atoms in the topology is used. + * + * Either the topology must be provided, or \p natoms must be > 0. + * + * \p natoms determines the largest atom index that can be selected by + * the selection: even if the topology contains more atoms, they will + * not be selected. + * + * Does not throw currently, but this is subject to change when more + * underlying code is converted to C++. + */ + void setTopology(gmx_mtop_t* top, int natoms); + /*! \brief + * Sets the external index groups to use for the selections. + * + * \param[in] grps Index groups to use for the selections. + * \throws std::bad_alloc if out of memory. + * \throws InconsistentInputError if a group reference cannot be resolved. + * + * Only the first call to this method can have a non-NULL \p grps. + * At this point, any selections that have already been provided are + * searched for references to external groups, and the references are + * replaced by the contents of the groups. If any referenced group + * cannot be found in \p grps (or if \p grps is NULL and there are any + * references), InconsistentInputError is thrown. + * + * The selection collection keeps a reference to \p grps until this + * method is called with a NULL \p grps. + * If this method is not called before compile(), it is automatically + * called as setIndexGroups(NULL). + */ + void setIndexGroups(gmx_ana_indexgrps_t* grps); + /*! \brief + * Parses selection(s) from standard input. + * + * \param[in] count Number of selections to parse + * (if -1, parse as many as provided by the user). + * \param[in] bInteractive Whether the parser should behave + * interactively. + * \param[in] context Context to print for interactive input. + * \returns Vector of parsed selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if there is a parsing error + * (an interactive parser only throws this if too few selections + * are provided and the user forced the end of input). + * + * The returned objects remain valid for the lifetime of + * the selection collection. + * Some information about the selections only becomes available once + * compile() has been called; see \ref Selection. + * + * The string provided to \p context should be such that it can replace + * the three dots in "Specify selections ...:". It can be empty. + */ + SelectionList parseFromStdin(int count, bool bInteractive, const std::string& context); + /*! \brief + * Parses selection(s) interactively using provided streams. + * + * \param[in] count Number of selections to parse + * (if -1, parse as many as provided by the user). + * \param[in] inputStream Stream to use for input. + * \param[in] outputStream Stream to use for output + * (if NULL, the parser runs non-interactively and does not + * produce any status messages). + * \param[in] context Context to print for interactive input. + * \returns Vector of parsed selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if there is a parsing error + * (an interactive parser only throws this if too few selections + * are provided and the user forced the end of input). + * + * Works the same as parseFromStdin(), except that the caller can + * provide streams to use instead of `stdin` and `stderr`. + * + * Mainly usable for unit testing interactive input. + */ + SelectionList parseInteractive(int count, + TextInputStream* inputStream, + TextOutputStream* outputStream, + const std::string& context); + /*! \brief + * Parses selection(s) from a file. + * + * \param[in] filename Name of the file to parse selections from. + * \returns Vector of parsed selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if there is a parsing error. + * + * The returned objects remain valid for the lifetime of + * the selection collection. + * Some information about the selections only becomes available once + * compile() has been called; see \ref Selection. + */ + SelectionList parseFromFile(const std::string& filename); + /*! \brief + * Parses selection(s) from a string. + * + * \param[in] str String to parse selections from. + * \returns Vector of parsed selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if there is a parsing error. + * + * The returned objects remain valid for the lifetime of + * the selection collection. + * Some information about the selections only becomes available once + * compile() has been called; see \ref Selection. + */ + SelectionList parseFromString(const std::string& str); + /*! \brief + * Prepares the selections for evaluation and performs optimizations. + * + * \throws InconsistentInputError if topology is required but not set. + * \throws InvalidInputError if setIndexGroups() has not been called + * and there are index group references. + * \throws unspecified if compilation fails (TODO: list/reduce these). + * + * Before compilation, selections should have been added to the + * collection using the parseFrom*() functions. + * The compiled selection collection can be passed to evaluate() to + * evaluate the selection for a frame. + * Before the compiled selection is evaluated, the selections indicate + * the maximal set of atoms/positions to which they can be evaluated; + * see \ref Selection. + * + * If an error occurs, the collection is cleared. + * + * The covered fraction information is initialized to ::CFRAC_NONE for + * all selections. + */ + void compile(); + /*! \brief + * Evaluates selections in the collection. + * + * \param[in] fr Frame for which the evaluation should be carried out. + * \param[in] pbc PBC data, or NULL if no PBC should be used. + * \throws unspeficied Multiple possible exceptions to indicate + * evaluation failure (TODO: enumerate). + */ + void evaluate(t_trxframe* fr, t_pbc* pbc); + /*! \brief + * Evaluates the largest possible index groups from dynamic selections. + * + * \param[in] nframes Total number of frames. + * + * This method restores the selections to the state they were after + * compile(). + * + * \p nframes should equal the number of times evaluate() has been + * called. + * + * Does not throw. + */ + void evaluateFinal(int nframes); - PrivateImplPointer impl_; + /*! \brief + * Prints a human-readable version of the internal selection element + * tree. + * + * \param[in] fp File handle to receive the output. + * \param[in] bValues If true, the evaluated values of selection + * elements are printed as well. + * + * The output is very techical, and intended for debugging purposes. + * + * Does not throw. + */ + void printTree(FILE* fp, bool bValues) const; + /*! \brief + * Prints the selection strings into an XVGR file as comments. + * + * \param[in] fp Output file. + * + * Does not throw. + */ + void printXvgrInfo(FILE* fp) const; - /*! \brief - * Needed for the compiler to freely modify the collection. - */ - friend class SelectionCompiler; - /*! \brief - * Needed for the evaluator to freely modify the collection. - */ - friend class SelectionEvaluator; +private: + class Impl; + + PrivateImplPointer impl_; + + /*! \brief + * Needed for the compiler to freely modify the collection. + */ + friend class SelectionCompiler; + /*! \brief + * Needed for the evaluator to freely modify the collection. + */ + friend class SelectionEvaluator; }; } // namespace gmx diff --git a/src/gromacs/selection/selectioncollection_impl.h b/src/gromacs/selection/selectioncollection_impl.h index c8028af48f..28b54e9ad5 100644 --- a/src/gromacs/selection/selectioncollection_impl.h +++ b/src/gromacs/selection/selectioncollection_impl.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2016, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -83,9 +84,9 @@ struct SelectionTopologyProperties; struct gmx_ana_selcollection_t { //! Position calculation collection used for selection position evaluation. - gmx::PositionCalculationCollection pcc; + gmx::PositionCalculationCollection pcc; //! Root of the selection element tree. - gmx::SelectionTreeElementPointer root; + gmx::SelectionTreeElementPointer root; /*! \brief * Array of compiled selections. * @@ -93,23 +94,23 @@ struct gmx_ana_selcollection_t * but note that gmx::Selection instances also hold pointers to the * objects. */ - gmx::SelectionDataList sel; + gmx::SelectionDataList sel; /** Number of variables defined. */ - int nvars; + int nvars; /** Selection strings for variables. */ - char **varstrs; + char** varstrs; /** Topology for the collection. */ - const gmx_mtop_t *top; + const gmx_mtop_t* top; /** Index group that contains all the atoms. */ - gmx_ana_index_t gall; + gmx_ana_index_t gall; /** Memory pool used for selection evaluation. */ - gmx_sel_mempool_t *mempool; + gmx_sel_mempool_t* mempool; //! Parser symbol table. // Never releases ownership. - std::unique_ptr symtab; + std::unique_ptr symtab; //! Root of help topic tree (NULL is no help yet requested). - gmx::HelpTopicPointer rootHelp; + gmx::HelpTopicPointer rootHelp; }; namespace gmx @@ -124,69 +125,67 @@ class ExceptionInitializer; */ class SelectionCollection::Impl { - public: - /*! \brief - * Creates a new selection collection. - * - * \throws std::bad_alloc if out of memory. - */ - Impl(); - ~Impl(); - - /*! \brief - * Clears the symbol table of the selection collection. - * - * Does not throw. - */ - void clearSymbolTable(); - /*! \brief - * Replace group references by group contents. - * - * \param[in] root Root of selection tree to process. - * \param errors Object for reporting any error messages. - * \throws std::bad_alloc if out of memory. - * - * Recursively searches the selection tree for unresolved external - * references. If one is found, finds the referenced group in - * \a grps_ and replaces the reference with a constant element that - * contains the atoms from the referenced group. Any failures to - * resolve references are reported to \p errors. - */ - void resolveExternalGroups(const gmx::SelectionTreeElementPointer &root, - ExceptionInitializer *errors); - - //! Whether forces have been requested for some selection. - bool areForcesRequested() const; - /*! \brief - * Returns topology properties needed for a certain position type. - */ - SelectionTopologyProperties - requiredTopologyPropertiesForPositionType(const std::string &post, - bool forces) const; - - //! Internal data, used for interfacing with old C code. - gmx_ana_selcollection_t sc_; - //! Default reference position type for selections. - std::string rpost_; - //! Default output position type for selections. - std::string spost_; - //! Atoms needed for evaluating the selections. - gmx_ana_index_t requiredAtoms_; - /*! \brief - * Debugging level for the collection. - * - * Possible values: - * - 0: no debugging - * - 1: print selection trees after parsing and compilation - * - 2: like 1, also print intermediate compilation trees - * - 3: like 1, also print the tree after evaluation - * - 4: combine 2 and 3 - */ - int debugLevel_; - //! Whether setIndexGroups() has been called. - bool bExternalGroupsSet_; - //! External index groups (can be NULL). - gmx_ana_indexgrps_t *grps_; +public: + /*! \brief + * Creates a new selection collection. + * + * \throws std::bad_alloc if out of memory. + */ + Impl(); + ~Impl(); + + /*! \brief + * Clears the symbol table of the selection collection. + * + * Does not throw. + */ + void clearSymbolTable(); + /*! \brief + * Replace group references by group contents. + * + * \param[in] root Root of selection tree to process. + * \param errors Object for reporting any error messages. + * \throws std::bad_alloc if out of memory. + * + * Recursively searches the selection tree for unresolved external + * references. If one is found, finds the referenced group in + * \a grps_ and replaces the reference with a constant element that + * contains the atoms from the referenced group. Any failures to + * resolve references are reported to \p errors. + */ + void resolveExternalGroups(const gmx::SelectionTreeElementPointer& root, ExceptionInitializer* errors); + + //! Whether forces have been requested for some selection. + bool areForcesRequested() const; + /*! \brief + * Returns topology properties needed for a certain position type. + */ + SelectionTopologyProperties requiredTopologyPropertiesForPositionType(const std::string& post, + bool forces) const; + + //! Internal data, used for interfacing with old C code. + gmx_ana_selcollection_t sc_; + //! Default reference position type for selections. + std::string rpost_; + //! Default output position type for selections. + std::string spost_; + //! Atoms needed for evaluating the selections. + gmx_ana_index_t requiredAtoms_; + /*! \brief + * Debugging level for the collection. + * + * Possible values: + * - 0: no debugging + * - 1: print selection trees after parsing and compilation + * - 2: like 1, also print intermediate compilation trees + * - 3: like 1, also print the tree after evaluation + * - 4: combine 2 and 3 + */ + int debugLevel_; + //! Whether setIndexGroups() has been called. + bool bExternalGroupsSet_; + //! External index groups (can be NULL). + gmx_ana_indexgrps_t* grps_; }; /*! \internal @@ -200,17 +199,17 @@ class SelectionCollection::Impl */ class SelectionEvaluator { - public: - SelectionEvaluator(); - - /*! \brief - * Evaluates selections in a collection. - */ - void evaluate(SelectionCollection *sc, t_trxframe *fr, t_pbc *pbc); - /*! \brief - * Evaluates the final state for dynamic selections. - */ - void evaluateFinal(SelectionCollection *sc, int nframes); +public: + SelectionEvaluator(); + + /*! \brief + * Evaluates selections in a collection. + */ + void evaluate(SelectionCollection* sc, t_trxframe* fr, t_pbc* pbc); + /*! \brief + * Evaluates the final state for dynamic selections. + */ + void evaluateFinal(SelectionCollection* sc, int nframes); }; } // namespace gmx diff --git a/src/gromacs/selection/selectionenums.h b/src/gromacs/selection/selectionenums.h index 34d4b28dde..b62652bb00 100644 --- a/src/gromacs/selection/selectionenums.h +++ b/src/gromacs/selection/selectionenums.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,8 +51,8 @@ */ typedef enum { - CFRAC_NONE, /**< No covered fraction (everything covered). */ - CFRAC_SOLIDANGLE /**< Fraction of a solid (3D) angle covered. */ + CFRAC_NONE, /**< No covered fraction (everything covered). */ + CFRAC_SOLIDANGLE /**< Fraction of a solid (3D) angle covered. */ } e_coverfrac_t; namespace gmx @@ -67,17 +67,17 @@ namespace gmx */ enum SelectionFlag { - efSelection_OnlyStatic = 1<<0, - efSelection_OnlyAtoms = 1<<1, - efSelection_OnlySorted = 1<<2, + efSelection_OnlyStatic = 1 << 0, + efSelection_OnlyAtoms = 1 << 1, + efSelection_OnlySorted = 1 << 2, //! Whether ::POS_MASKONLY should be used for output position evaluation. - efSelection_DynamicMask = 1<<3, + efSelection_DynamicMask = 1 << 3, //! If set, unconditionally empty selections result in compilation errors. - efSelection_DisallowEmpty = 1<<4, + efSelection_DisallowEmpty = 1 << 4, //! Whether velocities of output positions should be evaluated. - efSelection_EvaluateVelocities = 1<<5, + efSelection_EvaluateVelocities = 1 << 5, //! Whether forces on output positions should be evaluated. - efSelection_EvaluateForces = 1<<6, + efSelection_EvaluateForces = 1 << 6, }; //! Holds a collection of ::SelectionFlag values. @@ -100,24 +100,19 @@ struct SelectionTopologyProperties return SelectionTopologyProperties(true, false); } //! Returns a property object that requires atom masses. - static SelectionTopologyProperties masses() - { - return SelectionTopologyProperties(true, true); - } + static SelectionTopologyProperties masses() { return SelectionTopologyProperties(true, true); } //! Initializes properties that does not require anything. - SelectionTopologyProperties() - : needsTopology(false), needsMasses(false) - { - } + SelectionTopologyProperties() : needsTopology(false), needsMasses(false) {} //! Initializes properties with the given flags. - SelectionTopologyProperties(bool needsTopology, bool needsMasses) - : needsTopology(needsTopology), needsMasses(needsMasses) + SelectionTopologyProperties(bool needsTopology, bool needsMasses) : + needsTopology(needsTopology), + needsMasses(needsMasses) { } //! Combines flags from another properties object to this. - void merge(const SelectionTopologyProperties &other) + void merge(const SelectionTopologyProperties& other) { needsTopology = needsTopology || other.needsTopology; needsMasses = needsMasses || other.needsMasses; @@ -133,6 +128,6 @@ struct SelectionTopologyProperties bool needsMasses; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/selection/selectionfileoption.h b/src/gromacs/selection/selectionfileoption.h index df0612cbc8..73942520a0 100644 --- a/src/gromacs/selection/selectionfileoption.h +++ b/src/gromacs/selection/selectionfileoption.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,16 +68,15 @@ class SelectionOptionManager; */ class SelectionFileOption : public AbstractOption { - public: - //! OptionInfo subclass corresponding to this option type. - typedef SelectionFileOptionInfo InfoType; +public: + //! OptionInfo subclass corresponding to this option type. + typedef SelectionFileOptionInfo InfoType; - //! Initializes an option with the given name. - explicit SelectionFileOption(const char *name); + //! Initializes an option with the given name. + explicit SelectionFileOption(const char* name); - private: - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; +private: + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; }; /*! \libinternal \brief @@ -88,13 +87,13 @@ class SelectionFileOption : public AbstractOption */ class SelectionFileOptionInfo : public OptionInfo { - public: - /*! \brief - * Creates option info object for given storage object. - * - * Does not throw. - */ - explicit SelectionFileOptionInfo(SelectionFileOptionStorage *option); +public: + /*! \brief + * Creates option info object for given storage object. + * + * Does not throw. + */ + explicit SelectionFileOptionInfo(SelectionFileOptionStorage* option); }; } // namespace gmx diff --git a/src/gromacs/selection/selectionfileoptionstorage.h b/src/gromacs/selection/selectionfileoptionstorage.h index 01c243c4a0..bbfee71903 100644 --- a/src/gromacs/selection/selectionfileoptionstorage.h +++ b/src/gromacs/selection/selectionfileoptionstorage.h @@ -58,33 +58,34 @@ class SelectionOptionManager; */ class SelectionFileOptionStorage : public AbstractOptionStorage { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Storage settings. - * \param manager Manager for this object. - */ - SelectionFileOptionStorage(const SelectionFileOption &settings, - SelectionOptionManager *manager); +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Storage settings. + * \param manager Manager for this object. + */ + SelectionFileOptionStorage(const SelectionFileOption& settings, SelectionOptionManager* manager); - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override { return "file"; } - int valueCount() const override { return 0; } - std::vector defaultValues() const override { return {}; } - std::vector defaultValuesAsStrings() const override { return {}; } - std::vector - normalizeValues(const std::vector &values) const override { return values; } + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return "file"; } + int valueCount() const override { return 0; } + std::vector defaultValues() const override { return {}; } + std::vector defaultValuesAsStrings() const override { return {}; } + std::vector normalizeValues(const std::vector& values) const override + { + return values; + } - private: - void clearSet() override; - void convertValue(const Any &value) override; - void processSet() override; - void processAll() override {} +private: + void clearSet() override; + void convertValue(const Any& value) override; + void processSet() override; + void processAll() override {} - SelectionFileOptionInfo info_; - SelectionOptionManager &manager_; - bool bValueParsed_; + SelectionFileOptionInfo info_; + SelectionOptionManager& manager_; + bool bValueParsed_; }; } // namespace gmx diff --git a/src/gromacs/selection/selectionoption.cpp b/src/gromacs/selection/selectionoption.cpp index 3e43983fbb..76612b3ea3 100644 --- a/src/gromacs/selection/selectionoption.cpp +++ b/src/gromacs/selection/selectionoption.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,12 +64,13 @@ namespace gmx * SelectionOptionStorage */ -SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings, - SelectionOptionManager *manager) - : MyBase(settings, OptionFlags() | efOption_NoDefaultValue - | efOption_DontCheckMinimumCount), - info_(this), manager_(*manager), defaultText_(settings.defaultText_), - selectionFlags_(settings.selectionFlags_) +SelectionOptionStorage::SelectionOptionStorage(const SelectionOption& settings, + SelectionOptionManager* manager) : + MyBase(settings, OptionFlags() | efOption_NoDefaultValue | efOption_DontCheckMinimumCount), + info_(this), + manager_(*manager), + defaultText_(settings.defaultText_), + selectionFlags_(settings.selectionFlags_) { GMX_RELEASE_ASSERT(manager != nullptr, "SelectionOptionManager must be added before SelectionOption"); @@ -78,22 +80,19 @@ SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings, } -std::string SelectionOptionStorage::formatSingleValue(const Selection &value) const +std::string SelectionOptionStorage::formatSingleValue(const Selection& value) const { return value.selectionText(); } -std::vector -SelectionOptionStorage::normalizeValues(const std::vector & /*values*/) const +std::vector SelectionOptionStorage::normalizeValues(const std::vector& /*values*/) const { GMX_THROW(NotImplementedError("Selection options not supported in this context")); } -void SelectionOptionStorage::addSelections( - const SelectionList &selections, - bool bFullValue) +void SelectionOptionStorage::addSelections(const SelectionList& selections, bool bFullValue) { if (bFullValue && selections.size() < static_cast(minValueCount())) { @@ -125,12 +124,12 @@ void SelectionOptionStorage::addSelections( } -void SelectionOptionStorage::convertValue(const Any &value) +void SelectionOptionStorage::convertValue(const Any& value) { manager_.convertOptionValue(this, value.cast(), false); } -void SelectionOptionStorage::processSetValues(ValueList *values) +void SelectionOptionStorage::processSetValues(ValueList* values) { if (values->empty()) { @@ -174,7 +173,7 @@ void SelectionOptionStorage::setAllowedValueCount(int count) { setMaxValueCount(count); } - catch (const UserInputError &ex) + catch (const UserInputError& ex) { errors.append(ex.what()); } @@ -187,7 +186,7 @@ void SelectionOptionStorage::setAllowedValueCount(int count) void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet) { - for (const Selection &value : values()) + for (const Selection& value : values()) { if (flag == efSelection_OnlyStatic && bSet && value.isDynamic()) { @@ -199,7 +198,7 @@ void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet) } } selectionFlags_.set(flag, bSet); - for (Selection &value : values()) + for (Selection& value : values()) { value.data().setFlags(selectionFlags_); } @@ -210,19 +209,16 @@ void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet) * SelectionOptionInfo */ -SelectionOptionInfo::SelectionOptionInfo(SelectionOptionStorage *option) - : OptionInfo(option) -{ -} +SelectionOptionInfo::SelectionOptionInfo(SelectionOptionStorage* option) : OptionInfo(option) {} -SelectionOptionStorage &SelectionOptionInfo::option() +SelectionOptionStorage& SelectionOptionInfo::option() { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } -const SelectionOptionStorage &SelectionOptionInfo::option() const +const SelectionOptionStorage& SelectionOptionInfo::option() const { - return static_cast(OptionInfo::option()); + return static_cast(OptionInfo::option()); } void SelectionOptionInfo::setValueCount(int count) @@ -260,11 +256,9 @@ void SelectionOptionInfo::setDynamicMask(bool bEnabled) * SelectionOption */ -AbstractOptionStorage * -SelectionOption::createStorage(const OptionManagerContainer &managers) const +AbstractOptionStorage* SelectionOption::createStorage(const OptionManagerContainer& managers) const { - return new SelectionOptionStorage( - *this, managers.get()); + return new SelectionOptionStorage(*this, managers.get()); } @@ -272,11 +266,12 @@ SelectionOption::createStorage(const OptionManagerContainer &managers) const * SelectionFileOptionStorage */ -SelectionFileOptionStorage::SelectionFileOptionStorage( - const SelectionFileOption &settings, SelectionOptionManager *manager) - : AbstractOptionStorage(settings, OptionFlags() | efOption_MultipleTimes - | efOption_DontCheckMinimumCount), - info_(this), manager_(*manager), bValueParsed_(false) +SelectionFileOptionStorage::SelectionFileOptionStorage(const SelectionFileOption& settings, + SelectionOptionManager* manager) : + AbstractOptionStorage(settings, OptionFlags() | efOption_MultipleTimes | efOption_DontCheckMinimumCount), + info_(this), + manager_(*manager), + bValueParsed_(false) { GMX_RELEASE_ASSERT(manager != nullptr, "SelectionOptionManager must be added before SelectionFileOption"); @@ -287,7 +282,7 @@ void SelectionFileOptionStorage::clearSet() bValueParsed_ = false; } -void SelectionFileOptionStorage::convertValue(const Any &value) +void SelectionFileOptionStorage::convertValue(const Any& value) { if (bValueParsed_) { @@ -311,8 +306,8 @@ void SelectionFileOptionStorage::processSet() * SelectionFileOptionInfo */ -SelectionFileOptionInfo::SelectionFileOptionInfo(SelectionFileOptionStorage *option) - : OptionInfo(option) +SelectionFileOptionInfo::SelectionFileOptionInfo(SelectionFileOptionStorage* option) : + OptionInfo(option) { } @@ -321,17 +316,14 @@ SelectionFileOptionInfo::SelectionFileOptionInfo(SelectionFileOptionStorage *opt * SelectionFileOption */ -SelectionFileOption::SelectionFileOption(const char *name) - : AbstractOption(name) +SelectionFileOption::SelectionFileOption(const char* name) : AbstractOption(name) { setDescription("Provide selections from files"); } -AbstractOptionStorage * -SelectionFileOption::createStorage(const OptionManagerContainer &managers) const +AbstractOptionStorage* SelectionFileOption::createStorage(const OptionManagerContainer& managers) const { - return new SelectionFileOptionStorage( - *this, managers.get()); + return new SelectionFileOptionStorage(*this, managers.get()); } } // namespace gmx diff --git a/src/gromacs/selection/selectionoption.h b/src/gromacs/selection/selectionoption.h index 8206175f1d..b9435f4580 100644 --- a/src/gromacs/selection/selectionoption.h +++ b/src/gromacs/selection/selectionoption.h @@ -77,98 +77,119 @@ class SelectionOptionStorage; */ class SelectionOption : public OptionTemplate { - public: - //! OptionInfo subclass corresponding to this option type. - typedef SelectionOptionInfo InfoType; +public: + //! OptionInfo subclass corresponding to this option type. + typedef SelectionOptionInfo InfoType; - //! Initializes an option with the given name. - explicit SelectionOption(const char *name) - : MyBase(name), defaultText_(""), - selectionFlags_(efSelection_DisallowEmpty) - { - } + //! Initializes an option with the given name. + explicit SelectionOption(const char* name) : + MyBase(name), + defaultText_(""), + selectionFlags_(efSelection_DisallowEmpty) + { + } - /*! \brief - * Request velocity evaluation for output positions. - * - * \see Selection::setEvaluateVelocities() - */ - MyClass &evaluateVelocities() - { selectionFlags_.set(efSelection_EvaluateVelocities); return me(); } - /*! \brief - * Request force evaluation for output positions. - * - * \see Selection::setEvaluateForces() - */ - MyClass &evaluateForces() - { selectionFlags_.set(efSelection_EvaluateForces); return me(); } - /*! \brief - * Only accept selections that evaluate to atom positions. - */ - MyClass &onlyAtoms() - { selectionFlags_.set(efSelection_OnlyAtoms); return me(); } - /*! \brief - * Only accept selections that evaluate to atom positions in sorted order. - */ - MyClass &onlySortedAtoms() - { - selectionFlags_.set(efSelection_OnlyAtoms); - selectionFlags_.set(efSelection_OnlySorted); - return me(); - } - /*! \brief - * Only accept static selections for this option. - */ - MyClass &onlyStatic() - { selectionFlags_.set(efSelection_OnlyStatic); return me(); } - /*! \brief - * Handle dynamic selections for this option with position masks. - * - * \see Selection - * \see SelectionPosition::selected() - */ - MyClass &dynamicMask() - { selectionFlags_.set(efSelection_DynamicMask); return me(); } - /*! \brief - * Allow specifying an unconditionally empty selection for this option. - * - * If this option is not set, selections that are unconditionally empty - * (i.e., can never match any atoms) result in errors. - * Note that even without this option, it is still possible that a - * dynamic selection evaluates to zero atoms for some frames. - */ - MyClass &allowEmpty() - { selectionFlags_.clear(efSelection_DisallowEmpty); return me(); } + /*! \brief + * Request velocity evaluation for output positions. + * + * \see Selection::setEvaluateVelocities() + */ + MyClass& evaluateVelocities() + { + selectionFlags_.set(efSelection_EvaluateVelocities); + return me(); + } + /*! \brief + * Request force evaluation for output positions. + * + * \see Selection::setEvaluateForces() + */ + MyClass& evaluateForces() + { + selectionFlags_.set(efSelection_EvaluateForces); + return me(); + } + /*! \brief + * Only accept selections that evaluate to atom positions. + */ + MyClass& onlyAtoms() + { + selectionFlags_.set(efSelection_OnlyAtoms); + return me(); + } + /*! \brief + * Only accept selections that evaluate to atom positions in sorted order. + */ + MyClass& onlySortedAtoms() + { + selectionFlags_.set(efSelection_OnlyAtoms); + selectionFlags_.set(efSelection_OnlySorted); + return me(); + } + /*! \brief + * Only accept static selections for this option. + */ + MyClass& onlyStatic() + { + selectionFlags_.set(efSelection_OnlyStatic); + return me(); + } + /*! \brief + * Handle dynamic selections for this option with position masks. + * + * \see Selection + * \see SelectionPosition::selected() + */ + MyClass& dynamicMask() + { + selectionFlags_.set(efSelection_DynamicMask); + return me(); + } + /*! \brief + * Allow specifying an unconditionally empty selection for this option. + * + * If this option is not set, selections that are unconditionally empty + * (i.e., can never match any atoms) result in errors. + * Note that even without this option, it is still possible that a + * dynamic selection evaluates to zero atoms for some frames. + */ + MyClass& allowEmpty() + { + selectionFlags_.clear(efSelection_DisallowEmpty); + return me(); + } - /*! \brief - * Sets default selection text for the option. - * - * If the option is not set by the user, the provided text is parsed as - * the value of the selection. - */ - MyClass &defaultSelectionText(const char *text) - { defaultText_ = text; return me(); } + /*! \brief + * Sets default selection text for the option. + * + * If the option is not set by the user, the provided text is parsed as + * the value of the selection. + */ + MyClass& defaultSelectionText(const char* text) + { + defaultText_ = text; + return me(); + } - private: - // Disable possibility to allow multiple occurrences, since it isn't - // implemented. - using MyBase::allowMultiple; - // Disable default value because it is impossible to provide a - // Selection object. - using MyBase::defaultValue; - using MyBase::defaultValueIfSet; +private: + // Disable possibility to allow multiple occurrences, since it isn't + // implemented. + using MyBase::allowMultiple; + // Disable default value because it is impossible to provide a + // Selection object. + using MyBase::defaultValue; + using MyBase::defaultValueIfSet; - AbstractOptionStorage *createStorage( - const OptionManagerContainer &managers) const override; + AbstractOptionStorage* createStorage(const OptionManagerContainer& managers) const override; - const char *defaultText_; - SelectionFlags selectionFlags_; + const char* defaultText_; + SelectionFlags selectionFlags_; - /*! \brief - * Needed to initialize SelectionOptionStorage from this class without - * otherwise unnecessary accessors. - */ - friend class SelectionOptionStorage; + /*! \brief + * Needed to initialize SelectionOptionStorage from this class without + * otherwise unnecessary accessors. + */ + friend class SelectionOptionStorage; }; /*! \brief @@ -217,82 +238,82 @@ class SelectionOption : public OptionTemplate */ class SelectionOptionInfo : public OptionInfo { - public: - /*! \brief - * Creates option info object for given storage object. - * - * Does not throw. - */ - explicit SelectionOptionInfo(SelectionOptionStorage *option); +public: + /*! \brief + * Creates option info object for given storage object. + * + * Does not throw. + */ + explicit SelectionOptionInfo(SelectionOptionStorage* option); - /*! \brief - * Sets the number of selections allowed for the option. - * - * \param[in] count Number of allowed selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if values have already been provided - * and their count does not match. - */ - void setValueCount(int count); + /*! \brief + * Sets the number of selections allowed for the option. + * + * \param[in] count Number of allowed selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if values have already been provided + * and their count does not match. + */ + void setValueCount(int count); - /*! \brief - * Sets whether this option evaluates velocities for positions. - * - * \param[in] bEnabled If true, velocities are evaluated. - * - * Does not throw. - * - * \see Selection::setEvaluateVelocities() - */ - void setEvaluateVelocities(bool bEnabled); - /*! \brief - * Sets whether this option evaluates forces for positions. - * - * \param[in] bEnabled If true, forces are evaluated. - * - * Does not throw. - * - * \see Selection::setEvaluateForces() - */ - void setEvaluateForces(bool bEnabled); - /*! \brief - * Sets whether this option accepts positions that come from multiple - * atoms. - * - * \param[in] bEnabled If true, the option accepts only positions that - * evaluate to atom positions. - * - * \see SelectionOption::onlyAtoms() - */ - void setOnlyAtoms(bool bEnabled); - /*! \brief - * Sets whether this option accepts dynamic selections. - * - * \param[in] bEnabled If true, the option accepts only static - * selections. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if dynamic selections have already been - * provided. - * - * Strong exception safety guarantee. - * - * \see SelectionOption::onlyStatic() - */ - void setOnlyStatic(bool bEnabled); - /*! \brief - * Sets whether this option uses position masks for dynamic selections. - * - * \param[in] bEnabled If true, the position masks are used. - * - * Does not throw. - * - * \see SelectionOption::dynamicMask() - */ - void setDynamicMask(bool bEnabled); + /*! \brief + * Sets whether this option evaluates velocities for positions. + * + * \param[in] bEnabled If true, velocities are evaluated. + * + * Does not throw. + * + * \see Selection::setEvaluateVelocities() + */ + void setEvaluateVelocities(bool bEnabled); + /*! \brief + * Sets whether this option evaluates forces for positions. + * + * \param[in] bEnabled If true, forces are evaluated. + * + * Does not throw. + * + * \see Selection::setEvaluateForces() + */ + void setEvaluateForces(bool bEnabled); + /*! \brief + * Sets whether this option accepts positions that come from multiple + * atoms. + * + * \param[in] bEnabled If true, the option accepts only positions that + * evaluate to atom positions. + * + * \see SelectionOption::onlyAtoms() + */ + void setOnlyAtoms(bool bEnabled); + /*! \brief + * Sets whether this option accepts dynamic selections. + * + * \param[in] bEnabled If true, the option accepts only static + * selections. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if dynamic selections have already been + * provided. + * + * Strong exception safety guarantee. + * + * \see SelectionOption::onlyStatic() + */ + void setOnlyStatic(bool bEnabled); + /*! \brief + * Sets whether this option uses position masks for dynamic selections. + * + * \param[in] bEnabled If true, the position masks are used. + * + * Does not throw. + * + * \see SelectionOption::dynamicMask() + */ + void setDynamicMask(bool bEnabled); - private: - SelectionOptionStorage &option(); - const SelectionOptionStorage &option() const; +private: + SelectionOptionStorage& option(); + const SelectionOptionStorage& option() const; }; } // namespace gmx diff --git a/src/gromacs/selection/selectionoptionbehavior.cpp b/src/gromacs/selection/selectionoptionbehavior.cpp index 5cc4a4abcd..c6c68d8805 100644 --- a/src/gromacs/selection/selectionoptionbehavior.cpp +++ b/src/gromacs/selection/selectionoptionbehavior.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,9 +66,7 @@ namespace gmx * ITopologyProvider */ -ITopologyProvider::~ITopologyProvider() -{ -} +ITopologyProvider::~ITopologyProvider() {} /******************************************************************** * SelectionOptionBehavior @@ -76,142 +74,140 @@ ITopologyProvider::~ITopologyProvider() class SelectionOptionBehavior::Impl { - public: - Impl(SelectionCollection *selections, - ITopologyProvider *topologyProvider) - : selections_(*selections), topologyProvider_(*topologyProvider), - manager_(selections), grps_(nullptr) +public: + Impl(SelectionCollection* selections, ITopologyProvider* topologyProvider) : + selections_(*selections), + topologyProvider_(*topologyProvider), + manager_(selections), + grps_(nullptr) + { + } + ~Impl() + { + if (grps_ != nullptr) { + gmx_ana_indexgrps_free(grps_); } - ~Impl() + } + + void promptSelections() + { + const bool isInteractive = StandardInputStream::instance().isInteractive(); + initIndexGroups(); + manager_.parseRequestedFromStdin(isInteractive); + doneIndexGroups(); + } + void initIndexGroups() + { + if (!selections_.requiresIndexGroups() && !manager_.hasRequestedSelections()) { - if (grps_ != nullptr) + if (!ndxfile_.empty()) { - gmx_ana_indexgrps_free(grps_); + std::fprintf(stderr, + "NOTE: You provided an index file\n" + " %s\n(with -n), but it was not used by any selection.\n", + ndxfile_.c_str()); } + selections_.setIndexGroups(nullptr); + return; } - - void promptSelections() + if (ndxfile_.empty()) { - const bool isInteractive = StandardInputStream::instance().isInteractive(); - initIndexGroups(); - manager_.parseRequestedFromStdin(isInteractive); - doneIndexGroups(); + gmx_mtop_t* top = topologyProvider_.getTopology(false); + gmx_ana_indexgrps_init(&grps_, top, nullptr); } - void initIndexGroups() + else { - if (!selections_.requiresIndexGroups() - && !manager_.hasRequestedSelections()) - { - if (!ndxfile_.empty()) - { - std::fprintf(stderr, "NOTE: You provided an index file\n" - " %s\n(with -n), but it was not used by any selection.\n", - ndxfile_.c_str()); - } - selections_.setIndexGroups(nullptr); - return; - } - if (ndxfile_.empty()) - { - gmx_mtop_t *top = topologyProvider_.getTopology(false); - gmx_ana_indexgrps_init(&grps_, top, nullptr); - } - else - { - gmx_ana_indexgrps_init(&grps_, nullptr, ndxfile_.c_str()); - } - selections_.setIndexGroups(grps_); + gmx_ana_indexgrps_init(&grps_, nullptr, ndxfile_.c_str()); } - void doneIndexGroups() + selections_.setIndexGroups(grps_); + } + void doneIndexGroups() + { + if (grps_ != nullptr) { - if (grps_ != nullptr) - { - selections_.setIndexGroups(nullptr); - gmx_ana_indexgrps_free(grps_); - grps_ = nullptr; - } + selections_.setIndexGroups(nullptr); + gmx_ana_indexgrps_free(grps_); + grps_ = nullptr; } - - void compileSelections() + } + + void compileSelections() + { + const bool topRequired = selections_.requiredTopologyProperties().needsTopology; + gmx_mtop_t* top = topologyProvider_.getTopology(topRequired); + int natoms = -1; + if (top == nullptr) { - const bool topRequired = selections_.requiredTopologyProperties().needsTopology; - gmx_mtop_t *top = topologyProvider_.getTopology(topRequired); - int natoms = -1; - if (top == nullptr) - { - natoms = topologyProvider_.getAtomCount(); - } - getMassesIfRequired(top); - selections_.setTopology(top, natoms); - selections_.compile(); - // Situation may have changed after compilation. - getMassesIfRequired(top); + natoms = topologyProvider_.getAtomCount(); } - - void getMassesIfRequired(gmx_mtop_t *top) + getMassesIfRequired(top); + selections_.setTopology(top, natoms); + selections_.compile(); + // Situation may have changed after compilation. + getMassesIfRequired(top); + } + + void getMassesIfRequired(gmx_mtop_t* top) + { + const bool massRequired = selections_.requiredTopologyProperties().needsMasses; + if (!massRequired) { - const bool massRequired = selections_.requiredTopologyProperties().needsMasses; - if (!massRequired) - { - return; - } - // TODO: There can be some corner cases that still hit this assert - // when the user has not provided the topology. - GMX_RELEASE_ASSERT(top != nullptr, - "Masses are required, but no topology is loaded"); - for (gmx_moltype_t &moltype : top->moltype) + return; + } + // TODO: There can be some corner cases that still hit this assert + // when the user has not provided the topology. + GMX_RELEASE_ASSERT(top != nullptr, "Masses are required, but no topology is loaded"); + for (gmx_moltype_t& moltype : top->moltype) + { + if (!moltype.atoms.haveMass) { + atomsSetMassesBasedOnNames(&moltype.atoms, TRUE); if (!moltype.atoms.haveMass) { - atomsSetMassesBasedOnNames(&moltype.atoms, TRUE); - if (!moltype.atoms.haveMass) - { - GMX_THROW(InconsistentInputError("Selections require mass information for evaluation, but it is not available in the input and could not be determined for all atoms based on atom names.")); - } + GMX_THROW(InconsistentInputError( + "Selections require mass information for evaluation, but it is not " + "available in the input and could not be determined for all atoms " + "based on atom names.")); } } } - - SelectionCollection &selections_; - ITopologyProvider &topologyProvider_; - SelectionOptionManager manager_; - //! Name of the index file (empty if no index file provided). - std::string ndxfile_; - gmx_ana_indexgrps_t *grps_; + } + + SelectionCollection& selections_; + ITopologyProvider& topologyProvider_; + SelectionOptionManager manager_; + //! Name of the index file (empty if no index file provided). + std::string ndxfile_; + gmx_ana_indexgrps_t* grps_; }; -SelectionOptionBehavior::SelectionOptionBehavior( - SelectionCollection *selections, - ITopologyProvider *topologyProvider) - : impl_(new Impl(selections, topologyProvider)) +SelectionOptionBehavior::SelectionOptionBehavior(SelectionCollection* selections, + ITopologyProvider* topologyProvider) : + impl_(new Impl(selections, topologyProvider)) { } -SelectionOptionBehavior::~SelectionOptionBehavior() -{ -} +SelectionOptionBehavior::~SelectionOptionBehavior() {} -void -SelectionOptionBehavior::initOptions(IOptionsContainer *options) +void SelectionOptionBehavior::initOptions(IOptionsContainer* options) { options->addOption(FileNameOption("n") - .filetype(eftIndex).inputFile() - .store(&impl_->ndxfile_) - .defaultBasename("index") - .description("Extra index groups")); + .filetype(eftIndex) + .inputFile() + .store(&impl_->ndxfile_) + .defaultBasename("index") + .description("Extra index groups")); options->addOption(SelectionFileOption("sf")); impl_->manager_.initOptions(options); } -void -SelectionOptionBehavior::initBehavior(Options *options) +void SelectionOptionBehavior::initBehavior(Options* options) { options->addManager(&impl_->manager_); } -void -SelectionOptionBehavior::optionsFinished() +void SelectionOptionBehavior::optionsFinished() { impl_->promptSelections(); impl_->compileSelections(); diff --git a/src/gromacs/selection/selectionoptionbehavior.h b/src/gromacs/selection/selectionoptionbehavior.h index 2e58c69930..16f1a572c2 100644 --- a/src/gromacs/selection/selectionoptionbehavior.h +++ b/src/gromacs/selection/selectionoptionbehavior.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -78,33 +78,33 @@ class SelectionCollection; */ class ITopologyProvider { - public: - /*! \brief - * Returns the topology to use. - * - * \param[in] required Whether the topology is required by the caller. - * - * Can return NULL if \p required is `false` and the topology is not - * provided by the user. - * If \p required is `true`, should throw an error if the topology - * cannot be loaded. - * - * This method may get called multiple times, potentially with - * different values of \p required. Subsequent calls should just - * return the same topology that was loaded in the first call. - */ - virtual gmx_mtop_t *getTopology(bool required) = 0; - /*! \brief - * Returns the number of atoms. - * - * This method is only called if getTopology() returns NULL. - * It should return the number of atoms that at most need to be - * selected by the selections. - */ - virtual int getAtomCount() = 0; +public: + /*! \brief + * Returns the topology to use. + * + * \param[in] required Whether the topology is required by the caller. + * + * Can return NULL if \p required is `false` and the topology is not + * provided by the user. + * If \p required is `true`, should throw an error if the topology + * cannot be loaded. + * + * This method may get called multiple times, potentially with + * different values of \p required. Subsequent calls should just + * return the same topology that was loaded in the first call. + */ + virtual gmx_mtop_t* getTopology(bool required) = 0; + /*! \brief + * Returns the number of atoms. + * + * This method is only called if getTopology() returns NULL. + * It should return the number of atoms that at most need to be + * selected by the selections. + */ + virtual int getAtomCount() = 0; - protected: - virtual ~ITopologyProvider(); +protected: + virtual ~ITopologyProvider(); }; /*! \brief @@ -142,39 +142,38 @@ class ITopologyProvider */ class SelectionOptionBehavior : public IOptionsBehavior { - public: - /*! \brief - * Creates a behavior to use selections. - * - * \param[in,out] selections Selection collection to use. - * \param[in] topologyProvider Callback to load/provide topology - * information to selections when required. - * - * The methods in \p topologyProvider are called after all options have - * been parsed and finished, so the caller can, e.g., load the topology - * from a file specified by a file option. - */ - SelectionOptionBehavior(SelectionCollection *selections, - ITopologyProvider *topologyProvider); - ~SelectionOptionBehavior() override; +public: + /*! \brief + * Creates a behavior to use selections. + * + * \param[in,out] selections Selection collection to use. + * \param[in] topologyProvider Callback to load/provide topology + * information to selections when required. + * + * The methods in \p topologyProvider are called after all options have + * been parsed and finished, so the caller can, e.g., load the topology + * from a file specified by a file option. + */ + SelectionOptionBehavior(SelectionCollection* selections, ITopologyProvider* topologyProvider); + ~SelectionOptionBehavior() override; - /*! \brief - * Add common options for controlling selections. - * - * This method is separate from the constructor so that the caller can - * control the order of options better. - */ - void initOptions(IOptionsContainer *options); + /*! \brief + * Add common options for controlling selections. + * + * This method is separate from the constructor so that the caller can + * control the order of options better. + */ + void initOptions(IOptionsContainer* options); - // From IOptionsBehavior - void initBehavior(Options *options) override; - void optionsFinishing(Options * /*options*/) override {} - void optionsFinished() override; + // From IOptionsBehavior + void initBehavior(Options* options) override; + void optionsFinishing(Options* /*options*/) override {} + void optionsFinished() override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; diff --git a/src/gromacs/selection/selectionoptionmanager.cpp b/src/gromacs/selection/selectionoptionmanager.cpp index 54d43a4cc5..6627942cff 100644 --- a/src/gromacs/selection/selectionoptionmanager.cpp +++ b/src/gromacs/selection/selectionoptionmanager.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,138 +67,115 @@ namespace gmx */ class SelectionOptionManager::Impl { - public: - /*! \brief - * Request for postponed parsing of selections. - */ - struct SelectionRequest - { - //! Initializes a request for the given option. - explicit SelectionRequest(SelectionOptionStorage *storage) - : storage_(storage) - { - } - - //! Returns name of the requested selection optin. - const std::string &name() const - { - return storage_->name(); - } - //! Returns description for the requested selection option. - const std::string &description() const - { - return storage_->description(); - } - /*! \brief - * Returns the number of selections requested in this request. - * - * -1 indicates no upper limit. - */ - int count() const - { - return storage_->maxValueCount(); - } - - //! Storage object to which the selections will be added. - SelectionOptionStorage *storage_; - }; - - //! Collection for a list of selection requests. - typedef std::vector RequestList; - //! Collection for list of option storage objects. - typedef std::vector OptionList; - - /*! \brief - * Helper class that clears a request list on scope exit. - * - * Methods in this class do not throw. - */ - class RequestsClearer - { - public: - //! Constructs an object that clears given list on scope exit. - explicit RequestsClearer(RequestList *requests) - : requests_(requests) - { - } - //! Clears the request list given to the constructor. - ~RequestsClearer() - { - requests_->clear(); - } - - private: - RequestList *requests_; - }; - - /*! \brief - * Creates a new selection collection. - * - * \throws std::bad_alloc if out of memory. - */ - explicit Impl(SelectionCollection *collection); +public: + /*! \brief + * Request for postponed parsing of selections. + */ + struct SelectionRequest + { + //! Initializes a request for the given option. + explicit SelectionRequest(SelectionOptionStorage* storage) : storage_(storage) {} + //! Returns name of the requested selection optin. + const std::string& name() const { return storage_->name(); } + //! Returns description for the requested selection option. + const std::string& description() const { return storage_->description(); } /*! \brief - * Assign selections from a list to pending requests. + * Returns the number of selections requested in this request. * - * \param[in] selections List of selections to assign. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if the assignment cannot be done - * (see parseRequestedFromFile() for documented conditions). - * - * Loops through \p selections and the pending requests lists in order, - * and for each requests, assigns the first yet unassigned selections - * from the list. + * -1 indicates no upper limit. */ - void placeSelectionsInRequests(const SelectionList &selections); - /*! \brief - * Adds a request for each required option that is not yet set. - * - * \throws std::bad_alloc if out of memory. - */ - void requestUnsetRequiredOptions(); - - //! Selection collection to which selections are stored. - SelectionCollection &collection_; - //! List of selection options (storage objects) this manager manages. - OptionList options_; - //! List of selections requested for later parsing. - RequestList requests_; + int count() const { return storage_->maxValueCount(); } + + //! Storage object to which the selections will be added. + SelectionOptionStorage* storage_; + }; + + //! Collection for a list of selection requests. + typedef std::vector RequestList; + //! Collection for list of option storage objects. + typedef std::vector OptionList; + + /*! \brief + * Helper class that clears a request list on scope exit. + * + * Methods in this class do not throw. + */ + class RequestsClearer + { + public: + //! Constructs an object that clears given list on scope exit. + explicit RequestsClearer(RequestList* requests) : requests_(requests) {} + //! Clears the request list given to the constructor. + ~RequestsClearer() { requests_->clear(); } + + private: + RequestList* requests_; + }; + + /*! \brief + * Creates a new selection collection. + * + * \throws std::bad_alloc if out of memory. + */ + explicit Impl(SelectionCollection* collection); + + /*! \brief + * Assign selections from a list to pending requests. + * + * \param[in] selections List of selections to assign. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if the assignment cannot be done + * (see parseRequestedFromFile() for documented conditions). + * + * Loops through \p selections and the pending requests lists in order, + * and for each requests, assigns the first yet unassigned selections + * from the list. + */ + void placeSelectionsInRequests(const SelectionList& selections); + /*! \brief + * Adds a request for each required option that is not yet set. + * + * \throws std::bad_alloc if out of memory. + */ + void requestUnsetRequiredOptions(); + + //! Selection collection to which selections are stored. + SelectionCollection& collection_; + //! List of selection options (storage objects) this manager manages. + OptionList options_; + //! List of selections requested for later parsing. + RequestList requests_; }; -SelectionOptionManager::Impl::Impl(SelectionCollection *collection) - : collection_(*collection) -{ -} +SelectionOptionManager::Impl::Impl(SelectionCollection* collection) : collection_(*collection) {} -void SelectionOptionManager::Impl::placeSelectionsInRequests( - const SelectionList &selections) +void SelectionOptionManager::Impl::placeSelectionsInRequests(const SelectionList& selections) { if (requests_.empty()) { requestUnsetRequiredOptions(); } - RequestsClearer clearRequestsOnExit(&requests_); + RequestsClearer clearRequestsOnExit(&requests_); SelectionList::const_iterator first = selections.begin(); SelectionList::const_iterator last = first; RequestList::const_iterator i; for (i = requests_.begin(); i != requests_.end(); ++i) { - const SelectionRequest &request = *i; + const SelectionRequest& request = *i; if (request.count() > 0) { int remaining = selections.end() - first; if (remaining < request.count()) { int assigned = first - selections.begin(); - GMX_THROW(InvalidInputError(formatString( - "Too few selections provided for '%s': " - "Expected %d selections, but only %d left " - "after assigning the first %d to other selections.", - request.name().c_str(), request.count(), - remaining, assigned))); + GMX_THROW(InvalidInputError( + formatString("Too few selections provided for '%s': " + "Expected %d selections, but only %d left " + "after assigning the first %d to other selections.", + request.name().c_str(), request.count(), remaining, assigned))); } last = first + request.count(); } @@ -208,16 +185,16 @@ void SelectionOptionManager::Impl::placeSelectionsInRequests( ++nextRequest; if (nextRequest != requests_.end()) { - const char *name = request.name().c_str(); - const char *conflictName = nextRequest->name().c_str(); - GMX_THROW(InvalidInputError(formatString( - "Ambiguous selections for '%s' and '%s': " - "Any number of selections is acceptable for " - "'%s', but you have requested subsequent " - "selections to be assigned to '%s'. " - "Resolution for such cases is not implemented, " - "and may be impossible.", - name, conflictName, name, conflictName))); + const char* name = request.name().c_str(); + const char* conflictName = nextRequest->name().c_str(); + GMX_THROW(InvalidInputError( + formatString("Ambiguous selections for '%s' and '%s': " + "Any number of selections is acceptable for " + "'%s', but you have requested subsequent " + "selections to be assigned to '%s'. " + "Resolution for such cases is not implemented, " + "and may be impossible.", + name, conflictName, name, conflictName))); } last = selections.end(); } @@ -230,11 +207,11 @@ void SelectionOptionManager::Impl::placeSelectionsInRequests( int count = selections.end() - selections.begin(); int remaining = selections.end() - last; int assigned = last - selections.begin(); - GMX_THROW(InvalidInputError(formatString( - "Too many selections provided: " - "Expected %d selections, but %d provided. " - "Last %d selections could not be assigned to any option.", - assigned, count, remaining))); + GMX_THROW(InvalidInputError( + formatString("Too many selections provided: " + "Expected %d selections, but %d provided. " + "Last %d selections could not be assigned to any option.", + assigned, count, remaining))); } } @@ -243,7 +220,7 @@ void SelectionOptionManager::Impl::requestUnsetRequiredOptions() OptionList::const_iterator i; for (i = options_.begin(); i != options_.end(); ++i) { - SelectionOptionStorage &storage = **i; + SelectionOptionStorage& storage = **i; if (storage.isRequired() && !storage.isSet()) { requests_.emplace_back(&storage); @@ -256,48 +233,40 @@ void SelectionOptionManager::Impl::requestUnsetRequiredOptions() * SelectionOptionManager */ -SelectionOptionManager::SelectionOptionManager(SelectionCollection *collection) - : impl_(new Impl(collection)) +SelectionOptionManager::SelectionOptionManager(SelectionCollection* collection) : + impl_(new Impl(collection)) { } -SelectionOptionManager::~SelectionOptionManager() -{ -} +SelectionOptionManager::~SelectionOptionManager() {} -void -SelectionOptionManager::registerOption(SelectionOptionStorage *storage) +void SelectionOptionManager::registerOption(SelectionOptionStorage* storage) { impl_->requests_.reserve(impl_->options_.size() + 1); impl_->options_.push_back(storage); } -void -SelectionOptionManager::convertOptionValue(SelectionOptionStorage *storage, - const std::string &value, - bool bFullValue) +void SelectionOptionManager::convertOptionValue(SelectionOptionStorage* storage, + const std::string& value, + bool bFullValue) { SelectionList selections = impl_->collection_.parseFromString(value); storage->addSelections(selections, bFullValue); } -void -SelectionOptionManager::requestOptionDelayedParsing( - SelectionOptionStorage *storage) +void SelectionOptionManager::requestOptionDelayedParsing(SelectionOptionStorage* storage) { impl_->requests_.emplace_back(storage); } -bool -SelectionOptionManager::hasRequestedSelections() const +bool SelectionOptionManager::hasRequestedSelections() const { return !impl_->requests_.empty(); } -void -SelectionOptionManager::initOptions(IOptionsContainer *options) +void SelectionOptionManager::initOptions(IOptionsContainer* options) { - bool allowOnlyAtomOutput = true; + bool allowOnlyAtomOutput = true; Impl::OptionList::const_iterator iter; for (iter = impl_->options_.begin(); iter != impl_->options_.end(); ++iter) { @@ -307,51 +276,43 @@ SelectionOptionManager::initOptions(IOptionsContainer *options) } } - SelectionCollection::SelectionTypeOption typeOption - = allowOnlyAtomOutput - ? SelectionCollection::AlwaysAtomSelections - : SelectionCollection::IncludeSelectionTypeOption; + SelectionCollection::SelectionTypeOption typeOption = + allowOnlyAtomOutput ? SelectionCollection::AlwaysAtomSelections + : SelectionCollection::IncludeSelectionTypeOption; impl_->collection_.initOptions(options, typeOption); } -void -SelectionOptionManager::parseRequestedFromStdin(bool bInteractive) +void SelectionOptionManager::parseRequestedFromStdin(bool bInteractive) { - Impl::RequestsClearer clearRequestsOnExit(&impl_->requests_); + Impl::RequestsClearer clearRequestsOnExit(&impl_->requests_); Impl::RequestList::const_iterator i; for (i = impl_->requests_.begin(); i != impl_->requests_.end(); ++i) { - const Impl::SelectionRequest &request = *i; - std::string context = - formatString("for option '%s'\n(%s)", - request.name().c_str(), request.description().c_str()); - SelectionList selections - = impl_->collection_.parseFromStdin(request.count(), bInteractive, - context); + const Impl::SelectionRequest& request = *i; + std::string context = formatString("for option '%s'\n(%s)", request.name().c_str(), + request.description().c_str()); + SelectionList selections = + impl_->collection_.parseFromStdin(request.count(), bInteractive, context); request.storage_->addSelections(selections, true); } } -void -SelectionOptionManager::parseRequestedFromFile(const std::string &filename) +void SelectionOptionManager::parseRequestedFromFile(const std::string& filename) { SelectionList selections = impl_->collection_.parseFromFile(filename); try { impl_->placeSelectionsInRequests(selections); } - catch (GromacsException &ex) + catch (GromacsException& ex) { - ex.prependContext(formatString( - "Error in adding selections from file '%s'", - filename.c_str())); + ex.prependContext(formatString("Error in adding selections from file '%s'", filename.c_str())); throw; } } -void -SelectionOptionManager::parseRequestedFromString(const std::string &str) +void SelectionOptionManager::parseRequestedFromString(const std::string& str) { SelectionList selections = impl_->collection_.parseFromString(str); impl_->placeSelectionsInRequests(selections); diff --git a/src/gromacs/selection/selectionoptionmanager.h b/src/gromacs/selection/selectionoptionmanager.h index 06b1d35400..963d9d1e1b 100644 --- a/src/gromacs/selection/selectionoptionmanager.h +++ b/src/gromacs/selection/selectionoptionmanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -80,149 +80,147 @@ class SelectionOptionStorage; */ class SelectionOptionManager : public IOptionManager { - public: - /*! \brief - * Creates a manager for selection options. - * - * \throws std::bad_alloc if out of memory. - */ - explicit SelectionOptionManager(SelectionCollection *selections); - ~SelectionOptionManager() override; +public: + /*! \brief + * Creates a manager for selection options. + * + * \throws std::bad_alloc if out of memory. + */ + explicit SelectionOptionManager(SelectionCollection* selections); + ~SelectionOptionManager() override; - /*! \brief - * Adds a selection option to be managed. - * - * \param storage Storage object for the option to register. - * \throws std::bad_alloc if out of memory. - * - * This is only for internal use by the selection module. - * It is not possible to obtain a SelectionOptionStorage pointer - * through any public or library API. - * - * Strong exception safety. - */ - void registerOption(SelectionOptionStorage *storage); - /*! \brief - * Converts a string value to selections for an option. - * - * \param storage Storage object to receive the selections. - * \param[in] value Value to convert. - * \param[in] bFullValue If true, the provided selections are the full - * value of the option, and additional checks are performed. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if the selection string is not valid, - * or uses a feature not supported by the option. - * - * This is only for internal use by the selection module. - * It is not possible to obtain a SelectionOptionStorage pointer - * through any public or library API. - */ - void convertOptionValue(SelectionOptionStorage *storage, - const std::string &value, - bool bFullValue); - /*! \brief - * Adds a selection option for delayed user input. - * - * \param storage Storage object for the option to request. - * \throws std::bad_alloc if out of memory. - * - * This is only for internal use by the selection module. - * It is not possible to obtain a SelectionOptionStorage pointer - * through any public or library API. - * - * Strong exception safety. - */ - void requestOptionDelayedParsing(SelectionOptionStorage *storage); + /*! \brief + * Adds a selection option to be managed. + * + * \param storage Storage object for the option to register. + * \throws std::bad_alloc if out of memory. + * + * This is only for internal use by the selection module. + * It is not possible to obtain a SelectionOptionStorage pointer + * through any public or library API. + * + * Strong exception safety. + */ + void registerOption(SelectionOptionStorage* storage); + /*! \brief + * Converts a string value to selections for an option. + * + * \param storage Storage object to receive the selections. + * \param[in] value Value to convert. + * \param[in] bFullValue If true, the provided selections are the full + * value of the option, and additional checks are performed. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if the selection string is not valid, + * or uses a feature not supported by the option. + * + * This is only for internal use by the selection module. + * It is not possible to obtain a SelectionOptionStorage pointer + * through any public or library API. + */ + void convertOptionValue(SelectionOptionStorage* storage, const std::string& value, bool bFullValue); + /*! \brief + * Adds a selection option for delayed user input. + * + * \param storage Storage object for the option to request. + * \throws std::bad_alloc if out of memory. + * + * This is only for internal use by the selection module. + * It is not possible to obtain a SelectionOptionStorage pointer + * through any public or library API. + * + * Strong exception safety. + */ + void requestOptionDelayedParsing(SelectionOptionStorage* storage); - /*! \brief - * Returns whether there are requested selections that need input from - * parseRequestedFrom*(). - */ - bool hasRequestedSelections() const; + /*! \brief + * Returns whether there are requested selections that need input from + * parseRequestedFrom*(). + */ + bool hasRequestedSelections() const; - /*! \brief - * Initializes options for setting global selection properties. - * - * \param[in,out] options Options object to initialize. - * \throws std::bad_alloc if out of memory. - * - * \see SelectionCollection::initOptions() - */ - void initOptions(IOptionsContainer *options); + /*! \brief + * Initializes options for setting global selection properties. + * + * \param[in,out] options Options object to initialize. + * \throws std::bad_alloc if out of memory. + * + * \see SelectionCollection::initOptions() + */ + void initOptions(IOptionsContainer* options); - /*! \brief - * Parses selection(s) from standard input for options not yet - * provided. - * - * \param[in] bInteractive Whether the parser should behave - * interactively. - * \throws unspecified Can throw any exception thrown by - * SelectionCollection::parseFromStdin(). - * \throws std::bad_alloc if out of memory. - * - * This method cooperates with SelectionOption to allow interactive - * input of requested selections after all options have been processed. - * It should be called after the Options::finish() method has been - * called on all options that add selections to this collection. - * For each required selection option that has not been given, as well - * as for optional selection options that have been specified without - * values, it will prompt the user to input the necessary selections. - */ - void parseRequestedFromStdin(bool bInteractive); - /*! \brief - * Parses selection(s) from a file for options not yet provided. - * - * \param[in] filename Name of the file to parse selections from. - * \throws unspecified Can throw any exception thrown by - * SelectionCollection::parseFromFile(). - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if - * - the number of selections in \p filename doesn't match the - * number requested. - * - any selection uses a feature that is not allowed for the - * corresponding option. - * - if there is a request for any number of selections that is - * not the last (in which case it is not possible to determine - * which selections belong to which request). - * - * This method behaves as parseRequestedFromStdin(), with two - * exceptions: - * -# It reads the selections from a file instead of standard input. - * -# If no requests are pending, assigns values to all required - * options that have not yet been set. - * - * This method used to implement SelectionFileOption. - * - * \see parseRequestedFromStdin() - */ - void parseRequestedFromFile(const std::string &filename); - /*! \brief - * Parses selection(s) from a string for options not yet provided. - * - * \param[in] str String to parse. - * \throws unspecified Can throw any exception thrown by - * SelectionCollection::parseFromString(). - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError in same conditions as - * parseRequestedFromFile(). - * - * This method behaves as parseRequestedFromFile(), but reads the - * selections from a string instead of a file. - * This method is mainly used for testing. - * - * \see parseRequestedFromFile() - */ - void parseRequestedFromString(const std::string &str); + /*! \brief + * Parses selection(s) from standard input for options not yet + * provided. + * + * \param[in] bInteractive Whether the parser should behave + * interactively. + * \throws unspecified Can throw any exception thrown by + * SelectionCollection::parseFromStdin(). + * \throws std::bad_alloc if out of memory. + * + * This method cooperates with SelectionOption to allow interactive + * input of requested selections after all options have been processed. + * It should be called after the Options::finish() method has been + * called on all options that add selections to this collection. + * For each required selection option that has not been given, as well + * as for optional selection options that have been specified without + * values, it will prompt the user to input the necessary selections. + */ + void parseRequestedFromStdin(bool bInteractive); + /*! \brief + * Parses selection(s) from a file for options not yet provided. + * + * \param[in] filename Name of the file to parse selections from. + * \throws unspecified Can throw any exception thrown by + * SelectionCollection::parseFromFile(). + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if + * - the number of selections in \p filename doesn't match the + * number requested. + * - any selection uses a feature that is not allowed for the + * corresponding option. + * - if there is a request for any number of selections that is + * not the last (in which case it is not possible to determine + * which selections belong to which request). + * + * This method behaves as parseRequestedFromStdin(), with two + * exceptions: + * -# It reads the selections from a file instead of standard input. + * -# If no requests are pending, assigns values to all required + * options that have not yet been set. + * + * This method used to implement SelectionFileOption. + * + * \see parseRequestedFromStdin() + */ + void parseRequestedFromFile(const std::string& filename); + /*! \brief + * Parses selection(s) from a string for options not yet provided. + * + * \param[in] str String to parse. + * \throws unspecified Can throw any exception thrown by + * SelectionCollection::parseFromString(). + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError in same conditions as + * parseRequestedFromFile(). + * + * This method behaves as parseRequestedFromFile(), but reads the + * selections from a string instead of a file. + * This method is mainly used for testing. + * + * \see parseRequestedFromFile() + */ + void parseRequestedFromString(const std::string& str); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed for handling delayed selection parsing requests. - */ - friend class SelectionOptionStorage; + /*! \brief + * Needed for handling delayed selection parsing requests. + */ + friend class SelectionOptionStorage; }; } // namespace gmx diff --git a/src/gromacs/selection/selectionoptionstorage.h b/src/gromacs/selection/selectionoptionstorage.h index d59ae7b436..ff666062ff 100644 --- a/src/gromacs/selection/selectionoptionstorage.h +++ b/src/gromacs/selection/selectionoptionstorage.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,78 +66,72 @@ class SelectionOptionManager; */ class SelectionOptionStorage : public OptionStorageTemplate { - public: - /*! \brief - * Initializes the storage from option settings. - * - * \param[in] settings Storage settings. - * \param manager Manager for this object. - */ - SelectionOptionStorage(const SelectionOption &settings, - SelectionOptionManager *manager); +public: + /*! \brief + * Initializes the storage from option settings. + * + * \param[in] settings Storage settings. + * \param manager Manager for this object. + */ + SelectionOptionStorage(const SelectionOption& settings, SelectionOptionManager* manager); - OptionInfo &optionInfo() override { return info_; } - std::string typeString() const override { return "selection"; } - std::string formatSingleValue(const Selection &value) const override; - std::vector - normalizeValues(const std::vector &values) const override; + OptionInfo& optionInfo() override { return info_; } + std::string typeString() const override { return "selection"; } + std::string formatSingleValue(const Selection& value) const override; + std::vector normalizeValues(const std::vector& values) const override; - /*! \brief - * Adds selections to the storage. - * - * \param[in] selections List of selections to add. - * \param[in] bFullValue If true, the provided selections are the full - * value of the option, and additional checks are performed. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if - * - There is an incorrect number of selections in \p selections. - * - Any selection in \p selections is not allowed for this - * option. - * - * This function is used to add selections from SelectionOptionManager. - * It is called with \p bFullValue set to false from - * SelectionOptionManager::convertOptionValue(), and \p bFullValue set - * to true when parsing requested selections. - */ - void addSelections(const SelectionList &selections, - bool bFullValue); + /*! \brief + * Adds selections to the storage. + * + * \param[in] selections List of selections to add. + * \param[in] bFullValue If true, the provided selections are the full + * value of the option, and additional checks are performed. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if + * - There is an incorrect number of selections in \p selections. + * - Any selection in \p selections is not allowed for this + * option. + * + * This function is used to add selections from SelectionOptionManager. + * It is called with \p bFullValue set to false from + * SelectionOptionManager::convertOptionValue(), and \p bFullValue set + * to true when parsing requested selections. + */ + void addSelections(const SelectionList& selections, bool bFullValue); - // Required to access the number of values in selection requests. - // See SelectionCollection::Impl. - using MyBase::maxValueCount; - //! Whether the option allows only atom-valued selections. - bool allowsOnlyAtoms() const - { - return selectionFlags_.test(efSelection_OnlyAtoms); - } - //! \copydoc SelectionOptionInfo::setValueCount() - void setAllowedValueCount(int count); - /*! \brief - * Alters flags for the selections created by this option. - * - * \param[in] flag Flag to change. - * \param[in] bSet Whether to set or clear the flag. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if selections have already been - * provided and conflict with the given flags. - * - * If selections have already been provided, it is checked that they - * match the limitations enforced by the flags. Pending requests are - * also affected. - * - * Strong exception safety guarantee. - */ - void setSelectionFlag(SelectionFlag flag, bool bSet); + // Required to access the number of values in selection requests. + // See SelectionCollection::Impl. + using MyBase::maxValueCount; + //! Whether the option allows only atom-valued selections. + bool allowsOnlyAtoms() const { return selectionFlags_.test(efSelection_OnlyAtoms); } + //! \copydoc SelectionOptionInfo::setValueCount() + void setAllowedValueCount(int count); + /*! \brief + * Alters flags for the selections created by this option. + * + * \param[in] flag Flag to change. + * \param[in] bSet Whether to set or clear the flag. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if selections have already been + * provided and conflict with the given flags. + * + * If selections have already been provided, it is checked that they + * match the limitations enforced by the flags. Pending requests are + * also affected. + * + * Strong exception safety guarantee. + */ + void setSelectionFlag(SelectionFlag flag, bool bSet); - private: - void convertValue(const Any &value) override; - void processSetValues(ValueList *values) override; - void processAll() override; +private: + void convertValue(const Any& value) override; + void processSetValues(ValueList* values) override; + void processAll() override; - SelectionOptionInfo info_; - SelectionOptionManager &manager_; - std::string defaultText_; - SelectionFlags selectionFlags_; + SelectionOptionInfo info_; + SelectionOptionManager& manager_; + std::string defaultText_; + SelectionFlags selectionFlags_; }; } // namespace gmx diff --git a/src/gromacs/selection/selelem.cpp b/src/gromacs/selection/selelem.cpp index d9dfc58c57..e9619c63ec 100644 --- a/src/gromacs/selection/selelem.cpp +++ b/src/gromacs/selection/selelem.cpp @@ -67,21 +67,22 @@ * * The function returns NULL if \p sel->type is not one of the valid values. */ -const char * -_gmx_selelem_type_str(const gmx::SelectionTreeElement &sel) +const char* _gmx_selelem_type_str(const gmx::SelectionTreeElement& sel) { - const char *p = nullptr; + const char* p = nullptr; switch (sel.type) { - case SEL_CONST: p = "CONST"; break; - case SEL_EXPRESSION: p = "EXPR"; break; - case SEL_BOOLEAN: p = "BOOL"; break; - case SEL_ARITHMETIC: p = "ARITH"; break; - case SEL_ROOT: p = "ROOT"; break; - case SEL_SUBEXPR: p = "SUBEXPR"; break; - case SEL_SUBEXPRREF: p = "REF"; break; - case SEL_GROUPREF: p = "GROUPREF"; break; - case SEL_MODIFIER: p = "MODIFIER"; break; + case SEL_CONST: p = "CONST"; break; + case SEL_EXPRESSION: p = "EXPR"; break; + case SEL_BOOLEAN: p = "BOOL"; break; + case SEL_ARITHMETIC: p = "ARITH"; break; + case SEL_ROOT: p = "ROOT"; break; + case SEL_SUBEXPR: p = "SUBEXPR"; break; + case SEL_SUBEXPRREF: p = "REF"; break; + case SEL_GROUPREF: p = "GROUPREF"; break; + case SEL_MODIFIER: + p = "MODIFIER"; + break; // No default clause so we intentionally get compiler errors // if new selection choices are added later. } @@ -95,18 +96,19 @@ _gmx_selelem_type_str(const gmx::SelectionTreeElement &sel) * * The return value points to a string constant and should not be \p free'd. */ -const char * -_gmx_sel_value_type_str(const gmx_ana_selvalue_t *val) +const char* _gmx_sel_value_type_str(const gmx_ana_selvalue_t* val) { - const char *p = nullptr; + const char* p = nullptr; switch (val->type) { - case NO_VALUE: p = "NONE"; break; - case INT_VALUE: p = "INT"; break; - case REAL_VALUE: p = "REAL"; break; - case STR_VALUE: p = "STR"; break; - case POS_VALUE: p = "VEC"; break; - case GROUP_VALUE: p = "GROUP"; break; + case NO_VALUE: p = "NONE"; break; + case INT_VALUE: p = "INT"; break; + case REAL_VALUE: p = "REAL"; break; + case STR_VALUE: p = "STR"; break; + case POS_VALUE: p = "VEC"; break; + case GROUP_VALUE: + p = "GROUP"; + break; // No default clause so we intentionally get compiler errors // if new selection choices are added later. } @@ -114,16 +116,17 @@ _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val) } /*! \copydoc _gmx_selelem_type_str() */ -const char * -_gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement &sel) +const char* _gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement& sel) { - const char *p = nullptr; + const char* p = nullptr; switch (sel.u.boolt) { - case BOOL_NOT: p = "NOT"; break; - case BOOL_AND: p = "AND"; break; - case BOOL_OR: p = "OR"; break; - case BOOL_XOR: p = "XOR"; break; + case BOOL_NOT: p = "NOT"; break; + case BOOL_AND: p = "AND"; break; + case BOOL_OR: p = "OR"; break; + case BOOL_XOR: + p = "XOR"; + break; // No default clause so we intentionally get compiler errors // if new selection choices are added later. } @@ -134,12 +137,11 @@ _gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement &sel) namespace gmx { -SelectionTreeElement::SelectionTreeElement(e_selelem_t type, - const SelectionLocation &location) - : location_(location) +SelectionTreeElement::SelectionTreeElement(e_selelem_t type, const SelectionLocation& location) : + location_(location) { - this->type = type; - this->flags = (type != SEL_ROOT) ? SEL_ALLOCVAL : 0; + this->type = type; + this->flags = (type != SEL_ROOT) ? SEL_ALLOCVAL : 0; if (type == SEL_BOOLEAN) { this->v.type = GROUP_VALUE; @@ -151,9 +153,9 @@ SelectionTreeElement::SelectionTreeElement(e_selelem_t type, } _gmx_selvalue_clear(&this->v); std::memset(&this->u, 0, sizeof(this->u)); - this->evaluate = nullptr; - this->mempool = nullptr; - this->cdata = nullptr; + this->evaluate = nullptr; + this->mempool = nullptr; + this->cdata = nullptr; } SelectionTreeElement::~SelectionTreeElement() @@ -195,8 +197,7 @@ void SelectionTreeElement::freeValues() gmx_ana_index_deinit(&v.u.g[i]); } break; - default: /* No special handling for other types */ - break; + default: /* No special handling for other types */ break; } } _gmx_selvalue_free(&v); @@ -209,8 +210,7 @@ void SelectionTreeElement::freeValues() } } -void -SelectionTreeElement::freeExpressionData() +void SelectionTreeElement::freeExpressionData() { if (type == SEL_EXPRESSION || type == SEL_MODIFIER) { @@ -232,8 +232,7 @@ SelectionTreeElement::freeExpressionData() sfree(u.arith.opstr); u.arith.opstr = nullptr; } - if (type == SEL_SUBEXPR || type == SEL_ROOT - || (type == SEL_CONST && v.type == GROUP_VALUE)) + if (type == SEL_SUBEXPR || type == SEL_ROOT || (type == SEL_CONST && v.type == GROUP_VALUE)) { gmx_ana_index_deinit(&u.cgrp); } @@ -252,21 +251,16 @@ void SelectionTreeElement::mempoolReserve(int count) switch (v.type) { case INT_VALUE: - v.u.i = static_cast( - _gmx_sel_mempool_alloc(mempool, sizeof(*v.u.i)*count)); + v.u.i = static_cast(_gmx_sel_mempool_alloc(mempool, sizeof(*v.u.i) * count)); break; case REAL_VALUE: - v.u.r = static_cast( - _gmx_sel_mempool_alloc(mempool, sizeof(*v.u.r)*count)); + v.u.r = static_cast(_gmx_sel_mempool_alloc(mempool, sizeof(*v.u.r) * count)); break; - case GROUP_VALUE: - _gmx_sel_mempool_alloc_group(mempool, v.u.g, count); - break; + case GROUP_VALUE: _gmx_sel_mempool_alloc_group(mempool, v.u.g, count); break; - default: - gmx_incons("Memory pooling not implemented for requested type"); + default: gmx_incons("Memory pooling not implemented for requested type"); } } @@ -291,15 +285,13 @@ void SelectionTreeElement::mempoolRelease() } break; - default: - gmx_incons("Memory pooling not implemented for requested type"); + default: gmx_incons("Memory pooling not implemented for requested type"); } } -void SelectionTreeElement::fillNameIfMissing(const char *selectionText) +void SelectionTreeElement::fillNameIfMissing(const char* selectionText) { - GMX_RELEASE_ASSERT(type == SEL_ROOT, - "Should not be called for non-root elements"); + GMX_RELEASE_ASSERT(type == SEL_ROOT, "Should not be called for non-root elements"); if (name().empty()) { // Check whether the actual selection given was from an external group, @@ -308,8 +300,7 @@ void SelectionTreeElement::fillNameIfMissing(const char *selectionText) if (_gmx_selelem_is_default_kwpos(*child) && child->child && child->child->type == SEL_SUBEXPRREF && child->child->child) { - if (child->child->child->type == SEL_CONST - && child->child->child->v.type == GROUP_VALUE) + if (child->child->child->type == SEL_CONST && child->child->child->v.type == GROUP_VALUE) { setName(child->child->child->name()); return; @@ -326,8 +317,7 @@ void SelectionTreeElement::fillNameIfMissing(const char *selectionText) } } -SelectionTopologyProperties -SelectionTreeElement::requiredTopologyProperties() const +SelectionTopologyProperties SelectionTreeElement::requiredTopologyProperties() const { SelectionTopologyProperties props; if (type == SEL_EXPRESSION || type == SEL_MODIFIER) @@ -342,10 +332,12 @@ SelectionTreeElement::requiredTopologyProperties() const if (u.expr.pc != nullptr) { auto requiredTopologyInfo = gmx_ana_poscalc_required_topology_info(u.expr.pc); - needsTop = needsTop - || (requiredTopologyInfo != PositionCalculationCollection::RequiredTopologyInfo::None); + needsTop = needsTop + || (requiredTopologyInfo + != PositionCalculationCollection::RequiredTopologyInfo::None); needsMasses = needsMasses - || (requiredTopologyInfo == PositionCalculationCollection::RequiredTopologyInfo::TopologyAndMasses); + || (requiredTopologyInfo + == PositionCalculationCollection::RequiredTopologyInfo::TopologyAndMasses); } if (needsTop) { @@ -365,12 +357,11 @@ SelectionTreeElement::requiredTopologyProperties() const return props; } -void SelectionTreeElement::checkUnsortedAtoms( - bool bUnsortedAllowed, ExceptionInitializer *errors) const +void SelectionTreeElement::checkUnsortedAtoms(bool bUnsortedAllowed, ExceptionInitializer* errors) const { - const bool bUnsortedSupported - = (type == SEL_CONST && v.type == GROUP_VALUE) - || type == SEL_ROOT || type == SEL_SUBEXPR || type == SEL_SUBEXPRREF + const bool bUnsortedSupported = + (type == SEL_CONST && v.type == GROUP_VALUE) || type == SEL_ROOT || type == SEL_SUBEXPR + || type == SEL_SUBEXPRREF // TODO: Consolidate. || type == SEL_MODIFIER || (type == SEL_EXPRESSION && ((u.expr.method->flags & SMETH_ALLOW_UNSORTED) != 0)); @@ -381,23 +372,21 @@ void SelectionTreeElement::checkUnsortedAtoms( SelectionTreeElementPointer child = this->child; while (child) { - child->checkUnsortedAtoms(bUnsortedAllowed && bUnsortedSupported, - errors); + child->checkUnsortedAtoms(bUnsortedAllowed && bUnsortedSupported, errors); child = child->next; } // The logic here is simplified by the fact that only constant groups can // currently be the root cause of SEL_UNSORTED being set, so only those // need to be considered in triggering the error. - if (!bUnsortedAllowed && (flags & SEL_UNSORTED) - && type == SEL_CONST && v.type == GROUP_VALUE) + if (!bUnsortedAllowed && (flags & SEL_UNSORTED) && type == SEL_CONST && v.type == GROUP_VALUE) { std::string message = formatString( - "Group '%s' cannot be used in selections except " - "as a full value of the selection, " - "because atom indices in it are not sorted and/or " - "it contains duplicate atoms.", - name().c_str()); + "Group '%s' cannot be used in selections except " + "as a full value of the selection, " + "because atom indices in it are not sorted and/or " + "it contains duplicate atoms.", + name().c_str()); errors->addNested(InconsistentInputError(message)); } } @@ -420,16 +409,14 @@ bool SelectionTreeElement::requiresIndexGroups() const return false; } -void SelectionTreeElement::resolveIndexGroupReference( - gmx_ana_indexgrps_t *grps, int natoms) +void SelectionTreeElement::resolveIndexGroupReference(gmx_ana_indexgrps_t* grps, int natoms) { GMX_RELEASE_ASSERT(type == SEL_GROUPREF, "Should only be called for index group reference elements"); if (grps == nullptr) { std::string message = formatString( - "Cannot match '%s', because index groups are not available.", - name().c_str()); + "Cannot match '%s', because index groups are not available.", name().c_str()); GMX_THROW(InconsistentInputError(message)); } @@ -440,8 +427,7 @@ void SelectionTreeElement::resolveIndexGroupReference( if (!gmx_ana_indexgrps_find(&foundGroup, &foundName, grps, u.gref.name)) { std::string message = formatString( - "Cannot match '%s', because no such index group can be found.", - name().c_str()); + "Cannot match '%s', because no such index group can be found.", name().c_str()); GMX_THROW(InconsistentInputError(message)); } } @@ -450,8 +436,7 @@ void SelectionTreeElement::resolveIndexGroupReference( if (!gmx_ana_indexgrps_extract(&foundGroup, &foundName, grps, u.gref.id)) { std::string message = formatString( - "Cannot match '%s', because no such index group can be found.", - name().c_str()); + "Cannot match '%s', because no such index group can be found.", name().c_str()); GMX_THROW(InconsistentInputError(message)); } } @@ -463,8 +448,7 @@ void SelectionTreeElement::resolveIndexGroupReference( sfree(u.gref.name); type = SEL_CONST; - gmx_ana_index_set(&u.cgrp, foundGroup.isize, foundGroup.index, - foundGroup.nalloc_index); + gmx_ana_index_set(&u.cgrp, foundGroup.isize, foundGroup.index, foundGroup.nalloc_index); setName(foundName); if (natoms > 0) @@ -480,10 +464,10 @@ void SelectionTreeElement::checkIndexGroup(int natoms) if (!gmx_ana_index_check_range(&u.cgrp, natoms)) { std::string message = formatString( - "Group '%s' cannot be used in selections, because it " - "contains negative atom indices and/or references atoms " - "not present (largest allowed atom index is %d).", - name().c_str(), natoms); + "Group '%s' cannot be used in selections, because it " + "contains negative atom indices and/or references atoms " + "not present (largest allowed atom index is %d).", + name().c_str(), natoms); GMX_THROW(InconsistentInputError(message)); } } @@ -500,9 +484,7 @@ void SelectionTreeElement::checkIndexGroup(int natoms) * This function should only be called at most once for each element, * preferably right after calling _gmx_selelem_create(). */ -void -_gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer &sel, - e_selvalue_t vtype) +void _gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer& sel, e_selvalue_t vtype) { GMX_RELEASE_ASSERT(sel->type != SEL_BOOLEAN || vtype == GROUP_VALUE, "Boolean elements must have a group value"); @@ -515,8 +497,7 @@ _gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer &sel, } } -void -_gmx_selelem_free_param(gmx_ana_selparam_t *param) +void _gmx_selelem_free_param(gmx_ana_selparam_t* param) { if (param->val.u.ptr != nullptr) { @@ -531,8 +512,7 @@ _gmx_selelem_free_param(gmx_ana_selparam_t *param) } } -void -_gmx_selelem_free_method(gmx_ana_selmethod_t *method, void *mdata) +void _gmx_selelem_free_method(gmx_ana_selmethod_t* method, void* mdata) { sel_freefunc free_func = nullptr; @@ -578,14 +558,12 @@ _gmx_selelem_free_method(gmx_ana_selmethod_t *method, void *mdata) * are printed as well. * \param[in] level Indentation level, starting from zero. */ -void -_gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, - bool bValues, int level) +void _gmx_selelem_print_tree(FILE* fp, const gmx::SelectionTreeElement& sel, bool bValues, int level) { - int i; + int i; - fprintf(fp, "%*c %s %s", level*2+1, '*', - _gmx_selelem_type_str(sel), _gmx_sel_value_type_str(&sel.v)); + fprintf(fp, "%*c %s %s", level * 2 + 1, '*', _gmx_selelem_type_str(sel), + _gmx_sel_value_type_str(&sel.v)); if (!sel.name().empty()) { fprintf(fp, " \"%s\"", sel.name().c_str()); @@ -639,7 +617,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, } else if (sel.v.type == GROUP_VALUE) { - const gmx_ana_index_t *g = sel.v.u.g; + const gmx_ana_index_t* g = sel.v.u.g; if (!g || g->isize == 0) { g = &sel.u.cgrp; @@ -651,8 +629,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, { fprintf(fp, " %s", _gmx_selelem_boolean_type_str(sel)); } - else if (sel.type == SEL_EXPRESSION - && sel.u.expr.method->name == sm_compare.name) + else if (sel.type == SEL_EXPRESSION && sel.u.expr.method->name == sm_compare.name) { _gmx_selelem_print_compare_info(fp, sel.u.expr.mdata); } @@ -669,18 +646,18 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, if ((sel.type == SEL_CONST && sel.v.type == GROUP_VALUE) || sel.type == SEL_ROOT) { - const gmx_ana_index_t *g = sel.v.u.g; + const gmx_ana_index_t* g = sel.v.u.g; if (!g || g->isize == 0 || sel.evaluate != nullptr) { g = &sel.u.cgrp; } if (g->isize < 0) { - fprintf(fp, "%*c group: (null)\n", level*2+1, ' '); + fprintf(fp, "%*c group: (null)\n", level * 2 + 1, ' '); } else if (g->isize > 0) { - fprintf(fp, "%*c group:", level*2+1, ' '); + fprintf(fp, "%*c group:", level * 2 + 1, ' '); if (g->isize <= 20) { for (i = 0; i < g->isize; ++i) @@ -699,13 +676,13 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, { if (sel.u.expr.pc) { - fprintf(fp, "%*c COM", level*2+3, '*'); + fprintf(fp, "%*c COM", level * 2 + 3, '*'); fprintf(fp, "\n"); } } else if (sel.type == SEL_SUBEXPRREF && sel.u.param != nullptr) { - fprintf(fp, "%*c param", level*2+1, ' '); + fprintf(fp, "%*c param", level * 2 + 1, ' '); if (sel.u.param->name != nullptr) { fprintf(fp, " \"%s\"", sel.u.param->name); @@ -728,7 +705,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, if (bValues && sel.type != SEL_CONST && sel.type != SEL_ROOT && sel.v.u.ptr) { - fprintf(fp, "%*c value: ", level*2+1, ' '); + fprintf(fp, "%*c value: ", level * 2 + 1, ' '); switch (sel.v.type) { case POS_VALUE: @@ -737,8 +714,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, * segfaults when printing the selection tree. */ if (sel.v.u.p->x) { - fprintf(fp, "(%f, %f, %f)", - sel.v.u.p->x[0][XX], sel.v.u.p->x[0][YY], + fprintf(fp, "(%f, %f, %f)", sel.v.u.p->x[0][XX], sel.v.u.p->x[0][YY], sel.v.u.p->x[0][ZZ]); } else @@ -760,9 +736,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, } } break; - default: - fprintf(fp, "???"); - break; + default: fprintf(fp, "???"); break; } fprintf(fp, "\n"); } @@ -773,7 +747,7 @@ _gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, { if (!(sel.type == SEL_SUBEXPRREF && child->type == SEL_SUBEXPR)) { - _gmx_selelem_print_tree(fp, *child, bValues, level+1); + _gmx_selelem_print_tree(fp, *child, bValues, level + 1); } child = child->next; } diff --git a/src/gromacs/selection/selelem.h b/src/gromacs/selection/selelem.h index 91f06b680b..b53bfca870 100644 --- a/src/gromacs/selection/selelem.h +++ b/src/gromacs/selection/selelem.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -107,32 +108,29 @@ typedef enum /** Defines the boolean operation of gmx::SelectionTreeElement objects with type \ref SEL_BOOLEAN. */ typedef enum { - BOOL_NOT, /**< Not */ - BOOL_AND, /**< And */ - BOOL_OR, /**< Or */ - BOOL_XOR /**< Xor (not implemented). */ + BOOL_NOT, /**< Not */ + BOOL_AND, /**< And */ + BOOL_OR, /**< Or */ + BOOL_XOR /**< Xor (not implemented). */ } e_boolean_t; /** Defines the arithmetic operation of gmx::SelectionTreeElement objects with type \ref SEL_ARITHMETIC. */ typedef enum { - ARITH_PLUS, /**< Addition (`+`) */ - ARITH_MINUS, /**< Subtraction (`-`) */ - ARITH_NEG, /**< Unary `-` */ - ARITH_MULT, /**< Multiplication (`*`) */ - ARITH_DIV, /**< Division (`/`) */ - ARITH_EXP /**< Power (`^`) */ + ARITH_PLUS, /**< Addition (`+`) */ + ARITH_MINUS, /**< Subtraction (`-`) */ + ARITH_NEG, /**< Unary `-` */ + ARITH_MULT, /**< Multiplication (`*`) */ + ARITH_DIV, /**< Division (`/`) */ + ARITH_EXP /**< Power (`^`) */ } e_arithmetic_t; /** Returns a string representation of the type of a gmx::SelectionTreeElement. */ -extern const char * -_gmx_selelem_type_str(const gmx::SelectionTreeElement &sel); +extern const char* _gmx_selelem_type_str(const gmx::SelectionTreeElement& sel); /** Returns a string representation of the boolean type of a \ref SEL_BOOLEAN gmx::SelectionTreeElement. */ -extern const char * -_gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement &sel); +extern const char* _gmx_selelem_boolean_type_str(const gmx::SelectionTreeElement& sel); /** Returns a string representation of the type of a \c gmx_ana_selvalue_t. */ -extern const char * -_gmx_sel_value_type_str(const gmx_ana_selvalue_t *val); +extern const char* _gmx_sel_value_type_str(const gmx_ana_selvalue_t* val); //!\} @@ -148,29 +146,29 @@ _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val); * If this flag is set, the flags covered by \ref SEL_VALFLAGMASK * have been set properly for the element. */ -#define SEL_FLAGSSET 1 +#define SEL_FLAGSSET 1 /*! \brief * The element evaluates to a single value. * * This flag is always set for \ref GROUP_VALUE elements. */ -#define SEL_SINGLEVAL 2 +#define SEL_SINGLEVAL 2 /*! \brief * The element evaluates to one value for each input atom. */ -#define SEL_ATOMVAL 4 +#define SEL_ATOMVAL 4 /*! \brief * The element evaluates to an arbitrary number of values. */ -#define SEL_VARNUMVAL 8 +#define SEL_VARNUMVAL 8 /*! \brief * The element (or one of its children) is dynamic. */ -#define SEL_DYNAMIC 16 +#define SEL_DYNAMIC 16 /*! \brief * The element may contain atom indices in an unsorted order. */ -#define SEL_UNSORTED 32 +#define SEL_UNSORTED 32 /*! \brief * Mask that covers the flags that describe the number of values. */ @@ -196,7 +194,7 @@ _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val); * is changed and is used in places where this flag is not, so this would * require a careful investigation of the selection code. */ -#define SEL_ALLOCVAL (1<<8) +#define SEL_ALLOCVAL (1 << 8) /*! \brief * Data has been allocated for the group/position structure. * @@ -206,11 +204,11 @@ _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val); * This field has no effect if the value type is not \ref GROUP_VALUE or * \ref POS_VALUE, but should not be set. */ -#define SEL_ALLOCDATA (1<<9) +#define SEL_ALLOCDATA (1 << 9) /*! \brief * \p method->init_frame should be called for the frame. */ -#define SEL_INITFRAME (1<<10) +#define SEL_INITFRAME (1 << 10) /*! \brief * Parameter has been evaluated for the current frame. * @@ -220,17 +218,17 @@ _gmx_sel_value_type_str(const gmx_ana_selvalue_t *val); * It is not set for \ref SEL_ATOMVAL elements, because they may need to * be evaluated multiple times. */ -#define SEL_EVALFRAME (1<<11) +#define SEL_EVALFRAME (1 << 11) /*! \brief * \p method->init has been called. */ -#define SEL_METHODINIT (1<<12) +#define SEL_METHODINIT (1 << 12) /*! \brief * \p method->outinit has been called. * * This flag is also used for \ref SEL_SUBEXPRREF elements. */ -#define SEL_OUTINIT (1<<13) +#define SEL_OUTINIT (1 << 13) //!\} @@ -243,9 +241,9 @@ class ExceptionInitializer; /*! \brief * Function pointer for evaluating a gmx::SelectionTreeElement. */ -typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t *data, - const SelectionTreeElementPointer &sel, - gmx_ana_index_t *g); +typedef void (*sel_evalfunc)(struct gmx_sel_evaluate_t* data, + const SelectionTreeElementPointer& sel, + gmx_ana_index_t* g); //! \endcond /*! \internal @@ -264,14 +262,14 @@ struct SelectionLocation //! Returns an empty location. static SelectionLocation createEmpty() { - SelectionLocation empty = {0, 0}; + SelectionLocation empty = { 0, 0 }; return empty; } //! Start index of the string where this element has been parsed from. - int startIndex; + int startIndex; //! End index of the string where this element has been parsed from. - int endIndex; + int endIndex; }; /*! \internal \brief @@ -279,226 +277,228 @@ struct SelectionLocation */ class SelectionTreeElement { - public: - /*! \brief - * Allocates memory and performs common initialization. +public: + /*! \brief + * Allocates memory and performs common initialization. + * + * \param[in] type Type of selection element to create. + * \param[in] location Location of the element. + * + * \a type is set to \p type, + * \a v::type is set to \ref GROUP_VALUE for boolean and comparison + * expressions and \ref NO_VALUE for others, and + * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA + * is also set for \ref SEL_BOOLEAN elements). + * All the pointers are set to NULL. + */ + SelectionTreeElement(e_selelem_t type, const SelectionLocation& location); + ~SelectionTreeElement(); + + //! Frees the memory allocated for the \a v union. + void freeValues(); + //! Frees the memory allocated for the \a u union. + void freeExpressionData(); + /* In compiler.cpp */ + /*! \brief + * Frees the memory allocated for the selection compiler. + * + * This function only frees the data for the given selection, not its + * children. It is safe to call the function when compiler data has + * not been allocated or has already been freed; in such a case, + * nothing is done. + */ + void freeCompilerData(); + + /*! \brief + * Reserves memory for value from a memory pool. + * + * \param[in] count Number of values to reserve memory for. + * + * Reserves memory for the values of this element from the \a mempool + * memory pool. + * If no memory pool is set, nothing is done. + */ + void mempoolReserve(int count); + /*! \brief + * Releases memory pool used for value. + * + * Releases the memory allocated for the values of this element from the + * \a mempool memory pool. + * If no memory pool is set, nothing is done. + */ + void mempoolRelease(); + + //! Returns the name of the element. + const std::string& name() const { return name_; } + //! Returns the location of the element. + const SelectionLocation& location() const { return location_; } + + /*! \brief + * Sets the name of the element. + * + * \param[in] name Name to set (can be NULL). + * \throws std::bad_alloc if out of memory. + */ + void setName(const char* name) { name_ = (name != nullptr ? name : ""); } + //! \copydoc setName(const char *) + void setName(const std::string& name) { name_ = name; } + /*! \brief + * Sets the name of a root element if it is missing. + * + * \param[in] selectionText Full selection text to use as a fallback. + * \throws std::bad_alloc if out of memory. + * + * If index groups have not yet been set and the selection is a result + * of a group reference, the name may still be empty after this call. + * + * Strong exception safety guarantee. + */ + void fillNameIfMissing(const char* selectionText); + + /*! \brief + * Returns which topology properties the selection element subtree requires + * for evaluation. + * + * \returns List of topology properties required for evaluation. + */ + SelectionTopologyProperties requiredTopologyProperties() const; + /*! \brief + * Checks that this element and its children do not contain unsupported + * elements with unsorted atoms. + * + * \param[in] bUnsortedAllowed Whether this element's parents allow it + * to have unsorted atoms. + * \param errors Object for reporting any error messages. + * \throws std::bad_alloc if out of memory. + * + * Errors are reported as nested exceptions in \p errors. + */ + void checkUnsortedAtoms(bool bUnsortedAllowed, ExceptionInitializer* errors) const; + /*! \brief + * Checks whether the element or its children have unresolved index + * group references. + * + * Does not throw. + */ + bool requiresIndexGroups() const; + /*! \brief + * Resolves an unresolved reference to an index group. + * + * \param[in] grps Index groups to use to resolve the reference. + * \param[in] natoms Maximum number of atoms the selections can evaluate to + * (zero if the topology/atom count is not set yet). + * \throws std::bad_alloc if out of memory. + * \throws InconsistentInputError if the reference cannot be + * resolved. + */ + void resolveIndexGroupReference(gmx_ana_indexgrps_t* grps, int natoms); + /*! \brief + * Checks that an index group has valid atom indices. + * + * \param[in] natoms Maximum number of atoms the selections can evaluate to. + * \throws std::bad_alloc if out of memory. + * \throws InconsistentInputError if there are invalid atom indices. + */ + void checkIndexGroup(int natoms); + + //! Type of the element. + e_selelem_t type; + /*! \brief + * Value storage of the element. + * + * This field contains the evaluated value of the element, as well as + * the output value type. + */ + gmx_ana_selvalue_t v; + /*! \brief + * Evaluation function for the element. + * + * Can be either NULL (if the expression is a constant and does not + * require evaluation) or point to one of the functions defined in + * evaluate.h. + */ + sel_evalfunc evaluate; + /*! \brief + * Information flags about the element. + * + * Allowed flags are listed here: + * \ref selelem_flags "flags for gmx::SelectionTreeElement". + */ + int flags; + //! Data required by the evaluation function. + union { + /*! \brief Index group data for several element types. * - * \param[in] type Type of selection element to create. - * \param[in] location Location of the element. - * - * \a type is set to \p type, - * \a v::type is set to \ref GROUP_VALUE for boolean and comparison - * expressions and \ref NO_VALUE for others, and - * \ref SEL_ALLOCVAL is set for non-root elements (\ref SEL_ALLOCDATA - * is also set for \ref SEL_BOOLEAN elements). - * All the pointers are set to NULL. - */ - SelectionTreeElement(e_selelem_t type, const SelectionLocation &location); - ~SelectionTreeElement(); - - //! Frees the memory allocated for the \a v union. - void freeValues(); - //! Frees the memory allocated for the \a u union. - void freeExpressionData(); - /* In compiler.cpp */ - /*! \brief - * Frees the memory allocated for the selection compiler. - * - * This function only frees the data for the given selection, not its - * children. It is safe to call the function when compiler data has - * not been allocated or has already been freed; in such a case, - * nothing is done. - */ - void freeCompilerData(); - - /*! \brief - * Reserves memory for value from a memory pool. - * - * \param[in] count Number of values to reserve memory for. - * - * Reserves memory for the values of this element from the \a mempool - * memory pool. - * If no memory pool is set, nothing is done. - */ - void mempoolReserve(int count); - /*! \brief - * Releases memory pool used for value. - * - * Releases the memory allocated for the values of this element from the - * \a mempool memory pool. - * If no memory pool is set, nothing is done. - */ - void mempoolRelease(); - - //! Returns the name of the element. - const std::string &name() const { return name_; } - //! Returns the location of the element. - const SelectionLocation &location() const { return location_; } - - /*! \brief - * Sets the name of the element. - * - * \param[in] name Name to set (can be NULL). - * \throws std::bad_alloc if out of memory. - */ - void setName(const char *name) { name_ = (name != nullptr ? name : ""); } - //! \copydoc setName(const char *) - void setName(const std::string &name) { name_ = name; } - /*! \brief - * Sets the name of a root element if it is missing. - * - * \param[in] selectionText Full selection text to use as a fallback. - * \throws std::bad_alloc if out of memory. - * - * If index groups have not yet been set and the selection is a result - * of a group reference, the name may still be empty after this call. - * - * Strong exception safety guarantee. - */ - void fillNameIfMissing(const char *selectionText); - - /*! \brief - * Returns which topology properties the selection element subtree requires - * for evaluation. - * - * \returns List of topology properties required for evaluation. - */ - SelectionTopologyProperties requiredTopologyProperties() const; - /*! \brief - * Checks that this element and its children do not contain unsupported - * elements with unsorted atoms. - * - * \param[in] bUnsortedAllowed Whether this element's parents allow it - * to have unsorted atoms. - * \param errors Object for reporting any error messages. - * \throws std::bad_alloc if out of memory. - * - * Errors are reported as nested exceptions in \p errors. - */ - void checkUnsortedAtoms(bool bUnsortedAllowed, - ExceptionInitializer *errors) const; - /*! \brief - * Checks whether the element or its children have unresolved index - * group references. - * - * Does not throw. - */ - bool requiresIndexGroups() const; - /*! \brief - * Resolves an unresolved reference to an index group. - * - * \param[in] grps Index groups to use to resolve the reference. - * \param[in] natoms Maximum number of atoms the selections can evaluate to - * (zero if the topology/atom count is not set yet). - * \throws std::bad_alloc if out of memory. - * \throws InconsistentInputError if the reference cannot be - * resolved. - */ - void resolveIndexGroupReference(gmx_ana_indexgrps_t *grps, int natoms); - /*! \brief - * Checks that an index group has valid atom indices. - * - * \param[in] natoms Maximum number of atoms the selections can evaluate to. - * \throws std::bad_alloc if out of memory. - * \throws InconsistentInputError if there are invalid atom indices. - */ - void checkIndexGroup(int natoms); - - //! Type of the element. - e_selelem_t type; - /*! \brief - * Value storage of the element. - * - * This field contains the evaluated value of the element, as well as - * the output value type. - */ - gmx_ana_selvalue_t v; - /*! \brief - * Evaluation function for the element. - * - * Can be either NULL (if the expression is a constant and does not - * require evaluation) or point to one of the functions defined in - * evaluate.h. - */ - sel_evalfunc evaluate; - /*! \brief - * Information flags about the element. - * - * Allowed flags are listed here: - * \ref selelem_flags "flags for gmx::SelectionTreeElement". + * - \ref SEL_CONST : if the value type is \ref GROUP_VALUE, + * this field holds the unprocessed group value. + * - \ref SEL_ROOT : holds the group value for which the + * selection subtree should be evaluated. + * - \ref SEL_SUBEXPR : holds the group for which the subexpression + * has been evaluated. */ - int flags; - //! Data required by the evaluation function. - union { - /*! \brief Index group data for several element types. - * - * - \ref SEL_CONST : if the value type is \ref GROUP_VALUE, - * this field holds the unprocessed group value. - * - \ref SEL_ROOT : holds the group value for which the - * selection subtree should be evaluated. - * - \ref SEL_SUBEXPR : holds the group for which the subexpression - * has been evaluated. - */ - gmx_ana_index_t cgrp; - //! Data for \ref SEL_EXPRESSION and \ref SEL_MODIFIER elements. - struct { - //! Pointer the method used in this expression. - struct gmx_ana_selmethod_t *method; - //! Pointer to the data allocated by the method's \p init_data (see sel_datafunc()). - void *mdata; - //! Pointer to the position data passed to the method. - struct gmx_ana_pos_t *pos; - //! Pointer to the evaluation data for \p pos. - struct gmx_ana_poscalc_t *pc; - } expr; - //! Operation type for \ref SEL_BOOLEAN elements. - e_boolean_t boolt; - //! Operation type for \ref SEL_ARITHMETIC elements. - struct { - //! Operation type. - e_arithmetic_t type; - //! String representation. - char *opstr; - } arith; - //! Associated selection parameter for \ref SEL_SUBEXPRREF elements. - struct gmx_ana_selparam_t *param; - //! The string/number used to reference the group. - struct { - //! Name of the referenced external group. - char *name; - //! If \a name is NULL, the index number of the referenced group. - int id; - } gref; - } u; - //! Memory pool to use for values, or NULL if standard memory handling. - struct gmx_sel_mempool_t *mempool; - //! Internal data for the selection compiler. - t_compiler_data *cdata; - - /*! \brief The first child element. - * - * Other children can be accessed through the \p next field of \p child. - */ - SelectionTreeElementPointer child; - //! The next sibling element. - SelectionTreeElementPointer next; - - private: - /*! \brief - * Name of the element. - * - * This field is only used for diagnostic purposes. - */ - std::string name_; - /*! \brief - * Location of the element in the selection text. - * - * This field is only used for diagnostic purposes (including error - * messages). - */ - SelectionLocation location_; - - GMX_DISALLOW_COPY_AND_ASSIGN(SelectionTreeElement); + gmx_ana_index_t cgrp; + //! Data for \ref SEL_EXPRESSION and \ref SEL_MODIFIER elements. + struct + { + //! Pointer the method used in this expression. + struct gmx_ana_selmethod_t* method; + //! Pointer to the data allocated by the method's \p init_data (see sel_datafunc()). + void* mdata; + //! Pointer to the position data passed to the method. + struct gmx_ana_pos_t* pos; + //! Pointer to the evaluation data for \p pos. + struct gmx_ana_poscalc_t* pc; + } expr; + //! Operation type for \ref SEL_BOOLEAN elements. + e_boolean_t boolt; + //! Operation type for \ref SEL_ARITHMETIC elements. + struct + { + //! Operation type. + e_arithmetic_t type; + //! String representation. + char* opstr; + } arith; + //! Associated selection parameter for \ref SEL_SUBEXPRREF elements. + struct gmx_ana_selparam_t* param; + //! The string/number used to reference the group. + struct + { + //! Name of the referenced external group. + char* name; + //! If \a name is NULL, the index number of the referenced group. + int id; + } gref; + } u; + //! Memory pool to use for values, or NULL if standard memory handling. + struct gmx_sel_mempool_t* mempool; + //! Internal data for the selection compiler. + t_compiler_data* cdata; + + /*! \brief The first child element. + * + * Other children can be accessed through the \p next field of \p child. + */ + SelectionTreeElementPointer child; + //! The next sibling element. + SelectionTreeElementPointer next; + +private: + /*! \brief + * Name of the element. + * + * This field is only used for diagnostic purposes. + */ + std::string name_; + /*! \brief + * Location of the element in the selection text. + * + * This field is only used for diagnostic purposes (including error + * messages). + */ + SelectionLocation location_; + + GMX_DISALLOW_COPY_AND_ASSIGN(SelectionTreeElement); }; } // namespace gmx @@ -510,47 +510,36 @@ class SelectionTreeElement /* In evaluate.c */ /** Writes out a human-readable name for an evaluation function. */ -void -_gmx_sel_print_evalfunc_name(FILE *fp, gmx::sel_evalfunc evalfunc); +void _gmx_sel_print_evalfunc_name(FILE* fp, gmx::sel_evalfunc evalfunc); /** Sets the value type of a gmx::SelectionTreeElement. */ -void -_gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer &sel, - e_selvalue_t vtype); +void _gmx_selelem_set_vtype(const gmx::SelectionTreeElementPointer& sel, e_selvalue_t vtype); /*! \brief * Frees the memory allocated for a selection method parameter. * * \param[in] param Parameter to free. */ -void -_gmx_selelem_free_param(struct gmx_ana_selparam_t *param); +void _gmx_selelem_free_param(struct gmx_ana_selparam_t* param); /*! \brief * Frees the memory allocated for a selection method. * * \param[in] method Method to free. * \param[in] mdata Method data to free. */ -void -_gmx_selelem_free_method(struct gmx_ana_selmethod_t *method, void *mdata); +void _gmx_selelem_free_method(struct gmx_ana_selmethod_t* method, void* mdata); /** Prints a human-readable version of a selection element subtree. */ -void -_gmx_selelem_print_tree(FILE *fp, const gmx::SelectionTreeElement &sel, - bool bValues, int level); +void _gmx_selelem_print_tree(FILE* fp, const gmx::SelectionTreeElement& sel, bool bValues, int level); /* In compiler.c */ /** Prints a human-readable version of the internal compiler data structure. */ -void -_gmx_selelem_print_compiler_info(FILE *fp, const gmx::SelectionTreeElement &sel, - int level); +void _gmx_selelem_print_compiler_info(FILE* fp, const gmx::SelectionTreeElement& sel, int level); /* In sm_insolidangle.c */ /** Returns true if the covered fraction of the selection can be calculated. */ -bool -_gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel); +bool _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement& sel); /** Returns the covered fraction of the selection for the current frame. */ -real -_gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement &sel); +real _gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement& sel); //!\} diff --git a/src/gromacs/selection/selhelp.cpp b/src/gromacs/selection/selhelp.cpp index 7a966f6ef8..159cda551d 100644 --- a/src/gromacs/selection/selhelp.cpp +++ b/src/gromacs/selection/selhelp.cpp @@ -66,13 +66,12 @@ struct CommonHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char CommonHelpText::name[] = "selections"; -const char CommonHelpText::title[] = - "Selection syntax and usage"; -const char *const CommonHelpText::text[] = { +const char CommonHelpText::title[] = "Selection syntax and usage"; +const char* const CommonHelpText::text[] = { "Selections are used to select atoms/molecules/residues for analysis.", "In contrast to traditional index files, selections can be dynamic, i.e.,", "select different atoms for different trajectory frames. The GROMACS", @@ -95,13 +94,12 @@ struct ArithmeticHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char ArithmeticHelpText::name[] = "arithmetic"; -const char ArithmeticHelpText::title[] = - "Arithmetic expressions in selections"; -const char *const ArithmeticHelpText::text[] = { +const char ArithmeticHelpText::title[] = "Arithmetic expressions in selections"; +const char* const ArithmeticHelpText::text[] = { "Basic arithmetic evaluation is supported for numeric expressions.", "Supported operations are addition, subtraction, negation, multiplication,", "division, and exponentiation (using ^).", @@ -112,13 +110,12 @@ struct CmdLineHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char CmdLineHelpText::name[] = "cmdline"; -const char CmdLineHelpText::title[] = - "Specifying selections from command line"; -const char *const CmdLineHelpText::text[] = { +const char CmdLineHelpText::title[] = "Specifying selections from command line"; +const char* const CmdLineHelpText::text[] = { "If no selections are provided on the command line, you are prompted to", "type the selections interactively (a pipe can also be used to provide", "the selections in this case for most tools). While this works well for", @@ -186,13 +183,12 @@ struct EvaluationHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char EvaluationHelpText::name[] = "evaluation"; -const char EvaluationHelpText::title[] = - "Selection evaluation and optimization"; -const char *const EvaluationHelpText::text[] = { +const char EvaluationHelpText::title[] = "Selection evaluation and optimization"; +const char* const EvaluationHelpText::text[] = { "Boolean evaluation proceeds from left to right and is short-circuiting", "i.e., as soon as it is known whether an atom will be selected, the", "remaining expressions are not evaluated at all.", @@ -227,13 +223,12 @@ struct ExamplesHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char ExamplesHelpText::name[] = "examples"; -const char ExamplesHelpText::title[] = - "Selection examples"; -const char *const ExamplesHelpText::text[] = { +const char ExamplesHelpText::title[] = "Selection examples"; +const char* const ExamplesHelpText::text[] = { "Below, examples of different types of selections are given.", "", "* Selection of all water oxygens::", @@ -324,13 +319,12 @@ struct KeywordsHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char KeywordsHelpText::name[] = "keywords"; -const char KeywordsHelpText::title[] = - "Selection keywords"; -const char *const KeywordsHelpText::text[] = { +const char KeywordsHelpText::title[] = "Selection keywords"; +const char* const KeywordsHelpText::text[] = { "The following selection keywords are currently available.", "For keywords marked with a plus, additional help is available through", "a subtopic KEYWORD, where KEYWORD is the name of the keyword.", @@ -340,13 +334,12 @@ struct LimitationsHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char LimitationsHelpText::name[] = "limitations"; -const char LimitationsHelpText::title[] = - "Selection limitations"; -const char *const LimitationsHelpText::text[] = { +const char LimitationsHelpText::title[] = "Selection limitations"; +const char* const LimitationsHelpText::text[] = { "* Some analysis programs may require a special structure for the input", " selections (e.g., some options of [TT]gmx gangle[tt] require the index", " group to be made of groups of three or four atoms).", @@ -398,13 +391,12 @@ struct PositionsHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char PositionsHelpText::name[] = "positions"; -const char PositionsHelpText::title[] = - "Specifying positions in selections"; -const char *const PositionsHelpText::text[] = { +const char PositionsHelpText::title[] = "Specifying positions in selections"; +const char* const PositionsHelpText::text[] = { "Possible ways of specifying positions in selections are:", "", "1. A constant position can be defined as [TT][XX, YY, ZZ][tt], where", @@ -451,13 +443,12 @@ struct SyntaxHelpText { static const char name[]; static const char title[]; - static const char *const text[]; + static const char* const text[]; }; const char SyntaxHelpText::name[] = "syntax"; -const char SyntaxHelpText::title[] = - "Selection syntax"; -const char *const SyntaxHelpText::text[] = { +const char SyntaxHelpText::title[] = "Selection syntax"; +const char* const SyntaxHelpText::text[] = { "A set of selections consists of one or more selections, separated by", "semicolons. Each selection defines a set of positions for the analysis.", "Each selection can also be preceded by a string that gives a name for", @@ -544,35 +535,28 @@ namespace */ class KeywordDetailsHelpTopic : public AbstractSimpleHelpTopic { - public: - //! Initialize help topic for the given selection method. - KeywordDetailsHelpTopic(const std::string &name, - const gmx_ana_selmethod_t &method) - : name_(name), method_(method) - { - } +public: + //! Initialize help topic for the given selection method. + KeywordDetailsHelpTopic(const std::string& name, const gmx_ana_selmethod_t& method) : + name_(name), + method_(method) + { + } - const char *name() const override - { - return name_.c_str(); - } - const char *title() const override - { - return method_.help.helpTitle; - } + const char* name() const override { return name_.c_str(); } + const char* title() const override { return method_.help.helpTitle; } - protected: - std::string helpText() const override - { - return joinStrings(method_.help.help, - method_.help.help + method_.help.nlhelp, "\n"); - } +protected: + std::string helpText() const override + { + return joinStrings(method_.help.help, method_.help.help + method_.help.nlhelp, "\n"); + } - private: - std::string name_; - const gmx_ana_selmethod_t &method_; +private: + std::string name_; + const gmx_ana_selmethod_t& method_; - GMX_DISALLOW_COPY_AND_ASSIGN(KeywordDetailsHelpTopic); + GMX_DISALLOW_COPY_AND_ASSIGN(KeywordDetailsHelpTopic); }; /*! \internal \brief @@ -582,53 +566,48 @@ class KeywordDetailsHelpTopic : public AbstractSimpleHelpTopic */ class KeywordsHelpTopic : public CompositeHelpTopic { - public: - KeywordsHelpTopic(); - - void writeHelp(const HelpWriterContext &context) const override; - - private: - /*! \brief - * Container for known selection methods. - * - * The first item in the pair is the name of the selection method, and - * the second points to the static data structure that describes the - * method. - * The name in the first item may differ from the name of the static - * data structure if an alias is defined for that method. - */ - typedef std::vector > - MethodList; - - /*! \brief - * Prints markup for starting a list of keywords. - */ - void writeKeywordListStart(const HelpWriterContext &context, - const char *heading) const; - /*! \brief - * Prints markup for ending a list of keywords. - */ - void writeKeywordListEnd(const HelpWriterContext &context, - const char *extraInfo) const; - - /*! \brief - * Prints a brief list of keywords (selection methods) available. - * - * \param[in] context Context for printing the help. - * \param[in] type Only methods that return this type are printed. - * \param[in] bModifiers If false, \ref SMETH_MODIFIER methods are - * excluded, otherwise only them are printed. - */ - void printKeywordList(const HelpWriterContext &context, - e_selvalue_t type, bool bModifiers) const; - - /*! \brief - * Prints the detailed help for keywords for rst export. - */ - void writeKeywordSubTopics(const HelpWriterContext &context) const; - - MethodList methods_; +public: + KeywordsHelpTopic(); + + void writeHelp(const HelpWriterContext& context) const override; + +private: + /*! \brief + * Container for known selection methods. + * + * The first item in the pair is the name of the selection method, and + * the second points to the static data structure that describes the + * method. + * The name in the first item may differ from the name of the static + * data structure if an alias is defined for that method. + */ + typedef std::vector> MethodList; + + /*! \brief + * Prints markup for starting a list of keywords. + */ + void writeKeywordListStart(const HelpWriterContext& context, const char* heading) const; + /*! \brief + * Prints markup for ending a list of keywords. + */ + void writeKeywordListEnd(const HelpWriterContext& context, const char* extraInfo) const; + + /*! \brief + * Prints a brief list of keywords (selection methods) available. + * + * \param[in] context Context for printing the help. + * \param[in] type Only methods that return this type are printed. + * \param[in] bModifiers If false, \ref SMETH_MODIFIER methods are + * excluded, otherwise only them are printed. + */ + void printKeywordList(const HelpWriterContext& context, e_selvalue_t type, bool bModifiers) const; + + /*! \brief + * Prints the detailed help for keywords for rst export. + */ + void writeKeywordSubTopics(const HelpWriterContext& context) const; + + MethodList methods_; }; KeywordsHelpTopic::KeywordsHelpTopic() @@ -636,27 +615,24 @@ KeywordsHelpTopic::KeywordsHelpTopic() // TODO: This is not a very elegant way of getting the list of selection // methods, but this needs to be rewritten in any case if/when #652 is // implemented. - const std::unique_ptr symtab( - new SelectionParserSymbolTable); + const std::unique_ptr symtab(new SelectionParserSymbolTable); gmx_ana_selmethod_register_defaults(symtab.get()); - SelectionParserSymbolIterator symbol - = symtab->beginIterator(SelectionParserSymbol::MethodSymbol); + SelectionParserSymbolIterator symbol = symtab->beginIterator(SelectionParserSymbol::MethodSymbol); while (symbol != symtab->endIterator()) { - const std::string &symname = symbol->name(); - const gmx_ana_selmethod_t *method = symbol->methodValue(); + const std::string& symname = symbol->name(); + const gmx_ana_selmethod_t* method = symbol->methodValue(); methods_.push_back(std::make_pair(std::string(symname), method)); if (method->help.nlhelp > 0 && method->help.help != nullptr) { - addSubTopic(HelpTopicPointer( - new KeywordDetailsHelpTopic(symname, *method))); + addSubTopic(HelpTopicPointer(new KeywordDetailsHelpTopic(symname, *method))); } ++symbol; } } -void KeywordsHelpTopic::writeHelp(const HelpWriterContext &context) const +void KeywordsHelpTopic::writeHelp(const HelpWriterContext& context) const { context.writeTextBlock(helpText()); @@ -689,8 +665,7 @@ void KeywordsHelpTopic::writeHelp(const HelpWriterContext &context) const writeKeywordSubTopics(context); } -void KeywordsHelpTopic::writeKeywordListStart(const HelpWriterContext &context, - const char *heading) const +void KeywordsHelpTopic::writeKeywordListStart(const HelpWriterContext& context, const char* heading) const { context.paragraphBreak(); std::string fullHeading("* "); @@ -704,8 +679,7 @@ void KeywordsHelpTopic::writeKeywordListStart(const HelpWriterContext &context, } } -void KeywordsHelpTopic::writeKeywordListEnd(const HelpWriterContext &context, - const char *extraInfo) const +void KeywordsHelpTopic::writeKeywordListEnd(const HelpWriterContext& context, const char* extraInfo) const { if (context.outputFormat() == eHelpOutputFormat_Rst) { @@ -719,22 +693,18 @@ void KeywordsHelpTopic::writeKeywordListEnd(const HelpWriterContext &context, } } -void KeywordsHelpTopic::printKeywordList(const HelpWriterContext &context, - e_selvalue_t type, - bool bModifiers) const +void KeywordsHelpTopic::printKeywordList(const HelpWriterContext& context, e_selvalue_t type, bool bModifiers) const { - TextWriter &file = context.outputFile(); + TextWriter& file = context.outputFile(); MethodList::const_iterator iter; for (iter = methods_.begin(); iter != methods_.end(); ++iter) { - const gmx_ana_selmethod_t &method = *iter->second; - const bool bIsModifier - = (method.flags & SMETH_MODIFIER) != 0; + const gmx_ana_selmethod_t& method = *iter->second; + const bool bIsModifier = (method.flags & SMETH_MODIFIER) != 0; if (method.type == type && bModifiers == bIsModifier) { - const bool bHasHelp = (method.help.nlhelp > 0 && method.help.help != nullptr); - const bool bPrintHelpMark - = bHasHelp && context.outputFormat() == eHelpOutputFormat_Console; + const bool bHasHelp = (method.help.nlhelp > 0 && method.help.help != nullptr); + const bool bPrintHelpMark = bHasHelp && context.outputFormat() == eHelpOutputFormat_Console; file.writeString(formatString(" %c ", bPrintHelpMark ? '+' : ' ')); if (method.help.syntax != nullptr) { @@ -753,7 +723,7 @@ void KeywordsHelpTopic::printKeywordList(const HelpWriterContext &context, } } -void KeywordsHelpTopic::writeKeywordSubTopics(const HelpWriterContext &context) const +void KeywordsHelpTopic::writeKeywordSubTopics(const HelpWriterContext& context) const { if (context.outputFormat() != eHelpOutputFormat_Rst) { @@ -763,15 +733,14 @@ void KeywordsHelpTopic::writeKeywordSubTopics(const HelpWriterContext &context) MethodList::const_iterator iter; for (iter = methods_.begin(); iter != methods_.end(); ++iter) { - const gmx_ana_selmethod_t &method = *iter->second; - const bool bHasHelp - = (method.help.nlhelp > 0 && method.help.help != nullptr); + const gmx_ana_selmethod_t& method = *iter->second; + const bool bHasHelp = (method.help.nlhelp > 0 && method.help.help != nullptr); if (!bHasHelp || usedSymbols.count(iter->first) > 0) { continue; } - std::string title; + std::string title; if (method.help.helpTitle != nullptr) { title = method.help.helpTitle; @@ -789,28 +758,28 @@ void KeywordsHelpTopic::writeKeywordSubTopics(const HelpWriterContext &context) } } - const IHelpTopic *subTopic = findSubTopic(iter->first.c_str()); + const IHelpTopic* subTopic = findSubTopic(iter->first.c_str()); GMX_RELEASE_ASSERT(subTopic != nullptr, "Keyword subtopic no longer exists"); - HelpWriterContext subContext(context); + HelpWriterContext subContext(context); subContext.enterSubSection(title); subTopic->writeHelp(subContext); } } -} // namespace +} // namespace //! \cond libapi */ HelpTopicPointer createSelectionHelpTopic() { CompositeHelpTopicPointer root(new CompositeHelpTopic); - root->registerSubTopic >(); - root->registerSubTopic >(); - root->registerSubTopic >(); - root->registerSubTopic >(); + root->registerSubTopic>(); + root->registerSubTopic>(); + root->registerSubTopic>(); + root->registerSubTopic>(); root->registerSubTopic(); - root->registerSubTopic >(); - root->registerSubTopic >(); - root->registerSubTopic >(); + root->registerSubTopic>(); + root->registerSubTopic>(); + root->registerSubTopic>(); return HelpTopicPointer(root.release()); } //! \endcond diff --git a/src/gromacs/selection/selmethod.cpp b/src/gromacs/selection/selmethod.cpp index b2a456481b..a648c3ca4f 100644 --- a/src/gromacs/selection/selmethod.cpp +++ b/src/gromacs/selection/selmethod.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,26 +58,26 @@ /*! \internal \brief * Helper structure for defining selection methods. */ -typedef struct { +typedef struct +{ /*! \brief * Name to register the method under. * * If NULL, use the actual name of the method. * This field is used for defining synonyms. */ - const char *name; + const char* name; /** Method data structure to register. */ - gmx_ana_selmethod_t *method; + gmx_ana_selmethod_t* method; } t_register_method; /*! \brief * Convenience function for reporting errors found in selection methods. */ -static void -report_error(FILE *fp, const char *name, gmx_fmtstr const char *fmt, ...) gmx_format(printf, 3, 4); +static void report_error(FILE* fp, const char* name, gmx_fmtstr const char* fmt, ...) + gmx_format(printf, 3, 4); -static void -report_error(FILE *fp, const char *name, gmx_fmtstr const char *fmt, ...) +static void report_error(FILE* fp, const char* name, gmx_fmtstr const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -92,12 +93,9 @@ report_error(FILE *fp, const char *name, gmx_fmtstr const char *fmt, ...) /*! \brief * Convenience function for reporting errors found in selection method parameters. */ -static void -report_param_error(FILE *fp, const char *mname, const char *pname, - gmx_fmtstr const char *fmt, ...) gmx_format(printf, 4, 5); -static void -report_param_error(FILE *fp, const char *mname, const char *pname, - gmx_fmtstr const char *fmt, ...) +static void report_param_error(FILE* fp, const char* mname, const char* pname, gmx_fmtstr const char* fmt, ...) + gmx_format(printf, 4, 5); +static void report_param_error(FILE* fp, const char* mname, const char* pname, gmx_fmtstr const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -131,12 +129,14 @@ report_param_error(FILE *fp, const char *mname, const char *pname, * If you remove a check, make sure that the parameter parser can handle the * resulting parameters. */ -static bool -check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[], - const gmx::SelectionParserSymbolTable &symtab) +static bool check_params(FILE* fp, + const char* name, + int nparams, + gmx_ana_selparam_t param[], + const gmx::SelectionParserSymbolTable& symtab) { - bool bOk = true; - int i, j; + bool bOk = true; + int i, j; if (nparams > 0 && !param) { @@ -181,45 +181,54 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] { if (param[i].val.type != INT_VALUE && param[i].val.type != REAL_VALUE) { - report_param_error(fp, name, param[i].name, "error: SPAR_RANGES cannot be set for a non-numeric parameter"); + report_param_error(fp, name, param[i].name, + "error: SPAR_RANGES cannot be set for a non-numeric parameter"); bOk = false; } if (param[i].flags & SPAR_DYNAMIC) { - report_param_error(fp, name, param[i].name, "warning: SPAR_DYNAMIC does not have effect with SPAR_RANGES"); + report_param_error(fp, name, param[i].name, + "warning: SPAR_DYNAMIC does not have effect with SPAR_RANGES"); param[i].flags &= ~SPAR_DYNAMIC; } if (!(param[i].flags & SPAR_VARNUM) && param[i].val.nr != 1) { - report_param_error(fp, name, param[i].name, "error: range should take either one or an arbitrary number of values"); + report_param_error( + fp, name, param[i].name, + "error: range should take either one or an arbitrary number of values"); bOk = false; } if (param[i].flags & SPAR_ATOMVAL) { - report_param_error(fp, name, param[i].name, "error: SPAR_RANGES and SPAR_ATOMVAL both set"); + report_param_error(fp, name, param[i].name, + "error: SPAR_RANGES and SPAR_ATOMVAL both set"); bOk = false; } } if ((param[i].flags & SPAR_VARNUM) && (param[i].flags & SPAR_ATOMVAL)) { - report_param_error(fp, name, param[i].name, "error: SPAR_VARNUM and SPAR_ATOMVAL both set"); + report_param_error(fp, name, param[i].name, + "error: SPAR_VARNUM and SPAR_ATOMVAL both set"); bOk = false; } if (param[i].flags & SPAR_ENUMVAL) { if (param[i].val.type != STR_VALUE) { - report_param_error(fp, name, param[i].name, "error: SPAR_ENUMVAL can only be set for string parameters"); + report_param_error(fp, name, param[i].name, + "error: SPAR_ENUMVAL can only be set for string parameters"); bOk = false; } if (param[i].val.nr != 1) { - report_param_error(fp, name, param[i].name, "error: SPAR_ENUMVAL parameters should take exactly one value"); + report_param_error(fp, name, param[i].name, + "error: SPAR_ENUMVAL parameters should take exactly one value"); bOk = false; } if (param[i].flags & (SPAR_DYNAMIC | SPAR_VARNUM | SPAR_ATOMVAL)) { - report_param_error(fp, name, param[i].name, "error: only SPAR_OPTIONAL supported with SPAR_ENUMVAL"); + report_param_error(fp, name, param[i].name, + "error: only SPAR_OPTIONAL supported with SPAR_ENUMVAL"); bOk = false; } } @@ -228,7 +237,8 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] { if (param[i].val.nr != 0) { - report_param_error(fp, name, param[i].name, "error: number of values should be zero for boolean parameters"); + report_param_error(fp, name, param[i].name, + "error: number of values should be zero for boolean parameters"); bOk = false; } /* The boolean parameters should always be optional, so set the @@ -237,7 +247,8 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] /* Any other flags should not be specified */ if (param[i].flags & ~SPAR_OPTIONAL) { - report_param_error(fp, name, param[i].name, "error: boolean parameter should not have any flags set"); + report_param_error(fp, name, param[i].name, + "error: boolean parameter should not have any flags set"); bOk = false; } } @@ -246,7 +257,9 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] { if (param[i].val.nr != -1) { - report_param_error(fp, name, param[i].name, "warning: val.nr is not -1 although SPAR_VARNUM/SPAR_ATOMVAL is set"); + report_param_error( + fp, name, param[i].name, + "warning: val.nr is not -1 although SPAR_VARNUM/SPAR_ATOMVAL is set"); } param[i].val.nr = -1; } @@ -282,7 +295,8 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] { if (param[i].name[j] != '_' && !isalnum(param[i].name[j])) { - report_param_error(fp, name, param[i].name, "error: name contains non-alphanumeric characters"); + report_param_error(fp, name, param[i].name, + "error: name contains non-alphanumeric characters"); bOk = false; break; } @@ -294,21 +308,22 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] /* Check that the name does not conflict with a method */ if (symtab.findSymbol(param[i].name) != nullptr) { - report_param_error(fp, name, param[i].name, "error: name conflicts with another method or a keyword"); + report_param_error(fp, name, param[i].name, + "error: name conflicts with another method or a keyword"); bOk = false; } } /* End of parameter loop */ /* Check parameters of existing methods */ - gmx::SelectionParserSymbolIterator symbol - = symtab.beginIterator(gmx::SelectionParserSymbol::MethodSymbol); + gmx::SelectionParserSymbolIterator symbol = + symtab.beginIterator(gmx::SelectionParserSymbol::MethodSymbol); while (symbol != symtab.endIterator()) { - gmx_ana_selmethod_t *method = symbol->methodValue(); - gmx_ana_selparam_t *param = - gmx_ana_selmethod_find_param(name, method); + gmx_ana_selmethod_t* method = symbol->methodValue(); + gmx_ana_selparam_t* param = gmx_ana_selmethod_find_param(name, method); if (param) { - report_param_error(fp, method->name, param->name, "error: name conflicts with another method or a keyword"); + report_param_error(fp, method->name, param->name, + "error: name conflicts with another method or a keyword"); bOk = false; } ++symbol; @@ -329,17 +344,17 @@ check_params(FILE *fp, const char *name, int nparams, gmx_ana_selparam_t param[] * This function checks that all the required callbacks are defined, i.e., * not NULL, to find programming errors. */ -static bool -check_callbacks(FILE *fp, gmx_ana_selmethod_t *method) +static bool check_callbacks(FILE* fp, gmx_ana_selmethod_t* method) { - bool bOk = true; - bool bNeedInit; - int i; + bool bOk = true; + bool bNeedInit; + int i; /* Make some checks on init_data and free */ if (method->nparams > 0 && !method->init_data) { - report_error(fp, method->name, "error: init_data should be provided because the method has parameters"); + report_error(fp, method->name, + "error: init_data should be provided because the method has parameters"); bOk = false; } if (method->free && !method->init_data) @@ -349,13 +364,15 @@ check_callbacks(FILE *fp, gmx_ana_selmethod_t *method) /* Check presence of outinit for position-valued methods */ if (method->type == POS_VALUE && !method->outinit) { - report_error(fp, method->name, "error: outinit should be provided because the method has POS_VALUE"); + report_error(fp, method->name, + "error: outinit should be provided because the method has POS_VALUE"); bOk = false; } /* Check presence of outinit for variable output count methods */ if ((method->flags & SMETH_VARNUMVAL) && !method->outinit) { - report_error(fp, method->name, "error: outinit should be provided because the method has SMETH_VARNUMVAL"); + report_error(fp, method->name, + "error: outinit should be provided because the method has SMETH_VARNUMVAL"); bOk = false; } /* Warn of dynamic callbacks in static methods */ @@ -406,11 +423,9 @@ check_callbacks(FILE *fp, gmx_ana_selmethod_t *method) * If you remove a check, please make sure that the selection parser, * compiler, and evaluation functions can deal with the method. */ -static bool -check_method(FILE *fp, gmx_ana_selmethod_t *method, - const gmx::SelectionParserSymbolTable &symtab) +static bool check_method(FILE* fp, gmx_ana_selmethod_t* method, const gmx::SelectionParserSymbolTable& symtab) { - bool bOk = true; + bool bOk = true; /* Check the type */ if (method->type == NO_VALUE) @@ -432,14 +447,14 @@ check_method(FILE *fp, gmx_ana_selmethod_t *method, /* Check that conflicting flags are not present. */ if (method->flags & SMETH_VARNUMVAL) { - report_error(fp, method->name, "error: SMETH_VARNUMVAL cannot be set for group-valued methods"); + report_error(fp, method->name, + "error: SMETH_VARNUMVAL cannot be set for group-valued methods"); bOk = false; } } else { - if ((method->flags & SMETH_SINGLEVAL) - && (method->flags & SMETH_VARNUMVAL)) + if ((method->flags & SMETH_SINGLEVAL) && (method->flags & SMETH_VARNUMVAL)) { report_error(fp, method->name, "error: SMETH_SINGLEVAL and SMETH_VARNUMVAL both set"); bOk = false; @@ -447,7 +462,8 @@ check_method(FILE *fp, gmx_ana_selmethod_t *method, } if ((method->flags & SMETH_CHARVAL) && method->type != STR_VALUE) { - report_error(fp, method->name, "error: SMETH_CHARVAL can only be specified for STR_VALUE methods"); + report_error(fp, method->name, + "error: SMETH_CHARVAL can only be specified for STR_VALUE methods"); bOk = false; } /* Check the parameters */ @@ -477,11 +493,9 @@ check_method(FILE *fp, gmx_ana_selmethod_t *method, * If you remove a check, please make sure that the selection parser, * compiler, and evaluation functions can deal with the method. */ -static bool -check_modifier(FILE *fp, gmx_ana_selmethod_t *method, - const gmx::SelectionParserSymbolTable &symtab) +static bool check_modifier(FILE* fp, gmx_ana_selmethod_t* method, const gmx::SelectionParserSymbolTable& symtab) { - bool bOk = true; + bool bOk = true; /* Check the type */ if (method->type != NO_VALUE && method->type != POS_VALUE) @@ -492,12 +506,13 @@ check_modifier(FILE *fp, gmx_ana_selmethod_t *method, /* Check flags */ if (method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) { - report_error(fp, method->name, "error: modifier should not have SMETH_SINGLEVAL or SMETH_VARNUMVAL set"); + report_error(fp, method->name, + "error: modifier should not have SMETH_SINGLEVAL or SMETH_VARNUMVAL set"); bOk = false; } /* Check the parameters */ /* The first parameter is skipped */ - if (!check_params(fp, method->name, method->nparams-1, method->param+1, symtab)) + if (!check_params(fp, method->name, method->nparams - 1, method->param + 1, symtab)) { bOk = false; } @@ -537,9 +552,9 @@ check_modifier(FILE *fp, gmx_ana_selmethod_t *method, * Some problems only generate warnings. * All problems are described to \p stderr. */ -int -gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable *symtab, - const char *name, gmx_ana_selmethod_t *method) +int gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable* symtab, + const char* name, + gmx_ana_selmethod_t* method) { bool bOk; @@ -559,7 +574,7 @@ gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable *symtab, { symtab->addMethod(name, method); } - catch (const gmx::APIError &ex) + catch (const gmx::APIError& ex) { report_error(stderr, name, "%s", ex.what()); bOk = false; @@ -578,63 +593,43 @@ gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable *symtab, * \returns 0 on success, -1 if any of the default methods could not be * registered. */ -int -gmx_ana_selmethod_register_defaults(gmx::SelectionParserSymbolTable *symtab) +int gmx_ana_selmethod_register_defaults(gmx::SelectionParserSymbolTable* symtab) { /* Array of selection methods defined in the library. */ const t_register_method smtable_def[] = { - {nullptr, &sm_cog}, - {nullptr, &sm_com}, + { nullptr, &sm_cog }, { nullptr, &sm_com }, - {nullptr, &sm_all}, - {nullptr, &sm_none}, - {nullptr, &sm_atomnr}, - {nullptr, &sm_resnr}, - {"resid", &sm_resnr}, - {nullptr, &sm_resindex}, - {"residue", &sm_resindex}, - {nullptr, &sm_molindex}, - {"mol", &sm_molindex}, - {"molecule", &sm_molindex}, - {nullptr, &sm_atomname}, - {"name", &sm_atomname}, - {nullptr, &sm_pdbatomname}, - {"pdbname", &sm_pdbatomname}, - {nullptr, &sm_atomtype}, - {"type", &sm_atomtype}, - {nullptr, &sm_resname}, - {nullptr, &sm_insertcode}, - {nullptr, &sm_chain}, - {nullptr, &sm_mass}, - {nullptr, &sm_charge}, - {nullptr, &sm_altloc}, - {nullptr, &sm_occupancy}, - {nullptr, &sm_betafactor}, - {"beta", &sm_betafactor}, - {nullptr, &sm_x}, - {nullptr, &sm_y}, - {nullptr, &sm_z}, + { nullptr, &sm_all }, { nullptr, &sm_none }, + { nullptr, &sm_atomnr }, { nullptr, &sm_resnr }, + { "resid", &sm_resnr }, { nullptr, &sm_resindex }, + { "residue", &sm_resindex }, { nullptr, &sm_molindex }, + { "mol", &sm_molindex }, { "molecule", &sm_molindex }, + { nullptr, &sm_atomname }, { "name", &sm_atomname }, + { nullptr, &sm_pdbatomname }, { "pdbname", &sm_pdbatomname }, + { nullptr, &sm_atomtype }, { "type", &sm_atomtype }, + { nullptr, &sm_resname }, { nullptr, &sm_insertcode }, + { nullptr, &sm_chain }, { nullptr, &sm_mass }, + { nullptr, &sm_charge }, { nullptr, &sm_altloc }, + { nullptr, &sm_occupancy }, { nullptr, &sm_betafactor }, + { "beta", &sm_betafactor }, { nullptr, &sm_x }, + { nullptr, &sm_y }, { nullptr, &sm_z }, - {nullptr, &sm_distance}, - {"dist", &sm_distance}, - {nullptr, &sm_mindistance}, - {"mindist", &sm_mindistance}, - {nullptr, &sm_within}, - {nullptr, &sm_insolidangle}, - {nullptr, &sm_same}, + { nullptr, &sm_distance }, { "dist", &sm_distance }, + { nullptr, &sm_mindistance }, { "mindist", &sm_mindistance }, + { nullptr, &sm_within }, { nullptr, &sm_insolidangle }, + { nullptr, &sm_same }, - {nullptr, &sm_merge}, - {nullptr, &sm_plus}, - {nullptr, &sm_permute}, + { nullptr, &sm_merge }, { nullptr, &sm_plus }, + { nullptr, &sm_permute }, }; - int rc; - bool bOk; + int rc; + bool bOk; bOk = true; for (int i = 0; i < asize(smtable_def); ++i) { - gmx_ana_selmethod_t *method = smtable_def[i].method; + gmx_ana_selmethod_t* method = smtable_def[i].method; if (smtable_def[i].name == nullptr) { @@ -661,8 +656,7 @@ gmx_ana_selmethod_register_defaults(gmx::SelectionParserSymbolTable *symtab) * * This is a simple wrapper for gmx_ana_selparam_find(). */ -gmx_ana_selparam_t * -gmx_ana_selmethod_find_param(const char *name, gmx_ana_selmethod_t *method) +gmx_ana_selparam_t* gmx_ana_selmethod_find_param(const char* name, gmx_ana_selmethod_t* method) { return gmx_ana_selparam_find(name, method->nparams, method->param); } diff --git a/src/gromacs/selection/selmethod.h b/src/gromacs/selection/selmethod.h index 4b55153089..8836db6411 100644 --- a/src/gromacs/selection/selmethod.h +++ b/src/gromacs/selection/selmethod.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2009-2016, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -328,8 +329,10 @@ class SelectionParserSymbolTable; struct SelMethodEvalContext { //! Initializes the context with given values. - SelMethodEvalContext(const gmx_mtop_t *top, t_trxframe *fr, const t_pbc *pbc) - : top(top), fr(fr), pbc(pbc) + SelMethodEvalContext(const gmx_mtop_t* top, t_trxframe* fr, const t_pbc* pbc) : + top(top), + fr(fr), + pbc(pbc) { } @@ -339,20 +342,20 @@ struct SelMethodEvalContext * Can be NULL if \ref SMETH_REQTOP or \ref SMETH_REQMASS is not set for * the method. */ - const gmx_mtop_t *top; + const gmx_mtop_t* top; /*! \brief * Trajectory frame. * * For static methods that are evaluated based on topology information * alone, this is `NULL`. */ - t_trxframe *fr; + t_trxframe* fr; /*! \brief * Periodic boundary condition information. * * Can be `NULL`, in which case PBC should not be used. */ - const t_pbc *pbc; + const t_pbc* pbc; }; } // namespace gmx @@ -362,25 +365,25 @@ struct SelMethodEvalContext */ /*@{*/ //! If set, the method requires topology information. -#define SMETH_REQTOP 1 +#define SMETH_REQTOP 1 //! If set, the method requires atom masses. -#define SMETH_REQMASS 2 +#define SMETH_REQMASS 2 //! If set, the method can only be evaluated dynamically. -#define SMETH_DYNAMIC 4 +#define SMETH_DYNAMIC 4 /*! \brief * If set, the method evaluates to a single value. * * The default is that the method evaluates to a value for each input atom. * Cannot be combined with \ref SMETH_VARNUMVAL. */ -#define SMETH_SINGLEVAL 8 +#define SMETH_SINGLEVAL 8 /*! \brief * If set, the method evaluates to an arbitrary number of values. * * The default is that the method evaluates to a value for each input atom. * Cannot be combined with \ref SMETH_SINGLEVAL or with \ref GROUP_VALUE. */ -#define SMETH_VARNUMVAL 16 +#define SMETH_VARNUMVAL 16 /*! \brief * If set, the method evaluates to single-character strings. * @@ -390,7 +393,7 @@ struct SelMethodEvalContext * character in the strings in the output data structure and should not change * the string pointers. */ -#define SMETH_CHARVAL 64 +#define SMETH_CHARVAL 64 /*! \brief * If set, the method accepts unsorted atoms in its input parameters. * @@ -406,7 +409,7 @@ struct SelMethodEvalContext * The method type should be \ref GROUP_VALUE or \ref NO_VALUE . * Cannot be combined with \ref SMETH_SINGLEVAL or \ref SMETH_VARNUMVAL . */ -#define SMETH_MODIFIER 256 +#define SMETH_MODIFIER 256 /*@}*/ /*! \brief @@ -443,7 +446,7 @@ struct SelMethodEvalContext * * If the method takes any parameters, this function must be provided. */ -typedef void *(*sel_datafunc)(int npar, gmx_ana_selparam_t *param); +typedef void* (*sel_datafunc)(int npar, gmx_ana_selparam_t* param); /*! \brief * Sets the position calculation collection for the method. * @@ -456,7 +459,7 @@ typedef void *(*sel_datafunc)(int npar, gmx_ana_selparam_t *param); * The pointer \p pcc should then be stored and used for initialization for * any position calculation structures. */ -typedef void (*sel_posfunc)(gmx::PositionCalculationCollection *pcc, void *data); +typedef void (*sel_posfunc)(gmx::PositionCalculationCollection* pcc, void* data); /*! \brief * Does initialization based on topology and/or parameter values. * @@ -501,8 +504,7 @@ typedef void (*sel_posfunc)(gmx::PositionCalculationCollection *pcc, void *data * This function may be called multiple times for the same method if the * method takes parameters with \ref SPAR_ATOMVAL set. */ -typedef void (*sel_initfunc)(const gmx_mtop_t *top, int npar, - gmx_ana_selparam_t *param, void *data); +typedef void (*sel_initfunc)(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes output data structure. * @@ -530,8 +532,7 @@ typedef void (*sel_initfunc)(const gmx_mtop_t *top, int npar, * This function may be called multiple times for the same method if the * method takes parameters with \ref SPAR_ATOMVAL set. */ -typedef void (*sel_outinitfunc)(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, - void *data); +typedef void (*sel_outinitfunc)(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /*! \brief * Frees the internal data. * @@ -549,7 +550,7 @@ typedef void (*sel_outinitfunc)(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, * Pointers set as the value pointer of \ref SPAR_ENUMVAL parameters should not * be freed. */ -typedef void (*sel_freefunc)(void *data); +typedef void (*sel_freefunc)(void* data); /*! \brief * Initializes the evaluation for a new frame. @@ -569,8 +570,7 @@ typedef void (*sel_freefunc)(void *data); * For static methods, it is called once, with \p fr and \p pbc set to * NULL. */ -typedef void (*sel_framefunc)(const gmx::SelMethodEvalContext &context, - void *data); +typedef void (*sel_framefunc)(const gmx::SelMethodEvalContext& context, void* data); /*! \brief * Evaluates a selection method. * @@ -597,9 +597,10 @@ typedef void (*sel_framefunc)(const gmx::SelMethodEvalContext &context, * contains such an atom in case the \p fr has been loaded from a trajectory * that only contains a subset of the system. */ -typedef void (*sel_updatefunc)(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, - void *data); +typedef void (*sel_updatefunc)(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Evaluates a selection method using positions. * @@ -627,9 +628,10 @@ typedef void (*sel_updatefunc)(const gmx::SelMethodEvalContext &context, * contains such an atom in case the \p fr has been loaded from a trajectory * that only contains a subset of the system. */ -typedef void (*sel_updatefunc_pos)(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, - void *data); +typedef void (*sel_updatefunc_pos)(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /*! \internal * \brief @@ -645,27 +647,27 @@ struct gmx_ana_selmethod_help_t * * If NULL, the name of the method is used. */ - const char *syntax; + const char* syntax; /*! \brief * Title for the help text in \p help. * * If NULL, the name of the method is used. * Only used if `nlhelp > 0`. */ - const char *helpTitle; + const char* helpTitle; /*! \brief * Number of strings in \p help. * * Set to 0 if \p help is NULL. */ - int nlhelp; + int nlhelp; /*! \brief * Detailed help for the method. * * If there is no help available in addition to \p syntax, this can be set * to NULL. */ - const char *const *help; + const char* const* help; }; /*! \internal @@ -684,52 +686,50 @@ struct gmx_ana_selmethod_help_t struct gmx_ana_selmethod_t { /** Name of the method. */ - const char *name; + const char* name; /** Type which the method returns. */ - e_selvalue_t type; + e_selvalue_t type; /*! \brief * Flags to specify how the method should be handled. * * See \ref selmethod_flags for allowed values. */ - int flags; + int flags; /** Number of parameters the method takes. */ - int nparams; + int nparams; /** Pointer to the array of parameter descriptions. */ - gmx_ana_selparam_t *param; + gmx_ana_selparam_t* param; /** Function for allocating and initializing internal data and parameters. */ - sel_datafunc init_data; + sel_datafunc init_data; /** Function to set the position calculation collection. */ - sel_posfunc set_poscoll; + sel_posfunc set_poscoll; /** Function to do initialization based on topology and/or parameter values. */ - sel_initfunc init; + sel_initfunc init; /** Function to initialize output data structure. */ - sel_outinitfunc outinit; + sel_outinitfunc outinit; /** Function to free the internal data. */ - sel_freefunc free; + sel_freefunc free; /** Function to initialize the calculation for a new frame. */ - sel_framefunc init_frame; + sel_framefunc init_frame; /** Function to evaluate the value. */ - sel_updatefunc update; + sel_updatefunc update; /** Function to evaluate the value using positions. */ - sel_updatefunc_pos pupdate; + sel_updatefunc_pos pupdate; /** Help data for the method. */ gmx_ana_selmethod_help_t help; }; /** Registers a selection method. */ -int -gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable *symtab, - const char *name, gmx_ana_selmethod_t *method); +int gmx_ana_selmethod_register(gmx::SelectionParserSymbolTable* symtab, + const char* name, + gmx_ana_selmethod_t* method); /** Registers all selection methods in the library. */ -int -gmx_ana_selmethod_register_defaults(gmx::SelectionParserSymbolTable *symtab); +int gmx_ana_selmethod_register_defaults(gmx::SelectionParserSymbolTable* symtab); /** Finds a parameter from a selection method by name. */ -gmx_ana_selparam_t * -gmx_ana_selmethod_find_param(const char *name, gmx_ana_selmethod_t *method); +gmx_ana_selparam_t* gmx_ana_selmethod_find_param(const char* name, gmx_ana_selmethod_t* method); #endif diff --git a/src/gromacs/selection/selparam.h b/src/gromacs/selection/selparam.h index bedfaadff1..90c468744e 100644 --- a/src/gromacs/selection/selparam.h +++ b/src/gromacs/selection/selparam.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ * * This flag is set automatically, and should not be set by the user. */ -#define SPAR_SET 1 +#define SPAR_SET 1 /*! \brief * If not set, an error is reported if the parameter is not specified by the * user. @@ -76,7 +76,7 @@ * The flag is cleared before sel_initfunc() if the value provided is actually * static. */ -#define SPAR_DYNAMIC 4 +#define SPAR_DYNAMIC 4 /*! \brief * If set, the parameter value is parsed into sorted ranges. * @@ -91,7 +91,7 @@ * ranges. \p gmx_ana_selparam_t::nval should be 1 or \ref SPAR_VARNUM should be * specified; other values would lead to unpredictable behavior. */ -#define SPAR_RANGES 8 +#define SPAR_RANGES 8 /*! \brief * If set, the parameter can have any number of values. * @@ -108,7 +108,7 @@ * * Cannot be combined with \ref GROUP_VALUE parameters. */ -#define SPAR_VARNUM 16 +#define SPAR_VARNUM 16 /*! \brief * If set, the parameter can have a separate value for each atom. * @@ -117,7 +117,7 @@ * * Cannot be combined with \ref POS_VALUE or \ref GROUP_VALUE parameters. */ -#define SPAR_ATOMVAL 32 +#define SPAR_ATOMVAL 32 /*! \brief * If set, the parameter takes one of a set of predefined strings. * @@ -134,7 +134,7 @@ * array for multiple instances of the same method is automatically taken care * of. */ -#define SPAR_ENUMVAL 128 +#define SPAR_ENUMVAL 128 /*@}*/ /*! \internal \brief @@ -143,7 +143,7 @@ typedef struct gmx_ana_selparam_t { /** Name of the parameter. */ - const char *name; + const char* name; /*! \brief * The parameter value. * @@ -164,7 +164,7 @@ typedef struct gmx_ana_selparam_t * makes a copy of the parameter structure for each instance of the * method, and the original parameter array is not changed. */ - gmx_ana_selvalue_t val; + gmx_ana_selvalue_t val; /*! \brief * Pointer to store the number of values. * @@ -176,17 +176,16 @@ typedef struct gmx_ana_selparam_t * Should be initialized to NULL in the definition a \c gmx_ana_selmethod_t * and initialized in sel_datafunc(). */ - int *nvalptr; + int* nvalptr; /*! \brief * Flags that alter the way the parameter is parsed/handled. * * See \ref selparam_flags for allowed values. */ - int flags; + int flags; } gmx_ana_selparam_t; /** Finds a parameter from an array by name. */ -gmx_ana_selparam_t * -gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param); +gmx_ana_selparam_t* gmx_ana_selparam_find(const char* name, int nparam, gmx_ana_selparam_t* param); #endif diff --git a/src/gromacs/selection/selvalue.cpp b/src/gromacs/selection/selvalue.cpp index 427cfdea66..172bf4ff7d 100644 --- a/src/gromacs/selection/selvalue.cpp +++ b/src/gromacs/selection/selvalue.cpp @@ -49,16 +49,14 @@ #include "position.h" -void -_gmx_selvalue_clear(gmx_ana_selvalue_t *val) +void _gmx_selvalue_clear(gmx_ana_selvalue_t* val) { val->nr = 0; val->u.ptr = nullptr; val->nalloc = 0; } -void -_gmx_selvalue_free(gmx_ana_selvalue_t *val) +void _gmx_selvalue_free(gmx_ana_selvalue_t* val) { if (val->nalloc > 0) { @@ -76,10 +74,9 @@ _gmx_selvalue_free(gmx_ana_selvalue_t *val) val->nalloc = 0; } -void -_gmx_selvalue_reserve(gmx_ana_selvalue_t *val, int n) +void _gmx_selvalue_reserve(gmx_ana_selvalue_t* val, int n) { - int i; + int i; if (val->nalloc == -1) { @@ -90,8 +87,8 @@ _gmx_selvalue_reserve(gmx_ana_selvalue_t *val, int n) { switch (val->type) { - case INT_VALUE: srenew(val->u.i, n); break; - case REAL_VALUE: srenew(val->u.r, n); break; + case INT_VALUE: srenew(val->u.i, n); break; + case REAL_VALUE: srenew(val->u.r, n); break; case STR_VALUE: srenew(val->u.s, n); for (i = val->nalloc; i < n; ++i) @@ -111,14 +108,13 @@ _gmx_selvalue_reserve(gmx_ana_selvalue_t *val, int n) gmx_ana_index_clear(&val->u.g[i]); } break; - case NO_VALUE: break; + case NO_VALUE: break; } val->nalloc = n; } } -void -_gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t *val, void **ptr, int *nalloc) +void _gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t* val, void** ptr, int* nalloc) { *ptr = val->u.ptr; *nalloc = val->nalloc; @@ -126,17 +122,14 @@ _gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t *val, void **ptr, int *nal val->nalloc = 0; } -void -_gmx_selvalue_setstore(gmx_ana_selvalue_t *val, void *ptr) +void _gmx_selvalue_setstore(gmx_ana_selvalue_t* val, void* ptr) { - GMX_ASSERT(val->nalloc <= 0, - "Memory leak from discarding an existing value"); + GMX_ASSERT(val->nalloc <= 0, "Memory leak from discarding an existing value"); val->u.ptr = ptr; val->nalloc = (ptr ? -1 : 0); } -void -_gmx_selvalue_setstore_alloc(gmx_ana_selvalue_t *val, void *ptr, int nalloc) +void _gmx_selvalue_setstore_alloc(gmx_ana_selvalue_t* val, void* ptr, int nalloc) { GMX_ASSERT(val->nalloc <= 0 || (ptr == val->u.ptr && nalloc == val->nalloc), "Memory leak from discarding an existing value"); diff --git a/src/gromacs/selection/selvalue.h b/src/gromacs/selection/selvalue.h index d4a1e13318..08872a29a9 100644 --- a/src/gromacs/selection/selvalue.h +++ b/src/gromacs/selection/selvalue.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,13 +50,13 @@ /** Defines the value type of a different selection objects. */ typedef enum { - NO_VALUE, /**< No value; either an error condition or an boolean - parameter. */ - INT_VALUE, /**< One or more integer values. */ - REAL_VALUE, /**< One or more real values. */ - STR_VALUE, /**< One or more string values. */ - POS_VALUE, /**< One or more position values. */ - GROUP_VALUE /**< One group of atoms. */ + NO_VALUE, /**< No value; either an error condition or an boolean + parameter. */ + INT_VALUE, /**< One or more integer values. */ + REAL_VALUE, /**< One or more real values. */ + STR_VALUE, /**< One or more string values. */ + POS_VALUE, /**< One or more position values. */ + GROUP_VALUE /**< One group of atoms. */ } e_selvalue_t; /*! \internal @@ -69,7 +69,7 @@ typedef enum typedef struct gmx_ana_selvalue_t { /** Type of the value. */ - e_selvalue_t type; + e_selvalue_t type; /*! \brief * Number of values in the array pointed by the union. * @@ -77,7 +77,7 @@ typedef struct gmx_ana_selvalue_t * data structures in the array, not the number of positions or * the number of atoms in the group. */ - int nr; + int nr; /** Pointer to the value. */ union { /*! \brief @@ -85,24 +85,24 @@ typedef struct gmx_ana_selvalue_t * * Needs to be the first member to be able to use initialized arrays. */ - void *ptr; + void* ptr; /** Integer value(s) (type \ref INT_VALUE). */ - int *i; + int* i; /** Real value(s) (type \ref REAL_VALUE). */ - real *r; + real* r; /** String value(s) (type \ref STR_VALUE). */ - char **s; + char** s; /** Structure for the position value(s) (type \ref POS_VALUE). */ - struct gmx_ana_pos_t *p; + struct gmx_ana_pos_t* p; /** Group value (type \ref GROUP_VALUE). */ - struct gmx_ana_index_t *g; + struct gmx_ana_index_t* g; /** Boolean value (only parameters of type \ref NO_VALUE); */ - bool *b; - } u; + bool* b; + } u; /*! \brief * Number of elements allocated for the value array. */ - int nalloc; + int nalloc; } gmx_ana_selvalue_t; /*! \brief @@ -113,8 +113,7 @@ typedef struct gmx_ana_selvalue_t * The type of \p val is not touched. * Any contents of \p val are discarded without freeing. */ -void -_gmx_selvalue_clear(gmx_ana_selvalue_t *val); +void _gmx_selvalue_clear(gmx_ana_selvalue_t* val); /*! \brief * Frees memory allocated for a selection value structure. * @@ -124,8 +123,7 @@ _gmx_selvalue_clear(gmx_ana_selvalue_t *val); * If memory is not allocated, the value pointers are simply cleared without * freeing. */ -void -_gmx_selvalue_free(gmx_ana_selvalue_t *val); +void _gmx_selvalue_free(gmx_ana_selvalue_t* val); /*! \brief * Reserve memory for storing selection values. * @@ -141,8 +139,7 @@ _gmx_selvalue_free(gmx_ana_selvalue_t *val); * Similarly, for \ref STR_VALUE values, the pointers are set to NULL. * For other values, the memory is uninitialized. */ -void -_gmx_selvalue_reserve(gmx_ana_selvalue_t *val, int n); +void _gmx_selvalue_reserve(gmx_ana_selvalue_t* val, int n); /*! \brief * Gets and releases the memory pointer for storing selection values. * @@ -153,8 +150,7 @@ _gmx_selvalue_reserve(gmx_ana_selvalue_t *val, int n); * Returns the pointer where values of \p val were stored in \p ptr and * \p nalloc, and clears the memory in \p val. */ -void -_gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t *val, void **ptr, int *nalloc); +void _gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t* val, void** ptr, int* nalloc); /*! \brief * Sets the memory for storing selection values. * @@ -165,8 +161,7 @@ _gmx_selvalue_getstore_and_release(gmx_ana_selvalue_t *val, void **ptr, int *nal * Asserts if \p val had a previous storage that it owned, as that would result * in a memory leak. */ -void -_gmx_selvalue_setstore(gmx_ana_selvalue_t *val, void *ptr); +void _gmx_selvalue_setstore(gmx_ana_selvalue_t* val, void* ptr); /*! \brief * Sets the memory for storing selection values and marks it for automatic freeing. * @@ -177,7 +172,6 @@ _gmx_selvalue_setstore(gmx_ana_selvalue_t *val, void *ptr); * Asserts if \p val had a previous storage that it owned, as that would result * in a memory leak. */ -void -_gmx_selvalue_setstore_alloc(gmx_ana_selvalue_t *val, void *ptr, int nalloc); +void _gmx_selvalue_setstore_alloc(gmx_ana_selvalue_t* val, void* ptr, int nalloc); #endif diff --git a/src/gromacs/selection/sm_compare.cpp b/src/gromacs/selection/sm_compare.cpp index 7df2342792..754a02be42 100644 --- a/src/gromacs/selection/sm_compare.cpp +++ b/src/gromacs/selection/sm_compare.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,25 +55,25 @@ /** Defines the comparison operator for comparison expressions. */ typedef enum { - CMP_INVALID, /**< Indicates an error */ - CMP_LESS, /**< '<' */ - CMP_LEQ, /**< '<=' */ - CMP_GTR, /**< '>' */ - CMP_GEQ, /**< '>=' */ - CMP_EQUAL, /**< '==' */ - CMP_NEQ /**< '!=' */ + CMP_INVALID, /**< Indicates an error */ + CMP_LESS, /**< '<' */ + CMP_LEQ, /**< '<=' */ + CMP_GTR, /**< '>' */ + CMP_GEQ, /**< '>=' */ + CMP_EQUAL, /**< '==' */ + CMP_NEQ /**< '!=' */ } e_comparison_t; /** The operand has a single value. */ -#define CMP_SINGLEVAL 1 +#define CMP_SINGLEVAL 1 /** The operand value is dynamic. */ #define CMP_DYNAMICVAL 2 /** The value is real. */ -#define CMP_REALVAL 4 +#define CMP_REALVAL 4 /** The integer array is allocated. */ -#define CMP_ALLOCINT 16 +#define CMP_ALLOCINT 16 /** The real array is allocated. */ -#define CMP_ALLOCREAL 32 +#define CMP_ALLOCREAL 32 /*! \internal \brief * Data structure for comparison expression operand values. @@ -81,11 +81,11 @@ typedef enum typedef struct { /** Flags that describe the type of the operand. */ - int flags; + int flags; /** (Array of) integer value(s). */ - int *i; + int* i; /** (Array of) real value(s). */ - real *r; + real* r; } t_compare_value; /*! \internal \brief @@ -94,13 +94,13 @@ typedef struct typedef struct { /** Comparison operator as a string. */ - char *cmpop; + char* cmpop; /** Comparison operator type. */ - e_comparison_t cmpt; + e_comparison_t cmpt; /** Left value. */ - t_compare_value left; + t_compare_value left; /** Right value. */ - t_compare_value right; + t_compare_value right; } t_methoddata_compare; /*! \brief @@ -113,8 +113,7 @@ typedef struct * * Allocates memory for a \c t_methoddata_compare structure. */ -static void * -init_data_compare(int npar, gmx_ana_selparam_t *param); +static void* init_data_compare(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes data for comparison expression evaluation. * @@ -124,11 +123,9 @@ init_data_compare(int npar, gmx_ana_selparam_t *param); * \param[in] data Should point to a \c t_methoddata_compare. * \returns 0 if the input data is valid, -1 on error. */ -static void -init_compare(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_compare(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Frees the memory allocated for comparison expression evaluation. */ -static void -free_data_compare(void *data); +static void free_data_compare(void* data); /*! \brief * Evaluates comparison expressions. * @@ -137,27 +134,27 @@ free_data_compare(void *data); * \param[out] out Output data structure (\p out->u.g is used). * \param[in] data Should point to a \c t_methoddata_compare. */ -static void -evaluate_compare(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_compare(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for comparison expression evaluation. */ static gmx_ana_selparam_t smparams_compare[] = { - {"int1", {INT_VALUE, -1, {nullptr}}, nullptr, - SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL}, - {"real1", {REAL_VALUE, -1, {nullptr}}, nullptr, - SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL}, - {"op", {STR_VALUE, 1, {nullptr}}, nullptr, 0}, - {"int2", {INT_VALUE, -1, {nullptr}}, nullptr, - SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL}, - {"real2", {REAL_VALUE, -1, {nullptr}}, nullptr, - SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL}, + { "int1", { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL }, + { "real1", { REAL_VALUE, -1, { nullptr } }, nullptr, SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL }, + { "op", { STR_VALUE, 1, { nullptr } }, nullptr, 0 }, + { "int2", { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL }, + { "real2", { REAL_VALUE, -1, { nullptr } }, nullptr, SPAR_OPTIONAL | SPAR_DYNAMIC | SPAR_ATOMVAL }, }; /** \internal Selection method data for comparison expression evaluation. */ gmx_ana_selmethod_t sm_compare = { - "cmp", GROUP_VALUE, SMETH_SINGLEVAL, - asize(smparams_compare), smparams_compare, + "cmp", + GROUP_VALUE, + SMETH_SINGLEVAL, + asize(smparams_compare), + smparams_compare, &init_data_compare, nullptr, &init_compare, @@ -166,7 +163,7 @@ gmx_ana_selmethod_t sm_compare = { nullptr, &evaluate_compare, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; /*! \brief @@ -181,15 +178,14 @@ gmx_ana_selmethod_t sm_compare = { * If the beginning of \p str does not match any of the recognized types, * \ref CMP_INVALID is returned. */ -static e_comparison_t -comparison_type(const char *str) +static e_comparison_t comparison_type(const char* str) { switch (str[0]) { - case '<': return (str[1] == '=') ? CMP_LEQ : CMP_LESS; - case '>': return (str[1] == '=') ? CMP_GEQ : CMP_GTR; + case '<': return (str[1] == '=') ? CMP_LEQ : CMP_LESS; + case '>': return (str[1] == '=') ? CMP_GEQ : CMP_GTR; case '=': return (str[1] == '=') ? CMP_EQUAL : CMP_INVALID; - case '!': return (str[1] == '=') ? CMP_NEQ : CMP_INVALID; + case '!': return (str[1] == '=') ? CMP_NEQ : CMP_INVALID; } return CMP_INVALID; } @@ -204,19 +200,20 @@ comparison_type(const char *str) * * The function returns NULL if \p cmpt is not one of the valid values. */ -static const char * -comparison_type_str(e_comparison_t cmpt) +static const char* comparison_type_str(e_comparison_t cmpt) { - const char *p = nullptr; + const char* p = nullptr; switch (cmpt) { case CMP_INVALID: p = "INVALID"; break; - case CMP_LESS: p = "<"; break; - case CMP_LEQ: p = "<="; break; - case CMP_GTR: p = ">"; break; - case CMP_GEQ: p = ">="; break; - case CMP_EQUAL: p = "=="; break; - case CMP_NEQ: p = "!="; break; + case CMP_LESS: p = "<"; break; + case CMP_LEQ: p = "<="; break; + case CMP_GTR: p = ">"; break; + case CMP_GEQ: p = ">="; break; + case CMP_EQUAL: p = "=="; break; + case CMP_NEQ: + p = "!="; + break; // No default clause so we intentionally get compiler errors // if new selection choices are added later. } @@ -227,10 +224,9 @@ comparison_type_str(e_comparison_t cmpt) * \param[in] fp File to receive the output. * \param[in] data Should point to a \c t_methoddata_compare. */ -void -_gmx_selelem_print_compare_info(FILE *fp, void *data) +void _gmx_selelem_print_compare_info(FILE* fp, void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); fprintf(fp, " \""); /* Print the left value */ @@ -269,10 +265,9 @@ _gmx_selelem_print_compare_info(FILE *fp, void *data) fprintf(fp, "\""); } -static void * -init_data_compare(int /* npar */, gmx_ana_selparam_t *param) +static void* init_data_compare(int /* npar */, gmx_ana_selparam_t* param) { - t_methoddata_compare *data; + t_methoddata_compare* data; snew(data, 1); param[2].val.u.s = &data->cmpop; @@ -286,16 +281,15 @@ init_data_compare(int /* npar */, gmx_ana_selparam_t *param) * \returns The correct comparison operator that equals \p type when the * left and right sides are interchanged. */ -static e_comparison_t -reverse_comparison_type(e_comparison_t type) +static e_comparison_t reverse_comparison_type(e_comparison_t type) { switch (type) { case CMP_LESS: return CMP_GTR; - case CMP_LEQ: return CMP_GEQ; - case CMP_GTR: return CMP_LESS; - case CMP_GEQ: return CMP_LEQ; - default: break; + case CMP_LEQ: return CMP_GEQ; + case CMP_GTR: return CMP_LESS; + case CMP_GEQ: return CMP_LEQ; + default: break; } return type; } @@ -307,32 +301,31 @@ reverse_comparison_type(e_comparison_t type) * \param[in] param Parameters to use for initialization. * \returns The number of values provided for the value, 0 on error. */ -static int -init_comparison_value(t_compare_value *val, gmx_ana_selparam_t param[2]) +static int init_comparison_value(t_compare_value* val, gmx_ana_selparam_t param[2]) { - int n; + int n; val->flags = 0; if (param[0].flags & SPAR_SET) { - val->flags |= (param[0].flags & SPAR_DYNAMIC) ? CMP_DYNAMICVAL : 0; - val->flags |= !(param[0].flags & SPAR_ATOMVAL) ? CMP_SINGLEVAL : 0; - n = param[0].val.nr; - val->i = param[0].val.u.i; + val->flags |= (param[0].flags & SPAR_DYNAMIC) ? CMP_DYNAMICVAL : 0; + val->flags |= !(param[0].flags & SPAR_ATOMVAL) ? CMP_SINGLEVAL : 0; + n = param[0].val.nr; + val->i = param[0].val.u.i; } else if (param[1].flags & SPAR_SET) { - val->flags |= (param[1].flags & SPAR_DYNAMIC) ? CMP_DYNAMICVAL : 0; - val->flags |= !(param[1].flags & SPAR_ATOMVAL) ? CMP_SINGLEVAL : 0; + val->flags |= (param[1].flags & SPAR_DYNAMIC) ? CMP_DYNAMICVAL : 0; + val->flags |= !(param[1].flags & SPAR_ATOMVAL) ? CMP_SINGLEVAL : 0; val->flags |= CMP_REALVAL; - n = param[1].val.nr; - val->r = param[1].val.u.r; + n = param[1].val.nr; + val->r = param[1].val.u.r; } else { - n = 0; - val->i = nullptr; - val->r = nullptr; + n = 0; + val->i = nullptr; + val->r = nullptr; } return n; } @@ -343,11 +336,10 @@ init_comparison_value(t_compare_value *val, gmx_ana_selparam_t param[2]) * \param[in] n Number of values in the \p val->u array. * \param[in,out] val Value to convert. */ -static void -convert_int_real(int n, t_compare_value *val) +static void convert_int_real(int n, t_compare_value* val) { int i; - real *rv; + real* rv; snew(rv, n); for (i = 0; i < n; ++i) @@ -356,7 +348,7 @@ convert_int_real(int n, t_compare_value *val) } /* Free the previous value if one is present. */ sfree(val->r); - val->r = rv; + val->r = rv; val->flags |= CMP_REALVAL | CMP_ALLOCREAL; } @@ -372,11 +364,10 @@ convert_int_real(int n, t_compare_value *val) * * The values are rounded such that the same comparison operator can be used. */ -static void -convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, bool bRight) +static void convert_real_int(int n, t_compare_value* val, e_comparison_t cmpt, bool bRight) { - int i; - int *iv; + int i; + int* iv; if (!bRight) { @@ -389,13 +380,9 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, bool bRight) switch (cmpt) { case CMP_LESS: - case CMP_GEQ: - iv[i] = static_cast(std::ceil(val->r[i])); - break; + case CMP_GEQ: iv[i] = static_cast(std::ceil(val->r[i])); break; case CMP_GTR: - case CMP_LEQ: - iv[i] = static_cast(std::floor(val->r[i])); - break; + case CMP_LEQ: iv[i] = static_cast(std::floor(val->r[i])); break; case CMP_EQUAL: case CMP_NEQ: sfree(iv); @@ -403,7 +390,9 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, bool bRight) * Implementation is only a matter of proper initialization, * the evaluation function can already handle this case with * proper preparations. */ - GMX_THROW(gmx::NotImplementedError("Equality comparison between dynamic integer and static real expressions not implemented")); + GMX_THROW( + gmx::NotImplementedError("Equality comparison between dynamic integer and " + "static real expressions not implemented")); case CMP_INVALID: /* Should not be reached */ sfree(iv); GMX_THROW(gmx::InternalError("Invalid comparison type")); @@ -411,15 +400,14 @@ convert_real_int(int n, t_compare_value *val, e_comparison_t cmpt, bool bRight) } /* Free the previous value if one is present. */ sfree(val->i); - val->i = iv; + val->i = iv; val->flags &= ~CMP_REALVAL; val->flags |= CMP_ALLOCINT; } -static void -init_compare(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_compare(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); int n1, n2; /* Store the values */ @@ -457,7 +445,7 @@ init_compare(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *p if (d->left.flags & d->right.flags & CMP_DYNAMICVAL) { /* Reverse the sides to place the integer on the right */ - int flags; + int flags; d->left.r = d->right.r; d->right.r = nullptr; d->right.i = d->left.i; @@ -483,10 +471,9 @@ init_compare(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *p * * Frees the memory allocated for \c t_methoddata_compare. */ -static void -free_data_compare(void *data) +static void free_data_compare(void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); sfree(d->cmpop); if (d->left.flags & CMP_ALLOCINT) @@ -515,10 +502,9 @@ free_data_compare(void *data) * \param[out] out Output data structure (\p out->u.g is used). * \param[in] data Should point to a \c t_methoddata_compare. */ -static void -evaluate_compare_int(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_compare_int(gmx_ana_index_t* g, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); int i, i1, i2, ig; int a, b; bool bAccept; @@ -531,12 +517,12 @@ evaluate_compare_int(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) switch (d->cmpt) { case CMP_INVALID: break; - case CMP_LESS: bAccept = a < b; break; - case CMP_LEQ: bAccept = a <= b; break; - case CMP_GTR: bAccept = a > b; break; - case CMP_GEQ: bAccept = a >= b; break; - case CMP_EQUAL: bAccept = a == b; break; - case CMP_NEQ: bAccept = a != b; break; + case CMP_LESS: bAccept = a < b; break; + case CMP_LEQ: bAccept = a <= b; break; + case CMP_GTR: bAccept = a > b; break; + case CMP_GEQ: bAccept = a >= b; break; + case CMP_EQUAL: bAccept = a == b; break; + case CMP_NEQ: bAccept = a != b; break; } if (bAccept) { @@ -564,10 +550,9 @@ evaluate_compare_int(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) * Left value is assumed to be real-valued; right value can be either. * This is ensured by the initialization method. */ -static void -evaluate_compare_real(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_compare_real(gmx_ana_index_t* g, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); int i, i1, i2, ig; real a, b; bool bAccept; @@ -580,12 +565,12 @@ evaluate_compare_real(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) switch (d->cmpt) { case CMP_INVALID: break; - case CMP_LESS: bAccept = a < b; break; - case CMP_LEQ: bAccept = a <= b; break; - case CMP_GTR: bAccept = a > b; break; - case CMP_GEQ: bAccept = a >= b; break; - case CMP_EQUAL: bAccept = gmx_within_tol(a, b, GMX_REAL_EPS); break; - case CMP_NEQ: bAccept = !gmx_within_tol(a, b, GMX_REAL_EPS); break; + case CMP_LESS: bAccept = a < b; break; + case CMP_LEQ: bAccept = a <= b; break; + case CMP_GTR: bAccept = a > b; break; + case CMP_GEQ: bAccept = a >= b; break; + case CMP_EQUAL: bAccept = gmx_within_tol(a, b, GMX_REAL_EPS); break; + case CMP_NEQ: bAccept = !gmx_within_tol(a, b, GMX_REAL_EPS); break; } if (bAccept) { @@ -603,11 +588,12 @@ evaluate_compare_real(gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) out->u.g->isize = ig; } -static void -evaluate_compare(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_compare(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_compare *d = static_cast(data); + t_methoddata_compare* d = static_cast(data); if (!((d->left.flags | d->right.flags) & CMP_REALVAL)) { diff --git a/src/gromacs/selection/sm_distance.cpp b/src/gromacs/selection/sm_distance.cpp index c52d492fad..c9dc219fde 100644 --- a/src/gromacs/selection/sm_distance.cpp +++ b/src/gromacs/selection/sm_distance.cpp @@ -63,18 +63,16 @@ */ struct t_methoddata_distance { - t_methoddata_distance() : cutoff(-1.0) - { - } + t_methoddata_distance() : cutoff(-1.0) {} /** Cutoff distance. */ - real cutoff; + real cutoff; /** Positions of the reference points. */ - gmx_ana_pos_t p; + gmx_ana_pos_t p; /** Neighborhood search data. */ - gmx::AnalysisNeighborhood nb; + gmx::AnalysisNeighborhood nb; /** Neighborhood search for an invididual frame. */ - gmx::AnalysisNeighborhoodSearch nbsearch; + gmx::AnalysisNeighborhoodSearch nbsearch; }; /*! \brief @@ -92,8 +90,7 @@ struct t_methoddata_distance * - the second parameter defines the reference positions and the value is * stored in \c t_methoddata_distance::p. */ -static void * -init_data_common(int npar, gmx_ana_selparam_t *param); +static void* init_data_common(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes a distance-based selection method. * @@ -108,11 +105,9 @@ init_data_common(int npar, gmx_ana_selparam_t *param); * (\c t_methoddata_distance::nb). * Also checks that the cutoff is valid. */ -static void -init_common(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_common(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Frees the data allocated for a distance-based selection method. */ -static void -free_data_common(void *data); +static void free_data_common(void* data); /*! \brief * Initializes the evaluation of a distance-based within selection method for a * frame. @@ -123,39 +118,40 @@ free_data_common(void *data); * * Initializes the neighborhood search for the current frame. */ -static void -init_frame_common(const gmx::SelMethodEvalContext &context, void *data); +static void init_frame_common(const gmx::SelMethodEvalContext& context, void* data); /** Evaluates the \p distance selection method. */ -static void -evaluate_distance(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_distance(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p within selection method. */ -static void -evaluate_within(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_within(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for the \p distance selection method. */ static gmx_ana_selparam_t smparams_distance[] = { - {"cutoff", {REAL_VALUE, 1, {nullptr}}, nullptr, SPAR_OPTIONAL}, - {"from", {POS_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, + { "cutoff", { REAL_VALUE, 1, { nullptr } }, nullptr, SPAR_OPTIONAL }, + { "from", { POS_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, }; /** Parameters for the \p mindistance selection method. */ static gmx_ana_selparam_t smparams_mindistance[] = { - {"cutoff", {REAL_VALUE, 1, {nullptr}}, nullptr, SPAR_OPTIONAL}, - {"from", {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, + { "cutoff", { REAL_VALUE, 1, { nullptr } }, nullptr, SPAR_OPTIONAL }, + { "from", { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, }; /** Parameters for the \p within selection method. */ static gmx_ana_selparam_t smparams_within[] = { - {nullptr, {REAL_VALUE, 1, {nullptr}}, nullptr, 0}, - {"of", {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, + { nullptr, { REAL_VALUE, 1, { nullptr } }, nullptr, 0 }, + { "of", { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, }; //! Help title for distance selection methods. -static const char helptitle_distance[] = "Selecting based on distance"; +static const char helptitle_distance[] = "Selecting based on distance"; //! Help text for distance selection methods. -static const char *const help_distance[] = { +static const char* const help_distance[] = { "::", "", " distance from POS [cutoff REAL]", @@ -177,8 +173,11 @@ static const char *const help_distance[] = { /** Selection method data for the \p distance method. */ gmx_ana_selmethod_t sm_distance = { - "distance", REAL_VALUE, SMETH_DYNAMIC, - asize(smparams_distance), smparams_distance, + "distance", + REAL_VALUE, + SMETH_DYNAMIC, + asize(smparams_distance), + smparams_distance, &init_data_common, nullptr, &init_common, @@ -187,14 +186,16 @@ gmx_ana_selmethod_t sm_distance = { &init_frame_common, nullptr, &evaluate_distance, - {"distance from POS [cutoff REAL]", - helptitle_distance, asize(help_distance), help_distance}, + { "distance from POS [cutoff REAL]", helptitle_distance, asize(help_distance), help_distance }, }; /** Selection method data for the \p distance method. */ gmx_ana_selmethod_t sm_mindistance = { - "mindistance", REAL_VALUE, SMETH_DYNAMIC, - asize(smparams_mindistance), smparams_mindistance, + "mindistance", + REAL_VALUE, + SMETH_DYNAMIC, + asize(smparams_mindistance), + smparams_mindistance, &init_data_common, nullptr, &init_common, @@ -203,14 +204,16 @@ gmx_ana_selmethod_t sm_mindistance = { &init_frame_common, nullptr, &evaluate_distance, - {"mindistance from POS_EXPR [cutoff REAL]", - helptitle_distance, asize(help_distance), help_distance}, + { "mindistance from POS_EXPR [cutoff REAL]", helptitle_distance, asize(help_distance), help_distance }, }; /** Selection method data for the \p within method. */ gmx_ana_selmethod_t sm_within = { - "within", GROUP_VALUE, SMETH_DYNAMIC, - asize(smparams_within), smparams_within, + "within", + GROUP_VALUE, + SMETH_DYNAMIC, + asize(smparams_within), + smparams_within, &init_data_common, nullptr, &init_common, @@ -219,23 +222,20 @@ gmx_ana_selmethod_t sm_within = { &init_frame_common, nullptr, &evaluate_within, - {"within REAL of POS_EXPR", - helptitle_distance, asize(help_distance), help_distance}, + { "within REAL of POS_EXPR", helptitle_distance, asize(help_distance), help_distance }, }; -static void * -init_data_common(int /* npar */, gmx_ana_selparam_t *param) +static void* init_data_common(int /* npar */, gmx_ana_selparam_t* param) { - t_methoddata_distance *data = new t_methoddata_distance(); - param[0].val.u.r = &data->cutoff; - param[1].val.u.p = &data->p; + t_methoddata_distance* data = new t_methoddata_distance(); + param[0].val.u.r = &data->cutoff; + param[1].val.u.p = &data->p; return data; } -static void -init_common(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_common(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_distance *d = static_cast(data); + t_methoddata_distance* d = static_cast(data); if ((param[0].flags & SPAR_SET) && d->cutoff <= 0) { @@ -250,16 +250,14 @@ init_common(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *pa * Frees the memory allocated for \c t_methoddata_distance::xref and * \c t_methoddata_distance::nb. */ -static void -free_data_common(void *data) +static void free_data_common(void* data) { - delete static_cast(data); + delete static_cast(data); } -static void -init_frame_common(const gmx::SelMethodEvalContext &context, void *data) +static void init_frame_common(const gmx::SelMethodEvalContext& context, void* data) { - t_methoddata_distance *d = static_cast(data); + t_methoddata_distance* d = static_cast(data); d->nbsearch.reset(); gmx::AnalysisNeighborhoodPositions pos(d->p.x, d->p.count()); @@ -273,11 +271,12 @@ init_frame_common(const gmx::SelMethodEvalContext &context, void *data) * Calculates the distance of each position from \c t_methoddata_distance::p * and puts them in \p out->u.r. */ -static void -evaluate_distance(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data) +static void evaluate_distance(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_distance *d = static_cast(data); + t_methoddata_distance* d = static_cast(data); out->nr = pos->count(); for (int i = 0; i < pos->count(); ++i) @@ -293,11 +292,12 @@ evaluate_distance(const gmx::SelMethodEvalContext & /*context*/, * Finds the atoms that are closer than the defined cutoff to * \c t_methoddata_distance::xref and puts them in \p out.g. */ -static void -evaluate_within(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data) +static void evaluate_within(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_distance *d = static_cast(data); + t_methoddata_distance* d = static_cast(data); out->u.g->isize = 0; for (int b = 0; b < pos->count(); ++b) diff --git a/src/gromacs/selection/sm_insolidangle.cpp b/src/gromacs/selection/sm_insolidangle.cpp index a5e196222f..4ad20f4e2c 100644 --- a/src/gromacs/selection/sm_insolidangle.cpp +++ b/src/gromacs/selection/sm_insolidangle.cpp @@ -83,11 +83,10 @@ * (Pythagoras's theorem in spherical coordinates). * -# For each zenith angle bin that is at least partially covered by the * cone, calculate the span of the cone at the edges using - * \f[\sin^2 \frac{\Delta \phi}{2} = \frac{\sin^2 \frac{\alpha}{2} - \sin^2 \frac{\theta - \theta'}{2}}{\sin \theta \sin \theta'}\f] - * (distance in spherical geometry), - * where \f$\theta'\f$ is the zenith angle of the bin edge. - * Treat zenith angle bins that are completely covered by the cone (in the - * case that the cone is centered close to the pole) as a special case. + * \f[\sin^2 \frac{\Delta \phi}{2} = \frac{\sin^2 \frac{\alpha}{2} - \sin^2 \frac{\theta - + * \theta'}{2}}{\sin \theta \sin \theta'}\f] (distance in spherical geometry), where \f$\theta'\f$ + * is the zenith angle of the bin edge. Treat zenith angle bins that are completely covered by the + * cone (in the case that the cone is centered close to the pole) as a special case. * -# Using the values calculated above, loop through the azimuthal bins that * are partially or completely covered by the cone and update them. * @@ -134,8 +133,8 @@ #include "selmethod.h" #include "selmethod_impl.h" -using std::min; using std::max; +using std::min; /*! \internal * \brief @@ -148,9 +147,9 @@ using std::max; typedef struct { /** Left edge of the partition. */ - real left; + real left; /** Bin index corresponding to this partition. */ - int bin; + int bin; } t_partition_item; /*! \internal @@ -166,9 +165,9 @@ typedef struct typedef struct { /** Number of partition items (\p p contains \p n+1 items). */ - int n; + int n; /** Array of partition edges and corresponding bins. */ - t_partition_item *p; + t_partition_item* p; } t_partition; /*! \internal @@ -184,11 +183,11 @@ typedef struct typedef struct { /** Number of points in the array \p x, -1 if whole bin covered. */ - int n; + int n; /** Number of elements allocated for \p x. */ - int n_alloc; + int n_alloc; /** Array of points that partially cover the bin. */ - rvec *x; + rvec* x; } t_spheresurfacebin; /*! \internal @@ -202,31 +201,31 @@ typedef struct typedef struct { /** Center of the solid angle. */ - gmx_ana_pos_t center; + gmx_ana_pos_t center; /** Positions that span the solid angle. */ - gmx_ana_pos_t span; + gmx_ana_pos_t span; /** Cutoff angle. */ - real angcut; + real angcut; /** Estimate of the covered fraction. */ - real cfrac; + real cfrac; /** Cutoff for the cosine (equals cos(angcut)). */ - real distccut; + real distccut; /** Bin size to be used as the target bin size when constructing the bins. */ - real targetbinsize; + real targetbinsize; /** Number of bins in the \p tbin array. */ - int ntbins; + int ntbins; /** Size of one bin in the zenith angle direction. */ - real tbinsize; + real tbinsize; /** Array of zenith angle slices. */ - t_partition *tbin; + t_partition* tbin; /** Number of elements allocated for the \p bin array. */ - int maxbins; + int maxbins; /** Number of elements used in the \p bin array. */ - int nbins; + int nbins; /** Array of individual bins. */ - t_spheresurfacebin *bin; + t_spheresurfacebin* bin; } t_methoddata_insolidangle; /*! \brief @@ -243,8 +242,7 @@ typedef struct * - \p span defines the value for t_methoddata_insolidangle::span. * - \p cutoff defines the value for t_methoddata_insolidangle::angcut. */ -static void * -init_data_insolidangle(int npar, gmx_ana_selparam_t *param); +static void* init_data_insolidangle(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes the \p insolidangle selection method. * @@ -257,11 +255,9 @@ init_data_insolidangle(int npar, gmx_ana_selparam_t *param); * Converts t_methoddata_insolidangle::angcut to radians and allocates * and allocates memory for the bins used during the evaluation. */ -static void -init_insolidangle(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t * param, void *data); +static void init_insolidangle(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Frees the data allocated for the \p insolidangle selection method. */ -static void -free_data_insolidangle(void *data); +static void free_data_insolidangle(void* data); /*! \brief * Initializes the evaluation of the \p insolidangle selection method for a frame. * @@ -271,45 +267,39 @@ free_data_insolidangle(void *data); * Creates a lookup structure that enables fast queries of whether a point * is within the solid angle or not. */ -static void -init_frame_insolidangle(const gmx::SelMethodEvalContext &context, void *data); +static void init_frame_insolidangle(const gmx::SelMethodEvalContext& context, void* data); /** Internal helper function for evaluate_insolidangle(). */ -static bool -accept_insolidangle(rvec x, const t_pbc *pbc, void *data); +static bool accept_insolidangle(rvec x, const t_pbc* pbc, void* data); /** Evaluates the \p insolidangle selection method. */ -static void -evaluate_insolidangle(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_insolidangle(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /** Calculates the distance between unit vectors. */ -static real -sph_distc(rvec x1, rvec x2); +static real sph_distc(rvec x1, rvec x2); /** Does a binary search on a \p t_partition to find a bin for a value. */ -static int -find_partition_bin(t_partition *p, real value); +static int find_partition_bin(t_partition* p, real value); /** Finds a bin that corresponds to a location on the unit sphere surface. */ -static int -find_surface_bin(t_methoddata_insolidangle *surf, rvec x); +static int find_surface_bin(t_methoddata_insolidangle* surf, rvec x); /** Clears/initializes the bins on the unit sphere surface. */ -static void -clear_surface_points(t_methoddata_insolidangle *surf); +static void clear_surface_points(t_methoddata_insolidangle* surf); /** Frees memory allocated for storing the reference points in the surface bins. */ -static void -free_surface_points(t_methoddata_insolidangle *surf); +static void free_surface_points(t_methoddata_insolidangle* surf); /** Adds a reference point to a given bin. */ -static void -add_surface_point(t_methoddata_insolidangle *surf, int tbin, int pbin, rvec x); +static void add_surface_point(t_methoddata_insolidangle* surf, int tbin, int pbin, rvec x); /** Marks a bin as completely covered. */ -static void -mark_surface_covered(t_methoddata_insolidangle *surf, int tbin, int pbin); +static void mark_surface_covered(t_methoddata_insolidangle* surf, int tbin, int pbin); /** Helper function for store_surface_point() to update a single zenith angle bin. */ -static void -update_surface_bin(t_methoddata_insolidangle *surf, int tbin, - real phi, real pdelta1, real pdelta2, real pdeltamax, - rvec x); +static void update_surface_bin(t_methoddata_insolidangle* surf, + int tbin, + real phi, + real pdelta1, + real pdelta2, + real pdeltamax, + rvec x); /** Adds a single reference point and updates the surface bins. */ -static void -store_surface_point(t_methoddata_insolidangle *surf, rvec x); +static void store_surface_point(t_methoddata_insolidangle* surf, rvec x); /*! \brief * Optimizes the surface bins for faster searching. * @@ -317,24 +307,21 @@ store_surface_point(t_methoddata_insolidangle *surf, rvec x); * * Currently, this function does nothing. */ -static void -optimize_surface_points(t_methoddata_insolidangle *surf); +static void optimize_surface_points(t_methoddata_insolidangle* surf); /** Estimates the area covered by the reference cones. */ -static real -estimate_covered_fraction(t_methoddata_insolidangle *surf); +static real estimate_covered_fraction(t_methoddata_insolidangle* surf); /** Checks whether a point lies within a solid angle. */ -static bool -is_surface_covered(t_methoddata_insolidangle *surf, rvec x); +static bool is_surface_covered(t_methoddata_insolidangle* surf, rvec x); /** Parameters for the \p insolidangle selection method. */ static gmx_ana_selparam_t smparams_insolidangle[] = { - {"center", {POS_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, - {"span", {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, - {"cutoff", {REAL_VALUE, 1, {nullptr}}, nullptr, SPAR_OPTIONAL}, + { "center", { POS_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, + { "span", { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, + { "cutoff", { REAL_VALUE, 1, { nullptr } }, nullptr, SPAR_OPTIONAL }, }; /** Help text for the \p insolidangle selection method. */ -static const char *const help_insolidangle[] = { +static const char* const help_insolidangle[] = { "::", "", " insolidangle center POS span POS_EXPR [cutoff REAL]", @@ -354,8 +341,11 @@ static const char *const help_insolidangle[] = { /** Selection method data for the \p insolidangle method. */ gmx_ana_selmethod_t sm_insolidangle = { - "insolidangle", GROUP_VALUE, SMETH_DYNAMIC, - asize(smparams_insolidangle), smparams_insolidangle, + "insolidangle", + GROUP_VALUE, + SMETH_DYNAMIC, + asize(smparams_insolidangle), + smparams_insolidangle, &init_data_insolidangle, nullptr, &init_insolidangle, @@ -364,27 +354,25 @@ gmx_ana_selmethod_t sm_insolidangle = { &init_frame_insolidangle, nullptr, &evaluate_insolidangle, - {"insolidangle center POS span POS_EXPR [cutoff REAL]", - "Selecting atoms in a solid angle", - asize(help_insolidangle), help_insolidangle}, + { "insolidangle center POS span POS_EXPR [cutoff REAL]", "Selecting atoms in a solid angle", + asize(help_insolidangle), help_insolidangle }, }; -static void * -init_data_insolidangle(int /* npar */, gmx_ana_selparam_t *param) +static void* init_data_insolidangle(int /* npar */, gmx_ana_selparam_t* param) { - t_methoddata_insolidangle *data = new t_methoddata_insolidangle(); - data->angcut = 5.0; - data->cfrac = 0.0; + t_methoddata_insolidangle* data = new t_methoddata_insolidangle(); + data->angcut = 5.0; + data->cfrac = 0.0; data->distccut = 0.0; data->targetbinsize = 0.0; - data->ntbins = 0; - data->tbinsize = 0.0; - data->tbin = nullptr; - data->maxbins = 0; - data->nbins = 0; - data->bin = nullptr; + data->ntbins = 0; + data->tbinsize = 0.0; + data->tbin = nullptr; + data->maxbins = 0; + data->nbins = 0; + data->bin = nullptr; param[0].val.u.p = &data->center; param[1].val.u.p = &data->span; @@ -392,10 +380,12 @@ init_data_insolidangle(int /* npar */, gmx_ana_selparam_t *param) return data; } -static void -init_insolidangle(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t * /* param */, void *data) +static void init_insolidangle(const gmx_mtop_t* /* top */, + int /* npar */, + gmx_ana_selparam_t* /* param */, + void* data) { - t_methoddata_insolidangle *surf = static_cast(data); + t_methoddata_insolidangle* surf = static_cast(data); int i, c; if (surf->angcut <= 0) @@ -408,16 +398,16 @@ init_insolidangle(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam surf->distccut = -std::cos(surf->angcut); surf->targetbinsize = surf->angcut / 2; surf->ntbins = static_cast(M_PI / surf->targetbinsize); - surf->tbinsize = (180.0 / surf->ntbins)*DEG2RAD; + surf->tbinsize = (180.0 / surf->ntbins) * DEG2RAD; snew(surf->tbin, static_cast(M_PI / surf->tbinsize) + 1); surf->maxbins = 0; for (i = 0; i < surf->ntbins; ++i) { - c = static_cast(std::max(std::sin(surf->tbinsize*i), - std::sin(surf->tbinsize*(i+1))) - * M_2PI / surf->targetbinsize) + 1; - snew(surf->tbin[i].p, c+1); + c = static_cast(std::max(std::sin(surf->tbinsize * i), std::sin(surf->tbinsize * (i + 1))) + * M_2PI / surf->targetbinsize) + + 1; + snew(surf->tbin[i].p, c + 1); surf->maxbins += c; } surf->nbins = 0; @@ -431,10 +421,9 @@ init_insolidangle(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam * \c t_methoddata_insolidangle::span, as well as the memory for the internal * bin structure. */ -static void -free_data_insolidangle(void *data) +static void free_data_insolidangle(void* data) { - t_methoddata_insolidangle *d = static_cast(data); + t_methoddata_insolidangle* d = static_cast(data); int i; if (d->tbin) @@ -450,10 +439,9 @@ free_data_insolidangle(void *data) delete d; } -static void -init_frame_insolidangle(const gmx::SelMethodEvalContext &context, void *data) +static void init_frame_insolidangle(const gmx::SelMethodEvalContext& context, void* data) { - t_methoddata_insolidangle *d = static_cast(data); + t_methoddata_insolidangle* d = static_cast(data); rvec dx; int i; @@ -482,10 +470,9 @@ init_frame_insolidangle(const gmx::SelMethodEvalContext &context, void *data) * \param[in] data Pointer to a \c t_methoddata_insolidangle data structure. * \returns true if \p x is within the solid angle, false otherwise. */ -static bool -accept_insolidangle(rvec x, const t_pbc *pbc, void *data) +static bool accept_insolidangle(rvec x, const t_pbc* pbc, void* data) { - t_methoddata_insolidangle *d = static_cast(data); + t_methoddata_insolidangle* d = static_cast(data); rvec dx; if (pbc) @@ -508,9 +495,10 @@ accept_insolidangle(rvec x, const t_pbc *pbc, void *data) * \c t_methoddata_insolidangle::span and centered at * \c t_methoddata_insolidangle::center, and stores the result in \p out->u.g. */ -static void -evaluate_insolidangle(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data) +static void evaluate_insolidangle(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data) { out->u.g->isize = 0; for (int b = 0; b < pos->count(); ++b) @@ -527,16 +515,15 @@ evaluate_insolidangle(const gmx::SelMethodEvalContext &context, * \returns true if the covered fraction can be estimated for \p sel with * _gmx_selelem_estimate_coverfrac(), false otherwise. */ -bool -_gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel) +bool _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement& sel) { if (sel.type == SEL_BOOLEAN && sel.u.boolt == BOOL_OR) { return false; } - bool bFound = false; - bool bDynFound = false; - gmx::SelectionTreeElementPointer child = sel.child; + bool bFound = false; + bool bDynFound = false; + gmx::SelectionTreeElementPointer child = sel.child; while (child) { if (child->type == SEL_EXPRESSION) @@ -549,8 +536,7 @@ _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel) } bFound = true; } - else if (child->u.expr.method - && (child->u.expr.method->flags & SMETH_DYNAMIC)) + else if (child->u.expr.method && (child->u.expr.method->flags & SMETH_DYNAMIC)) { if (bFound) { @@ -577,14 +563,13 @@ _gmx_selelem_can_estimate_cover(const gmx::SelectionTreeElement &sel) * Should be called after gmx_ana_evaluate_selections() has been called for the * frame. */ -real -_gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement &sel) +real _gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement& sel) { - real cfrac; + real cfrac; if (sel.type == SEL_EXPRESSION && sel.u.expr.method->name == sm_insolidangle.name) { - t_methoddata_insolidangle *d = static_cast(sel.u.expr.mdata); + t_methoddata_insolidangle* d = static_cast(sel.u.expr.mdata); if (d->cfrac < 0) { d->cfrac = estimate_covered_fraction(d); @@ -626,8 +611,7 @@ _gmx_selelem_estimate_coverfrac(const gmx::SelectionTreeElement &sel) * for efficiency, and the minus is there to make it behave like a normal * distance (larger values mean longer distances). */ -static real -sph_distc(rvec x1, rvec x2) +static real sph_distc(rvec x1, rvec x2) { return -iprod(x1, x2); } @@ -641,13 +625,13 @@ sph_distc(rvec x1, rvec x2) * Otherwise, the return value \c i satisfies \c p->p[i].left<=value and * \c p->p[i+1].left>value */ -static int -find_partition_bin(t_partition *p, real value) +static int find_partition_bin(t_partition* p, real value) { int pmin, pmax, pbin; /* Binary search the partition */ - pmin = 0; pmax = p->n; + pmin = 0; + pmax = p->n; while (pmax > pmin + 1) { pbin = pmin + (pmax - pmin) / 2; @@ -671,8 +655,7 @@ find_partition_bin(t_partition *p, real value) * * The return value is an index to the \p surf->bin array. */ -static int -find_surface_bin(t_methoddata_insolidangle *surf, rvec x) +static int find_surface_bin(t_methoddata_insolidangle* surf, rvec x) { real theta, phi; int tbin, pbin; @@ -694,17 +677,16 @@ find_surface_bin(t_methoddata_insolidangle *surf, rvec x) * Clears the reference points from the bins and (re)initializes the edges * of the azimuthal bins. */ -static void -clear_surface_points(t_methoddata_insolidangle *surf) +static void clear_surface_points(t_methoddata_insolidangle* surf) { int i, j, c; surf->nbins = 0; for (i = 0; i < surf->ntbins; ++i) { - c = static_cast(std::min(std::sin(surf->tbinsize*i), - std::sin(surf->tbinsize*(i+1))) - * M_2PI / surf->targetbinsize) + 1; + c = static_cast(std::min(std::sin(surf->tbinsize * i), std::sin(surf->tbinsize * (i + 1))) + * M_2PI / surf->targetbinsize) + + 1; if (c <= 0) { c = 1; @@ -712,7 +694,7 @@ clear_surface_points(t_methoddata_insolidangle *surf) surf->tbin[i].n = c; for (j = 0; j < c; ++j) { - surf->tbin[i].p[j].left = -M_PI + j*M_2PI/c - 0.0001; + surf->tbin[i].p[j].left = -M_PI + j * M_2PI / c - 0.0001; surf->tbin[i].p[j].bin = surf->nbins; surf->bin[surf->nbins].n = 0; surf->nbins++; @@ -725,8 +707,7 @@ clear_surface_points(t_methoddata_insolidangle *surf) /*! * \param[in,out] surf Surface data structure. */ -static void -free_surface_points(t_methoddata_insolidangle *surf) +static void free_surface_points(t_methoddata_insolidangle* surf) { int i; @@ -747,8 +728,7 @@ free_surface_points(t_methoddata_insolidangle *surf) * \param[in] pbin Bin number in the azimuthal angle direction. * \param[in] x Point to store. */ -static void -add_surface_point(t_methoddata_insolidangle *surf, int tbin, int pbin, rvec x) +static void add_surface_point(t_methoddata_insolidangle* surf, int tbin, int pbin, rvec x) { int bin; @@ -774,8 +754,7 @@ add_surface_point(t_methoddata_insolidangle *surf, int tbin, int pbin, rvec x) * \param[in] tbin Bin number in the zenith angle direction. * \param[in] pbin Bin number in the azimuthal angle direction. */ -static void -mark_surface_covered(t_methoddata_insolidangle *surf, int tbin, int pbin) +static void mark_surface_covered(t_methoddata_insolidangle* surf, int tbin, int pbin) { int bin; @@ -792,10 +771,13 @@ mark_surface_covered(t_methoddata_insolidangle *surf, int tbin, int pbin) * \param[in] pdeltamax Max. width of the cone inside \p tbin. * \param[in] x Point to store (should have unit length). */ -static void -update_surface_bin(t_methoddata_insolidangle *surf, int tbin, - real phi, real pdelta1, real pdelta2, real pdeltamax, - rvec x) +static void update_surface_bin(t_methoddata_insolidangle* surf, + int tbin, + real phi, + real pdelta1, + real pdelta2, + real pdeltamax, + rvec x) { real pdelta, phi1, phi2; int pbin1, pbin2, pbiniter, pbin; @@ -820,7 +802,7 @@ update_surface_bin(t_methoddata_insolidangle *surf, int tbin, } else { - pbin2 = find_partition_bin(&surf->tbin[tbin], phi2 - M_2PI); + pbin2 = find_partition_bin(&surf->tbin[tbin], phi2 - M_2PI); pbin2 += surf->tbin[tbin].n; } ++pbin2; @@ -842,13 +824,12 @@ update_surface_bin(t_methoddata_insolidangle *surf, int tbin, /* Wrap bin around if end reached */ if (pbin == surf->tbin[tbin].n) { - pbin = 0; + pbin = 0; phi1 -= M_2PI; phi2 -= M_2PI; } /* Check if bin is completely covered and update */ - if (surf->tbin[tbin].p[pbin].left >= phi1 - && surf->tbin[tbin].p[pbin+1].left <= phi2) + if (surf->tbin[tbin].p[pbin].left >= phi1 && surf->tbin[tbin].p[pbin + 1].left <= phi2) { mark_surface_covered(surf, tbin, pbin); } @@ -866,8 +847,7 @@ update_surface_bin(t_methoddata_insolidangle *surf, int tbin, * Finds all the bins covered by the cone centered at \p x and calls * update_surface_bin() to update them. */ -static void -store_surface_point(t_methoddata_insolidangle *surf, rvec x) +static void store_surface_point(t_methoddata_insolidangle* surf, rvec x) { real theta, phi; real pdeltamax, tmax; @@ -904,18 +884,16 @@ store_surface_point(t_methoddata_insolidangle *surf, rvec x) pdelta1 = M_PI; } /* Loop through all affected bins */ - while (tbin < std::ceil((theta + surf->angcut) / surf->tbinsize) - && tbin < surf->ntbins) + while (tbin < std::ceil((theta + surf->angcut) / surf->tbinsize) && tbin < surf->ntbins) { /* Calculate the next boundaries */ - theta2 = (tbin+1) * surf->tbinsize; + theta2 = (tbin + 1) * surf->tbinsize; if (theta2 > theta + surf->angcut) { /* The circle is completely outside the cone */ pdelta2 = 0; } - else if (theta2 <= -(theta - surf->angcut) - || theta2 >= M_2PI - (theta + surf->angcut) + else if (theta2 <= -(theta - surf->angcut) || theta2 >= M_2PI - (theta + surf->angcut) || tbin == surf->ntbins - 1) { /* The circle is completely inside the cone, or we are in the @@ -929,9 +907,10 @@ store_surface_point(t_methoddata_insolidangle *surf, rvec x) * much, but it would be nicer to adjust the theta bin boundaries * such that the case above catches this instead of falling through * here. */ - pdelta2 = 2*asin(std::sqrt( - (gmx::square(std::sin(surf->angcut/2)) - gmx::square(std::sin((theta2-theta)/2))) / - (sin(theta) * sin(theta2)))); + pdelta2 = 2 + * asin(std::sqrt((gmx::square(std::sin(surf->angcut / 2)) + - gmx::square(std::sin((theta2 - theta) / 2))) + / (sin(theta) * sin(theta2)))); } /* Update the bin */ if (tmax >= theta1 && tmax <= theta2) @@ -949,8 +928,7 @@ store_surface_point(t_methoddata_insolidangle *surf, rvec x) } } -static void -optimize_surface_points(t_methoddata_insolidangle * /* surf */) +static void optimize_surface_points(t_methoddata_insolidangle* /* surf */) { /* TODO: Implement */ } @@ -959,8 +937,7 @@ optimize_surface_points(t_methoddata_insolidangle * /* surf */) * \param[in] surf Surface data structure. * \returns An estimate for the area covered by the reference points. */ -static real -estimate_covered_fraction(t_methoddata_insolidangle *surf) +static real estimate_covered_fraction(t_methoddata_insolidangle* surf) { int t, p, n; real cfrac, tfrac, pfrac; @@ -968,22 +945,22 @@ estimate_covered_fraction(t_methoddata_insolidangle *surf) cfrac = 0.0; for (t = 0; t < surf->ntbins; ++t) { - tfrac = std::cos(t * surf->tbinsize) - std::cos((t+1) * surf->tbinsize); + tfrac = std::cos(t * surf->tbinsize) - std::cos((t + 1) * surf->tbinsize); for (p = 0; p < surf->tbin[t].n; ++p) { - pfrac = surf->tbin[t].p[p+1].left - surf->tbin[t].p[p].left; + pfrac = surf->tbin[t].p[p + 1].left - surf->tbin[t].p[p].left; n = surf->bin[surf->tbin[t].p[p].bin].n; if (n == -1) /* Bin completely covered */ { cfrac += tfrac * pfrac; } - else if (n > 0) /* Bin partially covered */ + else if (n > 0) /* Bin partially covered */ { cfrac += tfrac * pfrac / 2; /* A rough estimate */ } } } - return cfrac / (4*M_PI); + return cfrac / (4 * M_PI); } /*! @@ -991,10 +968,9 @@ estimate_covered_fraction(t_methoddata_insolidangle *surf) * \param[in] x Unit vector to check. * \returns true if \p x is within the solid angle, false otherwise. */ -static bool -is_surface_covered(t_methoddata_insolidangle *surf, rvec x) +static bool is_surface_covered(t_methoddata_insolidangle* surf, rvec x) { - int bin, i; + int bin, i; bin = find_surface_bin(surf, x); /* Check for completely covered bin */ diff --git a/src/gromacs/selection/sm_keywords.cpp b/src/gromacs/selection/sm_keywords.cpp index 73228d6a52..c2fe093f86 100644 --- a/src/gromacs/selection/sm_keywords.cpp +++ b/src/gromacs/selection/sm_keywords.cpp @@ -71,8 +71,7 @@ * * Allocates memory for a \ref t_methoddata_kwint structure. */ -static void * -init_data_kwint(int npar, gmx_ana_selparam_t * param); +static void* init_data_kwint(int npar, gmx_ana_selparam_t* param); /*! \brief * Allocates data for real keyword evaluation. * @@ -82,8 +81,7 @@ init_data_kwint(int npar, gmx_ana_selparam_t * param); * * Allocates memory for a \ref t_methoddata_kwreal structure. */ -static void * -init_data_kwreal(int npar, gmx_ana_selparam_t * param); +static void* init_data_kwreal(int npar, gmx_ana_selparam_t* param); /*! \brief * Allocates data for string keyword evaluation. * @@ -93,8 +91,7 @@ init_data_kwreal(int npar, gmx_ana_selparam_t * param); * * Allocates memory for a t_methoddata_kwstr structure. */ -static void * -init_data_kwstr(int npar, gmx_ana_selparam_t * param); +static void* init_data_kwstr(int npar, gmx_ana_selparam_t* param); /** /brief Initializes data for integer keyword evaluation. * * \param[in] top Not used. @@ -102,8 +99,7 @@ init_data_kwstr(int npar, gmx_ana_selparam_t * param); * \param[in] param Method parameters (should point to \ref smparams_keyword_int). * \param[in] data Should point to \ref t_methoddata_kwint. */ -static void -init_kwint(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_kwint(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes data for real keyword evaluation. * @@ -113,8 +109,7 @@ init_kwint(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *dat * \param[in] data Should point to \ref t_methoddata_kwreal. * \returns 0 (the initialization always succeeds). */ -static void -init_kwreal(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_kwreal(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes data for string keyword evaluation. * @@ -123,23 +118,24 @@ init_kwreal(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *da * \param[in] param Method parameters (should point to \ref smparams_keyword_str). * \param[in] data Should point to t_methoddata_kwstr. */ -static void -init_kwstr(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_kwstr(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Frees the memory allocated for string keyword evaluation. */ -static void -free_data_kwstr(void *data); +static void free_data_kwstr(void* data); /** Evaluates integer selection keywords. */ -static void -evaluate_keyword_int(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_keyword_int(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates real selection keywords. */ -static void -evaluate_keyword_real(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_keyword_real(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates string selection keywords. */ -static void -evaluate_keyword_str(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_keyword_str(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \internal \brief * Data structure for integer keyword expression evaluation. @@ -147,9 +143,9 @@ evaluate_keyword_str(const gmx::SelMethodEvalContext &context, typedef struct t_methoddata_kwint { /** Array of values for the keyword. */ - int *v; + int* v; /** Number of ranges in the \p r array. */ - int n; + int n; /*! \brief * Array of sorted integer ranges to match against. * @@ -157,7 +153,7 @@ typedef struct t_methoddata_kwint * This field stores the pointer to the ranges allocated by the * parameter parser; see \ref SPAR_RANGES for more information. */ - int *r; + int* r; } t_methoddata_kwint; /*! \internal \brief @@ -166,9 +162,9 @@ typedef struct t_methoddata_kwint typedef struct t_methoddata_kwreal { /** Array of values for the keyword. */ - real *v; + real* v; /** Number of ranges in the \p r array. */ - int n; + int n; /*! \brief * Array of sorted ranges to match against. * @@ -176,7 +172,7 @@ typedef struct t_methoddata_kwreal * This field stores the pointer to the ranges allocated by the * parameter parser; see \ref SPAR_RANGES for more information. */ - real *r; + real* r; } t_methoddata_kwreal; namespace @@ -189,75 +185,72 @@ namespace */ class StringKeywordMatchItem { - public: - /*! \brief - * Constructs a matcher from a string. - * - * \param[in] matchType String matching type. - * \param[in] str String to use for matching. - */ - StringKeywordMatchItem(gmx::SelectionStringMatchType matchType, - const char *str) - : str_(str) +public: + /*! \brief + * Constructs a matcher from a string. + * + * \param[in] matchType String matching type. + * \param[in] str String to use for matching. + */ + StringKeywordMatchItem(gmx::SelectionStringMatchType matchType, const char* str) : str_(str) + { + useRegExp_ = (matchType == gmx::eStringMatchType_RegularExpression); + if (matchType == gmx::eStringMatchType_Auto) { - useRegExp_ = (matchType == gmx::eStringMatchType_RegularExpression); - if (matchType == gmx::eStringMatchType_Auto) - { - for (size_t j = 0; j < std::strlen(str); ++j) - { - if (std::ispunct(str[j]) && str[j] != '?' && str[j] != '*') - { - useRegExp_ = true; - break; - } - } - } - if (useRegExp_) + for (size_t j = 0; j < std::strlen(str); ++j) { - try + if (std::ispunct(str[j]) && str[j] != '?' && str[j] != '*') { - regex_.assign(str, std::regex::nosubs | std::regex::extended); - } - catch (const std::regex_error & /*ex*/) - { - // TODO: Better error messages. - GMX_THROW(gmx::InvalidInputError - (gmx::formatString("Error in regular expression \"%s\"", str))); + useRegExp_ = true; + break; } } } - - /*! \brief - * Checks whether this item matches a string. - * - * \param[in] matchType String matching type. - * \param[in] value String to match. - * \returns true if this item matches \p value. - */ - bool match(gmx::SelectionStringMatchType matchType, - const char *value) const + if (useRegExp_) { - if (matchType == gmx::eStringMatchType_Exact) + try { - return str_ == value; + regex_.assign(str, std::regex::nosubs | std::regex::extended); } - else if (useRegExp_) - { - return std::regex_match(value, regex_); - } - else + catch (const std::regex_error& /*ex*/) { - return gmx_wcmatch(str_.c_str(), value) == 0; + // TODO: Better error messages. + GMX_THROW(gmx::InvalidInputError( + gmx::formatString("Error in regular expression \"%s\"", str))); } } + } - private: - //! The raw string passed for the matcher. - std::string str_; - //! Whether a regular expression match is used. - bool useRegExp_; - //! Regular expression compiled from \p str_, if applicable. - std::regex regex_; + /*! \brief + * Checks whether this item matches a string. + * + * \param[in] matchType String matching type. + * \param[in] value String to match. + * \returns true if this item matches \p value. + */ + bool match(gmx::SelectionStringMatchType matchType, const char* value) const + { + if (matchType == gmx::eStringMatchType_Exact) + { + return str_ == value; + } + else if (useRegExp_) + { + return std::regex_match(value, regex_); + } + else + { + return gmx_wcmatch(str_.c_str(), value) == 0; + } + } + +private: + //! The raw string passed for the matcher. + std::string str_; + //! Whether a regular expression match is used. + bool useRegExp_; + //! Regular expression compiled from \p str_, if applicable. + std::regex regex_; }; /*! \internal \brief @@ -266,9 +259,9 @@ class StringKeywordMatchItem struct t_methoddata_kwstr { /** Matching type for the strings. */ - gmx::SelectionStringMatchType matchType; + gmx::SelectionStringMatchType matchType; /** Array of values for the keyword. */ - char **v; + char** v; /** Array of strings/regular expressions to match against.*/ std::vector matches; }; @@ -277,26 +270,29 @@ struct t_methoddata_kwstr /** Parameters for integer keyword evaluation. */ static gmx_ana_selparam_t smparams_keyword_int[] = { - {nullptr, {INT_VALUE, -1, {nullptr}}, nullptr, SPAR_ATOMVAL}, - {nullptr, {INT_VALUE, -1, {nullptr}}, nullptr, SPAR_RANGES | SPAR_VARNUM}, + { nullptr, { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_ATOMVAL }, + { nullptr, { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_RANGES | SPAR_VARNUM }, }; /** Parameters for real keyword evaluation. */ static gmx_ana_selparam_t smparams_keyword_real[] = { - {nullptr, {REAL_VALUE, -1, {nullptr}}, nullptr, SPAR_ATOMVAL | SPAR_DYNAMIC}, - {nullptr, {REAL_VALUE, -1, {nullptr}}, nullptr, SPAR_RANGES | SPAR_VARNUM}, + { nullptr, { REAL_VALUE, -1, { nullptr } }, nullptr, SPAR_ATOMVAL | SPAR_DYNAMIC }, + { nullptr, { REAL_VALUE, -1, { nullptr } }, nullptr, SPAR_RANGES | SPAR_VARNUM }, }; /** Parameters for string keyword evaluation. */ static gmx_ana_selparam_t smparams_keyword_str[] = { - {nullptr, {STR_VALUE, -1, {nullptr}}, nullptr, SPAR_ATOMVAL}, - {nullptr, {STR_VALUE, -1, {nullptr}}, nullptr, SPAR_VARNUM}, + { nullptr, { STR_VALUE, -1, { nullptr } }, nullptr, SPAR_ATOMVAL }, + { nullptr, { STR_VALUE, -1, { nullptr } }, nullptr, SPAR_VARNUM }, }; /** Selection method data for integer keyword evaluation. */ gmx_ana_selmethod_t sm_keyword_int = { - "kw_int", GROUP_VALUE, SMETH_SINGLEVAL, - asize(smparams_keyword_int), smparams_keyword_int, + "kw_int", + GROUP_VALUE, + SMETH_SINGLEVAL, + asize(smparams_keyword_int), + smparams_keyword_int, &init_data_kwint, nullptr, &init_kwint, @@ -305,13 +301,16 @@ gmx_ana_selmethod_t sm_keyword_int = { nullptr, &evaluate_keyword_int, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; /** Selection method data for real keyword evaluation. */ gmx_ana_selmethod_t sm_keyword_real = { - "kw_real", GROUP_VALUE, SMETH_SINGLEVAL, - asize(smparams_keyword_real), smparams_keyword_real, + "kw_real", + GROUP_VALUE, + SMETH_SINGLEVAL, + asize(smparams_keyword_real), + smparams_keyword_real, &init_data_kwreal, nullptr, &init_kwreal, @@ -320,13 +319,16 @@ gmx_ana_selmethod_t sm_keyword_real = { nullptr, &evaluate_keyword_real, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; /** Selection method data for string keyword evaluation. */ gmx_ana_selmethod_t sm_keyword_str = { - "kw_str", GROUP_VALUE, SMETH_SINGLEVAL, - asize(smparams_keyword_str), smparams_keyword_str, + "kw_str", + GROUP_VALUE, + SMETH_SINGLEVAL, + asize(smparams_keyword_str), + smparams_keyword_str, &init_data_kwstr, nullptr, &init_kwstr, @@ -335,7 +337,7 @@ gmx_ana_selmethod_t sm_keyword_str = { nullptr, &evaluate_keyword_str, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; /*! \brief @@ -349,8 +351,7 @@ gmx_ana_selmethod_t sm_keyword_str = { * * Calls the initialization method of the wrapped keyword. */ -static void -init_kweval(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t * param, void *data); +static void init_kweval(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes output for keyword evaluation in an arbitrary group. * @@ -359,14 +360,11 @@ init_kweval(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t * param, void *d * \param[in,out] data Should point to \c t_methoddata_kweval. * \returns 0 for success. */ -static void -init_output_kweval(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data); +static void init_output_kweval(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /** Frees the data allocated for keyword evaluation in an arbitrary group. */ -static void -free_data_kweval(void *data); +static void free_data_kweval(void* data); /** Initializes frame evaluation for keyword evaluation in an arbitrary group. */ -static void -init_frame_kweval(const gmx::SelMethodEvalContext &context, void *data); +static void init_frame_kweval(const gmx::SelMethodEvalContext& context, void* data); /*! \brief * Evaluates keywords in an arbitrary group. * @@ -377,9 +375,10 @@ init_frame_kweval(const gmx::SelMethodEvalContext &context, void *data); * parameters, with the exception of using \c t_methoddata_kweval::g for the * evaluation group. */ -static void -evaluate_kweval(const gmx::SelMethodEvalContext &context, gmx_ana_index_t *g, - gmx_ana_selvalue_t *out, void *data); +static void evaluate_kweval(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Evaluates keywords in an arbitrary set of positions. * @@ -390,9 +389,10 @@ evaluate_kweval(const gmx::SelMethodEvalContext &context, gmx_ana_index_t *g, * parameters, with the exception of using \c t_methoddata_kweval::p for the * evaluation positions. */ -static void -evaluate_kweval_pos(const gmx::SelMethodEvalContext &context, gmx_ana_index_t *g, - gmx_ana_selvalue_t *out, void *data); +static void evaluate_kweval_pos(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \internal \brief * Data structure for keyword evaluation in arbitrary groups. @@ -400,33 +400,29 @@ evaluate_kweval_pos(const gmx::SelMethodEvalContext &context, gmx_ana_index_t *g struct t_methoddata_kweval { //! Initialize new keyword evaluator for the given keyword. - t_methoddata_kweval(gmx_ana_selmethod_t *method, void *data) - : kwmethod(method), kwmdata(data) + t_methoddata_kweval(gmx_ana_selmethod_t* method, void* data) : kwmethod(method), kwmdata(data) { gmx_ana_index_clear(&g); } - ~t_methoddata_kweval() - { - _gmx_selelem_free_method(kwmethod, kwmdata); - } + ~t_methoddata_kweval() { _gmx_selelem_free_method(kwmethod, kwmdata); } //! Wrapped keyword method for evaluating the values. - gmx_ana_selmethod_t *kwmethod; + gmx_ana_selmethod_t* kwmethod; //! Method data for \p kwmethod. - void *kwmdata; + void* kwmdata; //! Group in which \p kwmethod should be evaluated. - gmx_ana_index_t g; + gmx_ana_index_t g; //! Positions for which \p kwmethod should be evaluated. - gmx_ana_pos_t p; + gmx_ana_pos_t p; }; /** Parameters for keyword evaluation in an arbitrary group. */ static gmx_ana_selparam_t smparams_kweval_group[] = { - {nullptr, {GROUP_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, + { nullptr, { GROUP_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, }; /** Parameters for keyword evaluation from positions. */ static gmx_ana_selparam_t smparams_kweval_pos[] = { - {nullptr, {POS_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, + { nullptr, { POS_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, }; @@ -434,19 +430,17 @@ static gmx_ana_selparam_t smparams_kweval_pos[] = { * INTEGER KEYWORD EVALUATION ********************************************************************/ -static void * -init_data_kwint(int /* npar */, gmx_ana_selparam_t * /* param */) +static void* init_data_kwint(int /* npar */, gmx_ana_selparam_t* /* param */) { - t_methoddata_kwint *data; + t_methoddata_kwint* data; snew(data, 1); return data; } -static void -init_kwint(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_kwint(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_kwint *d = static_cast(data); + t_methoddata_kwint* d = static_cast(data); d->v = param[0].val.u.i; d->n = param[1].val.nr; @@ -461,11 +455,12 @@ init_kwint(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *par * \c t_methoddata_kwint structure for this selection. * Matching atoms are stored in \p out->u.g. */ -static void -evaluate_keyword_int(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_keyword_int(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_kwint *d = static_cast(data); + t_methoddata_kwint* d = static_cast(data); int n, i, j, jmin, jmax; int val; @@ -474,7 +469,7 @@ evaluate_keyword_int(const gmx::SelMethodEvalContext & /*context*/, for (i = 0; i < g->isize; ++i) { val = d->v[i]; - if (d->r[0] > val || d->r[2*n-1] < val) + if (d->r[0] > val || d->r[2 * n - 1] < val) { continue; } @@ -483,21 +478,21 @@ evaluate_keyword_int(const gmx::SelMethodEvalContext & /*context*/, while (jmax - jmin > 1) { j = jmin + (jmax - jmin) / 2; - if (val < d->r[2*j]) + if (val < d->r[2 * j]) { jmax = j; } else { jmin = j; - if (val <= d->r[2*j+1]) + if (val <= d->r[2 * j + 1]) { break; } /* ++jmin;*/ } } - if (val <= d->r[2*jmin+1]) + if (val <= d->r[2 * jmin + 1]) { out->u.g->index[out->u.g->isize++] = g->index[i]; } @@ -509,19 +504,17 @@ evaluate_keyword_int(const gmx::SelMethodEvalContext & /*context*/, * REAL KEYWORD EVALUATION ********************************************************************/ -static void * -init_data_kwreal(int /* npar */, gmx_ana_selparam_t * /* param */) +static void* init_data_kwreal(int /* npar */, gmx_ana_selparam_t* /* param */) { - t_methoddata_kwreal *data; + t_methoddata_kwreal* data; snew(data, 1); return data; } -static void -init_kwreal(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_kwreal(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_kwreal *d = static_cast(data); + t_methoddata_kwreal* d = static_cast(data); d->v = param[0].val.u.r; d->n = param[1].val.nr; @@ -536,11 +529,12 @@ init_kwreal(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *pa * \c t_methoddata_kwreal structure for this selection. * Matching atoms are stored in \p out->u.g. */ -static void -evaluate_keyword_real(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_keyword_real(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_kwreal *d = static_cast(data); + t_methoddata_kwreal* d = static_cast(data); int n, i, j, jmin, jmax; real val; @@ -549,7 +543,7 @@ evaluate_keyword_real(const gmx::SelMethodEvalContext & /*context*/, for (i = 0; i < g->isize; ++i) { val = d->v[i]; - if (d->r[0] > val || d->r[2*n-1] < val) + if (d->r[0] > val || d->r[2 * n - 1] < val) { continue; } @@ -558,21 +552,21 @@ evaluate_keyword_real(const gmx::SelMethodEvalContext & /*context*/, while (jmax - jmin > 1) { j = jmin + (jmax - jmin) / 2; - if (val < d->r[2*j]) + if (val < d->r[2 * j]) { jmax = j; } else { jmin = j; - if (val <= d->r[2*j+1]) + if (val <= d->r[2 * j + 1]) { break; } /* ++jmin;*/ } } - if (val <= d->r[2*jmin+1]) + if (val <= d->r[2 * jmin + 1]) { out->u.g->index[out->u.g->isize++] = g->index[i]; } @@ -584,11 +578,10 @@ evaluate_keyword_real(const gmx::SelMethodEvalContext & /*context*/, * STRING KEYWORD EVALUATION ********************************************************************/ -static void * -init_data_kwstr(int /* npar */, gmx_ana_selparam_t * /* param */) +static void* init_data_kwstr(int /* npar */, gmx_ana_selparam_t* /* param */) { - t_methoddata_kwstr *data = new t_methoddata_kwstr(); - data->matchType = gmx::eStringMatchType_Auto; + t_methoddata_kwstr* data = new t_methoddata_kwstr(); + data->matchType = gmx::eStringMatchType_Auto; return data; } @@ -598,11 +591,10 @@ init_data_kwstr(int /* npar */, gmx_ana_selparam_t * /* param */) * * Sets the string matching method for string keyword matching. */ -void -_gmx_selelem_set_kwstr_match_type(const gmx::SelectionTreeElementPointer &sel, - gmx::SelectionStringMatchType matchType) +void _gmx_selelem_set_kwstr_match_type(const gmx::SelectionTreeElementPointer& sel, + gmx::SelectionStringMatchType matchType) { - t_methoddata_kwstr *d = static_cast(sel->u.expr.mdata); + t_methoddata_kwstr* d = static_cast(sel->u.expr.mdata); if (sel->type != SEL_EXPRESSION || !sel->u.expr.method || sel->u.expr.method->name != sm_keyword_str.name) @@ -612,12 +604,11 @@ _gmx_selelem_set_kwstr_match_type(const gmx::SelectionTreeElementPointer &sel, d->matchType = matchType; } -static void -init_kwstr(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_kwstr(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_kwstr *d = static_cast(data); + t_methoddata_kwstr* d = static_cast(data); - d->v = param[0].val.u.s; + d->v = param[0].val.u.s; /* Return if this is not the first time */ if (!d->matches.empty()) { @@ -627,7 +618,7 @@ init_kwstr(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *par d->matches.reserve(n); for (int i = 0; i < n; ++i) { - const char *s = param[1].val.u.s[i]; + const char* s = param[1].val.u.s[i]; d->matches.emplace_back(d->matchType, s); } } @@ -635,10 +626,9 @@ init_kwstr(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *par /*! * \param data Data to free (should point to a t_methoddata_kwstr). */ -static void -free_data_kwstr(void *data) +static void free_data_kwstr(void* data) { - t_methoddata_kwstr *d = static_cast(data); + t_methoddata_kwstr* d = static_cast(data); delete d; } @@ -651,11 +641,12 @@ free_data_kwstr(void *data) * Wildcards are allowed in the strings. * Matching atoms are stored in \p out->u.g. */ -static void -evaluate_keyword_str(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_keyword_str(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_kwstr *d = static_cast(data); + t_methoddata_kwstr* d = static_cast(data); out->u.g->isize = 0; for (int i = 0; i < g->isize; ++i) @@ -676,18 +667,16 @@ evaluate_keyword_str(const gmx::SelMethodEvalContext & /*context*/, * KEYWORD EVALUATION FOR ARBITRARY GROUPS ********************************************************************/ -static void -init_kweval(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void *data) +static void init_kweval(const gmx_mtop_t* top, int /* npar */, gmx_ana_selparam_t* /* param */, void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); d->kwmethod->init(top, 0, nullptr, d->kwmdata); } -static void -init_output_kweval(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void *data) +static void init_output_kweval(const gmx_mtop_t* /* top */, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); out->nr = d->g.isize; _gmx_selvalue_reserve(out, out->nr); @@ -698,10 +687,9 @@ init_output_kweval(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void * * * Frees the memory allocated for all the members of \c t_methoddata_kweval. */ -static void -free_data_kweval(void *data) +static void free_data_kweval(void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); delete d; } @@ -710,28 +698,29 @@ free_data_kweval(void *data) * \param[in] context Evaluation context. * \param data Should point to a \ref t_methoddata_kweval. */ -static void -init_frame_kweval(const gmx::SelMethodEvalContext &context, void *data) +static void init_frame_kweval(const gmx::SelMethodEvalContext& context, void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); d->kwmethod->init_frame(context, d->kwmdata); } -static void -evaluate_kweval(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void *data) +static void evaluate_kweval(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* /* g */, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); d->kwmethod->update(context, &d->g, out, d->kwmdata); } -static void -evaluate_kweval_pos(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void *data) +static void evaluate_kweval_pos(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* /* g */, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_kweval *d = static_cast(data); + t_methoddata_kweval* d = static_cast(data); d->kwmethod->pupdate(context, &d->p, out, d->kwmdata); } @@ -747,50 +736,44 @@ evaluate_kweval_pos(const gmx::SelMethodEvalContext &context, * Implements _gmx_sel_init_keyword_evaluator() for \ref GROUP_VALUE input * selections. */ -static gmx::SelectionTreeElementPointer -init_evaluator_group(gmx_ana_selmethod_t *method, - const gmx::SelectionParserParameterList ¶ms, - void *scanner) +static gmx::SelectionTreeElementPointer init_evaluator_group(gmx_ana_selmethod_t* method, + const gmx::SelectionParserParameterList& params, + void* scanner) { - if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) - || method->outinit || method->pupdate) + if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) || method->outinit || method->pupdate) { - std::string message - = gmx::formatString("Keyword '%s' cannot be evaluated in this context", - method->name); + std::string message = + gmx::formatString("Keyword '%s' cannot be evaluated in this context", method->name); GMX_THROW(gmx::InvalidInputError(message)); } // TODO: For same ... as ..., some other location could be more intuitive. - gmx::SelectionTreeElementPointer sel( - new gmx::SelectionTreeElement( - SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); + gmx::SelectionTreeElementPointer sel(new gmx::SelectionTreeElement( + SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(sel, method, scanner); - t_methoddata_kweval *data - = new t_methoddata_kweval(sel->u.expr.method, sel->u.expr.mdata); + t_methoddata_kweval* data = new t_methoddata_kweval(sel->u.expr.method, sel->u.expr.mdata); snew(sel->u.expr.method, 1); - sel->u.expr.method->name = data->kwmethod->name; - sel->u.expr.method->type = data->kwmethod->type; - sel->u.expr.method->flags = data->kwmethod->flags | SMETH_VARNUMVAL; - sel->u.expr.method->init_data = nullptr; - sel->u.expr.method->set_poscoll = nullptr; - sel->u.expr.method->init = method->init ? &init_kweval : nullptr; - sel->u.expr.method->outinit = &init_output_kweval; - sel->u.expr.method->free = &free_data_kweval; - sel->u.expr.method->init_frame = method->init_frame ? &init_frame_kweval : nullptr; - sel->u.expr.method->update = &evaluate_kweval; - sel->u.expr.method->pupdate = nullptr; - sel->u.expr.method->nparams = asize(smparams_kweval_group); - sel->u.expr.method->param = smparams_kweval_group; + sel->u.expr.method->name = data->kwmethod->name; + sel->u.expr.method->type = data->kwmethod->type; + sel->u.expr.method->flags = data->kwmethod->flags | SMETH_VARNUMVAL; + sel->u.expr.method->init_data = nullptr; + sel->u.expr.method->set_poscoll = nullptr; + sel->u.expr.method->init = method->init ? &init_kweval : nullptr; + sel->u.expr.method->outinit = &init_output_kweval; + sel->u.expr.method->free = &free_data_kweval; + sel->u.expr.method->init_frame = method->init_frame ? &init_frame_kweval : nullptr; + sel->u.expr.method->update = &evaluate_kweval; + sel->u.expr.method->pupdate = nullptr; + sel->u.expr.method->nparams = asize(smparams_kweval_group); + sel->u.expr.method->param = smparams_kweval_group; _gmx_selelem_init_method_params(sel, scanner); sel->u.expr.mdata = data; sel->u.expr.method->param[0].val.u.g = &data->g; - _gmx_sel_parse_params(params, sel->u.expr.method->nparams, - sel->u.expr.method->param, sel, scanner); + _gmx_sel_parse_params(params, sel->u.expr.method->nparams, sel->u.expr.method->param, sel, scanner); return sel; } @@ -805,60 +788,52 @@ init_evaluator_group(gmx_ana_selmethod_t *method, * Implements _gmx_sel_init_keyword_evaluator() for \ref POS_VALUE input * selections. */ -static gmx::SelectionTreeElementPointer -init_evaluator_pos(gmx_ana_selmethod_t *method, - const gmx::SelectionParserParameterList ¶ms, - void *scanner) +static gmx::SelectionTreeElementPointer init_evaluator_pos(gmx_ana_selmethod_t* method, + const gmx::SelectionParserParameterList& params, + void* scanner) { - if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) - || method->outinit || method->pupdate == nullptr) + if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL)) || method->outinit || method->pupdate == nullptr) { - std::string message - = gmx::formatString("Keyword '%s' cannot be evaluated in this context", - method->name); + std::string message = + gmx::formatString("Keyword '%s' cannot be evaluated in this context", method->name); GMX_THROW(gmx::InvalidInputError(message)); } - gmx::SelectionTreeElementPointer sel( - new gmx::SelectionTreeElement( - SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); + gmx::SelectionTreeElementPointer sel(new gmx::SelectionTreeElement( + SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner))); _gmx_selelem_set_method(sel, method, scanner); - t_methoddata_kweval *data - = new t_methoddata_kweval(sel->u.expr.method, sel->u.expr.mdata); + t_methoddata_kweval* data = new t_methoddata_kweval(sel->u.expr.method, sel->u.expr.mdata); snew(sel->u.expr.method, 1); - sel->u.expr.method->name = data->kwmethod->name; - sel->u.expr.method->type = data->kwmethod->type; - sel->u.expr.method->flags = data->kwmethod->flags | SMETH_SINGLEVAL; - sel->u.expr.method->init_data = nullptr; - sel->u.expr.method->set_poscoll = nullptr; - sel->u.expr.method->init = method->init ? &init_kweval : nullptr; - sel->u.expr.method->outinit = nullptr; - sel->u.expr.method->free = &free_data_kweval; - sel->u.expr.method->init_frame = method->init_frame ? &init_frame_kweval : nullptr; - sel->u.expr.method->update = &evaluate_kweval_pos; - sel->u.expr.method->pupdate = nullptr; - sel->u.expr.method->nparams = asize(smparams_kweval_pos); - sel->u.expr.method->param = smparams_kweval_pos; + sel->u.expr.method->name = data->kwmethod->name; + sel->u.expr.method->type = data->kwmethod->type; + sel->u.expr.method->flags = data->kwmethod->flags | SMETH_SINGLEVAL; + sel->u.expr.method->init_data = nullptr; + sel->u.expr.method->set_poscoll = nullptr; + sel->u.expr.method->init = method->init ? &init_kweval : nullptr; + sel->u.expr.method->outinit = nullptr; + sel->u.expr.method->free = &free_data_kweval; + sel->u.expr.method->init_frame = method->init_frame ? &init_frame_kweval : nullptr; + sel->u.expr.method->update = &evaluate_kweval_pos; + sel->u.expr.method->pupdate = nullptr; + sel->u.expr.method->nparams = asize(smparams_kweval_pos); + sel->u.expr.method->param = smparams_kweval_pos; _gmx_selelem_init_method_params(sel, scanner); sel->u.expr.mdata = data; sel->u.expr.method->param[0].val.u.p = &data->p; - _gmx_sel_parse_params(params, sel->u.expr.method->nparams, - sel->u.expr.method->param, sel, scanner); + _gmx_sel_parse_params(params, sel->u.expr.method->nparams, sel->u.expr.method->param, sel, scanner); return sel; } -gmx::SelectionTreeElementPointer -_gmx_sel_init_keyword_evaluator(gmx_ana_selmethod_t *method, - const gmx::SelectionTreeElementPointer &child, - void *scanner) +gmx::SelectionTreeElementPointer _gmx_sel_init_keyword_evaluator(gmx_ana_selmethod_t* method, + const gmx::SelectionTreeElementPointer& child, + void* scanner) { - gmx::SelectionParserParameterList params; - params.push_back( - gmx::SelectionParserParameter::createFromExpression(nullptr, child)); + gmx::SelectionParserParameterList params; + params.push_back(gmx::SelectionParserParameter::createFromExpression(nullptr, child)); if (child->v.type == GROUP_VALUE) { return init_evaluator_group(method, params, scanner); @@ -870,9 +845,8 @@ _gmx_sel_init_keyword_evaluator(gmx_ana_selmethod_t *method, else { std::string text(_gmx_sel_lexer_get_text(scanner, child->location())); - std::string message - = gmx::formatString("Expression '%s' cannot be used to evaluate keywords", - text.c_str()); + std::string message = + gmx::formatString("Expression '%s' cannot be used to evaluate keywords", text.c_str()); GMX_THROW(gmx::InvalidInputError(message)); } } diff --git a/src/gromacs/selection/sm_merge.cpp b/src/gromacs/selection/sm_merge.cpp index 048e5ca3e4..553c10fc54 100644 --- a/src/gromacs/selection/sm_merge.cpp +++ b/src/gromacs/selection/sm_merge.cpp @@ -57,16 +57,15 @@ typedef struct { /** Input positions. */ - gmx_ana_pos_t p1; + gmx_ana_pos_t p1; /** Other input positions. */ - gmx_ana_pos_t p2; + gmx_ana_pos_t p2; /** Stride for merging (\c stride values from \c p1 for each in \c p2). */ - int stride; + int stride; } t_methoddata_merge; /** Allocates data for the merging selection modifiers. */ -static void * -init_data_merge(int npar, gmx_ana_selparam_t *param); +static void* init_data_merge(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes data for the merging selection modifiers. * @@ -76,17 +75,13 @@ init_data_merge(int npar, gmx_ana_selparam_t *param); * \param[in] data Should point to a \p t_methoddata_merge. * \returns 0 if everything is successful, -1 on error. */ -static void -init_merge(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_merge(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Initializes output for the \p merge selection modifier. */ -static void -init_output_merge(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data); +static void init_output_merge(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /** Initializes output for the \p plus selection modifier. */ -static void -init_output_plus(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data); +static void init_output_plus(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /** Frees the memory allocated for the merging selection modifiers. */ -static void -free_data_merge(void *data); +static void free_data_merge(void* data); /*! \brief * Evaluates the \p merge selection modifier. * @@ -95,9 +90,10 @@ free_data_merge(void *data); * \param[out] out Output data structure (\p out->u.p is used). * \param[in] data Should point to a \p t_methoddata_merge. */ -static void -evaluate_merge(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t * p, gmx_ana_selvalue_t *out, void *data); +static void evaluate_merge(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* p, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Evaluates the \p plus selection modifier. * @@ -106,21 +102,22 @@ evaluate_merge(const gmx::SelMethodEvalContext &context, * \param[out] out Output data structure (\p out->u.p is used). * \param[in] data Should point to a \p t_methoddata_merge. */ -static void -evaluate_plus(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t * p, gmx_ana_selvalue_t *out, void *data); +static void evaluate_plus(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* p, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for the merging selection modifiers. */ static gmx_ana_selparam_t smparams_merge[] = { - {nullptr, {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, - {nullptr, {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, - {"stride", {INT_VALUE, 1, {nullptr}}, nullptr, SPAR_OPTIONAL}, + { nullptr, { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, + { nullptr, { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, + { "stride", { INT_VALUE, 1, { nullptr } }, nullptr, SPAR_OPTIONAL }, }; //! Help title for the merging selection modifiers. -static const char helptitle_merge[] = "Merging selections"; +static const char helptitle_merge[] = "Merging selections"; //! Help text for the merging selection modifiers. -static const char *const help_merge[] = { +static const char* const help_merge[] = { "::", "", " POSEXPR merge POSEXPR [stride INT]", @@ -147,8 +144,11 @@ static const char *const help_merge[] = { /** Selection method data for the \p plus modifier. */ gmx_ana_selmethod_t sm_merge = { - "merge", POS_VALUE, SMETH_MODIFIER, - asize(smparams_merge), smparams_merge, + "merge", + POS_VALUE, + SMETH_MODIFIER, + asize(smparams_merge), + smparams_merge, &init_data_merge, nullptr, &init_merge, @@ -157,13 +157,16 @@ gmx_ana_selmethod_t sm_merge = { nullptr, nullptr, &evaluate_merge, - {"merge POSEXPR", helptitle_merge, asize(help_merge), help_merge}, + { "merge POSEXPR", helptitle_merge, asize(help_merge), help_merge }, }; /** Selection method data for the \p plus modifier. */ gmx_ana_selmethod_t sm_plus = { - "plus", POS_VALUE, SMETH_MODIFIER, - asize(smparams_merge)-1, smparams_merge, + "plus", + POS_VALUE, + SMETH_MODIFIER, + asize(smparams_merge) - 1, + smparams_merge, &init_data_merge, nullptr, &init_merge, @@ -172,7 +175,7 @@ gmx_ana_selmethod_t sm_plus = { nullptr, nullptr, &evaluate_plus, - {"plus POSEXPR", helptitle_merge, asize(help_merge), help_merge}, + { "plus POSEXPR", helptitle_merge, asize(help_merge), help_merge }, }; /*! @@ -183,13 +186,12 @@ gmx_ana_selmethod_t sm_plus = { * * Allocates memory for a \p t_methoddata_merge structure. */ -static void * -init_data_merge(int npar, gmx_ana_selparam_t *param) +static void* init_data_merge(int npar, gmx_ana_selparam_t* param) { - t_methoddata_merge *data = new t_methoddata_merge(); - data->stride = 0; - param[0].val.u.p = &data->p1; - param[1].val.u.p = &data->p2; + t_methoddata_merge* data = new t_methoddata_merge(); + data->stride = 0; + param[0].val.u.p = &data->p1; + param[1].val.u.p = &data->p2; if (npar > 2) { param[2].val.u.i = &data->stride; @@ -197,10 +199,9 @@ init_data_merge(int npar, gmx_ana_selparam_t *param) return data; } -static void -init_merge(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t * /* param */, void *data) +static void init_merge(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* /* param */, void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); if (d->stride < 0) { @@ -211,9 +212,10 @@ init_merge(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t * /* { d->stride = d->p1.count() / d->p2.count(); } - if (d->p1.count() != d->stride*d->p2.count()) + if (d->p1.count() != d->stride * d->p2.count()) { - GMX_THROW(gmx::InconsistentInputError("The number of positions to be merged are not compatible")); + GMX_THROW(gmx::InconsistentInputError( + "The number of positions to be merged are not compatible")); } } @@ -224,10 +226,9 @@ init_merge(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t * /* * \param[in,out] out Pointer to output data structure. * \param[in,out] data Should point to \c t_methoddata_merge. */ -static void -init_output_common(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) +static void init_output_common(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); GMX_UNUSED_VALUE(top); if (d->p1.m.type != d->p2.m.type) @@ -240,8 +241,7 @@ init_output_common(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) out->u.p->m.type = d->p1.m.type; } gmx_ana_pos_reserve_for_append(out->u.p, d->p1.count() + d->p2.count(), - d->p1.m.b.nra + d->p2.m.b.nra, - d->p1.v != nullptr, d->p1.f != nullptr); + d->p1.m.b.nra + d->p2.m.b.nra, d->p1.v != nullptr, d->p1.f != nullptr); gmx_ana_pos_empty_init(out->u.p); } @@ -250,10 +250,9 @@ init_output_common(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) * \param[in,out] out Pointer to output data structure. * \param[in,out] data Should point to \c t_methoddata_merge. */ -static void -init_output_merge(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) +static void init_output_merge(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); int i, j; init_output_common(top, out, data); @@ -272,10 +271,9 @@ init_output_merge(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) * \param[in,out] out Pointer to output data structure. * \param[in,out] data Should point to \c t_methoddata_merge. */ -static void -init_output_plus(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) +static void init_output_plus(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); int i; init_output_common(top, out, data); @@ -294,48 +292,50 @@ init_output_plus(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data) * * Frees the memory allocated for \c t_methoddata_merge. */ -static void -free_data_merge(void *data) +static void free_data_merge(void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); delete d; } -static void -evaluate_merge(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t * /* p */, gmx_ana_selvalue_t *out, void *data) +static void evaluate_merge(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* /* p */, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); int i, j; int refid; - if (d->p1.count() != d->stride*d->p2.count()) + if (d->p1.count() != d->stride * d->p2.count()) { - GMX_THROW(gmx::InconsistentInputError("The number of positions to be merged are not compatible")); + GMX_THROW(gmx::InconsistentInputError( + "The number of positions to be merged are not compatible")); } gmx_ana_pos_empty(out->u.p); for (i = 0; i < d->p2.count(); ++i) { for (j = 0; j < d->stride; ++j) { - refid = d->p1.m.refid[d->stride*i+j]; + refid = d->p1.m.refid[d->stride * i + j]; if (refid != -1) { - refid = (d->stride+1) * (refid / d->stride) + (refid % d->stride); + refid = (d->stride + 1) * (refid / d->stride) + (refid % d->stride); } - gmx_ana_pos_append(out->u.p, &d->p1, d->stride*i+j, refid); + gmx_ana_pos_append(out->u.p, &d->p1, d->stride * i + j, refid); } - refid = (d->stride+1)*d->p2.m.refid[i] + d->stride; + refid = (d->stride + 1) * d->p2.m.refid[i] + d->stride; gmx_ana_pos_append(out->u.p, &d->p2, i, refid); } gmx_ana_pos_append_finish(out->u.p); } -static void -evaluate_plus(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t * /* p */, gmx_ana_selvalue_t *out, void *data) +static void evaluate_plus(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* /* p */, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_merge *d = static_cast(data); + t_methoddata_merge* d = static_cast(data); int i; int refid; diff --git a/src/gromacs/selection/sm_permute.cpp b/src/gromacs/selection/sm_permute.cpp index bc258a1c42..a5d7222ae4 100644 --- a/src/gromacs/selection/sm_permute.cpp +++ b/src/gromacs/selection/sm_permute.cpp @@ -57,13 +57,13 @@ typedef struct { /** Positions to permute. */ - gmx_ana_pos_t p; + gmx_ana_pos_t p; /** Number of elements in the permutation. */ - int n; + int n; /** Array describing the permutation. */ - int *perm; + int* perm; /** Array that has the permutation reversed. */ - int *rperm; + int* rperm; } t_methoddata_permute; /*! \brief @@ -76,8 +76,7 @@ typedef struct * * Allocates memory for a \p t_methoddata_permute structure. */ -static void * -init_data_permute(int npar, gmx_ana_selparam_t *param); +static void* init_data_permute(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes data for the \p permute selection modifier. * @@ -87,8 +86,7 @@ init_data_permute(int npar, gmx_ana_selparam_t *param); * \param[in] data Should point to a \p t_methoddata_permute. * \returns 0 if the input permutation is valid, -1 on error. */ -static void -init_permute(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_permute(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes output for the \p permute selection modifier. * @@ -96,11 +94,9 @@ init_permute(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *d * \param[in,out] out Pointer to output data structure. * \param[in,out] data Should point to \c t_methoddata_permute. */ -static void -init_output_permute(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data); +static void init_output_permute(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /** Frees the memory allocated for the \p permute selection modifier. */ -static void -free_data_permute(void *data); +static void free_data_permute(void* data); /*! \brief * Evaluates the \p permute selection modifier. * @@ -112,18 +108,19 @@ free_data_permute(void *data); * Throws if the size of \p p is not divisible by the number of * elements in the permutation. */ -static void -evaluate_permute(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *p, gmx_ana_selvalue_t *out, void *data); +static void evaluate_permute(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* p, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for the \p permute selection modifier. */ static gmx_ana_selparam_t smparams_permute[] = { - {nullptr, {POS_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, - {nullptr, {INT_VALUE, -1, {nullptr}}, nullptr, SPAR_VARNUM}, + { nullptr, { POS_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, + { nullptr, { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_VARNUM }, }; /** Help text for the \p permute selection modifier. */ -static const char *const help_permute[] = { +static const char* const help_permute[] = { "::", "", " permute P1 ... PN", @@ -143,8 +140,11 @@ static const char *const help_permute[] = { /** Selection method data for the \p permute modifier. */ gmx_ana_selmethod_t sm_permute = { - "permute", POS_VALUE, SMETH_MODIFIER, - asize(smparams_permute), smparams_permute, + "permute", + POS_VALUE, + SMETH_MODIFIER, + asize(smparams_permute), + smparams_permute, &init_data_permute, nullptr, &init_permute, @@ -153,33 +153,30 @@ gmx_ana_selmethod_t sm_permute = { nullptr, nullptr, &evaluate_permute, - {"POSEXPR permute P1 ... PN", - "Permuting selections", asize(help_permute), help_permute}, + { "POSEXPR permute P1 ... PN", "Permuting selections", asize(help_permute), help_permute }, }; -static void * -init_data_permute(int /* npar */, gmx_ana_selparam_t *param) +static void* init_data_permute(int /* npar */, gmx_ana_selparam_t* param) { - t_methoddata_permute *data = new t_methoddata_permute(); - data->n = 0; - data->perm = nullptr; - data->rperm = nullptr; - param[0].val.u.p = &data->p; + t_methoddata_permute* data = new t_methoddata_permute(); + data->n = 0; + data->perm = nullptr; + data->rperm = nullptr; + param[0].val.u.p = &data->p; return data; } -static void -init_permute(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_permute(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_permute *d = static_cast(data); + t_methoddata_permute* d = static_cast(data); int i; d->n = param[1].val.nr; d->perm = param[1].val.u.i; if (d->p.count() % d->n != 0) { - GMX_THROW(gmx::InconsistentInputError( - gmx::formatString("The number of positions to be permuted is not divisible by %d", d->n))); + GMX_THROW(gmx::InconsistentInputError(gmx::formatString( + "The number of positions to be permuted is not divisible by %d", d->n))); } snew(d->rperm, d->n); for (i = 0; i < d->n; ++i) @@ -201,15 +198,14 @@ init_permute(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *p } } -static void -init_output_permute(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void *data) +static void init_output_permute(const gmx_mtop_t* /* top */, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_permute *d = static_cast(data); + t_methoddata_permute* d = static_cast(data); int i, j, b; out->u.p->m.type = d->p.m.type; - gmx_ana_pos_reserve_for_append(out->u.p, d->p.count(), d->p.m.b.nra, - d->p.v != nullptr, d->p.f != nullptr); + gmx_ana_pos_reserve_for_append(out->u.p, d->p.count(), d->p.m.b.nra, d->p.v != nullptr, + d->p.f != nullptr); gmx_ana_pos_empty_init(out->u.p); for (i = 0; i < d->p.count(); i += d->n) { @@ -226,27 +222,27 @@ init_output_permute(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void * * Frees the memory allocated for \c t_methoddata_permute. */ -static void -free_data_permute(void *data) +static void free_data_permute(void* data) { - t_methoddata_permute *d = static_cast(data); + t_methoddata_permute* d = static_cast(data); sfree(d->rperm); delete d; } -static void -evaluate_permute(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t * /*p*/, gmx_ana_selvalue_t *out, void *data) +static void evaluate_permute(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* /*p*/, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_permute *d = static_cast(data); + t_methoddata_permute* d = static_cast(data); int i, j, b; int refid; if (d->p.count() % d->n != 0) { - GMX_THROW(gmx::InconsistentInputError( - gmx::formatString("The number of positions to be permuted is not divisible by %d", d->n))); + GMX_THROW(gmx::InconsistentInputError(gmx::formatString( + "The number of positions to be permuted is not divisible by %d", d->n))); } gmx_ana_pos_empty(out->u.p); for (i = 0; i < d->p.count(); i += d->n) diff --git a/src/gromacs/selection/sm_position.cpp b/src/gromacs/selection/sm_position.cpp index 06bb5016f0..7e103e243b 100644 --- a/src/gromacs/selection/sm_position.cpp +++ b/src/gromacs/selection/sm_position.cpp @@ -59,25 +59,23 @@ typedef struct { /** Position calculation collection to use. */ - gmx::PositionCalculationCollection *pcc; + gmx::PositionCalculationCollection* pcc; /** Index group for which the center should be evaluated. */ - gmx_ana_index_t g; + gmx_ana_index_t g; /** Position evaluation data structure. */ - gmx_ana_poscalc_t *pc; + gmx_ana_poscalc_t* pc; /** true if periodic boundary conditions should be used. */ - bool bPBC; + bool bPBC; /** Type of positions to calculate. */ - char *type; + char* type; /** Flags for the position calculation. */ - int flags; + int flags; } t_methoddata_pos; /** Allocates data for position evaluation selection methods. */ -static void * -init_data_pos(int npar, gmx_ana_selparam_t *param); +static void* init_data_pos(int npar, gmx_ana_selparam_t* param); /** Sets the position calculation collection for position evaluation selection methods. */ -static void -set_poscoll_pos(gmx::PositionCalculationCollection *pcc, void *data); +static void set_poscoll_pos(gmx::PositionCalculationCollection* pcc, void* data); /*! \brief * Initializes position evaluation keywords. * @@ -90,8 +88,7 @@ set_poscoll_pos(gmx::PositionCalculationCollection *pcc, void *data); * The \c t_methoddata_pos::type field should have been initialized * externally using _gmx_selelem_set_kwpos_type(). */ -static void -init_kwpos(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_kwpos(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes the \p cog selection method. * @@ -101,8 +98,7 @@ init_kwpos(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *dat * \param[in,out] data Should point to \c t_methoddata_pos. * \returns 0 on success, a non-zero error code on error. */ -static void -init_cog(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_cog(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes the \p cog selection method. * @@ -112,8 +108,7 @@ init_cog(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data) * \param[in,out] data Should point to \c t_methoddata_pos. * \returns 0 on success, a non-zero error code on error. */ -static void -init_com(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_com(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /*! \brief * Initializes output for position evaluation selection methods. * @@ -122,31 +117,33 @@ init_com(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data) * \param[in,out] data Should point to \c t_methoddata_pos. * \returns 0 for success. */ -static void -init_output_pos(const gmx_mtop_t *top, gmx_ana_selvalue_t *out, void *data); +static void init_output_pos(const gmx_mtop_t* top, gmx_ana_selvalue_t* out, void* data); /** Frees the data allocated for position evaluation selection methods. */ -static void -free_data_pos(void *data); +static void free_data_pos(void* data); /** Evaluates position evaluation selection methods. */ -static void -evaluate_pos(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void *data); +static void evaluate_pos(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* /* g */, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for position keyword evaluation. */ static gmx_ana_selparam_t smparams_keyword_pos[] = { - {nullptr, {GROUP_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, + { nullptr, { GROUP_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, }; /** Parameters for the \p cog and \p com selection methods. */ static gmx_ana_selparam_t smparams_com[] = { - {"of", {GROUP_VALUE, 1, {nullptr}}, nullptr, SPAR_DYNAMIC}, - {"pbc", {NO_VALUE, 0, {nullptr}}, nullptr, 0}, + { "of", { GROUP_VALUE, 1, { nullptr } }, nullptr, SPAR_DYNAMIC }, + { "pbc", { NO_VALUE, 0, { nullptr } }, nullptr, 0 }, }; /** Selection method data for position keyword evaluation. */ gmx_ana_selmethod_t sm_keyword_pos = { - "kw_pos", POS_VALUE, SMETH_DYNAMIC | SMETH_VARNUMVAL | SMETH_ALLOW_UNSORTED, - asize(smparams_keyword_pos), smparams_keyword_pos, + "kw_pos", + POS_VALUE, + SMETH_DYNAMIC | SMETH_VARNUMVAL | SMETH_ALLOW_UNSORTED, + asize(smparams_keyword_pos), + smparams_keyword_pos, &init_data_pos, &set_poscoll_pos, &init_kwpos, @@ -155,13 +152,16 @@ gmx_ana_selmethod_t sm_keyword_pos = { nullptr, &evaluate_pos, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; /** Selection method data for the \p cog method. */ gmx_ana_selmethod_t sm_cog = { - "cog", POS_VALUE, SMETH_DYNAMIC | SMETH_SINGLEVAL, - asize(smparams_com), smparams_com, + "cog", + POS_VALUE, + SMETH_DYNAMIC | SMETH_SINGLEVAL, + asize(smparams_com), + smparams_com, &init_data_pos, &set_poscoll_pos, &init_cog, @@ -170,13 +170,16 @@ gmx_ana_selmethod_t sm_cog = { nullptr, &evaluate_pos, nullptr, - {"cog of ATOM_EXPR [pbc]", nullptr, 0, nullptr}, + { "cog of ATOM_EXPR [pbc]", nullptr, 0, nullptr }, }; /** Selection method data for the \p com method. */ gmx_ana_selmethod_t sm_com = { - "com", POS_VALUE, SMETH_REQMASS | SMETH_DYNAMIC | SMETH_SINGLEVAL, - asize(smparams_com), smparams_com, + "com", + POS_VALUE, + SMETH_REQMASS | SMETH_DYNAMIC | SMETH_SINGLEVAL, + asize(smparams_com), + smparams_com, &init_data_pos, &set_poscoll_pos, &init_com, @@ -185,7 +188,7 @@ gmx_ana_selmethod_t sm_com = { nullptr, &evaluate_pos, nullptr, - {"com of ATOM_EXPR [pbc]", nullptr, 0, nullptr}, + { "com of ATOM_EXPR [pbc]", nullptr, 0, nullptr }, }; /*! @@ -199,10 +202,9 @@ gmx_ana_selmethod_t sm_com = { * If a second parameter is present, it is used for setting the * \c t_methoddata_pos::bPBC flag. */ -static void * -init_data_pos(int npar, gmx_ana_selparam_t *param) +static void* init_data_pos(int npar, gmx_ana_selparam_t* param) { - t_methoddata_pos *data; + t_methoddata_pos* data; snew(data, 1); param[0].val.u.g = &data->g; @@ -210,10 +212,10 @@ init_data_pos(int npar, gmx_ana_selparam_t *param) { param[1].val.u.b = &data->bPBC; } - data->pc = nullptr; - data->bPBC = false; - data->type = nullptr; - data->flags = -1; + data->pc = nullptr; + data->bPBC = false; + data->type = nullptr; + data->flags = -1; return data; } @@ -221,14 +223,12 @@ init_data_pos(int npar, gmx_ana_selparam_t *param) * \param[in] pcc Position calculation collection to use. * \param[in,out] data Should point to \c t_methoddata_pos. */ -static void -set_poscoll_pos(gmx::PositionCalculationCollection *pcc, void *data) +static void set_poscoll_pos(gmx::PositionCalculationCollection* pcc, void* data) { - (static_cast(data))->pcc = pcc; + (static_cast(data))->pcc = pcc; } -bool -_gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement &sel) +bool _gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement& sel) { if (sel.type != SEL_EXPRESSION || !sel.u.expr.method || sel.u.expr.method->name != sm_keyword_pos.name) @@ -236,7 +236,7 @@ _gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement &sel) return false; } - t_methoddata_pos *d = static_cast(sel.u.expr.mdata); + t_methoddata_pos* d = static_cast(sel.u.expr.mdata); return d->type == nullptr; } @@ -246,8 +246,7 @@ _gmx_selelem_is_default_kwpos(const gmx::SelectionTreeElement &sel) * Sets the flags to require topology and/or masses if the position calculation * requires them. */ -static void set_pos_method_flags(gmx_ana_selmethod_t *method, - t_methoddata_pos *d) +static void set_pos_method_flags(gmx_ana_selmethod_t* method, t_methoddata_pos* d) { const bool forces = (d->flags != -1 && ((d->flags & POS_FORCES) != 0)); switch (gmx::PositionCalculationCollection::requiredTopologyInfoForType(d->type, forces)) @@ -259,8 +258,7 @@ static void set_pos_method_flags(gmx_ana_selmethod_t *method, case gmx::PositionCalculationCollection::RequiredTopologyInfo::Topology: method->flags |= SMETH_REQTOP; break; - case gmx::PositionCalculationCollection::RequiredTopologyInfo::None: - break; + case gmx::PositionCalculationCollection::RequiredTopologyInfo::None: break; } } @@ -273,10 +271,9 @@ static void set_pos_method_flags(gmx_ana_selmethod_t *method, * If called multiple times, the first setting takes effect, and later calls * are neglected. */ -void -_gmx_selelem_set_kwpos_type(gmx::SelectionTreeElement *sel, const char *type) +void _gmx_selelem_set_kwpos_type(gmx::SelectionTreeElement* sel, const char* type) { - t_methoddata_pos *d = static_cast(sel->u.expr.mdata); + t_methoddata_pos* d = static_cast(sel->u.expr.mdata); if (sel->type != SEL_EXPRESSION || !sel->u.expr.method || sel->u.expr.method->name != sm_keyword_pos.name) @@ -299,10 +296,9 @@ _gmx_selelem_set_kwpos_type(gmx::SelectionTreeElement *sel, const char *type) * If called multiple times, the first setting takes effect, and later calls * are neglected. */ -void -_gmx_selelem_set_kwpos_flags(gmx::SelectionTreeElement *sel, int flags) +void _gmx_selelem_set_kwpos_flags(gmx::SelectionTreeElement* sel, int flags) { - t_methoddata_pos *d = static_cast(sel->u.expr.mdata); + t_methoddata_pos* d = static_cast(sel->u.expr.mdata); if (sel->type != SEL_EXPRESSION || !sel->u.expr.method || sel->u.expr.method->name != sm_keyword_pos.name) @@ -311,17 +307,15 @@ _gmx_selelem_set_kwpos_flags(gmx::SelectionTreeElement *sel, int flags) } if (d->flags == -1) { - GMX_RELEASE_ASSERT(d->type != nullptr, - "Position type should be set before flags"); + GMX_RELEASE_ASSERT(d->type != nullptr, "Position type should be set before flags"); d->flags = flags; set_pos_method_flags(sel->u.expr.method, d); } } -static void -init_kwpos(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_kwpos(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); if (!(param[0].flags & SPAR_DYNAMIC)) { @@ -335,31 +329,28 @@ init_kwpos(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *par gmx_ana_poscalc_set_maxindex(d->pc, &d->g); } -static void -init_cog(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_cog(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0; d->pc = d->pcc->createCalculation(d->bPBC ? POS_ALL_PBC : POS_ALL, d->flags); gmx_ana_poscalc_set_maxindex(d->pc, &d->g); } -static void -init_com(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_com(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); - d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0; + d->flags = (param[0].flags & SPAR_DYNAMIC) ? POS_DYNAMIC : 0; d->flags |= POS_MASS; - d->pc = d->pcc->createCalculation(d->bPBC ? POS_ALL_PBC : POS_ALL, d->flags); + d->pc = d->pcc->createCalculation(d->bPBC ? POS_ALL_PBC : POS_ALL, d->flags); gmx_ana_poscalc_set_maxindex(d->pc, &d->g); } -static void -init_output_pos(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void *data) +static void init_output_pos(const gmx_mtop_t* /* top */, gmx_ana_selvalue_t* out, void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); gmx_ana_poscalc_init_pos(d->pc, out->u.p); } @@ -370,10 +361,9 @@ init_output_pos(const gmx_mtop_t * /* top */, gmx_ana_selvalue_t *out, void *dat * Frees the memory allocated for \c t_methoddata_pos::g and * \c t_methoddata_pos::pc. */ -static void -free_data_pos(void *data) +static void free_data_pos(void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); sfree(d->type); gmx_ana_poscalc_free(d->pc); @@ -387,11 +377,12 @@ free_data_pos(void *data) * Calculates the positions using \c t_methoddata_pos::pc for the index group * in \c t_methoddata_pos::g and stores the results in \p out->u.p. */ -static void -evaluate_pos(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void *data) +static void evaluate_pos(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* /* g */, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_pos *d = static_cast(data); + t_methoddata_pos* d = static_cast(data); gmx_ana_poscalc_update(d->pc, out->u.p, &d->g, context.fr, context.pbc); } diff --git a/src/gromacs/selection/sm_same.cpp b/src/gromacs/selection/sm_same.cpp index 26d7c5d16c..d9cc3a8695 100644 --- a/src/gromacs/selection/sm_same.cpp +++ b/src/gromacs/selection/sm_same.cpp @@ -66,26 +66,24 @@ typedef struct { /** Value for each atom to match. */ - union - { - int *i; - char **s; - void *ptr; - } val; + union { + int* i; + char** s; + void* ptr; + } val; /*! \brief * Number of values in the \p as array. * * For string values, this is actually the number of values in the * \p as_s_sorted array. */ - int nas; + int nas; /** Values to match against. */ - union - { - int *i; - char **s; - void *ptr; - } as; + union { + int* i; + char** s; + void* ptr; + } as; /*! \brief * Separate array for sorted \p as.s array. * @@ -94,9 +92,9 @@ typedef struct * may be reused for several evaluations), so we keep our own copy for * modifications. */ - char **as_s_sorted; + char** as_s_sorted; /** Whether simple matching can be used. */ - bool bSorted; + bool bSorted; } t_methoddata_same; /*! \brief @@ -107,8 +105,7 @@ typedef struct * ::smparams_same_int or ::smparams_same_str). * \returns Pointer to the allocated data (\ref t_methoddata_same). */ -static void * -init_data_same(int npar, gmx_ana_selparam_t *param); +static void* init_data_same(int npar, gmx_ana_selparam_t* param); /*! \brief * Initializes the \p same selection method. * @@ -119,11 +116,9 @@ init_data_same(int npar, gmx_ana_selparam_t *param); * \param data Pointer to \ref t_methoddata_same to initialize. * \returns 0 on success, -1 on failure. */ -static void -init_same(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void init_same(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Frees the data allocated for the \p same selection method. */ -static void -free_data_same(void *data); +static void free_data_same(void* data); /*! \brief * Initializes the evaluation of the \p same selection method for a frame. * @@ -133,12 +128,12 @@ free_data_same(void *data); * Sorts the \c data->as.i array and removes identical values for faster and * simpler lookup. */ -static void -init_frame_same_int(const gmx::SelMethodEvalContext &context, void *data); +static void init_frame_same_int(const gmx::SelMethodEvalContext& context, void* data); /** Evaluates the \p same selection method. */ -static void -evaluate_same_int(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_same_int(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Initializes the evaluation of the \p same selection method for a frame. * @@ -148,27 +143,27 @@ evaluate_same_int(const gmx::SelMethodEvalContext &context, * Sorts the \c data->as.s array and removes identical values for faster and * simpler lookup. */ -static void -init_frame_same_str(const gmx::SelMethodEvalContext &context, void *data); +static void init_frame_same_str(const gmx::SelMethodEvalContext& context, void* data); /** Evaluates the \p same selection method. */ -static void -evaluate_same_str(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_same_str(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Parameters for the \p same selection method. */ static gmx_ana_selparam_t smparams_same_int[] = { - {nullptr, {INT_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_ATOMVAL}, - {"as", {INT_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, + { nullptr, { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_ATOMVAL }, + { "as", { INT_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, }; /** Parameters for the \p same selection method. */ static gmx_ana_selparam_t smparams_same_str[] = { - {nullptr, {STR_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_ATOMVAL}, - {"as", {STR_VALUE, -1, {nullptr}}, nullptr, SPAR_DYNAMIC | SPAR_VARNUM}, + { nullptr, { STR_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_ATOMVAL }, + { "as", { STR_VALUE, -1, { nullptr } }, nullptr, SPAR_DYNAMIC | SPAR_VARNUM }, }; /** Help text for the \p same selection method. */ -static const char *const help_same[] = { +static const char* const help_same[] = { "::", "", " same KEYWORD as ATOM_EXPR", @@ -181,8 +176,11 @@ static const char *const help_same[] = { /*! \internal \brief Selection method data for the \p same method. */ gmx_ana_selmethod_t sm_same = { - "same", GROUP_VALUE, 0, - asize(smparams_same_int), smparams_same_int, + "same", + GROUP_VALUE, + 0, + asize(smparams_same_int), + smparams_same_int, &init_data_same, nullptr, &init_same, @@ -191,8 +189,7 @@ gmx_ana_selmethod_t sm_same = { &init_frame_same_int, &evaluate_same_int, nullptr, - {"same KEYWORD as ATOM_EXPR", - "Extending selections", asize(help_same), help_same}, + { "same KEYWORD as ATOM_EXPR", "Extending selections", asize(help_same), help_same }, }; /*! \brief @@ -203,8 +200,11 @@ gmx_ana_selmethod_t sm_same = { * with this method in cases where it is required. */ static gmx_ana_selmethod_t sm_same_str = { - "same", GROUP_VALUE, SMETH_SINGLEVAL, - asize(smparams_same_str), smparams_same_str, + "same", + GROUP_VALUE, + SMETH_SINGLEVAL, + asize(smparams_same_str), + smparams_same_str, &init_data_same, nullptr, &init_same, @@ -213,13 +213,12 @@ static gmx_ana_selmethod_t sm_same_str = { &init_frame_same_str, &evaluate_same_str, nullptr, - {nullptr, nullptr, 0, nullptr}, + { nullptr, nullptr, 0, nullptr }, }; -static void * -init_data_same(int /* npar */, gmx_ana_selparam_t *param) +static void* init_data_same(int /* npar */, gmx_ana_selparam_t* param) { - t_methoddata_same *data; + t_methoddata_same* data; snew(data, 1); data->as_s_sorted = nullptr; @@ -235,10 +234,9 @@ init_data_same(int /* npar */, gmx_ana_selparam_t *param) * If \p *method is not a \c same method, this function returns * immediately. */ -void -_gmx_selelem_custom_init_same(gmx_ana_selmethod_t **method, - const gmx::SelectionParserParameterListPointer ¶ms, - void *scanner) +void _gmx_selelem_custom_init_same(gmx_ana_selmethod_t** method, + const gmx::SelectionParserParameterListPointer& params, + void* scanner) { /* Do nothing if this is not a same method. */ @@ -247,13 +245,13 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t **me return; } - const gmx::SelectionParserValueList &kwvalues = params->front().values(); + const gmx::SelectionParserValueList& kwvalues = params->front().values(); if (kwvalues.size() != 1 || !kwvalues.front().hasExpressionValue() || kwvalues.front().expr->type != SEL_EXPRESSION) { GMX_THROW(gmx::InvalidInputError("'same' should be followed by a single keyword")); } - gmx_ana_selmethod_t *kwmethod = kwvalues.front().expr->u.expr.method; + gmx_ana_selmethod_t* kwmethod = kwvalues.front().expr->u.expr.method; if (kwmethod->type == STR_VALUE) { *method = &sm_same_str; @@ -263,28 +261,28 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t **me gmx::SelectionParserParameterList::iterator asparam = ++params->begin(); if (asparam != params->end() && asparam->name() == sm_same.param[1].name) { - const gmx::SelectionParserValueList &asvalues = asparam->values(); + const gmx::SelectionParserValueList& asvalues = asparam->values(); if (asvalues.size() != 1 || !asvalues.front().hasExpressionValue()) { // TODO: Think about providing more informative context. - GMX_THROW(gmx::InvalidInputError("'same ... as' should be followed by a single expression")); + GMX_THROW(gmx::InvalidInputError( + "'same ... as' should be followed by a single expression")); } - const gmx::SelectionTreeElementPointer &child = asvalues.front().expr; + const gmx::SelectionTreeElementPointer& child = asvalues.front().expr; /* Create a second keyword evaluation element for the keyword given as * the first parameter, evaluating the keyword in the group given by the * second parameter. */ - gmx::SelectionTreeElementPointer kwelem - = _gmx_sel_init_keyword_evaluator(kwmethod, child, scanner); + gmx::SelectionTreeElementPointer kwelem = + _gmx_sel_init_keyword_evaluator(kwmethod, child, scanner); /* Replace the second parameter with one with a value from \p kwelem. */ std::string pname = asparam->name(); - *asparam = gmx::SelectionParserParameter::createFromExpression(pname, kwelem); + *asparam = gmx::SelectionParserParameter::createFromExpression(pname, kwelem); } } -static void -init_same(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *param, void *data) +static void init_same(const gmx_mtop_t* /* top */, int /* npar */, gmx_ana_selparam_t* param, void* data) { - t_methoddata_same *d = static_cast(data); + t_methoddata_same* d = static_cast(data); d->val.ptr = param[0].val.u.ptr; d->as.ptr = param[1].val.u.ptr; @@ -294,19 +292,18 @@ init_same(const gmx_mtop_t * /* top */, int /* npar */, gmx_ana_selparam_t *para } if (!(param[0].flags & SPAR_ATOMVAL)) { - GMX_THROW(gmx::InvalidInputError( - "The 'same' selection keyword combined with a " - "non-keyword does not make sense")); + GMX_THROW( + gmx::InvalidInputError("The 'same' selection keyword combined with a " + "non-keyword does not make sense")); } } /*! * \param data Data to free (should point to a \ref t_methoddata_same). */ -static void -free_data_same(void *data) +static void free_data_same(void* data) { - t_methoddata_same *d = static_cast(data); + t_methoddata_same* d = static_cast(data); sfree(d->as_s_sorted); sfree(d); @@ -315,8 +312,7 @@ free_data_same(void *data) /*! \brief * Helper function for comparison of two integers. */ -static int -cmp_int(const void *a, const void *b) +static int cmp_int(const void* a, const void* b) { if (*reinterpret_cast(a) < *reinterpret_cast(b)) { @@ -329,10 +325,9 @@ cmp_int(const void *a, const void *b) return 0; } -static void -init_frame_same_int(const gmx::SelMethodEvalContext & /*context*/, void *data) +static void init_frame_same_int(const gmx::SelMethodEvalContext& /*context*/, void* data) { - t_methoddata_same *d = static_cast(data); + t_methoddata_same* d = static_cast(data); int i, j; /* Collapse adjacent values, and check whether the array is sorted. */ @@ -381,15 +376,16 @@ init_frame_same_int(const gmx::SelMethodEvalContext & /*context*/, void *data) * binary search of \c data->as is performed for each block of values in * \c data->val. */ -static void -evaluate_same_int(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_same_int(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_same *d = static_cast(data); - int i, j; + t_methoddata_same* d = static_cast(data); + int i, j; out->u.g->isize = 0; - i = j = 0; + i = j = 0; while (j < g->isize) { if (d->bSorted) @@ -451,22 +447,20 @@ evaluate_same_int(const gmx::SelMethodEvalContext & /*context*/, /*! \brief * Helper function for comparison of two strings. */ -static int -cmp_str(const void *a, const void *b) +static int cmp_str(const void* a, const void* b) { - return strcmp(*static_cast(a), *static_cast(b)); + return strcmp(*static_cast(a), *static_cast(b)); } -static void -init_frame_same_str(const gmx::SelMethodEvalContext & /*context*/, void *data) +static void init_frame_same_str(const gmx::SelMethodEvalContext& /*context*/, void* data) { - t_methoddata_same *d = static_cast(data); + t_methoddata_same* d = static_cast(data); int i, j; /* Collapse adjacent values. * For strings, it's unlikely that the values would be sorted originally, * so set bSorted always to false. */ - d->bSorted = false; + d->bSorted = false; if (d->nas == 0) { return; @@ -504,26 +498,26 @@ init_frame_same_str(const gmx::SelMethodEvalContext & /*context*/, void *data) * A binary search of \c data->as is performed for each block of values in * \c data->val. */ -static void -evaluate_same_str(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data) +static void evaluate_same_str(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data) { - t_methoddata_same *d = static_cast(data); - int j; + t_methoddata_same* d = static_cast(data); + int j; out->u.g->isize = 0; j = 0; while (j < g->isize) { /* Do a binary search of the strings. */ - void *ptr; - ptr = bsearch(&d->val.s[j], d->as_s_sorted, d->nas, - sizeof(d->as_s_sorted[0]), &cmp_str); + void* ptr; + ptr = bsearch(&d->val.s[j], d->as_s_sorted, d->nas, sizeof(d->as_s_sorted[0]), &cmp_str); /* Check whether the value was found in the as list. */ if (ptr == nullptr) { /* If not, skip all atoms with the same value. */ - const char *tmpval = d->val.s[j]; + const char* tmpval = d->val.s[j]; ++j; while (j < g->isize && strcmp(d->val.s[j], tmpval) == 0) { @@ -532,7 +526,7 @@ evaluate_same_str(const gmx::SelMethodEvalContext & /*context*/, } else { - const char *tmpval = d->val.s[j]; + const char* tmpval = d->val.s[j]; /* Copy all the atoms with this value to the output. */ while (j < g->isize && strcmp(d->val.s[j], tmpval) == 0) { diff --git a/src/gromacs/selection/sm_simple.cpp b/src/gromacs/selection/sm_simple.cpp index c66fe166b9..f5ec185c29 100644 --- a/src/gromacs/selection/sm_simple.cpp +++ b/src/gromacs/selection/sm_simple.cpp @@ -54,25 +54,30 @@ #include "selmethod_impl.h" /** Evaluates the \p all selection keyword. */ -static void -evaluate_all(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_all(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p none selection keyword. */ -static void -evaluate_none(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_none(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p atomnr selection keyword. */ -static void -evaluate_atomnr(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_atomnr(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p resnr selection keyword. */ -static void -evaluate_resnr(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_resnr(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p resindex selection keyword. */ -static void -evaluate_resindex(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_resindex(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Checks whether molecule information is present in the topology. * @@ -84,20 +89,22 @@ evaluate_resindex(const gmx::SelMethodEvalContext &context, * * If molecule information is not found, also prints an error message. */ -static void -check_molecules(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void check_molecules(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Evaluates the \p molindex selection keyword. */ -static void -evaluate_molindex(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_molindex(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p atomname selection keyword. */ -static void -evaluate_atomname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_atomname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p pdbatomname selection keyword. */ -static void -evaluate_pdbatomname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_pdbatomname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Checks whether atom types are present in the topology. * @@ -106,24 +113,27 @@ evaluate_pdbatomname(const gmx::SelMethodEvalContext &context, * \param param Not used. * \param data Not used. */ -static void -check_atomtype(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void check_atomtype(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Evaluates the \p atomtype selection keyword. */ -static void -evaluate_atomtype(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_atomtype(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p insertcode selection keyword. */ -static void -evaluate_insertcode(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_insertcode(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p chain selection keyword. */ -static void -evaluate_chain(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_chain(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p mass selection keyword. */ -static void -evaluate_mass(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_mass(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Checks whether charges are present in the topology. * @@ -132,12 +142,12 @@ evaluate_mass(const gmx::SelMethodEvalContext &context, * \param param Not used. * \param data Not used. */ -static void -check_charge(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void check_charge(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Evaluates the \p charge selection keyword. */ -static void -evaluate_charge(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_charge(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /*! \brief * Checks whether PDB info is present in the topology. * @@ -149,42 +159,48 @@ evaluate_charge(const gmx::SelMethodEvalContext &context, * * If PDB info is not found, also prints an error message. */ -static void -check_pdbinfo(const gmx_mtop_t *top, int npar, gmx_ana_selparam_t *param, void *data); +static void check_pdbinfo(const gmx_mtop_t* top, int npar, gmx_ana_selparam_t* param, void* data); /** Evaluates the \p altloc selection keyword. */ -static void -evaluate_altloc(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_altloc(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p occupancy selection keyword. */ -static void -evaluate_occupancy(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_occupancy(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p betafactor selection keyword. */ -static void -evaluate_betafactor(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_betafactor(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p resname selection keyword. */ -static void -evaluate_resname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void *data); +static void evaluate_resname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p x selection keyword. */ -static void -evaluate_x(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_x(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p y selection keyword. */ -static void -evaluate_y(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_y(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); /** Evaluates the \p z selection keyword. */ -static void -evaluate_z(const gmx::SelMethodEvalContext &context, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); +static void evaluate_z(const gmx::SelMethodEvalContext& context, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* data); //! Help title for atom name selection keywords. -static const char helptitle_atomname[] = "Selecting atoms by name"; +static const char helptitle_atomname[] = "Selecting atoms by name"; //! Help text for atom name selection keywords. -static const char *const help_atomname[] = { +static const char* const help_atomname[] = { "::", "", " name", @@ -207,9 +223,9 @@ static const char *const help_atomname[] = { }; //! Help title for residue index selection keywords. -static const char helptitle_resindex[] = "Selecting atoms by residue number"; +static const char helptitle_resindex[] = "Selecting atoms by residue number"; //! Help text for residue index selection keywords. -static const char *const help_resindex[] = { +static const char* const help_resindex[] = { "::", "", " resnr", @@ -230,152 +246,93 @@ static const char *const help_resindex[] = { /** Selection method data for \p all selection keyword. */ gmx_ana_selmethod_t sm_all = { - "all", GROUP_VALUE, 0, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_all, - nullptr, + "all", GROUP_VALUE, 0, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, &evaluate_all, nullptr, }; /** Selection method data for \p none selection keyword. */ gmx_ana_selmethod_t sm_none = { - "none", GROUP_VALUE, 0, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_none, - nullptr, + "none", GROUP_VALUE, 0, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, &evaluate_none, nullptr, }; /** Selection method data for \p atomnr selection keyword. */ gmx_ana_selmethod_t sm_atomnr = { - "atomnr", INT_VALUE, 0, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_atomnr, - nullptr, + "atomnr", INT_VALUE, 0, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, &evaluate_atomnr, nullptr, }; /** Selection method data for \p resnr selection keyword. */ gmx_ana_selmethod_t sm_resnr = { - "resnr", INT_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_resnr, - nullptr, - {nullptr, helptitle_resindex, asize(help_resindex), help_resindex} + "resnr", INT_VALUE, + SMETH_REQTOP, 0, + nullptr, nullptr, + nullptr, nullptr, + nullptr, nullptr, + nullptr, &evaluate_resnr, + nullptr, { nullptr, helptitle_resindex, asize(help_resindex), help_resindex } }; /** Selection method data for \p resindex selection keyword. */ gmx_ana_selmethod_t sm_resindex = { - "resindex", INT_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_resindex, - nullptr, - {nullptr, helptitle_resindex, asize(help_resindex), help_resindex} + "resindex", INT_VALUE, + SMETH_REQTOP, 0, + nullptr, nullptr, + nullptr, nullptr, + nullptr, nullptr, + nullptr, &evaluate_resindex, + nullptr, { nullptr, helptitle_resindex, asize(help_resindex), help_resindex } }; /** Selection method data for \p molindex selection keyword. */ gmx_ana_selmethod_t sm_molindex = { - "molindex", INT_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_molecules, - nullptr, - nullptr, - nullptr, - &evaluate_molindex, + "molindex", INT_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, + nullptr, &check_molecules, nullptr, nullptr, nullptr, &evaluate_molindex, nullptr, }; /** Selection method data for \p atomname selection keyword. */ gmx_ana_selmethod_t sm_atomname = { - "atomname", STR_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_atomname, - nullptr, - {nullptr, helptitle_atomname, asize(help_atomname), help_atomname} + "atomname", STR_VALUE, + SMETH_REQTOP, 0, + nullptr, nullptr, + nullptr, nullptr, + nullptr, nullptr, + nullptr, &evaluate_atomname, + nullptr, { nullptr, helptitle_atomname, asize(help_atomname), help_atomname } }; /** Selection method data for \p pdbatomname selection keyword. */ gmx_ana_selmethod_t sm_pdbatomname = { - "pdbatomname", STR_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_pdbinfo, - nullptr, - nullptr, - nullptr, - &evaluate_pdbatomname, - nullptr, - {nullptr, helptitle_atomname, asize(help_atomname), help_atomname} + "pdbatomname", STR_VALUE, + SMETH_REQTOP, 0, + nullptr, nullptr, + nullptr, &check_pdbinfo, + nullptr, nullptr, + nullptr, &evaluate_pdbatomname, + nullptr, { nullptr, helptitle_atomname, asize(help_atomname), help_atomname } }; /** Selection method data for \p atomtype selection keyword. */ gmx_ana_selmethod_t sm_atomtype = { - "atomtype", STR_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_atomtype, - nullptr, - nullptr, - nullptr, - &evaluate_atomtype, + "atomtype", STR_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, + nullptr, &check_atomtype, nullptr, nullptr, nullptr, &evaluate_atomtype, nullptr, }; /** Selection method data for \p resname selection keyword. */ gmx_ana_selmethod_t sm_resname = { - "resname", STR_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_resname, - nullptr, + "resname", STR_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, &evaluate_resname, nullptr, }; /** Selection method data for \p chain selection keyword. */ gmx_ana_selmethod_t sm_insertcode = { - "insertcode", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL, - 0, nullptr, + "insertcode", + STR_VALUE, + SMETH_REQTOP | SMETH_CHARVAL, + 0, + nullptr, nullptr, nullptr, nullptr, @@ -389,127 +346,63 @@ gmx_ana_selmethod_t sm_insertcode = { /** Selection method data for \p chain selection keyword. */ gmx_ana_selmethod_t sm_chain = { "chain", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_chain, + 0, nullptr, nullptr, + nullptr, nullptr, nullptr, + nullptr, nullptr, &evaluate_chain, nullptr, }; /** Selection method data for \p mass selection keyword. */ gmx_ana_selmethod_t sm_mass = { - "mass", REAL_VALUE, SMETH_REQMASS, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_mass, - nullptr, + "mass", REAL_VALUE, SMETH_REQMASS, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, &evaluate_mass, nullptr, }; /** Selection method data for \p charge selection keyword. */ gmx_ana_selmethod_t sm_charge = { - "charge", REAL_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_charge, - nullptr, - nullptr, - nullptr, - &evaluate_charge, - nullptr, + "charge", REAL_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, nullptr, + &check_charge, nullptr, nullptr, nullptr, &evaluate_charge, nullptr, }; /** Selection method data for \p chain selection keyword. */ gmx_ana_selmethod_t sm_altloc = { - "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL, - 0, nullptr, - nullptr, - nullptr, - &check_pdbinfo, - nullptr, - nullptr, - nullptr, - &evaluate_altloc, + "altloc", STR_VALUE, SMETH_REQTOP | SMETH_CHARVAL, + 0, nullptr, nullptr, + nullptr, &check_pdbinfo, nullptr, + nullptr, nullptr, &evaluate_altloc, nullptr, }; /** Selection method data for \p occupancy selection keyword. */ gmx_ana_selmethod_t sm_occupancy = { - "occupancy", REAL_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_pdbinfo, - nullptr, - nullptr, - nullptr, - &evaluate_occupancy, + "occupancy", REAL_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, + nullptr, &check_pdbinfo, nullptr, nullptr, nullptr, &evaluate_occupancy, nullptr, }; /** Selection method data for \p betafactor selection keyword. */ gmx_ana_selmethod_t sm_betafactor = { - "betafactor", REAL_VALUE, SMETH_REQTOP, - 0, nullptr, - nullptr, - nullptr, - &check_pdbinfo, - nullptr, - nullptr, - nullptr, - &evaluate_betafactor, + "betafactor", REAL_VALUE, SMETH_REQTOP, 0, nullptr, nullptr, + nullptr, &check_pdbinfo, nullptr, nullptr, nullptr, &evaluate_betafactor, nullptr, }; /** Selection method data for \p x selection keyword. */ gmx_ana_selmethod_t sm_x = { - "x", REAL_VALUE, SMETH_DYNAMIC, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_x, + "x", REAL_VALUE, SMETH_DYNAMIC, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, &evaluate_x, }; /** Selection method data for \p y selection keyword. */ gmx_ana_selmethod_t sm_y = { - "y", REAL_VALUE, SMETH_DYNAMIC, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_y, + "y", REAL_VALUE, SMETH_DYNAMIC, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, &evaluate_y, }; /** Selection method data for \p z selection keyword. */ gmx_ana_selmethod_t sm_z = { - "z", REAL_VALUE, SMETH_DYNAMIC, - 0, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - &evaluate_z, + "z", REAL_VALUE, SMETH_DYNAMIC, 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, &evaluate_z, }; /*! @@ -518,9 +411,10 @@ gmx_ana_selmethod_t sm_z = { * * Copies \p g to \p out->u.g. */ -static void -evaluate_all(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_all(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { gmx_ana_index_copy(out->u.g, g, false); } @@ -531,9 +425,10 @@ evaluate_all(const gmx::SelMethodEvalContext & /*context*/, * * Returns an empty \p out->u.g. */ -static void -evaluate_none(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t * /* g */, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_none(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* /* g */, + gmx_ana_selvalue_t* out, + void* /* data */) { out->u.g->isize = 0; } @@ -544,11 +439,12 @@ evaluate_none(const gmx::SelMethodEvalContext & /*context*/, * * Returns the indices for each atom in \p out->u.i. */ -static void -evaluate_atomnr(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_atomnr(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - int i; + int i; out->nr = g->isize; for (i = 0; i < g->isize; ++i) @@ -563,16 +459,16 @@ evaluate_atomnr(const gmx::SelMethodEvalContext & /*context*/, * * Returns the residue numbers for each atom in \p out->u.i. */ -static void -evaluate_resnr(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_resnr(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { - mtopGetAtomAndResidueName(context.top, g->index[i], &molb, - nullptr, &out->u.i[i], nullptr, nullptr); + mtopGetAtomAndResidueName(context.top, g->index[i], &molb, nullptr, &out->u.i[i], nullptr, nullptr); } } @@ -582,23 +478,22 @@ evaluate_resnr(const gmx::SelMethodEvalContext &context, * * Returns the residue indices for each atom in \p out->u.i. */ -static void -evaluate_resindex(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_resindex(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { int resind; - mtopGetAtomAndResidueName(context.top, g->index[i], &molb, - nullptr, nullptr, nullptr, &resind); + mtopGetAtomAndResidueName(context.top, g->index[i], &molb, nullptr, nullptr, nullptr, &resind); out->u.i[i] = resind + 1; } } -static void -check_molecules(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */) +static void check_molecules(const gmx_mtop_t* top, int /* npar */, gmx_ana_selparam_t* /* param */, void* /* data */) { bool bOk; @@ -615,9 +510,10 @@ check_molecules(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* p * * Returns the molecule indices for each atom in \p out->u.i. */ -static void -evaluate_molindex(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_molindex(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { out->nr = g->isize; int molb = 0; @@ -633,18 +529,18 @@ evaluate_molindex(const gmx::SelMethodEvalContext &context, * * Returns the atom name for each atom in \p out->u.s. */ -static void -evaluate_atomname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_atomname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { - const char *atom_name; - mtopGetAtomAndResidueName(context.top, g->index[i], &molb, - &atom_name, nullptr, nullptr, nullptr); - out->u.s[i] = const_cast(atom_name); + const char* atom_name; + mtopGetAtomAndResidueName(context.top, g->index[i], &molb, &atom_name, nullptr, nullptr, nullptr); + out->u.s[i] = const_cast(atom_name); } } @@ -654,25 +550,25 @@ evaluate_atomname(const gmx::SelMethodEvalContext &context, * * Returns the PDB atom name for each atom in \p out->u.s. */ -static void -evaluate_pdbatomname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_pdbatomname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { - const char *s = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).atomnm; + const char* s = mtopGetAtomPdbInfo(context.top, g->index[i], &molb).atomnm; while (std::isspace(*s)) { ++s; } - out->u.s[i] = const_cast(s); + out->u.s[i] = const_cast(s); } } -static void -check_atomtype(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */) +static void check_atomtype(const gmx_mtop_t* top, int /* npar */, gmx_ana_selparam_t* /* param */, void* /* data */) { if (!gmx_mtop_has_atomtypes(top)) { @@ -687,19 +583,19 @@ check_atomtype(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* pa * Returns the atom type for each atom in \p out->u.s. * Segfaults if atom types are not found in the topology. */ -static void -evaluate_atomtype(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_atomtype(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { int atomIndexInMolecule; - mtopGetMolblockIndex(context.top, g->index[i], &molb, - nullptr, &atomIndexInMolecule); - const gmx_moltype_t &moltype = context.top->moltype[context.top->molblock[molb].type]; - out->u.s[i] = *moltype.atoms.atomtype[atomIndexInMolecule]; + mtopGetMolblockIndex(context.top, g->index[i], &molb, nullptr, &atomIndexInMolecule); + const gmx_moltype_t& moltype = context.top->moltype[context.top->molblock[molb].type]; + out->u.s[i] = *moltype.atoms.atomtype[atomIndexInMolecule]; } } @@ -709,11 +605,12 @@ evaluate_atomtype(const gmx::SelMethodEvalContext &context, * * Returns the residue name for each atom in \p out->u.s. */ -static void -evaluate_resname(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_resname(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -727,11 +624,12 @@ evaluate_resname(const gmx::SelMethodEvalContext &context, * * Returns the insertion code for each atom in \p out->u.s. */ -static void -evaluate_insertcode(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_insertcode(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -745,11 +643,12 @@ evaluate_insertcode(const gmx::SelMethodEvalContext &context, * * Returns the chain for each atom in \p out->u.s. */ -static void -evaluate_chain(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_chain(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -763,13 +662,13 @@ evaluate_chain(const gmx::SelMethodEvalContext &context, * * Returns the mass for each atom in \p out->u.r. */ -static void -evaluate_mass(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_mass(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - GMX_RELEASE_ASSERT(gmx_mtop_has_masses(context.top), - "Masses not available for evaluation"); - out->nr = g->isize; + GMX_RELEASE_ASSERT(gmx_mtop_has_masses(context.top), "Masses not available for evaluation"); + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -778,8 +677,7 @@ evaluate_mass(const gmx::SelMethodEvalContext &context, } -static void -check_charge(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */) +static void check_charge(const gmx_mtop_t* top, int /* npar */, gmx_ana_selparam_t* /* param */, void* /* data */) { if (!gmx_mtop_has_charges(top)) { @@ -793,11 +691,12 @@ check_charge(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* para * * Returns the charge for each atom in \p out->u.r. */ -static void -evaluate_charge(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_charge(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -805,8 +704,7 @@ evaluate_charge(const gmx::SelMethodEvalContext &context, } } -static void -check_pdbinfo(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* param */, void * /* data */) +static void check_pdbinfo(const gmx_mtop_t* top, int /* npar */, gmx_ana_selparam_t* /* param */, void* /* data */) { if (!gmx_mtop_has_pdbinfo(top)) { @@ -820,11 +718,12 @@ check_pdbinfo(const gmx_mtop_t *top, int /* npar */, gmx_ana_selparam_t * /* par * * Returns the alternate location identifier for each atom in \p out->u.s. */ -static void -evaluate_altloc(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_altloc(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -839,11 +738,12 @@ evaluate_altloc(const gmx::SelMethodEvalContext &context, * Returns the occupancy numbers for each atom in \p out->u.r. * Segfaults if PDB info is not found in the topology. */ -static void -evaluate_occupancy(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_occupancy(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -858,11 +758,12 @@ evaluate_occupancy(const gmx::SelMethodEvalContext &context, * Returns the B-factors for each atom in \p out->u.r. * Segfaults if PDB info is not found in the topology. */ -static void -evaluate_betafactor(const gmx::SelMethodEvalContext &context, - gmx_ana_index_t *g, gmx_ana_selvalue_t *out, void * /* data */) +static void evaluate_betafactor(const gmx::SelMethodEvalContext& context, + gmx_ana_index_t* g, + gmx_ana_selvalue_t* out, + void* /* data */) { - out->nr = g->isize; + out->nr = g->isize; int molb = 0; for (int i = 0; i < g->isize; ++i) { @@ -880,8 +781,7 @@ evaluate_betafactor(const gmx::SelMethodEvalContext &context, * This function is used internally by evaluate_x(), evaluate_y() and * evaluate_z() to do the actual evaluation. */ -static void -evaluate_coord(real out[], gmx_ana_pos_t *pos, int d) +static void evaluate_coord(real out[], gmx_ana_pos_t* pos, int d) { for (int i = 0; i < pos->count(); ++i) { @@ -898,9 +798,10 @@ evaluate_coord(real out[], gmx_ana_pos_t *pos, int d) * * Returns the \p x coordinate for each position in \p out->u.r. */ -static void -evaluate_x(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/) +static void evaluate_x(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* /*data*/) { out->nr = pos->count(); evaluate_coord(out->u.r, pos, XX); @@ -912,9 +813,10 @@ evaluate_x(const gmx::SelMethodEvalContext & /*context*/, * * Returns the \p y coordinate for each position in \p out->u.r. */ -static void -evaluate_y(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/) +static void evaluate_y(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* /*data*/) { out->nr = pos->count(); evaluate_coord(out->u.r, pos, YY); @@ -926,9 +828,10 @@ evaluate_y(const gmx::SelMethodEvalContext & /*context*/, * * Returns the \p z coordinate for each position in \p out->u.r. */ -static void -evaluate_z(const gmx::SelMethodEvalContext & /*context*/, - gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void * /*data*/) +static void evaluate_z(const gmx::SelMethodEvalContext& /*context*/, + gmx_ana_pos_t* pos, + gmx_ana_selvalue_t* out, + void* /*data*/) { out->nr = pos->count(); evaluate_coord(out->u.r, pos, ZZ); diff --git a/src/gromacs/selection/symrec.cpp b/src/gromacs/selection/symrec.cpp index 0d4e5b48dc..b435dda6b7 100644 --- a/src/gromacs/selection/symrec.cpp +++ b/src/gromacs/selection/symrec.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,62 +71,50 @@ namespace gmx */ class SelectionParserSymbol::Impl { - public: - /*! \brief - * Initializes a symbol. - * - * \param[in] type Type for the symbol. - * \param[in] name Name for the symbol. - * - * The symbol table is responsible for initializing the \a meth_ and - * \a var_ members as appropriate. - */ - Impl(SymbolType type, const char *name) - : name_(name), type_(type), meth_(nullptr) - { - } - - //! Name of the symbol. - std::string name_; - //! Type of the symbol. - SymbolType type_; - //! Pointer to the method structure (\ref MethodSymbol). - gmx_ana_selmethod_t *meth_; - //! Pointer to the variable value (\ref VariableSymbol). - SelectionTreeElementPointer var_; +public: + /*! \brief + * Initializes a symbol. + * + * \param[in] type Type for the symbol. + * \param[in] name Name for the symbol. + * + * The symbol table is responsible for initializing the \a meth_ and + * \a var_ members as appropriate. + */ + Impl(SymbolType type, const char* name) : name_(name), type_(type), meth_(nullptr) {} + + //! Name of the symbol. + std::string name_; + //! Type of the symbol. + SymbolType type_; + //! Pointer to the method structure (\ref MethodSymbol). + gmx_ana_selmethod_t* meth_; + //! Pointer to the variable value (\ref VariableSymbol). + SelectionTreeElementPointer var_; }; -SelectionParserSymbol::SelectionParserSymbol(Impl *impl) - : impl_(impl) -{ -} +SelectionParserSymbol::SelectionParserSymbol(Impl* impl) : impl_(impl) {} -SelectionParserSymbol::~SelectionParserSymbol() -{ -} +SelectionParserSymbol::~SelectionParserSymbol() {} -const std::string & -SelectionParserSymbol::name() const +const std::string& SelectionParserSymbol::name() const { return impl_->name_; } -SelectionParserSymbol::SymbolType -SelectionParserSymbol::type() const +SelectionParserSymbol::SymbolType SelectionParserSymbol::type() const { return impl_->type_; } -gmx_ana_selmethod_t * -SelectionParserSymbol::methodValue() const +gmx_ana_selmethod_t* SelectionParserSymbol::methodValue() const { GMX_RELEASE_ASSERT(type() == MethodSymbol, "Attempting to get method handle for a non-method symbol"); return impl_->meth_; } -const gmx::SelectionTreeElementPointer & -SelectionParserSymbol::variableValue() const +const gmx::SelectionTreeElementPointer& SelectionParserSymbol::variableValue() const { GMX_RELEASE_ASSERT(type() == VariableSymbol, "Attempting to get variable value for a non-variable symbol"); @@ -146,69 +135,52 @@ SelectionParserSymbol::variableValue() const */ class SelectionParserSymbolTable::Impl { - public: - //! Smart pointer type for managing a SelectionParserSymbol. - typedef std::unique_ptr - SymbolPointer; - //! Container type for the list of symbols. - typedef std::map SymbolMap; - - /*! \brief - * Adds a symbol to the symbol list. - * - * \param[in] symbol Symbol to add. - */ - void addSymbol(SymbolPointer symbol); - //! Adds the reserved symbols to this symbol table. - void addReservedSymbols(); - //! Adds the position symbols to this symbol table. - void addPositionSymbols(); - - //! Symbols in this symbol table. - SymbolMap symbols_; +public: + //! Smart pointer type for managing a SelectionParserSymbol. + typedef std::unique_ptr SymbolPointer; + //! Container type for the list of symbols. + typedef std::map SymbolMap; + + /*! \brief + * Adds a symbol to the symbol list. + * + * \param[in] symbol Symbol to add. + */ + void addSymbol(SymbolPointer symbol); + //! Adds the reserved symbols to this symbol table. + void addReservedSymbols(); + //! Adds the position symbols to this symbol table. + void addPositionSymbols(); + + //! Symbols in this symbol table. + SymbolMap symbols_; }; -void -SelectionParserSymbolTable::Impl::addSymbol(SymbolPointer symbol) +void SelectionParserSymbolTable::Impl::addSymbol(SymbolPointer symbol) { symbols_.insert(std::make_pair(symbol->name(), std::move(symbol))); } -void -SelectionParserSymbolTable::Impl::addReservedSymbols() +void SelectionParserSymbolTable::Impl::addReservedSymbols() { - const char *const sym_reserved[] = { - "group", - "to", - "not", - "and", - "or", - "xor", - "yes", - "no", - "on", - "off" - }; + const char* const sym_reserved[] = { "group", "to", "not", "and", "or", + "xor", "yes", "no", "on", "off" }; for (int i = 0; i < asize(sym_reserved); ++i) { - SymbolPointer sym(new SelectionParserSymbol( - new SelectionParserSymbol::Impl( - SelectionParserSymbol::ReservedSymbol, sym_reserved[i]))); + SymbolPointer sym(new SelectionParserSymbol(new SelectionParserSymbol::Impl( + SelectionParserSymbol::ReservedSymbol, sym_reserved[i]))); addSymbol(std::move(sym)); } } -void -SelectionParserSymbolTable::Impl::addPositionSymbols() +void SelectionParserSymbolTable::Impl::addPositionSymbols() { - const char *const *postypes - = gmx::PositionCalculationCollection::typeEnumValues; + const char* const* postypes = gmx::PositionCalculationCollection::typeEnumValues; for (int i = 0; postypes[i] != nullptr; ++i) { - SymbolPointer sym(new SelectionParserSymbol( - new SelectionParserSymbol::Impl( - SelectionParserSymbol::PositionSymbol, postypes[i]))); + SymbolPointer sym(new SelectionParserSymbol(new SelectionParserSymbol::Impl( + SelectionParserSymbol::PositionSymbol, postypes[i]))); addSymbol(std::move(sym)); } } @@ -224,78 +196,62 @@ SelectionParserSymbolTable::Impl::addPositionSymbols() */ class SelectionParserSymbolIterator::Impl { - public: - //! Shorthand for the underlying iterator type. - typedef SelectionParserSymbolTable::Impl::SymbolMap::const_iterator - IteratorType; - - /*! \brief - * Constructs an end iterator. - * - * \param[in] end Iterator to the end of the iterated container. - */ - explicit Impl(IteratorType end) - : iter_(end), end_(end) - { - } - /*! \brief - * Constructs an iterator. - * - * \param[in] iter Iterator to the current symbol. - * \param[in] end Iterator to the end of the iterated container. - */ - Impl(IteratorType iter, IteratorType end) - : iter_(iter), end_(end) - { - } - - //! Underlying iterator to the symbol container. - IteratorType iter_; - //! End of the symbol container being iterated. - IteratorType end_; +public: + //! Shorthand for the underlying iterator type. + typedef SelectionParserSymbolTable::Impl::SymbolMap::const_iterator IteratorType; + + /*! \brief + * Constructs an end iterator. + * + * \param[in] end Iterator to the end of the iterated container. + */ + explicit Impl(IteratorType end) : iter_(end), end_(end) {} + /*! \brief + * Constructs an iterator. + * + * \param[in] iter Iterator to the current symbol. + * \param[in] end Iterator to the end of the iterated container. + */ + Impl(IteratorType iter, IteratorType end) : iter_(iter), end_(end) {} + + //! Underlying iterator to the symbol container. + IteratorType iter_; + //! End of the symbol container being iterated. + IteratorType end_; }; -SelectionParserSymbolIterator::SelectionParserSymbolIterator(Impl *impl) - : impl_(impl) -{ -} +SelectionParserSymbolIterator::SelectionParserSymbolIterator(Impl* impl) : impl_(impl) {} -SelectionParserSymbolIterator::SelectionParserSymbolIterator( - const SelectionParserSymbolIterator &other) - : impl_(new Impl(*other.impl_)) +SelectionParserSymbolIterator::SelectionParserSymbolIterator(const SelectionParserSymbolIterator& other) : + impl_(new Impl(*other.impl_)) { } -SelectionParserSymbolIterator::~SelectionParserSymbolIterator() -{ -} +SelectionParserSymbolIterator::~SelectionParserSymbolIterator() {} -SelectionParserSymbolIterator &SelectionParserSymbolIterator::operator=( - const SelectionParserSymbolIterator &other) +SelectionParserSymbolIterator& SelectionParserSymbolIterator::operator=(const SelectionParserSymbolIterator& other) { impl_.reset(new Impl(*other.impl_)); return *this; } -bool SelectionParserSymbolIterator::operator==( - const SelectionParserSymbolIterator &other) const +bool SelectionParserSymbolIterator::operator==(const SelectionParserSymbolIterator& other) const { return impl_->iter_ == other.impl_->iter_; } -const SelectionParserSymbol &SelectionParserSymbolIterator::operator*() const +const SelectionParserSymbol& SelectionParserSymbolIterator::operator*() const { return *impl_->iter_->second; } -SelectionParserSymbolIterator &SelectionParserSymbolIterator::operator++() +SelectionParserSymbolIterator& SelectionParserSymbolIterator::operator++() { SelectionParserSymbol::SymbolType type = impl_->iter_->second->type(); do { ++impl_->iter_; - } - while (impl_->iter_ != impl_->end_ && impl_->iter_->second->type() != type); + } while (impl_->iter_ != impl_->end_ && impl_->iter_->second->type() != type); return *this; } @@ -303,19 +259,15 @@ SelectionParserSymbolIterator &SelectionParserSymbolIterator::operator++() * SelectionParserSymbolTable */ -SelectionParserSymbolTable::SelectionParserSymbolTable() - : impl_(new Impl) +SelectionParserSymbolTable::SelectionParserSymbolTable() : impl_(new Impl) { impl_->addReservedSymbols(); impl_->addPositionSymbols(); } -SelectionParserSymbolTable::~SelectionParserSymbolTable() -{ -} +SelectionParserSymbolTable::~SelectionParserSymbolTable() {} -const SelectionParserSymbol * -SelectionParserSymbolTable::findSymbol(const std::string &name) const +const SelectionParserSymbol* SelectionParserSymbolTable::findSymbol(const std::string& name) const { Impl::SymbolMap::const_iterator sym = impl_->symbols_.lower_bound(name); if (sym == impl_->symbols_.end()) @@ -329,8 +281,7 @@ SelectionParserSymbolTable::findSymbol(const std::string &name) const return nullptr; } -SelectionParserSymbolIterator -SelectionParserSymbolTable::beginIterator(SelectionParserSymbol::SymbolType type) const +SelectionParserSymbolIterator SelectionParserSymbolTable::beginIterator(SelectionParserSymbol::SymbolType type) const { Impl::SymbolMap::const_iterator sym; Impl::SymbolMap::const_iterator end = impl_->symbols_.end(); @@ -338,23 +289,18 @@ SelectionParserSymbolTable::beginIterator(SelectionParserSymbol::SymbolType type { if (sym->second->type() == type) { - return SelectionParserSymbolIterator( - new SelectionParserSymbolIterator::Impl(sym, end)); + return SelectionParserSymbolIterator(new SelectionParserSymbolIterator::Impl(sym, end)); } } return endIterator(); } -SelectionParserSymbolIterator -SelectionParserSymbolTable::endIterator() const +SelectionParserSymbolIterator SelectionParserSymbolTable::endIterator() const { - return SelectionParserSymbolIterator( - new SelectionParserSymbolIterator::Impl(impl_->symbols_.end())); + return SelectionParserSymbolIterator(new SelectionParserSymbolIterator::Impl(impl_->symbols_.end())); } -void -SelectionParserSymbolTable::addVariable(const char *name, - const gmx::SelectionTreeElementPointer &sel) +void SelectionParserSymbolTable::addVariable(const char* name, const gmx::SelectionTreeElementPointer& sel) { // In the current parser implementation, a syntax error is produced before // this point is reached, but the check is here for robustness. @@ -363,37 +309,28 @@ SelectionParserSymbolTable::addVariable(const char * { if (other->second->type() == SelectionParserSymbol::VariableSymbol) { - GMX_THROW(InvalidInputError( - formatString("Reassigning variable '%s' is not supported", - name))); + GMX_THROW(InvalidInputError(formatString("Reassigning variable '%s' is not supported", name))); } else { GMX_THROW(InvalidInputError( - formatString("Variable name '%s' conflicts with a reserved keyword", - name))); + formatString("Variable name '%s' conflicts with a reserved keyword", name))); } } Impl::SymbolPointer sym(new SelectionParserSymbol( - new SelectionParserSymbol::Impl( - SelectionParserSymbol::VariableSymbol, name))); + new SelectionParserSymbol::Impl(SelectionParserSymbol::VariableSymbol, name))); sym->impl_->var_ = sel; impl_->addSymbol(std::move(sym)); } -void -SelectionParserSymbolTable::addMethod(const char *name, - gmx_ana_selmethod_t *method) +void SelectionParserSymbolTable::addMethod(const char* name, gmx_ana_selmethod_t* method) { if (impl_->symbols_.find(name) != impl_->symbols_.end()) { - GMX_THROW(APIError( - formatString("Method name '%s' conflicts with another symbol", - name))); + GMX_THROW(APIError(formatString("Method name '%s' conflicts with another symbol", name))); } Impl::SymbolPointer sym(new SelectionParserSymbol( - new SelectionParserSymbol::Impl( - SelectionParserSymbol::MethodSymbol, name))); + new SelectionParserSymbol::Impl(SelectionParserSymbol::MethodSymbol, name))); sym->impl_->meth_ = method; impl_->addSymbol(std::move(sym)); } diff --git a/src/gromacs/selection/symrec.h b/src/gromacs/selection/symrec.h index ed416cf92e..41cf89becb 100644 --- a/src/gromacs/selection/symrec.h +++ b/src/gromacs/selection/symrec.h @@ -68,59 +68,59 @@ class SelectionParserSymbolTable; */ class SelectionParserSymbol { - public: - //! Defines the type of the symbol. - enum SymbolType - { - ReservedSymbol, //!< The symbol is a reserved keyword. - VariableSymbol, //!< The symbol is a variable. - MethodSymbol, //!< The symbol is a selection method. - PositionSymbol //!< The symbol is a position keyword. - }; +public: + //! Defines the type of the symbol. + enum SymbolType + { + ReservedSymbol, //!< The symbol is a reserved keyword. + VariableSymbol, //!< The symbol is a variable. + MethodSymbol, //!< The symbol is a selection method. + PositionSymbol //!< The symbol is a position keyword. + }; - ~SelectionParserSymbol(); + ~SelectionParserSymbol(); - //! Returns the name of the symbol. - const std::string &name() const; - //! Returns the type of the symbol. - SymbolType type() const; + //! Returns the name of the symbol. + const std::string& name() const; + //! Returns the type of the symbol. + SymbolType type() const; - /*! \brief - * Returns the method associated with a \ref MethodSymbol symbol. - * - * \returns The method associated with the symbol. - * - * Must only be called if type() returns \ref MethodSymbol. - */ - gmx_ana_selmethod_t *methodValue() const; - /*! \brief - * Returns the selection tree associated with a \ref VariableSymbol symbol. - * - * \returns The variable expression associated with the symbol. - * - * Must only be called if type() returns \ref VariableSymbol. - */ - const SelectionTreeElementPointer &variableValue() const; + /*! \brief + * Returns the method associated with a \ref MethodSymbol symbol. + * + * \returns The method associated with the symbol. + * + * Must only be called if type() returns \ref MethodSymbol. + */ + gmx_ana_selmethod_t* methodValue() const; + /*! \brief + * Returns the selection tree associated with a \ref VariableSymbol symbol. + * + * \returns The variable expression associated with the symbol. + * + * Must only be called if type() returns \ref VariableSymbol. + */ + const SelectionTreeElementPointer& variableValue() const; - private: - class Impl; +private: + class Impl; - /*! \brief - * Initializes a new symbol with the given data. - * - * \param impl Implementation data. - * \throws std::bad_alloc if out of memory. - * - * Only the parent symbol table creates symbol objects. - */ - explicit SelectionParserSymbol(Impl *impl); + /*! \brief + * Initializes a new symbol with the given data. + * + * \param impl Implementation data. + * \throws std::bad_alloc if out of memory. + * + * Only the parent symbol table creates symbol objects. + */ + explicit SelectionParserSymbol(Impl* impl); - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed to call the constructor and for other initialization. - */ - friend class SelectionParserSymbolTable; + /*! \brief + * Needed to call the constructor and for other initialization. + */ + friend class SelectionParserSymbolTable; }; /*! \internal @@ -143,66 +143,62 @@ class SelectionParserSymbol */ class SelectionParserSymbolIterator { - public: - /*! \name Iterator type traits - * Satisfies the requirements for STL input iterator. - * \{ - */ - using iterator_category = std::input_iterator_tag; - using value_type = const SelectionParserSymbol; - using difference_type = std::ptrdiff_t; - using pointer = const SelectionParserSymbol*; - using reference = const SelectionParserSymbol&; - //! \} +public: + /*! \name Iterator type traits + * Satisfies the requirements for STL input iterator. + * \{ + */ + using iterator_category = std::input_iterator_tag; + using value_type = const SelectionParserSymbol; + using difference_type = std::ptrdiff_t; + using pointer = const SelectionParserSymbol*; + using reference = const SelectionParserSymbol&; + //! \} - //! Creates an independent copy of an iterator. - SelectionParserSymbolIterator(const SelectionParserSymbolIterator &other); - ~SelectionParserSymbolIterator(); + //! Creates an independent copy of an iterator. + SelectionParserSymbolIterator(const SelectionParserSymbolIterator& other); + ~SelectionParserSymbolIterator(); - //! Creates an independent copy of an iterator. - SelectionParserSymbolIterator & - operator=(const SelectionParserSymbolIterator &other); + //! Creates an independent copy of an iterator. + SelectionParserSymbolIterator& operator=(const SelectionParserSymbolIterator& other); - //! Equality comparison for iterators. - bool operator==(const SelectionParserSymbolIterator &other) const; - //! Inequality comparison for iterators. - bool operator!=(const SelectionParserSymbolIterator &other) const - { - return !operator==(other); - } - //! Dereferences the iterator. - reference operator*() const; - //! Dereferences the iterator. - pointer operator->() const { return &operator*(); } - //! Moves the iterator to the next symbol. - SelectionParserSymbolIterator &operator++(); - //! Moves the iterator to the next symbol. - SelectionParserSymbolIterator operator++(int) - { - SelectionParserSymbolIterator tmp(*this); - operator++(); - return tmp; - } + //! Equality comparison for iterators. + bool operator==(const SelectionParserSymbolIterator& other) const; + //! Inequality comparison for iterators. + bool operator!=(const SelectionParserSymbolIterator& other) const { return !operator==(other); } + //! Dereferences the iterator. + reference operator*() const; + //! Dereferences the iterator. + pointer operator->() const { return &operator*(); } + //! Moves the iterator to the next symbol. + SelectionParserSymbolIterator& operator++(); + //! Moves the iterator to the next symbol. + SelectionParserSymbolIterator operator++(int) + { + SelectionParserSymbolIterator tmp(*this); + operator++(); + return tmp; + } - private: - class Impl; +private: + class Impl; - /*! \brief - * Initializes a new iterator with the given data. - * - * \param impl Implementation data. - * - * Only the parent symbol table can create non-default-constructed - * iterators. - */ - explicit SelectionParserSymbolIterator(Impl *impl); + /*! \brief + * Initializes a new iterator with the given data. + * + * \param impl Implementation data. + * + * Only the parent symbol table can create non-default-constructed + * iterators. + */ + explicit SelectionParserSymbolIterator(Impl* impl); - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed to access the constructor. - */ - friend class SelectionParserSymbolTable; + /*! \brief + * Needed to access the constructor. + */ + friend class SelectionParserSymbolTable; }; /*! \internal \brief @@ -212,81 +208,78 @@ class SelectionParserSymbolIterator */ class SelectionParserSymbolTable { - public: - /*! \brief - * Creates a new symbol table. - * - * \throws std::bad_alloc if out of memory. - * - * The created table is initialized with reserved and position symbols. - */ - SelectionParserSymbolTable(); - ~SelectionParserSymbolTable(); +public: + /*! \brief + * Creates a new symbol table. + * + * \throws std::bad_alloc if out of memory. + * + * The created table is initialized with reserved and position symbols. + */ + SelectionParserSymbolTable(); + ~SelectionParserSymbolTable(); - /*! \brief - * Finds a symbol by name. - * - * \param[in] name Symbol name to find. - * \returns Pointer to the symbol with name \p name, or - * NULL if not found. - * - * Does not throw. - */ - const SelectionParserSymbol * - findSymbol(const std::string &name) const; + /*! \brief + * Finds a symbol by name. + * + * \param[in] name Symbol name to find. + * \returns Pointer to the symbol with name \p name, or + * NULL if not found. + * + * Does not throw. + */ + const SelectionParserSymbol* findSymbol(const std::string& name) const; - /*! \brief - * Returns the start iterator for iterating symbols of a given type. - * - * \param[in] type Type of symbols to iterate over. - * \returns Iterator that points to the first symbol of type \p type. - * \throws std::bad_alloc if out of memory. - * - * \see SelectionParserSymbolIterator - */ - SelectionParserSymbolIterator - beginIterator(SelectionParserSymbol::SymbolType type) const; - /*! \brief - * Returns the end iterator for symbol iteration. - * - * \throws std::bad_alloc if out of memory. - * - * Currently, the end value is the same for all symbol types. - * - * \see SelectionParserSymbolIterator - */ - SelectionParserSymbolIterator endIterator() const; + /*! \brief + * Returns the start iterator for iterating symbols of a given type. + * + * \param[in] type Type of symbols to iterate over. + * \returns Iterator that points to the first symbol of type \p type. + * \throws std::bad_alloc if out of memory. + * + * \see SelectionParserSymbolIterator + */ + SelectionParserSymbolIterator beginIterator(SelectionParserSymbol::SymbolType type) const; + /*! \brief + * Returns the end iterator for symbol iteration. + * + * \throws std::bad_alloc if out of memory. + * + * Currently, the end value is the same for all symbol types. + * + * \see SelectionParserSymbolIterator + */ + SelectionParserSymbolIterator endIterator() const; - /*! \brief - * Adds a new variable symbol. - * - * \param[in] name Name of the new symbol. - * \param[in] sel Value of the variable. - * \throws std::bad_alloc if out of memory. - * \throws InvalidInputError if there was a symbol with the same - * name. - */ - void addVariable(const char *name, - const SelectionTreeElementPointer &sel); - /*! \brief - * Adds a new method symbol. - * - * \param[in] name Name of the new symbol. - * \param[in] method Method that this symbol represents. - * \throws std::bad_alloc if out of memory. - * \throws APIError if there was a symbol with the same name. - */ - void addMethod(const char *name, gmx_ana_selmethod_t *method); + /*! \brief + * Adds a new variable symbol. + * + * \param[in] name Name of the new symbol. + * \param[in] sel Value of the variable. + * \throws std::bad_alloc if out of memory. + * \throws InvalidInputError if there was a symbol with the same + * name. + */ + void addVariable(const char* name, const SelectionTreeElementPointer& sel); + /*! \brief + * Adds a new method symbol. + * + * \param[in] name Name of the new symbol. + * \param[in] method Method that this symbol represents. + * \throws std::bad_alloc if out of memory. + * \throws APIError if there was a symbol with the same name. + */ + void addMethod(const char* name, gmx_ana_selmethod_t* method); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed to access implementation types. - */ - friend class SelectionParserSymbolIterator; + /*! \brief + * Needed to access implementation types. + */ + friend class SelectionParserSymbolIterator; }; } // namespace gmx diff --git a/src/gromacs/selection/tests/indexutil.cpp b/src/gromacs/selection/tests/indexutil.cpp index f30ae8fd17..7bce7c26b9 100644 --- a/src/gromacs/selection/tests/indexutil.cpp +++ b/src/gromacs/selection/tests/indexutil.cpp @@ -81,35 +81,35 @@ TEST(IndexGroupTest, RemovesDuplicates) //! Text fixture for index block operations class IndexBlockTest : public ::testing::Test { - public: - IndexBlockTest(); - ~IndexBlockTest() override; - - //@{ - //! Set the input group for the index block operation - void setGroup(int count, const int atoms[]); - template - void setGroup(const int (&atoms)[count]) - { - setGroup(count, atoms); - } - //@} - /*! \brief Check the input group and output with refdata, with - * an optional \c id to name the refdata block */ - void checkBlocka(const char *id = "Block"); - //! Make a simple topology to check with - void makeSimpleTopology(); - //! Make a complex topology to check with - void makeComplexTopology(); - - //! Managers reference data for the tests - gmx::test::TestReferenceData data_; - //! Manages setting up a topology and matching data structures - gmx::test::TopologyManager topManager_; - //! The input group to test with - gmx_ana_index_t g_; - //! The output block to test on - t_blocka blocka_; +public: + IndexBlockTest(); + ~IndexBlockTest() override; + + //@{ + //! Set the input group for the index block operation + void setGroup(int count, const int atoms[]); + template + void setGroup(const int (&atoms)[count]) + { + setGroup(count, atoms); + } + //@} + /*! \brief Check the input group and output with refdata, with + * an optional \c id to name the refdata block */ + void checkBlocka(const char* id = "Block"); + //! Make a simple topology to check with + void makeSimpleTopology(); + //! Make a complex topology to check with + void makeComplexTopology(); + + //! Managers reference data for the tests + gmx::test::TestReferenceData data_; + //! Manages setting up a topology and matching data structures + gmx::test::TopologyManager topManager_; + //! The input group to test with + gmx_ana_index_t g_; + //! The output block to test on + t_blocka blocka_; }; IndexBlockTest::IndexBlockTest() @@ -131,21 +131,18 @@ IndexBlockTest::~IndexBlockTest() void IndexBlockTest::setGroup(int count, const int atoms[]) { g_.isize = count; - g_.index = const_cast(atoms); + g_.index = const_cast(atoms); } -void IndexBlockTest::checkBlocka(const char *id) +void IndexBlockTest::checkBlocka(const char* id) { - gmx::test::TestReferenceChecker compound( - data_.rootChecker().checkCompound("BlockAtoms", id)); + gmx::test::TestReferenceChecker compound(data_.rootChecker().checkCompound("BlockAtoms", id)); compound.checkSequenceArray(g_.isize, g_.index, "Input"); compound.checkInteger(blocka_.nr, "Count"); for (int i = 0; i < blocka_.nr; ++i) { - gmx::test::TestReferenceChecker blockCompound( - compound.checkCompound("Block", nullptr)); - blockCompound.checkSequence(&blocka_.a[blocka_.index[i]], - &blocka_.a[blocka_.index[i+1]], + gmx::test::TestReferenceChecker blockCompound(compound.checkCompound("Block", nullptr)); + blockCompound.checkSequence(&blocka_.a[blocka_.index[i]], &blocka_.a[blocka_.index[i + 1]], "Atoms"); } } @@ -155,7 +152,7 @@ void IndexBlockTest::makeSimpleTopology() topManager_.initTopology(1, 1); { int moleculeTypeIndex = 0; - std::vector numAtomsInResidues = {3, 3, 3}; + std::vector numAtomsInResidues = { 3, 3, 3 }; int moleculeBlockIndex = 0; int numMoleculesInBlock = 1; topManager_.setMoleculeType(moleculeTypeIndex, numAtomsInResidues); @@ -169,7 +166,7 @@ void IndexBlockTest::makeComplexTopology() topManager_.initTopology(3, 4); { int moleculeTypeIndex = 0; - std::vector numAtomsInResidues = {2, 2, 1}; + std::vector numAtomsInResidues = { 2, 2, 1 }; int moleculeBlockIndex = 0; int numMoleculesInBlock = 1; topManager_.setMoleculeType(moleculeTypeIndex, numAtomsInResidues); @@ -177,7 +174,7 @@ void IndexBlockTest::makeComplexTopology() } { int moleculeTypeIndex = 1; - std::vector numAtomsInResidues = {1}; + std::vector numAtomsInResidues = { 1 }; int moleculeBlockIndex = 1; int numMoleculesInBlock = 3; topManager_.setMoleculeType(moleculeTypeIndex, numAtomsInResidues); @@ -185,7 +182,7 @@ void IndexBlockTest::makeComplexTopology() } { int moleculeTypeIndex = 2; - std::vector numAtomsInResidues = {3}; + std::vector numAtomsInResidues = { 3 }; int moleculeBlockIndex = 2; int numMoleculesInBlock = 1; topManager_.setMoleculeType(moleculeTypeIndex, numAtomsInResidues); @@ -247,20 +244,20 @@ TEST_F(IndexBlockTest, CreatesResidueBlocksForComplexTopology) gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, false); checkBlocka("FromAllAtoms"); done_blocka(&blocka_); - //SCOPED_TRACE("Group with all atoms with completion"); - //gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, true); - //checkBlocka("FromAllAtoms"); - //done_blocka(&blocka_); + // SCOPED_TRACE("Group with all atoms with completion"); + // gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, true); + // checkBlocka("FromAllAtoms"); + // done_blocka(&blocka_); SCOPED_TRACE("Group with some atoms without completion"); const int subgroup[] = { 0, 3, 4, 5, 6, 7, 8, 12, 13, 15 }; setGroup(subgroup); gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, false); checkBlocka("FromSomeAtomsWithoutCompletion"); - //done_blocka(&blocka_); - //SCOPED_TRACE("Group with some atoms with completion"); - //gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, true); - //checkBlocka("FromSomeAtomsWithCompletion"); + // done_blocka(&blocka_); + // SCOPED_TRACE("Group with some atoms with completion"); + // gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, true); + // checkBlocka("FromSomeAtomsWithCompletion"); } TEST_F(IndexBlockTest, CreatesMoleculeBlocksForSimpleTopology) @@ -286,20 +283,20 @@ TEST_F(IndexBlockTest, CreatesMoleculeBlocksForComplexTopology) gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, false); checkBlocka("FromAllAtoms"); done_blocka(&blocka_); - //SCOPED_TRACE("Group with all atoms with completion"); - //gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, true); - //checkBlocka("FromAllAtoms"); - //done_blocka(&blocka_); + // SCOPED_TRACE("Group with all atoms with completion"); + // gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, true); + // checkBlocka("FromAllAtoms"); + // done_blocka(&blocka_); SCOPED_TRACE("Group with some atoms without completion"); const int subgroup[] = { 1, 5, 6, 7, 11, 12 }; setGroup(subgroup); gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, false); checkBlocka("FromSomeAtomsWithoutCompletion"); - //done_blocka(&blocka_); - //SCOPED_TRACE("Group with some atoms with completion"); - //gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, true); - //checkBlocka("FromSomeAtomsWithCompletion"); + // done_blocka(&blocka_); + // SCOPED_TRACE("Group with some atoms with completion"); + // gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_MOL, true); + // checkBlocka("FromSomeAtomsWithCompletion"); } TEST_F(IndexBlockTest, CreatesSingleBlock) @@ -319,39 +316,33 @@ TEST_F(IndexBlockTest, CreatesSingleBlock) TEST_F(IndexBlockTest, ChecksGroupForFullBlocksPositive) { - const int maxGroup[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - }; + const int maxGroup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; const int testGroup[] = { 3, 4, 5, 6, 7, 8, 12, 13, 14 }; topManager_.initAtoms(18); topManager_.initUniformResidues(3); setGroup(maxGroup); - gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, - INDEX_RES, false); + gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, false); setGroup(testGroup); EXPECT_TRUE(gmx_ana_index_has_full_ablocks(&g_, &blocka_)); } TEST_F(IndexBlockTest, ChecksOutOfOrderGroupForFullBlocksPositive) { - const int maxGroup[] = { - 15, 16, 17, 2, 1, 0, 12, 13, 14, 5, 4, 3, 9, 10, 11, 8, 7, 6 + const int maxGroup[] = { 15, 16, 17, 2, 1, 0, 12, 13, 14, 5, 4, 3, 9, 10, 11, 8, 7, 6 }; + const int testGroup[] = { + 2, 1, 0, 5, 4, 3, 8, 7, 6, }; - const int testGroup[] = { 2, 1, 0, 5, 4, 3, 8, 7, 6, }; topManager_.initAtoms(18); topManager_.initUniformResidues(3); setGroup(maxGroup); - gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, - INDEX_RES, false); + gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, false); setGroup(testGroup); EXPECT_TRUE(gmx_ana_index_has_full_ablocks(&g_, &blocka_)); } TEST_F(IndexBlockTest, ChecksGroupForFullBlocksNegative) { - const int maxGroup[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - }; + const int maxGroup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; const int testGroup1[] = { 3, 4, 5, 6, 7, 8, 12, 13 }; const int testGroup2[] = { 3, 4, 5, 6, 7, 12, 13, 14 }; const int testGroup3[] = { 4, 5, 6, 7, 8, 12, 13, 14 }; @@ -359,8 +350,7 @@ TEST_F(IndexBlockTest, ChecksGroupForFullBlocksNegative) topManager_.initAtoms(18); topManager_.initUniformResidues(3); setGroup(maxGroup); - gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, - INDEX_RES, false); + gmx_ana_index_make_block(&blocka_, topManager_.topology(), &g_, INDEX_RES, false); setGroup(testGroup1); EXPECT_FALSE(gmx_ana_index_has_full_ablocks(&g_, &blocka_)); @@ -392,7 +382,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteResiduesPositive) topManager_.initAtoms(15); topManager_.initUniformResidues(3); - gmx_mtop_t *top = topManager_.topology(); + gmx_mtop_t* top = topManager_.topology(); setGroup(group1); EXPECT_TRUE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top)); @@ -410,7 +400,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteResiduesNegative) topManager_.initAtoms(18); topManager_.initUniformResidues(3); - gmx_mtop_t *top = topManager_.topology(); + gmx_mtop_t* top = topManager_.topology(); setGroup(group1); EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_RES, top)); @@ -432,7 +422,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesPositive) topManager_.initAtoms(15); topManager_.initUniformResidues(1); topManager_.initUniformMolecules(3); - gmx_mtop_t *top = topManager_.topology(); + gmx_mtop_t* top = topManager_.topology(); setGroup(group); EXPECT_TRUE(gmx_ana_index_has_complete_elems(&g_, INDEX_MOL, top)); @@ -447,7 +437,7 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesNegative) topManager_.initAtoms(18); topManager_.initUniformResidues(1); topManager_.initUniformMolecules(3); - gmx_mtop_t *top = topManager_.topology(); + gmx_mtop_t* top = topManager_.topology(); setGroup(group1); EXPECT_FALSE(gmx_ana_index_has_complete_elems(&g_, INDEX_MOL, top)); @@ -465,39 +455,36 @@ TEST_F(IndexBlockTest, ChecksGroupForCompleteMoleculesNegative) class IndexMapTest : public ::testing::Test { - public: - IndexMapTest(); - ~IndexMapTest() override; +public: + IndexMapTest(); + ~IndexMapTest() override; - void testInit(int atomCount, const int atoms[], e_index_t type); - void testUpdate(int atomCount, const int atoms[], bool bMaskOnly, - const char *name); - void testOrgIdGroup(e_index_t type, const char *name); - template - void testInit(const int (&atoms)[count], e_index_t type) - { - testInit(count, atoms, type); - } - template - void testUpdate(const int (&atoms)[count], bool bMaskOnly, - const char *name) - { - testUpdate(count, atoms, bMaskOnly, name); - } + void testInit(int atomCount, const int atoms[], e_index_t type); + void testUpdate(int atomCount, const int atoms[], bool bMaskOnly, const char* name); + void testOrgIdGroup(e_index_t type, const char* name); + template + void testInit(const int (&atoms)[count], e_index_t type) + { + testInit(count, atoms, type); + } + template + void testUpdate(const int (&atoms)[count], bool bMaskOnly, const char* name) + { + testUpdate(count, atoms, bMaskOnly, name); + } - void checkMapping(int atomCount, const int atoms[], const char *name); + void checkMapping(int atomCount, const int atoms[], const char* name); - gmx::test::TestReferenceData data_; - gmx::test::TestReferenceChecker checker_; - gmx::test::TopologyManager topManager_; - gmx_ana_indexmap_t map_; + gmx::test::TestReferenceData data_; + gmx::test::TestReferenceChecker checker_; + gmx::test::TopologyManager topManager_; + gmx_ana_indexmap_t map_; - private: - gmx_ana_index_t initGroup_; +private: + gmx_ana_index_t initGroup_; }; -IndexMapTest::IndexMapTest() - : checker_(data_.rootChecker()) +IndexMapTest::IndexMapTest() : checker_(data_.rootChecker()) { gmx_ana_indexmap_clear(&map_); gmx_ana_index_clear(&initGroup_); @@ -511,18 +498,17 @@ IndexMapTest::~IndexMapTest() void IndexMapTest::testInit(int atomCount, const int atoms[], e_index_t type) { initGroup_.isize = atomCount; - initGroup_.index = const_cast(atoms); + initGroup_.index = const_cast(atoms); gmx_ana_indexmap_init(&map_, &initGroup_, topManager_.topology(), type); EXPECT_EQ(type, map_.type); checkMapping(atomCount, atoms, "Initialized"); } -void IndexMapTest::testUpdate(int atomCount, const int atoms[], bool bMaskOnly, - const char *name) +void IndexMapTest::testUpdate(int atomCount, const int atoms[], bool bMaskOnly, const char* name) { gmx_ana_index_t g; g.isize = atomCount; - g.index = const_cast(atoms); + g.index = const_cast(atoms); gmx_ana_indexmap_update(&map_, &g, bMaskOnly); if (name == nullptr) { @@ -538,12 +524,10 @@ void IndexMapTest::testUpdate(int atomCount, const int atoms[], bool bMaskOnly, } } -void IndexMapTest::testOrgIdGroup(e_index_t type, const char *name) +void IndexMapTest::testOrgIdGroup(e_index_t type, const char* name) { - gmx::test::TestReferenceChecker compound( - checker_.checkCompound("OrgIdGroups", name)); - const int count - = gmx_ana_indexmap_init_orgid_group(&map_, topManager_.topology(), type); + gmx::test::TestReferenceChecker compound(checker_.checkCompound("OrgIdGroups", name)); + const int count = gmx_ana_indexmap_init_orgid_group(&map_, topManager_.topology(), type); compound.checkInteger(count, "GroupCount"); compound.checkSequenceArray(map_.mapb.nr, map_.orgid, "OrgId"); for (int i = 0; i < map_.mapb.nr; ++i) @@ -552,19 +536,15 @@ void IndexMapTest::testOrgIdGroup(e_index_t type, const char *name) } } -void IndexMapTest::checkMapping(int atomCount, const int atoms[], - const char *name) +void IndexMapTest::checkMapping(int atomCount, const int atoms[], const char* name) { - gmx::test::TestReferenceChecker compound( - checker_.checkCompound("IndexMapping", name)); + gmx::test::TestReferenceChecker compound(checker_.checkCompound("IndexMapping", name)); compound.checkSequenceArray(atomCount, atoms, "Input"); compound.checkInteger(map_.mapb.nr, "Count"); for (int i = 0; i < map_.mapb.nr; ++i) { - gmx::test::TestReferenceChecker blockCompound( - compound.checkCompound("Block", nullptr)); - blockCompound.checkSequence(&atoms[map_.mapb.index[i]], - &atoms[map_.mapb.index[i+1]], + gmx::test::TestReferenceChecker blockCompound(compound.checkCompound("Block", nullptr)); + blockCompound.checkSequence(&atoms[map_.mapb.index[i]], &atoms[map_.mapb.index[i + 1]], "Atoms"); blockCompound.checkInteger(map_.refid[i], "RefId"); blockCompound.checkInteger(map_.mapid[i], "MapId"); @@ -644,9 +624,7 @@ TEST_F(IndexMapTest, MapsSingleBlock) TEST_F(IndexMapTest, MapsResidueBlocks) { - const int maxGroup[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - }; + const int maxGroup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; const int evalGroup[] = { 3, 4, 7, 8, 13 }; topManager_.initAtoms(18); topManager_.initUniformResidues(3); @@ -656,9 +634,7 @@ TEST_F(IndexMapTest, MapsResidueBlocks) TEST_F(IndexMapTest, MapsResidueBlocksWithMask) { - const int maxGroup[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - }; + const int maxGroup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; const int evalGroup[] = { 3, 4, 7, 8, 13 }; topManager_.initAtoms(18); topManager_.initUniformResidues(3); @@ -668,9 +644,7 @@ TEST_F(IndexMapTest, MapsResidueBlocksWithMask) TEST_F(IndexMapTest, HandlesMultipleRequests) { - const int maxGroup[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 - }; + const int maxGroup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; const int evalGroup[] = { 3, 4, 7, 8, 13 }; topManager_.initAtoms(18); topManager_.initUniformResidues(3); @@ -689,48 +663,44 @@ TEST_F(IndexMapTest, HandlesMultipleRequests) class IndexGroupsAndNamesTest : public ::testing::Test { - public: - IndexGroupsAndNamesTest() - { - init_blocka(&blockA_); - addGroupToBlocka_(indicesGroupA_); - addGroupToBlocka_(indicesGroupB_); - addGroupToBlocka_(indicesGroupSecondA_); - addGroupToBlocka_(indicesGroupC_); - - const char *const namesAsConstCharArray[4] = { - groupNames[0].c_str(), groupNames[1].c_str(), - groupNames[2].c_str(), groupNames[3].c_str() - }; - indexGroupAndNames_ = std::make_unique(blockA_, namesAsConstCharArray); - } - ~IndexGroupsAndNamesTest() override - { - done_blocka(&blockA_); - } - protected: - std::unique_ptr indexGroupAndNames_; - const std::vector groupNames = { "A", "B - Name", "A", "C" }; - const std::vector indicesGroupA_ = { }; - const std::vector indicesGroupB_ = { 1, 2 }; - const std::vector indicesGroupSecondA_ = { 5 }; - const std::vector indicesGroupC_ = { 10 }; - - private: - //! Add a new group to t_blocka - void addGroupToBlocka_(gmx::ArrayRef index) +public: + IndexGroupsAndNamesTest() + { + init_blocka(&blockA_); + addGroupToBlocka_(indicesGroupA_); + addGroupToBlocka_(indicesGroupB_); + addGroupToBlocka_(indicesGroupSecondA_); + addGroupToBlocka_(indicesGroupC_); + + const char* const namesAsConstCharArray[4] = { groupNames[0].c_str(), groupNames[1].c_str(), + groupNames[2].c_str(), groupNames[3].c_str() }; + indexGroupAndNames_ = std::make_unique(blockA_, namesAsConstCharArray); + } + ~IndexGroupsAndNamesTest() override { done_blocka(&blockA_); } + +protected: + std::unique_ptr indexGroupAndNames_; + const std::vector groupNames = { "A", "B - Name", "A", "C" }; + const std::vector indicesGroupA_ = {}; + const std::vector indicesGroupB_ = { 1, 2 }; + const std::vector indicesGroupSecondA_ = { 5 }; + const std::vector indicesGroupC_ = { 10 }; + +private: + //! Add a new group to t_blocka + void addGroupToBlocka_(gmx::ArrayRef index) + { + srenew(blockA_.index, blockA_.nr + 2); + srenew(blockA_.a, blockA_.nra + index.size()); + for (int i = 0; (i < index.ssize()); i++) { - srenew(blockA_.index, blockA_.nr + 2); - srenew(blockA_.a, blockA_.nra + index.size()); - for (int i = 0; (i < index.ssize()); i++) - { - blockA_.a[blockA_.nra++] = index[i]; - } - blockA_.nr++; - blockA_.index[blockA_.nr] = blockA_.nra; + blockA_.a[blockA_.nra++] = index[i]; } + blockA_.nr++; + blockA_.index[blockA_.nr] = blockA_.nra; + } - t_blocka blockA_; + t_blocka blockA_; }; TEST_F(IndexGroupsAndNamesTest, containsNames) @@ -751,8 +721,8 @@ TEST_F(IndexGroupsAndNamesTest, throwsWhenNameMissing) TEST_F(IndexGroupsAndNamesTest, groupIndicesCorrect) { - using ::testing::Pointwise; using ::testing::Eq; + using ::testing::Pointwise; EXPECT_THAT(indicesGroupA_, Pointwise(Eq(), indexGroupAndNames_->indices("A"))); EXPECT_THAT(indicesGroupB_, Pointwise(Eq(), indexGroupAndNames_->indices("B - name"))); EXPECT_THAT(indicesGroupC_, Pointwise(Eq(), indexGroupAndNames_->indices("C"))); diff --git a/src/gromacs/selection/tests/nbsearch.cpp b/src/gromacs/selection/tests/nbsearch.cpp index 7b6d88e78a..7e85995a1d 100644 --- a/src/gromacs/selection/tests/nbsearch.cpp +++ b/src/gromacs/selection/tests/nbsearch.cpp @@ -79,128 +79,122 @@ namespace class NeighborhoodSearchTestData { - public: - struct RefPair +public: + struct RefPair + { + RefPair(int refIndex, real distance) : + refIndex(refIndex), + distance(distance), + bFound(false), + bExcluded(false), + bIndexed(true) { - RefPair(int refIndex, real distance) - : refIndex(refIndex), distance(distance), bFound(false), - bExcluded(false), bIndexed(true) - { - } + } - bool operator<(const RefPair &other) const - { - return refIndex < other.refIndex; - } + bool operator<(const RefPair& other) const { return refIndex < other.refIndex; } + + int refIndex; + real distance; + // The variables below are state variables that are only used + // during the actual testing after creating a copy of the reference + // pair list, not as part of the reference data. + // Simpler to have just a single structure for both purposes. + bool bFound; + bool bExcluded; + bool bIndexed; + }; - int refIndex; - real distance; - // The variables below are state variables that are only used - // during the actual testing after creating a copy of the reference - // pair list, not as part of the reference data. - // Simpler to have just a single structure for both purposes. - bool bFound; - bool bExcluded; - bool bIndexed; - }; - - struct TestPosition + struct TestPosition + { + explicit TestPosition(const rvec x) : refMinDist(0.0), refNearestPoint(-1) { - explicit TestPosition(const rvec x) - : refMinDist(0.0), refNearestPoint(-1) - { - copy_rvec(x, this->x); - } + copy_rvec(x, this->x); + } - rvec x; - real refMinDist; - int refNearestPoint; - std::vector refPairs; - }; + rvec x; + real refMinDist; + int refNearestPoint; + std::vector refPairs; + }; - typedef std::vector TestPositionList; + typedef std::vector TestPositionList; - NeighborhoodSearchTestData(uint64_t seed, real cutoff); + NeighborhoodSearchTestData(uint64_t seed, real cutoff); - gmx::AnalysisNeighborhoodPositions refPositions() const - { - return gmx::AnalysisNeighborhoodPositions(refPos_); - } - gmx::AnalysisNeighborhoodPositions testPositions() const + gmx::AnalysisNeighborhoodPositions refPositions() const + { + return gmx::AnalysisNeighborhoodPositions(refPos_); + } + gmx::AnalysisNeighborhoodPositions testPositions() const + { + if (testPos_.empty()) { - if (testPos_.empty()) + testPos_.reserve(testPositions_.size()); + for (size_t i = 0; i < testPositions_.size(); ++i) { - testPos_.reserve(testPositions_.size()); - for (size_t i = 0; i < testPositions_.size(); ++i) - { - testPos_.emplace_back(testPositions_[i].x); - } + testPos_.emplace_back(testPositions_[i].x); } - return gmx::AnalysisNeighborhoodPositions(testPos_); - } - gmx::AnalysisNeighborhoodPositions testPosition(int index) const - { - return testPositions().selectSingleFromArray(index); - } - - void addTestPosition(const rvec x) - { - GMX_RELEASE_ASSERT(testPos_.empty(), - "Cannot add positions after testPositions() call"); - testPositions_.emplace_back(x); - } - gmx::RVec generateRandomPosition(); - std::vector generateIndex(int count, uint64_t seed) const; - void generateRandomRefPositions(int count); - void generateRandomTestPositions(int count); - void useRefPositionsAsTestPositions(); - void computeReferences(t_pbc *pbc) - { - computeReferencesInternal(pbc, false); - } - void computeReferencesXY(t_pbc *pbc) - { - computeReferencesInternal(pbc, true); } + return gmx::AnalysisNeighborhoodPositions(testPos_); + } + gmx::AnalysisNeighborhoodPositions testPosition(int index) const + { + return testPositions().selectSingleFromArray(index); + } - bool containsPair(int testIndex, const RefPair &pair) const - { - const std::vector &refPairs = testPositions_[testIndex].refPairs; - std::vector::const_iterator foundRefPair - = std::lower_bound(refPairs.begin(), refPairs.end(), pair); - return !(foundRefPair == refPairs.end() || foundRefPair->refIndex != pair.refIndex); - } + void addTestPosition(const rvec x) + { + GMX_RELEASE_ASSERT(testPos_.empty(), "Cannot add positions after testPositions() call"); + testPositions_.emplace_back(x); + } + gmx::RVec generateRandomPosition(); + std::vector generateIndex(int count, uint64_t seed) const; + void generateRandomRefPositions(int count); + void generateRandomTestPositions(int count); + void useRefPositionsAsTestPositions(); + void computeReferences(t_pbc* pbc) { computeReferencesInternal(pbc, false); } + void computeReferencesXY(t_pbc* pbc) { computeReferencesInternal(pbc, true); } + + bool containsPair(int testIndex, const RefPair& pair) const + { + const std::vector& refPairs = testPositions_[testIndex].refPairs; + std::vector::const_iterator foundRefPair = + std::lower_bound(refPairs.begin(), refPairs.end(), pair); + return !(foundRefPair == refPairs.end() || foundRefPair->refIndex != pair.refIndex); + } - // Return a tolerance that accounts for the magnitudes of the coordinates - // when doing subtractions, so that we set the ULP tolerance relative to the - // coordinate values rather than their difference. - // i.e., 10.0-9.9999999 will achieve a few ULP accuracy relative - // to 10.0, but a much larger error relative to the difference. - gmx::test::FloatingPointTolerance relativeTolerance() const - { - real magnitude = std::max(box_[XX][XX], std::max(box_[YY][YY], box_[ZZ][ZZ])); - return gmx::test::relativeToleranceAsUlp(magnitude, 4); - } + // Return a tolerance that accounts for the magnitudes of the coordinates + // when doing subtractions, so that we set the ULP tolerance relative to the + // coordinate values rather than their difference. + // i.e., 10.0-9.9999999 will achieve a few ULP accuracy relative + // to 10.0, but a much larger error relative to the difference. + gmx::test::FloatingPointTolerance relativeTolerance() const + { + real magnitude = std::max(box_[XX][XX], std::max(box_[YY][YY], box_[ZZ][ZZ])); + return gmx::test::relativeToleranceAsUlp(magnitude, 4); + } - gmx::DefaultRandomEngine rng_; - real cutoff_; - matrix box_; - t_pbc pbc_; - int refPosCount_; - std::vector refPos_; - TestPositionList testPositions_; + gmx::DefaultRandomEngine rng_; + real cutoff_; + matrix box_; + t_pbc pbc_; + int refPosCount_; + std::vector refPos_; + TestPositionList testPositions_; - private: - void computeReferencesInternal(t_pbc *pbc, bool bXY); +private: + void computeReferencesInternal(t_pbc* pbc, bool bXY); - mutable std::vector testPos_; + mutable std::vector testPos_; }; //! Shorthand for a collection of reference pairs. typedef std::vector RefPairList; -NeighborhoodSearchTestData::NeighborhoodSearchTestData(uint64_t seed, real cutoff) - : rng_(seed), cutoff_(cutoff), refPosCount_(0) +NeighborhoodSearchTestData::NeighborhoodSearchTestData(uint64_t seed, real cutoff) : + rng_(seed), + cutoff_(cutoff), + refPosCount_(0) { clear_mat(box_); set_pbc(&pbc_, epbcNONE, box_); @@ -208,8 +202,8 @@ NeighborhoodSearchTestData::NeighborhoodSearchTestData(uint64_t seed, real cutof gmx::RVec NeighborhoodSearchTestData::generateRandomPosition() { - gmx::UniformRealDistribution dist; - rvec fx, x; + gmx::UniformRealDistribution dist; + rvec fx, x; fx[XX] = dist(rng_); fx[YY] = dist(rng_); fx[ZZ] = dist(rng_); @@ -223,9 +217,9 @@ gmx::RVec NeighborhoodSearchTestData::generateRandomPosition() std::vector NeighborhoodSearchTestData::generateIndex(int count, uint64_t seed) const { - gmx::DefaultRandomEngine rngIndex(seed); - gmx::UniformRealDistribution dist; - std::vector result; + gmx::DefaultRandomEngine rngIndex(seed); + gmx::UniformRealDistribution dist; + std::vector result; for (int i = 0; i < count; ++i) { @@ -259,20 +253,20 @@ void NeighborhoodSearchTestData::generateRandomTestPositions(int count) void NeighborhoodSearchTestData::useRefPositionsAsTestPositions() { testPositions_.reserve(refPosCount_); - for (const auto &refPos : refPos_) + for (const auto& refPos : refPos_) { addTestPosition(refPos); } } -void NeighborhoodSearchTestData::computeReferencesInternal(t_pbc *pbc, bool bXY) +void NeighborhoodSearchTestData::computeReferencesInternal(t_pbc* pbc, bool bXY) { real cutoff = cutoff_; if (cutoff <= 0) { cutoff = std::numeric_limits::max(); } - for (TestPosition &testPos : testPositions_) + for (TestPosition& testPos : testPositions_) { testPos.refMinDist = cutoff; testPos.refNearestPoint = -1; @@ -291,8 +285,7 @@ void NeighborhoodSearchTestData::computeReferencesInternal(t_pbc *pbc, bool bXY) // TODO: This may not work intuitively for 2D with the third box // vector not parallel to the Z axis, but neither does the actual // neighborhood search. - const real dist = - !bXY ? norm(dx) : std::hypot(dx[XX], dx[YY]); + const real dist = !bXY ? norm(dx) : std::hypot(dx[XX], dx[YY]); if (dist < testPos.refMinDist) { testPos.refMinDist = dist; @@ -315,47 +308,44 @@ void NeighborhoodSearchTestData::computeReferencesInternal(t_pbc *pbc, bool bXY) class ExclusionsHelper { - public: - static void markExcludedPairs(RefPairList *refPairs, int testIndex, - const t_blocka *excls); +public: + static void markExcludedPairs(RefPairList* refPairs, int testIndex, const t_blocka* excls); - ExclusionsHelper(int refPosCount, int testPosCount); + ExclusionsHelper(int refPosCount, int testPosCount); - void generateExclusions(); + void generateExclusions(); - const t_blocka *exclusions() const { return &excls_; } + const t_blocka* exclusions() const { return &excls_; } - gmx::ArrayRef refPosIds() const - { - return gmx::makeArrayRef(exclusionIds_).subArray(0, refPosCount_); - } - gmx::ArrayRef testPosIds() const - { - return gmx::makeArrayRef(exclusionIds_).subArray(0, testPosCount_); - } + gmx::ArrayRef refPosIds() const + { + return gmx::makeArrayRef(exclusionIds_).subArray(0, refPosCount_); + } + gmx::ArrayRef testPosIds() const + { + return gmx::makeArrayRef(exclusionIds_).subArray(0, testPosCount_); + } - private: - int refPosCount_; - int testPosCount_; - std::vector exclusionIds_; - std::vector exclsIndex_; - std::vector exclsAtoms_; - t_blocka excls_; +private: + int refPosCount_; + int testPosCount_; + std::vector exclusionIds_; + std::vector exclsIndex_; + std::vector exclsAtoms_; + t_blocka excls_; }; // static -void ExclusionsHelper::markExcludedPairs(RefPairList *refPairs, int testIndex, - const t_blocka *excls) +void ExclusionsHelper::markExcludedPairs(RefPairList* refPairs, int testIndex, const t_blocka* excls) { int count = 0; for (int i = excls->index[testIndex]; i < excls->index[testIndex + 1]; ++i) { const int excludedIndex = excls->a[i]; NeighborhoodSearchTestData::RefPair searchPair(excludedIndex, 0.0); - RefPairList::iterator excludedRefPair - = std::lower_bound(refPairs->begin(), refPairs->end(), searchPair); - if (excludedRefPair != refPairs->end() - && excludedRefPair->refIndex == excludedIndex) + RefPairList::iterator excludedRefPair = + std::lower_bound(refPairs->begin(), refPairs->end(), searchPair); + if (excludedRefPair != refPairs->end() && excludedRefPair->refIndex == excludedIndex) { excludedRefPair->bFound = true; excludedRefPair->bExcluded = true; @@ -364,16 +354,16 @@ void ExclusionsHelper::markExcludedPairs(RefPairList *refPairs, int testIndex, } } -ExclusionsHelper::ExclusionsHelper(int refPosCount, int testPosCount) - : refPosCount_(refPosCount), testPosCount_(testPosCount) +ExclusionsHelper::ExclusionsHelper(int refPosCount, int testPosCount) : + refPosCount_(refPosCount), + testPosCount_(testPosCount) { // Generate an array of 0, 1, 2, ... // TODO: Make the tests work also with non-trivial exclusion IDs, // and test that. exclusionIds_.resize(std::max(refPosCount, testPosCount), 1); exclusionIds_[0] = 0; - std::partial_sum(exclusionIds_.begin(), exclusionIds_.end(), - exclusionIds_.begin()); + std::partial_sum(exclusionIds_.begin(), exclusionIds_.end(), exclusionIds_.begin()); excls_.nr = 0; excls_.index = nullptr; @@ -396,7 +386,7 @@ void ExclusionsHelper::generateExclusions() { for (int j = 0; j < 20; ++j) { - exclsAtoms_.push_back(i + j*3); + exclsAtoms_.push_back(i + j * 3); } exclsIndex_.push_back(exclsAtoms_.size()); } @@ -412,45 +402,39 @@ void ExclusionsHelper::generateExclusions() class NeighborhoodSearchTest : public ::testing::Test { - public: - void testIsWithin(gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data); - void testMinimumDistance(gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data); - void testNearestPoint(gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data); - void testPairSearch(gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data); - void testPairSearchIndexed(gmx::AnalysisNeighborhood *nb, - const NeighborhoodSearchTestData &data, - uint64_t seed); - void testPairSearchFull(gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data, - const gmx::AnalysisNeighborhoodPositions &pos, - const t_blocka *excls, - const gmx::ArrayRef &refIndices, - const gmx::ArrayRef &testIndices, - bool selfPairs); - - gmx::AnalysisNeighborhood nb_; +public: + void testIsWithin(gmx::AnalysisNeighborhoodSearch* search, const NeighborhoodSearchTestData& data); + void testMinimumDistance(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data); + void testNearestPoint(gmx::AnalysisNeighborhoodSearch* search, const NeighborhoodSearchTestData& data); + void testPairSearch(gmx::AnalysisNeighborhoodSearch* search, const NeighborhoodSearchTestData& data); + void testPairSearchIndexed(gmx::AnalysisNeighborhood* nb, + const NeighborhoodSearchTestData& data, + uint64_t seed); + void testPairSearchFull(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data, + const gmx::AnalysisNeighborhoodPositions& pos, + const t_blocka* excls, + const gmx::ArrayRef& refIndices, + const gmx::ArrayRef& testIndices, + bool selfPairs); + + gmx::AnalysisNeighborhood nb_; }; -void NeighborhoodSearchTest::testIsWithin( - gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data) +void NeighborhoodSearchTest::testIsWithin(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data) { NeighborhoodSearchTestData::TestPositionList::const_iterator i; for (i = data.testPositions_.begin(); i != data.testPositions_.end(); ++i) { const bool bWithin = (i->refMinDist <= data.cutoff_); - EXPECT_EQ(bWithin, search->isWithin(i->x)) - << "Distance is " << i->refMinDist; + EXPECT_EQ(bWithin, search->isWithin(i->x)) << "Distance is " << i->refMinDist; } } -void NeighborhoodSearchTest::testMinimumDistance( - gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data) +void NeighborhoodSearchTest::testMinimumDistance(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data) { NeighborhoodSearchTestData::TestPositionList::const_iterator i; @@ -461,9 +445,8 @@ void NeighborhoodSearchTest::testMinimumDistance( } } -void NeighborhoodSearchTest::testNearestPoint( - gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data) +void NeighborhoodSearchTest::testNearestPoint(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data) { NeighborhoodSearchTestData::TestPositionList::const_iterator i; for (i = data.testPositions_.begin(); i != data.testPositions_.end(); ++i) @@ -491,9 +474,10 @@ std::string formatVector(const rvec x) /*! \brief * Helper function to check that all expected pairs were found. */ -void checkAllPairsFound(const RefPairList &refPairs, - const std::vector &refPos, - int testPosIndex, const rvec testPos) +void checkAllPairsFound(const RefPairList& refPairs, + const std::vector& refPos, + int testPosIndex, + const rvec testPos) { // This could be elegantly expressed with Google Mock matchers, but that // has a significant effect on the runtime of the tests... @@ -509,46 +493,39 @@ void checkAllPairsFound(const RefPairList &refPairs, } if (count > 0) { - ADD_FAILURE() - << "Some pairs (" << count << "/" << refPairs.size() << ") " - << "within the cutoff were not found. First pair:\n" - << " Ref: " << first->refIndex << " at " - << formatVector(refPos[first->refIndex]) << "\n" - << "Test: " << testPosIndex << " at " << formatVector(testPos) << "\n" - << "Dist: " << first->distance; + ADD_FAILURE() << "Some pairs (" << count << "/" << refPairs.size() << ") " + << "within the cutoff were not found. First pair:\n" + << " Ref: " << first->refIndex << " at " + << formatVector(refPos[first->refIndex]) << "\n" + << "Test: " << testPosIndex << " at " << formatVector(testPos) << "\n" + << "Dist: " << first->distance; } } -void NeighborhoodSearchTest::testPairSearch( - gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data) +void NeighborhoodSearchTest::testPairSearch(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data) { - testPairSearchFull(search, data, data.testPositions(), nullptr, - {}, {}, false); + testPairSearchFull(search, data, data.testPositions(), nullptr, {}, {}, false); } -void NeighborhoodSearchTest::testPairSearchIndexed( - gmx::AnalysisNeighborhood *nb, - const NeighborhoodSearchTestData &data, - uint64_t seed) +void NeighborhoodSearchTest::testPairSearchIndexed(gmx::AnalysisNeighborhood* nb, + const NeighborhoodSearchTestData& data, + uint64_t seed) { - std::vector refIndices(data.generateIndex(data.refPos_.size(), seed++)); - std::vector testIndices(data.generateIndex(data.testPositions_.size(), seed++)); + std::vector refIndices(data.generateIndex(data.refPos_.size(), seed++)); + std::vector testIndices(data.generateIndex(data.testPositions_.size(), seed++)); gmx::AnalysisNeighborhoodSearch search = - nb->initSearch(&data.pbc_, - data.refPositions().indexed(refIndices)); - testPairSearchFull(&search, data, data.testPositions(), nullptr, - refIndices, testIndices, false); + nb->initSearch(&data.pbc_, data.refPositions().indexed(refIndices)); + testPairSearchFull(&search, data, data.testPositions(), nullptr, refIndices, testIndices, false); } -void NeighborhoodSearchTest::testPairSearchFull( - gmx::AnalysisNeighborhoodSearch *search, - const NeighborhoodSearchTestData &data, - const gmx::AnalysisNeighborhoodPositions &pos, - const t_blocka *excls, - const gmx::ArrayRef &refIndices, - const gmx::ArrayRef &testIndices, - bool selfPairs) +void NeighborhoodSearchTest::testPairSearchFull(gmx::AnalysisNeighborhoodSearch* search, + const NeighborhoodSearchTestData& data, + const gmx::AnalysisNeighborhoodPositions& pos, + const t_blocka* excls, + const gmx::ArrayRef& refIndices, + const gmx::ArrayRef& testIndices, + bool selfPairs) { std::map refPairs; // TODO: Some parts of this code do not work properly if pos does not @@ -570,7 +547,7 @@ void NeighborhoodSearchTest::testPairSearchFull( if (excls != nullptr) { GMX_RELEASE_ASSERT(!selfPairs, "Self-pairs testing not implemented with exclusions"); - for (auto &entry : refPairs) + for (auto& entry : refPairs) { const int testIndex = entry.first; ExclusionsHelper::markExcludedPairs(&entry.second, testIndex, excls); @@ -579,9 +556,9 @@ void NeighborhoodSearchTest::testPairSearchFull( if (!refIndices.empty()) { GMX_RELEASE_ASSERT(!selfPairs, "Self-pairs testing not implemented with indexing"); - for (auto &entry : refPairs) + for (auto& entry : refPairs) { - for (auto &refPair : entry.second) + for (auto& refPair : entry.second) { refPair.bIndexed = false; } @@ -594,7 +571,7 @@ void NeighborhoodSearchTest::testPairSearchFull( refPair->bIndexed = true; } } - for (auto &refPair : entry.second) + for (auto& refPair : entry.second) { if (!refPair.bIndexed) { @@ -604,62 +581,51 @@ void NeighborhoodSearchTest::testPairSearchFull( } } - gmx::AnalysisNeighborhoodPositions posCopy(pos); + gmx::AnalysisNeighborhoodPositions posCopy(pos); if (!testIndices.empty()) { posCopy.indexed(testIndices); } - gmx::AnalysisNeighborhoodPairSearch pairSearch - = selfPairs - ? search->startSelfPairSearch() - : search->startPairSearch(posCopy); - gmx::AnalysisNeighborhoodPair pair; + gmx::AnalysisNeighborhoodPairSearch pairSearch = + selfPairs ? search->startSelfPairSearch() : search->startPairSearch(posCopy); + gmx::AnalysisNeighborhoodPair pair; while (pairSearch.findNextPair(&pair)) { - const int testIndex = - (testIndices.empty() ? pair.testIndex() : testIndices[pair.testIndex()]); - const int refIndex = - (refIndices.empty() ? pair.refIndex() : refIndices[pair.refIndex()]); + const int testIndex = (testIndices.empty() ? pair.testIndex() : testIndices[pair.testIndex()]); + const int refIndex = (refIndices.empty() ? pair.refIndex() : refIndices[pair.refIndex()]); if (refPairs.count(testIndex) == 0) { - ADD_FAILURE() - << "Expected: No pairs are returned for test position " << testIndex << ".\n" - << " Actual: Pair with ref " << refIndex << " is returned."; + ADD_FAILURE() << "Expected: No pairs are returned for test position " << testIndex << ".\n" + << " Actual: Pair with ref " << refIndex << " is returned."; continue; } - NeighborhoodSearchTestData::RefPair searchPair(refIndex, - std::sqrt(pair.distance2())); - const auto foundRefPair - = std::lower_bound(refPairs[testIndex].begin(), refPairs[testIndex].end(), - searchPair); + NeighborhoodSearchTestData::RefPair searchPair(refIndex, std::sqrt(pair.distance2())); + const auto foundRefPair = + std::lower_bound(refPairs[testIndex].begin(), refPairs[testIndex].end(), searchPair); if (foundRefPair == refPairs[testIndex].end() || foundRefPair->refIndex != refIndex) { - ADD_FAILURE() - << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex - << ") is not within the cutoff.\n" - << " Actual: It is returned."; + ADD_FAILURE() << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex + << ") is not within the cutoff.\n" + << " Actual: It is returned."; } else if (foundRefPair->bExcluded) { - ADD_FAILURE() - << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex - << ") is excluded from the search.\n" - << " Actual: It is returned."; + ADD_FAILURE() << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex + << ") is excluded from the search.\n" + << " Actual: It is returned."; } else if (!foundRefPair->bIndexed) { - ADD_FAILURE() - << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex - << ") is not part of the indexed set.\n" - << " Actual: It is returned."; + ADD_FAILURE() << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex + << ") is not part of the indexed set.\n" + << " Actual: It is returned."; } else if (foundRefPair->bFound) { - ADD_FAILURE() - << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex - << ") is returned only once.\n" - << " Actual: It is returned multiple times."; + ADD_FAILURE() << "Expected: Pair (ref: " << refIndex << ", test: " << testIndex + << ") is returned only once.\n" + << " Actual: It is returned multiple times."; return; } else @@ -667,13 +633,12 @@ void NeighborhoodSearchTest::testPairSearchFull( foundRefPair->bFound = true; EXPECT_REAL_EQ_TOL(foundRefPair->distance, searchPair.distance, data.relativeTolerance()) - << "Distance computed by the neighborhood search does not match."; + << "Distance computed by the neighborhood search does not match."; if (selfPairs) { - searchPair = NeighborhoodSearchTestData::RefPair(testIndex, 0.0); - const auto otherRefPair - = std::lower_bound(refPairs[refIndex].begin(), refPairs[refIndex].end(), - searchPair); + searchPair = NeighborhoodSearchTestData::RefPair(testIndex, 0.0); + const auto otherRefPair = std::lower_bound(refPairs[refIndex].begin(), + refPairs[refIndex].end(), searchPair); GMX_RELEASE_ASSERT(otherRefPair != refPairs[refIndex].end(), "Precomputed reference data is not symmetric"); otherRefPair->bFound = true; @@ -681,11 +646,10 @@ void NeighborhoodSearchTest::testPairSearchFull( } } - for (auto &entry : refPairs) + for (auto& entry : refPairs) { const int testIndex = entry.first; - checkAllPairsFound(entry.second, data.refPos_, testIndex, - data.testPositions_[testIndex].x); + checkAllPairsFound(entry.second, data.refPos_, testIndex, data.testPositions_[testIndex].x); } } @@ -695,229 +659,229 @@ void NeighborhoodSearchTest::testPairSearchFull( class TrivialTestData { - public: - static const NeighborhoodSearchTestData &get() - { - static TrivialTestData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static TrivialTestData singleton; + return singleton.data_; + } - TrivialTestData() : data_(12345, 1.0) - { - // Make the box so small we are virtually guaranteed to have - // several neighbors for the five test positions - data_.box_[XX][XX] = 3.0; - data_.box_[YY][YY] = 3.0; - data_.box_[ZZ][ZZ] = 3.0; - data_.generateRandomRefPositions(10); - data_.generateRandomTestPositions(5); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferences(&data_.pbc_); - } + TrivialTestData() : data_(12345, 1.0) + { + // Make the box so small we are virtually guaranteed to have + // several neighbors for the five test positions + data_.box_[XX][XX] = 3.0; + data_.box_[YY][YY] = 3.0; + data_.box_[ZZ][ZZ] = 3.0; + data_.generateRandomRefPositions(10); + data_.generateRandomTestPositions(5); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class TrivialSelfPairsTestData { - public: - static const NeighborhoodSearchTestData &get() - { - static TrivialSelfPairsTestData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static TrivialSelfPairsTestData singleton; + return singleton.data_; + } - TrivialSelfPairsTestData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 3.0; - data_.box_[YY][YY] = 3.0; - data_.box_[ZZ][ZZ] = 3.0; - data_.generateRandomRefPositions(20); - data_.useRefPositionsAsTestPositions(); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferences(&data_.pbc_); - } + TrivialSelfPairsTestData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 3.0; + data_.box_[YY][YY] = 3.0; + data_.box_[ZZ][ZZ] = 3.0; + data_.generateRandomRefPositions(20); + data_.useRefPositionsAsTestPositions(); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class TrivialNoPBCTestData { - public: - static const NeighborhoodSearchTestData &get() - { - static TrivialNoPBCTestData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static TrivialNoPBCTestData singleton; + return singleton.data_; + } - TrivialNoPBCTestData() : data_(12345, 1.0) - { - data_.generateRandomRefPositions(10); - data_.generateRandomTestPositions(5); - data_.computeReferences(nullptr); - } + TrivialNoPBCTestData() : data_(12345, 1.0) + { + data_.generateRandomRefPositions(10); + data_.generateRandomTestPositions(5); + data_.computeReferences(nullptr); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomBoxFullPBCData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomBoxFullPBCData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomBoxFullPBCData singleton; + return singleton.data_; + } - RandomBoxFullPBCData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 10.0; - data_.box_[YY][YY] = 5.0; - data_.box_[ZZ][ZZ] = 7.0; - // TODO: Consider whether manually picking some positions would give better - // test coverage. - data_.generateRandomRefPositions(1000); - data_.generateRandomTestPositions(100); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferences(&data_.pbc_); - } + RandomBoxFullPBCData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 10.0; + data_.box_[YY][YY] = 5.0; + data_.box_[ZZ][ZZ] = 7.0; + // TODO: Consider whether manually picking some positions would give better + // test coverage. + data_.generateRandomRefPositions(1000); + data_.generateRandomTestPositions(100); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomBoxSelfPairsData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomBoxSelfPairsData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomBoxSelfPairsData singleton; + return singleton.data_; + } - RandomBoxSelfPairsData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 10.0; - data_.box_[YY][YY] = 5.0; - data_.box_[ZZ][ZZ] = 7.0; - data_.generateRandomRefPositions(1000); - data_.useRefPositionsAsTestPositions(); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferences(&data_.pbc_); - } + RandomBoxSelfPairsData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 10.0; + data_.box_[YY][YY] = 5.0; + data_.box_[ZZ][ZZ] = 7.0; + data_.generateRandomRefPositions(1000); + data_.useRefPositionsAsTestPositions(); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomBoxXYFullPBCData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomBoxXYFullPBCData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomBoxXYFullPBCData singleton; + return singleton.data_; + } - RandomBoxXYFullPBCData() : data_(54321, 1.0) - { - data_.box_[XX][XX] = 10.0; - data_.box_[YY][YY] = 5.0; - data_.box_[ZZ][ZZ] = 7.0; - // TODO: Consider whether manually picking some positions would give better - // test coverage. - data_.generateRandomRefPositions(1000); - data_.generateRandomTestPositions(100); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferencesXY(&data_.pbc_); - } + RandomBoxXYFullPBCData() : data_(54321, 1.0) + { + data_.box_[XX][XX] = 10.0; + data_.box_[YY][YY] = 5.0; + data_.box_[ZZ][ZZ] = 7.0; + // TODO: Consider whether manually picking some positions would give better + // test coverage. + data_.generateRandomRefPositions(1000); + data_.generateRandomTestPositions(100); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferencesXY(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomTriclinicFullPBCData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomTriclinicFullPBCData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomTriclinicFullPBCData singleton; + return singleton.data_; + } - RandomTriclinicFullPBCData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 5.0; - data_.box_[YY][XX] = 2.5; - data_.box_[YY][YY] = 2.5*std::sqrt(3.0); - data_.box_[ZZ][XX] = 2.5; - data_.box_[ZZ][YY] = 2.5*std::sqrt(1.0/3.0); - data_.box_[ZZ][ZZ] = 5.0*std::sqrt(2.0/3.0); - // TODO: Consider whether manually picking some positions would give better - // test coverage. - data_.generateRandomRefPositions(1000); - data_.generateRandomTestPositions(100); - set_pbc(&data_.pbc_, epbcXYZ, data_.box_); - data_.computeReferences(&data_.pbc_); - } + RandomTriclinicFullPBCData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 5.0; + data_.box_[YY][XX] = 2.5; + data_.box_[YY][YY] = 2.5 * std::sqrt(3.0); + data_.box_[ZZ][XX] = 2.5; + data_.box_[ZZ][YY] = 2.5 * std::sqrt(1.0 / 3.0); + data_.box_[ZZ][ZZ] = 5.0 * std::sqrt(2.0 / 3.0); + // TODO: Consider whether manually picking some positions would give better + // test coverage. + data_.generateRandomRefPositions(1000); + data_.generateRandomTestPositions(100); + set_pbc(&data_.pbc_, epbcXYZ, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomBox2DPBCData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomBox2DPBCData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomBox2DPBCData singleton; + return singleton.data_; + } - RandomBox2DPBCData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 10.0; - data_.box_[YY][YY] = 7.0; - data_.box_[ZZ][ZZ] = 5.0; - // TODO: Consider whether manually picking some positions would give better - // test coverage. - data_.generateRandomRefPositions(1000); - data_.generateRandomTestPositions(100); - set_pbc(&data_.pbc_, epbcXY, data_.box_); - data_.computeReferences(&data_.pbc_); - } + RandomBox2DPBCData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 10.0; + data_.box_[YY][YY] = 7.0; + data_.box_[ZZ][ZZ] = 5.0; + // TODO: Consider whether manually picking some positions would give better + // test coverage. + data_.generateRandomRefPositions(1000); + data_.generateRandomTestPositions(100); + set_pbc(&data_.pbc_, epbcXY, data_.box_); + data_.computeReferences(&data_.pbc_); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; class RandomBoxNoPBCData { - public: - static const NeighborhoodSearchTestData &get() - { - static RandomBoxNoPBCData singleton; - return singleton.data_; - } +public: + static const NeighborhoodSearchTestData& get() + { + static RandomBoxNoPBCData singleton; + return singleton.data_; + } - RandomBoxNoPBCData() : data_(12345, 1.0) - { - data_.box_[XX][XX] = 10.0; - data_.box_[YY][YY] = 5.0; - data_.box_[ZZ][ZZ] = 7.0; - // TODO: Consider whether manually picking some positions would give better - // test coverage. - data_.generateRandomRefPositions(1000); - data_.generateRandomTestPositions(100); - set_pbc(&data_.pbc_, epbcNONE, data_.box_); - data_.computeReferences(nullptr); - } + RandomBoxNoPBCData() : data_(12345, 1.0) + { + data_.box_[XX][XX] = 10.0; + data_.box_[YY][YY] = 5.0; + data_.box_[ZZ][ZZ] = 7.0; + // TODO: Consider whether manually picking some positions would give better + // test coverage. + data_.generateRandomRefPositions(1000); + data_.generateRandomTestPositions(100); + set_pbc(&data_.pbc_, epbcNONE, data_.box_); + data_.computeReferences(nullptr); + } - private: - NeighborhoodSearchTestData data_; +private: + NeighborhoodSearchTestData data_; }; /******************************************************************** @@ -926,12 +890,11 @@ class RandomBoxNoPBCData TEST_F(NeighborhoodSearchTest, SimpleSearch) { - const NeighborhoodSearchTestData &data = RandomBoxFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxFullPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Simple); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); testIsWithin(&search, data); @@ -945,13 +908,12 @@ TEST_F(NeighborhoodSearchTest, SimpleSearch) TEST_F(NeighborhoodSearchTest, SimpleSearchXY) { - const NeighborhoodSearchTestData &data = RandomBoxXYFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxXYFullPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Simple); nb_.setXYMode(true); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); testIsWithin(&search, data); @@ -962,12 +924,11 @@ TEST_F(NeighborhoodSearchTest, SimpleSearchXY) TEST_F(NeighborhoodSearchTest, GridSearchBox) { - const NeighborhoodSearchTestData &data = RandomBoxFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxFullPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); testIsWithin(&search, data); @@ -981,12 +942,11 @@ TEST_F(NeighborhoodSearchTest, GridSearchBox) TEST_F(NeighborhoodSearchTest, GridSearchTriclinic) { - const NeighborhoodSearchTestData &data = RandomTriclinicFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomTriclinicFullPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); testPairSearch(&search, data); @@ -994,12 +954,11 @@ TEST_F(NeighborhoodSearchTest, GridSearchTriclinic) TEST_F(NeighborhoodSearchTest, GridSearch2DPBC) { - const NeighborhoodSearchTestData &data = RandomBox2DPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBox2DPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); testIsWithin(&search, data); @@ -1010,12 +969,11 @@ TEST_F(NeighborhoodSearchTest, GridSearch2DPBC) TEST_F(NeighborhoodSearchTest, GridSearchNoPBC) { - const NeighborhoodSearchTestData &data = RandomBoxNoPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxNoPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); testPairSearch(&search, data); @@ -1023,13 +981,12 @@ TEST_F(NeighborhoodSearchTest, GridSearchNoPBC) TEST_F(NeighborhoodSearchTest, GridSearchXYBox) { - const NeighborhoodSearchTestData &data = RandomBoxXYFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxXYFullPBCData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); nb_.setXYMode(true); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); testIsWithin(&search, data); @@ -1040,55 +997,47 @@ TEST_F(NeighborhoodSearchTest, GridSearchXYBox) TEST_F(NeighborhoodSearchTest, SimpleSelfPairsSearch) { - const NeighborhoodSearchTestData &data = TrivialSelfPairsTestData::get(); + const NeighborhoodSearchTestData& data = TrivialSelfPairsTestData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Simple); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); - testPairSearchFull(&search, data, data.testPositions(), nullptr, - {}, {}, true); + testPairSearchFull(&search, data, data.testPositions(), nullptr, {}, {}, true); } TEST_F(NeighborhoodSearchTest, GridSelfPairsSearch) { - const NeighborhoodSearchTestData &data = RandomBoxSelfPairsData::get(); + const NeighborhoodSearchTestData& data = RandomBoxSelfPairsData::get(); nb_.setCutoff(data.cutoff_); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); - testPairSearchFull(&search, data, data.testPositions(), nullptr, - {}, {}, true); + testPairSearchFull(&search, data, data.testPositions(), nullptr, {}, {}, true); } TEST_F(NeighborhoodSearchTest, HandlesConcurrentSearches) { - const NeighborhoodSearchTestData &data = TrivialTestData::get(); + const NeighborhoodSearchTestData& data = TrivialTestData::get(); nb_.setCutoff(data.cutoff_); - gmx::AnalysisNeighborhoodSearch search1 = - nb_.initSearch(&data.pbc_, data.refPositions()); - gmx::AnalysisNeighborhoodSearch search2 = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search1 = nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search2 = nb_.initSearch(&data.pbc_, data.refPositions()); // These checks are fragile, and unfortunately depend on the random // engine used to create the test positions. There is no particular reason // why exactly particles 0 & 2 should have neighbors, but in this case they do. - gmx::AnalysisNeighborhoodPairSearch pairSearch1 = - search1.startPairSearch(data.testPosition(0)); - gmx::AnalysisNeighborhoodPairSearch pairSearch2 = - search1.startPairSearch(data.testPosition(2)); + gmx::AnalysisNeighborhoodPairSearch pairSearch1 = search1.startPairSearch(data.testPosition(0)); + gmx::AnalysisNeighborhoodPairSearch pairSearch2 = search1.startPairSearch(data.testPosition(2)); testPairSearch(&search2, data); gmx::AnalysisNeighborhoodPair pair; ASSERT_TRUE(pairSearch1.findNextPair(&pair)) - << "Test data did not contain any pairs for position 0 (problem in the test)."; + << "Test data did not contain any pairs for position 0 (problem in the test)."; EXPECT_EQ(0, pair.testIndex()); { NeighborhoodSearchTestData::RefPair searchPair(pair.refIndex(), std::sqrt(pair.distance2())); @@ -1096,7 +1045,7 @@ TEST_F(NeighborhoodSearchTest, HandlesConcurrentSearches) } ASSERT_TRUE(pairSearch2.findNextPair(&pair)) - << "Test data did not contain any pairs for position 2 (problem in the test)."; + << "Test data did not contain any pairs for position 2 (problem in the test)."; EXPECT_EQ(2, pair.testIndex()); { NeighborhoodSearchTestData::RefPair searchPair(pair.refIndex(), std::sqrt(pair.distance2())); @@ -1106,11 +1055,10 @@ TEST_F(NeighborhoodSearchTest, HandlesConcurrentSearches) TEST_F(NeighborhoodSearchTest, HandlesNoPBC) { - const NeighborhoodSearchTestData &data = TrivialNoPBCTestData::get(); + const NeighborhoodSearchTestData& data = TrivialNoPBCTestData::get(); nb_.setCutoff(data.cutoff_); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); testIsWithin(&search, data); @@ -1121,11 +1069,10 @@ TEST_F(NeighborhoodSearchTest, HandlesNoPBC) TEST_F(NeighborhoodSearchTest, HandlesNullPBC) { - const NeighborhoodSearchTestData &data = TrivialNoPBCTestData::get(); + const NeighborhoodSearchTestData& data = TrivialNoPBCTestData::get(); nb_.setCutoff(data.cutoff_); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(nullptr, data.refPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(nullptr, data.refPositions()); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); testIsWithin(&search, data); @@ -1136,13 +1083,11 @@ TEST_F(NeighborhoodSearchTest, HandlesNullPBC) TEST_F(NeighborhoodSearchTest, HandlesSkippingPairs) { - const NeighborhoodSearchTestData &data = TrivialTestData::get(); + const NeighborhoodSearchTestData& data = TrivialTestData::get(); nb_.setCutoff(data.cutoff_); - gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, data.refPositions()); - gmx::AnalysisNeighborhoodPairSearch pairSearch = - search.startPairSearch(data.testPositions()); + gmx::AnalysisNeighborhoodSearch search = nb_.initSearch(&data.pbc_, data.refPositions()); + gmx::AnalysisNeighborhoodPairSearch pairSearch = search.startPairSearch(data.testPositions()); gmx::AnalysisNeighborhoodPair pair; // TODO: This test needs to be adjusted if the grid search gets optimized // to loop over the test positions in cell order (first, the ordering @@ -1165,44 +1110,38 @@ TEST_F(NeighborhoodSearchTest, HandlesSkippingPairs) TEST_F(NeighborhoodSearchTest, SimpleSearchExclusions) { - const NeighborhoodSearchTestData &data = RandomBoxFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxFullPBCData::get(); - ExclusionsHelper helper(data.refPosCount_, data.testPositions_.size()); + ExclusionsHelper helper(data.refPosCount_, data.testPositions_.size()); helper.generateExclusions(); nb_.setCutoff(data.cutoff_); nb_.setTopologyExclusions(helper.exclusions()); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Simple); gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, - data.refPositions().exclusionIds(helper.refPosIds())); + nb_.initSearch(&data.pbc_, data.refPositions().exclusionIds(helper.refPosIds())); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Simple, search.mode()); - testPairSearchFull(&search, data, - data.testPositions().exclusionIds(helper.testPosIds()), - helper.exclusions(), {}, - {}, false); + testPairSearchFull(&search, data, data.testPositions().exclusionIds(helper.testPosIds()), + helper.exclusions(), {}, {}, false); } TEST_F(NeighborhoodSearchTest, GridSearchExclusions) { - const NeighborhoodSearchTestData &data = RandomBoxFullPBCData::get(); + const NeighborhoodSearchTestData& data = RandomBoxFullPBCData::get(); - ExclusionsHelper helper(data.refPosCount_, data.testPositions_.size()); + ExclusionsHelper helper(data.refPosCount_, data.testPositions_.size()); helper.generateExclusions(); nb_.setCutoff(data.cutoff_); nb_.setTopologyExclusions(helper.exclusions()); nb_.setMode(gmx::AnalysisNeighborhood::eSearchMode_Grid); gmx::AnalysisNeighborhoodSearch search = - nb_.initSearch(&data.pbc_, - data.refPositions().exclusionIds(helper.refPosIds())); + nb_.initSearch(&data.pbc_, data.refPositions().exclusionIds(helper.refPosIds())); ASSERT_EQ(gmx::AnalysisNeighborhood::eSearchMode_Grid, search.mode()); - testPairSearchFull(&search, data, - data.testPositions().exclusionIds(helper.testPosIds()), - helper.exclusions(), {}, - {}, false); + testPairSearchFull(&search, data, data.testPositions().exclusionIds(helper.testPosIds()), + helper.exclusions(), {}, {}, false); } } // namespace diff --git a/src/gromacs/selection/tests/poscalc.cpp b/src/gromacs/selection/tests/poscalc.cpp index 89348c8e59..37ac153d63 100644 --- a/src/gromacs/selection/tests/poscalc.cpp +++ b/src/gromacs/selection/tests/poscalc.cpp @@ -69,72 +69,75 @@ namespace class PositionCalculationTest : public ::testing::Test { - public: - PositionCalculationTest(); - ~PositionCalculationTest() override; - - void generateCoordinates(); - - gmx_ana_poscalc_t *createCalculation(e_poscalc_t type, int flags); - void setMaximumGroup(gmx_ana_poscalc_t *pc, const gmx::ArrayRef &atoms); - gmx_ana_pos_t *initPositions(gmx_ana_poscalc_t *pc, const char *name); - - void checkInitialized(); - void updateAndCheck(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, - const gmx::ArrayRef &atoms, - gmx::test::TestReferenceChecker *checker, - const char *name); - - void testSingleStatic(e_poscalc_t type, int flags, bool bExpectTop, - const gmx::ArrayRef &atoms, - const gmx::ArrayRef &index = {}); - void testSingleDynamic(e_poscalc_t type, int flags, bool bExpectTop, - const gmx::ArrayRef &initAtoms, - const gmx::ArrayRef &evalAtoms, - const gmx::ArrayRef &index = {}); - - gmx::test::TestReferenceData data_; - gmx::test::TestReferenceChecker checker_; - gmx::test::TopologyManager topManager_; - gmx::PositionCalculationCollection pcc_; - - private: - typedef std::unique_ptr PositionPointer; - - struct PositionTest +public: + PositionCalculationTest(); + ~PositionCalculationTest() override; + + void generateCoordinates(); + + gmx_ana_poscalc_t* createCalculation(e_poscalc_t type, int flags); + void setMaximumGroup(gmx_ana_poscalc_t* pc, const gmx::ArrayRef& atoms); + gmx_ana_pos_t* initPositions(gmx_ana_poscalc_t* pc, const char* name); + + void checkInitialized(); + void updateAndCheck(gmx_ana_poscalc_t* pc, + gmx_ana_pos_t* p, + const gmx::ArrayRef& atoms, + gmx::test::TestReferenceChecker* checker, + const char* name); + + void testSingleStatic(e_poscalc_t type, + int flags, + bool bExpectTop, + const gmx::ArrayRef& atoms, + const gmx::ArrayRef& index = {}); + void testSingleDynamic(e_poscalc_t type, + int flags, + bool bExpectTop, + const gmx::ArrayRef& initAtoms, + const gmx::ArrayRef& evalAtoms, + const gmx::ArrayRef& index = {}); + + gmx::test::TestReferenceData data_; + gmx::test::TestReferenceChecker checker_; + gmx::test::TopologyManager topManager_; + gmx::PositionCalculationCollection pcc_; + +private: + typedef std::unique_ptr PositionPointer; + + struct PositionTest + { + PositionTest(PositionPointer pos, gmx_ana_poscalc_t* pc, const char* name) : + pos(std::move(pos)), + pc(pc), + name(name) { - PositionTest(PositionPointer pos, gmx_ana_poscalc_t *pc, - const char *name) - : pos(std::move(pos)), pc(pc), name(name) - { - } - - PositionPointer pos; - gmx_ana_poscalc_t *pc; - const char *name; - }; - - typedef std::vector PositionTestList; - - void setTopologyIfRequired(); - void checkPositions(gmx::test::TestReferenceChecker *checker, - const char *name, gmx_ana_pos_t *p, - bool bCoordinates); - - std::vector pcList_; - PositionTestList posList_; - bool bTopSet_; + } + + PositionPointer pos; + gmx_ana_poscalc_t* pc; + const char* name; + }; + + typedef std::vector PositionTestList; + + void setTopologyIfRequired(); + void checkPositions(gmx::test::TestReferenceChecker* checker, const char* name, gmx_ana_pos_t* p, bool bCoordinates); + + std::vector pcList_; + PositionTestList posList_; + bool bTopSet_; }; -PositionCalculationTest::PositionCalculationTest() - : checker_(data_.rootChecker()), bTopSet_(false) +PositionCalculationTest::PositionCalculationTest() : checker_(data_.rootChecker()), bTopSet_(false) { topManager_.requestFrame(); } PositionCalculationTest::~PositionCalculationTest() { - std::vector::reverse_iterator pci; + std::vector::reverse_iterator pci; for (pci = pcList_.rbegin(); pci != pcList_.rend(); ++pci) { gmx_ana_poscalc_free(*pci); @@ -143,8 +146,8 @@ PositionCalculationTest::~PositionCalculationTest() void PositionCalculationTest::generateCoordinates() { - t_atoms &atoms = topManager_.atoms(); - t_trxframe *frame = topManager_.frame(); + t_atoms& atoms = topManager_.atoms(); + t_trxframe* frame = topManager_.frame(); for (int i = 0; i < atoms.nr; ++i) { frame->x[i][XX] = i; @@ -163,30 +166,27 @@ void PositionCalculationTest::generateCoordinates() } } -gmx_ana_poscalc_t * -PositionCalculationTest::createCalculation(e_poscalc_t type, int flags) +gmx_ana_poscalc_t* PositionCalculationTest::createCalculation(e_poscalc_t type, int flags) { pcList_.reserve(pcList_.size() + 1); pcList_.push_back(pcc_.createCalculation(type, flags)); return pcList_.back(); } -void PositionCalculationTest::setMaximumGroup(gmx_ana_poscalc_t *pc, - const gmx::ArrayRef &atoms) +void PositionCalculationTest::setMaximumGroup(gmx_ana_poscalc_t* pc, const gmx::ArrayRef& atoms) { setTopologyIfRequired(); gmx_ana_index_t g; g.isize = atoms.size(); - g.index = const_cast(atoms.data()); + g.index = const_cast(atoms.data()); gmx_ana_poscalc_set_maxindex(pc, &g); } -gmx_ana_pos_t * -PositionCalculationTest::initPositions(gmx_ana_poscalc_t *pc, const char *name) +gmx_ana_pos_t* PositionCalculationTest::initPositions(gmx_ana_poscalc_t* pc, const char* name) { posList_.reserve(posList_.size() + 1); PositionPointer p(new gmx_ana_pos_t()); - gmx_ana_pos_t *result = p.get(); + gmx_ana_pos_t* result = p.get(); posList_.emplace_back(std::move(p), pc, name); gmx_ana_poscalc_init_pos(pc, result); return result; @@ -194,8 +194,7 @@ PositionCalculationTest::initPositions(gmx_ana_poscalc_t *pc, const char *name) void PositionCalculationTest::checkInitialized() { - gmx::test::TestReferenceChecker compound( - checker_.checkCompound("InitializedPositions", nullptr)); + gmx::test::TestReferenceChecker compound(checker_.checkCompound("InitializedPositions", nullptr)); PositionTestList::const_iterator pi; for (pi = posList_.begin(); pi != posList_.end(); ++pi) { @@ -203,23 +202,26 @@ void PositionCalculationTest::checkInitialized() } } -void PositionCalculationTest::updateAndCheck( - gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p, const gmx::ArrayRef &atoms, - gmx::test::TestReferenceChecker *checker, const char *name) +void PositionCalculationTest::updateAndCheck(gmx_ana_poscalc_t* pc, + gmx_ana_pos_t* p, + const gmx::ArrayRef& atoms, + gmx::test::TestReferenceChecker* checker, + const char* name) { gmx_ana_index_t g; g.isize = atoms.size(); - g.index = const_cast(atoms.data()); + g.index = const_cast(atoms.data()); gmx_ana_poscalc_update(pc, p, &g, topManager_.frame(), nullptr); checkPositions(checker, name, p, true); } -void PositionCalculationTest::testSingleStatic( - e_poscalc_t type, int flags, bool bExpectTop, - const gmx::ArrayRef &atoms, - const gmx::ArrayRef &index) +void PositionCalculationTest::testSingleStatic(e_poscalc_t type, + int flags, + bool bExpectTop, + const gmx::ArrayRef& atoms, + const gmx::ArrayRef& index) { - t_trxframe *frame = topManager_.frame(); + t_trxframe* frame = topManager_.frame(); if (frame->bV) { flags |= POS_VELOCITIES; @@ -228,13 +230,12 @@ void PositionCalculationTest::testSingleStatic( { flags |= POS_FORCES; } - gmx_ana_poscalc_t *pc = createCalculation(type, flags); - const bool requiresTopology - = gmx_ana_poscalc_required_topology_info(pc) - != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; + gmx_ana_poscalc_t* pc = createCalculation(type, flags); + const bool requiresTopology = gmx_ana_poscalc_required_topology_info(pc) + != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; EXPECT_EQ(bExpectTop, requiresTopology); setMaximumGroup(pc, atoms); - gmx_ana_pos_t *p = initPositions(pc, nullptr); + gmx_ana_pos_t* p = initPositions(pc, nullptr); checkInitialized(); { generateCoordinates(); @@ -250,19 +251,19 @@ void PositionCalculationTest::testSingleStatic( } } -void PositionCalculationTest::testSingleDynamic( - e_poscalc_t type, int flags, bool bExpectTop, - const gmx::ArrayRef &initAtoms, - const gmx::ArrayRef &evalAtoms, - const gmx::ArrayRef &index) +void PositionCalculationTest::testSingleDynamic(e_poscalc_t type, + int flags, + bool bExpectTop, + const gmx::ArrayRef& initAtoms, + const gmx::ArrayRef& evalAtoms, + const gmx::ArrayRef& index) { - gmx_ana_poscalc_t *pc = createCalculation(type, flags | POS_DYNAMIC); - const bool requiresTopology - = gmx_ana_poscalc_required_topology_info(pc) - != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; + gmx_ana_poscalc_t* pc = createCalculation(type, flags | POS_DYNAMIC); + const bool requiresTopology = gmx_ana_poscalc_required_topology_info(pc) + != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; EXPECT_EQ(bExpectTop, requiresTopology); setMaximumGroup(pc, initAtoms); - gmx_ana_pos_t *p = initPositions(pc, nullptr); + gmx_ana_pos_t* p = initPositions(pc, nullptr); checkInitialized(); { generateCoordinates(); @@ -284,12 +285,11 @@ void PositionCalculationTest::setTopologyIfRequired() { return; } - std::vector::const_iterator pci; + std::vector::const_iterator pci; for (pci = pcList_.begin(); pci != pcList_.end(); ++pci) { - const bool requiresTopology - = gmx_ana_poscalc_required_topology_info(*pci) - != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; + const bool requiresTopology = gmx_ana_poscalc_required_topology_info(*pci) + != gmx::PositionCalculationCollection::RequiredTopologyInfo::None; if (requiresTopology) { bTopSet_ = true; @@ -299,31 +299,29 @@ void PositionCalculationTest::setTopologyIfRequired() } } -void PositionCalculationTest::checkPositions( - gmx::test::TestReferenceChecker *checker, - const char *name, gmx_ana_pos_t *p, bool bCoordinates) +void PositionCalculationTest::checkPositions(gmx::test::TestReferenceChecker* checker, + const char* name, + gmx_ana_pos_t* p, + bool bCoordinates) { - gmx::test::TestReferenceChecker compound( - checker->checkCompound("Positions", name)); + gmx::test::TestReferenceChecker compound(checker->checkCompound("Positions", name)); compound.checkInteger(p->count(), "Count"); - const char *type = "???"; + const char* type = "???"; switch (p->m.type) { - case INDEX_UNKNOWN: type = "unknown"; break; - case INDEX_ATOM: type = "atoms"; break; - case INDEX_RES: type = "residues"; break; - case INDEX_MOL: type = "molecules"; break; - case INDEX_ALL: type = "single"; break; + case INDEX_UNKNOWN: type = "unknown"; break; + case INDEX_ATOM: type = "atoms"; break; + case INDEX_RES: type = "residues"; break; + case INDEX_MOL: type = "molecules"; break; + case INDEX_ALL: type = "single"; break; } compound.checkString(type, "Type"); compound.checkSequenceArray(p->count() + 1, p->m.mapb.index, "Block"); for (int i = 0; i < p->count(); ++i) { - gmx::test::TestReferenceChecker posCompound( - compound.checkCompound("Position", nullptr)); + gmx::test::TestReferenceChecker posCompound(compound.checkCompound("Position", nullptr)); posCompound.checkSequence(&p->m.mapb.a[p->m.mapb.index[i]], - &p->m.mapb.a[p->m.mapb.index[i+1]], - "Atoms"); + &p->m.mapb.a[p->m.mapb.index[i + 1]], "Atoms"); posCompound.checkInteger(p->m.refid[i], "RefId"); if (bCoordinates) { @@ -442,15 +440,15 @@ TEST_F(PositionCalculationTest, HandlesIdenticalStaticCalculations) topManager_.initAtoms(9); topManager_.initUniformResidues(3); - gmx_ana_poscalc_t *pc1 = createCalculation(POS_RES, 0); - gmx_ana_poscalc_t *pc2 = createCalculation(POS_RES, 0); - gmx_ana_poscalc_t *pc3 = createCalculation(POS_RES, 0); + gmx_ana_poscalc_t* pc1 = createCalculation(POS_RES, 0); + gmx_ana_poscalc_t* pc2 = createCalculation(POS_RES, 0); + gmx_ana_poscalc_t* pc3 = createCalculation(POS_RES, 0); setMaximumGroup(pc1, group); setMaximumGroup(pc2, group); setMaximumGroup(pc3, group); - gmx_ana_pos_t *p1 = initPositions(pc1, "Positions"); - gmx_ana_pos_t *p2 = initPositions(pc2, "Positions"); - gmx_ana_pos_t *p3 = initPositions(pc3, "Positions"); + gmx_ana_pos_t* p1 = initPositions(pc1, "Positions"); + gmx_ana_pos_t* p2 = initPositions(pc2, "Positions"); + gmx_ana_pos_t* p3 = initPositions(pc3, "Positions"); checkInitialized(); { generateCoordinates(); @@ -471,12 +469,12 @@ TEST_F(PositionCalculationTest, HandlesOverlappingStaticCalculations) topManager_.initAtoms(9); topManager_.initUniformResidues(3); - gmx_ana_poscalc_t *pc1 = createCalculation(POS_RES, 0); - gmx_ana_poscalc_t *pc2 = createCalculation(POS_RES, 0); + gmx_ana_poscalc_t* pc1 = createCalculation(POS_RES, 0); + gmx_ana_poscalc_t* pc2 = createCalculation(POS_RES, 0); setMaximumGroup(pc1, group1); setMaximumGroup(pc2, group2); - gmx_ana_pos_t *p1 = initPositions(pc1, "P1"); - gmx_ana_pos_t *p2 = initPositions(pc2, "P2"); + gmx_ana_pos_t* p1 = initPositions(pc1, "P1"); + gmx_ana_pos_t* p2 = initPositions(pc2, "P2"); checkInitialized(); { generateCoordinates(); diff --git a/src/gromacs/selection/tests/selectioncollection.cpp b/src/gromacs/selection/tests/selectioncollection.cpp index cc484f181b..94484badc2 100644 --- a/src/gromacs/selection/tests/selectioncollection.cpp +++ b/src/gromacs/selection/tests/selectioncollection.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,24 +74,21 @@ namespace class SelectionCollectionTest : public ::testing::Test { - public: - static int s_debugLevel; +public: + static int s_debugLevel; - SelectionCollectionTest(); - ~SelectionCollectionTest() override; + SelectionCollectionTest(); + ~SelectionCollectionTest() override; - void setAtomCount(int natoms) - { - ASSERT_NO_THROW_GMX(sc_.setTopology(nullptr, natoms)); - } - void loadTopology(const char *filename); - void setTopology(); - void loadIndexGroups(const char *filename); - - gmx::test::TopologyManager topManager_; - gmx::SelectionCollection sc_; - gmx::SelectionList sel_; - gmx_ana_indexgrps_t *grps_; + void setAtomCount(int natoms) { ASSERT_NO_THROW_GMX(sc_.setTopology(nullptr, natoms)); } + void loadTopology(const char* filename); + void setTopology(); + void loadIndexGroups(const char* filename); + + gmx::test::TopologyManager topManager_; + gmx::SelectionCollection sc_; + gmx::SelectionList sel_; + gmx_ana_indexgrps_t* grps_; }; int SelectionCollectionTest::s_debugLevel = 0; @@ -100,13 +98,12 @@ int SelectionCollectionTest::s_debugLevel = 0; GMX_TEST_OPTIONS(SelectionCollectionTestOptions, options) { options->addOption(gmx::IntegerOption("seldebug") - .store(&SelectionCollectionTest::s_debugLevel) - .description("Set selection debug level")); + .store(&SelectionCollectionTest::s_debugLevel) + .description("Set selection debug level")); } #endif -SelectionCollectionTest::SelectionCollectionTest() - : grps_(nullptr) +SelectionCollectionTest::SelectionCollectionTest() : grps_(nullptr) { topManager_.requestFrame(); sc_.setDebugLevel(s_debugLevel); @@ -122,26 +119,21 @@ SelectionCollectionTest::~SelectionCollectionTest() } } -void -SelectionCollectionTest::loadTopology(const char *filename) +void SelectionCollectionTest::loadTopology(const char* filename) { topManager_.loadTopology(filename); setTopology(); } -void -SelectionCollectionTest::setTopology() +void SelectionCollectionTest::setTopology() { ASSERT_NO_THROW_GMX(sc_.setTopology(topManager_.topology(), -1)); } -void -SelectionCollectionTest::loadIndexGroups(const char *filename) +void SelectionCollectionTest::loadIndexGroups(const char* filename) { - GMX_RELEASE_ASSERT(grps_ == nullptr, - "External groups can only be loaded once"); - std::string fullpath = - gmx::test::TestFileManager::getInputFilePath(filename); + GMX_RELEASE_ASSERT(grps_ == nullptr, "External groups can only be loaded once"); + std::string fullpath = gmx::test::TestFileManager::getInputFilePath(filename); gmx_ana_indexgrps_init(&grps_, nullptr, fullpath.c_str()); sc_.setIndexGroups(grps_); } @@ -153,29 +145,24 @@ SelectionCollectionTest::loadIndexGroups(const char *filename) class SelectionCollectionInteractiveTest : public SelectionCollectionTest { - public: - SelectionCollectionInteractiveTest() - : helper_(data_.rootChecker()) - { - } +public: + SelectionCollectionInteractiveTest() : helper_(data_.rootChecker()) {} - void runTest(int count, bool bInteractive, - const gmx::ArrayRef &input); + void runTest(int count, bool bInteractive, const gmx::ArrayRef& input); - gmx::test::TestReferenceData data_; - gmx::test::InteractiveTestHelper helper_; + gmx::test::TestReferenceData data_; + gmx::test::InteractiveTestHelper helper_; }; -void SelectionCollectionInteractiveTest::runTest( - int count, bool bInteractive, - const gmx::ArrayRef &inputLines) +void SelectionCollectionInteractiveTest::runTest(int count, + bool bInteractive, + const gmx::ArrayRef& inputLines) { helper_.setInputLines(inputLines); // TODO: Check something about the returned selections as well. - ASSERT_NO_THROW_GMX(sc_.parseInteractive( - count, &helper_.inputStream(), - bInteractive ? &helper_.outputStream() : nullptr, - "for test context")); + ASSERT_NO_THROW_GMX(sc_.parseInteractive(count, &helper_.inputStream(), + bInteractive ? &helper_.outputStream() : nullptr, + "for test context")); helper_.checkSession(); } @@ -186,55 +173,50 @@ void SelectionCollectionInteractiveTest::runTest( class SelectionCollectionDataTest : public SelectionCollectionTest { - public: - enum TestFlag - { - efTestEvaluation = 1<<0, - efTestPositionAtoms = 1<<1, - efTestPositionCoordinates = 1<<2, - efTestPositionMapping = 1<<3, - efTestPositionMasses = 1<<4, - efTestPositionCharges = 1<<5, - efTestSelectionNames = 1<<6, - efDontTestCompiledAtoms = 1<<8 - }; - typedef gmx::FlagsTemplate TestFlags; - - SelectionCollectionDataTest() - : checker_(data_.rootChecker()), count_(0), framenr_(0) - { - } +public: + enum TestFlag + { + efTestEvaluation = 1 << 0, + efTestPositionAtoms = 1 << 1, + efTestPositionCoordinates = 1 << 2, + efTestPositionMapping = 1 << 3, + efTestPositionMasses = 1 << 4, + efTestPositionCharges = 1 << 5, + efTestSelectionNames = 1 << 6, + efDontTestCompiledAtoms = 1 << 8 + }; + typedef gmx::FlagsTemplate TestFlags; + + SelectionCollectionDataTest() : checker_(data_.rootChecker()), count_(0), framenr_(0) {} - void setFlags(TestFlags flags) { flags_ = flags; } + void setFlags(TestFlags flags) { flags_ = flags; } - void runParser(const gmx::ArrayRef &selections); - void runCompiler(); - void runEvaluate(); - void runEvaluateFinal(); + void runParser(const gmx::ArrayRef& selections); + void runCompiler(); + void runEvaluate(); + void runEvaluateFinal(); - void runTest(int natoms, - const gmx::ArrayRef &selections); - void runTest(const char *filename, - const gmx::ArrayRef &selections); + void runTest(int natoms, const gmx::ArrayRef& selections); + void runTest(const char* filename, const gmx::ArrayRef& selections); - private: - static void checkSelection(gmx::test::TestReferenceChecker *checker, - const gmx::Selection &sel, TestFlags flags); +private: + static void checkSelection(gmx::test::TestReferenceChecker* checker, + const gmx::Selection& sel, + TestFlags flags); - void checkCompiled(); + void checkCompiled(); - gmx::test::TestReferenceData data_; - gmx::test::TestReferenceChecker checker_; - size_t count_; - int framenr_; - TestFlags flags_; + gmx::test::TestReferenceData data_; + gmx::test::TestReferenceChecker checker_; + size_t count_; + int framenr_; + TestFlags flags_; }; -void -SelectionCollectionDataTest::checkSelection( - gmx::test::TestReferenceChecker *checker, - const gmx::Selection &sel, TestFlags flags) +void SelectionCollectionDataTest::checkSelection(gmx::test::TestReferenceChecker* checker, + const gmx::Selection& sel, + TestFlags flags) { using gmx::test::TestReferenceChecker; @@ -242,18 +224,15 @@ SelectionCollectionDataTest::checkSelection( gmx::ArrayRef atoms = sel.atomIndices(); checker->checkSequence(atoms.begin(), atoms.end(), "Atoms"); } - if (flags.test(efTestPositionAtoms) - || flags.test(efTestPositionCoordinates) - || flags.test(efTestPositionMapping) - || flags.test(efTestPositionMasses) + if (flags.test(efTestPositionAtoms) || flags.test(efTestPositionCoordinates) + || flags.test(efTestPositionMapping) || flags.test(efTestPositionMasses) || flags.test(efTestPositionCharges)) { - TestReferenceChecker compound( - checker->checkSequenceCompound("Positions", sel.posCount())); + TestReferenceChecker compound(checker->checkSequenceCompound("Positions", sel.posCount())); for (int i = 0; i < sel.posCount(); ++i) { TestReferenceChecker poscompound(compound.checkCompound("Position", nullptr)); - const gmx::SelectionPosition &p = sel.position(i); + const gmx::SelectionPosition& p = sel.position(i); if (flags.test(efTestPositionAtoms)) { gmx::ArrayRef atoms = p.atomIndices(); @@ -281,35 +260,30 @@ SelectionCollectionDataTest::checkSelection( } -void -SelectionCollectionDataTest::runParser( - const gmx::ArrayRef &selections) +void SelectionCollectionDataTest::runParser(const gmx::ArrayRef& selections) { using gmx::test::TestReferenceChecker; TestReferenceChecker compound(checker_.checkCompound("ParsedSelections", "Parsed")); size_t varcount = 0; - count_ = 0; + count_ = 0; for (gmx::index i = 0; i < selections.ssize(); ++i) { - SCOPED_TRACE(std::string("Parsing selection \"") - + selections[i] + "\""); + SCOPED_TRACE(std::string("Parsing selection \"") + selections[i] + "\""); gmx::SelectionList result; ASSERT_NO_THROW_GMX(result = sc_.parseFromString(selections[i])); sel_.insert(sel_.end(), result.begin(), result.end()); if (sel_.size() == count_) { - std::string id = gmx::formatString("Variable%d", static_cast(varcount + 1)); - TestReferenceChecker varcompound( - compound.checkCompound("ParsedVariable", id.c_str())); + std::string id = gmx::formatString("Variable%d", static_cast(varcount + 1)); + TestReferenceChecker varcompound(compound.checkCompound("ParsedVariable", id.c_str())); varcompound.checkString(selections[i], "Input"); ++varcount; } else { - std::string id = gmx::formatString("Selection%d", static_cast(count_ + 1)); - TestReferenceChecker selcompound( - compound.checkCompound("ParsedSelection", id.c_str())); + std::string id = gmx::formatString("Selection%d", static_cast(count_ + 1)); + TestReferenceChecker selcompound(compound.checkCompound("ParsedSelection", id.c_str())); selcompound.checkString(selections[i], "Input"); if (flags_.test(efTestSelectionNames)) { @@ -323,8 +297,7 @@ SelectionCollectionDataTest::runParser( } -void -SelectionCollectionDataTest::runCompiler() +void SelectionCollectionDataTest::runCompiler() { ASSERT_NO_THROW_GMX(sc_.compile()); ASSERT_EQ(count_, sel_.size()); @@ -332,20 +305,17 @@ SelectionCollectionDataTest::runCompiler() } -void -SelectionCollectionDataTest::checkCompiled() +void SelectionCollectionDataTest::checkCompiled() { using gmx::test::TestReferenceChecker; - const TestFlags mask = ~TestFlags(efTestPositionCoordinates); + const TestFlags mask = ~TestFlags(efTestPositionCoordinates); TestReferenceChecker compound(checker_.checkCompound("CompiledSelections", "Compiled")); for (size_t i = 0; i < count_; ++i) { - SCOPED_TRACE(std::string("Checking selection \"") + - sel_[i].selectionText() + "\""); + SCOPED_TRACE(std::string("Checking selection \"") + sel_[i].selectionText() + "\""); std::string id = gmx::formatString("Selection%d", static_cast(i + 1)); - TestReferenceChecker selcompound( - compound.checkCompound("Selection", id.c_str())); + TestReferenceChecker selcompound(compound.checkCompound("Selection", id.c_str())); if (flags_.test(efTestSelectionNames)) { selcompound.checkString(sel_[i].name(), "Name"); @@ -358,39 +328,32 @@ SelectionCollectionDataTest::checkCompiled() } -void -SelectionCollectionDataTest::runEvaluate() +void SelectionCollectionDataTest::runEvaluate() { using gmx::test::TestReferenceChecker; ++framenr_; ASSERT_NO_THROW_GMX(sc_.evaluate(topManager_.frame(), nullptr)); std::string frame = gmx::formatString("Frame%d", framenr_); - TestReferenceChecker compound( - checker_.checkCompound("EvaluatedSelections", frame.c_str())); + TestReferenceChecker compound(checker_.checkCompound("EvaluatedSelections", frame.c_str())); for (size_t i = 0; i < count_; ++i) { - SCOPED_TRACE(std::string("Checking selection \"") + - sel_[i].selectionText() + "\""); + SCOPED_TRACE(std::string("Checking selection \"") + sel_[i].selectionText() + "\""); std::string id = gmx::formatString("Selection%d", static_cast(i + 1)); - TestReferenceChecker selcompound( - compound.checkCompound("Selection", id.c_str())); + TestReferenceChecker selcompound(compound.checkCompound("Selection", id.c_str())); checkSelection(&selcompound, sel_[i], flags_); } } -void -SelectionCollectionDataTest::runEvaluateFinal() +void SelectionCollectionDataTest::runEvaluateFinal() { ASSERT_NO_THROW_GMX(sc_.evaluateFinal(framenr_)); checkCompiled(); } -void -SelectionCollectionDataTest::runTest( - int natoms, const gmx::ArrayRef &selections) +void SelectionCollectionDataTest::runTest(int natoms, const gmx::ArrayRef& selections) { ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(setAtomCount(natoms)); @@ -398,9 +361,8 @@ SelectionCollectionDataTest::runTest( } -void -SelectionCollectionDataTest::runTest( - const char *filename, const gmx::ArrayRef &selections) +void SelectionCollectionDataTest::runTest(const char* filename, + const gmx::ArrayRef& selections) { ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(loadTopology(filename)); @@ -473,8 +435,8 @@ TEST_F(SelectionCollectionTest, HandlesForceRequestForCenterOfGeometry) TEST_F(SelectionCollectionTest, ParsesSelectionsFromFile) { - ASSERT_NO_THROW_GMX(sel_ = sc_.parseFromFile( - gmx::test::TestFileManager::getInputFilePath("selfile.dat"))); + ASSERT_NO_THROW_GMX( + sel_ = sc_.parseFromFile(gmx::test::TestFileManager::getInputFilePath("selfile.dat"))); // These should match the contents of selfile.dat ASSERT_EQ(2U, sel_.size()); EXPECT_STREQ("resname RA RB", sel_[0].selectionText()); @@ -493,28 +455,27 @@ TEST_F(SelectionCollectionTest, HandlesAtypicalWhitespace) TEST_F(SelectionCollectionTest, HandlesInvalidRegularExpressions) { ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro")); - EXPECT_THROW_GMX({ - sc_.parseFromString("resname ~ \"R[A\""); - sc_.compile(); - }, gmx::InvalidInputError); + EXPECT_THROW_GMX( + { + sc_.parseFromString("resname ~ \"R[A\""); + sc_.compile(); + }, + gmx::InvalidInputError); } TEST_F(SelectionCollectionTest, HandlesMissingMethodParamValue) { - EXPECT_THROW_GMX(sc_.parseFromString("mindist from atomnr 1 cutoff"), - gmx::InvalidInputError); + EXPECT_THROW_GMX(sc_.parseFromString("mindist from atomnr 1 cutoff"), gmx::InvalidInputError); } TEST_F(SelectionCollectionTest, HandlesMissingMethodParamValue2) { - EXPECT_THROW_GMX(sc_.parseFromString("within 1 of"), - gmx::InvalidInputError); + EXPECT_THROW_GMX(sc_.parseFromString("within 1 of"), gmx::InvalidInputError); } TEST_F(SelectionCollectionTest, HandlesMissingMethodParamValue3) { - EXPECT_THROW_GMX(sc_.parseFromString("within of atomnr 1"), - gmx::InvalidInputError); + EXPECT_THROW_GMX(sc_.parseFromString("within of atomnr 1"), gmx::InvalidInputError); } // TODO: Tests for more parser errors @@ -554,10 +515,8 @@ TEST_F(SelectionCollectionTest, HandlesUnsortedGroupReference) ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx")); EXPECT_THROW_GMX(sc_.parseFromString("atomnr 1 to 3 and group \"GrpUnsorted\""), gmx::InconsistentInputError); - EXPECT_THROW_GMX(sc_.parseFromString("group 2 or atomnr 2 to 5"), - gmx::InconsistentInputError); - EXPECT_THROW_GMX(sc_.parseFromString("within 1 of group 2"), - gmx::InconsistentInputError); + EXPECT_THROW_GMX(sc_.parseFromString("group 2 or atomnr 2 to 5"), gmx::InconsistentInputError); + EXPECT_THROW_GMX(sc_.parseFromString("within 1 of group 2"), gmx::InconsistentInputError); } TEST_F(SelectionCollectionTest, HandlesUnsortedGroupReferenceDelayed) @@ -682,59 +641,38 @@ TEST_F(SelectionCollectionTest, HandlesFramesWithTooSmallAtomSubsets4) TEST_F(SelectionCollectionInteractiveTest, HandlesBasicInput) { - const char *const input[] = { - "foo = resname RA", - "resname RB", - "\"Name\" resname RC" - }; + const char* const input[] = { "foo = resname RA", "resname RB", "\"Name\" resname RC" }; runTest(-1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesContinuation) { - const char *const input[] = { - "resname RB and \\", - "resname RC" - }; + const char* const input[] = { "resname RB and \\", "resname RC" }; runTest(-1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInput) { - const char *const input[] = { - "foo = resname RA", - "resname RA" - }; + const char* const input[] = { "foo = resname RA", "resname RA" }; runTest(1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesTwoSelectionInput) { - const char *const input[] = { - "resname RA", - "resname RB" - }; + const char* const input[] = { "resname RA", "resname RB" }; runTest(2, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesStatusWithGroups) { - const char *const input[] = { - "resname RA", - "" - }; + const char* const input[] = { "resname RA", "" }; loadIndexGroups("simple.ndx"); runTest(-1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesStatusWithExistingSelections) { - const char *const input[] = { - "", - "bar = resname RC", - "resname RA", - "" - }; + const char* const input[] = { "", "bar = resname RC", "resname RA", "" }; ASSERT_NO_THROW_GMX(sc_.parseFromString("foo = resname RA")); ASSERT_NO_THROW_GMX(sc_.parseFromString("resname RB")); runTest(-1, true, input); @@ -742,31 +680,19 @@ TEST_F(SelectionCollectionInteractiveTest, HandlesStatusWithExistingSelections) TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInputStatus) { - const char *const input[] = { - "foo = resname RA", - "", - "resname RB" - }; + const char* const input[] = { "foo = resname RA", "", "resname RB" }; runTest(1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesTwoSelectionInputStatus) { - const char *const input[] = { - "\"Sel\" resname RA", - "", - "resname RB" - }; + const char* const input[] = { "\"Sel\" resname RA", "", "resname RB" }; runTest(2, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesMultiSelectionInputStatus) { - const char *const input[] = { - "\"Sel\" resname RA", - "\"Sel2\" resname RB", - "" - }; + const char* const input[] = { "\"Sel\" resname RA", "\"Sel2\" resname RB", "" }; runTest(-1, true, input); } @@ -774,49 +700,32 @@ TEST_F(SelectionCollectionInteractiveTest, HandlesNoFinalNewline) { // TODO: There is an extra prompt printed after the input is finished; it // would be cleaner not to have it, but it's only a cosmetic issue. - const char *const input[] = { - "resname RA" - }; + const char* const input[] = { "resname RA" }; helper_.setLastNewline(false); runTest(-1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesEmptySelections) { - const char *const input[] = { - "resname RA;", - "; resname RB;;", - " ", - ";" - }; + const char* const input[] = { "resname RA;", "; resname RB;;", " ", ";" }; runTest(-1, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesMultipleSelectionsOnLine) { - const char *const input[] = { - "resname RA; resname RB and \\", - "resname RC" - }; + const char* const input[] = { "resname RA; resname RB and \\", "resname RC" }; runTest(2, true, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesNoninteractiveInput) { - const char *const input[] = { - "foo = resname RA", - "resname RB", - "\"Name\" resname RC" - }; + const char* const input[] = { "foo = resname RA", "resname RB", "\"Name\" resname RC" }; runTest(-1, false, input); } TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInputNoninteractively) { - const char *const input[] = { - "foo = resname RA", - "resname RA" - }; + const char* const input[] = { "foo = resname RA", "resname RA" }; runTest(1, false, input); } @@ -827,47 +736,32 @@ TEST_F(SelectionCollectionInteractiveTest, HandlesSingleSelectionInputNoninterac TEST_F(SelectionCollectionDataTest, HandlesAllNone) { - static const char * const selections[] = { - "all", - "none" - }; + static const char* const selections[] = { "all", "none" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesAtomnr) { - static const char * const selections[] = { - "atomnr 1 to 3 6 to 8", - "atomnr 4 2 5 to 7", - "atomnr <= 5" - }; + static const char* const selections[] = { "atomnr 1 to 3 6 to 8", "atomnr 4 2 5 to 7", + "atomnr <= 5" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesResnr) { - static const char * const selections[] = { - "resnr 1 2 5", - "resid 4 to 3" - }; + static const char* const selections[] = { "resnr 1 2 5", "resid 4 to 3" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesResIndex) { - static const char * const selections[] = { - "resindex 1 4", - "residue 1 3" - }; + static const char* const selections[] = { "resindex 1 4", "residue 1 3" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesMolIndex) { - static const char * const selections[] = { - "molindex 1 4", - "molecule 2 3 5" - }; + static const char* const selections[] = { "molindex 1 4", "molecule 2 3 5" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); topManager_.initUniformMolecules(3); @@ -877,33 +771,24 @@ TEST_F(SelectionCollectionDataTest, HandlesMolIndex) TEST_F(SelectionCollectionDataTest, HandlesAtomname) { - static const char * const selections[] = { - "name CB", - "atomname S1 S2" - }; + static const char* const selections[] = { "name CB", "atomname S1 S2" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesPdbAtomname) { - static const char * const selections[] = { - "name HG21", - "name 1HG2", - "pdbname HG21 CB", - "pdbatomname 1HG2" - }; + static const char* const selections[] = { "name HG21", "name 1HG2", "pdbname HG21 CB", + "pdbatomname 1HG2" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesAtomtype) { - static const char * const selections[] = { - "atomtype CA" - }; + static const char* const selections[] = { "atomtype CA" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); - const char *const types[] = { "CA", "SA", "SB" }; + const char* const types[] = { "CA", "SA", "SB" }; topManager_.initAtomTypes(types); ASSERT_NO_FATAL_FAILURE(setTopology()); ASSERT_NO_FATAL_FAILURE(runCompiler()); @@ -911,22 +796,17 @@ TEST_F(SelectionCollectionDataTest, HandlesAtomtype) TEST_F(SelectionCollectionDataTest, HandlesChain) { - static const char * const selections[] = { - "chain A", - "chain B" - }; + static const char* const selections[] = { "chain A", "chain B" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesMass) { - static const char * const selections[] = { - "mass > 5" - }; + static const char* const selections[] = { "mass > 5" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); EXPECT_TRUE(sc_.requiredTopologyProperties().needsMasses); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); - t_atoms &atoms = topManager_.atoms(); + t_atoms& atoms = topManager_.atoms(); for (int i = 0; i < atoms.nr; ++i) { atoms.atom[i].m = 1.0 + i; @@ -938,12 +818,10 @@ TEST_F(SelectionCollectionDataTest, HandlesMass) TEST_F(SelectionCollectionDataTest, HandlesCharge) { - static const char * const selections[] = { - "charge < 0.5" - }; + static const char* const selections[] = { "charge < 0.5" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); - t_atoms &atoms = topManager_.atoms(); + t_atoms& atoms = topManager_.atoms(); for (int i = 0; i < atoms.nr; ++i) { atoms.atom[i].q = i / 10.0; @@ -958,56 +836,37 @@ TEST_F(SelectionCollectionDataTest, HandlesCharge) TEST_F(SelectionCollectionDataTest, HandlesAltLoc) { - static const char * const selections[] = { - "altloc \" \"", - "altloc A" - }; + static const char* const selections[] = { "altloc \" \"", "altloc A" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesInsertCode) { - static const char * const selections[] = { - "insertcode \" \"", - "insertcode A" - }; + static const char* const selections[] = { "insertcode \" \"", "insertcode A" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesOccupancy) { - static const char * const selections[] = { - "occupancy 1", - "occupancy < .5" - }; + static const char* const selections[] = { "occupancy 1", "occupancy < .5" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesBeta) { - static const char * const selections[] = { - "beta 0", - "beta >= 0.3" - }; + static const char* const selections[] = { "beta 0", "beta >= 0.3" }; runTest("simple.pdb", selections); } TEST_F(SelectionCollectionDataTest, HandlesResname) { - static const char * const selections[] = { - "resname RA", - "resname RB RC" - }; + static const char* const selections[] = { "resname RA", "resname RB RC" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesCoordinateKeywords) { - static const char * const selections[] = { - "x < 3", - "y >= 3", - "x {-1 to 2}" - }; + static const char* const selections[] = { "x < 3", "y >= 3", "x {-1 to 2}" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1015,42 +874,31 @@ TEST_F(SelectionCollectionDataTest, HandlesCoordinateKeywords) TEST_F(SelectionCollectionDataTest, HandlesSameResidue) { - static const char * const selections[] = { - "same residue as atomnr 1 4 12" - }; + static const char* const selections[] = { "same residue as atomnr 1 4 12" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesSameResidueName) { - static const char * const selections[] = { - "same resname as atomnr 1 14" - }; + static const char* const selections[] = { "same resname as atomnr 1 14" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesPositionKeywords) { - static const char * const selections[] = { - "cog of resnr 1 3", - "res_cog of name CB and resnr 1 3", - "whole_res_cog of name CB and resnr 1 3", - "part_res_cog of x < 3", - "dyn_res_cog of x < 3" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionAtoms); + static const char* const selections[] = { "cog of resnr 1 3", "res_cog of name CB and resnr 1 3", + "whole_res_cog of name CB and resnr 1 3", + "part_res_cog of x < 3", "dyn_res_cog of x < 3" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesDistanceKeyword) { - static const char * const selections[] = { - "distance from cog of resnr 1 < 2" - }; + static const char* const selections[] = { "distance from cog of resnr 1 < 2" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1058,9 +906,7 @@ TEST_F(SelectionCollectionDataTest, HandlesDistanceKeyword) TEST_F(SelectionCollectionDataTest, HandlesMinDistanceKeyword) { - static const char * const selections[] = { - "mindistance from resnr 1 < 2" - }; + static const char* const selections[] = { "mindistance from resnr 1 < 2" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1068,9 +914,7 @@ TEST_F(SelectionCollectionDataTest, HandlesMinDistanceKeyword) TEST_F(SelectionCollectionDataTest, HandlesWithinKeyword) { - static const char * const selections[] = { - "within 1 of resnr 2" - }; + static const char* const selections[] = { "within 1 of resnr 2" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1079,7 +923,7 @@ TEST_F(SelectionCollectionDataTest, HandlesWithinKeyword) TEST_F(SelectionCollectionDataTest, HandlesInSolidAngleKeyword) { // Both of these should evaluate to empty on a correct implementation. - static const char * const selections[] = { + static const char* const selections[] = { "resname TP and not insolidangle center cog of resname C span resname R cutoff 20", "resname TN and insolidangle center cog of resname C span resname R cutoff 20" }; @@ -1090,39 +934,36 @@ TEST_F(SelectionCollectionDataTest, HandlesInSolidAngleKeyword) TEST_F(SelectionCollectionDataTest, HandlesPermuteModifier) { - static const char * const selections[] = { - "all permute 3 1 2", - "res_cog of resnr 1 to 4 permute 2 1", - "name CB S1 and res_cog x < 3 permute 2 1" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionAtoms | efTestPositionMapping); + static const char* const selections[] = { "all permute 3 1 2", + "res_cog of resnr 1 to 4 permute 2 1", + "name CB S1 and res_cog x < 3 permute 2 1" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms + | efTestPositionMapping); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesPlusModifier) { - static const char * const selections[] = { - "name S2 plus name S1", - "res_cog of resnr 2 plus res_cog of resnr 1 plus res_cog of resnr 3", + static const char* const selections[] = { + "name S2 plus name S1", "res_cog of resnr 2 plus res_cog of resnr 1 plus res_cog of resnr 3", "name S1 and y < 3 plus res_cog of x < 2.5" }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionAtoms | efTestPositionMapping); + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms + | efTestPositionMapping); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesMergeModifier) { - static const char * const selections[] = { + static const char* const selections[] = { "name S2 merge name S1", "resnr 1 2 and name S2 merge resnr 1 2 and name S1 merge res_cog of resnr 1 2", "name S1 and x < 2.5 merge res_cog of x < 2.5" }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionAtoms | efTestPositionMapping); + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms + | efTestPositionMapping); runTest("simple.gro", selections); } @@ -1133,19 +974,15 @@ TEST_F(SelectionCollectionDataTest, HandlesMergeModifier) TEST_F(SelectionCollectionDataTest, ComputesMassesAndCharges) { - static const char * const selections[] = { - "name CB", - "y > 2", - "res_cog of y > 2" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionAtoms - | efTestPositionMasses | efTestPositionCharges); + static const char* const selections[] = { "name CB", "y > 2", "res_cog of y > 2" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionAtoms | efTestPositionMasses + | efTestPositionCharges); ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); - t_atoms &atoms = topManager_.atoms(); + t_atoms& atoms = topManager_.atoms(); for (int i = 0; i < atoms.nr; ++i) { - atoms.atom[i].m = 1.0 + i / 100.0; + atoms.atom[i].m = 1.0 + i / 100.0; atoms.atom[i].q = -(1.0 + i / 100.0); } atoms.haveMass = TRUE; @@ -1158,24 +995,16 @@ TEST_F(SelectionCollectionDataTest, ComputesMassesAndCharges) TEST_F(SelectionCollectionDataTest, ComputesMassesAndChargesWithoutTopology) { - static const char * const selections[] = { - "atomnr 1 to 3 8 to 9", - "y > 2", - "cog of (y > 2)" - }; - setFlags(TestFlags() | efTestPositionAtoms - | efTestPositionMasses | efTestPositionCharges); + static const char* const selections[] = { "atomnr 1 to 3 8 to 9", "y > 2", "cog of (y > 2)" }; + setFlags(TestFlags() | efTestPositionAtoms | efTestPositionMasses | efTestPositionCharges); runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesFramesWithAtomSubsets) { - const int index[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11 }; - const char * const selections[] = { - "resnr 1 4", - "atomnr 1 2 5 11 and y > 2", - "res_cog of atomnr 2 5 11" - }; + const int index[] = { 0, 1, 2, 3, 4, 5, 9, 10, 11 }; + const char* const selections[] = { "resnr 1 4", "atomnr 1 2 5 11 and y > 2", + "res_cog of atomnr 2 5 11" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionAtoms); ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro")); @@ -1192,11 +1021,8 @@ TEST_F(SelectionCollectionDataTest, HandlesFramesWithAtomSubsets) TEST_F(SelectionCollectionDataTest, HandlesSelectionNames) { - static const char * const selections[] = { - "\"GroupSelection\" group \"GrpA\"", - "\"DynamicSelection\" x < 5", - "y < 3" - }; + static const char* const selections[] = { "\"GroupSelection\" group \"GrpA\"", + "\"DynamicSelection\" x < 5", "y < 3" }; setFlags(TestFlags() | efTestSelectionNames); ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx")); runTest(10, selections); @@ -1204,17 +1030,13 @@ TEST_F(SelectionCollectionDataTest, HandlesSelectionNames) TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelections) { - static const char * const selections[] = { - "group \"GrpA\"", - "GrpB", - "1", - // These test that the name of the group is not too eagerly promoted to - // the name of the selection. - "group \"GrpB\" and resname RB", - "group \"GrpA\" permute 5 3 2 1 4", - "group \"GrpA\" plus group \"GrpB\"", - "res_cog of group \"GrpA\"" - }; + static const char* const selections[] = { "group \"GrpA\"", "GrpB", "1", + // These test that the name of the group is not too + // eagerly promoted to the name of the selection. + "group \"GrpB\" and resname RB", + "group \"GrpA\" permute 5 3 2 1 4", + "group \"GrpA\" plus group \"GrpB\"", + "res_cog of group \"GrpA\"" }; setFlags(TestFlags() | efTestSelectionNames); ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx")); runTest("simple.gro", selections); @@ -1222,12 +1044,8 @@ TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelections) TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelectionsDelayed) { - static const char * const selections[] = { - "group \"GrpA\"", - "GrpB", - "1", - "group \"GrpB\" and resname RB" - }; + static const char* const selections[] = { "group \"GrpA\"", "GrpB", "1", + "group \"GrpB\" and resname RB" }; setFlags(TestFlags() | efTestSelectionNames); ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro")); @@ -1237,32 +1055,27 @@ TEST_F(SelectionCollectionDataTest, HandlesIndexGroupsInSelectionsDelayed) TEST_F(SelectionCollectionDataTest, HandlesUnsortedIndexGroupsInSelections) { - static const char * const selections[] = { - "foo = group \"GrpUnsorted\"", - "group \"GrpUnsorted\"", - "GrpUnsorted", - "2", - "res_cog of group \"GrpUnsorted\"", - "group \"GrpUnsorted\" permute 2 1", - "foo" - }; - setFlags(TestFlags() | efTestPositionAtoms | efTestPositionMapping - | efTestSelectionNames); + static const char* const selections[] = { "foo = group \"GrpUnsorted\"", + "group \"GrpUnsorted\"", + "GrpUnsorted", + "2", + "res_cog of group \"GrpUnsorted\"", + "group \"GrpUnsorted\" permute 2 1", + "foo" }; + setFlags(TestFlags() | efTestPositionAtoms | efTestPositionMapping | efTestSelectionNames); ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx")); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesUnsortedIndexGroupsInSelectionsDelayed) { - static const char * const selections[] = { - "foo = group \"GrpUnsorted\"", - "group \"GrpUnsorted\"", - "GrpUnsorted", - "2", - "res_cog of group \"GrpUnsorted\"", - "group \"GrpUnsorted\" permute 2 1", - "foo" - }; + static const char* const selections[] = { "foo = group \"GrpUnsorted\"", + "group \"GrpUnsorted\"", + "GrpUnsorted", + "2", + "res_cog of group \"GrpUnsorted\"", + "group \"GrpUnsorted\" permute 2 1", + "foo" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(loadTopology("simple.gro")); ASSERT_NO_THROW_GMX(loadIndexGroups("simple.ndx")); @@ -1272,31 +1085,23 @@ TEST_F(SelectionCollectionDataTest, HandlesUnsortedIndexGroupsInSelectionsDelaye TEST_F(SelectionCollectionDataTest, HandlesConstantPositions) { - static const char * const selections[] = { - "[1, -2, 3.5]" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionMapping); + static const char* const selections[] = { "[1, -2, 3.5]" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionMapping); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesConstantPositionsWithModifiers) { - static const char * const selections[] = { - "[0, 0, 0] plus [0, 1, 0]" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionMapping); + static const char* const selections[] = { "[0, 0, 0] plus [0, 1, 0]" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionMapping); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesWithinConstantPositions) { - static const char * const selections[] = { - "within 1 of [2, 1, 0]" - }; + static const char* const selections[] = { "within 1 of [2, 1, 0]" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1304,23 +1109,18 @@ TEST_F(SelectionCollectionDataTest, HandlesWithinConstantPositions) TEST_F(SelectionCollectionDataTest, HandlesOverlappingIntegerRanges) { - static const char * const selections[] = { - "atomnr 2 to 4 5 to 8", - "atomnr 2 to 5 4 to 7" - }; + static const char* const selections[] = { "atomnr 2 to 4 5 to 8", "atomnr 2 to 5 4 to 7" }; ASSERT_NO_FATAL_FAILURE(runTest(10, selections)); } TEST_F(SelectionCollectionDataTest, HandlesOverlappingRealRanges) { - static const char * const selections[] = { - "charge {-0.35 to -0.05 0.25 to 0.75}", - "charge {0.05 to -0.3 -0.05 to 0.55}" - }; + static const char* const selections[] = { "charge {-0.35 to -0.05 0.25 to 0.75}", + "charge {0.05 to -0.3 -0.05 to 0.55}" }; ASSERT_NO_FATAL_FAILURE(runParser(selections)); ASSERT_NO_FATAL_FAILURE(topManager_.loadTopology("simple.gro")); - t_atoms &atoms = topManager_.atoms(); + t_atoms& atoms = topManager_.atoms(); for (int i = 0; i < atoms.nr; ++i) { atoms.atom[i].q = i / 10.0 - 0.5; @@ -1333,39 +1133,29 @@ TEST_F(SelectionCollectionDataTest, HandlesOverlappingRealRanges) TEST_F(SelectionCollectionDataTest, HandlesForcedStringMatchingMode) { - static const char * const selections[] = { - "name = S1 \"C?\"", - "name ? S1 \"C?\"" - }; + static const char* const selections[] = { "name = S1 \"C?\"", "name ? S1 \"C?\"" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesWildcardMatching) { - static const char * const selections[] = { - "name \"S?\"", - "name ? \"S?\"" - }; + static const char* const selections[] = { "name \"S?\"", "name ? \"S?\"" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesRegexMatching) { - static const char * const selections[] = { - "resname \"R[BD]\"", - "resname ~ \"R[BD]\"" - }; + static const char* const selections[] = { "resname \"R[BD]\"", "resname ~ \"R[BD]\"" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesBasicBoolean) { - static const char * const selections[] = { - "atomnr 1 to 5 and atomnr 2 to 7", - "atomnr 1 to 5 or not atomnr 3 to 8", + static const char* const selections[] = { + "atomnr 1 to 5 and atomnr 2 to 7", "atomnr 1 to 5 or not atomnr 3 to 8", "not not atomnr 1 to 5 and atomnr 2 to 6 and not not atomnr 3 to 7", "atomnr 1 to 5 and (atomnr 2 to 7 and atomnr 3 to 6)", "x < 5 and atomnr 1 to 5 and y < 3 and atomnr 2 to 4" @@ -1376,7 +1166,7 @@ TEST_F(SelectionCollectionDataTest, HandlesBasicBoolean) TEST_F(SelectionCollectionDataTest, HandlesDynamicAtomValuedParameters) { - static const char * const selections[] = { + static const char* const selections[] = { "same residue as (atomnr 3 5 13 or y > 5)", "(resnr 1 3 5 or x > 10) and same residue as (atomnr 3 5 13 or z > 5)" }; @@ -1387,30 +1177,22 @@ TEST_F(SelectionCollectionDataTest, HandlesDynamicAtomValuedParameters) TEST_F(SelectionCollectionDataTest, HandlesEmptySelectionWithUnevaluatedExpressions) { - static const char * const selections[] = { - "none and x > 2", - "none and same resname as resnr 2" - }; + static const char* const selections[] = { "none and x > 2", + "none and same resname as resnr 2" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesEmptyReferenceForSame) { - static const char * const selections[] = { - "same residue as none", - "same resname as none" - }; + static const char* const selections[] = { "same residue as none", "same resname as none" }; runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesPositionModifiersForKeywords) { - static const char * const selections[] = { - "res_cog x > 2", - "name CB and res_cog y > 2.5" - }; + static const char* const selections[] = { "res_cog x > 2", "name CB and res_cog y > 2.5" }; setFlags(TestFlags() | efTestEvaluation); runTest("simple.gro", selections); } @@ -1418,10 +1200,8 @@ TEST_F(SelectionCollectionDataTest, HandlesPositionModifiersForKeywords) TEST_F(SelectionCollectionDataTest, HandlesPositionModifiersForMethods) { - static const char * const selections[] = { - "res_cog distance from cog of resnr 1 < 2", - "res_cog within 2 of cog of resnr 1" - }; + static const char* const selections[] = { "res_cog distance from cog of resnr 1 < 2", + "res_cog within 2 of cog of resnr 1" }; setFlags(TestFlags() | efTestEvaluation); runTest("simple.gro", selections); } @@ -1429,18 +1209,14 @@ TEST_F(SelectionCollectionDataTest, HandlesPositionModifiersForMethods) TEST_F(SelectionCollectionDataTest, HandlesKeywordOfPositions) { - static const char * const selections[] = { - "x < y of cog of resnr 2" - }; + static const char* const selections[] = { "x < y of cog of resnr 2" }; setFlags(TestFlags() | efTestEvaluation); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesKeywordOfPositionsInArithmetic) { - static const char * const selections[] = { - "x - y of cog of resnr 2 < 0" - }; + static const char* const selections[] = { "x - y of cog of resnr 2 < 0" }; setFlags(TestFlags() | efTestEvaluation); runTest("simple.gro", selections); } @@ -1448,13 +1224,8 @@ TEST_F(SelectionCollectionDataTest, HandlesKeywordOfPositionsInArithmetic) TEST_F(SelectionCollectionDataTest, HandlesNumericComparisons) { - static const char * const selections[] = { - "x > 2", - "2 < x", - "y > resnr", - "resnr < 2.5", - "2.5 > resnr" - }; + static const char* const selections[] = { "x > 2", "2 < x", "y > resnr", "resnr < 2.5", + "2.5 > resnr" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1462,12 +1233,7 @@ TEST_F(SelectionCollectionDataTest, HandlesNumericComparisons) TEST_F(SelectionCollectionDataTest, HandlesArithmeticExpressions) { - static const char * const selections[] = { - "x+1 > 3", - "(y-1)^2 <= 1", - "x+--1 > 3", - "-x+-1 < -3" - }; + static const char* const selections[] = { "x+1 > 3", "(y-1)^2 <= 1", "x+--1 > 3", "-x+-1 < -3" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1475,12 +1241,8 @@ TEST_F(SelectionCollectionDataTest, HandlesArithmeticExpressions) TEST_F(SelectionCollectionDataTest, HandlesNumericVariables) { - static const char * const selections[] = { - "value = x + y", - "value <= 4", - "index = resnr", - "index < 3" - }; + static const char* const selections[] = { "value = x + y", "value <= 4", "index = resnr", + "index < 3" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1488,13 +1250,9 @@ TEST_F(SelectionCollectionDataTest, HandlesNumericVariables) TEST_F(SelectionCollectionDataTest, HandlesComplexNumericVariables) { - static const char * const selections[] = { - "value = x + y", - "resname RA and value <= 4", - "resname RA RB and x < 3 and value <= 4", - "index = atomnr", - "resname RA and index < 3", - "resname RB and y < 3 and index < 6" + static const char* const selections[] = { + "value = x + y", "resname RA and value <= 4", "resname RA RB and x < 3 and value <= 4", + "index = atomnr", "resname RA and index < 3", "resname RB and y < 3 and index < 6" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); @@ -1503,13 +1261,9 @@ TEST_F(SelectionCollectionDataTest, HandlesComplexNumericVariables) TEST_F(SelectionCollectionDataTest, HandlesPositionVariables) { - static const char * const selections[] = { - "foo = res_cog of resname RA", - "foo", - "within 1 of foo", - "bar = cog of resname RA", - "bar", - "within 1 of bar" + static const char* const selections[] = { + "foo = res_cog of resname RA", "foo", "within 1 of foo", + "bar = cog of resname RA", "bar", "within 1 of bar" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); @@ -1518,11 +1272,8 @@ TEST_F(SelectionCollectionDataTest, HandlesPositionVariables) TEST_F(SelectionCollectionDataTest, HandlesPositionVariableInModifier) { - static const char * const selections[] = { - "foo = cog of resnr 1", - "cog of resnr 2 plus foo", - "cog of resnr 3 plus foo" - }; + static const char* const selections[] = { "foo = cog of resnr 1", "cog of resnr 2 plus foo", + "cog of resnr 3 plus foo" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1530,26 +1281,17 @@ TEST_F(SelectionCollectionDataTest, HandlesPositionVariableInModifier) TEST_F(SelectionCollectionDataTest, HandlesConstantPositionInVariable) { - static const char * const selections[] = { - "constpos = [1.0, 2.5, 0.5]", - "constpos", - "within 2 of constpos" - }; - setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates - | efTestPositionAtoms); + static const char* const selections[] = { "constpos = [1.0, 2.5, 0.5]", "constpos", + "within 2 of constpos" }; + setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates | efTestPositionAtoms); runTest("simple.gro", selections); } TEST_F(SelectionCollectionDataTest, HandlesNumericConstantsInVariables) { - static const char * const selections[] = { - "constint = 4", - "constreal1 = 0.5", - "constreal2 = 2.7", - "resnr < constint", - "x + constreal1 < constreal2" - }; + static const char* const selections[] = { "constint = 4", "constreal1 = 0.5", "constreal2 = 2.7", + "resnr < constint", "x + constreal1 < constreal2" }; setFlags(TestFlags() | efTestEvaluation | efTestPositionCoordinates); runTest("simple.gro", selections); } @@ -1561,9 +1303,8 @@ TEST_F(SelectionCollectionDataTest, HandlesNumericConstantsInVariables) TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysis) { - static const char * const selections[] = { - "atomnr 1 to 5 and atomnr 2 to 7 and x < 2", - "atomnr 1 to 5 and (atomnr 4 to 7 or x < 2)", + static const char* const selections[] = { + "atomnr 1 to 5 and atomnr 2 to 7 and x < 2", "atomnr 1 to 5 and (atomnr 4 to 7 or x < 2)", "atomnr 1 to 5 and y < 3 and (atomnr 4 to 7 or x < 2)", "atomnr 1 to 5 and not (atomnr 4 to 7 or x < 2)", "atomnr 1 to 5 or (atomnr 4 to 6 and (atomnr 5 to 7 or x < 2))" @@ -1574,26 +1315,22 @@ TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysis) TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysisWithVariables) { - static const char * const selections[] = { - "foo = atomnr 4 to 7 or x < 2", - "atomnr 1 to 4 and foo", - "atomnr 2 to 6 and y < 3 and foo", - "atomnr 6 to 10 and not foo" - }; + static const char* const selections[] = { "foo = atomnr 4 to 7 or x < 2", + "atomnr 1 to 4 and foo", + "atomnr 2 to 6 and y < 3 and foo", + "atomnr 6 to 10 and not foo" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysisWithMoreVariables) { - static const char * const selections[] = { - "foo = atomnr 4 to 7", - "bar = foo and x < 2", - "bar2 = foo and y < 2", - "atomnr 1 to 4 and bar", - "atomnr 2 to 6 and y < 3 and bar2", - "atomnr 6 to 10 and not foo" - }; + static const char* const selections[] = { "foo = atomnr 4 to 7", + "bar = foo and x < 2", + "bar2 = foo and y < 2", + "atomnr 1 to 4 and bar", + "atomnr 2 to 6 and y < 3 and bar2", + "atomnr 6 to 10 and not foo" }; runTest(10, selections); } @@ -1607,46 +1344,32 @@ TEST_F(SelectionCollectionDataTest, HandlesBooleanStaticAnalysisWithMoreVariable TEST_F(SelectionCollectionDataTest, HandlesUnusedVariables) { - static const char * const selections[] = { - "unused1 = atomnr 1 to 3", - "foo = atomnr 4 to 7", - "atomnr 1 to 6 and foo", - "unused2 = atomnr 3 to 5" - }; + static const char* const selections[] = { "unused1 = atomnr 1 to 3", "foo = atomnr 4 to 7", + "atomnr 1 to 6 and foo", "unused2 = atomnr 3 to 5" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesVariablesWithStaticEvaluationGroups) { - static const char * const selections[] = { - "foo = atomnr 4 to 7 and x < 2", - "atomnr 1 to 5 and foo", - "atomnr 3 to 7 and foo" - }; + static const char* const selections[] = { "foo = atomnr 4 to 7 and x < 2", + "atomnr 1 to 5 and foo", "atomnr 3 to 7 and foo" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesVariablesWithMixedEvaluationGroups) { - static const char * const selections[] = { - "foo = atomnr 4 to 7 and x < 2", - "atomnr 1 to 6 and foo", - "within 1 of foo", - "foo" - }; + static const char* const selections[] = { "foo = atomnr 4 to 7 and x < 2", + "atomnr 1 to 6 and foo", "within 1 of foo", "foo" }; runTest(10, selections); } TEST_F(SelectionCollectionDataTest, HandlesVariablesWithMixedEvaluationGroups2) { - static const char * const selections[] = { - "foo = atomnr 1 to 8 and x < 10", - "atomnr 1 to 5 and y < 10 and foo", - "foo" - }; + static const char* const selections[] = { "foo = atomnr 1 to 8 and x < 10", + "atomnr 1 to 5 and y < 10 and foo", "foo" }; setFlags(TestFlags() | efTestEvaluation); runTest("simple.gro", selections); } diff --git a/src/gromacs/selection/tests/selectionoption.cpp b/src/gromacs/selection/tests/selectionoption.cpp index f230af5a69..0fb7024df9 100644 --- a/src/gromacs/selection/tests/selectionoption.cpp +++ b/src/gromacs/selection/tests/selectionoption.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,28 +70,27 @@ namespace class SelectionOptionTestBase : public ::testing::Test { - public: - SelectionOptionTestBase(); +public: + SelectionOptionTestBase(); - void loadTopology(const char *filename); + void loadTopology(const char* filename); - gmx::SelectionCollection sc_; - gmx::SelectionOptionManager manager_; - gmx::Options options_; + gmx::SelectionCollection sc_; + gmx::SelectionOptionManager manager_; + gmx::Options options_; - private: - gmx::test::TopologyManager topManager_; +private: + gmx::test::TopologyManager topManager_; }; -SelectionOptionTestBase::SelectionOptionTestBase() - : manager_(&sc_) +SelectionOptionTestBase::SelectionOptionTestBase() : manager_(&sc_) { options_.addManager(&manager_); sc_.setReferencePosType("atom"); sc_.setOutputPosType("atom"); } -void SelectionOptionTestBase::loadTopology(const char *filename) +void SelectionOptionTestBase::loadTopology(const char* filename) { topManager_.loadTopology(filename); @@ -127,8 +127,7 @@ TEST_F(SelectionOptionTest, HandlesDynamicSelectionWhenStaticRequired) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel).onlyStatic())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlyStatic())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -144,8 +143,7 @@ TEST_F(SelectionOptionTest, HandlesNonAtomicSelectionWhenAtomsRequired) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel).onlyAtoms())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlyAtoms())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -164,8 +162,7 @@ TEST_F(SelectionOptionTest, ChecksForSortedAtomsWhenRequired) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel).onlySortedAtoms())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).onlySortedAtoms())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -184,8 +181,7 @@ TEST_F(SelectionOptionTest, ChecksEmptySelections) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -203,8 +199,7 @@ TEST_F(SelectionOptionTest, ChecksEmptyDelayedSelections) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -239,8 +234,7 @@ TEST_F(SelectionOptionTest, HandlesTooFewSelections) { gmx::Selection sel[2]; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(sel).valueCount(2))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(sel).valueCount(2))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -256,8 +250,7 @@ TEST_F(SelectionOptionTest, HandlesDefaultSelectionText) { gmx::Selection sel; using gmx::SelectionOption; - options_.addOption(SelectionOption("sel").store(&sel) - .defaultSelectionText("all")); + options_.addOption(SelectionOption("sel").store(&sel).defaultSelectionText("all")); EXPECT_NO_THROW_GMX(options_.finish()); @@ -272,10 +265,10 @@ TEST_F(SelectionOptionTest, HandlesDefaultSelectionText) TEST_F(SelectionOptionTest, HandlesAdjuster) { - gmx::SelectionList sel; + gmx::SelectionList sel; using gmx::SelectionOption; - gmx::SelectionOptionInfo *info = options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue()); + gmx::SelectionOptionInfo* info = + options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -291,10 +284,9 @@ TEST_F(SelectionOptionTest, HandlesAdjuster) TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster) { - gmx::Selection sel; + gmx::Selection sel; using gmx::SelectionOption; - gmx::SelectionOptionInfo *info = options_.addOption( - SelectionOption("sel").store(&sel)); + gmx::SelectionOptionInfo* info = options_.addOption(SelectionOption("sel").store(&sel)); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -309,10 +301,10 @@ TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster) TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster) { - gmx::SelectionList sel; + gmx::SelectionList sel; using gmx::SelectionOption; - gmx::SelectionOptionInfo *info = options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue()); + gmx::SelectionOptionInfo* info = + options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -328,10 +320,10 @@ TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster) TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster) { - gmx::SelectionList sel; + gmx::SelectionList sel; using gmx::SelectionOption; - gmx::SelectionOptionInfo *info = options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue()); + gmx::SelectionOptionInfo* info = + options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue()); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -348,8 +340,7 @@ TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection) { gmx::Selection sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(&sel).required())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(&sel).required())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -364,9 +355,7 @@ TEST_F(SelectionOptionTest, HandlesTooFewDelayedRequiredSelections) { gmx::Selection sel[2]; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").store(sel).required() - .valueCount(2))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").store(sel).required().valueCount(2))); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -395,10 +384,10 @@ TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection) TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster) { - gmx::SelectionList sel; + gmx::SelectionList sel; using gmx::SelectionOption; - gmx::SelectionOptionInfo *info = options_.addOption( - SelectionOption("sel").storeVector(&sel).valueCount(3)); + gmx::SelectionOptionInfo* info = + options_.addOption(SelectionOption("sel").storeVector(&sel).valueCount(3)); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -417,8 +406,8 @@ TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster) class SelectionFileOptionTest : public SelectionOptionTestBase { - public: - SelectionFileOptionTest(); +public: + SelectionFileOptionTest(); }; SelectionFileOptionTest::SelectionFileOptionTest() @@ -432,11 +421,9 @@ TEST_F(SelectionFileOptionTest, HandlesSingleSelectionOptionFromFile) gmx::SelectionList sel; gmx::SelectionList reqsel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue())); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("reqsel").storeVector(&reqsel) - .multiValue().required())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue())); + ASSERT_NO_THROW_GMX( + options_.addOption(SelectionOption("reqsel").storeVector(&reqsel).multiValue().required())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -461,10 +448,8 @@ TEST_F(SelectionFileOptionTest, HandlesTwoSeparateSelectionOptions) gmx::SelectionList sel1; gmx::SelectionList sel2; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel1").storeVector(&sel1).multiValue())); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel2").storeVector(&sel2).multiValue())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1).multiValue())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2).multiValue())); gmx::OptionsAssigner assigner(&options_); std::string value(TestFileManager::getInputFilePath("selfile.dat")); @@ -497,10 +482,8 @@ TEST_F(SelectionFileOptionTest, HandlesTwoSelectionOptionsFromSingleFile) gmx::SelectionList sel1; gmx::SelectionList sel2; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel1").storeVector(&sel1))); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel2").storeVector(&sel2))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1))); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2))); gmx::OptionsAssigner assigner(&options_); std::string value(TestFileManager::getInputFilePath("selfile.dat")); @@ -528,12 +511,9 @@ TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFile) gmx::SelectionList sel; gmx::SelectionList optsel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").storeVector(&sel) - .multiValue().required())); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("optsel").storeVector(&optsel) - .multiValue())); + ASSERT_NO_THROW_GMX( + options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue().required())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("optsel").storeVector(&optsel).multiValue())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -561,12 +541,10 @@ TEST_F(SelectionFileOptionTest, HandlesRequiredOptionFromFileWithOtherOptionSet) gmx::SelectionList sel1; gmx::SelectionList sel2; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel1").storeVector(&sel1) - .multiValue().required())); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel2").storeVector(&sel2) - .multiValue().required())); + ASSERT_NO_THROW_GMX( + options_.addOption(SelectionOption("sel1").storeVector(&sel1).multiValue().required())); + ASSERT_NO_THROW_GMX( + options_.addOption(SelectionOption("sel2").storeVector(&sel2).multiValue().required())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -593,10 +571,8 @@ TEST_F(SelectionFileOptionTest, HandlesTwoRequiredOptionsFromSingleFile) gmx::SelectionList sel1; gmx::SelectionList sel2; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel1").storeVector(&sel1).required())); - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel2").storeVector(&sel2).required())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel1").storeVector(&sel1).required())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel2").storeVector(&sel2).required())); gmx::OptionsAssigner assigner(&options_); std::string value(TestFileManager::getInputFilePath("selfile.dat")); @@ -619,8 +595,7 @@ TEST_F(SelectionFileOptionTest, GivesErrorWithNoFile) { gmx::SelectionList sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -637,8 +612,7 @@ TEST_F(SelectionFileOptionTest, GivesErrorWithNonExistentFile) { gmx::SelectionList sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); @@ -659,8 +633,7 @@ TEST_F(SelectionFileOptionTest, GivesErrorWithMultipleFiles) { gmx::SelectionList sel; using gmx::SelectionOption; - ASSERT_NO_THROW_GMX(options_.addOption( - SelectionOption("sel").storeVector(&sel).multiValue())); + ASSERT_NO_THROW_GMX(options_.addOption(SelectionOption("sel").storeVector(&sel).multiValue())); gmx::OptionsAssigner assigner(&options_); EXPECT_NO_THROW_GMX(assigner.start()); diff --git a/src/gromacs/selection/tests/toputils.cpp b/src/gromacs/selection/tests/toputils.cpp index a544d8796e..9ce9ed93cc 100644 --- a/src/gromacs/selection/tests/toputils.cpp +++ b/src/gromacs/selection/tests/toputils.cpp @@ -68,10 +68,7 @@ namespace gmx namespace test { -TopologyManager::TopologyManager() - : frame_(nullptr) -{ -} +TopologyManager::TopologyManager() : frame_(nullptr) {} TopologyManager::~TopologyManager() { @@ -84,7 +81,7 @@ TopologyManager::~TopologyManager() sfree(frame_); } - for (char *atomtype : atomtypes_) + for (char* atomtype : atomtypes_) { sfree(atomtype); } @@ -92,8 +89,7 @@ TopologyManager::~TopologyManager() void TopologyManager::requestFrame() { - GMX_RELEASE_ASSERT(mtop_ == nullptr, - "Frame must be requested before initializing topology"); + GMX_RELEASE_ASSERT(mtop_ == nullptr, "Frame must be requested before initializing topology"); if (frame_ == nullptr) { snew(frame_, 1); @@ -102,8 +98,7 @@ void TopologyManager::requestFrame() void TopologyManager::requestVelocities() { - GMX_RELEASE_ASSERT(frame_ != nullptr, - "Velocities requested before requesting a frame"); + GMX_RELEASE_ASSERT(frame_ != nullptr, "Velocities requested before requesting a frame"); frame_->bV = TRUE; if (frame_->natoms > 0) { @@ -113,8 +108,7 @@ void TopologyManager::requestVelocities() void TopologyManager::requestForces() { - GMX_RELEASE_ASSERT(frame_ != nullptr, - "Forces requested before requesting a frame"); + GMX_RELEASE_ASSERT(frame_ != nullptr, "Forces requested before requesting a frame"); frame_->bF = TRUE; if (frame_->natoms > 0) { @@ -122,19 +116,17 @@ void TopologyManager::requestForces() } } -void TopologyManager::loadTopology(const char *filename) +void TopologyManager::loadTopology(const char* filename) { - bool fullTopology; - int ePBC; - rvec *xtop = nullptr; - matrix box; + bool fullTopology; + int ePBC; + rvec* xtop = nullptr; + matrix box; GMX_RELEASE_ASSERT(mtop_ == nullptr, "Topology initialized more than once"); mtop_ = std::make_unique(); - readConfAndTopology( - gmx::test::TestFileManager::getInputFilePath(filename).c_str(), - &fullTopology, mtop_.get(), &ePBC, frame_ != nullptr ? &xtop : nullptr, - nullptr, box); + readConfAndTopology(gmx::test::TestFileManager::getInputFilePath(filename).c_str(), &fullTopology, + mtop_.get(), &ePBC, frame_ != nullptr ? &xtop : nullptr, nullptr, box); if (frame_ != nullptr) { @@ -143,7 +135,7 @@ void TopologyManager::loadTopology(const char *filename) frame_->bX = TRUE; snew(frame_->x, frame_->natoms); std::memcpy(frame_->x, xtop, sizeof(*frame_->x) * frame_->natoms); - frame_->bBox = TRUE; + frame_->bBox = TRUE; copy_mat(box, frame_->box); } @@ -157,13 +149,15 @@ void TopologyManager::initAtoms(int count) mtop_->moltype.resize(1); init_t_atoms(&mtop_->moltype[0].atoms, count, FALSE); mtop_->molblock.resize(1); - mtop_->molblock[0].type = 0; - mtop_->molblock[0].nmol = 1; - mtop_->natoms = count; - mtop_->maxres_renum = 0; + mtop_->molblock[0].type = 0; + mtop_->molblock[0].nmol = 1; + mtop_->natoms = count; + mtop_->maxres_renum = 0; gmx_mtop_finalize(mtop_.get()); - GMX_RELEASE_ASSERT(mtop_->maxres_renum == 0, "maxres_renum in mtop can be modified by an env.var., that is not supported in this test"); - t_atoms &atoms = this->atoms(); + GMX_RELEASE_ASSERT(mtop_->maxres_renum == 0, + "maxres_renum in mtop can be modified by an env.var., that is not supported " + "in this test"); + t_atoms& atoms = this->atoms(); for (int i = 0; i < count; ++i) { atoms.atom[i].m = (i % 3 == 0 ? 2.0 : 1.0); @@ -185,17 +179,17 @@ void TopologyManager::initAtoms(int count) } } -void TopologyManager::initAtomTypes(const ArrayRef &types) +void TopologyManager::initAtomTypes(const ArrayRef& types) { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); atomtypes_.reserve(types.size()); - for (const char *type : types) + for (const char* type : types) { atomtypes_.push_back(gmx_strdup(type)); } - t_atoms &atoms = this->atoms(); + t_atoms& atoms = this->atoms(); snew(atoms.atomtype, atoms.nr); - index j = 0; + index j = 0; for (int i = 0; i < atoms.nr; ++i, ++j) { if (j == types.ssize()) @@ -207,8 +201,7 @@ void TopologyManager::initAtomTypes(const ArrayRef &types) atoms.haveType = TRUE; } -void TopologyManager::initTopology(const int numMoleculeTypes, - const int numMoleculeBlocks) +void TopologyManager::initTopology(const int numMoleculeTypes, const int numMoleculeBlocks) { GMX_RELEASE_ASSERT(mtop_ == nullptr, "Topology initialized more than once"); mtop_ = std::make_unique(); @@ -216,29 +209,24 @@ void TopologyManager::initTopology(const int numMoleculeTypes, mtop_->molblock.resize(numMoleculeBlocks); } -void TopologyManager::setMoleculeType(const int moleculeTypeIndex, - const ArrayRef residueSizes) +void TopologyManager::setMoleculeType(const int moleculeTypeIndex, const ArrayRef residueSizes) { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); // Make a molecule block that refers to a new molecule type - auto &newMoleculeType = mtop_->moltype[moleculeTypeIndex]; - auto &atoms = newMoleculeType.atoms; + auto& newMoleculeType = mtop_->moltype[moleculeTypeIndex]; + auto& atoms = newMoleculeType.atoms; - auto numAtomsInMolecule = std::accumulate(residueSizes.begin(), residueSizes.end(), 0); + auto numAtomsInMolecule = std::accumulate(residueSizes.begin(), residueSizes.end(), 0); init_t_atoms(&atoms, numAtomsInMolecule, FALSE); atoms.nres = residueSizes.size(); // Fill the residues in the molecule type - int residueIndex = 0; - auto residueSize = std::begin(residueSizes); - for (int i = 0; - i < atoms.nr && residueSize != std::end(residueSizes); - ++residueSize, ++residueIndex) + int residueIndex = 0; + auto residueSize = std::begin(residueSizes); + for (int i = 0; i < atoms.nr && residueSize != std::end(residueSizes); ++residueSize, ++residueIndex) { - for (int j = 0; - i < atoms.nr && j < *residueSize; - ++i, ++j) + for (int j = 0; i < atoms.nr && j < *residueSize; ++i, ++j) { atoms.atom[i].resind = residueIndex; atoms.atom[i].m = (i % 3 == 0 ? 2.0 : 1.0); @@ -254,9 +242,9 @@ void TopologyManager::setMoleculeBlock(const int moleculeBlockIndex, { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); - auto &newMoleculeBlock = mtop_->molblock[moleculeBlockIndex]; - newMoleculeBlock.type = moleculeTypeIndex; - newMoleculeBlock.nmol = numMoleculesToAdd; + auto& newMoleculeBlock = mtop_->molblock[moleculeBlockIndex]; + newMoleculeBlock.type = moleculeTypeIndex; + newMoleculeBlock.nmol = numMoleculesToAdd; mtop_->natoms += numMoleculesToAdd * mtop_->moltype[moleculeTypeIndex].atoms.nr; } @@ -273,7 +261,7 @@ void TopologyManager::finalizeTopology() void TopologyManager::initUniformResidues(int residueSize) { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); - t_atoms &atoms = this->atoms(); + t_atoms& atoms = this->atoms(); int residueIndex = -1; for (int i = 0; i < atoms.nr; ++i) { @@ -289,22 +277,23 @@ void TopologyManager::initUniformResidues(int residueSize) void TopologyManager::initUniformMolecules(int moleculeSize) { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); - GMX_RELEASE_ASSERT(mtop_->molblock.size() == 1, "initUniformMolecules only implemented for a single molblock"); - gmx_molblock_t &molblock = mtop_->molblock[0]; - t_atoms &atoms = mtop_->moltype[molblock.type].atoms; + GMX_RELEASE_ASSERT(mtop_->molblock.size() == 1, + "initUniformMolecules only implemented for a single molblock"); + gmx_molblock_t& molblock = mtop_->molblock[0]; + t_atoms& atoms = mtop_->moltype[molblock.type].atoms; GMX_RELEASE_ASSERT(atoms.nr % moleculeSize == 0, "The number of atoms should be a multiple of moleculeSize"); - molblock.nmol = atoms.nr/moleculeSize; + molblock.nmol = atoms.nr / moleculeSize; atoms.nr = moleculeSize; const int nres = atoms.atom[atoms.nr].resind; - GMX_RELEASE_ASSERT(atoms.atom[atoms.nr-1].resind != nres, + GMX_RELEASE_ASSERT(atoms.atom[atoms.nr - 1].resind != nres, "The residues should break at molecule boundaries"); atoms.nres = nres; mtop_->haveMoleculeIndices = true; gmx_mtop_finalize(mtop_.get()); } -void TopologyManager::initFrameIndices(const ArrayRef &index) +void TopologyManager::initFrameIndices(const ArrayRef& index) { GMX_RELEASE_ASSERT(frame_ != nullptr, "Frame not initialized"); GMX_RELEASE_ASSERT(!frame_->bIndex, "Frame atom indices can only be set once"); @@ -316,7 +305,7 @@ void TopologyManager::initFrameIndices(const ArrayRef &index) frame_->natoms = index.size(); } -t_atoms &TopologyManager::atoms() +t_atoms& TopologyManager::atoms() { GMX_RELEASE_ASSERT(mtop_ != nullptr, "Topology not initialized"); GMX_RELEASE_ASSERT(mtop_->natoms == mtop_->moltype[0].atoms.nr, diff --git a/src/gromacs/selection/tests/toputils.h b/src/gromacs/selection/tests/toputils.h index e405c812dc..9394960000 100644 --- a/src/gromacs/selection/tests/toputils.h +++ b/src/gromacs/selection/tests/toputils.h @@ -52,7 +52,7 @@ struct t_trxframe; namespace gmx { -template +template class ArrayRef; namespace test @@ -63,68 +63,64 @@ namespace test * related data structures. */ class TopologyManager { - public: - TopologyManager(); - ~TopologyManager(); +public: + TopologyManager(); + ~TopologyManager(); - //@{ - /*! \brief Prepare the memory within a trajectory frame needed - * for test */ - void requestFrame(); - void requestVelocities(); - void requestForces(); - void initFrameIndices(const ArrayRef &index); - //@} + //@{ + /*! \brief Prepare the memory within a trajectory frame needed + * for test */ + void requestFrame(); + void requestVelocities(); + void requestForces(); + void initFrameIndices(const ArrayRef& index); + //@} - //! Load a topology from an input file relative to the source tree - void loadTopology(const char *filename); + //! Load a topology from an input file relative to the source tree + void loadTopology(const char* filename); - //@{ - /*! \brief Functions for creating simplistic topologies - * - * These are easy to work with for some kinds of tests. */ - void initAtoms(int count); - void initAtomTypes(const ArrayRef &types); - void initUniformResidues(int residueSize); - void initUniformMolecules(int moleculeSize); - //@} + //@{ + /*! \brief Functions for creating simplistic topologies + * + * These are easy to work with for some kinds of tests. */ + void initAtoms(int count); + void initAtomTypes(const ArrayRef& types); + void initUniformResidues(int residueSize); + void initUniformMolecules(int moleculeSize); + //@} - //@{ - /*! \brief Functions for creating realistic topologies - * - * Real topologies aren't uniform, so we need to be able to - * create custom topologies to test against. - * - * Ideally, we'd just be able to push new molecule types and - * blocks, but the data structures are not mature enough for - * that yet. The intended usage pattern is to initialize the - * topology and declare the number of molecule types and - * blocks, and then call the setter functions to fill in the - * data structures. */ - void initTopology(int numMoleculeTypes, - int numMoleculeBlocks); - void setMoleculeType(int moleculeTypeIndex, - ArrayRef residueSizes); - void setMoleculeBlock(int moleculeBlockIndex, - int moleculeTypeIndex, - int numMoleculesToAdd); - void finalizeTopology(); - //@} + //@{ + /*! \brief Functions for creating realistic topologies + * + * Real topologies aren't uniform, so we need to be able to + * create custom topologies to test against. + * + * Ideally, we'd just be able to push new molecule types and + * blocks, but the data structures are not mature enough for + * that yet. The intended usage pattern is to initialize the + * topology and declare the number of molecule types and + * blocks, and then call the setter functions to fill in the + * data structures. */ + void initTopology(int numMoleculeTypes, int numMoleculeBlocks); + void setMoleculeType(int moleculeTypeIndex, ArrayRef residueSizes); + void setMoleculeBlock(int moleculeBlockIndex, int moleculeTypeIndex, int numMoleculesToAdd); + void finalizeTopology(); + //@} - //@{ - //! Getters - gmx_mtop_t *topology() { return mtop_.get(); } - t_atoms &atoms(); - t_trxframe *frame() { return frame_; } - //@} + //@{ + //! Getters + gmx_mtop_t* topology() { return mtop_.get(); } + t_atoms& atoms(); + t_trxframe* frame() { return frame_; } + //@} - private: - //! Topology - std::unique_ptr mtop_; - //! Trajectory frame - t_trxframe *frame_; - //! Atom type names - std::vector atomtypes_; +private: + //! Topology + std::unique_ptr mtop_; + //! Trajectory frame + t_trxframe* frame_; + //! Atom type names + std::vector atomtypes_; }; } // namespace test diff --git a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_definitions.h b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_definitions.h index 6e767c5aaa..a00c9e34c6 100644 --- a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_definitions.h +++ b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -36,47 +36,48 @@ #ifndef GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H #define GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 0 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 // Although there is support, it is disabled in GROMACS, because rsqrtIter does not work correctly for inputs near MAX_FLOAT -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 0 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT \ + 0 // Although there is support, it is disabled in GROMACS, because rsqrtIter does not work correctly for inputs near MAX_FLOAT +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#undef GMX_SIMD_DOUBLE_WIDTH -#define GMX_SIMD_FINT32_WIDTH 4 -#undef GMX_SIMD_DINT32_WIDTH -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single) -#define GMX_SIMD_RSQRT_BITS 8 -#define GMX_SIMD_RCP_BITS 8 +#define GMX_SIMD_FLOAT_WIDTH 4 +#undef GMX_SIMD_DOUBLE_WIDTH +#define GMX_SIMD_FINT32_WIDTH 4 +#undef GMX_SIMD_DINT32_WIDTH +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single) +#define GMX_SIMD_RSQRT_BITS 8 +#define GMX_SIMD_RCP_BITS 8 #endif // GMX_SIMD_IMPL_ARM_NEON_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_general.h b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_general.h index 696a53d902..966fb4ce37 100644 --- a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_general.h +++ b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,14 +38,13 @@ namespace gmx { -static inline void -simdPrefetch(void * m) +static inline void simdPrefetch(void* m) { #ifdef __GNUC__ __builtin_prefetch(m); #endif } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_GENERAL_H diff --git a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd4_float.h b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd4_float.h index 83d12729d8..b947b4bad9 100644 --- a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd4_float.h +++ b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd4_float.h @@ -47,314 +47,238 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) : simdInternal_(vdupq_n_f32(f)) {} + Simd4Float(float f) : simdInternal_(vdupq_n_f32(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(float32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(float32x4_t simd) : simdInternal_(simd) {} - float32x4_t simdInternal_; + float32x4_t simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - //! \brief Construct from scalar bool - Simd4FBool(bool b) : simdInternal_(vdupq_n_u32( b ? 0xFFFFFFFF : 0)) {} + //! \brief Construct from scalar bool + Simd4FBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - Simd4FBool(uint32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(uint32x4_t simd) : simdInternal_(simd) {} - uint32x4_t simdInternal_; + uint32x4_t simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { assert(size_t(m) % 16 == 0); - return { - vld1q_f32(m) - }; + return { vld1q_f32(m) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { assert(size_t(m) % 16 == 0); vst1q_f32(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { - vld1q_f32(m) - }; + return { vld1q_f32(m) }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { vst1q_f32(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - vdupq_n_f32(0.0F) - }; + return { vdupq_n_f32(0.0F) }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_), - vreinterpretq_s32_f32(a.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_), + vreinterpretq_s32_f32(a.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - vaddq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vaddq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - vsubq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vsubq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - vnegq_f32(x.simdInternal_) - }; + return { vnegq_f32(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - vmulq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vmulq_f32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { return { -#ifdef __ARM_FEATURE_FMA - vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#else - vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#endif +# ifdef __ARM_FEATURE_FMA + vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# else + vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# endif }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { return { -#ifdef __ARM_FEATURE_FMA - vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#else - vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#endif +# ifdef __ARM_FEATURE_FMA + vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# else + vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# endif }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { return { -#ifdef __ARM_FEATURE_FMA - vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#else - vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#endif +# ifdef __ARM_FEATURE_FMA + vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# else + vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# endif }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { return { -#ifdef __ARM_FEATURE_FMA - vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#else - vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#endif +# ifdef __ARM_FEATURE_FMA + vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# else + vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# endif }; } #endif -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - vrsqrteq_f32(x.simdInternal_) - }; + return { vrsqrteq_f32(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - vabsq_f32( x.simdInternal_ ) - }; + return { vabsq_f32(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - vmaxq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vmaxq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - vminq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vminq_f32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { // Convert x to nearest integer - float32x4_t signBitOfX = vreinterpretq_f32_u32(vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(x.simdInternal_))); - float32x4_t half = vdupq_n_f32(0.5F); - float32x4_t corr = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfX))); + float32x4_t signBitOfX = vreinterpretq_f32_u32( + vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(x.simdInternal_))); + float32x4_t half = vdupq_n_f32(0.5F); + float32x4_t corr = vreinterpretq_f32_u32( + vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfX))); - int32x4_t integerX = vcvtq_s32_f32(vaddq_f32(x.simdInternal_, corr)); + int32x4_t integerX = vcvtq_s32_f32(vaddq_f32(x.simdInternal_, corr)); // Convert back to float - return { - vcvtq_f32_s32(integerX) - }; + return { vcvtq_f32_s32(integerX) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - vcvtq_f32_s32( vcvtq_s32_f32(x.simdInternal_) ) - }; + return { vcvtq_f32_s32(vcvtq_s32_f32(x.simdInternal_)) }; } #endif -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { - float32x4x2_t t0 = vuzpq_f32(v0->simdInternal_, v2->simdInternal_); - float32x4x2_t t1 = vuzpq_f32(v1->simdInternal_, v3->simdInternal_); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4x2_t t0 = vuzpq_f32(v0->simdInternal_, v2->simdInternal_); + float32x4x2_t t1 = vuzpq_f32(v1->simdInternal_, v3->simdInternal_); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); v0->simdInternal_ = t2.val[0]; v1->simdInternal_ = t3.val[0]; v2->simdInternal_ = t2.val[1]; v3->simdInternal_ = t3.val[1]; } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - vceqq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vceqq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) - }; + return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - vcltq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vcltq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - vcleq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vcleq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - vandq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vandq_u32(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - vorrq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vorrq_u32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { uint32x4_t x = a.simdInternal_; uint32x4_t y = vextq_u32(x, x, 2); @@ -366,36 +290,24 @@ anyTrue(Simd4FBool a) } #endif -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m) { - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m) { - return { - vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { float32x4_t x = a.simdInternal_; float32x4_t y = vextq_f32(x, x, 2); @@ -406,8 +318,7 @@ reduce(Simd4Float a) return vgetq_lane_f32(x, 0); } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { Simd4Float c; @@ -418,6 +329,6 @@ dotProduct(Simd4Float a, Simd4Float b) } #endif -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd_float.h b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd_float.h index 67fcd4d6f6..3e486a7a3e 100644 --- a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd_float.h +++ b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_simd_float.h @@ -50,319 +50,249 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) : simdInternal_(vdupq_n_f32(f)) {} + SimdFloat(float f) : simdInternal_(vdupq_n_f32(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(float32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(float32x4_t simd) : simdInternal_(simd) {} - float32x4_t simdInternal_; + float32x4_t simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) : simdInternal_(vdupq_n_s32(i)) {} + SimdFInt32(std::int32_t i) : simdInternal_(vdupq_n_s32(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(int32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(int32x4_t simd) : simdInternal_(simd) {} - int32x4_t simdInternal_; + int32x4_t simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_(vdupq_n_u32( b ? 0xFFFFFFFF : 0)) {} + SimdFBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFBool(uint32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(uint32x4_t simd) : simdInternal_(simd) {} - uint32x4_t simdInternal_; + uint32x4_t simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_(vdupq_n_u32( b ? 0xFFFFFFFF : 0)) {} + SimdFIBool(bool b) : simdInternal_(vdupq_n_u32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFIBool(uint32x4_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(uint32x4_t simd) : simdInternal_(simd) {} - uint32x4_t simdInternal_; + uint32x4_t simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { assert(std::size_t(m) % 16 == 0); - return { - vld1q_f32(m) - }; + return { vld1q_f32(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { assert(std::size_t(m) % 16 == 0); vst1q_f32(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { - return { - vld1q_f32(m) - }; + return { vld1q_f32(m) }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { vst1q_f32(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - vdupq_n_f32(0.0F) - }; + return { vdupq_n_f32(0.0F) }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { assert(std::size_t(m) % 16 == 0); - return { - vld1q_s32(m) - }; + return { vld1q_s32(m) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { assert(std::size_t(m) % 16 == 0); vst1q_s32(m, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { - return { - vld1q_s32(m) - }; + return { vld1q_s32(m) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { vst1q_s32(m, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - vdupq_n_s32(0) - }; + return { vdupq_n_s32(0) }; } -template gmx_simdcall -static inline std::int32_t -extract(SimdFInt32 a) +template +gmx_simdcall static inline std::int32_t extract(SimdFInt32 a) { return vgetq_lane_s32(a.simdInternal_, index); } -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vandq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_), - vreinterpretq_s32_f32(a.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vbicq_s32(vreinterpretq_s32_f32(b.simdInternal_), + vreinterpretq_s32_f32(a.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(vorrq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_), - vreinterpretq_s32_f32(b.simdInternal_))) - }; + return { vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a.simdInternal_), + vreinterpretq_s32_f32(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - vaddq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vaddq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - vsubq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vsubq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - vnegq_f32(x.simdInternal_) - }; + return { vnegq_f32(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - vmulq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vmulq_f32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { return { -#ifdef __ARM_FEATURE_FMA - vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#else - vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#endif +# ifdef __ARM_FEATURE_FMA + vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# else + vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# endif }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { return { -#ifdef __ARM_FEATURE_FMA - vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#else - vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#endif +# ifdef __ARM_FEATURE_FMA + vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# else + vnegq_f32(vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# endif }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { return { -#ifdef __ARM_FEATURE_FMA - vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#else - vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) -#endif +# ifdef __ARM_FEATURE_FMA + vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# else + vmlsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) +# endif }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { return { -#ifdef __ARM_FEATURE_FMA - vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#else - vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) -#endif +# ifdef __ARM_FEATURE_FMA + vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# else + vnegq_f32(vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) +# endif }; } #endif -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - vrsqrteq_f32(x.simdInternal_) - }; + return { vrsqrteq_f32(x.simdInternal_) }; } // The SIMD implementation seems to overflow when we square lu for // values close to FLOAT_MAX, so we fall back on the version in // simd_math.h, which is probably slightly slower. #if GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT -static inline SimdFloat gmx_simdcall -rsqrtIter(SimdFloat lu, SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrtIter(SimdFloat lu, SimdFloat x) { - return { - vmulq_f32(lu.simdInternal_, vrsqrtsq_f32(vmulq_f32(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) - }; + return { vmulq_f32(lu.simdInternal_, + vrsqrtsq_f32(vmulq_f32(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) }; } #endif -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - vrecpeq_f32(x.simdInternal_) - }; + return { vrecpeq_f32(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcpIter(SimdFloat lu, SimdFloat x) +static inline SimdFloat gmx_simdcall rcpIter(SimdFloat lu, SimdFloat x) { - return { - vmulq_f32(lu.simdInternal_, vrecpsq_f32(lu.simdInternal_, x.simdInternal_)) - }; + return { vmulq_f32(lu.simdInternal_, vrecpsq_f32(lu.simdInternal_, x.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - b.simdInternal_ = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(b.simdInternal_), - m.simdInternal_)); + b.simdInternal_ = + vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(b.simdInternal_), m.simdInternal_)); - return { - vaddq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vaddq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { SimdFloat tmp = a * b; - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp.simdInternal_), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp.simdInternal_), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { #ifdef __ARM_FEATURE_FMA float32x4_t tmp = vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_); @@ -370,90 +300,67 @@ maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) float32x4_t tmp = vmlaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_); #endif - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(tmp), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions #ifndef NDEBUG x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F)); #endif - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vrsqrteq_f32(x.simdInternal_)), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32( + vandq_u32(vreinterpretq_u32_f32(vrsqrteq_f32(x.simdInternal_)), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions #ifndef NDEBUG x.simdInternal_ = vbslq_f32(m.simdInternal_, x.simdInternal_, vdupq_n_f32(1.0F)); #endif - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(vrecpeq_f32(x.simdInternal_)), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32( + vandq_u32(vreinterpretq_u32_f32(vrecpeq_f32(x.simdInternal_)), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - vabsq_f32( x.simdInternal_ ) - }; + return { vabsq_f32(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - vmaxq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vmaxq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - vminq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vminq_f32(a.simdInternal_, b.simdInternal_) }; } // Round and trunc operations are defined at the end of this file, since they // need to use float-to-integer and integer-to-float conversions. -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { - const int32x4_t exponentMask = vdupq_n_s32(0x7F800000); - const int32x4_t mantissaMask = vdupq_n_s32(0x807FFFFF); - const int32x4_t exponentBias = vdupq_n_s32(126); // add 1 to make our definition identical to frexp() - const float32x4_t half = vdupq_n_f32(0.5F); - int32x4_t iExponent; + const int32x4_t exponentMask = vdupq_n_s32(0x7F800000); + const int32x4_t mantissaMask = vdupq_n_s32(0x807FFFFF); + const int32x4_t exponentBias = vdupq_n_s32(126); // add 1 to make our definition identical to frexp() + const float32x4_t half = vdupq_n_f32(0.5F); + int32x4_t iExponent; iExponent = vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), exponentMask); iExponent = vsubq_s32(vshrq_n_s32(iExponent, 23), exponentBias); exponent->simdInternal_ = iExponent; - return { - vreinterpretq_f32_s32(vorrq_s32(vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), - mantissaMask), - vreinterpretq_s32_f32(half))) - }; + return { vreinterpretq_f32_s32(vorrq_s32(vandq_s32(vreinterpretq_s32_f32(value.simdInternal_), mantissaMask), + vreinterpretq_s32_f32(half))) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { const int32x4_t exponentBias = vdupq_n_s32(127); int32x4_t iExponent = vaddq_s32(exponent.simdInternal_, exponentBias); @@ -464,17 +371,14 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = vmaxq_s32(iExponent, vdupq_n_s32(0)); } - iExponent = vshlq_n_s32( iExponent, 23); + iExponent = vshlq_n_s32(iExponent, 23); - return { - vmulq_f32(value.simdInternal_, vreinterpretq_f32_s32(iExponent)) - }; + return { vmulq_f32(value.simdInternal_, vreinterpretq_f32_s32(iExponent)) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { float32x4_t x = a.simdInternal_; float32x4_t y = vextq_f32(x, x, 2); @@ -486,69 +390,47 @@ reduce(SimdFloat a) } #endif -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - vceqq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vceqq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) - }; + return { vmvnq_u32(vceqq_f32(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - vcltq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vcltq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - vcleq_f32(a.simdInternal_, b.simdInternal_) - }; + return { vcleq_f32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { uint32x4_t tmp = vreinterpretq_u32_f32(a.simdInternal_); - return { - vtstq_u32(tmp, tmp) - }; + return { vtstq_u32(tmp, tmp) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - vandq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vandq_u32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - vorrq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vorrq_u32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { uint32x4_t x = a.simdInternal_; uint32x4_t y = vextq_u32(x, x, 2); @@ -560,132 +442,84 @@ anyTrue(SimdFBool a) } #endif -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m) { - return { - vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m) { - return { - vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), - m.simdInternal_)) - }; + return { vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.simdInternal_), m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vbslq_f32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - vandq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vandq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - vbicq_s32(b.simdInternal_, a.simdInternal_) - }; + return { vbicq_s32(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - vorrq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vorrq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - veorq_s32(a.simdInternal_, b.simdInternal_) - }; + return { veorq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - vaddq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vaddq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - vsubq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vsubq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - vmulq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vmulq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - vceqq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vceqq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - vtstq_s32(a.simdInternal_, a.simdInternal_) - }; + return { vtstq_s32(a.simdInternal_, a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - vcltq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vcltq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - vandq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vandq_u32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - vorrq_u32(a.simdInternal_, b.simdInternal_) - }; + return { vorrq_u32(a.simdInternal_, b.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { uint32x4_t x = a.simdInternal_; uint32x4_t y = vextq_u32(x, x, 2); @@ -697,92 +531,68 @@ anyTrue(SimdFIBool a) } #endif -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m) { - return { - vandq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) - }; + return { vandq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m) { - return { - vbicq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) - }; + return { vbicq_s32(a.simdInternal_, vreinterpretq_s32_u32(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - vbslq_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vbslq_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - float32x4_t signBitOfA = vreinterpretq_f32_u32(vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(a.simdInternal_))); - float32x4_t half = vdupq_n_f32(0.5F); - float32x4_t corr = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfA))); + float32x4_t signBitOfA = vreinterpretq_f32_u32( + vandq_u32(vdupq_n_u32(0x80000000), vreinterpretq_u32_f32(a.simdInternal_))); + float32x4_t half = vdupq_n_f32(0.5F); + float32x4_t corr = vreinterpretq_f32_u32( + vorrq_u32(vreinterpretq_u32_f32(half), vreinterpretq_u32_f32(signBitOfA))); - return { - vcvtq_s32_f32(vaddq_f32(a.simdInternal_, corr)) - }; + return { vcvtq_s32_f32(vaddq_f32(a.simdInternal_, corr)) }; } #endif -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - vcvtq_s32_f32(a.simdInternal_) - }; + return { vcvtq_s32_f32(a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - vcvtq_f32_s32(a.simdInternal_) - }; + return { vcvtq_f32_s32(a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } // Override for Neon-Asimd #if GMX_SIMD_ARM_NEON -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { return cvtI2R(cvtR2I(x)); } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { return cvtI2R(cvttR2I(x)); } #endif -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h index 81c3ff0ea2..8918e8fe95 100644 --- a/src/gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h +++ b/src/gromacs/simd/impl_arm_neon/impl_arm_neon_util_float.h @@ -51,14 +51,13 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { assert(std::size_t(offset) % 16 == 0); assert(std::size_t(base) % 16 == 0); @@ -66,91 +65,83 @@ gatherLoadTranspose(const float * base, // Unfortunately we cannot use the beautiful Neon structured load // instructions since the data comes from four different memory locations. - float32x4x2_t t0 = vuzpq_f32(vld1q_f32( base + align * offset[0] ), vld1q_f32( base + align * offset[2] )); - float32x4x2_t t1 = vuzpq_f32(vld1q_f32( base + align * offset[1] ), vld1q_f32( base + align * offset[3] )); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4x2_t t0 = + vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2])); + float32x4x2_t t1 = + vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3])); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); v0->simdInternal_ = t2.val[0]; v1->simdInternal_ = t3.val[0]; v2->simdInternal_ = t2.val[1]; v3->simdInternal_ = t3.val[1]; } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { assert(std::size_t(offset) % 16 == 0); assert(std::size_t(base) % 8 == 0); assert(align % 2 == 0); - v0->simdInternal_ = vcombine_f32(vld1_f32( base + align * offset[0] ), - vld1_f32( base + align * offset[2] )); - v1->simdInternal_ = vcombine_f32(vld1_f32( base + align * offset[1] ), - vld1_f32( base + align * offset[3] )); + v0->simdInternal_ = + vcombine_f32(vld1_f32(base + align * offset[0]), vld1_f32(base + align * offset[2])); + v1->simdInternal_ = + vcombine_f32(vld1_f32(base + align * offset[1]), vld1_f32(base + align * offset[3])); - float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_); + float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_); - v0->simdInternal_ = tmp.val[0]; - v1->simdInternal_ = tmp.val[1]; + v0->simdInternal_ = tmp.val[0]; + v1->simdInternal_ = tmp.val[1]; } static const int c_simdBestPairAlignmentFloat = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { assert(std::size_t(offset) % 16 == 0); - float32x4x2_t t0 = vuzpq_f32(vld1q_f32( base + align * offset[0] ), vld1q_f32( base + align * offset[2] )); - float32x4x2_t t1 = vuzpq_f32(vld1q_f32( base + align * offset[1] ), vld1q_f32( base + align * offset[3] )); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4x2_t t0 = + vuzpq_f32(vld1q_f32(base + align * offset[0]), vld1q_f32(base + align * offset[2])); + float32x4x2_t t1 = + vuzpq_f32(vld1q_f32(base + align * offset[1]), vld1q_f32(base + align * offset[3])); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); v0->simdInternal_ = t2.val[0]; v1->simdInternal_ = t3.val[0]; v2->simdInternal_ = t2.val[1]; } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { assert(std::size_t(offset) % 16 == 0); float32x4x2_t tmp = vtrnq_f32(v0.simdInternal_, v1.simdInternal_); - vst1_f32( base + align * offset[0], vget_low_f32(tmp.val[0]) ); - vst1_f32( base + align * offset[1], vget_low_f32(tmp.val[1]) ); - vst1_f32( base + align * offset[2], vget_high_f32(tmp.val[0]) ); - vst1_f32( base + align * offset[3], vget_high_f32(tmp.val[1]) ); + vst1_f32(base + align * offset[0], vget_low_f32(tmp.val[0])); + vst1_f32(base + align * offset[1], vget_low_f32(tmp.val[1])); + vst1_f32(base + align * offset[2], vget_high_f32(tmp.val[0])); + vst1_f32(base + align * offset[3], vget_high_f32(tmp.val[1])); - vst1q_lane_f32( base + align * offset[0] + 2, v2.simdInternal_, 0); - vst1q_lane_f32( base + align * offset[1] + 2, v2.simdInternal_, 1); - vst1q_lane_f32( base + align * offset[2] + 2, v2.simdInternal_, 2); - vst1q_lane_f32( base + align * offset[3] + 2, v2.simdInternal_, 3); + vst1q_lane_f32(base + align * offset[0] + 2, v2.simdInternal_, 0); + vst1q_lane_f32(base + align * offset[1] + 2, v2.simdInternal_, 1); + vst1q_lane_f32(base + align * offset[2] + 2, v2.simdInternal_, 2); + vst1q_lane_f32(base + align * offset[3] + 2, v2.simdInternal_, 3); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { assert(std::size_t(offset) % 16 == 0); @@ -166,31 +157,31 @@ transposeScatterIncrU(float * base, t0 = vadd_f32(t0, vld1_f32(base + align * offset[0])); vst1_f32(base + align * offset[0], t0); - base[ align * offset[0] + 2] += vgetq_lane_f32(v2.simdInternal_, 0); + base[align * offset[0] + 2] += vgetq_lane_f32(v2.simdInternal_, 0); t1 = vadd_f32(t1, vld1_f32(base + align * offset[1])); vst1_f32(base + align * offset[1], t1); - base[ align * offset[1] + 2] += vgetq_lane_f32(v2.simdInternal_, 1); + base[align * offset[1] + 2] += vgetq_lane_f32(v2.simdInternal_, 1); t2 = vadd_f32(t2, vld1_f32(base + align * offset[2])); vst1_f32(base + align * offset[2], t2); - base[ align * offset[2] + 2] += vgetq_lane_f32(v2.simdInternal_, 2); + base[align * offset[2] + 2] += vgetq_lane_f32(v2.simdInternal_, 2); t3 = vadd_f32(t3, vld1_f32(base + align * offset[3])); vst1_f32(base + align * offset[3], t3); - base[ align * offset[3] + 2] += vgetq_lane_f32(v2.simdInternal_, 3); + base[align * offset[3] + 2] += vgetq_lane_f32(v2.simdInternal_, 3); } else { // Extra elements means we can use full width-4 load/store operations - float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); - float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F)); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); - float32x4_t t4 = t2.val[0]; - float32x4_t t5 = t3.val[0]; - float32x4_t t6 = t2.val[1]; - float32x4_t t7 = t3.val[1]; + float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); + float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F)); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4_t t4 = t2.val[0]; + float32x4_t t5 = t3.val[0]; + float32x4_t t6 = t2.val[1]; + float32x4_t t7 = t3.val[1]; vst1q_f32(base + align * offset[0], vaddq_f32(t4, vld1q_f32(base + align * offset[0]))); vst1q_f32(base + align * offset[1], vaddq_f32(t5, vld1q_f32(base + align * offset[1]))); @@ -199,13 +190,9 @@ transposeScatterIncrU(float * base, } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { assert(std::size_t(offset) % 16 == 0); @@ -221,31 +208,31 @@ transposeScatterDecrU(float * base, t0 = vsub_f32(vld1_f32(base + align * offset[0]), t0); vst1_f32(base + align * offset[0], t0); - base[ align * offset[0] + 2] -= vgetq_lane_f32(v2.simdInternal_, 0); + base[align * offset[0] + 2] -= vgetq_lane_f32(v2.simdInternal_, 0); t1 = vsub_f32(vld1_f32(base + align * offset[1]), t1); vst1_f32(base + align * offset[1], t1); - base[ align * offset[1] + 2] -= vgetq_lane_f32(v2.simdInternal_, 1); + base[align * offset[1] + 2] -= vgetq_lane_f32(v2.simdInternal_, 1); t2 = vsub_f32(vld1_f32(base + align * offset[2]), t2); vst1_f32(base + align * offset[2], t2); - base[ align * offset[2] + 2] -= vgetq_lane_f32(v2.simdInternal_, 2); + base[align * offset[2] + 2] -= vgetq_lane_f32(v2.simdInternal_, 2); t3 = vsub_f32(vld1_f32(base + align * offset[3]), t3); vst1_f32(base + align * offset[3], t3); - base[ align * offset[3] + 2] -= vgetq_lane_f32(v2.simdInternal_, 3); + base[align * offset[3] + 2] -= vgetq_lane_f32(v2.simdInternal_, 3); } else { // Extra elements means we can use full width-4 load/store operations - float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); - float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F)); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); - float32x4_t t4 = t2.val[0]; - float32x4_t t5 = t3.val[0]; - float32x4_t t6 = t2.val[1]; - float32x4_t t7 = t3.val[1]; + float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); + float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, vdupq_n_f32(0.0F)); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4_t t4 = t2.val[0]; + float32x4_t t5 = t3.val[0]; + float32x4_t t6 = t2.val[1]; + float32x4_t t7 = t3.val[1]; vst1q_f32(base + align * offset[0], vsubq_f32(vld1q_f32(base + align * offset[0]), t4)); vst1q_f32(base + align * offset[1], vsubq_f32(vld1q_f32(base + align * offset[1]), t5)); @@ -254,11 +241,10 @@ transposeScatterDecrU(float * base, } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { float32x2_t lo, hi; float32x4_t t0, t1, t2, t3; @@ -277,16 +263,15 @@ expandScalarsToTriplets(SimdFloat scalar, } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 offset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; assert(std::size_t(base) % 16 == 0); assert(align % 4 == 0); @@ -295,53 +280,41 @@ gatherLoadBySimdIntTranspose(const float * base, gatherLoadTranspose(base, ioffset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1); } - -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; store(ioffset, offset); - v0->simdInternal_ = vcombine_f32(vld1_f32( base + align * ioffset[0] ), - vld1_f32( base + align * ioffset[2] )); - v1->simdInternal_ = vcombine_f32(vld1_f32( base + align * ioffset[1] ), - vld1_f32( base + align * ioffset[3] )); - float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_ ); + v0->simdInternal_ = + vcombine_f32(vld1_f32(base + align * ioffset[0]), vld1_f32(base + align * ioffset[2])); + v1->simdInternal_ = + vcombine_f32(vld1_f32(base + align * ioffset[1]), vld1_f32(base + align * ioffset[3])); + float32x4x2_t tmp = vtrnq_f32(v0->simdInternal_, v1->simdInternal_); v0->simdInternal_ = tmp.val[0]; v1->simdInternal_ = tmp.val[1]; } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { assert(std::size_t(m) % 16 == 0); - float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); - float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, v3.simdInternal_); - float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); - float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); + float32x4x2_t t0 = vuzpq_f32(v0.simdInternal_, v2.simdInternal_); + float32x4x2_t t1 = vuzpq_f32(v1.simdInternal_, v3.simdInternal_); + float32x4x2_t t2 = vtrnq_f32(t0.val[0], t1.val[0]); + float32x4x2_t t3 = vtrnq_f32(t0.val[1], t1.val[1]); v0.simdInternal_ = t2.val[0]; v1.simdInternal_ = t3.val[0]; v2.simdInternal_ = t2.val[1]; @@ -356,6 +329,6 @@ reduceIncr4ReturnSum(float * m, return reduce(v0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_definitions.h b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_definitions.h index 20ab5bceea..3b058916fa 100644 --- a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_definitions.h +++ b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,47 +38,47 @@ // ARM (AArch64) NEON Advanced SIMD -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 1 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 1 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 1 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 1 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) -#define GMX_SIMD_RSQRT_BITS 8 -#define GMX_SIMD_RCP_BITS 8 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) +#define GMX_SIMD_RSQRT_BITS 8 +#define GMX_SIMD_RCP_BITS 8 #endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd4_float.h b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd4_float.h index f501402221..d77d4a2f30 100644 --- a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd4_float.h +++ b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd4_float.h @@ -45,71 +45,50 @@ namespace gmx { -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - vrndnq_f32(x.simdInternal_) - }; + return { vrndnq_f32(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - vrndq_f32(x.simdInternal_) - }; + return { vrndq_f32(x.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { return (vmaxvq_u32(a.simdInternal_) != 0); } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { float32x4_t b = a.simdInternal_; - b = vpaddq_f32(b, b); - b = vpaddq_f32(b, b); + b = vpaddq_f32(b, b); + b = vpaddq_f32(b, b); return vgetq_lane_f32(b, 0); } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { Simd4Float c; @@ -119,6 +98,6 @@ dotProduct(Simd4Float a, Simd4Float b) return reduce(c); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_double.h b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_double.h index 38757514ca..2315ea0a5c 100644 --- a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_double.h +++ b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,384 +51,281 @@ namespace gmx class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - SimdDouble(double d) : simdInternal_(vdupq_n_f64(d)) {} + SimdDouble(double d) : simdInternal_(vdupq_n_f64(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(float64x2_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(float64x2_t simd) : simdInternal_(simd) {} - float64x2_t simdInternal_; + float64x2_t simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - SimdDInt32(std::int32_t i) : simdInternal_(vdup_n_s32(i)) {} + SimdDInt32(std::int32_t i) : simdInternal_(vdup_n_s32(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(int32x2_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(int32x2_t simd) : simdInternal_(simd) {} - int32x2_t simdInternal_; + int32x2_t simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - SimdDBool(bool b) : simdInternal_(vdupq_n_u64( b ? 0xFFFFFFFFFFFFFFFF : 0)) {} + SimdDBool(bool b) : simdInternal_(vdupq_n_u64(b ? 0xFFFFFFFFFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdDBool(uint64x2_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(uint64x2_t simd) : simdInternal_(simd) {} - uint64x2_t simdInternal_; + uint64x2_t simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - SimdDIBool(bool b) : simdInternal_(vdup_n_u32( b ? 0xFFFFFFFF : 0)) {} + SimdDIBool(bool b) : simdInternal_(vdup_n_u32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdDIBool(uint32x2_t simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(uint32x2_t simd) : simdInternal_(simd) {} - uint32x2_t simdInternal_; + uint32x2_t simdInternal_; }; -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { assert(std::size_t(m) % 16 == 0); - return { - vld1q_f64(m) - }; + return { vld1q_f64(m) }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { assert(std::size_t(m) % 16 == 0); vst1q_f64(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { - return { - vld1q_f64(m) - }; + return { vld1q_f64(m) }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { vst1q_f64(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - vdupq_n_f64(0.0) - }; + return { vdupq_n_f64(0.0) }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { assert(std::size_t(m) % 8 == 0); - return { - vld1_s32(m) - }; + return { vld1_s32(m) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { assert(std::size_t(m) % 8 == 0); vst1_s32(m, a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { - return { - vld1_s32(m) - }; + return { vld1_s32(m) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { vst1_s32(m, a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - vdup_n_s32(0) - }; + return { vdup_n_s32(0) }; } -template gmx_simdcall -static inline std::int32_t -extract(SimdDInt32 a) +template +gmx_simdcall static inline std::int32_t extract(SimdDInt32 a) { return vget_lane_s32(a.simdInternal_, index); } -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - return { - float64x2_t(vandq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) - }; + return { float64x2_t(vandq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - return { - float64x2_t(vbicq_s64(int64x2_t(b.simdInternal_), int64x2_t(a.simdInternal_))) - }; + return { float64x2_t(vbicq_s64(int64x2_t(b.simdInternal_), int64x2_t(a.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - return { - float64x2_t(vorrq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) - }; + return { float64x2_t(vorrq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - return { - float64x2_t(veorq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) - }; + return { float64x2_t(veorq_s64(int64x2_t(a.simdInternal_), int64x2_t(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - return { - vaddq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vaddq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - return { - vsubq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vsubq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble x) +static inline SimdDouble gmx_simdcall operator-(SimdDouble x) { - return { - vnegq_f64(x.simdInternal_) - }; + return { vnegq_f64(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - return { - vmulq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vmulq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vfmaq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmaq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vnegq_f64(vfmsq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f64(vfmsq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vfmsq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmsq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vnegq_f64(vfmaq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f64(vfmaq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - vrsqrteq_f64(x.simdInternal_) - }; + return { vrsqrteq_f64(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rsqrtIter(SimdDouble lu, SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrtIter(SimdDouble lu, SimdDouble x) { - return { - vmulq_f64(lu.simdInternal_, vrsqrtsq_f64(vmulq_f64(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) - }; + return { vmulq_f64(lu.simdInternal_, + vrsqrtsq_f64(vmulq_f64(lu.simdInternal_, lu.simdInternal_), x.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - vrecpeq_f64(x.simdInternal_) - }; + return { vrecpeq_f64(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rcpIter(SimdDouble lu, SimdDouble x) +static inline SimdDouble gmx_simdcall rcpIter(SimdDouble lu, SimdDouble x) { - return { - vmulq_f64(lu.simdInternal_, vrecpsq_f64(lu.simdInternal_, x.simdInternal_)) - }; + return { vmulq_f64(lu.simdInternal_, vrecpsq_f64(lu.simdInternal_, x.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { float64x2_t addend = float64x2_t(vandq_u64(uint64x2_t(b.simdInternal_), m.simdInternal_)); - return { - vaddq_f64(a.simdInternal_, addend) - }; + return { vaddq_f64(a.simdInternal_, addend) }; } -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { float64x2_t prod = vmulq_f64(a.simdInternal_, b.simdInternal_); - return { - float64x2_t(vandq_u64(uint64x2_t(prod), m.simdInternal_)) - }; + return { float64x2_t(vandq_u64(uint64x2_t(prod), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { float64x2_t prod = vfmaq_f64(c.simdInternal_, b.simdInternal_, a.simdInternal_); - return { - float64x2_t(vandq_u64(uint64x2_t(prod), m.simdInternal_)) - }; + return { float64x2_t(vandq_u64(uint64x2_t(prod), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions #ifndef NDEBUG x.simdInternal_ = vbslq_f64(m.simdInternal_, x.simdInternal_, vdupq_n_f64(1.0)); #endif - return { - float64x2_t(vandq_u64(uint64x2_t(vrsqrteq_f64(x.simdInternal_)), m.simdInternal_)) - }; + return { float64x2_t(vandq_u64(uint64x2_t(vrsqrteq_f64(x.simdInternal_)), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions #ifndef NDEBUG x.simdInternal_ = vbslq_f64(m.simdInternal_, x.simdInternal_, vdupq_n_f64(1.0)); #endif - return { - float64x2_t(vandq_u64(uint64x2_t(vrecpeq_f64(x.simdInternal_)), m.simdInternal_)) - }; + return { float64x2_t(vandq_u64(uint64x2_t(vrecpeq_f64(x.simdInternal_)), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -abs(SimdDouble x) +static inline SimdDouble gmx_simdcall abs(SimdDouble x) { - return { - vabsq_f64( x.simdInternal_ ) - }; + return { vabsq_f64(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - return { - vmaxq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vmaxq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - return { - vminq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vminq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { - return { - vrndnq_f64(x.simdInternal_) - }; + return { vrndnq_f64(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { - return { - vrndq_f64( x.simdInternal_ ) - }; + return { vrndq_f64(x.simdInternal_) }; } -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) { - const float64x2_t exponentMask = float64x2_t( vdupq_n_s64(0x7FF0000000000000LL) ); - const float64x2_t mantissaMask = float64x2_t( vdupq_n_s64(0x800FFFFFFFFFFFFFLL) ); + const float64x2_t exponentMask = float64x2_t(vdupq_n_s64(0x7FF0000000000000LL)); + const float64x2_t mantissaMask = float64x2_t(vdupq_n_s64(0x800FFFFFFFFFFFFFLL)); - const int64x2_t exponentBias = vdupq_n_s64(1022); // add 1 to make our definition identical to frexp() - const float64x2_t half = vdupq_n_f64(0.5); + const int64x2_t exponentBias = vdupq_n_s64(1022); // add 1 to make our definition identical to frexp() + const float64x2_t half = vdupq_n_f64(0.5); int64x2_t iExponent; - iExponent = vandq_s64( int64x2_t(value.simdInternal_), int64x2_t(exponentMask) ); + iExponent = vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(exponentMask)); iExponent = vsubq_s64(vshrq_n_s64(iExponent, 52), exponentBias); exponent->simdInternal_ = vmovn_s64(iExponent); - return { - float64x2_t(vorrq_s64(vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(mantissaMask)), int64x2_t(half))) - }; + return { float64x2_t(vorrq_s64( + vandq_s64(int64x2_t(value.simdInternal_), int64x2_t(mantissaMask)), int64x2_t(half))) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { const int32x2_t exponentBias = vdup_n_s32(1023); int32x2_t iExponent = vadd_s32(exponent.simdInternal_, exponentBias); @@ -443,285 +340,187 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent64 = vmovl_s32(iExponent); iExponent64 = vshlq_n_s64(iExponent64, 52); - return { - vmulq_f64(value.simdInternal_, float64x2_t(iExponent64)) - }; + return { vmulq_f64(value.simdInternal_, float64x2_t(iExponent64)) }; } -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { float64x2_t b = vpaddq_f64(a.simdInternal_, a.simdInternal_); return vgetq_lane_f64(b, 0); } -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - vceqq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vceqq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - vreinterpretq_u64_u32(vmvnq_u32(vreinterpretq_u32_u64(vceqq_f64(a.simdInternal_, b.simdInternal_)))) - }; + return { vreinterpretq_u64_u32( + vmvnq_u32(vreinterpretq_u32_u64(vceqq_f64(a.simdInternal_, b.simdInternal_)))) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - vcltq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vcltq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - vcleq_f64(a.simdInternal_, b.simdInternal_) - }; + return { vcleq_f64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { - return { - vtstq_s64( int64x2_t(a.simdInternal_), int64x2_t(a.simdInternal_) ) - }; + return { vtstq_s64(int64x2_t(a.simdInternal_), int64x2_t(a.simdInternal_)) }; } -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - vandq_u64(a.simdInternal_, b.simdInternal_) - }; + return { vandq_u64(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - vorrq_u64(a.simdInternal_, b.simdInternal_) - }; + return { vorrq_u64(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) +static inline bool gmx_simdcall anyTrue(SimdDBool a) { return (vmaxvq_u32((uint32x4_t)(a.simdInternal_)) != 0); } -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool m) { - return { - float64x2_t(vandq_u64(uint64x2_t(a.simdInternal_), m.simdInternal_)) - }; + return { float64x2_t(vandq_u64(uint64x2_t(a.simdInternal_), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool m) { - return { - float64x2_t(vbicq_u64(uint64x2_t(a.simdInternal_), m.simdInternal_)) - }; + return { float64x2_t(vbicq_u64(uint64x2_t(a.simdInternal_), m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - vbslq_f64(sel.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vbslq_f64(sel.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - vand_s32(a.simdInternal_, b.simdInternal_) - }; + return { vand_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - vbic_s32(b.simdInternal_, a.simdInternal_) - }; + return { vbic_s32(b.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - vorr_s32(a.simdInternal_, b.simdInternal_) - }; + return { vorr_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - veor_s32(a.simdInternal_, b.simdInternal_) - }; + return { veor_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - vadd_s32(a.simdInternal_, b.simdInternal_) - }; + return { vadd_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - vsub_s32(a.simdInternal_, b.simdInternal_) - }; + return { vsub_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - vmul_s32(a.simdInternal_, b.simdInternal_) - }; + return { vmul_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - vceq_s32(a.simdInternal_, b.simdInternal_) - }; + return { vceq_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { - return { - vtst_s32( a.simdInternal_, a.simdInternal_) - }; + return { vtst_s32(a.simdInternal_, a.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - vclt_s32(a.simdInternal_, b.simdInternal_) - }; + return { vclt_s32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - vand_u32(a.simdInternal_, b.simdInternal_) - }; + return { vand_u32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - vorr_u32(a.simdInternal_, b.simdInternal_) - }; + return { vorr_u32(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) +static inline bool gmx_simdcall anyTrue(SimdDIBool a) { return (vmaxv_u32(a.simdInternal_) != 0); } -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool m) { - return { - vand_s32(a.simdInternal_, vreinterpret_s32_u32(m.simdInternal_)) - }; + return { vand_s32(a.simdInternal_, vreinterpret_s32_u32(m.simdInternal_)) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool m) { - return { - vbic_s32(a.simdInternal_, vreinterpret_s32_u32(m.simdInternal_)) - }; + return { vbic_s32(a.simdInternal_, vreinterpret_s32_u32(m.simdInternal_)) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - vbsl_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vbsl_s32(sel.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { - return { - vmovn_s64(vcvtnq_s64_f64(a.simdInternal_)) - }; + return { vmovn_s64(vcvtnq_s64_f64(a.simdInternal_)) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { - return { - vmovn_s64(vcvtq_s64_f64(a.simdInternal_)) - }; + return { vmovn_s64(vcvtq_s64_f64(a.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { - return { - vcvtq_f64_s64(vmovl_s32(a.simdInternal_)) - }; + return { vcvtq_f64_s64(vmovl_s32(a.simdInternal_)) }; } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { - return { - vqmovn_u64(a.simdInternal_) - }; + return { vqmovn_u64(a.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { - return { - vorrq_u64(vmovl_u32(a.simdInternal_), vshlq_n_u64(vmovl_u32(a.simdInternal_), 32)) - }; + return { vorrq_u64(vmovl_u32(a.simdInternal_), vshlq_n_u64(vmovl_u32(a.simdInternal_), 32)) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { d0->simdInternal_ = vcvt_f64_f32(vget_low_f32(f.simdInternal_)); d1->simdInternal_ = vcvt_high_f64_f32(f.simdInternal_); } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { - return { - vcvt_high_f32_f64(vcvt_f32_f64(d0.simdInternal_), d1.simdInternal_) - }; + return { vcvt_high_f32_f64(vcvt_f32_f64(d0.simdInternal_), d1.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_float.h b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_float.h index 340f9298d9..ee825f388d 100644 --- a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_float.h +++ b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,83 +45,59 @@ namespace gmx { -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f32(vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) - }; + return { vfmsq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) - }; + return { vnegq_f32(vfmaq_f32(c.simdInternal_, b.simdInternal_, a.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - vrndnq_f32(x.simdInternal_) - }; + return { vrndnq_f32(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - vrndq_f32(x.simdInternal_) - }; + return { vrndq_f32(x.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - vcvtnq_s32_f32(a.simdInternal_) - }; + return { vcvtnq_s32_f32(a.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { return (vmaxvq_u32(a.simdInternal_) != 0); } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { return (vmaxvq_u32(a.simdInternal_) != 0); } -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { float32x4_t b = a.simdInternal_; - b = vpaddq_f32(b, b); - b = vpaddq_f32(b, b); + b = vpaddq_f32(b, b); + b = vpaddq_f32(b, b); return vgetq_lane_f32(b, 0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_util_double.h b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_util_double.h index 4377c00618..a3d7454c87 100644 --- a/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_util_double.h +++ b/src/gromacs/simd/impl_arm_neon_asimd/impl_arm_neon_asimd_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,14 +49,13 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { float64x2_t t1, t2, t3, t4; @@ -74,12 +73,9 @@ gatherLoadTranspose(const double * base, v3->simdInternal_ = vuzp2q_f64(t3, t4); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { float64x2_t t1, t2; @@ -95,13 +91,12 @@ gatherLoadTranspose(const double * base, static const int c_simdBestPairAlignmentDouble = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { float64x2_t t1, t2; float64x1_t t3, t4; @@ -117,41 +112,36 @@ gatherLoadUTranspose(const double * base, v2->simdInternal_ = vcombine_f64(t3, t4); } -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { float64x2_t t0, t1; assert(std::size_t(offset) % 8 == 0); - t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); - t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); + t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); + t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); vst1q_f64(base + align * offset[0], t0); vst1q_f64(base + align * offset[1], t1); vst1_f64(base + align * offset[0] + 2, vget_low_f64(v2.simdInternal_)); vst1_f64(base + align * offset[1] + 2, vget_high_f64(v2.simdInternal_)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { float64x2_t t0, t1, t2; float64x1_t t3; assert(std::size_t(offset) % 8 == 0); - t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); // x0 y0 - t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); // x1 y1 + t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); // x0 y0 + t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); // x1 y1 t2 = vld1q_f64(base + align * offset[0]); t2 = vaddq_f64(t2, t0); @@ -170,21 +160,17 @@ transposeScatterIncrU(double * base, vst1_f64(base + align * offset[1] + 2, t3); } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { float64x2_t t0, t1, t2; float64x1_t t3; assert(std::size_t(offset) % 8 == 0); - t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); // x0 y0 - t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); // x1 y1 + t0 = vuzp1q_f64(v0.simdInternal_, v1.simdInternal_); // x0 y0 + t1 = vuzp2q_f64(v0.simdInternal_, v1.simdInternal_); // x1 y1 t2 = vld1q_f64(base + align * offset[0]); t2 = vsubq_f64(t2, t0); @@ -203,27 +189,25 @@ transposeScatterDecrU(double * base, vst1_f64(base + align * offset[1] + 2, t3); } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { triplets0->simdInternal_ = vuzp1q_f64(scalar.simdInternal_, scalar.simdInternal_); triplets1->simdInternal_ = scalar.simdInternal_; triplets2->simdInternal_ = vuzp2q_f64(scalar.simdInternal_, scalar.simdInternal_); } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 offset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; assert(std::size_t(base) % 16 == 0); assert(align % 2 == 0); @@ -233,14 +217,11 @@ gatherLoadBySimdIntTranspose(const double * base, } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; assert(std::size_t(base) % 16 == 0); assert(align % 2 == 0); @@ -249,14 +230,11 @@ gatherLoadBySimdIntTranspose(const double * base, gatherLoadTranspose(base, ioffset, v0, v1); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; vst1_s32(ioffset, offset.simdInternal_); @@ -270,11 +248,7 @@ gatherLoadUBySimdIntTranspose(const double * base, static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { float64x2_t t1, t2, t3, t4; @@ -299,6 +273,6 @@ reduceIncr4ReturnSum(double * m, return vgetq_lane_f64(t2, 0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_ARM_NEON_ASIMD_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_definitions.h b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_definitions.h index 3400c80977..d91fc6db79 100644 --- a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_definitions.h +++ b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,56 +41,56 @@ #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) // According to G++ documentation, when using altivec in C++ we // must undefine vector & bool macros after including altivec.h -# undef vector -# undef bool +# undef vector +# undef bool # define vmxBool __bool #else // We cannot undefine bool on xlc, but somehow it works anyway # define vmxBool bool #endif -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 0 -#define GMX_SIMD_HAVE_LOADU 0 -#define GMX_SIMD_HAVE_STOREU 0 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 0 +#define GMX_SIMD_HAVE_LOADU 0 +#define GMX_SIMD_HAVE_STOREU 0 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#undef GMX_SIMD_DOUBLE_WIDTH -#define GMX_SIMD_FINT32_WIDTH 4 -#undef GMX_SIMD_DINT32_WIDTH -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single) -#define GMX_SIMD_RSQRT_BITS 14 -#define GMX_SIMD_RCP_BITS 14 +#define GMX_SIMD_FLOAT_WIDTH 4 +#undef GMX_SIMD_DOUBLE_WIDTH +#define GMX_SIMD_FINT32_WIDTH 4 +#undef GMX_SIMD_DINT32_WIDTH +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single) +#define GMX_SIMD_RSQRT_BITS 14 +#define GMX_SIMD_RCP_BITS 14 #endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_general.h b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_general.h index 33185c397e..d93c8086e8 100644 --- a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_general.h +++ b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,8 +39,7 @@ namespace gmx { -static inline void -simdPrefetch(const void * m) +static inline void simdPrefetch(const void* m) { #if defined(__ibmxl__) || defined(__xlC__) __dcbt(m); @@ -49,6 +48,6 @@ simdPrefetch(const void * m) #endif } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_GENERAL_H diff --git a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd4_float.h b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd4_float.h index f979bcc250..c489f92061 100644 --- a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd4_float.h +++ b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,213 +47,154 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) - { - __vector unsigned char perm; + Simd4Float(float f) + { + __vector unsigned char perm; - simdInternal_ = vec_lde(0, const_cast(&f)); - perm = vec_lvsl(0, const_cast(&f)); - simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); - simdInternal_ = vec_splat(simdInternal_, 0); - } + simdInternal_ = vec_lde(0, const_cast(&f)); + perm = vec_lvsl(0, const_cast(&f)); + simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); + simdInternal_ = vec_splat(simdInternal_, 0); + } - // Internal utility constructor to simplify return statements - Simd4Float(__vector float simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__vector float simd) : simdInternal_(simd) {} - __vector float simdInternal_; + __vector float simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - Simd4FBool(bool b) - { - simdInternal_ = reinterpret_cast<__vector vmxBool int>(vec_splat_u32( b ? 0xFFFFFFFF : 0)); - } + Simd4FBool(bool b) + { + simdInternal_ = reinterpret_cast<__vector vmxBool int>(vec_splat_u32(b ? 0xFFFFFFFF : 0)); + } - // Internal utility constructor to simplify return statements - Simd4FBool(__vector vmxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__vector vmxBool int simd) : simdInternal_(simd) {} - __vector vmxBool int simdInternal_; + __vector vmxBool int simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { - return { - vec_ld(0, const_cast(m)) - }; + return { vec_ld(0, const_cast(m)) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { - vec_st(a.simdInternal_, 0, const_cast(m)); + vec_st(a.simdInternal_, 0, const_cast(m)); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - reinterpret_cast<__vector float>(vec_splat_u32(0)) - }; + return { reinterpret_cast<__vector float>(vec_splat_u32(0)) }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - vec_xor(x.simdInternal_, reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) - }; + return { vec_xor(x.simdInternal_, + reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, reinterpret_cast<__vector float>(vec_splat_u32(0)) ) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, + reinterpret_cast<__vector float>(vec_splat_u32(0))) }; } -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - vec_rsqrte(x.simdInternal_) - }; + return { vec_rsqrte(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - vec_abs( x.simdInternal_ ) - }; + return { vec_abs(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - vec_max(a.simdInternal_, b.simdInternal_) - }; + return { vec_max(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - vec_min(a.simdInternal_, b.simdInternal_) - }; + return { vec_min(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - vec_round( x.simdInternal_ ) - }; + return { vec_round(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - vec_trunc( x.simdInternal_ ) - }; + return { vec_trunc(x.simdInternal_) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { - float res; + float res; - __vector float c = vec_madd(a.simdInternal_, b.simdInternal_, reinterpret_cast<__vector float>(vec_splat_u32(0))); + __vector float c = vec_madd(a.simdInternal_, b.simdInternal_, + reinterpret_cast<__vector float>(vec_splat_u32(0))); // Keep only elements 0,1,2 by shifting in zero from right (xor of a vector with itself is 0) c = vec_sld(c, vec_xor(a.simdInternal_, a.simdInternal_), 4); // calculate sum @@ -263,9 +204,7 @@ dotProduct(Simd4Float a, Simd4Float b) return res; } -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { __vector float t0 = vec_mergeh(v0->simdInternal_, v2->simdInternal_); __vector float t1 = vec_mergel(v0->simdInternal_, v2->simdInternal_); @@ -277,87 +216,58 @@ transpose(Simd4Float * v0, Simd4Float * v1, v3->simdInternal_ = vec_mergel(t1, t3); } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), - vec_cmplt(a.simdInternal_, b.simdInternal_)) - }; + return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), + vec_cmplt(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - vec_cmple(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmple(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0))); } -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __vector float c = a.simdInternal_; float res; @@ -369,6 +279,6 @@ reduce(Simd4Float a) return res; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd_float.h b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd_float.h index cc51a61aeb..159bac73f7 100644 --- a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd_float.h +++ b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_simd_float.h @@ -50,349 +50,272 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) - { - __vector unsigned char perm; + SimdFloat(float f) + { + __vector unsigned char perm; - simdInternal_ = vec_lde(0, const_cast(&f)); - perm = vec_lvsl(0, const_cast(&f)); - simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); - simdInternal_ = vec_splat(simdInternal_, 0); - } + simdInternal_ = vec_lde(0, const_cast(&f)); + perm = vec_lvsl(0, const_cast(&f)); + simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); + simdInternal_ = vec_splat(simdInternal_, 0); + } - // Internal utility constructor to simplify return statements - SimdFloat(__vector float simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__vector float simd) : simdInternal_(simd) {} - __vector float simdInternal_; + __vector float simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) - { - __vector unsigned char perm; + SimdFInt32(std::int32_t i) + { + __vector unsigned char perm; - simdInternal_ = vec_lde(0, const_cast(&i)); - perm = vec_lvsl(0, const_cast(&i)); - simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); - simdInternal_ = vec_splat(simdInternal_, 0); - } + simdInternal_ = vec_lde(0, const_cast(&i)); + perm = vec_lvsl(0, const_cast(&i)); + simdInternal_ = vec_perm(simdInternal_, simdInternal_, perm); + simdInternal_ = vec_splat(simdInternal_, 0); + } - // Internal utility constructor to simplify return statements - SimdFInt32(__vector signed int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__vector signed int simd) : simdInternal_(simd) {} - __vector signed int simdInternal_; + __vector signed int simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_( reinterpret_cast<__vector vmxBool int>(vec_splat_u32( b ? 0xFFFFFFFF : 0))) {} + SimdFBool(bool b) : + simdInternal_(reinterpret_cast<__vector vmxBool int>(vec_splat_u32(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdFBool(__vector vmxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__vector vmxBool int simd) : simdInternal_(simd) {} - __vector vmxBool int simdInternal_; + __vector vmxBool int simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_( reinterpret_cast<__vector vmxBool int>(vec_splat_u32( b ? 0xFFFFFFFF : 0))) {} + SimdFIBool(bool b) : + simdInternal_(reinterpret_cast<__vector vmxBool int>(vec_splat_u32(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdFIBool(__vector vmxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__vector vmxBool int simd) : simdInternal_(simd) {} - __vector vmxBool int simdInternal_; + __vector vmxBool int simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { - return { - vec_ld(0, const_cast(m)) - }; + return { vec_ld(0, const_cast(m)) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { - vec_st(a.simdInternal_, 0, const_cast(m)); + vec_st(a.simdInternal_, 0, const_cast(m)); } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - reinterpret_cast<__vector float>(vec_splat_u32(0)) - }; + return { reinterpret_cast<__vector float>(vec_splat_u32(0)) }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { - return { - vec_ld(0, const_cast(m)) - }; + return { vec_ld(0, const_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { - vec_st(a.simdInternal_, 0, const_cast(m)); + vec_st(a.simdInternal_, 0, const_cast(m)); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - vec_splat_s32(0) - }; + return { vec_splat_s32(0) }; } -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - vec_xor(x.simdInternal_, reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) - }; + return { vec_xor(x.simdInternal_, + reinterpret_cast<__vector float>(vec_sl(vec_splat_u32(-1), vec_splat_u32(-1)))) }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, reinterpret_cast<__vector float>(vec_splat_u32(0)) ) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, + reinterpret_cast<__vector float>(vec_splat_u32(0))) }; } -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, -c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { -vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - vec_rsqrte(x.simdInternal_) - }; + return { vec_rsqrte(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - vec_re(x.simdInternal_) - }; + return { vec_re(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - vec_add(a.simdInternal_, vec_and(b.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_))) - }; + return { vec_add(a.simdInternal_, + vec_and(b.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { SimdFloat prod = a * b; - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { SimdFloat prod = fma(a, b, c); - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { #ifndef NDEBUG SimdFloat one(1.0F); x.simdInternal_ = vec_sel(one.simdInternal_, x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { #ifndef NDEBUG SimdFloat one(1.0F); x.simdInternal_ = vec_sel(one.simdInternal_, x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - vec_abs( x.simdInternal_ ) - }; + return { vec_abs(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - vec_max(a.simdInternal_, b.simdInternal_) - }; + return { vec_max(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - vec_min(a.simdInternal_, b.simdInternal_) - }; + return { vec_min(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - vec_round( x.simdInternal_ ) - }; + return { vec_round(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - vec_trunc( x.simdInternal_ ) - }; + return { vec_trunc(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { // Generate constants without memory operations - const __vector signed int exponentMask = vec_sl(vec_add(vec_splat_s32(15), vec_sl(vec_splat_s32(15), vec_splat_u32(4))), - vec_add(vec_splat_u32(15), vec_splat_u32(8))); // 0x7F800000 - const __vector signed int exponentBias = vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(2)); // 126 - const SimdFloat half(0.5F); - __vector signed int iExponent; - - iExponent = vec_and(reinterpret_cast<__vector signed int>(value.simdInternal_), exponentMask); - iExponent = vec_sr(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8))); - iExponent = vec_sub(iExponent, exponentBias); + const __vector signed int exponentMask = + vec_sl(vec_add(vec_splat_s32(15), vec_sl(vec_splat_s32(15), vec_splat_u32(4))), + vec_add(vec_splat_u32(15), vec_splat_u32(8))); // 0x7F800000 + const __vector signed int exponentBias = + vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(2)); // 126 + const SimdFloat half(0.5F); + __vector signed int iExponent; + + iExponent = vec_and(reinterpret_cast<__vector signed int>(value.simdInternal_), exponentMask); + iExponent = vec_sr(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8))); + iExponent = vec_sub(iExponent, exponentBias); exponent->simdInternal_ = iExponent; - return { - vec_or( vec_andc(value.simdInternal_, reinterpret_cast<__vector float>(exponentMask)), half.simdInternal_) - }; + return { vec_or(vec_andc(value.simdInternal_, reinterpret_cast<__vector float>(exponentMask)), + half.simdInternal_) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { - const __vector signed int exponentBias = vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(1)); // 127 - __vector signed int iExponent; + const __vector signed int exponentBias = + vec_sub(vec_sl(vec_splat_s32(1), vec_splat_u32(7)), vec_splat_s32(1)); // 127 + __vector signed int iExponent; - iExponent = vec_add(exponent.simdInternal_, exponentBias); + iExponent = vec_add(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -400,15 +323,13 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = vec_max(iExponent, vec_splat_s32(0)); } - iExponent = vec_sl(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8))); + iExponent = vec_sl(iExponent, vec_add(vec_splat_u32(15), vec_splat_u32(8))); - return { - vec_madd(value.simdInternal_, reinterpret_cast<__vector float>(iExponent), reinterpret_cast<__vector float>(vec_splat_u32(0))) - }; + return { vec_madd(value.simdInternal_, reinterpret_cast<__vector float>(iExponent), + reinterpret_cast<__vector float>(vec_splat_u32(0))) }; } -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { __vector float c = a.simdInternal_; float res; @@ -420,259 +341,167 @@ reduce(SimdFloat a) return res; } -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), - vec_cmplt(a.simdInternal_, b.simdInternal_)) - }; + return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), + vec_cmplt(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - vec_cmple(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmple(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { - return { - vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0))); } -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - a.simdInternal_ * b.simdInternal_ - }; + return { a.simdInternal_ * b.simdInternal_ }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splat_u32(0)) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vmxBool int>(vec_splat_u32(0))); } -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - vec_cts(vec_round(a.simdInternal_), 0) - }; + return { vec_cts(vec_round(a.simdInternal_), 0) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - vec_cts(a.simdInternal_, 0) - }; + return { vec_cts(a.simdInternal_, 0) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - vec_ctf(a.simdInternal_, 0) - }; + return { vec_ctf(a.simdInternal_, 0) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VMX_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_util_float.h b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_util_float.h index 3fc3aaa117..20d1709907 100644 --- a/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_util_float.h +++ b/src/gromacs/simd/impl_ibm_vmx/impl_ibm_vmx_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,19 +48,18 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { - *v0 = simdLoad( base + align * offset[0] ); - *v1 = simdLoad( base + align * offset[1] ); - *v2 = simdLoad( base + align * offset[2] ); - *v3 = simdLoad( base + align * offset[3] ); + *v0 = simdLoad(base + align * offset[0]); + *v1 = simdLoad(base + align * offset[1]); + *v2 = simdLoad(base + align * offset[2]); + *v3 = simdLoad(base + align * offset[3]); __vector float t0 = vec_mergeh(v0->simdInternal_, v2->simdInternal_); __vector float t1 = vec_mergel(v0->simdInternal_, v2->simdInternal_); @@ -72,12 +71,9 @@ gatherLoadTranspose(const float * base, v3->simdInternal_ = vec_mergel(t1, t3); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { if (align % 4 == 0) { @@ -130,13 +126,12 @@ gatherLoadTranspose(const float * base, static const int c_simdBestPairAlignmentFloat = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { if (align % 4 == 0) { @@ -202,24 +197,20 @@ gatherLoadUTranspose(const float * base, } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __vector unsigned char p0, p1, p2, p3; - __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_); - __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); - __vector float t2 = vec_mergeh(v1.simdInternal_, v2.simdInternal_); - __vector float t3 = vec_mergel(v1.simdInternal_, v2.simdInternal_); - __vector float t4 = vec_mergeh(t0, t2); - __vector float t5 = vec_mergel(t0, t2); - __vector float t6 = vec_mergeh(t1, t3); - __vector float t7 = vec_mergel(t1, t3); + __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_); + __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); + __vector float t2 = vec_mergeh(v1.simdInternal_, v2.simdInternal_); + __vector float t3 = vec_mergel(v1.simdInternal_, v2.simdInternal_); + __vector float t4 = vec_mergeh(t0, t2); + __vector float t5 = vec_mergel(t0, t2); + __vector float t6 = vec_mergeh(t1, t3); + __vector float t7 = vec_mergel(t1, t3); p0 = vec_lvsr(0, base + align * offset[0]); p1 = vec_lvsr(0, base + align * offset[1]); @@ -246,13 +237,9 @@ transposeScatterStoreU(float * base, } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { if (align % 4 == 0) { @@ -266,10 +253,10 @@ transposeScatterIncrU(float * base, __vector float t6 = vec_mergeh(t1, t3); __vector float t7 = vec_mergel(t1, t3); - vec_st( vec_add( vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]); - vec_st( vec_add( vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]); - vec_st( vec_add( vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]); - vec_st( vec_add( vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]); + vec_st(vec_add(vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]); + vec_st(vec_add(vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]); + vec_st(vec_add(vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]); + vec_st(vec_add(vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]); } else { @@ -281,28 +268,24 @@ transposeScatterIncrU(float * base, vec_st(v1.simdInternal_, 0, rdata1); vec_st(v2.simdInternal_, 0, rdata2); - base[align*offset[0] + 0] += rdata0[0]; - base[align*offset[0] + 1] += rdata1[0]; - base[align*offset[0] + 2] += rdata2[0]; - base[align*offset[1] + 0] += rdata0[1]; - base[align*offset[1] + 1] += rdata1[1]; - base[align*offset[1] + 2] += rdata2[1]; - base[align*offset[2] + 0] += rdata0[2]; - base[align*offset[2] + 1] += rdata1[2]; - base[align*offset[2] + 2] += rdata2[2]; - base[align*offset[3] + 0] += rdata0[3]; - base[align*offset[3] + 1] += rdata1[3]; - base[align*offset[3] + 2] += rdata2[3]; + base[align * offset[0] + 0] += rdata0[0]; + base[align * offset[0] + 1] += rdata1[0]; + base[align * offset[0] + 2] += rdata2[0]; + base[align * offset[1] + 0] += rdata0[1]; + base[align * offset[1] + 1] += rdata1[1]; + base[align * offset[1] + 2] += rdata2[1]; + base[align * offset[2] + 0] += rdata0[2]; + base[align * offset[2] + 1] += rdata1[2]; + base[align * offset[2] + 2] += rdata2[2]; + base[align * offset[3] + 0] += rdata0[3]; + base[align * offset[3] + 1] += rdata1[3]; + base[align * offset[3] + 2] += rdata2[3]; } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { if (align % 4 == 0) { @@ -316,10 +299,10 @@ transposeScatterDecrU(float * base, __vector float t6 = vec_mergeh(t1, t3); __vector float t7 = vec_mergel(t1, t3); - vec_st( vec_sub( vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]); - vec_st( vec_sub( vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]); - vec_st( vec_sub( vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]); - vec_st( vec_sub( vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]); + vec_st(vec_sub(vec_ld(0, base + align * offset[0]), t4), 0, base + align * offset[0]); + vec_st(vec_sub(vec_ld(0, base + align * offset[1]), t5), 0, base + align * offset[1]); + vec_st(vec_sub(vec_ld(0, base + align * offset[2]), t6), 0, base + align * offset[2]); + vec_st(vec_sub(vec_ld(0, base + align * offset[3]), t7), 0, base + align * offset[3]); } else { @@ -331,30 +314,30 @@ transposeScatterDecrU(float * base, vec_st(v1.simdInternal_, 0, rdata1); vec_st(v2.simdInternal_, 0, rdata2); - base[align*offset[0] + 0] -= rdata0[0]; - base[align*offset[0] + 1] -= rdata1[0]; - base[align*offset[0] + 2] -= rdata2[0]; - base[align*offset[1] + 0] -= rdata0[1]; - base[align*offset[1] + 1] -= rdata1[1]; - base[align*offset[1] + 2] -= rdata2[1]; - base[align*offset[2] + 0] -= rdata0[2]; - base[align*offset[2] + 1] -= rdata1[2]; - base[align*offset[2] + 2] -= rdata2[2]; - base[align*offset[3] + 0] -= rdata0[3]; - base[align*offset[3] + 1] -= rdata1[3]; - base[align*offset[3] + 2] -= rdata2[3]; + base[align * offset[0] + 0] -= rdata0[0]; + base[align * offset[0] + 1] -= rdata1[0]; + base[align * offset[0] + 2] -= rdata2[0]; + base[align * offset[1] + 0] -= rdata0[1]; + base[align * offset[1] + 1] -= rdata1[1]; + base[align * offset[1] + 2] -= rdata2[1]; + base[align * offset[2] + 0] -= rdata0[2]; + base[align * offset[2] + 1] -= rdata1[2]; + base[align * offset[2] + 2] -= rdata2[2]; + base[align * offset[3] + 0] -= rdata0[3]; + base[align * offset[3] + 1] -= rdata1[3]; + base[align * offset[3] + 2] -= rdata2[3]; } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { const __vector unsigned char perm0 = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7 }; const __vector unsigned char perm1 = { 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11 }; - const __vector unsigned char perm2 = { 8, 9, 10, 11, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15 }; + const __vector unsigned char perm2 = { 8, 9, 10, 11, 12, 13, 14, 15, + 12, 13, 14, 15, 12, 13, 14, 15 }; triplets0->simdInternal_ = vec_perm(scalar.simdInternal_, scalar.simdInternal_, perm0); triplets1->simdInternal_ = vec_perm(scalar.simdInternal_, scalar.simdInternal_, perm1); @@ -362,51 +345,41 @@ expandScalarsToTriplets(SimdFloat scalar, } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 offset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - vec_st( offset.simdInternal_, 0, ioffset); + vec_st(offset.simdInternal_, 0, ioffset); gatherLoadTranspose(base, ioffset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - vec_st( offset.simdInternal_, 0, ioffset); + vec_st(offset.simdInternal_, 0, ioffset); gatherLoadTranspose(base, ioffset, v0, v1); } - -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_); __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); __vector float t2 = vec_mergeh(v1.simdInternal_, v3.simdInternal_); __vector float t3 = vec_mergel(v1.simdInternal_, v3.simdInternal_); - v0.simdInternal_ = vec_mergeh(t0, t2); - v1.simdInternal_ = vec_mergel(t0, t2); - v2.simdInternal_ = vec_mergeh(t1, t3); - v3.simdInternal_ = vec_mergel(t1, t3); + v0.simdInternal_ = vec_mergeh(t0, t2); + v1.simdInternal_ = vec_mergel(t0, t2); + v2.simdInternal_ = vec_mergeh(t1, t3); + v3.simdInternal_ = vec_mergel(t1, t3); v0 = v0 + v1; v2 = v2 + v3; @@ -417,6 +390,6 @@ reduceIncr4ReturnSum(float * m, return reduce(v0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_IBM_VMX_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_definitions.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_definitions.h index cac2236141..76bd1cb500 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_definitions.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,72 +47,73 @@ #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) // According to G++ documentation, when using VSX in C++ we // must undefine vector & bool macros after including altivec.h -# undef vector -# undef bool +# undef vector +# undef bool # define vsxBool __bool #else // We cannot undefine bool on xlc, but somehow it works anyway # define vsxBool bool #endif -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 // GMX_SIMD_HAVE_DOUBLE is conditionally defined further down -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 // GMX_SIMD_HAVE_DINT32_EXTRACT is conditionally defined further down // GMX_SIMD_HAVE_DINT32_LOGICAL is conditionally defined further down // GMX_SIMD_HAVE_DINT32_ARITHMETICS is conditionally defined further down -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 // GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE is conditionally defined further down -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // With GCC, only version 4.9 or later supports all parts of double precision VSX. // We check explicitly for xlc, since that compiler appears to like pretending it is gcc, // but there double precision seems to work fine. -#if defined(__ibmxl__) || defined(__xlC__) || !(defined(__GNUC__) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 9)))) -# define GMX_SIMD_HAVE_DOUBLE 1 -# define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -# define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -# define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#if defined(__ibmxl__) || defined(__xlC__) \ + || !(defined(__GNUC__) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 9)))) +# define GMX_SIMD_HAVE_DOUBLE 1 +# define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +# define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +# define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 #else -# define GMX_SIMD_HAVE_DOUBLE 0 -# define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -# define GMX_SIMD_HAVE_DINT32_LOGICAL 0 -# define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 -# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 +# define GMX_SIMD_HAVE_DOUBLE 0 +# define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +# define GMX_SIMD_HAVE_DINT32_LOGICAL 0 +# define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 +# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 0 #endif // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*sdouble) -#define GMX_SIMD_RSQRT_BITS 14 -#define GMX_SIMD_RCP_BITS 14 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*sdouble) +#define GMX_SIMD_RSQRT_BITS 14 +#define GMX_SIMD_RCP_BITS 14 #endif /* GMX_SIMD_IMPLEMENTATION_IBM_VSX_COMMON_H */ diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_general.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_general.h index 89adcd4efd..03045e519e 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_general.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -39,16 +39,15 @@ namespace gmx { -static inline void -simdPrefetch(const void * m) +static inline void simdPrefetch(const void* m) { #if defined(__ibmxl__) || defined(__xlC__) - __dcbt((void *)m); + __dcbt((void*)m); #elif defined __GNUC__ __builtin_prefetch(m); #endif } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_GENERAL_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd4_float.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd4_float.h index 0876d93ee5..b6957e249e 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd4_float.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd4_float.h @@ -48,30 +48,33 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - // gcc-4.9 does not recognize that we use the parameter - Simd4Float(float gmx_unused f) : simdInternal_(vec_splats(f)) {} + // gcc-4.9 does not recognize that we use the parameter + Simd4Float(float gmx_unused f) : simdInternal_(vec_splats(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(__vector float simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__vector float simd) : simdInternal_(simd) {} - __vector float simdInternal_; + __vector float simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - //! \brief Construct from scalar bool - Simd4FBool(bool b) : simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats( b ? 0xFFFFFFFF : 0))) {} + //! \brief Construct from scalar bool + Simd4FBool(bool b) : + simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - Simd4FBool(__vector vsxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__vector vsxBool int simd) : simdInternal_(simd) {} - __vector vsxBool int simdInternal_; + __vector vsxBool int simdInternal_; }; // The VSX load & store operations are a bit of a mess. The interface is different @@ -88,196 +91,133 @@ class Simd4FBool // revisit things once xlc is a bit more stable - for now you probably want // to stick to gcc... -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { - return { - *reinterpret_cast(m) - }; + return { *reinterpret_cast(m) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { - *reinterpret_cast<__vector float *>(m) = a.simdInternal_; + *reinterpret_cast<__vector float*>(m) = a.simdInternal_; } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { + return + { #if __GNUC__ < 7 - *reinterpret_cast(m) + *reinterpret_cast(m) #else - vec_xl(0, m) + vec_xl(0, m) #endif }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { #if __GNUC__ < 7 - *reinterpret_cast<__vector float *>(m) = a.simdInternal_; + *reinterpret_cast<__vector float*>(m) = a.simdInternal_; #else vec_xst(a.simdInternal_, 0, m); #endif } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - vec_splats(0.0F) - }; + return { vec_splats(0.0F) }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - -x.simdInternal_ - }; + return { -x.simdInternal_ }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - vec_mul(a.simdInternal_, b.simdInternal_) - }; + return { vec_mul(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - vec_rsqrte(x.simdInternal_) - }; + return { vec_rsqrte(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - vec_abs( x.simdInternal_ ) - }; + return { vec_abs(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - vec_max(a.simdInternal_, b.simdInternal_) - }; + return { vec_max(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - vec_min(a.simdInternal_, b.simdInternal_) - }; + return { vec_min(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - vec_round( x.simdInternal_ ) - }; + return { vec_round(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - vec_trunc( x.simdInternal_ ) - }; + return { vec_trunc(x.simdInternal_) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { const __vector unsigned char perm1 = { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 }; const __vector unsigned char perm2 = { 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 }; @@ -288,9 +228,7 @@ dotProduct(Simd4Float a, Simd4Float b) return vec_extract(sum, 0); } -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { __vector float t0 = vec_mergeh(v0->simdInternal_, v2->simdInternal_); __vector float t1 = vec_mergel(v0->simdInternal_, v2->simdInternal_); @@ -302,87 +240,58 @@ transpose(Simd4Float * v0, Simd4Float * v1, v3->simdInternal_ = vec_mergel(t1, t3); } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), - vec_cmplt(a.simdInternal_, b.simdInternal_)) - }; + return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), + vec_cmplt(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - vec_cmple(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmple(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vsxBool int>(vec_splats(0))); } -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline float gmx_simdcall -reduce(Simd4Float x) +static inline float gmx_simdcall reduce(Simd4Float x) { const __vector unsigned char perm1 = { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 }; const __vector unsigned char perm2 = { 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 }; @@ -392,6 +301,6 @@ reduce(Simd4Float x) return vec_extract(x.simdInternal_, 0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_double.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_double.h index b70adf7333..da46d0852d 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_double.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,423 +48,338 @@ namespace gmx class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - // gcc-4.9 does not recognize that we use the parameter - SimdDouble(double gmx_unused d) : simdInternal_(vec_splats(d)) {} + // gcc-4.9 does not recognize that we use the parameter + SimdDouble(double gmx_unused d) : simdInternal_(vec_splats(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(__vector double simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(__vector double simd) : simdInternal_(simd) {} - __vector double simdInternal_; + __vector double simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - // gcc-4.9 does not recognize that we use the parameter - SimdDInt32(std::int32_t gmx_unused i) : simdInternal_(vec_splats(i)) {} + // gcc-4.9 does not recognize that we use the parameter + SimdDInt32(std::int32_t gmx_unused i) : simdInternal_(vec_splats(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(__vector signed int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(__vector signed int simd) : simdInternal_(simd) {} - __vector signed int simdInternal_; + __vector signed int simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - SimdDBool(bool b) : simdInternal_(reinterpret_cast<__vector vsxBool long long>(vec_splats( b ? 0xFFFFFFFFFFFFFFFFULL : 0))) {} + SimdDBool(bool b) : + simdInternal_(reinterpret_cast<__vector vsxBool long long>(vec_splats(b ? 0xFFFFFFFFFFFFFFFFULL : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdDBool(__vector vsxBool long long simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(__vector vsxBool long long simd) : simdInternal_(simd) {} - __vector vsxBool long long simdInternal_; + __vector vsxBool long long simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - SimdDIBool(bool b) : simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats( b ? 0xFFFFFFFF : 0))) {} + SimdDIBool(bool b) : + simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdDIBool(__vector vsxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(__vector vsxBool int simd) : simdInternal_(simd) {} - __vector vsxBool int simdInternal_; + __vector vsxBool int simdInternal_; }; // Note that the interfaces we use here have been a mess in xlc; // currently version 13.1.5 is required. -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { - return { + return + { #if defined(__ibmxl__) - vec_ld(0, m) + vec_ld(0, m) #else -# if __GNUC__ < 7 - *reinterpret_cast(m) -# else - vec_vsx_ld(0, m) -# endif +# if __GNUC__ < 7 + *reinterpret_cast(m) +# else + vec_vsx_ld(0, m) +# endif #endif }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { #if defined(__ibmxl__) vec_st(a.simdInternal_, 0, m); #else -# if __GNUC__ < 7 - *reinterpret_cast<__vector double *>(m) = a.simdInternal_; -# else +# if __GNUC__ < 7 + *reinterpret_cast<__vector double*>(m) = a.simdInternal_; +# else vec_vsx_st(a.simdInternal_, 0, m); -# endif +# endif #endif } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { - return { + return + { #if defined(__ibmxl__) - vec_xl(0, m) + vec_xl(0, m) #else -# if __GNUC__ < 7 - *reinterpret_cast(m) -# else - vec_vsx_ld(0, m) -# endif +# if __GNUC__ < 7 + *reinterpret_cast(m) +# else + vec_vsx_ld(0, m) +# endif #endif }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { #if defined(__ibmxl__) vec_xst(a.simdInternal_, 0, m); #else -# if __GNUC__ < 7 - *reinterpret_cast<__vector double *>(m) = a.simdInternal_; -# else +# if __GNUC__ < 7 + *reinterpret_cast<__vector double*>(m) = a.simdInternal_; +# else vec_vsx_st(a.simdInternal_, 0, m); -# endif +# endif #endif } -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - vec_splats(0.0) - }; + return { vec_splats(0.0) }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { __vector signed int t0, t1; const __vector unsigned char perm = { 0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19, 16, 17, 18, 19 }; - t0 = vec_splats(m[0]); - t1 = vec_splats(m[1]); - return { - vec_perm(t0, t1, perm) - }; + t0 = vec_splats(m[0]); + t1 = vec_splats(m[1]); + return { vec_perm(t0, t1, perm) }; } // gcc-4.9 does not understand that arguments to vec_extract() are used -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 gmx_unused x) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 gmx_unused x) { m[0] = vec_extract(x.simdInternal_, 0); m[1] = vec_extract(x.simdInternal_, 2); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { return simdLoad(m, SimdDInt32Tag()); } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { return store(m, a); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - vec_splats(static_cast(0)) - }; + return { vec_splats(static_cast(0)) }; } // gcc-4.9 does not detect that vec_extract() uses its argument template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 gmx_unused a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 gmx_unused a) { - return vec_extract(a.simdInternal_, 2*index); + return vec_extract(a.simdInternal_, 2 * index); } -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble x) +static inline SimdDouble gmx_simdcall operator-(SimdDouble x) { - return { - -x.simdInternal_ - }; + return { -x.simdInternal_ }; } -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - return { - vec_mul(a.simdInternal_, b.simdInternal_) - }; + return { vec_mul(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - vec_rsqrte(x.simdInternal_) - }; + return { vec_rsqrte(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - vec_re(x.simdInternal_) - }; + return { vec_re(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - vec_add(a.simdInternal_, vec_and(b.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_))) - }; + return { vec_add(a.simdInternal_, + vec_and(b.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { SimdDouble prod = a * b; - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { SimdDouble prod = fma(a, b, c); - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = vec_sel(vec_splats(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = vec_sel(vec_splats(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -abs(SimdDouble x) +static inline SimdDouble gmx_simdcall abs(SimdDouble x) { - return { - vec_abs( x.simdInternal_ ) - }; + return { vec_abs(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - return { - vec_max(a.simdInternal_, b.simdInternal_) - }; + return { vec_max(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - return { - vec_min(a.simdInternal_, b.simdInternal_) - }; + return { vec_min(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) -// gcc up to at least version 4.9 does not have vec_round() in double precision - use inline asm + // gcc up to at least version 4.9 does not have vec_round() in double precision - use inline asm __vector double res; - __asm__ ("xvrdpi %x0,%x1" : "=wd" (res) : "wd" (x.simdInternal_)); - return { - res - }; + __asm__("xvrdpi %x0,%x1" : "=wd"(res) : "wd"(x.simdInternal_)); + return { res }; #else - return { - vec_round( x.simdInternal_ ) - }; + return { vec_round(x.simdInternal_) }; #endif } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { - return { - vec_trunc( x.simdInternal_ ) - }; + return { vec_trunc(x.simdInternal_) }; } -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) { - const __vector double exponentMask = reinterpret_cast<__vector double>(vec_splats(0x7FF0000000000000ULL)); + const __vector double exponentMask = + reinterpret_cast<__vector double>(vec_splats(0x7FF0000000000000ULL)); const __vector signed int exponentBias = vec_splats(1022); const __vector double half = vec_splats(0.5); __vector signed int iExponent; - iExponent = reinterpret_cast<__vector signed int>(vec_and(value.simdInternal_, exponentMask)); + iExponent = reinterpret_cast<__vector signed int>(vec_and(value.simdInternal_, exponentMask)); // The data is in the upper half of each double (corresponding to elements 1 and 3). // First shift 52-32=20bits, and then permute to swap element 0 with 1 and element 2 with 3 // For big endian they are in opposite order, so then we simply skip the swap. - iExponent = vec_sr(iExponent, vec_splats(20U)); + iExponent = vec_sr(iExponent, vec_splats(20U)); #ifndef __BIG_ENDIAN__ - const __vector unsigned char perm = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; - iExponent = vec_perm(iExponent, iExponent, perm); + const __vector unsigned char perm = { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 }; + iExponent = vec_perm(iExponent, iExponent, perm); #endif iExponent = vec_sub(iExponent, exponentBias); exponent->simdInternal_ = iExponent; - return { - vec_or(vec_andc(value.simdInternal_, exponentMask), half) - }; + return { vec_or(vec_andc(value.simdInternal_, exponentMask), half) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { - const __vector signed int exponentBias = vec_splats(1023); - __vector signed int iExponent; + const __vector signed int exponentBias = vec_splats(1023); + __vector signed int iExponent; #ifdef __BIG_ENDIAN__ - const __vector unsigned char perm = {0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 16, 17, 18, 19}; + const __vector unsigned char perm = { 0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 16, 17, 18, 19 }; #else - const __vector unsigned char perm = {16, 17, 18, 19, 0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11}; + const __vector unsigned char perm = { 16, 17, 18, 19, 0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11 }; #endif iExponent = vec_add(exponent.simdInternal_, exponentBias); @@ -482,372 +397,272 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent = vec_sl(iExponent, vec_splats(20U)); iExponent = vec_perm(iExponent, vec_splats(0), perm); - return { - vec_mul(value.simdInternal_, reinterpret_cast<__vector double>(iExponent)) - }; + return { vec_mul(value.simdInternal_, reinterpret_cast<__vector double>(iExponent)) }; } -static inline double gmx_simdcall -reduce(SimdDouble x) +static inline double gmx_simdcall reduce(SimdDouble x) { const __vector unsigned char perm = { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 }; #ifdef __xlC__ /* old xlc version 12 does not understand vec_perm() with double arguments */ - x.simdInternal_ = vec_add(x.simdInternal_, - reinterpret_cast<__vector double>(vec_perm(reinterpret_cast<__vector signed int>(x.simdInternal_), - reinterpret_cast<__vector signed int>(x.simdInternal_), perm))); + x.simdInternal_ = vec_add( + x.simdInternal_, reinterpret_cast<__vector double>(vec_perm( + reinterpret_cast<__vector signed int>(x.simdInternal_), + reinterpret_cast<__vector signed int>(x.simdInternal_), perm))); #else x.simdInternal_ = vec_add(x.simdInternal_, vec_perm(x.simdInternal_, x.simdInternal_, perm)); #endif return vec_extract(x.simdInternal_, 0); } -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - reinterpret_cast<__vector vsxBool long long>(vec_or(reinterpret_cast<__vector signed int>(vec_cmpgt(a.simdInternal_, b.simdInternal_)), - reinterpret_cast<__vector signed int>(vec_cmplt(a.simdInternal_, b.simdInternal_)))) - }; + return { reinterpret_cast<__vector vsxBool long long>(vec_or( + reinterpret_cast<__vector signed int>(vec_cmpgt(a.simdInternal_, b.simdInternal_)), + reinterpret_cast<__vector signed int>(vec_cmplt(a.simdInternal_, b.simdInternal_)))) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - vec_cmple(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmple(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { #ifdef __POWER8_VECTOR__ // Power8 VSX has proper support for operations on long long integers - return { - vec_cmpgt(reinterpret_cast<__vector unsigned long long>(a.simdInternal_), vec_splats(0ULL)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned long long>(a.simdInternal_), vec_splats(0ULL)) }; #else // No support for long long operations. // Start with comparing 32-bit subfields bitwise by casting to integers - __vector vsxBool int tmp = vec_cmpgt( reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)); + __vector vsxBool int tmp = + vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)); // Shuffle low/high 32-bit fields of tmp into tmp2 - const __vector unsigned char perm = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; - __vector vsxBool int tmp2 = vec_perm(tmp, tmp, perm); + const __vector unsigned char perm = { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 }; + __vector vsxBool int tmp2 = vec_perm(tmp, tmp, perm); // Return the or:d parts of tmp & tmp2 - return { - reinterpret_cast<__vector vsxBool long long>(vec_or(tmp, tmp2)) - }; + return { reinterpret_cast<__vector vsxBool long long>(vec_or(tmp, tmp2)) }; #endif } -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - reinterpret_cast<__vector vsxBool long long>(vec_and(reinterpret_cast<__vector signed int>(a.simdInternal_), reinterpret_cast<__vector signed int>(b.simdInternal_))) - }; + return { reinterpret_cast<__vector vsxBool long long>( + vec_and(reinterpret_cast<__vector signed int>(a.simdInternal_), + reinterpret_cast<__vector signed int>(b.simdInternal_))) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - reinterpret_cast<__vector vsxBool long long>(vec_or(reinterpret_cast<__vector signed int>(a.simdInternal_), reinterpret_cast<__vector signed int>(b.simdInternal_))) - }; + return { reinterpret_cast<__vector vsxBool long long>( + vec_or(reinterpret_cast<__vector signed int>(a.simdInternal_), + reinterpret_cast<__vector signed int>(b.simdInternal_))) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) +static inline bool gmx_simdcall anyTrue(SimdDBool a) { - return vec_any_ne(reinterpret_cast<__vector vsxBool int>(a.simdInternal_), reinterpret_cast<__vector vsxBool int>(vec_splats(0))); + return vec_any_ne(reinterpret_cast<__vector vsxBool int>(a.simdInternal_), + reinterpret_cast<__vector vsxBool int>(vec_splats(0))); } -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector double>(m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - a.simdInternal_ * b.simdInternal_ - }; + return { a.simdInternal_ * b.simdInternal_ }; } -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { - return { - vec_cmpgt( reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) +static inline bool gmx_simdcall anyTrue(SimdDIBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vsxBool int>(vec_splats(0))); } -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) -// gcc up to at least version 6.1 is missing intrinsics for converting double to/from int - use inline asm - const __vector unsigned char perm = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; + // gcc up to at least version 6.1 is missing intrinsics for converting double to/from int - use inline asm + const __vector unsigned char perm = { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 }; __vector double ix; - __asm__ ("xvcvdpsxws %x0,%x1" : "=wa" (ix) : "wd" (a.simdInternal_)); + __asm__("xvcvdpsxws %x0,%x1" : "=wa"(ix) : "wd"(a.simdInternal_)); - return { - reinterpret_cast<__vector signed int>(vec_perm(ix, ix, perm)) - }; + return { reinterpret_cast<__vector signed int>(vec_perm(ix, ix, perm)) }; #else - return { - vec_cts(a.simdInternal_, 0) - }; + return { vec_cts(a.simdInternal_, 0) }; #endif } -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { return cvttR2I(round(a)); } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) -// gcc up to at least version 4.9 is missing intrinsics for converting double to/from int - use inline asm - __vector double x; -#ifndef __BIG_ENDIAN__ - const __vector unsigned char perm = {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}; - a.simdInternal_ = vec_perm(a.simdInternal_, a.simdInternal_, perm); -#endif + // gcc up to at least version 4.9 is missing intrinsics for converting double to/from int - use inline asm + __vector double x; +# ifndef __BIG_ENDIAN__ + const __vector unsigned char perm = { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 }; + a.simdInternal_ = vec_perm(a.simdInternal_, a.simdInternal_, perm); +# endif - __asm__ ("xvcvsxwdp %x0,%x1" : "=wd" (x) : "wa" (a.simdInternal_)); + __asm__("xvcvsxwdp %x0,%x1" : "=wd"(x) : "wa"(a.simdInternal_)); - return { - x - }; + return { x }; #else - return { - vec_ctd(a.simdInternal_, 0) - }; + return { vec_ctd(a.simdInternal_, 0) }; #endif } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { - return { - reinterpret_cast<__vector vsxBool int>(a.simdInternal_) - }; + return { reinterpret_cast<__vector vsxBool int>(a.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { - return { - reinterpret_cast<__vector vsxBool long long>(a.simdInternal_) - }; + return { reinterpret_cast<__vector vsxBool long long>(a.simdInternal_) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { __vector float fA, fB; - fA = vec_mergeh(f.simdInternal_, f.simdInternal_); /* 0011 */ - fB = vec_mergel(f.simdInternal_, f.simdInternal_); /* 2233 */ + fA = vec_mergeh(f.simdInternal_, f.simdInternal_); /* 0011 */ + fB = vec_mergel(f.simdInternal_, f.simdInternal_); /* 2233 */ #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) // gcc-4.9 is missing double-to-float/float-to-double conversions. - __asm__ ("xvcvspdp %x0,%x1" : "=wd" (d0->simdInternal_) : "wf" (fA)); - __asm__ ("xvcvspdp %x0,%x1" : "=wd" (d1->simdInternal_) : "wf" (fB)); + __asm__("xvcvspdp %x0,%x1" : "=wd"(d0->simdInternal_) : "wf"(fA)); + __asm__("xvcvspdp %x0,%x1" : "=wd"(d1->simdInternal_) : "wf"(fB)); #else - d0->simdInternal_ = vec_cvf(fA); /* 01 */ - d1->simdInternal_ = vec_cvf(fB); /* 23 */ + d0->simdInternal_ = vec_cvf(fA); /* 01 */ + d1->simdInternal_ = vec_cvf(fB); /* 23 */ #endif } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { __vector float fA, fB, fC, fD, fE; #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) // gcc-4.9 is missing double-to-float/float-to-double conversions. - __asm__ ("xvcvdpsp %x0,%x1" : "=wf" (fA) : "wd" (d0.simdInternal_)); - __asm__ ("xvcvdpsp %x0,%x1" : "=wf" (fB) : "wd" (d1.simdInternal_)); + __asm__("xvcvdpsp %x0,%x1" : "=wf"(fA) : "wd"(d0.simdInternal_)); + __asm__("xvcvdpsp %x0,%x1" : "=wf"(fB) : "wd"(d1.simdInternal_)); #else - fA = vec_cvf(d0.simdInternal_); /* 0x1x */ - fB = vec_cvf(d1.simdInternal_); /* 2x3x */ + fA = vec_cvf(d0.simdInternal_); /* 0x1x */ + fB = vec_cvf(d1.simdInternal_); /* 2x3x */ #endif - fC = vec_mergeh(fA, fB); /* 02xx */ - fD = vec_mergel(fA, fB); /* 13xx */ - fE = vec_mergeh(fC, fD); /* 0123 */ - return { - fE - }; + fC = vec_mergeh(fA, fB); /* 02xx */ + fD = vec_mergel(fA, fB); /* 13xx */ + fE = vec_mergeh(fC, fD); /* 0123 */ + return { fE }; } -static inline SimdDouble gmx_simdcall -copysign(SimdDouble x, SimdDouble y) +static inline SimdDouble gmx_simdcall copysign(SimdDouble x, SimdDouble y) { #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) __vector double res; - __asm__ ("xvcpsgndp %x0,%x1,%x2" : "=wd" (res) : "wd" (y.simdInternal_), "wd" (x.simdInternal_)); - return { - res - }; + __asm__("xvcpsgndp %x0,%x1,%x2" : "=wd"(res) : "wd"(y.simdInternal_), "wd"(x.simdInternal_)); + return { res }; #else - return { - vec_cpsgn(y.simdInternal_, x.simdInternal_) - }; + return { vec_cpsgn(y.simdInternal_, x.simdInternal_) }; #endif } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_float.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_float.h index 91f3436a2e..66b338f374 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_float.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_simd_float.h @@ -48,384 +48,298 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - // gcc-4.9 does not recognize that we use the parameter - SimdFloat(float gmx_unused f) : simdInternal_(vec_splats(f)) {} + // gcc-4.9 does not recognize that we use the parameter + SimdFloat(float gmx_unused f) : simdInternal_(vec_splats(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(__vector float simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__vector float simd) : simdInternal_(simd) {} - __vector float simdInternal_; + __vector float simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - // gcc-4.9 does not recognize that we use the parameter - SimdFInt32(std::int32_t gmx_unused i) : simdInternal_(vec_splats(i)) {} + // gcc-4.9 does not recognize that we use the parameter + SimdFInt32(std::int32_t gmx_unused i) : simdInternal_(vec_splats(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(__vector signed int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__vector signed int simd) : simdInternal_(simd) {} - __vector signed int simdInternal_; + __vector signed int simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats( b ? 0xFFFFFFFF : 0))) {} + SimdFBool(bool b) : + simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdFBool(__vector vsxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__vector vsxBool int simd) : simdInternal_(simd) {} - __vector vsxBool int simdInternal_; + __vector vsxBool int simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats( b ? 0xFFFFFFFF : 0))) {} + SimdFIBool(bool b) : + simdInternal_(reinterpret_cast<__vector vsxBool int>(vec_splats(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - SimdFIBool(__vector vsxBool int simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__vector vsxBool int simd) : simdInternal_(simd) {} - __vector vsxBool int simdInternal_; + __vector vsxBool int simdInternal_; }; // Note that the interfaces we use here have been a mess in xlc; // currently version 13.1.5 is required. -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { - return { - *reinterpret_cast(m) - }; + return { *reinterpret_cast(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { - *reinterpret_cast<__vector float *>(m) = a.simdInternal_; + *reinterpret_cast<__vector float*>(m) = a.simdInternal_; } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { - return { + return + { #if __GNUC__ < 7 - *reinterpret_cast(m) + *reinterpret_cast(m) #else - vec_xl(0, m) + vec_xl(0, m) #endif }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { #if __GNUC__ < 7 - *reinterpret_cast<__vector float *>(m) = a.simdInternal_; + *reinterpret_cast<__vector float*>(m) = a.simdInternal_; #else vec_xst(a.simdInternal_, 0, m); #endif } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - vec_splats(0.0F) - }; + return { vec_splats(0.0F) }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { - return { - *reinterpret_cast(m) - }; + return { *reinterpret_cast(m) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { - *reinterpret_cast<__vector int *>(m) = a.simdInternal_; + *reinterpret_cast<__vector int*>(m) = a.simdInternal_; } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { - return { + return + { #if __GNUC__ < 7 - *reinterpret_cast(m) + *reinterpret_cast(m) #else - vec_xl(0, m) + vec_xl(0, m) #endif }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { #if __GNUC__ < 7 - *reinterpret_cast<__vector int *>(m) = a.simdInternal_; + *reinterpret_cast<__vector int*>(m) = a.simdInternal_; #else vec_xst(a.simdInternal_, 0, m); #endif } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - vec_splats(static_cast(0)) - }; + return { vec_splats(static_cast(0)) }; } // gcc-4.9 does not detect that vec_extract() uses its argument template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 gmx_unused a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 gmx_unused a) { return vec_extract(a.simdInternal_, index); } -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - -x.simdInternal_ - }; + return { -x.simdInternal_ }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - vec_mul(a.simdInternal_, b.simdInternal_) - }; + return { vec_mul(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_madd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_msub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmsub(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { vec_nmadd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - vec_rsqrte(x.simdInternal_) - }; + return { vec_rsqrte(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - vec_re(x.simdInternal_) - }; + return { vec_re(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - vec_add(a.simdInternal_, vec_and(b.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_))) - }; + return { vec_add(a.simdInternal_, + vec_and(b.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { SimdFloat prod = a * b; - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { SimdFloat prod = fma(a, b, c); - return { - vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(prod.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = vec_sel(vec_splats(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(vec_rsqrte(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = vec_sel(vec_splats(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(vec_re(x.simdInternal_), reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - vec_abs( x.simdInternal_ ) - }; + return { vec_abs(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - vec_max(a.simdInternal_, b.simdInternal_) - }; + return { vec_max(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - vec_min(a.simdInternal_, b.simdInternal_) - }; + return { vec_min(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - vec_round( x.simdInternal_ ) - }; + return { vec_round(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - vec_trunc( x.simdInternal_ ) - }; + return { vec_trunc(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { - const __vector float exponentMask = reinterpret_cast<__vector float>(vec_splats(0x7F800000U)); - const __vector signed int exponentBias = vec_splats(126); - const __vector float half = vec_splats(0.5F); + const __vector float exponentMask = reinterpret_cast<__vector float>(vec_splats(0x7F800000U)); + const __vector signed int exponentBias = vec_splats(126); + const __vector float half = vec_splats(0.5F); __vector signed int iExponent; - iExponent = reinterpret_cast<__vector signed int>(vec_and(value.simdInternal_, exponentMask)); - iExponent = vec_sub(vec_sr(iExponent, vec_splats(23U)), exponentBias); + iExponent = reinterpret_cast<__vector signed int>(vec_and(value.simdInternal_, exponentMask)); + iExponent = vec_sub(vec_sr(iExponent, vec_splats(23U)), exponentBias); exponent->simdInternal_ = iExponent; - return { - vec_or( vec_andc(value.simdInternal_, exponentMask), half) - }; + return { vec_or(vec_andc(value.simdInternal_, exponentMask), half) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { - const __vector signed int exponentBias = vec_splats(127); + const __vector signed int exponentBias = vec_splats(127); __vector signed int iExponent; - iExponent = vec_add(exponent.simdInternal_, exponentBias); + iExponent = vec_add(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -433,15 +347,12 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = vec_max(iExponent, vec_splat_s32(0)); } - iExponent = vec_sl( iExponent, vec_splats(23U)); + iExponent = vec_sl(iExponent, vec_splats(23U)); - return { - vec_mul(value.simdInternal_, reinterpret_cast<__vector float>(iExponent)) - }; + return { vec_mul(value.simdInternal_, reinterpret_cast<__vector float>(iExponent)) }; } -static inline float gmx_simdcall -reduce(SimdFloat x) +static inline float gmx_simdcall reduce(SimdFloat x) { const __vector unsigned char perm1 = { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 }; const __vector unsigned char perm2 = { 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 }; @@ -451,275 +362,178 @@ reduce(SimdFloat x) return vec_extract(x.simdInternal_, 0); } -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), - vec_cmplt(a.simdInternal_, b.simdInternal_)) - }; + return { vec_or(vec_cmpgt(a.simdInternal_, b.simdInternal_), + vec_cmplt(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - vec_cmple(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmple(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { - return { - vec_cmpgt( reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vsxBool int>(vec_splats(0))); } -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector float>(m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - vec_andc(b.simdInternal_, a.simdInternal_) - }; + return { vec_andc(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - vec_xor(a.simdInternal_, b.simdInternal_) - }; + return { vec_xor(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - vec_add(a.simdInternal_, b.simdInternal_) - }; + return { vec_add(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - vec_sub(a.simdInternal_, b.simdInternal_) - }; + return { vec_sub(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - a.simdInternal_ * b.simdInternal_ - }; + return { a.simdInternal_ * b.simdInternal_ }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - vec_cmpeq(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmpeq(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - vec_cmpgt( reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) - }; + return { vec_cmpgt(reinterpret_cast<__vector unsigned int>(a.simdInternal_), vec_splats(0U)) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - vec_cmplt(a.simdInternal_, b.simdInternal_) - }; + return { vec_cmplt(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - vec_and(a.simdInternal_, b.simdInternal_) - }; + return { vec_and(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - vec_or(a.simdInternal_, b.simdInternal_) - }; + return { vec_or(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { return vec_any_ne(a.simdInternal_, reinterpret_cast<__vector vsxBool int>(vec_splats(0))); } -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m) { - return { - vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_and(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m) { - return { - vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) - }; + return { vec_andc(a.simdInternal_, reinterpret_cast<__vector signed int>(m.simdInternal_)) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { vec_sel(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - vec_cts(vec_round(a.simdInternal_), 0) - }; + return { vec_cts(vec_round(a.simdInternal_), 0) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - vec_cts(a.simdInternal_, 0) - }; + return { vec_cts(a.simdInternal_, 0) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - vec_ctf(a.simdInternal_, 0) - }; + return { vec_ctf(a.simdInternal_, 0) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFloat gmx_simdcall -copysign(SimdFloat x, SimdFloat y) +static inline SimdFloat gmx_simdcall copysign(SimdFloat x, SimdFloat y) { #if defined(__GNUC__) && !defined(__ibmxl__) && !defined(__xlC__) __vector float res; - __asm__ ("xvcpsgnsp %x0,%x1,%x2" : "=wf" (res) : "wf" (y.simdInternal_), "wf" (x.simdInternal_)); - return { - res - }; + __asm__("xvcpsgnsp %x0,%x1,%x2" : "=wf"(res) : "wf"(y.simdInternal_), "wf"(x.simdInternal_)); + return { res }; #else - return { - vec_cpsgn(y.simdInternal_, x.simdInternal_) - }; + return { vec_cpsgn(y.simdInternal_, x.simdInternal_) }; #endif } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_double.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_double.h index 6d96e43ce4..ca5852f421 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_double.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,58 +46,51 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { __vector double t1, t2, t3, t4; - t1 = *reinterpret_cast(base + align * offset[0]); - t2 = *reinterpret_cast(base + align * offset[1]); - t3 = *reinterpret_cast(base + align * offset[0] + 2); - t4 = *reinterpret_cast(base + align * offset[1] + 2); + t1 = *reinterpret_cast(base + align * offset[0]); + t2 = *reinterpret_cast(base + align * offset[1]); + t3 = *reinterpret_cast(base + align * offset[0] + 2); + t4 = *reinterpret_cast(base + align * offset[1] + 2); v0->simdInternal_ = vec_mergeh(t1, t2); v1->simdInternal_ = vec_mergel(t1, t2); v2->simdInternal_ = vec_mergeh(t3, t4); v3->simdInternal_ = vec_mergel(t3, t4); - } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { __vector double t1, t2; - t1 = *reinterpret_cast(base + align * offset[0]); - t2 = *reinterpret_cast(base + align * offset[1]); + t1 = *reinterpret_cast(base + align * offset[0]); + t2 = *reinterpret_cast(base + align * offset[1]); v0->simdInternal_ = vec_mergeh(t1, t2); v1->simdInternal_ = vec_mergel(t1, t2); - } static const int c_simdBestPairAlignmentDouble = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { - SimdDouble t1, t2; + SimdDouble t1, t2; - t1 = simdLoad(base + align * offset[0]); - t2 = simdLoad(base + align * offset[1]); + t1 = simdLoad(base + align * offset[0]); + t2 = simdLoad(base + align * offset[1]); v0->simdInternal_ = vec_mergeh(t1.simdInternal_, t2.simdInternal_); v1->simdInternal_ = vec_mergel(t1.simdInternal_, t2.simdInternal_); @@ -106,13 +99,12 @@ gatherLoadUTranspose(const double * base, } // gcc-4.9 fails to recognize that the argument to vec_extract() is used -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble gmx_unused v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble gmx_unused v2) { SimdDouble t1, t2; @@ -120,18 +112,14 @@ transposeScatterStoreU(double * base, t2.simdInternal_ = vec_mergel(v0.simdInternal_, v1.simdInternal_); store(base + align * offset[0], t1); - base[align * offset[0] + 2] = vec_extract(v2.simdInternal_, 0); + base[align * offset[0] + 2] = vec_extract(v2.simdInternal_, 0); store(base + align * offset[1], t2); - base[align * offset[1] + 2] = vec_extract(v2.simdInternal_, 1); + base[align * offset[1] + 2] = vec_extract(v2.simdInternal_, 1); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { if (align % 4 == 0) { @@ -165,25 +153,21 @@ transposeScatterIncrU(double * base, t1 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); - t3 = simdLoad(base + align * offset[0]); - t3.simdInternal_ = vec_add(t3.simdInternal_, t1); + t3 = simdLoad(base + align * offset[0]); + t3.simdInternal_ = vec_add(t3.simdInternal_, t1); store(base + align * offset[0], t3); base[align * offset[0] + 2] += vec_extract(v2.simdInternal_, 0); - t4 = simdLoad(base + align * offset[1]); - t4.simdInternal_ = vec_add(t4.simdInternal_, t2); + t4 = simdLoad(base + align * offset[1]); + t4.simdInternal_ = vec_add(t4.simdInternal_, t2); store(base + align * offset[1], t4); base[align * offset[1] + 2] += vec_extract(v2.simdInternal_, 1); } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { if (align % 4 == 0) { @@ -217,64 +201,56 @@ transposeScatterDecrU(double * base, t1 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); - t3 = simdLoad(base + align * offset[0]); - t3.simdInternal_ = vec_sub(t3.simdInternal_, t1); + t3 = simdLoad(base + align * offset[0]); + t3.simdInternal_ = vec_sub(t3.simdInternal_, t1); store(base + align * offset[0], t3); base[align * offset[0] + 2] -= vec_extract(v2.simdInternal_, 0); - t4 = simdLoad(base + align * offset[1]); - t4.simdInternal_ = vec_sub(t4.simdInternal_, t2); + t4 = simdLoad(base + align * offset[1]); + t4.simdInternal_ = vec_sub(t4.simdInternal_, t2); store(base + align * offset[1], t4); base[align * offset[1] + 2] -= vec_extract(v2.simdInternal_, 1); } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { triplets0->simdInternal_ = vec_mergeh(scalar.simdInternal_, scalar.simdInternal_); triplets1->simdInternal_ = scalar.simdInternal_; triplets2->simdInternal_ = vec_mergel(scalar.simdInternal_, scalar.simdInternal_); } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 offset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; - store(ioffset, offset ); + store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; - store(ioffset, offset ); + store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; @@ -287,11 +263,7 @@ gatherLoadUBySimdIntTranspose(const double * base, } static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __vector double t1, t2, t3, t4; @@ -303,13 +275,13 @@ reduceIncr4ReturnSum(double * m, t1 = vec_add(t1, t2); t3 = vec_add(t3, t4); - *reinterpret_cast<__vector double *>(m) += t1; - *reinterpret_cast<__vector double *>(m+2) += t3; + *reinterpret_cast<__vector double*>(m) += t1; + *reinterpret_cast<__vector double*>(m + 2) += t3; t1 = vec_add(t1, t3); return reduce(t1); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_float.h b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_float.h index c35b7311de..7013a36223 100644 --- a/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_float.h +++ b/src/gromacs/simd/impl_ibm_vsx/impl_ibm_vsx_util_float.h @@ -46,21 +46,20 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { __vector float l0, l1, l2, l3; - l0 = simdLoad( base + align * offset[0] ).simdInternal_; - l1 = simdLoad( base + align * offset[1] ).simdInternal_; - l2 = simdLoad( base + align * offset[2] ).simdInternal_; - l3 = simdLoad( base + align * offset[3] ).simdInternal_; + l0 = simdLoad(base + align * offset[0]).simdInternal_; + l1 = simdLoad(base + align * offset[1]).simdInternal_; + l2 = simdLoad(base + align * offset[2]).simdInternal_; + l3 = simdLoad(base + align * offset[3]).simdInternal_; __vector float t0 = vec_mergeh(l0, l2); __vector float t1 = vec_mergel(l0, l2); @@ -72,19 +71,20 @@ gatherLoadTranspose(const float * base, v3->simdInternal_ = vec_mergel(t1, t3); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { __vector float t0, t1, t2, t3; - t0 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[0]))); - t1 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[1]))); - t2 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[2]))); - t3 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[3]))); + t0 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[0]))); + t1 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[1]))); + t2 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[2]))); + t3 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[3]))); t0 = vec_mergeh(t0, t2); t1 = vec_mergeh(t1, t3); v0->simdInternal_ = vec_mergeh(t0, t1); @@ -93,13 +93,12 @@ gatherLoadTranspose(const float * base, static const int c_simdBestPairAlignmentFloat = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { if (align % 4 == 0) @@ -110,17 +109,23 @@ gatherLoadUTranspose(const float * base, else { __vector float t1, t2, t3, t4, t5, t6, t7, t8; - const __vector unsigned char perm_lo2hi = { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 }; - const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15 }; - - t1 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[0]))); - t2 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[1]))); - t3 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[2]))); - t4 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[3]))); - t5 = vec_splats( *(base + align * offset[0] + 2) ); - t6 = vec_splats( *(base + align * offset[1] + 2) ); - t7 = vec_splats( *(base + align * offset[2] + 2) ); - t8 = vec_splats( *(base + align * offset[3] + 2) ); + const __vector unsigned char perm_lo2hi = { 0, 1, 2, 3, 4, 5, 6, 7, + 16, 17, 18, 19, 20, 21, 22, 23 }; + const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, + 8, 9, 10, 11, 12, 13, 14, 15 }; + + t1 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[0]))); + t2 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[1]))); + t3 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[2]))); + t4 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[3]))); + t5 = vec_splats(*(base + align * offset[0] + 2)); + t6 = vec_splats(*(base + align * offset[1] + 2)); + t7 = vec_splats(*(base + align * offset[2] + 2)); + t8 = vec_splats(*(base + align * offset[3] + 2)); t1 = vec_mergeh(t1, t2); t3 = vec_mergeh(t3, t4); @@ -134,39 +139,39 @@ gatherLoadUTranspose(const float * base, // gcc-4.9 does not recognize that the argument to vec_extract() is used -template -static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat gmx_unused v2) +template +static inline void gmx_simdcall transposeScatterStoreU(float* base, + const std::int32_t offset[], + SimdFloat v0, + SimdFloat v1, + SimdFloat gmx_unused v2) { __vector float t1, t2; - t1 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); - t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); - *reinterpret_cast( base + align * offset[0] ) = vec_extract(reinterpret_cast<__vector double>(t1), 0); - base[align*offset[0] + 2] = vec_extract(v2.simdInternal_, 0); - *reinterpret_cast( base + align * offset[1] ) = vec_extract(reinterpret_cast<__vector double>(t1), 1); - base[align*offset[1] + 2] = vec_extract(v2.simdInternal_, 1); - *reinterpret_cast( base + align * offset[2] ) = vec_extract(reinterpret_cast<__vector double>(t2), 0); - base[align*offset[2] + 2] = vec_extract(v2.simdInternal_, 2); - *reinterpret_cast( base + align * offset[3] ) = vec_extract(reinterpret_cast<__vector double>(t2), 1); - base[align*offset[3] + 2] = vec_extract(v2.simdInternal_, 3); + t1 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); + t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); + *reinterpret_cast(base + align * offset[0]) = + vec_extract(reinterpret_cast<__vector double>(t1), 0); + base[align * offset[0] + 2] = vec_extract(v2.simdInternal_, 0); + *reinterpret_cast(base + align * offset[1]) = + vec_extract(reinterpret_cast<__vector double>(t1), 1); + base[align * offset[1] + 2] = vec_extract(v2.simdInternal_, 1); + *reinterpret_cast(base + align * offset[2]) = + vec_extract(reinterpret_cast<__vector double>(t2), 0); + base[align * offset[2] + 2] = vec_extract(v2.simdInternal_, 2); + *reinterpret_cast(base + align * offset[3]) = + vec_extract(reinterpret_cast<__vector double>(t2), 1); + base[align * offset[3] + 2] = vec_extract(v2.simdInternal_, 3); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { if (align < 4) { - const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15 }; + const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, + 8, 9, 10, 11, 12, 13, 14, 15 }; __vector float t0, t1, t2, t3, t4, t5, t6, t7; t0 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); // x0 y0 x1 y1 @@ -174,36 +179,44 @@ transposeScatterIncrU(float * base, t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); // x2 y2 x3 y3 t3 = vec_perm(t2, t2, perm_hi2lo); // x3 y3 - t4 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[0]))); + t4 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[0]))); t4 = vec_add(t4, t0); - *reinterpret_cast( base + align * offset[0] ) = vec_extract(reinterpret_cast<__vector double>(t4), 0); + *reinterpret_cast(base + align * offset[0]) = + vec_extract(reinterpret_cast<__vector double>(t4), 0); { float extracted = vec_extract(v2.simdInternal_, 0); - base[align*offset[0] + 2] += extracted; + base[align * offset[0] + 2] += extracted; } - t5 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[1]))); + t5 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[1]))); t5 = vec_add(t5, t1); - *reinterpret_cast( base + align * offset[1] ) = vec_extract(reinterpret_cast<__vector double>(t5), 0); + *reinterpret_cast(base + align * offset[1]) = + vec_extract(reinterpret_cast<__vector double>(t5), 0); { float extracted = vec_extract(v2.simdInternal_, 1); - base[align*offset[1] + 2] += extracted; + base[align * offset[1] + 2] += extracted; } - t6 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[2]))); + t6 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[2]))); t6 = vec_add(t6, t2); - *reinterpret_cast( base + align * offset[2] ) = vec_extract(reinterpret_cast<__vector double>(t6), 0); + *reinterpret_cast(base + align * offset[2]) = + vec_extract(reinterpret_cast<__vector double>(t6), 0); { float extracted = vec_extract(v2.simdInternal_, 2); - base[align*offset[2] + 2] += extracted; + base[align * offset[2] + 2] += extracted; } - t7 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[3]))); + t7 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[3]))); t7 = vec_add(t7, t3); - *reinterpret_cast( base + align * offset[3] ) = vec_extract(reinterpret_cast<__vector double>(t7), 0); + *reinterpret_cast(base + align * offset[3]) = + vec_extract(reinterpret_cast<__vector double>(t7), 0); { float extracted = vec_extract(v2.simdInternal_, 3); - base[align*offset[3] + 2] += extracted; + base[align * offset[3] + 2] += extracted; } } else @@ -214,29 +227,26 @@ transposeScatterIncrU(float * base, __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); __vector float t2 = vec_mergeh(v1.simdInternal_, vec_splats(0.0F)); __vector float t3 = vec_mergel(v1.simdInternal_, vec_splats(0.0F)); - v0.simdInternal_ = vec_mergeh(t0, t2); - v1.simdInternal_ = vec_mergel(t0, t2); - v2.simdInternal_ = vec_mergeh(t1, t3); - v3.simdInternal_ = vec_mergel(t1, t3); - - store(base + align * offset[0], simdLoad(base + align * offset[0]) + v0 ); - store(base + align * offset[1], simdLoad(base + align * offset[1]) + v1 ); - store(base + align * offset[2], simdLoad(base + align * offset[2]) + v2 ); - store(base + align * offset[3], simdLoad(base + align * offset[3]) + v3 ); + v0.simdInternal_ = vec_mergeh(t0, t2); + v1.simdInternal_ = vec_mergel(t0, t2); + v2.simdInternal_ = vec_mergeh(t1, t3); + v3.simdInternal_ = vec_mergel(t1, t3); + + store(base + align * offset[0], simdLoad(base + align * offset[0]) + v0); + store(base + align * offset[1], simdLoad(base + align * offset[1]) + v1); + store(base + align * offset[2], simdLoad(base + align * offset[2]) + v2); + store(base + align * offset[3], simdLoad(base + align * offset[3]) + v3); } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { if (align < 4) { - const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, 8, 9, 10, 11, 12, 13, 14, 15 }; + const __vector unsigned char perm_hi2lo = { 24, 25, 26, 27, 28, 29, 30, 31, + 8, 9, 10, 11, 12, 13, 14, 15 }; __vector float t0, t1, t2, t3, t4, t5, t6, t7; t0 = vec_mergeh(v0.simdInternal_, v1.simdInternal_); // x0 y0 x1 y1 @@ -244,36 +254,44 @@ transposeScatterDecrU(float * base, t2 = vec_mergel(v0.simdInternal_, v1.simdInternal_); // x2 y2 x3 y3 t3 = vec_perm(t2, t2, perm_hi2lo); // x3 y3 - t4 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[0]))); + t4 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[0]))); t4 = vec_sub(t4, t0); - *reinterpret_cast( base + align * offset[0] ) = vec_extract(reinterpret_cast<__vector double>(t4), 0); + *reinterpret_cast(base + align * offset[0]) = + vec_extract(reinterpret_cast<__vector double>(t4), 0); { float extracted = vec_extract(v2.simdInternal_, 0); - base[align*offset[0] + 2] -= extracted; + base[align * offset[0] + 2] -= extracted; } - t5 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[1]))); + t5 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[1]))); t5 = vec_sub(t5, t1); - *reinterpret_cast( base + align * offset[1] ) = vec_extract(reinterpret_cast<__vector double>(t5), 0); + *reinterpret_cast(base + align * offset[1]) = + vec_extract(reinterpret_cast<__vector double>(t5), 0); { float extracted = vec_extract(v2.simdInternal_, 1); - base[align*offset[1] + 2] -= extracted; + base[align * offset[1] + 2] -= extracted; } - t6 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[2]))); + t6 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[2]))); t6 = vec_sub(t6, t2); - *reinterpret_cast( base + align * offset[2] ) = vec_extract(reinterpret_cast<__vector double>(t6), 0); + *reinterpret_cast(base + align * offset[2]) = + vec_extract(reinterpret_cast<__vector double>(t6), 0); { float extracted = vec_extract(v2.simdInternal_, 2); - base[align*offset[2] + 2] -= extracted; + base[align * offset[2] + 2] -= extracted; } - t7 = reinterpret_cast<__vector float>(vec_splats(*reinterpret_cast(base + align * offset[3]))); + t7 = reinterpret_cast<__vector float>( + vec_splats(*reinterpret_cast(base + align * offset[3]))); t7 = vec_sub(t7, t3); - *reinterpret_cast( base + align * offset[3] ) = vec_extract(reinterpret_cast<__vector double>(t7), 0); + *reinterpret_cast(base + align * offset[3]) = + vec_extract(reinterpret_cast<__vector double>(t7), 0); { float extracted = vec_extract(v2.simdInternal_, 3); - base[align*offset[3] + 2] -= extracted; + base[align * offset[3] + 2] -= extracted; } } else @@ -284,23 +302,22 @@ transposeScatterDecrU(float * base, __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); __vector float t2 = vec_mergeh(v1.simdInternal_, vec_splats(0.0F)); __vector float t3 = vec_mergel(v1.simdInternal_, vec_splats(0.0F)); - v0.simdInternal_ = vec_mergeh(t0, t2); - v1.simdInternal_ = vec_mergel(t0, t2); - v2.simdInternal_ = vec_mergeh(t1, t3); - v3.simdInternal_ = vec_mergel(t1, t3); - - store(base + align * offset[0], simdLoad(base + align * offset[0]) - v0 ); - store(base + align * offset[1], simdLoad(base + align * offset[1]) - v1 ); - store(base + align * offset[2], simdLoad(base + align * offset[2]) - v2 ); - store(base + align * offset[3], simdLoad(base + align * offset[3]) - v3 ); + v0.simdInternal_ = vec_mergeh(t0, t2); + v1.simdInternal_ = vec_mergel(t0, t2); + v2.simdInternal_ = vec_mergeh(t1, t3); + v3.simdInternal_ = vec_mergel(t1, t3); + + store(base + align * offset[0], simdLoad(base + align * offset[0]) - v0); + store(base + align * offset[1], simdLoad(base + align * offset[1]) - v1); + store(base + align * offset[2], simdLoad(base + align * offset[2]) - v2); + store(base + align * offset[3], simdLoad(base + align * offset[3]) - v3); } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { // These permutes will be translated to immediate permutes (xxpermdi) // since they operate on doublewords, which will be faster than loading @@ -321,62 +338,50 @@ expandScalarsToTriplets(SimdFloat scalar, /* TODO In debug mode, xlc 13.1.5 seems to overwrite v0 on the stack, leading to segfaults. Possibly the calling convention doesn't implement __vector int correctly. Release mode is OK. gcc is OK. */ -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 offset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - store(ioffset, offset ); + store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - store(ioffset, offset ); + store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - store(ioffset, offset ); + store(ioffset, offset); gatherLoadTranspose(base, ioffset, v0, v1); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { __vector float t0 = vec_mergeh(v0.simdInternal_, v2.simdInternal_); __vector float t1 = vec_mergel(v0.simdInternal_, v2.simdInternal_); __vector float t2 = vec_mergeh(v1.simdInternal_, v3.simdInternal_); __vector float t3 = vec_mergel(v1.simdInternal_, v3.simdInternal_); - v0.simdInternal_ = vec_mergeh(t0, t2); - v1.simdInternal_ = vec_mergel(t0, t2); - v2.simdInternal_ = vec_mergeh(t1, t3); - v3.simdInternal_ = vec_mergel(t1, t3); + v0.simdInternal_ = vec_mergeh(t0, t2); + v1.simdInternal_ = vec_mergel(t0, t2); + v2.simdInternal_ = vec_mergeh(t1, t3); + v3.simdInternal_ = vec_mergel(t1, t3); v0 = v0 + v1; v2 = v2 + v3; @@ -387,6 +392,6 @@ reduceIncr4ReturnSum(float * m, return reduce(v0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPLEMENTATION_IBM_VSX_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_none/impl_none.h b/src/gromacs/simd/impl_none/impl_none.h index b85fcc2825..f98de3b990 100644 --- a/src/gromacs/simd/impl_none/impl_none.h +++ b/src/gromacs/simd/impl_none/impl_none.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,28 +37,28 @@ #define GMX_SIMD_IMPL_NONE_H /* No SIMD implementation - assign 0 to all defines */ -#define GMX_SIMD 0 -#define GMX_SIMD_HAVE_FLOAT 0 -#define GMX_SIMD_HAVE_DOUBLE 0 -#define GMX_SIMD_HAVE_LOADU 0 -#define GMX_SIMD_HAVE_STOREU 0 -#define GMX_SIMD_HAVE_LOGICAL 0 -#define GMX_SIMD_HAVE_FMA 0 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 0 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 -#define GMX_SIMD4_HAVE_FLOAT 0 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD 0 +#define GMX_SIMD_HAVE_FLOAT 0 +#define GMX_SIMD_HAVE_DOUBLE 0 +#define GMX_SIMD_HAVE_LOADU 0 +#define GMX_SIMD_HAVE_STOREU 0 +#define GMX_SIMD_HAVE_LOGICAL 0 +#define GMX_SIMD_HAVE_FMA 0 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 0 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 0 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 +#define GMX_SIMD4_HAVE_FLOAT 0 +#define GMX_SIMD4_HAVE_DOUBLE 0 #undef GMX_SIMD_FLOAT_WIDTH #undef GMX_SIMD_DOUBLE_WIDTH #undef GMX_SIMD_FINT32_WIDTH #undef GMX_SIMD_DINT32_WIDTH #undef GMX_SIMD4_WIDTH -#define GMX_SIMD_ALIGNMENT 8 // 1*double +#define GMX_SIMD_ALIGNMENT 8 // 1*double #undef GMX_SIMD_RSQRT_BITS #undef GMX_SIMD_RCP_BITS diff --git a/src/gromacs/simd/impl_reference/impl_reference_definitions.h b/src/gromacs/simd/impl_reference/impl_reference_definitions.h index 87e9dd7ac7..7cbb7965ce 100644 --- a/src/gromacs/simd/impl_reference/impl_reference_definitions.h +++ b/src/gromacs/simd/impl_reference/impl_reference_definitions.h @@ -61,23 +61,23 @@ namespace gmx */ //! \brief 1 if any SIMD support is present, otherwise 0. -#define GMX_SIMD 1 +#define GMX_SIMD 1 /*! \brief 1 when SIMD float support is present, otherwise 0 * * You should only use this to specifically check for single precision SIMD, * support, even when the rest of Gromacs uses double precision. */ -#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_FLOAT 1 //! \brief 1 if SIMD double support is present, otherwise 0 -#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_DOUBLE 1 //! \brief 1 if the SIMD implementation supports unaligned loads, otherwise 0 -#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_LOADU 1 //! \brief 1 if the SIMD implementation supports unaligned stores, otherwise 0 -#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_STOREU 1 /*! \brief 1 if the SIMD implementation has fused-multiply add hardware * @@ -86,165 +86,165 @@ namespace gmx * a few very tight loops you might be able to save a few instructions * with a separate non-FMA code path. */ -#define GMX_SIMD_HAVE_FMA 0 +#define GMX_SIMD_HAVE_FMA 0 //! \brief 1 if SIMD impl has logical operations on floating-point data, otherwise 0 -#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_LOGICAL 1 //! \brief Support for extracting integers from \ref gmx::SimdFInt32 (1/0 for present/absent) -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 //! \brief 1 if SIMD logical ops are supported for \ref gmx::SimdFInt32, otherwise 0 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 //! \brief 1 if SIMD arithmetic ops are supported for \ref gmx::SimdFInt32, otherwise 0 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 //! \brief Support for extracting integer from \ref gmx::SimdDInt32 (1/0 for present/absent) -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 //! \brief 1 if logical operations are supported for \ref gmx::SimdDInt32, otherwise 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 //! \brief 1 if SIMD arithmetic ops are supported for \ref gmx::SimdDInt32, otherwise 0 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 /*! \brief 1 if implementation provides single precision copysign() * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 /*! \brief 1 if implementation provides single precision 1/sqrt(x) N-R iterations faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 /*! \brief 1 if implementation provides single precision 1/x N-R iterations faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 /*! \brief 1 if implementation provides single precision log() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 /*! \brief 1 if implementation provides single precision exp2() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 /*! \brief 1 if implementation provides single precision exp() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 /*! \brief 1 if implementation provides double precision copysign() * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 /*! \brief 1 if implementation provides double precision 1/sqrt(x) N-R iterations faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 /*! \brief 1 if implementation provides double precision 1/x N-R iterations faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 /*! \brief 1 if implementation provides double precision log() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 /*! \brief 1 if implementation provides double precision exp2() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 /*! \brief 1 if implementation provides double precision exp() faster than simd_math.h * * Only used in simd_math.h to selectively override the generic implementation. */ -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 //! \brief 1 if \ref gmx::gatherLoadUBySimdIntTranspose is present, otherwise 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 //! \brief 1 if \ref gmx::gatherLoadUBySimdIntTranspose is present, otherwise 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 //! \brief 1 if float half-register load/store/reduce utils present, otherwise 0 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 //! \brief 1 if double half-register load/store/reduce utils present, otherwise 0 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 #ifdef GMX_SIMD_REF_FLOAT_WIDTH -# define GMX_SIMD_FLOAT_WIDTH GMX_SIMD_REF_FLOAT_WIDTH +# define GMX_SIMD_FLOAT_WIDTH GMX_SIMD_REF_FLOAT_WIDTH #else //! \brief Width of the \ref gmx::SimdFloat datatype -# define GMX_SIMD_FLOAT_WIDTH 4 +# define GMX_SIMD_FLOAT_WIDTH 4 #endif #ifdef GMX_SIMD_REF_DOUBLE_WIDTH -# define GMX_SIMD_DOUBLE_WIDTH GMX_SIMD_REF_DOUBLE_WIDTH +# define GMX_SIMD_DOUBLE_WIDTH GMX_SIMD_REF_DOUBLE_WIDTH #else //! \brief Width of the \ref gmx::SimdDouble datatype -# define GMX_SIMD_DOUBLE_WIDTH 4 +# define GMX_SIMD_DOUBLE_WIDTH 4 #endif -#if GMX_SIMD_FLOAT_WIDTH >= 8 || defined DOXYGEN //set in simd.h for GMX_SIMD_FLOAT_WIDTH<=4 +#if GMX_SIMD_FLOAT_WIDTH >= 8 || defined DOXYGEN // set in simd.h for GMX_SIMD_FLOAT_WIDTH<=4 //! \brief 1 if float 4xN load utils present, otherwise 0 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 #endif -#if GMX_SIMD_DOUBLE_WIDTH >= 8 || defined DOXYGEN //set in simd.h for GMX_SIMD_DOUBLE_WIDTH<=4 +#if GMX_SIMD_DOUBLE_WIDTH >= 8 || defined DOXYGEN // set in simd.h for GMX_SIMD_DOUBLE_WIDTH<=4 //! \brief 1 if double 4xN load utils present, otherwise 0 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 #endif //! \brief 1 if implementation provides \ref gmx::Simd4Float, otherwise 0. -#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_FLOAT 1 //! \brief 1 if the implementation provides \ref gmx::Simd4Double, otherwise 0. -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 //! \brief Width of the \ref gmx::SimdFInt32 datatype. -#define GMX_SIMD_FINT32_WIDTH GMX_SIMD_FLOAT_WIDTH +#define GMX_SIMD_FINT32_WIDTH GMX_SIMD_FLOAT_WIDTH //! \brief Width of the \ref gmx::SimdDInt32 datatype. -#define GMX_SIMD_DINT32_WIDTH GMX_SIMD_DOUBLE_WIDTH +#define GMX_SIMD_DINT32_WIDTH GMX_SIMD_DOUBLE_WIDTH //! \brief The SIMD4 type is always four units wide, but this makes code more explicit -#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD4_WIDTH 4 /*! \brief Maximum required alignment in bytes for aligned load/store of multiple * values (maximum required for either float or double). */ -#if GMX_SIMD_DOUBLE_WIDTH >= 2*GMX_SIMD_FLOAT_WIDTH -#define GMX_SIMD_ALIGNMENT (GMX_SIMD_DOUBLE_WIDTH*8) +#if GMX_SIMD_DOUBLE_WIDTH >= 2 * GMX_SIMD_FLOAT_WIDTH +# define GMX_SIMD_ALIGNMENT (GMX_SIMD_DOUBLE_WIDTH * 8) #else -#define GMX_SIMD_ALIGNMENT (GMX_SIMD_FLOAT_WIDTH*4) +# define GMX_SIMD_ALIGNMENT (GMX_SIMD_FLOAT_WIDTH * 4) #endif //! \brief Accuracy of SIMD 1/sqrt(x) lookup. Used to determine number of iterations. -#define GMX_SIMD_RSQRT_BITS 23 +#define GMX_SIMD_RSQRT_BITS 23 //! \brief Accuracy of SIMD 1/x lookup. Used to determine number of iterations. -#define GMX_SIMD_RCP_BITS 23 +#define GMX_SIMD_RCP_BITS 23 //! \} @@ -252,5 +252,5 @@ namespace gmx //! \endcond -} +} // namespace gmx #endif // GMX_SIMD_IMPL_REFERENCE_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_reference/impl_reference_general.h b/src/gromacs/simd/impl_reference/impl_reference_general.h index 448415126c..99d113ae48 100644 --- a/src/gromacs/simd/impl_reference/impl_reference_general.h +++ b/src/gromacs/simd/impl_reference/impl_reference_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,12 +67,11 @@ namespace gmx * but if the pointer is not aligned the prefetch might start at the * lower cache line boundary (meaning fewer bytes are prefetched). */ -static inline void gmx_unused -simdPrefetch(void gmx_unused * m) +static inline void gmx_unused simdPrefetch(void gmx_unused* m) { // Do nothing for reference implementation } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_REFERENCE_GENERAL_H diff --git a/src/gromacs/simd/impl_reference/impl_reference_simd4_double.h b/src/gromacs/simd/impl_reference/impl_reference_simd4_double.h index 864c167a96..6511c96b5d 100644 --- a/src/gromacs/simd/impl_reference/impl_reference_simd4_double.h +++ b/src/gromacs/simd/impl_reference/impl_reference_simd4_double.h @@ -79,20 +79,20 @@ namespace gmx */ class Simd4Double { - public: - Simd4Double() {} - - //! \brief Construct from scalar - Simd4Double(double d) { simdInternal_.fill(d); } - - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; +public: + Simd4Double() {} + + //! \brief Construct from scalar + Simd4Double(double d) { simdInternal_.fill(d); } + + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief SIMD4 variable type to use for logical comparisons on doubles. @@ -106,20 +106,20 @@ class Simd4Double */ class Simd4DBool { - public: - Simd4DBool() {} +public: + Simd4DBool() {} - //! \brief Construct from scalar - Simd4DBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar + Simd4DBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \brief Load 4 double values from aligned memory into SIMD4 variable. @@ -127,14 +127,13 @@ class Simd4DBool * \param m Pointer to memory aligned to 4 elements. * \return SIMD4 variable with data loaded. */ -static inline Simd4Double gmx_simdcall -load4(const double *m) +static inline Simd4Double gmx_simdcall load4(const double* m) { Simd4Double a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(double)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(double)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -143,10 +142,9 @@ load4(const double *m) * \param[out] m Pointer to memory, aligned to 4 elements. * \param a SIMD4 variable to store */ -static inline void gmx_simdcall -store4(double *m, Simd4Double a) +static inline void gmx_simdcall store4(double* m, Simd4Double a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(double)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(double)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -158,11 +156,10 @@ store4(double *m, Simd4Double a) * \param m Pointer to memory, no alignment requirement. * \return SIMD4 variable with data loaded. */ -static inline Simd4Double gmx_simdcall -load4U(const double *m) +static inline Simd4Double gmx_simdcall load4U(const double* m) { Simd4Double a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -173,8 +170,7 @@ load4U(const double *m) * \param[out] m Pointer to memory, no alignment requirement. * \param a SIMD4 variable to store. */ -static inline void gmx_simdcall -store4U(double *m, Simd4Double a) +static inline void gmx_simdcall store4U(double* m, Simd4Double a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -186,8 +182,7 @@ store4U(double *m, Simd4Double a) * * \return SIMD4 0.0 */ -static inline Simd4Double gmx_simdcall -simd4SetZeroD() +static inline Simd4Double gmx_simdcall simd4SetZeroD() { return Simd4Double(0.0); } @@ -201,17 +196,14 @@ simd4SetZeroD() * \param b data2 * \return data1 & data2 */ -static inline Simd4Double gmx_simdcall -operator&(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -232,17 +224,14 @@ operator&(Simd4Double a, Simd4Double b) * \param b data2 * \return (~data1) & data2 */ -static inline Simd4Double gmx_simdcall -andNot(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -263,17 +252,14 @@ andNot(Simd4Double a, Simd4Double b) * \param b data2 * \return data1 | data2 */ -static inline Simd4Double gmx_simdcall -operator|(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -293,17 +279,14 @@ operator|(Simd4Double a, Simd4Double b) * \param b data2 * \return data1 ^ data2 */ -static inline Simd4Double gmx_simdcall -operator^(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -321,10 +304,9 @@ operator^(Simd4Double a, Simd4Double b) * \param b term2 * \return a+b */ -static inline Simd4Double gmx_simdcall -operator+(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -339,10 +321,9 @@ operator+(Simd4Double a, Simd4Double b) * \param b term2 * \return a-b */ -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -356,10 +337,9 @@ operator-(Simd4Double a, Simd4Double b) * \param a SIMD4 floating-point value * \return -a */ -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -374,10 +354,9 @@ operator-(Simd4Double a) * \param b factor2 * \return a*b. */ -static inline Simd4Double gmx_simdcall -operator*(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -393,10 +372,9 @@ operator*(Simd4Double a, Simd4Double b) * \param c term * \return a*b+c */ -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return a*b+c; + return a * b + c; } /*! \brief SIMD4 Fused-multiply-subtract. Result is a*b-c. @@ -406,10 +384,9 @@ fma(Simd4Double a, Simd4Double b, Simd4Double c) * \param c term * \return a*b-c */ -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return a*b-c; + return a * b - c; } /*! \brief SIMD4 Fused-negated-multiply-add. Result is -a*b+c. @@ -419,10 +396,9 @@ fms(Simd4Double a, Simd4Double b, Simd4Double c) * \param c term * \return -a*b+c */ -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return c-a*b; + return c - a * b; } /*! \brief SIMD4 Fused-negated-multiply-subtract. Result is -a*b-c. @@ -432,10 +408,9 @@ fnma(Simd4Double a, Simd4Double b, Simd4Double c) * \param c term * \return -a*b-c */ -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return -a*b-c; + return -a * b - c; } /*! \brief SIMD4 1.0/sqrt(x) lookup. @@ -446,10 +421,9 @@ fnms(Simd4Double a, Simd4Double b, Simd4Double c) * \param x Argument, x>0 * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. */ -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -465,10 +439,9 @@ rsqrt(Simd4Double x) * \param a any floating point values * \return fabs(a) for each element. */ -static inline Simd4Double gmx_simdcall -abs(Simd4Double a) +static inline Simd4Double gmx_simdcall abs(Simd4Double a) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -483,10 +456,9 @@ abs(Simd4Double a) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline Simd4Double gmx_simdcall -max(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -502,10 +474,9 @@ max(Simd4Double a, Simd4Double b) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline Simd4Double gmx_simdcall -min(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -520,10 +491,9 @@ min(Simd4Double a, Simd4Double b) * \param a Any floating-point value * \return The nearest integer, represented in floating-point format. */ -static inline Simd4Double gmx_simdcall -round(Simd4Double a) +static inline Simd4Double gmx_simdcall round(Simd4Double a) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -542,10 +512,9 @@ round(Simd4Double a) * is that truncation is virtually always present as a dedicated hardware * instruction, but floor() frequently isn't. */ -static inline Simd4Double gmx_simdcall -trunc(Simd4Double a) +static inline Simd4Double gmx_simdcall trunc(Simd4Double a) { - Simd4Double res; + Simd4Double res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -563,13 +532,10 @@ trunc(Simd4Double a) * \param b vector2 * \result a[0]*b[0]+a[1]*b[1]+a[2]*b[2], returned as scalar. Last element is ignored. */ -static inline double gmx_simdcall -dotProduct(Simd4Double a, Simd4Double b) +static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b) { - return - (a.simdInternal_[0] * b.simdInternal_[0] + - a.simdInternal_[1] * b.simdInternal_[1] + - a.simdInternal_[2] * b.simdInternal_[2]); + return (a.simdInternal_[0] * b.simdInternal_[0] + a.simdInternal_[1] * b.simdInternal_[1] + + a.simdInternal_[2] * b.simdInternal_[2]); } /*! \brief SIMD4 double transpose @@ -579,14 +545,12 @@ dotProduct(Simd4Double a, Simd4Double b) * \param[in,out] v2 Row 2 on input, column 2 on output * \param[in,out] v3 Row 3 on input, column 3 on output */ -static inline void gmx_simdcall -transpose(Simd4Double * v0, Simd4Double * v1, - Simd4Double * v2, Simd4Double * v3) +static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3) { - Simd4Double t0 = *v0; - Simd4Double t1 = *v1; - Simd4Double t2 = *v2; - Simd4Double t3 = *v3; + Simd4Double t0 = *v0; + Simd4Double t1 = *v1; + Simd4Double t2 = *v2; + Simd4Double t3 = *v3; v0->simdInternal_[0] = t0.simdInternal_[0]; v0->simdInternal_[1] = t1.simdInternal_[0]; v0->simdInternal_[2] = t2.simdInternal_[0]; @@ -611,10 +575,9 @@ transpose(Simd4Double * v0, Simd4Double * v1, * \param b value2 * \return Each element of the boolean will be set to true if a==b. */ -static inline Simd4DBool gmx_simdcall -operator==(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b) { - Simd4DBool res; + Simd4DBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -629,10 +592,9 @@ operator==(Simd4Double a, Simd4Double b) * \param b value2 * \return Each element of the boolean will be set to true if a!=b. */ -static inline Simd4DBool gmx_simdcall -operator!=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b) { - Simd4DBool res; + Simd4DBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -647,10 +609,9 @@ operator!=(Simd4Double a, Simd4Double b) * \param b value2 * \return Each element of the boolean will be set to true if a simdInternal_; +public: + Simd4Float() {} + + //! \brief Construct from scalar + Simd4Float(float f) { simdInternal_.fill(f); } + + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief SIMD4 variable type to use for logical comparisons on floats. @@ -106,20 +106,20 @@ class Simd4Float */ class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - //! \brief Construct from scalar bool - Simd4FBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar bool + Simd4FBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \brief Load 4 float values from aligned memory into SIMD4 variable. @@ -127,14 +127,13 @@ class Simd4FBool * \param m Pointer to memory aligned to 4 elements. * \return SIMD4 variable with data loaded. */ -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { Simd4Float a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(float)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(float)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -143,10 +142,9 @@ load4(const float *m) * \param[out] m Pointer to memory, aligned to 4 elements. * \param a SIMD4 variable to store */ -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(float)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(float)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -158,11 +156,10 @@ store4(float *m, Simd4Float a) * \param m Pointer to memory, no alignment requirement. * \return SIMD4 variable with data loaded. */ -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { Simd4Float a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -173,8 +170,7 @@ load4U(const float *m) * \param[out] m Pointer to memory, no alignment requirement. * \param a SIMD4 variable to store. */ -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -186,8 +182,7 @@ store4U(float *m, Simd4Float a) * * \return SIMD4 0.0 */ -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { return Simd4Float(0.0F); } @@ -201,17 +196,14 @@ simd4SetZeroF() * \param b data2 * \return data1 & data2 */ -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -232,17 +224,14 @@ operator&(Simd4Float a, Simd4Float b) * \param b data2 * \return (~data1) & data2 */ -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -263,17 +252,14 @@ andNot(Simd4Float a, Simd4Float b) * \param b data2 * \return data1 | data2 */ -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -293,17 +279,14 @@ operator|(Simd4Float a, Simd4Float b) * \param b data2 * \return data1 ^ data2 */ -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -321,10 +304,9 @@ operator^(Simd4Float a, Simd4Float b) * \param b term2 * \return a+b */ -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -339,10 +321,9 @@ operator+(Simd4Float a, Simd4Float b) * \param b term2 * \return a-b */ -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -356,10 +337,9 @@ operator-(Simd4Float a, Simd4Float b) * \param a SIMD4 floating-point value * \return -a */ -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -374,10 +354,9 @@ operator-(Simd4Float a) * \param b factor2 * \return a*b. */ -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -393,10 +372,9 @@ operator*(Simd4Float a, Simd4Float b) * \param c term * \return a*b+c */ -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return a*b+c; + return a * b + c; } /*! \brief SIMD4 Fused-multiply-subtract. Result is a*b-c. @@ -406,10 +384,9 @@ fma(Simd4Float a, Simd4Float b, Simd4Float c) * \param c term * \return a*b-c */ -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return a*b-c; + return a * b - c; } /*! \brief SIMD4 Fused-negated-multiply-add. Result is -a*b+c. @@ -419,10 +396,9 @@ fms(Simd4Float a, Simd4Float b, Simd4Float c) * \param c term * \return -a*b+c */ -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return c-a*b; + return c - a * b; } /*! \brief SIMD4 Fused-negated-multiply-subtract. Result is -a*b-c. @@ -432,10 +408,9 @@ fnma(Simd4Float a, Simd4Float b, Simd4Float c) * \param c term * \return -a*b-c */ -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return -a*b-c; + return -a * b - c; } /*! \brief SIMD4 1.0/sqrt(x) lookup. @@ -446,10 +421,9 @@ fnms(Simd4Float a, Simd4Float b, Simd4Float c) * \param x Argument, x>0 * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. */ -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -464,10 +438,9 @@ rsqrt(Simd4Float x) * \param a any floating point values * \return fabs(a) for each element. */ -static inline Simd4Float gmx_simdcall -abs(Simd4Float a) +static inline Simd4Float gmx_simdcall abs(Simd4Float a) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -482,10 +455,9 @@ abs(Simd4Float a) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -501,10 +473,9 @@ max(Simd4Float a, Simd4Float b) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -519,10 +490,9 @@ min(Simd4Float a, Simd4Float b) * \param a Any floating-point value * \return The nearest integer, represented in floating-point format. */ -static inline Simd4Float gmx_simdcall -round(Simd4Float a) +static inline Simd4Float gmx_simdcall round(Simd4Float a) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -541,10 +511,9 @@ round(Simd4Float a) * is that truncation is virtually always present as a dedicated hardware * instruction, but floor() frequently isn't. */ -static inline Simd4Float gmx_simdcall -trunc(Simd4Float a) +static inline Simd4Float gmx_simdcall trunc(Simd4Float a) { - Simd4Float res; + Simd4Float res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -562,13 +531,10 @@ trunc(Simd4Float a) * \param b vector2 * \result a[0]*b[0]+a[1]*b[1]+a[2]*b[2], returned as scalar. Last element is ignored. */ -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { - return - (a.simdInternal_[0] * b.simdInternal_[0] + - a.simdInternal_[1] * b.simdInternal_[1] + - a.simdInternal_[2] * b.simdInternal_[2]); + return (a.simdInternal_[0] * b.simdInternal_[0] + a.simdInternal_[1] * b.simdInternal_[1] + + a.simdInternal_[2] * b.simdInternal_[2]); } /*! \brief SIMD4 float transpose @@ -578,14 +544,12 @@ dotProduct(Simd4Float a, Simd4Float b) * \param[in,out] v2 Row 2 on input, column 2 on output * \param[in,out] v3 Row 3 on input, column 3 on output */ -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { - Simd4Float t0 = *v0; - Simd4Float t1 = *v1; - Simd4Float t2 = *v2; - Simd4Float t3 = *v3; + Simd4Float t0 = *v0; + Simd4Float t1 = *v1; + Simd4Float t2 = *v2; + Simd4Float t3 = *v3; v0->simdInternal_[0] = t0.simdInternal_[0]; v0->simdInternal_[1] = t1.simdInternal_[0]; v0->simdInternal_[2] = t2.simdInternal_[0]; @@ -610,10 +574,9 @@ transpose(Simd4Float * v0, Simd4Float * v1, * \param b value2 * \return Each element of the boolean will be set to true if a==b. */ -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - Simd4FBool res; + Simd4FBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -628,10 +591,9 @@ operator==(Simd4Float a, Simd4Float b) * \param b value2 * \return Each element of the boolean will be set to true if a!=b. */ -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - Simd4FBool res; + Simd4FBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -646,10 +608,9 @@ operator!=(Simd4Float a, Simd4Float b) * \param b value2 * \return Each element of the boolean will be set to true if a simdInternal_; +public: + SimdDouble() {} + + //! \brief Construct from scalar + SimdDouble(double d) { simdInternal_.fill(d); } + + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Integer SIMD variable type to use for conversions to/from double. @@ -114,20 +114,20 @@ class SimdDouble */ class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - //! \brief Construct from scalar - SimdDInt32(std::int32_t i) { simdInternal_.fill(i); } + //! \brief Construct from scalar + SimdDInt32(std::int32_t i) { simdInternal_.fill(i); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Boolean type for double SIMD data. @@ -141,20 +141,20 @@ class SimdDInt32 */ class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - //! \brief Construct from scalar bool - SimdDBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar bool + SimdDBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Boolean type for integer datatypes corresponding to double SIMD. @@ -168,20 +168,20 @@ class SimdDBool */ class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - //! \brief Construct from scalar - SimdDIBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar + SimdDIBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \} @@ -195,14 +195,13 @@ class SimdDIBool * \param m Pointer to memory aligned to the SIMD width. * \return SIMD variable with data loaded. */ -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { SimdDouble a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(double)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(double)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -211,10 +210,9 @@ simdLoad(const double *m, SimdDoubleTag = {}) * \param[out] m Pointer to memory, aligned to SIMD width. * \param a SIMD variable to store */ -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(double)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(double)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -226,11 +224,10 @@ store(double *m, SimdDouble a) * \param m Pointer to memory, no alignment requirement. * \return SIMD variable with data loaded. */ -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { SimdDouble a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -241,8 +238,7 @@ simdLoadU(const double *m, SimdDoubleTag = {}) * \param[out] m Pointer to memory, no alignment requirement. * \param a SIMD variable to store. */ -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -254,8 +250,7 @@ storeU(double *m, SimdDouble a) * * \return SIMD 0.0 */ -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { return SimdDouble(0.0); } @@ -274,14 +269,13 @@ setZeroD() * \param m Pointer to memory, aligned to (double) integer SIMD width. * \return SIMD integer variable. */ -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { SimdDInt32 a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(std::int32_t)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(std::int32_t)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; }; @@ -290,10 +284,9 @@ simdLoad(const std::int32_t * m, SimdDInt32Tag) * \param m Memory aligned to (double) integer SIMD width. * \param a SIMD (double) integer variable to store. */ -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(std::int32_t)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(std::int32_t)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); }; @@ -308,11 +301,10 @@ store(std::int32_t * m, SimdDInt32 a) * \param m Pointer to memory, no alignment requirements. * \return SIMD integer variable. */ -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { SimdDInt32 a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -323,8 +315,7 @@ simdLoadU(const std::int32_t *m, SimdDInt32Tag) * \param m Memory pointer, no alignment requirements. * \param a SIMD (double) integer variable to store. */ -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -336,8 +327,7 @@ storeU(std::int32_t * m, SimdDInt32 a) * * \return SIMD 0 */ -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { return SimdDInt32(0); } @@ -351,8 +341,7 @@ setZeroDI() * \return Single integer from position index in SIMD variable. */ template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 a) { return a.simdInternal_[index]; } @@ -371,17 +360,14 @@ extract(SimdDInt32 a) * \param b data2 * \return data1 & data2 */ -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -401,17 +387,14 @@ operator&(SimdDouble a, SimdDouble b) * \param b data2 * \return (~data1) & data2 */ -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -431,17 +414,14 @@ andNot(SimdDouble a, SimdDouble b) * \param b data2 * \return data1 | data2 */ -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -461,17 +441,14 @@ operator|(SimdDouble a, SimdDouble b) * \param b data2 * \return data1 ^ data2 */ -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; - union - { - double r; - std::int64_t i; - } - conv1, conv2; + union { + double r; + std::int64_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -495,10 +472,9 @@ operator^(SimdDouble a, SimdDouble b) * \param b term2 * \return a+b */ -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -513,10 +489,9 @@ operator+(SimdDouble a, SimdDouble b) * \param b term2 * \return a-b */ -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -530,10 +505,9 @@ operator-(SimdDouble a, SimdDouble b) * \param a SIMD double precision value * \return -a */ -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -548,10 +522,9 @@ operator-(SimdDouble a) * \param b factor2 * \return a*b. */ -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -567,10 +540,9 @@ operator*(SimdDouble a, SimdDouble b) * \param c term * \return a*b+c */ -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return a*b+c; + return a * b + c; } /*! \brief SIMD double Fused-multiply-subtract. Result is a*b-c. @@ -580,10 +552,9 @@ fma(SimdDouble a, SimdDouble b, SimdDouble c) * \param c term * \return a*b-c */ -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return a*b-c; + return a * b - c; } /*! \brief SIMD double Fused-negated-multiply-add. Result is -a*b+c. @@ -593,10 +564,9 @@ fms(SimdDouble a, SimdDouble b, SimdDouble c) * \param c term * \return -a*b+c */ -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return c-a*b; + return c - a * b; } /*! \brief SIMD double Fused-negated-multiply-subtract. Result is -a*b-c. @@ -606,10 +576,9 @@ fnma(SimdDouble a, SimdDouble b, SimdDouble c) * \param c term * \return -a*b-c */ -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return -a*b-c; + return -a * b - c; } /*! \brief double SIMD 1.0/sqrt(x) lookup. @@ -620,10 +589,9 @@ fnms(SimdDouble a, SimdDouble b, SimdDouble c) * \param x Argument, x>0 * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. */ -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -641,10 +609,9 @@ rsqrt(SimdDouble x) * \param x Argument, x!=0 * \return Approximation of 1/x, accuracy is \ref GMX_SIMD_RCP_BITS. */ -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -661,10 +628,9 @@ rcp(SimdDouble x) * \param m mask * \return a+b where mask is true, 0.0 otherwise. */ -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -680,10 +646,9 @@ maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) * \param m mask * \return a*b where mask is true, 0.0 otherwise. */ -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -700,14 +665,14 @@ maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) * \param m mask * \return a*b+c where mask is true, 0.0 otherwise. */ -static inline SimdDouble gmx_simdcall -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { - res.simdInternal_[i] = m.simdInternal_[i] ? (a.simdInternal_[i] * b.simdInternal_[i] + c.simdInternal_[i]) : 0.0; + res.simdInternal_[i] = + m.simdInternal_[i] ? (a.simdInternal_[i] * b.simdInternal_[i] + c.simdInternal_[i]) : 0.0; } return res; } @@ -722,15 +687,16 @@ maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. * The result for masked-out entries will be 0.0. */ -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { // sic - we only use single precision for the lookup - res.simdInternal_[i] = (m.simdInternal_[i] != 0) ? 1.0F / std::sqrt(static_cast(x.simdInternal_[i])) : 0.0; + res.simdInternal_[i] = (m.simdInternal_[i] != 0) + ? 1.0F / std::sqrt(static_cast(x.simdInternal_[i])) + : 0.0; } return res; } @@ -745,14 +711,14 @@ maskzRsqrt(SimdDouble x, SimdDBool m) * \return Approximation of 1/x, accuracy is \ref GMX_SIMD_RCP_BITS. * The result for masked-out entries will be 0.0. */ -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { - res.simdInternal_[i] = (m.simdInternal_[i] != 0) ? 1.0F / static_cast(x.simdInternal_[i]) : 0.0; + res.simdInternal_[i] = + (m.simdInternal_[i] != 0) ? 1.0F / static_cast(x.simdInternal_[i]) : 0.0; } return res; } @@ -762,10 +728,9 @@ maskzRcp(SimdDouble x, SimdDBool m) * \param a any floating point values * \return fabs(a) for each element. */ -static inline SimdDouble gmx_simdcall -abs(SimdDouble a) +static inline SimdDouble gmx_simdcall abs(SimdDouble a) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -780,10 +745,9 @@ abs(SimdDouble a) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -798,10 +762,9 @@ max(SimdDouble a, SimdDouble b) * \param b Any floating-point value * \return min(a,b) for each element. */ -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -818,10 +781,9 @@ min(SimdDouble a, SimdDouble b) * \note Round mode is implementation defined. The only guarantee is that it * is consistent between rounding functions (round, cvtR2I). */ -static inline SimdDouble gmx_simdcall -round(SimdDouble a) +static inline SimdDouble gmx_simdcall round(SimdDouble a) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -839,10 +801,9 @@ round(SimdDouble a) * is that truncation is virtually always present as a dedicated hardware * instruction, but floor() frequently isn't. */ -static inline SimdDouble gmx_simdcall -trunc(SimdDouble a) +static inline SimdDouble gmx_simdcall trunc(SimdDouble a) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -857,8 +818,7 @@ trunc(SimdDouble a) * \param[out] exponent Returned exponent of value, integer SIMD format. * \return Fraction of value, floating-point SIMD format. */ -static inline SimdDouble gmx_simdcall -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble gmx_simdcall frexp(SimdDouble value, SimdDInt32* exponent) { SimdDouble fraction; @@ -883,11 +843,10 @@ frexp(SimdDouble value, SimdDInt32 * exponent) * \param exponent Integer that will not overflow as 2^exponent. * \return value*2^exponent */ -template -static inline SimdDouble gmx_simdcall -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble gmx_simdcall ldexp(SimdDouble value, SimdDInt32 exponent) { - SimdDouble res; + SimdDouble res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -904,8 +863,7 @@ ldexp(SimdDouble value, SimdDInt32 exponent) * \return The sum of all elements in the argument variable. * */ -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { double sum = 0.0; @@ -930,10 +888,9 @@ reduce(SimdDouble a) * * Beware that exact floating-point comparisons are difficult. */ -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - SimdDBool res; + SimdDBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -950,10 +907,9 @@ operator==(SimdDouble a, SimdDouble b) * * Beware that exact floating-point comparisons are difficult. */ -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - SimdDBool res; + SimdDBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -968,10 +924,9 @@ operator!=(SimdDouble a, SimdDouble b) * \param b value2 * \return Each element of the boolean will be set to true if asimdInternal_.size(); i++) { d0->simdInternal_[i] = f.simdInternal_[i]; - d1->simdInternal_[i] = f.simdInternal_[f.simdInternal_.size()/2 + i]; + d1->simdInternal_[i] = f.simdInternal_[f.simdInternal_.size() / 2 + i]; } #else gmx_fatal(FARGS, "simdCvtF2DD() requires GMX_SIMD_FLOAT_WIDTH==2*GMX_SIMD_DOUBLE_WIDTH"); @@ -1682,15 +1606,14 @@ cvtF2DD(SimdFloat gmx_unused f, SimdDouble gmx_unused * d0, SimdDouble gmx_unuse * \param d1 Double-precision SIMD variable, second half of values to put in f. * \return Single-precision SIMD variable with all values. */ -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble gmx_unused d0, SimdDouble gmx_unused d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble gmx_unused d0, SimdDouble gmx_unused d1) { -#if (GMX_SIMD_FLOAT_WIDTH == 2*GMX_SIMD_DOUBLE_WIDTH) - SimdFloat f; +#if (GMX_SIMD_FLOAT_WIDTH == 2 * GMX_SIMD_DOUBLE_WIDTH) + SimdFloat f; for (std::size_t i = 0; i < d0.simdInternal_.size(); i++) { - f.simdInternal_[i] = d0.simdInternal_[i]; - f.simdInternal_[f.simdInternal_.size()/2 + i] = d1.simdInternal_[i]; + f.simdInternal_[i] = d0.simdInternal_[i]; + f.simdInternal_[f.simdInternal_.size() / 2 + i] = d1.simdInternal_[i]; } return f; #else @@ -1703,6 +1626,6 @@ cvtDD2F(SimdDouble gmx_unused d0, SimdDouble gmx_unused d1) /*! \} */ /*! \endcond */ -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_REFERENCE_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_reference/impl_reference_simd_float.h b/src/gromacs/simd/impl_reference/impl_reference_simd_float.h index 5261bc36a7..6b0a943abb 100644 --- a/src/gromacs/simd/impl_reference/impl_reference_simd_float.h +++ b/src/gromacs/simd/impl_reference/impl_reference_simd_float.h @@ -79,20 +79,20 @@ namespace gmx */ class SimdFloat { - public: - SimdFloat() {} - - //! \brief Construct from scalar - SimdFloat(float f) { simdInternal_.fill(f); } - - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; +public: + SimdFloat() {} + + //! \brief Construct from scalar + SimdFloat(float f) { simdInternal_.fill(f); } + + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Integer SIMD variable type to use for conversions to/from float. @@ -111,20 +111,20 @@ class SimdFloat */ class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - //! \brief Construct from scalar - SimdFInt32(std::int32_t i) { simdInternal_.fill(i); } + //! \brief Construct from scalar + SimdFInt32(std::int32_t i) { simdInternal_.fill(i); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Boolean type for float SIMD data. @@ -138,20 +138,20 @@ class SimdFInt32 */ class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - //! \brief Construct from scalar - SimdFBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar + SimdFBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \libinternal \brief Boolean type for integer datatypes corresponding to float SIMD. @@ -165,20 +165,20 @@ class SimdFBool */ class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - //! \brief Construct from scalar - SimdFIBool(bool b) { simdInternal_.fill(b); } + //! \brief Construct from scalar + SimdFIBool(bool b) { simdInternal_.fill(b); } - /*! \brief Internal SIMD data. Implementation dependent, don't touch. - * - * This has to be public to enable usage in combination with static inline - * functions, but it should never, EVER, be accessed by any code outside - * the corresponding implementation directory since the type will depend - * on the architecture. - */ - std::array simdInternal_; + /*! \brief Internal SIMD data. Implementation dependent, don't touch. + * + * This has to be public to enable usage in combination with static inline + * functions, but it should never, EVER, be accessed by any code outside + * the corresponding implementation directory since the type will depend + * on the architecture. + */ + std::array simdInternal_; }; /*! \} @@ -192,14 +192,13 @@ class SimdFIBool * \param m Pointer to memory aligned to the SIMD width. * \return SIMD variable with data loaded. */ -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { SimdFloat a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(float)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(float)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -208,10 +207,9 @@ simdLoad(const float *m, SimdFloatTag = {}) * \param[out] m Pointer to memory, aligned to SIMD width. * \param a SIMD variable to store */ -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(float)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(float)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -223,11 +221,10 @@ store(float *m, SimdFloat a) * \param m Pointer to memory, no alignment requirement. * \return SIMD variable with data loaded. */ -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { SimdFloat a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -238,8 +235,7 @@ simdLoadU(const float *m, SimdFloatTag = {}) * \param[out] m Pointer to memory, no alignment requirement. * \param a SIMD variable to store. */ -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -251,8 +247,7 @@ storeU(float *m, SimdFloat a) * * \return SIMD 0.0F */ -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { return SimdFloat(0.0F); } @@ -273,14 +268,13 @@ setZeroF() * \param m Pointer to memory, aligned to (float) integer SIMD width. * \return SIMD integer variable. */ -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { SimdFInt32 a; - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(std::int32_t)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(std::int32_t)) == 0); - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; }; @@ -289,10 +283,9 @@ simdLoad(const std::int32_t * m, SimdFInt32Tag) * \param m Memory aligned to (float) integer SIMD width. * \param a SIMD variable to store. */ -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { - assert(std::size_t(m) % (a.simdInternal_.size()*sizeof(std::int32_t)) == 0); + assert(std::size_t(m) % (a.simdInternal_.size() * sizeof(std::int32_t)) == 0); std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); }; @@ -307,11 +300,10 @@ store(std::int32_t * m, SimdFInt32 a) * \param m Pointer to memory, no alignment requirements. * \return SIMD integer variable. */ -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { SimdFInt32 a; - std::copy(m, m+a.simdInternal_.size(), a.simdInternal_.begin()); + std::copy(m, m + a.simdInternal_.size(), a.simdInternal_.begin()); return a; } @@ -322,8 +314,7 @@ simdLoadU(const std::int32_t *m, SimdFInt32Tag) * \param m Memory pointer, no alignment requirements. * \param a SIMD variable to store. */ -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { std::copy(a.simdInternal_.begin(), a.simdInternal_.end(), m); } @@ -335,8 +326,7 @@ storeU(std::int32_t * m, SimdFInt32 a) * * \return SIMD 0 */ -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { return SimdFInt32(0); } @@ -350,8 +340,7 @@ setZeroFI() * \return Single integer from position index in SIMD variable. */ template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 a) { return a.simdInternal_[index]; } @@ -370,17 +359,14 @@ extract(SimdFInt32 a) * \param b data2 * \return data1 & data2 */ -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -400,17 +386,14 @@ operator&(SimdFloat a, SimdFloat b) * \param b data2 * \return (~data1) & data2 */ -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -430,17 +413,14 @@ andNot(SimdFloat a, SimdFloat b) * \param b data2 * \return data1 | data2 */ -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -460,17 +440,14 @@ operator|(SimdFloat a, SimdFloat b) * \param b data2 * \return data1 ^ data2 */ -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; - union - { - float r; - std::int32_t i; - } - conv1, conv2; + union { + float r; + std::int32_t i; + } conv1, conv2; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -494,10 +471,9 @@ operator^(SimdFloat a, SimdFloat b) * \param b term2 * \return a+b */ -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -512,10 +488,9 @@ operator+(SimdFloat a, SimdFloat b) * \param b term2 * \return a-b */ -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -529,10 +504,9 @@ operator-(SimdFloat a, SimdFloat b) * \param a SIMD double precision value * \return -a */ -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -547,10 +521,9 @@ operator-(SimdFloat a) * \param b factor2 * \return a*b. */ -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -566,10 +539,9 @@ operator*(SimdFloat a, SimdFloat b) * \param c term * \return a*b+c */ -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return a*b+c; + return a * b + c; } /*! \brief SIMD float Fused-multiply-subtract. Result is a*b-c. @@ -579,10 +551,9 @@ fma(SimdFloat a, SimdFloat b, SimdFloat c) * \param c term * \return a*b-c */ -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return a*b-c; + return a * b - c; } /*! \brief SIMD float Fused-negated-multiply-add. Result is -a*b+c. @@ -592,10 +563,9 @@ fms(SimdFloat a, SimdFloat b, SimdFloat c) * \param c term * \return -a*b+c */ -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return c-a*b; + return c - a * b; } /*! \brief SIMD float Fused-negated-multiply-subtract. Result is -a*b-c. @@ -605,10 +575,9 @@ fnma(SimdFloat a, SimdFloat b, SimdFloat c) * \param c term * \return -a*b-c */ -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return -a*b-c; + return -a * b - c; } /*! \brief SIMD float 1.0/sqrt(x) lookup. @@ -619,10 +588,9 @@ fnms(SimdFloat a, SimdFloat b, SimdFloat c) * \param x Argument, x>0 * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. */ -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -639,10 +607,9 @@ rsqrt(SimdFloat x) * \param x Argument, x!=0 * \return Approximation of 1/x, accuracy is \ref GMX_SIMD_RCP_BITS. */ -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -658,10 +625,9 @@ rcp(SimdFloat x) * \param m mask * \return a+b where mask is true, a otherwise. */ -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -677,10 +643,9 @@ maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) * \param m mask * \return a*b where mask is true, 0.0 otherwise. */ -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -697,14 +662,14 @@ maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) * \param m mask * \return a*b+c where mask is true, 0.0 otherwise. */ -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { - res.simdInternal_[i] = m.simdInternal_[i] ? (a.simdInternal_[i] * b.simdInternal_[i] + c.simdInternal_[i]) : 0.0F; + res.simdInternal_[i] = + m.simdInternal_[i] ? (a.simdInternal_[i] * b.simdInternal_[i] + c.simdInternal_[i]) : 0.0F; } return res; } @@ -719,10 +684,9 @@ maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) * \return Approximation of 1/sqrt(x), accuracy is \ref GMX_SIMD_RSQRT_BITS. * The result for masked-out entries will be 0.0. */ -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -741,10 +705,9 @@ maskzRsqrt(SimdFloat x, SimdFBool m) * \return Approximation of 1/x, accuracy is \ref GMX_SIMD_RCP_BITS. * The result for masked-out entries will be 0.0. */ -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -758,10 +721,9 @@ maskzRcp(SimdFloat x, SimdFBool m) * \param a any floating point values * \return abs(a) for each element. */ -static inline SimdFloat gmx_simdcall -abs(SimdFloat a) +static inline SimdFloat gmx_simdcall abs(SimdFloat a) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -776,10 +738,9 @@ abs(SimdFloat a) * \param b Any floating-point value * \return max(a,b) for each element. */ -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -794,10 +755,9 @@ max(SimdFloat a, SimdFloat b) * \param b Any floating-point value * \return min(a,b) for each element. */ -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -814,10 +774,9 @@ min(SimdFloat a, SimdFloat b) * \note Round mode is implementation defined. The only guarantee is that it * is consistent between rounding functions (round, cvtR2I). */ -static inline SimdFloat gmx_simdcall -round(SimdFloat a) +static inline SimdFloat gmx_simdcall round(SimdFloat a) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -835,10 +794,9 @@ round(SimdFloat a) * is that truncation is virtually always present as a dedicated hardware * instruction, but floor() frequently isn't. */ -static inline SimdFloat gmx_simdcall -trunc(SimdFloat a) +static inline SimdFloat gmx_simdcall trunc(SimdFloat a) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -853,8 +811,7 @@ trunc(SimdFloat a) * \param[out] exponent Returned exponent of value, integer SIMD format. * \return Fraction of value, floating-point SIMD format. */ -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { SimdFloat fraction; @@ -879,11 +836,10 @@ frexp(SimdFloat value, SimdFInt32 * exponent) * \param exponent Integer that will not overflow as 2^exponent. * \return value*2^exponent */ -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { - SimdFloat res; + SimdFloat res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -900,8 +856,7 @@ ldexp(SimdFloat value, SimdFInt32 exponent) * \return The sum of all elements in the argument variable. * */ -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { float sum = 0.0F; @@ -926,10 +881,9 @@ reduce(SimdFloat a) * * Beware that exact floating-point comparisons are difficult. */ -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - SimdFBool res; + SimdFBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -946,10 +900,9 @@ operator==(SimdFloat a, SimdFloat b) * * Beware that exact floating-point comparisons are difficult. */ -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - SimdFBool res; + SimdFBool res; for (std::size_t i = 0; i < res.simdInternal_.size(); i++) { @@ -964,10 +917,9 @@ operator!=(SimdFloat a, SimdFloat b) * \param b value2 * \return Each element of the boolean will be set to true if a -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); // Base pointer must be aligned to the smaller of 4 elements and double SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4)*sizeof(double)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4) * sizeof(double)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_DOUBLE_WIDTH, 4) == 0); @@ -149,17 +148,14 @@ gatherLoadTranspose(const double * base, * \note You should NOT scale offsets before calling this routine; it is * done internally by using the alignment template parameter instead. */ -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); // Base pointer must be aligned to the smaller of 2 elements and double SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2)*sizeof(double)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2) * sizeof(double)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_DOUBLE_WIDTH, 2) == 0); @@ -217,16 +213,15 @@ static const int c_simdBestPairAlignmentDouble = 2; * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0->simdInternal_.size(); i++) { @@ -270,16 +265,15 @@ gatherLoadUTranspose(const double * base, * load the data from memory. On the architectures we have tested this * is faster even when a SIMD integer datatype is present. */ -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { @@ -330,20 +324,16 @@ transposeScatterStoreU(double * base, * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { - base[align * offset[i]] += v0.simdInternal_[i]; + base[align * offset[i]] += v0.simdInternal_[i]; base[align * offset[i] + 1] += v1.simdInternal_[i]; base[align * offset[i] + 2] += v2.simdInternal_[i]; } @@ -389,20 +379,16 @@ transposeScatterIncrU(double * base, * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { // Offset list must be aligned for SIMD DINT32 - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { - base[align * offset[i]] -= v0.simdInternal_[i]; + base[align * offset[i]] -= v0.simdInternal_[i]; base[align * offset[i] + 1] -= v1.simdInternal_[i]; base[align * offset[i] + 2] -= v2.simdInternal_[i]; } @@ -429,11 +415,10 @@ transposeScatterDecrU(double * base, * first, second and third pair of SIMD variables, and store the three * results back into a suitable vector-format array. */ -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { for (std::size_t i = 0; i < scalar.simdInternal_.size(); i++) { @@ -470,17 +455,16 @@ expandScalarsToTriplets(SimdDouble scalar, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 offset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { // Base pointer must be aligned to the smaller of 4 elements and double SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4)*sizeof(double)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4) * sizeof(double)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_DOUBLE_WIDTH, 4) == 0); @@ -518,12 +502,9 @@ gatherLoadBySimdIntTranspose(const double * base, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { for (std::size_t i = 0; i < v0->simdInternal_.size(); i++) { @@ -556,15 +537,12 @@ gatherLoadUBySimdIntTranspose(const double * base, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { // Base pointer must be aligned to the smaller of 2 elements and double SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2)*sizeof(double)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2) * sizeof(double)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_DOUBLE_WIDTH, 2) == 0); @@ -602,16 +580,12 @@ gatherLoadBySimdIntTranspose(const double * base, * just ignore the return value (Checked with gcc-4.9.1 and clang-3.6 for AVX). */ static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { double sum[4]; // Note that the 4 here corresponds to the 4 m-elements, not any SIMD width // Make sure the memory pointer is aligned to the smaller of 4 elements and double SIMD width - assert(std::size_t(m) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4)*sizeof(double)) == 0); + assert(std::size_t(m) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4) * sizeof(double)) == 0); sum[0] = reduce(v0); sum[1] = reduce(v1); @@ -647,20 +621,18 @@ reduceIncr4ReturnSum(double * m, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline SimdDouble gmx_simdcall -loadDualHsimd(const double * m0, - const double * m1) +static inline SimdDouble gmx_simdcall loadDualHsimd(const double* m0, const double* m1) { - SimdDouble a; + SimdDouble a; // Make sure the memory pointers are aligned to half double SIMD width - assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m0[i]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = m1[i]; + a.simdInternal_[i] = m0[i]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = m1[i]; } return a; } @@ -673,18 +645,17 @@ loadDualHsimd(const double * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline SimdDouble gmx_simdcall -loadDuplicateHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadDuplicateHsimd(const double* m) { - SimdDouble a; + SimdDouble a; // Make sure the memory pointer is aligned - assert(std::size_t(m) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); + assert(std::size_t(m) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m[i]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = a.simdInternal_[i]; + a.simdInternal_[i] = m[i]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = a.simdInternal_[i]; } return a; } @@ -702,15 +673,14 @@ loadDuplicateHsimd(const double * m) * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline SimdDouble gmx_simdcall -loadU1DualHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadU1DualHsimd(const double* m) { - SimdDouble a; + SimdDouble a; - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m[0]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = m[1]; + a.simdInternal_[i] = m[0]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = m[1]; } return a; } @@ -724,19 +694,16 @@ loadU1DualHsimd(const double * m) * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline void gmx_simdcall -storeDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall storeDualHsimd(double* m0, double* m1, SimdDouble a) { // Make sure the memory pointers are aligned to half double SIMD width - assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { m0[i] = a.simdInternal_[i]; - m1[i] = a.simdInternal_[a.simdInternal_.size()/2 + i]; + m1[i] = a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -753,22 +720,19 @@ storeDualHsimd(double * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline void gmx_simdcall -incrDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall incrDualHsimd(double* m0, double* m1, SimdDouble a) { // Make sure the memory pointer is aligned to half double SIMD width - assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { m0[i] += a.simdInternal_[i]; } - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - m1[i] += a.simdInternal_[a.simdInternal_.size()/2 + i]; + m1[i] += a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -785,16 +749,14 @@ incrDualHsimd(double * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline void gmx_simdcall -decrHsimd(double * m, - SimdDouble a) +static inline void gmx_simdcall decrHsimd(double* m, SimdDouble a) { // Make sure the memory pointer is aligned to half double SIMD width - assert(std::size_t(m) % (GMX_SIMD_DOUBLE_WIDTH/2*sizeof(double)) == 0); + assert(std::size_t(m) % (GMX_SIMD_DOUBLE_WIDTH / 2 * sizeof(double)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - m[i] -= a.simdInternal_[i] + a.simdInternal_[a.simdInternal_.size()/2 + i]; + m[i] -= a.simdInternal_[i] + a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -833,28 +795,27 @@ decrHsimd(double * m, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const double * base0, - const double * base1, - std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const double* base0, + const double* base1, + std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1) { // Offset list must be aligned for half SIMD DINT32 width - assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH/2*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_DINT32_WIDTH / 2 * sizeof(std::int32_t)) == 0); // base pointers must be aligned to the smaller of 2 elements and double SIMD width - assert(std::size_t(base0) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2)*sizeof(double)) == 0); - assert(std::size_t(base1) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2)*sizeof(double)) == 0); + assert(std::size_t(base0) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2) * sizeof(double)) == 0); + assert(std::size_t(base1) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 2) * sizeof(double)) == 0); // alignment parameter must be also be multiple of the above required alignment assert(align % std::min(GMX_SIMD_DOUBLE_WIDTH, 2) == 0); - for (std::size_t i = 0; i < v0->simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < v0->simdInternal_.size() / 2; i++) { - v0->simdInternal_[i] = base0[align * offset[i]]; - v1->simdInternal_[i] = base0[align * offset[i] + 1]; - v0->simdInternal_[v0->simdInternal_.size()/2 + i] = base1[align * offset[i]]; - v1->simdInternal_[v1->simdInternal_.size()/2 + i] = base1[align * offset[i] + 1]; + v0->simdInternal_[i] = base0[align * offset[i]]; + v1->simdInternal_[i] = base0[align * offset[i] + 1]; + v0->simdInternal_[v0->simdInternal_.size() / 2 + i] = base1[align * offset[i]]; + v1->simdInternal_[v1->simdInternal_.size() / 2 + i] = base1[align * offset[i] + 1]; } } @@ -878,24 +839,21 @@ gatherLoadTransposeHsimd(const double * base0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE is 1. */ -static inline double gmx_simdcall -reduceIncr4ReturnSumHsimd(double * m, - SimdDouble v0, - SimdDouble v1) +static inline double gmx_simdcall reduceIncr4ReturnSumHsimd(double* m, SimdDouble v0, SimdDouble v1) { // The 4 here corresponds to the 4 elements in memory, not any SIMD width double sum[4] = { 0.0, 0.0, 0.0, 0.0 }; - for (std::size_t i = 0; i < v0.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < v0.simdInternal_.size() / 2; i++) { sum[0] += v0.simdInternal_[i]; - sum[1] += v0.simdInternal_[v0.simdInternal_.size()/2 + i]; + sum[1] += v0.simdInternal_[v0.simdInternal_.size() / 2 + i]; sum[2] += v1.simdInternal_[i]; - sum[3] += v1.simdInternal_[v1.simdInternal_.size()/2 + i]; + sum[3] += v1.simdInternal_[v1.simdInternal_.size() / 2 + i]; } // Make sure the memory pointer is aligned to the smaller of 4 elements and double SIMD width - assert(std::size_t(m) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4)*sizeof(double)) == 0); + assert(std::size_t(m) % (std::min(GMX_SIMD_DOUBLE_WIDTH, 4) * sizeof(double)) == 0); m[0] += sum[0]; m[1] += sum[1]; @@ -905,7 +863,7 @@ reduceIncr4ReturnSumHsimd(double * m, return sum[0] + sum[1] + sum[2] + sum[3]; } -#if GMX_SIMD_DOUBLE_WIDTH > 8 || defined DOXYGEN +#if GMX_SIMD_DOUBLE_WIDTH > 8 || defined DOXYGEN /*! \brief Load N doubles and duplicate them 4 times each. * * \param m Pointer to unaligned memory @@ -917,16 +875,15 @@ reduceIncr4ReturnSumHsimd(double * m, * contigous and different values are 4 positions in SIMD * apart. */ -static inline SimdDouble gmx_simdcall -loadUNDuplicate4(const double* m) +static inline SimdDouble gmx_simdcall loadUNDuplicate4(const double* m) { - SimdDouble a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdDouble a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[i]; - a.simdInternal_[i*4+1] = m[i]; - a.simdInternal_[i*4+2] = m[i]; - a.simdInternal_[i*4+3] = m[i]; + a.simdInternal_[i * 4] = m[i]; + a.simdInternal_[i * 4 + 1] = m[i]; + a.simdInternal_[i * 4 + 2] = m[i]; + a.simdInternal_[i * 4 + 3] = m[i]; } return a; } @@ -942,16 +899,15 @@ loadUNDuplicate4(const double* m) * contigous and same values are 4 positions in SIMD * apart. */ -static inline SimdDouble gmx_simdcall -load4DuplicateN(const double* m) +static inline SimdDouble gmx_simdcall load4DuplicateN(const double* m) { - SimdDouble a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdDouble a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[0]; - a.simdInternal_[i*4+1] = m[1]; - a.simdInternal_[i*4+2] = m[2]; - a.simdInternal_[i*4+3] = m[3]; + a.simdInternal_[i * 4] = m[0]; + a.simdInternal_[i * 4 + 1] = m[1]; + a.simdInternal_[i * 4 + 2] = m[2]; + a.simdInternal_[i * 4 + 3] = m[3]; } return a; } @@ -969,16 +925,15 @@ load4DuplicateN(const double* m) * Blocks of 4 doubles are loaded from m+n*offset where n * is the n-th block of 4 doubles. */ -static inline SimdDouble gmx_simdcall -loadU4NOffset(const double* m, int offset) +static inline SimdDouble gmx_simdcall loadU4NOffset(const double* m, int offset) { - SimdDouble a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdDouble a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[offset*i + 0]; - a.simdInternal_[i*4+1] = m[offset*i + 1]; - a.simdInternal_[i*4+2] = m[offset*i + 2]; - a.simdInternal_[i*4+3] = m[offset*i + 3]; + a.simdInternal_[i * 4] = m[offset * i + 0]; + a.simdInternal_[i * 4 + 1] = m[offset * i + 1]; + a.simdInternal_[i * 4 + 2] = m[offset * i + 2]; + a.simdInternal_[i * 4 + 3] = m[offset * i + 3]; } return a; } @@ -990,6 +945,6 @@ loadU4NOffset(const double* m, int offset) /*! \} */ /*! \endcond */ -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_REFERENCE_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_reference/impl_reference_util_float.h b/src/gromacs/simd/impl_reference/impl_reference_util_float.h index 51e1a725ef..54f66b2af0 100644 --- a/src/gromacs/simd/impl_reference/impl_reference_util_float.h +++ b/src/gromacs/simd/impl_reference/impl_reference_util_float.h @@ -105,19 +105,18 @@ namespace gmx * \note You should NOT scale offsets before calling this routine; it is * done internally by using the alignment template parameter instead. */ -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); // Base pointer must be aligned to the smaller of 4 elements and float SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4)*sizeof(float)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4) * sizeof(float)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_FLOAT_WIDTH, 4) == 0); @@ -156,17 +155,14 @@ gatherLoadTranspose(const float * base, * \note You should NOT scale offsets before calling this routine; it is * done internally by using the alignment template parameter instead. */ -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); // Base pointer must be aligned to the smaller of 2 elements and float SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2)*sizeof(float)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2) * sizeof(float)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_FLOAT_WIDTH, 2) == 0); @@ -235,16 +231,15 @@ static const int c_simdBestPairAlignmentFloat = 2; * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0->simdInternal_.size(); i++) { @@ -289,16 +284,12 @@ gatherLoadUTranspose(const float * base, * load the data from memory. On the architectures we have tested this * is faster even when a SIMD integer datatype is present. */ -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { @@ -349,20 +340,16 @@ transposeScatterStoreU(float * base, * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { - base[align * offset[i]] += v0.simdInternal_[i]; + base[align * offset[i]] += v0.simdInternal_[i]; base[align * offset[i] + 1] += v1.simdInternal_[i]; base[align * offset[i] + 2] += v2.simdInternal_[i]; } @@ -409,20 +396,16 @@ transposeScatterIncrU(float * base, * starting at the last offset. If you use the Gromacs aligned memory * allocation routines this will always be the case. */ -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { // Offset list must be aligned for SIMD FINT32 - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH * sizeof(std::int32_t)) == 0); for (std::size_t i = 0; i < v0.simdInternal_.size(); i++) { - base[align * offset[i]] -= v0.simdInternal_[i]; + base[align * offset[i]] -= v0.simdInternal_[i]; base[align * offset[i] + 1] -= v1.simdInternal_[i]; base[align * offset[i] + 2] -= v2.simdInternal_[i]; } @@ -449,11 +432,10 @@ transposeScatterDecrU(float * base, * first, second and third pair of SIMD variables, and store the three * results back into a suitable vector-format array. */ -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { for (std::size_t i = 0; i < scalar.simdInternal_.size(); i++) { @@ -489,17 +471,16 @@ expandScalarsToTriplets(SimdFloat scalar, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 offset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { // Base pointer must be aligned to the smaller of 4 elements and float SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4)*sizeof(float)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4) * sizeof(float)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_FLOAT_WIDTH, 4) == 0); @@ -537,12 +518,9 @@ gatherLoadBySimdIntTranspose(const float * base, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { for (std::size_t i = 0; i < v0->simdInternal_.size(); i++) { @@ -575,15 +553,12 @@ gatherLoadUBySimdIntTranspose(const float * base, * a SIMD offset index, since the result of the real-to-integer conversion * is present in a SIMD register just before calling this routine. */ -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { // Base pointer must be aligned to the smaller of 2 elements and float SIMD width - assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2)*sizeof(float)) == 0); + assert(std::size_t(base) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2) * sizeof(float)) == 0); // align parameter must also be a multiple of the above alignment requirement assert(align % std::min(GMX_SIMD_FLOAT_WIDTH, 2) == 0); @@ -620,17 +595,12 @@ gatherLoadBySimdIntTranspose(const float * base, * do not need these, this extra code will be optimized away completely if you * just ignore the return value (Checked with gcc-4.9.1 and clang-3.6 for AVX). */ -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { float sum[4]; // Note that the 4 here corresponds to the 4 m-elements, not any SIMD width // Make sure the memory pointer is aligned to the smaller of 4 elements and float SIMD width - assert(std::size_t(m) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4)*sizeof(float)) == 0); + assert(std::size_t(m) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4) * sizeof(float)) == 0); sum[0] = reduce(v0); sum[1] = reduce(v1); @@ -696,20 +666,18 @@ reduceIncr4ReturnSum(float * m, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline SimdFloat gmx_simdcall -loadDualHsimd(const float * m0, - const float * m1) +static inline SimdFloat gmx_simdcall loadDualHsimd(const float* m0, const float* m1) { - SimdFloat a; + SimdFloat a; // Make sure the memory pointers are aligned to half float SIMD width - assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m0[i]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = m1[i]; + a.simdInternal_[i] = m0[i]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = m1[i]; } return a; } @@ -722,18 +690,17 @@ loadDualHsimd(const float * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline SimdFloat gmx_simdcall -loadDuplicateHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m) { - SimdFloat a; + SimdFloat a; // Make sure the memory pointer is aligned - assert(std::size_t(m) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); + assert(std::size_t(m) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m[i]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = a.simdInternal_[i]; + a.simdInternal_[i] = m[i]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = a.simdInternal_[i]; } return a; } @@ -751,15 +718,14 @@ loadDuplicateHsimd(const float * m) * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline SimdFloat gmx_simdcall -loadU1DualHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m) { - SimdFloat a; + SimdFloat a; - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - a.simdInternal_[i] = m[0]; - a.simdInternal_[a.simdInternal_.size()/2 + i] = m[1]; + a.simdInternal_[i] = m[0]; + a.simdInternal_[a.simdInternal_.size() / 2 + i] = m[1]; } return a; } @@ -773,19 +739,16 @@ loadU1DualHsimd(const float * m) * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline void gmx_simdcall -storeDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall storeDualHsimd(float* m0, float* m1, SimdFloat a) { // Make sure the memory pointers are aligned to half float SIMD width - assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { m0[i] = a.simdInternal_[i]; - m1[i] = a.simdInternal_[a.simdInternal_.size()/2 + i]; + m1[i] = a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -802,22 +765,19 @@ storeDualHsimd(float * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline void gmx_simdcall -incrDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall incrDualHsimd(float* m0, float* m1, SimdFloat a) { // Make sure the memory pointer is aligned to half float SIMD width - assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); - assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); + assert(std::size_t(m0) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); + assert(std::size_t(m1) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { m0[i] += a.simdInternal_[i]; } - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - m1[i] += a.simdInternal_[a.simdInternal_.size()/2 + i]; + m1[i] += a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -834,16 +794,14 @@ incrDualHsimd(float * m0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline void gmx_simdcall -decrHsimd(float * m, - SimdFloat a) +static inline void gmx_simdcall decrHsimd(float* m, SimdFloat a) { // Make sure the memory pointer is aligned to half float SIMD width - assert(std::size_t(m) % (GMX_SIMD_FLOAT_WIDTH/2*sizeof(float)) == 0); + assert(std::size_t(m) % (GMX_SIMD_FLOAT_WIDTH / 2 * sizeof(float)) == 0); - for (std::size_t i = 0; i < a.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < a.simdInternal_.size() / 2; i++) { - m[i] -= a.simdInternal_[i] + a.simdInternal_[a.simdInternal_.size()/2 + i]; + m[i] -= a.simdInternal_[i] + a.simdInternal_[a.simdInternal_.size() / 2 + i]; } } @@ -881,28 +839,27 @@ decrHsimd(float * m, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const float * base0, - const float * base1, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const float* base0, + const float* base1, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1) { // Offset list must be aligned for half SIMD FINT32 width - assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH/2*sizeof(std::int32_t)) == 0); + assert(std::size_t(offset) % (GMX_SIMD_FINT32_WIDTH / 2 * sizeof(std::int32_t)) == 0); // base pointers must be aligned to the smaller of 2 elements and float SIMD width - assert(std::size_t(base0) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2)*sizeof(float)) == 0); - assert(std::size_t(base1) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2)*sizeof(float)) == 0); + assert(std::size_t(base0) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2) * sizeof(float)) == 0); + assert(std::size_t(base1) % (std::min(GMX_SIMD_FLOAT_WIDTH, 2) * sizeof(float)) == 0); // alignment parameter must be also be multiple of the above required alignment assert(align % std::min(GMX_SIMD_FLOAT_WIDTH, 2) == 0); - for (std::size_t i = 0; i < v0->simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < v0->simdInternal_.size() / 2; i++) { - v0->simdInternal_[i] = base0[align * offset[i]]; - v1->simdInternal_[i] = base0[align * offset[i] + 1]; - v0->simdInternal_[v0->simdInternal_.size()/2 + i] = base1[align * offset[i]]; - v1->simdInternal_[v1->simdInternal_.size()/2 + i] = base1[align * offset[i] + 1]; + v0->simdInternal_[i] = base0[align * offset[i]]; + v1->simdInternal_[i] = base0[align * offset[i] + 1]; + v0->simdInternal_[v0->simdInternal_.size() / 2 + i] = base1[align * offset[i]]; + v1->simdInternal_[v1->simdInternal_.size() / 2 + i] = base1[align * offset[i] + 1]; } } @@ -925,24 +882,21 @@ gatherLoadTransposeHsimd(const float * base0, * * Available if \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT is 1. */ -static inline float gmx_simdcall -reduceIncr4ReturnSumHsimd(float * m, - SimdFloat v0, - SimdFloat v1) +static inline float gmx_simdcall reduceIncr4ReturnSumHsimd(float* m, SimdFloat v0, SimdFloat v1) { // The 4 here corresponds to the 4 elements in memory, not any SIMD width float sum[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - for (std::size_t i = 0; i < v0.simdInternal_.size()/2; i++) + for (std::size_t i = 0; i < v0.simdInternal_.size() / 2; i++) { sum[0] += v0.simdInternal_[i]; - sum[1] += v0.simdInternal_[v0.simdInternal_.size()/2 + i]; + sum[1] += v0.simdInternal_[v0.simdInternal_.size() / 2 + i]; sum[2] += v1.simdInternal_[i]; - sum[3] += v1.simdInternal_[v1.simdInternal_.size()/2 + i]; + sum[3] += v1.simdInternal_[v1.simdInternal_.size() / 2 + i]; } // Make sure the memory pointer is aligned to the smaller of 4 elements and float SIMD width - assert(std::size_t(m) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4)*sizeof(float)) == 0); + assert(std::size_t(m) % (std::min(GMX_SIMD_FLOAT_WIDTH, 4) * sizeof(float)) == 0); m[0] += sum[0]; m[1] += sum[1]; @@ -964,16 +918,15 @@ reduceIncr4ReturnSumHsimd(float * m, * contigous and different values are 4 positions in SIMD * apart. */ -static inline SimdFloat gmx_simdcall -loadUNDuplicate4(const float* m) +static inline SimdFloat gmx_simdcall loadUNDuplicate4(const float* m) { - SimdFloat a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdFloat a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[i]; - a.simdInternal_[i*4+1] = m[i]; - a.simdInternal_[i*4+2] = m[i]; - a.simdInternal_[i*4+3] = m[i]; + a.simdInternal_[i * 4] = m[i]; + a.simdInternal_[i * 4 + 1] = m[i]; + a.simdInternal_[i * 4 + 2] = m[i]; + a.simdInternal_[i * 4 + 3] = m[i]; } return a; } @@ -989,16 +942,15 @@ loadUNDuplicate4(const float* m) * contigous and same values are 4 positions in SIMD * apart. */ -static inline SimdFloat gmx_simdcall -load4DuplicateN(const float* m) +static inline SimdFloat gmx_simdcall load4DuplicateN(const float* m) { - SimdFloat a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdFloat a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[0]; - a.simdInternal_[i*4+1] = m[1]; - a.simdInternal_[i*4+2] = m[2]; - a.simdInternal_[i*4+3] = m[3]; + a.simdInternal_[i * 4] = m[0]; + a.simdInternal_[i * 4 + 1] = m[1]; + a.simdInternal_[i * 4 + 2] = m[2]; + a.simdInternal_[i * 4 + 3] = m[3]; } return a; } @@ -1016,16 +968,15 @@ load4DuplicateN(const float* m) * Blocks of 4 floats are loaded from m+n*offset where n * is the n-th block of 4 floats. */ -static inline SimdFloat gmx_simdcall -loadU4NOffset(const float* m, int offset) +static inline SimdFloat gmx_simdcall loadU4NOffset(const float* m, int offset) { - SimdFloat a; - for (std::size_t i = 0; i < a.simdInternal_.size()/4; i++) + SimdFloat a; + for (std::size_t i = 0; i < a.simdInternal_.size() / 4; i++) { - a.simdInternal_[i*4] = m[offset*i + 0]; - a.simdInternal_[i*4+1] = m[offset*i + 1]; - a.simdInternal_[i*4+2] = m[offset*i + 2]; - a.simdInternal_[i*4+3] = m[offset*i + 3]; + a.simdInternal_[i * 4] = m[offset * i + 0]; + a.simdInternal_[i * 4 + 1] = m[offset * i + 1]; + a.simdInternal_[i * 4 + 2] = m[offset * i + 2]; + a.simdInternal_[i * 4 + 3] = m[offset * i + 3]; } return a; } @@ -1036,6 +987,6 @@ loadU4NOffset(const float* m, int offset) /*! \} */ /*! \endcond */ -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_REFERENCE_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h index 482886033d..2762635542 100644 --- a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h +++ b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_common.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,29 +41,29 @@ * a single-precision interface where we only offer single-precision accuracy * in math functions - this can save quite a few cycles. */ -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 0 -#define GMX_SIMD_HAVE_STOREU 0 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 -#define GMX_SIMD4_HAVE_FLOAT 0 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 0 +#define GMX_SIMD_HAVE_STOREU 0 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 0 +#define GMX_SIMD4_HAVE_FLOAT 0 +#define GMX_SIMD4_HAVE_DOUBLE 0 /* Implementation details */ -#define GMX_SIMD_FLOAT_WIDTH 2 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 2 -#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD_FLOAT_WIDTH 2 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 2 +#define GMX_SIMD_DINT32_WIDTH 2 /* No SIMD4 support in either single or double */ -#define GMX_SIMD_RSQRT_BITS 10 -#define GMX_SIMD_RCP_BITS 9 +#define GMX_SIMD_RSQRT_BITS 10 +#define GMX_SIMD_RCP_BITS 9 #endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_COMMON_H */ diff --git a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_double.h b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_double.h index 9b1c964b44..e811489516 100644 --- a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_double.h +++ b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,163 +64,150 @@ /**************************************************** * DOUBLE PRECISION SIMD IMPLEMENTATION * ****************************************************/ -#define SimdDouble _fjsp_v2r8 -#define simdLoadD _fjsp_load_v2r8 -#define simdLoad1D(m) _fjsp_set_v2r8((*m), (*m)) -#define simdSet1D(a) _fjsp_set_v2r8(a, a) -#define simdStoreD _fjsp_store_v2r8 -#define simdLoadUD simdLoadD +#define SimdDouble _fjsp_v2r8 +#define simdLoadD _fjsp_load_v2r8 +#define simdLoad1D(m) _fjsp_set_v2r8((*m), (*m)) +#define simdSet1D(a) _fjsp_set_v2r8(a, a) +#define simdStoreD _fjsp_store_v2r8 +#define simdLoadUD simdLoadD /* No unaligned store of SimdDouble */ -#define simdSetZeroD _fjsp_setzero_v2r8 -#define simdAddD _fjsp_add_v2r8 -#define simdSubD _fjsp_sub_v2r8 -#define simdMulD _fjsp_mul_v2r8 -#define simdFmaddD(a, b, c) _fjsp_madd_v2r8(a, b, c) -#define simdFmsubD(a, b, c) _fjsp_msub_v2r8(a, b, c) -#define simdFnmaddD(a, b, c) _fjsp_nmsub_v2r8(a, b, c) -#define simdFnmsubD(a, b, c) _fjsp_nmadd_v2r8(a, b, c) -#define simdAndD _fjsp_and_v2r8 -#define simdAndNotD _fjsp_andnot1_v2r8 -#define simdOrD _fjsp_or_v2r8 -#define simdXorD _fjsp_xor_v2r8 -#define simdRsqrtD(x) _fjsp_rsqrta_v2r8(x) -#define simdRcpD(x) _fjsp_rcpa_v2r8(x) -#define simdAbsD(x) _fjsp_abs_v2r8(x) -#define simdNegD(x) _fjsp_neg_v2r8(x) -#define simdMaxD _fjsp_max_v2r8 -#define simdMinD _fjsp_min_v2r8 -#define simdRoundD(x) simdCvtI2D(simdCvtD2I(x)) -#define simdTruncD(x) simdCvtI2D(simdCvttD2I(x)) -#define simdFractionD(x) simdSubD(x, simdTruncD(x)) -#define simdGetExponentD simdGetExponentD_sparc64_hpc_ace -#define simdGetMantissaD simdGetMantissaD_sparc64_hpc_ace -#define simdSetExponentD simdSetExponentD_sparc64_hpc_ace +#define simdSetZeroD _fjsp_setzero_v2r8 +#define simdAddD _fjsp_add_v2r8 +#define simdSubD _fjsp_sub_v2r8 +#define simdMulD _fjsp_mul_v2r8 +#define simdFmaddD(a, b, c) _fjsp_madd_v2r8(a, b, c) +#define simdFmsubD(a, b, c) _fjsp_msub_v2r8(a, b, c) +#define simdFnmaddD(a, b, c) _fjsp_nmsub_v2r8(a, b, c) +#define simdFnmsubD(a, b, c) _fjsp_nmadd_v2r8(a, b, c) +#define simdAndD _fjsp_and_v2r8 +#define simdAndNotD _fjsp_andnot1_v2r8 +#define simdOrD _fjsp_or_v2r8 +#define simdXorD _fjsp_xor_v2r8 +#define simdRsqrtD(x) _fjsp_rsqrta_v2r8(x) +#define simdRcpD(x) _fjsp_rcpa_v2r8(x) +#define simdAbsD(x) _fjsp_abs_v2r8(x) +#define simdNegD(x) _fjsp_neg_v2r8(x) +#define simdMaxD _fjsp_max_v2r8 +#define simdMinD _fjsp_min_v2r8 +#define simdRoundD(x) simdCvtI2D(simdCvtD2I(x)) +#define simdTruncD(x) simdCvtI2D(simdCvttD2I(x)) +#define simdFractionD(x) simdSubD(x, simdTruncD(x)) +#define simdGetExponentD simdGetExponentD_sparc64_hpc_ace +#define simdGetMantissaD simdGetMantissaD_sparc64_hpc_ace +#define simdSetExponentD simdSetExponentD_sparc64_hpc_ace /* integer datatype corresponding to double: SimdDInt32 */ -#define SimdDInt32 _fjsp_v2r8 -#define simdLoadDI(m) simdLoadDI_sparc64_hpc_ace(m) -#define simdSet1DI(i) simdSet1DI_sparc64_hpc_ace(i) -#define simdStoreDI(m, x) simdStoreDI_sparc64_hpc_ace(m, x) -#define simdLoadUDI simdLoadDI +#define SimdDInt32 _fjsp_v2r8 +#define simdLoadDI(m) simdLoadDI_sparc64_hpc_ace(m) +#define simdSet1DI(i) simdSet1DI_sparc64_hpc_ace(i) +#define simdStoreDI(m, x) simdStoreDI_sparc64_hpc_ace(m, x) +#define simdLoadUDI simdLoadDI /* No unaligned store of SimdDInt32 */ -#define simdSetZeroDI _fjsp_setzero_v2r8 -#define simdCvtD2I simdCvtD2I_sparc64_hpc_ace -#define simdCvttD2I _fjsp_dtox_v2r8 -#define simdCvtI2D _fjsp_xtod_v2r8 -#define simdExtractDI simdExtractDI_sparc64_hpc_ace +#define simdSetZeroDI _fjsp_setzero_v2r8 +#define simdCvtD2I simdCvtD2I_sparc64_hpc_ace +#define simdCvttD2I _fjsp_dtox_v2r8 +#define simdCvtI2D _fjsp_xtod_v2r8 +#define simdExtractDI simdExtractDI_sparc64_hpc_ace /* Integer logical ops on SimdDInt32 */ -#define simdSlliDI simdSlliDI_sparc64_hpc_ace -#define simdSrliDI simdSrliDI_sparc64_hpc_ace -#define simdAndDI _fjsp_and_v2r8 -#define simdAndNotDI _fjsp_andnot1_v2r8 -#define simdOrDI _fjsp_or_v2r8 -#define simdXorDI _fjsp_xor_v2r8 +#define simdSlliDI simdSlliDI_sparc64_hpc_ace +#define simdSrliDI simdSrliDI_sparc64_hpc_ace +#define simdAndDI _fjsp_and_v2r8 +#define simdAndNotDI _fjsp_andnot1_v2r8 +#define simdOrDI _fjsp_or_v2r8 +#define simdXorDI _fjsp_xor_v2r8 /* Integer arithmetic ops on integer datatype corresponding to double */ /* Boolean & comparison operations on SimdDouble */ -#define SimdDBool _fjsp_v2r8 -#define simdCmpEqD _fjsp_cmpeq_v2r8 -#define simdCmpLtD _fjsp_cmplt_v2r8 -#define simdCmpLeD _fjsp_cmple_v2r8 -#define simdAndDB _fjsp_and_v2r8 -#define simdOrDB _fjsp_or_v2r8 -#define simdAnyTrueDB gmx_simd_anytrue_d_sparc64_hpc_ace -#define simdMaskD _fjsp_and_v2r8 -#define simdMaskNotD(a, sel) _fjsp_andnot1_v2r8(sel, a) +#define SimdDBool _fjsp_v2r8 +#define simdCmpEqD _fjsp_cmpeq_v2r8 +#define simdCmpLtD _fjsp_cmplt_v2r8 +#define simdCmpLeD _fjsp_cmple_v2r8 +#define simdAndDB _fjsp_and_v2r8 +#define simdOrDB _fjsp_or_v2r8 +#define simdAnyTrueDB gmx_simd_anytrue_d_sparc64_hpc_ace +#define simdMaskD _fjsp_and_v2r8 +#define simdMaskNotD(a, sel) _fjsp_andnot1_v2r8(sel, a) #define simdBlendD(a, b, sel) _fjsp_selmov_v2r8(b, a, sel) -#define simdReduceD(a) simdReduceD_sparc64_hpc_ace(a) +#define simdReduceD(a) simdReduceD_sparc64_hpc_ace(a) /* No boolean & comparison operations on SimdDInt32 */ /* Float/double conversion */ -#define simdCvtF2D(f) (f) -#define simdCvtD2F(d) (d) +#define simdCvtF2D(f) (f) +#define simdCvtD2F(d) (d) /**************************************************** * DOUBLE PRECISION IMPLEMENTATION HELPER FUNCTIONS * ****************************************************/ -static inline SimdDInt32 -simdLoadDI_sparc64_hpc_ace(const int *m) +static inline SimdDInt32 simdLoadDI_sparc64_hpc_ace(const int* m) { - union - { - _fjsp_v2r8 simd; - long long int i[2]; - } - conv; + union { + _fjsp_v2r8 simd; + long long int i[2]; + } conv; conv.i[0] = m[0]; conv.i[1] = m[1]; - return _fjsp_load_v2r8( (double *) &(conv.simd) ); + return _fjsp_load_v2r8((double*)&(conv.simd)); } -static inline void -simdStoreDI_sparc64_hpc_ace(int *m, SimdDInt32 x) +static inline void simdStoreDI_sparc64_hpc_ace(int* m, SimdDInt32 x) { - union - { - _fjsp_v2r8 simd; - long long int i[2]; - } - conv; + union { + _fjsp_v2r8 simd; + long long int i[2]; + } conv; - _fjsp_store_v2r8( (double *) &(conv.simd), x ); + _fjsp_store_v2r8((double*)&(conv.simd), x); m[0] = conv.i[0]; m[1] = conv.i[1]; } -static inline SimdDInt32 -simdSet1DI_sparc64_hpc_ace(int i) +static inline SimdDInt32 simdSet1DI_sparc64_hpc_ace(int i) { - union - { - _fjsp_v2r8 simd; - long long int i[2]; - } - conv; + union { + _fjsp_v2r8 simd; + long long int i[2]; + } conv; conv.i[0] = i; conv.i[1] = i; - return _fjsp_load_v2r8( (double *) &(conv.simd) ); + return _fjsp_load_v2r8((double*)&(conv.simd)); } -static inline int -simdExtractDI_sparc64_hpc_ace(SimdDInt32 x, int i) +static inline int simdExtractDI_sparc64_hpc_ace(SimdDInt32 x, int i) { long long int res; /* This conditional should be optimized away at compile time */ if (i == 0) { - _fjsp_storel_v2r8((double *)&res, x); + _fjsp_storel_v2r8((double*)&res, x); } else { - _fjsp_storeh_v2r8((double *)&res, x); + _fjsp_storeh_v2r8((double*)&res, x); } return (int)res; } -static inline SimdDInt32 -simdSlliDI_sparc64_hpc_ace(SimdDInt32 x, int i) +static inline SimdDInt32 simdSlliDI_sparc64_hpc_ace(SimdDInt32 x, int i) { - _fjsp_v2i8 ix = *((_fjsp_v2i8 *)&x); - ix = _fjsp_slli_v2i8(ix, i); - x = *((_fjsp_v2r8 *)&ix); + _fjsp_v2i8 ix = *((_fjsp_v2i8*)&x); + ix = _fjsp_slli_v2i8(ix, i); + x = *((_fjsp_v2r8*)&ix); return x; } -static inline SimdDInt32 -simdSrliDI_sparc64_hpc_ace(SimdDInt32 x, int i) +static inline SimdDInt32 simdSrliDI_sparc64_hpc_ace(SimdDInt32 x, int i) { - _fjsp_v2i8 ix = *((_fjsp_v2i8 *)&x); - ix = _fjsp_srli_v2i8(ix, i); - x = *((_fjsp_v2r8 *)&ix); + _fjsp_v2i8 ix = *((_fjsp_v2i8*)&x); + ix = _fjsp_srli_v2i8(ix, i); + x = *((_fjsp_v2r8*)&ix); return x; } -static inline SimdDInt32 -simdCvtD2I_sparc64_hpc_ace(SimdDouble x) +static inline SimdDInt32 simdCvtD2I_sparc64_hpc_ace(SimdDouble x) { _fjsp_v2r8 signbit = _fjsp_set_v2r8(-0.0, -0.0); _fjsp_v2r8 half = _fjsp_set_v2r8(0.5, 0.5); @@ -229,17 +216,15 @@ simdCvtD2I_sparc64_hpc_ace(SimdDouble x) return _fjsp_dtox_v2r8(x); } -static inline int -gmx_simd_anytrue_d_sparc64_hpc_ace(SimdDBool x) +static inline int gmx_simd_anytrue_d_sparc64_hpc_ace(SimdDBool x) { long long int i; x = _fjsp_or_v2r8(x, _fjsp_unpackhi_v2r8(x, x)); - _fjsp_storel_v2r8((double *)&i, x); + _fjsp_storel_v2r8((double*)&i, x); return (i != 0LL); } -static inline double -simdReduceD_sparc64_hpc_ace(SimdDouble x) +static inline double simdReduceD_sparc64_hpc_ace(SimdDouble x) { double d; x = _fjsp_add_v2r8(x, _fjsp_unpackhi_v2r8(x, x)); @@ -248,58 +233,51 @@ simdReduceD_sparc64_hpc_ace(SimdDouble x) } -static inline SimdDouble -simdGetExponentD_sparc64_hpc_ace(SimdDouble x) +static inline SimdDouble simdGetExponentD_sparc64_hpc_ace(SimdDouble x) { /* HPC-ACE cannot cast _fjsp_v2r8 to _fjsp_v4i4, so to perform shifts we * would need to store and reload. Since we are only operating on two * numbers it is likely more efficient to do the operations directly on * normal registers. */ - const std::int64_t expmask = 0x7ff0000000000000LL; - const std::int64_t expbias = 1023LL; + const std::int64_t expmask = 0x7ff0000000000000LL; + const std::int64_t expbias = 1023LL; - union - { - _fjsp_v2r8 simd; - long long int i[2]; - } - conv; + union { + _fjsp_v2r8 simd; + long long int i[2]; + } conv; - _fjsp_store_v2r8( (double *) &conv.simd, x); + _fjsp_store_v2r8((double*)&conv.simd, x); conv.i[0] = ((conv.i[0] & expmask) >> 52) - expbias; conv.i[1] = ((conv.i[1] & expmask) >> 52) - expbias; - x = _fjsp_load_v2r8( (double *) &conv.simd); + x = _fjsp_load_v2r8((double*)&conv.simd); return _fjsp_xtod_v2r8(x); } -static inline SimdDouble -simdGetMantissaD_sparc64_hpc_ace(SimdDouble x) +static inline SimdDouble simdGetMantissaD_sparc64_hpc_ace(SimdDouble x) { - std::int64_t mantmask[2] = {0x000fffffffffffffLL, 0x000fffffffffffffLL}; - SimdDouble one = _fjsp_set_v2r8(1.0, 1.0); + std::int64_t mantmask[2] = { 0x000fffffffffffffLL, 0x000fffffffffffffLL }; + SimdDouble one = _fjsp_set_v2r8(1.0, 1.0); - x = _fjsp_and_v2r8(x, _fjsp_load_v2r8((double *)mantmask)); + x = _fjsp_and_v2r8(x, _fjsp_load_v2r8((double*)mantmask)); return _fjsp_or_v2r8(x, one); } -static inline SimdDouble -simdSetExponentD_sparc64_hpc_ace(SimdDouble x) +static inline SimdDouble simdSetExponentD_sparc64_hpc_ace(SimdDouble x) { - const std::int64_t expbias = 1023; - union - { - _fjsp_v2r8 simd; - long long int i[2]; - } - conv; + const std::int64_t expbias = 1023; + union { + _fjsp_v2r8 simd; + long long int i[2]; + } conv; - _fjsp_store_v2r8( (double *) &conv.simd, simdCvtD2I_sparc64_hpc_ace(x)); + _fjsp_store_v2r8((double*)&conv.simd, simdCvtD2I_sparc64_hpc_ace(x)); conv.i[0] = (conv.i[0] + expbias) << 52; conv.i[1] = (conv.i[1] + expbias) << 52; - return _fjsp_load_v2r8( (double *) &conv.simd); + return _fjsp_load_v2r8((double*)&conv.simd); } #endif /* GMX_SIMD_IMPL_SPARC64_HPC_ACE_SIMD_DOUBLE_H */ diff --git a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_float.h b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_float.h index 551df2184b..54749ea992 100644 --- a/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_float.h +++ b/src/gromacs/simd/impl_sparc64_hpc_ace/impl_sparc64_hpc_ace_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -77,97 +77,95 @@ /**************************************************** * SINGLE PRECISION SIMD IMPLEMENTATION * ****************************************************/ -#define SimdFloat _fjsp_v2r8 -#define simdLoadF simdLoadF_sparc64_hpc_ace -#define simdLoad1F(m) _fjsp_set_v2r8((*m), (*m)) -#define simdSet1F(a) _fjsp_set_v2r8(a, a) -#define simdStoreF simdStoreF_sparc64_hpc_ace -#define simdLoadUF simdLoadF +#define SimdFloat _fjsp_v2r8 +#define simdLoadF simdLoadF_sparc64_hpc_ace +#define simdLoad1F(m) _fjsp_set_v2r8((*m), (*m)) +#define simdSet1F(a) _fjsp_set_v2r8(a, a) +#define simdStoreF simdStoreF_sparc64_hpc_ace +#define simdLoadUF simdLoadF /* No unaligned store of SimdFloat */ -#define simdSetZeroF _fjsp_setzero_v2r8 -#define simdAddF _fjsp_add_v2r8 -#define simdSubF _fjsp_sub_v2r8 -#define simdMulF _fjsp_mul_v2r8 -#define simdFmaddF(a, b, c) _fjsp_madd_v2r8(a, b, c) -#define simdFmsubF(a, b, c) _fjsp_msub_v2r8(a, b, c) -#define simdFnmaddF(a, b, c) _fjsp_nmsub_v2r8(a, b, c) -#define simdFnmsubF(a, b, c) _fjsp_nmadd_v2r8(a, b, c) -#define simdAndF _fjsp_and_v2r8 -#define simdAndNotF _fjsp_andnot1_v2r8 -#define simdOrF _fjsp_or_v2r8 -#define simdXorF _fjsp_xor_v2r8 -#define simdRsqrtF _fjsp_rsqrta_v2r8 -#define simdRcpF _fjsp_rcpa_v2r8 -#define simdAbsF(x) _fjsp_abs_v2r8(x) -#define simdNegF(x) _fjsp_neg_v2r8(x) -#define simdMaxF _fjsp_max_v2r8 -#define simdMinF _fjsp_min_v2r8 -#define simdRoundF(x) simdRoundD(x) -#define simdTruncF(x) simdTruncD(x) -#define simdFractionF(x) simdSubF(x, simdTruncF(x)) -#define simdGetExponentF simdGetExponentD_sparc64_hpc_ace -#define simdGetMantissaF simdGetMantissaD_sparc64_hpc_ace -#define simdSetExponentF simdSetExponentD_sparc64_hpc_ace +#define simdSetZeroF _fjsp_setzero_v2r8 +#define simdAddF _fjsp_add_v2r8 +#define simdSubF _fjsp_sub_v2r8 +#define simdMulF _fjsp_mul_v2r8 +#define simdFmaddF(a, b, c) _fjsp_madd_v2r8(a, b, c) +#define simdFmsubF(a, b, c) _fjsp_msub_v2r8(a, b, c) +#define simdFnmaddF(a, b, c) _fjsp_nmsub_v2r8(a, b, c) +#define simdFnmsubF(a, b, c) _fjsp_nmadd_v2r8(a, b, c) +#define simdAndF _fjsp_and_v2r8 +#define simdAndNotF _fjsp_andnot1_v2r8 +#define simdOrF _fjsp_or_v2r8 +#define simdXorF _fjsp_xor_v2r8 +#define simdRsqrtF _fjsp_rsqrta_v2r8 +#define simdRcpF _fjsp_rcpa_v2r8 +#define simdAbsF(x) _fjsp_abs_v2r8(x) +#define simdNegF(x) _fjsp_neg_v2r8(x) +#define simdMaxF _fjsp_max_v2r8 +#define simdMinF _fjsp_min_v2r8 +#define simdRoundF(x) simdRoundD(x) +#define simdTruncF(x) simdTruncD(x) +#define simdFractionF(x) simdSubF(x, simdTruncF(x)) +#define simdGetExponentF simdGetExponentD_sparc64_hpc_ace +#define simdGetMantissaF simdGetMantissaD_sparc64_hpc_ace +#define simdSetExponentF simdSetExponentD_sparc64_hpc_ace /* integer datatype corresponding to float: SimdFInt32 */ -#define SimdFInt32 _fjsp_v2r8 -#define simdLoadFI(m) simdLoadDI_sparc64_hpc_ace(m) -#define simdSet1FI(i) simdSet1DI_sparc64_hpc_ace(i) -#define simdStoreFI(m, x) simdStoreDI_sparc64_hpc_ace(m, x) -#define simdLoadUFI simdLoadFI +#define SimdFInt32 _fjsp_v2r8 +#define simdLoadFI(m) simdLoadDI_sparc64_hpc_ace(m) +#define simdSet1FI(i) simdSet1DI_sparc64_hpc_ace(i) +#define simdStoreFI(m, x) simdStoreDI_sparc64_hpc_ace(m, x) +#define simdLoadUFI simdLoadFI /* No unaligned store of SimdFInt32 */ -#define simdSetZeroFI _fjsp_setzero_v2r8 -#define simdCvtF2I simdCvtD2I -#define simdCvttF2I _fjsp_dtox_v2r8 -#define simdCvtI2F _fjsp_xtod_v2r8 -#define simdExtractFI simdExtractDI_sparc64_hpc_ace +#define simdSetZeroFI _fjsp_setzero_v2r8 +#define simdCvtF2I simdCvtD2I +#define simdCvttF2I _fjsp_dtox_v2r8 +#define simdCvtI2F _fjsp_xtod_v2r8 +#define simdExtractFI simdExtractDI_sparc64_hpc_ace /* Integer logical ops on SimdFInt32 */ /* Shifts are horrible since they require memory re-loads. */ -#define simdSlliFI simdSlliDI_sparc64_hpc_ace -#define simdSrliFI simdSrliDI_sparc64_hpc_ace -#define simdAndFI _fjsp_and_v2r8 -#define simdAndNotFI(a, b) _fjsp_andnot1_v2r8(a, b) -#define simdOrFI _fjsp_or_v2r8 -#define simdXorFI _fjsp_xor_v2r8 +#define simdSlliFI simdSlliDI_sparc64_hpc_ace +#define simdSrliFI simdSrliDI_sparc64_hpc_ace +#define simdAndFI _fjsp_and_v2r8 +#define simdAndNotFI(a, b) _fjsp_andnot1_v2r8(a, b) +#define simdOrFI _fjsp_or_v2r8 +#define simdXorFI _fjsp_xor_v2r8 /* No integer arithmetic ops on SimdFInt32 */ /* Boolean & comparison operations on SimdFloat */ -#define SimdFBool _fjsp_v2r8 -#define simdCmpEqF _fjsp_cmpeq_v2r8 -#define simdCmpLtF _fjsp_cmplt_v2r8 -#define simdCmpLeF _fjsp_cmple_v2r8 -#define simdAndFB _fjsp_and_v2r8 -#define simdOrFB _fjsp_or_v2r8 -#define simdAnyTrueFB gmx_simd_anytrue_d_sparc64_hpc_ace -#define simdMaskF _fjsp_and_v2r8 +#define SimdFBool _fjsp_v2r8 +#define simdCmpEqF _fjsp_cmpeq_v2r8 +#define simdCmpLtF _fjsp_cmplt_v2r8 +#define simdCmpLeF _fjsp_cmple_v2r8 +#define simdAndFB _fjsp_and_v2r8 +#define simdOrFB _fjsp_or_v2r8 +#define simdAnyTrueFB gmx_simd_anytrue_d_sparc64_hpc_ace +#define simdMaskF _fjsp_and_v2r8 #define simdMaskNotF(a, sel) _fjsp_andnot1_v2r8(sel, a) #define simdBlendF(a, b, s) _fjsp_selmov_v2r8(b, a, s) -#define simdReduceF(a) simdReduceD_sparc64_hpc_ace(a) +#define simdReduceF(a) simdReduceD_sparc64_hpc_ace(a) /* No boolean & comparison operations on SimdFInt32 */ /* No conversions between different booleans */ /**************************************************** * SINGLE PRECISION IMPLEMENTATION HELPER FUNCTIONS * ****************************************************/ -static inline SimdFloat -simdLoadF_sparc64_hpc_ace(const float *m) +static inline SimdFloat simdLoadF_sparc64_hpc_ace(const float* m) { /* We are not allowed to cast single-to-double registers, but we can * masquerade the memory location as a variable of type _fjsp_v2r4. */ - const _fjsp_v2r4 *p = (const _fjsp_v2r4 *)m; + const _fjsp_v2r4* p = (const _fjsp_v2r4*)m; _fjsp_v2r4 simd; simd = *p; return _fjsp_stod_v2r8(simd); } -static inline void -simdStoreF_sparc64_hpc_ace(float *m, SimdFloat x) +static inline void simdStoreF_sparc64_hpc_ace(float* m, SimdFloat x) { /* We are not allowed to cast single-to-double registers, but we can * masquerade the memory location as a variable of type _fjsp_v2r4. */ - _fjsp_v2r4 *p = (_fjsp_v2r4 *)m; - *p = _fjsp_dtos_v2r4(x); + _fjsp_v2r4* p = (_fjsp_v2r4*)m; + *p = _fjsp_dtos_v2r4(x); } /* Note that some single precision defines refer to the double precision helpers */ diff --git a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_definitions.h b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_definitions.h index b44204bddc..85c07b44d0 100644 --- a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_definitions.h +++ b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,47 +37,47 @@ #define GMX_SIMD_IMPL_X86_AVX2_128_DEFINITIONS_H // Capability definitions for (mostly) 128-bit AVX2 -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 32 // Bytes (4*double for SIMD4) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 32 // Bytes (4*double for SIMD4) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 #endif // GMX_SIMD_IMPL_X86_AVX2_128_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_double.h b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_double.h index 8fb554c411..38abfa5378 100644 --- a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,45 +45,32 @@ namespace gmx { -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { __m128d b = _mm_add_sd(a.simdInternal_, _mm_permute_pd(a.simdInternal_, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_128_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_float.h b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_float.h index eda4881e96..4103efb1f2 100644 --- a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,46 +45,35 @@ namespace gmx { -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { - a.simdInternal_ = _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - a.simdInternal_ = _mm_add_ss(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&a); + a.simdInternal_ = + _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); + a.simdInternal_ = + _mm_add_ss(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&a); } -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_128_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_double.h b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_double.h index 01bfa6c59d..131532bb6b 100644 --- a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_double.h +++ b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,23 +45,17 @@ namespace gmx { -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { triplets0->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(0, 0)); triplets1->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(1, 0)); triplets2->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(1, 1)); } -static inline double -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) +static inline double reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __m128d t1, t2, t3, t4; @@ -83,9 +77,9 @@ reduceIncr4ReturnSum(double * m, t1 = _mm_add_pd(t1, t3); t2 = _mm_add_sd(t1, _mm_permute_pd(t1, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&t2); + return *reinterpret_cast(&t2); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_128_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_float.h b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_float.h index f22be079d3..acc344589d 100644 --- a/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_float.h +++ b/src/gromacs/simd/impl_x86_avx2_128/impl_x86_avx2_128_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,23 +45,17 @@ namespace gmx { -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { triplets0->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(1, 0, 0, 0)); triplets1->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(2, 2, 1, 1)); triplets2->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { _MM_TRANSPOSE4_PS(v0.simdInternal_, v1.simdInternal_, v2.simdInternal_, v3.simdInternal_); v0.simdInternal_ = _mm_add_ps(v0.simdInternal_, v1.simdInternal_); @@ -74,10 +68,10 @@ reduceIncr4ReturnSum(float * m, _mm_store_ps(m, v2.simdInternal_); __m128 b = _mm_add_ps(v0.simdInternal_, _mm_permute_ps(v0.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&b); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_128_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_definitions.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_definitions.h index da2d146cda..8af57a2486 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_definitions.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,48 +37,48 @@ #define GMX_SIMD_IMPL_X86_AVX2_256_DEFINITIONS_H // Capability definitions for 256-bit AVX2 -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // Not needed for width 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // Not needed for width 4 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 8 -#define GMX_SIMD_DOUBLE_WIDTH 4 -#define GMX_SIMD_FINT32_WIDTH 8 -#define GMX_SIMD_DINT32_WIDTH 4 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 32 // Bytes (8*single or 4*double) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 8 +#define GMX_SIMD_DOUBLE_WIDTH 4 +#define GMX_SIMD_FINT32_WIDTH 8 +#define GMX_SIMD_DINT32_WIDTH 4 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 32 // Bytes (8*single or 4*double) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 #endif // GMX_SIMD_IMPL_X86_AVX2_256_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_double.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_double.h index 73962f144f..dcf467ac04 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_double.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,38 +45,26 @@ namespace gmx { -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_float.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_float.h index 693e82ea6f..8472605e1f 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_float.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,38 +45,26 @@ namespace gmx { -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_double.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_double.h index 099bc40ddc..56253042a4 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,77 +46,60 @@ namespace gmx { -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { __m256i ia = _mm256_castpd_si256(a.simdInternal_); - __m256i res = _mm256_andnot_si256( _mm256_cmpeq_epi64(ia, _mm256_setzero_si256()), _mm256_cmpeq_epi64(ia, ia)); + __m256i res = _mm256_andnot_si256(_mm256_cmpeq_epi64(ia, _mm256_setzero_si256()), + _mm256_cmpeq_epi64(ia, ia)); - return { - _mm256_castsi256_pd(res) - }; + return { _mm256_castsi256_pd(res) }; } -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) { - const __m256d exponentMask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FF0000000000000LL)); - const __m256d mantissaMask = _mm256_castsi256_pd( _mm256_set1_epi64x(0x800FFFFFFFFFFFFFLL)); - const __m256i exponentBias = _mm256_set1_epi64x(1022LL); // add 1 to make our definition identical to frexp() - const __m256d half = _mm256_set1_pd(0.5); - __m256i iExponent; - __m128i iExponent128; + const __m256d exponentMask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FF0000000000000LL)); + const __m256d mantissaMask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x800FFFFFFFFFFFFFLL)); + const __m256i exponentBias = + _mm256_set1_epi64x(1022LL); // add 1 to make our definition identical to frexp() + const __m256d half = _mm256_set1_pd(0.5); + __m256i iExponent; + __m128i iExponent128; iExponent = _mm256_castpd_si256(_mm256_and_pd(value.simdInternal_, exponentMask)); iExponent = _mm256_sub_epi64(_mm256_srli_epi64(iExponent, 52), exponentBias); iExponent = _mm256_shuffle_epi32(iExponent, _MM_SHUFFLE(3, 1, 2, 0)); - iExponent128 = _mm256_extractf128_si256(iExponent, 1); - exponent->simdInternal_ = _mm_unpacklo_epi64(_mm256_castsi256_si128(iExponent), iExponent128); + iExponent128 = _mm256_extractf128_si256(iExponent, 1); + exponent->simdInternal_ = _mm_unpacklo_epi64(_mm256_castsi256_si128(iExponent), iExponent128); - return { - _mm256_or_pd(_mm256_and_pd(value.simdInternal_, mantissaMask), half) - }; + return { _mm256_or_pd(_mm256_and_pd(value.simdInternal_, mantissaMask), half) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { - const __m128i exponentBias = _mm_set1_epi32(1023); - __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); + const __m128i exponentBias = _mm_set1_epi32(1023); + __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -125,11 +108,9 @@ ldexp(SimdDouble value, SimdDInt32 exponent) } __m256i iExponent256 = _mm256_slli_epi64(_mm256_cvtepi32_epi64(iExponent), 52); - return { - _mm256_mul_pd(value.simdInternal_, _mm256_castsi256_pd(iExponent256)) - }; + return { _mm256_mul_pd(value.simdInternal_, _mm256_castsi256_pd(iExponent256)) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_float.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_float.h index bca233ab3f..b514aa0f94 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,83 +48,65 @@ namespace gmx class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_(_mm256_set1_epi32( b ? 0xFFFFFFFF : 0)) {} + SimdFIBool(bool b) : simdInternal_(_mm256_set1_epi32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFIBool(__m256i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__m256i simd) : simdInternal_(simd) {} - __m256i simdInternal_; + __m256i simdInternal_; }; -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { __m256i ia = _mm256_castps_si256(a.simdInternal_); - __m256i res = _mm256_andnot_si256( _mm256_cmpeq_epi32(ia, _mm256_setzero_si256()), _mm256_cmpeq_epi32(ia, ia)); + __m256i res = _mm256_andnot_si256(_mm256_cmpeq_epi32(ia, _mm256_setzero_si256()), + _mm256_cmpeq_epi32(ia, ia)); - return { - _mm256_castsi256_ps(res) - }; + return { _mm256_castsi256_ps(res) }; } -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { const __m256 exponentMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7F800000)); const __m256 mantissaMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x807FFFFF)); const __m256i exponentBias = _mm256_set1_epi32(126); // add 1 to make our definition identical to frexp() - const __m256 half = _mm256_set1_ps(0.5); + const __m256 half = _mm256_set1_ps(0.5); __m256i iExponent; iExponent = _mm256_castps_si256(_mm256_and_ps(value.simdInternal_, exponentMask)); exponent->simdInternal_ = _mm256_sub_epi32(_mm256_srli_epi32(iExponent, 23), exponentBias); - return { - _mm256_or_ps(_mm256_and_ps(value.simdInternal_, mantissaMask), half) - }; + return { _mm256_or_ps(_mm256_and_ps(value.simdInternal_, mantissaMask), half) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { - const __m256i exponentBias = _mm256_set1_epi32(127); - __m256i iExponent = _mm256_add_epi32(exponent.simdInternal_, exponentBias); + const __m256i exponentBias = _mm256_set1_epi32(127); + __m256i iExponent = _mm256_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -133,151 +115,100 @@ ldexp(SimdFloat value, SimdFInt32 exponent) } iExponent = _mm256_slli_epi32(iExponent, 23); - return { - _mm256_mul_ps(value.simdInternal_, _mm256_castsi256_ps(iExponent)) - }; + return { _mm256_mul_ps(value.simdInternal_, _mm256_castsi256_ps(iExponent)) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_and_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_andnot_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_or_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_xor_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_cmpeq_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_cmpeq_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - _mm256_andnot_si256(_mm256_cmpeq_epi32(a.simdInternal_, _mm256_setzero_si256()), - _mm256_cmpeq_epi32(a.simdInternal_, a.simdInternal_)) - }; + return { _mm256_andnot_si256(_mm256_cmpeq_epi32(a.simdInternal_, _mm256_setzero_si256()), + _mm256_cmpeq_epi32(a.simdInternal_, a.simdInternal_)) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - _mm256_cmpgt_epi32(b.simdInternal_, a.simdInternal_) - }; + return { _mm256_cmpgt_epi32(b.simdInternal_, a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - _mm256_and_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - _mm256_or_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_si256(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) { return _mm256_movemask_epi8(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdFIBool a) +{ + return _mm256_movemask_epi8(a.simdInternal_) != 0; +} -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool mask) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool mask) { - return { - _mm256_and_si256(a.simdInternal_, mask.simdInternal_) - }; + return { _mm256_and_si256(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool mask) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool mask) { - return { - _mm256_andnot_si256(mask.simdInternal_, a.simdInternal_) - }; + return { _mm256_andnot_si256(mask.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - _mm256_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm256_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - _mm256_castps_si256(a.simdInternal_) - }; + return { _mm256_castps_si256(a.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - _mm256_castsi256_ps(a.simdInternal_) - }; + return { _mm256_castsi256_ps(a.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_double.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_double.h index 0d9b3e5388..c8fe810fe6 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_double.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,26 +48,25 @@ namespace gmx // This version is marginally slower than the AVX 4-wide component load // version on Intel Skylake. On older Intel architectures this version // is significantly slower. -template -static inline void gmx_simdcall -gatherLoadUTransposeSafe(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTransposeSafe(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { assert(std::size_t(offset) % 16 == 0); const SimdDInt32 alignSimd = SimdDInt32(align); - SimdDInt32 vindex = simdLoad(offset, SimdDInt32Tag()); - vindex = vindex*alignSimd; + SimdDInt32 vindex = simdLoad(offset, SimdDInt32Tag()); + vindex = vindex * alignSimd; *v0 = _mm256_i32gather_pd(base + 0, vindex.simdInternal_, sizeof(double)); *v1 = _mm256_i32gather_pd(base + 1, vindex.simdInternal_, sizeof(double)); *v2 = _mm256_i32gather_pd(base + 2, vindex.simdInternal_, sizeof(double)); } -} //namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_float.h b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_float.h index 110b6d1675..7bdc50946d 100644 --- a/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_float.h +++ b/src/gromacs/simd/impl_x86_avx2_256/impl_x86_avx2_256_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,26 +48,25 @@ namespace gmx // This version is marginally slower than the AVX 4-wide component load // version on Intel Skylake. On older Intel architectures this version // is significantly slower. -template -static inline void gmx_simdcall -gatherLoadUTransposeSafe(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTransposeSafe(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { assert(std::size_t(offset) % 32 == 0); const SimdFInt32 alignSimd = SimdFInt32(align); - SimdFInt32 vindex = simdLoad(offset, SimdFInt32Tag()); - vindex = vindex*alignSimd; + SimdFInt32 vindex = simdLoad(offset, SimdFInt32Tag()); + vindex = vindex * alignSimd; *v0 = _mm256_i32gather_ps(base + 0, vindex.simdInternal_, sizeof(float)); *v1 = _mm256_i32gather_ps(base + 1, vindex.simdInternal_, sizeof(float)); *v2 = _mm256_i32gather_ps(base + 2, vindex.simdInternal_, sizeof(float)); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX2_256_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_definitions.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_definitions.h index a3d53e6461..0978441253 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_definitions.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,51 +37,51 @@ #define GMX_SIMD_IMPL_X86_AVX_128_FMA_DEFINITIONS_H // Capability definitions for AVX-128-FMA -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 // Uses 256-bit avx for SIMD4-double +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Uses 256-bit avx for SIMD4-double // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 32 // Bytes (4*double for SIMD4) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 32 // Bytes (4*double for SIMD4) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 -#define gmx_mm_maskload_ps(mem, mask) _mm_maskload_ps((mem), (mask)) -#define gmx_mm_maskstore_ps(mem, mask, x) _mm_maskstore_ps((mem), (mask), (x)) +#define gmx_mm_maskload_ps(mem, mask) _mm_maskload_ps((mem), (mask)) +#define gmx_mm_maskstore_ps(mem, mask, x) _mm_maskstore_ps((mem), (mask), (x)) -#endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_DEFINITIONS_H +#endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_double.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_double.h index d51633ec7d..3649362edf 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_double.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,229 +49,163 @@ namespace gmx class Simd4Double { - public: - Simd4Double() {} +public: + Simd4Double() {} - Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} + Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - Simd4Double(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Double(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; class Simd4DBool { - public: - Simd4DBool() {} +public: + Simd4DBool() {} - //! \brief Construct from scalar bool - Simd4DBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + //! \brief Construct from scalar bool + Simd4DBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - Simd4DBool(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4DBool(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; -static inline Simd4Double gmx_simdcall -load4(const double *m) +static inline Simd4Double gmx_simdcall load4(const double* m) { assert(size_t(m) % 32 == 0); - return { - _mm256_load_pd(m) - }; + return { _mm256_load_pd(m) }; } -static inline void gmx_simdcall -store4(double *m, Simd4Double a) +static inline void gmx_simdcall store4(double* m, Simd4Double a) { assert(size_t(m) % 32 == 0); _mm256_store_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -load4U(const double *m) +static inline Simd4Double gmx_simdcall load4U(const double* m) { - return { - _mm256_loadu_pd(m) - }; + return { _mm256_loadu_pd(m) }; } -static inline void gmx_simdcall -store4U(double *m, Simd4Double a) +static inline void gmx_simdcall store4U(double* m, Simd4Double a) { _mm256_storeu_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -simd4SetZeroD() +static inline Simd4Double gmx_simdcall simd4SetZeroD() { - return { - _mm256_setzero_pd() - }; + return { _mm256_setzero_pd() }; } -static inline Simd4Double gmx_simdcall -operator&(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -andNot(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b) { - return { - _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator|(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator^(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b) { - return { - _mm256_xor_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator+(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b) { - return { - _mm256_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b) { - return { - _mm256_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double x) +static inline Simd4Double gmx_simdcall operator-(Simd4Double x) { - return { - _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) - }; + return { _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) }; } -static inline Simd4Double gmx_simdcall -operator*(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b) { - return { - _mm256_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mul_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_macc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_macc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_msub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_msub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_nmacc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_nmacc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_nmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_nmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { - return { - _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) - }; + return { _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -abs(Simd4Double x) +static inline Simd4Double gmx_simdcall abs(Simd4Double x) { - return { - _mm256_andnot_pd( _mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_ ) - }; + return { _mm256_andnot_pd(_mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -max(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b) { - return { - _mm256_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -min(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b) { - return { - _mm256_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_min_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -round(Simd4Double x) +static inline Simd4Double gmx_simdcall round(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Double gmx_simdcall -trunc(Simd4Double x) +static inline Simd4Double gmx_simdcall trunc(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline double gmx_simdcall -dotProduct(Simd4Double a, Simd4Double b) +static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b) { __m128d tmp1, tmp2; - a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); - tmp1 = _mm256_castpd256_pd128(a.simdInternal_); - tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); + a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); + tmp1 = _mm256_castpd256_pd128(a.simdInternal_); + tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); tmp1 = _mm_add_pd(tmp1, _mm_permute_pd(tmp1, _MM_SHUFFLE2(0, 1))); tmp1 = _mm_add_pd(tmp1, tmp2); - return *reinterpret_cast(&tmp1); + return *reinterpret_cast(&tmp1); } -static inline void gmx_simdcall -transpose(Simd4Double * v0, Simd4Double * v1, - Simd4Double * v2, Simd4Double * v3) +static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3) { __m256d t1, t2, t3, t4; t1 = _mm256_unpacklo_pd(v0->simdInternal_, v1->simdInternal_); @@ -284,83 +218,57 @@ transpose(Simd4Double * v0, Simd4Double * v1, v3->simdInternal_ = _mm256_permute2f128_pd(t2, t4, 0x31); } -static inline Simd4DBool gmx_simdcall -operator==(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator!=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator&&(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4DBool gmx_simdcall -operator||(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator||(Simd4DBool a, Simd4DBool b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4DBool a) { return _mm256_movemask_pd(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(Simd4DBool a) +{ + return _mm256_movemask_pd(a.simdInternal_) != 0; +} -static inline Simd4Double gmx_simdcall -selectByMask(Simd4Double a, Simd4DBool mask) +static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool mask) { - return { - _mm256_and_pd(a.simdInternal_, mask.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, mask.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -selectByNotMask(Simd4Double a, Simd4DBool mask) +static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool mask) { - return { - _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) - }; + return { _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -blend(Simd4Double a, Simd4Double b, Simd4DBool sel) +static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel) { - return { - _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline double gmx_simdcall -reduce(Simd4Double a) +static inline double gmx_simdcall reduce(Simd4Double a) { __m128d a0, a1; /* test with shuffle & add as an alternative to hadd later */ @@ -368,9 +276,9 @@ reduce(Simd4Double a) a0 = _mm256_castpd256_pd128(a.simdInternal_); a1 = _mm256_extractf128_pd(a.simdInternal_, 0x1); a0 = _mm_add_sd(a0, a1); - return *reinterpret_cast(&a0); + return *reinterpret_cast(&a0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_float.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_float.h index 15fd2fbc1a..ffa331184c 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_float.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,47 +46,34 @@ namespace gmx { -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_macc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_macc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_msub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_msub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_nmacc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmacc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_nmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __m128 b; b = _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_double.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_double.h index 0bbc2a1657..ce34d19dc6 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,45 +46,32 @@ namespace gmx { -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { __m128d b = _mm_add_sd(a.simdInternal_, _mm_permute_pd(a.simdInternal_, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_macc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_macc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_msub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_msub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_nmacc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmacc_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_nmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif /* GMX_SIMD_IMPL_X86_AVX_128_FMA_SIMD_DOUBLE_H */ diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_float.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_float.h index 7ac5dcc327..b9b22098ce 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,46 +46,35 @@ namespace gmx { -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { - a.simdInternal_ = _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - a.simdInternal_ = _mm_add_ss(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&a); + a.simdInternal_ = + _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); + a.simdInternal_ = + _mm_add_ss(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&a); } -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_macc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_macc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_msub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_msub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_nmacc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmacc_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_nmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_nmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_double.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_double.h index 6a8daa7502..1eaf881316 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_double.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,23 +49,17 @@ namespace gmx { -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { triplets0->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(0, 0)); triplets1->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(1, 0)); triplets2->simdInternal_ = _mm_permute_pd(scalar.simdInternal_, _MM_SHUFFLE2(1, 1)); } -static inline double -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) +static inline double reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __m128d t1, t2, t3, t4; @@ -87,9 +81,9 @@ reduceIncr4ReturnSum(double * m, t1 = _mm_add_pd(t1, t3); t2 = _mm_add_sd(t1, _mm_permute_pd(t1, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&t2); + return *reinterpret_cast(&t2); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_float.h b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_float.h index 2d971262b8..61bbdc8720 100644 --- a/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_float.h +++ b/src/gromacs/simd/impl_x86_avx_128_fma/impl_x86_avx_128_fma_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,23 +58,17 @@ namespace gmx * throughput just-so-slightly. */ -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { triplets0->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(1, 0, 0, 0)); triplets1->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(2, 2, 1, 1)); triplets2->simdInternal_ = _mm_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { _MM_TRANSPOSE4_PS(v0.simdInternal_, v1.simdInternal_, v2.simdInternal_, v3.simdInternal_); v0.simdInternal_ = _mm_add_ps(v0.simdInternal_, v1.simdInternal_); @@ -87,10 +81,10 @@ reduceIncr4ReturnSum(float * m, _mm_store_ps(m, v2.simdInternal_); __m128 b = _mm_add_ps(v0.simdInternal_, _mm_permute_ps(v0.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&b); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_128_FMA_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_definitions.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_definitions.h index 106ba1c3e6..13974aecb6 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_definitions.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,48 +37,48 @@ #define GMX_SIMD_IMPL_X86_AVX_256_DEFINITIONS_H // Capability definitions for 256-bit AVX -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 0 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 // Emulated -#define GMX_SIMD_HAVE_FINT32_LOGICAL 0 // AVX1 cannot do 256-bit int shifts -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 // AVX1 cannot do 256-bit int +,-,* -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 // Native, since we use __m128i -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // Not needed for width 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 0 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 // Emulated +#define GMX_SIMD_HAVE_FINT32_LOGICAL 0 // AVX1 cannot do 256-bit int shifts +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 0 // AVX1 cannot do 256-bit int +,-,* +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 // Native, since we use __m128i +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // Not needed for width 4 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 8 -#define GMX_SIMD_DOUBLE_WIDTH 4 -#define GMX_SIMD_FINT32_WIDTH 8 -#define GMX_SIMD_DINT32_WIDTH 4 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 32 // Bytes (8*single or 4*double) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 8 +#define GMX_SIMD_DOUBLE_WIDTH 4 +#define GMX_SIMD_FINT32_WIDTH 8 +#define GMX_SIMD_DINT32_WIDTH 4 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 32 // Bytes (8*single or 4*double) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 #endif // GMX_SIMD_IMPL_X86_AVX_256_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_general.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_general.h index c55f924353..57999e7959 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_general.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,12 +41,11 @@ namespace gmx { -static inline void -simdPrefetch(void *m) +static inline void simdPrefetch(void* m) { - _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_GENERAL_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_double.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_double.h index 70d312f744..fbdbf9819e 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_double.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,232 +48,167 @@ namespace gmx class Simd4Double { - public: - Simd4Double() {} +public: + Simd4Double() {} - Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} + Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - Simd4Double(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Double(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; class Simd4DBool { - public: - Simd4DBool() {} +public: + Simd4DBool() {} - //! \brief Construct from scalar bool - Simd4DBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + //! \brief Construct from scalar bool + Simd4DBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32(b ? 0xFFFFFFFF : 0))) + { + } - // Internal utility constructor to simplify return statements - Simd4DBool(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4DBool(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; -static inline Simd4Double gmx_simdcall -load4(const double *m) +static inline Simd4Double gmx_simdcall load4(const double* m) { assert(std::size_t(m) % 32 == 0); - return { - _mm256_load_pd(m) - }; + return { _mm256_load_pd(m) }; } -static inline void gmx_simdcall -store4(double *m, Simd4Double a) +static inline void gmx_simdcall store4(double* m, Simd4Double a) { assert(std::size_t(m) % 32 == 0); _mm256_store_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -load4U(const double *m) +static inline Simd4Double gmx_simdcall load4U(const double* m) { - return { - _mm256_loadu_pd(m) - }; + return { _mm256_loadu_pd(m) }; } -static inline void gmx_simdcall -store4U(double *m, Simd4Double a) +static inline void gmx_simdcall store4U(double* m, Simd4Double a) { _mm256_storeu_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -simd4SetZeroD() +static inline Simd4Double gmx_simdcall simd4SetZeroD() { - return { - _mm256_setzero_pd() - }; + return { _mm256_setzero_pd() }; } -static inline Simd4Double gmx_simdcall -operator&(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -andNot(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b) { - return { - _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator|(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator^(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b) { - return { - _mm256_xor_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator+(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b) { - return { - _mm256_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b) { - return { - _mm256_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double x) +static inline Simd4Double gmx_simdcall operator-(Simd4Double x) { - return { - _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) - }; + return { _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) }; } -static inline Simd4Double gmx_simdcall -operator*(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b) { - return { - _mm256_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mul_pd(a.simdInternal_, b.simdInternal_) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_sub_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_sub_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_sub_pd(c.simdInternal_, _mm256_mul_pd(a.simdInternal_, b.simdInternal_)) - }; + return { _mm256_sub_pd(c.simdInternal_, _mm256_mul_pd(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_sub_pd(_mm256_setzero_pd(), _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm256_sub_pd(_mm256_setzero_pd(), + _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { - return { - _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) - }; + return { _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -abs(Simd4Double x) +static inline Simd4Double gmx_simdcall abs(Simd4Double x) { - return { - _mm256_andnot_pd( _mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_ ) - }; + return { _mm256_andnot_pd(_mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -max(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b) { - return { - _mm256_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -min(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b) { - return { - _mm256_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_min_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -round(Simd4Double x) +static inline Simd4Double gmx_simdcall round(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Double gmx_simdcall -trunc(Simd4Double x) +static inline Simd4Double gmx_simdcall trunc(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline double gmx_simdcall -dotProduct(Simd4Double a, Simd4Double b) +static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b) { __m128d tmp1, tmp2; - a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); - tmp1 = _mm256_castpd256_pd128(a.simdInternal_); - tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); + a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); + tmp1 = _mm256_castpd256_pd128(a.simdInternal_); + tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); tmp1 = _mm_add_pd(tmp1, _mm_permute_pd(tmp1, _MM_SHUFFLE2(0, 1))); tmp1 = _mm_add_pd(tmp1, tmp2); - return *reinterpret_cast(&tmp1); + return *reinterpret_cast(&tmp1); } -static inline void gmx_simdcall -transpose(Simd4Double * v0, Simd4Double * v1, - Simd4Double * v2, Simd4Double * v3) +static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3) { __m256d t1, t2, t3, t4; t1 = _mm256_unpacklo_pd(v0->simdInternal_, v1->simdInternal_); @@ -286,83 +221,57 @@ transpose(Simd4Double * v0, Simd4Double * v1, v3->simdInternal_ = _mm256_permute2f128_pd(t2, t4, 0x31); } -static inline Simd4DBool gmx_simdcall -operator==(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator!=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator&&(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4DBool gmx_simdcall -operator||(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator||(Simd4DBool a, Simd4DBool b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4DBool a) { return _mm256_movemask_pd(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(Simd4DBool a) +{ + return _mm256_movemask_pd(a.simdInternal_) != 0; +} -static inline Simd4Double gmx_simdcall -selectByMask(Simd4Double a, Simd4DBool mask) +static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool mask) { - return { - _mm256_and_pd(a.simdInternal_, mask.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, mask.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -selectByNotMask(Simd4Double a, Simd4DBool mask) +static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool mask) { - return { - _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) - }; + return { _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -blend(Simd4Double a, Simd4Double b, Simd4DBool sel) +static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel) { - return { - _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline double gmx_simdcall -reduce(Simd4Double a) +static inline double gmx_simdcall reduce(Simd4Double a) { __m128d a0, a1; // test with shuffle & add as an alternative to hadd later @@ -370,9 +279,9 @@ reduce(Simd4Double a) a0 = _mm256_castpd256_pd128(a.simdInternal_); a1 = _mm256_extractf128_pd(a.simdInternal_, 0x1); a0 = _mm_add_sd(a0, a1); - return *reinterpret_cast(&a0); + return *reinterpret_cast(&a0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_float.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_float.h index e2a35812c1..f3b3a776d7 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_float.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,317 +48,224 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} + Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - //! \brief Construct from scalar bool - Simd4FBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + //! \brief Construct from scalar bool + Simd4FBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - Simd4FBool(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { assert(std::size_t(m) % 16 == 0); - return { - _mm_load_ps(m) - }; + return { _mm_load_ps(m) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { assert(std::size_t(m) % 16 == 0); _mm_store_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { - _mm_loadu_ps(m) - }; + return { _mm_loadu_ps(m) }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { _mm_storeu_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - _mm_setzero_ps() - }; + return { _mm_setzero_ps() }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - _mm_andnot_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - _mm_xor_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - _mm_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - _mm_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) - }; + return { _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - _mm_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mul_ps(a.simdInternal_, b.simdInternal_) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) - }; + return { _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(_mm_setzero_ps(), _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm_sub_ps(_mm_setzero_ps(), + _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - _mm_rsqrt_ps(x.simdInternal_) - }; + return { _mm_rsqrt_ps(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - _mm_andnot_ps( _mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_ ) - }; + return { _mm_andnot_ps(_mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - _mm_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - _mm_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_min_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { __m128 c, d; c = _mm_mul_ps(a.simdInternal_, b.simdInternal_); d = _mm_add_ps(c, _mm_permute_ps(c, _MM_SHUFFLE(2, 1, 2, 1))); d = _mm_add_ps(d, _mm_permute_ps(c, _MM_SHUFFLE(3, 2, 3, 2))); - return *reinterpret_cast(&d); + return *reinterpret_cast(&d); } -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { _MM_TRANSPOSE4_PS(v0->simdInternal_, v1->simdInternal_, v2->simdInternal_, v3->simdInternal_); } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) { return _mm_movemask_ps(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(Simd4FBool a) +{ + return _mm_movemask_ps(a.simdInternal_) != 0; +} -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool mask) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool mask) { - return { - _mm_and_ps(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, mask.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool mask) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool mask) { - return { - _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __m128 b; b = _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_double.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_double.h index d8eb25ffc2..4b506b1656 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,359 +49,263 @@ #include "impl_x86_avx_256_simd_float.h" - - namespace gmx { class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - SimdDouble(double d) : simdInternal_(_mm256_set1_pd(d)) {} + SimdDouble(double d) : simdInternal_(_mm256_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - SimdDInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} + SimdDInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - SimdDBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + SimdDBool(bool b) : simdInternal_(_mm256_castsi256_pd(_mm256_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - SimdDBool(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - SimdDIBool(bool b) : simdInternal_(_mm_set1_epi32( b ? 0xFFFFFFFF : 0)) {} + SimdDIBool(bool b) : simdInternal_(_mm_set1_epi32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdDIBool(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag /*unused*/ = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag /*unused*/ = {}) { assert(std::size_t(m) % 32 == 0); - return { - _mm256_load_pd(m) - }; + return { _mm256_load_pd(m) }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { assert(std::size_t(m) % 32 == 0); _mm256_store_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag /*unused*/ = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag /*unused*/ = {}) { - return { - _mm256_loadu_pd(m) - }; + return { _mm256_loadu_pd(m) }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { _mm256_storeu_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - _mm256_setzero_pd() - }; + return { _mm256_setzero_pd() }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag /*unused*/) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag /*unused*/) { assert(std::size_t(m) % 16 == 0); - return { - _mm_load_si128(reinterpret_cast(m)) - }; + return { _mm_load_si128(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { assert(std::size_t(m) % 16 == 0); - _mm_store_si128(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_store_si128(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag /*unused*/) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag /*unused*/) { - return { - _mm_loadu_si128(reinterpret_cast(m)) - }; + return { _mm_loadu_si128(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { - _mm_storeu_si128(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_storeu_si128(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - _mm_setzero_si128() - }; + return { _mm_setzero_si128() }; } template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 a) { return _mm_extract_epi32(a.simdInternal_, index); } -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - return { - _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - return { - _mm256_xor_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - return { - _mm256_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - return { - _mm256_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble x) +static inline SimdDouble gmx_simdcall operator-(SimdDouble x) { - return { - _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) - }; + return { _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) }; } -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - return { - _mm256_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mul_pd(a.simdInternal_, b.simdInternal_) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_sub_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_sub_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_sub_pd(c.simdInternal_, _mm256_mul_pd(a.simdInternal_, b.simdInternal_)) - }; + return { _mm256_sub_pd(c.simdInternal_, _mm256_mul_pd(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm256_sub_pd(_mm256_setzero_pd(), _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm256_sub_pd(_mm256_setzero_pd(), + _mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) - }; + return { _mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - _mm256_cvtps_pd(_mm_rcp_ps(_mm256_cvtpd_ps(x.simdInternal_))) - }; + return { _mm256_cvtps_pd(_mm_rcp_ps(_mm256_cvtpd_ps(x.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm256_add_pd(a.simdInternal_, _mm256_and_pd(b.simdInternal_, m.simdInternal_)) - }; + return { _mm256_add_pd(a.simdInternal_, _mm256_and_pd(b.simdInternal_, m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm256_and_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), m.simdInternal_) }; } -static inline SimdDouble -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { - return { - _mm256_and_pd(_mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_pd(_mm256_add_pd(_mm256_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_), + m.simdInternal_) }; } -static inline SimdDouble -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzRsqrt(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = _mm256_blendv_pd(_mm256_set1_pd(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - _mm256_and_pd(_mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; + return { _mm256_and_pd(_mm256_cvtps_pd(_mm_rsqrt_ps(_mm256_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } -static inline SimdDouble -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzRcp(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = _mm256_blendv_pd(_mm256_set1_pd(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - _mm256_and_pd(_mm256_cvtps_pd(_mm_rcp_ps(_mm256_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; + return { _mm256_and_pd(_mm256_cvtps_pd(_mm_rcp_ps(_mm256_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -abs(SimdDouble x) +static inline SimdDouble gmx_simdcall abs(SimdDouble x) { - return { - _mm256_andnot_pd( _mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_ ) - }; + return { _mm256_andnot_pd(_mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - return { - _mm256_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - return { - _mm256_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_min_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) -{ - const __m256d exponentMask = _mm256_castsi256_pd( _mm256_set1_epi64x(0x7FF0000000000000LL)); - const __m256d mantissaMask = _mm256_castsi256_pd( _mm256_set1_epi64x(0x800FFFFFFFFFFFFFLL)); - const __m256d half = _mm256_set1_pd(0.5); - const __m128i exponentBias = _mm_set1_epi32(1022); // add 1 to make our definition identical to frexp() - __m256i iExponent; - __m128i iExponentLow, iExponentHigh; +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) +{ + const __m256d exponentMask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x7FF0000000000000LL)); + const __m256d mantissaMask = _mm256_castsi256_pd(_mm256_set1_epi64x(0x800FFFFFFFFFFFFFLL)); + const __m256d half = _mm256_set1_pd(0.5); + const __m128i exponentBias = _mm_set1_epi32(1022); // add 1 to make our definition identical to frexp() + __m256i iExponent; + __m128i iExponentLow, iExponentHigh; iExponent = _mm256_castpd_si256(_mm256_and_pd(value.simdInternal_, exponentMask)); iExponentHigh = _mm256_extractf128_si256(iExponent, 0x1); @@ -413,86 +317,68 @@ frexp(SimdDouble value, SimdDInt32 * exponent) iExponentLow = _mm_or_si128(iExponentLow, iExponentHigh); exponent->simdInternal_ = _mm_sub_epi32(iExponentLow, exponentBias); - return { - _mm256_or_pd(_mm256_and_pd(value.simdInternal_, mantissaMask), half) - }; + return { _mm256_or_pd(_mm256_and_pd(value.simdInternal_, mantissaMask), half) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { const __m128i exponentBias = _mm_set1_epi32(1023); __m128i iExponentLow, iExponentHigh; __m256d fExponent; - iExponentLow = _mm_add_epi32(exponent.simdInternal_, exponentBias); + iExponentLow = _mm_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { // Make sure biased argument is not negative - iExponentLow = _mm_max_epi32(iExponentLow, _mm_setzero_si128()); + iExponentLow = _mm_max_epi32(iExponentLow, _mm_setzero_si128()); } iExponentHigh = _mm_shuffle_epi32(iExponentLow, _MM_SHUFFLE(3, 3, 2, 2)); iExponentLow = _mm_shuffle_epi32(iExponentLow, _MM_SHUFFLE(1, 1, 0, 0)); iExponentHigh = _mm_slli_epi64(iExponentHigh, 52); iExponentLow = _mm_slli_epi64(iExponentLow, 52); - fExponent = _mm256_castsi256_pd(_mm256_insertf128_si256(_mm256_castsi128_si256(iExponentLow), iExponentHigh, 0x1)); - return { - _mm256_mul_pd(value.simdInternal_, fExponent) - }; + fExponent = _mm256_castsi256_pd( + _mm256_insertf128_si256(_mm256_castsi128_si256(iExponentLow), iExponentHigh, 0x1)); + return { _mm256_mul_pd(value.simdInternal_, fExponent) }; } #endif -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { __m128d a0, a1; - a.simdInternal_ = _mm256_add_pd(a.simdInternal_, _mm256_permute_pd(a.simdInternal_, 0b0101 )); + a.simdInternal_ = _mm256_add_pd(a.simdInternal_, _mm256_permute_pd(a.simdInternal_, 0b0101)); a0 = _mm256_castpd256_pd128(a.simdInternal_); a1 = _mm256_extractf128_pd(a.simdInternal_, 0x1); a0 = _mm_add_sd(a0, a1); - return *reinterpret_cast(&a0); + return *reinterpret_cast(&a0); } -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm256_cmp_pd(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { // Do an or of the low/high 32 bits of each double (so the data is replicated), // and then use the same algorithm as we use for single precision. @@ -501,246 +387,169 @@ testBits(SimdDouble a) tst = _mm256_or_ps(tst, _mm256_permute_ps(tst, _MM_SHUFFLE(2, 3, 0, 1))); tst = _mm256_cvtepi32_ps(_mm256_castps_si256(tst)); - return { - _mm256_castps_pd(_mm256_cmp_ps(tst, _mm256_setzero_ps(), _CMP_NEQ_OQ)) - }; + return { _mm256_castps_pd(_mm256_cmp_ps(tst, _mm256_setzero_ps(), _CMP_NEQ_OQ)) }; } #endif -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) { return _mm256_movemask_pd(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdDBool a) +{ + return _mm256_movemask_pd(a.simdInternal_) != 0; +} -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool mask) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool mask) { - return { - _mm256_and_pd(a.simdInternal_, mask.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool mask) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool mask) { - return { - _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) - }; + return { _mm256_andnot_pd(mask.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm256_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_andnot_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_xor_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { __m128i x = a.simdInternal_; - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); - return { - res - }; + return { res }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) { return _mm_movemask_epi8(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdDIBool a) +{ + return _mm_movemask_epi8(a.simdInternal_) != 0; +} -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool mask) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool mask) { - return { - _mm_and_si128(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool mask) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool mask) { - return { - _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { - return { - _mm256_cvtpd_epi32(a.simdInternal_) - }; + return { _mm256_cvtpd_epi32(a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { - return { - _mm256_cvttpd_epi32(a.simdInternal_) - }; + return { _mm256_cvttpd_epi32(a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { - return { - _mm256_cvtepi32_pd(a.simdInternal_) - }; + return { _mm256_cvtepi32_pd(a.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { __m128i a1 = _mm256_extractf128_si256(_mm256_castpd_si256(a.simdInternal_), 0x1); __m128i a0 = _mm256_castsi256_si128(_mm256_castpd_si256(a.simdInternal_)); - a0 = _mm_shuffle_epi32(a0, _MM_SHUFFLE(2, 0, 2, 0)); - a1 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(2, 0, 2, 0)); + a0 = _mm_shuffle_epi32(a0, _MM_SHUFFLE(2, 0, 2, 0)); + a1 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(2, 0, 2, 0)); - return { - _mm_blend_epi16(a0, a1, 0xF0) - }; + return { _mm_blend_epi16(a0, a1, 0xF0) }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { __m128d lo = _mm_castsi128_pd(_mm_unpacklo_epi32(a.simdInternal_, a.simdInternal_)); __m128d hi = _mm_castsi128_pd(_mm_unpackhi_epi32(a.simdInternal_, a.simdInternal_)); - return { - _mm256_insertf128_pd(_mm256_castpd128_pd256(lo), hi, 0x1) - }; + return { _mm256_insertf128_pd(_mm256_castpd128_pd256(lo), hi, 0x1) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { d0->simdInternal_ = _mm256_cvtps_pd(_mm256_castps256_ps128(f.simdInternal_)); d1->simdInternal_ = _mm256_cvtps_pd(_mm256_extractf128_ps(f.simdInternal_, 0x1)); } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { __m128 f0 = _mm256_cvtpd_ps(d0.simdInternal_); __m128 f1 = _mm256_cvtpd_ps(d1.simdInternal_); - return { - _mm256_insertf128_ps(_mm256_castps128_ps256(f0), f1, 0x1) - }; + return { _mm256_insertf128_ps(_mm256_castps128_ps256(f0), f1, 0x1) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_float.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_float.h index bd3e5fd399..4137858aac 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_simd_float.h @@ -51,338 +51,244 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) : simdInternal_(_mm256_set1_ps(f)) {} + SimdFloat(float f) : simdInternal_(_mm256_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(__m256 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__m256 simd) : simdInternal_(simd) {} - __m256 simdInternal_; + __m256 simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) : simdInternal_(_mm256_set1_epi32(i)) {} + SimdFInt32(std::int32_t i) : simdInternal_(_mm256_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(__m256i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__m256i simd) : simdInternal_(simd) {} - __m256i simdInternal_; + __m256i simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_(_mm256_castsi256_ps(_mm256_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + SimdFBool(bool b) : simdInternal_(_mm256_castsi256_ps(_mm256_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - SimdFBool(__m256 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__m256 simd) : simdInternal_(simd) {} - __m256 simdInternal_; + __m256 simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag /*unused*/ = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag /*unused*/ = {}) { assert(std::size_t(m) % 32 == 0); - return { - _mm256_load_ps(m) - }; + return { _mm256_load_ps(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { assert(std::size_t(m) % 32 == 0); _mm256_store_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag /*unused*/ = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag /*unused*/ = {}) { - return { - _mm256_loadu_ps(m) - }; + return { _mm256_loadu_ps(m) }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { _mm256_storeu_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - _mm256_setzero_ps() - }; + return { _mm256_setzero_ps() }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag /*unused*/) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag /*unused*/) { assert(std::size_t(m) % 32 == 0); - return { - _mm256_load_si256(reinterpret_cast(m)) - }; + return { _mm256_load_si256(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { assert(std::size_t(m) % 32 == 0); - _mm256_store_si256(reinterpret_cast<__m256i *>(m), a.simdInternal_); + _mm256_store_si256(reinterpret_cast<__m256i*>(m), a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag /*unused*/) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag /*unused*/) { - return { - _mm256_loadu_si256(reinterpret_cast(m)) - }; + return { _mm256_loadu_si256(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { - _mm256_storeu_si256(reinterpret_cast<__m256i *>(m), a.simdInternal_); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(m), a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - _mm256_setzero_si256() - }; + return { _mm256_setzero_si256() }; } template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 a) { - return _mm_extract_epi32(_mm256_extractf128_si256(a.simdInternal_, index>>2), index & 0x3); + return _mm_extract_epi32(_mm256_extractf128_si256(a.simdInternal_, index >> 2), index & 0x3); } -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - _mm256_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - _mm256_andnot_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - _mm256_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - _mm256_xor_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - _mm256_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - _mm256_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - _mm256_xor_ps(x.simdInternal_, _mm256_set1_ps(GMX_FLOAT_NEGZERO)) - }; + return { _mm256_xor_ps(x.simdInternal_, _mm256_set1_ps(GMX_FLOAT_NEGZERO)) }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - _mm256_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mul_ps(a.simdInternal_, b.simdInternal_) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_sub_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm256_sub_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_sub_ps(c.simdInternal_, _mm256_mul_ps(a.simdInternal_, b.simdInternal_)) - }; + return { _mm256_sub_ps(c.simdInternal_, _mm256_mul_ps(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm256_sub_ps(_mm256_setzero_ps(), _mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm256_sub_ps(_mm256_setzero_ps(), + _mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - _mm256_rsqrt_ps(x.simdInternal_) - }; + return { _mm256_rsqrt_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - _mm256_rcp_ps(x.simdInternal_) - }; + return { _mm256_rcp_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm256_add_ps(a.simdInternal_, _mm256_and_ps(b.simdInternal_, m.simdInternal_)) - }; + return { _mm256_add_ps(a.simdInternal_, _mm256_and_ps(b.simdInternal_, m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm256_and_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { - return { - _mm256_and_ps(_mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_ps(_mm256_add_ps(_mm256_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_), + m.simdInternal_) }; } -static inline SimdFloat -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzRsqrt(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = _mm256_blendv_ps(_mm256_set1_ps(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - _mm256_and_ps(_mm256_rsqrt_ps(x.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_ps(_mm256_rsqrt_ps(x.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzRcp(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = _mm256_blendv_ps(_mm256_set1_ps(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - _mm256_and_ps(_mm256_rcp_ps(x.simdInternal_), m.simdInternal_) - }; + return { _mm256_and_ps(_mm256_rcp_ps(x.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - _mm256_andnot_ps( _mm256_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_ ) - }; + return { _mm256_andnot_ps(_mm256_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - _mm256_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - _mm256_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_min_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - _mm256_round_ps(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm256_round_ps(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - _mm256_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm256_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { - const __m256 exponentMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7F800000)); - const __m256 mantissaMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x807FFFFF)); - const __m256 half = _mm256_set1_ps(0.5); - const __m128i exponentBias = _mm_set1_epi32(126); // add 1 to make our definition identical to frexp() - __m256i iExponent; - __m128i iExponentLow, iExponentHigh; + const __m256 exponentMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7F800000)); + const __m256 mantissaMask = _mm256_castsi256_ps(_mm256_set1_epi32(0x807FFFFF)); + const __m256 half = _mm256_set1_ps(0.5); + const __m128i exponentBias = _mm_set1_epi32(126); // add 1 to make our definition identical to frexp() + __m256i iExponent; + __m128i iExponentLow, iExponentHigh; iExponent = _mm256_castps_si256(_mm256_and_ps(value.simdInternal_, exponentMask)); iExponentHigh = _mm256_extractf128_si256(iExponent, 0x1); @@ -394,17 +300,13 @@ frexp(SimdFloat value, SimdFInt32 * exponent) iExponent = _mm256_castsi128_si256(iExponentLow); exponent->simdInternal_ = _mm256_insertf128_si256(iExponent, iExponentHigh, 0x1); - return { - _mm256_or_ps(_mm256_and_ps(value.simdInternal_, mantissaMask), half) - }; - + return { _mm256_or_ps(_mm256_and_ps(value.simdInternal_, mantissaMask), half) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { - const __m128i exponentBias = _mm_set1_epi32(127); + const __m128i exponentBias = _mm_set1_epi32(127); __m256i iExponent; __m128i iExponentLow, iExponentHigh; @@ -425,134 +327,94 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponentHigh = _mm_slli_epi32(iExponentHigh, 23); iExponent = _mm256_castsi128_si256(iExponentLow); iExponent = _mm256_insertf128_si256(iExponent, iExponentHigh, 0x1); - return { - _mm256_mul_ps(value.simdInternal_, _mm256_castsi256_ps(iExponent)) - }; + return { _mm256_mul_ps(value.simdInternal_, _mm256_castsi256_ps(iExponent)) }; } #endif -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { __m128 t0; t0 = _mm_add_ps(_mm256_castps256_ps128(a.simdInternal_), _mm256_extractf128_ps(a.simdInternal_, 0x1)); t0 = _mm_add_ps(t0, _mm_permute_ps(t0, _MM_SHUFFLE(1, 0, 3, 2))); t0 = _mm_add_ss(t0, _mm_permute_ps(t0, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&t0); + return *reinterpret_cast(&t0); } -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm256_cmp_ps(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } // Override for AVX2 and higher #if GMX_SIMD_X86_AVX_256 -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { __m256 tst = _mm256_cvtepi32_ps(_mm256_castps_si256(a.simdInternal_)); - return { - _mm256_cmp_ps(tst, _mm256_setzero_ps(), _CMP_NEQ_OQ) - }; + return { _mm256_cmp_ps(tst, _mm256_setzero_ps(), _CMP_NEQ_OQ) }; } #endif -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - _mm256_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - _mm256_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) { return _mm256_movemask_ps(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdFBool a) +{ + return _mm256_movemask_ps(a.simdInternal_) != 0; +} -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool mask) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool mask) { - return { - _mm256_and_ps(a.simdInternal_, mask.simdInternal_) - }; + return { _mm256_and_ps(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool mask) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool mask) { - return { - _mm256_andnot_ps(mask.simdInternal_, a.simdInternal_) - }; + return { _mm256_andnot_ps(mask.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - _mm256_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm256_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - _mm256_cvtps_epi32(a.simdInternal_) - }; + return { _mm256_cvtps_epi32(a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - _mm256_cvttps_epi32(a.simdInternal_) - }; + return { _mm256_cvttps_epi32(a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - _mm256_cvtepi32_ps(a.simdInternal_) - }; + return { _mm256_cvtepi32_ps(a.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_double.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_double.h index 522dc560ad..d404eb783f 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_double.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,11 +52,7 @@ namespace gmx { // Internal utility function: Full 4x4 transpose of __m256d -static inline void gmx_simdcall -avx256Transpose4By4(__m256d * v0, - __m256d * v1, - __m256d * v2, - __m256d * v3) +static inline void gmx_simdcall avx256Transpose4By4(__m256d* v0, __m256d* v1, __m256d* v2, __m256d* v3) { __m256d t1 = _mm256_unpacklo_pd(*v0, *v1); __m256d t2 = _mm256_unpackhi_pd(*v0, *v1); @@ -68,32 +64,28 @@ avx256Transpose4By4(__m256d * v0, *v3 = _mm256_permute2f128_pd(t2, t4, 0x31); } -template -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { assert(std::size_t(offset) % 16 == 0); assert(std::size_t(base) % 32 == 0); assert(align % 4 == 0); - v0->simdInternal_ = _mm256_load_pd( base + align * offset[0] ); - v1->simdInternal_ = _mm256_load_pd( base + align * offset[1] ); - v2->simdInternal_ = _mm256_load_pd( base + align * offset[2] ); - v3->simdInternal_ = _mm256_load_pd( base + align * offset[3] ); + v0->simdInternal_ = _mm256_load_pd(base + align * offset[0]); + v1->simdInternal_ = _mm256_load_pd(base + align * offset[1]); + v2->simdInternal_ = _mm256_load_pd(base + align * offset[2]); + v3->simdInternal_ = _mm256_load_pd(base + align * offset[3]); avx256Transpose4By4(&v0->simdInternal_, &v1->simdInternal_, &v2->simdInternal_, &v3->simdInternal_); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2, t3, t4; __m256d tA, tB; @@ -102,12 +94,12 @@ gatherLoadTranspose(const double * base, assert(std::size_t(base) % 16 == 0); assert(align % 2 == 0); - t1 = _mm_load_pd( base + align * offset[0] ); - t2 = _mm_load_pd( base + align * offset[1] ); - t3 = _mm_load_pd( base + align * offset[2] ); - t4 = _mm_load_pd( base + align * offset[3] ); - tA = _mm256_insertf128_pd(_mm256_castpd128_pd256(t1), t3, 0x1); - tB = _mm256_insertf128_pd(_mm256_castpd128_pd256(t2), t4, 0x1); + t1 = _mm_load_pd(base + align * offset[0]); + t2 = _mm_load_pd(base + align * offset[1]); + t3 = _mm_load_pd(base + align * offset[2]); + t4 = _mm_load_pd(base + align * offset[3]); + tA = _mm256_insertf128_pd(_mm256_castpd128_pd256(t1), t3, 0x1); + tB = _mm256_insertf128_pd(_mm256_castpd128_pd256(t2), t4, 0x1); v0->simdInternal_ = _mm256_unpacklo_pd(tA, tB); v1->simdInternal_ = _mm256_unpackhi_pd(tA, tB); @@ -119,30 +111,29 @@ static const int c_simdBestPairAlignmentDouble = 2; // For loading a triplet, we load 4 floats and ignore the last. Another thread // might write to this element, but that will not affect the result. // On AVX2 we can use a gather intrinsic instead. -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { assert(std::size_t(offset) % 16 == 0); __m256d t1, t2, t3, t4, t5, t6, t7, t8; if (align % 4 == 0) { - t1 = _mm256_load_pd(base + align * offset[0]); - t2 = _mm256_load_pd(base + align * offset[1]); - t3 = _mm256_load_pd(base + align * offset[2]); - t4 = _mm256_load_pd(base + align * offset[3]); + t1 = _mm256_load_pd(base + align * offset[0]); + t2 = _mm256_load_pd(base + align * offset[1]); + t3 = _mm256_load_pd(base + align * offset[2]); + t4 = _mm256_load_pd(base + align * offset[3]); } else { - t1 = _mm256_loadu_pd(base + align * offset[0]); - t2 = _mm256_loadu_pd(base + align * offset[1]); - t3 = _mm256_loadu_pd(base + align * offset[2]); - t4 = _mm256_loadu_pd(base + align * offset[3]); + t1 = _mm256_loadu_pd(base + align * offset[0]); + t2 = _mm256_loadu_pd(base + align * offset[1]); + t3 = _mm256_loadu_pd(base + align * offset[2]); + t4 = _mm256_loadu_pd(base + align * offset[3]); } t5 = _mm256_unpacklo_pd(t1, t2); t6 = _mm256_unpackhi_pd(t1, t2); @@ -153,13 +144,12 @@ gatherLoadUTranspose(const double * base, v2->simdInternal_ = _mm256_permute2f128_pd(t5, t7, 0x31); } -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { __m256d t0, t1, t2; @@ -184,13 +174,9 @@ transposeScatterStoreU(double * base, _mm_store_sd(base + align * offset[3] + 2, _mm256_extractf128_pd(t2, 0x1)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { __m256d t0, t1; __m128d t2, tA, tB; @@ -202,10 +188,14 @@ transposeScatterIncrU(double * base, // we can use aligned load/store t0 = _mm256_setzero_pd(); avx256Transpose4By4(&v0.simdInternal_, &v1.simdInternal_, &v2.simdInternal_, &t0); - _mm256_store_pd(base + align * offset[0], _mm256_add_pd(_mm256_load_pd(base + align * offset[0]), v0.simdInternal_)); - _mm256_store_pd(base + align * offset[1], _mm256_add_pd(_mm256_load_pd(base + align * offset[1]), v1.simdInternal_)); - _mm256_store_pd(base + align * offset[2], _mm256_add_pd(_mm256_load_pd(base + align * offset[2]), v2.simdInternal_)); - _mm256_store_pd(base + align * offset[3], _mm256_add_pd(_mm256_load_pd(base + align * offset[3]), t0)); + _mm256_store_pd(base + align * offset[0], + _mm256_add_pd(_mm256_load_pd(base + align * offset[0]), v0.simdInternal_)); + _mm256_store_pd(base + align * offset[1], + _mm256_add_pd(_mm256_load_pd(base + align * offset[1]), v1.simdInternal_)); + _mm256_store_pd(base + align * offset[2], + _mm256_add_pd(_mm256_load_pd(base + align * offset[2]), v2.simdInternal_)); + _mm256_store_pd(base + align * offset[3], + _mm256_add_pd(_mm256_load_pd(base + align * offset[3]), t0)); } else { @@ -246,13 +236,9 @@ transposeScatterIncrU(double * base, _mm_storeh_pd(base + align * offset[3] + 2, tB); } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { __m256d t0, t1; __m128d t2, tA, tB; @@ -264,10 +250,14 @@ transposeScatterDecrU(double * base, // we can use aligned load/store t0 = _mm256_setzero_pd(); avx256Transpose4By4(&v0.simdInternal_, &v1.simdInternal_, &v2.simdInternal_, &t0); - _mm256_store_pd(base + align * offset[0], _mm256_sub_pd(_mm256_load_pd(base + align * offset[0]), v0.simdInternal_)); - _mm256_store_pd(base + align * offset[1], _mm256_sub_pd(_mm256_load_pd(base + align * offset[1]), v1.simdInternal_)); - _mm256_store_pd(base + align * offset[2], _mm256_sub_pd(_mm256_load_pd(base + align * offset[2]), v2.simdInternal_)); - _mm256_store_pd(base + align * offset[3], _mm256_sub_pd(_mm256_load_pd(base + align * offset[3]), t0)); + _mm256_store_pd(base + align * offset[0], + _mm256_sub_pd(_mm256_load_pd(base + align * offset[0]), v0.simdInternal_)); + _mm256_store_pd(base + align * offset[1], + _mm256_sub_pd(_mm256_load_pd(base + align * offset[1]), v1.simdInternal_)); + _mm256_store_pd(base + align * offset[2], + _mm256_sub_pd(_mm256_load_pd(base + align * offset[2]), v2.simdInternal_)); + _mm256_store_pd(base + align * offset[3], + _mm256_sub_pd(_mm256_load_pd(base + align * offset[3]), t0)); } else { @@ -309,11 +299,10 @@ transposeScatterDecrU(double * base, } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { __m256d t0 = _mm256_permute2f128_pd(scalar.simdInternal_, scalar.simdInternal_, 0x21); __m256d t1 = _mm256_permute_pd(scalar.simdInternal_, 0b0000); @@ -323,20 +312,19 @@ expandScalarsToTriplets(SimdDouble scalar, triplets2->simdInternal_ = _mm256_blend_pd(t0, t2, 0b1100); } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 offset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { assert(std::size_t(base) % 32 == 0); assert(align % 4 == 0); alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; - _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_); + _mm_store_si128(reinterpret_cast<__m128i*>(ioffset), offset.simdInternal_); v0->simdInternal_ = _mm256_load_pd(base + align * ioffset[0]); v1->simdInternal_ = _mm256_load_pd(base + align * ioffset[1]); @@ -346,12 +334,9 @@ gatherLoadBySimdIntTranspose(const double * base, avx256Transpose4By4(&v0->simdInternal_, &v1->simdInternal_, &v2->simdInternal_, &v3->simdInternal_); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2, t3, t4; __m256d tA, tB; @@ -359,13 +344,13 @@ gatherLoadBySimdIntTranspose(const double * base, assert(std::size_t(base) % 16 == 0); assert(align % 2 == 0); - alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; - _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_); + alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; + _mm_store_si128(reinterpret_cast<__m128i*>(ioffset), offset.simdInternal_); - t1 = _mm_load_pd(base + align * ioffset[0]); - t2 = _mm_load_pd(base + align * ioffset[1]); - t3 = _mm_load_pd(base + align * ioffset[2]); - t4 = _mm_load_pd(base + align * ioffset[3]); + t1 = _mm_load_pd(base + align * ioffset[0]); + t2 = _mm_load_pd(base + align * ioffset[1]); + t3 = _mm_load_pd(base + align * ioffset[2]); + t4 = _mm_load_pd(base + align * ioffset[3]); tA = _mm256_insertf128_pd(_mm256_castpd128_pd256(t1), t3, 0x1); tB = _mm256_insertf128_pd(_mm256_castpd128_pd256(t2), t4, 0x1); @@ -373,37 +358,30 @@ gatherLoadBySimdIntTranspose(const double * base, v1->simdInternal_ = _mm256_unpackhi_pd(tA, tB); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2, t3, t4; __m256d tA, tB; alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_DINT32_WIDTH]; - _mm_store_si128( reinterpret_cast<__m128i *>(ioffset), offset.simdInternal_); + _mm_store_si128(reinterpret_cast<__m128i*>(ioffset), offset.simdInternal_); - t1 = _mm_loadu_pd(base + align * ioffset[0]); - t2 = _mm_loadu_pd(base + align * ioffset[1]); - t3 = _mm_loadu_pd(base + align * ioffset[2]); - t4 = _mm_loadu_pd(base + align * ioffset[3]); + t1 = _mm_loadu_pd(base + align * ioffset[0]); + t2 = _mm_loadu_pd(base + align * ioffset[1]); + t3 = _mm_loadu_pd(base + align * ioffset[2]); + t4 = _mm_loadu_pd(base + align * ioffset[3]); - tA = _mm256_insertf128_pd(_mm256_castpd128_pd256(t1), t3, 0x1); - tB = _mm256_insertf128_pd(_mm256_castpd128_pd256(t2), t4, 0x1); + tA = _mm256_insertf128_pd(_mm256_castpd128_pd256(t1), t3, 0x1); + tB = _mm256_insertf128_pd(_mm256_castpd128_pd256(t2), t4, 0x1); v0->simdInternal_ = _mm256_unpacklo_pd(tA, tB); v1->simdInternal_ = _mm256_unpackhi_pd(tA, tB); } static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __m256d t0, t1, t2; __m128d a0, a1; @@ -420,14 +398,14 @@ reduceIncr4ReturnSum(double * m, t1 = _mm256_add_pd(t0, _mm256_load_pd(m)); _mm256_store_pd(m, t1); - t0 = _mm256_add_pd(t0, _mm256_permute_pd(t0, 0b0101 )); - a0 = _mm256_castpd256_pd128(t0); - a1 = _mm256_extractf128_pd(t0, 0x1); - a0 = _mm_add_sd(a0, a1); + t0 = _mm256_add_pd(t0, _mm256_permute_pd(t0, 0b0101)); + a0 = _mm256_castpd256_pd128(t0); + a1 = _mm256_extractf128_pd(t0, 0x1); + a0 = _mm_add_sd(a0, a1); - return *reinterpret_cast(&a0); + return *reinterpret_cast(&a0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_float.h b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_float.h index bb7f2c6116..f6aadba6b8 100644 --- a/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_float.h +++ b/src/gromacs/simd/impl_x86_avx_256/impl_x86_avx_256_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,11 +66,7 @@ namespace gmx * * Here, - means undefined. Note that such values will not be zero! */ -static inline void gmx_simdcall -avx256Transpose3By4InLanes(__m256 * v0, - __m256 * v1, - __m256 * v2, - __m256 * v3) +static inline void gmx_simdcall avx256Transpose3By4InLanes(__m256* v0, __m256* v1, __m256* v2, __m256* v3) { __m256 t1 = _mm256_unpacklo_ps(*v0, *v1); __m256 t2 = _mm256_unpackhi_ps(*v0, *v1); @@ -80,14 +76,13 @@ avx256Transpose3By4InLanes(__m256 * v0, *v2 = _mm256_shuffle_ps(t2, *v2, _MM_SHUFFLE(0, 2, 1, 0)); } -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { __m128 t1, t2, t3, t4, t5, t6, t7, t8; __m256 tA, tB, tC, tD; @@ -96,24 +91,24 @@ gatherLoadTranspose(const float * base, assert(std::size_t(base) % 16 == 0); assert(align % 4 == 0); - t1 = _mm_load_ps( base + align * offset[0] ); - t2 = _mm_load_ps( base + align * offset[1] ); - t3 = _mm_load_ps( base + align * offset[2] ); - t4 = _mm_load_ps( base + align * offset[3] ); - t5 = _mm_load_ps( base + align * offset[4] ); - t6 = _mm_load_ps( base + align * offset[5] ); - t7 = _mm_load_ps( base + align * offset[6] ); - t8 = _mm_load_ps( base + align * offset[7] ); + t1 = _mm_load_ps(base + align * offset[0]); + t2 = _mm_load_ps(base + align * offset[1]); + t3 = _mm_load_ps(base + align * offset[2]); + t4 = _mm_load_ps(base + align * offset[3]); + t5 = _mm_load_ps(base + align * offset[4]); + t6 = _mm_load_ps(base + align * offset[5]); + t7 = _mm_load_ps(base + align * offset[6]); + t8 = _mm_load_ps(base + align * offset[7]); v0->simdInternal_ = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); v1->simdInternal_ = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); v2->simdInternal_ = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); v3->simdInternal_ = _mm256_insertf128_ps(_mm256_castps128_ps256(t4), t8, 0x1); - tA = _mm256_unpacklo_ps(v0->simdInternal_, v1->simdInternal_); - tB = _mm256_unpacklo_ps(v2->simdInternal_, v3->simdInternal_); - tC = _mm256_unpackhi_ps(v0->simdInternal_, v1->simdInternal_); - tD = _mm256_unpackhi_ps(v2->simdInternal_, v3->simdInternal_); + tA = _mm256_unpacklo_ps(v0->simdInternal_, v1->simdInternal_); + tB = _mm256_unpacklo_ps(v2->simdInternal_, v3->simdInternal_); + tC = _mm256_unpackhi_ps(v0->simdInternal_, v1->simdInternal_); + tD = _mm256_unpackhi_ps(v2->simdInternal_, v3->simdInternal_); v0->simdInternal_ = _mm256_shuffle_ps(tA, tB, _MM_SHUFFLE(1, 0, 1, 0)); v1->simdInternal_ = _mm256_shuffle_ps(tA, tB, _MM_SHUFFLE(3, 2, 3, 2)); @@ -121,12 +116,9 @@ gatherLoadTranspose(const float * base, v3->simdInternal_ = _mm256_shuffle_ps(tC, tD, _MM_SHUFFLE(3, 2, 3, 2)); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { __m128 t1, t2, t3, t4, t5, t6, t7, t8; __m256 tA, tB, tC, tD; @@ -135,19 +127,19 @@ gatherLoadTranspose(const float * base, assert(std::size_t(base) % 8 == 0); assert(align % 2 == 0); - t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[0] ) ); - t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[1] ) ); - t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[2] ) ); - t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[3] ) ); - t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[4] ) ); - t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[5] ) ); - t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[6] ) ); - t8 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[7] ) ); + t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[0])); + t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[1])); + t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[2])); + t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[3])); + t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[4])); + t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[5])); + t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[6])); + t8 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[7])); - tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); - tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); - tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); - tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t4), t8, 0x1); + tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); + tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); + tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); + tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t4), t8, 0x1); tA = _mm256_unpacklo_ps(tA, tC); tB = _mm256_unpacklo_ps(tB, tD); @@ -161,15 +153,14 @@ static const int c_simdBestPairAlignmentFloat = 2; // For loading a triplet, we load 4 floats and ignore the last. Another thread // might write to this element, but that will not affect the result. // On AVX2 we can use a gather intrinsic instead. -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { - __m256 t1, t2, t3, t4, t5, t6, t7, t8; + __m256 t1, t2, t3, t4, t5, t6, t7, t8; assert(std::size_t(offset) % 32 == 0); @@ -177,26 +168,26 @@ gatherLoadUTranspose(const float * base, { // we can use aligned loads since base should also be aligned in this case assert(std::size_t(base) % 16 == 0); - t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps( base + align * offset[0] )), - _mm_load_ps( base + align * offset[4] ), 0x1); - t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[1] )), - _mm_load_ps( base + align * offset[5] ), 0x1); - t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[2] )), - _mm_load_ps( base + align * offset[6] ), 0x1); - t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[3] )), - _mm_load_ps( base + align * offset[7] ), 0x1); + t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[0])), + _mm_load_ps(base + align * offset[4]), 0x1); + t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[1])), + _mm_load_ps(base + align * offset[5]), 0x1); + t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[2])), + _mm_load_ps(base + align * offset[6]), 0x1); + t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(base + align * offset[3])), + _mm_load_ps(base + align * offset[7]), 0x1); } else { // Use unaligned loads - t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps( base + align * offset[0] )), - _mm_loadu_ps( base + align * offset[4] ), 0x1); - t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[1] )), - _mm_loadu_ps( base + align * offset[5] ), 0x1); - t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[2] )), - _mm_loadu_ps( base + align * offset[6] ), 0x1); - t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[3] )), - _mm_loadu_ps( base + align * offset[7] ), 0x1); + t1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[0])), + _mm_loadu_ps(base + align * offset[4]), 0x1); + t2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[1])), + _mm_loadu_ps(base + align * offset[5]), 0x1); + t3 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[2])), + _mm_loadu_ps(base + align * offset[6]), 0x1); + t4 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(base + align * offset[3])), + _mm_loadu_ps(base + align * offset[7]), 0x1); } t5 = _mm256_unpacklo_ps(t1, t2); @@ -208,13 +199,9 @@ gatherLoadUTranspose(const float * base, v2->simdInternal_ = _mm256_shuffle_ps(t7, t8, _MM_SHUFFLE(1, 0, 1, 0)); } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __m256 tv3; __m128i mask = _mm_set_epi32(0, -1, -1, -1); @@ -222,253 +209,276 @@ transposeScatterStoreU(float * base, assert(std::size_t(offset) % 32 == 0); avx256Transpose3By4InLanes(&v0.simdInternal_, &v1.simdInternal_, &v2.simdInternal_, &tv3); - _mm_maskstore_ps( base + align * offset[0], mask, _mm256_castps256_ps128(v0.simdInternal_)); - _mm_maskstore_ps( base + align * offset[1], mask, _mm256_castps256_ps128(v1.simdInternal_)); - _mm_maskstore_ps( base + align * offset[2], mask, _mm256_castps256_ps128(v2.simdInternal_)); - _mm_maskstore_ps( base + align * offset[3], mask, _mm256_castps256_ps128(tv3)); - _mm_maskstore_ps( base + align * offset[4], mask, _mm256_extractf128_ps(v0.simdInternal_, 0x1)); - _mm_maskstore_ps( base + align * offset[5], mask, _mm256_extractf128_ps(v1.simdInternal_, 0x1)); - _mm_maskstore_ps( base + align * offset[6], mask, _mm256_extractf128_ps(v2.simdInternal_, 0x1)); - _mm_maskstore_ps( base + align * offset[7], mask, _mm256_extractf128_ps(tv3, 0x1)); + _mm_maskstore_ps(base + align * offset[0], mask, _mm256_castps256_ps128(v0.simdInternal_)); + _mm_maskstore_ps(base + align * offset[1], mask, _mm256_castps256_ps128(v1.simdInternal_)); + _mm_maskstore_ps(base + align * offset[2], mask, _mm256_castps256_ps128(v2.simdInternal_)); + _mm_maskstore_ps(base + align * offset[3], mask, _mm256_castps256_ps128(tv3)); + _mm_maskstore_ps(base + align * offset[4], mask, _mm256_extractf128_ps(v0.simdInternal_, 0x1)); + _mm_maskstore_ps(base + align * offset[5], mask, _mm256_extractf128_ps(v1.simdInternal_, 0x1)); + _mm_maskstore_ps(base + align * offset[6], mask, _mm256_extractf128_ps(v2.simdInternal_, 0x1)); + _mm_maskstore_ps(base + align * offset[7], mask, _mm256_extractf128_ps(tv3, 0x1)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __m256 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; __m128 tA, tB, tC, tD, tE, tF, tG, tH, tX; if (align < 4) { - t5 = _mm256_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); - t6 = _mm256_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); - t7 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); - t8 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); - t9 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); - t10 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); - - tA = _mm256_castps256_ps128(t7); - tB = _mm256_castps256_ps128(t8); - tC = _mm256_castps256_ps128(t9); - tD = _mm256_castps256_ps128(t10); - tE = _mm256_extractf128_ps(t7, 0x1); - tF = _mm256_extractf128_ps(t8, 0x1); - tG = _mm256_extractf128_ps(t9, 0x1); - tH = _mm256_extractf128_ps(t10, 0x1); - - tX = _mm_load_ss(base + align * offset[0]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[0] + 1)); - tX = _mm_add_ps(tX, tA); + t5 = _mm256_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); + t6 = _mm256_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); + t7 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); + t8 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); + t9 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); + t10 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); + + tA = _mm256_castps256_ps128(t7); + tB = _mm256_castps256_ps128(t8); + tC = _mm256_castps256_ps128(t9); + tD = _mm256_castps256_ps128(t10); + tE = _mm256_extractf128_ps(t7, 0x1); + tF = _mm256_extractf128_ps(t8, 0x1); + tG = _mm256_extractf128_ps(t9, 0x1); + tH = _mm256_extractf128_ps(t10, 0x1); + + tX = _mm_load_ss(base + align * offset[0]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[0] + 1)); + tX = _mm_add_ps(tX, tA); _mm_store_ss(base + align * offset[0], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[0] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[0] + 1), tX); - tX = _mm_load_ss(base + align * offset[1]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[1] + 1)); - tX = _mm_add_ps(tX, tB); + tX = _mm_load_ss(base + align * offset[1]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[1] + 1)); + tX = _mm_add_ps(tX, tB); _mm_store_ss(base + align * offset[1], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[1] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1] + 1), tX); - tX = _mm_load_ss(base + align * offset[2]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[2] + 1)); - tX = _mm_add_ps(tX, tC); + tX = _mm_load_ss(base + align * offset[2]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[2] + 1)); + tX = _mm_add_ps(tX, tC); _mm_store_ss(base + align * offset[2], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[2] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[2] + 1), tX); - tX = _mm_load_ss(base + align * offset[3]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[3] + 1)); - tX = _mm_add_ps(tX, tD); + tX = _mm_load_ss(base + align * offset[3]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[3] + 1)); + tX = _mm_add_ps(tX, tD); _mm_store_ss(base + align * offset[3], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[3] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[3] + 1), tX); - tX = _mm_load_ss(base + align * offset[4]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[4] + 1)); - tX = _mm_add_ps(tX, tE); + tX = _mm_load_ss(base + align * offset[4]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[4] + 1)); + tX = _mm_add_ps(tX, tE); _mm_store_ss(base + align * offset[4], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[4] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[4] + 1), tX); - tX = _mm_load_ss(base + align * offset[5]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[5] + 1)); - tX = _mm_add_ps(tX, tF); + tX = _mm_load_ss(base + align * offset[5]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[5] + 1)); + tX = _mm_add_ps(tX, tF); _mm_store_ss(base + align * offset[5], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[5] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[5] + 1), tX); - tX = _mm_load_ss(base + align * offset[6]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[6] + 1)); - tX = _mm_add_ps(tX, tG); + tX = _mm_load_ss(base + align * offset[6]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[6] + 1)); + tX = _mm_add_ps(tX, tG); _mm_store_ss(base + align * offset[6], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[6] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[6] + 1), tX); - tX = _mm_load_ss(base + align * offset[7]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[7] + 1)); - tX = _mm_add_ps(tX, tH); + tX = _mm_load_ss(base + align * offset[7]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[7] + 1)); + tX = _mm_add_ps(tX, tH); _mm_store_ss(base + align * offset[7], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[7] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[7] + 1), tX); } else { // Extra elements means we can use full width-4 load/store operations - t1 = _mm256_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); - t2 = _mm256_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); - t3 = _mm256_unpacklo_ps(v1.simdInternal_, _mm256_setzero_ps()); - t4 = _mm256_unpackhi_ps(v1.simdInternal_, _mm256_setzero_ps()); - t5 = _mm256_unpacklo_ps(t1, t3); // x0 y0 z0 0 | x4 y4 z4 0 - t6 = _mm256_unpackhi_ps(t1, t3); // x1 y1 z1 0 | x5 y5 z5 0 - t7 = _mm256_unpacklo_ps(t2, t4); // x2 y2 z2 0 | x6 y6 z6 0 - t8 = _mm256_unpackhi_ps(t2, t4); // x3 y3 z3 0 | x7 y7 z7 0 + t1 = _mm256_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); + t2 = _mm256_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); + t3 = _mm256_unpacklo_ps(v1.simdInternal_, _mm256_setzero_ps()); + t4 = _mm256_unpackhi_ps(v1.simdInternal_, _mm256_setzero_ps()); + t5 = _mm256_unpacklo_ps(t1, t3); // x0 y0 z0 0 | x4 y4 z4 0 + t6 = _mm256_unpackhi_ps(t1, t3); // x1 y1 z1 0 | x5 y5 z5 0 + t7 = _mm256_unpacklo_ps(t2, t4); // x2 y2 z2 0 | x6 y6 z6 0 + t8 = _mm256_unpackhi_ps(t2, t4); // x3 y3 z3 0 | x7 y7 z7 0 if (align % 4 == 0) { // We can use aligned load & store - _mm_store_ps(base + align * offset[0], _mm_add_ps(_mm_load_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); - _mm_store_ps(base + align * offset[1], _mm_add_ps(_mm_load_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); - _mm_store_ps(base + align * offset[2], _mm_add_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); - _mm_store_ps(base + align * offset[3], _mm_add_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); - _mm_store_ps(base + align * offset[4], _mm_add_ps(_mm_load_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1))); - _mm_store_ps(base + align * offset[5], _mm_add_ps(_mm_load_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1))); - _mm_store_ps(base + align * offset[6], _mm_add_ps(_mm_load_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1))); - _mm_store_ps(base + align * offset[7], _mm_add_ps(_mm_load_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1))); + _mm_store_ps(base + align * offset[0], + _mm_add_ps(_mm_load_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); + _mm_store_ps(base + align * offset[1], + _mm_add_ps(_mm_load_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); + _mm_store_ps(base + align * offset[2], + _mm_add_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); + _mm_store_ps(base + align * offset[3], + _mm_add_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); + _mm_store_ps(base + align * offset[4], _mm_add_ps(_mm_load_ps(base + align * offset[4]), + _mm256_extractf128_ps(t5, 0x1))); + _mm_store_ps(base + align * offset[5], _mm_add_ps(_mm_load_ps(base + align * offset[5]), + _mm256_extractf128_ps(t6, 0x1))); + _mm_store_ps(base + align * offset[6], _mm_add_ps(_mm_load_ps(base + align * offset[6]), + _mm256_extractf128_ps(t7, 0x1))); + _mm_store_ps(base + align * offset[7], _mm_add_ps(_mm_load_ps(base + align * offset[7]), + _mm256_extractf128_ps(t8, 0x1))); } else { // alignment >=5, but not a multiple of 4 - _mm_storeu_ps(base + align * offset[0], _mm_add_ps(_mm_loadu_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); - _mm_storeu_ps(base + align * offset[1], _mm_add_ps(_mm_loadu_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); - _mm_storeu_ps(base + align * offset[2], _mm_add_ps(_mm_loadu_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); - _mm_storeu_ps(base + align * offset[3], _mm_add_ps(_mm_loadu_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); - _mm_storeu_ps(base + align * offset[4], _mm_add_ps(_mm_loadu_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1))); - _mm_storeu_ps(base + align * offset[5], _mm_add_ps(_mm_loadu_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1))); - _mm_storeu_ps(base + align * offset[6], _mm_add_ps(_mm_loadu_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1))); - _mm_storeu_ps(base + align * offset[7], _mm_add_ps(_mm_loadu_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1))); + _mm_storeu_ps(base + align * offset[0], _mm_add_ps(_mm_loadu_ps(base + align * offset[0]), + _mm256_castps256_ps128(t5))); + _mm_storeu_ps(base + align * offset[1], _mm_add_ps(_mm_loadu_ps(base + align * offset[1]), + _mm256_castps256_ps128(t6))); + _mm_storeu_ps(base + align * offset[2], _mm_add_ps(_mm_loadu_ps(base + align * offset[2]), + _mm256_castps256_ps128(t7))); + _mm_storeu_ps(base + align * offset[3], _mm_add_ps(_mm_loadu_ps(base + align * offset[3]), + _mm256_castps256_ps128(t8))); + _mm_storeu_ps(base + align * offset[4], _mm_add_ps(_mm_loadu_ps(base + align * offset[4]), + _mm256_extractf128_ps(t5, 0x1))); + _mm_storeu_ps(base + align * offset[5], _mm_add_ps(_mm_loadu_ps(base + align * offset[5]), + _mm256_extractf128_ps(t6, 0x1))); + _mm_storeu_ps(base + align * offset[6], _mm_add_ps(_mm_loadu_ps(base + align * offset[6]), + _mm256_extractf128_ps(t7, 0x1))); + _mm_storeu_ps(base + align * offset[7], _mm_add_ps(_mm_loadu_ps(base + align * offset[7]), + _mm256_extractf128_ps(t8, 0x1))); } } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __m256 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; __m128 tA, tB, tC, tD, tE, tF, tG, tH, tX; if (align < 4) { - t5 = _mm256_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); - t6 = _mm256_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); - t7 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); - t8 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); - t9 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); - t10 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); - - tA = _mm256_castps256_ps128(t7); - tB = _mm256_castps256_ps128(t8); - tC = _mm256_castps256_ps128(t9); - tD = _mm256_castps256_ps128(t10); - tE = _mm256_extractf128_ps(t7, 0x1); - tF = _mm256_extractf128_ps(t8, 0x1); - tG = _mm256_extractf128_ps(t9, 0x1); - tH = _mm256_extractf128_ps(t10, 0x1); - - tX = _mm_load_ss(base + align * offset[0]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[0] + 1)); - tX = _mm_sub_ps(tX, tA); + t5 = _mm256_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); + t6 = _mm256_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); + t7 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); + t8 = _mm256_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); + t9 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); + t10 = _mm256_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); + + tA = _mm256_castps256_ps128(t7); + tB = _mm256_castps256_ps128(t8); + tC = _mm256_castps256_ps128(t9); + tD = _mm256_castps256_ps128(t10); + tE = _mm256_extractf128_ps(t7, 0x1); + tF = _mm256_extractf128_ps(t8, 0x1); + tG = _mm256_extractf128_ps(t9, 0x1); + tH = _mm256_extractf128_ps(t10, 0x1); + + tX = _mm_load_ss(base + align * offset[0]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[0] + 1)); + tX = _mm_sub_ps(tX, tA); _mm_store_ss(base + align * offset[0], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[0] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[0] + 1), tX); - tX = _mm_load_ss(base + align * offset[1]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[1] + 1)); - tX = _mm_sub_ps(tX, tB); + tX = _mm_load_ss(base + align * offset[1]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[1] + 1)); + tX = _mm_sub_ps(tX, tB); _mm_store_ss(base + align * offset[1], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[1] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1] + 1), tX); - tX = _mm_load_ss(base + align * offset[2]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[2] + 1)); - tX = _mm_sub_ps(tX, tC); + tX = _mm_load_ss(base + align * offset[2]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[2] + 1)); + tX = _mm_sub_ps(tX, tC); _mm_store_ss(base + align * offset[2], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[2] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[2] + 1), tX); - tX = _mm_load_ss(base + align * offset[3]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[3] + 1)); - tX = _mm_sub_ps(tX, tD); + tX = _mm_load_ss(base + align * offset[3]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[3] + 1)); + tX = _mm_sub_ps(tX, tD); _mm_store_ss(base + align * offset[3], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[3] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[3] + 1), tX); - tX = _mm_load_ss(base + align * offset[4]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[4] + 1)); - tX = _mm_sub_ps(tX, tE); + tX = _mm_load_ss(base + align * offset[4]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[4] + 1)); + tX = _mm_sub_ps(tX, tE); _mm_store_ss(base + align * offset[4], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[4] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[4] + 1), tX); - tX = _mm_load_ss(base + align * offset[5]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[5] + 1)); - tX = _mm_sub_ps(tX, tF); + tX = _mm_load_ss(base + align * offset[5]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[5] + 1)); + tX = _mm_sub_ps(tX, tF); _mm_store_ss(base + align * offset[5], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[5] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[5] + 1), tX); - tX = _mm_load_ss(base + align * offset[6]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[6] + 1)); - tX = _mm_sub_ps(tX, tG); + tX = _mm_load_ss(base + align * offset[6]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[6] + 1)); + tX = _mm_sub_ps(tX, tG); _mm_store_ss(base + align * offset[6], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[6] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[6] + 1), tX); - tX = _mm_load_ss(base + align * offset[7]); - tX = _mm_loadh_pi(tX, reinterpret_cast< __m64 *>(base + align * offset[7] + 1)); - tX = _mm_sub_ps(tX, tH); + tX = _mm_load_ss(base + align * offset[7]); + tX = _mm_loadh_pi(tX, reinterpret_cast<__m64*>(base + align * offset[7] + 1)); + tX = _mm_sub_ps(tX, tH); _mm_store_ss(base + align * offset[7], tX); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[7] + 1), tX); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[7] + 1), tX); } else { // Extra elements means we can use full width-4 load/store operations - t1 = _mm256_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); - t2 = _mm256_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); - t3 = _mm256_unpacklo_ps(v1.simdInternal_, _mm256_setzero_ps()); - t4 = _mm256_unpackhi_ps(v1.simdInternal_, _mm256_setzero_ps()); - t5 = _mm256_unpacklo_ps(t1, t3); // x0 y0 z0 0 | x4 y4 z4 0 - t6 = _mm256_unpackhi_ps(t1, t3); // x1 y1 z1 0 | x5 y5 z5 0 - t7 = _mm256_unpacklo_ps(t2, t4); // x2 y2 z2 0 | x6 y6 z6 0 - t8 = _mm256_unpackhi_ps(t2, t4); // x3 y3 z3 0 | x7 y7 z7 0 + t1 = _mm256_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); + t2 = _mm256_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); + t3 = _mm256_unpacklo_ps(v1.simdInternal_, _mm256_setzero_ps()); + t4 = _mm256_unpackhi_ps(v1.simdInternal_, _mm256_setzero_ps()); + t5 = _mm256_unpacklo_ps(t1, t3); // x0 y0 z0 0 | x4 y4 z4 0 + t6 = _mm256_unpackhi_ps(t1, t3); // x1 y1 z1 0 | x5 y5 z5 0 + t7 = _mm256_unpacklo_ps(t2, t4); // x2 y2 z2 0 | x6 y6 z6 0 + t8 = _mm256_unpackhi_ps(t2, t4); // x3 y3 z3 0 | x7 y7 z7 0 if (align % 4 == 0) { // We can use aligned load & store - _mm_store_ps(base + align * offset[0], _mm_sub_ps(_mm_load_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); - _mm_store_ps(base + align * offset[1], _mm_sub_ps(_mm_load_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); - _mm_store_ps(base + align * offset[2], _mm_sub_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); - _mm_store_ps(base + align * offset[3], _mm_sub_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); - _mm_store_ps(base + align * offset[4], _mm_sub_ps(_mm_load_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1))); - _mm_store_ps(base + align * offset[5], _mm_sub_ps(_mm_load_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1))); - _mm_store_ps(base + align * offset[6], _mm_sub_ps(_mm_load_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1))); - _mm_store_ps(base + align * offset[7], _mm_sub_ps(_mm_load_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1))); + _mm_store_ps(base + align * offset[0], + _mm_sub_ps(_mm_load_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); + _mm_store_ps(base + align * offset[1], + _mm_sub_ps(_mm_load_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); + _mm_store_ps(base + align * offset[2], + _mm_sub_ps(_mm_load_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); + _mm_store_ps(base + align * offset[3], + _mm_sub_ps(_mm_load_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); + _mm_store_ps(base + align * offset[4], _mm_sub_ps(_mm_load_ps(base + align * offset[4]), + _mm256_extractf128_ps(t5, 0x1))); + _mm_store_ps(base + align * offset[5], _mm_sub_ps(_mm_load_ps(base + align * offset[5]), + _mm256_extractf128_ps(t6, 0x1))); + _mm_store_ps(base + align * offset[6], _mm_sub_ps(_mm_load_ps(base + align * offset[6]), + _mm256_extractf128_ps(t7, 0x1))); + _mm_store_ps(base + align * offset[7], _mm_sub_ps(_mm_load_ps(base + align * offset[7]), + _mm256_extractf128_ps(t8, 0x1))); } else { // alignment >=5, but not a multiple of 4 - _mm_storeu_ps(base + align * offset[0], _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]), _mm256_castps256_ps128(t5))); - _mm_storeu_ps(base + align * offset[1], _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]), _mm256_castps256_ps128(t6))); - _mm_storeu_ps(base + align * offset[2], _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]), _mm256_castps256_ps128(t7))); - _mm_storeu_ps(base + align * offset[3], _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]), _mm256_castps256_ps128(t8))); - _mm_storeu_ps(base + align * offset[4], _mm_sub_ps(_mm_loadu_ps(base + align * offset[4]), _mm256_extractf128_ps(t5, 0x1))); - _mm_storeu_ps(base + align * offset[5], _mm_sub_ps(_mm_loadu_ps(base + align * offset[5]), _mm256_extractf128_ps(t6, 0x1))); - _mm_storeu_ps(base + align * offset[6], _mm_sub_ps(_mm_loadu_ps(base + align * offset[6]), _mm256_extractf128_ps(t7, 0x1))); - _mm_storeu_ps(base + align * offset[7], _mm_sub_ps(_mm_loadu_ps(base + align * offset[7]), _mm256_extractf128_ps(t8, 0x1))); + _mm_storeu_ps(base + align * offset[0], _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]), + _mm256_castps256_ps128(t5))); + _mm_storeu_ps(base + align * offset[1], _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]), + _mm256_castps256_ps128(t6))); + _mm_storeu_ps(base + align * offset[2], _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]), + _mm256_castps256_ps128(t7))); + _mm_storeu_ps(base + align * offset[3], _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]), + _mm256_castps256_ps128(t8))); + _mm_storeu_ps(base + align * offset[4], _mm_sub_ps(_mm_loadu_ps(base + align * offset[4]), + _mm256_extractf128_ps(t5, 0x1))); + _mm_storeu_ps(base + align * offset[5], _mm_sub_ps(_mm_loadu_ps(base + align * offset[5]), + _mm256_extractf128_ps(t6, 0x1))); + _mm_storeu_ps(base + align * offset[6], _mm_sub_ps(_mm_loadu_ps(base + align * offset[6]), + _mm256_extractf128_ps(t7, 0x1))); + _mm_storeu_ps(base + align * offset[7], _mm_sub_ps(_mm_loadu_ps(base + align * offset[7]), + _mm256_extractf128_ps(t8, 0x1))); } } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { __m256 t0 = _mm256_permute2f128_ps(scalar.simdInternal_, scalar.simdInternal_, 0x21); __m256 t1 = _mm256_permute_ps(scalar.simdInternal_, _MM_SHUFFLE(1, 0, 0, 0)); @@ -479,59 +489,52 @@ expandScalarsToTriplets(SimdFloat scalar, triplets2->simdInternal_ = _mm256_blend_ps(t2, t3, 0xF0); } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 simdoffset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; - _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_); + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; + _mm256_store_si256(reinterpret_cast<__m256i*>(offset), simdoffset.simdInternal_); gatherLoadTranspose(base, offset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; - _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_); + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; + _mm256_store_si256(reinterpret_cast<__m256i*>(offset), simdoffset.simdInternal_); gatherLoadTranspose(base, offset, v0, v1); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1) { __m128 t1, t2, t3, t4, t5, t6, t7, t8; __m256 tA, tB, tC, tD; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; - _mm256_store_si256( reinterpret_cast<__m256i *>(offset), simdoffset.simdInternal_); + alignas(GMX_SIMD_ALIGNMENT) std::int32_t offset[GMX_SIMD_FLOAT_WIDTH]; + _mm256_store_si256(reinterpret_cast<__m256i*>(offset), simdoffset.simdInternal_); - t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[0] ) ); - t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[1] ) ); - t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[2] ) ); - t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[3] ) ); - t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[4] ) ); - t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[5] ) ); - t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[6] ) ); - t8 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast( base + align * offset[7] ) ); + t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[0])); + t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[1])); + t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[2])); + t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[3])); + t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[4])); + t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[5])); + t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[6])); + t8 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base + align * offset[7])); - tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); - tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); - tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); - tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t4), t8, 0x1); + tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); + tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); + tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); + tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t4), t8, 0x1); tA = _mm256_unpacklo_ps(tA, tC); tB = _mm256_unpacklo_ps(tB, tD); @@ -539,12 +542,7 @@ gatherLoadUBySimdIntTranspose(const float * base, v1->simdInternal_ = _mm256_unpackhi_ps(tA, tB); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { __m128 t0, t2; @@ -560,51 +558,38 @@ reduceIncr4ReturnSum(float * m, t0 = _mm_add_ps(t0, _mm_permute_ps(t0, _MM_SHUFFLE(1, 0, 3, 2))); t0 = _mm_add_ss(t0, _mm_permute_ps(t0, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&t0); + return *reinterpret_cast(&t0); } /************************************* * Half-simd-width utility functions * *************************************/ -static inline SimdFloat gmx_simdcall -loadDualHsimd(const float * m0, - const float * m1) +static inline SimdFloat gmx_simdcall loadDualHsimd(const float* m0, const float* m1) { assert(std::size_t(m0) % 16 == 0); assert(std::size_t(m1) % 16 == 0); - return { - _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(m0)), _mm_load_ps(m1), 0x1) - }; + return { _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_load_ps(m0)), _mm_load_ps(m1), 0x1) }; } -static inline SimdFloat gmx_simdcall -loadDuplicateHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m) { assert(std::size_t(m) % 16 == 0); - return { - _mm256_broadcast_ps(reinterpret_cast(m)) - }; + return { _mm256_broadcast_ps(reinterpret_cast(m)) }; } -static inline SimdFloat gmx_simdcall -loadU1DualHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m) { __m128 t0, t1; t0 = _mm_broadcast_ss(m); - t1 = _mm_broadcast_ss(m+1); - return { - _mm256_insertf128_ps(_mm256_castps128_ps256(t0), t1, 0x1) - }; + t1 = _mm_broadcast_ss(m + 1); + return { _mm256_insertf128_ps(_mm256_castps128_ps256(t0), t1, 0x1) }; } -static inline void gmx_simdcall -storeDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall storeDualHsimd(float* m0, float* m1, SimdFloat a) { assert(std::size_t(m0) % 16 == 0); assert(std::size_t(m1) % 16 == 0); @@ -612,10 +597,7 @@ storeDualHsimd(float * m0, _mm_store_ps(m1, _mm256_extractf128_ps(a.simdInternal_, 0x1)); } -static inline void gmx_simdcall -incrDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall incrDualHsimd(float* m0, float* m1, SimdFloat a) { assert(std::size_t(m0) % 16 == 0); assert(std::size_t(m1) % 16 == 0); @@ -623,23 +605,21 @@ incrDualHsimd(float * m0, _mm_store_ps(m1, _mm_add_ps(_mm256_extractf128_ps(a.simdInternal_, 0x1), _mm_load_ps(m1))); } -static inline void gmx_simdcall -decrHsimd(float * m, - SimdFloat a) +static inline void gmx_simdcall decrHsimd(float* m, SimdFloat a) { assert(std::size_t(m) % 16 == 0); - __m128 asum = _mm_add_ps(_mm256_castps256_ps128(a.simdInternal_), _mm256_extractf128_ps(a.simdInternal_, 0x1)); + __m128 asum = _mm_add_ps(_mm256_castps256_ps128(a.simdInternal_), + _mm256_extractf128_ps(a.simdInternal_, 0x1)); _mm_store_ps(m, _mm_sub_ps(_mm_load_ps(m), asum)); } -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const float * base0, - const float * base1, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const float* base0, + const float* base1, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1) { __m128 t0, t1, t2, t3, t4, t5, t6, t7; __m256 tA, tB, tC, tD; @@ -649,19 +629,19 @@ gatherLoadTransposeHsimd(const float * base0, assert(std::size_t(base1) % 8 == 0); assert(align % 2 == 0); - t0 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[0])); - t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[1])); - t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[2])); - t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[3])); - t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[0])); - t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[1])); - t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[2])); - t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[3])); + t0 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[0])); + t1 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[1])); + t2 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[2])); + t3 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base0 + align * offset[3])); + t4 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[0])); + t5 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[1])); + t6 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[2])); + t7 = _mm_loadl_pi(_mm_setzero_ps(), reinterpret_cast(base1 + align * offset[3])); - tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t0), t4, 0x1); - tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); - tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); - tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); + tA = _mm256_insertf128_ps(_mm256_castps128_ps256(t0), t4, 0x1); + tB = _mm256_insertf128_ps(_mm256_castps128_ps256(t1), t5, 0x1); + tC = _mm256_insertf128_ps(_mm256_castps128_ps256(t2), t6, 0x1); + tD = _mm256_insertf128_ps(_mm256_castps128_ps256(t3), t7, 0x1); tA = _mm256_unpacklo_ps(tA, tC); tB = _mm256_unpacklo_ps(tB, tD); @@ -670,10 +650,7 @@ gatherLoadTransposeHsimd(const float * base0, } -static inline float gmx_simdcall -reduceIncr4ReturnSumHsimd(float * m, - SimdFloat v0, - SimdFloat v1) +static inline float gmx_simdcall reduceIncr4ReturnSumHsimd(float* m, SimdFloat v0, SimdFloat v1) { __m128 t0, t1; @@ -684,23 +661,20 @@ reduceIncr4ReturnSumHsimd(float * m, assert(std::size_t(m) % 16 == 0); - t1 = _mm_add_ps(t0, _mm_load_ps(m)); + t1 = _mm_add_ps(t0, _mm_load_ps(m)); _mm_store_ps(m, t1); t0 = _mm_add_ps(t0, _mm_permute_ps(t0, _MM_SHUFFLE(1, 0, 3, 2))); t0 = _mm_add_ss(t0, _mm_permute_ps(t0, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&t0); + return *reinterpret_cast(&t0); } -static inline SimdFloat gmx_simdcall -loadU4NOffset(const float *m, int offset) +static inline SimdFloat gmx_simdcall loadU4NOffset(const float* m, int offset) { - return { - _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(m)), _mm_loadu_ps(m+offset), 0x1) - }; + return { _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(m)), _mm_loadu_ps(m + offset), 0x1) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_256_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512.h index 952816b116..c88d8161db 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,5 +46,4 @@ #include "impl_x86_avx_512_util_float.h" - #endif // GMX_SIMD_IMPL_X86_AVX_512_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_definitions.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_definitions.h index 27e1c807c8..3a173dc40d 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_definitions.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,52 +49,52 @@ // can specify a rounding mode also appear to be buggy. We conditionally work // around this by using conversions to/from integer instead. -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 // Technically it is straightforward to emulate extract on AVX-512 through // memory operations, but when applied to 16 elements as part of a table lookup // it will be faster to just store the entire vector once, so we avoid setting it. -#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 16 -#define GMX_SIMD_DOUBLE_WIDTH 8 -#define GMX_SIMD_FINT32_WIDTH 16 -#define GMX_SIMD_DINT32_WIDTH 8 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) -#define GMX_SIMD_RSQRT_BITS 14 -#define GMX_SIMD_RCP_BITS 14 +#define GMX_SIMD_FLOAT_WIDTH 16 +#define GMX_SIMD_DOUBLE_WIDTH 8 +#define GMX_SIMD_FINT32_WIDTH 16 +#define GMX_SIMD_DINT32_WIDTH 8 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) +#define GMX_SIMD_RSQRT_BITS 14 +#define GMX_SIMD_RCP_BITS 14 #endif // GMX_SIMD_IMPL_X86_AVX_512_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_general.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_general.h index 6eb2457fd9..f1a0e8e82d 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_general.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,10 +41,9 @@ namespace gmx { -static inline void -simdPrefetch(const void * m) +static inline void simdPrefetch(const void* m) { - _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); } /*! \brief Return integer from AVX-512 mask @@ -53,8 +52,7 @@ simdPrefetch(const void * m) * * \return Short integer representation of mask */ -static inline short -avx512Mask2Int(__mmask16 m) +static inline short avx512Mask2Int(__mmask16 m) { return static_cast(m); } @@ -65,12 +63,11 @@ avx512Mask2Int(__mmask16 m) * * \return Mask suitable for use with AVX-512 instructions. */ -static inline __mmask16 -avx512Int2Mask(short i) +static inline __mmask16 avx512Int2Mask(short i) { return static_cast<__mmask16>(i); } -} +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_GENERAL_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_double.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_double.h index 44d13a1e06..75b7c2d663 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_double.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,229 +51,161 @@ namespace gmx class Simd4Double { - public: - Simd4Double() {} +public: + Simd4Double() {} - Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} + Simd4Double(double d) : simdInternal_(_mm256_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - Simd4Double(__m256d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Double(__m256d simd) : simdInternal_(simd) {} - __m256d simdInternal_; + __m256d simdInternal_; }; class Simd4DBool { - public: - Simd4DBool() {} +public: + Simd4DBool() {} - // Internal utility constructor to simplify return statements - Simd4DBool(__mmask8 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4DBool(__mmask8 simd) : simdInternal_(simd) {} - __mmask8 simdInternal_; + __mmask8 simdInternal_; }; -static inline Simd4Double gmx_simdcall -load4(const double *m) +static inline Simd4Double gmx_simdcall load4(const double* m) { assert(size_t(m) % 32 == 0); - return { - _mm256_load_pd(m) - }; + return { _mm256_load_pd(m) }; } -static inline void gmx_simdcall -store4(double *m, Simd4Double a) +static inline void gmx_simdcall store4(double* m, Simd4Double a) { assert(size_t(m) % 32 == 0); _mm256_store_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -load4U(const double *m) +static inline Simd4Double gmx_simdcall load4U(const double* m) { - return { - _mm256_loadu_pd(m) - }; + return { _mm256_loadu_pd(m) }; } -static inline void gmx_simdcall -store4U(double *m, Simd4Double a) +static inline void gmx_simdcall store4U(double* m, Simd4Double a) { _mm256_storeu_pd(m, a.simdInternal_); } -static inline Simd4Double gmx_simdcall -simd4SetZeroD() +static inline Simd4Double gmx_simdcall simd4SetZeroD() { - return { - _mm256_setzero_pd() - }; + return { _mm256_setzero_pd() }; } -static inline Simd4Double gmx_simdcall -operator&(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b) { - return { - _mm256_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -andNot(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b) { - return { - _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator|(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b) { - return { - _mm256_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator^(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b) { - return { - _mm256_xor_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator+(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b) { - return { - _mm256_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b) { - return { - _mm256_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double x) +static inline Simd4Double gmx_simdcall operator-(Simd4Double x) { - return { - _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) - }; + return { _mm256_xor_pd(x.simdInternal_, _mm256_set1_pd(GMX_DOUBLE_NEGZERO)) }; } -static inline Simd4Double gmx_simdcall -operator*(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b) { - return { - _mm256_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mul_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm256_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { - return { - _mm512_castpd512_pd256(_mm512_rsqrt14_pd(_mm512_castpd256_pd512(x.simdInternal_))) - }; + return { _mm512_castpd512_pd256(_mm512_rsqrt14_pd(_mm512_castpd256_pd512(x.simdInternal_))) }; } #endif -static inline Simd4Double gmx_simdcall -abs(Simd4Double x) +static inline Simd4Double gmx_simdcall abs(Simd4Double x) { - return { - _mm256_andnot_pd(_mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) - }; + return { _mm256_andnot_pd(_mm256_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -max(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b) { - return { - _mm256_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -min(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b) { - return { - _mm256_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_min_pd(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -round(Simd4Double x) +static inline Simd4Double gmx_simdcall round(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Double gmx_simdcall -trunc(Simd4Double x) +static inline Simd4Double gmx_simdcall trunc(Simd4Double x) { - return { - _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm256_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline double gmx_simdcall -dotProduct(Simd4Double a, Simd4Double b) +static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b) { __m128d tmp1, tmp2; - a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); - tmp1 = _mm256_castpd256_pd128(a.simdInternal_); - tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); + a.simdInternal_ = _mm256_mul_pd(a.simdInternal_, b.simdInternal_); + tmp1 = _mm256_castpd256_pd128(a.simdInternal_); + tmp2 = _mm256_extractf128_pd(a.simdInternal_, 0x1); tmp1 = _mm_add_pd(tmp1, _mm_permute_pd(tmp1, _MM_SHUFFLE2(0, 1))); tmp1 = _mm_add_pd(tmp1, tmp2); - return *reinterpret_cast(&tmp1); + return *reinterpret_cast(&tmp1); } -static inline void gmx_simdcall -transpose(Simd4Double * v0, Simd4Double * v1, - Simd4Double * v2, Simd4Double * v3) +static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3) { __m256d t1, t2, t3, t4; t1 = _mm256_unpacklo_pd(v0->simdInternal_, v1->simdInternal_); @@ -286,86 +218,65 @@ transpose(Simd4Double * v0, Simd4Double * v1, v3->simdInternal_ = _mm256_permute2f128_pd(t2, t4, 0x31); } -static inline Simd4DBool gmx_simdcall -operator==(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), _mm512_castpd256_pd512(b.simdInternal_), _CMP_EQ_OQ) - }; + return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), + _mm512_castpd256_pd512(b.simdInternal_), _CMP_EQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator!=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), _mm512_castpd256_pd512(b.simdInternal_), _CMP_NEQ_OQ) - }; + return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), + _mm512_castpd256_pd512(b.simdInternal_), _CMP_NEQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), _mm512_castpd256_pd512(b.simdInternal_), _CMP_LT_OQ) - }; + return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), + _mm512_castpd256_pd512(b.simdInternal_), _CMP_LT_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator<=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), _mm512_castpd256_pd512(b.simdInternal_), _CMP_LE_OQ) - }; + return { _mm512_mask_cmp_pd_mask(avx512Int2Mask(0xF), _mm512_castpd256_pd512(a.simdInternal_), + _mm512_castpd256_pd512(b.simdInternal_), _CMP_LE_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator&&(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b) { - return { - static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4DBool gmx_simdcall -operator||(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator||(Simd4DBool a, Simd4DBool b) { - return { - static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) }; } -static inline bool gmx_simdcall -anyTrue(Simd4DBool x) +static inline bool gmx_simdcall anyTrue(Simd4DBool x) { - return ( avx512Mask2Int(x.simdInternal_) & 0xF ) != 0; + return (avx512Mask2Int(x.simdInternal_) & 0xF) != 0; } -static inline Simd4Double gmx_simdcall -selectByMask(Simd4Double a, Simd4DBool m) +static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool m) { - return { - _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, _mm512_castpd256_pd512(a.simdInternal_))) - }; + return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, + _mm512_castpd256_pd512(a.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -selectByNotMask(Simd4Double a, Simd4DBool m) +static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool m) { - return { - _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_castpd256_pd512(a.simdInternal_), m.simdInternal_, _mm512_setzero_pd())) - }; + return { _mm512_castpd512_pd256(_mm512_mask_mov_pd(_mm512_castpd256_pd512(a.simdInternal_), + m.simdInternal_, _mm512_setzero_pd())) }; } -static inline Simd4Double gmx_simdcall -blend(Simd4Double a, Simd4Double b, Simd4DBool sel) +static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel) { - return { - _mm512_castpd512_pd256(_mm512_mask_blend_pd(sel.simdInternal_, _mm512_castpd256_pd512(a.simdInternal_), _mm512_castpd256_pd512(b.simdInternal_))) - }; + return { _mm512_castpd512_pd256(_mm512_mask_blend_pd(sel.simdInternal_, + _mm512_castpd256_pd512(a.simdInternal_), + _mm512_castpd256_pd512(b.simdInternal_))) }; } -static inline double gmx_simdcall -reduce(Simd4Double a) +static inline double gmx_simdcall reduce(Simd4Double a) { __m128d a0, a1; @@ -373,9 +284,9 @@ reduce(Simd4Double a) a0 = _mm256_castpd256_pd128(a.simdInternal_); a1 = _mm256_extractf128_pd(a.simdInternal_, 0x1); a0 = _mm_add_sd(a0, a1); - return *reinterpret_cast(&a0); + return *reinterpret_cast(&a0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_float.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_float.h index 0a060bf8e5..48debf7f2f 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_float.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,226 +51,158 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} + Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - // Internal utility constructor to simplify return statements - Simd4FBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { assert(size_t(m) % 16 == 0); - return { - _mm_load_ps(m) - }; + return { _mm_load_ps(m) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { assert(size_t(m) % 16 == 0); _mm_store_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { - _mm_loadu_ps(m) - }; + return { _mm_loadu_ps(m) }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { _mm_storeu_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - _mm_setzero_ps() - }; + return { _mm_setzero_ps() }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - _mm_andnot_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - _mm_xor_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - _mm_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - _mm_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) - }; + return { _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - _mm_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mul_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - _mm512_castps512_ps128(_mm512_rsqrt14_ps(_mm512_castps128_ps512(x.simdInternal_))) - }; + return { _mm512_castps512_ps128(_mm512_rsqrt14_ps(_mm512_castps128_ps512(x.simdInternal_))) }; } #endif -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - _mm_andnot_ps(_mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) - }; + return { _mm_andnot_ps(_mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - _mm_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - _mm_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_min_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { __m128 c, d; c = _mm_mul_ps(a.simdInternal_, b.simdInternal_); d = _mm_add_ps(c, _mm_permute_ps(c, _MM_SHUFFLE(0, 3, 2, 1))); d = _mm_add_ps(d, _mm_permute_ps(c, _MM_SHUFFLE(1, 0, 3, 2))); - return *reinterpret_cast(&d); + return *reinterpret_cast(&d); } -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { __m128 t0, t1, t2, t3; @@ -284,93 +216,72 @@ transpose(Simd4Float * v0, Simd4Float * v1, v3->simdInternal_ = _mm_unpackhi_ps(t1, t3); } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), _mm512_castps128_ps512(b.simdInternal_), _CMP_EQ_OQ) - }; + return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), + _mm512_castps128_ps512(b.simdInternal_), _CMP_EQ_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), _mm512_castps128_ps512(b.simdInternal_), _CMP_NEQ_OQ) - }; + return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), + _mm512_castps128_ps512(b.simdInternal_), _CMP_NEQ_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), _mm512_castps128_ps512(b.simdInternal_), _CMP_LT_OQ) - }; + return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), + _mm512_castps128_ps512(b.simdInternal_), _CMP_LT_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), _mm512_castps128_ps512(b.simdInternal_), _CMP_LE_OQ) - }; + return { _mm512_mask_cmp_ps_mask(avx512Int2Mask(0xF), _mm512_castps128_ps512(a.simdInternal_), + _mm512_castps128_ps512(b.simdInternal_), _CMP_LE_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { - return ( avx512Mask2Int(a.simdInternal_) & 0xF ) != 0; + return (avx512Mask2Int(a.simdInternal_) & 0xF) != 0; } -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m) { - return { - _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, _mm512_castps128_ps512(a.simdInternal_))) - }; + return { _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, + _mm512_castps128_ps512(a.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m) { - return { - _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_castps128_ps512(a.simdInternal_), m.simdInternal_, _mm512_setzero_ps())) - }; + return { _mm512_castps512_ps128(_mm512_mask_mov_ps(_mm512_castps128_ps512(a.simdInternal_), + m.simdInternal_, _mm512_setzero_ps())) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - _mm512_castps512_ps128(_mm512_mask_blend_ps(sel.simdInternal_, _mm512_castps128_ps512(a.simdInternal_), _mm512_castps128_ps512(b.simdInternal_))) - }; + return { _mm512_castps512_ps128(_mm512_mask_blend_ps(sel.simdInternal_, + _mm512_castps128_ps512(a.simdInternal_), + _mm512_castps128_ps512(b.simdInternal_))) }; } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __m128 b; b = _mm_add_ps(a.simdInternal_, _mm_permute_ps(a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); b = _mm_add_ss(b, _mm_permute_ps(b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_double.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_double.h index 0aa73524a6..1bb0ae6737 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,348 +54,254 @@ namespace gmx class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - SimdDouble(double d) : simdInternal_(_mm512_set1_pd(d)) {} + SimdDouble(double d) : simdInternal_(_mm512_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(__m512d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(__m512d simd) : simdInternal_(simd) {} - __m512d simdInternal_; + __m512d simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - SimdDInt32(std::int32_t i) : simdInternal_(_mm256_set1_epi32(i)) {} + SimdDInt32(std::int32_t i) : simdInternal_(_mm256_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(__m256i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(__m256i simd) : simdInternal_(simd) {} - __m256i simdInternal_; + __m256i simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - // Internal utility constructor to simplify return statements - SimdDBool(__mmask8 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(__mmask8 simd) : simdInternal_(simd) {} - __mmask8 simdInternal_; + __mmask8 simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - // Internal utility constructor to simplify return statements - SimdDIBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_pd(m) - }; + return { _mm512_load_pd(m) }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { assert(std::size_t(m) % 64 == 0); _mm512_store_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { - return { - _mm512_loadu_pd(m) - }; + return { _mm512_loadu_pd(m) }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { _mm512_storeu_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - _mm512_setzero_pd() - }; + return { _mm512_setzero_pd() }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { assert(std::size_t(m) % 32 == 0); - return { - _mm256_load_si256(reinterpret_cast(m)) - }; + return { _mm256_load_si256(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { assert(std::size_t(m) % 32 == 0); - _mm256_store_si256(reinterpret_cast<__m256i *>(m), a.simdInternal_); + _mm256_store_si256(reinterpret_cast<__m256i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { - return { - _mm256_loadu_si256(reinterpret_cast(m)) - }; + return { _mm256_loadu_si256(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { - _mm256_storeu_si256(reinterpret_cast<__m256i *>(m), a.simdInternal_); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - _mm256_setzero_si256() - }; + return { _mm256_setzero_si256() }; } -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - return { - _mm512_castsi512_pd(_mm512_and_epi32(_mm512_castpd_si512(a.simdInternal_), _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_and_epi32(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - return { - _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(a.simdInternal_), _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - return { - _mm512_castsi512_pd(_mm512_or_epi32(_mm512_castpd_si512(a.simdInternal_), _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_or_epi32(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - return { - _mm512_castsi512_pd(_mm512_xor_epi32(_mm512_castpd_si512(a.simdInternal_), _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_xor_epi32(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - return { - _mm512_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - return { - _mm512_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble x) +static inline SimdDouble gmx_simdcall operator-(SimdDouble x) { - return { - _mm512_castsi512_pd(_mm512_xor_epi32(_mm512_castpd_si512(x.simdInternal_), _mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)))) - }; + return { _mm512_castsi512_pd(_mm512_xor_epi32(_mm512_castpd_si512(x.simdInternal_), + _mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)))) }; } -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - return { - _mm512_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mul_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm512_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm512_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm512_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fnmadd_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm512_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fnmsub_pd(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - _mm512_rsqrt14_pd(x.simdInternal_) - }; + return { _mm512_rsqrt14_pd(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - _mm512_rcp14_pd(x.simdInternal_) - }; + return { _mm512_rcp14_pd(x.simdInternal_) }; } #endif -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm512_mask_add_pd(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_add_pd(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm512_maskz_mul_pd(m.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_maskz_mul_pd(m.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { - return { - _mm512_maskz_fmadd_pd(m.simdInternal_, a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_maskz_fmadd_pd(m.simdInternal_, a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { - return { - _mm512_maskz_rsqrt14_pd(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rsqrt14_pd(m.simdInternal_, x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { - return { - _mm512_maskz_rcp14_pd(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rcp14_pd(m.simdInternal_, x.simdInternal_) }; } #endif -static inline SimdDouble gmx_simdcall -abs(SimdDouble x) +static inline SimdDouble gmx_simdcall abs(SimdDouble x) { - return { - _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)), _mm512_castpd_si512(x.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_andnot_epi32(_mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)), + _mm512_castpd_si512(x.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - return { - _mm512_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - return { - _mm512_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_min_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { - return { - _mm512_roundscale_pd(x.simdInternal_, 0) - }; + return { _mm512_roundscale_pd(x.simdInternal_, 0) }; } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { #if defined(__INTEL_COMPILER) || defined(__ECC) - return { - _mm512_trunc_pd(x.simdInternal_) - }; + return { _mm512_trunc_pd(x.simdInternal_) }; #else - return { - _mm512_cvtepi32_pd(_mm512_cvttpd_epi32(x.simdInternal_)) - }; + return { _mm512_cvtepi32_pd(_mm512_cvttpd_epi32(x.simdInternal_)) }; #endif } -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) { __m512d rExponent = _mm512_getexp_pd(value.simdInternal_); __m256i iExponent = _mm512_cvtpd_epi32(rExponent); exponent->simdInternal_ = _mm256_add_epi32(iExponent, _mm256_set1_epi32(1)); - return { - _mm512_getmant_pd(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) - }; + return { _mm512_getmant_pd(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { const __m256i exponentBias = _mm256_set1_epi32(1023); __m256i iExponent = _mm256_add_epi32(exponent.simdInternal_, exponentBias); @@ -407,301 +313,212 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent = _mm256_max_epi32(iExponent, _mm256_setzero_si256()); } - iExponent512 = _mm512_permutexvar_epi32(_mm512_set_epi32(7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0), _mm512_castsi256_si512(iExponent)); - iExponent512 = _mm512_mask_slli_epi32(_mm512_setzero_epi32(), avx512Int2Mask(0xAAAA), iExponent512, 20); + iExponent512 = + _mm512_permutexvar_epi32(_mm512_set_epi32(7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0), + _mm512_castsi256_si512(iExponent)); + iExponent512 = + _mm512_mask_slli_epi32(_mm512_setzero_epi32(), avx512Int2Mask(0xAAAA), iExponent512, 20); return _mm512_mul_pd(_mm512_castsi512_pd(iExponent512), value.simdInternal_); } -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { __m512d x = a.simdInternal_; - x = _mm512_add_pd(x, _mm512_shuffle_f64x2(x, x, 0xEE)); - x = _mm512_add_pd(x, _mm512_shuffle_f64x2(x, x, 0x11)); - x = _mm512_add_pd(x, _mm512_permute_pd(x, 0x01)); - return *reinterpret_cast(&x); + x = _mm512_add_pd(x, _mm512_shuffle_f64x2(x, x, 0xEE)); + x = _mm512_add_pd(x, _mm512_shuffle_f64x2(x, x, 0x11)); + x = _mm512_add_pd(x, _mm512_permute_pd(x, 0x01)); + return *reinterpret_cast(&x); } -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { - return { - _mm512_test_epi64_mask(_mm512_castpd_si512(a.simdInternal_), _mm512_castpd_si512(a.simdInternal_)) - }; + return { _mm512_test_epi64_mask(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(a.simdInternal_)) }; } -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) +static inline bool gmx_simdcall anyTrue(SimdDBool a) { - return ( avx512Mask2Int(a.simdInternal_) != 0); + return (avx512Mask2Int(a.simdInternal_) != 0); } -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool m) { - return { - _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool m) { - return { - _mm512_mask_mov_pd(a.simdInternal_, m.simdInternal_, _mm512_setzero_pd()) - }; + return { _mm512_mask_mov_pd(a.simdInternal_, m.simdInternal_, _mm512_setzero_pd()) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -copysign(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall copysign(SimdDouble a, SimdDouble b) { - return { - _mm512_castsi512_pd(_mm512_ternarylogic_epi64( - _mm512_castpd_si512(a.simdInternal_), - _mm512_castpd_si512(b.simdInternal_), - _mm512_set1_epi64(INT64_MIN), 0xD8)) - }; + return { _mm512_castsi512_pd(_mm512_ternarylogic_epi64(_mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_), + _mm512_set1_epi64(INT64_MIN), 0xD8)) }; } -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_and_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_and_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_andnot_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_andnot_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_or_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_or_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_xor_si256(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_xor_si256(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - _mm256_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm256_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_EQ) - }; + return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), + _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_EQ) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { - return { - _mm512_mask_test_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), _mm512_castsi256_si512(a.simdInternal_)) - }; + return { _mm512_mask_test_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), + _mm512_castsi256_si512(a.simdInternal_)) }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_LT) - }; + return { _mm512_mask_cmp_epi32_mask(avx512Int2Mask(0xFF), _mm512_castsi256_si512(a.simdInternal_), + _mm512_castsi256_si512(b.simdInternal_), _MM_CMPINT_LT) }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) +static inline bool gmx_simdcall anyTrue(SimdDIBool a) { - return ( avx512Mask2Int(a.simdInternal_) & 0xFF) != 0; + return (avx512Mask2Int(a.simdInternal_) & 0xFF) != 0; } -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool m) { - return { - _mm512_castsi512_si256(_mm512_mask_mov_epi32(_mm512_setzero_si512(), m.simdInternal_, _mm512_castsi256_si512(a.simdInternal_))) - }; + return { _mm512_castsi512_si256(_mm512_mask_mov_epi32( + _mm512_setzero_si512(), m.simdInternal_, _mm512_castsi256_si512(a.simdInternal_))) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool m) { - return { - _mm512_castsi512_si256(_mm512_mask_mov_epi32(_mm512_castsi256_si512(a.simdInternal_), m.simdInternal_, _mm512_setzero_si512())) - }; + return { _mm512_castsi512_si256(_mm512_mask_mov_epi32( + _mm512_castsi256_si512(a.simdInternal_), m.simdInternal_, _mm512_setzero_si512())) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - _mm512_castsi512_si256(_mm512_mask_blend_epi32(sel.simdInternal_, _mm512_castsi256_si512(a.simdInternal_), _mm512_castsi256_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_si256( + _mm512_mask_blend_epi32(sel.simdInternal_, _mm512_castsi256_si512(a.simdInternal_), + _mm512_castsi256_si512(b.simdInternal_))) }; } -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { - return { - _mm512_cvtpd_epi32(a.simdInternal_) - }; + return { _mm512_cvtpd_epi32(a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { - return { - _mm512_cvttpd_epi32(a.simdInternal_) - }; + return { _mm512_cvttpd_epi32(a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { - return { - _mm512_cvtepi32_pd(a.simdInternal_) - }; + return { _mm512_cvtepi32_pd(a.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { - return { - static_cast<__mmask8>(a.simdInternal_) - }; + return { static_cast<__mmask8>(a.simdInternal_) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { d0->simdInternal_ = _mm512_cvtps_pd(_mm512_castps512_ps256(f.simdInternal_)); - d1->simdInternal_ = _mm512_cvtps_pd(_mm512_castps512_ps256(_mm512_shuffle_f32x4(f.simdInternal_, f.simdInternal_, 0xEE))); + d1->simdInternal_ = _mm512_cvtps_pd( + _mm512_castps512_ps256(_mm512_shuffle_f32x4(f.simdInternal_, f.simdInternal_, 0xEE))); } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { __m512 f0 = _mm512_castps256_ps512(_mm512_cvtpd_ps(d0.simdInternal_)); __m512 f1 = _mm512_castps256_ps512(_mm512_cvtpd_ps(d1.simdInternal_)); - return { - _mm512_shuffle_f32x4(f0, f1, 0x44) - }; + return { _mm512_shuffle_f32x4(f0, f1, 0x44) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_float.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_float.h index 6f5b482117..282789b89a 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_simd_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,352 +53,258 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) : simdInternal_(_mm512_set1_ps(f)) {} + SimdFloat(float f) : simdInternal_(_mm512_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(__m512 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__m512 simd) : simdInternal_(simd) {} - __m512 simdInternal_; + __m512 simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} + SimdFInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(__m512i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__m512i simd) : simdInternal_(simd) {} - __m512i simdInternal_; + __m512i simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - // Internal utility constructor to simplify return statements - SimdFBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - // Internal utility constructor to simplify return statements - SimdFIBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_ps(m) - }; + return { _mm512_load_ps(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { assert(std::size_t(m) % 64 == 0); _mm512_store_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { - return { - _mm512_loadu_ps(m) - }; + return { _mm512_loadu_ps(m) }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { _mm512_storeu_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - _mm512_setzero_ps() - }; + return { _mm512_setzero_ps() }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_si512(m) - }; + return { _mm512_load_si512(m) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { assert(std::size_t(m) % 64 == 0); _mm512_store_si512(m, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { - return { - _mm512_loadu_si512(m) - }; + return { _mm512_loadu_si512(m) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { _mm512_storeu_si512(m, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - _mm512_setzero_si512() - }; + return { _mm512_setzero_si512() }; } -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - _mm512_castsi512_ps(_mm512_or_epi32(_mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_or_epi32(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - _mm512_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - _mm512_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(x.simdInternal_), _mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)))) - }; + return { _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(x.simdInternal_), + _mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)))) }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - _mm512_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mul_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm512_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm512_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm512_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fnmadd_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm512_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_fnmsub_ps(a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - _mm512_rsqrt14_ps(x.simdInternal_) - }; + return { _mm512_rsqrt14_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - _mm512_rcp14_ps(x.simdInternal_) - }; + return { _mm512_rcp14_ps(x.simdInternal_) }; } #endif -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm512_mask_add_ps(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_add_ps(a.simdInternal_, m.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm512_maskz_mul_ps(m.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_maskz_mul_ps(m.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { - return { - _mm512_maskz_fmadd_ps(m.simdInternal_, a.simdInternal_, b.simdInternal_, c.simdInternal_) - }; + return { _mm512_maskz_fmadd_ps(m.simdInternal_, a.simdInternal_, b.simdInternal_, c.simdInternal_) }; } // Override for AVX-512-KNL #if GMX_SIMD_X86_AVX_512 -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { - return { - _mm512_maskz_rsqrt14_ps(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rsqrt14_ps(m.simdInternal_, x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { - return { - _mm512_maskz_rcp14_ps(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rcp14_ps(m.simdInternal_, x.simdInternal_) }; } #endif -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)), _mm512_castps_si512(x.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_andnot_epi32(_mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)), + _mm512_castps_si512(x.simdInternal_))) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - _mm512_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - _mm512_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_min_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - _mm512_roundscale_ps(x.simdInternal_, 0) - }; + return { _mm512_roundscale_ps(x.simdInternal_, 0) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { #if defined(__INTEL_COMPILER) || defined(__ECC) - return { - _mm512_trunc_ps(x.simdInternal_) - }; + return { _mm512_trunc_ps(x.simdInternal_) }; #else - return { - _mm512_cvtepi32_ps(_mm512_cvttps_epi32(x.simdInternal_)) - }; + return { _mm512_cvtepi32_ps(_mm512_cvttps_epi32(x.simdInternal_)) }; #endif } -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { __m512 rExponent = _mm512_getexp_ps(value.simdInternal_); - __m512i iExponent = _mm512_cvtps_epi32(rExponent); + __m512i iExponent = _mm512_cvtps_epi32(rExponent); exponent->simdInternal_ = _mm512_add_epi32(iExponent, _mm512_set1_epi32(1)); - return { - _mm512_getmant_ps(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) - }; + return { _mm512_getmant_ps(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { const __m512i exponentBias = _mm512_set1_epi32(127); - __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias); + __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -408,285 +314,187 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = _mm512_slli_epi32(iExponent, 23); - return { - _mm512_mul_ps(value.simdInternal_, _mm512_castsi512_ps(iExponent)) - }; + return { _mm512_mul_ps(value.simdInternal_, _mm512_castsi512_ps(iExponent)) }; } -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { __m512 x = a.simdInternal_; - x = _mm512_add_ps(x, _mm512_shuffle_f32x4(x, x, 0xEE)); - x = _mm512_add_ps(x, _mm512_shuffle_f32x4(x, x, 0x11)); - x = _mm512_add_ps(x, _mm512_permute_ps(x, 0xEE)); - x = _mm512_add_ps(x, _mm512_permute_ps(x, 0x11)); - return *reinterpret_cast(&x); + x = _mm512_add_ps(x, _mm512_shuffle_f32x4(x, x, 0xEE)); + x = _mm512_add_ps(x, _mm512_shuffle_f32x4(x, x, 0x11)); + x = _mm512_add_ps(x, _mm512_permute_ps(x, 0xEE)); + x = _mm512_add_ps(x, _mm512_permute_ps(x, 0x11)); + return *reinterpret_cast(&x); } -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_OQ) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OQ) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OQ) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { - return { - _mm512_test_epi32_mask( _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(a.simdInternal_) ) - }; + return { _mm512_test_epi32_mask(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(a.simdInternal_)) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { - return ( avx512Mask2Int(a.simdInternal_) != 0); + return (avx512Mask2Int(a.simdInternal_) != 0); } -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m) { - return { - _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m) { - return { - _mm512_mask_mov_ps(a.simdInternal_, m.simdInternal_, _mm512_setzero_ps()) - }; + return { _mm512_mask_mov_ps(a.simdInternal_, m.simdInternal_, _mm512_setzero_ps()) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -copysign(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall copysign(SimdFloat a, SimdFloat b) { - return { - _mm512_castsi512_ps(_mm512_ternarylogic_epi32( - _mm512_castps_si512(a.simdInternal_), - _mm512_castps_si512(b.simdInternal_), - _mm512_set1_epi32(INT32_MIN), 0xD8)) - }; + return { _mm512_castsi512_ps(_mm512_ternarylogic_epi32(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_), + _mm512_set1_epi32(INT32_MIN), 0xD8)) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_and_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_and_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_or_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_or_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - _mm512_test_epi32_mask( a.simdInternal_, a.simdInternal_ ) - }; + return { _mm512_test_epi32_mask(a.simdInternal_, a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { - return ( avx512Mask2Int(a.simdInternal_) != 0); + return (avx512Mask2Int(a.simdInternal_) != 0); } -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m) { - return { - _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m) { - return { - _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) - }; + return { _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - _mm512_cvtps_epi32(a.simdInternal_) - }; + return { _mm512_cvtps_epi32(a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - _mm512_cvttps_epi32(a.simdInternal_) - }; + return { _mm512_cvttps_epi32(a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - _mm512_cvtepi32_ps(a.simdInternal_) - }; + return { _mm512_cvtepi32_ps(a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_double.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_double.h index 3d938b4c20..e722b77846 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_double.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_double.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -80,80 +81,76 @@ SimdDInt32 fastMultiply(SimdDInt32 x) } template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double *, SimdDInt32) +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double*, SimdDInt32) { - //Nothing to do. Termination of recursion. -} + // Nothing to do. Termination of recursion. } +} // namespace -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, SimdDInt32 offset, SimdDouble *v, Targs... Fargs) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v, Targs... Fargs) { if (align > 1) { offset = fastMultiply(offset); } constexpr size_t scale = sizeof(double); - v->simdInternal_ = _mm512_i32gather_pd(offset.simdInternal_, base, scale); - gatherLoadBySimdIntTranspose<1>(base+1, offset, Fargs ...); + v->simdInternal_ = _mm512_i32gather_pd(offset.simdInternal_, base, scale); + gatherLoadBySimdIntTranspose<1>(base + 1, offset, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double *base, SimdDInt32 offset, SimdDouble *v, Targs... Fargs) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, offset, v, Fargs ...); + gatherLoadBySimdIntTranspose(base, offset, v, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double *base, const std::int32_t offset[], SimdDouble *v, Targs... Fargs) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v, Fargs ...); + gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadUTranspose(const double *base, const std::int32_t offset[], SimdDouble *v, Targs... Fargs) + gatherLoadUTranspose(const double* base, const std::int32_t offset[], SimdDouble* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v, Fargs ...); + gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v, Fargs...); } -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { SimdDInt32 simdoffset = simdLoad(offset, SimdDInt32Tag()); if (align > 1) { - simdoffset = fastMultiply(simdoffset);; + simdoffset = fastMultiply(simdoffset); + ; } constexpr size_t scale = sizeof(double); - _mm512_i32scatter_pd(base, simdoffset.simdInternal_, v0.simdInternal_, scale); + _mm512_i32scatter_pd(base, simdoffset.simdInternal_, v0.simdInternal_, scale); _mm512_i32scatter_pd(&(base[1]), simdoffset.simdInternal_, v1.simdInternal_, scale); _mm512_i32scatter_pd(&(base[2]), simdoffset.simdInternal_, v2.simdInternal_, scale); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { - __m512d t[4], t5, t6, t7, t8; - alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8]; - //TODO: should use fastMultiply - _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(_mm256_load_si256((const __m256i*)(offset )), _mm256_set1_epi32(align)))); + __m512d t[4], t5, t6, t7, t8; + alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8]; + // TODO: should use fastMultiply + _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32( + _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align)))); t5 = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); t6 = _mm512_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); t7 = _mm512_unpacklo_pd(v2.simdInternal_, _mm512_setzero_pd()); @@ -166,10 +163,13 @@ transposeScatterIncrU(double * base, { for (int i = 0; i < 4; i++) { - _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7), _mm512_castpd256_pd512( - _mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])))); - _mm512_mask_storeu_pd(base + o[4 + i], avx512Int2Mask(7), _mm512_castpd256_pd512( - _mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1)))); + _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7), + _mm512_castpd256_pd512(_mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i])))); + _mm512_mask_storeu_pd( + base + o[4 + i], avx512Int2Mask(7), + _mm512_castpd256_pd512(_mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1)))); } } else @@ -178,37 +178,34 @@ transposeScatterIncrU(double * base, { for (int i = 0; i < 4; i++) { - _mm256_store_pd(base + o[0 + i], - _mm256_add_pd(_mm256_load_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i]))); - _mm256_store_pd(base + o[4 + i], - _mm256_add_pd(_mm256_load_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1))); + _mm256_store_pd(base + o[0 + i], _mm256_add_pd(_mm256_load_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i]))); + _mm256_store_pd(base + o[4 + i], _mm256_add_pd(_mm256_load_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1))); } } else { for (int i = 0; i < 4; i++) { - _mm256_storeu_pd(base + o[0 + i], - _mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i]))); - _mm256_storeu_pd(base + o[4 + i], - _mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1))); + _mm256_storeu_pd(base + o[0 + i], _mm256_add_pd(_mm256_loadu_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i]))); + _mm256_storeu_pd(base + o[4 + i], _mm256_add_pd(_mm256_loadu_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1))); } } } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { - __m512d t[4], t5, t6, t7, t8; - alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8]; - //TODO: should use fastMultiply - _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32(_mm256_load_si256((const __m256i*)(offset )), _mm256_set1_epi32(align)))); + __m512d t[4], t5, t6, t7, t8; + alignas(GMX_SIMD_ALIGNMENT) std::int64_t o[8]; + // TODO: should use fastMultiply + _mm512_store_epi64(o, _mm512_cvtepi32_epi64(_mm256_mullo_epi32( + _mm256_load_si256((const __m256i*)(offset)), _mm256_set1_epi32(align)))); t5 = _mm512_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); t6 = _mm512_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); t7 = _mm512_unpacklo_pd(v2.simdInternal_, _mm512_setzero_pd()); @@ -221,10 +218,13 @@ transposeScatterDecrU(double * base, { for (int i = 0; i < 4; i++) { - _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7), _mm512_castpd256_pd512( - _mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i])))); - _mm512_mask_storeu_pd(base + o[4 + i], avx512Int2Mask(7), _mm512_castpd256_pd512( - _mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1)))); + _mm512_mask_storeu_pd(base + o[0 + i], avx512Int2Mask(7), + _mm512_castpd256_pd512(_mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i])))); + _mm512_mask_storeu_pd( + base + o[4 + i], avx512Int2Mask(7), + _mm512_castpd256_pd512(_mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1)))); } } else @@ -233,46 +233,44 @@ transposeScatterDecrU(double * base, { for (int i = 0; i < 4; i++) { - _mm256_store_pd(base + o[0 + i], - _mm256_sub_pd(_mm256_load_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i]))); - _mm256_store_pd(base + o[4 + i], - _mm256_sub_pd(_mm256_load_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1))); + _mm256_store_pd(base + o[0 + i], _mm256_sub_pd(_mm256_load_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i]))); + _mm256_store_pd(base + o[4 + i], _mm256_sub_pd(_mm256_load_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1))); } } else { for (int i = 0; i < 4; i++) { - _mm256_storeu_pd(base + o[0 + i], - _mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]), _mm512_castpd512_pd256(t[i]))); - _mm256_storeu_pd(base + o[4 + i], - _mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]), _mm512_extractf64x4_pd(t[i], 1))); + _mm256_storeu_pd(base + o[0 + i], _mm256_sub_pd(_mm256_loadu_pd(base + o[0 + i]), + _mm512_castpd512_pd256(t[i]))); + _mm256_storeu_pd(base + o[4 + i], _mm256_sub_pd(_mm256_loadu_pd(base + o[4 + i]), + _mm512_extractf64x4_pd(t[i], 1))); } } } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { - triplets0->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32(_mm512_set_epi32(5, 4, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0), - _mm512_castpd_si512(scalar.simdInternal_))); - triplets1->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32(_mm512_set_epi32(11, 10, 9, 8, 9, 8, 9, 8, 7, 6, 7, 6, 7, 6, 5, 4), - _mm512_castpd_si512(scalar.simdInternal_))); - triplets2->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32(_mm512_set_epi32(15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 11, 10, 11, 10), - _mm512_castpd_si512(scalar.simdInternal_))); + triplets0->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32( + _mm512_set_epi32(5, 4, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0), + _mm512_castpd_si512(scalar.simdInternal_))); + triplets1->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32( + _mm512_set_epi32(11, 10, 9, 8, 9, 8, 9, 8, 7, 6, 7, 6, 7, 6, 5, 4), + _mm512_castpd_si512(scalar.simdInternal_))); + triplets2->simdInternal_ = _mm512_castsi512_pd(_mm512_permutexvar_epi32( + _mm512_set_epi32(15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 11, 10, 11, 10), + _mm512_castpd_si512(scalar.simdInternal_))); } static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __m512d t0, t2; __m256d t3, t4; @@ -281,8 +279,10 @@ reduceIncr4ReturnSum(double * m, t0 = _mm512_add_pd(v0.simdInternal_, _mm512_permute_pd(v0.simdInternal_, 0x55)); t2 = _mm512_add_pd(v2.simdInternal_, _mm512_permute_pd(v2.simdInternal_, 0x55)); - t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xAA), v1.simdInternal_, _mm512_permute_pd(v1.simdInternal_, 0x55)); - t2 = _mm512_mask_add_pd(t2, avx512Int2Mask(0xAA), v3.simdInternal_, _mm512_permute_pd(v3.simdInternal_, 0x55)); + t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xAA), v1.simdInternal_, + _mm512_permute_pd(v1.simdInternal_, 0x55)); + t2 = _mm512_mask_add_pd(t2, avx512Int2Mask(0xAA), v3.simdInternal_, + _mm512_permute_pd(v3.simdInternal_, 0x55)); t0 = _mm512_add_pd(t0, _mm512_shuffle_f64x2(t0, t0, 0x4E)); t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xF0), t2, _mm512_shuffle_f64x2(t2, t2, 0x4E)); t0 = _mm512_add_pd(t0, _mm512_shuffle_f64x2(t0, t0, 0xB1)); @@ -299,43 +299,29 @@ reduceIncr4ReturnSum(double * m, return _mm_cvtsd_f64(_mm512_castpd512_pd128(t0)); } -static inline SimdDouble gmx_simdcall -loadDualHsimd(const double * m0, - const double * m1) +static inline SimdDouble gmx_simdcall loadDualHsimd(const double* m0, const double* m1) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); - return { - _mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_load_pd(m0)), - _mm256_load_pd(m1), 1) - }; + return { _mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_load_pd(m0)), _mm256_load_pd(m1), 1) }; } -static inline SimdDouble gmx_simdcall -loadDuplicateHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadDuplicateHsimd(const double* m) { assert(std::size_t(m) % 32 == 0); - return { - _mm512_broadcast_f64x4(_mm256_load_pd(m)) - }; + return { _mm512_broadcast_f64x4(_mm256_load_pd(m)) }; } -static inline SimdDouble gmx_simdcall -loadU1DualHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadU1DualHsimd(const double* m) { - return { - _mm512_insertf64x4(_mm512_broadcastsd_pd(_mm_load_sd(m)), - _mm256_broadcastsd_pd(_mm_load_sd(m+1)), 1) - }; + return { _mm512_insertf64x4(_mm512_broadcastsd_pd(_mm_load_sd(m)), + _mm256_broadcastsd_pd(_mm_load_sd(m + 1)), 1) }; } -static inline void gmx_simdcall -storeDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall storeDualHsimd(double* m0, double* m1, SimdDouble a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -344,10 +330,7 @@ storeDualHsimd(double * m0, _mm256_store_pd(m1, _mm512_extractf64x4_pd(a.simdInternal_, 1)); } -static inline void gmx_simdcall -incrDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall incrDualHsimd(double* m0, double* m1, SimdDouble a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -365,32 +348,30 @@ incrDualHsimd(double * m0, _mm256_store_pd(m1, x); } -static inline void gmx_simdcall -decrHsimd(double * m, - SimdDouble a) +static inline void gmx_simdcall decrHsimd(double* m, SimdDouble a) { __m256d t; assert(std::size_t(m) % 32 == 0); - a.simdInternal_ = _mm512_add_pd(a.simdInternal_, _mm512_shuffle_f64x2(a.simdInternal_, a.simdInternal_, 0xEE)); + a.simdInternal_ = _mm512_add_pd(a.simdInternal_, + _mm512_shuffle_f64x2(a.simdInternal_, a.simdInternal_, 0xEE)); t = _mm256_load_pd(m); t = _mm256_sub_pd(t, _mm512_castpd512_pd256(a.simdInternal_)); _mm256_store_pd(m, t); } -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const double * base0, - const double * base1, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const double* base0, + const double* base1, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1) { - __m128i idx0, idx1; - __m256i idx; - __m512d tmp1, tmp2; + __m128i idx0, idx1; + __m256i idx; + __m512d tmp1, tmp2; assert(std::size_t(offset) % 16 == 0); assert(std::size_t(base0) % 16 == 0); @@ -406,25 +387,23 @@ gatherLoadTransposeHsimd(const double * base0, idx = _mm256_inserti128_si256(_mm256_castsi128_si256(idx0), idx1, 1); constexpr size_t scale = sizeof(double); - tmp1 = _mm512_i32gather_pd(idx, base0, scale); //TODO: Might be faster to use invidual loads + tmp1 = _mm512_i32gather_pd(idx, base0, scale); // TODO: Might be faster to use invidual loads tmp2 = _mm512_i32gather_pd(idx, base1, scale); - v0->simdInternal_ = _mm512_shuffle_f64x2(tmp1, tmp2, 0x44 ); - v1->simdInternal_ = _mm512_shuffle_f64x2(tmp1, tmp2, 0xEE ); + v0->simdInternal_ = _mm512_shuffle_f64x2(tmp1, tmp2, 0x44); + v1->simdInternal_ = _mm512_shuffle_f64x2(tmp1, tmp2, 0xEE); } -static inline double gmx_simdcall -reduceIncr4ReturnSumHsimd(double * m, - SimdDouble v0, - SimdDouble v1) +static inline double gmx_simdcall reduceIncr4ReturnSumHsimd(double* m, SimdDouble v0, SimdDouble v1) { - __m512d t0; - __m256d t2, t3; + __m512d t0; + __m256d t2, t3; assert(std::size_t(m) % 32 == 0); t0 = _mm512_add_pd(v0.simdInternal_, _mm512_permutex_pd(v0.simdInternal_, 0x4E)); - t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xCC), v1.simdInternal_, _mm512_permutex_pd(v1.simdInternal_, 0x4E)); + t0 = _mm512_mask_add_pd(t0, avx512Int2Mask(0xCC), v1.simdInternal_, + _mm512_permutex_pd(v1.simdInternal_, 0x4E)); t0 = _mm512_add_pd(t0, _mm512_permutex_pd(t0, 0xB1)); t0 = _mm512_mask_shuffle_f64x2(t0, avx512Int2Mask(0xAA), t0, t0, 0xEE); @@ -439,15 +418,12 @@ reduceIncr4ReturnSumHsimd(double * m, return _mm_cvtsd_f64(_mm512_castpd512_pd128(t0)); } -static inline SimdDouble gmx_simdcall -loadU4NOffset(const double *m, int offset) +static inline SimdDouble gmx_simdcall loadU4NOffset(const double* m, int offset) { - return { - _mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_loadu_pd(m)), - _mm256_loadu_pd(m+offset), 1) - }; + return { _mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_loadu_pd(m)), + _mm256_loadu_pd(m + offset), 1) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_float.h b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_float.h index c9e290bc12..ae50e73f63 100644 --- a/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_float.h +++ b/src/gromacs/simd/impl_x86_avx_512/impl_x86_avx_512_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -80,16 +80,15 @@ SimdFInt32 fastMultiply(SimdFInt32 x) } template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float *, SimdFInt32) +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float*, SimdFInt32) { - //Nothing to do. Termination of recursion. -} + // Nothing to do. Termination of recursion. } +} // namespace -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float *base, SimdFInt32 offset, SimdFloat *v, Targs... Fargs) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v, Targs... Fargs) { // For align 1 or 2: No multiplication of offset is needed if (align > 2) @@ -98,39 +97,35 @@ gatherLoadBySimdIntTranspose(const float *base, SimdFInt32 offset, SimdFloat *v, } // For align 2: Scale of 2*sizeof(float) is used (maximum supported scale) constexpr int align_ = (align > 2) ? 1 : align; - v->simdInternal_ = _mm512_i32gather_ps(offset.simdInternal_, base, sizeof(float)*align_); + v->simdInternal_ = _mm512_i32gather_ps(offset.simdInternal_, base, sizeof(float) * align_); // Gather remaining elements. Avoid extra multiplication (new align is 1 or 2). - gatherLoadBySimdIntTranspose(base+1, offset, Fargs ...); + gatherLoadBySimdIntTranspose(base + 1, offset, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float *base, SimdFInt32 offset, SimdFloat *v, Targs... Fargs) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, offset, v, Fargs ...); + gatherLoadBySimdIntTranspose(base, offset, v, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float *base, const std::int32_t offset[], SimdFloat *v, Targs... Fargs) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v, Fargs ...); + gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v, Fargs...); } -template +template static inline void gmx_simdcall -gatherLoadUTranspose(const float *base, const std::int32_t offset[], SimdFloat *v, Targs... Fargs) + gatherLoadUTranspose(const float* base, const std::int32_t offset[], SimdFloat* v, Targs... Fargs) { - gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v, Fargs ...); + gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v, Fargs...); } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { SimdFInt32 simdoffset = simdLoad(offset, SimdFInt32Tag()); if (align > 2) @@ -139,22 +134,18 @@ transposeScatterStoreU(float * base, } constexpr size_t scale = (align > 2) ? sizeof(float) : sizeof(float) * align; - _mm512_i32scatter_ps(base, simdoffset.simdInternal_, v0.simdInternal_, scale); + _mm512_i32scatter_ps(base, simdoffset.simdInternal_, v0.simdInternal_, scale); _mm512_i32scatter_ps(&(base[1]), simdoffset.simdInternal_, v1.simdInternal_, scale); _mm512_i32scatter_ps(&(base[2]), simdoffset.simdInternal_, v2.simdInternal_, scale); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { - __m512 t[4], t5, t6, t7, t8; - int i; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t o[16]; + __m512 t[4], t5, t6, t7, t8; + int i; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t o[16]; store(o, fastMultiply(simdLoad(offset, SimdFInt32Tag()))); if (align < 4) { @@ -166,67 +157,69 @@ transposeScatterIncrU(float * base, t[3] = _mm512_shuffle_ps(t6, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); for (i = 0; i < 4; i++) { - _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_add_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i])))); - _mm512_mask_storeu_ps(base + o[ 4 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_add_ps(_mm_loadu_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1)))); - _mm512_mask_storeu_ps(base + o[ 8 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_add_ps(_mm_loadu_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2)))); - _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_add_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)))); + _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[i]), + _mm512_castps512_ps128(t[i])))); + _mm512_mask_storeu_ps(base + o[4 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[4 + i]), + _mm512_extractf32x4_ps(t[i], 1)))); + _mm512_mask_storeu_ps(base + o[8 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[8 + i]), + _mm512_extractf32x4_ps(t[i], 2)))); + _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_add_ps(_mm_loadu_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3)))); } } else { - //One could use shuffle here too if it is OK to overwrite the padded elements for alignment - t5 = _mm512_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); - t6 = _mm512_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); - t7 = _mm512_unpacklo_ps(v1.simdInternal_, _mm512_setzero_ps()); - t8 = _mm512_unpackhi_ps(v1.simdInternal_, _mm512_setzero_ps()); - t[0] = _mm512_unpacklo_ps(t5, t7); // x0 y0 z0 0 | x4 y4 z4 0 - t[1] = _mm512_unpackhi_ps(t5, t7); // x1 y1 z1 0 | x5 y5 z5 0 - t[2] = _mm512_unpacklo_ps(t6, t8); // x2 y2 z2 0 | x6 y6 z6 0 - t[3] = _mm512_unpackhi_ps(t6, t8); // x3 y3 z3 0 | x7 y7 z7 0 + // One could use shuffle here too if it is OK to overwrite the padded elements for alignment + t5 = _mm512_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); + t6 = _mm512_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); + t7 = _mm512_unpacklo_ps(v1.simdInternal_, _mm512_setzero_ps()); + t8 = _mm512_unpackhi_ps(v1.simdInternal_, _mm512_setzero_ps()); + t[0] = _mm512_unpacklo_ps(t5, t7); // x0 y0 z0 0 | x4 y4 z4 0 + t[1] = _mm512_unpackhi_ps(t5, t7); // x1 y1 z1 0 | x5 y5 z5 0 + t[2] = _mm512_unpacklo_ps(t6, t8); // x2 y2 z2 0 | x6 y6 z6 0 + t[3] = _mm512_unpackhi_ps(t6, t8); // x3 y3 z3 0 | x7 y7 z7 0 if (align % 4 == 0) { for (i = 0; i < 4; i++) { - _mm_store_ps(base + o[i], _mm_add_ps(_mm_load_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); - _mm_store_ps(base + o[ 4 + i], - _mm_add_ps(_mm_load_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1))); - _mm_store_ps(base + o[ 8 + i], - _mm_add_ps(_mm_load_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2))); - _mm_store_ps(base + o[12 + i], - _mm_add_ps(_mm_load_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3))); + _mm_store_ps(base + o[i], + _mm_add_ps(_mm_load_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); + _mm_store_ps(base + o[4 + i], + _mm_add_ps(_mm_load_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1))); + _mm_store_ps(base + o[8 + i], + _mm_add_ps(_mm_load_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2))); + _mm_store_ps(base + o[12 + i], _mm_add_ps(_mm_load_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3))); } } else { for (i = 0; i < 4; i++) { - _mm_storeu_ps(base + o[i], _mm_add_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); - _mm_storeu_ps(base + o[ 4 + i], - _mm_add_ps(_mm_loadu_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1))); - _mm_storeu_ps(base + o[ 8 + i], - _mm_add_ps(_mm_loadu_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2))); - _mm_storeu_ps(base + o[12 + i], - _mm_add_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3))); + _mm_storeu_ps(base + o[i], + _mm_add_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); + _mm_storeu_ps(base + o[4 + i], _mm_add_ps(_mm_loadu_ps(base + o[4 + i]), + _mm512_extractf32x4_ps(t[i], 1))); + _mm_storeu_ps(base + o[8 + i], _mm_add_ps(_mm_loadu_ps(base + o[8 + i]), + _mm512_extractf32x4_ps(t[i], 2))); + _mm_storeu_ps(base + o[12 + i], _mm_add_ps(_mm_loadu_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3))); } } } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { - __m512 t[4], t5, t6, t7, t8; - int i; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t o[16]; + __m512 t[4], t5, t6, t7, t8; + int i; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t o[16]; store(o, fastMultiply(simdLoad(offset, SimdFInt32Tag()))); if (align < 4) { @@ -238,77 +231,78 @@ transposeScatterDecrU(float * base, t[3] = _mm512_shuffle_ps(t6, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); for (i = 0; i < 4; i++) { - _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_sub_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i])))); - _mm512_mask_storeu_ps(base + o[ 4 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_sub_ps(_mm_loadu_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1)))); - _mm512_mask_storeu_ps(base + o[ 8 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_sub_ps(_mm_loadu_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2)))); - _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7), _mm512_castps128_ps512( - _mm_sub_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3)))); + _mm512_mask_storeu_ps(base + o[i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[i]), + _mm512_castps512_ps128(t[i])))); + _mm512_mask_storeu_ps(base + o[4 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[4 + i]), + _mm512_extractf32x4_ps(t[i], 1)))); + _mm512_mask_storeu_ps(base + o[8 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[8 + i]), + _mm512_extractf32x4_ps(t[i], 2)))); + _mm512_mask_storeu_ps(base + o[12 + i], avx512Int2Mask(7), + _mm512_castps128_ps512(_mm_sub_ps(_mm_loadu_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3)))); } } else { - //One could use shuffle here too if it is OK to overwrite the padded elements for alignment - t5 = _mm512_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); - t6 = _mm512_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); - t7 = _mm512_unpacklo_ps(v1.simdInternal_, _mm512_setzero_ps()); - t8 = _mm512_unpackhi_ps(v1.simdInternal_, _mm512_setzero_ps()); - t[0] = _mm512_unpacklo_ps(t5, t7); // x0 y0 z0 0 | x4 y4 z4 0 - t[1] = _mm512_unpackhi_ps(t5, t7); // x1 y1 z1 0 | x5 y5 z5 0 - t[2] = _mm512_unpacklo_ps(t6, t8); // x2 y2 z2 0 | x6 y6 z6 0 - t[3] = _mm512_unpackhi_ps(t6, t8); // x3 y3 z3 0 | x7 y7 z7 0 + // One could use shuffle here too if it is OK to overwrite the padded elements for alignment + t5 = _mm512_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); + t6 = _mm512_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); + t7 = _mm512_unpacklo_ps(v1.simdInternal_, _mm512_setzero_ps()); + t8 = _mm512_unpackhi_ps(v1.simdInternal_, _mm512_setzero_ps()); + t[0] = _mm512_unpacklo_ps(t5, t7); // x0 y0 z0 0 | x4 y4 z4 0 + t[1] = _mm512_unpackhi_ps(t5, t7); // x1 y1 z1 0 | x5 y5 z5 0 + t[2] = _mm512_unpacklo_ps(t6, t8); // x2 y2 z2 0 | x6 y6 z6 0 + t[3] = _mm512_unpackhi_ps(t6, t8); // x3 y3 z3 0 | x7 y7 z7 0 if (align % 4 == 0) { for (i = 0; i < 4; i++) { - _mm_store_ps(base + o[i], _mm_sub_ps(_mm_load_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); - _mm_store_ps(base + o[ 4 + i], - _mm_sub_ps(_mm_load_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1))); - _mm_store_ps(base + o[ 8 + i], - _mm_sub_ps(_mm_load_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2))); - _mm_store_ps(base + o[12 + i], - _mm_sub_ps(_mm_load_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3))); + _mm_store_ps(base + o[i], + _mm_sub_ps(_mm_load_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); + _mm_store_ps(base + o[4 + i], + _mm_sub_ps(_mm_load_ps(base + o[4 + i]), _mm512_extractf32x4_ps(t[i], 1))); + _mm_store_ps(base + o[8 + i], + _mm_sub_ps(_mm_load_ps(base + o[8 + i]), _mm512_extractf32x4_ps(t[i], 2))); + _mm_store_ps(base + o[12 + i], _mm_sub_ps(_mm_load_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3))); } } else { for (i = 0; i < 4; i++) { - _mm_storeu_ps(base + o[i], _mm_sub_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); - _mm_storeu_ps(base + o[ 4 + i], - _mm_sub_ps(_mm_loadu_ps(base + o[ 4 + i]), _mm512_extractf32x4_ps(t[i], 1))); - _mm_storeu_ps(base + o[ 8 + i], - _mm_sub_ps(_mm_loadu_ps(base + o[ 8 + i]), _mm512_extractf32x4_ps(t[i], 2))); - _mm_storeu_ps(base + o[12 + i], - _mm_sub_ps(_mm_loadu_ps(base + o[12 + i]), _mm512_extractf32x4_ps(t[i], 3))); + _mm_storeu_ps(base + o[i], + _mm_sub_ps(_mm_loadu_ps(base + o[i]), _mm512_castps512_ps128(t[i]))); + _mm_storeu_ps(base + o[4 + i], _mm_sub_ps(_mm_loadu_ps(base + o[4 + i]), + _mm512_extractf32x4_ps(t[i], 1))); + _mm_storeu_ps(base + o[8 + i], _mm_sub_ps(_mm_loadu_ps(base + o[8 + i]), + _mm512_extractf32x4_ps(t[i], 2))); + _mm_storeu_ps(base + o[12 + i], _mm_sub_ps(_mm_loadu_ps(base + o[12 + i]), + _mm512_extractf32x4_ps(t[i], 3))); } } } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { - triplets0->simdInternal_ = _mm512_permutexvar_ps(_mm512_set_epi32(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0), - scalar.simdInternal_); - triplets1->simdInternal_ = _mm512_permutexvar_ps(_mm512_set_epi32(10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5), - scalar.simdInternal_); - triplets2->simdInternal_ = _mm512_permutexvar_ps(_mm512_set_epi32(15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10), - scalar.simdInternal_); + triplets0->simdInternal_ = _mm512_permutexvar_ps( + _mm512_set_epi32(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0), scalar.simdInternal_); + triplets1->simdInternal_ = _mm512_permutexvar_ps( + _mm512_set_epi32(10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5), scalar.simdInternal_); + triplets2->simdInternal_ = _mm512_permutexvar_ps( + _mm512_set_epi32(15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10), + scalar.simdInternal_); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { __m512 t0, t1, t2; __m128 t3, t4; @@ -316,9 +310,11 @@ reduceIncr4ReturnSum(float * m, assert(std::size_t(m) % 16 == 0); t0 = _mm512_add_ps(v0.simdInternal_, _mm512_permute_ps(v0.simdInternal_, 0x4E)); - t0 = _mm512_mask_add_ps(t0, avx512Int2Mask(0xCCCC), v2.simdInternal_, _mm512_permute_ps(v2.simdInternal_, 0x4E)); + t0 = _mm512_mask_add_ps(t0, avx512Int2Mask(0xCCCC), v2.simdInternal_, + _mm512_permute_ps(v2.simdInternal_, 0x4E)); t1 = _mm512_add_ps(v1.simdInternal_, _mm512_permute_ps(v1.simdInternal_, 0x4E)); - t1 = _mm512_mask_add_ps(t1, avx512Int2Mask(0xCCCC), v3.simdInternal_, _mm512_permute_ps(v3.simdInternal_, 0x4E)); + t1 = _mm512_mask_add_ps(t1, avx512Int2Mask(0xCCCC), v3.simdInternal_, + _mm512_permute_ps(v3.simdInternal_, 0x4E)); t2 = _mm512_add_ps(t0, _mm512_permute_ps(t0, 0xB1)); t2 = _mm512_mask_add_ps(t2, avx512Int2Mask(0xAAAA), t1, _mm512_permute_ps(t1, 0xB1)); @@ -334,57 +330,42 @@ reduceIncr4ReturnSum(float * m, t3 = _mm_add_ps(t3, _mm_permute_ps(t3, 0xB1)); return _mm_cvtss_f32(t3); - } -static inline SimdFloat gmx_simdcall -loadDualHsimd(const float * m0, - const float * m1) +static inline SimdFloat gmx_simdcall loadDualHsimd(const float* m0, const float* m1) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); - return { - _mm512_castpd_ps(_mm512_insertf64x4(_mm512_castpd256_pd512(_mm256_load_pd(reinterpret_cast(m0))), - _mm256_load_pd(reinterpret_cast(m1)), 1)) - }; + return { _mm512_castpd_ps(_mm512_insertf64x4( + _mm512_castpd256_pd512(_mm256_load_pd(reinterpret_cast(m0))), + _mm256_load_pd(reinterpret_cast(m1)), 1)) }; } -static inline SimdFloat gmx_simdcall -loadDuplicateHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m) { assert(std::size_t(m) % 32 == 0); - return { - _mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_load_pd(reinterpret_cast(m)))) - }; + return { _mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_load_pd(reinterpret_cast(m)))) }; } -static inline SimdFloat gmx_simdcall -loadU1DualHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m) { - return { - _mm512_shuffle_f32x4(_mm512_broadcastss_ps(_mm_load_ss(m)), - _mm512_broadcastss_ps(_mm_load_ss(m+1)), 0x44) - }; + return { _mm512_shuffle_f32x4(_mm512_broadcastss_ps(_mm_load_ss(m)), + _mm512_broadcastss_ps(_mm_load_ss(m + 1)), 0x44) }; } -static inline void gmx_simdcall -storeDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall storeDualHsimd(float* m0, float* m1, SimdFloat a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); _mm256_store_ps(m0, _mm512_castps512_ps256(a.simdInternal_)); - _mm256_store_pd(reinterpret_cast(m1), _mm512_extractf64x4_pd(_mm512_castps_pd(a.simdInternal_), 1)); + _mm256_store_pd(reinterpret_cast(m1), + _mm512_extractf64x4_pd(_mm512_castps_pd(a.simdInternal_), 1)); } -static inline void gmx_simdcall -incrDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall incrDualHsimd(float* m0, float* m1, SimdFloat a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -402,28 +383,26 @@ incrDualHsimd(float * m0, _mm256_store_ps(m1, x); } -static inline void gmx_simdcall -decrHsimd(float * m, - SimdFloat a) +static inline void gmx_simdcall decrHsimd(float* m, SimdFloat a) { __m256 t; assert(std::size_t(m) % 32 == 0); - a.simdInternal_ = _mm512_add_ps(a.simdInternal_, _mm512_shuffle_f32x4(a.simdInternal_, a.simdInternal_, 0xEE)); + a.simdInternal_ = _mm512_add_ps(a.simdInternal_, + _mm512_shuffle_f32x4(a.simdInternal_, a.simdInternal_, 0xEE)); t = _mm256_load_ps(m); t = _mm256_sub_ps(t, _mm512_castps512_ps256(a.simdInternal_)); _mm256_store_ps(m, t); } -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const float * base0, - const float * base1, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const float* base0, + const float* base1, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1) { __m256i idx; __m512 tmp1, tmp2; @@ -440,20 +419,21 @@ gatherLoadTransposeHsimd(const float * base0, idx = _mm256_slli_epi32(idx, 1); } - tmp1 = _mm512_castpd_ps(_mm512_i32gather_pd(idx, reinterpret_cast(base0), sizeof(double))); - tmp2 = _mm512_castpd_ps(_mm512_i32gather_pd(idx, reinterpret_cast(base1), sizeof(double))); + tmp1 = _mm512_castpd_ps( + _mm512_i32gather_pd(idx, reinterpret_cast(base0), sizeof(double))); + tmp2 = _mm512_castpd_ps( + _mm512_i32gather_pd(idx, reinterpret_cast(base1), sizeof(double))); v0->simdInternal_ = _mm512_mask_moveldup_ps(tmp1, 0xAAAA, tmp2); v1->simdInternal_ = _mm512_mask_movehdup_ps(tmp2, 0x5555, tmp1); - v0->simdInternal_ = _mm512_permutexvar_ps(_mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), v0->simdInternal_); - v1->simdInternal_ = _mm512_permutexvar_ps(_mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), v1->simdInternal_); + v0->simdInternal_ = _mm512_permutexvar_ps( + _mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), v0->simdInternal_); + v1->simdInternal_ = _mm512_permutexvar_ps( + _mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), v1->simdInternal_); } -static inline float gmx_simdcall -reduceIncr4ReturnSumHsimd(float * m, - SimdFloat v0, - SimdFloat v1) +static inline float gmx_simdcall reduceIncr4ReturnSumHsimd(float* m, SimdFloat v0, SimdFloat v1) { __m512 t0, t1; __m128 t2, t3; @@ -478,33 +458,24 @@ reduceIncr4ReturnSumHsimd(float * m, return _mm_cvtss_f32(t3); } -static inline SimdFloat gmx_simdcall -loadUNDuplicate4(const float* f) +static inline SimdFloat gmx_simdcall loadUNDuplicate4(const float* f) { - return { - _mm512_permute_ps(_mm512_maskz_expandloadu_ps(0x1111, f), 0) - }; + return { _mm512_permute_ps(_mm512_maskz_expandloadu_ps(0x1111, f), 0) }; } -static inline SimdFloat gmx_simdcall -load4DuplicateN(const float* f) +static inline SimdFloat gmx_simdcall load4DuplicateN(const float* f) { - return { - _mm512_broadcast_f32x4(_mm_load_ps(f)) - }; + return { _mm512_broadcast_f32x4(_mm_load_ps(f)) }; } -static inline SimdFloat gmx_simdcall -loadU4NOffset(const float* f, int offset) +static inline SimdFloat gmx_simdcall loadU4NOffset(const float* f, int offset) { const __m256i idx = _mm256_setr_epi32(0, 0, 1, 1, 2, 2, 3, 3); const __m256i gdx = _mm256_add_epi32(_mm256_setr_epi32(0, 2, 0, 2, 0, 2, 0, 2), _mm256_mullo_epi32(idx, _mm256_set1_epi32(offset))); - return { - _mm512_castpd_ps(_mm512_i32gather_pd(gdx, reinterpret_cast(f), sizeof(float))) - }; + return { _mm512_castpd_ps(_mm512_i32gather_pd(gdx, reinterpret_cast(f), sizeof(float))) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_definitions.h b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_definitions.h index 940423552c..8d26f73939 100644 --- a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_definitions.h +++ b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,52 +38,52 @@ #include -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 // Technically it is straightforward to emulate extract on AVX-512F through // memory operations, but when applied to 16 elements as part of a table lookup // it will be faster to just store the entire vector once, so we avoid setting it. -#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 0 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 1 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 1 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 16 -#define GMX_SIMD_DOUBLE_WIDTH 8 -#define GMX_SIMD_FINT32_WIDTH 16 -#define GMX_SIMD_DINT32_WIDTH 8 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) -#define GMX_SIMD_RSQRT_BITS 28 -#define GMX_SIMD_RCP_BITS 28 +#define GMX_SIMD_FLOAT_WIDTH 16 +#define GMX_SIMD_DOUBLE_WIDTH 8 +#define GMX_SIMD_FINT32_WIDTH 16 +#define GMX_SIMD_DINT32_WIDTH 8 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) +#define GMX_SIMD_RSQRT_BITS 28 +#define GMX_SIMD_RCP_BITS 28 #endif // GMX_SIMD_IMPL_X86_AVX_512_KNL_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_double.h b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_double.h index b96dfbdbc2..9163a9a282 100644 --- a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_double.h +++ b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,18 +45,18 @@ namespace gmx { -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { return { -#ifndef NDEBUG //for debug mask to the 4 actually used elements to not trigger 1/0 fp exception - _mm512_castpd512_pd256(_mm512_maskz_rsqrt28_pd(avx512Int2Mask(0xF), _mm512_castpd256_pd512(x.simdInternal_))) +#ifndef NDEBUG // for debug mask to the 4 actually used elements to not trigger 1/0 fp exception + _mm512_castpd512_pd256(_mm512_maskz_rsqrt28_pd(avx512Int2Mask(0xF), + _mm512_castpd256_pd512(x.simdInternal_))) #else - _mm512_castpd512_pd256(_mm512_rsqrt28_pd(_mm512_castpd256_pd512(x.simdInternal_))) + _mm512_castpd512_pd256(_mm512_rsqrt28_pd(_mm512_castpd256_pd512(x.simdInternal_))) #endif }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_KNL_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_float.h b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_float.h index cd04ec231a..ff493eaf2d 100644 --- a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_float.h +++ b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,18 +45,18 @@ namespace gmx { -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { return { -#ifndef NDEBUG //for debug mask to the 4 actually used elements to not trigger 1/0 fp exception - _mm512_castps512_ps128(_mm512_maskz_rsqrt28_ps(avx512Int2Mask(0xF), _mm512_castps128_ps512(x.simdInternal_))) +#ifndef NDEBUG // for debug mask to the 4 actually used elements to not trigger 1/0 fp exception + _mm512_castps512_ps128(_mm512_maskz_rsqrt28_ps(avx512Int2Mask(0xF), + _mm512_castps128_ps512(x.simdInternal_))) #else - _mm512_castps512_ps128(_mm512_rsqrt28_ps(_mm512_castps128_ps512(x.simdInternal_))) + _mm512_castps512_ps128(_mm512_rsqrt28_ps(_mm512_castps128_ps512(x.simdInternal_))) #endif }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_KNL_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_double.h b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_double.h index 592be2ea8f..2bca1679e9 100644 --- a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_double.h +++ b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,38 +45,26 @@ namespace gmx { -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - _mm512_rsqrt28_pd(x.simdInternal_) - }; + return { _mm512_rsqrt28_pd(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - _mm512_rcp28_pd(x.simdInternal_) - }; + return { _mm512_rcp28_pd(x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { - return { - _mm512_maskz_rsqrt28_pd(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rsqrt28_pd(m.simdInternal_, x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { - return { - _mm512_maskz_rcp28_pd(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rcp28_pd(m.simdInternal_, x.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_KNL_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_float.h b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_float.h index 3c6749a67a..52f862314c 100644 --- a/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_float.h +++ b/src/gromacs/simd/impl_x86_avx_512_knl/impl_x86_avx_512_knl_simd_float.h @@ -46,53 +46,37 @@ namespace gmx { -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - _mm512_rsqrt28_ps(x.simdInternal_) - }; + return { _mm512_rsqrt28_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - _mm512_rcp28_ps(x.simdInternal_) - }; + return { _mm512_rcp28_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { - return { - _mm512_maskz_rsqrt28_ps(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rsqrt28_ps(m.simdInternal_, x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { - return { - _mm512_maskz_rcp28_ps(m.simdInternal_, x.simdInternal_) - }; + return { _mm512_maskz_rcp28_ps(m.simdInternal_, x.simdInternal_) }; } -template -static inline SimdFloat gmx_simdcall -exp2(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp2(SimdFloat x) { - return { - _mm512_exp2a23_ps(x.simdInternal_) - }; + return { _mm512_exp2a23_ps(x.simdInternal_) }; } -template -static inline SimdFloat gmx_simdcall -exp(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp(SimdFloat x) { - const __m512 argscale = _mm512_set1_ps(1.44269504088896341F); - const __m512 invargscale = _mm512_set1_ps(-0.69314718055994528623F); + const __m512 argscale = _mm512_set1_ps(1.44269504088896341F); + const __m512 invargscale = _mm512_set1_ps(-0.69314718055994528623F); if (opt == MathOptimization::Safe) { @@ -114,15 +98,13 @@ exp(SimdFloat x) // Note that this only adds two instructions (and maybe some constant loads). // find the difference - x = _mm512_fmadd_ps(invargscale, xscaled, x.simdInternal_); + x = _mm512_fmadd_ps(invargscale, xscaled, x.simdInternal_); // x will now be a _very_ small number, so approximate exp(x)=1+x. // We should thus apply the correction as r'=r*(1+x)=r+r*x - r = _mm512_fmadd_ps(r, x.simdInternal_, r); - return { - r - }; + r = _mm512_fmadd_ps(r, x.simdInternal_, r); + return { r }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_AVX_512_KNL_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_definitions.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_definitions.h index 628ee88fbf..2e9a6b6880 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_definitions.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -36,47 +36,47 @@ #ifndef GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H #define GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 1 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 1 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 1 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 1 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 1 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 16 -#define GMX_SIMD_DOUBLE_WIDTH 8 -#define GMX_SIMD_FINT32_WIDTH 16 -#define GMX_SIMD_DINT32_WIDTH 8 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) -#define GMX_SIMD_RSQRT_BITS 23 -#define GMX_SIMD_RCP_BITS 23 +#define GMX_SIMD_FLOAT_WIDTH 16 +#define GMX_SIMD_DOUBLE_WIDTH 8 +#define GMX_SIMD_FINT32_WIDTH 16 +#define GMX_SIMD_DINT32_WIDTH 8 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 64 // Bytes (16*single or 8*double) +#define GMX_SIMD_RSQRT_BITS 23 +#define GMX_SIMD_RCP_BITS 23 #endif // GMX_SIMD_IMPL_X86_MIC_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_general.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_general.h index 42b9c8cfd1..4c2c49f108 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_general.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,12 +41,11 @@ namespace gmx { -static inline void -simdPrefetch(const void * m) +static inline void simdPrefetch(const void* m) { - _mm_prefetch((const char *)m, _MM_HINT_T0); + _mm_prefetch((const char*)m, _MM_HINT_T0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_OTHER_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_double.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_double.h index 29320adf41..b4965c9677 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_double.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,250 +51,201 @@ namespace gmx class Simd4Double { - public: - Simd4Double() {} +public: + Simd4Double() {} - Simd4Double(double d) : simdInternal_(_mm512_set1_pd(d)) {} + Simd4Double(double d) : simdInternal_(_mm512_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - Simd4Double(__m512d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Double(__m512d simd) : simdInternal_(simd) {} - __m512d simdInternal_; + __m512d simdInternal_; }; class Simd4DBool { - public: - Simd4DBool() {} +public: + Simd4DBool() {} - // Internal utility constructor to simplify return statements - Simd4DBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4DBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline Simd4Double gmx_simdcall -load4(const double *m) +static inline Simd4Double gmx_simdcall load4(const double* m) { assert(size_t(m) % 32 == 0); - return { - _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) - }; + return { _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, + _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) }; } -static inline void gmx_simdcall -store4(double *m, Simd4Double a) +static inline void gmx_simdcall store4(double* m, Simd4Double a) { assert(size_t(m) % 32 == 0); _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), a.simdInternal_); } -static inline Simd4Double gmx_simdcall -load4U(const double *m) +static inline Simd4Double gmx_simdcall load4U(const double* m) { - return { - _mm512_mask_loadunpackhi_pd(_mm512_mask_loadunpacklo_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m), _mm512_int2mask(0xF), m+8) - }; + return { _mm512_mask_loadunpackhi_pd( + _mm512_mask_loadunpacklo_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m), + _mm512_int2mask(0xF), m + 8) }; } -static inline void gmx_simdcall -store4U(double *m, Simd4Double a) +static inline void gmx_simdcall store4U(double* m, Simd4Double a) { _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), a.simdInternal_); - _mm512_mask_packstorehi_pd(m+8, _mm512_int2mask(0xF), a.simdInternal_); + _mm512_mask_packstorehi_pd(m + 8, _mm512_int2mask(0xF), a.simdInternal_); } -static inline Simd4Double gmx_simdcall -simd4SetZeroD() +static inline Simd4Double gmx_simdcall simd4SetZeroD() { - return { - _mm512_setzero_pd() - }; + return { _mm512_setzero_pd() }; } -static inline Simd4Double gmx_simdcall -operator&(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator&(Simd4Double a, Simd4Double b) { - return { - _mm512_castsi512_pd(_mm512_mask_and_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), - _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_mask_and_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -andNot(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall andNot(Simd4Double a, Simd4Double b) { - return { - _mm512_castsi512_pd(_mm512_mask_andnot_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), - _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_mask_andnot_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -operator|(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator|(Simd4Double a, Simd4Double b) { - return { - _mm512_castsi512_pd(_mm512_mask_or_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), - _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_mask_or_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -operator^(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator^(Simd4Double a, Simd4Double b) { - return { - _mm512_castsi512_pd(_mm512_mask_xor_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), - _mm512_castpd_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_pd(_mm512_mask_xor_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), _mm512_castpd_si512(a.simdInternal_), + _mm512_castpd_si512(b.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -operator+(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator+(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_add_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_add_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator-(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_sub_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_sub_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -operator-(Simd4Double x) +static inline Simd4Double gmx_simdcall operator-(Simd4Double x) { - return { - _mm512_mask_addn_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_, _mm512_setzero_pd()) - }; + return { _mm512_mask_addn_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_, + _mm512_setzero_pd()) }; } -static inline Simd4Double gmx_simdcall -operator*(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall operator*(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_mul_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_mul_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm512_mask_fmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm512_mask_fmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnma(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnma(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm512_mask_fnmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fnmadd_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -fnms(Simd4Double a, Simd4Double b, Simd4Double c) +static inline Simd4Double gmx_simdcall fnms(Simd4Double a, Simd4Double b, Simd4Double c) { - return { - _mm512_mask_fnmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fnmsub_pd(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -rsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrt(Simd4Double x) { - return { - _mm512_mask_cvtpslo_pd(_mm512_undefined_pd(), - _mm512_int2mask(0xF), - _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), - _mm512_int2mask(0xF), - _mm512_mask_cvtpd_pslo(_mm512_undefined_ps(), - _mm512_int2mask(0xF), x.simdInternal_))) - }; + return { _mm512_mask_cvtpslo_pd( + _mm512_undefined_pd(), _mm512_int2mask(0xF), + _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), + _mm512_mask_cvtpd_pslo(_mm512_undefined_ps(), + _mm512_int2mask(0xF), x.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -abs(Simd4Double x) +static inline Simd4Double gmx_simdcall abs(Simd4Double x) { - return { - _mm512_castsi512_pd(_mm512_mask_andnot_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), - _mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)), - _mm512_castpd_si512(x.simdInternal_))) + return { _mm512_castsi512_pd(_mm512_mask_andnot_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0x00FF), + _mm512_castpd_si512(_mm512_set1_pd(GMX_DOUBLE_NEGZERO)), _mm512_castpd_si512(x.simdInternal_))) }; } -static inline Simd4Double gmx_simdcall -max(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall max(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_gmax_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_gmax_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -min(Simd4Double a, Simd4Double b) +static inline Simd4Double gmx_simdcall min(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_gmin_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_gmin_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -round(Simd4Double x) +static inline Simd4Double gmx_simdcall round(Simd4Double x) { - return { - _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) - }; + return { _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_, + _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) }; } -static inline Simd4Double gmx_simdcall -trunc(Simd4Double x) +static inline Simd4Double gmx_simdcall trunc(Simd4Double x) { - return { - _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) - }; + return { _mm512_mask_roundfxpnt_adjust_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), + x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) }; } -static inline double gmx_simdcall -dotProduct(Simd4Double a, Simd4Double b) +static inline double gmx_simdcall dotProduct(Simd4Double a, Simd4Double b) { return _mm512_mask_reduce_add_pd(_mm512_int2mask(7), _mm512_mask_mul_pd(_mm512_undefined_pd(), _mm512_int2mask(7), a.simdInternal_, b.simdInternal_)); } -static inline void gmx_simdcall -transpose(Simd4Double * v0, Simd4Double * v1, - Simd4Double * v2, Simd4Double * v3) +static inline void gmx_simdcall transpose(Simd4Double* v0, Simd4Double* v1, Simd4Double* v2, Simd4Double* v3) { __m512i t0 = _mm512_mask_permute4f128_epi32(_mm512_castpd_si512(v0->simdInternal_), 0xFF00, _mm512_castpd_si512(v1->simdInternal_), _MM_PERM_BABA); __m512i t1 = _mm512_mask_permute4f128_epi32(_mm512_castpd_si512(v2->simdInternal_), 0xFF00, _mm512_castpd_si512(v3->simdInternal_), _MM_PERM_BABA); - t0 = _mm512_permutevar_epi32(_mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t0); - t1 = _mm512_permutevar_epi32(_mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t1); + t0 = _mm512_permutevar_epi32( + _mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t0); + t1 = _mm512_permutevar_epi32( + _mm512_set_epi32(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0), t1); v0->simdInternal_ = _mm512_mask_swizzle_pd(_mm512_castsi512_pd(t0), _mm512_int2mask(0xCC), _mm512_castsi512_pd(t1), _MM_SWIZ_REG_BADC); v1->simdInternal_ = _mm512_mask_swizzle_pd(_mm512_castsi512_pd(t1), _mm512_int2mask(0x33), _mm512_castsi512_pd(t0), _MM_SWIZ_REG_BADC); - v2->simdInternal_ = _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v0->simdInternal_), _MM_PERM_DCDC)); - v3->simdInternal_ = _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v1->simdInternal_), _MM_PERM_DCDC)); + v2->simdInternal_ = + _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v0->simdInternal_), _MM_PERM_DCDC)); + v3->simdInternal_ = + _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(v1->simdInternal_), _MM_PERM_DCDC)); } // Picky, picky, picky: @@ -304,90 +255,61 @@ transpose(Simd4Double * v0, Simd4Double * v1, // 2) Unordered-quiet for != // 3) Ordered-signaling for < and <= -static inline Simd4DBool gmx_simdcall -operator==(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator==(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline Simd4DBool gmx_simdcall -operator!=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator!=(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) - }; + return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) }; } -static inline Simd4DBool gmx_simdcall -operator<(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) - }; + return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) }; } -static inline Simd4DBool gmx_simdcall -operator<=(Simd4Double a, Simd4Double b) +static inline Simd4DBool gmx_simdcall operator<=(Simd4Double a, Simd4Double b) { - return { - _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) - }; + return { _mm512_mask_cmp_pd_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) }; } -static inline Simd4DBool gmx_simdcall -operator&&(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator&&(Simd4DBool a, Simd4DBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4DBool gmx_simdcall -operator||(Simd4DBool a, Simd4DBool b) +static inline Simd4DBool gmx_simdcall operator||(Simd4DBool a, Simd4DBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4DBool a) +static inline bool gmx_simdcall anyTrue(Simd4DBool a) { return (_mm512_mask2int(a.simdInternal_) & 0xF) != 0; } -static inline Simd4Double gmx_simdcall -selectByMask(Simd4Double a, Simd4DBool m) +static inline Simd4Double gmx_simdcall selectByMask(Simd4Double a, Simd4DBool m) { - return { - _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -selectByNotMask(Simd4Double a, Simd4DBool m) +static inline Simd4Double gmx_simdcall selectByNotMask(Simd4Double a, Simd4DBool m) { - return { - _mm512_mask_mov_pd(_mm512_setzero_pd(), _mm512_knot(m.simdInternal_), a.simdInternal_) - }; + return { _mm512_mask_mov_pd(_mm512_setzero_pd(), _mm512_knot(m.simdInternal_), a.simdInternal_) }; } -static inline Simd4Double gmx_simdcall -blend(Simd4Double a, Simd4Double b, Simd4DBool sel) +static inline Simd4Double gmx_simdcall blend(Simd4Double a, Simd4Double b, Simd4DBool sel) { - return { - _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline double gmx_simdcall -reduce(Simd4Double a) +static inline double gmx_simdcall reduce(Simd4Double a) { return _mm512_mask_reduce_add_pd(_mm512_int2mask(0xF), a.simdInternal_); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_SIMD4_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_float.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_float.h index 2b72a39432..a9bb3a860a 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_float.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,242 +51,195 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) : simdInternal_(_mm512_set1_ps(f)) {} + Simd4Float(float f) : simdInternal_(_mm512_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(__m512 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__m512 simd) : simdInternal_(simd) {} - __m512 simdInternal_; + __m512 simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - // Internal utility constructor to simplify return statements - Simd4FBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { assert(size_t(m) % 16 == 0); - return { - _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE) - }; + return { _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, + _MM_UPCONV_PS_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { assert(size_t(m) % 16 == 0); _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), a.simdInternal_); } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { - _mm512_mask_loadunpackhi_ps(_mm512_mask_loadunpacklo_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m), _mm512_int2mask(0xF), m+16) - }; + return { _mm512_mask_loadunpackhi_ps( + _mm512_mask_loadunpacklo_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m), + _mm512_int2mask(0xF), m + 16) }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), a.simdInternal_); - _mm512_mask_packstorehi_ps(m+16, _mm512_int2mask(0xF), a.simdInternal_); + _mm512_mask_packstorehi_ps(m + 16, _mm512_int2mask(0xF), a.simdInternal_); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - _mm512_setzero_ps() - }; + return { _mm512_setzero_ps() }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - _mm512_castsi512_ps(_mm512_mask_and_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), - _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_mask_and_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), + _mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - _mm512_castsi512_ps(_mm512_mask_andnot_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), - _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_mask_andnot_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0xF), _mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - _mm512_castsi512_ps(_mm512_mask_or_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), - _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_mask_or_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), + _mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - _mm512_castsi512_ps(_mm512_mask_xor_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), - _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(b.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_mask_xor_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), + _mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(b.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_add_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_add_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_sub_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_sub_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - _mm512_mask_addn_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_, _mm512_setzero_ps()) - }; + return { _mm512_mask_addn_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_, + _mm512_setzero_ps()) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_mul_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_mul_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm512_mask_fmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm512_mask_fmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm512_mask_fnmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fnmadd_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm512_mask_fnmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) - }; + return { _mm512_mask_fnmsub_ps(a.simdInternal_, _mm512_int2mask(0xF), b.simdInternal_, c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_) - }; + return { _mm512_mask_rsqrt23_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - _mm512_castsi512_ps(_mm512_mask_andnot_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0xF), - _mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)), - _mm512_castps_si512(x.simdInternal_))) - }; + return { _mm512_castsi512_ps(_mm512_mask_andnot_epi32( + _mm512_undefined_epi32(), _mm512_int2mask(0xF), + _mm512_castps_si512(_mm512_set1_ps(GMX_FLOAT_NEGZERO)), _mm512_castps_si512(x.simdInternal_))) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_gmax_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_gmax_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_gmin_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_gmin_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), a.simdInternal_, + b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), - x.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) - }; + return { _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_, + _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), - x.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) - }; + return { _mm512_mask_round_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), x.simdInternal_, + _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { - __m512 x = _mm512_mask_mul_ps(_mm512_setzero_ps(), _mm512_int2mask(0x7), a.simdInternal_, b.simdInternal_); - x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC)); - x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB)); + __m512 x = _mm512_mask_mul_ps(_mm512_setzero_ps(), _mm512_int2mask(0x7), a.simdInternal_, + b.simdInternal_); + x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC)); + x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB)); float f; _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), x); return f; } -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { - v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0x00F0), v1->simdInternal_, _MM_PERM_AAAA); - v2->simdInternal_ = _mm512_mask_permute4f128_ps(v2->simdInternal_, _mm512_int2mask(0x00F0), v3->simdInternal_, _MM_PERM_AAAA); - v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0xFF00), v2->simdInternal_, _MM_PERM_BABA); - v0->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(_mm512_set_epi32(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0), - _mm512_castps_si512(v0->simdInternal_))); - v1->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), v0->simdInternal_, _MM_PERM_BBBB); - v2->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), v0->simdInternal_, _MM_PERM_CCCC); - v3->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), v0->simdInternal_, _MM_PERM_DDDD); + v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0x00F0), + v1->simdInternal_, _MM_PERM_AAAA); + v2->simdInternal_ = _mm512_mask_permute4f128_ps(v2->simdInternal_, _mm512_int2mask(0x00F0), + v3->simdInternal_, _MM_PERM_AAAA); + v0->simdInternal_ = _mm512_mask_permute4f128_ps(v0->simdInternal_, _mm512_int2mask(0xFF00), + v2->simdInternal_, _MM_PERM_BABA); + v0->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32( + _mm512_set_epi32(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0), + _mm512_castps_si512(v0->simdInternal_))); + v1->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), + v0->simdInternal_, _MM_PERM_BBBB); + v2->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), + v0->simdInternal_, _MM_PERM_CCCC); + v3->simdInternal_ = _mm512_mask_permute4f128_ps(_mm512_setzero_ps(), _mm512_int2mask(0x000F), + v0->simdInternal_, _MM_PERM_DDDD); } // Picky, picky, picky: @@ -296,95 +249,66 @@ transpose(Simd4Float * v0, Simd4Float * v1, // 2) Unordered-quiet for != // 3) Ordered-signaling for < and <= -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) - }; + return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) - }; + return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LT_OS) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) - }; + return { _mm512_mask_cmp_ps_mask(_mm512_int2mask(0xF), a.simdInternal_, b.simdInternal_, _CMP_LE_OS) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) +static inline bool gmx_simdcall anyTrue(Simd4FBool a) { - return ( _mm512_mask2int(a.simdInternal_) & 0xF) != 0; + return (_mm512_mask2int(a.simdInternal_) & 0xF) != 0; } -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool m) { - return { - _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool m) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool m) { - return { - _mm512_mask_mov_ps(_mm512_setzero_ps(), _mm512_knot(m.simdInternal_), a.simdInternal_) - }; + return { _mm512_mask_mov_ps(_mm512_setzero_ps(), _mm512_knot(m.simdInternal_), a.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __m512 x = a.simdInternal_; - x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC)); - x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB)); + x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_BADC)); + x = _mm512_add_ps(x, _mm512_swizzle_ps(x, _MM_SWIZ_REG_CDAB)); float f; _mm512_mask_packstorelo_ps(&f, _mm512_mask2int(0x1), x); return f; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_double.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_double.h index fbcaf1ea17..d549bd83c8 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_double.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,349 +53,258 @@ namespace gmx class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - SimdDouble(double d) : simdInternal_(_mm512_set1_pd(d)) {} + SimdDouble(double d) : simdInternal_(_mm512_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(__m512d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(__m512d simd) : simdInternal_(simd) {} - __m512d simdInternal_; + __m512d simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - SimdDInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} + SimdDInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(__m512i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(__m512i simd) : simdInternal_(simd) {} - __m512i simdInternal_; + __m512i simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - // Internal utility constructor to simplify return statements - SimdDBool(__mmask8 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(__mmask8 simd) : simdInternal_(simd) {} - __mmask8 simdInternal_; + __mmask8 simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - // Internal utility constructor to simplify return statements - SimdDIBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_pd(m) - }; + return { _mm512_load_pd(m) }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { assert(std::size_t(m) % 64 == 0); _mm512_store_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { - return { - _mm512_loadunpackhi_pd(_mm512_loadunpacklo_pd(_mm512_undefined_pd(), m), m+8) - }; + return { _mm512_loadunpackhi_pd(_mm512_loadunpacklo_pd(_mm512_undefined_pd(), m), m + 8) }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) +static inline void gmx_simdcall storeU(double* m, SimdDouble a) { _mm512_packstorelo_pd(m, a.simdInternal_); - _mm512_packstorehi_pd(m+8, a.simdInternal_); - + _mm512_packstorehi_pd(m + 8, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - _mm512_setzero_pd() - }; + return { _mm512_setzero_pd() }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { assert(std::size_t(m) % 32 == 0); - return { - _mm512_extload_epi64(m, _MM_UPCONV_EPI64_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) - }; + return { _mm512_extload_epi64(m, _MM_UPCONV_EPI64_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { assert(std::size_t(m) % 32 == 0); _mm512_mask_packstorelo_epi32(m, _mm512_int2mask(0x00FF), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { - return { - _mm512_mask_loadunpackhi_epi32(_mm512_mask_loadunpacklo_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), m), - _mm512_int2mask(0x00FF), m+16) - }; + return { _mm512_mask_loadunpackhi_epi32( + _mm512_mask_loadunpacklo_epi32(_mm512_undefined_epi32(), _mm512_int2mask(0x00FF), m), + _mm512_int2mask(0x00FF), m + 16) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { _mm512_mask_packstorelo_epi32(m, _mm512_int2mask(0x00FF), a.simdInternal_); - _mm512_mask_packstorehi_epi32(m+16, _mm512_int2mask(0x00FF), a.simdInternal_); + _mm512_mask_packstorehi_epi32(m + 16, _mm512_int2mask(0x00FF), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - _mm512_setzero_epi32() - }; + return { _mm512_setzero_epi32() }; } template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 a) { int r; - _mm512_mask_packstorelo_epi32(&r, _mm512_mask2int(1<simdInternal_ = _mm512_add_epi32(iExponent, _mm512_set1_epi32(1)); - return { - _mm512_getmant_pd(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) - }; + return { _mm512_getmant_pd(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { const __m512i exponentBias = _mm512_set1_epi32(1023); __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias); @@ -406,13 +315,13 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent = _mm512_max_epi32(iExponent, _mm512_setzero_epi32()); } - iExponent = _mm512_permutevar_epi32(_mm512_set_epi32(7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0), iExponent); + iExponent = _mm512_permutevar_epi32( + _mm512_set_epi32(7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0), iExponent); iExponent = _mm512_mask_slli_epi32(_mm512_setzero_epi32(), _mm512_int2mask(0xAAAA), iExponent, 20); return _mm512_mul_pd(_mm512_castsi512_pd(iExponent), value.simdInternal_); } -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { return _mm512_reduce_add_pd(a.simdInternal_); } @@ -424,40 +333,27 @@ reduce(SimdDouble a) // 2) Unordered-quiet for != // 3) Ordered-signaling for < and <= -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) - }; + return { _mm512_cmp_pd_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { // This is a bit problematic since Knight's corner does not have any 64-bit integer comparisons, // and we cannot use floating-point since values with just a single bit set can evaluate to 0.0. @@ -472,227 +368,148 @@ testBits(SimdDouble a) __m512i ia = _mm512_castpd_si512(a.simdInternal_); ia = _mm512_or_epi32(ia, _mm512_swizzle_epi32(ia, _MM_SWIZ_REG_CDAB)); - ia = _mm512_permutevar_epi32( _mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), ia); + ia = _mm512_permutevar_epi32( + _mm512_set_epi32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0), ia); - return { - static_cast<__mmask8>(_mm512_cmp_epi32_mask(ia, _mm512_setzero_si512(), _MM_CMPINT_NE)) - }; + return { static_cast<__mmask8>(_mm512_cmp_epi32_mask(ia, _mm512_setzero_si512(), _MM_CMPINT_NE)) }; } -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kand(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) - }; + return { static_cast<__mmask8>(_mm512_kor(a.simdInternal_, b.simdInternal_)) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) +static inline bool gmx_simdcall anyTrue(SimdDBool a) { return _mm512_mask2int(a.simdInternal_) != 0; } -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool m) { - return { - _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_pd(_mm512_setzero_pd(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool m) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool m) { - return { - _mm512_mask_mov_pd(a.simdInternal_, m.simdInternal_, _mm512_setzero_pd()) - }; + return { _mm512_mask_mov_pd(a.simdInternal_, m.simdInternal_, _mm512_setzero_pd()) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_pd(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_and_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_and_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_or_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_or_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, _mm512_setzero_si512(), _MM_CMPINT_NE) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, _mm512_setzero_si512(), _MM_CMPINT_NE) }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) +static inline bool gmx_simdcall anyTrue(SimdDIBool a) { - return ( _mm512_mask2int(a.simdInternal_) & 0xFF) != 0; + return (_mm512_mask2int(a.simdInternal_) & 0xFF) != 0; } -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool m) { - return { - _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool m) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool m) { - return { - _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) - }; + return { _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { - return { - _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT) - }; + return { _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { - return { - _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_ZERO) - }; + return { _mm512_cvtfxpnt_roundpd_epi32lo(a.simdInternal_, _MM_FROUND_TO_ZERO) }; } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { - return { - _mm512_cvtepi32lo_pd(a.simdInternal_) - }; + return { _mm512_cvtepi32lo_pd(a.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { - return { - static_cast<__mmask8>(a.simdInternal_) - }; + return { static_cast<__mmask8>(a.simdInternal_) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { __m512i i1 = _mm512_permute4f128_epi32(_mm512_castps_si512(f.simdInternal_), _MM_PERM_DCDC); @@ -700,16 +517,13 @@ cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) *d1 = _mm512_cvtpslo_pd(_mm512_castsi512_ps(i1)); } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { __m512 f0 = _mm512_cvtpd_pslo(d0.simdInternal_); __m512 f1 = _mm512_cvtpd_pslo(d1.simdInternal_); - return { - _mm512_mask_permute4f128_ps(f0, _mm512_int2mask(0xFF00), f1, _MM_PERM_BABA) - }; + return { _mm512_mask_permute4f128_ps(f0, _mm512_int2mask(0xFF00), f1, _MM_PERM_BABA) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_float.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_float.h index 87b9b8f318..ec01923119 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_float.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_simd_float.h @@ -50,352 +50,260 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) : simdInternal_(_mm512_set1_ps(f)) {} + SimdFloat(float f) : simdInternal_(_mm512_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(__m512 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__m512 simd) : simdInternal_(simd) {} - __m512 simdInternal_; + __m512 simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} + SimdFInt32(std::int32_t i) : simdInternal_(_mm512_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(__m512i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__m512i simd) : simdInternal_(simd) {} - __m512i simdInternal_; + __m512i simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_(_mm512_int2mask( b ? 0xFFFF : 0)) {} + SimdFBool(bool b) : simdInternal_(_mm512_int2mask(b ? 0xFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_(_mm512_int2mask( b ? 0xFFFF : 0)) {} + SimdFIBool(bool b) : simdInternal_(_mm512_int2mask(b ? 0xFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFIBool(__mmask16 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__mmask16 simd) : simdInternal_(simd) {} - __mmask16 simdInternal_; + __mmask16 simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_ps(m) - }; + return { _mm512_load_ps(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { assert(std::size_t(m) % 64 == 0); _mm512_store_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { - return { - _mm512_loadunpackhi_ps(_mm512_loadunpacklo_ps(_mm512_undefined_ps(), m), m+16) - }; + return { _mm512_loadunpackhi_ps(_mm512_loadunpacklo_ps(_mm512_undefined_ps(), m), m + 16) }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) +static inline void gmx_simdcall storeU(float* m, SimdFloat a) { _mm512_packstorelo_ps(m, a.simdInternal_); - _mm512_packstorehi_ps(m+16, a.simdInternal_); + _mm512_packstorehi_ps(m + 16, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - _mm512_setzero_ps() - }; + return { _mm512_setzero_ps() }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { assert(std::size_t(m) % 64 == 0); - return { - _mm512_load_epi32(m) - }; + return { _mm512_load_epi32(m) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { assert(std::size_t(m) % 64 == 0); _mm512_store_epi32(m, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { - return { - _mm512_loadunpackhi_epi32(_mm512_loadunpacklo_epi32(_mm512_undefined_epi32(), m), m+16) - }; + return { _mm512_loadunpackhi_epi32(_mm512_loadunpacklo_epi32(_mm512_undefined_epi32(), m), m + 16) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { _mm512_packstorelo_epi32(m, a.simdInternal_); - _mm512_packstorehi_epi32(m+16, a.simdInternal_); + _mm512_packstorehi_epi32(m + 16, a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - _mm512_setzero_si512() - }; + return { _mm512_setzero_si512() }; } template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 a) { int r; - _mm512_mask_packstorelo_epi32(&r, _mm512_mask2int(1<simdInternal_ = _mm512_add_epi32(iExponent, _mm512_set1_epi32(1)); - return { - _mm512_getmant_ps(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) - }; + return { _mm512_getmant_ps(value.simdInternal_, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { const __m512i exponentBias = _mm512_set1_epi32(127); __m512i iExponent = _mm512_add_epi32(exponent.simdInternal_, exponentBias); @@ -406,15 +314,12 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = _mm512_max_epi32(iExponent, _mm512_setzero_epi32()); } - iExponent = _mm512_slli_epi32( iExponent, 23); + iExponent = _mm512_slli_epi32(iExponent, 23); - return { - _mm512_mul_ps(value.simdInternal_, _mm512_castsi512_ps(iExponent)) - }; + return { _mm512_mul_ps(value.simdInternal_, _mm512_castsi512_ps(iExponent)) }; } -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { return _mm512_reduce_add_ps(a.simdInternal_); } @@ -426,274 +331,182 @@ reduce(SimdFloat a) // 2) Unordered-quiet for != // 3) Ordered-signaling for < and <= -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_EQ_OQ) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_NEQ_UQ) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LT_OS) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) - }; + return { _mm512_cmp_ps_mask(a.simdInternal_, b.simdInternal_, _CMP_LE_OS) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { - return { - _mm512_test_epi32_mask( _mm512_castps_si512(a.simdInternal_), _mm512_castps_si512(a.simdInternal_) ) - }; + return { _mm512_test_epi32_mask(_mm512_castps_si512(a.simdInternal_), + _mm512_castps_si512(a.simdInternal_)) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) +static inline bool gmx_simdcall anyTrue(SimdFBool a) { return _mm512_mask2int(a.simdInternal_) != 0; } -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool m) { - return { - _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_ps(_mm512_setzero_ps(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool m) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool m) { - return { - _mm512_mask_mov_ps(a.simdInternal_, m.simdInternal_, _mm512_setzero_ps()) - }; + return { _mm512_mask_mov_ps(a.simdInternal_, m.simdInternal_, _mm512_setzero_ps()) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_ps(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_and_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_and_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_andnot_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_or_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_or_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_xor_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_sub_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_EQ) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { - return { - _mm512_test_epi32_mask( a.simdInternal_, a.simdInternal_ ) - }; + return { _mm512_test_epi32_mask(a.simdInternal_, a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) - }; + return { _mm512_cmp_epi32_mask(a.simdInternal_, b.simdInternal_, _MM_CMPINT_LT) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - _mm512_kand(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kand(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - _mm512_kor(a.simdInternal_, b.simdInternal_) - }; + return { _mm512_kor(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) +static inline bool gmx_simdcall anyTrue(SimdFIBool a) { return _mm512_mask2int(a.simdInternal_) != 0; } -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool m) { - return { - _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) - }; + return { _mm512_mask_mov_epi32(_mm512_setzero_epi32(), m.simdInternal_, a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool m) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool m) { - return { - _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) - }; + return { _mm512_mask_mov_epi32(a.simdInternal_, m.simdInternal_, _mm512_setzero_epi32()) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) - }; + return { _mm512_mask_blend_epi32(sel.simdInternal_, a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) - }; + return { _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT, + _MM_EXPADJ_NONE) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) - }; + return { _mm512_cvtfxpnt_round_adjustps_epi32(a.simdInternal_, _MM_FROUND_TO_ZERO, _MM_EXPADJ_NONE) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - _mm512_cvtfxpnt_round_adjustepi32_ps(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT, _MM_EXPADJ_NONE) - }; + return { _mm512_cvtfxpnt_round_adjustepi32_ps(a.simdInternal_, _MM_FROUND_TO_NEAREST_INT, + _MM_EXPADJ_NONE) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - a.simdInternal_ - }; + return { a.simdInternal_ }; } -template -static inline SimdFloat gmx_simdcall -exp2(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp2(SimdFloat x) { - return { - _mm512_exp223_ps(_mm512_cvtfxpnt_round_adjustps_epi32(x.simdInternal_, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24)) - }; + return { _mm512_exp223_ps(_mm512_cvtfxpnt_round_adjustps_epi32( + x.simdInternal_, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24)) }; } -template -static inline SimdFloat gmx_simdcall -exp(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp(SimdFloat x) { - const __m512 argscale = _mm512_set1_ps(1.44269504088896341F); - const __m512 invargscale = _mm512_set1_ps(-0.69314718055994528623F); + const __m512 argscale = _mm512_set1_ps(1.44269504088896341F); + const __m512 invargscale = _mm512_set1_ps(-0.69314718055994528623F); if (opt == MathOptimization::Safe) { @@ -704,8 +517,9 @@ exp(SimdFloat x) x = max(x, smallArgLimit); } - __m512 xscaled = _mm512_mul_ps(x.simdInternal_, argscale); - __m512 r = _mm512_exp223_ps(_mm512_cvtfxpnt_round_adjustps_epi32(xscaled, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24)); + __m512 xscaled = _mm512_mul_ps(x.simdInternal_, argscale); + __m512 r = _mm512_exp223_ps( + _mm512_cvtfxpnt_round_adjustps_epi32(xscaled, _MM_ROUND_MODE_NEAREST, _MM_EXPADJ_24)); // exp2a23_ps provides 23 bits of accuracy, but we ruin some of that with our argument // scaling. To correct this, we find the difference between the scaled argument and @@ -715,23 +529,19 @@ exp(SimdFloat x) // Note that this only adds two instructions (and maybe some constant loads). // find the difference - x = _mm512_fmadd_ps(invargscale, xscaled, x.simdInternal_); + x = _mm512_fmadd_ps(invargscale, xscaled, x.simdInternal_); // x will now be a _very_ small number, so approximate exp(x)=1+x. // We should thus apply the correction as r'=r*(1+x)=r+r*x - r = _mm512_fmadd_ps(r, x.simdInternal_, r); - return { - r - }; + r = _mm512_fmadd_ps(r, x.simdInternal_, r); + return { r }; } -static inline SimdFloat gmx_simdcall -log(SimdFloat x) +static inline SimdFloat gmx_simdcall log(SimdFloat x) { - return { - _mm512_mul_ps(_mm512_set1_ps(0.693147180559945286226764F), _mm512_log2ae23_ps(x.simdInternal_)) - }; + return { _mm512_mul_ps(_mm512_set1_ps(0.693147180559945286226764F), + _mm512_log2ae23_ps(x.simdInternal_)) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_double.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_double.h index e6d6679818..bc4fd5ec3f 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_double.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,14 +53,13 @@ namespace gmx // On MIC it is better to use scatter operations, so we define the load routines // that use a SIMD offset variable first. -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 simdoffset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 simdoffset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { assert((size_t)base % 32 == 0); assert(align % 4 == 0); @@ -81,18 +80,17 @@ gatherLoadBySimdIntTranspose(const double * base, simdoffset = simdoffset * SimdDInt32(align); } - v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); - v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+1, sizeof(double)); - v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+2, sizeof(double)); - v3->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+3, sizeof(double)); + v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); + v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double)); + v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 2, sizeof(double)); + v3->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 3, sizeof(double)); } -template -static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 simdoffset, - SimdDouble * v0, - SimdDouble * v1) +template +static inline void gmx_simdcall gatherLoadUBySimdIntTranspose(const double* base, + SimdDInt32 simdoffset, + SimdDouble* v0, + SimdDouble* v1) { // All instructions might be latency ~4 on MIC, so we use shifts where we // only need a single instruction (since the shift parameter is an immediate), @@ -114,16 +112,15 @@ gatherLoadUBySimdIntTranspose(const double * base, simdoffset = simdoffset * SimdDInt32(align); } - v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); - v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+1, sizeof(double)); + v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); + v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double)); } -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 simdoffset, - SimdDouble * v0, - SimdDouble * v1) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 simdoffset, + SimdDouble* v0, + SimdDouble* v1) { assert(std::size_t(base) % 16 == 0); assert(align % 2 == 0); @@ -131,39 +128,32 @@ gatherLoadBySimdIntTranspose(const double * base, } - - -template -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdDInt32Tag()), v0, v1); } static const int c_simdBestPairAlignmentDouble = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { SimdDInt32 simdoffset; @@ -187,18 +177,17 @@ gatherLoadUTranspose(const double * base, simdoffset = simdoffset * SimdDInt32(align); } - v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); - v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+1, sizeof(double)); - v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base+2, sizeof(double)); + v0->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base, sizeof(double)); + v1->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 1, sizeof(double)); + v2->simdInternal_ = _mm512_i32logather_pd(simdoffset.simdInternal_, base + 2, sizeof(double)); } -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { SimdDInt32 simdoffset; @@ -222,22 +211,18 @@ transposeScatterStoreU(double * base, simdoffset = simdoffset * SimdDInt32(align); } - _mm512_i32loscatter_pd(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(double)); - _mm512_i32loscatter_pd(base+1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(double)); - _mm512_i32loscatter_pd(base+2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(double)); + _mm512_i32loscatter_pd(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(double)); + _mm512_i32loscatter_pd(base + 1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(double)); + _mm512_i32loscatter_pd(base + 2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(double)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { - alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH]; store(rdata0, v0); store(rdata1, v1); @@ -245,23 +230,19 @@ transposeScatterIncrU(double * base, for (int i = 0; i < GMX_SIMD_DOUBLE_WIDTH; i++) { - base[ align * offset[i] + 0] += rdata0[i]; - base[ align * offset[i] + 1] += rdata1[i]; - base[ align * offset[i] + 2] += rdata2[i]; + base[align * offset[i] + 0] += rdata0[i]; + base[align * offset[i] + 1] += rdata1[i]; + base[align * offset[i] + 2] += rdata2[i]; } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { - alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata0[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata1[GMX_SIMD_DOUBLE_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double rdata2[GMX_SIMD_DOUBLE_WIDTH]; store(rdata0, v0); store(rdata1, v1); @@ -269,42 +250,42 @@ transposeScatterDecrU(double * base, for (int i = 0; i < GMX_SIMD_DOUBLE_WIDTH; i++) { - base[ align * offset[i] + 0] -= rdata0[i]; - base[ align * offset[i] + 1] -= rdata1[i]; - base[ align * offset[i] + 2] -= rdata2[i]; + base[align * offset[i] + 0] -= rdata0[i]; + base[align * offset[i] + 1] -= rdata1[i]; + base[align * offset[i] + 2] -= rdata2[i]; } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { - triplets0->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0), - _mm512_castpd_si512(scalar.simdInternal_))); - triplets1->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32(_mm512_set_epi32(11, 10, 9, 8, 9, 8, 9, 8, 7, 6, 7, 6, 7, 6, 5, 4), - _mm512_castpd_si512(scalar.simdInternal_))); - triplets2->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32(_mm512_set_epi32(15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 11, 10, 11, 10), - _mm512_castpd_si512(scalar.simdInternal_))); + triplets0->simdInternal_ = _mm512_castsi512_pd( + _mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0), + _mm512_castpd_si512(scalar.simdInternal_))); + triplets1->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32( + _mm512_set_epi32(11, 10, 9, 8, 9, 8, 9, 8, 7, 6, 7, 6, 7, 6, 5, 4), + _mm512_castpd_si512(scalar.simdInternal_))); + triplets2->simdInternal_ = _mm512_castsi512_pd(_mm512_permutevar_epi32( + _mm512_set_epi32(15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 11, 10, 11, 10), + _mm512_castpd_si512(scalar.simdInternal_))); } static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { double d; __m512d t0, t1, t2, t3; assert(std::size_t(m) % 32 == 0); - t0 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v0.simdInternal_, v2.simdInternal_), _MM_SWIZ_REG_BADC); + t0 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v0.simdInternal_, v2.simdInternal_), + _MM_SWIZ_REG_BADC); t2 = _mm512_mask_blend_pd(_mm512_int2mask(0x33), v2.simdInternal_, v0.simdInternal_); - t1 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v1.simdInternal_, v3.simdInternal_), _MM_SWIZ_REG_BADC); + t1 = _mm512_swizzle_pd(_mm512_mask_blend_pd(_mm512_int2mask(0x33), v1.simdInternal_, v3.simdInternal_), + _MM_SWIZ_REG_BADC); t3 = _mm512_mask_blend_pd(_mm512_int2mask(0x33), v3.simdInternal_, v1.simdInternal_); t0 = _mm512_add_pd(t0, t2); t1 = _mm512_add_pd(t1, t3); @@ -315,7 +296,8 @@ reduceIncr4ReturnSum(double * m, t2 = _mm512_add_pd(t2, _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(t2), _MM_PERM_BADC))); - t0 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); + t0 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE); t0 = _mm512_add_pd(t0, t2); _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), t0); @@ -326,37 +308,32 @@ reduceIncr4ReturnSum(double * m, return d; } -static inline SimdDouble gmx_simdcall -loadDualHsimd(const double * m0, - const double * m1) +static inline SimdDouble gmx_simdcall loadDualHsimd(const double* m0, const double* m1) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); - return _mm512_mask_extload_pd(_mm512_extload_pd(m0, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE), _mm512_int2mask(0xF0), - m1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); + return _mm512_mask_extload_pd( + _mm512_extload_pd(m0, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE), + _mm512_int2mask(0xF0), m1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); } -static inline SimdDouble gmx_simdcall -loadDuplicateHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadDuplicateHsimd(const double* m) { assert(std::size_t(m) % 32 == 0); return _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); } -static inline SimdDouble gmx_simdcall -loadU1DualHsimd(const double * m) +static inline SimdDouble gmx_simdcall loadU1DualHsimd(const double* m) { - return _mm512_mask_extload_pd(_mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE), _mm512_int2mask(0xF0), - m+1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE); + return _mm512_mask_extload_pd( + _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE), + _mm512_int2mask(0xF0), m + 1, _MM_UPCONV_PD_NONE, _MM_BROADCAST_1X8, _MM_HINT_NONE); } -static inline void gmx_simdcall -storeDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall storeDualHsimd(double* m0, double* m1, SimdDouble a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -365,10 +342,7 @@ storeDualHsimd(double * m0, _mm512_mask_packstorelo_pd(m1, _mm512_int2mask(0xF0), a.simdInternal_); } -static inline void gmx_simdcall -incrDualHsimd(double * m0, - double * m1, - SimdDouble a) +static inline void gmx_simdcall incrDualHsimd(double* m0, double* m1, SimdDouble a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -386,36 +360,35 @@ incrDualHsimd(double * m0, _mm512_mask_packstorelo_pd(m1, _mm512_int2mask(0xF0), x); } -static inline void gmx_simdcall -decrHsimd(double * m, - SimdDouble a) +static inline void gmx_simdcall decrHsimd(double* m, SimdDouble a) { __m512d t; assert(std::size_t(m) % 32 == 0); t = _mm512_extload_pd(m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); - a.simdInternal_ = _mm512_add_pd(a.simdInternal_, _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(a.simdInternal_), _MM_PERM_BADC))); - t = _mm512_sub_pd(t, a.simdInternal_); + a.simdInternal_ = _mm512_add_pd( + a.simdInternal_, + _mm512_castps_pd(_mm512_permute4f128_ps(_mm512_castpd_ps(a.simdInternal_), _MM_PERM_BADC))); + t = _mm512_sub_pd(t, a.simdInternal_); _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0x0F), t); } -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const double * base0, - const double * base1, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const double* base0, + const double* base1, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1) { - __m512i idx0, idx1, idx; - __m512d tmp1, tmp2; + __m512i idx0, idx1, idx; + __m512d tmp1, tmp2; assert(std::size_t(offset) % 16 == 0); assert(std::size_t(base0) % 16 == 0); assert(std::size_t(base1) % 16 == 0); - assert(std::size_t(align) % 2 == 0); + assert(std::size_t(align) % 2 == 0); idx0 = _mm512_extload_epi32(offset, _MM_UPCONV_EPI32_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE); @@ -427,27 +400,28 @@ gatherLoadTransposeHsimd(const double * base0, tmp1 = _mm512_i32logather_pd(idx, base0, sizeof(double)); tmp2 = _mm512_i32logather_pd(idx, base1, sizeof(double)); - v0->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps(_mm512_castpd_ps(tmp1), _mm512_int2mask(0xFF00), _mm512_castpd_ps(tmp2), _MM_PERM_BABA)); - v1->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps(_mm512_castpd_ps(tmp2), _mm512_int2mask(0x00FF), _mm512_castpd_ps(tmp1), _MM_PERM_DCDC)); + v0->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps( + _mm512_castpd_ps(tmp1), _mm512_int2mask(0xFF00), _mm512_castpd_ps(tmp2), _MM_PERM_BABA)); + v1->simdInternal_ = _mm512_castps_pd(_mm512_mask_permute4f128_ps( + _mm512_castpd_ps(tmp2), _mm512_int2mask(0x00FF), _mm512_castpd_ps(tmp1), _MM_PERM_DCDC)); } -static inline double gmx_simdcall -reduceIncr4ReturnSumHsimd(double * m, - SimdDouble v0, - SimdDouble v1) +static inline double gmx_simdcall reduceIncr4ReturnSumHsimd(double* m, SimdDouble v0, SimdDouble v1) { - double d; - __m512d t0, t1; + double d; + __m512d t0, t1; assert(std::size_t(m) % 32 == 0); t0 = _mm512_add_pd(v0.simdInternal_, _mm512_swizzle_pd(v0.simdInternal_, _MM_SWIZ_REG_BADC)); - t0 = _mm512_mask_add_pd(t0, _mm512_int2mask(0xCC), v1.simdInternal_, _mm512_swizzle_pd(v1.simdInternal_, _MM_SWIZ_REG_BADC)); + t0 = _mm512_mask_add_pd(t0, _mm512_int2mask(0xCC), v1.simdInternal_, + _mm512_swizzle_pd(v1.simdInternal_, _MM_SWIZ_REG_BADC)); t0 = _mm512_add_pd(t0, _mm512_swizzle_pd(t0, _MM_SWIZ_REG_CDAB)); t0 = _mm512_castps_pd(_mm512_mask_permute4f128_ps(_mm512_castpd_ps(t0), _mm512_int2mask(0xCCCC), _mm512_castpd_ps(t0), _MM_PERM_DCDC)); - t1 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE); + t1 = _mm512_mask_extload_pd(_mm512_undefined_pd(), _mm512_int2mask(0xF), m, _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE); t1 = _mm512_add_pd(t1, t0); _mm512_mask_packstorelo_pd(m, _mm512_int2mask(0xF), t1); @@ -458,6 +432,6 @@ reduceIncr4ReturnSumHsimd(double * m, return d; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_float.h b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_float.h index b766e1b444..4911d74c5b 100644 --- a/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_float.h +++ b/src/gromacs/simd/impl_x86_mic/impl_x86_mic_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,14 +53,13 @@ namespace gmx // On MIC it is better to use scatter operations, so we define the load routines // that use a SIMD offset variable first. -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 simdoffset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { assert(std::size_t(base) % 16 == 0); assert(align % 4 == 0); @@ -81,18 +80,15 @@ gatherLoadBySimdIntTranspose(const float * base, simdoffset = simdoffset * SimdFInt32(align); } - v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); - v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+1, sizeof(float)); - v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+2, sizeof(float)); - v3->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+3, sizeof(float)); + v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); + v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float)); + v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 2, sizeof(float)); + v3->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 3, sizeof(float)); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1) { // All instructions might be latency ~4 on MIC, so we use shifts where we // only need a single instruction (since the shift parameter is an immediate), @@ -101,8 +97,9 @@ gatherLoadUBySimdIntTranspose(const float * base, // which can take constants up to 8 in total. if (align == 2) { - v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, align * sizeof(float)); - v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+1, align * sizeof(float)); + v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, align * sizeof(float)); + v1->simdInternal_ = + _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, align * sizeof(float)); } else { @@ -118,54 +115,46 @@ gatherLoadUBySimdIntTranspose(const float * base, { simdoffset = simdoffset * SimdFInt32(align); } - v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); - v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+1, sizeof(float)); + v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); + v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float)); } } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 simdoffset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 simdoffset, SimdFloat* v0, SimdFloat* v1) { assert(std::size_t(base) % 8 == 0); assert(align % 2 == 0); gatherLoadUBySimdIntTranspose(base, simdoffset, v0, v1); } -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { gatherLoadBySimdIntTranspose(base, simdLoad(offset, SimdFInt32Tag()), v0, v1); } static const int c_simdBestPairAlignmentFloat = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { SimdFInt32 simdoffset; @@ -189,19 +178,15 @@ gatherLoadUTranspose(const float * base, simdoffset = simdoffset * SimdFInt32(align); } - v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); - v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+1, sizeof(float)); - v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base+2, sizeof(float)); + v0->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base, sizeof(float)); + v1->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 1, sizeof(float)); + v2->simdInternal_ = _mm512_i32gather_ps(simdoffset.simdInternal_, base + 2, sizeof(float)); } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { SimdFInt32 simdoffset; @@ -225,23 +210,19 @@ transposeScatterStoreU(float * base, simdoffset = simdoffset * SimdFInt32(align); } - _mm512_i32scatter_ps(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(float)); - _mm512_i32scatter_ps(base+1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(float)); - _mm512_i32scatter_ps(base+2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(float)); + _mm512_i32scatter_ps(base, simdoffset.simdInternal_, v0.simdInternal_, sizeof(float)); + _mm512_i32scatter_ps(base + 1, simdoffset.simdInternal_, v1.simdInternal_, sizeof(float)); + _mm512_i32scatter_ps(base + 2, simdoffset.simdInternal_, v2.simdInternal_, sizeof(float)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { - alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH]; store(rdata0, v0); store(rdata1, v1); @@ -249,23 +230,19 @@ transposeScatterIncrU(float * base, for (int i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { - base[ align * offset[i] + 0] += rdata0[i]; - base[ align * offset[i] + 1] += rdata1[i]; - base[ align * offset[i] + 2] += rdata2[i]; + base[align * offset[i] + 0] += rdata0[i]; + base[align * offset[i] + 1] += rdata1[i]; + base[align * offset[i] + 2] += rdata2[i]; } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { - alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata0[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata1[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) float rdata2[GMX_SIMD_FLOAT_WIDTH]; store(rdata0, v0); store(rdata1, v1); @@ -273,33 +250,30 @@ transposeScatterDecrU(float * base, for (int i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { - base[ align * offset[i] + 0] -= rdata0[i]; - base[ align * offset[i] + 1] -= rdata1[i]; - base[ align * offset[i] + 2] -= rdata2[i]; + base[align * offset[i] + 0] -= rdata0[i]; + base[align * offset[i] + 1] -= rdata1[i]; + base[align * offset[i] + 2] -= rdata2[i]; } } -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { - triplets0->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0), - _mm512_castps_si512(scalar.simdInternal_))); - triplets1->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(_mm512_set_epi32(10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5), - _mm512_castps_si512(scalar.simdInternal_))); - triplets2->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32(_mm512_set_epi32(15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10), - _mm512_castps_si512(scalar.simdInternal_))); + triplets0->simdInternal_ = _mm512_castsi512_ps( + _mm512_permutevar_epi32(_mm512_set_epi32(5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0), + _mm512_castps_si512(scalar.simdInternal_))); + triplets1->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32( + _mm512_set_epi32(10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5), + _mm512_castps_si512(scalar.simdInternal_))); + triplets2->simdInternal_ = _mm512_castsi512_ps(_mm512_permutevar_epi32( + _mm512_set_epi32(15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10), + _mm512_castps_si512(scalar.simdInternal_))); } -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { float f; __m512 t0, t1, t2, t3; @@ -307,16 +281,19 @@ reduceIncr4ReturnSum(float * m, assert(std::size_t(m) % 16 == 0); t0 = _mm512_add_ps(v0.simdInternal_, _mm512_swizzle_ps(v0.simdInternal_, _MM_SWIZ_REG_BADC)); - t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v2.simdInternal_, _mm512_swizzle_ps(v2.simdInternal_, _MM_SWIZ_REG_BADC)); + t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v2.simdInternal_, + _mm512_swizzle_ps(v2.simdInternal_, _MM_SWIZ_REG_BADC)); t1 = _mm512_add_ps(v1.simdInternal_, _mm512_swizzle_ps(v1.simdInternal_, _MM_SWIZ_REG_BADC)); - t1 = _mm512_mask_add_ps(t1, _mm512_int2mask(0xCCCC), v3.simdInternal_, _mm512_swizzle_ps(v3.simdInternal_, _MM_SWIZ_REG_BADC)); + t1 = _mm512_mask_add_ps(t1, _mm512_int2mask(0xCCCC), v3.simdInternal_, + _mm512_swizzle_ps(v3.simdInternal_, _MM_SWIZ_REG_BADC)); t2 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_CDAB)); t2 = _mm512_mask_add_ps(t2, _mm512_int2mask(0xAAAA), t1, _mm512_swizzle_ps(t1, _MM_SWIZ_REG_CDAB)); t2 = _mm512_add_ps(t2, _mm512_permute4f128_ps(t2, _MM_PERM_BADC)); t2 = _mm512_add_ps(t2, _mm512_permute4f128_ps(t2, _MM_PERM_CDAB)); - t0 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE); + t0 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE, + _MM_BROADCAST_4X16, _MM_HINT_NONE); t0 = _mm512_add_ps(t0, t2); _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), t0); @@ -327,37 +304,35 @@ reduceIncr4ReturnSum(float * m, return f; } -static inline SimdFloat gmx_simdcall -loadDualHsimd(const float * m0, - const float * m1) +static inline SimdFloat gmx_simdcall loadDualHsimd(const float* m0, const float* m1) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); - return _mm512_castpd_ps(_mm512_mask_extload_pd(_mm512_extload_pd(reinterpret_cast(m0), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE), - _mm512_int2mask(0xF0), reinterpret_cast(m1), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); + return _mm512_castpd_ps(_mm512_mask_extload_pd( + _mm512_extload_pd(reinterpret_cast(m0), _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE), + _mm512_int2mask(0xF0), reinterpret_cast(m1), _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE)); } -static inline SimdFloat gmx_simdcall -loadDuplicateHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadDuplicateHsimd(const float* m) { assert(std::size_t(m) % 32 == 0); - return _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); + return _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m), + _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); } -static inline SimdFloat gmx_simdcall -loadU1DualHsimd(const float * m) +static inline SimdFloat gmx_simdcall loadU1DualHsimd(const float* m) { - return _mm512_mask_extload_ps(_mm512_extload_ps(m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE), _mm512_int2mask(0xFF00), - m+1, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE); + return _mm512_mask_extload_ps( + _mm512_extload_ps(m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE), + _mm512_int2mask(0xFF00), m + 1, _MM_UPCONV_PS_NONE, _MM_BROADCAST_1X16, _MM_HINT_NONE); } -static inline void gmx_simdcall -storeDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall storeDualHsimd(float* m0, float* m1, SimdFloat a) { __m512 t0; @@ -368,10 +343,7 @@ storeDualHsimd(float * m0, _mm512_mask_packstorelo_ps(m1, _mm512_int2mask(0xFF00), a.simdInternal_); } -static inline void gmx_simdcall -incrDualHsimd(float * m0, - float * m1, - SimdFloat a) +static inline void gmx_simdcall incrDualHsimd(float* m0, float* m1, SimdFloat a) { assert(std::size_t(m0) % 32 == 0); assert(std::size_t(m1) % 32 == 0); @@ -379,38 +351,38 @@ incrDualHsimd(float * m0, __m512 x; // Update lower half - x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m0), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); + x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m0), _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE)); x = _mm512_add_ps(x, a.simdInternal_); _mm512_mask_packstorelo_ps(m0, _mm512_int2mask(0x00FF), x); // Update upper half - x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m1), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); + x = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m1), _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE)); x = _mm512_add_ps(x, a.simdInternal_); _mm512_mask_packstorelo_ps(m1, _mm512_int2mask(0xFF00), x); } -static inline void gmx_simdcall -decrHsimd(float * m, - SimdFloat a) +static inline void gmx_simdcall decrHsimd(float* m, SimdFloat a) { __m512 t; assert(std::size_t(m) % 32 == 0); - t = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m), _MM_UPCONV_PD_NONE, _MM_BROADCAST_4X8, _MM_HINT_NONE)); + t = _mm512_castpd_ps(_mm512_extload_pd(reinterpret_cast(m), _MM_UPCONV_PD_NONE, + _MM_BROADCAST_4X8, _MM_HINT_NONE)); a = _mm512_add_ps(a.simdInternal_, _mm512_permute4f128_ps(a.simdInternal_, _MM_PERM_BADC)); t = _mm512_sub_ps(t, a.simdInternal_); _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0x00FF), t); } -template -static inline void gmx_simdcall -gatherLoadTransposeHsimd(const float * base0, - const float * base1, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) +template +static inline void gmx_simdcall gatherLoadTransposeHsimd(const float* base0, + const float* base1, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1) { __m512i idx0, idx1, idx; __m512 tmp1, tmp2; @@ -434,10 +406,7 @@ gatherLoadTransposeHsimd(const float * base0, v1->simdInternal_ = _mm512_mask_permute4f128_ps(tmp2, _mm512_int2mask(0x00FF), tmp1, _MM_PERM_DCDC); } -static inline float gmx_simdcall -reduceIncr4ReturnSumHsimd(float * m, - SimdFloat v0, - SimdFloat v1) +static inline float gmx_simdcall reduceIncr4ReturnSumHsimd(float* m, SimdFloat v0, SimdFloat v1) { float f; __m512 t0, t1; @@ -445,11 +414,13 @@ reduceIncr4ReturnSumHsimd(float * m, assert(std::size_t(m) % 32 == 0); t0 = _mm512_add_ps(v0.simdInternal_, _mm512_swizzle_ps(v0.simdInternal_, _MM_SWIZ_REG_BADC)); - t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v1.simdInternal_, _mm512_swizzle_ps(v1.simdInternal_, _MM_SWIZ_REG_BADC)); + t0 = _mm512_mask_add_ps(t0, _mm512_int2mask(0xCCCC), v1.simdInternal_, + _mm512_swizzle_ps(v1.simdInternal_, _MM_SWIZ_REG_BADC)); t0 = _mm512_add_ps(t0, _mm512_swizzle_ps(t0, _MM_SWIZ_REG_CDAB)); t0 = _mm512_add_ps(t0, _mm512_castpd_ps(_mm512_swizzle_pd(_mm512_castps_pd(t0), _MM_SWIZ_REG_BADC))); t0 = _mm512_mask_permute4f128_ps(t0, _mm512_int2mask(0xAAAA), t0, _MM_PERM_BADC); - t1 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE, _MM_BROADCAST_4X16, _MM_HINT_NONE); + t1 = _mm512_mask_extload_ps(_mm512_undefined_ps(), _mm512_int2mask(0xF), m, _MM_UPCONV_PS_NONE, + _MM_BROADCAST_4X16, _MM_HINT_NONE); t1 = _mm512_add_ps(t1, t0); _mm512_mask_packstorelo_ps(m, _mm512_int2mask(0xF), t1); @@ -460,6 +431,6 @@ reduceIncr4ReturnSumHsimd(float * m, return f; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_MIC_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_definitions.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_definitions.h index 85128bb0dc..d22389cb41 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_definitions.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,47 +37,47 @@ #define GMX_SIMD_IMPL_X86_SSE2_DEFINITIONS_H // Capability definitions for SSE2. -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 0 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 // No SSE2 instruction, but use shifts -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 // No SSE2 instruction, but use shifts -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 0 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 // No SSE2 instruction, but use shifts +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 // No SSE2 instruction, but use shifts +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 #endif // GMX_SIMD_IMPL_X86_SSE2_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_general.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_general.h index 6ae98c835c..7eefa2f37e 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_general.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_general.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,12 +40,11 @@ namespace gmx { -static inline void -simdPrefetch(void * m) +static inline void simdPrefetch(void* m) { - _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); + _mm_prefetch(reinterpret_cast(m), _MM_HINT_T0); } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_GENERAL_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd4_float.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd4_float.h index a2af83a127..0cff9bd951 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd4_float.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,326 +47,235 @@ namespace gmx class Simd4Float { - public: - Simd4Float() {} +public: + Simd4Float() {} - Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} + Simd4Float(float f) : simdInternal_(_mm_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - Simd4Float(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4Float(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; class Simd4FBool { - public: - Simd4FBool() {} +public: + Simd4FBool() {} - //! \brief Construct from scalar bool - Simd4FBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + //! \brief Construct from scalar bool + Simd4FBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - Simd4FBool(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + Simd4FBool(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; -static inline Simd4Float gmx_simdcall -load4(const float *m) +static inline Simd4Float gmx_simdcall load4(const float* m) { assert(size_t(m) % 16 == 0); - return { - _mm_load_ps(m) - }; + return { _mm_load_ps(m) }; } -static inline void gmx_simdcall -store4(float *m, Simd4Float a) +static inline void gmx_simdcall store4(float* m, Simd4Float a) { assert(size_t(m) % 16 == 0); _mm_store_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -load4U(const float *m) +static inline Simd4Float gmx_simdcall load4U(const float* m) { - return { - _mm_loadu_ps(m) - }; + return { _mm_loadu_ps(m) }; } -static inline void gmx_simdcall -store4U(float *m, Simd4Float a) +static inline void gmx_simdcall store4U(float* m, Simd4Float a) { _mm_storeu_ps(m, a.simdInternal_); } -static inline Simd4Float gmx_simdcall -simd4SetZeroF() +static inline Simd4Float gmx_simdcall simd4SetZeroF() { - return { - _mm_setzero_ps() - }; + return { _mm_setzero_ps() }; } -static inline Simd4Float gmx_simdcall -operator&(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator&(Simd4Float a, Simd4Float b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -andNot(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall andNot(Simd4Float a, Simd4Float b) { - return { - _mm_andnot_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator|(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator|(Simd4Float a, Simd4Float b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator^(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator^(Simd4Float a, Simd4Float b) { - return { - _mm_xor_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator+(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator+(Simd4Float a, Simd4Float b) { - return { - _mm_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator-(Simd4Float a, Simd4Float b) { - return { - _mm_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -operator-(Simd4Float x) +static inline Simd4Float gmx_simdcall operator-(Simd4Float x) { - return { - _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) - }; + return { _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) }; } -static inline Simd4Float gmx_simdcall -operator*(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall operator*(Simd4Float a, Simd4Float b) { - return { - _mm_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mul_ps(a.simdInternal_, b.simdInternal_) }; } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline Simd4Float gmx_simdcall -fma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -fnma(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnma(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) - }; + return { _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -fnms(Simd4Float a, Simd4Float b, Simd4Float c) +static inline Simd4Float gmx_simdcall fnms(Simd4Float a, Simd4Float b, Simd4Float c) { - return { - _mm_sub_ps(_mm_setzero_ps(), _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm_sub_ps(_mm_setzero_ps(), + _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline Simd4Float gmx_simdcall -rsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrt(Simd4Float x) { - return { - _mm_rsqrt_ps(x.simdInternal_) - }; + return { _mm_rsqrt_ps(x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -abs(Simd4Float x) +static inline Simd4Float gmx_simdcall abs(Simd4Float x) { - return { - _mm_andnot_ps( _mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_ ) - }; + return { _mm_andnot_ps(_mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -max(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall max(Simd4Float a, Simd4Float b) { - return { - _mm_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -min(Simd4Float a, Simd4Float b) +static inline Simd4Float gmx_simdcall min(Simd4Float a, Simd4Float b) { - return { - _mm_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_min_ps(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - _mm_cvtepi32_ps( _mm_cvtps_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_ps(_mm_cvtps_epi32(x.simdInternal_)) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - _mm_cvtepi32_ps( _mm_cvttps_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_ps(_mm_cvttps_epi32(x.simdInternal_)) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { __m128 c, d; c = _mm_mul_ps(a.simdInternal_, b.simdInternal_); d = _mm_add_ps(c, _mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 1, 2, 1))); d = _mm_add_ps(d, _mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 2, 3, 2))); - return *reinterpret_cast(&d); + return *reinterpret_cast(&d); } #endif -static inline void gmx_simdcall -transpose(Simd4Float * v0, Simd4Float * v1, - Simd4Float * v2, Simd4Float * v3) +static inline void gmx_simdcall transpose(Simd4Float* v0, Simd4Float* v1, Simd4Float* v2, Simd4Float* v3) { _MM_TRANSPOSE4_PS(v0->simdInternal_, v1->simdInternal_, v2->simdInternal_, v3->simdInternal_); } -static inline Simd4FBool gmx_simdcall -operator==(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator==(Simd4Float a, Simd4Float b) { - return { - _mm_cmpeq_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator!=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator!=(Simd4Float a, Simd4Float b) { - return { - _mm_cmpneq_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpneq_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator<(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<(Simd4Float a, Simd4Float b) { - return { - _mm_cmplt_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator<=(Simd4Float a, Simd4Float b) +static inline Simd4FBool gmx_simdcall operator<=(Simd4Float a, Simd4Float b) { - return { - _mm_cmple_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmple_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator&&(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator&&(Simd4FBool a, Simd4FBool b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline Simd4FBool gmx_simdcall -operator||(Simd4FBool a, Simd4FBool b) +static inline Simd4FBool gmx_simdcall operator||(Simd4FBool a, Simd4FBool b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(Simd4FBool a) { return _mm_movemask_ps(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(Simd4FBool a) +{ + return _mm_movemask_ps(a.simdInternal_) != 0; +} -static inline Simd4Float gmx_simdcall -selectByMask(Simd4Float a, Simd4FBool mask) +static inline Simd4Float gmx_simdcall selectByMask(Simd4Float a, Simd4FBool mask) { - return { - _mm_and_ps(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, mask.simdInternal_) }; } -static inline Simd4Float gmx_simdcall -selectByNotMask(Simd4Float a, Simd4FBool mask) +static inline Simd4Float gmx_simdcall selectByNotMask(Simd4Float a, Simd4FBool mask) { - return { - _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - _mm_or_ps(_mm_andnot_ps(sel.simdInternal_, a.simdInternal_), _mm_and_ps(sel.simdInternal_, b.simdInternal_)) - }; + return { _mm_or_ps(_mm_andnot_ps(sel.simdInternal_, a.simdInternal_), + _mm_and_ps(sel.simdInternal_, b.simdInternal_)) }; } #endif // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline float gmx_simdcall -reduce(Simd4Float a) +static inline float gmx_simdcall reduce(Simd4Float a) { __m128 b; - b = _mm_add_ps(a.simdInternal_, _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); + b = _mm_add_ps(a.simdInternal_, + _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); b = _mm_add_ss(b, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + return *reinterpret_cast(&b); } #endif -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_double.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_double.h index 2a49131b6b..b81839eb5c 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_double.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,379 +52,289 @@ namespace gmx class SimdDouble { - public: - SimdDouble() {} +public: + SimdDouble() {} - SimdDouble(double d) : simdInternal_(_mm_set1_pd(d)) {} + SimdDouble(double d) : simdInternal_(_mm_set1_pd(d)) {} - // Internal utility constructor to simplify return statements - SimdDouble(__m128d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDouble(__m128d simd) : simdInternal_(simd) {} - __m128d simdInternal_; + __m128d simdInternal_; }; class SimdDInt32 { - public: - SimdDInt32() {} +public: + SimdDInt32() {} - SimdDInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} + SimdDInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdDInt32(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDInt32(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; class SimdDBool { - public: - SimdDBool() {} +public: + SimdDBool() {} - SimdDBool(bool b) : simdInternal_(_mm_castsi128_pd(_mm_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + SimdDBool(bool b) : simdInternal_(_mm_castsi128_pd(_mm_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - SimdDBool(__m128d simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDBool(__m128d simd) : simdInternal_(simd) {} - __m128d simdInternal_; + __m128d simdInternal_; }; class SimdDIBool { - public: - SimdDIBool() {} +public: + SimdDIBool() {} - SimdDIBool(bool b) : simdInternal_(_mm_set1_epi32( b ? 0xFFFFFFFF : 0)) {} + SimdDIBool(bool b) : simdInternal_(_mm_set1_epi32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdDIBool(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdDIBool(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; -static inline SimdDouble gmx_simdcall -simdLoad(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoad(const double* m, SimdDoubleTag = {}) { assert(std::size_t(m) % 16 == 0); - return { - _mm_load_pd(m) - }; + return { _mm_load_pd(m) }; } -static inline void gmx_simdcall -store(double *m, SimdDouble a) +static inline void gmx_simdcall store(double* m, SimdDouble a) { assert(std::size_t(m) % 16 == 0); _mm_store_pd(m, a.simdInternal_); } -static inline SimdDouble gmx_simdcall -simdLoadU(const double *m, SimdDoubleTag = {}) +static inline SimdDouble gmx_simdcall simdLoadU(const double* m, SimdDoubleTag = {}) { - return { - _mm_loadu_pd(m) - }; + return { _mm_loadu_pd(m) }; } -static inline void gmx_simdcall -storeU(double *m, SimdDouble a) { _mm_storeu_pd(m, a.simdInternal_); } +static inline void gmx_simdcall storeU(double* m, SimdDouble a) +{ + _mm_storeu_pd(m, a.simdInternal_); +} -static inline SimdDouble gmx_simdcall -setZeroD() +static inline SimdDouble gmx_simdcall setZeroD() { - return { - _mm_setzero_pd() - }; + return { _mm_setzero_pd() }; } -static inline SimdDInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdDInt32Tag) { assert(std::size_t(m) % 8 == 0); - return { - _mm_loadl_epi64(reinterpret_cast(m)) - }; + return { _mm_loadl_epi64(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdDInt32 a) { assert(std::size_t(m) % 8 == 0); - _mm_storel_epi64(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_storel_epi64(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdDInt32Tag) +static inline SimdDInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdDInt32Tag) { - return { - _mm_loadl_epi64(reinterpret_cast(m)) - }; + return { _mm_loadl_epi64(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdDInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdDInt32 a) { - _mm_storel_epi64(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_storel_epi64(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdDInt32 gmx_simdcall -setZeroDI() +static inline SimdDInt32 gmx_simdcall setZeroDI() { - return { - _mm_setzero_si128() - }; + return { _mm_setzero_si128() }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 a) { - return _mm_cvtsi128_si32( _mm_srli_si128(a.simdInternal_, 4 * index) ); + return _mm_cvtsi128_si32(_mm_srli_si128(a.simdInternal_, 4 * index)); } #endif -static inline SimdDouble gmx_simdcall -operator&(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator&(SimdDouble a, SimdDouble b) { - return { - _mm_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -andNot(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall andNot(SimdDouble a, SimdDouble b) { - return { - _mm_andnot_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator|(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator|(SimdDouble a, SimdDouble b) { - return { - _mm_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator^(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator^(SimdDouble a, SimdDouble b) { - return { - _mm_xor_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator+(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator+(SimdDouble a, SimdDouble b) { - return { - _mm_add_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator-(SimdDouble a, SimdDouble b) { - return { - _mm_sub_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -operator-(SimdDouble x) +static inline SimdDouble gmx_simdcall operator-(SimdDouble x) { - return { - _mm_xor_pd(x.simdInternal_, _mm_set1_pd(GMX_DOUBLE_NEGZERO)) - }; + return { _mm_xor_pd(x.simdInternal_, _mm_set1_pd(GMX_DOUBLE_NEGZERO)) }; } -static inline SimdDouble gmx_simdcall -operator*(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall operator*(SimdDouble a, SimdDouble b) { - return { - _mm_mul_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mul_pd(a.simdInternal_, b.simdInternal_) }; } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline SimdDouble gmx_simdcall -fma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_sub_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_sub_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -fnma(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnma(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_sub_pd(c.simdInternal_, _mm_mul_pd(a.simdInternal_, b.simdInternal_)) - }; + return { _mm_sub_pd(c.simdInternal_, _mm_mul_pd(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -fnms(SimdDouble a, SimdDouble b, SimdDouble c) +static inline SimdDouble gmx_simdcall fnms(SimdDouble a, SimdDouble b, SimdDouble c) { - return { - _mm_sub_pd(_mm_setzero_pd(), _mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm_sub_pd(_mm_setzero_pd(), + _mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline SimdDouble gmx_simdcall -rsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrt(SimdDouble x) { - return { - _mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))) - }; + return { _mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -rcp(SimdDouble x) +static inline SimdDouble gmx_simdcall rcp(SimdDouble x) { - return { - _mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))) - }; + return { _mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))) }; } -static inline SimdDouble gmx_simdcall -maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskAdd(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm_add_pd(a.simdInternal_, _mm_and_pd(b.simdInternal_, m.simdInternal_)) - }; + return { _mm_add_pd(a.simdInternal_, _mm_and_pd(b.simdInternal_, m.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzMul(SimdDouble a, SimdDouble b, SimdDBool m) { - return { - _mm_and_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), m.simdInternal_) - }; + return { _mm_and_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), m.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzFma(SimdDouble a, SimdDouble b, SimdDouble c, SimdDBool m) { - return { - _mm_and_pd(_mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_), m.simdInternal_) - }; + return { _mm_and_pd(_mm_add_pd(_mm_mul_pd(a.simdInternal_, b.simdInternal_), c.simdInternal_), + m.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDouble gmx_simdcall -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRsqrt(SimdDouble x, SimdDBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions -#ifndef NDEBUG - x.simdInternal_ = _mm_or_pd(_mm_andnot_pd(m.simdInternal_, _mm_set1_pd(1.0)), _mm_and_pd(m.simdInternal_, x.simdInternal_)); -#endif - return { - _mm_and_pd(_mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; +# ifndef NDEBUG + x.simdInternal_ = _mm_or_pd(_mm_andnot_pd(m.simdInternal_, _mm_set1_pd(1.0)), + _mm_and_pd(m.simdInternal_, x.simdInternal_)); +# endif + return { _mm_and_pd(_mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzRcp(SimdDouble x, SimdDBool m) { // The result will always be correct since we mask the result with m, but // for debug builds we also want to make sure not to generate FP exceptions -#ifndef NDEBUG - x.simdInternal_ = _mm_or_pd(_mm_andnot_pd(m.simdInternal_, _mm_set1_pd(1.0)), _mm_and_pd(m.simdInternal_, x.simdInternal_)); -#endif - return { - _mm_and_pd(_mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; +# ifndef NDEBUG + x.simdInternal_ = _mm_or_pd(_mm_andnot_pd(m.simdInternal_, _mm_set1_pd(1.0)), + _mm_and_pd(m.simdInternal_, x.simdInternal_)); +# endif + return { _mm_and_pd(_mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } #endif -static inline SimdDouble gmx_simdcall -abs(SimdDouble x) +static inline SimdDouble gmx_simdcall abs(SimdDouble x) { - return { - _mm_andnot_pd( _mm_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_ ) - }; + return { _mm_andnot_pd(_mm_set1_pd(GMX_DOUBLE_NEGZERO), x.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -max(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall max(SimdDouble a, SimdDouble b) { - return { - _mm_max_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_max_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -min(SimdDouble a, SimdDouble b) +static inline SimdDouble gmx_simdcall min(SimdDouble a, SimdDouble b) { - return { - _mm_min_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_min_pd(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { - return { - _mm_cvtepi32_pd( _mm_cvtpd_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_pd(_mm_cvtpd_epi32(x.simdInternal_)) }; } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { - return { - _mm_cvtepi32_pd( _mm_cvttpd_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_pd(_mm_cvttpd_epi32(x.simdInternal_)) }; } #endif -static inline SimdDouble -frexp(SimdDouble value, SimdDInt32 * exponent) +static inline SimdDouble frexp(SimdDouble value, SimdDInt32* exponent) { // Don't use _mm_set1_epi64x() - on MSVC it is only supported for 64-bit builds - const __m128d exponentMask = _mm_castsi128_pd( _mm_set_epi32(0x7FF00000, 0x00000000, 0x7FF00000, 0x00000000) ); - const __m128d mantissaMask = _mm_castsi128_pd( _mm_set_epi32(0x800FFFFF, 0xFFFFFFFF, 0x800FFFFF, 0xFFFFFFFF) ); + const __m128d exponentMask = + _mm_castsi128_pd(_mm_set_epi32(0x7FF00000, 0x00000000, 0x7FF00000, 0x00000000)); + const __m128d mantissaMask = + _mm_castsi128_pd(_mm_set_epi32(0x800FFFFF, 0xFFFFFFFF, 0x800FFFFF, 0xFFFFFFFF)); const __m128i exponentBias = _mm_set1_epi32(1022); // add 1 to make our definition identical to frexp() - const __m128d half = _mm_set1_pd(0.5); + const __m128d half = _mm_set1_pd(0.5); __m128i iExponent; iExponent = _mm_castpd_si128(_mm_and_pd(value.simdInternal_, exponentMask)); iExponent = _mm_sub_epi32(_mm_srli_epi64(iExponent, 52), exponentBias); - iExponent = _mm_shuffle_epi32(iExponent, _MM_SHUFFLE(3, 1, 2, 0) ); + iExponent = _mm_shuffle_epi32(iExponent, _MM_SHUFFLE(3, 1, 2, 0)); exponent->simdInternal_ = iExponent; - return { - _mm_or_pd(_mm_and_pd(value.simdInternal_, mantissaMask), half) - }; + return { _mm_or_pd(_mm_and_pd(value.simdInternal_, mantissaMask), half) }; } // Override for SSE4.1 #if GMX_SIMD_X86_SSE2 -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { - const __m128i exponentBias = _mm_set1_epi32(1023); - __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); + const __m128i exponentBias = _mm_set1_epi32(1023); + __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -437,313 +347,220 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent = _mm_shuffle_epi32(iExponent, _MM_SHUFFLE(3, 1, 2, 0)); iExponent = _mm_slli_epi64(iExponent, 52); - return { - _mm_mul_pd(value.simdInternal_, _mm_castsi128_pd(iExponent)) - }; + return { _mm_mul_pd(value.simdInternal_, _mm_castsi128_pd(iExponent)) }; } #endif // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline double gmx_simdcall -reduce(SimdDouble a) +static inline double gmx_simdcall reduce(SimdDouble a) { - __m128d b = _mm_add_sd(a.simdInternal_, _mm_shuffle_pd(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&b); + __m128d b = _mm_add_sd(a.simdInternal_, + _mm_shuffle_pd(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE2(1, 1))); + return *reinterpret_cast(&b); } #endif -static inline SimdDBool gmx_simdcall -operator==(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator==(SimdDouble a, SimdDouble b) { - return { - _mm_cmpeq_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator!=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator!=(SimdDouble a, SimdDouble b) { - return { - _mm_cmpneq_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpneq_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator<(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<(SimdDouble a, SimdDouble b) { - return { - _mm_cmplt_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator<=(SimdDouble a, SimdDouble b) +static inline SimdDBool gmx_simdcall operator<=(SimdDouble a, SimdDouble b) { - return { - _mm_cmple_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmple_pd(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { - __m128i ia = _mm_castpd_si128(a.simdInternal_); - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi32(ia, _mm_setzero_si128()), _mm_cmpeq_epi32(ia, ia)); + __m128i ia = _mm_castpd_si128(a.simdInternal_); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi32(ia, _mm_setzero_si128()), _mm_cmpeq_epi32(ia, ia)); // set each 64-bit element if low or high 32-bit part is set res = _mm_or_si128(res, _mm_shuffle_epi32(res, _MM_SHUFFLE(2, 3, 0, 1))); - return { - _mm_castsi128_pd(res) - }; + return { _mm_castsi128_pd(res) }; } #endif -static inline SimdDBool gmx_simdcall -operator&&(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator&&(SimdDBool a, SimdDBool b) { - return { - _mm_and_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_pd(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDBool gmx_simdcall -operator||(SimdDBool a, SimdDBool b) +static inline SimdDBool gmx_simdcall operator||(SimdDBool a, SimdDBool b) { - return { - _mm_or_pd(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_pd(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDBool a) { return _mm_movemask_pd(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdDBool a) +{ + return _mm_movemask_pd(a.simdInternal_) != 0; +} -static inline SimdDouble gmx_simdcall -selectByMask(SimdDouble a, SimdDBool mask) +static inline SimdDouble gmx_simdcall selectByMask(SimdDouble a, SimdDBool mask) { - return { - _mm_and_pd(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_pd(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -selectByNotMask(SimdDouble a, SimdDBool mask) +static inline SimdDouble gmx_simdcall selectByNotMask(SimdDouble a, SimdDBool mask) { - return { - _mm_andnot_pd(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_pd(mask.simdInternal_, a.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - _mm_or_pd(_mm_andnot_pd(sel.simdInternal_, a.simdInternal_), _mm_and_pd(sel.simdInternal_, b.simdInternal_)) - }; + return { _mm_or_pd(_mm_andnot_pd(sel.simdInternal_, a.simdInternal_), + _mm_and_pd(sel.simdInternal_, b.simdInternal_)) }; } #endif -static inline SimdDInt32 gmx_simdcall -operator&(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator&(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -andNot(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall andNot(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_andnot_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator|(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator|(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator^(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator^(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_xor_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator+(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator+(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator-(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator-(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_epi32(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { __m128i tmpA = _mm_unpacklo_epi32(a.simdInternal_, _mm_setzero_si128()); // 0 a[1] 0 a[0] __m128i tmpB = _mm_unpacklo_epi32(b.simdInternal_, _mm_setzero_si128()); // 0 b[1] 0 b[0] - __m128i tmpC = _mm_mul_epu32(tmpA, tmpB); // 0 a[1]*b[1] 0 a[0]*b[0] + __m128i tmpC = _mm_mul_epu32(tmpA, tmpB); // 0 a[1]*b[1] 0 a[0]*b[0] - return { - _mm_shuffle_epi32(tmpC, _MM_SHUFFLE(3, 1, 2, 0)) - }; + return { _mm_shuffle_epi32(tmpC, _MM_SHUFFLE(3, 1, 2, 0)) }; } #endif -static inline SimdDIBool gmx_simdcall -operator==(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator==(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -testBits(SimdDInt32 a) +static inline SimdDIBool gmx_simdcall testBits(SimdDInt32 a) { __m128i x = a.simdInternal_; - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); - return { - res - }; + return { res }; } -static inline SimdDIBool gmx_simdcall -operator<(SimdDInt32 a, SimdDInt32 b) +static inline SimdDIBool gmx_simdcall operator<(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator&&(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator&&(SimdDIBool a, SimdDIBool b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -operator||(SimdDIBool a, SimdDIBool b) +static inline SimdDIBool gmx_simdcall operator||(SimdDIBool a, SimdDIBool b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdDIBool a) +static inline bool gmx_simdcall anyTrue(SimdDIBool a) { return _mm_movemask_epi8(_mm_shuffle_epi32(a.simdInternal_, _MM_SHUFFLE(1, 0, 1, 0))) != 0; } -static inline SimdDInt32 gmx_simdcall -selectByMask(SimdDInt32 a, SimdDIBool mask) +static inline SimdDInt32 gmx_simdcall selectByMask(SimdDInt32 a, SimdDIBool mask) { - return { - _mm_and_si128(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -selectByNotMask(SimdDInt32 a, SimdDIBool mask) +static inline SimdDInt32 gmx_simdcall selectByNotMask(SimdDInt32 a, SimdDIBool mask) { - return { - _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - _mm_or_si128(_mm_andnot_si128(sel.simdInternal_, a.simdInternal_), _mm_and_si128(sel.simdInternal_, b.simdInternal_)) - }; + return { _mm_or_si128(_mm_andnot_si128(sel.simdInternal_, a.simdInternal_), + _mm_and_si128(sel.simdInternal_, b.simdInternal_)) }; } #endif -static inline SimdDInt32 gmx_simdcall -cvtR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvtR2I(SimdDouble a) { - return { - _mm_cvtpd_epi32(a.simdInternal_) - }; + return { _mm_cvtpd_epi32(a.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -cvttR2I(SimdDouble a) +static inline SimdDInt32 gmx_simdcall cvttR2I(SimdDouble a) { - return { - _mm_cvttpd_epi32(a.simdInternal_) - }; + return { _mm_cvttpd_epi32(a.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -cvtI2R(SimdDInt32 a) +static inline SimdDouble gmx_simdcall cvtI2R(SimdDInt32 a) { - return { - _mm_cvtepi32_pd(a.simdInternal_) - }; + return { _mm_cvtepi32_pd(a.simdInternal_) }; } -static inline SimdDIBool gmx_simdcall -cvtB2IB(SimdDBool a) +static inline SimdDIBool gmx_simdcall cvtB2IB(SimdDBool a) { - return { - _mm_shuffle_epi32(_mm_castpd_si128(a.simdInternal_), _MM_SHUFFLE(2, 0, 2, 0)) - }; + return { _mm_shuffle_epi32(_mm_castpd_si128(a.simdInternal_), _MM_SHUFFLE(2, 0, 2, 0)) }; } -static inline SimdDBool gmx_simdcall -cvtIB2B(SimdDIBool a) +static inline SimdDBool gmx_simdcall cvtIB2B(SimdDIBool a) { - return { - _mm_castsi128_pd(_mm_shuffle_epi32(a.simdInternal_, _MM_SHUFFLE(1, 1, 0, 0))) - }; + return { _mm_castsi128_pd(_mm_shuffle_epi32(a.simdInternal_, _MM_SHUFFLE(1, 1, 0, 0))) }; } -static inline void gmx_simdcall -cvtF2DD(SimdFloat f, SimdDouble *d0, SimdDouble *d1) +static inline void gmx_simdcall cvtF2DD(SimdFloat f, SimdDouble* d0, SimdDouble* d1) { d0->simdInternal_ = _mm_cvtps_pd(f.simdInternal_); d1->simdInternal_ = _mm_cvtps_pd(_mm_movehl_ps(f.simdInternal_, f.simdInternal_)); } -static inline SimdFloat gmx_simdcall -cvtDD2F(SimdDouble d0, SimdDouble d1) +static inline SimdFloat gmx_simdcall cvtDD2F(SimdDouble d0, SimdDouble d1) { - return { - _mm_movelh_ps(_mm_cvtpd_ps(d0.simdInternal_), _mm_cvtpd_ps(d1.simdInternal_)) - }; + return { _mm_movelh_ps(_mm_cvtpd_ps(d0.simdInternal_), _mm_cvtpd_ps(d1.simdInternal_)) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_float.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_float.h index 4cfd589a29..37e78f88a0 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_float.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_simd_float.h @@ -50,371 +50,279 @@ namespace gmx class SimdFloat { - public: - SimdFloat() {} +public: + SimdFloat() {} - SimdFloat(float f) : simdInternal_(_mm_set1_ps(f)) {} + SimdFloat(float f) : simdInternal_(_mm_set1_ps(f)) {} - // Internal utility constructor to simplify return statements - SimdFloat(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFloat(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; class SimdFInt32 { - public: - SimdFInt32() {} +public: + SimdFInt32() {} - SimdFInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} + SimdFInt32(std::int32_t i) : simdInternal_(_mm_set1_epi32(i)) {} - // Internal utility constructor to simplify return statements - SimdFInt32(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFInt32(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; class SimdFBool { - public: - SimdFBool() {} +public: + SimdFBool() {} - SimdFBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32( b ? 0xFFFFFFFF : 0))) {} + SimdFBool(bool b) : simdInternal_(_mm_castsi128_ps(_mm_set1_epi32(b ? 0xFFFFFFFF : 0))) {} - // Internal utility constructor to simplify return statements - SimdFBool(__m128 simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFBool(__m128 simd) : simdInternal_(simd) {} - __m128 simdInternal_; + __m128 simdInternal_; }; class SimdFIBool { - public: - SimdFIBool() {} +public: + SimdFIBool() {} - SimdFIBool(bool b) : simdInternal_(_mm_set1_epi32( b ? 0xFFFFFFFF : 0)) {} + SimdFIBool(bool b) : simdInternal_(_mm_set1_epi32(b ? 0xFFFFFFFF : 0)) {} - // Internal utility constructor to simplify return statements - SimdFIBool(__m128i simd) : simdInternal_(simd) {} + // Internal utility constructor to simplify return statements + SimdFIBool(__m128i simd) : simdInternal_(simd) {} - __m128i simdInternal_; + __m128i simdInternal_; }; -static inline SimdFloat gmx_simdcall -simdLoad(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoad(const float* m, SimdFloatTag = {}) { assert(std::size_t(m) % 16 == 0); - return { - _mm_load_ps(m) - }; + return { _mm_load_ps(m) }; } -static inline void gmx_simdcall -store(float *m, SimdFloat a) +static inline void gmx_simdcall store(float* m, SimdFloat a) { assert(std::size_t(m) % 16 == 0); _mm_store_ps(m, a.simdInternal_); } -static inline SimdFloat gmx_simdcall -simdLoadU(const float *m, SimdFloatTag = {}) +static inline SimdFloat gmx_simdcall simdLoadU(const float* m, SimdFloatTag = {}) { - return { - _mm_loadu_ps(m) - }; + return { _mm_loadu_ps(m) }; } -static inline void gmx_simdcall -storeU(float *m, SimdFloat a) { _mm_storeu_ps(m, a.simdInternal_); } +static inline void gmx_simdcall storeU(float* m, SimdFloat a) +{ + _mm_storeu_ps(m, a.simdInternal_); +} -static inline SimdFloat gmx_simdcall -setZeroF() +static inline SimdFloat gmx_simdcall setZeroF() { - return { - _mm_setzero_ps() - }; + return { _mm_setzero_ps() }; } -static inline SimdFInt32 gmx_simdcall -simdLoad(const std::int32_t * m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoad(const std::int32_t* m, SimdFInt32Tag) { assert(std::size_t(m) % 16 == 0); - return { - _mm_load_si128(reinterpret_cast(m)) - }; + return { _mm_load_si128(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -store(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall store(std::int32_t* m, SimdFInt32 a) { assert(std::size_t(m) % 16 == 0); - _mm_store_si128(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_store_si128(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -simdLoadU(const std::int32_t *m, SimdFInt32Tag) +static inline SimdFInt32 gmx_simdcall simdLoadU(const std::int32_t* m, SimdFInt32Tag) { - return { - _mm_loadu_si128(reinterpret_cast(m)) - }; + return { _mm_loadu_si128(reinterpret_cast(m)) }; } -static inline void gmx_simdcall -storeU(std::int32_t * m, SimdFInt32 a) +static inline void gmx_simdcall storeU(std::int32_t* m, SimdFInt32 a) { - _mm_storeu_si128(reinterpret_cast<__m128i *>(m), a.simdInternal_); + _mm_storeu_si128(reinterpret_cast<__m128i*>(m), a.simdInternal_); } -static inline SimdFInt32 gmx_simdcall -setZeroFI() +static inline SimdFInt32 gmx_simdcall setZeroFI() { - return { - _mm_setzero_si128() - }; + return { _mm_setzero_si128() }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 a) { - return _mm_cvtsi128_si32( _mm_srli_si128(a.simdInternal_, 4 * index) ); + return _mm_cvtsi128_si32(_mm_srli_si128(a.simdInternal_, 4 * index)); } #endif -static inline SimdFloat gmx_simdcall -operator&(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator&(SimdFloat a, SimdFloat b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -andNot(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall andNot(SimdFloat a, SimdFloat b) { - return { - _mm_andnot_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator|(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator|(SimdFloat a, SimdFloat b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator^(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator^(SimdFloat a, SimdFloat b) { - return { - _mm_xor_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator+(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator+(SimdFloat a, SimdFloat b) { - return { - _mm_add_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator-(SimdFloat a, SimdFloat b) { - return { - _mm_sub_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -operator-(SimdFloat x) +static inline SimdFloat gmx_simdcall operator-(SimdFloat x) { - return { - _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) - }; + return { _mm_xor_ps(x.simdInternal_, _mm_set1_ps(GMX_FLOAT_NEGZERO)) }; } -static inline SimdFloat gmx_simdcall -operator*(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall operator*(SimdFloat a, SimdFloat b) { - return { - _mm_mul_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mul_ps(a.simdInternal_, b.simdInternal_) }; } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline SimdFloat gmx_simdcall -fma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) - }; + return { _mm_sub_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -fnma(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnma(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) - }; + return { _mm_sub_ps(c.simdInternal_, _mm_mul_ps(a.simdInternal_, b.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -fnms(SimdFloat a, SimdFloat b, SimdFloat c) +static inline SimdFloat gmx_simdcall fnms(SimdFloat a, SimdFloat b, SimdFloat c) { - return { - _mm_sub_ps(_mm_setzero_ps(), _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) - }; + return { _mm_sub_ps(_mm_setzero_ps(), + _mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_)) }; } #endif -static inline SimdFloat gmx_simdcall -rsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrt(SimdFloat x) { - return { - _mm_rsqrt_ps(x.simdInternal_) - }; + return { _mm_rsqrt_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -rcp(SimdFloat x) +static inline SimdFloat gmx_simdcall rcp(SimdFloat x) { - return { - _mm_rcp_ps(x.simdInternal_) - }; + return { _mm_rcp_ps(x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskAdd(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm_add_ps(a.simdInternal_, _mm_and_ps(b.simdInternal_, m.simdInternal_)) - }; + return { _mm_add_ps(a.simdInternal_, _mm_and_ps(b.simdInternal_, m.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzMul(SimdFloat a, SimdFloat b, SimdFBool m) { - return { - _mm_and_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), m.simdInternal_) - }; + return { _mm_and_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzFma(SimdFloat a, SimdFloat b, SimdFloat c, SimdFBool m) { - return { - _mm_and_ps(_mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_), m.simdInternal_) - }; + return { _mm_and_ps(_mm_add_ps(_mm_mul_ps(a.simdInternal_, b.simdInternal_), c.simdInternal_), + m.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdFloat gmx_simdcall -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRsqrt(SimdFloat x, SimdFBool m) { -#ifndef NDEBUG - x.simdInternal_ = _mm_or_ps(_mm_andnot_ps(m.simdInternal_, _mm_set1_ps(1.0F)), _mm_and_ps(m.simdInternal_, x.simdInternal_)); -#endif - return { - _mm_and_ps(_mm_rsqrt_ps(x.simdInternal_), m.simdInternal_) - }; +# ifndef NDEBUG + x.simdInternal_ = _mm_or_ps(_mm_andnot_ps(m.simdInternal_, _mm_set1_ps(1.0F)), + _mm_and_ps(m.simdInternal_, x.simdInternal_)); +# endif + return { _mm_and_ps(_mm_rsqrt_ps(x.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzRcp(SimdFloat x, SimdFBool m) { -#ifndef NDEBUG - x.simdInternal_ = _mm_or_ps(_mm_andnot_ps(m.simdInternal_, _mm_set1_ps(1.0F)), _mm_and_ps(m.simdInternal_, x.simdInternal_)); -#endif - return { - _mm_and_ps(_mm_rcp_ps(x.simdInternal_), m.simdInternal_) - }; +# ifndef NDEBUG + x.simdInternal_ = _mm_or_ps(_mm_andnot_ps(m.simdInternal_, _mm_set1_ps(1.0F)), + _mm_and_ps(m.simdInternal_, x.simdInternal_)); +# endif + return { _mm_and_ps(_mm_rcp_ps(x.simdInternal_), m.simdInternal_) }; } #endif -static inline SimdFloat gmx_simdcall -abs(SimdFloat x) +static inline SimdFloat gmx_simdcall abs(SimdFloat x) { - return { - _mm_andnot_ps( _mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_ ) - }; + return { _mm_andnot_ps(_mm_set1_ps(GMX_FLOAT_NEGZERO), x.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -max(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall max(SimdFloat a, SimdFloat b) { - return { - _mm_max_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_max_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -min(SimdFloat a, SimdFloat b) +static inline SimdFloat gmx_simdcall min(SimdFloat a, SimdFloat b) { - return { - _mm_min_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_min_ps(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - _mm_cvtepi32_ps( _mm_cvtps_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_ps(_mm_cvtps_epi32(x.simdInternal_)) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - _mm_cvtepi32_ps( _mm_cvttps_epi32(x.simdInternal_) ) - }; + return { _mm_cvtepi32_ps(_mm_cvttps_epi32(x.simdInternal_)) }; } #endif -static inline SimdFloat gmx_simdcall -frexp(SimdFloat value, SimdFInt32 * exponent) +static inline SimdFloat gmx_simdcall frexp(SimdFloat value, SimdFInt32* exponent) { - const __m128 exponentMask = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000)); - const __m128 mantissaMask = _mm_castsi128_ps(_mm_set1_epi32(0x807FFFFF)); - const __m128i exponentBias = _mm_set1_epi32(126); // add 1 to make our definition identical to frexp() - const __m128 half = _mm_set1_ps(0.5F); - __m128i iExponent; + const __m128 exponentMask = _mm_castsi128_ps(_mm_set1_epi32(0x7F800000)); + const __m128 mantissaMask = _mm_castsi128_ps(_mm_set1_epi32(0x807FFFFF)); + const __m128i exponentBias = _mm_set1_epi32(126); // add 1 to make our definition identical to frexp() + const __m128 half = _mm_set1_ps(0.5F); + __m128i iExponent; iExponent = _mm_castps_si128(_mm_and_ps(value.simdInternal_, exponentMask)); iExponent = _mm_sub_epi32(_mm_srli_epi32(iExponent, 23), exponentBias); exponent->simdInternal_ = iExponent; - return { - _mm_or_ps( _mm_and_ps(value.simdInternal_, mantissaMask), half) - }; + return { _mm_or_ps(_mm_and_ps(value.simdInternal_, mantissaMask), half) }; } // Override for SSE4.1 #if GMX_SIMD_X86_SSE2 -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { const __m128i exponentBias = _mm_set1_epi32(127); __m128i iExponent; @@ -427,168 +335,121 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = _mm_and_si128(iExponent, _mm_cmpgt_epi32(iExponent, _mm_setzero_si128())); } - iExponent = _mm_slli_epi32( iExponent, 23); + iExponent = _mm_slli_epi32(iExponent, 23); - return { - _mm_mul_ps(value.simdInternal_, _mm_castsi128_ps(iExponent)) - }; + return { _mm_mul_ps(value.simdInternal_, _mm_castsi128_ps(iExponent)) }; } #endif // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline float gmx_simdcall -reduce(SimdFloat a) +static inline float gmx_simdcall reduce(SimdFloat a) { // Shuffle has latency 1/throughput 1, followed by add with latency 3, t-put 1. // This is likely faster than using _mm_hadd_ps, which has latency 5, t-put 2. - a.simdInternal_ = _mm_add_ps(a.simdInternal_, _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - a.simdInternal_ = _mm_add_ss(a.simdInternal_, _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&a); + a.simdInternal_ = _mm_add_ps( + a.simdInternal_, _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); + a.simdInternal_ = _mm_add_ss( + a.simdInternal_, _mm_shuffle_ps(a.simdInternal_, a.simdInternal_, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&a); } #endif -static inline SimdFBool gmx_simdcall -operator==(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator==(SimdFloat a, SimdFloat b) { - return { - _mm_cmpeq_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator!=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator!=(SimdFloat a, SimdFloat b) { - return { - _mm_cmpneq_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpneq_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator<(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<(SimdFloat a, SimdFloat b) { - return { - _mm_cmplt_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator<=(SimdFloat a, SimdFloat b) +static inline SimdFBool gmx_simdcall operator<=(SimdFloat a, SimdFloat b) { - return { - _mm_cmple_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmple_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -testBits(SimdFloat a) +static inline SimdFBool gmx_simdcall testBits(SimdFloat a) { - __m128i ia = _mm_castps_si128(a.simdInternal_); - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi32(ia, _mm_setzero_si128()), _mm_cmpeq_epi32(ia, ia)); + __m128i ia = _mm_castps_si128(a.simdInternal_); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi32(ia, _mm_setzero_si128()), _mm_cmpeq_epi32(ia, ia)); - return { - _mm_castsi128_ps(res) - }; + return { _mm_castsi128_ps(res) }; } -static inline SimdFBool gmx_simdcall -operator&&(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator&&(SimdFBool a, SimdFBool b) { - return { - _mm_and_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -operator||(SimdFBool a, SimdFBool b) +static inline SimdFBool gmx_simdcall operator||(SimdFBool a, SimdFBool b) { - return { - _mm_or_ps(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_ps(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFBool a) { return _mm_movemask_ps(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdFBool a) +{ + return _mm_movemask_ps(a.simdInternal_) != 0; +} -static inline SimdFloat gmx_simdcall -selectByMask(SimdFloat a, SimdFBool mask) +static inline SimdFloat gmx_simdcall selectByMask(SimdFloat a, SimdFBool mask) { - return { - _mm_and_ps(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_ps(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -selectByNotMask(SimdFloat a, SimdFBool mask) +static inline SimdFloat gmx_simdcall selectByNotMask(SimdFloat a, SimdFBool mask) { - return { - _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_ps(mask.simdInternal_, a.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - _mm_or_ps(_mm_andnot_ps(sel.simdInternal_, a.simdInternal_), _mm_and_ps(sel.simdInternal_, b.simdInternal_)) - }; + return { _mm_or_ps(_mm_andnot_ps(sel.simdInternal_, a.simdInternal_), + _mm_and_ps(sel.simdInternal_, b.simdInternal_)) }; } #endif -static inline SimdFInt32 gmx_simdcall -operator&(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator&(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -andNot(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall andNot(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_andnot_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_andnot_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator|(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator|(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator^(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator^(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_xor_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_xor_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator+(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator+(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_add_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_add_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator-(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator-(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_sub_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_sub_epi32(a.simdInternal_, b.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { __m128i a1 = _mm_srli_si128(a.simdInternal_, 4); // - a[3] a[2] a[1] __m128i b1 = _mm_srli_si128(b.simdInternal_, 4); // - b[3] b[2] b[1] @@ -598,125 +459,87 @@ operator*(SimdFInt32 a, SimdFInt32 b) c = _mm_shuffle_epi32(c, _MM_SHUFFLE(3, 1, 2, 0)); // - - a[2]*b[2] a[0]*b[0] c1 = _mm_shuffle_epi32(c1, _MM_SHUFFLE(3, 1, 2, 0)); // - - a[3]*b[3] a[1]*b[1] - return { - _mm_unpacklo_epi32(c, c1) - }; + return { _mm_unpacklo_epi32(c, c1) }; } #endif -static inline SimdFIBool gmx_simdcall -operator==(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator==(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmpeq_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -testBits(SimdFInt32 a) +static inline SimdFIBool gmx_simdcall testBits(SimdFInt32 a) { __m128i x = a.simdInternal_; - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi32(x, _mm_setzero_si128()), _mm_cmpeq_epi32(x, x)); - return { - res - }; + return { res }; } -static inline SimdFIBool gmx_simdcall -operator<(SimdFInt32 a, SimdFInt32 b) +static inline SimdFIBool gmx_simdcall operator<(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_cmplt_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator&&(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator&&(SimdFIBool a, SimdFIBool b) { - return { - _mm_and_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -operator||(SimdFIBool a, SimdFIBool b) +static inline SimdFIBool gmx_simdcall operator||(SimdFIBool a, SimdFIBool b) { - return { - _mm_or_si128(a.simdInternal_, b.simdInternal_) - }; + return { _mm_or_si128(a.simdInternal_, b.simdInternal_) }; } -static inline bool gmx_simdcall -anyTrue(SimdFIBool a) { return _mm_movemask_epi8(a.simdInternal_) != 0; } +static inline bool gmx_simdcall anyTrue(SimdFIBool a) +{ + return _mm_movemask_epi8(a.simdInternal_) != 0; +} -static inline SimdFInt32 gmx_simdcall -selectByMask(SimdFInt32 a, SimdFIBool mask) +static inline SimdFInt32 gmx_simdcall selectByMask(SimdFInt32 a, SimdFIBool mask) { - return { - _mm_and_si128(a.simdInternal_, mask.simdInternal_) - }; + return { _mm_and_si128(a.simdInternal_, mask.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -selectByNotMask(SimdFInt32 a, SimdFIBool mask) +static inline SimdFInt32 gmx_simdcall selectByNotMask(SimdFInt32 a, SimdFIBool mask) { - return { - _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) - }; + return { _mm_andnot_si128(mask.simdInternal_, a.simdInternal_) }; } // Override for SSE4.1 and higher #if GMX_SIMD_X86_SSE2 -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - _mm_or_si128(_mm_andnot_si128(sel.simdInternal_, a.simdInternal_), _mm_and_si128(sel.simdInternal_, b.simdInternal_)) - }; + return { _mm_or_si128(_mm_andnot_si128(sel.simdInternal_, a.simdInternal_), + _mm_and_si128(sel.simdInternal_, b.simdInternal_)) }; } #endif -static inline SimdFInt32 gmx_simdcall -cvtR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvtR2I(SimdFloat a) { - return { - _mm_cvtps_epi32(a.simdInternal_) - }; + return { _mm_cvtps_epi32(a.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -cvttR2I(SimdFloat a) +static inline SimdFInt32 gmx_simdcall cvttR2I(SimdFloat a) { - return { - _mm_cvttps_epi32(a.simdInternal_) - }; + return { _mm_cvttps_epi32(a.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -cvtI2R(SimdFInt32 a) +static inline SimdFloat gmx_simdcall cvtI2R(SimdFInt32 a) { - return { - _mm_cvtepi32_ps(a.simdInternal_) - }; + return { _mm_cvtepi32_ps(a.simdInternal_) }; } -static inline SimdFIBool gmx_simdcall -cvtB2IB(SimdFBool a) +static inline SimdFIBool gmx_simdcall cvtB2IB(SimdFBool a) { - return { - _mm_castps_si128(a.simdInternal_) - }; + return { _mm_castps_si128(a.simdInternal_) }; } -static inline SimdFBool gmx_simdcall -cvtIB2B(SimdFIBool a) +static inline SimdFBool gmx_simdcall cvtIB2B(SimdFIBool a) { - return { - _mm_castsi128_ps(a.simdInternal_) - }; + return { _mm_castsi128_ps(a.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_SIMD_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_double.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_double.h index ba8c78d331..5183cb8fc6 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_double.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,14 +48,13 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { __m128d t1, t2, t3, t4; @@ -72,12 +71,9 @@ gatherLoadTranspose(const double * base, v3->simdInternal_ = _mm_unpackhi_pd(t3, t4); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1) + gatherLoadTranspose(const double* base, const std::int32_t offset[], SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2; @@ -92,13 +88,12 @@ gatherLoadTranspose(const double * base, static const int c_simdBestPairAlignmentDouble = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const double* base, + const std::int32_t offset[], + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2) { __m128d t1, t2, t3, t4; t1 = _mm_loadu_pd(base + align * offset[0]); @@ -110,105 +105,97 @@ gatherLoadUTranspose(const double * base, v2->simdInternal_ = _mm_unpacklo_pd(t3, t4); } -template -static inline void gmx_simdcall -transposeScatterStoreU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) +template +static inline void gmx_simdcall transposeScatterStoreU(double* base, + const std::int32_t offset[], + SimdDouble v0, + SimdDouble v1, + SimdDouble v2) { __m128d t1, t2; - t1 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); - t2 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); + t1 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); + t2 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); _mm_storeu_pd(base + align * offset[0], t1); _mm_store_sd(base + align * offset[0] + 2, v2.simdInternal_); _mm_storeu_pd(base + align * offset[1], t2); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[1] + 2), _mm_castpd_ps(v2.simdInternal_)); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1] + 2), _mm_castpd_ps(v2.simdInternal_)); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterIncrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { __m128d t1, t2, t3, t4, t5, t6, t7; - t5 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); - t6 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); - t7 = _mm_unpackhi_pd(v2.simdInternal_, v2.simdInternal_); + t5 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); + t6 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); + t7 = _mm_unpackhi_pd(v2.simdInternal_, v2.simdInternal_); - t1 = _mm_loadu_pd(base + align * offset[0]); - t2 = _mm_load_sd(base + align * offset[0] + 2); - t1 = _mm_add_pd(t1, t5); - t2 = _mm_add_sd(t2, v2.simdInternal_); + t1 = _mm_loadu_pd(base + align * offset[0]); + t2 = _mm_load_sd(base + align * offset[0] + 2); + t1 = _mm_add_pd(t1, t5); + t2 = _mm_add_sd(t2, v2.simdInternal_); _mm_storeu_pd(base + align * offset[0], t1); _mm_store_sd(base + align * offset[0] + 2, t2); - t3 = _mm_loadu_pd(base + align * offset[1]); - t4 = _mm_load_sd(base + align * offset[1] + 2); - t3 = _mm_add_pd(t3, t6); - t4 = _mm_add_sd(t4, t7); + t3 = _mm_loadu_pd(base + align * offset[1]); + t4 = _mm_load_sd(base + align * offset[1] + 2); + t3 = _mm_add_pd(t3, t6); + t4 = _mm_add_sd(t4, t7); _mm_storeu_pd(base + align * offset[1], t3); _mm_store_sd(base + align * offset[1] + 2, t4); } -template +template static inline void gmx_simdcall -transposeScatterDecrU(double * base, - const std::int32_t offset[], - SimdDouble v0, - SimdDouble v1, - SimdDouble v2) + transposeScatterDecrU(double* base, const std::int32_t offset[], SimdDouble v0, SimdDouble v1, SimdDouble v2) { // This implementation is identical to the increment version, apart from using subtraction instead __m128d t1, t2, t3, t4, t5, t6, t7; - t5 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); - t6 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); - t7 = _mm_unpackhi_pd(v2.simdInternal_, v2.simdInternal_); + t5 = _mm_unpacklo_pd(v0.simdInternal_, v1.simdInternal_); + t6 = _mm_unpackhi_pd(v0.simdInternal_, v1.simdInternal_); + t7 = _mm_unpackhi_pd(v2.simdInternal_, v2.simdInternal_); - t1 = _mm_loadu_pd(base + align * offset[0]); - t2 = _mm_load_sd(base + align * offset[0] + 2); - t1 = _mm_sub_pd(t1, t5); - t2 = _mm_sub_sd(t2, v2.simdInternal_); + t1 = _mm_loadu_pd(base + align * offset[0]); + t2 = _mm_load_sd(base + align * offset[0] + 2); + t1 = _mm_sub_pd(t1, t5); + t2 = _mm_sub_sd(t2, v2.simdInternal_); _mm_storeu_pd(base + align * offset[0], t1); _mm_store_sd(base + align * offset[0] + 2, t2); - t3 = _mm_loadu_pd(base + align * offset[1]); - t4 = _mm_load_sd(base + align * offset[1] + 2); - t3 = _mm_sub_pd(t3, t6); - t4 = _mm_sub_sd(t4, t7); + t3 = _mm_loadu_pd(base + align * offset[1]); + t4 = _mm_load_sd(base + align * offset[1] + 2); + t3 = _mm_sub_pd(t3, t6); + t4 = _mm_sub_sd(t4, t7); _mm_storeu_pd(base + align * offset[1], t3); _mm_store_sd(base + align * offset[1] + 2, t4); } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline void gmx_simdcall -expandScalarsToTriplets(SimdDouble scalar, - SimdDouble * triplets0, - SimdDouble * triplets1, - SimdDouble * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdDouble scalar, + SimdDouble* triplets0, + SimdDouble* triplets1, + SimdDouble* triplets2) { - triplets0->simdInternal_ = _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(0, 0)); - triplets1->simdInternal_ = _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(1, 0)); - triplets2->simdInternal_ = _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(1, 1)); + triplets0->simdInternal_ = + _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(0, 0)); + triplets1->simdInternal_ = + _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(1, 0)); + triplets2->simdInternal_ = + _mm_shuffle_pd(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE2(1, 1)); } #endif -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1, - SimdDouble * v2, - SimdDouble * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const double* base, + SimdDInt32 offset, + SimdDouble* v0, + SimdDouble* v1, + SimdDouble* v2, + SimdDouble* v3) { __m128d t1, t2, t3, t4; // Use optimized bit-shift multiply for the most common alignments @@ -223,7 +210,8 @@ gatherLoadBySimdIntTranspose(const double * base, else if (align == 12) { /* multiply by 3, then by 4 */ - offset.simdInternal_ = _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); + offset.simdInternal_ = + _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); offset.simdInternal_ = _mm_slli_epi32(offset.simdInternal_, 2); } else if (align == 16) @@ -236,20 +224,20 @@ gatherLoadBySimdIntTranspose(const double * base, assert(std::size_t(base + extract<0>(offset)) % 16 == 0); assert(std::size_t(base + extract<1>(offset)) % 16 == 0); - t1 = _mm_load_pd(base + extract<0>(offset)); - t2 = _mm_load_pd(base + extract<1>(offset)); - t3 = _mm_load_pd(base + extract<0>(offset) + 2); - t4 = _mm_load_pd(base + extract<1>(offset) + 2); + t1 = _mm_load_pd(base + extract<0>(offset)); + t2 = _mm_load_pd(base + extract<1>(offset)); + t3 = _mm_load_pd(base + extract<0>(offset) + 2); + t4 = _mm_load_pd(base + extract<1>(offset) + 2); } else { assert(std::size_t(base + align * extract<0>(offset)) % 16 == 0); assert(std::size_t(base + align * extract<1>(offset)) % 16 == 0); - t1 = _mm_load_pd(base + align * extract<0>(offset)); - t2 = _mm_load_pd(base + align * extract<1>(offset)); - t3 = _mm_load_pd(base + align * extract<0>(offset) + 2); - t4 = _mm_load_pd(base + align * extract<1>(offset) + 2); + t1 = _mm_load_pd(base + align * extract<0>(offset)); + t2 = _mm_load_pd(base + align * extract<1>(offset)); + t3 = _mm_load_pd(base + align * extract<0>(offset) + 2); + t4 = _mm_load_pd(base + align * extract<1>(offset) + 2); } v0->simdInternal_ = _mm_unpacklo_pd(t1, t2); v1->simdInternal_ = _mm_unpackhi_pd(t1, t2); @@ -257,12 +245,9 @@ gatherLoadBySimdIntTranspose(const double * base, v3->simdInternal_ = _mm_unpackhi_pd(t3, t4); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2; @@ -278,7 +263,8 @@ gatherLoadBySimdIntTranspose(const double * base, else if (align == 6) { // multiply by 3, then by 2 - offset.simdInternal_ = _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); + offset.simdInternal_ = + _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); offset.simdInternal_ = _mm_slli_epi32(offset.simdInternal_, 1); } else if (align == 8) @@ -288,7 +274,8 @@ gatherLoadBySimdIntTranspose(const double * base, else if (align == 12) { // multiply by 3, then by 4 - offset.simdInternal_ = _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); + offset.simdInternal_ = + _mm_add_epi32(offset.simdInternal_, _mm_slli_epi32(offset.simdInternal_, 1)); offset.simdInternal_ = _mm_slli_epi32(offset.simdInternal_, 2); } else if (align == 16) @@ -296,34 +283,30 @@ gatherLoadBySimdIntTranspose(const double * base, offset.simdInternal_ = _mm_slli_epi32(offset.simdInternal_, 4); } - if (align == 2 || align == 4 || align == 6 || - align == 8 || align == 12 || align == 16) + if (align == 2 || align == 4 || align == 6 || align == 8 || align == 12 || align == 16) { assert(std::size_t(base + extract<0>(offset)) % 16 == 0); assert(std::size_t(base + extract<1>(offset)) % 16 == 0); - t1 = _mm_load_pd(base + extract<0>(offset)); - t2 = _mm_load_pd(base + extract<1>(offset)); + t1 = _mm_load_pd(base + extract<0>(offset)); + t2 = _mm_load_pd(base + extract<1>(offset)); } else { assert(std::size_t(base + align * extract<0>(offset)) % 16 == 0); assert(std::size_t(base + align * extract<1>(offset)) % 16 == 0); - t1 = _mm_load_pd(base + align * extract<0>(offset)); - t2 = _mm_load_pd(base + align * extract<1>(offset)); + t1 = _mm_load_pd(base + align * extract<0>(offset)); + t2 = _mm_load_pd(base + align * extract<1>(offset)); } v0->simdInternal_ = _mm_unpacklo_pd(t1, t2); v1->simdInternal_ = _mm_unpackhi_pd(t1, t2); } -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const double * base, - SimdDInt32 offset, - SimdDouble * v0, - SimdDouble * v1) + gatherLoadUBySimdIntTranspose(const double* base, SimdDInt32 offset, SimdDouble* v0, SimdDouble* v1) { __m128d t1, t2; // Use optimized bit-shift multiply for the most common alignments. @@ -340,13 +323,13 @@ gatherLoadUBySimdIntTranspose(const double * base, if (align == 1 || align == 2 || align == 4) { - t1 = _mm_loadu_pd(base + extract<0>(offset)); - t2 = _mm_loadu_pd(base + extract<1>(offset)); + t1 = _mm_loadu_pd(base + extract<0>(offset)); + t2 = _mm_loadu_pd(base + extract<1>(offset)); } else { - t1 = _mm_loadu_pd(base + align * extract<0>(offset)); - t2 = _mm_loadu_pd(base + align * extract<1>(offset)); + t1 = _mm_loadu_pd(base + align * extract<0>(offset)); + t2 = _mm_loadu_pd(base + align * extract<1>(offset)); } v0->simdInternal_ = _mm_unpacklo_pd(t1, t2); v1->simdInternal_ = _mm_unpackhi_pd(t1, t2); @@ -355,11 +338,7 @@ gatherLoadUBySimdIntTranspose(const double * base, // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 static inline double gmx_simdcall -reduceIncr4ReturnSum(double * m, - SimdDouble v0, - SimdDouble v1, - SimdDouble v2, - SimdDouble v3) + reduceIncr4ReturnSum(double* m, SimdDouble v0, SimdDouble v1, SimdDouble v2, SimdDouble v3) { __m128d t1, t2, t3, t4; @@ -382,10 +361,10 @@ reduceIncr4ReturnSum(double * m, t1 = _mm_add_pd(t1, t3); t2 = _mm_add_sd(t1, _mm_shuffle_pd(t1, t1, _MM_SHUFFLE2(1, 1))); - return *reinterpret_cast(&t2); + return *reinterpret_cast(&t2); } #endif -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_UTIL_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_float.h b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_float.h index 53bcaffc8a..0c4de5265a 100644 --- a/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_float.h +++ b/src/gromacs/simd/impl_x86_sse2/impl_x86_sse2_util_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,164 +51,156 @@ namespace gmx { -template -static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { assert(std::size_t(base + align * offset[0]) % 16 == 0); assert(std::size_t(base + align * offset[1]) % 16 == 0); assert(std::size_t(base + align * offset[2]) % 16 == 0); assert(std::size_t(base + align * offset[3]) % 16 == 0); - v0->simdInternal_ = _mm_load_ps( base + align * offset[0] ); - v1->simdInternal_ = _mm_load_ps( base + align * offset[1] ); - v2->simdInternal_ = _mm_load_ps( base + align * offset[2] ); - v3->simdInternal_ = _mm_load_ps( base + align * offset[3] ); + v0->simdInternal_ = _mm_load_ps(base + align * offset[0]); + v1->simdInternal_ = _mm_load_ps(base + align * offset[1]); + v2->simdInternal_ = _mm_load_ps(base + align * offset[2]); + v3->simdInternal_ = _mm_load_ps(base + align * offset[3]); _MM_TRANSPOSE4_PS(v0->simdInternal_, v1->simdInternal_, v2->simdInternal_, v3->simdInternal_); } -template +template static inline void gmx_simdcall -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1) + gatherLoadTranspose(const float* base, const std::int32_t offset[], SimdFloat* v0, SimdFloat* v1) { __m128 t1, t2; - v0->simdInternal_ = _mm_castpd_ps(_mm_load_sd( reinterpret_cast( base + align * offset[0] ) )); - v1->simdInternal_ = _mm_castpd_ps(_mm_load_sd( reinterpret_cast( base + align * offset[1] ) )); - t1 = _mm_castpd_ps(_mm_load_sd( reinterpret_cast( base + align * offset[2] ) )); - t2 = _mm_castpd_ps(_mm_load_sd( reinterpret_cast( base + align * offset[3] ) )); - t1 = _mm_unpacklo_ps(v0->simdInternal_, t1); - t2 = _mm_unpacklo_ps(v1->simdInternal_, t2); + v0->simdInternal_ = + _mm_castpd_ps(_mm_load_sd(reinterpret_cast(base + align * offset[0]))); + v1->simdInternal_ = + _mm_castpd_ps(_mm_load_sd(reinterpret_cast(base + align * offset[1]))); + t1 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast(base + align * offset[2]))); + t2 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast(base + align * offset[3]))); + t1 = _mm_unpacklo_ps(v0->simdInternal_, t1); + t2 = _mm_unpacklo_ps(v1->simdInternal_, t2); v0->simdInternal_ = _mm_unpacklo_ps(t1, t2); v1->simdInternal_ = _mm_unpackhi_ps(t1, t2); } static const int c_simdBestPairAlignmentFloat = 2; -template -static inline void gmx_simdcall -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2) +template +static inline void gmx_simdcall gatherLoadUTranspose(const float* base, + const std::int32_t offset[], + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2) { __m128 t1, t2, t3, t4, t5, t6, t7, t8; if (align % 4 != 0) { // general case, not aligned to 4-byte boundary - t1 = _mm_loadu_ps( base + align * offset[0] ); - t2 = _mm_loadu_ps( base + align * offset[1] ); - t3 = _mm_loadu_ps( base + align * offset[2] ); - t4 = _mm_loadu_ps( base + align * offset[3] ); + t1 = _mm_loadu_ps(base + align * offset[0]); + t2 = _mm_loadu_ps(base + align * offset[1]); + t3 = _mm_loadu_ps(base + align * offset[2]); + t4 = _mm_loadu_ps(base + align * offset[3]); } else { // aligned to 4-byte boundary or more - t1 = _mm_load_ps( base + align * offset[0] ); - t2 = _mm_load_ps( base + align * offset[1] ); - t3 = _mm_load_ps( base + align * offset[2] ); - t4 = _mm_load_ps( base + align * offset[3] ); + t1 = _mm_load_ps(base + align * offset[0]); + t2 = _mm_load_ps(base + align * offset[1]); + t3 = _mm_load_ps(base + align * offset[2]); + t4 = _mm_load_ps(base + align * offset[3]); } - t5 = _mm_unpacklo_ps(t1, t2); - t6 = _mm_unpacklo_ps(t3, t4); - t7 = _mm_unpackhi_ps(t1, t2); - t8 = _mm_unpackhi_ps(t3, t4); - *v0 = _mm_movelh_ps(t5, t6); - *v1 = _mm_movehl_ps(t6, t5); - *v2 = _mm_movelh_ps(t7, t8); + t5 = _mm_unpacklo_ps(t1, t2); + t6 = _mm_unpacklo_ps(t3, t4); + t7 = _mm_unpackhi_ps(t1, t2); + t8 = _mm_unpackhi_ps(t3, t4); + *v0 = _mm_movelh_ps(t5, t6); + *v1 = _mm_movehl_ps(t6, t5); + *v2 = _mm_movelh_ps(t7, t8); } -template +template static inline void gmx_simdcall -transposeScatterStoreU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterStoreU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __m128 t1, t2; // general case, not aligned to 4-byte boundary - t1 = _mm_unpacklo_ps(v0.simdInternal_, v1.simdInternal_); - t2 = _mm_unpackhi_ps(v0.simdInternal_, v1.simdInternal_); - _mm_storel_pi( reinterpret_cast< __m64 *>( base + align * offset[0] ), t1); + t1 = _mm_unpacklo_ps(v0.simdInternal_, v1.simdInternal_); + t2 = _mm_unpackhi_ps(v0.simdInternal_, v1.simdInternal_); + _mm_storel_pi(reinterpret_cast<__m64*>(base + align * offset[0]), t1); _mm_store_ss(base + align * offset[0] + 2, v2.simdInternal_); - _mm_storeh_pi( reinterpret_cast< __m64 *>( base + align * offset[1] ), t1); - _mm_store_ss(base + align * offset[1] + 2, _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(1, 1, 1, 1))); - _mm_storel_pi( reinterpret_cast< __m64 *>( base + align * offset[2] ), t2); - _mm_store_ss(base + align * offset[2] + 2, _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(2, 2, 2, 2))); - _mm_storeh_pi( reinterpret_cast< __m64 *>( base + align * offset[3] ), t2); - _mm_store_ss(base + align * offset[3] + 2, _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1]), t1); + _mm_store_ss(base + align * offset[1] + 2, + _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_storel_pi(reinterpret_cast<__m64*>(base + align * offset[2]), t2); + _mm_store_ss(base + align * offset[2] + 2, + _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(2, 2, 2, 2))); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[3]), t2); + _mm_store_ss(base + align * offset[3] + 2, + _mm_shuffle_ps(v2.simdInternal_, v2.simdInternal_, _MM_SHUFFLE(3, 3, 3, 3))); } -template +template static inline void gmx_simdcall -transposeScatterIncrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterIncrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { __m128 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; if (align < 4) { - t5 = _mm_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); - t6 = _mm_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); - t7 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); - t8 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); - t9 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); - t10 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); - - t1 = _mm_load_ss(base + align * offset[0]); - t1 = _mm_loadh_pi(t1, reinterpret_cast< __m64 *>(base + align * offset[0] + 1)); - t1 = _mm_add_ps(t1, t7); + t5 = _mm_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); + t6 = _mm_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); + t7 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); + t8 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); + t9 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); + t10 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); + + t1 = _mm_load_ss(base + align * offset[0]); + t1 = _mm_loadh_pi(t1, reinterpret_cast<__m64*>(base + align * offset[0] + 1)); + t1 = _mm_add_ps(t1, t7); _mm_store_ss(base + align * offset[0], t1); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[0] + 1), t1); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[0] + 1), t1); - t2 = _mm_load_ss(base + align * offset[1]); - t2 = _mm_loadh_pi(t2, reinterpret_cast< __m64 *>(base + align * offset[1] + 1)); - t2 = _mm_add_ps(t2, t8); + t2 = _mm_load_ss(base + align * offset[1]); + t2 = _mm_loadh_pi(t2, reinterpret_cast<__m64*>(base + align * offset[1] + 1)); + t2 = _mm_add_ps(t2, t8); _mm_store_ss(base + align * offset[1], t2); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[1] + 1), t2); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1] + 1), t2); - t3 = _mm_load_ss(base + align * offset[2]); - t3 = _mm_loadh_pi(t3, reinterpret_cast< __m64 *>(base + align * offset[2] + 1)); - t3 = _mm_add_ps(t3, t9); + t3 = _mm_load_ss(base + align * offset[2]); + t3 = _mm_loadh_pi(t3, reinterpret_cast<__m64*>(base + align * offset[2] + 1)); + t3 = _mm_add_ps(t3, t9); _mm_store_ss(base + align * offset[2], t3); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[2] + 1), t3); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[2] + 1), t3); - t4 = _mm_load_ss(base + align * offset[3]); - t4 = _mm_loadh_pi(t4, reinterpret_cast< __m64 *>(base + align * offset[3] + 1)); - t4 = _mm_add_ps(t4, t10); + t4 = _mm_load_ss(base + align * offset[3]); + t4 = _mm_loadh_pi(t4, reinterpret_cast<__m64*>(base + align * offset[3] + 1)); + t4 = _mm_add_ps(t4, t10); _mm_store_ss(base + align * offset[3], t4); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[3] + 1), t4); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[3] + 1), t4); } else { // Extra elements means we can use full width-4 load/store operations - t1 = _mm_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); // x0 z0 x1 z1 - t2 = _mm_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); // x2 z2 x3 z3 - t3 = _mm_unpacklo_ps(v1.simdInternal_, _mm_setzero_ps()); // y0 0 y1 0 - t4 = _mm_unpackhi_ps(v1.simdInternal_, _mm_setzero_ps()); // y2 0 y3 0 - t5 = _mm_unpacklo_ps(t1, t3); // x0 y0 z0 0 - t6 = _mm_unpackhi_ps(t1, t3); // x1 y1 z1 0 - t7 = _mm_unpacklo_ps(t2, t4); // x2 y2 z2 0 - t8 = _mm_unpackhi_ps(t2, t4); // x3 y3 z3 0 + t1 = _mm_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); // x0 z0 x1 z1 + t2 = _mm_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); // x2 z2 x3 z3 + t3 = _mm_unpacklo_ps(v1.simdInternal_, _mm_setzero_ps()); // y0 0 y1 0 + t4 = _mm_unpackhi_ps(v1.simdInternal_, _mm_setzero_ps()); // y2 0 y3 0 + t5 = _mm_unpacklo_ps(t1, t3); // x0 y0 z0 0 + t6 = _mm_unpackhi_ps(t1, t3); // x1 y1 z1 0 + t7 = _mm_unpacklo_ps(t2, t4); // x2 y2 z2 0 + t8 = _mm_unpackhi_ps(t2, t4); // x3 y3 z3 0 if (align % 4 == 0) { @@ -221,70 +213,70 @@ transposeScatterIncrU(float * base, else { // alignment >=5, but not a multiple of 4 - _mm_storeu_ps(base + align * offset[0], _mm_add_ps(_mm_loadu_ps(base + align * offset[0]), t5)); - _mm_storeu_ps(base + align * offset[1], _mm_add_ps(_mm_loadu_ps(base + align * offset[1]), t6)); - _mm_storeu_ps(base + align * offset[2], _mm_add_ps(_mm_loadu_ps(base + align * offset[2]), t7)); - _mm_storeu_ps(base + align * offset[3], _mm_add_ps(_mm_loadu_ps(base + align * offset[3]), t8)); + _mm_storeu_ps(base + align * offset[0], + _mm_add_ps(_mm_loadu_ps(base + align * offset[0]), t5)); + _mm_storeu_ps(base + align * offset[1], + _mm_add_ps(_mm_loadu_ps(base + align * offset[1]), t6)); + _mm_storeu_ps(base + align * offset[2], + _mm_add_ps(_mm_loadu_ps(base + align * offset[2]), t7)); + _mm_storeu_ps(base + align * offset[3], + _mm_add_ps(_mm_loadu_ps(base + align * offset[3]), t8)); } } } -template +template static inline void gmx_simdcall -transposeScatterDecrU(float * base, - const std::int32_t offset[], - SimdFloat v0, - SimdFloat v1, - SimdFloat v2) + transposeScatterDecrU(float* base, const std::int32_t offset[], SimdFloat v0, SimdFloat v1, SimdFloat v2) { // This implementation is identical to the increment version, apart from using subtraction instead __m128 t1, t2, t3, t4, t5, t6, t7, t8, t9, t10; if (align < 4) { - t5 = _mm_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); - t6 = _mm_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); - t7 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); - t8 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); - t9 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); - t10 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); - - t1 = _mm_load_ss(base + align * offset[0]); - t1 = _mm_loadh_pi(t1, reinterpret_cast< __m64 *>(base + align * offset[0] + 1)); - t1 = _mm_sub_ps(t1, t7); + t5 = _mm_unpacklo_ps(v1.simdInternal_, v2.simdInternal_); + t6 = _mm_unpackhi_ps(v1.simdInternal_, v2.simdInternal_); + t7 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(1, 0, 0, 0)); + t8 = _mm_shuffle_ps(v0.simdInternal_, t5, _MM_SHUFFLE(3, 2, 0, 1)); + t9 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(1, 0, 0, 2)); + t10 = _mm_shuffle_ps(v0.simdInternal_, t6, _MM_SHUFFLE(3, 2, 0, 3)); + + t1 = _mm_load_ss(base + align * offset[0]); + t1 = _mm_loadh_pi(t1, reinterpret_cast<__m64*>(base + align * offset[0] + 1)); + t1 = _mm_sub_ps(t1, t7); _mm_store_ss(base + align * offset[0], t1); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[0] + 1), t1); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[0] + 1), t1); - t2 = _mm_load_ss(base + align * offset[1]); - t2 = _mm_loadh_pi(t2, reinterpret_cast< __m64 *>(base + align * offset[1] + 1)); - t2 = _mm_sub_ps(t2, t8); + t2 = _mm_load_ss(base + align * offset[1]); + t2 = _mm_loadh_pi(t2, reinterpret_cast<__m64*>(base + align * offset[1] + 1)); + t2 = _mm_sub_ps(t2, t8); _mm_store_ss(base + align * offset[1], t2); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[1] + 1), t2); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[1] + 1), t2); - t3 = _mm_load_ss(base + align * offset[2]); - t3 = _mm_loadh_pi(t3, reinterpret_cast< __m64 *>(base + align * offset[2] + 1)); - t3 = _mm_sub_ps(t3, t9); + t3 = _mm_load_ss(base + align * offset[2]); + t3 = _mm_loadh_pi(t3, reinterpret_cast<__m64*>(base + align * offset[2] + 1)); + t3 = _mm_sub_ps(t3, t9); _mm_store_ss(base + align * offset[2], t3); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[2] + 1), t3); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[2] + 1), t3); - t4 = _mm_load_ss(base + align * offset[3]); - t4 = _mm_loadh_pi(t4, reinterpret_cast< __m64 *>(base + align * offset[3] + 1)); - t4 = _mm_sub_ps(t4, t10); + t4 = _mm_load_ss(base + align * offset[3]); + t4 = _mm_loadh_pi(t4, reinterpret_cast<__m64*>(base + align * offset[3] + 1)); + t4 = _mm_sub_ps(t4, t10); _mm_store_ss(base + align * offset[3], t4); - _mm_storeh_pi(reinterpret_cast< __m64 *>(base + align * offset[3] + 1), t4); + _mm_storeh_pi(reinterpret_cast<__m64*>(base + align * offset[3] + 1), t4); } else { // Extra elements means we can use full width-4 load/store operations - t1 = _mm_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); // x0 z0 x1 z1 - t2 = _mm_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); // x2 z2 x3 z3 - t3 = _mm_unpacklo_ps(v1.simdInternal_, _mm_setzero_ps()); // y0 0 y1 0 - t4 = _mm_unpackhi_ps(v1.simdInternal_, _mm_setzero_ps()); // y2 0 y3 0 - t5 = _mm_unpacklo_ps(t1, t3); // x0 y0 z0 0 - t6 = _mm_unpackhi_ps(t1, t3); // x1 y1 z1 0 - t7 = _mm_unpacklo_ps(t2, t4); // x2 y2 z2 0 - t8 = _mm_unpackhi_ps(t2, t4); // x3 y3 z3 0 + t1 = _mm_unpacklo_ps(v0.simdInternal_, v2.simdInternal_); // x0 z0 x1 z1 + t2 = _mm_unpackhi_ps(v0.simdInternal_, v2.simdInternal_); // x2 z2 x3 z3 + t3 = _mm_unpacklo_ps(v1.simdInternal_, _mm_setzero_ps()); // y0 0 y1 0 + t4 = _mm_unpackhi_ps(v1.simdInternal_, _mm_setzero_ps()); // y2 0 y3 0 + t5 = _mm_unpacklo_ps(t1, t3); // x0 y0 z0 0 + t6 = _mm_unpackhi_ps(t1, t3); // x1 y1 z1 0 + t7 = _mm_unpacklo_ps(t2, t4); // x2 y2 z2 0 + t8 = _mm_unpackhi_ps(t2, t4); // x3 y3 z3 0 if (align % 4 == 0) { @@ -297,37 +289,42 @@ transposeScatterDecrU(float * base, else { // alignment >=5, but not a multiple of 4 - _mm_storeu_ps(base + align * offset[0], _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]), t5)); - _mm_storeu_ps(base + align * offset[1], _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]), t6)); - _mm_storeu_ps(base + align * offset[2], _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]), t7)); - _mm_storeu_ps(base + align * offset[3], _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]), t8)); + _mm_storeu_ps(base + align * offset[0], + _mm_sub_ps(_mm_loadu_ps(base + align * offset[0]), t5)); + _mm_storeu_ps(base + align * offset[1], + _mm_sub_ps(_mm_loadu_ps(base + align * offset[1]), t6)); + _mm_storeu_ps(base + align * offset[2], + _mm_sub_ps(_mm_loadu_ps(base + align * offset[2]), t7)); + _mm_storeu_ps(base + align * offset[3], + _mm_sub_ps(_mm_loadu_ps(base + align * offset[3]), t8)); } } } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline void gmx_simdcall -expandScalarsToTriplets(SimdFloat scalar, - SimdFloat * triplets0, - SimdFloat * triplets1, - SimdFloat * triplets2) +static inline void gmx_simdcall expandScalarsToTriplets(SimdFloat scalar, + SimdFloat* triplets0, + SimdFloat* triplets1, + SimdFloat* triplets2) { - triplets0->simdInternal_ = _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(1, 0, 0, 0)); - triplets1->simdInternal_ = _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(2, 2, 1, 1)); - triplets2->simdInternal_ = _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); + triplets0->simdInternal_ = + _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(1, 0, 0, 0)); + triplets1->simdInternal_ = + _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(2, 2, 1, 1)); + triplets2->simdInternal_ = + _mm_shuffle_ps(scalar.simdInternal_, scalar.simdInternal_, _MM_SHUFFLE(3, 3, 3, 2)); } #endif -template -static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1, - SimdFloat * v2, - SimdFloat * v3) +template +static inline void gmx_simdcall gatherLoadBySimdIntTranspose(const float* base, + SimdFInt32 offset, + SimdFloat* v0, + SimdFloat* v1, + SimdFloat* v2, + SimdFloat* v3) { // For present-generation x86 CPUs it appears to be faster to simply // store the SIMD integer to memory and then use the normal load operations. @@ -335,16 +332,13 @@ gatherLoadBySimdIntTranspose(const float * base, // the alignment scaling can often be done as part of the load instruction // (which is even cheaper than doing it in SIMD registers). alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_); + _mm_store_si128((__m128i*)ioffset, offset.simdInternal_); gatherLoadTranspose(base, ioffset, v0, v1, v2, v3); } -template +template static inline void gmx_simdcall -gatherLoadBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { // For present-generation x86 CPUs it appears to be faster to simply // store the SIMD integer to memory and then use the normal load operations. @@ -352,18 +346,14 @@ gatherLoadBySimdIntTranspose(const float * base, // the alignment scaling can often be done as part of the load instruction // (which is even cheaper than doing it in SIMD registers). alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_); + _mm_store_si128((__m128i*)ioffset, offset.simdInternal_); gatherLoadTranspose(base, ioffset, v0, v1); } - -template +template static inline void gmx_simdcall -gatherLoadUBySimdIntTranspose(const float * base, - SimdFInt32 offset, - SimdFloat * v0, - SimdFloat * v1) + gatherLoadUBySimdIntTranspose(const float* base, SimdFInt32 offset, SimdFloat* v0, SimdFloat* v1) { // For present-generation x86 CPUs it appears to be faster to simply // store the SIMD integer to memory and then use the normal load operations. @@ -371,18 +361,13 @@ gatherLoadUBySimdIntTranspose(const float * base, // the alignment scaling can often be done as part of the load instruction // (which is even cheaper than doing it in SIMD registers). alignas(GMX_SIMD_ALIGNMENT) std::int32_t ioffset[GMX_SIMD_FINT32_WIDTH]; - _mm_store_si128( (__m128i *)ioffset, offset.simdInternal_); + _mm_store_si128((__m128i*)ioffset, offset.simdInternal_); gatherLoadTranspose(base, ioffset, v0, v1); } // Override for AVX-128-FMA and higher #if GMX_SIMD_X86_SSE2 || GMX_SIMD_X86_SSE4_1 -static inline float gmx_simdcall -reduceIncr4ReturnSum(float * m, - SimdFloat v0, - SimdFloat v1, - SimdFloat v2, - SimdFloat v3) +static inline float gmx_simdcall reduceIncr4ReturnSum(float* m, SimdFloat v0, SimdFloat v1, SimdFloat v2, SimdFloat v3) { _MM_TRANSPOSE4_PS(v0.simdInternal_, v1.simdInternal_, v2.simdInternal_, v3.simdInternal_); v0.simdInternal_ = _mm_add_ps(v0.simdInternal_, v1.simdInternal_); @@ -393,12 +378,13 @@ reduceIncr4ReturnSum(float * m, assert(std::size_t(m) % 16 == 0); _mm_store_ps(m, v2.simdInternal_); - __m128 b = _mm_add_ps(v0.simdInternal_, _mm_shuffle_ps(v0.simdInternal_, v0.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); - b = _mm_add_ss(b, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 3, 2, 1))); - return *reinterpret_cast(&b); + __m128 b = _mm_add_ps(v0.simdInternal_, + _mm_shuffle_ps(v0.simdInternal_, v0.simdInternal_, _MM_SHUFFLE(1, 0, 3, 2))); + b = _mm_add_ss(b, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 3, 2, 1))); + return *reinterpret_cast(&b); } #endif -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE2_UTIL_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_definitions.h b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_definitions.h index 0d5d3f48b9..933754c3a5 100644 --- a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_definitions.h +++ b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_definitions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -37,47 +37,47 @@ #define GMX_SIMD_IMPL_X86_SSE4_1_DEFINITIONS_H // Capability definitions for SSE4.1 -#define GMX_SIMD 1 -#define GMX_SIMD_HAVE_FLOAT 1 -#define GMX_SIMD_HAVE_DOUBLE 1 -#define GMX_SIMD_HAVE_LOADU 1 -#define GMX_SIMD_HAVE_STOREU 1 -#define GMX_SIMD_HAVE_LOGICAL 1 -#define GMX_SIMD_HAVE_FMA 0 -#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 -#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 -#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 -#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 -#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 -#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 -#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 -#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 +#define GMX_SIMD 1 +#define GMX_SIMD_HAVE_FLOAT 1 +#define GMX_SIMD_HAVE_DOUBLE 1 +#define GMX_SIMD_HAVE_LOADU 1 +#define GMX_SIMD_HAVE_STOREU 1 +#define GMX_SIMD_HAVE_LOGICAL 1 +#define GMX_SIMD_HAVE_FMA 0 +#define GMX_SIMD_HAVE_FINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_FINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_FINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_DINT32_EXTRACT 1 +#define GMX_SIMD_HAVE_DINT32_LOGICAL 1 +#define GMX_SIMD_HAVE_DINT32_ARITHMETICS 1 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_FLOAT 0 +#define GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE 0 +#define GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE 0 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT 1 +#define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE 1 +#define GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT 0 // No need for half-simd, width is 4 +#define GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE 0 // No need for half-simd, width is 2 -#define GMX_SIMD4_HAVE_FLOAT 1 -#define GMX_SIMD4_HAVE_DOUBLE 0 +#define GMX_SIMD4_HAVE_FLOAT 1 +#define GMX_SIMD4_HAVE_DOUBLE 0 // Implementation details -#define GMX_SIMD_FLOAT_WIDTH 4 -#define GMX_SIMD_DOUBLE_WIDTH 2 -#define GMX_SIMD_FINT32_WIDTH 4 -#define GMX_SIMD_DINT32_WIDTH 2 -#define GMX_SIMD4_WIDTH 4 -#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) -#define GMX_SIMD_RSQRT_BITS 11 -#define GMX_SIMD_RCP_BITS 11 +#define GMX_SIMD_FLOAT_WIDTH 4 +#define GMX_SIMD_DOUBLE_WIDTH 2 +#define GMX_SIMD_FINT32_WIDTH 4 +#define GMX_SIMD_DINT32_WIDTH 2 +#define GMX_SIMD4_WIDTH 4 +#define GMX_SIMD_ALIGNMENT 16 // Bytes (4*single or 2*double) +#define GMX_SIMD_RSQRT_BITS 11 +#define GMX_SIMD_RCP_BITS 11 #endif // GMX_SIMD_IMPL_X86_SSE4_1_DEFINITIONS_H diff --git a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd4_float.h b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd4_float.h index 2b0b25870c..d214816a88 100644 --- a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd4_float.h +++ b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd4_float.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,37 +45,27 @@ namespace gmx { -static inline Simd4Float gmx_simdcall -round(Simd4Float x) +static inline Simd4Float gmx_simdcall round(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline Simd4Float gmx_simdcall -trunc(Simd4Float x) +static inline Simd4Float gmx_simdcall trunc(Simd4Float x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline float gmx_simdcall -dotProduct(Simd4Float a, Simd4Float b) +static inline float gmx_simdcall dotProduct(Simd4Float a, Simd4Float b) { __m128 res = _mm_dp_ps(a.simdInternal_, b.simdInternal_, 0x71); - return *reinterpret_cast(&res); + return *reinterpret_cast(&res); } -static inline Simd4Float gmx_simdcall -blend(Simd4Float a, Simd4Float b, Simd4FBool sel) +static inline Simd4Float gmx_simdcall blend(Simd4Float a, Simd4Float b, Simd4FBool sel) { - return { - _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE4_1_SIMD4_FLOAT_H diff --git a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_double.h b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_double.h index 0e4b5ea171..3adf63d134 100644 --- a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_double.h +++ b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_double.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,91 +46,65 @@ namespace gmx { template -static inline std::int32_t gmx_simdcall -extract(SimdDInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdDInt32 a) { return _mm_extract_epi32(a.simdInternal_, index); } -static inline SimdDouble -maskzRsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzRsqrt(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = _mm_blendv_pd(_mm_set1_pd(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - _mm_and_pd(_mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; + return { _mm_and_pd(_mm_cvtps_pd(_mm_rsqrt_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } -static inline SimdDouble -maskzRcp(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzRcp(SimdDouble x, SimdDBool m) { #ifndef NDEBUG x.simdInternal_ = _mm_blendv_pd(_mm_set1_pd(1.0), x.simdInternal_, m.simdInternal_); #endif - return { - _mm_and_pd(_mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) - }; + return { _mm_and_pd(_mm_cvtps_pd(_mm_rcp_ps(_mm_cvtpd_ps(x.simdInternal_))), m.simdInternal_) }; } -static inline SimdDouble gmx_simdcall -round(SimdDouble x) +static inline SimdDouble gmx_simdcall round(SimdDouble x) { - return { - _mm_round_pd(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm_round_pd(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline SimdDouble gmx_simdcall -trunc(SimdDouble x) +static inline SimdDouble gmx_simdcall trunc(SimdDouble x) { - return { - _mm_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm_round_pd(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline SimdDBool gmx_simdcall -testBits(SimdDouble a) +static inline SimdDBool gmx_simdcall testBits(SimdDouble a) { - __m128i ia = _mm_castpd_si128(a.simdInternal_); - __m128i res = _mm_andnot_si128( _mm_cmpeq_epi64(ia, _mm_setzero_si128()), _mm_cmpeq_epi64(ia, ia)); + __m128i ia = _mm_castpd_si128(a.simdInternal_); + __m128i res = _mm_andnot_si128(_mm_cmpeq_epi64(ia, _mm_setzero_si128()), _mm_cmpeq_epi64(ia, ia)); - return { - _mm_castsi128_pd(res) - }; + return { _mm_castsi128_pd(res) }; } -static inline SimdDouble gmx_simdcall -blend(SimdDouble a, SimdDouble b, SimdDBool sel) +static inline SimdDouble gmx_simdcall blend(SimdDouble a, SimdDouble b, SimdDBool sel) { - return { - _mm_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_pd(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -operator*(SimdDInt32 a, SimdDInt32 b) +static inline SimdDInt32 gmx_simdcall operator*(SimdDInt32 a, SimdDInt32 b) { - return { - _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdDInt32 gmx_simdcall -blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) +static inline SimdDInt32 gmx_simdcall blend(SimdDInt32 a, SimdDInt32 b, SimdDIBool sel) { - return { - _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -template -static inline SimdDouble -ldexp(SimdDouble value, SimdDInt32 exponent) +template +static inline SimdDouble ldexp(SimdDouble value, SimdDInt32 exponent) { - const __m128i exponentBias = _mm_set1_epi32(1023); - __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); + const __m128i exponentBias = _mm_set1_epi32(1023); + __m128i iExponent = _mm_add_epi32(exponent.simdInternal_, exponentBias); if (opt == MathOptimization::Safe) { @@ -143,11 +117,9 @@ ldexp(SimdDouble value, SimdDInt32 exponent) iExponent = _mm_shuffle_epi32(iExponent, _MM_SHUFFLE(3, 1, 2, 0)); iExponent = _mm_slli_epi64(iExponent, 52); - return { - _mm_mul_pd(value.simdInternal_, _mm_castsi128_pd(iExponent)) - }; + return { _mm_mul_pd(value.simdInternal_, _mm_castsi128_pd(iExponent)) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE4_1_SIMD_DOUBLE_H diff --git a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_float.h b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_float.h index b4a89c5fa3..6d42a44925 100644 --- a/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_float.h +++ b/src/gromacs/simd/impl_x86_sse4_1/impl_x86_sse4_1_simd_float.h @@ -46,77 +46,54 @@ namespace gmx { template -static inline std::int32_t gmx_simdcall -extract(SimdFInt32 a) +static inline std::int32_t gmx_simdcall extract(SimdFInt32 a) { return _mm_extract_epi32(a.simdInternal_, index); } -static inline SimdFloat -maskzRsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzRsqrt(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = _mm_blendv_ps(_mm_set1_ps(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - _mm_and_ps(_mm_rsqrt_ps(x.simdInternal_), m.simdInternal_) - }; + return { _mm_and_ps(_mm_rsqrt_ps(x.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat -maskzRcp(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzRcp(SimdFloat x, SimdFBool m) { #ifndef NDEBUG x.simdInternal_ = _mm_blendv_ps(_mm_set1_ps(1.0F), x.simdInternal_, m.simdInternal_); #endif - return { - _mm_and_ps(_mm_rcp_ps(x.simdInternal_), m.simdInternal_) - }; + return { _mm_and_ps(_mm_rcp_ps(x.simdInternal_), m.simdInternal_) }; } -static inline SimdFloat gmx_simdcall -round(SimdFloat x) +static inline SimdFloat gmx_simdcall round(SimdFloat x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_NINT) }; } -static inline SimdFloat gmx_simdcall -trunc(SimdFloat x) +static inline SimdFloat gmx_simdcall trunc(SimdFloat x) { - return { - _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) - }; + return { _mm_round_ps(x.simdInternal_, _MM_FROUND_TRUNC) }; } -static inline SimdFloat gmx_simdcall -blend(SimdFloat a, SimdFloat b, SimdFBool sel) +static inline SimdFloat gmx_simdcall blend(SimdFloat a, SimdFloat b, SimdFBool sel) { - return { - _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_ps(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -operator*(SimdFInt32 a, SimdFInt32 b) +static inline SimdFInt32 gmx_simdcall operator*(SimdFInt32 a, SimdFInt32 b) { - return { - _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) - }; + return { _mm_mullo_epi32(a.simdInternal_, b.simdInternal_) }; } -static inline SimdFInt32 gmx_simdcall -blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) +static inline SimdFInt32 gmx_simdcall blend(SimdFInt32 a, SimdFInt32 b, SimdFIBool sel) { - return { - _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) - }; + return { _mm_blendv_epi8(a.simdInternal_, b.simdInternal_, sel.simdInternal_) }; } -template -static inline SimdFloat gmx_simdcall -ldexp(SimdFloat value, SimdFInt32 exponent) +template +static inline SimdFloat gmx_simdcall ldexp(SimdFloat value, SimdFInt32 exponent) { const __m128i exponentBias = _mm_set1_epi32(127); __m128i iExponent; @@ -129,13 +106,11 @@ ldexp(SimdFloat value, SimdFInt32 exponent) iExponent = _mm_max_epi32(iExponent, _mm_setzero_si128()); } - iExponent = _mm_slli_epi32( iExponent, 23); + iExponent = _mm_slli_epi32(iExponent, 23); - return { - _mm_mul_ps(value.simdInternal_, _mm_castsi128_ps(iExponent)) - }; + return { _mm_mul_ps(value.simdInternal_, _mm_castsi128_ps(iExponent)) }; } -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_IMPL_X86_SSE4_1_SIMD_FLOAT_H diff --git a/src/gromacs/simd/scalar/scalar.h b/src/gromacs/simd/scalar/scalar.h index fb4213d91f..25f0471a43 100644 --- a/src/gromacs/simd/scalar/scalar.h +++ b/src/gromacs/simd/scalar/scalar.h @@ -75,8 +75,7 @@ namespace gmx * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -store(float *m, float a) +static inline void store(float* m, float a) { *m = a; } @@ -90,8 +89,7 @@ store(float *m, float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -storeU(float *m, float a) +static inline void storeU(float* m, float a) { *m = a; } @@ -110,12 +108,11 @@ storeU(float *m, float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -fma(float a, float b, float c) +static inline float fma(float a, float b, float c) { // Note that we purposely do not use the single-rounding std::fma // as that can be very slow without hardware support - return a*b + c; + return a * b + c; } /*! \brief Float Fused-multiply-subtract. Result is a*b - c. @@ -129,10 +126,9 @@ fma(float a, float b, float c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -fms(float a, float b, float c) +static inline float fms(float a, float b, float c) { - return a*b - c; + return a * b - c; } /*! \brief Float Fused-negated-multiply-add. Result is -a*b + c. @@ -146,10 +142,9 @@ fms(float a, float b, float c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -fnma(float a, float b, float c) +static inline float fnma(float a, float b, float c) { - return c - a*b; + return c - a * b; } /*! \brief Float Fused-negated-multiply-subtract. Result is -a*b - c. @@ -163,10 +158,9 @@ fnma(float a, float b, float c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -fnms(float a, float b, float c) +static inline float fnms(float a, float b, float c) { - return -a*b - c; + return -a * b - c; } /*! \brief Add two float variables, masked version. @@ -180,8 +174,7 @@ fnms(float a, float b, float c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -maskAdd(float a, float b, float m) +static inline float maskAdd(float a, float b, float m) { return a + (m != 0.0F ? b : 0.0F); } @@ -197,8 +190,7 @@ maskAdd(float a, float b, float m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -maskzMul(float a, float b, float m) +static inline float maskzMul(float a, float b, float m) { return m != 0.0F ? (a * b) : 0.0F; } @@ -215,8 +207,7 @@ maskzMul(float a, float b, float m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -maskzFma(float a, float b, float c, float m) +static inline float maskzFma(float a, float b, float c, float m) { return m != 0.0F ? (a * b + c) : 0.0F; } @@ -230,8 +221,7 @@ maskzFma(float a, float b, float c, float m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -abs(float a) +static inline float abs(float a) { return std::abs(a); } @@ -246,8 +236,7 @@ abs(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -max(float a, float b) +static inline float max(float a, float b) { return std::max(a, b); } @@ -262,8 +251,7 @@ max(float a, float b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -min(float a, float b) +static inline float min(float a, float b) { return std::min(a, b); } @@ -277,8 +265,7 @@ min(float a, float b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -round(float a) +static inline float round(float a) { return std::round(a); } @@ -292,8 +279,7 @@ round(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -trunc(float a) +static inline float trunc(float a) { return std::trunc(a); } @@ -307,8 +293,7 @@ trunc(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -reduce(float a) +static inline float reduce(float a) { return a; } @@ -323,11 +308,9 @@ reduce(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -andNot(float a, float b) +static inline float andNot(float a, float b) { - union - { + union { float r; std::uint32_t i; } conv1, conv2; @@ -353,11 +336,9 @@ andNot(float a, float b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -testBits(float a) +static inline bool testBits(float a) { - union - { + union { std::uint32_t i; float f; } conv; @@ -375,8 +356,7 @@ testBits(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -anyTrue(bool a) +static inline bool anyTrue(bool a) { return a; } @@ -391,8 +371,7 @@ anyTrue(bool a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -selectByMask(float a, bool mask) +static inline float selectByMask(float a, bool mask) { return mask ? a : 0.0F; } @@ -407,8 +386,7 @@ selectByMask(float a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -selectByNotMask(float a, bool mask) +static inline float selectByNotMask(float a, bool mask) { return mask ? 0.0F : a; } @@ -424,8 +402,7 @@ selectByNotMask(float a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -blend(float a, float b, bool sel) +static inline float blend(float a, float b, bool sel) { return sel ? b : a; } @@ -439,8 +416,7 @@ blend(float a, float b, bool sel) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -cvtR2I(float a) +static inline std::int32_t cvtR2I(float a) { return static_cast(std::round(a)); }; @@ -454,8 +430,7 @@ cvtR2I(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -cvttR2I(float a) +static inline std::int32_t cvttR2I(float a) { return static_cast(std::trunc(a)); }; @@ -473,8 +448,7 @@ cvttR2I(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -cvtI2R(std::int32_t a) +static inline std::int32_t cvtI2R(std::int32_t a) { return a; } @@ -492,8 +466,7 @@ cvtI2R(std::int32_t a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -store(double *m, double a) +static inline void store(double* m, double a) { *m = a; } @@ -507,8 +480,7 @@ store(double *m, double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -storeU(double *m, double a) +static inline void storeU(double* m, double a) { *m = a; } @@ -527,12 +499,11 @@ storeU(double *m, double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -fma(double a, double b, double c) +static inline double fma(double a, double b, double c) { // Note that we purposely do not use the single-rounding std::fma // as that can be very slow without hardware support - return a*b + c; + return a * b + c; } /*! \brief double Fused-multiply-subtract. Result is a*b - c. @@ -546,10 +517,9 @@ fma(double a, double b, double c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -fms(double a, double b, double c) +static inline double fms(double a, double b, double c) { - return a*b - c; + return a * b - c; } /*! \brief double Fused-negated-multiply-add. Result is - a*b + c. @@ -563,10 +533,9 @@ fms(double a, double b, double c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -fnma(double a, double b, double c) +static inline double fnma(double a, double b, double c) { - return c - a*b; + return c - a * b; } /*! \brief double Fused-negated-multiply-subtract. Result is -a*b - c. @@ -580,10 +549,9 @@ fnma(double a, double b, double c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -fnms(double a, double b, double c) +static inline double fnms(double a, double b, double c) { - return -a*b - c; + return -a * b - c; } /*! \brief Add two double variables, masked version. @@ -597,8 +565,7 @@ fnms(double a, double b, double c) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskAdd(double a, double b, double m) +static inline double maskAdd(double a, double b, double m) { return a + (m != 0.0 ? b : 0.0); } @@ -614,8 +581,7 @@ maskAdd(double a, double b, double m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzMul(double a, double b, double m) +static inline double maskzMul(double a, double b, double m) { return m != 0.0 ? (a * b) : 0.0; } @@ -632,8 +598,7 @@ maskzMul(double a, double b, double m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzFma(double a, double b, double c, double m) +static inline double maskzFma(double a, double b, double c, double m) { return m != 0.0 ? (a * b + c) : 0.0; } @@ -647,8 +612,7 @@ maskzFma(double a, double b, double c, double m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -abs(double a) +static inline double abs(double a) { return std::abs(a); } @@ -663,8 +627,7 @@ abs(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -max(double a, double b) +static inline double max(double a, double b) { return std::max(a, b); } @@ -679,8 +642,7 @@ max(double a, double b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -min(double a, double b) +static inline double min(double a, double b) { return std::min(a, b); } @@ -694,8 +656,7 @@ min(double a, double b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -round(double a) +static inline double round(double a) { return std::round(a); } @@ -709,8 +670,7 @@ round(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -trunc(double a) +static inline double trunc(double a) { return std::trunc(a); } @@ -724,8 +684,7 @@ trunc(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -reduce(double a) +static inline double reduce(double a) { return a; } @@ -740,11 +699,9 @@ reduce(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -andNot(double a, double b) +static inline double andNot(double a, double b) { - union - { + union { double r; std::uint64_t i; } conv1, conv2; @@ -770,13 +727,11 @@ andNot(double a, double b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -testBits(double a) +static inline bool testBits(double a) { - union - { - std::uint64_t i; - double f; + union { + std::uint64_t i; + double f; } conv; conv.f = a; @@ -793,8 +748,7 @@ testBits(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -selectByMask(double a, bool mask) +static inline double selectByMask(double a, bool mask) { return mask ? a : 0.0; } @@ -809,8 +763,7 @@ selectByMask(double a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -selectByNotMask(double a, bool mask) +static inline double selectByNotMask(double a, bool mask) { return mask ? 0.0 : a; } @@ -826,8 +779,7 @@ selectByNotMask(double a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -blend(double a, double b, bool sel) +static inline double blend(double a, double b, bool sel) { return sel ? b : a; } @@ -841,8 +793,7 @@ blend(double a, double b, bool sel) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -cvtR2I(double a) +static inline std::int32_t cvtR2I(double a) { return static_cast(std::round(a)); }; @@ -856,8 +807,7 @@ cvtR2I(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -cvttR2I(double a) +static inline std::int32_t cvttR2I(double a) { return static_cast(std::trunc(a)); }; @@ -876,8 +826,7 @@ cvttR2I(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -cvtF2D(float a) +static inline double cvtF2D(float a) { return a; } @@ -891,8 +840,7 @@ cvtF2D(float a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -cvtD2F(double a) +static inline float cvtD2F(double a) { return a; } @@ -910,8 +858,7 @@ cvtD2F(double a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -store(std::int32_t *m, std::int32_t a) +static inline void store(std::int32_t* m, std::int32_t a) { *m = a; } @@ -925,8 +872,7 @@ store(std::int32_t *m, std::int32_t a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -storeU(std::int32_t *m, std::int32_t a) +static inline void storeU(std::int32_t* m, std::int32_t a) { *m = a; } @@ -941,8 +887,7 @@ storeU(std::int32_t *m, std::int32_t a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -andNot(std::int32_t a, std::int32_t b) +static inline std::int32_t andNot(std::int32_t a, std::int32_t b) { return ~a & b; } @@ -959,8 +904,7 @@ andNot(std::int32_t a, std::int32_t b) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -testBits(std::int32_t a) +static inline bool testBits(std::int32_t a) { return (a != 0); } @@ -975,8 +919,7 @@ testBits(std::int32_t a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -selectByMask(std::int32_t a, bool mask) +static inline std::int32_t selectByMask(std::int32_t a, bool mask) { return mask ? a : 0; } @@ -991,8 +934,7 @@ selectByMask(std::int32_t a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -selectByNotMask(std::int32_t a, bool mask) +static inline std::int32_t selectByNotMask(std::int32_t a, bool mask) { return mask ? 0 : a; } @@ -1008,8 +950,7 @@ selectByNotMask(std::int32_t a, bool mask) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline std::int32_t -blend(std::int32_t a, std::int32_t b, bool sel) +static inline std::int32_t blend(std::int32_t a, std::int32_t b, bool sel) { return sel ? b : a; } @@ -1023,8 +964,7 @@ blend(std::int32_t a, std::int32_t b, bool sel) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -cvtB2IB(bool a) +static inline bool cvtB2IB(bool a) { return a; } @@ -1038,8 +978,7 @@ cvtB2IB(bool a) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline bool -cvtIB2B(bool a) +static inline bool cvtIB2B(bool a) { return a; } diff --git a/src/gromacs/simd/scalar/scalar_math.h b/src/gromacs/simd/scalar/scalar_math.h index b0834a0653..246e45b7f2 100644 --- a/src/gromacs/simd/scalar/scalar_math.h +++ b/src/gromacs/simd/scalar/scalar_math.h @@ -76,8 +76,7 @@ namespace gmx * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -copysign(float x, float y) +static inline float copysign(float x, float y) { return std::copysign(x, y); } @@ -95,9 +94,7 @@ copysign(float x, float y) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -invsqrtPair(float x0, float x1, - float *out0, float *out1) +static inline void invsqrtPair(float x0, float x1, float* out0, float* out1) { *out0 = invsqrt(x0); *out1 = invsqrt(x1); @@ -112,10 +109,9 @@ invsqrtPair(float x0, float x1, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -inv(float x) +static inline float inv(float x) { - return 1.0F/x; + return 1.0F / x; } /*! \brief Calculate 1/sqrt(x) for masked entry of float. @@ -133,8 +129,7 @@ inv(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -maskzInvsqrt(float x, bool m) +static inline float maskzInvsqrt(float x, bool m) { return m ? invsqrt(x) : 0.0F; } @@ -154,8 +149,7 @@ maskzInvsqrt(float x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -maskzInv(float x, bool m) +static inline float maskzInv(float x, bool m) { return m ? inv(x) : 0.0F; } @@ -169,9 +163,8 @@ maskzInv(float x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline float -sqrt(float x) +template +static inline float sqrt(float x) { return std::sqrt(x); } @@ -185,8 +178,7 @@ sqrt(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -log(float x) +static inline float log(float x) { return std::log(x); } @@ -200,9 +192,8 @@ log(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline float -exp2(float x) +template +static inline float exp2(float x) { return std::exp2(x); } @@ -216,9 +207,8 @@ exp2(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline float -exp(float x) +template +static inline float exp(float x) { return std::exp(x); } @@ -232,8 +222,7 @@ exp(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -erf(float x) +static inline float erf(float x) { return std::erf(x); } @@ -247,8 +236,7 @@ erf(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -erfc(float x) +static inline float erfc(float x) { return std::erfc(x); } @@ -264,8 +252,7 @@ erfc(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -sincos(float x, float *sinval, float *cosval) +static inline void sincos(float x, float* sinval, float* cosval) { *sinval = std::sin(x); *cosval = std::cos(x); @@ -280,8 +267,7 @@ sincos(float x, float *sinval, float *cosval) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -sin(float x) +static inline float sin(float x) { return std::sin(x); } @@ -295,8 +281,7 @@ sin(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -cos(float x) +static inline float cos(float x) { return std::cos(x); } @@ -310,8 +295,7 @@ cos(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -tan(float x) +static inline float tan(float x) { return std::tan(x); } @@ -325,8 +309,7 @@ tan(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -asin(float x) +static inline float asin(float x) { return std::asin(x); } @@ -340,8 +323,7 @@ asin(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -acos(float x) +static inline float acos(float x) { return std::acos(x); } @@ -355,8 +337,7 @@ acos(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -atan(float x) +static inline float atan(float x) { return std::atan(x); } @@ -371,8 +352,7 @@ atan(float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -atan2(float y, float x) +static inline float atan2(float y, float x) { return std::atan2(y, x); } @@ -388,39 +368,38 @@ atan2(float y, float x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -pmeForceCorrection(float z2) +static inline float pmeForceCorrection(float z2) { - const float FN6(-1.7357322914161492954e-8F); - const float FN5(1.4703624142580877519e-6F); - const float FN4(-0.000053401640219807709149F); - const float FN3(0.0010054721316683106153F); - const float FN2(-0.019278317264888380590F); - const float FN1(0.069670166153766424023F); - const float FN0(-0.75225204789749321333F); + const float FN6(-1.7357322914161492954e-8F); + const float FN5(1.4703624142580877519e-6F); + const float FN4(-0.000053401640219807709149F); + const float FN3(0.0010054721316683106153F); + const float FN2(-0.019278317264888380590F); + const float FN1(0.069670166153766424023F); + const float FN0(-0.75225204789749321333F); - const float FD4(0.0011193462567257629232F); - const float FD3(0.014866955030185295499F); - const float FD2(0.11583842382862377919F); - const float FD1(0.50736591960530292870F); - const float FD0(1.0F); + const float FD4(0.0011193462567257629232F); + const float FD3(0.014866955030185295499F); + const float FD2(0.11583842382862377919F); + const float FD1(0.50736591960530292870F); + const float FD0(1.0F); - float z4; - float polyFN0, polyFN1, polyFD0, polyFD1; + float z4; + float polyFN0, polyFN1, polyFD0, polyFD1; - z4 = z2 * z2; + z4 = z2 * z2; - polyFD0 = fma(FD4, z4, FD2); - polyFD1 = fma(FD3, z4, FD1); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = fma(polyFD1, z2, polyFD0); + polyFD0 = fma(FD4, z4, FD2); + polyFD1 = fma(FD3, z4, FD1); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = fma(polyFD1, z2, polyFD0); - polyFN0 = fma(FN6, z4, FN4); - polyFN1 = fma(FN5, z4, FN3); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN0 = fma(polyFN1, z2, polyFN0); + polyFN0 = fma(FN6, z4, FN4); + polyFN1 = fma(FN5, z4, FN3); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN0 = fma(polyFN1, z2, polyFN0); return polyFN0 / polyFD0; } @@ -436,37 +415,36 @@ pmeForceCorrection(float z2) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -pmePotentialCorrection(float z2) +static inline float pmePotentialCorrection(float z2) { - const float VN6(1.9296833005951166339e-8F); - const float VN5(-1.4213390571557850962e-6F); - const float VN4(0.000041603292906656984871F); - const float VN3(-0.00013134036773265025626F); - const float VN2(0.038657983986041781264F); - const float VN1(0.11285044772717598220F); - const float VN0(1.1283802385263030286F); + const float VN6(1.9296833005951166339e-8F); + const float VN5(-1.4213390571557850962e-6F); + const float VN4(0.000041603292906656984871F); + const float VN3(-0.00013134036773265025626F); + const float VN2(0.038657983986041781264F); + const float VN1(0.11285044772717598220F); + const float VN0(1.1283802385263030286F); - const float VD3(0.0066752224023576045451F); - const float VD2(0.078647795836373922256F); - const float VD1(0.43336185284710920150F); - const float VD0(1.0F); + const float VD3(0.0066752224023576045451F); + const float VD2(0.078647795836373922256F); + const float VD1(0.43336185284710920150F); + const float VD0(1.0F); - float z4; - float polyVN0, polyVN1, polyVD0, polyVD1; + float z4; + float polyVN0, polyVN1, polyVD0, polyVD1; - z4 = z2 * z2; + z4 = z2 * z2; - polyVD1 = fma(VD3, z4, VD1); - polyVD0 = fma(VD2, z4, VD0); - polyVD0 = fma(polyVD1, z2, polyVD0); + polyVD1 = fma(VD3, z4, VD1); + polyVD0 = fma(VD2, z4, VD0); + polyVD0 = fma(polyVD1, z2, polyVD0); - polyVN0 = fma(VN6, z4, VN4); - polyVN1 = fma(VN5, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2, polyVN0); + polyVN0 = fma(VN6, z4, VN4); + polyVN1 = fma(VN5, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2, polyVN0); return polyVN0 / polyVD0; } @@ -486,8 +464,7 @@ pmePotentialCorrection(float z2) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -copysign(double x, double y) +static inline double copysign(double x, double y) { return std::copysign(x, y); } @@ -505,9 +482,7 @@ copysign(double x, double y) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -invsqrtPair(double x0, double x1, - double *out0, double *out1) +static inline void invsqrtPair(double x0, double x1, double* out0, double* out1) { *out0 = invsqrt(x0); *out1 = invsqrt(x1); @@ -522,10 +497,9 @@ invsqrtPair(double x0, double x1, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -inv(double x) +static inline double inv(double x) { - return 1.0/x; + return 1.0 / x; } /*! \brief Calculate 1/sqrt(x) for masked entry of double. @@ -543,8 +517,7 @@ inv(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzInvsqrt(double x, bool m) +static inline double maskzInvsqrt(double x, bool m) { return m ? invsqrt(x) : 0.0; } @@ -564,8 +537,7 @@ maskzInvsqrt(double x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzInv(double x, bool m) +static inline double maskzInv(double x, bool m) { return m ? inv(x) : 0.0; } @@ -579,9 +551,8 @@ maskzInv(double x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline double -sqrt(double x) +template +static inline double sqrt(double x) { return std::sqrt(x); } @@ -595,8 +566,7 @@ sqrt(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -log(double x) +static inline double log(double x) { return std::log(x); } @@ -610,9 +580,8 @@ log(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline double -exp2(double x) +template +static inline double exp2(double x) { return std::exp2(x); } @@ -626,9 +595,8 @@ exp2(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline double -exp(double x) +template +static inline double exp(double x) { return std::exp(x); } @@ -642,8 +610,7 @@ exp(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -erf(double x) +static inline double erf(double x) { return std::erf(x); } @@ -657,8 +624,7 @@ erf(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -erfc(double x) +static inline double erfc(double x) { return std::erfc(x); } @@ -674,8 +640,7 @@ erfc(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -sincos(double x, double *sinval, double *cosval) +static inline void sincos(double x, double* sinval, double* cosval) { *sinval = std::sin(x); *cosval = std::cos(x); @@ -690,8 +655,7 @@ sincos(double x, double *sinval, double *cosval) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -sin(double x) +static inline double sin(double x) { return std::sin(x); } @@ -705,8 +669,7 @@ sin(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -cos(double x) +static inline double cos(double x) { return std::cos(x); } @@ -720,8 +683,7 @@ cos(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -tan(double x) +static inline double tan(double x) { return std::tan(x); } @@ -735,8 +697,7 @@ tan(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -asin(double x) +static inline double asin(double x) { return std::asin(x); } @@ -750,8 +711,7 @@ asin(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -acos(double x) +static inline double acos(double x) { return std::acos(x); } @@ -765,8 +725,7 @@ acos(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -atan(double x) +static inline double atan(double x) { return std::atan(x); } @@ -781,8 +740,7 @@ atan(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -atan2(double y, double x) +static inline double atan2(double y, double x) { return std::atan2(y, x); } @@ -798,52 +756,51 @@ atan2(double y, double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -pmeForceCorrection(double z2) -{ - const double FN10(-8.0072854618360083154e-14); - const double FN9(1.1859116242260148027e-11); - const double FN8(-8.1490406329798423616e-10); - const double FN7(3.4404793543907847655e-8); - const double FN6(-9.9471420832602741006e-7); - const double FN5(0.000020740315999115847456); - const double FN4(-0.00031991745139313364005); - const double FN3(0.0035074449373659008203); - const double FN2(-0.031750380176100813405); - const double FN1(0.13884101728898463426); - const double FN0(-0.75225277815249618847); - - const double FD5(0.000016009278224355026701); - const double FD4(0.00051055686934806966046); - const double FD3(0.0081803507497974289008); - const double FD2(0.077181146026670287235); - const double FD1(0.41543303143712535988); - const double FD0(1.0); - - double z4; - double polyFN0, polyFN1, polyFD0, polyFD1; - - z4 = z2 * z2; - - polyFD1 = fma(FD5, z4, FD3); - polyFD1 = fma(polyFD1, z4, FD1); - polyFD1 = polyFD1 * z2; - polyFD0 = fma(FD4, z4, FD2); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = polyFD0 + polyFD1; - - polyFD0 = inv(polyFD0); - - polyFN0 = fma(FN10, z4, FN8); - polyFN0 = fma(polyFN0, z4, FN6); - polyFN0 = fma(polyFN0, z4, FN4); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN1 = fma(FN9, z4, FN7); - polyFN1 = fma(polyFN1, z4, FN5); - polyFN1 = fma(polyFN1, z4, FN3); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN1, z2, polyFN0); +static inline double pmeForceCorrection(double z2) +{ + const double FN10(-8.0072854618360083154e-14); + const double FN9(1.1859116242260148027e-11); + const double FN8(-8.1490406329798423616e-10); + const double FN7(3.4404793543907847655e-8); + const double FN6(-9.9471420832602741006e-7); + const double FN5(0.000020740315999115847456); + const double FN4(-0.00031991745139313364005); + const double FN3(0.0035074449373659008203); + const double FN2(-0.031750380176100813405); + const double FN1(0.13884101728898463426); + const double FN0(-0.75225277815249618847); + + const double FD5(0.000016009278224355026701); + const double FD4(0.00051055686934806966046); + const double FD3(0.0081803507497974289008); + const double FD2(0.077181146026670287235); + const double FD1(0.41543303143712535988); + const double FD0(1.0); + + double z4; + double polyFN0, polyFN1, polyFD0, polyFD1; + + z4 = z2 * z2; + + polyFD1 = fma(FD5, z4, FD3); + polyFD1 = fma(polyFD1, z4, FD1); + polyFD1 = polyFD1 * z2; + polyFD0 = fma(FD4, z4, FD2); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = polyFD0 + polyFD1; + + polyFD0 = inv(polyFD0); + + polyFN0 = fma(FN10, z4, FN8); + polyFN0 = fma(polyFN0, z4, FN6); + polyFN0 = fma(polyFN0, z4, FN4); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN1 = fma(FN9, z4, FN7); + polyFN1 = fma(polyFN1, z4, FN5); + polyFN1 = fma(polyFN1, z4, FN3); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN1, z2, polyFN0); return polyFN0 * polyFD0; } @@ -859,49 +816,48 @@ pmeForceCorrection(double z2) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -pmePotentialCorrection(double z2) -{ - const double VN9(-9.3723776169321855475e-13); - const double VN8(1.2280156762674215741e-10); - const double VN7(-7.3562157912251309487e-9); - const double VN6(2.6215886208032517509e-7); - const double VN5(-4.9532491651265819499e-6); - const double VN4(0.00025907400778966060389); - const double VN3(0.0010585044856156469792); - const double VN2(0.045247661136833092885); - const double VN1(0.11643931522926034421); - const double VN0(1.1283791671726767970); - - const double VD5(0.000021784709867336150342); - const double VD4(0.00064293662010911388448); - const double VD3(0.0096311444822588683504); - const double VD2(0.085608012351550627051); - const double VD1(0.43652499166614811084); - const double VD0(1.0); - - double z4; - double polyVN0, polyVN1, polyVD0, polyVD1; - - z4 = z2 * z2; - - polyVD1 = fma(VD5, z4, VD3); - polyVD0 = fma(VD4, z4, VD2); - polyVD1 = fma(polyVD1, z4, VD1); - polyVD0 = fma(polyVD0, z4, VD0); - polyVD0 = fma(polyVD1, z2, polyVD0); - - polyVD0 = inv(polyVD0); - - polyVN1 = fma(VN9, z4, VN7); - polyVN0 = fma(VN8, z4, VN6); - polyVN1 = fma(polyVN1, z4, VN5); - polyVN0 = fma(polyVN0, z4, VN4); - polyVN1 = fma(polyVN1, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2, polyVN0); +static inline double pmePotentialCorrection(double z2) +{ + const double VN9(-9.3723776169321855475e-13); + const double VN8(1.2280156762674215741e-10); + const double VN7(-7.3562157912251309487e-9); + const double VN6(2.6215886208032517509e-7); + const double VN5(-4.9532491651265819499e-6); + const double VN4(0.00025907400778966060389); + const double VN3(0.0010585044856156469792); + const double VN2(0.045247661136833092885); + const double VN1(0.11643931522926034421); + const double VN0(1.1283791671726767970); + + const double VD5(0.000021784709867336150342); + const double VD4(0.00064293662010911388448); + const double VD3(0.0096311444822588683504); + const double VD2(0.085608012351550627051); + const double VD1(0.43652499166614811084); + const double VD0(1.0); + + double z4; + double polyVN0, polyVN1, polyVD0, polyVD1; + + z4 = z2 * z2; + + polyVD1 = fma(VD5, z4, VD3); + polyVD0 = fma(VD4, z4, VD2); + polyVD1 = fma(polyVD1, z4, VD1); + polyVD0 = fma(polyVD0, z4, VD0); + polyVD0 = fma(polyVD1, z2, polyVD0); + + polyVD0 = inv(polyVD0); + + polyVN1 = fma(VN9, z4, VN7); + polyVN0 = fma(VN8, z4, VN6); + polyVN1 = fma(polyVN1, z4, VN5); + polyVN0 = fma(polyVN0, z4, VN4); + polyVN1 = fma(polyVN1, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2, polyVN0); return polyVN0 * polyVD0; } @@ -922,8 +878,7 @@ pmePotentialCorrection(double z2) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -invsqrtSingleAccuracy(double x) +static inline double invsqrtSingleAccuracy(double x) { return invsqrt(static_cast(x)); } @@ -939,9 +894,7 @@ invsqrtSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -invsqrtPairSingleAccuracy(double x0, double x1, - double *out0, double *out1) +static inline void invsqrtPairSingleAccuracy(double x0, double x1, double* out0, double* out1) { *out0 = invsqrt(static_cast(x0)); *out1 = invsqrt(static_cast(x1)); @@ -956,10 +909,9 @@ invsqrtPairSingleAccuracy(double x0, double x1, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -invSingleAccuracy(double x) +static inline double invSingleAccuracy(double x) { - return 1.0F/x; + return 1.0F / x; } /*! \brief Calculate 1/sqrt(x) for masked entry of double, but with single accuracy. @@ -977,8 +929,7 @@ invSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzInvsqrtSingleAccuracy(double x, bool m) +static inline double maskzInvsqrtSingleAccuracy(double x, bool m) { return m ? invsqrtSingleAccuracy(x) : 0.0; } @@ -998,8 +949,7 @@ maskzInvsqrtSingleAccuracy(double x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -maskzInvSingleAccuracy(double x, bool m) +static inline double maskzInvSingleAccuracy(double x, bool m) { return m ? invSingleAccuracy(x) : 0.0; } @@ -1013,8 +963,7 @@ maskzInvSingleAccuracy(double x, bool m) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -sqrtSingleAccuracy(double x) +static inline double sqrtSingleAccuracy(double x) { return std::sqrt(static_cast(x)); } @@ -1028,8 +977,7 @@ sqrtSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -logSingleAccuracy(double x) +static inline double logSingleAccuracy(double x) { return std::log(static_cast(x)); } @@ -1043,8 +991,7 @@ logSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -exp2SingleAccuracy(double x) +static inline double exp2SingleAccuracy(double x) { return std::exp2(static_cast(x)); } @@ -1058,8 +1005,7 @@ exp2SingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -expSingleAccuracy(double x) +static inline double expSingleAccuracy(double x) { return std::exp(static_cast(x)); } @@ -1073,8 +1019,7 @@ expSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -erfSingleAccuracy(double x) +static inline double erfSingleAccuracy(double x) { return std::erf(static_cast(x)); } @@ -1088,8 +1033,7 @@ erfSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -erfcSingleAccuracy(double x) +static inline double erfcSingleAccuracy(double x) { return std::erfc(static_cast(x)); } @@ -1105,8 +1049,7 @@ erfcSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -sincosSingleAccuracy(double x, double *sinval, double *cosval) +static inline void sincosSingleAccuracy(double x, double* sinval, double* cosval) { // There is no single-precision sincos guaranteed in C++11, so use // separate functions and hope the compiler optimizes it for us. @@ -1123,8 +1066,7 @@ sincosSingleAccuracy(double x, double *sinval, double *cosval) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -sinSingleAccuracy(double x) +static inline double sinSingleAccuracy(double x) { return std::sin(static_cast(x)); } @@ -1138,8 +1080,7 @@ sinSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -cosSingleAccuracy(double x) +static inline double cosSingleAccuracy(double x) { return std::cos(static_cast(x)); } @@ -1153,8 +1094,7 @@ cosSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -tanSingleAccuracy(double x) +static inline double tanSingleAccuracy(double x) { return std::tan(static_cast(x)); } @@ -1168,8 +1108,7 @@ tanSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -asinSingleAccuracy(double x) +static inline double asinSingleAccuracy(double x) { return std::asin(static_cast(x)); } @@ -1183,8 +1122,7 @@ asinSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -acosSingleAccuracy(double x) +static inline double acosSingleAccuracy(double x) { return std::acos(static_cast(x)); } @@ -1198,8 +1136,7 @@ acosSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -atanSingleAccuracy(double x) +static inline double atanSingleAccuracy(double x) { return std::atan(static_cast(x)); } @@ -1214,8 +1151,7 @@ atanSingleAccuracy(double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -atan2SingleAccuracy(double y, double x) +static inline double atan2SingleAccuracy(double y, double x) { return std::atan2(static_cast(y), static_cast(x)); } @@ -1231,41 +1167,40 @@ atan2SingleAccuracy(double y, double x) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -pmeForceCorrectionSingleAccuracy(double z2) +static inline double pmeForceCorrectionSingleAccuracy(double z2) { - const float FN6(-1.7357322914161492954e-8F); - const float FN5(1.4703624142580877519e-6F); - const float FN4(-0.000053401640219807709149F); - const float FN3(0.0010054721316683106153F); - const float FN2(-0.019278317264888380590F); - const float FN1(0.069670166153766424023F); - const float FN0(-0.75225204789749321333F); + const float FN6(-1.7357322914161492954e-8F); + const float FN5(1.4703624142580877519e-6F); + const float FN4(-0.000053401640219807709149F); + const float FN3(0.0010054721316683106153F); + const float FN2(-0.019278317264888380590F); + const float FN1(0.069670166153766424023F); + const float FN0(-0.75225204789749321333F); - const float FD4(0.0011193462567257629232F); - const float FD3(0.014866955030185295499F); - const float FD2(0.11583842382862377919F); - const float FD1(0.50736591960530292870F); - const float FD0(1.0F); + const float FD4(0.0011193462567257629232F); + const float FD3(0.014866955030185295499F); + const float FD2(0.11583842382862377919F); + const float FD1(0.50736591960530292870F); + const float FD0(1.0F); - float z4; - float polyFN0, polyFN1, polyFD0, polyFD1; + float z4; + float polyFN0, polyFN1, polyFD0, polyFD1; - float z2f = z2; + float z2f = z2; - z4 = z2f * z2f; + z4 = z2f * z2f; - polyFD0 = fma(FD4, z4, FD2); - polyFD1 = fma(FD3, z4, FD1); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = fma(polyFD1, z2f, polyFD0); + polyFD0 = fma(FD4, z4, FD2); + polyFD1 = fma(FD3, z4, FD1); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = fma(polyFD1, z2f, polyFD0); - polyFN0 = fma(FN6, z4, FN4); - polyFN1 = fma(FN5, z4, FN3); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN0 = fma(polyFN1, z2f, polyFN0); + polyFN0 = fma(FN6, z4, FN4); + polyFN1 = fma(FN5, z4, FN3); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN0 = fma(polyFN1, z2f, polyFN0); return polyFN0 / polyFD0; } @@ -1281,45 +1216,43 @@ pmeForceCorrectionSingleAccuracy(double z2) * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -pmePotentialCorrectionSingleAccuracy(double z2) +static inline double pmePotentialCorrectionSingleAccuracy(double z2) { - const float VN6(1.9296833005951166339e-8F); - const float VN5(-1.4213390571557850962e-6F); - const float VN4(0.000041603292906656984871F); - const float VN3(-0.00013134036773265025626F); - const float VN2(0.038657983986041781264F); - const float VN1(0.11285044772717598220F); - const float VN0(1.1283802385263030286F); + const float VN6(1.9296833005951166339e-8F); + const float VN5(-1.4213390571557850962e-6F); + const float VN4(0.000041603292906656984871F); + const float VN3(-0.00013134036773265025626F); + const float VN2(0.038657983986041781264F); + const float VN1(0.11285044772717598220F); + const float VN0(1.1283802385263030286F); - const float VD3(0.0066752224023576045451F); - const float VD2(0.078647795836373922256F); - const float VD1(0.43336185284710920150F); - const float VD0(1.0F); + const float VD3(0.0066752224023576045451F); + const float VD2(0.078647795836373922256F); + const float VD1(0.43336185284710920150F); + const float VD0(1.0F); - float z4; - float polyVN0, polyVN1, polyVD0, polyVD1; + float z4; + float polyVN0, polyVN1, polyVD0, polyVD1; - float z2f = z2; + float z2f = z2; - z4 = z2f * z2f; + z4 = z2f * z2f; - polyVD1 = fma(VD3, z4, VD1); - polyVD0 = fma(VD2, z4, VD0); - polyVD0 = fma(polyVD1, z2f, polyVD0); + polyVD1 = fma(VD3, z4, VD1); + polyVD0 = fma(VD2, z4, VD0); + polyVD0 = fma(polyVD1, z2f, polyVD0); - polyVN0 = fma(VN6, z4, VN4); - polyVN1 = fma(VN5, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2f, polyVN0); + polyVN0 = fma(VN6, z4, VN4); + polyVN1 = fma(VN5, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2f, polyVN0); return polyVN0 / polyVD0; } - } // namespace gmx diff --git a/src/gromacs/simd/scalar/scalar_util.h b/src/gromacs/simd/scalar/scalar_util.h index 66550477f0..5002726307 100644 --- a/src/gromacs/simd/scalar/scalar_util.h +++ b/src/gromacs/simd/scalar/scalar_util.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,19 +73,14 @@ namespace gmx * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template +template static inline void -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - float * v0, - float * v1, - float * v2, - float * v3) +gatherLoadTranspose(const float* base, const std::int32_t offset[], float* v0, float* v1, float* v2, float* v3) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; - *v2 = base[align*offset[0]+2]; - *v3 = base[align*offset[0]+3]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; + *v2 = base[align * offset[0] + 2]; + *v3 = base[align * offset[0] + 3]; } /*! \brief Load 2 consecutive floats from base/offset into four variables @@ -100,15 +95,11 @@ gatherLoadTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadTranspose(const float * base, - const std::int32_t offset[], - float * v0, - float * v1) +template +static inline void gatherLoadTranspose(const float* base, const std::int32_t offset[], float* v0, float* v1) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; } @@ -126,17 +117,13 @@ gatherLoadTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template +template static inline void -gatherLoadUTranspose(const float * base, - const std::int32_t offset[], - float * v0, - float * v1, - float * v2) +gatherLoadUTranspose(const float* base, const std::int32_t offset[], float* v0, float* v1, float* v2) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; - *v2 = base[align*offset[0]+2]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; + *v2 = base[align * offset[0] + 2]; } /*! \brief Store 3 floats to 3 to base/offset. @@ -153,17 +140,12 @@ gatherLoadUTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterStoreU(float * base, - const std::int32_t offset[], - float v0, - float v1, - float v2) +template +static inline void transposeScatterStoreU(float* base, const std::int32_t offset[], float v0, float v1, float v2) { - base[align*offset[0]] = v0; - base[align*offset[0]+1] = v1; - base[align*offset[0]+2] = v2; + base[align * offset[0]] = v0; + base[align * offset[0] + 1] = v1; + base[align * offset[0] + 2] = v2; } /*! \brief Add 3 floats to base/offset. @@ -180,17 +162,12 @@ transposeScatterStoreU(float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterIncrU(float * base, - const std::int32_t offset[], - float v0, - float v1, - float v2) +template +static inline void transposeScatterIncrU(float* base, const std::int32_t offset[], float v0, float v1, float v2) { - base[align*offset[0]] += v0; - base[align*offset[0]+1] += v1; - base[align*offset[0]+2] += v2; + base[align * offset[0]] += v0; + base[align * offset[0] + 1] += v1; + base[align * offset[0] + 2] += v2; } /*! \brief Subtract 3 floats from base/offset. @@ -207,17 +184,12 @@ transposeScatterIncrU(float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterDecrU(float * base, - const std::int32_t offset[], - float v0, - float v1, - float v2) +template +static inline void transposeScatterDecrU(float* base, const std::int32_t offset[], float v0, float v1, float v2) { - base[align*offset[0]] -= v0; - base[align*offset[0]+1] -= v1; - base[align*offset[0]+2] -= v2; + base[align * offset[0]] -= v0; + base[align * offset[0] + 1] -= v1; + base[align * offset[0] + 2] -= v2; } /*! \brief Copy single float to three variables. @@ -231,11 +203,7 @@ transposeScatterDecrU(float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -expandScalarsToTriplets(float scalar, - float * triplets0, - float * triplets1, - float * triplets2) +static inline void expandScalarsToTriplets(float scalar, float* triplets0, float* triplets1, float* triplets2) { *triplets0 = scalar; *triplets1 = scalar; @@ -257,19 +225,14 @@ expandScalarsToTriplets(float scalar, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template +template static inline void -gatherLoadBySimdIntTranspose(const float * base, - std::int32_t offset, - float * v0, - float * v1, - float * v2, - float * v3) +gatherLoadBySimdIntTranspose(const float* base, std::int32_t offset, float* v0, float* v1, float* v2, float* v3) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; - *v2 = base[align*offset+2]; - *v3 = base[align*offset+3]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; + *v2 = base[align * offset + 2]; + *v3 = base[align * offset + 3]; } /*! \brief Load 2 floats from base/offsets and store into variables (unaligned). @@ -285,15 +248,11 @@ gatherLoadBySimdIntTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadUBySimdIntTranspose(const float * base, - std::int32_t offset, - float * v0, - float * v1) +template +static inline void gatherLoadUBySimdIntTranspose(const float* base, std::int32_t offset, float* v0, float* v1) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; } /*! \brief Load 2 floats from base/offsets and store into variables (aligned). @@ -309,15 +268,11 @@ gatherLoadUBySimdIntTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadBySimdIntTranspose(const float * base, - std::int32_t offset, - float * v0, - float * v1) +template +static inline void gatherLoadBySimdIntTranspose(const float* base, std::int32_t offset, float* v0, float* v1) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; } /*! \brief Add each float to four consecutive memory locations, return sum. @@ -334,12 +289,7 @@ gatherLoadBySimdIntTranspose(const float * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float -reduceIncr4ReturnSum(float * m, - float v0, - float v1, - float v2, - float v3) +static inline float reduceIncr4ReturnSum(float* m, float v0, float v1, float v2, float v3) { m[0] += v0; m[1] += v1; @@ -368,19 +318,18 @@ reduceIncr4ReturnSum(float * m, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - double * v0, - double * v1, - double * v2, - double * v3) +template +static inline void gatherLoadTranspose(const double* base, + const std::int32_t offset[], + double* v0, + double* v1, + double* v2, + double* v3) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; - *v2 = base[align*offset[0]+2]; - *v3 = base[align*offset[0]+3]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; + *v2 = base[align * offset[0] + 2]; + *v3 = base[align * offset[0] + 3]; } /*! \brief Load 2 consecutive doubles from base/offset into four variables @@ -395,15 +344,11 @@ gatherLoadTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadTranspose(const double * base, - const std::int32_t offset[], - double * v0, - double * v1) +template +static inline void gatherLoadTranspose(const double* base, const std::int32_t offset[], double* v0, double* v1) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; } @@ -421,17 +366,13 @@ gatherLoadTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template +template static inline void -gatherLoadUTranspose(const double * base, - const std::int32_t offset[], - double * v0, - double * v1, - double * v2) +gatherLoadUTranspose(const double* base, const std::int32_t offset[], double* v0, double* v1, double* v2) { - *v0 = base[align*offset[0]]; - *v1 = base[align*offset[0]+1]; - *v2 = base[align*offset[0]+2]; + *v0 = base[align * offset[0]]; + *v1 = base[align * offset[0] + 1]; + *v2 = base[align * offset[0] + 2]; } /*! \brief Store 3 doubles to 3 to base/offset. @@ -448,17 +389,12 @@ gatherLoadUTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterStoreU(double * base, - const std::int32_t offset[], - double v0, - double v1, - double v2) +template +static inline void transposeScatterStoreU(double* base, const std::int32_t offset[], double v0, double v1, double v2) { - base[align*offset[0]] = v0; - base[align*offset[0]+1] = v1; - base[align*offset[0]+2] = v2; + base[align * offset[0]] = v0; + base[align * offset[0] + 1] = v1; + base[align * offset[0] + 2] = v2; } /*! \brief Add 3 doubles to base/offset. @@ -475,17 +411,12 @@ transposeScatterStoreU(double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterIncrU(double * base, - const std::int32_t offset[], - double v0, - double v1, - double v2) +template +static inline void transposeScatterIncrU(double* base, const std::int32_t offset[], double v0, double v1, double v2) { - base[align*offset[0]] += v0; - base[align*offset[0]+1] += v1; - base[align*offset[0]+2] += v2; + base[align * offset[0]] += v0; + base[align * offset[0] + 1] += v1; + base[align * offset[0] + 2] += v2; } /*! \brief Subtract 3 doubles from base/offset. @@ -502,17 +433,12 @@ transposeScatterIncrU(double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -transposeScatterDecrU(double * base, - const std::int32_t offset[], - double v0, - double v1, - double v2) +template +static inline void transposeScatterDecrU(double* base, const std::int32_t offset[], double v0, double v1, double v2) { - base[align*offset[0]] -= v0; - base[align*offset[0]+1] -= v1; - base[align*offset[0]+2] -= v2; + base[align * offset[0]] -= v0; + base[align * offset[0] + 1] -= v1; + base[align * offset[0] + 2] -= v2; } /*! \brief Copy single double to three variables. @@ -526,11 +452,7 @@ transposeScatterDecrU(double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline void -expandScalarsToTriplets(double scalar, - double * triplets0, - double * triplets1, - double * triplets2) +static inline void expandScalarsToTriplets(double scalar, double* triplets0, double* triplets1, double* triplets2) { *triplets0 = scalar; *triplets1 = scalar; @@ -552,19 +474,18 @@ expandScalarsToTriplets(double scalar, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadBySimdIntTranspose(const double * base, - std::int32_t offset, - double * v0, - double * v1, - double * v2, - double * v3) +template +static inline void gatherLoadBySimdIntTranspose(const double* base, + std::int32_t offset, + double* v0, + double* v1, + double* v2, + double* v3) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; - *v2 = base[align*offset+2]; - *v3 = base[align*offset+3]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; + *v2 = base[align * offset + 2]; + *v3 = base[align * offset + 3]; } /*! \brief Load 2 doubles from base/offsets and store into variables (unaligned). @@ -580,15 +501,11 @@ gatherLoadBySimdIntTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadUBySimdIntTranspose(const double * base, - std::int32_t offset, - double * v0, - double * v1) +template +static inline void gatherLoadUBySimdIntTranspose(const double* base, std::int32_t offset, double* v0, double* v1) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; } /*! \brief Load 2 doubles from base/offsets and store into variables (aligned). @@ -604,15 +521,11 @@ gatherLoadUBySimdIntTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -template -static inline void -gatherLoadBySimdIntTranspose(const double * base, - std::int32_t offset, - double * v0, - double * v1) +template +static inline void gatherLoadBySimdIntTranspose(const double* base, std::int32_t offset, double* v0, double* v1) { - *v0 = base[align*offset]; - *v1 = base[align*offset+1]; + *v0 = base[align * offset]; + *v1 = base[align * offset + 1]; } /*! \brief Add each double to four consecutive memory locations, return sum. @@ -629,12 +542,7 @@ gatherLoadBySimdIntTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline double -reduceIncr4ReturnSum(double * m, - double v0, - double v1, - double v2, - double v3) +static inline double reduceIncr4ReturnSum(double* m, double v0, double v1, double v2, double v3) { m[0] += v0; m[1] += v1; diff --git a/src/gromacs/simd/simd.h b/src/gromacs/simd/simd.h index c7c52197ca..fc51f4099d 100644 --- a/src/gromacs/simd/simd.h +++ b/src/gromacs/simd/simd.h @@ -91,14 +91,22 @@ namespace gmx { /*! \libinternal \brief Tag type to select to load SimdFloat with simdLoad(U) */ -struct SimdFloatTag {}; +struct SimdFloatTag +{ +}; /*! \libinternal \brief Tag type to select to load SimdDouble with simdLoad(U) */ -struct SimdDoubleTag {}; +struct SimdDoubleTag +{ +}; /*! \libinternal \brief Tag type to select to load SimdFInt32 with simdLoad(U) */ -struct SimdFInt32Tag {}; +struct SimdFInt32Tag +{ +}; /*! \libinternal \brief Tag type to select to load SimdDInt32 with simdLoad(U) */ -struct SimdDInt32Tag {}; -} // namespace gmx +struct SimdDInt32Tag +{ +}; +} // namespace gmx /*! \name SIMD predefined macros to describe high-level capabilities * @@ -110,14 +118,14 @@ struct SimdDInt32Tag {}; */ #ifdef __clang__ -#pragma clang diagnostic push +# pragma clang diagnostic push /* reinterpret_cast is used for SIMD->scalar conversion * * In general using reinterpret_cast for bit_cast is UB but * for intrinsics types it works for all known compilers * and not all compilers produce as good code for memcpy. */ -#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" +# pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" #endif #if GMX_SIMD_X86_SSE2 @@ -153,7 +161,7 @@ struct SimdDInt32Tag {}; #endif #ifdef __clang__ -#pragma clang diagnostic pop +# pragma clang diagnostic pop #endif // The scalar SIMD-mimicking functions are always included so we can use @@ -164,68 +172,70 @@ struct SimdDInt32Tag {}; #if GMX_DOUBLE -# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_DOUBLE -# define GMX_SIMD_REAL_WIDTH GMX_SIMD_DOUBLE_WIDTH -# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_DINT32_EXTRACT -# define GMX_SIMD_HAVE_INT32_LOGICAL GMX_SIMD_HAVE_DINT32_LOGICAL -# define GMX_SIMD_HAVE_INT32_ARITHMETICS GMX_SIMD_HAVE_DINT32_ARITHMETICS -# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE -# define GMX_SIMD_HAVE_HSIMD_UTIL_REAL GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE -# define GMX_SIMD4_HAVE_REAL GMX_SIMD4_HAVE_DOUBLE +# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_DOUBLE +# define GMX_SIMD_REAL_WIDTH GMX_SIMD_DOUBLE_WIDTH +# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_DINT32_EXTRACT +# define GMX_SIMD_HAVE_INT32_LOGICAL GMX_SIMD_HAVE_DINT32_LOGICAL +# define GMX_SIMD_HAVE_INT32_ARITHMETICS GMX_SIMD_HAVE_DINT32_ARITHMETICS +# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL \ + GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE +# define GMX_SIMD_HAVE_HSIMD_UTIL_REAL GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE +# define GMX_SIMD4_HAVE_REAL GMX_SIMD4_HAVE_DOUBLE #else // GMX_DOUBLE /*! \brief 1 if SimdReal is available, otherwise 0. * * \ref GMX_SIMD_HAVE_DOUBLE if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD_HAVE_FLOAT. */ -# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_FLOAT +# define GMX_SIMD_HAVE_REAL GMX_SIMD_HAVE_FLOAT /*! \brief Width of SimdReal. * * \ref GMX_SIMD_DOUBLE_WIDTH if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD_FLOAT_WIDTH. */ -# define GMX_SIMD_REAL_WIDTH GMX_SIMD_FLOAT_WIDTH +# define GMX_SIMD_REAL_WIDTH GMX_SIMD_FLOAT_WIDTH /*! \brief 1 if support is available for extracting elements from SimdInt32, otherwise 0 * * \ref GMX_SIMD_HAVE_DINT32_EXTRACT if GMX_DOUBLE is 1, otherwise * \ref GMX_SIMD_HAVE_FINT32_EXTRACT. */ -# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_FINT32_EXTRACT +# define GMX_SIMD_HAVE_INT32_EXTRACT GMX_SIMD_HAVE_FINT32_EXTRACT /*! \brief 1 if logical ops are supported on SimdInt32, otherwise 0. * * \ref GMX_SIMD_HAVE_DINT32_LOGICAL if GMX_DOUBLE is 1, otherwise * \ref GMX_SIMD_HAVE_FINT32_LOGICAL. */ -# define GMX_SIMD_HAVE_INT32_LOGICAL GMX_SIMD_HAVE_FINT32_LOGICAL +# define GMX_SIMD_HAVE_INT32_LOGICAL GMX_SIMD_HAVE_FINT32_LOGICAL /*! \brief 1 if arithmetic ops are supported on SimdInt32, otherwise 0. * * \ref GMX_SIMD_HAVE_DINT32_ARITHMETICS if GMX_DOUBLE is 1, otherwise * \ref GMX_SIMD_HAVE_FINT32_ARITHMETICS. */ -# define GMX_SIMD_HAVE_INT32_ARITHMETICS GMX_SIMD_HAVE_FINT32_ARITHMETICS +# define GMX_SIMD_HAVE_INT32_ARITHMETICS GMX_SIMD_HAVE_FINT32_ARITHMETICS /*! \brief 1 if gmx::simdGatherLoadUBySimdIntTranspose is present, otherwise 0 * * \ref GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_DOUBLE if GMX_DOUBLE is 1, otherwise * \ref GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT. */ -# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT +# define GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL \ + GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_FLOAT /*! \brief 1 if real half-register load/store/reduce utils present, otherwise 0 * * \ref GMX_SIMD_HAVE_HSIMD_UTIL_DOUBLE if GMX_DOUBLE is 1, otherwise * \ref GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT. */ -# define GMX_SIMD_HAVE_HSIMD_UTIL_REAL GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT +# define GMX_SIMD_HAVE_HSIMD_UTIL_REAL GMX_SIMD_HAVE_HSIMD_UTIL_FLOAT /*! \brief 1 if Simd4Real is available, otherwise 0. * * \ref GMX_SIMD4_HAVE_DOUBLE if GMX_DOUBLE is 1, otherwise \ref GMX_SIMD4_HAVE_FLOAT. */ -# define GMX_SIMD4_HAVE_REAL GMX_SIMD4_HAVE_FLOAT +# define GMX_SIMD4_HAVE_REAL GMX_SIMD4_HAVE_FLOAT #endif // GMX_DOUBLE @@ -242,7 +252,8 @@ struct AlignedArray; * Should not be deleted through base pointer (destructor is non-virtual). */ template -struct alignas(GMX_SIMD_FLOAT_WIDTH*sizeof(float))AlignedArray : public std::array +struct alignas(GMX_SIMD_FLOAT_WIDTH * sizeof(float)) AlignedArray : + public std::array { }; #endif @@ -252,7 +263,8 @@ struct alignas(GMX_SIMD_FLOAT_WIDTH*sizeof(float))AlignedArray : publi * Should not be deleted through base pointer (destructor is non-virtual). */ template -struct alignas(GMX_SIMD_DOUBLE_WIDTH*sizeof(double))AlignedArray : public std::array +struct alignas(GMX_SIMD_DOUBLE_WIDTH * sizeof(double)) AlignedArray : + public std::array { }; #endif @@ -279,9 +291,9 @@ struct alignas(GMX_SIMD_DOUBLE_WIDTH*sizeof(double))AlignedArray : pu * memory on the heap, but it occurs for stack structures too. */ # if GMX_DOUBLE -typedef SimdDouble SimdReal; +typedef SimdDouble SimdReal; # else -typedef SimdFloat SimdReal; +typedef SimdFloat SimdReal; # endif @@ -303,9 +315,9 @@ typedef SimdFloat SimdReal; * memory on the heap, but it occurs for stack structures too. */ # if GMX_DOUBLE -typedef SimdDBool SimdBool; +typedef SimdDBool SimdBool; # else -typedef SimdFBool SimdBool; +typedef SimdFBool SimdBool; # endif @@ -324,12 +336,12 @@ typedef SimdFBool SimdBool; * memory on the heap, but it occurs for stack structures too. */ # if GMX_DOUBLE -typedef SimdDInt32 SimdInt32; +typedef SimdDInt32 SimdInt32; # else -typedef SimdFInt32 SimdInt32; +typedef SimdFInt32 SimdInt32; # endif -#if GMX_SIMD_HAVE_INT32_ARITHMETICS +# if GMX_SIMD_HAVE_INT32_ARITHMETICS /*! \brief Boolean SIMD type for usage with \ref SimdInt32. * * This type is only available if \ref GMX_SIMD_HAVE_INT32_ARITHMETICS is 1. @@ -353,21 +365,21 @@ typedef SimdFInt32 SimdInt32; * alignment. This is likely particularly severe when allocating such * memory on the heap, but it occurs for stack structures too. */ -# if GMX_DOUBLE -typedef SimdDIBool SimdIBool; -# else -typedef SimdFIBool SimdIBool; -# endif -#endif // GMX_SIMD_HAVE_INT32_ARITHMETICS +# if GMX_DOUBLE +typedef SimdDIBool SimdIBool; +# else +typedef SimdFIBool SimdIBool; +# endif +# endif // GMX_SIMD_HAVE_INT32_ARITHMETICS -#if GMX_DOUBLE +# if GMX_DOUBLE const int c_simdBestPairAlignment = c_simdBestPairAlignmentDouble; -#else -const int c_simdBestPairAlignment = c_simdBestPairAlignmentFloat; -#endif +# else +const int c_simdBestPairAlignment = c_simdBestPairAlignmentFloat; +# endif -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL #if GMX_SIMD4_HAVE_REAL /*! \brief Real precision floating-point SIMD4 datatype. @@ -382,9 +394,9 @@ const int c_simdBestPairAlignment = c_simdBestPairAlignmentFloat; * memory on the heap, but it occurs for stack structures too. */ # if GMX_DOUBLE -typedef Simd4Double Simd4Real; +typedef Simd4Double Simd4Real; # else -typedef Simd4Float Simd4Real; +typedef Simd4Float Simd4Real; # endif @@ -404,9 +416,9 @@ typedef Simd4Float Simd4Real; * memory on the heap, but it occurs for stack structures too. */ # if GMX_DOUBLE -typedef Simd4DBool Simd4Bool; +typedef Simd4DBool Simd4Bool; # else -typedef Simd4FBool Simd4Bool; +typedef Simd4FBool Simd4Bool; # endif #endif // GMX_SIMD4_HAVE_REAL @@ -428,53 +440,55 @@ namespace internal * - tag: tag used for type dispatch of load function */ template -struct SimdTraits {}; +struct SimdTraits +{ +}; #if GMX_SIMD_HAVE_FLOAT template<> struct SimdTraits { - using type = float; + using type = float; static constexpr int width = GMX_SIMD_FLOAT_WIDTH; - using tag = SimdFloatTag; + using tag = SimdFloatTag; }; #endif #if GMX_SIMD_HAVE_DOUBLE template<> struct SimdTraits { - using type = double; + using type = double; static constexpr int width = GMX_SIMD_DOUBLE_WIDTH; - using tag = SimdDoubleTag; + using tag = SimdDoubleTag; }; #endif #if GMX_SIMD_HAVE_FLOAT template<> struct SimdTraits { - using type = int; + using type = int; static constexpr int width = GMX_SIMD_FINT32_WIDTH; - using tag = SimdFInt32Tag; + using tag = SimdFInt32Tag; }; #endif #if GMX_SIMD_HAVE_DOUBLE template<> struct SimdTraits { - using type = int; + using type = int; static constexpr int width = GMX_SIMD_DINT32_WIDTH; - using tag = SimdDInt32Tag; + using tag = SimdDInt32Tag; }; #endif template struct SimdTraits { - using type = const typename SimdTraits::type; + using type = const typename SimdTraits::type; static constexpr int width = SimdTraits::width; - using tag = typename SimdTraits::tag; + using tag = typename SimdTraits::tag; }; -} //namespace internal +} // namespace internal /*! \brief Load function that returns SIMD or scalar * @@ -488,7 +502,7 @@ struct SimdTraits */ template static inline std::remove_const_t -load(const typename internal::SimdTraits::type *m) //disabled by SFINAE for non-SIMD types +load(const typename internal::SimdTraits::type* m) // disabled by SFINAE for non-SIMD types { return simdLoad(m, typename internal::SimdTraits::tag()); } @@ -505,9 +519,8 @@ load(const std::enable_if_t::value, T> *m) return *m; } -template -static inline T gmx_simdcall -load(const AlignedArray::type, N> &m) +template +static inline T gmx_simdcall load(const AlignedArray::type, N>& m) { return simdLoad(m.data(), typename internal::SimdTraits::tag()); } @@ -519,22 +532,19 @@ load(const AlignedArray::type, N> &m) * \return Loaded SimdFloat/Double/Int or basic scalar type */ template -static inline T -loadU(const typename internal::SimdTraits::type *m) +static inline T loadU(const typename internal::SimdTraits::type* m) { return simdLoadU(m, typename internal::SimdTraits::tag()); } template -static inline T -loadU(const std::enable_if_t::value, T> *m) +static inline T loadU(const std::enable_if_t::value, T>* m) { return *m; } -template -static inline T gmx_simdcall -loadU(const AlignedArray::type, N> &m) +template +static inline T gmx_simdcall loadU(const AlignedArray::type, N>& m) { return simdLoadU(m.data(), typename internal::SimdTraits::tag()); } @@ -546,32 +556,32 @@ loadU(const AlignedArray::type, N> &m) */ class SimdSetZeroProxy { - public: - //!\brief Conversion method that returns 0.0 as float - operator float() const { return 0.0F; } - //!\brief Conversion method that returns 0.0 as double - operator double() const { return 0.0; } - //!\brief Conversion method that returns 0.0 as int32 - operator std::int32_t() const { return 0; } +public: + //!\brief Conversion method that returns 0.0 as float + operator float() const { return 0.0F; } + //!\brief Conversion method that returns 0.0 as double + operator double() const { return 0.0; } + //!\brief Conversion method that returns 0.0 as int32 + operator std::int32_t() const { return 0; } #if GMX_SIMD_HAVE_FLOAT - //!\brief Conversion method that will execute setZero() for SimdFloat - operator SimdFloat() const { return setZeroF(); } - //!\brief Conversion method that will execute setZero() for SimdFInt32 - operator SimdFInt32() const { return setZeroFI(); } + //!\brief Conversion method that will execute setZero() for SimdFloat + operator SimdFloat() const { return setZeroF(); } + //!\brief Conversion method that will execute setZero() for SimdFInt32 + operator SimdFInt32() const { return setZeroFI(); } #endif #if GMX_SIMD4_HAVE_FLOAT - //!\brief Conversion method that will execute setZero() for Simd4Float - operator Simd4Float() const { return simd4SetZeroF(); } + //!\brief Conversion method that will execute setZero() for Simd4Float + operator Simd4Float() const { return simd4SetZeroF(); } #endif #if GMX_SIMD_HAVE_DOUBLE - //!\brief Conversion method that will execute setZero() for SimdDouble - operator SimdDouble() const { return setZeroD(); } - //!\brief Conversion method that will execute setZero() for SimdDInt32 - operator SimdDInt32() const { return setZeroDI(); } + //!\brief Conversion method that will execute setZero() for SimdDouble + operator SimdDouble() const { return setZeroD(); } + //!\brief Conversion method that will execute setZero() for SimdDInt32 + operator SimdDInt32() const { return setZeroDI(); } #endif #if GMX_SIMD4_HAVE_DOUBLE - //!\brief Conversion method that will execute setZero() for Simd4Double - operator Simd4Double() const { return simd4SetZeroD(); } + //!\brief Conversion method that will execute setZero() for Simd4Double + operator Simd4Double() const { return simd4SetZeroD(); } #endif }; @@ -581,17 +591,18 @@ class SimdSetZeroProxy * variable to zero based on the conversion function called when you * assign the result. */ -static inline SimdSetZeroProxy gmx_simdcall -setZero() +static inline SimdSetZeroProxy gmx_simdcall setZero() { return {}; } namespace internal { -//TODO: Don't foward function but properly rename them and use proper traits +// TODO: Don't foward function but properly rename them and use proper traits template -struct Simd4Traits {}; +struct Simd4Traits +{ +}; #if GMX_SIMD4_HAVE_FLOAT template<> @@ -608,7 +619,7 @@ struct Simd4Traits using type = double; }; #endif -} //namespace internal +} // namespace internal #if GMX_SIMD4_HAVE_REAL template @@ -628,126 +639,116 @@ T loadU(const typename internal::Simd4Traits::type* m) * For width=4 all functions are forwarded and for width=8 all but loadU4NOffset are forwarded. */ #if GMX_SIMD_HAVE_FLOAT -#if GMX_SIMD_FLOAT_WIDTH < 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT (GMX_SIMD_HAVE_LOADU && GMX_SIMD4_HAVE_FLOAT) -#elif GMX_SIMD_FLOAT_WIDTH == 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT GMX_SIMD_HAVE_LOADU -//For GMX_SIMD_FLOAT_WIDTH>4 it is the reponsibility of the implementation to set -//GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT -#endif +# if GMX_SIMD_FLOAT_WIDTH < 4 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT (GMX_SIMD_HAVE_LOADU && GMX_SIMD4_HAVE_FLOAT) +# elif GMX_SIMD_FLOAT_WIDTH == 4 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT GMX_SIMD_HAVE_LOADU +// For GMX_SIMD_FLOAT_WIDTH>4 it is the reponsibility of the implementation to set +// GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT +# endif -#if GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT -#if GMX_SIMD_FLOAT_WIDTH < 4 +# if GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT +# if GMX_SIMD_FLOAT_WIDTH < 4 using Simd4NFloat = Simd4Float; -#define GMX_SIMD4N_FLOAT_WIDTH 4 -#else +# define GMX_SIMD4N_FLOAT_WIDTH 4 +# else using Simd4NFloat = SimdFloat; -#define GMX_SIMD4N_FLOAT_WIDTH GMX_SIMD_FLOAT_WIDTH -#endif +# define GMX_SIMD4N_FLOAT_WIDTH GMX_SIMD_FLOAT_WIDTH +# endif -#if GMX_SIMD_FLOAT_WIDTH <= 4 -static inline Simd4NFloat gmx_simdcall -loadUNDuplicate4(const float* f) +# if GMX_SIMD_FLOAT_WIDTH <= 4 +static inline Simd4NFloat gmx_simdcall loadUNDuplicate4(const float* f) { return Simd4NFloat(*f); } -static inline Simd4NFloat gmx_simdcall -load4DuplicateN(const float* f) +static inline Simd4NFloat gmx_simdcall load4DuplicateN(const float* f) { return load(f); } -static inline Simd4NFloat gmx_simdcall -loadU4NOffset(const float* f, int) +static inline Simd4NFloat gmx_simdcall loadU4NOffset(const float* f, int) { return loadU(f); } -#elif GMX_SIMD_FLOAT_WIDTH == 8 -static inline Simd4NFloat gmx_simdcall -loadUNDuplicate4(const float* f) +# elif GMX_SIMD_FLOAT_WIDTH == 8 +static inline Simd4NFloat gmx_simdcall loadUNDuplicate4(const float* f) { return loadU1DualHsimd(f); } -static inline Simd4NFloat gmx_simdcall -load4DuplicateN(const float* f) +static inline Simd4NFloat gmx_simdcall load4DuplicateN(const float* f) { return loadDuplicateHsimd(f); } -#endif -#endif //GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT -#else //GMX_SIMD_HAVE_FLOAT -#define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 0 +# endif +# endif // GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT +#else // GMX_SIMD_HAVE_FLOAT +# define GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT 0 #endif #if GMX_SIMD_HAVE_DOUBLE -#if GMX_SIMD_DOUBLE_WIDTH < 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE (GMX_SIMD_HAVE_LOADU && GMX_SIMD4_HAVE_DOUBLE) -#elif GMX_SIMD_DOUBLE_WIDTH == 4 -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE GMX_SIMD_HAVE_LOADU -//For GMX_SIMD_DOUBLE_WIDTH>4 it is the reponsibility of the implementation to set -//GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE -#endif +# if GMX_SIMD_DOUBLE_WIDTH < 4 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE (GMX_SIMD_HAVE_LOADU && GMX_SIMD4_HAVE_DOUBLE) +# elif GMX_SIMD_DOUBLE_WIDTH == 4 +# define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE GMX_SIMD_HAVE_LOADU +// For GMX_SIMD_DOUBLE_WIDTH>4 it is the reponsibility of the implementation to set +// GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE +# endif -#if GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE -#if GMX_SIMD_DOUBLE_WIDTH < 4 +# if GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE +# if GMX_SIMD_DOUBLE_WIDTH < 4 using Simd4NDouble = Simd4Double; -#define GMX_SIMD4N_DOUBLE_WIDTH 4 -#else +# define GMX_SIMD4N_DOUBLE_WIDTH 4 +# else using Simd4NDouble = SimdDouble; -#define GMX_SIMD4N_DOUBLE_WIDTH GMX_SIMD_DOUBLE_WIDTH -#endif +# define GMX_SIMD4N_DOUBLE_WIDTH GMX_SIMD_DOUBLE_WIDTH +# endif -#if GMX_SIMD_DOUBLE_WIDTH <= 4 -static inline Simd4NDouble gmx_simdcall -loadUNDuplicate4(const double* f) +# if GMX_SIMD_DOUBLE_WIDTH <= 4 +static inline Simd4NDouble gmx_simdcall loadUNDuplicate4(const double* f) { return Simd4NDouble(*f); } -static inline Simd4NDouble gmx_simdcall -load4DuplicateN(const double* f) +static inline Simd4NDouble gmx_simdcall load4DuplicateN(const double* f) { return load(f); } -static inline Simd4NDouble gmx_simdcall -loadU4NOffset(const double* f, int /*unused*/) +static inline Simd4NDouble gmx_simdcall loadU4NOffset(const double* f, int /*unused*/) { return loadU(f); } -#elif GMX_SIMD_DOUBLE_WIDTH == 8 -static inline Simd4NDouble gmx_simdcall -loadUNDuplicate4(const double* f) +# elif GMX_SIMD_DOUBLE_WIDTH == 8 +static inline Simd4NDouble gmx_simdcall loadUNDuplicate4(const double* f) { return loadU1DualHsimd(f); } -static inline Simd4NDouble gmx_simdcall -load4DuplicateN(const double* f) +static inline Simd4NDouble gmx_simdcall load4DuplicateN(const double* f) { return loadDuplicateHsimd(f); } -#endif -#endif //GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE -#else //GMX_SIMD_HAVE_DOUBLE -#define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 0 +# endif +# endif // GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE +#else // GMX_SIMD_HAVE_DOUBLE +# define GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE 0 #endif #if GMX_DOUBLE -#define GMX_SIMD_HAVE_4NSIMD_UTIL_REAL GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE +# define GMX_SIMD_HAVE_4NSIMD_UTIL_REAL GMX_SIMD_HAVE_4NSIMD_UTIL_DOUBLE #else -#define GMX_SIMD_HAVE_4NSIMD_UTIL_REAL GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT +# define GMX_SIMD_HAVE_4NSIMD_UTIL_REAL GMX_SIMD_HAVE_4NSIMD_UTIL_FLOAT #endif #if GMX_SIMD_HAVE_4NSIMD_UTIL_REAL -#if GMX_DOUBLE +# if GMX_DOUBLE using Simd4NReal = Simd4NDouble; -#define GMX_SIMD4N_REAL_WIDTH GMX_SIMD4N_DOUBLE_WIDTH -#else +# define GMX_SIMD4N_REAL_WIDTH GMX_SIMD4N_DOUBLE_WIDTH +# else using Simd4NReal = Simd4NFloat; -#define GMX_SIMD4N_REAL_WIDTH GMX_SIMD4N_FLOAT_WIDTH -#endif +# define GMX_SIMD4N_REAL_WIDTH GMX_SIMD4N_FLOAT_WIDTH +# endif #endif //! \} end of name-group proxy objects -} // namespace gmx +} // namespace gmx // \} end of module_simd @@ -760,9 +761,9 @@ using Simd4NReal = Simd4NFloat; * * \param[in] ptr A pointer to a float */ -static inline bool isSimdAligned(const float *ptr) +static inline bool isSimdAligned(const float* ptr) { - return reinterpret_cast(ptr) % (GMX_SIMD_FLOAT_WIDTH*sizeof(float)) == 0; + return reinterpret_cast(ptr) % (GMX_SIMD_FLOAT_WIDTH * sizeof(float)) == 0; } #endif // GMX_SIMD_HAVE_FLOAT @@ -773,18 +774,18 @@ static inline bool isSimdAligned(const float *ptr) * * \param[in] ptr A pointer to a double */ -static inline bool isSimdAligned(const double *ptr) +static inline bool isSimdAligned(const double* ptr) { - return reinterpret_cast(ptr) % (GMX_SIMD_DOUBLE_WIDTH*sizeof(double)) == 0; + return reinterpret_cast(ptr) % (GMX_SIMD_DOUBLE_WIDTH * sizeof(double)) == 0; } #endif // GMX_SIMD_HAVE_DOUBLE #if GMX_SIMD_HAVE_REAL -#if GMX_SIMD_REAL_WIDTH > GMX_REAL_MAX_SIMD_WIDTH -#error "GMX_SIMD_REAL_WIDTH > GMX_REAL_MAX_SIMD_WIDTH: increase GMX_REAL_MAX_SIMD_WIDTH in real.h" -#endif +# if GMX_SIMD_REAL_WIDTH > GMX_REAL_MAX_SIMD_WIDTH +# error "GMX_SIMD_REAL_WIDTH > GMX_REAL_MAX_SIMD_WIDTH: increase GMX_REAL_MAX_SIMD_WIDTH in real.h" +# endif #endif @@ -806,8 +807,8 @@ static inline bool isSimdAligned(const double *ptr) If there's ever other kinds of SIMD code that might have the same problem, we might want to add other variables here. */ -# define GMX_SIMD_HAVE_FLOAT 1 -# define GMX_SIMD_HAVE_DOUBLE 1 +# define GMX_SIMD_HAVE_FLOAT 1 +# define GMX_SIMD_HAVE_DOUBLE 1 #endif // end of hack diff --git a/src/gromacs/simd/simd_math.h b/src/gromacs/simd/simd_math.h index e3973183e7..09ea3757a3 100644 --- a/src/gromacs/simd/simd_math.h +++ b/src/gromacs/simd/simd_math.h @@ -81,7 +81,7 @@ namespace gmx /*! \} */ -#if GMX_SIMD_HAVE_FLOAT +# if GMX_SIMD_HAVE_FLOAT /*! \name Single precision SIMD math functions * @@ -93,25 +93,24 @@ namespace gmx * SINGLE PRECISION SIMD MATH FUNCTIONS * ****************************************/ -#if !GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_COPYSIGN_FLOAT /*! \brief Composes floating point value with the magnitude of x and the sign of y. * * \param x Values to set sign for * \param y Values used to set sign * \return Magnitude of x, sign of y */ -static inline SimdFloat gmx_simdcall -copysign(SimdFloat x, SimdFloat y) +static inline SimdFloat gmx_simdcall copysign(SimdFloat x, SimdFloat y) { -#if GMX_SIMD_HAVE_LOGICAL - return abs(x) | ( SimdFloat(GMX_FLOAT_NEGZERO) & y ); -#else +# if GMX_SIMD_HAVE_LOGICAL + return abs(x) | (SimdFloat(GMX_FLOAT_NEGZERO) & y); +# else return blend(abs(x), -abs(x), y < setZero()); -#endif +# endif } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_FLOAT /*! \brief Perform one Newton-Raphson iteration to improve 1/sqrt(x) for SIMD float. * * This is a low-level routine that should only be used by SIMD math routine @@ -121,15 +120,14 @@ copysign(SimdFloat x, SimdFloat y) * \param x The reference (starting) value x for which we want 1/sqrt(x). * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline SimdFloat gmx_simdcall -rsqrtIter(SimdFloat lu, SimdFloat x) +static inline SimdFloat gmx_simdcall rsqrtIter(SimdFloat lu, SimdFloat x) { - SimdFloat tmp1 = x*lu; - SimdFloat tmp2 = SimdFloat(-0.5F)*lu; - tmp1 = fma(tmp1, lu, SimdFloat(-3.0F)); - return tmp1*tmp2; + SimdFloat tmp1 = x * lu; + SimdFloat tmp2 = SimdFloat(-0.5F) * lu; + tmp1 = fma(tmp1, lu, SimdFloat(-3.0F)); + return tmp1 * tmp2; } -#endif +# endif /*! \brief Calculate 1/sqrt(x) for SIMD float. * @@ -144,19 +142,18 @@ rsqrtIter(SimdFloat lu, SimdFloat x) * * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline SimdFloat gmx_simdcall -invsqrt(SimdFloat x) +static inline SimdFloat gmx_simdcall invsqrt(SimdFloat x) { SimdFloat lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -179,15 +176,13 @@ invsqrt(SimdFloat x) * responsibility for checking falls on you - this routine does not * check arguments. */ -static inline void gmx_simdcall -invsqrtPair(SimdFloat x0, SimdFloat x1, - SimdFloat *out0, SimdFloat *out1) +static inline void gmx_simdcall invsqrtPair(SimdFloat x0, SimdFloat x1, SimdFloat* out0, SimdFloat* out1) { *out0 = invsqrt(x0); *out1 = invsqrt(x1); } -#if !GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_RCP_ITER_FLOAT /*! \brief Perform one Newton-Raphson iteration to improve 1/x for SIMD float. * * This is a low-level routine that should only be used by SIMD math routine @@ -197,12 +192,11 @@ invsqrtPair(SimdFloat x0, SimdFloat x1, * \param x The reference (starting) value x for which we want 1/x. * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline SimdFloat gmx_simdcall -rcpIter(SimdFloat lu, SimdFloat x) +static inline SimdFloat gmx_simdcall rcpIter(SimdFloat lu, SimdFloat x) { - return lu*fnma(lu, x, SimdFloat(2.0F)); + return lu * fnma(lu, x, SimdFloat(2.0F)); } -#endif +# endif /*! \brief Calculate 1/x for SIMD float. * @@ -217,19 +211,18 @@ rcpIter(SimdFloat lu, SimdFloat x) * * \return 1/x. Result is undefined if your argument was invalid. */ -static inline SimdFloat gmx_simdcall -inv(SimdFloat x) +static inline SimdFloat gmx_simdcall inv(SimdFloat x) { SimdFloat lu = rcp(x); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -248,10 +241,9 @@ inv(SimdFloat x) * \note This function does not use any masking to avoid problems with * zero values in the denominator. */ -static inline SimdFloat gmx_simdcall -operator/(SimdFloat nom, SimdFloat denom) +static inline SimdFloat gmx_simdcall operator/(SimdFloat nom, SimdFloat denom) { - return nom*inv(denom); + return nom * inv(denom); } /*! \brief Calculate 1/sqrt(x) for masked entries of SIMD float. @@ -267,19 +259,18 @@ operator/(SimdFloat nom, SimdFloat denom) * \return 1/sqrt(x). Result is undefined if your argument was invalid or * entry was not masked, and 0.0 for masked-out entries. */ -static inline SimdFloat -maskzInvsqrt(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzInvsqrt(SimdFloat x, SimdFBool m) { SimdFloat lu = maskzRsqrt(x, m); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -291,19 +282,18 @@ maskzInvsqrt(SimdFloat x, SimdFBool m) * \param m Mask * \return 1/x for elements where m is true, or 0.0 for masked-out entries. */ -static inline SimdFloat gmx_simdcall -maskzInv(SimdFloat x, SimdFBool m) +static inline SimdFloat gmx_simdcall maskzInv(SimdFloat x, SimdFBool m) { SimdFloat lu = maskzRcp(x, m); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -325,14 +315,13 @@ maskzInv(SimdFloat x, SimdFBool m) * \return sqrt(x). The result is undefined if the input value does not fall * in the allowed range specified for the argument. */ -template -static inline SimdFloat gmx_simdcall -sqrt(SimdFloat x) +template +static inline SimdFloat gmx_simdcall sqrt(SimdFloat x) { if (opt == MathOptimization::Safe) { - SimdFloat res = maskzInvsqrt(x, setZero() < x); - return res*x; + SimdFloat res = maskzInvsqrt(x, setZero() < x); + return res * x; } else { @@ -347,11 +336,10 @@ sqrt(SimdFloat x) * be treated as 0.0. * \return Cube root of x. */ -static inline SimdFloat gmx_simdcall -cbrt(SimdFloat x) +static inline SimdFloat gmx_simdcall cbrt(SimdFloat x) { - const SimdFloat signBit(GMX_FLOAT_NEGZERO); - const SimdFloat minFloat(std::numeric_limits::min()); + const SimdFloat signBit(GMX_FLOAT_NEGZERO); + const SimdFloat minFloat(std::numeric_limits::min()); // Bias is 128-1 = 127, which is not divisible by 3. Since the largest-magnitude // negative exponent from frexp() is -126, we can subtract one more unit to get 126 // as offset, which is divisible by 3 (result 42). To avoid clang warnings about fragile integer @@ -363,7 +351,7 @@ cbrt(SimdFloat x) const SimdFloat one(1.0F); const SimdFloat two(2.0F); const SimdFloat three(3.0F); - const SimdFloat oneThird(1.0F/3.0F); + const SimdFloat oneThird(1.0F / 3.0F); const SimdFloat cbrt2(1.2599210498948731648F); const SimdFloat sqrCbrt2(1.5874010519681994748F); @@ -373,24 +361,24 @@ cbrt(SimdFloat x) // A number x is represented in IEEE754 as fraction*2^e. We rewrite this as // x=fraction*2^(3*n)*2^m, where e=3*n+m, and m is a remainder. // The cube root can the be evaluated by calculating the cube root of the fraction - // limited to the mantissa range, multiplied by 2^mod (which is either 1, +/-2^(1/3) or +/-2^(2/3), - // and then we load this into a new IEEE754 fp number with the exponent 2^n, where + // limited to the mantissa range, multiplied by 2^mod (which is either 1, +/-2^(1/3) or + // +/-2^(2/3), and then we load this into a new IEEE754 fp number with the exponent 2^n, where // n is the integer part of the original exponent divided by 3. - SimdFloat xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdFloat xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) - SimdFBool xIsNonZero = (minFloat <= xAbs); // treat denormals as 0 + SimdFloat xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdFloat xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + SimdFBool xIsNonZero = (minFloat <= xAbs); // treat denormals as 0 SimdFInt32 exponent; - SimdFloat y = frexp(xAbs, &exponent); + SimdFloat y = frexp(xAbs, &exponent); // For the mantissa (y) we will use a limited-range approximation of cbrt(y), // by first using a polynomial and then evaluating // Transform y to z = c2*y^2 + c1*y + c0, then w = z^3, and finally // evaluate the quotient q = z * (w + 2 * y) / (2 * w + y). - SimdFloat z = fma(fma(y, c2, c1), y, c0); - SimdFloat w = z*z*z; - SimdFloat nom = z * fma(two, y, w); - SimdFloat invDenom = inv(fma(two, w, y)); + SimdFloat z = fma(fma(y, c2, c1), y, c0); + SimdFloat w = z * z * z; + SimdFloat nom = z * fma(two, y, w); + SimdFloat invDenom = inv(fma(two, w, y)); // Handle the exponent. In principle there are beautiful ways to do this with custom 16-bit // division converted to multiplication... but we can't do that since our SIMD layer cannot @@ -445,24 +433,25 @@ cbrt(SimdFloat x) // will work just A-OK on all SIMD implementations, which avoids diverging code paths. // The 0.1 here is the safety margin due to truncation described in item 4 in the comments above. - SimdFloat offsetExp = cvtI2R(exponent) + SimdFloat(static_cast(3*offsetDiv3) + 0.1); + SimdFloat offsetExp = cvtI2R(exponent) + SimdFloat(static_cast(3 * offsetDiv3) + 0.1); - SimdFloat offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdFloat offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division - SimdFInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdFloat(static_cast(offsetDiv3))); + SimdFInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdFloat(static_cast(offsetDiv3))); - SimdFloat remainder = offsetExp - offsetExpDiv3 * three; + SimdFloat remainder = offsetExp - offsetExpDiv3 * three; // If remainder is 0 we should just have the factor 1.0, // so first pick 1.0 if it is below 0.5, and 2^(1/3) if it's above 0.5 (i.e., 1 or 2) - SimdFloat factor = blend(one, cbrt2, SimdFloat(0.5) < remainder); + SimdFloat factor = blend(one, cbrt2, SimdFloat(0.5) < remainder); // Second, we overwrite with 2^(2/3) if rem>1.5 (i.e., 2) - factor = blend(factor, sqrCbrt2, SimdFloat(1.5) < remainder); + factor = blend(factor, sqrCbrt2, SimdFloat(1.5) < remainder); // Assemble the non-signed fraction, and add the sign back by xor - SimdFloat fraction = (nom * invDenom * factor) ^ xSignBit; + SimdFloat fraction = (nom * invDenom * factor) ^ xSignBit; // Load to IEEE754 number, and set result to 0.0 if x was 0.0 or denormal - SimdFloat result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); + SimdFloat result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); return result; } @@ -475,11 +464,10 @@ cbrt(SimdFloat x) * \return Cube root of x. Undefined for values that don't * fulfill the restriction of abs(x) > minFloat. */ -static inline SimdFloat gmx_simdcall -invcbrt(SimdFloat x) +static inline SimdFloat gmx_simdcall invcbrt(SimdFloat x) { - const SimdFloat signBit(GMX_FLOAT_NEGZERO); - const SimdFloat minFloat(std::numeric_limits::min()); + const SimdFloat signBit(GMX_FLOAT_NEGZERO); + const SimdFloat minFloat(std::numeric_limits::min()); // Bias is 128-1 = 127, which is not divisible by 3. Since the largest-magnitude // negative exponent from frexp() is -126, we can subtract one more unit to get 126 // as offset, which is divisible by 3 (result 42). To avoid clang warnings about fragile integer @@ -491,46 +479,47 @@ invcbrt(SimdFloat x) const SimdFloat one(1.0F); const SimdFloat two(2.0F); const SimdFloat three(3.0F); - const SimdFloat oneThird(1.0F/3.0F); - const SimdFloat invCbrt2(1.0F/1.2599210498948731648F); - const SimdFloat invSqrCbrt2(1.0F/1.5874010519681994748F); + const SimdFloat oneThird(1.0F / 3.0F); + const SimdFloat invCbrt2(1.0F / 1.2599210498948731648F); + const SimdFloat invSqrCbrt2(1.0F / 1.5874010519681994748F); // We use pretty much exactly the same implementation as for cbrt(x), // but to compute the inverse we swap the nominator/denominator // in the quotient, and also swap the sign of the exponent parts. - SimdFloat xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdFloat xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + SimdFloat xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdFloat xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) SimdFInt32 exponent; - SimdFloat y = frexp(xAbs, &exponent); + SimdFloat y = frexp(xAbs, &exponent); // For the mantissa (y) we will use a limited-range approximation of cbrt(y), // by first using a polynomial and then evaluating // Transform y to z = c2*y^2 + c1*y + c0, then w = z^3, and finally // evaluate the quotient q = z * (w + 2 * y) / (2 * w + y). - SimdFloat z = fma(fma(y, c2, c1), y, c0); - SimdFloat w = z*z*z; - SimdFloat nom = fma(two, w, y); - SimdFloat invDenom = inv(z * fma(two, y, w)); + SimdFloat z = fma(fma(y, c2, c1), y, c0); + SimdFloat w = z * z * z; + SimdFloat nom = fma(two, w, y); + SimdFloat invDenom = inv(z * fma(two, y, w)); // The 0.1 here is the safety margin due to truncation described in item 4 in the comments above. - SimdFloat offsetExp = cvtI2R(exponent) + SimdFloat(static_cast(3*offsetDiv3) + 0.1); - SimdFloat offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdFloat offsetExp = cvtI2R(exponent) + SimdFloat(static_cast(3 * offsetDiv3) + 0.1); + SimdFloat offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division // We should swap the sign here, so we change order of the terms in the subtraction - SimdFInt32 expDiv3 = cvtR2I(SimdFloat(static_cast(offsetDiv3)) - offsetExpDiv3); + SimdFInt32 expDiv3 = cvtR2I(SimdFloat(static_cast(offsetDiv3)) - offsetExpDiv3); // Swap sign here too, so remainder is either 0, -1 or -2 - SimdFloat remainder = offsetExpDiv3 * three - offsetExp; + SimdFloat remainder = offsetExpDiv3 * three - offsetExp; // If remainder is 0 we should just have the factor 1.0, // so first pick 1.0 if it is above -0.5, and 2^(-1/3) if it's below -0.5 (i.e., -1 or -2) - SimdFloat factor = blend(one, invCbrt2, remainder < SimdFloat(-0.5) ); + SimdFloat factor = blend(one, invCbrt2, remainder < SimdFloat(-0.5)); // Second, we overwrite with 2^(-2/3) if rem<-1.5 (i.e., -2) - factor = blend(factor, invSqrCbrt2, remainder < SimdFloat(-1.5)); + factor = blend(factor, invSqrCbrt2, remainder < SimdFloat(-1.5)); // Assemble the non-signed fraction, and add the sign back by xor - SimdFloat fraction = (nom * invDenom * factor) ^ xSignBit; + SimdFloat fraction = (nom * invDenom * factor) ^ xSignBit; // Load to IEEE754 number, and set result to 0.0 if x was 0.0 or denormal SimdFloat result = ldexp(fraction, expDiv3); @@ -542,95 +531,93 @@ invcbrt(SimdFloat x) * \param x Argument, should be >0. * \result The base-2 logarithm of x. Undefined if argument is invalid. */ -static inline SimdFloat gmx_simdcall -log2(SimdFloat x) +static inline SimdFloat gmx_simdcall log2(SimdFloat x) { // This implementation computes log2 by // 1) Extracting the exponent and adding it to... // 2) A 9th-order minimax approximation using only odd // terms of (x-1)/(x+1), where x is the mantissa. -#if GMX_SIMD_HAVE_NATIVE_LOG_FLOAT +# if GMX_SIMD_HAVE_NATIVE_LOG_FLOAT // Just rescale if native log2() is not present, but log() is. return log(x) * SimdFloat(std::log2(std::exp(1.0))); -#else - const SimdFloat one(1.0F); - const SimdFloat two(2.0F); - const SimdFloat invsqrt2(1.0F/std::sqrt(2.0F)); - const SimdFloat CL9(0.342149508897807708152F); - const SimdFloat CL7(0.411570606888219447939F); - const SimdFloat CL5(0.577085979152320294183F); - const SimdFloat CL3(0.961796550607099898222F); - const SimdFloat CL1(2.885390081777926774009F); - SimdFloat fExp, x2, p; - SimdFBool m; - SimdFInt32 iExp; - - x = frexp(x, &iExp); - fExp = cvtI2R(iExp); - - m = x < invsqrt2; +# else + const SimdFloat one(1.0F); + const SimdFloat two(2.0F); + const SimdFloat invsqrt2(1.0F / std::sqrt(2.0F)); + const SimdFloat CL9(0.342149508897807708152F); + const SimdFloat CL7(0.411570606888219447939F); + const SimdFloat CL5(0.577085979152320294183F); + const SimdFloat CL3(0.961796550607099898222F); + const SimdFloat CL1(2.885390081777926774009F); + SimdFloat fExp, x2, p; + SimdFBool m; + SimdFInt32 iExp; + + x = frexp(x, &iExp); + fExp = cvtI2R(iExp); + + m = x < invsqrt2; // Adjust to non-IEEE format for x<1/sqrt(2): exponent -= 1, mantissa *= 2.0 - fExp = fExp - selectByMask(one, m); - x = x * blend(one, two, m); + fExp = fExp - selectByMask(one, m); + x = x * blend(one, two, m); - x = (x-one) * inv( x+one ); - x2 = x * x; + x = (x - one) * inv(x + one); + x2 = x * x; - p = fma(CL9, x2, CL7); - p = fma(p, x2, CL5); - p = fma(p, x2, CL3); - p = fma(p, x2, CL1); - p = fma(p, x, fExp); + p = fma(CL9, x2, CL7); + p = fma(p, x2, CL5); + p = fma(p, x2, CL3); + p = fma(p, x2, CL1); + p = fma(p, x, fExp); return p; -#endif +# endif } -#if !GMX_SIMD_HAVE_NATIVE_LOG_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_LOG_FLOAT /*! \brief SIMD float log(x). This is the natural logarithm. * * \param x Argument, should be >0. * \result The natural logarithm of x. Undefined if argument is invalid. */ -static inline SimdFloat gmx_simdcall -log(SimdFloat x) +static inline SimdFloat gmx_simdcall log(SimdFloat x) { - const SimdFloat one(1.0F); - const SimdFloat two(2.0F); - const SimdFloat invsqrt2(1.0F/std::sqrt(2.0F)); - const SimdFloat corr(0.693147180559945286226764F); - const SimdFloat CL9(0.2371599674224853515625F); - const SimdFloat CL7(0.285279005765914916992188F); - const SimdFloat CL5(0.400005519390106201171875F); - const SimdFloat CL3(0.666666567325592041015625F); - const SimdFloat CL1(2.0F); - SimdFloat fExp, x2, p; - SimdFBool m; - SimdFInt32 iExp; - - x = frexp(x, &iExp); - fExp = cvtI2R(iExp); - - m = x < invsqrt2; + const SimdFloat one(1.0F); + const SimdFloat two(2.0F); + const SimdFloat invsqrt2(1.0F / std::sqrt(2.0F)); + const SimdFloat corr(0.693147180559945286226764F); + const SimdFloat CL9(0.2371599674224853515625F); + const SimdFloat CL7(0.285279005765914916992188F); + const SimdFloat CL5(0.400005519390106201171875F); + const SimdFloat CL3(0.666666567325592041015625F); + const SimdFloat CL1(2.0F); + SimdFloat fExp, x2, p; + SimdFBool m; + SimdFInt32 iExp; + + x = frexp(x, &iExp); + fExp = cvtI2R(iExp); + + m = x < invsqrt2; // Adjust to non-IEEE format for x<1/sqrt(2): exponent -= 1, mantissa *= 2.0 - fExp = fExp - selectByMask(one, m); - x = x * blend(one, two, m); + fExp = fExp - selectByMask(one, m); + x = x * blend(one, two, m); - x = (x-one) * inv( x+one ); - x2 = x * x; + x = (x - one) * inv(x + one); + x2 = x * x; - p = fma(CL9, x2, CL7); - p = fma(p, x2, CL5); - p = fma(p, x2, CL3); - p = fma(p, x2, CL1); - p = fma(p, x, corr*fExp); + p = fma(CL9, x2, CL7); + p = fma(p, x2, CL5); + p = fma(p, x2, CL3); + p = fma(p, x2, CL1); + p = fma(p, x, corr * fExp); return p; } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_EXP2_FLOAT /*! \brief SIMD float 2^x * * \tparam opt If this is changed from the default (safe) into the unsafe @@ -660,21 +647,20 @@ log(SimdFloat x) * take the minimum of your variable and the largest valid argument * before calling this routine. */ -template -static inline SimdFloat gmx_simdcall -exp2(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp2(SimdFloat x) { - const SimdFloat CC6(0.0001534581200287996416911311F); - const SimdFloat CC5(0.001339993121934088894618990F); - const SimdFloat CC4(0.009618488957115180159497841F); - const SimdFloat CC3(0.05550328776964726865751735F); - const SimdFloat CC2(0.2402264689063408646490722F); - const SimdFloat CC1(0.6931472057372680777553816F); - const SimdFloat one(1.0F); - - SimdFloat intpart; - SimdFloat fexppart; - SimdFloat p; + const SimdFloat CC6(0.0001534581200287996416911311F); + const SimdFloat CC5(0.001339993121934088894618990F); + const SimdFloat CC4(0.009618488957115180159497841F); + const SimdFloat CC3(0.05550328776964726865751735F); + const SimdFloat CC2(0.2402264689063408646490722F); + const SimdFloat CC1(0.6931472057372680777553816F); + const SimdFloat one(1.0F); + + SimdFloat intpart; + SimdFloat fexppart; + SimdFloat p; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -695,25 +681,25 @@ exp2(SimdFloat x) // with an argument that is so negative it cannot be converted to an integer. if (opt == MathOptimization::Safe) { - x = max(x, SimdFloat(std::numeric_limits::lowest())); + x = max(x, SimdFloat(std::numeric_limits::lowest())); } - fexppart = ldexp(one, cvtR2I(x)); - intpart = round(x); - x = x - intpart; - - p = fma(CC6, x, CC5); - p = fma(p, x, CC4); - p = fma(p, x, CC3); - p = fma(p, x, CC2); - p = fma(p, x, CC1); - p = fma(p, x, one); - x = p * fexppart; + fexppart = ldexp(one, cvtR2I(x)); + intpart = round(x); + x = x - intpart; + + p = fma(CC6, x, CC5); + p = fma(p, x, CC4); + p = fma(p, x, CC3); + p = fma(p, x, CC2); + p = fma(p, x, CC1); + p = fma(p, x, one); + x = p * fexppart; return x; } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_EXP_FLOAT +# if !GMX_SIMD_HAVE_NATIVE_EXP_FLOAT /*! \brief SIMD float exp(x). * * In addition to scaling the argument for 2^x this routine correctly does @@ -747,22 +733,21 @@ exp2(SimdFloat x) * take the minimum of your variable and the largest valid argument * before calling this routine. */ -template -static inline SimdFloat gmx_simdcall -exp(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp(SimdFloat x) { - const SimdFloat argscale(1.44269504088896341F); - const SimdFloat invargscale0(-0.693145751953125F); - const SimdFloat invargscale1(-1.428606765330187045e-06F); - const SimdFloat CC4(0.00136324646882712841033936F); - const SimdFloat CC3(0.00836596917361021041870117F); - const SimdFloat CC2(0.0416710823774337768554688F); - const SimdFloat CC1(0.166665524244308471679688F); - const SimdFloat CC0(0.499999850988388061523438F); - const SimdFloat one(1.0F); - SimdFloat fexppart; - SimdFloat intpart; - SimdFloat y, p; + const SimdFloat argscale(1.44269504088896341F); + const SimdFloat invargscale0(-0.693145751953125F); + const SimdFloat invargscale1(-1.428606765330187045e-06F); + const SimdFloat CC4(0.00136324646882712841033936F); + const SimdFloat CC3(0.00836596917361021041870117F); + const SimdFloat CC2(0.0416710823774337768554688F); + const SimdFloat CC1(0.166665524244308471679688F); + const SimdFloat CC0(0.499999850988388061523438F); + const SimdFloat one(1.0F); + SimdFloat fexppart; + SimdFloat intpart; + SimdFloat y, p; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -785,32 +770,32 @@ exp(SimdFloat x) if (opt == MathOptimization::Safe) { - x = max(x, SimdFloat(std::numeric_limits::lowest())/argscale); + x = max(x, SimdFloat(std::numeric_limits::lowest()) / argscale); } - y = x * argscale; + y = x * argscale; - fexppart = ldexp(one, cvtR2I(y)); - intpart = round(y); + fexppart = ldexp(one, cvtR2I(y)); + intpart = round(y); // Extended precision arithmetics - x = fma(invargscale0, intpart, x); - x = fma(invargscale1, intpart, x); - - p = fma(CC4, x, CC3); - p = fma(p, x, CC2); - p = fma(p, x, CC1); - p = fma(p, x, CC0); - p = fma(x*x, p, x); -#if GMX_SIMD_HAVE_FMA - x = fma(p, fexppart, fexppart); -#else - x = (p + one) * fexppart; -#endif + x = fma(invargscale0, intpart, x); + x = fma(invargscale1, intpart, x); + + p = fma(CC4, x, CC3); + p = fma(p, x, CC2); + p = fma(p, x, CC1); + p = fma(p, x, CC0); + p = fma(x * x, p, x); +# if GMX_SIMD_HAVE_FMA + x = fma(p, fexppart, fexppart); +# else + x = (p + one) * fexppart; +# endif return x; } -#endif +# endif /*! \brief SIMD float pow(x,y) * @@ -833,9 +818,8 @@ exp(SimdFloat x) * take the minimum of your variable and the largest valid argument * before calling this routine. */ -template -static inline SimdFloat gmx_simdcall -pow(SimdFloat x, SimdFloat y) +template +static inline SimdFloat gmx_simdcall pow(SimdFloat x, SimdFloat y) { SimdFloat xcorr; @@ -854,7 +838,7 @@ pow(SimdFloat x, SimdFloat y) { // if x==0 and y>0 we explicitly set the result to 0.0 // For any x with y==0, the result will already be 1.0 since we multiply by y (0.0) and call exp(). - result = blend(result, setZero(), x == setZero() && setZero() < y ); + result = blend(result, setZero(), x == setZero() && setZero() < y); } return result; @@ -869,99 +853,98 @@ pow(SimdFloat x, SimdFloat y) * This routine achieves very close to full precision, but we do not care about * the last bit or the subnormal result range. */ -static inline SimdFloat gmx_simdcall -erf(SimdFloat x) +static inline SimdFloat gmx_simdcall erf(SimdFloat x) { // Coefficients for minimax approximation of erf(x)=x*P(x^2) in range [-1,1] - const SimdFloat CA6(7.853861353153693e-5F); - const SimdFloat CA5(-8.010193625184903e-4F); - const SimdFloat CA4(5.188327685732524e-3F); - const SimdFloat CA3(-2.685381193529856e-2F); - const SimdFloat CA2(1.128358514861418e-1F); - const SimdFloat CA1(-3.761262582423300e-1F); - const SimdFloat CA0(1.128379165726710F); + const SimdFloat CA6(7.853861353153693e-5F); + const SimdFloat CA5(-8.010193625184903e-4F); + const SimdFloat CA4(5.188327685732524e-3F); + const SimdFloat CA3(-2.685381193529856e-2F); + const SimdFloat CA2(1.128358514861418e-1F); + const SimdFloat CA1(-3.761262582423300e-1F); + const SimdFloat CA0(1.128379165726710F); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*P((1/(x-1))^2) in range [0.67,2] - const SimdFloat CB9(-0.0018629930017603923F); - const SimdFloat CB8(0.003909821287598495F); - const SimdFloat CB7(-0.0052094582210355615F); - const SimdFloat CB6(0.005685614362160572F); - const SimdFloat CB5(-0.0025367682853477272F); - const SimdFloat CB4(-0.010199799682318782F); - const SimdFloat CB3(0.04369575504816542F); - const SimdFloat CB2(-0.11884063474674492F); - const SimdFloat CB1(0.2732120154030589F); - const SimdFloat CB0(0.42758357702025784F); + const SimdFloat CB9(-0.0018629930017603923F); + const SimdFloat CB8(0.003909821287598495F); + const SimdFloat CB7(-0.0052094582210355615F); + const SimdFloat CB6(0.005685614362160572F); + const SimdFloat CB5(-0.0025367682853477272F); + const SimdFloat CB4(-0.010199799682318782F); + const SimdFloat CB3(0.04369575504816542F); + const SimdFloat CB2(-0.11884063474674492F); + const SimdFloat CB1(0.2732120154030589F); + const SimdFloat CB0(0.42758357702025784F); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*(1/x)*P((1/x)^2) in range [2,9.19] - const SimdFloat CC10(-0.0445555913112064F); - const SimdFloat CC9(0.21376355144663348F); - const SimdFloat CC8(-0.3473187200259257F); - const SimdFloat CC7(0.016690861551248114F); - const SimdFloat CC6(0.7560973182491192F); - const SimdFloat CC5(-1.2137903600145787F); - const SimdFloat CC4(0.8411872321232948F); - const SimdFloat CC3(-0.08670413896296343F); - const SimdFloat CC2(-0.27124782687240334F); - const SimdFloat CC1(-0.0007502488047806069F); - const SimdFloat CC0(0.5642114853803148F); - const SimdFloat one(1.0F); - const SimdFloat two(2.0F); - - SimdFloat x2, x4, y; - SimdFloat t, t2, w, w2; - SimdFloat pA0, pA1, pB0, pB1, pC0, pC1; - SimdFloat expmx2; - SimdFloat res_erf, res_erfc, res; - SimdFBool m, maskErf; + const SimdFloat CC10(-0.0445555913112064F); + const SimdFloat CC9(0.21376355144663348F); + const SimdFloat CC8(-0.3473187200259257F); + const SimdFloat CC7(0.016690861551248114F); + const SimdFloat CC6(0.7560973182491192F); + const SimdFloat CC5(-1.2137903600145787F); + const SimdFloat CC4(0.8411872321232948F); + const SimdFloat CC3(-0.08670413896296343F); + const SimdFloat CC2(-0.27124782687240334F); + const SimdFloat CC1(-0.0007502488047806069F); + const SimdFloat CC0(0.5642114853803148F); + const SimdFloat one(1.0F); + const SimdFloat two(2.0F); + + SimdFloat x2, x4, y; + SimdFloat t, t2, w, w2; + SimdFloat pA0, pA1, pB0, pB1, pC0, pC1; + SimdFloat expmx2; + SimdFloat res_erf, res_erfc, res; + SimdFBool m, maskErf; // Calculate erf() - x2 = x * x; - x4 = x2 * x2; - - pA0 = fma(CA6, x4, CA4); - pA1 = fma(CA5, x4, CA3); - pA0 = fma(pA0, x4, CA2); - pA1 = fma(pA1, x4, CA1); - pA0 = pA0*x4; - pA0 = fma(pA1, x2, pA0); + x2 = x * x; + x4 = x2 * x2; + + pA0 = fma(CA6, x4, CA4); + pA1 = fma(CA5, x4, CA3); + pA0 = fma(pA0, x4, CA2); + pA1 = fma(pA1, x4, CA1); + pA0 = pA0 * x4; + pA0 = fma(pA1, x2, pA0); // Constant term must come last for precision reasons - pA0 = pA0+CA0; + pA0 = pA0 + CA0; - res_erf = x*pA0; + res_erf = x * pA0; // Calculate erfc y = abs(x); maskErf = SimdFloat(0.75F) <= y; t = maskzInv(y, maskErf); - w = t-one; - t2 = t*t; - w2 = w*w; + w = t - one; + t2 = t * t; + w2 = w * w; // No need for a floating-point sieve here (as in erfc), since erf() // will never return values that are extremely small for large args. - expmx2 = exp( -y*y ); - - pB1 = fma(CB9, w2, CB7); - pB0 = fma(CB8, w2, CB6); - pB1 = fma(pB1, w2, CB5); - pB0 = fma(pB0, w2, CB4); - pB1 = fma(pB1, w2, CB3); - pB0 = fma(pB0, w2, CB2); - pB1 = fma(pB1, w2, CB1); - pB0 = fma(pB0, w2, CB0); - pB0 = fma(pB1, w, pB0); - - pC0 = fma(CC10, t2, CC8); - pC1 = fma(CC9, t2, CC7); - pC0 = fma(pC0, t2, CC6); - pC1 = fma(pC1, t2, CC5); - pC0 = fma(pC0, t2, CC4); - pC1 = fma(pC1, t2, CC3); - pC0 = fma(pC0, t2, CC2); - pC1 = fma(pC1, t2, CC1); - - pC0 = fma(pC0, t2, CC0); - pC0 = fma(pC1, t, pC0); - pC0 = pC0*t; + expmx2 = exp(-y * y); + + pB1 = fma(CB9, w2, CB7); + pB0 = fma(CB8, w2, CB6); + pB1 = fma(pB1, w2, CB5); + pB0 = fma(pB0, w2, CB4); + pB1 = fma(pB1, w2, CB3); + pB0 = fma(pB0, w2, CB2); + pB1 = fma(pB1, w2, CB1); + pB0 = fma(pB0, w2, CB0); + pB0 = fma(pB1, w, pB0); + + pC0 = fma(CC10, t2, CC8); + pC1 = fma(CC9, t2, CC7); + pC0 = fma(pC0, t2, CC6); + pC1 = fma(pC1, t2, CC5); + pC0 = fma(pC0, t2, CC4); + pC1 = fma(pC1, t2, CC3); + pC0 = fma(pC0, t2, CC2); + pC1 = fma(pC1, t2, CC1); + + pC0 = fma(pC0, t2, CC0); + pC0 = fma(pC1, t, pC0); + pC0 = pC0 * t; // Select pB0 or pC0 for erfc() m = two < y; @@ -970,10 +953,10 @@ erf(SimdFloat x) // erfc(x<0) = 2-erfc(|x|) m = x < setZero(); - res_erfc = blend(res_erfc, two-res_erfc, m); + res_erfc = blend(res_erfc, two - res_erfc, m); // Select erf() or erfc() - res = blend(res_erf, one-res_erfc, maskErf); + res = blend(res_erf, one - res_erfc, maskErf); return res; } @@ -989,47 +972,46 @@ erf(SimdFloat x) * (think results that are in the ballpark of 10^-30 for single precision) * since that is not relevant for MD. */ -static inline SimdFloat gmx_simdcall -erfc(SimdFloat x) +static inline SimdFloat gmx_simdcall erfc(SimdFloat x) { // Coefficients for minimax approximation of erf(x)=x*P(x^2) in range [-1,1] - const SimdFloat CA6(7.853861353153693e-5F); - const SimdFloat CA5(-8.010193625184903e-4F); - const SimdFloat CA4(5.188327685732524e-3F); - const SimdFloat CA3(-2.685381193529856e-2F); - const SimdFloat CA2(1.128358514861418e-1F); - const SimdFloat CA1(-3.761262582423300e-1F); - const SimdFloat CA0(1.128379165726710F); + const SimdFloat CA6(7.853861353153693e-5F); + const SimdFloat CA5(-8.010193625184903e-4F); + const SimdFloat CA4(5.188327685732524e-3F); + const SimdFloat CA3(-2.685381193529856e-2F); + const SimdFloat CA2(1.128358514861418e-1F); + const SimdFloat CA1(-3.761262582423300e-1F); + const SimdFloat CA0(1.128379165726710F); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*P((1/(x-1))^2) in range [0.67,2] - const SimdFloat CB9(-0.0018629930017603923F); - const SimdFloat CB8(0.003909821287598495F); - const SimdFloat CB7(-0.0052094582210355615F); - const SimdFloat CB6(0.005685614362160572F); - const SimdFloat CB5(-0.0025367682853477272F); - const SimdFloat CB4(-0.010199799682318782F); - const SimdFloat CB3(0.04369575504816542F); - const SimdFloat CB2(-0.11884063474674492F); - const SimdFloat CB1(0.2732120154030589F); - const SimdFloat CB0(0.42758357702025784F); + const SimdFloat CB9(-0.0018629930017603923F); + const SimdFloat CB8(0.003909821287598495F); + const SimdFloat CB7(-0.0052094582210355615F); + const SimdFloat CB6(0.005685614362160572F); + const SimdFloat CB5(-0.0025367682853477272F); + const SimdFloat CB4(-0.010199799682318782F); + const SimdFloat CB3(0.04369575504816542F); + const SimdFloat CB2(-0.11884063474674492F); + const SimdFloat CB1(0.2732120154030589F); + const SimdFloat CB0(0.42758357702025784F); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*(1/x)*P((1/x)^2) in range [2,9.19] - const SimdFloat CC10(-0.0445555913112064F); - const SimdFloat CC9(0.21376355144663348F); - const SimdFloat CC8(-0.3473187200259257F); - const SimdFloat CC7(0.016690861551248114F); - const SimdFloat CC6(0.7560973182491192F); - const SimdFloat CC5(-1.2137903600145787F); - const SimdFloat CC4(0.8411872321232948F); - const SimdFloat CC3(-0.08670413896296343F); - const SimdFloat CC2(-0.27124782687240334F); - const SimdFloat CC1(-0.0007502488047806069F); - const SimdFloat CC0(0.5642114853803148F); + const SimdFloat CC10(-0.0445555913112064F); + const SimdFloat CC9(0.21376355144663348F); + const SimdFloat CC8(-0.3473187200259257F); + const SimdFloat CC7(0.016690861551248114F); + const SimdFloat CC6(0.7560973182491192F); + const SimdFloat CC5(-1.2137903600145787F); + const SimdFloat CC4(0.8411872321232948F); + const SimdFloat CC3(-0.08670413896296343F); + const SimdFloat CC2(-0.27124782687240334F); + const SimdFloat CC1(-0.0007502488047806069F); + const SimdFloat CC0(0.5642114853803148F); // Coefficients for expansion of exp(x) in [0,0.1] // CD0 and CD1 are both 1.0, so no need to declare them separately - const SimdFloat CD2(0.5000066608081202F); - const SimdFloat CD3(0.1664795422874624F); - const SimdFloat CD4(0.04379839977652482F); - const SimdFloat one(1.0F); - const SimdFloat two(2.0F); + const SimdFloat CD2(0.5000066608081202F); + const SimdFloat CD3(0.1664795422874624F); + const SimdFloat CD4(0.04379839977652482F); + const SimdFloat one(1.0F); + const SimdFloat two(2.0F); /* We need to use a small trick here, since we cannot assume all SIMD * architectures support integers, and the flag we want (0xfffff000) would @@ -1038,37 +1020,38 @@ erfc(SimdFloat x) * fp numbers, and perform a logical or. Since the expression is constant, * we can at least hope it is evaluated at compile-time. */ -#if GMX_SIMD_HAVE_LOGICAL - const SimdFloat sieve(SimdFloat(-5.965323564e+29F) | SimdFloat(7.05044434e-30F)); -#else - const int isieve = 0xFFFFF000; - alignas(GMX_SIMD_ALIGNMENT) float mem[GMX_SIMD_FLOAT_WIDTH]; +# if GMX_SIMD_HAVE_LOGICAL + const SimdFloat sieve(SimdFloat(-5.965323564e+29F) | SimdFloat(7.05044434e-30F)); +# else + const int isieve = 0xFFFFF000; + alignas(GMX_SIMD_ALIGNMENT) float mem[GMX_SIMD_FLOAT_WIDTH]; union { - float f; int i; + float f; + int i; } conv; - int i; -#endif + int i; +# endif - SimdFloat x2, x4, y; - SimdFloat q, z, t, t2, w, w2; - SimdFloat pA0, pA1, pB0, pB1, pC0, pC1; - SimdFloat expmx2, corr; - SimdFloat res_erf, res_erfc, res; - SimdFBool m, msk_erf; + SimdFloat x2, x4, y; + SimdFloat q, z, t, t2, w, w2; + SimdFloat pA0, pA1, pB0, pB1, pC0, pC1; + SimdFloat expmx2, corr; + SimdFloat res_erf, res_erfc, res; + SimdFBool m, msk_erf; // Calculate erf() - x2 = x * x; - x4 = x2 * x2; - - pA0 = fma(CA6, x4, CA4); - pA1 = fma(CA5, x4, CA3); - pA0 = fma(pA0, x4, CA2); - pA1 = fma(pA1, x4, CA1); - pA1 = pA1 * x2; - pA0 = fma(pA0, x4, pA1); + x2 = x * x; + x4 = x2 * x2; + + pA0 = fma(CA6, x4, CA4); + pA1 = fma(CA5, x4, CA3); + pA0 = fma(pA0, x4, CA2); + pA1 = fma(pA1, x4, CA1); + pA1 = pA1 * x2; + pA0 = fma(pA0, x4, pA1); // Constant term must come last for precision reasons - pA0 = pA0 + CA0; + pA0 = pA0 + CA0; res_erf = x * pA0; @@ -1096,49 +1079,49 @@ erfc(SimdFloat x) * in double, but we still need memory as a backup when that is not available, * and this case is rare enough that we go directly there... */ -#if GMX_SIMD_HAVE_LOGICAL - z = y & sieve; -#else +# if GMX_SIMD_HAVE_LOGICAL + z = y & sieve; +# else store(mem, y); for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { - conv.f = mem[i]; - conv.i = conv.i & isieve; - mem[i] = conv.f; + conv.f = mem[i]; + conv.i = conv.i & isieve; + mem[i] = conv.f; } z = load(mem); -#endif - q = (z-y) * (z+y); - corr = fma(CD4, q, CD3); - corr = fma(corr, q, CD2); - corr = fma(corr, q, one); - corr = fma(corr, q, one); - - expmx2 = exp( -z*z ); - expmx2 = expmx2 * corr; - - pB1 = fma(CB9, w2, CB7); - pB0 = fma(CB8, w2, CB6); - pB1 = fma(pB1, w2, CB5); - pB0 = fma(pB0, w2, CB4); - pB1 = fma(pB1, w2, CB3); - pB0 = fma(pB0, w2, CB2); - pB1 = fma(pB1, w2, CB1); - pB0 = fma(pB0, w2, CB0); - pB0 = fma(pB1, w, pB0); - - pC0 = fma(CC10, t2, CC8); - pC1 = fma(CC9, t2, CC7); - pC0 = fma(pC0, t2, CC6); - pC1 = fma(pC1, t2, CC5); - pC0 = fma(pC0, t2, CC4); - pC1 = fma(pC1, t2, CC3); - pC0 = fma(pC0, t2, CC2); - pC1 = fma(pC1, t2, CC1); - - pC0 = fma(pC0, t2, CC0); - pC0 = fma(pC1, t, pC0); - pC0 = pC0 * t; +# endif + q = (z - y) * (z + y); + corr = fma(CD4, q, CD3); + corr = fma(corr, q, CD2); + corr = fma(corr, q, one); + corr = fma(corr, q, one); + + expmx2 = exp(-z * z); + expmx2 = expmx2 * corr; + + pB1 = fma(CB9, w2, CB7); + pB0 = fma(CB8, w2, CB6); + pB1 = fma(pB1, w2, CB5); + pB0 = fma(pB0, w2, CB4); + pB1 = fma(pB1, w2, CB3); + pB0 = fma(pB0, w2, CB2); + pB1 = fma(pB1, w2, CB1); + pB0 = fma(pB0, w2, CB0); + pB0 = fma(pB1, w, pB0); + + pC0 = fma(CC10, t2, CC8); + pC1 = fma(CC9, t2, CC7); + pC0 = fma(pC0, t2, CC6); + pC1 = fma(pC1, t2, CC5); + pC0 = fma(pC0, t2, CC4); + pC1 = fma(pC1, t2, CC3); + pC0 = fma(pC0, t2, CC2); + pC1 = fma(pC1, t2, CC1); + + pC0 = fma(pC0, t2, CC0); + pC0 = fma(pC1, t, pC0); + pC0 = pC0 * t; // Select pB0 or pC0 for erfc() m = two < y; @@ -1147,10 +1130,10 @@ erfc(SimdFloat x) // erfc(x<0) = 2-erfc(|x|) m = x < setZero(); - res_erfc = blend(res_erfc, two-res_erfc, m); + res_erfc = blend(res_erfc, two - res_erfc, m); // Select erf() or erfc() - res = blend(one-res_erf, res_erfc, msk_erf); + res = blend(one - res_erf, res_erfc, msk_erf); return res; } @@ -1165,44 +1148,43 @@ erfc(SimdFloat x) * magnitudes of the argument we inherently begin to lose accuracy due to the * argument reduction, despite using extended precision arithmetics internally. */ -static inline void gmx_simdcall -sincos(SimdFloat x, SimdFloat *sinval, SimdFloat *cosval) +static inline void gmx_simdcall sincos(SimdFloat x, SimdFloat* sinval, SimdFloat* cosval) { // Constants to subtract Pi/4*x from y while minimizing precision loss - const SimdFloat argred0(-1.5703125); - const SimdFloat argred1(-4.83751296997070312500e-04F); - const SimdFloat argred2(-7.54953362047672271729e-08F); - const SimdFloat argred3(-2.56334406825708960298e-12F); - const SimdFloat two_over_pi(static_cast(2.0F/M_PI)); - const SimdFloat const_sin2(-1.9515295891e-4F); - const SimdFloat const_sin1( 8.3321608736e-3F); - const SimdFloat const_sin0(-1.6666654611e-1F); - const SimdFloat const_cos2( 2.443315711809948e-5F); - const SimdFloat const_cos1(-1.388731625493765e-3F); - const SimdFloat const_cos0( 4.166664568298827e-2F); - const SimdFloat half(0.5F); - const SimdFloat one(1.0F); - SimdFloat ssign, csign; - SimdFloat x2, y, z, psin, pcos, sss, ccc; - SimdFBool m; - -#if GMX_SIMD_HAVE_FINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + const SimdFloat argred0(-1.5703125); + const SimdFloat argred1(-4.83751296997070312500e-04F); + const SimdFloat argred2(-7.54953362047672271729e-08F); + const SimdFloat argred3(-2.56334406825708960298e-12F); + const SimdFloat two_over_pi(static_cast(2.0F / M_PI)); + const SimdFloat const_sin2(-1.9515295891e-4F); + const SimdFloat const_sin1(8.3321608736e-3F); + const SimdFloat const_sin0(-1.6666654611e-1F); + const SimdFloat const_cos2(2.443315711809948e-5F); + const SimdFloat const_cos1(-1.388731625493765e-3F); + const SimdFloat const_cos0(4.166664568298827e-2F); + const SimdFloat half(0.5F); + const SimdFloat one(1.0F); + SimdFloat ssign, csign; + SimdFloat x2, y, z, psin, pcos, sss, ccc; + SimdFBool m; + +# if GMX_SIMD_HAVE_FINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL const SimdFInt32 ione(1); const SimdFInt32 itwo(2); SimdFInt32 iy; - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - - m = cvtIB2B((iy & ione) == SimdFInt32(0)); - ssign = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), cvtIB2B((iy & itwo) == itwo)); - csign = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), cvtIB2B(((iy+ione) & itwo) == itwo)); -#else - const SimdFloat quarter(0.25f); - const SimdFloat minusquarter(-0.25f); - SimdFloat q; - SimdFBool m1, m2, m3; + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + + m = cvtIB2B((iy & ione) == SimdFInt32(0)); + ssign = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), cvtIB2B((iy & itwo) == itwo)); + csign = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), cvtIB2B(((iy + ione) & itwo) == itwo)); +# else + const SimdFloat quarter(0.25f); + const SimdFloat minusquarter(-0.25f); + SimdFloat q; + SimdFBool m1, m2, m3; /* The most obvious way to find the arguments quadrant in the unit circle * to calculate the sign is to use integer arithmetic, but that is not @@ -1213,68 +1195,68 @@ sincos(SimdFloat x, SimdFloat *sinval, SimdFloat *cosval) * slightly slower (~10%) due to the longer latencies of floating-point, so * we only use it when integer SIMD arithmetic is not present. */ - ssign = x; - x = abs(x); + ssign = x; + x = abs(x); // It is critical that half-way cases are rounded down - z = fma(x, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); + z = fma(x, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); /* z now starts at 0.0 for x=-pi/4 (although neg. values cannot occur), and * then increased by 1.0 as x increases by 2*Pi, when it resets to 0.0. * This removes the 2*Pi periodicity without using any integer arithmetic. * First check if y had the value 2 or 3, set csign if true. */ - q = q - half; + q = q - half; /* If we have logical operations we can work directly on the signbit, which * saves instructions. Otherwise we need to represent signs as +1.0/-1.0. * Thus, if you are altering defines to debug alternative code paths, the * two GMX_SIMD_HAVE_LOGICAL sections in this routine must either both be * active or inactive - you will get errors if only one is used. */ -# if GMX_SIMD_HAVE_LOGICAL - ssign = ssign & SimdFloat(GMX_FLOAT_NEGZERO); - csign = andNot(q, SimdFloat(GMX_FLOAT_NEGZERO)); - ssign = ssign ^ csign; -# else - ssign = copysign(SimdFloat(1.0f), ssign); - csign = copysign(SimdFloat(1.0f), q); - csign = -csign; - ssign = ssign * csign; // swap ssign if csign was set. -# endif +# if GMX_SIMD_HAVE_LOGICAL + ssign = ssign & SimdFloat(GMX_FLOAT_NEGZERO); + csign = andNot(q, SimdFloat(GMX_FLOAT_NEGZERO)); + ssign = ssign ^ csign; +# else + ssign = copysign(SimdFloat(1.0f), ssign); + csign = copysign(SimdFloat(1.0f), q); + csign = -csign; + ssign = ssign * csign; // swap ssign if csign was set. +# endif // Check if y had value 1 or 3 (remember we subtracted 0.5 from q) - m1 = (q < minusquarter); - m2 = (setZero() <= q); - m3 = (q < quarter); - m2 = m2 && m3; - m = m1 || m2; + m1 = (q < minusquarter); + m2 = (setZero() <= q); + m3 = (q < quarter); + m2 = m2 && m3; + m = m1 || m2; // where mask is FALSE, swap sign. csign = csign * blend(SimdFloat(-1.0f), one, m); -#endif - x = fma(y, argred0, x); - x = fma(y, argred1, x); - x = fma(y, argred2, x); - x = fma(y, argred3, x); - x2 = x * x; - - psin = fma(const_sin2, x2, const_sin1); - psin = fma(psin, x2, const_sin0); - psin = fma(psin, x * x2, x); - pcos = fma(const_cos2, x2, const_cos1); - pcos = fma(pcos, x2, const_cos0); - pcos = fms(pcos, x2, half); - pcos = fma(pcos, x2, one); - - sss = blend(pcos, psin, m); - ccc = blend(psin, pcos, m); +# endif + x = fma(y, argred0, x); + x = fma(y, argred1, x); + x = fma(y, argred2, x); + x = fma(y, argred3, x); + x2 = x * x; + + psin = fma(const_sin2, x2, const_sin1); + psin = fma(psin, x2, const_sin0); + psin = fma(psin, x * x2, x); + pcos = fma(const_cos2, x2, const_cos1); + pcos = fma(pcos, x2, const_cos0); + pcos = fms(pcos, x2, half); + pcos = fma(pcos, x2, one); + + sss = blend(pcos, psin, m); + ccc = blend(psin, pcos, m); // See comment for GMX_SIMD_HAVE_LOGICAL section above. -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL *sinval = sss ^ ssign; *cosval = ccc ^ csign; -#else +# else *sinval = sss * ssign; *cosval = ccc * csign; -#endif +# endif } /*! \brief SIMD float sin(x). @@ -1285,8 +1267,7 @@ sincos(SimdFloat x, SimdFloat *sinval, SimdFloat *cosval) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdFloat gmx_simdcall -sin(SimdFloat x) +static inline SimdFloat gmx_simdcall sin(SimdFloat x) { SimdFloat s, c; sincos(x, &s, &c); @@ -1301,8 +1282,7 @@ sin(SimdFloat x) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdFloat gmx_simdcall -cos(SimdFloat x) +static inline SimdFloat gmx_simdcall cos(SimdFloat x) { SimdFloat s, c; sincos(x, &s, &c); @@ -1314,71 +1294,70 @@ cos(SimdFloat x) * \param x The argument to evaluate tan for * \result Tan(x) */ -static inline SimdFloat gmx_simdcall -tan(SimdFloat x) +static inline SimdFloat gmx_simdcall tan(SimdFloat x) { - const SimdFloat argred0(-1.5703125); - const SimdFloat argred1(-4.83751296997070312500e-04F); - const SimdFloat argred2(-7.54953362047672271729e-08F); - const SimdFloat argred3(-2.56334406825708960298e-12F); - const SimdFloat two_over_pi(static_cast(2.0F/M_PI)); - const SimdFloat CT6(0.009498288995810566122993911); - const SimdFloat CT5(0.002895755790837379295226923); - const SimdFloat CT4(0.02460087336161924491836265); - const SimdFloat CT3(0.05334912882656359828045988); - const SimdFloat CT2(0.1333989091464957704418495); - const SimdFloat CT1(0.3333307599244198227797507); - - SimdFloat x2, p, y, z; - SimdFBool m; - -#if GMX_SIMD_HAVE_FINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL - SimdFInt32 iy; - SimdFInt32 ione(1); - - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - m = cvtIB2B((iy & ione) == ione); - - x = fma(y, argred0, x); - x = fma(y, argred1, x); - x = fma(y, argred2, x); - x = fma(y, argred3, x); - x = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), m) ^ x; -#else - const SimdFloat quarter(0.25f); - const SimdFloat half(0.5f); - const SimdFloat threequarter(0.75f); - SimdFloat w, q; - SimdFBool m1, m2, m3; - - w = abs(x); - z = fma(w, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); - m1 = quarter <= q; - m2 = q < half; - m3 = threequarter <= q; - m1 = m1 && m2; - m = m1 || m3; - w = fma(y, argred0, w); - w = fma(y, argred1, w); - w = fma(y, argred2, w); - w = fma(y, argred3, w); - w = blend(w, -w, m); - x = w * copysign( SimdFloat(1.0), x ); -#endif - x2 = x * x; - p = fma(CT6, x2, CT5); - p = fma(p, x2, CT4); - p = fma(p, x2, CT3); - p = fma(p, x2, CT2); - p = fma(p, x2, CT1); - p = fma(x2 * p, x, x); - - p = blend( p, maskzInv(p, m), m); + const SimdFloat argred0(-1.5703125); + const SimdFloat argred1(-4.83751296997070312500e-04F); + const SimdFloat argred2(-7.54953362047672271729e-08F); + const SimdFloat argred3(-2.56334406825708960298e-12F); + const SimdFloat two_over_pi(static_cast(2.0F / M_PI)); + const SimdFloat CT6(0.009498288995810566122993911); + const SimdFloat CT5(0.002895755790837379295226923); + const SimdFloat CT4(0.02460087336161924491836265); + const SimdFloat CT3(0.05334912882656359828045988); + const SimdFloat CT2(0.1333989091464957704418495); + const SimdFloat CT1(0.3333307599244198227797507); + + SimdFloat x2, p, y, z; + SimdFBool m; + +# if GMX_SIMD_HAVE_FINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + SimdFInt32 iy; + SimdFInt32 ione(1); + + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + m = cvtIB2B((iy & ione) == ione); + + x = fma(y, argred0, x); + x = fma(y, argred1, x); + x = fma(y, argred2, x); + x = fma(y, argred3, x); + x = selectByMask(SimdFloat(GMX_FLOAT_NEGZERO), m) ^ x; +# else + const SimdFloat quarter(0.25f); + const SimdFloat half(0.5f); + const SimdFloat threequarter(0.75f); + SimdFloat w, q; + SimdFBool m1, m2, m3; + + w = abs(x); + z = fma(w, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); + m1 = quarter <= q; + m2 = q < half; + m3 = threequarter <= q; + m1 = m1 && m2; + m = m1 || m3; + w = fma(y, argred0, w); + w = fma(y, argred1, w); + w = fma(y, argred2, w); + w = fma(y, argred3, w); + w = blend(w, -w, m); + x = w * copysign(SimdFloat(1.0), x); +# endif + x2 = x * x; + p = fma(CT6, x2, CT5); + p = fma(p, x2, CT4); + p = fma(p, x2, CT3); + p = fma(p, x2, CT2); + p = fma(p, x2, CT1); + p = fma(x2 * p, x, x); + + p = blend(p, maskzInv(p, m), m); return p; } @@ -1387,13 +1366,12 @@ tan(SimdFloat x) * \param x The argument to evaluate asin for * \result Asin(x) */ -static inline SimdFloat gmx_simdcall -asin(SimdFloat x) +static inline SimdFloat gmx_simdcall asin(SimdFloat x) { const SimdFloat limitlow(1e-4F); const SimdFloat half(0.5F); const SimdFloat one(1.0F); - const SimdFloat halfpi(static_cast(M_PI/2.0F)); + const SimdFloat halfpi(static_cast(M_PI / 2.0F)); const SimdFloat CC5(4.2163199048E-2F); const SimdFloat CC4(2.4181311049E-2F); const SimdFloat CC3(4.5470025998E-2F); @@ -1404,30 +1382,30 @@ asin(SimdFloat x) SimdFloat pA, pB; SimdFBool m, m2; - xabs = abs(x); - m = half < xabs; - z1 = half * (one-xabs); - m2 = xabs < one; - q1 = z1 * maskzInvsqrt(z1, m2); - q2 = xabs; - z2 = q2 * q2; - z = blend(z2, z1, m); - q = blend(q2, q1, m); - - z2 = z * z; - pA = fma(CC5, z2, CC3); - pB = fma(CC4, z2, CC2); - pA = fma(pA, z2, CC1); - pA = pA * z; - z = fma(pB, z2, pA); - z = fma(z, q, q); - q2 = halfpi - z; - q2 = q2 - z; - z = blend(z, q2, m); - - m = limitlow < xabs; - z = blend( xabs, z, m ); - z = copysign(z, x); + xabs = abs(x); + m = half < xabs; + z1 = half * (one - xabs); + m2 = xabs < one; + q1 = z1 * maskzInvsqrt(z1, m2); + q2 = xabs; + z2 = q2 * q2; + z = blend(z2, z1, m); + q = blend(q2, q1, m); + + z2 = z * z; + pA = fma(CC5, z2, CC3); + pB = fma(CC4, z2, CC2); + pA = fma(pA, z2, CC1); + pA = pA * z; + z = fma(pB, z2, pA); + z = fma(z, q, q); + q2 = halfpi - z; + q2 = q2 - z; + z = blend(z, q2, m); + + m = limitlow < xabs; + z = blend(xabs, z, m); + z = copysign(z, x); return z; } @@ -1437,32 +1415,31 @@ asin(SimdFloat x) * \param x The argument to evaluate acos for * \result Acos(x) */ -static inline SimdFloat gmx_simdcall -acos(SimdFloat x) +static inline SimdFloat gmx_simdcall acos(SimdFloat x) { const SimdFloat one(1.0F); const SimdFloat half(0.5F); const SimdFloat pi(static_cast(M_PI)); - const SimdFloat halfpi(static_cast(M_PI/2.0F)); + const SimdFloat halfpi(static_cast(M_PI / 2.0F)); SimdFloat xabs; SimdFloat z, z1, z2, z3; SimdFBool m1, m2, m3; - xabs = abs(x); - m1 = half < xabs; - m2 = setZero() < x; + xabs = abs(x); + m1 = half < xabs; + m2 = setZero() < x; - z = fnma(half, xabs, half); - m3 = xabs < one; - z = z * maskzInvsqrt(z, m3); - z = blend(x, z, m1); - z = asin(z); + z = fnma(half, xabs, half); + m3 = xabs < one; + z = z * maskzInvsqrt(z, m3); + z = blend(x, z, m1); + z = asin(z); - z2 = z + z; - z1 = pi - z2; - z3 = halfpi - z; - z = blend(z1, z2, m2); - z = blend(z3, z, m1); + z2 = z + z; + z1 = pi - z2; + z3 = halfpi - z; + z = blend(z1, z2, m2); + z = blend(z3, z, m1); return z; } @@ -1472,41 +1449,40 @@ acos(SimdFloat x) * \param x The argument to evaluate atan for * \result Atan(x), same argument/value range as standard math library. */ -static inline SimdFloat gmx_simdcall -atan(SimdFloat x) +static inline SimdFloat gmx_simdcall atan(SimdFloat x) { - const SimdFloat halfpi(static_cast(M_PI/2.0F)); + const SimdFloat halfpi(static_cast(M_PI / 2.0F)); const SimdFloat CA17(0.002823638962581753730774F); const SimdFloat CA15(-0.01595690287649631500244F); const SimdFloat CA13(0.04250498861074447631836F); const SimdFloat CA11(-0.07489009201526641845703F); - const SimdFloat CA9 (0.1063479334115982055664F); - const SimdFloat CA7 (-0.1420273631811141967773F); - const SimdFloat CA5 (0.1999269574880599975585F); - const SimdFloat CA3 (-0.3333310186862945556640F); - const SimdFloat one (1.0F); + const SimdFloat CA9(0.1063479334115982055664F); + const SimdFloat CA7(-0.1420273631811141967773F); + const SimdFloat CA5(0.1999269574880599975585F); + const SimdFloat CA3(-0.3333310186862945556640F); + const SimdFloat one(1.0F); SimdFloat x2, x3, x4, pA, pB; SimdFBool m, m2; - m = x < setZero(); - x = abs(x); - m2 = one < x; - x = blend(x, maskzInv(x, m2), m2); - - x2 = x * x; - x3 = x2 * x; - x4 = x2 * x2; - pA = fma(CA17, x4, CA13); - pB = fma(CA15, x4, CA11); - pA = fma(pA, x4, CA9); - pB = fma(pB, x4, CA7); - pA = fma(pA, x4, CA5); - pB = fma(pB, x4, CA3); - pA = fma(pA, x2, pB); - pA = fma(pA, x3, x); - - pA = blend(pA, halfpi-pA, m2); - pA = blend(pA, -pA, m); + m = x < setZero(); + x = abs(x); + m2 = one < x; + x = blend(x, maskzInv(x, m2), m2); + + x2 = x * x; + x3 = x2 * x; + x4 = x2 * x2; + pA = fma(CA17, x4, CA13); + pB = fma(CA15, x4, CA11); + pA = fma(pA, x4, CA9); + pB = fma(pB, x4, CA7); + pA = fma(pA, x4, CA5); + pB = fma(pB, x4, CA3); + pA = fma(pA, x2, pB); + pA = fma(pA, x3, x); + + pA = blend(pA, halfpi - pA, m2); + pA = blend(pA, -pA, m); return pA; } @@ -1524,11 +1500,10 @@ atan(SimdFloat x) * of any concern in Gromacs, and in particular it will not affect calculations * of angles from vectors. */ -static inline SimdFloat gmx_simdcall -atan2(SimdFloat y, SimdFloat x) +static inline SimdFloat gmx_simdcall atan2(SimdFloat y, SimdFloat x) { const SimdFloat pi(static_cast(M_PI)); - const SimdFloat halfpi(static_cast(M_PI/2.0)); + const SimdFloat halfpi(static_cast(M_PI / 2.0)); SimdFloat xinv, p, aoffset; SimdFBool mask_xnz, mask_ynz, mask_xlt0, mask_ylt0; @@ -1537,16 +1512,16 @@ atan2(SimdFloat y, SimdFloat x) mask_xlt0 = x < setZero(); mask_ylt0 = y < setZero(); - aoffset = selectByNotMask(halfpi, mask_xnz); - aoffset = selectByMask(aoffset, mask_ynz); + aoffset = selectByNotMask(halfpi, mask_xnz); + aoffset = selectByMask(aoffset, mask_ynz); - aoffset = blend(aoffset, pi, mask_xlt0); - aoffset = blend(aoffset, -aoffset, mask_ylt0); + aoffset = blend(aoffset, pi, mask_xlt0); + aoffset = blend(aoffset, -aoffset, mask_ylt0); - xinv = maskzInv(x, mask_xnz); - p = y * xinv; - p = atan(p); - p = p + aoffset; + xinv = maskzInv(x, mask_xnz); + p = y * xinv; + p = atan(p); + p = p + aoffset; return p; } @@ -1630,47 +1605,45 @@ atan2(SimdFloat y, SimdFloat x) * For \f$\beta r \geq 7206\f$ the return value can be inf or NaN. * */ -static inline SimdFloat gmx_simdcall -pmeForceCorrection(SimdFloat z2) +static inline SimdFloat gmx_simdcall pmeForceCorrection(SimdFloat z2) { - const SimdFloat FN6(-1.7357322914161492954e-8F); - const SimdFloat FN5(1.4703624142580877519e-6F); - const SimdFloat FN4(-0.000053401640219807709149F); - const SimdFloat FN3(0.0010054721316683106153F); - const SimdFloat FN2(-0.019278317264888380590F); - const SimdFloat FN1(0.069670166153766424023F); - const SimdFloat FN0(-0.75225204789749321333F); - - const SimdFloat FD4(0.0011193462567257629232F); - const SimdFloat FD3(0.014866955030185295499F); - const SimdFloat FD2(0.11583842382862377919F); - const SimdFloat FD1(0.50736591960530292870F); - const SimdFloat FD0(1.0F); - - SimdFloat z4; - SimdFloat polyFN0, polyFN1, polyFD0, polyFD1; - - z4 = z2 * z2; - - polyFD0 = fma(FD4, z4, FD2); - polyFD1 = fma(FD3, z4, FD1); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = fma(polyFD1, z2, polyFD0); - - polyFD0 = inv(polyFD0); - - polyFN0 = fma(FN6, z4, FN4); - polyFN1 = fma(FN5, z4, FN3); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN0 = fma(polyFN1, z2, polyFN0); + const SimdFloat FN6(-1.7357322914161492954e-8F); + const SimdFloat FN5(1.4703624142580877519e-6F); + const SimdFloat FN4(-0.000053401640219807709149F); + const SimdFloat FN3(0.0010054721316683106153F); + const SimdFloat FN2(-0.019278317264888380590F); + const SimdFloat FN1(0.069670166153766424023F); + const SimdFloat FN0(-0.75225204789749321333F); + + const SimdFloat FD4(0.0011193462567257629232F); + const SimdFloat FD3(0.014866955030185295499F); + const SimdFloat FD2(0.11583842382862377919F); + const SimdFloat FD1(0.50736591960530292870F); + const SimdFloat FD0(1.0F); + + SimdFloat z4; + SimdFloat polyFN0, polyFN1, polyFD0, polyFD1; + + z4 = z2 * z2; + + polyFD0 = fma(FD4, z4, FD2); + polyFD1 = fma(FD3, z4, FD1); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = fma(polyFD1, z2, polyFD0); + + polyFD0 = inv(polyFD0); + + polyFN0 = fma(FN6, z4, FN4); + polyFN1 = fma(FN5, z4, FN3); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN0 = fma(polyFN1, z2, polyFN0); return polyFN0 * polyFD0; } - /*! \brief Calculate the potential correction due to PME analytically in SIMD float. * * \param z2 \f$(r \beta)^2\f$ - see below for details. @@ -1708,47 +1681,46 @@ pmeForceCorrection(SimdFloat z2) * when added to \f$1/r\f$ the error will be insignificant. * For \f$\beta r \geq 7142\f$ the return value can be inf or NaN. */ -static inline SimdFloat gmx_simdcall -pmePotentialCorrection(SimdFloat z2) +static inline SimdFloat gmx_simdcall pmePotentialCorrection(SimdFloat z2) { - const SimdFloat VN6(1.9296833005951166339e-8F); - const SimdFloat VN5(-1.4213390571557850962e-6F); - const SimdFloat VN4(0.000041603292906656984871F); - const SimdFloat VN3(-0.00013134036773265025626F); - const SimdFloat VN2(0.038657983986041781264F); - const SimdFloat VN1(0.11285044772717598220F); - const SimdFloat VN0(1.1283802385263030286F); + const SimdFloat VN6(1.9296833005951166339e-8F); + const SimdFloat VN5(-1.4213390571557850962e-6F); + const SimdFloat VN4(0.000041603292906656984871F); + const SimdFloat VN3(-0.00013134036773265025626F); + const SimdFloat VN2(0.038657983986041781264F); + const SimdFloat VN1(0.11285044772717598220F); + const SimdFloat VN0(1.1283802385263030286F); - const SimdFloat VD3(0.0066752224023576045451F); - const SimdFloat VD2(0.078647795836373922256F); - const SimdFloat VD1(0.43336185284710920150F); - const SimdFloat VD0(1.0F); + const SimdFloat VD3(0.0066752224023576045451F); + const SimdFloat VD2(0.078647795836373922256F); + const SimdFloat VD1(0.43336185284710920150F); + const SimdFloat VD0(1.0F); - SimdFloat z4; - SimdFloat polyVN0, polyVN1, polyVD0, polyVD1; + SimdFloat z4; + SimdFloat polyVN0, polyVN1, polyVD0, polyVD1; - z4 = z2 * z2; + z4 = z2 * z2; - polyVD1 = fma(VD3, z4, VD1); - polyVD0 = fma(VD2, z4, VD0); - polyVD0 = fma(polyVD1, z2, polyVD0); + polyVD1 = fma(VD3, z4, VD1); + polyVD0 = fma(VD2, z4, VD0); + polyVD0 = fma(polyVD1, z2, polyVD0); - polyVD0 = inv(polyVD0); + polyVD0 = inv(polyVD0); - polyVN0 = fma(VN6, z4, VN4); - polyVN1 = fma(VN5, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2, polyVN0); + polyVN0 = fma(VN6, z4, VN4); + polyVN1 = fma(VN5, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2, polyVN0); return polyVN0 * polyVD0; } -#endif +# endif /*! \} */ -#if GMX_SIMD_HAVE_DOUBLE +# if GMX_SIMD_HAVE_DOUBLE /*! \name Double precision SIMD math functions @@ -1761,25 +1733,24 @@ pmePotentialCorrection(SimdFloat z2) * DOUBLE PRECISION SIMD MATH FUNCTIONS * ****************************************/ -#if !GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_COPYSIGN_DOUBLE /*! \brief Composes floating point value with the magnitude of x and the sign of y. * * \param x Values to set sign for * \param y Values used to set sign * \return Magnitude of x, sign of y */ -static inline SimdDouble gmx_simdcall -copysign(SimdDouble x, SimdDouble y) +static inline SimdDouble gmx_simdcall copysign(SimdDouble x, SimdDouble y) { -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL return abs(x) | (SimdDouble(GMX_DOUBLE_NEGZERO) & y); -#else +# else return blend(abs(x), -abs(x), (y < setZero())); -#endif +# endif } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_RSQRT_ITER_DOUBLE /*! \brief Perform one Newton-Raphson iteration to improve 1/sqrt(x) for SIMD double. * * This is a low-level routine that should only be used by SIMD math routine @@ -1789,15 +1760,14 @@ copysign(SimdDouble x, SimdDouble y) * \param x The reference (starting) value x for which we want 1/sqrt(x). * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline SimdDouble gmx_simdcall -rsqrtIter(SimdDouble lu, SimdDouble x) +static inline SimdDouble gmx_simdcall rsqrtIter(SimdDouble lu, SimdDouble x) { - SimdDouble tmp1 = x*lu; - SimdDouble tmp2 = SimdDouble(-0.5)*lu; - tmp1 = fma(tmp1, lu, SimdDouble(-3.0)); - return tmp1*tmp2; + SimdDouble tmp1 = x * lu; + SimdDouble tmp2 = SimdDouble(-0.5) * lu; + tmp1 = fma(tmp1, lu, SimdDouble(-3.0)); + return tmp1 * tmp2; } -#endif +# endif /*! \brief Calculate 1/sqrt(x) for SIMD double. * @@ -1812,22 +1782,21 @@ rsqrtIter(SimdDouble lu, SimdDouble x) * * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline SimdDouble gmx_simdcall -invsqrt(SimdDouble x) +static inline SimdDouble gmx_simdcall invsqrt(SimdDouble x) { SimdDouble lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -1850,43 +1819,42 @@ invsqrt(SimdDouble x) * responsibility for checking falls on you - this routine does not * check arguments. */ -static inline void gmx_simdcall -invsqrtPair(SimdDouble x0, SimdDouble x1, - SimdDouble *out0, SimdDouble *out1) +static inline void gmx_simdcall invsqrtPair(SimdDouble x0, SimdDouble x1, SimdDouble* out0, SimdDouble* out1) { -#if GMX_SIMD_HAVE_FLOAT && (GMX_SIMD_FLOAT_WIDTH == 2*GMX_SIMD_DOUBLE_WIDTH) && (GMX_SIMD_RSQRT_BITS < 22) +# if GMX_SIMD_HAVE_FLOAT && (GMX_SIMD_FLOAT_WIDTH == 2 * GMX_SIMD_DOUBLE_WIDTH) \ + && (GMX_SIMD_RSQRT_BITS < 22) SimdFloat xf = cvtDD2F(x0, x1); SimdFloat luf = rsqrt(xf); SimdDouble lu0, lu1; // Intermediate target is single - mantissa+1 bits -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif +# endif cvtF2DD(luf, &lu0, &lu1); // Last iteration(s) performed in double - if we had 22 bits, this gets us to 44 (~1e-15) -#if (GMX_SIMD_ACCURACY_BITS_SINGLE < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_ACCURACY_BITS_SINGLE < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu0 = rsqrtIter(lu0, x0); lu1 = rsqrtIter(lu1, x1); -#endif -#if (GMX_SIMD_ACCURACY_BITS_SINGLE*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_ACCURACY_BITS_SINGLE * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu0 = rsqrtIter(lu0, x0); lu1 = rsqrtIter(lu1, x1); -#endif +# endif *out0 = lu0; *out1 = lu1; -#else +# else *out0 = invsqrt(x0); *out1 = invsqrt(x1); -#endif +# endif } -#if !GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_RCP_ITER_DOUBLE /*! \brief Perform one Newton-Raphson iteration to improve 1/x for SIMD double. * * This is a low-level routine that should only be used by SIMD math routine @@ -1896,12 +1864,11 @@ invsqrtPair(SimdDouble x0, SimdDouble x1, * \param x The reference (starting) value x for which we want 1/x. * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline SimdDouble gmx_simdcall -rcpIter(SimdDouble lu, SimdDouble x) +static inline SimdDouble gmx_simdcall rcpIter(SimdDouble lu, SimdDouble x) { - return lu*fnma(lu, x, SimdDouble(2.0)); + return lu * fnma(lu, x, SimdDouble(2.0)); } -#endif +# endif /*! \brief Calculate 1/x for SIMD double. * @@ -1916,22 +1883,21 @@ rcpIter(SimdDouble lu, SimdDouble x) * * \return 1/x. Result is undefined if your argument was invalid. */ -static inline SimdDouble gmx_simdcall -inv(SimdDouble x) +static inline SimdDouble gmx_simdcall inv(SimdDouble x) { SimdDouble lu = rcp(x); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -1950,10 +1916,9 @@ inv(SimdDouble x) * \note This function does not use any masking to avoid problems with * zero values in the denominator. */ -static inline SimdDouble gmx_simdcall -operator/(SimdDouble nom, SimdDouble denom) +static inline SimdDouble gmx_simdcall operator/(SimdDouble nom, SimdDouble denom) { - return nom*inv(denom); + return nom * inv(denom); } @@ -1970,22 +1935,21 @@ operator/(SimdDouble nom, SimdDouble denom) * \return 1/sqrt(x). Result is undefined if your argument was invalid or * entry was not masked, and 0.0 for masked-out entries. */ -static inline SimdDouble -maskzInvsqrt(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzInvsqrt(SimdDouble x, SimdDBool m) { SimdDouble lu = maskzRsqrt(x, m); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -1997,22 +1961,21 @@ maskzInvsqrt(SimdDouble x, SimdDBool m) * \param m Mask * \return 1/x for elements where m is true, or 0.0 for masked-out entries. */ -static inline SimdDouble gmx_simdcall -maskzInv(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzInv(SimdDouble x, SimdDBool m) { SimdDouble lu = maskzRcp(x, m); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RCP_BITS * 8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -2021,15 +1984,14 @@ maskzInv(SimdDouble x, SimdDBool m) * * \copydetails sqrt(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -sqrt(SimdDouble x) +template +static inline SimdDouble gmx_simdcall sqrt(SimdDouble x) { if (opt == MathOptimization::Safe) { // As we might use a float version of rsqrt, we mask out small values SimdDouble res = maskzInvsqrt(x, SimdDouble(GMX_FLOAT_MIN) < x); - return res*x; + return res * x; } else { @@ -2044,55 +2006,55 @@ sqrt(SimdDouble x) * be treated as 0.0. * \return Cube root of x. */ -static inline SimdDouble gmx_simdcall -cbrt(SimdDouble x) +static inline SimdDouble gmx_simdcall cbrt(SimdDouble x) { - const SimdDouble signBit(GMX_DOUBLE_NEGZERO); - const SimdDouble minDouble(std::numeric_limits::min()); + const SimdDouble signBit(GMX_DOUBLE_NEGZERO); + const SimdDouble minDouble(std::numeric_limits::min()); // Bias is 1024-1 = 1023, which is divisible by 3, so no need to change it more. // To avoid clang warnings about fragile integer division mixed with FP, we let // the divided value (1023/3=341) be the original constant. - const std::int32_t offsetDiv3(341); - const SimdDouble c6(-0.145263899385486377); - const SimdDouble c5(0.784932344976639262); - const SimdDouble c4(-1.83469277483613086); - const SimdDouble c3(2.44693122563534430); - const SimdDouble c2(-2.11499494167371287); - const SimdDouble c1(1.50819193781584896); - const SimdDouble c0(0.354895765043919860); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble three(3.0); - const SimdDouble oneThird(1.0/3.0); - const SimdDouble cbrt2(1.2599210498948731648); - const SimdDouble sqrCbrt2(1.5874010519681994748); + const std::int32_t offsetDiv3(341); + const SimdDouble c6(-0.145263899385486377); + const SimdDouble c5(0.784932344976639262); + const SimdDouble c4(-1.83469277483613086); + const SimdDouble c3(2.44693122563534430); + const SimdDouble c2(-2.11499494167371287); + const SimdDouble c1(1.50819193781584896); + const SimdDouble c0(0.354895765043919860); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble three(3.0); + const SimdDouble oneThird(1.0 / 3.0); + const SimdDouble cbrt2(1.2599210498948731648); + const SimdDouble sqrCbrt2(1.5874010519681994748); // See the single precision routines for documentation of the algorithm - SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) - SimdDBool xIsNonZero = (minDouble <= xAbs); // treat denormals as 0 - - SimdDInt32 exponent; - SimdDouble y = frexp(xAbs, &exponent); - SimdDouble z = fma(y, c6, c5); - z = fma(z, y, c4); - z = fma(z, y, c3); - z = fma(z, y, c2); - z = fma(z, y, c1); - z = fma(z, y, c0); - SimdDouble w = z*z*z; - SimdDouble nom = z * fma(two, y, w); - SimdDouble invDenom = inv(fma(two, w, y)); - - SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3*offsetDiv3) + 0.1); - SimdDouble offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division - SimdDInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdDouble(static_cast(offsetDiv3))); - SimdDouble remainder = offsetExp - offsetExpDiv3 * three; - SimdDouble factor = blend(one, cbrt2, SimdDouble(0.5) < remainder); - factor = blend(factor, sqrCbrt2, SimdDouble(1.5) < remainder); - SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; - SimdDouble result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); + SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + SimdDBool xIsNonZero = (minDouble <= xAbs); // treat denormals as 0 + + SimdDInt32 exponent; + SimdDouble y = frexp(xAbs, &exponent); + SimdDouble z = fma(y, c6, c5); + z = fma(z, y, c4); + z = fma(z, y, c3); + z = fma(z, y, c2); + z = fma(z, y, c1); + z = fma(z, y, c0); + SimdDouble w = z * z * z; + SimdDouble nom = z * fma(two, y, w); + SimdDouble invDenom = inv(fma(two, w, y)); + + SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3 * offsetDiv3) + 0.1); + SimdDouble offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdDInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdDouble(static_cast(offsetDiv3))); + SimdDouble remainder = offsetExp - offsetExpDiv3 * three; + SimdDouble factor = blend(one, cbrt2, SimdDouble(0.5) < remainder); + factor = blend(factor, sqrCbrt2, SimdDouble(1.5) < remainder); + SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; + SimdDouble result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); return result; } @@ -2104,52 +2066,52 @@ cbrt(SimdDouble x) * \return Cube root of x. Undefined for values that don't * fulfill the restriction of abs(x) > minDouble. */ -static inline SimdDouble gmx_simdcall -invcbrt(SimdDouble x) +static inline SimdDouble gmx_simdcall invcbrt(SimdDouble x) { - const SimdDouble signBit(GMX_DOUBLE_NEGZERO); + const SimdDouble signBit(GMX_DOUBLE_NEGZERO); // Bias is 1024-1 = 1023, which is divisible by 3, so no need to change it more. // To avoid clang warnings about fragile integer division mixed with FP, we let // the divided value (1023/3=341) be the original constant. - const std::int32_t offsetDiv3(341); - const SimdDouble c6(-0.145263899385486377); - const SimdDouble c5(0.784932344976639262); - const SimdDouble c4(-1.83469277483613086); - const SimdDouble c3(2.44693122563534430); - const SimdDouble c2(-2.11499494167371287); - const SimdDouble c1(1.50819193781584896); - const SimdDouble c0(0.354895765043919860); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble three(3.0); - const SimdDouble oneThird(1.0/3.0); - const SimdDouble invCbrt2(1.0/1.2599210498948731648); - const SimdDouble invSqrCbrt2(1.0F/1.5874010519681994748); + const std::int32_t offsetDiv3(341); + const SimdDouble c6(-0.145263899385486377); + const SimdDouble c5(0.784932344976639262); + const SimdDouble c4(-1.83469277483613086); + const SimdDouble c3(2.44693122563534430); + const SimdDouble c2(-2.11499494167371287); + const SimdDouble c1(1.50819193781584896); + const SimdDouble c0(0.354895765043919860); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble three(3.0); + const SimdDouble oneThird(1.0 / 3.0); + const SimdDouble invCbrt2(1.0 / 1.2599210498948731648); + const SimdDouble invSqrCbrt2(1.0F / 1.5874010519681994748); // See the single precision routines for documentation of the algorithm - SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) - - SimdDInt32 exponent; - SimdDouble y = frexp(xAbs, &exponent); - SimdDouble z = fma(y, c6, c5); - z = fma(z, y, c4); - z = fma(z, y, c3); - z = fma(z, y, c2); - z = fma(z, y, c1); - z = fma(z, y, c0); - SimdDouble w = z*z*z; - SimdDouble nom = fma(two, w, y); - SimdDouble invDenom = inv(z * fma(two, y, w)); - SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3*offsetDiv3) + 0.1); - SimdDouble offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division - SimdDInt32 expDiv3 = cvtR2I(SimdDouble(static_cast(offsetDiv3)) - offsetExpDiv3); - SimdDouble remainder = offsetExpDiv3 * three - offsetExp; - SimdDouble factor = blend(one, invCbrt2, remainder < SimdDouble(-0.5) ); - factor = blend(factor, invSqrCbrt2, remainder < SimdDouble(-1.5)); - SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; - SimdDouble result = ldexp(fraction, expDiv3); + SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + + SimdDInt32 exponent; + SimdDouble y = frexp(xAbs, &exponent); + SimdDouble z = fma(y, c6, c5); + z = fma(z, y, c4); + z = fma(z, y, c3); + z = fma(z, y, c2); + z = fma(z, y, c1); + z = fma(z, y, c0); + SimdDouble w = z * z * z; + SimdDouble nom = fma(two, w, y); + SimdDouble invDenom = inv(z * fma(two, y, w)); + SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3 * offsetDiv3) + 0.1); + SimdDouble offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdDInt32 expDiv3 = cvtR2I(SimdDouble(static_cast(offsetDiv3)) - offsetExpDiv3); + SimdDouble remainder = offsetExpDiv3 * three - offsetExp; + SimdDouble factor = blend(one, invCbrt2, remainder < SimdDouble(-0.5)); + factor = blend(factor, invSqrCbrt2, remainder < SimdDouble(-1.5)); + SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; + SimdDouble result = ldexp(fraction, expDiv3); return result; } @@ -2158,126 +2120,123 @@ invcbrt(SimdDouble x) * \param x Argument, should be >0. * \result The base-2 logarithm of x. Undefined if argument is invalid. */ -static inline SimdDouble gmx_simdcall -log2(SimdDouble x) +static inline SimdDouble gmx_simdcall log2(SimdDouble x) { -#if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE +# if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE // Just rescale if native log2() is not present, but log is. return log(x) * SimdDouble(std::log2(std::exp(1.0))); -#else - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble invsqrt2(1.0/std::sqrt(2.0)); - const SimdDouble CL15(0.2138031565795550370534528); - const SimdDouble CL13(0.2208884091496370882801159); - const SimdDouble CL11(0.2623358279761824340958754); - const SimdDouble CL9(0.3205984930182496084327681); - const SimdDouble CL7(0.4121985864521960363227038); - const SimdDouble CL5(0.5770780163410746954610886); - const SimdDouble CL3(0.9617966939260027547931031); - const SimdDouble CL1(2.885390081777926774009302); - SimdDouble fExp, x2, p; - SimdDBool m; - SimdDInt32 iExp; - - x = frexp(x, &iExp); - fExp = cvtI2R(iExp); - - m = x < invsqrt2; +# else + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble invsqrt2(1.0 / std::sqrt(2.0)); + const SimdDouble CL15(0.2138031565795550370534528); + const SimdDouble CL13(0.2208884091496370882801159); + const SimdDouble CL11(0.2623358279761824340958754); + const SimdDouble CL9(0.3205984930182496084327681); + const SimdDouble CL7(0.4121985864521960363227038); + const SimdDouble CL5(0.5770780163410746954610886); + const SimdDouble CL3(0.9617966939260027547931031); + const SimdDouble CL1(2.885390081777926774009302); + SimdDouble fExp, x2, p; + SimdDBool m; + SimdDInt32 iExp; + + x = frexp(x, &iExp); + fExp = cvtI2R(iExp); + + m = x < invsqrt2; // Adjust to non-IEEE format for x<1/sqrt(2): exponent -= 1, mantissa *= 2.0 - fExp = fExp - selectByMask(one, m); - x = x * blend(one, two, m); + fExp = fExp - selectByMask(one, m); + x = x * blend(one, two, m); - x = (x-one) * inv( x+one ); - x2 = x * x; + x = (x - one) * inv(x + one); + x2 = x * x; - p = fma(CL15, x2, CL13); - p = fma(p, x2, CL11); - p = fma(p, x2, CL9); - p = fma(p, x2, CL7); - p = fma(p, x2, CL5); - p = fma(p, x2, CL3); - p = fma(p, x2, CL1); - p = fma(p, x, fExp); + p = fma(CL15, x2, CL13); + p = fma(p, x2, CL11); + p = fma(p, x2, CL9); + p = fma(p, x2, CL7); + p = fma(p, x2, CL5); + p = fma(p, x2, CL3); + p = fma(p, x2, CL1); + p = fma(p, x, fExp); return p; -#endif +# endif } -#if !GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE /*! \brief SIMD double log(x). This is the natural logarithm. * * \param x Argument, should be >0. * \result The natural logarithm of x. Undefined if argument is invalid. */ -static inline SimdDouble gmx_simdcall -log(SimdDouble x) +static inline SimdDouble gmx_simdcall log(SimdDouble x) { - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble invsqrt2(1.0/std::sqrt(2.0)); - const SimdDouble corr(0.693147180559945286226764); - const SimdDouble CL15(0.148197055177935105296783); - const SimdDouble CL13(0.153108178020442575739679); - const SimdDouble CL11(0.181837339521549679055568); - const SimdDouble CL9(0.22222194152736701733275); - const SimdDouble CL7(0.285714288030134544449368); - const SimdDouble CL5(0.399999999989941956712869); - const SimdDouble CL3(0.666666666666685503450651); - const SimdDouble CL1(2.0); - SimdDouble fExp, x2, p; - SimdDBool m; - SimdDInt32 iExp; - - x = frexp(x, &iExp); - fExp = cvtI2R(iExp); - - m = x < invsqrt2; + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble invsqrt2(1.0 / std::sqrt(2.0)); + const SimdDouble corr(0.693147180559945286226764); + const SimdDouble CL15(0.148197055177935105296783); + const SimdDouble CL13(0.153108178020442575739679); + const SimdDouble CL11(0.181837339521549679055568); + const SimdDouble CL9(0.22222194152736701733275); + const SimdDouble CL7(0.285714288030134544449368); + const SimdDouble CL5(0.399999999989941956712869); + const SimdDouble CL3(0.666666666666685503450651); + const SimdDouble CL1(2.0); + SimdDouble fExp, x2, p; + SimdDBool m; + SimdDInt32 iExp; + + x = frexp(x, &iExp); + fExp = cvtI2R(iExp); + + m = x < invsqrt2; // Adjust to non-IEEE format for x<1/sqrt(2): exponent -= 1, mantissa *= 2.0 - fExp = fExp - selectByMask(one, m); - x = x * blend(one, two, m); + fExp = fExp - selectByMask(one, m); + x = x * blend(one, two, m); - x = (x-one) * inv( x+one ); - x2 = x * x; + x = (x - one) * inv(x + one); + x2 = x * x; - p = fma(CL15, x2, CL13); - p = fma(p, x2, CL11); - p = fma(p, x2, CL9); - p = fma(p, x2, CL7); - p = fma(p, x2, CL5); - p = fma(p, x2, CL3); - p = fma(p, x2, CL1); - p = fma(p, x, corr * fExp); + p = fma(CL15, x2, CL13); + p = fma(p, x2, CL11); + p = fma(p, x2, CL9); + p = fma(p, x2, CL7); + p = fma(p, x2, CL5); + p = fma(p, x2, CL3); + p = fma(p, x2, CL1); + p = fma(p, x, corr * fExp); return p; } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE /*! \brief SIMD double 2^x. * * \copydetails exp2(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -exp2(SimdDouble x) +template +static inline SimdDouble gmx_simdcall exp2(SimdDouble x) { - const SimdDouble CE11(4.435280790452730022081181e-10); - const SimdDouble CE10(7.074105630863314448024247e-09); - const SimdDouble CE9(1.017819803432096698472621e-07); - const SimdDouble CE8(1.321543308956718799557863e-06); - const SimdDouble CE7(0.00001525273348995851746990884); - const SimdDouble CE6(0.0001540353046251466849082632); - const SimdDouble CE5(0.001333355814678995257307880); - const SimdDouble CE4(0.009618129107588335039176502); - const SimdDouble CE3(0.05550410866481992147457793); - const SimdDouble CE2(0.2402265069591015620470894); - const SimdDouble CE1(0.6931471805599453304615075); - const SimdDouble one(1.0); - - SimdDouble intpart; - SimdDouble fexppart; - SimdDouble p; + const SimdDouble CE11(4.435280790452730022081181e-10); + const SimdDouble CE10(7.074105630863314448024247e-09); + const SimdDouble CE9(1.017819803432096698472621e-07); + const SimdDouble CE8(1.321543308956718799557863e-06); + const SimdDouble CE7(0.00001525273348995851746990884); + const SimdDouble CE6(0.0001540353046251466849082632); + const SimdDouble CE5(0.001333355814678995257307880); + const SimdDouble CE4(0.009618129107588335039176502); + const SimdDouble CE3(0.05550410866481992147457793); + const SimdDouble CE2(0.2402265069591015620470894); + const SimdDouble CE1(0.6931471805599453304615075); + const SimdDouble one(1.0); + + SimdDouble intpart; + SimdDouble fexppart; + SimdDouble p; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -2298,56 +2257,55 @@ exp2(SimdDouble x) // with an argument that is so negative it cannot be converted to an integer. if (opt == MathOptimization::Safe) { - x = max(x, SimdDouble(std::numeric_limits::lowest())); + x = max(x, SimdDouble(std::numeric_limits::lowest())); } - fexppart = ldexp(one, cvtR2I(x)); - intpart = round(x); - x = x - intpart; - - p = fma(CE11, x, CE10); - p = fma(p, x, CE9); - p = fma(p, x, CE8); - p = fma(p, x, CE7); - p = fma(p, x, CE6); - p = fma(p, x, CE5); - p = fma(p, x, CE4); - p = fma(p, x, CE3); - p = fma(p, x, CE2); - p = fma(p, x, CE1); - p = fma(p, x, one); - x = p * fexppart; + fexppart = ldexp(one, cvtR2I(x)); + intpart = round(x); + x = x - intpart; + + p = fma(CE11, x, CE10); + p = fma(p, x, CE9); + p = fma(p, x, CE8); + p = fma(p, x, CE7); + p = fma(p, x, CE6); + p = fma(p, x, CE5); + p = fma(p, x, CE4); + p = fma(p, x, CE3); + p = fma(p, x, CE2); + p = fma(p, x, CE1); + p = fma(p, x, one); + x = p * fexppart; return x; } -#endif +# endif -#if !GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE +# if !GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE /*! \brief SIMD double exp(x). * * \copydetails exp(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -exp(SimdDouble x) +template +static inline SimdDouble gmx_simdcall exp(SimdDouble x) { - const SimdDouble argscale(1.44269504088896340735992468100); - const SimdDouble invargscale0(-0.69314718055966295651160180568695068359375); - const SimdDouble invargscale1(-2.8235290563031577122588448175013436025525412068e-13); - const SimdDouble CE12(2.078375306791423699350304e-09); - const SimdDouble CE11(2.518173854179933105218635e-08); - const SimdDouble CE10(2.755842049600488770111608e-07); - const SimdDouble CE9(2.755691815216689746619849e-06); - const SimdDouble CE8(2.480158383706245033920920e-05); - const SimdDouble CE7(0.0001984127043518048611841321); - const SimdDouble CE6(0.001388888889360258341755930); - const SimdDouble CE5(0.008333333332907368102819109); - const SimdDouble CE4(0.04166666666663836745814631); - const SimdDouble CE3(0.1666666666666796929434570); - const SimdDouble CE2(0.5); - const SimdDouble one(1.0); - SimdDouble fexppart; - SimdDouble intpart; - SimdDouble y, p; + const SimdDouble argscale(1.44269504088896340735992468100); + const SimdDouble invargscale0(-0.69314718055966295651160180568695068359375); + const SimdDouble invargscale1(-2.8235290563031577122588448175013436025525412068e-13); + const SimdDouble CE12(2.078375306791423699350304e-09); + const SimdDouble CE11(2.518173854179933105218635e-08); + const SimdDouble CE10(2.755842049600488770111608e-07); + const SimdDouble CE9(2.755691815216689746619849e-06); + const SimdDouble CE8(2.480158383706245033920920e-05); + const SimdDouble CE7(0.0001984127043518048611841321); + const SimdDouble CE6(0.001388888889360258341755930); + const SimdDouble CE5(0.008333333332907368102819109); + const SimdDouble CE4(0.04166666666663836745814631); + const SimdDouble CE3(0.1666666666666796929434570); + const SimdDouble CE2(0.5); + const SimdDouble one(1.0); + SimdDouble fexppart; + SimdDouble intpart; + SimdDouble y, p; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -2370,38 +2328,38 @@ exp(SimdDouble x) if (opt == MathOptimization::Safe) { - x = max(x, SimdDouble(std::numeric_limits::lowest())/argscale); + x = max(x, SimdDouble(std::numeric_limits::lowest()) / argscale); } - y = x * argscale; + y = x * argscale; - fexppart = ldexp(one, cvtR2I(y)); - intpart = round(y); + fexppart = ldexp(one, cvtR2I(y)); + intpart = round(y); // Extended precision arithmetics - x = fma(invargscale0, intpart, x); - x = fma(invargscale1, intpart, x); - - p = fma(CE12, x, CE11); - p = fma(p, x, CE10); - p = fma(p, x, CE9); - p = fma(p, x, CE8); - p = fma(p, x, CE7); - p = fma(p, x, CE6); - p = fma(p, x, CE5); - p = fma(p, x, CE4); - p = fma(p, x, CE3); - p = fma(p, x, CE2); - p = fma(p, x * x, x); -#if GMX_SIMD_HAVE_FMA - x = fma(p, fexppart, fexppart); -#else - x = (p + one) * fexppart; -#endif + x = fma(invargscale0, intpart, x); + x = fma(invargscale1, intpart, x); + + p = fma(CE12, x, CE11); + p = fma(p, x, CE10); + p = fma(p, x, CE9); + p = fma(p, x, CE8); + p = fma(p, x, CE7); + p = fma(p, x, CE6); + p = fma(p, x, CE5); + p = fma(p, x, CE4); + p = fma(p, x, CE3); + p = fma(p, x, CE2); + p = fma(p, x * x, x); +# if GMX_SIMD_HAVE_FMA + x = fma(p, fexppart, fexppart); +# else + x = (p + one) * fexppart; +# endif return x; } -#endif +# endif /*! \brief SIMD double pow(x,y) * @@ -2424,9 +2382,8 @@ exp(SimdDouble x) * take the minimum of your variable and the largest valid argument * before calling this routine. */ -template -static inline SimdDouble gmx_simdcall -pow(SimdDouble x, SimdDouble y) +template +static inline SimdDouble gmx_simdcall pow(SimdDouble x, SimdDouble y) { SimdDouble xcorr; @@ -2445,7 +2402,7 @@ pow(SimdDouble x, SimdDouble y) { // if x==0 and y>0 we explicitly set the result to 0.0 // For any x with y==0, the result will already be 1.0 since we multiply by y (0.0) and call exp(). - result = blend(result, setZero(), x == setZero() && setZero() < y ); + result = blend(result, setZero(), x == setZero() && setZero() < y); } return result; @@ -2460,8 +2417,7 @@ pow(SimdDouble x, SimdDouble y) * This routine achieves very close to full precision, but we do not care about * the last bit or the subnormal result range. */ -static inline SimdDouble gmx_simdcall -erf(SimdDouble x) +static inline SimdDouble gmx_simdcall erf(SimdDouble x) { // Coefficients for minimax approximation of erf(x)=x*(CAoffset + P(x^2)/Q(x^2)) in range [-0.75,0.75] const SimdDouble CAP4(-0.431780540597889301512e-4); @@ -2517,13 +2473,13 @@ erf(SimdDouble x) const SimdDouble two(2.0); const SimdDouble minFloat(std::numeric_limits::min()); - SimdDouble xabs, x2, x4, t, t2, w, w2; - SimdDouble PolyAP0, PolyAP1, PolyAQ0, PolyAQ1; - SimdDouble PolyBP0, PolyBP1, PolyBQ0, PolyBQ1; - SimdDouble PolyCP0, PolyCP1, PolyCQ0, PolyCQ1; - SimdDouble res_erf, res_erfcB, res_erfcC, res_erfc, res; - SimdDouble expmx2; - SimdDBool mask, mask_erf, notmask_erf; + SimdDouble xabs, x2, x4, t, t2, w, w2; + SimdDouble PolyAP0, PolyAP1, PolyAQ0, PolyAQ1; + SimdDouble PolyBP0, PolyBP1, PolyBQ0, PolyBQ1; + SimdDouble PolyCP0, PolyCP1, PolyCQ0, PolyCQ1; + SimdDouble res_erf, res_erfcB, res_erfcC, res_erfc, res; + SimdDouble expmx2; + SimdDBool mask, mask_erf, notmask_erf; // Calculate erf() xabs = abs(x); @@ -2532,31 +2488,31 @@ erf(SimdDouble x) x2 = x * x; x4 = x2 * x2; - PolyAP0 = fma(CAP4, x4, CAP2); - PolyAP1 = fma(CAP3, x4, CAP1); - PolyAP0 = fma(PolyAP0, x4, CAP0); - PolyAP0 = fma(PolyAP1, x2, PolyAP0); + PolyAP0 = fma(CAP4, x4, CAP2); + PolyAP1 = fma(CAP3, x4, CAP1); + PolyAP0 = fma(PolyAP0, x4, CAP0); + PolyAP0 = fma(PolyAP1, x2, PolyAP0); - PolyAQ1 = fma(CAQ5, x4, CAQ3); - PolyAQ0 = fma(CAQ4, x4, CAQ2); - PolyAQ1 = fma(PolyAQ1, x4, CAQ1); - PolyAQ0 = fma(PolyAQ0, x4, one); - PolyAQ0 = fma(PolyAQ1, x2, PolyAQ0); + PolyAQ1 = fma(CAQ5, x4, CAQ3); + PolyAQ0 = fma(CAQ4, x4, CAQ2); + PolyAQ1 = fma(PolyAQ1, x4, CAQ1); + PolyAQ0 = fma(PolyAQ0, x4, one); + PolyAQ0 = fma(PolyAQ1, x2, PolyAQ0); - res_erf = PolyAP0 * maskzInv(PolyAQ0, mask_erf && (minFloat <= abs(PolyAQ0) ) ); - res_erf = CAoffset + res_erf; - res_erf = x * res_erf; + res_erf = PolyAP0 * maskzInv(PolyAQ0, mask_erf && (minFloat <= abs(PolyAQ0))); + res_erf = CAoffset + res_erf; + res_erf = x * res_erf; // Calculate erfc() in range [1,4.5] - t = xabs - one; - t2 = t * t; + t = xabs - one; + t2 = t * t; - PolyBP0 = fma(CBP6, t2, CBP4); - PolyBP1 = fma(CBP5, t2, CBP3); - PolyBP0 = fma(PolyBP0, t2, CBP2); - PolyBP1 = fma(PolyBP1, t2, CBP1); - PolyBP0 = fma(PolyBP0, t2, CBP0); - PolyBP0 = fma(PolyBP1, t, PolyBP0); + PolyBP0 = fma(CBP6, t2, CBP4); + PolyBP1 = fma(CBP5, t2, CBP3); + PolyBP0 = fma(PolyBP0, t2, CBP2); + PolyBP1 = fma(PolyBP1, t2, CBP1); + PolyBP0 = fma(PolyBP0, t2, CBP0); + PolyBP0 = fma(PolyBP1, t, PolyBP0); PolyBQ1 = fma(CBQ7, t2, CBQ5); PolyBQ0 = fma(CBQ6, t2, CBQ4); @@ -2567,32 +2523,32 @@ erf(SimdDouble x) PolyBQ0 = fma(PolyBQ1, t, PolyBQ0); // The denominator polynomial can be zero outside the range - res_erfcB = PolyBP0 * maskzInv(PolyBQ0, notmask_erf && (minFloat <= abs(PolyBQ0) ) ); + res_erfcB = PolyBP0 * maskzInv(PolyBQ0, notmask_erf && (minFloat <= abs(PolyBQ0))); res_erfcB = res_erfcB * xabs; // Calculate erfc() in range [4.5,inf] - w = maskzInv(xabs, notmask_erf && (minFloat <= xabs) ); - w2 = w * w; + w = maskzInv(xabs, notmask_erf && (minFloat <= xabs)); + w2 = w * w; - PolyCP0 = fma(CCP6, w2, CCP4); - PolyCP1 = fma(CCP5, w2, CCP3); - PolyCP0 = fma(PolyCP0, w2, CCP2); - PolyCP1 = fma(PolyCP1, w2, CCP1); - PolyCP0 = fma(PolyCP0, w2, CCP0); - PolyCP0 = fma(PolyCP1, w, PolyCP0); + PolyCP0 = fma(CCP6, w2, CCP4); + PolyCP1 = fma(CCP5, w2, CCP3); + PolyCP0 = fma(PolyCP0, w2, CCP2); + PolyCP1 = fma(PolyCP1, w2, CCP1); + PolyCP0 = fma(PolyCP0, w2, CCP0); + PolyCP0 = fma(PolyCP1, w, PolyCP0); - PolyCQ0 = fma(CCQ6, w2, CCQ4); - PolyCQ1 = fma(CCQ5, w2, CCQ3); - PolyCQ0 = fma(PolyCQ0, w2, CCQ2); - PolyCQ1 = fma(PolyCQ1, w2, CCQ1); - PolyCQ0 = fma(PolyCQ0, w2, one); - PolyCQ0 = fma(PolyCQ1, w, PolyCQ0); + PolyCQ0 = fma(CCQ6, w2, CCQ4); + PolyCQ1 = fma(CCQ5, w2, CCQ3); + PolyCQ0 = fma(PolyCQ0, w2, CCQ2); + PolyCQ1 = fma(PolyCQ1, w2, CCQ1); + PolyCQ0 = fma(PolyCQ0, w2, one); + PolyCQ0 = fma(PolyCQ1, w, PolyCQ0); - expmx2 = exp( -x2 ); + expmx2 = exp(-x2); // The denominator polynomial can be zero outside the range - res_erfcC = PolyCP0 * maskzInv(PolyCQ0, notmask_erf && (minFloat <= abs(PolyCQ0) ) ); + res_erfcC = PolyCP0 * maskzInv(PolyCQ0, notmask_erf && (minFloat <= abs(PolyCQ0))); res_erfcC = res_erfcC + CCoffset; res_erfcC = res_erfcC * w; @@ -2606,7 +2562,7 @@ erf(SimdDouble x) res_erfc = blend(res_erfc, two - res_erfc, mask); // Select erf() or erfc() - res = blend(one - res_erfc, res_erf, mask_erf); + res = blend(one - res_erfc, res_erf, mask_erf); return res; } @@ -2622,8 +2578,7 @@ erf(SimdDouble x) * (think results that are in the ballpark of 10^-200 for double) * since that is not relevant for MD. */ -static inline SimdDouble gmx_simdcall -erfc(SimdDouble x) +static inline SimdDouble gmx_simdcall erfc(SimdDouble x) { // Coefficients for minimax approximation of erf(x)=x*(CAoffset + P(x^2)/Q(x^2)) in range [-0.75,0.75] const SimdDouble CAP4(-0.431780540597889301512e-4); @@ -2679,13 +2634,13 @@ erfc(SimdDouble x) const SimdDouble two(2.0); const SimdDouble minFloat(std::numeric_limits::min()); - SimdDouble xabs, x2, x4, t, t2, w, w2; - SimdDouble PolyAP0, PolyAP1, PolyAQ0, PolyAQ1; - SimdDouble PolyBP0, PolyBP1, PolyBQ0, PolyBQ1; - SimdDouble PolyCP0, PolyCP1, PolyCQ0, PolyCQ1; - SimdDouble res_erf, res_erfcB, res_erfcC, res_erfc, res; - SimdDouble expmx2; - SimdDBool mask, mask_erf, notmask_erf; + SimdDouble xabs, x2, x4, t, t2, w, w2; + SimdDouble PolyAP0, PolyAP1, PolyAQ0, PolyAQ1; + SimdDouble PolyBP0, PolyBP1, PolyBQ0, PolyBQ1; + SimdDouble PolyCP0, PolyCP1, PolyCQ0, PolyCQ1; + SimdDouble res_erf, res_erfcB, res_erfcC, res_erfc, res; + SimdDouble expmx2; + SimdDBool mask, mask_erf, notmask_erf; // Calculate erf() xabs = abs(x); @@ -2694,30 +2649,30 @@ erfc(SimdDouble x) x2 = x * x; x4 = x2 * x2; - PolyAP0 = fma(CAP4, x4, CAP2); - PolyAP1 = fma(CAP3, x4, CAP1); - PolyAP0 = fma(PolyAP0, x4, CAP0); - PolyAP0 = fma(PolyAP1, x2, PolyAP0); - PolyAQ1 = fma(CAQ5, x4, CAQ3); - PolyAQ0 = fma(CAQ4, x4, CAQ2); - PolyAQ1 = fma(PolyAQ1, x4, CAQ1); - PolyAQ0 = fma(PolyAQ0, x4, one); - PolyAQ0 = fma(PolyAQ1, x2, PolyAQ0); + PolyAP0 = fma(CAP4, x4, CAP2); + PolyAP1 = fma(CAP3, x4, CAP1); + PolyAP0 = fma(PolyAP0, x4, CAP0); + PolyAP0 = fma(PolyAP1, x2, PolyAP0); + PolyAQ1 = fma(CAQ5, x4, CAQ3); + PolyAQ0 = fma(CAQ4, x4, CAQ2); + PolyAQ1 = fma(PolyAQ1, x4, CAQ1); + PolyAQ0 = fma(PolyAQ0, x4, one); + PolyAQ0 = fma(PolyAQ1, x2, PolyAQ0); - res_erf = PolyAP0 * maskzInv(PolyAQ0, mask_erf && (minFloat <= abs(PolyAQ0) ) ); - res_erf = CAoffset + res_erf; - res_erf = x * res_erf; + res_erf = PolyAP0 * maskzInv(PolyAQ0, mask_erf && (minFloat <= abs(PolyAQ0))); + res_erf = CAoffset + res_erf; + res_erf = x * res_erf; // Calculate erfc() in range [1,4.5] - t = xabs - one; - t2 = t * t; + t = xabs - one; + t2 = t * t; - PolyBP0 = fma(CBP6, t2, CBP4); - PolyBP1 = fma(CBP5, t2, CBP3); - PolyBP0 = fma(PolyBP0, t2, CBP2); - PolyBP1 = fma(PolyBP1, t2, CBP1); - PolyBP0 = fma(PolyBP0, t2, CBP0); - PolyBP0 = fma(PolyBP1, t, PolyBP0); + PolyBP0 = fma(CBP6, t2, CBP4); + PolyBP1 = fma(CBP5, t2, CBP3); + PolyBP0 = fma(PolyBP0, t2, CBP2); + PolyBP1 = fma(PolyBP1, t2, CBP1); + PolyBP0 = fma(PolyBP0, t2, CBP0); + PolyBP0 = fma(PolyBP1, t, PolyBP0); PolyBQ1 = fma(CBQ7, t2, CBQ5); PolyBQ0 = fma(CBQ6, t2, CBQ4); @@ -2728,33 +2683,33 @@ erfc(SimdDouble x) PolyBQ0 = fma(PolyBQ1, t, PolyBQ0); // The denominator polynomial can be zero outside the range - res_erfcB = PolyBP0 * maskzInv(PolyBQ0, notmask_erf && (minFloat <= abs(PolyBQ0) ) ); + res_erfcB = PolyBP0 * maskzInv(PolyBQ0, notmask_erf && (minFloat <= abs(PolyBQ0))); res_erfcB = res_erfcB * xabs; // Calculate erfc() in range [4.5,inf] // Note that 1/x can only handle single precision! - w = maskzInv(xabs, minFloat <= xabs ); - w2 = w * w; + w = maskzInv(xabs, minFloat <= xabs); + w2 = w * w; - PolyCP0 = fma(CCP6, w2, CCP4); - PolyCP1 = fma(CCP5, w2, CCP3); - PolyCP0 = fma(PolyCP0, w2, CCP2); - PolyCP1 = fma(PolyCP1, w2, CCP1); - PolyCP0 = fma(PolyCP0, w2, CCP0); - PolyCP0 = fma(PolyCP1, w, PolyCP0); + PolyCP0 = fma(CCP6, w2, CCP4); + PolyCP1 = fma(CCP5, w2, CCP3); + PolyCP0 = fma(PolyCP0, w2, CCP2); + PolyCP1 = fma(PolyCP1, w2, CCP1); + PolyCP0 = fma(PolyCP0, w2, CCP0); + PolyCP0 = fma(PolyCP1, w, PolyCP0); - PolyCQ0 = fma(CCQ6, w2, CCQ4); - PolyCQ1 = fma(CCQ5, w2, CCQ3); - PolyCQ0 = fma(PolyCQ0, w2, CCQ2); - PolyCQ1 = fma(PolyCQ1, w2, CCQ1); - PolyCQ0 = fma(PolyCQ0, w2, one); - PolyCQ0 = fma(PolyCQ1, w, PolyCQ0); + PolyCQ0 = fma(CCQ6, w2, CCQ4); + PolyCQ1 = fma(CCQ5, w2, CCQ3); + PolyCQ0 = fma(PolyCQ0, w2, CCQ2); + PolyCQ1 = fma(PolyCQ1, w2, CCQ1); + PolyCQ0 = fma(PolyCQ0, w2, one); + PolyCQ0 = fma(PolyCQ1, w, PolyCQ0); - expmx2 = exp( -x2 ); + expmx2 = exp(-x2); // The denominator polynomial can be zero outside the range - res_erfcC = PolyCP0 * maskzInv(PolyCQ0, notmask_erf && (minFloat <= abs(PolyCQ0) ) ); + res_erfcC = PolyCP0 * maskzInv(PolyCQ0, notmask_erf && (minFloat <= abs(PolyCQ0))); res_erfcC = res_erfcC + CCoffset; res_erfcC = res_erfcC * w; @@ -2768,7 +2723,7 @@ erfc(SimdDouble x) res_erfc = blend(res_erfc, two - res_erfc, mask); // Select erf() or erfc() - res = blend(res_erfc, one - res_erf, mask_erf); + res = blend(res_erfc, one - res_erf, mask_erf); return res; } @@ -2783,50 +2738,49 @@ erfc(SimdDouble x) * magnitudes of the argument we inherently begin to lose accuracy due to the * argument reduction, despite using extended precision arithmetics internally. */ -static inline void gmx_simdcall -sincos(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) +static inline void gmx_simdcall sincos(SimdDouble x, SimdDouble* sinval, SimdDouble* cosval) { // Constants to subtract Pi/4*x from y while minimizing precision loss - const SimdDouble argred0(-2*0.78539816290140151978); - const SimdDouble argred1(-2*4.9604678871439933374e-10); - const SimdDouble argred2(-2*1.1258708853173288931e-18); - const SimdDouble argred3(-2*1.7607799325916000908e-27); - const SimdDouble two_over_pi(2.0/M_PI); - const SimdDouble const_sin5( 1.58938307283228937328511e-10); - const SimdDouble const_sin4(-2.50506943502539773349318e-08); - const SimdDouble const_sin3( 2.75573131776846360512547e-06); - const SimdDouble const_sin2(-0.000198412698278911770864914); - const SimdDouble const_sin1( 0.0083333333333191845961746); - const SimdDouble const_sin0(-0.166666666666666130709393); - - const SimdDouble const_cos7(-1.13615350239097429531523e-11); - const SimdDouble const_cos6( 2.08757471207040055479366e-09); - const SimdDouble const_cos5(-2.75573144028847567498567e-07); - const SimdDouble const_cos4( 2.48015872890001867311915e-05); - const SimdDouble const_cos3(-0.00138888888888714019282329); - const SimdDouble const_cos2( 0.0416666666666665519592062); - const SimdDouble half(0.5); - const SimdDouble one(1.0); - SimdDouble ssign, csign; - SimdDouble x2, y, z, psin, pcos, sss, ccc; - SimdDBool mask; -#if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL - const SimdDInt32 ione(1); - const SimdDInt32 itwo(2); - SimdDInt32 iy; - - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - - mask = cvtIB2B((iy & ione) == setZero()); - ssign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B((iy & itwo) == itwo)); - csign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B(((iy + ione) & itwo) == itwo)); -#else - const SimdDouble quarter(0.25); - const SimdDouble minusquarter(-0.25); - SimdDouble q; - SimdDBool m1, m2, m3; + const SimdDouble argred0(-2 * 0.78539816290140151978); + const SimdDouble argred1(-2 * 4.9604678871439933374e-10); + const SimdDouble argred2(-2 * 1.1258708853173288931e-18); + const SimdDouble argred3(-2 * 1.7607799325916000908e-27); + const SimdDouble two_over_pi(2.0 / M_PI); + const SimdDouble const_sin5(1.58938307283228937328511e-10); + const SimdDouble const_sin4(-2.50506943502539773349318e-08); + const SimdDouble const_sin3(2.75573131776846360512547e-06); + const SimdDouble const_sin2(-0.000198412698278911770864914); + const SimdDouble const_sin1(0.0083333333333191845961746); + const SimdDouble const_sin0(-0.166666666666666130709393); + + const SimdDouble const_cos7(-1.13615350239097429531523e-11); + const SimdDouble const_cos6(2.08757471207040055479366e-09); + const SimdDouble const_cos5(-2.75573144028847567498567e-07); + const SimdDouble const_cos4(2.48015872890001867311915e-05); + const SimdDouble const_cos3(-0.00138888888888714019282329); + const SimdDouble const_cos2(0.0416666666666665519592062); + const SimdDouble half(0.5); + const SimdDouble one(1.0); + SimdDouble ssign, csign; + SimdDouble x2, y, z, psin, pcos, sss, ccc; + SimdDBool mask; +# if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + const SimdDInt32 ione(1); + const SimdDInt32 itwo(2); + SimdDInt32 iy; + + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + + mask = cvtIB2B((iy & ione) == setZero()); + ssign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B((iy & itwo) == itwo)); + csign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B(((iy + ione) & itwo) == itwo)); +# else + const SimdDouble quarter(0.25); + const SimdDouble minusquarter(-0.25); + SimdDouble q; + SimdDBool m1, m2, m3; /* The most obvious way to find the arguments quadrant in the unit circle * to calculate the sign is to use integer arithmetic, but that is not @@ -2837,75 +2791,75 @@ sincos(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) * slightly slower (~10%) due to the longer latencies of floating-point, so * we only use it when integer SIMD arithmetic is not present. */ - ssign = x; - x = abs(x); + ssign = x; + x = abs(x); // It is critical that half-way cases are rounded down - z = fma(x, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); + z = fma(x, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); /* z now starts at 0.0 for x=-pi/4 (although neg. values cannot occur), and * then increased by 1.0 as x increases by 2*Pi, when it resets to 0.0. * This removes the 2*Pi periodicity without using any integer arithmetic. * First check if y had the value 2 or 3, set csign if true. */ - q = q - half; + q = q - half; /* If we have logical operations we can work directly on the signbit, which * saves instructions. Otherwise we need to represent signs as +1.0/-1.0. * Thus, if you are altering defines to debug alternative code paths, the * two GMX_SIMD_HAVE_LOGICAL sections in this routine must either both be * active or inactive - you will get errors if only one is used. */ -# if GMX_SIMD_HAVE_LOGICAL - ssign = ssign & SimdDouble(GMX_DOUBLE_NEGZERO); - csign = andNot(q, SimdDouble(GMX_DOUBLE_NEGZERO)); - ssign = ssign ^ csign; -# else - ssign = copysign(SimdDouble(1.0), ssign); - csign = copysign(SimdDouble(1.0), q); - csign = -csign; - ssign = ssign * csign; // swap ssign if csign was set. -# endif +# if GMX_SIMD_HAVE_LOGICAL + ssign = ssign & SimdDouble(GMX_DOUBLE_NEGZERO); + csign = andNot(q, SimdDouble(GMX_DOUBLE_NEGZERO)); + ssign = ssign ^ csign; +# else + ssign = copysign(SimdDouble(1.0), ssign); + csign = copysign(SimdDouble(1.0), q); + csign = -csign; + ssign = ssign * csign; // swap ssign if csign was set. +# endif // Check if y had value 1 or 3 (remember we subtracted 0.5 from q) - m1 = (q < minusquarter); - m2 = (setZero() <= q); - m3 = (q < quarter); - m2 = m2 && m3; - mask = m1 || m2; + m1 = (q < minusquarter); + m2 = (setZero() <= q); + m3 = (q < quarter); + m2 = m2 && m3; + mask = m1 || m2; // where mask is FALSE, swap sign. csign = csign * blend(SimdDouble(-1.0), one, mask); -#endif - x = fma(y, argred0, x); - x = fma(y, argred1, x); - x = fma(y, argred2, x); - x = fma(y, argred3, x); - x2 = x * x; - - psin = fma(const_sin5, x2, const_sin4); - psin = fma(psin, x2, const_sin3); - psin = fma(psin, x2, const_sin2); - psin = fma(psin, x2, const_sin1); - psin = fma(psin, x2, const_sin0); - psin = fma(psin, x2 * x, x); - - pcos = fma(const_cos7, x2, const_cos6); - pcos = fma(pcos, x2, const_cos5); - pcos = fma(pcos, x2, const_cos4); - pcos = fma(pcos, x2, const_cos3); - pcos = fma(pcos, x2, const_cos2); - pcos = fms(pcos, x2, half); - pcos = fma(pcos, x2, one); - - sss = blend(pcos, psin, mask); - ccc = blend(psin, pcos, mask); +# endif + x = fma(y, argred0, x); + x = fma(y, argred1, x); + x = fma(y, argred2, x); + x = fma(y, argred3, x); + x2 = x * x; + + psin = fma(const_sin5, x2, const_sin4); + psin = fma(psin, x2, const_sin3); + psin = fma(psin, x2, const_sin2); + psin = fma(psin, x2, const_sin1); + psin = fma(psin, x2, const_sin0); + psin = fma(psin, x2 * x, x); + + pcos = fma(const_cos7, x2, const_cos6); + pcos = fma(pcos, x2, const_cos5); + pcos = fma(pcos, x2, const_cos4); + pcos = fma(pcos, x2, const_cos3); + pcos = fma(pcos, x2, const_cos2); + pcos = fms(pcos, x2, half); + pcos = fma(pcos, x2, one); + + sss = blend(pcos, psin, mask); + ccc = blend(psin, pcos, mask); // See comment for GMX_SIMD_HAVE_LOGICAL section above. -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL *sinval = sss ^ ssign; *cosval = ccc ^ csign; -#else +# else *sinval = sss * ssign; *cosval = ccc * csign; -#endif +# endif } /*! \brief SIMD double sin(x). @@ -2916,8 +2870,7 @@ sincos(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdDouble gmx_simdcall -sin(SimdDouble x) +static inline SimdDouble gmx_simdcall sin(SimdDouble x) { SimdDouble s, c; sincos(x, &s, &c); @@ -2932,8 +2885,7 @@ sin(SimdDouble x) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdDouble gmx_simdcall -cos(SimdDouble x) +static inline SimdDouble gmx_simdcall cos(SimdDouble x) { SimdDouble s, c; sincos(x, &s, &c); @@ -2945,92 +2897,91 @@ cos(SimdDouble x) * \param x The argument to evaluate tan for * \result Tan(x) */ -static inline SimdDouble gmx_simdcall -tan(SimdDouble x) +static inline SimdDouble gmx_simdcall tan(SimdDouble x) { - const SimdDouble argred0(-2*0.78539816290140151978); - const SimdDouble argred1(-2*4.9604678871439933374e-10); - const SimdDouble argred2(-2*1.1258708853173288931e-18); - const SimdDouble argred3(-2*1.7607799325916000908e-27); - const SimdDouble two_over_pi(2.0/M_PI); - const SimdDouble CT15(1.01419718511083373224408e-05); - const SimdDouble CT14(-2.59519791585924697698614e-05); - const SimdDouble CT13(5.23388081915899855325186e-05); - const SimdDouble CT12(-3.05033014433946488225616e-05); - const SimdDouble CT11(7.14707504084242744267497e-05); - const SimdDouble CT10(8.09674518280159187045078e-05); - const SimdDouble CT9(0.000244884931879331847054404); - const SimdDouble CT8(0.000588505168743587154904506); - const SimdDouble CT7(0.00145612788922812427978848); - const SimdDouble CT6(0.00359208743836906619142924); - const SimdDouble CT5(0.00886323944362401618113356); - const SimdDouble CT4(0.0218694882853846389592078); - const SimdDouble CT3(0.0539682539781298417636002); - const SimdDouble CT2(0.133333333333125941821962); - const SimdDouble CT1(0.333333333333334980164153); - const SimdDouble minFloat(std::numeric_limits::min()); - - SimdDouble x2, p, y, z; - SimdDBool m; - -#if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL - SimdDInt32 iy; - SimdDInt32 ione(1); - - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - m = cvtIB2B((iy & ione) == ione); - - x = fma(y, argred0, x); - x = fma(y, argred1, x); - x = fma(y, argred2, x); - x = fma(y, argred3, x); - x = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), m) ^ x; -#else - const SimdDouble quarter(0.25); - const SimdDouble half(0.5); - const SimdDouble threequarter(0.75); - const SimdDouble minFloat(std::numeric_limits::min()); - SimdDouble w, q; - SimdDBool m1, m2, m3; - - w = abs(x); - z = fma(w, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); - m1 = (quarter <= q); - m2 = (q < half); - m3 = (threequarter <= q); - m1 = m1 && m2; - m = m1 || m3; - w = fma(y, argred0, w); - w = fma(y, argred1, w); - w = fma(y, argred2, w); - w = fma(y, argred3, w); - - w = blend(w, -w, m); - x = w * copysign( SimdDouble(1.0), x ); -#endif - x2 = x * x; - p = fma(CT15, x2, CT14); - p = fma(p, x2, CT13); - p = fma(p, x2, CT12); - p = fma(p, x2, CT11); - p = fma(p, x2, CT10); - p = fma(p, x2, CT9); - p = fma(p, x2, CT8); - p = fma(p, x2, CT7); - p = fma(p, x2, CT6); - p = fma(p, x2, CT5); - p = fma(p, x2, CT4); - p = fma(p, x2, CT3); - p = fma(p, x2, CT2); - p = fma(p, x2, CT1); - p = fma(x2, p * x, x); - - p = blend( p, maskzInv(p, m && (minFloat < abs(p) ) ), m); + const SimdDouble argred0(-2 * 0.78539816290140151978); + const SimdDouble argred1(-2 * 4.9604678871439933374e-10); + const SimdDouble argred2(-2 * 1.1258708853173288931e-18); + const SimdDouble argred3(-2 * 1.7607799325916000908e-27); + const SimdDouble two_over_pi(2.0 / M_PI); + const SimdDouble CT15(1.01419718511083373224408e-05); + const SimdDouble CT14(-2.59519791585924697698614e-05); + const SimdDouble CT13(5.23388081915899855325186e-05); + const SimdDouble CT12(-3.05033014433946488225616e-05); + const SimdDouble CT11(7.14707504084242744267497e-05); + const SimdDouble CT10(8.09674518280159187045078e-05); + const SimdDouble CT9(0.000244884931879331847054404); + const SimdDouble CT8(0.000588505168743587154904506); + const SimdDouble CT7(0.00145612788922812427978848); + const SimdDouble CT6(0.00359208743836906619142924); + const SimdDouble CT5(0.00886323944362401618113356); + const SimdDouble CT4(0.0218694882853846389592078); + const SimdDouble CT3(0.0539682539781298417636002); + const SimdDouble CT2(0.133333333333125941821962); + const SimdDouble CT1(0.333333333333334980164153); + const SimdDouble minFloat(std::numeric_limits::min()); + + SimdDouble x2, p, y, z; + SimdDBool m; + +# if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + SimdDInt32 iy; + SimdDInt32 ione(1); + + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + m = cvtIB2B((iy & ione) == ione); + + x = fma(y, argred0, x); + x = fma(y, argred1, x); + x = fma(y, argred2, x); + x = fma(y, argred3, x); + x = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), m) ^ x; +# else + const SimdDouble quarter(0.25); + const SimdDouble half(0.5); + const SimdDouble threequarter(0.75); + const SimdDouble minFloat(std::numeric_limits::min()); + SimdDouble w, q; + SimdDBool m1, m2, m3; + + w = abs(x); + z = fma(w, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); + m1 = (quarter <= q); + m2 = (q < half); + m3 = (threequarter <= q); + m1 = m1 && m2; + m = m1 || m3; + w = fma(y, argred0, w); + w = fma(y, argred1, w); + w = fma(y, argred2, w); + w = fma(y, argred3, w); + + w = blend(w, -w, m); + x = w * copysign(SimdDouble(1.0), x); +# endif + x2 = x * x; + p = fma(CT15, x2, CT14); + p = fma(p, x2, CT13); + p = fma(p, x2, CT12); + p = fma(p, x2, CT11); + p = fma(p, x2, CT10); + p = fma(p, x2, CT9); + p = fma(p, x2, CT8); + p = fma(p, x2, CT7); + p = fma(p, x2, CT6); + p = fma(p, x2, CT5); + p = fma(p, x2, CT4); + p = fma(p, x2, CT3); + p = fma(p, x2, CT2); + p = fma(p, x2, CT1); + p = fma(x2, p * x, x); + + p = blend(p, maskzInv(p, m && (minFloat < abs(p))), m); return p; } @@ -3039,14 +2990,13 @@ tan(SimdDouble x) * \param x The argument to evaluate asin for * \result Asin(x) */ -static inline SimdDouble gmx_simdcall -asin(SimdDouble x) +static inline SimdDouble gmx_simdcall asin(SimdDouble x) { // Same algorithm as cephes library const SimdDouble limit1(0.625); const SimdDouble limit2(1e-8); const SimdDouble one(1.0); - const SimdDouble quarterpi(M_PI/4.0); + const SimdDouble quarterpi(M_PI / 4.0); const SimdDouble morebits(6.123233995736765886130e-17); const SimdDouble P5(4.253011369004428248960e-3); @@ -3073,72 +3023,72 @@ asin(SimdDouble x) const SimdDouble S1(-3.838770957603691357202e2); const SimdDouble S0(3.424398657913078477438e2); - SimdDouble xabs; - SimdDouble zz, ww, z, q, w, zz2, ww2; - SimdDouble PA, PB; - SimdDouble QA, QB; - SimdDouble RA, RB; - SimdDouble SA, SB; - SimdDouble nom, denom; - SimdDBool mask, mask2; + SimdDouble xabs; + SimdDouble zz, ww, z, q, w, zz2, ww2; + SimdDouble PA, PB; + SimdDouble QA, QB; + SimdDouble RA, RB; + SimdDouble SA, SB; + SimdDouble nom, denom; + SimdDBool mask, mask2; - xabs = abs(x); + xabs = abs(x); - mask = (limit1 < xabs); + mask = (limit1 < xabs); - zz = one - xabs; - ww = xabs * xabs; - zz2 = zz * zz; - ww2 = ww * ww; + zz = one - xabs; + ww = xabs * xabs; + zz2 = zz * zz; + ww2 = ww * ww; // R - RA = fma(R4, zz2, R2); - RB = fma(R3, zz2, R1); - RA = fma(RA, zz2, R0); - RA = fma(RB, zz, RA); + RA = fma(R4, zz2, R2); + RB = fma(R3, zz2, R1); + RA = fma(RA, zz2, R0); + RA = fma(RB, zz, RA); // S, SA = zz2 - SB = fma(S3, zz2, S1); - SA = zz2 + S2; - SA = fma(SA, zz2, S0); - SA = fma(SB, zz, SA); + SB = fma(S3, zz2, S1); + SA = zz2 + S2; + SA = fma(SA, zz2, S0); + SA = fma(SB, zz, SA); // P - PA = fma(P5, ww2, P3); - PB = fma(P4, ww2, P2); - PA = fma(PA, ww2, P1); - PB = fma(PB, ww2, P0); - PA = fma(PA, ww, PB); + PA = fma(P5, ww2, P3); + PB = fma(P4, ww2, P2); + PA = fma(PA, ww2, P1); + PB = fma(PB, ww2, P0); + PA = fma(PA, ww, PB); // Q, QA = ww2 - QB = fma(Q4, ww2, Q2); - QA = ww2 + Q3; - QA = fma(QA, ww2, Q1); - QB = fma(QB, ww2, Q0); - QA = fma(QA, ww, QB); + QB = fma(Q4, ww2, Q2); + QA = ww2 + Q3; + QA = fma(QA, ww2, Q1); + QB = fma(QB, ww2, Q0); + QA = fma(QA, ww, QB); - RA = RA * zz; - PA = PA * ww; + RA = RA * zz; + PA = PA * ww; - nom = blend( PA, RA, mask ); - denom = blend( QA, SA, mask ); + nom = blend(PA, RA, mask); + denom = blend(QA, SA, mask); mask2 = (limit2 < xabs); q = nom * maskzInv(denom, mask2); - zz = zz + zz; - zz = sqrt(zz); - z = quarterpi - zz; - zz = fms(zz, q, morebits); - z = z - zz; - z = z + quarterpi; + zz = zz + zz; + zz = sqrt(zz); + z = quarterpi - zz; + zz = fms(zz, q, morebits); + z = z - zz; + z = z + quarterpi; - w = xabs * q; - w = w + xabs; + w = xabs * q; + w = w + xabs; - z = blend( w, z, mask ); + z = blend(w, z, mask); - z = blend( xabs, z, mask2 ); + z = blend(xabs, z, mask2); z = copysign(z, x); @@ -3150,31 +3100,30 @@ asin(SimdDouble x) * \param x The argument to evaluate acos for * \result Acos(x) */ -static inline SimdDouble gmx_simdcall -acos(SimdDouble x) +static inline SimdDouble gmx_simdcall acos(SimdDouble x) { const SimdDouble one(1.0); const SimdDouble half(0.5); const SimdDouble quarterpi0(7.85398163397448309616e-1); const SimdDouble quarterpi1(6.123233995736765886130e-17); - SimdDBool mask1; - SimdDouble z, z1, z2; + SimdDBool mask1; + SimdDouble z, z1, z2; mask1 = (half < x); z1 = half * (one - x); z1 = sqrt(z1); - z = blend( x, z1, mask1 ); + z = blend(x, z1, mask1); - z = asin(z); + z = asin(z); - z1 = z + z; + z1 = z + z; - z2 = quarterpi0 - z; - z2 = z2 + quarterpi1; - z2 = z2 + quarterpi0; + z2 = quarterpi0 - z; + z2 = z2 + quarterpi1; + z2 = z2 + quarterpi0; - z = blend(z2, z1, mask1); + z = blend(z2, z1, mask1); return z; } @@ -3184,16 +3133,15 @@ acos(SimdDouble x) * \param x The argument to evaluate atan for * \result Atan(x), same argument/value range as standard math library. */ -static inline SimdDouble gmx_simdcall -atan(SimdDouble x) +static inline SimdDouble gmx_simdcall atan(SimdDouble x) { // Same algorithm as cephes library const SimdDouble limit1(0.66); const SimdDouble limit2(2.41421356237309504880); - const SimdDouble quarterpi(M_PI/4.0); - const SimdDouble halfpi(M_PI/2.0); + const SimdDouble quarterpi(M_PI / 4.0); + const SimdDouble halfpi(M_PI / 2.0); const SimdDouble mone(-1.0); - const SimdDouble morebits1(0.5*6.123233995736765886130E-17); + const SimdDouble morebits1(0.5 * 6.123233995736765886130E-17); const SimdDouble morebits2(6.123233995736765886130E-17); const SimdDouble P4(-8.750608600031904122785E-1); @@ -3208,50 +3156,50 @@ atan(SimdDouble x) const SimdDouble Q1(4.853903996359136964868E2); const SimdDouble Q0(1.945506571482613964425E2); - SimdDouble y, xabs, t1, t2; - SimdDouble z, z2; - SimdDouble P_A, P_B, Q_A, Q_B; - SimdDBool mask1, mask2; + SimdDouble y, xabs, t1, t2; + SimdDouble z, z2; + SimdDouble P_A, P_B, Q_A, Q_B; + SimdDBool mask1, mask2; - xabs = abs(x); + xabs = abs(x); - mask1 = (limit1 < xabs); - mask2 = (limit2 < xabs); + mask1 = (limit1 < xabs); + mask2 = (limit2 < xabs); - t1 = (xabs + mone) * maskzInv(xabs - mone, mask1); - t2 = mone * maskzInv(xabs, mask2); + t1 = (xabs + mone) * maskzInv(xabs - mone, mask1); + t2 = mone * maskzInv(xabs, mask2); - y = selectByMask(quarterpi, mask1); - y = blend(y, halfpi, mask2); - xabs = blend(xabs, t1, mask1); - xabs = blend(xabs, t2, mask2); + y = selectByMask(quarterpi, mask1); + y = blend(y, halfpi, mask2); + xabs = blend(xabs, t1, mask1); + xabs = blend(xabs, t2, mask2); - z = xabs * xabs; - z2 = z * z; + z = xabs * xabs; + z2 = z * z; - P_A = fma(P4, z2, P2); - P_B = fma(P3, z2, P1); - P_A = fma(P_A, z2, P0); - P_A = fma(P_B, z, P_A); + P_A = fma(P4, z2, P2); + P_B = fma(P3, z2, P1); + P_A = fma(P_A, z2, P0); + P_A = fma(P_B, z, P_A); // Q_A = z2 - Q_B = fma(Q4, z2, Q2); - Q_A = z2 + Q3; - Q_A = fma(Q_A, z2, Q1); - Q_B = fma(Q_B, z2, Q0); - Q_A = fma(Q_A, z, Q_B); + Q_B = fma(Q4, z2, Q2); + Q_A = z2 + Q3; + Q_A = fma(Q_A, z2, Q1); + Q_B = fma(Q_B, z2, Q0); + Q_A = fma(Q_A, z, Q_B); - z = z * P_A; - z = z * inv(Q_A); - z = fma(z, xabs, xabs); + z = z * P_A; + z = z * inv(Q_A); + z = fma(z, xabs, xabs); - t1 = selectByMask(morebits1, mask1); - t1 = blend(t1, morebits2, mask2); + t1 = selectByMask(morebits1, mask1); + t1 = blend(t1, morebits2, mask2); - z = z + t1; - y = y + z; + z = z + t1; + y = y + z; - y = copysign(y, x); + y = copysign(y, x); return y; } @@ -3269,11 +3217,10 @@ atan(SimdDouble x) * of any concern in Gromacs, and in particular it will not affect calculations * of angles from vectors. */ -static inline SimdDouble gmx_simdcall -atan2(SimdDouble y, SimdDouble x) +static inline SimdDouble gmx_simdcall atan2(SimdDouble y, SimdDouble x) { const SimdDouble pi(M_PI); - const SimdDouble halfpi(M_PI/2.0); + const SimdDouble halfpi(M_PI / 2.0); const SimdDouble minFloat(std::numeric_limits::min()); SimdDouble xinv, p, aoffset; SimdDBool mask_xnz, mask_ynz, mask_xlt0, mask_ylt0; @@ -3283,16 +3230,16 @@ atan2(SimdDouble y, SimdDouble x) mask_xlt0 = (x < setZero()); mask_ylt0 = (y < setZero()); - aoffset = selectByNotMask(halfpi, mask_xnz); - aoffset = selectByMask(aoffset, mask_ynz); + aoffset = selectByNotMask(halfpi, mask_xnz); + aoffset = selectByMask(aoffset, mask_ynz); - aoffset = blend(aoffset, pi, mask_xlt0); - aoffset = blend(aoffset, -aoffset, mask_ylt0); + aoffset = blend(aoffset, pi, mask_xlt0); + aoffset = blend(aoffset, -aoffset, mask_ylt0); - xinv = maskzInv(x, mask_xnz && (minFloat <= abs(x) ) ); - p = y * xinv; - p = atan(p); - p = p + aoffset; + xinv = maskzInv(x, mask_xnz && (minFloat <= abs(x))); + p = y * xinv; + p = atan(p); + p = p + aoffset; return p; } @@ -3308,59 +3255,57 @@ atan2(SimdDouble y, SimdDouble x) * direct-space PME electrostatic force to avoid tables. For details, see the * single precision function. */ -static inline SimdDouble gmx_simdcall -pmeForceCorrection(SimdDouble z2) +static inline SimdDouble gmx_simdcall pmeForceCorrection(SimdDouble z2) { - const SimdDouble FN10(-8.0072854618360083154e-14); - const SimdDouble FN9(1.1859116242260148027e-11); - const SimdDouble FN8(-8.1490406329798423616e-10); - const SimdDouble FN7(3.4404793543907847655e-8); - const SimdDouble FN6(-9.9471420832602741006e-7); - const SimdDouble FN5(0.000020740315999115847456); - const SimdDouble FN4(-0.00031991745139313364005); - const SimdDouble FN3(0.0035074449373659008203); - const SimdDouble FN2(-0.031750380176100813405); - const SimdDouble FN1(0.13884101728898463426); - const SimdDouble FN0(-0.75225277815249618847); - - const SimdDouble FD5(0.000016009278224355026701); - const SimdDouble FD4(0.00051055686934806966046); - const SimdDouble FD3(0.0081803507497974289008); - const SimdDouble FD2(0.077181146026670287235); - const SimdDouble FD1(0.41543303143712535988); - const SimdDouble FD0(1.0); - - SimdDouble z4; - SimdDouble polyFN0, polyFN1, polyFD0, polyFD1; - - z4 = z2 * z2; - - polyFD1 = fma(FD5, z4, FD3); - polyFD1 = fma(polyFD1, z4, FD1); - polyFD1 = polyFD1 * z2; - polyFD0 = fma(FD4, z4, FD2); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = polyFD0 + polyFD1; - - polyFD0 = inv(polyFD0); - - polyFN0 = fma(FN10, z4, FN8); - polyFN0 = fma(polyFN0, z4, FN6); - polyFN0 = fma(polyFN0, z4, FN4); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN1 = fma(FN9, z4, FN7); - polyFN1 = fma(polyFN1, z4, FN5); - polyFN1 = fma(polyFN1, z4, FN3); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN1, z2, polyFN0); + const SimdDouble FN10(-8.0072854618360083154e-14); + const SimdDouble FN9(1.1859116242260148027e-11); + const SimdDouble FN8(-8.1490406329798423616e-10); + const SimdDouble FN7(3.4404793543907847655e-8); + const SimdDouble FN6(-9.9471420832602741006e-7); + const SimdDouble FN5(0.000020740315999115847456); + const SimdDouble FN4(-0.00031991745139313364005); + const SimdDouble FN3(0.0035074449373659008203); + const SimdDouble FN2(-0.031750380176100813405); + const SimdDouble FN1(0.13884101728898463426); + const SimdDouble FN0(-0.75225277815249618847); + + const SimdDouble FD5(0.000016009278224355026701); + const SimdDouble FD4(0.00051055686934806966046); + const SimdDouble FD3(0.0081803507497974289008); + const SimdDouble FD2(0.077181146026670287235); + const SimdDouble FD1(0.41543303143712535988); + const SimdDouble FD0(1.0); + + SimdDouble z4; + SimdDouble polyFN0, polyFN1, polyFD0, polyFD1; + + z4 = z2 * z2; + + polyFD1 = fma(FD5, z4, FD3); + polyFD1 = fma(polyFD1, z4, FD1); + polyFD1 = polyFD1 * z2; + polyFD0 = fma(FD4, z4, FD2); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = polyFD0 + polyFD1; + + polyFD0 = inv(polyFD0); + + polyFN0 = fma(FN10, z4, FN8); + polyFN0 = fma(polyFN0, z4, FN6); + polyFN0 = fma(polyFN0, z4, FN4); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN1 = fma(FN9, z4, FN7); + polyFN1 = fma(polyFN1, z4, FN5); + polyFN1 = fma(polyFN1, z4, FN3); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN1, z2, polyFN0); return polyFN0 * polyFD0; } - /*! \brief Calculate the potential correction due to PME analytically in SIMD double. * * \param z2 This should be the value \f$(r \beta)^2\f$, where r is your @@ -3371,49 +3316,48 @@ pmeForceCorrection(SimdDouble z2) * direct-space PME electrostatic potential to avoid tables. For details, see the * single precision function. */ -static inline SimdDouble gmx_simdcall -pmePotentialCorrection(SimdDouble z2) +static inline SimdDouble gmx_simdcall pmePotentialCorrection(SimdDouble z2) { - const SimdDouble VN9(-9.3723776169321855475e-13); - const SimdDouble VN8(1.2280156762674215741e-10); - const SimdDouble VN7(-7.3562157912251309487e-9); - const SimdDouble VN6(2.6215886208032517509e-7); - const SimdDouble VN5(-4.9532491651265819499e-6); - const SimdDouble VN4(0.00025907400778966060389); - const SimdDouble VN3(0.0010585044856156469792); - const SimdDouble VN2(0.045247661136833092885); - const SimdDouble VN1(0.11643931522926034421); - const SimdDouble VN0(1.1283791671726767970); - - const SimdDouble VD5(0.000021784709867336150342); - const SimdDouble VD4(0.00064293662010911388448); - const SimdDouble VD3(0.0096311444822588683504); - const SimdDouble VD2(0.085608012351550627051); - const SimdDouble VD1(0.43652499166614811084); - const SimdDouble VD0(1.0); - - SimdDouble z4; - SimdDouble polyVN0, polyVN1, polyVD0, polyVD1; - - z4 = z2 * z2; - - polyVD1 = fma(VD5, z4, VD3); - polyVD0 = fma(VD4, z4, VD2); - polyVD1 = fma(polyVD1, z4, VD1); - polyVD0 = fma(polyVD0, z4, VD0); - polyVD0 = fma(polyVD1, z2, polyVD0); - - polyVD0 = inv(polyVD0); - - polyVN1 = fma(VN9, z4, VN7); - polyVN0 = fma(VN8, z4, VN6); - polyVN1 = fma(polyVN1, z4, VN5); - polyVN0 = fma(polyVN0, z4, VN4); - polyVN1 = fma(polyVN1, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2, polyVN0); + const SimdDouble VN9(-9.3723776169321855475e-13); + const SimdDouble VN8(1.2280156762674215741e-10); + const SimdDouble VN7(-7.3562157912251309487e-9); + const SimdDouble VN6(2.6215886208032517509e-7); + const SimdDouble VN5(-4.9532491651265819499e-6); + const SimdDouble VN4(0.00025907400778966060389); + const SimdDouble VN3(0.0010585044856156469792); + const SimdDouble VN2(0.045247661136833092885); + const SimdDouble VN1(0.11643931522926034421); + const SimdDouble VN0(1.1283791671726767970); + + const SimdDouble VD5(0.000021784709867336150342); + const SimdDouble VD4(0.00064293662010911388448); + const SimdDouble VD3(0.0096311444822588683504); + const SimdDouble VD2(0.085608012351550627051); + const SimdDouble VD1(0.43652499166614811084); + const SimdDouble VD0(1.0); + + SimdDouble z4; + SimdDouble polyVN0, polyVN1, polyVD0, polyVD1; + + z4 = z2 * z2; + + polyVD1 = fma(VD5, z4, VD3); + polyVD0 = fma(VD4, z4, VD2); + polyVD1 = fma(polyVD1, z4, VD1); + polyVD0 = fma(polyVD0, z4, VD0); + polyVD0 = fma(polyVD1, z2, polyVD0); + + polyVD0 = inv(polyVD0); + + polyVN1 = fma(VN9, z4, VN7); + polyVN0 = fma(VN8, z4, VN6); + polyVN1 = fma(polyVN1, z4, VN5); + polyVN0 = fma(polyVN0, z4, VN4); + polyVN1 = fma(polyVN1, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2, polyVN0); return polyVN0 * polyVD0; } @@ -3453,19 +3397,18 @@ pmePotentialCorrection(SimdDouble z2) * * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline SimdDouble gmx_simdcall -invsqrtSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall invsqrtSingleAccuracy(SimdDouble x) { SimdDouble lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -3488,19 +3431,18 @@ invsqrtSingleAccuracy(SimdDouble x) * \return 1/sqrt(x). Result is undefined if your argument was invalid or * entry was not masked, and 0.0 for masked-out entries. */ -static inline SimdDouble -maskzInvsqrtSingleAccuracy(SimdDouble x, SimdDBool m) +static inline SimdDouble maskzInvsqrtSingleAccuracy(SimdDouble x, SimdDBool m) { SimdDouble lu = maskzRsqrt(x, m); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -3523,32 +3465,34 @@ maskzInvsqrtSingleAccuracy(SimdDouble x, SimdDBool m) * responsibility for checking falls on you - this routine does not * check arguments. */ -static inline void gmx_simdcall -invsqrtPairSingleAccuracy(SimdDouble x0, SimdDouble x1, - SimdDouble *out0, SimdDouble *out1) +static inline void gmx_simdcall invsqrtPairSingleAccuracy(SimdDouble x0, + SimdDouble x1, + SimdDouble* out0, + SimdDouble* out1) { -#if GMX_SIMD_HAVE_FLOAT && (GMX_SIMD_FLOAT_WIDTH == 2*GMX_SIMD_DOUBLE_WIDTH) && (GMX_SIMD_RSQRT_BITS < 22) +# if GMX_SIMD_HAVE_FLOAT && (GMX_SIMD_FLOAT_WIDTH == 2 * GMX_SIMD_DOUBLE_WIDTH) \ + && (GMX_SIMD_RSQRT_BITS < 22) SimdFloat xf = cvtDD2F(x0, x1); SimdFloat luf = rsqrt(xf); SimdDouble lu0, lu1; // Intermediate target is single - mantissa+1 bits -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) luf = rsqrtIter(luf, xf); -#endif +# endif cvtF2DD(luf, &lu0, &lu1); // We now have single-precision accuracy values in lu0/lu1 *out0 = lu0; *out1 = lu1; -#else +# else *out0 = invsqrtSingleAccuracy(x0); *out1 = invsqrtSingleAccuracy(x1); -#endif +# endif } /*! \brief Calculate 1/x for SIMD double, but in single accuracy. @@ -3564,19 +3508,18 @@ invsqrtPairSingleAccuracy(SimdDouble x0, SimdDouble x1, * * \return 1/x. Result is undefined if your argument was invalid. */ -static inline SimdDouble gmx_simdcall -invSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall invSingleAccuracy(SimdDouble x) { SimdDouble lu = rcp(x); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -3594,19 +3537,18 @@ invSingleAccuracy(SimdDouble x) * \param m Mask * \return 1/x for elements where m is true, or 0.0 for masked-out entries. */ -static inline SimdDouble gmx_simdcall -maskzInvSingleAccuracy(SimdDouble x, SimdDBool m) +static inline SimdDouble gmx_simdcall maskzInvSingleAccuracy(SimdDouble x, SimdDBool m) { SimdDouble lu = maskzRcp(x, m); -#if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RCP_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif -#if (GMX_SIMD_RCP_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RCP_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rcpIter(lu, x); -#endif +# endif return lu; } @@ -3615,14 +3557,13 @@ maskzInvSingleAccuracy(SimdDouble x, SimdDBool m) * * \copydetails sqrt(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -sqrtSingleAccuracy(SimdDouble x) +template +static inline SimdDouble gmx_simdcall sqrtSingleAccuracy(SimdDouble x) { if (opt == MathOptimization::Safe) { SimdDouble res = maskzInvsqrt(x, SimdDouble(GMX_FLOAT_MIN) < x); - return res*x; + return res * x; } else { @@ -3637,45 +3578,45 @@ sqrtSingleAccuracy(SimdDouble x) * be treated as 0.0. * \return Cube root of x. */ -static inline SimdDouble gmx_simdcall -cbrtSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall cbrtSingleAccuracy(SimdDouble x) { - const SimdDouble signBit(GMX_DOUBLE_NEGZERO); - const SimdDouble minDouble(std::numeric_limits::min()); + const SimdDouble signBit(GMX_DOUBLE_NEGZERO); + const SimdDouble minDouble(std::numeric_limits::min()); // Bias is 1024-1 = 1023, which is divisible by 3, so no need to change it more. // Use the divided value as original constant to avoid division warnings. - const std::int32_t offsetDiv3(341); - const SimdDouble c2(-0.191502161678719066); - const SimdDouble c1(0.697570460207922770); - const SimdDouble c0(0.492659620528969547); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble three(3.0); - const SimdDouble oneThird(1.0/3.0); - const SimdDouble cbrt2(1.2599210498948731648); - const SimdDouble sqrCbrt2(1.5874010519681994748); + const std::int32_t offsetDiv3(341); + const SimdDouble c2(-0.191502161678719066); + const SimdDouble c1(0.697570460207922770); + const SimdDouble c0(0.492659620528969547); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble three(3.0); + const SimdDouble oneThird(1.0 / 3.0); + const SimdDouble cbrt2(1.2599210498948731648); + const SimdDouble sqrCbrt2(1.5874010519681994748); // See the single precision routines for documentation of the algorithm - SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) - SimdDBool xIsNonZero = (minDouble <= xAbs); // treat denormals as 0 - - SimdDInt32 exponent; - SimdDouble y = frexp(xAbs, &exponent); - SimdDouble z = fma(fma(y, c2, c1), y, c0); - SimdDouble w = z*z*z; - SimdDouble nom = z * fma(two, y, w); - SimdDouble invDenom = inv(fma(two, w, y)); - - SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3*offsetDiv3) + 0.1); - SimdDouble offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division - SimdDInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdDouble(static_cast(offsetDiv3))); - SimdDouble remainder = offsetExp - offsetExpDiv3 * three; - SimdDouble factor = blend(one, cbrt2, SimdDouble(0.5) < remainder); - factor = blend(factor, sqrCbrt2, SimdDouble(1.5) < remainder); - SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; - SimdDouble result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); + SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + SimdDBool xIsNonZero = (minDouble <= xAbs); // treat denormals as 0 + + SimdDInt32 exponent; + SimdDouble y = frexp(xAbs, &exponent); + SimdDouble z = fma(fma(y, c2, c1), y, c0); + SimdDouble w = z * z * z; + SimdDouble nom = z * fma(two, y, w); + SimdDouble invDenom = inv(fma(two, w, y)); + + SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3 * offsetDiv3) + 0.1); + SimdDouble offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdDInt32 expDiv3 = cvtR2I(offsetExpDiv3 - SimdDouble(static_cast(offsetDiv3))); + SimdDouble remainder = offsetExp - offsetExpDiv3 * three; + SimdDouble factor = blend(one, cbrt2, SimdDouble(0.5) < remainder); + factor = blend(factor, sqrCbrt2, SimdDouble(1.5) < remainder); + SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; + SimdDouble result = selectByMask(ldexp(fraction, expDiv3), xIsNonZero); return result; } @@ -3687,42 +3628,42 @@ cbrtSingleAccuracy(SimdDouble x) * \return Cube root of x. Undefined for values that don't * fulfill the restriction of abs(x) > minDouble. */ -static inline SimdDouble gmx_simdcall -invcbrtSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall invcbrtSingleAccuracy(SimdDouble x) { - const SimdDouble signBit(GMX_DOUBLE_NEGZERO); + const SimdDouble signBit(GMX_DOUBLE_NEGZERO); // Bias is 1024-1 = 1023, which is divisible by 3, so no need to change it more. // Use the divided value as original constant to avoid division warnings. - const std::int32_t offsetDiv3(341); - const SimdDouble c2(-0.191502161678719066); - const SimdDouble c1(0.697570460207922770); - const SimdDouble c0(0.492659620528969547); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble three(3.0); - const SimdDouble oneThird(1.0/3.0); - const SimdDouble invCbrt2(1.0/1.2599210498948731648); - const SimdDouble invSqrCbrt2(1.0F/1.5874010519681994748); + const std::int32_t offsetDiv3(341); + const SimdDouble c2(-0.191502161678719066); + const SimdDouble c1(0.697570460207922770); + const SimdDouble c0(0.492659620528969547); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble three(3.0); + const SimdDouble oneThird(1.0 / 3.0); + const SimdDouble invCbrt2(1.0 / 1.2599210498948731648); + const SimdDouble invSqrCbrt2(1.0F / 1.5874010519681994748); // See the single precision routines for documentation of the algorithm - SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 - SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) - - SimdDInt32 exponent; - SimdDouble y = frexp(xAbs, &exponent); - SimdDouble z = fma(fma(y, c2, c1), y, c0); - SimdDouble w = z*z*z; - SimdDouble nom = fma(two, w, y); - SimdDouble invDenom = inv(z * fma(two, y, w)); - SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3*offsetDiv3) + 0.1); - SimdDouble offsetExpDiv3 = trunc(offsetExp * oneThird); // important to truncate here to mimic integer division - SimdDInt32 expDiv3 = cvtR2I(SimdDouble(static_cast(offsetDiv3)) - offsetExpDiv3); - SimdDouble remainder = offsetExpDiv3 * three - offsetExp; - SimdDouble factor = blend(one, invCbrt2, remainder < SimdDouble(-0.5) ); - factor = blend(factor, invSqrCbrt2, remainder < SimdDouble(-1.5)); - SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; - SimdDouble result = ldexp(fraction, expDiv3); + SimdDouble xSignBit = x & signBit; // create bit mask where the sign bit is 1 for x elements < 0 + SimdDouble xAbs = andNot(signBit, x); // select everthing but the sign bit => abs(x) + + SimdDInt32 exponent; + SimdDouble y = frexp(xAbs, &exponent); + SimdDouble z = fma(fma(y, c2, c1), y, c0); + SimdDouble w = z * z * z; + SimdDouble nom = fma(two, w, y); + SimdDouble invDenom = inv(z * fma(two, y, w)); + SimdDouble offsetExp = cvtI2R(exponent) + SimdDouble(static_cast(3 * offsetDiv3) + 0.1); + SimdDouble offsetExpDiv3 = + trunc(offsetExp * oneThird); // important to truncate here to mimic integer division + SimdDInt32 expDiv3 = cvtR2I(SimdDouble(static_cast(offsetDiv3)) - offsetExpDiv3); + SimdDouble remainder = offsetExpDiv3 * three - offsetExp; + SimdDouble factor = blend(one, invCbrt2, remainder < SimdDouble(-0.5)); + factor = blend(factor, invSqrCbrt2, remainder < SimdDouble(-1.5)); + SimdDouble fraction = (nom * invDenom * factor) ^ xSignBit; + SimdDouble result = ldexp(fraction, expDiv3); return result; } @@ -3731,43 +3672,42 @@ invcbrtSingleAccuracy(SimdDouble x) * \param x Argument, should be >0. * \result The base 2 logarithm of x. Undefined if argument is invalid. */ -static inline SimdDouble gmx_simdcall -log2SingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall log2SingleAccuracy(SimdDouble x) { -#if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE +# if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE return log(x) * SimdDouble(std::log2(std::exp(1.0))); -#else - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble sqrt2(std::sqrt(2.0)); - const SimdDouble CL9(0.342149508897807708152F); - const SimdDouble CL7(0.411570606888219447939F); - const SimdDouble CL5(0.577085979152320294183F); - const SimdDouble CL3(0.961796550607099898222F); - const SimdDouble CL1(2.885390081777926774009F); - SimdDouble fexp, x2, p; - SimdDInt32 iexp; - SimdDBool mask; - - x = frexp(x, &iexp); - fexp = cvtI2R(iexp); - - mask = (x < sqrt2); +# else + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble sqrt2(std::sqrt(2.0)); + const SimdDouble CL9(0.342149508897807708152F); + const SimdDouble CL7(0.411570606888219447939F); + const SimdDouble CL5(0.577085979152320294183F); + const SimdDouble CL3(0.961796550607099898222F); + const SimdDouble CL1(2.885390081777926774009F); + SimdDouble fexp, x2, p; + SimdDInt32 iexp; + SimdDBool mask; + + x = frexp(x, &iexp); + fexp = cvtI2R(iexp); + + mask = (x < sqrt2); // Adjust to non-IEEE format for x0. * \result The natural logarithm of x. Undefined if argument is invalid. */ -static inline SimdDouble gmx_simdcall -logSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall logSingleAccuracy(SimdDouble x) { -#if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE +# if GMX_SIMD_HAVE_NATIVE_LOG_DOUBLE return log(x); -#else - const SimdDouble one(1.0); - const SimdDouble two(2.0); - const SimdDouble invsqrt2(1.0/std::sqrt(2.0)); - const SimdDouble corr(0.693147180559945286226764); - const SimdDouble CL9(0.2371599674224853515625); - const SimdDouble CL7(0.285279005765914916992188); - const SimdDouble CL5(0.400005519390106201171875); - const SimdDouble CL3(0.666666567325592041015625); - const SimdDouble CL1(2.0); - SimdDouble fexp, x2, p; - SimdDInt32 iexp; - SimdDBool mask; - - x = frexp(x, &iexp); - fexp = cvtI2R(iexp); - - mask = x < invsqrt2; +# else + const SimdDouble one(1.0); + const SimdDouble two(2.0); + const SimdDouble invsqrt2(1.0 / std::sqrt(2.0)); + const SimdDouble corr(0.693147180559945286226764); + const SimdDouble CL9(0.2371599674224853515625); + const SimdDouble CL7(0.285279005765914916992188); + const SimdDouble CL5(0.400005519390106201171875); + const SimdDouble CL3(0.666666567325592041015625); + const SimdDouble CL1(2.0); + SimdDouble fexp, x2, p; + SimdDInt32 iexp; + SimdDBool mask; + + x = frexp(x, &iexp); + fexp = cvtI2R(iexp); + + mask = x < invsqrt2; // Adjust to non-IEEE format for x<1/sqrt(2): exponent -= 1, mantissa *= 2.0 - fexp = fexp - selectByMask(one, mask); - x = x * blend(one, two, mask); + fexp = fexp - selectByMask(one, mask); + x = x * blend(one, two, mask); - x = (x - one) * invSingleAccuracy( x + one ); - x2 = x * x; + x = (x - one) * invSingleAccuracy(x + one); + x2 = x * x; - p = fma(CL9, x2, CL7); - p = fma(p, x2, CL5); - p = fma(p, x2, CL3); - p = fma(p, x2, CL1); - p = fma(p, x, corr * fexp); + p = fma(CL9, x2, CL7); + p = fma(p, x2, CL5); + p = fma(p, x2, CL3); + p = fma(p, x2, CL1); + p = fma(p, x, corr * fexp); return p; -#endif +# endif } /*! \brief SIMD 2^x. Double precision SIMD, single accuracy. * * \copydetails exp2(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -exp2SingleAccuracy(SimdDouble x) +template +static inline SimdDouble gmx_simdcall exp2SingleAccuracy(SimdDouble x) { -#if GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE +# if GMX_SIMD_HAVE_NATIVE_EXP2_DOUBLE return exp2(x); -#else - const SimdDouble CC6(0.0001534581200287996416911311); - const SimdDouble CC5(0.001339993121934088894618990); - const SimdDouble CC4(0.009618488957115180159497841); - const SimdDouble CC3(0.05550328776964726865751735); - const SimdDouble CC2(0.2402264689063408646490722); - const SimdDouble CC1(0.6931472057372680777553816); - const SimdDouble one(1.0); - - SimdDouble intpart; - SimdDouble p; - SimdDInt32 ix; +# else + const SimdDouble CC6(0.0001534581200287996416911311); + const SimdDouble CC5(0.001339993121934088894618990); + const SimdDouble CC4(0.009618488957115180159497841); + const SimdDouble CC3(0.05550328776964726865751735); + const SimdDouble CC2(0.2402264689063408646490722); + const SimdDouble CC1(0.6931472057372680777553816); + const SimdDouble one(1.0); + + SimdDouble intpart; + SimdDouble p; + SimdDInt32 ix; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -3857,51 +3795,49 @@ exp2SingleAccuracy(SimdDouble x) // with an argument that is so negative it cannot be converted to an integer. if (opt == MathOptimization::Safe) { - x = max(x, SimdDouble(std::numeric_limits::lowest())); + x = max(x, SimdDouble(std::numeric_limits::lowest())); } - ix = cvtR2I(x); - intpart = round(x); - x = x - intpart; + ix = cvtR2I(x); + intpart = round(x); + x = x - intpart; - p = fma(CC6, x, CC5); - p = fma(p, x, CC4); - p = fma(p, x, CC3); - p = fma(p, x, CC2); - p = fma(p, x, CC1); - p = fma(p, x, one); - x = ldexp(p, ix); + p = fma(CC6, x, CC5); + p = fma(p, x, CC4); + p = fma(p, x, CC3); + p = fma(p, x, CC2); + p = fma(p, x, CC1); + p = fma(p, x, one); + x = ldexp(p, ix); return x; -#endif +# endif } - /*! \brief SIMD exp(x). Double precision SIMD, single accuracy. * * \copydetails exp(SimdFloat) */ -template -static inline SimdDouble gmx_simdcall -expSingleAccuracy(SimdDouble x) +template +static inline SimdDouble gmx_simdcall expSingleAccuracy(SimdDouble x) { -#if GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE +# if GMX_SIMD_HAVE_NATIVE_EXP_DOUBLE return exp(x); -#else - const SimdDouble argscale(1.44269504088896341); +# else + const SimdDouble argscale(1.44269504088896341); // Lower bound: Clamp args that would lead to an IEEE fp exponent below -1023. - const SimdDouble smallArgLimit(-709.0895657128); - const SimdDouble invargscale(-0.69314718055994528623); - const SimdDouble CC4(0.00136324646882712841033936); - const SimdDouble CC3(0.00836596917361021041870117); - const SimdDouble CC2(0.0416710823774337768554688); - const SimdDouble CC1(0.166665524244308471679688); - const SimdDouble CC0(0.499999850988388061523438); - const SimdDouble one(1.0); - SimdDouble intpart; - SimdDouble y, p; - SimdDInt32 iy; + const SimdDouble smallArgLimit(-709.0895657128); + const SimdDouble invargscale(-0.69314718055994528623); + const SimdDouble CC4(0.00136324646882712841033936); + const SimdDouble CC3(0.00836596917361021041870117); + const SimdDouble CC2(0.0416710823774337768554688); + const SimdDouble CC1(0.166665524244308471679688); + const SimdDouble CC0(0.499999850988388061523438); + const SimdDouble one(1.0); + SimdDouble intpart; + SimdDouble y, p; + SimdDInt32 iy; // Large negative values are valid arguments to exp2(), so there are two // things we need to account for: @@ -3924,27 +3860,27 @@ expSingleAccuracy(SimdDouble x) if (opt == MathOptimization::Safe) { - x = max(x, SimdDouble(std::numeric_limits::lowest())/argscale); + x = max(x, SimdDouble(std::numeric_limits::lowest()) / argscale); } - y = x * argscale; + y = x * argscale; - iy = cvtR2I(y); - intpart = round(y); // use same rounding algorithm here + iy = cvtR2I(y); + intpart = round(y); // use same rounding algorithm here // Extended precision arithmetics not needed since // we have double precision and only need single accuracy. - x = fma(invargscale, intpart, x); - - p = fma(CC4, x, CC3); - p = fma(p, x, CC2); - p = fma(p, x, CC1); - p = fma(p, x, CC0); - p = fma(x*x, p, x); - p = p + one; - x = ldexp(p, iy); + x = fma(invargscale, intpart, x); + + p = fma(CC4, x, CC3); + p = fma(p, x, CC2); + p = fma(p, x, CC1); + p = fma(p, x, CC0); + p = fma(x * x, p, x); + p = p + one; + x = ldexp(p, iy); return x; -#endif +# endif } /*! \brief SIMD pow(x,y). Double precision SIMD data, single accuracy. @@ -3968,9 +3904,8 @@ expSingleAccuracy(SimdDouble x) * take the minimum of your variable and the largest valid argument * before calling this routine. */ -template -static inline SimdDouble gmx_simdcall -powSingleAccuracy(SimdDouble x, SimdDouble y) +template +static inline SimdDouble gmx_simdcall powSingleAccuracy(SimdDouble x, SimdDouble y) { SimdDouble xcorr; @@ -3989,7 +3924,7 @@ powSingleAccuracy(SimdDouble x, SimdDouble y) { // if x==0 and y>0 we explicitly set the result to 0.0 // For any x with y==0, the result will already be 1.0 since we multiply by y (0.0) and call exp(). - result = blend(result, setZero(), x == setZero() && setZero() < y ); + result = blend(result, setZero(), x == setZero() && setZero() < y); } return result; @@ -4003,62 +3938,61 @@ powSingleAccuracy(SimdDouble x, SimdDouble y) * This routine achieves very close to single precision, but we do not care about * the last bit or the subnormal result range. */ -static inline SimdDouble gmx_simdcall -erfSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall erfSingleAccuracy(SimdDouble x) { // Coefficients for minimax approximation of erf(x)=x*P(x^2) in range [-1,1] - const SimdDouble CA6(7.853861353153693e-5); - const SimdDouble CA5(-8.010193625184903e-4); - const SimdDouble CA4(5.188327685732524e-3); - const SimdDouble CA3(-2.685381193529856e-2); - const SimdDouble CA2(1.128358514861418e-1); - const SimdDouble CA1(-3.761262582423300e-1); - const SimdDouble CA0(1.128379165726710); + const SimdDouble CA6(7.853861353153693e-5); + const SimdDouble CA5(-8.010193625184903e-4); + const SimdDouble CA4(5.188327685732524e-3); + const SimdDouble CA3(-2.685381193529856e-2); + const SimdDouble CA2(1.128358514861418e-1); + const SimdDouble CA1(-3.761262582423300e-1); + const SimdDouble CA0(1.128379165726710); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*P((1/(x-1))^2) in range [0.67,2] - const SimdDouble CB9(-0.0018629930017603923); - const SimdDouble CB8(0.003909821287598495); - const SimdDouble CB7(-0.0052094582210355615); - const SimdDouble CB6(0.005685614362160572); - const SimdDouble CB5(-0.0025367682853477272); - const SimdDouble CB4(-0.010199799682318782); - const SimdDouble CB3(0.04369575504816542); - const SimdDouble CB2(-0.11884063474674492); - const SimdDouble CB1(0.2732120154030589); - const SimdDouble CB0(0.42758357702025784); + const SimdDouble CB9(-0.0018629930017603923); + const SimdDouble CB8(0.003909821287598495); + const SimdDouble CB7(-0.0052094582210355615); + const SimdDouble CB6(0.005685614362160572); + const SimdDouble CB5(-0.0025367682853477272); + const SimdDouble CB4(-0.010199799682318782); + const SimdDouble CB3(0.04369575504816542); + const SimdDouble CB2(-0.11884063474674492); + const SimdDouble CB1(0.2732120154030589); + const SimdDouble CB0(0.42758357702025784); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*(1/x)*P((1/x)^2) in range [2,9.19] - const SimdDouble CC10(-0.0445555913112064); - const SimdDouble CC9(0.21376355144663348); - const SimdDouble CC8(-0.3473187200259257); - const SimdDouble CC7(0.016690861551248114); - const SimdDouble CC6(0.7560973182491192); - const SimdDouble CC5(-1.2137903600145787); - const SimdDouble CC4(0.8411872321232948); - const SimdDouble CC3(-0.08670413896296343); - const SimdDouble CC2(-0.27124782687240334); - const SimdDouble CC1(-0.0007502488047806069); - const SimdDouble CC0(0.5642114853803148); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - - SimdDouble x2, x4, y; - SimdDouble t, t2, w, w2; - SimdDouble pA0, pA1, pB0, pB1, pC0, pC1; - SimdDouble expmx2; - SimdDouble res_erf, res_erfc, res; - SimdDBool mask, msk_erf; + const SimdDouble CC10(-0.0445555913112064); + const SimdDouble CC9(0.21376355144663348); + const SimdDouble CC8(-0.3473187200259257); + const SimdDouble CC7(0.016690861551248114); + const SimdDouble CC6(0.7560973182491192); + const SimdDouble CC5(-1.2137903600145787); + const SimdDouble CC4(0.8411872321232948); + const SimdDouble CC3(-0.08670413896296343); + const SimdDouble CC2(-0.27124782687240334); + const SimdDouble CC1(-0.0007502488047806069); + const SimdDouble CC0(0.5642114853803148); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + + SimdDouble x2, x4, y; + SimdDouble t, t2, w, w2; + SimdDouble pA0, pA1, pB0, pB1, pC0, pC1; + SimdDouble expmx2; + SimdDouble res_erf, res_erfc, res; + SimdDBool mask, msk_erf; // Calculate erf() - x2 = x * x; - x4 = x2 * x2; - - pA0 = fma(CA6, x4, CA4); - pA1 = fma(CA5, x4, CA3); - pA0 = fma(pA0, x4, CA2); - pA1 = fma(pA1, x4, CA1); - pA0 = pA0 * x4; - pA0 = fma(pA1, x2, pA0); + x2 = x * x; + x4 = x2 * x2; + + pA0 = fma(CA6, x4, CA4); + pA1 = fma(CA5, x4, CA3); + pA0 = fma(pA0, x4, CA2); + pA1 = fma(pA1, x4, CA1); + pA0 = pA0 * x4; + pA0 = fma(pA1, x2, pA0); // Constant term must come last for precision reasons - pA0 = pA0 + CA0; + pA0 = pA0 + CA0; res_erf = x * pA0; @@ -4070,30 +4004,30 @@ erfSingleAccuracy(SimdDouble x) t2 = t * t; w2 = w * w; - expmx2 = expSingleAccuracy( -y*y ); - - pB1 = fma(CB9, w2, CB7); - pB0 = fma(CB8, w2, CB6); - pB1 = fma(pB1, w2, CB5); - pB0 = fma(pB0, w2, CB4); - pB1 = fma(pB1, w2, CB3); - pB0 = fma(pB0, w2, CB2); - pB1 = fma(pB1, w2, CB1); - pB0 = fma(pB0, w2, CB0); - pB0 = fma(pB1, w, pB0); - - pC0 = fma(CC10, t2, CC8); - pC1 = fma(CC9, t2, CC7); - pC0 = fma(pC0, t2, CC6); - pC1 = fma(pC1, t2, CC5); - pC0 = fma(pC0, t2, CC4); - pC1 = fma(pC1, t2, CC3); - pC0 = fma(pC0, t2, CC2); - pC1 = fma(pC1, t2, CC1); - - pC0 = fma(pC0, t2, CC0); - pC0 = fma(pC1, t, pC0); - pC0 = pC0 * t; + expmx2 = expSingleAccuracy(-y * y); + + pB1 = fma(CB9, w2, CB7); + pB0 = fma(CB8, w2, CB6); + pB1 = fma(pB1, w2, CB5); + pB0 = fma(pB0, w2, CB4); + pB1 = fma(pB1, w2, CB3); + pB0 = fma(pB0, w2, CB2); + pB1 = fma(pB1, w2, CB1); + pB0 = fma(pB0, w2, CB0); + pB0 = fma(pB1, w, pB0); + + pC0 = fma(CC10, t2, CC8); + pC1 = fma(CC9, t2, CC7); + pC0 = fma(pC0, t2, CC6); + pC1 = fma(pC1, t2, CC5); + pC0 = fma(pC0, t2, CC4); + pC1 = fma(pC1, t2, CC3); + pC0 = fma(pC0, t2, CC2); + pC1 = fma(pC1, t2, CC1); + + pC0 = fma(pC0, t2, CC0); + pC0 = fma(pC1, t, pC0); + pC0 = pC0 * t; // Select pB0 or pC0 for erfc() mask = (two < y); @@ -4122,62 +4056,61 @@ erfSingleAccuracy(SimdDouble x) * (think results that are in the ballpark of 10^-30) since that is not * relevant for MD. */ -static inline SimdDouble gmx_simdcall -erfcSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall erfcSingleAccuracy(SimdDouble x) { // Coefficients for minimax approximation of erf(x)=x*P(x^2) in range [-1,1] - const SimdDouble CA6(7.853861353153693e-5); - const SimdDouble CA5(-8.010193625184903e-4); - const SimdDouble CA4(5.188327685732524e-3); - const SimdDouble CA3(-2.685381193529856e-2); - const SimdDouble CA2(1.128358514861418e-1); - const SimdDouble CA1(-3.761262582423300e-1); - const SimdDouble CA0(1.128379165726710); + const SimdDouble CA6(7.853861353153693e-5); + const SimdDouble CA5(-8.010193625184903e-4); + const SimdDouble CA4(5.188327685732524e-3); + const SimdDouble CA3(-2.685381193529856e-2); + const SimdDouble CA2(1.128358514861418e-1); + const SimdDouble CA1(-3.761262582423300e-1); + const SimdDouble CA0(1.128379165726710); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*P((1/(x-1))^2) in range [0.67,2] - const SimdDouble CB9(-0.0018629930017603923); - const SimdDouble CB8(0.003909821287598495); - const SimdDouble CB7(-0.0052094582210355615); - const SimdDouble CB6(0.005685614362160572); - const SimdDouble CB5(-0.0025367682853477272); - const SimdDouble CB4(-0.010199799682318782); - const SimdDouble CB3(0.04369575504816542); - const SimdDouble CB2(-0.11884063474674492); - const SimdDouble CB1(0.2732120154030589); - const SimdDouble CB0(0.42758357702025784); + const SimdDouble CB9(-0.0018629930017603923); + const SimdDouble CB8(0.003909821287598495); + const SimdDouble CB7(-0.0052094582210355615); + const SimdDouble CB6(0.005685614362160572); + const SimdDouble CB5(-0.0025367682853477272); + const SimdDouble CB4(-0.010199799682318782); + const SimdDouble CB3(0.04369575504816542); + const SimdDouble CB2(-0.11884063474674492); + const SimdDouble CB1(0.2732120154030589); + const SimdDouble CB0(0.42758357702025784); // Coefficients for minimax approximation of erfc(x)=Exp(-x^2)*(1/x)*P((1/x)^2) in range [2,9.19] - const SimdDouble CC10(-0.0445555913112064); - const SimdDouble CC9(0.21376355144663348); - const SimdDouble CC8(-0.3473187200259257); - const SimdDouble CC7(0.016690861551248114); - const SimdDouble CC6(0.7560973182491192); - const SimdDouble CC5(-1.2137903600145787); - const SimdDouble CC4(0.8411872321232948); - const SimdDouble CC3(-0.08670413896296343); - const SimdDouble CC2(-0.27124782687240334); - const SimdDouble CC1(-0.0007502488047806069); - const SimdDouble CC0(0.5642114853803148); - const SimdDouble one(1.0); - const SimdDouble two(2.0); - - SimdDouble x2, x4, y; - SimdDouble t, t2, w, w2; - SimdDouble pA0, pA1, pB0, pB1, pC0, pC1; - SimdDouble expmx2; - SimdDouble res_erf, res_erfc, res; - SimdDBool mask, msk_erf; + const SimdDouble CC10(-0.0445555913112064); + const SimdDouble CC9(0.21376355144663348); + const SimdDouble CC8(-0.3473187200259257); + const SimdDouble CC7(0.016690861551248114); + const SimdDouble CC6(0.7560973182491192); + const SimdDouble CC5(-1.2137903600145787); + const SimdDouble CC4(0.8411872321232948); + const SimdDouble CC3(-0.08670413896296343); + const SimdDouble CC2(-0.27124782687240334); + const SimdDouble CC1(-0.0007502488047806069); + const SimdDouble CC0(0.5642114853803148); + const SimdDouble one(1.0); + const SimdDouble two(2.0); + + SimdDouble x2, x4, y; + SimdDouble t, t2, w, w2; + SimdDouble pA0, pA1, pB0, pB1, pC0, pC1; + SimdDouble expmx2; + SimdDouble res_erf, res_erfc, res; + SimdDBool mask, msk_erf; // Calculate erf() - x2 = x * x; - x4 = x2 * x2; - - pA0 = fma(CA6, x4, CA4); - pA1 = fma(CA5, x4, CA3); - pA0 = fma(pA0, x4, CA2); - pA1 = fma(pA1, x4, CA1); - pA1 = pA1 * x2; - pA0 = fma(pA0, x4, pA1); + x2 = x * x; + x4 = x2 * x2; + + pA0 = fma(CA6, x4, CA4); + pA1 = fma(CA5, x4, CA3); + pA0 = fma(pA0, x4, CA2); + pA1 = fma(pA1, x4, CA1); + pA1 = pA1 * x2; + pA0 = fma(pA0, x4, pA1); // Constant term must come last for precision reasons - pA0 = pA0 + CA0; + pA0 = pA0 + CA0; res_erf = x * pA0; @@ -4189,30 +4122,30 @@ erfcSingleAccuracy(SimdDouble x) t2 = t * t; w2 = w * w; - expmx2 = expSingleAccuracy( -y*y ); - - pB1 = fma(CB9, w2, CB7); - pB0 = fma(CB8, w2, CB6); - pB1 = fma(pB1, w2, CB5); - pB0 = fma(pB0, w2, CB4); - pB1 = fma(pB1, w2, CB3); - pB0 = fma(pB0, w2, CB2); - pB1 = fma(pB1, w2, CB1); - pB0 = fma(pB0, w2, CB0); - pB0 = fma(pB1, w, pB0); - - pC0 = fma(CC10, t2, CC8); - pC1 = fma(CC9, t2, CC7); - pC0 = fma(pC0, t2, CC6); - pC1 = fma(pC1, t2, CC5); - pC0 = fma(pC0, t2, CC4); - pC1 = fma(pC1, t2, CC3); - pC0 = fma(pC0, t2, CC2); - pC1 = fma(pC1, t2, CC1); - - pC0 = fma(pC0, t2, CC0); - pC0 = fma(pC1, t, pC0); - pC0 = pC0 * t; + expmx2 = expSingleAccuracy(-y * y); + + pB1 = fma(CB9, w2, CB7); + pB0 = fma(CB8, w2, CB6); + pB1 = fma(pB1, w2, CB5); + pB0 = fma(pB0, w2, CB4); + pB1 = fma(pB1, w2, CB3); + pB0 = fma(pB0, w2, CB2); + pB1 = fma(pB1, w2, CB1); + pB0 = fma(pB0, w2, CB0); + pB0 = fma(pB1, w, pB0); + + pC0 = fma(CC10, t2, CC8); + pC1 = fma(CC9, t2, CC7); + pC0 = fma(pC0, t2, CC6); + pC1 = fma(pC1, t2, CC5); + pC0 = fma(pC0, t2, CC4); + pC1 = fma(pC1, t2, CC3); + pC0 = fma(pC0, t2, CC2); + pC1 = fma(pC1, t2, CC1); + + pC0 = fma(pC0, t2, CC0); + pC0 = fma(pC1, t, pC0); + pC0 = pC0 * t; // Select pB0 or pC0 for erfc() mask = (two < y); @@ -4236,44 +4169,43 @@ erfcSingleAccuracy(SimdDouble x) * \param[out] sinval Sin(x) * \param[out] cosval Cos(x) */ -static inline void gmx_simdcall -sinCosSingleAccuracy(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) +static inline void gmx_simdcall sinCosSingleAccuracy(SimdDouble x, SimdDouble* sinval, SimdDouble* cosval) { // Constants to subtract Pi/4*x from y while minimizing precision loss - const SimdDouble argred0(2*0.78539816290140151978); - const SimdDouble argred1(2*4.9604678871439933374e-10); - const SimdDouble argred2(2*1.1258708853173288931e-18); - const SimdDouble two_over_pi(2.0/M_PI); - const SimdDouble const_sin2(-1.9515295891e-4); - const SimdDouble const_sin1( 8.3321608736e-3); - const SimdDouble const_sin0(-1.6666654611e-1); - const SimdDouble const_cos2( 2.443315711809948e-5); - const SimdDouble const_cos1(-1.388731625493765e-3); - const SimdDouble const_cos0( 4.166664568298827e-2); - - const SimdDouble half(0.5); - const SimdDouble one(1.0); - SimdDouble ssign, csign; - SimdDouble x2, y, z, psin, pcos, sss, ccc; - SimdDBool mask; - -#if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL - const SimdDInt32 ione(1); - const SimdDInt32 itwo(2); - SimdDInt32 iy; - - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - - mask = cvtIB2B((iy & ione) == setZero()); - ssign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B((iy & itwo) == itwo)); - csign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B(((iy + ione) & itwo) == itwo)); -#else - const SimdDouble quarter(0.25); - const SimdDouble minusquarter(-0.25); - SimdDouble q; - SimdDBool m1, m2, m3; + const SimdDouble argred0(2 * 0.78539816290140151978); + const SimdDouble argred1(2 * 4.9604678871439933374e-10); + const SimdDouble argred2(2 * 1.1258708853173288931e-18); + const SimdDouble two_over_pi(2.0 / M_PI); + const SimdDouble const_sin2(-1.9515295891e-4); + const SimdDouble const_sin1(8.3321608736e-3); + const SimdDouble const_sin0(-1.6666654611e-1); + const SimdDouble const_cos2(2.443315711809948e-5); + const SimdDouble const_cos1(-1.388731625493765e-3); + const SimdDouble const_cos0(4.166664568298827e-2); + + const SimdDouble half(0.5); + const SimdDouble one(1.0); + SimdDouble ssign, csign; + SimdDouble x2, y, z, psin, pcos, sss, ccc; + SimdDBool mask; + +# if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + const SimdDInt32 ione(1); + const SimdDInt32 itwo(2); + SimdDInt32 iy; + + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + + mask = cvtIB2B((iy & ione) == setZero()); + ssign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B((iy & itwo) == itwo)); + csign = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), cvtIB2B(((iy + ione) & itwo) == itwo)); +# else + const SimdDouble quarter(0.25); + const SimdDouble minusquarter(-0.25); + SimdDouble q; + SimdDBool m1, m2, m3; /* The most obvious way to find the arguments quadrant in the unit circle * to calculate the sign is to use integer arithmetic, but that is not @@ -4284,67 +4216,67 @@ sinCosSingleAccuracy(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) * slightly slower (~10%) due to the longer latencies of floating-point, so * we only use it when integer SIMD arithmetic is not present. */ - ssign = x; - x = abs(x); + ssign = x; + x = abs(x); // It is critical that half-way cases are rounded down - z = fma(x, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); + z = fma(x, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); /* z now starts at 0.0 for x=-pi/4 (although neg. values cannot occur), and * then increased by 1.0 as x increases by 2*Pi, when it resets to 0.0. * This removes the 2*Pi periodicity without using any integer arithmetic. * First check if y had the value 2 or 3, set csign if true. */ - q = q - half; + q = q - half; /* If we have logical operations we can work directly on the signbit, which * saves instructions. Otherwise we need to represent signs as +1.0/-1.0. * Thus, if you are altering defines to debug alternative code paths, the * two GMX_SIMD_HAVE_LOGICAL sections in this routine must either both be * active or inactive - you will get errors if only one is used. */ -# if GMX_SIMD_HAVE_LOGICAL - ssign = ssign & SimdDouble(GMX_DOUBLE_NEGZERO); - csign = andNot(q, SimdDouble(GMX_DOUBLE_NEGZERO)); - ssign = ssign ^ csign; -# else - ssign = copysign(SimdDouble(1.0), ssign); - csign = copysign(SimdDouble(1.0), q); - csign = -csign; - ssign = ssign * csign; // swap ssign if csign was set. -# endif +# if GMX_SIMD_HAVE_LOGICAL + ssign = ssign & SimdDouble(GMX_DOUBLE_NEGZERO); + csign = andNot(q, SimdDouble(GMX_DOUBLE_NEGZERO)); + ssign = ssign ^ csign; +# else + ssign = copysign(SimdDouble(1.0), ssign); + csign = copysign(SimdDouble(1.0), q); + csign = -csign; + ssign = ssign * csign; // swap ssign if csign was set. +# endif // Check if y had value 1 or 3 (remember we subtracted 0.5 from q) - m1 = (q < minusquarter); - m2 = (setZero() <= q); - m3 = (q < quarter); - m2 = m2 && m3; - mask = m1 || m2; + m1 = (q < minusquarter); + m2 = (setZero() <= q); + m3 = (q < quarter); + m2 = m2 && m3; + mask = m1 || m2; // where mask is FALSE, swap sign. csign = csign * blend(SimdDouble(-1.0), one, mask); -#endif - x = fnma(y, argred0, x); - x = fnma(y, argred1, x); - x = fnma(y, argred2, x); - x2 = x * x; - - psin = fma(const_sin2, x2, const_sin1); - psin = fma(psin, x2, const_sin0); - psin = fma(psin, x * x2, x); - pcos = fma(const_cos2, x2, const_cos1); - pcos = fma(pcos, x2, const_cos0); - pcos = fms(pcos, x2, half); - pcos = fma(pcos, x2, one); - - sss = blend(pcos, psin, mask); - ccc = blend(psin, pcos, mask); +# endif + x = fnma(y, argred0, x); + x = fnma(y, argred1, x); + x = fnma(y, argred2, x); + x2 = x * x; + + psin = fma(const_sin2, x2, const_sin1); + psin = fma(psin, x2, const_sin0); + psin = fma(psin, x * x2, x); + pcos = fma(const_cos2, x2, const_cos1); + pcos = fma(pcos, x2, const_cos0); + pcos = fms(pcos, x2, half); + pcos = fma(pcos, x2, one); + + sss = blend(pcos, psin, mask); + ccc = blend(psin, pcos, mask); // See comment for GMX_SIMD_HAVE_LOGICAL section above. -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL *sinval = sss ^ ssign; *cosval = ccc ^ csign; -#else +# else *sinval = sss * ssign; *cosval = ccc * csign; -#endif +# endif } /*! \brief SIMD sin(x). Double precision SIMD data, single accuracy. @@ -4355,8 +4287,7 @@ sinCosSingleAccuracy(SimdDouble x, SimdDouble *sinval, SimdDouble *cosval) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdDouble gmx_simdcall -sinSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall sinSingleAccuracy(SimdDouble x) { SimdDouble s, c; sinCosSingleAccuracy(x, &s, &c); @@ -4371,8 +4302,7 @@ sinSingleAccuracy(SimdDouble x) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdDouble gmx_simdcall -cosSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall cosSingleAccuracy(SimdDouble x) { SimdDouble s, c; sinCosSingleAccuracy(x, &s, &c); @@ -4384,69 +4314,68 @@ cosSingleAccuracy(SimdDouble x) * \param x The argument to evaluate tan for * \result Tan(x) */ -static inline SimdDouble gmx_simdcall -tanSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall tanSingleAccuracy(SimdDouble x) { - const SimdDouble argred0(2*0.78539816290140151978); - const SimdDouble argred1(2*4.9604678871439933374e-10); - const SimdDouble argred2(2*1.1258708853173288931e-18); - const SimdDouble two_over_pi(2.0/M_PI); - const SimdDouble CT6(0.009498288995810566122993911); - const SimdDouble CT5(0.002895755790837379295226923); - const SimdDouble CT4(0.02460087336161924491836265); - const SimdDouble CT3(0.05334912882656359828045988); - const SimdDouble CT2(0.1333989091464957704418495); - const SimdDouble CT1(0.3333307599244198227797507); - - SimdDouble x2, p, y, z; - SimdDBool mask; - -#if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL - SimdDInt32 iy; - SimdDInt32 ione(1); - - z = x * two_over_pi; - iy = cvtR2I(z); - y = round(z); - mask = cvtIB2B((iy & ione) == ione); - - x = fnma(y, argred0, x); - x = fnma(y, argred1, x); - x = fnma(y, argred2, x); - x = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), mask) ^ x; -#else - const SimdDouble quarter(0.25); - const SimdDouble half(0.5); - const SimdDouble threequarter(0.75); - SimdDouble w, q; - SimdDBool m1, m2, m3; - - w = abs(x); - z = fma(w, two_over_pi, half); - y = trunc(z); - q = z * quarter; - q = q - trunc(q); - m1 = (quarter <= q); - m2 = (q < half); - m3 = (threequarter <= q); - m1 = m1 && m2; - mask = m1 || m3; - w = fnma(y, argred0, w); - w = fnma(y, argred1, w); - w = fnma(y, argred2, w); - - w = blend(w, -w, mask); - x = w * copysign( SimdDouble(1.0), x ); -#endif - x2 = x * x; - p = fma(CT6, x2, CT5); - p = fma(p, x2, CT4); - p = fma(p, x2, CT3); - p = fma(p, x2, CT2); - p = fma(p, x2, CT1); - p = fma(x2, p * x, x); - - p = blend( p, maskzInvSingleAccuracy(p, mask), mask); + const SimdDouble argred0(2 * 0.78539816290140151978); + const SimdDouble argred1(2 * 4.9604678871439933374e-10); + const SimdDouble argred2(2 * 1.1258708853173288931e-18); + const SimdDouble two_over_pi(2.0 / M_PI); + const SimdDouble CT6(0.009498288995810566122993911); + const SimdDouble CT5(0.002895755790837379295226923); + const SimdDouble CT4(0.02460087336161924491836265); + const SimdDouble CT3(0.05334912882656359828045988); + const SimdDouble CT2(0.1333989091464957704418495); + const SimdDouble CT1(0.3333307599244198227797507); + + SimdDouble x2, p, y, z; + SimdDBool mask; + +# if GMX_SIMD_HAVE_DINT32_ARITHMETICS && GMX_SIMD_HAVE_LOGICAL + SimdDInt32 iy; + SimdDInt32 ione(1); + + z = x * two_over_pi; + iy = cvtR2I(z); + y = round(z); + mask = cvtIB2B((iy & ione) == ione); + + x = fnma(y, argred0, x); + x = fnma(y, argred1, x); + x = fnma(y, argred2, x); + x = selectByMask(SimdDouble(GMX_DOUBLE_NEGZERO), mask) ^ x; +# else + const SimdDouble quarter(0.25); + const SimdDouble half(0.5); + const SimdDouble threequarter(0.75); + SimdDouble w, q; + SimdDBool m1, m2, m3; + + w = abs(x); + z = fma(w, two_over_pi, half); + y = trunc(z); + q = z * quarter; + q = q - trunc(q); + m1 = (quarter <= q); + m2 = (q < half); + m3 = (threequarter <= q); + m1 = m1 && m2; + mask = m1 || m3; + w = fnma(y, argred0, w); + w = fnma(y, argred1, w); + w = fnma(y, argred2, w); + + w = blend(w, -w, mask); + x = w * copysign(SimdDouble(1.0), x); +# endif + x2 = x * x; + p = fma(CT6, x2, CT5); + p = fma(p, x2, CT4); + p = fma(p, x2, CT3); + p = fma(p, x2, CT2); + p = fma(p, x2, CT1); + p = fma(x2, p * x, x); + + p = blend(p, maskzInvSingleAccuracy(p, mask), mask); return p; } @@ -4455,13 +4384,12 @@ tanSingleAccuracy(SimdDouble x) * \param x The argument to evaluate asin for * \result Asin(x) */ -static inline SimdDouble gmx_simdcall -asinSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall asinSingleAccuracy(SimdDouble x) { const SimdDouble limitlow(1e-4); const SimdDouble half(0.5); const SimdDouble one(1.0); - const SimdDouble halfpi(M_PI/2.0); + const SimdDouble halfpi(M_PI / 2.0); const SimdDouble CC5(4.2163199048E-2); const SimdDouble CC4(2.4181311049E-2); const SimdDouble CC3(4.5470025998E-2); @@ -4482,20 +4410,20 @@ asinSingleAccuracy(SimdDouble x) z = blend(z2, z1, mask); q = blend(q2, q1, mask); - z2 = z * z; - pA = fma(CC5, z2, CC3); - pB = fma(CC4, z2, CC2); - pA = fma(pA, z2, CC1); - pA = pA * z; - z = fma(pB, z2, pA); - z = fma(z, q, q); - q2 = halfpi - z; - q2 = q2 - z; - z = blend(z, q2, mask); - - mask = (limitlow < xabs); - z = blend( xabs, z, mask ); - z = copysign(z, x); + z2 = z * z; + pA = fma(CC5, z2, CC3); + pB = fma(CC4, z2, CC2); + pA = fma(pA, z2, CC1); + pA = pA * z; + z = fma(pB, z2, pA); + z = fma(z, q, q); + q2 = halfpi - z; + q2 = q2 - z; + z = blend(z, q2, mask); + + mask = (limitlow < xabs); + z = blend(xabs, z, mask); + z = copysign(z, x); return z; } @@ -4505,13 +4433,12 @@ asinSingleAccuracy(SimdDouble x) * \param x The argument to evaluate acos for * \result Acos(x) */ -static inline SimdDouble gmx_simdcall -acosSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall acosSingleAccuracy(SimdDouble x) { const SimdDouble one(1.0); const SimdDouble half(0.5); const SimdDouble pi(M_PI); - const SimdDouble halfpi(M_PI/2.0); + const SimdDouble halfpi(M_PI / 2.0); SimdDouble xabs; SimdDouble z, z1, z2, z3; SimdDBool mask1, mask2, mask3; @@ -4526,11 +4453,11 @@ acosSingleAccuracy(SimdDouble x) z = blend(x, z, mask1); z = asinSingleAccuracy(z); - z2 = z + z; - z1 = pi - z2; - z3 = halfpi - z; - z = blend(z1, z2, mask2); - z = blend(z3, z, mask1); + z2 = z + z; + z1 = pi - z2; + z3 = halfpi - z; + z = blend(z1, z2, mask2); + z = blend(z3, z, mask1); return z; } @@ -4540,10 +4467,9 @@ acosSingleAccuracy(SimdDouble x) * \param x The argument to evaluate atan for * \result Atan(x), same argument/value range as standard math library. */ -static inline SimdDouble gmx_simdcall -atanSingleAccuracy(SimdDouble x) +static inline SimdDouble gmx_simdcall atanSingleAccuracy(SimdDouble x) { - const SimdDouble halfpi(M_PI/2); + const SimdDouble halfpi(M_PI / 2); const SimdDouble CA17(0.002823638962581753730774); const SimdDouble CA15(-0.01595690287649631500244); const SimdDouble CA13(0.04250498861074447631836); @@ -4560,20 +4486,20 @@ atanSingleAccuracy(SimdDouble x) mask2 = (SimdDouble(1.0) < x); x = blend(x, maskzInvSingleAccuracy(x, mask2), mask2); - x2 = x * x; - x3 = x2 * x; - x4 = x2 * x2; - pA = fma(CA17, x4, CA13); - pB = fma(CA15, x4, CA11); - pA = fma(pA, x4, CA9); - pB = fma(pB, x4, CA7); - pA = fma(pA, x4, CA5); - pB = fma(pB, x4, CA3); - pA = fma(pA, x2, pB); - pA = fma(pA, x3, x); - - pA = blend(pA, halfpi - pA, mask2); - pA = blend(pA, -pA, mask); + x2 = x * x; + x3 = x2 * x; + x4 = x2 * x2; + pA = fma(CA17, x4, CA13); + pB = fma(CA15, x4, CA11); + pA = fma(pA, x4, CA9); + pB = fma(pB, x4, CA7); + pA = fma(pA, x4, CA5); + pB = fma(pB, x4, CA3); + pA = fma(pA, x2, pB); + pA = fma(pA, x3, x); + + pA = blend(pA, halfpi - pA, mask2); + pA = blend(pA, -pA, mask); return pA; } @@ -4591,11 +4517,10 @@ atanSingleAccuracy(SimdDouble x) * of any concern in Gromacs, and in particular it will not affect calculations * of angles from vectors. */ -static inline SimdDouble gmx_simdcall -atan2SingleAccuracy(SimdDouble y, SimdDouble x) +static inline SimdDouble gmx_simdcall atan2SingleAccuracy(SimdDouble y, SimdDouble x) { const SimdDouble pi(M_PI); - const SimdDouble halfpi(M_PI/2.0); + const SimdDouble halfpi(M_PI / 2.0); SimdDouble xinv, p, aoffset; SimdDBool mask_xnz, mask_ynz, mask_xlt0, mask_ylt0; @@ -4604,16 +4529,16 @@ atan2SingleAccuracy(SimdDouble y, SimdDouble x) mask_xlt0 = (x < setZero()); mask_ylt0 = (y < setZero()); - aoffset = selectByNotMask(halfpi, mask_xnz); - aoffset = selectByMask(aoffset, mask_ynz); + aoffset = selectByNotMask(halfpi, mask_xnz); + aoffset = selectByMask(aoffset, mask_ynz); - aoffset = blend(aoffset, pi, mask_xlt0); - aoffset = blend(aoffset, -aoffset, mask_ylt0); + aoffset = blend(aoffset, pi, mask_xlt0); + aoffset = blend(aoffset, -aoffset, mask_ylt0); - xinv = maskzInvSingleAccuracy(x, mask_xnz); - p = y * xinv; - p = atanSingleAccuracy(p); - p = p + aoffset; + xinv = maskzInvSingleAccuracy(x, mask_xnz); + p = y * xinv; + p = atanSingleAccuracy(p); + p = p + aoffset; return p; } @@ -4694,47 +4619,45 @@ atan2SingleAccuracy(SimdDouble y, SimdDouble x) * added to \f$1/r\f$ the error will be insignificant. * */ -static inline SimdDouble gmx_simdcall -pmeForceCorrectionSingleAccuracy(SimdDouble z2) +static inline SimdDouble gmx_simdcall pmeForceCorrectionSingleAccuracy(SimdDouble z2) { - const SimdDouble FN6(-1.7357322914161492954e-8); - const SimdDouble FN5(1.4703624142580877519e-6); - const SimdDouble FN4(-0.000053401640219807709149); - const SimdDouble FN3(0.0010054721316683106153); - const SimdDouble FN2(-0.019278317264888380590); - const SimdDouble FN1(0.069670166153766424023); - const SimdDouble FN0(-0.75225204789749321333); - - const SimdDouble FD4(0.0011193462567257629232); - const SimdDouble FD3(0.014866955030185295499); - const SimdDouble FD2(0.11583842382862377919); - const SimdDouble FD1(0.50736591960530292870); - const SimdDouble FD0(1.0); - - SimdDouble z4; - SimdDouble polyFN0, polyFN1, polyFD0, polyFD1; - - z4 = z2 * z2; - - polyFD0 = fma(FD4, z4, FD2); - polyFD1 = fma(FD3, z4, FD1); - polyFD0 = fma(polyFD0, z4, FD0); - polyFD0 = fma(polyFD1, z2, polyFD0); - - polyFD0 = invSingleAccuracy(polyFD0); - - polyFN0 = fma(FN6, z4, FN4); - polyFN1 = fma(FN5, z4, FN3); - polyFN0 = fma(polyFN0, z4, FN2); - polyFN1 = fma(polyFN1, z4, FN1); - polyFN0 = fma(polyFN0, z4, FN0); - polyFN0 = fma(polyFN1, z2, polyFN0); + const SimdDouble FN6(-1.7357322914161492954e-8); + const SimdDouble FN5(1.4703624142580877519e-6); + const SimdDouble FN4(-0.000053401640219807709149); + const SimdDouble FN3(0.0010054721316683106153); + const SimdDouble FN2(-0.019278317264888380590); + const SimdDouble FN1(0.069670166153766424023); + const SimdDouble FN0(-0.75225204789749321333); + + const SimdDouble FD4(0.0011193462567257629232); + const SimdDouble FD3(0.014866955030185295499); + const SimdDouble FD2(0.11583842382862377919); + const SimdDouble FD1(0.50736591960530292870); + const SimdDouble FD0(1.0); + + SimdDouble z4; + SimdDouble polyFN0, polyFN1, polyFD0, polyFD1; + + z4 = z2 * z2; + + polyFD0 = fma(FD4, z4, FD2); + polyFD1 = fma(FD3, z4, FD1); + polyFD0 = fma(polyFD0, z4, FD0); + polyFD0 = fma(polyFD1, z2, polyFD0); + + polyFD0 = invSingleAccuracy(polyFD0); + + polyFN0 = fma(FN6, z4, FN4); + polyFN1 = fma(FN5, z4, FN3); + polyFN0 = fma(polyFN0, z4, FN2); + polyFN1 = fma(polyFN1, z4, FN1); + polyFN0 = fma(polyFN0, z4, FN0); + polyFN0 = fma(polyFN1, z2, polyFN0); return polyFN0 * polyFD0; } - /*! \brief Analytical PME potential correction, double SIMD data, single accuracy. * * \param z2 \f$(r \beta)^2\f$ - see below for details. @@ -4766,44 +4689,43 @@ pmeForceCorrectionSingleAccuracy(SimdDouble z2) * This approximation achieves an accuracy slightly lower than 1e-6; when * added to \f$1/r\f$ the error will be insignificant. */ -static inline SimdDouble gmx_simdcall -pmePotentialCorrectionSingleAccuracy(SimdDouble z2) +static inline SimdDouble gmx_simdcall pmePotentialCorrectionSingleAccuracy(SimdDouble z2) { - const SimdDouble VN6(1.9296833005951166339e-8); - const SimdDouble VN5(-1.4213390571557850962e-6); - const SimdDouble VN4(0.000041603292906656984871); - const SimdDouble VN3(-0.00013134036773265025626); - const SimdDouble VN2(0.038657983986041781264); - const SimdDouble VN1(0.11285044772717598220); - const SimdDouble VN0(1.1283802385263030286); + const SimdDouble VN6(1.9296833005951166339e-8); + const SimdDouble VN5(-1.4213390571557850962e-6); + const SimdDouble VN4(0.000041603292906656984871); + const SimdDouble VN3(-0.00013134036773265025626); + const SimdDouble VN2(0.038657983986041781264); + const SimdDouble VN1(0.11285044772717598220); + const SimdDouble VN0(1.1283802385263030286); - const SimdDouble VD3(0.0066752224023576045451); - const SimdDouble VD2(0.078647795836373922256); - const SimdDouble VD1(0.43336185284710920150); - const SimdDouble VD0(1.0); + const SimdDouble VD3(0.0066752224023576045451); + const SimdDouble VD2(0.078647795836373922256); + const SimdDouble VD1(0.43336185284710920150); + const SimdDouble VD0(1.0); - SimdDouble z4; - SimdDouble polyVN0, polyVN1, polyVD0, polyVD1; + SimdDouble z4; + SimdDouble polyVN0, polyVN1, polyVD0, polyVD1; - z4 = z2 * z2; + z4 = z2 * z2; - polyVD1 = fma(VD3, z4, VD1); - polyVD0 = fma(VD2, z4, VD0); - polyVD0 = fma(polyVD1, z2, polyVD0); + polyVD1 = fma(VD3, z4, VD1); + polyVD0 = fma(VD2, z4, VD0); + polyVD0 = fma(polyVD1, z2, polyVD0); - polyVD0 = invSingleAccuracy(polyVD0); + polyVD0 = invSingleAccuracy(polyVD0); - polyVN0 = fma(VN6, z4, VN4); - polyVN1 = fma(VN5, z4, VN3); - polyVN0 = fma(polyVN0, z4, VN2); - polyVN1 = fma(polyVN1, z4, VN1); - polyVN0 = fma(polyVN0, z4, VN0); - polyVN0 = fma(polyVN1, z2, polyVN0); + polyVN0 = fma(VN6, z4, VN4); + polyVN1 = fma(VN5, z4, VN3); + polyVN0 = fma(polyVN0, z4, VN2); + polyVN1 = fma(polyVN1, z4, VN1); + polyVN0 = fma(polyVN0, z4, VN0); + polyVN0 = fma(polyVN1, z2, polyVN0); return polyVN0 * polyVD0; } -#endif +# endif /*! \name SIMD4 math functions @@ -4813,7 +4735,7 @@ pmePotentialCorrectionSingleAccuracy(SimdDouble z2) */ -#if GMX_SIMD4_HAVE_FLOAT +# if GMX_SIMD4_HAVE_FLOAT /************************************************************************* * SINGLE PRECISION SIMD4 MATH FUNCTIONS - JUST A SMALL SUBSET SUPPORTED * @@ -4828,13 +4750,12 @@ pmePotentialCorrectionSingleAccuracy(SimdDouble z2) * \param x The reference (starting) value x for which we want 1/sqrt(x). * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline Simd4Float gmx_simdcall -rsqrtIter(Simd4Float lu, Simd4Float x) +static inline Simd4Float gmx_simdcall rsqrtIter(Simd4Float lu, Simd4Float x) { - Simd4Float tmp1 = x*lu; - Simd4Float tmp2 = Simd4Float(-0.5F)*lu; - tmp1 = fma(tmp1, lu, Simd4Float(-3.0F)); - return tmp1*tmp2; + Simd4Float tmp1 = x * lu; + Simd4Float tmp2 = Simd4Float(-0.5F) * lu; + tmp1 = fma(tmp1, lu, Simd4Float(-3.0F)); + return tmp1 * tmp2; } /*! \brief Calculate 1/sqrt(x) for SIMD4 float. @@ -4849,28 +4770,26 @@ rsqrtIter(Simd4Float lu, Simd4Float x) * check arguments. * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline Simd4Float gmx_simdcall -invsqrt(Simd4Float x) +static inline Simd4Float gmx_simdcall invsqrt(Simd4Float x) { Simd4Float lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } -#endif // GMX_SIMD4_HAVE_FLOAT +# endif // GMX_SIMD4_HAVE_FLOAT - -#if GMX_SIMD4_HAVE_DOUBLE +# if GMX_SIMD4_HAVE_DOUBLE /************************************************************************* * DOUBLE PRECISION SIMD4 MATH FUNCTIONS - JUST A SMALL SUBSET SUPPORTED * *************************************************************************/ @@ -4884,13 +4803,12 @@ invsqrt(Simd4Float x) * \param x The reference (starting) value x for which we want 1/sqrt(x). * \return An improved approximation with roughly twice as many bits of accuracy. */ -static inline Simd4Double gmx_simdcall -rsqrtIter(Simd4Double lu, Simd4Double x) +static inline Simd4Double gmx_simdcall rsqrtIter(Simd4Double lu, Simd4Double x) { - Simd4Double tmp1 = x*lu; - Simd4Double tmp2 = Simd4Double(-0.5F)*lu; + Simd4Double tmp1 = x * lu; + Simd4Double tmp2 = Simd4Double(-0.5F) * lu; tmp1 = fma(tmp1, lu, Simd4Double(-3.0F)); - return tmp1*tmp2; + return tmp1 * tmp2; } /*! \brief Calculate 1/sqrt(x) for SIMD4 double. @@ -4905,22 +4823,21 @@ rsqrtIter(Simd4Double lu, Simd4Double x) * check arguments. * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline Simd4Double gmx_simdcall -invsqrt(Simd4Double x) +static inline Simd4Double gmx_simdcall invsqrt(Simd4Double x) { Simd4Double lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 8 < GMX_SIMD_ACCURACY_BITS_DOUBLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } @@ -4941,29 +4858,27 @@ invsqrt(Simd4Double x) * check arguments. * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline Simd4Double gmx_simdcall -invsqrtSingleAccuracy(Simd4Double x) +static inline Simd4Double gmx_simdcall invsqrtSingleAccuracy(Simd4Double x) { Simd4Double lu = rsqrt(x); -#if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) +# if (GMX_SIMD_RSQRT_BITS < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*2 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 2 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif -#if (GMX_SIMD_RSQRT_BITS*4 < GMX_SIMD_ACCURACY_BITS_SINGLE) +# endif +# if (GMX_SIMD_RSQRT_BITS * 4 < GMX_SIMD_ACCURACY_BITS_SINGLE) lu = rsqrtIter(lu, x); -#endif +# endif return lu; } - -#endif // GMX_SIMD4_HAVE_DOUBLE +# endif // GMX_SIMD4_HAVE_DOUBLE /*! \} */ -#if GMX_SIMD_HAVE_FLOAT +# if GMX_SIMD_HAVE_FLOAT /*! \brief Calculate 1/sqrt(x) for SIMD float, only targeting single accuracy. * * \param x Argument that must be larger than GMX_FLOAT_MIN and smaller than @@ -4976,8 +4891,7 @@ invsqrtSingleAccuracy(Simd4Double x) * check arguments. * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline SimdFloat gmx_simdcall -invsqrtSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall invsqrtSingleAccuracy(SimdFloat x) { return invsqrt(x); } @@ -5000,8 +4914,7 @@ invsqrtSingleAccuracy(SimdFloat x) * \return 1/sqrt(x). Result is undefined if your argument was invalid or * entry was not masked, and 0.0 for masked-out entries. */ -static inline SimdFloat -maskzInvsqrtSingleAccuracy(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzInvsqrtSingleAccuracy(SimdFloat x, SimdFBool m) { return maskzInvsqrt(x, m); } @@ -5025,9 +4938,7 @@ maskzInvsqrtSingleAccuracy(SimdFloat x, SimdFBool m) * responsibility for checking falls on you - this routine does not * check arguments. */ -static inline void gmx_simdcall -invsqrtPairSingleAccuracy(SimdFloat x0, SimdFloat x1, - SimdFloat *out0, SimdFloat *out1) +static inline void gmx_simdcall invsqrtPairSingleAccuracy(SimdFloat x0, SimdFloat x1, SimdFloat* out0, SimdFloat* out1) { return invsqrtPair(x0, x1, out0, out1); } @@ -5044,8 +4955,7 @@ invsqrtPairSingleAccuracy(SimdFloat x0, SimdFloat x1, * check arguments. * \return 1/x. Result is undefined if your argument was invalid. */ -static inline SimdFloat gmx_simdcall -invSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall invSingleAccuracy(SimdFloat x) { return inv(x); } @@ -5064,8 +4974,7 @@ invSingleAccuracy(SimdFloat x) * \param m Mask * \return 1/x for elements where m is true, or 0.0 for masked-out entries. */ -static inline SimdFloat -maskzInvSingleAccuracy(SimdFloat x, SimdFBool m) +static inline SimdFloat maskzInvSingleAccuracy(SimdFloat x, SimdFBool m) { return maskzInv(x, m); } @@ -5074,9 +4983,8 @@ maskzInvSingleAccuracy(SimdFloat x, SimdFBool m) * * \copydetails sqrt(SimdFloat) */ -template -static inline SimdFloat gmx_simdcall -sqrtSingleAccuracy(SimdFloat x) +template +static inline SimdFloat gmx_simdcall sqrtSingleAccuracy(SimdFloat x) { return sqrt(x); } @@ -5085,8 +4993,7 @@ sqrtSingleAccuracy(SimdFloat x) * * \copydetails cbrt(SimdFloat) */ -static inline SimdFloat gmx_simdcall -cbrtSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall cbrtSingleAccuracy(SimdFloat x) { return cbrt(x); } @@ -5095,8 +5002,7 @@ cbrtSingleAccuracy(SimdFloat x) * * \copydetails cbrt(SimdFloat) */ -static inline SimdFloat gmx_simdcall -invcbrtSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall invcbrtSingleAccuracy(SimdFloat x) { return invcbrt(x); } @@ -5106,8 +5012,7 @@ invcbrtSingleAccuracy(SimdFloat x) * \param x Argument, should be >0. * \result The base-2 logarithm of x. Undefined if argument is invalid. */ -static inline SimdFloat gmx_simdcall -log2SingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall log2SingleAccuracy(SimdFloat x) { return log2(x); } @@ -5117,8 +5022,7 @@ log2SingleAccuracy(SimdFloat x) * \param x Argument, should be >0. * \result The natural logarithm of x. Undefined if argument is invalid. */ -static inline SimdFloat gmx_simdcall -logSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall logSingleAccuracy(SimdFloat x) { return log(x); } @@ -5127,9 +5031,8 @@ logSingleAccuracy(SimdFloat x) * * \copydetails exp2(SimdFloat) */ -template -static inline SimdFloat gmx_simdcall -exp2SingleAccuracy(SimdFloat x) +template +static inline SimdFloat gmx_simdcall exp2SingleAccuracy(SimdFloat x) { return exp2(x); } @@ -5138,9 +5041,8 @@ exp2SingleAccuracy(SimdFloat x) * * \copydetails exp(SimdFloat) */ -template -static inline SimdFloat gmx_simdcall -expSingleAccuracy(SimdFloat x) +template +static inline SimdFloat gmx_simdcall expSingleAccuracy(SimdFloat x) { return exp(x); } @@ -5149,9 +5051,8 @@ expSingleAccuracy(SimdFloat x) * * \copydetails pow(SimdFloat) */ -template -static inline SimdFloat gmx_simdcall -powSingleAccuracy(SimdFloat x, SimdFloat y) +template +static inline SimdFloat gmx_simdcall powSingleAccuracy(SimdFloat x, SimdFloat y) { return pow(x, y); } @@ -5164,8 +5065,7 @@ powSingleAccuracy(SimdFloat x, SimdFloat y) * This routine achieves very close to single precision, but we do not care about * the last bit or the subnormal result range. */ -static inline SimdFloat gmx_simdcall -erfSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall erfSingleAccuracy(SimdFloat x) { return erf(x); } @@ -5181,8 +5081,7 @@ erfSingleAccuracy(SimdFloat x) * (think results that are in the ballpark of 10^-30) since that is not * relevant for MD. */ -static inline SimdFloat gmx_simdcall -erfcSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall erfcSingleAccuracy(SimdFloat x) { return erfc(x); } @@ -5193,8 +5092,7 @@ erfcSingleAccuracy(SimdFloat x) * \param[out] sinval Sin(x) * \param[out] cosval Cos(x) */ -static inline void gmx_simdcall -sinCosSingleAccuracy(SimdFloat x, SimdFloat *sinval, SimdFloat *cosval) +static inline void gmx_simdcall sinCosSingleAccuracy(SimdFloat x, SimdFloat* sinval, SimdFloat* cosval) { sincos(x, sinval, cosval); } @@ -5207,8 +5105,7 @@ sinCosSingleAccuracy(SimdFloat x, SimdFloat *sinval, SimdFloat *cosval) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdFloat gmx_simdcall -sinSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall sinSingleAccuracy(SimdFloat x) { return sin(x); } @@ -5221,8 +5118,7 @@ sinSingleAccuracy(SimdFloat x) * \attention Do NOT call both sin & cos if you need both results, since each of them * will then call \ref sincos and waste a factor 2 in performance. */ -static inline SimdFloat gmx_simdcall -cosSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall cosSingleAccuracy(SimdFloat x) { return cos(x); } @@ -5232,8 +5128,7 @@ cosSingleAccuracy(SimdFloat x) * \param x The argument to evaluate tan for * \result Tan(x) */ -static inline SimdFloat gmx_simdcall -tanSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall tanSingleAccuracy(SimdFloat x) { return tan(x); } @@ -5243,8 +5138,7 @@ tanSingleAccuracy(SimdFloat x) * \param x The argument to evaluate asin for * \result Asin(x) */ -static inline SimdFloat gmx_simdcall -asinSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall asinSingleAccuracy(SimdFloat x) { return asin(x); } @@ -5254,8 +5148,7 @@ asinSingleAccuracy(SimdFloat x) * \param x The argument to evaluate acos for * \result Acos(x) */ -static inline SimdFloat gmx_simdcall -acosSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall acosSingleAccuracy(SimdFloat x) { return acos(x); } @@ -5265,8 +5158,7 @@ acosSingleAccuracy(SimdFloat x) * \param x The argument to evaluate atan for * \result Atan(x), same argument/value range as standard math library. */ -static inline SimdFloat gmx_simdcall -atanSingleAccuracy(SimdFloat x) +static inline SimdFloat gmx_simdcall atanSingleAccuracy(SimdFloat x) { return atan(x); } @@ -5284,8 +5176,7 @@ atanSingleAccuracy(SimdFloat x) * of any concern in Gromacs, and in particular it will not affect calculations * of angles from vectors. */ -static inline SimdFloat gmx_simdcall -atan2SingleAccuracy(SimdFloat y, SimdFloat x) +static inline SimdFloat gmx_simdcall atan2SingleAccuracy(SimdFloat y, SimdFloat x) { return atan2(y, x); } @@ -5295,8 +5186,7 @@ atan2SingleAccuracy(SimdFloat y, SimdFloat x) * \param z2 \f$(r \beta)^2\f$ - see default single precision version for details. * \result Correction factor to coulomb force. */ -static inline SimdFloat gmx_simdcall -pmeForceCorrectionSingleAccuracy(SimdFloat z2) +static inline SimdFloat gmx_simdcall pmeForceCorrectionSingleAccuracy(SimdFloat z2) { return pmeForceCorrection(z2); } @@ -5306,14 +5196,13 @@ pmeForceCorrectionSingleAccuracy(SimdFloat z2) * \param z2 \f$(r \beta)^2\f$ - see default single precision version for details. * \result Correction factor to coulomb force. */ -static inline SimdFloat gmx_simdcall -pmePotentialCorrectionSingleAccuracy(SimdFloat z2) +static inline SimdFloat gmx_simdcall pmePotentialCorrectionSingleAccuracy(SimdFloat z2) { return pmePotentialCorrection(z2); } -#endif // GMX_SIMD_HAVE_FLOAT +# endif // GMX_SIMD_HAVE_FLOAT -#if GMX_SIMD4_HAVE_FLOAT +# if GMX_SIMD4_HAVE_FLOAT /*! \brief Calculate 1/sqrt(x) for SIMD4 float, only targeting single accuracy. * * \param x Argument that must be larger than GMX_FLOAT_MIN and smaller than @@ -5326,18 +5215,17 @@ pmePotentialCorrectionSingleAccuracy(SimdFloat z2) * check arguments. * \return 1/sqrt(x). Result is undefined if your argument was invalid. */ -static inline Simd4Float gmx_simdcall -invsqrtSingleAccuracy(Simd4Float x) +static inline Simd4Float gmx_simdcall invsqrtSingleAccuracy(Simd4Float x) { return invsqrt(x); } -#endif // GMX_SIMD4_HAVE_FLOAT +# endif // GMX_SIMD4_HAVE_FLOAT /*! \} end of addtogroup module_simd */ /*! \endcond end of condition libabl */ #endif // GMX_SIMD -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_SIMD_MATH_H diff --git a/src/gromacs/simd/simd_memory.h b/src/gromacs/simd/simd_memory.h index 089072cb04..0244284df9 100644 --- a/src/gromacs/simd/simd_memory.h +++ b/src/gromacs/simd/simd_memory.h @@ -53,110 +53,113 @@ namespace internal template class SimdReference { - private: - using non_const_T = std::remove_const_t; - using pointer = typename SimdTraits::type*; - public: - //! \brief Constructor - explicit SimdReference(pointer m) : m_(m) {} - //! \brief Conversion method that will execute load - operator non_const_T() const { return load(m_); } - //! \brief Assignment operator that will execute store - SimdReference operator=(T o) // NOLINT(misc-unconventional-assign-operator,cppcoreguidelines-c-copy-assignment-signature) - { - store(m_, o); - return *this; - } - //! \brief Addition assignment operator that will execute load+store - SimdReference operator+=(T o) - { - store(m_, load(m_) + o); - return *this; - } - //! \brief Subtraction assignment operator that will execute load+store - SimdReference operator-=(T o) - { - store(m_, load(m_) - o); - return *this; - } - //! \brief Multiplication assignment operator that will execute load+store - SimdReference operator*=(T o) - { - store(m_, load(m_) * o); - return *this; - } - private: - pointer const m_; //!< The pointer used to load memory +private: + using non_const_T = std::remove_const_t; + using pointer = typename SimdTraits::type*; + +public: + //! \brief Constructor + explicit SimdReference(pointer m) : m_(m) {} + //! \brief Conversion method that will execute load + operator non_const_T() const { return load(m_); } + //! \brief Assignment operator that will execute store + SimdReference operator=(T o) // NOLINT(misc-unconventional-assign-operator,cppcoreguidelines-c-copy-assignment-signature) + { + store(m_, o); + return *this; + } + //! \brief Addition assignment operator that will execute load+store + SimdReference operator+=(T o) + { + store(m_, load(m_) + o); + return *this; + } + //! \brief Subtraction assignment operator that will execute load+store + SimdReference operator-=(T o) + { + store(m_, load(m_) - o); + return *this; + } + //! \brief Multiplication assignment operator that will execute load+store + SimdReference operator*=(T o) + { + store(m_, load(m_) * o); + return *this; + } + +private: + pointer const m_; //!< The pointer used to load memory }; template class SimdIterator { - public: - //! Type for representing size of the container. - using size_type = size_t; - //! Type for representing difference between two container indices. - using difference_type = std::ptrdiff_t; - //! Type of values stored in the container. - using value_type = T; - //! Pointer to a container element. - using pointer = typename SimdTraits::type*; - //! Reference to a container element. - using reference = internal::SimdReference; +public: + //! Type for representing size of the container. + using size_type = size_t; + //! Type for representing difference between two container indices. + using difference_type = std::ptrdiff_t; + //! Type of values stored in the container. + using value_type = T; + //! Pointer to a container element. + using pointer = typename SimdTraits::type*; + //! Reference to a container element. + using reference = internal::SimdReference; - explicit SimdIterator(pointer p = 0) : p_(p) - { - GMX_ASSERT((reinterpret_cast(p)/sizeof(*p))%simdWidth == 0, - "Trying to create aligned iterator for non aligned address."); - } - SimdIterator &operator++() - { - p_ += simdWidth; - return *this; - } - SimdIterator operator++(int) - { - SimdIterator retval = *this; - ++(*this); - return retval; - } - SimdIterator &operator--() - { - p_ -= simdWidth; - return *this; - } - SimdIterator operator--(int) - { - SimdIterator retval = *this; - --(*this); - return retval; - } - SimdIterator &operator+=(difference_type d) - { - p_ += simdWidth * d; - return *this; - } - SimdIterator &operator-=(difference_type d) - { - p_ -= simdWidth * d; - return *this; - } - SimdIterator operator+(difference_type d) { return SimdIterator(p_ + simdWidth*d); } - SimdIterator operator-(difference_type d) { return SimdIterator(p_ - simdWidth*d); } + explicit SimdIterator(pointer p = 0) : p_(p) + { + GMX_ASSERT((reinterpret_cast(p) / sizeof(*p)) % simdWidth == 0, + "Trying to create aligned iterator for non aligned address."); + } + SimdIterator& operator++() + { + p_ += simdWidth; + return *this; + } + SimdIterator operator++(int) + { + SimdIterator retval = *this; + ++(*this); + return retval; + } + SimdIterator& operator--() + { + p_ -= simdWidth; + return *this; + } + SimdIterator operator--(int) + { + SimdIterator retval = *this; + --(*this); + return retval; + } + SimdIterator& operator+=(difference_type d) + { + p_ += simdWidth * d; + return *this; + } + SimdIterator& operator-=(difference_type d) + { + p_ -= simdWidth * d; + return *this; + } + SimdIterator operator+(difference_type d) { return SimdIterator(p_ + simdWidth * d); } + SimdIterator operator-(difference_type d) { return SimdIterator(p_ - simdWidth * d); } - difference_type operator-(SimdIterator o) { return (p_ - o.p_)/simdWidth; } + difference_type operator-(SimdIterator o) { return (p_ - o.p_) / simdWidth; } - bool operator==(SimdIterator other) const { return p_ == other.p_; } - bool operator!=(SimdIterator other) const { return p_ != other.p_; } - bool operator< (SimdIterator other) const { return p_ < other.p_; } - bool operator> (SimdIterator other) const { return p_ > other.p_; } - bool operator<=(SimdIterator other) const { return p_ <= other.p_; } - bool operator>=(SimdIterator other) const { return p_ >= other.p_; } + bool operator==(SimdIterator other) const { return p_ == other.p_; } + bool operator!=(SimdIterator other) const { return p_ != other.p_; } + bool operator<(SimdIterator other) const { return p_ < other.p_; } + bool operator>(SimdIterator other) const { return p_ > other.p_; } + bool operator<=(SimdIterator other) const { return p_ <= other.p_; } + bool operator>=(SimdIterator other) const { return p_ >= other.p_; } - reference operator*() const { return reference(p_); } - private: - pointer p_; - static constexpr int simdWidth = SimdTraits::width; + reference operator*() const { return reference(p_); } + +private: + pointer p_; + static constexpr int simdWidth = SimdTraits::width; }; /*! \internal @@ -176,79 +179,76 @@ class SimdIterator template class SimdArrayRef { - public: - //! Type for representing size of the container. - using size_type = size_t; - //! Type for representing difference between two container indices. - using difference_type = std::ptrdiff_t; - //! Type of values stored in the container. - using value_type = T; - //! Pointer to a container element. - using pointer = typename SimdTraits::type*; - //! Reference to a container element. - using reference = internal::SimdReference; - //! Iterator type for the container. - using iterator = SimdIterator; - //! Standard reverse iterator. - using reverse_iterator = std::reverse_iterator; +public: + //! Type for representing size of the container. + using size_type = size_t; + //! Type for representing difference between two container indices. + using difference_type = std::ptrdiff_t; + //! Type of values stored in the container. + using value_type = T; + //! Pointer to a container element. + using pointer = typename SimdTraits::type*; + //! Reference to a container element. + using reference = internal::SimdReference; + //! Iterator type for the container. + using iterator = SimdIterator; + //! Standard reverse iterator. + using reverse_iterator = std::reverse_iterator; + + //! \copydoc ArrayRef::ArrayRef(pointer, pointer) + SimdArrayRef(pointer begin, pointer end) : begin_(begin), end_(end) + { + GMX_ASSERT(end >= begin, "Invalid range"); + GMX_ASSERT((reinterpret_cast(begin) / sizeof(*begin)) % simdWidth == 0, + "Aligned ArrayRef requires aligned starting address"); + GMX_ASSERT((reinterpret_cast(end) / sizeof(*end)) % simdWidth == 0, + "Size of ArrayRef needs to be divisible by type size"); + } + //! \copydoc ArrayRef::ArrayRef(U) + template::pointer, pointer>::value>> + SimdArrayRef(U&& o) : + begin_(reinterpret_cast(o.data())), + end_(reinterpret_cast(o.data() + o.size())) + { + } + // reinterpret_cast is only needed for const conversion of SimdArrayRef itself. + // All other containers have type(o.data())==U::pointer (the cast does nothing). - //! \copydoc ArrayRef::ArrayRef(pointer, pointer) - SimdArrayRef(pointer begin, pointer end) - : begin_(begin), end_(end) - { - GMX_ASSERT(end >= begin, "Invalid range"); - GMX_ASSERT((reinterpret_cast(begin)/sizeof(*begin))%simdWidth == 0, - "Aligned ArrayRef requires aligned starting address"); - GMX_ASSERT((reinterpret_cast(end)/sizeof(*end))%simdWidth == 0, - "Size of ArrayRef needs to be divisible by type size"); - } - //! \copydoc ArrayRef::ArrayRef(U) - template::pointer, - pointer>::value> > - SimdArrayRef(U &&o) : begin_(reinterpret_cast(o.data())), - end_(reinterpret_cast(o.data()+o.size())) {} - //reinterpret_cast is only needed for const conversion of SimdArrayRef itself. - //All other containers have type(o.data())==U::pointer (the cast does nothing). + //! Returns the size of the container. + size_type size() const { return (end_ - begin_) / simdWidth; } + //! Whether the container is empty. + bool empty() const { return begin_ == end_; } + //! Returns an iterator to the beginning of the container. + iterator begin() const { return iterator(begin_); } + //! Returns an iterator to the end of the container. + iterator end() const { return iterator(end_); } - //! Returns the size of the container. - size_type size() const { return (end_-begin_)/simdWidth; } - //! Whether the container is empty. - bool empty() const { return begin_ == end_; } - //! Returns an iterator to the beginning of the container. - iterator begin() const { return iterator(begin_); } - //! Returns an iterator to the end of the container. - iterator end() const { return iterator(end_); } + //! Access container element. + reference operator[](size_type n) { return reference(begin_ + n * simdWidth); } - //! Access container element. - reference operator[](size_type n) - { - return reference(begin_+n*simdWidth); - } + //! Returns the first element in the container. + reference front() const { return reference(begin_); } + //! Returns the first element in the container. + reference back() const { return reference(end_ - simdWidth); } - //! Returns the first element in the container. - reference front() const { return reference(begin_); } - //! Returns the first element in the container. - reference back() const { return reference(end_ - simdWidth); } - private: - static constexpr int simdWidth = SimdTraits::width; - using pack_type = typename SimdTraits::type[simdWidth]; - // Private because dereferencing return value is undefined behavior (strict aliasing rule) - // Only use is conversion constructor above which immediately casts it back. - // Return type is not "pointer" because then data()+size() would be ill defined. - // Has to be pack_type and not value_type in case - // sizeof(value_type)/sizeof(pointer)!=simdWidth (e.g. int32 for double SSE2). - pack_type* data() const { return reinterpret_cast(begin_); } +private: + static constexpr int simdWidth = SimdTraits::width; + using pack_type = typename SimdTraits::type[simdWidth]; + // Private because dereferencing return value is undefined behavior (strict aliasing rule) + // Only use is conversion constructor above which immediately casts it back. + // Return type is not "pointer" because then data()+size() would be ill defined. + // Has to be pack_type and not value_type in case + // sizeof(value_type)/sizeof(pointer)!=simdWidth (e.g. int32 for double SSE2). + pack_type* data() const { return reinterpret_cast(begin_); } - template - friend class SimdArrayRef; + template + friend class SimdArrayRef; - pointer const begin_; - pointer const end_; + pointer const begin_; + pointer const end_; }; -} //namespace internal +} // namespace internal /* Specialize ArraryRef * So far only an aligned version is implemented. The constructor verifies that diff --git a/src/gromacs/simd/support.cpp b/src/gromacs/simd/support.cpp index 220b782cdb..7512e0e909 100644 --- a/src/gromacs/simd/support.cpp +++ b/src/gromacs/simd/support.cpp @@ -63,27 +63,25 @@ namespace gmx /*! \cond libapi */ -const std::string & -simdString(SimdType s) +const std::string& simdString(SimdType s) { - static const std::map name = - { - { SimdType::None, "None" }, - { SimdType::Reference, "Reference" }, - { SimdType::Generic, "Generic" }, - { SimdType::X86_Sse2, "SSE2" }, - { SimdType::X86_Sse4_1, "SSE4.1" }, - { SimdType::X86_Avx128Fma, "AVX_128_FMA" }, - { SimdType::X86_Avx, "AVX_256" }, - { SimdType::X86_Avx2, "AVX2_256" }, - { SimdType::X86_Avx2_128, "AVX2_128" }, - { SimdType::X86_Avx512, "AVX_512" }, - { SimdType::X86_Avx512Knl, "AVX_512_KNL" }, - { SimdType::X86_Mic, "X86_MIC" }, - { SimdType::Arm_Neon, "ARM_NEON" }, - { SimdType::Arm_NeonAsimd, "ARM_NEON_ASIMD" }, - { SimdType::Ibm_Vmx, "IBM_VMX" }, - { SimdType::Ibm_Vsx, "IBM_VSX" }, + static const std::map name = { + { SimdType::None, "None" }, + { SimdType::Reference, "Reference" }, + { SimdType::Generic, "Generic" }, + { SimdType::X86_Sse2, "SSE2" }, + { SimdType::X86_Sse4_1, "SSE4.1" }, + { SimdType::X86_Avx128Fma, "AVX_128_FMA" }, + { SimdType::X86_Avx, "AVX_256" }, + { SimdType::X86_Avx2, "AVX2_256" }, + { SimdType::X86_Avx2_128, "AVX2_128" }, + { SimdType::X86_Avx512, "AVX_512" }, + { SimdType::X86_Avx512Knl, "AVX_512_KNL" }, + { SimdType::X86_Mic, "X86_MIC" }, + { SimdType::Arm_Neon, "ARM_NEON" }, + { SimdType::Arm_NeonAsimd, "ARM_NEON_ASIMD" }, + { SimdType::Ibm_Vmx, "IBM_VMX" }, + { SimdType::Ibm_Vsx, "IBM_VSX" }, { SimdType::Fujitsu_HpcAce, "Fujitsu HPC-ACE" } }; @@ -95,8 +93,7 @@ namespace //! Helper to detect correct AMD Zen architecture. -bool -cpuIsAmdZen1(const CpuInfo &cpuInfo) +bool cpuIsAmdZen1(const CpuInfo& cpuInfo) { // Both Zen/Zen+/Zen2 have family==23 // Model numbers for Zen: @@ -105,17 +102,15 @@ cpuIsAmdZen1(const CpuInfo &cpuInfo) // Model numbers for Zen+: // 8) Pinnacle Ridge // 24) Picasso - return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && - cpuInfo.family() == 23 && - (cpuInfo.model() == 1 || cpuInfo.model() == 17 || - cpuInfo.model() == 8 || cpuInfo.model() == 24) ); + return (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && cpuInfo.family() == 23 + && (cpuInfo.model() == 1 || cpuInfo.model() == 17 || cpuInfo.model() == 8 + || cpuInfo.model() == 24)); } -} // namespace +} // namespace -SimdType -simdSuggested(const CpuInfo &c) +SimdType simdSuggested(const CpuInfo& c) { SimdType suggested = SimdType::None; @@ -131,7 +126,7 @@ simdSuggested(const CpuInfo &c) else if (c.feature(CpuInfo::Feature::X86_Avx512F)) { // If we could not identify the number of AVX512 FMA units we assume 2 - suggested = ( identifyAvx512FmaUnits() == 1 ) ? SimdType::X86_Avx2 : SimdType::X86_Avx512; + suggested = (identifyAvx512FmaUnits() == 1) ? SimdType::X86_Avx2 : SimdType::X86_Avx512; } else if (c.feature(CpuInfo::Feature::X86_Avx2)) { @@ -209,15 +204,13 @@ simdSuggested(const CpuInfo &c) suggested = SimdType::Fujitsu_HpcAce; } break; - default: - break; + default: break; } } return suggested; } -SimdType -simdCompiled() +SimdType simdCompiled() { #if GMX_SIMD_X86_AVX_512_KNL return SimdType::X86_Avx512Knl; @@ -254,12 +247,9 @@ simdCompiled() #endif } -bool -simdCheck(gmx::SimdType wanted, - FILE * log, - bool warnToStdErr) +bool simdCheck(gmx::SimdType wanted, FILE* log, bool warnToStdErr) { - SimdType compiled = simdCompiled(); + SimdType compiled = simdCompiled(); gmx::TextLineWrapper wrapper; std::string logMsg; @@ -269,29 +259,34 @@ simdCheck(gmx::SimdType wanted, if (compiled == SimdType::X86_Avx2 && wanted == SimdType::X86_Avx512) { - logMsg = wrapper.wrapToString(formatString("Highest SIMD level requested by all nodes in run: %s\n" - "SIMD instructions selected at compile time: %s\n" - "This program was compiled for different hardware than you are running on, " - "which could influence performance. This build might have been configured on " - "a login node with only a single AVX-512 FMA unit (in which case AVX2 is faster), " - "while the node you are running on has dual AVX-512 FMA units.", - simdString(wanted).c_str(), simdString(compiled).c_str())); - warnMsg = wrapper.wrapToString(formatString("Compiled SIMD: %s, but for this host/run %s might be better (see log).", - simdString(compiled).c_str(), simdString(wanted).c_str())); + logMsg = wrapper.wrapToString(formatString( + "Highest SIMD level requested by all nodes in run: %s\n" + "SIMD instructions selected at compile time: %s\n" + "This program was compiled for different hardware than you are running on, " + "which could influence performance. This build might have been configured on " + "a login node with only a single AVX-512 FMA unit (in which case AVX2 is faster), " + "while the node you are running on has dual AVX-512 FMA units.", + simdString(wanted).c_str(), simdString(compiled).c_str())); + warnMsg = wrapper.wrapToString(formatString( + "Compiled SIMD: %s, but for this host/run %s might be better (see log).", + simdString(compiled).c_str(), simdString(wanted).c_str())); } - else if (compiled == SimdType::X86_Avx512 && wanted == SimdType::X86_Avx2 && identifyAvx512FmaUnits() == 1) + else if (compiled == SimdType::X86_Avx512 && wanted == SimdType::X86_Avx2 + && identifyAvx512FmaUnits() == 1) { // The reason for explicitly checking the number of FMA units above is to avoid triggering // this conditional if the AVX2 SIMD was requested by some other node in a heterogeneous MPI run. - logMsg = wrapper.wrapToString(formatString("Highest SIMD level requested by all nodes in run: %s\n" - "SIMD instructions selected at compile time: %s\n" - "This program was compiled for different hardware than you are running on, " - "which could influence performance." - "This host supports AVX-512, but since it only has 1 AVX-512" - "FMA unit, it would be faster to use AVX2 instead.", - simdString(wanted).c_str(), simdString(compiled).c_str())); - warnMsg = wrapper.wrapToString(formatString("Compiled SIMD: %s, but for this host/run %s might be better (see log).", - simdString(compiled).c_str(), simdString(wanted).c_str())); + logMsg = wrapper.wrapToString(formatString( + "Highest SIMD level requested by all nodes in run: %s\n" + "SIMD instructions selected at compile time: %s\n" + "This program was compiled for different hardware than you are running on, " + "which could influence performance." + "This host supports AVX-512, but since it only has 1 AVX-512" + "FMA unit, it would be faster to use AVX2 instead.", + simdString(wanted).c_str(), simdString(compiled).c_str())); + warnMsg = wrapper.wrapToString(formatString( + "Compiled SIMD: %s, but for this host/run %s might be better (see log).", + simdString(compiled).c_str(), simdString(wanted).c_str())); } else if (compiled == SimdType::X86_Avx2 && wanted == SimdType::X86_Avx2_128) { @@ -305,22 +300,25 @@ simdCheck(gmx::SimdType wanted, // Normally it is close to catastrophic if the compiled SIMD type is larger than // the supported one, but AVX128Fma is an exception: AMD CPUs will (strongly) prefer // AVX128Fma, but they will work fine with AVX too. Thus, make an exception for this. - logMsg = wrapper.wrapToString(formatString("Highest SIMD level requested by all nodes in run: %s\n" - "SIMD instructions selected at compile time: %s\n" - "Compiled SIMD newer than requested; program might crash.", - simdString(wanted).c_str(), simdString(compiled).c_str())); + logMsg = wrapper.wrapToString( + formatString("Highest SIMD level requested by all nodes in run: %s\n" + "SIMD instructions selected at compile time: %s\n" + "Compiled SIMD newer than requested; program might crash.", + simdString(wanted).c_str(), simdString(compiled).c_str())); warnMsg = logMsg; } else if (wanted != compiled) { // This warning will also occur if compiled is X86_Avx and wanted is X86_Avx128Fma - logMsg = wrapper.wrapToString(formatString("Highest SIMD level requested by all nodes in run: %s\n" - "SIMD instructions selected at compile time: %s\n" - "This program was compiled for different hardware than you are running on, " - "which could influence performance.", - simdString(wanted).c_str(), simdString(compiled).c_str())); - warnMsg = wrapper.wrapToString(formatString("Compiled SIMD: %s, but for this host/run %s might be better (see log).", - simdString(compiled).c_str(), simdString(wanted).c_str())); + logMsg = wrapper.wrapToString(formatString( + "Highest SIMD level requested by all nodes in run: %s\n" + "SIMD instructions selected at compile time: %s\n" + "This program was compiled for different hardware than you are running on, " + "which could influence performance.", + simdString(wanted).c_str(), simdString(compiled).c_str())); + warnMsg = wrapper.wrapToString(formatString( + "Compiled SIMD: %s, but for this host/run %s might be better (see log).", + simdString(compiled).c_str(), simdString(wanted).c_str())); } if (!logMsg.empty() && log != nullptr) @@ -337,4 +335,4 @@ simdCheck(gmx::SimdType wanted, /*! \endcond */ -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/simd/support.h b/src/gromacs/simd/support.h index 44a84dbf85..1fd891658d 100644 --- a/src/gromacs/simd/support.h +++ b/src/gromacs/simd/support.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,39 +56,36 @@ namespace gmx /*! \brief Enumerated options for SIMD architectures */ enum class SimdType { - None, //!< Disable all SIMD support - Reference, //!< Gromacs reference software SIMD - Generic, //!< Placeholder for future support for gcc generic SIMD - X86_Sse2, //!< SSE2 - X86_Sse4_1, //!< SSE4.1 - X86_Avx128Fma, //!< 128-bit Avx with FMA (Amd) - X86_Avx, //!< 256-bit Avx - X86_Avx2, //!< AVX2 - X86_Avx2_128, //!< 128-bit AVX2, better than 256-bit for AMD Ryzen - X86_Avx512, //!< AVX_512 - X86_Avx512Knl, //!< AVX_512_KNL - X86_Mic, //!< Knight's corner - Arm_Neon, //!< 32-bit ARM NEON - Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD - Ibm_Vmx, //!< IBM VMX SIMD (Altivec on Power6 and later) - Ibm_Vsx, //!< IBM VSX SIMD (Power7 and later) - Fujitsu_HpcAce //!< Fujitsu K-computer + None, //!< Disable all SIMD support + Reference, //!< Gromacs reference software SIMD + Generic, //!< Placeholder for future support for gcc generic SIMD + X86_Sse2, //!< SSE2 + X86_Sse4_1, //!< SSE4.1 + X86_Avx128Fma, //!< 128-bit Avx with FMA (Amd) + X86_Avx, //!< 256-bit Avx + X86_Avx2, //!< AVX2 + X86_Avx2_128, //!< 128-bit AVX2, better than 256-bit for AMD Ryzen + X86_Avx512, //!< AVX_512 + X86_Avx512Knl, //!< AVX_512_KNL + X86_Mic, //!< Knight's corner + Arm_Neon, //!< 32-bit ARM NEON + Arm_NeonAsimd, //!< 64-bit ARM AArch64 Advanced SIMD + Ibm_Vmx, //!< IBM VMX SIMD (Altivec on Power6 and later) + Ibm_Vsx, //!< IBM VSX SIMD (Power7 and later) + Fujitsu_HpcAce //!< Fujitsu K-computer }; /*! \libinternal \brief Return a string with the name of a SIMD type * * \param s SIMD type to turn into string */ -const std::string & -simdString(SimdType s); +const std::string& simdString(SimdType s); /*! \libinternal \brief Return the SIMD type that would fit this hardware best */ -SimdType -simdSuggested(const CpuInfo &c); +SimdType simdSuggested(const CpuInfo& c); /*! \libinternal \brief Return the SIMD type the library was compiled with */ -SimdType -simdCompiled(); +SimdType simdCompiled(); /*! \libinternal \brief Check if binary was compiled with the provided SIMD type * @@ -98,10 +95,7 @@ simdCompiled(); * If we do not have a match there will also be a warning. * \param warnToStdErr If true, warnings will also be printed to stderr. */ -bool -simdCheck(SimdType s, - FILE * log, - bool warnToStdErr); +bool simdCheck(SimdType s, FILE* log, bool warnToStdErr); /*! \endcond */ diff --git a/src/gromacs/simd/tests/base.cpp b/src/gromacs/simd/tests/base.cpp index d7d13c0ad5..88015754b1 100644 --- a/src/gromacs/simd/tests/base.cpp +++ b/src/gromacs/simd/tests/base.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,33 +58,36 @@ namespace GMX_TEST_OPTIONS(SimdBaseTestOptions, options) { options->addOption(::gmx::IntegerOption("npoints") - .store(&SimdBaseTest::s_nPoints) - .description("Number of points to test for SIMD math functions")); + .store(&SimdBaseTest::s_nPoints) + .description("Number of points to test for SIMD math functions")); } /*! \endcond */ -} // namespace +} // namespace /*! \cond internal */ /*! \addtogroup module_simd */ /*! \{ */ -int SimdBaseTest::s_nPoints = 10000; +int SimdBaseTest::s_nPoints = 10000; -::testing::AssertionResult -SimdBaseTest::compareVectorRealUlp(const char * refExpr, const char * tstExpr, - const std::vector &ref, const std::vector &tst) +::testing::AssertionResult SimdBaseTest::compareVectorRealUlp(const char* refExpr, + const char* tstExpr, + const std::vector& ref, + const std::vector& tst) { - std::vector absDiff(tst.size()); - std::vector ulpDiff(tst.size()); - bool allOk; - size_t i; + std::vector absDiff(tst.size()); + std::vector ulpDiff(tst.size()); + bool allOk; + size_t i; union { #if GMX_DOUBLE - double r; std::int64_t i; + double r; + std::int64_t i; #else - float r; std::int32_t i; + float r; + std::int32_t i; #endif } conv0, conv1; @@ -97,13 +100,13 @@ SimdBaseTest::compareVectorRealUlp(const char * refExpr, const char * tstExpr, for (i = 0, allOk = true; i < tst.size(); i++) { - absDiff[i] = std::abs(ref[i]-tst[i]); - conv0.r = ref[i]; - conv1.r = tst[i]; - ulpDiff[i] = llabs(conv0.i-conv1.i); + absDiff[i] = std::abs(ref[i] - tst[i]); + conv0.r = ref[i]; + conv1.r = tst[i]; + ulpDiff[i] = llabs(conv0.i - conv1.i); /* Use strict smaller-than for absolute tolerance check, so we disable it with absTol_=0 */ - allOk = allOk && ( ( absDiff[i] < absTol_ ) || ( ( ref[i]*tst[i] >= 0 ) && (ulpDiff[i] <= ulpTol_) ) ); + allOk = allOk && ((absDiff[i] < absTol_) || ((ref[i] * tst[i] >= 0) && (ulpDiff[i] <= ulpTol_))); } if (allOk) @@ -127,5 +130,5 @@ SimdBaseTest::compareVectorRealUlp(const char * refExpr, const char * tstExpr, /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/simd/tests/base.h b/src/gromacs/simd/tests/base.h index 04d8c07737..5b17e771f1 100644 --- a/src/gromacs/simd/tests/base.h +++ b/src/gromacs/simd/tests/base.h @@ -70,7 +70,8 @@ namespace test { //! \internal \brief Test-time utility macro for current precision accuracy -#define GMX_SIMD_ACCURACY_BITS_REAL (GMX_DOUBLE ? GMX_SIMD_ACCURACY_BITS_DOUBLE : GMX_SIMD_ACCURACY_BITS_SINGLE) +#define GMX_SIMD_ACCURACY_BITS_REAL \ + (GMX_DOUBLE ? GMX_SIMD_ACCURACY_BITS_DOUBLE : GMX_SIMD_ACCURACY_BITS_SINGLE) /*! \internal * \brief @@ -84,126 +85,125 @@ namespace test */ class SimdBaseTest : public ::testing::Test { - public: - /*! \brief Return the default ulp tolerance for current precision - */ - static constexpr std::int64_t - defaultRealUlpTol() +public: + /*! \brief Return the default ulp tolerance for current precision + */ + static constexpr std::int64_t defaultRealUlpTol() + { + return (1LL << (2 + std::numeric_limits::digits - GMX_SIMD_ACCURACY_BITS_REAL)); + } + + /*! \brief Initialize new SIMD test fixture with default tolerances. + * + * The default absolute tolerance is set to 0, which means the we always + * check the ulp tolerance by default (passing the absolute tolerance + * test would otherwise mean we approve the test instantly). + * + * The default ulp tolerance is set based on the target number of + * bits requested for single or double precision, depending on what + * the default Gromacs precision is. We add two bits to avoid + * tests failing due to corner cases where compiler optimization might + * cause a slight precision loss e.g. for very small numbers. + * + * Most SIMD math functions actually achieve 2-3 ulp accuracy in single, + * but by being a bit liberal we only catch real errors rather than + * doing compiler-standard-compliance debugging. + * + * The range is used by derived classes to test math functions. The + * default test range will be [1,10], which is intentionally + * conservative so it works with (inverse) square root, division, + * exponentials, logarithms, and error functions. + */ + SimdBaseTest() : ulpTol_(defaultRealUlpTol()), absTol_(0) {} + + /*! \brief Adjust ulp tolerance from the default 10 (float) or 255 (double). */ + void setUlpTol(std::int64_t newTol) { ulpTol_ = newTol; } + + /*! \brief Adjust ulp tolerance for single accuracy functions. */ + void setUlpTolSingleAccuracy(std::int64_t newTol) + { + const int realBits = std::numeric_limits::digits; + const int singleBits = std::numeric_limits::digits; + // In single precision the expression (1LL << 0) evaluates to 1. + setUlpTol(newTol * (1LL << (realBits - singleBits))); + } + + /*! \brief Adjust the absolute tolerance from the default 0. + * + * If values are closer than the absolute tolerance, the test will pass + * no matter what their ulp difference is. + */ + void setAbsTol(real newTol) { absTol_ = newTol; } + + /*! \brief Number of test points to use, settable on command line. + * + * \note While this has to be a static non-const variable for the + * command-line option to work, you should never change it + * manually in any of the tests, because the static storage + * class will make the value apply to all subsequent tests + * unless you remember to reset it. + */ + static int s_nPoints; + + /*! \brief Compare two std::vector for approximate equality. + * + * This is an internal implementation routine that will be used by + * routines in derived child classes that first convert SIMD or SIMD4 + * variables to std::vector. Do not call it directly. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the vector test variable is within the class tolerances of the corresponding + * reference elements. + */ + ::testing::AssertionResult compareVectorRealUlp(const char* refExpr, + const char* tstExpr, + const std::vector& ref, + const std::vector& tst); + + /*! \brief Compare std::vectors for exact equality. + * + * The template in this class makes it usable for testing both + * SIMD floating-point and integers variables, after conversion to + * vectors. + * This is an internal implementation routine that will be used by + * routines in derived child classes that first convert SIMD or SIMD4 + * variables to std::vector. Do not call it directly. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the vector test variable is within the class tolerances of the corresponding + * reference elements. + */ + template + ::testing::AssertionResult compareVectorEq(const char* refExpr, + const char* tstExpr, + const std::vector& ref, + const std::vector& tst) + { + if (ref == tst) { - return (1LL << (2 + std::numeric_limits::digits-GMX_SIMD_ACCURACY_BITS_REAL)); + return ::testing::AssertionSuccess(); } - - /*! \brief Initialize new SIMD test fixture with default tolerances. - * - * The default absolute tolerance is set to 0, which means the we always - * check the ulp tolerance by default (passing the absolute tolerance - * test would otherwise mean we approve the test instantly). - * - * The default ulp tolerance is set based on the target number of - * bits requested for single or double precision, depending on what - * the default Gromacs precision is. We add two bits to avoid - * tests failing due to corner cases where compiler optimization might - * cause a slight precision loss e.g. for very small numbers. - * - * Most SIMD math functions actually achieve 2-3 ulp accuracy in single, - * but by being a bit liberal we only catch real errors rather than - * doing compiler-standard-compliance debugging. - * - * The range is used by derived classes to test math functions. The - * default test range will be [1,10], which is intentionally - * conservative so it works with (inverse) square root, division, - * exponentials, logarithms, and error functions. - */ - SimdBaseTest() : - ulpTol_(defaultRealUlpTol()), absTol_(0) - { - } - - /*! \brief Adjust ulp tolerance from the default 10 (float) or 255 (double). */ - void setUlpTol(std::int64_t newTol) { ulpTol_ = newTol; } - - /*! \brief Adjust ulp tolerance for single accuracy functions. */ - void setUlpTolSingleAccuracy(std::int64_t newTol) - { - const int realBits = std::numeric_limits::digits; - const int singleBits = std::numeric_limits::digits; - // In single precision the expression (1LL << 0) evaluates to 1. - setUlpTol(newTol * (1LL << (realBits - singleBits))); - } - - /*! \brief Adjust the absolute tolerance from the default 0. - * - * If values are closer than the absolute tolerance, the test will pass - * no matter what their ulp difference is. - */ - void setAbsTol(real newTol) { absTol_ = newTol; } - - /*! \brief Number of test points to use, settable on command line. - * - * \note While this has to be a static non-const variable for the - * command-line option to work, you should never change it - * manually in any of the tests, because the static storage - * class will make the value apply to all subsequent tests - * unless you remember to reset it. - */ - static int s_nPoints; - - /*! \brief Compare two std::vector for approximate equality. - * - * This is an internal implementation routine that will be used by - * routines in derived child classes that first convert SIMD or SIMD4 - * variables to std::vector. Do not call it directly. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the vector test variable is within the class tolerances of the corresponding - * reference elements. - */ - ::testing::AssertionResult - compareVectorRealUlp(const char * refExpr, const char * tstExpr, - const std::vector &ref, const std::vector &tst); - - /*! \brief Compare std::vectors for exact equality. - * - * The template in this class makes it usable for testing both - * SIMD floating-point and integers variables, after conversion to - * vectors. - * This is an internal implementation routine that will be used by - * routines in derived child classes that first convert SIMD or SIMD4 - * variables to std::vector. Do not call it directly. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the vector test variable is within the class tolerances of the corresponding - * reference elements. - */ - template ::testing::AssertionResult - compareVectorEq(const char * refExpr, const char * tstExpr, - const std::vector &ref, const std::vector &tst) + else { - if (ref == tst) - { - return ::testing::AssertionSuccess(); - } - else - { - return ::testing::AssertionFailure() - << "Failing SIMD comparison between " << refExpr << " and " << tstExpr << std::endl - << "Ref. values: " << ::testing::PrintToString(ref) << std::endl - << "Test values: " << ::testing::PrintToString(tst) << std::endl; - } + return ::testing::AssertionFailure() + << "Failing SIMD comparison between " << refExpr << " and " << tstExpr << std::endl + << "Ref. values: " << ::testing::PrintToString(ref) << std::endl + << "Test values: " << ::testing::PrintToString(tst) << std::endl; } + } - protected: - std::int64_t ulpTol_; //!< Current tolerance in units-in-last-position. - real absTol_; //!< Current absolute tolerance. +protected: + std::int64_t ulpTol_; //!< Current tolerance in units-in-last-position. + real absTol_; //!< Current absolute tolerance. }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD_TESTS_BASE_H diff --git a/src/gromacs/simd/tests/bootstrap_loadstore.cpp b/src/gromacs/simd/tests/bootstrap_loadstore.cpp index bb9307f3c7..52ba8e396b 100644 --- a/src/gromacs/simd/tests/bootstrap_loadstore.cpp +++ b/src/gromacs/simd/tests/bootstrap_loadstore.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -82,42 +82,45 @@ namespace * real and int are pretty much similar, so we use a template function with * additional function pointers for the actual load/store calls. */ -template void -loadStoreTester(TSimd gmx_simdcall loadFn(const T* mem), void gmx_simdcall storeFn(T* mem, TSimd), - const int loadOffset, const int storeOffset) +template +void loadStoreTester(TSimd gmx_simdcall loadFn(const T* mem), + void gmx_simdcall storeFn(T* mem, TSimd), + const int loadOffset, + const int storeOffset) { /* We need simdWidth storage in the first place, another simdWidth elements * so we can create (deliberately) offset un-aligned pointers, and finally * simdWidth elements at the beginning and end * to test we are not polluting memory there either. Sum=4*simdWidth. */ - alignas(GMX_SIMD_ALIGNMENT) T src[simdWidth*4]; - alignas(GMX_SIMD_ALIGNMENT) T dst[simdWidth*4]; + alignas(GMX_SIMD_ALIGNMENT) T src[simdWidth * 4]; + alignas(GMX_SIMD_ALIGNMENT) T dst[simdWidth * 4]; // Make sure we have memory to check both before and after the test pointers - T * pCopySrc = src + simdWidth + loadOffset; - T * pCopyDst = dst + simdWidth + storeOffset; - int i; + T* pCopySrc = src + simdWidth + loadOffset; + T* pCopyDst = dst + simdWidth + storeOffset; + int i; - for (i = 0; i < simdWidth*4; i++) + for (i = 0; i < simdWidth * 4; i++) { - src[i] = 1+i; - dst[i] = -1-i; + src[i] = 1 + i; + dst[i] = -1 - i; } storeFn(pCopyDst, loadFn(pCopySrc)); for (i = 0; i < simdWidth; i++) { - EXPECT_EQ(pCopySrc[i], pCopyDst[i]) << "SIMD load or store not moving data correctly for element " << i; + EXPECT_EQ(pCopySrc[i], pCopyDst[i]) + << "SIMD load or store not moving data correctly for element " << i; } - for (i = 0; i < simdWidth*4; i++) + for (i = 0; i < simdWidth * 4; i++) { - EXPECT_EQ(src[i], (T)(1+i)) << "Side effect on source memory, i = " << i; - if (dst+i < pCopyDst || dst+i >= pCopyDst+simdWidth) + EXPECT_EQ(src[i], (T)(1 + i)) << "Side effect on source memory, i = " << i; + if (dst + i < pCopyDst || dst + i >= pCopyDst + simdWidth) { - EXPECT_EQ(dst[i], (T)(-1-i)) << "Side effect on destination memory, i = " << i; + EXPECT_EQ(dst[i], (T)(-1 - i)) << "Side effect on destination memory, i = " << i; } } } @@ -128,8 +131,11 @@ loadStoreTester(TSimd gmx_simdcall loadFn(const T* mem), void gmx_simdcall store * \tparam TSimd Corresponding SIMD type * \param m Memory address to load from */ -template TSimd gmx_simdcall -loadWrapper(const T * m) { return load(m); } +template +TSimd gmx_simdcall loadWrapper(const T* m) +{ + return load(m); +} /*! \brief Wrapper to handle proxy objects returned by some loadU functions. * @@ -137,17 +143,20 @@ loadWrapper(const T * m) { return load(m); } * \tparam TSimd Corresponding SIMD type * \param m Memory address to load from */ -template TSimd gmx_simdcall -loadUWrapper(const T * m) { return loadU(m); } +template +TSimd gmx_simdcall loadUWrapper(const T* m) +{ + return loadU(m); +} -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL TEST(SimdBootstrapTest, loadStore) { loadStoreTester(loadWrapper, store, 0, 0); } -# if GMX_SIMD_HAVE_LOADU +# if GMX_SIMD_HAVE_LOADU TEST(SimdBootstrapTest, loadU) { for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -155,9 +164,9 @@ TEST(SimdBootstrapTest, loadU) loadStoreTester(loadUWrapper, store, i, 0); } } -# endif // GMX_SIMD_HAVE_LOADU +# endif // GMX_SIMD_HAVE_LOADU -# if GMX_SIMD_HAVE_STOREU +# if GMX_SIMD_HAVE_STOREU TEST(SimdBootstrapTest, storeU) { for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -165,7 +174,7 @@ TEST(SimdBootstrapTest, storeU) loadStoreTester(loadWrapper, storeU, 0, i); } } -# endif // GMX_SIMD_HAVE_STOREU +# endif // GMX_SIMD_HAVE_STOREU // Tests for SimdInt32 load & store operations TEST(SimdBootstrapTest, loadStoreI) @@ -173,7 +182,7 @@ TEST(SimdBootstrapTest, loadStoreI) loadStoreTester(loadWrapper, store, 0, 0); } -# if GMX_SIMD_HAVE_LOADU +# if GMX_SIMD_HAVE_LOADU TEST(SimdBootstrapTest, loadUI) { for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -181,9 +190,9 @@ TEST(SimdBootstrapTest, loadUI) loadStoreTester(loadUWrapper, store, i, 0); } } -# endif // GMX_SIMD_HAVE_LOADU +# endif // GMX_SIMD_HAVE_LOADU -# if GMX_SIMD_HAVE_STOREU +# if GMX_SIMD_HAVE_STOREU TEST(SimdBootstrapTest, storeUI) { for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -191,16 +200,16 @@ TEST(SimdBootstrapTest, storeUI) loadStoreTester(loadWrapper, storeU, 0, i); } } -# endif // GMX_SIMD_HAVE_STOREU -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_STOREU +# endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD4_HAVE_REAL +# if GMX_SIMD4_HAVE_REAL TEST(SimdBootstrapTest, simd4LoadStore) { loadStoreTester(load4, store4, 0, 0); } -# if GMX_SIMD_HAVE_LOADU +# if GMX_SIMD_HAVE_LOADU TEST(SimdBootstrapTest, simd4LoadU) { for (int i = 0; i < GMX_SIMD4_WIDTH; i++) @@ -208,9 +217,9 @@ TEST(SimdBootstrapTest, simd4LoadU) loadStoreTester(load4U, store4, i, 0); } } -# endif // GMX_SIMD_HAVE_LOADU +# endif // GMX_SIMD_HAVE_LOADU -# if GMX_SIMD_HAVE_STOREU +# if GMX_SIMD_HAVE_STOREU TEST(SimdBootstrapTest, simd4StoreU) { for (int i = 0; i < GMX_SIMD4_WIDTH; i++) @@ -218,16 +227,16 @@ TEST(SimdBootstrapTest, simd4StoreU) loadStoreTester(load4, store4U, 0, i); } } -# endif // GMX_SIMD_HAVE_STOREU -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD_HAVE_STOREU +# endif // GMX_SIMD4_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace +} // namespace -} // namespace test +} // namespace test -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/data.h b/src/gromacs/simd/tests/data.h index c6c21a6e07..52b36e15b8 100644 --- a/src/gromacs/simd/tests/data.h +++ b/src/gromacs/simd/tests/data.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,7 +75,7 @@ constexpr real c8 = 8.967213114754099; //!< test constant 8.0 + 59.0/61.0 /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/gromacs/simd/tests/scalar.cpp b/src/gromacs/simd/tests/scalar.cpp index 9ae28508eb..4eb3d30a4d 100644 --- a/src/gromacs/simd/tests/scalar.cpp +++ b/src/gromacs/simd/tests/scalar.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -111,40 +111,40 @@ TEST(SimdScalarTest, andNot) TEST(SimdScalarTest, fma) { - EXPECT_REAL_EQ_TOL(c1*c2+c3, fma(real(c1), real(c2), real(c3)), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(c1 * c2 + c3, fma(real(c1), real(c2), real(c3)), defaultRealTolerance()); } TEST(SimdScalarTest, fms) { - EXPECT_REAL_EQ_TOL(c1*c2-c3, fms(c1, c2, c3), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(c1 * c2 - c3, fms(c1, c2, c3), defaultRealTolerance()); } TEST(SimdScalarTest, fnma) { - EXPECT_REAL_EQ_TOL(-c1*c2+c3, fnma(c1, c2, c3), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(-c1 * c2 + c3, fnma(c1, c2, c3), defaultRealTolerance()); } TEST(SimdScalarTest, fnms) { - EXPECT_REAL_EQ_TOL(-c1*c2-c3, fnms(c1, c2, c3), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(-c1 * c2 - c3, fnms(c1, c2, c3), defaultRealTolerance()); } TEST(SimdScalarTest, maskAdd) { EXPECT_REAL_EQ_TOL(c1, maskAdd(c1, c2, false), defaultRealTolerance()); - EXPECT_REAL_EQ_TOL(c1+c2, maskAdd(c1, c2, true), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(c1 + c2, maskAdd(c1, c2, true), defaultRealTolerance()); } TEST(SimdScalarTest, maskzMul) { EXPECT_REAL_EQ_TOL(czero, maskzMul(c1, c2, false), defaultRealTolerance()); - EXPECT_REAL_EQ_TOL(c1*c2, maskzMul(c1, c2, true), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(c1 * c2, maskzMul(c1, c2, true), defaultRealTolerance()); } TEST(SimdScalarTest, maskzFma) { EXPECT_REAL_EQ_TOL(czero, maskzFma(c1, c2, c3, false), defaultRealTolerance()); - EXPECT_REAL_EQ_TOL(c1*c2+c3, maskzFma(c1, c2, c3, true), defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(c1 * c2 + c3, maskzFma(c1, c2, c3, true), defaultRealTolerance()); } TEST(SimdScalarTest, abs) @@ -290,8 +290,7 @@ TEST(SimdScalarTest, storeUI) TEST(SimdScalarTest, andNotI) { - EXPECT_EQ(std::int32_t(0x0C0C0C0C), - andNot(std::int32_t(0xF0F0F0F0), std::int32_t(0xCCCCCCCC))); + EXPECT_EQ(std::int32_t(0x0C0C0C0C), andNot(std::int32_t(0xF0F0F0F0), std::int32_t(0xCCCCCCCC))); } TEST(SimdScalarTest, testBitsI) @@ -333,6 +332,6 @@ TEST(SimdScalarTest, cvtIB2B) /*! \} */ /*! \endcond internal */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/simd/tests/scalar_math.cpp b/src/gromacs/simd/tests/scalar_math.cpp index 557ff3085a..556e5b4205 100644 --- a/src/gromacs/simd/tests/scalar_math.cpp +++ b/src/gromacs/simd/tests/scalar_math.cpp @@ -89,7 +89,7 @@ TEST(SimdScalarMathTest, inv) { real x0 = c0; - EXPECT_EQ(real(1.0)/x0, inv(x0)); + EXPECT_EQ(real(1.0) / x0, inv(x0)); } TEST(SimdScalarMathTest, maskzInvsqrt) @@ -204,13 +204,13 @@ TEST(SimdScalarMathTest, pmeForceCorrection) // Calculate reference value for z2!=0 real z = std::sqrt(z2); - real ref = 2.0*std::exp(-z2)/(std::sqrt(M_PI)*z2) - std::erf(z)/(z2*z); + real ref = 2.0 * std::exp(-z2) / (std::sqrt(M_PI) * z2) - std::erf(z) / (z2 * z); // Pme correction only needs to be ~1e-6 accuracy single, 1e-10 double #if GMX_DOUBLE - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-10)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-10)); #else - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); #endif EXPECT_REAL_EQ_TOL(ref, pmeForceCorrection(z2), tolerance); @@ -222,13 +222,13 @@ TEST(SimdScalarMathTest, pmePotentialCorrection) // Calculate reference value for z2!=0 real z = std::sqrt(z2); - real ref = std::erf(z)/z; + real ref = std::erf(z) / z; // Pme correction only needs to be ~1e-6 accuracy single, 1e-10 double #if GMX_DOUBLE - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-10)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-10)); #else - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); #endif EXPECT_REAL_EQ_TOL(ref, pmePotentialCorrection(z2), tolerance); @@ -255,42 +255,36 @@ TEST(SimdScalarMathTest, invSingleAccuracy) { double x0 = c1; - EXPECT_EQ(1.0F/static_cast(x0), - static_cast(invSingleAccuracy(x0))); + EXPECT_EQ(1.0F / static_cast(x0), static_cast(invSingleAccuracy(x0))); } TEST(SimdScalarMathTest, maskzInvsqrtSingleAccuracy) { double x0 = c1; - EXPECT_EQ(invsqrt(static_cast(x0)), - static_cast(maskzInvsqrtSingleAccuracy(x0, true))); - EXPECT_EQ(0.0F, - static_cast(maskzInvsqrtSingleAccuracy(x0, false))); + EXPECT_EQ(invsqrt(static_cast(x0)), static_cast(maskzInvsqrtSingleAccuracy(x0, true))); + EXPECT_EQ(0.0F, static_cast(maskzInvsqrtSingleAccuracy(x0, false))); } TEST(SimdScalarMathTest, logSingleAccuracy) { double x0 = c1; - EXPECT_EQ(std::log(static_cast(x0)), - static_cast(logSingleAccuracy(x0))); + EXPECT_EQ(std::log(static_cast(x0)), static_cast(logSingleAccuracy(x0))); } TEST(SimdScalarMathTest, exp2SingleAccuracy) { double x0 = c1; - EXPECT_EQ(std::exp2(static_cast(x0)), - static_cast(exp2SingleAccuracy(x0))); + EXPECT_EQ(std::exp2(static_cast(x0)), static_cast(exp2SingleAccuracy(x0))); } TEST(SimdScalarMathTest, expSingleAccuracy) { double x0 = c1; - EXPECT_EQ(std::exp(static_cast(x0)), - static_cast(expSingleAccuracy(x0))); + EXPECT_EQ(std::exp(static_cast(x0)), static_cast(expSingleAccuracy(x0))); } TEST(SimdScalarMathTest, erfSingleAccuracy) @@ -322,24 +316,21 @@ TEST(SimdScalarMathTest, sinSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::sin(static_cast(x0)), - static_cast(sinSingleAccuracy(x0))); + EXPECT_EQ(std::sin(static_cast(x0)), static_cast(sinSingleAccuracy(x0))); } TEST(SimdScalarMathTest, cosSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::cos(static_cast(x0)), - static_cast(cosSingleAccuracy(x0))); + EXPECT_EQ(std::cos(static_cast(x0)), static_cast(cosSingleAccuracy(x0))); } TEST(SimdScalarMathTest, tanSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::tan(static_cast(x0)), - static_cast(tanSingleAccuracy(x0))); + EXPECT_EQ(std::tan(static_cast(x0)), static_cast(tanSingleAccuracy(x0))); } @@ -347,24 +338,21 @@ TEST(SimdScalarMathTest, asinSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::asin(static_cast(x0)), - static_cast(asinSingleAccuracy(x0))); + EXPECT_EQ(std::asin(static_cast(x0)), static_cast(asinSingleAccuracy(x0))); } TEST(SimdScalarMathTest, acosSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::acos(static_cast(x0)), - static_cast(acosSingleAccuracy(x0))); + EXPECT_EQ(std::acos(static_cast(x0)), static_cast(acosSingleAccuracy(x0))); } TEST(SimdScalarMathTest, atanSingleAccuracy) { double x0 = c0; - EXPECT_EQ(std::atan(static_cast(x0)), - static_cast(atanSingleAccuracy(x0))); + EXPECT_EQ(std::atan(static_cast(x0)), static_cast(atanSingleAccuracy(x0))); } TEST(SimdScalarMathTest, atan2SingleAccuracy) @@ -383,10 +371,11 @@ TEST(SimdScalarMathTest, pmeForceCorrectionSingleAccuracy) // Calculate reference value for z2!=0 in single precision float z = std::sqrt(static_cast(z2)); - float ref = 2.0*std::exp(static_cast(-z2))/(std::sqrt(static_cast(M_PI))*z2) - std::erf(z)/(z2*z); + float ref = 2.0 * std::exp(static_cast(-z2)) / (std::sqrt(static_cast(M_PI)) * z2) + - std::erf(z) / (z2 * z); // Pme correction only needs to be ~1e-6 accuracy single - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); EXPECT_REAL_EQ_TOL(ref, static_cast(pmeForceCorrectionSingleAccuracy(z2)), tolerance); } @@ -397,10 +386,10 @@ TEST(SimdScalarMathTest, pmePotentialCorrectionSingleAccuracy) // Calculate reference value for z2!=0 in single precision float z = std::sqrt(static_cast(z2)); - float ref = std::erf(z)/z; + float ref = std::erf(z) / z; // Pme correction only needs to be ~1e-6 accuracy single - FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); + FloatingPointTolerance tolerance(relativeToleranceAsFloatingPoint(1.0, 5e-6)); EXPECT_REAL_EQ_TOL(ref, static_cast(pmePotentialCorrectionSingleAccuracy(z2)), tolerance); } @@ -408,6 +397,6 @@ TEST(SimdScalarMathTest, pmePotentialCorrectionSingleAccuracy) /*! \} */ /*! \endcond internal */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/simd/tests/scalar_util.cpp b/src/gromacs/simd/tests/scalar_util.cpp index a234d48fdb..69aa82b216 100644 --- a/src/gromacs/simd/tests/scalar_util.cpp +++ b/src/gromacs/simd/tests/scalar_util.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,7 +59,7 @@ namespace TEST(SimdScalarUtilTest, gatherLoadTranspose) { - real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; + real data[8] = { c0, c1, c2, c3, c4, c5, c6, c7 }; std::int32_t offset = 1; real v0, v1, v2, v3; @@ -78,7 +78,7 @@ TEST(SimdScalarUtilTest, gatherLoadTranspose) TEST(SimdScalarUtilTest, gatherLoadUTranspose) { - real data[6] = {c0, c1, c2, c3, c4, c5}; + real data[6] = { c0, c1, c2, c3, c4, c5 }; std::int32_t offset = 1; real v0, v1, v2; @@ -91,7 +91,7 @@ TEST(SimdScalarUtilTest, gatherLoadUTranspose) TEST(SimdScalarUtilTest, transposeScatterStoreU) { - real data[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + real data[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; std::int32_t offset = 1; real v0 = 1; real v1 = 2; @@ -112,7 +112,7 @@ TEST(SimdScalarUtilTest, transposeScatterStoreU) TEST(SimdScalarUtilTest, transposeScatterIncrU) { - real data[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; + real data[9] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; std::int32_t offset = 1; real v0 = c1; real v1 = c2; @@ -123,9 +123,9 @@ TEST(SimdScalarUtilTest, transposeScatterIncrU) EXPECT_EQ(real(10), data[0]); EXPECT_EQ(real(20), data[1]); EXPECT_EQ(real(30), data[2]); - EXPECT_EQ(real(40+c1), data[3]); - EXPECT_EQ(real(50+c2), data[4]); - EXPECT_EQ(real(60+c3), data[5]); + EXPECT_EQ(real(40 + c1), data[3]); + EXPECT_EQ(real(50 + c2), data[4]); + EXPECT_EQ(real(60 + c3), data[5]); EXPECT_EQ(real(70), data[6]); EXPECT_EQ(real(80), data[7]); EXPECT_EQ(real(90), data[8]); @@ -133,7 +133,7 @@ TEST(SimdScalarUtilTest, transposeScatterIncrU) TEST(SimdScalarUtilTest, transposeScatterDecrU) { - real data[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; + real data[9] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; std::int32_t offset = 1; real v0 = c1; real v1 = c2; @@ -144,9 +144,9 @@ TEST(SimdScalarUtilTest, transposeScatterDecrU) EXPECT_EQ(real(10), data[0]); EXPECT_EQ(real(20), data[1]); EXPECT_EQ(real(30), data[2]); - EXPECT_EQ(real(40-c1), data[3]); - EXPECT_EQ(real(50-c2), data[4]); - EXPECT_EQ(real(60-c3), data[5]); + EXPECT_EQ(real(40 - c1), data[3]); + EXPECT_EQ(real(50 - c2), data[4]); + EXPECT_EQ(real(60 - c3), data[5]); EXPECT_EQ(real(70), data[6]); EXPECT_EQ(real(80), data[7]); EXPECT_EQ(real(90), data[8]); @@ -167,7 +167,7 @@ TEST(SimdScalarTest, expandScalarsToTriplets) TEST(SimdScalarUtilTest, gatherLoadBySimdIntTranspose) { - real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; + real data[8] = { c0, c1, c2, c3, c4, c5, c6, c7 }; std::int32_t offset = 1; real v0, v1, v2, v3; @@ -186,7 +186,7 @@ TEST(SimdScalarUtilTest, gatherLoadBySimdIntTranspose) TEST(SimdScalarUtilTest, gatherLoadUBySimdIntTranspose) { - real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; + real data[8] = { c0, c1, c2, c3, c4, c5, c6, c7 }; std::int32_t offset = 1; real v0, v1; @@ -198,14 +198,14 @@ TEST(SimdScalarUtilTest, gatherLoadUBySimdIntTranspose) TEST(SimdScalarUtilTest, reduceIncr4ReturnSum) { - real data[6] = {0, 0, 0, 0, 0, 0}; + real data[6] = { 0, 0, 0, 0, 0, 0 }; real v0 = c1; real v1 = c2; real v2 = c3; real v3 = c4; real sum; - sum = reduceIncr4ReturnSum(data+1, v0, v1, v2, v3); + sum = reduceIncr4ReturnSum(data + 1, v0, v1, v2, v3); EXPECT_EQ(czero, data[0]); EXPECT_EQ(v0, data[1]); @@ -214,12 +214,12 @@ TEST(SimdScalarUtilTest, reduceIncr4ReturnSum) EXPECT_EQ(v3, data[4]); EXPECT_EQ(czero, data[5]); - EXPECT_REAL_EQ_TOL(real(v0+v1+v2+v3), sum, defaultRealTolerance()); + EXPECT_REAL_EQ_TOL(real(v0 + v1 + v2 + v3), sum, defaultRealTolerance()); } /*! \} */ /*! \endcond internal */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/simd/tests/simd.cpp b/src/gromacs/simd/tests/simd.cpp index 77a91e7900..e519643d7c 100644 --- a/src/gromacs/simd/tests/simd.cpp +++ b/src/gromacs/simd/tests/simd.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,73 +63,77 @@ namespace test * occasionally have many digits that need to be exactly right, and keeping * them in a single place makes sure they are consistent. */ -#if GMX_SIMD_HAVE_REAL -const SimdReal rSimd_c0c1c2 = setSimdRealFrom3R( c0, c1, c2); -const SimdReal rSimd_c3c4c5 = setSimdRealFrom3R( c3, c4, c5); -const SimdReal rSimd_c6c7c8 = setSimdRealFrom3R( c6, c7, c8); -const SimdReal rSimd_c3c0c4 = setSimdRealFrom3R( c3, c0, c4); -const SimdReal rSimd_c4c6c8 = setSimdRealFrom3R( c4, c6, c8); -const SimdReal rSimd_c7c2c3 = setSimdRealFrom3R( c7, c2, c3); +# if GMX_SIMD_HAVE_REAL +const SimdReal rSimd_c0c1c2 = setSimdRealFrom3R(c0, c1, c2); +const SimdReal rSimd_c3c4c5 = setSimdRealFrom3R(c3, c4, c5); +const SimdReal rSimd_c6c7c8 = setSimdRealFrom3R(c6, c7, c8); +const SimdReal rSimd_c3c0c4 = setSimdRealFrom3R(c3, c0, c4); +const SimdReal rSimd_c4c6c8 = setSimdRealFrom3R(c4, c6, c8); +const SimdReal rSimd_c7c2c3 = setSimdRealFrom3R(c7, c2, c3); const SimdReal rSimd_m0m1m2 = setSimdRealFrom3R(-c0, -c1, -c2); const SimdReal rSimd_m3m0m4 = setSimdRealFrom3R(-c3, -c0, -c4); -const SimdReal rSimd_2p25 = setSimdRealFrom1R( 2.25); -const SimdReal rSimd_3p25 = setSimdRealFrom1R( 3.25); -const SimdReal rSimd_3p75 = setSimdRealFrom1R( 3.75); -const SimdReal rSimd_m2p25 = setSimdRealFrom1R(-2.25); -const SimdReal rSimd_m3p25 = setSimdRealFrom1R(-3.25); -const SimdReal rSimd_m3p75 = setSimdRealFrom1R(-3.75); -const SimdReal rSimd_Exp = setSimdRealFrom3R( 1.4055235171027452623914516e+18, - 5.3057102734253445623914516e-13, - -2.1057102745623934534514516e+16); -#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +const SimdReal rSimd_2p25 = setSimdRealFrom1R(2.25); +const SimdReal rSimd_3p25 = setSimdRealFrom1R(3.25); +const SimdReal rSimd_3p75 = setSimdRealFrom1R(3.75); +const SimdReal rSimd_m2p25 = setSimdRealFrom1R(-2.25); +const SimdReal rSimd_m3p25 = setSimdRealFrom1R(-3.25); +const SimdReal rSimd_m3p75 = setSimdRealFrom1R(-3.75); +const SimdReal rSimd_Exp = setSimdRealFrom3R(1.4055235171027452623914516e+18, + 5.3057102734253445623914516e-13, + -2.1057102745623934534514516e+16); +# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE // Make sure we also test exponents outside single precision when we use double -const SimdReal rSimd_ExpDouble = setSimdRealFrom3R( 6.287393598732017379054414e+176, - 8.794495252903116023030553e-140, - -3.637060701570496477655022e+202); -#endif // GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +const SimdReal rSimd_ExpDouble = setSimdRealFrom3R(6.287393598732017379054414e+176, + 8.794495252903116023030553e-140, + -3.637060701570496477655022e+202); +# endif // GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL // The numbers below all have exponent (2^0), which will not change with AND/OR operations. // We also leave the last part of the mantissa as zeros, to avoid rounding issues in the compiler -#if GMX_DOUBLE -const SimdReal rSimd_logicalA = setSimdRealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 -const SimdReal rSimd_logicalB = setSimdRealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 -const SimdReal rSimd_logicalResultAnd = setSimdRealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 -const SimdReal rSimd_logicalResultOr = setSimdRealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 -#else // GMX_DOUBLE -const SimdReal rSimd_logicalA = setSimdRealFrom1R(1.3333282470703125); // mantissa 0101010101010101 -const SimdReal rSimd_logicalB = setSimdRealFrom1R(1.79998779296875); // mantissa 1100110011001100 -const SimdReal rSimd_logicalResultAnd = setSimdRealFrom1R(1.26666259765625); // mantissa 0100010001000100 -const SimdReal rSimd_logicalResultOr = setSimdRealFrom1R(1.8666534423828125); // mantissa 1101110111011101 -#endif // GMX_DOUBLE -#endif // GMX_SIMD_HAVE_LOGICAL - -#endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD_HAVE_INT32_ARITHMETICS -const SimdInt32 iSimd_1_2_3 = setSimdIntFrom3I(1, 2, 3); -const SimdInt32 iSimd_4_5_6 = setSimdIntFrom3I(4, 5, 6); -const SimdInt32 iSimd_7_8_9 = setSimdIntFrom3I(7, 8, 9); -const SimdInt32 iSimd_5_7_9 = setSimdIntFrom3I(5, 7, 9); -const SimdInt32 iSimd_1M_2M_3M = setSimdIntFrom3I(1000000, 2000000, 3000000); -const SimdInt32 iSimd_4M_5M_6M = setSimdIntFrom3I(4000000, 5000000, 6000000); -const SimdInt32 iSimd_5M_7M_9M = setSimdIntFrom3I(5000000, 7000000, 9000000); -#endif -#if GMX_SIMD_HAVE_INT32_LOGICAL +# if GMX_DOUBLE +const SimdReal rSimd_logicalA = + setSimdRealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 +const SimdReal rSimd_logicalB = + setSimdRealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 +const SimdReal rSimd_logicalResultAnd = + setSimdRealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 +const SimdReal rSimd_logicalResultOr = + setSimdRealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 +# else // GMX_DOUBLE +const SimdReal rSimd_logicalA = setSimdRealFrom1R(1.3333282470703125); // mantissa 0101010101010101 +const SimdReal rSimd_logicalB = setSimdRealFrom1R(1.79998779296875); // mantissa 1100110011001100 +const SimdReal rSimd_logicalResultAnd = setSimdRealFrom1R(1.26666259765625); // mantissa 0100010001000100 +const SimdReal rSimd_logicalResultOr = setSimdRealFrom1R(1.8666534423828125); // mantissa 1101110111011101 +# endif // GMX_DOUBLE +# endif // GMX_SIMD_HAVE_LOGICAL + +# endif // GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_INT32_ARITHMETICS +const SimdInt32 iSimd_1_2_3 = setSimdIntFrom3I(1, 2, 3); +const SimdInt32 iSimd_4_5_6 = setSimdIntFrom3I(4, 5, 6); +const SimdInt32 iSimd_7_8_9 = setSimdIntFrom3I(7, 8, 9); +const SimdInt32 iSimd_5_7_9 = setSimdIntFrom3I(5, 7, 9); +const SimdInt32 iSimd_1M_2M_3M = setSimdIntFrom3I(1000000, 2000000, 3000000); +const SimdInt32 iSimd_4M_5M_6M = setSimdIntFrom3I(4000000, 5000000, 6000000); +const SimdInt32 iSimd_5M_7M_9M = setSimdIntFrom3I(5000000, 7000000, 9000000); +# endif +# if GMX_SIMD_HAVE_INT32_LOGICAL const SimdInt32 iSimd_0xF0F0F0F0 = setSimdIntFrom1I(0xF0F0F0F0); const SimdInt32 iSimd_0xCCCCCCCC = setSimdIntFrom1I(0xCCCCCCCC); -#endif +# endif -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL TEST(SimdTest, GmxAligned) { // Test alignment with two variables that must be aligned, and one that // doesn't have to be. The order of variables is up to the compiler, but // if it ignores alignment it is highly unlikely that both r1/r3 still end // up being aligned by mistake. - alignas(GMX_SIMD_ALIGNMENT) real r1; - real r2; - alignas(GMX_SIMD_ALIGNMENT) real r3; + alignas(GMX_SIMD_ALIGNMENT) real r1; + real r2; + alignas(GMX_SIMD_ALIGNMENT) real r3; std::uint64_t addr1 = reinterpret_cast(&r1); std::uint64_t addr2 = reinterpret_cast(&r2); @@ -139,9 +143,9 @@ TEST(SimdTest, GmxAligned) EXPECT_NE(0, addr2); // Just so r2 is not optimized away EXPECT_EQ(0, addr3 % GMX_SIMD_ALIGNMENT); - alignas(GMX_SIMD_ALIGNMENT) std::int32_t i1; - std::int32_t i2; - alignas(GMX_SIMD_ALIGNMENT) std::int32_t i3; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t i1; + std::int32_t i2; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t i3; addr1 = reinterpret_cast(&i1); addr2 = reinterpret_cast(&i2); @@ -153,31 +157,28 @@ TEST(SimdTest, GmxAligned) } -::std::vector -simdReal2Vector(const SimdReal simd) +::std::vector simdReal2Vector(const SimdReal simd) { - alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD_REAL_WIDTH]; store(mem, simd); - std::vector v(mem, mem+GMX_SIMD_REAL_WIDTH); + std::vector v(mem, mem + GMX_SIMD_REAL_WIDTH); return v; } -SimdReal -vector2SimdReal(const std::vector &v) +SimdReal vector2SimdReal(const std::vector& v) { - alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD_REAL_WIDTH]; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { - mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width + mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width } return load(mem); } -SimdReal -setSimdRealFrom3R(real r0, real r1, real r2) +SimdReal setSimdRealFrom3R(real r0, real r1, real r2) { std::vector v(3); v[0] = r0; @@ -186,8 +187,7 @@ setSimdRealFrom3R(real r0, real r1, real r2) return vector2SimdReal(v); } -SimdReal -setSimdRealFrom1R(real value) +SimdReal setSimdRealFrom1R(real value) { std::vector v(GMX_SIMD_REAL_WIDTH); for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -197,45 +197,44 @@ setSimdRealFrom1R(real value) return vector2SimdReal(v); } -testing::AssertionResult -SimdTest::compareSimdRealUlp(const char * refExpr, const char * tstExpr, - const SimdReal ref, const SimdReal tst) +testing::AssertionResult SimdTest::compareSimdRealUlp(const char* refExpr, + const char* tstExpr, + const SimdReal ref, + const SimdReal tst) { return compareVectorRealUlp(refExpr, tstExpr, simdReal2Vector(ref), simdReal2Vector(tst)); } -testing::AssertionResult -SimdTest::compareSimdEq(const char * refExpr, const char * tstExpr, - const SimdReal ref, const SimdReal tst) +testing::AssertionResult SimdTest::compareSimdEq(const char* refExpr, + const char* tstExpr, + const SimdReal ref, + const SimdReal tst) { return compareVectorEq(refExpr, tstExpr, simdReal2Vector(ref), simdReal2Vector(tst)); } -std::vector -simdInt2Vector(const SimdInt32 simd) +std::vector simdInt2Vector(const SimdInt32 simd) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t mem[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t mem[GMX_SIMD_REAL_WIDTH]; store(mem, simd); - std::vector v(mem, mem+GMX_SIMD_REAL_WIDTH); + std::vector v(mem, mem + GMX_SIMD_REAL_WIDTH); return v; } -SimdInt32 -vector2SimdInt(const std::vector &v) +SimdInt32 vector2SimdInt(const std::vector& v) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t mem[GMX_SIMD_REAL_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t mem[GMX_SIMD_REAL_WIDTH]; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { - mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width + mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width } return load(mem); } -SimdInt32 -setSimdIntFrom3I(int i0, int i1, int i2) +SimdInt32 setSimdIntFrom3I(int i0, int i1, int i2) { std::vector v(3); v[0] = i0; @@ -244,8 +243,7 @@ setSimdIntFrom3I(int i0, int i1, int i2) return vector2SimdInt(v); } -SimdInt32 -setSimdIntFrom1I(int value) +SimdInt32 setSimdIntFrom1I(int value) { std::vector v(GMX_SIMD_REAL_WIDTH); for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -255,19 +253,20 @@ setSimdIntFrom1I(int value) return vector2SimdInt(v); } -::testing::AssertionResult -SimdTest::compareSimdEq(const char * refExpr, const char * tstExpr, - const SimdInt32 ref, const SimdInt32 tst) +::testing::AssertionResult SimdTest::compareSimdEq(const char* refExpr, + const char* tstExpr, + const SimdInt32 ref, + const SimdInt32 tst) { return compareVectorEq(refExpr, tstExpr, simdInt2Vector(ref), simdInt2Vector(tst)); } -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd.h b/src/gromacs/simd/tests/simd.h index 8c0ecbd96b..9e94c2ea73 100644 --- a/src/gromacs/simd/tests/simd.h +++ b/src/gromacs/simd/tests/simd.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -108,57 +108,57 @@ namespace test * occasionally have many digits that need to be exactly right, and keeping * them in a single place makes sure they are consistent. */ -#if GMX_SIMD_HAVE_REAL -extern const SimdReal rSimd_c0c1c2; //!< c0,c1,c2 repeated -extern const SimdReal rSimd_c3c4c5; //!< c3,c4,c5 repeated -extern const SimdReal rSimd_c6c7c8; //!< c6,c7,c8 repeated -extern const SimdReal rSimd_c3c0c4; //!< c3,c0,c4 repeated -extern const SimdReal rSimd_c4c6c8; //!< c4,c6,c8 repeated -extern const SimdReal rSimd_c7c2c3; //!< c7,c2,c3 repeated -extern const SimdReal rSimd_m0m1m2; //!< -c0,-c1,-c2 repeated -extern const SimdReal rSimd_m3m0m4; //!< -c3,-c0,-c4 repeated - -extern const SimdReal rSimd_2p25; //!< Value that rounds down. -extern const SimdReal rSimd_3p25; //!< Value that rounds down. -extern const SimdReal rSimd_3p75; //!< Value that rounds up. -extern const SimdReal rSimd_m2p25; //!< Negative value that rounds up. -extern const SimdReal rSimd_m3p25; //!< Negative value that rounds up. -extern const SimdReal rSimd_m3p75; //!< Negative value that rounds down. +# if GMX_SIMD_HAVE_REAL +extern const SimdReal rSimd_c0c1c2; //!< c0,c1,c2 repeated +extern const SimdReal rSimd_c3c4c5; //!< c3,c4,c5 repeated +extern const SimdReal rSimd_c6c7c8; //!< c6,c7,c8 repeated +extern const SimdReal rSimd_c3c0c4; //!< c3,c0,c4 repeated +extern const SimdReal rSimd_c4c6c8; //!< c4,c6,c8 repeated +extern const SimdReal rSimd_c7c2c3; //!< c7,c2,c3 repeated +extern const SimdReal rSimd_m0m1m2; //!< -c0,-c1,-c2 repeated +extern const SimdReal rSimd_m3m0m4; //!< -c3,-c0,-c4 repeated + +extern const SimdReal rSimd_2p25; //!< Value that rounds down. +extern const SimdReal rSimd_3p25; //!< Value that rounds down. +extern const SimdReal rSimd_3p75; //!< Value that rounds up. +extern const SimdReal rSimd_m2p25; //!< Negative value that rounds up. +extern const SimdReal rSimd_m3p25; //!< Negative value that rounds up. +extern const SimdReal rSimd_m3p75; //!< Negative value that rounds down. //! Three large floating-point values whose exponents are >32. extern const SimdReal rSimd_Exp; -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL extern const SimdReal rSimd_logicalA; //!< Bit pattern to test logical ops extern const SimdReal rSimd_logicalB; //!< Bit pattern to test logical ops extern const SimdReal rSimd_logicalResultOr; //!< Result or bitwise 'or' of A and B extern const SimdReal rSimd_logicalResultAnd; //!< Result or bitwise 'and' of A and B -#endif // GMX_SIMD_HAVE_LOGICAL +# endif // GMX_SIMD_HAVE_LOGICAL -# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE // Make sure we also test exponents outside single precision when we use double extern const SimdReal rSimd_ExpDouble; -# endif +# endif // Magic FP numbers corresponding to specific bit patterns -extern const SimdReal rSimd_Bits1; //!< Pattern F0 repeated to fill single/double. -extern const SimdReal rSimd_Bits2; //!< Pattern CC repeated to fill single/double. -extern const SimdReal rSimd_Bits3; //!< Pattern C0 repeated to fill single/double. -extern const SimdReal rSimd_Bits4; //!< Pattern 0C repeated to fill single/double. -extern const SimdReal rSimd_Bits5; //!< Pattern FC repeated to fill single/double. -extern const SimdReal rSimd_Bits6; //!< Pattern 3C repeated to fill single/double. -#endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD_HAVE_INT32_ARITHMETICS -extern const SimdInt32 iSimd_1_2_3; //!< Three generic ints. -extern const SimdInt32 iSimd_4_5_6; //!< Three generic ints. -extern const SimdInt32 iSimd_7_8_9; //!< Three generic ints. -extern const SimdInt32 iSimd_5_7_9; //!< iSimd_1_2_3 + iSimd_4_5_6. -extern const SimdInt32 iSimd_1M_2M_3M; //!< Term1 for 32bit add/sub. -extern const SimdInt32 iSimd_4M_5M_6M; //!< Term2 for 32bit add/sub. -extern const SimdInt32 iSimd_5M_7M_9M; //!< iSimd_1M_2M_3M + iSimd_4M_5M_6M. -#endif -#if GMX_SIMD_HAVE_INT32_LOGICAL +extern const SimdReal rSimd_Bits1; //!< Pattern F0 repeated to fill single/double. +extern const SimdReal rSimd_Bits2; //!< Pattern CC repeated to fill single/double. +extern const SimdReal rSimd_Bits3; //!< Pattern C0 repeated to fill single/double. +extern const SimdReal rSimd_Bits4; //!< Pattern 0C repeated to fill single/double. +extern const SimdReal rSimd_Bits5; //!< Pattern FC repeated to fill single/double. +extern const SimdReal rSimd_Bits6; //!< Pattern 3C repeated to fill single/double. +# endif // GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_INT32_ARITHMETICS +extern const SimdInt32 iSimd_1_2_3; //!< Three generic ints. +extern const SimdInt32 iSimd_4_5_6; //!< Three generic ints. +extern const SimdInt32 iSimd_7_8_9; //!< Three generic ints. +extern const SimdInt32 iSimd_5_7_9; //!< iSimd_1_2_3 + iSimd_4_5_6. +extern const SimdInt32 iSimd_1M_2M_3M; //!< Term1 for 32bit add/sub. +extern const SimdInt32 iSimd_4M_5M_6M; //!< Term2 for 32bit add/sub. +extern const SimdInt32 iSimd_5M_7M_9M; //!< iSimd_1M_2M_3M + iSimd_4M_5M_6M. +# endif +# if GMX_SIMD_HAVE_INT32_LOGICAL extern const SimdInt32 iSimd_0xF0F0F0F0; //!< Bitpattern to test integer logical operations. extern const SimdInt32 iSimd_0xCCCCCCCC; //!< Bitpattern to test integer logical operations. -#endif +# endif /*! \internal @@ -171,61 +171,56 @@ extern const SimdInt32 iSimd_0xCCCCCCCC; //!< Bitpattern to test integer logical */ class SimdTest : public SimdBaseTest { - public: -#if GMX_SIMD_HAVE_REAL - /*! \brief Compare two real SIMD variables for approximate equality. - * - * This is an internal implementation routine. YOu should always use - * GMX_EXPECT_SIMD_REAL_NEAR() instead. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the SIMD test variable is within the class tolerances of the corresponding - * reference element. - */ - - - ::testing::AssertionResult - compareSimdRealUlp(const char * refExpr, const char * tstExpr, - SimdReal ref, SimdReal tst); - - /*! \brief Compare two real SIMD variables for exact equality. - * - * This is an internal implementation routine. YOu should always use - * GMX_EXPECT_SIMD_REAL_NEAR() instead. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the SIMD test variable is within the class tolerances of the corresponding - * reference element. - */ - ::testing::AssertionResult - compareSimdEq(const char * refExpr, const char * tstExpr, - SimdReal ref, SimdReal tst); - - /*! \brief Compare two 32-bit integer SIMD variables. - * - * This is an internal implementation routine. YOu should always use - * GMX_EXPECT_SIMD_INT_EQ() instead. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro, while the SIMD and - * tolerance arguments are used to decide if the values are approximately equal. - * - * The comparison is applied to each element, and it returns true if each element - * in the SIMD variable tst is identical to the corresponding reference element. - */ - ::testing::AssertionResult - compareSimdEq(const char * refExpr, const char * tstExpr, - SimdInt32 ref, SimdInt32 tst); -#endif +public: +# if GMX_SIMD_HAVE_REAL + /*! \brief Compare two real SIMD variables for approximate equality. + * + * This is an internal implementation routine. YOu should always use + * GMX_EXPECT_SIMD_REAL_NEAR() instead. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the SIMD test variable is within the class tolerances of the corresponding + * reference element. + */ + + + ::testing::AssertionResult + compareSimdRealUlp(const char* refExpr, const char* tstExpr, SimdReal ref, SimdReal tst); + + /*! \brief Compare two real SIMD variables for exact equality. + * + * This is an internal implementation routine. YOu should always use + * GMX_EXPECT_SIMD_REAL_NEAR() instead. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the SIMD test variable is within the class tolerances of the corresponding + * reference element. + */ + ::testing::AssertionResult compareSimdEq(const char* refExpr, const char* tstExpr, SimdReal ref, SimdReal tst); + + /*! \brief Compare two 32-bit integer SIMD variables. + * + * This is an internal implementation routine. YOu should always use + * GMX_EXPECT_SIMD_INT_EQ() instead. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro, while the SIMD and + * tolerance arguments are used to decide if the values are approximately equal. + * + * The comparison is applied to each element, and it returns true if each element + * in the SIMD variable tst is identical to the corresponding reference element. + */ + ::testing::AssertionResult compareSimdEq(const char* refExpr, const char* tstExpr, SimdInt32 ref, SimdInt32 tst); +# endif }; -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL /*! \brief Convert SIMD real to std::vector. * * The returned vector will have the same length as the SIMD width. @@ -237,7 +232,7 @@ std::vector simdReal2Vector(SimdReal simd); * If the vector is longer than SIMD width, only the first elements will be used. * If it is shorter, the contents will be repeated to fill the SIMD register. */ -SimdReal vector2SimdReal(const std::vector &v); +SimdReal vector2SimdReal(const std::vector& v); /*! \brief Set SIMD register contents from three real values. * @@ -245,7 +240,7 @@ SimdReal vector2SimdReal(const std::vector &v); * SIMD width, so this way there will not be any simple repeated patterns e.g. * between the low/high 64/128/256 bits in the SIMD register, which could hide bugs. */ -SimdReal setSimdRealFrom3R(real r0, real r1, real r2); +SimdReal setSimdRealFrom3R(real r0, real r1, real r2); /*! \brief Set SIMD register contents from single real value. * @@ -253,29 +248,30 @@ SimdReal setSimdRealFrom3R(real r0, real r1, real r2); * operation as simdSet1(), but is implemented using only load/store * operations that have been tested separately in the bootstrapping tests. */ -SimdReal setSimdRealFrom1R(real value); +SimdReal setSimdRealFrom1R(real value); /*! \brief Test if a SIMD real is bitwise identical to reference SIMD value. */ -#define GMX_EXPECT_SIMD_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) +# define GMX_EXPECT_SIMD_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) /*! \brief Test if a SIMD is bitwise identical to reference SIMD value. */ -#define GMX_EXPECT_SIMD_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) +# define GMX_EXPECT_SIMD_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) /*! \brief Test if a SIMD real is within tolerance of reference SIMD value. */ -#define GMX_EXPECT_SIMD_REAL_NEAR(ref, tst) EXPECT_PRED_FORMAT2(compareSimdRealUlp, ref, tst) +# define GMX_EXPECT_SIMD_REAL_NEAR(ref, tst) \ + EXPECT_PRED_FORMAT2(compareSimdRealUlp, ref, tst) /*! \brief Convert SIMD integer to std::vector. * * The returned vector will have the same length as the SIMD width. */ -std::vector simdInt2Vector(SimdInt32 simd); +std::vector simdInt2Vector(SimdInt32 simd); /*! \brief Return 32-bit integer SIMD value from std::vector. * * If the vector is longer than SIMD width, only the first elements will be used. * If it is shorter, the contents will be repeated to fill the SIMD register. */ -SimdInt32 vector2SimdInt(const std::vector &v); +SimdInt32 vector2SimdInt(const std::vector& v); /*! \brief Set SIMD register contents from three int values. * @@ -283,7 +279,7 @@ SimdInt32 vector2SimdInt(const std::vector &v); * SIMD width, so this way there will not be any simple repeated patterns e.g. * between the low/high 64/128/256 bits in the SIMD register, which could hide bugs. */ -SimdInt32 setSimdIntFrom3I(int i0, int i1, int i2); +SimdInt32 setSimdIntFrom3I(int i0, int i1, int i2); /*! \brief Set SIMD register contents from single integer value. * @@ -291,22 +287,22 @@ SimdInt32 setSimdIntFrom3I(int i0, int i1, int i2); * operation as simdSet1I(), but is implemented using only load/store * operations that have been tested separately in the bootstrapping tests. */ -SimdInt32 setSimdIntFrom1I(int value); +SimdInt32 setSimdIntFrom1I(int value); /*! \brief Macro that checks SIMD integer expression against SIMD or reference int. * * If the reference argument is a scalar integer it will be expanded into * the width of the SIMD register and tested against all elements. */ -#define GMX_EXPECT_SIMD_INT_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) +# define GMX_EXPECT_SIMD_INT_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimdEq, ref, tst) -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd4.cpp b/src/gromacs/simd/tests/simd4.cpp index fa98e14828..dca34032a2 100644 --- a/src/gromacs/simd/tests/simd4.cpp +++ b/src/gromacs/simd/tests/simd4.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,62 +52,63 @@ namespace test /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD4_HAVE_REAL - -const Simd4Real rSimd4_c0c1c2 = setSimd4RealFrom3R( c0, c1, c2); -const Simd4Real rSimd4_c3c4c5 = setSimd4RealFrom3R( c3, c4, c5); -const Simd4Real rSimd4_c6c7c8 = setSimd4RealFrom3R( c6, c7, c8); -const Simd4Real rSimd4_c3c0c4 = setSimd4RealFrom3R( c3, c0, c4); -const Simd4Real rSimd4_c4c6c8 = setSimd4RealFrom3R( c4, c6, c8); -const Simd4Real rSimd4_c7c2c3 = setSimd4RealFrom3R( c7, c2, c3); -const Simd4Real rSimd4_m0m1m2 = setSimd4RealFrom3R(-c0, -c1, -c2); -const Simd4Real rSimd4_m3m0m4 = setSimd4RealFrom3R(-c3, -c0, -c4); -const Simd4Real rSimd4_2p25 = setSimd4RealFrom1R(2.25); -const Simd4Real rSimd4_3p75 = setSimd4RealFrom1R(3.75); -const Simd4Real rSimd4_m2p25 = setSimd4RealFrom1R(-2.25); -const Simd4Real rSimd4_m3p75 = setSimd4RealFrom1R(-3.75); - -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD4_HAVE_REAL + +const Simd4Real rSimd4_c0c1c2 = setSimd4RealFrom3R(c0, c1, c2); +const Simd4Real rSimd4_c3c4c5 = setSimd4RealFrom3R(c3, c4, c5); +const Simd4Real rSimd4_c6c7c8 = setSimd4RealFrom3R(c6, c7, c8); +const Simd4Real rSimd4_c3c0c4 = setSimd4RealFrom3R(c3, c0, c4); +const Simd4Real rSimd4_c4c6c8 = setSimd4RealFrom3R(c4, c6, c8); +const Simd4Real rSimd4_c7c2c3 = setSimd4RealFrom3R(c7, c2, c3); +const Simd4Real rSimd4_m0m1m2 = setSimd4RealFrom3R(-c0, -c1, -c2); +const Simd4Real rSimd4_m3m0m4 = setSimd4RealFrom3R(-c3, -c0, -c4); +const Simd4Real rSimd4_2p25 = setSimd4RealFrom1R(2.25); +const Simd4Real rSimd4_3p75 = setSimd4RealFrom1R(3.75); +const Simd4Real rSimd4_m2p25 = setSimd4RealFrom1R(-2.25); +const Simd4Real rSimd4_m3p75 = setSimd4RealFrom1R(-3.75); + +# if GMX_SIMD_HAVE_LOGICAL // The numbers below all have exponent (2^0), which will not change with AND/OR operations. // We also leave the last part of the mantissa as zeros, to avoid rounding issues in the compiler -#if GMX_DOUBLE -const Simd4Real rSimd4_logicalA = setSimd4RealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 -const Simd4Real rSimd4_logicalB = setSimd4RealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 -const Simd4Real rSimd4_logicalResultAnd = setSimd4RealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 -const Simd4Real rSimd4_logicalResultOr = setSimd4RealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 -#else // GMX_DOUBLE -const Simd4Real rSimd4_logicalA = setSimd4RealFrom1R(1.3333282470703125); // mantissa 0101010101010101 -const Simd4Real rSimd4_logicalB = setSimd4RealFrom1R(1.79998779296875); // mantissa 1100110011001100 -const Simd4Real rSimd4_logicalResultAnd = setSimd4RealFrom1R(1.26666259765625); // mantissa 0100010001000100 -const Simd4Real rSimd4_logicalResultOr = setSimd4RealFrom1R(1.8666534423828125); // mantissa 1101110111011101 -#endif // GMX_DOUBLE -#endif // GMX_SIMD_HAVE_LOGICAL - -::std::vector -simd4Real2Vector(const Simd4Real simd4) +# if GMX_DOUBLE +const Simd4Real rSimd4_logicalA = + setSimd4RealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 +const Simd4Real rSimd4_logicalB = + setSimd4RealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 +const Simd4Real rSimd4_logicalResultAnd = + setSimd4RealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 +const Simd4Real rSimd4_logicalResultOr = + setSimd4RealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 +# else // GMX_DOUBLE +const Simd4Real rSimd4_logicalA = setSimd4RealFrom1R(1.3333282470703125); // mantissa 0101010101010101 +const Simd4Real rSimd4_logicalB = setSimd4RealFrom1R(1.79998779296875); // mantissa 1100110011001100 +const Simd4Real rSimd4_logicalResultAnd = setSimd4RealFrom1R(1.26666259765625); // mantissa 0100010001000100 +const Simd4Real rSimd4_logicalResultOr = setSimd4RealFrom1R(1.8666534423828125); // mantissa 1101110111011101 +# endif // GMX_DOUBLE +# endif // GMX_SIMD_HAVE_LOGICAL + +::std::vector simd4Real2Vector(const Simd4Real simd4) { - alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD4_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD4_WIDTH]; store4(mem, simd4); - std::vector v(mem, mem+GMX_SIMD4_WIDTH); + std::vector v(mem, mem + GMX_SIMD4_WIDTH); return v; } -Simd4Real -vector2Simd4Real(const std::vector &v) +Simd4Real vector2Simd4Real(const std::vector& v) { - alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD4_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) real mem[GMX_SIMD4_WIDTH]; for (int i = 0; i < GMX_SIMD4_WIDTH; i++) { - mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width + mem[i] = v[i % v.size()]; // repeat vector contents to fill simd width } return load4(mem); } -Simd4Real -setSimd4RealFrom3R(real r0, real r1, real r2) +Simd4Real setSimd4RealFrom3R(real r0, real r1, real r2) { std::vector v(3); v[0] = r0; @@ -116,8 +117,7 @@ setSimd4RealFrom3R(real r0, real r1, real r2) return vector2Simd4Real(v); } -Simd4Real -setSimd4RealFrom1R(real value) +Simd4Real setSimd4RealFrom1R(real value) { std::vector v(GMX_SIMD4_WIDTH); for (int i = 0; i < GMX_SIMD4_WIDTH; i++) @@ -127,26 +127,28 @@ setSimd4RealFrom1R(real value) return vector2Simd4Real(v); } -testing::AssertionResult -Simd4Test::compareSimd4RealUlp(const char * refExpr, const char * tstExpr, - const Simd4Real ref, const Simd4Real tst) +testing::AssertionResult Simd4Test::compareSimd4RealUlp(const char* refExpr, + const char* tstExpr, + const Simd4Real ref, + const Simd4Real tst) { return compareVectorRealUlp(refExpr, tstExpr, simd4Real2Vector(ref), simd4Real2Vector(tst)); } -testing::AssertionResult -Simd4Test::compareSimd4RealEq(const char * refExpr, const char * tstExpr, - const Simd4Real ref, const Simd4Real tst) +testing::AssertionResult Simd4Test::compareSimd4RealEq(const char* refExpr, + const char* tstExpr, + const Simd4Real ref, + const Simd4Real tst) { return compareVectorEq(refExpr, tstExpr, simd4Real2Vector(ref), simd4Real2Vector(tst)); } -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD4_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd4.h b/src/gromacs/simd/tests/simd4.h index bee86fd969..6378bf924c 100644 --- a/src/gromacs/simd/tests/simd4.h +++ b/src/gromacs/simd/tests/simd4.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,35 +67,35 @@ namespace test /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD4_HAVE_REAL -extern const Simd4Real rSimd4_c0c1c2; //!< c0,c1,c2 repeated -extern const Simd4Real rSimd4_c3c4c5; //!< c3,c4,c5 repeated -extern const Simd4Real rSimd4_c6c7c8; //!< c6,c7,c8 repeated -extern const Simd4Real rSimd4_c3c0c4; //!< c3,c0,c4 repeated -extern const Simd4Real rSimd4_c4c6c8; //!< c4,c6,c8 repeated -extern const Simd4Real rSimd4_c7c2c3; //!< c7,c2,c3 repeated -extern const Simd4Real rSimd4_m0m1m2; //!< -c0,-c1,-c2 repeated -extern const Simd4Real rSimd4_m3m0m4; //!< -c3,-c0,-c4 repeated -extern const Simd4Real rSimd4_2p25; //!< Value that rounds down. -extern const Simd4Real rSimd4_3p75; //!< Value that rounds up. -extern const Simd4Real rSimd4_m2p25; //!< Negative value that rounds up. -extern const Simd4Real rSimd4_m3p75; //!< Negative value that rounds down. +# if GMX_SIMD4_HAVE_REAL +extern const Simd4Real rSimd4_c0c1c2; //!< c0,c1,c2 repeated +extern const Simd4Real rSimd4_c3c4c5; //!< c3,c4,c5 repeated +extern const Simd4Real rSimd4_c6c7c8; //!< c6,c7,c8 repeated +extern const Simd4Real rSimd4_c3c0c4; //!< c3,c0,c4 repeated +extern const Simd4Real rSimd4_c4c6c8; //!< c4,c6,c8 repeated +extern const Simd4Real rSimd4_c7c2c3; //!< c7,c2,c3 repeated +extern const Simd4Real rSimd4_m0m1m2; //!< -c0,-c1,-c2 repeated +extern const Simd4Real rSimd4_m3m0m4; //!< -c3,-c0,-c4 repeated +extern const Simd4Real rSimd4_2p25; //!< Value that rounds down. +extern const Simd4Real rSimd4_3p75; //!< Value that rounds up. +extern const Simd4Real rSimd4_m2p25; //!< Negative value that rounds up. +extern const Simd4Real rSimd4_m3p75; //!< Negative value that rounds down. //! Three large floating-point values whose exponents are >32. extern const Simd4Real rSimd4_Exp; -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL extern const Simd4Real rSimd4_logicalA; //!< Bit pattern to test logical ops extern const Simd4Real rSimd4_logicalB; //!< Bit pattern to test logical ops extern const Simd4Real rSimd4_logicalResultOr; //!< Result or bitwise 'or' of A and B extern const Simd4Real rSimd4_logicalResultAnd; //!< Result or bitwise 'and' of A and B -#endif // GMX_SIMD_HAVE_LOGICAL +# endif // GMX_SIMD_HAVE_LOGICAL -extern const Simd4Real rSimd4_Bits1; //!< Pattern F0 repeated to fill single/double. -extern const Simd4Real rSimd4_Bits2; //!< Pattern CC repeated to fill single/double. -extern const Simd4Real rSimd4_Bits3; //!< Pattern C0 repeated to fill single/double. -extern const Simd4Real rSimd4_Bits4; //!< Pattern 0C repeated to fill single/double. -extern const Simd4Real rSimd4_Bits5; //!< Pattern FC repeated to fill single/double. -extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill single/double. +extern const Simd4Real rSimd4_Bits1; //!< Pattern F0 repeated to fill single/double. +extern const Simd4Real rSimd4_Bits2; //!< Pattern CC repeated to fill single/double. +extern const Simd4Real rSimd4_Bits3; //!< Pattern C0 repeated to fill single/double. +extern const Simd4Real rSimd4_Bits4; //!< Pattern 0C repeated to fill single/double. +extern const Simd4Real rSimd4_Bits5; //!< Pattern FC repeated to fill single/double. +extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill single/double. /*! \internal * \brief @@ -107,38 +107,36 @@ extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill */ class Simd4Test : public SimdBaseTest { - public: - /*! \brief Compare two real SIMD4 variables for approximate equality. - * - * This is an internal implementation routine. YOu should always use - * GMX_EXPECT_SIMD4_REAL_NEAR() instead. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the SIMD4 test variable is within the class tolerances of the corresponding - * reference element. - */ - ::testing::AssertionResult - compareSimd4RealUlp(const char * refExpr, const char * tstExpr, - Simd4Real ref, Simd4Real tst); - - /*! \brief Compare two real SIMD4 variables for exact equality. - * - * This is an internal implementation routine. YOu should always use - * GMX_EXPECT_SIMD4_REAL_NEAR() instead. - * - * This routine is designed according to the Google test specs, so the char - * strings will describe the arguments to the macro. - * - * The comparison is applied to each element, and it returns true if each element - * in the SIMD4 test variable is within the class tolerances of the corresponding - * reference element. - */ - ::testing::AssertionResult - compareSimd4RealEq(const char * refExpr, const char * tstExpr, - Simd4Real ref, Simd4Real tst); +public: + /*! \brief Compare two real SIMD4 variables for approximate equality. + * + * This is an internal implementation routine. YOu should always use + * GMX_EXPECT_SIMD4_REAL_NEAR() instead. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the SIMD4 test variable is within the class tolerances of the corresponding + * reference element. + */ + ::testing::AssertionResult + compareSimd4RealUlp(const char* refExpr, const char* tstExpr, Simd4Real ref, Simd4Real tst); + + /*! \brief Compare two real SIMD4 variables for exact equality. + * + * This is an internal implementation routine. YOu should always use + * GMX_EXPECT_SIMD4_REAL_NEAR() instead. + * + * This routine is designed according to the Google test specs, so the char + * strings will describe the arguments to the macro. + * + * The comparison is applied to each element, and it returns true if each element + * in the SIMD4 test variable is within the class tolerances of the corresponding + * reference element. + */ + ::testing::AssertionResult + compareSimd4RealEq(const char* refExpr, const char* tstExpr, Simd4Real ref, Simd4Real tst); }; /*! \brief Convert SIMD4 real to std::vector. @@ -152,7 +150,7 @@ std::vector simd4Real2Vector(Simd4Real simd4); * If the vector is longer than SIMD4 width, only the first elements will be used. * If it is shorter, the contents will be repeated to fill the SIMD4 register. */ -Simd4Real vector2Simd4Real(const std::vector &v); +Simd4Real vector2Simd4Real(const std::vector& v); /*! \brief Set SIMD4 register contents from three real values. * @@ -160,7 +158,7 @@ Simd4Real vector2Simd4Real(const std::vector &v); * is 4, but it simplifies the test organization when the SIMD and SIMD4 tests * are completely symmetric. */ -Simd4Real setSimd4RealFrom3R(real r0, real r1, real r2); +Simd4Real setSimd4RealFrom3R(real r0, real r1, real r2); /*! \brief Set SIMD4 register contents from single real value. * @@ -168,21 +166,22 @@ Simd4Real setSimd4RealFrom3R(real r0, real r1, real r2); * operation as simd4Set1(), but is implemented using only load/store * operations that have been tested separately in the bootstrapping tests. */ -Simd4Real setSimd4RealFrom1R(real value); +Simd4Real setSimd4RealFrom1R(real value); /*! \brief Test if a SIMD4 real is bitwise identical to reference SIMD4 value. */ -#define GMX_EXPECT_SIMD4_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimd4RealEq, ref, tst) +# define GMX_EXPECT_SIMD4_REAL_EQ(ref, tst) EXPECT_PRED_FORMAT2(compareSimd4RealEq, ref, tst) /*! \brief Test if a SIMD4 real is within tolerance of reference SIMD4 value. */ -#define GMX_EXPECT_SIMD4_REAL_NEAR(ref, tst) EXPECT_PRED_FORMAT2(compareSimd4RealUlp, ref, tst) +# define GMX_EXPECT_SIMD4_REAL_NEAR(ref, tst) \ + EXPECT_PRED_FORMAT2(compareSimd4RealUlp, ref, tst) -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD4_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd4_floatingpoint.cpp b/src/gromacs/simd/tests/simd4_floatingpoint.cpp index 007b25e0fa..ea5c4f5844 100644 --- a/src/gromacs/simd/tests/simd4_floatingpoint.cpp +++ b/src/gromacs/simd/tests/simd4_floatingpoint.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,7 +58,7 @@ namespace /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD4_HAVE_REAL +# if GMX_SIMD4_HAVE_REAL /*! \brief Test fixture for SIMD4 floating-point operations (identical to the SIMD4 \ref Simd4Test) */ typedef Simd4Test Simd4FloatingpointTest; @@ -75,21 +75,17 @@ TEST_F(Simd4FloatingpointTest, set) TEST_F(Simd4FloatingpointTest, add) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 + c3, c1 + c4, c2 + c5 ), - rSimd4_c0c1c2 + rSimd4_c3c4c5); - + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 + c3, c1 + c4, c2 + c5), rSimd4_c0c1c2 + rSimd4_c3c4c5); } TEST_F(Simd4FloatingpointTest, sub) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 - c3, c1 - c4, c2 - c5 ), - rSimd4_c0c1c2 - rSimd4_c3c4c5); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 - c3, c1 - c4, c2 - c5), rSimd4_c0c1c2 - rSimd4_c3c4c5); } TEST_F(Simd4FloatingpointTest, mul) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 * c3, c1 * c4, c2 * c5 ), - rSimd4_c0c1c2 * rSimd4_c3c4c5); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 * c3, c1 * c4, c2 * c5), rSimd4_c0c1c2 * rSimd4_c3c4c5); } TEST_F(Simd4FloatingpointTest, fma) @@ -132,17 +128,15 @@ TEST_F(Simd4FloatingpointTest, neg) GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, -(rSimd4_m0m1m2)); // fneg(-x)=x } -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL TEST_F(Simd4FloatingpointTest, and) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultAnd, - (rSimd4_logicalA & rSimd4_logicalB)); + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultAnd, (rSimd4_logicalA & rSimd4_logicalB)); } TEST_F(Simd4FloatingpointTest, or) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultOr, - (rSimd4_logicalA | rSimd4_logicalB)); + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultOr, (rSimd4_logicalA | rSimd4_logicalB)); } TEST_F(Simd4FloatingpointTest, xor) @@ -161,23 +155,24 @@ TEST_F(Simd4FloatingpointTest, andNot) * to extract the sign bit, and then use andnot to take absolute values. */ Simd4Real signbit = Simd4Real(c1) ^ Simd4Real(-c1); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c2, c3, c4), andNot(signbit, setSimd4RealFrom3R(-c2, c3, -c4))); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c2, c3, c4), + andNot(signbit, setSimd4RealFrom3R(-c2, c3, -c4))); } -#endif +# endif TEST_F(Simd4FloatingpointTest, max) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c3, c1, c4), max(rSimd4_c0c1c2, rSimd4_c3c0c4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c3, c1, c4), max(rSimd4_c3c0c4, rSimd4_c0c1c2)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c3, c1, c4), max(rSimd4_c0c1c2, rSimd4_c3c0c4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c3, c1, c4), max(rSimd4_c3c0c4, rSimd4_c0c1c2)); GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c0, -c0, -c2), max(rSimd4_m0m1m2, rSimd4_m3m0m4)); GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c0, -c0, -c2), max(rSimd4_m3m0m4, rSimd4_m0m1m2)); } TEST_F(Simd4FloatingpointTest, min) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c0, c0, c2), min(rSimd4_c0c1c2, rSimd4_c3c0c4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c0, c0, c2), min(rSimd4_c3c0c4, rSimd4_c0c1c2)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c0, c2), min(rSimd4_c0c1c2, rSimd4_c3c0c4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c0, c2), min(rSimd4_c3c0c4, rSimd4_c0c1c2)); GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c3, -c1, -c4), min(rSimd4_m0m1m2, rSimd4_m3m0m4)); GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c3, -c1, -c4), min(rSimd4_m3m0m4, rSimd4_m0m1m2)); } @@ -204,9 +199,9 @@ TEST_F(Simd4FloatingpointTest, trunc) */ TEST_F(Simd4FloatingpointTest, gmxSimd4RsqrtR) { - Simd4Real x = setSimd4RealFrom3R(4.0, M_PI, 1234567890.0); - Simd4Real ref = setSimd4RealFrom3R(0.5, 1.0/std::sqrt(M_PI), 1.0/std::sqrt(1234567890.0)); - int shiftbits = std::numeric_limits::digits-GMX_SIMD_RSQRT_BITS; + Simd4Real x = setSimd4RealFrom3R(4.0, M_PI, 1234567890.0); + Simd4Real ref = setSimd4RealFrom3R(0.5, 1.0 / std::sqrt(M_PI), 1.0 / std::sqrt(1234567890.0)); + int shiftbits = std::numeric_limits::digits - GMX_SIMD_RSQRT_BITS; if (shiftbits < 0) { @@ -221,45 +216,45 @@ TEST_F(Simd4FloatingpointTest, gmxSimd4RsqrtR) TEST_F(Simd4FloatingpointTest, cmpEqAndSelectByMask) { - Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, c2), selectByMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, selectByNotMask) { - Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByNotMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, cmpNe) { - Simd4Bool eq = rSimd4_c4c6c8 != rSimd4_c6c7c8; + Simd4Bool eq = rSimd4_c4c6c8 != rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, cmpLe) { - Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; + Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, selectByMask(rSimd4_c0c1c2, le)); } TEST_F(Simd4FloatingpointTest, cmpLt) { - Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByMask(rSimd4_c0c1c2, lt)); } TEST_F(Simd4FloatingpointTest, andB) { - Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; - Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, c2), selectByMask(rSimd4_c0c1c2, (eq && le))); } TEST_F(Simd4FloatingpointTest, orB) { - Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; - Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, selectByMask(rSimd4_c0c1c2, (eq || lt))); } @@ -280,7 +275,7 @@ TEST_F(Simd4FloatingpointTest, anyTrue) TEST_F(Simd4FloatingpointTest, blend) { - Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c3, c4, c2), blend(rSimd4_c0c1c2, rSimd4_c3c4c5, lt)); } @@ -296,35 +291,35 @@ TEST_F(Simd4FloatingpointTest, reduce) sum += v[i]; } - EXPECT_REAL_EQ_TOL(sum, reduce(rSimd4_c3c4c5), defaultRealTolerance() ); + EXPECT_REAL_EQ_TOL(sum, reduce(rSimd4_c3c4c5), defaultRealTolerance()); } TEST_F(Simd4FloatingpointTest, dotProduct) { - real res = c0*c3 + c1*c4 + c2*c5; + real res = c0 * c3 + c1 * c4 + c2 * c5; EXPECT_REAL_EQ_TOL(res, dotProduct(rSimd4_c0c1c2, rSimd4_c3c4c5), defaultRealTolerance()); } TEST_F(Simd4FloatingpointTest, transpose) { - Simd4Real v0, v1, v2, v3; - int i; + Simd4Real v0, v1, v2, v3; + int i; // aligned pointers - alignas(GMX_SIMD_ALIGNMENT) real p0[4*GMX_SIMD4_WIDTH]; - real * p1 = p0 + GMX_SIMD4_WIDTH; - real * p2 = p0 + 2*GMX_SIMD4_WIDTH; - real * p3 = p0 + 3*GMX_SIMD4_WIDTH; + alignas(GMX_SIMD_ALIGNMENT) real p0[4 * GMX_SIMD4_WIDTH]; + real* p1 = p0 + GMX_SIMD4_WIDTH; + real* p2 = p0 + 2 * GMX_SIMD4_WIDTH; + real* p3 = p0 + 3 * GMX_SIMD4_WIDTH; // Assign data with tens as row, single-digit as column for (i = 0; i < 4; i++) { // Scale by 1+100*eps to use low bits tii - p0[i] = (0*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); - p1[i] = (1*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); - p2[i] = (2*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); - p3[i] = (3*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); + p0[i] = (0 * 10 + i * 1) * (1.0 + 100 * GMX_REAL_EPS); + p1[i] = (1 * 10 + i * 1) * (1.0 + 100 * GMX_REAL_EPS); + p2[i] = (2 * 10 + i * 1) * (1.0 + 100 * GMX_REAL_EPS); + p3[i] = (3 * 10 + i * 1) * (1.0 + 100 * GMX_REAL_EPS); } v0 = load4(p0); @@ -341,20 +336,20 @@ TEST_F(Simd4FloatingpointTest, transpose) for (i = 0; i < 4; i++) { - EXPECT_REAL_EQ_TOL( (i*10+0) * (1.0 + 100*GMX_REAL_EPS), p0[i], defaultRealTolerance()); - EXPECT_REAL_EQ_TOL( (i*10+1) * (1.0 + 100*GMX_REAL_EPS), p1[i], defaultRealTolerance()); - EXPECT_REAL_EQ_TOL( (i*10+2) * (1.0 + 100*GMX_REAL_EPS), p2[i], defaultRealTolerance()); - EXPECT_REAL_EQ_TOL( (i*10+3) * (1.0 + 100*GMX_REAL_EPS), p3[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL((i * 10 + 0) * (1.0 + 100 * GMX_REAL_EPS), p0[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL((i * 10 + 1) * (1.0 + 100 * GMX_REAL_EPS), p1[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL((i * 10 + 2) * (1.0 + 100 * GMX_REAL_EPS), p2[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL((i * 10 + 3) * (1.0 + 100 * GMX_REAL_EPS), p3[i], defaultRealTolerance()); } } -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD4_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd4_math.cpp b/src/gromacs/simd/tests/simd4_math.cpp index 51a925dde2..c60c1e58f5 100644 --- a/src/gromacs/simd/tests/simd4_math.cpp +++ b/src/gromacs/simd/tests/simd4_math.cpp @@ -54,7 +54,7 @@ namespace test { -#if GMX_SIMD4_HAVE_REAL +# if GMX_SIMD4_HAVE_REAL /*! \cond internal */ /*! \addtogroup module_simd */ @@ -85,35 +85,35 @@ namespace TEST_F(Simd4MathTest, invsqrt) { - const real x0 = std::numeric_limits::min(); - const real x1 = std::numeric_limits::max(); - const real x2 = M_PI; + const real x0 = std::numeric_limits::min(); + const real x1 = std::numeric_limits::max(); + const real x2 = M_PI; - GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(1.0/sqrt(x0), 1.0/sqrt(x1), 1.0/sqrt(x2)), + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(1.0 / sqrt(x0), 1.0 / sqrt(x1), 1.0 / sqrt(x2)), invsqrt(setSimd4RealFrom3R(x0, x1, x2))); } TEST_F(Simd4MathTest, invsqrtSingleAccuracy) { - const real x0 = std::numeric_limits::min(); - const real x1 = std::numeric_limits::max(); - const real x2 = M_PI; + const real x0 = std::numeric_limits::min(); + const real x1 = std::numeric_limits::max(); + const real x2 = M_PI; /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(1.0/sqrt(x0), 1.0/sqrt(x1), 1.0/sqrt(x2)), + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(1.0 / sqrt(x0), 1.0 / sqrt(x1), 1.0 / sqrt(x2)), invsqrtSingleAccuracy(setSimd4RealFrom3R(x0, x1, x2))); } /*! \} */ /*! \endcond */ -} // namespace +} // namespace -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD4_HAVE_REAL -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd4_vector_operations.cpp b/src/gromacs/simd/tests/simd4_vector_operations.cpp index 60653ecbc0..4853a5a662 100644 --- a/src/gromacs/simd/tests/simd4_vector_operations.cpp +++ b/src/gromacs/simd/tests/simd4_vector_operations.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,7 +55,7 @@ namespace /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD4_HAVE_REAL +# if GMX_SIMD4_HAVE_REAL /*! \brief Test fixture for SIMD4 vector operations (identical to the SIMD4 \ref Simd4Test) */ typedef Simd4Test Simd4VectorOperationsTest; @@ -65,21 +65,20 @@ TEST_F(Simd4VectorOperationsTest, norm2) Simd4Real simdX = rSimd4_c0c1c2; Simd4Real simdY = rSimd4_c3c4c5; Simd4Real simdZ = rSimd4_c6c7c8; - Simd4Real simdR2 = setSimd4RealFrom3R(c0*c0 + c3*c3 + c6*c6, - c1*c1 + c4*c4 + c7*c7, - c2*c2 + c5*c5 + c8*c8); + Simd4Real simdR2 = setSimd4RealFrom3R(c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7, + c2 * c2 + c5 * c5 + c8 * c8); setUlpTol(2); GMX_EXPECT_SIMD4_REAL_NEAR(simdR2, norm2(simdX, simdY, simdZ)); } -#endif // GMX_SIMD4_HAVE_REAL +# endif // GMX_SIMD4_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd_floatingpoint.cpp b/src/gromacs/simd/tests/simd_floatingpoint.cpp index 55efc79e12..a0d2d96498 100644 --- a/src/gromacs/simd/tests/simd_floatingpoint.cpp +++ b/src/gromacs/simd/tests/simd_floatingpoint.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ namespace /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL /*! \brief Test fixture for floating-point tests (identical to the generic \ref SimdTest) */ typedef SimdTest SimdFloatingpointTest; @@ -73,40 +73,37 @@ TEST_F(SimdFloatingpointTest, setZero) TEST_F(SimdFloatingpointTest, set) { - const real *p = &c0; + const real* p = &c0; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(c1), SimdReal(c1)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(c0), SimdReal(*p)); } TEST_F(SimdFloatingpointTest, add) { - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + c4, c2 + c5 ), - rSimd_c0c1c2 + rSimd_c3c4c5); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + c4, c2 + c5), rSimd_c0c1c2 + rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, maskAdd) { SimdBool m = setSimdRealFrom3R(c6, 0, c7) != setZero(); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + 0.0, c2 + c5 ), + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + 0.0, c2 + c5), maskAdd(rSimd_c0c1c2, rSimd_c3c4c5, m)); } TEST_F(SimdFloatingpointTest, sub) { - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 - c3, c1 - c4, c2 - c5 ), - rSimd_c0c1c2 - rSimd_c3c4c5); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 - c3, c1 - c4, c2 - c5), rSimd_c0c1c2 - rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, mul) { - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, c1 * c4, c2 * c5 ), - rSimd_c0c1c2 * rSimd_c3c4c5); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, c1 * c4, c2 * c5), rSimd_c0c1c2 * rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, maskzMul) { SimdBool m = setSimdRealFrom3R(c1, 0, c1) != setZero(); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, 0.0, c2 * c5 ), + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, 0.0, c2 * c5), maskzMul(rSimd_c0c1c2, rSimd_c3c4c5, m)); } @@ -159,17 +156,15 @@ TEST_F(SimdFloatingpointTest, neg) GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, -(rSimd_m0m1m2)); // fneg(-x)=x } -#if GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_LOGICAL TEST_F(SimdFloatingpointTest, and) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultAnd, - (rSimd_logicalA & rSimd_logicalB)); + GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultAnd, (rSimd_logicalA & rSimd_logicalB)); } TEST_F(SimdFloatingpointTest, or) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultOr, - (rSimd_logicalA | rSimd_logicalB)); + GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultOr, (rSimd_logicalA | rSimd_logicalB)); } TEST_F(SimdFloatingpointTest, xor) @@ -188,23 +183,24 @@ TEST_F(SimdFloatingpointTest, andNot) * to extract the sign bit, and then use andnot to take absolute values. */ SimdReal signbit = SimdReal(c1) ^ SimdReal(-c1); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c2, c3, c4), andNot(signbit, setSimdRealFrom3R(-c2, c3, -c4))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c2, c3, c4), + andNot(signbit, setSimdRealFrom3R(-c2, c3, -c4))); } -#endif +# endif TEST_F(SimdFloatingpointTest, max) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c3, c1, c4), max(rSimd_c0c1c2, rSimd_c3c0c4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c3, c1, c4), max(rSimd_c3c0c4, rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c3, c1, c4), max(rSimd_c0c1c2, rSimd_c3c0c4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c3, c1, c4), max(rSimd_c3c0c4, rSimd_c0c1c2)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, -c0, -c2), max(rSimd_m0m1m2, rSimd_m3m0m4)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, -c0, -c2), max(rSimd_m3m0m4, rSimd_m0m1m2)); } TEST_F(SimdFloatingpointTest, min) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, c0, c2), min(rSimd_c0c1c2, rSimd_c3c0c4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, c0, c2), min(rSimd_c3c0c4, rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c0, c2), min(rSimd_c0c1c2, rSimd_c3c0c4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c0, c2), min(rSimd_c3c0c4, rSimd_c0c1c2)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c3, -c1, -c4), min(rSimd_m0m1m2, rSimd_m3m0m4)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c3, -c1, -c4), min(rSimd_m3m0m4, rSimd_m0m1m2)); } @@ -220,8 +216,8 @@ TEST_F(SimdFloatingpointTest, round) TEST_F(SimdFloatingpointTest, roundMode) { /* Rounding mode needs to be consistent between round and cvtR2I */ - SimdReal x0 = setSimdRealFrom3R(0.5, 11.5, 99.5); - SimdReal x1 = setSimdRealFrom3R(-0.5, -11.5, -99.5); + SimdReal x0 = setSimdRealFrom3R(0.5, 11.5, 99.5); + SimdReal x1 = setSimdRealFrom3R(-0.5, -11.5, -99.5); GMX_EXPECT_SIMD_REAL_EQ(round(x0), cvtI2R(cvtR2I(x0))); GMX_EXPECT_SIMD_REAL_EQ(round(x1), cvtI2R(cvtR2I(x1))); @@ -246,22 +242,20 @@ TEST_F(SimdFloatingpointTest, frexp) fraction = frexp(rSimd_Exp, &exponent); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128, - 0.5833690139241746175358116, + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.609548660288905419513128, 0.5833690139241746175358116, -0.584452007502232362412542), fraction); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(61, -40, 55), exponent); -#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE fraction = frexp(rSimd_ExpDouble, &exponent); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.6206306194761728178832527, - 0.5236473618795619566768096, + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0.6206306194761728178832527, 0.5236473618795619566768096, -0.9280331023751380303821179), fraction); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(588, -461, 673), exponent); -#endif +# endif } TEST_F(SimdFloatingpointTest, ldexp) @@ -270,10 +264,10 @@ TEST_F(SimdFloatingpointTest, ldexp) GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(pow(2.0, 60.0), pow(2.0, -41.0), pow(2.0, 54.0)), ldexp(one, setSimdIntFrom3I(60, -41, 54))); -#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(pow(2.0, 587.0), pow(2.0, -462.0), pow(2.0, 672.0)), ldexp(one, setSimdIntFrom3I(587, -462, 672))); -#endif +# endif // The default safe version must be able to handle very negative arguments too GMX_EXPECT_SIMD_REAL_EQ(setZero(), ldexp(one, setSimdIntFrom3I(-2000, -1000000, -1000000000))); } @@ -285,9 +279,9 @@ TEST_F(SimdFloatingpointTest, ldexp) TEST_F(SimdFloatingpointTest, rsqrt) { - SimdReal x = setSimdRealFrom3R(4.0, M_PI, 1234567890.0); - SimdReal ref = setSimdRealFrom3R(0.5, 1.0/std::sqrt(M_PI), 1.0/std::sqrt(1234567890.0)); - int shiftbits = std::numeric_limits::digits-GMX_SIMD_RSQRT_BITS; + SimdReal x = setSimdRealFrom3R(4.0, M_PI, 1234567890.0); + SimdReal ref = setSimdRealFrom3R(0.5, 1.0 / std::sqrt(M_PI), 1.0 / std::sqrt(1234567890.0)); + int shiftbits = std::numeric_limits::digits - GMX_SIMD_RSQRT_BITS; if (shiftbits < 0) { @@ -303,11 +297,11 @@ TEST_F(SimdFloatingpointTest, rsqrt) TEST_F(SimdFloatingpointTest, maskzRsqrt) { - SimdReal x = setSimdRealFrom3R(M_PI, -4.0, 0.0); + SimdReal x = setSimdRealFrom3R(M_PI, -4.0, 0.0); // simdCmpLe is tested separately further down - SimdBool m = setZero() < x; - SimdReal ref = setSimdRealFrom3R(1.0/std::sqrt(M_PI), 0.0, 0.0); - int shiftbits = std::numeric_limits::digits-GMX_SIMD_RSQRT_BITS; + SimdBool m = setZero() < x; + SimdReal ref = setSimdRealFrom3R(1.0 / std::sqrt(M_PI), 0.0, 0.0); + int shiftbits = std::numeric_limits::digits - GMX_SIMD_RSQRT_BITS; if (shiftbits < 0) { @@ -323,9 +317,9 @@ TEST_F(SimdFloatingpointTest, maskzRsqrt) TEST_F(SimdFloatingpointTest, rcp) { - SimdReal x = setSimdRealFrom3R(4.0, M_PI, 1234567890.0); - SimdReal ref = setSimdRealFrom3R(0.25, 1.0/M_PI, 1.0/1234567890.0); - int shiftbits = std::numeric_limits::digits-GMX_SIMD_RCP_BITS; + SimdReal x = setSimdRealFrom3R(4.0, M_PI, 1234567890.0); + SimdReal ref = setSimdRealFrom3R(0.25, 1.0 / M_PI, 1.0 / 1234567890.0); + int shiftbits = std::numeric_limits::digits - GMX_SIMD_RCP_BITS; if (shiftbits < 0) { @@ -341,10 +335,10 @@ TEST_F(SimdFloatingpointTest, rcp) TEST_F(SimdFloatingpointTest, maskzRcp) { - SimdReal x = setSimdRealFrom3R(M_PI, 0.0, -1234567890.0); - SimdBool m = (x != setZero()); - SimdReal ref = setSimdRealFrom3R(1.0/M_PI, 0.0, -1.0/1234567890.0); - int shiftbits = std::numeric_limits::digits-GMX_SIMD_RCP_BITS; + SimdReal x = setSimdRealFrom3R(M_PI, 0.0, -1234567890.0); + SimdBool m = (x != setZero()); + SimdReal ref = setSimdRealFrom3R(1.0 / M_PI, 0.0, -1.0 / 1234567890.0); + int shiftbits = std::numeric_limits::digits - GMX_SIMD_RCP_BITS; if (shiftbits < 0) { @@ -360,63 +354,63 @@ TEST_F(SimdFloatingpointTest, maskzRcp) TEST_F(SimdFloatingpointTest, cmpEqAndSelectByMask) { - SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, c2), selectByMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, selectByNotMask) { - SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByNotMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, cmpNe) { - SimdBool eq = rSimd_c4c6c8 != rSimd_c6c7c8; + SimdBool eq = rSimd_c4c6c8 != rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, cmpLe) { - SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; + SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, le)); } TEST_F(SimdFloatingpointTest, cmpLt) { - SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByMask(rSimd_c0c1c2, lt)); } -#if GMX_SIMD_HAVE_INT32_LOGICAL || GMX_SIMD_HAVE_LOGICAL +# if GMX_SIMD_HAVE_INT32_LOGICAL || GMX_SIMD_HAVE_LOGICAL TEST_F(SimdFloatingpointTest, testBits) { - SimdBool eq = testBits(setSimdRealFrom3R(c1, 0, c1)); + SimdBool eq = testBits(setSimdRealFrom3R(c1, 0, c1)); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, 0, c2), selectByMask(rSimd_c0c1c2, eq)); // Test if we detect only the sign bit being set - eq = testBits(setSimdRealFrom1R(GMX_REAL_NEGZERO)); + eq = testBits(setSimdRealFrom1R(GMX_REAL_NEGZERO)); GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, eq)); } -#endif +# endif TEST_F(SimdFloatingpointTest, andB) { - SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; - SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, c2), selectByMask(rSimd_c0c1c2, (eq && le))); } TEST_F(SimdFloatingpointTest, orB) { - SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; - SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, (eq || lt))); } TEST_F(SimdFloatingpointTest, anyTrueB) { - alignas(GMX_SIMD_ALIGNMENT) std::array mem {}; + alignas(GMX_SIMD_ALIGNMENT) std::array mem{}; // Test the false case EXPECT_FALSE(anyTrue(setZero() < load(mem.data()))); @@ -426,13 +420,14 @@ TEST_F(SimdFloatingpointTest, anyTrueB) { mem.fill(0.0); mem[i] = 1.0; - EXPECT_TRUE(anyTrue(setZero() < load(mem.data()))) << "Not detecting true in element " << i; + EXPECT_TRUE(anyTrue(setZero() < load(mem.data()))) + << "Not detecting true in element " << i; } } TEST_F(SimdFloatingpointTest, blend) { - SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c3, c4, c2), blend(rSimd_c0c1c2, rSimd_c3c4c5, lt)); } @@ -448,39 +443,39 @@ TEST_F(SimdFloatingpointTest, reduce) sum += v[i]; } - EXPECT_REAL_EQ_TOL(sum, reduce(rSimd_c3c4c5), defaultRealTolerance() ); + EXPECT_REAL_EQ_TOL(sum, reduce(rSimd_c3c4c5), defaultRealTolerance()); } -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD_HAVE_FLOAT && GMX_SIMD_HAVE_DOUBLE +# if GMX_SIMD_HAVE_FLOAT && GMX_SIMD_HAVE_DOUBLE TEST_F(SimdFloatingpointTest, cvtFloat2Double) { - alignas(GMX_SIMD_ALIGNMENT) float f[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double d[GMX_SIMD_FLOAT_WIDTH]; // Yes, double array length should be same as float + alignas(GMX_SIMD_ALIGNMENT) float f[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double d[GMX_SIMD_FLOAT_WIDTH]; // Yes, double array length should be same as float - int i; - SimdFloat vf; - SimdDouble vd0; - FloatingPointTolerance tolerance(defaultRealTolerance()); + int i; + SimdFloat vf; + SimdDouble vd0; + FloatingPointTolerance tolerance(defaultRealTolerance()); for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { // Scale by 1+100*eps to use low bits too. // Due to the conversions we want to avoid being too sensitive to fluctuations in last bit - f[i] = i * (1.0 + 100*GMX_FLOAT_EPS); + f[i] = i * (1.0 + 100 * GMX_FLOAT_EPS); } vf = load(f); -#if (GMX_SIMD_FLOAT_WIDTH == 2*GMX_SIMD_DOUBLE_WIDTH) +# if (GMX_SIMD_FLOAT_WIDTH == 2 * GMX_SIMD_DOUBLE_WIDTH) SimdDouble vd1; cvtF2DD(vf, &vd0, &vd1); store(d + GMX_SIMD_DOUBLE_WIDTH, vd1); // Store upper part halfway through array -#elif (GMX_SIMD_FLOAT_WIDTH == GMX_SIMD_DOUBLE_WIDTH) +# elif (GMX_SIMD_FLOAT_WIDTH == GMX_SIMD_DOUBLE_WIDTH) vd0 = cvtF2D(vf); -#else -# error Width of float SIMD must either be identical to double, or twice the width. -#endif +# else +# error Width of float SIMD must either be identical to double, or twice the width. +# endif store(d, vd0); // store lower (or whole) part from start of vector for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) @@ -491,30 +486,30 @@ TEST_F(SimdFloatingpointTest, cvtFloat2Double) TEST_F(SimdFloatingpointTest, cvtDouble2Float) { - alignas(GMX_SIMD_ALIGNMENT) float f[GMX_SIMD_FLOAT_WIDTH]; - alignas(GMX_SIMD_ALIGNMENT) double d[GMX_SIMD_FLOAT_WIDTH]; // Yes, double array length should be same as float - int i; - SimdFloat vf; - SimdDouble vd0; - FloatingPointTolerance tolerance(defaultRealTolerance()); + alignas(GMX_SIMD_ALIGNMENT) float f[GMX_SIMD_FLOAT_WIDTH]; + alignas(GMX_SIMD_ALIGNMENT) double d[GMX_SIMD_FLOAT_WIDTH]; // Yes, double array length should be same as float + int i; + SimdFloat vf; + SimdDouble vd0; + FloatingPointTolerance tolerance(defaultRealTolerance()); // This fills elements for pd1 too when double width is 2*single width for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { // Scale by 1+eps to use low bits too. // Due to the conversions we want to avoid being too sensitive to fluctuations in last bit - d[i] = i * (1.0 + 100*GMX_FLOAT_EPS); + d[i] = i * (1.0 + 100 * GMX_FLOAT_EPS); } vd0 = load(d); -#if (GMX_SIMD_FLOAT_WIDTH == 2*GMX_SIMD_DOUBLE_WIDTH) +# if (GMX_SIMD_FLOAT_WIDTH == 2 * GMX_SIMD_DOUBLE_WIDTH) SimdDouble vd1 = load(d + GMX_SIMD_DOUBLE_WIDTH); // load upper half of data - vf = cvtDD2F(vd0, vd1); -#elif (GMX_SIMD_FLOAT_WIDTH == GMX_SIMD_DOUBLE_WIDTH) - vf = cvtD2F(vd0); -#else -# error Width of float SIMD must either be identical to double, or twice the width. -#endif + vf = cvtDD2F(vd0, vd1); +# elif (GMX_SIMD_FLOAT_WIDTH == GMX_SIMD_DOUBLE_WIDTH) + vf = cvtD2F(vd0); +# else +# error Width of float SIMD must either be identical to double, or twice the width. +# endif store(f, vf); // This will check elements in pd1 too when double width is 2*single width @@ -523,13 +518,13 @@ TEST_F(SimdFloatingpointTest, cvtDouble2Float) EXPECT_FLOAT_EQ_TOL(d[i], f[i], tolerance); } } -#endif // GMX_SIMD_HAVE_FLOAT && GMX_SIMD_HAVE_DOUBLE +# endif // GMX_SIMD_HAVE_FLOAT && GMX_SIMD_HAVE_DOUBLE /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd_floatingpoint_util.cpp b/src/gromacs/simd/tests/simd_floatingpoint_util.cpp index fe4eece001..89cb01018e 100644 --- a/src/gromacs/simd/tests/simd_floatingpoint_util.cpp +++ b/src/gromacs/simd/tests/simd_floatingpoint_util.cpp @@ -63,77 +63,76 @@ namespace */ class SimdFloatingpointUtilTest : public SimdTest { - public: - SimdFloatingpointUtilTest() - { - // Resize vectors to get the amount of memory we need - integerMemory_.resize(GMX_SIMD_REAL_WIDTH); - - // The total memory we allocate corresponds to two work arrays - // and 4 values each of GMX_SIMD_REAL_WIDTH. - realMemory_.resize(2*s_workMemSize_+4*GMX_SIMD_REAL_WIDTH); - - offset_ = integerMemory_.data(); - val0_ = realMemory_.data(); - val1_ = val0_ + GMX_SIMD_REAL_WIDTH; - val2_ = val1_ + GMX_SIMD_REAL_WIDTH; - val3_ = val2_ + GMX_SIMD_REAL_WIDTH; - mem0_ = val3_ + GMX_SIMD_REAL_WIDTH; - mem1_ = mem0_ + s_workMemSize_; - - // Set default values for offset and variables val0_ through val3_ - // We cannot fill mem_ here since those values depend on the test. - for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) - { - // Use every third point to avoid a continguous access pattern - offset_[i] = 3 * i; - // Multiply numbers by 1+100*GMX_REAL_EPS ensures some low bits are - // set too, so the tests make sure we read all bits correctly. - val0_[i] = (i ) * (1.0 + 100*GMX_REAL_EPS); - val1_[i] = (i + 0.1) * (1.0 + 100*GMX_REAL_EPS); - val2_[i] = (i + 0.2) * (1.0 + 100*GMX_REAL_EPS); - val3_[i] = (i + 0.3) * (1.0 + 100*GMX_REAL_EPS); - } - } - - protected: - //! \brief Size of memory work buffers - // - // To have a somewhat odd access pattern, we use every - // third entry, so the largest value of offset_[i] is 3*GMX_SIMD_REAL_WIDTH. - // Then we also allow alignments up to 16, which means the largest index in mem0_[] - // that we might access is 16*3*GMX_SIMD_REAL_WIDTH+3. - static const std::size_t s_workMemSize_ = 16*3*GMX_SIMD_REAL_WIDTH+4; - - std::vector > integerMemory_; //!< Aligned integer memory - std::vector > realMemory_; //!< Aligned real memory - - int * offset_; //!< Pointer to offset indices, aligned memory - real * val0_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned - real * val1_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned - real * val2_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned - real * val3_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned - - real * mem0_; //!< Pointer to aligned memory, s_workMemSize real values - real * mem1_; //!< Pointer to aligned memory, s_workMemSize real values +public: + SimdFloatingpointUtilTest() + { + // Resize vectors to get the amount of memory we need + integerMemory_.resize(GMX_SIMD_REAL_WIDTH); + + // The total memory we allocate corresponds to two work arrays + // and 4 values each of GMX_SIMD_REAL_WIDTH. + realMemory_.resize(2 * s_workMemSize_ + 4 * GMX_SIMD_REAL_WIDTH); + + offset_ = integerMemory_.data(); + val0_ = realMemory_.data(); + val1_ = val0_ + GMX_SIMD_REAL_WIDTH; + val2_ = val1_ + GMX_SIMD_REAL_WIDTH; + val3_ = val2_ + GMX_SIMD_REAL_WIDTH; + mem0_ = val3_ + GMX_SIMD_REAL_WIDTH; + mem1_ = mem0_ + s_workMemSize_; + + // Set default values for offset and variables val0_ through val3_ + // We cannot fill mem_ here since those values depend on the test. + for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) + { + // Use every third point to avoid a continguous access pattern + offset_[i] = 3 * i; + // Multiply numbers by 1+100*GMX_REAL_EPS ensures some low bits are + // set too, so the tests make sure we read all bits correctly. + val0_[i] = (i) * (1.0 + 100 * GMX_REAL_EPS); + val1_[i] = (i + 0.1) * (1.0 + 100 * GMX_REAL_EPS); + val2_[i] = (i + 0.2) * (1.0 + 100 * GMX_REAL_EPS); + val3_[i] = (i + 0.3) * (1.0 + 100 * GMX_REAL_EPS); + } + } + +protected: + //! \brief Size of memory work buffers + // + // To have a somewhat odd access pattern, we use every + // third entry, so the largest value of offset_[i] is 3*GMX_SIMD_REAL_WIDTH. + // Then we also allow alignments up to 16, which means the largest index in mem0_[] + // that we might access is 16*3*GMX_SIMD_REAL_WIDTH+3. + static const std::size_t s_workMemSize_ = 16 * 3 * GMX_SIMD_REAL_WIDTH + 4; + + std::vector> integerMemory_; //!< Aligned integer memory + std::vector> realMemory_; //!< Aligned real memory + + int* offset_; //!< Pointer to offset indices, aligned memory + real* val0_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned + real* val1_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned + real* val2_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned + real* val3_; //!< Pointer to GMX_SIMD_REAL_WIDTH values, aligned + + real* mem0_; //!< Pointer to aligned memory, s_workMemSize real values + real* mem1_; //!< Pointer to aligned memory, s_workMemSize real values }; - TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose4) { - SimdReal v0, v1, v2, v3; - SimdReal ref0, ref1, ref2, ref3; - const int nalign = 3; - int alignmentList[nalign] = { 4, 8, 12 }; - int i, j, align; + SimdReal v0, v1, v2, v3; + SimdReal ref0, ref1, ref2, ref3; + const int nalign = 3; + int alignmentList[nalign] = { 4, 8, 12 }; + int i, j, align; for (i = 0; i < nalign; i++) { align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; mem0_[align * offset_[j] + 2] = val2_[j]; mem0_[align * offset_[j] + 3] = val3_[j]; @@ -170,11 +169,11 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose4) TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2) { - SimdReal v0, v1; - SimdReal ref0, ref1; - const int nalign = 3; - int alignmentList[nalign] = { 2, 4, c_simdBestPairAlignment }; - int i, j, align; + SimdReal v0, v1; + SimdReal ref0, ref1; + const int nalign = 3; + int alignmentList[nalign] = { 2, 4, c_simdBestPairAlignment }; + int i, j, align; EXPECT_TRUE(c_simdBestPairAlignment <= GMX_SIMD_REAL_WIDTH); @@ -183,7 +182,7 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2) align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; } @@ -214,18 +213,18 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2) TEST_F(SimdFloatingpointUtilTest, gatherLoadUTranspose3) { - SimdReal v0, v1, v2; - SimdReal ref0, ref1, ref2; - const int nalign = 2; - int alignmentList[nalign] = { 3, 4 }; - int i, j, align; + SimdReal v0, v1, v2; + SimdReal ref0, ref1, ref2; + const int nalign = 2; + int alignmentList[nalign] = { 3, 4 }; + int i, j, align; for (i = 0; i < nalign; i++) { align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; mem0_[align * offset_[j] + 2] = val2_[j]; } @@ -255,12 +254,12 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadUTranspose3) TEST_F(SimdFloatingpointUtilTest, transposeScatterStoreU3) { - SimdReal v0, v1, v2; - real refmem[s_workMemSize_]; - const int nalign = 2; - int alignmentList[nalign] = { 3, 4 }; - int i, align; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0, v1, v2; + real refmem[s_workMemSize_]; + const int nalign = 2; + int alignmentList[nalign] = { 3, 4 }; + int i, align; + FloatingPointTolerance tolerance(defaultRealTolerance()); for (i = 0; i < nalign; i++) { @@ -270,13 +269,13 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterStoreU3) for (std::size_t j = 0; j < s_workMemSize_; j++) { // Multiply by 1+100*eps to make sure low bits are also used - mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { // set values in _reference_ memory (we will then test with mem0_, and compare) - refmem[align * offset_[j] ] = val0_[j]; + refmem[align * offset_[j]] = val0_[j]; refmem[align * offset_[j] + 1] = val1_[j]; refmem[align * offset_[j] + 2] = val2_[j]; } @@ -307,12 +306,12 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterStoreU3) TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3) { - SimdReal v0, v1, v2; - real refmem[s_workMemSize_]; - const int nalign = 2; - int alignmentList[nalign] = { 3, 4 }; - int i, align; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0, v1, v2; + real refmem[s_workMemSize_]; + const int nalign = 2; + int alignmentList[nalign] = { 3, 4 }; + int i, align; + FloatingPointTolerance tolerance(defaultRealTolerance()); for (i = 0; i < nalign; i++) { @@ -322,13 +321,13 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3) for (std::size_t j = 0; j < s_workMemSize_; j++) { // Multiply by 1+100*eps to make sure low bits are also used - mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { // Add values to _reference_ memory (we will then test with mem0_, and compare) - refmem[align * offset_[j] ] += val0_[j]; + refmem[align * offset_[j]] += val0_[j]; refmem[align * offset_[j] + 1] += val1_[j]; refmem[align * offset_[j] + 2] += val2_[j]; } @@ -359,9 +358,9 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3) TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3Overlapping) { - SimdReal v0, v1, v2; - real refmem[s_workMemSize_]; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0, v1, v2; + real refmem[s_workMemSize_]; + FloatingPointTolerance tolerance(defaultRealTolerance()); // Alter offset_ to make all entries point to the same (first) value, so all entries will overlap for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -373,13 +372,13 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3Overlapping) for (std::size_t j = 0; j < s_workMemSize_; j++) { // Multiply by 1+100*eps to make sure low bits are also used - mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { // Add values to _reference_ memory (we will then test with mem0_, and compare) - refmem[3 * offset_[j] ] += val0_[j]; + refmem[3 * offset_[j]] += val0_[j]; refmem[3 * offset_[j] + 1] += val1_[j]; refmem[3 * offset_[j] + 2] += val2_[j]; } @@ -398,12 +397,12 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3Overlapping) TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3) { - SimdReal v0, v1, v2; - real refmem[s_workMemSize_]; - const int nalign = 2; - int alignmentList[nalign] = { 3, 4 }; - int i, align; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0, v1, v2; + real refmem[s_workMemSize_]; + const int nalign = 2; + int alignmentList[nalign] = { 3, 4 }; + int i, align; + FloatingPointTolerance tolerance(defaultRealTolerance()); for (i = 0; i < nalign; i++) { @@ -413,13 +412,13 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3) for (std::size_t j = 0; j < s_workMemSize_; j++) { // Multiply by 1+100*eps to make sure low bits are also used - mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { // Subtract values from _reference_ memory (we will then test with mem0_, and compare) - refmem[align * offset_[j] ] -= val0_[j]; + refmem[align * offset_[j]] -= val0_[j]; refmem[align * offset_[j] + 1] -= val1_[j]; refmem[align * offset_[j] + 2] -= val2_[j]; } @@ -450,9 +449,9 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3) TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3Overlapping) { - SimdReal v0, v1, v2; - real refmem[s_workMemSize_]; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0, v1, v2; + real refmem[s_workMemSize_]; + FloatingPointTolerance tolerance(defaultRealTolerance()); // Alter offset_ to make all entries point to the same (first) value, so all entries will overlap for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -464,16 +463,16 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3Overlapping) for (std::size_t j = 0; j < s_workMemSize_; j++) { // Multiply by 1+100*eps to make sure low bits are also used - mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100 * GMX_REAL_EPS); } -#ifdef __INTEL_COMPILER //Bug in (at least) 19u1 and 18u5 (03424712) - #pragma novector -#endif +# ifdef __INTEL_COMPILER // Bug in (at least) 19u1 and 18u5 (03424712) +# pragma novector +# endif for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { // Subtract values from _reference_ memory (we will then test with mem0_, and compare) - refmem[3 * offset_[j] ] -= val0_[j]; + refmem[3 * offset_[j]] -= val0_[j]; refmem[3 * offset_[j] + 1] -= val1_[j]; refmem[3 * offset_[j] + 2] -= val2_[j]; } @@ -492,8 +491,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3Overlapping) TEST_F(SimdFloatingpointUtilTest, expandScalarsToTriplets) { - SimdReal vs, v0, v1, v2; - int i; + SimdReal vs, v0, v1, v2; + int i; for (i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { @@ -519,19 +518,19 @@ TEST_F(SimdFloatingpointUtilTest, expandScalarsToTriplets) TEST_F(SimdFloatingpointUtilTest, gatherLoadBySimdIntTranspose4) { - SimdReal v0, v1, v2, v3; - SimdReal ref0, ref1, ref2, ref3; - SimdInt32 simdoffset; - const int nalign = 3; - int alignmentList[nalign] = { 4, 8, 12 }; - int i, j, align; + SimdReal v0, v1, v2, v3; + SimdReal ref0, ref1, ref2, ref3; + SimdInt32 simdoffset; + const int nalign = 3; + int alignmentList[nalign] = { 4, 8, 12 }; + int i, j, align; for (i = 0; i < nalign; i++) { align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; mem0_[align * offset_[j] + 2] = val2_[j]; mem0_[align * offset_[j] + 3] = val3_[j]; @@ -570,19 +569,19 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadBySimdIntTranspose4) TEST_F(SimdFloatingpointUtilTest, gatherLoadBySimdIntTranspose2) { - SimdReal v0, v1; - SimdReal ref0, ref1; - SimdInt32 simdoffset; - const int nalign = 3; - int alignmentList[nalign] = { 4, 8, 12 }; - int i, j, align; + SimdReal v0, v1; + SimdReal ref0, ref1; + SimdInt32 simdoffset; + const int nalign = 3; + int alignmentList[nalign] = { 4, 8, 12 }; + int i, j, align; for (i = 0; i < nalign; i++) { align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; } @@ -612,22 +611,22 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadBySimdIntTranspose2) } } -#if GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL +# if GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL TEST_F(SimdFloatingpointUtilTest, gatherLoadUBySimdIntTranspose2) { - SimdReal v0, v1; - SimdReal ref0, ref1; - SimdInt32 simdoffset; - const int nalign = 3; - int alignmentList[nalign] = { 1, 3, 5 }; - int i, j, align; + SimdReal v0, v1; + SimdReal ref0, ref1; + SimdInt32 simdoffset; + const int nalign = 3; + int alignmentList[nalign] = { 1, 3, 5 }; + int i, j, align; for (i = 0; i < nalign; i++) { align = alignmentList[i]; for (j = 0; j < GMX_SIMD_REAL_WIDTH; j++) { - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; } @@ -656,14 +655,14 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadUBySimdIntTranspose2) GMX_EXPECT_SIMD_REAL_EQ(ref1, v1); } } -#endif // GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL +# endif // GMX_SIMD_HAVE_GATHER_LOADU_BYSIMDINT_TRANSPOSE_REAL TEST_F(SimdFloatingpointUtilTest, reduceIncr4Sum) { - int i; - SimdReal v0, v1, v2, v3; - real sum0, sum1, sum2, sum3, tstsum; - FloatingPointTolerance tolerance(defaultRealTolerance()); + int i; + SimdReal v0, v1, v2, v3; + real sum0, sum1, sum2, sum3, tstsum; + FloatingPointTolerance tolerance(defaultRealTolerance()); v0 = load(val0_); v1 = load(val1_); @@ -695,14 +694,14 @@ TEST_F(SimdFloatingpointUtilTest, reduceIncr4Sum) EXPECT_REAL_EQ_TOL(sum0 + sum1 + sum2 + sum3, tstsum, tolerance); } -#if GMX_SIMD_HAVE_HSIMD_UTIL_REAL +# if GMX_SIMD_HAVE_HSIMD_UTIL_REAL TEST_F(SimdFloatingpointUtilTest, loadDualHsimd) { SimdReal v0, v1; // Point p to the upper half of val0_ - real * p = val0_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val0_ + GMX_SIMD_REAL_WIDTH / 2; v0 = load(val0_); v1 = loadDualHsimd(val0_, p); @@ -712,10 +711,10 @@ TEST_F(SimdFloatingpointUtilTest, loadDualHsimd) TEST_F(SimdFloatingpointUtilTest, loadDuplicateHsimd) { - SimdReal v0, v1; - int i; + SimdReal v0, v1; + int i; // Point p to the upper half of val0_ - real * p = val0_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val0_ + GMX_SIMD_REAL_WIDTH / 2; // Copy data so upper half is identical to lower for (i = 0; i < GMX_SIMD_REAL_WIDTH / 2; i++) { @@ -731,12 +730,12 @@ TEST_F(SimdFloatingpointUtilTest, loadDuplicateHsimd) TEST_F(SimdFloatingpointUtilTest, loadU1DualHsimd) { - SimdReal v0, v1; - int i; - real data[2] = { 1, 2 }; + SimdReal v0, v1; + int i; + real data[2] = { 1, 2 }; // Point p to the upper half of val0_ - real * p = val0_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val0_ + GMX_SIMD_REAL_WIDTH / 2; // Set all low elements to data[0], an high to data[1] for (i = 0; i < GMX_SIMD_REAL_WIDTH / 2; i++) { @@ -753,11 +752,11 @@ TEST_F(SimdFloatingpointUtilTest, loadU1DualHsimd) TEST_F(SimdFloatingpointUtilTest, storeDualHsimd) { - SimdReal v0; - int i; + SimdReal v0; + int i; // Point p to the upper half of val0_ - real * p = val0_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val0_ + GMX_SIMD_REAL_WIDTH / 2; v0 = load(val2_); storeDualHsimd(val0_, p, v0); @@ -770,8 +769,8 @@ TEST_F(SimdFloatingpointUtilTest, storeDualHsimd) TEST_F(SimdFloatingpointUtilTest, incrDualHsimd) { - real reference[GMX_SIMD_REAL_WIDTH]; - SimdReal v0; + real reference[GMX_SIMD_REAL_WIDTH]; + SimdReal v0; // Create reference values for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -780,7 +779,7 @@ TEST_F(SimdFloatingpointUtilTest, incrDualHsimd) } // Point p to the upper half of val0_ - real * p = val0_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val0_ + GMX_SIMD_REAL_WIDTH / 2; v0 = load(val2_); incrDualHsimd(val0_, p, v0); @@ -793,19 +792,19 @@ TEST_F(SimdFloatingpointUtilTest, incrDualHsimd) TEST_F(SimdFloatingpointUtilTest, incrDualHsimdOverlapping) { - real reference[GMX_SIMD_REAL_WIDTH/2]; - SimdReal v0; + real reference[GMX_SIMD_REAL_WIDTH / 2]; + SimdReal v0; // Create reference values - for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH/2; i++) + for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH / 2; i++) { - reference[i] = val0_[i] + val2_[i] + val2_[GMX_SIMD_REAL_WIDTH/2+i]; + reference[i] = val0_[i] + val2_[i] + val2_[GMX_SIMD_REAL_WIDTH / 2 + i]; } v0 = load(val2_); incrDualHsimd(val0_, val0_, v0); - for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH/2; i++) + for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH / 2; i++) { EXPECT_EQ(reference[i], val0_[i]); } @@ -813,16 +812,16 @@ TEST_F(SimdFloatingpointUtilTest, incrDualHsimdOverlapping) TEST_F(SimdFloatingpointUtilTest, decrHsimd) { - SimdReal v0; - real ref[GMX_SIMD_REAL_WIDTH / 2]; - int i; - FloatingPointTolerance tolerance(defaultRealTolerance()); + SimdReal v0; + real ref[GMX_SIMD_REAL_WIDTH / 2]; + int i; + FloatingPointTolerance tolerance(defaultRealTolerance()); // Point p to the upper half of val1_ - real * p = val1_ + GMX_SIMD_REAL_WIDTH / 2; + real* p = val1_ + GMX_SIMD_REAL_WIDTH / 2; for (i = 0; i < GMX_SIMD_REAL_WIDTH / 2; i++) { - ref[i] = val0_[i] - ( val1_[i] + p[i] ); + ref[i] = val0_[i] - (val1_[i] + p[i]); } v0 = load(val1_); @@ -837,12 +836,12 @@ TEST_F(SimdFloatingpointUtilTest, decrHsimd) TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2Hsimd) { - SimdReal v0, v1; - SimdReal ref0, ref1; + SimdReal v0, v1; + SimdReal ref0, ref1; - const int nalign = 3; - int alignmentList[nalign] = { 2, 4, c_simdBestPairAlignment }; - int i, j, align; + const int nalign = 3; + int alignmentList[nalign] = { 2, 4, c_simdBestPairAlignment }; + int i, j, align; for (i = 0; i < nalign; i++) { @@ -850,12 +849,11 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2Hsimd) for (j = 0; j < GMX_SIMD_REAL_WIDTH / 2; j++) { // Use mem0_ as base for lower half - mem0_[align * offset_[j] ] = val0_[j]; + mem0_[align * offset_[j]] = val0_[j]; mem0_[align * offset_[j] + 1] = val1_[j]; // Use mem1_ as base for upper half - mem1_[align * offset_[j] ] = val0_[GMX_SIMD_REAL_WIDTH / 2 + j]; + mem1_[align * offset_[j]] = val0_[GMX_SIMD_REAL_WIDTH / 2 + j]; mem1_[align * offset_[j] + 1] = val1_[GMX_SIMD_REAL_WIDTH / 2 + j]; - } ref0 = load(val0_); @@ -886,10 +884,10 @@ TEST_F(SimdFloatingpointUtilTest, gatherLoadTranspose2Hsimd) TEST_F(SimdFloatingpointUtilTest, reduceIncr4SumHsimd) { - int i; - SimdReal v0, v1; - real sum0, sum1, sum2, sum3, tstsum; - FloatingPointTolerance tolerance(defaultRealTolerance()); + int i; + SimdReal v0, v1; + real sum0, sum1, sum2, sum3, tstsum; + FloatingPointTolerance tolerance(defaultRealTolerance()); // Use the half-SIMD storage in memory val0_ and val1_. v0 = load(val0_); @@ -920,24 +918,24 @@ TEST_F(SimdFloatingpointUtilTest, reduceIncr4SumHsimd) EXPECT_REAL_EQ_TOL(sum0 + sum1 + sum2 + sum3, tstsum, tolerance); } -#endif // GMX_SIMD_HAVE_HSIMD_UTIL_REAL +# endif // GMX_SIMD_HAVE_HSIMD_UTIL_REAL -//Test Currently doesn't work for GMX_SIMD_REAL_WIDTH<4. Should be fixed by having GMX_EXPECT_SIMD_REAL_EQ which works for both Simd and Simd4 -#if GMX_SIMD_HAVE_4NSIMD_UTIL_REAL && GMX_SIMD_REAL_WIDTH >= 4 +// Test Currently doesn't work for GMX_SIMD_REAL_WIDTH<4. Should be fixed by having GMX_EXPECT_SIMD_REAL_EQ which works for both Simd and Simd4 +# if GMX_SIMD_HAVE_4NSIMD_UTIL_REAL && GMX_SIMD_REAL_WIDTH >= 4 TEST_F(SimdFloatingpointUtilTest, loadUNDuplicate4) { - Simd4NReal v0, v1; - int i; - real data[GMX_SIMD_REAL_WIDTH/4]; - std::iota(data, data+GMX_SIMD_REAL_WIDTH/4, 1); - -#if defined __ICC && __ICC == 1800 || defined __ICL && __ICL == 1800 -#pragma novector /* Work-around for incorrect vectorization for AVX_512(_KNL) */ -#endif + Simd4NReal v0, v1; + int i; + real data[GMX_SIMD_REAL_WIDTH / 4]; + std::iota(data, data + GMX_SIMD_REAL_WIDTH / 4, 1); + +# if defined __ICC && __ICC == 1800 || defined __ICL && __ICL == 1800 +# pragma novector /* Work-around for incorrect vectorization for AVX_512(_KNL) */ +# endif for (i = 0; i < GMX_SIMD_REAL_WIDTH / 4; i++) { - val0_[i*4] = val0_[i*4+1] = val0_[i*4+2] = val0_[i*4+3] = data[i]; + val0_[i * 4] = val0_[i * 4 + 1] = val0_[i * 4 + 2] = val0_[i * 4 + 3] = data[i]; } v0 = load(val0_); @@ -948,16 +946,16 @@ TEST_F(SimdFloatingpointUtilTest, loadUNDuplicate4) TEST_F(SimdFloatingpointUtilTest, load4DuplicateN) { - Simd4NReal v0, v1; - int i; - real data[4] = { 1, 2, 3, 4}; + Simd4NReal v0, v1; + int i; + real data[4] = { 1, 2, 3, 4 }; for (i = 0; i < GMX_SIMD_REAL_WIDTH / 4; i++) { - val0_[i*4] = data[0]; - val0_[i*4+1] = data[1]; - val0_[i*4+2] = data[2]; - val0_[i*4+3] = data[3]; + val0_[i * 4] = data[0]; + val0_[i * 4 + 1] = data[1]; + val0_[i * 4 + 2] = data[2]; + val0_[i * 4 + 3] = data[3]; } v0 = load(val0_); @@ -968,17 +966,17 @@ TEST_F(SimdFloatingpointUtilTest, load4DuplicateN) TEST_F(SimdFloatingpointUtilTest, loadU4NOffset) { - constexpr int offset = 6; //non power of 2 - constexpr int dataLen = 4+offset*(GMX_SIMD_REAL_WIDTH/4-1); - real data[dataLen]; - std::iota(data, data+dataLen, 1); + constexpr int offset = 6; // non power of 2 + constexpr int dataLen = 4 + offset * (GMX_SIMD_REAL_WIDTH / 4 - 1); + real data[dataLen]; + std::iota(data, data + dataLen, 1); for (int i = 0; i < GMX_SIMD_REAL_WIDTH / 4; i++) { - val0_[i*4] = data[0+offset*i]; - val0_[i*4+1] = data[1+offset*i]; - val0_[i*4+2] = data[2+offset*i]; - val0_[i*4+3] = data[3+offset*i]; + val0_[i * 4] = data[0 + offset * i]; + val0_[i * 4 + 1] = data[1 + offset * i]; + val0_[i * 4 + 2] = data[2 + offset * i]; + val0_[i * 4 + 3] = data[3 + offset * i]; } const Simd4NReal v0 = load(val0_); @@ -987,13 +985,13 @@ TEST_F(SimdFloatingpointUtilTest, loadU4NOffset) GMX_EXPECT_SIMD_REAL_EQ(v0, v1); } -#endif // GMX_SIMD_HAVE_4NSIMD_UTIL_REAL +# endif // GMX_SIMD_HAVE_4NSIMD_UTIL_REAL -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/gromacs/simd/tests/simd_integer.cpp b/src/gromacs/simd/tests/simd_integer.cpp index 6024e2b3e9..d0422fda88 100644 --- a/src/gromacs/simd/tests/simd_integer.cpp +++ b/src/gromacs/simd/tests/simd_integer.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,7 +75,7 @@ typedef SimdTest SimdIntegerTest; * The second we have default-precision floating-point SIMD, we also have * the integer SIMD dataype and the most fundamental load/store ops. */ -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL TEST_F(SimdIntegerTest, setZero) { @@ -85,30 +85,31 @@ TEST_F(SimdIntegerTest, set) { GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(1), SimdInt32(1)); } -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD_HAVE_INT32_ARITHMETICS +# if GMX_SIMD_HAVE_INT32_ARITHMETICS TEST_F(SimdIntegerTest, add) { - GMX_EXPECT_SIMD_INT_EQ(iSimd_5_7_9, iSimd_1_2_3 + iSimd_4_5_6 ); // short add + GMX_EXPECT_SIMD_INT_EQ(iSimd_5_7_9, iSimd_1_2_3 + iSimd_4_5_6); // short add GMX_EXPECT_SIMD_INT_EQ(iSimd_5M_7M_9M, iSimd_1M_2M_3M + iSimd_4M_5M_6M); // 32 bit add } TEST_F(SimdIntegerTest, sub) { - GMX_EXPECT_SIMD_INT_EQ(iSimd_1_2_3, iSimd_5_7_9 - iSimd_4_5_6 ); // short sub - GMX_EXPECT_SIMD_INT_EQ(iSimd_1M_2M_3M, iSimd_5M_7M_9M - iSimd_4M_5M_6M ); // 32 bit sub + GMX_EXPECT_SIMD_INT_EQ(iSimd_1_2_3, iSimd_5_7_9 - iSimd_4_5_6); // short sub + GMX_EXPECT_SIMD_INT_EQ(iSimd_1M_2M_3M, iSimd_5M_7M_9M - iSimd_4M_5M_6M); // 32 bit sub } TEST_F(SimdIntegerTest, mul) { - GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(4, 10, 18), iSimd_1_2_3 * iSimd_4_5_6); // 2*3=6 (short mul) - GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(268435456), SimdInt32(16384) * SimdInt32(16384) ); // 16384*16384 = 268435456 (long mul) + GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(4, 10, 18), iSimd_1_2_3 * iSimd_4_5_6); // 2*3=6 (short mul) + GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(268435456), + SimdInt32(16384) * SimdInt32(16384)); // 16384*16384 = 268435456 (long mul) } -#endif // GMX_SIMD_HAVE_INT32_ARITHMETICS +# endif // GMX_SIMD_HAVE_INT32_ARITHMETICS -#if GMX_SIMD_HAVE_INT32_LOGICAL +# if GMX_SIMD_HAVE_INT32_LOGICAL TEST_F(SimdIntegerTest, and) { GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(0xC0C0C0C0), iSimd_0xF0F0F0F0 & iSimd_0xCCCCCCCC); @@ -126,19 +127,19 @@ TEST_F(SimdIntegerTest, or) TEST_F(SimdIntegerTest, xor) { - GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(0x3C3C3C3C), iSimd_0xF0F0F0F0 ^iSimd_0xCCCCCCCC); + GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(0x3C3C3C3C), iSimd_0xF0F0F0F0 ^ iSimd_0xCCCCCCCC); } -#endif // GMX_SIMD_HAVE_INT32_LOGICAL +# endif // GMX_SIMD_HAVE_INT32_LOGICAL -#if GMX_SIMD_HAVE_INT32_EXTRACT +# if GMX_SIMD_HAVE_INT32_EXTRACT TEST_F(SimdIntegerTest, extract) { - alignas(GMX_SIMD_ALIGNMENT) std::int32_t idata[GMX_SIMD_REAL_WIDTH]; - SimdInt32 simd; + alignas(GMX_SIMD_ALIGNMENT) std::int32_t idata[GMX_SIMD_REAL_WIDTH]; + SimdInt32 simd; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { - idata[i] = i+1; + idata[i] = i + 1; } simd = load(idata); @@ -152,26 +153,26 @@ TEST_F(SimdIntegerTest, extract) int extracted_int; extracted_int = extract<0>(simd); EXPECT_EQ(1, extracted_int); -#if GMX_SIMD_REAL_WIDTH >= 2 +# if GMX_SIMD_REAL_WIDTH >= 2 extracted_int = extract<1>(simd); EXPECT_EQ(2, extracted_int); -#endif -#if GMX_SIMD_REAL_WIDTH >= 4 +# endif +# if GMX_SIMD_REAL_WIDTH >= 4 extracted_int = extract<3>(simd); EXPECT_EQ(4, extracted_int); -#endif -#if GMX_SIMD_REAL_WIDTH >= 6 +# endif +# if GMX_SIMD_REAL_WIDTH >= 6 extracted_int = extract<5>(simd); EXPECT_EQ(6, extracted_int); -#endif -#if GMX_SIMD_REAL_WIDTH >= 8 +# endif +# if GMX_SIMD_REAL_WIDTH >= 8 extracted_int = extract<7>(simd); EXPECT_EQ(8, extracted_int); -#endif +# endif } -#endif // GMX_SIMD_HAVE_INT32_EXTRACT +# endif // GMX_SIMD_HAVE_INT32_EXTRACT -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL TEST_F(SimdIntegerTest, cvtR2I) { GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(2), cvtR2I(rSimd_2p25)); @@ -187,14 +188,14 @@ TEST_F(SimdIntegerTest, cvtR2I) GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(123456), cvtR2I(setSimdRealFrom1R(123456.3))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-123456), cvtR2I(setSimdRealFrom1R(-123456.3))); -#if GMX_DOUBLE +# if GMX_DOUBLE // Test number with more digits than we can represent in single. // Note that our SIMD integers are only 32 bits, so we cannot go beyond that. GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(12345679), cvtR2I(setSimdRealFrom1R(12345678.6))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-12345679), cvtR2I(setSimdRealFrom1R(-12345678.6))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(12345678), cvtR2I(setSimdRealFrom1R(12345678.3))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-12345678), cvtR2I(setSimdRealFrom1R(-12345678.3))); -#endif +# endif } TEST_F(SimdIntegerTest, cvttR2I) @@ -212,14 +213,14 @@ TEST_F(SimdIntegerTest, cvttR2I) GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(123456), cvttR2I(setSimdRealFrom1R(123456.3))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-123456), cvttR2I(setSimdRealFrom1R(-123456.3))); -#if GMX_DOUBLE +# if GMX_DOUBLE // Test number with more digits than we can represent in single. // Note that our SIMD integers are only 32 bits, so we cannot go beyond that. GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(12345678), cvttR2I(setSimdRealFrom1R(12345678.6))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-12345678), cvttR2I(setSimdRealFrom1R(-12345678.6))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(12345678), cvttR2I(setSimdRealFrom1R(12345678.3))); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom1I(-12345678), cvttR2I(setSimdRealFrom1R(-12345678.3))); -#endif +# endif } TEST_F(SimdIntegerTest, cvtI2R) @@ -229,54 +230,54 @@ TEST_F(SimdIntegerTest, cvtI2R) GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(102448689), cvtI2R(SimdInt32(102448689))); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(-102448689), cvtI2R(SimdInt32(-102448689))); } -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL -#if GMX_SIMD_HAVE_INT32_ARITHMETICS +# if GMX_SIMD_HAVE_INT32_ARITHMETICS TEST_F(SimdIntegerTest, cmpEqAndSelectMask) { - SimdIBool eq = (iSimd_5_7_9 == iSimd_7_8_9); + SimdIBool eq = (iSimd_5_7_9 == iSimd_7_8_9); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(0, 0, 3), selectByMask(iSimd_1_2_3, eq)); } TEST_F(SimdIntegerTest, cmpEqAndSelectNotMask) { - SimdIBool eq = (iSimd_5_7_9 == iSimd_7_8_9); + SimdIBool eq = (iSimd_5_7_9 == iSimd_7_8_9); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 2, 0), selectByNotMask(iSimd_1_2_3, eq)); } TEST_F(SimdIntegerTest, cmpLt) { - SimdIBool lt = (iSimd_5_7_9 < iSimd_7_8_9); + SimdIBool lt = (iSimd_5_7_9 < iSimd_7_8_9); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 2, 0), selectByMask(iSimd_1_2_3, lt)); } TEST_F(SimdIntegerTest, testBits) { - SimdIBool eq = testBits(setSimdIntFrom3I(1, 0, 2)); + SimdIBool eq = testBits(setSimdIntFrom3I(1, 0, 2)); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 0, 3), selectByMask(iSimd_1_2_3, eq)); // Test if we detect only the sign bit being set - eq = testBits(setSimdIntFrom1I(0x80000000)); + eq = testBits(setSimdIntFrom1I(0x80000000)); GMX_EXPECT_SIMD_INT_EQ(iSimd_1_2_3, selectByMask(iSimd_1_2_3, eq)); } TEST_F(SimdIntegerTest, andB) { - SimdIBool eq1 = (iSimd_5_7_9 == iSimd_7_8_9); - SimdIBool eq2 = (iSimd_5_7_9 == iSimd_5_7_9); + SimdIBool eq1 = (iSimd_5_7_9 == iSimd_7_8_9); + SimdIBool eq2 = (iSimd_5_7_9 == iSimd_5_7_9); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(0, 0, 3), selectByMask(iSimd_1_2_3, eq1 && eq2)); } TEST_F(SimdIntegerTest, orB) { - SimdIBool eq1 = (iSimd_5_7_9 == iSimd_7_8_9); - SimdIBool eq2 = (iSimd_5_7_9 == setSimdIntFrom3I(5, 0, 0)); + SimdIBool eq1 = (iSimd_5_7_9 == iSimd_7_8_9); + SimdIBool eq2 = (iSimd_5_7_9 == setSimdIntFrom3I(5, 0, 0)); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 0, 3), selectByMask(iSimd_1_2_3, eq1 || eq2)); } TEST_F(SimdIntegerTest, anyTrue) { - alignas(GMX_SIMD_ALIGNMENT) std::array mem {}; + alignas(GMX_SIMD_ALIGNMENT) std::array mem{}; // Test the false case EXPECT_FALSE(anyTrue(setZero() < load(mem.data()))); @@ -286,39 +287,39 @@ TEST_F(SimdIntegerTest, anyTrue) { mem.fill(0); mem[i] = 1; - EXPECT_TRUE(anyTrue(setZero() < load(mem.data()))) << "Not detecting true in element " << i; + EXPECT_TRUE(anyTrue(setZero() < load(mem.data()))) + << "Not detecting true in element " << i; } } TEST_F(SimdIntegerTest, blend) { - SimdIBool lt = (iSimd_5_7_9 < iSimd_7_8_9); + SimdIBool lt = (iSimd_5_7_9 < iSimd_7_8_9); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(4, 5, 3), blend(iSimd_1_2_3, iSimd_4_5_6, lt)); } -#endif // GMX_SIMD_HAVE_INT32_ARITHMETICS +# endif // GMX_SIMD_HAVE_INT32_ARITHMETICS -#if GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS +# if GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS TEST_F(SimdIntegerTest, cvtB2IB) { - SimdBool eq = (rSimd_c3c4c5 == rSimd_c3c0c4); // eq should be T,F,F - SimdIBool eqi = cvtB2IB(eq); + SimdBool eq = (rSimd_c3c4c5 == rSimd_c3c0c4); // eq should be T,F,F + SimdIBool eqi = cvtB2IB(eq); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 0, 0), selectByMask(iSimd_1_2_3, eqi)); - } TEST_F(SimdIntegerTest, cvtIB2B) { - SimdIBool eqi = (iSimd_5_7_9 == setSimdIntFrom3I(5, 0, 0)); // eq should be T,F,F - SimdBool eq = cvtIB2B(eqi); + SimdIBool eqi = (iSimd_5_7_9 == setSimdIntFrom3I(5, 0, 0)); // eq should be T,F,F + SimdBool eq = cvtIB2B(eqi); GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, 0, 0), selectByMask(rSimd_c0c1c2, eq)); } -#endif // GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS +# endif // GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd_math.cpp b/src/gromacs/simd/tests/simd_math.cpp index 959009013a..f5e9f74e38 100644 --- a/src/gromacs/simd/tests/simd_math.cpp +++ b/src/gromacs/simd/tests/simd_math.cpp @@ -65,101 +65,95 @@ namespace test /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL class SimdMathTest : public SimdTest { - public: - - /*! \brief Type for half-open intervals specifying test ranges */ - typedef std::pair Range; - - /*! \brief Control what is considered matching values - * - * Normal simply means that we request the values to be equal - * to within the specified tolerance. - * However, there are also two more cases that are special: - * - * - Even if we only care about normal (i.e., not denormal) values, some math - * libraries might clamp the value to zero, which means our SIMD output - * might not match their values. By using MatchRule::Dtz, we will consider - * all values both from the reference and test functions that are within the - * requested ulp tolerance of a denormal number to be equivalent to 0.0. - * - For some older architectures without fused multiply-add units (e.g. x86 SSE2), - * we might end up clamping the results to zero just before reaching - * denormal output, since the intermediate results e.g. in polynomial - * approximations can be smaller than the final one. We often simply don't - * care about those values, and then one can use - * MatchRule::ReferenceOrZero to allow the test value to either match - * the reference or be zero. - */ - enum class MatchRule - { - Normal, //!< Match function values - Dtz, //!< Match function values after setting denormals to zero both in test and reference - ReferenceOrZero, //!< Test values can either match reference or be zero - }; +public: + /*! \brief Type for half-open intervals specifying test ranges */ + typedef std::pair Range; + + /*! \brief Control what is considered matching values + * + * Normal simply means that we request the values to be equal + * to within the specified tolerance. + * However, there are also two more cases that are special: + * + * - Even if we only care about normal (i.e., not denormal) values, some math + * libraries might clamp the value to zero, which means our SIMD output + * might not match their values. By using MatchRule::Dtz, we will consider + * all values both from the reference and test functions that are within the + * requested ulp tolerance of a denormal number to be equivalent to 0.0. + * - For some older architectures without fused multiply-add units (e.g. x86 SSE2), + * we might end up clamping the results to zero just before reaching + * denormal output, since the intermediate results e.g. in polynomial + * approximations can be smaller than the final one. We often simply don't + * care about those values, and then one can use + * MatchRule::ReferenceOrZero to allow the test value to either match + * the reference or be zero. + */ + enum class MatchRule + { + Normal, //!< Match function values + Dtz, //!< Match function values after setting denormals to zero both in test and reference + ReferenceOrZero, //!< Test values can either match reference or be zero + }; - const std::map matchRuleNames_ = - { - { MatchRule::Normal, "Test should match reference." }, - { MatchRule::Dtz, "Test should match reference, with denormals treated as 0.0." }, - { MatchRule::ReferenceOrZero, "Test should match reference or 0.0." } - }; + const std::map matchRuleNames_ = { + { MatchRule::Normal, "Test should match reference." }, + { MatchRule::Dtz, "Test should match reference, with denormals treated as 0.0." }, + { MatchRule::ReferenceOrZero, "Test should match reference or 0.0." } + }; - /*! \brief Settings used for simd math function comparisons */ - struct CompareSettings - { - Range range; //!< Range over which to test function - std::int64_t ulpTol; //!< Ulp tolerance - real absTol; //!< Absolute tolerance - MatchRule matchRule; //!< Decide what we consider a match - }; - - ::testing::AssertionResult - compareSimdMathFunction(const char * refFuncExpr, - const char * simdFuncExpr, - const char * compareSettingsExpr, - real refFunc(real x), - SimdReal gmx_simdcall simdFunc(SimdReal x), - const CompareSettings &compareSettings); - - /*! \brief Generate test point vector - * - * \param range The test interval, half open. Upper limit is not included. - * Pass by value, since we need to modify in method anyway. - * \param points Number of points to generate. This might be increased - * slightly to account both for extra special values like 0.0 - * and the SIMD width. - * - * This routine generates a vector with test points separated by constant - * multiplicative factors, based on the range and number of points in the - * class. If the range includes both negative and positive values, points - * will be generated separately for the negative/positive intervals down - * to the smallest real number that can be represented, and we also include - * 0.0 explicitly. - * - * This is highly useful for large test ranges. For example, with a linear - * 1000-point division of the range (1,1e10) the first three values to test - * would be 1, 10000000.999, and 20000000.998, etc. For large values we would - * commonly hit the point where adding the small delta has no effect due to - * limited numerical precision. - * When we instead use this routine, the values will be 1, 1.0239, 1.0471, etc. - * This will spread the entropy over all bits in the IEEE754 representation, - * and be a much better test of all potential input values. - * - * \note We do not use the static variable s_nPoints in the parent class - * to avoid altering any value the user has set on the command line; since - * it's a static member, changing it would have permanent effect. - */ - std::vector - generateTestPoints(Range range, std::size_t points); - - /*! \brief Test routine for the test point vector generation - */ - void - generateTestPointsTest(); + /*! \brief Settings used for simd math function comparisons */ + struct CompareSettings + { + Range range; //!< Range over which to test function + std::int64_t ulpTol; //!< Ulp tolerance + real absTol; //!< Absolute tolerance + MatchRule matchRule; //!< Decide what we consider a match + }; + ::testing::AssertionResult compareSimdMathFunction(const char* refFuncExpr, + const char* simdFuncExpr, + const char* compareSettingsExpr, + real refFunc(real x), + SimdReal gmx_simdcall simdFunc(SimdReal x), + const CompareSettings& compareSettings); + + /*! \brief Generate test point vector + * + * \param range The test interval, half open. Upper limit is not included. + * Pass by value, since we need to modify in method anyway. + * \param points Number of points to generate. This might be increased + * slightly to account both for extra special values like 0.0 + * and the SIMD width. + * + * This routine generates a vector with test points separated by constant + * multiplicative factors, based on the range and number of points in the + * class. If the range includes both negative and positive values, points + * will be generated separately for the negative/positive intervals down + * to the smallest real number that can be represented, and we also include + * 0.0 explicitly. + * + * This is highly useful for large test ranges. For example, with a linear + * 1000-point division of the range (1,1e10) the first three values to test + * would be 1, 10000000.999, and 20000000.998, etc. For large values we would + * commonly hit the point where adding the small delta has no effect due to + * limited numerical precision. + * When we instead use this routine, the values will be 1, 1.0239, 1.0471, etc. + * This will spread the entropy over all bits in the IEEE754 representation, + * and be a much better test of all potential input values. + * + * \note We do not use the static variable s_nPoints in the parent class + * to avoid altering any value the user has set on the command line; since + * it's a static member, changing it would have permanent effect. + */ + std::vector generateTestPoints(Range range, std::size_t points); + + /*! \brief Test routine for the test point vector generation + */ + void generateTestPointsTest(); }; /*! \brief Test approximate equality of SIMD vs reference version of a function. @@ -169,24 +163,24 @@ class SimdMathTest : public SimdTest * * The third option controls the range, tolerances, and match settings. */ -#define GMX_EXPECT_SIMD_FUNC_NEAR(refFunc, tstFunc, compareSettings) \ - EXPECT_PRED_FORMAT3(compareSimdMathFunction, refFunc, tstFunc, compareSettings) +# define GMX_EXPECT_SIMD_FUNC_NEAR(refFunc, tstFunc, compareSettings) \ + EXPECT_PRED_FORMAT3(compareSimdMathFunction, refFunc, tstFunc, compareSettings) -std::vector -SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) +std::vector SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) { std::vector testPoints; testPoints.reserve(inputPoints); - GMX_RELEASE_ASSERT(inputRange.first < inputRange.second, "The start of the interval must come before the end"); + GMX_RELEASE_ASSERT(inputRange.first < inputRange.second, + "The start of the interval must come before the end"); std::vector testRanges; if (inputRange.first < 0 && inputRange.second > 0) { - testRanges.emplace_back(Range({inputRange.first, -std::numeric_limits::min()})); - testRanges.emplace_back(Range({0.0, inputRange.second})); + testRanges.emplace_back(Range({ inputRange.first, -std::numeric_limits::min() })); + testRanges.emplace_back(Range({ 0.0, inputRange.second })); } else { @@ -198,7 +192,7 @@ SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) testRanges.push_back(inputRange); } - for (Range &range : testRanges) + for (Range& range : testRanges) { std::size_t points = inputPoints / testRanges.size(); @@ -213,12 +207,10 @@ SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) points--; // Used one point } - union - { + union { real r; std::conditional::type i; - } - low, high, x; + } low, high, x; low.r = range.first; high.r = range.second; @@ -228,9 +220,9 @@ SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) // in the bitwise representation corresponds to a constant multiplicative factor. // // Divide the ulp difference evenly - std::int64_t ulpDiff = high.i-low.i; + std::int64_t ulpDiff = high.i - low.i; // dividend and divisor must both be signed types - std::int64_t ulpDelta = ulpDiff/static_cast(points); + std::int64_t ulpDelta = ulpDiff / static_cast(points); std::int64_t minUlpDelta = (ulpDiff > 0) ? 1 : -1; if (ulpDelta == 0) @@ -245,14 +237,14 @@ SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) // Use an index-based loop to avoid floating-point comparisons with // values that might have overflowed. Save one point for the very last // bitwise value that is part of the interval - for (std::size_t i = 0; i < points-1; i++) + for (std::size_t i = 0; i < points - 1; i++) { testPoints.push_back(x.r); x.i += ulpDelta; } // Make sure we test the very last point that is inside the interval - x.r = high.r; + x.r = high.r; x.i -= minUlpDelta; testPoints.push_back(x.r); } @@ -272,26 +264,24 @@ SimdMathTest::generateTestPoints(Range inputRange, std::size_t inputPoints) * \note You should not never call this function directly, but use the * macro GMX_EXPECT_SIMD_FUNC_NEAR(refFunc,tstFunc,matchRule) instead. */ -::testing::AssertionResult -SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, - const char * simdFuncExpr, - const char gmx_unused * compareSettingsExpr, - real refFunc(real x), - SimdReal gmx_simdcall simdFunc(SimdReal x), - const CompareSettings &compareSettings) -{ - std::vector vx(GMX_SIMD_REAL_WIDTH); - std::vector vref(GMX_SIMD_REAL_WIDTH); - std::vector vtst(GMX_SIMD_REAL_WIDTH); - real absDiff; - std::int64_t ulpDiff; - std::int64_t maxUlpDiff = 0; - real maxUlpDiffPos; - real refValMaxUlpDiff, simdValMaxUlpDiff; - const int niter = s_nPoints/GMX_SIMD_REAL_WIDTH; - - union - { +::testing::AssertionResult SimdMathTest::compareSimdMathFunction(const char* refFuncExpr, + const char* simdFuncExpr, + const char gmx_unused* compareSettingsExpr, + real refFunc(real x), + SimdReal gmx_simdcall simdFunc(SimdReal x), + const CompareSettings& compareSettings) +{ + std::vector vx(GMX_SIMD_REAL_WIDTH); + std::vector vref(GMX_SIMD_REAL_WIDTH); + std::vector vtst(GMX_SIMD_REAL_WIDTH); + real absDiff; + std::int64_t ulpDiff; + std::int64_t maxUlpDiff = 0; + real maxUlpDiffPos; + real refValMaxUlpDiff, simdValMaxUlpDiff; + const int niter = s_nPoints / GMX_SIMD_REAL_WIDTH; + + union { real r; std::conditional::type i; } conv0, conv1; @@ -304,9 +294,9 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, // Calculate the tolerance limit to use for denormals - we want // values that are within the ulp tolerance of denormals to be considered matching - conv0.r = std::numeric_limits::min(); - conv0.i += compareSettings.ulpTol - 1; // min() itself is not denormal, but one ulp larger - const real denormalLimit = conv0.r; + conv0.r = std::numeric_limits::min(); + conv0.i += compareSettings.ulpTol - 1; // min() itself is not denormal, but one ulp larger + const real denormalLimit = conv0.r; // We want to test as many diverse bit combinations as possible over the range requested, // and in particular do it evenly spaced in bit-space. @@ -316,7 +306,7 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, // specific testing values to a separate routine std::vector testPoints = generateTestPoints(compareSettings.range, s_nPoints); - size_t pointIndex = 0; + size_t pointIndex = 0; for (int iter = 0; iter < niter; iter++) { @@ -326,18 +316,18 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, vref[i] = refFunc(vx[i]); // If we reach the end of the points, stop increasing index so we pad with // extra copies of the last element up to the SIMD width - if (pointIndex + 1 < testPoints.size() ) + if (pointIndex + 1 < testPoints.size()) { pointIndex++; } } - vtst = simdReal2Vector(simdFunc(vector2SimdReal(vx))); + vtst = simdReal2Vector(simdFunc(vector2SimdReal(vx))); bool absOk = true, signOk = true; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { - if (compareSettings.matchRule == MatchRule::Dtz && - std::abs(vref[i]) <= denormalLimit && std::abs(vtst[i]) <= denormalLimit) + if (compareSettings.matchRule == MatchRule::Dtz && std::abs(vref[i]) <= denormalLimit + && std::abs(vtst[i]) <= denormalLimit) { continue; } @@ -348,9 +338,9 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, continue; } - absDiff = std::abs(vref[i]-vtst[i]); - absOk = absOk && ( absDiff < compareSettings.absTol ); - signOk = signOk && ( (vref[i] >= 0 && vtst[i] >= 0) || (vref[i] <= 0 && vtst[i] <= 0)); + absDiff = std::abs(vref[i] - vtst[i]); + absOk = absOk && (absDiff < compareSettings.absTol); + signOk = signOk && ((vref[i] >= 0 && vtst[i] >= 0) || (vref[i] <= 0 && vtst[i] <= 0)); if (absDiff >= compareSettings.absTol) { @@ -359,9 +349,9 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, * us to run through the entire test range and report the largest deviation * without lots of extra glue routines. */ - conv0.r = vref[i]; - conv1.r = vtst[i]; - ulpDiff = llabs(conv0.i-conv1.i); + conv0.r = vref[i]; + conv1.r = vtst[i]; + ulpDiff = llabs(conv0.i - conv1.i); if (ulpDiff > maxUlpDiff) { maxUlpDiff = ulpDiff; @@ -371,17 +361,21 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, } } } - if ( (!absOk) && (!signOk) ) + if ((!absOk) && (!signOk)) { return ::testing::AssertionFailure() << "Failing SIMD math function comparison due to sign differences." << std::endl << "Reference function: " << refFuncExpr << std::endl << "Simd function: " << simdFuncExpr << std::endl - << "Test range is ( " << compareSettings.range.first << " , " << compareSettings.range.second << " ) " << std::endl + << "Test range is ( " << compareSettings.range.first << " , " + << compareSettings.range.second << " ) " << std::endl << "Match rule: " << matchRuleNames_.at(compareSettings.matchRule) << std::endl - << "First sign difference around x=" << std::setprecision(20) << ::testing::PrintToString(vx) << std::endl - << "Ref values: " << std::setprecision(20) << ::testing::PrintToString(vref) << std::endl - << "SIMD values: " << std::setprecision(20) << ::testing::PrintToString(vtst) << std::endl; + << "First sign difference around x=" << std::setprecision(20) + << ::testing::PrintToString(vx) << std::endl + << "Ref values: " << std::setprecision(20) << ::testing::PrintToString(vref) + << std::endl + << "SIMD values: " << std::setprecision(20) << ::testing::PrintToString(vtst) + << std::endl; } } @@ -393,11 +387,13 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, else { return ::testing::AssertionFailure() - << "Failing SIMD math function ulp comparison between " << refFuncExpr << " and " << simdFuncExpr << std::endl + << "Failing SIMD math function ulp comparison between " << refFuncExpr << " and " + << simdFuncExpr << std::endl << "Requested ulp tolerance: " << compareSettings.ulpTol << std::endl << "Requested abs tolerance: " << compareSettings.absTol << std::endl << "Match rule: " << matchRuleNames_.at(compareSettings.matchRule) << std::endl - << "Largest Ulp difference occurs for x=" << std::setprecision(20) << maxUlpDiffPos << std::endl + << "Largest Ulp difference occurs for x=" << std::setprecision(20) << maxUlpDiffPos + << std::endl << "Ref values: " << std::setprecision(20) << refValMaxUlpDiff << std::endl << "SIMD values: " << std::setprecision(20) << simdValMaxUlpDiff << std::endl << "Ulp diff.: " << std::setprecision(20) << maxUlpDiff << std::endl; @@ -407,14 +403,13 @@ SimdMathTest::compareSimdMathFunction(const char * refFuncExpr, // Actual routine to generate a small set of test points in current precision. This will // be called by either the double or single precision test fixture, since we need different // test names to compare to the right reference data. -void -SimdMathTest::generateTestPointsTest() +void SimdMathTest::generateTestPointsTest() { - int points(10); - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); + int points(10); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); - std::vector result; + std::vector result; result = generateTestPoints(Range(-1e10, -1), points); checker.checkSequence(result.begin(), result.end(), "Test points for interval [-1e10,-1["); @@ -462,40 +457,41 @@ namespace /*! \{ */ // Reference data is selected based on test name, so make the test name precision-dependent -#if GMX_DOUBLE +# if GMX_DOUBLE TEST_F(SimdMathTest, generateTestPointsDouble) { generateTestPointsTest(); } -#else +# else TEST_F(SimdMathTest, generateTestPointsFloat) { generateTestPointsTest(); } -#endif +# endif TEST_F(SimdMathTest, copysign) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), copysign(setSimdRealFrom3R( c0, c1, c2), setSimdRealFrom3R(-c3, c4, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R(-c3, c4, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, -c1, c2), copysign(setSimdRealFrom3R( c0, c1, c2), setSimdRealFrom3R( c3, -c4, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, -c1, c2), copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R( c3, -c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), + copysign(setSimdRealFrom3R(c0, c1, c2), setSimdRealFrom3R(-c3, c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), + copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R(-c3, c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, -c1, c2), + copysign(setSimdRealFrom3R(c0, c1, c2), setSimdRealFrom3R(c3, -c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, -c1, c2), + copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R(c3, -c4, 0))); } /*! \brief Function wrapper to evaluate reference 1/sqrt(x) */ -real -refInvsqrt(real x) +real refInvsqrt(real x) { - return 1.0/std::sqrt(x); + return 1.0 / std::sqrt(x); } TEST_F(SimdMathTest, invsqrt) { const real low = std::numeric_limits::min(); const real high = std::numeric_limits::max(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, invsqrt, settings); } @@ -504,13 +500,12 @@ TEST_F(SimdMathTest, maskzInvsqrt) { SimdReal x = setSimdRealFrom3R(c1, 0.0, c2); SimdBool m = (setZero() < x); - SimdReal ref = setSimdRealFrom3R(1.0/std::sqrt(c1), 0.0, 1.0/std::sqrt(c2)); + SimdReal ref = setSimdRealFrom3R(1.0 / std::sqrt(c1), 0.0, 1.0 / std::sqrt(c2)); GMX_EXPECT_SIMD_REAL_NEAR(ref, maskzInvsqrt(x, m)); } /*! \brief Function wrapper to return first result when testing \ref invsqrtPair */ -SimdReal gmx_simdcall -tstInvsqrtPair0(SimdReal x) +SimdReal gmx_simdcall tstInvsqrtPair0(SimdReal x) { SimdReal r0, r1; invsqrtPair(x, x, &r0, &r1); @@ -518,8 +513,7 @@ tstInvsqrtPair0(SimdReal x) } /*! \brief Function wrapper to return second result when testing \ref invsqrtPair */ -SimdReal gmx_simdcall -tstInvsqrtPair1(SimdReal x) +SimdReal gmx_simdcall tstInvsqrtPair1(SimdReal x) { SimdReal r0, r1; invsqrtPair(x, x, &r0, &r1); @@ -533,17 +527,14 @@ TEST_F(SimdMathTest, invsqrtPair) // Accuracy conversions lose a bit of accuracy compared to all-double, // so increase the tolerance to 4*ulpTol_ - CompareSettings settings { - Range(low, high), 4*ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), 4 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, tstInvsqrtPair0, settings); GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, tstInvsqrtPair1, settings); } /*! \brief Function wrapper to evaluate reference sqrt(x) */ -real -refSqrt(real x) +real refSqrt(real x) { return std::sqrt(x); } @@ -555,17 +546,18 @@ TEST_F(SimdMathTest, sqrt) // compiled in double precision. const real minFloat = std::numeric_limits::min(); - const real minSafeFloat = minFloat*10; - const real maxSafeFloat = std::numeric_limits::max()*0.1; + const real minSafeFloat = minFloat * 10; + const real maxSafeFloat = std::numeric_limits::max() * 0.1; CompareSettings settings; // The accuracy conversions lose a bit of extra accuracy compared to // doing the iterations in all-double. - setUlpTol(4*ulpTol_); + setUlpTol(4 * ulpTol_); // First test that 0.0 and a few other values work - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c1), std::sqrt(c2)), sqrt(setSimdRealFrom3R(0, c1, c2))); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c1), std::sqrt(c2)), + sqrt(setSimdRealFrom3R(0, c1, c2))); -#if GMX_DOUBLE +# if GMX_DOUBLE // As mentioned above, we cannot guarantee that very small double precision // input values (below std::numeric_limits::min()) are handled correctly, // so our implementation will clamp it to zero. In this range we allow either @@ -576,7 +568,7 @@ TEST_F(SimdMathTest, sqrt) // they end up being flushed to zero, and the loop would never end. settings = { Range(0.0, minFloat), ulpTol_, absTol_, MatchRule::ReferenceOrZero }; GMX_EXPECT_SIMD_FUNC_NEAR(refSqrt, sqrt, settings); -#endif +# endif // Next range: Just about minFloat the lookup should always work, but the results // might be a bit fragile due to issues with the N-R iterations being flushed to zero @@ -592,23 +584,21 @@ TEST_F(SimdMathTest, sqrt) TEST_F(SimdMathTest, sqrtUnsafe) { - const real minSafeFloat = std::numeric_limits::min()*10; - const real maxSafeFloat = std::numeric_limits::max()*0.1; + const real minSafeFloat = std::numeric_limits::min() * 10; + const real maxSafeFloat = std::numeric_limits::max() * 0.1; // The accuracy conversions lose a bit of extra accuracy compared to // doing the iterations in all-double, so we use 4*ulpTol_ - setUlpTol(4*ulpTol_); + setUlpTol(4 * ulpTol_); - CompareSettings settings { - Range(minSafeFloat, maxSafeFloat), 4*ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(minSafeFloat, maxSafeFloat), 4 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refSqrt, sqrt, settings); } /*! \brief Function wrapper to evaluate reference 1/x */ real refInv(real x) { - return 1.0/x; + return 1.0 / x; } TEST_F(SimdMathTest, inv) @@ -618,10 +608,13 @@ TEST_F(SimdMathTest, inv) // compiled in double precision. // Relevant threshold points - const real minSafeFloat = std::numeric_limits::min()*10; // X value guaranteed not to result in Inf intermediates for 1/x calc. - const real maxSafeFloat = std::numeric_limits::max()*0.1; // X value guaranteed not to result in DTZ intermediates for 1/x calc. + const real minSafeFloat = std::numeric_limits::min() + * 10; // X value guaranteed not to result in Inf intermediates for 1/x calc. + const real maxSafeFloat = std::numeric_limits::max() + * 0.1; // X value guaranteed not to result in DTZ intermediates for 1/x calc. // Scale highest value by 1-eps, since we will do some arithmetics on this value - const real maxFloat = std::numeric_limits::max()*(1.0 - std::numeric_limits::epsilon() ); + const real maxFloat = + std::numeric_limits::max() * (1.0 - std::numeric_limits::epsilon()); CompareSettings settings; // Danger zone where intermediates might be flushed to zero and produce 1/x==0.0 @@ -629,17 +622,17 @@ TEST_F(SimdMathTest, inv) GMX_EXPECT_SIMD_FUNC_NEAR(refInv, inv, settings); // Normal checks for x < 0 - settings = { Range(-maxSafeFloat, -minSafeFloat), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(-maxSafeFloat, -minSafeFloat), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInv, inv, settings); // We do not care about the small range -minSafeFloat < x < +minSafeFloat where the result can be +/- Inf, since we don't require strict IEEE754. // Normal checks for x > 0 - settings = { Range(minSafeFloat, maxSafeFloat), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(minSafeFloat, maxSafeFloat), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInv, inv, settings); // Danger zone where intermediates might be flushed to zero and produce 1/x==0.0 - settings = { Range(maxSafeFloat, maxFloat), ulpTol_, absTol_, MatchRule::ReferenceOrZero }; + settings = { Range(maxSafeFloat, maxFloat), ulpTol_, absTol_, MatchRule::ReferenceOrZero }; GMX_EXPECT_SIMD_FUNC_NEAR(refInv, inv, settings); } @@ -647,36 +640,32 @@ TEST_F(SimdMathTest, maskzInv) { SimdReal x = setSimdRealFrom3R(c1, 0.0, c2); SimdBool m = (setZero() < x); - SimdReal ref = setSimdRealFrom3R(1.0/c1, 0.0, 1.0/c2); + SimdReal ref = setSimdRealFrom3R(1.0 / c1, 0.0, 1.0 / c2); GMX_EXPECT_SIMD_REAL_NEAR(ref, maskzInv(x, m)); } TEST_F(SimdMathTest, cbrt) { - const real low = -std::numeric_limits::max(); - const real high = std::numeric_limits::max(); + const real low = -std::numeric_limits::max(); + const real high = std::numeric_limits::max(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cbrt, cbrt, settings); } /*! \brief Function wrapper to evaluate reference 1/cbrt(x) */ real refInvCbrt(real x) { - return 1.0/std::cbrt(x); + return 1.0 / std::cbrt(x); } TEST_F(SimdMathTest, invcbrt) { // Negative values first - real low = -std::numeric_limits::max(); - real high = -std::numeric_limits::min(); + real low = -std::numeric_limits::max(); + real high = -std::numeric_limits::min(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvCbrt, invcbrt, settings); // Positive values @@ -688,95 +677,110 @@ TEST_F(SimdMathTest, invcbrt) TEST_F(SimdMathTest, log2) { - const real low = std::numeric_limits::min(); - const real high = std::numeric_limits::max(); + const real low = std::numeric_limits::min(); + const real high = std::numeric_limits::max(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::log2, log2, settings); } TEST_F(SimdMathTest, log) { - const real low = std::numeric_limits::min(); - const real high = std::numeric_limits::max(); + const real low = std::numeric_limits::min(); + const real high = std::numeric_limits::max(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::log, log, settings); } TEST_F(SimdMathTest, exp2) { // Relevant threshold points - constexpr real lowestReal = -std::numeric_limits::max(); - constexpr real lowestRealThatProducesNormal = std::numeric_limits::min_exponent - 1; // adding the significant corresponds to one more unit in exponent - constexpr real lowestRealThatProducesDenormal = lowestRealThatProducesNormal - std::numeric_limits::digits; // digits refer to bits in significand, so 24/53 for float/double - constexpr real highestRealThatProducesNormal = std::numeric_limits::max_exponent - 1; // adding the significant corresponds to one more unit in exponent + constexpr real lowestReal = -std::numeric_limits::max(); + constexpr real lowestRealThatProducesNormal = + std::numeric_limits::min_exponent + - 1; // adding the significant corresponds to one more unit in exponent + constexpr real lowestRealThatProducesDenormal = + lowestRealThatProducesNormal + - std::numeric_limits::digits; // digits refer to bits in significand, so 24/53 for float/double + constexpr real highestRealThatProducesNormal = + std::numeric_limits::max_exponent + - 1; // adding the significant corresponds to one more unit in exponent CompareSettings settings; // Below subnormal range all results should be zero (so, match the reference) - settings = { Range(lowestReal, lowestRealThatProducesDenormal), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(lowestReal, lowestRealThatProducesDenormal), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings); // Subnormal range, require matching, but DTZ is fine - settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Dtz }; + settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Dtz }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings); // Normal range, standard result expected - settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings); } TEST_F(SimdMathTest, exp2Unsafe) { // The unsafe version is only defined in the normal range - constexpr real lowestRealThatProducesNormal = std::numeric_limits::min_exponent - 1; // adding the significant corresponds to one more unit in exponent - constexpr real highestRealThatProducesNormal = std::numeric_limits::max_exponent - 1; // adding the significant corresponds to one more unit in exponent - - CompareSettings settings { - Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal - }; + constexpr real lowestRealThatProducesNormal = + std::numeric_limits::min_exponent + - 1; // adding the significant corresponds to one more unit in exponent + constexpr real highestRealThatProducesNormal = + std::numeric_limits::max_exponent + - 1; // adding the significant corresponds to one more unit in exponent + + CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), + ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2, settings); } TEST_F(SimdMathTest, exp) { - // Relevant threshold points. See the exp2 test for more details about the values; these are simply - // scaled by log(2) due to the difference between exp2 and exp. - const real lowestReal = -std::numeric_limits::max(); + // Relevant threshold points. See the exp2 test for more details about the values; these are + // simply scaled by log(2) due to the difference between exp2 and exp. + const real lowestReal = -std::numeric_limits::max(); // In theory the smallest value should be (min_exponent-1)*log(2), but rounding after the multiplication will cause this // value to be a single ulp too low. This might cause failed tests on CPUs that use different DTZ modes for SIMD vs. // non-SIMD arithmetics (ARM v7), so multiply by (1.0-eps) to increase it by a single ulp. - const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1)*std::log(2.0)*(1-std::numeric_limits::epsilon()); - const real lowestRealThatProducesDenormal = lowestRealThatProducesNormal - std::numeric_limits::digits*std::log(2.0); - const real highestRealThatProducesNormal = (std::numeric_limits::max_exponent - 1)*std::log(2.0); + const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1) + * std::log(2.0) + * (1 - std::numeric_limits::epsilon()); + const real lowestRealThatProducesDenormal = + lowestRealThatProducesNormal - std::numeric_limits::digits * std::log(2.0); + const real highestRealThatProducesNormal = + (std::numeric_limits::max_exponent - 1) * std::log(2.0); CompareSettings settings; // Below subnormal range all results should be zero (so, match the reference) - settings = { Range(lowestReal, lowestRealThatProducesDenormal), ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(lowestReal, lowestRealThatProducesDenormal), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings); // Subnormal range, require matching, but DTZ is fine - settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Dtz}; + settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Dtz }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings); // Normal range, standard result expected - settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings); } TEST_F(SimdMathTest, expUnsafe) { // See test of exp() for comments about test ranges - const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1)*std::log(2.0)*(1-std::numeric_limits::epsilon()); - const real highestRealThatProducesNormal = (std::numeric_limits::max_exponent - 1)*std::log(2.0); - - CompareSettings settings { - Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal - }; + const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1) + * std::log(2.0) + * (1 - std::numeric_limits::epsilon()); + const real highestRealThatProducesNormal = + (std::numeric_limits::max_exponent - 1) * std::log(2.0); + + CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), + ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, exp, settings); } @@ -793,7 +797,8 @@ TEST_F(SimdMathTest, pow) pow(rSimd_c0c1c2, rSimd_m3m0m4)); // 0^0 = 1 , 0^c1=0, -c1^0=1 - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(1.0, 0.0, 1.0), pow(setSimdRealFrom3R(0, 0.0, -c1), setSimdRealFrom3R(0.0, c1, 0.0))); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(1.0, 0.0, 1.0), + pow(setSimdRealFrom3R(0, 0.0, -c1), setSimdRealFrom3R(0.0, c1, 0.0))); } TEST_F(SimdMathTest, powUnsafe) @@ -814,17 +819,14 @@ TEST_F(SimdMathTest, powUnsafe) * \note Single-precision erf() in some libraries can be slightly lower precision * than the SIMD flavor, so we use a cast to force double precision for reference. */ -real -refErf(real x) +real refErf(real x) { return std::erf(static_cast(x)); } TEST_F(SimdMathTest, erf) { - CompareSettings settings { - Range(-9, 9), ulpTol_, std::numeric_limits::min(), MatchRule::Normal - }; + CompareSettings settings{ Range(-9, 9), ulpTol_, std::numeric_limits::min(), MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refErf, erf, settings); } @@ -833,8 +835,7 @@ TEST_F(SimdMathTest, erf) * \note Single-precision erfc() in some libraries can be slightly lower precision * than the SIMD flavor, so we use a cast to force double precision for reference. */ -real -refErfc(real x) +real refErfc(real x) { return std::erfc(static_cast(x)); } @@ -842,33 +843,28 @@ refErfc(real x) TEST_F(SimdMathTest, erfc) { // Our erfc algorithm has 4 ulp accuracy, so relax tolerance a bit to 4*ulpTol - CompareSettings settings { - Range(-9, 9), 4*ulpTol_, std::numeric_limits::min(), MatchRule::Normal - }; + CompareSettings settings{ Range(-9, 9), 4 * ulpTol_, std::numeric_limits::min(), + MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refErfc, erfc, settings); } TEST_F(SimdMathTest, sin) { - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::sin, sin, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), 2*ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), 2 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::sin, sin, settings); } TEST_F(SimdMathTest, cos) { - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cos, cos, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), 2*ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), 2 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cos, cos, settings); } @@ -877,54 +873,50 @@ TEST_F(SimdMathTest, tan) // Tan(x) is a little sensitive due to the division in the algorithm. // Rather than using lots of extra FP operations, we accept the algorithm // presently only achieves a ~3 ulp error and use the medium tolerance. - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::tan, tan, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), 2*ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), 2 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::tan, tan, settings); } TEST_F(SimdMathTest, asin) { // Our present asin(x) algorithm achieves 2-3 ulp accuracy - CompareSettings settings { - Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::asin, asin, settings); } TEST_F(SimdMathTest, acos) { // Our present acos(x) algorithm achieves 2-3 ulp accuracy - CompareSettings settings { - Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::acos, acos, settings); } TEST_F(SimdMathTest, atan) { // Our present atan(x) algorithm achieves 1 ulp accuracy - CompareSettings settings { - Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::atan, atan, settings); } TEST_F(SimdMathTest, atan2) { // test each quadrant - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), - atan2(rSimd_c0c1c2, rSimd_c3c4c5)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), - atan2(rSimd_m0m1m2, rSimd_c3c4c5)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), - atan2(rSimd_m0m1m2, rSimd_m3m0m4)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), - atan2(rSimd_c0c1c2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), + atan2(rSimd_c0c1c2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), + atan2(rSimd_m0m1m2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), + atan2(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), + atan2(rSimd_c0c1c2, rSimd_m3m0m4)); // cases important for calculating angles // values on coordinate axes @@ -932,27 +924,28 @@ TEST_F(SimdMathTest, atan2) atan2(setZero(), rSimd_c0c1c2)); GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, 0), std::atan2(c1, 0), std::atan2(c2, 0)), atan2(rSimd_c0c1c2, setZero())); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), - atan2(setZero(), rSimd_m0m1m2)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), - atan2(rSimd_m0m1m2, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), + atan2(setZero(), rSimd_m0m1m2)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), + atan2(rSimd_m0m1m2, setZero())); // degenerate value (origin) should return 0.0. At least IBM xlc 13.1.5 gets the reference // value wrong (-nan) at -O3 optimization, so we compare to the correct value (0.0) instead. GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(0.0), atan2(setSimdRealFrom3R(0.0, 0.0, 0.0), setZero())); } /*! \brief Evaluate reference version of PME force correction. */ -real -refPmeForceCorrection(real x) +real refPmeForceCorrection(real x) { if (x != 0) { real y = std::sqrt(x); - return 2*std::exp(-x)/(std::sqrt(M_PI)*x) - std::erf(static_cast(y))/(x*y); + return 2 * std::exp(-x) / (std::sqrt(M_PI) * x) - std::erf(static_cast(y)) / (x * y); } else { - return -4/(3*std::sqrt(M_PI)); + return -4 / (3 * std::sqrt(M_PI)); } } @@ -960,31 +953,26 @@ refPmeForceCorrection(real x) TEST_F(SimdMathTest, pmeForceCorrection) { // Pme correction relative accuracy only needs to be ~1e-6 accuracy single, 1e-10 double - const std::int64_t ulpTol = (GMX_DOUBLE ? 5e-10 : 5e-6) /GMX_REAL_EPS; + const std::int64_t ulpTol = (GMX_DOUBLE ? 5e-10 : 5e-6) / GMX_REAL_EPS; - CompareSettings settings { - Range(0.15, 4), ulpTol, GMX_REAL_EPS, MatchRule::Normal - }; + CompareSettings settings{ Range(0.15, 4), ulpTol, GMX_REAL_EPS, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refPmeForceCorrection, pmeForceCorrection, settings); } /*! \brief Evaluate reference version of PME potential correction. */ -real -refPmePotentialCorrection(real x) +real refPmePotentialCorrection(real x) { real y = std::sqrt(x); - return std::erf(static_cast(y))/y; + return std::erf(static_cast(y)) / y; } // The PME corrections will be added to ~1/r, so absolute tolerance of EPS is fine. TEST_F(SimdMathTest, pmePotentialCorrection) { // Pme correction relative accuracy only needs to be ~1e-6 accuracy single, 1e-10 double - const std::int64_t ulpTol = (GMX_DOUBLE ? 5e-10 : 5e-6) /GMX_REAL_EPS; + const std::int64_t ulpTol = (GMX_DOUBLE ? 5e-10 : 5e-6) / GMX_REAL_EPS; - CompareSettings settings { - Range(0.15, 4), ulpTol, GMX_REAL_EPS, MatchRule::Normal - }; + CompareSettings settings{ Range(0.15, 4), ulpTol, GMX_REAL_EPS, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refPmePotentialCorrection, pmePotentialCorrection, settings); } @@ -999,15 +987,12 @@ TEST_F(SimdMathTest, invsqrtSingleAccuracy) /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, invsqrtSingleAccuracy, settings); } /*! \brief Function wrapper to return first result when testing \ref invsqrtPairSingleAccuracy */ -SimdReal gmx_simdcall -tst_invsqrt_SingleAccuracy_pair0(SimdReal x) +SimdReal gmx_simdcall tst_invsqrt_SingleAccuracy_pair0(SimdReal x) { SimdReal r0, r1; invsqrtPairSingleAccuracy(x, x, &r0, &r1); @@ -1015,8 +1000,7 @@ tst_invsqrt_SingleAccuracy_pair0(SimdReal x) } /*! \brief Function wrapper to return second result when testing \ref invsqrtPairSingleAccuracy */ -SimdReal gmx_simdcall -tst_invsqrt_SingleAccuracy_pair1(SimdReal x) +SimdReal gmx_simdcall tst_invsqrt_SingleAccuracy_pair1(SimdReal x) { SimdReal r0, r1; invsqrtPairSingleAccuracy(x, x, &r0, &r1); @@ -1031,9 +1015,7 @@ TEST_F(SimdMathTest, invsqrtPairSingleAccuracy) /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, tst_invsqrt_SingleAccuracy_pair0, settings); GMX_EXPECT_SIMD_FUNC_NEAR(refInvsqrt, tst_invsqrt_SingleAccuracy_pair1, settings); } @@ -1045,7 +1027,7 @@ TEST_F(SimdMathTest, sqrtSingleAccuracy) // compiled in double precision - thus we use single precision limits here. // Scale lowest value by 1+eps, since we will do some arithmetics on this value - const real low = std::numeric_limits::min()*(1.0 + std::numeric_limits::epsilon() ); + const real low = std::numeric_limits::min() * (1.0 + std::numeric_limits::epsilon()); const real high = std::numeric_limits::max(); CompareSettings settings; @@ -1053,9 +1035,10 @@ TEST_F(SimdMathTest, sqrtSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // First test that 0.0 and a few other values works - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c0), std::sqrt(c1)), sqrtSingleAccuracy(setSimdRealFrom3R(0, c0, c1))); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c0), std::sqrt(c1)), + sqrtSingleAccuracy(setSimdRealFrom3R(0, c0, c1))); -#if GMX_DOUBLE +# if GMX_DOUBLE // As mentioned above, we cannot guarantee that very small double precision // input values (below std::numeric_limits::min()) are handled correctly, // so our implementation will clamp it to zero. In this range we allow either @@ -1066,7 +1049,7 @@ TEST_F(SimdMathTest, sqrtSingleAccuracy) // they end up being flushed to zero, and the loop would never end. settings = { Range(0.0, low), ulpTol_, absTol_, MatchRule::ReferenceOrZero }; GMX_EXPECT_SIMD_FUNC_NEAR(refSqrt, sqrtSingleAccuracy, settings); -#endif +# endif settings = { Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refSqrt, sqrtSingleAccuracy, settings); @@ -1081,9 +1064,7 @@ TEST_F(SimdMathTest, sqrtSingleAccuracyUnsafe) /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refSqrt, sqrtSingleAccuracy, settings); } @@ -1094,10 +1075,13 @@ TEST_F(SimdMathTest, invSingleAccuracy) // compiled in double precision. // Relevant threshold points - const real minSafeFloat = std::numeric_limits::min()*10; // X value guaranteed not to result in Inf intermediates for 1/x calc. - const real maxSafeFloat = std::numeric_limits::max()*0.1; // X value guaranteed not to result in DTZ intermediates for 1/x calc. + const real minSafeFloat = std::numeric_limits::min() + * 10; // X value guaranteed not to result in Inf intermediates for 1/x calc. + const real maxSafeFloat = std::numeric_limits::max() + * 0.1; // X value guaranteed not to result in DTZ intermediates for 1/x calc. // Scale highest value by 1-eps, since we will do some arithmetics on this value - const real maxFloat = std::numeric_limits::max()*(1.0 - std::numeric_limits::epsilon() ); + const real maxFloat = + std::numeric_limits::max() * (1.0 - std::numeric_limits::epsilon()); CompareSettings settings; // Increase the allowed error by the difference between the actual precision and single @@ -1124,15 +1108,13 @@ TEST_F(SimdMathTest, invSingleAccuracy) TEST_F(SimdMathTest, cbrtSingleAccuracy) { - const real low = -std::numeric_limits::max(); - const real high = std::numeric_limits::max(); + const real low = -std::numeric_limits::max(); + const real high = std::numeric_limits::max(); // Increase the allowed error by the difference between the actual precision and single setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cbrt, cbrtSingleAccuracy, settings); } @@ -1142,12 +1124,10 @@ TEST_F(SimdMathTest, invcbrtSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // Negative values first - real low = -std::numeric_limits::max(); - real high = -std::numeric_limits::min(); + real low = -std::numeric_limits::max(); + real high = -std::numeric_limits::min(); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refInvCbrt, invcbrtSingleAccuracy, settings); // Positive values @@ -1165,9 +1145,7 @@ TEST_F(SimdMathTest, log2SingleAccuracy) // Increase the allowed error by the difference between the actual precision and single setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::log2, log2SingleAccuracy, settings); } @@ -1179,19 +1157,23 @@ TEST_F(SimdMathTest, logSingleAccuracy) // Increase the allowed error by the difference between the actual precision and single setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(low, high), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(low, high), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::log, logSingleAccuracy, settings); } TEST_F(SimdMathTest, exp2SingleAccuracy) { // Relevant threshold points - float limits since we only target single accuracy - constexpr real lowestReal = -std::numeric_limits::max(); - constexpr real lowestRealThatProducesNormal = std::numeric_limits::min_exponent - 1; // adding the significant corresponds to one more unit in exponent - constexpr real lowestRealThatProducesDenormal = lowestRealThatProducesNormal - std::numeric_limits::digits; // digits refer to bits in significand, so 24/53 for float/double - constexpr real highestRealThatProducesNormal = std::numeric_limits::max_exponent - 1; // adding the significant corresponds to one more unit in exponent + constexpr real lowestReal = -std::numeric_limits::max(); + constexpr real lowestRealThatProducesNormal = + std::numeric_limits::min_exponent + - 1; // adding the significant corresponds to one more unit in exponent + constexpr real lowestRealThatProducesDenormal = + lowestRealThatProducesNormal + - std::numeric_limits::digits; // digits refer to bits in significand, so 24/53 for float/double + constexpr real highestRealThatProducesNormal = + std::numeric_limits::max_exponent + - 1; // adding the significant corresponds to one more unit in exponent CompareSettings settings; // Increase the allowed error by the difference between the actual precision and single @@ -1202,39 +1184,48 @@ TEST_F(SimdMathTest, exp2SingleAccuracy) GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings); // Subnormal range, require matching, but DTZ is fine - settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Dtz }; + settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Dtz }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings); // Normal range, standard result expected - settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings); } TEST_F(SimdMathTest, exp2SingleAccuracyUnsafe) { // The unsafe version is only defined in the normal range - constexpr real lowestRealThatProducesNormal = std::numeric_limits::min_exponent - 1; // adding the significant corresponds to one more unit in exponent - constexpr real highestRealThatProducesNormal = std::numeric_limits::max_exponent - 1; // adding the significant corresponds to one more unit in exponent + constexpr real lowestRealThatProducesNormal = + std::numeric_limits::min_exponent + - 1; // adding the significant corresponds to one more unit in exponent + constexpr real highestRealThatProducesNormal = + std::numeric_limits::max_exponent + - 1; // adding the significant corresponds to one more unit in exponent /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), + ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp2, exp2SingleAccuracy, settings); } TEST_F(SimdMathTest, expSingleAccuracy) { // See threshold point comments in normal exp() test - const real lowestReal = -std::numeric_limits::max(); + const real lowestReal = -std::numeric_limits::max(); // In theory the smallest value should be (min_exponent-1)*log(2), but rounding after the multiplication will cause this // value to be a single ulp too low. This might cause failed tests on CPUs that use different DTZ modes for SIMD vs. // non-SIMD arithmetics (ARM v7), so multiply by (1.0-eps) to increase it by a single ulp. - const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1)*std::log(2.0)*(1.0-std::numeric_limits::epsilon()); - const real lowestRealThatProducesDenormal = lowestRealThatProducesNormal - std::numeric_limits::digits*std::log(2.0); - const real highestRealThatProducesNormal = (std::numeric_limits::max_exponent - 1)*std::log(2.0); + const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1) + * std::log(2.0) + * (1.0 - std::numeric_limits::epsilon()); + const real lowestRealThatProducesDenormal = + lowestRealThatProducesNormal - std::numeric_limits::digits * std::log(2.0); + const real highestRealThatProducesNormal = + (std::numeric_limits::max_exponent - 1) * std::log(2.0); CompareSettings settings; // Increase the allowed error by the difference between the actual precision and single @@ -1245,26 +1236,30 @@ TEST_F(SimdMathTest, expSingleAccuracy) GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings); // Subnormal range, require matching, but DTZ is fine - settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Dtz }; + settings = { Range(lowestRealThatProducesDenormal, lowestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Dtz }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings); // Normal range, standard result expected - settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal }; + settings = { Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, + absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings); } TEST_F(SimdMathTest, expSingleAccuracyUnsafe) { // See test of exp() for comments about test ranges - const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1)*std::log(2.0)*(1-std::numeric_limits::epsilon()); - const real highestRealThatProducesNormal = (std::numeric_limits::max_exponent - 1)*std::log(2.0); + const real lowestRealThatProducesNormal = (std::numeric_limits::min_exponent - 1) + * std::log(2.0) + * (1 - std::numeric_limits::epsilon()); + const real highestRealThatProducesNormal = + (std::numeric_limits::max_exponent - 1) * std::log(2.0); // Increase the allowed error by the difference between the actual precision and single setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(lowestRealThatProducesNormal, highestRealThatProducesNormal), + ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::exp, expSingleAccuracy, settings); } @@ -1284,7 +1279,9 @@ TEST_F(SimdMathTest, powSingleAccuracy) powSingleAccuracy(rSimd_c0c1c2, rSimd_m3m0m4)); // 0^0 = 1 , 0^c1=0, -c1^0=1 - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(1.0, 0.0, 1.0), powSingleAccuracy(setSimdRealFrom3R(0, 0.0, -c1), setSimdRealFrom3R(0.0, c1, 0.0))); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(1.0, 0.0, 1.0), + powSingleAccuracy(setSimdRealFrom3R(0, 0.0, -c1), setSimdRealFrom3R(0.0, c1, 0.0))); } TEST_F(SimdMathTest, powSingleAccuracyUnsafe) @@ -1308,9 +1305,7 @@ TEST_F(SimdMathTest, erfSingleAccuracy) // Increase the allowed error by the difference between the actual precision and single setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(-9, 9), ulpTol_, GMX_REAL_MIN, MatchRule::Normal - }; + CompareSettings settings{ Range(-9, 9), ulpTol_, GMX_REAL_MIN, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refErf, erfSingleAccuracy, settings); } @@ -1320,9 +1315,7 @@ TEST_F(SimdMathTest, erfcSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // Our erfc algorithm has 4 ulp accuracy, so relax tolerance a bit - CompareSettings settings { - Range(-9, 9), 4*ulpTol_, GMX_REAL_MIN, MatchRule::Normal - }; + CompareSettings settings{ Range(-9, 9), 4 * ulpTol_, GMX_REAL_MIN, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refErfc, erfcSingleAccuracy, settings); } @@ -1332,13 +1325,11 @@ TEST_F(SimdMathTest, sinSingleAccuracy) /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::sin, sinSingleAccuracy, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), 2*ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), 2 * ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::sin, sinSingleAccuracy, settings); } @@ -1347,13 +1338,11 @@ TEST_F(SimdMathTest, cosSingleAccuracy) /* Increase the allowed error by the difference between the actual precision and single */ setUlpTolSingleAccuracy(ulpTol_); - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cos, cosSingleAccuracy, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::cos, cosSingleAccuracy, settings); } @@ -1365,13 +1354,11 @@ TEST_F(SimdMathTest, tanSingleAccuracy) // Tan(x) is a little sensitive due to the division in the algorithm. // Rather than using lots of extra FP operations, we accept the algorithm // presently only achieves a ~3 ulp error and use the medium tolerance. - CompareSettings settings { - Range(-8*M_PI, 8*M_PI), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-8 * M_PI, 8 * M_PI), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::tan, tanSingleAccuracy, settings); // Range reduction leads to accuracy loss, so we might want higher tolerance here - settings = { Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal}; + settings = { Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::tan, tanSingleAccuracy, settings); } @@ -1381,9 +1368,7 @@ TEST_F(SimdMathTest, asinSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // Our present asin(x) algorithm achieves 2-3 ulp accuracy - CompareSettings settings { - Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::asin, asinSingleAccuracy, settings); } @@ -1393,9 +1378,7 @@ TEST_F(SimdMathTest, acosSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // Our present acos(x) algorithm achieves 2-3 ulp accuracy - CompareSettings settings { - Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-1, 1), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::acos, acosSingleAccuracy, settings); } @@ -1405,9 +1388,7 @@ TEST_F(SimdMathTest, atanSingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // Our present atan(x) algorithm achieves 1 ulp accuracy - CompareSettings settings { - Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal - }; + CompareSettings settings{ Range(-10000, 10000), ulpTol_, absTol_, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(std::atan, atanSingleAccuracy, settings); } @@ -1417,28 +1398,35 @@ TEST_F(SimdMathTest, atan2SingleAccuracy) setUlpTolSingleAccuracy(ulpTol_); // test each quadrant - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), - atan2SingleAccuracy(rSimd_c0c1c2, rSimd_c3c4c5)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), - atan2SingleAccuracy(rSimd_m0m1m2, rSimd_c3c4c5)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), - atan2SingleAccuracy(rSimd_m0m1m2, rSimd_m3m0m4)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), - atan2SingleAccuracy(rSimd_c0c1c2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), + atan2SingleAccuracy(rSimd_c0c1c2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), + atan2SingleAccuracy(rSimd_m0m1m2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), + atan2SingleAccuracy(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), + atan2SingleAccuracy(rSimd_c0c1c2, rSimd_m3m0m4)); // cases important for calculating angles // values on coordinate axes GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, c0), std::atan2(0, c1), std::atan2(0, c2)), atan2SingleAccuracy(setZero(), rSimd_c0c1c2)); GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, 0), std::atan2(c1, 0), std::atan2(c2, 0)), atan2SingleAccuracy(rSimd_c0c1c2, setZero())); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), - atan2SingleAccuracy(setZero(), rSimd_m0m1m2)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), - atan2SingleAccuracy(rSimd_m0m1m2, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), + atan2SingleAccuracy(setZero(), rSimd_m0m1m2)); + GMX_EXPECT_SIMD_REAL_NEAR( + setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), + atan2SingleAccuracy(rSimd_m0m1m2, setZero())); // degenerate value (origin) should return 0.0. At least IBM xlc 13.1.5 gets the reference // value wrong (-nan) at -O3 optimization, so we compare to the correct value (0.0) instead. - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(0.0), atan2SingleAccuracy(setSimdRealFrom3R(0.0, 0.0, 0.0), setZero())); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(0.0), + atan2SingleAccuracy(setSimdRealFrom3R(0.0, 0.0, 0.0), setZero())); } TEST_F(SimdMathTest, pmeForceCorrectionSingleAccuracy) @@ -1446,11 +1434,9 @@ TEST_F(SimdMathTest, pmeForceCorrectionSingleAccuracy) // The PME corrections will be added to ~1/r2, so absolute tolerance of EPS is fine. // Pme correction only needs to be ~1e-6 accuracy single. // Then increase the allowed error by the difference between the actual precision and single. - setUlpTolSingleAccuracy(std::int64_t(5e-6/GMX_FLOAT_EPS)); + setUlpTolSingleAccuracy(std::int64_t(5e-6 / GMX_FLOAT_EPS)); - CompareSettings settings { - Range(0.15, 4), ulpTol_, GMX_FLOAT_EPS, MatchRule::Normal - }; + CompareSettings settings{ Range(0.15, 4), ulpTol_, GMX_FLOAT_EPS, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refPmeForceCorrection, pmeForceCorrectionSingleAccuracy, settings); } @@ -1459,22 +1445,20 @@ TEST_F(SimdMathTest, pmePotentialCorrectionSingleAccuracy) // The PME corrections will be added to ~1/r, so absolute tolerance of EPS is fine. // Pme correction only needs to be ~1e-6 accuracy single. // Then increase the allowed error by the difference between the actual precision and single. - setUlpTolSingleAccuracy(std::int64_t(5e-6/GMX_FLOAT_EPS)); + setUlpTolSingleAccuracy(std::int64_t(5e-6 / GMX_FLOAT_EPS)); - CompareSettings settings { - Range(0.15, 4), ulpTol_, GMX_FLOAT_EPS, MatchRule::Normal - }; + CompareSettings settings{ Range(0.15, 4), ulpTol_, GMX_FLOAT_EPS, MatchRule::Normal }; GMX_EXPECT_SIMD_FUNC_NEAR(refPmePotentialCorrection, pmePotentialCorrectionSingleAccuracy, settings); } -} // namespace +} // namespace -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/tests/simd_memory.cpp b/src/gromacs/simd/tests/simd_memory.cpp index 7e08b2fb25..b9604b49b8 100644 --- a/src/gromacs/simd/tests/simd_memory.cpp +++ b/src/gromacs/simd/tests/simd_memory.cpp @@ -84,164 +84,163 @@ TEST(EmptyArrayRefTest, IsEmpty) EXPECT_TRUE(empty.empty()); } -#ifdef GTEST_HAS_TYPED_TEST +# ifdef GTEST_HAS_TYPED_TEST /*! \brief Permit all the tests to run on all kinds of ArrayRefs * * The main objective is to verify that all the different kinds of * construction lead to the expected result. */ -template +template class ArrayRefTest : public test::SimdTest { - public: - using ArrayRefType = TypeParam; - using PointerType = typename ArrayRefType::pointer; - using ValueType = typename ArrayRefType::value_type; - using ElementType = std::remove_const_t < typename gmx::internal::SimdTraits < ValueType>::type>; - static constexpr int width = gmx::internal::SimdTraits::width; - - /*! \brief Run the same tests all the time - * - * Note that test cases must call this->runTests(), because - * that's how the derived-class templates that implement - * type-parameterized tests actually work. */ - void runReadOnlyTests(PointerType a, - size_t aSize, - ArrayRefType &arrayRef) +public: + using ArrayRefType = TypeParam; + using PointerType = typename ArrayRefType::pointer; + using ValueType = typename ArrayRefType::value_type; + using ElementType = std::remove_const_t::type>; + static constexpr int width = gmx::internal::SimdTraits::width; + + /*! \brief Run the same tests all the time + * + * Note that test cases must call this->runTests(), because + * that's how the derived-class templates that implement + * type-parameterized tests actually work. */ + void runReadOnlyTests(PointerType a, size_t aSize, ArrayRefType& arrayRef) + { + ASSERT_EQ(aSize, arrayRef.size()); + ASSERT_FALSE(arrayRef.empty()); + + GMX_EXPECT_SIMD_EQ(load(a), arrayRef.front()); + GMX_EXPECT_SIMD_EQ(load(a + (aSize - 1) * width), arrayRef.back()); + + auto it = arrayRef.begin(); + for (size_t i = 0; i != aSize; ++i, ++it) { - ASSERT_EQ(aSize, arrayRef.size()); - ASSERT_FALSE(arrayRef.empty()); - - GMX_EXPECT_SIMD_EQ(load(a), arrayRef.front()); - GMX_EXPECT_SIMD_EQ(load(a+(aSize-1)*width), arrayRef.back()); - - auto it = arrayRef.begin(); - for (size_t i = 0; i != aSize; ++i, ++it) - { - GMX_EXPECT_SIMD_EQ(load(a+i*width), arrayRef[i]); - GMX_EXPECT_SIMD_EQ(load(a+i*width), *it); - } - - EXPECT_EQ(aSize, arrayRef.end()-arrayRef.begin()); - EXPECT_EQ(arrayRef.begin()+1, arrayRef.end()-(aSize-1)); - EXPECT_LT(arrayRef.end()-1, arrayRef.end()); - EXPECT_GT(arrayRef.begin()+1, arrayRef.begin()); - EXPECT_LE(arrayRef.end()-1, arrayRef.end()); - EXPECT_GE(arrayRef.begin()+1, arrayRef.begin()); - - it = arrayRef.begin(); - it++; - ASSERT_EQ(arrayRef.begin()+1, it); - it--; - ASSERT_EQ(arrayRef.begin(), it); - it += 1; - ASSERT_EQ(arrayRef.begin()+1, it); - it -= 1; - ASSERT_EQ(arrayRef.begin(), it); - ++it; - ASSERT_EQ(arrayRef.begin()+1, it); - --it; - ASSERT_EQ(arrayRef.begin(), it); + GMX_EXPECT_SIMD_EQ(load(a + i * width), arrayRef[i]); + GMX_EXPECT_SIMD_EQ(load(a + i * width), *it); } + + EXPECT_EQ(aSize, arrayRef.end() - arrayRef.begin()); + EXPECT_EQ(arrayRef.begin() + 1, arrayRef.end() - (aSize - 1)); + EXPECT_LT(arrayRef.end() - 1, arrayRef.end()); + EXPECT_GT(arrayRef.begin() + 1, arrayRef.begin()); + EXPECT_LE(arrayRef.end() - 1, arrayRef.end()); + EXPECT_GE(arrayRef.begin() + 1, arrayRef.begin()); + + it = arrayRef.begin(); + it++; + ASSERT_EQ(arrayRef.begin() + 1, it); + it--; + ASSERT_EQ(arrayRef.begin(), it); + it += 1; + ASSERT_EQ(arrayRef.begin() + 1, it); + it -= 1; + ASSERT_EQ(arrayRef.begin(), it); + ++it; + ASSERT_EQ(arrayRef.begin() + 1, it); + --it; + ASSERT_EQ(arrayRef.begin(), it); + } }; -using ArrayRefTypes = ::testing::Types, ArrayRef, - ArrayRef, ArrayRef >; +using ArrayRefTypes = + ::testing::Types, ArrayRef, ArrayRef, ArrayRef>; TYPED_TEST_CASE(ArrayRefTest, ArrayRefTypes); TYPED_TEST(ArrayRefTest, ConstructFromPointersWorks) { - alignas(TestFixture::width*sizeof(typename TestFixture::ElementType)) - std::array a; + alignas(TestFixture::width * sizeof(typename TestFixture::ElementType)) + std::array + a; std::iota(a.begin(), a.end(), 0); - typename TestFixture::ArrayRefType arrayRef(a.data(), a.data()+a.size()); + typename TestFixture::ArrayRefType arrayRef(a.data(), a.data() + a.size()); this->runReadOnlyTests(a.data(), 3, arrayRef); } TYPED_TEST(ArrayRefTest, ConstructFromArrayRefWorks) { - alignas(TestFixture::width*sizeof(typename TestFixture::ElementType)) - std::array a; + alignas(TestFixture::width * sizeof(typename TestFixture::ElementType)) + std::array + a; std::iota(a.begin(), a.end(), 0); - ArrayRef < std::remove_const_t < typename TestFixture::ValueType>> - ref(a.data(), a.data()+a.size()); - typename TestFixture::ArrayRefType arrayRef(ref); + ArrayRef> ref(a.data(), a.data() + a.size()); + typename TestFixture::ArrayRefType arrayRef(ref); this->runReadOnlyTests(a.data(), 3, arrayRef); } TYPED_TEST(ArrayRefTest, ConstructFromArrayWorks) { - alignas(TestFixture::width*sizeof(typename TestFixture::ElementType)) - std::array a; + alignas(TestFixture::width * sizeof(typename TestFixture::ElementType)) + std::array + a; std::iota(a.begin(), a.end(), 0); typename TestFixture::ArrayRefType arrayRef(a); this->runReadOnlyTests(a.data(), 3, arrayRef); } -template +template using ArrayRefReadWriteTest = ArrayRefTest; -using ArrayRefReadWriteTypes = ::testing::Types< ArrayRef, ArrayRef >; +using ArrayRefReadWriteTypes = ::testing::Types, ArrayRef>; TYPED_TEST_CASE(ArrayRefReadWriteTest, ArrayRefReadWriteTypes); TYPED_TEST(ArrayRefReadWriteTest, Assignment) { constexpr int width = TestFixture::width; - alignas(width*sizeof(typename TestFixture::ElementType)) - std::array a; + alignas(width * sizeof(typename TestFixture::ElementType)) std::array a; - typename TestFixture::ArrayRefType arrayRef(a.data(), a.data()+a.size()); + typename TestFixture::ArrayRefType arrayRef(a.data(), a.data() + a.size()); arrayRef.front() = 1; - EXPECT_EQ(1, a[0*width]); + EXPECT_EQ(1, a[0 * width]); (arrayRef.front() = 1) = 2; - EXPECT_EQ(2, a[0*width]); + EXPECT_EQ(2, a[0 * width]); arrayRef[1] = 2; - EXPECT_EQ(2, a[1*width]); - *(arrayRef.begin()+2) = 3; - EXPECT_EQ(3, a[2*width]); + EXPECT_EQ(2, a[1 * width]); + *(arrayRef.begin() + 2) = 3; + EXPECT_EQ(3, a[2 * width]); arrayRef.back() = 4; - EXPECT_EQ(4, a[3*width]); + EXPECT_EQ(4, a[3 * width]); } -template +template using ArrayRefArithmeticTest = ArrayRefTest; -using ArrayRefArithmeticTypes = ::testing::Types< ArrayRef -#if GMX_SIMD_HAVE_INT32_ARITHMETICS - , ArrayRef -#endif - >; +using ArrayRefArithmeticTypes = ::testing::Types +# if GMX_SIMD_HAVE_INT32_ARITHMETICS + , + ArrayRef +# endif + >; TYPED_TEST_CASE(ArrayRefArithmeticTest, ArrayRefArithmeticTypes); TYPED_TEST(ArrayRefArithmeticTest, Basic) { constexpr int width = TestFixture::width; - alignas(width*sizeof(typename TestFixture::ElementType)) - std::array a; + alignas(width * sizeof(typename TestFixture::ElementType)) std::array a; - typename TestFixture::ArrayRefType arrayRef(a.data(), a.data()+a.size()); + typename TestFixture::ArrayRefType arrayRef(a.data(), a.data() + a.size()); arrayRef.front() = 1; - ASSERT_EQ(1, a[0*width]); + ASSERT_EQ(1, a[0 * width]); arrayRef.front() += 1; - ASSERT_EQ(2, a[0*width]); + ASSERT_EQ(2, a[0 * width]); arrayRef.front() *= 2; - ASSERT_EQ(4, a[0*width]); + ASSERT_EQ(4, a[0 * width]); arrayRef.front() -= 3; - ASSERT_EQ(1, a[0*width]); + ASSERT_EQ(1, a[0 * width]); } -#endif // GTEST_HAS_TYPED_TEST +# endif // GTEST_HAS_TYPED_TEST -} // namespace +} // namespace #endif // GMX_HAVE_SIMD_REAL -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/simd/tests/simd_vector_operations.cpp b/src/gromacs/simd/tests/simd_vector_operations.cpp index 9229e32922..a662f14a84 100644 --- a/src/gromacs/simd/tests/simd_vector_operations.cpp +++ b/src/gromacs/simd/tests/simd_vector_operations.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,7 +55,7 @@ namespace /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD_HAVE_REAL +# if GMX_SIMD_HAVE_REAL /*! \internal \brief Test fixture for vector operations tests (identical to the generic \ref SimdTest) */ typedef SimdTest SimdVectorOperationsTest; @@ -68,9 +68,8 @@ TEST_F(SimdVectorOperationsTest, iprod) SimdReal bX = rSimd_c3c0c4; SimdReal bY = rSimd_c4c6c8; SimdReal bZ = rSimd_c7c2c3; - SimdReal iprodRef = setSimdRealFrom3R(c0*c3 + c3*c4 + c6*c7, - c1*c0 + c4*c6 + c7*c2, - c2*c4 + c5*c8 + c8*c3); + SimdReal iprodRef = setSimdRealFrom3R(c0 * c3 + c3 * c4 + c6 * c7, c1 * c0 + c4 * c6 + c7 * c2, + c2 * c4 + c5 * c8 + c8 * c3); setUlpTol(2); GMX_EXPECT_SIMD_REAL_NEAR(iprodRef, iprod(aX, aY, aZ, bX, bY, bZ)); @@ -81,9 +80,8 @@ TEST_F(SimdVectorOperationsTest, norm2) SimdReal simdX = rSimd_c0c1c2; SimdReal simdY = rSimd_c3c4c5; SimdReal simdZ = rSimd_c6c7c8; - SimdReal norm2Ref = setSimdRealFrom3R(c0*c0 + c3*c3 + c6*c6, - c1*c1 + c4*c4 + c7*c7, - c2*c2 + c5*c5 + c8*c8); + SimdReal norm2Ref = setSimdRealFrom3R(c0 * c0 + c3 * c3 + c6 * c6, c1 * c1 + c4 * c4 + c7 * c7, + c2 * c2 + c5 * c5 + c8 * c8); setUlpTol(2); GMX_EXPECT_SIMD_REAL_NEAR(norm2Ref, norm2(simdX, simdY, simdZ)); @@ -91,27 +89,30 @@ TEST_F(SimdVectorOperationsTest, norm2) TEST_F(SimdVectorOperationsTest, cprod) { - SimdReal aX = rSimd_c0c1c2; - SimdReal aY = rSimd_c3c4c5; - SimdReal aZ = rSimd_c6c7c8; - SimdReal bX = rSimd_c3c0c4; - SimdReal bY = rSimd_c4c6c8; - SimdReal bZ = rSimd_c7c2c3; - //The SIMD version might use FMA. If we don't force FMA for the reference value, the compiler is free to use FMA - //for either product. If the compiler uses FMA for one product and the SIMD version uses FMA for the other, the - //rounding error of each product adds up and the total possible ulp-error is 12. - SimdReal refcX = setSimdRealFrom3R( std::fma(-c6, c4, c3*c7), std::fma(-c7, c6, c4*c2), std::fma(-c8, c8, c5*c3)); - SimdReal refcY = setSimdRealFrom3R( std::fma(-c0, c7, c6*c3), std::fma(-c1, c2, c7*c0), std::fma(-c2, c3, c8*c4)); - SimdReal refcZ = setSimdRealFrom3R( std::fma(-c3, c3, c0*c4), std::fma(-c4, c0, c1*c6), std::fma(-c5, c4, c2*c8)); + SimdReal aX = rSimd_c0c1c2; + SimdReal aY = rSimd_c3c4c5; + SimdReal aZ = rSimd_c6c7c8; + SimdReal bX = rSimd_c3c0c4; + SimdReal bY = rSimd_c4c6c8; + SimdReal bZ = rSimd_c7c2c3; + // The SIMD version might use FMA. If we don't force FMA for the reference value, the compiler is free to use FMA + // for either product. If the compiler uses FMA for one product and the SIMD version uses FMA for the other, the + // rounding error of each product adds up and the total possible ulp-error is 12. + SimdReal refcX = setSimdRealFrom3R(std::fma(-c6, c4, c3 * c7), std::fma(-c7, c6, c4 * c2), + std::fma(-c8, c8, c5 * c3)); + SimdReal refcY = setSimdRealFrom3R(std::fma(-c0, c7, c6 * c3), std::fma(-c1, c2, c7 * c0), + std::fma(-c2, c3, c8 * c4)); + SimdReal refcZ = setSimdRealFrom3R(std::fma(-c3, c3, c0 * c4), std::fma(-c4, c0, c1 * c6), + std::fma(-c5, c4, c2 * c8)); SimdReal cX, cY, cZ; - //The test assumes that cprod uses FMA on architectures which have FMA so that the compiler can't choose which - //product is computed with FMA. + // The test assumes that cprod uses FMA on architectures which have FMA so that the compiler + // can't choose which product is computed with FMA. cprod(aX, aY, aZ, bX, bY, bZ, &cX, &cY, &cZ); - //The test values cannot be computed without FMA for the case that SIMD has no FMA. Even if no explicit FMA were - //used, the compiler could choose to use FMA. This causes up to 6upl error because of the product is up to 6 times - //larger than the final result after the difference. + // The test values cannot be computed without FMA for the case that SIMD has no FMA. Even if no + // explicit FMA were used, the compiler could choose to use FMA. This causes up to 6upl error + // because of the product is up to 6 times larger than the final result after the difference. setUlpTol(GMX_SIMD_HAVE_FMA ? ulpTol_ : 6); GMX_EXPECT_SIMD_REAL_NEAR(refcX, cX); @@ -119,13 +120,13 @@ TEST_F(SimdVectorOperationsTest, cprod) GMX_EXPECT_SIMD_REAL_NEAR(refcZ, cZ); } -#endif // GMX_SIMD_HAVE_REAL +# endif // GMX_SIMD_HAVE_REAL /*! \} */ /*! \endcond */ -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx #endif // GMX_SIMD diff --git a/src/gromacs/simd/vector_operations.h b/src/gromacs/simd/vector_operations.h index 9dca30e03a..b97e21b302 100644 --- a/src/gromacs/simd/vector_operations.h +++ b/src/gromacs/simd/vector_operations.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,9 +64,9 @@ namespace gmx * check-source to know that this file depends on simd.h (though * symbols like GMX_SIMD_HAVE_FLOAT are actually defined in its * implementation headers). */ -#if GMX_SIMD_HAVE_REAL || defined DOXYGEN +# if GMX_SIMD_HAVE_REAL || defined DOXYGEN -#if GMX_SIMD_HAVE_FLOAT || defined DOXYGEN +# if GMX_SIMD_HAVE_FLOAT || defined DOXYGEN /*! \brief SIMD float inner product of multiple float vectors. * * \param ax X components of first vectors @@ -81,8 +81,7 @@ namespace gmx * \note The SIMD part is that we calculate many scalar products in one call. */ static inline SimdFloat gmx_simdcall -iprod(SimdFloat ax, SimdFloat ay, SimdFloat az, - SimdFloat bx, SimdFloat by, SimdFloat bz) + iprod(SimdFloat ax, SimdFloat ay, SimdFloat az, SimdFloat bx, SimdFloat by, SimdFloat bz) { SimdFloat ret; @@ -104,8 +103,7 @@ iprod(SimdFloat ax, SimdFloat ay, SimdFloat az, * \note This corresponds to the scalar product of the vector with itself, but * the compiler might be able to optimize it better with identical vectors. */ -static inline SimdFloat gmx_simdcall -norm2(SimdFloat ax, SimdFloat ay, SimdFloat az) +static inline SimdFloat gmx_simdcall norm2(SimdFloat ax, SimdFloat ay, SimdFloat az) { SimdFloat ret; @@ -134,10 +132,15 @@ norm2(SimdFloat ax, SimdFloat ay, SimdFloat az) * The arguments x/y/z denotes the different components, and each element * corresponds to a separate vector. */ -static inline void gmx_simdcall -cprod(SimdFloat ax, SimdFloat ay, SimdFloat az, - SimdFloat bx, SimdFloat by, SimdFloat bz, - SimdFloat *cx, SimdFloat *cy, SimdFloat *cz) +static inline void gmx_simdcall cprod(SimdFloat ax, + SimdFloat ay, + SimdFloat az, + SimdFloat bx, + SimdFloat by, + SimdFloat bz, + SimdFloat* cx, + SimdFloat* cy, + SimdFloat* cz) { *cx = ay * bz; *cx = fnma(az, by, *cx); @@ -148,9 +151,9 @@ cprod(SimdFloat ax, SimdFloat ay, SimdFloat az, *cz = ax * by; *cz = fnma(ay, bx, *cz); } -#endif // GMX_SIMD_HAVE_FLOAT +# endif // GMX_SIMD_HAVE_FLOAT -#if GMX_SIMD_HAVE_DOUBLE || defined DOXYGEN +# if GMX_SIMD_HAVE_DOUBLE || defined DOXYGEN /*! \brief SIMD double inner product of multiple double vectors. * * \param ax X components of first vectors @@ -165,8 +168,7 @@ cprod(SimdFloat ax, SimdFloat ay, SimdFloat az, * \note The SIMD part is that we calculate many scalar products in one call. */ static inline SimdDouble gmx_simdcall -iprod(SimdDouble ax, SimdDouble ay, SimdDouble az, - SimdDouble bx, SimdDouble by, SimdDouble bz) + iprod(SimdDouble ax, SimdDouble ay, SimdDouble az, SimdDouble bx, SimdDouble by, SimdDouble bz) { SimdDouble ret; @@ -188,8 +190,7 @@ iprod(SimdDouble ax, SimdDouble ay, SimdDouble az, * \note This corresponds to the scalar product of the vector with itself, but * the compiler might be able to optimize it better with identical vectors. */ -static inline SimdDouble gmx_simdcall -norm2(SimdDouble ax, SimdDouble ay, SimdDouble az) +static inline SimdDouble gmx_simdcall norm2(SimdDouble ax, SimdDouble ay, SimdDouble az) { SimdDouble ret; @@ -218,10 +219,15 @@ norm2(SimdDouble ax, SimdDouble ay, SimdDouble az) * The arguments x/y/z denotes the different components, and each element * corresponds to a separate vector. */ -static inline void gmx_simdcall -cprod(SimdDouble ax, SimdDouble ay, SimdDouble az, - SimdDouble bx, SimdDouble by, SimdDouble bz, - SimdDouble *cx, SimdDouble *cy, SimdDouble *cz) +static inline void gmx_simdcall cprod(SimdDouble ax, + SimdDouble ay, + SimdDouble az, + SimdDouble bx, + SimdDouble by, + SimdDouble bz, + SimdDouble* cx, + SimdDouble* cy, + SimdDouble* cz) { *cx = ay * bz; *cx = *cx - az * by; @@ -232,10 +238,10 @@ cprod(SimdDouble ax, SimdDouble ay, SimdDouble az, *cz = ax * by; *cz = *cz - ay * bx; } -#endif // GMX_SIMD_HAVE_DOUBLE +# endif // GMX_SIMD_HAVE_DOUBLE -#if GMX_SIMD4_HAVE_FLOAT || defined DOXYGEN +# if GMX_SIMD4_HAVE_FLOAT || defined DOXYGEN /*! \brief SIMD4 float norm squared of multiple vectors. * * \param ax X components of vectors @@ -247,8 +253,7 @@ cprod(SimdDouble ax, SimdDouble ay, SimdDouble az, * \note This corresponds to the scalar product of the vector with itself, but * the compiler might be able to optimize it better with identical vectors. */ -static inline Simd4Float gmx_simdcall -norm2(Simd4Float ax, Simd4Float ay, Simd4Float az) +static inline Simd4Float gmx_simdcall norm2(Simd4Float ax, Simd4Float ay, Simd4Float az) { Simd4Float ret; @@ -259,9 +264,9 @@ norm2(Simd4Float ax, Simd4Float ay, Simd4Float az) return ret; } -#endif // GMX_SIMD4_HAVE_FLOAT +# endif // GMX_SIMD4_HAVE_FLOAT -#if GMX_SIMD4_HAVE_DOUBLE || defined DOXYGEN +# if GMX_SIMD4_HAVE_DOUBLE || defined DOXYGEN /*! \brief SIMD4 double norm squared of multiple vectors. * * \param ax X components of vectors @@ -273,8 +278,7 @@ norm2(Simd4Float ax, Simd4Float ay, Simd4Float az) * \note This corresponds to the scalar product of the vector with itself, but * the compiler might be able to optimize it better with identical vectors. */ -static inline Simd4Double gmx_simdcall -norm2(Simd4Double ax, Simd4Double ay, Simd4Double az) +static inline Simd4Double gmx_simdcall norm2(Simd4Double ax, Simd4Double ay, Simd4Double az) { Simd4Double ret; @@ -285,15 +289,15 @@ norm2(Simd4Double ax, Simd4Double ay, Simd4Double az) return ret; } -#endif // GMX_SIMD4_HAVE_DOUBLE +# endif // GMX_SIMD4_HAVE_DOUBLE -#endif // GMX_SIMD_HAVE REAL || defined DOXYGEN +# endif // GMX_SIMD_HAVE REAL || defined DOXYGEN /*! \} */ /*! \endcond */ #endif // GMX_SIMD -} // namespace gmx +} // namespace gmx #endif // GMX_SIMD_VECTOR_OPERATIONS_H diff --git a/src/gromacs/statistics/statistics.cpp b/src/gromacs/statistics/statistics.cpp index ee4cecb124..f7d8cf5d37 100644 --- a/src/gromacs/statistics/statistics.cpp +++ b/src/gromacs/statistics/statistics.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,8 @@ static int gmx_dnint(double x) return gmx::roundToInt(x); } -typedef struct gmx_stats { +typedef struct gmx_stats +{ double aa, a, b, sigma_aa, sigma_a, sigma_b, aver, sigma_aver, error; double rmsd, Rdata, Rfit, Rfitaa, chi2, chi2aa; double *x, *y, *dx, *dy; @@ -61,16 +62,16 @@ typedef struct gmx_stats { gmx_stats_t gmx_stats_init() { - gmx_stats *stats; + gmx_stats* stats; snew(stats, 1); return static_cast(stats); } -int gmx_stats_get_npoints(gmx_stats_t gstats, int *N) +int gmx_stats_get_npoints(gmx_stats_t gstats, int* N) { - gmx_stats *stats = static_cast(gstats); + gmx_stats* stats = static_cast(gstats); *N = stats->np; @@ -79,7 +80,7 @@ int gmx_stats_get_npoints(gmx_stats_t gstats, int *N) void gmx_stats_free(gmx_stats_t gstats) { - gmx_stats *stats = static_cast(gstats); + gmx_stats* stats = static_cast(gstats); sfree(stats->x); sfree(stats->y); @@ -88,12 +89,11 @@ void gmx_stats_free(gmx_stats_t gstats) sfree(stats); } -int gmx_stats_add_point(gmx_stats_t gstats, double x, double y, - double dx, double dy) +int gmx_stats_add_point(gmx_stats_t gstats, double x, double y, double dx, double dy) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; - if (stats->np+1 >= stats->nalloc) + if (stats->np + 1 >= stats->nalloc) { if (stats->nalloc == 0) { @@ -125,10 +125,9 @@ int gmx_stats_add_point(gmx_stats_t gstats, double x, double y, return estatsOK; } -int gmx_stats_get_point(gmx_stats_t gstats, real *x, real *y, - real *dx, real *dy, real level) +int gmx_stats_get_point(gmx_stats_t gstats, real* x, real* y, real* dx, real* dy, real level) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok, outlier; real rmsd, r; @@ -140,16 +139,16 @@ int gmx_stats_get_point(gmx_stats_t gstats, real *x, real *y, while ((outlier == 0) && (stats->np_c < stats->np)) { r = std::abs(stats->x[stats->np_c] - stats->y[stats->np_c]); - outlier = static_cast(r > rmsd*level); + outlier = static_cast(r > rmsd * level); if (outlier) { if (nullptr != x) { - *x = stats->x[stats->np_c]; + *x = stats->x[stats->np_c]; } if (nullptr != y) { - *y = stats->y[stats->np_c]; + *y = stats->y[stats->np_c]; } if (nullptr != dx) { @@ -173,15 +172,14 @@ int gmx_stats_get_point(gmx_stats_t gstats, real *x, real *y, return estatsNO_POINTS; } -int gmx_stats_add_points(gmx_stats_t gstats, int n, real *x, real *y, - real *dx, real *dy) +int gmx_stats_add_points(gmx_stats_t gstats, int n, real* x, real* y, real* dx, real* dy) { for (int i = 0; (i < n); i++) { int ok; - if ((ok = gmx_stats_add_point(gstats, x[i], y[i], - (nullptr != dx) ? dx[i] : 0, - (nullptr != dy) ? dy[i] : 0)) != estatsOK) + if ((ok = gmx_stats_add_point(gstats, x[i], y[i], (nullptr != dx) ? dx[i] : 0, + (nullptr != dy) ? dy[i] : 0)) + != estatsOK) { return ok; } @@ -189,13 +187,13 @@ int gmx_stats_add_points(gmx_stats_t gstats, int n, real *x, real *y, return estatsOK; } -static int gmx_stats_compute(gmx_stats *stats, int weight) +static int gmx_stats_compute(gmx_stats* stats, int weight) { double yy, yx, xx, sx, sy, dy, chi2, chi2aa, d2; double ssxx, ssyy, ssxy; double w, wtot, yx_nw, sy_nw, sx_nw, yy_nw, xx_nw, dx2, dy2; - int N = stats->np; + int N = stats->np; if (stats->computed == 0) { @@ -204,73 +202,73 @@ static int gmx_stats_compute(gmx_stats *stats, int weight) return estatsNO_POINTS; } - xx = xx_nw = 0; - yy = yy_nw = 0; - yx = yx_nw = 0; - sx = sx_nw = 0; - sy = sy_nw = 0; - wtot = 0; - d2 = 0; + xx = xx_nw = 0; + yy = yy_nw = 0; + yx = yx_nw = 0; + sx = sx_nw = 0; + sy = sy_nw = 0; + wtot = 0; + d2 = 0; for (int i = 0; (i < N); i++) { - d2 += gmx::square(stats->x[i]-stats->y[i]); + d2 += gmx::square(stats->x[i] - stats->y[i]); if (((stats->dy[i]) != 0.0) && (weight == elsqWEIGHT_Y)) { - w = 1/gmx::square(stats->dy[i]); + w = 1 / gmx::square(stats->dy[i]); } else { w = 1; } - wtot += w; + wtot += w; - xx += w*gmx::square(stats->x[i]); + xx += w * gmx::square(stats->x[i]); xx_nw += gmx::square(stats->x[i]); - yy += w*gmx::square(stats->y[i]); + yy += w * gmx::square(stats->y[i]); yy_nw += gmx::square(stats->y[i]); - yx += w*stats->y[i]*stats->x[i]; - yx_nw += stats->y[i]*stats->x[i]; + yx += w * stats->y[i] * stats->x[i]; + yx_nw += stats->y[i] * stats->x[i]; - sx += w*stats->x[i]; + sx += w * stats->x[i]; sx_nw += stats->x[i]; - sy += w*stats->y[i]; + sy += w * stats->y[i]; sy_nw += stats->y[i]; } /* Compute average, sigma and error */ - stats->aver = sy_nw/N; - stats->sigma_aver = std::sqrt(yy_nw/N - gmx::square(sy_nw/N)); - stats->error = stats->sigma_aver/std::sqrt(static_cast(N)); + stats->aver = sy_nw / N; + stats->sigma_aver = std::sqrt(yy_nw / N - gmx::square(sy_nw / N)); + stats->error = stats->sigma_aver / std::sqrt(static_cast(N)); /* Compute RMSD between x and y */ - stats->rmsd = std::sqrt(d2/N); + stats->rmsd = std::sqrt(d2 / N); /* Correlation coefficient for data */ - yx_nw /= N; - xx_nw /= N; - yy_nw /= N; - sx_nw /= N; - sy_nw /= N; - ssxx = N*(xx_nw - gmx::square(sx_nw)); - ssyy = N*(yy_nw - gmx::square(sy_nw)); - ssxy = N*(yx_nw - (sx_nw*sy_nw)); - stats->Rdata = std::sqrt(gmx::square(ssxy)/(ssxx*ssyy)); + yx_nw /= N; + xx_nw /= N; + yy_nw /= N; + sx_nw /= N; + sy_nw /= N; + ssxx = N * (xx_nw - gmx::square(sx_nw)); + ssyy = N * (yy_nw - gmx::square(sy_nw)); + ssxy = N * (yx_nw - (sx_nw * sy_nw)); + stats->Rdata = std::sqrt(gmx::square(ssxy) / (ssxx * ssyy)); /* Compute straight line through datapoints, either with intercept zero (result in aa) or with intercept variable (results in a and b) */ - yx = yx/wtot; - xx = xx/wtot; - sx = sx/wtot; - sy = sy/wtot; + yx = yx / wtot; + xx = xx / wtot; + sx = sx / wtot; + sy = sy / wtot; - stats->aa = (yx/xx); - stats->a = (yx-sx*sy)/(xx-sx*sx); - stats->b = (sy)-(stats->a)*(sx); + stats->aa = (yx / xx); + stats->a = (yx - sx * sy) / (xx - sx * sx); + stats->b = (sy) - (stats->a) * (sx); /* Compute chi2, deviation from a line y = ax+b. Also compute chi2aa which returns the deviation from a line y = ax. */ @@ -286,21 +284,21 @@ static int gmx_stats_compute(gmx_stats *stats, int weight) { dy = 1; } - chi2aa += gmx::square((stats->y[i]-(stats->aa*stats->x[i]))/dy); - chi2 += gmx::square((stats->y[i]-(stats->a*stats->x[i]+stats->b))/dy); + chi2aa += gmx::square((stats->y[i] - (stats->aa * stats->x[i])) / dy); + chi2 += gmx::square((stats->y[i] - (stats->a * stats->x[i] + stats->b)) / dy); } if (N > 2) { - stats->chi2 = std::sqrt(chi2/(N-2)); - stats->chi2aa = std::sqrt(chi2aa/(N-2)); + stats->chi2 = std::sqrt(chi2 / (N - 2)); + stats->chi2aa = std::sqrt(chi2aa / (N - 2)); /* Look up equations! */ - dx2 = (xx-sx*sx); - dy2 = (yy-sy*sy); - stats->sigma_a = std::sqrt(stats->chi2/((N-2)*dx2)); - stats->sigma_b = stats->sigma_a*std::sqrt(xx); - stats->Rfit = std::abs(ssxy)/std::sqrt(ssxx*ssyy); - stats->Rfitaa = stats->aa*std::sqrt(dx2/dy2); + dx2 = (xx - sx * sx); + dy2 = (yy - sy * sy); + stats->sigma_a = std::sqrt(stats->chi2 / ((N - 2) * dx2)); + stats->sigma_b = stats->sigma_a * std::sqrt(xx); + stats->Rfit = std::abs(ssxy) / std::sqrt(ssxx * ssyy); + stats->Rfitaa = stats->aa * std::sqrt(dx2 / dy2); } else { @@ -318,11 +316,9 @@ static int gmx_stats_compute(gmx_stats *stats, int weight) return estatsOK; } -int gmx_stats_get_ab(gmx_stats_t gstats, int weight, - real *a, real *b, real *da, real *db, - real *chi2, real *Rfit) +int gmx_stats_get_ab(gmx_stats_t gstats, int weight, real* a, real* b, real* da, real* db, real* chi2, real* Rfit) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, weight)) != estatsOK) @@ -331,19 +327,19 @@ int gmx_stats_get_ab(gmx_stats_t gstats, int weight, } if (nullptr != a) { - *a = stats->a; + *a = stats->a; } if (nullptr != b) { - *b = stats->b; + *b = stats->b; } if (nullptr != da) { - *da = stats->sigma_a; + *da = stats->sigma_a; } if (nullptr != db) { - *db = stats->sigma_b; + *db = stats->sigma_b; } if (nullptr != chi2) { @@ -357,10 +353,9 @@ int gmx_stats_get_ab(gmx_stats_t gstats, int weight, return estatsOK; } -int gmx_stats_get_a(gmx_stats_t gstats, int weight, real *a, real *da, - real *chi2, real *Rfit) +int gmx_stats_get_a(gmx_stats_t gstats, int weight, real* a, real* da, real* chi2, real* Rfit) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, weight)) != estatsOK) @@ -369,11 +364,11 @@ int gmx_stats_get_a(gmx_stats_t gstats, int weight, real *a, real *da, } if (nullptr != a) { - *a = stats->aa; + *a = stats->aa; } if (nullptr != da) { - *da = stats->sigma_aa; + *da = stats->sigma_aa; } if (nullptr != chi2) { @@ -387,9 +382,9 @@ int gmx_stats_get_a(gmx_stats_t gstats, int weight, real *a, real *da, return estatsOK; } -int gmx_stats_get_average(gmx_stats_t gstats, real *aver) +int gmx_stats_get_average(gmx_stats_t gstats, real* aver) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -402,9 +397,9 @@ int gmx_stats_get_average(gmx_stats_t gstats, real *aver) return estatsOK; } -int gmx_stats_get_ase(gmx_stats_t gstats, real *aver, real *sigma, real *error) +int gmx_stats_get_ase(gmx_stats_t gstats, real* aver, real* sigma, real* error) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -414,7 +409,7 @@ int gmx_stats_get_ase(gmx_stats_t gstats, real *aver, real *sigma, real *error) if (nullptr != aver) { - *aver = stats->aver; + *aver = stats->aver; } if (nullptr != sigma) { @@ -428,9 +423,9 @@ int gmx_stats_get_ase(gmx_stats_t gstats, real *aver, real *sigma, real *error) return estatsOK; } -int gmx_stats_get_sigma(gmx_stats_t gstats, real *sigma) +int gmx_stats_get_sigma(gmx_stats_t gstats, real* sigma) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -443,9 +438,9 @@ int gmx_stats_get_sigma(gmx_stats_t gstats, real *sigma) return estatsOK; } -int gmx_stats_get_error(gmx_stats_t gstats, real *error) +int gmx_stats_get_error(gmx_stats_t gstats, real* error) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -458,9 +453,9 @@ int gmx_stats_get_error(gmx_stats_t gstats, real *error) return estatsOK; } -int gmx_stats_get_corr_coeff(gmx_stats_t gstats, real *R) +int gmx_stats_get_corr_coeff(gmx_stats_t gstats, real* R) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -473,9 +468,9 @@ int gmx_stats_get_corr_coeff(gmx_stats_t gstats, real *R) return estatsOK; } -int gmx_stats_get_rmsd(gmx_stats_t gstats, real *rmsd) +int gmx_stats_get_rmsd(gmx_stats_t gstats, real* rmsd) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int ok; if ((ok = gmx_stats_compute(stats, elsqWEIGHT_NONE)) != estatsOK) @@ -488,14 +483,13 @@ int gmx_stats_get_rmsd(gmx_stats_t gstats, real *rmsd) return estatsOK; } -int gmx_stats_dump_xy(gmx_stats_t gstats, FILE *fp) +int gmx_stats_dump_xy(gmx_stats_t gstats, FILE* fp) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; for (int i = 0; (i < stats->np); i++) { - fprintf(fp, "%12g %12g %12g %12g\n", stats->x[i], stats->y[i], - stats->dx[i], stats->dy[i]); + fprintf(fp, "%12g %12g %12g %12g\n", stats->x[i], stats->y[i], stats->dx[i], stats->dy[i]); } return estatsOK; @@ -503,8 +497,8 @@ int gmx_stats_dump_xy(gmx_stats_t gstats, FILE *fp) int gmx_stats_remove_outliers(gmx_stats_t gstats, double level) { - gmx_stats *stats = gstats; - int iter = 1, done = 0, ok; + gmx_stats* stats = gstats; + int iter = 1, done = 0, ok; real rmsd, r; while ((stats->np >= 10) && !done) @@ -514,19 +508,19 @@ int gmx_stats_remove_outliers(gmx_stats_t gstats, double level) return ok; } done = 1; - for (int i = 0; (i < stats->np); ) + for (int i = 0; (i < stats->np);) { - r = std::abs(stats->x[i]-stats->y[i]); - if (r > level*rmsd) + r = std::abs(stats->x[i] - stats->y[i]); + if (r > level * rmsd) { - fprintf(stderr, "Removing outlier, iter = %d, rmsd = %g, x = %g, y = %g\n", - iter, rmsd, stats->x[i], stats->y[i]); - if (i < stats->np-1) + fprintf(stderr, "Removing outlier, iter = %d, rmsd = %g, x = %g, y = %g\n", iter, + rmsd, stats->x[i], stats->y[i]); + if (i < stats->np - 1) { - stats->x[i] = stats->x[stats->np-1]; - stats->y[i] = stats->y[stats->np-1]; - stats->dx[i] = stats->dx[stats->np-1]; - stats->dy[i] = stats->dy[stats->np-1]; + stats->x[i] = stats->x[stats->np - 1]; + stats->y[i] = stats->y[stats->np - 1]; + stats->dx[i] = stats->dx[stats->np - 1]; + stats->dy[i] = stats->dy[stats->np - 1]; } stats->np--; done = 0; @@ -542,15 +536,13 @@ int gmx_stats_remove_outliers(gmx_stats_t gstats, double level) return estatsOK; } -int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, - int ehisto, int normalized, real **x, real **y) +int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int* nb, int ehisto, int normalized, real** x, real** y) { - gmx_stats *stats = gstats; + gmx_stats* stats = gstats; int index = 0, nbins = *nb, *nindex; double minx, maxx, maxy, miny, delta, dd, minh; - if (((binwidth <= 0) && (nbins <= 0)) || - ((binwidth > 0) && (nbins > 0))) + if (((binwidth <= 0) && (nbins <= 0)) || ((binwidth > 0) && (nbins > 0))) { return estatsINVALID_INPUT; } @@ -569,12 +561,12 @@ int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, } if (ehisto == ehistoX) { - delta = maxx-minx; + delta = maxx - minx; minh = minx; } else if (ehisto == ehistoY) { - delta = maxy-miny; + delta = maxy - miny; minh = miny; } else @@ -584,17 +576,17 @@ int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, if (binwidth == 0) { - binwidth = (delta)/nbins; + binwidth = (delta) / nbins; } else { - nbins = gmx_dnint((delta)/binwidth + 0.5); + nbins = gmx_dnint((delta) / binwidth + 0.5); } snew(*x, nbins); snew(nindex, nbins); for (int i = 0; (i < nbins); i++) { - (*x)[i] = minh + binwidth*(i+0.5); + (*x)[i] = minh + binwidth * (i + 0.5); } if (normalized == 0) { @@ -602,7 +594,7 @@ int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, } else { - dd = 1.0/(binwidth*stats->np); + dd = 1.0 / (binwidth * stats->np); } snew(*y, nbins); @@ -610,19 +602,19 @@ int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, { if (ehisto == ehistoY) { - index = static_cast((stats->y[i]-miny)/binwidth); + index = static_cast((stats->y[i] - miny) / binwidth); } else if (ehisto == ehistoX) { - index = static_cast((stats->x[i]-minx)/binwidth); + index = static_cast((stats->x[i] - minx) / binwidth); } if (index < 0) { index = 0; } - if (index > nbins-1) + if (index > nbins - 1) { - index = nbins-1; + index = nbins - 1; } (*y)[index] += dd; nindex[index]++; @@ -644,17 +636,11 @@ int gmx_stats_make_histogram(gmx_stats_t gstats, real binwidth, int *nb, return estatsOK; } -static const char *stats_error[estatsNR] = -{ - "All well in STATS land", - "No points", - "Not enough memory", - "Invalid histogram input", - "Unknown error", - "Not implemented yet" -}; - -const char *gmx_stats_message(int estats) +static const char* stats_error[estatsNR] = { "All well in STATS land", "No points", + "Not enough memory", "Invalid histogram input", + "Unknown error", "Not implemented yet" }; + +const char* gmx_stats_message(int estats) { if ((estats >= 0) && (estats < estatsNR)) { @@ -668,7 +654,7 @@ const char *gmx_stats_message(int estats) /* Old convenience functions, should be merged with the core statistics above. */ -int lsq_y_ax(int n, real x[], real y[], real *a) +int lsq_y_ax(int n, real x[], real y[], real* a) { gmx_stats_t lsq = gmx_stats_init(); int ok; @@ -681,8 +667,7 @@ int lsq_y_ax(int n, real x[], real y[], real *a) return ok; } -static int low_lsq_y_ax_b(int n, const real *xr, const double *xd, real yr[], - real *a, real *b, real *r, real *chi2) +static int low_lsq_y_ax_b(int n, const real* xr, const double* xd, real yr[], real* a, real* b, real* r, real* chi2) { gmx_stats_t lsq = gmx_stats_init(); int ok; @@ -716,20 +701,17 @@ static int low_lsq_y_ax_b(int n, const real *xr, const double *xd, real yr[], return ok; } -int lsq_y_ax_b(int n, real x[], real y[], real *a, real *b, real *r, real *chi2) +int lsq_y_ax_b(int n, real x[], real y[], real* a, real* b, real* r, real* chi2) { return low_lsq_y_ax_b(n, x, nullptr, y, a, b, r, chi2); } -int lsq_y_ax_b_xdouble(int n, double x[], real y[], real *a, real *b, - real *r, real *chi2) +int lsq_y_ax_b_xdouble(int n, double x[], real y[], real* a, real* b, real* r, real* chi2) { return low_lsq_y_ax_b(n, nullptr, x, y, a, b, r, chi2); } -int lsq_y_ax_b_error(int n, real x[], real y[], real dy[], - real *a, real *b, real *da, real *db, - real *r, real *chi2) +int lsq_y_ax_b_error(int n, real x[], real y[], real dy[], real* a, real* b, real* da, real* db, real* r, real* chi2) { gmx_stats_t lsq = gmx_stats_init(); int ok; diff --git a/src/gromacs/statistics/statistics.h b/src/gromacs/statistics/statistics.h index d50bdf14e8..818bdf317a 100644 --- a/src/gromacs/statistics/statistics.h +++ b/src/gromacs/statistics/statistics.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,23 +49,36 @@ #include "gromacs/utility/real.h" //! Abstract container type -typedef struct gmx_stats *gmx_stats_t; +typedef struct gmx_stats* gmx_stats_t; //! Error codes returned by the routines -enum { - estatsOK, estatsNO_POINTS, estatsNO_MEMORY, estatsERROR, - estatsINVALID_INPUT, estatsNOT_IMPLEMENTED, estatsNR +enum +{ + estatsOK, + estatsNO_POINTS, + estatsNO_MEMORY, + estatsERROR, + estatsINVALID_INPUT, + estatsNOT_IMPLEMENTED, + estatsNR }; //! Enum for statistical weights -enum { - elsqWEIGHT_NONE, elsqWEIGHT_X, elsqWEIGHT_Y, - elsqWEIGHT_XY, elsqWEIGHT_NR +enum +{ + elsqWEIGHT_NONE, + elsqWEIGHT_X, + elsqWEIGHT_Y, + elsqWEIGHT_XY, + elsqWEIGHT_NR }; //! Enum determining which coordinate to histogram -enum { - ehistoX, ehistoY, ehistoNR +enum +{ + ehistoX, + ehistoY, + ehistoNR }; /*! \brief @@ -98,8 +111,7 @@ int gmx_stats_remove_outliers(gmx_stats_t stats, double level); * \param[in] dy The error in the y value * \return error code */ -int gmx_stats_add_point(gmx_stats_t stats, double x, double y, - double dx, double dy); +int gmx_stats_add_point(gmx_stats_t stats, double x, double y, double dx, double dy); /*! \brief * Add a series of datapoints at once. The arrays dx and dy may @@ -113,8 +125,7 @@ int gmx_stats_add_point(gmx_stats_t stats, double x, double y, * \param[in] dy The error in the y value * \return error code */ -int gmx_stats_add_points(gmx_stats_t stats, int n, real *x, real *y, - real *dx, real *dy); +int gmx_stats_add_points(gmx_stats_t stats, int n, real* x, real* y, real* dx, real* dy); /*! \brief * Delivers data points from the statistics. @@ -135,8 +146,7 @@ int gmx_stats_add_points(gmx_stats_t stats, int n, real *x, real *y, * \param[in] level sigma level (see above) * \return error code */ -int gmx_stats_get_point(gmx_stats_t stats, real *x, real *y, - real *dx, real *dy, real level); +int gmx_stats_get_point(gmx_stats_t stats, real* x, real* y, real* dx, real* dy, real level); /*! \brief * Fit the data to y = ax + b, possibly weighted, if uncertainties @@ -151,9 +161,7 @@ int gmx_stats_get_point(gmx_stats_t stats, real *x, real *y, * \param[out] Rfit correlation coefficient * \return error code */ -int gmx_stats_get_ab(gmx_stats_t stats, int weight, - real *a, real *b, - real *da, real *db, real *chi2, real *Rfit); +int gmx_stats_get_ab(gmx_stats_t stats, int weight, real* a, real* b, real* da, real* db, real* chi2, real* Rfit); /*! \brief * Fit the data to y = ax, possibly weighted, if uncertainties have @@ -166,8 +174,7 @@ int gmx_stats_get_ab(gmx_stats_t stats, int weight, * \param[out] Rfit correlation coefficient * \return error code */ -int gmx_stats_get_a(gmx_stats_t stats, int weight, - real *a, real *da, real *chi2, real *Rfit); +int gmx_stats_get_a(gmx_stats_t stats, int weight, real* a, real* da, real* chi2, real* Rfit); /*! \brief * Get the correlation coefficient. @@ -175,7 +182,7 @@ int gmx_stats_get_a(gmx_stats_t stats, int weight, * \param[out] R the correlation coefficient between the data (x and y) as input to the structure. * \return error code */ -int gmx_stats_get_corr_coeff(gmx_stats_t stats, real *R); +int gmx_stats_get_corr_coeff(gmx_stats_t stats, real* R); /*! \brief * Get the root mean square deviation. @@ -183,7 +190,7 @@ int gmx_stats_get_corr_coeff(gmx_stats_t stats, real *R); * \param[out] rmsd the root mean square deviation between x and y values. * \return error code */ -int gmx_stats_get_rmsd(gmx_stats_t stats, real *rmsd); +int gmx_stats_get_rmsd(gmx_stats_t stats, real* rmsd); /*! \brief * Get the number of points. @@ -191,7 +198,7 @@ int gmx_stats_get_rmsd(gmx_stats_t stats, real *rmsd); * \param[out] N number of data points * \return error code */ -int gmx_stats_get_npoints(gmx_stats_t stats, int *N); +int gmx_stats_get_npoints(gmx_stats_t stats, int* N); /*! \brief * Computes and returns the average value. @@ -199,7 +206,7 @@ int gmx_stats_get_npoints(gmx_stats_t stats, int *N); * \param[out] aver Average value * \return error code */ -int gmx_stats_get_average(gmx_stats_t stats, real *aver); +int gmx_stats_get_average(gmx_stats_t stats, real* aver); /*! \brief * Computes and returns the standard deviation. @@ -207,7 +214,7 @@ int gmx_stats_get_average(gmx_stats_t stats, real *aver); * \param[out] sigma Standard deviation * \return error code */ -int gmx_stats_get_sigma(gmx_stats_t stats, real *sigma); +int gmx_stats_get_sigma(gmx_stats_t stats, real* sigma); /*! \brief * Computes and returns the standard error. @@ -215,7 +222,7 @@ int gmx_stats_get_sigma(gmx_stats_t stats, real *sigma); * \param[out] error Standard error * \return error code */ -int gmx_stats_get_error(gmx_stats_t stats, real *error); +int gmx_stats_get_error(gmx_stats_t stats, real* error); /*! \brief * Pointers may be null, in which case no assignment will be done. @@ -225,7 +232,7 @@ int gmx_stats_get_error(gmx_stats_t stats, real *error); * \param[out] error Standard error * \return error code */ -int gmx_stats_get_ase(gmx_stats_t stats, real *aver, real *sigma, real *error); +int gmx_stats_get_ase(gmx_stats_t stats, real* aver, real* sigma, real* error); /*! \brief * Dump the x, y, dx, dy data to a text file @@ -233,7 +240,7 @@ int gmx_stats_get_ase(gmx_stats_t stats, real *aver, real *sigma, real *error); * \param[in] fp File pointer * \return error code */ -int gmx_stats_dump_xy(gmx_stats_t stats, FILE *fp); +int gmx_stats_dump_xy(gmx_stats_t stats, FILE* fp); /*! \brief * Make a histogram of the data present. @@ -256,15 +263,19 @@ int gmx_stats_dump_xy(gmx_stats_t stats, FILE *fp); * \param[out] y see above * \return error code */ -int gmx_stats_make_histogram(gmx_stats_t stats, real binwidth, int *nbins, - int ehisto, - int normalized, real **x, real **y); +int gmx_stats_make_histogram(gmx_stats_t stats, + real binwidth, + int* nbins, + int ehisto, + int normalized, + real** x, + real** y); /*! \brief * Return message belonging to error code * \param[in] estats error code */ -const char *gmx_stats_message(int estats); +const char* gmx_stats_message(int estats); /**************************************************** * Some statistics utilities for convenience: useful when a complete data @@ -279,7 +290,7 @@ const char *gmx_stats_message(int estats); * \param[out] a slope * \return error code */ -int lsq_y_ax(int n, real x[], real y[], real *a); +int lsq_y_ax(int n, real x[], real y[], real* a); /*! \brief * Fit a straight line y=ax+b thru the n data points x, y. @@ -292,13 +303,11 @@ int lsq_y_ax(int n, real x[], real y[], real *a); * \param[out] chi2 quality of fit * \return error code */ -int lsq_y_ax_b(int n, real x[], real y[], real *a, real *b, real *r, - real *chi2); +int lsq_y_ax_b(int n, real x[], real y[], real* a, real* b, real* r, real* chi2); /*! \copydoc lsq_y_ax_b */ -int lsq_y_ax_b_xdouble(int n, double x[], real y[], - real *a, real *b, real *r, real *chi2); +int lsq_y_ax_b_xdouble(int n, double x[], real y[], real* a, real* b, real* r, real* chi2); /*! \brief * Fit a straight line y=ax+b thru the n data points x, y. @@ -314,8 +323,6 @@ int lsq_y_ax_b_xdouble(int n, double x[], real y[], * \param[out] chi2 quality of fit * \return error code */ -int lsq_y_ax_b_error(int n, real x[], real y[], real dy[], - real *a, real *b, real *da, real *db, - real *r, real *chi2); +int lsq_y_ax_b_error(int n, real x[], real y[], real dy[], real* a, real* b, real* da, real* db, real* r, real* chi2); #endif diff --git a/src/gromacs/swap/swapcoords.cpp b/src/gromacs/swap/swapcoords.cpp index edc034cd78..0a05fe62ec 100644 --- a/src/gromacs/swap/swapcoords.cpp +++ b/src/gromacs/swap/swapcoords.cpp @@ -79,27 +79,37 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/snprintf.h" -static const char *SwS = {"SWAP:"}; /**< For output that comes from the swap module */ -static const char *SwSEmpty = {" "}; /**< Placeholder for multi-line output */ -static const char* CompStr[eCompNR] = {"A", "B" }; /**< Compartment name */ -static const char *SwapStr[eSwapTypesNR+1] = { "", "X-", "Y-", "Z-", nullptr}; /**< Name for the swap types. */ -static const char *DimStr[DIM+1] = { "X", "Y", "Z", nullptr}; /**< Name for the swap dimension. */ +static const char* SwS = { "SWAP:" }; /**< For output that comes from the swap module */ +static const char* SwSEmpty = { " " }; /**< Placeholder for multi-line output */ +static const char* CompStr[eCompNR] = { "A", "B" }; /**< Compartment name */ +static const char* SwapStr[eSwapTypesNR + 1] = { "", "X-", "Y-", "Z-", + nullptr }; /**< Name for the swap types. */ +static const char* DimStr[DIM + 1] = { "X", "Y", "Z", nullptr }; /**< Name for the swap dimension. */ /** Keep track of through which channel the ions have passed */ -enum eChannelHistory { - eChHistPassedNone, eChHistPassedCh0, eChHistPassedCh1, eChHistNr +enum eChannelHistory +{ + eChHistPassedNone, + eChHistPassedCh0, + eChHistPassedCh1, + eChHistNr }; -static const char* ChannelString[eChHistNr] = { "none", "channel0", "channel1" }; /**< Name for the channels */ +static const char* ChannelString[eChHistNr] = { "none", "channel0", "channel1" }; /**< Name for the channels */ /*! \brief Domain identifier. * * Keeps track of from which compartment the ions came before passing the * channel. */ -enum eDomain { - eDomainNotset, eDomainA, eDomainB, eDomainNr +enum eDomain +{ + eDomainNotset, + eDomainA, + eDomainB, + eDomainNr }; -static const char* DomainString[eDomainNr] = { "not_assigned", "Domain_A", "Domain_B" }; /**< Name for the domains */ +static const char* DomainString[eDomainNr] = { "not_assigned", "Domain_A", + "Domain_B" }; /**< Name for the domains */ namespace gmx { @@ -112,9 +122,9 @@ extern template LocalAtomSet LocalAtomSetManager::add(ArrayRef createSwapCoordinatesModule() @@ -130,18 +140,18 @@ std::unique_ptr createSwapCoordinatesModule() */ typedef struct swap_compartment { - int nMol; /**< Number of ion or water molecules detected - in this compartment. */ - int nMolBefore; /**< Number of molecules before swapping. */ - int nMolReq; /**< Requested number of molecules in compartment. */ - real nMolAv; /**< Time-averaged number of molecules matching - the compartment conditions. */ - int *nMolPast; /**< Past molecule counts for time-averaging. */ - int *ind; /**< Indices to collective array of atoms. */ - real *dist; /**< Distance of atom to bulk layer, which is - normally the center layer of the compartment */ - int nalloc; /**< Allocation size for ind array. */ - int inflow_net; /**< Net inflow of ions into this compartment. */ + int nMol; /**< Number of ion or water molecules detected + in this compartment. */ + int nMolBefore; /**< Number of molecules before swapping. */ + int nMolReq; /**< Requested number of molecules in compartment. */ + real nMolAv; /**< Time-averaged number of molecules matching + the compartment conditions. */ + int* nMolPast; /**< Past molecule counts for time-averaging. */ + int* ind; /**< Indices to collective array of atoms. */ + real* dist; /**< Distance of atom to bulk layer, which is + normally the center layer of the compartment */ + int nalloc; /**< Allocation size for ind array. */ + int inflow_net; /**< Net inflow of ions into this compartment. */ } t_compartment; @@ -155,41 +165,40 @@ typedef struct swap_group * * \param[in] atomset Managed indices of atoms that are part of the swap group. */ - swap_group(const gmx::LocalAtomSet &atomset); - char *molname = nullptr; /**< Name of the group or ion type */ - int apm = 0; /**< Number of atoms in each molecule */ - gmx::LocalAtomSet atomset; /**< The atom indices in the swap group */ - rvec *xc = nullptr; /**< Collective array of group atom positions (size nat) */ - ivec *xc_shifts = nullptr; /**< Current (collective) shifts (size nat) */ - ivec *xc_eshifts = nullptr; /**< Extra shifts since last DD step (size nat) */ - rvec *xc_old = nullptr; /**< Old (collective) positions (size nat) */ - real q = 0.; /**< Total charge of one molecule of this group */ - real *m = nullptr; /**< Masses (can be omitted, size apm) */ - unsigned char *comp_from = nullptr; /**< (Collective) Stores from which compartment this - molecule has come. This way we keep track of - through which channel an ion permeates - (size nMol = nat/apm) */ - unsigned char *comp_now = nullptr; /**< In which compartment this ion is now (size nMol) */ - unsigned char *channel_label = nullptr; /**< Which channel was passed at last by this ion? - (size nMol) */ - rvec center; /**< Center of the group; COM if masses are used */ - t_compartment comp[eCompNR]; /**< Distribution of particles of this group across - the two compartments */ - real vacancy[eCompNR]; /**< How many molecules need to be swapped in? */ - int fluxfromAtoB[eChanNR]; /**< Net flux of ions per channel */ - int nCyl[eChanNR]; /**< Number of ions residing in a channel */ - int nCylBoth = 0; /**< Ions assigned to cyl0 and cyl1. Not good. */ + swap_group(const gmx::LocalAtomSet& atomset); + char* molname = nullptr; /**< Name of the group or ion type */ + int apm = 0; /**< Number of atoms in each molecule */ + gmx::LocalAtomSet atomset; /**< The atom indices in the swap group */ + rvec* xc = nullptr; /**< Collective array of group atom positions (size nat) */ + ivec* xc_shifts = nullptr; /**< Current (collective) shifts (size nat) */ + ivec* xc_eshifts = nullptr; /**< Extra shifts since last DD step (size nat) */ + rvec* xc_old = nullptr; /**< Old (collective) positions (size nat) */ + real q = 0.; /**< Total charge of one molecule of this group */ + real* m = nullptr; /**< Masses (can be omitted, size apm) */ + unsigned char* comp_from = nullptr; /**< (Collective) Stores from which compartment this + molecule has come. This way we keep track of + through which channel an ion permeates + (size nMol = nat/apm) */ + unsigned char* comp_now = nullptr; /**< In which compartment this ion is now (size nMol) */ + unsigned char* channel_label = nullptr; /**< Which channel was passed at last by this ion? + (size nMol) */ + rvec center; /**< Center of the group; COM if masses are used */ + t_compartment comp[eCompNR]; /**< Distribution of particles of this group across + the two compartments */ + real vacancy[eCompNR]; /**< How many molecules need to be swapped in? */ + int fluxfromAtoB[eChanNR]; /**< Net flux of ions per channel */ + int nCyl[eChanNR]; /**< Number of ions residing in a channel */ + int nCylBoth = 0; /**< Ions assigned to cyl0 and cyl1. Not good. */ } t_swapgrp; -t_swapgrp::swap_group(const gmx::LocalAtomSet& atomset) : atomset { - atomset -} { +t_swapgrp::swap_group(const gmx::LocalAtomSet& atomset) : atomset{ atomset } +{ center[0] = 0; center[1] = 0; center[2] = 0; for (int compartment = eCompA; compartment < eCompNR; ++compartment) { - comp[compartment] = {}; + comp[compartment] = {}; vacancy[compartment] = 0; } for (int channel = eChan0; channel < eChanNR; ++channel) @@ -204,17 +213,16 @@ t_swapgrp::swap_group(const gmx::LocalAtomSet& atomset) : atomset { */ struct t_swap { - int swapdim; /**< One of XX, YY, ZZ */ - t_pbc *pbc; /**< Needed to make molecules whole. */ - FILE *fpout; /**< Output file. */ - int ngrp; /**< Number of t_swapgrp groups */ - std::vector group; /**< Separate groups for channels, solvent, ions */ - int fluxleak; /**< Flux not going through any of the channels. */ - real deltaQ; /**< The charge imbalance between the compartments. */ + int swapdim; /**< One of XX, YY, ZZ */ + t_pbc* pbc; /**< Needed to make molecules whole. */ + FILE* fpout; /**< Output file. */ + int ngrp; /**< Number of t_swapgrp groups */ + std::vector group; /**< Separate groups for channels, solvent, ions */ + int fluxleak; /**< Flux not going through any of the channels. */ + real deltaQ; /**< The charge imbalance between the compartments. */ }; - /*! \brief Check whether point is in channel. * * A channel is a cylinder defined by a disc @@ -241,14 +249,7 @@ struct t_swap * * \returns Whether the point is inside the defined cylindric channel. */ -static gmx_bool is_in_channel( - rvec point, - rvec center, - real d_up, - real d_down, - real r_cyl2, - t_pbc *pbc, - int normal) +static gmx_bool is_in_channel(rvec point, rvec center, real d_up, real d_down, real r_cyl2, t_pbc* pbc, int normal) { rvec dr; int plane1, plane2; /* Directions tangential to membrane */ @@ -261,13 +262,13 @@ static gmx_bool is_in_channel( pbc_dx(pbc, point, center, dr); /* This puts center in the origin */ /* Check vertical direction */ - if ( (dr[normal] > d_up) || (dr[normal] < -d_down) ) + if ((dr[normal] > d_up) || (dr[normal] < -d_down)) { return FALSE; } /* Check radial direction */ - if ( (dr[plane1]*dr[plane1] + dr[plane2]*dr[plane2]) > r_cyl2) + if ((dr[plane1] * dr[plane1] + dr[plane2] * dr[plane2]) > r_cyl2) { return FALSE; } @@ -283,10 +284,7 @@ static gmx_bool is_in_channel( * where the centers of the split groups are, and how many ions of each type * passed the channels. */ -static void print_ionlist( - t_swap *s, - double time, - const char comment[]) +static void print_ionlist(t_swap* s, double time, const char comment[]) { // Output time fprintf(s->fpout, "%12.5e", time); @@ -297,15 +295,14 @@ static void print_ionlist( { for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { - t_compartment *comp = &s->group[ig].comp[iComp]; + t_compartment* comp = &s->group[ig].comp[iComp]; fprintf(s->fpout, "%10d%10.1f%10d", comp->nMol, comp->nMolAv - comp->nMolReq, comp->inflow_net); } } // Output center of split groups - fprintf(s->fpout, "%10g%10g", - s->group[eGrpSplit0].center[s->swapdim], + fprintf(s->fpout, "%10g%10g", s->group[eGrpSplit0].center[s->swapdim], s->group[eGrpSplit1].center[s->swapdim]); // Output ion flux for each channel and ion type @@ -313,7 +310,7 @@ static void print_ionlist( { for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { - t_swapgrp *g = &s->group[ig]; + t_swapgrp* g = &s->group[ig]; fprintf(s->fpout, "%10d", g->fluxfromAtoB[iChan]); } } @@ -330,12 +327,7 @@ static void print_ionlist( * Since with PBC an atom group might not be whole, use the first atom as the * reference atom and determine the center with respect to this reference. */ -static void get_molecule_center( - rvec x[], - int nat, - const real *weights, - rvec center, - t_pbc *pbc) +static void get_molecule_center(rvec x[], int nat, const real* weights, rvec center, t_pbc* pbc) { int i; rvec weightedPBCimage; @@ -375,11 +367,10 @@ static void get_molecule_center( } /* Normalize */ - svmul(1.0/wsum, center, center); + svmul(1.0 / wsum, center, center); } - /*! \brief Return TRUE if position x of ion (or water) is found in the compartment, * i.e. between w1 and w2. * @@ -412,28 +403,22 @@ static void get_molecule_center( * normally situated in the middle of w1 and w2 that would be considered as having * the bulk concentration of ions). */ -static gmx_bool compartment_contains_atom( - real w1, - real w2, - real x, - real l, - real bulkOffset, - real *distance_from_b) +static gmx_bool compartment_contains_atom(real w1, real w2, real x, real l, real bulkOffset, real* distance_from_b) { real m, l_2; real width; /* First set the origin in the middle of w1 and w2 */ - m = 0.5 * (w1 + w2); - w1 -= m; - w2 -= m; - x -= m; + m = 0.5 * (w1 + w2); + w1 -= m; + w2 -= m; + x -= m; width = w2 - w1; /* Now choose the PBC image of x that is closest to the origin: */ - l_2 = 0.5*l; - while (x > l_2) + l_2 = 0.5 * l; + while (x > l_2) { x -= l; } @@ -442,15 +427,15 @@ static gmx_bool compartment_contains_atom( x += l; } - *distance_from_b = static_cast(fabs(x - bulkOffset*0.5*width)); + *distance_from_b = static_cast(fabs(x - bulkOffset * 0.5 * width)); /* Return TRUE if we now are in area "????" */ - return (x >= w1) && (x < w2); + return (x >= w1) && (x < w2); } /*! \brief Updates the time-averaged number of ions in a compartment. */ -static void update_time_window(t_compartment *comp, int values, int replace) +static void update_time_window(t_compartment* comp, int values, int replace) { real average; int i; @@ -468,7 +453,7 @@ static void update_time_window(t_compartment *comp, int values, int replace) { average += comp->nMolPast[i]; } - average /= values; + average /= values; comp->nMolAv = average; } @@ -480,16 +465,13 @@ static void update_time_window(t_compartment *comp, int values, int replace) * \param[in] distance Shortest distance of this atom to the bulk layer, * from which ion/water pairs are selected for swapping. */ -static void add_to_list( - int ci, - t_compartment *comp, - real distance) +static void add_to_list(int ci, t_compartment* comp, real distance) { int nr = comp->nMol; if (nr >= comp->nalloc) { - comp->nalloc = over_alloc_dd(nr+1); + comp->nalloc = over_alloc_dd(nr + 1); srenew(comp->ind, comp->nalloc); srenew(comp->dist, comp->nalloc); } @@ -500,11 +482,7 @@ static void add_to_list( /*! \brief Determine the compartment boundaries from the channel centers. */ -static void get_compartment_boundaries( - int c, - t_swap *s, - const matrix box, - real *left, real *right) +static void get_compartment_boundaries(int c, t_swap* s, const matrix box, real* left, real* right) { real pos0, pos1; real leftpos, rightpos, leftpos_orig; @@ -512,7 +490,7 @@ static void get_compartment_boundaries( if (c >= eCompNR) { - gmx_fatal(FARGS, "No compartment %c.", c+'A'); + gmx_fatal(FARGS, "No compartment %c.", c + 'A'); } pos0 = s->group[eGrpSplit0].center[s->swapdim]; @@ -565,32 +543,33 @@ static void get_compartment_boundaries( * * \endcode */ -static void detect_flux_per_channel( - t_swapgrp *g, - int iAtom, - int comp, - rvec atomPosition, - unsigned char *comp_now, - unsigned char *comp_from, - unsigned char *channel_label, - t_swapcoords *sc, - t_swap *s, - real cyl0_r2, - real cyl1_r2, - int64_t step, - gmx_bool bRerun, - FILE *fpout) +static void detect_flux_per_channel(t_swapgrp* g, + int iAtom, + int comp, + rvec atomPosition, + unsigned char* comp_now, + unsigned char* comp_from, + unsigned char* channel_label, + t_swapcoords* sc, + t_swap* s, + real cyl0_r2, + real cyl1_r2, + int64_t step, + gmx_bool bRerun, + FILE* fpout) { - int sd, chan_nr; - gmx_bool in_cyl0, in_cyl1; - char buf[STRLEN]; + int sd, chan_nr; + gmx_bool in_cyl0, in_cyl1; + char buf[STRLEN]; - sd = s->swapdim; + sd = s->swapdim; /* Check whether ion is inside any of the channels */ - in_cyl0 = is_in_channel(atomPosition, s->group[eGrpSplit0].center, sc->cyl0u, sc->cyl0l, cyl0_r2, s->pbc, sd); - in_cyl1 = is_in_channel(atomPosition, s->group[eGrpSplit1].center, sc->cyl1u, sc->cyl1l, cyl1_r2, s->pbc, sd); + in_cyl0 = is_in_channel(atomPosition, s->group[eGrpSplit0].center, sc->cyl0u, sc->cyl0l, + cyl0_r2, s->pbc, sd); + in_cyl1 = is_in_channel(atomPosition, s->group[eGrpSplit1].center, sc->cyl1u, sc->cyl1l, + cyl1_r2, s->pbc, sd); if (in_cyl0 && in_cyl1) { @@ -633,10 +612,10 @@ static void detect_flux_per_channel( if (eDomainNotset == *comp_from) { /* Maybe we can set the domain now */ - *comp_from = *comp_now; /* Could still be eDomainNotset, though */ + *comp_from = *comp_now; /* Could still be eDomainNotset, though */ } - else if ( (*comp_now != eDomainNotset ) /* if in channel */ - && (*comp_from != *comp_now) ) + else if ((*comp_now != eDomainNotset) /* if in channel */ + && (*comp_from != *comp_now)) { /* Obviously the ion changed its domain. * Count this for the channel through which it has passed. */ @@ -645,21 +624,24 @@ static void detect_flux_per_channel( case eChHistPassedNone: ++s->fluxleak; - fprintf(stderr, " %s Warning! Step %s, ion %d moved from %s to %s\n", - SwS, gmx_step_str(step, buf), iAtom, DomainString[*comp_from], DomainString[*comp_now]); + fprintf(stderr, " %s Warning! Step %s, ion %d moved from %s to %s\n", SwS, + gmx_step_str(step, buf), iAtom, DomainString[*comp_from], + DomainString[*comp_now]); if (bRerun) { fprintf(stderr, ", possibly due to a swap in the original simulation.\n"); } else { - fprintf(stderr, "but did not pass cyl0 or cyl1 as defined in the .mdp file.\n" + fprintf(stderr, + "but did not pass cyl0 or cyl1 as defined in the .mdp file.\n" "Do you have an ion somewhere within the membrane?\n"); /* Write this info to the CompEL output file: */ - fprintf(s->fpout, " # Warning: step %s, ion %d moved from %s to %s (probably through the membrane)\n", - gmx_step_str(step, buf), iAtom, - DomainString[*comp_from], DomainString[*comp_now]); - + fprintf(s->fpout, + " # Warning: step %s, ion %d moved from %s to %s (probably through the " + "membrane)\n", + gmx_step_str(step, buf), iAtom, DomainString[*comp_from], + DomainString[*comp_now]); } break; case eChHistPassedCh0: @@ -681,11 +663,11 @@ static void detect_flux_per_channel( { g->fluxfromAtoB[chan_nr]--; } - fprintf(fpout, "# Atom nr. %d finished passing %s.\n", iAtom, ChannelString[*channel_label]); + fprintf(fpout, "# Atom nr. %d finished passing %s.\n", iAtom, + ChannelString[*channel_label]); break; default: - gmx_fatal(FARGS, "%s Unknown channel history entry for ion type '%s'\n", - SwS, g->molname); + gmx_fatal(FARGS, "%s Unknown channel history entry for ion type '%s'\n", SwS, g->molname); } /* This ion has moved to the _other_ compartment ... */ @@ -697,23 +679,22 @@ static void detect_flux_per_channel( /*! \brief Determines which ions or solvent molecules are in compartment A and B */ -static void sortMoleculesIntoCompartments( - t_swapgrp *g, - t_commrec *cr, - t_swapcoords *sc, - t_swap *s, - const matrix box, - int64_t step, - FILE *fpout, - gmx_bool bRerun, - gmx_bool bIsSolvent) +static void sortMoleculesIntoCompartments(t_swapgrp* g, + t_commrec* cr, + t_swapcoords* sc, + t_swap* s, + const matrix box, + int64_t step, + FILE* fpout, + gmx_bool bRerun, + gmx_bool bIsSolvent) { - int nMolNotInComp[eCompNR]; /* consistency check */ - real cyl0_r2 = sc->cyl0r * sc->cyl0r; - real cyl1_r2 = sc->cyl1r * sc->cyl1r; + int nMolNotInComp[eCompNR]; /* consistency check */ + real cyl0_r2 = sc->cyl0r * sc->cyl0r; + real cyl1_r2 = sc->cyl1r * sc->cyl1r; /* Get us a counter that cycles in the range of [0 ... sc->nAverage[ */ - int replace = (step/sc->nstswap) % sc->nAverage; + int replace = (step / sc->nstswap) % sc->nAverage; for (int comp = eCompA; comp <= eCompB; comp++) { @@ -727,13 +708,15 @@ static void sortMoleculesIntoCompartments( nMolNotInComp[comp] = 0; /* consistency check */ /* Loop over the molecules and atoms of this group */ - for (int iMol = 0, iAtom = 0; iAtom < static_cast(g->atomset.numAtomsGlobal()); iAtom += g->apm, iMol++) + for (int iMol = 0, iAtom = 0; iAtom < static_cast(g->atomset.numAtomsGlobal()); + iAtom += g->apm, iMol++) { real dist; int sd = s->swapdim; /* Is this first atom of the molecule in the compartment that we look at? */ - if (compartment_contains_atom(left, right, g->xc[iAtom][sd], box[sd][sd], sc->bulkOffset[comp], &dist) ) + if (compartment_contains_atom(left, right, g->xc[iAtom][sd], box[sd][sd], + sc->bulkOffset[comp], &dist)) { /* Add the first atom of this molecule to the list of molecules in this compartment */ add_to_list(iAtom, &g->comp[comp], dist); @@ -742,9 +725,9 @@ static void sortMoleculesIntoCompartments( if (MASTER(cr) && (g->comp_now != nullptr) && !bIsSolvent) { int globalAtomNr = g->atomset.globalIndex()[iAtom] + 1; /* PDB index starts at 1 ... */ - detect_flux_per_channel(g, globalAtomNr, comp, g->xc[iAtom], - &g->comp_now[iMol], &g->comp_from[iMol], &g->channel_label[iMol], - sc, s, cyl0_r2, cyl1_r2, step, bRerun, fpout); + detect_flux_per_channel(g, globalAtomNr, comp, g->xc[iAtom], &g->comp_now[iMol], + &g->comp_from[iMol], &g->channel_label[iMol], sc, s, + cyl0_r2, cyl1_r2, step, bRerun, fpout); } } else @@ -764,9 +747,12 @@ static void sortMoleculesIntoCompartments( { if (g->nCylBoth > 0) { - fprintf(stderr, "\n" - "%s Warning: %d atoms were detected as being in both channels! Probably your split\n" - "%s cylinder is way too large, or one compartment has collapsed (step %" PRId64 ")\n", + fprintf(stderr, + "\n" + "%s Warning: %d atoms were detected as being in both channels! Probably your " + "split\n" + "%s cylinder is way too large, or one compartment has collapsed (step " + "%" PRId64 ")\n", SwS, g->nCylBoth, SwS, step); fprintf(s->fpout, "Warning: %d atoms were assigned to both channels!\n", g->nCylBoth); @@ -777,39 +763,41 @@ static void sortMoleculesIntoCompartments( if (bIsSolvent && nullptr != fpout) { - fprintf(fpout, "# Solv. molecules in comp.%s: %d comp.%s: %d\n", - CompStr[eCompA], g->comp[eCompA].nMol, - CompStr[eCompB], g->comp[eCompB].nMol); + fprintf(fpout, "# Solv. molecules in comp.%s: %d comp.%s: %d\n", CompStr[eCompA], + g->comp[eCompA].nMol, CompStr[eCompB], g->comp[eCompB].nMol); } /* Consistency checks */ const auto numMolecules = static_cast(g->atomset.numAtomsGlobal() / g->apm); if (nMolNotInComp[eCompA] + nMolNotInComp[eCompB] != numMolecules) { - fprintf(stderr, "%s Warning: Inconsistency while assigning '%s' molecules to compartments. !inA: %d, !inB: %d, total molecules %d\n", + fprintf(stderr, + "%s Warning: Inconsistency while assigning '%s' molecules to compartments. !inA: " + "%d, !inB: %d, total molecules %d\n", SwS, g->molname, nMolNotInComp[eCompA], nMolNotInComp[eCompB], numMolecules); } int sum = g->comp[eCompA].nMol + g->comp[eCompB].nMol; if (sum != numMolecules) { - fprintf(stderr, "%s Warning: %d molecules are in group '%s', but altogether %d have been assigned to the compartments.\n", + fprintf(stderr, + "%s Warning: %d molecules are in group '%s', but altogether %d have been assigned " + "to the compartments.\n", SwS, numMolecules, g->molname, sum); } } /*! \brief Find out how many group atoms are in the compartments initially */ -static void get_initial_ioncounts( - const t_inputrec *ir, - t_swap *s, - const rvec x[], /* the initial positions */ - const matrix box, - t_commrec *cr, - gmx_bool bRerun) +static void get_initial_ioncounts(const t_inputrec* ir, + t_swap* s, + const rvec x[], /* the initial positions */ + const matrix box, + t_commrec* cr, + gmx_bool bRerun) { - t_swapcoords *sc; - t_swapgrp *g; + t_swapcoords* sc; + t_swapgrp* g; sc = ir->swap; @@ -847,13 +835,13 @@ static void get_initial_ioncounts( int req = g->comp[eCompA].nMolReq + g->comp[eCompB].nMolReq; int tot = g->comp[eCompA].nMol + g->comp[eCompB].nMol; - if ( (req != tot) ) + if ((req != tot)) { - gmx_fatal(FARGS, "Mismatch of the number of %s ions summed over both compartments.\n" + gmx_fatal(FARGS, + "Mismatch of the number of %s ions summed over both compartments.\n" "You requested a total of %d ions (%d in A and %d in B),\n" "but there are a total of %d ions of this type in the system.\n", - g->molname, req, g->comp[eCompA].nMolReq, - g->comp[eCompB].nMolReq, tot); + g->molname, req, g->comp[eCompA].nMolReq, g->comp[eCompB].nMolReq, tot); } /* Initialize time-averaging: @@ -875,15 +863,15 @@ static void get_initial_ioncounts( * When called, the checkpoint file has already been read in. Here we copy * over the values from .cpt file to the swap data structure. */ -static void get_initial_ioncounts_from_cpt( - const t_inputrec *ir, - t_swap *s, - swaphistory_t *swapstate, - t_commrec *cr, gmx_bool bVerbose) +static void get_initial_ioncounts_from_cpt(const t_inputrec* ir, + t_swap* s, + swaphistory_t* swapstate, + t_commrec* cr, + gmx_bool bVerbose) { - t_swapcoords *sc; - t_swapgrp *g; - swapstateIons_t *gs; + t_swapcoords* sc; + t_swapgrp* g; + swapstateIons_t* gs; sc = ir->swap; @@ -930,13 +918,10 @@ static void get_initial_ioncounts_from_cpt( /*! \brief The master lets all others know about the initial ion counts. */ -static void bc_initial_concentrations( - t_commrec *cr, - t_swapcoords *swap, - t_swap *s) +static void bc_initial_concentrations(t_commrec* cr, t_swapcoords* swap, t_swap* s) { int ic, ig; - t_swapgrp *g; + t_swapgrp* g; for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) @@ -946,20 +931,20 @@ static void bc_initial_concentrations( for (ic = 0; ic < eCompNR; ic++) { gmx_bcast(sizeof(g->comp[ic].nMolReq), &(g->comp[ic].nMolReq), cr); - gmx_bcast(sizeof(g->comp[ic].nMol ), &(g->comp[ic].nMol ), cr); - gmx_bcast( swap->nAverage * sizeof(g->comp[ic].nMolPast[0]), g->comp[ic].nMolPast, cr); + gmx_bcast(sizeof(g->comp[ic].nMol), &(g->comp[ic].nMol), cr); + gmx_bcast(swap->nAverage * sizeof(g->comp[ic].nMolPast[0]), g->comp[ic].nMolPast, cr); } } } /*! \brief Ensure that each atom belongs to at most one of the swap groups. */ -static void check_swap_groups(t_swap *s, int nat, gmx_bool bVerbose) +static void check_swap_groups(t_swap* s, int nat, gmx_bool bVerbose) { - int *nGroup = nullptr; /* This array counts for each atom in the MD system to - how many swap groups it belongs (should be 0 or 1!) */ - int ind = -1; - int nMultiple = 0; /* Number of atoms belonging to multiple groups */ + int* nGroup = nullptr; /* This array counts for each atom in the MD system to + how many swap groups it belongs (should be 0 or 1!) */ + int ind = -1; + int nMultiple = 0; /* Number of atoms belonging to multiple groups */ if (bVerbose) @@ -971,7 +956,7 @@ static void check_swap_groups(t_swap *s, int nat, gmx_bool bVerbose) snew(nGroup, nat); for (int i = 0; i < s->ngrp; i++) { - t_swapgrp *g = &s->group[i]; + t_swapgrp* g = &s->group[i]; for (size_t j = 0; j < g->atomset.numAtomsGlobal(); j++) { /* Get the global index of this atom of this group: */ @@ -991,9 +976,13 @@ static void check_swap_groups(t_swap *s, int nat, gmx_bool bVerbose) if (nMultiple) { - gmx_fatal(FARGS, "%s Cannot perform swapping since %d atom%s allocated to more than one swap index group.\n" - "%s Each atom must be allocated to at most one of the split groups, the swap groups, or the solvent.\n" - "%s Check the .mdp file settings regarding the swap index groups or the index groups themselves.\n", + gmx_fatal(FARGS, + "%s Cannot perform swapping since %d atom%s allocated to more than one swap " + "index group.\n" + "%s Each atom must be allocated to at most one of the split groups, the swap " + "groups, or the solvent.\n" + "%s Check the .mdp file settings regarding the swap index groups or the index " + "groups themselves.\n", SwS, nMultiple, (1 == nMultiple) ? " is" : "s are", SwSEmpty, SwSEmpty); } } @@ -1003,14 +992,10 @@ static void check_swap_groups(t_swap *s, int nat, gmx_bool bVerbose) * * Also ensure that all the molecules in this group have this number of atoms. */ -static int get_group_apm_check( - int igroup, - t_swap *s, - gmx_bool bVerbose, - gmx_mtop_t *mtop) +static int get_group_apm_check(int igroup, t_swap* s, gmx_bool bVerbose, gmx_mtop_t* mtop) { - t_swapgrp *g = &s->group[igroup]; - const int *ind = s->group[igroup].atomset.globalIndex().data(); + t_swapgrp* g = &s->group[igroup]; + const int* ind = s->group[igroup].atomset.globalIndex().data(); int nat = s->group[igroup].atomset.numAtomsGlobal(); /* Determine the number of solvent atoms per solvent molecule from the @@ -1031,12 +1016,11 @@ static int get_group_apm_check( mtopGetMolblockIndex(mtop, ind[i], &molb, nullptr, nullptr); if (apm != mtop->moleculeBlockIndices[molb].numAtomsPerMolecule) { - gmx_fatal(FARGS, "Not all molecules of swap group %d consist of %d atoms.", - igroup, apm); + gmx_fatal(FARGS, "Not all molecules of swap group %d consist of %d atoms.", igroup, apm); } } - //TODO: check whether charges and masses of each molecule are identical! + // TODO: check whether charges and masses of each molecule are identical! return apm; } @@ -1045,16 +1029,14 @@ static int get_group_apm_check( * * Also print the initial values of ion counts and position of split groups. */ -static void print_ionlist_legend(const t_inputrec *ir, - t_swap *s, - const gmx_output_env_t *oenv) +static void print_ionlist_legend(const t_inputrec* ir, t_swap* s, const gmx_output_env_t* oenv) { - const char **legend; + const char** legend; int count = 0; char buf[STRLEN]; - int nIonTypes = ir->swap->ngrp - eSwapFixedGrpNR; - snew(legend, eCompNR*nIonTypes*3 + 2 + eChanNR*nIonTypes + 1); + int nIonTypes = ir->swap->ngrp - eSwapFixedGrpNR; + snew(legend, eCompNR * nIonTypes * 3 + 2 + eChanNR * nIonTypes + 1); // Number of molecules and difference to reference counts for each // compartment and ion type @@ -1062,14 +1044,14 @@ static void print_ionlist_legend(const t_inputrec *ir, { for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { - t_swapGroup *g = &ir->swap->grp[ig]; + t_swapGroup* g = &ir->swap->grp[ig]; real q = s->group[ig].q; snprintf(buf, STRLEN, "%s %s ions (charge %s%g)", CompStr[ic], g->molname, q > 0 ? "+" : "", q); legend[count++] = gmx_strdup(buf); - snprintf(buf, STRLEN, "%s av. mismatch to %d %s ions", - CompStr[ic], s->group[ig].comp[ic].nMolReq, g->molname); + snprintf(buf, STRLEN, "%s av. mismatch to %d %s ions", CompStr[ic], + s->group[ig].comp[ic].nMolReq, g->molname); legend[count++] = gmx_strdup(buf); snprintf(buf, STRLEN, "%s net %s ion influx", CompStr[ic], g->molname); @@ -1078,9 +1060,11 @@ static void print_ionlist_legend(const t_inputrec *ir, } // Center of split groups - snprintf(buf, STRLEN, "%scenter of %s of split group 0", SwapStr[ir->eSwapCoords], (nullptr != s->group[eGrpSplit0].m) ? "mass" : "geometry"); + snprintf(buf, STRLEN, "%scenter of %s of split group 0", SwapStr[ir->eSwapCoords], + (nullptr != s->group[eGrpSplit0].m) ? "mass" : "geometry"); legend[count++] = gmx_strdup(buf); - snprintf(buf, STRLEN, "%scenter of %s of split group 1", SwapStr[ir->eSwapCoords], (nullptr != s->group[eGrpSplit1].m) ? "mass" : "geometry"); + snprintf(buf, STRLEN, "%scenter of %s of split group 1", SwapStr[ir->eSwapCoords], + (nullptr != s->group[eGrpSplit1].m) ? "mass" : "geometry"); legend[count++] = gmx_strdup(buf); // Ion flux for each channel and ion type @@ -1088,7 +1072,7 @@ static void print_ionlist_legend(const t_inputrec *ir, { for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { - t_swapGroup *g = &ir->swap->grp[ig]; + t_swapGroup* g = &ir->swap->grp[ig]; snprintf(buf, STRLEN, "A->ch%d->B %s permeations", ic, g->molname); legend[count++] = gmx_strdup(buf); } @@ -1100,7 +1084,8 @@ static void print_ionlist_legend(const t_inputrec *ir, xvgr_legend(s->fpout, count, legend, oenv); - fprintf(s->fpout, "# Instantaneous ion counts and time-averaged differences to requested numbers\n"); + fprintf(s->fpout, + "# Instantaneous ion counts and time-averaged differences to requested numbers\n"); // We add a simple text legend helping to identify the columns with xvgr legend strings fprintf(s->fpout, "# time (ps)"); @@ -1119,13 +1104,10 @@ static void print_ionlist_legend(const t_inputrec *ir, * Initialize arrays that keep track of where the ions come from and where * they go. */ -static void detect_flux_per_channel_init( - t_swap *s, - swaphistory_t *swapstate, - const bool isRestart) +static void detect_flux_per_channel_init(t_swap* s, swaphistory_t* swapstate, const bool isRestart) { - t_swapgrp *g; - swapstateIons_t *gs; + t_swapgrp* g; + swapstateIons_t* gs; /* All these flux detection routines run on the master only */ if (swapstate == nullptr) @@ -1148,15 +1130,15 @@ static void detect_flux_per_channel_init( } else /* allocate memory for molecule counts */ { - snew(g->comp_from, g->atomset.numAtomsGlobal()/g->apm); + snew(g->comp_from, g->atomset.numAtomsGlobal() / g->apm); gs->comp_from = g->comp_from; - snew(g->channel_label, g->atomset.numAtomsGlobal()/g->apm); + snew(g->channel_label, g->atomset.numAtomsGlobal() / g->apm); gs->channel_label = g->channel_label; } - snew(g->comp_now, g->atomset.numAtomsGlobal()/g->apm); + snew(g->comp_now, g->atomset.numAtomsGlobal() / g->apm); /* Initialize the channel and domain history counters */ - for (size_t i = 0; i < g->atomset.numAtomsGlobal()/g->apm; i++) + for (size_t i = 0; i < g->atomset.numAtomsGlobal() / g->apm; i++) { g->comp_now[i] = eDomainNotset; if (!isRestart) @@ -1188,7 +1170,8 @@ static void detect_flux_per_channel_init( for (int ic = 0; ic < eChanNR; ic++) { - fprintf(stderr, "%s Channel %d flux history for ion type %s (charge %g): ", SwS, ic, g->molname, g->q); + fprintf(stderr, "%s Channel %d flux history for ion type %s (charge %g): ", SwS, ic, + g->molname, g->q); if (isRestart) { g->fluxfromAtoB[ic] = gs->fluxfromAtoB[ic]; @@ -1198,8 +1181,7 @@ static void detect_flux_per_channel_init( g->fluxfromAtoB[ic] = 0; } - fprintf(stderr, "%d molecule%s", - g->fluxfromAtoB[ic], g->fluxfromAtoB[ic] == 1 ? "" : "s"); + fprintf(stderr, "%d molecule%s", g->fluxfromAtoB[ic], g->fluxfromAtoB[ic] == 1 ? "" : "s"); fprintf(stderr, "\n"); } } @@ -1226,17 +1208,21 @@ static void detect_flux_per_channel_init( * If this is not correct, the ion counts per channel will be very likely * wrong. */ -static void outputStartStructureIfWanted(gmx_mtop_t *mtop, rvec *x, int ePBC, const matrix box) +static void outputStartStructureIfWanted(gmx_mtop_t* mtop, rvec* x, int ePBC, const matrix box) { - char *env = getenv("GMX_COMPELDUMP"); + char* env = getenv("GMX_COMPELDUMP"); if (env != nullptr) { - fprintf(stderr, "\n%s Found env.var. GMX_COMPELDUMP, will output CompEL starting structure made whole.\n" - "%s In case of multimeric channels, please check whether they have the correct PBC representation.\n", + fprintf(stderr, + "\n%s Found env.var. GMX_COMPELDUMP, will output CompEL starting structure made " + "whole.\n" + "%s In case of multimeric channels, please check whether they have the correct PBC " + "representation.\n", SwS, SwSEmpty); - write_sto_conf_mtop("CompELAssumedWholeConfiguration.pdb", *mtop->name, mtop, x, nullptr, ePBC, box); + write_sto_conf_mtop("CompELAssumedWholeConfiguration.pdb", *mtop->name, mtop, x, nullptr, + ePBC, box); } } @@ -1251,17 +1237,16 @@ static void outputStartStructureIfWanted(gmx_mtop_t *mtop, rvec *x, int ePBC, co * swapstate to the x_old arrays, which contain the correct PBC representation of * multimeric channels at the last time step. */ -static void init_swapstate( - swaphistory_t *swapstate, - t_swapcoords *sc, - t_swap *s, - gmx_mtop_t *mtop, - const rvec *x, /* the initial positions */ - const matrix box, - const t_inputrec *ir) +static void init_swapstate(swaphistory_t* swapstate, + t_swapcoords* sc, + t_swap* s, + gmx_mtop_t* mtop, + const rvec* x, /* the initial positions */ + const matrix box, + const t_inputrec* ir) { - rvec *x_pbc = nullptr; /* positions of the whole MD system with molecules made whole */ - t_swapgrp *g; + rvec* x_pbc = nullptr; /* positions of the whole MD system with molecules made whole */ + t_swapgrp* g; /* We always need the last whole positions such that @@ -1270,12 +1255,12 @@ static void init_swapstate( { /* Copy the last whole positions of each channel from .cpt */ g = &(s->group[eGrpSplit0]); - for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++) + for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++) { copy_rvec(swapstate->xc_old_whole[eChan0][i], g->xc_old[i]); } g = &(s->group[eGrpSplit1]); - for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++) + for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++) { copy_rvec(swapstate->xc_old_whole[eChan1][i], g->xc_old[i]); } @@ -1292,8 +1277,8 @@ static void init_swapstate( * structure that is accessible during checkpoint writing */ for (int ii = 0; ii < swapstate->nIonTypes; ii++) { - swapstateIons_t *gs = &swapstate->ionType[ii]; - gs->nMol = sc->grp[ii + eSwapFixedGrpNR].nat; + swapstateIons_t* gs = &swapstate->ionType[ii]; + gs->nMol = sc->grp[ii + eSwapFixedGrpNR].nat; } /* Extract the initial split group positions. */ @@ -1332,11 +1317,11 @@ static void init_swapstate( } /*! \brief Determine the total charge imbalance resulting from the swap groups */ -static real getRequestedChargeImbalance(t_swap *s) +static real getRequestedChargeImbalance(t_swap* s) { int ig; real DeltaQ = 0.0; - t_swapgrp *g; + t_swapgrp* g; real particle_charge; real particle_number[eCompNR]; @@ -1363,26 +1348,25 @@ static real getRequestedChargeImbalance(t_swap *s) * This routine should be called for the 'anions' and 'cations' group, * of which the indices were lumped together in the older version of the code. */ -static void copyIndicesToGroup( - const int *indIons, - int nIons, - t_swapGroup *g, - t_commrec *cr) +static void copyIndicesToGroup(const int* indIons, int nIons, t_swapGroup* g, t_commrec* cr) { g->nat = nIons; /* If explicit ion counts were requested in the .mdp file * (by setting positive values for the number of ions), * we can make an additional consistency check here */ - if ( (g->nmolReq[eCompA] < 0) && (g->nmolReq[eCompB] < 0) ) + if ((g->nmolReq[eCompA] < 0) && (g->nmolReq[eCompB] < 0)) { - if (g->nat != (g->nmolReq[eCompA] + g->nmolReq[eCompB]) ) + if (g->nat != (g->nmolReq[eCompA] + g->nmolReq[eCompB])) { gmx_fatal_collective(FARGS, cr->mpi_comm_mysim, MASTER(cr), - "%s Inconsistency while importing swap-related data from an old input file version.\n" + "%s Inconsistency while importing swap-related data from an old " + "input file version.\n" "%s The requested ion counts in compartments A (%d) and B (%d)\n" - "%s do not add up to the number of ions (%d) of this type for the group '%s'.\n", - SwS, SwSEmpty, g->nmolReq[eCompA], g->nmolReq[eCompB], SwSEmpty, g->nat, g->molname); + "%s do not add up to the number of ions (%d) of this type for the " + "group '%s'.\n", + SwS, SwSEmpty, g->nmolReq[eCompA], g->nmolReq[eCompB], SwSEmpty, + g->nat, g->molname); } } @@ -1407,28 +1391,24 @@ static void copyIndicesToGroup( * #4 cations - empty before conversion * */ -static void convertOldToNewGroupFormat( - t_swapcoords *sc, - gmx_mtop_t *mtop, - gmx_bool bVerbose, - t_commrec *cr) +static void convertOldToNewGroupFormat(t_swapcoords* sc, gmx_mtop_t* mtop, gmx_bool bVerbose, t_commrec* cr) { - t_swapGroup *g = &sc->grp[3]; + t_swapGroup* g = &sc->grp[3]; /* Loop through the atom indices of group #3 (anions) and put all indices * that belong to cations into the cation group. */ int nAnions = 0; int nCations = 0; - int *indAnions = nullptr; - int *indCations = nullptr; + int* indAnions = nullptr; + int* indCations = nullptr; snew(indAnions, g->nat); snew(indCations, g->nat); int molb = 0; for (int i = 0; i < g->nat; i++) { - const t_atom &atom = mtopGetAtomParameters(mtop, g->ind[i], &molb); + const t_atom& atom = mtopGetAtomParameters(mtop, g->ind[i], &molb); if (atom.q < 0) { // This is an anion, add it to the list of anions @@ -1462,48 +1442,50 @@ static void convertOldToNewGroupFormat( /*! \brief Returns TRUE if we started from an old .tpr * * Then we need to re-sort anions and cations into separate groups */ -static gmx_bool bConvertFromOldTpr(t_swapcoords *sc) +static gmx_bool bConvertFromOldTpr(t_swapcoords* sc) { // If the last group has no atoms it means we need to convert! return (sc->ngrp >= 5) && (0 == sc->grp[4].nat); } -t_swap *init_swapcoords( - FILE *fplog, - const t_inputrec *ir, - const char *fn, - gmx_mtop_t *mtop, - const t_state *globalState, - ObservablesHistory *oh, - t_commrec *cr, - gmx::LocalAtomSetManager *atomSets, - const gmx_output_env_t *oenv, - const gmx::MdrunOptions &mdrunOptions, - const gmx::StartingBehavior startingBehavior) +t_swap* init_swapcoords(FILE* fplog, + const t_inputrec* ir, + const char* fn, + gmx_mtop_t* mtop, + const t_state* globalState, + ObservablesHistory* oh, + t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + const gmx_output_env_t* oenv, + const gmx::MdrunOptions& mdrunOptions, + const gmx::StartingBehavior startingBehavior) { - t_swapgrp *g; - swapstateIons_t *gs; - swaphistory_t *swapstate = nullptr; + t_swapgrp* g; + swapstateIons_t* gs; + swaphistory_t* swapstate = nullptr; - if ( (PAR(cr)) && !DOMAINDECOMP(cr) ) + if ((PAR(cr)) && !DOMAINDECOMP(cr)) { gmx_fatal(FARGS, "Position swapping is only implemented for domain decomposition!"); } - auto sc = ir->swap; - auto s = new t_swap(); + auto sc = ir->swap; + auto s = new t_swap(); if (mdrunOptions.rerun) { if (PAR(cr)) { - gmx_fatal(FARGS, "%s This module does not support reruns in parallel\nPlease request a serial run with -nt 1 / -np 1\n", SwS); + gmx_fatal(FARGS, + "%s This module does not support reruns in parallel\nPlease request a serial " + "run with -nt 1 / -np 1\n", + SwS); } fprintf(stderr, "%s Rerun - using every available frame\n", SwS); sc->nstswap = 1; - sc->nAverage = 1; /* averaging makes no sense for reruns */ + sc->nAverage = 1; /* averaging makes no sense for reruns */ } if (MASTER(cr) && startingBehavior == gmx::StartingBehavior::NewSimulation) @@ -1514,24 +1496,16 @@ t_swap *init_swapcoords( switch (ir->eSwapCoords) { - case eswapX: - s->swapdim = XX; - break; - case eswapY: - s->swapdim = YY; - break; - case eswapZ: - s->swapdim = ZZ; - break; - default: - s->swapdim = -1; - break; + case eswapX: s->swapdim = XX; break; + case eswapY: s->swapdim = YY; break; + case eswapZ: s->swapdim = ZZ; break; + default: s->swapdim = -1; break; } const gmx_bool bVerbose = mdrunOptions.verbose; // For compatibility with old .tpr files - if (bConvertFromOldTpr(sc) ) + if (bConvertFromOldTpr(sc)) { convertOldToNewGroupFormat(sc, mtop, bVerbose && MASTER(cr), cr); } @@ -1541,7 +1515,8 @@ t_swap *init_swapcoords( s->ngrp = sc->ngrp; for (int i = 0; i < s->ngrp; i++) { - s->group.emplace_back(atomSets->add(gmx::ArrayRef( sc->grp[i].ind, sc->grp[i].ind+sc->grp[i].nat))); + s->group.emplace_back(atomSets->add( + gmx::ArrayRef(sc->grp[i].ind, sc->grp[i].ind + sc->grp[i].nat))); s->group[i].molname = sc->grp[i].molname; } @@ -1558,7 +1533,7 @@ t_swap *init_swapcoords( /* For the split groups (the channels) we need some extra memory to * be able to make the molecules whole even if they span more than * half of the box size. */ - if ( (i == eGrpSplit0) || (i == eGrpSplit1) ) + if ((i == eGrpSplit0) || (i == eGrpSplit1)) { snew(g->xc_shifts, g->atomset.numAtomsGlobal()); snew(g->xc_eshifts, g->atomset.numAtomsGlobal()); @@ -1570,7 +1545,7 @@ t_swap *init_swapcoords( { if (oh->swapHistory == nullptr) { - oh->swapHistory = std::make_unique(swaphistory_t {}); + oh->swapHistory = std::make_unique(swaphistory_t{}); } swapstate = oh->swapHistory.get(); @@ -1584,7 +1559,7 @@ t_swap *init_swapcoords( for (int ig = eGrpSplit0; ig <= eGrpSplit1; ig++) { g = &(s->group[ig]); - gmx_bcast((g->atomset.numAtomsGlobal())*sizeof((g->xc_old)[0]), g->xc_old, (cr)); + gmx_bcast((g->atomset.numAtomsGlobal()) * sizeof((g->xc_old)[0]), g->xc_old, (cr)); } } @@ -1599,13 +1574,13 @@ t_swap *init_swapcoords( /* Since all molecules of a group are equal, we only need enough space * to determine properties of a single molecule at at time */ - snew(g->m, g->apm); /* For the center of mass */ - charge = 0; /* To determine the charge imbalance */ + snew(g->m, g->apm); /* For the center of mass */ + charge = 0; /* To determine the charge imbalance */ int molb = 0; for (int j = 0; j < g->apm; j++) { - const t_atom &atom = mtopGetAtomParameters(mtop, g->atomset.globalIndex()[j], &molb); - g->m[j] = atom.m; + const t_atom& atom = mtopGetAtomParameters(mtop, g->atomset.globalIndex()[j], &molb); + g->m[j] = atom.m; charge += atom.q; } /* Total charge of one molecule of this group: */ @@ -1638,10 +1613,11 @@ t_swap *init_swapcoords( { if (bVerbose) { - fprintf(stderr, "%s Opening output file %s%s\n", SwS, fn, restartWithAppending ? " for appending" : ""); + fprintf(stderr, "%s Opening output file %s%s\n", SwS, fn, + restartWithAppending ? " for appending" : ""); } - s->fpout = gmx_fio_fopen(fn, restartWithAppending ? "a" : "w" ); + s->fpout = gmx_fio_fopen(fn, restartWithAppending ? "a" : "w"); if (!restartWithAppending) { @@ -1651,12 +1627,13 @@ t_swap *init_swapcoords( { g = &(s->group[ig]); fprintf(s->fpout, "# %s group '%s' contains %d atom%s", - ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion", - g->molname, static_cast(g->atomset.numAtomsGlobal()), (g->atomset.numAtomsGlobal() > 1) ? "s" : ""); - if (!(eGrpSplit0 == ig || eGrpSplit1 == ig) ) + ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion", g->molname, + static_cast(g->atomset.numAtomsGlobal()), + (g->atomset.numAtomsGlobal() > 1) ? "s" : ""); + if (!(eGrpSplit0 == ig || eGrpSplit1 == ig)) { - fprintf(s->fpout, " with %d atom%s in each molecule of charge %g", - g->apm, (g->apm > 1) ? "s" : "", g->q); + fprintf(s->fpout, " with %d atom%s in each molecule of charge %g", g->apm, + (g->apm > 1) ? "s" : "", g->q); } fprintf(s->fpout, ".\n"); } @@ -1683,30 +1660,39 @@ t_swap *init_swapcoords( if (!restartWithAppending) { - if ( (0 != sc->bulkOffset[eCompA]) || (0 != sc->bulkOffset[eCompB]) ) + if ((0 != sc->bulkOffset[eCompA]) || (0 != sc->bulkOffset[eCompB])) { fprintf(s->fpout, "#\n"); - fprintf(s->fpout, "# You provided an offset for the position of the bulk layer(s).\n"); - fprintf(s->fpout, "# That means the layers to/from which ions and water molecules are swapped\n"); - fprintf(s->fpout, "# are not midway (= at 0.0) between the compartment-defining layers (at +/- 1.0).\n"); + fprintf(s->fpout, + "# You provided an offset for the position of the bulk layer(s).\n"); + fprintf(s->fpout, + "# That means the layers to/from which ions and water molecules are " + "swapped\n"); + fprintf(s->fpout, + "# are not midway (= at 0.0) between the compartment-defining layers (at " + "+/- 1.0).\n"); fprintf(s->fpout, "# bulk-offsetA = %g\n", sc->bulkOffset[eCompA]); fprintf(s->fpout, "# bulk-offsetB = %g\n", sc->bulkOffset[eCompB]); } fprintf(s->fpout, "#\n"); - fprintf(s->fpout, "# Split0 cylinder radius %f nm, up %f nm, down %f nm\n", - sc->cyl0r, sc->cyl0u, sc->cyl0l); - fprintf(s->fpout, "# Split1 cylinder radius %f nm, up %f nm, down %f nm\n", - sc->cyl1r, sc->cyl1u, sc->cyl1l); + fprintf(s->fpout, "# Split0 cylinder radius %f nm, up %f nm, down %f nm\n", sc->cyl0r, + sc->cyl0u, sc->cyl0l); + fprintf(s->fpout, "# Split1 cylinder radius %f nm, up %f nm, down %f nm\n", sc->cyl1r, + sc->cyl1u, sc->cyl1l); fprintf(s->fpout, "#\n"); if (!mdrunOptions.rerun) { - fprintf(s->fpout, "# Coupling constant (number of swap attempt steps to average over): %d (translates to %f ps).\n", - sc->nAverage, sc->nAverage*sc->nstswap*ir->delta_t); + fprintf(s->fpout, + "# Coupling constant (number of swap attempt steps to average over): %d " + "(translates to %f ps).\n", + sc->nAverage, sc->nAverage * sc->nstswap * ir->delta_t); fprintf(s->fpout, "# Threshold is %f\n", sc->threshold); fprintf(s->fpout, "#\n"); - fprintf(s->fpout, "# Remarks about which atoms passed which channel use global atoms numbers starting at one.\n"); + fprintf(s->fpout, + "# Remarks about which atoms passed which channel use global atoms numbers " + "starting at one.\n"); } } } @@ -1735,7 +1721,8 @@ t_swap *init_swapcoords( else { fprintf(stderr, "%s Determining initial numbers of ions per compartment.\n", SwS); - get_initial_ioncounts(ir, s, globalState->x.rvec_array(), globalState->box, cr, mdrunOptions.rerun); + get_initial_ioncounts(ir, s, globalState->x.rvec_array(), globalState->box, cr, + mdrunOptions.rerun); } /* Prepare (further) checkpoint writes ... */ @@ -1806,7 +1793,7 @@ t_swap *init_swapcoords( } -void finish_swapcoords(t_swap *s) +void finish_swapcoords(t_swap* s) { if (s == nullptr) { @@ -1824,11 +1811,10 @@ void finish_swapcoords(t_swap *s) * From the requested and average molecule counts we determine whether a swap is needed * at this time step. */ -static gmx_bool need_swap(t_swapcoords *sc, - t_swap *s) +static gmx_bool need_swap(t_swapcoords* sc, t_swap* s) { int ic, ig; - t_swapgrp *g; + t_swapgrp* g; for (ig = eSwapFixedGrpNR; ig < sc->ngrp; ig++) { @@ -1857,9 +1843,7 @@ static gmx_bool need_swap(t_swapcoords *sc, * * \returns Index of the first atom of the molecule chosen for a position exchange. */ -static int get_index_of_distant_atom( - t_compartment *comp, - const char molname[]) +static int get_index_of_distant_atom(t_compartment* comp, const char molname[]) { int ibest = -1; real d = GMX_REAL_MAX; @@ -1869,7 +1853,7 @@ static int get_index_of_distant_atom( * prior to doing any swaps. Some of these atoms may already have been * swapped out, but then they are marked with a distance of GMX_REAL_MAX */ - for (int iMol = 0; iMol < comp->nMolBefore; iMol++) + for (int iMol = 0; iMol < comp->nMolBefore; iMol++) { if (comp->dist[iMol] < d) { @@ -1880,7 +1864,9 @@ static int get_index_of_distant_atom( if (ibest < 0) { - gmx_fatal(FARGS, "Could not get index of %s atom. Compartment contains %d %s molecules before swaps.", + gmx_fatal(FARGS, + "Could not get index of %s atom. Compartment contains %d %s molecules before " + "swaps.", molname, comp->nMolBefore, molname); } @@ -1894,12 +1880,7 @@ static int get_index_of_distant_atom( /*! \brief Swaps centers of mass and makes molecule whole if broken */ -static void translate_positions( - rvec *x, - int apm, - rvec old_com, - rvec new_com, - t_pbc *pbc) +static void translate_positions(rvec* x, int apm, rvec old_com, rvec new_com, t_pbc* pbc) { int i; rvec reference, dx, correctPBCimage; @@ -1926,9 +1907,7 @@ static void translate_positions( /*! \brief Write back the modified local positions from the collective array to the official positions. */ -static void apply_modified_positions( - swap_group *g, - rvec x[]) +static void apply_modified_positions(swap_group* g, rvec x[]) { auto collectiveIndex = g->atomset.collectiveIndex().begin(); for (const auto localIndex : g->atomset.localIndex()) @@ -1940,30 +1919,29 @@ static void apply_modified_positions( } -gmx_bool do_swapcoords( - t_commrec *cr, - int64_t step, - double t, - t_inputrec *ir, - t_swap *s, - gmx_wallcycle *wcycle, - rvec x[], - matrix box, - gmx_bool bVerbose, - gmx_bool bRerun) +gmx_bool do_swapcoords(t_commrec* cr, + int64_t step, + double t, + t_inputrec* ir, + t_swap* s, + gmx_wallcycle* wcycle, + rvec x[], + matrix box, + gmx_bool bVerbose, + gmx_bool bRerun) { - t_swapcoords *sc; - int j, ic, ig, nswaps; - int thisC, otherC; /* Index into this compartment and the other one */ - gmx_bool bSwap = FALSE; - t_swapgrp *g, *gsol; - int isol, iion; - rvec com_solvent, com_particle; /* solvent and swap molecule's center of mass */ + t_swapcoords* sc; + int j, ic, ig, nswaps; + int thisC, otherC; /* Index into this compartment and the other one */ + gmx_bool bSwap = FALSE; + t_swapgrp * g, *gsol; + int isol, iion; + rvec com_solvent, com_particle; /* solvent and swap molecule's center of mass */ wallcycle_start(wcycle, ewcSWAP); - sc = ir->swap; + sc = ir->swap; set_pbc(s->pbc, ir->ePBC, box); @@ -1974,8 +1952,10 @@ gmx_bool do_swapcoords( for (ig = eGrpSplit0; ig <= eGrpSplit1; ig++) { g = &(s->group[ig]); - communicate_group_positions(cr, g->xc, g->xc_shifts, g->xc_eshifts, TRUE, - x, g->atomset.numAtomsGlobal(), g->atomset.numAtomsLocal(), g->atomset.localIndex().data(), g->atomset.collectiveIndex().data(), g->xc_old, box); + communicate_group_positions(cr, g->xc, g->xc_shifts, g->xc_eshifts, TRUE, x, + g->atomset.numAtomsGlobal(), g->atomset.numAtomsLocal(), + g->atomset.localIndex().data(), + g->atomset.collectiveIndex().data(), g->xc_old, box); get_center(g->xc, g->m, g->atomset.numAtomsGlobal(), g->center); /* center of split groups == channels */ } @@ -1986,8 +1966,9 @@ gmx_bool do_swapcoords( for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { g = &(s->group[ig]); - communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, - x, g->atomset.numAtomsGlobal(), g->atomset.numAtomsLocal(), g->atomset.localIndex().data(), g->atomset.collectiveIndex().data(), nullptr, nullptr); + communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, x, g->atomset.numAtomsGlobal(), + g->atomset.numAtomsLocal(), g->atomset.localIndex().data(), + g->atomset.collectiveIndex().data(), nullptr, nullptr); /* Determine how many ions of this type each compartment contains */ sortMoleculesIntoCompartments(g, cr, sc, s, box, step, s->fpout, bRerun, FALSE); @@ -2013,8 +1994,9 @@ gmx_bool do_swapcoords( /* Since we here know that we have to perform ion/water position exchanges, * we now assemble the solvent positions */ g = &(s->group[eGrpSolvent]); - communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, - x, g->atomset.numAtomsGlobal(), g->atomset.numAtomsLocal(), g->atomset.localIndex().data(), g->atomset.collectiveIndex().data(), nullptr, nullptr); + communicate_group_positions(cr, g->xc, nullptr, nullptr, FALSE, x, g->atomset.numAtomsGlobal(), + g->atomset.numAtomsLocal(), g->atomset.localIndex().data(), + g->atomset.collectiveIndex().data(), nullptr, nullptr); /* Determine how many molecules of solvent each compartment contains */ sortMoleculesIntoCompartments(g, cr, sc, s, box, step, s->fpout, bRerun, TRUE); @@ -2038,7 +2020,7 @@ gmx_bool do_swapcoords( } /* Now actually perform the particle exchanges, one swap group after another */ - gsol = &s->group[eGrpSolvent]; + gsol = &s->group[eGrpSolvent]; for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++) { nswaps = 0; @@ -2046,7 +2028,7 @@ gmx_bool do_swapcoords( for (thisC = 0; thisC < eCompNR; thisC++) { /* Index to the other compartment */ - otherC = (thisC+1) % eCompNR; + otherC = (thisC + 1) % eCompNR; while (g->vacancy[thisC] >= sc->threshold) { @@ -2067,24 +2049,24 @@ gmx_bool do_swapcoords( translate_positions(&g->xc[iion], g->apm, com_particle, com_solvent, s->pbc); /* Keep track of the changes */ - g->vacancy[thisC ]--; + g->vacancy[thisC]--; g->vacancy[otherC]++; - g->comp [thisC ].nMol++; - g->comp [otherC].nMol--; - g->comp [thisC ].inflow_net++; - g->comp [otherC].inflow_net--; + g->comp[thisC].nMol++; + g->comp[otherC].nMol--; + g->comp[thisC].inflow_net++; + g->comp[otherC].inflow_net--; /* Correct the past time window to still get the right averages from now on */ - g->comp [thisC ].nMolAv++; - g->comp [otherC].nMolAv--; + g->comp[thisC].nMolAv++; + g->comp[otherC].nMolAv--; for (j = 0; j < sc->nAverage; j++) { - g->comp[thisC ].nMolPast[j]++; + g->comp[thisC].nMolPast[j]++; g->comp[otherC].nMolPast[j]--; } /* Clear ion history */ if (MASTER(cr)) { - int iMol = iion / g->apm; + int iMol = iion / g->apm; g->channel_label[iMol] = eChHistPassedNone; g->comp_from[iMol] = eDomainNotset; } @@ -2095,8 +2077,8 @@ gmx_bool do_swapcoords( if (nswaps && bVerbose) { - fprintf(stderr, "%s Performed %d swap%s in step %" PRId64 " for iontype %s.\n", - SwS, nswaps, nswaps > 1 ? "s" : "", step, g->molname); + fprintf(stderr, "%s Performed %d swap%s in step %" PRId64 " for iontype %s.\n", SwS, + nswaps, nswaps > 1 ? "s" : "", step, g->molname); } } @@ -2109,7 +2091,7 @@ gmx_bool do_swapcoords( * (possibly modified) local positions to the official position array. */ for (ig = eGrpSolvent; ig < s->ngrp; ig++) { - g = &s->group[ig]; + g = &s->group[ig]; apply_modified_positions(g, x); } diff --git a/src/gromacs/swap/swapcoords.h b/src/gromacs/swap/swapcoords.h index a2e8bb1b5f..913ef99b24 100644 --- a/src/gromacs/swap/swapcoords.h +++ b/src/gromacs/swap/swapcoords.h @@ -103,25 +103,24 @@ std::unique_ptr createSwapCoordinatesModule(); * \param[in] mdrunOptions Options for mdrun. * \param[in] startingBehavior Describes whether this is a restart appending to output files */ -t_swap *init_swapcoords( - FILE *fplog, - const t_inputrec *ir, - const char *fn, - gmx_mtop_t *mtop, - const t_state *globalState, - ObservablesHistory *oh, - t_commrec *cr, - gmx::LocalAtomSetManager *atomSets, - const gmx_output_env_t *oenv, - const gmx::MdrunOptions &mdrunOptions, - gmx::StartingBehavior startingBehavior); +t_swap* init_swapcoords(FILE* fplog, + const t_inputrec* ir, + const char* fn, + gmx_mtop_t* mtop, + const t_state* globalState, + ObservablesHistory* oh, + t_commrec* cr, + gmx::LocalAtomSetManager* atomSets, + const gmx_output_env_t* oenv, + const gmx::MdrunOptions& mdrunOptions, + gmx::StartingBehavior startingBehavior); /*! \brief Finalizes ion / water position swapping, if it was active. * * \param[in] s Pointer to swap data. */ -void finish_swapcoords(t_swap *s); +void finish_swapcoords(t_swap* s); /*! \brief "Computational Electrophysiology" main routine within MD loop. @@ -139,16 +138,15 @@ void finish_swapcoords(t_swap *s); * * \returns Whether at least one pair of molecules was swapped. */ -gmx_bool do_swapcoords( - t_commrec *cr, - int64_t step, - double t, - t_inputrec *ir, - t_swap *s, - gmx_wallcycle *wcycle, - rvec x[], - matrix box, - gmx_bool bVerbose, - gmx_bool bRerun); +gmx_bool do_swapcoords(t_commrec* cr, + int64_t step, + double t, + t_inputrec* ir, + t_swap* s, + gmx_wallcycle* wcycle, + rvec x[], + matrix box, + gmx_bool bVerbose, + gmx_bool bRerun); #endif diff --git a/src/gromacs/tables/cubicsplinetable.cpp b/src/gromacs/tables/cubicsplinetable.cpp index 5609052df9..9f0bf2b451 100644 --- a/src/gromacs/tables/cubicsplinetable.cpp +++ b/src/gromacs/tables/cubicsplinetable.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -78,21 +78,20 @@ namespace * \param G Component to multiply with eps^2 * \param H Component to multiply with eps^3 */ -void -calculateCubicSplineCoefficients(double functionValue0, - double functionValue1, - double derivativeValue0, - double derivativeValue1, - double spacing, - double *Y, - double *F, - double *G, - double *H) +void calculateCubicSplineCoefficients(double functionValue0, + double functionValue1, + double derivativeValue0, + double derivativeValue1, + double spacing, + double* Y, + double* F, + double* G, + double* H) { - *Y = functionValue0; - *F = spacing * derivativeValue0; - *G = 3.0*( functionValue1 - functionValue0) - spacing * (derivativeValue1 + 2.0 * derivativeValue0); - *H = -2.0*( functionValue1 - functionValue0) + spacing * (derivativeValue1 + derivativeValue0); + *Y = functionValue0; + *F = spacing * derivativeValue0; + *G = 3.0 * (functionValue1 - functionValue0) - spacing * (derivativeValue1 + 2.0 * derivativeValue0); + *H = -2.0 * (functionValue1 - functionValue0) + spacing * (derivativeValue1 + derivativeValue0); } /*! \brief Perform cubic spline interpolation in interval from function/derivative @@ -106,31 +105,27 @@ calculateCubicSplineCoefficients(double functionValue0, * \param[out] interpolatedFunctionValue Output function value * \param[out] interpolatedDerivativeValue Output derivative value */ -void -cubicSplineInterpolationFromFunctionAndDerivative(double functionValue0, - double functionValue1, - double derivativeValue0, - double derivativeValue1, - double spacing, - double eps, - double *interpolatedFunctionValue, - double *interpolatedDerivativeValue) +void cubicSplineInterpolationFromFunctionAndDerivative(double functionValue0, + double functionValue1, + double derivativeValue0, + double derivativeValue1, + double spacing, + double eps, + double* interpolatedFunctionValue, + double* interpolatedDerivativeValue) { double Y, F, G, H; - calculateCubicSplineCoefficients(functionValue0, functionValue1, - derivativeValue0, derivativeValue1, - spacing, - &Y, &F, &G, &H); + calculateCubicSplineCoefficients(functionValue0, functionValue1, derivativeValue0, + derivativeValue1, spacing, &Y, &F, &G, &H); double Fp = fma(fma(H, eps, G), eps, F); *interpolatedFunctionValue = fma(Fp, eps, Y); - *interpolatedDerivativeValue = fma(eps, fma(2.0*eps, H, G), Fp)/spacing; + *interpolatedDerivativeValue = fma(eps, fma(2.0 * eps, H, G), Fp) / spacing; } - /*! \brief Construct the data for a single cubic table from analytical functions * * \param[in] function Analytical functiojn @@ -139,24 +134,23 @@ cubicSplineInterpolationFromFunctionAndDerivative(double functionValue0, * \param[in] spacing Distance between table points * \param[out] yfghTableData Output cubic spline table with Y,F,G,H entries */ -void -fillSingleCubicSplineTableData(const std::function &function, - const std::function &derivative, - const std::pair &range, - double spacing, - std::vector *yfghTableData) +void fillSingleCubicSplineTableData(const std::function& function, + const std::function& derivative, + const std::pair& range, + double spacing, + std::vector* yfghTableData) { - int endIndex = static_cast(range.second / spacing + 2); + int endIndex = static_cast(range.second / spacing + 2); - yfghTableData->resize(4*endIndex); + yfghTableData->resize(4 * endIndex); - double maxMagnitude = 0.0001*GMX_REAL_MAX; - bool functionIsInRange = true; - std::size_t lastIndexInRange = endIndex - 1; + double maxMagnitude = 0.0001 * GMX_REAL_MAX; + bool functionIsInRange = true; + std::size_t lastIndexInRange = endIndex - 1; for (int i = endIndex - 1; i >= 0; i--) { - double x = i * spacing; + double x = i * spacing; double tmpFunctionValue; double tmpDerivativeValue; double nextHigherFunction; @@ -174,8 +168,8 @@ fillSingleCubicSplineTableData(const std::function &function, { tmpFunctionValue = function(x); tmpDerivativeValue = derivative(x); - nextHigherFunction = ((i+1) < endIndex) ? function(x+spacing) : 0.0; - nextHigherDerivative = ((i+1) < endIndex) ? derivative(x+spacing) : 0.0; + nextHigherFunction = ((i + 1) < endIndex) ? function(x + spacing) : 0.0; + nextHigherDerivative = ((i + 1) < endIndex) ? derivative(x + spacing) : 0.0; if (std::abs(tmpFunctionValue) > maxMagnitude || std::abs(tmpDerivativeValue) > maxMagnitude) { @@ -185,16 +179,14 @@ fillSingleCubicSplineTableData(const std::function &function, if (functionIsInRange) { - calculateCubicSplineCoefficients(tmpFunctionValue, nextHigherFunction, - tmpDerivativeValue, nextHigherDerivative, - spacing, - &Y, &F, &G, &H); + calculateCubicSplineCoefficients(tmpFunctionValue, nextHigherFunction, tmpDerivativeValue, + nextHigherDerivative, spacing, &Y, &F, &G, &H); lastIndexInRange--; } else { - double lastIndexY = (*yfghTableData)[4*lastIndexInRange]; - double lastIndexF = (*yfghTableData)[4*lastIndexInRange + 1]; + double lastIndexY = (*yfghTableData)[4 * lastIndexInRange]; + double lastIndexF = (*yfghTableData)[4 * lastIndexInRange + 1]; Y = lastIndexY + lastIndexF * (i - lastIndexInRange); F = lastIndexF; @@ -202,10 +194,10 @@ fillSingleCubicSplineTableData(const std::function &function, H = 0.0; } - (*yfghTableData)[4*i ] = Y; - (*yfghTableData)[4*i+1] = F; - (*yfghTableData)[4*i+2] = G; - (*yfghTableData)[4*i+3] = H; + (*yfghTableData)[4 * i] = Y; + (*yfghTableData)[4 * i + 1] = F; + (*yfghTableData)[4 * i + 2] = G; + (*yfghTableData)[4 * i + 3] = H; } } @@ -219,22 +211,21 @@ fillSingleCubicSplineTableData(const std::function &function, * \param[in] spacing Distance between table points * \param[out] yfghTableData Output cubic spline table with Y,F,G,H entries */ -void -fillSingleCubicSplineTableData(ArrayRef function, - ArrayRef derivative, - double inputSpacing, - const std::pair &range, - double spacing, - std::vector *yfghTableData) +void fillSingleCubicSplineTableData(ArrayRef function, + ArrayRef derivative, + double inputSpacing, + const std::pair& range, + double spacing, + std::vector* yfghTableData) { - int endIndex = static_cast(range.second / spacing + 2); + int endIndex = static_cast(range.second / spacing + 2); std::vector tmpFunction(endIndex); std::vector tmpDerivative(endIndex); - double maxMagnitude = 0.0001*GMX_REAL_MAX; - bool functionIsInRange = true; - std::size_t lastIndexInRange = endIndex - 1; + double maxMagnitude = 0.0001 * GMX_REAL_MAX; + bool functionIsInRange = true; + std::size_t lastIndexInRange = endIndex - 1; // Interpolate function and derivative values in positions needed for output for (int i = endIndex - 1; i >= 0; i--) @@ -251,74 +242,66 @@ fillSingleCubicSplineTableData(ArrayRef function, functionIsInRange = false; } - if (functionIsInRange && (std::abs(function[index]) > maxMagnitude || std::abs(derivative[index]) > maxMagnitude)) + if (functionIsInRange + && (std::abs(function[index]) > maxMagnitude || std::abs(derivative[index]) > maxMagnitude)) { functionIsInRange = false; // Once this happens, it never resets to true again } if (functionIsInRange) { - cubicSplineInterpolationFromFunctionAndDerivative(function[index], - function[index+1], - derivative[index], - derivative[index+1], - inputSpacing, - eps, - &(tmpFunction[i]), - &(tmpDerivative[i])); + cubicSplineInterpolationFromFunctionAndDerivative( + function[index], function[index + 1], derivative[index], derivative[index + 1], + inputSpacing, eps, &(tmpFunction[i]), &(tmpDerivative[i])); lastIndexInRange--; } else { double lastIndexFunction = tmpFunction[lastIndexInRange]; double lastIndexDerivative = tmpDerivative[lastIndexInRange]; - tmpFunction[i] = lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; - tmpDerivative[i] = lastIndexDerivative; + tmpFunction[i] = lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; + tmpDerivative[i] = lastIndexDerivative; } } - yfghTableData->resize(4*endIndex); + yfghTableData->resize(4 * endIndex); for (int i = 0; i < endIndex; i++) { double Y, F, G, H; - double nextFunction = ((i+1) < endIndex) ? tmpFunction[i+1] : 0.0; - double nextDerivative = ((i+1) < endIndex) ? tmpDerivative[i+1] : 0.0; - - calculateCubicSplineCoefficients(tmpFunction[i], nextFunction, - tmpDerivative[i], nextDerivative, - spacing, - &Y, &F, &G, &H); - (*yfghTableData)[4*i ] = Y; - (*yfghTableData)[4*i+1] = F; - (*yfghTableData)[4*i+2] = G; - (*yfghTableData)[4*i+3] = H; - } + double nextFunction = ((i + 1) < endIndex) ? tmpFunction[i + 1] : 0.0; + double nextDerivative = ((i + 1) < endIndex) ? tmpDerivative[i + 1] : 0.0; + calculateCubicSplineCoefficients(tmpFunction[i], nextFunction, tmpDerivative[i], + nextDerivative, spacing, &Y, &F, &G, &H); + (*yfghTableData)[4 * i] = Y; + (*yfghTableData)[4 * i + 1] = F; + (*yfghTableData)[4 * i + 2] = G; + (*yfghTableData)[4 * i + 3] = H; + } } -} // namespace - +} // namespace #if GMX_DOUBLE -const real -CubicSplineTable::defaultTolerance = 1e-10; +const real CubicSplineTable::defaultTolerance = 1e-10; #else -const real -CubicSplineTable::defaultTolerance = 10.0 * GMX_FLOAT_EPS; +const real CubicSplineTable::defaultTolerance = 10.0 * GMX_FLOAT_EPS; #endif -CubicSplineTable::CubicSplineTable(std::initializer_list analyticalInputList, - const std::pair &range, - real tolerance) - : numFuncInTable_(analyticalInputList.size()), range_(range) +CubicSplineTable::CubicSplineTable(std::initializer_list analyticalInputList, + const std::pair& range, + real tolerance) : + numFuncInTable_(analyticalInputList.size()), + range_(range) { // Sanity check on input values - if (range_.first < 0.0 || (range_.second-range_.first) < 0.001) + if (range_.first < 0.0 || (range_.second - range_.first) < 0.001) { - GMX_THROW(InvalidInputError("Range to tabulate cannot include negative values and must span at least 0.001")); + GMX_THROW(InvalidInputError( + "Range to tabulate cannot include negative values and must span at least 0.001")); } if (tolerance < GMX_REAL_EPS) @@ -329,38 +312,43 @@ CubicSplineTable::CubicSplineTable(std::initializer_list 2e6) { - GMX_THROW(ToleranceError("Over a million points would be required for table; decrease range or increase tolerance")); + GMX_THROW( + ToleranceError("Over a million points would be required for table; decrease range " + "or increase tolerance")); } // Loop over all tables again. @@ -368,41 +356,41 @@ CubicSplineTable::CubicSplineTable(std::initializer_list tmpYfghTableData; - fillSingleCubicSplineTableData(thisFuncInput.function, - thisFuncInput.derivative, - range_, - spacing, - &tmpYfghTableData); + fillSingleCubicSplineTableData(thisFuncInput.function, thisFuncInput.derivative, range_, + spacing, &tmpYfghTableData); - internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, - 4, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, 4, + numFuncInTable_, funcIndex); funcIndex++; } - catch (gmx::GromacsException &ex) + catch (gmx::GromacsException& ex) { - ex.prependContext("Error generating cubic spline table for function '" + thisFuncInput.desc + "'"); + ex.prependContext("Error generating cubic spline table for function '" + + thisFuncInput.desc + "'"); throw; } } } -CubicSplineTable::CubicSplineTable(std::initializer_list numericalInputList, - const std::pair &range, - real tolerance) - : numFuncInTable_(numericalInputList.size()), range_(range) +CubicSplineTable::CubicSplineTable(std::initializer_list numericalInputList, + const std::pair& range, + real tolerance) : + numFuncInTable_(numericalInputList.size()), + range_(range) { // Sanity check on input values - if (range.first < 0.0 || (range.second-range.first) < 0.001) + if (range.first < 0.0 || (range.second - range.first) < 0.001) { - GMX_THROW(InvalidInputError("Range to tabulate cannot include negative values and must span at least 0.001")); + GMX_THROW(InvalidInputError( + "Range to tabulate cannot include negative values and must span at least 0.001")); } if (tolerance < GMX_REAL_EPS) @@ -421,19 +409,24 @@ CubicSplineTable::CubicSplineTable(std::initializer_list 1e6) { - GMX_THROW(ToleranceError("Requested tolerance would require over a million points in table")); + GMX_THROW( + ToleranceError("Requested tolerance would require over a million points in table")); } // Loop over all tables again. @@ -466,26 +461,24 @@ CubicSplineTable::CubicSplineTable(std::initializer_list tmpYfghTableData; - fillSingleCubicSplineTableData(thisFuncInput.function, - thisFuncInput.derivative, - thisFuncInput.spacing, - range, - spacing, - &tmpYfghTableData); + fillSingleCubicSplineTableData(thisFuncInput.function, thisFuncInput.derivative, + thisFuncInput.spacing, range, spacing, &tmpYfghTableData); - internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, - 4, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpYfghTableData, &yfghMultiTableData_, 4, + numFuncInTable_, funcIndex); funcIndex++; } - catch (gmx::GromacsException &ex) + catch (gmx::GromacsException& ex) { - ex.prependContext("Error generating cubic spline table for function '" + thisFuncInput.desc + "'"); + ex.prependContext("Error generating cubic spline table for function '" + + thisFuncInput.desc + "'"); throw; } } diff --git a/src/gromacs/tables/cubicsplinetable.h b/src/gromacs/tables/cubicsplinetable.h index 72e4c6399d..268a19faf1 100644 --- a/src/gromacs/tables/cubicsplinetable.h +++ b/src/gromacs/tables/cubicsplinetable.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -130,515 +130,510 @@ namespace gmx */ class CubicSplineTable { - private: - /*! \brief Change that function value falls inside range when debugging - * - * \tparam T Lookup argument floating-point type, typically SimdReal or real. - * \param r Lookup argument to test - * - * \throws Debug builds will throw gmx::RangeError for values that are - * larger than the upper limit of the range, or smaller than 0. - * We allow the table to be called with arguments between 0 and - * the lower limit of the range, since this might in theory occur - * once-in-a-blue-moon with some algorithms. - */ - template - void - rangeCheck(T gmx_unused r) const - { +private: + /*! \brief Change that function value falls inside range when debugging + * + * \tparam T Lookup argument floating-point type, typically SimdReal or real. + * \param r Lookup argument to test + * + * \throws Debug builds will throw gmx::RangeError for values that are + * larger than the upper limit of the range, or smaller than 0. + * We allow the table to be called with arguments between 0 and + * the lower limit of the range, since this might in theory occur + * once-in-a-blue-moon with some algorithms. + */ + template + void rangeCheck(T gmx_unused r) const + { #ifndef NDEBUG - // Check that all values fall in range when debugging - if (anyTrue( r < T(0.0) || T(range_.second) <= r ) ) - { - GMX_THROW(RangeError("Interpolation input value falls outside table definition range")); - } -#endif - } - - public: - - /*! \brief Default tolerance for cubic spline tables - * - * This is 10*GMX_FLOAT_EPS in single precision, and - * 1e-10 for double precision. It might not be worth setting - * this tolerance lower than 1e-10 in double precision, both because - * you will end up with very large tables, and because - * functions like r^-12 become so large for small values of r the - * table generation code will lead to some precision loss even - * in double precision. - */ - static const real defaultTolerance; - - /*! \brief Initialize table data from function - * - * \param analyticalInputList Initializer list with one or more functions to tabulate, - * specified as elements with a string description and - * the function as well as derivative. The function will also - * be called for values smaller than the lower limit of the - * range, but we avoid calling it for 0.0 if that value - * is not included in the range. - * Constructor will throw gmx::APIError for negative values. - * Due to the way the numerical derivative evaluation depends - * on machine precision internally, this range must be - * at least 0.001, or the constructor throws gmx::APIError. - * \param range Range over which the function will be tabulated. - * Constructor will throw gmx::APIError for negative values, - * or if the value/derivative vector does not cover the - * range. - * \param tolerance Requested accuracy of the table. This will be used to - * calculate the required internal spacing. If this cannot - * be achieved (for instance because the table would require - * too much memory) the constructor will throw gmx::ToleranceError. - * - * \note The functions are always defined in double precision to avoid - * losing accuracy when constructing tables. - * - * \note Since we fill the table for values below range.first, you can achieve - * a smaller table by using a smaller range where the tolerance has to be - * met, and accept that a few function calls below range.first do not - * quite reach the tolerance. - * - * \warning For efficiency reasons (since this code is used in some inner - * (kernels), we always allocate memory and calculate table indices - * for the complete interval [0,range.second], although the data will - * not be valid outside the definition range to avoid calling the - * function there. This means you should \a not use this class - * to tabulate functions for small ranges very far away from zero, - * since you would both waste a huge amount of memory and incur - * truncation errors when calculating the index. - * - * \throws gmx::ToleranceError if the requested tolerance cannot be achieved, - * and gmx::APIError for other incorrect input. - */ - CubicSplineTable(std::initializer_list analyticalInputList, - const std::pair &range, - real tolerance = defaultTolerance); - - /*! \brief Initialize table data from tabulated values and derivatives - * - * \param numericalInputList Initializer list with one or more functions to tabulate, - * specified as a string description, vectors with function and - * derivative values, and the input spacing. Data points are - * separated by the spacing parameter, starting from 0. - * Values below the lower limit of the range will be used to - * attempt defining the table, but we avoid using index 0 - * unless 0.0 is included in the range. Some extra points beyond - * range.second are required to re-interpolate values, so add - * some margin. The constructor will throw gmx::APIError if the - * input vectors are too short to cover the requested range - * (and they must always be at least five points). - * \param range Range over which the function will be tabulated. - * Constructor will throw gmx::APIError for negative values, - * or if the value/derivative vector does not cover the - * range. - * \param tolerance Requested accuracy of the table. This will be used to - * calculate the required internal spacing and possibly - * re-interpolate. The constructor will throw - * gmx::ToleranceError if the input spacing is too coarse - * to achieve this accuracy. - * - * \note The input data vectors are always double precision to avoid - * losing accuracy when constructing tables. - * - * \note Since we fill the table for values below range.first, you can achieve - * a smaller table by using a smaller range where the tolerance has to be - * met, and accept that a few function calls below range.first do not - * quite reach the tolerance. - * - * \warning For efficiency reasons (since this code is used in some inner - * (kernels), we always allocate memory and calculate table indices - * for the complete interval [0,range.second], although the data will - * not be valid outside the definition range to avoid calling the - * function there. This means you should \a not use this class - * to tabulate functions for small ranges very far away from zero, - * since you would both waste a huge amount of memory and incur - * truncation errors when calculating the index. - */ - CubicSplineTable(std::initializer_list numericalInputList, - const std::pair &range, - real tolerance = defaultTolerance); - - - /************************************************************ - * Evaluation methods for single functions * - ************************************************************/ - - /*! \brief Evaluate both function and derivative, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue Function value - * \param[out] derivativeValue Function derivative - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue, - T * derivativeValue) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex, tabIndex, &Y, &F, &G, &H); - *functionValue = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /*! \brief Evaluate function value only, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue Function value - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue) const + // Check that all values fall in range when debugging + if (anyTrue(r < T(0.0) || T(range_.second) <= r)) { - T der gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue, &der); + GMX_THROW(RangeError("Interpolation input value falls outside table definition range")); } - - /*! \brief Evaluate function derivative only, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue Function derivative - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex, tabIndex, &Y, &F, &G, &H); - *derivativeValue = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /************************************************************ - * Evaluation methods for two functions * - ************************************************************/ - - /*! \brief Evaluate both function and derivative, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue0 Interpolated value for first function - * \param[out] derivativeValue0 Interpolated derivative for first function - * \param[out] functionValue1 Interpolated value for second function - * \param[out] derivativeValue1 Interpolated derivative for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue0, - T * derivativeValue0, - T * functionValue1, - T * derivativeValue1) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex0, tabIndex, &Y, &F, &G, &H); - *functionValue0 = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue0 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex1, tabIndex, &Y, &F, &G, &H); - *functionValue1 = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue1 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /*! \brief Evaluate function value only, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue0 Interpolated value for first function - * \param[out] functionValue1 Interpolated value for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue0, - T * functionValue1) const - { - T der0 gmx_unused; - T der1 gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue0, &der0, functionValue1, &der1); - } - - /*! \brief Evaluate function derivative only, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue0 Interpolated derivative for first function - * \param[out] derivativeValue1 Interpolated derivative for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue0, - T * derivativeValue1) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); - *derivativeValue0 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); - *derivativeValue1 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /************************************************************ - * Evaluation methods for three functions * - ************************************************************/ - - - /*! \brief Evaluate both function and derivative, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue0 Interpolated value for first function - * \param[out] derivativeValue0 Interpolated derivative for first function - * \param[out] functionValue1 Interpolated value for second function - * \param[out] derivativeValue1 Interpolated derivative for second function - * \param[out] functionValue2 Interpolated value for third function - * \param[out] derivativeValue2 Interpolated derivative for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue0, - T * derivativeValue0, - T * functionValue1, - T * derivativeValue1, - T * functionValue2, - T * derivativeValue2) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex0, tabIndex, &Y, &F, &G, &H); - *functionValue0 = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue0 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex1, tabIndex, &Y, &F, &G, &H); - *functionValue1 = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue1 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4*funcIndex2, tabIndex, &Y, &F, &G, &H); - *functionValue2 = fma(fma(fma(H, eps, G), eps, F), eps, Y); - *derivativeValue2 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /*! \brief Evaluate function value only, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue0 Interpolated value for first function - * \param[out] functionValue1 Interpolated value for second function - * \param[out] functionValue2 Interpolated value for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue0, - T * functionValue1, - T * functionValue2) const - { - T der0 gmx_unused; - T der1 gmx_unused; - T der2 gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue0, &der0, functionValue1, &der1, functionValue2, &der2); - } - - /*! \brief Evaluate function derivative only, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue0 Interpolated derivative for first function - * \param[out] derivativeValue1 Interpolated derivative for second function - * \param[out] derivativeValue2 Interpolated derivative for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue0, - T * derivativeValue1, - T * derivativeValue2) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T Y, F, G, H; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); - *derivativeValue0 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); - *derivativeValue1 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex2, tabIndex, &Y, &F, &G, &H); - *derivativeValue2 = tableScale_ * fma(fma(T(3.0)*H, eps, T(2.0)*G), eps, F); - } - - /*! \brief Return the table spacing (distance between points) - * - * You should never have to use this for normal code, but due to the - * way tables are constructed internally we need this in the unit tests - * to check relative tolerances over each interval. - * - * \return table spacing. - */ - real - tableSpacing() const { return 1.0 / tableScale_; } - - private: - - std::size_t numFuncInTable_; //!< Number of separate tabluated functions - std::pair range_; //!< Range for which table evaluation is allowed - real tableScale_; //!< Table scale (inverse of spacing between points) - - /*! \brief Vector with combined table data to save calculations after lookup. - * - * For table point i, this vector contains the four coefficients - * Y,F,G,H that we use to express the function value as - * V(x) = Y + F e + G e^2 + H e^3, where e is the epsilon offset from - * the nearest table point. - * - * To allow aligned SIMD loads we need to use an aligned allocator for - * this container. - */ - std::vector > yfghMultiTableData_; - - // There should never be any reason to copy the table since it is read-only - GMX_DISALLOW_COPY_AND_ASSIGN(CubicSplineTable); +#endif + } + +public: + /*! \brief Default tolerance for cubic spline tables + * + * This is 10*GMX_FLOAT_EPS in single precision, and + * 1e-10 for double precision. It might not be worth setting + * this tolerance lower than 1e-10 in double precision, both because + * you will end up with very large tables, and because + * functions like r^-12 become so large for small values of r the + * table generation code will lead to some precision loss even + * in double precision. + */ + static const real defaultTolerance; + + /*! \brief Initialize table data from function + * + * \param analyticalInputList Initializer list with one or more functions to tabulate, + * specified as elements with a string description and + * the function as well as derivative. The function will also + * be called for values smaller than the lower limit of the + * range, but we avoid calling it for 0.0 if that value + * is not included in the range. + * Constructor will throw gmx::APIError for negative values. + * Due to the way the numerical derivative evaluation depends + * on machine precision internally, this range must be + * at least 0.001, or the constructor throws gmx::APIError. + * \param range Range over which the function will be tabulated. + * Constructor will throw gmx::APIError for negative values, + * or if the value/derivative vector does not cover the + * range. + * \param tolerance Requested accuracy of the table. This will be used to + * calculate the required internal spacing. If this cannot + * be achieved (for instance because the table would require + * too much memory) the constructor will throw gmx::ToleranceError. + * + * \note The functions are always defined in double precision to avoid + * losing accuracy when constructing tables. + * + * \note Since we fill the table for values below range.first, you can achieve + * a smaller table by using a smaller range where the tolerance has to be + * met, and accept that a few function calls below range.first do not + * quite reach the tolerance. + * + * \warning For efficiency reasons (since this code is used in some inner + * (kernels), we always allocate memory and calculate table indices + * for the complete interval [0,range.second], although the data will + * not be valid outside the definition range to avoid calling the + * function there. This means you should \a not use this class + * to tabulate functions for small ranges very far away from zero, + * since you would both waste a huge amount of memory and incur + * truncation errors when calculating the index. + * + * \throws gmx::ToleranceError if the requested tolerance cannot be achieved, + * and gmx::APIError for other incorrect input. + */ + CubicSplineTable(std::initializer_list analyticalInputList, + const std::pair& range, + real tolerance = defaultTolerance); + + /*! \brief Initialize table data from tabulated values and derivatives + * + * \param numericalInputList Initializer list with one or more functions to tabulate, + * specified as a string description, vectors with function and + * derivative values, and the input spacing. Data points are + * separated by the spacing parameter, starting from 0. + * Values below the lower limit of the range will be used to + * attempt defining the table, but we avoid using index 0 + * unless 0.0 is included in the range. Some extra points beyond + * range.second are required to re-interpolate values, so add + * some margin. The constructor will throw gmx::APIError if the + * input vectors are too short to cover the requested range + * (and they must always be at least five points). + * \param range Range over which the function will be tabulated. + * Constructor will throw gmx::APIError for negative values, + * or if the value/derivative vector does not cover the + * range. + * \param tolerance Requested accuracy of the table. This will be used to + * calculate the required internal spacing and possibly + * re-interpolate. The constructor will throw + * gmx::ToleranceError if the input spacing is too coarse + * to achieve this accuracy. + * + * \note The input data vectors are always double precision to avoid + * losing accuracy when constructing tables. + * + * \note Since we fill the table for values below range.first, you can achieve + * a smaller table by using a smaller range where the tolerance has to be + * met, and accept that a few function calls below range.first do not + * quite reach the tolerance. + * + * \warning For efficiency reasons (since this code is used in some inner + * (kernels), we always allocate memory and calculate table indices + * for the complete interval [0,range.second], although the data will + * not be valid outside the definition range to avoid calling the + * function there. This means you should \a not use this class + * to tabulate functions for small ranges very far away from zero, + * since you would both waste a huge amount of memory and incur + * truncation errors when calculating the index. + */ + CubicSplineTable(std::initializer_list numericalInputList, + const std::pair& range, + real tolerance = defaultTolerance); + + + /************************************************************ + * Evaluation methods for single functions * + ************************************************************/ + + /*! \brief Evaluate both function and derivative, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue Function value + * \param[out] derivativeValue Function derivative + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, T* functionValue, T* derivativeValue) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex, + tabIndex, &Y, &F, &G, &H); + *functionValue = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /*! \brief Evaluate function value only, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue Function value + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue) const + { + T der gmx_unused; + + evaluateFunctionAndDerivative(r, functionValue, &der); + } + + /*! \brief Evaluate function derivative only, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue Function derivative + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>(yfghMultiTableData_.data() + 4 * funcIndex, + tabIndex, &Y, &F, &G, &H); + *derivativeValue = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /************************************************************ + * Evaluation methods for two functions * + ************************************************************/ + + /*! \brief Evaluate both function and derivative, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue0 Interpolated value for first function + * \param[out] derivativeValue0 Interpolated derivative for first function + * \param[out] functionValue1 Interpolated value for second function + * \param[out] derivativeValue1 Interpolated derivative for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, T* functionValue0, T* derivativeValue0, T* functionValue1, T* derivativeValue1) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); + *functionValue0 = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue0 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); + *functionValue1 = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue1 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /*! \brief Evaluate function value only, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue0 Interpolated value for first function + * \param[out] functionValue1 Interpolated value for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue0, T* functionValue1) const + { + T der0 gmx_unused; + T der1 gmx_unused; + + evaluateFunctionAndDerivative( + r, functionValue0, &der0, functionValue1, &der1); + } + + /*! \brief Evaluate function derivative only, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue0 Interpolated derivative for first function + * \param[out] derivativeValue1 Interpolated derivative for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue0, T* derivativeValue1) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); + *derivativeValue0 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); + *derivativeValue1 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /************************************************************ + * Evaluation methods for three functions * + ************************************************************/ + + + /*! \brief Evaluate both function and derivative, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue0 Interpolated value for first function + * \param[out] derivativeValue0 Interpolated derivative for first function + * \param[out] functionValue1 Interpolated value for second function + * \param[out] derivativeValue1 Interpolated derivative for second function + * \param[out] functionValue2 Interpolated value for third function + * \param[out] derivativeValue2 Interpolated derivative for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, + T* functionValue0, + T* derivativeValue0, + T* functionValue1, + T* derivativeValue1, + T* functionValue2, + T* derivativeValue2) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); + *functionValue0 = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue0 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); + *functionValue1 = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue1 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex2, tabIndex, &Y, &F, &G, &H); + *functionValue2 = fma(fma(fma(H, eps, G), eps, F), eps, Y); + *derivativeValue2 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /*! \brief Evaluate function value only, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue0 Interpolated value for first function + * \param[out] functionValue1 Interpolated value for second function + * \param[out] functionValue2 Interpolated value for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue0, T* functionValue1, T* functionValue2) const + { + T der0 gmx_unused; + T der1 gmx_unused; + T der2 gmx_unused; + + evaluateFunctionAndDerivative( + r, functionValue0, &der0, functionValue1, &der1, functionValue2, &der2); + } + + /*! \brief Evaluate function derivative only, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue0 Interpolated derivative for first function + * \param[out] derivativeValue1 Interpolated derivative for second function + * \param[out] derivativeValue2 Interpolated derivative for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue0, T* derivativeValue1, T* derivativeValue2) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T Y, F, G, H; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex0, tabIndex, &Y, &F, &G, &H); + *derivativeValue0 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex1, tabIndex, &Y, &F, &G, &H); + *derivativeValue1 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + yfghMultiTableData_.data() + 4 * funcIndex2, tabIndex, &Y, &F, &G, &H); + *derivativeValue2 = tableScale_ * fma(fma(T(3.0) * H, eps, T(2.0) * G), eps, F); + } + + /*! \brief Return the table spacing (distance between points) + * + * You should never have to use this for normal code, but due to the + * way tables are constructed internally we need this in the unit tests + * to check relative tolerances over each interval. + * + * \return table spacing. + */ + real tableSpacing() const { return 1.0 / tableScale_; } + +private: + std::size_t numFuncInTable_; //!< Number of separate tabluated functions + std::pair range_; //!< Range for which table evaluation is allowed + real tableScale_; //!< Table scale (inverse of spacing between points) + + /*! \brief Vector with combined table data to save calculations after lookup. + * + * For table point i, this vector contains the four coefficients + * Y,F,G,H that we use to express the function value as + * V(x) = Y + F e + G e^2 + H e^3, where e is the epsilon offset from + * the nearest table point. + * + * To allow aligned SIMD loads we need to use an aligned allocator for + * this container. + */ + std::vector> yfghMultiTableData_; + + // There should never be any reason to copy the table since it is read-only + GMX_DISALLOW_COPY_AND_ASSIGN(CubicSplineTable); }; -} // namespace gmx +} // namespace gmx #endif // GMX_TABLES_CUBICSPLINETABLE_H diff --git a/src/gromacs/tables/forcetable.cpp b/src/gromacs/tables/forcetable.cpp index 7e10798ee3..f668513366 100644 --- a/src/gromacs/tables/forcetable.cpp +++ b/src/gromacs/tables/forcetable.cpp @@ -57,7 +57,8 @@ #include "gromacs/utility/smalloc.h" /* All the possible (implemented) table functions */ -enum { +enum +{ etabLJ6, etabLJ12, etabLJ6Shift, @@ -83,18 +84,18 @@ enum { }; /** Evaluates to true if the table type contains user data. */ -#define ETAB_USER(e) ((e) == etabUSER || \ - (e) == etabEwaldUser || (e) == etabEwaldUserSwitch) +#define ETAB_USER(e) ((e) == etabUSER || (e) == etabEwaldUser || (e) == etabEwaldUserSwitch) -typedef struct { - const char *name; +typedef struct +{ + const char* name; gmx_bool bCoulomb; } t_tab_props; /* This structure holds name and a flag that tells whether this is a Coulomb type funtion */ static const t_tab_props tprops[etabNR] = { - { "LJ6", FALSE }, + { "LJ6", FALSE }, { "LJ12", FALSE }, { "LJ6Shift", FALSE }, { "LJ12Shift", FALSE }, @@ -112,12 +113,13 @@ static const t_tab_props tprops[etabNR] = { { "COULSwitch", TRUE }, { "LJ6-Encad shift", FALSE }, { "LJ12-Encad shift", FALSE }, - { "COUL-Encad shift", TRUE }, + { "COUL-Encad shift", TRUE }, { "EXPMIN", FALSE }, { "USER", FALSE }, }; -typedef struct { +typedef struct +{ int nx, nx0; double tabscale; double *x, *v, *f; @@ -127,11 +129,11 @@ double v_q_ewald_lr(double beta, double r) { if (r == 0) { - return beta*2/sqrt(M_PI); + return beta * 2 / sqrt(M_PI); } else { - return std::erf(beta*r)/r; + return std::erf(beta * r) / r; } } @@ -140,24 +142,23 @@ double v_lj_ewald_lr(double beta, double r) double br, br2, br4, r6, factor; if (r == 0) { - return gmx::power6(beta)/6; + return gmx::power6(beta) / 6; } else { - br = beta*r; - br2 = br*br; - br4 = br2*br2; + br = beta * r; + br2 = br * br; + br4 = br2 * br2; r6 = gmx::power6(r); - factor = (1.0 - std::exp(-br2)*(1 + br2 + 0.5*br4))/r6; + factor = (1.0 - std::exp(-br2) * (1 + br2 + 0.5 * br4)) / r6; return factor; } } -EwaldCorrectionTables -generateEwaldCorrectionTables(const int numPoints, - const double tableScaling, - const real beta, - real_space_grid_contribution_computer v_lr) +EwaldCorrectionTables generateEwaldCorrectionTables(const int numPoints, + const double tableScaling, + const real beta, + real_space_grid_contribution_computer v_lr) { real tab_max; int i, i_inrange; @@ -175,13 +176,13 @@ generateEwaldCorrectionTables(const int numPoints, gmx_fatal(FARGS, "Can not make a spline table with less than 2 points"); } - const double dx = 1/tableScaling; + const double dx = 1 / tableScaling; EwaldCorrectionTables tables; tables.scale = tableScaling; tables.tableF.resize(numPoints); tables.tableV.resize(numPoints); - tables.tableFDV0.resize(numPoints*4); + tables.tableFDV0.resize(numPoints * 4); gmx::ArrayRef table_f = tables.tableF; gmx::ArrayRef table_v = tables.tableV; gmx::ArrayRef table_fdv0 = tables.tableFDV0; @@ -190,7 +191,7 @@ generateEwaldCorrectionTables(const int numPoints, * in the kernel and also to do the integration arithmetics * without going out of range. Furthemore, we divide by dx below. */ - tab_max = GMX_REAL_MAX*0.0001; + tab_max = GMX_REAL_MAX * 0.0001; /* This function produces a table with: * maximum energy error: V'''/(6*12*sqrt(3))*dx^3 @@ -204,7 +205,7 @@ generateEwaldCorrectionTables(const int numPoints, dc = 0; for (i = numPoints - 1; i >= 0; i--) { - x_r0 = i*dx; + x_r0 = i * dx; v_r0 = (*v_lr)(beta, x_r0); @@ -218,7 +219,7 @@ generateEwaldCorrectionTables(const int numPoints, else { /* Linear continuation for the last point in range */ - vi = v_inrange - dc*(i - i_inrange)*dx; + vi = v_inrange - dc * (i - i_inrange) * dx; } table_v[i] = vi; @@ -229,7 +230,7 @@ generateEwaldCorrectionTables(const int numPoints, } /* Get the potential at table point i-1 */ - v_r1 = (*v_lr)(beta, (i-1)*dx); + v_r1 = (*v_lr)(beta, (i - 1) * dx); if (v_r1 != v_r1 || v_r1 < -tab_max || v_r1 > tab_max) { @@ -241,12 +242,12 @@ generateEwaldCorrectionTables(const int numPoints, /* Calculate the average second derivative times dx over interval i-1 to i. * Using the function values at the end points and in the middle. */ - a2dx = (v_r0 + v_r1 - 2*(*v_lr)(beta, x_r0-0.5*dx))/(0.25*dx); + a2dx = (v_r0 + v_r1 - 2 * (*v_lr)(beta, x_r0 - 0.5 * dx)) / (0.25 * dx); /* Set the derivative of the spline to match the difference in potential * over the interval plus the average effect of the quadratic term. * This is the essential step for minimizing the error in the force. */ - dc = (v_r0 - v_r1)/dx + 0.5*a2dx; + dc = (v_r0 - v_r1) / dx + 0.5 * a2dx; } if (i == numPoints - 1) @@ -257,7 +258,7 @@ generateEwaldCorrectionTables(const int numPoints, else { /* tab[i] will contain the average of the splines over the two intervals */ - table_f[i] += -0.5*dc; + table_f[i] += -0.5 * dc; } if (!bOutOfRange) @@ -268,7 +269,7 @@ generateEwaldCorrectionTables(const int numPoints, */ a0 = v_r0; a1 = dc; - a2dx = (a1*dx + v_r1 - a0)*2/dx; + a2dx = (a1 * dx + v_r1 - a0) * 2 / dx; /* Set dc to the derivative at the next point */ dc_new = a1 - a2dx; @@ -283,7 +284,7 @@ generateEwaldCorrectionTables(const int numPoints, } } - table_f[(i-1)] = -0.5*dc; + table_f[(i - 1)] = -0.5 * dc; } /* Currently the last value only contains half the force: double it */ table_f[0] *= 2; @@ -295,16 +296,16 @@ generateEwaldCorrectionTables(const int numPoints, */ for (i = 0; i < numPoints - 1; i++) { - table_fdv0[4*i] = table_f[i]; - table_fdv0[4*i+1] = table_f[i+1]-table_f[i]; - table_fdv0[4*i+2] = table_v[i]; - table_fdv0[4*i+3] = 0.0; + table_fdv0[4 * i] = table_f[i]; + table_fdv0[4 * i + 1] = table_f[i + 1] - table_f[i]; + table_fdv0[4 * i + 2] = table_v[i]; + table_fdv0[4 * i + 3] = 0.0; } - const int lastPoint = numPoints - 1; - table_fdv0[4*lastPoint] = table_f[lastPoint]; - table_fdv0[4*lastPoint+1] = -table_f[lastPoint]; - table_fdv0[4*lastPoint+2] = table_v[lastPoint]; - table_fdv0[4*lastPoint+3] = 0.0; + const int lastPoint = numPoints - 1; + table_fdv0[4 * lastPoint] = table_f[lastPoint]; + table_fdv0[4 * lastPoint + 1] = -table_f[lastPoint]; + table_fdv0[4 * lastPoint + 2] = table_v[lastPoint]; + table_fdv0[4 * lastPoint + 3] = 0.0; } return tables; @@ -314,20 +315,18 @@ generateEwaldCorrectionTables(const int numPoints, * the third derivative, x_scale (unit 1/length) * and function tolerance. */ -static double spline3_table_scale(double third_deriv_max, - double x_scale, - double func_tol) +static double spline3_table_scale(double third_deriv_max, double x_scale, double func_tol) { double deriv_tol; double sc_deriv, sc_func; /* Force tolerance: single precision accuracy */ deriv_tol = GMX_FLOAT_EPS; - sc_deriv = sqrt(third_deriv_max/(6*4*deriv_tol*x_scale))*x_scale; + sc_deriv = sqrt(third_deriv_max / (6 * 4 * deriv_tol * x_scale)) * x_scale; /* Don't try to be more accurate on energy than the precision */ - func_tol = std::max(func_tol, static_cast(GMX_REAL_EPS)); - sc_func = std::cbrt(third_deriv_max/(6*12*std::sqrt(3.0)*func_tol))*x_scale; + func_tol = std::max(func_tol, static_cast(GMX_REAL_EPS)); + sc_func = std::cbrt(third_deriv_max / (6 * 12 * std::sqrt(3.0) * func_tol)) * x_scale; return std::max(sc_deriv, sc_func); } @@ -344,12 +343,14 @@ static double spline3_table_scale(double third_deriv_max, * faster kernels with both Coulomb and LJ Ewald, especially * when interleaving both tables (currently not implemented). */ -real ewald_spline3_table_scale(const interaction_const_t &ic, +real ewald_spline3_table_scale(const interaction_const_t& ic, const bool generateCoulombTables, const bool generateVdwTables) { - GMX_RELEASE_ASSERT(!generateCoulombTables || EEL_PME_EWALD(ic.eeltype), "Can only use tables with Ewald"); - GMX_RELEASE_ASSERT(!generateVdwTables || EVDW_PME(ic.vdwtype), "Can only use tables with Ewald"); + GMX_RELEASE_ASSERT(!generateCoulombTables || EEL_PME_EWALD(ic.eeltype), + "Can only use tables with Ewald"); + GMX_RELEASE_ASSERT(!generateVdwTables || EVDW_PME(ic.vdwtype), + "Can only use tables with Ewald"); real sc = 0; @@ -362,16 +363,16 @@ real ewald_spline3_table_scale(const interaction_const_t &ic, real sc_q; /* Energy tolerance: 0.1 times the cut-off jump */ - etol = 0.1*std::erfc(ic.ewaldcoeff_q*ic.rcoulomb); + etol = 0.1 * std::erfc(ic.ewaldcoeff_q * ic.rcoulomb); - sc_q = spline3_table_scale(erf_x_d3, ic.ewaldcoeff_q, etol); + sc_q = spline3_table_scale(erf_x_d3, ic.ewaldcoeff_q, etol); if (debug) { - fprintf(debug, "Ewald Coulomb quadratic spline table spacing: %f nm\n", 1/sc_q); + fprintf(debug, "Ewald Coulomb quadratic spline table spacing: %f nm\n", 1 / sc_q); } - sc = std::max(sc, sc_q); + sc = std::max(sc, sc_q); } if (generateVdwTables) @@ -383,14 +384,14 @@ real ewald_spline3_table_scale(const interaction_const_t &ic, real sc_lj; /* Energy tolerance: 0.1 times the cut-off jump */ - xrc2 = gmx::square(ic.ewaldcoeff_lj*ic.rvdw); - etol = 0.1*std::exp(-xrc2)*(1 + xrc2 + xrc2*xrc2/2.0); + xrc2 = gmx::square(ic.ewaldcoeff_lj * ic.rvdw); + etol = 0.1 * std::exp(-xrc2) * (1 + xrc2 + xrc2 * xrc2 / 2.0); sc_lj = spline3_table_scale(func_d3, ic.ewaldcoeff_lj, etol); if (debug) { - fprintf(debug, "Ewald LJ quadratic spline table spacing: %f nm\n", 1/sc_lj); + fprintf(debug, "Ewald LJ quadratic spline table spacing: %f nm\n", 1 / sc_lj); } sc = std::max(sc, sc_lj); @@ -399,46 +400,50 @@ real ewald_spline3_table_scale(const interaction_const_t &ic, return sc; } -static void copy2table(int n, int offset, int stride, - const double x[], const double Vtab[], const double Ftab[], real scalefactor, - real dest[]) +static void copy2table(int n, + int offset, + int stride, + const double x[], + const double Vtab[], + const double Ftab[], + real scalefactor, + real dest[]) { -/* Use double prec. for the intermediary variables - * and temporary x/vtab/vtab2 data to avoid unnecessary - * loss of precision. - */ + /* Use double prec. for the intermediary variables + * and temporary x/vtab/vtab2 data to avoid unnecessary + * loss of precision. + */ int i, nn0; double F, G, H, h; h = 0; for (i = 0; (i < n); i++) { - if (i < n-1) + if (i < n - 1) { - h = x[i+1] - x[i]; - F = -Ftab[i]*h; - G = 3*(Vtab[i+1] - Vtab[i]) + (Ftab[i+1] + 2*Ftab[i])*h; - H = -2*(Vtab[i+1] - Vtab[i]) - (Ftab[i+1] + Ftab[i])*h; + h = x[i + 1] - x[i]; + F = -Ftab[i] * h; + G = 3 * (Vtab[i + 1] - Vtab[i]) + (Ftab[i + 1] + 2 * Ftab[i]) * h; + H = -2 * (Vtab[i + 1] - Vtab[i]) - (Ftab[i + 1] + Ftab[i]) * h; } else { /* Fill the last entry with a linear potential, * this is mainly for rounding issues with angle and dihedral potentials. */ - F = -Ftab[i]*h; - G = 0; - H = 0; + F = -Ftab[i] * h; + G = 0; + H = 0; } - nn0 = offset + i*stride; - dest[nn0] = scalefactor*Vtab[i]; - dest[nn0+1] = scalefactor*F; - dest[nn0+2] = scalefactor*G; - dest[nn0+3] = scalefactor*H; + nn0 = offset + i * stride; + dest[nn0] = scalefactor * Vtab[i]; + dest[nn0 + 1] = scalefactor * F; + dest[nn0 + 2] = scalefactor * G; + dest[nn0 + 3] = scalefactor * H; } } -static void init_table(int n, int nx0, - double tabscale, t_tabledata *td, gmx_bool bAlloc) +static void init_table(int n, int nx0, double tabscale, t_tabledata* td, gmx_bool bAlloc) { td->nx = n; td->nx0 = nx0; @@ -451,8 +456,7 @@ static void init_table(int n, int nx0, } } -static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_bool bE3, - double f[]) +static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_bool bE3, double f[]) { int start, end, i; double v3, b_s, b_e, b; @@ -464,7 +468,10 @@ static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_ if (nx < 4 && (bS3 || bE3)) { - gmx_fatal(FARGS, "Can not generate splines with third derivative boundary conditions with less than 4 (%d) points", nx); + gmx_fatal(FARGS, + "Can not generate splines with third derivative boundary conditions with less " + "than 4 (%d) points", + nx); } /* To make life easy we initially set the spacing to 1 @@ -473,12 +480,12 @@ static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_ if (bS3) { /* Fit V''' at the start */ - v3 = v[3] - 3*v[2] + 3*v[1] - v[0]; + v3 = v[3] - 3 * v[2] + 3 * v[1] - v[0]; if (debug) { - fprintf(debug, "The left third derivative is %g\n", v3/(h*h*h)); + fprintf(debug, "The left third derivative is %g\n", v3 / (h * h * h)); } - b_s = 2*(v[1] - v[0]) + v3/6; + b_s = 2 * (v[1] - v[0]) + v3 / 6; start = 0; if (FALSE) @@ -486,36 +493,36 @@ static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_ /* Fit V'' at the start */ real v2; - v2 = -v[3] + 4*v[2] - 5*v[1] + 2*v[0]; + v2 = -v[3] + 4 * v[2] - 5 * v[1] + 2 * v[0]; /* v2 = v[2] - 2*v[1] + v[0]; */ if (debug) { - fprintf(debug, "The left second derivative is %g\n", v2/(h*h)); + fprintf(debug, "The left second derivative is %g\n", v2 / (h * h)); } - b_s = 3*(v[1] - v[0]) - v2/2; + b_s = 3 * (v[1] - v[0]) - v2 / 2; start = 0; } } else { - b_s = 3*(v[2] - v[0]) + f[0]*h; + b_s = 3 * (v[2] - v[0]) + f[0] * h; start = 1; } if (bE3) { /* Fit V''' at the end */ - v3 = v[nx-1] - 3*v[nx-2] + 3*v[nx-3] - v[nx-4]; + v3 = v[nx - 1] - 3 * v[nx - 2] + 3 * v[nx - 3] - v[nx - 4]; if (debug) { - fprintf(debug, "The right third derivative is %g\n", v3/(h*h*h)); + fprintf(debug, "The right third derivative is %g\n", v3 / (h * h * h)); } - b_e = 2*(v[nx-1] - v[nx-2]) + v3/6; + b_e = 2 * (v[nx - 1] - v[nx - 2]) + v3 / 6; end = nx; } else { /* V'=0 at the end */ - b_e = 3*(v[nx-1] - v[nx-3]) + f[nx-1]*h; + b_e = 3 * (v[nx - 1] - v[nx - 3]) + f[nx - 1] * h; end = nx - 1; } @@ -525,41 +532,38 @@ static void spline_forces(int nx, double h, const double v[], gmx_bool bS3, gmx_ /* For V'' fitting */ /* beta = (bS3 ? 2 : 4); */ - f[start] = b_s/beta; - for (i = start+1; i < end; i++) + f[start] = b_s / beta; + for (i = start + 1; i < end; i++) { - gamma[i] = 1/beta; + gamma[i] = 1 / beta; beta = 4 - gamma[i]; - b = 3*(v[i+1] - v[i-1]); - f[i] = (b - f[i-1])/beta; + b = 3 * (v[i + 1] - v[i - 1]); + f[i] = (b - f[i - 1]) / beta; } - gamma[end-1] = 1/beta; - beta = (bE3 ? 1 : 4) - gamma[end-1]; - f[end-1] = (b_e - f[end-2])/beta; + gamma[end - 1] = 1 / beta; + beta = (bE3 ? 1 : 4) - gamma[end - 1]; + f[end - 1] = (b_e - f[end - 2]) / beta; - for (i = end-2; i >= start; i--) + for (i = end - 2; i >= start; i--) { - f[i] -= gamma[i+1]*f[i+1]; + f[i] -= gamma[i + 1] * f[i + 1]; } sfree(gamma); /* Correct for the minus sign and the spacing */ for (i = start; i < end; i++) { - f[i] = -f[i]/h; + f[i] = -f[i] / h; } } -static void set_forces(FILE *fp, int angle, - int nx, double h, double v[], double f[], - int table) +static void set_forces(FILE* fp, int angle, int nx, double h, double v[], double f[], int table) { int start, end; if (angle == 2) { - gmx_fatal(FARGS, - "Force generation for dihedral tables is not (yet) implemented"); + gmx_fatal(FARGS, "Force generation for dihedral tables is not (yet) implemented"); } start = 0; @@ -569,7 +573,7 @@ static void set_forces(FILE *fp, int angle, } end = nx; - while (v[end-1] == 0) + while (v[end - 1] == 0) { end--; } @@ -585,13 +589,12 @@ static void set_forces(FILE *fp, int angle, if (fp) { fprintf(fp, "Generating forces for table %d, boundary conditions: V''' at %g, %s at %g\n", - table+1, start*h, end == nx ? "V'''" : "V'=0", (end-1)*h); + table + 1, start * h, end == nx ? "V'''" : "V'=0", (end - 1) * h); } - spline_forces(end-start, h, v+start, TRUE, end == nx, f+start); + spline_forces(end - start, h, v + start, TRUE, end == nx, f + start); } -static void read_tables(FILE *fp, const char *filename, - int ntab, int angle, t_tabledata td[]) +static void read_tables(FILE* fp, const char* filename, int ntab, int angle, t_tabledata td[]) { char buf[STRLEN]; double **yy = nullptr, start, end, dx0, dx1, ssd, vm, vp, f, numf; @@ -599,20 +602,19 @@ static void read_tables(FILE *fp, const char *filename, gmx_bool bAllZero, bZeroV, bZeroF; double tabscale; - nny = 2*ntab+1; + nny = 2 * ntab + 1; std::string libfn = gmx::findLibraryFile(filename); - nx = read_xvg(libfn.c_str(), &yy, &ny); + nx = read_xvg(libfn.c_str(), &yy, &ny); if (ny != nny) { - gmx_fatal(FARGS, "Trying to read file %s, but nr columns = %d, should be %d", - libfn.c_str(), ny, nny); + gmx_fatal(FARGS, "Trying to read file %s, but nr columns = %d, should be %d", libfn.c_str(), + ny, nny); } if (angle == 0) { if (yy[0][0] != 0.0) { - gmx_fatal(FARGS, - "The first distance in file %s is %f nm instead of %f nm", + gmx_fatal(FARGS, "The first distance in file %s is %f nm instead of %f nm", libfn.c_str(), yy[0][0], 0.0); } } @@ -627,14 +629,14 @@ static void read_tables(FILE *fp, const char *filename, start = -180.0; } end = 180.0; - if (yy[0][0] != start || yy[0][nx-1] != end) + if (yy[0][0] != start || yy[0][nx - 1] != end) { gmx_fatal(FARGS, "The angles in file %s should go from %f to %f instead of %f to %f\n", - libfn.c_str(), start, end, yy[0][0], yy[0][nx-1]); + libfn.c_str(), start, end, yy[0][0], yy[0][nx - 1]); } } - tabscale = (nx-1)/(yy[0][nx-1] - yy[0][0]); + tabscale = (nx - 1) / (yy[0][nx - 1] - yy[0][0]); if (fp) { @@ -654,15 +656,17 @@ static void read_tables(FILE *fp, const char *filename, { if (i >= 2) { - dx0 = yy[0][i-1] - yy[0][i-2]; - dx1 = yy[0][i] - yy[0][i-1]; + dx0 = yy[0][i - 1] - yy[0][i - 2]; + dx1 = yy[0][i] - yy[0][i - 1]; /* Check for 1% deviation in spacing */ - if (fabs(dx1 - dx0) >= 0.005*(fabs(dx0) + fabs(dx1))) + if (fabs(dx1 - dx0) >= 0.005 * (fabs(dx0) + fabs(dx1))) { - gmx_fatal(FARGS, "In table file '%s' the x values are not equally spaced: %f %f %f", filename, yy[0][i-2], yy[0][i-1], yy[0][i]); + gmx_fatal(FARGS, + "In table file '%s' the x values are not equally spaced: %f %f %f", + filename, yy[0][i - 2], yy[0][i - 1], yy[0][i]); } } - if (yy[1+k*2][i] != 0) + if (yy[1 + k * 2][i] != 0) { bZeroV = FALSE; if (bAllZero) @@ -670,14 +674,13 @@ static void read_tables(FILE *fp, const char *filename, bAllZero = FALSE; nx0 = i; } - if (yy[1+k*2][i] > 0.01*GMX_REAL_MAX || - yy[1+k*2][i] < -0.01*GMX_REAL_MAX) + if (yy[1 + k * 2][i] > 0.01 * GMX_REAL_MAX || yy[1 + k * 2][i] < -0.01 * GMX_REAL_MAX) { gmx_fatal(FARGS, "Out of range potential value %g in file '%s'", - yy[1+k*2][i], filename); + yy[1 + k * 2][i], filename); } } - if (yy[1+k*2+1][i] != 0) + if (yy[1 + k * 2 + 1][i] != 0) { bZeroF = FALSE; if (bAllZero) @@ -685,18 +688,17 @@ static void read_tables(FILE *fp, const char *filename, bAllZero = FALSE; nx0 = i; } - if (yy[1+k*2+1][i] > 0.01*GMX_REAL_MAX || - yy[1+k*2+1][i] < -0.01*GMX_REAL_MAX) + if (yy[1 + k * 2 + 1][i] > 0.01 * GMX_REAL_MAX || yy[1 + k * 2 + 1][i] < -0.01 * GMX_REAL_MAX) { gmx_fatal(FARGS, "Out of range force value %g in file '%s'", - yy[1+k*2+1][i], filename); + yy[1 + k * 2 + 1][i], filename); } } } if (!bZeroV && bZeroF) { - set_forces(fp, angle, nx, 1/tabscale, yy[1+k*2], yy[1+k*2+1], k); + set_forces(fp, angle, nx, 1 / tabscale, yy[1 + k * 2], yy[1 + k * 2 + 1], k); } else { @@ -705,18 +707,18 @@ static void read_tables(FILE *fp, const char *filename, */ ssd = 0; ns = 0; - for (i = 1; (i < nx-1); i++) + for (i = 1; (i < nx - 1); i++) { - vm = yy[1+2*k][i-1]; - vp = yy[1+2*k][i+1]; - f = yy[1+2*k+1][i]; + vm = yy[1 + 2 * k][i - 1]; + vp = yy[1 + 2 * k][i + 1]; + f = yy[1 + 2 * k + 1][i]; if (vm != 0 && vp != 0 && f != 0) { /* Take the centered difference */ - numf = -(vp - vm)*0.5*tabscale; + numf = -(vp - vm) * 0.5 * tabscale; if (f + numf != 0) { - ssd += fabs(2*(f - numf)/(f + numf)); + ssd += fabs(2 * (f - numf) / (f + numf)); } ns++; } @@ -724,9 +726,11 @@ static void read_tables(FILE *fp, const char *filename, if (ns > 0) { ssd /= ns; - sprintf(buf, "For the %d non-zero entries for table %d in %s the forces deviate on average %" PRId64 + sprintf(buf, + "For the %d non-zero entries for table %d in %s the forces deviate on " + "average %" PRId64 "%% from minus the numerical derivative of the potential\n", - ns, k, libfn.c_str(), gmx::roundToInt64(100*ssd)); + ns, k, libfn.c_str(), gmx::roundToInt64(100 * ssd)); if (debug) { fprintf(debug, "%s", buf); @@ -753,8 +757,8 @@ static void read_tables(FILE *fp, const char *filename, for (i = 0; (i < nx); i++) { td[k].x[i] = yy[0][i]; - td[k].v[i] = yy[2*k+1][i]; - td[k].f[i] = yy[2*k+2][i]; + td[k].v[i] = yy[2 * k + 1][i]; + td[k].f[i] = yy[2 * k + 2][i]; } } for (i = 0; (i < ny); i++) @@ -764,7 +768,7 @@ static void read_tables(FILE *fp, const char *filename, sfree(yy); } -static void done_tabledata(t_tabledata *td) +static void done_tabledata(t_tabledata* td) { if (!td) { @@ -776,8 +780,7 @@ static void done_tabledata(t_tabledata *td) sfree(td->f); } -static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, - gmx_bool b14only) +static void fill_table(t_tabledata* td, int tp, const interaction_const_t* ic, gmx_bool b14only) { /* Fill the table according to the formulas in the manual. * In principle, we only need the potential and the second @@ -789,15 +792,15 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, * we always use double precision to calculate them here, in order * to avoid unnecessary loss of precision. */ - int i; - double reppow, p; - double r1, rc, r12, r13; - double r, r2, r6, rc2, rc6, rc12; - double expr, Vtab, Ftab; + int i; + double reppow, p; + double r1, rc, r12, r13; + double r, r2, r6, rc2, rc6, rc12; + double expr, Vtab, Ftab; /* Parameters for David's function */ - double A = 0, B = 0, C = 0, A_3 = 0, B_4 = 0; + double A = 0, B = 0, C = 0, A_3 = 0, B_4 = 0; /* Parameters for the switching function */ - double ksw, swi, swi1; + double ksw, swi, swi1; /* Temporary parameters */ gmx_bool bPotentialSwitch, bForceSwitch, bPotentialShift; double ewc = ic->ewaldcoeff_q; @@ -812,17 +815,15 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, } else { - bPotentialSwitch = ((tp == etabLJ6Switch) || (tp == etabLJ12Switch) || - (tp == etabCOULSwitch) || - (tp == etabEwaldSwitch) || (tp == etabEwaldUserSwitch) || - (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSWITCH)) || - (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSWITCH))); - bForceSwitch = ((tp == etabLJ6Shift) || (tp == etabLJ12Shift) || - (tp == etabShift) || - (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodFORCESWITCH)) || - (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodFORCESWITCH))); - bPotentialShift = ((tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSHIFT)) || - (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSHIFT))); + bPotentialSwitch = ((tp == etabLJ6Switch) || (tp == etabLJ12Switch) || (tp == etabCOULSwitch) + || (tp == etabEwaldSwitch) || (tp == etabEwaldUserSwitch) + || (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSWITCH)) + || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSWITCH))); + bForceSwitch = ((tp == etabLJ6Shift) || (tp == etabLJ12Shift) || (tp == etabShift) + || (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodFORCESWITCH)) + || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodFORCESWITCH))); + bPotentialShift = ((tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSHIFT)) + || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSHIFT))); } reppow = ic->reppow; @@ -839,11 +840,11 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, } if (bPotentialSwitch) { - ksw = 1.0/(gmx::power5(rc-r1)); + ksw = 1.0 / (gmx::power5(rc - r1)); } else { - ksw = 0.0; + ksw = 0.0; } if (bForceSwitch) { @@ -860,30 +861,31 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, p = reppow; } - A = p * ((p+1)*r1-(p+4)*rc)/(std::pow(rc, p+2)*gmx::square(rc-r1)); - B = -p * ((p+1)*r1-(p+3)*rc)/(std::pow(rc, p+2)*gmx::power3(rc-r1)); - C = 1.0/std::pow(rc, p)-A/3.0*gmx::power3(rc-r1)-B/4.0*gmx::power4(rc-r1); + A = p * ((p + 1) * r1 - (p + 4) * rc) / (std::pow(rc, p + 2) * gmx::square(rc - r1)); + B = -p * ((p + 1) * r1 - (p + 3) * rc) / (std::pow(rc, p + 2) * gmx::power3(rc - r1)); + C = 1.0 / std::pow(rc, p) - A / 3.0 * gmx::power3(rc - r1) - B / 4.0 * gmx::power4(rc - r1); if (tp == etabLJ6Shift) { A = -A; B = -B; C = -C; } - A_3 = A/3.0; - B_4 = B/4.0; + A_3 = A / 3.0; + B_4 = B / 4.0; } if (debug) { - fprintf(debug, "Setting up tables\n"); fflush(debug); + fprintf(debug, "Setting up tables\n"); + fflush(debug); } if (bPotentialShift) { - rc2 = rc*rc; - rc6 = 1.0/(rc2*rc2*rc2); - if (gmx_within_tol(reppow, 12.0, 10*GMX_DOUBLE_EPS)) + rc2 = rc * rc; + rc6 = 1.0 / (rc2 * rc2 * rc2); + if (gmx_within_tol(reppow, 12.0, 10 * GMX_DOUBLE_EPS)) { - rc12 = rc6*rc6; + rc12 = rc6 * rc6; } else { @@ -897,56 +899,53 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, Vcut = -rc6; break; case etabLJ6Ewald: - Vcut = -rc6*exp(-ewclj*ewclj*rc2)*(1 + ewclj*ewclj*rc2 + gmx::power4(ewclj)*rc2*rc2/2); + Vcut = -rc6 * exp(-ewclj * ewclj * rc2) + * (1 + ewclj * ewclj * rc2 + gmx::power4(ewclj) * rc2 * rc2 / 2); break; case etabLJ12: /* Repulsion */ - Vcut = rc12; - break; - case etabCOUL: - Vcut = 1.0/rc; + Vcut = rc12; break; + case etabCOUL: Vcut = 1.0 / rc; break; case etabEwald: - case etabEwaldSwitch: - Vcut = std::erfc(ewc*rc)/rc; - break; + case etabEwaldSwitch: Vcut = std::erfc(ewc * rc) / rc; break; case etabEwaldUser: /* Only calculate minus the reciprocal space contribution */ - Vcut = -std::erf(ewc*rc)/rc; + Vcut = -std::erf(ewc * rc) / rc; break; case etabRF: case etabRF_ZERO: /* No need for preventing the usage of modifiers with RF */ - Vcut = 0.0; - break; - case etabEXPMIN: - Vcut = exp(-rc); + Vcut = 0.0; break; + case etabEXPMIN: Vcut = exp(-rc); break; default: - gmx_fatal(FARGS, "Cannot apply new potential-shift modifier to interaction type '%s' yet. (%s,%d)", + gmx_fatal(FARGS, + "Cannot apply new potential-shift modifier to interaction type '%s' yet. " + "(%s,%d)", tprops[tp].name, __FILE__, __LINE__); } } for (i = 0; (i < td->nx); i++) { - td->x[i] = i/td->tabscale; + td->x[i] = i / td->tabscale; } for (i = td->nx0; (i < td->nx); i++) { - r = td->x[i]; - r2 = r*r; - r6 = 1.0/(r2*r2*r2); - if (gmx_within_tol(reppow, 12.0, 10*GMX_DOUBLE_EPS)) + r = td->x[i]; + r2 = r * r; + r6 = 1.0 / (r2 * r2 * r2); + if (gmx_within_tol(reppow, 12.0, 10 * GMX_DOUBLE_EPS)) { - r12 = r6*r6; + r12 = r6 * r6; } else { r12 = std::pow(r, -reppow); } - Vtab = 0.0; - Ftab = 0.0; + Vtab = 0.0; + Ftab = 0.0; if (bPotentialSwitch) { /* swi is function, swi1 1st derivative and swi2 2nd derivative */ @@ -967,10 +966,10 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, } else { - swi = 1 - 10*gmx::power3(r-r1)*ksw*gmx::square(rc-r1) - + 15*gmx::power4(r-r1)*ksw*(rc-r1) - 6*gmx::power5(r-r1)*ksw; - swi1 = -30*gmx::square(r-r1)*ksw*gmx::square(rc-r1) - + 60*gmx::power3(r-r1)*ksw*(rc-r1) - 30*gmx::power4(r-r1)*ksw; + swi = 1 - 10 * gmx::power3(r - r1) * ksw * gmx::square(rc - r1) + + 15 * gmx::power4(r - r1) * ksw * (rc - r1) - 6 * gmx::power5(r - r1) * ksw; + swi1 = -30 * gmx::square(r - r1) * ksw * gmx::square(rc - r1) + + 60 * gmx::power3(r - r1) * ksw * (rc - r1) - 30 * gmx::power4(r - r1) * ksw; } } else /* not really needed, but avoids compiler warnings... */ @@ -979,15 +978,15 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, swi1 = 0.0; } - rc6 = rc*rc*rc; - rc6 = 1.0/(rc6*rc6); + rc6 = rc * rc * rc; + rc6 = 1.0 / (rc6 * rc6); switch (tp) { case etabLJ6: /* Dispersion */ Vtab = -r6; - Ftab = 6.0*Vtab/r; + Ftab = 6.0 * Vtab / r; break; case etabLJ6Switch: case etabLJ6Shift: @@ -995,79 +994,81 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, if (r < rc) { Vtab = -r6; - Ftab = 6.0*Vtab/r; + Ftab = 6.0 * Vtab / r; break; } break; case etabLJ12: /* Repulsion */ - Vtab = r12; - Ftab = reppow*Vtab/r; + Vtab = r12; + Ftab = reppow * Vtab / r; break; case etabLJ12Switch: case etabLJ12Shift: /* Repulsion */ if (r < rc) { - Vtab = r12; - Ftab = reppow*Vtab/r; + Vtab = r12; + Ftab = reppow * Vtab / r; } break; case etabLJ6Encad: if (r < rc) { - Vtab = -(r6-6.0*(rc-r)*rc6/rc-rc6); - Ftab = -(6.0*r6/r-6.0*rc6/rc); + Vtab = -(r6 - 6.0 * (rc - r) * rc6 / rc - rc6); + Ftab = -(6.0 * r6 / r - 6.0 * rc6 / rc); } else /* r>rc */ { - Vtab = 0; - Ftab = 0; + Vtab = 0; + Ftab = 0; } break; case etabLJ12Encad: if (r < rc) { - Vtab = -(r6-6.0*(rc-r)*rc6/rc-rc6); - Ftab = -(6.0*r6/r-6.0*rc6/rc); + Vtab = -(r6 - 6.0 * (rc - r) * rc6 / rc - rc6); + Ftab = -(6.0 * r6 / r - 6.0 * rc6 / rc); } else /* r>rc */ { - Vtab = 0; - Ftab = 0; + Vtab = 0; + Ftab = 0; } break; case etabCOUL: - Vtab = 1.0/r; - Ftab = 1.0/r2; + Vtab = 1.0 / r; + Ftab = 1.0 / r2; break; case etabCOULSwitch: case etabShift: if (r < rc) { - Vtab = 1.0/r; - Ftab = 1.0/r2; + Vtab = 1.0 / r; + Ftab = 1.0 / r2; } break; case etabEwald: case etabEwaldSwitch: - Vtab = std::erfc(ewc*r)/r; - Ftab = std::erfc(ewc*r)/r2+exp(-(ewc*ewc*r2))*ewc*M_2_SQRTPI/r; + Vtab = std::erfc(ewc * r) / r; + Ftab = std::erfc(ewc * r) / r2 + exp(-(ewc * ewc * r2)) * ewc * M_2_SQRTPI / r; break; case etabEwaldUser: case etabEwaldUserSwitch: /* Only calculate the negative of the reciprocal space contribution */ - Vtab = -std::erf(ewc*r)/r; - Ftab = -std::erf(ewc*r)/r2+exp(-(ewc*ewc*r2))*ewc*M_2_SQRTPI/r; + Vtab = -std::erf(ewc * r) / r; + Ftab = -std::erf(ewc * r) / r2 + exp(-(ewc * ewc * r2)) * ewc * M_2_SQRTPI / r; break; case etabLJ6Ewald: - Vtab = -r6*exp(-ewclj*ewclj*r2)*(1 + ewclj*ewclj*r2 + gmx::power4(ewclj)*r2*r2/2); - Ftab = 6.0*Vtab/r - r6*exp(-ewclj*ewclj*r2)*gmx::power5(ewclj)*ewclj*r2*r2*r; + Vtab = -r6 * exp(-ewclj * ewclj * r2) + * (1 + ewclj * ewclj * r2 + gmx::power4(ewclj) * r2 * r2 / 2); + Ftab = 6.0 * Vtab / r + - r6 * exp(-ewclj * ewclj * r2) * gmx::power5(ewclj) * ewclj * r2 * r2 * r; break; case etabRF: case etabRF_ZERO: - Vtab = 1.0/r + ic->k_rf*r2 - ic->c_rf; - Ftab = 1.0/r2 - 2*ic->k_rf*r; + Vtab = 1.0 / r + ic->k_rf * r2 - ic->c_rf; + Ftab = 1.0 / r2 - 2 * ic->k_rf * r; if (tp == etabRF_ZERO && r >= rc) { Vtab = 0; @@ -1075,25 +1076,24 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, } break; case etabEXPMIN: - expr = exp(-r); - Vtab = expr; - Ftab = expr; + expr = exp(-r); + Vtab = expr; + Ftab = expr; break; case etabCOULEncad: if (r < rc) { - Vtab = 1.0/r-(rc-r)/(rc*rc)-1.0/rc; - Ftab = 1.0/r2-1.0/(rc*rc); + Vtab = 1.0 / r - (rc - r) / (rc * rc) - 1.0 / rc; + Ftab = 1.0 / r2 - 1.0 / (rc * rc); } else /* r>rc */ { - Vtab = 0; - Ftab = 0; + Vtab = 0; + Ftab = 0; } break; default: - gmx_fatal(FARGS, "Table type %d not implemented yet. (%s,%d)", - tp, __FILE__, __LINE__); + gmx_fatal(FARGS, "Table type %d not implemented yet. (%s,%d)", tp, __FILE__, __LINE__); } if (bForceSwitch) { @@ -1104,10 +1104,10 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, /* If in Shifting range add something to it */ if (r > r1) { - r12 = (r-r1)*(r-r1); - r13 = (r-r1)*r12; - Vtab += -A_3*r13 - B_4*r12*r12; - Ftab += A*r12 + B*r13; + r12 = (r - r1) * (r - r1); + r13 = (r - r1) * r12; + Vtab += -A_3 * r13 - B_4 * r12 * r12; + Ftab += A * r12 + B * r13; } } else @@ -1147,26 +1147,26 @@ static void fill_table(t_tabledata *td, int tp, const interaction_const_t *ic, } else if (r > r1) { - Ftab = Ftab*swi - Vtab*swi1; - Vtab = Vtab*swi; + Ftab = Ftab * swi - Vtab * swi1; + Vtab = Vtab * swi; } } /* Convert to single precision when we store to mem */ - td->v[i] = Vtab; - td->f[i] = Ftab; + td->v[i] = Vtab; + td->f[i] = Ftab; } /* Continue the table linearly from nx0 to 0. * These values are only required for energy minimization with overlap or TPI. */ - for (i = td->nx0-1; i >= 0; i--) + for (i = td->nx0 - 1; i >= 0; i--) { - td->v[i] = td->v[i+1] + td->f[i+1]*(td->x[i+1] - td->x[i]); - td->f[i] = td->f[i+1]; + td->v[i] = td->v[i + 1] + td->f[i + 1] * (td->x[i + 1] - td->x[i]); + td->f[i] = td->f[i + 1]; } } -static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool b14only) +static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool b14only) { int eltype, vdwtype; @@ -1181,11 +1181,8 @@ static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool { case eelUSER: case eelPMEUSER: - case eelPMEUSERSWITCH: - eltype = eelUSER; - break; - default: - eltype = eelCUT; + case eelPMEUSERSWITCH: eltype = eelUSER; break; + default: eltype = eelCUT; } } else @@ -1195,12 +1192,8 @@ static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool switch (eltype) { - case eelCUT: - tabsel[etiCOUL] = etabCOUL; - break; - case eelPOISSON: - tabsel[etiCOUL] = etabShift; - break; + case eelCUT: tabsel[etiCOUL] = etabCOUL; break; + case eelPOISSON: tabsel[etiCOUL] = etabShift; break; case eelSHIFT: if (ic->rcoulomb > ic->rcoulomb_switch) { @@ -1213,33 +1206,16 @@ static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool break; case eelEWALD: case eelPME: - case eelP3M_AD: - tabsel[etiCOUL] = etabEwald; - break; - case eelPMESWITCH: - tabsel[etiCOUL] = etabEwaldSwitch; - break; - case eelPMEUSER: - tabsel[etiCOUL] = etabEwaldUser; - break; - case eelPMEUSERSWITCH: - tabsel[etiCOUL] = etabEwaldUserSwitch; - break; + case eelP3M_AD: tabsel[etiCOUL] = etabEwald; break; + case eelPMESWITCH: tabsel[etiCOUL] = etabEwaldSwitch; break; + case eelPMEUSER: tabsel[etiCOUL] = etabEwaldUser; break; + case eelPMEUSERSWITCH: tabsel[etiCOUL] = etabEwaldUserSwitch; break; case eelRF: - case eelRF_ZERO: - tabsel[etiCOUL] = etabRF_ZERO; - break; - case eelSWITCH: - tabsel[etiCOUL] = etabCOULSwitch; - break; - case eelUSER: - tabsel[etiCOUL] = etabUSER; - break; - case eelENCADSHIFT: - tabsel[etiCOUL] = etabCOULEncad; - break; - default: - gmx_fatal(FARGS, "Invalid eeltype %d", eltype); + case eelRF_ZERO: tabsel[etiCOUL] = etabRF_ZERO; break; + case eelSWITCH: tabsel[etiCOUL] = etabCOULSwitch; break; + case eelUSER: tabsel[etiCOUL] = etabUSER; break; + case eelENCADSHIFT: tabsel[etiCOUL] = etabCOULEncad; break; + default: gmx_fatal(FARGS, "Invalid eeltype %d", eltype); } /* Van der Waals time */ @@ -1286,16 +1262,16 @@ static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool tabsel[etiLJ12] = etabLJ12; break; default: - gmx_fatal(FARGS, "Invalid vdwtype %d in %s line %d", vdwtype, - __FILE__, __LINE__); + gmx_fatal(FARGS, "Invalid vdwtype %d in %s line %d", vdwtype, __FILE__, __LINE__); } if (!b14only && ic->vdw_modifier != eintmodNONE) { - if (ic->vdw_modifier != eintmodPOTSHIFT && - ic->vdwtype != evdwCUT) + if (ic->vdw_modifier != eintmodPOTSHIFT && ic->vdwtype != evdwCUT) { - gmx_incons("Potential modifiers other than potential-shift are only implemented for LJ cut-off"); + gmx_incons( + "Potential modifiers other than potential-shift are only implemented for " + "LJ cut-off"); } /* LJ-PME and other (shift-only) modifiers are handled by applying the modifiers @@ -1318,26 +1294,22 @@ static void set_table_type(int tabsel[], const interaction_const_t *ic, gmx_bool tabsel[etiLJ6] = etabLJ6Shift; tabsel[etiLJ12] = etabLJ12Shift; break; - default: - gmx_incons("Unsupported vdw_modifier"); + default: gmx_incons("Unsupported vdw_modifier"); } } } } } -t_forcetable *make_tables(FILE *out, - const interaction_const_t *ic, - const char *fn, - real rtab, int flags) +t_forcetable* make_tables(FILE* out, const interaction_const_t* ic, const char* fn, real rtab, int flags) { - t_tabledata *td; - gmx_bool b14only, useUserTable; - int nx0, tabsel[etiNR]; - real scalefactor; + t_tabledata* td; + gmx_bool b14only, useUserTable; + int nx0, tabsel[etiNR]; + real scalefactor; - t_forcetable *table = new t_forcetable(GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, - GMX_TABLE_FORMAT_CUBICSPLINE_YFGH); + t_forcetable* table = new t_forcetable(GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, + GMX_TABLE_FORMAT_CUBICSPLINE_YFGH); b14only = ((flags & GMX_MAKETABLES_14ONLY) != 0); @@ -1352,13 +1324,13 @@ t_forcetable *make_tables(FILE *out, set_table_type(tabsel, ic, b14only); } snew(td, etiNR); - table->r = rtab; - table->scale = 0; - table->n = 0; + table->r = rtab; + table->scale = 0; + table->n = 0; table->formatsize = 4; table->ninteractions = etiNR; - table->stride = table->formatsize*table->ninteractions; + table->stride = table->formatsize * table->ninteractions; /* Check whether we have to read or generate */ useUserTable = FALSE; @@ -1378,12 +1350,14 @@ t_forcetable *make_tables(FILE *out, } else { - if (td[0].x[td[0].nx-1] < rtab) + if (td[0].x[td[0].nx - 1] < rtab) { - gmx_fatal(FARGS, "Tables in file %s not long enough for cut-off:\n" - "\tshould be at least %f nm\n", fn, rtab); + gmx_fatal(FARGS, + "Tables in file %s not long enough for cut-off:\n" + "\tshould be at least %f nm\n", + fn, rtab); } - table->n = gmx::roundToInt(rtab*td[0].tabscale); + table->n = gmx::roundToInt(rtab * td[0].tabscale); } table->scale = td[0].tabscale; nx0 = td[0].nx0; @@ -1396,7 +1370,7 @@ t_forcetable *make_tables(FILE *out, #else table->scale = 500.0; #endif - table->n = static_cast(rtab*table->scale); + table->n = static_cast(rtab * table->scale); nx0 = 10; } @@ -1404,7 +1378,7 @@ t_forcetable *make_tables(FILE *out, * numbers per table->n+1 data points. For performance reasons we want * the table data to be aligned to a 32-byte boundary. */ - snew_aligned(table->data, table->stride*(table->n+1)*sizeof(real), 32); + snew_aligned(table->data, table->stride * (table->n + 1) * sizeof(real), 32); for (int k = 0; (k < etiNR); k++) { @@ -1414,9 +1388,7 @@ t_forcetable *make_tables(FILE *out, if (tabsel[k] != etabUSER) { real scale = table->scale; - if (ic->useBuckingham && - (ic->buckinghamBMax != 0) && - tabsel[k] == etabEXPMIN) + if (ic->useBuckingham && (ic->buckinghamBMax != 0) && tabsel[k] == etabEXPMIN) { scale /= ic->buckinghamBMax; } @@ -1425,10 +1397,10 @@ t_forcetable *make_tables(FILE *out, fill_table(&(td[k]), tabsel[k], ic, b14only); if (out) { - fprintf(out, "Generated table with %d data points for %s%s.\n" + fprintf(out, + "Generated table with %d data points for %s%s.\n" "Tabscale = %g points/nm\n", - td[k].nx, b14only ? "1-4 " : "", tprops[tabsel[k]].name, - td[k].tabscale); + td[k].nx, b14only ? "1-4 " : "", tprops[tabsel[k]].name, td[k].tabscale); } } @@ -1440,18 +1412,19 @@ t_forcetable *make_tables(FILE *out, */ if (k == etiLJ6) { - scalefactor = 1.0/6.0; + scalefactor = 1.0 / 6.0; } else if (k == etiLJ12 && tabsel[k] != etabEXPMIN) { - scalefactor = 1.0/12.0; + scalefactor = 1.0 / 12.0; } else { scalefactor = 1.0; } - copy2table(table->n, k*table->formatsize, table->stride, td[k].x, td[k].v, td[k].f, scalefactor, table->data); + copy2table(table->n, k * table->formatsize, table->stride, td[k].x, td[k].v, td[k].f, + scalefactor, table->data); done_tabledata(&(td[k])); } @@ -1460,7 +1433,7 @@ t_forcetable *make_tables(FILE *out, return table; } -bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle) +bondedtable_t make_bonded_table(FILE* fplog, const char* fn, int angle) { t_tabledata td; int i; @@ -1480,7 +1453,7 @@ bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle) } tab.n = td.nx; tab.scale = td.tabscale; - snew(tab.data, tab.n*stride); + snew(tab.data, tab.n * stride); copy2table(tab.n, 0, stride, td.x, td.v, td.f, 1.0, tab.data); done_tabledata(&td); @@ -1488,10 +1461,7 @@ bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle) } std::unique_ptr -makeDispersionCorrectionTable(FILE *fp, - const interaction_const_t *ic, - real rtab, - const char *tabfn) +makeDispersionCorrectionTable(FILE* fp, const interaction_const_t* ic, real rtab, const char* tabfn) { GMX_RELEASE_ASSERT(ic->vdwtype != evdwUSER || tabfn, "With VdW user tables we need a table file name"); @@ -1501,27 +1471,28 @@ makeDispersionCorrectionTable(FILE *fp, return std::unique_ptr(nullptr); } - t_forcetable *fullTable = make_tables(fp, ic, tabfn, rtab, 0); + t_forcetable* fullTable = make_tables(fp, ic, tabfn, rtab, 0); /* Copy the contents of the table to one that has just dispersion * and repulsion, to improve cache performance. We want the table * data to be aligned to 32-byte boundaries. */ std::unique_ptr dispersionCorrectionTable = - std::make_unique(GMX_TABLE_INTERACTION_VDWREP_VDWDISP, - fullTable->format); + std::make_unique(GMX_TABLE_INTERACTION_VDWREP_VDWDISP, fullTable->format); dispersionCorrectionTable->r = fullTable->r; dispersionCorrectionTable->n = fullTable->n; dispersionCorrectionTable->scale = fullTable->scale; dispersionCorrectionTable->formatsize = fullTable->formatsize; dispersionCorrectionTable->ninteractions = 2; - dispersionCorrectionTable->stride = dispersionCorrectionTable->formatsize * dispersionCorrectionTable->ninteractions; - snew_aligned(dispersionCorrectionTable->data, dispersionCorrectionTable->stride*(dispersionCorrectionTable->n+1), 32); + dispersionCorrectionTable->stride = + dispersionCorrectionTable->formatsize * dispersionCorrectionTable->ninteractions; + snew_aligned(dispersionCorrectionTable->data, + dispersionCorrectionTable->stride * (dispersionCorrectionTable->n + 1), 32); for (int i = 0; i <= fullTable->n; i++) { for (int j = 0; j < 8; j++) { - dispersionCorrectionTable->data[8*i+j] = fullTable->data[12*i+4+j]; + dispersionCorrectionTable->data[8 * i + j] = fullTable->data[12 * i + 4 + j]; } } delete fullTable; @@ -1529,8 +1500,7 @@ makeDispersionCorrectionTable(FILE *fp, return dispersionCorrectionTable; } -t_forcetable::t_forcetable(enum gmx_table_interaction interaction, - enum gmx_table_format format) : +t_forcetable::t_forcetable(enum gmx_table_interaction interaction, enum gmx_table_format format) : interaction(interaction), format(format), r(0), diff --git a/src/gromacs/tables/forcetable.h b/src/gromacs/tables/forcetable.h index f98327beaf..7b687250dc 100644 --- a/src/gromacs/tables/forcetable.h +++ b/src/gromacs/tables/forcetable.h @@ -54,16 +54,17 @@ #include "gromacs/utility/real.h" /*! \brief Flag to select user tables for make_tables */ -#define GMX_MAKETABLES_FORCEUSER (1<<0) +#define GMX_MAKETABLES_FORCEUSER (1 << 0) /*! \brief Flag to only make 1,4 pair tables for make_tables */ -#define GMX_MAKETABLES_14ONLY (1<<1) +#define GMX_MAKETABLES_14ONLY (1 << 1) /*! \brief Enumerated type to describe the interaction types in a table */ -enum { - etiCOUL, //!< Coulomb - etiLJ6, //!< Dispersion - etiLJ12, //!< Repulsion - etiNR //!< Total number of interaction types +enum +{ + etiCOUL, //!< Coulomb + etiLJ6, //!< Dispersion + etiLJ12, //!< Repulsion + etiNR //!< Total number of interaction types }; /*! \brief Function pointer to calculate the grid contribution for coulomb/LJ @@ -89,11 +90,10 @@ typedef double (*real_space_grid_contribution_computer)(double, double); * \param v_lr Pointer to function calculating real-space grid contribution * \returns a set of Ewald correction tables */ -EwaldCorrectionTables -generateEwaldCorrectionTables(int numPoints, - double tableScaling, - real beta, - real_space_grid_contribution_computer v_lr); +EwaldCorrectionTables generateEwaldCorrectionTables(int numPoints, + double tableScaling, + real beta, + real_space_grid_contribution_computer v_lr); /*! \brief Compute scaling for the Ewald quadratic spline tables. * @@ -102,9 +102,7 @@ generateEwaldCorrectionTables(int numPoints, * \param generateVdwTables Take the spacing for Van der Waals Ewald corrections into account * \return The scaling factor in units 1/nm */ -real ewald_spline3_table_scale(const interaction_const_t &ic, - bool generateCoulombTables, - bool generateVdwTables); +real ewald_spline3_table_scale(const interaction_const_t& ic, bool generateCoulombTables, bool generateVdwTables); /*! \brief Return the real space grid contribution for Ewald * @@ -132,9 +130,7 @@ double v_lj_ewald_lr(double beta, double r); * * \return Pointer to inner loop table structure */ -t_forcetable *make_tables(FILE *fp, - const interaction_const_t *ic, - const char *fn, real rtab, int flags); +t_forcetable* make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, int flags); /*! \brief Return a table for bonded interactions, * @@ -143,7 +139,7 @@ t_forcetable *make_tables(FILE *fp, * \param angle Type of angle: bonds 0, angles 1, dihedrals 2 * \return New bonded table datatype */ -bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle); +bondedtable_t make_bonded_table(FILE* fplog, const char* fn, int angle); /*! \brief Construct and return tabulated dispersion and repulsion interactions * @@ -151,7 +147,6 @@ bondedtable_t make_bonded_table(FILE *fplog, const char *fn, int angle); * Returns pointer owning nothing when tabfn=nullptr. */ std::unique_ptr -makeDispersionCorrectionTable(FILE *fp, const interaction_const_t *ic, - real rtab, const char *tabfn); +makeDispersionCorrectionTable(FILE* fp, const interaction_const_t* ic, real rtab, const char* tabfn); -#endif /* GMX_TABLES_FORCETABLE_H */ +#endif /* GMX_TABLES_FORCETABLE_H */ diff --git a/src/gromacs/tables/quadraticsplinetable.cpp b/src/gromacs/tables/quadraticsplinetable.cpp index 04b32c171a..2733b2e961 100644 --- a/src/gromacs/tables/quadraticsplinetable.cpp +++ b/src/gromacs/tables/quadraticsplinetable.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,26 +75,25 @@ namespace * \param[out] functionTableData Output table with function data * \param[out] derivativeTableData OUtput table with (adjusted) derivative data */ -void -fillSingleQuadraticSplineTableData(const std::function &function, - const std::function &derivative, - const std::pair &range, - double spacing, - std::vector *functionTableData, - std::vector *derivativeTableData) +void fillSingleQuadraticSplineTableData(const std::function& function, + const std::function& derivative, + const std::pair& range, + double spacing, + std::vector* functionTableData, + std::vector* derivativeTableData) { - std::size_t endIndex = static_cast(range.second / spacing + 2); + std::size_t endIndex = static_cast(range.second / spacing + 2); functionTableData->resize(endIndex); derivativeTableData->resize(endIndex); - double maxMagnitude = 0.0001*GMX_REAL_MAX; - bool functionIsInRange = true; - std::size_t lastIndexInRange = endIndex - 1; + double maxMagnitude = 0.0001 * GMX_REAL_MAX; + bool functionIsInRange = true; + std::size_t lastIndexInRange = endIndex - 1; for (int i = endIndex - 1; i >= 0; i--) { - double x = i * spacing; + double x = i * spacing; double tmpFunctionValue; double tmpDerivativeValue; @@ -112,11 +111,12 @@ fillSingleQuadraticSplineTableData(const std::function &functi // Calculate third derivative term (2nd derivative of the derivative) // Make sure we stay in range. In practice this means we use one-sided // interpolation at the interval endpoints (indentical to an offset for 3-point formula) - const double h = std::pow( GMX_DOUBLE_EPS, 0.25 ); - double y = std::min( std::max(x, range.first + h), range.second - h); - double thirdDerivativeValue = ( derivative(y+h) - 2.0 * derivative(y) + derivative(y-h) ) / ( h * h ); + const double h = std::pow(GMX_DOUBLE_EPS, 0.25); + double y = std::min(std::max(x, range.first + h), range.second - h); + double thirdDerivativeValue = + (derivative(y + h) - 2.0 * derivative(y) + derivative(y - h)) / (h * h); - tmpDerivativeValue = derivative(x) - spacing * spacing * thirdDerivativeValue / 12.0; + tmpDerivativeValue = derivative(x) - spacing * spacing * thirdDerivativeValue / 12.0; if (std::abs(tmpFunctionValue) > maxMagnitude || std::abs(tmpDerivativeValue) > maxMagnitude) { @@ -136,8 +136,9 @@ fillSingleQuadraticSplineTableData(const std::function &functi // we simply make a linear function from the last in-range value of the derivative. double lastIndexFunction = (*functionTableData)[lastIndexInRange]; double lastIndexDerivative = (*derivativeTableData)[lastIndexInRange]; - (*functionTableData)[i] = lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; - (*derivativeTableData)[i] = lastIndexDerivative; + (*functionTableData)[i] = + lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; + (*derivativeTableData)[i] = lastIndexDerivative; } } } @@ -153,29 +154,28 @@ fillSingleQuadraticSplineTableData(const std::function &functi * \param[out] functionTableData Output table with function data * \param[out] derivativeTableData OUtput table with (adjusted) derivative data */ -void -fillSingleQuadraticSplineTableData(ArrayRef function, - ArrayRef derivative, - double inputSpacing, - const std::pair &range, - double spacing, - std::vector *functionTableData, - std::vector *derivativeTableData) +void fillSingleQuadraticSplineTableData(ArrayRef function, + ArrayRef derivative, + double inputSpacing, + const std::pair& range, + double spacing, + std::vector* functionTableData, + std::vector* derivativeTableData) { - std::size_t endIndex = static_cast(range.second / spacing + 2); + std::size_t endIndex = static_cast(range.second / spacing + 2); functionTableData->resize(endIndex); derivativeTableData->resize(endIndex); - std::vector thirdDerivative(internal::vectorSecondDerivative(derivative, inputSpacing)); + std::vector thirdDerivative(internal::vectorSecondDerivative(derivative, inputSpacing)); - double maxMagnitude = 0.0001*GMX_REAL_MAX; - bool functionIsInRange = true; - std::size_t lastIndexInRange = endIndex - 1; + double maxMagnitude = 0.0001 * GMX_REAL_MAX; + bool functionIsInRange = true; + std::size_t lastIndexInRange = endIndex - 1; for (int i = endIndex - 1; i >= 0; i--) { - double x = i * spacing; + double x = i * spacing; double tmpFunctionValue; double tmpDerivativeValue; @@ -194,12 +194,15 @@ fillSingleQuadraticSplineTableData(ArrayRef functi double inputEps = inputXTab - inputIndex; // Linear interpolation of input derivative and third derivative - double thirdDerivativeValue = (1.0 - inputEps) * thirdDerivative[inputIndex] + inputEps * thirdDerivative[inputIndex+1]; - double derivativeValue = (1.0 - inputEps) * derivative[inputIndex] + inputEps * derivative[inputIndex+1]; + double thirdDerivativeValue = (1.0 - inputEps) * thirdDerivative[inputIndex] + + inputEps * thirdDerivative[inputIndex + 1]; + double derivativeValue = + (1.0 - inputEps) * derivative[inputIndex] + inputEps * derivative[inputIndex + 1]; // Quadratic interpolation for function value - tmpFunctionValue = function[inputIndex] + 0.5 * (derivative[inputIndex] + derivativeValue) * inputEps * inputSpacing; - tmpDerivativeValue = derivativeValue - spacing * spacing * thirdDerivativeValue / 12.0; + tmpFunctionValue = function[inputIndex] + + 0.5 * (derivative[inputIndex] + derivativeValue) * inputEps * inputSpacing; + tmpDerivativeValue = derivativeValue - spacing * spacing * thirdDerivativeValue / 12.0; if (std::abs(tmpFunctionValue) > maxMagnitude || std::abs(tmpDerivativeValue) > maxMagnitude) { @@ -219,8 +222,9 @@ fillSingleQuadraticSplineTableData(ArrayRef functi // we simply make a linear function from the last in-range value of the derivative. double lastIndexFunction = (*functionTableData)[lastIndexInRange]; double lastIndexDerivative = (*derivativeTableData)[lastIndexInRange]; - (*functionTableData)[i] = lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; - (*derivativeTableData)[i] = lastIndexDerivative; + (*functionTableData)[i] = + lastIndexFunction + lastIndexDerivative * (i - lastIndexInRange) * spacing; + (*derivativeTableData)[i] = lastIndexDerivative; } } } @@ -238,12 +242,12 @@ fillSingleQuadraticSplineTableData(ArrayRef functi * * \throws If the vector lengths do not match. */ -void -fillDdfzTableData(const std::vector &functionTableData, - const std::vector &derivativeTableData, - std::vector *ddfzTableData) +void fillDdfzTableData(const std::vector& functionTableData, + const std::vector& derivativeTableData, + std::vector* ddfzTableData) { - GMX_ASSERT(functionTableData.size() == derivativeTableData.size(), "Mismatching vector lengths"); + GMX_ASSERT(functionTableData.size() == derivativeTableData.size(), + "Mismatching vector lengths"); std::size_t points = functionTableData.size(); @@ -251,33 +255,33 @@ fillDdfzTableData(const std::vector &functionTableData, for (std::size_t i = 0; i < points; i++) { - (*ddfzTableData)[4*i] = derivativeTableData[i]; + (*ddfzTableData)[4 * i] = derivativeTableData[i]; - double nextDerivative = ( i < functionTableData.size() - 1 ) ? derivativeTableData[i+1] : 0.0; + double nextDerivative = (i < functionTableData.size() - 1) ? derivativeTableData[i + 1] : 0.0; - (*ddfzTableData)[4*i + 1] = nextDerivative - derivativeTableData[i]; - (*ddfzTableData)[4*i + 2] = functionTableData[i]; - (*ddfzTableData)[4*i + 3] = 0.0; + (*ddfzTableData)[4 * i + 1] = nextDerivative - derivativeTableData[i]; + (*ddfzTableData)[4 * i + 2] = functionTableData[i]; + (*ddfzTableData)[4 * i + 3] = 0.0; } } -} // namespace +} // namespace +const real QuadraticSplineTable::defaultTolerance = 10.0 * GMX_FLOAT_EPS; -const real -QuadraticSplineTable::defaultTolerance = 10.0 * GMX_FLOAT_EPS; - -QuadraticSplineTable::QuadraticSplineTable(std::initializer_list analyticalInputList, - const std::pair &range, - real tolerance) - : numFuncInTable_(analyticalInputList.size()), range_(range) +QuadraticSplineTable::QuadraticSplineTable(std::initializer_list analyticalInputList, + const std::pair& range, + real tolerance) : + numFuncInTable_(analyticalInputList.size()), + range_(range) { // Sanity check on input values - if (range_.first < 0.0 || (range_.second-range_.first) < 0.001) + if (range_.first < 0.0 || (range_.second - range_.first) < 0.001) { - GMX_THROW(InvalidInputError("Range to tabulate cannot include negative values and must span at least 0.001")); + GMX_THROW(InvalidInputError( + "Range to tabulate cannot include negative values and must span at least 0.001")); } if (tolerance < GMX_REAL_EPS) @@ -288,15 +292,17 @@ QuadraticSplineTable::QuadraticSplineTable(std::initializer_list 1e6) { - GMX_THROW(ToleranceError("Over a million points would be required for table; decrease range or increase tolerance")); + GMX_THROW( + ToleranceError("Over a million points would be required for table; decrease range " + "or increase tolerance")); } // Loop over all tables again. @@ -324,7 +333,7 @@ QuadraticSplineTable::QuadraticSplineTable(std::initializer_list tmpDerTableData; std::vector tmpDdfzTableData; - fillSingleQuadraticSplineTableData(thisFuncInput.function, - thisFuncInput.derivative, - range_, - spacing, - &tmpFuncTableData, - &tmpDerTableData); + fillSingleQuadraticSplineTableData(thisFuncInput.function, thisFuncInput.derivative, + range_, spacing, &tmpFuncTableData, &tmpDerTableData); fillDdfzTableData(tmpFuncTableData, tmpDerTableData, &tmpDdfzTableData); - internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, - 1, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, 1, + numFuncInTable_, funcIndex); - internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, - 4, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, 4, + numFuncInTable_, funcIndex); funcIndex++; } - catch (gmx::GromacsException &ex) + catch (gmx::GromacsException& ex) { - ex.prependContext("Error generating quadratic spline table for function '" + thisFuncInput.desc + "'"); + ex.prependContext("Error generating quadratic spline table for function '" + + thisFuncInput.desc + "'"); throw; } } } -QuadraticSplineTable::QuadraticSplineTable(std::initializer_list numericalInputList, - const std::pair &range, - real tolerance) - : numFuncInTable_(numericalInputList.size()), range_(range) +QuadraticSplineTable::QuadraticSplineTable(std::initializer_list numericalInputList, + const std::pair& range, + real tolerance) : + numFuncInTable_(numericalInputList.size()), + range_(range) { // Sanity check on input values - if (range.first < 0.0 || (range.second-range.first) < 0.001) + if (range.first < 0.0 || (range.second - range.first) < 0.001) { - GMX_THROW(InvalidInputError("Range to tabulate cannot include negative values and must span at least 0.001")); + GMX_THROW(InvalidInputError( + "Range to tabulate cannot include negative values and must span at least 0.001")); } if (tolerance < GMX_REAL_EPS) @@ -385,19 +393,24 @@ QuadraticSplineTable::QuadraticSplineTable(std::initializer_list 1e6) { - GMX_THROW(ToleranceError("Requested tolerance would require over a million points in table")); + GMX_THROW( + ToleranceError("Requested tolerance would require over a million points in table")); } // Loop over all tables again. @@ -434,34 +449,32 @@ QuadraticSplineTable::QuadraticSplineTable(std::initializer_list tmpFuncTableData; std::vector tmpDerTableData; std::vector tmpDdfzTableData; - fillSingleQuadraticSplineTableData(thisFuncInput.function, - thisFuncInput.derivative, - thisFuncInput.spacing, - range, - spacing, - &tmpFuncTableData, - &tmpDerTableData); + fillSingleQuadraticSplineTableData(thisFuncInput.function, thisFuncInput.derivative, + thisFuncInput.spacing, range, spacing, + &tmpFuncTableData, &tmpDerTableData); fillDdfzTableData(tmpFuncTableData, tmpDerTableData, &tmpDdfzTableData); - internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, - 1, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpDerTableData, &derivativeMultiTableData_, 1, + numFuncInTable_, funcIndex); - internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, - 4, numFuncInTable_, funcIndex); + internal::fillMultiplexedTableData(tmpDdfzTableData, &ddfzMultiTableData_, 4, + numFuncInTable_, funcIndex); funcIndex++; } - catch (gmx::GromacsException &ex) + catch (gmx::GromacsException& ex) { - ex.prependContext("Error generating quadratic spline table for function '" + thisFuncInput.desc + "'"); + ex.prependContext("Error generating quadratic spline table for function '" + + thisFuncInput.desc + "'"); throw; } } diff --git a/src/gromacs/tables/quadraticsplinetable.h b/src/gromacs/tables/quadraticsplinetable.h index 010372d12d..5c74216190 100644 --- a/src/gromacs/tables/quadraticsplinetable.h +++ b/src/gromacs/tables/quadraticsplinetable.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -120,8 +120,8 @@ namespace gmx * Summing the equations leads to * * \f[ - * 2 \Delta V = h(V'(0) + V'(h)) + \frac{1}{2} h^2 (V''(0)-V''(h)) + \frac{1}{6}h^3(V'''(0)+V'''(h)) + O(h^4) - * \f] + * 2 \Delta V = h(V'(0) + V'(h)) + \frac{1}{2} h^2 (V''(0)-V''(h)) + + * \frac{1}{6}h^3(V'''(0)+V'''(h)) + O(h^4) \f] * * To make the second term symmetric too, we can replace it with the average of * the Taylor expansion at 0 and h (i.e., using the third derivative). This gives @@ -174,575 +174,586 @@ namespace gmx */ class QuadraticSplineTable { - private: - /*! \brief Change that function value falls inside range when debugging - * - * \tparam T Lookup argument floating-point type, typically SimdReal or real. - * \param r Lookup argument to test - * - * \throws Debug builds will throw gmx::RangeError for values that are - * larger than the upper limit of the range, or smaller than 0. - * We allow the table to be called with arguments between 0 and - * the lower limit of the range, since this might in theory occur - * once-in-a-blue-moon with some algorithms. - */ - template - void - rangeCheck(T gmx_unused r) const - { +private: + /*! \brief Change that function value falls inside range when debugging + * + * \tparam T Lookup argument floating-point type, typically SimdReal or real. + * \param r Lookup argument to test + * + * \throws Debug builds will throw gmx::RangeError for values that are + * larger than the upper limit of the range, or smaller than 0. + * We allow the table to be called with arguments between 0 and + * the lower limit of the range, since this might in theory occur + * once-in-a-blue-moon with some algorithms. + */ + template + void rangeCheck(T gmx_unused r) const + { #ifndef NDEBUG - // Check that all values fall in range when debugging - if (anyTrue( r < T(0.0) || T(range_.second) <= r ) ) - { - GMX_THROW(RangeError("Interpolation input value falls outside table definition range")); - } -#endif - } - - public: - - /*! \brief Default tolerance for tables is 10*GMX_FLOAT_EPS - * - * \note Even for double precision builds we set the tolerance to - * one order of magnitude above the single precision epsilon. - */ - static const real defaultTolerance; - - /*! \brief Initialize table data from function - * - * \param analyticalInputList Initializer list with one or more functions to tabulate, - * specified as pairs containing analytical - * functions and their derivatives. The function will also - * be called for values smaller than the lower limit of the - * range, but we avoid calling it for 0.0 if that value - * is not included in the range. - * \param range Range over which the function will be tabulated. - * Constructor will throw gmx::APIError for negative values. - * Due to the way the numerical derivative evaluation depends - * on machine precision internally, this range must be - * at least 0.001, or the constructor throws gmx::APIError. - * \param tolerance Requested accuracy of the table. This will be used to - * calculate the required internal spacing. If this cannot - * be achieved (for instance because the table would require - * too much memory) the constructor will throw gmx::ToleranceError. - * - * \note The functions are always defined in double precision to avoid - * losing accuracy when constructing tables. - * - * \note Since we fill the table for values below range.first, you can achieve - * a smaller table by using a smaller range where the tolerance has to be - * met, and accept that a few function calls below range.first do not - * quite reach the tolerance. - * - * \warning For efficiency reasons (since this code is used in some inner - * (kernels), we always allocate memory and calculate table indices - * for the complete interval [0,range.second], although the data will - * not be valid outside the definition range to avoid calling the - * function there. This means you should \a not use this class - * to tabulate functions for small ranges very far away from zero, - * since you would both waste a huge amount of memory and incur - * truncation errors when calculating the index. - * - * \throws gmx::ToleranceError if the requested tolerance cannot be achieved, - * and gmx::APIError for other incorrect input. - */ - QuadraticSplineTable(std::initializer_list analyticalInputList, - const std::pair &range, - real tolerance = defaultTolerance); - - /*! \brief Initialize table data from tabulated values and derivatives - * - * \param numericalInputList Initializer list with one or more functions to tabulate, - * specified as pairs containing containing vectors for the - * function values and their derivatives. Data points are - * separated by the spacing parameter, starting from 0. - * Values below the lower limit of the range will be used to - * attempt defining the table, but we avoid using index 0 - * unless 0.0 is included in the range. Some extra points beyond - * range.second are required to re-interpolate values, so add - * some margin. The constructor will throw gmx::APIError if the - * input vectors are too short to cover the requested range - * (and they must always be at least five points). - * \param range Range over which the function will be tabulated. - * Constructor will throw gmx::APIError for negative values, - * or if the value/derivative vector does not cover the - * range. - * \param tolerance Requested accuracy of the table in the range. This will be - * used to calculate the required internal spacing and possibly - * re-interpolate. The constructor will throw - * gmx::ToleranceError if the input spacing is too coarse - * to achieve this accuracy. - * - * \note The input data vectors are always double precision to avoid - * losing accuracy when constructing tables. - * - * \note Since we fill the table for values below range.first, you can achieve - * a smaller table by using a smaller range where the tolerance has to be - * met, and accept that a few function calls below range.first do not - * quite reach the tolerance. - * - * \warning For efficiency reasons (since this code is used in some inner - * (kernels), we always allocate memory and calculate table indices - * for the complete interval [0,range.second], although the data will - * not be valid outside the definition range to avoid calling the - * function there. This means you should \a not use this class - * to tabulate functions for small ranges very far away from zero, - * since you would both waste a huge amount of memory and incur - * truncation errors when calculating the index. - */ - QuadraticSplineTable(std::initializer_list numericalInputList, - const std::pair &range, - real tolerance = defaultTolerance); - - - /************************************************************ - * Evaluation methods for single functions * - ************************************************************/ - - /*! \brief Evaluate both function and derivative, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue Function value - * \param[out] derivativeValue Function derivative - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue, - T * derivativeValue) const + // Check that all values fall in range when debugging + if (anyTrue(r < T(0.0) || T(range_.second) <= r)) { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T t0; - T t1; - T t2; - T t3 gmx_unused; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4 * funcIndex, tabIndex, &t0, &t1, &t2, &t3); - - t1 = t0 + eps * t1; - *functionValue = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue = t1; + GMX_THROW(RangeError("Interpolation input value falls outside table definition range")); } - - /*! \brief Evaluate function value only, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue Function value - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue) const - { - T der gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue, &der); - } - - /*! \brief Evaluate function derivative only, single table function - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 1 - * \tparam funcIndex Index of function to evaluate in table, default is 0 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue Function derivative - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue) const - { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T t0; - T t1; - T t2 gmx_unused; - - if (numFuncInTable == 1) - { - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, tabIndex, &t0, &t1); // works for scalar T too - } - else - { - // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that - // only loads a single value from memory to implement it better (will be written) - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, tabIndex + T(1), &t1, &t2); // works for scalar T too - } - - // (1-eps)*t0 + eps*t1 - *derivativeValue = fma(t1-t0, eps, t0); - } - - /************************************************************ - * Evaluation methods for two functions * - ************************************************************/ - - /*! \brief Evaluate both function and derivative, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue1 Interpolated value for first function - * \param[out] derivativeValue1 Interpolated derivative for first function - * \param[out] functionValue2 Interpolated value for second function - * \param[out] derivativeValue2 Interpolated derivative for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue1, - T * derivativeValue1, - T * functionValue2, - T * derivativeValue2) const +#endif + } + +public: + /*! \brief Default tolerance for tables is 10*GMX_FLOAT_EPS + * + * \note Even for double precision builds we set the tolerance to + * one order of magnitude above the single precision epsilon. + */ + static const real defaultTolerance; + + /*! \brief Initialize table data from function + * + * \param analyticalInputList Initializer list with one or more functions to tabulate, + * specified as pairs containing analytical + * functions and their derivatives. The function will also + * be called for values smaller than the lower limit of the + * range, but we avoid calling it for 0.0 if that value + * is not included in the range. + * \param range Range over which the function will be tabulated. + * Constructor will throw gmx::APIError for negative values. + * Due to the way the numerical derivative evaluation depends + * on machine precision internally, this range must be + * at least 0.001, or the constructor throws gmx::APIError. + * \param tolerance Requested accuracy of the table. This will be used to + * calculate the required internal spacing. If this cannot + * be achieved (for instance because the table would require + * too much memory) the constructor will throw gmx::ToleranceError. + * + * \note The functions are always defined in double precision to avoid + * losing accuracy when constructing tables. + * + * \note Since we fill the table for values below range.first, you can achieve + * a smaller table by using a smaller range where the tolerance has to be + * met, and accept that a few function calls below range.first do not + * quite reach the tolerance. + * + * \warning For efficiency reasons (since this code is used in some inner + * (kernels), we always allocate memory and calculate table indices + * for the complete interval [0,range.second], although the data will + * not be valid outside the definition range to avoid calling the + * function there. This means you should \a not use this class + * to tabulate functions for small ranges very far away from zero, + * since you would both waste a huge amount of memory and incur + * truncation errors when calculating the index. + * + * \throws gmx::ToleranceError if the requested tolerance cannot be achieved, + * and gmx::APIError for other incorrect input. + */ + QuadraticSplineTable(std::initializer_list analyticalInputList, + const std::pair& range, + real tolerance = defaultTolerance); + + /*! \brief Initialize table data from tabulated values and derivatives + * + * \param numericalInputList Initializer list with one or more functions to tabulate, + * specified as pairs containing containing vectors for the + * function values and their derivatives. Data points are + * separated by the spacing parameter, starting from 0. + * Values below the lower limit of the range will be used to + * attempt defining the table, but we avoid using index 0 + * unless 0.0 is included in the range. Some extra points beyond + * range.second are required to re-interpolate values, so add + * some margin. The constructor will throw gmx::APIError if the + * input vectors are too short to cover the requested range + * (and they must always be at least five points). + * \param range Range over which the function will be tabulated. + * Constructor will throw gmx::APIError for negative values, + * or if the value/derivative vector does not cover the + * range. + * \param tolerance Requested accuracy of the table in the range. This will be + * used to calculate the required internal spacing and possibly + * re-interpolate. The constructor will throw + * gmx::ToleranceError if the input spacing is too coarse + * to achieve this accuracy. + * + * \note The input data vectors are always double precision to avoid + * losing accuracy when constructing tables. + * + * \note Since we fill the table for values below range.first, you can achieve + * a smaller table by using a smaller range where the tolerance has to be + * met, and accept that a few function calls below range.first do not + * quite reach the tolerance. + * + * \warning For efficiency reasons (since this code is used in some inner + * (kernels), we always allocate memory and calculate table indices + * for the complete interval [0,range.second], although the data will + * not be valid outside the definition range to avoid calling the + * function there. This means you should \a not use this class + * to tabulate functions for small ranges very far away from zero, + * since you would both waste a huge amount of memory and incur + * truncation errors when calculating the index. + */ + QuadraticSplineTable(std::initializer_list numericalInputList, + const std::pair& range, + real tolerance = defaultTolerance); + + + /************************************************************ + * Evaluation methods for single functions * + ************************************************************/ + + /*! \brief Evaluate both function and derivative, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue Function value + * \param[out] derivativeValue Function derivative + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, T* functionValue, T* derivativeValue) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T t0; + T t1; + T t2; + T t3 gmx_unused; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>(ddfzMultiTableData_.data() + 4 * funcIndex, + tabIndex, &t0, &t1, &t2, &t3); + + t1 = t0 + eps * t1; + *functionValue = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue = t1; + } + + /*! \brief Evaluate function value only, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue Function value + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue) const + { + T der gmx_unused; + + evaluateFunctionAndDerivative(r, functionValue, &der); + } + + /*! \brief Evaluate function derivative only, single table function + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 1 + * \tparam funcIndex Index of function to evaluate in table, default is 0 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue Function derivative + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T t0; + T t1; + T t2 gmx_unused; + + if (numFuncInTable == 1) { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T t0; - T t1; - T t2; - T t3 gmx_unused; - - // Load Derivative, Delta, Function, and Zero values for each table point. - // The 4 refers to these four values - not any SIMD width. - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4*funcIndex0, tabIndex, &t0, &t1, &t2, &t3); - t1 = t0 + eps * t1; - *functionValue1 = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue1 = t1; - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4*funcIndex1, tabIndex, &t0, &t1, &t2, &t3); - t1 = t0 + eps * t1; - *functionValue2 = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue2 = t1; + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, + tabIndex, &t0, &t1); // works for scalar T too } - - /*! \brief Evaluate function value only, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue1 Interpolated value for first function - * \param[out] functionValue2 Interpolated value for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue1, - T * functionValue2) const + else { - T der1 gmx_unused; - T der2 gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue1, &der1, functionValue2, &der2); + // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that + // only loads a single value from memory to implement it better (will be written) + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex, + tabIndex + T(1), &t1, + &t2); // works for scalar T too } - /*! \brief Evaluate function derivative only, two table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 2 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue1 Interpolated derivative for first function - * \param[out] derivativeValue2 Interpolated derivative for second function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue1, - T * derivativeValue2) const + // (1-eps)*t0 + eps*t1 + *derivativeValue = fma(t1 - t0, eps, t0); + } + + /************************************************************ + * Evaluation methods for two functions * + ************************************************************/ + + /*! \brief Evaluate both function and derivative, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue1 Interpolated value for first function + * \param[out] derivativeValue1 Interpolated derivative for first function + * \param[out] functionValue2 Interpolated value for second function + * \param[out] derivativeValue2 Interpolated derivative for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, T* functionValue1, T* derivativeValue1, T* functionValue2, T* derivativeValue2) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T t0; + T t1; + T t2; + T t3 gmx_unused; + + // Load Derivative, Delta, Function, and Zero values for each table point. + // The 4 refers to these four values - not any SIMD width. + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + ddfzMultiTableData_.data() + 4 * funcIndex0, tabIndex, &t0, &t1, &t2, &t3); + t1 = t0 + eps * t1; + *functionValue1 = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue1 = t1; + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + ddfzMultiTableData_.data() + 4 * funcIndex1, tabIndex, &t0, &t1, &t2, &t3); + t1 = t0 + eps * t1; + *functionValue2 = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue2 = t1; + } + + /*! \brief Evaluate function value only, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue1 Interpolated value for first function + * \param[out] functionValue2 Interpolated value for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue1, T* functionValue2) const + { + T der1 gmx_unused; + T der2 gmx_unused; + + evaluateFunctionAndDerivative( + r, functionValue1, &der1, functionValue2, &der2); + } + + /*! \brief Evaluate function derivative only, two table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 2 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue1 Interpolated derivative for first function + * \param[out] derivativeValue2 Interpolated derivative for second function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue1, T* derivativeValue2) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + + if (numFuncInTable == 2 && funcIndex0 == 0 && funcIndex1 == 1) { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable, "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - - if (numFuncInTable == 2 && funcIndex0 == 0 && funcIndex1 == 1) - { - T t0A, t0B, t1A, t1B; - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data(), tabIndex, &t0A, &t0B); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 2, tabIndex, &t1A, &t1B); // works for scalar T too - *derivativeValue1 = fma(t1A-t0A, eps, t0A); - *derivativeValue2 = fma(t1B-t0B, eps, t0B); - } - else - { - T t0, t1, t2; - // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that - // only loads a single value from memory to implement it better (will be written) - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, tabIndex + T(1), &t1, &t2); // works for scalar T too - *derivativeValue1 = fma(t1-t0, eps, t0); - - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, tabIndex + T(1), &t1, &t2); // works for scalar T too - *derivativeValue2 = fma(t1-t0, eps, t0); - } + T t0A, t0B, t1A, t1B; + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data(), tabIndex, + &t0A, &t0B); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 2, tabIndex, + &t1A, &t1B); // works for scalar T too + *derivativeValue1 = fma(t1A - t0A, eps, t0A); + *derivativeValue2 = fma(t1B - t0B, eps, t0B); } - - /************************************************************ - * Evaluation methods for three functions * - ************************************************************/ - - - /*! \brief Evaluate both function and derivative, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function and derivative - * \param[out] functionValue1 Interpolated value for first function - * \param[out] derivativeValue1 Interpolated derivative for first function - * \param[out] functionValue2 Interpolated value for second function - * \param[out] derivativeValue2 Interpolated derivative for second function - * \param[out] functionValue3 Interpolated value for third function - * \param[out] derivativeValue3 Interpolated derivative for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunctionAndDerivative(T r, - T * functionValue1, - T * derivativeValue1, - T * functionValue2, - T * derivativeValue2, - T * functionValue3, - T * derivativeValue3) const + else { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, - "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - T t0; - T t1; - T t2; - T t3 gmx_unused; - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4*funcIndex0, tabIndex, &t0, &t1, &t2, &t3); - t1 = t0 + eps * t1; - *functionValue1 = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue1 = t1; - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4*funcIndex1, tabIndex, &t0, &t1, &t2, &t3); - t1 = t0 + eps * t1; - *functionValue2 = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue2 = t1; - - gatherLoadBySimdIntTranspose<4*numFuncInTable>(ddfzMultiTableData_.data() + 4*funcIndex2, tabIndex, &t0, &t1, &t2, &t3); - t1 = t0 + eps * t1; - *functionValue3 = fma( eps * T(halfSpacing_), t0 + t1, t2); - *derivativeValue3 = t1; + T t0, t1, t2; + // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that + // only loads a single value from memory to implement it better (will be written) + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, + tabIndex + T(1), &t1, + &t2); // works for scalar T too + *derivativeValue1 = fma(t1 - t0, eps, t0); + + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, + tabIndex + T(1), &t1, + &t2); // works for scalar T too + *derivativeValue2 = fma(t1 - t0, eps, t0); } - - /*! \brief Evaluate function value only, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function value - * \param[out] functionValue1 Interpolated value for first function - * \param[out] functionValue2 Interpolated value for second function - * \param[out] functionValue3 Interpolated value for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateFunction(T r, - T * functionValue1, - T * functionValue2, - T * functionValue3) const + } + + /************************************************************ + * Evaluation methods for three functions * + ************************************************************/ + + + /*! \brief Evaluate both function and derivative, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function and derivative + * \param[out] functionValue1 Interpolated value for first function + * \param[out] derivativeValue1 Interpolated derivative for first function + * \param[out] functionValue2 Interpolated value for second function + * \param[out] derivativeValue2 Interpolated derivative for second function + * \param[out] functionValue3 Interpolated value for third function + * \param[out] derivativeValue3 Interpolated derivative for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunctionAndDerivative(T r, + T* functionValue1, + T* derivativeValue1, + T* functionValue2, + T* derivativeValue2, + T* functionValue3, + T* derivativeValue3) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + T t0; + T t1; + T t2; + T t3 gmx_unused; + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + ddfzMultiTableData_.data() + 4 * funcIndex0, tabIndex, &t0, &t1, &t2, &t3); + t1 = t0 + eps * t1; + *functionValue1 = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue1 = t1; + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + ddfzMultiTableData_.data() + 4 * funcIndex1, tabIndex, &t0, &t1, &t2, &t3); + t1 = t0 + eps * t1; + *functionValue2 = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue2 = t1; + + gatherLoadBySimdIntTranspose<4 * numFuncInTable>( + ddfzMultiTableData_.data() + 4 * funcIndex2, tabIndex, &t0, &t1, &t2, &t3); + t1 = t0 + eps * t1; + *functionValue3 = fma(eps * T(halfSpacing_), t0 + t1, t2); + *derivativeValue3 = t1; + } + + /*! \brief Evaluate function value only, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function value + * \param[out] functionValue1 Interpolated value for first function + * \param[out] functionValue2 Interpolated value for second function + * \param[out] functionValue3 Interpolated value for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateFunction(T r, T* functionValue1, T* functionValue2, T* functionValue3) const + { + T der1 gmx_unused; + T der2 gmx_unused; + T der3 gmx_unused; + + evaluateFunctionAndDerivative( + r, functionValue1, &der1, functionValue2, &der2, functionValue3, &der3); + } + + /*! \brief Evaluate function derivative only, three table functions + * + * This is a templated method where the template can be either real or SimdReal. + * + * \tparam numFuncInTable Number of separate functions in table, default is 3 + * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 + * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 + * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 + * \tparam T Type (SimdReal or real) of lookup and result + * \param r Points for which to evaluate function derivative + * \param[out] derivativeValue1 Interpolated derivative for first function + * \param[out] derivativeValue2 Interpolated derivative for second function + * \param[out] derivativeValue3 Interpolated derivative for third function + * + * For debug builds we assert that the input values fall in the range + * specified when constructing the table. + */ + template + void evaluateDerivative(T r, T* derivativeValue1, T* derivativeValue2, T* derivativeValue3) const + { + rangeCheck(r); + GMX_ASSERT(numFuncInTable == numFuncInTable_, + "Evaluation method not matching number of functions in table"); + GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, + "Function index not in range of the number of tables"); + + T rTable = r * T(tableScale_); + auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 + T eps = rTable - trunc(rTable); + + if (numFuncInTable == 3 && funcIndex0 == 0 && funcIndex1 == 1 && funcIndex2 == 2) { - T der1 gmx_unused; - T der2 gmx_unused; - T der3 gmx_unused; - - evaluateFunctionAndDerivative(r, functionValue1, &der1, functionValue2, &der2, functionValue3, &der3); + T t0A, t0B, t0C, t1A, t1B, t1C; + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data(), + tabIndex, &t0A, &t0B); + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 2, + tabIndex, &t0C, &t1A); + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 4, + tabIndex, &t1B, &t1C); + *derivativeValue1 = fma(t1A - t0A, eps, t0A); + *derivativeValue2 = fma(t1B - t0B, eps, t0B); + *derivativeValue3 = fma(t1C - t0C, eps, t0C); } - - /*! \brief Evaluate function derivative only, three table functions - * - * This is a templated method where the template can be either real or SimdReal. - * - * \tparam numFuncInTable Number of separate functions in table, default is 3 - * \tparam funcIndex0 Index of 1st function to evaluate in table, default is 0 - * \tparam funcIndex1 Index of 2nd function to evaluate in table, default is 1 - * \tparam funcIndex2 Index of 3rd function to evaluate in table, default is 2 - * \tparam T Type (SimdReal or real) of lookup and result - * \param r Points for which to evaluate function derivative - * \param[out] derivativeValue1 Interpolated derivative for first function - * \param[out] derivativeValue2 Interpolated derivative for second function - * \param[out] derivativeValue3 Interpolated derivative for third function - * - * For debug builds we assert that the input values fall in the range - * specified when constructing the table. - */ - template - void - evaluateDerivative(T r, - T * derivativeValue1, - T * derivativeValue2, - T * derivativeValue3) const + else { - rangeCheck(r); - GMX_ASSERT(numFuncInTable == numFuncInTable_, "Evaluation method not matching number of functions in table"); - GMX_ASSERT(funcIndex0 < numFuncInTable && funcIndex1 < numFuncInTable && funcIndex2 < numFuncInTable, - "Function index not in range of the number of tables"); - - T rTable = r * T(tableScale_); - auto tabIndex = cvttR2I(rTable); // type is either std::int32_t or SimdInt32 - T eps = rTable - trunc(rTable); - - if (numFuncInTable == 3 && funcIndex0 == 0 && funcIndex1 == 1 && funcIndex2 == 2) - { - T t0A, t0B, t0C, t1A, t1B, t1C; - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data(), tabIndex, &t0A, &t0B); - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 2, tabIndex, &t0C, &t1A); - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + 4, tabIndex, &t1B, &t1C); - *derivativeValue1 = fma(t1A-t0A, eps, t0A); - *derivativeValue2 = fma(t1B-t0B, eps, t0B); - *derivativeValue3 = fma(t1C-t0C, eps, t0C); - } - else - { - T t0, t1, t2; - // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that - // only loads a single value from memory to implement it better (will be written) - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, tabIndex + T(1), &t1, &t2); // works for scalar T too - *derivativeValue1 = fma(t1-t0, eps, t0); - - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, tabIndex + T(1), &t1, &t2); // works for scalar T too - *derivativeValue2 = fma(t1-t0, eps, t0); - - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex2, tabIndex, &t0, &t2); // works for scalar T too - gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex2, tabIndex + T(1), &t1, &t2); // works for scalar T too - *derivativeValue3 = fma(t1-t0, eps, t0); - } + T t0, t1, t2; + // This is not ideal, but we need a version of gatherLoadUBySimdIntTranspose that + // only loads a single value from memory to implement it better (will be written) + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex0, + tabIndex + T(1), &t1, + &t2); // works for scalar T too + *derivativeValue1 = fma(t1 - t0, eps, t0); + + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex1, + tabIndex + T(1), &t1, + &t2); // works for scalar T too + *derivativeValue2 = fma(t1 - t0, eps, t0); + + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex2, + tabIndex, &t0, &t2); // works for scalar T too + gatherLoadUBySimdIntTranspose(derivativeMultiTableData_.data() + funcIndex2, + tabIndex + T(1), &t1, + &t2); // works for scalar T too + *derivativeValue3 = fma(t1 - t0, eps, t0); } - - /*! \brief Return the table spacing (distance between points) - * - * You should never have to use this for normal code, but due to the - * way tables are constructed internally we need this in the unit tests - * to check relative tolerances over each interval. - * - * \return table spacing. - */ - real - tableSpacing() const { return 1.0 / tableScale_; } - - private: - - std::size_t numFuncInTable_; //!< Number of separate tabluated functions - std::pair range_; //!< Range for which table evaluation is allowed - real tableScale_; //!< Table scale (inverse of spacing between points) - real halfSpacing_; //!< 0.5*spacing (used for DDFZ table data) - - //!< Derivative values only, with the third-derivative subtraction described in the class documentation. - std::vector derivativeMultiTableData_; - - /*! \brief Combined derivative, difference to next derivative, value, and zero. - * - * For table point i, this vector contains the four values: - * - derivative[i] - * - (derivative[i+1]-derivative[i]) - * - value[i] - * - 0.0 - * - * For the derivative terms we have subtracted the third-derivative term described - * in the main class documentation. - * - * This is typically more efficient than the individual tables, in particular - * when using SIMD. The result should be identical outside the class, so this - * is merely an internal implementation optimization. However, to allow - * aligned SIMD loads we need to use an aligned allocator for this container. - * We occasionally abbreviate this data as DDFZ. - */ - std::vector > ddfzMultiTableData_; - - // There should never be any reason to copy the table since it is read-only - GMX_DISALLOW_COPY_AND_ASSIGN(QuadraticSplineTable); + } + + /*! \brief Return the table spacing (distance between points) + * + * You should never have to use this for normal code, but due to the + * way tables are constructed internally we need this in the unit tests + * to check relative tolerances over each interval. + * + * \return table spacing. + */ + real tableSpacing() const { return 1.0 / tableScale_; } + +private: + std::size_t numFuncInTable_; //!< Number of separate tabluated functions + std::pair range_; //!< Range for which table evaluation is allowed + real tableScale_; //!< Table scale (inverse of spacing between points) + real halfSpacing_; //!< 0.5*spacing (used for DDFZ table data) + + //!< Derivative values only, with the third-derivative subtraction described in the class documentation. + std::vector derivativeMultiTableData_; + + /*! \brief Combined derivative, difference to next derivative, value, and zero. + * + * For table point i, this vector contains the four values: + * - derivative[i] + * - (derivative[i+1]-derivative[i]) + * - value[i] + * - 0.0 + * + * For the derivative terms we have subtracted the third-derivative term described + * in the main class documentation. + * + * This is typically more efficient than the individual tables, in particular + * when using SIMD. The result should be identical outside the class, so this + * is merely an internal implementation optimization. However, to allow + * aligned SIMD loads we need to use an aligned allocator for this container. + * We occasionally abbreviate this data as DDFZ. + */ + std::vector> ddfzMultiTableData_; + + // There should never be any reason to copy the table since it is read-only + GMX_DISALLOW_COPY_AND_ASSIGN(QuadraticSplineTable); }; -} // namespace gmx +} // namespace gmx #endif // GMX_TABLES_QUADRATICSPLINETABLE_H diff --git a/src/gromacs/tables/splineutil.cpp b/src/gromacs/tables/splineutil.cpp index e78b198c21..2f1c704843 100644 --- a/src/gromacs/tables/splineutil.cpp +++ b/src/gromacs/tables/splineutil.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,37 +63,37 @@ namespace gmx namespace internal { -void -throwUnlessDerivativeIsConsistentWithFunction(const std::function &function, - const std::function &derivative, - const std::pair &range) +void throwUnlessDerivativeIsConsistentWithFunction(const std::function& function, + const std::function& derivative, + const std::pair& range) { // Since the numerical derivative will evaluate extra points // we shrink the interval slightly to avoid calling the function with values // outside the range specified. - double h = std::cbrt(GMX_DOUBLE_EPS); // ideal spacing - std::pair newRange(range.first + h, range.second - h); - const int points = 1000; // arbitrary - double dx = (newRange.second - newRange.first) / points; - bool isConsistent = true; - double minFail = newRange.second; - double maxFail = newRange.first; + double h = std::cbrt(GMX_DOUBLE_EPS); // ideal spacing + std::pair newRange(range.first + h, range.second - h); + const int points = 1000; // arbitrary + double dx = (newRange.second - newRange.first) / points; + bool isConsistent = true; + double minFail = newRange.second; + double maxFail = newRange.first; // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for (double x = newRange.first; x <= newRange.second; x += dx) { double analyticalDerivative = derivative(x); - double numericalDerivative = (function(x+h)-function(x-h))/(2*h); - double thirdDerivative = (derivative(x+h)-2.0*derivative(x)+derivative(x-h))/(h*h); + double numericalDerivative = (function(x + h) - function(x - h)) / (2 * h); + double thirdDerivative = (derivative(x + h) - 2.0 * derivative(x) + derivative(x - h)) / (h * h); // We make two types of errors in numerical calculation of the derivative: // - The truncation error: eps * |f| / h // - The rounding error: h * h * |f'''| / 6.0 - double expectedErr = GMX_DOUBLE_EPS*std::abs(function(x))/h + h*h*std::abs(thirdDerivative)/6.0; + double expectedErr = + GMX_DOUBLE_EPS * std::abs(function(x)) / h + h * h * std::abs(thirdDerivative) / 6.0; // To avoid triggering false errors because of compiler optimization or numerical issues // in the function evalulation we allow an extra factor of 10 in the expected error - if (std::abs(analyticalDerivative-numericalDerivative) > 10.0*expectedErr) + if (std::abs(analyticalDerivative - numericalDerivative) > 10.0 * expectedErr) { isConsistent = false; minFail = std::min(minFail, x); @@ -103,38 +103,40 @@ throwUnlessDerivativeIsConsistentWithFunction(const std::function function, - ArrayRef derivative, - double inputSpacing, - const std::pair &range) +void throwUnlessDerivativeIsConsistentWithFunction(ArrayRef function, + ArrayRef derivative, + double inputSpacing, + const std::pair& range) { - std::size_t firstIndex = static_cast(range.first / inputSpacing); - std::size_t lastIndex = static_cast(range.second / inputSpacing); - bool isConsistent = true; - std::size_t minFail = lastIndex; - std::size_t maxFail = firstIndex; + std::size_t firstIndex = static_cast(range.first / inputSpacing); + std::size_t lastIndex = static_cast(range.second / inputSpacing); + bool isConsistent = true; + std::size_t minFail = lastIndex; + std::size_t maxFail = firstIndex; // The derivative will access one extra point before/after each point, so reduce interval for (std::size_t i = firstIndex + 1; (i + 1) < lastIndex; i++) { double inputDerivative = derivative[i]; - double numericalDerivative = (function[i+1] - function[i-1]) / (2.0 * inputSpacing); - double thirdDerivative = (derivative[i+1] - 2.0*derivative[i] + derivative[i-1])/(inputSpacing * inputSpacing); + double numericalDerivative = (function[i + 1] - function[i - 1]) / (2.0 * inputSpacing); + double thirdDerivative = (derivative[i + 1] - 2.0 * derivative[i] + derivative[i - 1]) + / (inputSpacing * inputSpacing); // We make two types of errors in numerical calculation of the derivative: // - The truncation error: eps * |f| / h // - The rounding error: h * h * |f'''| / 6.0 - double expectedErr = GMX_DOUBLE_EPS*std::abs(function[i])/inputSpacing + inputSpacing*inputSpacing*std::abs(thirdDerivative)/6.0; + double expectedErr = GMX_DOUBLE_EPS * std::abs(function[i]) / inputSpacing + + inputSpacing * inputSpacing * std::abs(thirdDerivative) / 6.0; // To avoid triggering false errors because of compiler optimization or numerical issues // in the function evalulation we allow an extra factor of 10 in the expected error - if (std::abs(inputDerivative-numericalDerivative) > 10.0*expectedErr) + if (std::abs(inputDerivative - numericalDerivative) > 10.0 * expectedErr) { isConsistent = false; minFail = std::min(minFail, i); @@ -143,7 +145,9 @@ throwUnlessDerivativeIsConsistentWithFunction(ArrayRef func } if (!isConsistent) { - GMX_THROW(InconsistentInputError(formatString("Derivative inconsistent with numerical vector for elements %zu-%zu", minFail+1, maxFail+1))); + GMX_THROW(InconsistentInputError( + formatString("Derivative inconsistent with numerical vector for elements %zu-%zu", + minFail + 1, maxFail + 1))); } } @@ -162,15 +166,15 @@ throwUnlessDerivativeIsConsistentWithFunction(ArrayRef func * derivative is smaller than sqrt(GMX_REAL_MIN), they will be set to * that value. */ -static double -quotientOfFunctionAndSecondDerivative(double previousPoint, - double thisPoint, - double nextPoint, - double spacing) +static double quotientOfFunctionAndSecondDerivative(double previousPoint, + double thisPoint, + double nextPoint, + double spacing) { - double lowerLimit = static_cast(std::sqrt(GMX_REAL_MIN)); - double value = std::max(std::abs( thisPoint ), lowerLimit ); - double secondDerivative = std::abs( (previousPoint - 2.0 * thisPoint + nextPoint) / (spacing * spacing ) ); + double lowerLimit = static_cast(std::sqrt(GMX_REAL_MIN)); + double value = std::max(std::abs(thisPoint), lowerLimit); + double secondDerivative = + std::abs((previousPoint - 2.0 * thisPoint + nextPoint) / (spacing * spacing)); // Make sure we do not divide by zero. This limit is arbitrary, // but it doesnt matter since this point will have a very large value, @@ -181,52 +185,48 @@ quotientOfFunctionAndSecondDerivative(double previousPoint, } -real -findSmallestQuotientOfFunctionAndSecondDerivative(const std::function &f, - const std::pair &range) +real findSmallestQuotientOfFunctionAndSecondDerivative(const std::function& f, + const std::pair& range) { // Since the numerical second derivative will evaluate extra points // we shrink the interval slightly to avoid calling the function with values // outside the range specified. - double h = std::pow( GMX_DOUBLE_EPS, 0.25 ); - std::pair newRange(range.first + h, range.second - h); - const int points = 500; // arbitrary - double dx = (newRange.second - newRange.first) / points; - double minQuotient = GMX_REAL_MAX; + double h = std::pow(GMX_DOUBLE_EPS, 0.25); + std::pair newRange(range.first + h, range.second - h); + const int points = 500; // arbitrary + double dx = (newRange.second - newRange.first) / points; + double minQuotient = GMX_REAL_MAX; // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for (double x = newRange.first; x <= newRange.second; x += dx) { - minQuotient = std::min(minQuotient, quotientOfFunctionAndSecondDerivative(f(x-h), f(x), f(x+h), h)); + minQuotient = std::min(minQuotient, + quotientOfFunctionAndSecondDerivative(f(x - h), f(x), f(x + h), h)); } return static_cast(minQuotient); } - - - - -real -findSmallestQuotientOfFunctionAndSecondDerivative(ArrayRef function, - double inputSpacing, - const std::pair &range) +real findSmallestQuotientOfFunctionAndSecondDerivative(ArrayRef function, + double inputSpacing, + const std::pair& range) { - std::size_t firstIndex = static_cast(range.first / inputSpacing); - std::size_t lastIndex = static_cast(range.second / inputSpacing); - double minQuotient = GMX_REAL_MAX; + std::size_t firstIndex = static_cast(range.first / inputSpacing); + std::size_t lastIndex = static_cast(range.second / inputSpacing); + double minQuotient = GMX_REAL_MAX; for (std::size_t i = firstIndex + 1; (i + 1) < lastIndex; i++) { - minQuotient = std::min(minQuotient, quotientOfFunctionAndSecondDerivative(function[i-1], function[i], function[i+1], inputSpacing)); + minQuotient = std::min( + minQuotient, quotientOfFunctionAndSecondDerivative(function[i - 1], function[i], + function[i + 1], inputSpacing)); } return static_cast(minQuotient); } - /*! \brief Calculate absolute quotient of function and its third derivative * * This is a utility function used in the functions to find the smallest quotient @@ -243,17 +243,18 @@ findSmallestQuotientOfFunctionAndSecondDerivative(ArrayRef * derivative is smaller than sqrt(GMX_REAL_MIN), they will be set to * that value. */ -static double -quotientOfFunctionAndThirdDerivative(double previousPreviousPoint, - double previousPoint, - double thisPoint, - double nextPoint, - double nextNextPoint, - double spacing) +static double quotientOfFunctionAndThirdDerivative(double previousPreviousPoint, + double previousPoint, + double thisPoint, + double nextPoint, + double nextNextPoint, + double spacing) { - double lowerLimit = static_cast(std::sqrt(GMX_REAL_MIN)); - double value = std::max(std::abs( thisPoint ), lowerLimit ); - double thirdDerivative = std::abs((nextNextPoint - 2 * nextPoint + 2 * previousPoint - previousPreviousPoint) / (2 * spacing * spacing * spacing)); + double lowerLimit = static_cast(std::sqrt(GMX_REAL_MIN)); + double value = std::max(std::abs(thisPoint), lowerLimit); + double thirdDerivative = + std::abs((nextNextPoint - 2 * nextPoint + 2 * previousPoint - previousPreviousPoint) + / (2 * spacing * spacing * spacing)); // Make sure we do not divide by zero. This limit is arbitrary, // but it doesnt matter since this point will have a very large value, @@ -264,49 +265,49 @@ quotientOfFunctionAndThirdDerivative(double previousPreviousPoint, } -real -findSmallestQuotientOfFunctionAndThirdDerivative(const std::function &f, - const std::pair &range) +real findSmallestQuotientOfFunctionAndThirdDerivative(const std::function& f, + const std::pair& range) { // Since the numerical second derivative will evaluate extra points // we shrink the interval slightly to avoid calling the function with values // outside the range specified. - double h = std::pow( GMX_DOUBLE_EPS, 0.2 ); // optimal spacing for 3rd derivative - std::pair newRange(range.first + 2*h, range.second - 2*h); - const int points = 500; // arbitrary - double dx = (newRange.second - newRange.first) / points; - double minQuotient = GMX_REAL_MAX; + double h = std::pow(GMX_DOUBLE_EPS, 0.2); // optimal spacing for 3rd derivative + std::pair newRange(range.first + 2 * h, range.second - 2 * h); + const int points = 500; // arbitrary + double dx = (newRange.second - newRange.first) / points; + double minQuotient = GMX_REAL_MAX; // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for (double x = newRange.first; x <= newRange.second; x += dx) { - minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative(f(x-2*h), f(x-h), f(x), f(x+h), f(x+2*h), h)); + minQuotient = std::min(minQuotient, + quotientOfFunctionAndThirdDerivative(f(x - 2 * h), f(x - h), f(x), + f(x + h), f(x + 2 * h), h)); } return static_cast(minQuotient); } -real -findSmallestQuotientOfFunctionAndThirdDerivative(ArrayRef function, - double inputSpacing, - const std::pair &range) +real findSmallestQuotientOfFunctionAndThirdDerivative(ArrayRef function, + double inputSpacing, + const std::pair& range) { - std::size_t firstIndex = static_cast(range.first / inputSpacing); - std::size_t lastIndex = static_cast(range.second / inputSpacing); - double minQuotient = GMX_REAL_MAX; + std::size_t firstIndex = static_cast(range.first / inputSpacing); + std::size_t lastIndex = static_cast(range.second / inputSpacing); + double minQuotient = GMX_REAL_MAX; for (std::size_t i = firstIndex + 2; (i + 2) < lastIndex; i++) { - minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative(function[i-2], function[i-1], function[i], function[i+1], function[i+2], inputSpacing)); + minQuotient = std::min(minQuotient, quotientOfFunctionAndThirdDerivative( + function[i - 2], function[i - 1], function[i], + function[i + 1], function[i + 2], inputSpacing)); } return static_cast(minQuotient); } - -std::vector -vectorSecondDerivative(ArrayRef f, double spacing) +std::vector vectorSecondDerivative(ArrayRef f, double spacing) { if (f.size() < 5) { @@ -318,27 +319,28 @@ vectorSecondDerivative(ArrayRef f, double spacing) // 5-point formula evaluated for points 0,1 i = 0; - d[i] = (11 * f[i+4] - 56 * f[i+3] + 114 * f[i+2] - 104 * f[i+1] + 35 * f[i]) / ( 12 * spacing * spacing); - i = 1; - d[i] = (-f[i+3] + 4 * f[i+2] + 6 * f[i+1] - 20 * f[i] + 11 * f[i-1]) / ( 12 * spacing * spacing); + d[i] = (11 * f[i + 4] - 56 * f[i + 3] + 114 * f[i + 2] - 104 * f[i + 1] + 35 * f[i]) + / (12 * spacing * spacing); + i = 1; + d[i] = (-f[i + 3] + 4 * f[i + 2] + 6 * f[i + 1] - 20 * f[i] + 11 * f[i - 1]) / (12 * spacing * spacing); for (std::size_t i = 2; i < d.size() - 2; i++) { // 5-point formula evaluated for central point (2) - d[i] = (-f[i+2] + 16 * f[i+1] - 30 * f[i] + 16 * f[i-1] - f[i-2]) / (12 * spacing * spacing); + d[i] = (-f[i + 2] + 16 * f[i + 1] - 30 * f[i] + 16 * f[i - 1] - f[i - 2]) / (12 * spacing * spacing); } // 5-point formula evaluated for points 3,4 - i = d.size() - 2; - d[i] = (11 * f[i+1] - 20 * f[i] + 6 * f[i-1] + 4 * f[i-2] - f[i-3]) / ( 12 * spacing * spacing); + i = d.size() - 2; + d[i] = (11 * f[i + 1] - 20 * f[i] + 6 * f[i - 1] + 4 * f[i - 2] - f[i - 3]) / (12 * spacing * spacing); i = d.size() - 1; - d[i] = (35 * f[i] - 104 * f[i-1] + 114 * f[i-2] - 56 * f[i-3] + 11 * f[i-4]) / ( 12 * spacing * spacing); + d[i] = (35 * f[i] - 104 * f[i - 1] + 114 * f[i - 2] - 56 * f[i - 3] + 11 * f[i - 4]) + / (12 * spacing * spacing); return d; } +} // namespace internal -} // namespace internal - -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/tables/splineutil.h b/src/gromacs/tables/splineutil.h index 8a58486c9d..1ce52d3fa0 100644 --- a/src/gromacs/tables/splineutil.h +++ b/src/gromacs/tables/splineutil.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -76,10 +76,9 @@ namespace internal * * \note The function/derivative are always double-valued to avoid accuracy loss. */ -void -throwUnlessDerivativeIsConsistentWithFunction(const std::function &function, - const std::function &derivative, - const std::pair &range); +void throwUnlessDerivativeIsConsistentWithFunction(const std::function& function, + const std::function& derivative, + const std::pair& range); /*! \brief Ensure vector of derivative values is the derivative of function vector. * @@ -103,13 +102,10 @@ throwUnlessDerivativeIsConsistentWithFunction(const std::function function, - ArrayRef derivative, - double inputSpacing, - const std::pair &range); - - +void throwUnlessDerivativeIsConsistentWithFunction(ArrayRef function, + ArrayRef derivative, + double inputSpacing, + const std::pair& range); /*! \brief Find smallest quotient between analytical function and its 2nd derivative @@ -140,12 +136,8 @@ throwUnlessDerivativeIsConsistentWithFunction(ArrayRef func * * \note The function is always double-valued to avoid accuracy loss. */ -real -findSmallestQuotientOfFunctionAndSecondDerivative(const std::function &f, - const std::pair &range); - - - +real findSmallestQuotientOfFunctionAndSecondDerivative(const std::function& f, + const std::pair& range); /*! \brief Find smallest quotient between vector of values and its 2nd derivative @@ -174,13 +166,9 @@ findSmallestQuotientOfFunctionAndSecondDerivative(const std::function function, - double inputSpacing, - const std::pair &range); - - - +real findSmallestQuotientOfFunctionAndSecondDerivative(ArrayRef function, + double inputSpacing, + const std::pair& range); /*! \brief Find smallest quotient between analytical function and its 3rd derivative @@ -211,11 +199,8 @@ findSmallestQuotientOfFunctionAndSecondDerivative(ArrayRef * * \note The function is always double-valued to avoid accuracy loss. */ -real -findSmallestQuotientOfFunctionAndThirdDerivative(const std::function &f, - const std::pair &range); - - +real findSmallestQuotientOfFunctionAndThirdDerivative(const std::function& f, + const std::pair& range); /*! \brief Find smallest quotient between function and 2nd derivative (vectors) @@ -244,10 +229,9 @@ findSmallestQuotientOfFunctionAndThirdDerivative(const std::function function, - double inputSpacing, - const std::pair &range); +real findSmallestQuotientOfFunctionAndThirdDerivative(ArrayRef function, + double inputSpacing, + const std::pair& range); /*! \brief Calculate second derivative of vector and return vector of same length @@ -263,9 +247,7 @@ findSmallestQuotientOfFunctionAndThirdDerivative(ArrayRef f * to be used on raw user input data for tables, where we want to avoid * accuracy loss (since differentiation can be numerically fragile). */ -std::vector -vectorSecondDerivative(ArrayRef f, - double spacing); +std::vector vectorSecondDerivative(ArrayRef f, double spacing); /*! \brief Copy (temporary) table data into aligned multiplexed vector @@ -290,16 +272,15 @@ vectorSecondDerivative(ArrayRef f, * in the GROMACS nonbonded kernels. */ template -void -fillMultiplexedTableData(const T inputData, - U * multiplexedOutputData, - std::size_t valuesPerTablePoint, - std::size_t numTables, - std::size_t thisTableIndex) +void fillMultiplexedTableData(const T inputData, + U* multiplexedOutputData, + std::size_t valuesPerTablePoint, + std::size_t numTables, + std::size_t thisTableIndex) { if (multiplexedOutputData->empty()) { - multiplexedOutputData->resize( inputData.size() * numTables ); + multiplexedOutputData->resize(inputData.size() * numTables); } else { @@ -315,7 +296,7 @@ fillMultiplexedTableData(const T inputData, for (std::size_t i = 0; i < points; i++) { std::size_t inputOffset = valuesPerTablePoint * i; - std::size_t outputOffset = valuesPerTablePoint * ( numTables * i + thisTableIndex ); + std::size_t outputOffset = valuesPerTablePoint * (numTables * i + thisTableIndex); for (std::size_t j = 0; j < valuesPerTablePoint; j++) { @@ -325,8 +306,8 @@ fillMultiplexedTableData(const T inputData, } -} // namespace internal +} // namespace internal -} // namespace gmx +} // namespace gmx #endif // GMX_TABLES_SPLINEUTIL_H diff --git a/src/gromacs/tables/tableinput.h b/src/gromacs/tables/tableinput.h index a866b8816f..6c30acd5fd 100644 --- a/src/gromacs/tables/tableinput.h +++ b/src/gromacs/tables/tableinput.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,25 +55,23 @@ namespace gmx /*! \libinternal \brief Specification for analytical table function (name, function, derivative) */ -struct -AnalyticalSplineTableInput +struct AnalyticalSplineTableInput { //NOLINTNEXTLINE(google-runtime-member-string-references) - const std::string &desc; //!< \libinternal Brief description of function - std::function function; //!< \libinternal Analytical form of function - std::function derivative; //!< \libinternal Analytical derivative + const std::string& desc; //!< \libinternal Brief description of function + std::function function; //!< \libinternal Analytical form of function + std::function derivative; //!< \libinternal Analytical derivative }; /*! \libinternal \brief Specification for vector table function (name, function, derivative, spacing) */ -struct -NumericalSplineTableInput +struct NumericalSplineTableInput { //NOLINTNEXTLINE(google-runtime-member-string-references) - const std::string &desc; //!< \libinternal Brief description of function - ArrayRef function; //!< \libinternal Vector with function values - ArrayRef derivative; //!< \libinternal Vector with derivative values - double spacing; //!< \libinternal Distance between data points + const std::string& desc; //!< \libinternal Brief description of function + ArrayRef function; //!< \libinternal Vector with function values + ArrayRef derivative; //!< \libinternal Vector with derivative values + double spacing; //!< \libinternal Distance between data points }; diff --git a/src/gromacs/tables/tests/splinetable.cpp b/src/gromacs/tables/tests/splinetable.cpp index 44c7061b93..7af4e80c2c 100644 --- a/src/gromacs/tables/tests/splinetable.cpp +++ b/src/gromacs/tables/tests/splinetable.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,79 +71,74 @@ namespace class SplineTableTestBase : public ::testing::Test { - public: - static int s_testPoints_; //!< Number of points to use. Public so we can set it as option +public: + static int s_testPoints_; //!< Number of points to use. Public so we can set it as option }; -int -SplineTableTestBase::s_testPoints_ = 100; +int SplineTableTestBase::s_testPoints_ = 100; /*! \cond */ /*! \brief Command-line option to adjust the number of points used to test SIMD math functions. */ GMX_TEST_OPTIONS(SplineTableTestOptions, options) { options->addOption(::gmx::IntegerOption("npoints") - .store(&SplineTableTestBase::s_testPoints_) - .description("Number of points to test for spline table functions")); + .store(&SplineTableTestBase::s_testPoints_) + .description("Number of points to test for spline table functions")); } /*! \endcond */ - - /*! \brief Test fixture for table comparision with analytical/numerical functions */ -template +template class SplineTableTest : public SplineTableTestBase { - public: - SplineTableTest() : tolerance_(T::defaultTolerance) {} - - /*! \brief Set a new tolerance to be used in table function comparison - * - * \param tol New tolerance to use - */ - void - setTolerance(real tol) { tolerance_ = tol; } - - //! \cond internal - /*! \internal \brief - * Assertion predicate formatter for comparing table with function/derivative - */ - template - void - testSplineTableAgainstFunctions(const std::string &desc, - const std::function &refFunc, - const std::function &refDer, - const T &table, - const std::pair &testRange); - //! \endcond - - private: - real tolerance_; //!< Tolerance to use +public: + SplineTableTest() : tolerance_(T::defaultTolerance) {} + + /*! \brief Set a new tolerance to be used in table function comparison + * + * \param tol New tolerance to use + */ + void setTolerance(real tol) { tolerance_ = tol; } + + //! \cond internal + /*! \internal \brief + * Assertion predicate formatter for comparing table with function/derivative + */ + template + void testSplineTableAgainstFunctions(const std::string& desc, + const std::function& refFunc, + const std::function& refDer, + const T& table, + const std::pair& testRange); + //! \endcond + +private: + real tolerance_; //!< Tolerance to use }; -template +template template -void -SplineTableTest::testSplineTableAgainstFunctions(const std::string &desc, - const std::function &refFunc, - const std::function &refDer, - const T &table, - const std::pair &testRange) +void SplineTableTest::testSplineTableAgainstFunctions(const std::string& desc, + const std::function& refFunc, + const std::function& refDer, + const T& table, + const std::pair& testRange) { - real dx = (testRange.second - testRange.first) / s_testPoints_; + real dx = (testRange.second - testRange.first) / s_testPoints_; FloatingPointTolerance funcTolerance(relativeToleranceAsFloatingPoint(0.0, tolerance_)); for (real x = testRange.first; x < testRange.second; x += dx) // NOLINT(clang-analyzer-security.FloatLoopCounter) { real h = std::sqrt(GMX_REAL_EPS); - real secondDerivative = (refDer(x+h)-refDer(x))/h; + real secondDerivative = (refDer(x + h) - refDer(x)) / h; real testFuncValue; real testDerValue; - table.template evaluateFunctionAndDerivative(x, &testFuncValue, &testDerValue); + table.template evaluateFunctionAndDerivative(x, &testFuncValue, + &testDerValue); // Check that we get the same values from function/derivative-only methods real tmpFunc, tmpDer; @@ -160,29 +155,33 @@ SplineTableTest::testSplineTableAgainstFunctions(const std::string // provided based on the requested accuracy of the table, but a tolerance related // to the floating-point precision used. For now we only allow deviations up // to 4 ulp (one for the FMA order, and then some margin). - FloatingPointTolerance consistencyTolerance(ulpTolerance(4)); + FloatingPointTolerance consistencyTolerance(ulpTolerance(4)); FloatingPointDifference evaluateFuncDiff(tmpFunc, testFuncValue); if (!consistencyTolerance.isWithin(evaluateFuncDiff)) { - ADD_FAILURE() - << "Interpolation inconsistency for table " << desc << std::endl - << numFuncInTable << " function(s) in table, testing index " << funcIndex << std::endl - << "First failure at x = " << x << std::endl - << "Function value when evaluating function & derivative: " << testFuncValue << std::endl - << "Function value when evaluating only function: " << tmpFunc << std::endl; + ADD_FAILURE() << "Interpolation inconsistency for table " << desc << std::endl + << numFuncInTable << " function(s) in table, testing index " << funcIndex + << std::endl + << "First failure at x = " << x << std::endl + << "Function value when evaluating function & derivative: " << testFuncValue + << std::endl + << "Function value when evaluating only function: " << tmpFunc + << std::endl; return; } FloatingPointDifference evaluateDerDiff(tmpDer, testDerValue); if (!consistencyTolerance.isWithin(evaluateDerDiff)) { - ADD_FAILURE() - << "Interpolation inconsistency for table " << desc << std::endl - << numFuncInTable << " function(s) in table, testing index " << funcIndex << std::endl - << "First failure at x = " << x << std::endl - << "Derivative value when evaluating function & derivative: " << testDerValue << std::endl - << "Derivative value when evaluating only derivative: " << tmpDer << std::endl; + ADD_FAILURE() << "Interpolation inconsistency for table " << desc << std::endl + << numFuncInTable << " function(s) in table, testing index " << funcIndex + << std::endl + << "First failure at x = " << x << std::endl + << "Derivative value when evaluating function & derivative: " << testDerValue + << std::endl + << "Derivative value when evaluating only derivative: " << tmpDer + << std::endl; return; } @@ -214,38 +213,39 @@ SplineTableTest::testSplineTableAgainstFunctions(const std::string // This means the truncation error in the value is derivative*x*eps_machine, and in the // derivative the error is 2nd_derivative*x*eps_machine. - real refFuncValue = refFunc(x); - real refDerValue = refDer(x); - real nextRefDerValue = refDer(x + table.tableSpacing()); + real refFuncValue = refFunc(x); + real refDerValue = refDer(x); + real nextRefDerValue = refDer(x + table.tableSpacing()); - real derMagnitude = std::max( std::abs(refDerValue), std::abs(nextRefDerValue)); + real derMagnitude = std::max(std::abs(refDerValue), std::abs(nextRefDerValue)); // Since the reference magnitude will change over each interval we need to re-evaluate // the derivative tolerance inside the loop. - FloatingPointTolerance derTolerance(relativeToleranceAsFloatingPoint(derMagnitude, tolerance_)); + FloatingPointTolerance derTolerance(relativeToleranceAsFloatingPoint(derMagnitude, tolerance_)); FloatingPointDifference funcDiff(refFuncValue, testFuncValue); FloatingPointDifference derDiff(refDerValue, testDerValue); - real allowedAbsFuncErr = std::abs(refDerValue) * x * GMX_REAL_EPS; - real allowedAbsDerErr = std::abs(secondDerivative) * x * GMX_REAL_EPS; + real allowedAbsFuncErr = std::abs(refDerValue) * x * GMX_REAL_EPS; + real allowedAbsDerErr = std::abs(secondDerivative) * x * GMX_REAL_EPS; - if ((!funcTolerance.isWithin(funcDiff) && funcDiff.asAbsolute() > allowedAbsFuncErr) || - (!derTolerance.isWithin(derDiff) && derDiff.asAbsolute() > allowedAbsDerErr)) + if ((!funcTolerance.isWithin(funcDiff) && funcDiff.asAbsolute() > allowedAbsFuncErr) + || (!derTolerance.isWithin(derDiff) && derDiff.asAbsolute() > allowedAbsDerErr)) { - ADD_FAILURE() - << "Failing comparison with function for table " << desc << std::endl - << numFuncInTable << " function(s) in table, testing index " << funcIndex << std::endl - << "Test range is ( " << testRange.first << " , " << testRange.second << " ) " << std::endl - << "Tolerance = " << tolerance_ << std::endl - << "First failure at x = " << x << std::endl - << "Reference function = " << refFuncValue << std::endl - << "Test table function = " << testFuncValue << std::endl - << "Allowed abs func err. = " << allowedAbsFuncErr << std::endl - << "Reference derivative = " << refDerValue << std::endl - << "Test table derivative = " << testDerValue << std::endl - << "Allowed abs der. err. = " << allowedAbsDerErr << std::endl - << "Actual abs der. err. = " << derDiff.asAbsolute() << std::endl; + ADD_FAILURE() << "Failing comparison with function for table " << desc << std::endl + << numFuncInTable << " function(s) in table, testing index " << funcIndex + << std::endl + << "Test range is ( " << testRange.first << " , " << testRange.second + << " ) " << std::endl + << "Tolerance = " << tolerance_ << std::endl + << "First failure at x = " << x << std::endl + << "Reference function = " << refFuncValue << std::endl + << "Test table function = " << testFuncValue << std::endl + << "Allowed abs func err. = " << allowedAbsFuncErr << std::endl + << "Reference derivative = " << refDerValue << std::endl + << "Test table derivative = " << testDerValue << std::endl + << "Allowed abs der. err. = " << allowedAbsDerErr << std::endl + << "Actual abs der. err. = " << derDiff.asAbsolute() << std::endl; return; } } @@ -257,10 +257,9 @@ SplineTableTest::testSplineTableAgainstFunctions(const std::string * \param r argument * \return r^-1 */ -double -coulombFunction(double r) +double coulombFunction(double r) { - return 1.0/r; + return 1.0 / r; } /*! \brief Derivative (not force) of coulomb electrostatics @@ -268,10 +267,9 @@ coulombFunction(double r) * \param r argument * \return -r^-2 */ -double -coulombDerivative(double r) +double coulombDerivative(double r) { - return -1.0/(r*r); + return -1.0 / (r * r); } /*! \brief Function similar to power-6 Lennard-Jones dispersion @@ -279,8 +277,7 @@ coulombDerivative(double r) * \param r argument * \return r^-6 */ -double -lj6Function(double r) +double lj6Function(double r) { return std::pow(r, -6.0); } @@ -290,10 +287,9 @@ lj6Function(double r) * \param r argument * \return -6.0*r^-7 */ -double -lj6Derivative(double r) +double lj6Derivative(double r) { - return -6.0*std::pow(r, -7.0); + return -6.0 * std::pow(r, -7.0); } /*! \brief Function similar to power-12 Lennard-Jones repulsion @@ -301,8 +297,7 @@ lj6Derivative(double r) * \param r argument * \return r^-12 */ -double -lj12Function(double r) +double lj12Function(double r) { return std::pow(r, -12.0); } @@ -312,10 +307,9 @@ lj12Function(double r) * \param r argument * \return -12.0*r^-13 */ -double -lj12Derivative(double r) +double lj12Derivative(double r) { - return -12.0*std::pow(r, -13.0); + return -12.0 * std::pow(r, -13.0); } /*! \brief The sinc function, sin(r)/r @@ -323,10 +317,9 @@ lj12Derivative(double r) * \param r argument * \return sin(r)/r */ -double -sincFunction(double r) +double sincFunction(double r) { - return std::sin(r)/r; + return std::sin(r) / r; } /*! \brief Derivative of the sinc function @@ -334,10 +327,9 @@ sincFunction(double r) * \param r argument * \return derivative of sinc, (r*cos(r)-sin(r))/r^2 */ -double -sincDerivative(double r) +double sincDerivative(double r) { - return (r*std::cos(r)-std::sin(r))/(r*r); + return (r * std::cos(r) - std::sin(r)) / (r * r); } /*! \brief Function for the direct-space PME correction to 1/r @@ -345,16 +337,15 @@ sincDerivative(double r) * \param r argument * \return PME correction function, erf(r)/r */ -double -pmeCorrFunction(double r) +double pmeCorrFunction(double r) { if (r == 0) { - return 2.0/std::sqrt(M_PI); + return 2.0 / std::sqrt(M_PI); } else { - return std::erf(r)/r; + return std::erf(r) / r; } } @@ -363,8 +354,7 @@ pmeCorrFunction(double r) * \param r argument * \return Derivative of the PME correction function. */ -double -pmeCorrDerivative(double r) +double pmeCorrDerivative(double r) { if (r == 0) { @@ -372,7 +362,7 @@ pmeCorrDerivative(double r) } else { - return (2.0*std::exp(-r*r)/std::sqrt(3.14159265358979323846)*r-erf(r))/(r*r); + return (2.0 * std::exp(-r * r) / std::sqrt(3.14159265358979323846) * r - erf(r)) / (r * r); } } @@ -385,27 +375,32 @@ TYPED_TEST_CASE(SplineTableTest, SplineTableTypes); TYPED_TEST(SplineTableTest, HandlesIncorrectInput) { // negative range - EXPECT_THROW_GMX(TypeParam( {{"LJ12", lj12Function, lj12Derivative}}, {-1.0, 0.0}), gmx::InvalidInputError); + EXPECT_THROW_GMX(TypeParam({ { "LJ12", lj12Function, lj12Derivative } }, { -1.0, 0.0 }), + gmx::InvalidInputError); // Too small range - EXPECT_THROW_GMX(TypeParam( {{"LJ12", lj12Function, lj12Derivative}}, {1.0, 1.00001}), gmx::InvalidInputError); + EXPECT_THROW_GMX(TypeParam({ { "LJ12", lj12Function, lj12Derivative } }, { 1.0, 1.00001 }), + gmx::InvalidInputError); // bad tolerance - EXPECT_THROW_GMX(TypeParam( {{"LJ12", lj12Function, lj12Derivative}}, {1.0, 2.0}, 1e-20), gmx::ToleranceError); + EXPECT_THROW_GMX(TypeParam({ { "LJ12", lj12Function, lj12Derivative } }, { 1.0, 2.0 }, 1e-20), + gmx::ToleranceError); // Range is so close to 0.0 that table would require >1e6 points - EXPECT_THROW_GMX(TypeParam( {{"LJ12", lj12Function, lj12Derivative}}, {1e-4, 2.0}), gmx::ToleranceError); + EXPECT_THROW_GMX(TypeParam({ { "LJ12", lj12Function, lj12Derivative } }, { 1e-4, 2.0 }), + gmx::ToleranceError); // mismatching function/derivative - EXPECT_THROW_GMX(TypeParam( { {"BadLJ12", lj12Derivative, lj12Function}}, {1.0, 2.0}), gmx::InconsistentInputError); + EXPECT_THROW_GMX(TypeParam({ { "BadLJ12", lj12Derivative, lj12Function } }, { 1.0, 2.0 }), + gmx::InconsistentInputError); } #ifndef NDEBUG TYPED_TEST(SplineTableTest, CatchesOutOfRangeValues) { - TypeParam table( {{"LJ12", lj12Function, lj12Derivative}}, {0.2, 1.0}); - real x, func, der; + TypeParam table({ { "LJ12", lj12Function, lj12Derivative } }, { 0.2, 1.0 }); + real x, func, der; x = -GMX_REAL_EPS; EXPECT_THROW_GMX(table.evaluateFunctionAndDerivative(x, &func, &der), gmx::RangeError); @@ -422,9 +417,9 @@ TYPED_TEST(SplineTableTest, Sinc) // we will not have full relative accuracy close to the zeros in the // derivative. Since this is intentially a pathological function we reduce // the interval slightly for now. - std::pair range(0.1, 3.1); + std::pair range(0.1, 3.1); - TypeParam sincTable( {{"Sinc", sincFunction, sincDerivative}}, range); + TypeParam sincTable({ { "Sinc", sincFunction, sincDerivative } }, range); TestFixture::testSplineTableAgainstFunctions("Sinc", sincFunction, sincDerivative, sincTable, range); } @@ -432,9 +427,9 @@ TYPED_TEST(SplineTableTest, Sinc) TYPED_TEST(SplineTableTest, LJ12) { - std::pair range(0.2, 2.0); + std::pair range(0.2, 2.0); - TypeParam lj12Table( {{"LJ12", lj12Function, lj12Derivative}}, range); + TypeParam lj12Table({ { "LJ12", lj12Function, lj12Derivative } }, range); TestFixture::testSplineTableAgainstFunctions("LJ12", lj12Function, lj12Derivative, lj12Table, range); } @@ -442,42 +437,43 @@ TYPED_TEST(SplineTableTest, LJ12) TYPED_TEST(SplineTableTest, PmeCorrection) { - std::pair range(0.0, 4.0); - real tolerance = 1e-5; + std::pair range(0.0, 4.0); + real tolerance = 1e-5; - TypeParam pmeCorrTable( {{"PMECorr", pmeCorrFunction, pmeCorrDerivative}}, range, tolerance); + TypeParam pmeCorrTable({ { "PMECorr", pmeCorrFunction, pmeCorrDerivative } }, range, tolerance); TestFixture::setTolerance(tolerance); - TestFixture::testSplineTableAgainstFunctions("PMECorr", pmeCorrFunction, pmeCorrDerivative, pmeCorrTable, range); + TestFixture::testSplineTableAgainstFunctions("PMECorr", pmeCorrFunction, pmeCorrDerivative, + pmeCorrTable, range); } - TYPED_TEST(SplineTableTest, HandlesIncorrectNumericalInput) { // Lengths do not match - std::vector functionValues(10); - std::vector derivativeValues(20); - EXPECT_THROW_GMX(TypeParam( {{"EmptyVectors", functionValues, derivativeValues, 0.001}}, - {1.0, 2.0}), gmx::InconsistentInputError); + std::vector functionValues(10); + std::vector derivativeValues(20); + EXPECT_THROW_GMX( + TypeParam({ { "EmptyVectors", functionValues, derivativeValues, 0.001 } }, { 1.0, 2.0 }), + gmx::InconsistentInputError); // Upper range is 2.0, spacing 0.1. This requires at least 21 points. Make sure we get an error for 20. functionValues.resize(20); derivativeValues.resize(20); - EXPECT_THROW_GMX(TypeParam( {{"EmptyVectors", functionValues, derivativeValues, 0.1}}, - {1.0, 2.0}), gmx::InconsistentInputError); + EXPECT_THROW_GMX(TypeParam({ { "EmptyVectors", functionValues, derivativeValues, 0.1 } }, { 1.0, 2.0 }), + gmx::InconsistentInputError); // Create some test data functionValues.clear(); derivativeValues.clear(); - std::vector badDerivativeValues; - double spacing = 1e-3; + std::vector badDerivativeValues; + double spacing = 1e-3; for (std::size_t i = 0; i < 1001; i++) { double x = i * spacing; - double func = (x >= 0.1) ? lj12Function(x) : 0.0; + double func = (x >= 0.1) ? lj12Function(x) : 0.0; double der = (x >= 0.1) ? lj12Derivative(x) : 0.0; functionValues.push_back(func); @@ -486,68 +482,74 @@ TYPED_TEST(SplineTableTest, HandlesIncorrectNumericalInput) } // Derivatives not consistent with function - EXPECT_THROW_GMX(TypeParam( {{"NumericalBadLJ12", functionValues, badDerivativeValues, spacing}}, - {0.2, 1.0}), gmx::InconsistentInputError); + EXPECT_THROW_GMX(TypeParam({ { "NumericalBadLJ12", functionValues, badDerivativeValues, spacing } }, + { 0.2, 1.0 }), + gmx::InconsistentInputError); // Spacing 1e-3 is not sufficient for r^-12 in range [0.1,1.0] // Make sure we get a tolerance error - EXPECT_THROW_GMX(TypeParam( {{"NumericalLJ12", functionValues, derivativeValues, spacing}}, - {0.2, 1.0}), gmx::ToleranceError); + EXPECT_THROW_GMX( + TypeParam({ { "NumericalLJ12", functionValues, derivativeValues, spacing } }, { 0.2, 1.0 }), + gmx::ToleranceError); } TYPED_TEST(SplineTableTest, NumericalInputPmeCorr) { - std::pair range(0.0, 4.0); - std::vector functionValues; - std::vector derivativeValues; + std::pair range(0.0, 4.0); + std::vector functionValues; + std::vector derivativeValues; - double inputSpacing = 1e-3; - real tolerance = 1e-5; + double inputSpacing = 1e-3; + real tolerance = 1e-5; // We only need data up to the argument 4.0, but add 1% margin - for (std::size_t i = 0; i < range.second*1.01/inputSpacing; i++) + for (std::size_t i = 0; i < range.second * 1.01 / inputSpacing; i++) { - double x = i * inputSpacing; + double x = i * inputSpacing; functionValues.push_back(pmeCorrFunction(x)); derivativeValues.push_back(pmeCorrDerivative(x)); } - TypeParam pmeCorrTable( {{"NumericalPMECorr", functionValues, derivativeValues, inputSpacing}}, - range, tolerance); + TypeParam pmeCorrTable({ { "NumericalPMECorr", functionValues, derivativeValues, inputSpacing } }, + range, tolerance); TestFixture::setTolerance(tolerance); - TestFixture::testSplineTableAgainstFunctions("NumericalPMECorr", pmeCorrFunction, pmeCorrDerivative, pmeCorrTable, range); + TestFixture::testSplineTableAgainstFunctions("NumericalPMECorr", pmeCorrFunction, + pmeCorrDerivative, pmeCorrTable, range); } TYPED_TEST(SplineTableTest, TwoFunctions) { - std::pair range(0.2, 2.0); + std::pair range(0.2, 2.0); - TypeParam table( {{"LJ6", lj6Function, lj6Derivative}, {"LJ12", lj12Function, lj12Derivative}}, range); + TypeParam table({ { "LJ6", lj6Function, lj6Derivative }, { "LJ12", lj12Function, lj12Derivative } }, + range); // Test entire range for each function. This will use the method that interpolates a single function - TestFixture::template testSplineTableAgainstFunctions<2, 0>("LJ6", lj6Function, lj6Derivative, table, range); - TestFixture::template testSplineTableAgainstFunctions<2, 1>("LJ12", lj12Function, lj12Derivative, table, range); + TestFixture::template testSplineTableAgainstFunctions<2, 0>("LJ6", lj6Function, lj6Derivative, + table, range); + TestFixture::template testSplineTableAgainstFunctions<2, 1>("LJ12", lj12Function, + lj12Derivative, table, range); // Test the methods that evaluated both functions for one value - real x = 0.5 * (range.first + range.second); - real refFunc0 = lj6Function(x); - real refDer0 = lj6Derivative(x); - real refFunc1 = lj12Function(x); - real refDer1 = lj12Derivative(x); + real x = 0.5 * (range.first + range.second); + real refFunc0 = lj6Function(x); + real refDer0 = lj6Derivative(x); + real refFunc1 = lj12Function(x); + real refDer1 = lj12Derivative(x); - real tstFunc0, tstDer0, tstFunc1, tstDer1; - real tmpFunc0, tmpFunc1, tmpDer0, tmpDer1; + real tstFunc0, tstDer0, tstFunc1, tstDer1; + real tmpFunc0, tmpFunc1, tmpDer0, tmpDer1; // test that we reproduce the reference functions table.evaluateFunctionAndDerivative(x, &tstFunc0, &tstDer0, &tstFunc1, &tstDer1); - real funcErr0 = std::abs(tstFunc0-refFunc0) / std::abs(refFunc0); - real funcErr1 = std::abs(tstFunc1-refFunc1) / std::abs(refFunc1); - real derErr0 = std::abs(tstDer0-refDer0) / std::abs(refDer0); - real derErr1 = std::abs(tstDer1-refDer1) / std::abs(refDer1); + real funcErr0 = std::abs(tstFunc0 - refFunc0) / std::abs(refFunc0); + real funcErr1 = std::abs(tstFunc1 - refFunc1) / std::abs(refFunc1); + real derErr0 = std::abs(tstDer0 - refDer0) / std::abs(refDer0); + real derErr1 = std::abs(tstDer1 - refDer1) / std::abs(refDer1); // Use asserts, since the following ones compare to these values. ASSERT_LT(funcErr0, TypeParam::defaultTolerance); @@ -580,36 +582,42 @@ TYPED_TEST(SplineTableTest, TwoFunctions) TYPED_TEST(SplineTableTest, ThreeFunctions) { - std::pair range(0.2, 2.0); + std::pair range(0.2, 2.0); - TypeParam table( {{"Coulomb", coulombFunction, coulombDerivative}, {"LJ6", lj6Function, lj6Derivative}, {"LJ12", lj12Function, lj12Derivative}}, range); + TypeParam table({ { "Coulomb", coulombFunction, coulombDerivative }, + { "LJ6", lj6Function, lj6Derivative }, + { "LJ12", lj12Function, lj12Derivative } }, + range); // Test entire range for each function - TestFixture::template testSplineTableAgainstFunctions<3, 0>("Coulomb", coulombFunction, coulombDerivative, table, range); - TestFixture::template testSplineTableAgainstFunctions<3, 1>("LJ6", lj6Function, lj6Derivative, table, range); - TestFixture::template testSplineTableAgainstFunctions<3, 2>("LJ12", lj12Function, lj12Derivative, table, range); + TestFixture::template testSplineTableAgainstFunctions<3, 0>("Coulomb", coulombFunction, + coulombDerivative, table, range); + TestFixture::template testSplineTableAgainstFunctions<3, 1>("LJ6", lj6Function, lj6Derivative, + table, range); + TestFixture::template testSplineTableAgainstFunctions<3, 2>("LJ12", lj12Function, + lj12Derivative, table, range); // Test the methods that evaluated both functions for one value - real x = 0.5 * (range.first + range.second); - real refFunc0 = coulombFunction(x); - real refDer0 = coulombDerivative(x); - real refFunc1 = lj6Function(x); - real refDer1 = lj6Derivative(x); - real refFunc2 = lj12Function(x); - real refDer2 = lj12Derivative(x); + real x = 0.5 * (range.first + range.second); + real refFunc0 = coulombFunction(x); + real refDer0 = coulombDerivative(x); + real refFunc1 = lj6Function(x); + real refDer1 = lj6Derivative(x); + real refFunc2 = lj12Function(x); + real refDer2 = lj12Derivative(x); - real tstFunc0, tstDer0, tstFunc1, tstDer1, tstFunc2, tstDer2; - real tmpFunc0, tmpFunc1, tmpFunc2, tmpDer0, tmpDer1, tmpDer2; + real tstFunc0, tstDer0, tstFunc1, tstDer1, tstFunc2, tstDer2; + real tmpFunc0, tmpFunc1, tmpFunc2, tmpDer0, tmpDer1, tmpDer2; // test that we reproduce the reference functions table.evaluateFunctionAndDerivative(x, &tstFunc0, &tstDer0, &tstFunc1, &tstDer1, &tstFunc2, &tstDer2); - real funcErr0 = std::abs(tstFunc0-refFunc0) / std::abs(refFunc0); - real derErr0 = std::abs(tstDer0-refDer0) / std::abs(refDer0); - real funcErr1 = std::abs(tstFunc1-refFunc1) / std::abs(refFunc1); - real derErr1 = std::abs(tstDer1-refDer1) / std::abs(refDer1); - real funcErr2 = std::abs(tstFunc2-refFunc2) / std::abs(refFunc2); - real derErr2 = std::abs(tstDer2-refDer2) / std::abs(refDer2); + real funcErr0 = std::abs(tstFunc0 - refFunc0) / std::abs(refFunc0); + real derErr0 = std::abs(tstDer0 - refDer0) / std::abs(refDer0); + real funcErr1 = std::abs(tstFunc1 - refFunc1) / std::abs(refFunc1); + real derErr1 = std::abs(tstDer1 - refDer1) / std::abs(refDer1); + real funcErr2 = std::abs(tstFunc2 - refFunc2) / std::abs(refFunc2); + real derErr2 = std::abs(tstDer2 - refDer2) / std::abs(refDer2); // Use asserts, since the following ones compare to these values. ASSERT_LT(funcErr0, TypeParam::defaultTolerance); @@ -645,7 +653,8 @@ TYPED_TEST(SplineTableTest, ThreeFunctions) EXPECT_EQ(tstDer1, tmpDer1); // Test that scrambled order interpolation methods work - table.template evaluateFunctionAndDerivative<3, 2, 1, 0>(x, &tstFunc2, &tstDer2, &tstFunc1, &tstDer1, &tstFunc0, &tstDer0); + table.template evaluateFunctionAndDerivative<3, 2, 1, 0>(x, &tstFunc2, &tstDer2, &tstFunc1, + &tstDer1, &tstFunc0, &tstDer0); EXPECT_EQ(tstFunc0, tmpFunc0); EXPECT_EQ(tstFunc1, tmpFunc1); EXPECT_EQ(tstFunc2, tmpFunc2); @@ -667,27 +676,27 @@ TYPED_TEST(SplineTableTest, ThreeFunctions) #if GMX_SIMD_HAVE_REAL TYPED_TEST(SplineTableTest, Simd) { - std::pair range(0.2, 1.0); - TypeParam table( {{"LJ12", lj12Function, lj12Derivative}}, range); + std::pair range(0.2, 1.0); + TypeParam table({ { "LJ12", lj12Function, lj12Derivative } }, range); // We already test that the SIMD operations handle the different elements // correctly in the SIMD module, so here we only test that interpolation // works for a single value in the middle of the interval - real x = 0.5 * (range.first + range.second); - real refFunc = lj12Function(x); - real refDer = lj12Derivative(x); - SimdReal tstFunc, tstDer; - real funcErr, derErr; + real x = 0.5 * (range.first + range.second); + real refFunc = lj12Function(x); + real refDer = lj12Derivative(x); + SimdReal tstFunc, tstDer; + real funcErr, derErr; alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH]; table.evaluateFunctionAndDerivative(SimdReal(x), &tstFunc, &tstDer); store(alignedMem, tstFunc); - funcErr = std::abs(alignedMem[0]-refFunc) / std::abs(refFunc); + funcErr = std::abs(alignedMem[0] - refFunc) / std::abs(refFunc); store(alignedMem, tstDer); - derErr = std::abs(alignedMem[0]-refDer ) / std::abs(refDer ); + derErr = std::abs(alignedMem[0] - refDer) / std::abs(refDer); EXPECT_LT(funcErr, TypeParam::defaultTolerance); EXPECT_LT(derErr, TypeParam::defaultTolerance); @@ -695,38 +704,39 @@ TYPED_TEST(SplineTableTest, Simd) TYPED_TEST(SplineTableTest, SimdTwoFunctions) { - std::pair range(0.2, 2.0); + std::pair range(0.2, 2.0); - TypeParam table( {{"LJ6", lj6Function, lj6Derivative}, {"LJ12", lj12Function, lj12Derivative}}, range); + TypeParam table({ { "LJ6", lj6Function, lj6Derivative }, { "LJ12", lj12Function, lj12Derivative } }, + range); // We already test that the SIMD operations handle the different elements // correctly in the SIMD module, so here we only test that interpolation // works for a single value in the middle of the interval - real x = 0.5 * (range.first + range.second); - real refFunc0 = lj6Function(x); - real refDer0 = lj6Derivative(x); - real refFunc1 = lj12Function(x); - real refDer1 = lj12Derivative(x); - SimdReal tstFunc0, tstDer0; - SimdReal tstFunc1, tstDer1; - real funcErr0, derErr0; - real funcErr1, derErr1; + real x = 0.5 * (range.first + range.second); + real refFunc0 = lj6Function(x); + real refDer0 = lj6Derivative(x); + real refFunc1 = lj12Function(x); + real refDer1 = lj12Derivative(x); + SimdReal tstFunc0, tstDer0; + SimdReal tstFunc1, tstDer1; + real funcErr0, derErr0; + real funcErr1, derErr1; alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH]; table.evaluateFunctionAndDerivative(SimdReal(x), &tstFunc0, &tstDer0, &tstFunc1, &tstDer1); store(alignedMem, tstFunc0); - funcErr0 = std::abs(alignedMem[0]-refFunc0) / std::abs(refFunc0); + funcErr0 = std::abs(alignedMem[0] - refFunc0) / std::abs(refFunc0); store(alignedMem, tstDer0); - derErr0 = std::abs(alignedMem[0]-refDer0 ) / std::abs(refDer0 ); + derErr0 = std::abs(alignedMem[0] - refDer0) / std::abs(refDer0); store(alignedMem, tstFunc1); - funcErr1 = std::abs(alignedMem[0]-refFunc1) / std::abs(refFunc1); + funcErr1 = std::abs(alignedMem[0] - refFunc1) / std::abs(refFunc1); store(alignedMem, tstDer1); - derErr1 = std::abs(alignedMem[0]-refDer1 ) / std::abs(refDer1 ); + derErr1 = std::abs(alignedMem[0] - refDer1) / std::abs(refDer1); EXPECT_LT(funcErr0, TypeParam::defaultTolerance); EXPECT_LT(derErr0, TypeParam::defaultTolerance); @@ -738,39 +748,39 @@ TYPED_TEST(SplineTableTest, SimdTwoFunctions) #if GMX_SIMD_HAVE_REAL && !defined NDEBUG TYPED_TEST(SplineTableTest, CatchesOutOfRangeValuesSimd) { - std::pair range(0.2, 1.0); - TypeParam table( {{"LJ12", lj12Function, lj12Derivative}}, range); - SimdReal x, func, der; + std::pair range(0.2, 1.0); + TypeParam table({ { "LJ12", lj12Function, lj12Derivative } }, range); + SimdReal x, func, der; AlignedArray alignedMem; alignedMem.fill(range.first); // Make position 1 incorrect if width>=2, otherwise position 0 // range.first-GMX_REAL_EPS is not invalid. See comment in table. - alignedMem[ (GMX_SIMD_REAL_WIDTH >= 2) ? 1 : 0] = -GMX_REAL_EPS; - x = load(alignedMem); + alignedMem[(GMX_SIMD_REAL_WIDTH >= 2) ? 1 : 0] = -GMX_REAL_EPS; + x = load(alignedMem); EXPECT_THROW_GMX(table.evaluateFunctionAndDerivative(x, &func, &der), gmx::RangeError); // Make position 1 incorrect if width>=2, otherwise position 0 - alignedMem[ (GMX_SIMD_REAL_WIDTH >= 2) ? 1 : 0] = range.second; - x = load(alignedMem); + alignedMem[(GMX_SIMD_REAL_WIDTH >= 2) ? 1 : 0] = range.second; + x = load(alignedMem); EXPECT_THROW_GMX(table.evaluateFunctionAndDerivative(x, &func, &der), gmx::RangeError); } TYPED_TEST(SplineTableTest, AcceptsInRangeValuesSimd) { - std::pair range(0.2, 1.0); - TypeParam table( {{"LJ12", lj12Function, lj12Derivative}}, range); - SimdReal x, func, der; + std::pair range(0.2, 1.0); + TypeParam table({ { "LJ12", lj12Function, lj12Derivative } }, range); + SimdReal x, func, der; alignas(GMX_SIMD_ALIGNMENT) real alignedMem[GMX_SIMD_REAL_WIDTH]; // Test all values between 0 and range.second for (std::size_t i = 0; i < GMX_SIMD_REAL_WIDTH; i++) { - alignedMem[i] = range.second*(1.0-GMX_REAL_EPS)*i/(GMX_SIMD_REAL_WIDTH-1); + alignedMem[i] = range.second * (1.0 - GMX_REAL_EPS) * i / (GMX_SIMD_REAL_WIDTH - 1); } x = load(alignedMem); diff --git a/src/gromacs/taskassignment/decidegpuusage.cpp b/src/gromacs/taskassignment/decidegpuusage.cpp index 3e481bcd75..66b1a3cc53 100644 --- a/src/gromacs/taskassignment/decidegpuusage.cpp +++ b/src/gromacs/taskassignment/decidegpuusage.cpp @@ -78,43 +78,40 @@ namespace { //! Helper variable to localise the text of an often repeated message. -const char * g_specifyEverythingFormatString = - "When you use mdrun -gputasks, %s must be set to non-default " - "values, so that the device IDs can be interpreted correctly." +const char* g_specifyEverythingFormatString = + "When you use mdrun -gputasks, %s must be set to non-default " + "values, so that the device IDs can be interpreted correctly." #if GMX_GPU != GMX_GPU_NONE - " If you simply want to restrict which GPUs are used, then it is " - "better to use mdrun -gpu_id. Otherwise, setting the " -# if GMX_GPU == GMX_GPU_CUDA - "CUDA_VISIBLE_DEVICES" -# elif GMX_GPU == GMX_GPU_OPENCL - // Technically there is no portable way to do this offered by the - // OpenCL standard, but the only current relevant case for GROMACS - // is AMD OpenCL, which offers this variable. - "GPU_DEVICE_ORDINAL" -# else -# error "Unreachable branch" -# endif - " environment variable in your bash profile or job " - "script may be more convenient." + " If you simply want to restrict which GPUs are used, then it is " + "better to use mdrun -gpu_id. Otherwise, setting the " +# if GMX_GPU == GMX_GPU_CUDA + "CUDA_VISIBLE_DEVICES" +# elif GMX_GPU == GMX_GPU_OPENCL + // Technically there is no portable way to do this offered by the + // OpenCL standard, but the only current relevant case for GROMACS + // is AMD OpenCL, which offers this variable. + "GPU_DEVICE_ORDINAL" +# else +# error "Unreachable branch" +# endif + " environment variable in your bash profile or job " + "script may be more convenient." #endif -; - -} // namespace - -bool -decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget nonbondedTarget, - const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, - const EmulateGpuNonbonded emulateGpuNonbonded, - const bool buildSupportsNonbondedOnGpu, - const bool nonbondedOnGpuIsUseful, - const int numRanksPerSimulation) + ; + +} // namespace + +bool decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget nonbondedTarget, + const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, + const EmulateGpuNonbonded emulateGpuNonbonded, + const bool buildSupportsNonbondedOnGpu, + const bool nonbondedOnGpuIsUseful, + const int numRanksPerSimulation) { // First, exclude all cases where we can't run NB on GPUs. - if (nonbondedTarget == TaskTarget::Cpu || - emulateGpuNonbonded == EmulateGpuNonbonded::Yes || - !nonbondedOnGpuIsUseful || - !buildSupportsNonbondedOnGpu) + if (nonbondedTarget == TaskTarget::Cpu || emulateGpuNonbonded == EmulateGpuNonbonded::Yes + || !nonbondedOnGpuIsUseful || !buildSupportsNonbondedOnGpu) { // If the user required NB on GPUs, we issue an error later. return false; @@ -125,10 +122,10 @@ decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget nonbon if (!userGpuTaskAssignment.empty()) { // Specifying -gputasks requires specifying everything. - if (nonbondedTarget == TaskTarget::Auto || - numRanksPerSimulation < 1) + if (nonbondedTarget == TaskTarget::Auto || numRanksPerSimulation < 1) { - GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "-nb and -ntmpi"))); + GMX_THROW(InconsistentInputError( + formatString(g_specifyEverythingFormatString, "-nb and -ntmpi"))); } return true; } @@ -147,23 +144,20 @@ decideWhetherToUseGpusForNonbondedWithThreadMpi(const TaskTarget nonbon return haveGpus; } -bool -decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbonded, - const TaskTarget pmeTarget, - const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_inputrec &inputrec, - const gmx_mtop_t &mtop, - const int numRanksPerSimulation, - const int numPmeRanksPerSimulation) +bool decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbonded, + const TaskTarget pmeTarget, + const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_inputrec& inputrec, + const gmx_mtop_t& mtop, + const int numRanksPerSimulation, + const int numPmeRanksPerSimulation) { // First, exclude all cases where we can't run PME on GPUs. - if ((pmeTarget == TaskTarget::Cpu) || - !useGpuForNonbonded || - !pme_gpu_supports_build(nullptr) || - !pme_gpu_supports_hardware(hardwareInfo, nullptr) || - !pme_gpu_supports_input(inputrec, mtop, nullptr)) + if ((pmeTarget == TaskTarget::Cpu) || !useGpuForNonbonded || !pme_gpu_supports_build(nullptr) + || !pme_gpu_supports_hardware(hardwareInfo, nullptr) + || !pme_gpu_supports_input(inputrec, mtop, nullptr)) { // PME can't run on a GPU. If the user required that, we issue // an error later. @@ -179,20 +173,21 @@ decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbo // later. // Specifying -gputasks requires specifying everything. - if (pmeTarget == TaskTarget::Auto || - numRanksPerSimulation < 1) + if (pmeTarget == TaskTarget::Auto || numRanksPerSimulation < 1) { - GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi"))); + GMX_THROW(InconsistentInputError( + formatString(g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi"))); } // PME on GPUs is only supported in a single case if (pmeTarget == TaskTarget::Gpu) { - if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) || - (numPmeRanksPerSimulation > 1)) + if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) + || (numPmeRanksPerSimulation > 1)) { - GMX_THROW(InconsistentInputError - ("When you run mdrun -pme gpu -gputasks, you must supply a PME-enabled .tpr file and use a single PME rank.")); + GMX_THROW(InconsistentInputError( + "When you run mdrun -pme gpu -gputasks, you must supply a PME-enabled .tpr " + "file and use a single PME rank.")); } return true; } @@ -207,13 +202,13 @@ decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbo if (pmeTarget == TaskTarget::Gpu) { - if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) || - (numPmeRanksPerSimulation > 1)) + if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) + || (numPmeRanksPerSimulation > 1)) { - GMX_THROW(NotImplementedError - ("PME tasks were required to run on GPUs, but that is not implemented with " - "more than one PME rank. Use a single rank simulation, or a separate PME rank, " - "or permit PME tasks to be assigned to the CPU.")); + GMX_THROW(NotImplementedError( + "PME tasks were required to run on GPUs, but that is not implemented with " + "more than one PME rank. Use a single rank simulation, or a separate PME rank, " + "or permit PME tasks to be assigned to the CPU.")); } return true; } @@ -237,20 +232,20 @@ decideWhetherToUseGpusForPmeWithThreadMpi(const bool useGpuForNonbo return false; } -bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarget, - const std::vector &userGpuTaskAssignment, - const EmulateGpuNonbonded emulateGpuNonbonded, - const bool buildSupportsNonbondedOnGpu, - const bool nonbondedOnGpuIsUseful, - const bool gpusWereDetected) +bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarget, + const std::vector& userGpuTaskAssignment, + const EmulateGpuNonbonded emulateGpuNonbonded, + const bool buildSupportsNonbondedOnGpu, + const bool nonbondedOnGpuIsUseful, + const bool gpusWereDetected) { if (nonbondedTarget == TaskTarget::Cpu) { if (!userGpuTaskAssignment.empty()) { - GMX_THROW(InconsistentInputError - ("A GPU task assignment was specified, but nonbonded interactions were " - "assigned to the CPU. Make no more than one of these choices.")); + GMX_THROW(InconsistentInputError( + "A GPU task assignment was specified, but nonbonded interactions were " + "assigned to the CPU. Make no more than one of these choices.")); } return false; @@ -258,11 +253,11 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarg if (!buildSupportsNonbondedOnGpu && nonbondedTarget == TaskTarget::Gpu) { - GMX_THROW(InconsistentInputError - ("Nonbonded interactions on the GPU were requested with -nb gpu, " - "but the GROMACS binary has been built without GPU support. " - "Either run without selecting GPU options, or recompile GROMACS " - "with GPU support enabled")); + GMX_THROW(InconsistentInputError( + "Nonbonded interactions on the GPU were requested with -nb gpu, " + "but the GROMACS binary has been built without GPU support. " + "Either run without selecting GPU options, or recompile GROMACS " + "with GPU support enabled")); } // TODO refactor all these TaskTarget::Gpu checks into one place? @@ -272,14 +267,15 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarg { if (nonbondedTarget == TaskTarget::Gpu) { - GMX_THROW(InconsistentInputError - ("Nonbonded interactions on the GPU were required, which is inconsistent " - "with choosing emulation. Make no more than one of these choices.")); + GMX_THROW(InconsistentInputError( + "Nonbonded interactions on the GPU were required, which is inconsistent " + "with choosing emulation. Make no more than one of these choices.")); } if (!userGpuTaskAssignment.empty()) { - GMX_THROW(InconsistentInputError - ("GPU ID usage was specified, as was GPU emulation. Make no more than one of these choices.")); + GMX_THROW( + InconsistentInputError("GPU ID usage was specified, as was GPU emulation. Make " + "no more than one of these choices.")); } return false; @@ -289,9 +285,9 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarg { if (nonbondedTarget == TaskTarget::Gpu) { - GMX_THROW(InconsistentInputError - ("Nonbonded interactions on the GPU were required, but not supported for these " - "simulation settings. Change your settings, or do not require using GPUs.")); + GMX_THROW(InconsistentInputError( + "Nonbonded interactions on the GPU were required, but not supported for these " + "simulation settings. Change your settings, or do not require using GPUs.")); } return false; @@ -302,7 +298,8 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarg // Specifying -gputasks requires specifying everything. if (nonbondedTarget == TaskTarget::Auto) { - GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "-nb and -ntmpi"))); + GMX_THROW(InconsistentInputError( + formatString(g_specifyEverythingFormatString, "-nb and -ntmpi"))); } return true; @@ -324,10 +321,10 @@ bool decideWhetherToUseGpusForNonbonded(const TaskTarget nonbondedTarg bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, const TaskTarget pmeTarget, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_inputrec &inputrec, - const gmx_mtop_t &mtop, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_inputrec& inputrec, + const gmx_mtop_t& mtop, const int numRanksPerSimulation, const int numPmeRanksPerSimulation, const bool gpusWereDetected) @@ -341,8 +338,8 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, { if (pmeTarget == TaskTarget::Gpu) { - GMX_THROW(NotImplementedError - ("PME on GPUs is only supported when nonbonded interactions run on GPUs also.")); + GMX_THROW(NotImplementedError( + "PME on GPUs is only supported when nonbonded interactions run on GPUs also.")); } return false; } @@ -352,8 +349,7 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, { if (pmeTarget == TaskTarget::Gpu) { - GMX_THROW(NotImplementedError - ("Cannot compute PME interactions on a GPU, because " + message)); + GMX_THROW(NotImplementedError("Cannot compute PME interactions on a GPU, because " + message)); } return false; } @@ -361,8 +357,7 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, { if (pmeTarget == TaskTarget::Gpu) { - GMX_THROW(NotImplementedError - ("Cannot compute PME interactions on a GPU, because " + message)); + GMX_THROW(NotImplementedError("Cannot compute PME interactions on a GPU, because " + message)); } return false; } @@ -370,8 +365,7 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, { if (pmeTarget == TaskTarget::Gpu) { - GMX_THROW(NotImplementedError - ("Cannot compute PME interactions on a GPU, because " + message)); + GMX_THROW(NotImplementedError("Cannot compute PME interactions on a GPU, because " + message)); } return false; } @@ -380,9 +374,9 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, { if (!userGpuTaskAssignment.empty()) { - GMX_THROW(InconsistentInputError - ("A GPU task assignment was specified, but PME interactions were " - "assigned to the CPU. Make no more than one of these choices.")); + GMX_THROW(InconsistentInputError( + "A GPU task assignment was specified, but PME interactions were " + "assigned to the CPU. Make no more than one of these choices.")); } return false; @@ -393,7 +387,8 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, // Specifying -gputasks requires specifying everything. if (pmeTarget == TaskTarget::Auto) { - GMX_THROW(InconsistentInputError(formatString(g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi"))); // TODO ntmpi? + GMX_THROW(InconsistentInputError(formatString( + g_specifyEverythingFormatString, "all of -nb, -pme, and -ntmpi"))); // TODO ntmpi? } return true; @@ -406,13 +401,13 @@ bool decideWhetherToUseGpusForPme(const bool useGpuForNonbonded, if (pmeTarget == TaskTarget::Gpu) { - if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) || - (numPmeRanksPerSimulation > 1)) + if (((numRanksPerSimulation > 1) && (numPmeRanksPerSimulation == 0)) + || (numPmeRanksPerSimulation > 1)) { - GMX_THROW(NotImplementedError - ("PME tasks were required to run on GPUs, but that is not implemented with " - "more than one PME rank. Use a single rank simulation, or a separate PME rank, " - "or permit PME tasks to be assigned to the CPU.")); + GMX_THROW(NotImplementedError( + "PME tasks were required to run on GPUs, but that is not implemented with " + "more than one PME rank. Use a single rank simulation, or a separate PME rank, " + "or permit PME tasks to be assigned to the CPU.")); } return true; } @@ -448,9 +443,9 @@ bool decideWhetherToUseGpusForBonded(const bool useGpuForNonbonded, { if (bondedTarget == TaskTarget::Gpu) { - GMX_THROW(InconsistentInputError - ("Bonded interactions on the GPU were required, but not supported for these " - "simulation settings. Change your settings, or do not require using GPUs.")); + GMX_THROW(InconsistentInputError( + "Bonded interactions on the GPU were required, but not supported for these " + "simulation settings. Change your settings, or do not require using GPUs.")); } return false; @@ -460,10 +455,10 @@ bool decideWhetherToUseGpusForBonded(const bool useGpuForNonbonded, { if (bondedTarget == TaskTarget::Gpu) { - GMX_THROW(InconsistentInputError - ("Bonded interactions on the GPU were required, but this requires that " - "short-ranged non-bonded interactions are also run on the GPU. Change " - "your settings, or do not require using GPUs.")); + GMX_THROW(InconsistentInputError( + "Bonded interactions on the GPU were required, but this requires that " + "short-ranged non-bonded interactions are also run on the GPU. Change " + "your settings, or do not require using GPUs.")); } return false; @@ -485,7 +480,8 @@ bool decideWhetherToUseGpusForBonded(const bool useGpuForNonbonded, // (It would be better to dynamically assign bondeds based on timings) // Note that here we assume that the auto setting of PME ranks will not // choose seperate PME ranks when nonBonded are assigned to the GPU. - bool usingOurCpuForPmeOrEwald = (usingLJPme || (usingElecPmeOrEwald && !useGpuForPme && numPmeRanksPerSimulation <= 0)); + bool usingOurCpuForPmeOrEwald = + (usingLJPme || (usingElecPmeOrEwald && !useGpuForPme && numPmeRanksPerSimulation <= 0)); return gpusWereDetected && usingOurCpuForPmeOrEwald; } @@ -496,7 +492,7 @@ bool decideWhetherToUseGpuForUpdate(const bool forceGpuUpdateDefaultOn, const bool useGpuForNonbonded, const TaskTarget updateTarget, const bool gpusWereDetected, - const t_inputrec &inputrec, + const t_inputrec& inputrec, const bool haveVSites, const bool useEssentialDynamics, const bool doOrientationRestraints, @@ -519,7 +515,8 @@ bool decideWhetherToUseGpuForUpdate(const bool forceGpuUpdateDefaultOn, // 2. Non-bonded interactions are on the GPU. if (!(useGpuForPme || useGpuForNonbonded)) { - errorMessage += "Either PME or short-ranged non-bonded interaction tasks must run on the GPU.\n"; + errorMessage += + "Either PME or short-ranged non-bonded interaction tasks must run on the GPU.\n"; } if (!gpusWereDetected) { @@ -582,14 +579,16 @@ bool decideWhetherToUseGpuForUpdate(const bool forceGpuUpdateDefaultOn, { if (updateTarget == TaskTarget::Gpu) { - std::string prefix = gmx::formatString("Update task on the GPU was required,\n" - "but the following condition(s) were not satisfied:\n"); + std::string prefix = gmx::formatString( + "Update task on the GPU was required,\n" + "but the following condition(s) were not satisfied:\n"); GMX_THROW(InconsistentInputError((prefix + errorMessage).c_str())); } return false; } - return ((forceGpuUpdateDefaultOn && updateTarget == TaskTarget::Auto) || (updateTarget == TaskTarget::Gpu)); + return ((forceGpuUpdateDefaultOn && updateTarget == TaskTarget::Auto) + || (updateTarget == TaskTarget::Gpu)); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/decidegpuusage.h b/src/gromacs/taskassignment/decidegpuusage.h index 1170359b0a..d564043ca0 100644 --- a/src/gromacs/taskassignment/decidegpuusage.h +++ b/src/gromacs/taskassignment/decidegpuusage.h @@ -92,12 +92,12 @@ class MDAtoms; * \throws std::bad_alloc If out of memory * InconsistentInputError If the user requirements are inconsistent. */ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget nonbondedTarget, - const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, + const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, EmulateGpuNonbonded emulateGpuNonbonded, - bool buildSupportsNonbondedOnGpu, - bool nonbondedOnGpuIsUseful, - int numRanksPerSimulation); + bool buildSupportsNonbondedOnGpu, + bool nonbondedOnGpuIsUseful, + int numRanksPerSimulation); /*! \brief Decide whether this thread-MPI simulation will run * PME tasks on GPUs. @@ -108,10 +108,10 @@ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget non * the number of thread-MPI ranks. * * \param[in] useGpuForNonbonded Whether GPUs will be used for nonbonded interactions. - * \param[in] pmeTarget The user's choice for mdrun -pme for where to assign long-ranged PME nonbonded interaction tasks. - * \param[in] gpuIdsToUse The compatible GPUs that the user permitted us to use. - * \param[in] userGpuTaskAssignment The user-specified assignment of GPU tasks to device IDs. - * \param[in] hardwareInfo Hardware information + * \param[in] pmeTarget The user's choice for mdrun -pme for where to assign + * long-ranged PME nonbonded interaction tasks. \param[in] gpuIdsToUse The compatible + * GPUs that the user permitted us to use. \param[in] userGpuTaskAssignment The user-specified + * assignment of GPU tasks to device IDs. \param[in] hardwareInfo Hardware information * \param[in] inputrec The user input * \param[in] mtop Global system topology * \param[in] numRanksPerSimulation The number of ranks in each simulation. @@ -123,11 +123,11 @@ bool decideWhetherToUseGpusForNonbondedWithThreadMpi(TaskTarget non * InconsistentInputError If the user requirements are inconsistent. */ bool decideWhetherToUseGpusForPmeWithThreadMpi(bool useGpuForNonbonded, TaskTarget pmeTarget, - const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_inputrec &inputrec, - const gmx_mtop_t &mtop, + const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_inputrec& inputrec, + const gmx_mtop_t& mtop, int numRanksPerSimulation, int numPmeRanksPerSimulation); @@ -159,7 +159,7 @@ bool decideWhetherToUseGpusForPmeWithThreadMpi(bool useGpuFor * \throws std::bad_alloc If out of memory * InconsistentInputError If the user requirements are inconsistent. */ bool decideWhetherToUseGpusForNonbonded(TaskTarget nonbondedTarget, - const std::vector &userGpuTaskAssignment, + const std::vector& userGpuTaskAssignment, EmulateGpuNonbonded emulateGpuNonbonded, bool buildSupportsNonbondedOnGpu, bool nonbondedOnGpuIsUseful, @@ -197,10 +197,10 @@ bool decideWhetherToUseGpusForNonbonded(TaskTarget nonbondedTarget, * InconsistentInputError If the user requirements are inconsistent. */ bool decideWhetherToUseGpusForPme(bool useGpuForNonbonded, TaskTarget pmeTarget, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_inputrec &inputrec, - const gmx_mtop_t &mtop, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_inputrec& inputrec, + const gmx_mtop_t& mtop, int numRanksPerSimulation, int numPmeRanksPerSimulation, bool gpusWereDetected); @@ -253,13 +253,13 @@ bool decideWhetherToUseGpuForUpdate(bool forceGpuUpdateDefaultOn, bool useGpuForNonbonded, TaskTarget updateTarget, bool gpusWereDetected, - const t_inputrec &inputrec, + const t_inputrec& inputrec, bool haveVSites, bool useEssentialDynamics, bool doOrientationRestraints, bool useReplicaExchange); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/decidesimulationworkload.cpp b/src/gromacs/taskassignment/decidesimulationworkload.cpp index 933aeaef67..afba4097f4 100644 --- a/src/gromacs/taskassignment/decidesimulationworkload.cpp +++ b/src/gromacs/taskassignment/decidesimulationworkload.cpp @@ -50,20 +50,20 @@ namespace gmx { -SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded, - PmeRunMode pmeRunMode, - bool useGpuForBonded, - bool useGpuForUpdate, - bool useGpuForBufferOps, - bool useGpuHaloExchange, - bool useGpuPmePpComm, - bool haveEwaldSurfaceContribution) +SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded, + PmeRunMode pmeRunMode, + bool useGpuForBonded, + bool useGpuForUpdate, + bool useGpuForBufferOps, + bool useGpuHaloExchange, + bool useGpuPmePpComm, + bool haveEwaldSurfaceContribution) { SimulationWorkload simulationWorkload; - simulationWorkload.useCpuNonbonded = !useGpuForNonbonded; - simulationWorkload.useGpuNonbonded = useGpuForNonbonded; - simulationWorkload.useCpuPme = (pmeRunMode == PmeRunMode::CPU); - simulationWorkload.useGpuPme = (pmeRunMode == PmeRunMode::GPU || pmeRunMode == PmeRunMode::Mixed); + simulationWorkload.useCpuNonbonded = !useGpuForNonbonded; + simulationWorkload.useGpuNonbonded = useGpuForNonbonded; + simulationWorkload.useCpuPme = (pmeRunMode == PmeRunMode::CPU); + simulationWorkload.useGpuPme = (pmeRunMode == PmeRunMode::GPU || pmeRunMode == PmeRunMode::Mixed); simulationWorkload.useGpuPmeFft = (pmeRunMode == PmeRunMode::Mixed); simulationWorkload.useGpuBonded = useGpuForBonded; simulationWorkload.useGpuUpdate = useGpuForUpdate; @@ -76,4 +76,4 @@ SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded return simulationWorkload; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/decidesimulationworkload.h b/src/gromacs/taskassignment/decidesimulationworkload.h index ef53314b39..538fa823ed 100644 --- a/src/gromacs/taskassignment/decidesimulationworkload.h +++ b/src/gromacs/taskassignment/decidesimulationworkload.h @@ -68,15 +68,15 @@ namespace gmx * \param[in] haveEwaldSurfaceContribution Whether there is an Ewald surface contribution * \returns Simulation lifetime constant workload description. */ -SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded, - PmeRunMode pmeRunMode, - bool useGpuForBonded, - bool useGpuForUpdate, - bool useGpuForBufferOps, - bool useGpuHaloExchange, - bool useGpuPmePpComm, - bool haveEwaldSurfaceContribution); +SimulationWorkload createSimulationWorkload(bool useGpuForNonbonded, + PmeRunMode pmeRunMode, + bool useGpuForBonded, + bool useGpuForUpdate, + bool useGpuForBufferOps, + bool useGpuHaloExchange, + bool useGpuPmePpComm, + bool haveEwaldSurfaceContribution); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/findallgputasks.cpp b/src/gromacs/taskassignment/findallgputasks.cpp index 4e12785aed..d1b403362d 100644 --- a/src/gromacs/taskassignment/findallgputasks.cpp +++ b/src/gromacs/taskassignment/findallgputasks.cpp @@ -60,16 +60,15 @@ namespace gmx { -std::vector -findGpuTasksOnThisRank(const bool haveGpusOnThisPhysicalNode, - const TaskTarget nonbondedTarget, - const TaskTarget pmeTarget, - const TaskTarget bondedTarget, - const TaskTarget updateTarget, - const bool useGpuForNonbonded, - const bool useGpuForPme, - const bool rankHasPpTask, - const bool rankHasPmeTask) +std::vector findGpuTasksOnThisRank(const bool haveGpusOnThisPhysicalNode, + const TaskTarget nonbondedTarget, + const TaskTarget pmeTarget, + const TaskTarget bondedTarget, + const TaskTarget updateTarget, + const bool useGpuForNonbonded, + const bool useGpuForPme, + const bool rankHasPpTask, + const bool rankHasPmeTask) { std::vector gpuTasksOnThisRank; if (rankHasPpTask) @@ -84,15 +83,19 @@ findGpuTasksOnThisRank(const bool haveGpusOnThisPhysicalNode, } else if (nonbondedTarget == TaskTarget::Gpu) { - gmx_fatal(FARGS, "Cannot run short-ranged nonbonded interactions on a GPU because no GPU is detected."); + gmx_fatal(FARGS, + "Cannot run short-ranged nonbonded interactions on a GPU because no GPU " + "is detected."); } else if (bondedTarget == TaskTarget::Gpu) { - gmx_fatal(FARGS, "Cannot run bonded interactions on a GPU because no GPU is detected."); + gmx_fatal(FARGS, + "Cannot run bonded interactions on a GPU because no GPU is detected."); } else if (updateTarget == TaskTarget::Gpu) { - gmx_fatal(FARGS, "Cannot run coordinate update on a GPU because no GPU is detected."); + gmx_fatal(FARGS, + "Cannot run coordinate update on a GPU because no GPU is detected."); } } } @@ -120,9 +123,7 @@ namespace constexpr bool g_usingMpi = GMX_MPI; //! Helper function to prepare to all-gather the vector of non-bonded tasks on this node. -std::vector allgather(const int &input, - int numRanks, - MPI_Comm communicator) +std::vector allgather(const int& input, int numRanks, MPI_Comm communicator) { std::vector result(numRanks); if (g_usingMpi && numRanks > 1) @@ -137,19 +138,9 @@ std::vector allgather(const int &input, // to compile warning-free with all versions of MPI headers. // // TODO Make an allgather template to deal with this nonsense. - MPI_Gather(const_cast(&input), - 1, - MPI_INT, - const_cast(result.data()), - 1, - MPI_INT, - root, - communicator); - MPI_Bcast(const_cast(result.data()), - result.size(), - MPI_INT, - root, - communicator); + MPI_Gather(const_cast(&input), 1, MPI_INT, const_cast(result.data()), 1, + MPI_INT, root, communicator); + MPI_Bcast(const_cast(result.data()), result.size(), MPI_INT, root, communicator); #else GMX_UNUSED_VALUE(communicator); #endif @@ -163,12 +154,12 @@ std::vector allgather(const int &input, } //! Helper function to compute allgatherv displacements. -std::vector computeDisplacements(ArrayRef extentOnEachRank, - int numRanks) +std::vector computeDisplacements(ArrayRef extentOnEachRank, int numRanks) { std::vector displacements(numRanks + 1); displacements[0] = 0; - std::partial_sum(std::begin(extentOnEachRank), std::end(extentOnEachRank), std::begin(displacements) + 1); + std::partial_sum(std::begin(extentOnEachRank), std::end(extentOnEachRank), + std::begin(displacements) + 1); return displacements; } @@ -179,7 +170,7 @@ std::vector allgatherv(ArrayRef input, MPI_Comm communicator) { // Now allocate the vector and do the allgatherv - int totalExtent = displacementForEachRank.back(); + int totalExtent = displacementForEachRank.back(); std::vector result; result.reserve(totalExtent); @@ -194,27 +185,17 @@ std::vector allgatherv(ArrayRef input, int root = 0; // Calling a C API with the const T * from data() doesn't seem to compile reliably. // TODO Make an allgatherv template to deal with this nonsense. - MPI_Gatherv(const_cast(input.data()), - input.size(), - MPI_INT, - const_cast(result.data()), - const_cast(extentOnEachRank.data()), - const_cast(displacementForEachRank.data()), - MPI_INT, - root, - communicator); - MPI_Bcast(const_cast(result.data()), - result.size(), - MPI_INT, - root, - communicator); + MPI_Gatherv(const_cast(input.data()), input.size(), MPI_INT, + const_cast(result.data()), const_cast(extentOnEachRank.data()), + const_cast(displacementForEachRank.data()), MPI_INT, root, communicator); + MPI_Bcast(const_cast(result.data()), result.size(), MPI_INT, root, communicator); #else GMX_UNUSED_VALUE(communicator); #endif } else { - for (const auto &gpuTask : input) + for (const auto& gpuTask : input) { result.push_back(gpuTask); } @@ -222,7 +203,7 @@ std::vector allgatherv(ArrayRef input, return result; } -} // namespace +} // namespace /*! \brief Returns container of all tasks on all ranks of this node * that are eligible for GPU execution. @@ -230,24 +211,24 @@ std::vector allgatherv(ArrayRef input, * Perform all necessary communication for preparing for task * assignment. Separating this aspect makes it possible to unit test * the logic of task assignment. */ -GpuTasksOnRanks -findAllGpuTasksOnThisNode(ArrayRef gpuTasksOnThisRank, - const PhysicalNodeCommunicator &physicalNodeComm) +GpuTasksOnRanks findAllGpuTasksOnThisNode(ArrayRef gpuTasksOnThisRank, + const PhysicalNodeCommunicator& physicalNodeComm) { int numRanksOnThisNode = physicalNodeComm.size_; MPI_Comm communicator = physicalNodeComm.comm_; // Find out how many GPU tasks are on each rank on this node. - auto numGpuTasksOnEachRankOfThisNode = - allgather(gpuTasksOnThisRank.size(), numRanksOnThisNode, communicator); + auto numGpuTasksOnEachRankOfThisNode = + allgather(gpuTasksOnThisRank.size(), numRanksOnThisNode, communicator); /* Collect on each rank of this node a vector describing all * GPU tasks on this node, in ascending order of rank. This * requires a vector allgather. The displacements indicate where * the GPU tasks on each rank of this node start and end within * the vector. */ - auto displacementsForEachRank = computeDisplacements(numGpuTasksOnEachRankOfThisNode, numRanksOnThisNode); - auto gpuTasksOnThisNode = allgatherv(gpuTasksOnThisRank, numGpuTasksOnEachRankOfThisNode, - displacementsForEachRank, communicator); + auto displacementsForEachRank = + computeDisplacements(numGpuTasksOnEachRankOfThisNode, numRanksOnThisNode); + auto gpuTasksOnThisNode = allgatherv(gpuTasksOnThisRank, numGpuTasksOnEachRankOfThisNode, + displacementsForEachRank, communicator); /* Next, we re-use the displacements to break up the vector * of GPU tasks into something that can be indexed like @@ -257,23 +238,24 @@ findAllGpuTasksOnThisNode(ArrayRef gpuTasksOnThisRank, // of iterators that point to adjacent container elements" or // "iterator that points to the first of a pair of valid adjacent // container elements, or end". - GMX_ASSERT(displacementsForEachRank.size() > 1, "Even with one rank, there's always both a start and end displacement"); + GMX_ASSERT(displacementsForEachRank.size() > 1, + "Even with one rank, there's always both a start and end displacement"); auto currentDisplacementIt = displacementsForEachRank.begin(); auto nextDisplacementIt = currentDisplacementIt + 1; do { gpuTasksOnRanksOfThisNode.emplace_back(std::vector()); - for (auto taskOnThisRankIndex = *currentDisplacementIt; taskOnThisRankIndex != *nextDisplacementIt; ++taskOnThisRankIndex) + for (auto taskOnThisRankIndex = *currentDisplacementIt; + taskOnThisRankIndex != *nextDisplacementIt; ++taskOnThisRankIndex) { gpuTasksOnRanksOfThisNode.back().push_back(gpuTasksOnThisNode[taskOnThisRankIndex]); } currentDisplacementIt = nextDisplacementIt; ++nextDisplacementIt; - } - while (nextDisplacementIt != displacementsForEachRank.end()); + } while (nextDisplacementIt != displacementsForEachRank.end()); return gpuTasksOnRanksOfThisNode; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/findallgputasks.h b/src/gromacs/taskassignment/findallgputasks.h index b3067d4157..c507c05f8c 100644 --- a/src/gromacs/taskassignment/findallgputasks.h +++ b/src/gromacs/taskassignment/findallgputasks.h @@ -50,9 +50,10 @@ namespace gmx enum class GpuTask; enum class TaskTarget; class PhysicalNodeCommunicator; -template class ArrayRef; +template +class ArrayRef; //! Container of compute tasks suitable to run on a GPU e.g. on each rank of a node. -using GpuTasksOnRanks = std::vector< std::vector >; +using GpuTasksOnRanks = std::vector>; /*! \brief Returns container of all tasks on this rank * that are eligible for GPU execution. @@ -69,16 +70,15 @@ using GpuTasksOnRanks = std::vector< std::vector >; * \param[in] rankHasPpTask Whether this rank has a PP task * \param[in] rankHasPmeTask Whether this rank has a PME task */ -std::vector -findGpuTasksOnThisRank(bool haveGpusOnThisPhysicalNode, - TaskTarget nonbondedTarget, - TaskTarget pmeTarget, - TaskTarget bondedTarget, - TaskTarget updateTarget, - bool useGpuForNonbonded, - bool useGpuForPme, - bool rankHasPpTask, - bool rankHasPmeTask); +std::vector findGpuTasksOnThisRank(bool haveGpusOnThisPhysicalNode, + TaskTarget nonbondedTarget, + TaskTarget pmeTarget, + TaskTarget bondedTarget, + TaskTarget updateTarget, + bool useGpuForNonbonded, + bool useGpuForPme, + bool rankHasPpTask, + bool rankHasPmeTask); /*! \brief Returns container of all tasks on all ranks of this node * that are eligible for GPU execution. @@ -86,10 +86,9 @@ findGpuTasksOnThisRank(bool haveGpusOnThisPhysicalNode, * Perform all necessary communication for preparing for task * assignment. Separating this aspect makes it possible to unit test * the logic of task assignment. */ -GpuTasksOnRanks -findAllGpuTasksOnThisNode(ArrayRef gpuTasksOnThisRank, - const PhysicalNodeCommunicator &physicalNodeComm); +GpuTasksOnRanks findAllGpuTasksOnThisNode(ArrayRef gpuTasksOnThisRank, + const PhysicalNodeCommunicator& physicalNodeComm); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/reportgpuusage.cpp b/src/gromacs/taskassignment/reportgpuusage.cpp index 830a69212b..7861cbafb1 100644 --- a/src/gromacs/taskassignment/reportgpuusage.cpp +++ b/src/gromacs/taskassignment/reportgpuusage.cpp @@ -66,13 +66,12 @@ namespace * GPUs used (per node) can be different from the number of GPU IDs * used. */ -size_t -countUniqueGpuIdsUsed(ArrayRef gpuTaskAssignmentOnRanksOfThisNode) +size_t countUniqueGpuIdsUsed(ArrayRef gpuTaskAssignmentOnRanksOfThisNode) { std::set uniqueIds; - for (const auto &assignmentsOnRank : gpuTaskAssignmentOnRanksOfThisNode) + for (const auto& assignmentsOnRank : gpuTaskAssignmentOnRanksOfThisNode) { - for (const auto &assignmentOfTask : assignmentsOnRank) + for (const auto& assignmentOfTask : assignmentsOnRank) { uniqueIds.insert(assignmentOfTask.deviceId_); } @@ -80,16 +79,15 @@ countUniqueGpuIdsUsed(ArrayRef gpuTaskAssignmentOnRanks return uniqueIds.size(); } -} // namespace +} // namespace -void -reportGpuUsage(const MDLogger &mdlog, - ArrayRef gpuTaskAssignmentOnRanksOfThisNode, - size_t numGpuTasksOnThisNode, - size_t numRanks, - bool printHostName, - bool useGpuForBonded, - PmeRunMode pmeRunMode) +void reportGpuUsage(const MDLogger& mdlog, + ArrayRef gpuTaskAssignmentOnRanksOfThisNode, + size_t numGpuTasksOnThisNode, + size_t numRanks, + bool printHostName, + bool useGpuForBonded, + PmeRunMode pmeRunMode) { size_t numGpusInUse = countUniqueGpuIdsUsed(gpuTaskAssignmentOnRanksOfThisNode); if (numGpusInUse == 0) @@ -100,28 +98,28 @@ reportGpuUsage(const MDLogger &mdlog, std::string output; { std::string gpuIdsString; - const char *currentSeparator = ""; - const char *separator = ","; - for (const auto &assignmentsOnRank : gpuTaskAssignmentOnRanksOfThisNode) + const char* currentSeparator = ""; + const char* separator = ","; + for (const auto& assignmentsOnRank : gpuTaskAssignmentOnRanksOfThisNode) { if (assignmentsOnRank.empty()) { - gpuIdsString += currentSeparator; - gpuIdsString += "none"; + gpuIdsString += currentSeparator; + gpuIdsString += "none"; currentSeparator = separator; } else { - for (const auto &assignmentOnRank : assignmentsOnRank) + for (const auto& assignmentOnRank : assignmentsOnRank) { - const char *rankType = (assignmentOnRank.task_ == GpuTask::Nonbonded ? "PP" : "PME"); - gpuIdsString += currentSeparator; - gpuIdsString += formatString("%s:%d", rankType, assignmentOnRank.deviceId_); + const char* rankType = (assignmentOnRank.task_ == GpuTask::Nonbonded ? "PP" : "PME"); + gpuIdsString += currentSeparator; + gpuIdsString += formatString("%s:%d", rankType, assignmentOnRank.deviceId_); currentSeparator = separator; } } } - bool bPluralGpus = numGpusInUse > 1; + bool bPluralGpus = numGpusInUse > 1; if (printHostName) { @@ -129,17 +127,16 @@ reportGpuUsage(const MDLogger &mdlog, gmx_gethostname(host, STRLEN); output += gmx::formatString("On host %s ", host); } - output += gmx::formatString("%zu GPU%s selected for this run.\n" - "Mapping of GPU IDs to the %zu GPU task%s in the %zu rank%s on this node:\n %s\n", - numGpusInUse, bPluralGpus ? "s" : "", - numGpuTasksOnThisNode, - (numGpuTasksOnThisNode > 1) ? "s" : "", - numRanks, - (numRanks > 1) ? "s" : "", - gpuIdsString.c_str()); + output += gmx::formatString( + "%zu GPU%s selected for this run.\n" + "Mapping of GPU IDs to the %zu GPU task%s in the %zu rank%s on this node:\n %s\n", + numGpusInUse, bPluralGpus ? "s" : "", numGpuTasksOnThisNode, + (numGpuTasksOnThisNode > 1) ? "s" : "", numRanks, (numRanks > 1) ? "s" : "", + gpuIdsString.c_str()); // Because there is a GPU in use, there must be a PP task on a GPU. - output += gmx::formatString("PP tasks will do (non-perturbed) short-ranged%s interactions on the GPU\n", - useGpuForBonded ? " and most bonded" : ""); + output += gmx::formatString( + "PP tasks will do (non-perturbed) short-ranged%s interactions on the GPU\n", + useGpuForBonded ? " and most bonded" : ""); if (pmeRunMode == PmeRunMode::Mixed) { output += gmx::formatString("PME tasks will do only spread and gather on the GPU\n"); @@ -154,4 +151,4 @@ reportGpuUsage(const MDLogger &mdlog, GMX_LOG(mdlog.warning).appendText(output); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/reportgpuusage.h b/src/gromacs/taskassignment/reportgpuusage.h index 9de34dd20f..82252f152a 100644 --- a/src/gromacs/taskassignment/reportgpuusage.h +++ b/src/gromacs/taskassignment/reportgpuusage.h @@ -57,8 +57,9 @@ namespace gmx class MDLogger; struct GpuTaskMapping; -template class ArrayRef; -using GpuTaskAssignment = std::vector ; +template +class ArrayRef; +using GpuTaskAssignment = std::vector; /*! \brief Log a report on how GPUs are being used on * the ranks of the physical node of rank 0 of the simulation. @@ -71,19 +72,18 @@ using GpuTaskAssignment = std::vector ; * \param[in] numGpuTasksOnThisNode The number of GPU tasks on this node. * \param[in] numPpRanks Number of PP ranks on this node * \param[in] printHostName Print the hostname in the usage information - * \param[in] useGpuForBonded Whether GPU PP tasks will do bonded work on the GPU - * \param[in] pmeRunMode Describes the execution of PME tasks + * \param[in] useGpuForBonded Whether GPU PP tasks will do bonded work on the + * GPU \param[in] pmeRunMode Describes the execution of PME tasks * * \throws std::bad_alloc if out of memory */ -void -reportGpuUsage(const MDLogger &mdlog, - ArrayRef gpuTaskAssignmentOnRanksOfThisNode, - size_t numGpuTasksOnThisNode, - size_t numPpRanks, - bool printHostName, - bool useGpuForBonded, - PmeRunMode pmeRunMode); +void reportGpuUsage(const MDLogger& mdlog, + ArrayRef gpuTaskAssignmentOnRanksOfThisNode, + size_t numGpuTasksOnThisNode, + size_t numPpRanks, + bool printHostName, + bool useGpuForBonded, + PmeRunMode pmeRunMode); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/resourcedivision.cpp b/src/gromacs/taskassignment/resourcedivision.cpp index 5be972ce93..5d0070d561 100644 --- a/src/gromacs/taskassignment/resourcedivision.cpp +++ b/src/gromacs/taskassignment/resourcedivision.cpp @@ -86,12 +86,12 @@ * are present. With fewer atoms than this, the number of thread-MPI * ranks will get lowered. */ -static constexpr int min_atoms_per_mpi_thread = 90; +static constexpr int min_atoms_per_mpi_thread = 90; /*! \brief The minimum number of atoms per GPU with thread-MPI * active. With fewer atoms than this, the number of thread-MPI ranks * will get lowered. */ -static constexpr int min_atoms_per_gpu = 900; +static constexpr int min_atoms_per_gpu = 900; /**@{*/ /*! \brief Constants for implementing default divisions of threads */ @@ -112,7 +112,7 @@ static constexpr int min_atoms_per_gpu = 900; * Sandy/Ivy Bridge, Has/Broadwell. By checking for AVX instead of * model numbers we ensure also future Intel CPUs are covered. */ -constexpr int nthreads_omp_faster_default = 8; +constexpr int nthreads_omp_faster_default = 8; constexpr int nthreads_omp_faster_Nehalem = 12; constexpr int nthreads_omp_faster_Intel_AVX = 16; constexpr int nthreads_omp_faster_AMD_Ryzen = 16; @@ -122,7 +122,7 @@ constexpr int nthreads_omp_faster_AMD_Ryzen = 16; * OpenMP threads counts can still be ok. Multiplying the numbers above * by a factor of 2 seems to be a good estimate. */ -constexpr int nthreads_omp_faster_gpu_fac = 2; +constexpr int nthreads_omp_faster_gpu_fac = 2; /* This is the case with MPI (2 or more MPI PP ranks). * By default we will terminate with a fatal error when more than 8 @@ -132,22 +132,21 @@ constexpr int nthreads_omp_faster_gpu_fac = 2; * we first try 6 OpenMP threads and then less until the number of MPI ranks * is divisible by the number of GPUs. */ -constexpr int nthreads_omp_mpi_ok_max = 8; -constexpr int nthreads_omp_mpi_ok_min_cpu = 1; -constexpr int nthreads_omp_mpi_ok_min_gpu = 2; -constexpr int nthreads_omp_mpi_target_max = 6; +constexpr int nthreads_omp_mpi_ok_max = 8; +constexpr int nthreads_omp_mpi_ok_min_cpu = 1; +constexpr int nthreads_omp_mpi_ok_min_gpu = 2; +constexpr int nthreads_omp_mpi_target_max = 6; /**@}*/ /*! \brief Returns the maximum OpenMP thread count for which using a single MPI rank * should be faster than using multiple ranks with the same total thread count. */ -static int nthreads_omp_faster(const gmx::CpuInfo &cpuInfo, gmx_bool bUseGPU) +static int nthreads_omp_faster(const gmx::CpuInfo& cpuInfo, gmx_bool bUseGPU) { int nth; - if (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Intel && - cpuInfo.feature(gmx::CpuInfo::Feature::X86_Avx)) + if (cpuInfo.vendor() == gmx::CpuInfo::Vendor::Intel && cpuInfo.feature(gmx::CpuInfo::Feature::X86_Avx)) { nth = nthreads_omp_faster_Intel_AVX; } @@ -156,8 +155,8 @@ static int nthreads_omp_faster(const gmx::CpuInfo &cpuInfo, gmx_bool bUseGPU) // Intel Nehalem nth = nthreads_omp_faster_Nehalem; } - else if ((cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && cpuInfo.family() >= 23) || - cpuInfo.vendor() == gmx::CpuInfo::Vendor::Hygon) + else if ((cpuInfo.vendor() == gmx::CpuInfo::Vendor::Amd && cpuInfo.family() >= 23) + || cpuInfo.vendor() == gmx::CpuInfo::Vendor::Hygon) { // AMD Ryzen || Hygon Dhyana nth = nthreads_omp_faster_AMD_Ryzen; @@ -178,9 +177,7 @@ static int nthreads_omp_faster(const gmx::CpuInfo &cpuInfo, gmx_bool bUseGPU) } /*! \brief Returns that maximum OpenMP thread count that passes the efficiency check */ -gmx_unused static int nthreads_omp_efficient_max(int gmx_unused nrank, - const gmx::CpuInfo &cpuInfo, - gmx_bool bUseGPU) +gmx_unused static int nthreads_omp_efficient_max(int gmx_unused nrank, const gmx::CpuInfo& cpuInfo, gmx_bool bUseGPU) { if (GMX_OPENMP && GMX_MPI && (nrank > 1)) { @@ -195,13 +192,13 @@ gmx_unused static int nthreads_omp_efficient_max(int gmx_unused nrank, /*! \brief Return the number of thread-MPI ranks to use. * This is chosen such that we can always obey our own efficiency checks. */ -gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, - const gmx_hw_opt_t &hw_opt, +gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t* hwinfo, + const gmx_hw_opt_t& hw_opt, int nthreads_tot, int ngpu) { int nrank; - const gmx::CpuInfo &cpuInfo = *hwinfo->cpuInfo; + const gmx::CpuInfo& cpuInfo = *hwinfo->cpuInfo; GMX_RELEASE_ASSERT(nthreads_tot > 0, "There must be at least one thread per rank"); @@ -217,8 +214,11 @@ gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, /* In this case it is unclear if we should use 1 rank per GPU * or more or less, so we require also setting the number of ranks. */ - gmx_fatal(FARGS, "When using GPUs, setting the number of OpenMP threads without specifying the number " - "of ranks can lead to conflicting demands. Please specify the number of thread-MPI ranks " + gmx_fatal(FARGS, + "When using GPUs, setting the number of OpenMP threads without specifying " + "the number " + "of ranks can lead to conflicting demands. Please specify the number of " + "thread-MPI ranks " "as well (option -ntmpi)."); } @@ -230,9 +230,10 @@ gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, * If the user does not set the number of OpenMP threads, nthreads_omp==0 and * this code has no effect. */ - GMX_RELEASE_ASSERT(hw_opt.nthreads_omp >= 0, "nthreads_omp is negative, but previous checks should " + GMX_RELEASE_ASSERT(hw_opt.nthreads_omp >= 0, + "nthreads_omp is negative, but previous checks should " "have prevented this"); - while (nrank*hw_opt.nthreads_omp > hwinfo->nthreads_hw_avail && nrank > 1) + while (nrank * hw_opt.nthreads_omp > hwinfo->nthreads_hw_avail && nrank > 1) { nrank--; } @@ -242,8 +243,8 @@ gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, /* #thread < #gpu is very unlikely, but if so: waste gpu(s) */ nrank = nthreads_tot; } - else if (nthreads_tot > nthreads_omp_faster(cpuInfo, ngpu > 0) || - (ngpu > 1 && nthreads_tot/ngpu > nthreads_omp_mpi_target_max)) + else if (nthreads_tot > nthreads_omp_faster(cpuInfo, ngpu > 0) + || (ngpu > 1 && nthreads_tot / ngpu > nthreads_omp_mpi_target_max)) { /* The high OpenMP thread count will likely result in sub-optimal * performance. Increase the rank count to reduce the thread count @@ -259,16 +260,16 @@ gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, do { nshare++; - nrank = ngpu*nshare; - } - while (nthreads_tot/nrank > nthreads_omp_mpi_target_max || - (nthreads_tot/(ngpu*(nshare + 1)) >= nthreads_omp_mpi_ok_min_gpu && nthreads_tot % nrank != 0)); + nrank = ngpu * nshare; + } while (nthreads_tot / nrank > nthreads_omp_mpi_target_max + || (nthreads_tot / (ngpu * (nshare + 1)) >= nthreads_omp_mpi_ok_min_gpu + && nthreads_tot % nrank != 0)); } } else if (hw_opt.nthreads_omp > 0) { /* Here we could oversubscribe, when we do, we issue a warning later */ - nrank = std::max(1, nthreads_tot/hw_opt.nthreads_omp); + nrank = std::max(1, nthreads_tot / hw_opt.nthreads_omp); } else { @@ -288,10 +289,10 @@ gmx_unused static int get_tmpi_omp_thread_division(const gmx_hw_info_t *hwinfo, } //! Return whether hyper threading is enabled. -static bool -gmxSmtIsEnabled(const gmx::HardwareTopology &hwTop) +static bool gmxSmtIsEnabled(const gmx::HardwareTopology& hwTop) { - return (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::Basic && hwTop.machine().sockets[0].cores[0].hwThreads.size() > 1); + return (hwTop.supportLevel() >= gmx::HardwareTopology::SupportLevel::Basic + && hwTop.machine().sockets[0].cores[0].hwThreads.size() > 1); } namespace @@ -300,34 +301,32 @@ namespace //! Handles checks for algorithms that must use a single rank. class SingleRankChecker { - public: - SingleRankChecker() : value_(false) {} - /*! \brief Call this function for each possible condition - under which a single rank is required, along with a string - describing the constraint when it is applied. */ - void applyConstraint(bool condition, const char *description) - { - if (condition) - { - value_ = true; - reasons_.push_back(gmx::formatString("%s only supports a single rank.", description)); - } - } - //! After applying any conditions, is a single rank required? - bool mustUseOneRank() const - { - return value_; - } - /*! \brief Return a formatted string to use when writing a - message when a single rank is required, (or empty if no - constraint exists.) */ - std::string getMessage() const +public: + SingleRankChecker() : value_(false) {} + /*! \brief Call this function for each possible condition + under which a single rank is required, along with a string + describing the constraint when it is applied. */ + void applyConstraint(bool condition, const char* description) + { + if (condition) { - return formatAndJoin(reasons_, "\n", gmx::IdentityFormatter()); + value_ = true; + reasons_.push_back(gmx::formatString("%s only supports a single rank.", description)); } - private: - bool value_; - std::vector reasons_; + } + //! After applying any conditions, is a single rank required? + bool mustUseOneRank() const { return value_; } + /*! \brief Return a formatted string to use when writing a + message when a single rank is required, (or empty if no + constraint exists.) */ + std::string getMessage() const + { + return formatAndJoin(reasons_, "\n", gmx::IdentityFormatter()); + } + +private: + bool value_; + std::vector reasons_; }; } // namespace @@ -339,28 +338,28 @@ class SingleRankChecker * Thus all options should be internally consistent and consistent * with the hardware, except that ntmpi could be larger than #GPU. */ -int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, - gmx_hw_opt_t *hw_opt, - const std::vector &gpuIdsToUse, +int get_nthreads_mpi(const gmx_hw_info_t* hwinfo, + gmx_hw_opt_t* hw_opt, + const std::vector& gpuIdsToUse, bool nonbondedOnGpu, bool pmeOnGpu, - const t_inputrec *inputrec, - const gmx_mtop_t *mtop, - const gmx::MDLogger &mdlog, + const t_inputrec* inputrec, + const gmx_mtop_t* mtop, + const gmx::MDLogger& mdlog, bool doMembed) { - int nthreads_hw, nthreads_tot_max, nrank, ngpu; - int min_atoms_per_mpi_rank; + int nthreads_hw, nthreads_tot_max, nrank, ngpu; + int min_atoms_per_mpi_rank; - const gmx::CpuInfo &cpuInfo = *hwinfo->cpuInfo; - const gmx::HardwareTopology &hwTop = *hwinfo->hardwareTopology; + const gmx::CpuInfo& cpuInfo = *hwinfo->cpuInfo; + const gmx::HardwareTopology& hwTop = *hwinfo->hardwareTopology; if (pmeOnGpu) { - GMX_RELEASE_ASSERT((EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)) && - pme_gpu_supports_build(nullptr) && - pme_gpu_supports_hardware(*hwinfo, nullptr) && - pme_gpu_supports_input(*inputrec, *mtop, nullptr), + GMX_RELEASE_ASSERT((EEL_PME(inputrec->coulombtype) || EVDW_PME(inputrec->vdwtype)) + && pme_gpu_supports_build(nullptr) + && pme_gpu_supports_hardware(*hwinfo, nullptr) + && pme_gpu_supports_input(*inputrec, *mtop, nullptr), "PME can't be on GPUs unless we are using PME"); // PME on GPUs supports a single PME rank with PP running on the same or few other ranks. @@ -387,10 +386,16 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, std::string message = checker.getMessage(); if (hw_opt->nthreads_tmpi > 1) { - gmx_fatal(FARGS, "%s However, you asked for more than 1 thread-MPI rank, so mdrun cannot continue. " - "Choose a single rank, or a different algorithm.", message.c_str()); + gmx_fatal(FARGS, + "%s However, you asked for more than 1 thread-MPI rank, so mdrun cannot " + "continue. " + "Choose a single rank, or a different algorithm.", + message.c_str()); } - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted("%s Choosing to use only a single thread-MPI rank.", message.c_str()); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted("%s Choosing to use only a single thread-MPI rank.", + message.c_str()); return 1; } } @@ -407,7 +412,9 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, if (nthreads_hw <= 0) { /* This should normally not happen, but if it does, we handle it */ - gmx_fatal(FARGS, "The number of available hardware threads can not be detected, please specify the number of " + gmx_fatal(FARGS, + "The number of available hardware threads can not be detected, please specify " + "the number of " "MPI ranks and the number of OpenMP threads (if supported) manually with options " "-ntmpi and -ntomp, respectively"); } @@ -426,8 +433,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, * is a rerun with energy groups. */ ngpu = (nonbondedOnGpu ? gmx::ssize(gpuIdsToUse) : 0); - nrank = - get_tmpi_omp_thread_division(hwinfo, *hw_opt, nthreads_tot_max, ngpu); + nrank = get_tmpi_omp_thread_division(hwinfo, *hw_opt, nthreads_tot_max, ngpu); if (inputrec->eI == eiNM || EI_TPI(inputrec->eI)) { @@ -450,19 +456,18 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, } } - if (mtop->natoms/nrank < min_atoms_per_mpi_rank) + if (mtop->natoms / nrank < min_atoms_per_mpi_rank) { int nrank_new; /* the rank number was chosen automatically, but there are too few atoms per rank, so we need to reduce the rank count */ - nrank_new = std::max(1, mtop->natoms/min_atoms_per_mpi_rank); + nrank_new = std::max(1, mtop->natoms / min_atoms_per_mpi_rank); /* Avoid partial use of Hyper-Threading */ - if (gmxSmtIsEnabled(hwTop) && - nrank_new > nthreads_hw/2 && nrank_new < nthreads_hw) + if (gmxSmtIsEnabled(hwTop) && nrank_new > nthreads_hw / 2 && nrank_new < nthreads_hw) { - nrank_new = nthreads_hw/2; + nrank_new = nthreads_hw / 2; } /* If the user specified the total thread count, ensure this is @@ -471,8 +476,7 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, * to the size of the system, but if the user asked for this many * threads we should respect that. */ - while (hw_opt->nthreads_tot > 0 && - hw_opt->nthreads_tot % nrank_new != 0) + while (hw_opt->nthreads_tot > 0 && hw_opt->nthreads_tot % nrank_new != 0) { nrank_new--; } @@ -484,12 +488,12 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, int fac; fac = 2; - while (3*fac*2 <= nrank_new) + while (3 * fac * 2 <= nrank_new) { fac *= 2; } - nrank_new = (nrank_new/fac)*fac; + nrank_new = (nrank_new / fac) * fac; } else { @@ -514,11 +518,11 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, * we should use all hardware threads, unless we will violate * our own efficiency limitation on the thread count. */ - int nt_omp_max; + int nt_omp_max; nt_omp_max = nthreads_omp_efficient_max(nrank, cpuInfo, ngpu >= 1); - if (nrank*nt_omp_max < hwinfo->nthreads_hw_avail) + if (nrank * nt_omp_max < hwinfo->nthreads_hw_avail) { /* Limit the number of OpenMP threads to start */ hw_opt->nthreads_omp = nt_omp_max; @@ -528,25 +532,27 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, fprintf(stderr, "\n"); fprintf(stderr, "NOTE: Parallelization is limited by the small number of atoms,\n"); fprintf(stderr, " only starting %d thread-MPI ranks.\n", nrank); - fprintf(stderr, " You can use the -nt and/or -ntmpi option to optimize the number of threads.\n\n"); + fprintf(stderr, + " You can use the -nt and/or -ntmpi option to optimize the number of " + "threads.\n\n"); } return nrank; } -void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, +void check_resource_division_efficiency(const gmx_hw_info_t* hwinfo, bool willUsePhysicalGpu, gmx_bool bNtOmpOptionSet, - t_commrec *cr, - const gmx::MDLogger &mdlog) + t_commrec* cr, + const gmx::MDLogger& mdlog) { #if GMX_OPENMP && GMX_MPI GMX_UNUSED_VALUE(hwinfo); int nth_omp_min, nth_omp_max; char buf[1000]; - const char *mpi_option = GMX_THREAD_MPI ? " (option -ntmpi)" : ""; + const char* mpi_option = GMX_THREAD_MPI ? " (option -ntmpi)" : ""; /* This function should be called after thread-MPI (when configured) and * OpenMP have been initialized. Check that here. @@ -556,7 +562,8 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, GMX_RELEASE_ASSERT(nthreads_omp_faster_default >= nthreads_omp_mpi_ok_max, "Inconsistent OpenMP thread count default values"); } - GMX_RELEASE_ASSERT(gmx_omp_nthreads_get(emntDefault) >= 1, "Must have at least one OpenMP thread"); + GMX_RELEASE_ASSERT(gmx_omp_nthreads_get(emntDefault) >= 1, + "Must have at least one OpenMP thread"); nth_omp_min = gmx_omp_nthreads_get(emntDefault); nth_omp_max = gmx_omp_nthreads_get(emntDefault); @@ -595,16 +602,16 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, if (DOMAINDECOMP(cr)) { - if (nth_omp_max < nthreads_omp_mpi_ok_min || - nth_omp_max > nthreads_omp_mpi_ok_max) + if (nth_omp_max < nthreads_omp_mpi_ok_min || nth_omp_max > nthreads_omp_mpi_ok_max) { /* Note that we print target_max here, not ok_max */ - sprintf(buf, "Your choice of number of MPI ranks and amount of resources results in using %d OpenMP " - "threads per rank, which is most likely inefficient. The optimum is usually between %d and" + sprintf(buf, + "Your choice of number of MPI ranks and amount of resources results in using " + "%d OpenMP " + "threads per rank, which is most likely inefficient. The optimum is usually " + "between %d and" " %d threads per rank.", - nth_omp_max, - nthreads_omp_mpi_ok_min, - nthreads_omp_mpi_target_max); + nth_omp_max, nthreads_omp_mpi_ok_min, nthreads_omp_mpi_target_max); if (bNtOmpOptionSet) { @@ -616,13 +623,15 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, * probably the only way to ensure that all users don't waste * a lot of resources, since many users don't read logs/stderr. */ - gmx_fatal(FARGS, "%s If you want to run with this setup, specify the -ntomp option. But we suggest to " + gmx_fatal(FARGS, + "%s If you want to run with this setup, specify the -ntomp option. But " + "we suggest to " "change the number of MPI ranks%s.", buf, mpi_option); } } } -#else // !GMX_OPENMP || ! GMX_MPI +#else // !GMX_OPENMP || ! GMX_MPI GMX_UNUSED_VALUE(bNtOmpOptionSet); GMX_UNUSED_VALUE(willUsePhysicalGpu); GMX_UNUSED_VALUE(cr); @@ -633,38 +642,40 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, */ if (!GMX_OPENMP && !GMX_MPI && hwinfo->hardwareTopology->numberOfCores() > 1) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: GROMACS was compiled without OpenMP and (thread-)MPI support, can only use a single CPU core"); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: GROMACS was compiled without OpenMP and (thread-)MPI support, can " + "only use a single CPU core"); } #endif // end GMX_OPENMP && GMX_MPI } //! Dump a \c hw_opt to \c fp. -static void print_hw_opt(FILE *fp, const gmx_hw_opt_t *hw_opt) +static void print_hw_opt(FILE* fp, const gmx_hw_opt_t* hw_opt) { fprintf(fp, "hw_opt: nt %d ntmpi %d ntomp %d ntomp_pme %d gpu_id '%s' gputasks '%s'\n", - hw_opt->nthreads_tot, - hw_opt->nthreads_tmpi, - hw_opt->nthreads_omp, - hw_opt->nthreads_omp_pme, - hw_opt->gpuIdsAvailable.c_str(), - hw_opt->userGpuTaskAssignment.c_str()); + hw_opt->nthreads_tot, hw_opt->nthreads_tmpi, hw_opt->nthreads_omp, hw_opt->nthreads_omp_pme, + hw_opt->gpuIdsAvailable.c_str(), hw_opt->userGpuTaskAssignment.c_str()); } -void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, - gmx_hw_opt_t *hw_opt, +void checkAndUpdateHardwareOptions(const gmx::MDLogger& mdlog, + gmx_hw_opt_t* hw_opt, const bool isSimulationMasterRank, const int nPmeRanks, - const t_inputrec *inputrec) + const t_inputrec* inputrec) { /* Currently hw_opt only contains default settings or settings supplied * by the user on the command line. */ if (hw_opt->nthreads_omp < 0) { - gmx_fatal(FARGS, "The number of OpenMP threads supplied on the command line is %d, which is negative " - "and not allowed", hw_opt->nthreads_omp); + gmx_fatal(FARGS, + "The number of OpenMP threads supplied on the command line is %d, which is " + "negative " + "and not allowed", + hw_opt->nthreads_omp); } /* Check for OpenMP settings stored in environment variables, which can @@ -680,12 +691,16 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, if (hw_opt->nthreads_tot > 0) { - gmx_fatal(FARGS, "Setting the total number of threads is only supported with thread-MPI and GROMACS was " + gmx_fatal(FARGS, + "Setting the total number of threads is only supported with thread-MPI and " + "GROMACS was " "compiled without thread-MPI"); } if (hw_opt->nthreads_tmpi > 0) { - gmx_fatal(FARGS, "Setting the number of thread-MPI ranks is only supported with thread-MPI and GROMACS was " + gmx_fatal(FARGS, + "Setting the number of thread-MPI ranks is only supported with thread-MPI " + "and GROMACS was " "compiled without thread-MPI"); } } @@ -708,7 +723,8 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, if (!GMX_THREAD_MPI || isSimulationMasterRank) { /* Check if mdrun is free to choose the total number of threads */ - hw_opt->totNumThreadsIsAuto = (hw_opt->nthreads_omp == 0 && hw_opt->nthreads_omp_pme == 0 && hw_opt->nthreads_tot == 0); + hw_opt->totNumThreadsIsAuto = (hw_opt->nthreads_omp == 0 && hw_opt->nthreads_omp_pme == 0 + && hw_opt->nthreads_tot == 0); } if (GMX_OPENMP) @@ -720,15 +736,15 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, gmx_fatal(FARGS, "You need to specify -ntomp in addition to -ntomp_pme"); } - if (hw_opt->nthreads_omp_pme >= 1 && - hw_opt->nthreads_omp_pme != hw_opt->nthreads_omp && - nPmeRanks <= 0) + if (hw_opt->nthreads_omp_pme >= 1 && hw_opt->nthreads_omp_pme != hw_opt->nthreads_omp + && nPmeRanks <= 0) { /* This can result in a fatal error on many MPI ranks, * but since the thread count can differ per rank, * we can't easily avoid this. */ - gmx_fatal(FARGS, "You need to explicitly specify the number of PME ranks (-npme) when using " + gmx_fatal(FARGS, + "You need to explicitly specify the number of PME ranks (-npme) when using " "different numbers of OpenMP threads for PP and PME ranks"); } } @@ -738,7 +754,9 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, if (hw_opt->nthreads_omp > 1 || hw_opt->nthreads_omp_pme > 1) { - gmx_fatal(FARGS, "More than 1 OpenMP thread requested, but GROMACS was compiled without OpenMP support"); + gmx_fatal(FARGS, + "More than 1 OpenMP thread requested, but GROMACS was compiled without " + "OpenMP support"); } hw_opt->nthreads_omp = 1; hw_opt->nthreads_omp_pme = 1; @@ -749,27 +767,30 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, /* We have the same number of OpenMP threads for PP and PME ranks, * thus we can perform several consistency checks. */ - if (hw_opt->nthreads_tmpi > 0 && - hw_opt->nthreads_omp > 0 && - hw_opt->nthreads_tot != hw_opt->nthreads_tmpi*hw_opt->nthreads_omp) + if (hw_opt->nthreads_tmpi > 0 && hw_opt->nthreads_omp > 0 + && hw_opt->nthreads_tot != hw_opt->nthreads_tmpi * hw_opt->nthreads_omp) { - gmx_fatal(FARGS, "The total number of threads requested (%d) does not match the thread-MPI ranks (%d) " + gmx_fatal(FARGS, + "The total number of threads requested (%d) does not match the thread-MPI " + "ranks (%d) " "times the OpenMP threads (%d) requested", hw_opt->nthreads_tot, hw_opt->nthreads_tmpi, hw_opt->nthreads_omp); } - if (hw_opt->nthreads_tmpi > 0 && - hw_opt->nthreads_tot % hw_opt->nthreads_tmpi != 0) + if (hw_opt->nthreads_tmpi > 0 && hw_opt->nthreads_tot % hw_opt->nthreads_tmpi != 0) { - gmx_fatal(FARGS, "The total number of threads requested (%d) is not divisible by the number of thread-MPI " + gmx_fatal(FARGS, + "The total number of threads requested (%d) is not divisible by the number " + "of thread-MPI " "ranks requested (%d)", hw_opt->nthreads_tot, hw_opt->nthreads_tmpi); } - if (hw_opt->nthreads_omp > 0 && - hw_opt->nthreads_tot % hw_opt->nthreads_omp != 0) + if (hw_opt->nthreads_omp > 0 && hw_opt->nthreads_tot % hw_opt->nthreads_omp != 0) { - gmx_fatal(FARGS, "The total number of threads requested (%d) is not divisible by the number of OpenMP " + gmx_fatal(FARGS, + "The total number of threads requested (%d) is not divisible by the number " + "of OpenMP " "threads requested (%d)", hw_opt->nthreads_tot, hw_opt->nthreads_omp); } @@ -779,14 +800,18 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, { if (hw_opt->nthreads_omp > hw_opt->nthreads_tot) { - gmx_fatal(FARGS, "You requested %d OpenMP threads with %d total threads. Choose a total number of threads " + gmx_fatal(FARGS, + "You requested %d OpenMP threads with %d total threads. Choose a total " + "number of threads " "that is a multiple of the number of OpenMP threads.", hw_opt->nthreads_omp, hw_opt->nthreads_tot); } if (hw_opt->nthreads_tmpi > hw_opt->nthreads_tot) { - gmx_fatal(FARGS, "You requested %d thread-MPI ranks with %d total threads. Choose a total number of " + gmx_fatal(FARGS, + "You requested %d thread-MPI ranks with %d total threads. Choose a total " + "number of " "threads that is a multiple of the number of thread-MPI ranks.", hw_opt->nthreads_tmpi, hw_opt->nthreads_tot); } @@ -794,7 +819,9 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, if (GMX_THREAD_MPI && nPmeRanks > 0 && hw_opt->nthreads_tmpi <= 0) { - gmx_fatal(FARGS, "You need to explicitly specify the number of MPI threads (-ntmpi) when using separate PME ranks"); + gmx_fatal(FARGS, + "You need to explicitly specify the number of MPI threads (-ntmpi) when using " + "separate PME ranks"); } if (debug) @@ -804,24 +831,26 @@ void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, /* Asserting this simplifies the hardware resource division later * on. */ - GMX_RELEASE_ASSERT(!(hw_opt->nthreads_omp_pme >= 1 && hw_opt->nthreads_omp <= 0), - "PME thread count should only be set when the normal thread count is also set"); + GMX_RELEASE_ASSERT( + !(hw_opt->nthreads_omp_pme >= 1 && hw_opt->nthreads_omp <= 0), + "PME thread count should only be set when the normal thread count is also set"); } -void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt, - const gmx_hw_info_t &hwinfo, - const t_commrec *cr, - const gmx_multisim_t *ms, +void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t* hw_opt, + const gmx_hw_info_t& hwinfo, + const t_commrec* cr, + const gmx_multisim_t* ms, int numRanksOnThisNode, PmeRunMode pmeRunMode, - const gmx_mtop_t &mtop, - const t_inputrec &inputrec) + const gmx_mtop_t& mtop, + const t_inputrec& inputrec) { if (EI_TPI(inputrec.eI)) { if (hw_opt->nthreads_omp > 1) { - gmx_fatal(FARGS, "You requested OpenMP parallelization, which is not supported with TPI."); + gmx_fatal(FARGS, + "You requested OpenMP parallelization, which is not supported with TPI."); } hw_opt->nthreads_omp = 1; } @@ -840,7 +869,9 @@ void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt, if (!GMX_OPENMP && hw_opt->nthreads_omp > 1) { - gmx_fatal(FARGS, "You (indirectly) asked for OpenMP threads by setting -nt > -ntmpi, but GROMACS was " + gmx_fatal(FARGS, + "You (indirectly) asked for OpenMP threads by setting -nt > -ntmpi, but " + "GROMACS was " "compiled without OpenMP support"); } } @@ -867,29 +898,32 @@ void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt, * We currently only limit SMT for simulations using a single rank. * TODO: Consider limiting also for multi-rank simulations. */ - bool canChooseNumOpenmpThreads = (GMX_OPENMP && hw_opt->nthreads_omp <= 0); - bool haveSmtSupport = (hwinfo.hardwareTopology->supportLevel() >= gmx::HardwareTopology::SupportLevel::Basic && - hwinfo.hardwareTopology->machine().logicalProcessorCount > hwinfo.hardwareTopology->numberOfCores()); + bool canChooseNumOpenmpThreads = (GMX_OPENMP && hw_opt->nthreads_omp <= 0); + bool haveSmtSupport = + (hwinfo.hardwareTopology->supportLevel() >= gmx::HardwareTopology::SupportLevel::Basic + && hwinfo.hardwareTopology->machine().logicalProcessorCount + > hwinfo.hardwareTopology->numberOfCores()); bool simRunsSingleRankNBAndPmeOnGpu = (cr->nnodes == 1 && pmeRunMode == PmeRunMode::GPU); - if (canChooseNumOpenmpThreads && haveSmtSupport && - simRunsSingleRankNBAndPmeOnGpu) + if (canChooseNumOpenmpThreads && haveSmtSupport && simRunsSingleRankNBAndPmeOnGpu) { /* Note that the queing system might have limited us from using * all detected ncore_tot physical cores. We are currently not * checking for that here. */ - int numRanksTot = cr->nnodes*(isMultiSim(ms) ? ms->nsim : 1); - int numAtomsPerRank = mtop.natoms/cr->nnodes; - int numCoresPerRank = hwinfo.ncore_tot/numRanksTot; - if (numAtomsPerRank < c_numAtomsPerCoreSquaredSmtThreshold*gmx::square(numCoresPerRank)) + int numRanksTot = cr->nnodes * (isMultiSim(ms) ? ms->nsim : 1); + int numAtomsPerRank = mtop.natoms / cr->nnodes; + int numCoresPerRank = hwinfo.ncore_tot / numRanksTot; + if (numAtomsPerRank < c_numAtomsPerCoreSquaredSmtThreshold * gmx::square(numCoresPerRank)) { /* Choose one OpenMP thread per physical core */ - hw_opt->nthreads_omp = std::max(1, hwinfo.hardwareTopology->numberOfCores()/numRanksOnThisNode); + hw_opt->nthreads_omp = + std::max(1, hwinfo.hardwareTopology->numberOfCores() / numRanksOnThisNode); } } - GMX_RELEASE_ASSERT(GMX_OPENMP || hw_opt->nthreads_omp == 1, "Without OpenMP support, only one thread per rank can be used"); + GMX_RELEASE_ASSERT(GMX_OPENMP || hw_opt->nthreads_omp == 1, + "Without OpenMP support, only one thread per rank can be used"); /* We are done with updating nthreads_omp, we can set nthreads_omp_pme */ if (hw_opt->nthreads_omp_pme <= 0 && hw_opt->nthreads_omp > 0) @@ -908,9 +942,9 @@ namespace gmx void checkHardwareOversubscription(int numThreadsOnThisRank, int rank, - const HardwareTopology &hwTop, - const PhysicalNodeCommunicator &comm, - const MDLogger &mdlog) + const HardwareTopology& hwTop, + const PhysicalNodeCommunicator& comm, + const MDLogger& mdlog) { if (hwTop.supportLevel() < HardwareTopology::SupportLevel::LogicalProcessorCount) { @@ -940,12 +974,13 @@ void checkHardwareOversubscription(int numThreadsOnT { mesg += "O"; } - mesg += formatString("versubscribing the available %d logical CPU cores", hwTop.machine().logicalProcessorCount); + mesg += formatString("versubscribing the available %d logical CPU cores", + hwTop.machine().logicalProcessorCount); if (GMX_LIB_MPI) { mesg += " per node"; } - mesg += formatString(" with %d ", numThreadsOnThisNode); + mesg += formatString(" with %d ", numThreadsOnThisNode); if (numRanksOnThisNode == numThreadsOnThisNode) { if (GMX_THREAD_MPI) @@ -961,7 +996,7 @@ void checkHardwareOversubscription(int numThreadsOnT { mesg += "threads."; } - mesg += "\n This will cause considerable performance loss."; + mesg += "\n This will cause considerable performance loss."; /* Note that only the master rank logs to stderr and only ranks * with an open log file write to log. * TODO: When we have a proper parallel logging framework, @@ -971,4 +1006,4 @@ void checkHardwareOversubscription(int numThreadsOnT } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/resourcedivision.h b/src/gromacs/taskassignment/resourcedivision.h index 2bea6245a0..a2185babf4 100644 --- a/src/gromacs/taskassignment/resourcedivision.h +++ b/src/gromacs/taskassignment/resourcedivision.h @@ -63,7 +63,7 @@ namespace gmx class HardwareTopology; class MDLogger; class PhysicalNodeCommunicator; -} +} // namespace gmx /*! \brief Return the number of threads to use for thread-MPI based on how many * were requested, which algorithms we're using, @@ -73,14 +73,14 @@ class PhysicalNodeCommunicator; * with the hardware, except that ntmpi could be larger than number of GPUs. * If necessary, this function will modify hw_opt->nthreads_omp. */ -int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, - gmx_hw_opt_t *hw_opt, - const std::vector &gpuIdsToUse, +int get_nthreads_mpi(const gmx_hw_info_t* hwinfo, + gmx_hw_opt_t* hw_opt, + const std::vector& gpuIdsToUse, bool nonbondedOnGpu, bool pmeOnGpu, - const t_inputrec *inputrec, - const gmx_mtop_t *mtop, - const gmx::MDLogger &mdlog, + const t_inputrec* inputrec, + const gmx_mtop_t* mtop, + const gmx::MDLogger& mdlog, bool doMembed); /*! \brief Check if the number of OpenMP threads is within reasonable range @@ -91,11 +91,11 @@ int get_nthreads_mpi(const gmx_hw_info_t *hwinfo, * bNtOmpSet==TRUE; with bNtOptOptionSet==FALSE a fatal error is issued. * This function should be called after thread-MPI and OpenMP are set up. */ -void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, +void check_resource_division_efficiency(const gmx_hw_info_t* hwinfo, bool willUsePhysicalGpu, gmx_bool bNtOmpOptionSet, - t_commrec *cr, - const gmx::MDLogger &mdlog); + t_commrec* cr, + const gmx::MDLogger& mdlog); /*! \brief Checks what our hardware options are based on how Gromacs was compiled * and user-set options @@ -106,24 +106,24 @@ void check_resource_division_efficiency(const gmx_hw_info_t *hwinfo, * \param[in] nPmeRanks Number of PME ranks * \param[in] inputrec The input record, should point to a valid object when \p isSimulationMasterRank = true * */ -void checkAndUpdateHardwareOptions(const gmx::MDLogger &mdlog, - gmx_hw_opt_t *hw_opt, +void checkAndUpdateHardwareOptions(const gmx::MDLogger& mdlog, + gmx_hw_opt_t* hw_opt, bool isSimulationMasterRank, int nPmeRanks, - const t_inputrec *inputrec); + const t_inputrec* inputrec); /*! \brief Check, and if necessary update, the number of OpenMP threads requested * * Should be called when we know the MPI rank count and PME run mode. */ -void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t *hw_opt, - const gmx_hw_info_t &hwinfo, - const t_commrec *cr, - const gmx_multisim_t *ms, +void checkAndUpdateRequestedNumOpenmpThreads(gmx_hw_opt_t* hw_opt, + const gmx_hw_info_t& hwinfo, + const t_commrec* cr, + const gmx_multisim_t* ms, int numRanksOnThisNode, PmeRunMode pmeRunMode, - const gmx_mtop_t &mtop, - const t_inputrec &inputrec); + const gmx_mtop_t& mtop, + const t_inputrec& inputrec); namespace gmx { @@ -132,10 +132,10 @@ namespace gmx */ void checkHardwareOversubscription(int numThreadsOnThisRank, int rank, - const HardwareTopology &hwTop, - const PhysicalNodeCommunicator &comm, - const MDLogger &mdlog); + const HardwareTopology& hwTop, + const PhysicalNodeCommunicator& comm, + const MDLogger& mdlog); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/taskassignment.cpp b/src/gromacs/taskassignment/taskassignment.cpp index 62071fe19f..e88a78b240 100644 --- a/src/gromacs/taskassignment/taskassignment.cpp +++ b/src/gromacs/taskassignment/taskassignment.cpp @@ -89,9 +89,8 @@ namespace * that are eligible to run on GPUs. * \param[in] gpuIds The user-supplied GPU IDs. */ -std::vector -buildTaskAssignment(const GpuTasksOnRanks &gpuTasksOnRanksOfThisNode, - ArrayRef gpuIds) +std::vector buildTaskAssignment(const GpuTasksOnRanks& gpuTasksOnRanksOfThisNode, + ArrayRef gpuIds) { std::vector gpuTaskAssignmentOnRanksOfThisNode(gpuTasksOnRanksOfThisNode.size()); @@ -100,19 +99,20 @@ buildTaskAssignment(const GpuTasksOnRanks &gpuTasksOnRanksOfThisNode, // provided by the user, to build a vector of mappings of task to // ID, for each rank on this node. Note that if there have not // been any GPU tasks identified, then gpuIds can be empty. - auto currentGpuId = gpuIds.begin(); - auto gpuTaskAssignmentOnRank = gpuTaskAssignmentOnRanksOfThisNode.begin(); - for (const auto &gpuTasksOnRank : gpuTasksOnRanksOfThisNode) + auto currentGpuId = gpuIds.begin(); + auto gpuTaskAssignmentOnRank = gpuTaskAssignmentOnRanksOfThisNode.begin(); + for (const auto& gpuTasksOnRank : gpuTasksOnRanksOfThisNode) { gpuTaskAssignmentOnRank->reserve(gpuTasksOnRank.size()); - for (const auto &gpuTaskType : gpuTasksOnRank) + for (const auto& gpuTaskType : gpuTasksOnRank) { GMX_RELEASE_ASSERT(currentGpuId != gpuIds.end(), "Indexing out of range for GPU tasks"); - gpuTaskAssignmentOnRank->push_back({gpuTaskType, *currentGpuId}); + gpuTaskAssignmentOnRank->push_back({ gpuTaskType, *currentGpuId }); ++currentGpuId; } GMX_RELEASE_ASSERT(gpuTaskAssignmentOnRank->size() == gpuTasksOnRank.size(), - "Mismatch in number of GPU tasks on a rank with the number of elements in the resulting task assignment"); + "Mismatch in number of GPU tasks on a rank with the number of elements " + "in the resulting task assignment"); ++gpuTaskAssignmentOnRank; } @@ -132,11 +132,11 @@ bool isAnyGpuSharedBetweenRanks(ArrayRef gpuTaskAssignm // the same rank are sharing a device? for (size_t i = 0; i < gpuTaskAssignments.size(); ++i) { - for (const auto &taskOnRankI : gpuTaskAssignments[i]) + for (const auto& taskOnRankI : gpuTaskAssignments[i]) { - for (size_t j = i+1; j < gpuTaskAssignments.size(); ++j) + for (size_t j = i + 1; j < gpuTaskAssignments.size(); ++j) { - for (const auto &taskOnRankJ : gpuTaskAssignments[j]) + for (const auto& taskOnRankJ : gpuTaskAssignments[j]) { if (taskOnRankI.deviceId_ == taskOnRankJ.deviceId_) { @@ -149,26 +149,29 @@ bool isAnyGpuSharedBetweenRanks(ArrayRef gpuTaskAssignm return false; } -} // namespace +} // namespace -void -GpuTaskAssignments::logPerformanceHints(const MDLogger &mdlog, - size_t numCompatibleGpusOnThisNode) +void GpuTaskAssignments::logPerformanceHints(const MDLogger& mdlog, size_t numCompatibleGpusOnThisNode) { if (numCompatibleGpusOnThisNode > numGpuTasksOnThisNode_) { /* TODO In principle, this warning could be warranted only on * some nodes, but we lack the infrastructure to do a good job * of reporting that. */ - GMX_LOG(mdlog.warning).asParagraph(). - appendText("NOTE: You assigned the GPU tasks on a node such that some GPUs " - "available on that node are unused, which might not be optimal."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: You assigned the GPU tasks on a node such that some GPUs " + "available on that node are unused, which might not be optimal."); } if (isAnyGpuSharedBetweenRanks(assignmentForAllRanksOnThisNode_)) { - GMX_LOG(mdlog.warning).asParagraph(). - appendText("NOTE: You assigned the same GPU ID(s) to multiple ranks, which is a good idea if you have measured the performance of alternatives."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: You assigned the same GPU ID(s) to multiple ranks, which is a good " + "idea if you have measured the performance of alternatives."); } } @@ -176,51 +179,43 @@ namespace { //! Counts all the GPU tasks on this node. -size_t countGpuTasksOnThisNode(const GpuTasksOnRanks &gpuTasksOnRanksOfThisNode) +size_t countGpuTasksOnThisNode(const GpuTasksOnRanks& gpuTasksOnRanksOfThisNode) { size_t numGpuTasksOnThisNode = 0; - for (const auto &gpuTasksOnRank : gpuTasksOnRanksOfThisNode) + for (const auto& gpuTasksOnRank : gpuTasksOnRanksOfThisNode) { numGpuTasksOnThisNode += gpuTasksOnRank.size(); } return numGpuTasksOnThisNode; } -} // namespace +} // namespace GpuTaskAssignmentsBuilder::GpuTaskAssignmentsBuilder() = default; -GpuTaskAssignments -GpuTaskAssignmentsBuilder::build(const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_commrec *cr, - const gmx_multisim_t *ms, - const PhysicalNodeCommunicator &physicalNodeComm, - const TaskTarget nonbondedTarget, - const TaskTarget pmeTarget, - const TaskTarget bondedTarget, - const TaskTarget updateTarget, - const bool useGpuForNonbonded, - const bool useGpuForPme, - bool rankHasPpTask, - bool rankHasPmeTask) +GpuTaskAssignments GpuTaskAssignmentsBuilder::build(const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_commrec* cr, + const gmx_multisim_t* ms, + const PhysicalNodeCommunicator& physicalNodeComm, + const TaskTarget nonbondedTarget, + const TaskTarget pmeTarget, + const TaskTarget bondedTarget, + const TaskTarget updateTarget, + const bool useGpuForNonbonded, + const bool useGpuForPme, + bool rankHasPpTask, + bool rankHasPmeTask) { size_t numRanksOnThisNode = physicalNodeComm.size_; - std::vector gpuTasksOnThisRank = findGpuTasksOnThisRank(!gpuIdsToUse.empty(), - nonbondedTarget, - pmeTarget, - bondedTarget, - updateTarget, - useGpuForNonbonded, - useGpuForPme, - rankHasPpTask, - rankHasPmeTask); + std::vector gpuTasksOnThisRank = findGpuTasksOnThisRank( + !gpuIdsToUse.empty(), nonbondedTarget, pmeTarget, bondedTarget, updateTarget, + useGpuForNonbonded, useGpuForPme, rankHasPpTask, rankHasPmeTask); /* Communicate among ranks on this node to find each task that can * be executed on a GPU, on each rank. */ - auto gpuTasksOnRanksOfThisNode = findAllGpuTasksOnThisNode(gpuTasksOnThisRank, - physicalNodeComm); - size_t numGpuTasksOnThisNode = countGpuTasksOnThisNode(gpuTasksOnRanksOfThisNode); + auto gpuTasksOnRanksOfThisNode = findAllGpuTasksOnThisNode(gpuTasksOnThisRank, physicalNodeComm); + size_t numGpuTasksOnThisNode = countGpuTasksOnThisNode(gpuTasksOnRanksOfThisNode); std::vector taskAssignmentOnRanksOfThisNode; try @@ -257,24 +252,24 @@ GpuTaskAssignmentsBuilder::build(const std::vector &gpuIdsToUse, // IDs, even if we have more than one kind of GPU task, we // do a simple round-robin assignment. That's not ideal, // but we don't have any way to do a better job reliably. - generatedGpuIds = makeGpuIds(compatibleGpusToUse, numGpuTasksOnThisNode); + generatedGpuIds = makeGpuIds(compatibleGpusToUse, numGpuTasksOnThisNode); - if ((numGpuTasksOnThisNode > gpuIdsToUse.size()) && - (numGpuTasksOnThisNode % gpuIdsToUse.size() != 0)) + if ((numGpuTasksOnThisNode > gpuIdsToUse.size()) + && (numGpuTasksOnThisNode % gpuIdsToUse.size() != 0)) { // TODO Decorating the message with hostname should be // the job of an error-reporting module. char host[STRLEN]; gmx_gethostname(host, STRLEN); - GMX_THROW(InconsistentInputError - (formatString("There were %zu GPU tasks found on node %s, but %zu GPUs were " - "available. If the GPUs are equivalent, then it is usually best " - "to have a number of tasks that is a multiple of the number of GPUs. " - "You should reconsider your GPU task assignment, " - "number of ranks, or your use of the -nb, -pme, and -npme options, " - "perhaps after measuring the performance you can get.", numGpuTasksOnThisNode, - host, gpuIdsToUse.size()))); + GMX_THROW(InconsistentInputError(formatString( + "There were %zu GPU tasks found on node %s, but %zu GPUs were " + "available. If the GPUs are equivalent, then it is usually best " + "to have a number of tasks that is a multiple of the number of GPUs. " + "You should reconsider your GPU task assignment, " + "number of ranks, or your use of the -nb, -pme, and -npme options, " + "perhaps after measuring the performance you can get.", + numGpuTasksOnThisNode, host, gpuIdsToUse.size()))); } gpuIdsForTaskAssignment = generatedGpuIds; } @@ -287,11 +282,11 @@ GpuTaskAssignmentsBuilder::build(const std::vector &gpuIdsToUse, char host[STRLEN]; gmx_gethostname(host, STRLEN); - GMX_THROW(InconsistentInputError - (formatString("There were %zu GPU tasks assigned on node %s, but %zu GPU tasks were " - "identified, and these must match. Reconsider your GPU task assignment, " - "number of ranks, or your use of the -nb, -pme, and -npme options.", userGpuTaskAssignment.size(), - host, numGpuTasksOnThisNode))); + GMX_THROW(InconsistentInputError(formatString( + "There were %zu GPU tasks assigned on node %s, but %zu GPU tasks were " + "identified, and these must match. Reconsider your GPU task assignment, " + "number of ranks, or your use of the -nb, -pme, and -npme options.", + userGpuTaskAssignment.size(), host, numGpuTasksOnThisNode))); } // Did the user choose compatible GPUs? checkUserGpuIds(hardwareInfo.gpu_info, gpuIdsToUse, userGpuTaskAssignment); @@ -299,10 +294,9 @@ GpuTaskAssignmentsBuilder::build(const std::vector &gpuIdsToUse, gpuIdsForTaskAssignment = userGpuTaskAssignment; } taskAssignmentOnRanksOfThisNode = - buildTaskAssignment(gpuTasksOnRanksOfThisNode, gpuIdsForTaskAssignment); - + buildTaskAssignment(gpuTasksOnRanksOfThisNode, gpuIdsForTaskAssignment); } - catch (const std::exception &ex) + catch (const std::exception& ex) { // TODO This implementation is quite similar to that of // processExceptionAsFatalError (which implements @@ -337,32 +331,24 @@ GpuTaskAssignmentsBuilder::build(const std::vector &gpuIdsToUse, return gpuTaskAssignments; } -GpuTaskAssignments::GpuTaskAssignments(const gmx_hw_info_t &hardwareInfo) - : hardwareInfo_(hardwareInfo) +GpuTaskAssignments::GpuTaskAssignments(const gmx_hw_info_t& hardwareInfo) : + hardwareInfo_(hardwareInfo) { } -void -GpuTaskAssignments::reportGpuUsage(const MDLogger &mdlog, - bool printHostName, - bool useGpuForBonded, - PmeRunMode pmeRunMode) +void GpuTaskAssignments::reportGpuUsage(const MDLogger& mdlog, + bool printHostName, + bool useGpuForBonded, + PmeRunMode pmeRunMode) { - gmx::reportGpuUsage(mdlog, - assignmentForAllRanksOnThisNode_, - numGpuTasksOnThisNode_, - numRanksOnThisNode_, - printHostName, - useGpuForBonded, - pmeRunMode); + gmx::reportGpuUsage(mdlog, assignmentForAllRanksOnThisNode_, numGpuTasksOnThisNode_, + numRanksOnThisNode_, printHostName, useGpuForBonded, pmeRunMode); } -gmx_device_info_t * -GpuTaskAssignments::initNonbondedDevice(const t_commrec *cr) const +gmx_device_info_t* GpuTaskAssignments::initNonbondedDevice(const t_commrec* cr) const { - gmx_device_info_t *deviceInfo = nullptr; - const GpuTaskAssignment &gpuTaskAssignment = - assignmentForAllRanksOnThisNode_[indexOfThisRank_]; + gmx_device_info_t* deviceInfo = nullptr; + const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_]; // This works because only one task of each type per rank is currently permitted. auto nbGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), @@ -370,7 +356,7 @@ GpuTaskAssignments::initNonbondedDevice(const t_commrec *cr) const if (nbGpuTaskMapping != gpuTaskAssignment.end()) { int deviceId = nbGpuTaskMapping->deviceId_; - deviceInfo = getDeviceInfo(hardwareInfo_.gpu_info, deviceId); + deviceInfo = getDeviceInfo(hardwareInfo_.gpu_info, deviceId); init_gpu(deviceInfo); // TODO Setting up this sharing should probably part of @@ -384,16 +370,14 @@ GpuTaskAssignments::initNonbondedDevice(const t_commrec *cr) const return deviceInfo; } -gmx_device_info_t * -GpuTaskAssignments::initPmeDevice() const +gmx_device_info_t* GpuTaskAssignments::initPmeDevice() const { - gmx_device_info_t *deviceInfo = nullptr; - const GpuTaskAssignment &gpuTaskAssignment = - assignmentForAllRanksOnThisNode_[indexOfThisRank_]; + gmx_device_info_t* deviceInfo = nullptr; + const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_]; // This works because only one task of each type is currently permitted. - auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), - hasTaskType); + auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), + hasTaskType); const bool thisRankHasPmeGpuTask = (pmeGpuTaskMapping != gpuTaskAssignment.end()); if (thisRankHasPmeGpuTask) { @@ -403,26 +387,23 @@ GpuTaskAssignments::initPmeDevice() const return deviceInfo; } -bool -GpuTaskAssignments::thisRankHasPmeGpuTask() const +bool GpuTaskAssignments::thisRankHasPmeGpuTask() const { - const GpuTaskAssignment &gpuTaskAssignment = - assignmentForAllRanksOnThisNode_[indexOfThisRank_]; + const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_]; - auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), hasTaskType); + auto pmeGpuTaskMapping = std::find_if(gpuTaskAssignment.begin(), gpuTaskAssignment.end(), + hasTaskType); const bool thisRankHasPmeGpuTask = (pmeGpuTaskMapping != gpuTaskAssignment.end()); return thisRankHasPmeGpuTask; } -bool -GpuTaskAssignments::thisRankHasAnyGpuTask() const +bool GpuTaskAssignments::thisRankHasAnyGpuTask() const { - const GpuTaskAssignment &gpuTaskAssignment = - assignmentForAllRanksOnThisNode_[indexOfThisRank_]; + const GpuTaskAssignment& gpuTaskAssignment = assignmentForAllRanksOnThisNode_[indexOfThisRank_]; const bool thisRankHasAnyGpuTask = !gpuTaskAssignment.empty(); return thisRankHasAnyGpuTask; } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/taskassignment.h b/src/gromacs/taskassignment/taskassignment.h index b518638e0a..749d91bef3 100644 --- a/src/gromacs/taskassignment/taskassignment.h +++ b/src/gromacs/taskassignment/taskassignment.h @@ -89,11 +89,11 @@ struct GpuTaskMapping //! The type of this GPU task. GpuTask task_; //! Device ID on this node to which this GPU task is mapped. - int deviceId_; + int deviceId_; }; //! Container of GPU tasks on a rank, specifying the task type and GPU device ID, e.g. potentially ready for consumption by the modules on that rank. -using GpuTaskAssignment = std::vector ; +using GpuTaskAssignment = std::vector; class GpuTaskAssignments; @@ -122,58 +122,58 @@ class GpuTaskAssignments; * selection, or automatically. */ class GpuTaskAssignmentsBuilder { - public: - //! Constructor - GpuTaskAssignmentsBuilder(); +public: + //! Constructor + GpuTaskAssignmentsBuilder(); - /*! \brief Builds a GpuTaskAssignments - * - * This method reconciles - * - * - user mdrun command-line options, - * - the results of hardware detection - * - the duty assigned by the DD setup, - * - the requested simulation modules, and - * - the possible existence of multi-simulations - * - * to assign the GPUs on each physical node to the tasks on - * the ranks of that node. It throws InconsistentInputError - * when a/the useful GPU task assignment is not possible. - * - * \param[in] gpuIdsToUse The compatible GPUs that the user permitted us to use. - * \param[in] userGpuTaskAssignment The user-specified assignment of GPU tasks to device IDs. - * \param[in] hardwareInfo The detected hardware - * \param[in] cr Communication object. - * \param[in] ms Multi-simulation handler. - * \param[in] physicalNodeComm Communication object for this physical node. - * \param[in] nonbondedTarget The user's choice for mdrun -nb for where to assign - * short-ranged nonbonded interaction tasks. - * \param[in] pmeTarget The user's choice for mdrun -pme for where to assign - * long-ranged PME nonbonded interaction tasks. - * \param[in] bondedTarget The user's choice for mdrun -bonded for where to assign tasks. - * \param[in] updateTarget The user's choice for mdrun -update for where to assign tasks. - * \param[in] useGpuForNonbonded Whether GPUs will be used for nonbonded interactions. - * \param[in] useGpuForPme Whether GPUs will be used for PME interactions. - * \param[in] rankHasPpTask Whether this rank has a PP task - * \param[in] rankHasPmeTask Whether this rank has a PME task - * - * \throws std::bad_alloc If out of memory. - * InconsistentInputError If user and/or detected inputs are inconsistent. - */ - GpuTaskAssignments build(const std::vector &gpuIdsToUse, - const std::vector &userGpuTaskAssignment, - const gmx_hw_info_t &hardwareInfo, - const t_commrec *cr, - const gmx_multisim_t *ms, - const PhysicalNodeCommunicator &physicalNodeComm, - TaskTarget nonbondedTarget, - TaskTarget pmeTarget, - TaskTarget bondedTarget, - TaskTarget updateTarget, - bool useGpuForNonbonded, - bool useGpuForPme, - bool rankHasPpTask, - bool rankHasPmeTask); + /*! \brief Builds a GpuTaskAssignments + * + * This method reconciles + * + * - user mdrun command-line options, + * - the results of hardware detection + * - the duty assigned by the DD setup, + * - the requested simulation modules, and + * - the possible existence of multi-simulations + * + * to assign the GPUs on each physical node to the tasks on + * the ranks of that node. It throws InconsistentInputError + * when a/the useful GPU task assignment is not possible. + * + * \param[in] gpuIdsToUse The compatible GPUs that the user permitted us to use. + * \param[in] userGpuTaskAssignment The user-specified assignment of GPU tasks to device IDs. + * \param[in] hardwareInfo The detected hardware + * \param[in] cr Communication object. + * \param[in] ms Multi-simulation handler. + * \param[in] physicalNodeComm Communication object for this physical node. + * \param[in] nonbondedTarget The user's choice for mdrun -nb for where to assign + * short-ranged nonbonded interaction tasks. + * \param[in] pmeTarget The user's choice for mdrun -pme for where to assign + * long-ranged PME nonbonded interaction tasks. + * \param[in] bondedTarget The user's choice for mdrun -bonded for where to assign tasks. + * \param[in] updateTarget The user's choice for mdrun -update for where to assign tasks. + * \param[in] useGpuForNonbonded Whether GPUs will be used for nonbonded interactions. + * \param[in] useGpuForPme Whether GPUs will be used for PME interactions. + * \param[in] rankHasPpTask Whether this rank has a PP task + * \param[in] rankHasPmeTask Whether this rank has a PME task + * + * \throws std::bad_alloc If out of memory. + * InconsistentInputError If user and/or detected inputs are inconsistent. + */ + GpuTaskAssignments build(const std::vector& gpuIdsToUse, + const std::vector& userGpuTaskAssignment, + const gmx_hw_info_t& hardwareInfo, + const t_commrec* cr, + const gmx_multisim_t* ms, + const PhysicalNodeCommunicator& physicalNodeComm, + TaskTarget nonbondedTarget, + TaskTarget pmeTarget, + TaskTarget bondedTarget, + TaskTarget updateTarget, + bool useGpuForNonbonded, + bool useGpuForPme, + bool rankHasPpTask, + bool rankHasPmeTask); }; /*! \libinternal @@ -186,84 +186,81 @@ class GpuTaskAssignmentsBuilder * This assignment is made by a GpuTaskAssignmentsBuilder object. */ class GpuTaskAssignments { - public: - //! Public move constructor to use with the builder - GpuTaskAssignments(GpuTaskAssignments &&source) noexcept = default; - private: - // Let the builder handle construction - friend class GpuTaskAssignmentsBuilder; - //! Private constructor so only the builder can construct - GpuTaskAssignments(const gmx_hw_info_t &hardwareInfo); - /*! \brief Information about hardware on this physical node - * - * The lifetime of the object referred to must exceed that - * of this object. */ - const gmx_hw_info_t &hardwareInfo_; - //! The GPU task assignment for all ranks on this node - std::vector assignmentForAllRanksOnThisNode_; - /*! \brief The index of this rank within those on this node. - * - * This is useful for indexing into \c - * assignmentForAllRanksOnThisNode_. */ - index indexOfThisRank_ = -1; - //! Number of GPU tasks on this node. - size_t numGpuTasksOnThisNode_ = 0; - //! Number of ranks on this physical node. - size_t numRanksOnThisNode_ = 0; - public: - /*! \brief Log a report on how GPUs are being used on - * the ranks of the physical node of rank 0 of the simulation. - * - * \todo It could be useful to report also whether any nodes differed, - * and in what way. - * - * \param[in] mdlog Logging object. - * \param[in] printHostName Print the hostname in the usage information - * \param[in] useGpuForBonded Whether GPU PP tasks will do bonded work on the GPU - * \param[in] pmeRunMode Describes the execution of PME tasks - * - * \throws std::bad_alloc if out of memory */ - void - reportGpuUsage(const MDLogger &mdlog, - bool printHostName, - bool useGpuForBonded, - PmeRunMode pmeRunMode); - /*! \brief Logs to \c mdlog information that may help a user - * learn how to let mdrun make a task assignment that runs - * faster. - * - * \param[in] mdlog Logging object. - * \param[in] numCompatibleGpusOnThisNode The number of compatible GPUs on this node. - * */ - void logPerformanceHints(const MDLogger &mdlog, - size_t numCompatibleGpusOnThisNode); - /*! \brief Return handle to the initialized GPU to use for the - * nonbonded task on this rank, if any. - * - * Returns nullptr if no such task is assigned to this rank. - * - * \todo This also sets up DLB for device sharing, where - * appropriate, but that responsbility should move - * elsewhere. */ - gmx_device_info_t *initNonbondedDevice(const t_commrec *cr) const; - /*! \brief Return handle to the initialized GPU to use for the - * PME task on this rank, if any. - * - * Returns nullptr if no such task is assigned to this rank. */ - gmx_device_info_t *initPmeDevice() const; - //! Return whether this rank has a PME task running on a GPU - bool thisRankHasPmeGpuTask() const; - //! Return whether this rank has any task running on a GPU - bool thisRankHasAnyGpuTask() const; +public: + //! Public move constructor to use with the builder + GpuTaskAssignments(GpuTaskAssignments&& source) noexcept = default; + +private: + // Let the builder handle construction + friend class GpuTaskAssignmentsBuilder; + //! Private constructor so only the builder can construct + GpuTaskAssignments(const gmx_hw_info_t& hardwareInfo); + /*! \brief Information about hardware on this physical node + * + * The lifetime of the object referred to must exceed that + * of this object. */ + const gmx_hw_info_t& hardwareInfo_; + //! The GPU task assignment for all ranks on this node + std::vector assignmentForAllRanksOnThisNode_; + /*! \brief The index of this rank within those on this node. + * + * This is useful for indexing into \c + * assignmentForAllRanksOnThisNode_. */ + index indexOfThisRank_ = -1; + //! Number of GPU tasks on this node. + size_t numGpuTasksOnThisNode_ = 0; + //! Number of ranks on this physical node. + size_t numRanksOnThisNode_ = 0; + +public: + /*! \brief Log a report on how GPUs are being used on + * the ranks of the physical node of rank 0 of the simulation. + * + * \todo It could be useful to report also whether any nodes differed, + * and in what way. + * + * \param[in] mdlog Logging object. + * \param[in] printHostName Print the hostname in the usage information + * \param[in] useGpuForBonded Whether GPU PP tasks will do bonded work on the GPU + * \param[in] pmeRunMode Describes the execution of PME tasks + * + * \throws std::bad_alloc if out of memory */ + void reportGpuUsage(const MDLogger& mdlog, bool printHostName, bool useGpuForBonded, PmeRunMode pmeRunMode); + /*! \brief Logs to \c mdlog information that may help a user + * learn how to let mdrun make a task assignment that runs + * faster. + * + * \param[in] mdlog Logging object. + * \param[in] numCompatibleGpusOnThisNode The number of compatible GPUs on this node. + * */ + void logPerformanceHints(const MDLogger& mdlog, size_t numCompatibleGpusOnThisNode); + /*! \brief Return handle to the initialized GPU to use for the + * nonbonded task on this rank, if any. + * + * Returns nullptr if no such task is assigned to this rank. + * + * \todo This also sets up DLB for device sharing, where + * appropriate, but that responsbility should move + * elsewhere. */ + gmx_device_info_t* initNonbondedDevice(const t_commrec* cr) const; + /*! \brief Return handle to the initialized GPU to use for the + * PME task on this rank, if any. + * + * Returns nullptr if no such task is assigned to this rank. */ + gmx_device_info_t* initPmeDevice() const; + //! Return whether this rank has a PME task running on a GPU + bool thisRankHasPmeGpuTask() const; + //! Return whether this rank has any task running on a GPU + bool thisRankHasAnyGpuTask() const; }; //! Function for whether the task of \c mapping has value \c TaskType. template -bool hasTaskType(const GpuTaskMapping &mapping) +bool hasTaskType(const GpuTaskMapping& mapping) { return mapping.task_ == TaskType; } -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/taskassignment/tests/usergpuids.cpp b/src/gromacs/taskassignment/tests/usergpuids.cpp index e7b509a7cc..32454e3636 100644 --- a/src/gromacs/taskassignment/tests/usergpuids.cpp +++ b/src/gromacs/taskassignment/tests/usergpuids.cpp @@ -61,8 +61,8 @@ namespace TEST(UserTaskAssignmentStringHandlingTest, ParsingAndReconstructionWork) { - using ::testing::UnorderedElementsAreArray; using ::testing::ElementsAreArray; + using ::testing::UnorderedElementsAreArray; // TODO It would be nicer to use EXPECT_THAT(assignment, // UnorderedElementsAreArray({0,1}) but MSVC 2015 does @@ -70,52 +70,52 @@ TEST(UserTaskAssignmentStringHandlingTest, ParsingAndReconstructionWork) // Test simple assignments and back mappings { - const char *strings[] = { "01", "0,1", "0,1," }; - for (const auto &s : strings) + const char* strings[] = { "01", "0,1", "0,1," }; + for (const auto& s : strings) { auto assignment = parseUserTaskAssignmentString(s); - auto matcher = UnorderedElementsAreArray({0, 1}); + auto matcher = UnorderedElementsAreArray({ 0, 1 }); EXPECT_THAT(assignment, matcher) << "for string " << s; - EXPECT_EQ("0", makeGpuIdString(assignment, 1)); - EXPECT_EQ("0,1", makeGpuIdString(assignment, 2)); + EXPECT_EQ("0", makeGpuIdString(assignment, 1)); + EXPECT_EQ("0,1", makeGpuIdString(assignment, 2)); EXPECT_EQ("0,0,1", makeGpuIdString(assignment, 3)); - auto gpuidList = parseUserGpuIdString(s); + auto gpuidList = parseUserGpuIdString(s); EXPECT_THAT(gpuidList, ElementsAreArray(assignment)); } } // Test an input that could be a single large index, or two small indices; and back mappings { auto assignment = parseUserTaskAssignmentString("11"); - auto matcher = UnorderedElementsAreArray({1, 1}); + auto matcher = UnorderedElementsAreArray({ 1, 1 }); EXPECT_THAT(assignment, matcher); - EXPECT_EQ("1", makeGpuIdString(assignment, 1)); - EXPECT_EQ("1,1", makeGpuIdString(assignment, 2)); + EXPECT_EQ("1", makeGpuIdString(assignment, 1)); + EXPECT_EQ("1,1", makeGpuIdString(assignment, 2)); EXPECT_EQ("1,1,1", makeGpuIdString(assignment, 3)); } // Test an input that must be a single large index; and back mappings { - const char *s = "11,"; + const char* s = "11,"; auto assignment = parseUserTaskAssignmentString(s); - auto matcher = UnorderedElementsAreArray({11}); + auto matcher = UnorderedElementsAreArray({ 11 }); EXPECT_THAT(assignment, matcher); - EXPECT_EQ("11", makeGpuIdString(assignment, 1)); - EXPECT_EQ("11,11", makeGpuIdString(assignment, 2)); + EXPECT_EQ("11", makeGpuIdString(assignment, 1)); + EXPECT_EQ("11,11", makeGpuIdString(assignment, 2)); EXPECT_EQ("11,11,11", makeGpuIdString(assignment, 3)); - auto gpuidList = parseUserGpuIdString(s); + auto gpuidList = parseUserGpuIdString(s); EXPECT_THAT(gpuidList, ElementsAreArray(assignment)); } // Test multiple large indices; and back mappings { - const char *strings[] = { "11,12", "11,12," }; - for (const auto &s : strings) + const char* strings[] = { "11,12", "11,12," }; + for (const auto& s : strings) { auto assignment = parseUserTaskAssignmentString(s); - auto matcher = UnorderedElementsAreArray({11, 12}); + auto matcher = UnorderedElementsAreArray({ 11, 12 }); EXPECT_THAT(assignment, matcher) << "for string " << s; - EXPECT_EQ("11", makeGpuIdString(assignment, 1)); - EXPECT_EQ("11,12", makeGpuIdString(assignment, 2)); + EXPECT_EQ("11", makeGpuIdString(assignment, 1)); + EXPECT_EQ("11,12", makeGpuIdString(assignment, 2)); EXPECT_EQ("11,11,12", makeGpuIdString(assignment, 3)); } } @@ -134,22 +134,18 @@ TEST(GpuIdAndAssignmentStringHandlingTest, InvalidInputsThrow) { { // common invalid strings - const char *commonStrings[] = { - "a", "0a", ",01", ",0,1", ",0,1,", - ":0", "0a:1b", "0:1:2", - ",", ";", ":", "-", "=", + const char* commonStrings[] = { + "a", "0a", ",01", ",0,1", ",0,1,", ":0", "0a:1b", "0:1:2", ",", ";", ":", "-", "=", }; - for (const auto &s : commonStrings) + for (const auto& s : commonStrings) { EXPECT_THROW(parseUserTaskAssignmentString(s), InvalidInputError) << "for string " << s; EXPECT_THROW(parseUserGpuIdString(s), InvalidInputError) << "for string " << s; } // strings invalid only in user GPU ID strings - const char *gpuidStrings[] = { - "00", "0,0" - }; - for (const auto &s : gpuidStrings) + const char* gpuidStrings[] = { "00", "0,0" }; + for (const auto& s : gpuidStrings) { EXPECT_THROW(parseUserGpuIdString(s), InvalidInputError) << "for string " << s; } diff --git a/src/gromacs/taskassignment/usergpuids.cpp b/src/gromacs/taskassignment/usergpuids.cpp index 8189999245..a370e506f7 100644 --- a/src/gromacs/taskassignment/usergpuids.cpp +++ b/src/gromacs/taskassignment/usergpuids.cpp @@ -71,18 +71,18 @@ namespace gmx * \throws std::bad_alloc If out of memory. * InvalidInputError If an invalid character is found (ie not a digit or ','). */ -static std::vector -parseGpuDeviceIdentifierList(const std::string &gpuIdString) +static std::vector parseGpuDeviceIdentifierList(const std::string& gpuIdString) { std::vector digits; auto foundCommaDelimiters = gpuIdString.find(',') != std::string::npos; if (!foundCommaDelimiters) { - for (const auto &c : gpuIdString) + for (const auto& c : gpuIdString) { if (std::isdigit(c) == 0) { - GMX_THROW(InvalidInputError(formatString("Invalid character in GPU ID string: \"%c\"\n", c))); + GMX_THROW(InvalidInputError( + formatString("Invalid character in GPU ID string: \"%c\"\n", c))); } // Convert each character in the token to an integer digits.push_back(c - '0'); @@ -111,8 +111,7 @@ parseGpuDeviceIdentifierList(const std::string &gpuIdString) return digits; } -std::vector -parseUserGpuIdString(const std::string &gpuIdString) +std::vector parseUserGpuIdString(const std::string& gpuIdString) { // An optional comma is used to separate GPU IDs assigned to the // same type of task, which will be useful for any nodes that have @@ -123,19 +122,21 @@ parseUserGpuIdString(const std::string &gpuIdString) // Check and enforce that no duplicate IDs are allowed for (size_t i = 0; i != digits.size(); ++i) { - for (size_t j = i+1; j != digits.size(); ++j) + for (size_t j = i + 1; j != digits.size(); ++j) { if (digits[i] == digits[j]) { - GMX_THROW(InvalidInputError(formatString("The string of available GPU device IDs '%s' may not contain duplicate device IDs", gpuIdString.c_str()))); + GMX_THROW( + InvalidInputError(formatString("The string of available GPU device IDs " + "'%s' may not contain duplicate device IDs", + gpuIdString.c_str()))); } } } return digits; } -std::vector makeGpuIdsToUse(const gmx_gpu_info_t &gpuInfo, - const std::string &gpuIdsAvailableString) +std::vector makeGpuIdsToUse(const gmx_gpu_info_t& gpuInfo, const std::string& gpuIdsAvailableString) { auto compatibleGpus = getCompatibleGpus(gpuInfo); std::vector gpuIdsAvailable = parseUserGpuIdString(gpuIdsAvailableString); @@ -148,10 +149,10 @@ std::vector makeGpuIdsToUse(const gmx_gpu_info_t &gpuInfo, std::vector gpuIdsToUse; gpuIdsToUse.reserve(gpuIdsAvailable.size()); std::vector availableGpuIdsThatAreIncompatible; - for (const auto &availableGpuId : gpuIdsAvailable) + for (const auto& availableGpuId : gpuIdsAvailable) { bool availableGpuIsCompatible = false; - for (const auto &compatibleGpuId : compatibleGpus) + for (const auto& compatibleGpuId : compatibleGpus) { if (availableGpuId == compatibleGpuId) { @@ -171,26 +172,23 @@ std::vector makeGpuIdsToUse(const gmx_gpu_info_t &gpuInfo, } if (!availableGpuIdsThatAreIncompatible.empty()) { - auto message = "You requested mdrun to use GPUs with IDs " + gpuIdsAvailableString + - ", but that includes the following incompatible GPUs: " + - formatAndJoin(availableGpuIdsThatAreIncompatible, ",", StringFormatter("%d")) + - ". Request only compatible GPUs."; + auto message = "You requested mdrun to use GPUs with IDs " + gpuIdsAvailableString + + ", but that includes the following incompatible GPUs: " + + formatAndJoin(availableGpuIdsThatAreIncompatible, ",", StringFormatter("%d")) + + ". Request only compatible GPUs."; GMX_THROW(InvalidInputError(message)); } return gpuIdsToUse; } -std::vector -parseUserTaskAssignmentString(const std::string &gpuIdString) +std::vector parseUserTaskAssignmentString(const std::string& gpuIdString) { // Implement any additional constraints here that need to be imposed return parseGpuDeviceIdentifierList(gpuIdString); } -std::vector -makeGpuIds(ArrayRef compatibleGpus, - size_t numGpuTasks) +std::vector makeGpuIds(ArrayRef compatibleGpus, size_t numGpuTasks) { std::vector gpuIdsToUse; @@ -199,7 +197,8 @@ makeGpuIds(ArrayRef compatibleGpus, auto currentGpuId = compatibleGpus.begin(); for (size_t i = 0; i != numGpuTasks; ++i) { - GMX_ASSERT(!compatibleGpus.empty(), "Must have compatible GPUs from which to build a list of GPU IDs to use"); + GMX_ASSERT(!compatibleGpus.empty(), + "Must have compatible GPUs from which to build a list of GPU IDs to use"); gpuIdsToUse.push_back(*currentGpuId); ++currentGpuId; if (currentGpuId == compatibleGpus.end()) @@ -212,30 +211,27 @@ makeGpuIds(ArrayRef compatibleGpus, return gpuIdsToUse; } -std::string -makeGpuIdString(const std::vector &gpuIds, - int totalNumberOfTasks) +std::string makeGpuIdString(const std::vector& gpuIds, int totalNumberOfTasks) { auto resultGpuIds = makeGpuIds(gpuIds, totalNumberOfTasks); return formatAndJoin(resultGpuIds, ",", StringFormatter("%d")); } -void checkUserGpuIds(const gmx_gpu_info_t &gpu_info, - const std::vector &compatibleGpus, - const std::vector &gpuIds) +void checkUserGpuIds(const gmx_gpu_info_t& gpu_info, + const std::vector& compatibleGpus, + const std::vector& gpuIds) { bool foundIncompatibleGpuIds = false; - std::string message - = "Some of the requested GPUs do not exist, behave strangely, or are not compatible:\n"; + std::string message = + "Some of the requested GPUs do not exist, behave strangely, or are not compatible:\n"; - for (const auto &gpuId : gpuIds) + for (const auto& gpuId : gpuIds) { if (std::find(compatibleGpus.begin(), compatibleGpus.end(), gpuId) == compatibleGpus.end()) { foundIncompatibleGpuIds = true; - message += gmx::formatString(" GPU #%d: %s\n", - gpuId, - getGpuCompatibilityDescription(gpu_info, gpuId)); + message += gmx::formatString(" GPU #%d: %s\n", gpuId, + getGpuCompatibilityDescription(gpu_info, gpuId)); } } if (foundIncompatibleGpuIds) @@ -244,4 +240,4 @@ void checkUserGpuIds(const gmx_gpu_info_t &gpu_info, } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/taskassignment/usergpuids.h b/src/gromacs/taskassignment/usergpuids.h index ec74c3c1be..9d9bef4967 100644 --- a/src/gromacs/taskassignment/usergpuids.h +++ b/src/gromacs/taskassignment/usergpuids.h @@ -74,8 +74,7 @@ namespace gmx * InvalidInputError If an invalid character is found (ie not a digit or ',') or if * identifiers are duplicated in the specifier list. */ -std::vector -parseUserGpuIdString(const std::string &gpuIdString); +std::vector parseUserGpuIdString(const std::string& gpuIdString); /*! \brief Implement GPU ID selection by returning the available GPU * IDs on this physical node that are compatible. @@ -100,8 +99,7 @@ parseUserGpuIdString(const std::string &gpuIdString); * InvalidInputError If gpuIdsAvailableString specifies GPU IDs that are * not compatible. */ -std::vector makeGpuIdsToUse(const gmx_gpu_info_t &gpuInfo, - const std::string &gpuIdsAvailableString); +std::vector makeGpuIdsToUse(const gmx_gpu_info_t& gpuInfo, const std::string& gpuIdsAvailableString); /*! \brief Parse a GPU ID specifier string into a container describing device ID to task mapping. * @@ -117,9 +115,7 @@ std::vector makeGpuIdsToUse(const gmx_gpu_info_t &gpuInfo, * \throws std::bad_alloc If out of memory. * InvalidInputError If an invalid character is found (ie not a digit or ','). */ -std::vector -parseUserTaskAssignmentString(const std::string &gpuIdString); - +std::vector parseUserTaskAssignmentString(const std::string& gpuIdString); /*! \brief Make a vector containing \c numGpuTasks IDs of the IDs found in \c compatibleGpus. @@ -129,9 +125,7 @@ parseUserTaskAssignmentString(const std::string &gpuIdString); * \returns A sorted vector of IDs of compatible vectors, whose * length matches that of the number of GPU tasks required. */ -std::vector -makeGpuIds(ArrayRef compatibleGpus, - size_t numGpuTasks); +std::vector makeGpuIds(ArrayRef compatibleGpus, size_t numGpuTasks); /*! \brief Convert a container of GPU deviced IDs to a string that * can be used by gmx tune_pme as input to mdrun -gputasks. @@ -148,8 +142,7 @@ makeGpuIds(ArrayRef compatibleGpus, * * \throws std::bad_alloc If out of memory. */ -std::string -makeGpuIdString(const std::vector &gpuIds, int totalNumberOfTasks); +std::string makeGpuIdString(const std::vector& gpuIds, int totalNumberOfTasks); /*! \brief Check that all user-selected GPUs are compatible. * @@ -177,10 +170,10 @@ makeGpuIdString(const std::vector &gpuIds, int totalNumberOfTasks); * \throws std::bad_alloc If out of memory * InconsistentInputError If the assigned GPUs are not valid */ -void checkUserGpuIds(const gmx_gpu_info_t &gpu_info, - const std::vector &compatibleGpus, - const std::vector &gpuIds); +void checkUserGpuIds(const gmx_gpu_info_t& gpu_info, + const std::vector& compatibleGpus, + const std::vector& gpuIds); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/timing/cyclecounter.cpp b/src/gromacs/timing/cyclecounter.cpp index 6778a9d484..b4557e9076 100644 --- a/src/gromacs/timing/cyclecounter.cpp +++ b/src/gromacs/timing/cyclecounter.cpp @@ -42,10 +42,10 @@ #include #ifdef HAVE_SYS_TIME_H -#include +# include #endif #ifdef _MSC_VER -#include +# include #endif #include "gromacs/utility/basedefinitions.h" @@ -62,8 +62,7 @@ * calculate on this system (for whatever reason) the return value * will be -1, so check that it is positive before using it. */ -double -gmx_cycles_calibrate(double sampletime) +double gmx_cycles_calibrate(double sampletime) { #ifdef _MSC_VER @@ -74,7 +73,7 @@ gmx_cycles_calibrate(double sampletime) QueryPerformanceFrequency(&i); - return 1.0/static_cast(i.QuadPart); + return 1.0 / static_cast(i.QuadPart); /* end of MS Windows implementation */ #elif HAVE_GETTIMEOFDAY @@ -90,7 +89,7 @@ gmx_cycles_calibrate(double sampletime) return -1; } -#if (defined(__alpha__) || defined(__alpha)) +# if (defined(__alpha__) || defined(__alpha)) /* Alpha cannot count to more than 4e9, but I don't expect * that the architecture will go over 2GHz before it dies, so * up to 2.0 seconds of sampling should be safe. @@ -99,7 +98,7 @@ gmx_cycles_calibrate(double sampletime) { sampletime = 2.0; } -#endif +# endif /* Start a timing loop. We want this to be largely independent * of machine speed, so we need to start with a very small number @@ -119,16 +118,15 @@ gmx_cycles_calibrate(double sampletime) */ for (int i = 0; i < 10000; i++) { - d = d/(1.0+static_cast(i)); + d = d / (1.0 + static_cast(i)); } /* Read the time again */ gettimeofday(&t2, nullptr); c2 = gmx_cycles_read(); - timediff = static_cast(t2.tv_sec-t1.tv_sec)+(t2.tv_usec-t1.tv_usec)*1e-6; - } - while (timediff < sampletime); + timediff = static_cast(t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) * 1e-6; + } while (timediff < sampletime); - cyclediff = c2-c1; + cyclediff = c2 - c1; /* Add a very small result so the delay loop cannot be optimized away */ if (d < 1e-30) @@ -137,7 +135,7 @@ gmx_cycles_calibrate(double sampletime) } /* Return seconds per cycle */ - return timediff/cyclediff; + return timediff / cyclediff; #else /* No timing function available */ diff --git a/src/gromacs/timing/cyclecounter.h b/src/gromacs/timing/cyclecounter.h index 40dddfae2a..7be59377af 100644 --- a/src/gromacs/timing/cyclecounter.h +++ b/src/gromacs/timing/cyclecounter.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 1991-2006 David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,111 +52,93 @@ #include "config.h" #ifdef _MSC_VER -#include +# include #endif -#if ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)) && \ - (defined(__i386__) || defined(__x86_64__))) +#if ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)) \ + && (defined(__i386__) || defined(__x86_64__))) /* x86 or x86-64 with GCC inline assembly */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; -#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) +#elif ((defined __aarch64__) \ + && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) /* 64-bit ARM cycle counters with GCC inline assembly */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; #elif defined(__ARM_ARCH_7A__) && defined(__GNUC__) /* Armv7A can provide 64-bit cycles by returning two registers */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; #elif defined(_MSC_VER) -#include -typedef __int64 - gmx_cycles_t; +# include +typedef __int64 gmx_cycles_t; #elif (defined(__hpux) || defined(__HP_cc)) && defined(__ia64) /* HP compiler on ia64 */ -#include -typedef unsigned long - gmx_cycles_t; +# include +typedef unsigned long gmx_cycles_t; #elif (defined(__INTEL_COMPILER) || defined(__ECC)) && defined(__ia64__) /* Intel compiler on ia64 */ -#include -typedef unsigned long - gmx_cycles_t; +# include +typedef unsigned long gmx_cycles_t; #elif defined(__GNUC__) && defined(__ia64__) /* ia64 with GCC inline assembly */ -typedef unsigned long - gmx_cycles_t; +typedef unsigned long gmx_cycles_t; -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__GNUC__)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__GNUC__)) /* HP PA-RISC, inline asm with gcc */ -typedef unsigned long - gmx_cycles_t; +typedef unsigned long gmx_cycles_t; -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__hpux)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__hpux)) /* HP PA-RISC, instruction when using HP compiler */ -#include -typedef unsigned long - gmx_cycles_t; +# include +typedef unsigned long gmx_cycles_t; #elif defined(__GNUC__) && defined(__s390__) /* S390, taken from FFTW who got it from James Treacy */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; #elif defined(__GNUC__) && defined(__alpha__) /* gcc inline assembly on alpha CPUs */ -typedef unsigned long - gmx_cycles_t; +typedef unsigned long gmx_cycles_t; #elif defined(__GNUC__) && defined(__sparc_v9__) /* gcc inline assembly on sparc v9 */ -typedef unsigned long - gmx_cycles_t; +typedef unsigned long gmx_cycles_t; #elif defined(__DECC) && defined(__alpha) /* Digital GEM C compiler on alpha */ -#include -typedef unsigned long - gmx_cycles_t; +# include +typedef unsigned long gmx_cycles_t; #elif (defined(__sgi) && defined(CLOCK_SGI_CYCLE)) /* Irix compilers on SGI hardware. Get nanoseconds from struct timespec */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; -#elif (defined(__SVR4) && defined (__SUNPRO_CC)) +#elif (defined(__SVR4) && defined(__SUNPRO_CC)) /* Solaris high-resolution timers */ -typedef hrtime_t - gmx_cycles_t; +typedef hrtime_t gmx_cycles_t; -#elif defined(__xlC__) && defined (_AIX) +#elif defined(__xlC__) && defined(_AIX) /* AIX compilers */ -#include -#include -typedef unsigned long long - gmx_cycles_t; +# include +# include +typedef unsigned long long gmx_cycles_t; -#elif ( ( defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM) ) && \ - ( defined(__powerpc__) || defined(__ppc__) ) ) +#elif ((defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM)) \ + && (defined(__powerpc__) || defined(__ppc__))) /* PowerPC using gcc inline assembly (also works on xlc>=7.0 with -qasm=gcc) */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; #elif (defined(__MWERKS__) && (defined(MAC) || defined(macintosh))) /* Metrowerks on macintosh */ -typedef unsigned long long - gmx_cycles_t; +typedef unsigned long long gmx_cycles_t; #elif defined(__sun) && defined(__sparcv9) -typedef unsigned long - gmx_cycles_t; +typedef unsigned long gmx_cycles_t; #else /*! \brief Integer-like datatype for cycle counter values @@ -170,8 +152,7 @@ typedef unsigned long * you run the calibration routine you can also multiply it with a factor to * translate the cycle data to seconds. */ -typedef long - gmx_cycles_t; +typedef long gmx_cycles_t; #endif @@ -197,28 +178,29 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) { return 0; } -#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)) && \ - (defined(__i386__) || defined(__x86_64__)) && !defined(_CRAYC)) +#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__)) \ + && (defined(__i386__) || defined(__x86_64__)) && !defined(_CRAYC)) static __inline__ gmx_cycles_t gmx_cycles_read() { /* x86 with GCC inline assembly - pentium TSC register */ - unsigned low, high; + unsigned low, high; -#if HAVE_RDTSCP - __asm__ __volatile__("rdtscp" : "=a" (low), "=d" (high) :: "ecx" ); -#else - __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)); -#endif +# if HAVE_RDTSCP + __asm__ __volatile__("rdtscp" : "=a"(low), "=d"(high)::"ecx"); +# else + __asm__ __volatile__("rdtsc" : "=a"(low), "=d"(high)); +# endif const gmx_cycles_t c_low = low; const gmx_cycles_t c_high = high; - return c_low | c_high <<32; + return c_low | c_high << 32; } -#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) +#elif ((defined __aarch64__) \ + && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* 64-bit ARM cycle counters with GCC inline assembly */ - gmx_cycles_t cycle; - __asm__ __volatile__("mrs %0, cntvct_el0" : "=r" (cycle) ); + gmx_cycles_t cycle; + __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(cycle)); return cycle; } @@ -226,31 +208,31 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) static __inline__ gmx_cycles_t gmx_cycles_read(void) { unsigned int cycles_lo, cycles_hi; - asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cycles_lo), "=r" (cycles_hi)); + asm volatile("mrrc p15, 1, %0, %1, c14" : "=r"(cycles_lo), "=r"(cycles_hi)); return ((gmx_cycles_t)cycles_lo) | (((gmx_cycles_t)cycles_hi) << 32); } #elif defined(_MSC_VER) static __inline gmx_cycles_t gmx_cycles_read(void) { -#ifdef _M_ARM +# ifdef _M_ARM /* Windows on 64-bit ARM */ return __rdpmccntr64(); -#else +# else /* x86 */ -# if HAVE_RDTSCP +# if HAVE_RDTSCP unsigned int ui; return __rdtscp(&ui); -# else +# else return __rdtsc(); +# endif # endif -#endif } #elif (defined(__hpux) || defined(__HP_cc)) && defined(__ia64) static inline gmx_cycles_t gmx_cycles_read(void) { /* HP compiler on ia64 */ gmx_cycles_t ret; - ret = _Asm_mov_from_ar (_AREG_ITC); + ret = _Asm_mov_from_ar(_AREG_ITC); return ret; } #elif (defined(__INTEL_COMPILER) && defined(__ia64__)) @@ -264,19 +246,19 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* ia64 with GCC inline assembly */ gmx_cycles_t ret; - __asm__ __volatile__ ("mov %0=ar.itc" : "=r" (ret)); + __asm__ __volatile__("mov %0=ar.itc" : "=r"(ret)); return ret; } -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__GNUC__)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__GNUC__)) static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* HP PA-RISC, inline asm with gcc */ gmx_cycles_t ret; - __asm__ __volatile__("mfctl 16, %0" : "=r" (ret)); + __asm__ __volatile__("mfctl 16, %0" : "=r"(ret)); /* no input, nothing else clobbered */ return ret; } -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__hpux)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__hpux)) static inline gmx_cycles_t gmx_cycles_read(void) { /* HP PA-RISC, instruction when using HP compiler */ @@ -289,7 +271,7 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* S390, taken from FFTW who got it from James Treacy */ gmx_cycles_t cycle; - __asm__("stck 0(%0)" : : "a" (&(cycle)) : "memory", "cc"); + __asm__("stck 0(%0)" : : "a"(&(cycle)) : "memory", "cc"); return cycle; } #elif defined(__GNUC__) && defined(__alpha__) @@ -297,7 +279,7 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* gcc inline assembly on alpha CPUs */ unsigned long cycle; - __asm__ __volatile__ ("rpcc %0" : "=r" (cycle)); + __asm__ __volatile__("rpcc %0" : "=r"(cycle)); return (cycle & 0xFFFFFFFF); } #elif defined(__GNUC__) && defined(__sparc_v9__) @@ -305,7 +287,7 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* gcc inline assembly on sparc v9 */ unsigned long ret; - __asm__("rd %%tick, %0" : "=r" (ret)); + __asm__("rd %%tick, %0" : "=r"(ret)); return ret; } #elif defined(__DECC) && defined(__alpha) @@ -313,7 +295,7 @@ static __inline gmx_cycles_t gmx_cycles_read(void) { /* Digital GEM C compiler on alpha */ unsigned long cycle; - cycle = asm ("rpcc %v0"); + cycle = asm("rpcc %v0"); return (cycle & 0xFFFFFFFF); } #elif (defined(__sgi) && defined(CLOCK_SGI_CYCLE)) @@ -323,16 +305,15 @@ static __inline gmx_cycles_t gmx_cycles_read(void) struct timespec t; clock_gettime(CLOCK_SGI_CYCLE, &t); /* Return the number of nanoseconds, so we can subtract/add */ - return ((unsigned long long)t.tv_sec)*1000000000+ - (unsigned long long)t.tv_nsec; + return ((unsigned long long)t.tv_sec) * 1000000000 + (unsigned long long)t.tv_nsec; } -#elif (defined(__SVR4) && defined (__SUNPRO_CC)) +#elif (defined(__SVR4) && defined(__SUNPRO_CC)) static inline gmx_cycles_t gmx_cycles_read(void) { /* Solaris high-resolution timers */ return gethrtime(); } -#elif defined(__xlC__) && defined (_AIX) +#elif defined(__xlC__) && defined(_AIX) static inline gmx_cycles_t gmx_cycles_read(void) { /* AIX compilers. Inline the calculation instead of using library functions */ @@ -343,15 +324,15 @@ static inline gmx_cycles_t gmx_cycles_read(void) */ if (t1.flag == RTC_POWER_PC) { - return ((gmx_cycles_t)t1.tb_high)<<32 | (gmx_cycles_t)t1.tb_low; + return ((gmx_cycles_t)t1.tb_high) << 32 | (gmx_cycles_t)t1.tb_low; } else { - return ((gmx_cycles_t)t1.tb_high)*1000000000+(gmx_cycles_t)t1.tb_low; + return ((gmx_cycles_t)t1.tb_high) * 1000000000 + (gmx_cycles_t)t1.tb_low; } } -#elif ( ( defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM) ) && \ - ( defined(__powerpc__) || defined(__ppc__) ) ) +#elif ((defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM)) \ + && (defined(__powerpc__) || defined(__ppc__))) static __inline__ gmx_cycles_t gmx_cycles_read(void) { /* PowerPC using gcc inline assembly (and xlC>=7.0 with -qasm=gcc, and clang) */ @@ -361,11 +342,10 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) // clang 3.7 incorrectly warns that mftb* are // deprecated. That's not correct - see // https://llvm.org/bugs/show_bug.cgi?id=23680. - __asm__ __volatile__ ("mftbu %0" : "=r" (high1) : ); - __asm__ __volatile__ ("mftb %0" : "=r" (low) : ); - __asm__ __volatile__ ("mftbu %0" : "=r" (high2) : ); - } - while (high1 != high2); + __asm__ __volatile__("mftbu %0" : "=r"(high1) :); + __asm__ __volatile__("mftb %0" : "=r"(low) :); + __asm__ __volatile__("mftbu %0" : "=r"(high2) :); + } while (high1 != high2); return (((gmx_cycles_t)high2) << 32) | (gmx_cycles_t)low; } @@ -376,11 +356,10 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) unsigned int long low, high1, high2; do { - __asm__ __volatile__ ("mftbu %0" : "=r" (high1) : ); - __asm__ __volatile__ ("mftb %0" : "=r" (low) : ); - __asm__ __volatile__ ("mftbu %0" : "=r" (high2) : ); - } - while (high1 != high2); + __asm__ __volatile__("mftbu %0" : "=r"(high1) :); + __asm__ __volatile__("mftb %0" : "=r"(low) :); + __asm__ __volatile__("mftbu %0" : "=r"(high2) :); + } while (high1 != high2); return (((gmx_cycles_t)high2) << 32) | (gmx_cycles_t)low; } @@ -389,12 +368,12 @@ static __inline__ gmx_cycles_t gmx_cycles_read(void) static __inline__ gmx_cycles_t gmx_cycles_read(void) { gmx_cycles_t ret; - __asm__ __volatile__("rd %%tick, %0" : "=r" (ret)); + __asm__ __volatile__("rd %%tick, %0" : "=r"(ret)); return ret; } #elif defined(_CRAYC) -#include +# include static __inline gmx_cycles_t gmx_cycles_read(void) { @@ -433,14 +412,16 @@ static __inline__ bool gmx_cycles_have_counter(void) { return 0; } -#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__) || defined(_CRAYC)) && \ - (defined(__i386__) || defined(__x86_64__))) +#elif ((defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) \ + || defined(__PGIC__) || defined(_CRAYC)) \ + && (defined(__i386__) || defined(__x86_64__))) static __inline__ bool gmx_cycles_have_counter() { /* x86 or x86-64 with GCC inline assembly - pentium TSC register */ return true; } -#elif ((defined __aarch64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) +#elif ((defined __aarch64__) \ + && (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__PATHSCALE__) || defined(__PGIC__))) static __inline bool gmx_cycles_have_counter(void) { /* 64-bit ARM cycle counters with GCC inline assembly */ @@ -484,13 +465,13 @@ static __inline__ bool gmx_cycles_have_counter(void) /* AMD64 with GCC inline assembly - TSC register */ return 1; } -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__GNUC__)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__GNUC__)) static __inline__ bool gmx_cycles_have_counter(void) { /* HP PA-RISC, inline asm with gcc */ return 1; } -#elif ((defined(__hppa__) || defined(__hppa)) && defined (__hpux)) +#elif ((defined(__hppa__) || defined(__hppa)) && defined(__hpux)) static inline bool gmx_cycles_have_counter(void) { /* HP PA-RISC, instruction when using HP compiler */ @@ -526,20 +507,20 @@ static __inline bool gmx_cycles_have_counter(void) /* Irix compilers on SGI hardware */ return 1; } -#elif (defined(__SVR4) && defined (__SUNPRO_CC)) +#elif (defined(__SVR4) && defined(__SUNPRO_CC)) static inline bool gmx_cycles_have_counter(void) { /* Solaris high-resolution timers */ return 1; } -#elif defined(__xlC__) && defined (_AIX) +#elif defined(__xlC__) && defined(_AIX) static inline bool gmx_cycles_have_counter(void) { /* AIX compilers */ return 1; } -#elif ( ( defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM) ) && \ - ( defined(__powerpc__) || defined(__ppc__) ) ) +#elif ((defined(__GNUC__) || defined(__IBM_GCC_ASM) || defined(__IBM_STDCPP_ASM)) \ + && (defined(__powerpc__) || defined(__ppc__))) static __inline__ bool gmx_cycles_have_counter(void) { /* PowerPC using gcc inline assembly (and xlc>=7.0 with -qasm=gcc) */ @@ -579,7 +560,6 @@ static bool gmx_cycles_have_counter(void) * calculate on this system (for whatever reason) the return value * will be -1, so check that it is positive before using it. */ -double -gmx_cycles_calibrate(double sampletime); +double gmx_cycles_calibrate(double sampletime); #endif diff --git a/src/gromacs/timing/gpu_timing.h b/src/gromacs/timing/gpu_timing.h index ad2fa0bacc..82d444ea7e 100644 --- a/src/gromacs/timing/gpu_timing.h +++ b/src/gromacs/timing/gpu_timing.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,8 +46,8 @@ /*! \internal \brief GPU kernel time and call count. */ struct gmx_kernel_timing_data_t { - double t; /**< Accumulated lapsed time */ - int c; /**< Number of calls corresponding to the elapsed time */ + double t; /**< Accumulated lapsed time */ + int c; /**< Number of calls corresponding to the elapsed time */ }; /*! \internal \brief @@ -78,16 +78,16 @@ struct gmx_wallclock_gpu_pme_t /*! \internal \brief GPU NB timings for kernels and H2d/D2H transfers. */ struct gmx_wallclock_gpu_nbnxn_t { - gmx_kernel_timing_data_t ktime[2][2]; /**< table containing the timings of the four - versions of the nonbonded kernels: force-only, - force+energy, force+pruning, and force+energy+pruning */ - gmx_kernel_timing_data_t pruneTime; /**< table containing the timings of the 1st pass prune-only kernels */ + gmx_kernel_timing_data_t ktime[2][2]; /**< table containing the timings of the four + versions of the nonbonded kernels: force-only, + force+energy, force+pruning, and force+energy+pruning */ + gmx_kernel_timing_data_t pruneTime; /**< table containing the timings of the 1st pass prune-only kernels */ gmx_kernel_timing_data_t dynamicPruneTime; /**< table containing the timings of dynamic prune-only kernels */ - double nb_h2d_t; /**< host to device transfer time in nb calculation */ - double nb_d2h_t; /**< device to host transfer time in nb calculation */ - int nb_c; /**< total call count of the nonbonded gpu operations */ - double pl_h2d_t; /**< pair search step host to device transfer time */ - int pl_h2d_c; /**< pair search step host to device transfer call count */ + double nb_h2d_t; /**< host to device transfer time in nb calculation */ + double nb_d2h_t; /**< device to host transfer time in nb calculation */ + int nb_c; /**< total call count of the nonbonded gpu operations */ + double pl_h2d_t; /**< pair search step host to device transfer time */ + int pl_h2d_c; /**< pair search step host to device transfer call count */ }; #endif diff --git a/src/gromacs/timing/wallcycle.cpp b/src/gromacs/timing/wallcycle.cpp index cf2320591e..59a55b8bd1 100644 --- a/src/gromacs/timing/wallcycle.cpp +++ b/src/gromacs/timing/wallcycle.cpp @@ -66,7 +66,7 @@ static const bool useCycleSubcounters = GMX_CYCLE_SUBCOUNTERS; /* #define DEBUG_WCYCLE */ #ifdef DEBUG_WCYCLE -#include "gromacs/utility/fatalerror.h" +# include "gromacs/utility/fatalerror.h" #endif typedef struct @@ -78,49 +78,85 @@ typedef struct struct gmx_wallcycle { - wallcc_t *wcc; + wallcc_t* wcc; /* did we detect one or more invalid cycle counts */ - gmx_bool haveInvalidCount; + gmx_bool haveInvalidCount; /* variables for testing/debugging */ - gmx_bool wc_barrier; - wallcc_t *wcc_all; - int wc_depth; + gmx_bool wc_barrier; + wallcc_t* wcc_all; + int wc_depth; #ifdef DEBUG_WCYCLE -#define DEPTH_MAX 6 - int counterlist[DEPTH_MAX]; - int count_depth; +# define DEPTH_MAX 6 + int counterlist[DEPTH_MAX]; + int count_depth; #endif - int ewc_prev; - gmx_cycles_t cycle_prev; - int64_t reset_counters; + int ewc_prev; + gmx_cycles_t cycle_prev; + int64_t reset_counters; #if GMX_MPI - MPI_Comm mpi_comm_mygroup; + MPI_Comm mpi_comm_mygroup; #endif - wallcc_t *wcsc; + wallcc_t* wcsc; }; /* Each name should not exceed 19 printing characters (ie. terminating null can be twentieth) */ -static const char *wcn[ewcNR] = -{ - "Run", "Step", "PP during PME", "Domain decomp.", "DD comm. load", - "DD comm. bounds", "Vsite constr.", "Send X to PME", "Neighbor search", "Launch GPU ops.", - "Comm. coord.", "Force", "Wait + Comm. F", "PME mesh", - "PME redist. X/F", "PME spread", "PME gather", "PME 3D-FFT", "PME 3D-FFT Comm.", "PME solve LJ", "PME solve Elec", - "PME wait for PP", "Wait + Recv. PME F", - "Wait PME GPU spread", "PME 3D-FFT", "PME solve", /* the strings for FFT/solve are repeated here for mixed mode counters */ - "Wait PME GPU gather", "Wait Bonded GPU", "Reduce GPU PME F", - "Wait GPU NB nonloc.", "Wait GPU NB local", "NB X/F buffer ops.", - "Vsite spread", "COM pull force", "AWH", - "Write traj.", "Update", "Constraints", "Comm. energies", - "Enforced rotation", "Add rot. forces", "Position swapping", "IMD", "Test" -}; - -static const char *wcsn[ewcsNR] = -{ - "DD redist.", "DD NS grid + sort", "DD setup comm.", - "DD make top.", "DD make constr.", "DD top. other", - "NS grid local", "NS grid non-loc.", "NS search local", "NS search non-loc.", +static const char* wcn[ewcNR] = { "Run", + "Step", + "PP during PME", + "Domain decomp.", + "DD comm. load", + "DD comm. bounds", + "Vsite constr.", + "Send X to PME", + "Neighbor search", + "Launch GPU ops.", + "Comm. coord.", + "Force", + "Wait + Comm. F", + "PME mesh", + "PME redist. X/F", + "PME spread", + "PME gather", + "PME 3D-FFT", + "PME 3D-FFT Comm.", + "PME solve LJ", + "PME solve Elec", + "PME wait for PP", + "Wait + Recv. PME F", + "Wait PME GPU spread", + "PME 3D-FFT", + "PME solve", /* the strings for FFT/solve are repeated here for mixed mode counters */ + "Wait PME GPU gather", + "Wait Bonded GPU", + "Reduce GPU PME F", + "Wait GPU NB nonloc.", + "Wait GPU NB local", + "NB X/F buffer ops.", + "Vsite spread", + "COM pull force", + "AWH", + "Write traj.", + "Update", + "Constraints", + "Comm. energies", + "Enforced rotation", + "Add rot. forces", + "Position swapping", + "IMD", + "Test" }; + +static const char* wcsn[ewcsNR] = { + "DD redist.", + "DD NS grid + sort", + "DD setup comm.", + "DD make top.", + "DD make constr.", + "DD top. other", + "NS grid local", + "NS grid non-loc.", + "NS search local", + "NS search non-loc.", "Bonded F", "Bonded-FEP F", "Restraints F", @@ -140,15 +176,9 @@ static const char *wcsn[ewcsNR] = }; /* PME GPU timing events' names - correspond to the enum in the gpu_timing.h */ -static const char *PMEStageNames[] = -{ - "PME spline", - "PME spread", - "PME spline + spread", - "PME 3D-FFT r2c", - "PME solve", - "PME 3D-FFT c2r", - "PME gather", +static const char* PMEStageNames[] = { + "PME spline", "PME spread", "PME spline + spread", "PME 3D-FFT r2c", + "PME solve", "PME 3D-FFT c2r", "PME gather", }; gmx_bool wallcycle_have_counter() @@ -156,7 +186,7 @@ gmx_bool wallcycle_have_counter() return gmx_cycles_have_counter(); } -gmx_wallcycle_t wallcycle_init(FILE *fplog, int resetstep, t_commrec gmx_unused *cr) +gmx_wallcycle_t wallcycle_init(FILE* fplog, int resetstep, t_commrec gmx_unused* cr) { gmx_wallcycle_t wc; @@ -168,12 +198,12 @@ gmx_wallcycle_t wallcycle_init(FILE *fplog, int resetstep, t_commrec gmx_unused snew(wc, 1); - wc->haveInvalidCount = FALSE; - wc->wc_barrier = FALSE; - wc->wcc_all = nullptr; - wc->wc_depth = 0; - wc->ewc_prev = -1; - wc->reset_counters = resetstep; + wc->haveInvalidCount = FALSE; + wc->wc_barrier = FALSE; + wc->wcc_all = nullptr; + wc->wc_depth = 0; + wc->ewc_prev = -1; + wc->reset_counters = resetstep; #if GMX_MPI if (PAR(cr) && getenv("GMX_CYCLE_BARRIER") != nullptr) @@ -194,7 +224,7 @@ gmx_wallcycle_t wallcycle_init(FILE *fplog, int resetstep, t_commrec gmx_unused { fprintf(fplog, "\nWill time all the code during the run\n\n"); } - snew(wc->wcc_all, ewcNR*ewcNR); + snew(wc->wcc_all, ewcNR * ewcNR); } if (useCycleSubcounters) @@ -239,8 +269,8 @@ static void wallcycle_all_start(gmx_wallcycle_t wc, int ewc, gmx_cycles_t cycle) static void wallcycle_all_stop(gmx_wallcycle_t wc, int ewc, gmx_cycles_t cycle) { - wc->wcc_all[wc->ewc_prev*ewcNR+ewc].n += 1; - wc->wcc_all[wc->ewc_prev*ewcNR+ewc].c += cycle - wc->cycle_prev; + wc->wcc_all[wc->ewc_prev * ewcNR + ewc].n += 1; + wc->wcc_all[wc->ewc_prev * ewcNR + ewc].c += cycle - wc->cycle_prev; } @@ -251,8 +281,7 @@ static void debug_start_check(gmx_wallcycle_t wc, int ewc) if (wc->count_depth < 0 || wc->count_depth >= DEPTH_MAX) { - gmx_fatal(FARGS, "wallcycle counter depth out of range: %d", - wc->count_depth); + gmx_fatal(FARGS, "wallcycle counter depth out of range: %d", wc->count_depth); } wc->counterlist[wc->count_depth] = ewc; wc->count_depth++; @@ -266,7 +295,8 @@ static void debug_stop_check(gmx_wallcycle_t wc, int ewc) if (wc->count_depth < 0) { - gmx_fatal(FARGS, "wallcycle counter depth out of range when stopping %s: %d", wcn[ewc], wc->count_depth); + gmx_fatal(FARGS, "wallcycle counter depth out of range when stopping %s: %d", wcn[ewc], + wc->count_depth); } if (wc->counterlist[wc->count_depth] != ewc) { @@ -360,17 +390,17 @@ double wallcycle_stop(gmx_wallcycle_t wc, int ewc) * large, especially for ewcRUN. If we detect a negative count, * we will not print the cycle accounting table. */ - cycle = gmx_cycles_read(); + cycle = gmx_cycles_read(); if (cycle >= wc->wcc[ewc].start) { - last = cycle - wc->wcc[ewc].start; + last = cycle - wc->wcc[ewc].start; } else { last = 0; wc->haveInvalidCount = TRUE; } - wc->wcc[ewc].c += last; + wc->wcc[ewc].c += last; wc->wcc[ewc].n++; if (wc->wcc_all) { @@ -388,7 +418,7 @@ double wallcycle_stop(gmx_wallcycle_t wc, int ewc) return last; } -void wallcycle_get(gmx_wallcycle_t wc, int ewc, int *n, double *c) +void wallcycle_get(gmx_wallcycle_t wc, int ewc, int* n, double* c) { *n = wc->wcc[ewc].n; *c = static_cast(wc->wcc[ewc].c); @@ -412,7 +442,7 @@ void wallcycle_reset_all(gmx_wallcycle_t wc) if (wc->wcc_all) { - for (i = 0; i < ewcNR*ewcNR; i++) + for (i = 0; i < ewcNR * ewcNR; i++) { wc->wcc_all[i].n = 0; wc->wcc_all[i].c = 0; @@ -439,7 +469,7 @@ static gmx_bool is_pme_subcounter(int ewc) } /* Subtract counter ewc_sub timed inside a timing block for ewc_main */ -static void subtract_cycles(wallcc_t *wcc, int ewc_main, int ewc_sub) +static void subtract_cycles(wallcc_t* wcc, int ewc_main, int ewc_sub) { if (wcc[ewc_sub].n > 0) { @@ -450,7 +480,7 @@ static void subtract_cycles(wallcc_t *wcc, int ewc_main, int ewc_sub) else { /* Something is wrong with the cycle counting */ - wcc[ewc_main].c = 0; + wcc[ewc_main].c = 0; } } } @@ -472,7 +502,7 @@ void wallcycle_scale_by_num_threads(gmx_wallcycle_t wc, bool isPmeRank, int nthr { for (int j = 0; j < ewcNR; j++) { - wc->wcc_all[i*ewcNR+j].c *= nthreads_pme; + wc->wcc_all[i * ewcNR + j].c *= nthreads_pme; } } } @@ -484,7 +514,7 @@ void wallcycle_scale_by_num_threads(gmx_wallcycle_t wc, bool isPmeRank, int nthr { for (int j = 0; j < ewcNR; j++) { - wc->wcc_all[i*ewcNR+j].c *= nthreads_pp; + wc->wcc_all[i * ewcNR + j].c *= nthreads_pp; } } } @@ -510,16 +540,16 @@ void wallcycle_scale_by_num_threads(gmx_wallcycle_t wc, bool isPmeRank, int nthr * wcc_all are unused by the GPU reporting, but it is not satisfactory * for the future. Also, there's no need for MPI_Allreduce, since * only MASTERRANK uses any of the results. */ -WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) +WallcycleCounts wallcycle_sum(const t_commrec* cr, gmx_wallcycle_t wc) { WallcycleCounts cycles_sum; - wallcc_t *wcc; - double cycles[ewcNR+ewcsNR]; + wallcc_t* wcc; + double cycles[ewcNR + ewcsNR]; #if GMX_MPI - double cycles_n[ewcNR+ewcsNR+1]; + double cycles_n[ewcNR + ewcsNR + 1]; #endif - int i; - int nsum; + int i; + int nsum; if (wc == nullptr) { @@ -548,7 +578,8 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) if (wcc[ewcPMEMESH].n > 0) { /* This must be a PME only node, calculate the Wait + Comm. time */ - GMX_ASSERT(wcc[ewcRUN].c >= wcc[ewcPMEMESH].c, "Total run ticks must be greater than PME-only ticks"); + GMX_ASSERT(wcc[ewcRUN].c >= wcc[ewcPMEMESH].c, + "Total run ticks must be greater than PME-only ticks"); wcc[ewcPMEWAITCOMM].c = wcc[ewcRUN].c - wcc[ewcPMEMESH].c; } } @@ -559,7 +590,7 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) #if GMX_MPI cycles_n[i] = static_cast(wcc[i].n); #endif - cycles[i] = static_cast(wcc[i].c); + cycles[i] = static_cast(wcc[i].c); } nsum = ewcNR; if (wc->wcsc) @@ -567,9 +598,9 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) for (i = 0; i < ewcsNR; i++) { #if GMX_MPI - cycles_n[ewcNR+i] = static_cast(wc->wcsc[i].n); + cycles_n[ewcNR + i] = static_cast(wc->wcsc[i].n); #endif - cycles[ewcNR+i] = static_cast(wc->wcsc[i].c); + cycles[ewcNR + i] = static_cast(wc->wcsc[i].c); } nsum += ewcsNR; } @@ -577,15 +608,14 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) #if GMX_MPI if (cr->nnodes > 1) { - double buf[ewcNR+ewcsNR+1]; + double buf[ewcNR + ewcsNR + 1]; // TODO this code is used only at the end of the run, so we // can just do a simple reduce of haveInvalidCount in // wallcycle_print, and avoid bugs cycles_n[nsum] = (wc->haveInvalidCount ? 1 : 0); // TODO Use MPI_Reduce - MPI_Allreduce(cycles_n, buf, nsum + 1, MPI_DOUBLE, MPI_MAX, - cr->mpi_comm_mysim); + MPI_Allreduce(cycles_n, buf, nsum + 1, MPI_DOUBLE, MPI_MAX, cr->mpi_comm_mysim); for (i = 0; i < ewcNR; i++) { wcc[i].n = gmx::roundToInt(buf[i]); @@ -595,28 +625,26 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) { for (i = 0; i < ewcsNR; i++) { - wc->wcsc[i].n = gmx::roundToInt(buf[ewcNR+i]); + wc->wcsc[i].n = gmx::roundToInt(buf[ewcNR + i]); } } // TODO Use MPI_Reduce - MPI_Allreduce(cycles, cycles_sum.data(), nsum, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mysim); + MPI_Allreduce(cycles, cycles_sum.data(), nsum, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim); if (wc->wcc_all != nullptr) { double *buf_all, *cyc_all; - snew(cyc_all, ewcNR*ewcNR); - snew(buf_all, ewcNR*ewcNR); - for (i = 0; i < ewcNR*ewcNR; i++) + snew(cyc_all, ewcNR * ewcNR); + snew(buf_all, ewcNR * ewcNR); + for (i = 0; i < ewcNR * ewcNR; i++) { cyc_all[i] = wc->wcc_all[i].c; } // TODO Use MPI_Reduce - MPI_Allreduce(cyc_all, buf_all, ewcNR*ewcNR, MPI_DOUBLE, MPI_SUM, - cr->mpi_comm_mysim); - for (i = 0; i < ewcNR*ewcNR; i++) + MPI_Allreduce(cyc_all, buf_all, ewcNR * ewcNR, MPI_DOUBLE, MPI_SUM, cr->mpi_comm_mysim); + for (i = 0; i < ewcNR * ewcNR; i++) { wc->wcc_all[i].c = static_cast(buf_all[i]); } @@ -636,9 +664,8 @@ WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc) return cycles_sum; } -static void print_cycles(FILE *fplog, double c2t, const char *name, - int nnodes, int nthreads, - int ncalls, double c_sum, double tot) +static void +print_cycles(FILE* fplog, double c2t, const char* name, int nnodes, int nthreads, int ncalls, double c_sum, double tot) { char nnodes_str[STRLEN]; char nthreads_str[STRLEN]; @@ -675,16 +702,14 @@ static void print_cycles(FILE *fplog, double c2t, const char *name, ncalls_str[0] = 0; } /* Convert the cycle count to wallclock time for this task */ - wallt = c_sum*c2t; + wallt = c_sum * c2t; - fprintf(fplog, " %-19.19s %4s %4s %10s %10.3f %14.3f %5.1f\n", - name, nnodes_str, nthreads_str, ncalls_str, wallt, - c_sum*1e-9, percentage); + fprintf(fplog, " %-19.19s %4s %4s %10s %10.3f %14.3f %5.1f\n", name, nnodes_str, + nthreads_str, ncalls_str, wallt, c_sum * 1e-9, percentage); } } -static void print_gputimes(FILE *fplog, const char *name, - int n, double t, double tot_t) +static void print_gputimes(FILE* fplog, const char* name, int n, double t, double tot_t) { char num[11]; char avg_perf[11]; @@ -692,7 +717,7 @@ static void print_gputimes(FILE *fplog, const char *name, if (n > 0) { snprintf(num, sizeof(num), "%10d", n); - snprintf(avg_perf, sizeof(avg_perf), "%10.3f", t/n); + snprintf(avg_perf, sizeof(avg_perf), "%10.3f", t / n); } else { @@ -701,17 +726,15 @@ static void print_gputimes(FILE *fplog, const char *name, } if (t != tot_t && tot_t > 0) { - fprintf(fplog, " %-29s %10s%12.3f %s %5.1f\n", - name, num, t/1000, avg_perf, 100 * t/tot_t); + fprintf(fplog, " %-29s %10s%12.3f %s %5.1f\n", name, num, t / 1000, avg_perf, 100 * t / tot_t); } else { - fprintf(fplog, " %-29s %10s%12.3f %s %5.1f\n", - name, "", t/1000, avg_perf, 100.0); + fprintf(fplog, " %-29s %10s%12.3f %s %5.1f\n", name, "", t / 1000, avg_perf, 100.0); } } -static void print_header(FILE *fplog, int nrank_pp, int nth_pp, int nrank_pme, int nth_pme) +static void print_header(FILE* fplog, int nrank_pp, int nth_pp, int nrank_pme, int nth_pme) { int nrank_tot = nrank_pp + nrank_pme; if (0 == nrank_pme) @@ -744,17 +767,24 @@ static void print_header(FILE *fplog, int nrank_pp, int nth_pp, int nrank_pme, i } -void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int npme, - int nth_pp, int nth_pme, double realtime, - gmx_wallcycle_t wc, const WallcycleCounts &cyc_sum, - const gmx_wallclock_gpu_nbnxn_t *gpu_nbnxn_t, - const gmx_wallclock_gpu_pme_t *gpu_pme_t) +void wallcycle_print(FILE* fplog, + const gmx::MDLogger& mdlog, + int nnodes, + int npme, + int nth_pp, + int nth_pme, + double realtime, + gmx_wallcycle_t wc, + const WallcycleCounts& cyc_sum, + const gmx_wallclock_gpu_nbnxn_t* gpu_nbnxn_t, + const gmx_wallclock_gpu_pme_t* gpu_pme_t) { double tot, tot_for_pp, tot_for_rest, tot_cpu_overlap, gpu_cpu_ratio; double c2t, c2t_pp, c2t_pme = 0; int i, j, npp, nth_tot; char buf[STRLEN]; - const char *hline = "-----------------------------------------------------------------------------"; + const char* hline = + "-----------------------------------------------------------------------------"; if (wc == nullptr) { @@ -765,11 +795,11 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np GMX_ASSERT(nth_pme > 0, "Number of PME threads must be >0"); GMX_ASSERT(nnodes > 0, "Number of nodes must be >0"); GMX_ASSERT(npme >= 0, "Number of PME nodes cannot be negative"); - npp = nnodes - npme; + npp = nnodes - npme; /* npme is the number of PME-only ranks used, and we always do PP work */ GMX_ASSERT(npp > 0, "Number of particle-particle nodes must be >0"); - nth_tot = npp*nth_pp + npme*nth_pme; + nth_tot = npp * nth_pp + npme * nth_pme; /* When using PME-only nodes, the next line is valid for both PP-only and PME-only nodes because they started ewcRUN at the @@ -786,25 +816,33 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np timing data might still be sensible for some non-Jenkins run, than is lost from diagnosing Jenkins FP exceptions on runs about whose execution time we don't care. */ - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "WARNING: A total of %f CPU cycles was recorded, so mdrun cannot print a time accounting", - tot); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "WARNING: A total of %f CPU cycles was recorded, so mdrun cannot print a " + "time accounting", + tot); return; } if (wc->haveInvalidCount) { - GMX_LOG(mdlog.warning).asParagraph().appendText("NOTE: Detected invalid cycle counts, probably because threads moved between CPU cores that do not have synchronized cycle counters. Will not print the cycle accounting."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: Detected invalid cycle counts, probably because threads moved " + "between CPU cores that do not have synchronized cycle counters. Will not " + "print the cycle accounting."); return; } /* Conversion factor from cycles to seconds */ - c2t = realtime/tot; - c2t_pp = c2t * nth_tot / static_cast(npp*nth_pp); + c2t = realtime / tot; + c2t_pp = c2t * nth_tot / static_cast(npp * nth_pp); if (npme > 0) { - c2t_pme = c2t * nth_tot / static_cast(npme*nth_pme); + c2t_pme = c2t * nth_tot / static_cast(npme * nth_pme); } else { @@ -816,7 +854,7 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np print_header(fplog, npp, nth_pp, npme, nth_pme); fprintf(fplog, "%s\n", hline); - for (i = ewcPPDURINGPME+1; i < ewcNR; i++) + for (i = ewcPPDURINGPME + 1; i < ewcNR; i++) { if (is_pme_subcounter(i)) { @@ -830,17 +868,13 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np * fits in the required maximum of 19 characters. */ char buffer[STRLEN]; snprintf(buffer, STRLEN, "%s *", wcn[i]); - print_cycles(fplog, c2t_pme, buffer, - npme, nth_pme, - wc->wcc[i].n, cyc_sum[i], tot); + print_cycles(fplog, c2t_pme, buffer, npme, nth_pme, wc->wcc[i].n, cyc_sum[i], tot); } else { /* Print timing information when it is for a PP or PP+PME node */ - print_cycles(fplog, c2t_pp, wcn[i], - npp, nth_pp, - wc->wcc[i].n, cyc_sum[i], tot); + print_cycles(fplog, c2t_pp, wcn[i], npp, nth_pp, wc->wcc[i].n, cyc_sum[i], tot); tot_for_pp += cyc_sum[i]; } } @@ -851,22 +885,15 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np for (j = 0; j < ewcNR; j++) { snprintf(buf, 20, "%-9.9s %-9.9s", wcn[i], wcn[j]); - print_cycles(fplog, c2t_pp, buf, - npp, nth_pp, - wc->wcc_all[i*ewcNR+j].n, - wc->wcc_all[i*ewcNR+j].c, - tot); + print_cycles(fplog, c2t_pp, buf, npp, nth_pp, wc->wcc_all[i * ewcNR + j].n, + wc->wcc_all[i * ewcNR + j].c, tot); } } } tot_for_rest = tot * npp * nth_pp / static_cast(nth_tot); - print_cycles(fplog, c2t_pp, "Rest", - npp, nth_pp, - -1, tot_for_rest - tot_for_pp, tot); + print_cycles(fplog, c2t_pp, "Rest", npp, nth_pp, -1, tot_for_rest - tot_for_pp, tot); fprintf(fplog, "%s\n", hline); - print_cycles(fplog, c2t, "Total", - npp, nth_pp, - -1, tot, tot); + print_cycles(fplog, c2t, "Total", npp, nth_pp, -1, tot, tot); fprintf(fplog, "%s\n", hline); if (npme > 0) @@ -874,7 +901,8 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np fprintf(fplog, "(*) Note that with separate PME ranks, the walltime column actually sums to\n" " twice the total reported, but the cycle count total and %% are correct.\n" - "%s\n", hline); + "%s\n", + hline); } if (wc->wcc[ewcPMEMESH].n > 0) @@ -882,7 +910,7 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np // A workaround to not print breakdown when no subcounters were recorded. // TODO: figure out and record PME GPU counters (what to do with the waiting ones?) std::vector validPmeSubcounterIndices; - for (i = ewcPPDURINGPME+1; i < ewcNR; i++) + for (i = ewcPPDURINGPME + 1; i < ewcNR; i++) { if (is_pme_subcounter(i) && wc->wcc[i].n > 0) { @@ -896,9 +924,8 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np fprintf(fplog, "%s\n", hline); for (auto i : validPmeSubcounterIndices) { - print_cycles(fplog, npme > 0 ? c2t_pme : c2t_pp, wcn[i], - npme > 0 ? npme : npp, nth_pme, - wc->wcc[i].n, cyc_sum[i], tot); + print_cycles(fplog, npme > 0 ? c2t_pme : c2t_pp, wcn[i], npme > 0 ? npme : npp, + nth_pme, wc->wcc[i].n, cyc_sum[i], tot); } fprintf(fplog, "%s\n", hline); } @@ -910,9 +937,7 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np fprintf(fplog, "%s\n", hline); for (i = 0; i < ewcsNR; i++) { - print_cycles(fplog, c2t_pp, wcsn[i], - npp, nth_pp, - wc->wcsc[i].n, cyc_sum[ewcNR+i], tot); + print_cycles(fplog, c2t_pp, wcsn[i], npp, nth_pp, wc->wcsc[i].n, cyc_sum[ewcNR + i], tot); } fprintf(fplog, "%s\n", hline); } @@ -928,10 +953,8 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np } if (gpu_nbnxn_t) { - const char *k_log_str[2][2] = { - {"Nonbonded F kernel", "Nonbonded F+ene k."}, - {"Nonbonded F+prune k.", "Nonbonded F+ene+prune k."} - }; + const char* k_log_str[2][2] = { { "Nonbonded F kernel", "Nonbonded F+ene k." }, + { "Nonbonded F+prune k.", "Nonbonded F+ene+prune k." } }; tot_gpu += gpu_nbnxn_t->pl_h2d_t + gpu_nbnxn_t->nb_h2d_t + gpu_nbnxn_t->nb_d2h_t; /* add up the kernel timings */ @@ -949,15 +972,14 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np { tot_cpu_overlap += wc->wcc[ewcPMEMESH].c; } - tot_cpu_overlap *= realtime*1000/tot; /* convert s to ms */ + tot_cpu_overlap *= realtime * 1000 / tot; /* convert s to ms */ fprintf(fplog, "\n GPU timings\n%s\n", hline); - fprintf(fplog, " Computing: Count Wall t (s) ms/step %c\n", '%'); + fprintf(fplog, + " Computing: Count Wall t (s) ms/step %c\n", '%'); fprintf(fplog, "%s\n", hline); - print_gputimes(fplog, "Pair list H2D", - gpu_nbnxn_t->pl_h2d_c, gpu_nbnxn_t->pl_h2d_t, tot_gpu); - print_gputimes(fplog, "X / q H2D", - gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_h2d_t, tot_gpu); + print_gputimes(fplog, "Pair list H2D", gpu_nbnxn_t->pl_h2d_c, gpu_nbnxn_t->pl_h2d_t, tot_gpu); + print_gputimes(fplog, "X / q H2D", gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_h2d_t, tot_gpu); for (i = 0; i < 2; i++) { @@ -965,8 +987,8 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np { if (gpu_nbnxn_t->ktime[i][j].c) { - print_gputimes(fplog, k_log_str[i][j], - gpu_nbnxn_t->ktime[i][j].c, gpu_nbnxn_t->ktime[i][j].t, tot_gpu); + print_gputimes(fplog, k_log_str[i][j], gpu_nbnxn_t->ktime[i][j].c, + gpu_nbnxn_t->ktime[i][j].t, tot_gpu); } } } @@ -976,18 +998,17 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np { if (gpu_pme_t->timing[k].c) { - print_gputimes(fplog, PMEStageNames[k], - gpu_pme_t->timing[k].c, - gpu_pme_t->timing[k].t, - tot_gpu); + print_gputimes(fplog, PMEStageNames[k], gpu_pme_t->timing[k].c, + gpu_pme_t->timing[k].t, tot_gpu); } } } if (gpu_nbnxn_t->pruneTime.c) { - print_gputimes(fplog, "Pruning kernel", gpu_nbnxn_t->pruneTime.c, gpu_nbnxn_t->pruneTime.t, tot_gpu); + print_gputimes(fplog, "Pruning kernel", gpu_nbnxn_t->pruneTime.c, + gpu_nbnxn_t->pruneTime.t, tot_gpu); } - print_gputimes(fplog, "F D2H", gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_d2h_t, tot_gpu); + print_gputimes(fplog, "F D2H", gpu_nbnxn_t->nb_c, gpu_nbnxn_t->nb_d2h_t, tot_gpu); fprintf(fplog, "%s\n", hline); print_gputimes(fplog, "Total ", gpu_nbnxn_t->nb_c, tot_gpu, tot_gpu); fprintf(fplog, "%s\n", hline); @@ -997,15 +1018,17 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np * and avoid adding it to tot_gpu as this is not in the force * overlap. We print the fraction as relative to the rest. */ - print_gputimes(fplog, "*Dynamic pruning", gpu_nbnxn_t->dynamicPruneTime.c, gpu_nbnxn_t->dynamicPruneTime.t, tot_gpu); + print_gputimes(fplog, "*Dynamic pruning", gpu_nbnxn_t->dynamicPruneTime.c, + gpu_nbnxn_t->dynamicPruneTime.t, tot_gpu); fprintf(fplog, "%s\n", hline); } - gpu_cpu_ratio = tot_gpu/tot_cpu_overlap; + gpu_cpu_ratio = tot_gpu / tot_cpu_overlap; if (gpu_nbnxn_t->nb_c > 0 && wc->wcc[ewcFORCE].n > 0) { - fprintf(fplog, "\nAverage per-step force GPU/CPU evaluation time ratio: %.3f ms/%.3f ms = %.3f\n", - tot_gpu/gpu_nbnxn_t->nb_c, tot_cpu_overlap/wc->wcc[ewcFORCE].n, - gpu_cpu_ratio); + fprintf(fplog, + "\nAverage per-step force GPU/CPU evaluation time ratio: %.3f ms/%.3f ms = " + "%.3f\n", + tot_gpu / gpu_nbnxn_t->nb_c, tot_cpu_overlap / wc->wcc[ewcFORCE].n, gpu_cpu_ratio); } /* only print notes related to CPU-GPU load balance with PME */ @@ -1025,26 +1048,37 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np /* The user could have used -notunepme, * but we currently can't check that here. */ - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: The CPU has >25% more load than the GPU. This imbalance wastes\n" - " GPU resources. Maybe the domain decomposition limits the PME tuning.\n" - " In that case, try setting the DD grid manually (-dd) or lowering -dds."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: The CPU has >25% more load than the GPU. This " + "imbalance wastes\n" + " GPU resources. Maybe the domain decomposition " + "limits the PME tuning.\n" + " In that case, try setting the DD grid manually " + "(-dd) or lowering -dds."); } else { /* We should not end up here, unless the box is * too small for increasing the cut-off for PME tuning. */ - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: The CPU has >25% more load than the GPU. This imbalance wastes\n" - " GPU resources."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: The CPU has >25% more load than the GPU. This " + "imbalance wastes\n" + " GPU resources."); } } if (gpu_cpu_ratio > 1.25) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "NOTE: The GPU has >25% more load than the CPU. This imbalance wastes\n" - " CPU resources."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "NOTE: The GPU has >25% more load than the CPU. This imbalance " + "wastes\n" + " CPU resources."); } } } @@ -1052,40 +1086,48 @@ void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int np if (wc->wc_barrier) { - GMX_LOG(mdlog.warning).asParagraph().appendText( - "MPI_Barrier was called before each cycle start/stop\n" - "call, so timings are not those of real runs."); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendText( + "MPI_Barrier was called before each cycle start/stop\n" + "call, so timings are not those of real runs."); } - if (wc->wcc[ewcNB_XF_BUF_OPS].n > 0 && - (cyc_sum[ewcDOMDEC] > tot*0.1 || - cyc_sum[ewcNS] > tot*0.1)) + if (wc->wcc[ewcNB_XF_BUF_OPS].n > 0 && (cyc_sum[ewcDOMDEC] > tot * 0.1 || cyc_sum[ewcNS] > tot * 0.1)) { /* Only the sim master calls this function, so always print to stderr */ if (wc->wcc[ewcDOMDEC].n == 0) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: %d %% of the run time was spent in pair search,\n" - " you might want to increase nstlist (this has no effect on accuracy)\n", - gmx::roundToInt(100*cyc_sum[ewcNS]/tot)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: %d %% of the run time was spent in pair search,\n" + " you might want to increase nstlist (this has no effect on " + "accuracy)\n", + gmx::roundToInt(100 * cyc_sum[ewcNS] / tot)); } else { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: %d %% of the run time was spent in domain decomposition,\n" - " %d %% of the run time was spent in pair search,\n" - " you might want to increase nstlist (this has no effect on accuracy)\n", - gmx::roundToInt(100*cyc_sum[ewcDOMDEC]/tot), - gmx::roundToInt(100*cyc_sum[ewcNS]/tot)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: %d %% of the run time was spent in domain decomposition,\n" + " %d %% of the run time was spent in pair search,\n" + " you might want to increase nstlist (this has no effect on " + "accuracy)\n", + gmx::roundToInt(100 * cyc_sum[ewcDOMDEC] / tot), + gmx::roundToInt(100 * cyc_sum[ewcNS] / tot)); } } - if (cyc_sum[ewcMoveE] > tot*0.05) + if (cyc_sum[ewcMoveE] > tot * 0.05) { - GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted( - "NOTE: %d %% of the run time was spent communicating energies,\n" - " you might want to increase some nst* mdp options\n", - gmx::roundToInt(100*cyc_sum[ewcMoveE]/tot)); + GMX_LOG(mdlog.warning) + .asParagraph() + .appendTextFormatted( + "NOTE: %d %% of the run time was spent communicating energies,\n" + " you might want to increase some nst* mdp options\n", + gmx::roundToInt(100 * cyc_sum[ewcMoveE] / tot)); } } diff --git a/src/gromacs/timing/wallcycle.h b/src/gromacs/timing/wallcycle.h index ed1d6a59ec..fa65919c60 100644 --- a/src/gromacs/timing/wallcycle.h +++ b/src/gromacs/timing/wallcycle.h @@ -44,29 +44,71 @@ #include "gromacs/utility/basedefinitions.h" -typedef struct gmx_wallcycle *gmx_wallcycle_t; +typedef struct gmx_wallcycle* gmx_wallcycle_t; struct t_commrec; static constexpr gmx_wallcycle* nullWallcycle = nullptr; -enum { - ewcRUN, ewcSTEP, ewcPPDURINGPME, ewcDOMDEC, ewcDDCOMMLOAD, - ewcDDCOMMBOUND, ewcVSITECONSTR, ewcPP_PMESENDX, ewcNS, ewcLAUNCH_GPU, - ewcMOVEX, ewcFORCE, ewcMOVEF, ewcPMEMESH, - ewcPME_REDISTXF, ewcPME_SPREAD, ewcPME_GATHER, ewcPME_FFT, ewcPME_FFTCOMM, ewcLJPME, ewcPME_SOLVE, - ewcPMEWAITCOMM, ewcPP_PMEWAITRECVF, - ewcWAIT_GPU_PME_SPREAD, ewcPME_FFT_MIXED_MODE, ewcPME_SOLVE_MIXED_MODE, - ewcWAIT_GPU_PME_GATHER, ewcWAIT_GPU_BONDED, ewcPME_GPU_F_REDUCTION, - ewcWAIT_GPU_NB_NL, ewcWAIT_GPU_NB_L, ewcNB_XF_BUF_OPS, - ewcVSITESPREAD, ewcPULLPOT, ewcAWH, - ewcTRAJ, ewcUPDATE, ewcCONSTR, ewcMoveE, ewcROT, ewcROTadd, ewcSWAP, ewcIMD, - ewcTEST, ewcNR +enum +{ + ewcRUN, + ewcSTEP, + ewcPPDURINGPME, + ewcDOMDEC, + ewcDDCOMMLOAD, + ewcDDCOMMBOUND, + ewcVSITECONSTR, + ewcPP_PMESENDX, + ewcNS, + ewcLAUNCH_GPU, + ewcMOVEX, + ewcFORCE, + ewcMOVEF, + ewcPMEMESH, + ewcPME_REDISTXF, + ewcPME_SPREAD, + ewcPME_GATHER, + ewcPME_FFT, + ewcPME_FFTCOMM, + ewcLJPME, + ewcPME_SOLVE, + ewcPMEWAITCOMM, + ewcPP_PMEWAITRECVF, + ewcWAIT_GPU_PME_SPREAD, + ewcPME_FFT_MIXED_MODE, + ewcPME_SOLVE_MIXED_MODE, + ewcWAIT_GPU_PME_GATHER, + ewcWAIT_GPU_BONDED, + ewcPME_GPU_F_REDUCTION, + ewcWAIT_GPU_NB_NL, + ewcWAIT_GPU_NB_L, + ewcNB_XF_BUF_OPS, + ewcVSITESPREAD, + ewcPULLPOT, + ewcAWH, + ewcTRAJ, + ewcUPDATE, + ewcCONSTR, + ewcMoveE, + ewcROT, + ewcROTadd, + ewcSWAP, + ewcIMD, + ewcTEST, + ewcNR }; -enum { - ewcsDD_REDIST, ewcsDD_GRID, ewcsDD_SETUPCOMM, - ewcsDD_MAKETOP, ewcsDD_MAKECONSTR, ewcsDD_TOPOTHER, - ewcsNBS_GRID_LOCAL, ewcsNBS_GRID_NONLOCAL, - ewcsNBS_SEARCH_LOCAL, ewcsNBS_SEARCH_NONLOCAL, +enum +{ + ewcsDD_REDIST, + ewcsDD_GRID, + ewcsDD_SETUPCOMM, + ewcsDD_MAKETOP, + ewcsDD_MAKECONSTR, + ewcsDD_TOPOTHER, + ewcsNBS_GRID_LOCAL, + ewcsNBS_GRID_NONLOCAL, + ewcsNBS_SEARCH_LOCAL, + ewcsNBS_SEARCH_NONLOCAL, ewcsLISTED, ewcsLISTED_FEP, ewcsRESTRAINTS, @@ -89,7 +131,7 @@ enum { gmx_bool wallcycle_have_counter(); /* Returns if cycle counting is supported */ -gmx_wallcycle_t wallcycle_init(FILE *fplog, int resetstep, struct t_commrec *cr); +gmx_wallcycle_t wallcycle_init(FILE* fplog, int resetstep, struct t_commrec* cr); /* Returns the wall cycle structure. * Returns NULL when cycle counting is not supported. */ @@ -109,7 +151,7 @@ double wallcycle_stop(gmx_wallcycle_t wc, int ewc); void wallcycle_increment_event_count(gmx_wallcycle_t wc, int ewc); /* Only increment call count for ewc by one */ -void wallcycle_get(gmx_wallcycle_t wc, int ewc, int *n, double *c); +void wallcycle_get(gmx_wallcycle_t wc, int ewc, int* n, double* c); /* Returns the cumulative count and cycle count for ewc */ void wallcycle_reset_all(gmx_wallcycle_t wc); diff --git a/src/gromacs/timing/wallcyclereporting.h b/src/gromacs/timing/wallcyclereporting.h index cffbb8e61a..270605772c 100644 --- a/src/gromacs/timing/wallcyclereporting.h +++ b/src/gromacs/timing/wallcyclereporting.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,22 +53,28 @@ namespace gmx class MDLogger; } -typedef struct gmx_wallcycle *gmx_wallcycle_t; +typedef struct gmx_wallcycle* gmx_wallcycle_t; struct gmx_wallclock_gpu_nbnxn_t; struct gmx_wallclock_gpu_pme_t; -typedef std::array WallcycleCounts; +typedef std::array WallcycleCounts; /* Convenience typedef */ -WallcycleCounts wallcycle_sum(const t_commrec *cr, gmx_wallcycle_t wc); +WallcycleCounts wallcycle_sum(const t_commrec* cr, gmx_wallcycle_t wc); /* Return a vector of the sum of cycle counts over the nodes in cr->mpi_comm_mysim. */ -void wallcycle_print(FILE *fplog, const gmx::MDLogger &mdlog, int nnodes, int npme, - int nth_pp, int nth_pme, double realtime, - gmx_wallcycle_t wc, const WallcycleCounts &cyc_sum, - const gmx_wallclock_gpu_nbnxn_t *gpu_nbnxn_t, - const gmx_wallclock_gpu_pme_t *gpu_pme_t); +void wallcycle_print(FILE* fplog, + const gmx::MDLogger& mdlog, + int nnodes, + int npme, + int nth_pp, + int nth_pme, + double realtime, + gmx_wallcycle_t wc, + const WallcycleCounts& cyc_sum, + const gmx_wallclock_gpu_nbnxn_t* gpu_nbnxn_t, + const gmx_wallclock_gpu_pme_t* gpu_pme_t); /* Print the cycle and time accounting */ #endif diff --git a/src/gromacs/timing/walltime_accounting.cpp b/src/gromacs/timing/walltime_accounting.cpp index 5828bcd1e8..16b056826a 100644 --- a/src/gromacs/timing/walltime_accounting.cpp +++ b/src/gromacs/timing/walltime_accounting.cpp @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,10 +42,10 @@ #include #ifdef HAVE_UNISTD_H -#include +# include #endif #ifdef HAVE_SYS_TIME_H -#include +# include #endif #include "gromacs/utility/basedefinitions.h" @@ -65,21 +65,22 @@ /*! \brief Manages caching wall-clock time measurements for * simulations */ -typedef struct gmx_walltime_accounting { +typedef struct gmx_walltime_accounting +{ //! Seconds since the epoch recorded at the start of the simulation - double start_time_stamp; + double start_time_stamp; /*! \brief Seconds since the epoch recorded at the reset of * counters for the simulation (or the start, if no reset has * occured). */ - double reset_time_stamp; + double reset_time_stamp; /*! \brief Seconds since the epoch recorded at the reset of * counters for the simulation for this thread (or the start, if * no reset has occured). */ - double reset_time_stamp_per_thread; + double reset_time_stamp_per_thread; //! Total seconds elapsed over the simulation since counter reset - double elapsed_time; + double elapsed_time; //! Total seconds elapsed over the simulation since counter reset running this thread - double elapsed_time_over_all_threads; + double elapsed_time_over_all_threads; /*! \brief Number of OpenMP threads that will be launched by this * MPI rank. * @@ -89,13 +90,13 @@ typedef struct gmx_walltime_accounting { * efficiency) return values such that the sum of * elapsed_time_over_all_threads over all threads was constant * with respect to parallelism implementation. */ - int numOpenMPThreads; + int numOpenMPThreads; //! Numbers of steps done before reset of counters - int64_t nsteps_done_at_reset; + int64_t nsteps_done_at_reset; //! Set by integrators to report the amount of work they did - int64_t nsteps_done; + int64_t nsteps_done; //! Whether the simulation has finished in a way valid for walltime reporting. - bool isValidFinish; + bool isValidFinish; } t_gmx_walltime_accounting; /*! \brief Calls system timing routines (e.g. clock_gettime) to get @@ -115,8 +116,7 @@ static double gmx_gettime_per_thread(); // object. When these become member functions, existence will be // guaranteed. -gmx_walltime_accounting_t -walltime_accounting_init(int numOpenMPThreads) +gmx_walltime_accounting_t walltime_accounting_init(int numOpenMPThreads) { gmx_walltime_accounting_t walltime_accounting; @@ -133,15 +133,12 @@ walltime_accounting_init(int numOpenMPThreads) return walltime_accounting; } -void -walltime_accounting_destroy(gmx_walltime_accounting_t walltime_accounting) +void walltime_accounting_destroy(gmx_walltime_accounting_t walltime_accounting) { sfree(walltime_accounting); } -void -walltime_accounting_reset_time(gmx_walltime_accounting_t walltime_accounting, - int64_t step) +void walltime_accounting_reset_time(gmx_walltime_accounting_t walltime_accounting, int64_t step) { walltime_accounting->reset_time_stamp = gmx_gettime(); walltime_accounting->reset_time_stamp_per_thread = gmx_gettime_per_thread(); @@ -150,23 +147,22 @@ walltime_accounting_reset_time(gmx_walltime_accounting_t walltime_accounting, walltime_accounting->nsteps_done_at_reset = step; } -void -walltime_accounting_start_time(gmx_walltime_accounting_t walltime_accounting) +void walltime_accounting_start_time(gmx_walltime_accounting_t walltime_accounting) { walltime_accounting_reset_time(walltime_accounting, 0); walltime_accounting->start_time_stamp = walltime_accounting->reset_time_stamp; } -void -walltime_accounting_end_time(gmx_walltime_accounting_t walltime_accounting) +void walltime_accounting_end_time(gmx_walltime_accounting_t walltime_accounting) { double now, now_per_thread; now = gmx_gettime(); now_per_thread = gmx_gettime_per_thread(); - walltime_accounting->elapsed_time = now - walltime_accounting->reset_time_stamp; - walltime_accounting->elapsed_time_over_all_threads = now_per_thread - walltime_accounting->reset_time_stamp_per_thread; + walltime_accounting->elapsed_time = now - walltime_accounting->reset_time_stamp; + walltime_accounting->elapsed_time_over_all_threads = + now_per_thread - walltime_accounting->reset_time_stamp_per_thread; /* For thread-MPI, the per-thread CPU timer makes this just * work. For OpenMP threads, the per-thread CPU timer measurement * needs to be multiplied by the number of OpenMP threads used, @@ -177,45 +173,37 @@ walltime_accounting_end_time(gmx_walltime_accounting_t walltime_accounting) walltime_accounting->elapsed_time_over_all_threads *= walltime_accounting->numOpenMPThreads; } -double -walltime_accounting_get_time_since_start(gmx_walltime_accounting_t walltime_accounting) +double walltime_accounting_get_time_since_start(gmx_walltime_accounting_t walltime_accounting) { return gmx_gettime() - walltime_accounting->start_time_stamp; } -double -walltime_accounting_get_time_since_reset(gmx_walltime_accounting_t walltime_accounting) +double walltime_accounting_get_time_since_reset(gmx_walltime_accounting_t walltime_accounting) { return gmx_gettime() - walltime_accounting->reset_time_stamp; } -double -walltime_accounting_get_time_since_reset_over_all_threads(gmx_walltime_accounting_t walltime_accounting) +double walltime_accounting_get_time_since_reset_over_all_threads(gmx_walltime_accounting_t walltime_accounting) { return walltime_accounting->elapsed_time_over_all_threads; } -double -walltime_accounting_get_start_time_stamp(gmx_walltime_accounting_t walltime_accounting) +double walltime_accounting_get_start_time_stamp(gmx_walltime_accounting_t walltime_accounting) { return walltime_accounting->start_time_stamp; } -int64_t -walltime_accounting_get_nsteps_done_since_reset(gmx_walltime_accounting_t walltime_accounting) +int64_t walltime_accounting_get_nsteps_done_since_reset(gmx_walltime_accounting_t walltime_accounting) { return walltime_accounting->nsteps_done - walltime_accounting->nsteps_done_at_reset; } -void -walltime_accounting_set_nsteps_done(gmx_walltime_accounting_t walltime_accounting, - int64_t nsteps_done) +void walltime_accounting_set_nsteps_done(gmx_walltime_accounting_t walltime_accounting, int64_t nsteps_done) { walltime_accounting->nsteps_done = nsteps_done; } -double -gmx_gettime() +double gmx_gettime() { /* Use clock_gettime only if we know linking the C run-time library will work (which is not trivial on e.g. Crays), and its @@ -226,7 +214,7 @@ gmx_gettime() double seconds; clock_gettime(CLOCK_REALTIME, &t); - seconds = static_cast(t.tv_sec) + 1e-9*t.tv_nsec; + seconds = static_cast(t.tv_sec) + 1e-9 * t.tv_nsec; return seconds; #elif HAVE_GETTIMEOFDAY @@ -236,11 +224,11 @@ gmx_gettime() double seconds; gettimeofday(&t, nullptr); - seconds = static_cast(t.tv_sec) + 1e-6*t.tv_usec; + seconds = static_cast(t.tv_sec) + 1e-6 * t.tv_usec; return seconds; #else - double seconds; + double seconds; seconds = time(nullptr); @@ -248,21 +236,18 @@ gmx_gettime() #endif } -void -walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting) +void walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting) { walltime_accounting->isValidFinish = true; } //! Return whether the simulation finished in a way valid for reporting walltime. -bool -walltime_accounting_get_valid_finish(const gmx_walltime_accounting* walltime_accounting) +bool walltime_accounting_get_valid_finish(const gmx_walltime_accounting* walltime_accounting) { return walltime_accounting->isValidFinish; } -static double -gmx_gettime_per_thread() +static double gmx_gettime_per_thread() { /* Use clock_gettime only if we know linking the C run-time library will work (which is not trivial on e.g. Crays), and its @@ -273,7 +258,7 @@ gmx_gettime_per_thread() double seconds; clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t); - seconds = static_cast(t.tv_sec) + 1e-9*t.tv_nsec; + seconds = static_cast(t.tv_sec) + 1e-9 * t.tv_nsec; return seconds; #else diff --git a/src/gromacs/timing/walltime_accounting.h b/src/gromacs/timing/walltime_accounting.h index 250672a6ca..f782acb52b 100644 --- a/src/gromacs/timing/walltime_accounting.h +++ b/src/gromacs/timing/walltime_accounting.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,71 +43,56 @@ /*! \brief * Contains per-process and per-thread data about elapsed wall-clock * times and integration steps performed. */ -typedef struct gmx_walltime_accounting *gmx_walltime_accounting_t; +typedef struct gmx_walltime_accounting* gmx_walltime_accounting_t; //! Constructor -gmx_walltime_accounting_t -walltime_accounting_init(int numOpenMPThreads); +gmx_walltime_accounting_t walltime_accounting_init(int numOpenMPThreads); //! Destructor -void -walltime_accounting_destroy(gmx_walltime_accounting_t walltime_accounting); +void walltime_accounting_destroy(gmx_walltime_accounting_t walltime_accounting); /*! \brief * Record initial time stamps, e.g. at run start */ -void -walltime_accounting_start_time(gmx_walltime_accounting_t walltime_accounting); +void walltime_accounting_start_time(gmx_walltime_accounting_t walltime_accounting); /*! \brief * Reset time stamps, e.g. at counter re-initalization time */ -void -walltime_accounting_reset_time(gmx_walltime_accounting_t walltime_accounting, - int64_t step); +void walltime_accounting_reset_time(gmx_walltime_accounting_t walltime_accounting, int64_t step); /*! \brief * Measure and cache the elapsed wall-clock time since * walltime_accounting_reset_time() */ -void -walltime_accounting_end_time(gmx_walltime_accounting_t walltime_accounting); +void walltime_accounting_end_time(gmx_walltime_accounting_t walltime_accounting); /*! \brief * Measure and return the elapsed wall-clock time since * walltime_accounting_reset_time() */ -double -walltime_accounting_get_time_since_reset(gmx_walltime_accounting_t walltime_accounting); +double walltime_accounting_get_time_since_reset(gmx_walltime_accounting_t walltime_accounting); //! Get the wall-clock time since the actual start of the run (regardless of any resets). -double -walltime_accounting_get_time_since_start(gmx_walltime_accounting_t walltime_accounting); +double walltime_accounting_get_time_since_start(gmx_walltime_accounting_t walltime_accounting); //! Get the cached wall-clock time, multiplied by the number of OpenMP threads -double -walltime_accounting_get_time_since_reset_over_all_threads(gmx_walltime_accounting_t walltime_accounting); +double walltime_accounting_get_time_since_reset_over_all_threads(gmx_walltime_accounting_t walltime_accounting); //! Get the cached initial time stamp for this node -double -walltime_accounting_get_start_time_stamp(gmx_walltime_accounting_t walltime_accounting); +double walltime_accounting_get_start_time_stamp(gmx_walltime_accounting_t walltime_accounting); //! Get the number of integration steps done -int64_t -walltime_accounting_get_nsteps_done_since_reset(gmx_walltime_accounting_t walltime_accounting); +int64_t walltime_accounting_get_nsteps_done_since_reset(gmx_walltime_accounting_t walltime_accounting); /*! \brief Set the number of integration steps done * * TODO consider whether this should get done in walltime_accounting_end */ -void -walltime_accounting_set_nsteps_done(gmx_walltime_accounting_t walltime_accounting, - int64_t nsteps_done); +void walltime_accounting_set_nsteps_done(gmx_walltime_accounting_t walltime_accounting, int64_t nsteps_done); //! Record that the simulation finished in a way valid for reporting walltime. -void -walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting); +void walltime_accounting_set_valid_finish(gmx_walltime_accounting_t walltime_accounting); //! Return whether the simulation finished in a way valid for reporting walltime. -bool -walltime_accounting_get_valid_finish(const gmx_walltime_accounting* walltime_accounting); +bool walltime_accounting_get_valid_finish(const gmx_walltime_accounting* walltime_accounting); /*! \brief * Calls system timing routines (e.g. clock_gettime) to get the (fractional) @@ -117,4 +102,4 @@ walltime_accounting_get_valid_finish(const gmx_walltime_accounting* walltime_acc * or microseconds. */ double gmx_gettime(); -#endif /* GMX_TIMING_WALLTIME_ACCOUNTING_H */ +#endif /* GMX_TIMING_WALLTIME_ACCOUNTING_H */ diff --git a/src/gromacs/tools/check.cpp b/src/gromacs/tools/check.cpp index 33c39a4cff..e34ea7a553 100644 --- a/src/gromacs/tools/check.cpp +++ b/src/gromacs/tools/check.cpp @@ -70,7 +70,8 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -typedef struct { +typedef struct +{ int bStep; int bTime; int bLambda; @@ -80,7 +81,8 @@ typedef struct { int bBox; } t_count; -typedef struct { +typedef struct +{ float bStep; float bTime; float bLambda; @@ -90,14 +92,13 @@ typedef struct { float bBox; } t_fr_time; -static void comp_tpx(const char *fn1, const char *fn2, - gmx_bool bRMSD, real ftol, real abstol) +static void comp_tpx(const char* fn1, const char* fn2, gmx_bool bRMSD, real ftol, real abstol) { - const char *ff[2]; - t_inputrec *ir[2]; - t_state state[2]; - gmx_mtop_t mtop[2]; - int i; + const char* ff[2]; + t_inputrec* ir[2]; + t_state state[2]; + gmx_mtop_t mtop[2]; + int i; ff[0] = fn1; ff[1] = fn2; @@ -130,13 +131,12 @@ static void comp_tpx(const char *fn1, const char *fn2, } } -static void comp_trx(const gmx_output_env_t *oenv, const char *fn1, const char *fn2, - gmx_bool bRMSD, real ftol, real abstol) +static void comp_trx(const gmx_output_env_t* oenv, const char* fn1, const char* fn2, gmx_bool bRMSD, real ftol, real abstol) { int i; - const char *fn[2]; + const char* fn[2]; t_trxframe fr[2]; - t_trxstatus *status[2]; + t_trxstatus* status[2]; gmx_bool b[2]; fn[0] = fn1; @@ -144,7 +144,7 @@ static void comp_trx(const gmx_output_env_t *oenv, const char *fn1, const char * fprintf(stderr, "Comparing trajectory files %s and %s\n", fn1, fn2); for (i = 0; i < 2; i++) { - b[i] = read_first_frame(oenv, &status[i], fn[i], &fr[i], TRX_READ_X|TRX_READ_V|TRX_READ_F); + b[i] = read_first_frame(oenv, &status[i], fn[i], &fr[i], TRX_READ_X | TRX_READ_V | TRX_READ_F); } if (b[0] && b[1]) @@ -157,14 +157,13 @@ static void comp_trx(const gmx_output_env_t *oenv, const char *fn1, const char * { b[i] = read_next_frame(oenv, status[i], &fr[i]); } - } - while (b[0] && b[1]); + } while (b[0] && b[1]); for (i = 0; i < 2; i++) { - if (b[i] && !b[1-i]) + if (b[i] && !b[1 - i]) { - fprintf(stdout, "\nEnd of file on %s but not on %s\n", fn[1-i], fn[i]); + fprintf(stdout, "\nEnd of file on %s but not on %s\n", fn[1 - i], fn[i]); } close_trx(status[i]); } @@ -175,7 +174,7 @@ static void comp_trx(const gmx_output_env_t *oenv, const char *fn1, const char * } } -static void chk_coords(int frame, int natoms, rvec *x, matrix box, real fac, real tol) +static void chk_coords(int frame, int natoms, rvec* x, matrix box, real fac, real tol) { int i, j; int nNul = 0; @@ -185,27 +184,23 @@ static void chk_coords(int frame, int natoms, rvec *x, matrix box, real fac, rea { for (j = 0; (j < DIM); j++) { - if ((vol > 0) && (fabs(x[i][j]) > fac*box[j][j])) + if ((vol > 0) && (fabs(x[i][j]) > fac * box[j][j])) { - printf("Warning at frame %d: coordinates for atom %d are large (%g)\n", - frame, i, x[i][j]); + printf("Warning at frame %d: coordinates for atom %d are large (%g)\n", frame, i, x[i][j]); } } - if ((fabs(x[i][XX]) < tol) && - (fabs(x[i][YY]) < tol) && - (fabs(x[i][ZZ]) < tol)) + if ((fabs(x[i][XX]) < tol) && (fabs(x[i][YY]) < tol) && (fabs(x[i][ZZ]) < tol)) { nNul++; } } if (nNul > 0) { - printf("Warning at frame %d: there are %d particles with all coordinates zero\n", - frame, nNul); + printf("Warning at frame %d: there are %d particles with all coordinates zero\n", frame, nNul); } } -static void chk_vels(int frame, int natoms, rvec *v) +static void chk_vels(int frame, int natoms, rvec* v) { int i, j; @@ -215,14 +210,13 @@ static void chk_vels(int frame, int natoms, rvec *v) { if (fabs(v[i][j]) > 500) { - printf("Warning at frame %d. Velocities for atom %d are large (%g)\n", - frame, i, v[i][j]); + printf("Warning at frame %d. Velocities for atom %d are large (%g)\n", frame, i, v[i][j]); } } } } -static void chk_forces(int frame, int natoms, rvec *f) +static void chk_forces(int frame, int natoms, rvec* f) { int i, j; @@ -232,14 +226,13 @@ static void chk_forces(int frame, int natoms, rvec *f) { if (fabs(f[i][j]) > 10000) { - printf("Warning at frame %d. Forces for atom %d are large (%g)\n", - frame, i, f[i][j]); + printf("Warning at frame %d. Forces for atom %d are large (%g)\n", frame, i, f[i][j]); } } } } -static void chk_bonds(t_idef *idef, int ePBC, rvec *x, matrix box, real tol) +static void chk_bonds(t_idef* idef, int ePBC, rvec* x, matrix box, real tol) { int ftype, k, ai, aj, type; real b0, blen, deviation; @@ -251,7 +244,7 @@ static void chk_bonds(t_idef *idef, int ePBC, rvec *x, matrix box, real tol) { if ((interaction_function[ftype].flags & IF_CHEMBOND) == IF_CHEMBOND) { - for (k = 0; (k < idef->il[ftype].nr); ) + for (k = 0; (k < idef->il[ftype].nr);) { type = idef->il[ftype].iatoms[k++]; ai = idef->il[ftype].iatoms[k++]; @@ -259,32 +252,22 @@ static void chk_bonds(t_idef *idef, int ePBC, rvec *x, matrix box, real tol) b0 = 0; switch (ftype) { - case F_BONDS: - b0 = idef->iparams[type].harmonic.rA; - break; - case F_G96BONDS: - b0 = std::sqrt(idef->iparams[type].harmonic.rA); - break; - case F_MORSE: - b0 = idef->iparams[type].morse.b0A; - break; - case F_CUBICBONDS: - b0 = idef->iparams[type].cubic.b0; - break; - case F_CONSTR: - b0 = idef->iparams[type].constr.dA; - break; - default: - break; + case F_BONDS: b0 = idef->iparams[type].harmonic.rA; break; + case F_G96BONDS: b0 = std::sqrt(idef->iparams[type].harmonic.rA); break; + case F_MORSE: b0 = idef->iparams[type].morse.b0A; break; + case F_CUBICBONDS: b0 = idef->iparams[type].cubic.b0; break; + case F_CONSTR: b0 = idef->iparams[type].constr.dA; break; + default: break; } if (b0 != 0) { pbc_dx(&pbc, x[ai], x[aj], dx); blen = norm(dx); - deviation = gmx::square(blen-b0); - if (std::sqrt(deviation/gmx::square(b0)) > tol) + deviation = gmx::square(blen - b0); + if (std::sqrt(deviation / gmx::square(b0)) > tol) { - fprintf(stderr, "Distance between atoms %d and %d is %.3f, should be %.3f\n", ai+1, aj+1, blen, b0); + fprintf(stderr, "Distance between atoms %d and %d is %.3f, should be %.3f\n", + ai + 1, aj + 1, blen, b0); } } } @@ -292,7 +275,7 @@ static void chk_bonds(t_idef *idef, int ePBC, rvec *x, matrix box, real tol) } } -static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tpr, real tol) +static void chk_trj(const gmx_output_env_t* oenv, const char* fn, const char* tpr, real tol) { t_trxframe fr; t_count count; @@ -300,7 +283,7 @@ static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tp int j = -1, new_natoms, natoms; real old_t1, old_t2; gmx_bool bShowTimestep = TRUE, newline = FALSE; - t_trxstatus *status; + t_trxstatus* status; gmx_mtop_t mtop; gmx_localtop_t top; t_state state; @@ -316,7 +299,7 @@ static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tp printf("Checking file %s\n", fn); - j = 0; + j = 0; old_t2 = -2.0; old_t1 = -1.0; @@ -353,24 +336,23 @@ static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tp fprintf(stderr, "\n# Atoms %d\n", fr.natoms); if (fr.bPrec) { - fprintf(stderr, "Precision %g (nm)\n", 1/fr.prec); + fprintf(stderr, "Precision %g (nm)\n", 1 / fr.prec); } } newline = TRUE; if ((natoms > 0) && (new_natoms != natoms)) { - fprintf(stderr, "\nNumber of atoms at t=%g don't match (%d, %d)\n", - old_t1, natoms, new_natoms); + fprintf(stderr, "\nNumber of atoms at t=%g don't match (%d, %d)\n", old_t1, natoms, new_natoms); newline = FALSE; } if (j >= 2) { - if (std::fabs((fr.time-old_t1)-(old_t1-old_t2)) > - 0.1*(std::fabs(fr.time-old_t1)+std::fabs(old_t1-old_t2)) ) + if (std::fabs((fr.time - old_t1) - (old_t1 - old_t2)) + > 0.1 * (std::fabs(fr.time - old_t1) + std::fabs(old_t1 - old_t2))) { bShowTimestep = FALSE; - fprintf(stderr, "%sTimesteps at t=%g don't match (%g, %g)\n", - newline ? "\n" : "", old_t1, old_t1-old_t2, fr.time-old_t1); + fprintf(stderr, "%sTimesteps at t=%g don't match (%g, %g)\n", newline ? "\n" : "", + old_t1, old_t1 - old_t2, fr.time - old_t1); } } natoms = new_natoms; @@ -395,18 +377,25 @@ static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tp old_t1 = fr.time; j++; new_natoms = fr.natoms; -#define INC(s, n, f, l, item) if ((s).item != 0) { if ((n).item == 0) { first.item = fr.time; } last.item = fr.time; (n).item++; \ -} - INC(fr, count, first, last, bStep); - INC(fr, count, first, last, bTime); - INC(fr, count, first, last, bLambda); - INC(fr, count, first, last, bX); - INC(fr, count, first, last, bV); - INC(fr, count, first, last, bF); - INC(fr, count, first, last, bBox); +#define INC(s, n, f, l, item) \ + if ((s).item != 0) \ + { \ + if ((n).item == 0) \ + { \ + first.item = fr.time; \ + } \ + last.item = fr.time; \ + (n).item++; \ + } + INC(fr, count, first, last, bStep) + INC(fr, count, first, last, bTime) + INC(fr, count, first, last, bLambda) + INC(fr, count, first, last, bX) + INC(fr, count, first, last, bV) + INC(fr, count, first, last, bF) + INC(fr, count, first, last, bBox) #undef INC - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); fprintf(stderr, "\n"); @@ -418,29 +407,36 @@ static void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tp fprintf(stderr, " Timestep (ps)"); } fprintf(stderr, "\n"); -#define PRINTITEM(label, item) fprintf(stderr, "%-10s %6d", label, count.item); if ((bShowTimestep) && (count.item > 1)) {fprintf(stderr, " %g\n", (last.item-first.item)/(count.item-1)); }else fprintf(stderr, "\n") - PRINTITEM ( "Step", bStep ); - PRINTITEM ( "Time", bTime ); - PRINTITEM ( "Lambda", bLambda ); - PRINTITEM ( "Coords", bX ); - PRINTITEM ( "Velocities", bV ); - PRINTITEM ( "Forces", bF ); - PRINTITEM ( "Box", bBox ); +#define PRINTITEM(label, item) \ + fprintf(stderr, "%-10s %6d", label, count.item); \ + if ((bShowTimestep) && (count.item > 1)) \ + { \ + fprintf(stderr, " %g\n", (last.item - first.item) / (count.item - 1)); \ + } \ + else \ + fprintf(stderr, "\n") + PRINTITEM("Step", bStep); + PRINTITEM("Time", bTime); + PRINTITEM("Lambda", bLambda); + PRINTITEM("Coords", bX); + PRINTITEM("Velocities", bV); + PRINTITEM("Forces", bF); + PRINTITEM("Box", bBox); } -static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) +static void chk_tps(const char* fn, real vdw_fac, real bon_lo, real bon_hi) { - int natom, i, j, k; - t_topology top; - int ePBC; - t_atoms *atoms; - rvec *x, *v; - rvec dx; - matrix box; - t_pbc pbc; - gmx_bool bV, bX, bB, bFirst, bOut; - real r2, ekin, temp1, temp2, dist2, vdwfac2, bonlo2, bonhi2; - real *atom_vdw; + int natom, i, j, k; + t_topology top; + int ePBC; + t_atoms* atoms; + rvec * x, *v; + rvec dx; + matrix box; + t_pbc pbc; + gmx_bool bV, bX, bB, bFirst, bOut; + real r2, ekin, temp1, temp2, dist2, vdwfac2, bonlo2, bonhi2; + real* atom_vdw; fprintf(stderr, "Checking coordinate file %s\n", fn); read_tps_conf(fn, &top, &ePBC, &x, &v, box, TRUE); @@ -481,16 +477,18 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) { for (j = 0; (j < DIM); j++) { - ekin += 0.5*atoms->atom[i].m*v[i][j]*v[i][j]; + ekin += 0.5 * atoms->atom[i].m * v[i][j] * v[i][j]; } } - temp1 = (2.0*ekin)/(natom*DIM*BOLTZ); - temp2 = (2.0*ekin)/(natom*(DIM-1)*BOLTZ); + temp1 = (2.0 * ekin) / (natom * DIM * BOLTZ); + temp2 = (2.0 * ekin) / (natom * (DIM - 1) * BOLTZ); fprintf(stderr, "Kinetic energy: %g (kJ/mol)\n", ekin); - fprintf(stderr, "Assuming the number of degrees of freedom to be " + fprintf(stderr, + "Assuming the number of degrees of freedom to be " "Natoms * %d or Natoms * %d,\n" "the velocities correspond to a temperature of the system\n" - "of %g K or %g K respectively.\n\n", DIM, DIM-1, temp1, temp2); + "of %g K or %g K respectively.\n\n", + DIM, DIM - 1, temp1, temp2); } /* check coordinates */ @@ -508,15 +506,12 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) AtomProperties aps; for (i = 0; (i < natom); i++) { - aps.setAtomProperty(epropVDW, - *(atoms->resinfo[atoms->atom[i].resind].name), + aps.setAtomProperty(epropVDW, *(atoms->resinfo[atoms->atom[i].resind].name), *(atoms->atomname[i]), &(atom_vdw[i])); if (debug) { - fprintf(debug, "%5d %4s %4s %7g\n", i+1, - *(atoms->resinfo[atoms->atom[i].resind].name), - *(atoms->atomname[i]), - atom_vdw[i]); + fprintf(debug, "%5d %4s %4s %7g\n", i + 1, *(atoms->resinfo[atoms->atom[i].resind].name), + *(atoms->atomname[i]), atom_vdw[i]); } } if (bB) @@ -527,12 +522,12 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) bFirst = TRUE; for (i = 0; (i < natom); i++) { - if (((i+1)%10) == 0) + if (((i + 1) % 10) == 0) { - fprintf(stderr, "\r%5d", i+1); + fprintf(stderr, "\r%5d", i + 1); fflush(stderr); } - for (j = i+1; (j < natom); j++) + for (j = i + 1; (j < natom); j++) { if (bB) { @@ -543,28 +538,20 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) rvec_sub(x[i], x[j], dx); } r2 = iprod(dx, dx); - dist2 = gmx::square(atom_vdw[i]+atom_vdw[j]); - if ( (r2 <= dist2*bonlo2) || - ( (r2 >= dist2*bonhi2) && (r2 <= dist2*vdwfac2) ) ) + dist2 = gmx::square(atom_vdw[i] + atom_vdw[j]); + if ((r2 <= dist2 * bonlo2) || ((r2 >= dist2 * bonhi2) && (r2 <= dist2 * vdwfac2))) { if (bFirst) { - fprintf(stderr, "\r%5s %4s %8s %5s %5s %4s %8s %5s %6s\n", - "atom#", "name", "residue", "r_vdw", - "atom#", "name", "residue", "r_vdw", "distance"); + fprintf(stderr, "\r%5s %4s %8s %5s %5s %4s %8s %5s %6s\n", "atom#", "name", + "residue", "r_vdw", "atom#", "name", "residue", "r_vdw", "distance"); bFirst = FALSE; } - fprintf(stderr, - "\r%5d %4s %4s%4d %-5.3g %5d %4s %4s%4d %-5.3g %-6.4g\n", - i+1, *(atoms->atomname[i]), - *(atoms->resinfo[atoms->atom[i].resind].name), - atoms->resinfo[atoms->atom[i].resind].nr, - atom_vdw[i], - j+1, *(atoms->atomname[j]), - *(atoms->resinfo[atoms->atom[j].resind].name), - atoms->resinfo[atoms->atom[j].resind].nr, - atom_vdw[j], - std::sqrt(r2) ); + fprintf(stderr, "\r%5d %4s %4s%4d %-5.3g %5d %4s %4s%4d %-5.3g %-6.4g\n", i + 1, + *(atoms->atomname[i]), *(atoms->resinfo[atoms->atom[i].resind].name), + atoms->resinfo[atoms->atom[i].resind].nr, atom_vdw[i], j + 1, + *(atoms->atomname[j]), *(atoms->resinfo[atoms->atom[j].resind].name), + atoms->resinfo[atoms->atom[j].resind].nr, atom_vdw[j], std::sqrt(r2)); } } } @@ -596,15 +583,14 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) { fprintf(stderr, "%g ", box[j][j]); } - fprintf(stderr, "):\n" + fprintf(stderr, + "):\n" "(These may occur often and are normally not a problem)\n" "%5s %4s %8s %5s %s\n", "atom#", "name", "residue", "r_vdw", "coordinate"); bFirst = FALSE; } - fprintf(stderr, - "%5d %4s %4s%4d %-5.3g", - i, *(atoms->atomname[i]), + fprintf(stderr, "%5d %4s %4s%4d %-5.3g", i, *(atoms->atomname[i]), *(atoms->resinfo[atoms->atom[i].resind].name), atoms->resinfo[atoms->atom[i].resind].nr, atom_vdw[i]); for (j = 0; (j < DIM); j++) @@ -627,10 +613,10 @@ static void chk_tps(const char *fn, real vdw_fac, real bon_lo, real bon_hi) } } -static void chk_ndx(const char *fn) +static void chk_ndx(const char* fn) { - t_blocka *grps; - char **grpname; + t_blocka* grps; + char** grpname; int i; grps = init_index(fn, &grpname); @@ -645,10 +631,8 @@ static void chk_ndx(const char *fn) printf("Nr. Group #Entries First Last\n"); for (i = 0; (i < grps->nr); i++) { - printf("%4d %-20s%8d%8d%8d\n", i, grpname[i], - grps->index[i+1]-grps->index[i], - grps->a[grps->index[i]]+1, - grps->a[grps->index[i+1]-1]+1); + printf("%4d %-20s%8d%8d%8d\n", i, grpname[i], grps->index[i + 1] - grps->index[i], + grps->a[grps->index[i]] + 1, grps->a[grps->index[i + 1] - 1] + 1); } } for (i = 0; (i < grps->nr); i++) @@ -659,16 +643,16 @@ static void chk_ndx(const char *fn) done_blocka(grps); } -static void chk_enx(const char *fn) +static void chk_enx(const char* fn) { - int nre, fnr; - ener_file_t in; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; - gmx_bool bShowTStep; - gmx_bool timeSet; - real t0, old_t1, old_t2; - char buf[22]; + int nre, fnr; + ener_file_t in; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; + gmx_bool bShowTStep; + gmx_bool timeSet; + real t0, old_t1, old_t2; + char buf[22]; fprintf(stderr, "Checking energy file %s\n\n", fn); @@ -687,12 +671,12 @@ static void chk_enx(const char *fn) { if (fnr >= 2) { - if (fabs((fr->t-old_t1)-(old_t1-old_t2)) > - 0.1*(fabs(fr->t-old_t1)+std::fabs(old_t1-old_t2)) ) + if (fabs((fr->t - old_t1) - (old_t1 - old_t2)) + > 0.1 * (fabs(fr->t - old_t1) + std::fabs(old_t1 - old_t2))) { bShowTStep = FALSE; - fprintf(stderr, "\nTimesteps at t=%g don't match (%g, %g)\n", - old_t1, old_t1-old_t2, fr->t-old_t1); + fprintf(stderr, "\nTimesteps at t=%g don't match (%g, %g)\n", old_t1, + old_t1 - old_t2, fr->t - old_t1); } } old_t2 = old_t1; @@ -704,15 +688,15 @@ static void chk_enx(const char *fn) } if (fnr == 0) { - fprintf(stderr, "\rframe: %6s (index %6d), t: %10.3f\n", - gmx_step_str(fr->step, buf), fnr, fr->t); + fprintf(stderr, "\rframe: %6s (index %6d), t: %10.3f\n", gmx_step_str(fr->step, buf), + fnr, fr->t); } fnr++; } fprintf(stderr, "\n\nFound %d frames", fnr); if (bShowTStep && fnr > 1) { - fprintf(stderr, " with a timestep of %g ps", (old_t1-t0)/(fnr-1)); + fprintf(stderr, " with a timestep of %g ps", (old_t1 - t0) / (fnr - 1)); } fprintf(stderr, ".\n"); @@ -721,9 +705,9 @@ static void chk_enx(const char *fn) sfree(fr); } -int gmx_check(int argc, char *argv[]) +int gmx_check(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] reads a trajectory ([REF].tng[ref], [REF].trr[ref] or ", "[REF].xtc[ref]), an energy file ([REF].edr[ref])", "or an index file ([REF].ndx[ref])", @@ -740,7 +724,8 @@ int gmx_check(int argc, char *argv[]) "the program will check whether the bond lengths defined in the tpr", "file are indeed correct in the trajectory. If not you may have", "non-matching files due to e.g. deshuffling or due to problems with", - "virtual sites. With these flags, [TT]gmx check[tt] provides a quick check for such problems.[PAR]", + "virtual sites. With these flags, [TT]gmx check[tt] provides a quick check for ", + "such problems.[PAR]", "The program can compare two run input ([REF].tpr[ref])", "files", "when both [TT]-s1[tt] and [TT]-s2[tt] are supplied. When comparing", @@ -753,21 +738,15 @@ int gmx_check(int argc, char *argv[]) "For free energy simulations the A and B state topology from one", "run input file can be compared with options [TT]-s1[tt] and [TT]-ab[tt].[PAR]" }; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffOPTRD }, - { efTRX, "-f2", nullptr, ffOPTRD }, - { efTPR, "-s1", "top1", ffOPTRD }, - { efTPR, "-s2", "top2", ffOPTRD }, - { efTPS, "-c", nullptr, ffOPTRD }, - { efEDR, "-e", nullptr, ffOPTRD }, - { efEDR, "-e2", "ener2", ffOPTRD }, - { efNDX, "-n", nullptr, ffOPTRD }, - { efTEX, "-m", nullptr, ffOPTWR } - }; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffOPTRD }, { efTRX, "-f2", nullptr, ffOPTRD }, + { efTPR, "-s1", "top1", ffOPTRD }, { efTPR, "-s2", "top2", ffOPTRD }, + { efTPS, "-c", nullptr, ffOPTRD }, { efEDR, "-e", nullptr, ffOPTRD }, + { efEDR, "-e2", "ener2", ffOPTRD }, { efNDX, "-n", nullptr, ffOPTRD }, + { efTEX, "-m", nullptr, ffOPTWR } }; #define NFILE asize(fnm) - const char *fn1 = nullptr, *fn2 = nullptr, *tex = nullptr; + const char *fn1 = nullptr, *fn2 = nullptr, *tex = nullptr; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; static real vdw_fac = 0.8; static real bon_lo = 0.4; static real bon_hi = 0.7; @@ -775,28 +754,37 @@ int gmx_check(int argc, char *argv[]) static real ftol = 0.001; static real abstol = 0.001; static gmx_bool bCompAB = FALSE; - static char *lastener = nullptr; + static char* lastener = nullptr; static t_pargs pa[] = { - { "-vdwfac", FALSE, etREAL, {&vdw_fac}, + { "-vdwfac", + FALSE, + etREAL, + { &vdw_fac }, "Fraction of sum of VdW radii used as warning cutoff" }, - { "-bonlo", FALSE, etREAL, {&bon_lo}, - "Min. fract. of sum of VdW radii for bonded atoms" }, - { "-bonhi", FALSE, etREAL, {&bon_hi}, - "Max. fract. of sum of VdW radii for bonded atoms" }, - { "-rmsd", FALSE, etBOOL, {&bRMSD}, - "Print RMSD for x, v and f" }, - { "-tol", FALSE, etREAL, {&ftol}, - "Relative tolerance for comparing real values defined as [MATH]2*(a-b)/([MAG]a[mag]+[MAG]b[mag])[math]" }, - { "-abstol", FALSE, etREAL, {&abstol}, + { "-bonlo", FALSE, etREAL, { &bon_lo }, "Min. fract. of sum of VdW radii for bonded atoms" }, + { "-bonhi", FALSE, etREAL, { &bon_hi }, "Max. fract. of sum of VdW radii for bonded atoms" }, + { "-rmsd", FALSE, etBOOL, { &bRMSD }, "Print RMSD for x, v and f" }, + { "-tol", + FALSE, + etREAL, + { &ftol }, + "Relative tolerance for comparing real values defined as " + "[MATH]2*(a-b)/([MAG]a[mag]+[MAG]b[mag])[math]" }, + { "-abstol", + FALSE, + etREAL, + { &abstol }, "Absolute tolerance, useful when sums are close to zero." }, - { "-ab", FALSE, etBOOL, {&bCompAB}, - "Compare the A and B topology from one file" }, - { "-lastener", FALSE, etSTR, {&lastener}, - "Last energy term to compare (if not given all are tested). It makes sense to go up until the Pressure." } + { "-ab", FALSE, etBOOL, { &bCompAB }, "Compare the A and B topology from one file" }, + { "-lastener", + FALSE, + etSTR, + { &lastener }, + "Last energy term to compare (if not given all are tested). It makes sense to go up " + "until the Pressure." } }; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -807,7 +795,8 @@ int gmx_check(int argc, char *argv[]) if (tex) { - fprintf(stderr, "LaTeX file writing has been removed from gmx check. " + fprintf(stderr, + "LaTeX file writing has been removed from gmx check. " "Please use gmx report-methods instead for it.\n"); } if (fn1 && fn2) diff --git a/src/gromacs/tools/check.h b/src/gromacs/tools/check.h index 435cd0d88a..6870b6fe8a 100644 --- a/src/gromacs/tools/check.h +++ b/src/gromacs/tools/check.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_check(int argc, char *argv[]); +int gmx_check(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/convert_tpr.cpp b/src/gromacs/tools/convert_tpr.cpp index 123f0f52bb..09adddc795 100644 --- a/src/gromacs/tools/convert_tpr.cpp +++ b/src/gromacs/tools/convert_tpr.cpp @@ -62,11 +62,16 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -#define RANGECHK(i, n) if ((i) >= (n)) gmx_fatal(FARGS, "Your index file contains atomnumbers (e.g. %d)\nthat are larger than the number of atoms in the tpr file (%d)", (i), (n)) - -static gmx_bool *bKeepIt(int gnx, int natoms, int index[]) +#define RANGECHK(i, n) \ + if ((i) >= (n)) \ + gmx_fatal(FARGS, \ + "Your index file contains atomnumbers (e.g. %d)\nthat are larger than the number " \ + "of atoms in the tpr file (%d)", \ + (i), (n)) + +static gmx_bool* bKeepIt(int gnx, int natoms, int index[]) { - gmx_bool *b; + gmx_bool* b; int i; snew(b, natoms); @@ -79,10 +84,10 @@ static gmx_bool *bKeepIt(int gnx, int natoms, int index[]) return b; } -static int *invind(int gnx, int natoms, int index[]) +static int* invind(int gnx, int natoms, int index[]) { - int *inv; - int i; + int* inv; + int i; snew(inv, natoms); for (i = 0; (i < gnx); i++) @@ -94,18 +99,17 @@ static int *invind(int gnx, int natoms, int index[]) return inv; } -static void reduce_block(const gmx_bool bKeep[], t_block *block, - const char *name) +static void reduce_block(const gmx_bool bKeep[], t_block* block, const char* name) { - int *index; - int i, j, newi, newj; + int* index; + int i, j, newi, newj; snew(index, block->nr); newi = newj = 0; for (i = 0; (i < block->nr); i++) { - for (j = block->index[i]; (j < block->index[i+1]); j++) + for (j = block->index[i]; (j < block->index[i + 1]); j++) { if (bKeep[j]) { @@ -119,17 +123,16 @@ static void reduce_block(const gmx_bool bKeep[], t_block *block, } } - fprintf(stderr, "Reduced block %8s from %6d to %6d index-, %6d to %6d a-entries\n", - name, block->nr, newi, block->index[block->nr], newj); + fprintf(stderr, "Reduced block %8s from %6d to %6d index-, %6d to %6d a-entries\n", name, + block->nr, newi, block->index[block->nr], newj); block->index = index; block->nr = newi; } -static void reduce_blocka(const int invindex[], const gmx_bool bKeep[], t_blocka *block, - const char *name) +static void reduce_blocka(const int invindex[], const gmx_bool bKeep[], t_blocka* block, const char* name) { - int *index, *a; - int i, j, k, newi, newj; + int *index, *a; + int i, j, k, newi, newj; snew(index, block->nr); snew(a, block->nra); @@ -137,7 +140,7 @@ static void reduce_blocka(const int invindex[], const gmx_bool bKeep[], t_blocka newi = newj = 0; for (i = 0; (i < block->nr); i++) { - for (j = block->index[i]; (j < block->index[i+1]); j++) + for (j = block->index[i]; (j < block->index[i + 1]); j++) { k = block->a[j]; if (bKeep[k]) @@ -153,8 +156,8 @@ static void reduce_blocka(const int invindex[], const gmx_bool bKeep[], t_blocka } } - fprintf(stderr, "Reduced block %8s from %6d to %6d index-, %6d to %6d a-entries\n", - name, block->nr, newi, block->nra, newj); + fprintf(stderr, "Reduced block %8s from %6d to %6d index-, %6d to %6d a-entries\n", name, + block->nr, newi, block->nra, newj); block->index = index; block->a = a; block->nr = newi; @@ -163,7 +166,7 @@ static void reduce_blocka(const int invindex[], const gmx_bool bKeep[], t_blocka static void reduce_rvec(int gnx, const int index[], rvec vv[]) { - rvec *ptr; + rvec* ptr; int i; snew(ptr, gnx); @@ -178,17 +181,16 @@ static void reduce_rvec(int gnx, const int index[], rvec vv[]) sfree(ptr); } -static void reduce_atom(int gnx, const int index[], t_atom atom[], char ***atomname, - int *nres, t_resinfo *resinfo) +static void reduce_atom(int gnx, const int index[], t_atom atom[], char*** atomname, int* nres, t_resinfo* resinfo) { - t_atom *ptr; - char ***aname; - t_resinfo *rinfo; + t_atom* ptr; + char*** aname; + t_resinfo* rinfo; int i, nr; snew(ptr, gnx); snew(aname, gnx); - snew(rinfo, atom[index[gnx-1]].resind+1); + snew(rinfo, atom[index[gnx - 1]].resind + 1); for (i = 0; (i < gnx); i++) { ptr[i] = atom[index[i]]; @@ -199,7 +201,7 @@ static void reduce_atom(int gnx, const int index[], t_atom atom[], char ***atomn { atom[i] = ptr[i]; atomname[i] = aname[i]; - if ((i == 0) || (atom[i].resind != atom[i-1].resind)) + if ((i == 0) || (atom[i].resind != atom[i - 1].resind)) { nr++; rinfo[nr] = resinfo[atom[i].resind]; @@ -218,10 +220,9 @@ static void reduce_atom(int gnx, const int index[], t_atom atom[], char ***atomn sfree(rinfo); } -static void reduce_ilist(const int invindex[], const gmx_bool bKeep[], - t_ilist *il, int nratoms, const char *name) +static void reduce_ilist(const int invindex[], const gmx_bool bKeep[], t_ilist* il, int nratoms, const char* name) { - t_iatom *ia; + t_iatom* ia; int i, j, newnr; gmx_bool bB; @@ -229,25 +230,24 @@ static void reduce_ilist(const int invindex[], const gmx_bool bKeep[], { snew(ia, il->nr); newnr = 0; - for (i = 0; (i < il->nr); i += nratoms+1) + for (i = 0; (i < il->nr); i += nratoms + 1) { bB = TRUE; for (j = 1; (j <= nratoms); j++) { - bB = bB && bKeep[il->iatoms[i+j]]; + bB = bB && bKeep[il->iatoms[i + j]]; } if (bB) { ia[newnr++] = il->iatoms[i]; for (j = 1; (j <= nratoms); j++) { - ia[newnr++] = invindex[il->iatoms[i+j]]; + ia[newnr++] = invindex[il->iatoms[i + j]]; } } } - fprintf(stderr, "Reduced ilist %8s from %6d to %6d entries\n", - name, il->nr/(nratoms+1), - newnr/(nratoms+1)); + fprintf(stderr, "Reduced ilist %8s from %6d to %6d entries\n", name, il->nr / (nratoms + 1), + newnr / (nratoms + 1)); il->nr = newnr; for (i = 0; (i < newnr); i++) @@ -259,13 +259,12 @@ static void reduce_ilist(const int invindex[], const gmx_bool bKeep[], } } -static void reduce_topology_x(int gnx, int index[], - gmx_mtop_t *mtop, rvec x[], rvec v[]) +static void reduce_topology_x(int gnx, int index[], gmx_mtop_t* mtop, rvec x[], rvec v[]) { - t_topology top; - gmx_bool *bKeep; - int *invindex; - int i; + t_topology top; + gmx_bool* bKeep; + int* invindex; + int i; top = gmx_mtop_t_to_t_topology(mtop, false); bKeep = bKeepIt(gnx, top.atoms.nr, index); @@ -275,13 +274,11 @@ static void reduce_topology_x(int gnx, int index[], reduce_blocka(invindex, bKeep, &(top.excls), "excls"); reduce_rvec(gnx, index, x); reduce_rvec(gnx, index, v); - reduce_atom(gnx, index, top.atoms.atom, top.atoms.atomname, - &(top.atoms.nres), top.atoms.resinfo); + reduce_atom(gnx, index, top.atoms.atom, top.atoms.atomname, &(top.atoms.nres), top.atoms.resinfo); for (i = 0; (i < F_NRE); i++) { - reduce_ilist(invindex, bKeep, &(top.idef.il[i]), - interaction_function[i].nratoms, + reduce_ilist(invindex, bKeep, &(top.idef.il[i]), interaction_function[i].nratoms, interaction_function[i].name); } @@ -292,7 +289,7 @@ static void reduce_topology_x(int gnx, int index[], mtop->moltype[0].atoms = top.atoms; for (i = 0; i < F_NRE; i++) { - InteractionList &ilist = mtop->moltype[0].ilist[i]; + InteractionList& ilist = mtop->moltype[0].ilist[i]; ilist.iatoms.resize(top.idef.il[i].nr); for (int j = 0; j < top.idef.il[i].nr; j++) { @@ -306,12 +303,12 @@ static void reduce_topology_x(int gnx, int index[], mtop->molblock[0].type = 0; mtop->molblock[0].nmol = 1; - mtop->natoms = top.atoms.nr; + mtop->natoms = top.atoms.nr; } -static void zeroq(const int index[], gmx_mtop_t *mtop) +static void zeroq(const int index[], gmx_mtop_t* mtop) { - for (gmx_moltype_t &moltype : mtop->moltype) + for (gmx_moltype_t& moltype : mtop->moltype) { for (int i = 0; i < moltype.atoms.nr; i++) { @@ -321,16 +318,17 @@ static void zeroq(const int index[], gmx_mtop_t *mtop) } } -int gmx_convert_tpr(int argc, char *argv[]) +int gmx_convert_tpr(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] can edit run input files in three ways.[PAR]", "[BB]1.[bb] by modifying the number of steps in a run input file", "with options [TT]-extend[tt], [TT]-until[tt] or [TT]-nsteps[tt]", "(nsteps=-1 means unlimited number of steps)[PAR]", "[BB]2.[bb] by creating a [REF].tpx[ref] file for a subset of your original", "tpx file, which is useful when you want to remove the solvent from", - "your [REF].tpx[ref] file, or when you want to make e.g. a pure C[GRK]alpha[grk] [REF].tpx[ref] file.", + "your [REF].tpx[ref] file, or when you want to make e.g. a pure C[GRK]alpha[grk] ", + "[REF].tpx[ref] file.", "Note that you may need to use [TT]-nsteps -1[tt] (or similar) to get", "this to work.", "[BB]WARNING: this [REF].tpx[ref] file is not fully functional[bb].[PAR]", @@ -339,7 +337,7 @@ int gmx_convert_tpr(int argc, char *argv[]) "using the LIE (Linear Interaction Energy) method." }; - const char *top_fn; + const char* top_fn; int i; int64_t nsteps_req, run_step; double run_t, state_t; @@ -349,35 +347,32 @@ int gmx_convert_tpr(int argc, char *argv[]) t_atoms atoms; t_state state; int gnx; - char *grpname; - int *index = nullptr; + char* grpname; + int* index = nullptr; char buf[200], buf2[200]; - gmx_output_env_t *oenv; - t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efTPR, "-o", "tprout", ffWRITE } - }; + gmx_output_env_t* oenv; + t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD }, + { efTPR, "-o", "tprout", ffWRITE } }; #define NFILE asize(fnm) /* Command line options */ static int nsteps_req_int = 0; - static real extend_t = 0.0, until_t = 0.0; - static gmx_bool bZeroQ = FALSE; - static t_pargs pa[] = { - { "-extend", FALSE, etREAL, {&extend_t}, - "Extend runtime by this amount (ps)" }, - { "-until", FALSE, etREAL, {&until_t}, - "Extend runtime until this ending time (ps)" }, - { "-nsteps", FALSE, etINT, {&nsteps_req_int}, - "Change the number of steps" }, - { "-zeroq", FALSE, etBOOL, {&bZeroQ}, + static real extend_t = 0.0, until_t = 0.0; + static gmx_bool bZeroQ = FALSE; + static t_pargs pa[] = { + { "-extend", FALSE, etREAL, { &extend_t }, "Extend runtime by this amount (ps)" }, + { "-until", FALSE, etREAL, { &until_t }, "Extend runtime until this ending time (ps)" }, + { "-nsteps", FALSE, etINT, { &nsteps_req_int }, "Change the number of steps" }, + { "-zeroq", + FALSE, + etBOOL, + { &bZeroQ }, "Set the charges of a group (from the index) to zero" } }; /* Parse the command line */ - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -392,10 +387,10 @@ int gmx_convert_tpr(int argc, char *argv[]) fprintf(stderr, "Reading toplogy and stuff from %s\n", top_fn); t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec* ir = &irInstance; read_tpx_state(top_fn, ir, &state, &mtop); run_step = ir->init_step; - run_t = ir->init_step*ir->delta_t + ir->init_t; + run_t = ir->init_step * ir->delta_t + ir->init_t; if (bNsteps) { @@ -407,26 +402,24 @@ int gmx_convert_tpr(int argc, char *argv[]) /* Determine total number of steps remaining */ if (bExtend) { - ir->nsteps = ir->nsteps - (run_step - ir->init_step) + gmx::roundToInt64(extend_t/ir->delta_t); - printf("Extending remaining runtime of by %g ps (now %s steps)\n", - extend_t, gmx_step_str(ir->nsteps, buf)); + ir->nsteps = ir->nsteps - (run_step - ir->init_step) + gmx::roundToInt64(extend_t / ir->delta_t); + printf("Extending remaining runtime of by %g ps (now %s steps)\n", extend_t, + gmx_step_str(ir->nsteps, buf)); } else if (bUntil) { printf("nsteps = %s, run_step = %s, current_t = %g, until = %g\n", - gmx_step_str(ir->nsteps, buf), - gmx_step_str(run_step, buf2), - run_t, until_t); - ir->nsteps = gmx::roundToInt64((until_t - run_t)/ir->delta_t); - printf("Extending remaining runtime until %g ps (now %s steps)\n", - until_t, gmx_step_str(ir->nsteps, buf)); + gmx_step_str(ir->nsteps, buf), gmx_step_str(run_step, buf2), run_t, until_t); + ir->nsteps = gmx::roundToInt64((until_t - run_t) / ir->delta_t); + printf("Extending remaining runtime until %g ps (now %s steps)\n", until_t, + gmx_step_str(ir->nsteps, buf)); } else { ir->nsteps -= run_step - ir->init_step; /* Print message */ - printf("%s steps (%g ps) remaining from first run.\n", - gmx_step_str(ir->nsteps, buf), ir->nsteps*ir->delta_t); + printf("%s steps (%g ps) remaining from first run.\n", gmx_step_str(ir->nsteps, buf), + ir->nsteps * ir->delta_t); } } @@ -434,12 +427,10 @@ int gmx_convert_tpr(int argc, char *argv[]) { ir->init_step = run_step; - if (ftp2bSet(efNDX, NFILE, fnm) || - !(bNsteps || bExtend || bUntil)) + if (ftp2bSet(efNDX, NFILE, fnm) || !(bNsteps || bExtend || bUntil)) { atoms = gmx_mtop_global_atoms(&mtop); - get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, - &gnx, &index, &grpname); + get_index(&atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &gnx, &index, &grpname); if (!bZeroQ) { bSel = (gnx != state.natoms); @@ -454,8 +445,10 @@ int gmx_convert_tpr(int argc, char *argv[]) } if (bSel) { - fprintf(stderr, "Will write subset %s of original tpx containing %d " - "atoms\n", grpname, gnx); + fprintf(stderr, + "Will write subset %s of original tpx containing %d " + "atoms\n", + grpname, gnx); reduce_topology_x(gnx, index, &mtop, state.x.rvec_array(), state.v.rvec_array()); state.natoms = gnx; } @@ -470,11 +463,12 @@ int gmx_convert_tpr(int argc, char *argv[]) } } - state_t = ir->init_t + ir->init_step*ir->delta_t; - sprintf(buf, "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10", PRId64, "%10", PRId64); + state_t = ir->init_t + ir->init_step * ir->delta_t; + sprintf(buf, "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10", + PRId64, "%10", PRId64); fprintf(stderr, buf, ir->init_step, ir->nsteps); fprintf(stderr, " time %10.3f and length %10.3f ps\n", - state_t, ir->nsteps*ir->delta_t); + state_t, ir->nsteps * ir->delta_t); write_tpx_state(opt2fn("-o", NFILE, fnm), ir, &state, &mtop); } else diff --git a/src/gromacs/tools/convert_tpr.h b/src/gromacs/tools/convert_tpr.h index 23c52ffa7e..ed8bf8adb6 100644 --- a/src/gromacs/tools/convert_tpr.h +++ b/src/gromacs/tools/convert_tpr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_convert_tpr(int argc, char *argv[]); +int gmx_convert_tpr(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/dump.cpp b/src/gromacs/tools/dump.cpp index 91d429b0dc..622b4c1eb3 100644 --- a/src/gromacs/tools/dump.cpp +++ b/src/gromacs/tools/dump.cpp @@ -88,26 +88,23 @@ namespace { //! Dump a TPR file -void list_tpr(const char *fn, +void list_tpr(const char* fn, gmx_bool bShowNumbers, gmx_bool bShowParameters, - const char *mdpfn, + const char* mdpfn, gmx_bool bSysTop, gmx_bool bOriginalInputrec) { - FILE *gp; - int indent, atot; - t_state state; - gmx_mtop_t mtop; - t_topology top; + FILE* gp; + int indent, atot; + t_state state; + gmx_mtop_t mtop; + t_topology top; TpxFileHeader tpx = readTpxHeader(fn, true); t_inputrec ir; - read_tpx_state(fn, - tpx.bIr ? &ir : nullptr, - &state, - tpx.bTop ? &mtop : nullptr); + read_tpx_state(fn, tpx.bIr ? &ir : nullptr, &state, tpx.bTop ? &mtop : nullptr); if (tpx.bIr && !bOriginalInputrec) { MDModules().adjustInputrecBasedOnModules(&ir); @@ -158,9 +155,9 @@ void list_tpr(const char *fn, pr_rvecs(stdout, indent, "v", tpx.bV ? state.v.rvec_array() : nullptr, state.natoms); } - const SimulationGroups &groups = mtop.groups; + const SimulationGroups& groups = mtop.groups; - gmx::EnumerationArray < SimulationAtomGroupType, std::vector < int>> gcount; + gmx::EnumerationArray> gcount; for (auto group : keysOf(gcount)) { gcount[group].resize(groups.groups[group].size()); @@ -178,7 +175,7 @@ void list_tpr(const char *fn, { atot = 0; printf("%-12s: ", shortName(group)); - for (const auto &entry : gcount[group]) + for (const auto& entry : gcount[group]) { printf(" %5d", entry); atot += entry; @@ -189,13 +186,13 @@ void list_tpr(const char *fn, } //! Dump a topology file -void list_top(const char *fn) +void list_top(const char* fn) { - int status, done; + int status, done; // Legacy string length macro char buf[STRLEN]; gmx_cpp_t handle; - char *cppopts[] = { nullptr }; + char* cppopts[] = { nullptr }; status = cpp_open_file(fn, &handle, cppopts); if (status != 0) @@ -217,8 +214,7 @@ void list_top(const char *fn) printf("%s\n", buf); } } - } - while (done == 0); + } while (done == 0); status = cpp_close_file(&handle); if (status != eCPP_OK) { @@ -227,17 +223,17 @@ void list_top(const char *fn) } //! Dump a TRR file -void list_trr(const char *fn) +void list_trr(const char* fn) { - t_fileio *fpread; - int nframe, indent; - char buf[256]; - rvec *x, *v, *f; - matrix box; - gmx_trr_header_t trrheader; - gmx_bool bOK; + t_fileio* fpread; + int nframe, indent; + char buf[256]; + rvec * x, *v, *f; + matrix box; + gmx_trr_header_t trrheader; + gmx_bool bOK; - fpread = gmx_trr_open(fn, "r"); + fpread = gmx_trr_open(fn, "r"); nframe = 0; while (gmx_trr_read_frame_header(fpread, &trrheader, &bOK)) @@ -245,11 +241,9 @@ void list_trr(const char *fn) snew(x, trrheader.natoms); snew(v, trrheader.natoms); snew(f, trrheader.natoms); - if (gmx_trr_read_frame_data(fpread, &trrheader, - trrheader.box_size ? box : nullptr, - trrheader.x_size ? x : nullptr, - trrheader.v_size ? v : nullptr, - trrheader.f_size ? f : nullptr)) + if (gmx_trr_read_frame_data(fpread, &trrheader, trrheader.box_size ? box : nullptr, + trrheader.x_size ? x : nullptr, trrheader.v_size ? v : nullptr, + trrheader.f_size ? f : nullptr)) { sprintf(buf, "%s frame %d", fn, nframe); indent = 0; @@ -276,8 +270,7 @@ void list_trr(const char *fn) } else { - fprintf(stderr, "\nWARNING: Incomplete frame: nr %d, t=%g\n", - nframe, trrheader.t); + fprintf(stderr, "\nWARNING: Incomplete frame: nr %d, t=%g\n", nframe, trrheader.t); } sfree(x); @@ -287,24 +280,23 @@ void list_trr(const char *fn) } if (!bOK) { - fprintf(stderr, "\nWARNING: Incomplete frame header: nr %d, t=%g\n", - nframe, trrheader.t); + fprintf(stderr, "\nWARNING: Incomplete frame header: nr %d, t=%g\n", nframe, trrheader.t); } gmx_trr_close(fpread); } //! Dump an xtc file -void list_xtc(const char *fn) +void list_xtc(const char* fn) { - t_fileio *xd; - int indent; - char buf[256]; - rvec *x; - matrix box; - int nframe, natoms; - int64_t step; - real prec, time; - gmx_bool bOK; + t_fileio* xd; + int indent; + char buf[256]; + rvec* x; + matrix box; + int nframe, natoms; + int64_t step; + real prec, time; + gmx_bool bOK; xd = open_xtc(fn, "r"); read_first_xtc(xd, &natoms, &step, &time, box, &x, &prec, &bOK); @@ -316,13 +308,12 @@ void list_xtc(const char *fn) indent = 0; indent = pr_title(stdout, indent, buf); pr_indent(stdout, indent); - fprintf(stdout, "natoms=%10d step=%10" PRId64 " time=%12.7e prec=%10g\n", - natoms, step, time, prec); + fprintf(stdout, "natoms=%10d step=%10" PRId64 " time=%12.7e prec=%10g\n", natoms, step, + time, prec); pr_rvecs(stdout, indent, "box", box, DIM); pr_rvecs(stdout, indent, "x", x, natoms); nframe++; - } - while (read_next_xtc(xd, natoms, &step, &time, box, x, &prec, &bOK) != 0); + } while (read_next_xtc(xd, natoms, &step, &time, box, x, &prec, &bOK) != 0); if (!bOK) { fprintf(stderr, "\nWARNING: Incomplete frame at time %g\n", time); @@ -334,19 +325,19 @@ void list_xtc(const char *fn) #if GMX_USE_TNG /*! \brief Callback used by list_tng_for_gmx_dump. */ -void list_tng_inner(const char *fn, +void list_tng_inner(const char* fn, gmx_bool bFirstFrame, - real *values, + real* values, int64_t step, double frame_time, int64_t n_values_per_frame, int64_t n_atoms, real prec, int64_t nframe, - char *block_name) + char* block_name) { - char buf[256]; - int indent = 0; + char buf[256]; + int indent = 0; if (bFirstFrame) { @@ -354,8 +345,7 @@ void list_tng_inner(const char *fn, indent = 0; indent = pr_title(stdout, indent, buf); pr_indent(stdout, indent); - fprintf(stdout, "natoms=%10" PRId64 " step=%10" PRId64 " time=%12.7e", - n_atoms, step, frame_time); + fprintf(stdout, "natoms=%10" PRId64 " step=%10" PRId64 " time=%12.7e", n_atoms, step, frame_time); if (prec > 0) { fprintf(stdout, " prec=%10g", prec); @@ -368,57 +358,47 @@ void list_tng_inner(const char *fn, #endif //! Dump a TNG file -void list_tng(const char *fn) +void list_tng(const char* fn) { #if GMX_USE_TNG gmx_tng_trajectory_t tng; int64_t nframe = 0; int64_t i, *block_ids = nullptr, step, ndatablocks; gmx_bool bOK; - real *values = nullptr; + real* values = nullptr; gmx_tng_open(fn, 'r', &tng); gmx_print_tng_molecule_system(tng, stdout); - bOK = gmx_get_tng_data_block_types_of_next_frame(tng, -1, - 0, - nullptr, - &step, &ndatablocks, - &block_ids); + bOK = gmx_get_tng_data_block_types_of_next_frame(tng, -1, 0, nullptr, &step, &ndatablocks, &block_ids); do { for (i = 0; i < ndatablocks; i++) { - double frame_time; - real prec; - int64_t n_values_per_frame, n_atoms; - char block_name[STRLEN]; - - gmx_get_tng_data_next_frame_of_block_type(tng, block_ids[i], &values, - &step, &frame_time, - &n_values_per_frame, &n_atoms, - &prec, - block_name, STRLEN, &bOK); + double frame_time; + real prec; + int64_t n_values_per_frame, n_atoms; + char block_name[STRLEN]; + + gmx_get_tng_data_next_frame_of_block_type(tng, block_ids[i], &values, &step, + &frame_time, &n_values_per_frame, &n_atoms, + &prec, block_name, STRLEN, &bOK); if (!bOK) { /* Can't write any output because we don't know what arrays are valid. */ - fprintf(stderr, "\nWARNING: Incomplete frame at time %g, will not write output\n", frame_time); + fprintf(stderr, "\nWARNING: Incomplete frame at time %g, will not write output\n", + frame_time); } else { - list_tng_inner(fn, (0 == i), values, step, frame_time, - n_values_per_frame, n_atoms, prec, nframe, block_name); + list_tng_inner(fn, (0 == i), values, step, frame_time, n_values_per_frame, n_atoms, + prec, nframe, block_name); } } nframe++; - } - while (gmx_get_tng_data_block_types_of_next_frame(tng, step, - 0, - nullptr, - &step, - &ndatablocks, - &block_ids)); + } while (gmx_get_tng_data_block_types_of_next_frame(tng, step, 0, nullptr, &step, &ndatablocks, + &block_ids)); if (block_ids) { @@ -432,19 +412,13 @@ void list_tng(const char *fn) } //! Dump a trajectory file -void list_trx(const char *fn) +void list_trx(const char* fn) { switch (fn2ftp(fn)) { - case efXTC: - list_xtc(fn); - break; - case efTRR: - list_trr(fn); - break; - case efTNG: - list_tng(fn); - break; + case efXTC: list_xtc(fn); break; + case efTRR: list_trr(fn); break; + case efTNG: list_tng(fn); break; default: fprintf(stderr, "File %s is of an unsupported type. Try using the command\n 'less %s'\n", fn, fn); @@ -452,14 +426,14 @@ void list_trx(const char *fn) } //! Dump an energy file -void list_ene(const char *fn) +void list_ene(const char* fn) { - ener_file_t in; - gmx_bool bCont; - gmx_enxnm_t *enm = nullptr; - t_enxframe *fr; - int i, j, nre, b; - char buf[22]; + ener_file_t in; + gmx_bool bCont; + gmx_enxnm_t* enm = nullptr; + t_enxframe* fr; + int i, j, nre, b; + char buf[22]; printf("gmx dump: %s\n", fn); in = open_enx(fn, "r"); @@ -479,41 +453,36 @@ void list_ene(const char *fn) if (bCont) { - printf("\n%24s %12.5e %12s %12s\n", "time:", - fr->t, "step:", gmx_step_str(fr->step, buf)); - printf("%24s %12s %12s %12s\n", - "", "", "nsteps:", gmx_step_str(fr->nsteps, buf)); - printf("%24s %12.5e %12s %12s\n", - "delta_t:", fr->dt, "sum steps:", gmx_step_str(fr->nsum, buf)); + printf("\n%24s %12.5e %12s %12s\n", "time:", fr->t, "step:", gmx_step_str(fr->step, buf)); + printf("%24s %12s %12s %12s\n", "", "", "nsteps:", gmx_step_str(fr->nsteps, buf)); + printf("%24s %12.5e %12s %12s\n", "delta_t:", fr->dt, + "sum steps:", gmx_step_str(fr->nsum, buf)); if (fr->nre == nre) { - printf("%24s %12s %12s %12s\n", - "Component", "Energy", "Av. Energy", "Sum Energy"); + printf("%24s %12s %12s %12s\n", "Component", "Energy", "Av. Energy", + "Sum Energy"); if (fr->nsum > 0) { for (i = 0; (i < nre); i++) { - printf("%24s %12.5e %12.5e %12.5e\n", - enm[i].name, fr->ener[i].e, fr->ener[i].eav, - fr->ener[i].esum); + printf("%24s %12.5e %12.5e %12.5e\n", enm[i].name, fr->ener[i].e, + fr->ener[i].eav, fr->ener[i].esum); } } else { for (i = 0; (i < nre); i++) { - printf("%24s %12.5e\n", - enm[i].name, fr->ener[i].e); + printf("%24s %12.5e\n", enm[i].name, fr->ener[i].e); } } } for (b = 0; b < fr->nblock; b++) { - const char *typestr = ""; + const char* typestr = ""; - t_enxblock *eb = &(fr->block[b]); - printf("Block data %2d (%3d subblocks, id=%d)\n", - b, eb->nsub, eb->id); + t_enxblock* eb = &(fr->block[b]); + printf("Block data %2d (%3d subblocks, id=%d)\n", b, eb->nsub, eb->id); if (eb->id < enxNR) { @@ -522,9 +491,9 @@ void list_ene(const char *fn) printf(" id='%s'\n", typestr); for (i = 0; i < eb->nsub; i++) { - t_enxsubblock *sb = &(eb->sub[i]); - printf(" Sub block %3d (%5d elems, type=%s) values:\n", - i, sb->nr, xdr_datatype_names[sb->type]); + t_enxsubblock* sb = &(eb->sub[i]); + printf(" Sub block %3d (%5d elems, type=%s) values:\n", i, sb->nr, + xdr_datatype_names[sb->type]); switch (sb->type) { @@ -549,8 +518,7 @@ void list_ene(const char *fn) case xdr_datatype_int64: for (j = 0; j < sb->nr; j++) { - printf("%14d %s\n", - j, gmx_step_str(sb->lval[j], buf)); + printf("%14d %s\n", j, gmx_step_str(sb->lval[j], buf)); } break; case xdr_datatype_char: @@ -565,14 +533,12 @@ void list_ene(const char *fn) printf("%14d %80s\n", j, sb->sval[j]); } break; - default: - gmx_incons("Unknown subblock type"); + default: gmx_incons("Unknown subblock type"); } } } } - } - while (bCont); + } while (bCont); close_enx(in); @@ -582,18 +548,18 @@ void list_ene(const char *fn) } //! Dump a (Hessian) matrix file -void list_mtx(const char *fn) +void list_mtx(const char* fn) { - int nrow, ncol, i, j, k; - real *full = nullptr, value; - gmx_sparsematrix_t * sparse = nullptr; + int nrow, ncol, i, j, k; + real * full = nullptr, value; + gmx_sparsematrix_t* sparse = nullptr; gmx_mtxio_read(fn, &nrow, &ncol, &full, &sparse); if (full == nullptr) { - snew(full, nrow*ncol); - for (i = 0; i < nrow*ncol; i++) + snew(full, nrow * ncol); + for (i = 0; i < nrow * ncol; i++) { full[i] = 0; } @@ -602,10 +568,10 @@ void list_mtx(const char *fn) { for (j = 0; j < sparse->ndata[i]; j++) { - k = sparse->data[i][j].col; - value = sparse->data[i][j].value; - full[i*ncol+k] = value; - full[k*ncol+i] = value; + k = sparse->data[i][j].col; + value = sparse->data[i][j].value; + full[i * ncol + k] = value; + full[k * ncol + i] = value; } } gmx_sparsematrix_destroy(sparse); @@ -616,7 +582,7 @@ void list_mtx(const char *fn) { for (j = 0; j < ncol; j++) { - printf(" %g", full[i*ncol+j]); + printf(" %g", full[i * ncol + j]); } printf("\n"); } @@ -626,57 +592,50 @@ void list_mtx(const char *fn) class Dump : public ICommandLineOptionsModule { - public: - Dump() - {} - - // From ICommandLineOptionsModule - void init(CommandLineModuleSettings * /*settings*/) override - { - } - - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - - void optionsFinished() override; - - int run() override; - - private: - //! Commandline options - //! \{ - bool bShowNumbers_ = true; - bool bShowParams_ = false; - bool bSysTop_ = false; - bool bOriginalInputrec_ = false; - //! \} - //! Commandline file options - //! \{ - std::string inputTprFilename_; - std::string inputTrajectoryFilename_; - std::string inputEnergyFilename_; - std::string inputCheckpointFilename_; - std::string inputTopologyFilename_; - std::string inputMatrixFilename_; - std::string outputMdpFilename_; - //! \} +public: + Dump() {} + + // From ICommandLineOptionsModule + void init(CommandLineModuleSettings* /*settings*/) override {} + + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + + void optionsFinished() override; + + int run() override; + +private: + //! Commandline options + //! \{ + bool bShowNumbers_ = true; + bool bShowParams_ = false; + bool bSysTop_ = false; + bool bOriginalInputrec_ = false; + //! \} + //! Commandline file options + //! \{ + std::string inputTprFilename_; + std::string inputTrajectoryFilename_; + std::string inputEnergyFilename_; + std::string inputCheckpointFilename_; + std::string inputTopologyFilename_; + std::string inputMatrixFilename_; + std::string outputMdpFilename_; + //! \} }; -void Dump::initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) +void Dump::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - const char *desc[] = { - "[THISMODULE] reads a run input file ([REF].tpr[ref]),", - "a trajectory ([REF].trr[ref]/[REF].xtc[ref]/[TT]tng[tt]), an energy", - "file ([REF].edr[ref]), a checkpoint file ([REF].cpt[ref])", - "or topology file ([REF].top[ref])", - "and prints that to standard output in a readable format.", - "This program is essential for checking your run input file in case of", - "problems." - }; + const char* desc[] = { "[THISMODULE] reads a run input file ([REF].tpr[ref]),", + "a trajectory ([REF].trr[ref]/[REF].xtc[ref]/[TT]tng[tt]), an energy", + "file ([REF].edr[ref]), a checkpoint file ([REF].cpt[ref])", + "or topology file ([REF].top[ref])", + "and prints that to standard output in a readable format.", + "This program is essential for checking your run input file in case of", + "problems." }; settings->setHelpText(desc); - const char *bugs[] = { + const char* bugs[] = { "The [REF].mdp[ref] file produced by [TT]-om[tt] can not be read by grompp." }; settings->setBugText(bugs); @@ -684,47 +643,35 @@ void Dump::initOptions(IOptionsContainer *options, // fix it or block that run path: // Position restraint output from -sys -s is broken - options->addOption(FileNameOption("s") - .filetype(eftRunInput).inputFile() - .store(&inputTprFilename_) - .description("Run input file to dump")); + options->addOption( + FileNameOption("s").filetype(eftRunInput).inputFile().store(&inputTprFilename_).description("Run input file to dump")); options->addOption(FileNameOption("f") - .filetype(eftTrajectory).inputFile() - .store(&inputTrajectoryFilename_) - .description("Trajectory file to dump")); - options->addOption(FileNameOption("e") - .filetype(eftEnergy).inputFile() - .store(&inputEnergyFilename_) - .description("Energy file to dump")); - options->addOption(FileNameOption("cp") - .legacyType(efCPT).inputFile() - .store(&inputCheckpointFilename_) - .description("Checkpoint file to dump")); - options->addOption(FileNameOption("p") - .legacyType(efTOP).inputFile() - .store(&inputTopologyFilename_) - .description("Topology file to dump")); - options->addOption(FileNameOption("mtx") - .legacyType(efMTX).inputFile() - .store(&inputMatrixFilename_) - .description("Hessian matrix to dump")); + .filetype(eftTrajectory) + .inputFile() + .store(&inputTrajectoryFilename_) + .description("Trajectory file to dump")); + options->addOption( + FileNameOption("e").filetype(eftEnergy).inputFile().store(&inputEnergyFilename_).description("Energy file to dump")); + options->addOption( + FileNameOption("cp").legacyType(efCPT).inputFile().store(&inputCheckpointFilename_).description("Checkpoint file to dump")); + options->addOption( + FileNameOption("p").legacyType(efTOP).inputFile().store(&inputTopologyFilename_).description("Topology file to dump")); + options->addOption( + FileNameOption("mtx").legacyType(efMTX).inputFile().store(&inputMatrixFilename_).description("Hessian matrix to dump")); options->addOption(FileNameOption("om") - .legacyType(efMDP).outputFile() - .store(&outputMdpFilename_) - .description("grompp input file from run input file")); - - options->addOption(BooleanOption("nr") - .store(&bShowNumbers_).defaultValue(true) - .description("Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)")); - options->addOption(BooleanOption("param") - .store(&bShowParams_).defaultValue(false) - .description("Show parameters for each bonded interaction (for comparing dumps, it is useful to combine this with -nonr)")); - options->addOption(BooleanOption("sys") - .store(&bShowParams_).defaultValue(false) - .description("List the atoms and bonded interactions for the whole system instead of for each molecule type")); - options->addOption(BooleanOption("orgir") - .store(&bShowParams_).defaultValue(false) - .description("Show input parameters from tpr as they were written by the version that produced the file, instead of how the current version reads them")); + .legacyType(efMDP) + .outputFile() + .store(&outputMdpFilename_) + .description("grompp input file from run input file")); + + options->addOption( + BooleanOption("nr").store(&bShowNumbers_).defaultValue(true).description("Show index numbers in output (leaving them out makes comparison easier, but creates a useless topology)")); + options->addOption( + BooleanOption("param").store(&bShowParams_).defaultValue(false).description("Show parameters for each bonded interaction (for comparing dumps, it is useful to combine this with -nonr)")); + options->addOption( + BooleanOption("sys").store(&bShowParams_).defaultValue(false).description("List the atoms and bonded interactions for the whole system instead of for each molecule type")); + options->addOption( + BooleanOption("orgir").store(&bShowParams_).defaultValue(false).description("Show input parameters from tpr as they were written by the version that produced the file, instead of how the current version reads them")); } void Dump::optionsFinished() @@ -739,8 +686,8 @@ int Dump::run() if (!inputTprFilename_.empty()) { list_tpr(inputTprFilename_.c_str(), bShowNumbers_, bShowParams_, - outputMdpFilename_.empty() ? nullptr : outputMdpFilename_.c_str(), - bSysTop_, bOriginalInputrec_); + outputMdpFilename_.empty() ? nullptr : outputMdpFilename_.c_str(), bSysTop_, + bOriginalInputrec_); } else if (!inputTrajectoryFilename_.empty()) { @@ -766,14 +713,13 @@ int Dump::run() return 0; } -} // namespace +} // namespace -const char DumpInfo::name[] = "dump"; -const char DumpInfo::shortDescription[] = - "Make binary files human readable"; +const char DumpInfo::name[] = "dump"; +const char DumpInfo::shortDescription[] = "Make binary files human readable"; ICommandLineOptionsModulePointer DumpInfo::create() { return std::make_unique(); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/tools/dump.h b/src/gromacs/tools/dump.h index f8f2f99ef9..efa27ad771 100644 --- a/src/gromacs/tools/dump.h +++ b/src/gromacs/tools/dump.h @@ -43,12 +43,12 @@ namespace gmx class DumpInfo { - public: - static const char name[]; - static const char shortDescription[]; - static ICommandLineOptionsModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static ICommandLineOptionsModulePointer create(); }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/tools/eneconv.cpp b/src/gromacs/tools/eneconv.cpp index c76e4b9eb2..4f9b1281f7 100644 --- a/src/gromacs/tools/eneconv.cpp +++ b/src/gromacs/tools/eneconv.cpp @@ -62,16 +62,16 @@ #define TIME_EXPLICIT 0 #define TIME_CONTINUE 1 -#define TIME_LAST 2 +#define TIME_LAST 2 #ifndef FLT_MAX -#define FLT_MAX 1e36 +# define FLT_MAX 1e36 #endif -static int *select_it(int nre, gmx_enxnm_t *nm, int *nset) +static int* select_it(int nre, gmx_enxnm_t* nm, int* nset) { - gmx_bool *bE; + gmx_bool* bE; int n, k, j, i; - int *set; + int* set; gmx_bool bVerbose = TRUE; if ((getenv("GMX_ENER_VERBOSE")) != nullptr) @@ -84,11 +84,11 @@ static int *select_it(int nre, gmx_enxnm_t *nm, int *nset) if (bVerbose) { - for (k = 0; (k < nre); ) + for (k = 0; (k < nre);) { for (j = 0; (j < 4) && (k < nre); j++, k++) { - fprintf(stderr, " %3d=%14s", k+1, nm[k].name); + fprintf(stderr, " %3d=%14s", k + 1, nm[k].name); } fprintf(stderr, "\n"); } @@ -103,10 +103,9 @@ static int *select_it(int nre, gmx_enxnm_t *nm, int *nset) } if ((n > 0) && (n <= nre)) { - bE[n-1] = TRUE; + bE[n - 1] = TRUE; } - } - while (n != 0); + } while (n != 0); snew(set, nre); for (i = (*nset) = 0; (i < nre); i++) @@ -122,7 +121,7 @@ static int *select_it(int nre, gmx_enxnm_t *nm, int *nset) return set; } -static void sort_files(gmx::ArrayRef files, real *settime) +static void sort_files(gmx::ArrayRef files, real* settime) { for (gmx::index i = 0; i < files.ssize(); i++) { @@ -147,16 +146,15 @@ static void sort_files(gmx::ArrayRef files, real *settime) } -static int scan_ene_files(const std::vector &files, - real *readtime, real *timestep, int *nremax) +static int scan_ene_files(const std::vector& files, real* readtime, real* timestep, int* nremax) { /* Check number of energy terms and start time of all files */ int nre, nremin = 0, nresav = 0; ener_file_t in; real t1, t2; char inputstring[STRLEN]; - gmx_enxnm_t *enm; - t_enxframe *fr; + gmx_enxnm_t* enm; + t_enxframe* fr; snew(fr, 1); @@ -175,7 +173,7 @@ static int scan_ene_files(const std::vector &files, t1 = fr->t; do_enx(in, fr); t2 = fr->t; - *timestep = t2-t1; + *timestep = t2 - t1; readtime[f] = t1; close_enx(in); } @@ -187,11 +185,13 @@ static int scan_ene_files(const std::vector &files, { fprintf(stderr, "Energy files don't match, different number of energies:\n" - " %s: %d\n %s: %d\n", files[f - 1].c_str(), nresav, files[f].c_str(), fr->nre); + " %s: %d\n %s: %d\n", + files[f - 1].c_str(), nresav, files[f].c_str(), fr->nre); fprintf(stderr, "\nContinue conversion using only the first %d terms (n/y)?\n" - "(you should be sure that the energy terms match)\n", nremin); - if (nullptr == fgets(inputstring, STRLEN-1, stdin)) + "(you should be sure that the energy terms match)\n", + nremin); + if (nullptr == fgets(inputstring, STRLEN - 1, stdin)) { gmx_fatal(FARGS, "Error reading user input"); } @@ -217,8 +217,12 @@ static int scan_ene_files(const std::vector &files, } -static void edit_files(gmx::ArrayRef files, real *readtime, - real *settime, int *cont_type, gmx_bool bSetTime, gmx_bool bSort) +static void edit_files(gmx::ArrayRef files, + real* readtime, + real* settime, + int* cont_type, + gmx_bool bSetTime, + gmx_bool bSort) { gmx_bool ok; char inputstring[STRLEN], *chptr; @@ -231,7 +235,8 @@ static void edit_files(gmx::ArrayRef files, real *readtime, } else { - fprintf(stderr, "\n\nEnter the new start time for each file.\n" + fprintf(stderr, + "\n\nEnter the new start time for each file.\n" "There are two special options, both disables sorting:\n\n" "c (continue) - The start time is taken from the end\n" "of the previous file. Use it when your continuation run\n" @@ -242,7 +247,8 @@ static void edit_files(gmx::ArrayRef files, real *readtime, "since this takes possible overlap into account.\n\n"); } - fprintf(stderr, " File Current start New start\n" + fprintf(stderr, + " File Current start New start\n" "---------------------------------------------------------\n"); for (gmx::index i = 0; i < files.ssize(); i++) @@ -251,11 +257,11 @@ static void edit_files(gmx::ArrayRef files, real *readtime, ok = FALSE; do { - if (nullptr == fgets(inputstring, STRLEN-1, stdin)) + if (nullptr == fgets(inputstring, STRLEN - 1, stdin)) { gmx_fatal(FARGS, "Error reading user input"); } - inputstring[std::strlen(inputstring)-1] = 0; + inputstring[std::strlen(inputstring) - 1] = 0; if (inputstring[0] == 'c' || inputstring[0] == 'C') { @@ -264,8 +270,7 @@ static void edit_files(gmx::ArrayRef files, real *readtime, ok = TRUE; settime[i] = FLT_MAX; } - else if (inputstring[0] == 'l' || - inputstring[0] == 'L') + else if (inputstring[0] == 'l' || inputstring[0] == 'L') { cont_type[i] = TIME_LAST; bSort = FALSE; @@ -285,8 +290,7 @@ static void edit_files(gmx::ArrayRef files, real *readtime, ok = TRUE; } } - } - while (!ok); + } while (!ok); } if (cont_type[0] != TIME_EXPLICIT) { @@ -313,7 +317,8 @@ static void edit_files(gmx::ArrayRef files, real *readtime, /* Write out the new order and start times */ - fprintf(stderr, "\nSummary of files and start times used:\n\n" + fprintf(stderr, + "\nSummary of files and start times used:\n\n" " File Start time\n" "-----------------------------------------\n"); for (gmx::index i = 0; i < files.ssize(); i++) @@ -339,15 +344,16 @@ static void edit_files(gmx::ArrayRef files, real *readtime, } -static void update_ee_sum(int nre, - int64_t *ee_sum_step, - int64_t *ee_sum_nsteps, - int64_t *ee_sum_nsum, - t_energy *ee_sum, - t_enxframe *fr, int out_step) +static void update_ee_sum(int nre, + int64_t* ee_sum_step, + int64_t* ee_sum_nsteps, + int64_t* ee_sum_nsum, + t_energy* ee_sum, + t_enxframe* fr, + int out_step) { - int64_t nsteps, nsum, fr_nsum; - int i; + int64_t nsteps, nsum, fr_nsum; + int i; nsteps = *ee_sum_nsteps; nsum = *ee_sum_nsum; @@ -385,9 +391,9 @@ static void update_ee_sum(int nre, { for (i = 0; i < nre; i++) { - ee_sum[i].eav += - gmx::square(ee_sum[i].esum/nsum - - (ee_sum[i].esum + fr->ener[i].e)/(nsum + 1))*nsum*(nsum + 1); + ee_sum[i].eav += gmx::square(ee_sum[i].esum / nsum + - (ee_sum[i].esum + fr->ener[i].e) / (nsum + 1)) + * nsum * (nsum + 1); ee_sum[i].esum += fr->ener[i].e; } } @@ -395,16 +401,15 @@ static void update_ee_sum(int nre, { for (i = 0; i < fr->nre; i++) { - ee_sum[i].eav += - fr->ener[i].eav + - gmx::square(ee_sum[i].esum/nsum - - (ee_sum[i].esum + fr->ener[i].esum)/(nsum + fr->nsum))* - nsum*(nsum + fr->nsum)/static_cast(fr->nsum); + ee_sum[i].eav += fr->ener[i].eav + + gmx::square(ee_sum[i].esum / nsum + - (ee_sum[i].esum + fr->ener[i].esum) / (nsum + fr->nsum)) + * nsum * (nsum + fr->nsum) / static_cast(fr->nsum); ee_sum[i].esum += fr->ener[i].esum; } } nsteps += fr->nsteps; - nsum += fr_nsum; + nsum += fr_nsum; } else { @@ -421,9 +426,9 @@ static void update_ee_sum(int nre, *ee_sum_nsum = nsum; } -int gmx_eneconv(int argc, char *argv[]) +int gmx_eneconv(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "With [IT]multiple files[it] specified for the [TT]-f[tt] option:[PAR]", "Concatenates several energy files in sorted order.", "In the case of double time frames, the one", @@ -440,73 +445,67 @@ int gmx_eneconv(int argc, char *argv[]) "[TT]-settime[tt] is applied first, then [TT]-dt[tt]/[TT]-offset[tt]", "followed by [TT]-b[tt] and [TT]-e[tt] to select which frames to write." }; - const char *bugs[] = { - "When combining trajectories the sigma and E^2 (necessary for statistics) are not updated correctly. Only the actual energy is correct. One thus has to compute statistics in another way." + const char* bugs[] = { + "When combining trajectories the sigma and E^2 (necessary for statistics) are not " + "updated correctly. Only the actual energy is correct. One thus has to compute " + "statistics in another way." }; - ener_file_t in = nullptr, out = nullptr; - gmx_enxnm_t *enm = nullptr; + ener_file_t in = nullptr, out = nullptr; + gmx_enxnm_t* enm = nullptr; #if 0 ener_file_t in, out = NULL; gmx_enxnm_t *enm = NULL; #endif - t_enxframe *fr, *fro; + t_enxframe * fr, *fro; int64_t ee_sum_step = 0, ee_sum_nsteps, ee_sum_nsum; - t_energy *ee_sum; + t_energy* ee_sum; int64_t lastfilestep, laststep, startstep_file = 0; int noutfr; int nre, nremax, this_nre, i, kkk, nset, *set = nullptr; double last_t; - real *readtime, *settime, timestep, tadjust; + real * readtime, *settime, timestep, tadjust; char buf[22], buf2[22]; - int *cont_type; + int* cont_type; gmx_bool bNewFile, bFirst, bNewOutput; - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; gmx_bool warned_about_dh = FALSE; - t_enxblock *blocks = nullptr; + t_enxblock* blocks = nullptr; int nblocks = 0; int nblocks_alloc = 0; - t_filenm fnm[] = { - { efEDR, "-f", nullptr, ffRDMULT }, - { efEDR, "-o", "fixed", ffWRITE }, + t_filenm fnm[] = { + { efEDR, "-f", nullptr, ffRDMULT }, + { efEDR, "-o", "fixed", ffWRITE }, }; #define NFILE asize(fnm) - gmx_bool bWrite; - static real delta_t = 0.0, toffset = 0, scalefac = 1; - static gmx_bool bSetTime = FALSE; - static gmx_bool bSort = TRUE, bError = TRUE; - static real begin = -1; - static real end = -1; - gmx_bool remove_dh = FALSE; - - t_pargs pa[] = { - { "-b", FALSE, etREAL, {&begin}, - "First time to use"}, - { "-e", FALSE, etREAL, {&end}, - "Last time to use"}, - { "-dt", FALSE, etREAL, {&delta_t}, - "Only write out frame when t MOD dt = offset" }, - { "-offset", FALSE, etREAL, {&toffset}, - "Time offset for [TT]-dt[tt] option" }, - { "-settime", FALSE, etBOOL, {&bSetTime}, - "Change starting time interactively" }, - { "-sort", FALSE, etBOOL, {&bSort}, - "Sort energy files (not frames)"}, - { "-rmdh", FALSE, etBOOL, {&remove_dh}, - "Remove free energy block data" }, - { "-scalefac", FALSE, etREAL, {&scalefac}, - "Multiply energy component by this factor" }, - { "-error", FALSE, etBOOL, {&bError}, - "Stop on errors in the file" } + gmx_bool bWrite; + static real delta_t = 0.0, toffset = 0, scalefac = 1; + static gmx_bool bSetTime = FALSE; + static gmx_bool bSort = TRUE, bError = TRUE; + static real begin = -1; + static real end = -1; + gmx_bool remove_dh = FALSE; + + t_pargs pa[] = { + { "-b", FALSE, etREAL, { &begin }, "First time to use" }, + { "-e", FALSE, etREAL, { &end }, "Last time to use" }, + { "-dt", FALSE, etREAL, { &delta_t }, "Only write out frame when t MOD dt = offset" }, + { "-offset", FALSE, etREAL, { &toffset }, "Time offset for [TT]-dt[tt] option" }, + { "-settime", FALSE, etBOOL, { &bSetTime }, "Change starting time interactively" }, + { "-sort", FALSE, etBOOL, { &bSort }, "Sort energy files (not frames)" }, + { "-rmdh", FALSE, etBOOL, { &remove_dh }, "Remove free energy block data" }, + { "-scalefac", FALSE, etREAL, { &scalefac }, "Multiply energy component by this factor" }, + { "-error", FALSE, etBOOL, { &bError }, "Stop on errors in the file" } }; - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), - pa, asize(desc), desc, asize(bugs), bugs, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, + asize(bugs), bugs, &oenv)) { return 0; } - fprintf(stdout, "Note that major changes are planned in future for " + fprintf(stdout, + "Note that major changes are planned in future for " "eneconv, to improve usability and utility."); tadjust = 0; @@ -564,17 +563,16 @@ int gmx_eneconv(int argc, char *argv[]) } /* start reading from the next file */ - while ((fro->t <= (settime[f+1] + GMX_REAL_EPS)) && - do_enx(in, fr)) + while ((fro->t <= (settime[f + 1] + GMX_REAL_EPS)) && do_enx(in, fr)) { if (bNewFile) { startstep_file = fr->step; tadjust = settime[f] - fr->t; - if (cont_type[f+1] == TIME_LAST) + if (cont_type[f + 1] == TIME_LAST) { - settime[f+1] = readtime[f+1]-readtime[f]+settime[f]; - cont_type[f+1] = TIME_EXPLICIT; + settime[f + 1] = readtime[f + 1] - readtime[f] + settime[f]; + cont_type[f + 1] = TIME_EXPLICIT; } bNewFile = FALSE; } @@ -584,48 +582,44 @@ int gmx_eneconv(int argc, char *argv[]) /* Skip this frame, since we already have it / past it */ if (debug) { - fprintf(debug, "fr->step %s, fr->t %.4f\n", - gmx_step_str(fr->step, buf), fr->t); - fprintf(debug, "tadjust %12.6e + fr->t %12.6e <= t %12.6e\n", - tadjust, fr->t, last_t); + fprintf(debug, "fr->step %s, fr->t %.4f\n", gmx_step_str(fr->step, buf), fr->t); + fprintf(debug, "tadjust %12.6e + fr->t %12.6e <= t %12.6e\n", tadjust, fr->t, last_t); } continue; } fro->step = lastfilestep + fr->step - startstep_file; - fro->t = tadjust + fr->t; + fro->t = tadjust + fr->t; - bWrite = ((begin < 0 || (fro->t >= begin-GMX_REAL_EPS)) && - (end < 0 || (fro->t <= end +GMX_REAL_EPS)) && - (fro->t <= settime[f+1]+0.5*timestep)); + bWrite = ((begin < 0 || (fro->t >= begin - GMX_REAL_EPS)) + && (end < 0 || (fro->t <= end + GMX_REAL_EPS)) + && (fro->t <= settime[f + 1] + 0.5 * timestep)); if (debug) { - fprintf(debug, - "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n", - gmx_step_str(fr->step, buf), fr->t, - gmx_step_str(fro->step, buf2), fro->t, gmx::boolToString(bWrite)); + fprintf(debug, "fr->step %s, fr->t %.4f, fro->step %s fro->t %.4f, w %s\n", + gmx_step_str(fr->step, buf), fr->t, gmx_step_str(fro->step, buf2), fro->t, + gmx::boolToString(bWrite)); } if (bError) { - if ((end > 0) && (fro->t > end+GMX_REAL_EPS)) + if ((end > 0) && (fro->t > end + GMX_REAL_EPS)) { f = files.size(); break; } } - if (fro->t >= begin-GMX_REAL_EPS) + if (fro->t >= begin - GMX_REAL_EPS) { if (bFirst) { - bFirst = FALSE; + bFirst = FALSE; } if (bWrite) { - update_ee_sum(nre, &ee_sum_step, &ee_sum_nsteps, &ee_sum_nsum, ee_sum, - fr, fro->step); + update_ee_sum(nre, &ee_sum_step, &ee_sum_nsteps, &ee_sum_nsum, ee_sum, fr, fro->step); } } @@ -637,8 +631,8 @@ int gmx_eneconv(int argc, char *argv[]) if (bNewOutput) { bNewOutput = FALSE; - fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n", - fro->t, gmx_step_str(fro->step, buf)); + fprintf(stderr, "\nContinue writing frames from t=%g, step=%s\n", fro->t, + gmx_step_str(fro->step, buf)); } /* Copy the energies */ @@ -656,8 +650,7 @@ int gmx_eneconv(int argc, char *argv[]) } else { - fro->nsum = int64_to_int(ee_sum_nsum, - "energy average summation"); + fro->nsum = int64_to_int(ee_sum_nsum, "energy average summation"); /* Copy the energy sums */ for (i = 0; i < nre; i++) { @@ -673,10 +666,10 @@ int gmx_eneconv(int argc, char *argv[]) { for (kkk = 0; kkk < nset; kkk++) { - fro->ener[set[kkk]].e *= scalefac; + fro->ener[set[kkk]].e *= scalefac; if (fro->nsum > 0) { - fro->ener[set[kkk]].eav *= scalefac*scalefac; + fro->ener[set[kkk]].eav *= scalefac * scalefac; fro->ener[set[kkk]].esum *= scalefac; } } @@ -685,9 +678,9 @@ int gmx_eneconv(int argc, char *argv[]) /*fro->ndisre = fr->ndisre; fro->disre_rm3tav = fr->disre_rm3tav; fro->disre_rt = fr->disre_rt;*/ - fro->nblock = fr->nblock; + fro->nblock = fr->nblock; /*fro->nr = fr->nr;*/ - fro->block = fr->block; + fro->block = fr->block; /* check if we have blocks with delta_h data and are throwing away data */ @@ -706,9 +699,8 @@ int gmx_eneconv(int argc, char *argv[]) for (i = 0; i < fr->nblock; i++) { - if ( (fr->block[i].id != enxDHCOLL) && - (fr->block[i].id != enxDH) && - (fr->block[i].id != enxDHHIST) ) + if ((fr->block[i].id != enxDHCOLL) && (fr->block[i].id != enxDH) + && (fr->block[i].id != enxDHHIST)) { /* copy everything verbatim */ blocks[nblocks] = fr->block[i]; @@ -725,8 +717,7 @@ int gmx_eneconv(int argc, char *argv[]) { for (i = 0; i < fr->nblock; i++) { - if (fr->block[i].id == enxDH || - fr->block[i].id == enxDHHIST) + if (fr->block[i].id == enxDH || fr->block[i].id == enxDHHIST) { int size; if (fr->block[i].id == enxDH) @@ -739,12 +730,17 @@ int gmx_eneconv(int argc, char *argv[]) } if (size > 0) { - printf("\nWARNING: %s contains delta H blocks or histograms for which\n" - " some data is thrown away on a block-by-block basis, where each block\n" + printf("\nWARNING: %s contains delta H blocks or " + "histograms for which\n" + " some data is thrown away on a " + "block-by-block basis, where each block\n" " contains up to %d samples.\n" - " This is almost certainly not what you want.\n" - " Use the -rmdh option to throw all delta H samples away.\n" - " Use g_energy -odh option to extract these samples.\n", + " This is almost certainly not what you " + "want.\n" + " Use the -rmdh option to throw all delta H " + "samples away.\n" + " Use g_energy -odh option to extract these " + "samples.\n", files[f].c_str(), size); warned_about_dh = TRUE; break; @@ -767,27 +763,25 @@ int gmx_eneconv(int argc, char *argv[]) { f--; } - printf("\nLast step written from %s: t %g, step %s\n", - files[f].c_str(), last_t, gmx_step_str(laststep, buf)); + printf("\nLast step written from %s: t %g, step %s\n", files[f].c_str(), last_t, + gmx_step_str(laststep, buf)); lastfilestep = laststep; /* set the next time from the last in previous file */ - if (cont_type[f+1] == TIME_CONTINUE) + if (cont_type[f + 1] == TIME_CONTINUE) { - settime[f+1] = fro->t; + settime[f + 1] = fro->t; /* in this case we have already written the last frame of * previous file, so update begin to avoid doubling it * with the start of the next file */ - begin = fro->t+0.5*timestep; + begin = fro->t + 0.5 * timestep; /* cont_type[f+1]==TIME_EXPLICIT; */ } - if ((fro->t < end) && (f < files.size() - 1) && - (fro->t < settime[f+1]-1.5*timestep)) + if ((fro->t < end) && (f < files.size() - 1) && (fro->t < settime[f + 1] - 1.5 * timestep)) { - fprintf(stderr, - "\nWARNING: There might be a gap around t=%g\n", fro->t); + fprintf(stderr, "\nWARNING: There might be a gap around t=%g\n", fro->t); } /* move energies to lastee */ diff --git a/src/gromacs/tools/eneconv.h b/src/gromacs/tools/eneconv.h index b0cbb9749d..5c9045dbc4 100644 --- a/src/gromacs/tools/eneconv.h +++ b/src/gromacs/tools/eneconv.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_eneconv(int argc, char *argv[]); +int gmx_eneconv(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/make_ndx.cpp b/src/gromacs/tools/make_ndx.cpp index a97fb81ece..e2e6b15083 100644 --- a/src/gromacs/tools/make_ndx.cpp +++ b/src/gromacs/tools/make_ndx.cpp @@ -63,10 +63,9 @@ #define NAME_LEN 1024 static const int NOTSET = -92637; -static gmx_bool bCase = FALSE; +static gmx_bool bCase = FALSE; -static int or_groups(int nr1, const int *at1, int nr2, const int *at2, - int *nr, int *at) +static int or_groups(int nr1, const int* at1, int nr2, const int* at2, int* nr, int* at) { int i1, i2, max = 0; gmx_bool bNotIncr; @@ -125,8 +124,7 @@ static int or_groups(int nr1, const int *at1, int nr2, const int *at2, return *nr; } -static int and_groups(int nr1, const int *at1, int nr2, const int *at2, - int *nr, int *at) +static int and_groups(int nr1, const int* at1, int nr2, const int* at2, int* nr, int* at) { int i1, i2; @@ -153,12 +151,12 @@ static gmx_bool is_name_char(char c) /* This string should contain all characters that can not be * the first letter of a name due to the make_ndx syntax. */ - const char *spec = " !&|"; + const char* spec = " !&|"; return (c != '\0' && std::strchr(spec, c) == nullptr); } -static int parse_names(char **string, int *n_names, char **names) +static int parse_names(char** string, int* n_names, char** names) { int i; @@ -169,7 +167,7 @@ static int parse_names(char **string, int *n_names, char **names) { if (*n_names >= MAXNAMES) { - gmx_fatal(FARGS, "To many names: %d\n", *n_names+1); + gmx_fatal(FARGS, "To many names: %d\n", *n_names + 1); } i = 0; while (is_name_char((*string)[i])) @@ -199,9 +197,9 @@ static int parse_names(char **string, int *n_names, char **names) return *n_names; } -static gmx_bool parse_int_char(char **string, int *nr, char *c) +static gmx_bool parse_int_char(char** string, int* nr, char* c) { - char *orig; + char* orig; gmx_bool bRet; orig = *string; @@ -217,11 +215,11 @@ static gmx_bool parse_int_char(char **string, int *nr, char *c) if (std::isdigit((*string)[0])) { - *nr = (*string)[0]-'0'; + *nr = (*string)[0] - '0'; (*string)++; while (std::isdigit((*string)[0])) { - *nr = (*nr)*10+(*string)[0]-'0'; + *nr = (*nr) * 10 + (*string)[0] - '0'; (*string)++; } if (std::isalpha((*string)[0])) @@ -247,9 +245,9 @@ static gmx_bool parse_int_char(char **string, int *nr, char *c) return bRet; } -static gmx_bool parse_int(char **string, int *nr) +static gmx_bool parse_int(char** string, int* nr) { - char *orig, c; + char * orig, c; gmx_bool bRet; orig = *string; @@ -268,7 +266,7 @@ static gmx_bool isquote(char c) return (c == '\"'); } -static gmx_bool parse_string(char **string, int *nr, int ngrps, char **grpname) +static gmx_bool parse_string(char** string, int* nr, int ngrps, char** grpname) { char *s, *sp; char c; @@ -287,20 +285,19 @@ static gmx_bool parse_string(char **string, int *nr, int ngrps, char **grpname) sp = std::strchr(s, c); if (sp != nullptr) { - (*string) += sp-s + 1; - sp[0] = '\0'; - (*nr) = find_group(s, ngrps, grpname); + (*string) += sp - s + 1; + sp[0] = '\0'; + (*nr) = find_group(s, ngrps, grpname); } } return (*nr) != NOTSET; } -static int select_atomnumbers(char **string, const t_atoms *atoms, int n1, - int *nr, int *index, char *gname) +static int select_atomnumbers(char** string, const t_atoms* atoms, int n1, int* nr, int* index, char* gname) { - char buf[STRLEN]; - int i, up; + char buf[STRLEN]; + int i, up; *nr = 0; while ((*string)[0] == ' ') @@ -317,7 +314,7 @@ static int select_atomnumbers(char **string, const t_atoms *atoms, int n1, } else { - for (i = n1-1; i <= up-1; i++) + for (i = n1 - 1; i <= up - 1; i++) { index[*nr] = i; (*nr)++; @@ -340,9 +337,9 @@ static int select_atomnumbers(char **string, const t_atoms *atoms, int n1, sprintf(gname, "a"); do { - if ((i-1 >= 0) && (i-1 < atoms->nr)) + if ((i - 1 >= 0) && (i - 1 < atoms->nr)) { - index[*nr] = i-1; + index[*nr] = i - 1; (*nr)++; sprintf(buf, "_%d", i); std::strcat(gname, buf); @@ -352,20 +349,17 @@ static int select_atomnumbers(char **string, const t_atoms *atoms, int n1, printf("Invalid atom number %d\n", i); *nr = 0; } - } - while ((*nr != 0) && (parse_int(string, &i))); + } while ((*nr != 0) && (parse_int(string, &i))); } return *nr; } -static int select_residuenumbers(char **string, const t_atoms *atoms, - int n1, char c, - int *nr, int *index, char *gname) +static int select_residuenumbers(char** string, const t_atoms* atoms, int n1, char c, int* nr, int* index, char* gname) { char buf[STRLEN]; int i, j, up; - t_resinfo *ri; + t_resinfo* ri; *nr = 0; while ((*string)[0] == ' ') @@ -395,8 +389,7 @@ static int select_residuenumbers(char **string, const t_atoms *atoms, } } } - printf("Found %d atom%s with res.nr. in range %d-%d\n", - *nr, (*nr == 1) ? "" : "s", n1, up); + printf("Found %d atom%s with res.nr. in range %d-%d\n", *nr, (*nr == 1) ? "" : "s", n1, up); if (n1 == up) { sprintf(buf, "r_%d", n1); @@ -425,22 +418,19 @@ static int select_residuenumbers(char **string, const t_atoms *atoms, } sprintf(buf, "_%d", j); std::strcat(gname, buf); - } - while (parse_int_char(string, &j, &c)); + } while (parse_int_char(string, &j, &c)); } return *nr; } -static int select_residueindices(char **string, const t_atoms *atoms, - int n1, char c, - int *nr, int *index, char *gname) +static int select_residueindices(char** string, const t_atoms* atoms, int n1, char c, int* nr, int* index, char* gname) { /*this should be similar to select_residuenumbers except select by index (sequential numbering in file)*/ /*resind+1 for 1-indexing*/ char buf[STRLEN]; int i, j, up; - t_resinfo *ri; + t_resinfo* ri; *nr = 0; while ((*string)[0] == ' ') @@ -463,15 +453,14 @@ static int select_residueindices(char **string, const t_atoms *atoms, ri = &atoms->resinfo[atoms->atom[i].resind]; for (j = n1; (j <= up); j++) { - if (atoms->atom[i].resind+1 == j && (c == ' ' || ri->ic == c)) + if (atoms->atom[i].resind + 1 == j && (c == ' ' || ri->ic == c)) { index[*nr] = i; (*nr)++; } } } - printf("Found %d atom%s with resind.+1 in range %d-%d\n", - *nr, (*nr == 1) ? "" : "s", n1, up); + printf("Found %d atom%s with resind.+1 in range %d-%d\n", *nr, (*nr == 1) ? "" : "s", n1, up); if (n1 == up) { sprintf(buf, "r_%d", n1); @@ -492,7 +481,7 @@ static int select_residueindices(char **string, const t_atoms *atoms, for (i = 0; i < atoms->nr; i++) { ri = &atoms->resinfo[atoms->atom[i].resind]; - if (atoms->atom[i].resind+1 == j && ri->ic == c) + if (atoms->atom[i].resind + 1 == j && ri->ic == c) { index[*nr] = i; (*nr)++; @@ -500,28 +489,26 @@ static int select_residueindices(char **string, const t_atoms *atoms, } sprintf(buf, "_%d", j); std::strcat(gname, buf); - } - while (parse_int_char(string, &j, &c)); + } while (parse_int_char(string, &j, &c)); } return *nr; } -static gmx_bool atoms_from_residuenumbers(const t_atoms *atoms, int group, t_blocka *block, - int *nr, int *index, char *gname) +static gmx_bool +atoms_from_residuenumbers(const t_atoms* atoms, int group, t_blocka* block, int* nr, int* index, char* gname) { int i, j, j0, j1, resnr, nres; j0 = block->index[group]; - j1 = block->index[group+1]; + j1 = block->index[group + 1]; nres = atoms->nres; for (j = j0; j < j1; j++) { if (block->a[j] >= nres) { - printf("Index %s contains number>nres (%d>%d)\n", - gname, block->a[j]+1, nres); + printf("Index %s contains number>nres (%d>%d)\n", gname, block->a[j] + 1, nres); return FALSE; } } @@ -530,7 +517,7 @@ static gmx_bool atoms_from_residuenumbers(const t_atoms *atoms, int group, t_blo resnr = atoms->resinfo[atoms->atom[i].resind].nr; for (j = j0; j < j1; j++) { - if (block->a[j]+1 == resnr) + if (block->a[j] + 1 == resnr) { index[*nr] = i; (*nr)++; @@ -538,12 +525,11 @@ static gmx_bool atoms_from_residuenumbers(const t_atoms *atoms, int group, t_blo } } } - printf("Found %d atom%s in %d residues from group %s\n", - *nr, (*nr == 1) ? "" : "s", j1-j0, gname); + printf("Found %d atom%s in %d residues from group %s\n", *nr, (*nr == 1) ? "" : "s", j1 - j0, gname); return *nr != 0; } -static gmx_bool comp_name(const char *name, const char *search) +static gmx_bool comp_name(const char* name, const char* search) { gmx_bool matches = TRUE; @@ -557,13 +543,13 @@ static gmx_bool comp_name(const char *name, const char *search) } else if (*search == '*') { - if (*(search+1)) + if (*(search + 1)) { printf("WARNING: Currently '*' is only supported at the end of an expression\n"); } // if * is the last char in search string, we have a match, // otherwise we just failed. Return in either case, we're done. - return (*(search+1) == '\0'); + return (*(search + 1) == '\0'); } // Compare one character @@ -582,12 +568,11 @@ static gmx_bool comp_name(const char *name, const char *search) return matches; } -static int select_chainnames(const t_atoms *atoms, int n_names, char **names, - int *nr, int *index) +static int select_chainnames(const t_atoms* atoms, int n_names, char** names, int* nr, int* index) { - char name[2]; - int j; - int i; + char name[2]; + int j; + int i; name[1] = 0; *nr = 0; @@ -605,8 +590,7 @@ static int select_chainnames(const t_atoms *atoms, int n_names, char **names, (*nr)++; } } - printf("Found %d atom%s with chain identifier%s", - *nr, (*nr == 1) ? "" : "s", (n_names == 1) ? "" : "s"); + printf("Found %d atom%s with chain identifier%s", *nr, (*nr == 1) ? "" : "s", (n_names == 1) ? "" : "s"); for (j = 0; (j < n_names); j++) { printf(" %s", names[j]); @@ -616,12 +600,11 @@ static int select_chainnames(const t_atoms *atoms, int n_names, char **names, return *nr; } -static int select_atomnames(const t_atoms *atoms, int n_names, char **names, - int *nr, int *index, gmx_bool bType) +static int select_atomnames(const t_atoms* atoms, int n_names, char** names, int* nr, int* index, gmx_bool bType) { - char *name; - int j; - int i; + char* name; + int j; + int i; *nr = 0; for (i = 0; i < atoms->nr; i++) @@ -645,8 +628,7 @@ static int select_atomnames(const t_atoms *atoms, int n_names, char **names, (*nr)++; } } - printf("Found %d atoms with %s%s", - *nr, bType ? "type" : "name", (n_names == 1) ? "" : "s"); + printf("Found %d atoms with %s%s", *nr, bType ? "type" : "name", (n_names == 1) ? "" : "s"); for (j = 0; (j < n_names); j++) { printf(" %s", names[j]); @@ -656,12 +638,11 @@ static int select_atomnames(const t_atoms *atoms, int n_names, char **names, return *nr; } -static int select_residuenames(const t_atoms *atoms, int n_names, char **names, - int *nr, int *index) +static int select_residuenames(const t_atoms* atoms, int n_names, char** names, int* nr, int* index) { - char *name; - int j; - int i; + char* name; + int j; + int i; *nr = 0; for (i = 0; i < atoms->nr; i++) @@ -688,23 +669,23 @@ static int select_residuenames(const t_atoms *atoms, int n_names, char **names, return *nr; } -static void copy2block(int n, const int *index, t_blocka *block) +static void copy2block(int n, const int* index, t_blocka* block) { int i, n0; block->nr++; n0 = block->nra; - block->nra = n0+n; - srenew(block->index, block->nr+1); - block->index[block->nr] = n0+n; - srenew(block->a, n0+n); + block->nra = n0 + n; + srenew(block->index, block->nr + 1); + block->index[block->nr] = n0 + n; + srenew(block->a, n0 + n); for (i = 0; (i < n); i++) { - block->a[n0+i] = index[i]; + block->a[n0 + i] = index[i]; } } -static void make_gname(int n, char **names, char *gname) +static void make_gname(int n, char** names, char* gname) { int i; @@ -716,96 +697,94 @@ static void make_gname(int n, char **names, char *gname) } } -static void copy_group(int g, t_blocka *block, int *nr, int *index) +static void copy_group(int g, t_blocka* block, int* nr, int* index) { int i, i0; i0 = block->index[g]; - *nr = block->index[g+1]-i0; + *nr = block->index[g + 1] - i0; for (i = 0; i < *nr; i++) { - index[i] = block->a[i0+i]; + index[i] = block->a[i0 + i]; } } -static void remove_group(int nr, int nr2, t_blocka *block, char ***gn) +static void remove_group(int nr, int nr2, t_blocka* block, char*** gn) { int i, j, shift; - char *name; + char* name; if (nr2 == NOTSET) { nr2 = nr; } - for (j = 0; j <= nr2-nr; j++) + for (j = 0; j <= nr2 - nr; j++) { if ((nr < 0) || (nr >= block->nr)) { - printf("Group %d does not exist\n", nr+j); + printf("Group %d does not exist\n", nr + j); } else { - shift = block->index[nr+1]-block->index[nr]; - for (i = block->index[nr+1]; i < block->nra; i++) + shift = block->index[nr + 1] - block->index[nr]; + for (i = block->index[nr + 1]; i < block->nra; i++) { - block->a[i-shift] = block->a[i]; + block->a[i - shift] = block->a[i]; } for (i = nr; i < block->nr; i++) { - block->index[i] = block->index[i+1]-shift; + block->index[i] = block->index[i + 1] - shift; } name = gmx_strdup((*gn)[nr]); sfree((*gn)[nr]); - for (i = nr; i < block->nr-1; i++) + for (i = nr; i < block->nr - 1; i++) { - (*gn)[i] = (*gn)[i+1]; + (*gn)[i] = (*gn)[i + 1]; } block->nr--; block->nra = block->index[block->nr]; - printf("Removed group %d '%s'\n", nr+j, name); + printf("Removed group %d '%s'\n", nr + j, name); sfree(name); } } } -static void split_group(const t_atoms *atoms, int sel_nr, t_blocka *block, char ***gn, - gmx_bool bAtom) +static void split_group(const t_atoms* atoms, int sel_nr, t_blocka* block, char*** gn, gmx_bool bAtom) { - char buf[STRLEN], *name; - int i, resind; - int a, n0, n1; + char buf[STRLEN], *name; + int i, resind; + int a, n0, n1; - printf("Splitting group %d '%s' into %s\n", sel_nr, (*gn)[sel_nr], - bAtom ? "atoms" : "residues"); + printf("Splitting group %d '%s' into %s\n", sel_nr, (*gn)[sel_nr], bAtom ? "atoms" : "residues"); n0 = block->index[sel_nr]; - n1 = block->index[sel_nr+1]; - srenew(block->a, block->nra+n1-n0); + n1 = block->index[sel_nr + 1]; + srenew(block->a, block->nra + n1 - n0); for (i = n0; i < n1; i++) { a = block->a[i]; resind = atoms->atom[a].resind; name = *(atoms->resinfo[resind].name); - if (bAtom || (i == n0) || (atoms->atom[block->a[i-1]].resind != resind)) + if (bAtom || (i == n0) || (atoms->atom[block->a[i - 1]].resind != resind)) { if (i > n0) { block->index[block->nr] = block->nra; } block->nr++; - srenew(block->index, block->nr+1); + srenew(block->index, block->nr + 1); srenew(*gn, block->nr); if (bAtom) { - sprintf(buf, "%s_%s_%d", (*gn)[sel_nr], *atoms->atomname[a], a+1); + sprintf(buf, "%s_%s_%d", (*gn)[sel_nr], *atoms->atomname[a], a + 1); } else { sprintf(buf, "%s_%s_%d", (*gn)[sel_nr], name, atoms->resinfo[resind].nr); } - (*gn)[block->nr-1] = gmx_strdup(buf); + (*gn)[block->nr - 1] = gmx_strdup(buf); } block->a[block->nra] = a; block->nra++; @@ -813,13 +792,12 @@ static void split_group(const t_atoms *atoms, int sel_nr, t_blocka *block, char block->index[block->nr] = block->nra; } -static int split_chain(const t_atoms *atoms, const rvec *x, - int sel_nr, t_blocka *block, char ***gn) +static int split_chain(const t_atoms* atoms, const rvec* x, int sel_nr, t_blocka* block, char*** gn) { - char buf[STRLEN]; - int j, nchain; - int i, a, natoms, *start = nullptr, *end = nullptr, ca_start, ca_end; - rvec vec; + char buf[STRLEN]; + int j, nchain; + int i, a, natoms, *start = nullptr, *end = nullptr, ca_start, ca_end; + rvec vec; natoms = atoms->nr; nchain = 0; @@ -833,12 +811,11 @@ static int split_chain(const t_atoms *atoms, const rvec *x, } if (ca_start < natoms) { - srenew(start, nchain+1); - srenew(end, nchain+1); + srenew(start, nchain + 1); + srenew(end, nchain + 1); start[nchain] = ca_start; - while ((start[nchain] > 0) && - (atoms->atom[start[nchain]-1].resind == - atoms->atom[ca_start].resind)) + while ((start[nchain] > 0) + && (atoms->atom[start[nchain] - 1].resind == atoms->atom[ca_start].resind)) { start[nchain]--; } @@ -850,8 +827,7 @@ static int split_chain(const t_atoms *atoms, const rvec *x, do { i++; - } - while ((i < natoms) && std::strcmp(*atoms->atomname[i], "CA") != 0); + } while ((i < natoms) && std::strcmp(*atoms->atomname[i], "CA") != 0); if (i < natoms) { rvec_sub(x[ca_end], x[i], vec); @@ -860,16 +836,15 @@ static int split_chain(const t_atoms *atoms, const rvec *x, { break; } - } - while (norm(vec) < 0.45); + } while (norm(vec) < 0.45); end[nchain] = ca_end; - while ((end[nchain]+1 < natoms) && - (atoms->atom[end[nchain]+1].resind == atoms->atom[ca_end].resind)) + while ((end[nchain] + 1 < natoms) + && (atoms->atom[end[nchain] + 1].resind == atoms->atom[ca_end].resind)) { end[nchain]++; } - ca_start = end[nchain]+1; + ca_start = end[nchain] + 1; nchain++; } } @@ -883,21 +858,20 @@ static int split_chain(const t_atoms *atoms, const rvec *x, } for (j = 0; j < nchain; j++) { - printf("%d:%6d atoms (%d to %d)\n", - j+1, end[j]-start[j]+1, start[j]+1, end[j]+1); + printf("%d:%6d atoms (%d to %d)\n", j + 1, end[j] - start[j] + 1, start[j] + 1, end[j] + 1); } if (nchain > 1) { - srenew(block->a, block->nra+block->index[sel_nr+1]-block->index[sel_nr]); + srenew(block->a, block->nra + block->index[sel_nr + 1] - block->index[sel_nr]); for (j = 0; j < nchain; j++) { block->nr++; - srenew(block->index, block->nr+1); + srenew(block->index, block->nr + 1); srenew(*gn, block->nr); - sprintf(buf, "%s_chain%d", (*gn)[sel_nr], j+1); - (*gn)[block->nr-1] = gmx_strdup(buf); - for (i = block->index[sel_nr]; i < block->index[sel_nr+1]; i++) + sprintf(buf, "%s_chain%d", (*gn)[sel_nr], j + 1); + (*gn)[block->nr - 1] = gmx_strdup(buf); + for (i = block->index[sel_nr]; i < block->index[sel_nr + 1]; i++) { a = block->a[i]; if ((a >= start[j]) && (a <= end[j])) @@ -907,9 +881,9 @@ static int split_chain(const t_atoms *atoms, const rvec *x, } } block->index[block->nr] = block->nra; - if (block->index[block->nr-1] == block->index[block->nr]) + if (block->index[block->nr - 1] == block->index[block->nr]) { - remove_group(block->nr-1, NOTSET, block, gn); + remove_group(block->nr - 1, NOTSET, block, gn); } } } @@ -919,7 +893,7 @@ static int split_chain(const t_atoms *atoms, const rvec *x, return nchain; } -static gmx_bool check_have_atoms(const t_atoms *atoms, char *string) +static gmx_bool check_have_atoms(const t_atoms* atoms, char* string) { if (atoms == nullptr) { @@ -932,11 +906,16 @@ static gmx_bool check_have_atoms(const t_atoms *atoms, char *string) } } -static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, - t_blocka *block, char ***gn, - int *nr, int *index, char *gname) +static gmx_bool parse_entry(char** string, + int natoms, + const t_atoms* atoms, + t_blocka* block, + char*** gn, + int* nr, + int* index, + char* gname) { - static char **names, *ostring; + static char ** names, *ostring; static gmx_bool bFirst = TRUE; int j, n_names, sel_nr1; int i, nr1, *index1; @@ -949,7 +928,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, snew(names, MAXNAMES); for (i = 0; i < MAXNAMES; i++) { - snew(names[i], NAME_LEN+1); + snew(names[i], NAME_LEN + 1); } } @@ -977,8 +956,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, ostring = *string; - if (parse_int(string, &sel_nr1) || - parse_string(string, &sel_nr1, block->nr, *gn)) + if (parse_int(string, &sel_nr1) || parse_string(string, &sel_nr1, block->nr, *gn)) { if ((sel_nr1 >= 0) && (sel_nr1 < block->nr)) { @@ -1011,8 +989,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, else if ((*string)[0] == 't') { (*string)++; - if (check_have_atoms(atoms, ostring) && - parse_names(string, &n_names, names)) + if (check_have_atoms(atoms, ostring) && parse_names(string, &n_names, names)) { if (!(atoms->haveType)) { @@ -1028,20 +1005,17 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, else if (std::strncmp(*string, "res", 3) == 0) { (*string) += 3; - if (check_have_atoms(atoms, ostring) && - parse_int(string, &sel_nr1) && - (sel_nr1 >= 0) && (sel_nr1 < block->nr) ) + if (check_have_atoms(atoms, ostring) && parse_int(string, &sel_nr1) && (sel_nr1 >= 0) + && (sel_nr1 < block->nr)) { - bRet = atoms_from_residuenumbers(atoms, - sel_nr1, block, nr, index, (*gn)[sel_nr1]); + bRet = atoms_from_residuenumbers(atoms, sel_nr1, block, nr, index, (*gn)[sel_nr1]); sprintf(gname, "atom_%s", (*gn)[sel_nr1]); } } else if (std::strncmp(*string, "ri", 2) == 0) { (*string) += 2; - if (check_have_atoms(atoms, ostring) && - parse_int_char(string, &sel_nr1, &c)) + if (check_have_atoms(atoms, ostring) && parse_int_char(string, &sel_nr1, &c)) { bRet = (select_residueindices(string, atoms, sel_nr1, c, nr, index, gname) != 0); } @@ -1065,8 +1039,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, else if (std::strncmp(*string, "chain", 5) == 0) { (*string) += 5; - if (check_have_atoms(atoms, ostring) && - parse_names(string, &n_names, names)) + if (check_have_atoms(atoms, ostring) && parse_names(string, &n_names, names)) { bRet = (select_chainnames(atoms, n_names, names, nr, index) != 0); sprintf(gname, "ch%s", names[0]); @@ -1078,7 +1051,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, } if (bRet && bCompl) { - snew(index1, natoms-*nr); + snew(index1, natoms - *nr); nr1 = 0; for (i = 0; i < natoms; i++) { @@ -1089,7 +1062,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, } if (j == *nr) { - if (nr1 >= natoms-*nr) + if (nr1 >= natoms - *nr) { printf("There are double atoms in your index group\n"); break; @@ -1105,9 +1078,9 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, } sfree(index1); - for (i = std::strlen(gname)+1; i > 0; i--) + for (i = std::strlen(gname) + 1; i > 0; i--) { - gname[i] = gname[i-1]; + gname[i] = gname[i - 1]; } gname[0] = '!'; printf("Complemented group: %d atoms\n", *nr); @@ -1116,7 +1089,7 @@ static gmx_bool parse_entry(char **string, int natoms, const t_atoms *atoms, return bRet; } -static void list_residues(const t_atoms *atoms) +static void list_residues(const t_atoms* atoms) { int i, j, start, end, prev_resind, resind; gmx_bool bDiff; @@ -1127,11 +1100,10 @@ static void list_residues(const t_atoms *atoms) for (i = 0; i < atoms->nr; i++) { resind = atoms->atom[i].resind; - if ((resind != prev_resind) || (i == atoms->nr-1)) + if ((resind != prev_resind) || (i == atoms->nr - 1)) { - if ((bDiff = (std::strcmp(*atoms->resinfo[resind].name, - *atoms->resinfo[start].name) != 0)) || - (i == atoms->nr-1)) + if ((bDiff = (std::strcmp(*atoms->resinfo[resind].name, *atoms->resinfo[start].name) != 0)) + || (i == atoms->nr - 1)) { if (bDiff) { @@ -1141,18 +1113,16 @@ static void list_residues(const t_atoms *atoms) { end = resind; } - if (end < start+3) + if (end < start + 3) { for (j = start; j <= end; j++) { - printf("%4d %-5s", - j+1, *(atoms->resinfo[j].name)); + printf("%4d %-5s", j + 1, *(atoms->resinfo[j].name)); } } else { - printf(" %4d - %4d %-5s ", - start+1, end+1, *(atoms->resinfo[start].name)); + printf(" %4d - %4d %-5s ", start + 1, end + 1, *(atoms->resinfo[start].name)); } start = resind; } @@ -1162,12 +1132,12 @@ static void list_residues(const t_atoms *atoms) printf("\n"); } -static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka *block, char ***gn, gmx_bool bVerbose) +static void edit_index(int natoms, const t_atoms* atoms, const rvec* x, t_blocka* block, char*** gn, gmx_bool bVerbose) { - static char **atnames, *ostring; + static char ** atnames, *ostring; static gmx_bool bFirst = TRUE; char inp_string[STRLEN], *string; - char gname[STRLEN*3], gname1[STRLEN], gname2[STRLEN]; + char gname[STRLEN * 3], gname1[STRLEN], gname2[STRLEN]; int i, i0, i1, sel_nr, sel_nr2, newgroup; int nr, nr1, nr2, *index, *index1, *index2; gmx_bool bAnd, bOr, bPrintOnce; @@ -1178,7 +1148,7 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka snew(atnames, MAXNAMES); for (i = 0; i < MAXNAMES; i++) { - snew(atnames[i], NAME_LEN+1); + snew(atnames[i], NAME_LEN + 1); } } @@ -1204,20 +1174,21 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka else { i0 = newgroup; - i1 = newgroup+1; + i1 = newgroup + 1; } for (i = i0; i < i1; i++) { - printf("%3d %-20s: %5d atoms\n", i, (*gn)[i], - block->index[i+1]-block->index[i]); + printf("%3d %-20s: %5d atoms\n", i, (*gn)[i], block->index[i + 1] - block->index[i]); } newgroup = NOTSET; } if (bVerbose || bPrintOnce) { printf("\n"); - printf(" nr : group '!': not 'name' nr name 'splitch' nr Enter: list groups\n"); - printf(" 'a': atom '&': and 'del' nr 'splitres' nr 'l': list residues\n"); + printf(" nr : group '!': not 'name' nr name 'splitch' nr Enter: list " + "groups\n"); + printf(" 'a': atom '&': and 'del' nr 'splitres' nr 'l': list " + "residues\n"); printf(" 't': atom type '|': or 'keep' nr 'splitat' nr 'h': help\n"); printf(" 'r': residue 'res' nr 'chain' char\n"); printf(" \"name\": group 'case': case %s 'q': save and quit\n", @@ -1231,7 +1202,7 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka { gmx_fatal(FARGS, "Error reading user input"); } - inp_string[std::strlen(inp_string)-1] = 0; + inp_string[std::strlen(inp_string) - 1] = 0; printf("\n"); string = inp_string; while (string[0] == ' ') @@ -1244,19 +1215,25 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka if (string[0] == 'h') { printf(" nr : selects an index group by number or quoted string.\n"); - printf(" The string is first matched against the whole group name,\n"); + printf(" The string is first matched against the whole group " + "name,\n"); printf(" then against the beginning and finally against an\n"); printf(" arbitrary substring. A multiple match is an error.\n"); printf(" 'a' nr1 [nr2 ...] : selects atoms, atom numbering starts at 1.\n"); printf(" 'a' nr1 - nr2 : selects atoms in the range from nr1 to nr2.\n"); - printf(" 'a' name1[*] [name2[*] ...] : selects atoms by name(s), '?' matches any char,\n"); + printf(" 'a' name1[*] [name2[*] ...] : selects atoms by name(s), '?' matches any " + "char,\n"); printf(" wildcard '*' allowed at the end of a name.\n"); - printf(" 't' type1[*] [type2[*] ...] : as 'a', but for type, run input file required.\n"); - printf(" 'r' nr1[ic1] [nr2[ic2] ...] : selects residues by number and insertion code.\n"); - printf(" 'r' nr1 - nr2 : selects residues in the range from nr1 to nr2.\n"); + printf(" 't' type1[*] [type2[*] ...] : as 'a', but for type, run input file " + "required.\n"); + printf(" 'r' nr1[ic1] [nr2[ic2] ...] : selects residues by number and insertion " + "code.\n"); + printf(" 'r' nr1 - nr2 : selects residues in the range from nr1 to " + "nr2.\n"); printf(" 'r' name1[*] [name2[*] ...] : as 'a', but for residue names.\n"); - printf(" 'ri' nr1 - nr2 : selects residue indices, 1-indexed, (as opposed to numbers) in the range from nr1 to nr2.\n"); + printf(" 'ri' nr1 - nr2 : selects residue indices, 1-indexed, (as opposed " + "to numbers) in the range from nr1 to nr2.\n"); printf(" 'chain' ch1 [ch2 ...] : selects atoms by chain identifier(s),\n"); printf(" not available with a .gro file as input.\n"); printf(" ! : takes the complement of a group with respect to all\n"); @@ -1264,7 +1241,8 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka printf(" & | : AND and OR, can be placed between any of the options\n"); printf(" above, the input is processed from left to right.\n"); printf(" 'name' nr name : rename group nr to name.\n"); - printf(" 'del' nr1 [- nr2] : deletes one group or groups in the range from nr1 to nr2.\n"); + printf(" 'del' nr1 [- nr2] : deletes one group or groups in the range from nr1 to " + "nr2.\n"); printf(" 'keep' nr : deletes all groups except nr.\n"); printf(" 'case' : make all name compares case (in)sensitive.\n"); printf(" 'splitch' nr : split group into chains using CA distances.\n"); @@ -1326,8 +1304,8 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka string += 4; if (parse_int(&string, &sel_nr)) { - remove_group(sel_nr+1, block->nr-1, block, gn); - remove_group(0, sel_nr-1, block, gn); + remove_group(sel_nr + 1, block->nr - 1, block, gn); + remove_group(0, sel_nr - 1, block, gn); } } else if (std::strncmp(string, "name", 4) == 0) @@ -1355,7 +1333,7 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka } else if (string[0] == 'l') { - if (check_have_atoms(atoms, ostring) ) + if (check_have_atoms(atoms, ostring)) { list_residues(atoms); } @@ -1363,9 +1341,8 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka else if (std::strncmp(string, "splitch", 7) == 0) { string += 7; - if (check_have_atoms(atoms, ostring) && - parse_int(&string, &sel_nr) && - (sel_nr >= 0) && (sel_nr < block->nr)) + if (check_have_atoms(atoms, ostring) && parse_int(&string, &sel_nr) && (sel_nr >= 0) + && (sel_nr < block->nr)) { split_chain(atoms, x, sel_nr, block, gn); } @@ -1373,9 +1350,8 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka else if (std::strncmp(string, "splitres", 8) == 0) { string += 8; - if (check_have_atoms(atoms, ostring) && - parse_int(&string, &sel_nr) && - (sel_nr >= 0) && (sel_nr < block->nr)) + if (check_have_atoms(atoms, ostring) && parse_int(&string, &sel_nr) && (sel_nr >= 0) + && (sel_nr < block->nr)) { split_group(atoms, sel_nr, block, gn, FALSE); } @@ -1383,9 +1359,8 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka else if (std::strncmp(string, "splitat", 7) == 0) { string += 7; - if (check_have_atoms(atoms, ostring) && - parse_int(&string, &sel_nr) && - (sel_nr >= 0) && (sel_nr < block->nr)) + if (check_have_atoms(atoms, ostring) && parse_int(&string, &sel_nr) && (sel_nr >= 0) + && (sel_nr < block->nr)) { split_group(atoms, sel_nr, block, gn, TRUE); } @@ -1440,8 +1415,7 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka } } } - } - while (bAnd || bOr); + } while (bAnd || bOr); } while (string[0] == ' ') { @@ -1455,7 +1429,7 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka { copy2block(nr, index, block); srenew(*gn, block->nr); - newgroup = block->nr-1; + newgroup = block->nr - 1; (*gn)[newgroup] = gmx_strdup(gname); } else @@ -1463,15 +1437,14 @@ static void edit_index(int natoms, const t_atoms *atoms, const rvec *x, t_blocka printf("Group is empty\n"); } } - } - while (string[0] != 'q'); + } while (string[0] != 'q'); sfree(index); sfree(index1); sfree(index2); } -static int block2natoms(t_blocka *block) +static int block2natoms(t_blocka* block) { int i, natoms; @@ -1485,103 +1458,100 @@ static int block2natoms(t_blocka *block) return natoms; } -static void merge_blocks(t_blocka *dest, t_blocka *source) +static void merge_blocks(t_blocka* dest, t_blocka* source) { - int i, nra0, i0; + int i, nra0, i0; /* count groups, srenew and fill */ - i0 = dest->nr; - nra0 = dest->nra; + i0 = dest->nr; + nra0 = dest->nra; dest->nr += source->nr; - srenew(dest->index, dest->nr+1); + srenew(dest->index, dest->nr + 1); for (i = 0; i < source->nr; i++) { - dest->index[i0+i] = nra0 + source->index[i]; + dest->index[i0 + i] = nra0 + source->index[i]; } /* count atoms, srenew and fill */ dest->nra += source->nra; srenew(dest->a, dest->nra); for (i = 0; i < source->nra; i++) { - dest->a[nra0+i] = source->a[i]; + dest->a[nra0 + i] = source->a[i]; } /* terminate list */ dest->index[dest->nr] = dest->nra; - } -int gmx_make_ndx(int argc, char *argv[]) +int gmx_make_ndx(int argc, char* argv[]) { - const char *desc[] = { - "Index groups are necessary for almost every GROMACS program.", - "All these programs can generate default index groups. You ONLY", - "have to use [THISMODULE] when you need SPECIAL index groups.", - "There is a default index group for the whole system, 9 default", - "index groups for proteins, and a default index group", - "is generated for every other residue name.", - "", - "When no index file is supplied, also [THISMODULE] will generate the", - "default groups.", - "With the index editor you can select on atom, residue and chain names", - "and numbers.", - "When a run input file is supplied you can also select on atom type.", - "You can use boolean operations, you can split groups", - "into chains, residues or atoms. You can delete and rename groups.", - "Type 'h' in the editor for more details.", - "", - "The atom numbering in the editor and the index file starts at 1.", - "", - "The [TT]-twin[tt] switch duplicates all index groups with an offset of", - "[TT]-natoms[tt], which is useful for Computational Electrophysiology", - "double-layer membrane setups.", - "", - "See also [gmx-select] [TT]-on[tt], which provides an alternative way", - "for constructing index groups. It covers nearly all of [THISMODULE]", - "functionality, and in many cases much more." - }; + const char* desc[] = { "Index groups are necessary for almost every GROMACS program.", + "All these programs can generate default index groups. You ONLY", + "have to use [THISMODULE] when you need SPECIAL index groups.", + "There is a default index group for the whole system, 9 default", + "index groups for proteins, and a default index group", + "is generated for every other residue name.", + "", + "When no index file is supplied, also [THISMODULE] will generate the", + "default groups.", + "With the index editor you can select on atom, residue and chain names", + "and numbers.", + "When a run input file is supplied you can also select on atom type.", + "You can use boolean operations, you can split groups", + "into chains, residues or atoms. You can delete and rename groups.", + "Type 'h' in the editor for more details.", + "", + "The atom numbering in the editor and the index file starts at 1.", + "", + "The [TT]-twin[tt] switch duplicates all index groups with an offset of", + "[TT]-natoms[tt], which is useful for Computational Electrophysiology", + "double-layer membrane setups.", + "", + "See also [gmx-select] [TT]-on[tt], which provides an alternative way", + "for constructing index groups. It covers nearly all of [THISMODULE]", + "functionality, and in many cases much more." }; static int natoms = 0; static gmx_bool bVerbose = FALSE; static gmx_bool bDuplicate = FALSE; - t_pargs pa[] = { - { "-natoms", FALSE, etINT, {&natoms}, - "set number of atoms (default: read from coordinate or index file)" }, - { "-twin", FALSE, etBOOL, {&bDuplicate}, - "Duplicate all index groups with an offset of -natoms" }, - { "-verbose", FALSE, etBOOL, {&bVerbose}, - "HIDDENVerbose output" } - }; + t_pargs pa[] = { { "-natoms", + FALSE, + etINT, + { &natoms }, + "set number of atoms (default: read from coordinate or index file)" }, + { "-twin", + FALSE, + etBOOL, + { &bDuplicate }, + "Duplicate all index groups with an offset of -natoms" }, + { "-verbose", FALSE, etBOOL, { &bVerbose }, "HIDDENVerbose output" } }; #define NPA asize(pa) - gmx_output_env_t *oenv; - const char *stxfile; - const char *ndxoutfile; + gmx_output_env_t* oenv; + const char* stxfile; + const char* ndxoutfile; gmx_bool bNatoms; int j; t_atoms atoms; - rvec *x, *v; + rvec * x, *v; int ePBC; matrix box; - t_blocka *block, *block2; - char **gnames, **gnames2; - t_filenm fnm[] = { - { efSTX, "-f", nullptr, ffOPTRD }, - { efNDX, "-n", nullptr, ffOPTRDMULT }, - { efNDX, "-o", nullptr, ffWRITE } - }; + t_blocka * block, *block2; + char ** gnames, **gnames2; + t_filenm fnm[] = { { efSTX, "-f", nullptr, ffOPTRD }, + { efNDX, "-n", nullptr, ffOPTRDMULT }, + { efNDX, "-o", nullptr, ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc, - 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - stxfile = ftp2fn_null(efSTX, NFILE, fnm); + stxfile = ftp2fn_null(efSTX, NFILE, fnm); gmx::ArrayRef ndxInFiles = opt2fnsIfOptionSet("-n", NFILE, fnm); - ndxoutfile = opt2fn("-o", NFILE, fnm); - bNatoms = opt2parg_bSet("-natoms", NPA, pa); + ndxoutfile = opt2fn("-o", NFILE, fnm); + bNatoms = opt2parg_bSet("-natoms", NPA, pa); if (!stxfile && ndxInFiles.empty()) { @@ -1593,8 +1563,7 @@ int gmx_make_ndx(int argc, char *argv[]) { bool haveFullTopology = false; fprintf(stderr, "\nReading structure file\n"); - readConfAndTopology(stxfile, &haveFullTopology, &mtop, - &ePBC, &x, &v, box); + readConfAndTopology(stxfile, &haveFullTopology, &mtop, &ePBC, &x, &v, box); atoms = gmx_mtop_global_atoms(&mtop); if (atoms.pdbinfo == nullptr) { @@ -1605,7 +1574,7 @@ int gmx_make_ndx(int argc, char *argv[]) } else { - x = nullptr; + x = nullptr; } /* read input file(s) */ @@ -1614,19 +1583,19 @@ int gmx_make_ndx(int argc, char *argv[]) printf("Going to read %td old index file(s)\n", ndxInFiles.ssize()); if (!ndxInFiles.empty()) { - for (const std::string &ndxInFile : ndxInFiles) + for (const std::string& ndxInFile : ndxInFiles) { block2 = init_index(ndxInFile.c_str(), &gnames2); - srenew(gnames, block->nr+block2->nr); + srenew(gnames, block->nr + block2->nr); for (j = 0; j < block2->nr; j++) { - gnames[block->nr+j] = gnames2[j]; + gnames[block->nr + j] = gnames2[j]; } sfree(gnames2); merge_blocks(block, block2); sfree(block2->a); sfree(block2->index); -/* done_block(block2); */ + /* done_block(block2); */ sfree(block2); } } diff --git a/src/gromacs/tools/make_ndx.h b/src/gromacs/tools/make_ndx.h index 7ae7c49a89..99cd2c865a 100644 --- a/src/gromacs/tools/make_ndx.h +++ b/src/gromacs/tools/make_ndx.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_make_ndx(int argc, char *argv[]); +int gmx_make_ndx(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/mk_angndx.cpp b/src/gromacs/tools/mk_angndx.cpp index cfa29e7d51..baa59f8bd9 100644 --- a/src/gromacs/tools/mk_angndx.cpp +++ b/src/gromacs/tools/mk_angndx.cpp @@ -51,9 +51,9 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" -static int calc_ntype(int nft, const int *ft, const t_idef *idef) +static int calc_ntype(int nft, const int* ft, const t_idef* idef) { - int i, f, nf = 0; + int i, f, nf = 0; for (i = 0; (i < idef->ntypes); i++) { @@ -69,8 +69,7 @@ static int calc_ntype(int nft, const int *ft, const t_idef *idef) return nf; } -static void fill_ft_ind(int nft, const int *ft, const t_idef *idef, - int ft_ind[], char *grpnames[]) +static void fill_ft_ind(int nft, const int* ft, const t_idef* idef, int ft_ind[], char* grpnames[]) { char buf[125]; int i, f, ftype, ind = 0; @@ -119,15 +118,15 @@ static void fill_ft_ind(int nft, const int *ft, const t_idef *idef, case F_RBDIHS: sprintf(buf, "RB-A1=%.2f", idef->iparams[i].rbdihs.rbcA[1]); break; - case F_RESTRANGLES: + case F_RESTRANGLES: sprintf(buf, "Theta=%.1f_%.2f", idef->iparams[i].harmonic.rA, idef->iparams[i].harmonic.krA); break; - case F_RESTRDIHS: + case F_RESTRDIHS: sprintf(buf, "Theta=%.1f_%.2f", idef->iparams[i].harmonic.rA, idef->iparams[i].harmonic.krA); break; - case F_CBTDIHS: + case F_CBTDIHS: sprintf(buf, "CBT-A1=%.2f", idef->iparams[i].cbtdihs.cbtcA[1]); break; @@ -142,15 +141,21 @@ static void fill_ft_ind(int nft, const int *ft, const t_idef *idef, } } -static void fill_ang(int nft, const int *ft, int fac, - int nr[], int *index[], const int ft_ind[], const t_topology *top, - gmx_bool bNoH, real hq) +static void fill_ang(int nft, + const int* ft, + int fac, + int nr[], + int* index[], + const int ft_ind[], + const t_topology* top, + gmx_bool bNoH, + real hq) { int f, ftype, i, j, indg, nr_fac; gmx_bool bUse; - const t_idef *idef; - t_atom *atom; - t_iatom *ia; + const t_idef* idef; + t_atom* atom; + t_iatom* ia; idef = &top->idef; @@ -160,7 +165,7 @@ static void fill_ang(int nft, const int *ft, int fac, { ftype = ft[f]; ia = idef->il[ftype].iatoms; - for (i = 0; (i < idef->il[ftype].nr); ) + for (i = 0; (i < idef->il[ftype].nr);) { indg = ft_ind[ia[0]]; if (indg == -1) @@ -172,7 +177,7 @@ static void fill_ang(int nft, const int *ft, int fac, { for (j = 0; j < fac; j++) { - if (atom[ia[1+j]].m < 1.5) + if (atom[ia[1 + j]].m < 1.5) { bUse = FALSE; } @@ -182,7 +187,7 @@ static void fill_ang(int nft, const int *ft, int fac, { for (j = 0; j < fac; j++) { - if (atom[ia[1+j]].m < 1.5 && std::abs(atom[ia[1+j]].q) < hq) + if (atom[ia[1 + j]].m < 1.5 && std::abs(atom[ia[1 + j]].q) < hq) { bUse = FALSE; } @@ -192,22 +197,22 @@ static void fill_ang(int nft, const int *ft, int fac, { if (nr[indg] % 1000 == 0) { - srenew(index[indg], fac*(nr[indg]+1000)); + srenew(index[indg], fac * (nr[indg] + 1000)); } - nr_fac = fac*nr[indg]; + nr_fac = fac * nr[indg]; for (j = 0; (j < fac); j++) { - index[indg][nr_fac+j] = ia[j+1]; + index[indg][nr_fac + j] = ia[j + 1]; } nr[indg]++; } - ia += interaction_function[ftype].nratoms+1; - i += interaction_function[ftype].nratoms+1; + ia += interaction_function[ftype].nratoms + 1; + i += interaction_function[ftype].nratoms + 1; } } } -static int *select_ftype(const char *opt, int *nft, int *mult) +static int* select_ftype(const char* opt, int* nft, int* mult) { int *ft = nullptr, ftype; @@ -216,12 +221,11 @@ static int *select_ftype(const char *opt, int *nft, int *mult) *mult = 3; for (ftype = 0; ftype < F_NRE; ftype++) { - if ((interaction_function[ftype].flags & IF_ATYPE) || - ftype == F_TABANGLES) + if ((interaction_function[ftype].flags & IF_ATYPE) || ftype == F_TABANGLES) { (*nft)++; srenew(ft, *nft); - ft[*nft-1] = ftype; + ft[*nft - 1] = ftype; } } } @@ -232,59 +236,49 @@ static int *select_ftype(const char *opt, int *nft, int *mult) snew(ft, *nft); switch (opt[0]) { - case 'd': - ft[0] = F_PDIHS; - break; - case 'i': - ft[0] = F_IDIHS; - break; - case 'r': - ft[0] = F_RBDIHS; - break; - default: - break; + case 'd': ft[0] = F_PDIHS; break; + case 'i': ft[0] = F_IDIHS; break; + case 'r': ft[0] = F_RBDIHS; break; + default: break; } } return ft; } -int gmx_mk_angndx(int argc, char *argv[]) +int gmx_mk_angndx(int argc, char* argv[]) { - static const char *desc[] = { + static const char* desc[] = { "[THISMODULE] makes an index file for calculation of", "angle distributions etc. It uses a run input file ([REF].tpx[ref]) for the", "definitions of the angles, dihedrals etc." }; - static const char *opt[] = { nullptr, "angle", "dihedral", "improper", "ryckaert-bellemans", nullptr }; + static const char* opt[] = { nullptr, "angle", "dihedral", "improper", "ryckaert-bellemans", + nullptr }; static gmx_bool bH = TRUE; static real hq = -1; - t_pargs pa[] = { - { "-type", FALSE, etENUM, {opt}, - "Type of angle" }, - { "-hyd", FALSE, etBOOL, {&bH}, - "Include angles with atoms with mass < 1.5" }, - { "-hq", FALSE, etREAL, {&hq}, - "Ignore angles with atoms with mass < 1.5 and magnitude of their charge less than this value" } - }; + t_pargs pa[] = { { "-type", FALSE, etENUM, { opt }, "Type of angle" }, + { "-hyd", FALSE, etBOOL, { &bH }, "Include angles with atoms with mass < 1.5" }, + { "-hq", + FALSE, + etREAL, + { &hq }, + "Ignore angles with atoms with mass < 1.5 and magnitude of their charge " + "less than this value" } }; - gmx_output_env_t *oenv; - FILE *out; - t_topology *top; - int i, j, ntype; - int nft = 0, *ft, mult = 0; - int **index; - int *ft_ind; - int *nr; - char **grpnames; - t_filenm fnm[] = { - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, "angle", ffWRITE } - }; + gmx_output_env_t* oenv; + FILE* out; + t_topology* top; + int i, j, ntype; + int nft = 0, *ft, mult = 0; + int** index; + int* ft_ind; + int* nr; + char** grpnames; + t_filenm fnm[] = { { efTPR, nullptr, nullptr, ffREAD }, { efNDX, nullptr, "angle", ffWRITE } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, - asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, 0, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } @@ -310,9 +304,9 @@ int gmx_mk_angndx(int argc, char *argv[]) if (nr[i] > 0) { fprintf(out, "[ %s ]\n", grpnames[i]); - for (j = 0; (j < nr[i]*mult); j++) + for (j = 0; (j < nr[i] * mult); j++) { - fprintf(out, " %5d", index[i][j]+1); + fprintf(out, " %5d", index[i][j] + 1); if ((j % 12) == 11) { fprintf(out, "\n"); diff --git a/src/gromacs/tools/mk_angndx.h b/src/gromacs/tools/mk_angndx.h index 86000dd685..e462fb7a3a 100644 --- a/src/gromacs/tools/mk_angndx.h +++ b/src/gromacs/tools/mk_angndx.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_mk_angndx(int argc, char *argv[]); +int gmx_mk_angndx(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/pme_error.cpp b/src/gromacs/tools/pme_error.cpp index 24f922a83b..26eef655ec 100644 --- a/src/gromacs/tools/pme_error.cpp +++ b/src/gromacs/tools/pme_error.cpp @@ -70,7 +70,8 @@ /* #define DEBUG */ /* Enum for situations that can occur during log file parsing */ -enum { +enum +{ eParselogOK, eParselogNotFound, eParselogNoPerfData, @@ -82,85 +83,85 @@ enum { typedef struct { - int64_t orig_sim_steps; /* Number of steps to be done in the real simulation */ - int n_entries; /* Number of entries in arrays */ - real volume; /* The volume of the box */ - matrix recipbox; /* The reciprocal box */ - int natoms; /* The number of atoms in the MD system */ - real *fac; /* The scaling factor */ - real *rcoulomb; /* The coulomb radii [0...nr_inputfiles] */ - real *rvdw; /* The vdW radii */ - int *nkx, *nky, *nkz; /* Number of k vectors in each spatial dimension */ - real *fourier_sp; /* Fourierspacing */ - real *ewald_rtol; /* Real space tolerance for Ewald, determines */ - /* the real/reciprocal space relative weight */ - real *ewald_beta; /* Splitting parameter [1/nm] */ - real fracself; /* fraction of particles for SI error */ - real q2all; /* sum ( q ^2 ) */ - real q2allnr; /* nr of charges */ - int *pme_order; /* Interpolation order for PME (bsplines) */ - char **fn_out; /* Name of the output tpr file */ - real *e_dir; /* Direct space part of PME error with these settings */ - real *e_rec; /* Reciprocal space part of PME error */ - gmx_bool bTUNE; /* flag for tuning */ + int64_t orig_sim_steps; /* Number of steps to be done in the real simulation */ + int n_entries; /* Number of entries in arrays */ + real volume; /* The volume of the box */ + matrix recipbox; /* The reciprocal box */ + int natoms; /* The number of atoms in the MD system */ + real* fac; /* The scaling factor */ + real* rcoulomb; /* The coulomb radii [0...nr_inputfiles] */ + real* rvdw; /* The vdW radii */ + int * nkx, *nky, *nkz; /* Number of k vectors in each spatial dimension */ + real* fourier_sp; /* Fourierspacing */ + real* ewald_rtol; /* Real space tolerance for Ewald, determines */ + /* the real/reciprocal space relative weight */ + real* ewald_beta; /* Splitting parameter [1/nm] */ + real fracself; /* fraction of particles for SI error */ + real q2all; /* sum ( q ^2 ) */ + real q2allnr; /* nr of charges */ + int* pme_order; /* Interpolation order for PME (bsplines) */ + char** fn_out; /* Name of the output tpr file */ + real* e_dir; /* Direct space part of PME error with these settings */ + real* e_rec; /* Reciprocal space part of PME error */ + gmx_bool bTUNE; /* flag for tuning */ } t_inputinfo; /* Returns TRUE when atom is charged */ static gmx_bool is_charge(real charge) { - return charge*charge > GMX_REAL_EPS; + return charge * charge > GMX_REAL_EPS; } /* calculate charge density */ -static void calc_q2all(const gmx_mtop_t *mtop, /* molecular topology */ - real *q2all, real *q2allnr) +static void calc_q2all(const gmx_mtop_t* mtop, /* molecular topology */ + real* q2all, + real* q2allnr) { - real q2_all = 0; /* Sum of squared charges */ - int nrq_mol; /* Number of charges in a single molecule */ - int nrq_all; /* Total number of charges in the MD system */ - real qi, q2_mol; + real q2_all = 0; /* Sum of squared charges */ + int nrq_mol; /* Number of charges in a single molecule */ + int nrq_all; /* Total number of charges in the MD system */ + real qi, q2_mol; #ifdef DEBUG fprintf(stderr, "\nCharge density:\n"); #endif - q2_all = 0.0; /* total q squared */ - nrq_all = 0; /* total number of charges in the system */ - for (const gmx_molblock_t &molblock : mtop->molblock) /* Loop over molecule types */ + q2_all = 0.0; /* total q squared */ + nrq_all = 0; /* total number of charges in the system */ + for (const gmx_molblock_t& molblock : mtop->molblock) /* Loop over molecule types */ { - q2_mol = 0.0; /* q squared value of this molecule */ - nrq_mol = 0; /* number of charges this molecule carries */ - const gmx_moltype_t &molecule = mtop->moltype[molblock.type]; + q2_mol = 0.0; /* q squared value of this molecule */ + nrq_mol = 0; /* number of charges this molecule carries */ + const gmx_moltype_t& molecule = mtop->moltype[molblock.type]; for (int i = 0; i < molecule.atoms.nr; i++) { qi = molecule.atoms.atom[i].q; /* Is this charge worth to be considered? */ if (is_charge(qi)) { - q2_mol += qi*qi; + q2_mol += qi * qi; nrq_mol++; } } /* Multiply with the number of molecules present of this type and add */ - q2_all += q2_mol*molblock.nmol; - nrq_all += nrq_mol*molblock.nmol; + q2_all += q2_mol * molblock.nmol; + nrq_all += nrq_mol * molblock.nmol; #ifdef DEBUG - fprintf(stderr, "Molecule %2d (%5d atoms) q2_mol=%10.3e nr.mol.charges=%5d (%6dx) q2_all=%10.3e tot.charges=%d\n", + fprintf(stderr, + "Molecule %2d (%5d atoms) q2_mol=%10.3e nr.mol.charges=%5d (%6dx) q2_all=%10.3e " + "tot.charges=%d\n", imol, molecule.atoms.nr, q2_mol, nrq_mol, molblock.nmol, q2_all, nrq_all); #endif } *q2all = q2_all; *q2allnr = nrq_all; - } /* Estimate the direct space part error of the SPME Ewald sum */ -static real estimate_direct( - t_inputinfo *info - ) +static real estimate_direct(t_inputinfo* info) { real e_dir = 0; /* Error estimate */ real beta = 0; /* Splitting parameter (1/nm) */ @@ -170,20 +171,19 @@ static real estimate_direct( beta = info->ewald_beta[0]; r_coulomb = info->rcoulomb[0]; - e_dir = 2.0 * info->q2all * gmx::invsqrt( info->q2allnr * r_coulomb * info->volume ); - e_dir *= std::exp (-beta*beta*r_coulomb*r_coulomb); + e_dir = 2.0 * info->q2all * gmx::invsqrt(info->q2allnr * r_coulomb * info->volume); + e_dir *= std::exp(-beta * beta * r_coulomb * r_coulomb); - return ONE_4PI_EPS0*e_dir; + return ONE_4PI_EPS0 * e_dir; } #define SUMORDER 6 /* the following 4 functions determine polynomials required for the reciprocal error estimate */ -static inline real eps_poly1( - real m, /* grid coordinate in certain direction */ - real K, /* grid size in corresponding direction */ - real n) /* spline interpolation order of the SPME */ +static inline real eps_poly1(real m, /* grid coordinate in certain direction */ + real K, /* grid size in corresponding direction */ + real n) /* spline interpolation order of the SPME */ { int i; real nom = 0; /* nominator */ @@ -197,30 +197,28 @@ static inline real eps_poly1( for (i = -SUMORDER; i < 0; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += std::pow( tmp, -n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += std::pow(tmp, -n); } for (i = SUMORDER; i > 0; i--) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += std::pow( tmp, -n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += std::pow(tmp, -n); } - tmp = m / K; - tmp *= 2.0*M_PI; - denom = std::pow( tmp, -n )+nom; - - return -nom/denom; + tmp = m / K; + tmp *= 2.0 * M_PI; + denom = std::pow(tmp, -n) + nom; + return -nom / denom; } -static inline real eps_poly2( - real m, /* grid coordinate in certain direction */ - real K, /* grid size in corresponding direction */ - real n) /* spline interpolation order of the SPME */ +static inline real eps_poly2(real m, /* grid coordinate in certain direction */ + real K, /* grid size in corresponding direction */ + real n) /* spline interpolation order of the SPME */ { int i; real nom = 0; /* nominator */ @@ -234,33 +232,31 @@ static inline real eps_poly2( for (i = -SUMORDER; i < 0; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += std::pow(tmp, -2 * n); } for (i = SUMORDER; i > 0; i--) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += std::pow(tmp, -2 * n); } - for (i = -SUMORDER; i < SUMORDER+1; i++) + for (i = -SUMORDER; i < SUMORDER + 1; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - denom += std::pow( tmp, -n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + denom += std::pow(tmp, -n); } tmp = eps_poly1(m, K, n); - return nom / denom / denom + tmp*tmp; - + return nom / denom / denom + tmp * tmp; } -static inline real eps_poly3( - real m, /* grid coordinate in certain direction */ - real K, /* grid size in corresponding direction */ - real n) /* spline interpolation order of the SPME */ +static inline real eps_poly3(real m, /* grid coordinate in certain direction */ + real K, /* grid size in corresponding direction */ + real n) /* spline interpolation order of the SPME */ { int i; real nom = 0; /* nominator */ @@ -274,33 +270,31 @@ static inline real eps_poly3( for (i = -SUMORDER; i < 0; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += i * std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += i * std::pow(tmp, -2 * n); } for (i = SUMORDER; i > 0; i--) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += i * std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += i * std::pow(tmp, -2 * n); } - for (i = -SUMORDER; i < SUMORDER+1; i++) + for (i = -SUMORDER; i < SUMORDER + 1; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - denom += std::pow( tmp, -n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + denom += std::pow(tmp, -n); } return 2.0 * M_PI * nom / denom / denom; - } -static inline real eps_poly4( - real m, /* grid coordinate in certain direction */ - real K, /* grid size in corresponding direction */ - real n) /* spline interpolation order of the SPME */ +static inline real eps_poly4(real m, /* grid coordinate in certain direction */ + real K, /* grid size in corresponding direction */ + real n) /* spline interpolation order of the SPME */ { int i; real nom = 0; /* nominator */ @@ -314,35 +308,33 @@ static inline real eps_poly4( for (i = -SUMORDER; i < 0; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += i * i * std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += i * i * std::pow(tmp, -2 * n); } for (i = SUMORDER; i > 0; i--) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - nom += i * i * std::pow( tmp, -2*n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + nom += i * i * std::pow(tmp, -2 * n); } - for (i = -SUMORDER; i < SUMORDER+1; i++) + for (i = -SUMORDER; i < SUMORDER + 1; i++) { - tmp = m / K + i; - tmp *= 2.0*M_PI; - denom += std::pow( tmp, -n ); + tmp = m / K + i; + tmp *= 2.0 * M_PI; + denom += std::pow(tmp, -n); } return 4.0 * M_PI * M_PI * nom / denom / denom; - } -static inline real eps_self( - real m, /* grid coordinate in certain direction */ - real K, /* grid size in corresponding direction */ - rvec rboxv, /* reciprocal box vector */ - real n, /* spline interpolation order of the SPME */ - rvec x) /* coordinate of charge */ +static inline real eps_self(real m, /* grid coordinate in certain direction */ + real K, /* grid size in corresponding direction */ + rvec rboxv, /* reciprocal box vector */ + real n, /* spline interpolation order of the SPME */ + rvec x) /* coordinate of charge */ { int i; real tmp = 0; /* temporary variables for computations */ @@ -363,29 +355,28 @@ static inline real eps_self( for (i = -SUMORDER; i < 0; i++) { - tmp = -std::sin(2.0 * M_PI * i * K * rcoord); - tmp1 = 2.0 * M_PI * m / K + 2.0 * M_PI * i; - tmp2 = std::pow(tmp1, -n); - nom += tmp * tmp2 * i; + tmp = -std::sin(2.0 * M_PI * i * K * rcoord); + tmp1 = 2.0 * M_PI * m / K + 2.0 * M_PI * i; + tmp2 = std::pow(tmp1, -n); + nom += tmp * tmp2 * i; denom += tmp2; } for (i = SUMORDER; i > 0; i--) { - tmp = -std::sin(2.0 * M_PI * i * K * rcoord); - tmp1 = 2.0 * M_PI * m / K + 2.0 * M_PI * i; - tmp2 = std::pow(tmp1, -n); - nom += tmp * tmp2 * i; + tmp = -std::sin(2.0 * M_PI * i * K * rcoord); + tmp1 = 2.0 * M_PI * m / K + 2.0 * M_PI * i; + tmp2 = std::pow(tmp1, -n); + nom += tmp * tmp2 * i; denom += tmp2; } - tmp = 2.0 * M_PI * m / K; - tmp1 = pow(tmp, -n); + tmp = 2.0 * M_PI * m / K; + tmp1 = pow(tmp, -n); denom += tmp1; return 2.0 * M_PI * nom / denom * K; - } #undef SUMORDER @@ -396,56 +387,55 @@ static void calc_recipbox(matrix box, matrix recipbox) { /* Save some time by assuming upper right part is zero */ - real tmp = 1.0/(box[XX][XX]*box[YY][YY]*box[ZZ][ZZ]); + real tmp = 1.0 / (box[XX][XX] * box[YY][YY] * box[ZZ][ZZ]); - recipbox[XX][XX] = box[YY][YY]*box[ZZ][ZZ]*tmp; + recipbox[XX][XX] = box[YY][YY] * box[ZZ][ZZ] * tmp; recipbox[XX][YY] = 0; recipbox[XX][ZZ] = 0; - recipbox[YY][XX] = -box[YY][XX]*box[ZZ][ZZ]*tmp; - recipbox[YY][YY] = box[XX][XX]*box[ZZ][ZZ]*tmp; + recipbox[YY][XX] = -box[YY][XX] * box[ZZ][ZZ] * tmp; + recipbox[YY][YY] = box[XX][XX] * box[ZZ][ZZ] * tmp; recipbox[YY][ZZ] = 0; - recipbox[ZZ][XX] = (box[YY][XX]*box[ZZ][YY]-box[YY][YY]*box[ZZ][XX])*tmp; - recipbox[ZZ][YY] = -box[ZZ][YY]*box[XX][XX]*tmp; - recipbox[ZZ][ZZ] = box[XX][XX]*box[YY][YY]*tmp; + recipbox[ZZ][XX] = (box[YY][XX] * box[ZZ][YY] - box[YY][YY] * box[ZZ][XX]) * tmp; + recipbox[ZZ][YY] = -box[ZZ][YY] * box[XX][XX] * tmp; + recipbox[ZZ][ZZ] = box[XX][XX] * box[YY][YY] * tmp; } /* Estimate the reciprocal space part error of the SPME Ewald sum. */ -static real estimate_reciprocal( - t_inputinfo *info, - rvec x[], /* array of particles */ - const real q[], /* array of charges */ - int nr, /* number of charges = size of the charge array */ - FILE gmx_unused *fp_out, - gmx_bool bVerbose, - int seed, /* The seed for the random number generator */ - int *nsamples, /* Return the number of samples used if Monte Carlo - * algorithm is used for self energy error estimate */ - t_commrec *cr) +static real estimate_reciprocal(t_inputinfo* info, + rvec x[], /* array of particles */ + const real q[], /* array of charges */ + int nr, /* number of charges = size of the charge array */ + FILE gmx_unused* fp_out, + gmx_bool bVerbose, + int seed, /* The seed for the random number generator */ + int* nsamples, /* Return the number of samples used if Monte Carlo + * algorithm is used for self energy error estimate */ + t_commrec* cr) { - real e_rec = 0; /* reciprocal error estimate */ - real e_rec1 = 0; /* Error estimate term 1*/ - real e_rec2 = 0; /* Error estimate term 2*/ - real e_rec3 = 0; /* Error estimate term 3 */ - real e_rec3x = 0; /* part of Error estimate term 3 in x */ - real e_rec3y = 0; /* part of Error estimate term 3 in y */ - real e_rec3z = 0; /* part of Error estimate term 3 in z */ - int i, ci; - int nx, ny, nz; /* grid coordinates */ - real q2_all = 0; /* sum of squared charges */ - rvec gridpx; /* reciprocal grid point in x direction*/ - rvec gridpxy; /* reciprocal grid point in x and y direction*/ - rvec gridp; /* complete reciprocal grid point in 3 directions*/ - rvec tmpvec; /* template to create points from basis vectors */ - rvec tmpvec2; /* template to create points from basis vectors */ - real coeff = 0; /* variable to compute coefficients of the error estimate */ - real coeff2 = 0; /* variable to compute coefficients of the error estimate */ - real tmp = 0; /* variables to compute different factors from vectors */ - real tmp1 = 0; - real tmp2 = 0; - gmx_bool bFraction; - - int *numbers = nullptr; + real e_rec = 0; /* reciprocal error estimate */ + real e_rec1 = 0; /* Error estimate term 1*/ + real e_rec2 = 0; /* Error estimate term 2*/ + real e_rec3 = 0; /* Error estimate term 3 */ + real e_rec3x = 0; /* part of Error estimate term 3 in x */ + real e_rec3y = 0; /* part of Error estimate term 3 in y */ + real e_rec3z = 0; /* part of Error estimate term 3 in z */ + int i, ci; + int nx, ny, nz; /* grid coordinates */ + real q2_all = 0; /* sum of squared charges */ + rvec gridpx; /* reciprocal grid point in x direction*/ + rvec gridpxy; /* reciprocal grid point in x and y direction*/ + rvec gridp; /* complete reciprocal grid point in 3 directions*/ + rvec tmpvec; /* template to create points from basis vectors */ + rvec tmpvec2; /* template to create points from basis vectors */ + real coeff = 0; /* variable to compute coefficients of the error estimate */ + real coeff2 = 0; /* variable to compute coefficients of the error estimate */ + real tmp = 0; /* variables to compute different factors from vectors */ + real tmp1 = 0; + real tmp2 = 0; + gmx_bool bFraction; + + int* numbers = nullptr; /* Index variables for parallel work distribution */ int startglobal, stopglobal; @@ -466,8 +456,8 @@ static real estimate_reciprocal( } fprintf(stderr, "Using random seed %d.\n", seed); - gmx::DefaultRandomEngine rng(seed); - gmx::UniformIntDistribution dist(0, nr-1); + gmx::DefaultRandomEngine rng(seed); + gmx::UniformIntDistribution dist(0, nr - 1); clear_rvec(gridpx); clear_rvec(gridpxy); @@ -477,18 +467,18 @@ static real estimate_reciprocal( for (i = 0; i < nr; i++) { - q2_all += q[i]*q[i]; + q2_all += q[i] * q[i]; } /* Calculate indices for work distribution */ - startglobal = -info->nkx[0]/2; - stopglobal = info->nkx[0]/2; - xtot = stopglobal*2+1; + startglobal = -info->nkx[0] / 2; + stopglobal = info->nkx[0] / 2; + xtot = stopglobal * 2 + 1; if (PAR(cr)) { x_per_core = static_cast(std::ceil(static_cast(xtot) / cr->nnodes)); - startlocal = startglobal + x_per_core*cr->nodeid; - stoplocal = startlocal + x_per_core -1; + startlocal = startglobal + x_per_core * cr->nodeid; + stoplocal = startlocal + x_per_core - 1; if (stoplocal > stopglobal) { stoplocal = stopglobal; @@ -502,43 +492,42 @@ static real estimate_reciprocal( } #if GMX_LIB_MPI -#ifdef TAKETIME +# ifdef TAKETIME if (MASTER(cr)) { t0 = MPI_Wtime(); } -#endif +# endif #endif if (MASTER(cr)) { fprintf(stderr, "Calculating reciprocal error part 1 ..."); - } for (nx = startlocal; nx <= stoplocal; nx++) { svmul(nx, info->recipbox[XX], gridpx); - for (ny = -info->nky[0]/2; ny < info->nky[0]/2+1; ny++) + for (ny = -info->nky[0] / 2; ny < info->nky[0] / 2 + 1; ny++) { svmul(ny, info->recipbox[YY], tmpvec); rvec_add(gridpx, tmpvec, gridpxy); - for (nz = -info->nkz[0]/2; nz < info->nkz[0]/2+1; nz++) + for (nz = -info->nkz[0] / 2; nz < info->nkz[0] / 2 + 1; nz++) { - if (0 == nx && 0 == ny && 0 == nz) + if (0 == nx && 0 == ny && 0 == nz) { continue; } svmul(nz, info->recipbox[ZZ], tmpvec); rvec_add(gridpxy, tmpvec, gridp); - tmp = norm2(gridp); - coeff = std::exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ); + tmp = norm2(gridp); + coeff = std::exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0]); coeff /= 2.0 * M_PI * info->volume * tmp; coeff2 = tmp; - tmp = eps_poly2(nx, info->nkx[0], info->pme_order[0]); + tmp = eps_poly2(nx, info->nkx[0], info->pme_order[0]); tmp += eps_poly2(ny, info->nkx[0], info->pme_order[0]); tmp += eps_poly2(nz, info->nkx[0], info->pme_order[0]); @@ -557,62 +546,61 @@ static real estimate_reciprocal( tmp += 2.0 * tmp1 * tmp2; - tmp1 = eps_poly1(nx, info->nkx[0], info->pme_order[0]); + tmp1 = eps_poly1(nx, info->nkx[0], info->pme_order[0]); tmp1 += eps_poly1(ny, info->nky[0], info->pme_order[0]); tmp1 += eps_poly1(nz, info->nkz[0], info->pme_order[0]); tmp += tmp1 * tmp1; - e_rec1 += 32.0 * M_PI * M_PI * coeff * coeff * coeff2 * tmp * q2_all * q2_all / nr; + e_rec1 += 32.0 * M_PI * M_PI * coeff * coeff * coeff2 * tmp * q2_all * q2_all / nr; - tmp1 = eps_poly3(nx, info->nkx[0], info->pme_order[0]); + tmp1 = eps_poly3(nx, info->nkx[0], info->pme_order[0]); tmp1 *= info->nkx[0]; - tmp2 = iprod(gridp, info->recipbox[XX]); + tmp2 = iprod(gridp, info->recipbox[XX]); - tmp = tmp1*tmp2; + tmp = tmp1 * tmp2; - tmp1 = eps_poly3(ny, info->nky[0], info->pme_order[0]); + tmp1 = eps_poly3(ny, info->nky[0], info->pme_order[0]); tmp1 *= info->nky[0]; - tmp2 = iprod(gridp, info->recipbox[YY]); + tmp2 = iprod(gridp, info->recipbox[YY]); - tmp += tmp1*tmp2; + tmp += tmp1 * tmp2; - tmp1 = eps_poly3(nz, info->nkz[0], info->pme_order[0]); + tmp1 = eps_poly3(nz, info->nkz[0], info->pme_order[0]); tmp1 *= info->nkz[0]; - tmp2 = iprod(gridp, info->recipbox[ZZ]); + tmp2 = iprod(gridp, info->recipbox[ZZ]); - tmp += tmp1*tmp2; + tmp += tmp1 * tmp2; tmp *= 4.0 * M_PI; - tmp1 = eps_poly4(nx, info->nkx[0], info->pme_order[0]); + tmp1 = eps_poly4(nx, info->nkx[0], info->pme_order[0]); tmp1 *= norm2(info->recipbox[XX]); tmp1 *= info->nkx[0] * info->nkx[0]; tmp += tmp1; - tmp1 = eps_poly4(ny, info->nky[0], info->pme_order[0]); + tmp1 = eps_poly4(ny, info->nky[0], info->pme_order[0]); tmp1 *= norm2(info->recipbox[YY]); tmp1 *= info->nky[0] * info->nky[0]; tmp += tmp1; - tmp1 = eps_poly4(nz, info->nkz[0], info->pme_order[0]); + tmp1 = eps_poly4(nz, info->nkz[0], info->pme_order[0]); tmp1 *= norm2(info->recipbox[ZZ]); tmp1 *= info->nkz[0] * info->nkz[0]; tmp += tmp1; e_rec2 += 4.0 * coeff * coeff * tmp * q2_all * q2_all / nr; - } } if (MASTER(cr)) { - fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%", 100.0*(nx-startlocal+1)/(x_per_core)); + fprintf(stderr, "\rCalculating reciprocal error part 1 ... %3.0f%%", + 100.0 * (nx - startlocal + 1) / (x_per_core)); fflush(stderr); } - } if (MASTER(cr)) @@ -621,15 +609,15 @@ static real estimate_reciprocal( } /* Use just a fraction of all charges to estimate the self energy error term? */ - bFraction = (info->fracself > 0.0) && (info->fracself < 1.0); + bFraction = (info->fracself > 0.0) && (info->fracself < 1.0); if (bFraction) { /* Here xtot is the number of samples taken for the Monte Carlo calculation * of the average of term IV of equation 35 in Wang2010. Round up to a * number of samples that is divisible by the number of nodes */ - x_per_core = static_cast(std::ceil(info->fracself * nr / cr->nnodes)); - xtot = x_per_core * cr->nnodes; + x_per_core = static_cast(std::ceil(info->fracself * nr / cr->nnodes)); + xtot = x_per_core * cr->nnodes; } else { @@ -638,8 +626,8 @@ static real estimate_reciprocal( x_per_core = static_cast(std::ceil(static_cast(xtot) / cr->nnodes)); } - startlocal = x_per_core * cr->nodeid; - stoplocal = std::min(startlocal + x_per_core, xtot); /* min needed if xtot == nr */ + startlocal = x_per_core * cr->nodeid; + stoplocal = std::min(startlocal + x_per_core, xtot); /* min needed if xtot == nr */ if (bFraction) { @@ -693,14 +681,14 @@ static real estimate_reciprocal( } /* for(nx=startlocal; nx<=stoplocal; nx++)*/ - for (nx = -info->nkx[0]/2; nx < info->nkx[0]/2+1; nx++) + for (nx = -info->nkx[0] / 2; nx < info->nkx[0] / 2 + 1; nx++) { svmul(nx, info->recipbox[XX], gridpx); - for (ny = -info->nky[0]/2; ny < info->nky[0]/2+1; ny++) + for (ny = -info->nky[0] / 2; ny < info->nky[0] / 2 + 1; ny++) { svmul(ny, info->recipbox[YY], tmpvec); rvec_add(gridpx, tmpvec, gridpxy); - for (nz = -info->nkz[0]/2; nz < info->nkz[0]/2+1; nz++) + for (nz = -info->nkz[0] / 2; nz < info->nkz[0] / 2 + 1; nz++) { if (0 == nx && 0 == ny && 0 == nz) @@ -710,13 +698,15 @@ static real estimate_reciprocal( svmul(nz, info->recipbox[ZZ], tmpvec); rvec_add(gridpxy, tmpvec, gridp); - tmp = norm2(gridp); - coeff = std::exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0] ); - coeff /= tmp; - e_rec3x += coeff*eps_self(nx, info->nkx[0], info->recipbox[XX], info->pme_order[0], x[ci]); - e_rec3y += coeff*eps_self(ny, info->nky[0], info->recipbox[YY], info->pme_order[0], x[ci]); - e_rec3z += coeff*eps_self(nz, info->nkz[0], info->recipbox[ZZ], info->pme_order[0], x[ci]); - + tmp = norm2(gridp); + coeff = std::exp(-1.0 * M_PI * M_PI * tmp / info->ewald_beta[0] / info->ewald_beta[0]); + coeff /= tmp; + e_rec3x += coeff + * eps_self(nx, info->nkx[0], info->recipbox[XX], info->pme_order[0], x[ci]); + e_rec3y += coeff + * eps_self(ny, info->nky[0], info->recipbox[YY], info->pme_order[0], x[ci]); + e_rec3z += coeff + * eps_self(nz, info->nkz[0], info->recipbox[ZZ], info->pme_order[0], x[ci]); } } } @@ -730,11 +720,11 @@ static real estimate_reciprocal( svmul(e_rec3z, info->recipbox[ZZ], tmpvec); rvec_inc(tmpvec2, tmpvec); - e_rec3 += q[ci]*q[ci]*q[ci]*q[ci]*norm2(tmpvec2) / ( xtot * M_PI * info->volume * M_PI * info->volume); + e_rec3 += q[ci] * q[ci] * q[ci] * q[ci] * norm2(tmpvec2) + / (xtot * M_PI * info->volume * M_PI * info->volume); if (MASTER(cr)) { - fprintf(stderr, "\rCalculating reciprocal error part 2 ... %3.0f%%", - 100.0*(i+1)/stoplocal); + fprintf(stderr, "\rCalculating reciprocal error part 2 ... %3.0f%%", 100.0 * (i + 1) / stoplocal); fflush(stderr); } } @@ -745,20 +735,19 @@ static real estimate_reciprocal( } #if GMX_LIB_MPI -#ifdef TAKETIME +# ifdef TAKETIME if (MASTER(cr)) { t1 = MPI_Wtime() - t0; fprintf(fp_out, "Recip. err. est. took : %lf s\n", t1); } -#endif +# endif #endif #ifdef DEBUG if (PAR(cr)) { - fprintf(stderr, "Rank %3d: nx=[%3d...%3d] e_rec3=%e\n", - cr->nodeid, startlocal, stoplocal, e_rec3); + fprintf(stderr, "Rank %3d: nx=[%3d...%3d] e_rec3=%e\n", cr->nodeid, startlocal, stoplocal, e_rec3); } #endif @@ -773,7 +762,7 @@ static real estimate_reciprocal( e_rec2*= q2_all / M_PI / M_PI / info->volume / info->volume / nr ; e_rec3/= M_PI * M_PI * info->volume * info->volume * nr ; */ - e_rec = std::sqrt(e_rec1+e_rec2+e_rec3); + e_rec = std::sqrt(e_rec1 + e_rec2 + e_rec3); return ONE_4PI_EPS0 * e_rec; @@ -781,7 +770,7 @@ static real estimate_reciprocal( /* Allocate memory for the inputinfo struct: */ -static void create_info(t_inputinfo *info) +static void create_info(t_inputinfo* info) { snew(info->fac, info->n_entries); snew(info->rcoulomb, info->n_entries); @@ -802,9 +791,9 @@ static void create_info(t_inputinfo *info) /* Allocate and fill an array with coordinates and charges, * returns the number of charges found */ -static int prepare_x_q(real *q[], rvec *x[], const gmx_mtop_t *mtop, const rvec x_orig[], t_commrec *cr) +static int prepare_x_q(real* q[], rvec* x[], const gmx_mtop_t* mtop, const rvec x_orig[], t_commrec* cr) { - int nq; /* number of charged particles */ + int nq; /* number of charged particles */ if (MASTER(cr)) @@ -815,7 +804,7 @@ static int prepare_x_q(real *q[], rvec *x[], const gmx_mtop_t *mtop, const rvec for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int i = atomP.globalAtomNumber(); if (is_charge(local.q)) { @@ -845,9 +834,14 @@ static int prepare_x_q(real *q[], rvec *x[], const gmx_mtop_t *mtop, const rvec } - /* Read in the tpr file and save information we need later in info */ -static void read_tpr_file(const char *fn_sim_tpr, t_inputinfo *info, t_state *state, gmx_mtop_t *mtop, t_inputrec *ir, real user_beta, real fracself) +static void read_tpr_file(const char* fn_sim_tpr, + t_inputinfo* info, + t_state* state, + gmx_mtop_t* mtop, + t_inputrec* ir, + real user_beta, + real fracself) { read_tpx_state(fn_sim_tpr, ir, state, mtop); @@ -868,7 +862,7 @@ static void read_tpr_file(const char *fn_sim_tpr, t_inputinfo *info, t_state *st } else { - info->ewald_beta[0] = calc_ewaldcoeff_q(info->rcoulomb[0], info->ewald_rtol[0]); + info->ewald_beta[0] = calc_ewaldcoeff_q(info->rcoulomb[0], info->ewald_rtol[0]); } /* Check if PME was chosen */ @@ -886,7 +880,7 @@ static void read_tpr_file(const char *fn_sim_tpr, t_inputinfo *info, t_state *st /* Transfer what we need for parallelizing the reciprocal error estimate */ -static void bcast_info(t_inputinfo *info, const t_commrec *cr) +static void bcast_info(t_inputinfo* info, const t_commrec* cr) { nblock_bc(cr, info->n_entries, info->nkx); nblock_bc(cr, info->n_entries, info->nky); @@ -909,12 +903,16 @@ static void bcast_info(t_inputinfo *info, const t_commrec *cr) * a) a homogeneous distribution of the charges * b) a total charge of zero. */ -static void estimate_PME_error(t_inputinfo *info, const t_state *state, - const gmx_mtop_t *mtop, FILE *fp_out, gmx_bool bVerbose, unsigned int seed, - t_commrec *cr) +static void estimate_PME_error(t_inputinfo* info, + const t_state* state, + const gmx_mtop_t* mtop, + FILE* fp_out, + gmx_bool bVerbose, + unsigned int seed, + t_commrec* cr) { - rvec *x = nullptr; /* The coordinates */ - real *q = nullptr; /* The charges */ + rvec* x = nullptr; /* The coordinates */ + real* q = nullptr; /* The charges */ real edir = 0.0; /* real space error */ real erec = 0.0; /* reciprocal space error */ real derr = 0.0; /* difference of real and reciprocal space error */ @@ -924,7 +922,7 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, int ncharges; /* The number of atoms with charges */ int nsamples; /* The number of samples used for the calculation of the * self-energy error term */ - int i = 0; + int i = 0; if (MASTER(cr)) { @@ -936,7 +934,7 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, if (MASTER(cr)) { calc_q2all(mtop, &(info->q2all), &(info->q2allnr)); - info->ewald_rtol[0] = std::erfc(info->rcoulomb[0]*info->ewald_beta[0]); + info->ewald_rtol[0] = std::erfc(info->rcoulomb[0] * info->ewald_beta[0]); /* Write some info to log file */ fprintf(fp_out, "Box volume : %g nm^3\n", info->volume); fprintf(fp_out, "Number of charged atoms : %d (total atoms %d)\n", ncharges, info->natoms); @@ -944,10 +942,9 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, fprintf(fp_out, "Ewald_rtol : %g\n", info->ewald_rtol[0]); fprintf(fp_out, "Ewald parameter beta : %g\n", info->ewald_beta[0]); fprintf(fp_out, "Interpolation order : %d\n", info->pme_order[0]); - fprintf(fp_out, "Fourier grid (nx,ny,nz) : %d x %d x %d\n", - info->nkx[0], info->nky[0], info->nkz[0]); + fprintf(fp_out, "Fourier grid (nx,ny,nz) : %d x %d x %d\n", info->nkx[0], info->nky[0], + info->nkz[0]); fflush(fp_out); - } if (PAR(cr)) @@ -960,8 +957,7 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, info->e_dir[0] = estimate_direct(info); /* Calculate reciprocal space error */ - info->e_rec[0] = estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, - seed, &nsamples, cr); + info->e_rec[0] = estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, seed, &nsamples, cr); if (PAR(cr)) { @@ -988,7 +984,7 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, } edir = info->e_dir[0]; erec = info->e_rec[0]; - derr0 = edir-erec; + derr0 = edir - erec; beta0 = info->ewald_beta[0]; if (derr > 0.0) { @@ -999,8 +995,7 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, info->ewald_beta[0] -= 0.1; } info->e_dir[0] = estimate_direct(info); - info->e_rec[0] = estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, - seed, &nsamples, cr); + info->e_rec[0] = estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, seed, &nsamples, cr); if (PAR(cr)) { @@ -1010,19 +1005,19 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, edir = info->e_dir[0]; erec = info->e_rec[0]; - derr = edir-erec; - while (std::abs(derr/std::min(erec, edir)) > 1e-4) + derr = edir - erec; + while (std::abs(derr / std::min(erec, edir)) > 1e-4) { - beta = info->ewald_beta[0]; - beta -= derr*(info->ewald_beta[0]-beta0)/(derr-derr0); + beta = info->ewald_beta[0]; + beta -= derr * (info->ewald_beta[0] - beta0) / (derr - derr0); beta0 = info->ewald_beta[0]; info->ewald_beta[0] = beta; derr0 = derr; info->e_dir[0] = estimate_direct(info); - info->e_rec[0] = estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, - seed, &nsamples, cr); + info->e_rec[0] = + estimate_reciprocal(info, x, q, ncharges, fp_out, bVerbose, seed, &nsamples, cr); if (PAR(cr)) { @@ -1031,18 +1026,19 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, edir = info->e_dir[0]; erec = info->e_rec[0]; - derr = edir-erec; + derr = edir - erec; if (MASTER(cr)) { i++; - fprintf(stderr, "difference between real and rec. space error (step %d): %g\n", i, std::abs(derr)); + fprintf(stderr, "difference between real and rec. space error (step %d): %g\n", i, + std::abs(derr)); fprintf(stderr, "old beta: %f\n", beta0); fprintf(stderr, "new beta: %f\n", beta); } } - info->ewald_rtol[0] = std::erfc(info->rcoulomb[0]*info->ewald_beta[0]); + info->ewald_rtol[0] = std::erfc(info->rcoulomb[0] * info->ewald_beta[0]); if (MASTER(cr)) { @@ -1056,17 +1052,14 @@ static void estimate_PME_error(t_inputinfo *info, const t_state *state, fprintf(fp_out, "Ewald_rtol : %g\n", info->ewald_rtol[0]); fprintf(fp_out, "Ewald parameter beta : %g\n", info->ewald_beta[0]); fflush(fp_out); - } - } - } -int gmx_pme_error(int argc, char *argv[]) +int gmx_pme_error(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] estimates the error of the electrostatic forces", "if using the sPME algorithm. The flag [TT]-tune[tt] will determine", "the splitting parameter such that the error is equally", @@ -1077,50 +1070,61 @@ int gmx_pme_error(int argc, char *argv[]) "indicated by the flag [TT]-self[tt].[PAR]", }; - real fs = 0.0; /* 0 indicates: not set by the user */ - real user_beta = -1.0; - real fracself = 1.0; - t_inputinfo info; - t_state state; /* The state from the tpr input file */ - gmx_mtop_t mtop; /* The topology from the tpr input file */ - FILE *fp = nullptr; - unsigned long PCA_Flags; - gmx_bool bTUNE = FALSE; - gmx_bool bVerbose = FALSE; - int seed = 0; - - - static t_filenm fnm[] = { - { efTPR, "-s", nullptr, ffREAD }, - { efOUT, "-o", "error", ffWRITE }, - { efTPR, "-so", "tuned", ffOPTWR } - }; - - gmx_output_env_t *oenv = nullptr; - - t_pargs pa[] = { - { "-beta", FALSE, etREAL, {&user_beta}, + real fs = 0.0; /* 0 indicates: not set by the user */ + real user_beta = -1.0; + real fracself = 1.0; + t_inputinfo info; + t_state state; /* The state from the tpr input file */ + gmx_mtop_t mtop; /* The topology from the tpr input file */ + FILE* fp = nullptr; + unsigned long PCA_Flags; + gmx_bool bTUNE = FALSE; + gmx_bool bVerbose = FALSE; + int seed = 0; + + + static t_filenm fnm[] = { { efTPR, "-s", nullptr, ffREAD }, + { efOUT, "-o", "error", ffWRITE }, + { efTPR, "-so", "tuned", ffOPTWR } }; + + gmx_output_env_t* oenv = nullptr; + + t_pargs pa[] = { + { "-beta", + FALSE, + etREAL, + { &user_beta }, "If positive, overwrite ewald_beta from [REF].tpr[ref] file with this value" }, - { "-tune", FALSE, etBOOL, {&bTUNE}, - "Tune the splitting parameter such that the error is equally distributed between real and reciprocal space" }, - { "-self", FALSE, etREAL, {&fracself}, - "If between 0.0 and 1.0, determine self interaction error from just this fraction of the charged particles" }, - { "-seed", FALSE, etINT, {&seed}, - "Random number seed used for Monte Carlo algorithm when [TT]-self[tt] is set to a value between 0.0 and 1.0" }, - { "-v", FALSE, etBOOL, {&bVerbose}, - "Be loud and noisy" } + { "-tune", + FALSE, + etBOOL, + { &bTUNE }, + "Tune the splitting parameter such that the error is equally distributed between " + "real and reciprocal space" }, + { "-self", + FALSE, + etREAL, + { &fracself }, + "If between 0.0 and 1.0, determine self interaction error from just this " + "fraction of the charged particles" }, + { "-seed", + FALSE, + etINT, + { &seed }, + "Random number seed used for Monte Carlo algorithm when [TT]-self[tt] is set to " + "a value between 0.0 and 1.0" }, + { "-v", FALSE, etBOOL, { &bVerbose }, "Be loud and noisy" } }; #define NFILE asize(fnm) CommrecHandle commrecHandle = init_commrec(MPI_COMM_WORLD, nullptr); - t_commrec *cr = commrecHandle.get(); - PCA_Flags = PCA_NOEXIT_ON_ARGS; + t_commrec* cr = commrecHandle.get(); + PCA_Flags = PCA_NOEXIT_ON_ARGS; - if (!parse_common_args(&argc, argv, PCA_Flags, - NFILE, fnm, asize(pa), pa, asize(desc), desc, - 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_Flags, NFILE, fnm, asize(pa), pa, asize(desc), desc, 0, + nullptr, &oenv)) { return 0; } @@ -1159,9 +1163,11 @@ int gmx_pme_error(int argc, char *argv[]) info.nkz[0] = 0; calcFftGrid(stdout, state.box, info.fourier_sp[0], minimalPmeGridSize(info.pme_order[0]), &(info.nkx[0]), &(info.nky[0]), &(info.nkz[0])); - if ( (ir.nkx != info.nkx[0]) || (ir.nky != info.nky[0]) || (ir.nkz != info.nkz[0]) ) + if ((ir.nkx != info.nkx[0]) || (ir.nky != info.nky[0]) || (ir.nkz != info.nkz[0])) { - gmx_fatal(FARGS, "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = %d x %d x %d", + gmx_fatal(FARGS, + "Wrong fourierspacing %f nm, input file grid = %d x %d x %d, computed grid = " + "%d x %d x %d", fs, ir.nkx, ir.nky, ir.nkz, info.nkx[0], info.nky[0], info.nkz[0]); } } diff --git a/src/gromacs/tools/pme_error.h b/src/gromacs/tools/pme_error.h index 19a30d502b..4add45053b 100644 --- a/src/gromacs/tools/pme_error.h +++ b/src/gromacs/tools/pme_error.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_pme_error(int argc, char *argv[]); +int gmx_pme_error(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/report_methods.cpp b/src/gromacs/tools/report_methods.cpp index 882e18d08a..4074465931 100644 --- a/src/gromacs/tools/report_methods.cpp +++ b/src/gromacs/tools/report_methods.cpp @@ -55,7 +55,7 @@ namespace gmx { -void writeHeader(TextWriter *writer, const std::string &text, const std::string §ion, bool writeFormattedText) +void writeHeader(TextWriter* writer, const std::string& text, const std::string& section, bool writeFormattedText) { std::string formattedText; if (writeFormattedText) @@ -69,11 +69,11 @@ void writeHeader(TextWriter *writer, const std::string &text, const std::string writer->writeString(formattedText); } -void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writeFormattedText) +void writeSystemInformation(TextWriter* writer, const gmx_mtop_t& top, bool writeFormattedText) { int nmol, nvsite = 0; gmx_mtop_atomloop_block_t aloop; - const t_atom *atom; + const t_atom* atom; writeHeader(writer, "Simulation system", "subsection", writeFormattedText); aloop = gmx_mtop_atomloop_block_init(&top); @@ -86,7 +86,7 @@ void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writ } { writer->writeLine(formatString("A system of %d molecules (%d atoms) was simulated.", - gmx_mtop_num_molecules(top), top.natoms-nvsite)); + gmx_mtop_num_molecules(top), top.natoms - nvsite)); } if (nvsite) { @@ -95,20 +95,24 @@ void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writ writer->ensureEmptyLine(); } -void writeParameterInformation(TextWriter *writer, const t_inputrec &ir, bool writeFormattedText) +void writeParameterInformation(TextWriter* writer, const t_inputrec& ir, bool writeFormattedText) { writeHeader(writer, "Simulation settings", "subsection", writeFormattedText); writer->writeLine(formatString("A total of %g ns were simulated with a time step of %g fs.", - ir.nsteps*ir.delta_t*0.001, 1000*ir.delta_t)); + ir.nsteps * ir.delta_t * 0.001, 1000 * ir.delta_t)); writer->writeLine(formatString("Neighbor searching was performed every %d steps.", ir.nstlist)); writer->writeLine(formatString("The %s algorithm was used for electrostatic interactions.", EELTYPE(ir.coulombtype))); writer->writeLine(formatString("with a cut-off of %g nm.", ir.rcoulomb)); if (ir.coulombtype == eelPME) { - writer->writeLine(formatString("A reciprocal grid of %d x %d x %d cells was used with %dth order B-spline interpolation.", ir.nkx, ir.nky, ir.nkz, ir.pme_order)); + writer->writeLine( + formatString("A reciprocal grid of %d x %d x %d cells was used with %dth order " + "B-spline interpolation.", + ir.nkx, ir.nky, ir.nkz, ir.pme_order)); } - writer->writeLine(formatString("A single cut-off of %g nm was used for Van der Waals interactions.", ir.rlist)); + writer->writeLine(formatString( + "A single cut-off of %g nm was used for Van der Waals interactions.", ir.rlist)); if (ir.etc != 0) { writer->writeLine(formatString("Temperature coupling was done with the %s algorithm.", @@ -122,10 +126,13 @@ void writeParameterInformation(TextWriter *writer, const t_inputrec &ir, bool wr writer->ensureEmptyLine(); } -void writeInformation(TextOutputFile *outputStream, const t_inputrec &ir, - const gmx_mtop_t &top, bool writeFormattedText, bool notStdout) +void writeInformation(TextOutputFile* outputStream, + const t_inputrec& ir, + const gmx_mtop_t& top, + bool writeFormattedText, + bool notStdout) { - TextWriter writer(outputStream); + TextWriter writer(outputStream); writer.ensureEmptyLine(); writeHeader(&writer, "Methods", "section", writeFormattedText); writeSystemInformation(&writer, top, writeFormattedText); @@ -143,73 +150,66 @@ namespace class ReportMethods : public ICommandLineOptionsModule { - public: - ReportMethods() - : writeLatex_(false), writePlainText_(false) - { - } - - // From ICommandLineOptionsModule - void init(CommandLineModuleSettings * /*settings*/) override - { - } - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - void optionsFinished() override; - int run() override; - - private: - - //! File name for the output LaTeX file or empty. - std::string outputFileLatex_; - //! File name for the unformatted output file or empty. - std::string outputFileUnformatted_; - //! File name of the run input file with full topology. - std::string inputTopology_; - //! Boolean reporting if writing to the LaTeX output file is requested. - bool writeLatex_; - //! Boolean reporting if writing to unformatted output is requested. - bool writePlainText_; +public: + ReportMethods() : writeLatex_(false), writePlainText_(false) {} + + // From ICommandLineOptionsModule + void init(CommandLineModuleSettings* /*settings*/) override {} + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + void optionsFinished() override; + int run() override; + +private: + //! File name for the output LaTeX file or empty. + std::string outputFileLatex_; + //! File name for the unformatted output file or empty. + std::string outputFileUnformatted_; + //! File name of the run input file with full topology. + std::string inputTopology_; + //! Boolean reporting if writing to the LaTeX output file is requested. + bool writeLatex_; + //! Boolean reporting if writing to unformatted output is requested. + bool writePlainText_; }; -void ReportMethods::initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) +void ReportMethods::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - const char *const desc[] = { - "[THISMODULE] reports basic system information for the run input", - "file specfied with [TT]-s[tt] either to the", - "terminal, to a LaTeX formatted output file if run with", - "the [TT]-m[tt] option or to an unformatted file with", - "the [TT]-o[tt] option.", - "The functionality has been moved here from its previous", - "place in [gmx-check]." - }; + const char* const desc[] = { "[THISMODULE] reports basic system information for the run input", + "file specfied with [TT]-s[tt] either to the", + "terminal, to a LaTeX formatted output file if run with", + "the [TT]-m[tt] option or to an unformatted file with", + "the [TT]-o[tt] option.", + "The functionality has been moved here from its previous", + "place in [gmx-check]." }; settings->setHelpText(desc); options->addOption(FileNameOption("s") - .filetype(eftTopology).inputFile().required() - .store(&inputTopology_) - .defaultBasename("topol") - .description("Run input file for report")); + .filetype(eftTopology) + .inputFile() + .required() + .store(&inputTopology_) + .defaultBasename("topol") + .description("Run input file for report")); // TODO: Replace use of legacyType. options->addOption(FileNameOption("m") - .legacyType(efTEX).outputFile() - .store(&outputFileLatex_).storeIsSet(&writeLatex_) - .defaultBasename("report") - .description("LaTeX formatted report output")); + .legacyType(efTEX) + .outputFile() + .store(&outputFileLatex_) + .storeIsSet(&writeLatex_) + .defaultBasename("report") + .description("LaTeX formatted report output")); options->addOption(FileNameOption("o") - .legacyType(efOUT).outputFile() - .store(&outputFileUnformatted_).storeIsSet(&writePlainText_) - .defaultBasename("report") - .description("Unformatted report output to file")); - + .legacyType(efOUT) + .outputFile() + .store(&outputFileUnformatted_) + .storeIsSet(&writePlainText_) + .defaultBasename("report") + .description("Unformatted report output to file")); } -void ReportMethods::optionsFinished() -{ -} +void ReportMethods::optionsFinished() {} int ReportMethods::run() { @@ -227,18 +227,18 @@ int ReportMethods::run() TextOutputFile file(outputFileUnformatted_); writeInformation(&file, ir, top, false, true); } - TextOutputFile &stdoutFile = TextOutputFile::standardOutput(); + TextOutputFile& stdoutFile = TextOutputFile::standardOutput(); writeInformation(&stdoutFile, ir, top, false, false); return 0; } -} // namespace +} // namespace -const char ReportMethodsInfo::name[] = "report-methods"; +const char ReportMethodsInfo::name[] = "report-methods"; const char ReportMethodsInfo::shortDescription[] = - "Write short summary about the simulation setup to a text file " - "and/or to the standard output."; + "Write short summary about the simulation setup to a text file " + "and/or to the standard output."; ICommandLineOptionsModulePointer ReportMethodsInfo::create() { return ICommandLineOptionsModulePointer(std::make_unique()); diff --git a/src/gromacs/tools/report_methods.h b/src/gromacs/tools/report_methods.h index dc918badc7..4512b24b2a 100644 --- a/src/gromacs/tools/report_methods.h +++ b/src/gromacs/tools/report_methods.h @@ -46,10 +46,10 @@ namespace gmx class ReportMethodsInfo { - public: - static const char name[]; - static const char shortDescription[]; - static ICommandLineOptionsModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static ICommandLineOptionsModulePointer create(); }; // Helper functions of the class @@ -62,7 +62,7 @@ class ReportMethodsInfo * \param[in] section String with section text for header. * \param[in] writeFormattedText If we need to format the text for LaTeX output or not */ -void writeHeader(TextWriter *writer, const std::string &text, const std::string §ion, bool writeFormattedText); +void writeHeader(TextWriter* writer, const std::string& text, const std::string& section, bool writeFormattedText); /*! \brief * Write information about the molecules in the system. @@ -75,7 +75,7 @@ void writeHeader(TextWriter *writer, const std::string &text, const std::string * \param[in] writeFormattedText Decide if we want formatted text output or not. * */ -void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writeFormattedText); +void writeSystemInformation(TextWriter* writer, const gmx_mtop_t& top, bool writeFormattedText); /*! \brief * Write information about system parameters. @@ -87,7 +87,7 @@ void writeSystemInformation(TextWriter *writer, const gmx_mtop_t &top, bool writ * \param[in] ir Reference to inputrec of the run input. * \param[in] writeFormattedText Decide if we want formatted text output or not. */ -void writeParameterInformation(TextWriter *writer, const t_inputrec &ir, bool writeFormattedText); +void writeParameterInformation(TextWriter* writer, const t_inputrec& ir, bool writeFormattedText); /*! \brief * Wrapper for writing out information. @@ -102,8 +102,11 @@ void writeParameterInformation(TextWriter *writer, const t_inputrec &ir, bool wr * \param[in] writeFormattedText Decide if we want formatted text output or not. * \param[in] notStdout Bool to see if we can close the file after writing or not in case of stdout. */ -void writeInformation(TextOutputFile *outputStream, const t_inputrec &ir, - const gmx_mtop_t &top, bool writeFormattedText, bool notStdout); +void writeInformation(TextOutputFile* outputStream, + const t_inputrec& ir, + const gmx_mtop_t& top, + bool writeFormattedText, + bool notStdout); } // namespace gmx diff --git a/src/gromacs/tools/tests/dump.cpp b/src/gromacs/tools/tests/dump.cpp index 5110162fa8..05982fa110 100644 --- a/src/gromacs/tools/tests/dump.cpp +++ b/src/gromacs/tools/tests/dump.cpp @@ -57,49 +57,45 @@ namespace test class DumpTest : public ::testing::Test { - public: - //! Run test case. - void runTest(CommandLine *cmdline); - protected: - // TODO this is changed in newer googletest versions - //! Prepare shared resources. - static void SetUpTestCase() - { - s_tprFileHandle = new TprAndFileManager("lysozyme"); - } - //! Clean up shared resources. - static void TearDownTestCase() - { - delete s_tprFileHandle; - s_tprFileHandle = nullptr; - } - //! Storage for opened file handles. - static TprAndFileManager *s_tprFileHandle; +public: + //! Run test case. + void runTest(CommandLine* cmdline); + +protected: + // TODO this is changed in newer googletest versions + //! Prepare shared resources. + static void SetUpTestCase() { s_tprFileHandle = new TprAndFileManager("lysozyme"); } + //! Clean up shared resources. + static void TearDownTestCase() + { + delete s_tprFileHandle; + s_tprFileHandle = nullptr; + } + //! Storage for opened file handles. + static TprAndFileManager* s_tprFileHandle; }; -TprAndFileManager *DumpTest::s_tprFileHandle = nullptr; +TprAndFileManager* DumpTest::s_tprFileHandle = nullptr; -void DumpTest::runTest(CommandLine *cmdline) +void DumpTest::runTest(CommandLine* cmdline) { - EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory( - &gmx::DumpInfo::create, cmdline)); + EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(&gmx::DumpInfo::create, cmdline)); } TEST_F(DumpTest, WorksWithTpr) { - const char *const command[] = - { "dump", "-s", s_tprFileHandle->tprName().c_str()}; + const char* const command[] = { "dump", "-s", s_tprFileHandle->tprName().c_str() }; CommandLine cmdline(command); runTest(&cmdline); } TEST_F(DumpTest, WorksWithTprAndMdpWriting) { - TestFileManager fileManager; - std::string mdpName = fileManager.getTemporaryFilePath("output.mdp"); - const char *const command[] = - { "dump", "-s", s_tprFileHandle->tprName().c_str(), "-om", mdpName.c_str() }; - CommandLine cmdline(command); + TestFileManager fileManager; + std::string mdpName = fileManager.getTemporaryFilePath("output.mdp"); + const char* const command[] = { "dump", "-s", s_tprFileHandle->tprName().c_str(), "-om", + mdpName.c_str() }; + CommandLine cmdline(command); runTest(&cmdline); } diff --git a/src/gromacs/tools/tests/report_methods.cpp b/src/gromacs/tools/tests/report_methods.cpp index 1d58227ef7..97b1760071 100644 --- a/src/gromacs/tools/tests/report_methods.cpp +++ b/src/gromacs/tools/tests/report_methods.cpp @@ -63,24 +63,21 @@ namespace test class ReportMethodsTest : public ::testing::Test { - protected: - // TODO this is changed in newer googletest versions - //! Prepare shared resources. - static void SetUpTestCase() - { - s_tprFileHandle = new TprAndFileManager("lysozyme"); - } - //! Clean up shared resources. - static void TearDownTestCase() - { - delete s_tprFileHandle; - s_tprFileHandle = nullptr; - } - //! Storage for opened file handles. - static TprAndFileManager *s_tprFileHandle; +protected: + // TODO this is changed in newer googletest versions + //! Prepare shared resources. + static void SetUpTestCase() { s_tprFileHandle = new TprAndFileManager("lysozyme"); } + //! Clean up shared resources. + static void TearDownTestCase() + { + delete s_tprFileHandle; + s_tprFileHandle = nullptr; + } + //! Storage for opened file handles. + static TprAndFileManager* s_tprFileHandle; }; -TprAndFileManager *ReportMethodsTest::s_tprFileHandle = nullptr; +TprAndFileManager* ReportMethodsTest::s_tprFileHandle = nullptr; /*! \brief * Reads a tpr for the test. @@ -91,11 +88,11 @@ TprAndFileManager *ReportMethodsTest::s_tprFileHandle = nullptr; * \param[in] mtop Pointer to topology datastructure to populate. * \param[in] ir Pointer to inputrec to populate. */ -static void readTprInput(const TprAndFileManager *tprHandle, gmx_mtop_t *mtop, t_inputrec *ir) +static void readTprInput(const TprAndFileManager* tprHandle, gmx_mtop_t* mtop, t_inputrec* ir) { -// read tpr into variables needed for output + // read tpr into variables needed for output { - t_state state; + t_state state; read_tpx_state(tprHandle->tprName().c_str(), ir, &state, mtop); } } @@ -134,8 +131,9 @@ TEST_F(ReportMethodsTest, WritesCorrectInformation) writeSystemInformation(&test, top, true); - std::string referenceString = "\\subsection{Simulation system}\n" - "A system of 1 molecules (156 atoms) was simulated.\n"; + std::string referenceString = + "\\subsection{Simulation system}\n" + "A system of 1 molecules (156 atoms) was simulated.\n"; EXPECT_EQ(stream.toString(), referenceString); } @@ -146,8 +144,9 @@ TEST_F(ReportMethodsTest, WritesCorrectInformation) writeSystemInformation(&test, top, false); - std::string referenceString = "subsection: Simulation system\n" - "A system of 1 molecules (156 atoms) was simulated.\n"; + std::string referenceString = + "subsection: Simulation system\n" + "A system of 1 molecules (156 atoms) was simulated.\n"; EXPECT_EQ(stream.toString(), referenceString); } @@ -159,12 +158,13 @@ TEST_F(ReportMethodsTest, WritesCorrectInformation) writeParameterInformation(&test, ir, true); - std::string referenceString = "\\subsection{Simulation settings}\n" - "A total of 0 ns were simulated with a time step of 1 fs.\n" - "Neighbor searching was performed every 10 steps.\n" - "The Cut-off algorithm was used for electrostatic interactions.\n" - "with a cut-off of 1 nm.\nA single cut-off of 1.1 nm was used " - "for Van der Waals interactions.\n"; + std::string referenceString = + "\\subsection{Simulation settings}\n" + "A total of 0 ns were simulated with a time step of 1 fs.\n" + "Neighbor searching was performed every 10 steps.\n" + "The Cut-off algorithm was used for electrostatic interactions.\n" + "with a cut-off of 1 nm.\nA single cut-off of 1.1 nm was used " + "for Van der Waals interactions.\n"; EXPECT_EQ(stream.toString(), referenceString); } @@ -172,13 +172,10 @@ TEST_F(ReportMethodsTest, WritesCorrectInformation) TEST_F(ReportMethodsTest, ToolEndToEndTest) { - const char *const command[] = { - "report-methods", "-s", s_tprFileHandle->tprName().c_str() - }; - CommandLine cmdline(command); - EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory( - &gmx::ReportMethodsInfo::create, &cmdline)); - + const char* const command[] = { "report-methods", "-s", s_tprFileHandle->tprName().c_str() }; + CommandLine cmdline(command); + EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(&gmx::ReportMethodsInfo::create, + &cmdline)); } } // namespace test diff --git a/src/gromacs/tools/tests/trjconv.cpp b/src/gromacs/tools/tests/trjconv.cpp index b73c01f85d..f220c7d4f5 100644 --- a/src/gromacs/tools/tests/trjconv.cpp +++ b/src/gromacs/tools/tests/trjconv.cpp @@ -52,28 +52,29 @@ namespace { -class TrjconvWithIndexGroupSubset : public gmx::test::CommandLineTestBase, - public ::testing::WithParamInterface +class TrjconvWithIndexGroupSubset : + public gmx::test::CommandLineTestBase, + public ::testing::WithParamInterface { - public: - void runTest(const char *fileName) - { - auto &cmdline = commandLine(); - - setInputFile("-s", "spc2.gro"); - setInputFile("-f", fileName); - setInputFile("-n", "spc2.ndx"); - setOutputFile("-o", "spc-traj.tng", gmx::test::NoTextMatch()); - - gmx::test::StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin("SecondWaterMolecule\n"); - - /* TODO Ideally, we would then check that the output file - has only 3 of the 6 atoms (which it does), but the - infrastructure for doing that automatically is still - being built. This would also fix the TODO below. */ - ASSERT_EQ(0, gmx_trjconv(cmdline.argc(), cmdline.argv())); - } +public: + void runTest(const char* fileName) + { + auto& cmdline = commandLine(); + + setInputFile("-s", "spc2.gro"); + setInputFile("-f", fileName); + setInputFile("-n", "spc2.ndx"); + setOutputFile("-o", "spc-traj.tng", gmx::test::NoTextMatch()); + + gmx::test::StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin("SecondWaterMolecule\n"); + + /* TODO Ideally, we would then check that the output file + has only 3 of the 6 atoms (which it does), but the + infrastructure for doing that automatically is still + being built. This would also fix the TODO below. */ + ASSERT_EQ(0, gmx_trjconv(cmdline.argc(), cmdline.argv())); + } }; /* TODO These tests are actually not very effective, because trjconv * can only return 0 or exit via gmx_fatal() (which currently also @@ -90,41 +91,38 @@ TEST_P(TrjconvWithIndexGroupSubset, WithDifferentInputFormats) * database. These all have two identical frames of two SPC water * molecules, which were generated via trjconv from the .gro * version. */ -const char *const trajectoryFileNames[] = { - "spc2-traj.trr", +const char* const trajectoryFileNames[] = { "spc2-traj.trr", #if GMX_USE_TNG - "spc2-traj.tng", + "spc2-traj.tng", #endif - "spc2-traj.xtc", - "spc2-traj.gro", - "spc2-traj.pdb", - "spc2-traj.g96" -}; + "spc2-traj.xtc", "spc2-traj.gro", + "spc2-traj.pdb", "spc2-traj.g96" }; INSTANTIATE_TEST_CASE_P(NoFatalErrorWhenWritingFrom, TrjconvWithIndexGroupSubset, - ::testing::ValuesIn(trajectoryFileNames)); + ::testing::ValuesIn(trajectoryFileNames)); -class TrjconvWithoutTopologyFile : public gmx::test::CommandLineTestBase, - public ::testing::WithParamInterface +class TrjconvWithoutTopologyFile : + public gmx::test::CommandLineTestBase, + public ::testing::WithParamInterface { - public: - void runTest(const char *fileName) - { - auto &cmdline = commandLine(); - - setInputFile("-f", fileName); - setInputFile("-n", "spc2.ndx"); - setOutputFile("-o", "spc-traj.trr", gmx::test::NoTextMatch()); - - gmx::test::StdioTestHelper stdioHelper(&fileManager()); - stdioHelper.redirectStringToStdin("SecondWaterMolecule\n"); - - /* As mentioned above, the tests don't check much besides - * that trjconv does not crash. - */ - ASSERT_EQ(0, gmx_trjconv(cmdline.argc(), cmdline.argv())); - } +public: + void runTest(const char* fileName) + { + auto& cmdline = commandLine(); + + setInputFile("-f", fileName); + setInputFile("-n", "spc2.ndx"); + setOutputFile("-o", "spc-traj.trr", gmx::test::NoTextMatch()); + + gmx::test::StdioTestHelper stdioHelper(&fileManager()); + stdioHelper.redirectStringToStdin("SecondWaterMolecule\n"); + + /* As mentioned above, the tests don't check much besides + * that trjconv does not crash. + */ + ASSERT_EQ(0, gmx_trjconv(cmdline.argc(), cmdline.argv())); + } }; TEST_P(TrjconvWithoutTopologyFile, WithDifferentInputFormats) @@ -134,5 +132,5 @@ TEST_P(TrjconvWithoutTopologyFile, WithDifferentInputFormats) INSTANTIATE_TEST_CASE_P(NoFatalErrorWhenWritingFrom, TrjconvWithoutTopologyFile, - ::testing::ValuesIn(trajectoryFileNames)); + ::testing::ValuesIn(trajectoryFileNames)); } // namespace diff --git a/src/gromacs/tools/trjcat.cpp b/src/gromacs/tools/trjcat.cpp index 781608e3d7..e5a45c8f04 100644 --- a/src/gromacs/tools/trjcat.cpp +++ b/src/gromacs/tools/trjcat.cpp @@ -66,20 +66,21 @@ #define TIME_EXPLICIT 0 #define TIME_CONTINUE 1 -#define TIME_LAST 2 +#define TIME_LAST 2 #ifndef FLT_MAX -#define FLT_MAX 1e36 +# define FLT_MAX 1e36 #endif #define FLAGS (TRX_READ_X | TRX_READ_V | TRX_READ_F) static void scan_trj_files(gmx::ArrayRef files, - real *readtime, - real *timestep, int imax, - const gmx_output_env_t *oenv) + real* readtime, + real* timestep, + int imax, + const gmx_output_env_t* oenv) { /* Check start time of all files */ int natoms = 0; - t_trxstatus *status; + t_trxstatus* status; t_trxframe fr; bool ok; @@ -89,7 +90,7 @@ static void scan_trj_files(gmx::ArrayRef files, if (!ok) { - gmx_fatal(FARGS, "\nCouldn't read frame from file." ); + gmx_fatal(FARGS, "\nCouldn't read frame from file."); } if (fr.bTime) { @@ -111,16 +112,14 @@ static void scan_trj_files(gmx::ArrayRef files, { if (natoms != fr.natoms) { - gmx_fatal(FARGS, "\nDifferent numbers of atoms (%d/%d) in files", - natoms, fr.natoms); + gmx_fatal(FARGS, "\nDifferent numbers of atoms (%d/%d) in files", natoms, fr.natoms); } } else { if (fr.natoms <= imax) { - gmx_fatal(FARGS, "\nNot enough atoms (%d) for index group (%d)", - fr.natoms, imax); + gmx_fatal(FARGS, "\nNot enough atoms (%d) for index group (%d)", fr.natoms, imax); } } } @@ -149,10 +148,9 @@ static void scan_trj_files(gmx::ArrayRef files, } } fprintf(stderr, "\n"); - } -static void sort_files(gmx::ArrayRef files, real *settime) +static void sort_files(gmx::ArrayRef files, real* settime) { for (gmx::index i = 0; i < files.ssize(); i++) { @@ -175,17 +173,22 @@ static void sort_files(gmx::ArrayRef files, real *settime) } static void edit_files(gmx::ArrayRef files, - real *readtime, real *timestep, - real *settime, int *cont_type, gmx_bool bSetTime, - gmx_bool bSort, const gmx_output_env_t *oenv) + real* readtime, + real* timestep, + real* settime, + int* cont_type, + gmx_bool bSetTime, + gmx_bool bSort, + const gmx_output_env_t* oenv) { gmx_bool ok; char inputstring[STRLEN], *chptr; - auto timeUnit = output_env_get_time_unit(oenv); + auto timeUnit = output_env_get_time_unit(oenv); if (bSetTime) { - fprintf(stderr, "\n\nEnter the new start time (%s) for each file.\n" + fprintf(stderr, + "\n\nEnter the new start time (%s) for each file.\n" "There are two special options, both disable sorting:\n\n" "c (continue) - The start time is taken from the end\n" "of the previous file. Use it when your continuation run\n" @@ -196,8 +199,7 @@ static void edit_files(gmx::ArrayRef files, "since this takes possible overlap into account.\n\n", timeUnit.c_str()); - fprintf( - stderr, + fprintf(stderr, " File Current start (%s) New start (%s)\n" "---------------------------------------------------------\n", timeUnit.c_str(), timeUnit.c_str()); @@ -211,10 +213,10 @@ static void edit_files(gmx::ArrayRef files, { if (nullptr == fgets(inputstring, STRLEN - 1, stdin)) { - gmx_fatal(FARGS, "Error reading user input" ); + gmx_fatal(FARGS, "Error reading user input"); } - inputstring[std::strlen(inputstring)-1] = 0; + inputstring[std::strlen(inputstring) - 1] = 0; if (inputstring[0] == 'c' || inputstring[0] == 'C') { @@ -223,8 +225,7 @@ static void edit_files(gmx::ArrayRef files, ok = TRUE; settime[i] = FLT_MAX; } - else if (inputstring[0] == 'l' || - inputstring[0] == 'L') + else if (inputstring[0] == 'l' || inputstring[0] == 'L') { cont_type[i] = TIME_LAST; bSort = FALSE; @@ -233,12 +234,13 @@ static void edit_files(gmx::ArrayRef files, } else { - settime[i] = strtod(inputstring, &chptr)* - output_env_get_time_invfactor(oenv); + settime[i] = strtod(inputstring, &chptr) * output_env_get_time_invfactor(oenv); if (chptr == inputstring) { - fprintf(stderr, "'%s' not recognized as a floating point number, 'c' or 'l'. " - "Try again: ", inputstring); + fprintf(stderr, + "'%s' not recognized as a floating point number, 'c' or 'l'. " + "Try again: ", + inputstring); } else { @@ -246,8 +248,7 @@ static void edit_files(gmx::ArrayRef files, ok = TRUE; } } - } - while (!ok); + } while (!ok); } if (cont_type[0] != TIME_EXPLICIT) { @@ -271,7 +272,8 @@ static void edit_files(gmx::ArrayRef files, sort_files(files, settime); } /* Write out the new order and start times */ - fprintf(stderr, "\nSummary of files and start times used:\n\n" + fprintf(stderr, + "\nSummary of files and start times used:\n\n" " File Start time Time step\n" "---------------------------------------------------------\n"); for (gmx::index i = 0; i < files.ssize(); i++) @@ -279,12 +281,10 @@ static void edit_files(gmx::ArrayRef files, switch (cont_type[i]) { case TIME_EXPLICIT: - fprintf(stderr, "%25s %10.3f %s %10.3f %s", - files[i].c_str(), + fprintf(stderr, "%25s %10.3f %s %10.3f %s", files[i].c_str(), output_env_conv_time(oenv, settime[i]), timeUnit.c_str(), output_env_conv_time(oenv, timestep[i]), timeUnit.c_str()); - if (i > 0 && - cont_type[i-1] == TIME_EXPLICIT && settime[i] == settime[i-1]) + if (i > 0 && cont_type[i - 1] == TIME_EXPLICIT && settime[i] == settime[i - 1]) { fprintf(stderr, " WARNING: same Start time as previous"); } @@ -294,8 +294,7 @@ static void edit_files(gmx::ArrayRef files, fprintf(stderr, "%25s Continue from last file\n", files[i].c_str()); break; case TIME_LAST: - fprintf(stderr, "%25s Change by same amount as last file\n", - files[i].c_str()); + fprintf(stderr, "%25s Change by same amount as last file\n", files[i].c_str()); break; } } @@ -307,15 +306,21 @@ static void edit_files(gmx::ArrayRef files, } static void do_demux(gmx::ArrayRef inFiles, - gmx::ArrayRef outFiles, int nval, - real **value, real *time, real dt_remd, int isize, - int index[], real dt, const gmx_output_env_t *oenv) + gmx::ArrayRef outFiles, + int nval, + real** value, + real* time, + real dt_remd, + int isize, + int index[], + real dt, + const gmx_output_env_t* oenv) { int k, natoms; t_trxstatus **fp_in, **fp_out; gmx_bool bCont, *bSet; real t, first_time = 0; - t_trxframe *trx; + t_trxframe* trx; snew(fp_in, inFiles.size()); snew(trx, inFiles.size()); @@ -324,8 +329,7 @@ static void do_demux(gmx::ArrayRef inFiles, t = -1; for (gmx::index i = 0; i < inFiles.ssize(); i++) { - read_first_frame(oenv, &(fp_in[i]), inFiles[i].c_str(), &(trx[i]), - TRX_NEED_X); + read_first_frame(oenv, &(fp_in[i]), inFiles[i].c_str(), &(trx[i]), TRX_NEED_X); if (natoms == -1) { natoms = trx[i].natoms; @@ -333,7 +337,8 @@ static void do_demux(gmx::ArrayRef inFiles, } else if (natoms != trx[i].natoms) { - gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", inFiles[i].c_str(), trx[i].natoms, natoms); + gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", + inFiles[i].c_str(), trx[i].natoms, natoms); } if (t == -1) { @@ -341,7 +346,8 @@ static void do_demux(gmx::ArrayRef inFiles, } else if (t != trx[i].time) { - gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", inFiles[i].c_str(), trx[i].time, t); + gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", + inFiles[i].c_str(), trx[i].time, t); } } @@ -357,7 +363,7 @@ static void do_demux(gmx::ArrayRef inFiles, } do { - while ((k+1 < nval) && ((trx[0].time - time[k+1]) > dt_remd*0.1)) + while ((k + 1 < nval) && ((trx[0].time - time[k + 1]) > dt_remd * 0.1)) { k++; } @@ -375,8 +381,7 @@ static void do_demux(gmx::ArrayRef inFiles, range_check(j, 0, inFiles.size()); if (bSet[j]) { - gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f", - j, trx[0].time); + gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f", j, trx[0].time); } bSet[j] = TRUE; @@ -398,8 +403,7 @@ static void do_demux(gmx::ArrayRef inFiles, { bCont = bCont && read_next_frame(oenv, fp_in[i], &trx[i]); } - } - while (bCont); + } while (bCont); for (gmx::index i = 0; i < inFiles.ssize(); i++) { @@ -408,10 +412,9 @@ static void do_demux(gmx::ArrayRef inFiles, } } -int gmx_trjcat(int argc, char *argv[]) +int gmx_trjcat(int argc, char* argv[]) { - const char *desc[] = - { + const char* desc[] = { "[THISMODULE] concatenates several input trajectory files in sorted order. ", "In case of double time frames the one in the later file is used. ", "By specifying [TT]-settime[tt] you will be asked for the start time ", @@ -449,61 +452,57 @@ int gmx_trjcat(int argc, char *argv[]) static real end = -1; static real dt = 0; - t_pargs - pa[] = - { - { "-b", FALSE, etTIME, - { &begin }, "First time to use (%t)" }, - { "-e", FALSE, etTIME, - { &end }, "Last time to use (%t)" }, - { "-dt", FALSE, etTIME, - { &dt }, "Only write frame when t MOD dt = first time (%t)" }, - { "-settime", FALSE, etBOOL, - { &bSetTime }, "Change starting time interactively" }, - { "-sort", FALSE, etBOOL, - { &bSort }, "Sort trajectory files (not frames)" }, - { "-keeplast", FALSE, etBOOL, - { &bKeepLast }, "Keep overlapping frames at end of trajectory" }, - { "-overwrite", FALSE, etBOOL, - { &bOverwrite }, "Overwrite overlapping frames during appending" }, - { "-cat", FALSE, etBOOL, - { &bCat }, "Do not discard double time frames" } + t_pargs pa[] = { + { "-b", FALSE, etTIME, { &begin }, "First time to use (%t)" }, + { "-e", FALSE, etTIME, { &end }, "Last time to use (%t)" }, + { "-dt", FALSE, etTIME, { &dt }, "Only write frame when t MOD dt = first time (%t)" }, + { "-settime", FALSE, etBOOL, { &bSetTime }, "Change starting time interactively" }, + { "-sort", FALSE, etBOOL, { &bSort }, "Sort trajectory files (not frames)" }, + { "-keeplast", + FALSE, + etBOOL, + { &bKeepLast }, + "Keep overlapping frames at end of trajectory" }, + { "-overwrite", + FALSE, + etBOOL, + { &bOverwrite }, + "Overwrite overlapping frames during appending" }, + { "-cat", FALSE, etBOOL, { &bCat }, "Do not discard double time frames" } }; #define npargs asize(pa) int ftpin, i, frame, frame_out; - t_trxstatus *status, *trxout = nullptr; + t_trxstatus * status, *trxout = nullptr; real t_corr; t_trxframe fr, frout; int n_append; gmx_bool bNewFile, bIndex, bWrite; - int *cont_type; - real *readtime, *timest, *settime; - real first_time = 0, lasttime = 0, last_ok_t = -1, timestep; + int* cont_type; + real * readtime, *timest, *settime; + real first_time = 0, lasttime = 0, last_ok_t = -1, timestep; gmx_bool lastTimeSet = FALSE; real last_frame_time, searchtime; int isize = 0, j; - int *index = nullptr, imax; - char *grpname; - real **val = nullptr, *t = nullptr, dt_remd; + int * index = nullptr, imax; + char* grpname; + real ** val = nullptr, *t = nullptr, dt_remd; int n, nset, ftpout = -1, prevEndStep = 0, filetype; gmx_off_t fpos; - gmx_output_env_t *oenv; - t_filenm fnm[] = - { - { efTRX, "-f", nullptr, ffRDMULT }, - { efTRO, "-o", nullptr, ffWRMULT }, - { efNDX, "-n", "index", ffOPTRD }, - { efXVG, "-demux", "remd", ffOPTRD } - }; + gmx_output_env_t* oenv; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffRDMULT }, + { efTRO, "-o", nullptr, ffWRMULT }, + { efNDX, "-n", "index", ffOPTRD }, + { efXVG, "-demux", "remd", ffOPTRD } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, PCA_TIME_UNIT, NFILE, fnm, - asize(pa), pa, asize(desc), desc, 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_TIME_UNIT, NFILE, fnm, asize(pa), pa, asize(desc), desc, + 0, nullptr, &oenv)) { return 0; } - fprintf(stdout, "Note that major changes are planned in future for " + fprintf(stdout, + "Note that major changes are planned in future for " "trjcat, to improve usability and utility."); auto timeUnit = output_env_get_time_unit(oenv); @@ -528,10 +527,8 @@ int gmx_trjcat(int argc, char *argv[]) { nset = 0; dt_remd = 0; - val = read_xvg_time(opt2fn("-demux", NFILE, fnm), TRUE, - opt2parg_bSet("-b", npargs, pa), begin, - opt2parg_bSet("-e", npargs, pa), end, 1, &nset, &n, - &dt_remd, &t); + val = read_xvg_time(opt2fn("-demux", NFILE, fnm), TRUE, opt2parg_bSet("-b", npargs, pa), + begin, opt2parg_bSet("-e", npargs, pa), end, 1, &nset, &n, &dt_remd, &t); printf("Read %d sets of %d points, dt = %g\n\n", nset, n, dt_remd); if (debug) { @@ -551,12 +548,13 @@ int gmx_trjcat(int argc, char *argv[]) gmx::ArrayRef inFiles = opt2fns("-f", NFILE, fnm); if (inFiles.empty()) { - gmx_fatal(FARGS, "No input files!" ); + gmx_fatal(FARGS, "No input files!"); } if (bDeMux && ssize(inFiles) != nset) { - gmx_fatal(FARGS, "You have specified %td files and %d entries in the demux table", inFiles.ssize(), nset); + gmx_fatal(FARGS, "You have specified %td files and %d entries in the demux table", + inFiles.ssize(), nset); } ftpin = fn2ftp(inFiles[0].c_str()); @@ -566,7 +564,7 @@ int gmx_trjcat(int argc, char *argv[]) gmx_fatal(FARGS, "gmx trjcat can only handle binary trajectory formats (trr, xtc, tng)"); } - for (const std::string &inFile : inFiles) + for (const std::string& inFile : inFiles) { if (ftpin != fn2ftp(inFile.c_str())) { @@ -581,11 +579,13 @@ int gmx_trjcat(int argc, char *argv[]) } if ((outFiles.size() > 1) && !bDeMux) { - gmx_fatal(FARGS, "Don't know what to do with more than 1 output file if not demultiplexing"); + gmx_fatal(FARGS, + "Don't know what to do with more than 1 output file if not demultiplexing"); } else if (bDeMux && ssize(outFiles) != nset && outFiles.size() != 1) { - gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %td", nset, outFiles.ssize()); + gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %td", nset, + outFiles.ssize()); } if (bDeMux) { @@ -610,15 +610,14 @@ int gmx_trjcat(int argc, char *argv[]) snew(settime, inFiles.size() + 1); snew(cont_type, inFiles.size() + 1); auto inFilesEdited = gmx::copyOf(inFiles); - edit_files(inFilesEdited, readtime, timest, settime, cont_type, bSetTime, bSort, - oenv); + edit_files(inFilesEdited, readtime, timest, settime, cont_type, bSetTime, bSort, oenv); /* Check whether the output file is amongst the input files * This has to be done after sorting etc. */ - const char *out_file = outFiles[0].c_str(); - ftpout = fn2ftp(out_file); - n_append = -1; + const char* out_file = outFiles[0].c_str(); + ftpout = fn2ftp(out_file); + n_append = -1; for (size_t i = 0; i < inFilesEdited.size() && n_append == -1; i++) { if (std::strcmp(inFilesEdited[i].c_str(), out_file) == 0) @@ -628,8 +627,7 @@ int gmx_trjcat(int argc, char *argv[]) } if (n_append == 0) { - fprintf(stderr, "Will append to %s rather than creating a new file\n", - out_file); + fprintf(stderr, "Will append to %s rather than creating a new file\n", out_file); } else if (n_append != -1) { @@ -657,13 +655,14 @@ int gmx_trjcat(int argc, char *argv[]) } if (bIndex) { - trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr, - inFilesEdited[0].c_str(), isize, nullptr, gmx::arrayRefFromArray(index, isize), grpname); + trxout = trjtools_gmx_prepare_tng_writing( + out_file, 'w', nullptr, inFilesEdited[0].c_str(), isize, nullptr, + gmx::arrayRefFromArray(index, isize), grpname); } else { - trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr, - inFilesEdited[0].c_str(), -1, nullptr, {}, nullptr); + trxout = trjtools_gmx_prepare_tng_writing( + out_file, 'w', nullptr, inFilesEdited[0].c_str(), -1, nullptr, {}, nullptr); } } else @@ -674,7 +673,7 @@ int gmx_trjcat(int argc, char *argv[]) } else { - t_fileio *stfio; + t_fileio* stfio; if (!read_first_frame(oenv, &status, out_file, &fr, FLAGS)) { @@ -684,7 +683,8 @@ int gmx_trjcat(int argc, char *argv[]) stfio = trx_get_fileio(status); if (!bKeepLast && !bOverwrite) { - fprintf(stderr, "\n\nWARNING: Appending without -overwrite implies -keeplast " + fprintf(stderr, + "\n\nWARNING: Appending without -overwrite implies -keeplast " "between the first two files. \n" "If the trajectories have an overlap and have not been written binary \n" "reproducible this will produce an incorrect trajectory!\n\n"); @@ -700,10 +700,7 @@ int gmx_trjcat(int argc, char *argv[]) } else { - while (read_next_frame(oenv, status, &fr)) - { - ; - } + while (read_next_frame(oenv, status, &fr)) {} lasttime = fr.time; } lastTimeSet = TRUE; @@ -715,17 +712,17 @@ int gmx_trjcat(int argc, char *argv[]) { if (gmx_fio_getftp(stfio) != efXTC) { - gmx_fatal(FARGS, "Overwrite only supported for XTC." ); + gmx_fatal(FARGS, "Overwrite only supported for XTC."); } last_frame_time = trx_get_time_of_final_frame(status); /* xtc_seek_time broken for trajectories containing only 1 or 2 frames * or when seek time = 0 */ - if (inFilesEdited.size() > 1 && settime[1] < last_frame_time+timest[0]*0.5) + if (inFilesEdited.size() > 1 && settime[1] < last_frame_time + timest[0] * 0.5) { /* Jump to one time-frame before the start of next * trajectory file */ - searchtime = settime[1]-timest[0]*1.25; + searchtime = settime[1] - timest[0] * 1.25; } else { @@ -736,7 +733,7 @@ int gmx_trjcat(int argc, char *argv[]) gmx_fatal(FARGS, "Error seeking to append position."); } read_next_frame(oenv, status, &fr); - if (std::abs(searchtime - fr.time) > timest[0]*0.5) + if (std::abs(searchtime - fr.time) > timest[0] * 0.5) { gmx_fatal(FARGS, "Error seeking: attempted to seek to %f but got %f.", searchtime, fr.time); @@ -777,15 +774,15 @@ int gmx_trjcat(int argc, char *argv[]) { if (cont_type[i] == TIME_CONTINUE) { - begin = frout.time; - begin += 0.5*timestep; + begin = frout.time; + begin += 0.5 * timestep; settime[i] = frout.time; cont_type[i] = TIME_EXPLICIT; } else if (cont_type[i] == TIME_LAST) { - begin = frout.time; - begin += 0.5*timestep; + begin = frout.time; + begin += 0.5 * timestep; } /* Or, if the time in the next part should be changed by the * same amount, start at half a timestep from the last time @@ -798,14 +795,14 @@ int gmx_trjcat(int argc, char *argv[]) /* Or, if time is set explicitly, we check for overlap/gap */ if (cont_type[i] == TIME_EXPLICIT) { - if (i < inFilesEdited.size() && - frout.time < settime[i] - 1.5*timestep) + if (i < inFilesEdited.size() && frout.time < settime[i] - 1.5 * timestep) { - fprintf(stderr, "WARNING: Frames around t=%f %s have a different " + fprintf(stderr, + "WARNING: Frames around t=%f %s have a different " "spacing than the rest,\n" "might be a gap or overlap that couldn't be corrected " - "automatically.\n", output_env_conv_time(oenv, frout.time), - timeUnit.c_str()); + "automatically.\n", + output_env_conv_time(oenv, frout.time), timeUnit.c_str()); } } } @@ -824,7 +821,7 @@ int gmx_trjcat(int argc, char *argv[]) if (cont_type[i] == TIME_EXPLICIT) { - t_corr = settime[i]-fr.time; + t_corr = settime[i] - fr.time; } /* t_corr is the amount we want to change the time. * If the user has chosen not to change the time for @@ -856,7 +853,7 @@ int gmx_trjcat(int argc, char *argv[]) frout.step += prevEndStep; } /* quit if we have reached the end of what should be written */ - if ((end > 0) && (frout.time > end+GMX_REAL_EPS)) + if ((end > 0) && (frout.time > end + GMX_REAL_EPS)) { i = inFilesEdited.size(); break; @@ -871,14 +868,14 @@ int gmx_trjcat(int argc, char *argv[]) /* write till last frame of this traj and skip first frame(s) of next traj */ { - bWrite = ( frout.time > lasttime+0.5*timestep ); + bWrite = (frout.time > lasttime + 0.5 * timestep); } else /* write till first frame of next traj */ { - bWrite = ( frout.time < settime[i+1]-0.5*timestep ); + bWrite = (frout.time < settime[i + 1] - 0.5 * timestep); } - if (bWrite && (frout.time >= begin) ) + if (bWrite && (frout.time >= begin)) { frame++; if (frame_out == -1) @@ -893,33 +890,31 @@ int gmx_trjcat(int argc, char *argv[]) last_ok_t = frout.time; if (bNewFile) { - fprintf(stderr, "\nContinue writing frames from %s t=%g %s, " + fprintf(stderr, + "\nContinue writing frames from %s t=%g %s, " "frame=%d \n", inFilesEdited[i].c_str(), - output_env_conv_time(oenv, frout.time), timeUnit.c_str(), - frame); + output_env_conv_time(oenv, frout.time), timeUnit.c_str(), frame); bNewFile = FALSE; } if (bIndex) { - write_trxframe_indexed(trxout, &frout, isize, index, - nullptr); + write_trxframe_indexed(trxout, &frout, isize, index, nullptr); } else { write_trxframe(trxout, &frout, nullptr); } - if ( ((frame % 10) == 0) || (frame < 10) ) + if (((frame % 10) == 0) || (frame < 10)) { - fprintf(stderr, " -> frame %6d time %8.3f %s \r", - frame_out, output_env_conv_time(oenv, frout.time), timeUnit.c_str()); + fprintf(stderr, " -> frame %6d time %8.3f %s \r", frame_out, + output_env_conv_time(oenv, frout.time), timeUnit.c_str()); fflush(stderr); } } } - } - while (read_next_frame(oenv, status, &fr)); + } while (read_next_frame(oenv, status, &fr)); close_trx(status); } @@ -927,8 +922,8 @@ int gmx_trjcat(int argc, char *argv[]) { close_trx(trxout); } - fprintf(stderr, "\nLast frame written was %d, time %f %s\n", - frame, output_env_conv_time(oenv, last_ok_t), timeUnit.c_str()); + fprintf(stderr, "\nLast frame written was %d, time %f %s\n", frame, + output_env_conv_time(oenv, last_ok_t), timeUnit.c_str()); } return 0; diff --git a/src/gromacs/tools/trjcat.h b/src/gromacs/tools/trjcat.h index 5cd756a6ad..cbbf005a3e 100644 --- a/src/gromacs/tools/trjcat.h +++ b/src/gromacs/tools/trjcat.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_trjcat(int argc, char *argv[]); +int gmx_trjcat(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/trjconv.cpp b/src/gromacs/tools/trjconv.cpp index f560ba3902..f222e4ead8 100644 --- a/src/gromacs/tools/trjconv.cpp +++ b/src/gromacs/tools/trjconv.cpp @@ -74,8 +74,7 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static void mk_filenm(char *base, const char *ext, int ndigit, int file_nr, - char out_file[]) +static void mk_filenm(char* base, const char* ext, int ndigit, int file_nr, char out_file[]) { char nbuf[128]; int nd = 0, fnr; @@ -86,19 +85,18 @@ static void mk_filenm(char *base, const char *ext, int ndigit, int file_nr, { fnr /= 10; nd++; - } - while (fnr > 0); + } while (fnr > 0); if (nd < ndigit) { - std::strncat(out_file, "00000000000", ndigit-nd); + std::strncat(out_file, "00000000000", ndigit - nd); } sprintf(nbuf, "%d.", file_nr); std::strcat(out_file, nbuf); std::strcat(out_file, ext); } -static void check_trr(const char *fn) +static void check_trr(const char* fn) { if (fn2ftp(fn) != efTRR) { @@ -106,10 +104,10 @@ static void check_trr(const char *fn) } } -static void do_trunc(const char *fn, real t0) +static void do_trunc(const char* fn, real t0) { - t_fileio *in; - FILE *fp; + t_fileio* in; + FILE* fp; gmx_bool bStop, bOK; gmx_trr_header_t sh; gmx_off_t fpos; @@ -125,8 +123,8 @@ static void do_trunc(const char *fn, real t0) /* Check whether this is a .trr file */ check_trr(fn); - in = gmx_trr_open(fn, "r"); - fp = gmx_fio_getfp(in); + in = gmx_trr_open(fn, "r"); + fp = gmx_fio_getfp(in); if (fp == nullptr) { fprintf(stderr, "Sorry, can not trunc %s, truncation of this filetype is not supported\n", fn); @@ -150,7 +148,8 @@ static void do_trunc(const char *fn, real t0) } if (bStop) { - fprintf(stderr, "Do you REALLY want to truncate this trajectory (%s) at:\n" + fprintf(stderr, + "Do you REALLY want to truncate this trajectory (%s) at:\n" "frame %d, time %g, bytes %ld ??? (type YES if so)\n", fn, j, t, static_cast(fpos)); if (1 != scanf("%s", yesno)) @@ -199,29 +198,25 @@ static void do_trunc(const char *fn, real t0) * molecule information will generally be present if the input TNG * file was written by a GROMACS tool, this seems like reasonable * behaviour. */ -static std::unique_ptr -read_mtop_for_tng(const char *tps_file, - const char *input_file, - const char *output_file) +static std::unique_ptr read_mtop_for_tng(const char* tps_file, + const char* input_file, + const char* output_file) { std::unique_ptr mtop; - if (fn2bTPX(tps_file) && - efTNG != fn2ftp(input_file) && - efTNG == fn2ftp(output_file)) + if (fn2bTPX(tps_file) && efTNG != fn2ftp(input_file) && efTNG == fn2ftp(output_file)) { int temp_natoms = -1; - mtop = std::make_unique(); - read_tpx(tps_file, nullptr, nullptr, &temp_natoms, - nullptr, nullptr, mtop.get()); + mtop = std::make_unique(); + read_tpx(tps_file, nullptr, nullptr, &temp_natoms, nullptr, nullptr, mtop.get()); } return mtop; } -int gmx_trjconv(int argc, char *argv[]) +int gmx_trjconv(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] can convert trajectory files in many ways:", "", "* from one format to another", @@ -257,7 +252,8 @@ int gmx_trjconv(int argc, char *argv[]) "[REF].trr[ref], [REF].gro[ref] and [TT].g96[tt] files.[PAR]", "Option [TT]-sep[tt] can be used to write every frame to a separate", - "[TT].gro, .g96[tt] or [REF].pdb[ref] file. By default, all frames all written to one file.", + "[TT].gro, .g96[tt] or [REF].pdb[ref] file. By default, all frames all written to ", + "one file.", "[REF].pdb[ref] files with all frames concatenated can be viewed with", "[TT]rasmol -nmrpdb[tt].[PAR]", @@ -357,7 +353,7 @@ int gmx_trjconv(int argc, char *argv[]) "will not be written." }; - int pbc_enum; + int pbc_enum; enum { epSel, @@ -370,116 +366,105 @@ int gmx_trjconv(int argc, char *argv[]) epWhole, epNR }; - const char *pbc_opt[epNR + 1] = - { - nullptr, "none", "mol", "res", "atom", "nojump", "cluster", "whole", - nullptr - }; + const char* pbc_opt[epNR + 1] = { nullptr, "none", "mol", "res", "atom", + "nojump", "cluster", "whole", nullptr }; int unitcell_enum; - const char *unitcell_opt[euNR+1] = - { nullptr, "rect", "tric", "compact", nullptr }; + const char* unitcell_opt[euNR + 1] = { nullptr, "rect", "tric", "compact", nullptr }; enum { - ecSel, ecTric, ecRect, ecZero, ecNR + ecSel, + ecTric, + ecRect, + ecZero, + ecNR }; - const char *center_opt[ecNR+1] = - { nullptr, "tric", "rect", "zero", nullptr }; + const char* center_opt[ecNR + 1] = { nullptr, "tric", "rect", "zero", nullptr }; int ecenter; - int fit_enum; + int fit_enum; enum { - efSel, efNone, efFit, efFitXY, efReset, efResetXY, efPFit, efNR - }; - const char *fit[efNR + 1] = - { - nullptr, "none", "rot+trans", "rotxy+transxy", "translation", "transxy", - "progressive", nullptr + efSel, + efNone, + efFit, + efFitXY, + efReset, + efResetXY, + efPFit, + efNR }; - - static gmx_bool bSeparate = FALSE, bVels = TRUE, bForce = FALSE, bCONECT = FALSE; - static gmx_bool bCenter = FALSE; - static int skip_nr = 1, ndec = 3, nzero = 0; - static real tzero = 0, delta_t = 0, timestep = 0, ttrunc = -1, tdump = -1, split_t = 0; - static rvec newbox = {0, 0, 0}, shift = {0, 0, 0}, trans = {0, 0, 0}; - static char *exec_command = nullptr; - static real dropunder = 0, dropover = 0; - static gmx_bool bRound = FALSE; - - t_pargs - pa[] = - { - { "-skip", FALSE, etINT, - { &skip_nr }, "Only write every nr-th frame" }, - { "-dt", FALSE, etTIME, - { &delta_t }, - "Only write frame when t MOD dt = first time (%t)" }, - { "-round", FALSE, etBOOL, - { &bRound }, "Round measurements to nearest picosecond"}, - { "-dump", FALSE, etTIME, - { &tdump }, "Dump frame nearest specified time (%t)" }, - { "-t0", FALSE, etTIME, - { &tzero }, - "Starting time (%t) (default: don't change)" }, - { "-timestep", FALSE, etTIME, - { ×tep }, - "Change time step between input frames (%t)" }, - { "-pbc", FALSE, etENUM, - { pbc_opt }, - "PBC treatment (see help text for full description)" }, - { "-ur", FALSE, etENUM, - { unitcell_opt }, "Unit-cell representation" }, - { "-center", FALSE, etBOOL, - { &bCenter }, "Center atoms in box" }, - { "-boxcenter", FALSE, etENUM, - { center_opt }, "Center for -pbc and -center" }, - { "-box", FALSE, etRVEC, - { newbox }, - "Size for new cubic box (default: read from input)" }, - { "-trans", FALSE, etRVEC, + const char* fit[efNR + 1] = { nullptr, "none", "rot+trans", "rotxy+transxy", + "translation", "transxy", "progressive", nullptr }; + + static gmx_bool bSeparate = FALSE, bVels = TRUE, bForce = FALSE, bCONECT = FALSE; + static gmx_bool bCenter = FALSE; + static int skip_nr = 1, ndec = 3, nzero = 0; + static real tzero = 0, delta_t = 0, timestep = 0, ttrunc = -1, tdump = -1, split_t = 0; + static rvec newbox = { 0, 0, 0 }, shift = { 0, 0, 0 }, trans = { 0, 0, 0 }; + static char* exec_command = nullptr; + static real dropunder = 0, dropover = 0; + static gmx_bool bRound = FALSE; + + t_pargs pa[] = { + { "-skip", FALSE, etINT, { &skip_nr }, "Only write every nr-th frame" }, + { "-dt", FALSE, etTIME, { &delta_t }, "Only write frame when t MOD dt = first time (%t)" }, + { "-round", FALSE, etBOOL, { &bRound }, "Round measurements to nearest picosecond" }, + { "-dump", FALSE, etTIME, { &tdump }, "Dump frame nearest specified time (%t)" }, + { "-t0", FALSE, etTIME, { &tzero }, "Starting time (%t) (default: don't change)" }, + { "-timestep", FALSE, etTIME, { ×tep }, "Change time step between input frames (%t)" }, + { "-pbc", FALSE, etENUM, { pbc_opt }, "PBC treatment (see help text for full description)" }, + { "-ur", FALSE, etENUM, { unitcell_opt }, "Unit-cell representation" }, + { "-center", FALSE, etBOOL, { &bCenter }, "Center atoms in box" }, + { "-boxcenter", FALSE, etENUM, { center_opt }, "Center for -pbc and -center" }, + { "-box", FALSE, etRVEC, { newbox }, "Size for new cubic box (default: read from input)" }, + { "-trans", + FALSE, + etRVEC, { trans }, "All coordinates will be translated by trans. This " "can advantageously be combined with -pbc mol -ur " "compact." }, - { "-shift", FALSE, etRVEC, - { shift }, - "All coordinates will be shifted by framenr*shift" }, - { "-fit", FALSE, etENUM, - { fit }, - "Fit molecule to ref structure in the structure file" }, - { "-ndec", FALSE, etINT, - { &ndec }, - "Number of decimal places to write to .xtc output" }, - { "-vel", FALSE, etBOOL, - { &bVels }, "Read and write velocities if possible" }, - { "-force", FALSE, etBOOL, - { &bForce }, "Read and write forces if possible" }, - { "-trunc", FALSE, etTIME, + { "-shift", FALSE, etRVEC, { shift }, "All coordinates will be shifted by framenr*shift" }, + { "-fit", FALSE, etENUM, { fit }, "Fit molecule to ref structure in the structure file" }, + { "-ndec", FALSE, etINT, { &ndec }, "Number of decimal places to write to .xtc output" }, + { "-vel", FALSE, etBOOL, { &bVels }, "Read and write velocities if possible" }, + { "-force", FALSE, etBOOL, { &bForce }, "Read and write forces if possible" }, + { "-trunc", + FALSE, + etTIME, { &ttrunc }, "Truncate input trajectory file after this time (%t)" }, - { "-exec", FALSE, etSTR, + { "-exec", + FALSE, + etSTR, { &exec_command }, "Execute command for every output frame with the " "frame number as argument" }, - { "-split", FALSE, etTIME, + { "-split", + FALSE, + etTIME, { &split_t }, "Start writing new file when t MOD split = first " "time (%t)" }, - { "-sep", FALSE, etBOOL, + { "-sep", + FALSE, + etBOOL, { &bSeparate }, "Write each frame to a separate .gro, .g96 or .pdb " "file" }, - { "-nzero", FALSE, etINT, + { "-nzero", + FALSE, + etINT, { &nzero }, "If the -sep flag is set, use these many digits " "for the file numbers and prepend zeros as needed" }, - { "-dropunder", FALSE, etREAL, - { &dropunder }, "Drop all frames below this value" }, - { "-dropover", FALSE, etREAL, - { &dropover }, "Drop all frames above this value" }, - { "-conect", FALSE, etBOOL, + { "-dropunder", FALSE, etREAL, { &dropunder }, "Drop all frames below this value" }, + { "-dropover", FALSE, etREAL, { &dropover }, "Drop all frames above this value" }, + { "-conect", + FALSE, + etBOOL, { &bCONECT }, "Add conect records when writing [REF].pdb[ref] files. Useful " "for visualization of non-standard molecules, e.g. " @@ -487,68 +472,61 @@ int gmx_trjconv(int argc, char *argv[]) }; #define NPA asize(pa) - FILE *out = nullptr; - t_trxstatus *trxout = nullptr; - t_trxstatus *trxin; - int file_nr; - t_trxframe fr, frout; - int flags; - rvec *xmem = nullptr, *vmem = nullptr, *fmem = nullptr; - rvec *xp = nullptr, x_shift, hbox; - real *w_rls = nullptr; - int m, i, d, frame, outframe, natoms, nout, ncent, newstep = 0, model_nr; + FILE* out = nullptr; + t_trxstatus* trxout = nullptr; + t_trxstatus* trxin; + int file_nr; + t_trxframe fr, frout; + int flags; + rvec * xmem = nullptr, *vmem = nullptr, *fmem = nullptr; + rvec * xp = nullptr, x_shift, hbox; + real* w_rls = nullptr; + int m, i, d, frame, outframe, natoms, nout, ncent, newstep = 0, model_nr; #define SKIP 10 - t_topology *top = nullptr; - gmx_conect gc = nullptr; - int ePBC = -1; - t_atoms *atoms = nullptr, useatoms; - matrix top_box; - int *index = nullptr, *cindex = nullptr; - char *grpnm = nullptr; - int *frindex, nrfri; - char *frname; - int ifit; - int *ind_fit; - char *gn_fit; - int ndrop = 0, ncol, drop0 = 0, drop1 = 0, dropuse = 0; - double **dropval; - real tshift = 0, dt = -1, prec; - gmx_bool bFit, bPFit, bReset; - int nfitdim; - gmx_rmpbc_t gpbc = nullptr; - gmx_bool bRmPBC, bPBCWhole, bPBCcomRes, bPBCcomMol, bPBCcomAtom, bPBC, bNoJump, bCluster; - gmx_bool bCopy, bDoIt, bIndex, bTDump, bSetTime, bTPS = FALSE, bDTset = FALSE; - gmx_bool bExec, bTimeStep = FALSE, bDumpFrame = FALSE, bSetXtcPrec, bNeedPrec; - gmx_bool bHaveFirstFrame, bHaveNextFrame, bSetBox, bSetUR, bSplit = FALSE; - gmx_bool bDropUnder = FALSE, bDropOver = FALSE, bTrans = FALSE; - gmx_bool bWriteFrame, bSplitHere; - const char *top_file, *in_file, *out_file = nullptr; - char out_file2[256], *charpt; - char *outf_base = nullptr; - const char *outf_ext = nullptr; - char top_title[256], timestr[32], stepstr[32], filemode[5]; - gmx_output_env_t *oenv; - - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTRO, "-o", nullptr, ffWRITE }, - { efTPS, nullptr, nullptr, ffOPTRD }, - { efNDX, nullptr, nullptr, ffOPTRD }, - { efNDX, "-fr", "frames", ffOPTRD }, - { efNDX, "-sub", "cluster", ffOPTRD }, - { efXVG, "-drop", "drop", ffOPTRD } - }; + t_topology* top = nullptr; + gmx_conect gc = nullptr; + int ePBC = -1; + t_atoms * atoms = nullptr, useatoms; + matrix top_box; + int * index = nullptr, *cindex = nullptr; + char* grpnm = nullptr; + int * frindex, nrfri; + char* frname; + int ifit; + int* ind_fit; + char* gn_fit; + int ndrop = 0, ncol, drop0 = 0, drop1 = 0, dropuse = 0; + double** dropval; + real tshift = 0, dt = -1, prec; + gmx_bool bFit, bPFit, bReset; + int nfitdim; + gmx_rmpbc_t gpbc = nullptr; + gmx_bool bRmPBC, bPBCWhole, bPBCcomRes, bPBCcomMol, bPBCcomAtom, bPBC, bNoJump, bCluster; + gmx_bool bCopy, bDoIt, bIndex, bTDump, bSetTime, bTPS = FALSE, bDTset = FALSE; + gmx_bool bExec, bTimeStep = FALSE, bDumpFrame = FALSE, bSetXtcPrec, bNeedPrec; + gmx_bool bHaveFirstFrame, bHaveNextFrame, bSetBox, bSetUR, bSplit = FALSE; + gmx_bool bDropUnder = FALSE, bDropOver = FALSE, bTrans = FALSE; + gmx_bool bWriteFrame, bSplitHere; + const char *top_file, *in_file, *out_file = nullptr; + char out_file2[256], *charpt; + char* outf_base = nullptr; + const char* outf_ext = nullptr; + char top_title[256], timestr[32], stepstr[32], filemode[5]; + gmx_output_env_t* oenv; + + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, { efTRO, "-o", nullptr, ffWRITE }, + { efTPS, nullptr, nullptr, ffOPTRD }, { efNDX, nullptr, nullptr, ffOPTRD }, + { efNDX, "-fr", "frames", ffOPTRD }, { efNDX, "-sub", "cluster", ffOPTRD }, + { efXVG, "-drop", "drop", ffOPTRD } }; #define NFILE asize(fnm) - if (!parse_common_args(&argc, argv, - PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | - PCA_TIME_UNIT, - NFILE, fnm, NPA, pa, asize(desc), desc, - 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW | PCA_TIME_UNIT, + NFILE, fnm, NPA, pa, asize(desc), desc, 0, nullptr, &oenv)) { return 0; } - fprintf(stdout, "Note that major changes are planned in future for " + fprintf(stdout, + "Note that major changes are planned in future for " "trjconv, to improve usability and utility.\n"); top_file = ftp2fn(efTPS, NFILE, fnm); @@ -594,11 +572,11 @@ int gmx_trjconv(int argc, char *argv[]) /* set and check option dependencies */ if (bPFit) { - bFit = TRUE; /* for pfit, fit *must* be set */ + bFit = TRUE; /* for pfit, fit *must* be set */ } if (bFit) { - bReset = TRUE; /* for fit, reset *must* be set */ + bReset = TRUE; /* for fit, reset *must* be set */ } nfitdim = 0; if (bFit || bReset) @@ -609,7 +587,7 @@ int gmx_trjconv(int argc, char *argv[]) if (bSetUR) { - if (!(bPBCcomRes || bPBCcomMol || bPBCcomAtom)) + if (!(bPBCcomRes || bPBCcomMol || bPBCcomAtom)) { fprintf(stderr, "WARNING: Option for unitcell representation (-ur %s)\n" @@ -620,10 +598,13 @@ int gmx_trjconv(int argc, char *argv[]) } if (bFit && bPBC) { - gmx_fatal(FARGS, "PBC condition treatment does not work together with rotational fit.\n" - "Please do the PBC condition treatment first and then run trjconv in a second step\n" + gmx_fatal(FARGS, + "PBC condition treatment does not work together with rotational fit.\n" + "Please do the PBC condition treatment first and then run trjconv in a " + "second step\n" "for the rotational fit.\n" - "First doing the rotational fit and then doing the PBC treatment gives incorrect\n" + "First doing the rotational fit and then doing the PBC treatment gives " + "incorrect\n" "results!"); } @@ -646,10 +627,9 @@ int gmx_trjconv(int argc, char *argv[]) if (bVels) { /* check if velocities are possible in input and output files */ - bVels = (ftp == efTRR || ftp == efGRO || - ftp == efG96 || ftp == efTNG) - && (ftpin == efTRR || ftpin == efGRO || - ftpin == efG96 || ftpin == efTNG || ftpin == efCPT); + bVels = (ftp == efTRR || ftp == efGRO || ftp == efG96 || ftp == efTNG) + && (ftpin == efTRR || ftpin == efGRO || ftpin == efG96 || ftpin == efTNG + || ftpin == efCPT); } if (bSeparate || bSplit) { @@ -658,14 +638,15 @@ int gmx_trjconv(int argc, char *argv[]) { gmx_fatal(FARGS, "Output file name '%s' does not contain a '.'", out_file); } - outf_base = gmx_strdup(out_file); + outf_base = gmx_strdup(out_file); outf_base[outf_ext - out_file] = '\0'; } bool bSubTraj = opt2bSet("-sub", NFILE, fnm); if (bSubTraj) { - gmx_fatal(FARGS, "The -sub option has been removed from gmx trjconv and is now part\n" + gmx_fatal(FARGS, + "The -sub option has been removed from gmx trjconv and is now part\n" "of gmx extract-cluster and does nothing here\n"); } @@ -678,9 +659,8 @@ int gmx_trjconv(int argc, char *argv[]) std::unique_ptr mtop = read_mtop_for_tng(top_file, in_file, out_file); /* Determine whether to read a topology */ - bTPS = (ftp2bSet(efTPS, NFILE, fnm) || - bRmPBC || bReset || bPBCcomMol || bCluster || - (ftp == efGRO) || (ftp == efPDB) || bCONECT); + bTPS = (ftp2bSet(efTPS, NFILE, fnm) || bRmPBC || bReset || bPBCcomMol || bCluster + || (ftp == efGRO) || (ftp == efPDB) || bCONECT); /* Determine if when can read index groups */ bIndex = (bIndex || bTPS); @@ -688,15 +668,15 @@ int gmx_trjconv(int argc, char *argv[]) if (bTPS) { snew(top, 1); - read_tps_conf(top_file, top, &ePBC, &xp, nullptr, top_box, - bReset || bPBCcomRes); + read_tps_conf(top_file, top, &ePBC, &xp, nullptr, top_box, bReset || bPBCcomRes); std::strncpy(top_title, *top->name, 255); top_title[255] = '\0'; atoms = &top->atoms; if (0 == top->mols.nr && (bCluster || bPBCcomMol)) { - gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option", pbc_opt[pbc_enum]); + gmx_fatal(FARGS, "Option -pbc %s requires a .tpr file for the -s option", + pbc_opt[pbc_enum]); } /* top_title is only used for gro and pdb, @@ -743,10 +723,8 @@ int gmx_trjconv(int argc, char *argv[]) /* get index groups etc. */ if (bReset) { - printf("Select group for %s fit\n", - bFit ? "least squares" : "translational"); - get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &ifit, &ind_fit, &gn_fit); + printf("Select group for %s fit\n", bFit ? "least squares" : "translational"); + get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit, &ind_fit, &gn_fit); if (bFit) { @@ -763,8 +741,7 @@ int gmx_trjconv(int argc, char *argv[]) else if (bCluster) { printf("Select group for clustering\n"); - get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &ifit, &ind_fit, &gn_fit); + get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ifit, &ind_fit, &gn_fit); } if (bIndex) @@ -772,12 +749,10 @@ int gmx_trjconv(int argc, char *argv[]) if (bCenter) { printf("Select group for centering\n"); - get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &ncent, &cindex, &grpnm); + get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &ncent, &cindex, &grpnm); } printf("Select group for output\n"); - get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), - 1, &nout, &index, &grpnm); + get_index(atoms, ftp2fn_null(efNDX, NFILE, fnm), 1, &nout, &index, &grpnm); } else { @@ -833,8 +808,7 @@ int gmx_trjconv(int argc, char *argv[]) fprintf(stderr, " %d time points\n", ndrop); if (ndrop == 0 || ncol < 2) { - gmx_fatal(FARGS, "Found no data points in %s", - opt2fn("-drop", NFILE, fnm)); + gmx_fatal(FARGS, "Found no data points in %s", opt2fn("-drop", NFILE, fnm)); } drop0 = 0; drop1 = 0; @@ -855,9 +829,9 @@ int gmx_trjconv(int argc, char *argv[]) useatoms.atom[i] = atoms->atom[index[i]]; if (atoms->havePdbInfo) { - useatoms.pdbinfo[i] = atoms->pdbinfo[index[i]]; + useatoms.pdbinfo[i] = atoms->pdbinfo[index[i]]; } - useatoms.nres = std::max(useatoms.nres, useatoms.atom[i].resind+1); + useatoms.nres = std::max(useatoms.nres, useatoms.atom[i].resind + 1); } useatoms.nr = nout; } @@ -883,17 +857,17 @@ int gmx_trjconv(int argc, char *argv[]) bHaveFirstFrame = read_first_frame(oenv, &trxin, in_file, &fr, flags); if (fr.bPrec) { - fprintf(stderr, "\nPrecision of %s is %g (nm)\n", in_file, 1/fr.prec); + fprintf(stderr, "\nPrecision of %s is %g (nm)\n", in_file, 1 / fr.prec); } if (bNeedPrec) { if (bSetXtcPrec || !fr.bPrec) { - fprintf(stderr, "\nSetting output precision to %g (nm)\n", 1/prec); + fprintf(stderr, "\nSetting output precision to %g (nm)\n", 1 / prec); } else { - fprintf(stderr, "Using output precision of %g (nm)\n", 1/prec); + fprintf(stderr, "Using output precision of %g (nm)\n", 1 / prec); } } @@ -911,7 +885,9 @@ int gmx_trjconv(int argc, char *argv[]) bDTset = TRUE; if (dt <= 0) { - fprintf(stderr, "Warning: Frame times are not incrementing - will dump first frame.\n"); + fprintf(stderr, + "Warning: Frame times are not incrementing - will dump first " + "frame.\n"); } } // Now close and reopen so we are at first frame again @@ -926,7 +902,7 @@ int gmx_trjconv(int argc, char *argv[]) if (bSetTime) { - tshift = tzero-fr.time; + tshift = tzero - fr.time; } else { @@ -944,7 +920,8 @@ int gmx_trjconv(int argc, char *argv[]) gmx_fatal(FARGS, "Index[%d] %d is larger than the number of atoms in the\n" "trajectory file (%d). There is a mismatch in the contents\n" - "of your -f, -s and/or -n files.", i, index[i]+1, natoms); + "of your -f, -s and/or -n files.", + i, index[i] + 1, natoms); } bCopy = bCopy || (i != index[i]); } @@ -955,14 +932,9 @@ int gmx_trjconv(int argc, char *argv[]) switch (ftp) { case efTNG: - trxout = trjtools_gmx_prepare_tng_writing(out_file, - filemode[0], - trxin, - nullptr, - nout, - mtop.get(), - gmx::arrayRefFromArray(index, nout), - grpnm); + trxout = trjtools_gmx_prepare_tng_writing( + out_file, filemode[0], trxin, nullptr, nout, mtop.get(), + gmx::arrayRefFromArray(index, nout), grpnm); break; case efXTC: case efTRR: @@ -980,8 +952,7 @@ int gmx_trjconv(int argc, char *argv[]) out = gmx_ffopen(out_file, filemode); } break; - default: - gmx_incons("Illegal output file format"); + default: gmx_incons("Illegal output file format"); } if (bCopy) @@ -998,10 +969,10 @@ int gmx_trjconv(int argc, char *argv[]) } /* Start the big loop over frames */ - file_nr = 0; - frame = 0; - outframe = 0; - model_nr = 0; + file_nr = 0; + frame = 0; + outframe = 0; + model_nr = 0; /* Main loop over frames */ do @@ -1061,7 +1032,7 @@ int gmx_trjconv(int argc, char *argv[]) // and we have overrun the frame time. Once we dump one // frame based on time we quit, so it does not matter // that this might be true for all subsequent frames too. - bDumpFrame = (fr.time > tdump-0.5*dt); + bDumpFrame = (fr.time > tdump - 0.5 * dt); } } else @@ -1074,7 +1045,7 @@ int gmx_trjconv(int argc, char *argv[]) { for (d = 0; d < DIM; d++) { - hbox[d] = 0.5*fr.box[d][d]; + hbox[d] = 0.5 * fr.box[d][d]; } for (i = 0; i < natoms; i++) { @@ -1082,18 +1053,18 @@ int gmx_trjconv(int argc, char *argv[]) { rvec_dec(fr.x[i], x_shift); } - for (m = DIM-1; m >= 0; m--) + for (m = DIM - 1; m >= 0; m--) { if (hbox[m] > 0) { - while (fr.x[i][m]-xp[i][m] <= -hbox[m]) + while (fr.x[i][m] - xp[i][m] <= -hbox[m]) { for (d = 0; d <= m; d++) { fr.x[i][d] += fr.box[m][d]; } } - while (fr.x[i][m]-xp[i][m] > hbox[m]) + while (fr.x[i][m] - xp[i][m] > hbox[m]) { for (d = 0; d <= m; d++) { @@ -1149,18 +1120,16 @@ int gmx_trjconv(int argc, char *argv[]) fprintf(debug, "dumping %d\n", frame); } - bWriteFrame = - ( ( !bTDump && (frindex == nullptr) && frame % skip_nr == 0 ) || bDumpFrame ); + bWriteFrame = ((!bTDump && (frindex == nullptr) && frame % skip_nr == 0) || bDumpFrame); if (bWriteFrame && (bDropUnder || bDropOver)) { - while (dropval[0][drop1] < fr.time && drop1+1 < ndrop) + while (dropval[0][drop1] < fr.time && drop1 + 1 < ndrop) { drop0 = drop1; drop1++; } - if (std::abs(dropval[0][drop0] - fr.time) - < std::abs(dropval[0][drop1] - fr.time)) + if (std::abs(dropval[0][drop0] - fr.time) < std::abs(dropval[0][drop1] - fr.time)) { dropuse = drop0; } @@ -1168,8 +1137,8 @@ int gmx_trjconv(int argc, char *argv[]) { dropuse = drop1; } - if ((bDropUnder && dropval[1][dropuse] < dropunder) || - (bDropOver && dropval[1][dropuse] > dropover)) + if ((bDropUnder && dropval[1][dropuse] < dropunder) + || (bDropOver && dropval[1][dropuse] > dropover)) { bWriteFrame = FALSE; } @@ -1188,7 +1157,7 @@ int gmx_trjconv(int argc, char *argv[]) /* calc new time */ if (bTimeStep) { - frout_time = tzero + frame*timestep; + frout_time = tzero + frame * timestep; } else if (bSetTime) { @@ -1198,7 +1167,8 @@ int gmx_trjconv(int argc, char *argv[]) if (bTDump) { fprintf(stderr, "\nDumping frame at t= %g %s\n", - output_env_conv_time(oenv, frout_time), output_env_get_time_unit(oenv).c_str()); + output_env_conv_time(oenv, frout_time), + output_env_get_time_unit(oenv).c_str()); } /* check for writing at each delta_t */ @@ -1212,18 +1182,18 @@ int gmx_trjconv(int argc, char *argv[]) else { /* round() is not C89 compatible, so we do this: */ - bDoIt = bRmod(std::floor(frout_time+0.5), std::floor(tzero+0.5), - std::floor(delta_t+0.5)); + bDoIt = bRmod(std::floor(frout_time + 0.5), std::floor(tzero + 0.5), + std::floor(delta_t + 0.5)); } } if (bDoIt || bTDump) { /* print sometimes */ - if ( ((outframe % SKIP) == 0) || (outframe < SKIP) ) + if (((outframe % SKIP) == 0) || (outframe < SKIP)) { - fprintf(stderr, " -> frame %6d time %8.3f \r", - outframe, output_env_conv_time(oenv, frout_time)); + fprintf(stderr, " -> frame %6d time %8.3f \r", outframe, + output_env_conv_time(oenv, frout_time)); fflush(stderr); } @@ -1259,7 +1229,8 @@ int gmx_trjconv(int argc, char *argv[]) } } - auto positionsArrayRef = gmx::arrayRefFromArray(reinterpret_cast(fr.x), natoms); + auto positionsArrayRef = + gmx::arrayRefFromArray(reinterpret_cast(fr.x), natoms); if (bPBCcomAtom) { switch (unitcell_enum) @@ -1271,21 +1242,19 @@ int gmx_trjconv(int argc, char *argv[]) put_atoms_in_triclinic_unitcell(ecenter, fr.box, positionsArrayRef); break; case euCompact: - put_atoms_in_compact_unitcell(ePBC, ecenter, fr.box, - positionsArrayRef); + put_atoms_in_compact_unitcell(ePBC, ecenter, fr.box, positionsArrayRef); break; } } if (bPBCcomRes) { - put_residue_com_in_box(unitcell_enum, ecenter, - natoms, atoms->atom, ePBC, fr.box, fr.x); + put_residue_com_in_box(unitcell_enum, ecenter, natoms, atoms->atom, + ePBC, fr.box, fr.x); } if (bPBCcomMol) { - put_molecule_com_in_box(unitcell_enum, ecenter, - &top->mols, - natoms, atoms->atom, ePBC, fr.box, fr.x); + put_molecule_com_in_box(unitcell_enum, ecenter, &top->mols, natoms, + atoms->atom, ePBC, fr.box, fr.x); } /* Copy the input trxframe struct to the output trxframe struct */ frout = fr; @@ -1329,7 +1298,7 @@ int gmx_trjconv(int argc, char *argv[]) { for (d = 0; d < DIM; d++) { - frout.x[i][d] += outframe*shift[d]; + frout.x[i][d] += outframe * shift[d]; } } } @@ -1341,9 +1310,9 @@ int gmx_trjconv(int argc, char *argv[]) else { /* round() is not C89 compatible, so we do this: */ - bSplitHere = bSplit && bRmod(std::floor(frout.time+0.5), - std::floor(tzero+0.5), - std::floor(split_t+0.5)); + bSplitHere = bSplit + && bRmod(std::floor(frout.time + 0.5), + std::floor(tzero + 0.5), std::floor(split_t + 0.5)); } if (bSeparate || bSplitHere) { @@ -1402,8 +1371,8 @@ int gmx_trjconv(int argc, char *argv[]) switch (ftp) { case efGRO: - write_hconf_p(out, title.c_str(), &useatoms, - frout.x, frout.bV ? frout.v : nullptr, frout.box); + write_hconf_p(out, title.c_str(), &useatoms, frout.x, + frout.bV ? frout.v : nullptr, frout.box); break; case efPDB: fprintf(out, "REMARK GENERATED BY TRJCONV\n"); @@ -1422,7 +1391,7 @@ int gmx_trjconv(int argc, char *argv[]) frout.ePBC, frout.box, ' ', model_nr, gc); break; case efG96: - const char *outputTitle = ""; + const char* outputTitle = ""; if (bSeparate || bTDump) { outputTitle = title.c_str(); @@ -1430,9 +1399,9 @@ int gmx_trjconv(int argc, char *argv[]) { frout.bAtoms = TRUE; } - frout.atoms = &useatoms; - frout.bStep = FALSE; - frout.bTime = FALSE; + frout.atoms = &useatoms; + frout.bStep = FALSE; + frout.bTime = FALSE; } else { @@ -1452,8 +1421,7 @@ int gmx_trjconv(int argc, char *argv[]) out = nullptr; } break; - default: - gmx_fatal(FARGS, "DHE, ftp=%d\n", ftp); + default: gmx_fatal(FARGS, "DHE, ftp=%d\n", ftp); } if (bSeparate || bSplitHere) { @@ -1464,7 +1432,7 @@ int gmx_trjconv(int argc, char *argv[]) if (bExec) { char c[255]; - sprintf(c, "%s %d", exec_command, file_nr-1); + sprintf(c, "%s %d", exec_command, file_nr - 1); /*fprintf(stderr,"Executing '%s'\n",c);*/ if (0 != system(c)) { @@ -1476,14 +1444,15 @@ int gmx_trjconv(int argc, char *argv[]) } frame++; bHaveNextFrame = read_next_frame(oenv, trxin, &fr); - } - while (!(bTDump && bDumpFrame) && bHaveNextFrame); + } while (!(bTDump && bDumpFrame) && bHaveNextFrame); } if (!bHaveFirstFrame || (bTDump && !bDumpFrame)) { - fprintf(stderr, "\nWARNING no output, " - "last frame read at t=%g\n", fr.time); + fprintf(stderr, + "\nWARNING no output, " + "last frame read at t=%g\n", + fr.time); } fprintf(stderr, "\n"); diff --git a/src/gromacs/tools/trjconv.h b/src/gromacs/tools/trjconv.h index de74074845..bb5849d6f6 100644 --- a/src/gromacs/tools/trjconv.h +++ b/src/gromacs/tools/trjconv.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_trjconv(int argc, char *argv[]); +int gmx_trjconv(int argc, char* argv[]); #endif diff --git a/src/gromacs/tools/tune_pme.cpp b/src/gromacs/tools/tune_pme.cpp index 3d9ab118d7..ed2c06f717 100644 --- a/src/gromacs/tools/tune_pme.cpp +++ b/src/gromacs/tools/tune_pme.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2009-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,7 +48,7 @@ #include #ifdef HAVE_SYS_TIME_H -#include +# include #endif #include "gromacs/commandline/pargs.h" @@ -80,7 +81,8 @@ * corresponding string entries can be found in do_the_tests() in * const char* ParseLog[] */ /* TODO clean up CamelCasing of these enum names */ -enum { +enum +{ eParselogOK, eParselogNotFound, eParselogNoPerfData, @@ -99,53 +101,53 @@ enum { typedef struct { - int nPMEnodes; /* number of PME-only nodes used in this test */ - int nx, ny, nz; /* DD grid */ - int guessPME; /* if nPMEnodes == -1, this is the guessed number of PME nodes */ - double *Gcycles; /* This can contain more than one value if doing multiple tests */ + int nPMEnodes; /* number of PME-only nodes used in this test */ + int nx, ny, nz; /* DD grid */ + int guessPME; /* if nPMEnodes == -1, this is the guessed number of PME nodes */ + double* Gcycles; /* This can contain more than one value if doing multiple tests */ double Gcycles_Av; - float *ns_per_day; + float* ns_per_day; float ns_per_day_Av; - float *PME_f_load; /* PME mesh/force load average*/ + float* PME_f_load; /* PME mesh/force load average*/ float PME_f_load_Av; /* Average average ;) ... */ - char *mdrun_cmd_line; /* Mdrun command line used for this test */ + char* mdrun_cmd_line; /* Mdrun command line used for this test */ } t_perf; typedef struct { - int nr_inputfiles; /* The number of tpr and mdp input files */ - int64_t orig_sim_steps; /* Number of steps to be done in the real simulation */ - int64_t orig_init_step; /* Init step for the real simulation */ - real *rcoulomb; /* The coulomb radii [0...nr_inputfiles] */ - real *rvdw; /* The vdW radii */ - real *rlist; /* Neighbourlist cutoff radius */ - int *nkx, *nky, *nkz; - real *fsx, *fsy, *fsz; /* Fourierspacing in x,y,z dimension */ + int nr_inputfiles; /* The number of tpr and mdp input files */ + int64_t orig_sim_steps; /* Number of steps to be done in the real simulation */ + int64_t orig_init_step; /* Init step for the real simulation */ + real* rcoulomb; /* The coulomb radii [0...nr_inputfiles] */ + real* rvdw; /* The vdW radii */ + real* rlist; /* Neighbourlist cutoff radius */ + int * nkx, *nky, *nkz; + real * fsx, *fsy, *fsz; /* Fourierspacing in x,y,z dimension */ } t_inputinfo; -static void sep_line(FILE *fp) +static void sep_line(FILE* fp) { fprintf(fp, "\n------------------------------------------------------------\n"); } /* Wrapper for system calls */ -static int gmx_system_call(char *command) +static int gmx_system_call(char* command) { - return ( system(command) ); + return (system(command)); } /* Check if string starts with substring */ -static gmx_bool str_starts(const char *string, const char *substring) +static gmx_bool str_starts(const char* string, const char* substring) { - return ( std::strncmp(string, substring, std::strlen(substring)) == 0); + return (std::strncmp(string, substring, std::strlen(substring)) == 0); } -static void cleandata(t_perf *perfdata, int test_nr) +static void cleandata(t_perf* perfdata, int test_nr) { perfdata->Gcycles[test_nr] = 0.0; perfdata->ns_per_day[test_nr] = 0.0; @@ -153,7 +155,7 @@ static void cleandata(t_perf *perfdata, int test_nr) } -static void remove_if_exists(const char *fn) +static void remove_if_exists(const char* fn) { if (gmx_fexist(fn)) { @@ -163,16 +165,16 @@ static void remove_if_exists(const char *fn) } -static void finalize(const char *fn_out) +static void finalize(const char* fn_out) { char buf[STRLEN]; - FILE *fp; + FILE* fp; fp = fopen(fn_out, "r"); fprintf(stdout, "\n\n"); - while (fgets(buf, STRLEN-1, fp) != nullptr) + while (fgets(buf, STRLEN - 1, fp) != nullptr) { fprintf(stdout, "%s", buf); } @@ -181,28 +183,36 @@ static void finalize(const char *fn_out) } -enum { - eFoundNothing, eFoundDDStr, eFoundAccountingStr, eFoundCycleStr +enum +{ + eFoundNothing, + eFoundDDStr, + eFoundAccountingStr, + eFoundCycleStr }; -static int parse_logfile(const char *logfile, const char *errfile, - t_perf *perfdata, int test_nr, int presteps, int64_t cpt_steps, - int nnodes) +static int parse_logfile(const char* logfile, + const char* errfile, + t_perf* perfdata, + int test_nr, + int presteps, + int64_t cpt_steps, + int nnodes) { - FILE *fp; - char line[STRLEN], dumstring[STRLEN], dumstring2[STRLEN]; - const char matchstrdd[] = "Domain decomposition grid"; - const char matchstrcr[] = "resetting all time and cycle counters"; - const char matchstrbal[] = "Average PME mesh/force load:"; - const char matchstring[] = "R E A L C Y C L E A N D T I M E A C C O U N T I N G"; - const char errSIG[] = "signal, stopping at the next"; - int iFound; - float dum1, dum2, dum3, dum4; - int ndum; - int npme; - int64_t resetsteps = -1; - gmx_bool bFoundResetStr = FALSE; - gmx_bool bResetChecked = FALSE; + FILE* fp; + char line[STRLEN], dumstring[STRLEN], dumstring2[STRLEN]; + const char matchstrdd[] = "Domain decomposition grid"; + const char matchstrcr[] = "resetting all time and cycle counters"; + const char matchstrbal[] = "Average PME mesh/force load:"; + const char matchstring[] = "R E A L C Y C L E A N D T I M E A C C O U N T I N G"; + const char errSIG[] = "signal, stopping at the next"; + int iFound; + float dum1, dum2, dum3, dum4; + int ndum; + int npme; + int64_t resetsteps = -1; + gmx_bool bFoundResetStr = FALSE; + gmx_bool bResetChecked = FALSE; if (!gmx_fexist(logfile)) @@ -212,7 +222,7 @@ static int parse_logfile(const char *logfile, const char *errfile, return eParselogNotFound; } - fp = fopen(logfile, "r"); + fp = fopen(logfile, "r"); perfdata->PME_f_load[test_nr] = -1.0; perfdata->guessPME = -1; @@ -243,15 +253,16 @@ static int parse_logfile(const char *logfile, const char *errfile, sprintf(dumstring, "step %s", "%" SCNd64); sscanf(line, dumstring, &resetsteps); bFoundResetStr = TRUE; - if (resetsteps == presteps+cpt_steps) + if (resetsteps == presteps + cpt_steps) { bResetChecked = TRUE; } else { sprintf(dumstring, "%" PRId64, resetsteps); - sprintf(dumstring2, "%" PRId64, presteps+cpt_steps); - fprintf(stderr, "WARNING: Time step counters were reset at step %s,\n" + sprintf(dumstring2, "%" PRId64, presteps + cpt_steps); + fprintf(stderr, + "WARNING: Time step counters were reset at step %s,\n" " though they were supposed to be reset at step %s!\n", dumstring, dumstring2); } @@ -273,7 +284,8 @@ static int parse_logfile(const char *logfile, const char *errfile, } else if (perfdata->nPMEnodes != npme) { - gmx_fatal(FARGS, "PME ranks from command line and output file are not identical"); + gmx_fatal(FARGS, + "PME ranks from command line and output file are not identical"); } iFound = eFoundDDStr; } @@ -362,12 +374,14 @@ static int parse_logfile(const char *logfile, const char *errfile, fp = fopen(errfile, "r"); while (fgets(line, STRLEN, fp) != nullptr) { - if (str_starts(line, "Fatal error:") ) + if (str_starts(line, "Fatal error:")) { if (fgets(line, STRLEN, fp) != nullptr) { - fprintf(stderr, "\nWARNING: An error occurred during this benchmark:\n" - "%s\n", line); + fprintf(stderr, + "\nWARNING: An error occurred during this benchmark:\n" + "%s\n", + line); } fclose(fp); cleandata(perfdata, test_nr); @@ -390,23 +404,22 @@ static int parse_logfile(const char *logfile, const char *errfile, } -static gmx_bool analyze_data( - FILE *fp, - const char *fn, - t_perf **perfdata, - int nnodes, - int ntprs, - int ntests, - int nrepeats, - t_inputinfo *info, - int *index_tpr, /* OUT: Nr of mdp file with best settings */ - int *npme_optimal) /* OUT: Optimal number of PME nodes */ +static gmx_bool analyze_data(FILE* fp, + const char* fn, + t_perf** perfdata, + int nnodes, + int ntprs, + int ntests, + int nrepeats, + t_inputinfo* info, + int* index_tpr, /* OUT: Nr of mdp file with best settings */ + int* npme_optimal) /* OUT: Optimal number of PME nodes */ { int i, j, k; - int line = 0, line_win = -1; + int line = 0, line_win = -1; int k_win = -1, i_win = -1, winPME; - double s = 0.0; /* standard deviation */ - t_perf *pd; + double s = 0.0; /* standard deviation */ + t_perf* pd; char strbuf[STRLEN]; char str_PME_f_load[13]; gmx_bool bCanUseOrigTPR; @@ -449,10 +462,10 @@ static gmx_bool analyze_data( /* Get the average run time of a setting */ for (j = 0; j < nrepeats; j++) { - pd->Gcycles_Av += pd->Gcycles[j]; + pd->Gcycles_Av += pd->Gcycles[j]; pd->PME_f_load_Av += pd->PME_f_load[j]; } - pd->Gcycles_Av /= nrepeats; + pd->Gcycles_Av /= nrepeats; pd->PME_f_load_Av /= nrepeats; for (j = 0; j < nrepeats; j++) @@ -465,7 +478,7 @@ static gmx_bool analyze_data( { /* Somehow the performance number was not aquired for this run, * therefor set the average to some negative value: */ - pd->ns_per_day_Av = -1.0F*nrepeats; + pd->ns_per_day_Av = -1.0F * nrepeats; break; } } @@ -492,14 +505,13 @@ static gmx_bool analyze_data( s = 0.0; for (j = 0; j < nrepeats; j++) { - s += gmx::square( pd->Gcycles[j] - pd->Gcycles_Av ); + s += gmx::square(pd->Gcycles[j] - pd->Gcycles_Av); } s /= (nrepeats - 1); - s = std::sqrt(s); + s = std::sqrt(s); - fprintf(fp, "%4d %3d %4d%s %12.3f %12.3f %12.3f %s", - line, k, pd->nPMEnodes, strbuf, pd->Gcycles_Av, s, - pd->ns_per_day_Av, str_PME_f_load); + fprintf(fp, "%4d %3d %4d%s %12.3f %12.3f %12.3f %s", line, k, pd->nPMEnodes, + strbuf, pd->Gcycles_Av, s, pd->ns_per_day_Av, str_PME_f_load); if (nnodes > 1) { fprintf(fp, " %3d %3d %3d", pd->nx, pd->ny, pd->nz); @@ -507,7 +519,7 @@ static gmx_bool analyze_data( fprintf(fp, "\n"); } /* Store the index of the best run found so far in 'winner': */ - if ( (k_win == -1) || (pd->Gcycles_Av < perfdata[k_win][i_win].Gcycles_Av) ) + if ((k_win == -1) || (pd->Gcycles_Av < perfdata[k_win][i_win].Gcycles_Av)) { k_win = k; i_win = i; @@ -554,9 +566,8 @@ static gmx_bool analyze_data( /* Only mention settings if they were modified: */ bRefinedCoul = !gmx_within_tol(info->rcoulomb[k_win], info->rcoulomb[0], GMX_REAL_EPS); bRefinedVdW = !gmx_within_tol(info->rvdw[k_win], info->rvdw[0], GMX_REAL_EPS); - bRefinedGrid = !(info->nkx[k_win] == info->nkx[0] && - info->nky[k_win] == info->nky[0] && - info->nkz[k_win] == info->nkz[0]); + bRefinedGrid = !(info->nkx[k_win] == info->nkx[0] && info->nky[k_win] == info->nky[0] + && info->nkz[k_win] == info->nkz[0]); if (bRefinedCoul || bRefinedVdW || bRefinedGrid) { @@ -570,7 +581,8 @@ static gmx_bool analyze_data( if (bRefinedCoul) { - fprintf(fp, " New Coulomb radius: %f nm (was %f nm)\n", info->rcoulomb[k_win], info->rcoulomb[0]); + fprintf(fp, " New Coulomb radius: %f nm (was %f nm)\n", info->rcoulomb[k_win], + info->rcoulomb[0]); } if (bRefinedVdW) @@ -580,8 +592,8 @@ static gmx_bool analyze_data( if (bRefinedGrid) { - fprintf(fp, " New Fourier grid xyz: %d %d %d (was %d %d %d)\n", info->nkx[k_win], info->nky[k_win], info->nkz[k_win], - info->nkx[0], info->nky[0], info->nkz[0]); + fprintf(fp, " New Fourier grid xyz: %d %d %d (was %d %d %d)\n", info->nkx[k_win], + info->nky[k_win], info->nkz[k_win], info->nkx[0], info->nky[0], info->nkz[0]); } if (bCanUseOrigTPR && ntprs > 1) @@ -601,17 +613,17 @@ static gmx_bool analyze_data( /* Get the commands we need to set up the runs from environment variables */ -static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char *cmd_mdrun[]) +static void get_program_paths(gmx_bool bThreads, char* cmd_mpirun[], char* cmd_mdrun[]) { - char *cp; - const char def_mpirun[] = "mpirun"; + char* cp; + const char def_mpirun[] = "mpirun"; const char empty_mpirun[] = ""; /* Get the commands we need to set up the runs from environment variables */ if (!bThreads) { - if ( (cp = getenv("MPIRUN")) != nullptr) + if ((cp = getenv("MPIRUN")) != nullptr) { *cmd_mpirun = gmx_strdup(cp); } @@ -630,7 +642,7 @@ static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char *cmd_m /* The use of MDRUN is deprecated, but made available in 5.1 for backward compatibility. It may be removed in a future version. */ - if ( (cp = getenv("MDRUN" )) != nullptr) + if ((cp = getenv("MDRUN")) != nullptr) { *cmd_mdrun = gmx_strdup(cp); } @@ -648,16 +660,16 @@ static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char *cmd_m compatible GPUs from mdrun, if the user of gmx tune-pme has not given one. */ static void check_mdrun_works(gmx_bool bThreads, - const char *cmd_mpirun, - const char *cmd_np, - const char *cmd_mdrun, + const char* cmd_mpirun, + const char* cmd_np, + const char* cmd_mdrun, gmx_bool bNeedGpuSupport) { - char *command = nullptr; - char *cp; + char* command = nullptr; + char* cp; char line[STRLEN]; - FILE *fp; - const char filename[] = "benchtest.log"; + FILE* fp; + const char filename[] = "benchtest.log"; /* This string should always be identical to the one in copyrite.c, * gmx_print_version_info() in the GMX_MPI section */ @@ -677,7 +689,8 @@ static void check_mdrun_works(gmx_bool bThreads, } else { - snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun) + std::strlen(filename) + 50); + snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun) + + std::strlen(filename) + 50); sprintf(command, "%s%s%s -version -maxh 0.001 1> %s 2>&1", cmd_mpirun, cmd_np, cmd_mdrun, filename); } fprintf(stdout, "Trying '%s' ... ", command); @@ -693,20 +706,20 @@ static void check_mdrun_works(gmx_bool bThreads, fp = fopen(filename, "r"); /* We need to scan the whole output file, since sometimes the queuing system * also writes stuff to stdout/err */ - while (!feof(fp) ) + while (!feof(fp)) { cp = fgets(line, STRLEN, fp); if (cp != nullptr) { - if (str_starts(line, match_mdrun) ) + if (str_starts(line, match_mdrun)) { bMdrun = TRUE; } - if (str_starts(line, match_mpi) ) + if (str_starts(line, match_mpi)) { bMPI = TRUE; } - if (str_starts(line, match_nogpu) ) + if (str_starts(line, match_nogpu)) { bHaveGpuSupport = FALSE; } @@ -718,7 +731,8 @@ static void check_mdrun_works(gmx_bool bThreads, { if (bMPI) { - gmx_fatal(FARGS, "Need a threaded version of mdrun. This one\n" + gmx_fatal(FARGS, + "Need a threaded version of mdrun. This one\n" "(%s)\n" "seems to have been compiled with MPI instead.", cmd_mdrun); @@ -728,7 +742,8 @@ static void check_mdrun_works(gmx_bool bThreads, { if (bMdrun && !bMPI) { - gmx_fatal(FARGS, "Need an MPI-enabled version of mdrun. This one\n" + gmx_fatal(FARGS, + "Need an MPI-enabled version of mdrun. This one\n" "(%s)\n" "seems to have been compiled without MPI support.", cmd_mdrun); @@ -737,8 +752,7 @@ static void check_mdrun_works(gmx_bool bThreads, if (!bMdrun) { - gmx_fatal(FARGS, "Cannot execute mdrun. Please check %s for problems!", - filename); + gmx_fatal(FARGS, "Cannot execute mdrun. Please check %s for problems!", filename); } if (bNeedGpuSupport && !bHaveGpuSupport) @@ -754,7 +768,7 @@ static void check_mdrun_works(gmx_bool bThreads, } /* Handles the no-GPU case by emitting an empty string. */ -static std::string make_gpu_id_command_line(const char *eligible_gpu_ids) +static std::string make_gpu_id_command_line(const char* eligible_gpu_ids) { /* If the user has given no eligible GPU IDs, or we're trying the * default behaviour, then there is nothing for tune_pme to give @@ -768,25 +782,25 @@ static std::string make_gpu_id_command_line(const char *eligible_gpu_ids) return std::string(); } -static void launch_simulation( - gmx_bool bLaunch, /* Should the simulation be launched? */ - FILE *fp, /* General log file */ - gmx_bool bThreads, /* whether to use threads */ - char *cmd_mpirun, /* Command for mpirun */ - char *cmd_np, /* Switch for -np or -ntmpi or empty */ - char *cmd_mdrun, /* Command for mdrun */ - char *args_for_mdrun, /* Arguments for mdrun */ - const char *simulation_tpr, /* This tpr will be simulated */ - int nPMEnodes, /* Number of PME ranks to use */ - const char *eligible_gpu_ids) /* Available GPU IDs for - * constructing mdrun command lines */ +static void launch_simulation(gmx_bool bLaunch, /* Should the simulation be launched? */ + FILE* fp, /* General log file */ + gmx_bool bThreads, /* whether to use threads */ + char* cmd_mpirun, /* Command for mpirun */ + char* cmd_np, /* Switch for -np or -ntmpi or empty */ + char* cmd_mdrun, /* Command for mdrun */ + char* args_for_mdrun, /* Arguments for mdrun */ + const char* simulation_tpr, /* This tpr will be simulated */ + int nPMEnodes, /* Number of PME ranks to use */ + const char* eligible_gpu_ids) /* Available GPU IDs for + * constructing mdrun command lines */ { - char *command; + char* command; /* Make enough space for the system call command, * (200 extra chars for -npme ... etc. options should suffice): */ - snew(command, std::strlen(cmd_mpirun)+std::strlen(cmd_mdrun)+std::strlen(cmd_np)+std::strlen(args_for_mdrun)+std::strlen(simulation_tpr)+200); + snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_mdrun) + std::strlen(cmd_np) + + std::strlen(args_for_mdrun) + std::strlen(simulation_tpr) + 200); auto cmd_gpu_ids = make_gpu_id_command_line(eligible_gpu_ids); @@ -794,16 +808,17 @@ static void launch_simulation( * of the command line string */ if (bThreads) { - sprintf(command, "%s%s-npme %d -s %s %s %s", - cmd_mdrun, cmd_np, nPMEnodes, simulation_tpr, args_for_mdrun, cmd_gpu_ids.c_str()); + sprintf(command, "%s%s-npme %d -s %s %s %s", cmd_mdrun, cmd_np, nPMEnodes, simulation_tpr, + args_for_mdrun, cmd_gpu_ids.c_str()); } else { - sprintf(command, "%s%s%s -npme %d -s %s %s %s", - cmd_mpirun, cmd_np, cmd_mdrun, nPMEnodes, simulation_tpr, args_for_mdrun, cmd_gpu_ids.c_str()); + sprintf(command, "%s%s%s -npme %d -s %s %s %s", cmd_mpirun, cmd_np, cmd_mdrun, nPMEnodes, + simulation_tpr, args_for_mdrun, cmd_gpu_ids.c_str()); } - fprintf(fp, "%s this command line to launch the simulation:\n\n%s", bLaunch ? "Using" : "Please use", command); + fprintf(fp, "%s this command line to launch the simulation:\n\n%s", + bLaunch ? "Using" : "Please use", command); sep_line(fp); fflush(fp); @@ -818,18 +833,17 @@ static void launch_simulation( } -static void modify_PMEsettings( - int64_t simsteps, /* Set this value as number of time steps */ - int64_t init_step, /* Set this value as init_step */ - const char *fn_best_tpr, /* tpr file with the best performance */ - const char *fn_sim_tpr) /* name of tpr file to be launched */ +static void modify_PMEsettings(int64_t simsteps, /* Set this value as number of time steps */ + int64_t init_step, /* Set this value as init_step */ + const char* fn_best_tpr, /* tpr file with the best performance */ + const char* fn_sim_tpr) /* name of tpr file to be launched */ { - t_state state; - gmx_mtop_t mtop; - char buf[200]; + t_state state; + gmx_mtop_t mtop; + char buf[200]; - t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec irInstance; + t_inputrec* ir = &irInstance; read_tpx_state(fn_best_tpr, ir, &state, &mtop); /* Reset nsteps and init_step to the value of the input .tpr file */ @@ -845,41 +859,39 @@ static void modify_PMEsettings( static gmx_bool can_scale_rvdw(int vdwtype) { - return (evdwCUT == vdwtype || - evdwPME == vdwtype); + return (evdwCUT == vdwtype || evdwPME == vdwtype); } #define EPME_SWITCHED(e) ((e) == eelPMESWITCH || (e) == eelPMEUSERSWITCH) /* Make additional TPR files with more computational load for the * direct space processors: */ -static void make_benchmark_tprs( - const char *fn_sim_tpr, /* READ : User-provided tpr file */ - char *fn_bench_tprs[], /* WRITE: Names of benchmark tpr files */ - int64_t benchsteps, /* Number of time steps for benchmark runs */ - int64_t statesteps, /* Step counter in checkpoint file */ - real rmin, /* Minimal Coulomb radius */ - real rmax, /* Maximal Coulomb radius */ - bool bScaleRvdw, /* Scale rvdw along with rcoulomb */ - const int *ntprs, /* No. of TPRs to write, each with a different - rcoulomb and fourierspacing */ - t_inputinfo *info, /* Contains information about mdp file options */ - FILE *fp) /* Write the output here */ +static void make_benchmark_tprs(const char* fn_sim_tpr, /* READ : User-provided tpr file */ + char* fn_bench_tprs[], /* WRITE: Names of benchmark tpr files */ + int64_t benchsteps, /* Number of time steps for benchmark runs */ + int64_t statesteps, /* Step counter in checkpoint file */ + real rmin, /* Minimal Coulomb radius */ + real rmax, /* Maximal Coulomb radius */ + bool bScaleRvdw, /* Scale rvdw along with rcoulomb */ + const int* ntprs, /* No. of TPRs to write, each with a different + rcoulomb and fourierspacing */ + t_inputinfo* info, /* Contains information about mdp file options */ + FILE* fp) /* Write the output here */ { - int i, j, d; - t_state state; - gmx_mtop_t mtop; - real nlist_buffer; /* Thickness of the buffer regions for PME-switch potentials */ - char buf[200]; - rvec box_size; - gmx_bool bNote = FALSE; - real add; /* Add this to rcoul for the next test */ - real fac = 1.0; /* Scaling factor for Coulomb radius */ - real fourierspacing; /* Basic fourierspacing from tpr */ - - - sprintf(buf, "Making benchmark tpr file%s with %s time step%s", - *ntprs > 1 ? "s" : "", "%" PRId64, benchsteps > 1 ? "s" : ""); + int i, j, d; + t_state state; + gmx_mtop_t mtop; + real nlist_buffer; /* Thickness of the buffer regions for PME-switch potentials */ + char buf[200]; + rvec box_size; + gmx_bool bNote = FALSE; + real add; /* Add this to rcoul for the next test */ + real fac = 1.0; /* Scaling factor for Coulomb radius */ + real fourierspacing; /* Basic fourierspacing from tpr */ + + + sprintf(buf, "Making benchmark tpr file%s with %s time step%s", *ntprs > 1 ? "s" : "", + "%" PRId64, benchsteps > 1 ? "s" : ""); fprintf(stdout, buf, benchsteps); if (statesteps > 0) { @@ -890,7 +902,7 @@ static void make_benchmark_tprs( fprintf(stdout, ".\n"); t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec* ir = &irInstance; read_tpx_state(fn_sim_tpr, ir, &state, &mtop); /* Check if some kind of PME was chosen */ @@ -901,11 +913,10 @@ static void make_benchmark_tprs( } /* Check if rcoulomb == rlist, which is necessary for plain PME. */ - if ( (ir->cutoff_scheme != ecutsVERLET) && - (eelPME == ir->coulombtype) && !(ir->rcoulomb == ir->rlist)) + if ((ir->cutoff_scheme != ecutsVERLET) && (eelPME == ir->coulombtype) && !(ir->rcoulomb == ir->rlist)) { - gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to rlist (%f).", - EELTYPE(eelPME), ir->rcoulomb, ir->rlist); + gmx_fatal(FARGS, "%s requires rcoulomb (%f) to be equal to rlist (%f).", EELTYPE(eelPME), + ir->rcoulomb, ir->rlist); } /* For other PME types, rcoulomb is allowed to be smaller than rlist */ else if (ir->rcoulomb > ir->rlist) @@ -928,7 +939,7 @@ static void make_benchmark_tprs( ir->init_step = 0; /* For PME-switch potentials, keep the radial distance of the buffer region */ - nlist_buffer = ir->rlist - ir->rcoulomb; + nlist_buffer = ir->rlist - ir->rcoulomb; /* Determine length of triclinic box vectors */ for (d = 0; d < DIM; d++) @@ -936,7 +947,7 @@ static void make_benchmark_tprs( box_size[d] = 0; for (i = 0; i < DIM; i++) { - box_size[d] += state.box[d][i]*state.box[d][i]; + box_size[d] += state.box[d][i] * state.box[d][i]; } box_size[d] = std::sqrt(box_size[d]); } @@ -950,9 +961,9 @@ static void make_benchmark_tprs( else { /* Reconstruct fourierspacing per dimension from the number of grid points and box size */ - info->fsx[0] = box_size[XX]/ir->nkx; - info->fsy[0] = box_size[YY]/ir->nky; - info->fsz[0] = box_size[ZZ]/ir->nkz; + info->fsx[0] = box_size[XX] / ir->nkx; + info->fsy[0] = box_size[YY] / ir->nky; + info->fsz[0] = box_size[ZZ] / ir->nkz; } /* If no value for the fourierspacing was provided on the command line, we @@ -968,15 +979,16 @@ static void make_benchmark_tprs( fourierspacing = std::max(std::max(info->fsx[0], info->fsy[0]), info->fsz[0]); } - fprintf(stdout, "Calculating PME grid points on the basis of a fourierspacing of %f nm\n", fourierspacing); + fprintf(stdout, "Calculating PME grid points on the basis of a fourierspacing of %f nm\n", + fourierspacing); /* For performance comparisons the number of particles is useful to have */ fprintf(fp, " Number of particles : %d\n", mtop.natoms); /* Print information about settings of which some are potentially modified: */ fprintf(fp, " Coulomb type : %s\n", EELTYPE(ir->coulombtype)); - fprintf(fp, " Grid spacing x y z : %f %f %f\n", - box_size[XX]/ir->nkx, box_size[YY]/ir->nky, box_size[ZZ]/ir->nkz); + fprintf(fp, " Grid spacing x y z : %f %f %f\n", box_size[XX] / ir->nkx, + box_size[YY] / ir->nky, box_size[ZZ] / ir->nkz); fprintf(fp, " Van der Waals type : %s\n", EVDWTYPE(ir->vdwtype)); if (ir_vdw_switched(ir)) { @@ -1010,28 +1022,28 @@ static void make_benchmark_tprs( if (j != 0) { /* Determine which Coulomb radii rc to use in the benchmarks */ - add = (rmax-rmin)/(*ntprs-1); + add = (rmax - rmin) / (*ntprs - 1); if (gmx_within_tol(rmin, info->rcoulomb[0], GMX_REAL_EPS)) { - ir->rcoulomb = rmin + j*add; + ir->rcoulomb = rmin + j * add; } else if (gmx_within_tol(rmax, info->rcoulomb[0], GMX_REAL_EPS)) { - ir->rcoulomb = rmin + (j-1)*add; + ir->rcoulomb = rmin + (j - 1) * add; } else { /* rmin != rcoul != rmax, ergo test between rmin and rmax */ - add = (rmax-rmin)/(*ntprs-2); - ir->rcoulomb = rmin + (j-1)*add; + add = (rmax - rmin) / (*ntprs - 2); + ir->rcoulomb = rmin + (j - 1) * add; } /* Determine the scaling factor fac */ - fac = ir->rcoulomb/info->rcoulomb[0]; + fac = ir->rcoulomb / info->rcoulomb[0]; /* Scale the Fourier grid spacing */ ir->nkx = ir->nky = ir->nkz = 0; - calcFftGrid(nullptr, state.box, fourierspacing*fac, minimalPmeGridSize(ir->pme_order), + calcFftGrid(nullptr, state.box, fourierspacing * fac, minimalPmeGridSize(ir->pme_order), &ir->nkx, &ir->nky, &ir->nkz); /* Adjust other radii since various conditions need to be fulfilled */ @@ -1048,8 +1060,7 @@ static void make_benchmark_tprs( if (bScaleRvdw && can_scale_rvdw(ir->vdwtype)) { - if (ecutsVERLET == ir->cutoff_scheme || - evdwPME == ir->vdwtype) + if (ecutsVERLET == ir->cutoff_scheme || evdwPME == ir->vdwtype) { /* With either the Verlet cutoff-scheme or LJ-PME, the van der Waals radius must always equal the @@ -1066,18 +1077,20 @@ static void make_benchmark_tprs( /* for j==0: Save the original settings * for j >0: Save modified radii and Fourier grids */ - info->rcoulomb[j] = ir->rcoulomb; - info->rvdw[j] = ir->rvdw; - info->nkx[j] = ir->nkx; - info->nky[j] = ir->nky; - info->nkz[j] = ir->nkz; - info->rlist[j] = ir->rlist; - info->fsx[j] = fac*fourierspacing; - info->fsy[j] = fac*fourierspacing; - info->fsz[j] = fac*fourierspacing; + info->rcoulomb[j] = ir->rcoulomb; + info->rvdw[j] = ir->rvdw; + info->nkx[j] = ir->nkx; + info->nky[j] = ir->nky; + info->nkz[j] = ir->nkz; + info->rlist[j] = ir->rlist; + info->fsx[j] = fac * fourierspacing; + info->fsy[j] = fac * fourierspacing; + info->fsz[j] = fac * fourierspacing; /* Write the benchmark tpr file */ - fn_bench_tprs[j] = gmx_strdup(gmx::Path::concatenateBeforeExtension(fn_sim_tpr, gmx::formatString("_bench%.2d", j)).c_str()); + fn_bench_tprs[j] = gmx_strdup( + gmx::Path::concatenateBeforeExtension(fn_sim_tpr, gmx::formatString("_bench%.2d", j)) + .c_str()); fprintf(stdout, "Writing benchmark tpr %s with nsteps=", fn_bench_tprs[j]); fprintf(stdout, "%" PRId64, ir->nsteps); @@ -1108,14 +1121,15 @@ static void make_benchmark_tprs( /* Make it clear to the user that some additional settings were modified */ if (!gmx_within_tol(ir->rvdw, info->rvdw[0], GMX_REAL_EPS) - || !gmx_within_tol(ir->rlist, info->rlist[0], GMX_REAL_EPS) ) + || !gmx_within_tol(ir->rlist, info->rlist[0], GMX_REAL_EPS)) { bNote = TRUE; } } if (bNote) { - fprintf(fp, "\nNote that in addition to the Coulomb radius and the Fourier grid\n" + fprintf(fp, + "\nNote that in addition to the Coulomb radius and the Fourier grid\n" "other input settings were also changed (see table above).\n" "Please check if the modified settings are appropriate.\n"); } @@ -1126,24 +1140,22 @@ static void make_benchmark_tprs( /* Rename the files we want to keep to some meaningful filename and * delete the rest */ -static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes, - int nPMEnodes, int nr, gmx_bool bKeepStderr) +static void cleanup(const t_filenm* fnm, int nfile, int k, int nnodes, int nPMEnodes, int nr, gmx_bool bKeepStderr) { char numstring[STRLEN]; - const char *fn = nullptr; + const char* fn = nullptr; int i; - const char *opt; + const char* opt; fprintf(stdout, "Cleaning up, deleting benchmark temp files ...\n"); for (i = 0; i < nfile; i++) { - opt = const_cast(fnm[i].opt); + opt = const_cast(fnm[i].opt); if (std::strcmp(opt, "-p") == 0) { /* do nothing; keep this file */ - ; } else if (std::strcmp(opt, "-bg") == 0) { @@ -1153,7 +1165,8 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes, { sprintf(numstring, "_%d", nr); } - std::string newfilename = gmx::formatString("%s_no%d_np%d_npme%d%s", opt2fn("-bg", nfile, fnm), k, nnodes, nPMEnodes, numstring); + std::string newfilename = gmx::formatString( + "%s_no%d_np%d_npme%d%s", opt2fn("-bg", nfile, fnm), k, nnodes, nPMEnodes, numstring); if (gmx_fexist(opt2fn("-bg", nfile, fnm))) { fprintf(stdout, "renaming log file to %s\n", newfilename.c_str()); @@ -1171,7 +1184,8 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes, { sprintf(numstring, "_%d", nr); } - std::string newfilename = gmx::formatString("%s_no%d_np%d_npme%d%s", fn, k, nnodes, nPMEnodes, numstring); + std::string newfilename = + gmx::formatString("%s_no%d_np%d_npme%d%s", fn, k, nnodes, nPMEnodes, numstring); if (gmx_fexist(fn)) { if (bKeepStderr) @@ -1188,7 +1202,7 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes, } } /* Delete the files which are created for each benchmark run: (options -b*) */ - else if ( (0 == std::strncmp(opt, "-b", 2)) && (opt2bSet(opt, nfile, fnm) || !is_optional(&fnm[i])) ) + else if ((0 == std::strncmp(opt, "-b", 2)) && (opt2bSet(opt, nfile, fnm) || !is_optional(&fnm[i]))) { remove_if_exists(opt2fn(opt, nfile, fnm)); } @@ -1196,35 +1210,39 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes, } -enum { - eNpmeAuto, eNpmeAll, eNpmeReduced, eNpmeSubset, eNpmeNr +enum +{ + eNpmeAuto, + eNpmeAll, + eNpmeReduced, + eNpmeSubset, + eNpmeNr }; /* Create a list of numbers of PME nodes to test */ -static void make_npme_list( - const char *npmevalues_opt, /* Make a complete list with all - * possibilities or a short list that keeps only - * reasonable numbers of PME nodes */ - int *nentries, /* Number of entries we put in the nPMEnodes list */ - int *nPMEnodes[], /* Each entry contains the value for -npme */ - int nnodes, /* Total number of nodes to do the tests on */ - int minPMEnodes, /* Minimum number of PME nodes */ - int maxPMEnodes) /* Maximum number of PME nodes */ +static void make_npme_list(const char* npmevalues_opt, /* Make a complete list with all + * possibilities or a short list that keeps + * only reasonable numbers of PME nodes */ + int* nentries, /* Number of entries we put in the nPMEnodes list */ + int* nPMEnodes[], /* Each entry contains the value for -npme */ + int nnodes, /* Total number of nodes to do the tests on */ + int minPMEnodes, /* Minimum number of PME nodes */ + int maxPMEnodes) /* Maximum number of PME nodes */ { int i, npme, npp; - int min_factor = 1; /* We request that npp and npme have this minimal - * largest common factor (depends on npp) */ - int nlistmax; /* Max. list size */ - int nlist; /* Actual number of entries in list */ + int min_factor = 1; /* We request that npp and npme have this minimal + * largest common factor (depends on npp) */ + int nlistmax; /* Max. list size */ + int nlist; /* Actual number of entries in list */ int eNPME = 0; /* Do we need to check all possible values for -npme or is a reduced list enough? */ - if (!std::strcmp(npmevalues_opt, "all") ) + if (!std::strcmp(npmevalues_opt, "all")) { eNPME = eNpmeAll; } - else if (!std::strcmp(npmevalues_opt, "subset") ) + else if (!std::strcmp(npmevalues_opt, "subset")) { eNPME = eNpmeSubset; } @@ -1264,22 +1282,17 @@ static void make_npme_list( for (i = 0; i < nlistmax - 2; i++) { npme = maxPMEnodes - i; - npp = nnodes-npme; + npp = nnodes - npme; switch (eNPME) { - case eNpmeAll: - min_factor = 1; - break; - case eNpmeReduced: - min_factor = 2; - break; + case eNpmeAll: min_factor = 1; break; + case eNpmeReduced: min_factor = 2; break; case eNpmeSubset: /* For 2d PME we want a common largest factor of at least the cube * root of the number of PP nodes */ min_factor = static_cast(std::cbrt(npp)); break; - default: - gmx_fatal(FARGS, "Unknown option for eNPME in make_npme_list"); + default: gmx_fatal(FARGS, "Unknown option for eNPME in make_npme_list"); } if (gmx_greatest_common_divisor(npp, npme) >= min_factor) { @@ -1288,21 +1301,21 @@ static void make_npme_list( } } /* We always test 0 PME nodes and the automatic number */ - *nentries = nlist + 2; - (*nPMEnodes)[nlist ] = 0; - (*nPMEnodes)[nlist+1] = -1; + *nentries = nlist + 2; + (*nPMEnodes)[nlist] = 0; + (*nPMEnodes)[nlist + 1] = -1; fprintf(stderr, "Will try the following %d different values for -npme:\n", *nentries); - for (i = 0; i < *nentries-1; i++) + for (i = 0; i < *nentries - 1; i++) { fprintf(stderr, "%d, ", (*nPMEnodes)[i]); } - fprintf(stderr, "and %d (auto).\n", (*nPMEnodes)[*nentries-1]); + fprintf(stderr, "and %d (auto).\n", (*nPMEnodes)[*nentries - 1]); } /* Allocate memory to store the performance data */ -static void init_perfdata(t_perf *perfdata[], int ntprs, int datasets, int repeats) +static void init_perfdata(t_perf* perfdata[], int ntprs, int datasets, int repeats) { int i, j, k; @@ -1324,13 +1337,12 @@ static void init_perfdata(t_perf *perfdata[], int ntprs, int datasets, int repea /* Check for errors on mdrun -h */ -static void make_sure_it_runs(char *mdrun_cmd_line, int length, FILE *fp, - const t_filenm *fnm, int nfile) +static void make_sure_it_runs(char* mdrun_cmd_line, int length, FILE* fp, const t_filenm* fnm, int nfile) { - char *command, *msg; - int ret; + char *command, *msg; + int ret; - snew(command, length + 15); + snew(command, length + 15); snew(msg, length + 500); fprintf(stdout, "Making sure the benchmarks can be executed by running just 1 step...\n"); @@ -1348,7 +1360,8 @@ static void make_sure_it_runs(char *mdrun_cmd_line, int length, FILE *fp, "argument that neither gmx tune_pme nor mdrun understands? If you're\n" "sure your command line should work, you can bypass this check with \n" "gmx tune_pme -nocheck. The failing command was:\n" - "\n%s\n\n", command); + "\n%s\n\n", + command); fprintf(stderr, "%s", msg); sep_line(fp); @@ -1368,70 +1381,64 @@ static void make_sure_it_runs(char *mdrun_cmd_line, int length, FILE *fp, remove_if_exists(opt2fn("-bx", nfile, fnm)); sfree(command); - sfree(msg ); + sfree(msg); } -static void do_the_tests( - FILE *fp, /* General tune_pme output file */ - char **tpr_names, /* Filenames of the input files to test */ - int maxPMEnodes, /* Max fraction of nodes to use for PME */ - int minPMEnodes, /* Min fraction of nodes to use for PME */ - int npme_fixed, /* If >= -1, test fixed number of PME - * nodes only */ - const char *npmevalues_opt, /* Which -npme values should be tested */ - t_perf **perfdata, /* Here the performace data is stored */ - int *pmeentries, /* Entries in the nPMEnodes list */ - int repeats, /* Repeat each test this often */ - int nnodes, /* Total number of nodes = nPP + nPME */ - int nr_tprs, /* Total number of tpr files to test */ - gmx_bool bThreads, /* Threads or MPI? */ - char *cmd_mpirun, /* mpirun command string */ - char *cmd_np, /* "-np", "-n", whatever mpirun needs */ - char *cmd_mdrun, /* mdrun command string */ - char *cmd_args_bench, /* arguments for mdrun in a string */ - const t_filenm *fnm, /* List of filenames from command line */ - int nfile, /* Number of files specified on the cmdl. */ - int presteps, /* DLB equilibration steps, is checked */ - int64_t cpt_steps, /* Time step counter in the checkpoint */ - gmx_bool bCheck, /* Check whether benchmark mdrun works */ - const char *eligible_gpu_ids) /* GPU IDs for - * constructing mdrun command lines */ +static void do_the_tests(FILE* fp, /* General tune_pme output file */ + char** tpr_names, /* Filenames of the input files to test */ + int maxPMEnodes, /* Max fraction of nodes to use for PME */ + int minPMEnodes, /* Min fraction of nodes to use for PME */ + int npme_fixed, /* If >= -1, test fixed number of PME + * nodes only */ + const char* npmevalues_opt, /* Which -npme values should be tested */ + t_perf** perfdata, /* Here the performace data is stored */ + int* pmeentries, /* Entries in the nPMEnodes list */ + int repeats, /* Repeat each test this often */ + int nnodes, /* Total number of nodes = nPP + nPME */ + int nr_tprs, /* Total number of tpr files to test */ + gmx_bool bThreads, /* Threads or MPI? */ + char* cmd_mpirun, /* mpirun command string */ + char* cmd_np, /* "-np", "-n", whatever mpirun needs */ + char* cmd_mdrun, /* mdrun command string */ + char* cmd_args_bench, /* arguments for mdrun in a string */ + const t_filenm* fnm, /* List of filenames from command line */ + int nfile, /* Number of files specified on the cmdl. */ + int presteps, /* DLB equilibration steps, is checked */ + int64_t cpt_steps, /* Time step counter in the checkpoint */ + gmx_bool bCheck, /* Check whether benchmark mdrun works */ + const char* eligible_gpu_ids) /* GPU IDs for + * constructing mdrun command lines */ { int i, nr, k, ret, count = 0, totaltests; - int *nPMEnodes = nullptr; - t_perf *pd = nullptr; + int* nPMEnodes = nullptr; + t_perf* pd = nullptr; int cmdline_length; - char *command, *cmd_stub; + char * command, *cmd_stub; char buf[STRLEN]; gmx_bool bResetProblem = FALSE; gmx_bool bFirst = TRUE; /* This string array corresponds to the eParselog enum type at the start * of this file */ - const char* ParseLog[] = { - "OK.", - "Logfile not found!", - "No timings, logfile truncated?", - "Run was terminated.", - "Counters were not reset properly.", - "No DD grid found for these settings.", - "TPX version conflict!", - "mdrun was not started in parallel!", - "Number of PP ranks has a prime factor that is too large.", - "The number of PP ranks did not suit the number of GPUs.", - "Some GPUs were not detected or are incompatible.", - "An error occurred." - }; + const char* ParseLog[] = { "OK.", + "Logfile not found!", + "No timings, logfile truncated?", + "Run was terminated.", + "Counters were not reset properly.", + "No DD grid found for these settings.", + "TPX version conflict!", + "mdrun was not started in parallel!", + "Number of PP ranks has a prime factor that is too large.", + "The number of PP ranks did not suit the number of GPUs.", + "Some GPUs were not detected or are incompatible.", + "An error occurred." }; char str_PME_f_load[13]; /* Allocate space for the mdrun command line. 100 extra characters should be more than enough for the -npme etcetera arguments */ - cmdline_length = std::strlen(cmd_mpirun) - + std::strlen(cmd_np) - + std::strlen(cmd_mdrun) - + std::strlen(cmd_args_bench) - + std::strlen(tpr_names[0]) + 100; + cmdline_length = std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun) + + std::strlen(cmd_args_bench) + std::strlen(tpr_names[0]) + 100; snew(command, cmdline_length); snew(cmd_stub, cmdline_length); @@ -1448,12 +1455,11 @@ static void do_the_tests( /* Create a list of numbers of PME nodes to test */ if (npme_fixed < -1) { - make_npme_list(npmevalues_opt, pmeentries, &nPMEnodes, - nnodes, minPMEnodes, maxPMEnodes); + make_npme_list(npmevalues_opt, pmeentries, &nPMEnodes, nnodes, minPMEnodes, maxPMEnodes); } else { - *pmeentries = 1; + *pmeentries = 1; snew(nPMEnodes, 1); nPMEnodes[0] = npme_fixed; fprintf(stderr, "Will use a fixed number of %d PME-only ranks.\n", nPMEnodes[0]); @@ -1473,7 +1479,7 @@ static void do_the_tests( /*****************************************/ /* Main loop over all tpr files to test: */ /*****************************************/ - totaltests = nr_tprs*(*pmeentries)*repeats; + totaltests = nr_tprs * (*pmeentries) * repeats; for (k = 0; k < nr_tprs; k++) { fprintf(fp, "\nIndividual timings for input file %d (%s):\n", k, tpr_names[k]); @@ -1494,8 +1500,8 @@ static void do_the_tests( * the -passall (if set) options requires cmd_args_bench to be * at the end of the command line string */ snew(pd->mdrun_cmd_line, cmdline_length); - sprintf(pd->mdrun_cmd_line, "%s-npme %d -s %s %s %s", - cmd_stub, pd->nPMEnodes, tpr_names[k], cmd_args_bench, cmd_gpu_ids.c_str()); + sprintf(pd->mdrun_cmd_line, "%s-npme %d -s %s %s %s", cmd_stub, pd->nPMEnodes, + tpr_names[k], cmd_args_bench, cmd_gpu_ids.c_str()); /* To prevent that all benchmarks fail due to a show-stopper argument * on the mdrun command line, we make a quick check first. @@ -1509,7 +1515,7 @@ static void do_the_tests( * for every .tpr, and the logic for it should be * immediately inside the loop over k, not in * this inner loop. */ - char *temporary_cmd_line; + char* temporary_cmd_line; snew(temporary_cmd_line, cmdline_length); /* TODO -npme 0 is more likely to succeed at low @@ -1520,8 +1526,8 @@ static void do_the_tests( do for this check, but it'll be easier to implement that after some refactoring of how the number of MPI ranks is managed. */ - sprintf(temporary_cmd_line, "%s-npme 0 -nb cpu -s %s %s", - cmd_stub, tpr_names[k], cmd_args_bench); + sprintf(temporary_cmd_line, "%s-npme 0 -nb cpu -s %s %s", cmd_stub, + tpr_names[k], cmd_args_bench); make_sure_it_runs(temporary_cmd_line, cmdline_length, fp, fnm, nfile); } bFirst = FALSE; @@ -1529,15 +1535,14 @@ static void do_the_tests( /* Do a benchmark simulation: */ if (repeats > 1) { - sprintf(buf, ", pass %d/%d", nr+1, repeats); + sprintf(buf, ", pass %d/%d", nr + 1, repeats); } else { buf[0] = '\0'; } fprintf(stdout, "\n=== Progress %2.0f%%, tpr %d/%d, run %d/%d%s:\n", - (100.0*count)/totaltests, - k+1, nr_tprs, i+1, *pmeentries, buf); + (100.0 * count) / totaltests, k + 1, nr_tprs, i + 1, *pmeentries, buf); make_backup(opt2fn("-err", nfile, fnm)); sprintf(command, "%s 1> /dev/null 2>%s", pd->mdrun_cmd_line, opt2fn("-err", nfile, fnm)); fprintf(stdout, "%s\n", pd->mdrun_cmd_line); @@ -1545,8 +1550,8 @@ static void do_the_tests( /* Collect the performance data from the log file; also check stderr * for fatal errors */ - ret = parse_logfile(opt2fn("-bg", nfile, fnm), opt2fn("-err", nfile, fnm), - pd, nr, presteps, cpt_steps, nnodes); + ret = parse_logfile(opt2fn("-bg", nfile, fnm), opt2fn("-err", nfile, fnm), pd, nr, + presteps, cpt_steps, nnodes); if ((presteps > 0) && (ret == eParselogResetProblem)) { bResetProblem = TRUE; @@ -1572,9 +1577,9 @@ static void do_the_tests( } /* Write the data we got to disk */ - fprintf(fp, "%4d%s %12.3f %12.3f %s %s", pd->nPMEnodes, - buf, pd->Gcycles[nr], pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]); - if (!(ret == eParselogOK || ret == eParselogNoDDGrid || ret == eParselogNotFound) ) + fprintf(fp, "%4d%s %12.3f %12.3f %s %s", pd->nPMEnodes, buf, pd->Gcycles[nr], + pd->ns_per_day[nr], str_PME_f_load, ParseLog[ret]); + if (!(ret == eParselogOK || ret == eParselogNoDDGrid || ret == eParselogNotFound)) { fprintf(fp, " Check %s file for problems.", ret == eParselogFatal ? "err" : "log"); } @@ -1588,8 +1593,10 @@ static void do_the_tests( /* If the first run with this number of processors already failed, do not try again: */ if (pd->Gcycles[0] <= 0.0 && repeats > 1) { - fprintf(stdout, "Skipping remaining passes of unsuccessful setting, see log file for details.\n"); - count += repeats-(nr+1); + fprintf(stdout, + "Skipping remaining passes of unsuccessful setting, see log file for " + "details.\n"); + count += repeats - (nr + 1); break; } } /* end of repeats loop */ @@ -1607,23 +1614,22 @@ static void do_the_tests( } -static void check_input( - int nnodes, - int repeats, - int *ntprs, - real *rmin, - real rcoulomb, - real *rmax, - real maxPMEfraction, - real minPMEfraction, - int npme_fixed, - int64_t bench_nsteps, - const t_filenm *fnm, - int nfile, - int sim_part, - int presteps, - int npargs, - t_pargs *pa) +static void check_input(int nnodes, + int repeats, + int* ntprs, + real* rmin, + real rcoulomb, + real* rmax, + real maxPMEfraction, + real minPMEfraction, + int npme_fixed, + int64_t bench_nsteps, + const t_filenm* fnm, + int nfile, + int sim_part, + int presteps, + int npargs, + t_pargs* pa) { int old; @@ -1635,9 +1641,11 @@ static void check_input( } /* Make sure that the checkpoint file is not overwritten during benchmarking */ - if ( (0 == std::strcmp(opt2fn("-cpi", nfile, fnm), opt2fn("-bcpo", nfile, fnm)) ) && (sim_part > 1) ) + if ((0 == std::strcmp(opt2fn("-cpi", nfile, fnm), opt2fn("-bcpo", nfile, fnm))) && (sim_part > 1)) { - gmx_fatal(FARGS, "Checkpoint input (-cpi) and benchmark checkpoint output (-bcpo) files must not be identical.\n" + gmx_fatal(FARGS, + "Checkpoint input (-cpi) and benchmark checkpoint output (-bcpo) files must not " + "be identical.\n" "The checkpoint input file must not be overwritten during the benchmarks.\n"); } @@ -1675,7 +1683,8 @@ static void check_input( { if (1 == *ntprs) { - fprintf(stderr, "Note: Choose ntpr>1 to shift PME load between real and reciprocal space.\n"); + fprintf(stderr, + "Note: Choose ntpr>1 to shift PME load between real and reciprocal space.\n"); } } @@ -1688,36 +1697,36 @@ static void check_input( { *rmax = rcoulomb; } - if (!(*rmin <= *rmax) ) + if (!(*rmin <= *rmax)) { - gmx_fatal(FARGS, "Please choose the Coulomb radii such that rmin <= rmax.\n" - "rmin = %g, rmax = %g, actual rcoul from .tpr file = %g\n", *rmin, *rmax, rcoulomb); + gmx_fatal(FARGS, + "Please choose the Coulomb radii such that rmin <= rmax.\n" + "rmin = %g, rmax = %g, actual rcoul from .tpr file = %g\n", + *rmin, *rmax, rcoulomb); } /* Add test scenarios if rmin or rmax were set */ if (*ntprs <= 2) { - if (!gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) && (*ntprs == 1) ) + if (!gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) && (*ntprs == 1)) { (*ntprs)++; - fprintf(stderr, "NOTE: Setting -rmin to %g changed -ntpr to %d\n", - *rmin, *ntprs); + fprintf(stderr, "NOTE: Setting -rmin to %g changed -ntpr to %d\n", *rmin, *ntprs); } - if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) && (*ntprs == 1) ) + if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) && (*ntprs == 1)) { (*ntprs)++; - fprintf(stderr, "NOTE: Setting -rmax to %g changed -ntpr to %d\n", - *rmax, *ntprs); + fprintf(stderr, "NOTE: Setting -rmax to %g changed -ntpr to %d\n", *rmax, *ntprs); } } old = *ntprs; /* If one of rmin, rmax is set, we need 2 tpr files at minimum */ - if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) || !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) ) + if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) || !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS)) { *ntprs = std::max(*ntprs, 2); } /* If both rmin, rmax are set, we need 3 tpr files at minimum */ - if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) && !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) ) + if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) && !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS)) { *ntprs = std::max(*ntprs, 3); } @@ -1729,9 +1738,11 @@ static void check_input( if (*ntprs > 1) { - if (gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) && gmx_within_tol(rcoulomb, *rmax, GMX_REAL_EPS)) /* We have just a single rc */ + if (gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) + && gmx_within_tol(rcoulomb, *rmax, GMX_REAL_EPS)) /* We have just a single rc */ { - fprintf(stderr, "WARNING: Resetting -ntpr to 1 since no Coulomb radius scaling is requested.\n" + fprintf(stderr, + "WARNING: Resetting -ntpr to 1 since no Coulomb radius scaling is requested.\n" "Please set rmin < rmax to test Coulomb radii in the [rmin, rmax] interval\n" "with correspondingly adjusted PME grid settings\n"); *ntprs = 1; @@ -1762,7 +1773,8 @@ static void check_input( { fprintf(stderr, "WARNING: steps="); fprintf(stderr, "%" PRId64, bench_nsteps); - fprintf(stderr, ". Are you sure you want to perform so %s steps for each benchmark?\n", (bench_nsteps < 100) ? "few" : "many"); + fprintf(stderr, ". Are you sure you want to perform so %s steps for each benchmark?\n", + (bench_nsteps < 100) ? "few" : "many"); } if (presteps < 0) @@ -1773,9 +1785,11 @@ static void check_input( /* Check for rcoulomb scaling if more than one .tpr file is tested */ if (*ntprs > 1) { - if (*rmin/rcoulomb < 0.75 || *rmax/rcoulomb > 1.25) + if (*rmin / rcoulomb < 0.75 || *rmax / rcoulomb > 1.25) { - fprintf(stderr, "WARNING: Applying extreme scaling factor. I hope you know what you are doing.\n"); + fprintf(stderr, + "WARNING: Applying extreme scaling factor. I hope you know what you are " + "doing.\n"); } } @@ -1785,19 +1799,23 @@ static void check_input( if (npme_fixed > -1) { /* No more than 50% of all nodes can be assigned as PME-only nodes. */ - if (2*npme_fixed > nnodes) + if (2 * npme_fixed > nnodes) { - gmx_fatal(FARGS, "Cannot have more than %d PME-only ranks for a total of %d ranks (you chose %d).\n", - nnodes/2, nnodes, npme_fixed); + gmx_fatal(FARGS, + "Cannot have more than %d PME-only ranks for a total of %d ranks (you chose " + "%d).\n", + nnodes / 2, nnodes, npme_fixed); } - if ((npme_fixed > 0) && (5*npme_fixed < nnodes)) + if ((npme_fixed > 0) && (5 * npme_fixed < nnodes)) { - fprintf(stderr, "WARNING: Only %g percent of the ranks are assigned as PME-only ranks.\n", - (100.0*npme_fixed)/nnodes); + fprintf(stderr, + "WARNING: Only %g percent of the ranks are assigned as PME-only ranks.\n", + (100.0 * npme_fixed) / nnodes); } if (opt2parg_bSet("-min", npargs, pa) || opt2parg_bSet("-max", npargs, pa)) { - fprintf(stderr, "NOTE: The -min, -max, and -npme options have no effect when a\n" + fprintf(stderr, + "NOTE: The -min, -max, and -npme options have no effect when a\n" " fixed number of PME-only ranks is requested with -fix.\n"); } } @@ -1805,7 +1823,7 @@ static void check_input( /* Returns TRUE when "opt" is needed at launch time */ -static gmx_bool is_launch_file(char *opt, gmx_bool bSet) +static gmx_bool is_launch_file(char* opt, gmx_bool bSet) { if (0 == std::strncmp(opt, "-swap", 5)) { @@ -1814,8 +1832,8 @@ static gmx_bool is_launch_file(char *opt, gmx_bool bSet) /* Apart from the input .tpr and the output log files we need all options that * were set on the command line and that do not start with -b */ - if (0 == std::strncmp(opt, "-b", 2) || 0 == std::strncmp(opt, "-s", 2) - || 0 == std::strncmp(opt, "-err", 4) || 0 == std::strncmp(opt, "-p", 2) ) + if (0 == std::strncmp(opt, "-b", 2) || 0 == std::strncmp(opt, "-s", 2) + || 0 == std::strncmp(opt, "-err", 4) || 0 == std::strncmp(opt, "-p", 2)) { return FALSE; } @@ -1825,7 +1843,7 @@ static gmx_bool is_launch_file(char *opt, gmx_bool bSet) /* Returns TRUE when "opt" defines a file which is needed for the benchmarks runs */ -static gmx_bool is_bench_file(char *opt, gmx_bool bSet, gmx_bool bOptional, gmx_bool bIsOutput) +static gmx_bool is_bench_file(char* opt, gmx_bool bSet, gmx_bool bOptional, gmx_bool bIsOutput) { /* Apart from the input .tpr, all files starting with "-b" are for * _b_enchmark files exclusively */ @@ -1853,7 +1871,7 @@ static gmx_bool is_bench_file(char *opt, gmx_bool bSet, gmx_bool bOptional, gmx_ /* Adds 'buf' to 'str' */ -static void add_to_string(char **str, const char *buf) +static void add_to_string(char** str, const char* buf) { int len; @@ -1865,21 +1883,21 @@ static void add_to_string(char **str, const char *buf) /* Create the command line for the benchmark as well as for the real run */ -static void create_command_line_snippets( - gmx_bool bAppendFiles, - gmx_bool bKeepAndNumCPT, - gmx_bool bResetHWay, - int presteps, - int nfile, - t_filenm fnm[], - char *cmd_args_bench[], /* command line arguments for benchmark runs */ - char *cmd_args_launch[], /* command line arguments for simulation run */ - char extra_args[], /* Add this to the end of the command line */ - char *deffnm) /* Default file names, or NULL if not set */ +static void +create_command_line_snippets(gmx_bool bAppendFiles, + gmx_bool bKeepAndNumCPT, + gmx_bool bResetHWay, + int presteps, + int nfile, + t_filenm fnm[], + char* cmd_args_bench[], /* command line arguments for benchmark runs */ + char* cmd_args_launch[], /* command line arguments for simulation run */ + char extra_args[], /* Add this to the end of the command line */ + char* deffnm) /* Default file names, or NULL if not set */ { int i; - char *opt; - const char *name; + char* opt; + const char* name; char strbuf[STRLEN]; @@ -1923,13 +1941,13 @@ static void create_command_line_snippets( /********************/ for (i = 0; i < nfile; i++) { - opt = const_cast(fnm[i].opt); + opt = const_cast(fnm[i].opt); name = opt2fn(opt, nfile, fnm); /* Strbuf contains the options, now let's sort out where we need that */ sprintf(strbuf, "%s %s ", opt, name); - if (is_bench_file(opt, opt2bSet(opt, nfile, fnm), is_optional(&fnm[i]), is_output(&fnm[i])) ) + if (is_bench_file(opt, opt2bSet(opt, nfile, fnm), is_optional(&fnm[i]), is_output(&fnm[i]))) { /* All options starting with -b* need the 'b' removed, * therefore overwrite strbuf */ @@ -1941,7 +1959,7 @@ static void create_command_line_snippets( add_to_string(cmd_args_bench, strbuf); } - if (is_launch_file(opt, opt2bSet(opt, nfile, fnm)) ) + if (is_launch_file(opt, opt2bSet(opt, nfile, fnm))) { add_to_string(cmd_args_launch, strbuf); } @@ -1953,7 +1971,7 @@ static void create_command_line_snippets( /* Set option opt */ -static void setopt(const char *opt, int nfile, t_filenm fnm[]) +static void setopt(const char* opt, int nfile, t_filenm fnm[]) { int i; @@ -1973,22 +1991,22 @@ static void setopt(const char *opt, int nfile, t_filenm fnm[]) * tuning run. * 2. returns the PME:PP load ratio * 3. returns rcoulomb from the tpr */ -static float inspect_tpr(int nfile, t_filenm fnm[], real *rcoulomb) +static float inspect_tpr(int nfile, t_filenm fnm[], real* rcoulomb) { - gmx_bool bTpi; /* Is test particle insertion requested? */ - gmx_bool bFree; /* Is a free energy simulation requested? */ - gmx_bool bNM; /* Is a normal mode analysis requested? */ - gmx_bool bSwap; /* Is water/ion position swapping requested? */ - t_state state; - gmx_mtop_t mtop; + gmx_bool bTpi; /* Is test particle insertion requested? */ + gmx_bool bFree; /* Is a free energy simulation requested? */ + gmx_bool bNM; /* Is a normal mode analysis requested? */ + gmx_bool bSwap; /* Is water/ion position swapping requested? */ + t_state state; + gmx_mtop_t mtop; /* Check tpr file for options that trigger extra output files */ t_inputrec irInstance; - t_inputrec *ir = &irInstance; + t_inputrec* ir = &irInstance; read_tpx_state(opt2fn("-s", nfile, fnm), ir, &state, &mtop); - bFree = (efepNO != ir->efep ); - bNM = (eiNM == ir->eI ); + bFree = (efepNO != ir->efep); + bNM = (eiNM == ir->eI); bSwap = (eswapNO != ir->eSwapCoords); bTpi = EI_TPI(ir->eI); @@ -2028,13 +2046,13 @@ static void couple_files_options(int nfile, t_filenm fnm[]) { int i; gmx_bool bSet, bBench; - char *opt; + char* opt; char buf[20]; for (i = 0; i < nfile; i++) { - opt = const_cast(fnm[i].opt); + opt = const_cast(fnm[i].opt); bSet = ((fnm[i].flag & ffSET) != 0); bBench = (0 == std::strncmp(opt, "-b", 2)); @@ -2057,9 +2075,9 @@ static void couple_files_options(int nfile, t_filenm fnm[]) #define BENCHSTEPS (1000) -int gmx_tune_pme(int argc, char *argv[]) +int gmx_tune_pme(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "For a given number [TT]-np[tt] or [TT]-ntmpi[tt] of ranks, [THISMODULE] systematically", "times [gmx-mdrun] with various numbers of PME-only ranks and determines", "which setting is fastest. It will also test whether performance can", @@ -2101,7 +2119,8 @@ int gmx_tune_pme(int argc, char *argv[]) "MD systems. The dynamic load balancing needs about 100 time steps", "to adapt to local load imbalances, therefore the time step counters", "are by default reset after 100 steps. For large systems (>1M atoms), as well as ", - "for a higher accuracy of the measurements, you should set [TT]-resetstep[tt] to a higher value.", + "for a higher accuracy of the measurements, you should set [TT]-resetstep[tt] to a higher ", + "value.", "From the 'DD' load imbalance entries in the md.log output file you", "can tell after how many steps the load is sufficiently balanced. Example call:[PAR]", "[TT]gmx tune_pme -np 64 -s protein.tpr -launch[tt][PAR]", @@ -2113,199 +2132,251 @@ int gmx_tune_pme(int argc, char *argv[]) "optimized parameters, use the command line option [TT]-launch[tt].[PAR]", "Basic support for GPU-enabled [TT]mdrun[tt] exists. Give a string containing the IDs", "of the GPUs that you wish to use in the optimization in the [TT]-gpu_id[tt]", - "command-line argument. This works exactly like [TT]mdrun -gpu_id[tt], does not imply a mapping,", - "and merely declares the eligible set of GPU devices. [TT]gmx-tune_pme[tt] will construct calls to", + "command-line argument. This works exactly like [TT]mdrun -gpu_id[tt], does not imply a ", + "mapping,", + "and merely declares the eligible set of GPU devices. [TT]gmx-tune_pme[tt] will construct ", + "calls to", "mdrun that use this set appropriately. [TT]gmx-tune_pme[tt] does not support", "[TT]-gputasks[tt].[PAR]", }; - int nnodes = 1; - int repeats = 2; - int pmeentries = 0; /* How many values for -npme do we actually test for each tpr file */ - real maxPMEfraction = 0.50; - real minPMEfraction = 0.25; - int maxPMEnodes, minPMEnodes; - float guessPMEratio; /* guessed PME:PP ratio based on the tpr file */ - float guessPMEnodes; - int npme_fixed = -2; /* If >= -1, use only this number - * of PME-only nodes */ - int ntprs = 0; - real rmin = 0.0, rmax = 0.0; /* min and max value for rcoulomb if scaling is requested */ - real rcoulomb = -1.0; /* Coulomb radius as set in .tpr file */ - gmx_bool bScaleRvdw = TRUE; - int64_t bench_nsteps = BENCHSTEPS; - int64_t new_sim_nsteps = -1; /* -1 indicates: not set by the user */ - int64_t cpt_steps = 0; /* Step counter in .cpt input file */ - int presteps = 1500; /* Do a full cycle reset after presteps steps */ - gmx_bool bOverwrite = FALSE, bKeepTPR; - gmx_bool bLaunch = FALSE; - char *ExtraArgs = nullptr; - char **tpr_names = nullptr; - const char *simulation_tpr = nullptr; - char *deffnm = nullptr; - int best_npme, best_tpr; - int sim_part = 1; /* For benchmarks with checkpoint files */ - char bbuf[STRLEN]; + int nnodes = 1; + int repeats = 2; + int pmeentries = 0; /* How many values for -npme do we actually test for each tpr file */ + real maxPMEfraction = 0.50; + real minPMEfraction = 0.25; + int maxPMEnodes, minPMEnodes; + float guessPMEratio; /* guessed PME:PP ratio based on the tpr file */ + float guessPMEnodes; + int npme_fixed = -2; /* If >= -1, use only this number + * of PME-only nodes */ + int ntprs = 0; + real rmin = 0.0, rmax = 0.0; /* min and max value for rcoulomb if scaling is requested */ + real rcoulomb = -1.0; /* Coulomb radius as set in .tpr file */ + gmx_bool bScaleRvdw = TRUE; + int64_t bench_nsteps = BENCHSTEPS; + int64_t new_sim_nsteps = -1; /* -1 indicates: not set by the user */ + int64_t cpt_steps = 0; /* Step counter in .cpt input file */ + int presteps = 1500; /* Do a full cycle reset after presteps steps */ + gmx_bool bOverwrite = FALSE, bKeepTPR; + gmx_bool bLaunch = FALSE; + char* ExtraArgs = nullptr; + char** tpr_names = nullptr; + const char* simulation_tpr = nullptr; + char* deffnm = nullptr; + int best_npme, best_tpr; + int sim_part = 1; /* For benchmarks with checkpoint files */ + char bbuf[STRLEN]; /* Default program names if nothing else is found */ - char *cmd_mpirun = nullptr, *cmd_mdrun = nullptr; - char *cmd_args_bench, *cmd_args_launch; - char *cmd_np = nullptr; + char *cmd_mpirun = nullptr, *cmd_mdrun = nullptr; + char *cmd_args_bench, *cmd_args_launch; + char* cmd_np = nullptr; /* IDs of GPUs that are eligible for computation */ - char *eligible_gpu_ids = nullptr; + char* eligible_gpu_ids = nullptr; - t_perf **perfdata = nullptr; - t_inputinfo *info; - int i; - FILE *fp; + t_perf** perfdata = nullptr; + t_inputinfo* info; + int i; + FILE* fp; /* Print out how long the tuning took */ - double seconds; - - static t_filenm fnm[] = { - /* tune_pme */ - { efOUT, "-p", "perf", ffWRITE }, - { efLOG, "-err", "bencherr", ffWRITE }, - { efTPR, "-so", "tuned", ffWRITE }, - /* mdrun: */ - { efTPR, "-s", nullptr, ffREAD }, - { efTRN, "-o", nullptr, ffWRITE }, - { efCOMPRESSED, "-x", nullptr, ffOPTWR }, - { efCPT, "-cpi", nullptr, ffOPTRD }, - { efCPT, "-cpo", nullptr, ffOPTWR }, - { efSTO, "-c", "confout", ffWRITE }, - { efEDR, "-e", "ener", ffWRITE }, - { efLOG, "-g", "md", ffWRITE }, - { efXVG, "-dhdl", "dhdl", ffOPTWR }, - { efXVG, "-field", "field", ffOPTWR }, - { efXVG, "-table", "table", ffOPTRD }, - { efXVG, "-tablep", "tablep", ffOPTRD }, - { efXVG, "-tableb", "table", ffOPTRD }, - { efTRX, "-rerun", "rerun", ffOPTRD }, - { efXVG, "-tpi", "tpi", ffOPTWR }, - { efXVG, "-tpid", "tpidist", ffOPTWR }, - { efEDI, "-ei", "sam", ffOPTRD }, - { efXVG, "-eo", "edsam", ffOPTWR }, - { efXVG, "-px", "pullx", ffOPTWR }, - { efXVG, "-pf", "pullf", ffOPTWR }, - { efXVG, "-ro", "rotation", ffOPTWR }, - { efLOG, "-ra", "rotangles", ffOPTWR }, - { efLOG, "-rs", "rotslabs", ffOPTWR }, - { efLOG, "-rt", "rottorque", ffOPTWR }, - { efMTX, "-mtx", "nm", ffOPTWR }, - { efXVG, "-swap", "swapions", ffOPTWR }, - /* Output files that are deleted after each benchmark run */ - { efTRN, "-bo", "bench", ffWRITE }, - { efXTC, "-bx", "bench", ffWRITE }, - { efCPT, "-bcpo", "bench", ffWRITE }, - { efSTO, "-bc", "bench", ffWRITE }, - { efEDR, "-be", "bench", ffWRITE }, - { efLOG, "-bg", "bench", ffWRITE }, - { efXVG, "-beo", "benchedo", ffOPTWR }, - { efXVG, "-bdhdl", "benchdhdl", ffOPTWR }, - { efXVG, "-bfield", "benchfld", ffOPTWR }, - { efXVG, "-btpi", "benchtpi", ffOPTWR }, - { efXVG, "-btpid", "benchtpid", ffOPTWR }, - { efXVG, "-bdevout", "benchdev", ffOPTWR }, - { efXVG, "-brunav", "benchrnav", ffOPTWR }, - { efXVG, "-bpx", "benchpx", ffOPTWR }, - { efXVG, "-bpf", "benchpf", ffOPTWR }, - { efXVG, "-bro", "benchrot", ffOPTWR }, - { efLOG, "-bra", "benchrota", ffOPTWR }, - { efLOG, "-brs", "benchrots", ffOPTWR }, - { efLOG, "-brt", "benchrott", ffOPTWR }, - { efMTX, "-bmtx", "benchn", ffOPTWR }, - { efNDX, "-bdn", "bench", ffOPTWR }, - { efXVG, "-bswap", "benchswp", ffOPTWR } + double seconds; + + static t_filenm fnm[] = { /* tune_pme */ + { efOUT, "-p", "perf", ffWRITE }, + { efLOG, "-err", "bencherr", ffWRITE }, + { efTPR, "-so", "tuned", ffWRITE }, + /* mdrun: */ + { efTPR, "-s", nullptr, ffREAD }, + { efTRN, "-o", nullptr, ffWRITE }, + { efCOMPRESSED, "-x", nullptr, ffOPTWR }, + { efCPT, "-cpi", nullptr, ffOPTRD }, + { efCPT, "-cpo", nullptr, ffOPTWR }, + { efSTO, "-c", "confout", ffWRITE }, + { efEDR, "-e", "ener", ffWRITE }, + { efLOG, "-g", "md", ffWRITE }, + { efXVG, "-dhdl", "dhdl", ffOPTWR }, + { efXVG, "-field", "field", ffOPTWR }, + { efXVG, "-table", "table", ffOPTRD }, + { efXVG, "-tablep", "tablep", ffOPTRD }, + { efXVG, "-tableb", "table", ffOPTRD }, + { efTRX, "-rerun", "rerun", ffOPTRD }, + { efXVG, "-tpi", "tpi", ffOPTWR }, + { efXVG, "-tpid", "tpidist", ffOPTWR }, + { efEDI, "-ei", "sam", ffOPTRD }, + { efXVG, "-eo", "edsam", ffOPTWR }, + { efXVG, "-px", "pullx", ffOPTWR }, + { efXVG, "-pf", "pullf", ffOPTWR }, + { efXVG, "-ro", "rotation", ffOPTWR }, + { efLOG, "-ra", "rotangles", ffOPTWR }, + { efLOG, "-rs", "rotslabs", ffOPTWR }, + { efLOG, "-rt", "rottorque", ffOPTWR }, + { efMTX, "-mtx", "nm", ffOPTWR }, + { efXVG, "-swap", "swapions", ffOPTWR }, + /* Output files that are deleted after each benchmark run */ + { efTRN, "-bo", "bench", ffWRITE }, + { efXTC, "-bx", "bench", ffWRITE }, + { efCPT, "-bcpo", "bench", ffWRITE }, + { efSTO, "-bc", "bench", ffWRITE }, + { efEDR, "-be", "bench", ffWRITE }, + { efLOG, "-bg", "bench", ffWRITE }, + { efXVG, "-beo", "benchedo", ffOPTWR }, + { efXVG, "-bdhdl", "benchdhdl", ffOPTWR }, + { efXVG, "-bfield", "benchfld", ffOPTWR }, + { efXVG, "-btpi", "benchtpi", ffOPTWR }, + { efXVG, "-btpid", "benchtpid", ffOPTWR }, + { efXVG, "-bdevout", "benchdev", ffOPTWR }, + { efXVG, "-brunav", "benchrnav", ffOPTWR }, + { efXVG, "-bpx", "benchpx", ffOPTWR }, + { efXVG, "-bpf", "benchpf", ffOPTWR }, + { efXVG, "-bro", "benchrot", ffOPTWR }, + { efLOG, "-bra", "benchrota", ffOPTWR }, + { efLOG, "-brs", "benchrots", ffOPTWR }, + { efLOG, "-brt", "benchrott", ffOPTWR }, + { efMTX, "-bmtx", "benchn", ffOPTWR }, + { efNDX, "-bdn", "bench", ffOPTWR }, + { efXVG, "-bswap", "benchswp", ffOPTWR } }; - gmx_bool bThreads = FALSE; + gmx_bool bThreads = FALSE; - int nthreads = 1; + int nthreads = 1; - const char *procstring[] = - { nullptr, "np", "n", "none", nullptr }; - const char *npmevalues_opt[] = - { nullptr, "auto", "all", "subset", nullptr }; + const char* procstring[] = { nullptr, "np", "n", "none", nullptr }; + const char* npmevalues_opt[] = { nullptr, "auto", "all", "subset", nullptr }; - gmx_bool bAppendFiles = TRUE; - gmx_bool bKeepAndNumCPT = FALSE; - gmx_bool bResetCountersHalfWay = FALSE; - gmx_bool bBenchmark = TRUE; - gmx_bool bCheck = TRUE; + gmx_bool bAppendFiles = TRUE; + gmx_bool bKeepAndNumCPT = FALSE; + gmx_bool bResetCountersHalfWay = FALSE; + gmx_bool bBenchmark = TRUE; + gmx_bool bCheck = TRUE; - gmx_output_env_t *oenv = nullptr; + gmx_output_env_t* oenv = nullptr; - t_pargs pa[] = { + t_pargs pa[] = { /***********************/ /* tune_pme options: */ /***********************/ - { "-mdrun", FALSE, etSTR, {&cmd_mdrun}, + { "-mdrun", + FALSE, + etSTR, + { &cmd_mdrun }, "Command line to run a simulation, e.g. 'gmx mdrun' or 'mdrun_mpi'" }, - { "-np", FALSE, etINT, {&nnodes}, + { "-np", + FALSE, + etINT, + { &nnodes }, "Number of ranks to run the tests on (must be > 2 for separate PME ranks)" }, - { "-npstring", FALSE, etENUM, {procstring}, - "Name of the [TT]$MPIRUN[tt] option that specifies the number of ranks to use ('np', or 'n'; use 'none' if there is no such option)" }, - { "-ntmpi", FALSE, etINT, {&nthreads}, - "Number of MPI-threads to run the tests on (turns MPI & mpirun off)"}, - { "-r", FALSE, etINT, {&repeats}, - "Repeat each test this often" }, - { "-max", FALSE, etREAL, {&maxPMEfraction}, - "Max fraction of PME ranks to test with" }, - { "-min", FALSE, etREAL, {&minPMEfraction}, - "Min fraction of PME ranks to test with" }, - { "-npme", FALSE, etENUM, {npmevalues_opt}, - "Within -min and -max, benchmark all possible values for [TT]-npme[tt], or just a reasonable subset. " - "Auto neglects -min and -max and chooses reasonable values around a guess for npme derived from the .tpr"}, - { "-fix", FALSE, etINT, {&npme_fixed}, - "If >= -1, do not vary the number of PME-only ranks, instead use this fixed value and only vary rcoulomb and the PME grid spacing."}, - { "-rmax", FALSE, etREAL, {&rmax}, - "If >0, maximal rcoulomb for -ntpr>1 (rcoulomb upscaling results in fourier grid downscaling)" }, - { "-rmin", FALSE, etREAL, {&rmin}, - "If >0, minimal rcoulomb for -ntpr>1" }, - { "-scalevdw", FALSE, etBOOL, {&bScaleRvdw}, - "Scale rvdw along with rcoulomb"}, - { "-ntpr", FALSE, etINT, {&ntprs}, - "Number of [REF].tpr[ref] files to benchmark. Create this many files with different rcoulomb scaling factors depending on -rmin and -rmax. " + { "-npstring", + FALSE, + etENUM, + { procstring }, + "Name of the [TT]$MPIRUN[tt] option that specifies the number of ranks to use ('np', or " + "'n'; use 'none' if there is no such option)" }, + { "-ntmpi", + FALSE, + etINT, + { &nthreads }, + "Number of MPI-threads to run the tests on (turns MPI & mpirun off)" }, + { "-r", FALSE, etINT, { &repeats }, "Repeat each test this often" }, + { "-max", FALSE, etREAL, { &maxPMEfraction }, "Max fraction of PME ranks to test with" }, + { "-min", FALSE, etREAL, { &minPMEfraction }, "Min fraction of PME ranks to test with" }, + { "-npme", + FALSE, + etENUM, + { npmevalues_opt }, + "Within -min and -max, benchmark all possible values for [TT]-npme[tt], or just a " + "reasonable subset. " + "Auto neglects -min and -max and chooses reasonable values around a guess for npme " + "derived from the .tpr" }, + { "-fix", + FALSE, + etINT, + { &npme_fixed }, + "If >= -1, do not vary the number of PME-only ranks, instead use this fixed value and " + "only vary rcoulomb and the PME grid spacing." }, + { "-rmax", + FALSE, + etREAL, + { &rmax }, + "If >0, maximal rcoulomb for -ntpr>1 (rcoulomb upscaling results in fourier grid " + "downscaling)" }, + { "-rmin", FALSE, etREAL, { &rmin }, "If >0, minimal rcoulomb for -ntpr>1" }, + { "-scalevdw", FALSE, etBOOL, { &bScaleRvdw }, "Scale rvdw along with rcoulomb" }, + { "-ntpr", + FALSE, + etINT, + { &ntprs }, + "Number of [REF].tpr[ref] files to benchmark. Create this many files with different " + "rcoulomb scaling factors depending on -rmin and -rmax. " "If < 1, automatically choose the number of [REF].tpr[ref] files to test" }, - { "-steps", FALSE, etINT64, {&bench_nsteps}, + { "-steps", + FALSE, + etINT64, + { &bench_nsteps }, "Take timings for this many steps in the benchmark runs" }, - { "-resetstep", FALSE, etINT, {&presteps}, - "Let dlb equilibrate this many steps before timings are taken (reset cycle counters after this many steps)" }, - { "-nsteps", FALSE, etINT64, {&new_sim_nsteps}, - "If non-negative, perform this many steps in the real run (overwrites nsteps from [REF].tpr[ref], add [REF].cpt[ref] steps)" }, - { "-launch", FALSE, etBOOL, {&bLaunch}, - "Launch the real simulation after optimization" }, - { "-bench", FALSE, etBOOL, {&bBenchmark}, + { "-resetstep", + FALSE, + etINT, + { &presteps }, + "Let dlb equilibrate this many steps before timings are taken (reset cycle counters " + "after this many steps)" }, + { "-nsteps", + FALSE, + etINT64, + { &new_sim_nsteps }, + "If non-negative, perform this many steps in the real run (overwrites nsteps from " + "[REF].tpr[ref], add [REF].cpt[ref] steps)" }, + { "-launch", FALSE, etBOOL, { &bLaunch }, "Launch the real simulation after optimization" }, + { "-bench", + FALSE, + etBOOL, + { &bBenchmark }, "Run the benchmarks or just create the input [REF].tpr[ref] files?" }, - { "-check", FALSE, etBOOL, {&bCheck}, + { "-check", + FALSE, + etBOOL, + { &bCheck }, "Before the benchmark runs, check whether mdrun works in parallel" }, - { "-gpu_id", FALSE, etSTR, {&eligible_gpu_ids}, + { "-gpu_id", + FALSE, + etSTR, + { &eligible_gpu_ids }, "List of unique GPU device IDs that are eligible for use" }, /******************/ /* mdrun options: */ /******************/ /* We let tune_pme parse and understand these options, because we need to * prevent that they appear on the mdrun command line for the benchmarks */ - { "-append", FALSE, etBOOL, {&bAppendFiles}, - "Append to previous output files when continuing from checkpoint instead of adding the simulation part number to all file names (for launch only)" }, - { "-cpnum", FALSE, etBOOL, {&bKeepAndNumCPT}, + { "-append", + FALSE, + etBOOL, + { &bAppendFiles }, + "Append to previous output files when continuing from checkpoint instead of adding the " + "simulation part number to all file names (for launch only)" }, + { "-cpnum", + FALSE, + etBOOL, + { &bKeepAndNumCPT }, "Keep and number checkpoint files (launch only)" }, - { "-deffnm", FALSE, etSTR, {&deffnm}, - "Set the default filenames (launch only)" }, - { "-resethway", FALSE, etBOOL, {&bResetCountersHalfWay}, - "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt] (launch only)" } + { "-deffnm", FALSE, etSTR, { &deffnm }, "Set the default filenames (launch only)" }, + { "-resethway", + FALSE, + etBOOL, + { &bResetCountersHalfWay }, + "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt] " + "(launch only)" } }; #define NFILE asize(fnm) seconds = gmx_gettime(); - if (!parse_common_args(&argc, argv, PCA_NOEXIT_ON_ARGS, - NFILE, fnm, asize(pa), pa, asize(desc), desc, - 0, nullptr, &oenv)) + if (!parse_common_args(&argc, argv, PCA_NOEXIT_ON_ARGS, NFILE, fnm, asize(pa), pa, asize(desc), + desc, 0, nullptr, &oenv)) { return 0; } @@ -2373,10 +2444,9 @@ int gmx_tune_pme(int argc, char *argv[]) sim_part = 1; if (opt2bSet("-cpi", NFILE, fnm)) { - const char *filename = opt2fn("-cpi", NFILE, fnm); + const char* filename = opt2fn("-cpi", NFILE, fnm); int cpt_sim_part; - read_checkpoint_part_and_step(filename, - &cpt_sim_part, &cpt_steps); + read_checkpoint_part_and_step(filename, &cpt_sim_part, &cpt_steps); if (cpt_sim_part == 0) { gmx_fatal(FARGS, "Checkpoint file %s could not be read!", filename); @@ -2389,10 +2459,8 @@ int gmx_tune_pme(int argc, char *argv[]) fp = gmx_ffopen(opt2fn("-p", NFILE, fnm), "w"); /* Make a quick consistency check of command line parameters */ - check_input(nnodes, repeats, &ntprs, &rmin, rcoulomb, &rmax, - maxPMEfraction, minPMEfraction, npme_fixed, - bench_nsteps, fnm, NFILE, sim_part, presteps, - asize(pa), pa); + check_input(nnodes, repeats, &ntprs, &rmin, rcoulomb, &rmax, maxPMEfraction, minPMEfraction, + npme_fixed, bench_nsteps, fnm, NFILE, sim_part, presteps, asize(pa), pa); /* Determine the maximum and minimum number of PME nodes to test, * the actual list of settings is build in do_the_tests(). */ @@ -2404,29 +2472,31 @@ int gmx_tune_pme(int argc, char *argv[]) if (guessPMEratio > 1.0) { /* More PME than PP work, probably we do not need separate PME nodes at all! */ - maxPMEnodes = nnodes/2; - minPMEnodes = nnodes/2; + maxPMEnodes = nnodes / 2; + minPMEnodes = nnodes / 2; } else { /* PME : PP load is in the range 0..1, let's test around the guess */ - guessPMEnodes = static_cast(nnodes/(1.0 + 1.0/guessPMEratio)); - minPMEnodes = static_cast(std::floor(0.7*guessPMEnodes)); - maxPMEnodes = static_cast(std::ceil(1.6*guessPMEnodes)); - maxPMEnodes = std::min(maxPMEnodes, nnodes/2); + guessPMEnodes = static_cast(nnodes / (1.0 + 1.0 / guessPMEratio)); + minPMEnodes = static_cast(std::floor(0.7 * guessPMEnodes)); + maxPMEnodes = static_cast(std::ceil(1.6 * guessPMEnodes)); + maxPMEnodes = std::min(maxPMEnodes, nnodes / 2); } } else { /* Determine the npme range based on user input */ - maxPMEnodes = static_cast(std::floor(maxPMEfraction*nnodes)); - minPMEnodes = std::max(static_cast(std::floor(minPMEfraction*nnodes)), 0); + maxPMEnodes = static_cast(std::floor(maxPMEfraction * nnodes)); + minPMEnodes = std::max(static_cast(std::floor(minPMEfraction * nnodes)), 0); fprintf(stdout, "Will try runs with %d ", minPMEnodes); if (maxPMEnodes != minPMEnodes) { fprintf(stdout, "- %d ", maxPMEnodes); } - fprintf(stdout, "PME-only ranks.\n Note that the automatic number of PME-only ranks and no separate PME ranks are always tested.\n"); + fprintf(stdout, + "PME-only ranks.\n Note that the automatic number of PME-only ranks and no " + "separate PME ranks are always tested.\n"); } } else @@ -2446,8 +2516,7 @@ int gmx_tune_pme(int argc, char *argv[]) sep_line(fp); fprintf(fp, "\n P E R F O R M A N C E R E S U L T S\n"); sep_line(fp); - fprintf(fp, "%s for GROMACS %s\n", output_env_get_program_display_name(oenv), - gmx_version()); + fprintf(fp, "%s for GROMACS %s\n", output_env_get_program_display_name(oenv), gmx_version()); if (!bThreads) { fprintf(fp, "Number of ranks : %d\n", nnodes); @@ -2484,7 +2553,7 @@ int gmx_tune_pme(int argc, char *argv[]) { bOverwrite = TRUE; fprintf(stderr, "Note: Simulation input file %s will have ", opt2fn("-so", NFILE, fnm)); - fprintf(stderr, "%" PRId64, new_sim_nsteps+cpt_steps); + fprintf(stderr, "%" PRId64, new_sim_nsteps + cpt_steps); fprintf(stderr, " steps.\n"); fprintf(fp, "Simulation steps : "); fprintf(fp, "%" PRId64, new_sim_nsteps); @@ -2527,8 +2596,8 @@ int gmx_tune_pme(int argc, char *argv[]) /* It can be that ntprs is reduced by make_benchmark_tprs if not enough * different grids could be found. */ - make_benchmark_tprs(opt2fn("-s", NFILE, fnm), tpr_names, bench_nsteps+presteps, - cpt_steps, rmin, rmax, bScaleRvdw, &ntprs, info, fp); + make_benchmark_tprs(opt2fn("-s", NFILE, fnm), tpr_names, bench_nsteps + presteps, cpt_steps, + rmin, rmax, bScaleRvdw, &ntprs, info, fp); /********************************************************************************/ /* Main loop over all scenarios we need to test: tpr files, PME nodes, repeats */ @@ -2536,12 +2605,13 @@ int gmx_tune_pme(int argc, char *argv[]) snew(perfdata, ntprs); if (bBenchmark) { - GMX_RELEASE_ASSERT(npmevalues_opt[0] != nullptr, "Options inconsistency; npmevalues_opt[0] is NULL"); - do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npme_fixed, npmevalues_opt[0], perfdata, &pmeentries, - repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, + GMX_RELEASE_ASSERT(npmevalues_opt[0] != nullptr, + "Options inconsistency; npmevalues_opt[0] is NULL"); + do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npme_fixed, npmevalues_opt[0], perfdata, + &pmeentries, repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, cmd_args_bench, fnm, NFILE, presteps, cpt_steps, bCheck, eligible_gpu_ids); - fprintf(fp, "\nTuning took%8.1f minutes.\n", (gmx_gettime()-seconds)/60.0); + fprintf(fp, "\nTuning took%8.1f minutes.\n", (gmx_gettime() - seconds) / 60.0); /* Analyse the results and give a suggestion for optimal settings: */ bKeepTPR = analyze_data(fp, opt2fn("-p", NFILE, fnm), perfdata, nnodes, ntprs, pmeentries, @@ -2555,7 +2625,7 @@ int gmx_tune_pme(int argc, char *argv[]) else { simulation_tpr = opt2fn("-so", NFILE, fnm); - modify_PMEsettings(bOverwrite ? (new_sim_nsteps+cpt_steps) : info->orig_sim_steps, + modify_PMEsettings(bOverwrite ? (new_sim_nsteps + cpt_steps) : info->orig_sim_steps, info->orig_init_step, tpr_names[best_tpr], simulation_tpr); } @@ -2567,8 +2637,8 @@ int gmx_tune_pme(int argc, char *argv[]) } /* Now start the real simulation if the user requested it ... */ - launch_simulation(bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, - cmd_args_launch, simulation_tpr, best_npme, eligible_gpu_ids); + launch_simulation(bLaunch, fp, bThreads, cmd_mpirun, cmd_np, cmd_mdrun, cmd_args_launch, + simulation_tpr, best_npme, eligible_gpu_ids); } gmx_ffclose(fp); diff --git a/src/gromacs/tools/tune_pme.h b/src/gromacs/tools/tune_pme.h index ec4da7db4e..cedd5f1370 100644 --- a/src/gromacs/tools/tune_pme.h +++ b/src/gromacs/tools/tune_pme.h @@ -40,6 +40,6 @@ * \param[in] argc argc value passed to main(). * \param[in] argv argv array passed to main(). */ -int gmx_tune_pme(int argc, char *argv[]); +int gmx_tune_pme(int argc, char* argv[]); #endif diff --git a/src/gromacs/topology/atomprop.cpp b/src/gromacs/topology/atomprop.cpp index 4333fa7677..f67bf0e2e1 100644 --- a/src/gromacs/topology/atomprop.cpp +++ b/src/gromacs/topology/atomprop.cpp @@ -58,34 +58,44 @@ #include "gromacs/utility/strdb.h" /* NOTFOUND should be smallest, others larger in increasing priority */ -enum { - NOTFOUND = -4, WILDCARD, WILDPROT, PROTEIN +enum +{ + NOTFOUND = -4, + WILDCARD, + WILDPROT, + PROTEIN }; //! Basic entries in AtomProperty. -struct BaseEntry { +struct BaseEntry +{ //! Default constructor. - BaseEntry(const std::string &aName, const std::string &rName) - : atomName(aName), residueName(rName), isAvailable(false), value(0.0) - {} + BaseEntry(const std::string& aName, const std::string& rName) : + atomName(aName), + residueName(rName), + isAvailable(false), + value(0.0) + { + } //! Name for atom. std::string atomName; //! Name for residue. std::string residueName; //! Is property available. - bool isAvailable; + bool isAvailable; //! Value set for property. - real value; + real value; }; //! Conglomeration of atom property entries. -struct AtomProperty { +struct AtomProperty +{ //! Has property been set. - bool isSet = false; + bool isSet = false; //! Database the property is coming from. - std::string db; + std::string db; //! Default value for property. - double def = 0.0; + double def = 0.0; //! Basic entries for properties. std::vector entry; }; @@ -93,15 +103,15 @@ struct AtomProperty { //! Implementation detail type for Atomproperties. class AtomProperties::Impl { - public: - //! Should user be warned about error. - bool bWarned = false; - //! Should user be warned about vdW not found. - bool bWarnVDW = false; - //! The different atom properties. - AtomProperty prop[epropNR]; - //! The residue types. - ResidueType restype; +public: + //! Should user be warned about error. + bool bWarned = false; + //! Should user be warned about vdW not found. + bool bWarnVDW = false; + //! The different atom properties. + AtomProperty prop[epropNR]; + //! The residue types. + ResidueType restype; }; /*! \brief @@ -115,7 +125,7 @@ class AtomProperties::Impl * \param[in] database Name of the database entry to compare to. * \returns Number of matching characters or NOTFOUND. */ -static int compareToDatabase(const std::string &search, const std::string &database) +static int compareToDatabase(const std::string& search, const std::string& database) { if (database.length() > search.length()) { @@ -149,23 +159,24 @@ static int compareToDatabase(const std::string &search, const std::string &datab * \param[in] bExact Do we have the correct match. * \returns The index for the property. */ -static int findPropertyIndex(AtomProperty *ap, ResidueType *restype, - const std::string &residueName, const std::string &atomName, - gmx_bool *bExact) +static int findPropertyIndex(AtomProperty* ap, + ResidueType* restype, + const std::string& residueName, + const std::string& atomName, + gmx_bool* bExact) { - int j = NOTFOUND; + int j = NOTFOUND; - bool bProtein = restype->namedResidueHasType(residueName, "Protein"); - bool bProtWild = residueName == "AAA"; - int malen = NOTFOUND; - int mrlen = NOTFOUND; + bool bProtein = restype->namedResidueHasType(residueName, "Protein"); + bool bProtWild = residueName == "AAA"; + int malen = NOTFOUND; + int mrlen = NOTFOUND; for (size_t i = 0; (i < ap->entry.size()); i++) { int rlen = compareToDatabase(residueName, ap->entry[i].residueName); if (rlen == NOTFOUND) { - if ( (ap->entry[i].residueName == "*") || - (ap->entry[i].residueName == "???") ) + if ((ap->entry[i].residueName == "*") || (ap->entry[i].residueName == "???")) { rlen = WILDCARD; } @@ -175,10 +186,9 @@ static int findPropertyIndex(AtomProperty *ap, ResidueType *restype, } } int alen = compareToDatabase(atomName, ap->entry[i].atomName); - if ( (alen > NOTFOUND) && (rlen > NOTFOUND)) + if ((alen > NOTFOUND) && (rlen > NOTFOUND)) { - if ( ( (alen > malen) && (rlen >= mrlen)) || - ( (rlen > mrlen) && (alen >= malen) ) ) + if (((alen > malen) && (rlen >= mrlen)) || ((rlen > mrlen) && (alen >= malen))) { malen = alen; mrlen = rlen; @@ -187,23 +197,21 @@ static int findPropertyIndex(AtomProperty *ap, ResidueType *restype, } } - *bExact = ((malen == static_cast(atomName.length())) && - ((mrlen == static_cast(residueName.length())) || - ((mrlen == WILDPROT) && bProtWild) || - ((mrlen == WILDCARD) && !bProtein && !bProtWild))); + *bExact = ((malen == static_cast(atomName.length())) + && ((mrlen == static_cast(residueName.length())) || ((mrlen == WILDPROT) && bProtWild) + || ((mrlen == WILDCARD) && !bProtein && !bProtWild))); if (debug) { - fprintf(debug, "searching residue: %4s atom: %4s\n", residueName.c_str(), - atomName.c_str()); + fprintf(debug, "searching residue: %4s atom: %4s\n", residueName.c_str(), atomName.c_str()); if (j == NOTFOUND) { fprintf(debug, " not successful\n"); } else { - fprintf(debug, " match: %4s %4s\n", - ap->entry[j].residueName.c_str(), ap->entry[j].atomName.c_str()); + fprintf(debug, " match: %4s %4s\n", ap->entry[j].residueName.c_str(), + ap->entry[j].atomName.c_str()); } } return j; @@ -219,9 +227,12 @@ static int findPropertyIndex(AtomProperty *ap, ResidueType *restype, * \param[in] propValue Value of property. * \param[in] line Where to add property. */ -static void addProperty(AtomProperty *ap, ResidueType *restype, - const std::string &residueName, const std::string &atomName, - real propValue, int line) +static void addProperty(AtomProperty* ap, + ResidueType* restype, + const std::string& residueName, + const std::string& atomName, + real propValue, + int line) { bool bExact; int j = findPropertyIndex(ap, restype, residueName, atomName, &bExact); @@ -241,10 +252,11 @@ static void addProperty(AtomProperty *ap, ResidueType *restype, } else { - fprintf(stderr, "Warning double different entries %s %s %g and %g on line %d in file %s\n" + fprintf(stderr, + "Warning double different entries %s %s %g and %g on line %d in file %s\n" "Using last entry (%g)\n", - residueName.c_str(), atomName.c_str(), - propValue, ap->entry[j].value, line, ap->db.c_str(), propValue); + residueName.c_str(), atomName.c_str(), propValue, ap->entry[j].value, line, + ap->db.c_str(), propValue); ap->entry[j].value = propValue; } } @@ -262,12 +274,12 @@ static void addProperty(AtomProperty *ap, ResidueType *restype, * \param[in] restype Library of residue types. * \param[in] factor Scaling factor for property. */ -static void readProperty(AtomProperty *ap, ResidueType *restype, double factor) +static void readProperty(AtomProperty* ap, ResidueType* restype, double factor) { - char line[STRLEN], resnm[32], atomnm[32]; + char line[STRLEN], resnm[32], atomnm[32]; - gmx::FilePtr fp = gmx::openLibraryFile(ap->db); - int line_no = 0; + gmx::FilePtr fp = gmx::openLibraryFile(ap->db); + int line_no = 0; while (get_a_line(fp.get(), line, STRLEN)) { line_no++; @@ -279,8 +291,7 @@ static void readProperty(AtomProperty *ap, ResidueType *restype, double factor) } else { - fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", - ap->db.c_str(), line_no); + fprintf(stderr, "WARNING: Error in file %s at line %d ignored\n", ap->db.c_str(), line_no); } } ap->isSet = TRUE; @@ -295,13 +306,14 @@ static void readProperty(AtomProperty *ap, ResidueType *restype, double factor) * \param[in] haveBeenWarned If we already set a warning before * \returns True of warning should be printed. */ -static bool setProperties(AtomProperty *ap, ResidueType *restype, int eprop, bool haveBeenWarned) +static bool setProperties(AtomProperty* ap, ResidueType* restype, int eprop, bool haveBeenWarned) { - const char *fns[epropNR] = { "atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat", "elements.dat" }; - double fac[epropNR] = { 1.0, 1.0, 418.4, 1.0, 1.0 }; - double def[epropNR] = { 12.011, 0.14, 0.0, 2.2, -1 }; + const char* fns[epropNR] = { "atommass.dat", "vdwradii.dat", "dgsolv.dat", "electroneg.dat", + "elements.dat" }; + double fac[epropNR] = { 1.0, 1.0, 418.4, 1.0, 1.0 }; + double def[epropNR] = { 12.011, 0.14, 0.0, 2.2, -1 }; - bool printWarning = false; + bool printWarning = false; if (!ap->isSet) { ap->db = fns[eprop]; @@ -313,30 +325,24 @@ static bool setProperties(AtomProperty *ap, ResidueType *restype, int eprop, boo fprintf(debug, "Entries in %s: %zu\n", ap->db.c_str(), ap->entry.size()); } - if ( (!haveBeenWarned && (eprop == epropMass) ) || (eprop == epropVDW)) + if ((!haveBeenWarned && (eprop == epropMass)) || (eprop == epropVDW)) { printWarning = true; } - } return printWarning; } -AtomProperties::AtomProperties() - : impl_(new Impl) -{ -} +AtomProperties::AtomProperties() : impl_(new Impl) {} -AtomProperties::~AtomProperties() -{ -} +AtomProperties::~AtomProperties() {} -AtomProperty *AtomProperties::prop(int eprop) +AtomProperty* AtomProperties::prop(int eprop) { return &impl_->prop[eprop]; } -ResidueType *AtomProperties::restype() +ResidueType* AtomProperties::restype() { return &impl_->restype; } @@ -353,7 +359,7 @@ static void printWarning() " files if necessary.\n\n"); } -static void printvdwWarning(FILE *fp) +static void printvdwWarning(FILE* fp) { if (nullptr != fp) { @@ -366,13 +372,13 @@ static void printvdwWarning(FILE *fp) } bool AtomProperties::setAtomProperty(int eprop, - const std::string &residueName, - const std::string &atomName, - real *value) + const std::string& residueName, + const std::string& atomName, + real* value) { - int j; - std::string tmpAtomName, tmpResidueName; - gmx_bool bExact; + int j; + std::string tmpAtomName, tmpResidueName; + gmx_bool bExact; if (setProperties(prop(eprop), restype(), eprop, impl_->bWarned)) { @@ -389,8 +395,7 @@ bool AtomProperties::setAtomProperty(int eprop, { tmpAtomName = atomName; } - j = findPropertyIndex(&(impl_->prop[eprop]), &impl_->restype, residueName, - tmpAtomName, &bExact); + j = findPropertyIndex(&(impl_->prop[eprop]), &impl_->restype, residueName, tmpAtomName, &bExact); if (eprop == epropVDW && !impl_->bWarnVDW) { @@ -417,7 +422,7 @@ std::string AtomProperties::elementFromAtomNumber(int atomNumber) printWarning(); impl_->bWarned = true; } - for (const auto &e : prop(epropElement)->entry) + for (const auto& e : prop(epropElement)->entry) { if (std::round(e.value) == atomNumber) { @@ -427,14 +432,14 @@ std::string AtomProperties::elementFromAtomNumber(int atomNumber) return ""; } -int AtomProperties::atomNumberFromElement(const char *element) +int AtomProperties::atomNumberFromElement(const char* element) { if (setProperties(prop(epropElement), restype(), epropElement, impl_->bWarned)) { printWarning(); impl_->bWarned = true; } - for (const auto &e : prop(epropElement)->entry) + for (const auto& e : prop(epropElement)->entry) { if (gmx_strcasecmp(e.atomName.c_str(), element) == 0) { diff --git a/src/gromacs/topology/atomprop.h b/src/gromacs/topology/atomprop.h index 267979c545..7e112b07ae 100644 --- a/src/gromacs/topology/atomprop.h +++ b/src/gromacs/topology/atomprop.h @@ -43,8 +43,13 @@ #include "gromacs/utility/classhelpers.h" #include "gromacs/utility/real.h" -enum { - epropMass, epropVDW, epropDGsol, epropElectroneg, epropElement, +enum +{ + epropMass, + epropVDW, + epropDGsol, + epropElectroneg, + epropElement, epropNR }; @@ -55,65 +60,62 @@ class ResidueType; */ class AtomProperties { - public: - //! Default constructor. - AtomProperties(); - //! Default destructor - ~AtomProperties(); +public: + //! Default constructor. + AtomProperties(); + //! Default destructor + ~AtomProperties(); - /*! \brief - * Get element string from atom number. - * - * \param[in] atomNumber Atomnumber to check. - * \returns Name of the element. - * - * \todo This should be made const once the lazy - * implementation is done properly for the class. - */ - std::string elementFromAtomNumber(int atomNumber); - /*! \brief - * Get atom number from element string. - * - * \param[in] element Name of element. - * \returns AtomNumber that was being looked for. - * - * \todo This should be made const once the lazy - * implementation is done properly for the class. - */ - int atomNumberFromElement(const char *element); - /*! \brief - * Set atom property based on atomname. - * - * Extract a \p value from the database. Returns true - * if this is successful, or false if not. Sets default value - * in the later case. The first time this function is called - * for this property the database will be initialized. - * - * \param[in] eprop Property to set. - * \param[in] residueName Residue name for entry. - * \param[in] atomName Atom name for entry. - * \param[out] value New value to set or default. - * \returns If the operation has been succesful. - */ - bool setAtomProperty(int eprop, - const std::string &residueName, - const std::string &atomName, - real *value); - /*! \brief - * Get handle to property. - * - * \param[in] eprop Which property we need a handle to. - * \returns Pointer to property entry. - */ - AtomProperty *prop(int eprop); - //! Get handle to residuetype library. - ResidueType *restype(); + /*! \brief + * Get element string from atom number. + * + * \param[in] atomNumber Atomnumber to check. + * \returns Name of the element. + * + * \todo This should be made const once the lazy + * implementation is done properly for the class. + */ + std::string elementFromAtomNumber(int atomNumber); + /*! \brief + * Get atom number from element string. + * + * \param[in] element Name of element. + * \returns AtomNumber that was being looked for. + * + * \todo This should be made const once the lazy + * implementation is done properly for the class. + */ + int atomNumberFromElement(const char* element); + /*! \brief + * Set atom property based on atomname. + * + * Extract a \p value from the database. Returns true + * if this is successful, or false if not. Sets default value + * in the later case. The first time this function is called + * for this property the database will be initialized. + * + * \param[in] eprop Property to set. + * \param[in] residueName Residue name for entry. + * \param[in] atomName Atom name for entry. + * \param[out] value New value to set or default. + * \returns If the operation has been succesful. + */ + bool setAtomProperty(int eprop, const std::string& residueName, const std::string& atomName, real* value); + /*! \brief + * Get handle to property. + * + * \param[in] eprop Which property we need a handle to. + * \returns Pointer to property entry. + */ + AtomProperty* prop(int eprop); + //! Get handle to residuetype library. + ResidueType* restype(); - private: - //! Implementation pointer. - class Impl; +private: + //! Implementation pointer. + class Impl; - gmx::PrivateImplPointer impl_; + gmx::PrivateImplPointer impl_; }; #endif diff --git a/src/gromacs/topology/atoms.cpp b/src/gromacs/topology/atoms.cpp index fa0071a64c..4200d75983 100644 --- a/src/gromacs/topology/atoms.cpp +++ b/src/gromacs/topology/atoms.cpp @@ -50,11 +50,9 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/txtdump.h" -const char *ptype_str[eptNR+1] = { - "Atom", "Nucleus", "Shell", "Bond", "VSite", nullptr -}; +const char* ptype_str[eptNR + 1] = { "Atom", "Nucleus", "Shell", "Bond", "VSite", nullptr }; -void init_atom(t_atoms *at) +void init_atom(t_atoms* at) { at->nr = 0; at->nres = 0; @@ -71,13 +69,13 @@ void init_atom(t_atoms *at) at->havePdbInfo = FALSE; } -void init_atomtypes(t_atomtypes *at) +void init_atomtypes(t_atomtypes* at) { at->nr = 0; at->atomnumber = nullptr; } -void done_atom(t_atoms *at) +void done_atom(t_atoms* at) { sfree(at->atom); sfree(at->resinfo); @@ -88,39 +86,39 @@ void done_atom(t_atoms *at) init_atom(at); } -void done_and_delete_atoms(t_atoms *atoms) +void done_and_delete_atoms(t_atoms* atoms) { done_atom(atoms); delete atoms; } -void done_atomtypes(t_atomtypes *atype) +void done_atomtypes(t_atomtypes* atype) { atype->nr = 0; sfree(atype->atomnumber); } -void add_t_atoms(t_atoms *atoms, int natom_extra, int nres_extra) +void add_t_atoms(t_atoms* atoms, int natom_extra, int nres_extra) { int i; if (natom_extra > 0) { - srenew(atoms->atomname, atoms->nr+natom_extra); - srenew(atoms->atom, atoms->nr+natom_extra); + srenew(atoms->atomname, atoms->nr + natom_extra); + srenew(atoms->atom, atoms->nr + natom_extra); if (nullptr != atoms->pdbinfo) { - srenew(atoms->pdbinfo, atoms->nr+natom_extra); + srenew(atoms->pdbinfo, atoms->nr + natom_extra); } if (nullptr != atoms->atomtype) { - srenew(atoms->atomtype, atoms->nr+natom_extra); + srenew(atoms->atomtype, atoms->nr + natom_extra); } if (nullptr != atoms->atomtypeB) { - srenew(atoms->atomtypeB, atoms->nr+natom_extra); + srenew(atoms->atomtypeB, atoms->nr + natom_extra); } - for (i = atoms->nr; (i < atoms->nr+natom_extra); i++) + for (i = atoms->nr; (i < atoms->nr + natom_extra); i++) { atoms->atomname[i] = nullptr; memset(&atoms->atom[i], 0, sizeof(atoms->atom[i])); @@ -141,8 +139,8 @@ void add_t_atoms(t_atoms *atoms, int natom_extra, int nres_extra) } if (nres_extra > 0) { - srenew(atoms->resinfo, atoms->nres+nres_extra); - for (i = atoms->nres; (i < atoms->nres+nres_extra); i++) + srenew(atoms->resinfo, atoms->nres + nres_extra); + for (i = atoms->nres; (i < atoms->nres + nres_extra); i++) { std::memset(&atoms->resinfo[i], 0, sizeof(atoms->resinfo[i])); } @@ -150,7 +148,7 @@ void add_t_atoms(t_atoms *atoms, int natom_extra, int nres_extra) } } -void init_t_atoms(t_atoms *atoms, int natoms, gmx_bool bPdbinfo) +void init_t_atoms(t_atoms* atoms, int natoms, gmx_bool bPdbinfo) { atoms->nr = natoms; atoms->nres = 0; @@ -174,7 +172,7 @@ void init_t_atoms(t_atoms *atoms, int natoms, gmx_bool bPdbinfo) } } -void gmx_pdbinfo_init_default(t_pdbinfo *pdbinfo) +void gmx_pdbinfo_init_default(t_pdbinfo* pdbinfo) { pdbinfo->type = epdbATOM; pdbinfo->atomnr = 0; @@ -183,12 +181,12 @@ void gmx_pdbinfo_init_default(t_pdbinfo *pdbinfo) pdbinfo->occup = 1.0; pdbinfo->bfac = 0.0; pdbinfo->bAnisotropic = FALSE; - std::fill(pdbinfo->uij, pdbinfo->uij+6, 0.0); + std::fill(pdbinfo->uij, pdbinfo->uij + 6, 0.0); } -t_atoms *copy_t_atoms(const t_atoms *src) +t_atoms* copy_t_atoms(const t_atoms* src) { - t_atoms *dst; + t_atoms* dst; int i; snew(dst, 1); @@ -215,7 +213,7 @@ t_atoms *copy_t_atoms(const t_atoms *src) } if (nullptr != src->atomname) { - dst->atomname[i] = src->atomname[i]; + dst->atomname[i] = src->atomname[i]; } if (nullptr != src->atomtype) { @@ -239,11 +237,16 @@ t_atoms *copy_t_atoms(const t_atoms *src) return dst; } -void t_atoms_set_resinfo(t_atoms *atoms, int atom_ind, t_symtab *symtab, - const char *resname, int resnr, unsigned char ic, - int chainnum, char chainid) +void t_atoms_set_resinfo(t_atoms* atoms, + int atom_ind, + t_symtab* symtab, + const char* resname, + int resnr, + unsigned char ic, + int chainnum, + char chainid) { - t_resinfo *ri; + t_resinfo* ri; ri = &atoms->resinfo[atoms->atom[atom_ind].resind]; ri->name = put_symtab(symtab, resname); @@ -254,7 +257,7 @@ void t_atoms_set_resinfo(t_atoms *atoms, int atom_ind, t_symtab *symtab, ri->chainid = chainid; } -static void pr_atom(FILE *fp, int indent, const char *title, const t_atom *atom, int n) +static void pr_atom(FILE* fp, int indent, const char* title, const t_atom* atom, int n) { int i; @@ -264,17 +267,16 @@ static void pr_atom(FILE *fp, int indent, const char *title, const t_atom *atom, for (i = 0; i < n; i++) { pr_indent(fp, indent); - fprintf(fp, "%s[%6d]={type=%3hu, typeB=%3hu, ptype=%8s, m=%12.5e, " + fprintf(fp, + "%s[%6d]={type=%3hu, typeB=%3hu, ptype=%8s, m=%12.5e, " "q=%12.5e, mB=%12.5e, qB=%12.5e, resind=%5d, atomnumber=%3d}\n", - title, i, atom[i].type, atom[i].typeB, ptype_str[atom[i].ptype], - atom[i].m, atom[i].q, atom[i].mB, atom[i].qB, - atom[i].resind, atom[i].atomnumber); + title, i, atom[i].type, atom[i].typeB, ptype_str[atom[i].ptype], atom[i].m, + atom[i].q, atom[i].mB, atom[i].qB, atom[i].resind, atom[i].atomnumber); } } } -static void pr_strings2(FILE *fp, int indent, const char *title, - char ***nm, char ***nmB, int n, gmx_bool bShowNumbers) +static void pr_strings2(FILE* fp, int indent, const char* title, char*** nm, char*** nmB, int n, gmx_bool bShowNumbers) { int i; @@ -284,14 +286,13 @@ static void pr_strings2(FILE *fp, int indent, const char *title, for (i = 0; i < n; i++) { pr_indent(fp, indent); - fprintf(fp, "%s[%d]={name=\"%s\",nameB=\"%s\"}\n", - title, bShowNumbers ? i : -1, *(nm[i]), *(nmB[i])); + fprintf(fp, "%s[%d]={name=\"%s\",nameB=\"%s\"}\n", title, bShowNumbers ? i : -1, + *(nm[i]), *(nmB[i])); } } } -static void pr_resinfo(FILE *fp, int indent, const char *title, const t_resinfo *resinfo, int n, - gmx_bool bShowNumbers) +static void pr_resinfo(FILE* fp, int indent, const char* title, const t_resinfo* resinfo, int n, gmx_bool bShowNumbers) { int i; @@ -301,16 +302,13 @@ static void pr_resinfo(FILE *fp, int indent, const char *title, const t_resinfo for (i = 0; i < n; i++) { pr_indent(fp, indent); - fprintf(fp, "%s[%d]={name=\"%s\", nr=%d, ic='%c'}\n", - title, bShowNumbers ? i : -1, - *(resinfo[i].name), resinfo[i].nr, - (resinfo[i].ic == '\0') ? ' ' : resinfo[i].ic); + fprintf(fp, "%s[%d]={name=\"%s\", nr=%d, ic='%c'}\n", title, bShowNumbers ? i : -1, + *(resinfo[i].name), resinfo[i].nr, (resinfo[i].ic == '\0') ? ' ' : resinfo[i].ic); } } } -void pr_atoms(FILE *fp, int indent, const char *title, const t_atoms *atoms, - gmx_bool bShownumbers) +void pr_atoms(FILE* fp, int indent, const char* title, const t_atoms* atoms, gmx_bool bShownumbers) { if (available(fp, atoms, indent, title)) { @@ -323,8 +321,7 @@ void pr_atoms(FILE *fp, int indent, const char *title, const t_atoms *atoms, } -void pr_atomtypes(FILE *fp, int indent, const char *title, const t_atomtypes *atomtypes, - gmx_bool bShowNumbers) +void pr_atomtypes(FILE* fp, int indent, const char* title, const t_atomtypes* atomtypes, gmx_bool bShowNumbers) { int i; if (available(fp, atomtypes, indent, title)) @@ -333,14 +330,13 @@ void pr_atomtypes(FILE *fp, int indent, const char *title, const t_atomtypes *at for (i = 0; i < atomtypes->nr; i++) { pr_indent(fp, indent); - fprintf(fp, - "atomtype[%3d]={atomnumber=%4d}\n", - bShowNumbers ? i : -1, atomtypes->atomnumber[i]); + fprintf(fp, "atomtype[%3d]={atomnumber=%4d}\n", bShowNumbers ? i : -1, + atomtypes->atomnumber[i]); } } } -static void compareAtom(FILE *fp, int index, const t_atom *a1, const t_atom *a2, real relativeTolerance, real absoluteTolerance) +static void compareAtom(FILE* fp, int index, const t_atom* a1, const t_atom* a2, real relativeTolerance, real absoluteTolerance) { if (a2) { @@ -354,7 +350,6 @@ static void compareAtom(FILE *fp, int index, const t_atom *a1, const t_atom *a2, cmp_real(fp, "atom.mB", index, a1->mB, a2->mB, relativeTolerance, absoluteTolerance); cmp_real(fp, "atom.qB", index, a1->qB, a2->qB, relativeTolerance, absoluteTolerance); cmp_str(fp, "elem", index, a1->elem, a2->elem); - } else { @@ -364,7 +359,7 @@ static void compareAtom(FILE *fp, int index, const t_atom *a1, const t_atom *a2, } } -static void compareResinfo(FILE *fp, int residue, const t_resinfo &r1, const t_resinfo &r2) +static void compareResinfo(FILE* fp, int residue, const t_resinfo& r1, const t_resinfo& r2) { fprintf(fp, "comparing t_resinfo\n"); cmp_str(fp, "name", residue, *r1.name, *r2.name); @@ -372,7 +367,7 @@ static void compareResinfo(FILE *fp, int residue, const t_resinfo &r1, const t_r cmp_uc(fp, "ic", residue, r1.ic, r2.ic); cmp_int(fp, "chainnum", residue, r1.chainnum, r2.chainnum); cmp_uc(fp, "chainid", residue, r1.chainid, r2.chainid); - if ((r1.rtp || r2.rtp ) && (!r1.rtp || !r2.rtp)) + if ((r1.rtp || r2.rtp) && (!r1.rtp || !r2.rtp)) { fprintf(fp, "rtp info is present in topology %d but not in the other\n", r1.rtp ? 1 : 2); } @@ -382,7 +377,12 @@ static void compareResinfo(FILE *fp, int residue, const t_resinfo &r1, const t_r } } -static void comparePdbinfo(FILE *fp, int pdb, const t_pdbinfo &pdb1, const t_pdbinfo &pdb2, real relativeTolerance, real absoluteTolerance) +static void comparePdbinfo(FILE* fp, + int pdb, + const t_pdbinfo& pdb1, + const t_pdbinfo& pdb2, + real relativeTolerance, + real absoluteTolerance) { fprintf(fp, "comparing t_pdbinfo\n"); cmp_int(fp, "type", pdb, pdb1.type, pdb2.type); @@ -400,11 +400,7 @@ static void comparePdbinfo(FILE *fp, int pdb, const t_pdbinfo &pdb1, const t_pdb } -void compareAtoms(FILE *fp, - const t_atoms *a1, - const t_atoms *a2, - real relativeTolerance, - real absoluteTolerance) +void compareAtoms(FILE* fp, const t_atoms* a1, const t_atoms* a2, real relativeTolerance, real absoluteTolerance) { fprintf(fp, "comparing atoms\n"); @@ -451,7 +447,7 @@ void compareAtoms(FILE *fp, } } -void atomsSetMassesBasedOnNames(t_atoms *atoms, gmx_bool printMissingMasses) +void atomsSetMassesBasedOnNames(t_atoms* atoms, gmx_bool printMissingMasses) { if (atoms->haveMass) { @@ -461,26 +457,23 @@ void atomsSetMassesBasedOnNames(t_atoms *atoms, gmx_bool printMissingMasses) return; } - int maxWarn = (printMissingMasses ? 10 : 0); - int numWarn = 0; + int maxWarn = (printMissingMasses ? 10 : 0); + int numWarn = 0; AtomProperties aps; - bool haveMass = true; + bool haveMass = true; for (int i = 0; i < atoms->nr; i++) { - if (!aps.setAtomProperty(epropMass, - *atoms->resinfo[atoms->atom[i].resind].name, - *atoms->atomname[i], - &atoms->atom[i].m)) + if (!aps.setAtomProperty(epropMass, *atoms->resinfo[atoms->atom[i].resind].name, + *atoms->atomname[i], &atoms->atom[i].m)) { haveMass = false; if (numWarn < maxWarn) { fprintf(stderr, "Can not find mass in database for atom %s in residue %d %s\n", - *atoms->atomname[i], - atoms->resinfo[atoms->atom[i].resind].nr, + *atoms->atomname[i], atoms->resinfo[atoms->atom[i].resind].nr, *atoms->resinfo[atoms->atom[i].resind].name); numWarn++; } diff --git a/src/gromacs/topology/atoms.h b/src/gromacs/topology/atoms.h index f9594b6aae..a7314cf7fc 100644 --- a/src/gromacs/topology/atoms.h +++ b/src/gromacs/topology/atoms.h @@ -48,54 +48,71 @@ struct t_symtab; /* The particle type */ -enum { - eptAtom, eptNucleus, eptShell, eptBond, eptVSite, eptNR +enum +{ + eptAtom, + eptNucleus, + eptShell, + eptBond, + eptVSite, + eptNR }; /* The particle type names */ -extern const char *ptype_str[eptNR+1]; +extern const char* ptype_str[eptNR + 1]; /* Enumerated type for pdb records. The other entries are ignored * when reading a pdb file */ -enum PDB_record { - epdbATOM, epdbHETATM, epdbANISOU, epdbCRYST1, epdbCOMPND, - epdbMODEL, epdbENDMDL, epdbTER, epdbHEADER, epdbTITLE, epdbREMARK, - epdbCONECT, epdbNR +enum PDB_record +{ + epdbATOM, + epdbHETATM, + epdbANISOU, + epdbCRYST1, + epdbCOMPND, + epdbMODEL, + epdbENDMDL, + epdbTER, + epdbHEADER, + epdbTITLE, + epdbREMARK, + epdbCONECT, + epdbNR }; typedef struct t_atom { - real m, q; /* Mass and charge */ - real mB, qB; /* Mass and charge for Free Energy calc */ - unsigned short type; /* Atom type */ - unsigned short typeB; /* Atom type for Free Energy calc */ - int ptype; /* Particle type */ - int resind; /* Index into resinfo (in t_atoms) */ - int atomnumber; /* Atomic Number or 0 */ - char elem[4]; /* Element name */ + real m, q; /* Mass and charge */ + real mB, qB; /* Mass and charge for Free Energy calc */ + unsigned short type; /* Atom type */ + unsigned short typeB; /* Atom type for Free Energy calc */ + int ptype; /* Particle type */ + int resind; /* Index into resinfo (in t_atoms) */ + int atomnumber; /* Atomic Number or 0 */ + char elem[4]; /* Element name */ } t_atom; typedef struct t_resinfo { - char **name; /* Pointer to the residue name */ - int nr; /* Residue number */ - unsigned char ic; /* Code for insertion of residues */ - int chainnum; /* Iincremented at TER or new chain id */ - char chainid; /* Chain identifier written/read to pdb */ - char **rtp; /* rtp building block name (optional) */ + char** name; /* Pointer to the residue name */ + int nr; /* Residue number */ + unsigned char ic; /* Code for insertion of residues */ + int chainnum; /* Iincremented at TER or new chain id */ + char chainid; /* Chain identifier written/read to pdb */ + char** rtp; /* rtp building block name (optional) */ } t_resinfo; typedef struct t_pdbinfo { - int type; /* PDB record name */ - int atomnr; /* PDB atom number */ - char altloc; /* Alternate location indicator */ - char atomnm[6]; /* True atom name including leading spaces */ - real occup; /* Occupancy */ - real bfac; /* B-factor */ - gmx_bool bAnisotropic; /* (an)isotropic switch */ - int uij[6]; /* Anisotropic B-factor */ + int type; /* PDB record name */ + int atomnr; /* PDB atom number */ + char altloc; /* Alternate location indicator */ + char atomnm[6]; /* True atom name including leading spaces */ + real occup; /* Occupancy */ + real bfac; /* B-factor */ + gmx_bool bAnisotropic; /* (an)isotropic switch */ + int uij[6]; /* Anisotropic B-factor */ } t_pdbinfo; //! Contains indices into group names for different groups. @@ -103,68 +120,71 @@ using AtomGroupIndices = std::vector; typedef struct t_atoms { - int nr; /* Nr of atoms */ - t_atom *atom; /* Array of atoms (dim: nr) */ - /* The following entries will not */ - /* always be used (nres==0) */ - char ***atomname; /* Array of pointers to atom name */ - /* use: (*(atomname[i])) */ - char ***atomtype; /* Array of pointers to atom types */ - /* use: (*(atomtype[i])) */ - char ***atomtypeB; /* Array of pointers to B atom types */ - /* use: (*(atomtypeB[i])) */ - int nres; /* The number of resinfo entries */ - t_resinfo *resinfo; /* Array of residue names and numbers */ - t_pdbinfo *pdbinfo; /* PDB Information, such as aniso. Bfac */ + int nr; /* Nr of atoms */ + t_atom* atom; /* Array of atoms (dim: nr) */ + /* The following entries will not */ + /* always be used (nres==0) */ + char*** atomname; /* Array of pointers to atom name */ + /* use: (*(atomname[i])) */ + char*** atomtype; /* Array of pointers to atom types */ + /* use: (*(atomtype[i])) */ + char*** atomtypeB; /* Array of pointers to B atom types */ + /* use: (*(atomtypeB[i])) */ + int nres; /* The number of resinfo entries */ + t_resinfo* resinfo; /* Array of residue names and numbers */ + t_pdbinfo* pdbinfo; /* PDB Information, such as aniso. Bfac */ /* Flags that tell if properties are set for all nr atoms. * For B-state parameters, both haveBState and the mass/charge/type * flag should be TRUE. */ - gmx_bool haveMass; /* Mass available */ - gmx_bool haveCharge; /* Charge available */ - gmx_bool haveType; /* Atom type available */ - gmx_bool haveBState; /* B-state parameters available */ - gmx_bool havePdbInfo; /* pdbinfo available */ + gmx_bool haveMass; /* Mass available */ + gmx_bool haveCharge; /* Charge available */ + gmx_bool haveType; /* Atom type available */ + gmx_bool haveBState; /* B-state parameters available */ + gmx_bool havePdbInfo; /* pdbinfo available */ } t_atoms; typedef struct t_atomtypes { - int nr; /* number of atomtypes */ - int *atomnumber; /* Atomic number, used for QM/MM */ + int nr; /* number of atomtypes */ + int* atomnumber; /* Atomic number, used for QM/MM */ } t_atomtypes; #define PERTURBED(a) (((a).mB != (a).m) || ((a).qB != (a).q) || ((a).typeB != (a).type)) -void init_atom(t_atoms *at); -void init_atomtypes(t_atomtypes *at); -void done_atom(t_atoms *at); -void done_and_delete_atoms(t_atoms *atoms); -void done_atomtypes(t_atomtypes *at); +void init_atom(t_atoms* at); +void init_atomtypes(t_atomtypes* at); +void done_atom(t_atoms* at); +void done_and_delete_atoms(t_atoms* atoms); +void done_atomtypes(t_atomtypes* at); -void init_t_atoms(t_atoms *atoms, int natoms, gmx_bool bPdbinfo); +void init_t_atoms(t_atoms* atoms, int natoms, gmx_bool bPdbinfo); /* allocate memory for the arrays, set nr to natoms and nres to 0 * set pdbinfo to NULL or allocate memory for it */ -void gmx_pdbinfo_init_default(t_pdbinfo *pdbinfo); +void gmx_pdbinfo_init_default(t_pdbinfo* pdbinfo); -t_atoms *copy_t_atoms(const t_atoms *src); +t_atoms* copy_t_atoms(const t_atoms* src); /* copy an atoms struct from src to a new one */ -void add_t_atoms(t_atoms *atoms, int natom_extra, int nres_extra); +void add_t_atoms(t_atoms* atoms, int natom_extra, int nres_extra); /* allocate extra space for more atoms and or residues */ -void t_atoms_set_resinfo(t_atoms *atoms, int atom_ind, struct t_symtab *symtab, - const char *resname, int resnr, unsigned char ic, - int chainnum, char chainid); +void t_atoms_set_resinfo(t_atoms* atoms, + int atom_ind, + struct t_symtab* symtab, + const char* resname, + int resnr, + unsigned char ic, + int chainnum, + char chainid); /* Set the residue name, number, insertion code and chain identifier * of atom index atom_ind. */ -void pr_atoms(FILE *fp, int indent, const char *title, const t_atoms *atoms, - gmx_bool bShownumbers); -void pr_atomtypes(FILE *fp, int indent, const char *title, - const t_atomtypes *atomtypes, gmx_bool bShowNumbers); +void pr_atoms(FILE* fp, int indent, const char* title, const t_atoms* atoms, gmx_bool bShownumbers); +void pr_atomtypes(FILE* fp, int indent, const char* title, const t_atomtypes* atomtypes, gmx_bool bShowNumbers); /*! \brief Compare information in the t_atoms data structure. * @@ -174,11 +194,7 @@ void pr_atomtypes(FILE *fp, int indent, const char *title, * \param[in] relativeTolerance Relative floating point comparison tolerance. * \param[in] absoluteTolerance Absolute floating point comparison tolerance. */ -void compareAtoms(FILE *fp, - const t_atoms *a1, - const t_atoms *a2, - real relativeTolerance, - real absoluteTolerance); +void compareAtoms(FILE* fp, const t_atoms* a1, const t_atoms* a2, real relativeTolerance, real absoluteTolerance); /*! \brief Set mass for each atom using the atom and residue names using a database * @@ -186,7 +202,7 @@ void compareAtoms(FILE *fp, * If printMissingMasss = TRUE, prints details for first 10 missing masses * to stderr. */ -void atomsSetMassesBasedOnNames(t_atoms *atoms, gmx_bool printMissingMasses); +void atomsSetMassesBasedOnNames(t_atoms* atoms, gmx_bool printMissingMasses); //! Deleter for t_atoms, needed until it has a proper destructor. using AtomsDataPtr = gmx::unique_cptr; diff --git a/src/gromacs/topology/atomsbuilder.cpp b/src/gromacs/topology/atomsbuilder.cpp index 281c6666c1..6e3b0735c0 100644 --- a/src/gromacs/topology/atomsbuilder.cpp +++ b/src/gromacs/topology/atomsbuilder.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,10 +57,13 @@ namespace gmx * AtomsBuilder */ -AtomsBuilder::AtomsBuilder(t_atoms *atoms, t_symtab *symtab) - : atoms_(atoms), symtab_(symtab), - nrAlloc_(atoms->nr), nresAlloc_(atoms->nres), - currentResidueIndex_(atoms->nres), nextResidueNumber_(-1) +AtomsBuilder::AtomsBuilder(t_atoms* atoms, t_symtab* symtab) : + atoms_(atoms), + symtab_(symtab), + nrAlloc_(atoms->nr), + nresAlloc_(atoms->nres), + currentResidueIndex_(atoms->nres), + nextResidueNumber_(-1) { if (atoms->nres > 0) { @@ -68,11 +71,9 @@ AtomsBuilder::AtomsBuilder(t_atoms *atoms, t_symtab *symtab) } } -AtomsBuilder::~AtomsBuilder() -{ -} +AtomsBuilder::~AtomsBuilder() {} -char **AtomsBuilder::symtabString(char **source) +char** AtomsBuilder::symtabString(char** source) { if (symtab_ != nullptr) { @@ -83,9 +84,9 @@ char **AtomsBuilder::symtabString(char **source) void AtomsBuilder::reserve(int atomCount, int residueCount) { - srenew(atoms_->atom, atomCount); + srenew(atoms_->atom, atomCount); srenew(atoms_->atomname, atomCount); - srenew(atoms_->resinfo, residueCount); + srenew(atoms_->resinfo, residueCount); if (atoms_->pdbinfo != nullptr) { srenew(atoms_->pdbinfo, atomCount); @@ -112,9 +113,9 @@ void AtomsBuilder::setNextResidueNumber(int number) nextResidueNumber_ = number; } -void AtomsBuilder::addAtom(const t_atoms &atoms, int i) +void AtomsBuilder::addAtom(const t_atoms& atoms, int i) { - const int index = atoms_->nr; + const int index = atoms_->nr; atoms_->atom[index] = atoms.atom[i]; atoms_->atomname[index] = symtabString(atoms.atomname[i]); atoms_->atom[index].resind = currentResidueIndex_; @@ -122,7 +123,7 @@ void AtomsBuilder::addAtom(const t_atoms &atoms, int i) { if (atoms.pdbinfo != nullptr) { - atoms_->pdbinfo[index] = atoms.pdbinfo[i]; + atoms_->pdbinfo[index] = atoms.pdbinfo[i]; } else { @@ -132,33 +133,33 @@ void AtomsBuilder::addAtom(const t_atoms &atoms, int i) ++atoms_->nr; } -void AtomsBuilder::startResidue(const t_resinfo &resinfo) +void AtomsBuilder::startResidue(const t_resinfo& resinfo) { if (nextResidueNumber_ == -1) { nextResidueNumber_ = resinfo.nr; } - const int index = atoms_->nres; + const int index = atoms_->nres; atoms_->resinfo[index] = resinfo; atoms_->resinfo[index].nr = nextResidueNumber_; atoms_->resinfo[index].name = symtabString(resinfo.name); ++nextResidueNumber_; - currentResidueIndex_ = index; + currentResidueIndex_ = index; ++atoms_->nres; } -void AtomsBuilder::finishResidue(const t_resinfo &resinfo) +void AtomsBuilder::finishResidue(const t_resinfo& resinfo) { if (nextResidueNumber_ == -1) { nextResidueNumber_ = resinfo.nr; } - const int index = currentResidueIndex_; + const int index = currentResidueIndex_; atoms_->resinfo[index] = resinfo; atoms_->resinfo[index].nr = nextResidueNumber_; atoms_->resinfo[index].name = symtabString(resinfo.name); ++nextResidueNumber_; - currentResidueIndex_ = index + 1; + currentResidueIndex_ = index + 1; if (index >= atoms_->nres) { ++atoms_->nres; @@ -176,10 +177,9 @@ void AtomsBuilder::discardCurrentResidue() atoms_->nres = currentResidueIndex_; } -void AtomsBuilder::mergeAtoms(const t_atoms &atoms) +void AtomsBuilder::mergeAtoms(const t_atoms& atoms) { - if (atoms_->nr + atoms.nr > nrAlloc_ - || atoms_->nres + atoms.nres > nresAlloc_) + if (atoms_->nr + atoms.nr > nrAlloc_ || atoms_->nres + atoms.nres > nresAlloc_) { reserve(atoms_->nr + atoms.nr, atoms_->nres + atoms.nres); } @@ -200,16 +200,11 @@ void AtomsBuilder::mergeAtoms(const t_atoms &atoms) * AtomsRemover */ -AtomsRemover::AtomsRemover(const t_atoms &atoms) - : removed_(atoms.nr, 0) -{ -} +AtomsRemover::AtomsRemover(const t_atoms& atoms) : removed_(atoms.nr, 0) {} -AtomsRemover::~AtomsRemover() -{ -} +AtomsRemover::~AtomsRemover() {} -void AtomsRemover::refreshAtomCount(const t_atoms &atoms) +void AtomsRemover::refreshAtomCount(const t_atoms& atoms) { removed_.resize(atoms.nr, 0); } @@ -219,7 +214,7 @@ void AtomsRemover::markAll() std::fill(removed_.begin(), removed_.end(), 1); } -void AtomsRemover::markResidue(const t_atoms &atoms, int atomIndex, bool bStatus) +void AtomsRemover::markResidue(const t_atoms& atoms, int atomIndex, bool bStatus) { const int resind = atoms.atom[atomIndex].resind; while (atomIndex > 0 && resind == atoms.atom[atomIndex - 1].resind) @@ -233,7 +228,7 @@ void AtomsRemover::markResidue(const t_atoms &atoms, int atomIndex, bool bStatus } } -void AtomsRemover::removeMarkedElements(std::vector *container) const +void AtomsRemover::removeMarkedElements(std::vector* container) const { GMX_RELEASE_ASSERT(container->size() == removed_.size(), "Mismatching contained passed for removing values"); @@ -249,7 +244,7 @@ void AtomsRemover::removeMarkedElements(std::vector *container) const container->resize(j); } -void AtomsRemover::removeMarkedElements(std::vector *container) const +void AtomsRemover::removeMarkedElements(std::vector* container) const { GMX_RELEASE_ASSERT(container->size() == removed_.size(), "Mismatching contained passed for removing values"); @@ -265,7 +260,7 @@ void AtomsRemover::removeMarkedElements(std::vector *container) const container->resize(j); } -void AtomsRemover::removeMarkedAtoms(t_atoms *atoms) const +void AtomsRemover::removeMarkedAtoms(t_atoms* atoms) const { const int originalAtomCount = atoms->nr; AtomsBuilder builder(atoms, nullptr); @@ -274,7 +269,7 @@ void AtomsRemover::removeMarkedAtoms(t_atoms *atoms) const builder.setNextResidueNumber(atoms->resinfo[0].nr); } builder.clearAtoms(); - int prevResInd = -1; + int prevResInd = -1; for (int i = 0; i < originalAtomCount; ++i) { if (!removed_[i]) diff --git a/src/gromacs/topology/atomsbuilder.h b/src/gromacs/topology/atomsbuilder.h index 91e8da9532..e1616ee318 100644 --- a/src/gromacs/topology/atomsbuilder.h +++ b/src/gromacs/topology/atomsbuilder.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,56 +57,56 @@ namespace gmx class AtomsBuilder { - public: - AtomsBuilder(t_atoms *atoms, t_symtab *symtab); - ~AtomsBuilder(); +public: + AtomsBuilder(t_atoms* atoms, t_symtab* symtab); + ~AtomsBuilder(); - void reserve(int atomCount, int residueCount); - void clearAtoms(); + void reserve(int atomCount, int residueCount); + void clearAtoms(); - int currentAtomCount() const; + int currentAtomCount() const; - void setNextResidueNumber(int number); - void addAtom(const t_atoms &atoms, int i); - void startResidue(const t_resinfo &resinfo); - void finishResidue(const t_resinfo &resinfo); - void discardCurrentResidue(); + void setNextResidueNumber(int number); + void addAtom(const t_atoms& atoms, int i); + void startResidue(const t_resinfo& resinfo); + void finishResidue(const t_resinfo& resinfo); + void discardCurrentResidue(); - void mergeAtoms(const t_atoms &atoms); + void mergeAtoms(const t_atoms& atoms); - private: - char **symtabString(char **source); +private: + char** symtabString(char** source); - t_atoms *atoms_; - t_symtab *symtab_; - int nrAlloc_; - int nresAlloc_; - int currentResidueIndex_; - int nextResidueNumber_; + t_atoms* atoms_; + t_symtab* symtab_; + int nrAlloc_; + int nresAlloc_; + int currentResidueIndex_; + int nextResidueNumber_; - GMX_DISALLOW_COPY_AND_ASSIGN(AtomsBuilder); + GMX_DISALLOW_COPY_AND_ASSIGN(AtomsBuilder); }; class AtomsRemover { - public: - explicit AtomsRemover(const t_atoms &atoms); - ~AtomsRemover(); +public: + explicit AtomsRemover(const t_atoms& atoms); + ~AtomsRemover(); - void refreshAtomCount(const t_atoms &atoms); + void refreshAtomCount(const t_atoms& atoms); - void markAll(); - void markResidue(const t_atoms &atoms, int atomIndex, bool bStatus); - bool isMarked(int atomIndex) const { return removed_[atomIndex] != 0; } + void markAll(); + void markResidue(const t_atoms& atoms, int atomIndex, bool bStatus); + bool isMarked(int atomIndex) const { return removed_[atomIndex] != 0; } - void removeMarkedElements(std::vector *container) const; - void removeMarkedElements(std::vector *container) const; - void removeMarkedAtoms(t_atoms *atoms) const; + void removeMarkedElements(std::vector* container) const; + void removeMarkedElements(std::vector* container) const; + void removeMarkedAtoms(t_atoms* atoms) const; - private: - std::vector removed_; +private: + std::vector removed_; - GMX_DISALLOW_COPY_AND_ASSIGN(AtomsRemover); + GMX_DISALLOW_COPY_AND_ASSIGN(AtomsRemover); }; } // namespace gmx diff --git a/src/gromacs/topology/block.cpp b/src/gromacs/topology/block.cpp index 4416300d60..7c1cc84357 100644 --- a/src/gromacs/topology/block.cpp +++ b/src/gromacs/topology/block.cpp @@ -64,33 +64,33 @@ void gmx::RangePartitioning::setAllBlocksSizeOne(int numBlocksToSet) } } -void init_block(t_block *block) +void init_block(t_block* block) { block->nr = 0; block->nalloc_index = 1; snew(block->index, block->nalloc_index); - block->index[0] = 0; + block->index[0] = 0; } -void init_block_null(t_block *block) +void init_block_null(t_block* block) { block->nr = 0; block->nalloc_index = 0; block->index = nullptr; } -void init_blocka(t_blocka *block) +void init_blocka(t_blocka* block) { block->nr = 0; block->nra = 0; block->nalloc_index = 1; snew(block->index, block->nalloc_index); - block->index[0] = 0; - block->nalloc_a = 0; - block->a = nullptr; + block->index[0] = 0; + block->nalloc_a = 0; + block->a = nullptr; } -void init_blocka_null(t_blocka *block) +void init_blocka_null(t_blocka* block) { block->nr = 0; block->nra = 0; @@ -100,9 +100,9 @@ void init_blocka_null(t_blocka *block) block->a = nullptr; } -t_blocka *new_blocka() +t_blocka* new_blocka() { - t_blocka *block; + t_blocka* block; snew(block, 1); snew(block->index, 1); @@ -110,18 +110,18 @@ t_blocka *new_blocka() return block; } -void done_block(t_block *block) +void done_block(t_block* block) { - block->nr = 0; + block->nr = 0; sfree(block->index); block->index = nullptr; block->nalloc_index = 0; } -void done_blocka(t_blocka *block) +void done_blocka(t_blocka* block) { - block->nr = 0; - block->nra = 0; + block->nr = 0; + block->nra = 0; sfree(block->index); sfree(block->a); block->index = nullptr; @@ -130,7 +130,7 @@ void done_blocka(t_blocka *block) block->nalloc_a = 0; } -void stupid_fill_block(t_block *grp, int natom, gmx_bool bOneIndexGroup) +void stupid_fill_block(t_block* grp, int natom, gmx_bool bOneIndexGroup) { if (bOneIndexGroup) { @@ -142,7 +142,7 @@ void stupid_fill_block(t_block *grp, int natom, gmx_bool bOneIndexGroup) } else { - grp->nalloc_index = natom+1; + grp->nalloc_index = natom + 1; srenew(grp->index, grp->nalloc_index); for (int i = 0; i <= natom; ++i) { @@ -152,7 +152,7 @@ void stupid_fill_block(t_block *grp, int natom, gmx_bool bOneIndexGroup) } } -void stupid_fill_blocka(t_blocka *grp, int natom) +void stupid_fill_blocka(t_blocka* grp, int natom) { grp->nalloc_a = natom; snew(grp->a, grp->nalloc_a); @@ -171,20 +171,20 @@ void stupid_fill_blocka(t_blocka *grp, int natom) grp->nr = natom; } -void copy_blocka(const t_blocka *src, t_blocka *dest) +void copy_blocka(const t_blocka* src, t_blocka* dest) { - dest->nr = src->nr; + dest->nr = src->nr; /* Workaround for inconsistent handling of nalloc_index in * other parts of the code. Often nalloc_index and nalloc_a * are not set. */ dest->nalloc_index = std::max(src->nalloc_index, dest->nr + 1); snew(dest->index, dest->nalloc_index); - for (int i = 0; i < dest->nr+1; ++i) + for (int i = 0; i < dest->nr + 1; ++i) { dest->index[i] = src->index[i]; } - dest->nra = src->nra; + dest->nra = src->nra; /* See above. */ dest->nalloc_a = std::max(src->nalloc_a, dest->nra); snew(dest->a, dest->nalloc_a); @@ -194,7 +194,7 @@ void copy_blocka(const t_blocka *src, t_blocka *dest) } } -static int pr_block_title(FILE *fp, int indent, const char *title, const t_block *block) +static int pr_block_title(FILE* fp, int indent, const char* title, const t_block* block) { if (available(fp, block, indent, title)) { @@ -205,7 +205,7 @@ static int pr_block_title(FILE *fp, int indent, const char *title, const t_block return indent; } -static int pr_blocka_title(FILE *fp, int indent, const char *title, const t_blocka *block) +static int pr_blocka_title(FILE* fp, int indent, const char* title, const t_blocka* block) { if (available(fp, block, indent, title)) { @@ -218,7 +218,7 @@ static int pr_blocka_title(FILE *fp, int indent, const char *title, const t_bloc return indent; } -static void low_pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, gmx_bool bShowNumbers) +static void low_pr_blocka(FILE* fp, int indent, const char* title, const t_blocka* block, gmx_bool bShowNumbers) { int i; @@ -227,20 +227,18 @@ static void low_pr_blocka(FILE *fp, int indent, const char *title, const t_block indent = pr_blocka_title(fp, indent, title, block); for (i = 0; i <= block->nr; i++) { - pr_indent(fp, indent+INDENT); - fprintf(fp, "%s->index[%d]=%d\n", - title, bShowNumbers ? i : -1, block->index[i]); + pr_indent(fp, indent + INDENT); + fprintf(fp, "%s->index[%d]=%d\n", title, bShowNumbers ? i : -1, block->index[i]); } for (i = 0; i < block->nra; i++) { - pr_indent(fp, indent+INDENT); - fprintf(fp, "%s->a[%d]=%d\n", - title, bShowNumbers ? i : -1, block->a[i]); + pr_indent(fp, indent + INDENT); + fprintf(fp, "%s->a[%d]=%d\n", title, bShowNumbers ? i : -1, block->a[i]); } } } -void pr_block(FILE *fp, int indent, const char *title, const t_block *block, gmx_bool bShowNumbers) +void pr_block(FILE* fp, int indent, const char* title, const t_block* block, gmx_bool bShowNumbers) { int i, start; @@ -256,7 +254,7 @@ void pr_block(FILE *fp, int indent, const char *title, const t_block *block, gmx { for (i = 0; i < block->nr; i++) { - int end = block->index[i+1]; + int end = block->index[i + 1]; pr_indent(fp, indent); if (end <= start) { @@ -264,9 +262,8 @@ void pr_block(FILE *fp, int indent, const char *title, const t_block *block, gmx } else { - fprintf(fp, "%s[%d]={%d..%d}\n", - title, bShowNumbers ? i : -1, - bShowNumbers ? start : -1, bShowNumbers ? end-1 : -1); + fprintf(fp, "%s[%d]={%d..%d}\n", title, bShowNumbers ? i : -1, + bShowNumbers ? start : -1, bShowNumbers ? end - 1 : -1); } start = end; } @@ -274,7 +271,7 @@ void pr_block(FILE *fp, int indent, const char *title, const t_block *block, gmx } } -void pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, gmx_bool bShowNumbers) +void pr_blocka(FILE* fp, int indent, const char* title, const t_blocka* block, gmx_bool bShowNumbers) { int i, j, ok, size, start, end; @@ -291,7 +288,7 @@ void pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, g { for (i = 0; i < block->nr; i++) { - end = block->index[i+1]; + end = block->index[i + 1]; size = pr_indent(fp, indent); if (end <= start) { @@ -299,9 +296,8 @@ void pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, g } else { - size += fprintf(fp, "%s[%d][%d..%d]={", - title, bShowNumbers ? i : -1, - bShowNumbers ? start : -1, bShowNumbers ? end-1 : -1); + size += fprintf(fp, "%s[%d][%d..%d]={", title, bShowNumbers ? i : -1, + bShowNumbers ? start : -1, bShowNumbers ? end - 1 : -1); } for (j = start; j < end; j++) { @@ -312,7 +308,7 @@ void pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, g if ((size) > (USE_WIDTH)) { fprintf(fp, "\n"); - size = pr_indent(fp, indent+INDENT); + size = pr_indent(fp, indent + INDENT); } size += fprintf(fp, "%d", block->a[j]); } @@ -329,16 +325,16 @@ void pr_blocka(FILE *fp, int indent, const char *title, const t_blocka *block, g } } -void copy_block(const t_block *src, t_block *dst) +void copy_block(const t_block* src, t_block* dst) { - dst->nr = src->nr; + dst->nr = src->nr; /* Workaround for inconsistent handling of nalloc_index in * other parts of the code. Often nalloc_index and nalloc_a * are not set. */ dst->nalloc_index = std::max(src->nalloc_index, dst->nr + 1); snew(dst->index, dst->nalloc_index); - for (int i = 0; i < dst->nr+1; ++i) + for (int i = 0; i < dst->nr + 1; ++i) { dst->index[i] = src->index[i]; } diff --git a/src/gromacs/topology/block.h b/src/gromacs/topology/block.h index 81d769ef3c..8db0164b90 100644 --- a/src/gromacs/topology/block.h +++ b/src/gromacs/topology/block.h @@ -56,81 +56,62 @@ namespace gmx */ class RangePartitioning { - public: - /*! \brief A block defined by a range of atom indices */ - using Block = Range; - - /*! \brief Returns the number of blocks */ - int numBlocks() const - { - return static_cast(index_.size()) - 1; - } - - /*! \brief Returns the size of the block with index \p blockIndex */ - Block block(int blockIndex) const - { - return Block(index_[blockIndex], index_[blockIndex + 1]); - } - - /*! \brief Returns the full range */ - Block fullRange() const - { - return Block(index_.front(), index_.back()); - } - - /*! \brief Returns a range starting at \p blockIndexBegin and ending at \p blockIndexEnd */ - Block subRange(int blockIndexBegin, - int blockIndexEnd) const - { - return Block(index_[blockIndexBegin], index_[blockIndexEnd]); - } - - /*! \brief Returns true when all blocks have size 0 or numBlocks()=0 */ - bool allBlocksHaveSizeOne() const - { - return (index_.back() == numBlocks()); - } - - /*! \brief Appends a block of size \p blockSize at the end of the range - * - * \note blocksize has to be >= 1 - */ - void appendBlock(int blockSize) - { - GMX_ASSERT(blockSize > 0, "block sizes should be >= 1"); - index_.push_back(index_.back() + blockSize); - } - - /*! \brief Removes all blocks */ - void clear() - { - index_.resize(1); - } - - /*! \brief Reduces the number of blocks to \p newNumBlocks - * - * \note \p newNumBlocks should be <= numBlocks(). - */ - void reduceNumBlocks(int newNumBlocks) - { - GMX_ASSERT(newNumBlocks <= numBlocks(), "Can only shrink to fewer blocks"); - index_.resize(newNumBlocks + 1); - } - - /*! \brief Sets the partitioning to \p numBlocks blocks each of size 1 */ - void setAllBlocksSizeOne(int numBlocks); - - /*! \brief Returns the raw block index array, avoid using this */ - std::vector &rawIndex() - { - return index_; - } - - private: - std::vector index_ = { 0 }; /**< The list of block begin/end indices */ +public: + /*! \brief A block defined by a range of atom indices */ + using Block = Range; + + /*! \brief Returns the number of blocks */ + int numBlocks() const { return static_cast(index_.size()) - 1; } + + /*! \brief Returns the size of the block with index \p blockIndex */ + Block block(int blockIndex) const { return Block(index_[blockIndex], index_[blockIndex + 1]); } + + /*! \brief Returns the full range */ + Block fullRange() const { return Block(index_.front(), index_.back()); } + + /*! \brief Returns a range starting at \p blockIndexBegin and ending at \p blockIndexEnd */ + Block subRange(int blockIndexBegin, int blockIndexEnd) const + { + return Block(index_[blockIndexBegin], index_[blockIndexEnd]); + } + + /*! \brief Returns true when all blocks have size 0 or numBlocks()=0 */ + bool allBlocksHaveSizeOne() const { return (index_.back() == numBlocks()); } + + /*! \brief Appends a block of size \p blockSize at the end of the range + * + * \note blocksize has to be >= 1 + */ + void appendBlock(int blockSize) + { + GMX_ASSERT(blockSize > 0, "block sizes should be >= 1"); + index_.push_back(index_.back() + blockSize); + } + + /*! \brief Removes all blocks */ + void clear() { index_.resize(1); } + + /*! \brief Reduces the number of blocks to \p newNumBlocks + * + * \note \p newNumBlocks should be <= numBlocks(). + */ + void reduceNumBlocks(int newNumBlocks) + { + GMX_ASSERT(newNumBlocks <= numBlocks(), "Can only shrink to fewer blocks"); + index_.resize(newNumBlocks + 1); + } + + /*! \brief Sets the partitioning to \p numBlocks blocks each of size 1 */ + void setAllBlocksSizeOne(int numBlocks); + + /*! \brief Returns the raw block index array, avoid using this */ + std::vector& rawIndex() { return index_; } + +private: + std::vector index_ = { 0 }; /**< The list of block begin/end indices */ }; -} // namespace gmx +} // namespace gmx /* Deprecated, C-style version of RangePartitioning */ typedef struct t_block @@ -141,24 +122,24 @@ typedef struct t_block return index[blockIndex + 1] - index[blockIndex]; } - int nr; /* The number of blocks */ - int *index; /* Array of indices (dim: nr+1) */ - int nalloc_index; /* The allocation size for index */ + int nr; /* The number of blocks */ + int* index; /* Array of indices (dim: nr+1) */ + int nalloc_index; /* The allocation size for index */ } t_block; struct t_blocka { - int nr; /* The number of blocks */ - int *index; /* Array of indices in a (dim: nr+1) */ - int nra; /* The number of atoms */ - int *a; /* Array of atom numbers in each group */ + int nr; /* The number of blocks */ + int* index; /* Array of indices in a (dim: nr+1) */ + int nra; /* The number of atoms */ + int* a; /* Array of atom numbers in each group */ /* (dim: nra) */ /* Block i (0<=i b2) +void blockaToExclusionBlocks(const t_blocka* b, gmx::ArrayRef b2) { for (int i = 0; (i < b->nr); i++) { - for (int j = b->index[i]; (j < b->index[i+1]); j++) + for (int j = b->index[i]; (j < b->index[i + 1]); j++) { b2[i].atomNumber.push_back(b->a[j]); } } } -void exclusionBlocksToBlocka(gmx::ArrayRef b2, t_blocka *b) +void exclusionBlocksToBlocka(gmx::ArrayRef b2, t_blocka* b) { int nra = 0; int i = 0; - for (const auto &block : b2) + for (const auto& block : b2) { b->index[i] = nra; - int j = 0; - for (const auto &entry : block.atomNumber) + int j = 0; + for (const auto& entry : block.atomNumber) { - b->a[nra+j] = entry; + b->a[nra + j] = entry; j++; } nra += block.nra(); @@ -79,13 +79,14 @@ void exclusionBlocksToBlocka(gmx::ArrayRef b2, t_blocka *b b->index[i] = nra; } -void mergeExclusions(t_blocka *excl, gmx::ArrayRef b2) +void mergeExclusions(t_blocka* excl, gmx::ArrayRef b2) { if (b2.empty()) { return; } - GMX_RELEASE_ASSERT(b2.ssize() == excl->nr, "Cannot merge exclusions for " + GMX_RELEASE_ASSERT(b2.ssize() == excl->nr, + "Cannot merge exclusions for " "blocks that do not describe the same number " "of particles"); @@ -94,15 +95,16 @@ void mergeExclusions(t_blocka *excl, gmx::ArrayRef b2) /* Count and sort the exclusions */ int nra = 0; - for (auto &block : b2) + for (auto& block : b2) { if (block.nra() > 0) { /* remove double entries */ std::sort(block.atomNumber.begin(), block.atomNumber.end()); - for (auto atom = block.atomNumber.begin() + 1; atom != block.atomNumber.end(); ) + for (auto atom = block.atomNumber.begin() + 1; atom != block.atomNumber.end();) { - GMX_RELEASE_ASSERT(atom < block.atomNumber.end(), "Need to stay in range of the size of the blocks"); + GMX_RELEASE_ASSERT(atom < block.atomNumber.end(), + "Need to stay in range of the size of the blocks"); auto prev = atom - 1; if (*prev == *atom) { @@ -113,7 +115,7 @@ void mergeExclusions(t_blocka *excl, gmx::ArrayRef b2) ++atom; } } - nra += block.nra(); + nra += block.nra(); } } excl->nra = nra; diff --git a/src/gromacs/topology/exclusionblocks.h b/src/gromacs/topology/exclusionblocks.h index 19cee4382c..b27db36093 100644 --- a/src/gromacs/topology/exclusionblocks.h +++ b/src/gromacs/topology/exclusionblocks.h @@ -53,7 +53,7 @@ struct ExclusionBlock //! Atom numbers for exclusion. std::vector atomNumber; //! Number of atoms in the exclusion. - int nra() const { return atomNumber.size(); } + int nra() const { return atomNumber.size(); } }; /*! \brief Merge the contents of \c b2 into \c excl. @@ -61,7 +61,7 @@ struct ExclusionBlock * Requires that \c b2 and \c excl describe the same number of * particles, if \c b2 describes a non-zero number. */ -void mergeExclusions(t_blocka *excl, gmx::ArrayRef b2); +void mergeExclusions(t_blocka* excl, gmx::ArrayRef b2); /*! \brief * Convert the exclusions. @@ -72,10 +72,10 @@ void mergeExclusions(t_blocka *excl, gmx::ArrayRef b2); * \param[in] b Exclusions in t_blocka form. * \param[inout] b2 ExclusionBlocks to populate with t_blocka exclusions. */ -void blockaToExclusionBlocks(const t_blocka *b, gmx::ArrayRef b2); +void blockaToExclusionBlocks(const t_blocka* b, gmx::ArrayRef b2); //! Convert the exclusions expressed in \c b into t_blocka form -void exclusionBlocksToBlocka(gmx::ArrayRef b2, t_blocka *b); +void exclusionBlocksToBlocka(gmx::ArrayRef b2, t_blocka* b); } // namespace gmx diff --git a/src/gromacs/topology/forcefieldparameters.cpp b/src/gromacs/topology/forcefieldparameters.cpp index 1935cd2f94..0ed646e2e4 100644 --- a/src/gromacs/topology/forcefieldparameters.cpp +++ b/src/gromacs/topology/forcefieldparameters.cpp @@ -41,21 +41,20 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/txtdump.h" -static void pr_cmap(FILE *fp, int indent, const char *title, - const gmx_cmap_t *cmap_grid, gmx_bool bShowNumbers) +static void pr_cmap(FILE* fp, int indent, const char* title, const gmx_cmap_t* cmap_grid, gmx_bool bShowNumbers) { int j, nelem; real dx, idx; if (cmap_grid->grid_spacing != 0) { - dx = 360.0 / cmap_grid->grid_spacing; + dx = 360.0 / cmap_grid->grid_spacing; } else { dx = 0; } - nelem = cmap_grid->grid_spacing*cmap_grid->grid_spacing; + nelem = cmap_grid->grid_spacing * cmap_grid->grid_spacing; if (available(fp, cmap_grid, indent, title)) { @@ -70,26 +69,23 @@ static void pr_cmap(FILE *fp, int indent, const char *title, for (j = 0; j < nelem; j++) { - if ( (j%cmap_grid->grid_spacing) == 0) + if ((j % cmap_grid->grid_spacing) == 0) { fprintf(fp, "%8.1f\n", idx); idx += dx; } - fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j*4]); - fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j*4+1]); - fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j*4+2]); - fprintf(fp, "%8.3f\n", cmap_grid->cmapdata[i].cmap[j*4+3]); + fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j * 4]); + fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j * 4 + 1]); + fprintf(fp, "%8.3f ", cmap_grid->cmapdata[i].cmap[j * 4 + 2]); + fprintf(fp, "%8.3f\n", cmap_grid->cmapdata[i].cmap[j * 4 + 3]); } fprintf(fp, "\n"); } } - } -void pr_ffparams(FILE *fp, int indent, const char *title, - const gmx_ffparams_t *ffparams, - gmx_bool bShowNumbers) +void pr_ffparams(FILE* fp, int indent, const char* title, const gmx_ffparams_t* ffparams, gmx_bool bShowNumbers) { int i; @@ -100,9 +96,8 @@ void pr_ffparams(FILE *fp, int indent, const char *title, fprintf(fp, "ntypes=%d\n", ffparams->numTypes()); for (i = 0; i < ffparams->numTypes(); i++) { - pr_indent(fp, indent+INDENT); - fprintf(fp, "functype[%d]=%s, ", - bShowNumbers ? i : -1, + pr_indent(fp, indent + INDENT); + fprintf(fp, "functype[%d]=%s, ", bShowNumbers ? i : -1, interaction_function[ffparams->functype[i]].name); pr_iparams(fp, ffparams->functype[i], &ffparams->iparams[i]); } diff --git a/src/gromacs/topology/forcefieldparameters.h b/src/gromacs/topology/forcefieldparameters.h index 55792988fe..11d9905e4f 100644 --- a/src/gromacs/topology/forcefieldparameters.h +++ b/src/gromacs/topology/forcefieldparameters.h @@ -68,7 +68,6 @@ struct gmx_ffparams_t gmx_cmap_t cmap_grid; /**< The dihedral correction maps */ }; -void pr_ffparams(FILE *fp, int indent, const char *title, - const gmx_ffparams_t *ffparams, gmx_bool bShowNumbers); +void pr_ffparams(FILE* fp, int indent, const char* title, const gmx_ffparams_t* ffparams, gmx_bool bShowNumbers); #endif diff --git a/src/gromacs/topology/idef.cpp b/src/gromacs/topology/idef.cpp index 800135002d..8f394c8375 100644 --- a/src/gromacs/topology/idef.cpp +++ b/src/gromacs/topology/idef.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,140 +45,121 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/txtdump.h" -static void pr_harm(FILE *fp, const t_iparams *iparams, const char *r, const char *kr) +static void pr_harm(FILE* fp, const t_iparams* iparams, const char* r, const char* kr) { - fprintf(fp, "%sA=%12.5e, %sA=%12.5e, %sB=%12.5e, %sB=%12.5e\n", - r, iparams->harmonic.rA, kr, iparams->harmonic.krA, - r, iparams->harmonic.rB, kr, iparams->harmonic.krB); + fprintf(fp, "%sA=%12.5e, %sA=%12.5e, %sB=%12.5e, %sB=%12.5e\n", r, iparams->harmonic.rA, kr, + iparams->harmonic.krA, r, iparams->harmonic.rB, kr, iparams->harmonic.krB); } -void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) +void pr_iparams(FILE* fp, t_functype ftype, const t_iparams* iparams) { switch (ftype) { case F_ANGLES: - case F_G96ANGLES: - pr_harm(fp, iparams, "th", "ct"); - break; + case F_G96ANGLES: pr_harm(fp, iparams, "th", "ct"); break; case F_CROSS_BOND_BONDS: - fprintf(fp, "r1e=%15.8e, r2e=%15.8e, krr=%15.8e\n", - iparams->cross_bb.r1e, iparams->cross_bb.r2e, - iparams->cross_bb.krr); + fprintf(fp, "r1e=%15.8e, r2e=%15.8e, krr=%15.8e\n", iparams->cross_bb.r1e, + iparams->cross_bb.r2e, iparams->cross_bb.krr); break; case F_CROSS_BOND_ANGLES: - fprintf(fp, "r1e=%15.8e, r1e=%15.8e, r3e=%15.8e, krt=%15.8e\n", - iparams->cross_ba.r1e, iparams->cross_ba.r2e, - iparams->cross_ba.r3e, iparams->cross_ba.krt); + fprintf(fp, "r1e=%15.8e, r1e=%15.8e, r3e=%15.8e, krt=%15.8e\n", iparams->cross_ba.r1e, + iparams->cross_ba.r2e, iparams->cross_ba.r3e, iparams->cross_ba.krt); break; case F_LINEAR_ANGLES: - fprintf(fp, "klinA=%15.8e, aA=%15.8e, klinB=%15.8e, aB=%15.8e\n", - iparams->linangle.klinA, iparams->linangle.aA, - iparams->linangle.klinB, iparams->linangle.aB); + fprintf(fp, "klinA=%15.8e, aA=%15.8e, klinB=%15.8e, aB=%15.8e\n", iparams->linangle.klinA, + iparams->linangle.aA, iparams->linangle.klinB, iparams->linangle.aB); break; case F_UREY_BRADLEY: - fprintf(fp, "thetaA=%15.8e, kthetaA=%15.8e, r13A=%15.8e, kUBA=%15.8e, thetaB=%15.8e, kthetaB=%15.8e, r13B=%15.8e, kUBB=%15.8e\n", iparams->u_b.thetaA, iparams->u_b.kthetaA, iparams->u_b.r13A, iparams->u_b.kUBA, iparams->u_b.thetaB, iparams->u_b.kthetaB, iparams->u_b.r13B, iparams->u_b.kUBB); + fprintf(fp, + "thetaA=%15.8e, kthetaA=%15.8e, r13A=%15.8e, kUBA=%15.8e, thetaB=%15.8e, " + "kthetaB=%15.8e, r13B=%15.8e, kUBB=%15.8e\n", + iparams->u_b.thetaA, iparams->u_b.kthetaA, iparams->u_b.r13A, iparams->u_b.kUBA, + iparams->u_b.thetaB, iparams->u_b.kthetaB, iparams->u_b.r13B, iparams->u_b.kUBB); break; case F_QUARTIC_ANGLES: fprintf(fp, "theta=%15.8e", iparams->qangle.theta); for (int i = 0; i < 5; i++) { - fprintf(fp, ", c%c=%15.8e", '0'+i, iparams->qangle.c[i]); + fprintf(fp, ", c%c=%15.8e", '0' + i, iparams->qangle.c[i]); } fprintf(fp, "\n"); break; case F_BHAM: - fprintf(fp, "a=%15.8e, b=%15.8e, c=%15.8e\n", - iparams->bham.a, iparams->bham.b, iparams->bham.c); + fprintf(fp, "a=%15.8e, b=%15.8e, c=%15.8e\n", iparams->bham.a, iparams->bham.b, + iparams->bham.c); break; case F_BONDS: case F_G96BONDS: - case F_HARMONIC: - pr_harm(fp, iparams, "b0", "cb"); - break; - case F_IDIHS: - pr_harm(fp, iparams, "xi", "cx"); - break; + case F_HARMONIC: pr_harm(fp, iparams, "b0", "cb"); break; + case F_IDIHS: pr_harm(fp, iparams, "xi", "cx"); break; case F_MORSE: - fprintf(fp, "b0A=%15.8e, cbA=%15.8e, betaA=%15.8e, b0B=%15.8e, cbB=%15.8e, betaB=%15.8e\n", + fprintf(fp, + "b0A=%15.8e, cbA=%15.8e, betaA=%15.8e, b0B=%15.8e, cbB=%15.8e, betaB=%15.8e\n", iparams->morse.b0A, iparams->morse.cbA, iparams->morse.betaA, iparams->morse.b0B, iparams->morse.cbB, iparams->morse.betaB); break; case F_CUBICBONDS: - fprintf(fp, "b0=%15.8e, kb=%15.8e, kcub=%15.8e\n", - iparams->cubic.b0, iparams->cubic.kb, iparams->cubic.kcub); - break; - case F_CONNBONDS: - fprintf(fp, "\n"); + fprintf(fp, "b0=%15.8e, kb=%15.8e, kcub=%15.8e\n", iparams->cubic.b0, iparams->cubic.kb, + iparams->cubic.kcub); break; + case F_CONNBONDS: fprintf(fp, "\n"); break; case F_FENEBONDS: fprintf(fp, "bm=%15.8e, kb=%15.8e\n", iparams->fene.bm, iparams->fene.kb); break; case F_RESTRBONDS: - fprintf(fp, "lowA=%15.8e, up1A=%15.8e, up2A=%15.8e, kA=%15.8e, lowB=%15.8e, up1B=%15.8e, up2B=%15.8e, kB=%15.8e,\n", - iparams->restraint.lowA, iparams->restraint.up1A, - iparams->restraint.up2A, iparams->restraint.kA, - iparams->restraint.lowB, iparams->restraint.up1B, + fprintf(fp, + "lowA=%15.8e, up1A=%15.8e, up2A=%15.8e, kA=%15.8e, lowB=%15.8e, up1B=%15.8e, " + "up2B=%15.8e, kB=%15.8e,\n", + iparams->restraint.lowA, iparams->restraint.up1A, iparams->restraint.up2A, + iparams->restraint.kA, iparams->restraint.lowB, iparams->restraint.up1B, iparams->restraint.up2B, iparams->restraint.kB); break; case F_TABBONDS: case F_TABBONDSNC: case F_TABANGLES: case F_TABDIHS: - fprintf(fp, "tab=%d, kA=%15.8e, kB=%15.8e\n", - iparams->tab.table, iparams->tab.kA, iparams->tab.kB); - break; - case F_POLARIZATION: - fprintf(fp, "alpha=%15.8e\n", iparams->polarize.alpha); + fprintf(fp, "tab=%d, kA=%15.8e, kB=%15.8e\n", iparams->tab.table, iparams->tab.kA, + iparams->tab.kB); break; + case F_POLARIZATION: fprintf(fp, "alpha=%15.8e\n", iparams->polarize.alpha); break; case F_ANHARM_POL: - fprintf(fp, "alpha=%15.8e drcut=%15.8e khyp=%15.8e\n", - iparams->anharm_polarize.alpha, - iparams->anharm_polarize.drcut, - iparams->anharm_polarize.khyp); + fprintf(fp, "alpha=%15.8e drcut=%15.8e khyp=%15.8e\n", iparams->anharm_polarize.alpha, + iparams->anharm_polarize.drcut, iparams->anharm_polarize.khyp); break; case F_THOLE_POL: - fprintf(fp, "a=%15.8e, alpha1=%15.8e, alpha2=%15.8e, rfac=%15.8e\n", - iparams->thole.a, iparams->thole.alpha1, iparams->thole.alpha2, - iparams->thole.rfac); + fprintf(fp, "a=%15.8e, alpha1=%15.8e, alpha2=%15.8e, rfac=%15.8e\n", iparams->thole.a, + iparams->thole.alpha1, iparams->thole.alpha2, iparams->thole.rfac); break; case F_WATER_POL: fprintf(fp, "al_x=%15.8e, al_y=%15.8e, al_z=%15.8e, rOH=%9.6f, rHH=%9.6f, rOD=%9.6f\n", - iparams->wpol.al_x, iparams->wpol.al_y, iparams->wpol.al_z, - iparams->wpol.rOH, iparams->wpol.rHH, iparams->wpol.rOD); - break; - case F_LJ: - fprintf(fp, "c6=%15.8e, c12=%15.8e\n", iparams->lj.c6, iparams->lj.c12); + iparams->wpol.al_x, iparams->wpol.al_y, iparams->wpol.al_z, iparams->wpol.rOH, + iparams->wpol.rHH, iparams->wpol.rOD); break; + case F_LJ: fprintf(fp, "c6=%15.8e, c12=%15.8e\n", iparams->lj.c6, iparams->lj.c12); break; case F_LJ14: - fprintf(fp, "c6A=%15.8e, c12A=%15.8e, c6B=%15.8e, c12B=%15.8e\n", - iparams->lj14.c6A, iparams->lj14.c12A, - iparams->lj14.c6B, iparams->lj14.c12B); + fprintf(fp, "c6A=%15.8e, c12A=%15.8e, c6B=%15.8e, c12B=%15.8e\n", iparams->lj14.c6A, + iparams->lj14.c12A, iparams->lj14.c6B, iparams->lj14.c12B); break; case F_LJC14_Q: - fprintf(fp, "fqq=%15.8e, qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e\n", - iparams->ljc14.fqq, - iparams->ljc14.qi, iparams->ljc14.qj, - iparams->ljc14.c6, iparams->ljc14.c12); + fprintf(fp, "fqq=%15.8e, qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e\n", iparams->ljc14.fqq, + iparams->ljc14.qi, iparams->ljc14.qj, iparams->ljc14.c6, iparams->ljc14.c12); break; case F_LJC_PAIRS_NB: - fprintf(fp, "qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e\n", - iparams->ljcnb.qi, iparams->ljcnb.qj, - iparams->ljcnb.c6, iparams->ljcnb.c12); + fprintf(fp, "qi=%15.8e, qj=%15.8e, c6=%15.8e, c12=%15.8e\n", iparams->ljcnb.qi, + iparams->ljcnb.qj, iparams->ljcnb.c6, iparams->ljcnb.c12); break; case F_PDIHS: case F_PIDIHS: case F_ANGRES: case F_ANGRESZ: fprintf(fp, "phiA=%15.8e, cpA=%15.8e, phiB=%15.8e, cpB=%15.8e, mult=%d\n", - iparams->pdihs.phiA, iparams->pdihs.cpA, - iparams->pdihs.phiB, iparams->pdihs.cpB, - iparams->pdihs.mult); + iparams->pdihs.phiA, iparams->pdihs.cpA, iparams->pdihs.phiB, + iparams->pdihs.cpB, iparams->pdihs.mult); break; case F_DISRES: fprintf(fp, "label=%4d, type=%1d, low=%15.8e, up1=%15.8e, up2=%15.8e, fac=%15.8e)\n", - iparams->disres.label, iparams->disres.type, - iparams->disres.low, iparams->disres.up1, - iparams->disres.up2, iparams->disres.kfac); + iparams->disres.label, iparams->disres.type, iparams->disres.low, + iparams->disres.up1, iparams->disres.up2, iparams->disres.kfac); break; case F_ORIRES: fprintf(fp, "ex=%4d, label=%d, power=%4d, c=%15.8e, obs=%15.8e, kfac=%15.8e)\n", @@ -186,24 +167,25 @@ void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) iparams->orires.c, iparams->orires.obs, iparams->orires.kfac); break; case F_DIHRES: - fprintf(fp, "phiA=%15.8e, dphiA=%15.8e, kfacA=%15.8e, phiB=%15.8e, dphiB=%15.8e, kfacB=%15.8e\n", + fprintf(fp, + "phiA=%15.8e, dphiA=%15.8e, kfacA=%15.8e, phiB=%15.8e, dphiB=%15.8e, " + "kfacB=%15.8e\n", iparams->dihres.phiA, iparams->dihres.dphiA, iparams->dihres.kfacA, iparams->dihres.phiB, iparams->dihres.dphiB, iparams->dihres.kfacB); break; case F_POSRES: - fprintf(fp, "pos0A=(%15.8e,%15.8e,%15.8e), fcA=(%15.8e,%15.8e,%15.8e), pos0B=(%15.8e,%15.8e,%15.8e), fcB=(%15.8e,%15.8e,%15.8e)\n", - iparams->posres.pos0A[XX], iparams->posres.pos0A[YY], - iparams->posres.pos0A[ZZ], iparams->posres.fcA[XX], - iparams->posres.fcA[YY], iparams->posres.fcA[ZZ], - iparams->posres.pos0B[XX], iparams->posres.pos0B[YY], - iparams->posres.pos0B[ZZ], iparams->posres.fcB[XX], - iparams->posres.fcB[YY], iparams->posres.fcB[ZZ]); + fprintf(fp, + "pos0A=(%15.8e,%15.8e,%15.8e), fcA=(%15.8e,%15.8e,%15.8e), " + "pos0B=(%15.8e,%15.8e,%15.8e), fcB=(%15.8e,%15.8e,%15.8e)\n", + iparams->posres.pos0A[XX], iparams->posres.pos0A[YY], iparams->posres.pos0A[ZZ], + iparams->posres.fcA[XX], iparams->posres.fcA[YY], iparams->posres.fcA[ZZ], + iparams->posres.pos0B[XX], iparams->posres.pos0B[YY], iparams->posres.pos0B[ZZ], + iparams->posres.fcB[XX], iparams->posres.fcB[YY], iparams->posres.fcB[ZZ]); break; case F_FBPOSRES: fprintf(fp, "pos0=(%15.8e,%15.8e,%15.8e), geometry=%d, r=%15.8e, k=%15.8e\n", - iparams->fbposres.pos0[XX], iparams->fbposres.pos0[YY], - iparams->fbposres.pos0[ZZ], iparams->fbposres.geom, - iparams->fbposres.r, iparams->fbposres.k); + iparams->fbposres.pos0[XX], iparams->fbposres.pos0[YY], iparams->fbposres.pos0[ZZ], + iparams->fbposres.geom, iparams->fbposres.r, iparams->fbposres.k); break; case F_RBDIHS: for (int i = 0; i < NR_RBDIHS; i++) @@ -222,19 +204,19 @@ void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) /* Use the OPLS -> Ryckaert-Bellemans formula backwards to get * the OPLS potential constants back. */ - const real *rbcA = iparams->rbdihs.rbcA; - const real *rbcB = iparams->rbdihs.rbcB; + const real* rbcA = iparams->rbdihs.rbcA; + const real* rbcB = iparams->rbdihs.rbcB; real VA[4], VB[4]; - VA[3] = -0.25*rbcA[4]; - VA[2] = -0.5*rbcA[3]; - VA[1] = 4.0*VA[3]-rbcA[2]; - VA[0] = 3.0*VA[2]-2.0*rbcA[1]; + VA[3] = -0.25 * rbcA[4]; + VA[2] = -0.5 * rbcA[3]; + VA[1] = 4.0 * VA[3] - rbcA[2]; + VA[0] = 3.0 * VA[2] - 2.0 * rbcA[1]; - VB[3] = -0.25*rbcB[4]; - VB[2] = -0.5*rbcB[3]; - VB[1] = 4.0*VB[3]-rbcB[2]; - VB[0] = 3.0*VB[2]-2.0*rbcB[1]; + VB[3] = -0.25 * rbcB[4]; + VB[2] = -0.5 * rbcB[3]; + VB[1] = 4.0 * VB[3] - rbcB[2]; + VB[0] = 3.0 * VB[2] - 2.0 * rbcB[1]; for (int i = 0; i < NR_FOURDIHS; i++) { @@ -254,12 +236,9 @@ void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) fprintf(fp, "dA=%15.8e, dB=%15.8e\n", iparams->constr.dA, iparams->constr.dB); break; case F_SETTLE: - fprintf(fp, "doh=%15.8e, dhh=%15.8e\n", iparams->settle.doh, - iparams->settle.dhh); - break; - case F_VSITE2: - fprintf(fp, "a=%15.8e\n", iparams->vsite.a); + fprintf(fp, "doh=%15.8e, dhh=%15.8e\n", iparams->settle.doh, iparams->settle.dhh); break; + case F_VSITE2: fprintf(fp, "a=%15.8e\n", iparams->vsite.a); break; case F_VSITE3: case F_VSITE3FD: case F_VSITE3FAD: @@ -268,8 +247,8 @@ void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) case F_VSITE3OUT: case F_VSITE4FD: case F_VSITE4FDN: - fprintf(fp, "a=%15.8e, b=%15.8e, c=%15.8e\n", - iparams->vsite.a, iparams->vsite.b, iparams->vsite.c); + fprintf(fp, "a=%15.8e, b=%15.8e, c=%15.8e\n", iparams->vsite.a, iparams->vsite.b, + iparams->vsite.c); break; case F_VSITEN: fprintf(fp, "n=%2d, a=%15.8e\n", iparams->vsiten.n, iparams->vsiten.a); @@ -286,35 +265,35 @@ void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams) case F_CMAP: fprintf(fp, "cmapA=%1d, cmapB=%1d\n", iparams->cmap.cmapA, iparams->cmap.cmapB); break; - case F_RESTRANGLES: - pr_harm(fp, iparams, "ktheta", "costheta0"); - break; - case F_RESTRDIHS: - fprintf(fp, "phiA=%15.8e, cpA=%15.8e", - iparams->pdihs.phiA, iparams->pdihs.cpA); + case F_RESTRANGLES: pr_harm(fp, iparams, "ktheta", "costheta0"); break; + case F_RESTRDIHS: + fprintf(fp, "phiA=%15.8e, cpA=%15.8e", iparams->pdihs.phiA, iparams->pdihs.cpA); break; - case F_CBTDIHS: + case F_CBTDIHS: fprintf(fp, "kphi=%15.8e", iparams->cbtdihs.cbtcA[0]); for (int i = 1; i < NR_CBTDIHS; i++) { - fprintf(fp, ", cbtcA[%d]=%15.8e", i-1, iparams->cbtdihs.cbtcA[i]); + fprintf(fp, ", cbtcA[%d]=%15.8e", i - 1, iparams->cbtdihs.cbtcA[i]); } fprintf(fp, "\n"); break; default: - gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", - ftype, interaction_function[ftype].name, __FILE__, __LINE__); + gmx_fatal(FARGS, "unknown function type %d (%s) in %s line %d", ftype, + interaction_function[ftype].name, __FILE__, __LINE__); } } -template -static void -printIlist(FILE *fp, int indent, const char *title, - const t_functype *functype, const T &ilist, - gmx_bool bShowNumbers, - gmx_bool bShowParameters, const t_iparams *iparams) +template +static void printIlist(FILE* fp, + int indent, + const char* title, + const t_functype* functype, + const T& ilist, + gmx_bool bShowNumbers, + gmx_bool bShowParameters, + const t_iparams* iparams) { - int i, j, k, type, ftype; + int i, j, k, type, ftype; indent = pr_title(fp, indent, title); pr_indent(fp, indent); @@ -323,9 +302,9 @@ printIlist(FILE *fp, int indent, const char *title, { pr_indent(fp, indent); fprintf(fp, "iatoms:\n"); - for (i = j = 0; i < ilist.size(); ) + for (i = j = 0; i < ilist.size();) { - pr_indent(fp, indent+INDENT); + pr_indent(fp, indent + INDENT); type = ilist.iatoms[i]; ftype = functype[type]; if (bShowNumbers) @@ -341,25 +320,27 @@ printIlist(FILE *fp, int indent, const char *title, if (bShowParameters) { fprintf(fp, " "); - pr_iparams(fp, ftype, &iparams[type]); + pr_iparams(fp, ftype, &iparams[type]); } fprintf(fp, "\n"); - i += 1+interaction_function[ftype].nratoms; + i += 1 + interaction_function[ftype].nratoms; } } } -void pr_ilist(FILE *fp, int indent, const char *title, - const t_functype *functype, const InteractionList &ilist, - gmx_bool bShowNumbers, - gmx_bool bShowParameters, const t_iparams *iparams) +void pr_ilist(FILE* fp, + int indent, + const char* title, + const t_functype* functype, + const InteractionList& ilist, + gmx_bool bShowNumbers, + gmx_bool bShowParameters, + const t_iparams* iparams) { - printIlist(fp, indent, title, functype, ilist, - bShowNumbers, bShowParameters, iparams); + printIlist(fp, indent, title, functype, ilist, bShowNumbers, bShowParameters, iparams); } -void pr_idef(FILE *fp, int indent, const char *title, const t_idef *idef, - gmx_bool bShowNumbers, gmx_bool bShowParameters) +void pr_idef(FILE* fp, int indent, const char* title, const t_idef* idef, gmx_bool bShowNumbers, gmx_bool bShowParameters) { int i, j; @@ -372,9 +353,8 @@ void pr_idef(FILE *fp, int indent, const char *title, const t_idef *idef, fprintf(fp, "ntypes=%d\n", idef->ntypes); for (i = 0; i < idef->ntypes; i++) { - pr_indent(fp, indent+INDENT); - fprintf(fp, "functype[%d]=%s, ", - bShowNumbers ? i : -1, + pr_indent(fp, indent + INDENT); + fprintf(fp, "functype[%d]=%s, ", bShowNumbers ? i : -1, interaction_function[idef->functype[i]].name); pr_iparams(fp, idef->functype[i], &idef->iparams[i]); } @@ -382,14 +362,13 @@ void pr_idef(FILE *fp, int indent, const char *title, const t_idef *idef, for (j = 0; (j < F_NRE); j++) { - printIlist(fp, indent, interaction_function[j].longname, - idef->functype, idef->il[j], bShowNumbers, - bShowParameters, idef->iparams); + printIlist(fp, indent, interaction_function[j].longname, idef->functype, idef->il[j], + bShowNumbers, bShowParameters, idef->iparams); } } } -void init_idef(t_idef *idef) +void init_idef(t_idef* idef) { idef->ntypes = 0; idef->atnr = 0; @@ -411,7 +390,7 @@ void init_idef(t_idef *idef) idef->ilsort = 0; } -void done_idef(t_idef *idef) +void done_idef(t_idef* idef) { sfree(idef->functype); sfree(idef->iparams); @@ -426,7 +405,7 @@ void done_idef(t_idef *idef) init_idef(idef); } -void copy_ilist(const t_ilist *src, t_ilist *dst) +void copy_ilist(const t_ilist* src, t_ilist* dst) { dst->nr = src->nr; dst->nr_nonperturbed = src->nr_nonperturbed; diff --git a/src/gromacs/topology/idef.h b/src/gromacs/topology/idef.h index 1cf3c8d374..a7a817fc96 100644 --- a/src/gromacs/topology/idef.h +++ b/src/gromacs/topology/idef.h @@ -47,125 +47,166 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -typedef union t_iparams -{ +typedef union t_iparams { /* Some parameters have A and B values for free energy calculations. * The B values are not used for regular simulations of course. * Free Energy for nonbondeds can be computed by changing the atom type. * The harmonic type is used for all harmonic potentials: * bonds, angles and improper dihedrals */ - struct { + struct + { real a, b, c; } bham; - struct { + struct + { real rA, krA, rB, krB; } harmonic; - struct { + struct + { real klinA, aA, klinB, aB; } linangle; - struct { + struct + { real lowA, up1A, up2A, kA, lowB, up1B, up2B, kB; } restraint; /* No free energy supported for cubic bonds, FENE, WPOL or cross terms */ - struct { + struct + { real b0, kb, kcub; } cubic; - struct { + struct + { real bm, kb; } fene; - struct { + struct + { real r1e, r2e, krr; } cross_bb; - struct { + struct + { real r1e, r2e, r3e, krt; } cross_ba; - struct { + struct + { real thetaA, kthetaA, r13A, kUBA, thetaB, kthetaB, r13B, kUBB; } u_b; - struct { + struct + { real theta, c[5]; } qangle; - struct { + struct + { real alpha; } polarize; - struct { + struct + { real alpha, drcut, khyp; } anharm_polarize; - struct { + struct + { real al_x, al_y, al_z, rOH, rHH, rOD; } wpol; - struct { + struct + { real a, alpha1, alpha2, rfac; } thole; - struct { + struct + { real c6, c12; } lj; - struct { + struct + { real c6A, c12A, c6B, c12B; } lj14; - struct { + struct + { real fqq, qi, qj, c6, c12; } ljc14; - struct { + struct + { real qi, qj, c6, c12; } ljcnb; /* Proper dihedrals can not have different multiplicity when * doing free energy calculations, because the potential would not * be periodic anymore. */ - struct { - real phiA, cpA; int mult; real phiB, cpB; + struct + { + real phiA, cpA; + int mult; + real phiB, cpB; } pdihs; - struct { + struct + { real dA, dB; } constr; /* Settle can not be used for Free energy calculations of water bond geometry. * Use shake (or lincs) instead if you have to change the water bonds. */ - struct { + struct + { real doh, dhh; } settle; - struct { + struct + { real b0A, cbA, betaA, b0B, cbB, betaB; } morse; - struct { + struct + { real pos0A[DIM], fcA[DIM], pos0B[DIM], fcB[DIM]; } posres; - struct { - real pos0[DIM], r, k; int geom; + struct + { + real pos0[DIM], r, k; + int geom; } fbposres; - struct { + struct + { real rbcA[NR_RBDIHS], rbcB[NR_RBDIHS]; } rbdihs; - struct { + struct + { real cbtcA[NR_CBTDIHS], cbtcB[NR_CBTDIHS]; } cbtdihs; - struct { + struct + { real a, b, c, d, e, f; } vsite; - struct { - int n; real a; + struct + { + int n; + real a; } vsiten; /* NOTE: npair is only set after reading the tpx file */ - struct { - real low, up1, up2, kfac; int type, label, npair; + struct + { + real low, up1, up2, kfac; + int type, label, npair; } disres; - struct { + struct + { real phiA, dphiA, kfacA, phiB, dphiB, kfacB; } dihres; - struct { - int ex, power, label; real c, obs, kfac; + struct + { + int ex, power, label; + real c, obs, kfac; } orires; - struct { - int table; real kA; real kB; + struct + { + int table; + real kA; + real kB; } tab; - struct { + struct + { int cmapA, cmapB; } cmap; - struct { + struct + { real buf[MAXFORCEPARAM]; - } generic; /* Conversion */ + } generic; /* Conversion */ } t_iparams; typedef int t_functype; @@ -178,10 +219,7 @@ typedef int t_functype; struct InteractionList { /* Returns the total number of elements in iatoms */ - int size() const - { - return gmx::ssize(iatoms); - } + int size() const { return gmx::ssize(iatoms); } /* List of interactions, see explanation further down */ std::vector iatoms; @@ -203,14 +241,11 @@ typedef std::array InteractionLists; struct t_ilist { /* Returns the total number of elements in iatoms */ - int size() const - { - return nr; - } + int size() const { return nr; } int nr; int nr_nonperturbed; - t_iatom *iatoms; + t_iatom* iatoms; int nalloc; }; @@ -247,7 +282,7 @@ struct t_ilist struct InteractionListHandle { const int functionType; //!< The function type - const std::vector &iatoms; //!< Reference to interaction list + const std::vector& iatoms; //!< Reference to interaction list }; /*! \brief Returns a list of all non-empty InteractionList entries with any of the interaction flags in \p flags set @@ -255,9 +290,7 @@ struct InteractionListHandle * \param[in] ilists Set of interaction lists * \param[in] flags Bit mask with one or more IF_... bits set */ -static inline std::vector -extractILists(const InteractionLists &ilists, - int flags) +static inline std::vector extractILists(const InteractionLists& ilists, int flags) { std::vector handles; for (size_t ftype = 0; ftype < ilists.size(); ftype++) @@ -274,7 +307,7 @@ extractILists(const InteractionLists &ilists, * * \param[in] ilistHandle The ilist to return the stride for */ -static inline int ilistStride(const InteractionListHandle &ilistHandle) +static inline int ilistStride(const InteractionListHandle& ilistHandle) { return 1 + NRAL(ilistHandle.functionType); } @@ -288,27 +321,31 @@ struct gmx_cmapdata_t struct gmx_cmap_t { int grid_spacing = 0; /* Grid spacing */ - std::vector cmapdata; /* Lists of grids with actual, pre-interpolated data */ + std::vector cmapdata; /* Lists of grids with actual, pre-interpolated data */ }; -enum { - ilsortUNKNOWN, ilsortNO_FE, ilsortFE_UNSORTED, ilsortFE_SORTED +enum +{ + ilsortUNKNOWN, + ilsortNO_FE, + ilsortFE_UNSORTED, + ilsortFE_SORTED }; typedef struct t_idef { int ntypes; int atnr; - t_functype *functype; - t_iparams *iparams; + t_functype* functype; + t_iparams* iparams; real fudgeQQ; - gmx_cmap_t *cmap_grid; - t_iparams *iparams_posres, *iparams_fbposres; + gmx_cmap_t* cmap_grid; + t_iparams * iparams_posres, *iparams_fbposres; int iparams_posres_nalloc, iparams_fbposres_nalloc; - t_ilist il[F_NRE]; - int ilsort; + t_ilist il[F_NRE]; + int ilsort; } t_idef; /* @@ -345,28 +382,31 @@ typedef struct t_idef * The state of the sorting of il, values are provided above. */ -void pr_iparams(FILE *fp, t_functype ftype, const t_iparams *iparams); -void pr_ilist(FILE *fp, int indent, const char *title, - const t_functype *functype, const InteractionList &ilist, - gmx_bool bShowNumbers, - gmx_bool bShowParameters, const t_iparams *iparams); -void pr_idef(FILE *fp, int indent, const char *title, const t_idef *idef, - gmx_bool bShowNumbers, gmx_bool bShowParameters); +void pr_iparams(FILE* fp, t_functype ftype, const t_iparams* iparams); +void pr_ilist(FILE* fp, + int indent, + const char* title, + const t_functype* functype, + const InteractionList& ilist, + gmx_bool bShowNumbers, + gmx_bool bShowParameters, + const t_iparams* iparams); +void pr_idef(FILE* fp, int indent, const char* title, const t_idef* idef, gmx_bool bShowNumbers, gmx_bool bShowParameters); /*! \brief * Properly initialize idef struct. * * \param[in] idef Pointer to idef struct to initialize. */ -void init_idef(t_idef *idef); +void init_idef(t_idef* idef); /*! \brief * Properly clean up idef struct. * * \param[in] idef Pointer to idef struct to clean up. */ -void done_idef(t_idef *idef); +void done_idef(t_idef* idef); -void copy_ilist(const t_ilist *src, t_ilist *dst); +void copy_ilist(const t_ilist* src, t_ilist* dst); #endif diff --git a/src/gromacs/topology/ifunc.cpp b/src/gromacs/topology/ifunc.cpp index ee60db622a..dded7eeb4d 100644 --- a/src/gromacs/topology/ifunc.cpp +++ b/src/gromacs/topology/ifunc.cpp @@ -39,142 +39,122 @@ #include "ifunc.h" -#define def_bonded(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND} +#define def_bonded(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND \ + } -#define def_bondedz(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_LIMZERO} +#define def_bondedz(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_LIMZERO \ + } -#define def_bondedt(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_TABULATED} +#define def_bondedt(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_TABULATED \ + } -#define def_bondedtz(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_TABULATED | IF_LIMZERO} +#define def_bondedtz(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_TABULATED | IF_LIMZERO \ + } -#define def_angle(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_ATYPE} +#define def_angle(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_ATYPE \ + } -#define def_bond(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND | IF_BTYPE} +#define def_bond(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND | IF_BTYPE \ + } -#define def_bondt(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND | IF_TABULATED} +#define def_bondt(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND | IF_TABULATED \ + } -#define def_bondnb(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND} +#define def_bondnb(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_BOND | IF_CHEMBOND \ + } -#define def_vsite(str, lstr, nra, nrpa) \ - {str, lstr, (nra), (nrpa), 0, IF_VSITE} +#define def_vsite(str, lstr, nra, nrpa) \ + { \ + str, lstr, (nra), (nrpa), 0, IF_VSITE \ + } -#define def_shk(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_CONSTRAINT} +#define def_shk(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_CONSTRAINT \ + } -#define def_shkcb(str, lstr, nra, nrpa, nrpb) \ - {str, lstr, (nra), (nrpa), (nrpb), IF_CONSTRAINT | IF_CHEMBOND} +#define def_shkcb(str, lstr, nra, nrpa, nrpb) \ + { \ + str, lstr, (nra), (nrpa), (nrpb), IF_CONSTRAINT | IF_CHEMBOND \ + } -#define def_nb(str, lstr, nra, nrp) \ - {str, lstr, (nra), (nrp), 0, IF_NULL} +#define def_nb(str, lstr, nra, nrp) \ + { \ + str, lstr, (nra), (nrp), 0, IF_NULL \ + } -#define def_nofc(str, lstr) \ - {str, lstr, 0, 0, 0, IF_NULL} +#define def_nofc(str, lstr) \ + { \ + str, lstr, 0, 0, 0, IF_NULL \ + } /* this MUST correspond to the enum in src/gromacs/topology/ifunc.h */ -const t_interaction_function interaction_function[F_NRE] = -{ - def_bond ("BONDS", "Bond", 2, 2, 2), - def_bond ("G96BONDS", "G96Bond", 2, 2, 2), - def_bond ("MORSE", "Morse", 2, 3, 3), - def_bond ("CUBICBONDS", "Cubic Bonds", 2, 3, 0), - def_bondnb ("CONNBONDS", "Connect Bonds", 2, 0, 0), - def_bonded ("HARMONIC", "Harmonic Pot.", 2, 2, 2), - def_bondnb ("FENEBONDS", "FENE Bonds", 2, 2, 0), - def_bondt ("TABBONDS", "Tab. Bonds", 2, 2, 2), - def_bondedtz("TABBONDSNC", "Tab. Bonds NC", 2, 2, 2), - def_bonded ("RESTRAINTPOT", "Restraint Pot.", 2, 4, 4), - def_angle ("ANGLES", "Angle", 3, 2, 2), - def_angle ("G96ANGLES", "G96Angle", 3, 2, 2), - def_angle ("RESTRANGLES", "Restricted Angles", 3, 2, 2), - def_angle ("LINEAR_ANGLES", "Lin. Angle", 3, 2, 2), - def_bonded ("CROSS_BOND_BOND", "Bond-Cross", 3, 3, 0), - def_bonded ("CROSS_BOND_ANGLE", "BA-Cross", 3, 4, 0), - def_angle ("UREY_BRADLEY", "U-B", 3, 4, 4), - def_angle ("QANGLES", "Quartic Angles", 3, 6, 0), - def_bondedt ("TABANGLES", "Tab. Angles", 3, 2, 2), - def_bonded ("PDIHS", "Proper Dih.", 4, 3, 3), - def_bonded ("RBDIHS", "Ryckaert-Bell.", 4, 6, 6), - def_bonded ("RESTRDIHS", "Restricted Dih.", 4, 2, 2), - def_bonded ("CBTDIHS", "CBT Dih.", 4, 6, 6), - def_bonded ("FOURDIHS", "Fourier Dih.", 4, 4, 4), - def_bonded ("IDIHS", "Improper Dih.", 4, 2, 2), - def_bonded ("PIDIHS", "Improper Dih.", 4, 3, 3), - def_bondedt ("TABDIHS", "Tab. Dih.", 4, 2, 2), - def_bonded ("CMAP", "CMAP Dih.", 5, -1, -1), - def_nofc ("GB12", "GB 1-2 Pol. (unused)" ), - def_nofc ("GB13", "GB 1-3 Pol. (unused)" ), - def_nofc ("GB14", "GB 1-4 Pol. (unused)" ), - def_nofc ("GBPOL", "GB Polarization (unused)" ), - def_nofc ("NPSOLVATION", "Nonpolar Sol. (unused)" ), - def_bondedz ("LJ14", "LJ-14", 2, 2, 2), - def_nofc ("COUL14", "Coulomb-14" ), - def_bondedz ("LJC14_Q", "LJC-14 q", 2, 5, 0), - def_bondedz ("LJC_NB", "LJC Pairs NB", 2, 4, 0), - def_nb ("LJ_SR", "LJ (SR)", 2, 2 ), - def_nb ("BHAM", "Buck.ham (SR)", 2, 3 ), - def_nofc ("LJ_LR", "LJ (unused)" ), - def_nofc ("BHAM_LR", "B.ham (unused)" ), - def_nofc ("DISPCORR", "Disper. corr." ), - def_nofc ("COUL_SR", "Coulomb (SR)" ), - def_nofc ("COUL_LR", "Coul (unused)" ), - def_nofc ("RF_EXCL", "RF excl." ), - def_nofc ("COUL_RECIP", "Coul. recip." ), - def_nofc ("LJ_RECIP", "LJ recip." ), - def_nofc ("DPD", "DPD" ), - def_bondnb ("POLARIZATION", "Polarization", 2, 1, 0), - def_bonded ("WATERPOL", "Water Pol.", 5, 6, 0), - def_bonded ("THOLE", "Thole Pol.", 4, 3, 0), - def_bondnb ("ANHARM_POL", "Anharm. Pol.", 2, 3, 0), - def_bonded ("POSRES", "Position Rest.", 1, 3, 3), - def_bonded ("FBPOSRES", "Flat-bottom posres", 1, 3, 0), - def_bonded ("DISRES", "Dis. Rest.", 2, 6, 0), - def_nofc ("DISRESVIOL", "D.R.Viol. (nm)" ), - def_bonded ("ORIRES", "Orient. Rest.", 2, 6, 0), - def_nofc ("ORDEV", "Ori. R. RMSD" ), - def_bonded ("ANGRES", "Angle Rest.", 4, 3, 3), - def_bonded ("ANGRESZ", "Angle Rest. Z", 2, 3, 3), - def_bonded ("DIHRES", "Dih. Rest.", 4, 3, 3), - def_nofc ("DIHRESVIOL", "Dih. Rest. Viol." ), /* obsolete */ - def_shkcb ("CONSTR", "Constraint", 2, 1, 1 ), - def_shk ("CONSTRNC", "Constr. No Conn.", 2, 1, 1 ), - def_shkcb ("SETTLE", "Settle", 3, 2, 0 ), - def_vsite ("VSITE2", "Virtual site 2", 3, 1 ), - def_vsite ("VSITE2FD", "Virtual site 2fd", 3, 1 ), - def_vsite ("VSITE3", "Virtual site 3", 4, 2 ), - def_vsite ("VSITE3FD", "Virtual site 3fd", 4, 2 ), - def_vsite ("VSITE3FAD", "Virtual site 3fad", 4, 2 ), - def_vsite ("VSITE3OUT", "Virtual site 3out", 4, 3 ), - def_vsite ("VSITE4FD", "Virtual site 4fd", 5, 3 ), - def_vsite ("VSITE4FDN", "Virtual site 4fdn", 5, 3 ), - def_vsite ("VSITEN", "Virtual site N", 2, 2 ), - def_nofc ("COM_PULL", "COM Pull En." ), - def_nofc ("DENSITYFIT", "Density fitting"), - def_nofc ("EQM", "Quantum En." ), - def_nofc ("EPOT", "Potential" ), - def_nofc ("EKIN", "Kinetic En." ), - def_nofc ("ETOT", "Total Energy" ), - def_nofc ("ECONS", "Conserved En." ), - def_nofc ("TEMP", "Temperature" ), - def_nofc ("VTEMP", "Vir. Temp. (not used)" ), +const t_interaction_function interaction_function[F_NRE] = { + def_bond("BONDS", "Bond", 2, 2, 2), def_bond("G96BONDS", "G96Bond", 2, 2, 2), + def_bond("MORSE", "Morse", 2, 3, 3), def_bond("CUBICBONDS", "Cubic Bonds", 2, 3, 0), + def_bondnb("CONNBONDS", "Connect Bonds", 2, 0, 0), + def_bonded("HARMONIC", "Harmonic Pot.", 2, 2, 2), def_bondnb("FENEBONDS", "FENE Bonds", 2, 2, 0), + def_bondt("TABBONDS", "Tab. Bonds", 2, 2, 2), def_bondedtz("TABBONDSNC", "Tab. Bonds NC", 2, 2, 2), + def_bonded("RESTRAINTPOT", "Restraint Pot.", 2, 4, 4), def_angle("ANGLES", "Angle", 3, 2, 2), + def_angle("G96ANGLES", "G96Angle", 3, 2, 2), def_angle("RESTRANGLES", "Restricted Angles", 3, 2, 2), + def_angle("LINEAR_ANGLES", "Lin. Angle", 3, 2, 2), + def_bonded("CROSS_BOND_BOND", "Bond-Cross", 3, 3, 0), + def_bonded("CROSS_BOND_ANGLE", "BA-Cross", 3, 4, 0), def_angle("UREY_BRADLEY", "U-B", 3, 4, 4), + def_angle("QANGLES", "Quartic Angles", 3, 6, 0), def_bondedt("TABANGLES", "Tab. Angles", 3, 2, 2), + def_bonded("PDIHS", "Proper Dih.", 4, 3, 3), def_bonded("RBDIHS", "Ryckaert-Bell.", 4, 6, 6), + def_bonded("RESTRDIHS", "Restricted Dih.", 4, 2, 2), def_bonded("CBTDIHS", "CBT Dih.", 4, 6, 6), + def_bonded("FOURDIHS", "Fourier Dih.", 4, 4, 4), def_bonded("IDIHS", "Improper Dih.", 4, 2, 2), + def_bonded("PIDIHS", "Improper Dih.", 4, 3, 3), def_bondedt("TABDIHS", "Tab. Dih.", 4, 2, 2), + def_bonded("CMAP", "CMAP Dih.", 5, -1, -1), def_nofc("GB12", "GB 1-2 Pol. (unused)"), + def_nofc("GB13", "GB 1-3 Pol. (unused)"), def_nofc("GB14", "GB 1-4 Pol. (unused)"), + def_nofc("GBPOL", "GB Polarization (unused)"), def_nofc("NPSOLVATION", "Nonpolar Sol. (unused)"), + def_bondedz("LJ14", "LJ-14", 2, 2, 2), def_nofc("COUL14", "Coulomb-14"), + def_bondedz("LJC14_Q", "LJC-14 q", 2, 5, 0), def_bondedz("LJC_NB", "LJC Pairs NB", 2, 4, 0), + def_nb("LJ_SR", "LJ (SR)", 2, 2), def_nb("BHAM", "Buck.ham (SR)", 2, 3), + def_nofc("LJ_LR", "LJ (unused)"), def_nofc("BHAM_LR", "B.ham (unused)"), + def_nofc("DISPCORR", "Disper. corr."), def_nofc("COUL_SR", "Coulomb (SR)"), + def_nofc("COUL_LR", "Coul (unused)"), def_nofc("RF_EXCL", "RF excl."), + def_nofc("COUL_RECIP", "Coul. recip."), def_nofc("LJ_RECIP", "LJ recip."), + def_nofc("DPD", "DPD"), def_bondnb("POLARIZATION", "Polarization", 2, 1, 0), + def_bonded("WATERPOL", "Water Pol.", 5, 6, 0), def_bonded("THOLE", "Thole Pol.", 4, 3, 0), + def_bondnb("ANHARM_POL", "Anharm. Pol.", 2, 3, 0), def_bonded("POSRES", "Position Rest.", 1, 3, 3), + def_bonded("FBPOSRES", "Flat-bottom posres", 1, 3, 0), def_bonded("DISRES", "Dis. Rest.", 2, 6, 0), + def_nofc("DISRESVIOL", "D.R.Viol. (nm)"), def_bonded("ORIRES", "Orient. Rest.", 2, 6, 0), + def_nofc("ORDEV", "Ori. R. RMSD"), def_bonded("ANGRES", "Angle Rest.", 4, 3, 3), + def_bonded("ANGRESZ", "Angle Rest. Z", 2, 3, 3), def_bonded("DIHRES", "Dih. Rest.", 4, 3, 3), + def_nofc("DIHRESVIOL", "Dih. Rest. Viol."), /* obsolete */ + def_shkcb("CONSTR", "Constraint", 2, 1, 1), def_shk("CONSTRNC", "Constr. No Conn.", 2, 1, 1), + def_shkcb("SETTLE", "Settle", 3, 2, 0), def_vsite("VSITE2", "Virtual site 2", 3, 1), + def_vsite("VSITE2FD", "Virtual site 2fd", 3, 1), def_vsite("VSITE3", "Virtual site 3", 4, 2), + def_vsite("VSITE3FD", "Virtual site 3fd", 4, 2), def_vsite("VSITE3FAD", "Virtual site 3fad", 4, 2), + def_vsite("VSITE3OUT", "Virtual site 3out", 4, 3), def_vsite("VSITE4FD", "Virtual site 4fd", 5, 3), + def_vsite("VSITE4FDN", "Virtual site 4fdn", 5, 3), def_vsite("VSITEN", "Virtual site N", 2, 2), + def_nofc("COM_PULL", "COM Pull En."), def_nofc("DENSITYFIT", "Density fitting"), + def_nofc("EQM", "Quantum En."), def_nofc("EPOT", "Potential"), def_nofc("EKIN", "Kinetic En."), + def_nofc("ETOT", "Total Energy"), def_nofc("ECONS", "Conserved En."), + def_nofc("TEMP", "Temperature"), def_nofc("VTEMP", "Vir. Temp. (not used)"), /* Note that pressure names can not be more than 8 char's, * because " (bar)" is appended to them. */ - def_nofc ("PDISPCORR", "Pres. DC" ), - def_nofc ("PRES", "Pressure" ), - def_nofc ("DH/DL_CON", "dH/dl constr." ), /* obsolete */ - def_nofc ("DV/DL", "dVremain/dl" ), - def_nofc ("DK/DL", "dEkin/dl" ), - def_nofc ("DVC/DL", "dVcoul/dl" ), - def_nofc ("DVV/DL", "dVvdw/dl" ), - def_nofc ("DVB/DL", "dVbonded/dl" ), - def_nofc ("DVR/DL", "dVrestraint/dl" ), - def_nofc ("DVT/DL", "dVtemperature/dl" ) + def_nofc("PDISPCORR", "Pres. DC"), def_nofc("PRES", "Pressure"), + def_nofc("DH/DL_CON", "dH/dl constr."), /* obsolete */ + def_nofc("DV/DL", "dVremain/dl"), def_nofc("DK/DL", "dEkin/dl"), def_nofc("DVC/DL", "dVcoul/dl"), + def_nofc("DVV/DL", "dVvdw/dl"), def_nofc("DVB/DL", "dVbonded/dl"), + def_nofc("DVR/DL", "dVrestraint/dl"), def_nofc("DVT/DL", "dVtemperature/dl") }; diff --git a/src/gromacs/topology/ifunc.h b/src/gromacs/topology/ifunc.h index 4d4e5d3479..49ead04b1a 100644 --- a/src/gromacs/topology/ifunc.h +++ b/src/gromacs/topology/ifunc.h @@ -90,28 +90,30 @@ constexpr unsigned int IF_LIMZERO = 1 << 7; struct t_interaction_function // NOLINT (clang-analyzer-optin.performance.Padding) { - const char *name; /* the name of this function */ - const char *longname; /* The name for printing etc. */ + const char* name; /* the name of this function */ + const char* longname; /* The name for printing etc. */ int nratoms; /* nr of atoms needed for this function */ int nrfpA, nrfpB; /* number of parameters for this function. */ /* this corresponds to the number of params in */ /* iparams struct! (see idef.h) */ /* A and B are for normal and free energy components respectively. */ - unsigned int flags; /* Flags (see above) */ + unsigned int flags; /* Flags (see above) */ }; #define NRFPA(ftype) (interaction_function[(ftype)].nrfpA) #define NRFPB(ftype) (interaction_function[(ftype)].nrfpB) -#define NRFP(ftype) (NRFPA(ftype)+NRFPB(ftype)) +#define NRFP(ftype) (NRFPA(ftype) + NRFPB(ftype)) #define NRAL(ftype) (interaction_function[(ftype)].nratoms) -#define IS_CHEMBOND(ftype) (interaction_function[(ftype)].nratoms == 2 && (interaction_function[(ftype)].flags & IF_CHEMBOND)) +#define IS_CHEMBOND(ftype) \ + (interaction_function[(ftype)].nratoms == 2 && (interaction_function[(ftype)].flags & IF_CHEMBOND)) /* IS_CHEMBOND tells if function type ftype represents a chemical bond */ /* IS_ANGLE tells if a function type ftype represents an angle * Per Larsson, 2007-11-06 */ -#define IS_ANGLE(ftype) (interaction_function[(ftype)].nratoms == 3 && (interaction_function[(ftype)].flags & IF_ATYPE)) +#define IS_ANGLE(ftype) \ + (interaction_function[(ftype)].nratoms == 3 && (interaction_function[(ftype)].flags & IF_ATYPE)) #define IS_VSITE(ftype) (interaction_function[(ftype)].flags & IF_VSITE) #define IS_TABULATED(ftype) (interaction_function[(ftype)].flags & IF_TABULATED) @@ -213,16 +215,14 @@ enum F_DVDL_BONDED, F_DVDL_RESTRAINT, F_DVDL_TEMPERATURE, /* not calculated for now, but should just be the energy (NVT) or enthalpy (NPT), or 0 (NVE) */ - F_NRE /* This number is for the total number of energies */ + F_NRE /* This number is for the total number of energies */ }; static inline bool IS_RESTRAINT_TYPE(int ifunc) { - return - ifunc == F_POSRES || ifunc == F_FBPOSRES || - ifunc == F_DISRES || ifunc == F_RESTRBONDS || ifunc == F_DISRESVIOL || - ifunc == F_ORIRES || ifunc == F_ORIRESDEV || - ifunc == F_ANGRES || ifunc == F_ANGRESZ || ifunc == F_DIHRES; + return ifunc == F_POSRES || ifunc == F_FBPOSRES || ifunc == F_DISRES || ifunc == F_RESTRBONDS + || ifunc == F_DISRESVIOL || ifunc == F_ORIRES || ifunc == F_ORIRESDEV + || ifunc == F_ANGRES || ifunc == F_ANGRESZ || ifunc == F_DIHRES; } /* Maximum allowed number of atoms, parameters and terms in interaction_function. diff --git a/src/gromacs/topology/index.cpp b/src/gromacs/topology/index.cpp index a0382f3da5..27b03c4fc6 100644 --- a/src/gromacs/topology/index.cpp +++ b/src/gromacs/topology/index.cpp @@ -65,8 +65,7 @@ static gmx_bool gmx_ask_yesno(gmx_bool bASK) do { c = toupper(fgetc(stdin)); - } - while ((c != 'Y') && (c != 'N')); + } while ((c != 'Y') && (c != 'N')); return (c == 'Y'); } @@ -76,9 +75,9 @@ static gmx_bool gmx_ask_yesno(gmx_bool bASK) } } -void write_index(const char *outf, t_blocka *b, char **gnames, gmx_bool bDuplicate, int natoms) +void write_index(const char* outf, t_blocka* b, char** gnames, gmx_bool bDuplicate, int natoms) { - FILE *out; + FILE* out; int i, j, k; out = gmx_ffopen(outf, "w"); @@ -86,10 +85,10 @@ void write_index(const char *outf, t_blocka *b, char **gnames, gmx_bool bDuplica for (i = 0; (i < b->nr); i++) { fprintf(out, "[ %s ]", gnames[i]); - for (k = 0, j = b->index[i]; j < b->index[i+1]; j++, k++) + for (k = 0, j = b->index[i]; j < b->index[i + 1]; j++, k++) { const char sep = (k % 15 == 0 ? '\n' : ' '); - fprintf(out, "%c%4d", sep, b->a[j]+1); + fprintf(out, "%c%4d", sep, b->a[j] + 1); } fprintf(out, "\n"); } @@ -101,10 +100,10 @@ void write_index(const char *outf, t_blocka *b, char **gnames, gmx_bool bDuplica for (i = 0; (i < b->nr); i++) { fprintf(out, "[ %s_copy ]", gnames[i]); - for (k = 0, j = b->index[i]; j < b->index[i+1]; j++, k++) + for (k = 0, j = b->index[i]; j < b->index[i + 1]; j++, k++) { const char sep = (k % 15 == 0 ? '\n' : ' '); - fprintf(out, "%c%4d", sep, b->a[j]+1 + natoms); + fprintf(out, "%c%4d", sep, b->a[j] + 1 + natoms); } fprintf(out, "\n"); } @@ -113,13 +112,13 @@ void write_index(const char *outf, t_blocka *b, char **gnames, gmx_bool bDuplica gmx_ffclose(out); } -void add_grp(t_blocka *b, char ***gnames, gmx::ArrayRef a, const std::string &name) +void add_grp(t_blocka* b, char*** gnames, gmx::ArrayRef a, const std::string& name) { - srenew(b->index, b->nr+2); - srenew(*gnames, b->nr+1); + srenew(b->index, b->nr + 2); + srenew(*gnames, b->nr + 1); (*gnames)[b->nr] = gmx_strdup(name.c_str()); - srenew(b->a, b->nra+a.size()); + srenew(b->a, b->nra + a.size()); for (gmx::index i = 0; (i < a.ssize()); i++) { b->a[b->nra++] = a[i]; @@ -139,24 +138,24 @@ void add_grp(t_blocka *b, char ***gnames, gmx::ArrayRef a, const std: * \param[in] index The index to check. * \returns True if groups are the same. */ -static bool grp_cmp(t_blocka *b, gmx::ArrayRef a, int index) +static bool grp_cmp(t_blocka* b, gmx::ArrayRef a, int index) { if (index < 0) { - index = b->nr-1+index; + index = b->nr - 1 + index; } if (index >= b->nr) { gmx_fatal(FARGS, "no such index group %d in t_blocka (nr=%d)", index, b->nr); } /* compare sizes */ - if (a.ssize() != b->index[index+1] - b->index[index]) + if (a.ssize() != b->index[index + 1] - b->index[index]) { return FALSE; } for (gmx::index i = 0; i < a.ssize(); i++) { - if (a[i] != b->a[b->index[index]+i]) + if (a[i] != b->a[b->index[index] + i]) { return false; } @@ -164,19 +163,14 @@ static bool grp_cmp(t_blocka *b, gmx::ArrayRef a, int index) return true; } //! Print out how many residues of a certain type are present. -static void p_status(gmx::ArrayRef restype, - gmx::ArrayRef typenames) +static void p_status(gmx::ArrayRef restype, gmx::ArrayRef typenames) { std::vector counter(typenames.size(), 0); - std::transform(typenames.begin(), typenames.end(), counter.begin(), - [&restype](const std::string &typenm) { - return std::count_if(restype.begin(), restype.end(), - [&typenm](const std::string &res) { - return gmx_strcasecmp(res.c_str(), typenm.c_str()) == 0; - } - ); - } - ); + std::transform(typenames.begin(), typenames.end(), counter.begin(), [&restype](const std::string& typenm) { + return std::count_if(restype.begin(), restype.end(), [&typenm](const std::string& res) { + return gmx_strcasecmp(res.c_str(), typenm.c_str()) == 0; + }); + }); for (int i = 0; (i < typenames.ssize()); i++) { @@ -197,9 +191,9 @@ static void p_status(gmx::ArrayRef restype, * \param[in] bMatch whether to return matching atoms or those that don't. * \returns Vector of atoms that match. */ -static std::vector mk_aid(const t_atoms *atoms, +static std::vector mk_aid(const t_atoms* atoms, gmx::ArrayRef restype, - const std::string &typestring, + const std::string& typestring, bool bMatch) { std::vector a; @@ -219,23 +213,30 @@ static std::vector mk_aid(const t_atoms *atoms, return a; } -typedef struct { - char *rname; +typedef struct +{ + char* rname; gmx_bool bNeg; - char *gname; + char* gname; } restp_t; -static void analyse_other(gmx::ArrayRef restype, const t_atoms *atoms, - t_blocka *gb, char ***gn, gmx_bool bASK, gmx_bool bVerb) +static void analyse_other(gmx::ArrayRef restype, + const t_atoms* atoms, + t_blocka* gb, + char*** gn, + gmx_bool bASK, + gmx_bool bVerb) { - restp_t *restp = nullptr; - char **attp = nullptr; - char *rname, *aname; + restp_t* restp = nullptr; + char** attp = nullptr; + char * rname, *aname; int i, resind, natp, nrestp = 0; for (i = 0; (i < atoms->nres); i++) { - if (gmx_strcasecmp(restype[i].c_str(), "Protein") && gmx_strcasecmp(restype[i].c_str(), "DNA") && gmx_strcasecmp(restype[i].c_str(), "RNA") && gmx_strcasecmp(restype[i].c_str(), "Water")) + if (gmx_strcasecmp(restype[i].c_str(), "Protein") + && gmx_strcasecmp(restype[i].c_str(), "DNA") && gmx_strcasecmp(restype[i].c_str(), "RNA") + && gmx_strcasecmp(restype[i].c_str(), "Water")) { break; } @@ -245,14 +246,17 @@ static void analyse_other(gmx::ArrayRef restype, const t_atoms *ato /* we have others */ if (bVerb) { - printf("Analysing residues not classified as Protein/DNA/RNA/Water and splitting into groups...\n"); + printf("Analysing residues not classified as Protein/DNA/RNA/Water and splitting into " + "groups...\n"); } for (int k = 0; (k < atoms->nr); k++) { resind = atoms->atom[k].resind; rname = *atoms->resinfo[resind].name; - if (gmx_strcasecmp(restype[resind].c_str(), "Protein") && gmx_strcasecmp(restype[resind].c_str(), "DNA") && - gmx_strcasecmp(restype[resind].c_str(), "RNA") && gmx_strcasecmp(restype[resind].c_str(), "Water")) + if (gmx_strcasecmp(restype[resind].c_str(), "Protein") + && gmx_strcasecmp(restype[resind].c_str(), "DNA") + && gmx_strcasecmp(restype[resind].c_str(), "RNA") + && gmx_strcasecmp(restype[resind].c_str(), "Water")) { int l; for (l = 0; (l < nrestp); l++) @@ -265,7 +269,7 @@ static void analyse_other(gmx::ArrayRef restype, const t_atoms *ato } if (l == nrestp) { - srenew(restp, nrestp+1); + srenew(restp, nrestp + 1); restp[nrestp].rname = gmx_strdup(rname); restp[nrestp].bNeg = FALSE; restp[nrestp].gname = gmx_strdup(rname); @@ -279,8 +283,8 @@ static void analyse_other(gmx::ArrayRef restype, const t_atoms *ato for (int j = 0; (j < atoms->nr); j++) { rname = *atoms->resinfo[atoms->atom[j].resind].name; - if ((strcmp(restp[i].rname, rname) == 0 && !restp[i].bNeg) || - (strcmp(restp[i].rname, rname) != 0 && restp[i].bNeg)) + if ((strcmp(restp[i].rname, rname) == 0 && !restp[i].bNeg) + || (strcmp(restp[i].rname, rname) != 0 && restp[i].bNeg)) { aid.push_back(j); } @@ -307,7 +311,7 @@ static void analyse_other(gmx::ArrayRef restype, const t_atoms *ato if (l == natp) { srenew(attp, ++natp); - attp[natp-1] = aname; + attp[natp - 1] = aname; } } if (natp > 1) @@ -344,11 +348,11 @@ static void analyse_other(gmx::ArrayRef restype, const t_atoms *ato typedef struct gmx_help_make_index_group // NOLINT(clang-analyzer-optin.performance.Padding) { /** The set of atom names that will be used to form this index group */ - const char **defining_atomnames; + const char** defining_atomnames; /** Size of the defining_atomnames array */ - int num_defining_atomnames; + int num_defining_atomnames; /** Name of this index group */ - const char *group_name; + const char* group_name; /** Whether the above atom names name the atoms in the group, or those not in the group */ gmx_bool bTakeComplement; @@ -364,42 +368,43 @@ typedef struct gmx_help_make_index_group // NOLINT(clang-analyzer-optin.performa int compareto; } t_gmx_help_make_index_group; -static void analyse_prot(gmx::ArrayRef restype, const t_atoms *atoms, - t_blocka *gb, char ***gn, gmx_bool bASK, gmx_bool bVerb) +static void analyse_prot(gmx::ArrayRef restype, + const t_atoms* atoms, + t_blocka* gb, + char*** gn, + gmx_bool bASK, + gmx_bool bVerb) { /* lists of atomnames to be used in constructing index groups: */ - static const char *pnoh[] = { "H", "HN" }; - static const char *pnodum[] = { - "MN1", "MN2", "MCB1", "MCB2", "MCG1", "MCG2", - "MCD1", "MCD2", "MCE1", "MCE2", "MNZ1", "MNZ2" - }; - static const char *calpha[] = { "CA" }; - static const char *bb[] = { "N", "CA", "C" }; - static const char *mc[] = { "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" }; - static const char *mcb[] = { "N", "CA", "CB", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" }; - static const char *mch[] = { - "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT", - "H1", "H2", "H3", "H", "HN" + static const char* pnoh[] = { "H", "HN" }; + static const char* pnodum[] = { "MN1", "MN2", "MCB1", "MCB2", "MCG1", "MCG2", + "MCD1", "MCD2", "MCE1", "MCE2", "MNZ1", "MNZ2" }; + static const char* calpha[] = { "CA" }; + static const char* bb[] = { "N", "CA", "C" }; + static const char* mc[] = { "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" }; + static const char* mcb[] = { "N", "CA", "CB", "C", "O", "O1", "O2", "OC1", "OC2", "OT", "OXT" }; + static const char* mch[] = { "N", "CA", "C", "O", "O1", "O2", "OC1", "OC2", + "OT", "OXT", "H1", "H2", "H3", "H", "HN" }; + + static const t_gmx_help_make_index_group constructing_data[] = { + { nullptr, 0, "Protein", TRUE, -1, -1 }, + { pnoh, asize(pnoh), "Protein-H", TRUE, 0, -1 }, + { calpha, asize(calpha), "C-alpha", FALSE, -1, -1 }, + { bb, asize(bb), "Backbone", FALSE, -1, -1 }, + { mc, asize(mc), "MainChain", FALSE, -1, -1 }, + { mcb, asize(mcb), "MainChain+Cb", FALSE, -1, -1 }, + { mch, asize(mch), "MainChain+H", FALSE, -1, -1 }, + { mch, asize(mch), "SideChain", TRUE, -1, -1 }, + { mch, asize(mch), "SideChain-H", TRUE, 11, -1 }, + { pnodum, asize(pnodum), "Prot-Masses", TRUE, -1, 0 }, }; + const int num_index_groups = asize(constructing_data); - static const t_gmx_help_make_index_group constructing_data[] = - {{ nullptr, 0, "Protein", TRUE, -1, -1}, - { pnoh, asize(pnoh), "Protein-H", TRUE, 0, -1}, - { calpha, asize(calpha), "C-alpha", FALSE, -1, -1}, - { bb, asize(bb), "Backbone", FALSE, -1, -1}, - { mc, asize(mc), "MainChain", FALSE, -1, -1}, - { mcb, asize(mcb), "MainChain+Cb", FALSE, -1, -1}, - { mch, asize(mch), "MainChain+H", FALSE, -1, -1}, - { mch, asize(mch), "SideChain", TRUE, -1, -1}, - { mch, asize(mch), "SideChain-H", TRUE, 11, -1}, - { pnodum, asize(pnodum), "Prot-Masses", TRUE, -1, 0}, }; - const int num_index_groups = asize(constructing_data); - - int n, j; - int npres; - gmx_bool match; - char ndx_name[STRLEN], *atnm; - int i; + int n, j; + int npres; + gmx_bool match; + char ndx_name[STRLEN], *atnm; + int i; if (bVerb) { @@ -432,7 +437,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms { atnm++; } - if ( (constructing_data[i].wholename == -1) || (j < constructing_data[i].wholename) ) + if ((constructing_data[i].wholename == -1) || (j < constructing_data[i].wholename)) { if (0 == gmx_strcasecmp(constructing_data[i].defining_atomnames[j], atnm)) { @@ -441,7 +446,9 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms } else { - if (0 == gmx_strncasecmp(constructing_data[i].defining_atomnames[j], atnm, strlen(constructing_data[i].defining_atomnames[j]))) + if (0 + == gmx_strncasecmp(constructing_data[i].defining_atomnames[j], atnm, + strlen(constructing_data[i].defining_atomnames[j]))) { match = TRUE; } @@ -455,7 +462,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms } /* if we want to add this group always or it differs from previous group, add it: */ - if (-1 == constructing_data[i].compareto || !grp_cmp(gb, aid, constructing_data[i].compareto-i) ) + if (-1 == constructing_data[i].compareto || !grp_cmp(gb, aid, constructing_data[i].compareto - i)) { add_grp(gb, gn, aid, constructing_data[i].group_name); } @@ -471,7 +478,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms { int resind; aid.clear(); - for (n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr)); ) + for (n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr));) { resind = atoms->atom[n].resind; for (; ((atoms->atom[n].resind == resind) && (n < atoms->nr)); n++) @@ -479,7 +486,9 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms match = FALSE; for (j = 0; (j < constructing_data[i].num_defining_atomnames); j++) { - if (0 == gmx_strcasecmp(constructing_data[i].defining_atomnames[j], *atoms->atomname[n])) + if (0 + == gmx_strcasecmp(constructing_data[i].defining_atomnames[j], + *atoms->atomname[n])) { match = TRUE; } @@ -492,10 +501,10 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms /* copy the residuename to the tail of the groupname */ if (!aid.empty()) { - t_resinfo *ri; + t_resinfo* ri; ri = &atoms->resinfo[resind]; - sprintf(ndx_name, "%s_%s%d%c", - constructing_data[i].group_name, *ri->name, ri->nr, ri->ic == ' ' ? '\0' : ri->ic); + sprintf(ndx_name, "%s_%s%d%c", constructing_data[i].group_name, *ri->name, + ri->nr, ri->ic == ' ' ? '\0' : ri->ic); add_grp(gb, gn, aid, ndx_name); aid.clear(); } @@ -507,7 +516,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms { /* Make swap sidechain C=O index */ aid.clear(); - for (int n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr)); ) + for (int n = 0; ((atoms->atom[n].resind < npres) && (n < atoms->nr));) { int resind = atoms->atom[n].resind; int hold = -1; @@ -533,7 +542,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms { gmx_incons("Atom naming problem"); } - aid[hold+1] = n; + aid[hold + 1] = n; } else if (strcmp("O1", *atoms->atomname[n]) == 0) { @@ -541,7 +550,7 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms { gmx_incons("Atom naming problem"); } - aid[hold+1] = n; + aid[hold + 1] = n; } else { @@ -559,12 +568,12 @@ static void analyse_prot(gmx::ArrayRef restype, const t_atoms } -void analyse(const t_atoms *atoms, t_blocka *gb, char ***gn, gmx_bool bASK, gmx_bool bVerb) +void analyse(const t_atoms* atoms, t_blocka* gb, char*** gn, gmx_bool bASK, gmx_bool bVerb) { - char *resnm; - int i; - int iwater, iion; - int nwater, nion; + char* resnm; + int i; + int iwater, iion; + int nwater, nion; if (bVerb) { @@ -579,7 +588,7 @@ void analyse(const t_atoms *atoms, t_blocka *gb, char ***gn, gmx_bool bASK, gmx_ add_grp(gb, gn, aid, "System"); /* For every residue, get a pointer to the residue type name */ - ResidueType rt; + ResidueType rt; std::vector restype; std::vector previousTypename; @@ -668,31 +677,31 @@ void analyse(const t_atoms *atoms, t_blocka *gb, char ***gn, gmx_bool bASK, gmx_ if (!gmx_strcasecmp((*gn)[i], "Water")) { iwater = i; - nwater = gb->index[i+1]-gb->index[i]; + nwater = gb->index[i + 1] - gb->index[i]; } else if (!gmx_strcasecmp((*gn)[i], "Ion")) { iion = i; - nion = gb->index[i+1]-gb->index[i]; + nion = gb->index[i + 1] - gb->index[i]; } } if (nwater > 0 && nion > 0) { - srenew(gb->index, gb->nr+2); - srenew(*gn, gb->nr+1); + srenew(gb->index, gb->nr + 2); + srenew(*gn, gb->nr + 1); (*gn)[gb->nr] = gmx_strdup("Water_and_ions"); - srenew(gb->a, gb->nra+nwater+nion); + srenew(gb->a, gb->nra + nwater + nion); if (nwater > 0) { - for (i = gb->index[iwater]; i < gb->index[iwater+1]; i++) + for (i = gb->index[iwater]; i < gb->index[iwater + 1]; i++) { gb->a[gb->nra++] = gb->a[i]; } } if (nion > 0) { - for (i = gb->index[iion]; i < gb->index[iion+1]; i++) + for (i = gb->index[iion]; i < gb->index[iion + 1]; i++) { gb->a[gb->nra++] = gb->a[i]; } @@ -703,7 +712,7 @@ void analyse(const t_atoms *atoms, t_blocka *gb, char ***gn, gmx_bool bASK, gmx_ } -void check_index(const char *gname, int n, int index[], const char *traj, int natoms) +void check_index(const char* gname, int n, int index[], const char* traj, int natoms) { int i; @@ -711,25 +720,26 @@ void check_index(const char *gname, int n, int index[], const char *traj, int na { if (index[i] >= natoms) { - gmx_fatal(FARGS, "%s atom number (index[%d]=%d) is larger than the number of atoms in %s (%d)", - gname ? gname : "Index", i+1, index[i]+1, - traj ? traj : "the trajectory", natoms); + gmx_fatal(FARGS, + "%s atom number (index[%d]=%d) is larger than the number of atoms in %s (%d)", + gname ? gname : "Index", i + 1, index[i] + 1, traj ? traj : "the trajectory", + natoms); } else if (index[i] < 0) { gmx_fatal(FARGS, "%s atom number (index[%d]=%d) is less than zero", - gname ? gname : "Index", i+1, index[i]+1); + gname ? gname : "Index", i + 1, index[i] + 1); } } } -t_blocka *init_index(const char *gfile, char ***grpname) +t_blocka* init_index(const char* gfile, char*** grpname) { - FILE *in; - t_blocka *b; - int maxentries; - int i, j; - char line[STRLEN], *pt, str[STRLEN]; + FILE* in; + t_blocka* b; + int maxentries; + int i, j; + char line[STRLEN], *pt, str[STRLEN]; in = gmx_ffopen(gfile, "r"); snew(b, 1); @@ -744,14 +754,14 @@ t_blocka *init_index(const char *gfile, char ***grpname) if (get_header(line, str)) { b->nr++; - srenew(b->index, b->nr+1); + srenew(b->index, b->nr + 1); srenew(*grpname, b->nr); if (b->nr == 1) { b->index[0] = 0; } - b->index[b->nr] = b->index[b->nr-1]; - (*grpname)[b->nr-1] = gmx_strdup(str); + b->index[b->nr] = b->index[b->nr - 1]; + (*grpname)[b->nr - 1] = gmx_strdup(str); } else { @@ -769,10 +779,10 @@ t_blocka *init_index(const char *gfile, char ***grpname) srenew(b->a, maxentries); } assert(b->a != nullptr); // for clang analyzer - b->a[i] = strtol(str, nullptr, 10)-1; + b->a[i] = strtol(str, nullptr, 10) - 1; b->index[b->nr]++; (b->nra)++; - pt = strstr(pt, str)+strlen(str); + pt = strstr(pt, str) + strlen(str); } } } @@ -781,12 +791,11 @@ t_blocka *init_index(const char *gfile, char ***grpname) for (i = 0; (i < b->nr); i++) { assert(b->a != nullptr); // for clang analyzer - for (j = b->index[i]; (j < b->index[i+1]); j++) + for (j = b->index[i]; (j < b->index[i + 1]); j++) { if (b->a[j] < 0) { - fprintf(stderr, "\nWARNING: negative index %d in group %s\n\n", - b->a[j], (*grpname)[i]); + fprintf(stderr, "\nWARNING: negative index %d in group %s\n\n", b->a[j], (*grpname)[i]); } } } @@ -794,7 +803,7 @@ t_blocka *init_index(const char *gfile, char ***grpname) return b; } -static void minstring(char *str) +static void minstring(char* str) { int i; @@ -807,7 +816,7 @@ static void minstring(char *str) } } -int find_group(const char *s, int ngrps, char **grpname) +int find_group(const char* s, int ngrps, char** grpname) { int aa, i, n; char string[STRLEN]; @@ -848,13 +857,13 @@ int find_group(const char *s, int ngrps, char **grpname) if (aa == -1) { char key[STRLEN]; - strncpy(key, s, sizeof(key)-1); - key[STRLEN-1] = '\0'; + strncpy(key, s, sizeof(key) - 1); + key[STRLEN - 1] = '\0'; upstring(key); minstring(key); for (i = 0; i < ngrps; i++) { - strncpy(string, grpname[i], STRLEN-1); + strncpy(string, grpname[i], STRLEN - 1); upstring(string); minstring(string); if (strstr(string, key) != nullptr) @@ -875,12 +884,12 @@ int find_group(const char *s, int ngrps, char **grpname) return aa; } -static int qgroup(int *a, int ngrps, char **grpname) +static int qgroup(int* a, int ngrps, char** grpname) { char s[STRLEN]; int aa; gmx_bool bInRange; - char *end; + char* end; do { @@ -892,8 +901,7 @@ static int qgroup(int *a, int ngrps, char **grpname) gmx_fatal(FARGS, "Cannot read from input"); } trim(s); /* remove spaces */ - } - while (strlen(s) == 0); + } while (strlen(s) == 0); aa = strtol(s, &end, 10); if (aa == 0 && end[0] != '\0') /* string entered */ { @@ -904,15 +912,14 @@ static int qgroup(int *a, int ngrps, char **grpname) { printf("Error: No such group '%s'\n", s); } - } - while (!bInRange); + } while (!bInRange); printf("Selected %d: '%s'\n", aa, grpname[aa]); *a = aa; return aa; } -static void rd_groups(t_blocka *grps, char **grpname, char *gnames[], - int ngrps, int isize[], int *index[], int grpnr[]) +static void +rd_groups(t_blocka* grps, char** grpname, char* gnames[], int ngrps, int isize[], int* index[], int grpnr[]) { int i, j, gnr1; @@ -923,7 +930,7 @@ static void rd_groups(t_blocka *grps, char **grpname, char *gnames[], for (i = 0; (i < grps->nr); i++) { fprintf(stderr, "Group %5d (%15s) has %5d elements\n", i, grpname[i], - grps->index[i+1]-grps->index[i]); + grps->index[i + 1] - grps->index[i]); } for (i = 0; (i < ngrps); i++) { @@ -934,10 +941,9 @@ static void rd_groups(t_blocka *grps, char **grpname, char *gnames[], gnr1 = qgroup(&grpnr[i], grps->nr, grpname); if ((gnr1 < 0) || (gnr1 >= grps->nr)) { - fprintf(stderr, "Select between %d and %d.\n", 0, grps->nr-1); + fprintf(stderr, "Select between %d and %d.\n", 0, grps->nr - 1); } - } - while ((gnr1 < 0) || (gnr1 >= grps->nr)); + } while ((gnr1 < 0) || (gnr1 >= grps->nr)); } else { @@ -945,21 +951,20 @@ static void rd_groups(t_blocka *grps, char **grpname, char *gnames[], gnr1 = 0; } gnames[i] = gmx_strdup(grpname[gnr1]); - isize[i] = grps->index[gnr1+1]-grps->index[gnr1]; + isize[i] = grps->index[gnr1 + 1] - grps->index[gnr1]; snew(index[i], isize[i]); for (j = 0; (j < isize[i]); j++) { - index[i][j] = grps->a[grps->index[gnr1]+j]; + index[i][j] = grps->a[grps->index[gnr1] + j]; } } } -void rd_index(const char *statfile, int ngrps, int isize[], - int *index[], char *grpnames[]) +void rd_index(const char* statfile, int ngrps, int isize[], int* index[], char* grpnames[]) { - char **gnames; - t_blocka *grps; - int *grpnr; + char** gnames; + t_blocka* grps; + int* grpnr; snew(grpnr, ngrps); if (!statfile) @@ -978,12 +983,11 @@ void rd_index(const char *statfile, int ngrps, int isize[], sfree(grps); } -void get_index(const t_atoms *atoms, const char *fnm, int ngrps, - int isize[], int *index[], char *grpnames[]) +void get_index(const t_atoms* atoms, const char* fnm, int ngrps, int isize[], int* index[], char* grpnames[]) { - char ***gnames; - t_blocka *grps = nullptr; - int *grpnr; + char*** gnames; + t_blocka* grps = nullptr; + int* grpnr; snew(grpnr, ngrps); snew(gnames, 1); @@ -1014,21 +1018,21 @@ void get_index(const t_atoms *atoms, const char *fnm, int ngrps, sfree(grps); } -t_cluster_ndx *cluster_index(FILE *fplog, const char *ndx) +t_cluster_ndx* cluster_index(FILE* fplog, const char* ndx) { - t_cluster_ndx *c; + t_cluster_ndx* c; int i; snew(c, 1); - c->clust = init_index(ndx, &c->grpname); - c->maxframe = -1; + c->clust = init_index(ndx, &c->grpname); + c->maxframe = -1; for (i = 0; (i < c->clust->nra); i++) { c->maxframe = std::max(c->maxframe, c->clust->a[i]); } fprintf(fplog ? fplog : stdout, - "There are %d clusters containing %d structures, highest framenr is %d\n", - c->clust->nr, c->clust->nra, c->maxframe); + "There are %d clusters containing %d structures, highest framenr is %d\n", c->clust->nr, + c->clust->nra, c->maxframe); if (debug) { pr_blocka(debug, 0, "clust", c->clust, TRUE); @@ -1036,8 +1040,10 @@ t_cluster_ndx *cluster_index(FILE *fplog, const char *ndx) { if ((c->clust->a[i] < 0) || (c->clust->a[i] > c->maxframe)) { - gmx_fatal(FARGS, "Range check error for c->clust->a[%d] = %d\n" - "should be within 0 and %d", i, c->clust->a[i], c->maxframe+1); + gmx_fatal(FARGS, + "Range check error for c->clust->a[%d] = %d\n" + "should be within 0 and %d", + i, c->clust->a[i], c->maxframe + 1); } } } diff --git a/src/gromacs/topology/index.h b/src/gromacs/topology/index.h index 148fcc8a6d..c6f1fb7263 100644 --- a/src/gromacs/topology/index.h +++ b/src/gromacs/topology/index.h @@ -45,18 +45,16 @@ struct t_atoms; struct t_blocka; -void check_index(const char *gname, int n, int index[], - const char *traj, int natoms); +void check_index(const char* gname, int n, int index[], const char* traj, int natoms); /* Checks if any index is smaller than zero or larger than natoms, * if so a fatal_error is given with the gname (if gname=NULL, "Index" is used) * and traj (if traj=NULL, "the trajectory" is used). */ -struct t_blocka *init_index(const char *gfile, char ***grpname); +struct t_blocka* init_index(const char* gfile, char*** grpname); /* Lower level routine than the next */ -void rd_index(const char *statfile, int ngrps, int isize[], - int *index[], char *grpnames[]); +void rd_index(const char* statfile, int ngrps, int isize[], int* index[], char* grpnames[]); /* Assume the group file is generated, so the * format need not be user-friendly. The format is: * nr of groups, total nr of atoms @@ -72,24 +70,24 @@ void rd_index(const char *statfile, int ngrps, int isize[], * the dimension of the isize and grpnames arrays are ngrps. */ -void get_index(const t_atoms *atoms, const char *fnm, int ngrps, - int isize[], int *index[], char *grpnames[]); +void get_index(const t_atoms* atoms, const char* fnm, int ngrps, int isize[], int* index[], char* grpnames[]); /* Does the same as rd_index, but if the fnm pointer is NULL it * will not read from fnm, but it will make default index groups * for the atoms in *atoms. */ -typedef struct { - int maxframe; - char **grpname; - struct t_blocka *clust; - int *inv_clust; +typedef struct +{ + int maxframe; + char** grpname; + struct t_blocka* clust; + int* inv_clust; } t_cluster_ndx; -t_cluster_ndx *cluster_index(FILE *fplog, const char *ndx); +t_cluster_ndx* cluster_index(FILE* fplog, const char* ndx); -void write_index(const char *outf, struct t_blocka *b, char **gnames, gmx_bool bDuplicate, int natoms); +void write_index(const char* outf, struct t_blocka* b, char** gnames, gmx_bool bDuplicate, int natoms); /* Writes index blocks to outf (writes an indexfile) */ /*! \brief @@ -100,11 +98,10 @@ void write_index(const char *outf, struct t_blocka *b, char **gnames, gmx_bool b * \param[in] a Group to add to Block. * \param[in] name Group name. */ -void add_grp(struct t_blocka *b, char ***gnames, gmx::ArrayRef a, const std::string &name); +void add_grp(struct t_blocka* b, char*** gnames, gmx::ArrayRef a, const std::string& name); /* Ads group a with name name to block b and namelist gnames */ -void analyse(const t_atoms *atoms, struct t_blocka *gb, char ***gn, - gmx_bool bASK, gmx_bool bVerb); +void analyse(const t_atoms* atoms, struct t_blocka* gb, char*** gn, gmx_bool bASK, gmx_bool bVerb); /* Makes index groups gb with names gn for atoms in atoms. * bASK=FALSE gives default groups. */ @@ -116,7 +113,7 @@ void analyse(const t_atoms *atoms, struct t_blocka *gb, char ***gn, * \param[in] grpname The names of the groups * \return the group number or -1 if not found. */ -int find_group(const char *s, int ngrps, char **grpname); +int find_group(const char* s, int ngrps, char** grpname); #endif diff --git a/src/gromacs/topology/invblock.cpp b/src/gromacs/topology/invblock.cpp index 3e5e6c069d..9f4d6878f3 100644 --- a/src/gromacs/topology/invblock.cpp +++ b/src/gromacs/topology/invblock.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,12 +43,12 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -int *make_invblock(const t_block *block, int nr) +int* make_invblock(const t_block* block, int nr) { - int i, j; - int *invblock; + int i, j; + int* invblock; - snew(invblock, nr+1); + snew(invblock, nr + 1); /* Mark unused numbers */ for (i = 0; i <= nr; i++) { @@ -56,7 +56,7 @@ int *make_invblock(const t_block *block, int nr) } for (i = 0; (i < block->nr); i++) { - for (j = block->index[i]; (j < block->index[i+1]); j++) + for (j = block->index[i]; (j < block->index[i + 1]); j++) { if (invblock[j] == -1) { @@ -64,7 +64,8 @@ int *make_invblock(const t_block *block, int nr) } else { - gmx_fatal(FARGS, "Double entries in block structure. Item %d is in blocks %d and %d\n" + gmx_fatal(FARGS, + "Double entries in block structure. Item %d is in blocks %d and %d\n" " Cannot make an unambiguous inverse block.", j, i, invblock[j]); } @@ -73,12 +74,12 @@ int *make_invblock(const t_block *block, int nr) return invblock; } -int *make_invblocka(const t_blocka *block, int nr) +int* make_invblocka(const t_blocka* block, int nr) { - int i, j; - int *invblock; + int i, j; + int* invblock; - snew(invblock, nr+1); + snew(invblock, nr + 1); /* Mark unused numbers */ for (i = 0; i <= nr; i++) { @@ -86,7 +87,7 @@ int *make_invblocka(const t_blocka *block, int nr) } for (i = 0; (i < block->nr); i++) { - for (j = block->index[i]; (j < block->index[i+1]); j++) + for (j = block->index[i]; (j < block->index[i + 1]); j++) { if (invblock[block->a[j]] == -1) { @@ -94,7 +95,8 @@ int *make_invblocka(const t_blocka *block, int nr) } else { - gmx_fatal(FARGS, "Double entries in block structure. Item %d is in blocks %d and %d\n" + gmx_fatal(FARGS, + "Double entries in block structure. Item %d is in blocks %d and %d\n" " Cannot make an unambiguous inverse block.", j, i, invblock[block->a[j]]); } diff --git a/src/gromacs/topology/invblock.h b/src/gromacs/topology/invblock.h index 875d72ec17..33494e5652 100644 --- a/src/gromacs/topology/invblock.h +++ b/src/gromacs/topology/invblock.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,12 +41,12 @@ struct t_block; struct t_blocka; -int *make_invblock(const struct t_block *block, int nr); +int* make_invblock(const struct t_block* block, int nr); /* Inverse the block structure. nr is the maximum entry in the inversed * array, and therefore the dimension of the returned array */ -int *make_invblocka(const struct t_blocka *block, int nr); +int* make_invblocka(const struct t_blocka* block, int nr); /* Inverse the block structure. nr is the maximum entry in the inversed * array, and therefore the dimension of the returned array */ diff --git a/src/gromacs/topology/mtop_lookup.h b/src/gromacs/topology/mtop_lookup.h index 3f5e03c5ec..f6491bbc9c 100644 --- a/src/gromacs/topology/mtop_lookup.h +++ b/src/gromacs/topology/mtop_lookup.h @@ -69,18 +69,16 @@ struct t_atom; * \param[out] moleculeIndex The index of the molecule in the block, can be NULL * \param[out] atomIndexInMolecule The atom index in the molecule, can be NULL */ -static inline void -mtopGetMolblockIndex(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock, - int *moleculeIndex, - int *atomIndexInMolecule) +static inline void mtopGetMolblockIndex(const gmx_mtop_t* mtop, + int globalAtomIndex, + int* moleculeBlock, + int* moleculeIndex, + int* atomIndexInMolecule) { GMX_ASSERT(globalAtomIndex >= 0, "The atom index to look up should not be negative"); GMX_ASSERT(globalAtomIndex < mtop->natoms, "The atom index to look up should be within range"); GMX_ASSERT(moleculeBlock != nullptr, "molBlock can not be NULL"); - GMX_ASSERT(!mtop->moleculeBlockIndices.empty(), - "The moleculeBlockIndices should not be empty"); + GMX_ASSERT(!mtop->moleculeBlockIndices.empty(), "The moleculeBlockIndices should not be empty"); GMX_ASSERT(*moleculeBlock >= 0, "The starting molecule block index for the search should not be negative"); GMX_ASSERT(*moleculeBlock < gmx::ssize(mtop->moleculeBlockIndices), @@ -109,14 +107,16 @@ mtopGetMolblockIndex(const gmx_mtop_t *mtop, *moleculeBlock = ((molBlock0 + molBlock1 + 1) >> 1); } - int molIndex = (globalAtomIndex - globalAtomStart) / mtop->moleculeBlockIndices[*moleculeBlock].numAtomsPerMolecule; + int molIndex = (globalAtomIndex - globalAtomStart) + / mtop->moleculeBlockIndices[*moleculeBlock].numAtomsPerMolecule; if (moleculeIndex != nullptr) { *moleculeIndex = molIndex; } if (atomIndexInMolecule != nullptr) { - *atomIndexInMolecule = globalAtomIndex - globalAtomStart - molIndex*mtop->moleculeBlockIndices[*moleculeBlock].numAtomsPerMolecule; + *atomIndexInMolecule = globalAtomIndex - globalAtomStart + - molIndex * mtop->moleculeBlockIndices[*moleculeBlock].numAtomsPerMolecule; } } @@ -132,10 +132,7 @@ mtopGetMolblockIndex(const gmx_mtop_t *mtop, * \param[in] globalAtomIndex The global atom index to look up * \param[in,out] moleculeBlock The molecule block index in \p mtop */ -static inline int -mtopGetMoleculeIndex(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock) +static inline int mtopGetMoleculeIndex(const gmx_mtop_t* mtop, int globalAtomIndex, int* moleculeBlock) { int localMoleculeIndex; mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, &localMoleculeIndex, nullptr); @@ -155,15 +152,11 @@ mtopGetMoleculeIndex(const gmx_mtop_t *mtop, * \param[in] globalAtomIndex The global atom index to look up * \param[in,out] moleculeBlock The molecule block index in \p mtop */ -static inline const t_atom & -mtopGetAtomParameters(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock) +static inline const t_atom& mtopGetAtomParameters(const gmx_mtop_t* mtop, int globalAtomIndex, int* moleculeBlock) { int atomIndexInMolecule; - mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, - nullptr, &atomIndexInMolecule); - const gmx_moltype_t &moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; + mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, nullptr, &atomIndexInMolecule); + const gmx_moltype_t& moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; return moltype.atoms.atom[atomIndexInMolecule]; } @@ -180,12 +173,9 @@ mtopGetAtomParameters(const gmx_mtop_t *mtop, * \param[in] globalAtomIndex The global atom index to look up * \param[in,out] moleculeBlock The molecule block index in \p mtop */ -static inline real -mtopGetAtomMass(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock) +static inline real mtopGetAtomMass(const gmx_mtop_t* mtop, int globalAtomIndex, int* moleculeBlock) { - const t_atom &atom = mtopGetAtomParameters(mtop, globalAtomIndex, moleculeBlock); + const t_atom& atom = mtopGetAtomParameters(mtop, globalAtomIndex, moleculeBlock); return atom.m; } @@ -208,23 +198,21 @@ mtopGetAtomMass(const gmx_mtop_t *mtop, * \param[out] residueName The residue name, input can be NULL * \param[out] globalResidueIndex The gobal residue index, input can be NULL */ -static inline void -mtopGetAtomAndResidueName(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock, - const char **atomName, - int *residueNumber, - const char **residueName, - int *globalResidueIndex) +static inline void mtopGetAtomAndResidueName(const gmx_mtop_t* mtop, + int globalAtomIndex, + int* moleculeBlock, + const char** atomName, + int* residueNumber, + const char** residueName, + int* globalResidueIndex) { int moleculeIndex; int atomIndexInMolecule; - mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, - &moleculeIndex, &atomIndexInMolecule); + mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, &moleculeIndex, &atomIndexInMolecule); - const gmx_molblock_t &molb = mtop->molblock[*moleculeBlock]; - const t_atoms &atoms = mtop->moltype[molb.type].atoms; - const MoleculeBlockIndices &indices = mtop->moleculeBlockIndices[*moleculeBlock]; + const gmx_molblock_t& molb = mtop->molblock[*moleculeBlock]; + const t_atoms& atoms = mtop->moltype[molb.type].atoms; + const MoleculeBlockIndices& indices = mtop->moleculeBlockIndices[*moleculeBlock]; if (atomName != nullptr) { *atomName = *(atoms.atomname[atomIndexInMolecule]); @@ -238,7 +226,8 @@ mtopGetAtomAndResidueName(const gmx_mtop_t *mtop, else { /* Single residue molecule, keep counting */ - *residueNumber = indices.residueNumberStart + moleculeIndex*atoms.nres + atoms.atom[atomIndexInMolecule].resind; + *residueNumber = indices.residueNumberStart + moleculeIndex * atoms.nres + + atoms.atom[atomIndexInMolecule].resind; } } if (residueName != nullptr) @@ -247,22 +236,22 @@ mtopGetAtomAndResidueName(const gmx_mtop_t *mtop, } if (globalResidueIndex != nullptr) { - *globalResidueIndex = indices.globalResidueStart + moleculeIndex*atoms.nres + atoms.atom[atomIndexInMolecule].resind; + *globalResidueIndex = indices.globalResidueStart + moleculeIndex * atoms.nres + + atoms.atom[atomIndexInMolecule].resind; } } //! \copydoc mtopGetAtomAndResidueName() -static inline void -mtopGetAtomAndResidueName(const gmx_mtop_t &mtop, - int globalAtomIndex, - int *moleculeBlock, - const char **atomName, - int *residueNumber, - const char **residueName, - int *globalResidueIndex) +static inline void mtopGetAtomAndResidueName(const gmx_mtop_t& mtop, + int globalAtomIndex, + int* moleculeBlock, + const char** atomName, + int* residueNumber, + const char** residueName, + int* globalResidueIndex) { - mtopGetAtomAndResidueName(&mtop, globalAtomIndex, moleculeBlock, - atomName, residueNumber, residueName, globalResidueIndex); + mtopGetAtomAndResidueName(&mtop, globalAtomIndex, moleculeBlock, atomName, residueNumber, + residueName, globalResidueIndex); } /*! \brief Returns residue information for an atom based on global atom index @@ -277,15 +266,11 @@ mtopGetAtomAndResidueName(const gmx_mtop_t &mtop, * \param[in] globalAtomIndex The global atom index to look up * \param[in,out] moleculeBlock The molecule block index in \p mtop */ -static inline const t_resinfo & -mtopGetResidueInfo(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock) +static inline const t_resinfo& mtopGetResidueInfo(const gmx_mtop_t* mtop, int globalAtomIndex, int* moleculeBlock) { int atomIndexInMolecule; - mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, - nullptr, &atomIndexInMolecule); - const gmx_moltype_t &moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; + mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, nullptr, &atomIndexInMolecule); + const gmx_moltype_t& moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; const int resind = moltype.atoms.atom[atomIndexInMolecule].resind; return moltype.atoms.resinfo[resind]; } @@ -302,15 +287,11 @@ mtopGetResidueInfo(const gmx_mtop_t *mtop, * \param[in] globalAtomIndex The global atom index to look up * \param[in,out] moleculeBlock The molecule block index in \p mtop */ -static inline const t_pdbinfo & -mtopGetAtomPdbInfo(const gmx_mtop_t *mtop, - int globalAtomIndex, - int *moleculeBlock) +static inline const t_pdbinfo& mtopGetAtomPdbInfo(const gmx_mtop_t* mtop, int globalAtomIndex, int* moleculeBlock) { int atomIndexInMolecule; - mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, - nullptr, &atomIndexInMolecule); - const gmx_moltype_t &moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; + mtopGetMolblockIndex(mtop, globalAtomIndex, moleculeBlock, nullptr, &atomIndexInMolecule); + const gmx_moltype_t& moltype = mtop->moltype[mtop->molblock[*moleculeBlock].type]; GMX_ASSERT(moltype.atoms.havePdbInfo, "PDB information not present when requested"); return moltype.atoms.pdbinfo[atomIndexInMolecule]; } diff --git a/src/gromacs/topology/mtop_util.cpp b/src/gromacs/topology/mtop_util.cpp index 363a37c5e8..4bc2e2946e 100644 --- a/src/gromacs/topology/mtop_util.cpp +++ b/src/gromacs/topology/mtop_util.cpp @@ -56,13 +56,13 @@ #include "gromacs/utility/real.h" #include "gromacs/utility/smalloc.h" -static int gmx_mtop_maxresnr(const gmx_mtop_t *mtop, int maxres_renum) +static int gmx_mtop_maxresnr(const gmx_mtop_t* mtop, int maxres_renum) { int maxresnr = 0; - for (const gmx_moltype_t &moltype : mtop->moltype) + for (const gmx_moltype_t& moltype : mtop->moltype) { - const t_atoms &atoms = moltype.atoms; + const t_atoms& atoms = moltype.atoms; if (atoms.nres > maxres_renum) { for (int r = 0; r < atoms.nres; r++) @@ -78,7 +78,7 @@ static int gmx_mtop_maxresnr(const gmx_mtop_t *mtop, int maxres_renum) return maxresnr; } -static void buildMolblockIndices(gmx_mtop_t *mtop) +static void buildMolblockIndices(gmx_mtop_t* mtop) { mtop->moleculeBlockIndices.resize(mtop->molblock.size()); @@ -88,29 +88,29 @@ static void buildMolblockIndices(gmx_mtop_t *mtop) int moleculeIndexStart = 0; for (size_t mb = 0; mb < mtop->molblock.size(); mb++) { - const gmx_molblock_t &molb = mtop->molblock[mb]; - MoleculeBlockIndices &indices = mtop->moleculeBlockIndices[mb]; + const gmx_molblock_t& molb = mtop->molblock[mb]; + MoleculeBlockIndices& indices = mtop->moleculeBlockIndices[mb]; const int numResPerMol = mtop->moltype[molb.type].atoms.nres; - indices.numAtomsPerMolecule = mtop->moltype[molb.type].atoms.nr; - indices.globalAtomStart = atomIndex; - indices.globalResidueStart = residueIndex; - atomIndex += molb.nmol*indices.numAtomsPerMolecule; - residueIndex += molb.nmol*numResPerMol; - indices.globalAtomEnd = atomIndex; - indices.residueNumberStart = residueNumberStart; + indices.numAtomsPerMolecule = mtop->moltype[molb.type].atoms.nr; + indices.globalAtomStart = atomIndex; + indices.globalResidueStart = residueIndex; + atomIndex += molb.nmol * indices.numAtomsPerMolecule; + residueIndex += molb.nmol * numResPerMol; + indices.globalAtomEnd = atomIndex; + indices.residueNumberStart = residueNumberStart; if (numResPerMol <= mtop->maxres_renum) { - residueNumberStart += molb.nmol*numResPerMol; + residueNumberStart += molb.nmol * numResPerMol; } - indices.moleculeIndexStart = moleculeIndexStart; - moleculeIndexStart += molb.nmol; + indices.moleculeIndexStart = moleculeIndexStart; + moleculeIndexStart += molb.nmol; } } -void gmx_mtop_finalize(gmx_mtop_t *mtop) +void gmx_mtop_finalize(gmx_mtop_t* mtop) { - char *env; + char* env; if (mtop->molblock.size() == 1 && mtop->molblock[0].nmol == 1) { @@ -144,15 +144,15 @@ void gmx_mtop_finalize(gmx_mtop_t *mtop) buildMolblockIndices(mtop); } -void gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[]) +void gmx_mtop_count_atomtypes(const gmx_mtop_t* mtop, int state, int typecount[]) { for (int i = 0; i < mtop->ffparams.atnr; ++i) { typecount[i] = 0; } - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const t_atoms &atoms = mtop->moltype[molb.type].atoms; + const t_atoms& atoms = mtop->moltype[molb.type].atoms; for (int i = 0; i < atoms.nr; ++i) { int tpi; @@ -169,37 +169,40 @@ void gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[] } } -int gmx_mtop_num_molecules(const gmx_mtop_t &mtop) +int gmx_mtop_num_molecules(const gmx_mtop_t& mtop) { int numMolecules = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { numMolecules += molb.nmol; } return numMolecules; } -int gmx_mtop_nres(const gmx_mtop_t *mtop) +int gmx_mtop_nres(const gmx_mtop_t* mtop) { int nres = 0; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - nres += molb.nmol*mtop->moltype[molb.type].atoms.nres; + nres += molb.nmol * mtop->moltype[molb.type].atoms.nres; } return nres; } -AtomIterator::AtomIterator(const gmx_mtop_t &mtop, int globalAtomNumber) - : mtop_(&mtop), mblock_(0), - atoms_(&mtop.moltype[mtop.molblock[0].type].atoms), - currentMolecule_(0), highestResidueNumber_(mtop.maxresnr), - localAtomNumber_(0), globalAtomNumber_(globalAtomNumber) +AtomIterator::AtomIterator(const gmx_mtop_t& mtop, int globalAtomNumber) : + mtop_(&mtop), + mblock_(0), + atoms_(&mtop.moltype[mtop.molblock[0].type].atoms), + currentMolecule_(0), + highestResidueNumber_(mtop.maxresnr), + localAtomNumber_(0), + globalAtomNumber_(globalAtomNumber) { GMX_ASSERT(globalAtomNumber == 0 || globalAtomNumber == mtop.natoms, "Starting at other atoms not implemented yet"); } -AtomIterator &AtomIterator::operator++() +AtomIterator& AtomIterator::operator++() { localAtomNumber_++; globalAtomNumber_++; @@ -234,17 +237,17 @@ AtomIterator AtomIterator::operator++(int) return temp; } -bool AtomIterator::operator==(const AtomIterator &o) const +bool AtomIterator::operator==(const AtomIterator& o) const { return mtop_ == o.mtop_ && globalAtomNumber_ == o.globalAtomNumber_; } -bool AtomIterator::operator!=(const AtomIterator &o) const +bool AtomIterator::operator!=(const AtomIterator& o) const { return !(*this == o); } -const t_atom &AtomProxy::atom() const +const t_atom& AtomProxy::atom() const { return it_->atoms_->atom[it_->localAtomNumber_]; } @@ -254,12 +257,12 @@ int AtomProxy::globalAtomNumber() const return it_->globalAtomNumber_; } -const char *AtomProxy::atomName() const +const char* AtomProxy::atomName() const { return *(it_->atoms_->atomname[it_->localAtomNumber_]); } -const char *AtomProxy::residueName() const +const char* AtomProxy::residueName() const { int residueIndexInMolecule = it_->atoms_->atom[it_->localAtomNumber_].resind; return *(it_->atoms_->resinfo[residueIndexInMolecule].name); @@ -278,7 +281,7 @@ int AtomProxy::residueNumber() const } } -const gmx_moltype_t &AtomProxy::moleculeType() const +const gmx_moltype_t& AtomProxy::moleculeType() const { return it_->mtop_->moltype[it_->mtop_->molblock[it_->mblock_].type]; } @@ -290,23 +293,22 @@ int AtomProxy::atomNumberInMol() const typedef struct gmx_mtop_atomloop_block { - const gmx_mtop_t *mtop; + const gmx_mtop_t* mtop; size_t mblock; - const t_atoms *atoms; + const t_atoms* atoms; int at_local; } t_gmx_mtop_atomloop_block; -gmx_mtop_atomloop_block_t -gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop) +gmx_mtop_atomloop_block_t gmx_mtop_atomloop_block_init(const gmx_mtop_t* mtop) { - struct gmx_mtop_atomloop_block *aloop; + struct gmx_mtop_atomloop_block* aloop; snew(aloop, 1); - aloop->mtop = mtop; - aloop->mblock = 0; - aloop->atoms = &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms; - aloop->at_local = -1; + aloop->mtop = mtop; + aloop->mblock = 0; + aloop->atoms = &mtop->moltype[mtop->molblock[aloop->mblock].type].atoms; + aloop->at_local = -1; return aloop; } @@ -316,8 +318,7 @@ static void gmx_mtop_atomloop_block_destroy(gmx_mtop_atomloop_block_t aloop) sfree(aloop); } -gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, - const t_atom **atom, int *nmol) +gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_atom** atom, int* nmol) { if (aloop == nullptr) { @@ -346,25 +347,23 @@ gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, typedef struct gmx_mtop_ilistloop { - const gmx_mtop_t *mtop; + const gmx_mtop_t* mtop; int mblock; } t_gmx_mtop_ilist; -gmx_mtop_ilistloop_t -gmx_mtop_ilistloop_init(const gmx_mtop_t *mtop) +gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t* mtop) { - struct gmx_mtop_ilistloop *iloop; + struct gmx_mtop_ilistloop* iloop; snew(iloop, 1); - iloop->mtop = mtop; - iloop->mblock = -1; + iloop->mtop = mtop; + iloop->mblock = -1; return iloop; } -gmx_mtop_ilistloop_t -gmx_mtop_ilistloop_init(const gmx_mtop_t &mtop) +gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop) { return gmx_mtop_ilistloop_init(&mtop); } @@ -374,9 +373,7 @@ static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop) sfree(iloop); } -const InteractionLists * -gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, - int *nmol) +const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol) { if (iloop == nullptr) { @@ -386,10 +383,9 @@ gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, iloop->mblock++; if (iloop->mblock >= gmx::ssize(iloop->mtop->molblock)) { - if (iloop->mblock == gmx::ssize(iloop->mtop->molblock) && - iloop->mtop->bIntermolecularInteractions) + if (iloop->mblock == gmx::ssize(iloop->mtop->molblock) && iloop->mtop->bIntermolecularInteractions) { - *nmol = 1; + *nmol = 1; return iloop->mtop->intermolecular_ilist.get(); } @@ -399,28 +395,26 @@ gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, *nmol = iloop->mtop->molblock[iloop->mblock].nmol; - return - &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist; + return &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist; } typedef struct gmx_mtop_ilistloop_all { - const gmx_mtop_t *mtop; + const gmx_mtop_t* mtop; size_t mblock; int mol; int a_offset; } t_gmx_mtop_ilist_all; -gmx_mtop_ilistloop_all_t -gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop) +gmx_mtop_ilistloop_all_t gmx_mtop_ilistloop_all_init(const gmx_mtop_t* mtop) { - struct gmx_mtop_ilistloop_all *iloop; + struct gmx_mtop_ilistloop_all* iloop; snew(iloop, 1); - iloop->mtop = mtop; - iloop->mblock = 0; - iloop->mol = -1; - iloop->a_offset = 0; + iloop->mtop = mtop; + iloop->mblock = 0; + iloop->mol = -1; + iloop->a_offset = 0; return iloop; } @@ -430,14 +424,13 @@ static void gmx_mtop_ilistloop_all_destroy(gmx_mtop_ilistloop_all_t iloop) sfree(iloop); } -const InteractionLists * -gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, - int *atnr_offset) +const InteractionLists* gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, int* atnr_offset) { if (iloop == nullptr) { - gmx_incons("gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init"); + gmx_incons( + "gmx_mtop_ilistloop_all_next called without calling gmx_mtop_ilistloop_all_init"); } if (iloop->mol >= 0) @@ -451,15 +444,14 @@ gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, * iloop->mblock == iloop->mtop->nmolblock, thus we should separately * check for this value in this conditional. */ - if (iloop->mblock == iloop->mtop->molblock.size() || - iloop->mol >= iloop->mtop->molblock[iloop->mblock].nmol) + if (iloop->mblock == iloop->mtop->molblock.size() + || iloop->mol >= iloop->mtop->molblock[iloop->mblock].nmol) { iloop->mblock++; iloop->mol = 0; if (iloop->mblock >= iloop->mtop->molblock.size()) { - if (iloop->mblock == iloop->mtop->molblock.size() && - iloop->mtop->bIntermolecularInteractions) + if (iloop->mblock == iloop->mtop->molblock.size() && iloop->mtop->bIntermolecularInteractions) { *atnr_offset = 0; return iloop->mtop->intermolecular_ilist.get(); @@ -472,50 +464,48 @@ gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, *atnr_offset = iloop->a_offset; - return - &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist; + return &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist; } -int gmx_mtop_ftype_count(const gmx_mtop_t *mtop, int ftype) +int gmx_mtop_ftype_count(const gmx_mtop_t* mtop, int ftype) { - gmx_mtop_ilistloop_t iloop; - int n, nmol; + gmx_mtop_ilistloop_t iloop; + int n, nmol; n = 0; iloop = gmx_mtop_ilistloop_init(mtop); - while (const InteractionLists *il = gmx_mtop_ilistloop_next(iloop, &nmol)) + while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) { - n += nmol*(*il)[ftype].size()/(1+NRAL(ftype)); + n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype)); } if (mtop->bIntermolecularInteractions) { - n += (*mtop->intermolecular_ilist)[ftype].size()/(1+NRAL(ftype)); + n += (*mtop->intermolecular_ilist)[ftype].size() / (1 + NRAL(ftype)); } return n; } -int gmx_mtop_ftype_count(const gmx_mtop_t &mtop, int ftype) +int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype) { return gmx_mtop_ftype_count(&mtop, ftype); } -int gmx_mtop_interaction_count(const gmx_mtop_t &mtop, - const int unsigned if_flags) +int gmx_mtop_interaction_count(const gmx_mtop_t& mtop, const int unsigned if_flags) { - int n = 0; + int n = 0; gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(mtop); int nmol; - while (const InteractionLists *il = gmx_mtop_ilistloop_next(iloop, &nmol)) + while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol)) { for (int ftype = 0; ftype < F_NRE; ftype++) { if ((interaction_function[ftype].flags & if_flags) == if_flags) { - n += nmol*(*il)[ftype].size()/(1 + NRAL(ftype)); + n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype)); } } } @@ -526,7 +516,7 @@ int gmx_mtop_interaction_count(const gmx_mtop_t &mtop, { if ((interaction_function[ftype].flags & if_flags) == if_flags) { - n += (*mtop.intermolecular_ilist)[ftype].size()/(1 + NRAL(ftype)); + n += (*mtop.intermolecular_ilist)[ftype].size() / (1 + NRAL(ftype)); } } } @@ -534,8 +524,7 @@ int gmx_mtop_interaction_count(const gmx_mtop_t &mtop, return n; } -static void atomcat(t_atoms *dest, const t_atoms *src, int copies, - int maxres_renum, int *maxresnr) +static void atomcat(t_atoms* dest, const t_atoms* src, int copies, int maxres_renum, int* maxresnr) { int i, j, l, size; int srcnr = src->nr; @@ -551,16 +540,16 @@ static void atomcat(t_atoms *dest, const t_atoms *src, int copies, } else { - dest->haveMass = dest->haveMass && src->haveMass; - dest->haveType = dest->haveType && src->haveType; - dest->haveCharge = dest->haveCharge && src->haveCharge; - dest->haveBState = dest->haveBState && src->haveBState; + dest->haveMass = dest->haveMass && src->haveMass; + dest->haveType = dest->haveType && src->haveType; + dest->haveCharge = dest->haveCharge && src->haveCharge; + dest->haveBState = dest->haveBState && src->haveBState; dest->havePdbInfo = dest->havePdbInfo && src->havePdbInfo; } if (srcnr) { - size = destnr+copies*srcnr; + size = destnr + copies * srcnr; srenew(dest->atom, size); srenew(dest->atomname, size); if (dest->haveType) @@ -578,37 +567,41 @@ static void atomcat(t_atoms *dest, const t_atoms *src, int copies, } if (src->nres) { - size = dest->nres+copies*src->nres; + size = dest->nres + copies * src->nres; srenew(dest->resinfo, size); } /* residue information */ for (l = dest->nres, j = 0; (j < copies); j++, l += src->nres) { - memcpy(reinterpret_cast(&(dest->resinfo[l])), reinterpret_cast(&(src->resinfo[0])), - static_cast(src->nres*sizeof(src->resinfo[0]))); + memcpy(reinterpret_cast(&(dest->resinfo[l])), reinterpret_cast(&(src->resinfo[0])), + static_cast(src->nres * sizeof(src->resinfo[0]))); } for (l = destnr, j = 0; (j < copies); j++, l += srcnr) { - memcpy(reinterpret_cast(&(dest->atom[l])), reinterpret_cast(&(src->atom[0])), - static_cast(srcnr*sizeof(src->atom[0]))); - memcpy(reinterpret_cast(&(dest->atomname[l])), reinterpret_cast(&(src->atomname[0])), - static_cast(srcnr*sizeof(src->atomname[0]))); + memcpy(reinterpret_cast(&(dest->atom[l])), reinterpret_cast(&(src->atom[0])), + static_cast(srcnr * sizeof(src->atom[0]))); + memcpy(reinterpret_cast(&(dest->atomname[l])), + reinterpret_cast(&(src->atomname[0])), + static_cast(srcnr * sizeof(src->atomname[0]))); if (dest->haveType) { - memcpy(reinterpret_cast(&(dest->atomtype[l])), reinterpret_cast(&(src->atomtype[0])), - static_cast(srcnr*sizeof(src->atomtype[0]))); + memcpy(reinterpret_cast(&(dest->atomtype[l])), + reinterpret_cast(&(src->atomtype[0])), + static_cast(srcnr * sizeof(src->atomtype[0]))); if (dest->haveBState) { - memcpy(reinterpret_cast(&(dest->atomtypeB[l])), reinterpret_cast(&(src->atomtypeB[0])), - static_cast(srcnr*sizeof(src->atomtypeB[0]))); + memcpy(reinterpret_cast(&(dest->atomtypeB[l])), + reinterpret_cast(&(src->atomtypeB[0])), + static_cast(srcnr * sizeof(src->atomtypeB[0]))); } } if (dest->havePdbInfo) { - memcpy(reinterpret_cast(&(dest->pdbinfo[l])), reinterpret_cast(&(src->pdbinfo[0])), - static_cast(srcnr*sizeof(src->pdbinfo[0]))); + memcpy(reinterpret_cast(&(dest->pdbinfo[l])), + reinterpret_cast(&(src->pdbinfo[0])), + static_cast(srcnr * sizeof(src->pdbinfo[0]))); } } @@ -617,7 +610,7 @@ static void atomcat(t_atoms *dest, const t_atoms *src, int copies, { for (i = 0; (i < srcnr); i++, l++) { - dest->atom[l].resind = dest->nres+j*src->nres+src->atom[i].resind; + dest->atom[l].resind = dest->nres + j * src->nres + src->atom[i].resind; } } @@ -629,26 +622,25 @@ static void atomcat(t_atoms *dest, const t_atoms *src, int copies, for (l = 0; l < src->nres; l++) { (*maxresnr)++; - dest->resinfo[dest->nres+j*src->nres+l].nr = *maxresnr; + dest->resinfo[dest->nres + j * src->nres + l].nr = *maxresnr; } } } - dest->nres += copies*src->nres; - dest->nr += copies*src->nr; + dest->nres += copies * src->nres; + dest->nr += copies * src->nr; } -t_atoms gmx_mtop_global_atoms(const gmx_mtop_t *mtop) +t_atoms gmx_mtop_global_atoms(const gmx_mtop_t* mtop) { - t_atoms atoms; + t_atoms atoms; init_t_atoms(&atoms, 0, FALSE); int maxresnr = mtop->maxresnr; - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - atomcat(&atoms, &mtop->moltype[molb.type].atoms, molb.nmol, - mtop->maxres_renum, &maxresnr); + atomcat(&atoms, &mtop->moltype[molb.type].atoms, molb.nmol, mtop->maxres_renum, &maxresnr); } return atoms; @@ -658,8 +650,7 @@ t_atoms gmx_mtop_global_atoms(const gmx_mtop_t *mtop) * The cat routines below are old code from src/kernel/topcat.c */ -static void blockacat(t_blocka *dest, const t_blocka *src, int copies, - int dnum, int snum) +static void blockacat(t_blocka* dest, const t_blocka* src, int copies, int dnum, int snum) { int i, j, l, size; int destnr = dest->nr; @@ -667,12 +658,12 @@ static void blockacat(t_blocka *dest, const t_blocka *src, int copies, if (src->nr) { - size = (dest->nr+copies*src->nr+1); + size = (dest->nr + copies * src->nr + 1); srenew(dest->index, size); } if (src->nra) { - size = (dest->nra+copies*src->nra); + size = (dest->nra + copies * src->nra); srenew(dest->a, size); } @@ -680,7 +671,7 @@ static void blockacat(t_blocka *dest, const t_blocka *src, int copies, { for (i = 0; (i < src->nr); i++) { - dest->index[l++] = dest->nra+src->index[i]; + dest->index[l++] = dest->nra + src->index[i]; } dest->nra += src->nra; } @@ -688,9 +679,9 @@ static void blockacat(t_blocka *dest, const t_blocka *src, int copies, { for (i = 0; (i < src->nra); i++) { - dest->a[l++] = dnum+src->a[i]; + dest->a[l++] = dnum + src->a[i]; } - dnum += snum; + dnum += snum; dest->nr += src->nr; } dest->index[dest->nr] = dest->nra; @@ -698,23 +689,18 @@ static void blockacat(t_blocka *dest, const t_blocka *src, int copies, dest->nalloc_a = dest->nra; } -static void ilistcat(int ftype, - t_ilist *dest, - const InteractionList &src, - int copies, - int dnum, - int snum) +static void ilistcat(int ftype, t_ilist* dest, const InteractionList& src, int copies, int dnum, int snum) { int nral, c, i, a; nral = NRAL(ftype); - dest->nalloc = dest->nr + copies*src.size(); + dest->nalloc = dest->nr + copies * src.size(); srenew(dest->iatoms, dest->nalloc); for (c = 0; c < copies; c++) { - for (i = 0; i < src.size(); ) + for (i = 0; i < src.size();) { dest->iatoms[dest->nr++] = src.iatoms[i++]; for (a = 0; a < nral; a++) @@ -726,23 +712,22 @@ static void ilistcat(int ftype, } } -static void set_posres_params(t_idef *idef, const gmx_molblock_t *molb, - int i0, int a_offset) +static void set_posres_params(t_idef* idef, const gmx_molblock_t* molb, int i0, int a_offset) { - t_ilist *il; + t_ilist* il; int i1, i, a_molb; - t_iparams *ip; + t_iparams* ip; - il = &idef->il[F_POSRES]; - i1 = il->nr/2; + il = &idef->il[F_POSRES]; + i1 = il->nr / 2; idef->iparams_posres_nalloc = i1; srenew(idef->iparams_posres, idef->iparams_posres_nalloc); for (i = i0; i < i1; i++) { ip = &idef->iparams_posres[i]; /* Copy the force constants */ - *ip = idef->iparams[il->iatoms[i*2]]; - a_molb = il->iatoms[i*2+1] - a_offset; + *ip = idef->iparams[il->iatoms[i * 2]]; + a_molb = il->iatoms[i * 2 + 1] - a_offset; if (molb->posres_xA.empty()) { gmx_incons("Position restraint coordinates are missing"); @@ -763,27 +748,26 @@ static void set_posres_params(t_idef *idef, const gmx_molblock_t *molb, ip->posres.pos0B[ZZ] = ip->posres.pos0A[ZZ]; } /* Set the parameter index for idef->iparams_posre */ - il->iatoms[i*2] = i; + il->iatoms[i * 2] = i; } } -static void set_fbposres_params(t_idef *idef, const gmx_molblock_t *molb, - int i0, int a_offset) +static void set_fbposres_params(t_idef* idef, const gmx_molblock_t* molb, int i0, int a_offset) { - t_ilist *il; + t_ilist* il; int i1, i, a_molb; - t_iparams *ip; + t_iparams* ip; - il = &idef->il[F_FBPOSRES]; - i1 = il->nr/2; + il = &idef->il[F_FBPOSRES]; + i1 = il->nr / 2; idef->iparams_fbposres_nalloc = i1; srenew(idef->iparams_fbposres, idef->iparams_fbposres_nalloc); for (i = i0; i < i1; i++) { ip = &idef->iparams_fbposres[i]; /* Copy the force constants */ - *ip = idef->iparams[il->iatoms[i*2]]; - a_molb = il->iatoms[i*2+1] - a_offset; + *ip = idef->iparams[il->iatoms[i * 2]]; + a_molb = il->iatoms[i * 2 + 1] - a_offset; if (molb->posres_xA.empty()) { gmx_incons("Position restraint coordinates are missing"); @@ -795,7 +779,7 @@ static void set_fbposres_params(t_idef *idef, const gmx_molblock_t *molb, /* Note: no B-type for flat-bottom posres */ /* Set the parameter index for idef->iparams_posre */ - il->iatoms[i*2] = i; + il->iatoms[i * 2] = i; } } @@ -810,15 +794,12 @@ static void set_fbposres_params(t_idef *idef, const gmx_molblock_t *molb, * \param[in] freeEnergyInteractionsAtEnd Decide if free energy stuff should * be added at the end. */ -static void copyIdefFromMtop(const gmx_mtop_t &mtop, - t_idef *idef, - bool freeEnergyInteractionsAtEnd, - bool mergeConstr) +static void copyIdefFromMtop(const gmx_mtop_t& mtop, t_idef* idef, bool freeEnergyInteractionsAtEnd, bool mergeConstr) { - const gmx_ffparams_t *ffp = &mtop.ffparams; + const gmx_ffparams_t* ffp = &mtop.ffparams; - idef->ntypes = ffp->numTypes(); - idef->atnr = ffp->atnr; + idef->ntypes = ffp->numTypes(); + idef->atnr = ffp->atnr; /* we can no longer copy the pointers to the mtop members, * because they will become invalid as soon as mtop gets free'd. * We also need to make sure to only operate on valid data! @@ -859,70 +840,67 @@ static void copyIdefFromMtop(const gmx_mtop_t &mtop, } int natoms = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; - int srcnr = molt.atoms.nr; - int destnr = natoms; + int srcnr = molt.atoms.nr; + int destnr = natoms; - int nposre_old = idef->il[F_POSRES].nr; - int nfbposre_old = idef->il[F_FBPOSRES].nr; + int nposre_old = idef->il[F_POSRES].nr; + int nfbposre_old = idef->il[F_FBPOSRES].nr; for (int ftype = 0; ftype < F_NRE; ftype++) { - if (mergeConstr && - ftype == F_CONSTR && molt.ilist[F_CONSTRNC].size() > 0) + if (mergeConstr && ftype == F_CONSTR && molt.ilist[F_CONSTRNC].size() > 0) { /* Merge all constrains into one ilist. * This simplifies the constraint code. */ for (int mol = 0; mol < molb.nmol; mol++) { - ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTR], - 1, destnr + mol*srcnr, srcnr); - ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTRNC], - 1, destnr + mol*srcnr, srcnr); + ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTR], 1, + destnr + mol * srcnr, srcnr); + ilistcat(ftype, &idef->il[F_CONSTR], molt.ilist[F_CONSTRNC], 1, + destnr + mol * srcnr, srcnr); } } else if (!(mergeConstr && ftype == F_CONSTRNC)) { - ilistcat(ftype, &idef->il[ftype], molt.ilist[ftype], - molb.nmol, destnr, srcnr); + ilistcat(ftype, &idef->il[ftype], molt.ilist[ftype], molb.nmol, destnr, srcnr); } } if (idef->il[F_POSRES].nr > nposre_old) { /* Executing this line line stops gmxdump -sys working * correctly. I'm not aware there's an elegant fix. */ - set_posres_params(idef, &molb, nposre_old/2, natoms); + set_posres_params(idef, &molb, nposre_old / 2, natoms); } if (idef->il[F_FBPOSRES].nr > nfbposre_old) { - set_fbposres_params(idef, &molb, nfbposre_old/2, natoms); + set_fbposres_params(idef, &molb, nfbposre_old / 2, natoms); } - natoms += molb.nmol*srcnr; + natoms += molb.nmol * srcnr; } if (mtop.bIntermolecularInteractions) { for (int ftype = 0; ftype < F_NRE; ftype++) { - ilistcat(ftype, &idef->il[ftype], (*mtop.intermolecular_ilist)[ftype], - 1, 0, mtop.natoms); + ilistcat(ftype, &idef->il[ftype], (*mtop.intermolecular_ilist)[ftype], 1, 0, mtop.natoms); } } if (freeEnergyInteractionsAtEnd && gmx_mtop_bondeds_free_energy(&mtop)) { - std::vector qA(mtop.natoms); - std::vector qB(mtop.natoms); + std::vector qA(mtop.natoms); + std::vector qB(mtop.natoms); for (const AtomProxy atomP : AtomRange(mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int index = atomP.globalAtomNumber(); - qA[index] = local.q; - qB[index] = local.qB; + qA[index] = local.q; + qB[index] = local.qB; } gmx_sort_ilist_fe(idef, qA.data(), qB.data()); } @@ -940,14 +918,14 @@ static void copyIdefFromMtop(const gmx_mtop_t &mtop, * \param[in] mtop Reference to input mtop. * \param[in] atomtypes Pointer to atomtypes to populate. */ -static void copyAtomtypesFromMtop(const gmx_mtop_t &mtop, - t_atomtypes *atomtypes) +static void copyAtomtypesFromMtop(const gmx_mtop_t& mtop, t_atomtypes* atomtypes) { atomtypes->nr = mtop.atomtypes.nr; if (mtop.atomtypes.atomnumber) { snew(atomtypes->atomnumber, mtop.atomtypes.nr); - std::copy(mtop.atomtypes.atomnumber, mtop.atomtypes.atomnumber + mtop.atomtypes.nr, atomtypes->atomnumber); + std::copy(mtop.atomtypes.atomnumber, mtop.atomtypes.atomnumber + mtop.atomtypes.nr, + atomtypes->atomnumber); } else { @@ -963,21 +941,20 @@ static void copyAtomtypesFromMtop(const gmx_mtop_t &mtop, * \param[in] mtop Reference to input mtop. * \param[in] excls Pointer to final excls data structure. */ -static void copyExclsFromMtop(const gmx_mtop_t &mtop, - t_blocka *excls) +static void copyExclsFromMtop(const gmx_mtop_t& mtop, t_blocka* excls) { init_blocka(excls); int natoms = 0; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { - const gmx_moltype_t &molt = mtop.moltype[molb.type]; + const gmx_moltype_t& molt = mtop.moltype[molb.type]; - int srcnr = molt.atoms.nr; - int destnr = natoms; + int srcnr = molt.atoms.nr; + int destnr = natoms; blockacat(excls, &molt.excls, molb.nmol, destnr, srcnr); - natoms += molb.nmol*srcnr; + natoms += molb.nmol * srcnr; } } @@ -989,12 +966,11 @@ static void copyExclsFromMtop(const gmx_mtop_t &mtop, * \param[inout] excls existing exclusions in local topology * \param[in] ids list of global IDs of atoms */ -static void addMimicExclusions(t_blocka *excls, - const gmx::ArrayRef ids) +static void addMimicExclusions(t_blocka* excls, const gmx::ArrayRef ids) { - t_blocka inter_excl {}; + t_blocka inter_excl{}; init_blocka(&inter_excl); - size_t n_q = ids.size(); + size_t n_q = ids.size(); inter_excl.nr = excls->nr; inter_excl.nra = n_q * n_q; @@ -1023,9 +999,9 @@ static void addMimicExclusions(t_blocka *excls, { continue; } - size_t index = n_q * i; - inter_excl.index[ids[i]] = index; - prev_index = index + n_q; + size_t index = n_q * i; + inter_excl.index[ids[i]] = index; + prev_index = index + n_q; for (size_t j = 0; j < n_q; ++j) { inter_excl.a[n_q * i + j] = ids[j]; @@ -1043,25 +1019,21 @@ static void addMimicExclusions(t_blocka *excls, gmx::mergeExclusions(excls, qmexcl2); } -static void gen_local_top(const gmx_mtop_t &mtop, - bool freeEnergyInteractionsAtEnd, - bool bMergeConstr, - gmx_localtop_t *top) +static void gen_local_top(const gmx_mtop_t& mtop, + bool freeEnergyInteractionsAtEnd, + bool bMergeConstr, + gmx_localtop_t* top) { copyAtomtypesFromMtop(mtop, &top->atomtypes); copyIdefFromMtop(mtop, &top->idef, freeEnergyInteractionsAtEnd, bMergeConstr); copyExclsFromMtop(mtop, &top->excls); if (!mtop.intermolecularExclusionGroup.empty()) { - addMimicExclusions(&top->excls, - mtop.intermolecularExclusionGroup); + addMimicExclusions(&top->excls, mtop.intermolecularExclusionGroup); } } -void -gmx_mtop_generate_local_top(const gmx_mtop_t &mtop, - gmx_localtop_t *top, - bool freeEnergyInteractionsAtEnd) +void gmx_mtop_generate_local_top(const gmx_mtop_t& mtop, gmx_localtop_t* top, bool freeEnergyInteractionsAtEnd) { gen_local_top(mtop, freeEnergyInteractionsAtEnd, true, top); } @@ -1071,29 +1043,28 @@ gmx_mtop_generate_local_top(const gmx_mtop_t &mtop, * \param[in] mtop The global topology * \param[out] index Array of size nr. of molecules + 1 to be filled with molecule begin/end indices */ -static void fillMoleculeIndices(const gmx_mtop_t &mtop, - gmx::ArrayRef index) +static void fillMoleculeIndices(const gmx_mtop_t& mtop, gmx::ArrayRef index) { int globalAtomIndex = 0; int globalMolIndex = 0; index[globalMolIndex] = globalAtomIndex; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { int numAtomsPerMolecule = mtop.moltype[molb.type].atoms.nr; for (int mol = 0; mol < molb.nmol; mol++) { - globalAtomIndex += numAtomsPerMolecule; - globalMolIndex += 1; - index[globalMolIndex] = globalAtomIndex; + globalAtomIndex += numAtomsPerMolecule; + globalMolIndex += 1; + index[globalMolIndex] = globalAtomIndex; } } } -gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t &mtop) +gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t& mtop) { gmx::RangePartitioning mols; - for (const gmx_molblock_t &molb : mtop.molblock) + for (const gmx_molblock_t& molb : mtop.molblock) { int numAtomsPerMolecule = mtop.moltype[molb.type].atoms.nr; for (int mol = 0; mol < molb.nmol; mol++) @@ -1109,7 +1080,7 @@ gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t &mtop) * * \param[in] mtop The global topology */ -static t_block gmx_mtop_molecules_t_block(const gmx_mtop_t &mtop) +static t_block gmx_mtop_molecules_t_block(const gmx_mtop_t& mtop) { t_block mols; @@ -1122,10 +1093,10 @@ static t_block gmx_mtop_molecules_t_block(const gmx_mtop_t &mtop) return mols; } -static void gen_t_topology(const gmx_mtop_t &mtop, +static void gen_t_topology(const gmx_mtop_t& mtop, bool freeEnergyInteractionsAtEnd, bool bMergeConstr, - t_topology *top) + t_topology* top) { copyAtomtypesFromMtop(mtop, &top->atomtypes); copyIdefFromMtop(mtop, &top->idef, freeEnergyInteractionsAtEnd, bMergeConstr); @@ -1138,9 +1109,9 @@ static void gen_t_topology(const gmx_mtop_t &mtop, top->symtab = mtop.symtab; } -t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop, bool freeMTop) +t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t* mtop, bool freeMTop) { - t_topology top; + t_topology top; gen_t_topology(*mtop, false, false, &top); @@ -1148,19 +1119,19 @@ t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop, bool freeMTop) { // Clear pointers and counts, such that the pointers copied to top // keep pointing to valid data after destroying mtop. - mtop->symtab.symbuf = nullptr; - mtop->symtab.nr = 0; + mtop->symtab.symbuf = nullptr; + mtop->symtab.nr = 0; } return top; } -std::vector get_atom_index(const gmx_mtop_t *mtop) +std::vector get_atom_index(const gmx_mtop_t* mtop) { - std::vector atom_index; + std::vector atom_index; for (const AtomProxy atomP : AtomRange(*mtop)) { - const t_atom &local = atomP.atom(); + const t_atom& local = atomP.atom(); int index = atomP.globalAtomNumber(); if (local.ptype == eptAtom) { @@ -1170,28 +1141,25 @@ std::vector get_atom_index(const gmx_mtop_t *mtop) return atom_index; } -void convertAtomsToMtop(t_symtab *symtab, - char **name, - t_atoms *atoms, - gmx_mtop_t *mtop) +void convertAtomsToMtop(t_symtab* symtab, char** name, t_atoms* atoms, gmx_mtop_t* mtop) { - mtop->symtab = *symtab; + mtop->symtab = *symtab; - mtop->name = name; + mtop->name = name; mtop->moltype.clear(); mtop->moltype.resize(1); - mtop->moltype.back().atoms = *atoms; + mtop->moltype.back().atoms = *atoms; mtop->molblock.resize(1); - mtop->molblock[0].type = 0; - mtop->molblock[0].nmol = 1; + mtop->molblock[0].type = 0; + mtop->molblock[0].nmol = 1; mtop->bIntermolecularInteractions = FALSE; - mtop->natoms = atoms->nr; + mtop->natoms = atoms->nr; - mtop->haveMoleculeIndices = false; + mtop->haveMoleculeIndices = false; gmx_mtop_finalize(mtop); } diff --git a/src/gromacs/topology/mtop_util.h b/src/gromacs/topology/mtop_util.h index 31cd43c4ed..0884c514dc 100644 --- a/src/gromacs/topology/mtop_util.h +++ b/src/gromacs/topology/mtop_util.h @@ -59,62 +59,62 @@ enum struct GmxQmmmMode; * to set some compute intesive variables to avoid * N^2 operations later on. */ -void -gmx_mtop_finalize(gmx_mtop_t *mtop); +void gmx_mtop_finalize(gmx_mtop_t* mtop); /* Counts the number of atoms of each type. State should be 0 for * state A and 1 for state B types. typecount should have at * least mtop->ffparams.atnr elements. */ -void -gmx_mtop_count_atomtypes(const gmx_mtop_t *mtop, int state, int typecount[]); +void gmx_mtop_count_atomtypes(const gmx_mtop_t* mtop, int state, int typecount[]); /*!\brief Returns the total number of molecules in mtop * * \param[in] mtop The global topology */ -int gmx_mtop_num_molecules(const gmx_mtop_t &mtop); +int gmx_mtop_num_molecules(const gmx_mtop_t& mtop); /* Returns the total number of residues in mtop. */ -int gmx_mtop_nres(const gmx_mtop_t *mtop); +int gmx_mtop_nres(const gmx_mtop_t* mtop); class AtomIterator; //! Proxy object returned from AtomIterator class AtomProxy { - public: - //! Default constructor. - AtomProxy(const AtomIterator* it) : it_(it) {} - //! Access current global atom number. - int globalAtomNumber() const; - //! Access current t_atom struct. - const t_atom &atom() const; - //! Access current name of the atom. - const char *atomName() const; - //! Access current name of the residue the atom is in. - const char *residueName() const; - //! Access current residue number. - int residueNumber() const; - //! Access current molecule type. - const gmx_moltype_t &moleculeType() const; - //! Access the position of the current atom in the molecule. - int atomNumberInMol() const; - private: - const AtomIterator* it_; +public: + //! Default constructor. + AtomProxy(const AtomIterator* it) : it_(it) {} + //! Access current global atom number. + int globalAtomNumber() const; + //! Access current t_atom struct. + const t_atom& atom() const; + //! Access current name of the atom. + const char* atomName() const; + //! Access current name of the residue the atom is in. + const char* residueName() const; + //! Access current residue number. + int residueNumber() const; + //! Access current molecule type. + const gmx_moltype_t& moleculeType() const; + //! Access the position of the current atom in the molecule. + int atomNumberInMol() const; + +private: + const AtomIterator* it_; }; //! Wrapper around proxy object to implement operator-> -template +template class ProxyPtr { - public: - //! Construct with proxy object. - ProxyPtr(T t) : t_(t) {} - //! Member of pointer operator. - T* operator->() { return &t_; } - private: - T t_; +public: + //! Construct with proxy object. + ProxyPtr(T t) : t_(t) {} + //! Member of pointer operator. + T* operator->() { return &t_; } + +private: + T t_; }; /*! \brief @@ -122,66 +122,65 @@ class ProxyPtr */ class AtomIterator { - public: - //! Construct from topology and optionalally a global atom number. - explicit AtomIterator(const gmx_mtop_t &mtop, int globalAtomNumber = 0); - - //! Prefix increment. - AtomIterator &operator++(); - //! Postfix increment. - AtomIterator operator++(int); - - //! Equality comparison. - bool operator==(const AtomIterator &o) const; - //! Non-equal comparison. - bool operator!=(const AtomIterator &o) const; - - //! Dereference operator. Returns proxy. - AtomProxy operator*() const { return {this}; } - //! Member of pointer operator. - ProxyPtr operator->() const { return {this}; } - - private: - //! Global topology. - const gmx_mtop_t *mtop_; - //! Current molecule block. - size_t mblock_; - //! The atoms of the current molecule. - const t_atoms *atoms_; - //! The current molecule. - int currentMolecule_; - //! Current highest number for residues. - int highestResidueNumber_; - //! Current local atom number. - int localAtomNumber_; - //! Global current atom number. - int globalAtomNumber_; - - friend class AtomProxy; +public: + //! Construct from topology and optionalally a global atom number. + explicit AtomIterator(const gmx_mtop_t& mtop, int globalAtomNumber = 0); + + //! Prefix increment. + AtomIterator& operator++(); + //! Postfix increment. + AtomIterator operator++(int); + + //! Equality comparison. + bool operator==(const AtomIterator& o) const; + //! Non-equal comparison. + bool operator!=(const AtomIterator& o) const; + + //! Dereference operator. Returns proxy. + AtomProxy operator*() const { return { this }; } + //! Member of pointer operator. + ProxyPtr operator->() const { return { this }; } + +private: + //! Global topology. + const gmx_mtop_t* mtop_; + //! Current molecule block. + size_t mblock_; + //! The atoms of the current molecule. + const t_atoms* atoms_; + //! The current molecule. + int currentMolecule_; + //! Current highest number for residues. + int highestResidueNumber_; + //! Current local atom number. + int localAtomNumber_; + //! Global current atom number. + int globalAtomNumber_; + + friend class AtomProxy; }; //! Range over all atoms of topology. class AtomRange { - public: - //! Default constructor. - explicit AtomRange(const gmx_mtop_t &mtop) : - begin_(mtop), end_(mtop, mtop.natoms) {} - //! Iterator to begin of range. - AtomIterator &begin() { return begin_; } - //! Iterator to end of range. - AtomIterator &end() { return end_; } - private: - AtomIterator begin_, end_; +public: + //! Default constructor. + explicit AtomRange(const gmx_mtop_t& mtop) : begin_(mtop), end_(mtop, mtop.natoms) {} + //! Iterator to begin of range. + AtomIterator& begin() { return begin_; } + //! Iterator to end of range. + AtomIterator& end() { return end_; } + +private: + AtomIterator begin_, end_; }; /* Abstract type for atom loop over atoms in all molecule blocks */ -typedef struct gmx_mtop_atomloop_block *gmx_mtop_atomloop_block_t; +typedef struct gmx_mtop_atomloop_block* gmx_mtop_atomloop_block_t; /* Initialize an atom loop over atoms in all molecule blocks the system. */ -gmx_mtop_atomloop_block_t -gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop); +gmx_mtop_atomloop_block_t gmx_mtop_atomloop_block_init(const gmx_mtop_t* mtop); /* Loop to the next atom. * When not at the end: @@ -196,21 +195,17 @@ gmx_mtop_atomloop_block_init(const gmx_mtop_t *mtop); * ... * } */ -gmx_bool -gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, - const t_atom **atom, int *nmol); +gmx_bool gmx_mtop_atomloop_block_next(gmx_mtop_atomloop_block_t aloop, const t_atom** atom, int* nmol); /* Abstract type for ilist loop over all ilists */ -typedef struct gmx_mtop_ilistloop *gmx_mtop_ilistloop_t; +typedef struct gmx_mtop_ilistloop* gmx_mtop_ilistloop_t; /* Initialize an ilist loop over all molecule types in the system. */ -gmx_mtop_ilistloop_t -gmx_mtop_ilistloop_init(const gmx_mtop_t *mtop); +gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t* mtop); /* Initialize an ilist loop over all molecule types in the system. */ -gmx_mtop_ilistloop_t -gmx_mtop_ilistloop_init(const gmx_mtop_t &mtop); +gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop); /* Loop to the next molecule, * When not at the end: @@ -218,20 +213,17 @@ gmx_mtop_ilistloop_init(const gmx_mtop_t &mtop); * writes the number of molecules for this ilist in *nmol. * When at the end, destroys iloop and returns nullptr. */ -const InteractionLists * -gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, - int *nmol); +const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol); /* Abstract type for ilist loop over all ilists of all molecules */ -typedef struct gmx_mtop_ilistloop_all *gmx_mtop_ilistloop_all_t; +typedef struct gmx_mtop_ilistloop_all* gmx_mtop_ilistloop_all_t; /* Initialize an ilist loop over all molecule types in the system. * Only use this when you really need to loop over all molecules, * i.e. when you use groups which might differ per molecule, * otherwise use gmx_mtop_ilistloop. */ -gmx_mtop_ilistloop_all_t -gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop); +gmx_mtop_ilistloop_all_t gmx_mtop_ilistloop_all_init(const gmx_mtop_t* mtop); /* Loop to the next molecule, * When not at the end: @@ -239,26 +231,20 @@ gmx_mtop_ilistloop_all_init(const gmx_mtop_t *mtop); * writes the atom offset which should be added to iatoms in atnr_offset. * When at the end, destroys iloop and returns nullptr. */ -const InteractionLists * -gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, - int *atnr_offset); +const InteractionLists* gmx_mtop_ilistloop_all_next(gmx_mtop_ilistloop_all_t iloop, int* atnr_offset); /* Returns the total number of interactions in the system of type ftype */ -int -gmx_mtop_ftype_count(const gmx_mtop_t *mtop, int ftype); +int gmx_mtop_ftype_count(const gmx_mtop_t* mtop, int ftype); /* Returns the total number of interactions in the system of type ftype */ -int -gmx_mtop_ftype_count(const gmx_mtop_t &mtop, int ftype); +int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype); /* Returns the total number of interactions in the system with all interaction flags that are set in \p if_flags set */ -int gmx_mtop_interaction_count(const gmx_mtop_t &mtop, - int unsigned if_flags); +int gmx_mtop_interaction_count(const gmx_mtop_t& mtop, int unsigned if_flags); /* Returns a single t_atoms struct for the whole system */ -t_atoms -gmx_mtop_global_atoms(const gmx_mtop_t *mtop); +t_atoms gmx_mtop_global_atoms(const gmx_mtop_t* mtop); /*! \brief @@ -271,10 +257,7 @@ gmx_mtop_global_atoms(const gmx_mtop_t *mtop); * \param[in,out] top New local topology populated from global \p mtop. * \param[in] freeEnergyInteractionsAtEnd If free energy interactions will be sorted. */ -void -gmx_mtop_generate_local_top(const gmx_mtop_t &mtop, - gmx_localtop_t *top, - bool freeEnergyInteractionsAtEnd); +void gmx_mtop_generate_local_top(const gmx_mtop_t& mtop, gmx_localtop_t* top, bool freeEnergyInteractionsAtEnd); /*!\brief Creates and returns a struct with begin/end atom indices of all molecules @@ -284,7 +267,7 @@ gmx_mtop_generate_local_top(const gmx_mtop_t &mtop, * of molecules and atom indices such that molecule m contains atoms a with: * index[m] <= a < index[m+1]. */ -gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t &mtop); +gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t& mtop); /* Converts a gmx_mtop_t struct to t_topology. @@ -296,8 +279,7 @@ gmx::RangePartitioning gmx_mtop_molecules(const gmx_mtop_t &mtop); * If freeMTop == false, mtop and the return value will share some of their * memory, and there is currently no way to consistently free all the memory. */ -t_topology -gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop, bool freeMTop); +t_topology gmx_mtop_t_to_t_topology(gmx_mtop_t* mtop, bool freeMTop); /*! \brief Get vector of atoms indices from topology * @@ -306,7 +288,7 @@ gmx_mtop_t_to_t_topology(gmx_mtop_t *mtop, bool freeMTop); * \param[in] mtop Molecular topology * \returns Vector that will be filled with the atom indices */ -std::vector get_atom_index(const gmx_mtop_t *mtop); +std::vector get_atom_index(const gmx_mtop_t* mtop); /*! \brief Converts a t_atoms struct to an mtop struct * @@ -318,10 +300,6 @@ std::vector get_atom_index(const gmx_mtop_t *mtop); * \param[in] atoms The atoms to convert * \param[out] mtop The molecular topology output containing atoms. */ -void -convertAtomsToMtop(t_symtab *symtab, - char **name, - t_atoms *atoms, - gmx_mtop_t *mtop); +void convertAtomsToMtop(t_symtab* symtab, char** name, t_atoms* atoms, gmx_mtop_t* mtop); #endif diff --git a/src/gromacs/topology/residuetypes.cpp b/src/gromacs/topology/residuetypes.cpp index 8387f8fe33..4c2577499b 100644 --- a/src/gromacs/topology/residuetypes.cpp +++ b/src/gromacs/topology/residuetypes.cpp @@ -58,9 +58,11 @@ const std::string c_undefinedResidueType = "Other"; struct ResidueTypeEntry { //! Default constructor creates complete object. - ResidueTypeEntry(const std::string &rName, const std::string &rType) - : residueName(rName), residueType(rType) - {} + ResidueTypeEntry(const std::string& rName, const std::string& rType) : + residueName(rName), + residueType(rType) + { + } //! Name of the residue in the entry. std::string residueName; //! Type of the residue in the entry. @@ -70,18 +72,17 @@ struct ResidueTypeEntry //! Implementation detail for ResidueTypes class ResidueType::Impl { - public: - //! Storage object for entries. - std::vector entry; +public: + //! Storage object for entries. + std::vector entry; }; -ResidueType::ResidueType() - : impl_(new Impl) +ResidueType::ResidueType() : impl_(new Impl) { - char line[STRLEN]; - char resname[STRLEN], restype[STRLEN], dum[STRLEN]; + char line[STRLEN]; + char resname[STRLEN], restype[STRLEN], dum[STRLEN]; - gmx::FilePtr db = gmx::openLibraryFile("residuetypes.dat"); + gmx::FilePtr db = gmx::openLibraryFile("residuetypes.dat"); while (get_a_line(db.get(), line, STRLEN)) { @@ -91,16 +92,16 @@ ResidueType::ResidueType() { if (sscanf(line, "%1000s %1000s %1000s", resname, restype, dum) != 2) { - gmx_fatal(FARGS, "Incorrect number of columns (2 expected) for line in residuetypes.dat "); + gmx_fatal( + FARGS, + "Incorrect number of columns (2 expected) for line in residuetypes.dat "); } addResidue(resname, restype); } } } -ResidueType::~ResidueType() -{ -} +ResidueType::~ResidueType() {} /*! \brief * Return an optional const iterator to a residue entry that matches the given name. @@ -110,26 +111,29 @@ ResidueType::~ResidueType() * \returns An optional iterator to the residue entry that was found. */ static gmx::compat::optional::const_iterator> -findResidueEntryWithName(gmx::ArrayRef entries, const std::string &residueName) +findResidueEntryWithName(gmx::ArrayRef entries, const std::string& residueName) { - auto foundIt = std::find_if(entries.begin(), entries.end(), - [&residueName](const ResidueTypeEntry &old) - { return gmx::equalCaseInsensitive(residueName, old.residueName); }); + auto foundIt = + std::find_if(entries.begin(), entries.end(), [&residueName](const ResidueTypeEntry& old) { + return gmx::equalCaseInsensitive(residueName, old.residueName); + }); return (foundIt != entries.end()) ? gmx::compat::make_optional(foundIt) : gmx::compat::nullopt; } -bool ResidueType::nameIndexedInResidueTypes(const std::string &residueName) +bool ResidueType::nameIndexedInResidueTypes(const std::string& residueName) { return findResidueEntryWithName(impl_->entry, residueName).has_value(); } -void ResidueType::addResidue(const std::string &residueName, const std::string &residueType) +void ResidueType::addResidue(const std::string& residueName, const std::string& residueType) { if (auto foundIt = findResidueEntryWithName(impl_->entry, residueName)) { if (!gmx::equalCaseInsensitive((*foundIt)->residueType, residueType)) { - fprintf(stderr, "Warning: Residue '%s' already present with type '%s' in database, ignoring new type '%s'.\n", + fprintf(stderr, + "Warning: Residue '%s' already present with type '%s' in database, ignoring " + "new type '%s'.\n", residueName.c_str(), (*foundIt)->residueType.c_str(), residueType.c_str()); } } @@ -139,7 +143,7 @@ void ResidueType::addResidue(const std::string &residueName, const std::string & } } -bool ResidueType::namedResidueHasType(const std::string &residueName, const std::string &residueType) +bool ResidueType::namedResidueHasType(const std::string& residueName, const std::string& residueType) { auto foundIt = findResidueEntryWithName(impl_->entry, residueName); return foundIt ? gmx::equalCaseInsensitive(residueType, (*foundIt)->residueType) : false; @@ -150,10 +154,10 @@ int ResidueType::numberOfEntries() const return impl_->entry.size(); } -int ResidueType::indexFromResidueName(const std::string &residueName) const +int ResidueType::indexFromResidueName(const std::string& residueName) const { gmx::ArrayRef temp(impl_->entry); - auto foundIt = findResidueEntryWithName(temp, residueName); + auto foundIt = findResidueEntryWithName(temp, residueName); return foundIt ? std::distance(temp.begin(), *foundIt) : -1; } @@ -169,15 +173,13 @@ std::string ResidueType::nameFromResidueIndex(int index) const } } -std::string -ResidueType::typeOfNamedDatabaseResidue(const std::string &residueName) +std::string ResidueType::typeOfNamedDatabaseResidue(const std::string& residueName) { auto foundIt = findResidueEntryWithName(impl_->entry, residueName); return foundIt ? (*foundIt)->residueType : c_undefinedResidueType; } -gmx::compat::optional -ResidueType::optionalTypeOfNamedDatabaseResidue(const std::string &residueName) +gmx::compat::optional ResidueType::optionalTypeOfNamedDatabaseResidue(const std::string& residueName) { auto foundIt = findResidueEntryWithName(impl_->entry, residueName); return foundIt ? gmx::compat::make_optional((*foundIt)->residueType) : gmx::compat::nullopt; diff --git a/src/gromacs/topology/residuetypes.h b/src/gromacs/topology/residuetypes.h index afadef8610..588617502f 100644 --- a/src/gromacs/topology/residuetypes.h +++ b/src/gromacs/topology/residuetypes.h @@ -45,75 +45,73 @@ struct ResidueTypeEntry; class ResidueType { - public: - //! Default constructor. - ResidueType(); - //! Default destructor. - ~ResidueType(); +public: + //! Default constructor. + ResidueType(); + //! Default destructor. + ~ResidueType(); - //! Get handle to underlying residue type data. - ResidueTypeEntry *ResidueTypes(); + //! Get handle to underlying residue type data. + ResidueTypeEntry* ResidueTypes(); - //! Get number of entries in ResidueTypes. - int numberOfEntries() const; - /*! \brief - * Return true if residue \p residueName is found or false otherwise. - * - * \param[in] residueName Residue name to search database for. - * \returns true if successful. - */ - bool nameIndexedInResidueTypes(const std::string &residueName); - /*! \brief - * Add entry to ResidueTypes if unique. - * - * \param[in] residueName Name of new residue. - * \param[in] residueType Type of new residue. - */ - void addResidue(const std::string &residueName, const std::string &residueType); - /*! \brief - * Checks if the indicated \p residueName if of \p residueType. - * - * \param[in] residueName Residue that should be checked. - * \param[in] residueType Which ResidueType the residue should have. - * \returns If the check was successful. - */ - bool namedResidueHasType(const std::string &residueName, const std::string &residueType); - /*! \brief - * Get index to entry in ResidueTypes with name \p residueName. - * - * \param[in] residueName Name of the residue being searched. - * \returns The index or -1 if not found. - */ - int indexFromResidueName(const std::string &residueName) const; - /*! \brief - * Get the name of the entry in ResidueTypes with \p index. - * - * \param[in] index Which entry should be returned. - * \returns The name of the entry at \p index, or nullptr. - */ - std::string nameFromResidueIndex(int index) const; - /*! \brief - * Return the residue type if a residue with that name exists, or "Other" - * - * \param[in] residueName Name of the residue to search for. - * \returns The residue type of any matching residue, or "Other" - */ - std::string - typeOfNamedDatabaseResidue(const std::string &residueName); - /*! \brief - * Return an optional residue type if a residue with that name exists - * - * \param[in] residueName Name of the residue to search for. - * \returns An optional containing the residue type of any matching residue - */ - gmx::compat::optional - optionalTypeOfNamedDatabaseResidue(const std::string &residueName); + //! Get number of entries in ResidueTypes. + int numberOfEntries() const; + /*! \brief + * Return true if residue \p residueName is found or false otherwise. + * + * \param[in] residueName Residue name to search database for. + * \returns true if successful. + */ + bool nameIndexedInResidueTypes(const std::string& residueName); + /*! \brief + * Add entry to ResidueTypes if unique. + * + * \param[in] residueName Name of new residue. + * \param[in] residueType Type of new residue. + */ + void addResidue(const std::string& residueName, const std::string& residueType); + /*! \brief + * Checks if the indicated \p residueName if of \p residueType. + * + * \param[in] residueName Residue that should be checked. + * \param[in] residueType Which ResidueType the residue should have. + * \returns If the check was successful. + */ + bool namedResidueHasType(const std::string& residueName, const std::string& residueType); + /*! \brief + * Get index to entry in ResidueTypes with name \p residueName. + * + * \param[in] residueName Name of the residue being searched. + * \returns The index or -1 if not found. + */ + int indexFromResidueName(const std::string& residueName) const; + /*! \brief + * Get the name of the entry in ResidueTypes with \p index. + * + * \param[in] index Which entry should be returned. + * \returns The name of the entry at \p index, or nullptr. + */ + std::string nameFromResidueIndex(int index) const; + /*! \brief + * Return the residue type if a residue with that name exists, or "Other" + * + * \param[in] residueName Name of the residue to search for. + * \returns The residue type of any matching residue, or "Other" + */ + std::string typeOfNamedDatabaseResidue(const std::string& residueName); + /*! \brief + * Return an optional residue type if a residue with that name exists + * + * \param[in] residueName Name of the residue to search for. + * \returns An optional containing the residue type of any matching residue + */ + gmx::compat::optional optionalTypeOfNamedDatabaseResidue(const std::string& residueName); - private: - //! Implementation pointer. - class Impl; +private: + //! Implementation pointer. + class Impl; - gmx::PrivateImplPointer impl_; + gmx::PrivateImplPointer impl_; }; #endif diff --git a/src/gromacs/topology/symtab.cpp b/src/gromacs/topology/symtab.cpp index f51e2a6ba5..ff3d3109d0 100644 --- a/src/gromacs/topology/symtab.cpp +++ b/src/gromacs/topology/symtab.cpp @@ -52,7 +52,7 @@ constexpr int c_trimSize = 1024; constexpr int c_maxBufSize = 5; -static char *trim_string(const char *s, char *out, int maxlen) +static char* trim_string(const char* s, char* out, int maxlen) /* * Returns a pointer to a static area which contains a copy * of s without leading or trailing spaces. Strings are @@ -64,26 +64,22 @@ static char *trim_string(const char *s, char *out, int maxlen) { int len, i; - if (strlen(s) > static_cast(maxlen-1)) + if (strlen(s) > static_cast(maxlen - 1)) { - gmx_fatal(FARGS, "String '%s' (%zu) is longer than buffer (%d).\n", - s, strlen(s), maxlen-1); + gmx_fatal(FARGS, "String '%s' (%zu) is longer than buffer (%d).\n", s, strlen(s), maxlen - 1); } - for (; (*s) == ' '; s++) - { - ; - } + for (; (*s) == ' '; s++) {} for (len = strlen(s); (len > 0); len--) { - if (s[len-1] != ' ') + if (s[len - 1] != ' ') { break; } } if (len >= c_trimSize) { - len = c_trimSize-1; + len = c_trimSize - 1; } for (i = 0; i < len; i++) { @@ -93,32 +89,32 @@ static char *trim_string(const char *s, char *out, int maxlen) return out; } -int lookup_symtab(t_symtab *symtab, char **name) +int lookup_symtab(t_symtab* symtab, char** name) { int base; - t_symbuf *symbuf; + t_symbuf* symbuf; base = 0; symbuf = symtab->symbuf; while (symbuf != nullptr) { - const int index = name-symbuf->buf; - if ( ( index >= 0 ) && ( index < symbuf->bufsize ) ) + const int index = name - symbuf->buf; + if ((index >= 0) && (index < symbuf->bufsize)) { - return index+base; + return index + base; } else { - base += symbuf->bufsize; + base += symbuf->bufsize; symbuf = symbuf->next; } } gmx_fatal(FARGS, "symtab lookup \"%s\" not found", *name); } -char **get_symtab_handle(t_symtab *symtab, int name) +char** get_symtab_handle(t_symtab* symtab, int name) { - t_symbuf *symbuf; + t_symbuf* symbuf; symbuf = symtab->symbuf; while (symbuf != nullptr) @@ -129,16 +125,16 @@ char **get_symtab_handle(t_symtab *symtab, int name) } else { - name -= symbuf->bufsize; + name -= symbuf->bufsize; symbuf = symbuf->next; } } gmx_fatal(FARGS, "symtab get_symtab_handle %d not found", name); } -static t_symbuf *new_symbuf() +static t_symbuf* new_symbuf() { - t_symbuf *symbuf; + t_symbuf* symbuf; snew(symbuf, 1); symbuf->bufsize = c_maxBufSize; @@ -148,11 +144,11 @@ static t_symbuf *new_symbuf() return symbuf; } -static char **enter_buf(t_symtab *symtab, char *name) +static char** enter_buf(t_symtab* symtab, char* name) { - int i; - t_symbuf *symbuf; - gmx_bool bCont; + int i; + t_symbuf* symbuf; + gmx_bool bCont; if (symtab->symbuf == nullptr) { @@ -184,8 +180,7 @@ static char **enter_buf(t_symtab *symtab, char *name) { bCont = FALSE; } - } - while (bCont); + } while (bCont); symbuf->next = new_symbuf(); symbuf = symbuf->next; @@ -195,36 +190,34 @@ static char **enter_buf(t_symtab *symtab, char *name) return &(symbuf->buf[0]); } -char **put_symtab(t_symtab *symtab, const char *name) +char** put_symtab(t_symtab* symtab, const char* name) { char buf[1024]; return enter_buf(symtab, trim_string(name, buf, 1023)); } -void open_symtab(t_symtab *symtab) +void open_symtab(t_symtab* symtab) { symtab->nr = 0; symtab->symbuf = nullptr; } -void close_symtab(t_symtab gmx_unused *symtab) -{ -} +void close_symtab(t_symtab gmx_unused* symtab) {} // TODO this will go away when we use a // std::list>> for t_symtab. -t_symtab *duplicateSymtab(const t_symtab *symtab) +t_symtab* duplicateSymtab(const t_symtab* symtab) { - t_symtab *copySymtab; + t_symtab* copySymtab; snew(copySymtab, 1); open_symtab(copySymtab); - t_symbuf *symbuf = symtab->symbuf; + t_symbuf* symbuf = symtab->symbuf; if (symbuf != nullptr) { snew(copySymtab->symbuf, 1); } - t_symbuf *copySymbuf = copySymtab->symbuf; + t_symbuf* copySymbuf = copySymtab->symbuf; while (symbuf != nullptr) { snew(copySymbuf->buf, symbuf->bufsize); @@ -247,7 +240,7 @@ t_symtab *duplicateSymtab(const t_symtab *symtab) return copySymtab; } -void done_symtab(t_symtab *symtab) +void done_symtab(t_symtab* symtab) { int i; t_symbuf *symbuf, *freeptr; @@ -273,7 +266,7 @@ void done_symtab(t_symtab *symtab) } } -void free_symtab(t_symtab *symtab) +void free_symtab(t_symtab* symtab) { t_symbuf *symbuf, *freeptr; @@ -282,8 +275,8 @@ void free_symtab(t_symtab *symtab) while (symbuf != nullptr) { symtab->nr -= std::min(symbuf->bufsize, symtab->nr); - freeptr = symbuf; - symbuf = symbuf->next; + freeptr = symbuf; + symbuf = symbuf->next; sfree(freeptr); } symtab->symbuf = nullptr; @@ -293,10 +286,10 @@ void free_symtab(t_symtab *symtab) } } -void pr_symtab(FILE *fp, int indent, const char *title, t_symtab *symtab) +void pr_symtab(FILE* fp, int indent, const char* title, t_symtab* symtab) { int i, j, nr; - t_symbuf *symbuf; + t_symbuf* symbuf; if (available(fp, symtab, indent, title)) { @@ -309,9 +302,9 @@ void pr_symtab(FILE *fp, int indent, const char *title, t_symtab *symtab) for (j = 0; (j < symbuf->bufsize) && (j < nr); j++) { pr_indent(fp, indent); - (void) fprintf(fp, "%s[%d]=\"%s\"\n", title, i++, symbuf->buf[j]); + (void)fprintf(fp, "%s[%d]=\"%s\"\n", title, i++, symbuf->buf[j]); } - nr -= j; + nr -= j; symbuf = symbuf->next; } if (nr != 0) diff --git a/src/gromacs/topology/symtab.h b/src/gromacs/topology/symtab.h index 491da9457b..cfb1678e4f 100644 --- a/src/gromacs/topology/symtab.h +++ b/src/gromacs/topology/symtab.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,15 +41,15 @@ typedef struct t_symbuf { - int bufsize; - char **buf; - struct t_symbuf *next; + int bufsize; + char** buf; + struct t_symbuf* next; } t_symbuf; typedef struct t_symtab { int nr; - t_symbuf *symbuf; + t_symbuf* symbuf; } t_symtab; /* @@ -63,11 +63,11 @@ typedef struct t_symtab * back to a text string handle by get_symtab_handle(). */ -void open_symtab(t_symtab *symtab); +void open_symtab(t_symtab* symtab); /* Initialises the symbol table symtab. */ -void close_symtab(t_symtab *symtab); +void close_symtab(t_symtab* symtab); /* Undoes the effect of open_symtab(), after invoking this function, * no value can be added to the symbol table, only values can be * retrieved using get_symtab(). @@ -76,47 +76,47 @@ void close_symtab(t_symtab *symtab); */ /*! \brief Returns a deep copy of \c symtab. */ -t_symtab *duplicateSymtab(const t_symtab *symtab); +t_symtab* duplicateSymtab(const t_symtab* symtab); -void free_symtab(t_symtab *symtab); +void free_symtab(t_symtab* symtab); /* Frees the space allocated by the symbol table itself */ -void done_symtab(t_symtab *symtab); +void done_symtab(t_symtab* symtab); /* Frees the space allocated by the symbol table, including all * entries in it */ -char **put_symtab(t_symtab *symtab, const char *name); +char** put_symtab(t_symtab* symtab, const char* name); /* Enters a string into the symbol table symtab, if it was not * available, a reference to a copy is returned else a reference * to the earlier entered value is returned. Strings are trimmed * of spaces. */ -int lookup_symtab(t_symtab *symtab, char **name); +int lookup_symtab(t_symtab* symtab, char** name); /* Returns a unique handle for **name, without a memory reference. * It is a failure when name cannot be found in the symbol table, * it should be entered before with put_symtab(). */ -char **get_symtab_handle(t_symtab *symtab, int name); +char** get_symtab_handle(t_symtab* symtab, int name); /* Returns a text string handle for name. Name should be a value * returned from lookup_symtab(). So get_symtab_handle() and * lookup_symtab() are inverse functions. */ -long wr_symtab(FILE *fp, t_symtab *symtab); +long wr_symtab(FILE* fp, t_symtab* symtab); /* Writes the symbol table symtab to the file, specified by fp. * The function returns the number of bytes written. */ -long rd_symtab(FILE *fp, t_symtab *symtab); +long rd_symtab(FILE* fp, t_symtab* symtab); /* Reads the symbol table symtab from the file, specified by fp. * This will include allocating the needed space. The function * returns the number of bytes read. The symtab is in the closed * state afterwards, so no strings can be added to it. */ -void pr_symtab(FILE *fp, int indent, const char *title, t_symtab *symtab); +void pr_symtab(FILE* fp, int indent, const char* title, t_symtab* symtab); /* This routine prints out a (human) readable representation of * the symbol table symtab to the file fp. Ident specifies the * number of spaces the text should be indented. Title is used diff --git a/src/gromacs/topology/tests/exclusionblocks.cpp b/src/gromacs/topology/tests/exclusionblocks.cpp index 2fa0d6b92a..ab9f1ad122 100644 --- a/src/gromacs/topology/tests/exclusionblocks.cpp +++ b/src/gromacs/topology/tests/exclusionblocks.cpp @@ -59,10 +59,10 @@ namespace { //! Add a new group to t_blocka -void addGroupToBlocka(t_blocka *b, gmx::ArrayRef indices) +void addGroupToBlocka(t_blocka* b, gmx::ArrayRef indices) { - srenew(b->index, b->nr+2); - srenew(b->a, b->nra+indices.size()); + srenew(b->index, b->nr + 2); + srenew(b->a, b->nra + indices.size()); for (index i = 0; i < indices.ssize(); i++) { b->a[b->nra++] = indices[i]; @@ -74,62 +74,61 @@ void addGroupToBlocka(t_blocka *b, gmx::ArrayRef indices) //! Fill ExclusionBlock with data. int fillExclusionBlock(gmx::ArrayRef b) { - std::vector < std::vector < int>> indices = {{0, 4, 7}, {1, 5, 8, 10}, {2, 6, 9, 11, 12}}; - int nra = 0; + std::vector> indices = { { 0, 4, 7 }, { 1, 5, 8, 10 }, { 2, 6, 9, 11, 12 } }; + int nra = 0; for (index i = 0; i < b.ssize(); i++) { b[i].atomNumber.clear(); - for (const auto &j : indices[i]) + for (const auto& j : indices[i]) { b[i].atomNumber.push_back(j); } - nra += b[i].nra(); + nra += b[i].nra(); } return nra; } //! Fill the t_blocka with some datastructures -void makeTestBlockAData(t_blocka *ba) +void makeTestBlockAData(t_blocka* ba) { init_blocka(ba); - std::vector indices = {12, 11, 9, 6, 2}; + std::vector indices = { 12, 11, 9, 6, 2 }; addGroupToBlocka(ba, indices); - indices = {10, 8, 5, 1}; + indices = { 10, 8, 5, 1 }; addGroupToBlocka(ba, indices); - indices = {7, 4, 0}; + indices = { 7, 4, 0 }; addGroupToBlocka(ba, indices); } class ExclusionBlockTest : public ::testing::Test { - public: - ExclusionBlockTest() - { - const int natom = 3; - makeTestBlockAData(&ba_); - b_.resize(natom); - } - ~ExclusionBlockTest() override - { - done_blocka(&ba_); - } +public: + ExclusionBlockTest() + { + const int natom = 3; + makeTestBlockAData(&ba_); + b_.resize(natom); + } + ~ExclusionBlockTest() override { done_blocka(&ba_); } - void compareBlocks() + void compareBlocks() + { + for (index i = 0; i < ssize(b_); i++) { - for (index i = 0; i < ssize(b_); i++) + int index = ba_.index[i]; + for (int j = 0; j < b_[i].nra(); j++) { - int index = ba_.index[i]; - for (int j = 0; j < b_[i].nra(); j++) - { - int pos = index + j; - EXPECT_EQ(b_[i].atomNumber[j], ba_.a[pos])<< "Block mismatch at " << i << " , " << j << "."; - } + int pos = index + j; + EXPECT_EQ(b_[i].atomNumber[j], ba_.a[pos]) + << "Block mismatch at " << i << " , " << j << "."; } } - protected: - t_blocka ba_; - std::vector b_; + } + +protected: + t_blocka ba_; + std::vector b_; }; TEST_F(ExclusionBlockTest, ConvertBlockAToExclusionBlocks) @@ -140,9 +139,9 @@ TEST_F(ExclusionBlockTest, ConvertBlockAToExclusionBlocks) TEST_F(ExclusionBlockTest, ConvertExclusionBlockToBlocka) { - int nra = fillExclusionBlock(b_); - srenew(ba_.a, nra+1); - srenew(ba_.index, b_.size()+1); + int nra = fillExclusionBlock(b_); + srenew(ba_.a, nra + 1); + srenew(ba_.index, b_.size() + 1); exclusionBlocksToBlocka(b_, &ba_); compareBlocks(); } @@ -153,8 +152,8 @@ TEST_F(ExclusionBlockTest, MergeExclusions) compareBlocks(); } -} // namespace +} // namespace -} // namespace testing +} // namespace testing -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/topology/tests/mtop.cpp b/src/gromacs/topology/tests/mtop.cpp index 72c6dcd7db..f555b46181 100644 --- a/src/gromacs/topology/tests/mtop.cpp +++ b/src/gromacs/topology/tests/mtop.cpp @@ -53,9 +53,9 @@ namespace /*! \brief Initializes a basic topology with 9 atoms with settle*/ void createBasicTop(gmx_mtop_t* mtop) { - gmx_moltype_t moltype; + gmx_moltype_t moltype; moltype.atoms.nr = NRAL(F_SETTLE); - std::vector &iatoms = moltype.ilist[F_SETTLE].iatoms; + std::vector& iatoms = moltype.ilist[F_SETTLE].iatoms; const int settleType = 0; iatoms.push_back(settleType); iatoms.push_back(0); @@ -74,7 +74,7 @@ TEST(MtopTest, RangeBasedLoop) { gmx_mtop_t mtop; createBasicTop(&mtop); - int count = 0; + int count = 0; for (const AtomProxy atomP : AtomRange(mtop)) { EXPECT_EQ(atomP.globalAtomNumber(), count); @@ -85,22 +85,22 @@ TEST(MtopTest, RangeBasedLoop) TEST(MtopTest, Operators) { - gmx_mtop_t mtop; + gmx_mtop_t mtop; createBasicTop(&mtop); AtomIterator it(mtop); AtomIterator otherIt(mtop); EXPECT_EQ((*it).globalAtomNumber(), 0); EXPECT_EQ(it->globalAtomNumber(), 0); - EXPECT_TRUE (it == otherIt); + EXPECT_TRUE(it == otherIt); EXPECT_FALSE(it != otherIt); ++it; EXPECT_EQ(it->globalAtomNumber(), 1); it++; EXPECT_EQ(it->globalAtomNumber(), 2); - EXPECT_TRUE (it != otherIt); + EXPECT_TRUE(it != otherIt); EXPECT_FALSE(it == otherIt); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/topology/tests/symtab.cpp b/src/gromacs/topology/tests/symtab.cpp index a65ba0c406..301685fdcf 100644 --- a/src/gromacs/topology/tests/symtab.cpp +++ b/src/gromacs/topology/tests/symtab.cpp @@ -62,45 +62,42 @@ namespace class SymtabTest : public ::testing::Test { - public: - SymtabTest() - { - open_symtab(&symtab_); - } - ~SymtabTest() override - { - done_symtab(&symtab_); - EXPECT_EQ(symtab_.nr, 0); - EXPECT_EQ(symtab_.symbuf, nullptr); - } +public: + SymtabTest() { open_symtab(&symtab_); } + ~SymtabTest() override + { + done_symtab(&symtab_); + EXPECT_EQ(symtab_.nr, 0); + EXPECT_EQ(symtab_.symbuf, nullptr); + } - //! Get handle to symbol table. - t_symtab *symtab() { return &symtab_; } - //! Dump symtab. Similar to pr_symtab function. - void dumpSymtab(); + //! Get handle to symbol table. + t_symtab* symtab() { return &symtab_; } + //! Dump symtab. Similar to pr_symtab function. + void dumpSymtab(); - private: - //! Get reference checker using lazy initialization - TestReferenceChecker *checker() +private: + //! Get reference checker using lazy initialization + TestReferenceChecker* checker() + { + if (!checker_) { - if (!checker_) - { - checker_ = std::make_unique(data_.rootChecker()); - } - return checker_.get(); + checker_ = std::make_unique(data_.rootChecker()); } - //! The symbol table being tested. - t_symtab symtab_; - //! Handler for reference data. - TestReferenceData data_; - //! Handler for checking reference data. - std::unique_ptr checker_; + return checker_.get(); + } + //! The symbol table being tested. + t_symtab symtab_; + //! Handler for reference data. + TestReferenceData data_; + //! Handler for checking reference data. + std::unique_ptr checker_; }; void SymtabTest::dumpSymtab() { int nr = symtab_.nr; - t_symbuf *symbuf = symtab_.symbuf; + t_symbuf* symbuf = symtab_.symbuf; std::vector symtabDump; int pos = 0; while (symbuf != nullptr) @@ -110,7 +107,7 @@ void SymtabTest::dumpSymtab() { symtabDump.emplace_back(formatString("Symtab[%d]=\"%s\"", pos++, symbuf->buf[i])); } - nr -= i; + nr -= i; symbuf = symbuf->next; } checker()->checkSequence(symtabDump.begin(), symtabDump.end(), "Complete dump of SymbolTable"); @@ -124,7 +121,7 @@ void SymtabTest::dumpSymtab() * \param[in] index Index into symtab corresponding to an entry. * \returns Whether to \p symbol and the entry returned by \p index are the same pointer. */ -bool entriesAreEqual(t_symtab *symtab, char **symbol, int index) +bool entriesAreEqual(t_symtab* symtab, char** symbol, int index) { return symbol == get_symtab_handle(symtab, index); } @@ -138,7 +135,7 @@ bool entriesAreEqual(t_symtab *symtab, char **symbol, int index) * \param[in] symtab Symbol table that contains the entries. * \param[in] symbol The entry obtained from placing a string in the symbol table. */ -void compareSymtabLookupAndHandle(t_symtab *symtab, char **symbol) +void compareSymtabLookupAndHandle(t_symtab* symtab, char** symbol) { ASSERT_NE(symtab->symbuf, nullptr); auto index = lookup_symtab(symtab, symbol); @@ -155,10 +152,7 @@ void compareSymtabLookupAndHandle(t_symtab *symtab, char **symbol) * \param[in] otherSymbol Other handle from obtained from separate string deposit. * \param[in] expectedOutcome If the handles should result in equal entries or not. */ -void compareDifferentHandles(t_symtab *symtab, - char **firstSymbol, - char **otherSymbol, - bool expectedOutcome) +void compareDifferentHandles(t_symtab* symtab, char** firstSymbol, char** otherSymbol, bool expectedOutcome) { ASSERT_NE(symtab->symbuf, nullptr); auto firstIndex = lookup_symtab(symtab, firstSymbol); @@ -228,8 +222,8 @@ TEST_F(SymtabTest, TryToAddDuplicates) TEST_F(SymtabTest, AddLargeNumberOfEntries) { - int numStringsToAdd = 7; // Larger than c_maxBufSize limit for size of symbuf. - std::vector symbolsAdded; + int numStringsToAdd = 7; // Larger than c_maxBufSize limit for size of symbuf. + std::vector symbolsAdded; symbolsAdded.reserve(numStringsToAdd); for (int i = 0; i < numStringsToAdd; ++i) { @@ -243,7 +237,7 @@ TEST_F(SymtabTest, AddLargeNumberOfEntries) } // Add something unrelated and check that indices still work afterward. auto foobarSymbol = put_symtab(symtab(), "foobar"); - ASSERT_EQ(numStringsToAdd+1, symtab()->nr); + ASSERT_EQ(numStringsToAdd + 1, symtab()->nr); for (int i = 0; i < numStringsToAdd; ++i) { EXPECT_STREQ(toString(i).c_str(), *symbolsAdded[i]); @@ -257,9 +251,9 @@ TEST_F(SymtabTest, AddLargeNumberOfEntries) TEST_F(SymtabTest, NoDuplicatesInLargeTable) { - int halfOfStringsToAdd = 7; // Larger than c_maxBufSize limit for size of symbuf. - int totalNumStringsToAdd = 2*halfOfStringsToAdd; - std::vector symbolsAdded; + int halfOfStringsToAdd = 7; // Larger than c_maxBufSize limit for size of symbuf. + int totalNumStringsToAdd = 2 * halfOfStringsToAdd; + std::vector symbolsAdded; symbolsAdded.reserve(halfOfStringsToAdd); for (int i = 0; i < halfOfStringsToAdd; ++i) { @@ -269,7 +263,7 @@ TEST_F(SymtabTest, NoDuplicatesInLargeTable) // We now try to mess around in the symtab. auto bazSymbol = put_symtab(symtab(), "baz"); - ASSERT_EQ(halfOfStringsToAdd+1, symtab()->nr); + ASSERT_EQ(halfOfStringsToAdd + 1, symtab()->nr); compareSymtabLookupAndHandle(symtab(), bazSymbol); // Now try to add more symbols, also including those that are already there. @@ -277,13 +271,13 @@ TEST_F(SymtabTest, NoDuplicatesInLargeTable) { symbolsAdded.push_back(put_symtab(symtab(), toString(i).c_str())); } - ASSERT_EQ(totalNumStringsToAdd+1, symtab()->nr); + ASSERT_EQ(totalNumStringsToAdd + 1, symtab()->nr); //! Check that entries that should be equal are, and new ones are not. for (int i = 0; i < halfOfStringsToAdd; i++) { - compareDifferentHandles(symtab(), symbolsAdded[i], symbolsAdded[halfOfStringsToAdd+i], true); - compareDifferentHandles(symtab(), symbolsAdded[i], symbolsAdded[2*halfOfStringsToAdd+i], false); + compareDifferentHandles(symtab(), symbolsAdded[i], symbolsAdded[halfOfStringsToAdd + i], true); + compareDifferentHandles(symtab(), symbolsAdded[i], symbolsAdded[2 * halfOfStringsToAdd + i], false); compareDifferentHandles(symtab(), symbolsAdded[i], bazSymbol, false); } compareSymtabLookupAndHandle(symtab(), bazSymbol); diff --git a/src/gromacs/topology/topology.cpp b/src/gromacs/topology/topology.cpp index 17c94f6ef6..3640148744 100644 --- a/src/gromacs/topology/topology.cpp +++ b/src/gromacs/topology/topology.cpp @@ -54,27 +54,17 @@ #include "gromacs/utility/strconvert.h" #include "gromacs/utility/txtdump.h" -static gmx::EnumerationArray -c_simulationAtomGroupTypeShortNames - = { { - "T-Coupling", - "Energy Mon.", - "Acceleration", - "Freeze", - "User1", - "User2", - "VCM", - "Compressed X", - "Or. Res. Fit", - "QMMM" - } }; - -const char *shortName(SimulationAtomGroupType type) +static gmx::EnumerationArray c_simulationAtomGroupTypeShortNames = { + { "T-Coupling", "Energy Mon.", "Acceleration", "Freeze", "User1", "User2", "VCM", + "Compressed X", "Or. Res. Fit", "QMMM" } +}; + +const char* shortName(SimulationAtomGroupType type) { return c_simulationAtomGroupTypeShortNames[type]; } -void init_top(t_topology *top) +void init_top(t_topology* top) { top->name = nullptr; init_idef(&top->idef); @@ -86,9 +76,7 @@ void init_top(t_topology *top) } -gmx_moltype_t::gmx_moltype_t() : - name(nullptr), - excls() +gmx_moltype_t::gmx_moltype_t() : name(nullptr), excls() { init_t_atoms(&atoms, 0, FALSE); } @@ -114,7 +102,7 @@ gmx_mtop_t::~gmx_mtop_t() done_atomtypes(&atomtypes); } -void done_top(t_topology *top) +void done_top(t_topology* top) { done_idef(&top->idef); done_atom(&(top->atoms)); @@ -127,7 +115,7 @@ void done_top(t_topology *top) done_blocka(&(top->excls)); } -void done_top_mtop(t_topology *top, gmx_mtop_t *mtop) +void done_top_mtop(t_topology* top, gmx_mtop_t* mtop) { if (mtop != nullptr) { @@ -163,7 +151,7 @@ gmx_localtop_t::~gmx_localtop_t() } } -bool gmx_mtop_has_masses(const gmx_mtop_t *mtop) +bool gmx_mtop_has_masses(const gmx_mtop_t* mtop) { if (mtop == nullptr) { @@ -172,7 +160,7 @@ bool gmx_mtop_has_masses(const gmx_mtop_t *mtop) return mtop->moltype.empty() || mtop->moltype[0].atoms.haveMass; } -bool gmx_mtop_has_charges(const gmx_mtop_t *mtop) +bool gmx_mtop_has_charges(const gmx_mtop_t* mtop) { if (mtop == nullptr) { @@ -181,11 +169,11 @@ bool gmx_mtop_has_charges(const gmx_mtop_t *mtop) return mtop->moltype.empty() || mtop->moltype[0].atoms.haveCharge; } -bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t &mtop) +bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t& mtop) { - for (const gmx_moltype_t &moltype : mtop.moltype) + for (const gmx_moltype_t& moltype : mtop.moltype) { - const t_atoms &atoms = moltype.atoms; + const t_atoms& atoms = moltype.atoms; if (atoms.haveBState) { for (int a = 0; a < atoms.nr; a++) @@ -200,7 +188,7 @@ bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t &mtop) return false; } -bool gmx_mtop_has_atomtypes(const gmx_mtop_t *mtop) +bool gmx_mtop_has_atomtypes(const gmx_mtop_t* mtop) { if (mtop == nullptr) { @@ -209,7 +197,7 @@ bool gmx_mtop_has_atomtypes(const gmx_mtop_t *mtop) return mtop->moltype.empty() || mtop->moltype[0].atoms.haveType; } -bool gmx_mtop_has_pdbinfo(const gmx_mtop_t *mtop) +bool gmx_mtop_has_pdbinfo(const gmx_mtop_t* mtop) { if (mtop == nullptr) { @@ -218,16 +206,14 @@ bool gmx_mtop_has_pdbinfo(const gmx_mtop_t *mtop) return mtop->moltype.empty() || mtop->moltype[0].atoms.havePdbInfo; } -static void pr_grps(FILE *fp, - const char *title, - gmx::ArrayRef grps, - char ***grpname) +static void pr_grps(FILE* fp, const char* title, gmx::ArrayRef grps, char*** grpname) { int index = 0; - for (const auto &group : grps) + for (const auto& group : grps) { - fprintf(fp, "%s[%-12s] nr=%zu, name=[", title, c_simulationAtomGroupTypeShortNames[index], group.size()); - for (const auto &entry : group) + fprintf(fp, "%s[%-12s] nr=%zu, name=[", title, c_simulationAtomGroupTypeShortNames[index], + group.size()); + for (const auto& entry : group) { fprintf(fp, " %s", *(grpname[entry])); } @@ -236,19 +222,15 @@ static void pr_grps(FILE *fp, } } -static void pr_groups(FILE *fp, int indent, - const SimulationGroups &groups, - gmx_bool bShowNumbers) +static void pr_groups(FILE* fp, int indent, const SimulationGroups& groups, gmx_bool bShowNumbers) { - pr_grps(fp, - "grp", - groups.groups, - const_cast(groups.groupNames.data())); - pr_strings(fp, indent, "grpname", const_cast(groups.groupNames.data()), groups.groupNames.size(), bShowNumbers); + pr_grps(fp, "grp", groups.groups, const_cast(groups.groupNames.data())); + pr_strings(fp, indent, "grpname", const_cast(groups.groupNames.data()), + groups.groupNames.size(), bShowNumbers); pr_indent(fp, indent); fprintf(fp, "groups "); - for (const auto &group : c_simulationAtomGroupTypeShortNames) + for (const auto& group : c_simulationAtomGroupTypeShortNames) { printf(" %5.5s", group); } @@ -283,18 +265,21 @@ static void pr_groups(FILE *fp, int indent, for (auto group : keysOf(groups.groups)) { fprintf(fp, " %3d ", - !groups.groupNumbers[group].empty() ? - groups.groupNumbers[group][i] : 0); + !groups.groupNumbers[group].empty() ? groups.groupNumbers[group][i] : 0); } fprintf(fp, "\n"); } } } -static void pr_moltype(FILE *fp, int indent, const char *title, - const gmx_moltype_t *molt, int n, - const gmx_ffparams_t *ffparams, - gmx_bool bShowNumbers, gmx_bool bShowParameters) +static void pr_moltype(FILE* fp, + int indent, + const char* title, + const gmx_moltype_t* molt, + int n, + const gmx_ffparams_t* ffparams, + gmx_bool bShowNumbers, + gmx_bool bShowParameters) { int j; @@ -305,20 +290,21 @@ static void pr_moltype(FILE *fp, int indent, const char *title, pr_blocka(fp, indent, "excls", &molt->excls, bShowNumbers); for (j = 0; (j < F_NRE); j++) { - pr_ilist(fp, indent, interaction_function[j].longname, - ffparams->functype.data(), molt->ilist[j], - bShowNumbers, bShowParameters, ffparams->iparams.data()); + pr_ilist(fp, indent, interaction_function[j].longname, ffparams->functype.data(), + molt->ilist[j], bShowNumbers, bShowParameters, ffparams->iparams.data()); } } -static void pr_molblock(FILE *fp, int indent, const char *title, - const gmx_molblock_t *molb, int n, - const std::vector &molt) +static void pr_molblock(FILE* fp, + int indent, + const char* title, + const gmx_molblock_t* molb, + int n, + const std::vector& molt) { indent = pr_title_n(fp, indent, title, n); pr_indent(fp, indent); - fprintf(fp, "%-20s = %d \"%s\"\n", - "moltype", molb->type, *(molt[molb->type].name)); + fprintf(fp, "%-20s = %d \"%s\"\n", "moltype", molb->type, *(molt[molb->type].name)); pr_int(fp, indent, "#molecules", molb->nmol); pr_int(fp, indent, "#posres_xA", molb->posres_xA.size()); if (!molb->posres_xA.empty()) @@ -332,8 +318,7 @@ static void pr_molblock(FILE *fp, int indent, const char *title, } } -void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop, - gmx_bool bShowNumbers, gmx_bool bShowParameters) +void pr_mtop(FILE* fp, int indent, const char* title, const gmx_mtop_t* mtop, gmx_bool bShowNumbers, gmx_bool bShowParameters) { if (available(fp, mtop, indent, title)) { @@ -353,8 +338,7 @@ void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop, for (int j = 0; j < F_NRE; j++) { pr_ilist(fp, indent, interaction_function[j].longname, - mtop->ffparams.functype.data(), - (*mtop->intermolecular_ilist)[j], + mtop->ffparams.functype.data(), (*mtop->intermolecular_ilist)[j], bShowNumbers, bShowParameters, mtop->ffparams.iparams.data()); } } @@ -362,15 +346,14 @@ void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop, pr_atomtypes(fp, indent, "atomtypes", &(mtop->atomtypes), bShowNumbers); for (size_t mt = 0; mt < mtop->moltype.size(); mt++) { - pr_moltype(fp, indent, "moltype", &mtop->moltype[mt], mt, - &mtop->ffparams, bShowNumbers, bShowParameters); + pr_moltype(fp, indent, "moltype", &mtop->moltype[mt], mt, &mtop->ffparams, bShowNumbers, + bShowParameters); } pr_groups(fp, indent, mtop->groups, bShowNumbers); } } -void pr_top(FILE *fp, int indent, const char *title, const t_topology *top, - gmx_bool bShowNumbers, gmx_bool bShowParameters) +void pr_top(FILE* fp, int indent, const char* title, const t_topology* top, gmx_bool bShowNumbers, gmx_bool bShowParameters) { if (available(fp, top, indent, title)) { @@ -387,8 +370,13 @@ void pr_top(FILE *fp, int indent, const char *title, const t_topology *top, } } -static void cmp_iparm(FILE *fp, const char *s, t_functype ft, - const t_iparams &ip1, const t_iparams &ip2, real relativeTolerance, real absoluteTolerance) +static void cmp_iparm(FILE* fp, + const char* s, + t_functype ft, + const t_iparams& ip1, + const t_iparams& ip2, + real relativeTolerance, + real absoluteTolerance) { int i; gmx_bool bDiff; @@ -407,8 +395,7 @@ static void cmp_iparm(FILE *fp, const char *s, t_functype ft, } } -static void cmp_iparm_AB(FILE *fp, const char *s, t_functype ft, - const t_iparams &ip1, real relativeTolerance, real absoluteTolerance) +static void cmp_iparm_AB(FILE* fp, const char* s, t_functype ft, const t_iparams& ip1, real relativeTolerance, real absoluteTolerance) { int nrfpA, nrfpB, p0, i; gmx_bool bDiff; @@ -430,7 +417,8 @@ static void cmp_iparm_AB(FILE *fp, const char *s, t_functype ft, bDiff = FALSE; for (i = 0; i < nrfpB && !bDiff; i++) { - bDiff = !equal_real(ip1.generic.buf[p0+i], ip1.generic.buf[nrfpA+i], relativeTolerance, absoluteTolerance); + bDiff = !equal_real(ip1.generic.buf[p0 + i], ip1.generic.buf[nrfpA + i], relativeTolerance, + absoluteTolerance); } if (bDiff) { @@ -439,7 +427,7 @@ static void cmp_iparm_AB(FILE *fp, const char *s, t_functype ft, } } -static void cmp_cmap(FILE *fp, const gmx_cmap_t *cmap1, const gmx_cmap_t *cmap2, real relativeTolerance, real absoluteTolerance) +static void cmp_cmap(FILE* fp, const gmx_cmap_t* cmap1, const gmx_cmap_t* cmap2, real relativeTolerance, real absoluteTolerance) { int cmap1_ngrid = (cmap1 ? cmap1->cmapdata.size() : 0); int cmap2_ngrid = (cmap2 ? cmap2->cmapdata.size() : 0); @@ -452,8 +440,7 @@ static void cmp_cmap(FILE *fp, const gmx_cmap_t *cmap1, const gmx_cmap_t *cmap2, } cmp_int(fp, "cmap grid_spacing", -1, cmap1->grid_spacing, cmap2->grid_spacing); - if (cmap1->cmapdata.size() == cmap2->cmapdata.size() && - cmap1->grid_spacing == cmap2->grid_spacing) + if (cmap1->cmapdata.size() == cmap2->cmapdata.size() && cmap1->grid_spacing == cmap2->grid_spacing) { for (size_t g = 0; g < cmap1->cmapdata.size(); g++) { @@ -461,15 +448,16 @@ static void cmp_cmap(FILE *fp, const gmx_cmap_t *cmap1, const gmx_cmap_t *cmap2, fprintf(fp, "comparing cmap %zu\n", g); - for (i = 0; i < 4*cmap1->grid_spacing*cmap1->grid_spacing; i++) + for (i = 0; i < 4 * cmap1->grid_spacing * cmap1->grid_spacing; i++) { - cmp_real(fp, "", i, cmap1->cmapdata[g].cmap[i], cmap2->cmapdata[g].cmap[i], relativeTolerance, absoluteTolerance); + cmp_real(fp, "", i, cmap1->cmapdata[g].cmap[i], cmap2->cmapdata[g].cmap[i], + relativeTolerance, absoluteTolerance); } } } } -static void cmp_blocka(FILE *fp, const t_blocka *b1, const t_blocka *b2, const char *s) +static void cmp_blocka(FILE* fp, const t_blocka* b1, const t_blocka* b2, const char* s) { char buf[32]; @@ -480,7 +468,11 @@ static void cmp_blocka(FILE *fp, const t_blocka *b1, const t_blocka *b2, const c cmp_int(fp, buf, -1, b1->nra, b2->nra); } -static void compareFfparams(FILE *fp, const gmx_ffparams_t &ff1, const gmx_ffparams_t &ff2, real relativeTolerance, real absoluteTolerance) +static void compareFfparams(FILE* fp, + const gmx_ffparams_t& ff1, + const gmx_ffparams_t& ff2, + real relativeTolerance, + real absoluteTolerance) { fprintf(fp, "comparing force field parameters\n"); cmp_int(fp, "numTypes", -1, ff1.numTypes(), ff2.numTypes()); @@ -493,12 +485,12 @@ static void compareFfparams(FILE *fp, const gmx_ffparams_t &ff1, const gmx_ffpar std::string buf = gmx::formatString("ffparams->functype[%d]", i); cmp_int(fp, buf.c_str(), i, ff1.functype[i], ff2.functype[i]); buf = gmx::formatString("ffparams->iparams[%d]", i); - cmp_iparm(fp, buf.c_str(), ff1.functype[i], ff1.iparams[i], ff2.iparams[i], relativeTolerance, absoluteTolerance); + cmp_iparm(fp, buf.c_str(), ff1.functype[i], ff1.iparams[i], ff2.iparams[i], + relativeTolerance, absoluteTolerance); } - } -static void compareFfparamAB(FILE *fp, const gmx_ffparams_t &ff1, real relativeTolerance, real absoluteTolerance) +static void compareFfparamAB(FILE* fp, const gmx_ffparams_t& ff1, real relativeTolerance, real absoluteTolerance) { fprintf(fp, "comparing free energy parameters\n"); for (int i = 0; i < ff1.numTypes(); i++) @@ -507,7 +499,7 @@ static void compareFfparamAB(FILE *fp, const gmx_ffparams_t &ff1, real relativeT cmp_iparm_AB(fp, buf.c_str(), ff1.functype[i], ff1.iparams[i], relativeTolerance, absoluteTolerance); } } -static void compareInteractionLists(FILE *fp, const InteractionLists *il1, const InteractionLists *il2) +static void compareInteractionLists(FILE* fp, const InteractionLists* il1, const InteractionLists* il2) { fprintf(fp, "comparing InteractionLists\n"); if ((il1 || il2) && (!il1 || !il2)) @@ -528,7 +520,11 @@ static void compareInteractionLists(FILE *fp, const InteractionLists *il1, const } } -static void compareMoltypes(FILE *fp, gmx::ArrayRef mt1, gmx::ArrayRef mt2, real relativeTolerance, real absoluteTolerance) +static void compareMoltypes(FILE* fp, + gmx::ArrayRef mt1, + gmx::ArrayRef mt2, + real relativeTolerance, + real absoluteTolerance) { fprintf(fp, "comparing molecule types\n"); cmp_int(fp, "moltype size", -1, mt1.size(), mt2.size()); @@ -542,7 +538,7 @@ static void compareMoltypes(FILE *fp, gmx::ArrayRef mt1, gm } } -static void compareMoletypeAB(FILE *fp, gmx::ArrayRef mt1, real relativeTolerance, real absoluteTolerance) +static void compareMoletypeAB(FILE* fp, gmx::ArrayRef mt1, real relativeTolerance, real absoluteTolerance) { fprintf(fp, "comparing free energy molecule types\n"); for (gmx::index i = 0; i < mt1.ssize(); i++) @@ -550,7 +546,9 @@ static void compareMoletypeAB(FILE *fp, gmx::ArrayRef mt1, compareAtoms(fp, &mt1[i].atoms, nullptr, relativeTolerance, absoluteTolerance); } } -static void compareMolblocks(FILE *fp, gmx::ArrayRef mb1, gmx::ArrayRef mb2) +static void compareMolblocks(FILE* fp, + gmx::ArrayRef mb1, + gmx::ArrayRef mb2) { fprintf(fp, "comparing molecule blocks\n"); cmp_int(fp, "molblock size", -1, mb1.size(), mb2.size()); @@ -563,10 +561,9 @@ static void compareMolblocks(FILE *fp, gmx::ArrayRef mb1, cmp_int(fp, "posres_xA size", i, mb1[i].posres_xA.size(), mb2[i].posres_xA.size()); cmp_int(fp, "posres_xB size", i, mb1[i].posres_xB.size(), mb2[i].posres_xB.size()); } - } -static void compareAtomtypes(FILE *fp, const t_atomtypes &at1, const t_atomtypes &at2) +static void compareAtomtypes(FILE* fp, const t_atomtypes& at1, const t_atomtypes& at2) { fprintf(fp, "comparing atomtypes\n"); cmp_int(fp, "nr", -1, at1.nr, at2.nr); @@ -577,7 +574,9 @@ static void compareAtomtypes(FILE *fp, const t_atomtypes &at1, const t_atomtypes } } -static void compareIntermolecularExclusions(FILE *fp, gmx::ArrayRef ime1, gmx::ArrayRef ime2) +static void compareIntermolecularExclusions(FILE* fp, + gmx::ArrayRef ime1, + gmx::ArrayRef ime2) { fprintf(fp, "comparing intermolecular exclusions\n"); cmp_int(fp, "exclusion number", -1, ime1.size(), ime2.size()); @@ -588,7 +587,9 @@ static void compareIntermolecularExclusions(FILE *fp, gmx::ArrayRef i } } -static void compareBlockIndices(FILE *fp, gmx::ArrayRef mbi1, gmx::ArrayRef mbi2) +static void compareBlockIndices(FILE* fp, + gmx::ArrayRef mbi1, + gmx::ArrayRef mbi2) { fprintf(fp, "comparing moleculeBlockIndices\n"); cmp_int(fp, "size", -1, mbi1.size(), mbi2.size()); @@ -603,14 +604,15 @@ static void compareBlockIndices(FILE *fp, gmx::ArrayRef(group), j); - cmp_str(fp, buf.c_str(), -1, - *g0.groupNames[g0.groups[group][j]], + cmp_str(fp, buf.c_str(), -1, *g0.groupNames[g0.groups[group][j]], *g1.groupNames[g1.groups[group][j]]); } } - cmp_int(fp, "ngrpnr", static_cast(group), g0.numberOfGroupNumbers(group), g1.numberOfGroupNumbers(group)); - if (g0.numberOfGroupNumbers(group) == g1.numberOfGroupNumbers(group) && natoms0 == natoms1 && - (!g0.groupNumbers[group].empty() || !g1.groupNumbers[group].empty())) + cmp_int(fp, "ngrpnr", static_cast(group), g0.numberOfGroupNumbers(group), + g1.numberOfGroupNumbers(group)); + if (g0.numberOfGroupNumbers(group) == g1.numberOfGroupNumbers(group) && natoms0 == natoms1 + && (!g0.groupNumbers[group].empty() || !g1.groupNumbers[group].empty())) { for (int j = 0; j < natoms0; j++) { - cmp_int(fp, c_simulationAtomGroupTypeShortNames[group], j, getGroupType(g0, group, j), getGroupType(g1, group, j)); + cmp_int(fp, c_simulationAtomGroupTypeShortNames[group], j, + getGroupType(g0, group, j), getGroupType(g1, group, j)); } } } @@ -664,17 +667,17 @@ void compareAtomGroups(FILE *fp, const SimulationGroups &g0, const SimulationGro */ } -int getGroupType(const SimulationGroups &group, SimulationAtomGroupType type, int atom) +int getGroupType(const SimulationGroups& group, SimulationAtomGroupType type, int atom) { return (group.groupNumbers[type].empty() ? 0 : group.groupNumbers[type][atom]); } -void copy_moltype(const gmx_moltype_t *src, gmx_moltype_t *dst) +void copy_moltype(const gmx_moltype_t* src, gmx_moltype_t* dst) { dst->name = src->name; copy_blocka(&src->excls, &dst->excls); - t_atoms *atomsCopy = copy_t_atoms(&src->atoms); - dst->atoms = *atomsCopy; + t_atoms* atomsCopy = copy_t_atoms(&src->atoms); + dst->atoms = *atomsCopy; sfree(atomsCopy); for (int i = 0; i < F_NRE; ++i) diff --git a/src/gromacs/topology/topology.h b/src/gromacs/topology/topology.h index 5b3fc8b103..710bbbd2d8 100644 --- a/src/gromacs/topology/topology.h +++ b/src/gromacs/topology/topology.h @@ -66,9 +66,9 @@ enum class SimulationAtomGroupType : int }; //! Short strings used for describing atom groups in log and energy files -const char *shortName(SimulationAtomGroupType type); +const char* shortName(SimulationAtomGroupType type); -//const char *shortName(int type); // if necessary +// const char *shortName(int type); // if necessary /*! \brief Molecules type data: atoms, interactions and exclusions */ struct gmx_moltype_t @@ -78,15 +78,15 @@ struct gmx_moltype_t ~gmx_moltype_t(); /*! \brief Deleted copy assignment operator to avoid (not) freeing pointers */ - gmx_moltype_t &operator=(const gmx_moltype_t &) = delete; + gmx_moltype_t& operator=(const gmx_moltype_t&) = delete; /*! \brief Default copy constructor */ - gmx_moltype_t(const gmx_moltype_t &) = default; + gmx_moltype_t(const gmx_moltype_t&) = default; - char **name; /**< Name of the molecule type */ - t_atoms atoms; /**< The atoms in this molecule */ - InteractionLists ilist; /**< Interaction list with local indices */ - t_blocka excls; /**< The exclusions */ + char** name; /**< Name of the molecule type */ + t_atoms atoms; /**< The atoms in this molecule */ + InteractionLists ilist; /**< Interaction list with local indices */ + t_blocka excls; /**< The exclusions */ }; /*! \brief Block of molecules of the same type, used in gmx_mtop_t */ @@ -101,12 +101,12 @@ struct gmx_molblock_t /*! \brief Indices for a gmx_molblock_t, derived from other gmx_mtop_t contents */ struct MoleculeBlockIndices { - int numAtomsPerMolecule; /**< Number of atoms in a molecule in the block */ - int globalAtomStart; /**< Global atom index of the first atom in the block */ - int globalAtomEnd; /**< Global atom index + 1 of the last atom in the block */ - int globalResidueStart; /**< Global residue index of the first residue in the block */ - int residueNumberStart; /**< Residue numbers start from this value if the number of residues per molecule is <= maxres_renum */ - int moleculeIndexStart; /**< Global molecule indexing starts from this value */ + int numAtomsPerMolecule; /**< Number of atoms in a molecule in the block */ + int globalAtomStart; /**< Global atom index of the first atom in the block */ + int globalAtomEnd; /**< Global atom index + 1 of the last atom in the block */ + int globalResidueStart; /**< Global residue index of the first residue in the block */ + int residueNumberStart; /**< Residue numbers start from this value if the number of residues per molecule is <= maxres_renum */ + int moleculeIndexStart; /**< Global molecule indexing starts from this value */ }; /*! \brief Contains the simulation atom groups. @@ -117,18 +117,21 @@ struct MoleculeBlockIndices struct SimulationGroups { //! Groups of particles - gmx::EnumerationArray groups; + gmx::EnumerationArray groups; //! Names of groups, stored as pointer to the entries in the symbol table. - std::vector groupNames; + std::vector groupNames; //! Group numbers for the different SimulationAtomGroupType groups. - gmx::EnumerationArray < SimulationAtomGroupType, std::vector < unsigned char>> groupNumbers; + gmx::EnumerationArray> groupNumbers; /*! \brief * Number of group numbers for a single SimulationGroup. * * \param[in] group Integer value for the group type. */ - int numberOfGroupNumbers(SimulationAtomGroupType group) const { return gmx::ssize(groupNumbers[group]); } + int numberOfGroupNumbers(SimulationAtomGroupType group) const + { + return gmx::ssize(groupNumbers[group]); + } }; /*! \brief @@ -141,7 +144,7 @@ struct SimulationGroups * \param[in] type Type of group to check. * \param[in] atom Atom to check if it has an entry. */ -int getGroupType (const SimulationGroups &group, SimulationAtomGroupType type, int atom); +int getGroupType(const SimulationGroups& group, SimulationAtomGroupType type, int atom); /* The global, complete system topology struct, based on molecule types. * This structure should contain no data that is O(natoms) in memory. @@ -156,38 +159,38 @@ struct gmx_mtop_t //NOLINT(clang-analyzer-optin.performance.Padding) ~gmx_mtop_t(); //! Name of the topology. - char **name = nullptr; + char** name = nullptr; //! Force field parameters used. - gmx_ffparams_t ffparams; + gmx_ffparams_t ffparams; //! Vector of different molecule types. - std::vector moltype; + std::vector moltype; //! Vector of different molecule blocks. - std::vector molblock; + std::vector molblock; //! Are there intermolecular interactions? - bool bIntermolecularInteractions = false; + bool bIntermolecularInteractions = false; /* \brief * List of intermolecular interactions using system wide * atom indices, either NULL or size F_NRE */ - std::unique_ptr intermolecular_ilist = nullptr; + std::unique_ptr intermolecular_ilist = nullptr; //! Number of global atoms. - int natoms = 0; + int natoms = 0; //! Parameter for residue numbering. - int maxres_renum = 0; + int maxres_renum = 0; //! The maximum residue number in moltype - int maxresnr = -1; + int maxresnr = -1; //! Atomtype properties - t_atomtypes atomtypes; + t_atomtypes atomtypes; //! Groups of atoms for different purposes - SimulationGroups groups; + SimulationGroups groups; //! The symbol table - t_symtab symtab; + t_symtab symtab; //! Tells whether we have valid molecule indices - bool haveMoleculeIndices = false; + bool haveMoleculeIndices = false; /*! \brief List of global atom indices of atoms between which * non-bonded interactions must be excluded. */ - std::vector intermolecularExclusionGroup; + std::vector intermolecularExclusionGroup; /* Derived data below */ //! Indices for each molblock entry for fast lookup of atom properties @@ -207,44 +210,42 @@ struct gmx_localtop_t ~gmx_localtop_t(); //! The interaction function definition - t_idef idef; + t_idef idef; //! Atomtype properties - t_atomtypes atomtypes; + t_atomtypes atomtypes; //! The exclusions - t_blocka excls; + t_blocka excls; //! Flag for domain decomposition so we don't free already freed memory. - bool useInDomainDecomp_ = false; + bool useInDomainDecomp_ = false; }; /* The old topology struct, completely written out, used in analysis tools */ typedef struct t_topology { - char **name; /* Name of the topology */ - t_idef idef; /* The interaction function definition */ - t_atoms atoms; /* The atoms */ - t_atomtypes atomtypes; /* Atomtype properties */ - t_block mols; /* The molecules */ - gmx_bool bIntermolecularInteractions; /* Inter.mol. int. ? */ - t_blocka excls; /* The exclusions */ - t_symtab symtab; /* The symbol table */ + char** name; /* Name of the topology */ + t_idef idef; /* The interaction function definition */ + t_atoms atoms; /* The atoms */ + t_atomtypes atomtypes; /* Atomtype properties */ + t_block mols; /* The molecules */ + gmx_bool bIntermolecularInteractions; /* Inter.mol. int. ? */ + t_blocka excls; /* The exclusions */ + t_symtab symtab; /* The symbol table */ } t_topology; -void init_top(t_topology *top); -void done_top(t_topology *top); +void init_top(t_topology* top); +void done_top(t_topology* top); // Frees both t_topology and gmx_mtop_t when the former has been created from // the latter. -void done_top_mtop(t_topology *top, gmx_mtop_t *mtop); +void done_top_mtop(t_topology* top, gmx_mtop_t* mtop); -bool gmx_mtop_has_masses(const gmx_mtop_t *mtop); -bool gmx_mtop_has_charges(const gmx_mtop_t *mtop); -bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t &mtop); -bool gmx_mtop_has_atomtypes(const gmx_mtop_t *mtop); -bool gmx_mtop_has_pdbinfo(const gmx_mtop_t *mtop); +bool gmx_mtop_has_masses(const gmx_mtop_t* mtop); +bool gmx_mtop_has_charges(const gmx_mtop_t* mtop); +bool gmx_mtop_has_perturbed_charges(const gmx_mtop_t& mtop); +bool gmx_mtop_has_atomtypes(const gmx_mtop_t* mtop); +bool gmx_mtop_has_pdbinfo(const gmx_mtop_t* mtop); -void pr_mtop(FILE *fp, int indent, const char *title, const gmx_mtop_t *mtop, - gmx_bool bShowNumbers, gmx_bool bShowParameters); -void pr_top(FILE *fp, int indent, const char *title, const t_topology *top, - gmx_bool bShowNumbers, gmx_bool bShowParameters); +void pr_mtop(FILE* fp, int indent, const char* title, const gmx_mtop_t* mtop, gmx_bool bShowNumbers, gmx_bool bShowParameters); +void pr_top(FILE* fp, int indent, const char* title, const t_topology* top, gmx_bool bShowNumbers, gmx_bool bShowParameters); /*! \brief Compare two mtop topologies. * @@ -254,7 +255,7 @@ void pr_top(FILE *fp, int indent, const char *title, const t_topology *top, * \param[in] relativeTolerance Relative tolerance for comparison. * \param[in] absoluteTolerance Absolute tolerance for comparison. */ -void compareMtop(FILE *fp, const gmx_mtop_t &mtop1, const gmx_mtop_t &mtop2, real relativeTolerance, real absoluteTolerance); +void compareMtop(FILE* fp, const gmx_mtop_t& mtop1, const gmx_mtop_t& mtop2, real relativeTolerance, real absoluteTolerance); /*! \brief Check perturbation parameters in topology. * @@ -263,7 +264,7 @@ void compareMtop(FILE *fp, const gmx_mtop_t &mtop1, const gmx_mtop_t &mtop2, rea * \param[in] relativeTolerance Relative tolerance for comparison. * \param[in] absoluteTolerance Absolute tolerance for comparison. */ -void compareMtopAB(FILE *fp, const gmx_mtop_t &mtop1, real relativeTolerance, real absoluteTolerance); +void compareMtopAB(FILE* fp, const gmx_mtop_t& mtop1, real relativeTolerance, real absoluteTolerance); /*! \brief Compare groups. * @@ -273,12 +274,11 @@ void compareMtopAB(FILE *fp, const gmx_mtop_t &mtop1, real relativeTolerance, re * \param[in] natoms0 Number of atoms for first group. * \param[in] natoms1 Number of atoms for second group. */ -void compareAtomGroups(FILE *fp, const SimulationGroups &g0, const SimulationGroups &g1, - int natoms0, int natoms1); +void compareAtomGroups(FILE* fp, const SimulationGroups& g0, const SimulationGroups& g1, int natoms0, int natoms1); //! Typedef for gmx_localtop in analysis tools. using ExpandedTopologyPtr = std::unique_ptr; -void copy_moltype(const gmx_moltype_t *src, gmx_moltype_t *dst); +void copy_moltype(const gmx_moltype_t* src, gmx_moltype_t* dst); #endif diff --git a/src/gromacs/topology/topsort.cpp b/src/gromacs/topology/topsort.cpp index 669586f8c9..cf7ed9d356 100644 --- a/src/gromacs/topology/topsort.cpp +++ b/src/gromacs/topology/topsort.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2008, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,7 +46,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static gmx_bool ip_pert(int ftype, const t_iparams *ip) +static gmx_bool ip_pert(int ftype, const t_iparams* ip) { gmx_bool bPert; int i; @@ -64,32 +64,26 @@ static gmx_bool ip_pert(int ftype, const t_iparams *ip) case F_ANGLES: case F_G96ANGLES: case F_IDIHS: - bPert = (ip->harmonic.rA != ip->harmonic.rB || - ip->harmonic.krA != ip->harmonic.krB); + bPert = (ip->harmonic.rA != ip->harmonic.rB || ip->harmonic.krA != ip->harmonic.krB); break; case F_MORSE: - bPert = (ip->morse.b0A != ip->morse.b0B || - ip->morse.cbA != ip->morse.cbB || - ip->morse.betaA != ip->morse.betaB); + bPert = (ip->morse.b0A != ip->morse.b0B || ip->morse.cbA != ip->morse.cbB + || ip->morse.betaA != ip->morse.betaB); break; case F_RESTRBONDS: - bPert = (ip->restraint.lowA != ip->restraint.lowB || - ip->restraint.up1A != ip->restraint.up1B || - ip->restraint.up2A != ip->restraint.up2B || - ip->restraint.kA != ip->restraint.kB); + bPert = (ip->restraint.lowA != ip->restraint.lowB || ip->restraint.up1A != ip->restraint.up1B + || ip->restraint.up2A != ip->restraint.up2B + || ip->restraint.kA != ip->restraint.kB); break; case F_UREY_BRADLEY: - bPert = (ip->u_b.thetaA != ip->u_b.thetaB || - ip->u_b.kthetaA != ip->u_b.kthetaB || - ip->u_b.r13A != ip->u_b.r13B || - ip->u_b.kUBA != ip->u_b.kUBB); + bPert = (ip->u_b.thetaA != ip->u_b.thetaB || ip->u_b.kthetaA != ip->u_b.kthetaB + || ip->u_b.r13A != ip->u_b.r13B || ip->u_b.kUBA != ip->u_b.kUBB); break; case F_PDIHS: case F_PIDIHS: case F_ANGRES: case F_ANGRESZ: - bPert = (ip->pdihs.phiA != ip->pdihs.phiB || - ip->pdihs.cpA != ip->pdihs.cpB); + bPert = (ip->pdihs.phiA != ip->pdihs.phiB || ip->pdihs.cpA != ip->pdihs.cpB); break; case F_RBDIHS: bPert = FALSE; @@ -104,32 +98,25 @@ static gmx_bool ip_pert(int ftype, const t_iparams *ip) case F_TABBONDS: case F_TABBONDSNC: case F_TABANGLES: - case F_TABDIHS: - bPert = (ip->tab.kA != ip->tab.kB); - break; + case F_TABDIHS: bPert = (ip->tab.kA != ip->tab.kB); break; case F_POSRES: bPert = FALSE; for (i = 0; i < DIM; i++) { - if (ip->posres.pos0A[i] != ip->posres.pos0B[i] || - ip->posres.fcA[i] != ip->posres.fcB[i]) + if (ip->posres.pos0A[i] != ip->posres.pos0B[i] || ip->posres.fcA[i] != ip->posres.fcB[i]) { bPert = TRUE; } } break; case F_DIHRES: - bPert = ((ip->dihres.phiA != ip->dihres.phiB) || - (ip->dihres.dphiA != ip->dihres.dphiB) || - (ip->dihres.kfacA != ip->dihres.kfacB)); + bPert = ((ip->dihres.phiA != ip->dihres.phiB) || (ip->dihres.dphiA != ip->dihres.dphiB) + || (ip->dihres.kfacA != ip->dihres.kfacB)); break; case F_LJ14: - bPert = (ip->lj14.c6A != ip->lj14.c6B || - ip->lj14.c12A != ip->lj14.c12B); - break; - case F_CMAP: - bPert = FALSE; + bPert = (ip->lj14.c6A != ip->lj14.c6B || ip->lj14.c12A != ip->lj14.c12B); break; + case F_CMAP: bPert = FALSE; break; case F_RESTRANGLES: case F_RESTRDIHS: case F_CBTDIHS: @@ -143,20 +130,18 @@ static gmx_bool ip_pert(int ftype, const t_iparams *ip) return bPert; } -static gmx_bool ip_q_pert(int ftype, const t_iatom *ia, - const t_iparams *ip, const real *qA, const real *qB) +static gmx_bool ip_q_pert(int ftype, const t_iatom* ia, const t_iparams* ip, const real* qA, const real* qB) { /* 1-4 interactions do not have the charges stored in the iparams list, * so we need a separate check for those. */ - return (ip_pert(ftype, ip+ia[0]) || - (ftype == F_LJ14 && (qA[ia[1]] != qB[ia[1]] || - qA[ia[2]] != qB[ia[2]]))); + return (ip_pert(ftype, ip + ia[0]) + || (ftype == F_LJ14 && (qA[ia[1]] != qB[ia[1]] || qA[ia[2]] != qB[ia[2]]))); } -gmx_bool gmx_mtop_bondeds_free_energy(const gmx_mtop_t *mtop) +gmx_bool gmx_mtop_bondeds_free_energy(const gmx_mtop_t* mtop) { - const gmx_ffparams_t *ffparams = &mtop->ffparams; + const gmx_ffparams_t* ffparams = &mtop->ffparams; /* Loop over all the function types and compare the A/B parameters */ gmx_bool bPert = FALSE; @@ -173,15 +158,14 @@ gmx_bool gmx_mtop_bondeds_free_energy(const gmx_mtop_t *mtop) } /* Check perturbed charges for 1-4 interactions */ - for (const gmx_molblock_t &molb : mtop->molblock) + for (const gmx_molblock_t& molb : mtop->molblock) { - const t_atom *atom = mtop->moltype[molb.type].atoms.atom; - const InteractionList &il = mtop->moltype[molb.type].ilist[F_LJ14]; - gmx::ArrayRef ia = il.iatoms; + const t_atom* atom = mtop->moltype[molb.type].atoms.atom; + const InteractionList& il = mtop->moltype[molb.type].ilist[F_LJ14]; + gmx::ArrayRef ia = il.iatoms; for (int i = 0; i < il.size(); i += 3) { - if (atom[ia[i+1]].q != atom[ia[i+1]].qB || - atom[ia[i+2]].q != atom[ia[i+2]].qB) + if (atom[ia[i + 1]].q != atom[ia[i + 1]].qB || atom[ia[i + 2]].q != atom[ia[i + 2]].qB) { bPert = TRUE; } @@ -191,13 +175,13 @@ gmx_bool gmx_mtop_bondeds_free_energy(const gmx_mtop_t *mtop) return bPert; } -void gmx_sort_ilist_fe(t_idef *idef, const real *qA, const real *qB) +void gmx_sort_ilist_fe(t_idef* idef, const real* qA, const real* qB) { - int ftype, nral, i, ic, ib, a; - t_ilist *ilist; - t_iatom *iatoms; - t_iatom *iabuf; - int iabuf_nalloc; + int ftype, nral, i, ic, ib, a; + t_ilist* ilist; + t_iatom* iatoms; + t_iatom* iabuf; + int iabuf_nalloc; if (qB == nullptr) { @@ -207,7 +191,7 @@ void gmx_sort_ilist_fe(t_idef *idef, const real *qA, const real *qB) iabuf_nalloc = 0; iabuf = nullptr; - const t_iparams *iparams = idef->iparams; + const t_iparams* iparams = idef->iparams; for (ftype = 0; ftype < F_NRE; ftype++) { @@ -222,15 +206,15 @@ void gmx_sort_ilist_fe(t_idef *idef, const real *qA, const real *qB) while (i < ilist->nr) { /* Check if this interaction is perturbed */ - if (ip_q_pert(ftype, iatoms+i, iparams, qA, qB)) + if (ip_q_pert(ftype, iatoms + i, iparams, qA, qB)) { /* Copy to the perturbed buffer */ if (ib + 1 + nral > iabuf_nalloc) { - iabuf_nalloc = over_alloc_large(ib+1+nral); + iabuf_nalloc = over_alloc_large(ib + 1 + nral); srenew(iabuf, iabuf_nalloc); } - for (a = 0; a < 1+nral; a++) + for (a = 0; a < 1 + nral; a++) { iabuf[ib++] = iatoms[i++]; } @@ -238,7 +222,7 @@ void gmx_sort_ilist_fe(t_idef *idef, const real *qA, const real *qB) else { /* Copy in place */ - for (a = 0; a < 1+nral; a++) + for (a = 0; a < 1 + nral; a++) { iatoms[ic++] = iatoms[i++]; } @@ -255,10 +239,8 @@ void gmx_sort_ilist_fe(t_idef *idef, const real *qA, const real *qB) if (debug) { - fprintf(debug, "%s non-pert %d pert %d\n", - interaction_function[ftype].longname, - ilist->nr_nonperturbed, - ilist->nr-ilist->nr_nonperturbed); + fprintf(debug, "%s non-pert %d pert %d\n", interaction_function[ftype].longname, + ilist->nr_nonperturbed, ilist->nr - ilist->nr_nonperturbed); } } } diff --git a/src/gromacs/topology/topsort.h b/src/gromacs/topology/topsort.h index 6d41d1025a..6bc89eb68e 100644 --- a/src/gromacs/topology/topsort.h +++ b/src/gromacs/topology/topsort.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2008,2009,2010,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2008,2009,2010,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,11 +42,11 @@ struct gmx_mtop_t; struct t_idef; /* Returns if there are perturbed bonded interactions */ -gmx_bool gmx_mtop_bondeds_free_energy(const struct gmx_mtop_t *mtop); +gmx_bool gmx_mtop_bondeds_free_energy(const struct gmx_mtop_t* mtop); /* Sort all the bonded ilists in idef to have the perturbed ones at the end * and set nr_nr_nonperturbed in ilist. */ -void gmx_sort_ilist_fe(struct t_idef *idef, const real *qA, const real *qB); +void gmx_sort_ilist_fe(struct t_idef* idef, const real* qA, const real* qB); #endif diff --git a/src/gromacs/trajectory/energyframe.cpp b/src/gromacs/trajectory/energyframe.cpp index 61f38ec827..41be658f4f 100644 --- a/src/gromacs/trajectory/energyframe.cpp +++ b/src/gromacs/trajectory/energyframe.cpp @@ -53,16 +53,17 @@ namespace gmx { -EnergyFrame::EnergyFrame(const t_enxframe &enxframe, - const std::map &indicesOfEnergyFields) - : step_(enxframe.step), time_(enxframe.t) +EnergyFrame::EnergyFrame(const t_enxframe& enxframe, const std::map& indicesOfEnergyFields) : + step_(enxframe.step), + time_(enxframe.t) { - for (auto &index : indicesOfEnergyFields) + for (auto& index : indicesOfEnergyFields) { if (index.second >= enxframe.nre) { - GMX_THROW(InternalError(formatString("Index %d for energy %s not present in energy frame with %d energies", - index.second, index.first.c_str(), enxframe.nre))); + GMX_THROW(InternalError(formatString( + "Index %d for energy %s not present in energy frame with %d energies", + index.second, index.first.c_str(), enxframe.nre))); } values_[index.first] = enxframe.ener[index.second].e; } @@ -73,12 +74,13 @@ std::string EnergyFrame::frameName() const return formatString("Time %f Step %" PRId64, time_, step_); } -const real &EnergyFrame::at(const std::string &name) const +const real& EnergyFrame::at(const std::string& name) const { auto valueIterator = values_.find(name); if (valueIterator == values_.end()) { - GMX_THROW(APIError("Cannot get energy value " + name + " unless previously registered when constructing EnergyFrameReader")); + GMX_THROW(APIError("Cannot get energy value " + name + + " unless previously registered when constructing EnergyFrameReader")); } return valueIterator->second; } @@ -93,9 +95,9 @@ EnergyFrame::MapConstIterator EnergyFrame::end() const return values_.end(); } -EnergyFrame::MapConstIterator EnergyFrame::find(const std::string &key) const +EnergyFrame::MapConstIterator EnergyFrame::find(const std::string& key) const { return values_.find(key); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/trajectory/energyframe.h b/src/gromacs/trajectory/energyframe.h index d99153763b..ce46bdae5b 100644 --- a/src/gromacs/trajectory/energyframe.h +++ b/src/gromacs/trajectory/energyframe.h @@ -48,7 +48,7 @@ struct t_enxblock; struct t_energy { //! The current energy. - real e; + real e; //! The running average of the energy double eav; //! The sum of energies until now. @@ -58,18 +58,18 @@ struct t_energy /* The frames that are read/written */ struct t_enxframe { - double t; /* Timestamp of this frame */ - int64_t step; /* MD step */ - int64_t nsteps; /* The number of steps between frames */ - double dt; /* The MD time step */ - int nsum; /* The number of terms for the sums in ener */ - int nre; /* Number of energies */ - int e_size; /* Size (in bytes) of energies */ - int e_alloc; /* Allocated size (in elements) of ener */ - t_energy *ener; /* The energies */ - int nblock; /* Number of following energy blocks */ - t_enxblock *block; /* The blocks */ - int nblock_alloc; /* The number of blocks allocated */ + double t; /* Timestamp of this frame */ + int64_t step; /* MD step */ + int64_t nsteps; /* The number of steps between frames */ + double dt; /* The MD time step */ + int nsum; /* The number of terms for the sums in ener */ + int nre; /* Number of energies */ + int e_size; /* Size (in bytes) of energies */ + int e_alloc; /* Allocated size (in elements) of ener */ + t_energy* ener; /* The energies */ + int nblock; /* Number of following energy blocks */ + t_enxblock* block; /* The blocks */ + int nblock_alloc; /* The number of blocks allocated */ }; namespace gmx @@ -81,37 +81,37 @@ namespace gmx * The interface of this class is intended to resemble a subset of std::map. */ class EnergyFrame { - public: - //! Convenience type - using MapType = std::map; - //! Convenience type - using MapConstIterator = MapType::const_iterator; - //! Constructor - EnergyFrame(const t_enxframe &enxframe, - const std::map &indicesOfEnergyFields); - /*! \brief Return string that helps users identify this frame, containing time and step number. - * - * \throws std::bad_alloc when out of memory */ - std::string frameName() const; - /*! \brief Return the value read for energy \c name. - * - * \throws APIError if \c name was not registered with EnergyFileReader. */ - const real &at(const std::string &name) const; - //! Return const interator to first element of values. - MapConstIterator begin() const; - //! Return const interator to past the end element of values. - MapConstIterator end() const; - //! Return a const interator to the element with \c key, or end() if not found. - MapConstIterator find(const std::string &key) const; - private: - //! Container for energy values, indexed by name - MapType values_; - //! Step number read from the .edr file frame - std::int64_t step_; - //! Time read from the .edr file frame - double time_; +public: + //! Convenience type + using MapType = std::map; + //! Convenience type + using MapConstIterator = MapType::const_iterator; + //! Constructor + EnergyFrame(const t_enxframe& enxframe, const std::map& indicesOfEnergyFields); + /*! \brief Return string that helps users identify this frame, containing time and step number. + * + * \throws std::bad_alloc when out of memory */ + std::string frameName() const; + /*! \brief Return the value read for energy \c name. + * + * \throws APIError if \c name was not registered with EnergyFileReader. */ + const real& at(const std::string& name) const; + //! Return const interator to first element of values. + MapConstIterator begin() const; + //! Return const interator to past the end element of values. + MapConstIterator end() const; + //! Return a const interator to the element with \c key, or end() if not found. + MapConstIterator find(const std::string& key) const; + +private: + //! Container for energy values, indexed by name + MapType values_; + //! Step number read from the .edr file frame + std::int64_t step_; + //! Time read from the .edr file frame + double time_; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/trajectory/trajectoryframe.cpp b/src/gromacs/trajectory/trajectoryframe.cpp index 54350b28fd..7baabd02a5 100644 --- a/src/gromacs/trajectory/trajectoryframe.cpp +++ b/src/gromacs/trajectory/trajectoryframe.cpp @@ -47,8 +47,7 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2, - gmx_bool bRMSD, real ftol, real abstol) +void comp_frame(FILE* fp, t_trxframe* fr1, t_trxframe* fr2, gmx_bool bRMSD, real ftol, real abstol) { fprintf(fp, "\n"); cmp_int(fp, "not_ok", -1, fr1->not_ok, fr2->not_ok); @@ -92,7 +91,7 @@ void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2, } } -void done_frame(t_trxframe *frame) +void done_frame(t_trxframe* frame) { if (frame->atoms) { @@ -107,12 +106,11 @@ void done_frame(t_trxframe *frame) namespace gmx { -TrajectoryFrame::TrajectoryFrame(const t_trxframe &frame) - : frame_(frame) +TrajectoryFrame::TrajectoryFrame(const t_trxframe& frame) : frame_(frame) { // This would be nicer as an initializer, but once uncrustify is // happy, Doxygen can't parse it. - box_ = {{{{0}}}}; + box_ = { { { { 0 } } } }; if (!frame.bStep) { @@ -158,8 +156,7 @@ ArrayRef TrajectoryFrame::x() const { if (frame_.bX) { - return arrayRefFromArray(reinterpret_cast(frame_.x), - frame_.natoms); + return arrayRefFromArray(reinterpret_cast(frame_.x), frame_.natoms); } else { @@ -171,8 +168,7 @@ ArrayRef TrajectoryFrame::v() const { if (frame_.bV) { - return arrayRefFromArray(reinterpret_cast(frame_.v), - frame_.natoms); + return arrayRefFromArray(reinterpret_cast(frame_.v), frame_.natoms); } else { @@ -184,8 +180,7 @@ ArrayRef TrajectoryFrame::f() const { if (frame_.bF) { - return arrayRefFromArray(reinterpret_cast(frame_.f), - frame_.natoms); + return arrayRefFromArray(reinterpret_cast(frame_.f), frame_.natoms); } else { @@ -198,7 +193,7 @@ bool TrajectoryFrame::hasBox() const return frame_.bBox; } -const BoxMatrix &TrajectoryFrame::box() const +const BoxMatrix& TrajectoryFrame::box() const { return box_; } diff --git a/src/gromacs/trajectory/trajectoryframe.h b/src/gromacs/trajectory/trajectoryframe.h index 65f4fef9ef..93d26dc78d 100644 --- a/src/gromacs/trajectory/trajectoryframe.h +++ b/src/gromacs/trajectory/trajectoryframe.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,41 +53,40 @@ struct t_atoms; -typedef struct t_trxframe // NOLINT (clang-analyzer-optin.performance.Padding) +typedef struct t_trxframe // NOLINT (clang-analyzer-optin.performance.Padding) { - int not_ok; /* integrity flags */ - gmx_bool bDouble; /* Double precision? */ - int natoms; /* number of atoms (atoms, x, v, f, index) */ - gmx_bool bStep; - int64_t step; /* MD step number */ - gmx_bool bTime; - real time; /* time of the frame */ - gmx_bool bLambda; - gmx_bool bFepState; /* does it contain fep_state? */ - real lambda; /* free energy perturbation lambda */ - int fep_state; /* which fep state are we in? */ - gmx_bool bAtoms; - t_atoms *atoms; /* atoms struct (natoms) */ - gmx_bool bPrec; - real prec; /* precision of x, fraction of 1 nm */ - gmx_bool bX; - rvec *x; /* coordinates (natoms) */ - gmx_bool bV; - rvec *v; /* velocities (natoms) */ - gmx_bool bF; - rvec *f; /* forces (natoms) */ - gmx_bool bBox; - matrix box; /* the 3 box vectors */ - gmx_bool bPBC; - int ePBC; /* the type of pbc */ - gmx_bool bIndex; - int *index; /* atom indices of contained coordinates */ + int not_ok; /* integrity flags */ + gmx_bool bDouble; /* Double precision? */ + int natoms; /* number of atoms (atoms, x, v, f, index) */ + gmx_bool bStep; + int64_t step; /* MD step number */ + gmx_bool bTime; + real time; /* time of the frame */ + gmx_bool bLambda; + gmx_bool bFepState; /* does it contain fep_state? */ + real lambda; /* free energy perturbation lambda */ + int fep_state; /* which fep state are we in? */ + gmx_bool bAtoms; + t_atoms* atoms; /* atoms struct (natoms) */ + gmx_bool bPrec; + real prec; /* precision of x, fraction of 1 nm */ + gmx_bool bX; + rvec* x; /* coordinates (natoms) */ + gmx_bool bV; + rvec* v; /* velocities (natoms) */ + gmx_bool bF; + rvec* f; /* forces (natoms) */ + gmx_bool bBox; + matrix box; /* the 3 box vectors */ + gmx_bool bPBC; + int ePBC; /* the type of pbc */ + gmx_bool bIndex; + int* index; /* atom indices of contained coordinates */ } t_trxframe; -void comp_frame(FILE *fp, t_trxframe *fr1, t_trxframe *fr2, - gmx_bool bRMSD, real ftol, real abstol); +void comp_frame(FILE* fp, t_trxframe* fr1, t_trxframe* fr2, gmx_bool bRMSD, real ftol, real abstol); -void done_frame(t_trxframe *frame); +void done_frame(t_trxframe* frame); namespace gmx { @@ -95,7 +94,7 @@ namespace gmx /*!\brief A 3x3 matrix data type useful for simulation boxes * * \todo Implement a full replacement for C-style real[DIM][DIM] */ -using BoxMatrix = std::array , DIM>; +using BoxMatrix = std::array, DIM>; /*! \internal * \brief Contains a valid trajectory frame. @@ -112,37 +111,38 @@ using BoxMatrix = std::array , DIM>; * a field may or may not have content. */ class TrajectoryFrame { - public: - /*! \brief Constructor - * - * \throws APIError If \c frame lacks either step or time. - */ - explicit TrajectoryFrame(const t_trxframe &frame); - /*! \brief Return a string that helps users identify this frame, containing time and step number. - * - * \throws std::bad_alloc when out of memory */ - std::string frameName() const; - //! Step number read from the trajectory file frame. - std::int64_t step() const; - //! Time read from the trajectory file frame. - double time() const; - //! The PBC characteristics of the box. - int pbc() const; - //! Get a view of position coordinates of the frame (which could be empty). - ArrayRef x() const; - //! Get a view of velocity coordinates of the frame (which could be empty). - ArrayRef v() const; - //! Get a view of force coordinates of the frame (which could be empty). - ArrayRef f() const; - //! Return whether the frame has a box. - bool hasBox() const; - //! Return a handle to the frame's box, which is all zero if the frame has no box. - const BoxMatrix &box() const; - private: - //! Handle to trajectory data - const t_trxframe &frame_; - //! Box matrix data from the frame_. - BoxMatrix box_; +public: + /*! \brief Constructor + * + * \throws APIError If \c frame lacks either step or time. + */ + explicit TrajectoryFrame(const t_trxframe& frame); + /*! \brief Return a string that helps users identify this frame, containing time and step number. + * + * \throws std::bad_alloc when out of memory */ + std::string frameName() const; + //! Step number read from the trajectory file frame. + std::int64_t step() const; + //! Time read from the trajectory file frame. + double time() const; + //! The PBC characteristics of the box. + int pbc() const; + //! Get a view of position coordinates of the frame (which could be empty). + ArrayRef x() const; + //! Get a view of velocity coordinates of the frame (which could be empty). + ArrayRef v() const; + //! Get a view of force coordinates of the frame (which could be empty). + ArrayRef f() const; + //! Return whether the frame has a box. + bool hasBox() const; + //! Return a handle to the frame's box, which is all zero if the frame has no box. + const BoxMatrix& box() const; + +private: + //! Handle to trajectory data + const t_trxframe& frame_; + //! Box matrix data from the frame_. + BoxMatrix box_; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/analysismodule.cpp b/src/gromacs/trajectoryanalysis/analysismodule.cpp index 18faf03b4b..06e289a4a4 100644 --- a/src/gromacs/trajectoryanalysis/analysismodule.cpp +++ b/src/gromacs/trajectoryanalysis/analysismodule.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,22 +66,22 @@ namespace gmx */ class TrajectoryAnalysisModule::Impl { - public: - //! Container that associates a data set with its name. - typedef std::map DatasetContainer; - //! Container that associates a AnalysisData object with its name. - typedef std::map AnalysisDatasetContainer; - - //! List of registered data set names. - std::vector datasetNames_; - /*! \brief - * Keeps all registered data sets. - * - * This container also includes datasets from \a analysisDatasets_. - */ - DatasetContainer datasets_; - //! Keeps registered AnalysisData objects. - AnalysisDatasetContainer analysisDatasets_; +public: + //! Container that associates a data set with its name. + typedef std::map DatasetContainer; + //! Container that associates a AnalysisData object with its name. + typedef std::map AnalysisDatasetContainer; + + //! List of registered data set names. + std::vector datasetNames_; + /*! \brief + * Keeps all registered data sets. + * + * This container also includes datasets from \a analysisDatasets_. + */ + DatasetContainer datasets_; + //! Keeps registered AnalysisData objects. + AnalysisDatasetContainer analysisDatasets_; }; /******************************************************************** @@ -94,34 +95,31 @@ class TrajectoryAnalysisModule::Impl */ class TrajectoryAnalysisModuleData::Impl { - public: - //! Container that associates a data handle to its AnalysisData object. - typedef std::map - HandleContainer; - - //! \copydoc TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData() - Impl(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections); - - //! Checks whether the given AnalysisData has been initialized. - bool isInitialized(const AnalysisData &data) const; - - //! Keeps a data handle for each AnalysisData object. - HandleContainer handles_; - //! Stores thread-local selections. - const SelectionCollection &selections_; +public: + //! Container that associates a data handle to its AnalysisData object. + typedef std::map HandleContainer; + + //! \copydoc TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData() + Impl(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections); + + //! Checks whether the given AnalysisData has been initialized. + bool isInitialized(const AnalysisData& data) const; + + //! Keeps a data handle for each AnalysisData object. + HandleContainer handles_; + //! Stores thread-local selections. + const SelectionCollection& selections_; }; -TrajectoryAnalysisModuleData::Impl::Impl( - TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) - : selections_(selections) +TrajectoryAnalysisModuleData::Impl::Impl(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) : + selections_(selections) { TrajectoryAnalysisModule::Impl::AnalysisDatasetContainer::const_iterator i; - for (i = module->impl_->analysisDatasets_.begin(); - i != module->impl_->analysisDatasets_.end(); ++i) + for (i = module->impl_->analysisDatasets_.begin(); i != module->impl_->analysisDatasets_.end(); ++i) { AnalysisDataHandle handle; if (isInitialized(*i->second)) @@ -132,8 +130,7 @@ TrajectoryAnalysisModuleData::Impl::Impl( } } -bool TrajectoryAnalysisModuleData::Impl::isInitialized( - const AnalysisData &data) const +bool TrajectoryAnalysisModuleData::Impl::isInitialized(const AnalysisData& data) const { for (int i = 0; i < data.dataSetCount(); ++i) { @@ -152,18 +149,15 @@ bool TrajectoryAnalysisModuleData::Impl::isInitialized( * TrajectoryAnalysisModuleData */ -TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData( - TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) - : impl_(new Impl(module, opt, selections)) +TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) : + impl_(new Impl(module, opt, selections)) { } -TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData() -{ -} +TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData() {} void TrajectoryAnalysisModuleData::finishDataHandles() @@ -181,28 +175,25 @@ void TrajectoryAnalysisModuleData::finishDataHandles() } -AnalysisDataHandle -TrajectoryAnalysisModuleData::dataHandle(const AnalysisData &data) +AnalysisDataHandle TrajectoryAnalysisModuleData::dataHandle(const AnalysisData& data) { Impl::HandleContainer::const_iterator i = impl_->handles_.find(&data); - GMX_RELEASE_ASSERT(i != impl_->handles_.end(), - "Data handle requested on unknown dataset"); + GMX_RELEASE_ASSERT(i != impl_->handles_.end(), "Data handle requested on unknown dataset"); return i->second; } -Selection TrajectoryAnalysisModuleData::parallelSelection(const Selection &selection) +Selection TrajectoryAnalysisModuleData::parallelSelection(const Selection& selection) { // TODO: Implement properly. return selection; } -SelectionList -TrajectoryAnalysisModuleData::parallelSelections(const SelectionList &selections) +SelectionList TrajectoryAnalysisModuleData::parallelSelections(const SelectionList& selections) { // TODO: Consider an implementation that does not allocate memory every time. - SelectionList newSelections; + SelectionList newSelections; newSelections.reserve(selections.size()); SelectionList::const_iterator i = selections.begin(); for (; i != selections.end(); ++i) @@ -230,79 +221,64 @@ namespace */ class TrajectoryAnalysisModuleDataBasic : public TrajectoryAnalysisModuleData { - public: - /*! \brief - * Initializes thread-local storage for data handles and selections. - * - * \param[in] module Analysis module to use for data objects. - * \param[in] opt Data parallelization options. - * \param[in] selections Thread-local selection collection. - */ - TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections); - - void finish() override; +public: + /*! \brief + * Initializes thread-local storage for data handles and selections. + * + * \param[in] module Analysis module to use for data objects. + * \param[in] opt Data parallelization options. + * \param[in] selections Thread-local selection collection. + */ + TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections); + + void finish() override; }; -TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic( - TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) - : TrajectoryAnalysisModuleData(module, opt, selections) +TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) : + TrajectoryAnalysisModuleData(module, opt, selections) { } -void -TrajectoryAnalysisModuleDataBasic::finish() +void TrajectoryAnalysisModuleDataBasic::finish() { finishDataHandles(); } -} // namespace +} // namespace /******************************************************************** * TrajectoryAnalysisModule */ -TrajectoryAnalysisModule::TrajectoryAnalysisModule() - : impl_(new Impl()) -{ -} +TrajectoryAnalysisModule::TrajectoryAnalysisModule() : impl_(new Impl()) {} -TrajectoryAnalysisModule::~TrajectoryAnalysisModule() -{ -} +TrajectoryAnalysisModule::~TrajectoryAnalysisModule() {} -void TrajectoryAnalysisModule::optionsFinished( - TrajectoryAnalysisSettings * /*settings*/) -{ -} +void TrajectoryAnalysisModule::optionsFinished(TrajectoryAnalysisSettings* /*settings*/) {} -void TrajectoryAnalysisModule::initAfterFirstFrame( - const TrajectoryAnalysisSettings & /*settings*/, - const t_trxframe & /*fr*/) +void TrajectoryAnalysisModule::initAfterFirstFrame(const TrajectoryAnalysisSettings& /*settings*/, + const t_trxframe& /*fr*/) { } -TrajectoryAnalysisModuleDataPointer -TrajectoryAnalysisModule::startFrames(const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) +TrajectoryAnalysisModuleDataPointer TrajectoryAnalysisModule::startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) { - return TrajectoryAnalysisModuleDataPointer( - new TrajectoryAnalysisModuleDataBasic(this, opt, selections)); + return TrajectoryAnalysisModuleDataPointer(new TrajectoryAnalysisModuleDataBasic(this, opt, selections)); } -void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/) -{ -} +void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData* /*pdata*/) {} int TrajectoryAnalysisModule::datasetCount() const @@ -311,27 +287,25 @@ int TrajectoryAnalysisModule::datasetCount() const } -const std::vector &TrajectoryAnalysisModule::datasetNames() const +const std::vector& TrajectoryAnalysisModule::datasetNames() const { return impl_->datasetNames_; } -AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromIndex(int index) const +AbstractAnalysisData& TrajectoryAnalysisModule::datasetFromIndex(int index) const { if (index < 0 || index >= datasetCount()) { GMX_THROW(APIError("Out of range data set index")); } - Impl::DatasetContainer::const_iterator item - = impl_->datasets_.find(impl_->datasetNames_[index]); - GMX_RELEASE_ASSERT(item != impl_->datasets_.end(), - "Inconsistent data set names"); + Impl::DatasetContainer::const_iterator item = impl_->datasets_.find(impl_->datasetNames_[index]); + GMX_RELEASE_ASSERT(item != impl_->datasets_.end(), "Inconsistent data set names"); return *item->second; } -AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromName(const char *name) const +AbstractAnalysisData& TrajectoryAnalysisModule::datasetFromName(const char* name) const { Impl::DatasetContainer::const_iterator item = impl_->datasets_.find(name); if (item == impl_->datasets_.end()) @@ -342,8 +316,7 @@ AbstractAnalysisData &TrajectoryAnalysisModule::datasetFromName(const char *name } -void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data, - const char *name) +void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData* data, const char* name) { GMX_RELEASE_ASSERT(data != nullptr, "Attempting to register NULL data"); // TODO: Strong exception safety should be possible to implement. @@ -354,8 +327,7 @@ void TrajectoryAnalysisModule::registerBasicDataset(AbstractAnalysisData *data, } -void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData *data, - const char *name) +void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData* data, const char* name) { // TODO: Strong exception safety should be possible to implement. registerBasicDataset(data, name); @@ -366,9 +338,7 @@ void TrajectoryAnalysisModule::registerAnalysisDataset(AnalysisData *data, void TrajectoryAnalysisModule::finishFrameSerial(int frameIndex) { Impl::AnalysisDatasetContainer::const_iterator data; - for (data = impl_->analysisDatasets_.begin(); - data != impl_->analysisDatasets_.end(); - ++data) + for (data = impl_->analysisDatasets_.begin(); data != impl_->analysisDatasets_.end(); ++data) { data->second->finishFrameSerial(frameIndex); } diff --git a/src/gromacs/trajectoryanalysis/analysismodule.h b/src/gromacs/trajectoryanalysis/analysismodule.h index e191559f4a..6326b81dc9 100644 --- a/src/gromacs/trajectoryanalysis/analysismodule.h +++ b/src/gromacs/trajectoryanalysis/analysismodule.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -85,101 +85,100 @@ class TrajectoryAnalysisSettings; */ class TrajectoryAnalysisModuleData { - public: - virtual ~TrajectoryAnalysisModuleData(); +public: + virtual ~TrajectoryAnalysisModuleData(); - /*! \brief - * Performs any finishing actions after all frames have been processed. - * - * \throws unspecified Implementation may throw exceptions to indicate - * errors. - * - * This function is called immediately before the destructor, after - * TrajectoryAnalysisModule::finishFrames(). - * Derived classes should implement any final operations that need to - * be done after successful analysis. - * All implementations should call finishDataHandles(). - */ - virtual void finish() = 0; + /*! \brief + * Performs any finishing actions after all frames have been processed. + * + * \throws unspecified Implementation may throw exceptions to indicate + * errors. + * + * This function is called immediately before the destructor, after + * TrajectoryAnalysisModule::finishFrames(). + * Derived classes should implement any final operations that need to + * be done after successful analysis. + * All implementations should call finishDataHandles(). + */ + virtual void finish() = 0; - /*! \brief - * Returns a data handle for a given dataset. - * - * \param[in] data Analysis data object. - * \returns Data handle for \p data stored in this thread-local data. - * - * \p data should have previously been registered with - * TrajectoryAnalysisModule::registerAnalysisDataset(). - * If \p data has zero columns in all data sets, the returned data - * handle is invalid. - * - * Does not throw. - */ - AnalysisDataHandle dataHandle(const AnalysisData &data); - /*! \brief - * Returns a selection that corresponds to the given selection. - * - * \param[in] selection Global selection object. - * \returns Selection object corresponding to this thread-local data. - * - * \p selection is the selection object that was obtained from - * SelectionOption. The return value is the corresponding selection - * in the selection collection with which this data object was - * constructed with. - * - * Does not throw. - */ - Selection parallelSelection(const Selection &selection); - /*! \brief - * Returns a set of selection that corresponds to the given selections. - * - * \throws std::bad_alloc if out of memory. - * - * Works as parallelSelection(), but for a list of selections at once. - * - * \see parallelSelection() - */ - SelectionList parallelSelections(const SelectionList &selections); + /*! \brief + * Returns a data handle for a given dataset. + * + * \param[in] data Analysis data object. + * \returns Data handle for \p data stored in this thread-local data. + * + * \p data should have previously been registered with + * TrajectoryAnalysisModule::registerAnalysisDataset(). + * If \p data has zero columns in all data sets, the returned data + * handle is invalid. + * + * Does not throw. + */ + AnalysisDataHandle dataHandle(const AnalysisData& data); + /*! \brief + * Returns a selection that corresponds to the given selection. + * + * \param[in] selection Global selection object. + * \returns Selection object corresponding to this thread-local data. + * + * \p selection is the selection object that was obtained from + * SelectionOption. The return value is the corresponding selection + * in the selection collection with which this data object was + * constructed with. + * + * Does not throw. + */ + Selection parallelSelection(const Selection& selection); + /*! \brief + * Returns a set of selection that corresponds to the given selections. + * + * \throws std::bad_alloc if out of memory. + * + * Works as parallelSelection(), but for a list of selections at once. + * + * \see parallelSelection() + */ + SelectionList parallelSelections(const SelectionList& selections); - protected: - /*! \brief - * Initializes thread-local storage for data handles and selections. - * - * \param[in] module Analysis module to use for data objects. - * \param[in] opt Data parallelization options. - * \param[in] selections Thread-local selection collection. - * \throws std::bad_alloc if out of memory. - * \throws unspecified Can throw any exception thrown by - * AnalysisData::startData(). - * - * Calls AnalysisData::startData() on all data objects registered with - * TrajectoryAnalysisModule::registerAnalysisDataset() in \p module. - * The handles are accessible through dataHandle(). - */ - TrajectoryAnalysisModuleData(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections); +protected: + /*! \brief + * Initializes thread-local storage for data handles and selections. + * + * \param[in] module Analysis module to use for data objects. + * \param[in] opt Data parallelization options. + * \param[in] selections Thread-local selection collection. + * \throws std::bad_alloc if out of memory. + * \throws unspecified Can throw any exception thrown by + * AnalysisData::startData(). + * + * Calls AnalysisData::startData() on all data objects registered with + * TrajectoryAnalysisModule::registerAnalysisDataset() in \p module. + * The handles are accessible through dataHandle(). + */ + TrajectoryAnalysisModuleData(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections); - /*! \brief - * Calls finishData() on all data handles. - * - * \throws unspecified Can throw any exception thrown by - * AnalysisDataHandle::finishData(). - * - * This function should be called from the implementation of finish() - * in all subclasses. - */ - void finishDataHandles(); + /*! \brief + * Calls finishData() on all data handles. + * + * \throws unspecified Can throw any exception thrown by + * AnalysisDataHandle::finishData(). + * + * This function should be called from the implementation of finish() + * in all subclasses. + */ + void finishDataHandles(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; //! Smart pointer to manage a TrajectoryAnalysisModuleData object. -typedef std::unique_ptr - TrajectoryAnalysisModuleDataPointer; +typedef std::unique_ptr TrajectoryAnalysisModuleDataPointer; /*! \brief * Base class for trajectory analysis modules. @@ -228,276 +227,271 @@ typedef std::unique_ptr */ class TrajectoryAnalysisModule { - public: - virtual ~TrajectoryAnalysisModule(); +public: + virtual ~TrajectoryAnalysisModule(); - /*! \brief - * Initializes options understood by the module. - * - * \param[in,out] options Options object to add the options to. - * \param[in,out] settings Settings to pass to and from the module. - * - * This method is called first after the constructor, and it should - * add options understood by the module to \p options. Output values - * from options (including selections) should be stored in member - * variables. - * - * In addition to initializing the options, this method can also - * provide information about the module's requirements using the - * \p settings object; see TrajectoryAnalysisSettings for more details. - * - * If settings depend on the option values provided by the user, see - * optionsFinished(). - */ - virtual void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) = 0; - /*! \brief - * Called after all option values have been set. - * - * \param[in,out] settings Settings to pass to and from the module. - * - * This method is called after option values have been assigned (but - * interactive selection input has not yet been performed). - * - * If the module needs to change settings that affect topology loading - * (can be done using the \p settings object) or selection - * initialization (can be done using SelectionOptionInfo) based on - * option values, this method has to be overridden. - * - * The default implementation does nothing. - */ - virtual void optionsFinished(TrajectoryAnalysisSettings *settings); - /*! \brief - * Initializes the analysis. - * - * \param[in] settings Settings to pass to and from the module. - * \param[in] top Topology information. - * - * When this function is called, selections have been initialized based - * on user input, and a topology has been loaded if provided by the - * user. For dynamic selections, the selections have been evaluated to - * the largest possible selection, i.e., the selections passed to - * analyzeFrame() are always a subset of the selections provided here. - */ - virtual void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) = 0; - /*! \brief - * Performs additional initialization after reading the first frame. - * - * When this function is called, selections are the same as in - * initAnalysis(), i.e., they have not been evaluated for the first - * frame. - * - * It is necessary to override this method only if the module needs to - * do initialization for which it requires data from the first frame. - * - * The default implementation does nothing. - */ - virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, - const t_trxframe &fr); + /*! \brief + * Initializes options understood by the module. + * + * \param[in,out] options Options object to add the options to. + * \param[in,out] settings Settings to pass to and from the module. + * + * This method is called first after the constructor, and it should + * add options understood by the module to \p options. Output values + * from options (including selections) should be stored in member + * variables. + * + * In addition to initializing the options, this method can also + * provide information about the module's requirements using the + * \p settings object; see TrajectoryAnalysisSettings for more details. + * + * If settings depend on the option values provided by the user, see + * optionsFinished(). + */ + virtual void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) = 0; + /*! \brief + * Called after all option values have been set. + * + * \param[in,out] settings Settings to pass to and from the module. + * + * This method is called after option values have been assigned (but + * interactive selection input has not yet been performed). + * + * If the module needs to change settings that affect topology loading + * (can be done using the \p settings object) or selection + * initialization (can be done using SelectionOptionInfo) based on + * option values, this method has to be overridden. + * + * The default implementation does nothing. + */ + virtual void optionsFinished(TrajectoryAnalysisSettings* settings); + /*! \brief + * Initializes the analysis. + * + * \param[in] settings Settings to pass to and from the module. + * \param[in] top Topology information. + * + * When this function is called, selections have been initialized based + * on user input, and a topology has been loaded if provided by the + * user. For dynamic selections, the selections have been evaluated to + * the largest possible selection, i.e., the selections passed to + * analyzeFrame() are always a subset of the selections provided here. + */ + virtual void initAnalysis(const TrajectoryAnalysisSettings& settings, + const TopologyInformation& top) = 0; + /*! \brief + * Performs additional initialization after reading the first frame. + * + * When this function is called, selections are the same as in + * initAnalysis(), i.e., they have not been evaluated for the first + * frame. + * + * It is necessary to override this method only if the module needs to + * do initialization for which it requires data from the first frame. + * + * The default implementation does nothing. + */ + virtual void initAfterFirstFrame(const TrajectoryAnalysisSettings& settings, const t_trxframe& fr); - /*! \brief - * Starts the analysis of frames. - * - * \param[in] opt Parallel options - * \param[in] selections Frame-local selection collection object. - * \returns Data structure for thread-local data. - * - * This function is necessary only for threaded parallelization. - * It is called once for each thread and should initialize a class that - * contains any required frame-local data in the returned value. - * The default implementation creates a basic data structure that holds - * thread-local data handles for all data objects registered with - * registerAnalysisDataset(), as well as the thread-local selection - * collection. These can be accessed in analyzeFrame() using the - * methods in TrajectoryAnalysisModuleData. - * If other thread-local data is needed, this function should be - * overridden and it should create an instance of a class derived from - * TrajectoryAnalysisModuleData. - * - * \see TrajectoryAnalysisModuleData - */ - virtual TrajectoryAnalysisModuleDataPointer startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections); - /*! \brief - * Analyzes a single frame. - * - * \param[in] frnr Frame number, a zero-based index that - * uniquely identifies the frame. - * \param[in] fr Current frame. - * \param[in] pbc Periodic boundary conditions for \p fr. - * \param[in,out] pdata Data structure for frame-local data. - * - * This method is called once for each frame to be analyzed, and should - * analyze the positions provided in the selections. Data handles and - * selections should be obtained from the \p pdata structure. - * - * For threaded analysis, this method is called asynchronously in - * different threads to analyze different frames. The \p pdata - * structure is one of the structures created with startFrames(), - * but no assumptions should be made about which of these data - * structures is used. It is guaranteed that two instances of - * analyzeFrame() are not running concurrently with the same \p pdata - * data structure. - * Any access to data structures not stored in \p pdata should be - * designed to be thread-safe. - */ - virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) = 0; - /*! \brief - * Finishes the analysis of frames. - * - * \param[in] pdata Data structure for thread-local data. - * - * This method is called once for each call of startFrames(), with the - * data structure returned by the corresponding startFrames(). - * The \p pdata object should be destroyed by the caller after this - * function has been called. - * - * You only need to override this method if you need custom - * operations to combine data from the frame-local data structures - * to get the final result. In such cases, the data should be - * aggregated in this function and stored in a member attribute. - * - * The default implementation does nothing. - * - * \see startFrames() - */ - virtual void finishFrames(TrajectoryAnalysisModuleData *pdata); + /*! \brief + * Starts the analysis of frames. + * + * \param[in] opt Parallel options + * \param[in] selections Frame-local selection collection object. + * \returns Data structure for thread-local data. + * + * This function is necessary only for threaded parallelization. + * It is called once for each thread and should initialize a class that + * contains any required frame-local data in the returned value. + * The default implementation creates a basic data structure that holds + * thread-local data handles for all data objects registered with + * registerAnalysisDataset(), as well as the thread-local selection + * collection. These can be accessed in analyzeFrame() using the + * methods in TrajectoryAnalysisModuleData. + * If other thread-local data is needed, this function should be + * overridden and it should create an instance of a class derived from + * TrajectoryAnalysisModuleData. + * + * \see TrajectoryAnalysisModuleData + */ + virtual TrajectoryAnalysisModuleDataPointer startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections); + /*! \brief + * Analyzes a single frame. + * + * \param[in] frnr Frame number, a zero-based index that + * uniquely identifies the frame. + * \param[in] fr Current frame. + * \param[in] pbc Periodic boundary conditions for \p fr. + * \param[in,out] pdata Data structure for frame-local data. + * + * This method is called once for each frame to be analyzed, and should + * analyze the positions provided in the selections. Data handles and + * selections should be obtained from the \p pdata structure. + * + * For threaded analysis, this method is called asynchronously in + * different threads to analyze different frames. The \p pdata + * structure is one of the structures created with startFrames(), + * but no assumptions should be made about which of these data + * structures is used. It is guaranteed that two instances of + * analyzeFrame() are not running concurrently with the same \p pdata + * data structure. + * Any access to data structures not stored in \p pdata should be + * designed to be thread-safe. + */ + virtual void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) = 0; + /*! \brief + * Finishes the analysis of frames. + * + * \param[in] pdata Data structure for thread-local data. + * + * This method is called once for each call of startFrames(), with the + * data structure returned by the corresponding startFrames(). + * The \p pdata object should be destroyed by the caller after this + * function has been called. + * + * You only need to override this method if you need custom + * operations to combine data from the frame-local data structures + * to get the final result. In such cases, the data should be + * aggregated in this function and stored in a member attribute. + * + * The default implementation does nothing. + * + * \see startFrames() + */ + virtual void finishFrames(TrajectoryAnalysisModuleData* pdata); - /*! \brief - * Postprocesses data after frames have been read. - * - * \param[in] nframes Total number of frames processed. - * - * This function is called after all finishFrames() calls have been - * called. - * \p nframes will equal the number of calls to analyzeFrame() that - * have occurred. - */ - virtual void finishAnalysis(int nframes) = 0; - /*! \brief - * Writes output into files and/or standard output/error. - * - * All output from the module, excluding data written out for each - * frame during analyzeFrame(), should be confined into this function. - * This function is guaranteed to be called only after - * finishAnalysis(). - */ - virtual void writeOutput() = 0; + /*! \brief + * Postprocesses data after frames have been read. + * + * \param[in] nframes Total number of frames processed. + * + * This function is called after all finishFrames() calls have been + * called. + * \p nframes will equal the number of calls to analyzeFrame() that + * have occurred. + */ + virtual void finishAnalysis(int nframes) = 0; + /*! \brief + * Writes output into files and/or standard output/error. + * + * All output from the module, excluding data written out for each + * frame during analyzeFrame(), should be confined into this function. + * This function is guaranteed to be called only after + * finishAnalysis(). + */ + virtual void writeOutput() = 0; - /*! \brief - * Returns the number of datasets provided by the module. - * - * Does not throw. - */ - int datasetCount() const; - /*! \brief - * Returns a vector with the names of datasets provided by the module. - * - * Does not throw. - */ - const std::vector &datasetNames() const; - /*! \brief - * Returns a pointer to the data set \p index. - * - * \param[in] index Data set to query for. - * \returns Reference to the requested data set. - * \throws APIError if \p index is not valid. - * - * \p index should be >= 0 and < datasetCount(). - * - * The return value is not const to allow callers to add modules to the - * data sets. However, the AbstractAnalysisData interface does not - * provide any means to alter the data, so the module does not need to - * care about external modifications. - */ - AbstractAnalysisData &datasetFromIndex(int index) const; - /*! \brief - * Returns a pointer to the data set with name \p name - * - * \param[in] name Data set to query for. - * \returns Reference to the requested data set. - * \throws APIError if \p name is not valid. - * - * \p name should be one of the names returned by datasetNames(). - * - * The return value is not const to allow callers to add modules to the - * data sets. However, the AbstractAnalysisData interface does not - * provide any means to alter the data, so the module does not need to - * care about external modifications. - */ - AbstractAnalysisData &datasetFromName(const char *name) const; - /*! \brief - * Processes data in AnalysisData objects in serial for each frame. - * - * \param[in] frameIndex Index of the frame that has been finished. - * - * This method is called by the framework in order for each frame, - * after the analysis for that frame has been finished. These calls - * always execute in serial and in sequential frame order, even during - * parallel analysis where multiple analyzeFrame() calls may be - * executing concurrently. - * - * \see AnalysisData::finishFrameSerial() - */ - void finishFrameSerial(int frameIndex); + /*! \brief + * Returns the number of datasets provided by the module. + * + * Does not throw. + */ + int datasetCount() const; + /*! \brief + * Returns a vector with the names of datasets provided by the module. + * + * Does not throw. + */ + const std::vector& datasetNames() const; + /*! \brief + * Returns a pointer to the data set \p index. + * + * \param[in] index Data set to query for. + * \returns Reference to the requested data set. + * \throws APIError if \p index is not valid. + * + * \p index should be >= 0 and < datasetCount(). + * + * The return value is not const to allow callers to add modules to the + * data sets. However, the AbstractAnalysisData interface does not + * provide any means to alter the data, so the module does not need to + * care about external modifications. + */ + AbstractAnalysisData& datasetFromIndex(int index) const; + /*! \brief + * Returns a pointer to the data set with name \p name + * + * \param[in] name Data set to query for. + * \returns Reference to the requested data set. + * \throws APIError if \p name is not valid. + * + * \p name should be one of the names returned by datasetNames(). + * + * The return value is not const to allow callers to add modules to the + * data sets. However, the AbstractAnalysisData interface does not + * provide any means to alter the data, so the module does not need to + * care about external modifications. + */ + AbstractAnalysisData& datasetFromName(const char* name) const; + /*! \brief + * Processes data in AnalysisData objects in serial for each frame. + * + * \param[in] frameIndex Index of the frame that has been finished. + * + * This method is called by the framework in order for each frame, + * after the analysis for that frame has been finished. These calls + * always execute in serial and in sequential frame order, even during + * parallel analysis where multiple analyzeFrame() calls may be + * executing concurrently. + * + * \see AnalysisData::finishFrameSerial() + */ + void finishFrameSerial(int frameIndex); - protected: - /*! \brief - * Initializes the dataset registration mechanism. - * - * \throws std::bad_alloc if out of memory. - */ - TrajectoryAnalysisModule(); +protected: + /*! \brief + * Initializes the dataset registration mechanism. + * + * \throws std::bad_alloc if out of memory. + */ + TrajectoryAnalysisModule(); - /*! \brief - * Registers a dataset that exports data. - * - * \param data Data object to register. - * \param[in] name Name to register the dataset with. - * \throws std::bad_alloc if out of memory. - * - * Registers \p data as a dataset that provides output from the - * analysis module. Callers for the module can access the dataset - * with datasetFromName() using \p name as an AbstractAnalysisData - * object. This allows them to add their own data modules to do extra - * processing. - * - * \p name must be unique across all calls within the same - * TrajectoryAnalysisModule instance. - */ - void registerBasicDataset(AbstractAnalysisData *data, const char *name); - /*! \brief - * Registers a parallelized dataset that exports data. - * - * \param data AnalysisData object to register. - * \param[in] name Name to register the dataset with. - * \throws std::bad_alloc if out of memory. - * - * This method works as registerBasicDataset(), but additionally allows - * data handles for \p data to be accessed using - * TrajectoryAnalysisData. - * - * \see registerBasicDataset() - */ - void registerAnalysisDataset(AnalysisData *data, const char *name); + /*! \brief + * Registers a dataset that exports data. + * + * \param data Data object to register. + * \param[in] name Name to register the dataset with. + * \throws std::bad_alloc if out of memory. + * + * Registers \p data as a dataset that provides output from the + * analysis module. Callers for the module can access the dataset + * with datasetFromName() using \p name as an AbstractAnalysisData + * object. This allows them to add their own data modules to do extra + * processing. + * + * \p name must be unique across all calls within the same + * TrajectoryAnalysisModule instance. + */ + void registerBasicDataset(AbstractAnalysisData* data, const char* name); + /*! \brief + * Registers a parallelized dataset that exports data. + * + * \param data AnalysisData object to register. + * \param[in] name Name to register the dataset with. + * \throws std::bad_alloc if out of memory. + * + * This method works as registerBasicDataset(), but additionally allows + * data handles for \p data to be accessed using + * TrajectoryAnalysisData. + * + * \see registerBasicDataset() + */ + void registerAnalysisDataset(AnalysisData* data, const char* name); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; - /*! \brief - * Needed to access the registered analysis data sets. - */ - friend class TrajectoryAnalysisModuleData; + /*! \brief + * Needed to access the registered analysis data sets. + */ + friend class TrajectoryAnalysisModuleData; }; //! Smart pointer to manage a TrajectoryAnalysisModule. -typedef std::unique_ptr - TrajectoryAnalysisModulePointer; +typedef std::unique_ptr TrajectoryAnalysisModulePointer; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/analysissettings.cpp b/src/gromacs/trajectoryanalysis/analysissettings.cpp index 5e3baaf465..6cd3ffc880 100644 --- a/src/gromacs/trajectoryanalysis/analysissettings.cpp +++ b/src/gromacs/trajectoryanalysis/analysissettings.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,83 +59,70 @@ namespace gmx * TrajectoryAnalysisSettings */ -TrajectoryAnalysisSettings::TrajectoryAnalysisSettings() - : impl_(new Impl) +TrajectoryAnalysisSettings::TrajectoryAnalysisSettings() : impl_(new Impl) { impl_->frflags |= TRX_NEED_X; } -TrajectoryAnalysisSettings::~TrajectoryAnalysisSettings() -{ -} +TrajectoryAnalysisSettings::~TrajectoryAnalysisSettings() {} -void TrajectoryAnalysisSettings::setOptionsModuleSettings( - ICommandLineOptionsModuleSettings *settings) +void TrajectoryAnalysisSettings::setOptionsModuleSettings(ICommandLineOptionsModuleSettings* settings) { impl_->optionsModuleSettings_ = settings; } -TimeUnit -TrajectoryAnalysisSettings::timeUnit() const +TimeUnit TrajectoryAnalysisSettings::timeUnit() const { return impl_->timeUnit; } -const AnalysisDataPlotSettings & -TrajectoryAnalysisSettings::plotSettings() const +const AnalysisDataPlotSettings& TrajectoryAnalysisSettings::plotSettings() const { return impl_->plotSettings; } -unsigned long -TrajectoryAnalysisSettings::flags() const +unsigned long TrajectoryAnalysisSettings::flags() const { return impl_->flags; } -bool -TrajectoryAnalysisSettings::hasFlag(unsigned long flag) const +bool TrajectoryAnalysisSettings::hasFlag(unsigned long flag) const { return (impl_->flags & flag) != 0U; } -bool -TrajectoryAnalysisSettings::hasPBC() const +bool TrajectoryAnalysisSettings::hasPBC() const { return impl_->bPBC; } -bool -TrajectoryAnalysisSettings::hasRmPBC() const +bool TrajectoryAnalysisSettings::hasRmPBC() const { return impl_->bRmPBC; } -int -TrajectoryAnalysisSettings::frflags() const +int TrajectoryAnalysisSettings::frflags() const { return impl_->frflags; } -void -TrajectoryAnalysisSettings::setFlags(unsigned long flags) +void TrajectoryAnalysisSettings::setFlags(unsigned long flags) { impl_->flags = flags; } -void -TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool bSet) +void TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool bSet) { if (bSet) { @@ -147,28 +135,24 @@ TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool bSet) } -void -TrajectoryAnalysisSettings::setPBC(bool bPBC) +void TrajectoryAnalysisSettings::setPBC(bool bPBC) { impl_->bPBC = bPBC; } -void -TrajectoryAnalysisSettings::setRmPBC(bool bRmPBC) +void TrajectoryAnalysisSettings::setRmPBC(bool bRmPBC) { impl_->bRmPBC = bRmPBC; } -void -TrajectoryAnalysisSettings::setFrameFlags(int frflags) +void TrajectoryAnalysisSettings::setFrameFlags(int frflags) { impl_->frflags = frflags; } -void -TrajectoryAnalysisSettings::setHelpText(const ArrayRef &help) +void TrajectoryAnalysisSettings::setHelpText(const ArrayRef& help) { GMX_RELEASE_ASSERT(impl_->optionsModuleSettings_ != nullptr, "setHelpText() called in invalid context"); diff --git a/src/gromacs/trajectoryanalysis/analysissettings.h b/src/gromacs/trajectoryanalysis/analysissettings.h index 9af29fc548..e3ac3799a8 100644 --- a/src/gromacs/trajectoryanalysis/analysissettings.h +++ b/src/gromacs/trajectoryanalysis/analysissettings.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +52,8 @@ namespace gmx { -template class ArrayRef; +template +class ArrayRef; class AnalysisDataPlotSettings; class ICommandLineOptionsModuleSettings; @@ -81,164 +83,164 @@ class TrajectoryAnalysisRunnerCommon; */ class TrajectoryAnalysisSettings { - public: - //! Recognized flags. - enum - { - /*! \brief - * Forces loading of a topology file. - * - * If this flag is not specified, the topology file is loaded only - * if it is provided on the command line explicitly. - */ - efRequireTop = 1<<0, - /*! \brief - * Requests topology coordinates. - * - * If this flag is specified, the position coordinates loaded from the - * topology can be accessed, otherwise they are not loaded. - * - * \see TopologyInformation - */ - efUseTopX = 1<<1, - /*! \brief - * Requests topology coordinates. - * - * If this flag is specified, the velocity coordinates loaded from the - * topology can be accessed, otherwise they are not loaded. - * - * \see TopologyInformation - */ - efUseTopV = 1<<2, - /*! \brief - * Disallows the user from changing PBC handling. - * - * If this option is not specified, the analysis module (see - * TrajectoryAnalysisModule::analyzeFrame()) may be passed a NULL - * PBC structure, and it should be able to handle such a situation. - * - * \see setPBC() - */ - efNoUserPBC = 1<<4, - /*! \brief - * Disallows the user from changing PBC removal. - * - * \see setRmPBC() - */ - efNoUserRmPBC = 1<<5, - }; - - //! Initializes default settings. - TrajectoryAnalysisSettings(); - ~TrajectoryAnalysisSettings(); - - //! Injects command line options module settings for some methods to use. - void setOptionsModuleSettings(ICommandLineOptionsModuleSettings *settings); - - //! Returns the time unit the user has requested. - TimeUnit timeUnit() const; - //! Returns common settings for analysis data plot modules. - const AnalysisDataPlotSettings &plotSettings() const; - - //! Returns the currently set flags. - unsigned long flags() const; - //! Tests whether a flag has been set. - bool hasFlag(unsigned long flag) const; +public: + //! Recognized flags. + enum + { /*! \brief - * Returns whether PBC should be used. + * Forces loading of a topology file. * - * Returns the value set with setPBC() and/or overridden by the user. - * The user-provided value can be accessed in - * TrajectoryAnalysisModule::optionsFinished(), and can be overridden - * with a call to setPBC(). + * If this flag is not specified, the topology file is loaded only + * if it is provided on the command line explicitly. */ - bool hasPBC() const; + efRequireTop = 1 << 0, /*! \brief - * Returns whether molecules should be made whole. + * Requests topology coordinates. * - * See hasPBC() for information on accessing or overriding the - * user-provided value. - */ - bool hasRmPBC() const; - //! Returns the currently set frame flags. - int frflags() const; - - /*! \brief - * Sets flags. + * If this flag is specified, the position coordinates loaded from the + * topology can be accessed, otherwise they are not loaded. * - * Overrides any earlier set flags. - * By default, no flags are set. + * \see TopologyInformation */ - void setFlags(unsigned long flags); - //! Sets or clears an individual flag. - void setFlag(unsigned long flag, bool bSet = true); + efUseTopX = 1 << 1, /*! \brief - * Sets whether PBC are used. - * - * \param[in] bPBC true if PBC should be used. + * Requests topology coordinates. * - * If called in TrajectoryAnalysisModule::initOptions(), this function - * sets the default for whether PBC are used in the analysis. - * If \ref efNoUserPBC is not set, a command-line option is provided - * for the user to override the default value. - * If called later, it overrides the setting provided by the user or an - * earlier call. + * If this flag is specified, the velocity coordinates loaded from the + * topology can be accessed, otherwise they are not loaded. * - * If this function is not called, the default is to use PBC. - * - * If PBC are not used, the \p pbc pointer passed to - * TrajectoryAnalysisModule::analyzeFrame() is NULL. - * The value of the flag can also be accessed with hasPBC(). - * - * \see efNoUserPBC + * \see TopologyInformation */ - void setPBC(bool bPBC); + efUseTopV = 1 << 2, /*! \brief - * Sets whether molecules are made whole. - * - * \param[in] bRmPBC true if molecules should be made whole. + * Disallows the user from changing PBC handling. * - * If called in TrajectoryAnalysisModule::initOptions(), this function - * sets the default for whether molecules are made whole. - * If \ref efNoUserRmPBC is not set, a command-line option is provided - * for the user to override the default value. - * If called later, it overrides the setting provided by the user or an - * earlier call. + * If this option is not specified, the analysis module (see + * TrajectoryAnalysisModule::analyzeFrame()) may be passed a NULL + * PBC structure, and it should be able to handle such a situation. * - * If this function is not called, the default is to make molecules - * whole. - * - * The main use of this function is to call it with \c false if your - * analysis program does not require whole molecules as this can - * increase the performance. - * In such a case, you can also specify \ref efNoUserRmPBC to not to - * confuse the user with an option that would only slow the program - * down. - * - * \see efNoUserRmPBC + * \see setPBC() */ - void setRmPBC(bool bRmPBC); + efNoUserPBC = 1 << 4, /*! \brief - * Sets flags that determine what to read from the trajectory. + * Disallows the user from changing PBC removal. * - * \param[in] frflags Flags for what to read from the trajectory file. - * - * If this function is not called, the flags default to TRX_NEED_X. - * If the analysis module needs some other information (velocities, - * forces), it can call this function to load additional information - * from the trajectory. + * \see setRmPBC() */ - void setFrameFlags(int frflags); - - //! \copydoc ICommandLineOptionsModuleSettings::setHelpText() - void setHelpText(const ArrayRef &help); - - private: - class Impl; - - PrivateImplPointer impl_; - - friend class TrajectoryAnalysisRunnerCommon; + efNoUserRmPBC = 1 << 5, + }; + + //! Initializes default settings. + TrajectoryAnalysisSettings(); + ~TrajectoryAnalysisSettings(); + + //! Injects command line options module settings for some methods to use. + void setOptionsModuleSettings(ICommandLineOptionsModuleSettings* settings); + + //! Returns the time unit the user has requested. + TimeUnit timeUnit() const; + //! Returns common settings for analysis data plot modules. + const AnalysisDataPlotSettings& plotSettings() const; + + //! Returns the currently set flags. + unsigned long flags() const; + //! Tests whether a flag has been set. + bool hasFlag(unsigned long flag) const; + /*! \brief + * Returns whether PBC should be used. + * + * Returns the value set with setPBC() and/or overridden by the user. + * The user-provided value can be accessed in + * TrajectoryAnalysisModule::optionsFinished(), and can be overridden + * with a call to setPBC(). + */ + bool hasPBC() const; + /*! \brief + * Returns whether molecules should be made whole. + * + * See hasPBC() for information on accessing or overriding the + * user-provided value. + */ + bool hasRmPBC() const; + //! Returns the currently set frame flags. + int frflags() const; + + /*! \brief + * Sets flags. + * + * Overrides any earlier set flags. + * By default, no flags are set. + */ + void setFlags(unsigned long flags); + //! Sets or clears an individual flag. + void setFlag(unsigned long flag, bool bSet = true); + /*! \brief + * Sets whether PBC are used. + * + * \param[in] bPBC true if PBC should be used. + * + * If called in TrajectoryAnalysisModule::initOptions(), this function + * sets the default for whether PBC are used in the analysis. + * If \ref efNoUserPBC is not set, a command-line option is provided + * for the user to override the default value. + * If called later, it overrides the setting provided by the user or an + * earlier call. + * + * If this function is not called, the default is to use PBC. + * + * If PBC are not used, the \p pbc pointer passed to + * TrajectoryAnalysisModule::analyzeFrame() is NULL. + * The value of the flag can also be accessed with hasPBC(). + * + * \see efNoUserPBC + */ + void setPBC(bool bPBC); + /*! \brief + * Sets whether molecules are made whole. + * + * \param[in] bRmPBC true if molecules should be made whole. + * + * If called in TrajectoryAnalysisModule::initOptions(), this function + * sets the default for whether molecules are made whole. + * If \ref efNoUserRmPBC is not set, a command-line option is provided + * for the user to override the default value. + * If called later, it overrides the setting provided by the user or an + * earlier call. + * + * If this function is not called, the default is to make molecules + * whole. + * + * The main use of this function is to call it with \c false if your + * analysis program does not require whole molecules as this can + * increase the performance. + * In such a case, you can also specify \ref efNoUserRmPBC to not to + * confuse the user with an option that would only slow the program + * down. + * + * \see efNoUserRmPBC + */ + void setRmPBC(bool bRmPBC); + /*! \brief + * Sets flags that determine what to read from the trajectory. + * + * \param[in] frflags Flags for what to read from the trajectory file. + * + * If this function is not called, the flags default to TRX_NEED_X. + * If the analysis module needs some other information (velocities, + * forces), it can call this function to load additional information + * from the trajectory. + */ + void setFrameFlags(int frflags); + + //! \copydoc ICommandLineOptionsModuleSettings::setHelpText() + void setHelpText(const ArrayRef& help); + +private: + class Impl; + + PrivateImplPointer impl_; + + friend class TrajectoryAnalysisRunnerCommon; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/analysissettings_impl.h b/src/gromacs/trajectoryanalysis/analysissettings_impl.h index edc2b3c5b3..68378ec95b 100644 --- a/src/gromacs/trajectoryanalysis/analysissettings_impl.h +++ b/src/gromacs/trajectoryanalysis/analysissettings_impl.h @@ -60,30 +60,34 @@ class ICommandLineOptionsModuleSettings; */ class TrajectoryAnalysisSettings::Impl { - public: - //! Initializes the default values for the settings object. - Impl() - : timeUnit(TimeUnit_Default), flags(0), frflags(0), - bRmPBC(true), bPBC(true), optionsModuleSettings_(nullptr) - { - } +public: + //! Initializes the default values for the settings object. + Impl() : + timeUnit(TimeUnit_Default), + flags(0), + frflags(0), + bRmPBC(true), + bPBC(true), + optionsModuleSettings_(nullptr) + { + } - //! Global time unit setting for the analysis module. - TimeUnit timeUnit; - //! Global plotting settings for the analysis module. - AnalysisDataPlotSettings plotSettings; - //! Flags for the analysis module. - unsigned long flags; - //! Frame reading flags for the analysis module. - int frflags; + //! Global time unit setting for the analysis module. + TimeUnit timeUnit; + //! Global plotting settings for the analysis module. + AnalysisDataPlotSettings plotSettings; + //! Flags for the analysis module. + unsigned long flags; + //! Frame reading flags for the analysis module. + int frflags; - //! Whether to make molecules whole for each frame. - bool bRmPBC; - //! Whether to pass PBC information to the analysis module. - bool bPBC; + //! Whether to make molecules whole for each frame. + bool bRmPBC; + //! Whether to pass PBC information to the analysis module. + bool bPBC; - //! Lower-level settings object wrapped by these settings. - ICommandLineOptionsModuleSettings *optionsModuleSettings_; + //! Lower-level settings object wrapped by these settings. + ICommandLineOptionsModuleSettings* optionsModuleSettings_; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/cmdlinerunner.cpp b/src/gromacs/trajectoryanalysis/cmdlinerunner.cpp index 733ebdd2c3..755782d827 100644 --- a/src/gromacs/trajectoryanalysis/cmdlinerunner.cpp +++ b/src/gromacs/trajectoryanalysis/cmdlinerunner.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -73,36 +74,33 @@ namespace class RunnerModule : public ICommandLineOptionsModule { - public: - explicit RunnerModule(TrajectoryAnalysisModulePointer module) - : module_(std::move(module)), common_(&settings_) - { - } +public: + explicit RunnerModule(TrajectoryAnalysisModulePointer module) : + module_(std::move(module)), + common_(&settings_) + { + } - void init(CommandLineModuleSettings * /*settings*/) override {} - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - void optionsFinished() override; - int run() override; + void init(CommandLineModuleSettings* /*settings*/) override {} + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + void optionsFinished() override; + int run() override; - TrajectoryAnalysisModulePointer module_; - TrajectoryAnalysisSettings settings_; - TrajectoryAnalysisRunnerCommon common_; - SelectionCollection selections_; + TrajectoryAnalysisModulePointer module_; + TrajectoryAnalysisSettings settings_; + TrajectoryAnalysisRunnerCommon common_; + SelectionCollection selections_; }; -void RunnerModule::initOptions( - IOptionsContainer *options, ICommandLineOptionsModuleSettings *settings) +void RunnerModule::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - std::shared_ptr timeUnitBehavior( - new TimeUnitBehavior()); + std::shared_ptr timeUnitBehavior(new TimeUnitBehavior()); std::shared_ptr selectionOptionBehavior( - new SelectionOptionBehavior(&selections_, - common_.topologyProvider())); + new SelectionOptionBehavior(&selections_, common_.topologyProvider())); settings->addOptionsBehavior(timeUnitBehavior); settings->addOptionsBehavior(selectionOptionBehavior); - IOptionsContainer &commonOptions = options->addGroup(); - IOptionsContainer &moduleOptions = options->addGroup(); + IOptionsContainer& commonOptions = options->addGroup(); + IOptionsContainer& moduleOptions = options->addGroup(); settings_.setOptionsModuleSettings(settings); module_->initOptions(&moduleOptions, &settings_); @@ -120,7 +118,7 @@ void RunnerModule::optionsFinished() int RunnerModule::run() { common_.initTopology(); - const TopologyInformation &topology = common_.topologyInformation(); + const TopologyInformation& topology = common_.topologyInformation(); module_->initAnalysis(settings_, topology); // Load first frame. @@ -129,16 +127,15 @@ int RunnerModule::run() module_->initAfterFirstFrame(settings_, common_.frame()); t_pbc pbc; - t_pbc *ppbc = settings_.hasPBC() ? &pbc : nullptr; + t_pbc* ppbc = settings_.hasPBC() ? &pbc : nullptr; - int nframes = 0; + int nframes = 0; AnalysisDataParallelOptions dataOptions; - TrajectoryAnalysisModuleDataPointer pdata( - module_->startFrames(dataOptions, selections_)); + TrajectoryAnalysisModuleDataPointer pdata(module_->startFrames(dataOptions, selections_)); do { common_.initFrame(); - t_trxframe &frame = common_.frame(); + t_trxframe& frame = common_.frame(); if (ppbc != nullptr) { set_pbc(ppbc, topology.ePBC(), frame.box); @@ -149,8 +146,7 @@ int RunnerModule::run() module_->finishFrameSerial(nframes); ++nframes; - } - while (common_.readNextFrame()); + } while (common_.readNextFrame()); module_->finishFrames(pdata.get()); if (pdata.get() != nullptr) { @@ -160,8 +156,7 @@ int RunnerModule::run() if (common_.hasTrajectory()) { - fprintf(stderr, "Analyzed %d frames, last time %.3f\n", - nframes, common_.frame().time); + fprintf(stderr, "Analyzed %d frames, last time %.3f\n", nframes, common_.frame().time); } else { @@ -177,42 +172,32 @@ int RunnerModule::run() return 0; } -} // namespace +} // namespace /******************************************************************** * TrajectoryAnalysisCommandLineRunner */ // static -int -TrajectoryAnalysisCommandLineRunner::runAsMain( - int argc, char *argv[], const ModuleFactoryMethod &factory) +int TrajectoryAnalysisCommandLineRunner::runAsMain(int argc, char* argv[], const ModuleFactoryMethod& factory) { - auto runnerFactory = [factory] - { - return createModule(factory()); - }; + auto runnerFactory = [factory] { return createModule(factory()); }; return ICommandLineOptionsModule::runAsMain(argc, argv, nullptr, nullptr, runnerFactory); } // static -void -TrajectoryAnalysisCommandLineRunner::registerModule( - CommandLineModuleManager *manager, const char *name, - const char *description, const ModuleFactoryMethod &factory) +void TrajectoryAnalysisCommandLineRunner::registerModule(CommandLineModuleManager* manager, + const char* name, + const char* description, + const ModuleFactoryMethod& factory) { - auto runnerFactory = [factory] - { - return createModule(factory()); - }; - ICommandLineOptionsModule::registerModuleFactory( - manager, name, description, runnerFactory); + auto runnerFactory = [factory] { return createModule(factory()); }; + ICommandLineOptionsModule::registerModuleFactory(manager, name, description, runnerFactory); } // static std::unique_ptr -TrajectoryAnalysisCommandLineRunner::createModule( - TrajectoryAnalysisModulePointer module) +TrajectoryAnalysisCommandLineRunner::createModule(TrajectoryAnalysisModulePointer module) { return ICommandLineOptionsModulePointer(new RunnerModule(std::move(module))); } diff --git a/src/gromacs/trajectoryanalysis/cmdlinerunner.h b/src/gromacs/trajectoryanalysis/cmdlinerunner.h index f7661f8739..246f70d9e7 100644 --- a/src/gromacs/trajectoryanalysis/cmdlinerunner.h +++ b/src/gromacs/trajectoryanalysis/cmdlinerunner.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,94 +67,92 @@ class ICommandLineOptionsModule; */ class TrajectoryAnalysisCommandLineRunner { - public: - /*! \brief - * Factory method type for creating a trajectory analysis module. - * - * This method allows the module creation to be postponed to the point - * where the module is needed, reducing initialization costs in, e.g., - * the `gmx` binary, and simplifying exception handling. - */ - typedef std::function - ModuleFactoryMethod; +public: + /*! \brief + * Factory method type for creating a trajectory analysis module. + * + * This method allows the module creation to be postponed to the point + * where the module is needed, reducing initialization costs in, e.g., + * the `gmx` binary, and simplifying exception handling. + */ + typedef std::function ModuleFactoryMethod; - /*! \brief - * Implements a main() method that runs a given module. - * - * \tparam ModuleType Trajectory analysis module. - * \param argc \c argc passed to main(). - * \param argv \c argv passed to main(). - * - * This method abstracts away all the logic required to implement a - * main() method in user tools, allowing that to be changed without - * requiring changes to the tools themselves. - * - * \p ModuleType should be default-constructible and derive from - * TrajectoryAnalysisModule. - * - * Does not throw. All exceptions are caught and handled internally. - */ - template - static int runAsMain(int argc, char *argv[]) - { - return runAsMain(argc, argv, &createModule); - } - /*! \brief - * Implements a main() method that runs a given module. - * - * \param argc \c argc passed to main(). - * \param argv \c argv passed to main(). - * \param factory Function that creates the module on demand. - * - * Implements the template runAsMain(), but can also be used - * independently. - * - * Does not throw. All exceptions are caught and handled internally. - */ - static int runAsMain(int argc, char *argv[], - const ModuleFactoryMethod &factory); - /*! \brief - * Registers a command-line module that runs a given module. - * - * \param manager Manager to register the module to. - * \param name Name of the module to register. - * \param description One-line description for the module to register. - * \param factory Function that creates the module on demand. - * - * \p name and \p descriptions must be string constants or otherwise - * stay valid for the duration of the program execution. - */ - static void registerModule(CommandLineModuleManager *manager, - const char *name, const char *description, - const ModuleFactoryMethod &factory); - /*! \brief - * Create a command-line module that runs the provided analysis module. - * - * \param[in] module Module to run. - * \returns Command-line module that runs the provided analysis - * module. - * \throws std::bad_alloc if out of memory. - * - * This is mainly provided for testing purposes that want to bypass - * CommandLineModuleManager. - */ - static std::unique_ptr - createModule(TrajectoryAnalysisModulePointer module); + /*! \brief + * Implements a main() method that runs a given module. + * + * \tparam ModuleType Trajectory analysis module. + * \param argc \c argc passed to main(). + * \param argv \c argv passed to main(). + * + * This method abstracts away all the logic required to implement a + * main() method in user tools, allowing that to be changed without + * requiring changes to the tools themselves. + * + * \p ModuleType should be default-constructible and derive from + * TrajectoryAnalysisModule. + * + * Does not throw. All exceptions are caught and handled internally. + */ + template + static int runAsMain(int argc, char* argv[]) + { + return runAsMain(argc, argv, &createModule); + } + /*! \brief + * Implements a main() method that runs a given module. + * + * \param argc \c argc passed to main(). + * \param argv \c argv passed to main(). + * \param factory Function that creates the module on demand. + * + * Implements the template runAsMain(), but can also be used + * independently. + * + * Does not throw. All exceptions are caught and handled internally. + */ + static int runAsMain(int argc, char* argv[], const ModuleFactoryMethod& factory); + /*! \brief + * Registers a command-line module that runs a given module. + * + * \param manager Manager to register the module to. + * \param name Name of the module to register. + * \param description One-line description for the module to register. + * \param factory Function that creates the module on demand. + * + * \p name and \p descriptions must be string constants or otherwise + * stay valid for the duration of the program execution. + */ + static void registerModule(CommandLineModuleManager* manager, + const char* name, + const char* description, + const ModuleFactoryMethod& factory); + /*! \brief + * Create a command-line module that runs the provided analysis module. + * + * \param[in] module Module to run. + * \returns Command-line module that runs the provided analysis + * module. + * \throws std::bad_alloc if out of memory. + * + * This is mainly provided for testing purposes that want to bypass + * CommandLineModuleManager. + */ + static std::unique_ptr createModule(TrajectoryAnalysisModulePointer module); - private: - // Prevent instantiation. - TrajectoryAnalysisCommandLineRunner() {} +private: + // Prevent instantiation. + TrajectoryAnalysisCommandLineRunner() {} - /*! \brief - * Creates a trajectory analysis module of a given type. - * - * \tparam ModuleType Module to create. - */ - template - static TrajectoryAnalysisModulePointer createModule() - { - return TrajectoryAnalysisModulePointer(new ModuleType()); - } + /*! \brief + * Creates a trajectory analysis module of a given type. + * + * \tparam ModuleType Module to create. + */ + template + static TrajectoryAnalysisModulePointer createModule() + { + return TrajectoryAnalysisModulePointer(new ModuleType()); + } }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/modules.cpp b/src/gromacs/trajectoryanalysis/modules.cpp index 5f635cfc2f..9c266bc03e 100644 --- a/src/gromacs/trajectoryanalysis/modules.cpp +++ b/src/gromacs/trajectoryanalysis/modules.cpp @@ -75,20 +75,18 @@ namespace * * \ingroup module_trajectoryanalysis */ -template -void registerModule(CommandLineModuleManager *manager, - CommandLineModuleGroup group) +template +void registerModule(CommandLineModuleManager* manager, CommandLineModuleGroup group) { TrajectoryAnalysisCommandLineRunner::registerModule( - manager, ModuleInfo::name, ModuleInfo::shortDescription, - &ModuleInfo::create); + manager, ModuleInfo::name, ModuleInfo::shortDescription, &ModuleInfo::create); group.addModule(ModuleInfo::name); } -} // namespace +} // namespace //! \cond libapi -void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager) +void registerTrajectoryAnalysisModules(CommandLineModuleManager* manager) { using namespace gmx::analysismodules; CommandLineModuleGroup group = manager->addModuleGroup("Trajectory analysis"); diff --git a/src/gromacs/trajectoryanalysis/modules.h b/src/gromacs/trajectoryanalysis/modules.h index 44ff5409bc..75acf8748a 100644 --- a/src/gromacs/trajectoryanalysis/modules.h +++ b/src/gromacs/trajectoryanalysis/modules.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +60,7 @@ class CommandLineModuleManager; * * \ingroup module_trajectoryanalysis */ -void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager); +void registerTrajectoryAnalysisModules(CommandLineModuleManager* manager); //! \endcond } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/modules/angle.cpp b/src/gromacs/trajectoryanalysis/modules/angle.cpp index ff81c402e4..344c4ee748 100644 --- a/src/gromacs/trajectoryanalysis/modules/angle.cpp +++ b/src/gromacs/trajectoryanalysis/modules/angle.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -104,138 +105,131 @@ namespace */ class AnglePositionIterator { - public: - /*! \brief - * Creates an iterator to loop over input selection positions. - * - * \param[in] selections List of selections. - * \param[in] posCountPerValue Number of selection positions that - * constitute a single value for the iteration. - * - * If \p selections is empty, and/or \p posCountPerValue is zero, the - * iterator can still be advanced and hasValue()/hasSingleValue() - * called, but values cannot be accessed. - */ - AnglePositionIterator(const SelectionList &selections, - int posCountPerValue) - : selections_(selections), posCountPerValue_(posCountPerValue), - currentSelection_(0), nextPosition_(0) - { - } +public: + /*! \brief + * Creates an iterator to loop over input selection positions. + * + * \param[in] selections List of selections. + * \param[in] posCountPerValue Number of selection positions that + * constitute a single value for the iteration. + * + * If \p selections is empty, and/or \p posCountPerValue is zero, the + * iterator can still be advanced and hasValue()/hasSingleValue() + * called, but values cannot be accessed. + */ + AnglePositionIterator(const SelectionList& selections, int posCountPerValue) : + selections_(selections), + posCountPerValue_(posCountPerValue), + currentSelection_(0), + nextPosition_(0) + { + } - //! Advances the iterator to the next group of angles. - void nextGroup() + //! Advances the iterator to the next group of angles. + void nextGroup() + { + if (selections_.size() > 1) { - if (selections_.size() > 1) - { - ++currentSelection_; - } - nextPosition_ = 0; + ++currentSelection_; } - //! Advances the iterator to the next angle in the current group. - void nextValue() + nextPosition_ = 0; + } + //! Advances the iterator to the next angle in the current group. + void nextValue() + { + if (!hasSingleValue()) { - if (!hasSingleValue()) - { - nextPosition_ += posCountPerValue_; - } + nextPosition_ += posCountPerValue_; } + } - /*! \brief - * Returns whether this iterator represents any values. - * - * If the return value is `false`, only nextGroup(), nextValue() and - * hasSingleValue() are allowed to be called. - */ - bool hasValue() const - { - return !selections_.empty(); - } - /*! \brief - * Returns whether the current selection only contains a single value. - * - * Returns `false` if hasValue() returns false, which allows cutting - * some corners in consistency checks. - */ - bool hasSingleValue() const - { - return hasValue() && currentSelection().posCount() == posCountPerValue_; - } - //! Returns whether the current selection is dynamic. - bool isDynamic() const + /*! \brief + * Returns whether this iterator represents any values. + * + * If the return value is `false`, only nextGroup(), nextValue() and + * hasSingleValue() are allowed to be called. + */ + bool hasValue() const { return !selections_.empty(); } + /*! \brief + * Returns whether the current selection only contains a single value. + * + * Returns `false` if hasValue() returns false, which allows cutting + * some corners in consistency checks. + */ + bool hasSingleValue() const + { + return hasValue() && currentSelection().posCount() == posCountPerValue_; + } + //! Returns whether the current selection is dynamic. + bool isDynamic() const { return currentSelection().isDynamic(); } + /*! \brief + * Returns whether positions in the current value are either all + * selected or all unselected. + */ + bool allValuesConsistentlySelected() const + { + if (posCountPerValue_ <= 1) { - return currentSelection().isDynamic(); + return true; } - /*! \brief - * Returns whether positions in the current value are either all - * selected or all unselected. - */ - bool allValuesConsistentlySelected() const + const bool bSelected = currentPosition(0).selected(); + for (int i = 1; i < posCountPerValue_; ++i) { - if (posCountPerValue_ <= 1) + if (currentPosition(i).selected() != bSelected) { - return true; + return false; } - const bool bSelected = currentPosition(0).selected(); - for (int i = 1; i < posCountPerValue_; ++i) - { - if (currentPosition(i).selected() != bSelected) - { - return false; - } - } - return true; - } - /*! \brief - * Returns whether positions in the current value are selected. - * - * Only works reliably if allValuesConsistentlySelected() returns - * `true`. - */ - bool currentValuesSelected() const - { - return selections_.empty() || currentPosition(0).selected(); } + return true; + } + /*! \brief + * Returns whether positions in the current value are selected. + * + * Only works reliably if allValuesConsistentlySelected() returns + * `true`. + */ + bool currentValuesSelected() const + { + return selections_.empty() || currentPosition(0).selected(); + } - //! Returns the currently active selection. - const Selection ¤tSelection() const - { - GMX_ASSERT(currentSelection_ < ssize(selections_), - "Accessing an invalid selection"); - return selections_[currentSelection_]; - } - //! Returns the `i`th position for the current value. - SelectionPosition currentPosition(int i) const - { - return currentSelection().position(nextPosition_ + i); - } - /*! \brief - * Extracts all coordinates corresponding to the current value. - * - * \param[out] x Array to which the positions are extracted. - * - * \p x should contain at minimum the number of positions per value - * passed to the constructor. - */ - void getCurrentPositions(rvec x[]) const + //! Returns the currently active selection. + const Selection& currentSelection() const + { + GMX_ASSERT(currentSelection_ < ssize(selections_), "Accessing an invalid selection"); + return selections_[currentSelection_]; + } + //! Returns the `i`th position for the current value. + SelectionPosition currentPosition(int i) const + { + return currentSelection().position(nextPosition_ + i); + } + /*! \brief + * Extracts all coordinates corresponding to the current value. + * + * \param[out] x Array to which the positions are extracted. + * + * \p x should contain at minimum the number of positions per value + * passed to the constructor. + */ + void getCurrentPositions(rvec x[]) const + { + GMX_ASSERT(posCountPerValue_ > 0, "Accessing positions for an invalid angle type"); + GMX_ASSERT(nextPosition_ + posCountPerValue_ <= currentSelection().posCount(), + "Accessing an invalid position"); + for (int i = 0; i < posCountPerValue_; ++i) { - GMX_ASSERT(posCountPerValue_ > 0, - "Accessing positions for an invalid angle type"); - GMX_ASSERT(nextPosition_ + posCountPerValue_ <= currentSelection().posCount(), - "Accessing an invalid position"); - for (int i = 0; i < posCountPerValue_; ++i) - { - copy_rvec(currentPosition(i).x(), x[i]); - } + copy_rvec(currentPosition(i).x(), x[i]); } + } - private: - const SelectionList &selections_; - const int posCountPerValue_; - int currentSelection_; - int nextPosition_; +private: + const SelectionList& selections_; + const int posCountPerValue_; + int currentSelection_; + int nextPosition_; - GMX_DISALLOW_COPY_AND_ASSIGN(AnglePositionIterator); + GMX_DISALLOW_COPY_AND_ASSIGN(AnglePositionIterator); }; /******************************************************************** @@ -261,63 +255,60 @@ enum Group2Type Group2Type_SphereNormal }; //! String values corresponding to Group1Type. -const char *const cGroup1TypeEnum[] = -{ "angle", "dihedral", "vector", "plane" }; +const char* const cGroup1TypeEnum[] = { "angle", "dihedral", "vector", "plane" }; //! String values corresponding to Group2Type. -const char *const cGroup2TypeEnum[] = -{ "none", "vector", "plane", "t0", "z", "sphnorm" }; +const char* const cGroup2TypeEnum[] = { "none", "vector", "plane", "t0", "z", "sphnorm" }; class Angle : public TrajectoryAnalysisModule { - public: - Angle(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - void initFromSelections(const SelectionList &sel1, - const SelectionList &sel2); - void checkSelections(const SelectionList &sel1, - const SelectionList &sel2) const; - - SelectionList sel1_; - SelectionList sel2_; - SelectionOptionInfo *sel1info_; - SelectionOptionInfo *sel2info_; - std::string fnAverage_; - std::string fnAll_; - std::string fnHistogram_; - - Group1Type g1type_; - Group2Type g2type_; - double binWidth_; - - AnalysisData angles_; - AnalysisDataFrameAverageModulePointer averageModule_; - AnalysisDataSimpleHistogramModulePointer histogramModule_; - - std::vector angleCount_; - int natoms1_; - int natoms2_; - std::vector > vt0_; - - // Copy and assign disallowed by base. +public: + Angle(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + void initFromSelections(const SelectionList& sel1, const SelectionList& sel2); + void checkSelections(const SelectionList& sel1, const SelectionList& sel2) const; + + SelectionList sel1_; + SelectionList sel2_; + SelectionOptionInfo* sel1info_; + SelectionOptionInfo* sel2info_; + std::string fnAverage_; + std::string fnAll_; + std::string fnHistogram_; + + Group1Type g1type_; + Group2Type g2type_; + double binWidth_; + + AnalysisData angles_; + AnalysisDataFrameAverageModulePointer averageModule_; + AnalysisDataSimpleHistogramModulePointer histogramModule_; + + std::vector angleCount_; + int natoms1_; + int natoms2_; + std::vector> vt0_; + + // Copy and assign disallowed by base. }; -Angle::Angle() - : sel1info_(nullptr), sel2info_(nullptr), - g1type_(Group1Type_Angle), g2type_(Group2Type_None), - binWidth_(1.0), natoms1_(0), natoms2_(0) +Angle::Angle() : + sel1info_(nullptr), + sel2info_(nullptr), + g1type_(Group1Type_Angle), + g2type_(Group2Type_None), + binWidth_(1.0), + natoms1_(0), + natoms2_(0) { averageModule_ = std::make_unique(); angles_.addModule(averageModule_); @@ -330,10 +321,9 @@ Angle::Angle() } -void -Angle::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Angle::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] computes different types of angles between vectors.", "It supports both vectors defined by two positions and normals of", "planes defined by three positions.", @@ -384,99 +374,102 @@ Angle::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *setti settings->setHelpText(desc); - options->addOption(FileNameOption("oav").filetype(eftPlot).outputFile() - .store(&fnAverage_).defaultBasename("angaver") - .description("Average angles as a function of time")); - options->addOption(FileNameOption("oall").filetype(eftPlot).outputFile() - .store(&fnAll_).defaultBasename("angles") - .description("All angles as a function of time")); - options->addOption(FileNameOption("oh").filetype(eftPlot).outputFile() - .store(&fnHistogram_).defaultBasename("anghist") - .description("Histogram of the angles")); - - options->addOption(EnumOption("g1").enumValue(cGroup1TypeEnum) - .store(&g1type_) - .description("Type of analysis/first vector group")); - options->addOption(EnumOption("g2").enumValue(cGroup2TypeEnum) - .store(&g2type_) - .description("Type of second vector group")); - options->addOption(DoubleOption("binw").store(&binWidth_) - .description("Binwidth for -oh in degrees")); - - sel1info_ = options->addOption(SelectionOption("group1") - .required().dynamicMask().storeVector(&sel1_) - .multiValue() - .description("First analysis/vector selection")); - sel2info_ = options->addOption(SelectionOption("group2") - .dynamicMask().storeVector(&sel2_) - .multiValue() - .description("Second analysis/vector selection")); + options->addOption(FileNameOption("oav") + .filetype(eftPlot) + .outputFile() + .store(&fnAverage_) + .defaultBasename("angaver") + .description("Average angles as a function of time")); + options->addOption(FileNameOption("oall") + .filetype(eftPlot) + .outputFile() + .store(&fnAll_) + .defaultBasename("angles") + .description("All angles as a function of time")); + options->addOption(FileNameOption("oh") + .filetype(eftPlot) + .outputFile() + .store(&fnHistogram_) + .defaultBasename("anghist") + .description("Histogram of the angles")); + + options->addOption( + EnumOption("g1").enumValue(cGroup1TypeEnum).store(&g1type_).description("Type of analysis/first vector group")); + options->addOption( + EnumOption("g2").enumValue(cGroup2TypeEnum).store(&g2type_).description("Type of second vector group")); + options->addOption( + DoubleOption("binw").store(&binWidth_).description("Binwidth for -oh in degrees")); + + sel1info_ = options->addOption( + SelectionOption("group1").required().dynamicMask().storeVector(&sel1_).multiValue().description( + "First analysis/vector selection")); + sel2info_ = options->addOption( + SelectionOption("group2").dynamicMask().storeVector(&sel2_).multiValue().description( + "Second analysis/vector selection")); } -void -Angle::optionsFinished(TrajectoryAnalysisSettings * /* settings */) +void Angle::optionsFinished(TrajectoryAnalysisSettings* /* settings */) { const bool bSingle = (g1type_ == Group1Type_Angle || g1type_ == Group1Type_Dihedral); if (bSingle && g2type_ != Group2Type_None) { - GMX_THROW(InconsistentInputError("Cannot use a second group (-g2) with " - "-g1 angle or dihedral")); + GMX_THROW( + InconsistentInputError("Cannot use a second group (-g2) with " + "-g1 angle or dihedral")); } if (bSingle && sel2info_->isSet()) { - GMX_THROW(InconsistentInputError("Cannot provide a second selection " - "(-group2) with -g1 angle or dihedral")); + GMX_THROW( + InconsistentInputError("Cannot provide a second selection " + "(-group2) with -g1 angle or dihedral")); } if (!bSingle && g2type_ == Group2Type_None) { - GMX_THROW(InconsistentInputError("Should specify a second group (-g2) " - "if the first group is not an angle or a dihedral")); + GMX_THROW( + InconsistentInputError("Should specify a second group (-g2) " + "if the first group is not an angle or a dihedral")); } // Set up the number of positions per angle. switch (g1type_) { - case Group1Type_Angle: natoms1_ = 3; break; + case Group1Type_Angle: natoms1_ = 3; break; case Group1Type_Dihedral: natoms1_ = 4; break; - case Group1Type_Vector: natoms1_ = 2; break; - case Group1Type_Plane: natoms1_ = 3; break; - default: - GMX_THROW(InternalError("invalid -g1 value")); + case Group1Type_Vector: natoms1_ = 2; break; + case Group1Type_Plane: natoms1_ = 3; break; + default: GMX_THROW(InternalError("invalid -g1 value")); } switch (g2type_) { - case Group2Type_None: natoms2_ = 0; break; - case Group2Type_Vector: natoms2_ = 2; break; - case Group2Type_Plane: natoms2_ = 3; break; - case Group2Type_TimeZero: natoms2_ = 0; break; - case Group2Type_Z: natoms2_ = 0; break; + case Group2Type_None: natoms2_ = 0; break; + case Group2Type_Vector: natoms2_ = 2; break; + case Group2Type_Plane: natoms2_ = 3; break; + case Group2Type_TimeZero: natoms2_ = 0; break; + case Group2Type_Z: natoms2_ = 0; break; case Group2Type_SphereNormal: natoms2_ = 1; break; - default: - GMX_THROW(InternalError("invalid -g2 value")); + default: GMX_THROW(InternalError("invalid -g2 value")); } if (natoms2_ == 0 && sel2info_->isSet()) { - GMX_THROW(InconsistentInputError("Cannot provide a second selection (-group2) with -g2 t0 or z")); + GMX_THROW(InconsistentInputError( + "Cannot provide a second selection (-group2) with -g2 t0 or z")); } // TODO: If bSingle is not set, the second selection option should be // required. } -void -Angle::initFromSelections(const SelectionList &sel1, - const SelectionList &sel2) +void Angle::initFromSelections(const SelectionList& sel1, const SelectionList& sel2) { const int angleGroups = std::max(sel1.size(), sel2.size()); const bool bHasSecondSelection = natoms2_ > 0; - if (bHasSecondSelection && sel1.size() != sel2.size() - && std::min(sel1.size(), sel2.size()) != 1) + if (bHasSecondSelection && sel1.size() != sel2.size() && std::min(sel1.size(), sel2.size()) != 1) { GMX_THROW(InconsistentInputError( - "-group1 and -group2 should specify the same number of selections")); + "-group1 and -group2 should specify the same number of selections")); } AnglePositionIterator iter1(sel1, natoms1_); @@ -487,8 +480,8 @@ Angle::initFromSelections(const SelectionList &sel1, if (natoms1_ > 1 && posCount1 % natoms1_ != 0) { GMX_THROW(InconsistentInputError(formatString( - "Number of positions in selection %d in the first group not divisible by %d", - static_cast(g + 1), natoms1_))); + "Number of positions in selection %d in the first group not divisible by %d", + static_cast(g + 1), natoms1_))); } const int angleCount1 = posCount1 / natoms1_; int angleCount = angleCount1; @@ -498,23 +491,23 @@ Angle::initFromSelections(const SelectionList &sel1, const int posCount2 = iter2.currentSelection().posCount(); if (natoms2_ > 1 && posCount2 % natoms2_ != 0) { - GMX_THROW(InconsistentInputError(formatString( - "Number of positions in selection %d in the second group not divisible by %d", - static_cast(g + 1), natoms2_))); + GMX_THROW(InconsistentInputError( + formatString("Number of positions in selection %d in the second group not " + "divisible by %d", + static_cast(g + 1), natoms2_))); } if (g2type_ == Group2Type_SphereNormal && posCount2 != 1) { GMX_THROW(InconsistentInputError( - "The second group should contain a single position with -g2 sphnorm")); + "The second group should contain a single position with -g2 sphnorm")); } const int angleCount2 = posCount2 / natoms2_; - angleCount = std::max(angleCount1, angleCount2); - if (angleCount1 != angleCount2 - && std::min(angleCount1, angleCount2) != 1) + angleCount = std::max(angleCount1, angleCount2); + if (angleCount1 != angleCount2 && std::min(angleCount1, angleCount2) != 1) { GMX_THROW(InconsistentInputError( - "Number of vectors defined by the two groups are not the same")); + "Number of vectors defined by the two groups are not the same")); } } angleCount_.push_back(angleCount); @@ -522,9 +515,7 @@ Angle::initFromSelections(const SelectionList &sel1, } -void -Angle::checkSelections(const SelectionList &sel1, - const SelectionList &sel2) const +void Angle::checkSelections(const SelectionList& sel1, const SelectionList& sel2) const { AnglePositionIterator iter1(sel1, natoms1_); AnglePositionIterator iter2(sel2, natoms2_); @@ -555,18 +546,17 @@ Angle::checkSelections(const SelectionList &sel1, } } if (iter2.hasValue() - && (angleCount_[g] == 1 - || (!iter1.hasSingleValue() && !iter2.hasSingleValue())) + && (angleCount_[g] == 1 || (!iter1.hasSingleValue() && !iter2.hasSingleValue())) && iter1.currentValuesSelected() != iter2.currentValuesSelected()) { bOk = false; } if (!bOk) { - std::string message = - formatString("Dynamic selection %d does not select " - "a consistent set of angles over the frames", - static_cast(g + 1)); + std::string message = formatString( + "Dynamic selection %d does not select " + "a consistent set of angles over the frames", + static_cast(g + 1)); GMX_THROW(InconsistentInputError(message)); } } @@ -575,9 +565,7 @@ Angle::checkSelections(const SelectionList &sel1, } -void -Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation & /* top */) +void Angle::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& /* top */) { initFromSelections(sel1_, sel2_); @@ -588,8 +576,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, angles_.setColumnCount(i, angleCount_[i]); } double histogramMin = (g1type_ == Group1Type_Dihedral ? -180.0 : 0); - histogramModule_->init(histogramFromRange(histogramMin, 180.0) - .binWidth(binWidth_).includeAll()); + histogramModule_->init(histogramFromRange(histogramMin, 180.0).binWidth(binWidth_).includeAll()); if (g2type_ == Group2Type_TimeZero) { @@ -602,8 +589,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnAverage_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAverage_); plotm->setTitle("Average angle"); plotm->setXAxisIsTime(); @@ -619,8 +605,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnAll_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAll_); plotm->setTitle("Angle"); plotm->setXAxisIsTime(); @@ -631,8 +616,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnHistogram_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnHistogram_); plotm->setTitle("Angle histogram"); plotm->setXLabel("Angle (degrees)"); @@ -649,8 +633,7 @@ Angle::initAnalysis(const TrajectoryAnalysisSettings &settings, //! Helper method to calculate a vector from two or three positions. -void -calc_vec(int natoms, rvec x[], t_pbc *pbc, rvec xout, rvec cout) +void calc_vec(int natoms, rvec x[], t_pbc* pbc, rvec xout, rvec cout) { switch (natoms) { @@ -682,22 +665,19 @@ calc_vec(int natoms, rvec x[], t_pbc *pbc, rvec xout, rvec cout) cprod(v1, v2, xout); rvec_add(x[0], x[1], cout); rvec_add(cout, x[2], cout); - svmul(1.0/3.0, cout, cout); + svmul(1.0 / 3.0, cout, cout); break; } - default: - GMX_RELEASE_ASSERT(false, "Incorrectly initialized number of atoms"); + default: GMX_RELEASE_ASSERT(false, "Incorrectly initialized number of atoms"); } } -void -Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void Angle::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { - AnalysisDataHandle dh = pdata->dataHandle(angles_); - const SelectionList &sel1 = pdata->parallelSelections(sel1_); - const SelectionList &sel2 = pdata->parallelSelections(sel2_); + AnalysisDataHandle dh = pdata->dataHandle(angles_); + const SelectionList& sel1 = pdata->parallelSelections(sel1_); + const SelectionList& sel2 = pdata->parallelSelections(sel2_); checkSelections(sel1, sel2); @@ -707,8 +687,8 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, AnglePositionIterator iter2(sel2, natoms2_); for (size_t g = 0; g < angleCount_.size(); ++g, iter1.nextGroup(), iter2.nextGroup()) { - rvec v1, v2; - rvec c1, c2; + rvec v1, v2; + rvec c1, c2; // v2 & c2 are conditionally set in the switch statement below, and conditionally // used in a different switch statement later. Apparently the clang static analyzer @@ -721,12 +701,8 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, switch (g2type_) { - case Group2Type_Z: - v2[ZZ] = 1.0; - break; - case Group2Type_SphereNormal: - copy_rvec(sel2_[g].position(0).x(), c2); - break; + case Group2Type_Z: v2[ZZ] = 1.0; break; + case Group2Type_SphereNormal: copy_rvec(sel2_[g].position(0).x(), c2); break; default: // do nothing break; @@ -737,15 +713,14 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, { rvec x[4]; // x[] will be assigned below based on the number of atoms used to initialize iter1, - // which in turn should correspond perfectly to g1type_ (which determines how many we read), - // but unsurprisingly the static analyzer chokes a bit on that. + // which in turn should correspond perfectly to g1type_ (which determines how many we + // read), but unsurprisingly the static analyzer chokes a bit on that. clear_rvecs(4, x); real angle; // checkSelections() ensures that this reflects all the involved // positions. - const bool bPresent = - iter1.currentValuesSelected() && iter2.currentValuesSelected(); + const bool bPresent = iter1.currentValuesSelected() && iter2.currentValuesSelected(); iter1.getCurrentPositions(x); switch (g1type_) { @@ -779,7 +754,7 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } cprod(dx[0], dx[1], v1); cprod(dx[1], dx[2], v2); - angle = gmx_angle(v1, v2); + angle = gmx_angle(v1, v2); real ipr = iprod(dx[0], v2); if (ipr < 0) { @@ -805,9 +780,7 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } copy_rvec(vt0_[g][n], v2); break; - case Group2Type_Z: - c1[XX] = c1[YY] = 0.0; - break; + case Group2Type_Z: c1[XX] = c1[YY] = 0.0; break; case Group2Type_SphereNormal: if (pbc) { @@ -818,13 +791,11 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, rvec_sub(c1, c2, v2); } break; - default: - GMX_THROW(InternalError("invalid -g2 value")); + default: GMX_THROW(InternalError("invalid -g2 value")); } angle = gmx_angle(v1, v2); break; - default: - GMX_THROW(InternalError("invalid -g1 value")); + default: GMX_THROW(InternalError("invalid -g1 value")); } dh.setPoint(n, angle * RAD2DEG, bPresent); } @@ -833,25 +804,20 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } -void -Angle::finishAnalysis(int /*nframes*/) +void Angle::finishAnalysis(int /*nframes*/) { - AbstractAverageHistogram &averageHistogram = histogramModule_->averager(); + AbstractAverageHistogram& averageHistogram = histogramModule_->averager(); averageHistogram.normalizeProbability(); averageHistogram.done(); } -void -Angle::writeOutput() -{ -} +void Angle::writeOutput() {} -} // namespace +} // namespace const char AngleInfo::name[] = "gangle"; -const char AngleInfo::shortDescription[] = - "Calculate angles"; +const char AngleInfo::shortDescription[] = "Calculate angles"; TrajectoryAnalysisModulePointer AngleInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/angle.h b/src/gromacs/trajectoryanalysis/modules/angle.h index 6b40390679..3a77d33853 100644 --- a/src/gromacs/trajectoryanalysis/modules/angle.h +++ b/src/gromacs/trajectoryanalysis/modules/angle.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class AngleInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/convert_trj.cpp b/src/gromacs/trajectoryanalysis/modules/convert_trj.cpp index 8b1af50a16..be07f61f5e 100644 --- a/src/gromacs/trajectoryanalysis/modules/convert_trj.cpp +++ b/src/gromacs/trajectoryanalysis/modules/convert_trj.cpp @@ -69,36 +69,30 @@ namespace class ConvertTrj : public TrajectoryAnalysisModule { - public: - ConvertTrj(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - TrajectoryFrameWriterPointer output_; - Selection sel_; - std::string name_; - OutputRequirementOptionDirector requirementsBuilder_; +public: + ConvertTrj(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + TrajectoryFrameWriterPointer output_; + Selection sel_; + std::string name_; + OutputRequirementOptionDirector requirementsBuilder_; }; -ConvertTrj::ConvertTrj() -{ -} +ConvertTrj::ConvertTrj() {} -void -ConvertTrj::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void ConvertTrj::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] converts trajectory files between different formats.", "The module supports writing all GROMACS supported file formats from", "the supported input formats.", @@ -112,25 +106,23 @@ ConvertTrj::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings * "selections.", }; - options->addOption(SelectionOption("select") - .store(&sel_) - .onlyAtoms() - .description("Selection of particles to write to the file")); + options->addOption(SelectionOption("select").store(&sel_).onlyAtoms().description( + "Selection of particles to write to the file")); options->addOption(FileNameOption("o") - .filetype(eftTrajectory) - .outputFile() - .store(&name_).defaultBasename("trajout") - .required() - .description("Output trajectory")); + .filetype(eftTrajectory) + .outputFile() + .store(&name_) + .defaultBasename("trajout") + .required() + .description("Output trajectory")); requirementsBuilder_.initOptions(options); settings->setHelpText(desc); } -void -ConvertTrj::optionsFinished(TrajectoryAnalysisSettings * settings) +void ConvertTrj::optionsFinished(TrajectoryAnalysisSettings* settings) { int frameFlags = TRX_NEED_X; @@ -141,41 +133,27 @@ ConvertTrj::optionsFinished(TrajectoryAnalysisSettings * settings) } -void -ConvertTrj::initAnalysis(const TrajectoryAnalysisSettings & /*settings*/, - const TopologyInformation &top) +void ConvertTrj::initAnalysis(const TrajectoryAnalysisSettings& /*settings*/, const TopologyInformation& top) { - output_ = createTrajectoryFrameWriter(top.mtop(), - sel_, - name_, + output_ = createTrajectoryFrameWriter(top.mtop(), sel_, name_, top.hasTopology() ? top.copyAtoms() : nullptr, requirementsBuilder_.process()); } -void -ConvertTrj::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc * /* pbc */, - TrajectoryAnalysisModuleData * /*pdata*/) +void ConvertTrj::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* /* pbc */, TrajectoryAnalysisModuleData* /*pdata*/) { output_->prepareAndWriteFrame(frnr, fr); } -void -ConvertTrj::finishAnalysis(int /*nframes*/) -{ -} +void ConvertTrj::finishAnalysis(int /*nframes*/) {} +void ConvertTrj::writeOutput() {} -void -ConvertTrj::writeOutput() -{ -} - -} // namespace +} // namespace const char ConvertTrjInfo::name[] = "convert-trj"; -const char ConvertTrjInfo::shortDescription[] = - "Converts between different trajectory types"; +const char ConvertTrjInfo::shortDescription[] = "Converts between different trajectory types"; TrajectoryAnalysisModulePointer ConvertTrjInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/convert_trj.h b/src/gromacs/trajectoryanalysis/modules/convert_trj.h index 02c752952e..ffce0dc84f 100644 --- a/src/gromacs/trajectoryanalysis/modules/convert_trj.h +++ b/src/gromacs/trajectoryanalysis/modules/convert_trj.h @@ -52,10 +52,10 @@ namespace analysismodules class ConvertTrjInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/distance.cpp b/src/gromacs/trajectoryanalysis/modules/distance.cpp index ff4bffc430..b23cd8ff27 100644 --- a/src/gromacs/trajectoryanalysis/modules/distance.cpp +++ b/src/gromacs/trajectoryanalysis/modules/distance.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,47 +75,46 @@ namespace class Distance : public TrajectoryAnalysisModule { - public: - Distance(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - SelectionList sel_; - std::string fnAverage_; - std::string fnAll_; - std::string fnXYZ_; - std::string fnHistogram_; - std::string fnAllStats_; - double meanLength_; - double lengthDev_; - double binWidth_; - - AnalysisData distances_; - AnalysisData xyz_; - AnalysisDataAverageModulePointer summaryStatsModule_; - AnalysisDataAverageModulePointer allStatsModule_; - AnalysisDataFrameAverageModulePointer averageModule_; - AnalysisDataSimpleHistogramModulePointer histogramModule_; - - // Copy and assign disallowed by base. +public: + Distance(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + SelectionList sel_; + std::string fnAverage_; + std::string fnAll_; + std::string fnXYZ_; + std::string fnHistogram_; + std::string fnAllStats_; + double meanLength_; + double lengthDev_; + double binWidth_; + + AnalysisData distances_; + AnalysisData xyz_; + AnalysisDataAverageModulePointer summaryStatsModule_; + AnalysisDataAverageModulePointer allStatsModule_; + AnalysisDataFrameAverageModulePointer averageModule_; + AnalysisDataSimpleHistogramModulePointer histogramModule_; + + // Copy and assign disallowed by base. }; -Distance::Distance() - : meanLength_(0.1), lengthDev_(1.0), binWidth_(0.001), - summaryStatsModule_(std::make_unique()), - allStatsModule_(std::make_unique()), - averageModule_(std::make_unique()), - histogramModule_(std::make_unique()) +Distance::Distance() : + meanLength_(0.1), + lengthDev_(1.0), + binWidth_(0.001), + summaryStatsModule_(std::make_unique()), + allStatsModule_(std::make_unique()), + averageModule_(std::make_unique()), + histogramModule_(std::make_unique()) { summaryStatsModule_->setAverageDataSets(true); distances_.addModule(summaryStatsModule_); @@ -131,10 +131,9 @@ Distance::Distance() } -void -Distance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Distance::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] calculates distances between pairs of positions", "as a function of time. Each selection specifies an independent set", "of distances to calculate. Each selection should consist of pairs", @@ -158,61 +157,76 @@ Distance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *se settings->setHelpText(desc); - options->addOption(FileNameOption("oav").filetype(eftPlot).outputFile() - .store(&fnAverage_).defaultBasename("distave") - .description("Average distances as function of time")); - options->addOption(FileNameOption("oall").filetype(eftPlot).outputFile() - .store(&fnAll_).defaultBasename("dist") - .description("All distances as function of time")); - options->addOption(FileNameOption("oxyz").filetype(eftPlot).outputFile() - .store(&fnXYZ_).defaultBasename("distxyz") - .description("Distance components as function of time")); - options->addOption(FileNameOption("oh").filetype(eftPlot).outputFile() - .store(&fnHistogram_).defaultBasename("disthist") - .description("Histogram of the distances")); - options->addOption(FileNameOption("oallstat").filetype(eftPlot).outputFile() - .store(&fnAllStats_).defaultBasename("diststat") - .description("Statistics for individual distances")); - options->addOption(SelectionOption("select").storeVector(&sel_) - .required().dynamicMask().multiValue() - .description("Position pairs to calculate distances for")); + options->addOption(FileNameOption("oav") + .filetype(eftPlot) + .outputFile() + .store(&fnAverage_) + .defaultBasename("distave") + .description("Average distances as function of time")); + options->addOption(FileNameOption("oall") + .filetype(eftPlot) + .outputFile() + .store(&fnAll_) + .defaultBasename("dist") + .description("All distances as function of time")); + options->addOption(FileNameOption("oxyz") + .filetype(eftPlot) + .outputFile() + .store(&fnXYZ_) + .defaultBasename("distxyz") + .description("Distance components as function of time")); + options->addOption(FileNameOption("oh") + .filetype(eftPlot) + .outputFile() + .store(&fnHistogram_) + .defaultBasename("disthist") + .description("Histogram of the distances")); + options->addOption(FileNameOption("oallstat") + .filetype(eftPlot) + .outputFile() + .store(&fnAllStats_) + .defaultBasename("diststat") + .description("Statistics for individual distances")); + options->addOption( + SelectionOption("select").storeVector(&sel_).required().dynamicMask().multiValue().description( + "Position pairs to calculate distances for")); // TODO: Extend the histogramming implementation to allow automatic // extension of the histograms to cover the data, removing the need for // the first two options. - options->addOption(DoubleOption("len").store(&meanLength_) - .description("Mean distance for histogramming")); - options->addOption(DoubleOption("tol").store(&lengthDev_) - .description("Width of full distribution as fraction of [TT]-len[tt]")); - options->addOption(DoubleOption("binw").store(&binWidth_) - .description("Bin width for histogramming")); + options->addOption( + DoubleOption("len").store(&meanLength_).description("Mean distance for histogramming")); + options->addOption( + DoubleOption("tol").store(&lengthDev_).description("Width of full distribution as fraction of [TT]-len[tt]")); + options->addOption( + DoubleOption("binw").store(&binWidth_).description("Bin width for histogramming")); } /*! \brief * Checks that selections conform to the expectations of the tool. */ -void checkSelections(const SelectionList &sel) +void checkSelections(const SelectionList& sel) { for (size_t g = 0; g < sel.size(); ++g) { if (sel[g].posCount() % 2 != 0) { std::string message = formatString( - "Selection '%s' does not evaluate into an even number of positions " - "(there are %d positions)", - sel[g].name(), sel[g].posCount()); + "Selection '%s' does not evaluate into an even number of positions " + "(there are %d positions)", + sel[g].name(), sel[g].posCount()); GMX_THROW(InconsistentInputError(message)); } if (sel[g].isDynamic()) { for (int i = 0; i < sel[g].posCount(); i += 2) { - if (sel[g].position(i).selected() != sel[g].position(i+1).selected()) + if (sel[g].position(i).selected() != sel[g].position(i + 1).selected()) { - std::string message = - formatString("Dynamic selection %d does not select " - "a consistent set of pairs over the frames", - static_cast(g + 1)); + std::string message = formatString( + "Dynamic selection %d does not select " + "a consistent set of pairs over the frames", + static_cast(g + 1)); GMX_THROW(InconsistentInputError(message)); } } @@ -221,9 +235,7 @@ void checkSelections(const SelectionList &sel) } -void -Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation & /*top*/) +void Distance::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& /*top*/) { checkSelections(sel_); @@ -237,13 +249,11 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, } const double histogramMin = (1.0 - lengthDev_) * meanLength_; const double histogramMax = (1.0 + lengthDev_) * meanLength_; - histogramModule_->init(histogramFromRange(histogramMin, histogramMax) - .binWidth(binWidth_).includeAll()); + histogramModule_->init(histogramFromRange(histogramMin, histogramMax).binWidth(binWidth_).includeAll()); if (!fnAverage_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAverage_); plotm->setTitle("Average distance"); plotm->setXAxisIsTime(); @@ -257,8 +267,7 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnAll_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAll_); plotm->setTitle("Distance"); plotm->setXAxisIsTime(); @@ -269,8 +278,7 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnXYZ_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnXYZ_); plotm->setTitle("Distance"); plotm->setXAxisIsTime(); @@ -281,8 +289,7 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnHistogram_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnHistogram_); plotm->setTitle("Distance histogram"); plotm->setXLabel("Distance (nm)"); @@ -296,8 +303,7 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnAllStats_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAllStats_); plotm->setErrorsAsSeparateColumn(true); plotm->setTitle("Statistics for individual distances"); @@ -314,13 +320,11 @@ Distance::initAnalysis(const TrajectoryAnalysisSettings &settings, } -void -Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void Distance::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { AnalysisDataHandle distHandle = pdata->dataHandle(distances_); AnalysisDataHandle xyzHandle = pdata->dataHandle(xyz_); - const SelectionList &sel = pdata->parallelSelections(sel_); + const SelectionList& sel = pdata->parallelSelections(sel_); checkSelections(sel); @@ -332,8 +336,8 @@ Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, xyzHandle.selectDataSet(g); for (int i = 0, n = 0; i < sel[g].posCount(); i += 2, ++n) { - const SelectionPosition &p1 = sel[g].position(i); - const SelectionPosition &p2 = sel[g].position(i+1); + const SelectionPosition& p1 = sel[g].position(i); + const SelectionPosition& p2 = sel[g].position(i + 1); rvec dx; if (pbc != nullptr) { @@ -346,7 +350,7 @@ Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, real dist = norm(dx); bool bPresent = p1.selected() && p2.selected(); distHandle.setPoint(n, dist, bPresent); - xyzHandle.setPoints(n*3, 3, dx, bPresent); + xyzHandle.setPoints(n * 3, 3, dx, bPresent); } } distHandle.finishFrame(); @@ -354,37 +358,31 @@ Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } -void -Distance::finishAnalysis(int /*nframes*/) +void Distance::finishAnalysis(int /*nframes*/) { - AbstractAverageHistogram &averageHistogram = histogramModule_->averager(); + AbstractAverageHistogram& averageHistogram = histogramModule_->averager(); averageHistogram.normalizeProbability(); averageHistogram.done(); } -void -Distance::writeOutput() +void Distance::writeOutput() { SelectionList::const_iterator sel; int index; for (sel = sel_.begin(), index = 0; sel != sel_.end(); ++sel, ++index) { printf("%s:\n", sel->name()); - printf(" Number of samples: %d\n", - summaryStatsModule_->sampleCount(index, 0)); - printf(" Average distance: %-8.5f nm\n", - summaryStatsModule_->average(index, 0)); - printf(" Standard deviation: %-8.5f nm\n", - summaryStatsModule_->standardDeviation(index, 0)); + printf(" Number of samples: %d\n", summaryStatsModule_->sampleCount(index, 0)); + printf(" Average distance: %-8.5f nm\n", summaryStatsModule_->average(index, 0)); + printf(" Standard deviation: %-8.5f nm\n", summaryStatsModule_->standardDeviation(index, 0)); } } -} // namespace +} // namespace const char DistanceInfo::name[] = "distance"; -const char DistanceInfo::shortDescription[] = - "Calculate distances between pairs of positions"; +const char DistanceInfo::shortDescription[] = "Calculate distances between pairs of positions"; TrajectoryAnalysisModulePointer DistanceInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/distance.h b/src/gromacs/trajectoryanalysis/modules/distance.h index 519176d577..571a5951cf 100644 --- a/src/gromacs/trajectoryanalysis/modules/distance.h +++ b/src/gromacs/trajectoryanalysis/modules/distance.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class DistanceInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/extract_cluster.cpp b/src/gromacs/trajectoryanalysis/modules/extract_cluster.cpp index c8fb600812..6fdfd8f9d6 100644 --- a/src/gromacs/trajectoryanalysis/modules/extract_cluster.cpp +++ b/src/gromacs/trajectoryanalysis/modules/extract_cluster.cpp @@ -72,41 +72,35 @@ namespace class ExtractCluster : public TrajectoryAnalysisModule { - public: - ExtractCluster(); - - ~ExtractCluster() override; - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - void analyzeFrame(int frameNumber, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - //! Storage of objects that handle output files. - std::vector writers_; - //! Selection used for output. - Selection sel_; - //! Name for output file. - std::string outputNamePrefix_; - //! Name for index file. - std::string indexFileName_; - //! Storage of requirements for creating output files. - OutputRequirementOptionDirector requirementsBuilder_; - //! Stores the index information for the clusters. TODO refactor this! - t_cluster_ndx *clusterIndex_ = nullptr; - +public: + ExtractCluster(); + + ~ExtractCluster() override; + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + void analyzeFrame(int frameNumber, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + //! Storage of objects that handle output files. + std::vector writers_; + //! Selection used for output. + Selection sel_; + //! Name for output file. + std::string outputNamePrefix_; + //! Name for index file. + std::string indexFileName_; + //! Storage of requirements for creating output files. + OutputRequirementOptionDirector requirementsBuilder_; + //! Stores the index information for the clusters. TODO refactor this! + t_cluster_ndx* clusterIndex_ = nullptr; }; -ExtractCluster::ExtractCluster() -{ -} +ExtractCluster::ExtractCluster() {} ExtractCluster::~ExtractCluster() { @@ -131,10 +125,9 @@ ExtractCluster::~ExtractCluster() } -void -ExtractCluster::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void ExtractCluster::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] can be used to extract trajectory frames that correspond to clusters ", "obtained from running gmx cluster with the -clndx option.", "The module supports writing all GROMACS supported trajectory file formats.", @@ -146,32 +139,32 @@ ExtractCluster::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettin }; options->addOption(FileNameOption("clusters") - .filetype(eftIndex) - .inputFile() - .required() - .store(&indexFileName_) - .defaultBasename("cluster") - .description("Name of index file containing frame indices for each cluster, obtained from gmx cluster -clndx.")); - - options->addOption(SelectionOption("select") - .store(&sel_) - .onlyAtoms() - .description("Selection of atoms to write to the file")); + .filetype(eftIndex) + .inputFile() + .required() + .store(&indexFileName_) + .defaultBasename("cluster") + .description("Name of index file containing frame indices for each " + "cluster, obtained from gmx cluster -clndx.")); + + options->addOption(SelectionOption("select").store(&sel_).onlyAtoms().description( + "Selection of atoms to write to the file")); options->addOption(FileNameOption("o") - .filetype(eftTrajectory) - .outputFile() - .store(&outputNamePrefix_).defaultBasename("trajout") - .required() - .description("Prefix for the name of the trajectory file written for each cluster.")); + .filetype(eftTrajectory) + .outputFile() + .store(&outputNamePrefix_) + .defaultBasename("trajout") + .required() + .description("Prefix for the name of the trajectory file written " + "for each cluster.")); requirementsBuilder_.initOptions(options); settings->setHelpText(desc); } -void -ExtractCluster::optionsFinished(TrajectoryAnalysisSettings * settings) +void ExtractCluster::optionsFinished(TrajectoryAnalysisSettings* settings) { int frameFlags = TRX_NEED_X; @@ -183,27 +176,24 @@ ExtractCluster::optionsFinished(TrajectoryAnalysisSettings * settings) } -void -ExtractCluster::initAnalysis(const TrajectoryAnalysisSettings & /*settings*/, - const TopologyInformation &top) +void ExtractCluster::initAnalysis(const TrajectoryAnalysisSettings& /*settings*/, + const TopologyInformation& top) { int numberOfClusters = clusterIndex_->clust->nr; for (int i = 0; i < numberOfClusters; i++) { - std::string outputName = - Path::concatenateBeforeExtension(outputNamePrefix_, - formatString("_%s", clusterIndex_->grpname[i])); - writers_.emplace_back(createTrajectoryFrameWriter(top.mtop(), - sel_, - outputName, + std::string outputName = Path::concatenateBeforeExtension( + outputNamePrefix_, formatString("_%s", clusterIndex_->grpname[i])); + writers_.emplace_back(createTrajectoryFrameWriter(top.mtop(), sel_, outputName, top.hasTopology() ? top.copyAtoms() : nullptr, requirementsBuilder_.process())); } } -void -ExtractCluster::analyzeFrame(int frameNumber, const t_trxframe &frame, t_pbc * /* pbc */, - TrajectoryAnalysisModuleData * /*pdata*/) +void ExtractCluster::analyzeFrame(int frameNumber, + const t_trxframe& frame, + t_pbc* /* pbc */, + TrajectoryAnalysisModuleData* /*pdata*/) { // modify frame to write out correct number of coords // and actually write out @@ -217,26 +207,18 @@ ExtractCluster::analyzeFrame(int frameNumber, const t_trxframe &frame, t_pbc * / { printf("Frame %d was not found in any cluster!", frameNumber); } - -} - -void -ExtractCluster::finishAnalysis(int /*nframes*/) -{ } +void ExtractCluster::finishAnalysis(int /*nframes*/) {} -void -ExtractCluster::writeOutput() -{ -} +void ExtractCluster::writeOutput() {} -} // namespace +} // namespace -const char ExtractClusterInfo::name[] = "extract-cluster"; +const char ExtractClusterInfo::name[] = "extract-cluster"; const char ExtractClusterInfo::shortDescription[] = - "Allows extracting frames corresponding to clusters from trajectory"; + "Allows extracting frames corresponding to clusters from trajectory"; TrajectoryAnalysisModulePointer ExtractClusterInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/extract_cluster.h b/src/gromacs/trajectoryanalysis/modules/extract_cluster.h index cdd9f49154..d9cf9dca33 100644 --- a/src/gromacs/trajectoryanalysis/modules/extract_cluster.h +++ b/src/gromacs/trajectoryanalysis/modules/extract_cluster.h @@ -53,10 +53,10 @@ namespace analysismodules class ExtractClusterInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/freevolume.cpp b/src/gromacs/trajectoryanalysis/modules/freevolume.cpp index 5c23093395..1b9362b11d 100644 --- a/src/gromacs/trajectoryanalysis/modules/freevolume.cpp +++ b/src/gromacs/trajectoryanalysis/modules/freevolume.cpp @@ -89,44 +89,40 @@ namespace */ class FreeVolume : public TrajectoryAnalysisModule { - public: - FreeVolume(); - ~FreeVolume() override {} - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - std::string fnFreevol_; - Selection sel_; - AnalysisData data_; - AnalysisDataAverageModulePointer adata_; - - int nmol_; - double mtot_; - double cutoff_; - double probeRadius_; - gmx::DefaultRandomEngine rng_; - int seed_, ninsert_; - AnalysisNeighborhood nb_; - //! The van der Waals radius per atom - std::vector vdw_radius_; - - // Copy and assign disallowed by base. +public: + FreeVolume(); + ~FreeVolume() override {} + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + std::string fnFreevol_; + Selection sel_; + AnalysisData data_; + AnalysisDataAverageModulePointer adata_; + + int nmol_; + double mtot_; + double cutoff_; + double probeRadius_; + gmx::DefaultRandomEngine rng_; + int seed_, ninsert_; + AnalysisNeighborhood nb_; + //! The van der Waals radius per atom + std::vector vdw_radius_; + + // Copy and assign disallowed by base. }; // Constructor. Here it is important to initialize the pointer to // subclasses that are elements of the main class. Here we have only // one. The type of this depends on what kind of tool you need. // Here we only have simple value/time kind of data. -FreeVolume::FreeVolume() - : adata_(new AnalysisDataAverageModule()) +FreeVolume::FreeVolume() : adata_(new AnalysisDataAverageModule()) { // We only compute two numbers per frame data_.setColumnCount(0, 2); @@ -141,11 +137,9 @@ FreeVolume::FreeVolume() } -void -FreeVolume::initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) +void FreeVolume::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] calculates the free volume in a box as", "a function of time. The free volume is", "plotted as a fraction of the total volume.", @@ -179,39 +173,38 @@ FreeVolume::initOptions(IOptionsContainer *options, settings->setHelpText(desc); // Add option for optional output file - options->addOption(FileNameOption("o").filetype(eftPlot).outputFile() - .store(&fnFreevol_).defaultBasename("freevolume") - .description("Computed free volume")); + options->addOption(FileNameOption("o") + .filetype(eftPlot) + .outputFile() + .store(&fnFreevol_) + .defaultBasename("freevolume") + .description("Computed free volume")); // Add option for selecting a subset of atoms - options->addOption(SelectionOption("select") - .store(&sel_).defaultSelectionText("all") - .onlyAtoms() - .description("Atoms that are considered as part of the excluded volume")); + options->addOption( + SelectionOption("select").store(&sel_).defaultSelectionText("all").onlyAtoms().description( + "Atoms that are considered as part of the excluded volume")); // Add option for the probe radius and initialize it - options->addOption(DoubleOption("radius").store(&probeRadius_) - .description("Radius of the probe to be inserted (nm, 0 yields the true free volume)")); + options->addOption( + DoubleOption("radius").store(&probeRadius_).description("Radius of the probe to be inserted (nm, 0 yields the true free volume)")); // Add option for the random number seed and initialize it to // generate a value automatically - options->addOption(IntegerOption("seed").store(&seed_) - .description("Seed for random number generator (0 means generate).")); + options->addOption(IntegerOption("seed").store(&seed_).description( + "Seed for random number generator (0 means generate).")); // Add option to determine number of insertion trials per frame - options->addOption(IntegerOption("ninsert").store(&ninsert_) - .description("Number of probe insertions per cubic nm to try for each frame in the trajectory.")); + options->addOption(IntegerOption("ninsert").store(&ninsert_).description( + "Number of probe insertions per cubic nm to try for each frame in the trajectory.")); // Control input settings - settings->setFlags(TrajectoryAnalysisSettings::efRequireTop | - TrajectoryAnalysisSettings::efNoUserPBC); + settings->setFlags(TrajectoryAnalysisSettings::efRequireTop | TrajectoryAnalysisSettings::efNoUserPBC); settings->setPBC(true); } -void -FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) +void FreeVolume::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) { // Add the module that will contain the averaging and the time series // for our calculation @@ -235,7 +228,7 @@ FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, cutoff_ = 0; int nnovdw = 0; AtomProperties aps; - auto atoms = top.copyAtoms(); + auto atoms = top.copyAtoms(); // Compute total mass mtot_ = 0; @@ -258,10 +251,7 @@ FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, // Lookup the Van der Waals radius of this atom int resnr = atoms->atom[i].resind; - if (aps.setAtomProperty(epropVDW, - *(atoms->resinfo[resnr].name), - *(atoms->atomname[i]), - &value)) + if (aps.setAtomProperty(epropVDW, *(atoms->resinfo[resnr].name), *(atoms->atomname[i]), &value)) { vdw_radius_.push_back(value); if (value > cutoff_) @@ -275,8 +265,7 @@ FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, if (nnovdw < maxnovdw) { fprintf(stderr, "Could not determine VDW radius for %s-%s. Set to zero.\n", - *(atoms->resinfo[resnr].name), - *(atoms->atomname[i])); + *(atoms->resinfo[resnr].name), *(atoms->atomname[i])); } vdw_radius_.push_back(0.0); } @@ -310,13 +299,11 @@ FreeVolume::initAnalysis(const TrajectoryAnalysisSettings &settings, nb_.setCutoff(cutoff_); } -void -FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void FreeVolume::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { - AnalysisDataHandle dh = pdata->dataHandle(data_); - const Selection &sel = pdata->parallelSelection(sel_); - gmx::UniformRealDistribution dist; + AnalysisDataHandle dh = pdata->dataHandle(data_); + const Selection& sel = pdata->parallelSelection(sel_); + gmx::UniformRealDistribution dist; GMX_RELEASE_ASSERT(nullptr != pbc, "You have no periodic boundary conditions"); @@ -325,7 +312,7 @@ FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, // Compute volume and number of insertions to perform real V = det(fr.box); - int Ninsert = static_cast(ninsert_*V); + int Ninsert = static_cast(ninsert_ * V); // Use neighborsearching tools! AnalysisNeighborhoodSearch nbsearch = nb_.initSearch(pbc, sel); @@ -355,9 +342,7 @@ FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, pbc_dx(pbc, ins, sel.position(jp).x(), dx); // See whether the distance is smaller than allowed - bOverlap = (norm(dx) < - probeRadius_+vdw_radius_[sel.position(jp).refId()]); - + bOverlap = (norm(dx) < probeRadius_ + vdw_radius_[sel.position(jp).refId()]); } if (!bOverlap) @@ -370,7 +355,7 @@ FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, double frac = 0; if (Ninsert > 0) { - frac = (100.0*NinsTot)/Ninsert; + frac = (100.0 * NinsTot) / Ninsert; } // Add the free volume fraction to the data set in column 0 dh.setPoint(0, frac); @@ -382,15 +367,13 @@ FreeVolume::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } -void -FreeVolume::finishAnalysis(int /* nframes */) +void FreeVolume::finishAnalysis(int /* nframes */) { please_cite(stdout, "Bondi1964a"); please_cite(stdout, "Lourenco2013a"); } -void -FreeVolume::writeOutput() +void FreeVolume::writeOutput() { // Final results come from statistics module in analysis framework double FVaver = adata_->average(0, 0); @@ -403,30 +386,27 @@ FreeVolume::writeOutput() printf("Number of molecules %d total mass %.2f Dalton\n", nmol_, mtot_); double RhoAver = mtot_ / (Vaver * 1e-24 * AVOGADRO); - double RhoError = gmx::square(RhoAver / Vaver)*Verror; - printf("Average molar mass: %.2f Dalton\n", mtot_/nmol_); + double RhoError = gmx::square(RhoAver / Vaver) * Verror; + printf("Average molar mass: %.2f Dalton\n", mtot_ / nmol_); - double VmAver = Vaver/nmol_; - double VmError = Verror/nmol_; + double VmAver = Vaver / nmol_; + double VmError = Verror / nmol_; printf("Density rho: %.2f +/- %.2f nm^3\n", RhoAver, RhoError); - printf("Molecular volume Vm assuming homogeneity: %.4f +/- %.4f nm^3\n", - VmAver, VmError); + printf("Molecular volume Vm assuming homogeneity: %.4f +/- %.4f nm^3\n", VmAver, VmError); - double VvdWaver = (1-FVaver/100)*VmAver; + double VvdWaver = (1 - FVaver / 100) * VmAver; double VvdWerror = 0; - printf("Molecular van der Waals volume assuming homogeneity: %.4f +/- %.4f nm^3\n", - VvdWaver, VvdWerror); + printf("Molecular van der Waals volume assuming homogeneity: %.4f +/- %.4f nm^3\n", VvdWaver, VvdWerror); - double FFVaver = 1-1.3*((100-FVaver)/100); - double FFVerror = (FVerror/FVaver)*FFVaver; + double FFVaver = 1 - 1.3 * ((100 - FVaver) / 100); + double FFVerror = (FVerror / FVaver) * FFVaver; printf("Fractional free volume %.3f +/- %.3f\n", FFVaver, FFVerror); } -} // namespace +} // namespace const char FreeVolumeInfo::name[] = "freevolume"; -const char FreeVolumeInfo::shortDescription[] = - "Calculate free volume"; +const char FreeVolumeInfo::shortDescription[] = "Calculate free volume"; TrajectoryAnalysisModulePointer FreeVolumeInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/freevolume.h b/src/gromacs/trajectoryanalysis/modules/freevolume.h index ba24de0951..a9f64fba3d 100644 --- a/src/gromacs/trajectoryanalysis/modules/freevolume.h +++ b/src/gromacs/trajectoryanalysis/modules/freevolume.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class FreeVolumeInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/pairdist.cpp b/src/gromacs/trajectoryanalysis/modules/pairdist.cpp index 438111e0c0..41109ee548 100644 --- a/src/gromacs/trajectoryanalysis/modules/pairdist.cpp +++ b/src/gromacs/trajectoryanalysis/modules/pairdist.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -94,92 +94,92 @@ enum GroupType }; //! Strings corresponding to DistanceType. -const char *const c_distanceTypes[] = { "min", "max" }; +const char* const c_distanceTypes[] = { "min", "max" }; //! Strings corresponding to GroupType. -const char *const c_groupTypes[] = { "all", "res", "mol", "none" }; +const char* const c_groupTypes[] = { "all", "res", "mol", "none" }; /*! \brief * Implements `gmx pairdist` trajectory analysis module. */ class PairDistance : public TrajectoryAnalysisModule { - public: - PairDistance(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - - TrajectoryAnalysisModuleDataPointer startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - /*! \brief - * Computed distances as a function of time. - * - * There is one data set for each selection in `sel_`. - * Within each data set, there is one column for each distance to be - * computed, as explained in the `-h` text. - */ - AnalysisData distances_; - - /*! \brief - * Reference selection to compute distances to. - * - * mappedId() identifies the group (of type `refGroupType_`) into which - * each position belogs. - */ - Selection refSel_; - /*! \brief - * Selections to compute distances from. - * - * mappedId() identifies the group (of type `selGroupType_`) into which - * each position belogs. - */ - SelectionList sel_; - - std::string fnDist_; - - double cutoff_; - DistanceType distanceType_; - GroupType refGroupType_; - GroupType selGroupType_; - - //! Number of groups in `refSel_`. - int refGroupCount_; - //! Maximum number of pairs of groups for one selection. - int maxGroupCount_; - //! Initial squared distance for distance accumulation. - real initialDist2_; - //! Cutoff squared for use in the actual calculation. - real cutoff2_; - - //! Neighborhood search object for the pair search. - AnalysisNeighborhood nb_; - - // Copy and assign disallowed by base. +public: + PairDistance(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + + TrajectoryAnalysisModuleDataPointer startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + /*! \brief + * Computed distances as a function of time. + * + * There is one data set for each selection in `sel_`. + * Within each data set, there is one column for each distance to be + * computed, as explained in the `-h` text. + */ + AnalysisData distances_; + + /*! \brief + * Reference selection to compute distances to. + * + * mappedId() identifies the group (of type `refGroupType_`) into which + * each position belogs. + */ + Selection refSel_; + /*! \brief + * Selections to compute distances from. + * + * mappedId() identifies the group (of type `selGroupType_`) into which + * each position belogs. + */ + SelectionList sel_; + + std::string fnDist_; + + double cutoff_; + DistanceType distanceType_; + GroupType refGroupType_; + GroupType selGroupType_; + + //! Number of groups in `refSel_`. + int refGroupCount_; + //! Maximum number of pairs of groups for one selection. + int maxGroupCount_; + //! Initial squared distance for distance accumulation. + real initialDist2_; + //! Cutoff squared for use in the actual calculation. + real cutoff2_; + + //! Neighborhood search object for the pair search. + AnalysisNeighborhood nb_; + + // Copy and assign disallowed by base. }; -PairDistance::PairDistance() - : cutoff_(0.0), distanceType_(eDistanceType_Min), - refGroupType_(eGroupType_All), selGroupType_(eGroupType_All), - refGroupCount_(0), maxGroupCount_(0), initialDist2_(0.0), cutoff2_(0.0) +PairDistance::PairDistance() : + cutoff_(0.0), + distanceType_(eDistanceType_Min), + refGroupType_(eGroupType_All), + selGroupType_(eGroupType_All), + refGroupCount_(0), + maxGroupCount_(0), + initialDist2_(0.0), + cutoff2_(0.0) { registerAnalysisDataset(&distances_, "dist"); } -void -PairDistance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void PairDistance::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] calculates pairwise distances between one reference", "selection (given with [TT]-ref[tt]) and one or more other selections", "(given with [TT]-sel[tt]). It can calculate either the minimum", @@ -216,46 +216,53 @@ PairDistance::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings settings->setHelpText(desc); - options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required() - .store(&fnDist_).defaultBasename("dist") - .description("Distances as function of time")); - - options->addOption(DoubleOption("cutoff").store(&cutoff_) - .description("Maximum distance to consider")); - options->addOption(EnumOption("type").store(&distanceType_) - .enumValue(c_distanceTypes) - .description("Type of distances to calculate")); - options->addOption(EnumOption("refgrouping").store(&refGroupType_) - .enumValue(c_groupTypes) - .description("Grouping of -ref positions to compute the min/max over")); - options->addOption(EnumOption("selgrouping").store(&selGroupType_) - .enumValue(c_groupTypes) - .description("Grouping of -sel positions to compute the min/max over")); - - options->addOption(SelectionOption("ref").store(&refSel_).required() - .description("Reference positions to calculate distances from")); - options->addOption(SelectionOption("sel").storeVector(&sel_).required().multiValue() - .description("Positions to calculate distances for")); + options->addOption(FileNameOption("o") + .filetype(eftPlot) + .outputFile() + .required() + .store(&fnDist_) + .defaultBasename("dist") + .description("Distances as function of time")); + + options->addOption( + DoubleOption("cutoff").store(&cutoff_).description("Maximum distance to consider")); + options->addOption(EnumOption("type") + .store(&distanceType_) + .enumValue(c_distanceTypes) + .description("Type of distances to calculate")); + options->addOption( + EnumOption("refgrouping") + .store(&refGroupType_) + .enumValue(c_groupTypes) + .description("Grouping of -ref positions to compute the min/max over")); + options->addOption( + EnumOption("selgrouping") + .store(&selGroupType_) + .enumValue(c_groupTypes) + .description("Grouping of -sel positions to compute the min/max over")); + + options->addOption(SelectionOption("ref").store(&refSel_).required().description( + "Reference positions to calculate distances from")); + options->addOption(SelectionOption("sel").storeVector(&sel_).required().multiValue().description( + "Positions to calculate distances for")); } //! Helper function to initialize the grouping for a selection. -int initSelectionGroups(Selection *sel, const gmx_mtop_t *top, int type) +int initSelectionGroups(Selection* sel, const gmx_mtop_t* top, int type) { e_index_t indexType = INDEX_UNKNOWN; switch (type) { - case eGroupType_All: indexType = INDEX_ALL; break; - case eGroupType_Residue: indexType = INDEX_RES; break; + case eGroupType_All: indexType = INDEX_ALL; break; + case eGroupType_Residue: indexType = INDEX_RES; break; case eGroupType_Molecule: indexType = INDEX_MOL; break; - case eGroupType_None: indexType = INDEX_ATOM; break; + case eGroupType_None: indexType = INDEX_ATOM; break; } return sel->initOriginalIdsToGroup(top, indexType); } -void -PairDistance::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) +void PairDistance::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) { refGroupCount_ = initSelectionGroups(&refSel_, top.mtop(), refGroupType_); @@ -263,17 +270,15 @@ PairDistance::initAnalysis(const TrajectoryAnalysisSettings &settings, distances_.setDataSetCount(sel_.size()); for (size_t i = 0; i < sel_.size(); ++i) { - const int selGroupCount - = initSelectionGroups(&sel_[i], top.mtop(), selGroupType_); - const int columnCount = refGroupCount_ * selGroupCount; - maxGroupCount_ = std::max(maxGroupCount_, columnCount); + const int selGroupCount = initSelectionGroups(&sel_[i], top.mtop(), selGroupType_); + const int columnCount = refGroupCount_ * selGroupCount; + maxGroupCount_ = std::max(maxGroupCount_, columnCount); distances_.setColumnCount(i, columnCount); } if (!fnDist_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnDist_); if (distanceType_ == eDistanceType_Max) { @@ -317,100 +322,95 @@ PairDistance::initAnalysis(const TrajectoryAnalysisSettings &settings, */ class PairDistanceModuleData : public TrajectoryAnalysisModuleData { - public: - /*! \brief - * Reserves memory for the frame-local data. - */ - PairDistanceModuleData(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections, - int refGroupCount, - const Selection &refSel, - int maxGroupCount) - : TrajectoryAnalysisModuleData(module, opt, selections) +public: + /*! \brief + * Reserves memory for the frame-local data. + */ + PairDistanceModuleData(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections, + int refGroupCount, + const Selection& refSel, + int maxGroupCount) : + TrajectoryAnalysisModuleData(module, opt, selections) + { + distArray_.resize(maxGroupCount); + countArray_.resize(maxGroupCount); + refCountArray_.resize(refGroupCount); + if (!refSel.isDynamic()) { - distArray_.resize(maxGroupCount); - countArray_.resize(maxGroupCount); - refCountArray_.resize(refGroupCount); - if (!refSel.isDynamic()) - { - initRefCountArray(refSel); - } + initRefCountArray(refSel); } + } - void finish() override { finishDataHandles(); } + void finish() override { finishDataHandles(); } - /*! \brief - * Computes the number of positions in each group in \p refSel - * and stores them into `refCountArray_`. - */ - void initRefCountArray(const Selection &refSel) + /*! \brief + * Computes the number of positions in each group in \p refSel + * and stores them into `refCountArray_`. + */ + void initRefCountArray(const Selection& refSel) + { + std::fill(refCountArray_.begin(), refCountArray_.end(), 0); + int refPos = 0; + while (refPos < refSel.posCount()) { - std::fill(refCountArray_.begin(), refCountArray_.end(), 0); - int refPos = 0; - while (refPos < refSel.posCount()) + const int refIndex = refSel.position(refPos).mappedId(); + const int startPos = refPos; + ++refPos; + while (refPos < refSel.posCount() && refSel.position(refPos).mappedId() == refIndex) { - const int refIndex = refSel.position(refPos).mappedId(); - const int startPos = refPos; ++refPos; - while (refPos < refSel.posCount() - && refSel.position(refPos).mappedId() == refIndex) - { - ++refPos; - } - refCountArray_[refIndex] = refPos - startPos; } + refCountArray_[refIndex] = refPos - startPos; } + } - /*! \brief - * Squared distance between each group - * - * One entry for each group pair for the current selection. - * Enough memory is allocated to fit the largest calculation selection. - * This is needed to support neighborhood searching, which may not - * return the pairs in order: for each group pair, we need to search - * through all the position pairs and update this array to find the - * minimum/maximum distance between them. - */ - std::vector distArray_; - /*! \brief - * Number of pairs within the cutoff that have contributed to the value - * in `distArray_`. - * - * This is needed to identify whether there were any pairs inside the - * cutoff and whether there were additional pairs outside the cutoff - * that were not covered by the neihborhood search. - */ - std::vector countArray_; - /*! \brief - * Number of positions within each reference group. - * - * This is used to more efficiently compute the total number of pairs - * (for comparison with `countArray_`), as otherwise these numbers - * would need to be recomputed for each selection. - */ - std::vector refCountArray_; + /*! \brief + * Squared distance between each group + * + * One entry for each group pair for the current selection. + * Enough memory is allocated to fit the largest calculation selection. + * This is needed to support neighborhood searching, which may not + * return the pairs in order: for each group pair, we need to search + * through all the position pairs and update this array to find the + * minimum/maximum distance between them. + */ + std::vector distArray_; + /*! \brief + * Number of pairs within the cutoff that have contributed to the value + * in `distArray_`. + * + * This is needed to identify whether there were any pairs inside the + * cutoff and whether there were additional pairs outside the cutoff + * that were not covered by the neihborhood search. + */ + std::vector countArray_; + /*! \brief + * Number of positions within each reference group. + * + * This is used to more efficiently compute the total number of pairs + * (for comparison with `countArray_`), as otherwise these numbers + * would need to be recomputed for each selection. + */ + std::vector refCountArray_; }; -TrajectoryAnalysisModuleDataPointer PairDistance::startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) +TrajectoryAnalysisModuleDataPointer PairDistance::startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) { - return TrajectoryAnalysisModuleDataPointer( - new PairDistanceModuleData(this, opt, selections, refGroupCount_, - refSel_, maxGroupCount_)); + return TrajectoryAnalysisModuleDataPointer(new PairDistanceModuleData( + this, opt, selections, refGroupCount_, refSel_, maxGroupCount_)); } -void -PairDistance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void PairDistance::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { - AnalysisDataHandle dh = pdata->dataHandle(distances_); - const Selection &refSel = pdata->parallelSelection(refSel_); - const SelectionList &sel = pdata->parallelSelections(sel_); - PairDistanceModuleData &frameData = *static_cast(pdata); - std::vector &distArray = frameData.distArray_; - std::vector &countArray = frameData.countArray_; + AnalysisDataHandle dh = pdata->dataHandle(distances_); + const Selection& refSel = pdata->parallelSelection(refSel_); + const SelectionList& sel = pdata->parallelSelections(sel_); + PairDistanceModuleData& frameData = *static_cast(pdata); + std::vector& distArray = frameData.distArray_; + std::vector& countArray = frameData.countArray_; if (cutoff_ > 0.0 && refSel.isDynamic()) { @@ -422,9 +422,9 @@ PairDistance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, // and it has been initialized in the constructor of the data object. frameData.initRefCountArray(refSel); } - const std::vector &refCountArray = frameData.refCountArray_; + const std::vector& refCountArray = frameData.refCountArray_; - AnalysisNeighborhoodSearch nbsearch = nb_.initSearch(pbc, refSel); + AnalysisNeighborhoodSearch nbsearch = nb_.initSearch(pbc, refSel); dh.startFrame(frnr, fr.time); for (size_t g = 0; g < sel.size(); ++g) { @@ -438,8 +438,8 @@ PairDistance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, AnalysisNeighborhoodPair pair; while (pairSearch.findNextPair(&pair)) { - const SelectionPosition &refPos = refSel.position(pair.refIndex()); - const SelectionPosition &selPos = sel[g].position(pair.testIndex()); + const SelectionPosition& refPos = refSel.position(pair.refIndex()); + const SelectionPosition& selPos = sel[g].position(pair.testIndex()); const int refIndex = refPos.mappedId(); const int selIndex = selPos.mappedId(); const int index = selIndex * refGroupCount_ + refIndex; @@ -482,8 +482,7 @@ PairDistance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, const int selIndex = sel[g].position(selPos).mappedId(); const int startPos = selPos; ++selPos; - while (selPos < sel[g].posCount() - && sel[g].position(selPos).mappedId() == selIndex) + while (selPos < sel[g].posCount() && sel[g].position(selPos).mappedId() == selIndex) { ++selPos; } @@ -526,23 +525,17 @@ PairDistance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, dh.finishFrame(); } -void -PairDistance::finishAnalysis(int /*nframes*/) -{ -} +void PairDistance::finishAnalysis(int /*nframes*/) {} -void -PairDistance::writeOutput() -{ -} +void PairDistance::writeOutput() {} //! \} -} // namespace +} // namespace -const char PairDistanceInfo::name[] = "pairdist"; +const char PairDistanceInfo::name[] = "pairdist"; const char PairDistanceInfo::shortDescription[] = - "Calculate pairwise distances between groups of positions"; + "Calculate pairwise distances between groups of positions"; TrajectoryAnalysisModulePointer PairDistanceInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/pairdist.h b/src/gromacs/trajectoryanalysis/modules/pairdist.h index eca2b873f8..ad151b4af9 100644 --- a/src/gromacs/trajectoryanalysis/modules/pairdist.h +++ b/src/gromacs/trajectoryanalysis/modules/pairdist.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014, by the GROMACS development team, led by + * Copyright (c) 2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class PairDistanceInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/rdf.cpp b/src/gromacs/trajectoryanalysis/modules/rdf.cpp index df711c35b1..cc45dadebc 100644 --- a/src/gromacs/trajectoryanalysis/modules/rdf.cpp +++ b/src/gromacs/trajectoryanalysis/modules/rdf.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -98,7 +98,7 @@ enum Normalization Normalization_None }; //! String values corresponding to Normalization. -const char *const c_NormalizationEnum[] = { "rdf", "number_density", "none" }; +const char* const c_NormalizationEnum[] = { "rdf", "number_density", "none" }; //! Whether to compute RDF wrt. surface of the reference group. enum SurfaceType { @@ -107,113 +107,114 @@ enum SurfaceType SurfaceType_Residue }; //! String values corresponding to SurfaceType. -const char *const c_SurfaceEnum[] = { "no", "mol", "res" }; +const char* const c_SurfaceEnum[] = { "no", "mol", "res" }; /*! \brief * Implements `gmx rdf` trajectory analysis module. */ class Rdf : public TrajectoryAnalysisModule { - public: - Rdf(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - void initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, - const t_trxframe &fr) override; - - TrajectoryAnalysisModuleDataPointer startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - std::string fnRdf_; - std::string fnCumulative_; - SurfaceType surface_; - AnalysisDataPlotSettings plotSettings_; - - /*! \brief - * Reference selection to compute RDFs around. - * - * With -surf, Selection::originalIds() and Selection::mappedIds() - * store the index of the surface group to which that position belongs. - * The RDF is computed by finding the nearest position from each - * surface group for each position, and then binning those distances. - */ - Selection refSel_; - /*! \brief - * Selections to compute RDFs for. - */ - SelectionList sel_; - - /*! \brief - * Raw pairwise distance data from which the RDF is computed. - * - * There is a data set for each selection in `sel_`, with a single - * column. Each point set will contain a single pairwise distance - * that contributes to the RDF. - */ - AnalysisData pairDist_; - /*! \brief - * Normalization factors for each frame. - * - * The first column contains the number of positions in `refSel_` for - * that frame (with surface RDF, the number of groups). There are - * `sel_.size()` more columns, each containing the number density of - * positions for one selection. - */ - AnalysisData normFactors_; - /*! \brief - * Histogram module that computes the actual RDF from `pairDist_`. - * - * The per-frame histograms are raw pair counts in each bin; - * the averager is normalized by the average number of reference - * positions (average of the first column of `normFactors_`). - */ - AnalysisDataSimpleHistogramModulePointer pairCounts_; - /*! \brief - * Average normalization factors. - */ - AnalysisDataAverageModulePointer normAve_; - //! Neighborhood search with `refSel_` as the reference positions. - AnalysisNeighborhood nb_; - //! Topology exclusions used by neighborhood searching. - const gmx_localtop_t *localTop_; - - // User input options. - double binwidth_; - double cutoff_; - double rmax_; - Normalization normalization_; - bool bNormalizationSet_; - bool bXY_; - bool bExclusions_; - - // Pre-computed values for faster access during analysis. - real cut2_; - real rmax2_; - int surfaceGroupCount_; - - // Copy and assign disallowed by base. +public: + Rdf(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + void initAfterFirstFrame(const TrajectoryAnalysisSettings& settings, const t_trxframe& fr) override; + + TrajectoryAnalysisModuleDataPointer startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + std::string fnRdf_; + std::string fnCumulative_; + SurfaceType surface_; + AnalysisDataPlotSettings plotSettings_; + + /*! \brief + * Reference selection to compute RDFs around. + * + * With -surf, Selection::originalIds() and Selection::mappedIds() + * store the index of the surface group to which that position belongs. + * The RDF is computed by finding the nearest position from each + * surface group for each position, and then binning those distances. + */ + Selection refSel_; + /*! \brief + * Selections to compute RDFs for. + */ + SelectionList sel_; + + /*! \brief + * Raw pairwise distance data from which the RDF is computed. + * + * There is a data set for each selection in `sel_`, with a single + * column. Each point set will contain a single pairwise distance + * that contributes to the RDF. + */ + AnalysisData pairDist_; + /*! \brief + * Normalization factors for each frame. + * + * The first column contains the number of positions in `refSel_` for + * that frame (with surface RDF, the number of groups). There are + * `sel_.size()` more columns, each containing the number density of + * positions for one selection. + */ + AnalysisData normFactors_; + /*! \brief + * Histogram module that computes the actual RDF from `pairDist_`. + * + * The per-frame histograms are raw pair counts in each bin; + * the averager is normalized by the average number of reference + * positions (average of the first column of `normFactors_`). + */ + AnalysisDataSimpleHistogramModulePointer pairCounts_; + /*! \brief + * Average normalization factors. + */ + AnalysisDataAverageModulePointer normAve_; + //! Neighborhood search with `refSel_` as the reference positions. + AnalysisNeighborhood nb_; + //! Topology exclusions used by neighborhood searching. + const gmx_localtop_t* localTop_; + + // User input options. + double binwidth_; + double cutoff_; + double rmax_; + Normalization normalization_; + bool bNormalizationSet_; + bool bXY_; + bool bExclusions_; + + // Pre-computed values for faster access during analysis. + real cut2_; + real rmax2_; + int surfaceGroupCount_; + + // Copy and assign disallowed by base. }; -Rdf::Rdf() - : surface_(SurfaceType_None), - pairCounts_(new AnalysisDataSimpleHistogramModule()), - normAve_(new AnalysisDataAverageModule()), - localTop_(nullptr), - binwidth_(0.002), cutoff_(0.0), rmax_(0.0), - normalization_(Normalization_Rdf), bNormalizationSet_(false), bXY_(false), - bExclusions_(false), - cut2_(0.0), rmax2_(0.0), surfaceGroupCount_(0) +Rdf::Rdf() : + surface_(SurfaceType_None), + pairCounts_(new AnalysisDataSimpleHistogramModule()), + normAve_(new AnalysisDataAverageModule()), + localTop_(nullptr), + binwidth_(0.002), + cutoff_(0.0), + rmax_(0.0), + normalization_(Normalization_Rdf), + bNormalizationSet_(false), + bXY_(false), + bExclusions_(false), + cut2_(0.0), + rmax2_(0.0), + surfaceGroupCount_(0) { pairDist_.setMultipoint(true); pairDist_.addModule(pairCounts_); @@ -224,10 +225,9 @@ Rdf::Rdf() registerAnalysisDataset(&normFactors_, "norm"); } -void -Rdf::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Rdf::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - const char *const desc[] = { + const char* const desc[] = { "[THISMODULE] calculates radial distribution functions from one", "reference set of position (set with [TT]-ref[tt]) to one or more", "sets of positions (set with [TT]-sel[tt]). To compute the RDF with", @@ -280,41 +280,47 @@ Rdf::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *setting settings->setHelpText(desc); - options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required() - .store(&fnRdf_).defaultBasename("rdf") - .description("Computed RDFs")); - options->addOption(FileNameOption("cn").filetype(eftPlot).outputFile() - .store(&fnCumulative_).defaultBasename("rdf_cn") - .description("Cumulative RDFs")); - - options->addOption(DoubleOption("bin").store(&binwidth_) - .description("Bin width (nm)")); - options->addOption(EnumOption("norm").enumValue(c_NormalizationEnum) - .store(&normalization_) - .storeIsSet(&bNormalizationSet_) - .description("Normalization")); - options->addOption(BooleanOption("xy").store(&bXY_) - .description("Use only the x and y components of the distance")); - options->addOption(BooleanOption("excl").store(&bExclusions_) - .description("Use exclusions from topology")); - options->addOption(DoubleOption("cut").store(&cutoff_) - .description("Shortest distance (nm) to be considered")); - options->addOption(DoubleOption("rmax").store(&rmax_) - .description("Largest distance (nm) to calculate")); - - options->addOption(EnumOption("surf").enumValue(c_SurfaceEnum) - .store(&surface_) - .description("RDF with respect to the surface of the reference")); - - options->addOption(SelectionOption("ref").store(&refSel_).required() - .description("Reference selection for RDF computation")); - options->addOption(SelectionOption("sel").storeVector(&sel_) - .required().multiValue() - .description("Selections to compute RDFs for from the reference")); + options->addOption(FileNameOption("o") + .filetype(eftPlot) + .outputFile() + .required() + .store(&fnRdf_) + .defaultBasename("rdf") + .description("Computed RDFs")); + options->addOption(FileNameOption("cn") + .filetype(eftPlot) + .outputFile() + .store(&fnCumulative_) + .defaultBasename("rdf_cn") + .description("Cumulative RDFs")); + + options->addOption(DoubleOption("bin").store(&binwidth_).description("Bin width (nm)")); + options->addOption(EnumOption("norm") + .enumValue(c_NormalizationEnum) + .store(&normalization_) + .storeIsSet(&bNormalizationSet_) + .description("Normalization")); + options->addOption(BooleanOption("xy").store(&bXY_).description( + "Use only the x and y components of the distance")); + options->addOption( + BooleanOption("excl").store(&bExclusions_).description("Use exclusions from topology")); + options->addOption(DoubleOption("cut").store(&cutoff_).description( + "Shortest distance (nm) to be considered")); + options->addOption( + DoubleOption("rmax").store(&rmax_).description("Largest distance (nm) to calculate")); + + options->addOption(EnumOption("surf") + .enumValue(c_SurfaceEnum) + .store(&surface_) + .description("RDF with respect to the surface of the reference")); + + options->addOption(SelectionOption("ref").store(&refSel_).required().description( + "Reference selection for RDF computation")); + options->addOption(SelectionOption("sel").storeVector(&sel_).required().multiValue().description( + "Selections to compute RDFs for from the reference")); } -void -Rdf::optionsFinished(TrajectoryAnalysisSettings *settings) +void Rdf::optionsFinished(TrajectoryAnalysisSettings* settings) { if (surface_ != SurfaceType_None) { @@ -340,9 +346,7 @@ Rdf::optionsFinished(TrajectoryAnalysisSettings *settings) } } -void -Rdf::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) +void Rdf::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) { pairDist_.setDataSetCount(sel_.size()); for (size_t i = 0; i < sel_.size(); ++i) @@ -362,34 +366,36 @@ Rdf::initAnalysis(const TrajectoryAnalysisSettings &settings, GMX_THROW(InconsistentInputError("-surf only works with -ref that consists of atoms")); } const e_index_t type = (surface_ == SurfaceType_Molecule ? INDEX_MOL : INDEX_RES); - surfaceGroupCount_ = refSel_.initOriginalIdsToGroup(top.mtop(), type); + surfaceGroupCount_ = refSel_.initOriginalIdsToGroup(top.mtop(), type); } if (bExclusions_) { if (!refSel_.hasOnlyAtoms() || !refSel_.hasSortedAtomIndices()) { - GMX_THROW(InconsistentInputError("-excl only works with a -ref selection that consist of atoms in ascending (sorted) order")); + GMX_THROW( + InconsistentInputError("-excl only works with a -ref selection that consist of " + "atoms in ascending (sorted) order")); } for (size_t i = 0; i < sel_.size(); ++i) { if (!sel_[i].hasOnlyAtoms()) { - GMX_THROW(InconsistentInputError("-excl only works with selections that consist of atoms")); + GMX_THROW(InconsistentInputError( + "-excl only works with selections that consist of atoms")); } } localTop_ = top.expandedTopology(); if (localTop_->excls.nr == 0) { - GMX_THROW(InconsistentInputError("-excl is set, but the file provided to -s does not define exclusions")); + GMX_THROW(InconsistentInputError( + "-excl is set, but the file provided to -s does not define exclusions")); } nb_.setTopologyExclusions(&localTop_->excls); } } -void -Rdf::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, - const t_trxframe &fr) +void Rdf::initAfterFirstFrame(const TrajectoryAnalysisSettings& settings, const t_trxframe& fr) { // If -rmax is not provided, determine one from the box for the first frame. if (rmax_ <= 0.0) @@ -400,9 +406,9 @@ Rdf::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, { if (bXY_) { - box[ZZ][ZZ] = 2*std::max(box[XX][XX], box[YY][YY]); + box[ZZ][ZZ] = 2 * std::max(box[XX][XX], box[YY][YY]); } - rmax_ = std::sqrt(0.99*0.99*max_cutoff2(bXY_ ? epbcXY : epbcXYZ, box)); + rmax_ = std::sqrt(0.99 * 0.99 * max_cutoff2(bXY_ ? epbcXY : epbcXYZ, box)); } else { @@ -410,7 +416,7 @@ Rdf::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, { clear_rvec(box[ZZ]); } - rmax_ = 3*std::max(box[XX][XX], std::max(box[YY][YY], box[ZZ][ZZ])); + rmax_ = 3 * std::max(box[XX][XX], std::max(box[YY][YY], box[ZZ][ZZ])); } } cut2_ = gmx::square(cutoff_); @@ -426,57 +432,53 @@ Rdf::initAfterFirstFrame(const TrajectoryAnalysisSettings &settings, */ class RdfModuleData : public TrajectoryAnalysisModuleData { - public: - /*! \brief - * Reserves memory for the frame-local data. - * - * `surfaceGroupCount` will be zero if -surf is not specified. - */ - RdfModuleData(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections, - int surfaceGroupCount) - : TrajectoryAnalysisModuleData(module, opt, selections) - { - surfaceDist2_.resize(surfaceGroupCount); - } +public: + /*! \brief + * Reserves memory for the frame-local data. + * + * `surfaceGroupCount` will be zero if -surf is not specified. + */ + RdfModuleData(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections, + int surfaceGroupCount) : + TrajectoryAnalysisModuleData(module, opt, selections) + { + surfaceDist2_.resize(surfaceGroupCount); + } - void finish() override { finishDataHandles(); } - - /*! \brief - * Minimum distance to each surface group. - * - * One entry for each group (residue/molecule, per -surf) in the - * reference selection. - * This is needed to support neighborhood searching, which may not - * return the reference positions in order: for each position, we need - * to search through all the reference positions and update this array - * to find the minimum distance to each surface group, and then compute - * the RDF from these numbers. - */ - std::vector surfaceDist2_; + void finish() override { finishDataHandles(); } + + /*! \brief + * Minimum distance to each surface group. + * + * One entry for each group (residue/molecule, per -surf) in the + * reference selection. + * This is needed to support neighborhood searching, which may not + * return the reference positions in order: for each position, we need + * to search through all the reference positions and update this array + * to find the minimum distance to each surface group, and then compute + * the RDF from these numbers. + */ + std::vector surfaceDist2_; }; -TrajectoryAnalysisModuleDataPointer Rdf::startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) +TrajectoryAnalysisModuleDataPointer Rdf::startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) { - return TrajectoryAnalysisModuleDataPointer( - new RdfModuleData(this, opt, selections, surfaceGroupCount_)); + return TrajectoryAnalysisModuleDataPointer(new RdfModuleData(this, opt, selections, surfaceGroupCount_)); } -void -Rdf::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void Rdf::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { AnalysisDataHandle dh = pdata->dataHandle(pairDist_); AnalysisDataHandle nh = pdata->dataHandle(normFactors_); - const Selection &refSel = pdata->parallelSelection(refSel_); - const SelectionList &sel = pdata->parallelSelections(sel_); - RdfModuleData &frameData = *static_cast(pdata); + const Selection& refSel = pdata->parallelSelection(refSel_); + const SelectionList& sel = pdata->parallelSelections(sel_); + RdfModuleData& frameData = *static_cast(pdata); const bool bSurface = !frameData.surfaceDist2_.empty(); - matrix boxForVolume; + matrix boxForVolume; copy_mat(fr.box, boxForVolume); if (bXY_) { @@ -519,7 +521,7 @@ Rdf::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } dh.startFrame(frnr, fr.time); - AnalysisNeighborhoodSearch nbsearch = nb_.initSearch(pbc, refSel); + AnalysisNeighborhoodSearch nbsearch = nb_.initSearch(pbc, refSel); for (size_t g = 0; g < sel.size(); ++g) { dh.selectDataSet(g); @@ -529,13 +531,11 @@ Rdf::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, // Special loop for surface calculation, where a separate neighbor // search is done for each position in the selection, and the // nearest position from each surface group is tracked. - std::vector &surfaceDist2 = frameData.surfaceDist2_; + std::vector& surfaceDist2 = frameData.surfaceDist2_; for (int i = 0; i < sel[g].posCount(); ++i) { - std::fill(surfaceDist2.begin(), surfaceDist2.end(), - std::numeric_limits::max()); - AnalysisNeighborhoodPairSearch pairSearch = - nbsearch.startPairSearch(sel[g].position(i)); + std::fill(surfaceDist2.begin(), surfaceDist2.end(), std::numeric_limits::max()); + AnalysisNeighborhoodPairSearch pairSearch = nbsearch.startPairSearch(sel[g].position(i)); AnalysisNeighborhoodPair pair; while (pairSearch.findNextPair(&pair)) { @@ -587,8 +587,7 @@ Rdf::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, nh.finishFrame(); } -void -Rdf::finishAnalysis(int /*nframes*/) +void Rdf::finishAnalysis(int /*nframes*/) { // Normalize the averager with the number of reference positions, // from where the normalization propagates to all the output. @@ -598,8 +597,7 @@ Rdf::finishAnalysis(int /*nframes*/) // TODO: Consider how these could be exposed to the testing framework // through the dataset registration mechanism. - AverageHistogramPointer finalRdf - = pairCounts_->averager().resampleDoubleBinWidth(true); + AverageHistogramPointer finalRdf = pairCounts_->averager().resampleDoubleBinWidth(true); if (normalization_ != Normalization_None) { @@ -608,22 +606,22 @@ Rdf::finishAnalysis(int /*nframes*/) std::vector invBinVolume; const int nbin = finalRdf->settings().binCount(); invBinVolume.resize(nbin); - real prevSphereVolume = 0.0; + real prevSphereVolume = 0.0; for (int i = 0; i < nbin; ++i) { - const real r = (i + 0.5)*binwidth_; + const real r = (i + 0.5) * binwidth_; real sphereVolume; if (bXY_) { - sphereVolume = M_PI*r*r; + sphereVolume = M_PI * r * r; } else { - sphereVolume = (4.0/3.0)*M_PI*r*r*r; + sphereVolume = (4.0 / 3.0) * M_PI * r * r * r; } const real binVolume = sphereVolume - prevSphereVolume; - invBinVolume[i] = 1.0 / binVolume; - prevSphereVolume = sphereVolume; + invBinVolume[i] = 1.0 / binVolume; + prevSphereVolume = sphereVolume; } finalRdf->scaleAllByVector(invBinVolume.data()); @@ -647,8 +645,7 @@ Rdf::finishAnalysis(int /*nframes*/) // TODO: Consider if some of this should be done in writeOutput(). { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(plotSettings_)); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(plotSettings_)); plotm->setFileName(fnRdf_); plotm->setTitle("Radial distribution"); plotm->setSubtitle(formatString("reference %s", refSel_.name())); @@ -663,13 +660,11 @@ Rdf::finishAnalysis(int /*nframes*/) if (!fnCumulative_.empty()) { - AverageHistogramPointer cumulativeRdf - = pairCounts_->averager().resampleDoubleBinWidth(false); + AverageHistogramPointer cumulativeRdf = pairCounts_->averager().resampleDoubleBinWidth(false); cumulativeRdf->makeCumulative(); cumulativeRdf->done(); - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(plotSettings_)); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(plotSettings_)); plotm->setFileName(fnCumulative_); plotm->setTitle("Cumulative Number RDF"); plotm->setSubtitle(formatString("reference %s", refSel_.name())); @@ -683,18 +678,14 @@ Rdf::finishAnalysis(int /*nframes*/) } } -void -Rdf::writeOutput() -{ -} +void Rdf::writeOutput() {} //! \} -} // namespace +} // namespace const char RdfInfo::name[] = "rdf"; -const char RdfInfo::shortDescription[] = - "Calculate radial distribution functions"; +const char RdfInfo::shortDescription[] = "Calculate radial distribution functions"; TrajectoryAnalysisModulePointer RdfInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/rdf.h b/src/gromacs/trajectoryanalysis/modules/rdf.h index 269d2a8bfb..fe521dc974 100644 --- a/src/gromacs/trajectoryanalysis/modules/rdf.h +++ b/src/gromacs/trajectoryanalysis/modules/rdf.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014, by the GROMACS development team, led by + * Copyright (c) 2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class RdfInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/sasa.cpp b/src/gromacs/trajectoryanalysis/modules/sasa.cpp index c10b32b648..06e20da425 100644 --- a/src/gromacs/trajectoryanalysis/modules/sasa.cpp +++ b/src/gromacs/trajectoryanalysis/modules/sasa.cpp @@ -94,13 +94,13 @@ namespace struct t_conect { //! Index of the second nearest neighbor dot. - int aa; + int aa; //! Index of the nearest neighbor dot. - int ab; + int ab; //! Squared distance to `aa`. - real d2a; + real d2a; //! Squared distance to `ab`. - real d2b; + real d2b; }; /*! \brief @@ -156,11 +156,11 @@ void add_rec(t_conect c[], int i, int j, real d2) * neighbors. The function is copied verbatim from the old gmx_sas.c * implementation. */ -void do_conect(const char *fn, int n, rvec x[]) +void do_conect(const char* fn, int n, rvec x[]) { - FILE *fp; + FILE* fp; int i, j; - t_conect *c; + t_conect* c; rvec dx; real d2; @@ -173,7 +173,7 @@ void do_conect(const char *fn, int n, rvec x[]) for (i = 0; (i < n); i++) { - for (j = i+1; (j < n); j++) + for (j = i + 1; (j < n); j++) { rvec_sub(x[i], x[j], dx); d2 = iprod(dx, dx); @@ -186,9 +186,9 @@ void do_conect(const char *fn, int n, rvec x[]) { if ((c[i].aa == -1) || (c[i].ab == -1)) { - fprintf(stderr, "Warning dot %d has no connections\n", i+1); + fprintf(stderr, "Warning dot %d has no connections\n", i + 1); } - fprintf(fp, "CONECT%5d%5d%5d\n", i+1, c[i].aa+1, c[i].ab+1); + fprintf(fp, "CONECT%5d%5d%5d\n", i + 1, c[i].aa + 1, c[i].ab + 1); } gmx_ffclose(fp); sfree(c); @@ -197,44 +197,51 @@ void do_conect(const char *fn, int n, rvec x[]) /*! \brief * Plots the surface into a PDB file, optionally including the original atoms. */ -void connolly_plot(const char *fn, int ndots, const real dots[], rvec x[], t_atoms *atoms, - t_symtab *symtab, int ePBC, const matrix box, gmx_bool bIncludeSolute) +void connolly_plot(const char* fn, + int ndots, + const real dots[], + rvec x[], + t_atoms* atoms, + t_symtab* symtab, + int ePBC, + const matrix box, + gmx_bool bIncludeSolute) { - const char *const atomnm = "DOT"; - const char *const resnm = "DOT"; - const char *const title = "Connolly Dot Surface Generated by gmx sasa"; + const char* const atomnm = "DOT"; + const char* const resnm = "DOT"; + const char* const title = "Connolly Dot Surface Generated by gmx sasa"; - int i, i0, r0, ii0, k; - rvec *xnew; - t_atoms aaa; + int i, i0, r0, ii0, k; + rvec* xnew; + t_atoms aaa; if (bIncludeSolute) { i0 = atoms->nr; r0 = atoms->nres; - srenew(atoms->atom, atoms->nr+ndots); - memset(&atoms->atom[i0], 0, sizeof(*atoms->atom)*ndots); - srenew(atoms->atomname, atoms->nr+ndots); - srenew(atoms->resinfo, r0+1); + srenew(atoms->atom, atoms->nr + ndots); + memset(&atoms->atom[i0], 0, sizeof(*atoms->atom) * ndots); + srenew(atoms->atomname, atoms->nr + ndots); + srenew(atoms->resinfo, r0 + 1); atoms->atom[i0].resind = r0; - t_atoms_set_resinfo(atoms, i0, symtab, resnm, r0+1, ' ', 0, ' '); + t_atoms_set_resinfo(atoms, i0, symtab, resnm, r0 + 1, ' ', 0, ' '); if (atoms->pdbinfo != nullptr) { - srenew(atoms->pdbinfo, atoms->nr+ndots); + srenew(atoms->pdbinfo, atoms->nr + ndots); } - snew(xnew, atoms->nr+ndots); + snew(xnew, atoms->nr + ndots); for (i = 0; (i < atoms->nr); i++) { copy_rvec(x[i], xnew[i]); } for (i = k = 0; (i < ndots); i++) { - ii0 = i0+i; - atoms->atomname[ii0] = put_symtab(symtab, atomnm); - atoms->atom[ii0].resind = r0; - xnew[ii0][XX] = dots[k++]; - xnew[ii0][YY] = dots[k++]; - xnew[ii0][ZZ] = dots[k++]; + ii0 = i0 + i; + atoms->atomname[ii0] = put_symtab(symtab, atomnm); + atoms->atom[ii0].resind = r0; + xnew[ii0][XX] = dots[k++]; + xnew[ii0][YY] = dots[k++]; + xnew[ii0][ZZ] = dots[k++]; if (atoms->pdbinfo != nullptr) { atoms->pdbinfo[ii0].type = epdbATOM; @@ -243,9 +250,9 @@ void connolly_plot(const char *fn, int ndots, const real dots[], rvec x[], t_ato atoms->pdbinfo[ii0].occup = 0.0; } } - atoms->nr = i0+ndots; - atoms->nres = r0+1; - write_sto_conf(fn, title, atoms, xnew, nullptr, ePBC, const_cast(box)); + atoms->nr = i0 + ndots; + atoms->nres = r0 + 1; + write_sto_conf(fn, title, atoms, xnew, nullptr, ePBC, const_cast(box)); atoms->nres = r0; atoms->nr = i0; } @@ -269,7 +276,7 @@ void connolly_plot(const char *fn, int ndots, const real dots[], rvec x[], t_ato aaa.pdbinfo[ii0].occup = 0.0; } aaa.nr = ndots; - write_sto_conf(fn, title, &aaa, xnew, nullptr, ePBC, const_cast(box)); + write_sto_conf(fn, title, &aaa, xnew, nullptr, ePBC, const_cast(box)); do_conect(fn, ndots, xnew); done_atom(&aaa); } @@ -285,123 +292,123 @@ void connolly_plot(const char *fn, int ndots, const real dots[], rvec x[], t_ato */ class Sasa : public TrajectoryAnalysisModule { - public: - Sasa(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - - TrajectoryAnalysisModuleDataPointer startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - /*! \brief - * Surface areas as a function of time. - * - * First column is for the calculation group, and the rest for the - * output groups. This data is always produced. - */ - AnalysisData area_; - /*! \brief - * Per-atom surface areas as a function of time. - * - * Contains one data set for each column in `area_`. - * Each column corresponds to a selection position in `surfaceSel_`. - * This data is only produced if atom or residue areas have been - * requested. - */ - AnalysisData atomArea_; - /*! \brief - * Per-residue surface areas as a function of time. - * - * Contains one data set for each column in `area_`. - * Each column corresponds to a distinct residue `surfaceSel_`. - * For example, if `surfaceSel_` selects residues 2, 5, and 7, there - * will be three columns here. - * This data is only produced if atom or residue areas have been - * requested. - */ - AnalysisData residueArea_; - /*! \brief - * Free energy estimates as a function of time. - * - * Column layout is the same as for `area_`. - * This data is only produced if the output is requested. - */ - AnalysisData dgSolv_; - /*! \brief - * Total volume and density of the calculation group as a function of - * time. - * - * The first column is the volume and the second column is the density. - * This data is only produced if the output is requested. - */ - AnalysisData volume_; - - /*! \brief - * The selection to calculate the surface for. - * - * Selection::originalId() and Selection::mappedId() store the mapping - * from the positions to the columns of `residueArea_`. - * The selection is computed with SelectionOption::dynamicMask(), i.e., - * even in the presence of a dynamic selection, the number of returned - * positions is fixed, and SelectionPosition::selected() is used. - */ - Selection surfaceSel_; - /*! \brief - * List of optional additional output groups. - * - * Each of these must be a subset of the `surfaceSel_`. - * Selection::originalId() and Selection::mappedId() store the mapping - * from the positions to the corresponsing positions in `surfaceSel_`. - */ - SelectionList outputSel_; - - std::string fnArea_; - std::string fnAtomArea_; - std::string fnResidueArea_; - std::string fnDGSolv_; - std::string fnVolume_; - std::string fnConnolly_; - - double solsize_; - int ndots_; - //double minarea_; - double dgsDefault_; - bool bIncludeSolute_; - - //! Global topology corresponding to the input. - gmx_mtop_t *mtop_; - //! Per-atom data corresponding to the input. - AtomsDataPtr atoms_; - //! Combined VdW and probe radii for each atom in the calculation group. - std::vector radii_; - /*! \brief - * Solvation free energy coefficients for each atom in the calculation - * group. - * - * Empty if the free energy output has not been requested. - */ - std::vector dgsFactor_; - //! Calculation algorithm. - SurfaceAreaCalculator calculator_; - - // Copy and assign disallowed by base. +public: + Sasa(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + + TrajectoryAnalysisModuleDataPointer startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + /*! \brief + * Surface areas as a function of time. + * + * First column is for the calculation group, and the rest for the + * output groups. This data is always produced. + */ + AnalysisData area_; + /*! \brief + * Per-atom surface areas as a function of time. + * + * Contains one data set for each column in `area_`. + * Each column corresponds to a selection position in `surfaceSel_`. + * This data is only produced if atom or residue areas have been + * requested. + */ + AnalysisData atomArea_; + /*! \brief + * Per-residue surface areas as a function of time. + * + * Contains one data set for each column in `area_`. + * Each column corresponds to a distinct residue `surfaceSel_`. + * For example, if `surfaceSel_` selects residues 2, 5, and 7, there + * will be three columns here. + * This data is only produced if atom or residue areas have been + * requested. + */ + AnalysisData residueArea_; + /*! \brief + * Free energy estimates as a function of time. + * + * Column layout is the same as for `area_`. + * This data is only produced if the output is requested. + */ + AnalysisData dgSolv_; + /*! \brief + * Total volume and density of the calculation group as a function of + * time. + * + * The first column is the volume and the second column is the density. + * This data is only produced if the output is requested. + */ + AnalysisData volume_; + + /*! \brief + * The selection to calculate the surface for. + * + * Selection::originalId() and Selection::mappedId() store the mapping + * from the positions to the columns of `residueArea_`. + * The selection is computed with SelectionOption::dynamicMask(), i.e., + * even in the presence of a dynamic selection, the number of returned + * positions is fixed, and SelectionPosition::selected() is used. + */ + Selection surfaceSel_; + /*! \brief + * List of optional additional output groups. + * + * Each of these must be a subset of the `surfaceSel_`. + * Selection::originalId() and Selection::mappedId() store the mapping + * from the positions to the corresponsing positions in `surfaceSel_`. + */ + SelectionList outputSel_; + + std::string fnArea_; + std::string fnAtomArea_; + std::string fnResidueArea_; + std::string fnDGSolv_; + std::string fnVolume_; + std::string fnConnolly_; + + double solsize_; + int ndots_; + // double minarea_; + double dgsDefault_; + bool bIncludeSolute_; + + //! Global topology corresponding to the input. + gmx_mtop_t* mtop_; + //! Per-atom data corresponding to the input. + AtomsDataPtr atoms_; + //! Combined VdW and probe radii for each atom in the calculation group. + std::vector radii_; + /*! \brief + * Solvation free energy coefficients for each atom in the calculation + * group. + * + * Empty if the free energy output has not been requested. + */ + std::vector dgsFactor_; + //! Calculation algorithm. + SurfaceAreaCalculator calculator_; + + // Copy and assign disallowed by base. }; -Sasa::Sasa() - : solsize_(0.14), ndots_(24), dgsDefault_(0), bIncludeSolute_(true), - mtop_(nullptr), atoms_(nullptr) +Sasa::Sasa() : + solsize_(0.14), + ndots_(24), + dgsDefault_(0), + bIncludeSolute_(true), + mtop_(nullptr), + atoms_(nullptr) { - //minarea_ = 0.5; + // minarea_ = 0.5; registerAnalysisDataset(&area_, "area"); registerAnalysisDataset(&atomArea_, "atomarea"); registerAnalysisDataset(&residueArea_, "resarea"); @@ -409,10 +416,9 @@ Sasa::Sasa() registerAnalysisDataset(&volume_, "volume"); } -void -Sasa::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Sasa::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] computes solvent accessible surface areas.", "See Eisenhaber F, Lijnzaad P, Argos P, Sander C, & Scharf M", "(1995) J. Comput. Chem. 16, 273-284 for the algorithm used.", @@ -431,8 +437,7 @@ Sasa::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settin "from the full surface.[PAR]", "The average and standard deviation of the area over the trajectory", - "can be calculated per residue and atom (options [TT]-or[tt] and", - "[TT]-oa[tt]).[PAR]", + "can be calculated per residue and atom (options [TT]-or[tt] and", "[TT]-oa[tt]).[PAR]", //"In combination with the latter option an [REF].itp[ref] file can be", //"generated (option [TT]-i[tt])", //"which can be used to restrain surface atoms.[PAR]", @@ -451,64 +456,83 @@ Sasa::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settin settings->setHelpText(desc); - options->addOption(FileNameOption("o").filetype(eftPlot).outputFile().required() - .store(&fnArea_).defaultBasename("area") - .description("Total area as a function of time")); - options->addOption(FileNameOption("odg").filetype(eftPlot).outputFile() - .store(&fnDGSolv_).defaultBasename("dgsolv") - .description("Estimated solvation free energy as a function of time")); - options->addOption(FileNameOption("or").filetype(eftPlot).outputFile() - .store(&fnResidueArea_).defaultBasename("resarea") - .description("Average area per residue")); - options->addOption(FileNameOption("oa").filetype(eftPlot).outputFile() - .store(&fnAtomArea_).defaultBasename("atomarea") - .description("Average area per atom")); - options->addOption(FileNameOption("tv").filetype(eftPlot).outputFile() - .store(&fnVolume_).defaultBasename("volume") - .description("Total volume and density as a function of time")); - options->addOption(FileNameOption("q").filetype(eftPDB).outputFile() - .store(&fnConnolly_).defaultBasename("connolly") - .description("PDB file for Connolly surface")); - //options->addOption(FileNameOption("i").filetype(eftITP).outputFile() + options->addOption(FileNameOption("o") + .filetype(eftPlot) + .outputFile() + .required() + .store(&fnArea_) + .defaultBasename("area") + .description("Total area as a function of time")); + options->addOption( + FileNameOption("odg") + .filetype(eftPlot) + .outputFile() + .store(&fnDGSolv_) + .defaultBasename("dgsolv") + .description("Estimated solvation free energy as a function of time")); + options->addOption(FileNameOption("or") + .filetype(eftPlot) + .outputFile() + .store(&fnResidueArea_) + .defaultBasename("resarea") + .description("Average area per residue")); + options->addOption(FileNameOption("oa") + .filetype(eftPlot) + .outputFile() + .store(&fnAtomArea_) + .defaultBasename("atomarea") + .description("Average area per atom")); + options->addOption(FileNameOption("tv") + .filetype(eftPlot) + .outputFile() + .store(&fnVolume_) + .defaultBasename("volume") + .description("Total volume and density as a function of time")); + options->addOption(FileNameOption("q") + .filetype(eftPDB) + .outputFile() + .store(&fnConnolly_) + .defaultBasename("connolly") + .description("PDB file for Connolly surface")); + // options->addOption(FileNameOption("i").filetype(eftITP).outputFile() // .store(&fnRestraints_).defaultBasename("surfat") // .description("Topology file for position restraings on surface atoms")); - options->addOption(DoubleOption("probe").store(&solsize_) - .description("Radius of the solvent probe (nm)")); - options->addOption(IntegerOption("ndots").store(&ndots_) - .description("Number of dots per sphere, more dots means more accuracy")); - //options->addOption(DoubleOption("minarea").store(&minarea_) + options->addOption( + DoubleOption("probe").store(&solsize_).description("Radius of the solvent probe (nm)")); + options->addOption(IntegerOption("ndots").store(&ndots_).description( + "Number of dots per sphere, more dots means more accuracy")); + // options->addOption(DoubleOption("minarea").store(&minarea_) // .description("The minimum area (nm^2) to count an atom as a surface atom when writing a position restraint file (see help)")); - options->addOption(BooleanOption("prot").store(&bIncludeSolute_) - .description("Output the protein to the Connolly [REF].pdb[ref] file too")); - options->addOption(DoubleOption("dgs").store(&dgsDefault_) - .description("Default value for solvation free energy per area (kJ/mol/nm^2)")); + options->addOption( + BooleanOption("prot").store(&bIncludeSolute_).description("Output the protein to the Connolly [REF].pdb[ref] file too")); + options->addOption( + DoubleOption("dgs").store(&dgsDefault_).description("Default value for solvation free energy per area (kJ/mol/nm^2)")); // Selections must select atoms for the VdW radii lookup to work. // The calculation group uses dynamicMask() so that the coordinates // match a static array of VdW radii. - options->addOption(SelectionOption("surface").store(&surfaceSel_) - .required().onlySortedAtoms().dynamicMask() - .description("Surface calculation selection")); - options->addOption(SelectionOption("output").storeVector(&outputSel_) - .onlySortedAtoms().multiValue() - .description("Output selection(s)")); + options->addOption(SelectionOption("surface") + .store(&surfaceSel_) + .required() + .onlySortedAtoms() + .dynamicMask() + .description("Surface calculation selection")); + options->addOption( + SelectionOption("output").storeVector(&outputSel_).onlySortedAtoms().multiValue().description("Output selection(s)")); // Atom names etc. are required for the VdW radii lookup. settings->setFlag(TrajectoryAnalysisSettings::efRequireTop); } -void -Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) +void Sasa::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) { mtop_ = top.mtop(); atoms_ = top.copyAtoms(); - //bITP = opt2bSet("-i", nfile, fnm); - const bool bResAt = - !fnResidueArea_.empty() || !fnAtomArea_.empty(); // || bITP; + // bITP = opt2bSet("-i", nfile, fnm); + const bool bResAt = !fnResidueArea_.empty() || !fnAtomArea_.empty(); // || bITP; const bool bDGsol = !fnDGSolv_.empty(); if (solsize_ < 0) @@ -523,7 +547,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, } please_cite(stderr, "Eisenhaber95"); - //if ((top.ePBC() != epbcXYZ) || (TRICLINIC(fr.box))) + // if ((top.ePBC() != epbcXYZ) || (TRICLINIC(fr.box))) //{ // fprintf(stderr, "\n\nWARNING: non-rectangular boxes may give erroneous results or crashes.\n" // "Analysis based on vacuum simulations (with the possibility of evaporation)\n" @@ -534,13 +558,16 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, { if (!top.hasFullTopology()) { - GMX_THROW(InconsistentInputError("Cannot compute Delta G of solvation without a tpr file")); + GMX_THROW(InconsistentInputError( + "Cannot compute Delta G of solvation without a tpr file")); } else { if (strcmp(*(atoms_->atomtype[0]), "?") == 0) { - GMX_THROW(InconsistentInputError("Your input tpr file is too old (does not contain atom types). Cannot not compute Delta G of solvation")); + GMX_THROW(InconsistentInputError( + "Your input tpr file is too old (does not contain atom types). Cannot not " + "compute Delta G of solvation")); } else { @@ -564,7 +591,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, // TODO: Not exception-safe, but nice solution would be to have a C++ // atom properties class... - AtomProperties aps; + AtomProperties aps; ArrayRef atomIndices = surfaceSel_.atomIndices(); int ndefault = 0; @@ -573,9 +600,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, const int ii = atomIndices[i]; const int resind = atoms_->atom[ii].resind; real radius; - if (!aps.setAtomProperty(epropVDW, - *(atoms_->resinfo[resind].name), - *(atoms_->atomname[ii]), &radius)) + if (!aps.setAtomProperty(epropVDW, *(atoms_->resinfo[resind].name), *(atoms_->atomname[ii]), &radius)) { ndefault++; } @@ -583,8 +608,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, if (bDGsol) { real dgsFactor; - if (!aps.setAtomProperty(epropDGsol, - *(atoms_->resinfo[resind].name), + if (!aps.setAtomProperty(epropDGsol, *(atoms_->resinfo[resind].name), *(atoms_->atomtype[ii]), &dgsFactor)) { dgsFactor = dgsDefault_; @@ -610,11 +634,11 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, } if (j == surfaceSel_.posCount() || outputIndices[i] != atomIndices[j]) { - const std::string message - = formatString("Output selection '%s' is not a subset of " - "the surface selection (atom %d is the first " - "atom not in the surface selection)", - outputSel_[g].name(), outputIndices[i] + 1); + const std::string message = formatString( + "Output selection '%s' is not a subset of " + "the surface selection (atom %d is the first " + "atom not in the surface selection)", + outputSel_[g].name(), outputIndices[i] + 1); GMX_THROW(InconsistentInputError(message)); } outputSel_[g].setOriginalId(i, j); @@ -628,8 +652,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, area_.setColumnCount(0, 1 + outputSel_.size()); { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnArea_); plotm->setTitle("Solvent Accessible Surface"); plotm->setXAxisIsTime(); @@ -660,8 +683,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, atomArea_.addModule(avem); if (!fnAtomArea_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnAtomArea_); plotm->setTitle("Area per atom over the trajectory"); plotm->setXLabel("Atom"); @@ -675,7 +697,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, } { AnalysisDataAverageModulePointer avem(new AnalysisDataAverageModule); - int nextRow = 0; + int nextRow = 0; for (int i = 0; i < surfaceSel_.posCount(); ++i) { const int residueGroup = surfaceSel_.position(i).mappedId(); @@ -692,8 +714,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, residueArea_.addModule(avem); if (!fnResidueArea_.empty()) { - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnResidueArea_); plotm->setTitle("Area per residue over the trajectory"); plotm->setXLabel("Residue"); @@ -710,8 +731,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnDGSolv_.empty()) { dgSolv_.setColumnCount(0, 1 + outputSel_.size()); - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnDGSolv_); plotm->setTitle("Free Energy of Solvation"); plotm->setXAxisIsTime(); @@ -727,8 +747,7 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, if (!fnVolume_.empty()) { volume_.setColumnCount(0, 2); - AnalysisDataPlotModulePointer plotm( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plotm(new AnalysisDataPlotModule(settings.plotSettings())); plotm->setFileName(fnVolume_); plotm->setTitle("Volume and Density"); plotm->setXAxisIsTime(); @@ -743,60 +762,59 @@ Sasa::initAnalysis(const TrajectoryAnalysisSettings &settings, */ class SasaModuleData : public TrajectoryAnalysisModuleData { - public: - /*! \brief - * Reserves memory for the frame-local data. - * - * `residueCount` will be zero if per-residue data is not being - * calculated. - */ - SasaModuleData(TrajectoryAnalysisModule *module, - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections, - int atomCount, int residueCount) - : TrajectoryAnalysisModuleData(module, opt, selections) +public: + /*! \brief + * Reserves memory for the frame-local data. + * + * `residueCount` will be zero if per-residue data is not being + * calculated. + */ + SasaModuleData(TrajectoryAnalysisModule* module, + const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections, + int atomCount, + int residueCount) : + TrajectoryAnalysisModuleData(module, opt, selections) + { + index_.reserve(atomCount); + // If the calculation group is not dynamic, pre-calculate + // the index, since it is not going to change. + for (int i = 0; i < atomCount; ++i) { - index_.reserve(atomCount); - // If the calculation group is not dynamic, pre-calculate - // the index, since it is not going to change. - for (int i = 0; i < atomCount; ++i) - { - index_.push_back(i); - } - atomAreas_.resize(atomCount); - res_a_.resize(residueCount); + index_.push_back(i); } + atomAreas_.resize(atomCount); + res_a_.resize(residueCount); + } - void finish() override { finishDataHandles(); } - - //! Indices of the calculation selection positions selected for the frame. - std::vector index_; - /*! \brief - * Atom areas for each calculation selection position for the frame. - * - * One entry for each position in the calculation group. - * Values for atoms not selected are set to zero. - */ - std::vector atomAreas_; - /*! \brief - * Working array to accumulate areas for each residue. - * - * One entry for each distinct residue in the calculation group; - * indices are not directly residue numbers or residue indices. - * - * This vector is empty if residue area calculations are not being - * performed. - */ - std::vector res_a_; + void finish() override { finishDataHandles(); } + + //! Indices of the calculation selection positions selected for the frame. + std::vector index_; + /*! \brief + * Atom areas for each calculation selection position for the frame. + * + * One entry for each position in the calculation group. + * Values for atoms not selected are set to zero. + */ + std::vector atomAreas_; + /*! \brief + * Working array to accumulate areas for each residue. + * + * One entry for each distinct residue in the calculation group; + * indices are not directly residue numbers or residue indices. + * + * This vector is empty if residue area calculations are not being + * performed. + */ + std::vector res_a_; }; -TrajectoryAnalysisModuleDataPointer Sasa::startFrames( - const AnalysisDataParallelOptions &opt, - const SelectionCollection &selections) +TrajectoryAnalysisModuleDataPointer Sasa::startFrames(const AnalysisDataParallelOptions& opt, + const SelectionCollection& selections) { - return TrajectoryAnalysisModuleDataPointer( - new SasaModuleData(this, opt, selections, surfaceSel_.posCount(), - residueArea_.columnCount(0))); + return TrajectoryAnalysisModuleDataPointer(new SasaModuleData( + this, opt, selections, surfaceSel_.posCount(), residueArea_.columnCount(0))); } /*! \brief @@ -818,13 +836,15 @@ TrajectoryAnalysisModuleDataPointer Sasa::startFrames( * * `atomAreaHandle` and `resAreaHandle` are not used if `resAreaWork` is empty. */ -void computeAreas(const Selection &surfaceSel, const Selection &sel, - const std::vector &atomAreas, - const std::vector &dgsFactor, - real *totalAreaOut, real *dgsolvOut, - AnalysisDataHandle atomAreaHandle, - AnalysisDataHandle resAreaHandle, - std::vector *resAreaWork) +void computeAreas(const Selection& surfaceSel, + const Selection& sel, + const std::vector& atomAreas, + const std::vector& dgsFactor, + real* totalAreaOut, + real* dgsolvOut, + AnalysisDataHandle atomAreaHandle, + AnalysisDataHandle resAreaHandle, + std::vector* resAreaWork) { const bool bResAt = !resAreaWork->empty(); const bool bDGsolv = !dgsFactor.empty(); @@ -840,7 +860,7 @@ void computeAreas(const Selection &surfaceSel, const Selection &sel, // Get the index of the atom in the calculation group. // For the output groups, the mapping has been precalculated in // initAnalysis(). - const int ii = (sel != surfaceSel ? sel.position(i).mappedId() : i); + const int ii = (sel != surfaceSel ? sel.position(i).mappedId() : i); if (!surfaceSel.position(ii).selected()) { // For the calculation group, skip unselected atoms. @@ -848,7 +868,8 @@ void computeAreas(const Selection &surfaceSel, const Selection &sel, { continue; } - GMX_THROW(InconsistentInputError("Output selection is not a subset of the surface selection")); + GMX_THROW(InconsistentInputError( + "Output selection is not a subset of the surface selection")); } // Get the internal index of the matching residue. // These have been precalculated in initAnalysis(). @@ -876,22 +897,20 @@ void computeAreas(const Selection &surfaceSel, const Selection &sel, *dgsolvOut = dgsolv; } -void -Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) +void Sasa::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) { AnalysisDataHandle ah = pdata->dataHandle(area_); AnalysisDataHandle dgh = pdata->dataHandle(dgSolv_); AnalysisDataHandle aah = pdata->dataHandle(atomArea_); AnalysisDataHandle rah = pdata->dataHandle(residueArea_); AnalysisDataHandle vh = pdata->dataHandle(volume_); - const Selection &surfaceSel = pdata->parallelSelection(surfaceSel_); - const SelectionList &outputSel = pdata->parallelSelections(outputSel_); - SasaModuleData &frameData = *static_cast(pdata); + const Selection& surfaceSel = pdata->parallelSelection(surfaceSel_); + const SelectionList& outputSel = pdata->parallelSelections(outputSel_); + SasaModuleData& frameData = *static_cast(pdata); - const bool bResAt = !frameData.res_a_.empty(); - const bool bDGsol = !dgsFactor_.empty(); - const bool bConnolly = (frnr == 0 && !fnConnolly_.empty()); + const bool bResAt = !frameData.res_a_.empty(); + const bool bDGsol = !dgsFactor_.empty(); + const bool bConnolly = (frnr == 0 && !fnConnolly_.empty()); // Update indices of selected atoms in the work array. if (surfaceSel.isDynamic()) @@ -907,7 +926,7 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } // Determine what needs to be calculated. - int flag = 0; + int flag = 0; if (bResAt || bDGsol || !outputSel.empty()) { flag |= FLAG_ATOM_AREA; @@ -929,18 +948,16 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, real totarea, totvolume; real *area = nullptr, *surfacedots = nullptr; int nsurfacedots; - calculator_.calculate(surfaceSel.coordinates().data(), pbc, - frameData.index_.size(), frameData.index_.data(), flag, - &totarea, &totvolume, &area, - &surfacedots, &nsurfacedots); + calculator_.calculate(surfaceSel.coordinates().data(), pbc, frameData.index_.size(), + frameData.index_.data(), flag, &totarea, &totvolume, &area, &surfacedots, + &nsurfacedots); // Unpack the atomwise areas into the frameData.atomAreas_ array for easier // indexing in the case of dynamic surfaceSel. if (area != nullptr) { if (surfaceSel.isDynamic()) { - std::fill(frameData.atomAreas_.begin(), frameData.atomAreas_.end(), - 0.0_real); + std::fill(frameData.atomAreas_.begin(), frameData.atomAreas_.end(), 0.0_real); for (size_t i = 0; i < frameData.index_.size(); ++i) { frameData.atomAreas_[frameData.index_[i]] = area[i]; @@ -948,8 +965,7 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } else { - std::copy(area, area + surfaceSel.posCount(), - frameData.atomAreas_.begin()); + std::copy(area, area + surfaceSel.posCount(), frameData.atomAreas_.begin()); } sfree(area); } @@ -959,14 +975,15 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, { if (fr.natoms != mtop_->natoms) { - GMX_THROW(InconsistentInputError("Connolly plot (-q) is only supported for trajectories that contain all the atoms")); + GMX_THROW( + InconsistentInputError("Connolly plot (-q) is only supported for trajectories " + "that contain all the atoms")); } // This is somewhat nasty, as it modifies the atoms and symtab // structures. But since it is only used in the first frame, and no // one else uses the topology after initialization, it may just work // even with future parallelization. - connolly_plot(fnConnolly_.c_str(), - nsurfacedots, surfacedots, fr.x, atoms_.get(), + connolly_plot(fnConnolly_.c_str(), nsurfacedots, surfacedots, fr.x, atoms_.get(), &mtop_->symtab, fr.ePBC, fr.box, bIncludeSolute_); } @@ -986,8 +1003,8 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, real totalArea, dgsolv; if (bResAt || bDGsol) { - computeAreas(surfaceSel, surfaceSel, frameData.atomAreas_, dgsFactor_, - &totalArea, &dgsolv, aah, rah, &frameData.res_a_); + computeAreas(surfaceSel, surfaceSel, frameData.atomAreas_, dgsFactor_, &totalArea, &dgsolv, + aah, rah, &frameData.res_a_); if (bDGsol) { dgh.setPoint(0, dgsolv); @@ -1000,8 +1017,8 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, aah.selectDataSet(g + 1); rah.selectDataSet(g + 1); } - computeAreas(surfaceSel, outputSel[g], frameData.atomAreas_, dgsFactor_, - &totalArea, &dgsolv, aah, rah, &frameData.res_a_); + computeAreas(surfaceSel, outputSel[g], frameData.atomAreas_, dgsFactor_, &totalArea, + &dgsolv, aah, rah, &frameData.res_a_); ah.setPoint(g + 1, totalArea); if (bDGsol) { @@ -1027,7 +1044,7 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, { totmass += surfaceSel.position(i).mass(); } - const real density = totmass*AMU/(totvolume*NANO*NANO*NANO); + const real density = totmass * AMU / (totvolume * NANO * NANO * NANO); vh.startFrame(frnr, fr.time); vh.setPoint(0, totvolume); vh.setPoint(1, density); @@ -1035,10 +1052,9 @@ Sasa::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, } } -void -Sasa::finishAnalysis(int /*nframes*/) +void Sasa::finishAnalysis(int /*nframes*/) { - //if (bITP) + // if (bITP) //{ // fp3 = ftp2FILE(efITP, nfile, fnm, "w"); // fprintf(fp3, "[ position_restraints ]\n" @@ -1057,18 +1073,14 @@ Sasa::finishAnalysis(int /*nframes*/) //} } -void -Sasa::writeOutput() -{ -} +void Sasa::writeOutput() {} //! \} -} // namespace +} // namespace const char SasaInfo::name[] = "sasa"; -const char SasaInfo::shortDescription[] = - "Compute solvent accessible surface area"; +const char SasaInfo::shortDescription[] = "Compute solvent accessible surface area"; TrajectoryAnalysisModulePointer SasaInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/sasa.h b/src/gromacs/trajectoryanalysis/modules/sasa.h index 4e2ca5eb1e..d1a1f07478 100644 --- a/src/gromacs/trajectoryanalysis/modules/sasa.h +++ b/src/gromacs/trajectoryanalysis/modules/sasa.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class SasaInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/select.cpp b/src/gromacs/trajectoryanalysis/modules/select.cpp index 98dc92a40c..9979991ed2 100644 --- a/src/gromacs/trajectoryanalysis/modules/select.cpp +++ b/src/gromacs/trajectoryanalysis/modules/select.cpp @@ -91,54 +91,55 @@ namespace */ class IndexFileWriterModule : public AnalysisDataModuleSerial { - public: - IndexFileWriterModule(); - ~IndexFileWriterModule() override; - - //! Sets the file name to write the index file to. - void setFileName(const std::string &fnm); - /*! \brief - * Adds information about a group to be printed. - * - * Must be called for each group present in the input data. - */ - void addGroup(const std::string &name, bool bDynamic); - - int flags() const override; - - void dataStarted(AbstractAnalysisData *data) override; - void frameStarted(const AnalysisDataFrameHeader &header) override; - void pointsAdded(const AnalysisDataPointSetRef &points) override; - void frameFinished(const AnalysisDataFrameHeader &header) override; - void dataFinished() override; - - private: - void closeFile(); - - struct GroupInfo - { - GroupInfo(const std::string &name, bool bDynamic) - : name(name), bDynamic(bDynamic) - { } - - std::string name; - bool bDynamic; - }; - - std::string fnm_; - std::vector groups_; - FILE *fp_; - int currentGroup_; - int currentSize_; - bool bAnyWritten_; +public: + IndexFileWriterModule(); + ~IndexFileWriterModule() override; + + //! Sets the file name to write the index file to. + void setFileName(const std::string& fnm); + /*! \brief + * Adds information about a group to be printed. + * + * Must be called for each group present in the input data. + */ + void addGroup(const std::string& name, bool bDynamic); + + int flags() const override; + + void dataStarted(AbstractAnalysisData* data) override; + void frameStarted(const AnalysisDataFrameHeader& header) override; + void pointsAdded(const AnalysisDataPointSetRef& points) override; + void frameFinished(const AnalysisDataFrameHeader& header) override; + void dataFinished() override; + +private: + void closeFile(); + + struct GroupInfo + { + GroupInfo(const std::string& name, bool bDynamic) : name(name), bDynamic(bDynamic) {} + + std::string name; + bool bDynamic; + }; + + std::string fnm_; + std::vector groups_; + FILE* fp_; + int currentGroup_; + int currentSize_; + bool bAnyWritten_; }; /******************************************************************** * IndexFileWriterModule */ -IndexFileWriterModule::IndexFileWriterModule() - : fp_(nullptr), currentGroup_(-1), currentSize_(0), bAnyWritten_(false) +IndexFileWriterModule::IndexFileWriterModule() : + fp_(nullptr), + currentGroup_(-1), + currentSize_(0), + bAnyWritten_(false) { } @@ -159,13 +160,13 @@ void IndexFileWriterModule::closeFile() } -void IndexFileWriterModule::setFileName(const std::string &fnm) +void IndexFileWriterModule::setFileName(const std::string& fnm) { fnm_ = fnm; } -void IndexFileWriterModule::addGroup(const std::string &name, bool bDynamic) +void IndexFileWriterModule::addGroup(const std::string& name, bool bDynamic) { std::string newName(name); std::replace(newName.begin(), newName.end(), ' ', '_'); @@ -179,7 +180,7 @@ int IndexFileWriterModule::flags() const } -void IndexFileWriterModule::dataStarted(AbstractAnalysisData * /*data*/) +void IndexFileWriterModule::dataStarted(AbstractAnalysisData* /*data*/) { if (!fnm_.empty()) { @@ -188,15 +189,14 @@ void IndexFileWriterModule::dataStarted(AbstractAnalysisData * /*data*/) } -void IndexFileWriterModule::frameStarted(const AnalysisDataFrameHeader & /*header*/) +void IndexFileWriterModule::frameStarted(const AnalysisDataFrameHeader& /*header*/) { bAnyWritten_ = false; currentGroup_ = -1; } -void -IndexFileWriterModule::pointsAdded(const AnalysisDataPointSetRef &points) +void IndexFileWriterModule::pointsAdded(const AnalysisDataPointSetRef& points) { if (fp_ == nullptr) { @@ -206,8 +206,7 @@ IndexFileWriterModule::pointsAdded(const AnalysisDataPointSetRef &points) if (points.firstColumn() == 0) { ++currentGroup_; - GMX_RELEASE_ASSERT(currentGroup_ < ssize(groups_), - "Too few groups initialized"); + GMX_RELEASE_ASSERT(currentGroup_ < ssize(groups_), "Too few groups initialized"); if (bFirstFrame || groups_[currentGroup_].bDynamic) { if (!bFirstFrame || currentGroup_ > 0) @@ -239,9 +238,7 @@ IndexFileWriterModule::pointsAdded(const AnalysisDataPointSetRef &points) } -void IndexFileWriterModule::frameFinished(const AnalysisDataFrameHeader & /*header*/) -{ -} +void IndexFileWriterModule::frameFinished(const AnalysisDataFrameHeader& /*header*/) {} void IndexFileWriterModule::dataFinished() @@ -271,62 +268,63 @@ enum PdbAtomsSelection PdbAtomsSelection_Selected }; //! String values corresponding to ResidueNumbering. -const char *const cResNumberEnum[] = { "number", "index" }; +const char* const cResNumberEnum[] = { "number", "index" }; //! String values corresponding to PdbAtomsSelection. -const char *const cPDBAtomsEnum[] = { "all", "maxsel", "selected" }; +const char* const cPDBAtomsEnum[] = { "all", "maxsel", "selected" }; class Select : public TrajectoryAnalysisModule { - public: - Select(); - - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; - - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; - - void finishAnalysis(int nframes) override; - void writeOutput() override; - - private: - SelectionList sel_; - - std::string fnSize_; - std::string fnFrac_; - std::string fnIndex_; - std::string fnNdx_; - std::string fnMask_; - std::string fnOccupancy_; - std::string fnPDB_; - std::string fnLifetime_; - bool bTotNorm_; - bool bFracNorm_; - bool bResInd_; - bool bCumulativeLifetimes_; - ResidueNumbering resNumberType_; - PdbAtomsSelection pdbAtoms_; - - //! The input topology. - const TopologyInformation *top_; - std::vector totsize_; - AnalysisData sdata_; - AnalysisData cdata_; - AnalysisData idata_; - AnalysisData mdata_; - AnalysisDataAverageModulePointer occupancyModule_; - AnalysisDataLifetimeModulePointer lifetimeModule_; +public: + Select(); + + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; + + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; + + void finishAnalysis(int nframes) override; + void writeOutput() override; + +private: + SelectionList sel_; + + std::string fnSize_; + std::string fnFrac_; + std::string fnIndex_; + std::string fnNdx_; + std::string fnMask_; + std::string fnOccupancy_; + std::string fnPDB_; + std::string fnLifetime_; + bool bTotNorm_; + bool bFracNorm_; + bool bResInd_; + bool bCumulativeLifetimes_; + ResidueNumbering resNumberType_; + PdbAtomsSelection pdbAtoms_; + + //! The input topology. + const TopologyInformation* top_; + std::vector totsize_; + AnalysisData sdata_; + AnalysisData cdata_; + AnalysisData idata_; + AnalysisData mdata_; + AnalysisDataAverageModulePointer occupancyModule_; + AnalysisDataLifetimeModulePointer lifetimeModule_; }; -Select::Select() - : bTotNorm_(false), bFracNorm_(false), bResInd_(false), - bCumulativeLifetimes_(true), resNumberType_(ResidueNumbering_ByNumber), - pdbAtoms_(PdbAtomsSelection_All), top_(nullptr), - occupancyModule_(new AnalysisDataAverageModule()), - lifetimeModule_(new AnalysisDataLifetimeModule()) +Select::Select() : + bTotNorm_(false), + bFracNorm_(false), + bResInd_(false), + bCumulativeLifetimes_(true), + resNumberType_(ResidueNumbering_ByNumber), + pdbAtoms_(PdbAtomsSelection_All), + top_(nullptr), + occupancyModule_(new AnalysisDataAverageModule()), + lifetimeModule_(new AnalysisDataLifetimeModule()) { mdata_.addModule(occupancyModule_); mdata_.addModule(lifetimeModule_); @@ -343,10 +341,9 @@ Select::Select() } -void -Select::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Select::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] writes out basic data about dynamic selections.", "It can be used for some simple analyses, or the output can", "be combined with output from other programs and/or external", @@ -424,51 +421,77 @@ Select::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *sett settings->setHelpText(desc); - options->addOption(FileNameOption("os").filetype(eftPlot).outputFile() - .store(&fnSize_).defaultBasename("size") - .description("Number of positions in each selection")); - options->addOption(FileNameOption("oc").filetype(eftPlot).outputFile() - .store(&fnFrac_).defaultBasename("cfrac") - .description("Covered fraction for each selection")); - options->addOption(FileNameOption("oi").filetype(eftGenericData).outputFile() - .store(&fnIndex_).defaultBasename("index") - .description("Indices selected by each selection")); - options->addOption(FileNameOption("on").filetype(eftIndex).outputFile() - .store(&fnNdx_).defaultBasename("index") - .description("Index file from the selection")); - options->addOption(FileNameOption("om").filetype(eftPlot).outputFile() - .store(&fnMask_).defaultBasename("mask") - .description("Mask for selected positions")); - options->addOption(FileNameOption("of").filetype(eftPlot).outputFile() - .store(&fnOccupancy_).defaultBasename("occupancy") - .description("Occupied fraction for selected positions")); - options->addOption(FileNameOption("ofpdb").filetype(eftPDB).outputFile() - .store(&fnPDB_).defaultBasename("occupancy") - .description("PDB file with occupied fraction for selected positions")); - options->addOption(FileNameOption("olt").filetype(eftPlot).outputFile() - .store(&fnLifetime_).defaultBasename("lifetime") - .description("Lifetime histogram")); - - options->addOption(SelectionOption("select").storeVector(&sel_) - .required().multiValue() - .description("Selections to analyze")); - - options->addOption(BooleanOption("norm").store(&bTotNorm_) - .description("Normalize by total number of positions with -os")); - options->addOption(BooleanOption("cfnorm").store(&bFracNorm_) - .description("Normalize by covered fraction with -os")); - options->addOption(EnumOption("resnr").store(&resNumberType_) - .enumValue(cResNumberEnum) - .description("Residue number output type with -oi and -on")); - options->addOption(EnumOption("pdbatoms").store(&pdbAtoms_) - .enumValue(cPDBAtomsEnum) - .description("Atoms to write with -ofpdb")); - options->addOption(BooleanOption("cumlt").store(&bCumulativeLifetimes_) - .description("Cumulate subintervals of longer intervals in -olt")); + options->addOption(FileNameOption("os") + .filetype(eftPlot) + .outputFile() + .store(&fnSize_) + .defaultBasename("size") + .description("Number of positions in each selection")); + options->addOption(FileNameOption("oc") + .filetype(eftPlot) + .outputFile() + .store(&fnFrac_) + .defaultBasename("cfrac") + .description("Covered fraction for each selection")); + options->addOption(FileNameOption("oi") + .filetype(eftGenericData) + .outputFile() + .store(&fnIndex_) + .defaultBasename("index") + .description("Indices selected by each selection")); + options->addOption(FileNameOption("on") + .filetype(eftIndex) + .outputFile() + .store(&fnNdx_) + .defaultBasename("index") + .description("Index file from the selection")); + options->addOption(FileNameOption("om") + .filetype(eftPlot) + .outputFile() + .store(&fnMask_) + .defaultBasename("mask") + .description("Mask for selected positions")); + options->addOption(FileNameOption("of") + .filetype(eftPlot) + .outputFile() + .store(&fnOccupancy_) + .defaultBasename("occupancy") + .description("Occupied fraction for selected positions")); + options->addOption( + FileNameOption("ofpdb") + .filetype(eftPDB) + .outputFile() + .store(&fnPDB_) + .defaultBasename("occupancy") + .description("PDB file with occupied fraction for selected positions")); + options->addOption(FileNameOption("olt") + .filetype(eftPlot) + .outputFile() + .store(&fnLifetime_) + .defaultBasename("lifetime") + .description("Lifetime histogram")); + + options->addOption(SelectionOption("select").storeVector(&sel_).required().multiValue().description( + "Selections to analyze")); + + options->addOption( + BooleanOption("norm").store(&bTotNorm_).description("Normalize by total number of positions with -os")); + options->addOption( + BooleanOption("cfnorm").store(&bFracNorm_).description("Normalize by covered fraction with -os")); + options->addOption(EnumOption("resnr") + .store(&resNumberType_) + .enumValue(cResNumberEnum) + .description("Residue number output type with -oi and -on")); + options->addOption(EnumOption("pdbatoms") + .store(&pdbAtoms_) + .enumValue(cPDBAtomsEnum) + .description("Atoms to write with -ofpdb")); + options->addOption(BooleanOption("cumlt") + .store(&bCumulativeLifetimes_) + .description("Cumulate subintervals of longer intervals in -olt")); } -void -Select::optionsFinished(TrajectoryAnalysisSettings *settings) +void Select::optionsFinished(TrajectoryAnalysisSettings* settings) { if (!fnPDB_.empty()) { @@ -477,9 +500,7 @@ Select::optionsFinished(TrajectoryAnalysisSettings *settings) } } -void -Select::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) +void Select::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) { bResInd_ = (resNumberType_ == ResidueNumbering_ByIndex); @@ -497,8 +518,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, } if (!fnSize_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnSize_); plot->setTitle("Selection size"); plot->setXAxisIsTime(); @@ -513,8 +533,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, cdata_.setColumnCount(0, sel_.size()); if (!fnFrac_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnFrac_); plot->setTitle("Covered fraction"); plot->setXAxisIsTime(); @@ -530,8 +549,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, // TODO: For large systems, a float may not have enough precision if (!fnIndex_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnIndex_); plot->setPlainOutput(true); plot->setYFormat(4, 0); @@ -556,8 +574,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, lifetimeModule_->setCumulative(bCumulativeLifetimes_); if (!fnMask_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnMask_); plot->setTitle("Selection mask"); plot->setXAxisIsTime(); @@ -568,8 +585,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, } if (!fnOccupancy_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnOccupancy_); plot->setTitle("Fraction of time selection matches"); plot->setXLabel("Selected position"); @@ -582,8 +598,7 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, } if (!fnLifetime_.empty()) { - AnalysisDataPlotModulePointer plot( - new AnalysisDataPlotModule(settings.plotSettings())); + AnalysisDataPlotModulePointer plot(new AnalysisDataPlotModule(settings.plotSettings())); plot->setFileName(fnLifetime_); plot->setTitle("Lifetime histogram"); plot->setXAxisIsTime(); @@ -599,15 +614,13 @@ Select::initAnalysis(const TrajectoryAnalysisSettings &settings, } -void -Select::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc * /* pbc */, - TrajectoryAnalysisModuleData *pdata) +void Select::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* /* pbc */, TrajectoryAnalysisModuleData* pdata) { AnalysisDataHandle sdh = pdata->dataHandle(sdata_); AnalysisDataHandle cdh = pdata->dataHandle(cdata_); AnalysisDataHandle idh = pdata->dataHandle(idata_); AnalysisDataHandle mdh = pdata->dataHandle(mdata_); - const SelectionList &sel = pdata->parallelSelections(sel_); + const SelectionList& sel = pdata->parallelSelections(sel_); sdh.startFrame(frnr, fr.time); for (size_t g = 0; g < sel.size(); ++g) @@ -635,7 +648,7 @@ Select::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc * /* pbc */, idh.finishPointSet(); for (int i = 0; i < sel[g].posCount(); ++i) { - const SelectionPosition &p = sel[g].position(i); + const SelectionPosition& p = sel[g].position(i); if (sel[g].type() == INDEX_RES && !bResInd_) { idh.setPoint(1, top_->atoms()->resinfo[p.mappedId()].nr); @@ -666,14 +679,10 @@ Select::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc * /* pbc */, } -void -Select::finishAnalysis(int /*nframes*/) -{ -} +void Select::finishAnalysis(int /*nframes*/) {} -void -Select::writeOutput() +void Select::writeOutput() { if (!fnPDB_.empty()) { @@ -693,8 +702,7 @@ Select::writeOutput() { for (int i = 0; i < sel_[g].posCount(); ++i) { - ArrayRef atomIndices - = sel_[g].position(i).atomIndices(); + ArrayRef atomIndices = sel_[g].position(i).atomIndices(); ArrayRef::const_iterator ai; for (ai = atomIndices.begin(); ai != atomIndices.end(); ++ai) { @@ -717,7 +725,7 @@ Select::writeOutput() { case PdbAtomsSelection_All: { - t_trxstatus *status = open_trx(fnPDB_.c_str(), "w"); + t_trxstatus* status = open_trx(fnPDB_.c_str(), "w"); write_trxframe(status, &fr, nullptr); close_trx(status); break; @@ -730,11 +738,9 @@ Select::writeOutput() ArrayRef atomIndices = sel_[g].atomIndices(); atomIndicesSet.insert(atomIndices.begin(), atomIndices.end()); } - std::vector allAtomIndices(atomIndicesSet.begin(), - atomIndicesSet.end()); - t_trxstatus *status = open_trx(fnPDB_.c_str(), "w"); - write_trxframe_indexed(status, &fr, allAtomIndices.size(), - allAtomIndices.data(), nullptr); + std::vector allAtomIndices(atomIndicesSet.begin(), atomIndicesSet.end()); + t_trxstatus* status = open_trx(fnPDB_.c_str(), "w"); + write_trxframe_indexed(status, &fr, allAtomIndices.size(), allAtomIndices.data(), nullptr); close_trx(status); break; } @@ -748,7 +754,7 @@ Select::writeOutput() indices.push_back(i); } } - t_trxstatus *status = open_trx(fnPDB_.c_str(), "w"); + t_trxstatus* status = open_trx(fnPDB_.c_str(), "w"); write_trxframe_indexed(status, &fr, indices.size(), indices.data(), nullptr); close_trx(status); break; @@ -760,11 +766,10 @@ Select::writeOutput() } } -} // namespace +} // namespace const char SelectInfo::name[] = "select"; -const char SelectInfo::shortDescription[] = - "Print general information about selections"; +const char SelectInfo::shortDescription[] = "Print general information about selections"; TrajectoryAnalysisModulePointer SelectInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/select.h b/src/gromacs/trajectoryanalysis/modules/select.h index 62b26a34af..ca1225373c 100644 --- a/src/gromacs/trajectoryanalysis/modules/select.h +++ b/src/gromacs/trajectoryanalysis/modules/select.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class SelectInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/surfacearea.cpp b/src/gromacs/trajectoryanalysis/modules/surfacearea.cpp index dade2e781c..bf93852622 100644 --- a/src/gromacs/trajectoryanalysis/modules/surfacearea.cpp +++ b/src/gromacs/trajectoryanalysis/modules/surfacearea.cpp @@ -57,74 +57,100 @@ using namespace gmx; -#define UNSP_ICO_DOD 9 -#define UNSP_ICO_ARC 10 +#define UNSP_ICO_DOD 9 +#define UNSP_ICO_ARC 10 -#define FOURPI (4.*M_PI) -#define TORAD(A) ((A)*0.017453293) -#define DP_TOL 0.001 +#define FOURPI (4. * M_PI) +#define TORAD(A) ((A)*0.017453293) +#define DP_TOL 0.001 static real safe_asin(real f) { - if ( (fabs(f) < 1.00) ) + if ((fabs(f) < 1.00)) { - return( asin(f) ); + return (asin(f)); } GMX_ASSERT(fabs(f) - 1.0 > DP_TOL, "Invalid argument"); - return(M_PI_2); + return (M_PI_2); } /* routines for dot distributions on the surface of the unit sphere */ -static real icosaeder_vertices(real *xus) +static real icosaeder_vertices(real* xus) { - const real rh = std::sqrt(1.-2.*cos(TORAD(72.)))/(1.-cos(TORAD(72.))); - const real rg = cos(TORAD(72.))/(1.-cos(TORAD(72.))); + const real rh = std::sqrt(1. - 2. * cos(TORAD(72.))) / (1. - cos(TORAD(72.))); + const real rg = cos(TORAD(72.)) / (1. - cos(TORAD(72.))); /* icosaeder vertices */ - xus[ 0] = 0.; xus[ 1] = 0.; xus[ 2] = 1.; - xus[ 3] = rh*cos(TORAD(72.)); xus[ 4] = rh*sin(TORAD(72.)); xus[ 5] = rg; - xus[ 6] = rh*cos(TORAD(144.)); xus[ 7] = rh*sin(TORAD(144.)); xus[ 8] = rg; - xus[ 9] = rh*cos(TORAD(216.)); xus[10] = rh*sin(TORAD(216.)); xus[11] = rg; - xus[12] = rh*cos(TORAD(288.)); xus[13] = rh*sin(TORAD(288.)); xus[14] = rg; - xus[15] = rh; xus[16] = 0; xus[17] = rg; - xus[18] = rh*cos(TORAD(36.)); xus[19] = rh*sin(TORAD(36.)); xus[20] = -rg; - xus[21] = rh*cos(TORAD(108.)); xus[22] = rh*sin(TORAD(108.)); xus[23] = -rg; - xus[24] = -rh; xus[25] = 0; xus[26] = -rg; - xus[27] = rh*cos(TORAD(252.)); xus[28] = rh*sin(TORAD(252.)); xus[29] = -rg; - xus[30] = rh*cos(TORAD(324.)); xus[31] = rh*sin(TORAD(324.)); xus[32] = -rg; - xus[33] = 0.; xus[34] = 0.; xus[35] = -1.; + xus[0] = 0.; + xus[1] = 0.; + xus[2] = 1.; + xus[3] = rh * cos(TORAD(72.)); + xus[4] = rh * sin(TORAD(72.)); + xus[5] = rg; + xus[6] = rh * cos(TORAD(144.)); + xus[7] = rh * sin(TORAD(144.)); + xus[8] = rg; + xus[9] = rh * cos(TORAD(216.)); + xus[10] = rh * sin(TORAD(216.)); + xus[11] = rg; + xus[12] = rh * cos(TORAD(288.)); + xus[13] = rh * sin(TORAD(288.)); + xus[14] = rg; + xus[15] = rh; + xus[16] = 0; + xus[17] = rg; + xus[18] = rh * cos(TORAD(36.)); + xus[19] = rh * sin(TORAD(36.)); + xus[20] = -rg; + xus[21] = rh * cos(TORAD(108.)); + xus[22] = rh * sin(TORAD(108.)); + xus[23] = -rg; + xus[24] = -rh; + xus[25] = 0; + xus[26] = -rg; + xus[27] = rh * cos(TORAD(252.)); + xus[28] = rh * sin(TORAD(252.)); + xus[29] = -rg; + xus[30] = rh * cos(TORAD(324.)); + xus[31] = rh * sin(TORAD(324.)); + xus[32] = -rg; + xus[33] = 0.; + xus[34] = 0.; + xus[35] = -1.; return rh; } -static void divarc(real x1, real y1, real z1, - real x2, real y2, real z2, - int div1, int div2, real *xr, real *yr, real *zr) +static void +divarc(real x1, real y1, real z1, real x2, real y2, real z2, int div1, int div2, real* xr, real* yr, real* zr) { real xd, yd, zd, dd, d1, d2, s, x, y, z; real phi, sphi, cphi; - xd = y1*z2-y2*z1; - yd = z1*x2-z2*x1; - zd = x1*y2-x2*y1; - dd = std::sqrt(xd*xd+yd*yd+zd*zd); + xd = y1 * z2 - y2 * z1; + yd = z1 * x2 - z2 * x1; + zd = x1 * y2 - x2 * y1; + dd = std::sqrt(xd * xd + yd * yd + zd * zd); GMX_ASSERT(dd >= DP_TOL, "Rotation axis vector too short"); - d1 = x1*x1+y1*y1+z1*z1; - d2 = x2*x2+y2*y2+z2*z2; + d1 = x1 * x1 + y1 * y1 + z1 * z1; + d2 = x2 * x2 + y2 * y2 + z2 * z2; GMX_ASSERT(d1 >= 0.5, "Vector 1 too short"); GMX_ASSERT(d2 >= 0.5, "Vector 2 too short"); - phi = safe_asin(dd/std::sqrt(d1*d2)); - phi = phi*(static_cast(div1))/(static_cast(div2)); - sphi = sin(phi); cphi = cos(phi); - s = (x1*xd+y1*yd+z1*zd)/dd; - - x = xd*s*(1.-cphi)/dd + x1 * cphi + (yd*z1-y1*zd)*sphi/dd; - y = yd*s*(1.-cphi)/dd + y1 * cphi + (zd*x1-z1*xd)*sphi/dd; - z = zd*s*(1.-cphi)/dd + z1 * cphi + (xd*y1-x1*yd)*sphi/dd; - dd = std::sqrt(x*x+y*y+z*z); - *xr = x/dd; *yr = y/dd; *zr = z/dd; + phi = safe_asin(dd / std::sqrt(d1 * d2)); + phi = phi * (static_cast(div1)) / (static_cast(div2)); + sphi = sin(phi); + cphi = cos(phi); + s = (x1 * xd + y1 * yd + z1 * zd) / dd; + + x = xd * s * (1. - cphi) / dd + x1 * cphi + (yd * z1 - y1 * zd) * sphi / dd; + y = yd * s * (1. - cphi) / dd + y1 * cphi + (zd * x1 - z1 * xd) * sphi / dd; + z = zd * s * (1. - cphi) / dd + z1 * cphi + (xd * y1 - x1 * yd) * sphi / dd; + dd = std::sqrt(x * x + y * y + z * z); + *xr = x / dd; + *yr = y / dd; + *zr = z / dd; } /* densit...required dots per unit sphere */ @@ -133,42 +159,41 @@ static std::vector ico_dot_arc(int densit) /* dot distribution on a unit sphere based on an icosaeder * * great circle average refining of icosahedral face */ - int i, j, k, tl, tl2, tn; - real a, d, x, y, z, x2, y2, z2, x3, y3, z3; - real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, - xjk, yjk, zjk, xkj, ykj, zkj; + int i, j, k, tl, tl2, tn; + real a, d, x, y, z, x2, y2, z2, x3, y3, z3; + real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, xjk, yjk, zjk, xkj, ykj, zkj; /* calculate tessalation level */ - a = std::sqrt(((static_cast(densit))-2.)/10.); - const int tess = static_cast(ceil(a)); - const int ndot = 10*tess*tess+2; + a = std::sqrt(((static_cast(densit)) - 2.) / 10.); + const int tess = static_cast(ceil(a)); + const int ndot = 10 * tess * tess + 2; GMX_RELEASE_ASSERT(ndot >= densit, "Inconsistent surface dot formula"); - std::vector xus(3*ndot); + std::vector xus(3 * ndot); const real rh = icosaeder_vertices(xus.data()); if (tess > 1) { tn = 12; - a = rh*rh*2.*(1.-cos(TORAD(72.))); + a = rh * rh * 2. * (1. - cos(TORAD(72.))); /* calculate tessalation of icosaeder edges */ for (i = 0; i < 11; i++) { - for (j = i+1; j < 12; j++) + for (j = i + 1; j < 12; j++) { - x = xus[3*i]-xus[3*j]; - y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * j]; + y = xus[1 + 3 * i] - xus[1 + 3 * j]; + z = xus[2 + 3 * i] - xus[2 + 3 * j]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } for (tl = 1; tl < tess; tl++) { GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count"); - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl, tess, &xus[3*tn], &xus[1+3*tn], &xus[2+3*tn]); + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], xus[1 + 3 * j], + xus[2 + 3 * j], tl, tess, &xus[3 * tn], &xus[1 + 3 * tn], &xus[2 + 3 * tn]); tn++; } } @@ -176,68 +201,63 @@ static std::vector ico_dot_arc(int densit) /* calculate tessalation of icosaeder faces */ for (i = 0; i < 10; i++) { - for (j = i+1; j < 11; j++) + for (j = i + 1; j < 11; j++) { - x = xus[3*i]-xus[3*j]; - y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * j]; + y = xus[1 + 3 * i] - xus[1 + 3 * j]; + z = xus[2 + 3 * i] - xus[2 + 3 * j]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - for (k = j+1; k < 12; k++) + for (k = j + 1; k < 12; k++) { - x = xus[3*i]-xus[3*k]; - y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * k]; + y = xus[1 + 3 * i] - xus[1 + 3 * k]; + z = xus[2 + 3 * i] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - x = xus[3*j]-xus[3*k]; - y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * j] - xus[3 * k]; + y = xus[1 + 3 * j] - xus[1 + 3 * k]; + z = xus[2 + 3 * j] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - for (tl = 1; tl < tess-1; tl++) + for (tl = 1; tl < tess - 1; tl++) { - divarc(xus[3*j], xus[1+3*j], xus[2+3*j], - xus[3*i], xus[1+3*i], xus[2+3*i], - tl, tess, &xji, &yji, &zji); - divarc(xus[3*k], xus[1+3*k], xus[2+3*k], - xus[3*i], xus[1+3*i], xus[2+3*i], - tl, tess, &xki, &yki, &zki); - - for (tl2 = 1; tl2 < tess-tl; tl2++) + divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * i], + xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xji, &yji, &zji); + divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * i], + xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xki, &yki, &zki); + + for (tl2 = 1; tl2 < tess - tl; tl2++) { - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl2, tess, &xij, &yij, &zij); - divarc(xus[3*k], xus[1+3*k], xus[2+3*k], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl2, tess, &xkj, &ykj, &zkj); - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*k], xus[1+3*k], xus[2+3*k], - tess-tl-tl2, tess, &xik, &yik, &zik); - divarc(xus[3*j], xus[1+3*j], xus[2+3*j], - xus[3*k], xus[1+3*k], xus[2+3*k], - tess-tl-tl2, tess, &xjk, &yjk, &zjk); - divarc(xki, yki, zki, xji, yji, zji, tl2, tess-tl, - &x, &y, &z); - divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess-tl2, - &x2, &y2, &z2); - divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl+tl2, - &x3, &y3, &z3); - GMX_ASSERT(tn < ndot, - "Inconsistent precomputed surface dot count"); - x = x+x2+x3; y = y+y2+y3; z = z+z2+z3; - d = std::sqrt(x*x+y*y+z*z); - xus[3*tn] = x/d; - xus[1+3*tn] = y/d; - xus[2+3*tn] = z/d; + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], + xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xij, &yij, &zij); + divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * j], + xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xkj, &ykj, &zkj); + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * k], xus[1 + 3 * k], + xus[2 + 3 * k], tess - tl - tl2, tess, &xik, &yik, &zik); + divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * k], xus[1 + 3 * k], + xus[2 + 3 * k], tess - tl - tl2, tess, &xjk, &yjk, &zjk); + divarc(xki, yki, zki, xji, yji, zji, tl2, tess - tl, &x, &y, &z); + divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess - tl2, &x2, &y2, &z2); + divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl + tl2, &x3, &y3, &z3); + GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count"); + x = x + x2 + x3; + y = y + y2 + y3; + z = z + z2 + z3; + d = std::sqrt(x * x + y * y + z * z); + xus[3 * tn] = x / d; + xus[1 + 3 * tn] = y / d; + xus[2 + 3 * tn] = z / d; tn++; } /* cycle tl2 */ } /* cycle tl */ @@ -245,10 +265,10 @@ static std::vector ico_dot_arc(int densit) } /* cycle j */ } /* cycle i */ GMX_ASSERT(tn == ndot, "Inconsistent precomputed surface dot count"); - } /* end of if (tess > 1) */ + } /* end of if (tess > 1) */ return xus; -} /* end of routine ico_dot_arc */ +} /* end of routine ico_dot_arc */ /* densit...required dots per unit sphere */ static std::vector ico_dot_dod(int densit) @@ -256,56 +276,60 @@ static std::vector ico_dot_dod(int densit) /* dot distribution on a unit sphere based on an icosaeder * * great circle average refining of icosahedral face */ - int i, j, k, tl, tl2, tn, tess, j1, j2; - real a, d, x, y, z, x2, y2, z2, x3, y3, z3, ai_d, adod; - real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, - xjk, yjk, zjk, xkj, ykj, zkj; + int i, j, k, tl, tl2, tn, tess, j1, j2; + real a, d, x, y, z, x2, y2, z2, x3, y3, z3, ai_d, adod; + real xij, yij, zij, xji, yji, zji, xik, yik, zik, xki, yki, zki, xjk, yjk, zjk, xkj, ykj, zkj; /* calculate tesselation level */ - a = std::sqrt(((static_cast(densit))-2.)/30.); - tess = std::max(static_cast(ceil(a)), 1); - const int ndot = 30*tess*tess+2; + a = std::sqrt(((static_cast(densit)) - 2.) / 30.); + tess = std::max(static_cast(ceil(a)), 1); + const int ndot = 30 * tess * tess + 2; GMX_RELEASE_ASSERT(ndot >= densit, "Inconsistent surface dot formula"); - std::vector xus(3*ndot); + std::vector xus(3 * ndot); const real rh = icosaeder_vertices(xus.data()); tn = 12; /* square of the edge of an icosaeder */ - a = rh*rh*2.*(1.-cos(TORAD(72.))); + a = rh * rh * 2. * (1. - cos(TORAD(72.))); /* dodecaeder vertices */ for (i = 0; i < 10; i++) { - for (j = i+1; j < 11; j++) + for (j = i + 1; j < 11; j++) { - x = xus[3*i]-xus[3*j]; - y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * j]; + y = xus[1 + 3 * i] - xus[1 + 3 * j]; + z = xus[2 + 3 * i] - xus[2 + 3 * j]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - for (k = j+1; k < 12; k++) + for (k = j + 1; k < 12; k++) { - x = xus[3*i]-xus[3*k]; - y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * k]; + y = xus[1 + 3 * i] - xus[1 + 3 * k]; + z = xus[2 + 3 * i] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - x = xus[3*j]-xus[3*k]; - y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * j] - xus[3 * k]; + y = xus[1 + 3 * j] - xus[1 + 3 * k]; + z = xus[2 + 3 * j] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } - x = xus[ 3*i]+xus[ 3*j]+xus[ 3*k]; - y = xus[1+3*i]+xus[1+3*j]+xus[1+3*k]; - z = xus[2+3*i]+xus[2+3*j]+xus[2+3*k]; - d = std::sqrt(x*x+y*y+z*z); - xus[3*tn] = x/d; xus[1+3*tn] = y/d; xus[2+3*tn] = z/d; + x = xus[3 * i] + xus[3 * j] + xus[3 * k]; + y = xus[1 + 3 * i] + xus[1 + 3 * j] + xus[1 + 3 * k]; + z = xus[2 + 3 * i] + xus[2 + 3 * j] + xus[2 + 3 * k]; + d = std::sqrt(x * x + y * y + z * z); + xus[3 * tn] = x / d; + xus[1 + 3 * tn] = y / d; + xus[2 + 3 * tn] = z / d; tn++; } } @@ -315,34 +339,36 @@ static std::vector ico_dot_dod(int densit) { tn = 32; /* square of the edge of an dodecaeder */ - adod = 4.*(cos(TORAD(108.))-cos(TORAD(120.)))/(1.-cos(TORAD(120.))); + adod = 4. * (cos(TORAD(108.)) - cos(TORAD(120.))) / (1. - cos(TORAD(120.))); /* square of the distance of two adjacent vertices of ico- and dodecaeder */ - ai_d = 2.*(1.-std::sqrt(1.-a/3.)); + ai_d = 2. * (1. - std::sqrt(1. - a / 3.)); /* calculate tessalation of mixed edges */ for (i = 0; i < 31; i++) { - j1 = 12; j2 = 32; a = ai_d; + j1 = 12; + j2 = 32; + a = ai_d; if (i >= 12) { - j1 = i+1; a = adod; + j1 = i + 1; + a = adod; } for (j = j1; j < j2; j++) { - x = xus[3*i]-xus[3*j]; - y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j]; - d = x*x+y*y+z*z; - if (std::fabs(a-d) > DP_TOL) + x = xus[3 * i] - xus[3 * j]; + y = xus[1 + 3 * i] - xus[1 + 3 * j]; + z = xus[2 + 3 * i] - xus[2 + 3 * j]; + d = x * x + y * y + z * z; + if (std::fabs(a - d) > DP_TOL) { continue; } for (tl = 1; tl < tess; tl++) { - GMX_ASSERT(tn < ndot, - "Inconsistent precomputed surface dot count"); - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl, tess, &xus[3*tn], &xus[1+3*tn], &xus[2+3*tn]); + GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count"); + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], xus[1 + 3 * j], + xus[2 + 3 * j], tl, tess, &xus[3 * tn], &xus[1 + 3 * tn], &xus[2 + 3 * tn]); tn++; } } @@ -352,66 +378,61 @@ static std::vector ico_dot_dod(int densit) { for (j = 12; j < 31; j++) { - x = xus[3*i]-xus[3*j]; - y = xus[1+3*i]-xus[1+3*j]; z = xus[2+3*i]-xus[2+3*j]; - d = x*x+y*y+z*z; - if (std::fabs(ai_d-d) > DP_TOL) + x = xus[3 * i] - xus[3 * j]; + y = xus[1 + 3 * i] - xus[1 + 3 * j]; + z = xus[2 + 3 * i] - xus[2 + 3 * j]; + d = x * x + y * y + z * z; + if (std::fabs(ai_d - d) > DP_TOL) { continue; } - for (k = j+1; k < 32; k++) + for (k = j + 1; k < 32; k++) { - x = xus[3*i]-xus[3*k]; - y = xus[1+3*i]-xus[1+3*k]; z = xus[2+3*i]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(ai_d-d) > DP_TOL) + x = xus[3 * i] - xus[3 * k]; + y = xus[1 + 3 * i] - xus[1 + 3 * k]; + z = xus[2 + 3 * i] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(ai_d - d) > DP_TOL) { continue; } - x = xus[3*j]-xus[3*k]; - y = xus[1+3*j]-xus[1+3*k]; z = xus[2+3*j]-xus[2+3*k]; - d = x*x+y*y+z*z; - if (std::fabs(adod-d) > DP_TOL) + x = xus[3 * j] - xus[3 * k]; + y = xus[1 + 3 * j] - xus[1 + 3 * k]; + z = xus[2 + 3 * j] - xus[2 + 3 * k]; + d = x * x + y * y + z * z; + if (std::fabs(adod - d) > DP_TOL) { continue; } - for (tl = 1; tl < tess-1; tl++) + for (tl = 1; tl < tess - 1; tl++) { - divarc(xus[3*j], xus[1+3*j], xus[2+3*j], - xus[3*i], xus[1+3*i], xus[2+3*i], - tl, tess, &xji, &yji, &zji); - divarc(xus[3*k], xus[1+3*k], xus[2+3*k], - xus[3*i], xus[1+3*i], xus[2+3*i], - tl, tess, &xki, &yki, &zki); - - for (tl2 = 1; tl2 < tess-tl; tl2++) + divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * i], + xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xji, &yji, &zji); + divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * i], + xus[1 + 3 * i], xus[2 + 3 * i], tl, tess, &xki, &yki, &zki); + + for (tl2 = 1; tl2 < tess - tl; tl2++) { - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl2, tess, &xij, &yij, &zij); - divarc(xus[3*k], xus[1+3*k], xus[2+3*k], - xus[3*j], xus[1+3*j], xus[2+3*j], - tl2, tess, &xkj, &ykj, &zkj); - divarc(xus[3*i], xus[1+3*i], xus[2+3*i], - xus[3*k], xus[1+3*k], xus[2+3*k], - tess-tl-tl2, tess, &xik, &yik, &zik); - divarc(xus[3*j], xus[1+3*j], xus[2+3*j], - xus[3*k], xus[1+3*k], xus[2+3*k], - tess-tl-tl2, tess, &xjk, &yjk, &zjk); - divarc(xki, yki, zki, xji, yji, zji, tl2, tess-tl, - &x, &y, &z); - divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess-tl2, - &x2, &y2, &z2); - divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl+tl2, - &x3, &y3, &z3); - GMX_ASSERT(tn < ndot, - "Inconsistent precomputed surface dot count"); - x = x+x2+x3; y = y+y2+y3; z = z+z2+z3; - d = std::sqrt(x*x+y*y+z*z); - xus[3*tn] = x/d; - xus[1+3*tn] = y/d; - xus[2+3*tn] = z/d; + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * j], + xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xij, &yij, &zij); + divarc(xus[3 * k], xus[1 + 3 * k], xus[2 + 3 * k], xus[3 * j], + xus[1 + 3 * j], xus[2 + 3 * j], tl2, tess, &xkj, &ykj, &zkj); + divarc(xus[3 * i], xus[1 + 3 * i], xus[2 + 3 * i], xus[3 * k], xus[1 + 3 * k], + xus[2 + 3 * k], tess - tl - tl2, tess, &xik, &yik, &zik); + divarc(xus[3 * j], xus[1 + 3 * j], xus[2 + 3 * j], xus[3 * k], xus[1 + 3 * k], + xus[2 + 3 * k], tess - tl - tl2, tess, &xjk, &yjk, &zjk); + divarc(xki, yki, zki, xji, yji, zji, tl2, tess - tl, &x, &y, &z); + divarc(xkj, ykj, zkj, xij, yij, zij, tl, tess - tl2, &x2, &y2, &z2); + divarc(xjk, yjk, zjk, xik, yik, zik, tl, tl + tl2, &x3, &y3, &z3); + GMX_ASSERT(tn < ndot, "Inconsistent precomputed surface dot count"); + x = x + x2 + x3; + y = y + y2 + y3; + z = z + z2 + z3; + d = std::sqrt(x * x + y * y + z * z); + xus[3 * tn] = x / d; + xus[1 + 3 * tn] = y / d; + xus[2 + 3 * tn] = z / d; tn++; } /* cycle tl2 */ } /* cycle tl */ @@ -419,25 +440,25 @@ static std::vector ico_dot_dod(int densit) } /* cycle j */ } /* cycle i */ GMX_ASSERT(tn == ndot, "Inconsistent precomputed surface dot count"); - } /* end of if (tess > 1) */ + } /* end of if (tess > 1) */ return xus; -} /* end of routine ico_dot_dod */ +} /* end of routine ico_dot_dod */ static int unsp_type(int densit) { int i1, i2; i1 = 1; - while (10*i1*i1+2 < densit) + while (10 * i1 * i1 + 2 < densit) { i1++; } i2 = 1; - while (30*i2*i2+2 < densit) + while (30 * i2 * i2 + 2 < densit) { i2++; } - if (10*i1*i1-2 < 30*i2*i2-2) + if (10 * i1 * i1 - 2 < 30 * i2 * i2 - 2) { return UNSP_ICO_ARC; } @@ -449,10 +470,10 @@ static int unsp_type(int densit) static std::vector make_unsp(int densit, int cubus) { - int *ico_wk, *ico_pt; - int ico_cube, ico_cube_cb, i, j, k, l, ijk, tn, tl, tl2; - int *work; - real x, y, z; + int *ico_wk, *ico_pt; + int ico_cube, ico_cube_cb, i, j, k, l, ijk, tn, tl, tl2; + int* work; + real x, y, z; int mode = unsp_type(densit); std::vector xus; @@ -469,7 +490,7 @@ static std::vector make_unsp(int densit, int cubus) GMX_RELEASE_ASSERT(false, "Invalid unit sphere mode"); } - const int ndot = ssize(xus)/3; + const int ndot = ssize(xus) / 3; /* determine distribution of points in elementary cubes */ if (cubus) @@ -478,40 +499,40 @@ static std::vector make_unsp(int densit, int cubus) } else { - i = 1; - while (i*i*i*2 < ndot) + i = 1; + while (i * i * i * 2 < ndot) { i++; } - ico_cube = std::max(i-1, 0); + ico_cube = std::max(i - 1, 0); } - ico_cube_cb = ico_cube*ico_cube*ico_cube; - const real del_cube = 2./(static_cast(ico_cube)); + ico_cube_cb = ico_cube * ico_cube * ico_cube; + const real del_cube = 2. / (static_cast(ico_cube)); snew(work, ndot); for (l = 0; l < ndot; l++) { - i = std::max(static_cast(floor((1.+xus[3*l])/del_cube)), 0); + i = std::max(static_cast(floor((1. + xus[3 * l]) / del_cube)), 0); if (i >= ico_cube) { - i = ico_cube-1; + i = ico_cube - 1; } - j = std::max(static_cast(floor((1.+xus[1+3*l])/del_cube)), 0); + j = std::max(static_cast(floor((1. + xus[1 + 3 * l]) / del_cube)), 0); if (j >= ico_cube) { - j = ico_cube-1; + j = ico_cube - 1; } - k = std::max(static_cast(floor((1.+xus[2+3*l])/del_cube)), 0); + k = std::max(static_cast(floor((1. + xus[2 + 3 * l]) / del_cube)), 0); if (k >= ico_cube) { - k = ico_cube-1; + k = ico_cube - 1; } - ijk = i+j*ico_cube+k*ico_cube*ico_cube; + ijk = i + j * ico_cube + k * ico_cube * ico_cube; work[l] = ijk; } - snew(ico_wk, 2*ico_cube_cb+1); + snew(ico_wk, 2 * ico_cube_cb + 1); - ico_pt = ico_wk+ico_cube_cb; + ico_pt = ico_wk + ico_cube_cb; for (l = 0; l < ndot; l++) { ico_wk[work[l]]++; /* dots per elementary cube */ @@ -525,23 +546,31 @@ static std::vector make_unsp(int densit, int cubus) { for (k = 0; k < ico_cube; k++) { - tl = 0; - tl2 = tn; - ijk = i+ico_cube*j+ico_cube*ico_cube*k; - *(ico_pt+ijk) = tn; + tl = 0; + tl2 = tn; + ijk = i + ico_cube * j + ico_cube * ico_cube * k; + *(ico_pt + ijk) = tn; for (l = tl2; l < ndot; l++) { if (ijk == work[l]) { - x = xus[3*l]; y = xus[1+3*l]; z = xus[2+3*l]; - xus[3*l] = xus[3*tn]; - xus[1+3*l] = xus[1+3*tn]; xus[2+3*l] = xus[2+3*tn]; - xus[3*tn] = x; xus[1+3*tn] = y; xus[2+3*tn] = z; - ijk = work[l]; work[l] = work[tn]; work[tn] = ijk; - tn++; tl++; + x = xus[3 * l]; + y = xus[1 + 3 * l]; + z = xus[2 + 3 * l]; + xus[3 * l] = xus[3 * tn]; + xus[1 + 3 * l] = xus[1 + 3 * tn]; + xus[2 + 3 * l] = xus[2 + 3 * tn]; + xus[3 * tn] = x; + xus[1 + 3 * tn] = y; + xus[2 + 3 * tn] = z; + ijk = work[l]; + work[l] = work[tn]; + work[tn] = ijk; + tn++; + tl++; } } - *(ico_wk+ijk) = tl; + *(ico_wk + ijk) = tl; } /* cycle k */ } /* cycle j */ } /* cycle i */ @@ -551,16 +580,22 @@ static std::vector make_unsp(int densit, int cubus) return xus; } -static void -nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, - const real *xus, int n_dot, int mode, - real *value_of_area, real **at_area, - real *value_of_vol, - real **lidots, int *nu_dots, - int index[], AnalysisNeighborhood *nb, - const t_pbc *pbc) +static void nsc_dclm_pbc(const rvec* coords, + const ArrayRef& radius, + int nat, + const real* xus, + int n_dot, + int mode, + real* value_of_area, + real** at_area, + real* value_of_vol, + real** lidots, + int* nu_dots, + int index[], + AnalysisNeighborhood* nb, + const t_pbc* pbc) { - const real dotarea = FOURPI/static_cast(n_dot); + const real dotarea = FOURPI / static_cast(n_dot); if (debug) { @@ -573,16 +608,16 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, { return; } - real area = 0.0, vol = 0.0; - real *dots = nullptr, *atom_area = nullptr; - int lfnr = 0, maxdots = 0; + real area = 0.0, vol = 0.0; + real *dots = nullptr, *atom_area = nullptr; + int lfnr = 0, maxdots = 0; if (mode & FLAG_VOLUME) { vol = 0.; } if (mode & FLAG_DOTS) { - maxdots = (3*n_dot*nat)/10; + maxdots = (3 * n_dot * nat) / 10; snew(dots, maxdots); lfnr = 0; } @@ -612,17 +647,16 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, AnalysisNeighborhoodPositions pos(coords, radius.size()); pos.indexed(constArrayRefFromArray(index, nat)); - AnalysisNeighborhoodSearch nbsearch(nb->initSearch(pbc, pos)); + AnalysisNeighborhoodSearch nbsearch(nb->initSearch(pbc, pos)); - std::vector wkdot(n_dot); + std::vector wkdot(n_dot); for (int i = 0; i < nat; ++i) { const int iat = index[i]; const real ai = radius[iat]; - const real aisq = ai*ai; - AnalysisNeighborhoodPairSearch pairSearch( - nbsearch.startPairSearch(coords[iat])); + const real aisq = ai * ai; + AnalysisNeighborhoodPairSearch pairSearch(nbsearch.startPairSearch(coords[iat])); AnalysisNeighborhoodPair pair; std::fill(wkdot.begin(), wkdot.end(), 1); int currDotCount = n_dot; @@ -631,12 +665,12 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, const int jat = index[pair.refIndex()]; const real aj = radius[jat]; const real d2 = pair.distance2(); - if (iat == jat || d2 > gmx::square(ai+aj)) + if (iat == jat || d2 > gmx::square(ai + aj)) { continue; } - const rvec &dx = pair.dx(); - const real refdot = (d2 + aisq - aj*aj)/(2*ai); + const rvec& dx = pair.dx(); + const real refdot = (d2 + aisq - aj * aj) / (2 * ai); // TODO: Consider whether micro-optimizations from the old // implementation would be useful, compared to the complexity that // they bring: instead of this direct loop, the neighbors were @@ -651,7 +685,7 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, // covered. for (int j = 0; j < n_dot; ++j) { - if (wkdot[j] && iprod(&xus[3*j], dx) > refdot) + if (wkdot[j] && iprod(&xus[3 * j], dx) > refdot) { --currDotCount; wkdot[j] = 0; @@ -660,7 +694,7 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, } const real a = aisq * dotarea * currDotCount; - area = area + a; + area = area + a; if (mode & FLAG_ATOM_AREA) { atom_area[i] = a; @@ -675,14 +709,14 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, if (wkdot[l]) { lfnr++; - if (maxdots <= 3*lfnr+1) + if (maxdots <= 3 * lfnr + 1) { - maxdots = maxdots+n_dot*3; + maxdots = maxdots + n_dot * 3; srenew(dots, maxdots); } - dots[3*lfnr-3] = ai*xus[3*l]+xi; - dots[3*lfnr-2] = ai*xus[1+3*l]+yi; - dots[3*lfnr-1] = ai*xus[2+3*l]+zi; + dots[3 * lfnr - 3] = ai * xus[3 * l] + xi; + dots[3 * lfnr - 2] = ai * xus[1 + 3 * l] + yi; + dots[3 * lfnr - 1] = ai * xus[2 + 3 * l] + zi; } } } @@ -693,25 +727,25 @@ nsc_dclm_pbc(const rvec *coords, const ArrayRef &radius, int nat, { if (wkdot[l]) { - dx = dx+xus[3*l]; - dy = dy+xus[1+3*l]; - dz = dz+xus[2+3*l]; + dx = dx + xus[3 * l]; + dy = dy + xus[1 + 3 * l]; + dz = dz + xus[2 + 3 * l]; } } - vol = vol+aisq*(dx*(xi-xs)+dy*(yi-ys)+dz*(zi-zs) + ai*currDotCount); + vol = vol + aisq * (dx * (xi - xs) + dy * (yi - ys) + dz * (zi - zs) + ai * currDotCount); } } if (mode & FLAG_VOLUME) { - *value_of_vol = vol*FOURPI/(3.*n_dot); + *value_of_vol = vol * FOURPI / (3. * n_dot); } if (mode & FLAG_DOTS) { GMX_RELEASE_ASSERT(nu_dots != nullptr, "Must have valid nu_dots pointer"); *nu_dots = lfnr; GMX_RELEASE_ASSERT(lidots != nullptr, "Must have valid lidots pointer"); - *lidots = dots; + *lidots = dots; } if (mode & FLAG_ATOM_AREA) { @@ -731,38 +765,31 @@ namespace gmx class SurfaceAreaCalculator::Impl { - public: - Impl() : flags_(0) - { - } +public: + Impl() : flags_(0) {} - std::vector unitSphereDots_; - ArrayRef radius_; - int flags_; - mutable AnalysisNeighborhood nb_; + std::vector unitSphereDots_; + ArrayRef radius_; + int flags_; + mutable AnalysisNeighborhood nb_; }; -SurfaceAreaCalculator::SurfaceAreaCalculator() - : impl_(new Impl()) -{ -} +SurfaceAreaCalculator::SurfaceAreaCalculator() : impl_(new Impl()) {} -SurfaceAreaCalculator::~SurfaceAreaCalculator() -{ -} +SurfaceAreaCalculator::~SurfaceAreaCalculator() {} void SurfaceAreaCalculator::setDotCount(int dotCount) { impl_->unitSphereDots_ = make_unsp(dotCount, 4); } -void SurfaceAreaCalculator::setRadii(const ArrayRef &radius) +void SurfaceAreaCalculator::setRadii(const ArrayRef& radius) { impl_->radius_ = radius; if (!radius.empty()) { const real maxRadius = *std::max_element(radius.begin(), radius.end()); - impl_->nb_.setCutoff(2*maxRadius); + impl_->nb_.setCutoff(2 * maxRadius); } } @@ -802,13 +829,19 @@ void SurfaceAreaCalculator::setCalculateSurfaceDots(bool bDots) } } -void SurfaceAreaCalculator::calculate( - const rvec *x, const t_pbc *pbc, - int nat, int index[], int flags, real *area, real *volume, - real **at_area, real **lidots, int *n_dots) const +void SurfaceAreaCalculator::calculate(const rvec* x, + const t_pbc* pbc, + int nat, + int index[], + int flags, + real* area, + real* volume, + real** at_area, + real** lidots, + int* n_dots) const { flags |= impl_->flags_; - *area = 0; + *area = 0; if (volume == nullptr) { flags &= ~FLAG_VOLUME; @@ -841,10 +874,8 @@ void SurfaceAreaCalculator::calculate( { *n_dots = 0; } - nsc_dclm_pbc(x, impl_->radius_, nat, - &impl_->unitSphereDots_[0], impl_->unitSphereDots_.size()/3, - flags, area, at_area, volume, lidots, n_dots, index, - &impl_->nb_, pbc); + nsc_dclm_pbc(x, impl_->radius_, nat, &impl_->unitSphereDots_[0], impl_->unitSphereDots_.size() / 3, + flags, area, at_area, volume, lidots, n_dots, index, &impl_->nb_, pbc); } } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/modules/surfacearea.h b/src/gromacs/trajectoryanalysis/modules/surfacearea.h index 09a0a8269c..cdfab3e7e2 100644 --- a/src/gromacs/trajectoryanalysis/modules/surfacearea.h +++ b/src/gromacs/trajectoryanalysis/modules/surfacearea.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,9 +44,9 @@ struct t_pbc; -#define FLAG_DOTS 01 -#define FLAG_VOLUME 02 -#define FLAG_ATOM_AREA 04 +#define FLAG_DOTS 01 +#define FLAG_VOLUME 02 +#define FLAG_ATOM_AREA 04 namespace gmx { @@ -75,107 +75,113 @@ namespace gmx */ class SurfaceAreaCalculator { - public: - /*! \brief - * Initializes a surface area calculator. - * - * \throws std::bad_alloc if out of memory. - */ - SurfaceAreaCalculator(); - ~SurfaceAreaCalculator(); +public: + /*! \brief + * Initializes a surface area calculator. + * + * \throws std::bad_alloc if out of memory. + */ + SurfaceAreaCalculator(); + ~SurfaceAreaCalculator(); - /*! \brief - * Sets the number of surface dots per sphere to use. - * - * This function must be called before calculate() to set the desired - * accuracy/computational cost. - */ - void setDotCount(int dotCount); - /*! \brief - * Sets the radii of spheres to use in the calculation. - * - * \param[in] radius Radius for each atom/sphere. - * - * This function must be called before calculate() to set the radii for - * the spheres. All calculations must use the same set of radii to - * share the same grid search. - * These radii are used as-is, without adding any probe radius. - * The passed array must remain valid for the lifetime of this object. - * - * Does not throw. - */ - void setRadii(const ArrayRef &radius); + /*! \brief + * Sets the number of surface dots per sphere to use. + * + * This function must be called before calculate() to set the desired + * accuracy/computational cost. + */ + void setDotCount(int dotCount); + /*! \brief + * Sets the radii of spheres to use in the calculation. + * + * \param[in] radius Radius for each atom/sphere. + * + * This function must be called before calculate() to set the radii for + * the spheres. All calculations must use the same set of radii to + * share the same grid search. + * These radii are used as-is, without adding any probe radius. + * The passed array must remain valid for the lifetime of this object. + * + * Does not throw. + */ + void setRadii(const ArrayRef& radius); - /*! \brief - * Requests calculation of volume. - * - * If not called, and FLAG_VOLUME is not passed to calculate(), the - * volume output is not produced. - * - * Does not throw. - */ - void setCalculateVolume(bool bVolume); - /*! \brief - * Requests output of per-atom areas. - * - * If not called, and FLAG_ATOM_AREA is not passed to calculate(), the - * atom area output is not produced. - * - * Does not throw. - */ - void setCalculateAtomArea(bool bAtomArea); - /*! \brief - * Requests output of all surface dots. - * - * If not called, and FLAG_DOTS is not passed to calculate(), the - * surface dot output is not produced. - * - * Does not throw. - */ - void setCalculateSurfaceDots(bool bDots); + /*! \brief + * Requests calculation of volume. + * + * If not called, and FLAG_VOLUME is not passed to calculate(), the + * volume output is not produced. + * + * Does not throw. + */ + void setCalculateVolume(bool bVolume); + /*! \brief + * Requests output of per-atom areas. + * + * If not called, and FLAG_ATOM_AREA is not passed to calculate(), the + * atom area output is not produced. + * + * Does not throw. + */ + void setCalculateAtomArea(bool bAtomArea); + /*! \brief + * Requests output of all surface dots. + * + * If not called, and FLAG_DOTS is not passed to calculate(), the + * surface dot output is not produced. + * + * Does not throw. + */ + void setCalculateSurfaceDots(bool bDots); - /*! \brief - * Calculates the surface area for a set of positions. - * - * \param[in] x Atom positions (sphere centers). - * \param[in] pbc PBC information (if `NULL`, calculation is done - * without PBC). - * \param[in] nat Number of atoms to calculate. - * \param[in] index Atom indices to include in the calculation. - * \param[in] flags Additional flags for the calculation. - * \param[out] area Total surface area (must be non-`NULL`). - * \param[out] volume Total volume (can be `NULL`). - * \param[out] at_area Surface area for each atom in \p index - * (\p nat values) (can be `NULL`). - * \param[out] lidots Surface dots as x,y,z triplets (`3*lidots` values) - * (can be `NULL`). - * \param[out] n_dots Number of surface dots in \p lidots - * (can be `NULL`). - * - * Calculates the surface area of spheres centered at `x[index[0]]`, - * ..., `x[index[nat-1]]`, with radii `radii[index[0]]`, ..., where - * `radii` is the array passed to setRadii(). - * - * If \p flags is 0, the calculation is done for the items specified - * with setCalculateVolume(), setCalculateAtomArea(), and - * setCalculateSurfaceDots(). Flags can specify FLAG_VOLUME, - * FLAG_ATOM_AREA, and/or FLAG_DOTS to request additional output for - * this particular calculation. If any output is `NULL`, that output - * is not calculated, irrespective of the calculation mode set. - * - * \todo - * Make the output options more C++-like, in particular for the array - * outputs. - */ - void calculate(const rvec *x, const t_pbc *pbc, - int nat, int index[], int flags, real *area, - real *volume, real **at_area, - real **lidots, int *n_dots) const; + /*! \brief + * Calculates the surface area for a set of positions. + * + * \param[in] x Atom positions (sphere centers). + * \param[in] pbc PBC information (if `NULL`, calculation is done + * without PBC). + * \param[in] nat Number of atoms to calculate. + * \param[in] index Atom indices to include in the calculation. + * \param[in] flags Additional flags for the calculation. + * \param[out] area Total surface area (must be non-`NULL`). + * \param[out] volume Total volume (can be `NULL`). + * \param[out] at_area Surface area for each atom in \p index + * (\p nat values) (can be `NULL`). + * \param[out] lidots Surface dots as x,y,z triplets (`3*lidots` values) + * (can be `NULL`). + * \param[out] n_dots Number of surface dots in \p lidots + * (can be `NULL`). + * + * Calculates the surface area of spheres centered at `x[index[0]]`, + * ..., `x[index[nat-1]]`, with radii `radii[index[0]]`, ..., where + * `radii` is the array passed to setRadii(). + * + * If \p flags is 0, the calculation is done for the items specified + * with setCalculateVolume(), setCalculateAtomArea(), and + * setCalculateSurfaceDots(). Flags can specify FLAG_VOLUME, + * FLAG_ATOM_AREA, and/or FLAG_DOTS to request additional output for + * this particular calculation. If any output is `NULL`, that output + * is not calculated, irrespective of the calculation mode set. + * + * \todo + * Make the output options more C++-like, in particular for the array + * outputs. + */ + void calculate(const rvec* x, + const t_pbc* pbc, + int nat, + int index[], + int flags, + real* area, + real* volume, + real** at_area, + real** lidots, + int* n_dots) const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/modules/trajectory.cpp b/src/gromacs/trajectoryanalysis/modules/trajectory.cpp index 71351caeb9..303d5dd792 100644 --- a/src/gromacs/trajectoryanalysis/modules/trajectory.cpp +++ b/src/gromacs/trajectoryanalysis/modules/trajectory.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,37 +71,33 @@ namespace class Trajectory : public TrajectoryAnalysisModule { - public: - Trajectory(); +public: + Trajectory(); - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void optionsFinished(TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void optionsFinished(TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; - void finishAnalysis(int nframes) override; - void writeOutput() override; + void finishAnalysis(int nframes) override; + void writeOutput() override; - private: - SelectionList sel_; +private: + SelectionList sel_; - std::string fnX_; - std::string fnV_; - std::string fnF_; - std::array dimMask_; - std::array maskSet_; + std::string fnX_; + std::string fnV_; + std::string fnF_; + std::array dimMask_; + std::array maskSet_; - AnalysisData xdata_; - AnalysisData vdata_; - AnalysisData fdata_; + AnalysisData xdata_; + AnalysisData vdata_; + AnalysisData fdata_; }; -Trajectory::Trajectory() : - dimMask_ {true, true, true, false}, maskSet_ {} +Trajectory::Trajectory() : dimMask_{ true, true, true, false }, maskSet_{} { registerAnalysisDataset(&xdata_, "x"); registerAnalysisDataset(&vdata_, "v"); @@ -109,10 +105,9 @@ Trajectory::Trajectory() : } -void -Trajectory::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings *settings) +void Trajectory::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { + static const char* const desc[] = { "[THISMODULE] plots coordinates, velocities, and/or forces for", "provided selections. By default, the X, Y, and Z components for", "the requested vectors are plotted, but specifying one or more of", @@ -124,37 +119,41 @@ Trajectory::initOptions(IOptionsContainer *options, TrajectoryAnalysisSettings * settings->setHelpText(desc); - options->addOption(FileNameOption("ox").filetype(eftPlot).outputFile() - .store(&fnX_).defaultBasename("coord") - .description("Coordinates for each position as a function of time")); - options->addOption(FileNameOption("ov").filetype(eftPlot).outputFile() - .store(&fnV_).defaultBasename("veloc") - .description("Velocities for each position as a function of time")); - options->addOption(FileNameOption("of").filetype(eftPlot).outputFile() - .store(&fnF_).defaultBasename("force") - .description("Forces for each position as a function of time")); - - options->addOption(SelectionOption("select").storeVector(&sel_) - .required().dynamicMask().multiValue() - .description("Selections to analyze")); - - options->addOption(BooleanOption("x").store(&dimMask_[XX]) - .storeIsSet(&maskSet_[XX]) - .description("Plot X component")); - options->addOption(BooleanOption("y").store(&dimMask_[YY]) - .storeIsSet(&maskSet_[YY]) - .description("Plot Y component")); - options->addOption(BooleanOption("z").store(&dimMask_[ZZ]) - .storeIsSet(&maskSet_[ZZ]) - .description("Plot Z component")); - options->addOption(BooleanOption("len").store(&dimMask_[DIM]) - .storeIsSet(&maskSet_[DIM]) - .description("Plot vector length")); + options->addOption(FileNameOption("ox") + .filetype(eftPlot) + .outputFile() + .store(&fnX_) + .defaultBasename("coord") + .description("Coordinates for each position as a function of time")); + options->addOption(FileNameOption("ov") + .filetype(eftPlot) + .outputFile() + .store(&fnV_) + .defaultBasename("veloc") + .description("Velocities for each position as a function of time")); + options->addOption(FileNameOption("of") + .filetype(eftPlot) + .outputFile() + .store(&fnF_) + .defaultBasename("force") + .description("Forces for each position as a function of time")); + + options->addOption( + SelectionOption("select").storeVector(&sel_).required().dynamicMask().multiValue().description( + "Selections to analyze")); + + options->addOption( + BooleanOption("x").store(&dimMask_[XX]).storeIsSet(&maskSet_[XX]).description("Plot X component")); + options->addOption( + BooleanOption("y").store(&dimMask_[YY]).storeIsSet(&maskSet_[YY]).description("Plot Y component")); + options->addOption( + BooleanOption("z").store(&dimMask_[ZZ]).storeIsSet(&maskSet_[ZZ]).description("Plot Z component")); + options->addOption( + BooleanOption("len").store(&dimMask_[DIM]).storeIsSet(&maskSet_[DIM]).description("Plot vector length")); } -void -Trajectory::optionsFinished(TrajectoryAnalysisSettings *settings) +void Trajectory::optionsFinished(TrajectoryAnalysisSettings* settings) { int frameFlags = TRX_NEED_X; if (!fnV_.empty()) @@ -179,19 +178,16 @@ Trajectory::optionsFinished(TrajectoryAnalysisSettings *settings) } -void -Trajectory::initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation & /*top*/) +void Trajectory::initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& /*top*/) { if (!fnX_.empty()) { xdata_.setDataSetCount(sel_.size()); for (size_t g = 0; g < sel_.size(); ++g) { - xdata_.setColumnCount(g, 3*sel_[g].posCount()); + xdata_.setColumnCount(g, 3 * sel_[g].posCount()); } - AnalysisDataVectorPlotModulePointer plot( - new AnalysisDataVectorPlotModule(settings.plotSettings())); + AnalysisDataVectorPlotModulePointer plot(new AnalysisDataVectorPlotModule(settings.plotSettings())); plot->setWriteMask(dimMask_.data()); plot->setFileName(fnX_); plot->setTitle("Coordinates"); @@ -205,10 +201,9 @@ Trajectory::initAnalysis(const TrajectoryAnalysisSettings &settings, for (size_t g = 0; g < sel_.size(); ++g) { sel_[g].setEvaluateVelocities(true); - vdata_.setColumnCount(g, 3*sel_[g].posCount()); + vdata_.setColumnCount(g, 3 * sel_[g].posCount()); } - AnalysisDataVectorPlotModulePointer plot( - new AnalysisDataVectorPlotModule(settings.plotSettings())); + AnalysisDataVectorPlotModulePointer plot(new AnalysisDataVectorPlotModule(settings.plotSettings())); plot->setWriteMask(dimMask_.data()); plot->setFileName(fnV_); plot->setTitle("Velocities"); @@ -222,10 +217,9 @@ Trajectory::initAnalysis(const TrajectoryAnalysisSettings &settings, for (size_t g = 0; g < sel_.size(); ++g) { sel_[g].setEvaluateForces(true); - fdata_.setColumnCount(g, 3*sel_[g].posCount()); + fdata_.setColumnCount(g, 3 * sel_[g].posCount()); } - AnalysisDataVectorPlotModulePointer plot( - new AnalysisDataVectorPlotModule(settings.plotSettings())); + AnalysisDataVectorPlotModulePointer plot(new AnalysisDataVectorPlotModule(settings.plotSettings())); plot->setWriteMask(dimMask_.data()); plot->setFileName(fnF_); plot->setTitle("Forces"); @@ -237,9 +231,8 @@ Trajectory::initAnalysis(const TrajectoryAnalysisSettings &settings, //! Helper function for Trajectory::analyzeFrame -template void -analyzeFrameImpl(int frnr, const t_trxframe &fr, - AnalysisDataHandle* dh, const SelectionList &sel, T getField) +template +void analyzeFrameImpl(int frnr, const t_trxframe& fr, AnalysisDataHandle* dh, const SelectionList& sel, T getField) { if (dh->isValid()) { @@ -249,49 +242,40 @@ analyzeFrameImpl(int frnr, const t_trxframe &fr, dh->selectDataSet(g); for (int i = 0; i < sel[g].posCount(); ++i) { - const SelectionPosition &pos = sel[g].position(i); - dh->setPoints(i*3, 3, getField(pos), pos.selected()); + const SelectionPosition& pos = sel[g].position(i); + dh->setPoints(i * 3, 3, getField(pos), pos.selected()); } } dh->finishFrame(); } } -void -Trajectory::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc * /* pbc */, - TrajectoryAnalysisModuleData *pdata) +void Trajectory::analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* /* pbc */, TrajectoryAnalysisModuleData* pdata) { AnalysisDataHandle dh = pdata->dataHandle(xdata_); - const SelectionList &sel = pdata->parallelSelections(sel_); - analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition &pos) { return pos.x(); }); + const SelectionList& sel = pdata->parallelSelections(sel_); + analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition& pos) { return pos.x(); }); if (fr.bV) { - analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition &pos) { return pos.v(); }); + analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition& pos) { return pos.v(); }); } if (fr.bF) { - analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition &pos) { return pos.f(); }); + analyzeFrameImpl(frnr, fr, &dh, sel, [](const SelectionPosition& pos) { return pos.f(); }); } - } -void -Trajectory::finishAnalysis(int /*nframes*/) -{ -} +void Trajectory::finishAnalysis(int /*nframes*/) {} -void -Trajectory::writeOutput() -{ -} +void Trajectory::writeOutput() {} -} // namespace +} // namespace -const char TrajectoryInfo::name[] = "trajectory"; +const char TrajectoryInfo::name[] = "trajectory"; const char TrajectoryInfo::shortDescription[] = - "Print coordinates, velocities, and/or forces for selections"; + "Print coordinates, velocities, and/or forces for selections"; TrajectoryAnalysisModulePointer TrajectoryInfo::create() { diff --git a/src/gromacs/trajectoryanalysis/modules/trajectory.h b/src/gromacs/trajectoryanalysis/modules/trajectory.h index 1f510af6a4..260fe7b10c 100644 --- a/src/gromacs/trajectoryanalysis/modules/trajectory.h +++ b/src/gromacs/trajectoryanalysis/modules/trajectory.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,10 +52,10 @@ namespace analysismodules class TrajectoryInfo { - public: - static const char name[]; - static const char shortDescription[]; - static TrajectoryAnalysisModulePointer create(); +public: + static const char name[]; + static const char shortDescription[]; + static TrajectoryAnalysisModulePointer create(); }; } // namespace analysismodules diff --git a/src/gromacs/trajectoryanalysis/modules/unionfind.h b/src/gromacs/trajectoryanalysis/modules/unionfind.h index afec611849..0b123575b2 100644 --- a/src/gromacs/trajectoryanalysis/modules/unionfind.h +++ b/src/gromacs/trajectoryanalysis/modules/unionfind.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,99 +71,98 @@ namespace gmx */ class UnionFinder { - public: - /*! \brief - * Initializes `count` items, putting each in its own set. - */ - void init(int count) +public: + /*! \brief + * Initializes `count` items, putting each in its own set. + */ + void init(int count) + { + parent_.clear(); + rank_.clear(); + parent_.reserve(count); + rank_.reserve(count); + parent_.resize(count); + rank_.resize(count, 0); + std::iota(parent_.begin(), parent_.end(), 0); + } + /*! \brief + * Merges sets that contain two given items. + * + * If the items are already in the same set, nothing happens. + */ + void merge(int item1, int item2) + { + GMX_ASSERT(item1 >= 0 && item1 < count(), "Input index out of range"); + GMX_ASSERT(item2 >= 0 && item2 < count(), "Input index out of range"); + const int root1 = findRootAndCompressPath(item1); + const int root2 = findRootAndCompressPath(item2); + if (root1 != root2) { - parent_.clear(); - rank_.clear(); - parent_.reserve(count); - rank_.reserve(count); - parent_.resize(count); - rank_.resize(count, 0); - std::iota(parent_.begin(), parent_.end(), 0); + mergeRoots(root1, root2); } - /*! \brief - * Merges sets that contain two given items. - * - * If the items are already in the same set, nothing happens. - */ - void merge(int item1, int item2) + } + /*! \brief + * Returns a representative item from the set containing `item`. + */ + int representativeItem(int item) + { + GMX_ASSERT(item >= 0 && item < count(), "Input index out of range"); + return findRootAndCompressPath(item); + } + /*! \brief + * Returns the sizes of all sets (in arbitrary order). + */ + std::vector allSizes() + { + const int count = parent_.size(); + std::vector result(count, 0); + for (int i = 0; i < count; ++i) { - GMX_ASSERT(item1 >= 0 && item1 < count(), "Input index out of range"); - GMX_ASSERT(item2 >= 0 && item2 < count(), "Input index out of range"); - const int root1 = findRootAndCompressPath(item1); - const int root2 = findRootAndCompressPath(item2); - if (root1 != root2) - { - mergeRoots(root1, root2); - } + ++result[findRootAndCompressPath(i)]; } - /*! \brief - * Returns a representative item from the set containing `item`. - */ - int representativeItem(int item) + result.erase(std::remove(result.begin(), result.end(), 0), result.end()); + return result; + } + +private: + //! Number of items. + int count() const { return parent_.size(); } + int findRootAndCompressPath(int i) + { + while (parent_[i] != i) { - GMX_ASSERT(item >= 0 && item < count(), "Input index out of range"); - return findRootAndCompressPath(item); + const int prev = i; + i = parent_[i]; + parent_[prev] = parent_[i]; } - /*! \brief - * Returns the sizes of all sets (in arbitrary order). - */ - std::vector allSizes() + return i; + } + void mergeRoots(int root1, int root2) + { + if (rank_[root1] > rank_[root2]) { - const int count = parent_.size(); - std::vector result(count, 0); - for (int i = 0; i < count; ++i) - { - ++result[findRootAndCompressPath(i)]; - } - result.erase(std::remove(result.begin(), result.end(), 0), - result.end()); - return result; + parent_[root2] = root1; } - - private: - //! Number of items. - int count() const { return parent_.size(); } - int findRootAndCompressPath(int i) + else if (rank_[root2] > rank_[root1]) { - while (parent_[i] != i) - { - const int prev = i; - i = parent_[i]; - parent_[prev] = parent_[i]; - } - return i; + parent_[root1] = root2; } - void mergeRoots(int root1, int root2) + else { - if (rank_[root1] > rank_[root2]) - { - parent_[root2] = root1; - } - else if (rank_[root2] > rank_[root1]) - { - parent_[root1] = root2; - } - else - { - parent_[root1] = root2; - ++rank_[root1]; - } + parent_[root1] = root2; + ++rank_[root1]; } + } - /*! \brief - * Parent item for each item in the tree representing the set. - * - * Root items are parents of themselves, and are the reprensentative - * items of their sets. - */ - std::vector parent_; - //! Worst-case height for each root (as if no compression was done). - std::vector rank_; + /*! \brief + * Parent item for each item in the tree representing the set. + * + * Root items are parents of themselves, and are the reprensentative + * items of their sets. + */ + std::vector parent_; + //! Worst-case height for each root (as if no compression was done). + std::vector rank_; }; /*! \libinternal \brief @@ -182,90 +181,80 @@ class UnionFinder */ class MappedUnionFinder { - public: - /*! \brief - * Initializes the finder with indices. - * - * The size of `indices` sets the number of input items, and each - * unique value in `indices` maps to a single internal item. - * If multiple indices are the same, then these items are considered - * equivalent. - */ - void initWithGroupIndices(ArrayRef indices) +public: + /*! \brief + * Initializes the finder with indices. + * + * The size of `indices` sets the number of input items, and each + * unique value in `indices` maps to a single internal item. + * If multiple indices are the same, then these items are considered + * equivalent. + */ + void initWithGroupIndices(ArrayRef indices) + { + mapping_.clear(); + int groupCount = 0; + if (!indices.empty()) { - mapping_.clear(); - int groupCount = 0; - if (!indices.empty()) + const int maxIndex = *std::max_element(indices.begin(), indices.end()); + mapping_.resize(maxIndex + 1, -1); + for (int item : indices) { - const int maxIndex = *std::max_element(indices.begin(), - indices.end()); - mapping_.resize(maxIndex + 1, -1); - for (int item : indices) + GMX_ASSERT(item >= 0, "Negative group numbers not supported"); + if (mapping_[item] == -1) { - GMX_ASSERT(item >= 0, "Negative group numbers not supported"); - if (mapping_[item] == -1) - { - mapping_[item] = groupCount; - ++groupCount; - } + mapping_[item] = groupCount; + ++groupCount; } } - finder_.init(groupCount); - } - /*! \brief - * Returns a reprensetative value for an item that is unique for each - * set. - * - * `group` should be one of the values that were passed in as an index - * to initWithGroupIndices(). - * The return value is an internal index that has no simple relation to - * the input indices. - */ - int representativeValue(int group) - { - GMX_ASSERT(group >= 0 && group < maxGroupNumber(), - "Input value out of range"); - GMX_ASSERT(mapping_[group] != -1, - "Input value not in initialization set"); - return finder_.representativeItem(mapping_[group]); - } - /*! \brief - * Merges sets that contain two given items. - * - * If the items are already in the same set, nothing happens. - * Each input value should be one of the values that were passed in as - * an index to initWithGroupIndices(). - */ - void mergeGroups(int group1, int group2) - { - GMX_ASSERT(group1 >= 0 && group1 < maxGroupNumber(), - "Input value out of range"); - GMX_ASSERT(group2 >= 0 && group2 < maxGroupNumber(), - "Input value out of range"); - GMX_ASSERT(mapping_[group1] != -1, - "Input value not in initialization set"); - GMX_ASSERT(mapping_[group2] != -1, - "Input value not in initialization set"); - finder_.merge(mapping_[group1], mapping_[group2]); - } - /*! \brief - * Returns the sizes of all sets (in arbitrary order). - * - * If there were multiple identical indices passed to - * initWithGroupIndices(), these are only counted as one when - * computing the sizes. - */ - std::vector allSizes() - { - return finder_.allSizes(); } + finder_.init(groupCount); + } + /*! \brief + * Returns a reprensetative value for an item that is unique for each + * set. + * + * `group` should be one of the values that were passed in as an index + * to initWithGroupIndices(). + * The return value is an internal index that has no simple relation to + * the input indices. + */ + int representativeValue(int group) + { + GMX_ASSERT(group >= 0 && group < maxGroupNumber(), "Input value out of range"); + GMX_ASSERT(mapping_[group] != -1, "Input value not in initialization set"); + return finder_.representativeItem(mapping_[group]); + } + /*! \brief + * Merges sets that contain two given items. + * + * If the items are already in the same set, nothing happens. + * Each input value should be one of the values that were passed in as + * an index to initWithGroupIndices(). + */ + void mergeGroups(int group1, int group2) + { + GMX_ASSERT(group1 >= 0 && group1 < maxGroupNumber(), "Input value out of range"); + GMX_ASSERT(group2 >= 0 && group2 < maxGroupNumber(), "Input value out of range"); + GMX_ASSERT(mapping_[group1] != -1, "Input value not in initialization set"); + GMX_ASSERT(mapping_[group2] != -1, "Input value not in initialization set"); + finder_.merge(mapping_[group1], mapping_[group2]); + } + /*! \brief + * Returns the sizes of all sets (in arbitrary order). + * + * If there were multiple identical indices passed to + * initWithGroupIndices(), these are only counted as one when + * computing the sizes. + */ + std::vector allSizes() { return finder_.allSizes(); } - private: - int maxGroupNumber() const { return mapping_.size(); } +private: + int maxGroupNumber() const { return mapping_.size(); } - UnionFinder finder_; - //! Mapping from input indices to zero-based indices used by finder_. - std::vector mapping_; + UnionFinder finder_; + //! Mapping from input indices to zero-based indices used by finder_. + std::vector mapping_; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/runnercommon.cpp b/src/gromacs/trajectoryanalysis/runnercommon.cpp index 93e47cec84..7496d39102 100644 --- a/src/gromacs/trajectoryanalysis/runnercommon.cpp +++ b/src/gromacs/trajectoryanalysis/runnercommon.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -78,69 +79,78 @@ namespace gmx class TrajectoryAnalysisRunnerCommon::Impl : public ITopologyProvider { - public: - explicit Impl(TrajectoryAnalysisSettings *settings); - ~Impl() override; +public: + explicit Impl(TrajectoryAnalysisSettings* settings); + ~Impl() override; - bool hasTrajectory() const { return !trjfile_.empty(); } + bool hasTrajectory() const { return !trjfile_.empty(); } - void initTopology(bool required); - void initFirstFrame(); - void initFrameIndexGroup(); - void finishTrajectory(); + void initTopology(bool required); + void initFirstFrame(); + void initFrameIndexGroup(); + void finishTrajectory(); - // From ITopologyProvider - gmx_mtop_t *getTopology(bool required) override - { - initTopology(required); - return topInfo_.mtop_.get(); - } - int getAtomCount() override + // From ITopologyProvider + gmx_mtop_t* getTopology(bool required) override + { + initTopology(required); + return topInfo_.mtop_.get(); + } + int getAtomCount() override + { + if (!topInfo_.hasTopology()) { - if (!topInfo_.hasTopology()) + if (trajectoryGroup_.isValid()) { - if (trajectoryGroup_.isValid()) - { - GMX_THROW(InconsistentInputError("-fgroup is only supported when -s is also specified")); - } - // Read the first frame if we don't know the maximum number of - // atoms otherwise. - initFirstFrame(); - return fr->natoms; + GMX_THROW(InconsistentInputError( + "-fgroup is only supported when -s is also specified")); } - return -1; + // Read the first frame if we don't know the maximum number of + // atoms otherwise. + initFirstFrame(); + return fr->natoms; } + return -1; + } - TrajectoryAnalysisSettings &settings_; - TopologyInformation topInfo_; - - //! Name of the trajectory file (empty if not provided). - std::string trjfile_; - //! Name of the topology file (empty if no topology provided). - std::string topfile_; - Selection trajectoryGroup_; - double startTime_; - double endTime_; - double deltaTime_; - bool bStartTimeSet_; - bool bEndTimeSet_; - bool bDeltaTimeSet_; - - bool bTrajOpen_; - //! The current frame, or \p NULL if no frame loaded yet. - t_trxframe *fr; - gmx_rmpbc_t gpbc_; - //! Used to store the status variable from read_first_frame(). - t_trxstatus *status_; - gmx_output_env_t *oenv_; + TrajectoryAnalysisSettings& settings_; + TopologyInformation topInfo_; + + //! Name of the trajectory file (empty if not provided). + std::string trjfile_; + //! Name of the topology file (empty if no topology provided). + std::string topfile_; + Selection trajectoryGroup_; + double startTime_; + double endTime_; + double deltaTime_; + bool bStartTimeSet_; + bool bEndTimeSet_; + bool bDeltaTimeSet_; + + bool bTrajOpen_; + //! The current frame, or \p NULL if no frame loaded yet. + t_trxframe* fr; + gmx_rmpbc_t gpbc_; + //! Used to store the status variable from read_first_frame(). + t_trxstatus* status_; + gmx_output_env_t* oenv_; }; -TrajectoryAnalysisRunnerCommon::Impl::Impl(TrajectoryAnalysisSettings *settings) - : settings_(*settings), - startTime_(0.0), endTime_(0.0), deltaTime_(0.0), - bStartTimeSet_(false), bEndTimeSet_(false), bDeltaTimeSet_(false), - bTrajOpen_(false), fr(nullptr), gpbc_(nullptr), status_(nullptr), oenv_(nullptr) +TrajectoryAnalysisRunnerCommon::Impl::Impl(TrajectoryAnalysisSettings* settings) : + settings_(*settings), + startTime_(0.0), + endTime_(0.0), + deltaTime_(0.0), + bStartTimeSet_(false), + bEndTimeSet_(false), + bDeltaTimeSet_(false), + bTrajOpen_(false), + fr(nullptr), + gpbc_(nullptr), + status_(nullptr), + oenv_(nullptr) { } @@ -163,8 +173,7 @@ TrajectoryAnalysisRunnerCommon::Impl::~Impl() } } -void -TrajectoryAnalysisRunnerCommon::Impl::initTopology(bool required) +void TrajectoryAnalysisRunnerCommon::Impl::initTopology(bool required) { // Return immediately if the topology has already been loaded. if (topInfo_.hasTopology()) @@ -181,29 +190,25 @@ TrajectoryAnalysisRunnerCommon::Impl::initTopology(bool required) if (!topfile_.empty()) { topInfo_.fillFromInputFile(topfile_); - if (hasTrajectory() - && !settings_.hasFlag(TrajectoryAnalysisSettings::efUseTopX)) + if (hasTrajectory() && !settings_.hasFlag(TrajectoryAnalysisSettings::efUseTopX)) { topInfo_.xtop_.clear(); } - if (hasTrajectory() - && !settings_.hasFlag(TrajectoryAnalysisSettings::efUseTopV)) + if (hasTrajectory() && !settings_.hasFlag(TrajectoryAnalysisSettings::efUseTopV)) { topInfo_.vtop_.clear(); } } } -void -TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame() +void TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame() { // Return if we have already initialized the trajectory. if (fr != nullptr) { return; } - time_unit_t time_unit - = static_cast(settings_.timeUnit() + 1); // NOLINT(bugprone-misplaced-widening-cast) + time_unit_t time_unit = static_cast(settings_.timeUnit() + 1); // NOLINT(bugprone-misplaced-widening-cast) output_env_init(&oenv_, getProgramContext(), time_unit, FALSE, exvgNONE, 0); int frflags = settings_.frflags(); @@ -224,9 +229,9 @@ TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame() const int topologyAtomCount = topInfo_.mtop()->natoms; if (fr->natoms > topologyAtomCount) { - const std::string message - = formatString("Trajectory (%d atoms) does not match topology (%d atoms)", - fr->natoms, topologyAtomCount); + const std::string message = + formatString("Trajectory (%d atoms) does not match topology (%d atoms)", + fr->natoms, topologyAtomCount); GMX_THROW(InconsistentInputError(message)); } } @@ -241,56 +246,50 @@ TrajectoryAnalysisRunnerCommon::Impl::initFirstFrame() fr->natoms = topInfo_.mtop()->natoms; fr->bX = TRUE; snew(fr->x, fr->natoms); - memcpy(fr->x, topInfo_.xtop_.data(), - sizeof(*fr->x) * fr->natoms); + memcpy(fr->x, topInfo_.xtop_.data(), sizeof(*fr->x) * fr->natoms); if (frflags & (TRX_NEED_V)) { if (topInfo_.vtop_.empty()) { - GMX_THROW(InvalidInputError("Velocities were required, but could not be read from the topology file")); + GMX_THROW(InvalidInputError( + "Velocities were required, but could not be read from the topology file")); } fr->bV = TRUE; snew(fr->v, fr->natoms); - memcpy(fr->v, topInfo_.vtop_.data(), - sizeof(*fr->v) * fr->natoms); + memcpy(fr->v, topInfo_.vtop_.data(), sizeof(*fr->v) * fr->natoms); } - fr->bBox = TRUE; + fr->bBox = TRUE; copy_mat(topInfo_.boxtop_, fr->box); } set_trxframe_ePBC(fr, topInfo_.ePBC()); if (topInfo_.hasTopology() && settings_.hasRmPBC()) { - gpbc_ = gmx_rmpbc_init(topInfo_); + gpbc_ = gmx_rmpbc_init(topInfo_); } } -void -TrajectoryAnalysisRunnerCommon::Impl::initFrameIndexGroup() +void TrajectoryAnalysisRunnerCommon::Impl::initFrameIndexGroup() { if (!trajectoryGroup_.isValid()) { return; } - GMX_RELEASE_ASSERT(bTrajOpen_, - "Trajectory index only makes sense with a real trajectory"); + GMX_RELEASE_ASSERT(bTrajOpen_, "Trajectory index only makes sense with a real trajectory"); if (trajectoryGroup_.atomCount() != fr->natoms) { const std::string message = formatString( - "Selection specified with -fgroup has %d atoms, but " - "the trajectory (-f) has %d atoms.", - trajectoryGroup_.atomCount(), fr->natoms); + "Selection specified with -fgroup has %d atoms, but " + "the trajectory (-f) has %d atoms.", + trajectoryGroup_.atomCount(), fr->natoms); GMX_THROW(InconsistentInputError(message)); } fr->bIndex = TRUE; snew(fr->index, trajectoryGroup_.atomCount()); - std::copy(trajectoryGroup_.atomIndices().begin(), - trajectoryGroup_.atomIndices().end(), - fr->index); + std::copy(trajectoryGroup_.atomIndices().begin(), trajectoryGroup_.atomIndices().end(), fr->index); } -void -TrajectoryAnalysisRunnerCommon::Impl::finishTrajectory() +void TrajectoryAnalysisRunnerCommon::Impl::finishTrajectory() { if (bTrajOpen_) { @@ -308,56 +307,55 @@ TrajectoryAnalysisRunnerCommon::Impl::finishTrajectory() * TrajectoryAnalysisRunnerCommon */ -TrajectoryAnalysisRunnerCommon::TrajectoryAnalysisRunnerCommon( - TrajectoryAnalysisSettings *settings) - : impl_(new Impl(settings)) +TrajectoryAnalysisRunnerCommon::TrajectoryAnalysisRunnerCommon(TrajectoryAnalysisSettings* settings) : + impl_(new Impl(settings)) { } -TrajectoryAnalysisRunnerCommon::~TrajectoryAnalysisRunnerCommon() -{ -} +TrajectoryAnalysisRunnerCommon::~TrajectoryAnalysisRunnerCommon() {} -ITopologyProvider * -TrajectoryAnalysisRunnerCommon::topologyProvider() +ITopologyProvider* TrajectoryAnalysisRunnerCommon::topologyProvider() { return impl_.get(); } -void -TrajectoryAnalysisRunnerCommon::initOptions(IOptionsContainer *options, - TimeUnitBehavior *timeUnitBehavior) +void TrajectoryAnalysisRunnerCommon::initOptions(IOptionsContainer* options, TimeUnitBehavior* timeUnitBehavior) { - TrajectoryAnalysisSettings &settings = impl_->settings_; + TrajectoryAnalysisSettings& settings = impl_->settings_; // Add common file name arguments. options->addOption(FileNameOption("f") - .filetype(eftTrajectory).inputFile() - .store(&impl_->trjfile_) - .defaultBasename("traj") - .description("Input trajectory or single configuration")); + .filetype(eftTrajectory) + .inputFile() + .store(&impl_->trjfile_) + .defaultBasename("traj") + .description("Input trajectory or single configuration")); options->addOption(FileNameOption("s") - .filetype(eftTopology).inputFile() - .store(&impl_->topfile_) - .defaultBasename("topol") - .description("Input structure")); + .filetype(eftTopology) + .inputFile() + .store(&impl_->topfile_) + .defaultBasename("topol") + .description("Input structure")); // Add options for trajectory time control. options->addOption(DoubleOption("b") - .store(&impl_->startTime_).storeIsSet(&impl_->bStartTimeSet_) - .timeValue() - .description("First frame (%t) to read from trajectory")); + .store(&impl_->startTime_) + .storeIsSet(&impl_->bStartTimeSet_) + .timeValue() + .description("First frame (%t) to read from trajectory")); options->addOption(DoubleOption("e") - .store(&impl_->endTime_).storeIsSet(&impl_->bEndTimeSet_) - .timeValue() - .description("Last frame (%t) to read from trajectory")); + .store(&impl_->endTime_) + .storeIsSet(&impl_->bEndTimeSet_) + .timeValue() + .description("Last frame (%t) to read from trajectory")); options->addOption(DoubleOption("dt") - .store(&impl_->deltaTime_).storeIsSet(&impl_->bDeltaTimeSet_) - .timeValue() - .description("Only use frame if t MOD dt == first time (%t)")); + .store(&impl_->deltaTime_) + .storeIsSet(&impl_->bDeltaTimeSet_) + .timeValue() + .description("Only use frame if t MOD dt == first time (%t)")); // Add time unit option. timeUnitBehavior->setTimeUnitFromEnvironment(); @@ -365,10 +363,11 @@ TrajectoryAnalysisRunnerCommon::initOptions(IOptionsContainer *options, timeUnitBehavior->setTimeUnitStore(&impl_->settings_.impl_->timeUnit); options->addOption(SelectionOption("fgroup") - .store(&impl_->trajectoryGroup_) - .onlySortedAtoms().onlyStatic() - .description("Atoms stored in the trajectory file " - "(if not set, assume first N atoms)")); + .store(&impl_->trajectoryGroup_) + .onlySortedAtoms() + .onlyStatic() + .description("Atoms stored in the trajectory file " + "(if not set, assume first N atoms)")); // Add plot options. settings.impl_->plotSettings.initOptions(options); @@ -376,19 +375,20 @@ TrajectoryAnalysisRunnerCommon::initOptions(IOptionsContainer *options, // Add common options for trajectory processing. if (!settings.hasFlag(TrajectoryAnalysisSettings::efNoUserRmPBC)) { - options->addOption(BooleanOption("rmpbc").store(&settings.impl_->bRmPBC) - .description("Make molecules whole for each frame")); + options->addOption( + BooleanOption("rmpbc").store(&settings.impl_->bRmPBC).description("Make molecules whole for each frame")); } if (!settings.hasFlag(TrajectoryAnalysisSettings::efNoUserPBC)) { - options->addOption(BooleanOption("pbc").store(&settings.impl_->bPBC) - .description("Use periodic boundary conditions for distance calculation")); + options->addOption( + BooleanOption("pbc") + .store(&settings.impl_->bPBC) + .description("Use periodic boundary conditions for distance calculation")); } } -void -TrajectoryAnalysisRunnerCommon::optionsFinished() +void TrajectoryAnalysisRunnerCommon::optionsFinished() { if (impl_->trjfile_.empty() && impl_->topfile_.empty()) { @@ -397,7 +397,8 @@ TrajectoryAnalysisRunnerCommon::optionsFinished() if (impl_->trajectoryGroup_.isValid() && impl_->trjfile_.empty()) { - GMX_THROW(InconsistentInputError("-fgroup only makes sense together with a trajectory (-f)")); + GMX_THROW( + InconsistentInputError("-fgroup only makes sense together with a trajectory (-f)")); } impl_->settings_.impl_->plotSettings.setTimeUnit(impl_->settings_.timeUnit()); @@ -417,31 +418,26 @@ TrajectoryAnalysisRunnerCommon::optionsFinished() } -void -TrajectoryAnalysisRunnerCommon::initTopology() +void TrajectoryAnalysisRunnerCommon::initTopology() { - const bool topologyRequired = - impl_->settings_.hasFlag(TrajectoryAnalysisSettings::efRequireTop); + const bool topologyRequired = impl_->settings_.hasFlag(TrajectoryAnalysisSettings::efRequireTop); impl_->initTopology(topologyRequired); } -void -TrajectoryAnalysisRunnerCommon::initFirstFrame() +void TrajectoryAnalysisRunnerCommon::initFirstFrame() { impl_->initFirstFrame(); } -void -TrajectoryAnalysisRunnerCommon::initFrameIndexGroup() +void TrajectoryAnalysisRunnerCommon::initFrameIndexGroup() { impl_->initFrameIndexGroup(); } -bool -TrajectoryAnalysisRunnerCommon::readNextFrame() +bool TrajectoryAnalysisRunnerCommon::readNextFrame() { bool bContinue = false; if (hasTrajectory()) @@ -456,8 +452,7 @@ TrajectoryAnalysisRunnerCommon::readNextFrame() } -void -TrajectoryAnalysisRunnerCommon::initFrame() +void TrajectoryAnalysisRunnerCommon::initFrame() { if (impl_->gpbc_ != nullptr) { @@ -466,22 +461,19 @@ TrajectoryAnalysisRunnerCommon::initFrame() } -bool -TrajectoryAnalysisRunnerCommon::hasTrajectory() const +bool TrajectoryAnalysisRunnerCommon::hasTrajectory() const { return impl_->hasTrajectory(); } -const TopologyInformation & -TrajectoryAnalysisRunnerCommon::topologyInformation() const +const TopologyInformation& TrajectoryAnalysisRunnerCommon::topologyInformation() const { return impl_->topInfo_; } -t_trxframe & -TrajectoryAnalysisRunnerCommon::frame() const +t_trxframe& TrajectoryAnalysisRunnerCommon::frame() const { GMX_RELEASE_ASSERT(impl_->fr != nullptr, "Frame not available when accessed"); return *impl_->fr; diff --git a/src/gromacs/trajectoryanalysis/runnercommon.h b/src/gromacs/trajectoryanalysis/runnercommon.h index 20d7033969..a9bd8af782 100644 --- a/src/gromacs/trajectoryanalysis/runnercommon.h +++ b/src/gromacs/trajectoryanalysis/runnercommon.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,68 +67,68 @@ class TrajectoryAnalysisSettings; */ class TrajectoryAnalysisRunnerCommon { - public: - /*! \brief - * Initializes a new runner helper. - * - * \param settings Settings object to use. - */ - explicit TrajectoryAnalysisRunnerCommon(TrajectoryAnalysisSettings *settings); - ~TrajectoryAnalysisRunnerCommon(); +public: + /*! \brief + * Initializes a new runner helper. + * + * \param settings Settings object to use. + */ + explicit TrajectoryAnalysisRunnerCommon(TrajectoryAnalysisSettings* settings); + ~TrajectoryAnalysisRunnerCommon(); - //! Returns a topology provider for SelectionOptionBehavior. - ITopologyProvider *topologyProvider(); + //! Returns a topology provider for SelectionOptionBehavior. + ITopologyProvider* topologyProvider(); - /*! \brief - * Initializes common options for trajectory analysis. - * - * \param[in,out] options Options object to add the options to. - * \param[in,out] timeUnitBehavior Time unit behavior to use for adding - * and handling the `-tu` option. - */ - void initOptions(IOptionsContainer *options, TimeUnitBehavior *timeUnitBehavior); - //! Processes common option values after they have been parsed. - void optionsFinished(); - //! Load topology information if provided and/or required. - void initTopology(); - /*! \brief - * Reads the first frame from the trajectory. - * - * After this call, frame() returns the first frame. - */ - void initFirstFrame(); - /*! \brief - * Initializes the index in frame() that specifies the atoms contained. - * - * Can be called after selections have been compiled. - */ - void initFrameIndexGroup(); - /*! \brief - * Reads the next frame from the trajectory. - * - * \returns false if there were no more frames. - * - * After this call, frame() returns the newly loaded frame. - */ - bool readNextFrame(); - /*! \brief - * Performs common initialization for the currently loaded frame. - * - * Currently, makes molecules whole if requested. - */ - void initFrame(); + /*! \brief + * Initializes common options for trajectory analysis. + * + * \param[in,out] options Options object to add the options to. + * \param[in,out] timeUnitBehavior Time unit behavior to use for adding + * and handling the `-tu` option. + */ + void initOptions(IOptionsContainer* options, TimeUnitBehavior* timeUnitBehavior); + //! Processes common option values after they have been parsed. + void optionsFinished(); + //! Load topology information if provided and/or required. + void initTopology(); + /*! \brief + * Reads the first frame from the trajectory. + * + * After this call, frame() returns the first frame. + */ + void initFirstFrame(); + /*! \brief + * Initializes the index in frame() that specifies the atoms contained. + * + * Can be called after selections have been compiled. + */ + void initFrameIndexGroup(); + /*! \brief + * Reads the next frame from the trajectory. + * + * \returns false if there were no more frames. + * + * After this call, frame() returns the newly loaded frame. + */ + bool readNextFrame(); + /*! \brief + * Performs common initialization for the currently loaded frame. + * + * Currently, makes molecules whole if requested. + */ + void initFrame(); - //! Returns true if input data comes from a trajectory. - bool hasTrajectory() const; - //! Returns the topology information object. - const TopologyInformation &topologyInformation() const; - //! Returns the currently loaded frame. - t_trxframe &frame() const; + //! Returns true if input data comes from a trajectory. + bool hasTrajectory() const; + //! Returns the topology information object. + const TopologyInformation& topologyInformation() const; + //! Returns the currently loaded frame. + t_trxframe& frame() const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/trajectoryanalysis/tests/angle.cpp b/src/gromacs/trajectoryanalysis/tests/angle.cpp index 8b85aba4bd..baa369a27a 100644 --- a/src/gromacs/trajectoryanalysis/tests/angle.cpp +++ b/src/gromacs/trajectoryanalysis/tests/angle.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,15 +59,12 @@ using gmx::test::CommandLine; */ //! Test fixture for the angle analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - AngleModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture AngleModuleTest; TEST_F(AngleModuleTest, ComputesSimpleAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "angle", "-group1", "resname RA1 RA2 and name A1 A2 A3", - "-binw", "60" + const char* const cmdline[] = { + "angle", "-g1", "angle", "-group1", "resname RA1 RA2 and name A1 A2 A3", "-binw", "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); @@ -75,9 +72,8 @@ TEST_F(AngleModuleTest, ComputesSimpleAngles) TEST_F(AngleModuleTest, ComputesDihedrals) { - const char *const cmdline[] = { - "angle", - "-g1", "dihedral", "-group1", "resname RD1 RD2 RD3 and name A1 A2 A3 A4", + const char* const cmdline[] = { + "angle", "-g1", "dihedral", "-group1", "resname RD1 RD2 RD3 and name A1 A2 A3 A4", "-binw", "120" }; setTopology("angle.gro"); @@ -86,35 +82,43 @@ TEST_F(AngleModuleTest, ComputesDihedrals) TEST_F(AngleModuleTest, ComputesVectorPairAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", "-group1", "resname RV1 RV2 and name A1 A2", - "-g2", "vector", "-group2", "resname RV3 RV4 and name A1 A2", - "-binw", "60" - }; + const char* const cmdline[] = { "angle", + "-g1", + "vector", + "-group1", + "resname RV1 RV2 and name A1 A2", + "-g2", + "vector", + "-group2", + "resname RV3 RV4 and name A1 A2", + "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); } TEST_F(AngleModuleTest, ComputesVectorPlanePairAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", "-group1", "resname RV1 RV2 and name A1 A2", - "-g2", "plane", "-group2", "resname RP1 RP2 and name A1 A2 A3", - "-binw", "60" - }; + const char* const cmdline[] = { "angle", + "-g1", + "vector", + "-group1", + "resname RV1 RV2 and name A1 A2", + "-g2", + "plane", + "-group2", + "resname RP1 RP2 and name A1 A2 A3", + "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); } TEST_F(AngleModuleTest, ComputesPlaneZAxisAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "plane", "-group1", "resname RP1 RP2 and name A1 A2 A3", - "-g2", "z", - "-binw", "60" + const char* const cmdline[] = { + "angle", "-g1", "plane", "-group1", "resname RP1 RP2 and name A1 A2 A3", + "-g2", "z", "-binw", "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); @@ -122,11 +126,10 @@ TEST_F(AngleModuleTest, ComputesPlaneZAxisAngles) TEST_F(AngleModuleTest, ComputesVectorSphereNormalZAxisAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", "-group1", "resname RV1 RV2 and name A1 A2", - "-g2", "sphnorm", "-group2", "cog of resname RS", - "-binw", "60" + const char* const cmdline[] = { + "angle", "-g1", "vector", "-group1", "resname RV1 RV2 and name A1 A2", + "-g2", "sphnorm", "-group2", "cog of resname RS", "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); @@ -134,11 +137,9 @@ TEST_F(AngleModuleTest, ComputesVectorSphereNormalZAxisAngles) TEST_F(AngleModuleTest, ComputesVectorTimeZeroAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", "-group1", "resname RV1 RV2 RV3 RV4 and name A1 A2", - "-g2", "t0", - "-binw", "60" + const char* const cmdline[] = { + "angle", "-g1", "vector", "-group1", "resname RV1 RV2 RV3 RV4 and name A1 A2", + "-g2", "t0", "-binw", "60" }; setTopology("angle.gro"); setTrajectory("angle.gro"); @@ -147,27 +148,27 @@ TEST_F(AngleModuleTest, ComputesVectorTimeZeroAngles) TEST_F(AngleModuleTest, ComputesMultipleAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", - "-group1", - "resname RV1 RV2 and name A1 A2", - "resname RV3 RV4 and name A1 A2", - "-g2", "plane", - "-group2", - "resname RP1 RP2 and name A1 A2 A3", - "resname RP1 RP2 and name A1 A2 A3", - "-binw", "60" - }; + const char* const cmdline[] = { "angle", + "-g1", + "vector", + "-group1", + "resname RV1 RV2 and name A1 A2", + "resname RV3 RV4 and name A1 A2", + "-g2", + "plane", + "-group2", + "resname RP1 RP2 and name A1 A2 A3", + "resname RP1 RP2 and name A1 A2 A3", + "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); } TEST_F(AngleModuleTest, HandlesDynamicSelections) { - const char *const cmdline[] = { - "angle", - "-g1", "angle", "-group1", "resname RA1 RA2 and name A1 A2 A3 and z < 0.5", + const char* const cmdline[] = { + "angle", "-g1", "angle", "-group1", "resname RA1 RA2 and name A1 A2 A3 and z < 0.5", "-binw", "60" }; setTopology("angle.gro"); @@ -176,29 +177,35 @@ TEST_F(AngleModuleTest, HandlesDynamicSelections) TEST_F(AngleModuleTest, HandlesOneVsMultipleVectorAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", "-group1", "resname RV1 RV2 and name A1 A2", - "-g2", "vector", "-group2", "resname RV3 and name A1 A2", - "-binw", "60" - }; + const char* const cmdline[] = { "angle", + "-g1", + "vector", + "-group1", + "resname RV1 RV2 and name A1 A2", + "-g2", + "vector", + "-group2", + "resname RV3 and name A1 A2", + "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); } TEST_F(AngleModuleTest, HandlesOneVsMultipleVectorGroupsAngles) { - const char *const cmdline[] = { - "angle", - "-g1", "vector", - "-group1", - "resname RV2 and name A1 A2", - "resname RV3 RV4 and name A1 A2", - "-g2", "plane", - "-group2", - "resname RP1 RP2 and name A1 A2 A3", - "-binw", "60" - }; + const char* const cmdline[] = { "angle", + "-g1", + "vector", + "-group1", + "resname RV2 and name A1 A2", + "resname RV3 RV4 and name A1 A2", + "-g2", + "plane", + "-group2", + "resname RP1 RP2 and name A1 A2 A3", + "-binw", + "60" }; setTopology("angle.gro"); runTest(CommandLine(cmdline)); } diff --git a/src/gromacs/trajectoryanalysis/tests/clustsize.cpp b/src/gromacs/trajectoryanalysis/tests/clustsize.cpp index eda82a7635..e14124fcb6 100644 --- a/src/gromacs/trajectoryanalysis/tests/clustsize.cpp +++ b/src/gromacs/trajectoryanalysis/tests/clustsize.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,37 +68,37 @@ namespace class ClustsizeTest : public CommandLineTestBase { - public: - ClustsizeTest() - { - double tolerance = 1e-4; - test::XvgMatch xvg; - test::XvgMatch &toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, tolerance)); - - setOutputFile("-mc", ".xvg", toler); - setOutputFile("-nc", ".xvg", toler); - setOutputFile("-ac", ".xvg", toler); - setOutputFile("-hc", ".xvg", toler); - setInputFile("-f", "clustsize.pdb"); - } - - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - - gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); - rootChecker.checkString(args.toString(), "CommandLine"); - - ASSERT_EQ(0, gmx_clustsize(cmdline.argc(), cmdline.argv())); - - checkOutputFiles(); - } +public: + ClustsizeTest() + { + double tolerance = 1e-4; + test::XvgMatch xvg; + test::XvgMatch& toler = xvg.tolerance(gmx::test::relativeToleranceAsFloatingPoint(1, tolerance)); + + setOutputFile("-mc", ".xvg", toler); + setOutputFile("-nc", ".xvg", toler); + setOutputFile("-ac", ".xvg", toler); + setOutputFile("-hc", ".xvg", toler); + setInputFile("-f", "clustsize.pdb"); + } + + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + + gmx::test::TestReferenceChecker rootChecker(this->rootChecker()); + rootChecker.checkString(args.toString(), "CommandLine"); + + ASSERT_EQ(0, gmx_clustsize(cmdline.argc(), cmdline.argv())); + + checkOutputFiles(); + } }; TEST_F(ClustsizeTest, NoMolDefaultCutoff) { - const char *const command[] = { "clustsize" }; + const char* const command[] = { "clustsize" }; CommandLine args = CommandLine(command); setInputFile("-n", "clustsize.ndx"); @@ -108,7 +108,7 @@ TEST_F(ClustsizeTest, NoMolDefaultCutoff) TEST_F(ClustsizeTest, NoMolShortCutoff) { - const char *const command[] = { "clustsize", "-cut", "0.3" }; + const char* const command[] = { "clustsize", "-cut", "0.3" }; CommandLine args = CommandLine(command); setInputFile("-n", "clustsize.ndx"); @@ -118,7 +118,7 @@ TEST_F(ClustsizeTest, NoMolShortCutoff) TEST_F(ClustsizeTest, MolDefaultCutoff) { - const char *const command[] = { "clustsize", "-mol" }; + const char* const command[] = { "clustsize", "-mol" }; CommandLine args = CommandLine(command); setInputFile("-s", "clustsize.tpr"); @@ -128,7 +128,7 @@ TEST_F(ClustsizeTest, MolDefaultCutoff) TEST_F(ClustsizeTest, MolShortCutoff) { - const char *const command[] = { "clustsize", "-mol", "-cut", "0.3" }; + const char* const command[] = { "clustsize", "-mol", "-cut", "0.3" }; CommandLine args = CommandLine(command); setInputFile("-s", "clustsize.tpr"); @@ -138,7 +138,7 @@ TEST_F(ClustsizeTest, MolShortCutoff) TEST_F(ClustsizeTest, MolCSize) { - const char *const command[] = { "clustsize", "-mol", "-nlevels", "6" }; + const char* const command[] = { "clustsize", "-mol", "-nlevels", "6" }; CommandLine args = CommandLine(command); setOutputFile("-o", ".xpm", ExactTextMatch()); diff --git a/src/gromacs/trajectoryanalysis/tests/cmdlinerunner.cpp b/src/gromacs/trajectoryanalysis/tests/cmdlinerunner.cpp index 6dfefd8c2c..9f67447aea 100644 --- a/src/gromacs/trajectoryanalysis/tests/cmdlinerunner.cpp +++ b/src/gromacs/trajectoryanalysis/tests/cmdlinerunner.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,51 +64,44 @@ namespace class MockModule : public gmx::TrajectoryAnalysisModule { - public: - MOCK_METHOD2(initOptions, void(gmx::IOptionsContainer *options, - gmx::TrajectoryAnalysisSettings *settings)); - MOCK_METHOD2(initAnalysis, void(const gmx::TrajectoryAnalysisSettings &settings, - const gmx::TopologyInformation &top)); - - MOCK_METHOD4(analyzeFrame, void(int frnr, const t_trxframe &fr, t_pbc *pbc, - gmx::TrajectoryAnalysisModuleData *pdata)); - MOCK_METHOD1(finishAnalysis, void(int nframes)); - MOCK_METHOD0(writeOutput, void()); +public: + MOCK_METHOD2(initOptions, + void(gmx::IOptionsContainer* options, gmx::TrajectoryAnalysisSettings* settings)); + MOCK_METHOD2(initAnalysis, + void(const gmx::TrajectoryAnalysisSettings& settings, const gmx::TopologyInformation& top)); + + MOCK_METHOD4(analyzeFrame, + void(int frnr, const t_trxframe& fr, t_pbc* pbc, gmx::TrajectoryAnalysisModuleData* pdata)); + MOCK_METHOD1(finishAnalysis, void(int nframes)); + MOCK_METHOD0(writeOutput, void()); }; using gmx::test::CommandLine; class TrajectoryAnalysisCommandLineRunnerTest : public gmx::test::CommandLineTestBase { - public: - TrajectoryAnalysisCommandLineRunnerTest() - : mockModule_(new MockModule()) - { - } - - gmx::ICommandLineOptionsModulePointer createRunner() - { - return gmx::TrajectoryAnalysisCommandLineRunner::createModule( - std::move(mockModule_)); - } - - void runTest(const CommandLine &args) - { - CommandLine &cmdline = commandLine(); - cmdline.merge(args); - ASSERT_EQ(0, gmx::test::CommandLineTestHelper::runModuleDirect(createRunner(), &cmdline)); - } - - std::unique_ptr mockModule_; +public: + TrajectoryAnalysisCommandLineRunnerTest() : mockModule_(new MockModule()) {} + + gmx::ICommandLineOptionsModulePointer createRunner() + { + return gmx::TrajectoryAnalysisCommandLineRunner::createModule(std::move(mockModule_)); + } + + void runTest(const CommandLine& args) + { + CommandLine& cmdline = commandLine(); + cmdline.merge(args); + ASSERT_EQ(0, gmx::test::CommandLineTestHelper::runModuleDirect(createRunner(), &cmdline)); + } + + std::unique_ptr mockModule_; }; //! Initializes options for help testing. -void initOptions(gmx::IOptionsContainer *options, gmx::TrajectoryAnalysisSettings *settings) +void initOptions(gmx::IOptionsContainer* options, gmx::TrajectoryAnalysisSettings* settings) { - const char *const desc[] = { - "Sample description", - "for testing [THISMODULE]." - }; + const char* const desc[] = { "Sample description", "for testing [THISMODULE]." }; settings->setHelpText(desc); options->addOption(gmx::BooleanOption("test").description("Test option")); @@ -121,16 +114,13 @@ TEST_F(TrajectoryAnalysisCommandLineRunnerTest, WritesHelp) EXPECT_CALL(*mockModule_, initOptions(_, _)).WillOnce(Invoke(&initOptions)); const std::unique_ptr module( - gmx::ICommandLineOptionsModule::createModule("mod", "Description", - createRunner())); + gmx::ICommandLineOptionsModule::createModule("mod", "Description", createRunner())); testWriteHelp(module.get()); } TEST_F(TrajectoryAnalysisCommandLineRunnerTest, RunsWithSubsetTrajectory) { - const char *const cmdline[] = { - "-fgroup", "atomnr 4 5 6 10 to 14" - }; + const char* const cmdline[] = { "-fgroup", "atomnr 4 5 6 10 to 14" }; using ::testing::_; EXPECT_CALL(*mockModule_, initOptions(_, _)); @@ -147,9 +137,7 @@ TEST_F(TrajectoryAnalysisCommandLineRunnerTest, RunsWithSubsetTrajectory) TEST_F(TrajectoryAnalysisCommandLineRunnerTest, DetectsIncorrectTrajectorySubset) { - const char *const cmdline[] = { - "-fgroup", "atomnr 3 to 6 10 to 14" - }; + const char* const cmdline[] = { "-fgroup", "atomnr 3 to 6 10 to 14" }; using ::testing::_; EXPECT_CALL(*mockModule_, initOptions(_, _)); @@ -162,9 +150,7 @@ TEST_F(TrajectoryAnalysisCommandLineRunnerTest, DetectsIncorrectTrajectorySubset TEST_F(TrajectoryAnalysisCommandLineRunnerTest, FailsWithTrajectorySubsetWithoutTrajectory) { - const char *const cmdline[] = { - "-fgroup", "atomnr 3 to 6 10 to 14" - }; + const char* const cmdline[] = { "-fgroup", "atomnr 3 to 6 10 to 14" }; using ::testing::_; EXPECT_CALL(*mockModule_, initOptions(_, _)); diff --git a/src/gromacs/trajectoryanalysis/tests/convert_trj.cpp b/src/gromacs/trajectoryanalysis/tests/convert_trj.cpp index c24c001ddb..004491019c 100644 --- a/src/gromacs/trajectoryanalysis/tests/convert_trj.cpp +++ b/src/gromacs/trajectoryanalysis/tests/convert_trj.cpp @@ -55,22 +55,19 @@ namespace { using gmx::test::CommandLine; -using gmx::test::NoContentsMatch; using gmx::test::ExactTextMatch; +using gmx::test::NoContentsMatch; /******************************************************************** * Tests for gmx::analysismodules::ConvertTrj. */ //! Test fixture for the convert-trj analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - ConvertTrjModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture ConvertTrjModuleTest; TEST_F(ConvertTrjModuleTest, WritesNormalOutput) { - const char *const cmdline[] = { - "convert-trj" - }; + const char* const cmdline[] = { "convert-trj" }; setTopology("freevolume.tpr"); setInputFile("-f", "freevolume.xtc"); setOutputFile("-o", "test.trr", NoContentsMatch()); @@ -79,10 +76,7 @@ TEST_F(ConvertTrjModuleTest, WritesNormalOutput) TEST_F(ConvertTrjModuleTest, WritesAtomSubset) { - const char *const cmdline[] = { - "convert-trj", - "-select", "not resname = CO2" - }; + const char* const cmdline[] = { "convert-trj", "-select", "not resname = CO2" }; setTopology("freevolume.tpr"); setInputFile("-f", "freevolume.xtc"); setOutputFile("-o", "test.trr", NoContentsMatch()); @@ -91,9 +85,7 @@ TEST_F(ConvertTrjModuleTest, WritesAtomSubset) TEST_F(ConvertTrjModuleTest, WorksWithAtomAdding) { - const char *const cmdline[] = { - "convert-trj", "-atoms", "always-from-structure" - }; + const char* const cmdline[] = { "convert-trj", "-atoms", "always-from-structure" }; // TODO check output structures once this is supported. setTopology("clustsize.tpr"); setInputFile("-f", "clustsize.pdb"); @@ -103,10 +95,8 @@ TEST_F(ConvertTrjModuleTest, WorksWithAtomAdding) TEST_F(ConvertTrjModuleTest, WorksWithAtomsAndSelection) { - const char *const cmdline[] = { - "convert-trj", "-atoms", "always-from-structure", - "-select", "not resname = CO2" - }; + const char* const cmdline[] = { "convert-trj", "-atoms", "always-from-structure", "-select", + "not resname = CO2" }; // TODO check output structures once this is supported. setTopology("clustsize.tpr"); setInputFile("-f", "clustsize.pdb"); diff --git a/src/gromacs/trajectoryanalysis/tests/distance.cpp b/src/gromacs/trajectoryanalysis/tests/distance.cpp index 5a63636346..49b0f8cb63 100644 --- a/src/gromacs/trajectoryanalysis/tests/distance.cpp +++ b/src/gromacs/trajectoryanalysis/tests/distance.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,27 +59,23 @@ using gmx::test::CommandLine; */ //! Test fixture for the angle analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - DistanceModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture DistanceModuleTest; TEST_F(DistanceModuleTest, ComputesDistances) { - const char *const cmdline[] = { - "distance", - "-select", "atomname S1 S2", - "-len", "2", "-binw", "0.5" - }; + const char* const cmdline[] = { "distance", "-select", "atomname S1 S2", "-len", "2", + "-binw", "0.5" }; setTopology("simple.gro"); runTest(CommandLine(cmdline)); } TEST_F(DistanceModuleTest, ComputesMultipleDistances) { - const char *const cmdline[] = { - "distance", - "-select", "atomname S1 S2", - "resindex 1 to 4 and atomname CB merge resindex 2 to 5 and atomname CB", - "-len", "2", "-binw", "0.5" + const char* const cmdline[] = { + "distance", "-select", + "atomname S1 S2", "resindex 1 to 4 and atomname CB merge resindex 2 to 5 and atomname CB", + "-len", "2", + "-binw", "0.5" }; setTopology("simple.gro"); runTest(CommandLine(cmdline)); @@ -87,11 +83,9 @@ TEST_F(DistanceModuleTest, ComputesMultipleDistances) TEST_F(DistanceModuleTest, HandlesDynamicSelections) { - const char *const cmdline[] = { - "distance", - "-select", "atomname S1 S2 and res_cog x < 2.8", - "-len", "2", "-binw", "0.5" - }; + const char* const cmdline[] = { "distance", "-select", "atomname S1 S2 and res_cog x < 2.8", + "-len", "2", "-binw", + "0.5" }; setTopology("simple.gro"); runTest(CommandLine(cmdline)); } diff --git a/src/gromacs/trajectoryanalysis/tests/extract_cluster.cpp b/src/gromacs/trajectoryanalysis/tests/extract_cluster.cpp index 584a9f5a91..2493d52c2a 100644 --- a/src/gromacs/trajectoryanalysis/tests/extract_cluster.cpp +++ b/src/gromacs/trajectoryanalysis/tests/extract_cluster.cpp @@ -70,11 +70,12 @@ namespace */ //! Helper struct to combine filename, path and FileMatcher -struct ManualOutputFile { +struct ManualOutputFile +{ //! Generated file name. - std::string filename; + std::string filename; //! Full generated file path. - std::string fullFilepath; + std::string fullFilepath; //! Corresponding file matcher to compare to reference. FileMatcherPointer matcher; }; @@ -82,22 +83,22 @@ struct ManualOutputFile { //! Test fixture for the convert-trj analysis module. class ExtractClusterModuleTest : public AbstractTrajectoryAnalysisModuleTestFixture { - protected: - TrajectoryAnalysisModulePointer createModule() override - { - return analysismodules::ExtractClusterInfo::create(); - } - - public: - //! Constructor - ExtractClusterModuleTest(); - - //! Compare generated files to expected ones. - void compareFiles(); - - private: - //! Array of names and paths for generated files. - std::array generatedFiles; +protected: + TrajectoryAnalysisModulePointer createModule() override + { + return analysismodules::ExtractClusterInfo::create(); + } + +public: + //! Constructor + ExtractClusterModuleTest(); + + //! Compare generated files to expected ones. + void compareFiles(); + +private: + //! Array of names and paths for generated files. + std::array generatedFiles; }; ExtractClusterModuleTest::ExtractClusterModuleTest() @@ -113,11 +114,10 @@ ExtractClusterModuleTest::ExtractClusterModuleTest() setInputFile("-clusters", "extract_cluster.ndx"); int fileNumber = 1; - for (auto &generatedFile : generatedFiles) + for (auto& generatedFile : generatedFiles) { generatedFile.filename = gmx::Path::concatenateBeforeExtension( - "test.g96", - gmx::formatString("_Cluster_000%d", fileNumber)); + "test.g96", gmx::formatString("_Cluster_000%d", fileNumber)); generatedFile.matcher = TextFileMatch(ExactTextMatch()).createFileMatcher(); generatedFile.fullFilepath = fileManager().getTemporaryFilePath(generatedFile.filename); fileNumber++; @@ -126,12 +126,10 @@ ExtractClusterModuleTest::ExtractClusterModuleTest() void ExtractClusterModuleTest::compareFiles() { - TestReferenceChecker outputChecker( - rootChecker().checkCompound("ClusterOutputFiles", "Files")); - for (const auto &file : generatedFiles) + TestReferenceChecker outputChecker(rootChecker().checkCompound("ClusterOutputFiles", "Files")); + for (const auto& file : generatedFiles) { - TestReferenceChecker manualFileChecker( - outputChecker.checkCompound("File", file.filename.c_str())); + TestReferenceChecker manualFileChecker(outputChecker.checkCompound("File", file.filename.c_str())); file.matcher->checkFile(file.fullFilepath, &manualFileChecker); } } @@ -139,9 +137,7 @@ void ExtractClusterModuleTest::compareFiles() TEST_F(ExtractClusterModuleTest, WorksWithAllAtoms) { std::string realFileName = TestFileManager::getTestSpecificFileName("test.g96"); - const char *const cmdline[] = { - "extract-cluster", "-o", realFileName.c_str() - }; + const char* const cmdline[] = { "extract-cluster", "-o", realFileName.c_str() }; runTest(CommandLine(cmdline)); compareFiles(); @@ -150,9 +146,8 @@ TEST_F(ExtractClusterModuleTest, WorksWithAllAtoms) TEST_F(ExtractClusterModuleTest, WorksWithAtomSubset) { std::string realFileName = TestFileManager::getTestSpecificFileName("test.g96"); - const char *const cmdline[] = { - "extract-cluster", "-o", realFileName.c_str(), "-select", "atomnr 1 2" - }; + const char* const cmdline[] = { "extract-cluster", "-o", realFileName.c_str(), "-select", + "atomnr 1 2" }; runTest(CommandLine(cmdline)); compareFiles(); diff --git a/src/gromacs/trajectoryanalysis/tests/freevolume.cpp b/src/gromacs/trajectoryanalysis/tests/freevolume.cpp index f199976cc5..debca10fac 100644 --- a/src/gromacs/trajectoryanalysis/tests/freevolume.cpp +++ b/src/gromacs/trajectoryanalysis/tests/freevolume.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,14 +59,11 @@ using gmx::test::CommandLine; */ //! Test fixture for the angle analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - FreeVolumeModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture FreeVolumeModuleTest; TEST_F(FreeVolumeModuleTest, ComputesFreeVolume) { - const char *const cmdline[] = { - "freevolume", "-seed", "13" - }; + const char* const cmdline[] = { "freevolume", "-seed", "13" }; setTopology("freevolume.tpr"); setTrajectory("freevolume.xtc"); runTest(CommandLine(cmdline)); @@ -74,10 +71,7 @@ TEST_F(FreeVolumeModuleTest, ComputesFreeVolume) TEST_F(FreeVolumeModuleTest, ComputesFreeVolumeSelection) { - const char *const cmdline[] = { - "freevolume", - "-select", "not resname = CO2", "-seed", "17" - }; + const char* const cmdline[] = { "freevolume", "-select", "not resname = CO2", "-seed", "17" }; setTopology("freevolume.tpr"); setTrajectory("freevolume.xtc"); runTest(CommandLine(cmdline)); diff --git a/src/gromacs/trajectoryanalysis/tests/moduletest.cpp b/src/gromacs/trajectoryanalysis/tests/moduletest.cpp index d80e1b74ca..d614f500cf 100644 --- a/src/gromacs/trajectoryanalysis/tests/moduletest.cpp +++ b/src/gromacs/trajectoryanalysis/tests/moduletest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,52 +67,47 @@ namespace test class AbstractTrajectoryAnalysisModuleTestFixture::Impl { - public: - struct DatasetInfo - { - DatasetInfo() - : bCheck(true), tolerance(defaultRealTolerance()) - { - } +public: + struct DatasetInfo + { + DatasetInfo() : bCheck(true), tolerance(defaultRealTolerance()) {} - bool bCheck; - FloatingPointTolerance tolerance; - }; + bool bCheck; + FloatingPointTolerance tolerance; + }; - typedef std::map DatasetList; + typedef std::map DatasetList; - explicit Impl(AbstractTrajectoryAnalysisModuleTestFixture *parent); + explicit Impl(AbstractTrajectoryAnalysisModuleTestFixture* parent); - TrajectoryAnalysisModule &module(); - void ensureModuleCreated(); - bool hasCheckedDatasets() const; + TrajectoryAnalysisModule& module(); + void ensureModuleCreated(); + bool hasCheckedDatasets() const; - AbstractTrajectoryAnalysisModuleTestFixture &parent_; - TrajectoryAnalysisModulePointer module_; - DatasetList datasets_; - bool bDatasetsIncluded_; + AbstractTrajectoryAnalysisModuleTestFixture& parent_; + TrajectoryAnalysisModulePointer module_; + DatasetList datasets_; + bool bDatasetsIncluded_; }; -AbstractTrajectoryAnalysisModuleTestFixture::Impl::Impl( - AbstractTrajectoryAnalysisModuleTestFixture *parent) - : parent_(*parent), bDatasetsIncluded_(false) +AbstractTrajectoryAnalysisModuleTestFixture::Impl::Impl(AbstractTrajectoryAnalysisModuleTestFixture* parent) : + parent_(*parent), + bDatasetsIncluded_(false) { } -TrajectoryAnalysisModule & -AbstractTrajectoryAnalysisModuleTestFixture::Impl::module() +TrajectoryAnalysisModule& AbstractTrajectoryAnalysisModuleTestFixture::Impl::module() { ensureModuleCreated(); return *module_; } -void -AbstractTrajectoryAnalysisModuleTestFixture::Impl::ensureModuleCreated() +void AbstractTrajectoryAnalysisModuleTestFixture::Impl::ensureModuleCreated() { if (module_.get() == nullptr) { module_ = parent_.createModule(); - const std::vector &datasetNames(module_->datasetNames()); + const std::vector& datasetNames(module_->datasetNames()); datasets_.clear(); std::vector::const_iterator i; for (i = datasetNames.begin(); i != datasetNames.end(); ++i) @@ -122,8 +117,7 @@ AbstractTrajectoryAnalysisModuleTestFixture::Impl::ensureModuleCreated() } } -bool -AbstractTrajectoryAnalysisModuleTestFixture::Impl::hasCheckedDatasets() const +bool AbstractTrajectoryAnalysisModuleTestFixture::Impl::hasCheckedDatasets() const { DatasetList::const_iterator dataset; for (dataset = datasets_.begin(); dataset != datasets_.end(); ++dataset) @@ -140,29 +134,24 @@ AbstractTrajectoryAnalysisModuleTestFixture::Impl::hasCheckedDatasets() const * AbstractTrajectoryAnalysisModuleTestFixture */ -AbstractTrajectoryAnalysisModuleTestFixture::AbstractTrajectoryAnalysisModuleTestFixture() - : impl_(new Impl(this)) +AbstractTrajectoryAnalysisModuleTestFixture::AbstractTrajectoryAnalysisModuleTestFixture() : + impl_(new Impl(this)) { } -AbstractTrajectoryAnalysisModuleTestFixture::~AbstractTrajectoryAnalysisModuleTestFixture() -{ -} +AbstractTrajectoryAnalysisModuleTestFixture::~AbstractTrajectoryAnalysisModuleTestFixture() {} -void -AbstractTrajectoryAnalysisModuleTestFixture::setTopology(const char *filename) +void AbstractTrajectoryAnalysisModuleTestFixture::setTopology(const char* filename) { setInputFile("-s", filename); } -void -AbstractTrajectoryAnalysisModuleTestFixture::setTrajectory(const char *filename) +void AbstractTrajectoryAnalysisModuleTestFixture::setTrajectory(const char* filename) { setInputFile("-f", filename); } -void -AbstractTrajectoryAnalysisModuleTestFixture::includeDataset(const char *name) +void AbstractTrajectoryAnalysisModuleTestFixture::includeDataset(const char* name) { impl_->ensureModuleCreated(); if (!impl_->bDatasetsIncluded_) @@ -179,8 +168,7 @@ AbstractTrajectoryAnalysisModuleTestFixture::includeDataset(const char *name) dataset->second.bCheck = true; } -void -AbstractTrajectoryAnalysisModuleTestFixture::excludeDataset(const char *name) +void AbstractTrajectoryAnalysisModuleTestFixture::excludeDataset(const char* name) { impl_->ensureModuleCreated(); Impl::DatasetList::iterator dataset = impl_->datasets_.find(name); @@ -189,9 +177,8 @@ AbstractTrajectoryAnalysisModuleTestFixture::excludeDataset(const char *name) dataset->second.bCheck = false; } -void -AbstractTrajectoryAnalysisModuleTestFixture::setDatasetTolerance( - const char *name, const FloatingPointTolerance &tolerance) +void AbstractTrajectoryAnalysisModuleTestFixture::setDatasetTolerance(const char* name, + const FloatingPointTolerance& tolerance) { impl_->ensureModuleCreated(); Impl::DatasetList::iterator dataset = impl_->datasets_.find(name); @@ -200,11 +187,10 @@ AbstractTrajectoryAnalysisModuleTestFixture::setDatasetTolerance( dataset->second.tolerance = tolerance; } -void -AbstractTrajectoryAnalysisModuleTestFixture::runTest(const CommandLine &args) +void AbstractTrajectoryAnalysisModuleTestFixture::runTest(const CommandLine& args) { - TrajectoryAnalysisModule &module = impl_->module(); - CommandLine &cmdline = commandLine(); + TrajectoryAnalysisModule& module = impl_->module(); + CommandLine& cmdline = commandLine(); cmdline.merge(args); TestReferenceChecker rootChecker(this->rootChecker()); @@ -212,19 +198,16 @@ AbstractTrajectoryAnalysisModuleTestFixture::runTest(const CommandLine &args) if (impl_->hasCheckedDatasets()) { - TestReferenceChecker dataChecker( - rootChecker.checkCompound("OutputData", "Data")); - Impl::DatasetList::const_iterator dataset; - for (dataset = impl_->datasets_.begin(); - dataset != impl_->datasets_.end(); - ++dataset) + TestReferenceChecker dataChecker(rootChecker.checkCompound("OutputData", "Data")); + Impl::DatasetList::const_iterator dataset; + for (dataset = impl_->datasets_.begin(); dataset != impl_->datasets_.end(); ++dataset) { if (dataset->second.bCheck) { - const char *const name = dataset->first.c_str(); - AbstractAnalysisData &data = module.datasetFromName(name); - AnalysisDataTestFixture::addReferenceCheckerModule( - dataChecker, name, &data, dataset->second.tolerance); + const char* const name = dataset->first.c_str(); + AbstractAnalysisData& data = module.datasetFromName(name); + AnalysisDataTestFixture::addReferenceCheckerModule(dataChecker, name, &data, + dataset->second.tolerance); } } } diff --git a/src/gromacs/trajectoryanalysis/tests/moduletest.h b/src/gromacs/trajectoryanalysis/tests/moduletest.h index 10e5f72875..6791b70ce0 100644 --- a/src/gromacs/trajectoryanalysis/tests/moduletest.h +++ b/src/gromacs/trajectoryanalysis/tests/moduletest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -91,97 +91,96 @@ class FloatingPointTolerance; */ class AbstractTrajectoryAnalysisModuleTestFixture : public CommandLineTestBase { - public: - AbstractTrajectoryAnalysisModuleTestFixture(); - ~AbstractTrajectoryAnalysisModuleTestFixture() override; - - /*! \brief - * Sets the topology file to use for the test. - * - * \param[in] filename Name of input topology file. - * - * \p filename is interpreted relative to the test input data - * directory, see getTestDataPath(). - * - * Must be called at most once. Either this method or setTrajectory() - * must be called before runTest(). - */ - void setTopology(const char *filename); - /*! \brief - * Sets the trajectory file to use for the test. - * - * \param[in] filename Name of input trajectory file. - * - * \p filename is interpreted relative to the test input data - * directory, see getTestDataPath(). - * - * Must be called at most once. Either this method or setTopology() - * must be called before runTest(). - */ - void setTrajectory(const char *filename); - /*! \brief - * Includes only specified dataset for the test. - * - * \param[in] name Name of dataset to include. - * - * If this method is not called, all datasets are tested by default. - * If called once, only the specified dataset is tested. - * If called more than once, also the additional datasets are tested. - * - * \p name should be one of the names registered for the tested module - * using TrajectoryAnalysisModule::registerBasicDataset() or - * TrajectoryAnalysisModule::registerAnalysisDataset(). - */ - void includeDataset(const char *name); - /*! \brief - * Excludes specified dataset from the test. - * - * \param[in] name Name of dataset to exclude. - * - * \p name should be one of the names registered for the tested module - * using TrajectoryAnalysisModule::registerBasicDataset() or - * TrajectoryAnalysisModule::registerAnalysisDataset(). - */ - void excludeDataset(const char *name); - /*! \brief - * Sets a custom tolerance for checking a dataset. - * - * \param[in] name Name of dataset to set the tolerance for. - * \param[in] tolerance Tolerance used when verifying the data. - * - * \p name should be one of the names registered for the tested module - * using TrajectoryAnalysisModule::registerBasicDataset() or - * TrajectoryAnalysisModule::registerAnalysisDataset(). - */ - void setDatasetTolerance(const char *name, - const FloatingPointTolerance &tolerance); - - /*! \brief - * Runs the analysis module with the given additional options. - * - * \param[in] args Options to provide to the module. - * - * \p args should be formatted as command-line options, and contain the - * name of the module as the first argument (the latter requirement is - * for clarity only). They are passed to the module in addition to - * those specified using other methods in this class. - * - * All other methods should be called before calling this method. - * - * Exceptions thrown by the module are caught by this method. - */ - void runTest(const CommandLine &args); - - protected: - /*! \brief - * Constructs the analysis module to be tested. - */ - virtual TrajectoryAnalysisModulePointer createModule() = 0; - - private: - class Impl; - - PrivateImplPointer impl_; +public: + AbstractTrajectoryAnalysisModuleTestFixture(); + ~AbstractTrajectoryAnalysisModuleTestFixture() override; + + /*! \brief + * Sets the topology file to use for the test. + * + * \param[in] filename Name of input topology file. + * + * \p filename is interpreted relative to the test input data + * directory, see getTestDataPath(). + * + * Must be called at most once. Either this method or setTrajectory() + * must be called before runTest(). + */ + void setTopology(const char* filename); + /*! \brief + * Sets the trajectory file to use for the test. + * + * \param[in] filename Name of input trajectory file. + * + * \p filename is interpreted relative to the test input data + * directory, see getTestDataPath(). + * + * Must be called at most once. Either this method or setTopology() + * must be called before runTest(). + */ + void setTrajectory(const char* filename); + /*! \brief + * Includes only specified dataset for the test. + * + * \param[in] name Name of dataset to include. + * + * If this method is not called, all datasets are tested by default. + * If called once, only the specified dataset is tested. + * If called more than once, also the additional datasets are tested. + * + * \p name should be one of the names registered for the tested module + * using TrajectoryAnalysisModule::registerBasicDataset() or + * TrajectoryAnalysisModule::registerAnalysisDataset(). + */ + void includeDataset(const char* name); + /*! \brief + * Excludes specified dataset from the test. + * + * \param[in] name Name of dataset to exclude. + * + * \p name should be one of the names registered for the tested module + * using TrajectoryAnalysisModule::registerBasicDataset() or + * TrajectoryAnalysisModule::registerAnalysisDataset(). + */ + void excludeDataset(const char* name); + /*! \brief + * Sets a custom tolerance for checking a dataset. + * + * \param[in] name Name of dataset to set the tolerance for. + * \param[in] tolerance Tolerance used when verifying the data. + * + * \p name should be one of the names registered for the tested module + * using TrajectoryAnalysisModule::registerBasicDataset() or + * TrajectoryAnalysisModule::registerAnalysisDataset(). + */ + void setDatasetTolerance(const char* name, const FloatingPointTolerance& tolerance); + + /*! \brief + * Runs the analysis module with the given additional options. + * + * \param[in] args Options to provide to the module. + * + * \p args should be formatted as command-line options, and contain the + * name of the module as the first argument (the latter requirement is + * for clarity only). They are passed to the module in addition to + * those specified using other methods in this class. + * + * All other methods should be called before calling this method. + * + * Exceptions thrown by the module are caught by this method. + */ + void runTest(const CommandLine& args); + +protected: + /*! \brief + * Constructs the analysis module to be tested. + */ + virtual TrajectoryAnalysisModulePointer createModule() = 0; + +private: + class Impl; + + PrivateImplPointer impl_; }; /*! \internal \brief @@ -194,15 +193,11 @@ class AbstractTrajectoryAnalysisModuleTestFixture : public CommandLineTestBase * * \ingroup module_trajectoryanalysis */ -template -class TrajectoryAnalysisModuleTestFixture - : public AbstractTrajectoryAnalysisModuleTestFixture +template +class TrajectoryAnalysisModuleTestFixture : public AbstractTrajectoryAnalysisModuleTestFixture { - protected: - TrajectoryAnalysisModulePointer createModule() override - { - return ModuleInfo::create(); - } +protected: + TrajectoryAnalysisModulePointer createModule() override { return ModuleInfo::create(); } }; } // namespace test diff --git a/src/gromacs/trajectoryanalysis/tests/pairdist.cpp b/src/gromacs/trajectoryanalysis/tests/pairdist.cpp index 75ae35190d..27a1cd4c2b 100644 --- a/src/gromacs/trajectoryanalysis/tests/pairdist.cpp +++ b/src/gromacs/trajectoryanalysis/tests/pairdist.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,16 +72,13 @@ using gmx::test::NoTextMatch; */ //! Test fixture for the select analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - PairDistanceModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture PairDistanceModuleTest; TEST_F(PairDistanceModuleTest, ComputesAllDistances) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1", "-refgrouping", "none", - "-sel", "resindex 3", "-selgrouping", "none" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1", + "-refgrouping", "none", "-sel", + "resindex 3", "-selgrouping", "none" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -89,12 +86,9 @@ TEST_F(PairDistanceModuleTest, ComputesAllDistances) TEST_F(PairDistanceModuleTest, ComputesAllDistancesWithCutoff) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1", "-refgrouping", "none", - "-sel", "resindex 3", "-selgrouping", "none", - "-cutoff", "1.5" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1", "-refgrouping", + "none", "-sel", "resindex 3", "-selgrouping", + "none", "-cutoff", "1.5" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -102,12 +96,8 @@ TEST_F(PairDistanceModuleTest, ComputesAllDistancesWithCutoff) TEST_F(PairDistanceModuleTest, ComputesMinDistanceWithCutoff) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1", - "-sel", "resindex 3", - "-cutoff", "1.5" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1", "-sel", + "resindex 3", "-cutoff", "1.5" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -115,12 +105,8 @@ TEST_F(PairDistanceModuleTest, ComputesMinDistanceWithCutoff) TEST_F(PairDistanceModuleTest, ComputesMaxDistance) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1", - "-sel", "resindex 3", - "-type", "max" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1", "-sel", + "resindex 3", "-type", "max" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -128,12 +114,8 @@ TEST_F(PairDistanceModuleTest, ComputesMaxDistance) TEST_F(PairDistanceModuleTest, ComputesMaxDistanceWithCutoff) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1", - "-sel", "resindex 3", - "-cutoff", "1.5", "-type", "max" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1", "-sel", "resindex 3", + "-cutoff", "1.5", "-type", "max" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -141,12 +123,10 @@ TEST_F(PairDistanceModuleTest, ComputesMaxDistanceWithCutoff) TEST_F(PairDistanceModuleTest, ComputesGroupedMinDistanceWithCutoff) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1 to 2", "-refgrouping", "res", - "-sel", "resindex 3 to 5", "-selgrouping", "res", - "-cutoff", "2.5" - }; + const char* const cmdline[] = { "pairdist", "-ref", "resindex 1 to 2", + "-refgrouping", "res", "-sel", + "resindex 3 to 5", "-selgrouping", "res", + "-cutoff", "2.5" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); @@ -154,12 +134,19 @@ TEST_F(PairDistanceModuleTest, ComputesGroupedMinDistanceWithCutoff) TEST_F(PairDistanceModuleTest, ComputesGroupedMaxDistanceWithCutoff) { - const char *const cmdline[] = { - "pairdist", - "-ref", "resindex 1 to 2", "-refgrouping", "res", - "-sel", "resindex 3 to 5", "-selgrouping", "res", - "-cutoff", "3.5", "-type", "max" - }; + const char* const cmdline[] = { "pairdist", + "-ref", + "resindex 1 to 2", + "-refgrouping", + "res", + "-sel", + "resindex 3 to 5", + "-selgrouping", + "res", + "-cutoff", + "3.5", + "-type", + "max" }; setTopology("simple.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); runTest(CommandLine(cmdline)); diff --git a/src/gromacs/trajectoryanalysis/tests/rdf.cpp b/src/gromacs/trajectoryanalysis/tests/rdf.cpp index e1fb5bd197..8bae34f47d 100644 --- a/src/gromacs/trajectoryanalysis/tests/rdf.cpp +++ b/src/gromacs/trajectoryanalysis/tests/rdf.cpp @@ -70,17 +70,12 @@ using gmx::test::NoTextMatch; */ //! Test fixture for the `rdf` analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - RdfModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture RdfModuleTest; TEST_F(RdfModuleTest, BasicTest) { - const char *const cmdline[] = { - "rdf", - "-bin", "0.05", - "-ref", "name OW", - "-sel", "name OW", "not name OW" - }; + const char* const cmdline[] = { "rdf", "-bin", "0.05", "-ref", + "name OW", "-sel", "name OW", "not name OW" }; setTopology("spc216.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); excludeDataset("pairdist"); @@ -89,14 +84,11 @@ TEST_F(RdfModuleTest, BasicTest) TEST_F(RdfModuleTest, SelectionsSolelyFromIndexFileWork) { - const char *const cmdline[] = { - "rdf", - "-bin", "0.05", - // Use selection that names a group in the index file - "-ref", "name_OW", - // Use selections that name groups in the index file - "-sel", "name_OW", "not_name_OW" - }; + const char* const cmdline[] = { "rdf", "-bin", "0.05", + // Use selection that names a group in the index file + "-ref", "name_OW", + // Use selections that name groups in the index file + "-sel", "name_OW", "not_name_OW" }; // Note not supplying a topology file to -s setTrajectory("spc216.gro"); setInputFile("-n", "index.ndx"); @@ -107,14 +99,11 @@ TEST_F(RdfModuleTest, SelectionsSolelyFromIndexFileWork) TEST_F(RdfModuleTest, SelectionsFromBothTopologyFileAndIndexFileWork) { - const char *const cmdline[] = { - "rdf", - "-bin", "0.05", - // Use selection whose parsing requires topology file - "-ref", "name OW", - // Use selections that name groups in the index file - "-sel", "name_OW", "not_name_OW" - }; + const char* const cmdline[] = { "rdf", "-bin", "0.05", + // Use selection whose parsing requires topology file + "-ref", "name OW", + // Use selections that name groups in the index file + "-sel", "name_OW", "not_name_OW" }; // Note supplying a topology file to -s setTopology("spc216.gro"); setInputFile("-n", "index.ndx"); @@ -125,12 +114,16 @@ TEST_F(RdfModuleTest, SelectionsFromBothTopologyFileAndIndexFileWork) TEST_F(RdfModuleTest, CalculatesSurf) { - const char *const cmdline[] = { - "rdf", - "-bin", "0.05", "-surf", "res", - "-ref", "within 0.5 of (resnr 1 and name OW)", - "-sel", "name OW", "not name OW" - }; + const char* const cmdline[] = { "rdf", + "-bin", + "0.05", + "-surf", + "res", + "-ref", + "within 0.5 of (resnr 1 and name OW)", + "-sel", + "name OW", + "not name OW" }; setTopology("spc216.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); excludeDataset("pairdist"); @@ -139,12 +132,8 @@ TEST_F(RdfModuleTest, CalculatesSurf) TEST_F(RdfModuleTest, CalculatesXY) { - const char *const cmdline[] = { - "rdf", - "-bin", "0.05", "-xy", - "-ref", "name OW", - "-sel", "name OW", "not name OW" - }; + const char* const cmdline[] = { "rdf", "-bin", "0.05", "-xy", "-ref", + "name OW", "-sel", "name OW", "not name OW" }; setTopology("spc216.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); excludeDataset("pairdist"); diff --git a/src/gromacs/trajectoryanalysis/tests/sasa.cpp b/src/gromacs/trajectoryanalysis/tests/sasa.cpp index 742ba2a399..eae540ec8a 100644 --- a/src/gromacs/trajectoryanalysis/tests/sasa.cpp +++ b/src/gromacs/trajectoryanalysis/tests/sasa.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,16 +72,11 @@ using gmx::test::XvgMatch; */ //! Test fixture for the `sasa` analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - SasaModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture SasaModuleTest; TEST_F(SasaModuleTest, BasicTest) { - const char *const cmdline[] = { - "sasa", - "-surface", "all", - "-output", "name N CA C O H" - }; + const char* const cmdline[] = { "sasa", "-surface", "all", "-output", "name N CA C O H" }; setTopology("lysozyme.gro"); setOutputFile("-o", ".xvg", XvgMatch().testData(false)); setOutputFile("-or", ".xvg", XvgMatch()); @@ -95,10 +90,7 @@ TEST_F(SasaModuleTest, BasicTest) TEST_F(SasaModuleTest, HandlesSelectedResidues) { - const char *const cmdline[] = { - "sasa", - "-surface", "resnr 2 4 to 5 8" - }; + const char* const cmdline[] = { "sasa", "-surface", "resnr 2 4 to 5 8" }; setTopology("lysozyme.gro"); setOutputFile("-o", ".xvg", XvgMatch().testData(false)); setOutputFile("-or", ".xvg", XvgMatch()); @@ -111,10 +103,7 @@ TEST_F(SasaModuleTest, HandlesSelectedResidues) TEST_F(SasaModuleTest, WritesConnollySurfaceWithSolute) { - const char *const cmdline[] = { - "sasa", - "-surface", "atomnr 1" - }; + const char* const cmdline[] = { "sasa", "-surface", "atomnr 1" }; setTopology("lysozyme.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); setOutputFile("-q", "connolly.pdb", ExactTextMatch()); @@ -145,11 +134,7 @@ TEST_F(SasaModuleTest, WritesConnollySurfaceWithoutSolute) TEST_F(SasaModuleTest, HandlesDynamicOutputGroup) { - const char *const cmdline[] = { - "sasa", - "-surface", "all", - "-output", "y > 1.5" - }; + const char* const cmdline[] = { "sasa", "-surface", "all", "-output", "y > 1.5" }; setTopology("lysozyme.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); setOutputFile("-or", ".xvg", NoTextMatch()); @@ -162,11 +147,7 @@ TEST_F(SasaModuleTest, HandlesDynamicOutputGroup) TEST_F(SasaModuleTest, HandlesDynamicCalculationGroup) { - const char *const cmdline[] = { - "sasa", - "-surface", "y > 1.5", - "-output", "y > 1.5 and z > 0" - }; + const char* const cmdline[] = { "sasa", "-surface", "y > 1.5", "-output", "y > 1.5 and z > 0" }; setTopology("lysozyme.gro"); setOutputFile("-o", ".xvg", NoTextMatch()); setOutputFile("-or", ".xvg", NoTextMatch()); diff --git a/src/gromacs/trajectoryanalysis/tests/select.cpp b/src/gromacs/trajectoryanalysis/tests/select.cpp index d7d276627f..5e6487ea51 100644 --- a/src/gromacs/trajectoryanalysis/tests/select.cpp +++ b/src/gromacs/trajectoryanalysis/tests/select.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,15 +69,11 @@ using gmx::test::ExactTextMatch; */ //! Test fixture for the select analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - SelectModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture SelectModuleTest; TEST_F(SelectModuleTest, BasicTest) { - const char *const cmdline[] = { - "select", - "-select", "y < 2.5", "resname RA" - }; + const char* const cmdline[] = { "select", "-select", "y < 2.5", "resname RA" }; setTopology("simple.gro"); setTrajectory("simple.gro"); setOutputFile("-oi", "index.dat", ExactTextMatch()); @@ -88,10 +84,7 @@ TEST_F(SelectModuleTest, BasicTest) TEST_F(SelectModuleTest, HandlesPDBOutputWithNonPDBInput) { - const char *const cmdline[] = { - "select", - "-select", "resname RA RD and y < 2.5" - }; + const char* const cmdline[] = { "select", "-select", "resname RA RD and y < 2.5" }; setTopology("simple.gro"); setTrajectory("simple.gro"); includeDataset("occupancy"); @@ -101,10 +94,7 @@ TEST_F(SelectModuleTest, HandlesPDBOutputWithNonPDBInput) TEST_F(SelectModuleTest, HandlesPDBOutputWithPDBInput) { - const char *const cmdline[] = { - "select", - "-select", "resname RA RD and y < 2.5" - }; + const char* const cmdline[] = { "select", "-select", "resname RA RD and y < 2.5" }; setTopology("simple.pdb"); setTrajectory("simple.gro"); includeDataset("occupancy"); @@ -114,11 +104,8 @@ TEST_F(SelectModuleTest, HandlesPDBOutputWithPDBInput) TEST_F(SelectModuleTest, HandlesMaxPDBOutput) { - const char *const cmdline[] = { - "select", - "-select", "resname RA RD and y < 2.5", "resname RA RB", - "-pdbatoms", "maxsel" - }; + const char* const cmdline[] = { "select", "-select", "resname RA RD and y < 2.5", + "resname RA RB", "-pdbatoms", "maxsel" }; setTopology("simple.pdb"); setTrajectory("simple.gro"); includeDataset("occupancy"); @@ -128,11 +115,8 @@ TEST_F(SelectModuleTest, HandlesMaxPDBOutput) TEST_F(SelectModuleTest, HandlesSelectedPDBOutput) { - const char *const cmdline[] = { - "select", - "-select", "resname RA RD and y < 2.5", "resname RA RB", - "-pdbatoms", "selected" - }; + const char* const cmdline[] = { "select", "-select", "resname RA RD and y < 2.5", + "resname RA RB", "-pdbatoms", "selected" }; setTopology("simple.pdb"); setTrajectory("simple.gro"); includeDataset("occupancy"); @@ -142,11 +126,8 @@ TEST_F(SelectModuleTest, HandlesSelectedPDBOutput) TEST_F(SelectModuleTest, NormalizesSizes) { - const char *const cmdline[] = { - "select", - "-select", "y < 2.5", "resname RA and y < 2.5", "resname RA", - "-norm" - }; + const char* const cmdline[] = { "select", "-select", "y < 2.5", "resname RA and y < 2.5", + "resname RA", "-norm" }; setTopology("simple.gro"); includeDataset("size"); runTest(CommandLine(cmdline)); @@ -154,10 +135,7 @@ TEST_F(SelectModuleTest, NormalizesSizes) TEST_F(SelectModuleTest, WritesResidueNumbers) { - const char *const cmdline[] = { - "select", - "-select", "res_com of resname RA RD" - }; + const char* const cmdline[] = { "select", "-select", "res_com of resname RA RD" }; setTopology("simple.gro"); includeDataset("index"); runTest(CommandLine(cmdline)); @@ -165,11 +143,8 @@ TEST_F(SelectModuleTest, WritesResidueNumbers) TEST_F(SelectModuleTest, WritesResidueIndices) { - const char *const cmdline[] = { - "select", - "-select", "res_com of resname RA RD", - "-resnr", "index" - }; + const char* const cmdline[] = { "select", "-select", "res_com of resname RA RD", "-resnr", + "index" }; setTopology("simple.gro"); includeDataset("index"); runTest(CommandLine(cmdline)); diff --git a/src/gromacs/trajectoryanalysis/tests/surfacearea.cpp b/src/gromacs/trajectoryanalysis/tests/surfacearea.cpp index f1473e479f..880e34ac22 100644 --- a/src/gromacs/trajectoryanalysis/tests/surfacearea.cpp +++ b/src/gromacs/trajectoryanalysis/tests/surfacearea.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,196 +68,192 @@ namespace class SurfaceAreaTest : public ::testing::Test { - public: - SurfaceAreaTest() - : box_(), rng_(12345), area_(0.0), volume_(0.0), - atomArea_(nullptr), dotCount_(0), dots_(nullptr) +public: + SurfaceAreaTest() : + box_(), + rng_(12345), + area_(0.0), + volume_(0.0), + atomArea_(nullptr), + dotCount_(0), + dots_(nullptr) + { + } + ~SurfaceAreaTest() override + { + sfree(atomArea_); + sfree(dots_); + } + + void addSphere(real x, real y, real z, real radius, bool bAddToIndex = true) + { + if (bAddToIndex) { + index_.push_back(x_.size()); } - ~SurfaceAreaTest() override + x_.emplace_back(x, y, z); + radius_.push_back(radius); + } + + void generateRandomPosition(rvec x, real* radius) + { + rvec fx; + gmx::UniformRealDistribution dist; + + fx[XX] = dist(rng_); + fx[YY] = dist(rng_); + fx[ZZ] = dist(rng_); + mvmul(box_, fx, x); + *radius = 1.5 * dist(rng_) + 0.5; + } + + void generateRandomPositions(int count) + { + x_.reserve(count); + radius_.reserve(count); + index_.reserve(count); + for (int i = 0; i < count; ++i) { - sfree(atomArea_); - sfree(dots_); + rvec x; + real radius; + generateRandomPosition(x, &radius); + addSphere(x[XX], x[YY], x[ZZ], radius); } - - void addSphere(real x, real y, real z, real radius, - bool bAddToIndex = true) + } + void translatePoints(real x, real y, real z) + { + for (size_t i = 0; i < x_.size(); ++i) { - if (bAddToIndex) - { - index_.push_back(x_.size()); - } - x_.emplace_back(x, y, z); - radius_.push_back(radius); + x_[i][XX] += x; + x_[i][YY] += y; + x_[i][ZZ] += z; } - - void generateRandomPosition(rvec x, real *radius) + } + + void calculate(int ndots, int flags, bool bPBC) + { + volume_ = 0.0; + sfree(atomArea_); + atomArea_ = nullptr; + dotCount_ = 0; + sfree(dots_); + dots_ = nullptr; + t_pbc pbc; + if (bPBC) { - rvec fx; - gmx::UniformRealDistribution dist; - - fx[XX] = dist(rng_); - fx[YY] = dist(rng_); - fx[ZZ] = dist(rng_); - mvmul(box_, fx, x); - *radius = 1.5*dist(rng_) + 0.5; + set_pbc(&pbc, epbcXYZ, box_); } - - void generateRandomPositions(int count) + ASSERT_NO_THROW_GMX({ + gmx::SurfaceAreaCalculator calculator; + calculator.setDotCount(ndots); + calculator.setRadii(radius_); + calculator.calculate(as_rvec_array(x_.data()), bPBC ? &pbc : nullptr, index_.size(), + index_.data(), flags, &area_, &volume_, &atomArea_, &dots_, &dotCount_); + }); + } + real resultArea() const { return area_; } + real resultVolume() const { return volume_; } + real atomArea(int index) const { return atomArea_[index]; } + + void checkReference(gmx::test::TestReferenceChecker* checker, const char* id, bool checkDotCoordinates) + { + gmx::test::TestReferenceChecker compound(checker->checkCompound("SASA", id)); + compound.checkReal(area_, "Area"); + if (volume_ > 0.0) { - x_.reserve(count); - radius_.reserve(count); - index_.reserve(count); - for (int i = 0; i < count; ++i) - { - rvec x; - real radius; - generateRandomPosition(x, &radius); - addSphere(x[XX], x[YY], x[ZZ], radius); - } - } - void translatePoints(real x, real y, real z) - { - for (size_t i = 0; i < x_.size(); ++i) - { - x_[i][XX] += x; - x_[i][YY] += y; - x_[i][ZZ] += z; - } + compound.checkReal(volume_, "Volume"); } - - void calculate(int ndots, int flags, bool bPBC) + if (atomArea_ != nullptr) { - volume_ = 0.0; - sfree(atomArea_); - atomArea_ = nullptr; - dotCount_ = 0; - sfree(dots_); - dots_ = nullptr; - t_pbc pbc; - if (bPBC) - { - set_pbc(&pbc, epbcXYZ, box_); - } - ASSERT_NO_THROW_GMX( - { - gmx::SurfaceAreaCalculator calculator; - calculator.setDotCount(ndots); - calculator.setRadii(radius_); - calculator.calculate(as_rvec_array(x_.data()), bPBC ? &pbc : nullptr, - index_.size(), index_.data(), flags, - &area_, &volume_, &atomArea_, - &dots_, &dotCount_); - }); + compound.checkSequenceArray(index_.size(), atomArea_, "AtomArea"); } - real resultArea() const { return area_; } - real resultVolume() const { return volume_; } - real atomArea(int index) const { return atomArea_[index]; } - - void checkReference(gmx::test::TestReferenceChecker *checker, const char *id, - bool checkDotCoordinates) + if (dots_ != nullptr) { - gmx::test::TestReferenceChecker compound( - checker->checkCompound("SASA", id)); - compound.checkReal(area_, "Area"); - if (volume_ > 0.0) - { - compound.checkReal(volume_, "Volume"); - } - if (atomArea_ != nullptr) + if (checkDotCoordinates) { - compound.checkSequenceArray(index_.size(), atomArea_, "AtomArea"); + // The algorithm may produce the dots in different order in + // single and double precision due to some internal + // sorting... + std::qsort(dots_, dotCount_, sizeof(rvec), &dotComparer); + compound.checkSequenceArray(3 * dotCount_, dots_, "Dots"); } - if (dots_ != nullptr) + else { - if (checkDotCoordinates) - { - // The algorithm may produce the dots in different order in - // single and double precision due to some internal - // sorting... - std::qsort(dots_, dotCount_, sizeof(rvec), &dotComparer); - compound.checkSequenceArray(3*dotCount_, dots_, "Dots"); - } - else - { - compound.checkInteger(dotCount_, "DotCount"); - } + compound.checkInteger(dotCount_, "DotCount"); } } + } - gmx::test::TestReferenceData data_; - matrix box_; + gmx::test::TestReferenceData data_; + matrix box_; - private: - static int dotComparer(const void *a, const void *b) +private: + static int dotComparer(const void* a, const void* b) + { + for (int d = DIM - 1; d >= 0; --d) { - for (int d = DIM - 1; d >= 0; --d) + const real ad = reinterpret_cast(a)[d]; + const real bd = reinterpret_cast(b)[d]; + // A fudge factor is needed to get an ordering that is the same + // in single and double precision, since the points are not + // exactly on the same Z plane even though in exact arithmetic + // they probably would be. + if (ad < bd - 0.001) { - const real ad = reinterpret_cast(a)[d]; - const real bd = reinterpret_cast(b)[d]; - // A fudge factor is needed to get an ordering that is the same - // in single and double precision, since the points are not - // exactly on the same Z plane even though in exact arithmetic - // they probably would be. - if (ad < bd - 0.001) - { - return -1; - } - else if (ad > bd + 0.001) - { - return 1; - } + return -1; + } + else if (ad > bd + 0.001) + { + return 1; } - return 0; } - - gmx::DefaultRandomEngine rng_; - std::vector x_; - std::vector radius_; - std::vector index_; - - real area_; - real volume_; - real *atomArea_; - int dotCount_; - real *dots_; + return 0; + } + + gmx::DefaultRandomEngine rng_; + std::vector x_; + std::vector radius_; + std::vector index_; + + real area_; + real volume_; + real* atomArea_; + int dotCount_; + real* dots_; }; TEST_F(SurfaceAreaTest, ComputesSinglePoint) { - gmx::test::FloatingPointTolerance tolerance( - gmx::test::defaultRealTolerance()); + gmx::test::FloatingPointTolerance tolerance(gmx::test::defaultRealTolerance()); addSphere(1, 1, 1, 1); ASSERT_NO_FATAL_FAILURE(calculate(24, FLAG_VOLUME | FLAG_ATOM_AREA, false)); - EXPECT_REAL_EQ_TOL(4*M_PI, resultArea(), tolerance); - EXPECT_REAL_EQ_TOL(4*M_PI, atomArea(0), tolerance); - EXPECT_REAL_EQ_TOL(4*M_PI/3, resultVolume(), tolerance); + EXPECT_REAL_EQ_TOL(4 * M_PI, resultArea(), tolerance); + EXPECT_REAL_EQ_TOL(4 * M_PI, atomArea(0), tolerance); + EXPECT_REAL_EQ_TOL(4 * M_PI / 3, resultVolume(), tolerance); } TEST_F(SurfaceAreaTest, ComputesTwoPoints) { - gmx::test::FloatingPointTolerance tolerance( - gmx::test::relativeToleranceAsFloatingPoint(1.0, 0.005)); + gmx::test::FloatingPointTolerance tolerance(gmx::test::relativeToleranceAsFloatingPoint(1.0, 0.005)); addSphere(1, 1, 1, 1); addSphere(2, 1, 1, 1); ASSERT_NO_FATAL_FAILURE(calculate(1000, FLAG_ATOM_AREA, false)); - EXPECT_REAL_EQ_TOL(2*2*M_PI*1.5, resultArea(), tolerance); - EXPECT_REAL_EQ_TOL(2*M_PI*1.5, atomArea(0), tolerance); - EXPECT_REAL_EQ_TOL(2*M_PI*1.5, atomArea(1), tolerance); + EXPECT_REAL_EQ_TOL(2 * 2 * M_PI * 1.5, resultArea(), tolerance); + EXPECT_REAL_EQ_TOL(2 * M_PI * 1.5, atomArea(0), tolerance); + EXPECT_REAL_EQ_TOL(2 * M_PI * 1.5, atomArea(1), tolerance); } TEST_F(SurfaceAreaTest, ComputesTwoPointsOfUnequalRadius) { - gmx::test::FloatingPointTolerance tolerance( - gmx::test::relativeToleranceAsFloatingPoint(1.0, 0.005)); + gmx::test::FloatingPointTolerance tolerance(gmx::test::relativeToleranceAsFloatingPoint(1.0, 0.005)); // Spheres of radius 1 and 2 with intersection at 1.5 const real dist = 0.5 + sqrt(3.25); addSphere(1.0, 1.0, 1.0, 1); addSphere(1.0 + dist, 1.0, 1.0, 2); ASSERT_NO_FATAL_FAILURE(calculate(1000, FLAG_ATOM_AREA, false)); - EXPECT_REAL_EQ_TOL(2*M_PI*(1.5 + (dist - 0.5 + 2)*2), resultArea(), tolerance); - EXPECT_REAL_EQ_TOL(2*M_PI*1.5, atomArea(0), tolerance); - EXPECT_REAL_EQ_TOL(2*M_PI*(dist - 0.5 + 2)*2, atomArea(1), tolerance); + EXPECT_REAL_EQ_TOL(2 * M_PI * (1.5 + (dist - 0.5 + 2) * 2), resultArea(), tolerance); + EXPECT_REAL_EQ_TOL(2 * M_PI * 1.5, atomArea(0), tolerance); + EXPECT_REAL_EQ_TOL(2 * M_PI * (dist - 0.5 + 2) * 2, atomArea(1), tolerance); } TEST_F(SurfaceAreaTest, SurfacePoints12) @@ -314,9 +310,9 @@ TEST_F(SurfaceAreaTest, Computes100PointsWithRectangularPBC) box_[YY][YY] = 10.0; box_[ZZ][ZZ] = 10.0; generateRandomPositions(100); - box_[XX][XX] = 20.0; - box_[YY][YY] = 20.0; - box_[ZZ][ZZ] = 20.0; + box_[XX][XX] = 20.0; + box_[YY][YY] = 20.0; + box_[ZZ][ZZ] = 20.0; const int flags = FLAG_ATOM_AREA | FLAG_VOLUME | FLAG_DOTS; ASSERT_NO_FATAL_FAILURE(calculate(24, flags, true)); checkReference(&checker, "100Points", false); @@ -346,10 +342,10 @@ TEST_F(SurfaceAreaTest, Computes100PointsWithTriclinicPBC) generateRandomPositions(100); box_[XX][XX] = 20.0; box_[YY][XX] = 10.0; - box_[YY][YY] = 10.0*sqrt(3.0); + box_[YY][YY] = 10.0 * sqrt(3.0); box_[ZZ][XX] = 10.0; - box_[ZZ][YY] = 10.0*sqrt(1.0/3.0); - box_[ZZ][ZZ] = 20.0*sqrt(2.0/3.0); + box_[ZZ][YY] = 10.0 * sqrt(1.0 / 3.0); + box_[ZZ][ZZ] = 20.0 * sqrt(2.0 / 3.0); const int flags = FLAG_ATOM_AREA | FLAG_VOLUME | FLAG_DOTS; ASSERT_NO_FATAL_FAILURE(calculate(24, flags, true)); diff --git a/src/gromacs/trajectoryanalysis/tests/test_selection.cpp b/src/gromacs/trajectoryanalysis/tests/test_selection.cpp index b1841dcf95..2a04f0d225 100644 --- a/src/gromacs/trajectoryanalysis/tests/test_selection.cpp +++ b/src/gromacs/trajectoryanalysis/tests/test_selection.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,39 +56,30 @@ namespace gmx class SelectionTester : public TrajectoryAnalysisModule { - public: - SelectionTester(); - ~SelectionTester() override; +public: + SelectionTester(); + ~SelectionTester() override; - void initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) override; - void initAnalysis(const TrajectoryAnalysisSettings &settings, - const TopologyInformation &top) override; + void initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) override; + void initAnalysis(const TrajectoryAnalysisSettings& settings, const TopologyInformation& top) override; - void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc, - TrajectoryAnalysisModuleData *pdata) override; + void analyzeFrame(int frnr, const t_trxframe& fr, t_pbc* pbc, TrajectoryAnalysisModuleData* pdata) override; - void finishAnalysis(int nframes) override; - void writeOutput() override; + void finishAnalysis(int nframes) override; + void writeOutput() override; - private: - void printSelections(); +private: + void printSelections(); - SelectionList selections_; - int nmaxind_; + SelectionList selections_; + int nmaxind_; }; -SelectionTester::SelectionTester() - : nmaxind_(20) -{ -} +SelectionTester::SelectionTester() : nmaxind_(20) {} -SelectionTester::~SelectionTester() -{ -} +SelectionTester::~SelectionTester() {} -void -SelectionTester::printSelections() +void SelectionTester::printSelections() { fprintf(stderr, "\nSelections:\n"); for (size_t g = 0; g < selections_.size(); ++g) @@ -97,38 +89,33 @@ SelectionTester::printSelections() fprintf(stderr, "\n"); } -void -SelectionTester::initOptions(IOptionsContainer *options, - TrajectoryAnalysisSettings *settings) +void SelectionTester::initOptions(IOptionsContainer* options, TrajectoryAnalysisSettings* settings) { - static const char *const desc[] = { - "This is a test program for selections." - }; + static const char* const desc[] = { "This is a test program for selections." }; settings->setHelpText(desc); - options->addOption(SelectionOption("select").storeVector(&selections_) - .required().multiValue() - .description("Selections to test")); - options->addOption(IntegerOption("pmax").store(&nmaxind_) - .description("Maximum number of indices to print in lists (-1 = print all)")); + options->addOption( + SelectionOption("select").storeVector(&selections_).required().multiValue().description("Selections to test")); + options->addOption(IntegerOption("pmax").store(&nmaxind_).description( + "Maximum number of indices to print in lists (-1 = print all)")); } -void -SelectionTester::initAnalysis(const TrajectoryAnalysisSettings & /*settings*/, - const TopologyInformation & /*top*/) +void SelectionTester::initAnalysis(const TrajectoryAnalysisSettings& /*settings*/, + const TopologyInformation& /*top*/) { printSelections(); } -void -SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe & /*fr*/, t_pbc * /*pbc*/, - TrajectoryAnalysisModuleData * /*pdata*/) +void SelectionTester::analyzeFrame(int /*frnr*/, + const t_trxframe& /*fr*/, + t_pbc* /*pbc*/, + TrajectoryAnalysisModuleData* /*pdata*/) { fprintf(stderr, "\n"); for (size_t g = 0; g < selections_.size(); ++g) { - const Selection &sel = selections_[g]; + const Selection& sel = selections_[g]; int n; fprintf(stderr, " Atoms (%d pcs):", sel.atomCount()); @@ -140,7 +127,7 @@ SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe & /*fr*/, t_pbc * / ArrayRef atoms = sel.atomIndices(); for (int i = 0; i < n; ++i) { - fprintf(stderr, " %d", atoms[i]+1); + fprintf(stderr, " %d", atoms[i] + 1); } if (n < sel.atomCount()) { @@ -156,10 +143,9 @@ SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe & /*fr*/, t_pbc * / } for (int i = 0; i < n; ++i) { - const SelectionPosition &p = sel.position(i); - fprintf(stderr, " (%.2f,%.2f,%.2f) r=%d, m=%d, n=%d\n", - p.x()[XX], p.x()[YY], p.x()[ZZ], - p.refId(), p.mappedId(), p.atomCount()); + const SelectionPosition& p = sel.position(i); + fprintf(stderr, " (%.2f,%.2f,%.2f) r=%d, m=%d, n=%d\n", p.x()[XX], p.x()[YY], + p.x()[ZZ], p.refId(), p.mappedId(), p.atomCount()); } if (n < sel.posCount()) { @@ -169,24 +155,19 @@ SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe & /*fr*/, t_pbc * / fprintf(stderr, "\n"); } -void -SelectionTester::finishAnalysis(int /*nframes*/) +void SelectionTester::finishAnalysis(int /*nframes*/) { printSelections(); } -void -SelectionTester::writeOutput() -{ -} +void SelectionTester::writeOutput() {} -} // namespace gmx +} // namespace gmx /*! \internal \brief * The main function for the selection testing tool. */ -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { return gmx::TrajectoryAnalysisCommandLineRunner::runAsMain(argc, argv); } diff --git a/src/gromacs/trajectoryanalysis/tests/topologyinformation.cpp b/src/gromacs/trajectoryanalysis/tests/topologyinformation.cpp index 6d29b0e670..7124600ac9 100644 --- a/src/gromacs/trajectoryanalysis/tests/topologyinformation.cpp +++ b/src/gromacs/trajectoryanalysis/tests/topologyinformation.cpp @@ -80,9 +80,7 @@ TEST(TopologyInformation, CantWorkWithoutReadingAFile) EXPECT_EQ(-1, topInfo.ePBC()); EXPECT_THROW(topInfo.x().size(), gmx::APIError); EXPECT_THROW(topInfo.v().size(), gmx::APIError); - matrix box {{ - -2 - }}; + matrix box{ { -2 } }; topInfo.getBox(box); EXPECT_EQ(0, box[XX][XX]); EXPECT_EQ(0, box[XX][YY]); @@ -97,7 +95,7 @@ TEST(TopologyInformation, CantWorkWithoutReadingAFile) } //! Common test code to reduce duplication -void runCommonTests(const TopologyInformation &topInfo, const int numAtoms) +void runCommonTests(const TopologyInformation& topInfo, const int numAtoms) { EXPECT_TRUE(topInfo.hasTopology()); ASSERT_TRUE(topInfo.mtop()); @@ -116,18 +114,16 @@ void runCommonTests(const TopologyInformation &topInfo, const int numAtoms) EXPECT_NE(atoms2.get(), atoms); EXPECT_EQ(numAtoms, topInfo.x().size()); EXPECT_EQ(numAtoms, topInfo.v().size()); - matrix box {{ - -2 - }}; + matrix box{ { -2 } }; topInfo.getBox(box); EXPECT_FLOAT_EQ(5.9062, box[XX][XX]); - EXPECT_FLOAT_EQ(0, box[XX][YY]); - EXPECT_FLOAT_EQ(0, box[XX][ZZ]); - EXPECT_FLOAT_EQ(0, box[YY][XX]); + EXPECT_FLOAT_EQ(0, box[XX][YY]); + EXPECT_FLOAT_EQ(0, box[XX][ZZ]); + EXPECT_FLOAT_EQ(0, box[YY][XX]); EXPECT_FLOAT_EQ(6.8451, box[YY][YY]); - EXPECT_FLOAT_EQ(0, box[YY][ZZ]); - EXPECT_FLOAT_EQ(0, box[ZZ][XX]); - EXPECT_FLOAT_EQ(0, box[ZZ][YY]); + EXPECT_FLOAT_EQ(0, box[YY][ZZ]); + EXPECT_FLOAT_EQ(0, box[ZZ][XX]); + EXPECT_FLOAT_EQ(0, box[ZZ][YY]); EXPECT_FLOAT_EQ(3.0517, box[ZZ][ZZ]); EXPECT_STREQ("First 10 residues from 1AKI", topInfo.name()); } diff --git a/src/gromacs/trajectoryanalysis/tests/trajectory.cpp b/src/gromacs/trajectoryanalysis/tests/trajectory.cpp index 2124ebe165..0c58d0ed48 100644 --- a/src/gromacs/trajectoryanalysis/tests/trajectory.cpp +++ b/src/gromacs/trajectoryanalysis/tests/trajectory.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,15 +66,11 @@ using gmx::test::NoTextMatch; */ //! Test fixture for the select analysis module. -typedef gmx::test::TrajectoryAnalysisModuleTestFixture - TrajectoryModuleTest; +typedef gmx::test::TrajectoryAnalysisModuleTestFixture TrajectoryModuleTest; TEST_F(TrajectoryModuleTest, BasicTest) { - const char *const cmdline[] = { - "trajectory", - "-select", "resnr 1", "resnr 3" - }; + const char* const cmdline[] = { "trajectory", "-select", "resnr 1", "resnr 3" }; setTopology("simple.gro"); setTrajectory("simple.gro"); setOutputFile("-ox", "coord.xvg", NoTextMatch()); @@ -84,11 +80,7 @@ TEST_F(TrajectoryModuleTest, BasicTest) TEST_F(TrajectoryModuleTest, PlotsXOnly) { - const char *const cmdline[] = { - "trajectory", - "-select", "resnr 1", "resnr 3", - "-x" - }; + const char* const cmdline[] = { "trajectory", "-select", "resnr 1", "resnr 3", "-x" }; setTopology("simple.gro"); setTrajectory("simple.gro"); setOutputFile("-ox", "coord.xvg", NoTextMatch()); @@ -98,9 +90,11 @@ TEST_F(TrajectoryModuleTest, PlotsXOnly) TEST_F(TrajectoryModuleTest, HandlesNoVelocities) { - const char *const cmdline[] = { + const char* const cmdline[] = { "trajectory", - "-select", "resnr 1", "resnr 3", + "-select", + "resnr 1", + "resnr 3", }; setTopology("simple.gro"); setTrajectory("simple.gro"); @@ -111,9 +105,11 @@ TEST_F(TrajectoryModuleTest, HandlesNoVelocities) TEST_F(TrajectoryModuleTest, HandlesNoForces) { - const char *const cmdline[] = { + const char* const cmdline[] = { "trajectory", - "-select", "resnr 1", "resnr 3", + "-select", + "resnr 1", + "resnr 3", }; setTopology("simple.gro"); setTrajectory("simple.gro"); diff --git a/src/gromacs/trajectoryanalysis/tests/unionfind.cpp b/src/gromacs/trajectoryanalysis/tests/unionfind.cpp index abfecf0fdd..37e9aa7298 100644 --- a/src/gromacs/trajectoryanalysis/tests/unionfind.cpp +++ b/src/gromacs/trajectoryanalysis/tests/unionfind.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -124,7 +124,7 @@ TEST(UnionFinderTest, LongLeftMerge) TEST(MappedUnionFinderTest, BasicMerges) { using ::testing::Each; - const int mapping[] = {1, 1, 2, 2, 4, 6}; + const int mapping[] = { 1, 1, 2, 2, 4, 6 }; gmx::MappedUnionFinder finder; finder.initWithGroupIndices(mapping); EXPECT_EQ(4U, finder.allSizes().size()); diff --git a/src/gromacs/trajectoryanalysis/topologyinformation.cpp b/src/gromacs/trajectoryanalysis/topologyinformation.cpp index 15f100aa9f..74f1609e51 100644 --- a/src/gromacs/trajectoryanalysis/topologyinformation.cpp +++ b/src/gromacs/trajectoryanalysis/topologyinformation.cpp @@ -59,20 +59,19 @@ namespace gmx { -TopologyInformation::TopologyInformation() - : hasLoadedMtop_(false), - expandedTopology_(nullptr), - atoms_ (nullptr), - bTop_(false), ePBC_(-1) +TopologyInformation::TopologyInformation() : + hasLoadedMtop_(false), + expandedTopology_(nullptr), + atoms_(nullptr), + bTop_(false), + ePBC_(-1) { } -TopologyInformation::~TopologyInformation() -{ -} +TopologyInformation::~TopologyInformation() {} -void TopologyInformation::fillFromInputFile(const std::string &filename) +void TopologyInformation::fillFromInputFile(const std::string& filename) { mtop_ = std::make_unique(); // TODO When filename is not a .tpr, then using readConfAndAtoms @@ -82,9 +81,7 @@ void TopologyInformation::fillFromInputFile(const std::string &filename) // TODO Once there are fewer callers of the file-reading // functionality, make them read directly into std::vector. rvec *x, *v; - readConfAndTopology(filename.c_str(), &bTop_, mtop_.get(), - &ePBC_, &x, &v, - boxtop_); + readConfAndTopology(filename.c_str(), &bTop_, mtop_.get(), &ePBC_, &x, &v, boxtop_); xtop_.assign(x, x + mtop_->natoms); vtop_.assign(v, v + mtop_->natoms); sfree(x); @@ -92,7 +89,7 @@ void TopologyInformation::fillFromInputFile(const std::string &filename) hasLoadedMtop_ = true; // TODO: Only load this here if the tool actually needs it; selections // take care of themselves. - for (gmx_moltype_t &moltype : mtop_->moltype) + for (gmx_moltype_t& moltype : mtop_->moltype) { if (!moltype.atoms.haveMass) { @@ -102,7 +99,7 @@ void TopologyInformation::fillFromInputFile(const std::string &filename) } } -const gmx_localtop_t *TopologyInformation::expandedTopology() const +const gmx_localtop_t* TopologyInformation::expandedTopology() const { // Do lazy initialization if (expandedTopology_ == nullptr && hasTopology()) @@ -118,7 +115,7 @@ namespace { //! Helps implement lazy initialization. -AtomsDataPtr makeAtoms(const TopologyInformation &top_) +AtomsDataPtr makeAtoms(const TopologyInformation& top_) { AtomsDataPtr atoms(new t_atoms); if (top_.hasTopology()) @@ -132,9 +129,9 @@ AtomsDataPtr makeAtoms(const TopologyInformation &top_) return atoms; } -} // namespace +} // namespace -const t_atoms *TopologyInformation::atoms() const +const t_atoms* TopologyInformation::atoms() const { // Do lazy initialization if (atoms_ == nullptr) @@ -154,8 +151,7 @@ AtomsDataPtr TopologyInformation::copyAtoms() const return makeAtoms(*this); } -ArrayRef -TopologyInformation::x() const +ArrayRef TopologyInformation::x() const { if (xtop_.empty()) { @@ -164,8 +160,7 @@ TopologyInformation::x() const return xtop_; } -ArrayRef -TopologyInformation::v() const +ArrayRef TopologyInformation::v() const { if (vtop_.empty()) { @@ -174,15 +169,13 @@ TopologyInformation::v() const return vtop_; } -void -TopologyInformation::getBox(matrix box) const +void TopologyInformation::getBox(matrix box) const { GMX_RELEASE_ASSERT(box != nullptr, "Must have valid box to fill"); - copy_mat(const_cast(boxtop_), box); + copy_mat(const_cast(boxtop_), box); } -const char * -TopologyInformation::name() const +const char* TopologyInformation::name() const { if (hasTopology() && mtop_->name) { @@ -191,7 +184,7 @@ TopologyInformation::name() const return nullptr; } -gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation &topInfo) +gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation& topInfo) { GMX_RELEASE_ASSERT(topInfo.hasTopology(), "Cannot remove PBC without a topology"); diff --git a/src/gromacs/trajectoryanalysis/topologyinformation.h b/src/gromacs/trajectoryanalysis/topologyinformation.h index 5748029dbc..e9f9d5374d 100644 --- a/src/gromacs/trajectoryanalysis/topologyinformation.h +++ b/src/gromacs/trajectoryanalysis/topologyinformation.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,12 +54,13 @@ #include "gromacs/utility/classhelpers.h" //! Forward declaration -typedef struct gmx_rmpbc *gmx_rmpbc_t; +typedef struct gmx_rmpbc* gmx_rmpbc_t; namespace gmx { -template class ArrayRef; +template +class ArrayRef; class TopologyInformation; class TrajectoryAnalysisRunnerCommon; @@ -97,108 +98,108 @@ class TrajectoryAnalysisRunnerCommon; */ class TopologyInformation { - public: - //! Returns true if a topology file was loaded. - bool hasTopology() const { return hasLoadedMtop_; } - //! Returns true if a full topology file was loaded. - bool hasFullTopology() const { return bTop_; } - /*! \brief Builder function to fill the contents of - * TopologyInformation in \c topInfo from \c filename. - * - * Different tools require, might need, would benefit from, or - * do not need topology information. This functions implements - * the two-phase construction that is currently needed to - * support that. - * - * Any coordinate or run input file format will work, but the - * kind of data available from the getter methods afterwards - * will vary. For example, the mtop() available after reading - * a plain structure file will have a single molecule block and - * molecule type, regardless of contents. - * - * After reading, this object can return many kinds of primary - * and derived data structures to its caller. - * - * \todo This should throw upon error but currently does - * not. */ - void fillFromInputFile(const std::string &filename); - /*! \brief Returns the loaded topology, or nullptr if not loaded. */ - gmx_mtop_t *mtop() const { return mtop_.get(); } - //! Returns the loaded topology fully expanded, or nullptr if no topology is available. - const gmx_localtop_t *expandedTopology() const; - /*! \brief Returns a read-only handle to the fully expanded - * atom data arrays, which might be valid but empty if no - * topology is available. */ - const t_atoms *atoms() const; - /*! \brief Copies the fully expanded atom data arrays, which - * might be valid but empty if no topology is available. */ - AtomsDataPtr copyAtoms() const; - //! Returns the ePBC field from the topology. - int ePBC() const { return ePBC_; } - /*! \brief - * Gets the configuration positions from the topology file. - * - * If TrajectoryAnalysisSettings::efUseTopX has not been specified, - * this method should not be called. - * - * \throws APIError if topology position coordinates are not available - */ - ArrayRef x() const; - /*! \brief - * Gets the configuration velocities from the topology file. - * - * If TrajectoryAnalysisSettings::efUseTopV has not been specified, - * this method should not be called. - * - * \throws APIError if topology velocity coordinates are not available - */ - ArrayRef v() const; - /*! \brief - * Gets the configuration box from the topology file. - * - * \param[out] box Box size from the topology file, must not be nullptr. - */ - void getBox(matrix box) const; - /*! \brief Returns a name for the topology. - * - * If a full topology was read from a a file, returns the name - * it contained, otherwise the empty string. */ - const char *name() const; +public: + //! Returns true if a topology file was loaded. + bool hasTopology() const { return hasLoadedMtop_; } + //! Returns true if a full topology file was loaded. + bool hasFullTopology() const { return bTop_; } + /*! \brief Builder function to fill the contents of + * TopologyInformation in \c topInfo from \c filename. + * + * Different tools require, might need, would benefit from, or + * do not need topology information. This functions implements + * the two-phase construction that is currently needed to + * support that. + * + * Any coordinate or run input file format will work, but the + * kind of data available from the getter methods afterwards + * will vary. For example, the mtop() available after reading + * a plain structure file will have a single molecule block and + * molecule type, regardless of contents. + * + * After reading, this object can return many kinds of primary + * and derived data structures to its caller. + * + * \todo This should throw upon error but currently does + * not. */ + void fillFromInputFile(const std::string& filename); + /*! \brief Returns the loaded topology, or nullptr if not loaded. */ + gmx_mtop_t* mtop() const { return mtop_.get(); } + //! Returns the loaded topology fully expanded, or nullptr if no topology is available. + const gmx_localtop_t* expandedTopology() const; + /*! \brief Returns a read-only handle to the fully expanded + * atom data arrays, which might be valid but empty if no + * topology is available. */ + const t_atoms* atoms() const; + /*! \brief Copies the fully expanded atom data arrays, which + * might be valid but empty if no topology is available. */ + AtomsDataPtr copyAtoms() const; + //! Returns the ePBC field from the topology. + int ePBC() const { return ePBC_; } + /*! \brief + * Gets the configuration positions from the topology file. + * + * If TrajectoryAnalysisSettings::efUseTopX has not been specified, + * this method should not be called. + * + * \throws APIError if topology position coordinates are not available + */ + ArrayRef x() const; + /*! \brief + * Gets the configuration velocities from the topology file. + * + * If TrajectoryAnalysisSettings::efUseTopV has not been specified, + * this method should not be called. + * + * \throws APIError if topology velocity coordinates are not available + */ + ArrayRef v() const; + /*! \brief + * Gets the configuration box from the topology file. + * + * \param[out] box Box size from the topology file, must not be nullptr. + */ + void getBox(matrix box) const; + /*! \brief Returns a name for the topology. + * + * If a full topology was read from a a file, returns the name + * it contained, otherwise the empty string. */ + const char* name() const; - TopologyInformation(); - ~TopologyInformation(); + TopologyInformation(); + ~TopologyInformation(); - private: - //! The topology structure, or nullptr if no topology loaded. - std::unique_ptr mtop_; - //! Whether a topology has been loaded. - bool hasLoadedMtop_; - //! The fully expanded topology structure, nullptr if not yet constructed. - mutable ExpandedTopologyPtr expandedTopology_; - //! The fully expanded atoms data structure, nullptr if not yet constructed. - mutable AtomsDataPtr atoms_; - //! true if full tpx file was loaded, false otherwise. - bool bTop_; - //! Position coordinates from the topology (can be nullptr). - std::vector xtop_; - //! Velocity coordinates from the topology (can be nullptr). - std::vector vtop_; - //! The box loaded from the topology file. - matrix boxtop_ {}; - //! The ePBC field loaded from the topology file. - int ePBC_; +private: + //! The topology structure, or nullptr if no topology loaded. + std::unique_ptr mtop_; + //! Whether a topology has been loaded. + bool hasLoadedMtop_; + //! The fully expanded topology structure, nullptr if not yet constructed. + mutable ExpandedTopologyPtr expandedTopology_; + //! The fully expanded atoms data structure, nullptr if not yet constructed. + mutable AtomsDataPtr atoms_; + //! true if full tpx file was loaded, false otherwise. + bool bTop_; + //! Position coordinates from the topology (can be nullptr). + std::vector xtop_; + //! Velocity coordinates from the topology (can be nullptr). + std::vector vtop_; + //! The box loaded from the topology file. + matrix boxtop_{}; + //! The ePBC field loaded from the topology file. + int ePBC_; - // TODO This type is probably movable if we need that. - GMX_DISALLOW_COPY_AND_ASSIGN(TopologyInformation); + // TODO This type is probably movable if we need that. + GMX_DISALLOW_COPY_AND_ASSIGN(TopologyInformation); - /*! \brief - * Needed to initialize the data. - */ - friend class TrajectoryAnalysisRunnerCommon; + /*! \brief + * Needed to initialize the data. + */ + friend class TrajectoryAnalysisRunnerCommon; }; //! Convenience overload useful for implementing legacy tools. -gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation &topInfo); +gmx_rmpbc_t gmx_rmpbc_init(const gmx::TopologyInformation& topInfo); } // namespace gmx diff --git a/src/gromacs/utility.h b/src/gromacs/utility.h index 5c132f6896..47385350fc 100644 --- a/src/gromacs/utility.h +++ b/src/gromacs/utility.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2010-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. diff --git a/src/gromacs/utility/alignedallocator.cpp b/src/gromacs/utility/alignedallocator.cpp index b7b7bf764c..a6d073c3c9 100644 --- a/src/gromacs/utility/alignedallocator.cpp +++ b/src/gromacs/utility/alignedallocator.cpp @@ -59,11 +59,11 @@ #endif #ifdef HAVE_UNISTD_H -#include +# include #endif #if GMX_NATIVE_WINDOWS -#include // only for the page size query purposes +# include // only for the page size query purposes #endif #include "gromacs/utility/gmxassert.h" @@ -97,13 +97,12 @@ namespace * gmx::alignedMalloc(). Just like system-provided routines, it provides * memory that is aligned - but not padded. */ -gmx_unused void * -alignedMallocGeneric(std::size_t bytes, std::size_t alignment) +gmx_unused void* alignedMallocGeneric(std::size_t bytes, std::size_t alignment) { // The amount of extra memory (beyound what the user asked for) we need is: // - sizeof(void *), to store the original pointer // - alignment, to make sure we have an aligned pointer in the area - void * pMalloc = malloc(bytes + sizeof(void *) + alignment); + void* pMalloc = malloc(bytes + sizeof(void*) + alignment); if (pMalloc == nullptr) { @@ -113,12 +112,13 @@ alignedMallocGeneric(std::size_t bytes, std::size_t alignment) // Convert pMalloc to size_t (so we work with raw bytes), add the space we // need to save the original pointer, and (alignment-1) bytes, and then mask // out the lowest bits. - std::size_t mask = ~static_cast(alignment-1); - void * pAligned = reinterpret_cast((reinterpret_cast(pMalloc) + sizeof(void *) + alignment - 1) & mask); + std::size_t mask = ~static_cast(alignment - 1); + void* pAligned = reinterpret_cast( + (reinterpret_cast(pMalloc) + sizeof(void*) + alignment - 1) & mask); // Store original pointer. Since we allocated at least sizeof(void *) extra // space this is always a valid memory location. - reinterpret_cast(pAligned)[-1] = pMalloc; + reinterpret_cast(pAligned)[-1] = pMalloc; return pAligned; } @@ -137,23 +137,22 @@ alignedMallocGeneric(std::size_t bytes, std::size_t alignment) * \note This is an internal routine that should only be called from * gmx::alignedFree(). */ -gmx_unused void -alignedFreeGeneric(void *p) +gmx_unused void alignedFreeGeneric(void* p) { if (p) { // Pick up the pointer stored just below p, and use that to call free() - free( reinterpret_cast(p)[-1] ); + free(reinterpret_cast(p)[-1]); } } //! Implement malloc of \c bytes of memory, aligned to \c alignment. -void *mallocImpl(std::size_t bytes, std::size_t alignment) +void* mallocImpl(std::size_t bytes, std::size_t alignment) { - void * p; + void* p; #if HAVE__MM_MALLOC - p = _mm_malloc( bytes, alignment ); + p = _mm_malloc(bytes, alignment); #elif HAVE_POSIX_MEMALIGN if (posix_memalign(&p, alignment, bytes) != 0) { @@ -171,7 +170,7 @@ void *mallocImpl(std::size_t bytes, std::size_t alignment) } //! Free aligned memory allocated with mallocImpl(). -void freeImpl(void *p) +void freeImpl(void* p) { if (p) { @@ -187,7 +186,7 @@ void freeImpl(void *p) } } -} // namespace +} // namespace // === AlignedAllocationPolicy @@ -209,8 +208,7 @@ std::size_t AlignedAllocationPolicy::alignment() return 128; } -void * -AlignedAllocationPolicy::malloc(std::size_t bytes) +void* AlignedAllocationPolicy::malloc(std::size_t bytes) { // Pad memory at the end with another alignment bytes to avoid false sharing auto size = alignment(); @@ -219,8 +217,7 @@ AlignedAllocationPolicy::malloc(std::size_t bytes) return mallocImpl(bytes, size); } -void -AlignedAllocationPolicy::free(void *p) +void AlignedAllocationPolicy::free(void* p) { freeImpl(p); } @@ -231,7 +228,7 @@ AlignedAllocationPolicy::free(void *p) //! \todo Move this function into sysinfo.cpp where other OS-specific code/includes live static std::size_t getPageSize() { - long pageSize; + long pageSize; #if GMX_NATIVE_WINDOWS SYSTEM_INFO si; GetNativeSystemInfo(&si); @@ -247,7 +244,7 @@ static std::size_t getPageSize() pageSize = -1; #endif return ((pageSize == -1) ? 4096 // A useful guess - : static_cast(pageSize)); + : static_cast(pageSize)); } /* Implements the "construct on first use" idiom to avoid the static @@ -266,14 +263,12 @@ std::size_t PageAlignedAllocationPolicy::alignment() return thePageSize; } -void * -PageAlignedAllocationPolicy::malloc(std::size_t bytes) +void* PageAlignedAllocationPolicy::malloc(std::size_t bytes) { return mallocImpl(bytes, alignment()); } -void -PageAlignedAllocationPolicy::free(void *p) +void PageAlignedAllocationPolicy::free(void* p) { freeImpl(p); } diff --git a/src/gromacs/utility/alignedallocator.h b/src/gromacs/utility/alignedallocator.h index 9936437dce..baf599b03b 100644 --- a/src/gromacs/utility/alignedallocator.h +++ b/src/gromacs/utility/alignedallocator.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,38 +58,35 @@ namespace gmx */ class AlignedAllocationPolicy { - public: - /*! \brief Return the alignment size. */ - static std::size_t - alignment(); - /*! \brief Allocate memory aligned to alignment() bytes. - * - * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for - * 0 bytes, which will return a non-null pointer that is properly - * aligned and padded (but that you should not use). - * - * \return Valid pointer if the allocation worked, otherwise nullptr. - * - * The memory will always be aligned to 128 bytes, which is our - * estimate of the longest cache lines on architectures currently in use. - * It will also be padded by the same amount at the end of the - * area, to help avoid false cache sharing. - * - * \note Memory allocated with this routine must be released with - * gmx::AlignedAllocationPolicy::free(), and absolutely not the system free(). - */ - static void * - malloc(std::size_t bytes); - /*! \brief Free aligned memory - * - * \param p Memory pointer previously returned from malloc() - * - * \note This routine should only be called with pointers obtained from - * gmx::AlignedAllocationPolicy::malloc(), and absolutely not any - * pointers obtained the system malloc(). - */ - static void - free(void *p); +public: + /*! \brief Return the alignment size. */ + static std::size_t alignment(); + /*! \brief Allocate memory aligned to alignment() bytes. + * + * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for + * 0 bytes, which will return a non-null pointer that is properly + * aligned and padded (but that you should not use). + * + * \return Valid pointer if the allocation worked, otherwise nullptr. + * + * The memory will always be aligned to 128 bytes, which is our + * estimate of the longest cache lines on architectures currently in use. + * It will also be padded by the same amount at the end of the + * area, to help avoid false cache sharing. + * + * \note Memory allocated with this routine must be released with + * gmx::AlignedAllocationPolicy::free(), and absolutely not the system free(). + */ + static void* malloc(std::size_t bytes); + /*! \brief Free aligned memory + * + * \param p Memory pointer previously returned from malloc() + * + * \note This routine should only be called with pointers obtained from + * gmx::AlignedAllocationPolicy::malloc(), and absolutely not any + * pointers obtained the system malloc(). + */ + static void free(void* p); }; /*! \brief Aligned memory allocator. @@ -103,7 +100,7 @@ class AlignedAllocationPolicy * always be aligned according to the behavior of * AlignedAllocationPolicy. */ -template +template using AlignedAllocator = Allocator; @@ -123,35 +120,32 @@ std::size_t pageSize(); */ class PageAlignedAllocationPolicy { - public: - /*! \brief Return the alignment size of memory pages on this system. - * - * Queries sysconf/WinAPI, otherwise guesses 4096. */ - static std::size_t - alignment(); - /*! \brief Allocate memory aligned to alignment() bytes. - * - * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for - * 0 bytes, which will return a non-null pointer that is properly - * aligned and padded (but that you should not use). - * - * \return Valid pointer if the allocation worked, otherwise nullptr. - * - * \note Memory allocated with this routine must be released with - * gmx::PageAlignedAllocationPolicy::free(), and absolutely not the system free(). - */ - static void * - malloc(std::size_t bytes); - /*! \brief Free aligned memory - * - * \param p Memory pointer previously returned from malloc() - * - * \note This routine should only be called with pointers obtained from - * gmx::PageAlignedAllocationPolicy::malloc(), and absolutely not any - * pointers obtained the system malloc(). - */ - static void - free(void *p); +public: + /*! \brief Return the alignment size of memory pages on this system. + * + * Queries sysconf/WinAPI, otherwise guesses 4096. */ + static std::size_t alignment(); + /*! \brief Allocate memory aligned to alignment() bytes. + * + * \param bytes Amount of memory (bytes) to allocate. It is valid to ask for + * 0 bytes, which will return a non-null pointer that is properly + * aligned and padded (but that you should not use). + * + * \return Valid pointer if the allocation worked, otherwise nullptr. + * + * \note Memory allocated with this routine must be released with + * gmx::PageAlignedAllocationPolicy::free(), and absolutely not the system free(). + */ + static void* malloc(std::size_t bytes); + /*! \brief Free aligned memory + * + * \param p Memory pointer previously returned from malloc() + * + * \note This routine should only be called with pointers obtained from + * gmx::PageAlignedAllocationPolicy::malloc(), and absolutely not any + * pointers obtained the system malloc(). + */ + static void free(void* p); }; /*! \brief PageAligned memory allocator. @@ -165,9 +159,9 @@ class PageAlignedAllocationPolicy * memory will always be aligned according to the behavior of * PageAlignedAllocationPolicy. */ -template +template using PageAlignedAllocator = Allocator; -} // namespace gmx +} // namespace gmx #endif // GMX_UTILITY_ALIGNEDALLOCATOR_H diff --git a/src/gromacs/utility/allocator.h b/src/gromacs/utility/allocator.h index c292a154bf..c4d4a23027 100644 --- a/src/gromacs/utility/allocator.h +++ b/src/gromacs/utility/allocator.h @@ -94,84 +94,84 @@ namespace gmx * \inlibraryapi * \ingroup module_utility */ -template +template class Allocator : public AllocationPolicy { - public: - // The standard library specification for a custom allocator - // requires this typedef, with this capitalization/underscoring. - typedef T value_type; //!< Type of allocated elements +public: + // The standard library specification for a custom allocator + // requires this typedef, with this capitalization/underscoring. + typedef T value_type; //!< Type of allocated elements - /*! \brief Constructor - * - * No constructor can be auto-generated in the presence of any - * user-defined constructor, but we want the default constructor. - */ - Allocator() = default; + /*! \brief Constructor + * + * No constructor can be auto-generated in the presence of any + * user-defined constructor, but we want the default constructor. + */ + Allocator() = default; - /*! \brief Constructor to accept an AllocationPolicy. - * - * This is useful for AllocationPolicies with state. - */ - Allocator(const AllocationPolicy &p) : AllocationPolicy(p) {} + /*! \brief Constructor to accept an AllocationPolicy. + * + * This is useful for AllocationPolicies with state. + */ + Allocator(const AllocationPolicy& p) : AllocationPolicy(p) {} - /*! \brief Do the actual memory allocation - * - * \param n Number of elements of type T to allocate. n can be - * 0 bytes, which will return a non-null properly aligned - * and padded pointer that should not be used. - * \param hint Optional value returned from previous call to allocate. - * For now this is not used. - * \return Pointer to allocated memory - * - * \throws std::bad_alloc if the allocation fails. - */ - value_type* - allocate(std::size_t n, typename std::allocator::const_pointer gmx_unused hint = nullptr) - { - void *p = AllocationPolicy::malloc(n*sizeof(T)); + /*! \brief Do the actual memory allocation + * + * \param n Number of elements of type T to allocate. n can be + * 0 bytes, which will return a non-null properly aligned + * and padded pointer that should not be used. + * \param hint Optional value returned from previous call to allocate. + * For now this is not used. + * \return Pointer to allocated memory + * + * \throws std::bad_alloc if the allocation fails. + */ + value_type* allocate(std::size_t n, typename std::allocator::const_pointer gmx_unused hint = nullptr) + { + void* p = AllocationPolicy::malloc(n * sizeof(T)); - if (p == nullptr) - { - throw std::bad_alloc(); - } - else - { - return static_cast(p); - } + if (p == nullptr) + { + throw std::bad_alloc(); } - - /*! \brief Release memory - * - * \param p Pointer to previously allocated memory returned from allocate() - * \param n number of objects previously passed to allocate() - */ - void - deallocate(value_type* p, std::size_t gmx_unused n) + else { - AllocationPolicy::free(p); + return static_cast(p); } + } + + /*! \brief Release memory + * + * \param p Pointer to previously allocated memory returned from allocate() + * \param n number of objects previously passed to allocate() + */ + void deallocate(value_type* p, std::size_t gmx_unused n) { AllocationPolicy::free(p); } - /*! \brief Return true if two allocators are identical - * - * This is a member function of the left-hand-side allocator. - * Always true for stateless polcies. Has to be defined in the policy for stateful policies. - * FUTURE: Can be removed with C++17 (is_always_equal) - */ - template::value> > - bool operator==(const Allocator & /*unused*/) const { return true; } + /*! \brief Return true if two allocators are identical + * + * This is a member function of the left-hand-side allocator. + * Always true for stateless polcies. Has to be defined in the policy for stateful policies. + * FUTURE: Can be removed with C++17 (is_always_equal) + */ + template::value>> + bool operator==(const Allocator& /*unused*/) const + { + return true; + } - /*! \brief Return true if two allocators are different - * - * \param rhs Other allocator. - * - * This is a member function of the left-hand-side allocator. - */ - template - bool operator!=(const Allocator &rhs) const { return !(*this == rhs); } + /*! \brief Return true if two allocators are different + * + * \param rhs Other allocator. + * + * This is a member function of the left-hand-side allocator. + */ + template + bool operator!=(const Allocator& rhs) const + { + return !(*this == rhs); + } }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/utility/any.cpp b/src/gromacs/utility/any.cpp index 39b82eaa3f..19f26cb11c 100644 --- a/src/gromacs/utility/any.cpp +++ b/src/gromacs/utility/any.cpp @@ -52,7 +52,7 @@ namespace gmx { //! \cond libapi -std::string simpleValueToString(const Any &value) +std::string simpleValueToString(const Any& value) { if (value.isType()) { diff --git a/src/gromacs/utility/any.h b/src/gromacs/utility/any.h index 30e4a732f3..7e2c86f441 100644 --- a/src/gromacs/utility/any.h +++ b/src/gromacs/utility/any.h @@ -77,166 +77,173 @@ namespace gmx */ class Any { - public: - /*! \brief - * Creates a any that holds the given value. - * - * \throws std::bad_alloc if out of memory. - * - * This method allows explicitly specifying the template argument, - * contrary to the templated constructor. - */ - template - static Any create(const T &value) { return Any(value); } - /*! \brief - * Creates a any that holds the given value. - * - * \throws std::bad_alloc if out of memory. - * - * In addition to allowing specifying the template argument, this - * method avoids copying when move-construction is possible. - */ - template - static Any create(T &&value) { return Any(std::forward(value)); } +public: + /*! \brief + * Creates a any that holds the given value. + * + * \throws std::bad_alloc if out of memory. + * + * This method allows explicitly specifying the template argument, + * contrary to the templated constructor. + */ + template + static Any create(const T& value) + { + return Any(value); + } + /*! \brief + * Creates a any that holds the given value. + * + * \throws std::bad_alloc if out of memory. + * + * In addition to allowing specifying the template argument, this + * method avoids copying when move-construction is possible. + */ + template + static Any create(T&& value) + { + return Any(std::forward(value)); + } - //! Creates an empty any value. - Any() {} - /*! \brief - * Creates a any that holds the given value. - * - * \throws std::bad_alloc if out of memory. - */ - template ::value> > - explicit Any(T &&value) - : content_(new Content < std::decay_t < T>>(std::forward(value))) - { - } - /*! \brief - * Creates a deep copy of a any. - * - * \throws std::bad_alloc if out of memory. - */ - Any(const Any &other) : content_(other.cloneContent()) {} - //! Move-constructs a any. - Any(Any &&other) noexcept : content_(std::move(other.content_)) {} - /*! \brief - * Assigns the any. - * - * \throws std::bad_alloc if out of memory. - */ - Any &operator=(const Any &other) - { - content_ = other.cloneContent(); - return *this; - } - //! Move-assigns the any. - Any &operator=(Any &&other) noexcept - { - content_ = std::move(other.content_); - return *this; - } + //! Creates an empty any value. + Any() {} + /*! \brief + * Creates a any that holds the given value. + * + * \throws std::bad_alloc if out of memory. + */ + template::value>> + explicit Any(T&& value) : content_(new Content>(std::forward(value))) + { + } + /*! \brief + * Creates a deep copy of a any. + * + * \throws std::bad_alloc if out of memory. + */ + Any(const Any& other) : content_(other.cloneContent()) {} + //! Move-constructs a any. + Any(Any&& other) noexcept : content_(std::move(other.content_)) {} + /*! \brief + * Assigns the any. + * + * \throws std::bad_alloc if out of memory. + */ + Any& operator=(const Any& other) + { + content_ = other.cloneContent(); + return *this; + } + //! Move-assigns the any. + Any& operator=(Any&& other) noexcept + { + content_ = std::move(other.content_); + return *this; + } - //! Whether any value is stored. - bool isEmpty() const { return content_ == nullptr; } - //! Returns the dynamic type of the value that is currently stored. - std::type_index type() const - { - const std::type_info &info - = !isEmpty() ? content_->typeInfo() : typeid(void); - return std::type_index(info); - } - //! Returns whether the type stored matches the template parameter. - template - bool isType() const - { - return !isEmpty() && content_->typeInfo() == typeid(T); - } + //! Whether any value is stored. + bool isEmpty() const { return content_ == nullptr; } + //! Returns the dynamic type of the value that is currently stored. + std::type_index type() const + { + const std::type_info& info = !isEmpty() ? content_->typeInfo() : typeid(void); + return std::type_index(info); + } + //! Returns whether the type stored matches the template parameter. + template + bool isType() const + { + return !isEmpty() && content_->typeInfo() == typeid(T); + } - /*! \brief - * Tries to get the value as the given type. - * - * \tparam T Type to get. - * \returns Pointer to the value, or nullptr if the type does not match - * the stored value. - */ - template - const T *tryCast() const - { - return isType() ? &static_cast *>(content_.get())->value_ : nullptr; - } - /*! \brief - * Gets the value when the type is known. - * - * \tparam T Type to get (which must match what the any stores). - * - * Asserts if the any is empty or does not contain the requested type. - */ - template - const T &cast() const - { - const T *value = tryCast(); - GMX_RELEASE_ASSERT(value != nullptr, "Cast to incorrect type"); - return *value; - } - /*! \brief - * Tries to get the value as the given type as a non-const pointer. - * - * \tparam T Type to get. - * \returns Pointer to the value, or nullptr if the type does not match - * the stored value. - * - * This method allows modifying the value in-place, which is useful - * with more complicated data structures. - */ - template - T *tryCastRef() - { - return isType() ? &static_cast *>(content_.get())->value_ : nullptr; - } - /*! \brief - * Gets the value when the type is known as a modifiable reference. - * - * \tparam T Type to get (which must match what the any stores). - * - * Asserts if the any is empty or does not contain the requested type. - */ - template - T &castRef() - { - T *value = tryCastRef(); - GMX_RELEASE_ASSERT(value != nullptr, "Cast to incorrect type"); - return *value; - } - - private: - class IContent - { - public: - virtual ~IContent() {} - virtual const std::type_info &typeInfo() const = 0; - virtual std::unique_ptr clone() const = 0; - }; + /*! \brief + * Tries to get the value as the given type. + * + * \tparam T Type to get. + * \returns Pointer to the value, or nullptr if the type does not match + * the stored value. + */ + template + const T* tryCast() const + { + return isType() ? &static_cast*>(content_.get())->value_ : nullptr; + } + /*! \brief + * Gets the value when the type is known. + * + * \tparam T Type to get (which must match what the any stores). + * + * Asserts if the any is empty or does not contain the requested type. + */ + template + const T& cast() const + { + const T* value = tryCast(); + GMX_RELEASE_ASSERT(value != nullptr, "Cast to incorrect type"); + return *value; + } + /*! \brief + * Tries to get the value as the given type as a non-const pointer. + * + * \tparam T Type to get. + * \returns Pointer to the value, or nullptr if the type does not match + * the stored value. + * + * This method allows modifying the value in-place, which is useful + * with more complicated data structures. + */ + template + T* tryCastRef() + { + return isType() ? &static_cast*>(content_.get())->value_ : nullptr; + } + /*! \brief + * Gets the value when the type is known as a modifiable reference. + * + * \tparam T Type to get (which must match what the any stores). + * + * Asserts if the any is empty or does not contain the requested type. + */ + template + T& castRef() + { + T* value = tryCastRef(); + GMX_RELEASE_ASSERT(value != nullptr, "Cast to incorrect type"); + return *value; + } - template - class Content : public IContent - { - public: - explicit Content(const T &value) : value_(value) {} - explicit Content(T &&value) : value_(std::move(value)) {} - - const std::type_info &typeInfo() const override { return typeid(T); } - std::unique_ptr clone() const override { return std::make_unique(value_); } +private: + class IContent + { + public: + virtual ~IContent() {} + virtual const std::type_info& typeInfo() const = 0; + virtual std::unique_ptr clone() const = 0; + }; - T value_; - }; + template + class Content : public IContent + { + public: + explicit Content(const T& value) : value_(value) {} + explicit Content(T&& value) : value_(std::move(value)) {} - //! Creates a deep copy of the content. - std::unique_ptr cloneContent() const + const std::type_info& typeInfo() const override { return typeid(T); } + std::unique_ptr clone() const override { - return content_ != nullptr ? content_->clone() : nullptr; + return std::make_unique(value_); } - std::unique_ptr content_; + T value_; + }; + + //! Creates a deep copy of the content. + std::unique_ptr cloneContent() const + { + return content_ != nullptr ? content_->clone() : nullptr; + } + + std::unique_ptr content_; }; //! \cond libapi @@ -248,7 +255,7 @@ class Any * * \ingroup module_utility */ -std::string simpleValueToString(const Any &value); +std::string simpleValueToString(const Any& value); //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/arrayref.h b/src/gromacs/utility/arrayref.h index ac7a8a0c7d..e8d242a168 100644 --- a/src/gromacs/utility/arrayref.h +++ b/src/gromacs/utility/arrayref.h @@ -99,172 +99,169 @@ namespace gmx * \inpublicapi * \ingroup module_utility */ -template +template class ArrayRef { - public: - //! Type of values stored in the reference. - typedef T value_type; - //! Type for representing size of the reference. - typedef size_t size_type; - //! Type for representing difference between two indices. - typedef ptrdiff_t difference_type; - //! Const reference to an element. - typedef const T &const_reference; - //! Const pointer to an element. - typedef const T *const_pointer; - //! Const iterator type to an element. - typedef const T *const_iterator; - //! Reference to an element. - typedef T &reference; - //! Pointer to an element. - typedef T *pointer; - //! Iterator type to an element. - typedef T *iterator; - //! Standard reverse iterator. - typedef std::reverse_iterator reverse_iterator; - //! Standard reverse iterator. - typedef std::reverse_iterator const_reverse_iterator; +public: + //! Type of values stored in the reference. + typedef T value_type; + //! Type for representing size of the reference. + typedef size_t size_type; + //! Type for representing difference between two indices. + typedef ptrdiff_t difference_type; + //! Const reference to an element. + typedef const T& const_reference; + //! Const pointer to an element. + typedef const T* const_pointer; + //! Const iterator type to an element. + typedef const T* const_iterator; + //! Reference to an element. + typedef T& reference; + //! Pointer to an element. + typedef T* pointer; + //! Iterator type to an element. + typedef T* iterator; + //! Standard reverse iterator. + typedef std::reverse_iterator reverse_iterator; + //! Standard reverse iterator. + typedef std::reverse_iterator const_reverse_iterator; - /*! \brief - * Constructs an empty reference. - */ - ArrayRef() : begin_(nullptr), end_(nullptr) {} - /*! \brief - * Constructs a reference to a container or reference - * - * \param[in] o container to reference. - * - * Can be used to create a reference to a whole vector, std::array or - * an ArrayRef. The destination has to have a convertible pointer type - * (identical besides const or base class). - * - * Passed container must remain valid and not be reallocated for the - * lifetime of this object. - * - * This constructor is not explicit to allow directly passing - * a container to a method that takes ArrayRef. - */ - template::pointer, - pointer>::value> > - ArrayRef(U &&o) : begin_(o.data()), end_(o.data()+o.size()) {} - /*! \brief - * Constructs a reference to a particular range. - * - * \param[in] begin Pointer to the beginning of a range. - * \param[in] end Pointer to the end of a range. - * - * Passed pointers must remain valid for the lifetime of this object. - */ - ArrayRef(pointer begin, pointer end) - : begin_(begin), end_(end) - { - GMX_ASSERT(end >= begin, "Invalid range"); - } - //! \cond - // Doxygen 1.8.5 doesn't parse the declaration correctly... - /*! \brief - * Constructs a reference to a C array. - * - * \param[in] array C array to reference. - * \tparam count Deduced number of elements in \p array. - * - * This constructor can only be used with a real array (not with a - * pointer). It constructs a reference to the whole array, without - * a need to pass the number of elements explicitly. The compiler - * must be able to deduce the array size. - * - * Passed array must remain valid for the lifetime of this object. - * - * This constructor is not explicit to allow directly passing - * a C array to a function that takes an ArrayRef parameter. - */ - template - ArrayRef(value_type (&array)[count]) - : begin_(array), end_(array + count) - { - } - //! \endcond + /*! \brief + * Constructs an empty reference. + */ + ArrayRef() : begin_(nullptr), end_(nullptr) {} + /*! \brief + * Constructs a reference to a container or reference + * + * \param[in] o container to reference. + * + * Can be used to create a reference to a whole vector, std::array or + * an ArrayRef. The destination has to have a convertible pointer type + * (identical besides const or base class). + * + * Passed container must remain valid and not be reallocated for the + * lifetime of this object. + * + * This constructor is not explicit to allow directly passing + * a container to a method that takes ArrayRef. + */ + template::pointer, pointer>::value>> + ArrayRef(U&& o) : begin_(o.data()), end_(o.data() + o.size()) + { + } + /*! \brief + * Constructs a reference to a particular range. + * + * \param[in] begin Pointer to the beginning of a range. + * \param[in] end Pointer to the end of a range. + * + * Passed pointers must remain valid for the lifetime of this object. + */ + ArrayRef(pointer begin, pointer end) : begin_(begin), end_(end) + { + GMX_ASSERT(end >= begin, "Invalid range"); + } + //! \cond + // Doxygen 1.8.5 doesn't parse the declaration correctly... + /*! \brief + * Constructs a reference to a C array. + * + * \param[in] array C array to reference. + * \tparam count Deduced number of elements in \p array. + * + * This constructor can only be used with a real array (not with a + * pointer). It constructs a reference to the whole array, without + * a need to pass the number of elements explicitly. The compiler + * must be able to deduce the array size. + * + * Passed array must remain valid for the lifetime of this object. + * + * This constructor is not explicit to allow directly passing + * a C array to a function that takes an ArrayRef parameter. + */ + template + ArrayRef(value_type (&array)[count]) : begin_(array), end_(array + count) + { + } + //! \endcond - //! Returns a reference to part of the memory. - ArrayRef subArray(size_type start, size_type count) const - { - return {begin_+start, begin_+start+count}; - } - //! Returns an iterator to the beginning of the reference. - iterator begin() const { return begin_; } - //! Returns an iterator to the end of the reference. - iterator end() const { return end_; } - //! Returns an iterator to the reverse beginning of the reference. - reverse_iterator rbegin() const { return reverse_iterator(end()); } - //! Returns an iterator to the reverse end of the reference. - reverse_iterator rend() const { return reverse_iterator(begin()); } + //! Returns a reference to part of the memory. + ArrayRef subArray(size_type start, size_type count) const + { + return { begin_ + start, begin_ + start + count }; + } + //! Returns an iterator to the beginning of the reference. + iterator begin() const { return begin_; } + //! Returns an iterator to the end of the reference. + iterator end() const { return end_; } + //! Returns an iterator to the reverse beginning of the reference. + reverse_iterator rbegin() const { return reverse_iterator(end()); } + //! Returns an iterator to the reverse end of the reference. + reverse_iterator rend() const { return reverse_iterator(begin()); } - /*! \brief Returns the size of the reference. - * - * \note Use ssize for any expression involving arithmetic operations - (including loop indices). - */ - size_type size() const { return end_ - begin_; } - //! Returns the signed size of the reference. - index ssize() const { return size(); } - //! Identical to size(). - size_type capacity() const { return end_ - begin_; } - //! Whether the reference refers to no memory. - bool empty() const { return begin_ == end_; } + /*! \brief Returns the size of the reference. + * + * \note Use ssize for any expression involving arithmetic operations + (including loop indices). + */ + size_type size() const { return end_ - begin_; } + //! Returns the signed size of the reference. + index ssize() const { return size(); } + //! Identical to size(). + size_type capacity() const { return end_ - begin_; } + //! Whether the reference refers to no memory. + bool empty() const { return begin_ == end_; } - //! Access an element. - reference operator[](size_type n) const { return begin_[n]; } - //! Access an element (throws on out-of-range error). - reference at(size_type n) const + //! Access an element. + reference operator[](size_type n) const { return begin_[n]; } + //! Access an element (throws on out-of-range error). + reference at(size_type n) const + { + if (n >= size()) { - if (n >= size()) - { - throw std::out_of_range("Vector index out of range"); - } - return begin_[n]; + throw std::out_of_range("Vector index out of range"); } - //! Returns the first element. - reference front() const { return *begin_; } - //! Returns the first element. - reference back() const { return *(end_ - 1); } + return begin_[n]; + } + //! Returns the first element. + reference front() const { return *begin_; } + //! Returns the first element. + reference back() const { return *(end_ - 1); } - //! Returns a raw pointer to the contents of the array. - pointer data() const { return begin_; } + //! Returns a raw pointer to the contents of the array. + pointer data() const { return begin_; } - /*! \brief - * Swaps referenced memory with the other object. - * - * The actual memory areas are not modified, only the references are - * swapped. - */ - void swap(ArrayRef &other) - { - std::swap(begin_, other.begin_); - std::swap(end_, other.end_); - } + /*! \brief + * Swaps referenced memory with the other object. + * + * The actual memory areas are not modified, only the references are + * swapped. + */ + void swap(ArrayRef& other) + { + std::swap(begin_, other.begin_); + std::swap(end_, other.end_); + } - private: - pointer begin_; - pointer end_; +private: + pointer begin_; + pointer end_; }; //! \copydoc ArrayRef::fromArray() //! \related ArrayRef -template -ArrayRef arrayRefFromArray(T *begin, size_t size) +template +ArrayRef arrayRefFromArray(T* begin, size_t size) { - return ArrayRef(begin, begin+size); + return ArrayRef(begin, begin + size); } //! \copydoc ArrayRef::fromArray() //! \related ArrayRef -template -ArrayRef constArrayRefFromArray(const T *begin, size_t size) +template +ArrayRef constArrayRefFromArray(const T* begin, size_t size) { - return ArrayRef(begin, begin+size); + return ArrayRef(begin, begin + size); } /*! \brief @@ -272,11 +269,9 @@ ArrayRef constArrayRefFromArray(const T *begin, size_t size) * * \see ArrayRef */ -template -ArrayRef < std::conditional_t < std::is_const::value, -const typename T::value_type, -typename T::value_type>> -makeArrayRef(T &c) +template +ArrayRef::value, const typename T::value_type, typename T::value_type>> +makeArrayRef(T& c) { return c; } @@ -286,8 +281,8 @@ makeArrayRef(T &c) * * \see ArrayRef */ -template -ArrayRef makeConstArrayRef(const T &c) +template +ArrayRef makeConstArrayRef(const T& c) { return c; } @@ -299,8 +294,8 @@ ArrayRef makeConstArrayRef(const T &c) * * \ingroup module_utility */ -template -void swap(ArrayRef &a, ArrayRef &b) +template +void swap(ArrayRef& a, ArrayRef& b) { a.swap(b); } @@ -315,8 +310,8 @@ void swap(ArrayRef &a, ArrayRef &b) * * \ingroup module_utility */ -template -std::vector copyOf(const ArrayRef &arrayRef) +template +std::vector copyOf(const ArrayRef& arrayRef) { return std::vector(arrayRef.begin(), arrayRef.end()); } diff --git a/src/gromacs/utility/arraysize.h b/src/gromacs/utility/arraysize.h index 6963fecd89..e7dcaa78b5 100644 --- a/src/gromacs/utility/arraysize.h +++ b/src/gromacs/utility/arraysize.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,8 +47,8 @@ * * \ingroup module_utility */ -template -constexpr int asize(T(&/*unused*/)[N]) +template +constexpr int asize(T (&/*unused*/)[N]) { static_assert(N >= 0, "Do negative size arrays exist?"); return N; diff --git a/src/gromacs/utility/basedefinitions.h b/src/gromacs/utility/basedefinitions.h index cb22dff80e..dd0bb86b00 100644 --- a/src/gromacs/utility/basedefinitions.h +++ b/src/gromacs/utility/basedefinitions.h @@ -54,11 +54,11 @@ typedef bool gmx_bool; #ifndef FALSE /** False value for ::gmx_bool. */ -# define FALSE false +# define FALSE false #endif #ifndef TRUE /** True value for ::gmx_bool. */ -# define TRUE true +# define TRUE true #endif /** Number of gmx_bool values. */ #define BOOL_NR 2 @@ -73,8 +73,11 @@ using index = std::ptrdiff_t; //! Return signed size of container template -index ssize(const T &t) { return t.size(); } -} // namespace gmx +index ssize(const T& t) +{ + return t.size(); +} +} // namespace gmx /* ICC, GCC, MSVC, Pathscale, PGI, XLC support __restrict. * Any other compiler can be added here. */ @@ -99,24 +102,24 @@ index ssize(const T &t) { return t.size(); } * (e.g. MPI). */ #ifndef gmx_unused -#ifdef __GNUC__ +# ifdef __GNUC__ /* GCC, clang, and some ICC pretending to be GCC */ -# define gmx_unused __attribute__ ((unused)) -#elif (defined(__INTEL_COMPILER) || defined(__ECC)) && !defined(_MSC_VER) +# define gmx_unused __attribute__((unused)) +# elif (defined(__INTEL_COMPILER) || defined(__ECC)) && !defined(_MSC_VER) /* ICC on *nix */ -# define gmx_unused __attribute__ ((unused)) -#elif defined(__PGI) +# define gmx_unused __attribute__((unused)) +# elif defined(__PGI) /* Portland group compilers */ -# define gmx_unused __attribute__ ((unused)) -#elif defined _MSC_VER +# define gmx_unused __attribute__((unused)) +# elif defined _MSC_VER /* MSVC */ -# define gmx_unused /*@unused@*/ -#elif defined(__xlC__) +# define gmx_unused /*@unused@*/ +# elif defined(__xlC__) /* IBM */ -# define gmx_unused __attribute__ ((unused)) -#else -# define gmx_unused -#endif +# define gmx_unused __attribute__((unused)) +# else +# define gmx_unused +# endif #endif /*! \brief Attribute to explicitly indicate that a parameter or @@ -125,14 +128,14 @@ index ssize(const T &t) { return t.size(); } * \ingroup module_utility */ #ifdef NDEBUG -#define gmx_used_in_debug gmx_unused +# define gmx_used_in_debug gmx_unused #else -#define gmx_used_in_debug +# define gmx_used_in_debug #endif #ifndef __has_feature /** For compatibility with non-clang compilers. */ -#define __has_feature(x) 0 +# define __has_feature(x) 0 #endif /*! \brief @@ -145,15 +148,15 @@ index ssize(const T &t) { return t.size(); } #define GMX_UNUSED_VALUE(value) (void)value #ifdef __clang__ -#define DO_PRAGMA(x) _Pragma (#x) -#define CLANG_DIAGNOSTIC_IGNORE(warning) _Pragma("clang diagnostic push") \ - DO_PRAGMA(clang diagnostic ignored #warning) -#define DIAGNOSTIC_RESET _Pragma("clang diagnostic pop") +# define DO_PRAGMA(x) _Pragma(# x) +# define CLANG_DIAGNOSTIC_IGNORE(warning) \ + _Pragma("clang diagnostic push") DO_PRAGMA(clang diagnostic ignored #warning) +# define DIAGNOSTIC_RESET _Pragma("clang diagnostic pop") #else //! Ignore specified clang warning until DIAGNOSTIC_RESET -#define CLANG_DIAGNOSTIC_IGNORE(warning) +# define CLANG_DIAGNOSTIC_IGNORE(warning) //! Reset all diagnostics to default -#define DIAGNOSTIC_RESET +# define DIAGNOSTIC_RESET #endif namespace gmx @@ -166,13 +169,13 @@ namespace internal * * \ingroup module_utility */ -template -static inline void ignoreValueHelper(const T & /*unused*/) +template +static inline void ignoreValueHelper(const T& /*unused*/) { } //! \endcond -} // namespace internal -} // namespace gmx +} // namespace internal +} // namespace gmx /*! \brief * Macro to explicitly ignore a return value of a call. @@ -187,7 +190,6 @@ static inline void ignoreValueHelper(const T & /*unused*/) * * \ingroup module_utility */ -#define GMX_IGNORE_RETURN_VALUE(call) \ - ::gmx::internal::ignoreValueHelper(call) +#define GMX_IGNORE_RETURN_VALUE(call) ::gmx::internal::ignoreValueHelper(call) #endif diff --git a/src/gromacs/utility/basenetwork.cpp b/src/gromacs/utility/basenetwork.cpp index b6e905a60a..5bb5a90158 100644 --- a/src/gromacs/utility/basenetwork.cpp +++ b/src/gromacs/utility/basenetwork.cpp @@ -66,14 +66,14 @@ int gmx_node_num() #if !GMX_MPI return 1; #else -#if GMX_THREAD_MPI +# if GMX_THREAD_MPI if (!gmx_mpi_initialized()) { return 1; } -#endif +# endif int i; - (void) MPI_Comm_size(MPI_COMM_WORLD, &i); + (void)MPI_Comm_size(MPI_COMM_WORLD, &i); return i; #endif } @@ -83,14 +83,14 @@ int gmx_node_rank() #if !GMX_MPI return 0; #else -#if GMX_THREAD_MPI +# if GMX_THREAD_MPI if (!gmx_mpi_initialized()) { return 0; } -#endif +# endif int i; - (void) MPI_Comm_rank(MPI_COMM_WORLD, &i); + (void)MPI_Comm_rank(MPI_COMM_WORLD, &i); return i; #endif } @@ -149,7 +149,7 @@ int gmx_physicalnode_id_hash() return hash; } -void gmx_broadcast_world(int size, void *buffer) +void gmx_broadcast_world(int size, void* buffer) { #if GMX_MPI MPI_Bcast(buffer, size, MPI_BYTE, 0, MPI_COMM_WORLD); diff --git a/src/gromacs/utility/basenetwork.h b/src/gromacs/utility/basenetwork.h index 70793c1c38..b1fa3833a1 100644 --- a/src/gromacs/utility/basenetwork.h +++ b/src/gromacs/utility/basenetwork.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -90,7 +90,7 @@ int gmx_physicalnode_id_hash(); /*! \brief * Broadcasts given data from rank zero to all other ranks. */ -void gmx_broadcast_world(int size, void *buffer); +void gmx_broadcast_world(int size, void* buffer); /** Abort the parallel run */ [[noreturn]] void gmx_abort(int errorno); diff --git a/src/gromacs/utility/baseversion.cpp b/src/gromacs/utility/baseversion.cpp index 23daa6d9a7..90828c3208 100644 --- a/src/gromacs/utility/baseversion.cpp +++ b/src/gromacs/utility/baseversion.cpp @@ -40,51 +40,47 @@ #include "baseversion_gen.h" -const char *gmx_version() +const char* gmx_version() { return _gmx_ver_string; } -const char *gmx_version_git_full_hash() +const char* gmx_version_git_full_hash() { return _gmx_full_git_hash; } -const char *gmx_version_git_central_base_hash() +const char* gmx_version_git_central_base_hash() { return _gmx_central_base_hash; } -const char *gmxDOI() +const char* gmxDOI() { return gmxSourceDoiString; } -const char *gmxReleaseSourceChecksum() +const char* gmxReleaseSourceChecksum() { return gmxReleaseSourceFileChecksum; } -const char *gmxCurrentSourceChecksum() +const char* gmxCurrentSourceChecksum() { return gmxCurrentSourceFileChecksum; } #if GMX_DOUBLE -void gmx_is_double_precision() -{ -} +void gmx_is_double_precision() {} #else -void gmx_is_single_precision() -{ -} +void gmx_is_single_precision() {} #endif /* Note that this array (and some which follow) must match the "GPU * support enumeration" in src/config.h.cmakein */ -static const char * const gpuImplementationStrings[] = { "disabled", "CUDA", "OpenCL" }; +static const char* const gpuImplementationStrings[] = { "disabled", "CUDA", "OpenCL" }; -const char *getGpuImplementationString() +const char* getGpuImplementationString() { return gpuImplementationStrings[GMX_GPU]; } diff --git a/src/gromacs/utility/baseversion.h b/src/gromacs/utility/baseversion.h index 7a1ef6f84a..cf54a4ff69 100644 --- a/src/gromacs/utility/baseversion.h +++ b/src/gromacs/utility/baseversion.h @@ -53,7 +53,7 @@ * * \ingroup module_utility */ -const char *gmx_version(); +const char* gmx_version(); /*! \brief * Full git hash of the latest commit. * @@ -61,7 +61,7 @@ const char *gmx_version(); * * \ingroup module_utility */ -const char *gmx_version_git_full_hash(); +const char* gmx_version_git_full_hash(); /*! \brief * Full git hash of the latest commit in a central \Gromacs repository. * @@ -71,7 +71,7 @@ const char *gmx_version_git_full_hash(); * * \ingroup module_utility */ -const char *gmx_version_git_central_base_hash(); +const char* gmx_version_git_central_base_hash(); /*! \brief * Defined if ``libgromacs`` has been compiled in double precision. @@ -94,25 +94,25 @@ void gmx_is_double_precision(); void gmx_is_single_precision(); /*! \brief Return a string describing what kind of GPU suport was configured in the build. */ -const char *getGpuImplementationString(); +const char* getGpuImplementationString(); /*! \brief * DOI string, or empty when not a release build. */ -const char *gmxDOI(); +const char* gmxDOI(); /*! \brief * Hash of the complete source released in the tarball. * * Empty when not a release tarball build. */ -const char *gmxReleaseSourceChecksum(); +const char* gmxReleaseSourceChecksum(); /*! \brief * Hash of the complete source actually used when building. * * Always computed when building from tarball. */ -const char *gmxCurrentSourceChecksum(); +const char* gmxCurrentSourceChecksum(); #endif diff --git a/src/gromacs/utility/binaryinformation.cpp b/src/gromacs/utility/binaryinformation.cpp index 47798cd9e2..d824fc4c35 100644 --- a/src/gromacs/utility/binaryinformation.cpp +++ b/src/gromacs/utility/binaryinformation.cpp @@ -48,19 +48,19 @@ #if GMX_FFT_FFTW3 || GMX_FFT_ARMPL_FFTW3 // Needed for construction of the FFT library description string -#include +# include #endif #ifdef HAVE_LIBMKL -#include +# include #endif #if HAVE_EXTRAE -#include +# include #endif #if GMX_USE_HWLOC -#include +# include #endif #include @@ -98,64 +98,31 @@ int centeringOffset(int width, int length) return std::max(width - length, 0) / 2; } -std::string formatCentered(int width, const char *text) +std::string formatCentered(int width, const char* text) { const int offset = centeringOffset(width, std::strlen(text)); return formatString("%*s%s", offset, "", text); } -void printCopyright(gmx::TextWriter *writer) +void printCopyright(gmx::TextWriter* writer) { - static const char * const Contributors[] = { - "Emile Apol", - "Rossen Apostolov", - "Paul Bauer", - "Herman J.C. Berendsen", - "Par Bjelkmar", - "Christian Blau", - "Viacheslav Bolnykh", - "Kevin Boyd", - "Aldert van Buuren", - "Rudi van Drunen", - "Anton Feenstra", - "Alan Gray", - "Gerrit Groenhof", - "Anca Hamuraru", - "Vincent Hindriksen", - "M. Eric Irrgang", - "Aleksei Iupinov", - "Christoph Junghans", - "Joe Jordan", - "Dimitrios Karkoulis", - "Peter Kasson", - "Jiri Kraus", - "Carsten Kutzner", - "Per Larsson", - "Justin A. Lemkul", - "Viveca Lindahl", - "Magnus Lundborg", - "Erik Marklund", - "Pascal Merz", - "Pieter Meulenhoff", - "Teemu Murtola", - "Szilard Pall", - "Sander Pronk", - "Roland Schulz", - "Michael Shirts", - "Alexey Shvetsov", - "Alfons Sijbers", - "Peter Tieleman", - "Jon Vincent", - "Teemu Virolainen", - "Christian Wennberg", - "Maarten Wolf", - "Artem Zhmurov" + static const char* const Contributors[] = { + "Emile Apol", "Rossen Apostolov", "Paul Bauer", "Herman J.C. Berendsen", + "Par Bjelkmar", "Christian Blau", "Viacheslav Bolnykh", "Kevin Boyd", + "Aldert van Buuren", "Rudi van Drunen", "Anton Feenstra", "Alan Gray", + "Gerrit Groenhof", "Anca Hamuraru", "Vincent Hindriksen", "M. Eric Irrgang", + "Aleksei Iupinov", "Christoph Junghans", "Joe Jordan", "Dimitrios Karkoulis", + "Peter Kasson", "Jiri Kraus", "Carsten Kutzner", "Per Larsson", + "Justin A. Lemkul", "Viveca Lindahl", "Magnus Lundborg", "Erik Marklund", + "Pascal Merz", "Pieter Meulenhoff", "Teemu Murtola", "Szilard Pall", + "Sander Pronk", "Roland Schulz", "Michael Shirts", "Alexey Shvetsov", + "Alfons Sijbers", "Peter Tieleman", "Jon Vincent", "Teemu Virolainen", + "Christian Wennberg", "Maarten Wolf", "Artem Zhmurov" }; - static const char * const CopyrightText[] = { + static const char* const CopyrightText[] = { "Copyright (c) 1991-2000, University of Groningen, The Netherlands.", "Copyright (c) 2001-2019, The GROMACS development team at", - "Uppsala University, Stockholm University and", - "the Royal Institute of Technology, Sweden.", + "Uppsala University, Stockholm University and", "the Royal Institute of Technology, Sweden.", "check out http://www.gromacs.org for more information." }; @@ -164,7 +131,7 @@ void printCopyright(gmx::TextWriter *writer) // TODO a centering behaviour of TextWriter could be useful here writer->writeLine(formatCentered(78, "GROMACS is written by:")); - for (int i = 0; i < NCONTRIBUTORS; ) + for (int i = 0; i < NCONTRIBUTORS;) { for (int j = 0; j < 4 && i < NCONTRIBUTORS; ++j, ++i) { @@ -173,14 +140,15 @@ void printCopyright(gmx::TextWriter *writer) const int offset = centeringOffset(width, strlen(Contributors[i])); GMX_RELEASE_ASSERT(static_cast(strlen(Contributors[i])) + offset < gmx::ssize(buf), "Formatting buffer is not long enough"); - std::fill(buf.begin(), buf.begin()+offset, ' '); - std::strncpy(buf.data()+offset, Contributors[i], gmx::ssize(buf) - offset); + std::fill(buf.begin(), buf.begin() + offset, ' '); + std::strncpy(buf.data() + offset, Contributors[i], gmx::ssize(buf) - offset); writer->writeString(formatString(" %-*s", width, buf.data())); } writer->ensureLineBreak(); } writer->writeLine(formatCentered(78, "and the project leaders:")); - writer->writeLine(formatCentered(78, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel")); + writer->writeLine( + formatCentered(78, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel")); writer->ensureEmptyLine(); for (int i = 0; i < NCR; ++i) { @@ -201,21 +169,21 @@ void printCopyright(gmx::TextWriter *writer) } // Construct a string that describes the library that provides FFT support to this build -const char *getFftDescriptionString() +const char* getFftDescriptionString() { // Define the FFT description string #if GMX_FFT_FFTW3 || GMX_FFT_ARMPL_FFTW3 -# if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS // Don't buy trouble return "fftw3"; -# else +# else // Use the version string provided by libfftw3 -# if GMX_DOUBLE +# if GMX_DOUBLE return fftw_version; -# else +# else return fftwf_version; +# endif # endif -# endif #endif #if GMX_FFT_MKL return "Intel MKL"; @@ -225,36 +193,50 @@ const char *getFftDescriptionString() #endif }; -void gmx_print_version_info(gmx::TextWriter *writer) +void gmx_print_version_info(gmx::TextWriter* writer) { writer->writeLine(formatString("GROMACS version: %s", gmx_version())); - const char *const git_hash = gmx_version_git_full_hash(); + const char* const git_hash = gmx_version_git_full_hash(); if (git_hash[0] != '\0') { writer->writeLine(formatString("GIT SHA1 hash: %s", git_hash)); } - const char *const base_hash = gmx_version_git_central_base_hash(); + const char* const base_hash = gmx_version_git_central_base_hash(); if (base_hash[0] != '\0') { writer->writeLine(formatString("Branched from: %s", base_hash)); } - const char *const releaseSourceChecksum = gmxReleaseSourceChecksum(); - const char *const currentSourceChecksum = gmxCurrentSourceChecksum(); + const char* const releaseSourceChecksum = gmxReleaseSourceChecksum(); + const char* const currentSourceChecksum = gmxCurrentSourceChecksum(); if (releaseSourceChecksum[0] != '\0') { if (std::strcmp(releaseSourceChecksum, "NoChecksumFile") == 0) { - writer->writeLine(formatString("The source code this program was compiled from has not been verified because the reference checksum was missing during compilation. This means you have an incomplete GROMACS distribution, please make sure to download an intact source distribution and compile that before proceeding.")); + writer->writeLine(formatString( + "The source code this program was compiled from has not been verified because " + "the reference checksum was missing during compilation. This means you have an " + "incomplete GROMACS distribution, please make sure to download an intact " + "source distribution and compile that before proceeding.")); writer->writeLine(formatString("Computed checksum: %s", currentSourceChecksum)); } else if (std::strcmp(releaseSourceChecksum, "NoPythonAvailable") == 0) { - writer->writeLine(formatString("Build source could not be verified, because the checksum could not be computed.")); + writer->writeLine( + formatString("Build source could not be verified, because the checksum could " + "not be computed.")); } else if (std::strcmp(releaseSourceChecksum, currentSourceChecksum) != 0) { - writer->writeLine(formatString("This program has been built from source code that has been altered and does not match the code released as part of the official GROMACS version %s. If you did not intend to use an altered GROMACS version, make sure to download an intact source distribution and compile that before proceeding.", gmx_version())); - writer->writeLine(formatString("If you have modified the source code, you are strongly encouraged to set your custom version suffix (using -DGMX_VERSION_STRING_OF_FORK) which will can help later with scientific reproducibility but also when reporting bugs.")); + writer->writeLine(formatString( + "This program has been built from source code that has been altered and does " + "not match the code released as part of the official GROMACS version %s. If " + "you did not intend to use an altered GROMACS version, make sure to download " + "an intact source distribution and compile that before proceeding.", + gmx_version())); + writer->writeLine(formatString( + "If you have modified the source code, you are strongly encouraged to set your " + "custom version suffix (using -DGMX_VERSION_STRING_OF_FORK) which will can " + "help later with scientific reproducibility but also when reporting bugs.")); writer->writeLine(formatString("Release checksum: %s", releaseSourceChecksum)); writer->writeLine(formatString("Computed checksum: %s", currentSourceChecksum)); } @@ -270,7 +252,7 @@ void gmx_print_version_info(gmx::TextWriter *writer) #else writer->writeLine("Precision: single"); #endif - writer->writeLine(formatString("Memory model: %u bit", static_cast(8*sizeof(void *)))); + writer->writeLine(formatString("Memory model: %u bit", static_cast(8 * sizeof(void*)))); #if GMX_THREAD_MPI writer->writeLine("MPI library: thread_mpi"); @@ -280,7 +262,8 @@ void gmx_print_version_info(gmx::TextWriter *writer) writer->writeLine("MPI library: none"); #endif #if GMX_OPENMP - writer->writeLine(formatString("OpenMP support: enabled (GMX_OPENMP_MAX_THREADS = %d)", GMX_OPENMP_MAX_THREADS)); + writer->writeLine(formatString("OpenMP support: enabled (GMX_OPENMP_MAX_THREADS = %d)", + GMX_OPENMP_MAX_THREADS)); #else writer->writeLine("OpenMP support: disabled"); #endif @@ -301,7 +284,8 @@ void gmx_print_version_info(gmx::TextWriter *writer) #if HAVE_EXTRAE unsigned major, minor, revision; Extrae_get_version(&major, &minor, &revision); - writer->writeLine(formatString("Tracing support: enabled. Using Extrae-%d.%d.%d", major, minor, revision)); + writer->writeLine(formatString("Tracing support: enabled. Using Extrae-%d.%d.%d", major, + minor, revision)); #else writer->writeLine("Tracing support: disabled"); #endif @@ -316,8 +300,8 @@ void gmx_print_version_info(gmx::TextWriter *writer) writer->writeLine(formatString("C++ compiler flags: %s", BUILD_CXXFLAGS)); #ifdef HAVE_LIBMKL /* MKL might be used for LAPACK/BLAS even if FFTs use FFTW, so keep it separate */ - writer->writeLine(formatString("Linked with Intel MKL version %d.%d.%d.", - __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__)); + writer->writeLine(formatString("Linked with Intel MKL version %d.%d.%d.", __INTEL_MKL__, + __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__)); #endif #if GMX_GPU == GMX_GPU_OPENCL writer->writeLine(formatString("OpenCL include dir: %s", OPENCL_INCLUDE_DIR)); @@ -339,45 +323,47 @@ void gmx_print_version_info(gmx::TextWriter *writer) namespace gmx { -BinaryInformationSettings::BinaryInformationSettings() - : bExtendedInfo_(false), bCopyright_(false), - bProcessId_(false), - bGeneratedByHeader_(false), prefix_(""), suffix_("") +BinaryInformationSettings::BinaryInformationSettings() : + bExtendedInfo_(false), + bCopyright_(false), + bProcessId_(false), + bGeneratedByHeader_(false), + prefix_(""), + suffix_("") { } -void printBinaryInformation(FILE *fp, - const IProgramContext &programContext) +void printBinaryInformation(FILE* fp, const IProgramContext& programContext) { TextWriter writer(fp); printBinaryInformation(&writer, programContext, BinaryInformationSettings()); } -void printBinaryInformation(FILE *fp, - const IProgramContext &programContext, - const BinaryInformationSettings &settings) +void printBinaryInformation(FILE* fp, + const IProgramContext& programContext, + const BinaryInformationSettings& settings) { try { TextWriter writer(fp); printBinaryInformation(&writer, programContext, settings); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR } -void printBinaryInformation(TextWriter *writer, - const IProgramContext &programContext, - const BinaryInformationSettings &settings) +void printBinaryInformation(TextWriter* writer, + const IProgramContext& programContext, + const BinaryInformationSettings& settings) { // TODO Perhaps the writer could be configured with the prefix and // suffix strings from the settings? - const char *prefix = settings.prefix_; - const char *suffix = settings.suffix_; - const char *precisionString = ""; + const char* prefix = settings.prefix_; + const char* suffix = settings.suffix_; + const char* precisionString = ""; #if GMX_DOUBLE precisionString = " (double precision)"; #endif - const char *const name = programContext.displayName(); + const char* const name = programContext.displayName(); if (settings.bGeneratedByHeader_) { writer->writeLine(formatString("%sCreated by:%s", prefix, suffix)); @@ -385,10 +371,9 @@ void printBinaryInformation(TextWriter *writer, // TODO: It would be nice to know here whether we are really running a // Gromacs binary or some other binary that is calling Gromacs; we // could then print "%s is part of GROMACS" or some alternative text. - std::string title - = formatString(":-) GROMACS - %s, %s%s (-:", name, gmx_version(), precisionString); - const int indent - = centeringOffset(78 - std::strlen(prefix) - std::strlen(suffix), title.length()) + 1; + std::string title = formatString(":-) GROMACS - %s, %s%s (-:", name, gmx_version(), precisionString); + const int indent = + centeringOffset(78 - std::strlen(prefix) - std::strlen(suffix), title.length()) + 1; writer->writeLine(formatString("%s%*c%s%s", prefix, indent, ' ', title.c_str(), suffix)); writer->writeLine(formatString("%s%s", prefix, suffix)); if (settings.bCopyright_) @@ -405,7 +390,7 @@ void printBinaryInformation(TextWriter *writer, writer->writeLine(formatString("%sGROMACS: %s, version %s%s%s", prefix, name, gmx_version(), precisionString, suffix)); } - const char *const binaryPath = programContext.fullBinaryPath(); + const char* const binaryPath = programContext.fullBinaryPath(); if (!gmx::isNullOrEmpty(binaryPath)) { writer->writeLine(formatString("%sExecutable: %s%s", prefix, binaryPath, suffix)); @@ -425,11 +410,11 @@ void printBinaryInformation(TextWriter *writer, { writer->writeLine(formatString("%sProcess ID: %d%s", prefix, gmx_getpid(), suffix)); } - const char *const commandLine = programContext.commandLine(); + const char* const commandLine = programContext.commandLine(); if (!gmx::isNullOrEmpty(commandLine)) { - writer->writeLine(formatString("%sCommand line:%s\n%s %s%s", - prefix, suffix, prefix, commandLine, suffix)); + writer->writeLine(formatString("%sCommand line:%s\n%s %s%s", prefix, suffix, prefix, + commandLine, suffix)); } if (settings.bExtendedInfo_) { diff --git a/src/gromacs/utility/binaryinformation.h b/src/gromacs/utility/binaryinformation.h index ba4c809b15..9542305898 100644 --- a/src/gromacs/utility/binaryinformation.h +++ b/src/gromacs/utility/binaryinformation.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,59 +61,58 @@ class TextWriter; */ class BinaryInformationSettings { - public: - BinaryInformationSettings(); +public: + BinaryInformationSettings(); - //! Set whether to print information about build settings. - BinaryInformationSettings &extendedInfo(bool bEnabled) - { - bExtendedInfo_ = bEnabled; - return *this; - } - //! Set whether to print copyright and license information. - BinaryInformationSettings ©right(bool bEnabled) - { - bCopyright_ = bEnabled; - return *this; - } - //! Set whether to print the process ID. - BinaryInformationSettings &processId(bool bEnabled) - { - bProcessId_ = bEnabled; - return *this; - } - //! Set whether to print a header line with "Generated by" text (for output files). - BinaryInformationSettings &generatedByHeader(bool bEnabled) - { - bGeneratedByHeader_ = bEnabled; - return *this; - } - //! Prefix each line with this string. - BinaryInformationSettings &linePrefix(const char *prefix) - { - prefix_ = prefix; - return *this; - } - //! Suffix each line with this string. - BinaryInformationSettings &lineSuffix(const char *suffix) - { - suffix_ = suffix; - return *this; - } + //! Set whether to print information about build settings. + BinaryInformationSettings& extendedInfo(bool bEnabled) + { + bExtendedInfo_ = bEnabled; + return *this; + } + //! Set whether to print copyright and license information. + BinaryInformationSettings& copyright(bool bEnabled) + { + bCopyright_ = bEnabled; + return *this; + } + //! Set whether to print the process ID. + BinaryInformationSettings& processId(bool bEnabled) + { + bProcessId_ = bEnabled; + return *this; + } + //! Set whether to print a header line with "Generated by" text (for output files). + BinaryInformationSettings& generatedByHeader(bool bEnabled) + { + bGeneratedByHeader_ = bEnabled; + return *this; + } + //! Prefix each line with this string. + BinaryInformationSettings& linePrefix(const char* prefix) + { + prefix_ = prefix; + return *this; + } + //! Suffix each line with this string. + BinaryInformationSettings& lineSuffix(const char* suffix) + { + suffix_ = suffix; + return *this; + } - private: - bool bExtendedInfo_; - bool bCopyright_; - bool bProcessId_; - bool bGeneratedByHeader_; - const char *prefix_; - const char *suffix_; +private: + bool bExtendedInfo_; + bool bCopyright_; + bool bProcessId_; + bool bGeneratedByHeader_; + const char* prefix_; + const char* suffix_; - //! Needed to read the members without otherwise unnecessary accessors. - friend void printBinaryInformation( - TextWriter *writer, - const IProgramContext &programContext, - const BinaryInformationSettings &settings); + //! Needed to read the members without otherwise unnecessary accessors. + friend void printBinaryInformation(TextWriter* writer, + const IProgramContext& programContext, + const BinaryInformationSettings& settings); }; /*! \brief @@ -122,8 +121,7 @@ class BinaryInformationSettings * \param fp Where to print the information to. * \param[in] programContext Program information object to use. */ -void printBinaryInformation(FILE *fp, - const IProgramContext &programContext); +void printBinaryInformation(FILE* fp, const IProgramContext& programContext); /*! \brief * Print basic information about the executable with custom settings. * @@ -133,9 +131,9 @@ void printBinaryInformation(FILE *fp, * * \see BinaryInformationSettings */ -void printBinaryInformation(FILE *fp, - const IProgramContext &programContext, - const BinaryInformationSettings &settings); +void printBinaryInformation(FILE* fp, + const IProgramContext& programContext, + const BinaryInformationSettings& settings); /*! \brief * Print basic information about the executable with custom settings. @@ -147,10 +145,10 @@ void printBinaryInformation(FILE *fp, * * \see BinaryInformationSettings */ -void printBinaryInformation(TextWriter *writer, - const IProgramContext &programContext, - const BinaryInformationSettings &settings); +void printBinaryInformation(TextWriter* writer, + const IProgramContext& programContext, + const BinaryInformationSettings& settings); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/utility/bitmask.h b/src/gromacs/utility/bitmask.h index 8d3d8659d6..eddec13736 100644 --- a/src/gromacs/utility/bitmask.h +++ b/src/gromacs/utility/bitmask.h @@ -56,19 +56,19 @@ /*! \brief Size of bitmask. Has to be 32 or multiple of 64. */ #ifndef BITMASK_SIZE -#define BITMASK_SIZE GMX_OPENMP_MAX_THREADS +# define BITMASK_SIZE GMX_OPENMP_MAX_THREADS #endif -#if BITMASK_SIZE != 32 && BITMASK_SIZE%64 != 0 -#error BITMASK_SIZE has to be 32 or a multiple of 64. +#if BITMASK_SIZE != 32 && BITMASK_SIZE % 64 != 0 +# error BITMASK_SIZE has to be 32 or a multiple of 64. #endif #if BITMASK_SIZE <= 64 || defined DOXYGEN -#if BITMASK_SIZE == 32 +# if BITMASK_SIZE == 32 typedef uint32_t gmx_bitmask_t; -#else +# else typedef uint64_t gmx_bitmask_t; /**< bitmask type */ -#endif +# endif /*! \brief Initialize all bits to 0 */ inline static void bitmask_clear(gmx_bitmask_t* m) @@ -124,7 +124,7 @@ inline static void bitmask_union(gmx_bitmask_t* a, gmx_bitmask_t b) *a |= b; } #else -#define BITMASK_ALEN (BITMASK_SIZE/64) +# define BITMASK_ALEN (BITMASK_SIZE / 64) using gmx_bitmask_t = std::array; inline static void bitmask_clear(gmx_bitmask_t* m) @@ -134,31 +134,31 @@ inline static void bitmask_clear(gmx_bitmask_t* m) inline static void bitmask_set_bit(gmx_bitmask_t* m, int b) { - (*m)[b/64] |= (static_cast(1) << (b%64)); + (*m)[b / 64] |= (static_cast(1) << (b % 64)); } inline static void bitmask_init_bit(gmx_bitmask_t* m, int b) { bitmask_clear(m); - (*m)[b/64] = (static_cast(1) << (b%64)); + (*m)[b / 64] = (static_cast(1) << (b % 64)); } inline static void bitmask_init_low_bits(gmx_bitmask_t* m, int b) { - memset(m->data(), 255, b/64*8); - (*m)[b/64] = (static_cast(1) << (b%64)) - 1; - memset(m->data()+(b/64+1), 0, (BITMASK_ALEN-b/64-1)*8); + memset(m->data(), 255, b / 64 * 8); + (*m)[b / 64] = (static_cast(1) << (b % 64)) - 1; + memset(m->data() + (b / 64 + 1), 0, (BITMASK_ALEN - b / 64 - 1) * 8); } inline static bool bitmask_is_set(gmx_bitmask_t m, int b) { - return (m[b/64] & (static_cast(1) << (b%64))) != 0; + return (m[b / 64] & (static_cast(1) << (b % 64))) != 0; } inline static bool bitmask_is_disjoint(gmx_bitmask_t a, gmx_bitmask_t b) { - int i; - bool r = true; + int i; + bool r = true; for (i = 0; i < BITMASK_ALEN; i++) { r = r && ((a[i] & b[i]) == 0U); @@ -168,8 +168,8 @@ inline static bool bitmask_is_disjoint(gmx_bitmask_t a, gmx_bitmask_t b) inline static bool bitmask_is_equal(gmx_bitmask_t a, gmx_bitmask_t b) { - int i; - bool r = true; + int i; + bool r = true; for (i = 0; i < BITMASK_ALEN; i++) { r = r && (a[i] == b[i]); @@ -179,8 +179,8 @@ inline static bool bitmask_is_equal(gmx_bitmask_t a, gmx_bitmask_t b) inline static bool bitmask_is_zero(gmx_bitmask_t m) { - int i; - bool r = true; + int i; + bool r = true; for (i = 0; i < BITMASK_ALEN; i++) { r = r && (m[i] == 0U); @@ -197,7 +197,7 @@ inline static void bitmask_union(gmx_bitmask_t* a, gmx_bitmask_t b) } } #endif -//In bitmask.h because only current use is for bitmask. +// In bitmask.h because only current use is for bitmask. //! Convert uint32_t to hex string inline static std::string to_hex_string(uint32_t m) @@ -210,7 +210,7 @@ inline static std::string to_hex_string(uint64_t m) return gmx::formatString("%016" PRIx64, m); } //! Convert container of intergers to hex string -template +template inline static std::string to_hex_string(C m) { std::string ret; diff --git a/src/gromacs/utility/classhelpers.h b/src/gromacs/utility/classhelpers.h index 041d1357f7..46c7a5c3a8 100644 --- a/src/gromacs/utility/classhelpers.h +++ b/src/gromacs/utility/classhelpers.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,11 +60,11 @@ namespace gmx * * \ingroup module_utility */ -#define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) +# define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) #else -#define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) \ - ClassName &operator=(const ClassName &) = delete; \ - ClassName(const ClassName &) = delete +# define GMX_DISALLOW_COPY_AND_ASSIGN(ClassName) \ + ClassName& operator=(const ClassName&) = delete; \ + ClassName(const ClassName&) = delete #endif /*! \brief * Macro to declare a class non-assignable. @@ -73,9 +73,9 @@ namespace gmx * * \ingroup module_utility */ -#define GMX_DISALLOW_ASSIGN(ClassName) \ - ClassName &operator=(const ClassName &) = delete +#define GMX_DISALLOW_ASSIGN(ClassName) ClassName& operator=(const ClassName&) = delete +// clang-format off #ifdef DOXYGEN /*! \brief * Macro to declare default constructors @@ -85,15 +85,16 @@ namespace gmx * * \ingroup module_utility */ -#define GMX_DEFAULT_CONSTRUCTORS(ClassName) +# define GMX_DEFAULT_CONSTRUCTORS(ClassName) #else -#define GMX_DEFAULT_CONSTRUCTORS(ClassName) \ - ClassName() = default; \ - ClassName &operator=(const ClassName &) = default; /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ \ - ClassName(const ClassName &) = default; \ - ClassName &operator=(ClassName &&) = default; /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ \ - ClassName(ClassName &&) = default /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ +# define GMX_DEFAULT_CONSTRUCTORS(ClassName) \ + ClassName() = default; \ + ClassName& operator=(const ClassName&) = default; /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ \ + ClassName(const ClassName&) = default; \ + ClassName& operator=(ClassName&&) = default; /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ \ + ClassName(ClassName&&) = default /* NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) */ #endif +//clang-format on /*! \brief * Helper class to manage a pointer to a private implementation class. @@ -156,54 +157,54 @@ namespace gmx * \inlibraryapi * \ingroup module_utility */ -template +template class PrivateImplPointer { - public: - //! Allow implicit initialization from nullptr to support comparison. - PrivateImplPointer(std::nullptr_t) : ptr_(nullptr) {} - //! Initialize with the given implementation class. - explicit PrivateImplPointer(Impl *ptr) : ptr_(ptr) {} - //! \cond - // Explicitly declared to work around MSVC problems. - PrivateImplPointer(PrivateImplPointer &&other) noexcept : ptr_(std::move(other.ptr_)) {} - PrivateImplPointer &operator=(PrivateImplPointer &&other) noexcept - { - ptr_ = std::move(other.ptr_); - return *this; - } - //! \endcond - - /*! \brief - * Sets a new implementation class and destructs the previous one. - * - * Needed, e.g., to implement lazily initializable or copy-assignable - * classes. - */ - void reset(Impl *ptr) { ptr_.reset(ptr); } - //! Access the raw pointer. - Impl *get() { return ptr_.get(); } - //! Access the implementation class as with a raw pointer. - Impl *operator->() { return ptr_.get(); } - //! Access the implementation class as with a raw pointer. - Impl &operator*() { return *ptr_; } - //! Access the implementation class as with a raw pointer. - const Impl *operator->() const { return ptr_.get(); } - //! Access the implementation class as with a raw pointer. - const Impl &operator*() const { return *ptr_; } - - //! Allows testing whether the implementation is initialized. - explicit operator bool() const { return ptr_ != nullptr; } - - //! Tests for equality (mainly useful against nullptr). - bool operator==(const PrivateImplPointer &other) const { return ptr_ == other.ptr_; } - //! Tests for inequality (mainly useful against nullptr). - bool operator!=(const PrivateImplPointer &other) const { return ptr_ != other.ptr_; } - - private: - std::unique_ptr ptr_; - - // Copy construction and assignment disabled by the unique_ptr member. +public: + //! Allow implicit initialization from nullptr to support comparison. + PrivateImplPointer(std::nullptr_t) : ptr_(nullptr) {} + //! Initialize with the given implementation class. + explicit PrivateImplPointer(Impl* ptr) : ptr_(ptr) {} + //! \cond + // Explicitly declared to work around MSVC problems. + PrivateImplPointer(PrivateImplPointer&& other) noexcept : ptr_(std::move(other.ptr_)) {} + PrivateImplPointer& operator=(PrivateImplPointer&& other) noexcept + { + ptr_ = std::move(other.ptr_); + return *this; + } + //! \endcond + + /*! \brief + * Sets a new implementation class and destructs the previous one. + * + * Needed, e.g., to implement lazily initializable or copy-assignable + * classes. + */ + void reset(Impl* ptr) { ptr_.reset(ptr); } + //! Access the raw pointer. + Impl* get() { return ptr_.get(); } + //! Access the implementation class as with a raw pointer. + Impl* operator->() { return ptr_.get(); } + //! Access the implementation class as with a raw pointer. + Impl& operator*() { return *ptr_; } + //! Access the implementation class as with a raw pointer. + const Impl* operator->() const { return ptr_.get(); } + //! Access the implementation class as with a raw pointer. + const Impl& operator*() const { return *ptr_; } + + //! Allows testing whether the implementation is initialized. + explicit operator bool() const { return ptr_ != nullptr; } + + //! Tests for equality (mainly useful against nullptr). + bool operator==(const PrivateImplPointer& other) const { return ptr_ == other.ptr_; } + //! Tests for inequality (mainly useful against nullptr). + bool operator!=(const PrivateImplPointer& other) const { return ptr_ != other.ptr_; } + +private: + std::unique_ptr ptr_; + + // Copy construction and assignment disabled by the unique_ptr member. }; } // namespace gmx diff --git a/src/gromacs/utility/compare.cpp b/src/gromacs/utility/compare.cpp index 6214f25995..7a32bf107b 100644 --- a/src/gromacs/utility/compare.cpp +++ b/src/gromacs/utility/compare.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,7 +46,7 @@ #include "gromacs/utility/strconvert.h" -void cmp_int(FILE *fp, const char *s, int index, int i1, int i2) +void cmp_int(FILE* fp, const char* s, int index, int i1, int i2) { if (i1 != i2) { @@ -61,7 +61,7 @@ void cmp_int(FILE *fp, const char *s, int index, int i1, int i2) } } -void cmp_int64(FILE *fp, const char *s, int64_t i1, int64_t i2) +void cmp_int64(FILE* fp, const char* s, int64_t i1, int64_t i2) { if (i1 != i2) { @@ -73,7 +73,7 @@ void cmp_int64(FILE *fp, const char *s, int64_t i1, int64_t i2) } } -void cmp_us(FILE *fp, const char *s, int index, unsigned short i1, unsigned short i2) +void cmp_us(FILE* fp, const char* s, int index, unsigned short i1, unsigned short i2) { if (i1 != i2) { @@ -88,40 +88,38 @@ void cmp_us(FILE *fp, const char *s, int index, unsigned short i1, unsigned shor } } -void cmp_uc(FILE *fp, const char *s, int index, unsigned char i1, unsigned char i2) +void cmp_uc(FILE* fp, const char* s, int index, unsigned char i1, unsigned char i2) { if (i1 != i2) { if (index != -1) { - fprintf(fp, "%s[%d] (%d - %d)\n", s, index, int{i1}, int{i2}); + fprintf(fp, "%s[%d] (%d - %d)\n", s, index, int{ i1 }, int{ i2 }); } else { - fprintf(fp, "%s (%d - %d)\n", s, int{i1}, int{i2}); + fprintf(fp, "%s (%d - %d)\n", s, int{ i1 }, int{ i2 }); } } } -gmx_bool cmp_bool(FILE *fp, const char *s, int index, gmx_bool b1, gmx_bool b2) +gmx_bool cmp_bool(FILE* fp, const char* s, int index, gmx_bool b1, gmx_bool b2) { if (b1 != b2) { if (index != -1) { - fprintf(fp, "%s[%d] (%s - %s)\n", s, index, - gmx::boolToString(b1), gmx::boolToString(b2)); + fprintf(fp, "%s[%d] (%s - %s)\n", s, index, gmx::boolToString(b1), gmx::boolToString(b2)); } else { - fprintf(fp, "%s (%s - %s)\n", s, - gmx::boolToString(b1), gmx::boolToString(b2)); + fprintf(fp, "%s (%s - %s)\n", s, gmx::boolToString(b1), gmx::boolToString(b2)); } } return b1 && b2; } -void cmp_str(FILE *fp, const char *s, int index, const char *s1, const char *s2) +void cmp_str(FILE* fp, const char* s, int index, const char* s1, const char* s2) { if (std::strcmp(s1, s2) != 0) { @@ -138,21 +136,21 @@ void cmp_str(FILE *fp, const char *s, int index, const char *s1, const char *s2) gmx_bool equal_real(real i1, real i2, real ftol, real abstol) { - return ( ( 2*std::fabs(i1 - i2) <= (fabs(i1) + fabs(i2))*ftol ) || std::fabs(i1-i2) <= abstol ); + return ((2 * std::fabs(i1 - i2) <= (fabs(i1) + fabs(i2)) * ftol) || std::fabs(i1 - i2) <= abstol); } gmx_bool equal_float(float i1, float i2, float ftol, float abstol) { - return ( ( 2*std::fabs(i1 - i2) <= (std::fabs(i1) + std::fabs(i2))*ftol ) || std::fabs(i1-i2) <= abstol ); + return ((2 * std::fabs(i1 - i2) <= (std::fabs(i1) + std::fabs(i2)) * ftol) + || std::fabs(i1 - i2) <= abstol); } gmx_bool equal_double(double i1, double i2, real ftol, real abstol) { - return ( ( 2*fabs(i1 - i2) <= (fabs(i1) + fabs(i2))*ftol ) || fabs(i1-i2) <= abstol ); + return ((2 * fabs(i1 - i2) <= (fabs(i1) + fabs(i2)) * ftol) || fabs(i1 - i2) <= abstol); } -void -cmp_real(FILE *fp, const char *s, int index, real i1, real i2, real ftol, real abstol) +void cmp_real(FILE* fp, const char* s, int index, real i1, real i2, real ftol, real abstol) { if (!equal_real(i1, i2, ftol, abstol)) { @@ -167,8 +165,7 @@ cmp_real(FILE *fp, const char *s, int index, real i1, real i2, real ftol, real a } } -void -cmp_float(FILE *fp, const char *s, int index, float i1, float i2, float ftol, float abstol) +void cmp_float(FILE* fp, const char* s, int index, float i1, float i2, float ftol, float abstol) { if (!equal_float(i1, i2, ftol, abstol)) { @@ -183,8 +180,7 @@ cmp_float(FILE *fp, const char *s, int index, float i1, float i2, float ftol, fl } } -void -cmp_double(FILE *fp, const char *s, int index, double i1, double i2, double ftol, double abstol) +void cmp_double(FILE* fp, const char* s, int index, double i1, double i2, double ftol, double abstol) { if (!equal_double(i1, i2, ftol, abstol)) { diff --git a/src/gromacs/utility/compare.h b/src/gromacs/utility/compare.h index 610cfc366c..96b4a269f2 100644 --- a/src/gromacs/utility/compare.h +++ b/src/gromacs/utility/compare.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,30 +57,30 @@ gmx_bool equal_float(float i1, float i2, float ftol, float abstol); gmx_bool equal_double(double i1, double i2, real ftol, real abstol); //! Compares two integers and prints differences. -void cmp_int(FILE *fp, const char *s, int index, int i1, int i2); +void cmp_int(FILE* fp, const char* s, int index, int i1, int i2); //! Compares two 64-bit integers and prints differences. -void cmp_int64(FILE *fp, const char *s, int64_t i1, int64_t i2); +void cmp_int64(FILE* fp, const char* s, int64_t i1, int64_t i2); //! Compares two unsigned short values and prints differences. -void cmp_us(FILE *fp, const char *s, int index, unsigned short i1, unsigned short i2); +void cmp_us(FILE* fp, const char* s, int index, unsigned short i1, unsigned short i2); //! Compares two unsigned char values and prints differences. -void cmp_uc(FILE *fp, const char *s, int index, unsigned char i1, unsigned char i2); +void cmp_uc(FILE* fp, const char* s, int index, unsigned char i1, unsigned char i2); //! Compares two boolean values and prints differences, and returns whether both are true. -gmx_bool cmp_bool(FILE *fp, const char *s, int index, gmx_bool b1, gmx_bool b2); +gmx_bool cmp_bool(FILE* fp, const char* s, int index, gmx_bool b1, gmx_bool b2); //! Compares two strings and prints differences. -void cmp_str(FILE *fp, const char *s, int index, const char *s1, const char *s2); +void cmp_str(FILE* fp, const char* s, int index, const char* s1, const char* s2); //! Compares two reals and prints differences. -void cmp_real(FILE *fp, const char *s, int index, real i1, real i2, real ftol, real abstol); +void cmp_real(FILE* fp, const char* s, int index, real i1, real i2, real ftol, real abstol); //! Compares two floats and prints differences. -void cmp_float(FILE *fp, const char *s, int index, float i1, float i2, float ftol, float abstol); +void cmp_float(FILE* fp, const char* s, int index, float i1, float i2, float ftol, float abstol); //! Compares two doubles and prints differences. -void cmp_double(FILE *fp, const char *s, int index, double i1, double i2, double ftol, double abstol); +void cmp_double(FILE* fp, const char* s, int index, double i1, double i2, double ftol, double abstol); #endif diff --git a/src/gromacs/utility/coolstuff.cpp b/src/gromacs/utility/coolstuff.cpp index b6c201df40..fadd38184d 100644 --- a/src/gromacs/utility/coolstuff.cpp +++ b/src/gromacs/utility/coolstuff.cpp @@ -73,19 +73,19 @@ bool beCool() } //! Return a valid random index into \c arrayRef -template -const T &getRandomElement(gmx::ArrayRef arrayRef) +template +const T& getRandomElement(gmx::ArrayRef arrayRef) { std::random_device generator; - std::uniform_int_distribution distribution(0, arrayRef.size()-1); + std::uniform_int_distribution distribution(0, arrayRef.size() - 1); return arrayRef[distribution(generator)]; } -} // namespace +} // namespace std::string bromacs() { - const char * const bromacsArray[] = { + const char* const bromacsArray[] = { "Good gRace! Old Maple Actually Chews Slate", "GRoups of Organic Molecules in ACtion for Science", "GRowing Old MAkes el Chrono Sweat", @@ -116,7 +116,7 @@ std::string bromacs() if (beCool()) { - return getRandomElement(bromacsArray); + return getRandomElement(bromacsArray); } else { @@ -128,8 +128,8 @@ std::string getCoolQuote() { struct Quote { - const char *text; - const char *author; + const char* text; + const char* author; }; const Quote quoteArray[] = { @@ -247,10 +247,18 @@ std::string getCoolQuote() { "Bring Out the Gimp", "Pulp Fiction" }, { "You Could Be a Shadow", "The Breeders" }, { "If You're So Special Why aren't You Dead ?", "The Breeders" }, - { "The Path Of the Righteous Man is Beset On All Sides With the Iniquities Of the Selfish and the Tyranny Of Evil Men.", "Pulp Fiction" }, - { "Blessed is He Who In the Name Of Charity and Good Will Shepherds the Weak Through the Valley Of Darkness, For He is Truly His Brother's Keeper and the Finder Of Lost Children.", "Pulp Fiction" }, - { "And I Will Strike Down Upon Thee With Great Vengeance and With Furious Anger Those Who Attempt to Poison and Destroy My Brothers.", "Pulp Fiction" }, - { "And You Will Know That My Name is the Lord When I Lay My Vengeance Upon Thee.", "Pulp Fiction" }, + { "The Path Of the Righteous Man is Beset On All Sides With the Iniquities Of the Selfish " + "and the Tyranny Of Evil Men.", + "Pulp Fiction" }, + { "Blessed is He Who In the Name Of Charity and Good Will Shepherds the Weak Through the " + "Valley Of Darkness, For He is Truly His Brother's Keeper and the Finder Of Lost " + "Children.", + "Pulp Fiction" }, + { "And I Will Strike Down Upon Thee With Great Vengeance and With Furious Anger Those Who " + "Attempt to Poison and Destroy My Brothers.", + "Pulp Fiction" }, + { "And You Will Know That My Name is the Lord When I Lay My Vengeance Upon Thee.", + "Pulp Fiction" }, { "Step On the Brakes", "2 Unlimited" }, { "You Don't Wanna Know", "Pulp Fiction" }, { "You Dirty Switch, You're On Again", "The Breeders" }, @@ -378,15 +386,18 @@ std::string getCoolQuote() { "Drugs are Bad, mmokay", "South Park" }, { "Let's Unzip And Let's Unfold", "Red Hot Chili Peppers" }, { "I'd Be Water If I Could", "Red Hot Chili Peppers" }, - { "Space May Be the Final Frontier, But It's Made in a Hollywood Basement", "Red Hot Chili Peppers" }, + { "Space May Be the Final Frontier, But It's Made in a Hollywood Basement", + "Red Hot Chili Peppers" }, { "Everything Must Go", "Red Hot Chili Peppers" }, { "There's Nothing We Can't Fix, 'coz We Can Do It in the Mix", "Indeep" }, { "It's Coming Right For Us !", "South Park" }, { "Disturb the Peace of a John Q Citizen", "Urban Dance Squad" }, { "Wicky-wicky Wa-wild West", "Will Smith" }, { "This is Tense !", "Star Wars Episode I The Phantom Menace" }, - { "Fly to the Court of England and Unfold", "Macbeth, Act 3, Scene 6, William Shakespeare" }, - { "Why, how now, Claudio ! Whence Comes this Restraint ?", "Lucio in Measure for measure, Act 1, Scene 4, William Shakespeare" }, + { "Fly to the Court of England and Unfold", + "Macbeth, Act 3, Scene 6, William Shakespeare" }, + { "Why, how now, Claudio ! Whence Comes this Restraint ?", + "Lucio in Measure for measure, Act 1, Scene 4, William Shakespeare" }, { "In the End Science Comes Down to Praying", "P. v.d. Berg" }, { "I'm Looking for a New Simulation", "Stone Temple Pilots" }, { "I Quit My Job Blowing Leaves", "Beck" }, @@ -445,13 +456,18 @@ std::string getCoolQuote() { "Nobody Never Learnt No-Nothing from No History", "Gogol Bordello" }, { "I'd be Safe and Warm if I was in L.A.", "The Mamas and the Papas" }, { "It's Unacceptable That Choclate Makes You Fat", "MI 3" }, - { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)", "Gogol Bordello" }, - { "Put Me Inside SSC, Let's Test Superstring Theory, Oh Yoi Yoi Accelerate the Protons", "Gogol Bordello" }, - { "Do You Have Sex Maniacs or Schizophrenics or Astrophysicists in Your Family?", "Gogol Bordello" }, + { "My Brothers are Protons (Protons!), My Sisters are Neurons (Neurons)", + "Gogol Bordello" }, + { "Put Me Inside SSC, Let's Test Superstring Theory, Oh Yoi Yoi Accelerate the Protons", + "Gogol Bordello" }, + { "Do You Have Sex Maniacs or Schizophrenics or Astrophysicists in Your Family?", + "Gogol Bordello" }, { "Screw a Lightbulb in your Head", "Gogol Bordello" }, { "Alas, You're Welcome", "Prof. Dumbledore in Potter Puppet Pals" }, { "Your Shopping Techniques are Amazing", "Gogol Bordello" }, - { "Your Country Raised You, Your Country Fed You, and Just Like Any Other Country it Will Break You", "Gogol Bordello" }, + { "Your Country Raised You, Your Country Fed You, and Just Like Any Other Country it Will " + "Break You", + "Gogol Bordello" }, { "What They Need's a Damn Good Whacking", "The Beatles" }, { "They Paint Their Faces So Differently From Ours", "Gogol Bordello" }, { "The Feeling of Power was Intoxicating, Magic", "Frida Hyvonen" }, @@ -461,16 +477,20 @@ std::string getCoolQuote() { "It's just the way this stuff is done", "Built to Spill" }, { "You Fill Me With Inertia", "The Long Blondes" }, { "I used to be blond and stupid, but now I dyed it black", "Miss Li" }, - { "Aber wenn der Quarterback kommt, um dir die Brille abzunehmen, sag ihm: Danke, die bleibt wo sie ist", "Wir sind Helden" }, + { "Aber wenn der Quarterback kommt, um dir die Brille abzunehmen, sag ihm: Danke, die " + "bleibt wo sie ist", + "Wir sind Helden" }, { "Jede der Scherben spiegelt das Licht", "Wir sind Helden" }, { "Ohne Arbeit waer das Leben oede", "Wir Sind Helden" }, { "Act like Prometheus would", "Gogol Bordello" }, { "Making merry out of nothing, like in refugee camp", "Gogol Bordello" }, { "History has expired", "PubMed Central" }, { "There's only music to make new ringtones", "Arctic Monkeys" }, - { "Can someone please tell Icarus that he's not the only one falling from the sky?", "Urban Dance Squad" }, + { "Can someone please tell Icarus that he's not the only one falling from the sky?", + "Urban Dance Squad" }, { "Ich war schwanger, mir gings zum kotzen", "Nina Hagen" }, - { "What if you're wrong about the great Ju Ju at the bottom of the sea?", "Richard Dawkins" }, + { "What if you're wrong about the great Ju Ju at the bottom of the sea?", + "Richard Dawkins" }, { "Come on boys, Let's push it hard", "P.J. Harvey" }, { "Look at these, my work-strong arms", "P.J. Harvey" }, { "Is it the invisible chemistry stuff?", "Frida Hyvonen" }, @@ -480,7 +500,8 @@ std::string getCoolQuote() { "Everything's formed from particles", "Van der Graaf Generator" }, { "The time for theory is over", "J. Hajdu" }, { "What's the point, yo, what's the spread?", "Red Hot Chili Peppers" }, - { "If There Is No Guitar In The House, You Know It's Owner Can Not Be Trusted", "Gogol Bordello" }, + { "If There Is No Guitar In The House, You Know It's Owner Can Not Be Trusted", + "Gogol Bordello" }, { "Carbohydrates is all they groove", "Frank Zappa" }, { "Never, I said never, compare with experiment", "Magnus Bergh" }, { "Suzy is a headbanger, her mother is a geek", "The Ramones" }, @@ -491,8 +512,11 @@ std::string getCoolQuote() { "Can I have everything louder than everything else?", "Deep Purple" }, { "He's using code that only you and I know", "Kate Bush" }, { "Chemical gases filling lungs of little ones", "Black Eyed Peas" }, - { "I've basically become a vegetarian since the only meat I'm eating is from animals I've killed myself", "Mark Zuckerberg" }, - { "Years of calculations and the stress, My science is waiting, nearly complete", "Midlake" }, + { "I've basically become a vegetarian since the only meat I'm eating is from animals I've " + "killed myself", + "Mark Zuckerberg" }, + { "Years of calculations and the stress, My science is waiting, nearly complete", + "Midlake" }, { "error: too many template-parameter-lists", "g++" }, { "Science Won't Change You", "The Talking Heads" }, { "It Doesn't Seem Right, No Computers in Sight", "Faun Fables" }, @@ -505,451 +529,979 @@ std::string getCoolQuote() { "When the universe has expanded, time will contract", "Franz Ferdinand" }, { "This really is a pretty scene, could you ask your kid to smile please?", "Joe Jackson" }, { "England's dancing days are done", "P. J. Harvey" }, - { "The future still looks good, and you've got time to rectify all the things that you should", "G. Harrison" }, - { "If humanity has fled shivering from the starry spaces, it has become minutely at home in the interstices of the speck that it inhabits for an instant", "George H. Mead" }, - { "The scientific method is an integral part of human intelligence, and when it has once been set at work it can only be dismissed by dismissing the intelligence itself", "George H. Mead" }, - { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie", "Lola rennt" }, + { "The future still looks good, and you've got time to rectify all the things that you " + "should", + "G. Harrison" }, + { "If humanity has fled shivering from the starry spaces, it has become minutely at home " + "in the interstices of the speck that it inhabits for an instant", + "George H. Mead" }, + { "The scientific method is an integral part of human intelligence, and when it has once " + "been set at work it can only be dismissed by dismissing the intelligence itself", + "George H. Mead" }, + { "Der Ball ist rund, das Spiel dauert 90 minuten, alles andere ist Theorie", + "Lola rennt" }, { "Life in the streets is not easy", "Marky Mark" }, { "How will I know it's working right?", "MGMT" }, { "There was no preconception on what to do", "Daft Punk" }, { "It takes money to make money, they say", "Lou Reed" }, { "The future always gets twisted and turned", "Lisa o Piu" }, - { "Do not go where the path may lead, go instead where there is no path and leave a trail", "Ralph Waldo Emerson" }, - { "I went to Venice and looked at the paintings of Canaletto to understand how he presented perspective, and it turned out it was an exponential law. If I had published this, maybe there would be a Karplus law in art theory as well as the Karplus equation in NMR", "Martin Karplus, Nobel lecture 2013" }, - { "Theoretical chemistry has of course always been important and useful ... at least to theoretical chemists", "Sven Lidin" }, + { "Do not go where the path may lead, go instead where there is no path and leave a trail", + "Ralph Waldo Emerson" }, + { "I went to Venice and looked at the paintings of Canaletto to understand how he " + "presented perspective, and it turned out it was an exponential law. If I had published " + "this, maybe there would be a Karplus law in art theory as well as the Karplus equation " + "in NMR", + "Martin Karplus, Nobel lecture 2013" }, + { "Theoretical chemistry has of course always been important and useful ... at least to " + "theoretical chemists", + "Sven Lidin" }, { "I do not believe continuum electrostatics", "Arieh Warshel, Nobel lecture 2013" }, - { "During my undergraduate work I concluded that electrostatics is unlikely to be important [for enzymes]", "Arieh Warshel, Nobel lecture 2013" }, - { "Martin [Karplus] had a green laser, Arieh [Warshel] had a red laser, I have a *blue* laser", "Michael Levitt, Nobel lecture 2013" }, + { "During my undergraduate work I concluded that electrostatics is unlikely to be " + "important [for enzymes]", + "Arieh Warshel, Nobel lecture 2013" }, + { "Martin [Karplus] had a green laser, Arieh [Warshel] had a red laser, I have a *blue* " + "laser", + "Michael Levitt, Nobel lecture 2013" }, { "There's so many shades of black", "The Raconteurs" }, - { "Let us not get carried away with our ideas and take our models too seriously", "Nancy Swanson" }, - { "Unfortunately, \"simulation\" has become increasingly misused to mean nothing more than \"calculation\"", "Bill Jorgensen" }, - { "Physics is a few rules, and with some handwaving you can make up the rest", "Michael Levitt" }, + { "Let us not get carried away with our ideas and take our models too seriously", + "Nancy Swanson" }, + { "Unfortunately, \"simulation\" has become increasingly misused to mean nothing more than " + "\"calculation\"", + "Bill Jorgensen" }, + { "Physics is a few rules, and with some handwaving you can make up the rest", + "Michael Levitt" }, { "It doesn't pay to make predictions", "Crowded House" }, { "Strength is just an accident arising from the weakness of others", "Joseph Conrad" }, - { "On the East coast, a purple patch, to show where the jolly pioneers of progress drink the jolly lager-beer", "Joseph Conrad" }, + { "On the East coast, a purple patch, to show where the jolly pioneers of progress drink " + "the jolly lager-beer", + "Joseph Conrad" }, { "Restraint! What possible restraint?", "Joseph Conrad" }, { "It was something to at least have a choice of nightmares", "Joseph Conrad" }, - { "You fight, work, sweat, nearly kill yourself, sometimes you do kill yourself, trying to accomplish something - and you can't.", "Joseph Conrad" }, - { "And after some more talk we agreed that the wisdom of rats had been grossly overrated, being in fact no greater than that of men", "Joseph Conrad" }, + { "You fight, work, sweat, nearly kill yourself, sometimes you do kill yourself, trying to " + "accomplish something - and you can't.", + "Joseph Conrad" }, + { "And after some more talk we agreed that the wisdom of rats had been grossly overrated, " + "being in fact no greater than that of men", + "Joseph Conrad" }, { "It's an easy game, just don't let the ball past!", "Szilard Pall" }, { "The soul? There's nothing but chemistry here", "Breaking Bad" }, { "You got one part of that wrong. This is not meth.", "Breaking Bad" }, - { "It's easy to remember: a half a kT is equal to five fourths of a kJ/mol.", "Anders Gabrielsson" }, + { "It's easy to remember: a half a kT is equal to five fourths of a kJ/mol.", + "Anders Gabrielsson" }, { "Ubiquitin's just a rock", "Berk Hess" }, - { "... an excellent man, almost worthy of such a wife ...", "Jane Eyre in Jane Eyre by Charlotte Bronte" }, - { "Humbug! Most things free-born will submit to anything for a salary", "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, - { "Like other defaulters, I like to lay half the blame on ill-fortune and adverse circumstances", "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, - { "Either you will be dashed to atoms on crag points, or lifted up and borne by some master-wave into a calmer current", "Charlotte Bronte" }, + { "... an excellent man, almost worthy of such a wife ...", + "Jane Eyre in Jane Eyre by Charlotte Bronte" }, + { "Humbug! Most things free-born will submit to anything for a salary", + "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, + { "Like other defaulters, I like to lay half the blame on ill-fortune and adverse " + "circumstances", + "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, + { "Either you will be dashed to atoms on crag points, or lifted up and borne by some " + "master-wave into a calmer current", + "Charlotte Bronte" }, { "I ought to warn you, I have no faith", "Jane Eyre in Jane Eyre by Charlotte Bronte" }, - { "... yet the [economic] profession continued to churn out purely theoretical results without even knowing what facts needed to be explained.", "Thomas Piketty" }, - { "Scientists think they are born with logic; God forbid they should study this discipline with a history of more than two and a half millennia.", "Roald Hoffmann" }, - { "In the processing of models we must be especially cautious of the human weakness to think that models can be verified or validated. Especially one's own.", "Roald Hoffmann" }, - { "... and that dream of dreams, a computational model that predicts everything accurately.", "Roald Hoffmann" }, - { "You see it through a charmed medium: you can not discern that the gilding is slime and the silk draperies cobwebs; that the marble is sordid slate, and the polished woods mere refuse chips and scale bark.", "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, - { "I know poetry is not dead, nor genius lost; nor has Mammon gained power over either, to bind or slay; they will both assert their existence, their presence, their liberty and strength again one day.", "Jane Eyre in Jane Eyre by Charlotte Bronte" }, + { "... yet the [economic] profession continued to churn out purely theoretical results " + "without even knowing what facts needed to be explained.", + "Thomas Piketty" }, + { "Scientists think they are born with logic; God forbid they should study this discipline " + "with a history of more than two and a half millennia.", + "Roald Hoffmann" }, + { "In the processing of models we must be especially cautious of the human weakness to " + "think that models can be verified or validated. Especially one's own.", + "Roald Hoffmann" }, + { "... and that dream of dreams, a computational model that predicts everything " + "accurately.", + "Roald Hoffmann" }, + { "You see it through a charmed medium: you can not discern that the gilding is slime and " + "the silk draperies cobwebs; that the marble is sordid slate, and the polished woods " + "mere refuse chips and scale bark.", + "Mr. Rochester in Jane Eyre by Charlotte Bronte" }, + { "I know poetry is not dead, nor genius lost; nor has Mammon gained power over either, to " + "bind or slay; they will both assert their existence, their presence, their liberty and " + "strength again one day.", + "Jane Eyre in Jane Eyre by Charlotte Bronte" }, { "Parallel programming is not about elegance!", "Bill Gropp" }, { "In a talk you have a choice: You can make one point or no points.", "Paul Sigler" }, { "Where all think alike, no one thinks very much.", "Walter Lippmann" }, - { "The scientist is not the person who always gives the right answers, he is the one who asks the right questions.", "Claude Levi-Strauss" }, - { "A curious aspect of the theory of evolution is that everybody thinks he understands it.", "Jacques Monod" }, - { "When a distinguished but elderly scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.", "Arthur C. Clarke" }, - { "Energy is a very subtle concept. It is very, very difficult to get right.", "Richard Feynman" }, + { "The scientist is not the person who always gives the right answers, he is the one who " + "asks the right questions.", + "Claude Levi-Strauss" }, + { "A curious aspect of the theory of evolution is that everybody thinks he understands it.", + "Jacques Monod" }, + { "When a distinguished but elderly scientist states that something is possible, he is " + "almost certainly right. When he states that something is impossible, he is very " + "probably wrong.", + "Arthur C. Clarke" }, + { "Energy is a very subtle concept. It is very, very difficult to get right.", + "Richard Feynman" }, { "The determined Real Programmer can write FORTRAN programs in any language.", "Ed Post" }, - { "FORTRAN was the language of choice for the same reason that three-legged races are popular.", "Ken Thompson" }, - { "A computer without COBOL and FORTRAN is like a piece of chocolate cake without ketchup or mustard.", "Unix fortune program" }, - { "Consistently separating words by spaces became a general custom about the tenth century A.D., and lasted until about 1957, when FORTRAN abandoned the practice.", "Sun FORTRAN Reference Manual" }, - { "Ludwig Boltzmann, who spent much of his life studying statistical mechanics, died in 1906, by his own hand. Paul Ehrenfest, carrying on the same work, died similarly in 1933. Now it is our turn to study statistical mechanics. Perhaps it will be wise to approach the subject cautiously.", "David Goodstein" }, - { "It all works because Avogadro's number is closer to infinity than to 10.", "Ralph Baierlein" }, + { "FORTRAN was the language of choice for the same reason that three-legged races are " + "popular.", + "Ken Thompson" }, + { "A computer without COBOL and FORTRAN is like a piece of chocolate cake without ketchup " + "or mustard.", + "Unix fortune program" }, + { "Consistently separating words by spaces became a general custom about the tenth century " + "A.D., and lasted until about 1957, when FORTRAN abandoned the practice.", + "Sun FORTRAN Reference Manual" }, + { "Ludwig Boltzmann, who spent much of his life studying statistical mechanics, died in " + "1906, by his own hand. Paul Ehrenfest, carrying on the same work, died similarly in " + "1933. Now it is our turn to study statistical mechanics. Perhaps it will be wise to " + "approach the subject cautiously.", + "David Goodstein" }, + { "It all works because Avogadro's number is closer to infinity than to 10.", + "Ralph Baierlein" }, { "In this house, we OBEY the laws of thermodynamics!", "Homer Simpson" }, { "We mathematicians are all a bit crazy.", "Lev Landau" }, - { "There is no such thing as free energy. Anyone who advocates it does not know what he is talking about.", "Alireza Haghighat" }, - { "In science it often happens that scientists say, 'You know that's a really good argument; my position is mistaken,' and then they would actually change their minds and you never hear that old view from them again. They really do it. It doesn't happen as often as it should, because scientists are human and change is sometimes painful. But it happens every day. I cannot recall the last time something like that happened in politics or religion.", "Carl Sagan" }, - { "There is nothing new to be discovered in physics now. All that remains is more and more precise measurement.", "Lord Kelvin, 1900" }, + { "There is no such thing as free energy. Anyone who advocates it does not know what he is " + "talking about.", + "Alireza Haghighat" }, + { "In science it often happens that scientists say, 'You know that's a really good " + "argument; my position is mistaken,' and then they would actually change their minds and " + "you never hear that old view from them again. They really do it. It doesn't happen as " + "often as it should, because scientists are human and change is sometimes painful. But " + "it happens every day. I cannot recall the last time something like that happened in " + "politics or religion.", + "Carl Sagan" }, + { "There is nothing new to be discovered in physics now. All that remains is more and more " + "precise measurement.", + "Lord Kelvin, 1900" }, { "I love fools' experiments. I am always making them.", "Charles Darwin" }, - { "If you want to save your child from polio, you can pray or you can inoculate... choose science.", "Carl Sagan" }, - { "Molecular biology is essentially the practice of biochemistry without a license.", "Edwin Chargaff" }, - { "If at one time or another I have brushed a few colleagues the wrong way, I must apologize: I had not realized that they were covered with fur.", "Edwin Chargaff" }, - { "It has not escaped our notice that the specific pairing we have postulated immediately suggests a possible copying mechanism for the genetic material.", "Watson & Crick" }, + { "If you want to save your child from polio, you can pray or you can inoculate... choose " + "science.", + "Carl Sagan" }, + { "Molecular biology is essentially the practice of biochemistry without a license.", + "Edwin Chargaff" }, + { "If at one time or another I have brushed a few colleagues the wrong way, I must " + "apologize: I had not realized that they were covered with fur.", + "Edwin Chargaff" }, + { "It has not escaped our notice that the specific pairing we have postulated immediately " + "suggests a possible copying mechanism for the genetic material.", + "Watson & Crick" }, { "The researcher's art is first of all to find himself a good boss.", "Andre Lwoff" }, - { "What about my nose?", "Aneesur Rahman, responding to an Argonne manager arguing the long hair of Charles Bennett in his group was disreputing the lab; Retold by Michael Klein" }, - { "Science, my lad, is made up of mistakes, but they are mistakes which it is useful to make, because they lead little by little to the truth.", "Jules Verne" }, - { "Don't be afraid of hard work. Nothing worthwhile comes easily. Don't let others discourage you or tell you that you can't do it. In my day I was told women didn't go into chemistry. I saw no reason why we couldn't.", "Gertrude Elion" }, - { "The Nobel Prize is fine, but the drugs I've developed are rewards in themselves.", "Gertrude Elion" }, + { "What about my nose?", + "Aneesur Rahman, responding to an Argonne manager arguing the long hair of Charles " + "Bennett in his group was disreputing the lab; Retold by Michael Klein" }, + { "Science, my lad, is made up of mistakes, but they are mistakes which it is useful to " + "make, because they lead little by little to the truth.", + "Jules Verne" }, + { "Don't be afraid of hard work. Nothing worthwhile comes easily. Don't let others " + "discourage you or tell you that you can't do it. In my day I was told women didn't go " + "into chemistry. I saw no reason why we couldn't.", + "Gertrude Elion" }, + { "The Nobel Prize is fine, but the drugs I've developed are rewards in themselves.", + "Gertrude Elion" }, { "...sometimes a scream is better than a thesis.", "Ralph Waldo Emerson" }, - { "The great tragedy of science - the slaying of a beautiful hypothesis by an ugly fact.", "Thomas Henry Huxley" }, - { "Dr Pauling, how do you have so many good ideas? Well David, I have a lot of ideas and throw away the bad ones.", "Linus Pauling" }, - { "I try to identify myself with the atoms... I ask what I would do If I were a carbon atom or a sodium atom.", "Linus Pauling" }, - { "I admired Bohr very much. We had long talks together, long talks in which Bohr did practically all the talking.", "Paul Dirac" }, + { "The great tragedy of science - the slaying of a beautiful hypothesis by an ugly fact.", + "Thomas Henry Huxley" }, + { "Dr Pauling, how do you have so many good ideas? Well David, I have a lot of ideas and " + "throw away the bad ones.", + "Linus Pauling" }, + { "I try to identify myself with the atoms... I ask what I would do If I were a carbon " + "atom or a sodium atom.", + "Linus Pauling" }, + { "I admired Bohr very much. We had long talks together, long talks in which Bohr did " + "practically all the talking.", + "Paul Dirac" }, { "Predictions can be very difficult - especially about the future.", "Niels Bohr" }, - { "For those who want some proof that physicists are human, the proof is in the idiocy of all the different units which they use for measuring energy.", "Richard Feynman" }, + { "For those who want some proof that physicists are human, the proof is in the idiocy of " + "all the different units which they use for measuring energy.", + "Richard Feynman" }, { "Dreams seldom materialize on their own.", "Dian Fossey" }, - { "Above all, don't fear difficult moments. The best comes from them.", "Rita Levi-Montalcini" }, - { "Our struggle today is not to have a female Einstein get appointed as an assistant professor. It is for a woman schlemiel to get as quickly promoted as a male schlemiel.", "Bella Abzug" }, - { "I never thought of stopping, and I just hated sleeping. I can't imagine having a better life.", "Barbara McClintock" }, - { "The farther the experiment is from theory, the closer it is to the Nobel Prize.", "Irene Joliot-Curie" }, + { "Above all, don't fear difficult moments. The best comes from them.", + "Rita Levi-Montalcini" }, + { "Our struggle today is not to have a female Einstein get appointed as an assistant " + "professor. It is for a woman schlemiel to get as quickly promoted as a male schlemiel.", + "Bella Abzug" }, + { "I never thought of stopping, and I just hated sleeping. I can't imagine having a better " + "life.", + "Barbara McClintock" }, + { "The farther the experiment is from theory, the closer it is to the Nobel Prize.", + "Irene Joliot-Curie" }, { "I never see what has been done; I only see what remains to be done.", "Marie Curie" }, - { "There is no reason for any individual to have a computer in his home.", "Ken Olsen, head of Digital Equipment Corp." }, - { "People disagree with me. I just ignore them.", "Linus Torvalds on the use of C++ in the kernel" }, - { "Beware of bugs in the above code; I have only proved it correct, not tried it.", "Donald Knuth" }, - { "My greatest contribution to the field of science is that I never entered it.", "Colin Powell" }, - { "We are perhaps not far removed from the time when we shall be able to submit the bulk of chemical phenomena to calculation.", "Joseph Gay-Lussac, 1808" }, - { "If mathematical analysis should ever hold a prominent place in chemistry - an aberration which is happily almost impossible - it would occasion a rapid and widespread degeneration of that science.", "Aguste Comte, 1830" }, - { "Almost without exception, the talented women I have known have believed they had less ability than they actually had. And almost without exception, the talented men I have known believed they had more.", "Gregory Petsko" }, - { "The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.", "Tom Cargill" }, + { "There is no reason for any individual to have a computer in his home.", + "Ken Olsen, head of Digital Equipment Corp." }, + { "People disagree with me. I just ignore them.", + "Linus Torvalds on the use of C++ in the kernel" }, + { "Beware of bugs in the above code; I have only proved it correct, not tried it.", + "Donald Knuth" }, + { "My greatest contribution to the field of science is that I never entered it.", + "Colin Powell" }, + { "We are perhaps not far removed from the time when we shall be able to submit the bulk " + "of chemical phenomena to calculation.", + "Joseph Gay-Lussac, 1808" }, + { "If mathematical analysis should ever hold a prominent place in chemistry - an " + "aberration which is happily almost impossible - it would occasion a rapid and " + "widespread degeneration of that science.", + "Aguste Comte, 1830" }, + { "Almost without exception, the talented women I have known have believed they had less " + "ability than they actually had. And almost without exception, the talented men I have " + "known believed they had more.", + "Gregory Petsko" }, + { "The first 90% of the code accounts for the first 90% of the development time. The " + "remaining 10% of the code accounts for the other 90% of the development time.", + "Tom Cargill" }, { "The Internet? We are not interested in it.", "Bill Gates, 1993" }, - { "Perl: The only language that looks the same before and after RSA encryption.", "Keith Bostic" }, - { "There are only two things wrong with C++: The initial concept and the implementation.", "Bertrand Meyer" }, - { "XML is not a language in the sense of a programming language any more than sketches on a napkin are a language.", "Charles Simonyi" }, - { "It has been discovered that C++ provides a remarkable facility for concealing the trivial details of a program - such as where its bugs are.", "David Keppel" }, - { "UNIX is basically a simple operating system. It just takes a genius to understand its simplicity.", "Dennis Ritchie" }, - { "There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence.", "Jeremy Anderson" }, - { "There are only two kinds of programming languages: those people always bitch about and those nobody uses.", "Bjarne Stroustrup" }, - { "If Java had true garbage collection, most programs would delete themselves upon execution.", "Robert Sewell" }, - { "Documentation is like sex: When it's good it's great, and when it's bad it's better than nothing.", "Linus Torvalds" }, - { "C has the power of assembly language and the convenience of... assembly language.", "Dennis Ritchie" }, - { "The last good thing written in C was Franz Schubert's Symphony Number 9.", "Erwin Dieterich" }, + { "Perl: The only language that looks the same before and after RSA encryption.", + "Keith Bostic" }, + { "There are only two things wrong with C++: The initial concept and the implementation.", + "Bertrand Meyer" }, + { "XML is not a language in the sense of a programming language any more than sketches on " + "a napkin are a language.", + "Charles Simonyi" }, + { "It has been discovered that C++ provides a remarkable facility for concealing the " + "trivial details of a program - such as where its bugs are.", + "David Keppel" }, + { "UNIX is basically a simple operating system. It just takes a genius to understand its " + "simplicity.", + "Dennis Ritchie" }, + { "There are two major products that come out of Berkeley: LSD and UNIX. We don't believe " + "this to be a coincidence.", + "Jeremy Anderson" }, + { "There are only two kinds of programming languages: those people always bitch about and " + "those nobody uses.", + "Bjarne Stroustrup" }, + { "If Java had true garbage collection, most programs would delete themselves upon " + "execution.", + "Robert Sewell" }, + { "Documentation is like sex: When it's good it's great, and when it's bad it's better " + "than nothing.", + "Linus Torvalds" }, + { "C has the power of assembly language and the convenience of... assembly language.", + "Dennis Ritchie" }, + { "The last good thing written in C was Franz Schubert's Symphony Number 9.", + "Erwin Dieterich" }, { "User-friendly, adj.: Programmer-hostile.", "New Hacker's Dictionary" }, - { "First off, I'd suggest printing out a copy of the GNU coding standards, and NOT read it. Burn them, it's a great symbolic gesture.", "Linus Torvalds" }, - { "I invented the term 'Object-Oriented', and I can tell you I did not have C++ in mind.", "Alay Kay, author of Smalltalk" }, - { "FORTRAN, the infantile disorder, by now nearly 20 years old, is hopelessly inadequate for whatever computer application you have in mind today: it is now too clumsy, too risky, and too expensive to use.", "Edsger Dijkstra, 1970" }, - { "Do you know what cations don't like? Dog-ions. Do you know what they like? Pie.", "Tom Cheatham" }, - { "The most exciting phrase to hear in science, the one that heralds new discoveries, is not \"Eureka\" but \"That's funny...\".", "Isaac Asimov" }, - { "Those people who think they know everything are a great annoyance to those of us who do.", "Isaac Asimov" }, + { "First off, I'd suggest printing out a copy of the GNU coding standards, and NOT read " + "it. Burn them, it's a great symbolic gesture.", + "Linus Torvalds" }, + { "I invented the term 'Object-Oriented', and I can tell you I did not have C++ in mind.", + "Alay Kay, author of Smalltalk" }, + { "FORTRAN, the infantile disorder, by now nearly 20 years old, is hopelessly inadequate " + "for whatever computer application you have in mind today: it is now too clumsy, too " + "risky, and too expensive to use.", + "Edsger Dijkstra, 1970" }, + { "Do you know what cations don't like? Dog-ions. Do you know what they like? Pie.", + "Tom Cheatham" }, + { "The most exciting phrase to hear in science, the one that heralds new discoveries, is " + "not \"Eureka\" but \"That's funny...\".", + "Isaac Asimov" }, + { "Those people who think they know everything are a great annoyance to those of us who " + "do.", + "Isaac Asimov" }, { "No great discovery was ever made without a bold guess.", "Marie Curie" }, { "Chance favors the prepared mind.", "Louis Pasteur" }, - { "I love deadlines. I like the whooshing sound they make as they fly by.", "Douglas Adams" }, - { "Good judgement is the result of experience; experience is the result of bad judgement.", "Mark Twain" }, + { "I love deadlines. I like the whooshing sound they make as they fly by.", + "Douglas Adams" }, + { "Good judgement is the result of experience; experience is the result of bad judgement.", + "Mark Twain" }, { "No matter how important you are, you are not as important as lunch.", "Randy Pausch" }, - { "There is just one thing I can promise you about the outer-space program: your tax dollar will go farther.", "Wernher von Braun" }, + { "There is just one thing I can promise you about the outer-space program: your tax " + "dollar will go farther.", + "Wernher von Braun" }, { "Harvard makes mistakes too, you know. Kissinger taught there.", "Woody Allen" }, - { "Nothing in biology makes sense except in the light of evolution.", "Theodosius Dobzhansky" }, - { "I have a hunch that the unknown sequences of DNA will decode into copyright notices and patent protections.", "Donald Knuth" }, - { "It always takes longer than you think even when you take Hofstadter's Law into account.", "Hofstadter's Law" }, - { "A ship in port is safe, but that is not what ships are for. Sail out to sea and do new things.", "Grace Hopper, developer of COBOL" }, - { "I was told I'd never make it to VP rank because I was too outspoken. Maybe so, but I think men will always find an excuse for keeping women in their 'place.' So, let's make that place the executive suite and start more of our own companies.", "Jean Bartik, ENIAC developer" }, - { "If it's a good idea, go ahead and do it. It's much easier to apologize than it is to get permission.", "Grace Hopper, developer of COBOL" }, + { "Nothing in biology makes sense except in the light of evolution.", + "Theodosius Dobzhansky" }, + { "I have a hunch that the unknown sequences of DNA will decode into copyright notices and " + "patent protections.", + "Donald Knuth" }, + { "It always takes longer than you think even when you take Hofstadter's Law into account.", + "Hofstadter's Law" }, + { "A ship in port is safe, but that is not what ships are for. Sail out to sea and do new " + "things.", + "Grace Hopper, developer of COBOL" }, + { "I was told I'd never make it to VP rank because I was too outspoken. Maybe so, but I " + "think men will always find an excuse for keeping women in their 'place.' So, let's make " + "that place the executive suite and start more of our own companies.", + "Jean Bartik, ENIAC developer" }, + { "If it's a good idea, go ahead and do it. It's much easier to apologize than it is to " + "get permission.", + "Grace Hopper, developer of COBOL" }, { "This isn't right. This isn't even wrong.", "Wolfgang Pauli" }, - { "Louis Pasteur's theory of germs is ridiculous fiction.", "Pierre Pachet, Professor of Physiology at Toulouse, 1872" }, - { "Research ! A mere excuse for idleness; it has never achieved, and will never achieve any results of the slightest value.", "Benjamin Jowett, British theologian, 1817-93" }, + { "Louis Pasteur's theory of germs is ridiculous fiction.", + "Pierre Pachet, Professor of Physiology at Toulouse, 1872" }, + { "Research ! A mere excuse for idleness; it has never achieved, and will never achieve " + "any results of the slightest value.", + "Benjamin Jowett, British theologian, 1817-93" }, { "Problems worthy of attack prove their worth by hitting back.", "Piet Hein" }, - { "You should never bet against anything in science at odds of more than about 10^12 to 1.", "Ernest Rutherford" }, + { "You should never bet against anything in science at odds of more than about 10^12 to 1.", + "Ernest Rutherford" }, { "X-rays will prove to be a hoax.", "Lord Kelvin, while president of the Royal Society" }, { "If you're doing I/O, you're doing it wrong!", "Cannada \"Drew\" Lewis" }, { "The easiest way to scale well is to have bad single-core performance", "Blind Freddie" }, - { "Heard a talk introducing a new language called Swift, from a guy named Wozniak, and it had nothing to do with Apple!", "Adam Cadien" }, + { "Heard a talk introducing a new language called Swift, from a guy named Wozniak, and it " + "had nothing to do with Apple!", + "Adam Cadien" }, { "When doing HPC, don't communica", "Jim Demmel" }, - { "Today we're not going to optimize our CUDA code, cause that's just a rabbit hole of misery!", "Tim Warburton" }, - { "Big Data is like teenage sex: everyone talks about it, nobody really knows how to do it, everyone thinks everyone else is doing it, so everyone claims they are doing it...", "Dan Ariely" }, - { "It seems likely that significant software contributions to existing scientific software projects are not likely to be rewarded through the traditional reputation economy of science. Together these factors provide a reason to expect the over-production of independent scientific software packages, and the underproduction of collaborative projects in which later academics build on the work of earlier ones.", "Howison & Herbsleb" }, - { "On average, it takes twenty years for the world's largest super computer to shrink down to the size of your laptop.", "Pete Beckman" }, - { "When using an abacus, a human can achieve about 0.1 flops/watt. Super-computers achieve about 2 gigaflops/watt.", "John Linford" }, + { "Today we're not going to optimize our CUDA code, cause that's just a rabbit hole of " + "misery!", + "Tim Warburton" }, + { "Big Data is like teenage sex: everyone talks about it, nobody really knows how to do " + "it, everyone thinks everyone else is doing it, so everyone claims they are doing it...", + "Dan Ariely" }, + { "It seems likely that significant software contributions to existing scientific software " + "projects are not likely to be rewarded through the traditional reputation economy of " + "science. Together these factors provide a reason to expect the over-production of " + "independent scientific software packages, and the underproduction of collaborative " + "projects in which later academics build on the work of earlier ones.", + "Howison & Herbsleb" }, + { "On average, it takes twenty years for the world's largest super computer to shrink down " + "to the size of your laptop.", + "Pete Beckman" }, + { "When using an abacus, a human can achieve about 0.1 flops/watt. Super-computers achieve " + "about 2 gigaflops/watt.", + "John Linford" }, { "Try to calculate the numbers that have been", "The Smoke Fairies" }, { "Please implement proper hep writing", "GROMACS" }, - { "The three principal virtues of a programmer are Laziness, Impatience, and Hubris", "Larry Wall" }, - { "You're like them scientists on TV explaining black holes. More you talk, less I get", "Jess Walter" }, - { "Wedged as we are between two eternities of idleness, there is no excuse for being idle now", "Anthony Burgess" }, - { "Even the *healthy* people move in clouds of cigarette smoke, women straining polyester, men in raggedly cutoffs slathering mayonnaise on foot-long hot dogs. It's as if the hotel were hosting a conference on adult onset diabetes", "Jess Walter" }, - { "In practice, throwing traditional norms and values overboard results not in perfect freedom and relationships based on reason, but in chaos and fear", "Paul Verhaeghe" }, - { "When I asked a younger colleague at the university how he had been able to change his research field several times within a decade or so, he answered: \"It's just a question of new software\"", "Paul Verhaeghe" }, + { "The three principal virtues of a programmer are Laziness, Impatience, and Hubris", + "Larry Wall" }, + { "You're like them scientists on TV explaining black holes. More you talk, less I get", + "Jess Walter" }, + { "Wedged as we are between two eternities of idleness, there is no excuse for being idle " + "now", + "Anthony Burgess" }, + { "Even the *healthy* people move in clouds of cigarette smoke, women straining polyester, " + "men in raggedly cutoffs slathering mayonnaise on foot-long hot dogs. It's as if the " + "hotel were hosting a conference on adult onset diabetes", + "Jess Walter" }, + { "In practice, throwing traditional norms and values overboard results not in perfect " + "freedom and relationships based on reason, but in chaos and fear", + "Paul Verhaeghe" }, + { "When I asked a younger colleague at the university how he had been able to change his " + "research field several times within a decade or so, he answered: \"It's just a question " + "of new software\"", + "Paul Verhaeghe" }, { "Never mind, death professor, your structure's fine", "TV on the Radio" }, { "Come and play on the hospital roof, I got something that's yours", "Sherlock" }, { "Njuta men inte frossa, springa men inte fly", "Paganus" }, { "Misslycka kan man med all kod", "Mats Nylen" }, - { "Two guys can move very fast when they're motivated enough and unemployed", "Eric Betzig" }, + { "Two guys can move very fast when they're motivated enough and unemployed", + "Eric Betzig" }, { "A protein is a chain of letters.", "Julie Bernauer" }, - { "The best way to obtain plausible negative examples is to run a docking program with a biophysics-based function.", "Julie Bernauer" }, + { "The best way to obtain plausible negative examples is to run a docking program with a " + "biophysics-based function.", + "Julie Bernauer" }, { "I think everybody should like everybody.", "Andy Warhol" }, { "But I always say, one's company, two's a crowd, and three's a party.", "Andy Warhol" }, - { "We'll celebrate a woman for anything, as long as it's not her talent.", "Colleen McCullough" }, - { "I believe the big bang of self-driving cars is about to come.", "Jen-Hsun Huang, CEO NVIDIA" }, - { "This is where we have been working hard to push down performance.", "Szilard Pall, GTC 2015 talk" }, + { "We'll celebrate a woman for anything, as long as it's not her talent.", + "Colleen McCullough" }, + { "I believe the big bang of self-driving cars is about to come.", + "Jen-Hsun Huang, CEO NVIDIA" }, + { "This is where we have been working hard to push down performance.", + "Szilard Pall, GTC 2015 talk" }, { "Some of these pro-drug messages come from popular culture.", "John Walters" }, - { "Don't pay any attention to what they write about you. Just measure it in inches.", "Andy Warhol" }, + { "Don't pay any attention to what they write about you. Just measure it in inches.", + "Andy Warhol" }, { "Art is what you can get away with.", "Andy Warhol" }, - { "I spent a lot of money on booze, birds and fast cars. The rest I just squandered.", "George Best" }, + { "I spent a lot of money on booze, birds and fast cars. The rest I just squandered.", + "George Best" }, { "The only greatness for man is immortality.", "James Dean" }, - { "Do not quench your inspiration and your imagination; do not become the slave of your model.", "Vincent Van Gogh" }, + { "Do not quench your inspiration and your imagination; do not become the slave of your " + "model.", + "Vincent Van Gogh" }, { "You always pass failure on the way to success.", "Mickey Rooney" }, - { "I always seem to get inspiration and renewed vitality by contact with this great novel land of yours which sticks up out of the Atlantic.", "Winston Churchill" }, + { "I always seem to get inspiration and renewed vitality by contact with this great novel " + "land of yours which sticks up out of the Atlantic.", + "Winston Churchill" }, { "I am at two with nature.", "Woody Allen" }, { "I'm no model lady. A model's just an imitation of the real thing.", "Mae West" }, - { "Science is the great antidote to the poison of enthusiasm and superstition.", "Adam Smith, Wealth of Nations, 1776" }, - { "Science is a wonderful thing if one does not have to earn one's living at it.", "Albert Einstein" }, + { "Science is the great antidote to the poison of enthusiasm and superstition.", + "Adam Smith, Wealth of Nations, 1776" }, + { "Science is a wonderful thing if one does not have to earn one's living at it.", + "Albert Einstein" }, { "Science is the record of dead religions.", "Oscar Wilde" }, - { "Physics isn't a religion. If it were, we'd have a much easier time raising money.", "Leon Lederman" }, - { "It is now quite lawful for a Catholic woman to avoid pregnancy by a resort to mathematics, though she is still forbidden to resort to physics and chemistry.", "Henry Louis Mencken" }, - { "An expert is a person who has made all the mistakes that can be made in a very narrow field.", "Niels Bohr" }, - { "In my opinion, we don't devote nearly enough scientific research to finding a cure for jerks.", "Bill Watterson" }, - { "Scientists do not join hands every Sunday and sing \"Yes gravity is real! I know gravity is real! I will have faith! I believe in my heart that what goes up, up, up must come down, down, down. Amen!\" If they did, we would think they were pretty insecure about the concept.", "Dan Barker" }, + { "Physics isn't a religion. If it were, we'd have a much easier time raising money.", + "Leon Lederman" }, + { "It is now quite lawful for a Catholic woman to avoid pregnancy by a resort to " + "mathematics, though she is still forbidden to resort to physics and chemistry.", + "Henry Louis Mencken" }, + { "An expert is a person who has made all the mistakes that can be made in a very narrow " + "field.", + "Niels Bohr" }, + { "In my opinion, we don't devote nearly enough scientific research to finding a cure for " + "jerks.", + "Bill Watterson" }, + { "Scientists do not join hands every Sunday and sing \"Yes gravity is real! I know " + "gravity is real! I will have faith! I believe in my heart that what goes up, up, up " + "must come down, down, down. Amen!\" If they did, we would think they were pretty " + "insecure about the concept.", + "Dan Barker" }, { "Take away paradox from the thinker and you have a professor.", "Soren Kirkegaard" }, - { "Measuring programming progress by lines of code is like measuring aircraft building progress by weight.", "Bill Gates" }, + { "Measuring programming progress by lines of code is like measuring aircraft building " + "progress by weight.", + "Bill Gates" }, { "Protons give an atom its identity, electrons its personality.", "Bill Bryson" }, - { "Money won't buy happiness, but it will pay the salaries of a large research staff to study the problem.", "Bill Vaughan" }, + { "Money won't buy happiness, but it will pay the salaries of a large research staff to " + "study the problem.", + "Bill Vaughan" }, { "Torture numbers, and they'll confess to anything.", "Greg Easterbrook" }, - { "Should we force science down the throats of those that have no taste for it? Is it our duty to drag them kicking and screaming into the twenty-first century? I am afraid that it is.", "George Porter" }, - { "A computer would deserve to be called intelligent if it could deceive a human into believing that it was human.", "Alan Turing" }, - { "Any one who considers arithmetical methods of producing random digits is, of course, in a state of sin.", "John von Neumann" }, + { "Should we force science down the throats of those that have no taste for it? Is it our " + "duty to drag them kicking and screaming into the twenty-first century? I am afraid that " + "it is.", + "George Porter" }, + { "A computer would deserve to be called intelligent if it could deceive a human into " + "believing that it was human.", + "Alan Turing" }, + { "Any one who considers arithmetical methods of producing random digits is, of course, in " + "a state of sin.", + "John von Neumann" }, { "No, no, you're not thinking, you're just being logical.", "Niels Bohr" }, - { "As an adolescent I aspired to lasting fame, I craved factual certainty, and I thirsted for a meaningful vision of human life -- so I became a scientist. This is like becoming an archbishop so you can meet girls.", "Matt Cartmill" }, + { "As an adolescent I aspired to lasting fame, I craved factual certainty, and I thirsted " + "for a meaningful vision of human life -- so I became a scientist. This is like becoming " + "an archbishop so you can meet girls.", + "Matt Cartmill" }, { "Problems worthy / of attack / prove their worth / by hitting back.", "Piet Hein" }, { "Naive you are if you believe life favours those who aren't naive.", "Piet Hein" }, - { "Never measure the height of a mountain until you have reached the top. Then you will see how low it was.", "Dag Hammarskjold" }, + { "Never measure the height of a mountain until you have reached the top. Then you will " + "see how low it was.", + "Dag Hammarskjold" }, { "Praise those of your critics for whom nothing is up to standard.", "Dag Hammarskjold" }, - { "Inventions have long since reached their limit, and I see no hope for further development.", "Julius Sextus Frontinus, 1st century A.D." }, + { "Inventions have long since reached their limit, and I see no hope for further " + "development.", + "Julius Sextus Frontinus, 1st century A.D." }, { "Lottery: A tax on people who are bad at math.", "Ambrose Bierce" }, - { "Even if you are on the right track, you will get run over if you just sit there.", "Will Rogers" }, - { "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning.", "Rick Cook" }, - { "There's a limit to how many times you can read how great you are and what an inspiration you are, but I'm not there yet.", "Randy Pausch" }, - { "Throughout my academic career, I'd given some pretty good talks. But being considered the best speaker in the computer science department is like being known as the tallest of the Seven Dwarfs.", "Randy Pausch" }, - { "If everything seems under control, you're just not going fast enough.", "Mario Andretti" }, - { "Sincerity is the key to success. Once you can fake that you've got it made.", "Groucho Marx" }, - { "This work contains many things which are new and interesting. Unfortunately, everything that is new is not interesting, and everything which is interesting, is not new.", "Lev Landau" }, + { "Even if you are on the right track, you will get run over if you just sit there.", + "Will Rogers" }, + { "Programming today is a race between software engineers striving to build bigger and " + "better idiot-proof programs, and the universe trying to build bigger and better idiots. " + "So far, the universe is winning.", + "Rick Cook" }, + { "There's a limit to how many times you can read how great you are and what an " + "inspiration you are, but I'm not there yet.", + "Randy Pausch" }, + { "Throughout my academic career, I'd given some pretty good talks. But being considered " + "the best speaker in the computer science department is like being known as the tallest " + "of the Seven Dwarfs.", + "Randy Pausch" }, + { "If everything seems under control, you're just not going fast enough.", + "Mario Andretti" }, + { "Sincerity is the key to success. Once you can fake that you've got it made.", + "Groucho Marx" }, + { "This work contains many things which are new and interesting. Unfortunately, everything " + "that is new is not interesting, and everything which is interesting, is not new.", + "Lev Landau" }, { "Does college pay? They do if you are a good open-field runner.", "Will Rogers" }, - { "Academe, n.: An ancient school where morality and philosophy were taught. Academy, n.: A modern school where football is taught.", "Ambrose Bierce" }, - { "This simulation is not as the former.", "Malvolio, Act II, scene V of Shaphespeare's Twelfth Night" }, + { "Academe, n.: An ancient school where morality and philosophy were taught. Academy, n.: " + "A modern school where football is taught.", + "Ambrose Bierce" }, + { "This simulation is not as the former.", + "Malvolio, Act II, scene V of Shaphespeare's Twelfth Night" }, { "Here, kitty, kitty...", "Erwin Schroedinger" }, - { "Sir, spare your threats: The bug which you would fright me with I seek.", "Hermione, Act III, scene II of Shakespeare's Winter's Tale" }, - { "Erwin with his psi can do / Calculations quite a few. / But one thing has not been seen / Just what psi really mean.", "Felix Bloch" }, + { "Sir, spare your threats: The bug which you would fright me with I seek.", + "Hermione, Act III, scene II of Shakespeare's Winter's Tale" }, + { "Erwin with his psi can do / Calculations quite a few. / But one thing has not been seen " + "/ Just what psi really mean.", + "Felix Bloch" }, { "Only entropy comes easy.", "Anton Chekov" }, - { "The loveliest theories are being overthrown by these damned experiments; it is no fun being a chemist any more.", "Justus von Liebig, letter to J.J. Berzelius 1834" }, - { "If all else fails, immortality can always be assured by spectacular error.", "John Kenneth Galbraith" }, - { "Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.", "Martin Golding" }, - { "If I have not seen as far as others, it is because giants were standing on my shoulders.", "Hal Abelson" }, - { "Weaseling out of things is important to learn. It's what separates us from the animals... except the weasels.", "Homer Simpson" }, + { "The loveliest theories are being overthrown by these damned experiments; it is no fun " + "being a chemist any more.", + "Justus von Liebig, letter to J.J. Berzelius 1834" }, + { "If all else fails, immortality can always be assured by spectacular error.", + "John Kenneth Galbraith" }, + { "Always code as if the person who ends up maintaining your code is a violent psychopath " + "who knows where you live.", + "Martin Golding" }, + { "If I have not seen as far as others, it is because giants were standing on my " + "shoulders.", + "Hal Abelson" }, + { "Weaseling out of things is important to learn. It's what separates us from the " + "animals... except the weasels.", + "Homer Simpson" }, { "In science, truth always wins.", "Max Perutz" }, - { "Creativity in science, as in art, cannot be organized. It arises spontaneously from individual talent. Well-run laboratories can foster it, but hierarchical organizations, inflexible bureaucratic rules, and mountains of futile paperwork can kill it.", "Max Perutz" }, + { "Creativity in science, as in art, cannot be organized. It arises spontaneously from " + "individual talent. Well-run laboratories can foster it, but hierarchical organizations, " + "inflexible bureaucratic rules, and mountains of futile paperwork can kill it.", + "Max Perutz" }, { "Every electron is sacred.", "Greg McMullan, on Cryo-EM detectors" }, - { "Science adjusts its views based on what's observed. Faith is the denial of observation so that belief can be preserved.", "Tim Minchin" }, - { "Isn't this enough? Just this world? Just this beautiful, complex wonderfully unfathomable world? How does it so fail to hold our attention that we have to diminish it with the invention of cheap, man-made myths and monsters?", "Tim Minchin" }, + { "Science adjusts its views based on what's observed. Faith is the denial of observation " + "so that belief can be preserved.", + "Tim Minchin" }, + { "Isn't this enough? Just this world? Just this beautiful, complex wonderfully " + "unfathomable world? How does it so fail to hold our attention that we have to diminish " + "it with the invention of cheap, man-made myths and monsters?", + "Tim Minchin" }, { "If you open your mind too much, your brains will fall out.", "Tim Minchin" }, - { "\"Everything organic and natural is good\" - ignoring the fact that organic natural substances include arsenic and poo and crocodiles. And everything chemical is bad, ignoring the fact that... everything is chemicals.", "Tim Minchin" }, + { "\"Everything organic and natural is good\" - ignoring the fact that organic natural " + "substances include arsenic and poo and crocodiles. And everything chemical is bad, " + "ignoring the fact that... everything is chemicals.", + "Tim Minchin" }, { "A program that has not been tested does not work.", "Bjarne Stroustrup" }, - { "You could give Aristotle a tutorial. And you could thrill him to the core of his being. Such is the privilege of living after Newton, Darwin, Einstein, Planck, Watson, Crick and their colleagues.", "Richard Dawkins" }, - { "A robot will be truly autonomous when you instruct it to go to work and it decides to go to the beach instead.", "Brad Templeton" }, + { "You could give Aristotle a tutorial. And you could thrill him to the core of his being. " + "Such is the privilege of living after Newton, Darwin, Einstein, Planck, Watson, Crick " + "and their colleagues.", + "Richard Dawkins" }, + { "A robot will be truly autonomous when you instruct it to go to work and it decides to " + "go to the beach instead.", + "Brad Templeton" }, { "If you want to destroy my sweater, hold this thread as I walk away.", "Weezer" }, { "To survive science you have to become science.", "Gerrit Groenhof" }, { "Contemplating answers that could break my bonds.", "Peter Hammill" }, - { "I always think there is something foreign about jolly phrases at breakfast.", "Mr. Carson in Downtown Abbey" }, + { "I always think there is something foreign about jolly phrases at breakfast.", + "Mr. Carson in Downtown Abbey" }, { "According to my computations we're overdue for a transformation.", "Jackson Browne" }, - { "Therefore, things must be learned only to be unlearned again or, more likely, to be corrected.", "Richard Feynman" }, - { "You wouldn't walk into a chemistry lab and mix two clear liquids together just because they look pretty much the same, would you?", "Justin Lemkul" }, + { "Therefore, things must be learned only to be unlearned again or, more likely, to be " + "corrected.", + "Richard Feynman" }, + { "You wouldn't walk into a chemistry lab and mix two clear liquids together just because " + "they look pretty much the same, would you?", + "Justin Lemkul" }, { "They don't have half hours in the north", "Carl Caleman" }, { "Safety lights are for dudes", "Ghostbusters 2016" }, - { "It's 2040 now. Our President is a plant.", "Ghostbusters 2016" }, + { "It's 2040 now. Our President is a plant.", "Ghostbusters 2016" }, { "It's just B I O L O G Y, can't you see?", "Joe Jackson" }, { "Input, output, electricity", "Joni Mitchell" }, { "Your daddy ain't your daddy but your daddy don't know", "Dalahan" }, - { "Why is the Earth moving 'round the sun? Floating in the vacuum with no purpose, not a one", "Fleet Foxes" }, + { "Why is the Earth moving 'round the sun? Floating in the vacuum with no purpose, not a " + "one", + "Fleet Foxes" }, { "Everybody has a plan until they get punched in the mouth", "Mike Tyson" }, - { "Sacrifices must be made", "Otto Lilienthal, dying after having crashed with his glider in 1896" }, + { "Sacrifices must be made", + "Otto Lilienthal, dying after having crashed with his glider in 1896" }, { "The secret to getting ahead is getting started", "Mark Twain" }, { "Water is just water", "Berk Hess" }, { "GROMACS First : Making MD Great Again", "Vedran Miletic" }, { "You still have to climb to the shoulders of the giants", "Vedran Miletic" }, { "The road to openness is paved with git commits", "Vedran Miletic" }, - { "Performance and power are great targets for tuning, but really you want to tune for money!", "Erik Lindahl" }, + { "Performance and power are great targets for tuning, but really you want to tune for " + "money!", + "Erik Lindahl" }, { "Here are all the 'gmx' tools... but no gmx writethesis", "Christian Blau" }, { "The best part of winter in Stockholm is going to Australia", "Mark Abraham" }, { "If you don't know what you're doing, use a (M)BAR-based method", "Erik Lindahl" }, { "All models are wrong, but some are useful.", "George Box" }, - { "If your experiment needs a statistician, you need a better experiment.", "Ernest Rutherford" }, + { "If your experiment needs a statistician, you need a better experiment.", + "Ernest Rutherford" }, { "Facts are stubborn things, but statistics are more pliable.", "Laurence Peter" }, - { "In ancient times they had no statistics so they had to fall back on lies.", "Stephen Leacock" }, - { "If at first you don't succeed, try two more times so that your failure is statistically significant.", "Dallas Warren" }, + { "In ancient times they had no statistics so they had to fall back on lies.", + "Stephen Leacock" }, + { "If at first you don't succeed, try two more times so that your failure is statistically " + "significant.", + "Dallas Warren" }, { "Your theory is crazy, but it's not crazy enough to be true.", "Niels Bohr" }, - { "Science may never come up with a better office communication system than the coffee break.", "Earl Wilson" }, - { "A scientific truth does not triumph by convincing its opponents and making them see the light, but rather because its opponents eventually die and a new generation grows up that is familiar with it.", "Max Planck" }, - { "Computer science is no more about computers than astronomy is about telescopes", "Edsger Dijkstra" }, - { "If we knew what it was we were doing, it would not be called research, would it?", "Albert Einstein" }, + { "Science may never come up with a better office communication system than the coffee " + "break.", + "Earl Wilson" }, + { "A scientific truth does not triumph by convincing its opponents and making them see the " + "light, but rather because its opponents eventually die and a new generation grows up " + "that is familiar with it.", + "Max Planck" }, + { "Computer science is no more about computers than astronomy is about telescopes", + "Edsger Dijkstra" }, + { "If we knew what it was we were doing, it would not be called research, would it?", + "Albert Einstein" }, { "I have not failed. I've just found 10,000 ways that won't work", "Thomas Alva Edison" }, - { "The public have an insatiable curiosity to know everything, except what is worth knowing.", "Oscar Wilde" }, - { "Philosophy of science is about as useful to scientists as ornithology is to birds.", "Richard Feynman" }, - { "I had trouble with physics in college. When I signed up I thought it said psychics.", "Greg Tamblyn" }, - { "There's an old saying among scientific guys: “You can't make an omelet without breaking eggs, ideally by dropping a cement truck on them from a crane.", "Dave Barry" }, - { "Occams Razor is the scientific principle that, all things being equal, the simplest explanation is always the dog ate my homework.", "Greg Tamblyn" }, - { "When you get right down to it, almost every explanation Man came up with for anything until about 1926 was stupid.", "Dave Barry" }, - { "We all understand the twinge of discomfort at the thought that we share a common ancestor with the apes. No one can embarrass you like a relative.", "Neal DeGrasse Tyson" }, - { "In physics, you don't have to go around making trouble for yourself. Nature does it for you.", "Frank Wilczek" }, - { "Every revolutionary idea seems to evoke three stages of reaction. They may be summed up by the phrases: (1) It's completely impossible. (2) It's possible, but not worth doing. (3) I said it was a good idea all along.", "Arthur C. Clarke" }, + { "The public have an insatiable curiosity to know everything, except what is worth " + "knowing.", + "Oscar Wilde" }, + { "Philosophy of science is about as useful to scientists as ornithology is to birds.", + "Richard Feynman" }, + { "I had trouble with physics in college. When I signed up I thought it said psychics.", + "Greg Tamblyn" }, + { "There's an old saying among scientific guys: “You can't make an omelet without breaking " + "eggs, ideally by dropping a cement truck on them from a crane.", + "Dave Barry" }, + { "Occams Razor is the scientific principle that, all things being equal, the simplest " + "explanation is always the dog ate my homework.", + "Greg Tamblyn" }, + { "When you get right down to it, almost every explanation Man came up with for anything " + "until about 1926 was stupid.", + "Dave Barry" }, + { "We all understand the twinge of discomfort at the thought that we share a common " + "ancestor with the apes. No one can embarrass you like a relative.", + "Neal DeGrasse Tyson" }, + { "In physics, you don't have to go around making trouble for yourself. Nature does it for " + "you.", + "Frank Wilczek" }, + { "Every revolutionary idea seems to evoke three stages of reaction. They may be summed up " + "by the phrases: (1) It's completely impossible. (2) It's possible, but not worth doing. " + "(3) I said it was a good idea all along.", + "Arthur C. Clarke" }, { "Computers are like humans - they do everything except think.", "John von Neumann" }, - { "With four parameters I can fit an elephant, and with five I can make him wiggle his trunk.", "John von Neumann" }, - { "Christianity may be OK between consenting adults in private but should not be taught to young children.", "Francis Crick" }, - { "All approaches at a higher level are suspect until confirmed at the molecular level.", "Francis Crick" }, + { "With four parameters I can fit an elephant, and with five I can make him wiggle his " + "trunk.", + "John von Neumann" }, + { "Christianity may be OK between consenting adults in private but should not be taught to " + "young children.", + "Francis Crick" }, + { "All approaches at a higher level are suspect until confirmed at the molecular level.", + "Francis Crick" }, { "We haven't the money, so we've got to think.", "Ernest Rutherford" }, { "Furious activity is no substitute for understanding.", "H.H. Williams" }, - { "Discovery: A couple of months in the laboratory can frequently save a couple of hours in the library.", "Anonymous" }, + { "Discovery: A couple of months in the laboratory can frequently save a couple of hours " + "in the library.", + "Anonymous" }, { "Never replicate a successful experiment.", "Fett's law." }, - { "Raw data is like raw sewage, it requires some processing before it can be spread around. The opposite is true of theories.", "Jim Carr" }, + { "Raw data is like raw sewage, it requires some processing before it can be spread " + "around. The opposite is true of theories.", + "Jim Carr" }, { "A university faculty is 500 egotists with a common parking problem.", "Keith Sullivan" }, - { "Studying expands knowledge. Knowledge is power. Power corrupts. Corruption is a crime. Crime doesn't pay.", "Anonymous" }, + { "Studying expands knowledge. Knowledge is power. Power corrupts. Corruption is a crime. " + "Crime doesn't pay.", + "Anonymous" }, { "A professor is one who talks in someone else's sleep.", "W.H. Auden" }, { "A tidy laboratory means a lazy chemist.", "J.J. Berzelius" }, { "Microbiology Lab - Staph Only.", "Anonymous" }, - { "I can't go to a restaurant and order food because I keep looking at the fonts on the menu. Five minutes later I realize that it's also talking about food.", "Donald Knuth" }, - { "Physics is like sex: sure, it may give some practical results, but that's not why we do it", "Richard P. Feynman" }, - { "Statistics: The only science that enables different experts using the same figures to draw different conclusions.", "Evan Esar" }, - { "If I could remember the names of all these particles, I'd be a botanist.", "Albert Einstein" }, + { "I can't go to a restaurant and order food because I keep looking at the fonts on the " + "menu. Five minutes later I realize that it's also talking about food.", + "Donald Knuth" }, + { "Physics is like sex: sure, it may give some practical results, but that's not why we do " + "it", + "Richard P. Feynman" }, + { "Statistics: The only science that enables different experts using the same figures to " + "draw different conclusions.", + "Evan Esar" }, + { "If I could remember the names of all these particles, I'd be a botanist.", + "Albert Einstein" }, { "Science... never solves a problem without creating ten more.", "George Bernard Shaw" }, - { "A mathematician is a blind man in a dark room looking for a black cat which isn't there.", "Charles Darwin" }, + { "A mathematician is a blind man in a dark room looking for a black cat which isn't " + "there.", + "Charles Darwin" }, { "Nothing shocks me. I'm a scientist.", "Harrison Ford as Indiana Jones" }, { "There is an infinite set A that is not too big.", "John von Neumann" }, - { "If it's all right with Dirac, it's all right with me.", "Enrico Fermi, on being told that there was experimental evidence He-3 nuclei obey Fermi-Dirac statistics." }, - { "I cannot think of a single one, not even intelligence.", "Enrico Fermi, when asked what characteristics physics Nobel laureates had in common." }, - { "Heavier-than-air flying machines are impossible.", "Lord Kelvin, President of Royal Society, 1895." }, - { "All that glitters may not be gold, but at least it contains free electrons.", "John Desmond Baernal" }, - { "It is disconcerting to reflect on the number of students we have flunked in chemistry for not knowing what we later found to be untrue.", "Robert L. Weber" }, + { "If it's all right with Dirac, it's all right with me.", + "Enrico Fermi, on being told that there was experimental evidence He-3 nuclei obey " + "Fermi-Dirac statistics." }, + { "I cannot think of a single one, not even intelligence.", + "Enrico Fermi, when asked what characteristics physics Nobel laureates had in common." }, + { "Heavier-than-air flying machines are impossible.", + "Lord Kelvin, President of Royal Society, 1895." }, + { "All that glitters may not be gold, but at least it contains free electrons.", + "John Desmond Baernal" }, + { "It is disconcerting to reflect on the number of students we have flunked in chemistry " + "for not knowing what we later found to be untrue.", + "Robert L. Weber" }, { "People are DNA's way of making more DNA.", "Edward O. Wilson" }, - { "The best model of a cat is another cat..., specially the same cat.", "Arturo Rosenblueth" }, + { "The best model of a cat is another cat..., specially the same cat.", + "Arturo Rosenblueth" }, { "Computer dating is fine, if you are a computer.", "Rita May Brown" }, - { "The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.", "Nathaniel Borenstein" }, - { "An intellectual is someone who has found something more interesting than sex.", "Edgar Wallace" }, + { "The most likely way for the world to be destroyed, most experts agree, is by accident. " + "That's where we come in; we're computer professionals. We cause accidents.", + "Nathaniel Borenstein" }, + { "An intellectual is someone who has found something more interesting than sex.", + "Edgar Wallace" }, { "Base eight is just like base ten really, if you're missing two fingers.", "Tom Lehrer" }, - { "If 10 years from now, when you are doing something quick and dirty, you suddenly visualize that I am looking over your shoulders and say to yourself: 'Dijkstra would not have liked this', well that would be enough immortality for me.", "Edsger Dijkstra" }, - { "Memory is like an orgasm. It's a lot better if you don't have to fake it.", "Seymour Cray, on virtual memory" }, - { "A computer once beat me at chess, but it was no match for me at kick boxing.", "Emo Philips" }, - { "Home computers are being called upon to perform many new functions, including the consumption of homework formerly eaten by the dog.", "Doug Larson" }, - { "Forcefields are like dating; things go fine for a while and then sometimes it goes really bad.", "Alex MacKerell" }, - { "This type of advanced sampling techniques... which are not so advanced, really.", "Viveca Lindahl, on AWH, at her thesis defense." }, - { "C++ is tricky. You can do everything. You can even make every mistake.", "Nicolai Josuttis, CppCon2017" }, - { "Why would the backup server database get corrupted anyway?", "Stefan Fleischmann -- system administrator, physicist, optimist." }, - { "Teaching quantum computing is like teaching computer science at Hogwarts.", "Thomas Sterling, ISC2018 keynote" }, - { "It is unfortunate that the authors did not make better use of all the electric power energy that went into these massive computations.", "An anonymous referee" }, - { "Doctor, doctor, it hurts when I hit myself in the head with the hammer! - So don't do it!", "Bjarne Stroustrup at CppCon2015" }, + { "If 10 years from now, when you are doing something quick and dirty, you suddenly " + "visualize that I am looking over your shoulders and say to yourself: 'Dijkstra would " + "not have liked this', well that would be enough immortality for me.", + "Edsger Dijkstra" }, + { "Memory is like an orgasm. It's a lot better if you don't have to fake it.", + "Seymour Cray, on virtual memory" }, + { "A computer once beat me at chess, but it was no match for me at kick boxing.", + "Emo Philips" }, + { "Home computers are being called upon to perform many new functions, including the " + "consumption of homework formerly eaten by the dog.", + "Doug Larson" }, + { "Forcefields are like dating; things go fine for a while and then sometimes it goes " + "really bad.", + "Alex MacKerell" }, + { "This type of advanced sampling techniques... which are not so advanced, really.", + "Viveca Lindahl, on AWH, at her thesis defense." }, + { "C++ is tricky. You can do everything. You can even make every mistake.", + "Nicolai Josuttis, CppCon2017" }, + { "Why would the backup server database get corrupted anyway?", + "Stefan Fleischmann -- system administrator, physicist, optimist." }, + { "Teaching quantum computing is like teaching computer science at Hogwarts.", + "Thomas Sterling, ISC2018 keynote" }, + { "It is unfortunate that the authors did not make better use of all the electric power " + "energy that went into these massive computations.", + "An anonymous referee" }, + { "Doctor, doctor, it hurts when I hit myself in the head with the hammer! - So don't do " + "it!", + "Bjarne Stroustrup at CppCon2015" }, { "This is extremely unlikely.", "Berk Hess" }, { "Nothing is more anarchic than power.", "Pier Paolo Pasolini" }, - { "Never attribute to malice that which can be adequately explained by stupidity.", "Robert Hanlon" }, - { "Developing the AI requires the work of a data scientist, and most of them understand neither data nor science.", "Scott LeGrand" }, - { "Before we work on artificial intelligence why don't we do something about natural stupidity?", "Steve Polyak" }, + { "Never attribute to malice that which can be adequately explained by stupidity.", + "Robert Hanlon" }, + { "Developing the AI requires the work of a data scientist, and most of them understand " + "neither data nor science.", + "Scott LeGrand" }, + { "Before we work on artificial intelligence why don't we do something about natural " + "stupidity?", + "Steve Polyak" }, { "If it weren't for C, we'd all be programming in BASI and OBOL.", "Anonymous" }, - { "Why is it that programmers always confuse Halloween with Christmas? Because 31 OCT = 25 DEC.", "Anonymous" }, - { "I'm not interrupting you, I'm putting our conversation in full-duplex mode.", "Antone Roundy" }, - { "The programmer got stuck in the shower because the instructions on the shampoo bottle said: Lather, Rinse, Repeat.", "Anonymous" }, - { "A programmer's spouse says 'While you're at the grocery store, buy some eggs.' The programmer never comes back.", "Anonymous" }, + { "Why is it that programmers always confuse Halloween with Christmas? Because 31 OCT = 25 " + "DEC.", + "Anonymous" }, + { "I'm not interrupting you, I'm putting our conversation in full-duplex mode.", + "Antone Roundy" }, + { "The programmer got stuck in the shower because the instructions on the shampoo bottle " + "said: Lather, Rinse, Repeat.", + "Anonymous" }, + { "A programmer's spouse says 'While you're at the grocery store, buy some eggs.' The " + "programmer never comes back.", + "Anonymous" }, { "What is a Unix or Linux sysadmin's favourite hangout place? Foo Bar.", "Anonymous" }, - { "If you have any trouble sounding condescending, find a UNIX user to show you how it's done.", "Scott Adams, Dibert Cartoonist" }, + { "If you have any trouble sounding condescending, find a UNIX user to show you how it's " + "done.", + "Scott Adams, Dibert Cartoonist" }, { "There is no place like ~", "Anonymous" }, { "Thou shalt not kill -9", "Anonymous" }, { "printf(\"%d is the year of the linux desktop\", year+1);", "Anonymous" }, - { "The use of COBOL cripples the mind; its teaching should therefore be regarded as a criminal offense.", "Edsger Dijkstra" }, - { "Computer system analysis is like child-rearing; you can do grievous damage, but you cannot ensure success.", "Tom DeMarcho" }, - { "PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a great and insidious evil, perpetrated by skilled but perverted professionals.", "Jon Ribbens" }, + { "The use of COBOL cripples the mind; its teaching should therefore be regarded as a " + "criminal offense.", + "Edsger Dijkstra" }, + { "Computer system analysis is like child-rearing; you can do grievous damage, but you " + "cannot ensure success.", + "Tom DeMarcho" }, + { "PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a " + "great and insidious evil, perpetrated by skilled but perverted professionals.", + "Jon Ribbens" }, { "C is not a high-level language.", "Brian Kernighan, C author" }, - { "I will not be a lemming and follow the crowd over the cliff and into the C.", "John Beidler" }, + { "I will not be a lemming and follow the crowd over the cliff and into the C.", + "John Beidler" }, { "C is quirky, flawed, and an enourmous success.", "Dennis Ritchie, C author" }, - { "A C program is like a fast dance on a newly waxed dance floor by people carrying razors.", "Waldi Ravens" }, - { "Fifty years of programming language research, and we end up with C++???", "Richard O'Keefe" }, - { "Quite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.", "Linus Torvalds" }, - { "Considering the current sad state of our computer programs, software development is clearly still a black art, and cannot yet be called an engineering discipline.", "William Jefferson Clinton" }, - { "I am rarely happier than when spending an entire day programming my computer to perform automatically a task that it would otherwise take me a good ten seconds to do by hand.", "Douglas Adams" }, + { "A C program is like a fast dance on a newly waxed dance floor by people carrying " + "razors.", + "Waldi Ravens" }, + { "Fifty years of programming language research, and we end up with C++???", + "Richard O'Keefe" }, + { "Quite frankly, even if the choice of C were to do *nothing* but keep the C++ " + "programmers out, that in itself would be a huge reason to use C.", + "Linus Torvalds" }, + { "Considering the current sad state of our computer programs, software development is " + "clearly still a black art, and cannot yet be called an engineering discipline.", + "William Jefferson Clinton" }, + { "I am rarely happier than when spending an entire day programming my computer to perform " + "automatically a task that it would otherwise take me a good ten seconds to do by hand.", + "Douglas Adams" }, { "#define QUESTION ((bb),| !(bb))", "William Shakespeare" }, { "I didn't know what MD was. I think I've managed to catch up.", "Berk Hess" }, - { "Teemu [Murtola] keeps beating our code, but that's fine because he's always right.", "Berk Hess" }, - { "Schrödinger's backup: The condition of any backup is unknown until a restore is attempted.", "Anonymous" }, + { "Teemu [Murtola] keeps beating our code, but that's fine because he's always right.", + "Berk Hess" }, + { "Schrödinger's backup: The condition of any backup is unknown until a restore is " + "attempted.", + "Anonymous" }, { "Don't waste pure thoughts on dirty enzymes.", "Efraim Racker" }, - { "I like single-molecule experiments because I hate to simulate 10^23 molecules at the same time.", "Helmut Grubmüller" }, + { "I like single-molecule experiments because I hate to simulate 10^23 molecules at the " + "same time.", + "Helmut Grubmüller" }, { "I wanted to make a clever chemistry joke, but the best ones Argon.", "39.948" }, - { "Not to get technical... but according to chemistry, alcohol is a solution.", "Anonymous" }, - { "The physical chemists never use their eyes and are most lamentably lacking in chemical culture. It is essential to cast out from our midst, root and branch, this physical element and return to our laboratories.", "Henry Edward Armstrong" }, - { "Time is the best appraiser of scientific work, and I am aware that an industrial discovery rarely produces all its fruit in the hands of its first inventor.", "Louis Pasteur" }, - { "Still I had a lurking question. Would it not be better if one could really 'see' whether molecules as complicated as the sterols, or strychnine were just as experiment suggested?", "Dorothy Hodgkin" }, - { "We think there is color, we think there is sweet, we think there is bitter, but in reality there are atoms and a void.", "Democritus" }, - { "A cop pulls Heisenberg over and asks him 'Do you know how fast you were going?' Heisenberg replies 'No, but I know exactly where I am'. The cop says 'You were doing 55 in a 35 zone'. Heisenberg: 'Great! Now I'm lost!", "Anonymous" }, - { "Two chemists walk into a bar. The first one says, 'I'll have some H2O.'. The second one says, 'I'll have some H2O, too'. He dies.", "Anonymous" }, - { "There are only two hard things in computer science - cache invalidation, naming things and off-by-one errors.", "Anonymous" }, - { "Science, for me, gives a partial explanation for life. In so far as it goes, it is based on fact, experience and experiment.", "Rosalind Franklin" }, + { "Not to get technical... but according to chemistry, alcohol is a solution.", + "Anonymous" }, + { "The physical chemists never use their eyes and are most lamentably lacking in chemical " + "culture. It is essential to cast out from our midst, root and branch, this physical " + "element and return to our laboratories.", + "Henry Edward Armstrong" }, + { "Time is the best appraiser of scientific work, and I am aware that an industrial " + "discovery rarely produces all its fruit in the hands of its first inventor.", + "Louis Pasteur" }, + { "Still I had a lurking question. Would it not be better if one could really 'see' " + "whether molecules as complicated as the sterols, or strychnine were just as experiment " + "suggested?", + "Dorothy Hodgkin" }, + { "We think there is color, we think there is sweet, we think there is bitter, but in " + "reality there are atoms and a void.", + "Democritus" }, + { "A cop pulls Heisenberg over and asks him 'Do you know how fast you were going?' " + "Heisenberg replies 'No, but I know exactly where I am'. The cop says 'You were doing 55 " + "in a 35 zone'. Heisenberg: 'Great! Now I'm lost!", + "Anonymous" }, + { "Two chemists walk into a bar. The first one says, 'I'll have some H2O.'. The second one " + "says, 'I'll have some H2O, too'. He dies.", + "Anonymous" }, + { "There are only two hard things in computer science - cache invalidation, naming things " + "and off-by-one errors.", + "Anonymous" }, + { "Science, for me, gives a partial explanation for life. In so far as it goes, it is " + "based on fact, experience and experiment.", + "Rosalind Franklin" }, { "I was taught that the way of progress was neither swift nor easy.", "Marie Curie" }, { "Life need not be easy, provided only that it is not empty.", "Lise Meitner" }, { "We ignore public understanding of science at our peril.", "Eugenie Clark" }, - { "All sorts of things can happen when you're open to new ideas and playing around with things.", "Stephanie Kwolek, inventor of Kevlar" }, - { "As always in life, people want a simple answer... and it's always wrong.", "Marie Daly" }, - { "For a research worker the unforgotten moments of his life are those rare ones which come after years of plodding work, when the veil over natures secret seems suddenly to lift & when what was dark & chaotic appears in a clear & beautiful light & pattern.", "Gerty Cori" }, - { "The more clearly we can focus our attention on the wonders and realities of the universe about us, the less taste we shall have for destruction.", "Rachel Carson" }, - { "I didn't want to just know names of things. I remember really wanting to know how it all worked.", "Elizabeth Blackburn" }, - { "Science is not a boy's game, it's not a girl's game. It's everyone's game. It's about where we are and where we're going.", "Nichelle Nichols" }, - { "If you know you are on the right track, if you have this inner knowledge, then nobody can turn you off... no matter what they say.", "Barbara McClintock" }, + { "All sorts of things can happen when you're open to new ideas and playing around with " + "things.", + "Stephanie Kwolek, inventor of Kevlar" }, + { "As always in life, people want a simple answer... and it's always wrong.", + "Marie Daly" }, + { "For a research worker the unforgotten moments of his life are those rare ones which " + "come after years of plodding work, when the veil over natures secret seems suddenly to " + "lift & when what was dark & chaotic appears in a clear & beautiful light & pattern.", + "Gerty Cori" }, + { "The more clearly we can focus our attention on the wonders and realities of the " + "universe about us, the less taste we shall have for destruction.", + "Rachel Carson" }, + { "I didn't want to just know names of things. I remember really wanting to know how it " + "all worked.", + "Elizabeth Blackburn" }, + { "Science is not a boy's game, it's not a girl's game. It's everyone's game. It's about " + "where we are and where we're going.", + "Nichelle Nichols" }, + { "If you know you are on the right track, if you have this inner knowledge, then nobody " + "can turn you off... no matter what they say.", + "Barbara McClintock" }, { "Science and everyday life cannot and should not be separated.", "Rosalind Franklin" }, - { "I hadn't been aware that there were doors closed to me until I started knocking on them.", "Gertrude Elion" }, - { "Humans are allergic to change. They love to say, 'We've always done it this way.' I try to fight that. That's why I have a clock on my wall that runs counter-clockwise.", "Grace Hopper" }, + { "I hadn't been aware that there were doors closed to me until I started knocking on " + "them.", + "Gertrude Elion" }, + { "Humans are allergic to change. They love to say, 'We've always done it this way.' I try " + "to fight that. That's why I have a clock on my wall that runs counter-clockwise.", + "Grace Hopper" }, { "Be less curious about people and more curious about ideas.", "Marie Curie" }, - { "I was a bit of an artist, and somewhere along the way had gotten the idea that computers could be used for animation and artists, because in-betweening was so tedious... Of course, everyone thought I was nuts.", "Carla Meninsky, Atari engineer" }, - { "I think it's very important to get more women into computing. My slogan is: Computing is too important to be left to men.", "Karen Jones" }, - { "There is only one thing worse than coming home from the lab to a sink full of dirty dishes, and that is not going to the lab at all!", "Chien-Shiung Wu" }, - { "They never asked me to go back over (my calculations) because when I did it, I had done my best, and it was right.", "Kathrine Jonson (legendary NASA mathematician)" }, + { "I was a bit of an artist, and somewhere along the way had gotten the idea that " + "computers could be used for animation and artists, because in-betweening was so " + "tedious... Of course, everyone thought I was nuts.", + "Carla Meninsky, Atari engineer" }, + { "I think it's very important to get more women into computing. My slogan is: Computing " + "is too important to be left to men.", + "Karen Jones" }, + { "There is only one thing worse than coming home from the lab to a sink full of dirty " + "dishes, and that is not going to the lab at all!", + "Chien-Shiung Wu" }, + { "They never asked me to go back over (my calculations) because when I did it, I had done " + "my best, and it was right.", + "Kathrine Jonson (legendary NASA mathematician)" }, { "Science is a way of thinking much more than it is a body of knowledge.", "Carl Sagan" }, { "Science is organized knowledge. Wisdom is organized life.", "Immanuel Kant" }, { "Everything is theoretically impossible, until it is done.", "Robert Heinlein" }, - { "Bad times have a scientific value. These are occasions a good learner would not miss.", "Ralph Waldo Emerson" }, - { "The scientist is not a person who gives the right answers, he's one who asks the right questions.", "Claude Levi-Strauss" }, + { "Bad times have a scientific value. These are occasions a good learner would not miss.", + "Ralph Waldo Emerson" }, + { "The scientist is not a person who gives the right answers, he's one who asks the right " + "questions.", + "Claude Levi-Strauss" }, { "Rockets are cool. There's no getting around that.", "Elon Musk" }, { "Life would be tragic if it weren't funny.", "Stephen Hawking" }, { "Somewhere, something incredible is waiting to be known.", "Carl Sagan" }, - { "I am driven by two main philosophies: know more today about the world than I knew yesterday and lessen the suffering of others. You'd be surprised how far that gets you.", "Neil deGrasse Tyson" }, - { "Your assumptions are your windows on the world. Scrub them off every once in a while, or the light won't come in.", "Isaac Asimov" }, + { "I am driven by two main philosophies: know more today about the world than I knew " + "yesterday and lessen the suffering of others. You'd be surprised how far that gets you.", + "Neil deGrasse Tyson" }, + { "Your assumptions are your windows on the world. Scrub them off every once in a while, " + "or the light won't come in.", + "Isaac Asimov" }, { "Religion is a culture of faith; science is a culture of doubt.", "Richard Feynman" }, { "Millions saw the apple fall, Newton was the only one who asked why?", "Bernard Baruch" }, - { "If you thought that science was certain - well, that is just an error on your part.", "Richard Feynman" }, - { "When my information changes, I alter my conclusions. What do you do, sir?", "John Maynard Keynes" }, - { "The aim of science is not to open the door to infinite wisdom, but to set a limit to infinite error.", "Bertolt Brecht, Life of Galileo" }, + { "If you thought that science was certain - well, that is just an error on your part.", + "Richard Feynman" }, + { "When my information changes, I alter my conclusions. What do you do, sir?", + "John Maynard Keynes" }, + { "The aim of science is not to open the door to infinite wisdom, but to set a limit to " + "infinite error.", + "Bertolt Brecht, Life of Galileo" }, { "As we all know, blinking lights means science.", "Joss Whedon" }, { "But in my opinion, all things in nature occur mathematically.", "Rene Decartes" }, - { "A weed scientist goes into a shop. He asks: 'Hey, you got any of that inhibitor of 3-phosphoshikimate-carboxyvinyl transferase?' Shopkeeper: 'You mean Roundup?' Scientist: 'Yeah, that's it. I can never remember that dang name!'", "John Pickett" }, - { "It is not clear that intelligence has any long-term survival value.", "Stephen Hawking" }, - { "The greatest shortcoming of the human race is our inability to understand the exponential function.", "Albert Bartlett" }, - { "You can get into a habit of thought in which you enjoy making fun of all those other people who don't see things as clearly as you do. We have to guard carefully against it.", "Carl Sagan" }, - { "I have no responsibility to live up to what others expect of me. That's their mistake, not my failing.", "Richard Feynman" }, + { "A weed scientist goes into a shop. He asks: 'Hey, you got any of that inhibitor of " + "3-phosphoshikimate-carboxyvinyl transferase?' Shopkeeper: 'You mean Roundup?' " + "Scientist: 'Yeah, that's it. I can never remember that dang name!'", + "John Pickett" }, + { "It is not clear that intelligence has any long-term survival value.", + "Stephen Hawking" }, + { "The greatest shortcoming of the human race is our inability to understand the " + "exponential function.", + "Albert Bartlett" }, + { "You can get into a habit of thought in which you enjoy making fun of all those other " + "people who don't see things as clearly as you do. We have to guard carefully against " + "it.", + "Carl Sagan" }, + { "I have no responsibility to live up to what others expect of me. That's their mistake, " + "not my failing.", + "Richard Feynman" }, { "Highly organized research is guaranteed to produce nothing new.", "Frank Herbert" }, { "Those who cannot remember the past are condemned to compute it.", "Steve Pinker" }, - { "If a rat is a good model for your emotional life, you're in big trouble.", "Robert Sapolsky" }, - { "I don't know how many of you have ever met Dijkstra, but you probably know that arrogance in computer science is measured in nano-Dijkstras.", "Alan Kay" }, - { "NASA spent millions of dollars inventing the ball-point pen so they could write in space. The Russians took a pencil.", "Will Chabot" }, + { "If a rat is a good model for your emotional life, you're in big trouble.", + "Robert Sapolsky" }, + { "I don't know how many of you have ever met Dijkstra, but you probably know that " + "arrogance in computer science is measured in nano-Dijkstras.", + "Alan Kay" }, + { "NASA spent millions of dollars inventing the ball-point pen so they could write in " + "space. The Russians took a pencil.", + "Will Chabot" }, { "By denying scientific principles, one may maintain any paradox.", "Galileo Galilei" }, { "Perfect is the enemy of good.", "Voltaire" }, { "Men love to wonder, and that is the seed of science.", "Ralph Waldo Emerson" }, - { "In mathematics you don't understand things, you just get used to them", "John von Neumann" }, - { "A real scientist solves problems, not wails that they are unsolvable.", "Anne McCaffrey" }, - { "Science progresses best when observations force us to alter our preconceptions.", "Vera Rubin" }, - { "Our two greatest problems are gravity and paper work. We can lick gravity, but sometimes the paperwork is overwhelming.", "Wernher von Braun" }, - { "I have had my results for a long time, but I do not yet know how I am to arrive at them.", "Carl Friedrich Gauss" }, - { "The difficulty lies, not in the new ideas, but in escaping the old ones.", "John Maynard Keynes" }, + { "In mathematics you don't understand things, you just get used to them", + "John von Neumann" }, + { "A real scientist solves problems, not wails that they are unsolvable.", + "Anne McCaffrey" }, + { "Science progresses best when observations force us to alter our preconceptions.", + "Vera Rubin" }, + { "Our two greatest problems are gravity and paper work. We can lick gravity, but " + "sometimes the paperwork is overwhelming.", + "Wernher von Braun" }, + { "I have had my results for a long time, but I do not yet know how I am to arrive at " + "them.", + "Carl Friedrich Gauss" }, + { "The difficulty lies, not in the new ideas, but in escaping the old ones.", + "John Maynard Keynes" }, { "The way to succeed is to double your failure rate.", "Thomas J. Watson" }, - { "We are continually faced by great opportunities brilliantly disguised as insoluble problems.", "Lee Iacocca" }, - { "Mathematics is a game played according to certain rules with meaningless marks on paper.", "David Hilbert" }, + { "We are continually faced by great opportunities brilliantly disguised as insoluble " + "problems.", + "Lee Iacocca" }, + { "Mathematics is a game played according to certain rules with meaningless marks on " + "paper.", + "David Hilbert" }, { "Mathematics is no more computation than typing is literature.", "John Allen Paulos" }, { "Mathematics is like love; a simple idea, but it can get complicated.", "Anonymous" }, { "I had a polynomial once. My doctor removed it.", "Michael Grant" }, - { "Since the mathematicians have invaded the theory of relativity I do not understand it myself any more.", "Albert Einstein" }, - { "I couldn't claim that I was smarter than sixty-five other guys - but the average of sixty-five other guys, certainly!", "Richard Feynman" }, - { "Your Excellency, I have no need of this hypothesis.", "Pierre Laplace, to Napoleon on why his works on celestial mechanics make no mention of God." }, + { "Since the mathematicians have invaded the theory of relativity I do not understand it " + "myself any more.", + "Albert Einstein" }, + { "I couldn't claim that I was smarter than sixty-five other guys - but the average of " + "sixty-five other guys, certainly!", + "Richard Feynman" }, + { "Your Excellency, I have no need of this hypothesis.", + "Pierre Laplace, to Napoleon on why his works on celestial mechanics make no mention of " + "God." }, { "The sign of wisdom is to have more questions than answers.", "Abhijit Naskar" }, { "Stupidity got us into this mess, and stupidity will get us out.", "Homer Simpson" }, { "Trying is the first step towards failure.", "Homer Simpson" }, - { "Same sex marriage is not a gay privilege, it's equal rights. Privilege would be something like gay people not paying taxes. Like churches don't.", "Ricky Gervais" }, - { "Remember, being healthy is basically dying as slowly as possible.", "Ricky Gervais"}, + { "Same sex marriage is not a gay privilege, it's equal rights. Privilege would be " + "something like gay people not paying taxes. Like churches don't.", + "Ricky Gervais" }, + { "Remember, being healthy is basically dying as slowly as possible.", "Ricky Gervais" }, { "Pain is inevitable. Suffering is optional.", "Haruki Murakami" }, - { "Aristotle maintained that women have fewer teeth than men; although he was twice married, it never occurred to him to verify this statement by examining his wives' mouths.", "Bertrand Russell" }, - { "I had trouble with physics in college. When I signed up I thought it said psychics.", "Greg Tamblyn" }, - { "I don't believe in astrology; I'm a Sagittarian and we're skeptical.", "Arthur C. Clarke" }, - { "I see they found out the universe is 80 million years older than we thought. It's also been lying about its weight.", "Bill Maher" }, + { "Aristotle maintained that women have fewer teeth than men; although he was twice " + "married, it never occurred to him to verify this statement by examining his wives' " + "mouths.", + "Bertrand Russell" }, + { "I had trouble with physics in college. When I signed up I thought it said psychics.", + "Greg Tamblyn" }, + { "I don't believe in astrology; I'm a Sagittarian and we're skeptical.", + "Arthur C. Clarke" }, + { "I see they found out the universe is 80 million years older than we thought. It's also " + "been lying about its weight.", + "Bill Maher" }, { "Do you have mole problems? If so, call Avogadro at 602-1023.", "Jay Leno" }, { "Marie, you're looking more radiant every day!", "Pierre Curie" }, - { "I don't want to achieve immortality through my work... I want to achieve it through not dying!", "Woody Allen" }, - { "Well, I am a dilettante. It's only in England that dilettantism is considered a bad thing. In other countries it's called interdisciplinary research.", "Brian Eno" }, - { "I think it would be a good idea.", "Mahatma Gandhi, when asked what he thought of Western civilization" }, + { "I don't want to achieve immortality through my work... I want to achieve it through not " + "dying!", + "Woody Allen" }, + { "Well, I am a dilettante. It's only in England that dilettantism is considered a bad " + "thing. In other countries it's called interdisciplinary research.", + "Brian Eno" }, + { "I think it would be a good idea.", + "Mahatma Gandhi, when asked what he thought of Western civilization" }, { "Nobody ever complained a seminar was too easy to understand.", "Ken Dill" }, - { "Academia is kind of like applied Marxism. The workers really do own the means of production.", "Niklas Blomberg" }, - { "The Lord of the Rings can be confusing to follow because many of the bad minions look and sound familiar; that's why Tolkien gave them each an ORCid.", "Caroline Bartman" }, - { "Mendeleev's first attempt, the perfluoric table, was a total disaster, and his subsequent attempts, the perchloric and perbromic tables, were not favorably received. Only his fourth attempt, the periodic table, gained general acceptance.", "Anonymous" }, + { "Academia is kind of like applied Marxism. The workers really do own the means of " + "production.", + "Niklas Blomberg" }, + { "The Lord of the Rings can be confusing to follow because many of the bad minions look " + "and sound familiar; that's why Tolkien gave them each an ORCid.", + "Caroline Bartman" }, + { "Mendeleev's first attempt, the perfluoric table, was a total disaster, and his " + "subsequent attempts, the perchloric and perbromic tables, were not favorably received. " + "Only his fourth attempt, the periodic table, gained general acceptance.", + "Anonymous" }, { "Don’t bring an anecdote to a data fight.", "Molly Hodgdon" }, - { "Give someone a program, you frustrate them for a day; teach them how to program, you frustrate them for a lifetime.", "David Leinweber" }, + { "Give someone a program, you frustrate them for a day; teach them how to program, you " + "frustrate them for a lifetime.", + "David Leinweber" }, { "Or (horrors!) use Berendsen!", "Justin Lemkul" }, { "The absence of real intelligence doesn't prove you're using AI", "Magnus Lundborg" }, - { "People who do QM/MM must be rather patient and enjoy quality over speed", "Kresten Lindorff-Larsen" }, + { "People who do QM/MM must be rather patient and enjoy quality over speed", + "Kresten Lindorff-Larsen" }, { "I don’t think we’re afraid of inline assembly.", "Szilard Pall" }, - { "I'm a strong believer that ignorance is important in science. If you know too much, you start seeing reasons why things won't work. That's why its important to change your field to collect more ignorance.", "Sydney Brenner" }, + { "I'm a strong believer that ignorance is important in science. If you know too much, you " + "start seeing reasons why things won't work. That's why its important to change your " + "field to collect more ignorance.", + "Sydney Brenner" }, { "It's more useful when you know what you're doing.", "Artem Zhmurov" }, - { "I have noticed a large, negative correlation between having a well-defined mission workload and concern for the Top500. It's almost like LINPACK is what you focus on when you don't know what to focus on.", "Jeff Hammond" }, - { "Between equal rights, force decides.", "Karl Marx"}, - {"To dissimulate is to feign not to have what one has. To simulate is to feign to have what one hasn't.", "Jean Baudrillard"}, + { "I have noticed a large, negative correlation between having a well-defined mission " + "workload and concern for the Top500. It's almost like LINPACK is what you focus on when " + "you don't know what to focus on.", + "Jeff Hammond" }, + { "Between equal rights, force decides.", "Karl Marx" }, + { "To dissimulate is to feign not to have what one has. To simulate is to feign to have " + "what one hasn't.", + "Jean Baudrillard" }, }; if (beCool()) @@ -963,4 +1515,4 @@ std::string getCoolQuote() } } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/utility/coolstuff.h b/src/gromacs/utility/coolstuff.h index c982fa47e0..3a13b77560 100644 --- a/src/gromacs/utility/coolstuff.h +++ b/src/gromacs/utility/coolstuff.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,6 +52,6 @@ std::string bromacs(); //! Return a string with a cool quote std::string getCoolQuote(); -} +} // namespace gmx #endif diff --git a/src/gromacs/utility/cstringutil.cpp b/src/gromacs/utility/cstringutil.cpp index 730aaf092d..2afafc3c97 100644 --- a/src/gromacs/utility/cstringutil.cpp +++ b/src/gromacs/utility/cstringutil.cpp @@ -56,16 +56,16 @@ //! Comment sign to use. #define COMMENTSIGN ';' -int continuing(char *s) +int continuing(char* s) { int sl; assert(s); rtrim(s); sl = strlen(s); - if ((sl > 0) && (s[sl-1] == CONTINUE)) + if ((sl > 0) && (s[sl - 1] == CONTINUE)) { - s[sl-1] = 0; + s[sl - 1] = 0; return TRUE; } else @@ -75,10 +75,9 @@ int continuing(char *s) } - -char *fgets2(char *line, int n, FILE *stream) +char* fgets2(char* line, int n, FILE* stream) { - char *c; + char* c; if (fgets(line, n, stream) == nullptr) { return nullptr; @@ -95,7 +94,10 @@ char *fgets2(char *line, int n, FILE *stream) */ if (!feof(stream)) { - gmx_fatal(FARGS, "An input file contains a line longer than %d characters, while the buffer passed to fgets2 has size %d. The line starts with: '%20.20s'", n, n, line); + gmx_fatal(FARGS, + "An input file contains a line longer than %d characters, while the buffer " + "passed to fgets2 has size %d. The line starts with: '%20.20s'", + n, n, line); } } if ((c = strchr(line, '\r')) != nullptr) @@ -106,9 +108,9 @@ char *fgets2(char *line, int n, FILE *stream) return line; } -void strip_comment (char *line) +void strip_comment(char* line) { - char *c; + char* c; if (!line) { @@ -122,7 +124,7 @@ void strip_comment (char *line) } } -void upstring (char *str) +void upstring(char* str) { int i; @@ -132,9 +134,9 @@ void upstring (char *str) } } -void ltrim (char *str) +void ltrim(char* str) { - int i, c; + int i, c; if (nullptr == str) { @@ -150,13 +152,13 @@ void ltrim (char *str) { for (i = c; ('\0' != str[i]); i++) { - str[i-c] = str[i]; + str[i - c] = str[i]; } - str[i-c] = '\0'; + str[i - c] = '\0'; } } -void rtrim (char *str) +void rtrim(char* str) { int nul; @@ -165,21 +167,21 @@ void rtrim (char *str) return; } - nul = strlen(str)-1; - while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t')) ) + nul = strlen(str) - 1; + while ((nul > 0) && ((str[nul] == ' ') || (str[nul] == '\t'))) { str[nul] = '\0'; nul--; } } -void trim (char *str) +void trim(char* str) { - ltrim (str); - rtrim (str); + ltrim(str); + rtrim(str); } -int gmx_strcasecmp_min(const char *str1, const char *str2) +int gmx_strcasecmp_min(const char* str1, const char* str2) { char ch1, ch2; @@ -188,53 +190,47 @@ int gmx_strcasecmp_min(const char *str1, const char *str2) do { ch1 = toupper(*(str1++)); - } - while ((ch1 == '-') || (ch1 == '_')); + } while ((ch1 == '-') || (ch1 == '_')); do { ch2 = toupper(*(str2++)); - } - while ((ch2 == '-') || (ch2 == '_')); + } while ((ch2 == '-') || (ch2 == '_')); if (ch1 != ch2) { - return (ch1-ch2); + return (ch1 - ch2); } - } - while (ch1 != 0); + } while (ch1 != 0); return 0; } -int gmx_strncasecmp_min(const char *str1, const char *str2, int n) +int gmx_strncasecmp_min(const char* str1, const char* str2, int n) { char ch1, ch2; char *stri1, *stri2; - stri1 = const_cast(str1); - stri2 = const_cast(str2); + stri1 = const_cast(str1); + stri2 = const_cast(str2); do { do { ch1 = toupper(*(str1++)); - } - while ((ch1 == '-') || (ch1 == '_')); + } while ((ch1 == '-') || (ch1 == '_')); do { ch2 = toupper(*(str2++)); - } - while ((ch2 == '-') || (ch2 == '_')); + } while ((ch2 == '-') || (ch2 == '_')); if (ch1 != ch2) { - return (ch1-ch2); + return (ch1 - ch2); } - } - while ((ch1 != 0) && (str1-stri1 < n) && (str2-stri2 < n)); + } while ((ch1 != 0) && (str1 - stri1 < n) && (str2 - stri2 < n)); return 0; } -int gmx_strcasecmp(const char *str1, const char *str2) +int gmx_strcasecmp(const char* str1, const char* str2) { char ch1, ch2; @@ -244,14 +240,13 @@ int gmx_strcasecmp(const char *str1, const char *str2) ch2 = toupper(*(str2++)); if (ch1 != ch2) { - return (ch1-ch2); + return (ch1 - ch2); } - } - while (ch1 != 0); + } while (ch1 != 0); return 0; } -int gmx_strncasecmp(const char *str1, const char *str2, int n) +int gmx_strncasecmp(const char* str1, const char* str2, int n) { char ch1, ch2; @@ -266,37 +261,35 @@ int gmx_strncasecmp(const char *str1, const char *str2, int n) ch2 = toupper(*(str2++)); if (ch1 != ch2) { - return (ch1-ch2); + return (ch1 - ch2); } n--; - } - while ((ch1 != 0) && (n != 0)); + } while ((ch1 != 0) && (n != 0)); return 0; } -char *gmx_strdup(const char *src) +char* gmx_strdup(const char* src) { - char *dest; + char* dest; - auto length = strlen(src)+1; + auto length = strlen(src) + 1; snew(dest, length); std::strncpy(dest, src, length); return dest; } -char * -gmx_strndup(const char *src, int n) +char* gmx_strndup(const char* src, int n) { int len; - char *dest; + char* dest; len = strlen(src); if (len > n) { len = n; } - snew(dest, len+1); + snew(dest, len + 1); strncpy(dest, src, len); dest[len] = 0; return dest; @@ -305,12 +298,10 @@ gmx_strndup(const char *src, int n) /* Magic hash init number for Dan J. Bernsteins algorithm. * Do NOT use any other value unless you really know what you are doing. */ -const unsigned int - gmx_string_hash_init = 5381; +const unsigned int gmx_string_hash_init = 5381; -unsigned int -gmx_string_fullhash_func(const char *s, unsigned int hash_init) +unsigned int gmx_string_fullhash_func(const char* s, unsigned int hash_init) { int c; @@ -321,8 +312,7 @@ gmx_string_fullhash_func(const char *s, unsigned int hash_init) return hash_init; } -unsigned int -gmx_string_hash_func(const char *s, unsigned int hash_init) +unsigned int gmx_string_hash_func(const char* s, unsigned int hash_init) { int c; @@ -330,14 +320,13 @@ gmx_string_hash_func(const char *s, unsigned int hash_init) { if (isalnum(c)) { - hash_init = ((hash_init << 5) + hash_init) ^ c; /* (hash * 33) xor c */ + hash_init = ((hash_init << 5) + hash_init) ^ c; /* (hash * 33) xor c */ } } return hash_init; } -int -gmx_wcmatch(const char *pattern, const char *str) +int gmx_wcmatch(const char* pattern, const char* str) { while (*pattern) { @@ -401,9 +390,9 @@ gmx_wcmatch(const char *pattern, const char *str) return (*str == 0) ? 0 : GMX_NO_WCMATCH; } -char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFirst) +char* wrap_lines(const char* buf, int line_width, int indent, gmx_bool bIndentFirst) { - char *b2; + char* b2; int i, i0, i2, j, b2len, lspace = 0, l2space = 0; gmx_bool bFirst, bFitsOnLine; @@ -420,7 +409,7 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi */ b2 = nullptr; - b2len = strlen(buf)+1+indent; + b2len = strlen(buf) + 1 + indent; snew(b2, b2len); i0 = i2 = 0; if (bIndentFirst) @@ -435,19 +424,19 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi { l2space = -1; /* find the last space before end of line */ - for (i = i0; ((i-i0 < line_width) || (l2space == -1)) && (buf[i]); i++) + for (i = i0; ((i - i0 < line_width) || (l2space == -1)) && (buf[i]); i++) { b2[i2++] = buf[i]; /* remember the position of a space */ if (buf[i] == ' ') { lspace = i; - l2space = i2-1; + l2space = i2 - 1; } /* if we have a newline before the line is full, reset counters */ - if (buf[i] == '\n' && buf[i+1]) + if (buf[i] == '\n' && buf[i + 1]) { - i0 = i+1; + i0 = i + 1; b2len += indent; srenew(b2, b2len); /* add indentation after the newline */ @@ -458,7 +447,7 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi } } /* If we are at the last newline, copy it */ - if (buf[i] == '\n' && !buf[i+1]) + if (buf[i] == '\n' && !buf[i + 1]) { b2[i2++] = buf[i++]; } @@ -466,12 +455,12 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi if (buf[i]) { /* check if one word does not fit on the line */ - bFitsOnLine = (i-i0 <= line_width); + bFitsOnLine = (i - i0 <= line_width); /* reset line counters to just after the space */ - i0 = lspace+1; - i2 = l2space+1; + i0 = lspace + 1; + i2 = l2space + 1; /* if the words fit on the line, and we're beyond the indentation part */ - if ( (bFitsOnLine) && (l2space >= indent) ) + if ((bFitsOnLine) && (l2space >= indent)) { /* start a new line */ b2[l2space] = '\n'; @@ -481,7 +470,7 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi if (bFirst) { line_width -= indent; - bFirst = FALSE; + bFirst = FALSE; } b2len += indent; srenew(b2, b2len); @@ -497,15 +486,13 @@ char *wrap_lines(const char *buf, int line_width, int indent, gmx_bool bIndentFi } } } - } - while (buf[i] != 0); + } while (buf[i] != 0); b2[i2] = '\0'; return b2; } -int64_t -str_to_int64_t(const char *str, char **endptr) +int64_t str_to_int64_t(const char* str, char** endptr) { #ifndef _MSC_VER return strtoll(str, endptr, 10); @@ -514,7 +501,7 @@ str_to_int64_t(const char *str, char **endptr) #endif } -char *gmx_step_str(int64_t i, char *buf) +char* gmx_step_str(int64_t i, char* buf) { sprintf(buf, "%" PRId64, i); return buf; diff --git a/src/gromacs/utility/cstringutil.h b/src/gromacs/utility/cstringutil.h index 859e9e0190..c80cdcf9a3 100644 --- a/src/gromacs/utility/cstringutil.h +++ b/src/gromacs/utility/cstringutil.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,7 +48,7 @@ #include "gromacs/utility/basedefinitions.h" /** Continuation character. */ -#define CONTINUE '\\' +#define CONTINUE '\\' /** Standard size for char* string buffers. */ #define STRLEN 4096 @@ -57,7 +57,7 @@ * * \returns TRUE if s ends with a CONTINUE, FALSE otherwise. */ -int continuing(char *s); +int continuing(char* s); /*! \brief * Reads a line from a stream. @@ -66,37 +66,37 @@ int continuing(char *s); * \0 and zero terminated, without newlines. \p s should be long * enough (>= \p n) */ -char *fgets2(char *s, int n, FILE *stream); +char* fgets2(char* s, int n, FILE* stream); /** Remove portion of a line after a ';' comment sign. */ -void strip_comment(char *line); +void strip_comment(char* line); /** Make a string uppercase. */ -void upstring(char *str); +void upstring(char* str); /** Remove leading whitespace from a string. */ -void ltrim(char *str); +void ltrim(char* str); /** Remove trailing whitespace from a string. */ -void rtrim(char *str); +void rtrim(char* str); /** Remove leading and trailing whitespace from a string. */ -void trim(char *str); +void trim(char* str); /** Version of gmx_strcasecmp() that also ignores '-' and '_'. */ -int gmx_strcasecmp_min(const char *str1, const char *str2); +int gmx_strcasecmp_min(const char* str1, const char* str2); /** Version of gmx_strncasecmp() that also ignores '-' and '_'. */ -int gmx_strncasecmp_min(const char *str1, const char *str2, int n); +int gmx_strncasecmp_min(const char* str1, const char* str2, int n); /** Case-insensitive strcmp(). */ -int gmx_strcasecmp(const char *str1, const char *str2); +int gmx_strcasecmp(const char* str1, const char* str2); /** Case-insensitive strncmp(). */ -int gmx_strncasecmp(const char *str1, const char *str2, int n); +int gmx_strncasecmp(const char* str1, const char* str2, int n); /** Creates a duplicate of \p src. */ -char *gmx_strdup(const char *src); +char* gmx_strdup(const char* src); /** Duplicates first \p n characters of \p src. */ -char *gmx_strndup(const char *src, int n); +char* gmx_strndup(const char* src, int n); /*! \brief * Pattern matching with wildcards. @@ -109,14 +109,13 @@ char *gmx_strndup(const char *src, int n); * All other characters are matched literally. * Currently, it is not possible to match literal * or ?. */ -int gmx_wcmatch(const char *pattern, const char *str); +int gmx_wcmatch(const char* pattern, const char* str); /** Return value for gmx_wcmatch() when there is no match. */ #define GMX_NO_WCMATCH 1 /** Magic hash initialization number from Dan J. Bernstein. */ -extern const unsigned int - gmx_string_hash_init; +extern const unsigned int gmx_string_hash_init; /*! \brief * Return a hash of the string according to Dan J. Bernsteins algorithm. @@ -130,8 +129,7 @@ extern const unsigned int * corresponding to several concatenated strings, provide the returned hash * value as hash_init for the second string, etc. */ -unsigned int -gmx_string_fullhash_func(const char *s, unsigned int hash_init); +unsigned int gmx_string_fullhash_func(const char* s, unsigned int hash_init); /*! \brief * Return a hash of the string according to Dan J. Bernsteins algorithm. @@ -144,8 +142,7 @@ gmx_string_fullhash_func(const char *s, unsigned int hash_init); * this routine only uses characters for which isalnum(c) is true, * and all characters are converted to upper case. */ -unsigned int -gmx_string_hash_func(const char *s, unsigned int hash_init); +unsigned int gmx_string_hash_func(const char* s, unsigned int hash_init); /*! \brief * Wraps lines, optionally indenting lines. @@ -156,8 +153,7 @@ gmx_string_hash_func(const char *s, unsigned int hash_init); * If \p bIndentFirst is FALSE, then the first line will not be indented, only * the lines that are created due to wapping. */ -char *wrap_lines(const char *buf, int line_width, int indent, - gmx_bool bIndentFirst); +char* wrap_lines(const char* buf, int line_width, int indent, gmx_bool bIndentFirst); /*! \brief * Convert a string to int64_t. @@ -165,7 +161,7 @@ char *wrap_lines(const char *buf, int line_width, int indent, * This method works as the standard library function strtol(), except that it * does not support different bases. */ -int64_t str_to_int64_t(const char *str, char **endptr); +int64_t str_to_int64_t(const char* str, char** endptr); /** Minimum size of buffer to pass to gmx_step_str(). */ #define STEPSTRSIZE 22 @@ -177,6 +173,6 @@ int64_t str_to_int64_t(const char *str, char **endptr); * When multiple int64_t values are printed in the same printf call, * be sure to call gmx_step_str with different buffers. */ -char *gmx_step_str(int64_t i, char *buf); +char* gmx_step_str(int64_t i, char* buf); #endif diff --git a/src/gromacs/utility/cuda_version_information.cu b/src/gromacs/utility/cuda_version_information.cu index 998e2b623e..f67e1eceb6 100644 --- a/src/gromacs/utility/cuda_version_information.cu +++ b/src/gromacs/utility/cuda_version_information.cu @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,7 +49,7 @@ std::string getCudaDriverVersionString() { return "N/A"; } - return formatString("%d.%d", cuda_driver/1000, cuda_driver%100); + return formatString("%d.%d", cuda_driver / 1000, cuda_driver % 100); } std::string getCudaRuntimeVersionString() @@ -59,7 +59,7 @@ std::string getCudaRuntimeVersionString() { return "N/A"; } - return formatString("%d.%d", cuda_runtime/1000, cuda_runtime%100); + return formatString("%d.%d", cuda_runtime / 1000, cuda_runtime % 100); } -} // namespace +} // namespace gmx diff --git a/src/gromacs/utility/cuda_version_information.h b/src/gromacs/utility/cuda_version_information.h index 446675a816..79b95a8a4d 100644 --- a/src/gromacs/utility/cuda_version_information.h +++ b/src/gromacs/utility/cuda_version_information.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,6 +46,6 @@ std::string getCudaDriverVersionString(); //! Returns a string of the CUDA runtime version. std::string getCudaRuntimeVersionString(); -} // namespace +} // namespace gmx #endif diff --git a/src/gromacs/utility/current_function.h b/src/gromacs/utility/current_function.h index 1408a33b87..1f18cab6ff 100644 --- a/src/gromacs/utility/current_function.h +++ b/src/gromacs/utility/current_function.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -72,36 +72,37 @@ namespace internal inline void current_function_helper() { -#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) -# define GMX_CURRENT_FUNCTION __PRETTY_FUNCTION__ +# define GMX_CURRENT_FUNCTION __PRETTY_FUNCTION__ #elif defined(__DMC__) && (__DMC__ >= 0x810) -# define GMX_CURRENT_FUNCTION __PRETTY_FUNCTION__ +# define GMX_CURRENT_FUNCTION __PRETTY_FUNCTION__ #elif defined(__FUNCSIG__) -# define GMX_CURRENT_FUNCTION __FUNCSIG__ +# define GMX_CURRENT_FUNCTION __FUNCSIG__ -#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) \ + || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) -# define GMX_CURRENT_FUNCTION __FUNCTION__ +# define GMX_CURRENT_FUNCTION __FUNCTION__ #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) -# define GMX_CURRENT_FUNCTION __FUNC__ +# define GMX_CURRENT_FUNCTION __FUNC__ #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) -# define GMX_CURRENT_FUNCTION __func__ +# define GMX_CURRENT_FUNCTION __func__ #else -# define GMX_CURRENT_FUNCTION "(unknown)" +# define GMX_CURRENT_FUNCTION "(unknown)" #endif - } } // namespace internal diff --git a/src/gromacs/utility/datafilefinder.cpp b/src/gromacs/utility/datafilefinder.cpp index 009e2c40ad..8df8f88574 100644 --- a/src/gromacs/utility/datafilefinder.cpp +++ b/src/gromacs/utility/datafilefinder.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,24 +66,22 @@ namespace gmx class DataFileFinder::Impl { - public: - static std::string getDefaultPath(); +public: + static std::string getDefaultPath(); - Impl() : envName_(nullptr), bEnvIsSet_(false) {} + Impl() : envName_(nullptr), bEnvIsSet_(false) {} - const char *envName_; - bool bEnvIsSet_; - std::vector searchPath_; + const char* envName_; + bool bEnvIsSet_; + std::vector searchPath_; }; std::string DataFileFinder::Impl::getDefaultPath() { - const InstallationPrefixInfo installPrefix - = getProgramContext().installationPrefix(); + const InstallationPrefixInfo installPrefix = getProgramContext().installationPrefix(); if (!isNullOrEmpty(installPrefix.path)) { - const char *const dataPath - = installPrefix.bSourceLayout ? "share" : GMX_INSTALL_GMXDATADIR; + const char* const dataPath = installPrefix.bSourceLayout ? "share" : GMX_INSTALL_GMXDATADIR; return Path::join(installPrefix.path, dataPath, "top"); } return std::string(); @@ -93,32 +91,27 @@ std::string DataFileFinder::Impl::getDefaultPath() * DataFileFinder */ -DataFileFinder::DataFileFinder() - : impl_(nullptr) -{ -} +DataFileFinder::DataFileFinder() : impl_(nullptr) {} -DataFileFinder::~DataFileFinder() -{ -} +DataFileFinder::~DataFileFinder() {} -void DataFileFinder::setSearchPathFromEnv(const char *envVarName) +void DataFileFinder::setSearchPathFromEnv(const char* envVarName) { if (!impl_) { impl_.reset(new Impl()); } - impl_->envName_ = envVarName; - const char *const lib = getenv(envVarName); + impl_->envName_ = envVarName; + const char* const lib = getenv(envVarName); if (!isNullOrEmpty(lib)) { - std::vector &path = impl_->searchPath_; // convenience - const std::string defaultPath = impl_->getDefaultPath(); - std::vector tmpPath; + std::vector& path = impl_->searchPath_; // convenience + const std::string defaultPath = impl_->getDefaultPath(); + std::vector tmpPath; Path::splitPathEnvironment(lib, &tmpPath); - std::set pathsSeen; + std::set pathsSeen; pathsSeen.insert(defaultPath); - for (auto &d : tmpPath) + for (auto& d : tmpPath) { if (!pathsSeen.count(d)) { @@ -130,7 +123,7 @@ void DataFileFinder::setSearchPathFromEnv(const char *envVarName) } } -FilePtr DataFileFinder::openFile(const DataFileOptions &options) const +FilePtr DataFileFinder::openFile(const DataFileOptions& options) const { // TODO: There is a small race here, since there is some time between // the exists() calls and actually opening the file. It would be better @@ -150,7 +143,7 @@ FilePtr DataFileFinder::openFile(const DataFileOptions &options) const return TextInputFile::openRawHandle(filename); } -std::string DataFileFinder::findFile(const DataFileOptions &options) const +std::string DataFileFinder::findFile(const DataFileOptions& options) const { if (options.bCurrentDir_ && Path::exists(options.filename_)) { @@ -170,7 +163,7 @@ std::string DataFileFinder::findFile(const DataFileOptions &options) const } } } - const std::string &defaultPath = Impl::getDefaultPath(); + const std::string& defaultPath = Impl::getDefaultPath(); if (!defaultPath.empty()) { std::string testPath = Path::join(defaultPath, options.filename_); @@ -181,10 +174,9 @@ std::string DataFileFinder::findFile(const DataFileOptions &options) const } if (options.bThrow_) { - const char *const envName = (impl_ != nullptr ? impl_->envName_ : nullptr); + const char* const envName = (impl_ != nullptr ? impl_->envName_ : nullptr); const bool bEnvIsSet = (impl_ != nullptr ? impl_->bEnvIsSet_ : false); - std::string message( - formatString("Library file '%s' not found", options.filename_)); + std::string message(formatString("Library file '%s' not found", options.filename_)); if (options.bCurrentDir_) { message.append(" in current dir nor"); @@ -219,15 +211,15 @@ std::string DataFileFinder::findFile(const DataFileOptions &options) const { message.append( formatString("\nYou can set additional directories to search " - "with the %s path variable.", envName)); + "with the %s path variable.", + envName)); } GMX_THROW(FileIOError(message)); } return std::string(); } -std::vector -DataFileFinder::enumerateFiles(const DataFileOptions &options) const +std::vector DataFileFinder::enumerateFiles(const DataFileOptions& options) const { // TODO: Consider if not being able to list one of the directories should // really be a fatal error. Or alternatively, check somewhere else that @@ -236,9 +228,8 @@ DataFileFinder::enumerateFiles(const DataFileOptions &options) const std::vector::const_iterator i; if (options.bCurrentDir_) { - std::vector files - = DirectoryEnumerator::enumerateFilesWithExtension( - ".", options.filename_, false); + std::vector files = + DirectoryEnumerator::enumerateFilesWithExtension(".", options.filename_, false); for (i = files.begin(); i != files.end(); ++i) { result.emplace_back(".", *i, false); @@ -249,21 +240,19 @@ DataFileFinder::enumerateFiles(const DataFileOptions &options) const std::vector::const_iterator j; for (j = impl_->searchPath_.begin(); j != impl_->searchPath_.end(); ++j) { - std::vector files - = DirectoryEnumerator::enumerateFilesWithExtension( - j->c_str(), options.filename_, false); + std::vector files = DirectoryEnumerator::enumerateFilesWithExtension( + j->c_str(), options.filename_, false); for (i = files.begin(); i != files.end(); ++i) { result.emplace_back(*j, *i, false); } } } - const std::string &defaultPath = Impl::getDefaultPath(); + const std::string& defaultPath = Impl::getDefaultPath(); if (!defaultPath.empty()) { - std::vector files - = DirectoryEnumerator::enumerateFilesWithExtension( - defaultPath.c_str(), options.filename_, false); + std::vector files = DirectoryEnumerator::enumerateFilesWithExtension( + defaultPath.c_str(), options.filename_, false); for (i = files.begin(); i != files.end(); ++i) { result.emplace_back(defaultPath, *i, true); diff --git a/src/gromacs/utility/datafilefinder.h b/src/gromacs/utility/datafilefinder.h index e3197d0ce8..43c95e21b1 100644 --- a/src/gromacs/utility/datafilefinder.h +++ b/src/gromacs/utility/datafilefinder.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -75,49 +75,50 @@ class DataFileFinder; */ class DataFileOptions { - public: - /*! \brief - * Constructs default options for searching for a file with the - * specified name. - * - * \param[in] filename File name to search for. - * - * This constructor is not explicit to allow passing a simple string to - * DataFileFinder methods to search for the string with the default - * parameters. - */ - DataFileOptions(const char *filename) - : filename_(filename), bCurrentDir_(true), bThrow_(true) - { - } - //! \copydoc DataFileOptions(const char *) - DataFileOptions(const std::string &filename) - : filename_(filename.c_str()), bCurrentDir_(true), bThrow_(true) - { - } +public: + /*! \brief + * Constructs default options for searching for a file with the + * specified name. + * + * \param[in] filename File name to search for. + * + * This constructor is not explicit to allow passing a simple string to + * DataFileFinder methods to search for the string with the default + * parameters. + */ + DataFileOptions(const char* filename) : filename_(filename), bCurrentDir_(true), bThrow_(true) + { + } + //! \copydoc DataFileOptions(const char *) + DataFileOptions(const std::string& filename) : + filename_(filename.c_str()), + bCurrentDir_(true), + bThrow_(true) + { + } - //! Sets whether to search first in the current (working) directory. - DataFileOptions &includeCurrentDir(bool bInclude) - { - bCurrentDir_ = bInclude; - return *this; - } - //! Sets whether an exception is thrown if the file could not be found. - DataFileOptions &throwIfNotFound(bool bThrow) - { - bThrow_ = bThrow; - return *this; - } + //! Sets whether to search first in the current (working) directory. + DataFileOptions& includeCurrentDir(bool bInclude) + { + bCurrentDir_ = bInclude; + return *this; + } + //! Sets whether an exception is thrown if the file could not be found. + DataFileOptions& throwIfNotFound(bool bThrow) + { + bThrow_ = bThrow; + return *this; + } - private: - const char *filename_; - bool bCurrentDir_; - bool bThrow_; +private: + const char* filename_; + bool bCurrentDir_; + bool bThrow_; - /*! \brief - * Needed to access the members without otherwise unnecessary accessors. - */ - friend class DataFileFinder; + /*! \brief + * Needed to access the members without otherwise unnecessary accessors. + */ + friend class DataFileFinder; }; /*! \brief @@ -129,8 +130,10 @@ class DataFileOptions struct DataFileInfo { //! Initializes the structure with given values. - DataFileInfo(const std::string &dir, const std::string &name, bool bDefault) - : dir(dir), name(name), bFromDefaultDir(bDefault) + DataFileInfo(const std::string& dir, const std::string& name, bool bDefault) : + dir(dir), + name(name), + bFromDefaultDir(bDefault) { } @@ -156,7 +159,7 @@ struct DataFileInfo * Consider replacing with an enum that identifies the source (current dir, * GMXLIB, default). */ - bool bFromDefaultDir; + bool bFromDefaultDir; }; /*! \brief @@ -167,91 +170,91 @@ struct DataFileInfo */ class DataFileFinder { - public: - /*! \brief - * Constructs a default data file finder. - * - * The constructed finder searches only in the directory specified by - * the global program context (see IProgramContext), and - * optionally in the current directory. - * - * Does not throw. - */ - DataFileFinder(); - ~DataFileFinder(); +public: + /*! \brief + * Constructs a default data file finder. + * + * The constructed finder searches only in the directory specified by + * the global program context (see IProgramContext), and + * optionally in the current directory. + * + * Does not throw. + */ + DataFileFinder(); + ~DataFileFinder(); - /*! \brief - * Adds search path from an environment variable. - * - * \param[in] envVarName Name of the environment variable to use. - * \throws std::bad_alloc if out of memory. - * - * If the specified environment variable is set, it is interpreted like - * a `PATH` environment variable on the platform (split at appropriate - * separators), and each path found is added to the search path this - * finder searches. The added paths take precedence over the default - * directory specified by the global program context, but the current - * directory is searched first. - */ - void setSearchPathFromEnv(const char *envVarName); + /*! \brief + * Adds search path from an environment variable. + * + * \param[in] envVarName Name of the environment variable to use. + * \throws std::bad_alloc if out of memory. + * + * If the specified environment variable is set, it is interpreted like + * a `PATH` environment variable on the platform (split at appropriate + * separators), and each path found is added to the search path this + * finder searches. The added paths take precedence over the default + * directory specified by the global program context, but the current + * directory is searched first. + */ + void setSearchPathFromEnv(const char* envVarName); - /*! \brief - * Opens a data file (if found) in an RAII-style `FILE` handle. - * - * \param[in] options Identifies the file to be searched for. - * \returns The opened file handle, or `NULL` if the file could not be - * found and exceptions were turned off. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if - * - no such file can be found, and \p options specifies that an - * exception should be thrown, or - * - there is an error opening the file (note that a file is skipped - * during the search if the user does not have rights to open the - * file at all). - * - * See findFile() for more details. - */ - FilePtr openFile(const DataFileOptions &options) const; - /*! \brief - * Finds a full path to a data file if found. - * - * \param[in] options Identifies the file to be searched for. - * \returns Full path to the data file, or an empty string if the file - * could not be found and exceptions were turned off. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if no such file can be found, and \p options - * specifies that an exception should be thrown. - * - * Searches for a data file in the search paths configured for the - * finder, as well as in the current directory if so required. - * Returns the full path to the first file found. - */ - std::string findFile(const DataFileOptions &options) const; - /*! \brief - * Enumerates files in the data directories. - * - * \param[in] options Idenfies files to be searched for. - * \returns Information about each found file. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if no such file can be found, and \p options - * specifies that an exception should be thrown. - * - * Enumerates all files in the data directories that have the - * extension/suffix specified by the file name in \p options. - * Unlike findFile() and openFile(), this only works on files that are - * in the actual data directories, not for any entry within - * subdirectories of those. - * See DataFileInfo for details on what is returned for each found - * file. - * Files from the same directory will be returned as a continuous block - * in the returned vector. - */ - std::vector enumerateFiles(const DataFileOptions &options) const; + /*! \brief + * Opens a data file (if found) in an RAII-style `FILE` handle. + * + * \param[in] options Identifies the file to be searched for. + * \returns The opened file handle, or `NULL` if the file could not be + * found and exceptions were turned off. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if + * - no such file can be found, and \p options specifies that an + * exception should be thrown, or + * - there is an error opening the file (note that a file is skipped + * during the search if the user does not have rights to open the + * file at all). + * + * See findFile() for more details. + */ + FilePtr openFile(const DataFileOptions& options) const; + /*! \brief + * Finds a full path to a data file if found. + * + * \param[in] options Identifies the file to be searched for. + * \returns Full path to the data file, or an empty string if the file + * could not be found and exceptions were turned off. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if no such file can be found, and \p options + * specifies that an exception should be thrown. + * + * Searches for a data file in the search paths configured for the + * finder, as well as in the current directory if so required. + * Returns the full path to the first file found. + */ + std::string findFile(const DataFileOptions& options) const; + /*! \brief + * Enumerates files in the data directories. + * + * \param[in] options Idenfies files to be searched for. + * \returns Information about each found file. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if no such file can be found, and \p options + * specifies that an exception should be thrown. + * + * Enumerates all files in the data directories that have the + * extension/suffix specified by the file name in \p options. + * Unlike findFile() and openFile(), this only works on files that are + * in the actual data directories, not for any entry within + * subdirectories of those. + * See DataFileInfo for details on what is returned for each found + * file. + * Files from the same directory will be returned as a continuous block + * in the returned vector. + */ + std::vector enumerateFiles(const DataFileOptions& options) const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/defaultinitializationallocator.h b/src/gromacs/utility/defaultinitializationallocator.h index a9e8ac2639..a98dc4491d 100644 --- a/src/gromacs/utility/defaultinitializationallocator.h +++ b/src/gromacs/utility/defaultinitializationallocator.h @@ -54,34 +54,35 @@ namespace gmx * * This can be used to avoid initialization e.g. on resize() in std::vector. */ -template > +template> class DefaultInitializationAllocator : public A { typedef std::allocator_traits a_t; - public: - template struct rebind { - using other = - DefaultInitializationAllocator < U, typename a_t::template rebind_alloc < U>>; - }; - using A::A; +public: + template + struct rebind + { + using other = DefaultInitializationAllocator>; + }; - /*! \brief Constructs an object and default initializes */ - template - void construct(U* ptr) - noexcept(std::is_nothrow_default_constructible::value) { - ::new(static_cast(ptr))U; - } + using A::A; - /*! \brief Constructs an object and value initializes */ - template - void construct(U* ptr, Args && ... args) - { - a_t::construct(static_cast(*this), - ptr, std::forward(args) ...); - } + /*! \brief Constructs an object and default initializes */ + template + void construct(U* ptr) noexcept(std::is_nothrow_default_constructible::value) + { + ::new (static_cast(ptr)) U; + } + + /*! \brief Constructs an object and value initializes */ + template + void construct(U* ptr, Args&&... args) + { + a_t::construct(static_cast(*this), ptr, std::forward(args)...); + } }; -} // namespace gmx +} // namespace gmx #endif // GMX_UTILITY_DEFAULTINITIALIZATIONALLOCATOR_H diff --git a/src/gromacs/utility/dir_separator.h b/src/gromacs/utility/dir_separator.h index f4bad600bd..203d5ac971 100644 --- a/src/gromacs/utility/dir_separator.h +++ b/src/gromacs/utility/dir_separator.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,9 +61,9 @@ * upon path objects rather than raw path strings. */ #if GMX_NATIVE_WINDOWS -#define DIR_SEPARATOR '\\' +# define DIR_SEPARATOR '\\' #else -#define DIR_SEPARATOR '/' +# define DIR_SEPARATOR '/' #endif #endif diff --git a/src/gromacs/utility/directoryenumerator.cpp b/src/gromacs/utility/directoryenumerator.cpp index 230f456be8..439473af3a 100644 --- a/src/gromacs/utility/directoryenumerator.cpp +++ b/src/gromacs/utility/directoryenumerator.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,10 +54,10 @@ #include #if HAVE_DIRENT_H -#include +# include #endif #if GMX_NATIVE_WINDOWS -#include +# include #endif #include "gromacs/utility/exceptions.h" @@ -80,155 +80,143 @@ namespace gmx // TODO: Consider if Windows provides more error details through other APIs. class DirectoryEnumerator::Impl { - public: - static Impl *init(const char *dirname, bool bThrow) +public: + static Impl* init(const char* dirname, bool bThrow) + { + std::string tmpname(dirname); + // Remove possible trailing directory separator. + // TODO: Use a method in gmx::Path instead. + if (tmpname.back() == '/' || tmpname.back() == '\\') { - std::string tmpname(dirname); - // Remove possible trailing directory separator. - // TODO: Use a method in gmx::Path instead. - if (tmpname.back() == '/' || tmpname.back() == '\\') - { - tmpname.pop_back(); - } + tmpname.pop_back(); + } - // Add wildcard. - tmpname.append("/*"); + // Add wildcard. + tmpname.append("/*"); - errno = 0; - _finddata_t finddata; - intptr_t handle = _findfirst(tmpname.c_str(), &finddata); - if (handle < 0L) + errno = 0; + _finddata_t finddata; + intptr_t handle = _findfirst(tmpname.c_str(), &finddata); + if (handle < 0L) + { + if (errno != ENOENT && bThrow) { - if (errno != ENOENT && bThrow) - { - const int code = errno; - const std::string message = - formatString("Failed to list files in directory '%s'", - dirname); - GMX_THROW_WITH_ERRNO(FileIOError(message), "_findfirst", code); - } - return NULL; + const int code = errno; + const std::string message = + formatString("Failed to list files in directory '%s'", dirname); + GMX_THROW_WITH_ERRNO(FileIOError(message), "_findfirst", code); } - return new Impl(handle, finddata); + return NULL; } - Impl(intptr_t handle, _finddata_t finddata) - : windows_handle(handle), finddata(finddata), bFirst_(true) - { - } - ~Impl() + return new Impl(handle, finddata); + } + Impl(intptr_t handle, _finddata_t finddata) : + windows_handle(handle), + finddata(finddata), + bFirst_(true) + { + } + ~Impl() { _findclose(windows_handle); } + + bool nextFile(std::string* filename) + { + if (bFirst_) { - _findclose(windows_handle); + *filename = finddata.name; + bFirst_ = false; + return true; } - - bool nextFile(std::string *filename) + else { - if (bFirst_) - { - *filename = finddata.name; - bFirst_ = false; - return true; - } - else + errno = 0; + if (_findnext(windows_handle, &finddata) != 0) { - errno = 0; - if (_findnext(windows_handle, &finddata) != 0) + if (errno == 0 || errno == ENOENT) + { + filename->clear(); + return false; + } + else { - if (errno == 0 || errno == ENOENT) - { - filename->clear(); - return false; - } - else - { - GMX_THROW_WITH_ERRNO( - FileIOError("Failed to list files in a directory"), - "_findnext", errno); - } + GMX_THROW_WITH_ERRNO(FileIOError("Failed to list files in a directory"), + "_findnext", errno); } - *filename = finddata.name; - return true; } + *filename = finddata.name; + return true; } + } - private: - intptr_t windows_handle; - _finddata_t finddata; - bool bFirst_; +private: + intptr_t windows_handle; + _finddata_t finddata; + bool bFirst_; }; #elif HAVE_DIRENT_H class DirectoryEnumerator::Impl { - public: - static Impl *init(const char *dirname, bool bThrow) +public: + static Impl* init(const char* dirname, bool bThrow) + { + errno = 0; + DIR* handle = opendir(dirname); + if (handle == nullptr) { - errno = 0; - DIR *handle = opendir(dirname); - if (handle == nullptr) + if (bThrow) { - if (bThrow) - { - const int code = errno; - const std::string message = - formatString("Failed to list files in directory '%s'", - dirname); - GMX_THROW_WITH_ERRNO(FileIOError(message), "opendir", code); - } - return nullptr; + const int code = errno; + const std::string message = + formatString("Failed to list files in directory '%s'", dirname); + GMX_THROW_WITH_ERRNO(FileIOError(message), "opendir", code); } - return new Impl(handle); - } - explicit Impl(DIR *handle) : dirent_handle(handle) {} - ~Impl() - { - closedir(dirent_handle); + return nullptr; } + return new Impl(handle); + } + explicit Impl(DIR* handle) : dirent_handle(handle) {} + ~Impl() { closedir(dirent_handle); } - bool nextFile(std::string *filename) + bool nextFile(std::string* filename) + { + errno = 0; + dirent* p = readdir(dirent_handle); + if (p == nullptr) { - errno = 0; - dirent *p = readdir(dirent_handle); - if (p == nullptr) + if (errno == 0) { - if (errno == 0) - { - // All the files have been found. - filename->clear(); - return false; - } - else - { - GMX_THROW_WITH_ERRNO( - FileIOError("Failed to list files in a directory"), - "readdir", errno); - } + // All the files have been found. + filename->clear(); + return false; + } + else + { + GMX_THROW_WITH_ERRNO(FileIOError("Failed to list files in a directory"), "readdir", errno); } - *filename = p->d_name; - return true; } + *filename = p->d_name; + return true; + } - private: - DIR *dirent_handle; +private: + DIR* dirent_handle; }; #else class DirectoryEnumerator::Impl { - public: - static Impl *init(const char * /*dirname*/, bool /*bThrow*/) - { - std::string message( - "Source compiled without POSIX dirent or Windows support " - "- cannot scan directories. In the very unlikely event " - "this is not a compile-time mistake you could consider " - "implementing support for your platform in " - "directoryenumerator.cpp, but contact the developers " - "to make sure it's really necessary!"); - GMX_THROW(NotImplementedError(message)); - } +public: + static Impl* init(const char* /*dirname*/, bool /*bThrow*/) + { + std::string message( + "Source compiled without POSIX dirent or Windows support " + "- cannot scan directories. In the very unlikely event " + "this is not a compile-time mistake you could consider " + "implementing support for your platform in " + "directoryenumerator.cpp, but contact the developers " + "to make sure it's really necessary!"); + GMX_THROW(NotImplementedError(message)); + } - bool nextFile(std::string * /*filename*/) - { - return false; - } + bool nextFile(std::string* /*filename*/) { return false; } }; #endif @@ -237,9 +225,9 @@ class DirectoryEnumerator::Impl */ // static -std::vector -DirectoryEnumerator::enumerateFilesWithExtension( - const char *dirname, const char *extension, bool bThrow) +std::vector DirectoryEnumerator::enumerateFilesWithExtension(const char* dirname, + const char* extension, + bool bThrow) { std::vector result; DirectoryEnumerator dir(dirname, bThrow); @@ -248,8 +236,7 @@ DirectoryEnumerator::enumerateFilesWithExtension( { if (debug) { - std::fprintf(debug, "dir '%s' file '%s'\n", - dirname, nextName.c_str()); + std::fprintf(debug, "dir '%s' file '%s'\n", dirname, nextName.c_str()); } // TODO: What about case sensitivity? if (endsWith(nextName, extension)) @@ -263,27 +250,22 @@ DirectoryEnumerator::enumerateFilesWithExtension( } -DirectoryEnumerator::DirectoryEnumerator(const char *dirname, bool bThrow) - : impl_(nullptr) +DirectoryEnumerator::DirectoryEnumerator(const char* dirname, bool bThrow) : impl_(nullptr) { GMX_RELEASE_ASSERT(dirname != nullptr && dirname[0] != '\0', "Attempted to open empty/null directory path"); impl_.reset(Impl::init(dirname, bThrow)); } -DirectoryEnumerator::DirectoryEnumerator(const std::string &dirname, bool bThrow) - : impl_(nullptr) +DirectoryEnumerator::DirectoryEnumerator(const std::string& dirname, bool bThrow) : impl_(nullptr) { - GMX_RELEASE_ASSERT(!dirname.empty(), - "Attempted to open empty/null directory path"); + GMX_RELEASE_ASSERT(!dirname.empty(), "Attempted to open empty/null directory path"); impl_.reset(Impl::init(dirname.c_str(), bThrow)); } -DirectoryEnumerator::~DirectoryEnumerator() -{ -} +DirectoryEnumerator::~DirectoryEnumerator() {} -bool DirectoryEnumerator::nextFile(std::string *filename) +bool DirectoryEnumerator::nextFile(std::string* filename) { if (impl_ == nullptr) { diff --git a/src/gromacs/utility/directoryenumerator.h b/src/gromacs/utility/directoryenumerator.h index bb4a05006f..18bf791982 100644 --- a/src/gromacs/utility/directoryenumerator.h +++ b/src/gromacs/utility/directoryenumerator.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,66 +63,67 @@ namespace gmx */ class DirectoryEnumerator { - public: - /*! \brief - * Convenience function to list files with certain extension from a - * directory. - * - * \param[in] dirname Path to the directory to list. - * \param[in] extension List files with the given extension - * (or suffix in file name). - * \param[in] bThrow Whether failure to open the directory should throw. - * \returns List of files with the given extension in \p dirname. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if opening the directory fails and `bThrow == true`. - * \throws FileIOError if some other I/O error occurs. - */ - static std::vector enumerateFilesWithExtension( - const char *dirname, const char *extension, bool bThrow); +public: + /*! \brief + * Convenience function to list files with certain extension from a + * directory. + * + * \param[in] dirname Path to the directory to list. + * \param[in] extension List files with the given extension + * (or suffix in file name). + * \param[in] bThrow Whether failure to open the directory should throw. + * \returns List of files with the given extension in \p dirname. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if opening the directory fails and `bThrow == true`. + * \throws FileIOError if some other I/O error occurs. + */ + static std::vector enumerateFilesWithExtension(const char* dirname, + const char* extension, + bool bThrow); - /*! \brief - * Opens a directory for listing. - * - * \param[in] dirname Path to the directory to list. - * \param[in] bThrow Whether failure to open the directory should throw. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if opening the directory fails and `bThrow == true` - */ - explicit DirectoryEnumerator(const char *dirname, bool bThrow = true); - //! \copydoc DirectoryEnumerator(const char *, bool) - explicit DirectoryEnumerator(const std::string &dirname, bool bThrow = true); - ~DirectoryEnumerator(); + /*! \brief + * Opens a directory for listing. + * + * \param[in] dirname Path to the directory to list. + * \param[in] bThrow Whether failure to open the directory should throw. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if opening the directory fails and `bThrow == true` + */ + explicit DirectoryEnumerator(const char* dirname, bool bThrow = true); + //! \copydoc DirectoryEnumerator(const char *, bool) + explicit DirectoryEnumerator(const std::string& dirname, bool bThrow = true); + ~DirectoryEnumerator(); - /*! \brief - * Gets next file in a directory. - * - * \param[out] filename Name of the next file. - * \returns `false` if there were no more files. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError if listing the next file fails. - * - * If all files from the directory have been returned (or there are no - * files in the directory and this is the first call), the method - * returns `false` and \p filename is cleared. - * Otherwise, the return value is `true` and the first/next file name - * is returned in \p filename. - * \p filename will not contain any path information, only the name of - * the file. - * - * If `bThrow` passed to the constructor was `false` and the directory - * was not successfully opened, the first call to this function will - * return `false`. - * - * This method is not thread safe when called on the same - * object by multiple threads. Such use requires external - * synchronization. - */ - bool nextFile(std::string *filename); + /*! \brief + * Gets next file in a directory. + * + * \param[out] filename Name of the next file. + * \returns `false` if there were no more files. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError if listing the next file fails. + * + * If all files from the directory have been returned (or there are no + * files in the directory and this is the first call), the method + * returns `false` and \p filename is cleared. + * Otherwise, the return value is `true` and the first/next file name + * is returned in \p filename. + * \p filename will not contain any path information, only the name of + * the file. + * + * If `bThrow` passed to the constructor was `false` and the directory + * was not successfully opened, the first call to this function will + * return `false`. + * + * This method is not thread safe when called on the same + * object by multiple threads. Such use requires external + * synchronization. + */ + bool nextFile(std::string* filename); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/enumerationhelpers.h b/src/gromacs/utility/enumerationhelpers.h index 20f11e908b..21793ff34f 100644 --- a/src/gromacs/utility/enumerationhelpers.h +++ b/src/gromacs/utility/enumerationhelpers.h @@ -103,68 +103,82 @@ namespace gmx * \tparam Last Last constant or number thereof (assumes a default 'Count' member). * \tparam Step Step increment. */ -template -< - typename EnumType, - EnumType Last = EnumType::Count, - unsigned int Step = 1 -> +template class EnumerationIterator final { - public: - //! Convenience alias - using IntegerType = std::underlying_type_t; +public: + //! Convenience alias + using IntegerType = std::underlying_type_t; - /*! \name Iterator type traits - * Satisfies the requirements for STL forward iterator. - * \{ - */ - using iterator_category = std::forward_iterator_tag; - using value_type = EnumType; - using difference_type = std::ptrdiff_t; - using pointer = EnumType*; - using reference = EnumType&; - //! \} + /*! \name Iterator type traits + * Satisfies the requirements for STL forward iterator. + * \{ + */ + using iterator_category = std::forward_iterator_tag; + using value_type = EnumType; + using difference_type = std::ptrdiff_t; + using pointer = EnumType*; + using reference = EnumType&; + //! \} - constexpr EnumerationIterator() noexcept : - m_current { 0 } // Assumes 0 is the first constant - { } - //! Copy constructor - constexpr EnumerationIterator(const EnumType index) noexcept - : m_current(static_cast(index)) - { } - //! Pre-increment operator - EnumerationIterator operator++() - { - m_current += Step; - return *this; - } - //! Post-increment operator - EnumerationIterator operator++(int) - { - EnumerationIterator old_val { *this }; - m_current += Step; - return old_val; - } - //! Dereference operator - EnumType operator*() const - { - GMX_ASSERT(m_current < static_cast(Last), "dereferencing out of range"); - return static_cast(m_current); - } + constexpr EnumerationIterator() noexcept : m_current{ 0 } // Assumes 0 is the first constant + { + } + //! Copy constructor + constexpr EnumerationIterator(const EnumType index) noexcept : + m_current(static_cast(index)) + { + } + //! Pre-increment operator + EnumerationIterator operator++() + { + m_current += Step; + return *this; + } + //! Post-increment operator + EnumerationIterator operator++(int) + { + EnumerationIterator old_val{ *this }; + m_current += Step; + return old_val; + } + //! Dereference operator + EnumType operator*() const + { + GMX_ASSERT(m_current < static_cast(Last), "dereferencing out of range"); + return static_cast(m_current); + } - /*!@{*/ - //! Comparision operators - bool operator== (const EnumerationIterator other) const noexcept { return m_current == other.m_current; } - bool operator!= (const EnumerationIterator other) const noexcept { return m_current != other.m_current; } - bool operator< (const EnumerationIterator other) const noexcept { return m_current < other.m_current; } - bool operator> (const EnumerationIterator other) const noexcept { return m_current > other.m_current; } - bool operator<= (const EnumerationIterator other) const noexcept { return m_current <= other.m_current; } - bool operator>= (const EnumerationIterator other) const noexcept { return m_current >= other.m_current; } - /*!@}*/ + /*!@{*/ + //! Comparision operators + bool operator==(const EnumerationIterator other) const noexcept + { + return m_current == other.m_current; + } + bool operator!=(const EnumerationIterator other) const noexcept + { + return m_current != other.m_current; + } + bool operator<(const EnumerationIterator other) const noexcept + { + return m_current < other.m_current; + } + bool operator>(const EnumerationIterator other) const noexcept + { + return m_current > other.m_current; + } + bool operator<=(const EnumerationIterator other) const noexcept + { + return m_current <= other.m_current; + } + bool operator>=(const EnumerationIterator other) const noexcept + { + return m_current >= other.m_current; + } + /*!@}*/ - private: - IntegerType m_current; +private: + IntegerType m_current; }; /*! \libinternal @@ -183,23 +197,18 @@ class EnumerationIterator final * \tparam Last Last constant or number thereof (assumes a default 'Count' member). * \tparam Step Step increment. */ -template -< - typename EnumType, - EnumType Last = EnumType::Count, - unsigned int Step = 1 -> +template class EnumerationWrapper final { - public: - //! Convenience alias. - using IteratorType = EnumerationIterator; +public: + //! Convenience alias. + using IteratorType = EnumerationIterator; - //! Functions required for range-based for statements to work. - /*!@{*/ - IteratorType begin() const { return IteratorType {}; } - IteratorType end() const { return IteratorType { Last }; } - /*!@}*/ + //! Functions required for range-based for statements to work. + /*!@{*/ + IteratorType begin() const { return IteratorType{}; } + IteratorType end() const { return IteratorType{ Last }; } + /*!@}*/ }; /*! \libinternal @@ -214,12 +223,10 @@ class EnumerationWrapper final * \tparam DataType Type of the data stored in the array. * \tparam ArraySize Size in entries of the array. */ -template -< - typename EnumType, // The enum (class) type. - typename DataType, // Type of the data stored in the array. - EnumType ArraySize = EnumType::Count // Size in entries of the array. -> +template struct EnumerationArray final { //! Convenience alias @@ -232,29 +239,29 @@ struct EnumerationArray final DataType m_elements[std::size_t(ArraySize)]; //! Returns an object that provides iterators over the keys. - static constexpr EnumerationWrapperType keys() { return EnumerationWrapperType {}; } + static constexpr EnumerationWrapperType keys() { return EnumerationWrapperType{}; } //! Returns the size of the enumeration. static constexpr std::size_t size() { return std::size_t(ArraySize); } /*!@{*/ //! Array access with asserts: - DataType &operator[](const std::size_t index) + DataType& operator[](const std::size_t index) { GMX_ASSERT(index < size(), "index out of range"); return m_elements[index]; } - const DataType &operator[](const std::size_t index) const + const DataType& operator[](const std::size_t index) const { GMX_ASSERT(index < size(), "index out of range"); return m_elements[index]; } - DataType &operator[](const EnumType index) + DataType& operator[](const EnumType index) { GMX_ASSERT(std::size_t(index) < size(), "index out of range"); return m_elements[std::size_t(index)]; } - const DataType &operator[](const EnumType index) const + const DataType& operator[](const EnumType index) const { GMX_ASSERT(std::size_t(index) < size(), "index out of range"); return m_elements[std::size_t(index)]; @@ -263,32 +270,32 @@ struct EnumerationArray final /*!@{*/ //! Range iterators (unchecked) - using iterator = DataType *; - using const_iterator = const DataType *; + using iterator = DataType*; + using const_iterator = const DataType*; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; /*!@}*/ /*!@{*/ //! Getters for forward iterators for ranges - iterator begin() { return &m_elements[0]; } - iterator end() { return &m_elements[size()]; } - const_iterator begin() const { return &m_elements[0]; } - const_iterator end() const { return &m_elements[size()]; } + iterator begin() { return &m_elements[0]; } + iterator end() { return &m_elements[size()]; } + const_iterator begin() const { return &m_elements[0]; } + const_iterator end() const { return &m_elements[size()]; } /*!@}*/ /*!@{*/ //! Getters for reverse iterators for ranges - reverse_iterator rbegin() { return reverse_iterator { end() }; } - reverse_iterator rend() { return reverse_iterator { begin() }; } - const_reverse_iterator rbegin() const { return const_reverse_iterator { end() }; } - const_reverse_iterator rend() const { return const_reverse_iterator { begin() }; } + reverse_iterator rbegin() { return reverse_iterator{ end() }; } + reverse_iterator rend() { return reverse_iterator{ begin() }; } + const_reverse_iterator rbegin() const { return const_reverse_iterator{ end() }; } + const_reverse_iterator rend() const { return const_reverse_iterator{ begin() }; } /*!@}*/ /*!@{*/ //! Pointers (unchecked) - using pointer = DataType *; - using const_pointer = const DataType *; + using pointer = DataType*; + using const_pointer = const DataType*; /*!@}*/ //! Returns a const raw pointer to the contents of the array. @@ -308,8 +315,8 @@ struct EnumerationArray final * member function (such as keys()) via an object rather than the * type, but clang-tidy warns about that. So instead we make available * a free function that calls that static method. */ -template -typename EnumerationArrayType::EnumerationWrapperType keysOf(const EnumerationArrayType & /* arrayObject */) +template +typename EnumerationArrayType::EnumerationWrapperType keysOf(const EnumerationArrayType& /* arrayObject */) { return EnumerationArrayType::keys(); } diff --git a/src/gromacs/utility/errorcodes.cpp b/src/gromacs/utility/errorcodes.cpp index d18c8bd116..76cb0e4efe 100644 --- a/src/gromacs/utility/errorcodes.cpp +++ b/src/gromacs/utility/errorcodes.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,8 +56,7 @@ namespace * * \ingroup module_utility */ -const char *const error_names[] = -{ +const char* const error_names[] = { "No error", "Out of memory", "File not found", @@ -78,9 +77,9 @@ const char *const error_names[] = "Unknown error", }; -} // namespace +} // namespace -const char *getErrorCodeString(int errorcode) +const char* getErrorCodeString(int errorcode) { if (errorcode < 0 || errorcode >= eeUnknownError) { diff --git a/src/gromacs/utility/errorcodes.h b/src/gromacs/utility/errorcodes.h index 08f94e1d38..3af1c18990 100644 --- a/src/gromacs/utility/errorcodes.h +++ b/src/gromacs/utility/errorcodes.h @@ -110,7 +110,7 @@ enum ErrorCode * * This function does not throw. */ -const char *getErrorCodeString(int errorcode); +const char* getErrorCodeString(int errorcode); /*!\}*/ diff --git a/src/gromacs/utility/errorformat.cpp b/src/gromacs/utility/errorformat.cpp index 1fc9d8b9cb..a4d1e8643b 100644 --- a/src/gromacs/utility/errorformat.cpp +++ b/src/gromacs/utility/errorformat.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,17 +61,16 @@ namespace gmx namespace internal { -void printFatalErrorHeader(FILE *fp, const char *title, - const char *func, const char *file, int line) +void printFatalErrorHeader(FILE* fp, const char* title, const char* func, const char* file, int line) { // In case ProgramInfo is not initialized and there is an issue with the // initialization, fall back to "GROMACS". - const char *programName = "GROMACS"; + const char* programName = "GROMACS"; try { programName = getProgramContext().displayName(); } - catch (const std::exception &) + catch (const std::exception&) { } @@ -78,8 +78,7 @@ void printFatalErrorHeader(FILE *fp, const char *title, std::fprintf(fp, "Program: %s, version %s\n", programName, gmx_version()); if (file != nullptr) { - std::fprintf(fp, "Source file: %s (line %d)\n", - Path::stripSourcePrefix(file), line); + std::fprintf(fp, "Source file: %s (line %d)\n", Path::stripSourcePrefix(file), line); } if (func != nullptr) { @@ -93,12 +92,12 @@ void printFatalErrorHeader(FILE *fp, const char *title, std::fprintf(fp, "%s:\n", title); } -void printFatalErrorMessageLine(FILE *fp, const char *text, int indent) +void printFatalErrorMessageLine(FILE* fp, const char* text, int indent) { gmx::TextLineWrapper wrapper; wrapper.settings().setLineLength(78 - indent); - size_t lineStart = 0; - size_t length = std::strlen(text); + size_t lineStart = 0; + size_t length = std::strlen(text); while (lineStart < length) { size_t nextLineStart = wrapper.findNextLine(text, lineStart); @@ -112,15 +111,16 @@ void printFatalErrorMessageLine(FILE *fp, const char *text, int indent) } } -void printFatalErrorFooter(FILE *fp) +void printFatalErrorFooter(FILE* fp) { std::fprintf(fp, "\n"); - std::fprintf(fp, "For more information and tips for troubleshooting, please check the GROMACS\n" + std::fprintf(fp, + "For more information and tips for troubleshooting, please check the GROMACS\n" "website at http://www.gromacs.org/Documentation/Errors"); std::fprintf(fp, "\n-------------------------------------------------------\n"); } -} // namespace internal +} // namespace internal //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/errorformat.h b/src/gromacs/utility/errorformat.h index eabdd8967b..54a14e7bce 100644 --- a/src/gromacs/utility/errorformat.h +++ b/src/gromacs/utility/errorformat.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,8 +58,7 @@ namespace internal * * \ingroup module_utility */ -void printFatalErrorHeader(FILE *fp, const char *title, - const char *func, const char *file, int line); +void printFatalErrorHeader(FILE* fp, const char* title, const char* func, const char* file, int line); /*! \brief * Formats a line of fatal error message text. * @@ -67,7 +66,7 @@ void printFatalErrorHeader(FILE *fp, const char *title, * * \ingroup module_utility */ -void printFatalErrorMessageLine(FILE *fp, const char *text, int indent); +void printFatalErrorMessageLine(FILE* fp, const char* text, int indent); /*! \brief * Formats a common footer for fatal error messages. * @@ -75,9 +74,9 @@ void printFatalErrorMessageLine(FILE *fp, const char *text, int indent); * * \ingroup module_utility */ -void printFatalErrorFooter(FILE *fp); +void printFatalErrorFooter(FILE* fp); -} // namespace internal +} // namespace internal //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/exceptions.cpp b/src/gromacs/utility/exceptions.cpp index 0e355ac9a2..142ac476fc 100644 --- a/src/gromacs/utility/exceptions.cpp +++ b/src/gromacs/utility/exceptions.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,17 +69,15 @@ namespace gmx namespace internal { -IExceptionInfo::~IExceptionInfo() -{ -} +IExceptionInfo::~IExceptionInfo() {} class ExceptionData { - public: - std::map infos_; +public: + std::map infos_; }; -} // namespace internal +} // namespace internal namespace { @@ -98,43 +97,42 @@ namespace */ class ErrorMessage { - public: - /*! \brief - * Creates an error message object with the specified text. - * - * \param[in] text Text for the message. - */ - explicit ErrorMessage(const std::string &text); - - //! Whether this object is a context string. - bool isContext() const { return static_cast(child_); } - //! Returns the text for this object. - const std::string &text() const { return text_; } - /*! \brief - * Returns the child object for a context object. - * - * Must not be called if isContext() returns false. - */ - const ErrorMessage &child() const - { - GMX_ASSERT(isContext(), - "Attempting to access nonexistent message object"); - return *child_; - } +public: + /*! \brief + * Creates an error message object with the specified text. + * + * \param[in] text Text for the message. + */ + explicit ErrorMessage(const std::string& text); + + //! Whether this object is a context string. + bool isContext() const { return static_cast(child_); } + //! Returns the text for this object. + const std::string& text() const { return text_; } + /*! \brief + * Returns the child object for a context object. + * + * Must not be called if isContext() returns false. + */ + const ErrorMessage& child() const + { + GMX_ASSERT(isContext(), "Attempting to access nonexistent message object"); + return *child_; + } - /*! \brief - * Creates a new message object with context prepended. - * - * \param[in] context Context string to add. - * \returns New error message object that has \p context as its text - * and \c this as its child. - * \throws std::bad_alloc if out of memory. - */ - ErrorMessage prependContext(const std::string &context) const; - - private: - std::string text_; - std::shared_ptr child_; + /*! \brief + * Creates a new message object with context prepended. + * + * \param[in] context Context string to add. + * \returns New error message object that has \p context as its text + * and \c this as its child. + * \throws std::bad_alloc if out of memory. + */ + ErrorMessage prependContext(const std::string& context) const; + +private: + std::string text_; + std::shared_ptr child_; }; /*! \internal \brief @@ -142,11 +140,9 @@ class ErrorMessage * * \ingroup module_utility */ -typedef ExceptionInfo - ExceptionInfoMessage; +typedef ExceptionInfo ExceptionInfoMessage; -ErrorMessage::ErrorMessage(const std::string &text) - : text_(text) +ErrorMessage::ErrorMessage(const std::string& text) : text_(text) { size_t length = text_.find_last_not_of(" \n"); if (length == std::string::npos) @@ -156,8 +152,7 @@ ErrorMessage::ErrorMessage(const std::string &text) text_.resize(length + 1); } -ErrorMessage -ErrorMessage::prependContext(const std::string &context) const +ErrorMessage ErrorMessage::prependContext(const std::string& context) const { ErrorMessage newMessage(context); newMessage.child_ = std::make_shared(*this); @@ -169,17 +164,16 @@ ErrorMessage::prependContext(const std::string &context) const * * \ingroup module_utility */ -typedef ExceptionInfo - ExceptionInfoNestedExceptions; +typedef ExceptionInfo ExceptionInfoNestedExceptions; -} // namespace +} // namespace /******************************************************************** * GromacsException */ -GromacsException::GromacsException(const ExceptionInitializer &details) - : data_(new internal::ExceptionData) +GromacsException::GromacsException(const ExceptionInitializer& details) : + data_(new internal::ExceptionData) { setInfo(ExceptionInfoMessage(ErrorMessage(details.reason_))); if (details.hasNestedExceptions()) @@ -188,9 +182,9 @@ GromacsException::GromacsException(const ExceptionInitializer &details) } } -const char *GromacsException::what() const noexcept +const char* GromacsException::what() const noexcept { - const ErrorMessage *msg = getInfo(); + const ErrorMessage* msg = getInfo(); if (msg == nullptr) { return "No reason provided"; @@ -202,15 +196,14 @@ const char *GromacsException::what() const noexcept return msg->text().c_str(); } -void GromacsException::prependContext(const std::string &context) +void GromacsException::prependContext(const std::string& context) { - const ErrorMessage *msg = getInfo(); + const ErrorMessage* msg = getInfo(); GMX_RELEASE_ASSERT(msg != nullptr, "Message should always be set"); setInfo(ExceptionInfoMessage(msg->prependContext(context))); } -const internal::IExceptionInfo * -GromacsException::getInfo(const std::type_index &index) const +const internal::IExceptionInfo* GromacsException::getInfo(const std::type_index& index) const { auto iter = data_->infos_.find(index); if (iter != data_->infos_.end()) @@ -220,8 +213,7 @@ GromacsException::getInfo(const std::type_index &index) const return nullptr; } -void GromacsException::setInfo( - const std::type_index &index, internal::ExceptionInfoPointer &&item) +void GromacsException::setInfo(const std::type_index& index, internal::ExceptionInfoPointer&& item) { data_->infos_[index] = std::move(item); } @@ -302,25 +294,24 @@ namespace */ class IMessageWriter { - public: - virtual ~IMessageWriter() {} - - /*! \brief - * Writes a single line of text into the output. - * - * \param[in] text Text to write on the line. - * \param[in] indent Suggested number of spaces to indent the line. - */ - virtual void writeLine(const char *text, int indent) = 0; - /*! \brief - * Writes information about a system error (errno-based). - * - * \param[in] errorNumber errno value - * \param[in] funcName Name of the system call (can be NULL). - * \param[in] indent Suggested number of spaces to indent the output. - */ - virtual void writeErrNoInfo(int errorNumber, const char *funcName, - int indent) = 0; +public: + virtual ~IMessageWriter() {} + + /*! \brief + * Writes a single line of text into the output. + * + * \param[in] text Text to write on the line. + * \param[in] indent Suggested number of spaces to indent the line. + */ + virtual void writeLine(const char* text, int indent) = 0; + /*! \brief + * Writes information about a system error (errno-based). + * + * \param[in] errorNumber errno value + * \param[in] funcName Name of the system call (can be NULL). + * \param[in] indent Suggested number of spaces to indent the output. + */ + virtual void writeErrNoInfo(int errorNumber, const char* funcName, int indent) = 0; }; /*! \brief @@ -331,28 +322,26 @@ class IMessageWriter */ class MessageWriterFileNoThrow : public IMessageWriter { - public: - //! Initializes a writer that writes to the given file handle. - explicit MessageWriterFileNoThrow(FILE *fp) : fp_(fp) {} +public: + //! Initializes a writer that writes to the given file handle. + explicit MessageWriterFileNoThrow(FILE* fp) : fp_(fp) {} - void writeLine(const char *text, int indent) override - { - internal::printFatalErrorMessageLine(fp_, text, indent); - } - void writeErrNoInfo(int errorNumber, const char *funcName, - int indent) override + void writeLine(const char* text, int indent) override + { + internal::printFatalErrorMessageLine(fp_, text, indent); + } + void writeErrNoInfo(int errorNumber, const char* funcName, int indent) override + { + std::fprintf(fp_, "%*sReason: %s\n", indent, "", std::strerror(errorNumber)); + if (funcName != nullptr) { - std::fprintf(fp_, "%*sReason: %s\n", indent, "", - std::strerror(errorNumber)); - if (funcName != nullptr) - { - std::fprintf(fp_, "%*s(call to %s() returned error code %d)\n", - indent, "", funcName, errorNumber); - } + std::fprintf(fp_, "%*s(call to %s() returned error code %d)\n", indent, "", funcName, + errorNumber); } + } - private: - FILE *fp_; +private: + FILE* fp_; }; /*! \brief @@ -360,32 +349,27 @@ class MessageWriterFileNoThrow : public IMessageWriter */ class MessageWriterTextWriter : public IMessageWriter { - public: - //! Initializes a writer that writes to the given stream. - explicit MessageWriterTextWriter(TextWriter *writer) : writer_(writer) - { - } +public: + //! Initializes a writer that writes to the given stream. + explicit MessageWriterTextWriter(TextWriter* writer) : writer_(writer) {} - void writeLine(const char *text, int indent) override - { - writer_->wrapperSettings().setIndent(indent); - writer_->writeLine(text); - } - void writeErrNoInfo(int errorNumber, const char *funcName, - int indent) override + void writeLine(const char* text, int indent) override + { + writer_->wrapperSettings().setIndent(indent); + writer_->writeLine(text); + } + void writeErrNoInfo(int errorNumber, const char* funcName, int indent) override + { + writer_->wrapperSettings().setIndent(indent); + writer_->writeLine(formatString("Reason: %s", std::strerror(errorNumber))); + if (funcName != nullptr) { - writer_->wrapperSettings().setIndent(indent); - writer_->writeLine(formatString("Reason: %s", std::strerror(errorNumber))); - if (funcName != nullptr) - { - writer_->writeLine( - formatString("(call to %s() returned error code %d)", - funcName, errorNumber)); - } + writer_->writeLine(formatString("(call to %s() returned error code %d)", funcName, errorNumber)); } + } - private: - TextWriter *writer_; +private: + TextWriter* writer_; }; /*! \brief @@ -393,39 +377,36 @@ class MessageWriterTextWriter : public IMessageWriter */ class MessageWriterString : public IMessageWriter { - public: - //! Post-processes the output string to not end in a line feed. - void removeTerminatingLineFeed() +public: + //! Post-processes the output string to not end in a line feed. + void removeTerminatingLineFeed() + { + if (!result_.empty()) { - if (!result_.empty()) - { - result_.erase(result_.size() - 1); - } + result_.erase(result_.size() - 1); } - //! Returns the constructed string. - const std::string &result() const { return result_; } + } + //! Returns the constructed string. + const std::string& result() const { return result_; } - void writeLine(const char *text, int indent) override - { - result_.append(indent, ' '); - result_.append(text); - result_.append("\n"); - } - void writeErrNoInfo(int errorNumber, const char *funcName, - int indent) override + void writeLine(const char* text, int indent) override + { + result_.append(indent, ' '); + result_.append(text); + result_.append("\n"); + } + void writeErrNoInfo(int errorNumber, const char* funcName, int indent) override + { + writeLine(formatString("Reason: %s", std::strerror(errorNumber)).c_str(), indent); + if (funcName != nullptr) { - writeLine(formatString("Reason: %s", std::strerror(errorNumber)).c_str(), + writeLine(formatString("(call to %s() returned error code %d)", funcName, errorNumber).c_str(), indent); - if (funcName != nullptr) - { - writeLine(formatString("(call to %s() returned error code %d)", - funcName, errorNumber).c_str(), - indent); - } } + } - private: - std::string result_; +private: + std::string result_; }; /*! \brief @@ -440,10 +421,9 @@ class MessageWriterString : public IMessageWriter * * Does not throw unless the writer throws. */ -void formatExceptionMessageInternal(IMessageWriter *writer, - const std::exception &ex, int indent) +void formatExceptionMessageInternal(IMessageWriter* writer, const std::exception& ex, int indent) { - const GromacsException *gmxEx = dynamic_cast(&ex); + const GromacsException* gmxEx = dynamic_cast(&ex); if (gmxEx != nullptr) { // TODO: Add an option to print location information for the tests @@ -455,42 +435,39 @@ void formatExceptionMessageInternal(IMessageWriter *writer, // funcPtr != NULL ? *funcPtr : ""); // } - bool bAnythingWritten = false; + bool bAnythingWritten = false; // TODO: Remove duplicate context if present in multiple nested exceptions. - const ErrorMessage *msg = gmxEx->getInfo(); + const ErrorMessage* msg = gmxEx->getInfo(); if (msg != nullptr) { while (msg != nullptr && msg->isContext()) { - writer->writeLine(msg->text().c_str(), indent*2); + writer->writeLine(msg->text().c_str(), indent * 2); ++indent; msg = &msg->child(); } if (msg != nullptr && !msg->text().empty()) { - writer->writeLine(msg->text().c_str(), indent*2); + writer->writeLine(msg->text().c_str(), indent * 2); bAnythingWritten = true; } } else { - writer->writeLine(ex.what(), indent*2); + writer->writeLine(ex.what(), indent * 2); bAnythingWritten = true; } - const int *errorNumber = gmxEx->getInfo(); + const int* errorNumber = gmxEx->getInfo(); if (errorNumber != nullptr && *errorNumber != 0) { - const char * const *funcName - = gmxEx->getInfo(); - writer->writeErrNoInfo(*errorNumber, - funcName != nullptr ? *funcName : nullptr, - (indent+1)*2); + const char* const* funcName = gmxEx->getInfo(); + writer->writeErrNoInfo(*errorNumber, funcName != nullptr ? *funcName : nullptr, + (indent + 1) * 2); bAnythingWritten = true; } - const internal::NestedExceptionList *nested - = gmxEx->getInfo(); + const internal::NestedExceptionList* nested = gmxEx->getInfo(); if (nested != nullptr) { internal::NestedExceptionList::const_iterator ni; @@ -500,7 +477,7 @@ void formatExceptionMessageInternal(IMessageWriter *writer, { std::rethrow_exception(*ni); } - catch (const std::exception &nestedEx) + catch (const std::exception& nestedEx) { const int newIndent = indent + (bAnythingWritten ? 1 : 0); formatExceptionMessageInternal(writer, nestedEx, newIndent); @@ -510,38 +487,38 @@ void formatExceptionMessageInternal(IMessageWriter *writer, } else { - writer->writeLine(ex.what(), indent*2); + writer->writeLine(ex.what(), indent * 2); } } //! \} -} // namespace +} // namespace -void printFatalErrorMessage(FILE *fp, const std::exception &ex) +void printFatalErrorMessage(FILE* fp, const std::exception& ex) { - const char *title = "Unknown exception"; + const char* title = "Unknown exception"; bool bPrintType = false; - const GromacsException *gmxEx = dynamic_cast(&ex); + const GromacsException* gmxEx = dynamic_cast(&ex); // TODO: Treat more of the standard exceptions if (gmxEx != nullptr) { title = getErrorCodeString(gmxEx->errorCode()); } - else if (dynamic_cast(&ex) != nullptr) + else if (dynamic_cast(&ex) != nullptr) { title = "System error in thread synchronization"; } - else if (dynamic_cast(&ex) != nullptr) + else if (dynamic_cast(&ex) != nullptr) { title = "Memory allocation failed"; } - else if (dynamic_cast(&ex) != nullptr) + else if (dynamic_cast(&ex) != nullptr) { title = "Standard library logic error (bug)"; bPrintType = true; } - else if (dynamic_cast(&ex) != nullptr) + else if (dynamic_cast(&ex) != nullptr) { title = "Standard library runtime error (possible bug)"; bPrintType = true; @@ -550,12 +527,12 @@ void printFatalErrorMessage(FILE *fp, const std::exception &ex) { bPrintType = true; } - const char *func = nullptr; - const char *file = nullptr; + const char* func = nullptr; + const char* file = nullptr; int line = 0; if (gmxEx != nullptr) { - const ThrowLocation *loc = gmxEx->getInfo(); + const ThrowLocation* loc = gmxEx->getInfo(); if (loc != nullptr) { func = loc->func; @@ -573,7 +550,7 @@ void printFatalErrorMessage(FILE *fp, const std::exception &ex) internal::printFatalErrorFooter(fp); } -std::string formatExceptionMessageToString(const std::exception &ex) +std::string formatExceptionMessageToString(const std::exception& ex) { MessageWriterString writer; formatExceptionMessageInternal(&writer, ex, 0); @@ -581,20 +558,19 @@ std::string formatExceptionMessageToString(const std::exception &ex) return writer.result(); } -void formatExceptionMessageToFile(FILE *fp, const std::exception &ex) +void formatExceptionMessageToFile(FILE* fp, const std::exception& ex) { MessageWriterFileNoThrow writer(fp); formatExceptionMessageInternal(&writer, ex, 0); } -void formatExceptionMessageToWriter(TextWriter *writer, - const std::exception &ex) +void formatExceptionMessageToWriter(TextWriter* writer, const std::exception& ex) { MessageWriterTextWriter messageWriter(writer); formatExceptionMessageInternal(&messageWriter, ex, 0); } -int processExceptionAtExit(const std::exception & /*ex*/) +int processExceptionAtExit(const std::exception& /*ex*/) { int returnCode = 1; // If we have more than one rank (whether real MPI or thread-MPI), @@ -609,7 +585,7 @@ int processExceptionAtExit(const std::exception & /*ex*/) return returnCode; } -void processExceptionAsFatalError(const std::exception &ex) +void processExceptionAsFatalError(const std::exception& ex) { printFatalErrorMessage(stderr, ex); gmx_exit_on_fatal_error(ExitType_Abort, 1); diff --git a/src/gromacs/utility/exceptions.h b/src/gromacs/utility/exceptions.h index 5d8c227eb1..fbcc2de183 100644 --- a/src/gromacs/utility/exceptions.h +++ b/src/gromacs/utility/exceptions.h @@ -85,9 +85,9 @@ typedef std::vector NestedExceptionList; */ class IExceptionInfo { - public: - virtual ~IExceptionInfo(); - GMX_DEFAULT_CONSTRUCTORS(IExceptionInfo); +public: + virtual ~IExceptionInfo(); + GMX_DEFAULT_CONSTRUCTORS(IExceptionInfo); }; //! Smart pointer to manage IExceptionInfo ownership. @@ -95,7 +95,7 @@ typedef std::unique_ptr ExceptionInfoPointer; class ExceptionData; -} // namespace internal +} // namespace internal //! \addtogroup module_utility //! \{ @@ -116,24 +116,21 @@ class ExceptionData; * * \inpublicapi */ -template +template class ExceptionInfo : public internal::IExceptionInfo { - public: - //! The type of value stored in this object. - typedef T value_type; +public: + //! The type of value stored in this object. + typedef T value_type; - //! Creates an info object from given value. - explicit ExceptionInfo(const T &value) - : value_(value) - { - } + //! Creates an info object from given value. + explicit ExceptionInfo(const T& value) : value_(value) {} - //! Returns the stored value. - const T &value() const { return value_; } + //! Returns the stored value. + const T& value() const { return value_; } - private: - T value_; +private: + T value_; }; /*! \internal @@ -143,28 +140,24 @@ class ExceptionInfo : public internal::IExceptionInfo struct ThrowLocation { //! Creates an object for storing the throw location. - ThrowLocation(const char *func, const char *file, int line) - : func(func), file(file), line(line) + ThrowLocation(const char* func, const char* file, int line) : func(func), file(file), line(line) { } //! Function where the throw occurred. - const char *func; + const char* func; //! File where the throw occurred. - const char *file; + const char* file; //! Line number where the throw occurred. - int line; + int line; }; //! Stores `errno` value that triggered the exception. -typedef ExceptionInfo - ExceptionInfoErrno; +typedef ExceptionInfo ExceptionInfoErrno; //! Stores the function name that returned the `errno` in ExceptionInfoErrno. -typedef ExceptionInfo - ExceptionInfoApiFunction; +typedef ExceptionInfo ExceptionInfoApiFunction; //! Stores the location where the exception was thrown. -typedef ExceptionInfo - ExceptionInfoLocation; +typedef ExceptionInfo ExceptionInfoLocation; /*! \brief * Provides information for Gromacs exception constructors. @@ -191,68 +184,59 @@ typedef ExceptionInfo */ class ExceptionInitializer { - public: - /*! \brief - * Creates an initialized with the given string as the reason. - * - * \param[in] reason Detailed reason for the exception. - * \throw std::bad_alloc if out of memory. - * - * This constructor is not explicit to allow constructing exceptions - * with a plain string argument given to the constructor without adding - * extra code to each exception class. - */ - ExceptionInitializer(const char *reason) - : reason_(reason) - { - } - //! \copydoc ExceptionInitializer(const char *) - ExceptionInitializer(const std::string &reason) - : reason_(reason) - { - } - - /*! \brief - * Returns true if addCurrentExceptionAsNested() has been called. - * - * Provided for convenience for cases where exceptions will be added - * conditionally, and the caller wants to check whether any excetions - * were actually added. - */ - bool hasNestedExceptions() const { return !nested_.empty(); } - /*! \brief - * Adds the currently caught exception as a nested exception. - * - * May be called multiple times; all provided exceptions will be added - * in a list of nested exceptions. - * - * Must not be called outside a catch block. - */ - void addCurrentExceptionAsNested() - { - nested_.push_back(std::current_exception()); - } - /*! \brief - * Adds the specified exception as a nested exception. - * - * May be called multiple times; all provided exceptions will be added - * in a list of nested exceptions. - * - * This is equivalent to throwing \p ex and calling - * addCurrentExceptionAsNested() in the catch block, but potentially - * more efficient. - */ - template - void addNested(const Exception &ex) - { - nested_.push_back(std::make_exception_ptr(ex)); - } +public: + /*! \brief + * Creates an initialized with the given string as the reason. + * + * \param[in] reason Detailed reason for the exception. + * \throw std::bad_alloc if out of memory. + * + * This constructor is not explicit to allow constructing exceptions + * with a plain string argument given to the constructor without adding + * extra code to each exception class. + */ + ExceptionInitializer(const char* reason) : reason_(reason) {} + //! \copydoc ExceptionInitializer(const char *) + ExceptionInitializer(const std::string& reason) : reason_(reason) {} + + /*! \brief + * Returns true if addCurrentExceptionAsNested() has been called. + * + * Provided for convenience for cases where exceptions will be added + * conditionally, and the caller wants to check whether any excetions + * were actually added. + */ + bool hasNestedExceptions() const { return !nested_.empty(); } + /*! \brief + * Adds the currently caught exception as a nested exception. + * + * May be called multiple times; all provided exceptions will be added + * in a list of nested exceptions. + * + * Must not be called outside a catch block. + */ + void addCurrentExceptionAsNested() { nested_.push_back(std::current_exception()); } + /*! \brief + * Adds the specified exception as a nested exception. + * + * May be called multiple times; all provided exceptions will be added + * in a list of nested exceptions. + * + * This is equivalent to throwing \p ex and calling + * addCurrentExceptionAsNested() in the catch block, but potentially + * more efficient. + */ + template + void addNested(const Exception& ex) + { + nested_.push_back(std::make_exception_ptr(ex)); + } - private: - std::string reason_; - internal::NestedExceptionList nested_; +private: + std::string reason_; + internal::NestedExceptionList nested_; - friend class GromacsException; + friend class GromacsException; }; /*! \brief @@ -262,98 +246,98 @@ class ExceptionInitializer */ class GromacsException : public std::exception { - public: - // Explicitly declared because some compiler/library combinations warn - // about missing noexcept otherwise. - ~GromacsException() noexcept override {} - - GMX_DEFAULT_CONSTRUCTORS(GromacsException); - - /*! \brief - * Returns the reason string for the exception. - * - * The return value is the string that was passed to the constructor. - */ - const char *what() const noexcept override; - /*! \brief - * Returns the error code corresponding to the exception type. - */ - virtual int errorCode() const = 0; - - /*! \brief - * Returns the value associated with given ExceptionInfo. - * - * \tparam InfoType ExceptionInfo type to get the value for. - * \returns Value set for `InfoType`, or `nullptr` if such info has not - * been set. - * - * Does not throw. - */ - template - const typename InfoType::value_type *getInfo() const +public: + // Explicitly declared because some compiler/library combinations warn + // about missing noexcept otherwise. + ~GromacsException() noexcept override {} + + GMX_DEFAULT_CONSTRUCTORS(GromacsException); + + /*! \brief + * Returns the reason string for the exception. + * + * The return value is the string that was passed to the constructor. + */ + const char* what() const noexcept override; + /*! \brief + * Returns the error code corresponding to the exception type. + */ + virtual int errorCode() const = 0; + + /*! \brief + * Returns the value associated with given ExceptionInfo. + * + * \tparam InfoType ExceptionInfo type to get the value for. + * \returns Value set for `InfoType`, or `nullptr` if such info has not + * been set. + * + * Does not throw. + */ + template + const typename InfoType::value_type* getInfo() const + { + const internal::IExceptionInfo* item = getInfo(typeid(InfoType)); + if (item != nullptr) { - const internal::IExceptionInfo *item = getInfo(typeid(InfoType)); - if (item != nullptr) - { - GMX_ASSERT(dynamic_cast(item) != nullptr, - "Invalid exception info item found"); - return &static_cast(item)->value(); - } - return nullptr; + GMX_ASSERT(dynamic_cast(item) != nullptr, + "Invalid exception info item found"); + return &static_cast(item)->value(); } + return nullptr; + } - /*! \brief - * Associates extra information with the exception. - * - * \tparam Tag ExceptionInfo tag type. - * \tparam T ExceptionInfo value type. - * \param[in] item ExceptionInfo to associate. - * \throws std::bad_alloc if out of memory. - * \throws unspecified any exception thrown by `T` copy construction. - * - * If an item of this type is already associated, it is overwritten. - */ - template - void setInfo(const ExceptionInfo &item) - { - typedef ExceptionInfo ItemType; - internal::ExceptionInfoPointer itemPtr(new ItemType(item)); - setInfo(typeid(ItemType), std::move(itemPtr)); - } + /*! \brief + * Associates extra information with the exception. + * + * \tparam Tag ExceptionInfo tag type. + * \tparam T ExceptionInfo value type. + * \param[in] item ExceptionInfo to associate. + * \throws std::bad_alloc if out of memory. + * \throws unspecified any exception thrown by `T` copy construction. + * + * If an item of this type is already associated, it is overwritten. + */ + template + void setInfo(const ExceptionInfo& item) + { + typedef ExceptionInfo ItemType; + internal::ExceptionInfoPointer itemPtr(new ItemType(item)); + setInfo(typeid(ItemType), std::move(itemPtr)); + } - /*! \brief - * Adds context information to this exception. - * - * \param[in] context Context string to add. - * \throws std::bad_alloc if out of memory. - * - * Typical use is to add additional information higher up in the call - * stack using this function in a catch block and the rethrow the - * exception. - * - * \todo - * The added information is currently not accessible through what(), - * nor through any other means except for calling - * printFatalErrorMessage(), formatExceptionMessageToString() or - * formatExceptionMessageToFile(). See ExceptionInitializer for more - * discussion. - */ - void prependContext(const std::string &context); - - protected: - /*! \brief - * Creates an exception object with the provided initializer/reason. - * - * \param[in] details Initializer for the exception. - * \throws std::bad_alloc if out of memory. - */ - explicit GromacsException(const ExceptionInitializer &details); - - private: - const internal::IExceptionInfo *getInfo(const std::type_index &index) const; - void setInfo(const std::type_index &index, internal::ExceptionInfoPointer &&item); - - std::shared_ptr data_; + /*! \brief + * Adds context information to this exception. + * + * \param[in] context Context string to add. + * \throws std::bad_alloc if out of memory. + * + * Typical use is to add additional information higher up in the call + * stack using this function in a catch block and the rethrow the + * exception. + * + * \todo + * The added information is currently not accessible through what(), + * nor through any other means except for calling + * printFatalErrorMessage(), formatExceptionMessageToString() or + * formatExceptionMessageToFile(). See ExceptionInitializer for more + * discussion. + */ + void prependContext(const std::string& context); + +protected: + /*! \brief + * Creates an exception object with the provided initializer/reason. + * + * \param[in] details Initializer for the exception. + * \throws std::bad_alloc if out of memory. + */ + explicit GromacsException(const ExceptionInitializer& details); + +private: + const internal::IExceptionInfo* getInfo(const std::type_index& index) const; + void setInfo(const std::type_index& index, internal::ExceptionInfoPointer&& item); + + std::shared_ptr data_; }; /*! \brief @@ -388,10 +372,9 @@ class GromacsException : public std::exception * would like to declare those. But currently we do not have such overloads, so * if the enable_if causes problems with some compilers, it can be removed. */ -template -inline -std::enable_if_t::value, Exception> -operator<<(Exception ex, const ExceptionInfo &item) +template +inline std::enable_if_t::value, Exception> +operator<<(Exception ex, const ExceptionInfo& item) { ex.setInfo(item); return ex; @@ -404,21 +387,20 @@ operator<<(Exception ex, const ExceptionInfo &item) */ class FileIOError : public GromacsException { - public: - /*! \brief - * Creates an exception object with the provided initializer/reason. - * - * \param[in] details Initializer for the exception. - * \throws std::bad_alloc if out of memory. - * - * It is possible to call this constructor either with an explicit - * ExceptionInitializer object (useful for more complex cases), or - * a simple string if only a reason string needs to be provided. - */ - explicit FileIOError(const ExceptionInitializer &details) - : GromacsException(details) {} - - int errorCode() const override; +public: + /*! \brief + * Creates an exception object with the provided initializer/reason. + * + * \param[in] details Initializer for the exception. + * \throws std::bad_alloc if out of memory. + * + * It is possible to call this constructor either with an explicit + * ExceptionInitializer object (useful for more complex cases), or + * a simple string if only a reason string needs to be provided. + */ + explicit FileIOError(const ExceptionInitializer& details) : GromacsException(details) {} + + int errorCode() const override; }; /*! \brief @@ -431,10 +413,9 @@ class FileIOError : public GromacsException */ class UserInputError : public GromacsException { - protected: - //! \copydoc FileIOError::FileIOError() - explicit UserInputError(const ExceptionInitializer &details) - : GromacsException(details) {} +protected: + //! \copydoc FileIOError::FileIOError() + explicit UserInputError(const ExceptionInitializer& details) : GromacsException(details) {} }; /*! \brief @@ -444,12 +425,11 @@ class UserInputError : public GromacsException */ class InvalidInputError : public UserInputError { - public: - //! \copydoc FileIOError::FileIOError() - explicit InvalidInputError(const ExceptionInitializer &details) - : UserInputError(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit InvalidInputError(const ExceptionInitializer& details) : UserInputError(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -459,12 +439,13 @@ class InvalidInputError : public UserInputError */ class InconsistentInputError : public UserInputError { - public: - //! \copydoc FileIOError::FileIOError() - explicit InconsistentInputError(const ExceptionInitializer &details) - : UserInputError(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit InconsistentInputError(const ExceptionInitializer& details) : UserInputError(details) + { + } - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -474,21 +455,20 @@ class InconsistentInputError : public UserInputError */ class ToleranceError : public GromacsException { - public: - /*! \brief - * Creates an exception object with the provided initializer/reason. - * - * \param[in] details Initializer for the exception. - * \throws std::bad_alloc if out of memory. - * - * It is possible to call this constructor either with an explicit - * ExceptionInitializer object (useful for more complex cases), or - * a simple string if only a reason string needs to be provided. - */ - explicit ToleranceError(const ExceptionInitializer &details) - : GromacsException(details) {} - - int errorCode() const override; +public: + /*! \brief + * Creates an exception object with the provided initializer/reason. + * + * \param[in] details Initializer for the exception. + * \throws std::bad_alloc if out of memory. + * + * It is possible to call this constructor either with an explicit + * ExceptionInitializer object (useful for more complex cases), or + * a simple string if only a reason string needs to be provided. + */ + explicit ToleranceError(const ExceptionInitializer& details) : GromacsException(details) {} + + int errorCode() const override; }; /*! \brief @@ -498,12 +478,14 @@ class ToleranceError : public GromacsException */ class SimulationInstabilityError : public GromacsException { - public: - //! \copydoc FileIOError::FileIOError() - explicit SimulationInstabilityError(const ExceptionInitializer &details) - : GromacsException(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit SimulationInstabilityError(const ExceptionInitializer& details) : + GromacsException(details) + { + } - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -513,12 +495,11 @@ class SimulationInstabilityError : public GromacsException */ class InternalError : public GromacsException { - public: - //! \copydoc FileIOError::FileIOError() - explicit InternalError(const ExceptionInitializer &details) - : GromacsException(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit InternalError(const ExceptionInitializer& details) : GromacsException(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -528,12 +509,11 @@ class InternalError : public GromacsException */ class APIError : public GromacsException { - public: - //! \copydoc FileIOError::FileIOError() - explicit APIError(const ExceptionInitializer &details) - : GromacsException(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit APIError(const ExceptionInitializer& details) : GromacsException(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -543,12 +523,11 @@ class APIError : public GromacsException */ class RangeError : public GromacsException { - public: - //! \copydoc FileIOError::FileIOError() - explicit RangeError(const ExceptionInitializer &details) - : GromacsException(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit RangeError(const ExceptionInitializer& details) : GromacsException(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -558,12 +537,11 @@ class RangeError : public GromacsException */ class NotImplementedError : public APIError { - public: - //! \copydoc FileIOError::FileIOError() - explicit NotImplementedError(const ExceptionInitializer &details) - : APIError(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit NotImplementedError(const ExceptionInitializer& details) : APIError(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief Exception class for use when ensuring that MPI ranks to throw @@ -578,12 +556,11 @@ class NotImplementedError : public APIError */ class ParallelConsistencyError : public APIError { - public: - //! \copydoc FileIOError::FileIOError() - explicit ParallelConsistencyError(const ExceptionInitializer &details) - : APIError(details) {} +public: + //! \copydoc FileIOError::FileIOError() + explicit ParallelConsistencyError(const ExceptionInitializer& details) : APIError(details) {} - int errorCode() const override; + int errorCode() const override; }; /*! \brief @@ -605,7 +582,7 @@ class ParallelConsistencyError : public APIError \endcode */ #define GMX_THROW(e) \ - throw (e) << gmx::ExceptionInfoLocation(gmx::ThrowLocation(GMX_CURRENT_FUNCTION, __FILE__, __LINE__)) + throw(e) << gmx::ExceptionInfoLocation(gmx::ThrowLocation(GMX_CURRENT_FUNCTION, __FILE__, __LINE__)) /*! \brief * Macro for throwing an exception based on errno. @@ -631,13 +608,14 @@ class ParallelConsistencyError : public APIError } \endcode */ -#define GMX_THROW_WITH_ERRNO(e, syscall, err) \ - do { \ - int stored_errno_ = (err); \ - GMX_THROW((e) << gmx::ExceptionInfoErrno(stored_errno_) \ - << gmx::ExceptionInfoApiFunction(syscall)); \ +#define GMX_THROW_WITH_ERRNO(e, syscall, err) \ + do \ + { \ + int stored_errno_ = (err); \ + GMX_THROW((e) << gmx::ExceptionInfoErrno(stored_errno_) \ + << gmx::ExceptionInfoApiFunction(syscall)); \ } while (0) -//TODO: Add an equivalent macro for Windows GetLastError +// TODO: Add an equivalent macro for Windows GetLastError /*! \brief * Formats a standard fatal error message for reporting an exception. @@ -666,7 +644,7 @@ class ParallelConsistencyError : public APIError } \endcode */ -void printFatalErrorMessage(FILE *fp, const std::exception &ex); +void printFatalErrorMessage(FILE* fp, const std::exception& ex); /*! \brief * Formats an error message for reporting an exception. * @@ -674,7 +652,7 @@ void printFatalErrorMessage(FILE *fp, const std::exception &ex); * \returns Formatted string containing details of \p ex. * \throws std::bad_alloc if out of memory. */ -std::string formatExceptionMessageToString(const std::exception &ex); +std::string formatExceptionMessageToString(const std::exception& ex); /*! \brief * Formats an error message for reporting an exception. * @@ -682,7 +660,7 @@ std::string formatExceptionMessageToString(const std::exception &ex); * \param[in] ex Exception to format. * \throws std::bad_alloc if out of memory. */ -void formatExceptionMessageToFile(FILE *fp, const std::exception &ex); +void formatExceptionMessageToFile(FILE* fp, const std::exception& ex); /*! \brief * Formats an error message for reporting an exception. * @@ -690,8 +668,7 @@ void formatExceptionMessageToFile(FILE *fp, const std::exception &ex); * \param[in] ex Exception to format. * \throws std::bad_alloc if out of memory. */ -void formatExceptionMessageToWriter(TextWriter *writer, - const std::exception &ex); +void formatExceptionMessageToWriter(TextWriter* writer, const std::exception& ex); /*! \brief * Handles an exception that is causing the program to terminate. * @@ -707,7 +684,7 @@ void formatExceptionMessageToWriter(TextWriter *writer, * * Does not throw. */ -int processExceptionAtExit(const std::exception &ex); +int processExceptionAtExit(const std::exception& ex); /*! \brief * Helper function for terminating the program on an exception. @@ -716,7 +693,7 @@ int processExceptionAtExit(const std::exception &ex); * * Does not throw, and does not return. */ -[[noreturn]] void processExceptionAsFatalError(const std::exception &ex); +[[noreturn]] void processExceptionAsFatalError(const std::exception& ex); /*! \brief * Macro for catching exceptions at C++ -> C boundary. @@ -741,9 +718,7 @@ int processExceptionAtExit(const std::exception &ex); \endcode */ #define GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR \ - catch (const std::exception &ex) { \ - ::gmx::processExceptionAsFatalError(ex); \ - } + catch (const std::exception& ex) { ::gmx::processExceptionAsFatalError(ex); } //! \} diff --git a/src/gromacs/utility/fatalerror.cpp b/src/gromacs/utility/fatalerror.cpp index 8271f5e0f4..c8534f791a 100644 --- a/src/gromacs/utility/fatalerror.cpp +++ b/src/gromacs/utility/fatalerror.cpp @@ -58,24 +58,24 @@ #include "errorcodes.h" #if GMX_MPI -#include "gromacs/utility/basenetwork.h" -#include "gromacs/utility/gmxmpi.h" +# include "gromacs/utility/basenetwork.h" +# include "gromacs/utility/gmxmpi.h" #endif #include "errorformat.h" -static bool bDebug = false; +static bool bDebug = false; static gmx::Mutex where_mutex; -FILE *debug = nullptr; -gmx_bool gmx_debug_at = FALSE; +FILE* debug = nullptr; +gmx_bool gmx_debug_at = FALSE; -static FILE *log_file = nullptr; +static FILE* log_file = nullptr; static gmx::Mutex error_mutex; using Lock = gmx::lock_guard; -void gmx_init_debug(const int dbglevel, const char *dbgfile) +void gmx_init_debug(const int dbglevel, const char* dbgfile) { if (!bDebug) { @@ -94,13 +94,12 @@ gmx_bool bDebugMode() return bDebug; } -void gmx_fatal_set_log_file(FILE *fp) +void gmx_fatal_set_log_file(FILE* fp) { log_file = fp; } -static void default_error_handler(const char *title, const std::string &msg, - const char *file, int line) +static void default_error_handler(const char* title, const std::string& msg, const char* file, int line) { if (log_file) { @@ -121,30 +120,29 @@ void gmx_set_error_handler(gmx_error_handler_t func) gmx_error_handler = func; } -static const char *gmx_strerror(const char *key) +static const char* gmx_strerror(const char* key) { - struct ErrorKeyEntry { - const char *key; - const char *msg; - }; - ErrorKeyEntry map[] = { - { "call", "Routine should not have been called" }, - { "comm", "Communication (parallel processing) problem" }, - { "fatal", "Fatal error" }, - { "file", "File input/output error" }, - { "impl", "Implementation restriction" }, - { "incons", "Software inconsistency error" }, - { "input", "Input error or input inconsistency" }, - { "mem", "Memory allocation/freeing error" }, - { "open", "Cannot open file" }, - { "range", "Range checking error" } + struct ErrorKeyEntry + { + const char* key; + const char* msg; }; + ErrorKeyEntry map[] = { { "call", "Routine should not have been called" }, + { "comm", "Communication (parallel processing) problem" }, + { "fatal", "Fatal error" }, + { "file", "File input/output error" }, + { "impl", "Implementation restriction" }, + { "incons", "Software inconsistency error" }, + { "input", "Input error or input inconsistency" }, + { "mem", "Memory allocation/freeing error" }, + { "open", "Cannot open file" }, + { "range", "Range checking error" } }; if (key == nullptr) { return "NULL error type (should not occur)"; } - for (const ErrorKeyEntry &entry : map) + for (const ErrorKeyEntry& entry : map) { if (std::strcmp(key, entry.key) == 0) { @@ -154,12 +152,10 @@ static const char *gmx_strerror(const char *key) return gmx::getErrorCodeString(gmx::eeUnknownError); } -static void call_error_handler(const char *key, const char *file, int line, const std::string &msg) +static void call_error_handler(const char* key, const char* file, int line, const std::string& msg) { Lock lock(error_mutex); - gmx_error_handler(gmx_strerror(key), - msg.empty() ? "Empty gmx_fatal message (bug)." : msg, - file, line); + gmx_error_handler(gmx_strerror(key), msg.empty() ? "Empty gmx_fatal message (bug)." : msg, file, line); } void gmx_exit_on_fatal_error(ExitType exitType, int returnValue) @@ -180,15 +176,13 @@ void gmx_exit_on_fatal_error(ExitType exitType, int returnValue) { switch (exitType) { - case ExitType_CleanExit: - MPI_Finalize(); - break; + case ExitType_CleanExit: MPI_Finalize(); break; case ExitType_Abort: -#if GMX_LIB_MPI +# if GMX_LIB_MPI gmx_abort(returnValue); -#else +# else break; -#endif +# endif case ExitType_NonMasterAbort: // Let all other processes wait till the master has printed // the error message and issued MPI_Abort. @@ -202,14 +196,18 @@ void gmx_exit_on_fatal_error(ExitType exitType, int returnValue) { std::exit(returnValue); } - // We cannot use std::exit() if other threads may still be executing, since that would cause destructors to be - // called for global objects that may still be in use elsewhere. + // We cannot use std::exit() if other threads may still be executing, since that would cause + // destructors to be called for global objects that may still be in use elsewhere. std::_Exit(returnValue); } -void gmx_fatal_mpi_va(int /*f_errno*/, const char *file, int line, - gmx_bool bMaster, gmx_bool bFinalize, - const char *fmt, va_list ap) +void gmx_fatal_mpi_va(int /*f_errno*/, + const char* file, + int line, + gmx_bool bMaster, + gmx_bool bFinalize, + const char* fmt, + va_list ap) { if (bMaster) { @@ -225,7 +223,7 @@ void gmx_fatal_mpi_va(int /*f_errno*/, const char *file, int line, gmx_exit_on_fatal_error(exitType, 1); } -void gmx_fatal(int f_errno, const char *file, int line, gmx_fmtstr const char *fmt, ...) +void gmx_fatal(int f_errno, const char* file, int line, gmx_fmtstr const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -233,32 +231,33 @@ void gmx_fatal(int f_errno, const char *file, int line, gmx_fmtstr const char *f va_end(ap); } -void _gmx_error(const char *key, const std::string &msg, const char *file, int line) +void _gmx_error(const char* key, const std::string& msg, const char* file, int line) { call_error_handler(key, file, line, msg); gmx_exit_on_fatal_error(ExitType_Abort, 1); } -void _range_check(int n, int n_min, int n_max, const char *warn_str, - const char *var, const char *file, int line) +void _range_check(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line) { if ((n < n_min) || (n >= n_max)) { std::string buf; if (warn_str != nullptr) { - buf = warn_str; + buf = warn_str; buf += "\n"; } - buf += gmx::formatString("Variable %s has value %d. It should have been " - "within [ %d .. %d ]\n", var, n, n_min, n_max); + buf += gmx::formatString( + "Variable %s has value %d. It should have been " + "within [ %d .. %d ]\n", + var, n, n_min, n_max); _gmx_error("range", buf, file, line); } } -void gmx_warning(gmx_fmtstr const char *fmt, ...) +void gmx_warning(gmx_fmtstr const char* fmt, ...) { va_list ap; char msg[STRLEN]; diff --git a/src/gromacs/utility/fatalerror.h b/src/gromacs/utility/fatalerror.h index df73d6a9d8..55f2c946ef 100644 --- a/src/gromacs/utility/fatalerror.h +++ b/src/gromacs/utility/fatalerror.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,7 +62,7 @@ } \endcode */ -extern FILE *debug; +extern FILE* debug; /** Whether extra debugging is enabled. */ extern gmx_bool gmx_debug_at; @@ -74,17 +74,16 @@ extern gmx_bool gmx_debug_at; * For command line programs, gmx::CommandLineModuleManager takes care * of this if the user requests debugging. */ -void gmx_init_debug(int dbglevel, const char *dbgfile); +void gmx_init_debug(int dbglevel, const char* dbgfile); /** Returns TRUE when the program was started in debug mode */ gmx_bool bDebugMode(); /** Sets the log file for printing error messages. */ -void -gmx_fatal_set_log_file(FILE *fp); +void gmx_fatal_set_log_file(FILE* fp); /** Function pointer type for fatal error handler callback. */ -typedef void (*gmx_error_handler_t)(const char *title, const std::string &msg, const char *file, int line); +typedef void (*gmx_error_handler_t)(const char* title, const std::string& msg, const char* file, int line); /*! \brief * Sets an error handler for gmx_fatal() and other fatal error routines. @@ -147,10 +146,13 @@ enum ExitType * This is used to implement gmx_fatal_collective() (which cannot be declared * here, since it would bring with it mdrun-specific dependencies). */ -[[noreturn]] void -gmx_fatal_mpi_va(int fatal_errno, const char *file, int line, - gmx_bool bMaster, gmx_bool bFinalize, - const char *fmt, va_list ap); +[[noreturn]] void gmx_fatal_mpi_va(int fatal_errno, + const char* file, + int line, + gmx_bool bMaster, + gmx_bool bFinalize, + const char* fmt, + va_list ap); /*! \brief * Fatal error reporting routine for \Gromacs. @@ -173,13 +175,13 @@ gmx_fatal_mpi_va(int fatal_errno, const char *file, int line, gmx_fatal(FARGS, fmt, ...); \endcode */ -[[noreturn]] void -gmx_fatal(int fatal_errno, const char *file, int line, gmx_fmtstr const char *fmt, ...) gmx_format(printf, 4, 5); +[[noreturn]] void gmx_fatal(int fatal_errno, const char* file, int line, gmx_fmtstr const char* fmt, ...) + gmx_format(printf, 4, 5); /** Helper macro to pass first three parameters to gmx_fatal(). */ #define FARGS 0, __FILE__, __LINE__ /** Implementation for gmx_error(). */ -[[noreturn]] void _gmx_error(const char *key, const std::string &msg, const char *file, int line); +[[noreturn]] void _gmx_error(const char* key, const std::string& msg, const char* file, int line); /*! \brief * Alternative fatal error routine with canned messages. * @@ -195,14 +197,14 @@ gmx_fatal(int fatal_errno, const char *file, int line, gmx_fmtstr const char *fm * recognized strings. */ /*! \{ */ -#define gmx_call(msg) gmx_error("call", msg) -#define gmx_comm(msg) gmx_error("comm", msg) -#define gmx_file(msg) gmx_error("file", msg) -#define gmx_impl(msg) gmx_error("impl", msg) +#define gmx_call(msg) gmx_error("call", msg) +#define gmx_comm(msg) gmx_error("comm", msg) +#define gmx_file(msg) gmx_error("file", msg) +#define gmx_impl(msg) gmx_error("impl", msg) #define gmx_incons(msg) gmx_error("incons", msg) -#define gmx_input(msg) gmx_error("input", msg) -#define gmx_mem(msg) gmx_error("mem", msg) -#define gmx_open(fn) gmx_error("open", fn) +#define gmx_input(msg) gmx_error("input", msg) +#define gmx_mem(msg) gmx_error("mem", msg) +#define gmx_open(fn) gmx_error("open", fn) /*! \} */ /*! \brief @@ -210,9 +212,7 @@ gmx_fatal(int fatal_errno, const char *file, int line, gmx_fmtstr const char *fm * * \p warn_str can be NULL. */ -void _range_check(int n, int n_min, int n_max, const char *warn_str, - const char *var, - const char *file, int line); +void _range_check(int n, int n_min, int n_max, const char* warn_str, const char* var, const char* file, int line); /*! \brief * Checks that a variable is within a range. @@ -220,14 +220,15 @@ void _range_check(int n, int n_min, int n_max, const char *warn_str, * If \p n is not in range [n_min, n_max), a fatal error is raised. * \p n_min is inclusive, but \p n_max is not. */ -#define range_check_mesg(n, n_min, n_max, str) _range_check(n, n_min, n_max, str,#n, __FILE__, __LINE__) +#define range_check_mesg(n, n_min, n_max, str) \ + _range_check(n, n_min, n_max, str, #n, __FILE__, __LINE__) /*! \brief * Checks that a variable is within a range. * * This works as range_check_mesg(), but with a default error message. */ -#define range_check(n, n_min, n_max) _range_check(n, n_min, n_max, NULL,#n, __FILE__, __LINE__) +#define range_check(n, n_min, n_max) _range_check(n, n_min, n_max, NULL, #n, __FILE__, __LINE__) /*! \brief * Prints a warning message to stderr. @@ -236,6 +237,6 @@ void _range_check(int n, int n_min, int n_max, const char *warn_str, * The message string should NOT start with "WARNING" * and should NOT end with a newline. */ -void gmx_warning(gmx_fmtstr const char *fmt, ...) gmx_format(printf, 1, 2); +void gmx_warning(gmx_fmtstr const char* fmt, ...) gmx_format(printf, 1, 2); #endif diff --git a/src/gromacs/utility/fileptr.h b/src/gromacs/utility/fileptr.h index d47b5e1b02..5a65ad0ada 100644 --- a/src/gromacs/utility/fileptr.h +++ b/src/gromacs/utility/fileptr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,13 +51,13 @@ namespace gmx { //! fclose wrapper to be used as unique_ptr deleter -inline void fclose_wrapper(FILE *fp) +inline void fclose_wrapper(FILE* fp) { fclose(fp); // NOLINT(cppcoreguidelines-owning-memory) } //! Simple guard pointer which calls fclose. See unique_cptr for details. -using FilePtr = std::unique_ptr < FILE, functor_wrapper < FILE, fclose_wrapper>>; +using FilePtr = std::unique_ptr>; } // namespace gmx diff --git a/src/gromacs/utility/fileredirector.cpp b/src/gromacs/utility/fileredirector.cpp index cfb71e4b91..880c6a7732 100644 --- a/src/gromacs/utility/fileredirector.cpp +++ b/src/gromacs/utility/fileredirector.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,13 +49,9 @@ namespace gmx { -IFileInputRedirector::~IFileInputRedirector() -{ -} +IFileInputRedirector::~IFileInputRedirector() {} -IFileOutputRedirector::~IFileOutputRedirector() -{ -} +IFileOutputRedirector::~IFileOutputRedirector() {} namespace { @@ -70,12 +66,11 @@ namespace */ class DefaultInputRedirector : public IFileInputRedirector { - public: - bool fileExists(const char *filename, - File::NotFoundHandler onNotFound) const override - { - return File::exists(filename, onNotFound); - } +public: + bool fileExists(const char* filename, File::NotFoundHandler onNotFound) const override + { + return File::exists(filename, onNotFound); + } }; /*! \internal @@ -89,27 +84,24 @@ class DefaultInputRedirector : public IFileInputRedirector */ class DefaultOutputRedirector : public IFileOutputRedirector { - public: - TextOutputStream &standardOutput() override - { - return TextOutputFile::standardOutput(); - } - TextOutputStreamPointer openTextOutputFile(const char *filename) override - { - return TextOutputStreamPointer(new TextOutputFile(filename)); - } +public: + TextOutputStream& standardOutput() override { return TextOutputFile::standardOutput(); } + TextOutputStreamPointer openTextOutputFile(const char* filename) override + { + return TextOutputStreamPointer(new TextOutputFile(filename)); + } }; -} // namespace +} // namespace //! \cond libapi -IFileInputRedirector &defaultFileInputRedirector() +IFileInputRedirector& defaultFileInputRedirector() { static DefaultInputRedirector instance; return instance; } -IFileOutputRedirector &defaultFileOutputRedirector() +IFileOutputRedirector& defaultFileOutputRedirector() { static DefaultOutputRedirector instance; return instance; diff --git a/src/gromacs/utility/fileredirector.h b/src/gromacs/utility/fileredirector.h index 2a190f0da8..3560011cfb 100644 --- a/src/gromacs/utility/fileredirector.h +++ b/src/gromacs/utility/fileredirector.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,25 +70,23 @@ namespace gmx */ class IFileInputRedirector { - public: - virtual ~IFileInputRedirector(); +public: + virtual ~IFileInputRedirector(); - /*! \brief - * Checks whether the provided path exists (and is a file). - * - * The \p onNotFound can be used to influence the behavior on error - * conditions. Functions to pass as this parameter are provided as - * members of gmx::File. - */ - virtual bool fileExists(const char *filename, - File::NotFoundHandler onNotFound) const = 0; + /*! \brief + * Checks whether the provided path exists (and is a file). + * + * The \p onNotFound can be used to influence the behavior on error + * conditions. Functions to pass as this parameter are provided as + * members of gmx::File. + */ + virtual bool fileExists(const char* filename, File::NotFoundHandler onNotFound) const = 0; - //! Convenience method to check file existence using an std::string path. - bool fileExists(const std::string &filename, - File::NotFoundHandler onNotFound) const - { - return fileExists(filename.c_str(), onNotFound); - } + //! Convenience method to check file existence using an std::string path. + bool fileExists(const std::string& filename, File::NotFoundHandler onNotFound) const + { + return fileExists(filename.c_str(), onNotFound); + } }; /*! \libinternal \brief @@ -119,25 +117,25 @@ class IFileInputRedirector */ class IFileOutputRedirector { - public: - virtual ~IFileOutputRedirector(); +public: + virtual ~IFileOutputRedirector(); - /*! \brief - * Returns a stream to use for `stdout` output. - */ - virtual TextOutputStream &standardOutput() = 0; - /*! \brief - * Returns a stream to use for output to a file at a given path. - * - * \param[in] filename Requested file name. - */ - virtual TextOutputStreamPointer openTextOutputFile(const char *filename) = 0; + /*! \brief + * Returns a stream to use for `stdout` output. + */ + virtual TextOutputStream& standardOutput() = 0; + /*! \brief + * Returns a stream to use for output to a file at a given path. + * + * \param[in] filename Requested file name. + */ + virtual TextOutputStreamPointer openTextOutputFile(const char* filename) = 0; - //! Convenience method to open a stream using an std::string path. - TextOutputStreamPointer openTextOutputFile(const std::string &filename) - { - return openTextOutputFile(filename.c_str()); - } + //! Convenience method to open a stream using an std::string path. + TextOutputStreamPointer openTextOutputFile(const std::string& filename) + { + return openTextOutputFile(filename.c_str()); + } }; //! \cond libapi @@ -151,7 +149,7 @@ class IFileOutputRedirector * * \ingroup module_utility */ -IFileInputRedirector &defaultFileInputRedirector(); +IFileInputRedirector& defaultFileInputRedirector(); /*! \brief * Returns default implementation for IFileOutputRedirector. * @@ -162,7 +160,7 @@ IFileInputRedirector &defaultFileInputRedirector(); * * \ingroup module_utility */ -IFileOutputRedirector &defaultFileOutputRedirector(); +IFileOutputRedirector& defaultFileOutputRedirector(); //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/filestream.cpp b/src/gromacs/utility/filestream.cpp index 4833eeb919..4893c509fe 100644 --- a/src/gromacs/utility/filestream.cpp +++ b/src/gromacs/utility/filestream.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,7 +49,7 @@ #include #ifdef HAVE_UNISTD_H -#include +# include #endif #include "gromacs/utility/exceptions.h" @@ -63,7 +63,7 @@ namespace { //! Helper function for implementing readLine() for input streams. -bool readLineImpl(FILE *fp, std::string *line) +bool readLineImpl(FILE* fp, std::string* line) { line->clear(); const size_t bufsize = 256; @@ -81,14 +81,13 @@ bool readLineImpl(FILE *fp, std::string *line) } if (std::ferror(fp)) { - GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"), - "fgets", errno); + GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"), "fgets", errno); } *line = result; return !result.empty() || (std::feof(fp) == 0); } -} // namespace +} // namespace namespace internal { @@ -99,63 +98,54 @@ namespace internal class FileStreamImpl { - public: - explicit FileStreamImpl(FILE *fp) - : fp_(fp), bClose_(false) - { - } - FileStreamImpl(const char *filename, const char *mode) - : fp_(nullptr), bClose_(true) +public: + explicit FileStreamImpl(FILE* fp) : fp_(fp), bClose_(false) {} + FileStreamImpl(const char* filename, const char* mode) : fp_(nullptr), bClose_(true) + { + fp_ = std::fopen(filename, mode); + if (fp_ == nullptr) { - fp_ = std::fopen(filename, mode); - if (fp_ == nullptr) - { - GMX_THROW_WITH_ERRNO( - FileIOError(formatString("Could not open file '%s'", filename)), - "fopen", errno); - } + GMX_THROW_WITH_ERRNO(FileIOError(formatString("Could not open file '%s'", filename)), + "fopen", errno); } - ~FileStreamImpl() + } + ~FileStreamImpl() + { + if (fp_ != nullptr && bClose_) { - if (fp_ != nullptr && bClose_) + if (std::fclose(fp_) != 0) { - if (std::fclose(fp_) != 0) - { - // TODO: Log the error somewhere - } + // TODO: Log the error somewhere } } + } - FILE *handle() - { - GMX_RELEASE_ASSERT(fp_ != nullptr, - "Attempted to access a file object that is not open"); - return fp_; - } + FILE* handle() + { + GMX_RELEASE_ASSERT(fp_ != nullptr, "Attempted to access a file object that is not open"); + return fp_; + } - void close() + void close() + { + GMX_RELEASE_ASSERT(fp_ != nullptr, "Attempted to close a file object that is not open"); + GMX_RELEASE_ASSERT(bClose_, "Attempted to close a file object that should not be"); + const bool bOk = (std::fclose(fp_) == 0); + fp_ = nullptr; + if (!bOk) { - GMX_RELEASE_ASSERT(fp_ != nullptr, - "Attempted to close a file object that is not open"); - GMX_RELEASE_ASSERT(bClose_, - "Attempted to close a file object that should not be"); - const bool bOk = (std::fclose(fp_) == 0); - fp_ = nullptr; - if (!bOk) - { - GMX_THROW_WITH_ERRNO( - FileIOError("Error while closing file"), "fclose", errno); - } + GMX_THROW_WITH_ERRNO(FileIOError("Error while closing file"), "fclose", errno); } + } - private: - //! File handle for this object (NULL if the stream has been closed). - FILE *fp_; - //! Whether \p fp_ should be closed by this object. - bool bClose_; +private: + //! File handle for this object (NULL if the stream has been closed). + FILE* fp_; + //! Whether \p fp_ should be closed by this object. + bool bClose_; }; -} // namespace internal +} // namespace internal using internal::FileStreamImpl; @@ -172,13 +162,13 @@ bool StandardInputStream::isInteractive() const #endif } -bool StandardInputStream::readLine(std::string *line) +bool StandardInputStream::readLine(std::string* line) { return readLineImpl(stdin, line); } // static -StandardInputStream &StandardInputStream::instance() +StandardInputStream& StandardInputStream::instance() { static StandardInputStream stdinObject; return stdinObject; @@ -189,44 +179,38 @@ StandardInputStream &StandardInputStream::instance() */ // static -FilePtr TextInputFile::openRawHandle(const char *filename) +FilePtr TextInputFile::openRawHandle(const char* filename) { FilePtr fp(fopen(filename, "r")); if (fp == nullptr) { - GMX_THROW_WITH_ERRNO( - FileIOError(formatString("Could not open file '%s'", filename)), - "fopen", errno); + GMX_THROW_WITH_ERRNO(FileIOError(formatString("Could not open file '%s'", filename)), + "fopen", errno); } return fp; } // static -FilePtr TextInputFile::openRawHandle(const std::string &filename) +FilePtr TextInputFile::openRawHandle(const std::string& filename) { return openRawHandle(filename.c_str()); } -TextInputFile::TextInputFile(const std::string &filename) - : impl_(new FileStreamImpl(filename.c_str(), "r")) +TextInputFile::TextInputFile(const std::string& filename) : + impl_(new FileStreamImpl(filename.c_str(), "r")) { } -TextInputFile::TextInputFile(FILE *fp) - : impl_(new FileStreamImpl(fp)) -{ -} +TextInputFile::TextInputFile(FILE* fp) : impl_(new FileStreamImpl(fp)) {} -TextInputFile::~TextInputFile() -{ -} +TextInputFile::~TextInputFile() {} -FILE *TextInputFile::handle() +FILE* TextInputFile::handle() { return impl_->handle(); } -bool TextInputFile::readLine(std::string *line) +bool TextInputFile::readLine(std::string* line) { return readLineImpl(impl_->handle(), line); } @@ -240,26 +224,20 @@ void TextInputFile::close() * TextOutputFile */ -TextOutputFile::TextOutputFile(const std::string &filename) - : impl_(new FileStreamImpl(filename.c_str(), "w")) +TextOutputFile::TextOutputFile(const std::string& filename) : + impl_(new FileStreamImpl(filename.c_str(), "w")) { } -TextOutputFile::TextOutputFile(FILE *fp) - : impl_(new FileStreamImpl(fp)) -{ -} +TextOutputFile::TextOutputFile(FILE* fp) : impl_(new FileStreamImpl(fp)) {} -TextOutputFile::~TextOutputFile() -{ -} +TextOutputFile::~TextOutputFile() {} -void TextOutputFile::write(const char *str) +void TextOutputFile::write(const char* str) { if (std::fprintf(impl_->handle(), "%s", str) < 0) { - GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"), - "fprintf", errno); + GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"), "fprintf", errno); } } @@ -269,14 +247,14 @@ void TextOutputFile::close() } // static -TextOutputFile &TextOutputFile::standardOutput() +TextOutputFile& TextOutputFile::standardOutput() { static TextOutputFile stdoutObject(stdout); return stdoutObject; } // static -TextOutputFile &TextOutputFile::standardError() +TextOutputFile& TextOutputFile::standardError() { static TextOutputFile stderrObject(stderr); return stderrObject; diff --git a/src/gromacs/utility/filestream.h b/src/gromacs/utility/filestream.h index b8395434d7..26c240a6bf 100644 --- a/src/gromacs/utility/filestream.h +++ b/src/gromacs/utility/filestream.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,26 +70,26 @@ class FileStreamImpl; */ class StandardInputStream : public TextInputStream { - public: - /*! \brief - * Returns whether `stdin` is an interactive terminal. - * - * Only works on Unix, otherwise always returns true. - * - * Does not throw. - */ - bool isInteractive() const; - - // From TextInputStream - bool readLine(std::string *line) override; - void close() override {} - - /*! \brief - * Returns a stream for accessing `stdin`. - * - * Does not throw. - */ - static StandardInputStream &instance(); +public: + /*! \brief + * Returns whether `stdin` is an interactive terminal. + * + * Only works on Unix, otherwise always returns true. + * + * Does not throw. + */ + bool isInteractive() const; + + // From TextInputStream + bool readLine(std::string* line) override; + void close() override {} + + /*! \brief + * Returns a stream for accessing `stdin`. + * + * Does not throw. + */ + static StandardInputStream& instance(); }; /*! \libinternal \brief @@ -103,53 +103,53 @@ class StandardInputStream : public TextInputStream */ class TextInputFile : public TextInputStream { - public: - /*! \brief - * Opens a file and returns an RAII-style `FILE` handle. - * - * \param[in] filename Path of the file to open. - * \throws FileIOError on any I/O error. - * - * Instead of returning `NULL` on errors, throws an exception with - * additional details (including the file name and `errno`). - */ - static FilePtr openRawHandle(const char *filename); - //! \copydoc openRawHandle(const char *) - static FilePtr openRawHandle(const std::string &filename); - - /*! \brief - * Opens a text file as a stream. - * - * \param[in] filename Path to the file to open. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - explicit TextInputFile(const std::string &filename); - /*! \brief - * Initializes file object from an existing file handle. - * - * \param[in] fp File handle to use. - * \throws std::bad_alloc if out of memory. - * - * The caller is responsible of closing the file; close() does nothing - * for an object constructed this way. - */ - explicit TextInputFile(FILE *fp); - ~TextInputFile() override; - - /*! \brief - * Returns a raw handle to the input file. - * - * This is provided for interoperability with older C-like code. - */ - FILE *handle(); - - // From TextInputStream - bool readLine(std::string *line) override; - void close() override; - - private: - PrivateImplPointer impl_; +public: + /*! \brief + * Opens a file and returns an RAII-style `FILE` handle. + * + * \param[in] filename Path of the file to open. + * \throws FileIOError on any I/O error. + * + * Instead of returning `NULL` on errors, throws an exception with + * additional details (including the file name and `errno`). + */ + static FilePtr openRawHandle(const char* filename); + //! \copydoc openRawHandle(const char *) + static FilePtr openRawHandle(const std::string& filename); + + /*! \brief + * Opens a text file as a stream. + * + * \param[in] filename Path to the file to open. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + explicit TextInputFile(const std::string& filename); + /*! \brief + * Initializes file object from an existing file handle. + * + * \param[in] fp File handle to use. + * \throws std::bad_alloc if out of memory. + * + * The caller is responsible of closing the file; close() does nothing + * for an object constructed this way. + */ + explicit TextInputFile(FILE* fp); + ~TextInputFile() override; + + /*! \brief + * Returns a raw handle to the input file. + * + * This is provided for interoperability with older C-like code. + */ + FILE* handle(); + + // From TextInputStream + bool readLine(std::string* line) override; + void close() override; + +private: + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -163,32 +163,32 @@ class TextInputFile : public TextInputStream */ class TextOutputFile : public TextOutputStream { - public: - //! \copydoc TextInputFile::TextInputFile(const std::string &) - explicit TextOutputFile(const std::string &filename); - //! \copydoc TextInputFile::TextInputFile(FILE *) - explicit TextOutputFile(FILE *fp); - ~TextOutputFile() override; - - // From TextOutputStream - void write(const char *text) override; - void close() override; - - /*! \brief - * Returns a stream for accessing `stdout`. - * - * \throws std::bad_alloc if out of memory (only on first call). - */ - static TextOutputFile &standardOutput(); - /*! \brief - * Returns a stream for accessing `stderr`. - * - * \throws std::bad_alloc if out of memory (only on first call). - */ - static TextOutputFile &standardError(); - - private: - PrivateImplPointer impl_; +public: + //! \copydoc TextInputFile::TextInputFile(const std::string &) + explicit TextOutputFile(const std::string& filename); + //! \copydoc TextInputFile::TextInputFile(FILE *) + explicit TextOutputFile(FILE* fp); + ~TextOutputFile() override; + + // From TextOutputStream + void write(const char* text) override; + void close() override; + + /*! \brief + * Returns a stream for accessing `stdout`. + * + * \throws std::bad_alloc if out of memory (only on first call). + */ + static TextOutputFile& standardOutput(); + /*! \brief + * Returns a stream for accessing `stderr`. + * + * \throws std::bad_alloc if out of memory (only on first call). + */ + static TextOutputFile& standardError(); + +private: + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/fixedcapacityvector.h b/src/gromacs/utility/fixedcapacityvector.h index 05c21948d6..03c6d79443 100644 --- a/src/gromacs/utility/fixedcapacityvector.h +++ b/src/gromacs/utility/fixedcapacityvector.h @@ -78,143 +78,143 @@ namespace gmx * \inpublicapi * \ingroup module_utility */ -template +template class FixedCapacityVector { - public: - //! Type of values stored in the vector - using value_type = T; - //! Type for representing size of the vector - using size_type = size_t; - //! Type for representing difference between two indices - using difference_type = ptrdiff_t; - //! Const reference to an element - using const_reference = const T&; - //! Const pointer to an element - using const_pointer = const T*; - //! Const iterator type to an element - using const_iterator = const T*; - //! Reference to an element - using reference = T&; - //! Pointer to an element - using pointer = T*; - //! Iterator type to an element - using iterator = T*; - //! Standard reverse iterator - using reverse_iterator = std::reverse_iterator; - //! Standard reverse iterator - using const_reverse_iterator = std::reverse_iterator; - - //! Returns a const iterator to the beginning - const_iterator begin() const noexcept { return data(); } - //! Returns an iterator to the beginning - iterator begin() noexcept { return data(); } - //! Returns a const iterator to the end - const_iterator end() const noexcept { return end_; } - //! Returns an iterator to the end - iterator end() noexcept { return end_; } - //! Returns a const iterator to the reverse beginning - const_reverse_iterator rbegin() const noexcept { return reverse_iterator(end_); } - //! Returns an iterator to the reverse beginning - reverse_iterator rbegin() noexcept { return reverse_iterator(end_); } - //! Returns a const iterator to the reverse end - const_reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } - //! Returns an iterator to the reverse end - reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - - /*! \brief Returns the size - * - * \note Use ssize for any expression involving arithmetic operations - (including loop indices). - */ - size_type size() const noexcept { return end_ - data(); } - //! Returns the signed size - index ssize() const noexcept { return end_ - data(); } - //! Returns whether the vector is empty - bool empty() const noexcept { return data() == end_; } - - //! Const access an element - const_reference operator[](size_type n) const noexcept +public: + //! Type of values stored in the vector + using value_type = T; + //! Type for representing size of the vector + using size_type = size_t; + //! Type for representing difference between two indices + using difference_type = ptrdiff_t; + //! Const reference to an element + using const_reference = const T&; + //! Const pointer to an element + using const_pointer = const T*; + //! Const iterator type to an element + using const_iterator = const T*; + //! Reference to an element + using reference = T&; + //! Pointer to an element + using pointer = T*; + //! Iterator type to an element + using iterator = T*; + //! Standard reverse iterator + using reverse_iterator = std::reverse_iterator; + //! Standard reverse iterator + using const_reverse_iterator = std::reverse_iterator; + + //! Returns a const iterator to the beginning + const_iterator begin() const noexcept { return data(); } + //! Returns an iterator to the beginning + iterator begin() noexcept { return data(); } + //! Returns a const iterator to the end + const_iterator end() const noexcept { return end_; } + //! Returns an iterator to the end + iterator end() noexcept { return end_; } + //! Returns a const iterator to the reverse beginning + const_reverse_iterator rbegin() const noexcept { return reverse_iterator(end_); } + //! Returns an iterator to the reverse beginning + reverse_iterator rbegin() noexcept { return reverse_iterator(end_); } + //! Returns a const iterator to the reverse end + const_reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } + //! Returns an iterator to the reverse end + reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + + /*! \brief Returns the size + * + * \note Use ssize for any expression involving arithmetic operations + (including loop indices). + */ + size_type size() const noexcept { return end_ - data(); } + //! Returns the signed size + index ssize() const noexcept { return end_ - data(); } + //! Returns whether the vector is empty + bool empty() const noexcept { return data() == end_; } + + //! Const access an element + const_reference operator[](size_type n) const noexcept + { + GMX_ASSERT(n < size(), "Index should be in range"); + return data_[n]; + } + //! Access an element + reference operator[](size_type n) noexcept + { + GMX_ASSERT(n < size(), "Index should be in range"); + return data_[n]; + } + //! Const access an element, throws an out_of_range exception when out of range + const_reference at(size_type n) const + { + if (n >= size()) { - GMX_ASSERT(n < size(), "Index should be in range"); - return data_[n]; + throw std::out_of_range("Vector index out of range"); } - //! Access an element - reference operator[](size_type n) noexcept + return data_[n]; + } + //! Access an element, throws an out_of_range exception when out of range + reference at(size_type n) + { + if (n >= size()) { - GMX_ASSERT(n < size(), "Index should be in range"); - return data_[n]; + throw std::out_of_range("Vector index out of range"); } - //! Const access an element, throws an out_of_range exception when out of range - const_reference at(size_type n) const + return data_[n]; + } + //! Returns the first element + reference front() const noexcept { return data_.front(); } + //! Returns the last element + reference back() const noexcept { return *(end_ - 1); } + + //! Returns a raw pointer to the contents of the array + const T* data() const noexcept { return data_.data(); } + + //! Returns a raw pointer to the contents of the array + T* data() noexcept { return data_.data(); } + + //! Adds element at the end + void push_back(const T& value) noexcept + { + GMX_ASSERT(size() < capacity, "Cannot add more elements than the capacity"); + *end_ = value; + end_++; + } + + //! Deletes last element + void pop_back() noexcept + { + GMX_ASSERT(!empty(), "Can only delete last element when present"); + end_--; + } + + //! Constructs an element at the end + template + reference emplace_back(Args&&... args) + { + GMX_ASSERT(size() < capacity, "Cannot add more elements than the capacity"); + if (std::is_move_assignable::value) { - if (n >= size()) - { - throw std::out_of_range("Vector index out of range"); - } - return data_[n]; + *end_ = std::move(T(args...)); } - //! Access an element, throws an out_of_range exception when out of range - reference at(size_type n) + else { - if (n >= size()) - { - throw std::out_of_range("Vector index out of range"); - } - return data_[n]; + *end_ = T(args...); } - //! Returns the first element - reference front() const noexcept { return data_.front(); } - //! Returns the last element - reference back() const noexcept { return *(end_ - 1); } + end_++; - //! Returns a raw pointer to the contents of the array - const T* data() const noexcept { return data_.data(); } + return back(); + } - //! Returns a raw pointer to the contents of the array - T* data() noexcept { return data_.data(); } + //! Clears content + void clear() noexcept { end_ = data(); } - //! Adds element at the end - void push_back(const T &value) noexcept - { - GMX_ASSERT(size() < capacity, "Cannot add more elements than the capacity"); - *end_ = value; - end_++; - } - - //! Deletes last element - void pop_back() noexcept - { - GMX_ASSERT(!empty(), "Can only delete last element when present"); - end_--; - } - - //! Constructs an element at the end - template - reference emplace_back (Args && ... args) - { - GMX_ASSERT(size() < capacity, "Cannot add more elements than the capacity"); - if (std::is_move_assignable::value) - { - *end_ = std::move(T(args ...)); - } - else - { - *end_ = T(args ...); - } - end_++; - - return back(); - } - - //! Clears content - void clear() noexcept { end_ = data(); } - - private: - //! The elements, stored in a fixed size array - std::array data_; - //! The size of the vector - pointer end_ = data(); +private: + //! The elements, stored in a fixed size array + std::array data_; + //! The size of the vector + pointer end_ = data(); }; } // namespace gmx diff --git a/src/gromacs/utility/flags.h b/src/gromacs/utility/flags.h index f34ac2e05f..d2f49344e2 100644 --- a/src/gromacs/utility/flags.h +++ b/src/gromacs/utility/flags.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,71 +62,65 @@ namespace gmx * \inlibraryapi * \ingroup module_utility */ -template +template class FlagsTemplate { - public: - //! Creates a flags object with no flags set. - FlagsTemplate() : flags_(0) {} - //! Creates a flags object from a single flag. - FlagsTemplate(FlagType flag) : flags_(flag) {} +public: + //! Creates a flags object with no flags set. + FlagsTemplate() : flags_(0) {} + //! Creates a flags object from a single flag. + FlagsTemplate(FlagType flag) : flags_(flag) {} - /*! \brief - * Tests if the given flag is set. - * - * Note that if \p flag has more than a single bit set, then returns - * true if any of them is set. - */ - bool test(FlagType flag) const { return (flags_ & flag) != 0; } - //! Clears all flags. - void clearAll() { flags_ = 0; } - //! Sets the given flag. - void set(FlagType flag) { flags_ |= flag; } - //! Clears the given flag. - void clear(FlagType flag) { flags_ &= ~flag; } - //! Sets or clears the given flag. - void set(FlagType flag, bool bSet) + /*! \brief + * Tests if the given flag is set. + * + * Note that if \p flag has more than a single bit set, then returns + * true if any of them is set. + */ + bool test(FlagType flag) const { return (flags_ & flag) != 0; } + //! Clears all flags. + void clearAll() { flags_ = 0; } + //! Sets the given flag. + void set(FlagType flag) { flags_ |= flag; } + //! Clears the given flag. + void clear(FlagType flag) { flags_ &= ~flag; } + //! Sets or clears the given flag. + void set(FlagType flag, bool bSet) + { + if (bSet) { - if (bSet) - { - set(flag); - } - else - { - clear(flag); - } + set(flag); } - - //! Combines flags from two flags objects. - FlagsTemplate - operator|(const FlagsTemplate &other) const - { - return FlagsTemplate(flags_ | other.flags_); - } - //! Combines flags from another flag object. - FlagsTemplate & - operator|=(const FlagsTemplate &other) - { - flags_ |= other.flags_; - return *this; - } - //! Combined flags from two flags objects. - FlagsTemplate - operator&(const FlagsTemplate &other) const - { - return FlagsTemplate(flags_ & other.flags_); - } - //! Returns an object with all flags flipped. - FlagsTemplate operator~() const + else { - return FlagsTemplate(~flags_); + clear(flag); } + } + + //! Combines flags from two flags objects. + FlagsTemplate operator|(const FlagsTemplate& other) const + { + return FlagsTemplate(flags_ | other.flags_); + } + //! Combines flags from another flag object. + FlagsTemplate& operator|=(const FlagsTemplate& other) + { + flags_ |= other.flags_; + return *this; + } + //! Combined flags from two flags objects. + FlagsTemplate operator&(const FlagsTemplate& other) const + { + return FlagsTemplate(flags_ & other.flags_); + } + //! Returns an object with all flags flipped. + FlagsTemplate operator~() const { return FlagsTemplate(~flags_); } - private: - //! Creates a flags object with the given flags. - explicit FlagsTemplate(unsigned long flags) : flags_(flags) {} +private: + //! Creates a flags object with the given flags. + explicit FlagsTemplate(unsigned long flags) : flags_(flags) {} - unsigned long flags_; + unsigned long flags_; }; } // namespace gmx diff --git a/src/gromacs/utility/futil.cpp b/src/gromacs/utility/futil.cpp index 99cb8f97b1..3505365e5f 100644 --- a/src/gromacs/utility/futil.cpp +++ b/src/gromacs/utility/futil.cpp @@ -52,12 +52,12 @@ #include #ifdef HAVE_UNISTD_H -#include +# include #endif #if GMX_NATIVE_WINDOWS -#include // For _chdir() and _getcwd() -#include -#include +# include // For _chdir() and _getcwd() +# include +# include #endif #include "gromacs/utility/cstringutil.h" @@ -75,14 +75,15 @@ compressed or .gzipped files. This way we can distinguish between them without having to change the semantics of reading from/writing to files) */ -typedef struct t_pstack { - FILE *fp; - struct t_pstack *prev; +typedef struct t_pstack +{ + FILE* fp; + struct t_pstack* prev; } t_pstack; -static t_pstack *pstack = nullptr; -static bool bUnbuffered = false; -static int s_maxBackupCount = 0; +static t_pstack* pstack = nullptr; +static bool bUnbuffered = false; +static int s_maxBackupCount = 0; /* this linked list is an intrinsically globally shared object, so we have to protect it with mutexes */ @@ -95,12 +96,12 @@ namespace gmx namespace { //! Global library file finder; stores the object set with setLibraryFileFinder(). -const DataFileFinder *g_libFileFinder; +const DataFileFinder* g_libFileFinder; //! Default library file finder if nothing is set. -const DataFileFinder g_defaultLibFileFinder; -} // namespace +const DataFileFinder g_defaultLibFileFinder; +} // namespace -const DataFileFinder &getLibraryFileFinder() +const DataFileFinder& getLibraryFileFinder() { if (g_libFileFinder != nullptr) { @@ -109,7 +110,7 @@ const DataFileFinder &getLibraryFileFinder() return g_defaultLibFileFinder; } -void setLibraryFileFinder(const DataFileFinder *finder) +void setLibraryFileFinder(const DataFileFinder* finder) { g_libFileFinder = finder; } @@ -125,7 +126,7 @@ void gmx_set_max_backup_count(int count) { if (count < 0) { - const char *env = getenv("GMX_MAXBACKUP"); + const char* env = getenv("GMX_MAXBACKUP"); if (env != nullptr) { // TODO: Check that the value is converted properly. @@ -146,11 +147,11 @@ void gmx_set_max_backup_count(int count) s_maxBackupCount = count; } -static void push_ps(FILE *fp) +static void push_ps(FILE* fp) { - t_pstack *ps; + t_pstack* ps; - Lock pstackLock(pstack_mutex); + Lock pstackLock(pstack_mutex); snew(ps, 1); ps->fp = fp; @@ -160,31 +161,31 @@ static void push_ps(FILE *fp) #if GMX_FAHCORE /* don't use pipes!*/ -#define popen fah_fopen -#define pclose fah_fclose -#define SKIP_FFOPS 1 +# define popen fah_fopen +# define pclose fah_fclose +# define SKIP_FFOPS 1 #else -#ifdef gmx_ffclose -#undef gmx_ffclose -#endif -#if (!HAVE_PIPES && !defined(__native_client__)) -static FILE *popen(const char *nm, const char *mode) +# ifdef gmx_ffclose +# undef gmx_ffclose +# endif +# if (!HAVE_PIPES && !defined(__native_client__)) +static FILE* popen(const char* nm, const char* mode) { gmx_impl("Sorry no pipes..."); return NULL; } -static int pclose(FILE *fp) +static int pclose(FILE* fp) { gmx_impl("Sorry no pipes..."); return 0; } -#endif /* !HAVE_PIPES && !defined(__native_client__) */ -#endif /* GMX_FAHCORE */ +# endif /* !HAVE_PIPES && !defined(__native_client__) */ +#endif /* GMX_FAHCORE */ -int gmx_ffclose(FILE *fp) +int gmx_ffclose(FILE* fp) { #ifdef SKIP_FFOPS return fclose(fp); @@ -192,7 +193,7 @@ int gmx_ffclose(FILE *fp) t_pstack *ps, *tmp; int ret = 0; - Lock pstackLock(pstack_mutex); + Lock pstackLock(pstack_mutex); ps = pstack; if (ps == nullptr) @@ -241,11 +242,11 @@ int gmx_ffclose(FILE *fp) } -void frewind(FILE *fp) +void frewind(FILE* fp) { - Lock pstackLock(pstack_mutex); + Lock pstackLock(pstack_mutex); - t_pstack *ps = pstack; + t_pstack* ps = pstack; while (ps != nullptr) { if (ps->fp == fp) @@ -258,49 +259,49 @@ void frewind(FILE *fp) rewind(fp); } -int gmx_fseek(FILE *stream, gmx_off_t offset, int whence) +int gmx_fseek(FILE* stream, gmx_off_t offset, int whence) { #if HAVE_FSEEKO return fseeko(stream, offset, whence); #else -#if HAVE__FSEEKI64 +# if HAVE__FSEEKI64 return _fseeki64(stream, offset, whence); -#else +# else return fseek(stream, offset, whence); -#endif +# endif #endif } -gmx_off_t gmx_ftell(FILE *stream) +gmx_off_t gmx_ftell(FILE* stream) { #if HAVE_FSEEKO return ftello(stream); #else -#if HAVE__FSEEKI64 -#ifndef __MINGW32__ +# if HAVE__FSEEKI64 +# ifndef __MINGW32__ return _ftelli64(stream); -#else +# else return ftello64(stream); -#endif -#else +# endif +# else return ftell(stream); -#endif +# endif #endif } -int gmx_truncate(const std::string &filename, gmx_off_t length) +int gmx_truncate(const std::string& filename, gmx_off_t length) { #if GMX_NATIVE_WINDOWS - FILE *fp = fopen(filename.c_str(), "rb+"); + FILE* fp = fopen(filename.c_str(), "rb+"); if (fp == NULL) { return -1; } -#ifdef _MSC_VER +# ifdef _MSC_VER int rc = _chsize_s(fileno(fp), length); -#else +# else int rc = _chsize(fileno(fp), length); -#endif +# endif fclose(fp); return rc; #else @@ -308,9 +309,9 @@ int gmx_truncate(const std::string &filename, gmx_off_t length) #endif } -static FILE *uncompress(const std::string &fn, const char *mode) +static FILE* uncompress(const std::string& fn, const char* mode) { - FILE *fp; + FILE* fp; std::string buf = "uncompress -c < " + fn; fprintf(stderr, "Going to execute '%s'\n", buf.c_str()); if ((fp = popen(buf.c_str(), mode)) == nullptr) @@ -322,9 +323,9 @@ static FILE *uncompress(const std::string &fn, const char *mode) return fp; } -static FILE *gunzip(const std::string &fn, const char *mode) +static FILE* gunzip(const std::string& fn, const char* mode) { - FILE *fp; + FILE* fp; std::string buf = "gunzip -c < "; buf += fn; fprintf(stderr, "Going to execute '%s'\n", buf.c_str()); @@ -337,9 +338,9 @@ static FILE *gunzip(const std::string &fn, const char *mode) return fp; } -gmx_bool gmx_fexist(const std::string &fname) +gmx_bool gmx_fexist(const std::string& fname) { - FILE *test; + FILE* test; if (fname.empty()) { @@ -348,13 +349,13 @@ gmx_bool gmx_fexist(const std::string &fname) test = fopen(fname.c_str(), "r"); if (test == nullptr) { - /*Windows doesn't allow fopen of directory - so we need to check this seperately */ - #if GMX_NATIVE_WINDOWS +/*Windows doesn't allow fopen of directory - so we need to check this seperately */ +#if GMX_NATIVE_WINDOWS DWORD attr = GetFileAttributes(fname.c_str()); return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY); - #else +#else return FALSE; - #endif +#endif } else { @@ -363,13 +364,13 @@ gmx_bool gmx_fexist(const std::string &fname) } } -static std::string backup_fn(const std::string &file) +static std::string backup_fn(const std::string& file) { - int count = 1; + int count = 1; - std::string directory = gmx::Path::getParentPath(file); - std::string fn = gmx::Path::getFilename(file); - std::string buf; + std::string directory = gmx::Path::getParentPath(file); + std::string fn = gmx::Path::getFilename(file); + std::string buf; if (directory.empty()) { directory = "."; @@ -378,15 +379,15 @@ static std::string backup_fn(const std::string &file) { buf = gmx::formatString("%s/#%s.%d#", directory.c_str(), fn.c_str(), count); count++; - } - while ((count <= s_maxBackupCount) && gmx_fexist(buf)); + } while ((count <= s_maxBackupCount) && gmx_fexist(buf)); /* Arbitrarily bail out */ if (count > s_maxBackupCount) { /* TODO: The error message is only accurate for code that starts with * Gromacs command-line interface. */ - gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n" + gmx_fatal(FARGS, + "Won't make more than %d backups of %s for you.\n" "The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.", s_maxBackupCount, fn.c_str()); } @@ -394,7 +395,7 @@ static std::string backup_fn(const std::string &file) return buf; } -void make_backup(const std::string &name) +void make_backup(const std::string& name) { if (s_maxBackupCount <= 0) { @@ -405,8 +406,7 @@ void make_backup(const std::string &name) auto backup = backup_fn(name); if (rename(name.c_str(), backup.c_str()) == 0) { - fprintf(stderr, "\nBack Off! I just backed up %s to %s\n", - name.c_str(), backup.c_str()); + fprintf(stderr, "\nBack Off! I just backed up %s to %s\n", name.c_str(), backup.c_str()); } else { @@ -415,12 +415,12 @@ void make_backup(const std::string &name) } } -FILE *gmx_ffopen(const std::string &file, const char *mode) +FILE* gmx_ffopen(const std::string& file, const char* mode) { #ifdef SKIP_FFOPS return fopen(file, mode); #else - FILE *ff = nullptr; + FILE* ff = nullptr; gmx_bool bRead; int bs; @@ -444,7 +444,7 @@ FILE *gmx_ffopen(const std::string &file, const char *mode) /* Check whether we should be using buffering (default) or not * (for debugging) */ - const char *bufsize = nullptr; + const char* bufsize = nullptr; if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != nullptr)) { /* Check whether to use completely unbuffered */ @@ -462,8 +462,8 @@ FILE *gmx_ffopen(const std::string &file, const char *mode) } else { - char *ptr; - snew(ptr, bs+8); + char* ptr; + snew(ptr, bs + 8); if (setvbuf(ff, ptr, _IOFBF, bs) != 0) { gmx_file("Buffering File"); @@ -481,7 +481,7 @@ FILE *gmx_ffopen(const std::string &file, const char *mode) } else { - compressedFileName = file; + compressedFileName = file; compressedFileName += ".gz"; if (gmx_fexist(compressedFileName)) { @@ -500,40 +500,37 @@ FILE *gmx_ffopen(const std::string &file, const char *mode) namespace gmx { -std::string findLibraryFile(const std::string &filename, bool bAddCWD, bool bFatal) +std::string findLibraryFile(const std::string& filename, bool bAddCWD, bool bFatal) { std::string result; try { - const DataFileFinder &finder = getLibraryFileFinder(); - result = finder.findFile(DataFileOptions(filename) - .includeCurrentDir(bAddCWD) - .throwIfNotFound(bFatal)); + const DataFileFinder& finder = getLibraryFileFinder(); + result = finder.findFile( + DataFileOptions(filename).includeCurrentDir(bAddCWD).throwIfNotFound(bFatal)); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR return result; } -std::string findLibraryFile(const char *filename, bool bAddCWD, bool bFatal) +std::string findLibraryFile(const char* filename, bool bAddCWD, bool bFatal) { return findLibraryFile(std::string(filename), bAddCWD, bFatal); } -FilePtr openLibraryFile(const std::string &filename, bool bAddCWD, bool bFatal) +FilePtr openLibraryFile(const std::string& filename, bool bAddCWD, bool bFatal) { FilePtr fp; try { - const DataFileFinder &finder = getLibraryFileFinder(); - fp = finder.openFile(DataFileOptions(filename) - .includeCurrentDir(bAddCWD) - .throwIfNotFound(bFatal)); + const DataFileFinder& finder = getLibraryFileFinder(); + fp = finder.openFile(DataFileOptions(filename).includeCurrentDir(bAddCWD).throwIfNotFound(bFatal)); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR return fp; } -FilePtr openLibraryFile(const char *filename, bool bAddCWD, bool bFatal) +FilePtr openLibraryFile(const char* filename, bool bAddCWD, bool bFatal) { return openLibraryFile(std::string(filename), bAddCWD, bFatal); } @@ -544,7 +541,7 @@ FilePtr openLibraryFile(const char *filename, bool bAddCWD, bool bFatal) * file and (on non-Windows systems) return a file descriptor to it. * * \todo Use std::string and std::vector. */ -static int makeTemporaryFilename(char *buf) +static int makeTemporaryFilename(char* buf) { int len; @@ -552,7 +549,7 @@ static int makeTemporaryFilename(char *buf) { gmx_fatal(FARGS, "Buf passed to gmx_tmpnam must be at least 7 bytes long"); } - for (int i = len-6; (i < len); i++) + for (int i = len - 6; (i < len); i++) { buf[i] = 'X'; } @@ -565,8 +562,7 @@ static int makeTemporaryFilename(char *buf) _mktemp(buf); if (buf == NULL) { - gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, - strerror(errno)); + gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, strerror(errno)); } fd = 0; #else @@ -574,14 +570,13 @@ static int makeTemporaryFilename(char *buf) if (fd < 0) { - gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, - strerror(errno)); + gmx_fatal(FARGS, "Error creating temporary file %s: %s", buf, strerror(errno)); } #endif return fd; } // TODO use std::string -void gmx_tmpnam(char *buf) +void gmx_tmpnam(char* buf) { int fd = makeTemporaryFilename(buf); #if !GMX_NATIVE_WINDOWS @@ -590,9 +585,9 @@ void gmx_tmpnam(char *buf) } // TODO use std::string -FILE *gmx_fopen_temporary(char *buf) +FILE* gmx_fopen_temporary(char* buf) { - FILE *fpout = nullptr; + FILE* fpout = nullptr; int fd = makeTemporaryFilename(buf); #if GMX_NATIVE_WINDOWS @@ -610,14 +605,13 @@ FILE *gmx_fopen_temporary(char *buf) return fpout; } -int gmx_file_rename(const char *oldname, const char *newname) +int gmx_file_rename(const char* oldname, const char* newname) { #if !GMX_NATIVE_WINDOWS /* under unix, rename() is atomic (at least, it should be). */ return rename(oldname, newname); #else - if (MoveFileEx(oldname, newname, - MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) + if (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { return 0; } @@ -628,7 +622,7 @@ int gmx_file_rename(const char *oldname, const char *newname) #endif } -int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty) +int gmx_file_copy(const char* oldname, const char* newname, gmx_bool copy_if_empty) { gmx::FilePtr in(fopen(oldname, "rb")); if (!in) @@ -649,7 +643,7 @@ int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_emp } /* the full copy buffer size: */ - constexpr int FILECOPY_BUFSIZE = 1<<16; + constexpr int FILECOPY_BUFSIZE = 1 << 16; std::vector buf(FILECOPY_BUFSIZE); while (!feof(in.get())) @@ -685,7 +679,7 @@ int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_emp } -int gmx_fsync(FILE *fp) +int gmx_fsync(FILE* fp) { int rc = 0; @@ -697,22 +691,22 @@ int gmx_fsync(FILE *fp) int fn; /* get the file number */ -#if HAVE_FILENO +# if HAVE_FILENO fn = fileno(fp); -#elif HAVE__FILENO +# elif HAVE__FILENO fn = _fileno(fp); -#else +# else fn = -1; -#endif +# endif /* do the actual fsync */ if (fn >= 0) { -#if HAVE_FSYNC +# if HAVE_FSYNC rc = fsync(fn); -#elif HAVE__COMMIT +# elif HAVE__COMMIT rc = _commit(fn); -#endif +# endif } } #endif /* GMX_FAHCORE */ @@ -738,30 +732,28 @@ int gmx_fsync(FILE *fp) return rc; } -void gmx_chdir(const char *directory) +void gmx_chdir(const char* directory) { #if GMX_NATIVE_WINDOWS int rc = _chdir(directory); #else - int rc = chdir(directory); + int rc = chdir(directory); #endif if (rc != 0) { - gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s", - directory, strerror(errno)); + gmx_fatal(FARGS, "Cannot change directory to '%s'. Reason: %s", directory, strerror(errno)); } } -void gmx_getcwd(char *buffer, size_t size) +void gmx_getcwd(char* buffer, size_t size) { #if GMX_NATIVE_WINDOWS - char *pdum = _getcwd(buffer, size); + char* pdum = _getcwd(buffer, size); #else - char *pdum = getcwd(buffer, size); + char* pdum = getcwd(buffer, size); #endif if (pdum == nullptr) { - gmx_fatal(FARGS, "Cannot get working directory. Reason: %s", - strerror(errno)); + gmx_fatal(FARGS, "Cannot get working directory. Reason: %s", strerror(errno)); } } diff --git a/src/gromacs/utility/futil.h b/src/gromacs/utility/futil.h index 1ba60ef3a6..ded880b5f6 100644 --- a/src/gromacs/utility/futil.h +++ b/src/gromacs/utility/futil.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,15 +58,15 @@ * Maximum path length, if the OS provides one, otherwise a fixed constant. */ #ifdef PATH_MAX -# define GMX_PATH_MAX PATH_MAX +# define GMX_PATH_MAX PATH_MAX #elif defined MAX_PATH -# define GMX_PATH_MAX MAX_PATH +# define GMX_PATH_MAX MAX_PATH #else -# define GMX_PATH_MAX 4096 +# define GMX_PATH_MAX 4096 #endif /** \Gromacs definition to use instead of `off_t`. */ -typedef int64_t gmx_off_t; +typedef int64_t gmx_off_t; /*! \brief * Turn off buffering for output files (which is default) for debugging @@ -95,12 +95,12 @@ void gmx_set_max_backup_count(int count); * Note that this returns `TRUE` even if \p fname is a directory instead of a * file. */ -gmx_bool gmx_fexist(const std::string &fname); +gmx_bool gmx_fexist(const std::string& fname); /*! \brief * Makes a backup of file if the file exists. */ -void make_backup(const std::string &file); +void make_backup(const std::string& file); /*! \brief * Opens a file, with \Gromacs-specific additions. @@ -115,10 +115,10 @@ void make_backup(const std::string &file); * overwriting it. * A fatal error results if the file cannot be opened, for whatever reason. */ -FILE *gmx_ffopen(const std::string &file, const char *mode); +FILE* gmx_ffopen(const std::string& file, const char* mode); /** Closes a file opened with gmx_ffopen(). */ -int gmx_ffclose(FILE *fp); +int gmx_ffclose(FILE* fp); /*! \brief * Wraps rewind() for files opened with gmx_ffopen(). @@ -126,22 +126,22 @@ int gmx_ffclose(FILE *fp); * A fatal error results if this function is called for a pipe (a compressed * input file). */ -void frewind(FILE *fp); +void frewind(FILE* fp); /** OS-independent 64-bit fseek(). * * \return 0 when successful, or -1 (and set errno) in case of error. */ -int gmx_fseek(FILE *stream, gmx_off_t offset, int whence); +int gmx_fseek(FILE* stream, gmx_off_t offset, int whence); /** OS-independent 64-bit ftell(). * * \return The current offset when successful, or -1 (and set errno) in case of error. */ -gmx_off_t gmx_ftell(FILE *stream); +gmx_off_t gmx_ftell(FILE* stream); /** OS-independent truncate(). */ -int gmx_truncate(const std::string &filename, gmx_off_t length); +int gmx_truncate(const std::string& filename, gmx_off_t length); namespace gmx { @@ -154,9 +154,9 @@ namespace gmx * error results if the file is not found in any location and \c * bFatal is true. */ -std::string findLibraryFile(const std::string &filename, bool bAddCWD = true, bool bFatal = true); +std::string findLibraryFile(const std::string& filename, bool bAddCWD = true, bool bFatal = true); //! \copydoc findLibraryFile(const std::string &, bool, bool) -std::string findLibraryFile(const char *filename, bool bAddCWD = true, bool bFatal = true); +std::string findLibraryFile(const char* filename, bool bAddCWD = true, bool bFatal = true); /*! \brief * Opens a library file for reading in an RAII-style `FILE` handle. @@ -164,9 +164,9 @@ std::string findLibraryFile(const char *filename, bool bAddCWD = true, bool bFat * Works as findLibraryFile(), except that it opens the file and * returns a file handle. */ -FilePtr openLibraryFile(const std::string &filename, bool bAddCWD = true, bool bFatal = true); +FilePtr openLibraryFile(const std::string& filename, bool bAddCWD = true, bool bFatal = true); //! \copydoc openLibraryFile(const std::string &, bool, bool) -FilePtr openLibraryFile(const char *filename, bool bAddCWD = true, bool bFatal = true); +FilePtr openLibraryFile(const char* filename, bool bAddCWD = true, bool bFatal = true); } // namespace gmx @@ -175,48 +175,48 @@ FilePtr openLibraryFile(const char *filename, bool bAddCWD = true, bool bFatal = * * \p buf should be at least 7 bytes long */ -FILE *gmx_fopen_temporary(char *buf); +FILE* gmx_fopen_temporary(char* buf); /*! \brief * Creates unique name for temp file (wrapper around mkstemp). * * \p buf should be at least 7 bytes long */ -void gmx_tmpnam(char *buf); +void gmx_tmpnam(char* buf); /*! \brief * OS-independent rename(). * * Renames/moves a file atomically, if the OS makes that available. */ -int gmx_file_rename(const char *oldname, const char *newname); +int gmx_file_rename(const char* oldname, const char* newname); /*! \brief * Copies a file (data only) oldname to newname. * * If \p copy_if_empty is `FALSE`, the file won't be copied if it's empty. */ -int gmx_file_copy(const char *oldname, const char *newname, gmx_bool copy_if_empty); +int gmx_file_copy(const char* oldname, const char* newname, gmx_bool copy_if_empty); /*! \brief * OS-independent fsync(). * * Only use this during checkpointing! */ -int gmx_fsync(FILE *fp); +int gmx_fsync(FILE* fp); /*! \brief * OS-independent chdir(). * * Exits with a fatal error if changing the directory fails. */ -void gmx_chdir(const char *directory); +void gmx_chdir(const char* directory); /*! \brief * OS-independent getcwd(). * * Exits with a fatal error if the call fails. */ -void gmx_getcwd(char *buffer, size_t size); +void gmx_getcwd(char* buffer, size_t size); namespace gmx { @@ -240,7 +240,7 @@ class DataFileFinder; * * \ingroup module_utility */ -const DataFileFinder &getLibraryFileFinder(); +const DataFileFinder& getLibraryFileFinder(); /*! \brief * Sets a finder for location data files from share/top/. * @@ -258,7 +258,7 @@ const DataFileFinder &getLibraryFileFinder(); * * Does not throw. */ -void setLibraryFileFinder(const DataFileFinder *finder); +void setLibraryFileFinder(const DataFileFinder* finder); } // namespace gmx diff --git a/src/gromacs/utility/gmxassert.cpp b/src/gromacs/utility/gmxassert.cpp index 9ab6a11fc4..e0d06d56ab 100644 --- a/src/gromacs/utility/gmxassert.cpp +++ b/src/gromacs/utility/gmxassert.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,8 +57,7 @@ namespace gmx namespace internal { -void assertHandler(const char *condition, const char *msg, - const char *func, const char *file, int line) +void assertHandler(const char* condition, const char* msg, const char* func, const char* file, int line) { printFatalErrorHeader(stderr, "Assertion failed", func, file, line); std::fprintf(stderr, "Condition: %s\n", condition); @@ -67,7 +66,7 @@ void assertHandler(const char *condition, const char *msg, gmx_exit_on_fatal_error(ExitType_Abort, 1); } -} // namespace internal +} // namespace internal //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/gmxassert.h b/src/gromacs/utility/gmxassert.h index d48997917b..c278f2c2fc 100644 --- a/src/gromacs/utility/gmxassert.h +++ b/src/gromacs/utility/gmxassert.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,22 +63,22 @@ * keep the option open. */ #ifdef GMX_DISABLE_ASSERTS -#define GMX_RELEASE_ASSERT(condition, msg) -#else -#ifdef _MSC_VER -#define GMX_RELEASE_ASSERT(condition, msg) \ - ((void) ((condition) ? (void)0 : \ - ::gmx::internal::assertHandler(#condition, msg, \ - GMX_CURRENT_FUNCTION, __FILE__, __LINE__))) +# define GMX_RELEASE_ASSERT(condition, msg) #else +# ifdef _MSC_VER +# define GMX_RELEASE_ASSERT(condition, msg) \ + ((void)((condition) ? (void)0 \ + : ::gmx::internal::assertHandler(#condition, msg, GMX_CURRENT_FUNCTION, \ + __FILE__, __LINE__))) +# else // Use an "immediately invoked function expression" to allow being // used in constexpr context with older GCC versions // https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ -#define GMX_RELEASE_ASSERT(condition, msg) \ - ((void) ((condition) ? (void)0 : \ - [&](){::gmx::internal::assertHandler(#condition, msg, \ - GMX_CURRENT_FUNCTION, __FILE__, __LINE__); } ())) -#endif +# define GMX_RELEASE_ASSERT(condition, msg) \ + ((void)((condition) ? (void)0 : [&]() { \ + ::gmx::internal::assertHandler(#condition, msg, GMX_CURRENT_FUNCTION, __FILE__, __LINE__); \ + }())) +# endif #endif /*! \def GMX_ASSERT * \brief @@ -89,9 +90,9 @@ * \see ::GMX_RELEASE_ASSERT */ #ifdef NDEBUG -#define GMX_ASSERT(condition, msg) ((void)0) +# define GMX_ASSERT(condition, msg) ((void)0) #else -#define GMX_ASSERT(condition, msg) GMX_RELEASE_ASSERT(condition, msg) +# define GMX_ASSERT(condition, msg) GMX_RELEASE_ASSERT(condition, msg) #endif //! \} @@ -111,11 +112,10 @@ namespace internal * * \ingroup module_utility */ -[[noreturn]] -void assertHandler(const char *condition, const char *msg, - const char *func, const char *file, int line); +[[noreturn]] void +assertHandler(const char* condition, const char* msg, const char* func, const char* file, int line); -} // namespace internal +} // namespace internal //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/gmxmpi.h b/src/gromacs/utility/gmxmpi.h index f39eb1b323..6c4d7a2281 100644 --- a/src/gromacs/utility/gmxmpi.h +++ b/src/gromacs/utility/gmxmpi.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,38 +54,38 @@ /*! \cond */ #if GMX_LIB_MPI /* MPI C++ binding is deprecated and can cause name conflicts (e.g. stdio/mpi seek) */ -#define MPICH_SKIP_MPICXX 1 -#define OMPI_SKIP_MPICXX 1 +# define MPICH_SKIP_MPICXX 1 +# define OMPI_SKIP_MPICXX 1 /* disable bindings for SGI MPT also */ -#define MPI_NO_CPPBIND 1 -#include +# define MPI_NO_CPPBIND 1 +# include /* Starting with 2.2 MPI_INT64_T is required. Earlier version still might have it. In theory MPI_Datatype doesn't have to be a #define, but current available MPI implementations (OpenMPI + MPICH (+derivates)) use #define and future versions should support 2.2. */ -#if (MPI_VERSION == 1 || (MPI_VERSION == 2 && MPI_SUBVERSION < 2)) && !defined MPI_INT64_T -#include -#if LONG_MAX == 9223372036854775807L -#define MPI_INT64_T MPI_LONG -#elif LONG_LONG_MAX == 9223372036854775807L -#define MPI_INT64_T MPI_LONG_LONG -#else -#error No MPI_INT64_T and no 64 bit integer found. -#endif -#endif /*MPI_INT64_T*/ -#else -#if GMX_THREAD_MPI -#include "thread_mpi/mpi_bindings.h" /* IWYU pragma: export */ -#include "thread_mpi/tmpi.h" /* IWYU pragma: export */ +# if (MPI_VERSION == 1 || (MPI_VERSION == 2 && MPI_SUBVERSION < 2)) && !defined MPI_INT64_T +# include +# if LONG_MAX == 9223372036854775807L +# define MPI_INT64_T MPI_LONG +# elif LONG_LONG_MAX == 9223372036854775807L +# define MPI_INT64_T MPI_LONG_LONG +# else +# error No MPI_INT64_T and no 64 bit integer found. +# endif +# endif /*MPI_INT64_T*/ #else +# if GMX_THREAD_MPI +# include "thread_mpi/mpi_bindings.h" /* IWYU pragma: export */ +# include "thread_mpi/tmpi.h" /* IWYU pragma: export */ +# else typedef void* MPI_Comm; typedef void* MPI_Request; typedef void* MPI_Status; typedef void* MPI_Group; -#define MPI_COMM_NULL nullptr -#define MPI_GROUP_NULL nullptr -#define MPI_COMM_WORLD nullptr -#endif +# define MPI_COMM_NULL nullptr +# define MPI_GROUP_NULL nullptr +# define MPI_COMM_WORLD nullptr +# endif #endif //! \endcond diff --git a/src/gromacs/utility/gmxomp.cpp b/src/gromacs/utility/gmxomp.cpp index 8be5a85842..35f3323dd2 100644 --- a/src/gromacs/utility/gmxomp.cpp +++ b/src/gromacs/utility/gmxomp.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,7 +48,7 @@ #include #if GMX_OPENMP -#include +# include #endif #include "gromacs/utility/basedefinitions.h" @@ -94,7 +94,7 @@ void gmx_omp_set_num_threads(int num_threads) #endif } -gmx_bool gmx_omp_check_thread_affinity(char **message) +gmx_bool gmx_omp_check_thread_affinity(char** message) { bool shouldSetAffinity = true; @@ -103,15 +103,15 @@ gmx_bool gmx_omp_check_thread_affinity(char **message) /* We assume that the affinity setting is available on all platforms * gcc supports. Even if this is not the case (e.g. Mac OS) the user * will only get a warning. */ -#if defined(__GNUC__) || defined(__INTEL_COMPILER) - const char *programName; +# if defined(__GNUC__) || defined(__INTEL_COMPILER) + const char* programName; try { programName = gmx::getProgramContext().displayName(); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR - const char *const gomp_env = getenv("GOMP_CPU_AFFINITY"); + const char* const gomp_env = getenv("GOMP_CPU_AFFINITY"); const bool bGompCpuAffinitySet = (gomp_env != nullptr); /* turn off internal pinning if GOMP_CPU_AFFINITY is set & non-empty */ @@ -120,42 +120,40 @@ gmx_bool gmx_omp_check_thread_affinity(char **message) try { std::string buf = gmx::formatString( - "NOTE: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n" - " setting as the two can conflict and cause performance degradation.\n" - " To keep using the %s internal affinity setting, unset the\n" - " GOMP_CPU_AFFINITY environment variable.", - programName, programName); + "NOTE: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n" + " setting as the two can conflict and cause performance degradation.\n" + " To keep using the %s internal affinity setting, unset the\n" + " GOMP_CPU_AFFINITY environment variable.", + programName, programName); *message = gmx_strdup(buf.c_str()); } - GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; + GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR shouldSetAffinity = false; } -#endif /* __GNUC__ || __INTEL_COMPILER */ +# endif /* __GNUC__ || __INTEL_COMPILER */ -#if defined(__INTEL_COMPILER) - const char *const kmp_env = getenv("KMP_AFFINITY"); +# if defined(__INTEL_COMPILER) + const char* const kmp_env = getenv("KMP_AFFINITY"); const bool bKmpAffinitySet = (kmp_env != NULL); // turn off internal pinning if KMP_AFFINITY is set but does not contain // the settings 'disabled' or 'none'. - if (bKmpAffinitySet && - (strstr(kmp_env, "disabled") == NULL) && - (strstr(kmp_env, "none") == NULL)) + if (bKmpAffinitySet && (strstr(kmp_env, "disabled") == NULL) && (strstr(kmp_env, "none") == NULL)) { try { std::string buf = gmx::formatString( - "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n" - " setting as the two can conflict and cause performance degradation.\n" - " To keep using the %s internal affinity setting, unset the\n" - " KMP_AFFINITY environment variable or set it to 'none' or 'disabled'.", - programName, programName); + "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n" + " setting as the two can conflict and cause performance degradation.\n" + " To keep using the %s internal affinity setting, unset the\n" + " KMP_AFFINITY environment variable or set it to 'none' or 'disabled'.", + programName, programName); *message = gmx_strdup(buf.c_str()); } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; shouldSetAffinity = false; } -#endif /* __INTEL_COMPILER */ +# endif /* __INTEL_COMPILER */ #endif /* GMX_OPENMP */ return shouldSetAffinity; diff --git a/src/gromacs/utility/gmxomp.h b/src/gromacs/utility/gmxomp.h index f00c5bdde5..ab23f90651 100644 --- a/src/gromacs/utility/gmxomp.h +++ b/src/gromacs/utility/gmxomp.h @@ -54,9 +54,9 @@ #include #if GMX_NATIVE_WINDOWS -#include +# include #elif HAVE_XMMINTRIN_H -#include +# include #endif #include "gromacs/utility/basedefinitions.h" @@ -112,7 +112,7 @@ void gmx_omp_set_num_threads(int num_threads); * allocated for \p *message. * If the return value is `true`, \p *message is NULL. */ -gmx_bool gmx_omp_check_thread_affinity(char **message); +gmx_bool gmx_omp_check_thread_affinity(char** message); /*! \brief * Pause for use in a spin-wait loop. diff --git a/src/gromacs/utility/ikeyvaluetreeerror.cpp b/src/gromacs/utility/ikeyvaluetreeerror.cpp index e9f258dbd8..d4ed991b3a 100644 --- a/src/gromacs/utility/ikeyvaluetreeerror.cpp +++ b/src/gromacs/utility/ikeyvaluetreeerror.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,24 +48,21 @@ namespace class DefaultKeyValueTreeErrorHandler : public IKeyValueTreeErrorHandler { - public: - bool onError(UserInputError *ex, const KeyValueTreePath &context) override - { - std::string message - = formatString("While processing '%s':", context.toString().c_str()); - ex->prependContext(message); - return false; - } +public: + bool onError(UserInputError* ex, const KeyValueTreePath& context) override + { + std::string message = formatString("While processing '%s':", context.toString().c_str()); + ex->prependContext(message); + return false; + } }; -} // namespace +} // namespace -IKeyValueTreeErrorHandler::~IKeyValueTreeErrorHandler() -{ -} +IKeyValueTreeErrorHandler::~IKeyValueTreeErrorHandler() {} //! \cond libapi -IKeyValueTreeErrorHandler *defaultKeyValueTreeErrorHandler() +IKeyValueTreeErrorHandler* defaultKeyValueTreeErrorHandler() { static DefaultKeyValueTreeErrorHandler instance; return &instance; diff --git a/src/gromacs/utility/ikeyvaluetreeerror.h b/src/gromacs/utility/ikeyvaluetreeerror.h index bf13183719..a697f15a2a 100644 --- a/src/gromacs/utility/ikeyvaluetreeerror.h +++ b/src/gromacs/utility/ikeyvaluetreeerror.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,11 +51,11 @@ class UserInputError; class IKeyValueTreeErrorHandler { - public: - virtual bool onError(UserInputError *ex, const KeyValueTreePath &context) = 0; +public: + virtual bool onError(UserInputError* ex, const KeyValueTreePath& context) = 0; - protected: - virtual ~IKeyValueTreeErrorHandler(); +protected: + virtual ~IKeyValueTreeErrorHandler(); }; //! \cond libapi @@ -64,7 +64,7 @@ class IKeyValueTreeErrorHandler * * \ingroup module_utility */ -IKeyValueTreeErrorHandler *defaultKeyValueTreeErrorHandler(); +IKeyValueTreeErrorHandler* defaultKeyValueTreeErrorHandler(); //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/init.cpp b/src/gromacs/utility/init.cpp index 5609e94a51..07d87b8f2f 100644 --- a/src/gromacs/utility/init.cpp +++ b/src/gromacs/utility/init.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,7 +49,7 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/gmxassert.h" #if GMX_LIB_MPI -#include "gromacs/utility/gmxmpi.h" +# include "gromacs/utility/gmxmpi.h" #endif namespace gmx @@ -61,9 +61,9 @@ namespace //! Maintains global counter of attempts to initialize MPI int g_initializationCounter = 0; #endif -} +} // namespace -void init(int *argc, char ***argv) // NOLINT(readability-non-const-parameter) +void init(int* argc, char*** argv) // NOLINT(readability-non-const-parameter) { #if GMX_LIB_MPI int isInitialized = 0, isFinalized = 0; @@ -81,10 +81,10 @@ void init(int *argc, char ***argv) // NOLINT(readability-non-const-parameter) } else { -#if GMX_FAHCORE +# if GMX_FAHCORE fah_MPI_Init(argc, argv); -#else -# if GMX_OPENMP +# else +# if GMX_OPENMP /* Formally we need to use MPI_Init_thread and ask for MPI_THREAD_FUNNELED * level of thread support when using OpenMP. However, in practice we * have never seen any problems with just using MPI_Init(), and some MPI @@ -108,13 +108,15 @@ void init(int *argc, char ***argv) // NOLINT(readability-non-const-parameter) rc = MPI_Init_thread(argc, argv, MPI_THREAD_FUNNELED, &provided); if (rc != 0 && provided < MPI_THREAD_FUNNELED) { - gmx_warning("GROMACS was compiled with OpenMP support, but there is no thread support in the MPI library. Keep your fingers crossed."); + gmx_warning( + "GROMACS was compiled with OpenMP support, but there is no thread support in " + "the MPI library. Keep your fingers crossed."); MPI_Init(argc, argv); } -# else +# else MPI_Init(argc, argv); +# endif # endif -#endif } // Bump the counter to record this initialization event g_initializationCounter++; diff --git a/src/gromacs/utility/init.h b/src/gromacs/utility/init.h index 804dd06284..84b0c8d2ed 100644 --- a/src/gromacs/utility/init.h +++ b/src/gromacs/utility/init.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -79,7 +79,7 @@ namespace gmx * * \ingroup module_utility */ -void init(int *argc, char ***argv); +void init(int* argc, char*** argv); /*! \brief * Deinitializes the \Gromacs library. * diff --git a/src/gromacs/utility/inmemoryserializer.cpp b/src/gromacs/utility/inmemoryserializer.cpp index 05955e2bcf..c1adcee5ee 100644 --- a/src/gromacs/utility/inmemoryserializer.cpp +++ b/src/gromacs/utility/inmemoryserializer.cpp @@ -47,36 +47,30 @@ namespace gmx namespace { -template +template class CharBuffer { - public: - static const size_t ValueSize = sizeof(T); - - explicit CharBuffer(T value) - { - u.v = value; - } - explicit CharBuffer(const char buffer[]) - { - std::copy(buffer, buffer + ValueSize, u.c); - } - - T value() const { return u.v; } - - void appendTo(std::vector *buffer) - { - buffer->insert(buffer->end(), u.c, u.c + ValueSize); - } - - private: - union { - char c[ValueSize]; - T v; - } u; +public: + static const size_t ValueSize = sizeof(T); + + explicit CharBuffer(T value) { u.v = value; } + explicit CharBuffer(const char buffer[]) { std::copy(buffer, buffer + ValueSize, u.c); } + + T value() const { return u.v; } + + void appendTo(std::vector* buffer) + { + buffer->insert(buffer->end(), u.c, u.c + ValueSize); + } + +private: + union { + char c[ValueSize]; + T v; + } u; }; -} // namespace +} // namespace /******************************************************************** * InMemorySerializer @@ -84,86 +78,81 @@ class CharBuffer class InMemorySerializer::Impl { - public: - template - void doValue(T value) - { - CharBuffer(value).appendTo(&buffer_); - } - void doString(const std::string &value) - { - doValue(value.size()); - buffer_.insert(buffer_.end(), value.begin(), value.end()); - } - - std::vector buffer_; +public: + template + void doValue(T value) + { + CharBuffer(value).appendTo(&buffer_); + } + void doString(const std::string& value) + { + doValue(value.size()); + buffer_.insert(buffer_.end(), value.begin(), value.end()); + } + + std::vector buffer_; }; -InMemorySerializer::InMemorySerializer() - : impl_(new Impl) -{ -} +InMemorySerializer::InMemorySerializer() : impl_(new Impl) {} -InMemorySerializer::~InMemorySerializer() -{ -} +InMemorySerializer::~InMemorySerializer() {} std::vector InMemorySerializer::finishAndGetBuffer() { return std::move(impl_->buffer_); } -void InMemorySerializer::doBool(bool *value) +void InMemorySerializer::doBool(bool* value) { impl_->doValue(*value); } -void InMemorySerializer::doUChar(unsigned char *value) +void InMemorySerializer::doUChar(unsigned char* value) { impl_->doValue(*value); } -void InMemorySerializer::doChar(char *value) +void InMemorySerializer::doChar(char* value) { impl_->doValue(*value); } -void InMemorySerializer::doUShort(unsigned short *value) +void InMemorySerializer::doUShort(unsigned short* value) { impl_->doValue(*value); } -void InMemorySerializer::doInt(int *value) +void InMemorySerializer::doInt(int* value) { impl_->doValue(*value); } -void InMemorySerializer::doInt32(int32_t *value) +void InMemorySerializer::doInt32(int32_t* value) { impl_->doValue(*value); } -void InMemorySerializer::doInt64(int64_t *value) +void InMemorySerializer::doInt64(int64_t* value) { impl_->doValue(*value); } -void InMemorySerializer::doFloat(float *value) +void InMemorySerializer::doFloat(float* value) { impl_->doValue(*value); } -void InMemorySerializer::doDouble(double *value) +void InMemorySerializer::doDouble(double* value) { impl_->doValue(*value); } -void InMemorySerializer::doReal(real *value) +void InMemorySerializer::doReal(real* value) { impl_->doValue(*value); } -void InMemorySerializer::doRvec(rvec *value) +void InMemorySerializer::doRvec(rvec* value) { for (int d = 0; d < DIM; d++) { @@ -171,7 +160,7 @@ void InMemorySerializer::doRvec(rvec *value) } } -void InMemorySerializer::doIvec(ivec *value) +void InMemorySerializer::doIvec(ivec* value) { for (int d = 0; d < DIM; d++) { @@ -179,7 +168,7 @@ void InMemorySerializer::doIvec(ivec *value) } } -void InMemorySerializer::doString(std::string *value) +void InMemorySerializer::doString(std::string* value) { impl_->doString(*value); } @@ -190,91 +179,91 @@ void InMemorySerializer::doString(std::string *value) class InMemoryDeserializer::Impl { - public: - explicit Impl(ArrayRef buffer, bool sourceIsDouble) - : buffer_(buffer), sourceIsDouble_(sourceIsDouble), pos_(0) - { - } - - template - void doValue(T *value) - { - *value = CharBuffer(&buffer_[pos_]).value(); - pos_ += CharBuffer::ValueSize; - } - void doString(std::string *value) - { - uint64_t size; - doValue(&size); - *value = std::string(&buffer_[pos_], size); - pos_ += size; - } - - ArrayRef buffer_; - bool sourceIsDouble_; - size_t pos_; +public: + explicit Impl(ArrayRef buffer, bool sourceIsDouble) : + buffer_(buffer), + sourceIsDouble_(sourceIsDouble), + pos_(0) + { + } + + template + void doValue(T* value) + { + *value = CharBuffer(&buffer_[pos_]).value(); + pos_ += CharBuffer::ValueSize; + } + void doString(std::string* value) + { + uint64_t size; + doValue(&size); + *value = std::string(&buffer_[pos_], size); + pos_ += size; + } + + ArrayRef buffer_; + bool sourceIsDouble_; + size_t pos_; }; -InMemoryDeserializer::InMemoryDeserializer(ArrayRef buffer, bool sourceIsDouble) - : impl_(new Impl(buffer, sourceIsDouble)) +InMemoryDeserializer::InMemoryDeserializer(ArrayRef buffer, bool sourceIsDouble) : + impl_(new Impl(buffer, sourceIsDouble)) { } -InMemoryDeserializer::~InMemoryDeserializer() -{ -} +InMemoryDeserializer::~InMemoryDeserializer() {} bool InMemoryDeserializer::sourceIsDouble() const { return impl_->sourceIsDouble_; } -void InMemoryDeserializer::doBool(bool *value) +void InMemoryDeserializer::doBool(bool* value) { impl_->doValue(value); } -void InMemoryDeserializer::doUChar(unsigned char *value) +void InMemoryDeserializer::doUChar(unsigned char* value) { impl_->doValue(value); } -void InMemoryDeserializer::doChar(char *value) +void InMemoryDeserializer::doChar(char* value) { impl_->doValue(value); } -void InMemoryDeserializer::doUShort(unsigned short *value) +void InMemoryDeserializer::doUShort(unsigned short* value) { impl_->doValue(value); } -void InMemoryDeserializer::doInt(int *value) +void InMemoryDeserializer::doInt(int* value) { impl_->doValue(value); } -void InMemoryDeserializer::doInt32(int32_t *value) +void InMemoryDeserializer::doInt32(int32_t* value) { impl_->doValue(value); } -void InMemoryDeserializer::doInt64(int64_t *value) +void InMemoryDeserializer::doInt64(int64_t* value) { impl_->doValue(value); } -void InMemoryDeserializer::doFloat(float *value) +void InMemoryDeserializer::doFloat(float* value) { impl_->doValue(value); } -void InMemoryDeserializer::doDouble(double *value) +void InMemoryDeserializer::doDouble(double* value) { impl_->doValue(value); } -void InMemoryDeserializer::doReal(real *value) +void InMemoryDeserializer::doReal(real* value) { if (sourceIsDouble()) { @@ -290,7 +279,7 @@ void InMemoryDeserializer::doReal(real *value) } } -void InMemoryDeserializer::doRvec(rvec *value) +void InMemoryDeserializer::doRvec(rvec* value) { for (int d = 0; d < DIM; d++) { @@ -298,7 +287,7 @@ void InMemoryDeserializer::doRvec(rvec *value) } } -void InMemoryDeserializer::doIvec(ivec *value) +void InMemoryDeserializer::doIvec(ivec* value) { for (int d = 0; d < DIM; d++) { @@ -306,7 +295,7 @@ void InMemoryDeserializer::doIvec(ivec *value) } } -void InMemoryDeserializer::doString(std::string *value) +void InMemoryDeserializer::doString(std::string* value) { impl_->doString(value); } diff --git a/src/gromacs/utility/inmemoryserializer.h b/src/gromacs/utility/inmemoryserializer.h index 6e89b68091..60998c15aa 100644 --- a/src/gromacs/utility/inmemoryserializer.h +++ b/src/gromacs/utility/inmemoryserializer.h @@ -54,63 +54,63 @@ namespace gmx class InMemorySerializer : public ISerializer { - public: - InMemorySerializer(); - ~InMemorySerializer() override; +public: + InMemorySerializer(); + ~InMemorySerializer() override; - std::vector finishAndGetBuffer(); + std::vector finishAndGetBuffer(); - // From ISerializer - bool reading() const override { return false; } - void doBool(bool *value) override; - void doUChar(unsigned char *value) override; - void doChar(char *value) override; - void doUShort(unsigned short *value) override; - void doInt(int *value) override; - void doInt32(int32_t *value) override; - void doInt64(int64_t *value) override; - void doFloat(float *value) override; - void doDouble(double *value) override; - void doReal(real *value) override; - void doIvec(ivec *value) override; - void doRvec(rvec *value) override; - void doString(std::string *value) override; + // From ISerializer + bool reading() const override { return false; } + void doBool(bool* value) override; + void doUChar(unsigned char* value) override; + void doChar(char* value) override; + void doUShort(unsigned short* value) override; + void doInt(int* value) override; + void doInt32(int32_t* value) override; + void doInt64(int64_t* value) override; + void doFloat(float* value) override; + void doDouble(double* value) override; + void doReal(real* value) override; + void doIvec(ivec* value) override; + void doRvec(rvec* value) override; + void doString(std::string* value) override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; class InMemoryDeserializer : public ISerializer { - public: - explicit InMemoryDeserializer(ArrayRef buffer, bool sourceIsDouble); - ~InMemoryDeserializer() override; +public: + explicit InMemoryDeserializer(ArrayRef buffer, bool sourceIsDouble); + ~InMemoryDeserializer() override; - //! Get if the source data was written in double precsion - bool sourceIsDouble() const; + //! Get if the source data was written in double precsion + bool sourceIsDouble() const; - // From ISerializer - bool reading() const override { return true; } - void doBool(bool *value) override; - void doUChar(unsigned char *value) override; - void doChar(char *value) override; - void doUShort(unsigned short *value) override; - void doInt(int *value) override; - void doInt32(int32_t *value) override; - void doInt64(int64_t *value) override; - void doFloat(float *value) override; - void doDouble(double *value) override; - void doReal(real *value) override; - void doIvec(ivec *value) override; - void doRvec(rvec *value) override; - void doString(std::string *value) override; + // From ISerializer + bool reading() const override { return true; } + void doBool(bool* value) override; + void doUChar(unsigned char* value) override; + void doChar(char* value) override; + void doUShort(unsigned short* value) override; + void doInt(int* value) override; + void doInt32(int32_t* value) override; + void doInt64(int64_t* value) override; + void doFloat(float* value) override; + void doDouble(double* value) override; + void doReal(real* value) override; + void doIvec(ivec* value) override; + void doRvec(rvec* value) override; + void doString(std::string* value) override; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/int64_to_int.cpp b/src/gromacs/utility/int64_to_int.cpp index c781b7a85c..0955138e62 100644 --- a/src/gromacs/utility/int64_to_int.cpp +++ b/src/gromacs/utility/int64_to_int.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,7 +40,7 @@ #include "gromacs/utility/basedefinitions.h" -int int64_to_int(int64_t step, const char *warn) +int int64_to_int(int64_t step, const char* warn) { int i; diff --git a/src/gromacs/utility/int64_to_int.h b/src/gromacs/utility/int64_to_int.h index 7c4c7d8e97..17b6e5b1eb 100644 --- a/src/gromacs/utility/int64_to_int.h +++ b/src/gromacs/utility/int64_to_int.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,6 +55,6 @@ * "WARNING during %s:", where warn is printed in %s. * \return the truncated step number. */ -int int64_to_int(int64_t step, const char *warn); +int int64_to_int(int64_t step, const char* warn); #endif diff --git a/src/gromacs/utility/iserializer.h b/src/gromacs/utility/iserializer.h index 63ab9da95d..44ad11e3eb 100644 --- a/src/gromacs/utility/iserializer.h +++ b/src/gromacs/utility/iserializer.h @@ -64,119 +64,118 @@ namespace gmx * conversion. */ class ISerializer { - public: - virtual ~ISerializer() {} - /*! \brief Returns whether the serializer is reading or - * writing, because details like memory management vary - * accordingly. */ - virtual bool reading() const = 0; - //! \brief Serialize values of different types. - ///@{ - virtual void doBool(bool *value) = 0; - virtual void doUChar(unsigned char *value) = 0; - virtual void doChar(char *value) = 0; - virtual void doUShort(unsigned short *value) = 0; - virtual void doInt(int *value) = 0; - virtual void doInt32(int32_t *value) = 0; - virtual void doInt64(int64_t *value) = 0; - virtual void doFloat(float *value) = 0; - virtual void doDouble(double *value) = 0; - virtual void doReal(real *value) = 0; - virtual void doIvec(ivec *value) = 0; - virtual void doRvec(rvec *value) = 0; - virtual void doString(std::string *value) = 0; - ///@} +public: + virtual ~ISerializer() {} + /*! \brief Returns whether the serializer is reading or + * writing, because details like memory management vary + * accordingly. */ + virtual bool reading() const = 0; + //! \brief Serialize values of different types. + ///@{ + virtual void doBool(bool* value) = 0; + virtual void doUChar(unsigned char* value) = 0; + virtual void doChar(char* value) = 0; + virtual void doUShort(unsigned short* value) = 0; + virtual void doInt(int* value) = 0; + virtual void doInt32(int32_t* value) = 0; + virtual void doInt64(int64_t* value) = 0; + virtual void doFloat(float* value) = 0; + virtual void doDouble(double* value) = 0; + virtual void doReal(real* value) = 0; + virtual void doIvec(ivec* value) = 0; + virtual void doRvec(rvec* value) = 0; + virtual void doString(std::string* value) = 0; + ///@} - //! \brief Serialize arrays of values of different types. - ///@{ - void doBoolArray(bool *values, int elements) + //! \brief Serialize arrays of values of different types. + ///@{ + void doBoolArray(bool* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doBool(&(values[i])); - } + doBool(&(values[i])); } - // Char, UChar and RVec have vector specializations that can be - // used instead of the default looping. - virtual void doCharArray(char *values, int elements) + } + // Char, UChar and RVec have vector specializations that can be + // used instead of the default looping. + virtual void doCharArray(char* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doChar(&(values[i])); - } + doChar(&(values[i])); } - virtual void doUCharArray(unsigned char *values, int elements) + } + virtual void doUCharArray(unsigned char* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doUChar(&(values[i])); - } + doUChar(&(values[i])); } - void doUShortArray(unsigned short *values, int elements) + } + void doUShortArray(unsigned short* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doUShort(&(values[i])); - } + doUShort(&(values[i])); } - void doIntArray(int *values, int elements) + } + void doIntArray(int* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doInt(&(values[i])); - } + doInt(&(values[i])); } - void doInt32Array(int32_t *values, int elements) + } + void doInt32Array(int32_t* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doInt32(&(values[i])); - } + doInt32(&(values[i])); } - void doInt64Array(int64_t *values, int elements) + } + void doInt64Array(int64_t* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doInt64(&(values[i])); - } + doInt64(&(values[i])); } - void doFloatArray(float *values, int elements) + } + void doFloatArray(float* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doFloat(&(values[i])); - } + doFloat(&(values[i])); } - void doDoubleArray(double *values, int elements) + } + void doDoubleArray(double* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doDouble(&(values[i])); - } + doDouble(&(values[i])); } - void doRealArray(real *values, int elements) + } + void doRealArray(real* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doReal(&(values[i])); - } + doReal(&(values[i])); } - void doIvecArray(ivec *values, int elements) + } + void doIvecArray(ivec* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doIvec(&(values[i])); - } + doIvec(&(values[i])); } - virtual void doRvecArray(rvec *values, int elements) + } + virtual void doRvecArray(rvec* values, int elements) + { + for (int i = 0; i < elements; i++) { - for (int i = 0; i < elements; i++) - { - doRvec(&(values[i])); - } + doRvec(&(values[i])); } - ///@} - + } + ///@} }; } // namespace gmx diff --git a/src/gromacs/utility/keyvaluetree.cpp b/src/gromacs/utility/keyvaluetree.cpp index d0e3c6b7aa..3d5b32abf0 100644 --- a/src/gromacs/utility/keyvaluetree.cpp +++ b/src/gromacs/utility/keyvaluetree.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,28 +52,21 @@ namespace { //! Helper function to split a KeyValueTreePath to its components -std::vector splitPathElements(const std::string &path) +std::vector splitPathElements(const std::string& path) { - GMX_ASSERT(!path.empty() && path[0] == '/', - "Paths to KeyValueTree should start with '/'"); + GMX_ASSERT(!path.empty() && path[0] == '/', "Paths to KeyValueTree should start with '/'"); return splitDelimitedString(path.substr(1), '/'); } -} // namespace +} // namespace /******************************************************************** * KeyValueTreePath */ -KeyValueTreePath::KeyValueTreePath(const char *path) - : path_(splitPathElements(path)) -{ -} +KeyValueTreePath::KeyValueTreePath(const char* path) : path_(splitPathElements(path)) {} -KeyValueTreePath::KeyValueTreePath(const std::string &path) - : path_(splitPathElements(path)) -{ -} +KeyValueTreePath::KeyValueTreePath(const std::string& path) : path_(splitPathElements(path)) {} std::string KeyValueTreePath::toString() const { @@ -84,14 +77,13 @@ std::string KeyValueTreePath::toString() const * KeyValueTreeObject */ -bool KeyValueTreeObject::hasDistinctProperties(const KeyValueTreeObject &obj) const +bool KeyValueTreeObject::hasDistinctProperties(const KeyValueTreeObject& obj) const { - for (const auto &prop : obj.values_) + for (const auto& prop : obj.values_) { if (keyExists(prop.key())) { - GMX_RELEASE_ASSERT(!prop.value().isArray(), - "Comparison of arrays not implemented"); + GMX_RELEASE_ASSERT(!prop.value().isArray(), "Comparison of arrays not implemented"); if (prop.value().isObject() && valueMap_.at(prop.key()).isObject()) { return valueMap_.at(prop.key()).asObject().hasDistinctProperties(prop.value().asObject()); @@ -107,11 +99,11 @@ bool KeyValueTreeObject::hasDistinctProperties(const KeyValueTreeObject &obj) co */ //! \cond libapi -void dumpKeyValueTree(TextWriter *writer, const KeyValueTreeObject &tree) +void dumpKeyValueTree(TextWriter* writer, const KeyValueTreeObject& tree) { - for (const auto &prop : tree.properties()) + for (const auto& prop : tree.properties()) { - const auto &value = prop.value(); + const auto& value = prop.value(); if (value.isObject()) { writer->writeString(prop.key()); @@ -124,12 +116,12 @@ void dumpKeyValueTree(TextWriter *writer, const KeyValueTreeObject &tree) else { int indent = writer->wrapperSettings().indent(); - writer->writeString(formatString("%*s", -(33-indent), prop.key().c_str())); + writer->writeString(formatString("%*s", -(33 - indent), prop.key().c_str())); writer->writeString(" = "); if (value.isArray()) { writer->writeString("["); - for (const auto &elem : value.asArray().values()) + for (const auto& elem : value.asArray().values()) { GMX_RELEASE_ASSERT(!elem.isObject() && !elem.isArray(), "Arrays of objects not currently implemented"); @@ -157,158 +149,153 @@ namespace class CompareHelper { - public: - CompareHelper(TextWriter *writer, real ftol, real abstol) - : writer_(writer), ftol_(ftol), abstol_(abstol) - { - } +public: + CompareHelper(TextWriter* writer, real ftol, real abstol) : + writer_(writer), + ftol_(ftol), + abstol_(abstol) + { + } - void compareObjects(const KeyValueTreeObject &obj1, - const KeyValueTreeObject &obj2) + void compareObjects(const KeyValueTreeObject& obj1, const KeyValueTreeObject& obj2) + { + for (const auto& prop1 : obj1.properties()) { - for (const auto &prop1 : obj1.properties()) + currentPath_.append(prop1.key()); + if (obj2.keyExists(prop1.key())) { - currentPath_.append(prop1.key()); - if (obj2.keyExists(prop1.key())) - { - compareValues(prop1.value(), obj2[prop1.key()]); - } - else - { - handleMissingKeyInSecondObject(prop1.value()); - } - currentPath_.pop_back(); + compareValues(prop1.value(), obj2[prop1.key()]); } - for (const auto &prop2 : obj2.properties()) + else { - currentPath_.append(prop2.key()); - if (!obj1.keyExists(prop2.key())) - { - handleMissingKeyInFirstObject(prop2.value()); - } - currentPath_.pop_back(); + handleMissingKeyInSecondObject(prop1.value()); } + currentPath_.pop_back(); } - - private: - void compareValues(const KeyValueTreeValue &value1, - const KeyValueTreeValue &value2) + for (const auto& prop2 : obj2.properties()) { - if (value1.type() == value2.type()) + currentPath_.append(prop2.key()); + if (!obj1.keyExists(prop2.key())) { - if (value1.isObject()) - { - compareObjects(value1.asObject(), value2.asObject()); - } - else if (value1.isArray()) - { - GMX_RELEASE_ASSERT(false, "Array comparison not implemented"); - } - else if (!areSimpleValuesOfSameTypeEqual(value1, value2)) - { - writer_->writeString(currentPath_.toString()); - writer_->writeLine(formatString(" (%s - %s)", simpleValueToString(value1).c_str(), simpleValueToString(value2).c_str())); - } - } - else if ((value1.isType() && value2.isType()) - || (value1.isType() && value2.isType())) - { - const bool firstIsDouble - = value1.isType(); - const float v1 = firstIsDouble ? value1.cast() : value1.cast(); - const float v2 = firstIsDouble ? value2.cast() : value2.cast(); - if (!equal_float(v1, v2, ftol_, abstol_)) - { - writer_->writeString(currentPath_.toString()); - writer_->writeLine(formatString(" (%e - %e)", v1, v2)); - } - } - else - { - handleMismatchingTypes(value1, value2); + handleMissingKeyInFirstObject(prop2.value()); } + currentPath_.pop_back(); } + } - bool areSimpleValuesOfSameTypeEqual( - const KeyValueTreeValue &value1, - const KeyValueTreeValue &value2) +private: + void compareValues(const KeyValueTreeValue& value1, const KeyValueTreeValue& value2) + { + if (value1.type() == value2.type()) { - GMX_ASSERT(value1.type() == value2.type(), - "Caller should ensure that types are equal"); - if (value1.isType()) - { - return value1.cast() == value2.cast(); - } - else if (value1.isType()) - { - return value1.cast() == value2.cast(); - } - else if (value1.isType()) - { - return value1.cast() == value2.cast(); - } - else if (value1.isType()) + if (value1.isObject()) { - return equal_double(value1.cast(), value2.cast(), ftol_, abstol_); + compareObjects(value1.asObject(), value2.asObject()); } - else if (value1.isType()) + else if (value1.isArray()) { - return equal_float(value1.cast(), value2.cast(), ftol_, abstol_); + GMX_RELEASE_ASSERT(false, "Array comparison not implemented"); } - else if (value1.isType()) + else if (!areSimpleValuesOfSameTypeEqual(value1, value2)) { - return value1.cast() == value2.cast(); + writer_->writeString(currentPath_.toString()); + writer_->writeLine(formatString(" (%s - %s)", simpleValueToString(value1).c_str(), + simpleValueToString(value2).c_str())); } - else + } + else if ((value1.isType() && value2.isType()) + || (value1.isType() && value2.isType())) + { + const bool firstIsDouble = value1.isType(); + const float v1 = firstIsDouble ? value1.cast() : value1.cast(); + const float v2 = firstIsDouble ? value2.cast() : value2.cast(); + if (!equal_float(v1, v2, ftol_, abstol_)) { - GMX_RELEASE_ASSERT(false, "Unknown value type"); - return false; + writer_->writeString(currentPath_.toString()); + writer_->writeLine(formatString(" (%e - %e)", v1, v2)); } } - - void handleMismatchingTypes(const KeyValueTreeValue & /* value1 */, - const KeyValueTreeValue & /* value2 */) + else { - writer_->writeString(currentPath_.toString()); - writer_->writeString(" type mismatch"); + handleMismatchingTypes(value1, value2); } + } - void handleMissingKeyInFirstObject(const KeyValueTreeValue &value) + bool areSimpleValuesOfSameTypeEqual(const KeyValueTreeValue& value1, const KeyValueTreeValue& value2) + { + GMX_ASSERT(value1.type() == value2.type(), "Caller should ensure that types are equal"); + if (value1.isType()) + { + return value1.cast() == value2.cast(); + } + else if (value1.isType()) + { + return value1.cast() == value2.cast(); + } + else if (value1.isType()) + { + return value1.cast() == value2.cast(); + } + else if (value1.isType()) + { + return equal_double(value1.cast(), value2.cast(), ftol_, abstol_); + } + else if (value1.isType()) { - const std::string message = formatString( - "%s (missing - %s)", currentPath_.toString().c_str(), - formatValueForMissingMessage(value).c_str()); - writer_->writeLine(message); + return equal_float(value1.cast(), value2.cast(), ftol_, abstol_); } - void handleMissingKeyInSecondObject(const KeyValueTreeValue &value) + else if (value1.isType()) { - const std::string message = formatString( - "%s (%s - missing)", currentPath_.toString().c_str(), - formatValueForMissingMessage(value).c_str()); - writer_->writeLine(message); + return value1.cast() == value2.cast(); } + else + { + GMX_RELEASE_ASSERT(false, "Unknown value type"); + return false; + } + } - std::string formatValueForMissingMessage(const KeyValueTreeValue &value) + void handleMismatchingTypes(const KeyValueTreeValue& /* value1 */, + const KeyValueTreeValue& /* value2 */) + { + writer_->writeString(currentPath_.toString()); + writer_->writeString(" type mismatch"); + } + + void handleMissingKeyInFirstObject(const KeyValueTreeValue& value) + { + const std::string message = formatString("%s (missing - %s)", currentPath_.toString().c_str(), + formatValueForMissingMessage(value).c_str()); + writer_->writeLine(message); + } + void handleMissingKeyInSecondObject(const KeyValueTreeValue& value) + { + const std::string message = formatString("%s (%s - missing)", currentPath_.toString().c_str(), + formatValueForMissingMessage(value).c_str()); + writer_->writeLine(message); + } + + std::string formatValueForMissingMessage(const KeyValueTreeValue& value) + { + if (value.isObject() || value.isArray()) { - if (value.isObject() || value.isArray()) - { - return "present"; - } - return simpleValueToString(value); + return "present"; } + return simpleValueToString(value); + } - KeyValueTreePath currentPath_; - TextWriter *writer_; - real ftol_; - real abstol_; + KeyValueTreePath currentPath_; + TextWriter* writer_; + real ftol_; + real abstol_; }; -} // namespace +} // namespace //! \cond libapi -void compareKeyValueTrees(TextWriter *writer, - const KeyValueTreeObject &tree1, - const KeyValueTreeObject &tree2, +void compareKeyValueTrees(TextWriter* writer, + const KeyValueTreeObject& tree1, + const KeyValueTreeObject& tree2, real ftol, real abstol) { diff --git a/src/gromacs/utility/keyvaluetree.h b/src/gromacs/utility/keyvaluetree.h index 0ce225ea75..8d1c85f023 100644 --- a/src/gromacs/utility/keyvaluetree.h +++ b/src/gromacs/utility/keyvaluetree.h @@ -103,52 +103,52 @@ class TextWriter; */ class KeyValueTreePath { - public: - //! Creates an empty path (corresponds to the root object). - KeyValueTreePath() = default; - //! Creates a path from given string representation. - KeyValueTreePath(const char *path); - //! Creates a path from given string representation. - KeyValueTreePath(const std::string &path); - - //! Adds another element to the path, making it a child of the old path. - void append(const std::string &key) { path_.push_back(key); } - //! Adds elements from another path to the path. - void append(const KeyValueTreePath &other) - { - auto elements = other.elements(); - path_.insert(path_.end(), elements.begin(), elements.end()); - } - //! Removes the last element in the path, making it the parent path. - void pop_back() { return path_.pop_back(); } - //! Removes and returns the last element in the path. - std::string pop_last() - { - std::string result = std::move(path_.back()); - path_.pop_back(); - return result; - } - - //! Whether the path is empty (pointing to the root object). - bool empty() const { return path_.empty(); } - //! Returns the number of elements (=nesting level) in the path. - size_t size() const { return path_.size(); } - //! Returns the i'th path element. - const std::string &operator[](int i) const { return path_[i]; } - //! Returns all the path elements. - const std::vector &elements() const { return path_; } - - //! Formats the path as a string for display. - std::string toString() const; - - private: - std::vector path_; +public: + //! Creates an empty path (corresponds to the root object). + KeyValueTreePath() = default; + //! Creates a path from given string representation. + KeyValueTreePath(const char* path); + //! Creates a path from given string representation. + KeyValueTreePath(const std::string& path); + + //! Adds another element to the path, making it a child of the old path. + void append(const std::string& key) { path_.push_back(key); } + //! Adds elements from another path to the path. + void append(const KeyValueTreePath& other) + { + auto elements = other.elements(); + path_.insert(path_.end(), elements.begin(), elements.end()); + } + //! Removes the last element in the path, making it the parent path. + void pop_back() { return path_.pop_back(); } + //! Removes and returns the last element in the path. + std::string pop_last() + { + std::string result = std::move(path_.back()); + path_.pop_back(); + return result; + } + + //! Whether the path is empty (pointing to the root object). + bool empty() const { return path_.empty(); } + //! Returns the number of elements (=nesting level) in the path. + size_t size() const { return path_.size(); } + //! Returns the i'th path element. + const std::string& operator[](int i) const { return path_[i]; } + //! Returns all the path elements. + const std::vector& elements() const { return path_; } + + //! Formats the path as a string for display. + std::string toString() const; + +private: + std::vector path_; }; //! \cond libapi //! Combines two paths as with KeyValueTreePath::append(). -inline KeyValueTreePath operator+(const KeyValueTreePath &a, const KeyValueTreePath &b) +inline KeyValueTreePath operator+(const KeyValueTreePath& a, const KeyValueTreePath& b) { KeyValueTreePath result(a); result.append(b); @@ -156,7 +156,7 @@ inline KeyValueTreePath operator+(const KeyValueTreePath &a, const KeyValueTreeP } //! Combines an element to a path as with KeyValueTreePath::append(). -inline KeyValueTreePath operator+(const KeyValueTreePath &a, const std::string &b) +inline KeyValueTreePath operator+(const KeyValueTreePath& a, const std::string& b) { KeyValueTreePath result(a); result.append(b); @@ -166,132 +166,133 @@ inline KeyValueTreePath operator+(const KeyValueTreePath &a, const std::string & class KeyValueTreeValue { - public: - //! Returns whether the value is an array (KeyValueTreeArray). - bool isArray() const; - //! Returns whether the value is an object (KeyValueTreeObject). - bool isObject() const; - //! Returns whether the value is of a given type. - template - bool isType() const { return value_.isType(); } - //! Returns the type of the value. - std::type_index type() const { return value_.type(); } - - KeyValueTreeArray &asArray(); - KeyValueTreeObject &asObject(); - const KeyValueTreeArray &asArray() const; - const KeyValueTreeObject &asObject() const; - template - const T &cast() const { return value_.cast(); } - - //! Returns the raw Any value (always possible). - const Any &asAny() const { return value_; } - - private: - explicit KeyValueTreeValue(Any &&value) : value_(std::move(value)) {} - - Any value_; - - friend class KeyValueTreeBuilder; - friend class KeyValueTreeObjectBuilder; - friend class KeyValueTreeValueBuilder; +public: + //! Returns whether the value is an array (KeyValueTreeArray). + bool isArray() const; + //! Returns whether the value is an object (KeyValueTreeObject). + bool isObject() const; + //! Returns whether the value is of a given type. + template + bool isType() const + { + return value_.isType(); + } + //! Returns the type of the value. + std::type_index type() const { return value_.type(); } + + KeyValueTreeArray& asArray(); + KeyValueTreeObject& asObject(); + const KeyValueTreeArray& asArray() const; + const KeyValueTreeObject& asObject() const; + template + const T& cast() const + { + return value_.cast(); + } + + //! Returns the raw Any value (always possible). + const Any& asAny() const { return value_; } + +private: + explicit KeyValueTreeValue(Any&& value) : value_(std::move(value)) {} + + Any value_; + + friend class KeyValueTreeBuilder; + friend class KeyValueTreeObjectBuilder; + friend class KeyValueTreeValueBuilder; }; class KeyValueTreeArray { - public: - //! Whether all elements of the array are objects. - bool isObjectArray() const - { - return std::all_of(values_.begin(), values_.end(), - std::mem_fn(&KeyValueTreeValue::isObject)); - } +public: + //! Whether all elements of the array are objects. + bool isObjectArray() const + { + return std::all_of(values_.begin(), values_.end(), std::mem_fn(&KeyValueTreeValue::isObject)); + } - //! Returns the values in the array. - const std::vector &values() const { return values_; } + //! Returns the values in the array. + const std::vector& values() const { return values_; } - private: - std::vector values_; +private: + std::vector values_; - friend class KeyValueTreeArrayBuilderBase; + friend class KeyValueTreeArrayBuilderBase; }; class KeyValueTreeProperty { - public: - const std::string &key() const { return value_->first; } - const KeyValueTreeValue &value() const { return value_->second; } +public: + const std::string& key() const { return value_->first; } + const KeyValueTreeValue& value() const { return value_->second; } - private: - typedef std::map::const_iterator - IteratorType; +private: + typedef std::map::const_iterator IteratorType; - explicit KeyValueTreeProperty(IteratorType value) : value_(value) {} + explicit KeyValueTreeProperty(IteratorType value) : value_(value) {} - IteratorType value_; + IteratorType value_; - friend class KeyValueTreeObject; - friend class KeyValueTreeObjectBuilder; + friend class KeyValueTreeObject; + friend class KeyValueTreeObjectBuilder; }; class KeyValueTreeObject { - public: - KeyValueTreeObject() = default; - //! Creates a deep copy of an object. - KeyValueTreeObject(const KeyValueTreeObject &other) +public: + KeyValueTreeObject() = default; + //! Creates a deep copy of an object. + KeyValueTreeObject(const KeyValueTreeObject& other) + { + for (const auto& value : other.values_) { - for (const auto &value : other.values_) - { - auto iter = valueMap_.insert(std::make_pair(value.key(), value.value())).first; - values_.push_back(KeyValueTreeProperty(iter)); - } + auto iter = valueMap_.insert(std::make_pair(value.key(), value.value())).first; + values_.push_back(KeyValueTreeProperty(iter)); } - //! Assigns a deep copy of an object. - KeyValueTreeObject &operator=(const KeyValueTreeObject &other) - { - KeyValueTreeObject tmp(other); - std::swap(tmp.valueMap_, valueMap_); - std::swap(tmp.values_, values_); - return *this; - } - //! Default move constructor. - //NOLINTNEXTLINE(performance-noexcept-move-constructor) bug #38733 - KeyValueTreeObject(KeyValueTreeObject &&) = default; - //! Default move assignment. - KeyValueTreeObject &operator=(KeyValueTreeObject &&) = default; - - /*! \brief - * Returns all properties in the object. - * - * The properties are in the order they were added to the object. - */ - const std::vector &properties() const { return values_; } - - //! Whether a property with given key exists. - bool keyExists(const std::string &key) const - { - return valueMap_.find(key) != valueMap_.end(); - } - //! Returns value for a given key. - const KeyValueTreeValue &operator[](const std::string &key) const - { - GMX_ASSERT(keyExists(key), "Accessing non-existent value"); - return valueMap_.at(key); - } - - /*! \brief - * Returns whether the given object shares any keys with `this`. - */ - bool hasDistinctProperties(const KeyValueTreeObject &obj) const; - - private: - //! Keeps the properties by key. - std::map valueMap_; - //! Keeps the insertion order of properties. - std::vector values_; - - friend class KeyValueTreeObjectBuilder; + } + //! Assigns a deep copy of an object. + KeyValueTreeObject& operator=(const KeyValueTreeObject& other) + { + KeyValueTreeObject tmp(other); + std::swap(tmp.valueMap_, valueMap_); + std::swap(tmp.values_, values_); + return *this; + } + //! Default move constructor. + //NOLINTNEXTLINE(performance-noexcept-move-constructor) bug #38733 + KeyValueTreeObject(KeyValueTreeObject&&) = default; + //! Default move assignment. + KeyValueTreeObject& operator=(KeyValueTreeObject&&) = default; + + /*! \brief + * Returns all properties in the object. + * + * The properties are in the order they were added to the object. + */ + const std::vector& properties() const { return values_; } + + //! Whether a property with given key exists. + bool keyExists(const std::string& key) const { return valueMap_.find(key) != valueMap_.end(); } + //! Returns value for a given key. + const KeyValueTreeValue& operator[](const std::string& key) const + { + GMX_ASSERT(keyExists(key), "Accessing non-existent value"); + return valueMap_.at(key); + } + + /*! \brief + * Returns whether the given object shares any keys with `this`. + */ + bool hasDistinctProperties(const KeyValueTreeObject& obj) const; + +private: + //! Keeps the properties by key. + std::map valueMap_; + //! Keeps the insertion order of properties. + std::vector values_; + + friend class KeyValueTreeObjectBuilder; }; /******************************************************************** @@ -306,19 +307,19 @@ inline bool KeyValueTreeValue::isObject() const { return value_.isType(); } -inline const KeyValueTreeArray &KeyValueTreeValue::asArray() const +inline const KeyValueTreeArray& KeyValueTreeValue::asArray() const { return value_.cast(); } -inline const KeyValueTreeObject &KeyValueTreeValue::asObject() const +inline const KeyValueTreeObject& KeyValueTreeValue::asObject() const { return value_.cast(); } -inline KeyValueTreeArray &KeyValueTreeValue::asArray() +inline KeyValueTreeArray& KeyValueTreeValue::asArray() { return value_.castRef(); } -inline KeyValueTreeObject &KeyValueTreeValue::asObject() +inline KeyValueTreeObject& KeyValueTreeValue::asObject() { return value_.castRef(); } @@ -333,22 +334,21 @@ inline KeyValueTreeObject &KeyValueTreeValue::asObject() * * \ingroup module_utility */ -void dumpKeyValueTree(TextWriter *writer, const KeyValueTreeObject &tree); +void dumpKeyValueTree(TextWriter* writer, const KeyValueTreeObject& tree); /*! \brief * Compares two KeyValueTrees and prints any differences. * * \ingroup module_utility */ -void compareKeyValueTrees(TextWriter *writer, - const KeyValueTreeObject &tree1, - const KeyValueTreeObject &tree2, +void compareKeyValueTrees(TextWriter* writer, + const KeyValueTreeObject& tree1, + const KeyValueTreeObject& tree2, real ftol, real abstol); //! Helper function to format a simple KeyValueTreeValue. -static inline std::string -simpleValueToString(const KeyValueTreeValue &value) +static inline std::string simpleValueToString(const KeyValueTreeValue& value) { return simpleValueToString(value.asAny()); } diff --git a/src/gromacs/utility/keyvaluetreebuilder.h b/src/gromacs/utility/keyvaluetreebuilder.h index d5c16dce85..6085f399c6 100644 --- a/src/gromacs/utility/keyvaluetreebuilder.h +++ b/src/gromacs/utility/keyvaluetreebuilder.h @@ -74,45 +74,45 @@ class KeyValueTreeObjectBuilder; */ class KeyValueTreeBuilder { - public: - //! Returns a builder for the root object. - KeyValueTreeObjectBuilder rootObject(); - - /*! \brief - * Builds the final object. - * - * The builder should not be accessed after this call. - */ - KeyValueTreeObject build() { return std::move(root_); } - - private: - /*! \brief - * Helper function for other builders to create values of certain type. - */ - template - static KeyValueTreeValue createValue(const T &value) - { - return KeyValueTreeValue(Any::create(value)); - } - /*! \brief - * Helper function for other builders to create default-constructed - * values. - */ - template - static KeyValueTreeValue createValue() - { - return KeyValueTreeValue(Any::create(T())); - } - - KeyValueTreeObject root_; - - //! For access to createValue() methods. - friend class KeyValueTreeObjectArrayBuilder; - //! For access to createValue() methods. - friend class KeyValueTreeObjectBuilder; - //! For access to createValue() methods. - template - friend class KeyValueTreeUniformArrayBuilder; +public: + //! Returns a builder for the root object. + KeyValueTreeObjectBuilder rootObject(); + + /*! \brief + * Builds the final object. + * + * The builder should not be accessed after this call. + */ + KeyValueTreeObject build() { return std::move(root_); } + +private: + /*! \brief + * Helper function for other builders to create values of certain type. + */ + template + static KeyValueTreeValue createValue(const T& value) + { + return KeyValueTreeValue(Any::create(value)); + } + /*! \brief + * Helper function for other builders to create default-constructed + * values. + */ + template + static KeyValueTreeValue createValue() + { + return KeyValueTreeValue(Any::create(T())); + } + + KeyValueTreeObject root_; + + //! For access to createValue() methods. + friend class KeyValueTreeObjectArrayBuilder; + //! For access to createValue() methods. + friend class KeyValueTreeObjectBuilder; + //! For access to createValue() methods. + template + friend class KeyValueTreeUniformArrayBuilder; }; /*! \libinternal \brief @@ -126,85 +126,79 @@ class KeyValueTreeBuilder */ class KeyValueTreeValueBuilder { - public: - //! Assigns a scalar value of certain type. - template - void setValue(const T &value) - { - value_ = Any::create(value); - } - //! Assigns a Any value to the built value. - void setAnyValue(Any &&value) - { - value_ = std::move(value); - } - /*! \brief - * Returns an object builder for building an object into this value. - * - * Any method call in this value builder invalidates the returned - * builder. - */ - KeyValueTreeObjectBuilder createObject(); - /*! \brief - * Returns an array builder for building an array into this value. - * - * Any method call in this value builder invalidates the returned - * builder. - */ - KeyValueTreeArrayBuilder createArray(); - - /*! \brief - * Builds the final value. - * - * The builder should not be accessed after this call. - */ - KeyValueTreeValue build() { return KeyValueTreeValue(std::move(value_)); } - - private: - Any value_; +public: + //! Assigns a scalar value of certain type. + template + void setValue(const T& value) + { + value_ = Any::create(value); + } + //! Assigns a Any value to the built value. + void setAnyValue(Any&& value) { value_ = std::move(value); } + /*! \brief + * Returns an object builder for building an object into this value. + * + * Any method call in this value builder invalidates the returned + * builder. + */ + KeyValueTreeObjectBuilder createObject(); + /*! \brief + * Returns an array builder for building an array into this value. + * + * Any method call in this value builder invalidates the returned + * builder. + */ + KeyValueTreeArrayBuilder createArray(); + + /*! \brief + * Builds the final value. + * + * The builder should not be accessed after this call. + */ + KeyValueTreeValue build() { return KeyValueTreeValue(std::move(value_)); } + +private: + Any value_; }; class KeyValueTreeArrayBuilderBase { - protected: - //! Creates an array builder for populating given array object. - explicit KeyValueTreeArrayBuilderBase(KeyValueTreeArray *array) - : array_(array) - { - } - - //! Appends a raw Any value to the array. - KeyValueTreeValue &addRawValue(Any &&value) - { - KeyValueTreeValueBuilder builder; - builder.setAnyValue(std::move(value)); - array_->values_.push_back(builder.build()); - return array_->values_.back(); - } - //! Appends a raw KeyValueTreeValue to the array. - KeyValueTreeValue &addRawValue(KeyValueTreeValue &&value) - { - array_->values_.push_back(std::move(value)); - return array_->values_.back(); - } - - private: - KeyValueTreeArray *array_; +protected: + //! Creates an array builder for populating given array object. + explicit KeyValueTreeArrayBuilderBase(KeyValueTreeArray* array) : array_(array) {} + + //! Appends a raw Any value to the array. + KeyValueTreeValue& addRawValue(Any&& value) + { + KeyValueTreeValueBuilder builder; + builder.setAnyValue(std::move(value)); + array_->values_.push_back(builder.build()); + return array_->values_.back(); + } + //! Appends a raw KeyValueTreeValue to the array. + KeyValueTreeValue& addRawValue(KeyValueTreeValue&& value) + { + array_->values_.push_back(std::move(value)); + return array_->values_.back(); + } + +private: + KeyValueTreeArray* array_; }; class KeyValueTreeArrayBuilder : public KeyValueTreeArrayBuilderBase { - public: - using KeyValueTreeArrayBuilderBase::addRawValue; +public: + using KeyValueTreeArrayBuilderBase::addRawValue; - private: - explicit KeyValueTreeArrayBuilder(KeyValueTreeArray *array) - : KeyValueTreeArrayBuilderBase(array) - { - } +private: + explicit KeyValueTreeArrayBuilder(KeyValueTreeArray* array) : + KeyValueTreeArrayBuilderBase(array) + { + } - friend class KeyValueTreeObjectBuilder; - friend class KeyValueTreeValueBuilder; + friend class KeyValueTreeObjectBuilder; + friend class KeyValueTreeValueBuilder; }; /*! \libinternal \brief @@ -217,23 +211,20 @@ class KeyValueTreeArrayBuilder : public KeyValueTreeArrayBuilderBase * \inlibraryapi * \ingroup module_utility */ -template +template class KeyValueTreeUniformArrayBuilder : public KeyValueTreeArrayBuilderBase { - public: - //! Appends a value to the array. - void addValue(const T &value) - { - addRawValue(KeyValueTreeBuilder::createValue(value)); - } +public: + //! Appends a value to the array. + void addValue(const T& value) { addRawValue(KeyValueTreeBuilder::createValue(value)); } - private: - explicit KeyValueTreeUniformArrayBuilder(KeyValueTreeArray *array) - : KeyValueTreeArrayBuilderBase(array) - { - } +private: + explicit KeyValueTreeUniformArrayBuilder(KeyValueTreeArray* array) : + KeyValueTreeArrayBuilderBase(array) + { + } - friend class KeyValueTreeObjectBuilder; + friend class KeyValueTreeObjectBuilder; }; /*! \libinternal \brief @@ -249,22 +240,22 @@ class KeyValueTreeUniformArrayBuilder : public KeyValueTreeArrayBuilderBase */ class KeyValueTreeObjectArrayBuilder : public KeyValueTreeArrayBuilderBase { - public: - /*! \brief - * Appends an object to the array. - * - * The object is created empty and can be built using the returned - * builder. - */ - KeyValueTreeObjectBuilder addObject(); - - private: - explicit KeyValueTreeObjectArrayBuilder(KeyValueTreeArray *array) - : KeyValueTreeArrayBuilderBase(array) - { - } - - friend class KeyValueTreeObjectBuilder; +public: + /*! \brief + * Appends an object to the array. + * + * The object is created empty and can be built using the returned + * builder. + */ + KeyValueTreeObjectBuilder addObject(); + +private: + explicit KeyValueTreeObjectArrayBuilder(KeyValueTreeArray* array) : + KeyValueTreeArrayBuilderBase(array) + { + } + + friend class KeyValueTreeObjectBuilder; }; /*! \libinternal \brief @@ -279,153 +270,143 @@ class KeyValueTreeObjectArrayBuilder : public KeyValueTreeArrayBuilderBase */ class KeyValueTreeObjectBuilder { - public: - //! Adds a property with given key from a KeyValueTreeValue. - void addRawValue(const std::string &key, KeyValueTreeValue &&value) +public: + //! Adds a property with given key from a KeyValueTreeValue. + void addRawValue(const std::string& key, KeyValueTreeValue&& value) + { + addProperty(key, std::move(value)); + } + //! Adds a property with given key from a Any value. + void addRawValue(const std::string& key, Any&& value) + { + addProperty(key, KeyValueTreeValue(std::move(value))); + } + //! Adds a scalar property with given key, type, and value. + template + void addValue(const std::string& key, const T& value) + { + addRawValue(key, KeyValueTreeBuilder::createValue(value)); + } + /*! \brief + * Adds an object-valued property with given key. + * + * The object is created empty and can be built using the returned + * builder. + */ + KeyValueTreeObjectBuilder addObject(const std::string& key) + { + auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); + return KeyValueTreeObjectBuilder(&iter->second); + } + /*! \brief + * Adds a generic array-valued property with given key. + * + * The array is created empty and can be built using the returned + * builder. + */ + KeyValueTreeArrayBuilder addArray(const std::string& key) + { + auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); + return KeyValueTreeArrayBuilder(&iter->second.asArray()); + } + /*! \brief + * Adds an array-valued property with uniform value types with given + * key. + * + * \tparam T Type for all values in the array. + * + * The array is created empty and can be built using the returned + * builder. + */ + template + KeyValueTreeUniformArrayBuilder addUniformArray(const std::string& key) + { + auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); + return KeyValueTreeUniformArrayBuilder(&iter->second.asArray()); + } + /*! \brief + * Adds an array-valued property with uniform value types with given + * key and values. + * + * \tparam T Type for all values in the array. + * + * The array is created to contain the values from `values`. + */ + template + void addUniformArray(const std::string& key, std::initializer_list values) + { + auto builder = addUniformArray(key); + for (const auto& value : values) { - addProperty(key, std::move(value)); + builder.addValue(value); } - //! Adds a property with given key from a Any value. - void addRawValue(const std::string &key, Any &&value) + } + /*! \brief + * Adds an array-valued property with objects in the array with given + * key. + * + * The array is created empty and can be built using the returned + * builder. + */ + KeyValueTreeObjectArrayBuilder addObjectArray(const std::string& key) + { + auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); + return KeyValueTreeObjectArrayBuilder(&iter->second.asArray()); + } + + //! Whether a property with given key exists. + bool keyExists(const std::string& key) const { return object_->keyExists(key); } + //! Returns value for a given key. + const KeyValueTreeValue& operator[](const std::string& key) const { return (*object_)[key]; } + //! Returns an object builder for an existing object. + KeyValueTreeObjectBuilder getObjectBuilder(const std::string& key) + { + GMX_ASSERT(keyExists(key), "Requested non-existent value"); + GMX_ASSERT((*this)[key].isObject(), "Accessing non-object value as object"); + return KeyValueTreeObjectBuilder(&object_->valueMap_.at(key).asObject()); + } + + /*! \brief + * Returns whether the given object shares any keys with \p this. + */ + bool objectHasDistinctProperties(const KeyValueTreeObject& obj) const + { + return object_->hasDistinctProperties(obj); + } + /*! \brief + * Merges properties from a given object to `this`. + * + * The objects should not share any keys, i.e., + * objectHasDistinctProperties() should return `true`. + */ + void mergeObject(KeyValueTreeObject&& obj) + { + GMX_ASSERT(objectHasDistinctProperties(obj), "Trying to merge overlapping object"); + for (auto& prop : obj.valueMap_) { - addProperty(key, KeyValueTreeValue(std::move(value))); + addRawValue(prop.first, std::move(prop.second)); } - //! Adds a scalar property with given key, type, and value. - template - void addValue(const std::string &key, const T &value) - { - addRawValue(key, KeyValueTreeBuilder::createValue(value)); - } - /*! \brief - * Adds an object-valued property with given key. - * - * The object is created empty and can be built using the returned - * builder. - */ - KeyValueTreeObjectBuilder addObject(const std::string &key) - { - auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); - return KeyValueTreeObjectBuilder(&iter->second); - } - /*! \brief - * Adds a generic array-valued property with given key. - * - * The array is created empty and can be built using the returned - * builder. - */ - KeyValueTreeArrayBuilder addArray(const std::string &key) - { - auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); - return KeyValueTreeArrayBuilder(&iter->second.asArray()); - } - /*! \brief - * Adds an array-valued property with uniform value types with given - * key. - * - * \tparam T Type for all values in the array. - * - * The array is created empty and can be built using the returned - * builder. - */ - template - KeyValueTreeUniformArrayBuilder addUniformArray(const std::string &key) - { - auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); - return KeyValueTreeUniformArrayBuilder(&iter->second.asArray()); - } - /*! \brief - * Adds an array-valued property with uniform value types with given - * key and values. - * - * \tparam T Type for all values in the array. - * - * The array is created to contain the values from `values`. - */ - template - void addUniformArray(const std::string &key, std::initializer_list values) - { - auto builder = addUniformArray(key); - for (const auto &value : values) - { - builder.addValue(value); - } - } - /*! \brief - * Adds an array-valued property with objects in the array with given - * key. - * - * The array is created empty and can be built using the returned - * builder. - */ - KeyValueTreeObjectArrayBuilder addObjectArray(const std::string &key) - { - auto iter = addProperty(key, KeyValueTreeBuilder::createValue()); - return KeyValueTreeObjectArrayBuilder(&iter->second.asArray()); - } - - //! Whether a property with given key exists. - bool keyExists(const std::string &key) const { return object_->keyExists(key); } - //! Returns value for a given key. - const KeyValueTreeValue &operator[](const std::string &key) const - { - return (*object_)[key]; - } - //! Returns an object builder for an existing object. - KeyValueTreeObjectBuilder getObjectBuilder(const std::string &key) - { - GMX_ASSERT(keyExists(key), "Requested non-existent value"); - GMX_ASSERT((*this)[key].isObject(), "Accessing non-object value as object"); - return KeyValueTreeObjectBuilder(&object_->valueMap_.at(key).asObject()); - } - - /*! \brief - * Returns whether the given object shares any keys with \p this. - */ - bool objectHasDistinctProperties(const KeyValueTreeObject &obj) const - { - return object_->hasDistinctProperties(obj); - } - /*! \brief - * Merges properties from a given object to `this`. - * - * The objects should not share any keys, i.e., - * objectHasDistinctProperties() should return `true`. - */ - void mergeObject(KeyValueTreeObject &&obj) - { - GMX_ASSERT(objectHasDistinctProperties(obj), - "Trying to merge overlapping object"); - for (auto &prop : obj.valueMap_) - { - addRawValue(prop.first, std::move(prop.second)); - } - } - - private: - explicit KeyValueTreeObjectBuilder(KeyValueTreeObject *object) - : object_(object) - { - } - explicit KeyValueTreeObjectBuilder(KeyValueTreeValue *value) - : object_(&value->asObject()) - { - } - - std::map::iterator - addProperty(const std::string &key, KeyValueTreeValue &&value) - { - GMX_RELEASE_ASSERT(!keyExists(key), "Duplicate key value"); - object_->values_.reserve(object_->values_.size() + 1); - auto iter = object_->valueMap_.insert(std::make_pair(key, std::move(value))).first; - object_->values_.push_back(KeyValueTreeProperty(iter)); - return iter; - } - - KeyValueTreeObject *object_; - - friend class KeyValueTreeBuilder; - friend class KeyValueTreeValueBuilder; - friend class KeyValueTreeObjectArrayBuilder; + } + +private: + explicit KeyValueTreeObjectBuilder(KeyValueTreeObject* object) : object_(object) {} + explicit KeyValueTreeObjectBuilder(KeyValueTreeValue* value) : object_(&value->asObject()) {} + + std::map::iterator addProperty(const std::string& key, + KeyValueTreeValue&& value) + { + GMX_RELEASE_ASSERT(!keyExists(key), "Duplicate key value"); + object_->values_.reserve(object_->values_.size() + 1); + auto iter = object_->valueMap_.insert(std::make_pair(key, std::move(value))).first; + object_->values_.push_back(KeyValueTreeProperty(iter)); + return iter; + } + + KeyValueTreeObject* object_; + + friend class KeyValueTreeBuilder; + friend class KeyValueTreeValueBuilder; + friend class KeyValueTreeObjectArrayBuilder; }; /******************************************************************** @@ -451,7 +432,7 @@ inline KeyValueTreeArrayBuilder KeyValueTreeValueBuilder::createArray() inline KeyValueTreeObjectBuilder KeyValueTreeObjectArrayBuilder::addObject() { - auto &value = addRawValue(KeyValueTreeBuilder::createValue()); + auto& value = addRawValue(KeyValueTreeBuilder::createValue()); return KeyValueTreeObjectBuilder(&value); } diff --git a/src/gromacs/utility/keyvaluetreemdpwriter.cpp b/src/gromacs/utility/keyvaluetreemdpwriter.cpp index 1c69979fee..bbe0dd43e8 100644 --- a/src/gromacs/utility/keyvaluetreemdpwriter.cpp +++ b/src/gromacs/utility/keyvaluetreemdpwriter.cpp @@ -55,12 +55,11 @@ namespace gmx { -void writeKeyValueTreeAsMdp(TextWriter *writer, - const KeyValueTreeObject &tree) +void writeKeyValueTreeAsMdp(TextWriter* writer, const KeyValueTreeObject& tree) { - for (const auto &prop : tree.properties()) + for (const auto& prop : tree.properties()) { - const auto &value = prop.value(); + const auto& value = prop.value(); GMX_RELEASE_ASSERT(!value.isObject(), "Only flat key-value trees can be written as mdp"); // Recognize a special key prefix that identifies comment @@ -69,7 +68,8 @@ void writeKeyValueTreeAsMdp(TextWriter *writer, // comments will need different handling then. if (prop.key().compare(0, 7, "comment") == 0) { - GMX_RELEASE_ASSERT(prop.value().isType(), "Comments must have string-typed values"); + GMX_RELEASE_ASSERT(prop.value().isType(), + "Comments must have string-typed values"); auto comment = prop.value().cast(); // TODO Consider implementing an MdpTextWriter that can // format an array of strings suitably, e.g. by prefixing @@ -86,7 +86,7 @@ void writeKeyValueTreeAsMdp(TextWriter *writer, if (value.isArray()) { bool first = true; - for (const auto &elem : value.asArray().values()) + for (const auto& elem : value.asArray().values()) { GMX_RELEASE_ASSERT(!elem.isObject() && !elem.isArray(), "Arrays of objects not currently implemented"); diff --git a/src/gromacs/utility/keyvaluetreemdpwriter.h b/src/gromacs/utility/keyvaluetreemdpwriter.h index a370cdeca9..60c8d64971 100644 --- a/src/gromacs/utility/keyvaluetreemdpwriter.h +++ b/src/gromacs/utility/keyvaluetreemdpwriter.h @@ -57,8 +57,7 @@ class TextWriter; * well as the normal key and value. The comment pair will * have a key of "comment", and the value will be used as a * comment (if non-empty). */ -void writeKeyValueTreeAsMdp(TextWriter *writer, - const KeyValueTreeObject &tree); +void writeKeyValueTreeAsMdp(TextWriter* writer, const KeyValueTreeObject& tree); } // namespace gmx diff --git a/src/gromacs/utility/keyvaluetreeserializer.cpp b/src/gromacs/utility/keyvaluetreeserializer.cpp index 2462857a2c..14510239cf 100644 --- a/src/gromacs/utility/keyvaluetreeserializer.cpp +++ b/src/gromacs/utility/keyvaluetreeserializer.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,58 +49,58 @@ namespace class ValueSerializer { - public: - static void initSerializers(); +public: + static void initSerializers(); - static void serialize(const KeyValueTreeValue &value, ISerializer *serializer); - static KeyValueTreeValue deserialize(ISerializer *serializer); + static void serialize(const KeyValueTreeValue& value, ISerializer* serializer); + static KeyValueTreeValue deserialize(ISerializer* serializer); - private: - ValueSerializer() = delete; +private: + ValueSerializer() = delete; - typedef void (*SerializerFunction)(const KeyValueTreeValue &value, ISerializer *serializer); - typedef void (*DeserializerFunction)(KeyValueTreeValueBuilder *builder, ISerializer *serializer); + typedef void (*SerializerFunction)(const KeyValueTreeValue& value, ISerializer* serializer); + typedef void (*DeserializerFunction)(KeyValueTreeValueBuilder* builder, ISerializer* serializer); - struct Serializer - { - unsigned char typeTag; - SerializerFunction serialize; - DeserializerFunction deserialize; - }; + struct Serializer + { + unsigned char typeTag; + SerializerFunction serialize; + DeserializerFunction deserialize; + }; - static Mutex s_initMutex; - static std::map s_serializers; - static std::map s_deserializers; + static Mutex s_initMutex; + static std::map s_serializers; + static std::map s_deserializers; }; Mutex ValueSerializer::s_initMutex; std::map ValueSerializer::s_serializers; std::map ValueSerializer::s_deserializers; -template +template struct SerializationTraits { }; -template <> +template<> struct SerializationTraits { - static void serialize(const KeyValueTreeObject &value, ISerializer *serializer) + static void serialize(const KeyValueTreeObject& value, ISerializer* serializer) { - int count = value.properties().size(); + int count = value.properties().size(); serializer->doInt(&count); - for (const auto &prop : value.properties()) + for (const auto& prop : value.properties()) { - serializer->doString(const_cast(&prop.key())); + serializer->doString(const_cast(&prop.key())); ValueSerializer::serialize(prop.value(), serializer); } } - static void deserialize(KeyValueTreeValueBuilder *value, ISerializer *serializer) + static void deserialize(KeyValueTreeValueBuilder* value, ISerializer* serializer) { KeyValueTreeObjectBuilder builder(value->createObject()); deserializeObject(&builder, serializer); } - static void deserializeObject(KeyValueTreeObjectBuilder *builder, ISerializer *serializer) + static void deserializeObject(KeyValueTreeObjectBuilder* builder, ISerializer* serializer) { int count; std::string key; @@ -113,19 +113,19 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(const KeyValueTreeArray &array, ISerializer *serializer) + static void serialize(const KeyValueTreeArray& array, ISerializer* serializer) { - int count = array.values().size(); + int count = array.values().size(); serializer->doInt(&count); - for (const auto &value : array.values()) + for (const auto& value : array.values()) { ValueSerializer::serialize(value, serializer); } } - static void deserialize(KeyValueTreeValueBuilder *value, ISerializer *serializer) + static void deserialize(KeyValueTreeValueBuilder* value, ISerializer* serializer) { KeyValueTreeArrayBuilder builder(value->createArray()); int count; @@ -137,14 +137,14 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(const std::string &value, ISerializer *serializer) + static void serialize(const std::string& value, ISerializer* serializer) { - serializer->doString(const_cast(&value)); + serializer->doString(const_cast(&value)); } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { std::string value; serializer->doString(&value); @@ -152,14 +152,11 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(bool value, ISerializer *serializer) - { - serializer->doBool(&value); - } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void serialize(bool value, ISerializer* serializer) { serializer->doBool(&value); } + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { bool value; serializer->doBool(&value); @@ -167,14 +164,11 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(int value, ISerializer *serializer) - { - serializer->doInt(&value); - } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void serialize(int value, ISerializer* serializer) { serializer->doInt(&value); } + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { int value; serializer->doInt(&value); @@ -182,14 +176,11 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(int64_t value, ISerializer *serializer) - { - serializer->doInt64(&value); - } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void serialize(int64_t value, ISerializer* serializer) { serializer->doInt64(&value); } + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { int64_t value; serializer->doInt64(&value); @@ -197,14 +188,11 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(float value, ISerializer *serializer) - { - serializer->doFloat(&value); - } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void serialize(float value, ISerializer* serializer) { serializer->doFloat(&value); } + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { float value; serializer->doFloat(&value); @@ -212,14 +200,11 @@ struct SerializationTraits } }; -template <> +template<> struct SerializationTraits { - static void serialize(double value, ISerializer *serializer) - { - serializer->doDouble(&value); - } - static void deserialize(KeyValueTreeValueBuilder *builder, ISerializer *serializer) + static void serialize(double value, ISerializer* serializer) { serializer->doDouble(&value); } + static void deserialize(KeyValueTreeValueBuilder* builder, ISerializer* serializer) { double value; serializer->doDouble(&value); @@ -228,15 +213,18 @@ struct SerializationTraits }; //! Helper function for serializing values of a certain type. -template -void serializeValueType(const KeyValueTreeValue &value, ISerializer *serializer) +template +void serializeValueType(const KeyValueTreeValue& value, ISerializer* serializer) { SerializationTraits::serialize(value.cast(), serializer); } -#define SERIALIZER(tag, type) \ - { std::type_index(typeid(type)), \ - { tag, &serializeValueType, &SerializationTraits::deserialize } \ +#define SERIALIZER(tag, type) \ + { \ + std::type_index(typeid(type)), \ + { \ + tag, &serializeValueType, &SerializationTraits::deserialize \ + } \ } // static @@ -257,49 +245,45 @@ void ValueSerializer::initSerializers() SERIALIZER('f', float), SERIALIZER('d', double), }; - for (const auto &item : s_serializers) + for (const auto& item : s_serializers) { s_deserializers[item.second.typeTag] = item.second.deserialize; } } -void ValueSerializer::serialize(const KeyValueTreeValue &value, ISerializer *serializer) +void ValueSerializer::serialize(const KeyValueTreeValue& value, ISerializer* serializer) { auto iter = s_serializers.find(value.type()); - GMX_RELEASE_ASSERT(iter != s_serializers.end(), - "Unknown value type for serializization"); + GMX_RELEASE_ASSERT(iter != s_serializers.end(), "Unknown value type for serializization"); unsigned char typeTag = iter->second.typeTag; serializer->doUChar(&typeTag); iter->second.serialize(value, serializer); } -KeyValueTreeValue ValueSerializer::deserialize(ISerializer *serializer) +KeyValueTreeValue ValueSerializer::deserialize(ISerializer* serializer) { unsigned char typeTag; serializer->doUChar(&typeTag); - auto iter = s_deserializers.find(typeTag); - GMX_RELEASE_ASSERT(iter != s_deserializers.end(), - "Unknown type tag for deserializization"); + auto iter = s_deserializers.find(typeTag); + GMX_RELEASE_ASSERT(iter != s_deserializers.end(), "Unknown type tag for deserializization"); KeyValueTreeValueBuilder builder; iter->second(&builder, serializer); return builder.build(); } -} // namespace +} // namespace //! \cond libapi -void serializeKeyValueTree(const KeyValueTreeObject &root, ISerializer *serializer) +void serializeKeyValueTree(const KeyValueTreeObject& root, ISerializer* serializer) { - GMX_RELEASE_ASSERT(!serializer->reading(), - "Incorrect serializer direction"); + GMX_RELEASE_ASSERT(!serializer->reading(), "Incorrect serializer direction"); ValueSerializer::initSerializers(); SerializationTraits::serialize(root, serializer); } -KeyValueTreeObject deserializeKeyValueTree(ISerializer *serializer) +KeyValueTreeObject deserializeKeyValueTree(ISerializer* serializer) { - GMX_RELEASE_ASSERT(serializer->reading(), - "Incorrect serializer direction"); + GMX_RELEASE_ASSERT(serializer->reading(), "Incorrect serializer direction"); ValueSerializer::initSerializers(); KeyValueTreeBuilder builder; KeyValueTreeObjectBuilder obj(builder.rootObject()); diff --git a/src/gromacs/utility/keyvaluetreeserializer.h b/src/gromacs/utility/keyvaluetreeserializer.h index 0cbbb2cc7f..28a91d1124 100644 --- a/src/gromacs/utility/keyvaluetreeserializer.h +++ b/src/gromacs/utility/keyvaluetreeserializer.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,13 +55,13 @@ class ISerializer; * * \ingroup module_utility */ -void serializeKeyValueTree(const KeyValueTreeObject &root, ISerializer *serializer); +void serializeKeyValueTree(const KeyValueTreeObject& root, ISerializer* serializer); /*! \brief * Deserializes a KeyValueTreeObject from a given serializer. * * \ingroup module_utility */ -KeyValueTreeObject deserializeKeyValueTree(ISerializer *serializer); +KeyValueTreeObject deserializeKeyValueTree(ISerializer* serializer); //! \endcond } // namespace gmx diff --git a/src/gromacs/utility/keyvaluetreetransform.cpp b/src/gromacs/utility/keyvaluetreetransform.cpp index 343143dd0d..f1481d8160 100644 --- a/src/gromacs/utility/keyvaluetreetransform.cpp +++ b/src/gromacs/utility/keyvaluetreetransform.cpp @@ -55,9 +55,7 @@ namespace gmx * IKeyValueTreeTransformRules */ -IKeyValueTreeTransformRules::~IKeyValueTreeTransformRules() -{ -} +IKeyValueTreeTransformRules::~IKeyValueTreeTransformRules() {} /******************************************************************** * KeyValueTreeTransformRulesScoped::Impl @@ -65,50 +63,46 @@ IKeyValueTreeTransformRules::~IKeyValueTreeTransformRules() class KeyValueTreeTransformRulesScoped::Impl : public IKeyValueTreeTransformRules { - public: - Impl(internal::KeyValueTreeTransformerImpl *impl, const KeyValueTreePath &prefix) - : impl_(impl), prefix_(prefix) - { - } +public: + Impl(internal::KeyValueTreeTransformerImpl* impl, const KeyValueTreePath& prefix) : + impl_(impl), + prefix_(prefix) + { + } - KeyValueTreeTransformRuleBuilder addRule() override - { - return KeyValueTreeTransformRuleBuilder(impl_, prefix_); - } + KeyValueTreeTransformRuleBuilder addRule() override + { + return KeyValueTreeTransformRuleBuilder(impl_, prefix_); + } - KeyValueTreeTransformRulesScoped - scopedTransform(const KeyValueTreePath &scope) override - { - return KeyValueTreeTransformRulesScoped(impl_, prefix_ + scope); - } + KeyValueTreeTransformRulesScoped scopedTransform(const KeyValueTreePath& scope) override + { + return KeyValueTreeTransformRulesScoped(impl_, prefix_ + scope); + } - private: - internal::KeyValueTreeTransformerImpl *impl_; - KeyValueTreePath prefix_; +private: + internal::KeyValueTreeTransformerImpl* impl_; + KeyValueTreePath prefix_; }; /******************************************************************** * KeyValueTreeTransformRulesScoped */ -KeyValueTreeTransformRulesScoped::KeyValueTreeTransformRulesScoped( - internal::KeyValueTreeTransformerImpl *impl, const KeyValueTreePath &prefix) - : impl_(new Impl(impl, prefix)) +KeyValueTreeTransformRulesScoped::KeyValueTreeTransformRulesScoped(internal::KeyValueTreeTransformerImpl* impl, + const KeyValueTreePath& prefix) : + impl_(new Impl(impl, prefix)) { } -KeyValueTreeTransformRulesScoped::KeyValueTreeTransformRulesScoped( - KeyValueTreeTransformRulesScoped &&) noexcept = default; +KeyValueTreeTransformRulesScoped::KeyValueTreeTransformRulesScoped(KeyValueTreeTransformRulesScoped&&) noexcept = default; -KeyValueTreeTransformRulesScoped & -KeyValueTreeTransformRulesScoped::operator=( - KeyValueTreeTransformRulesScoped &&) noexcept = default; +KeyValueTreeTransformRulesScoped& KeyValueTreeTransformRulesScoped:: + operator=(KeyValueTreeTransformRulesScoped&&) noexcept = default; -KeyValueTreeTransformRulesScoped::~KeyValueTreeTransformRulesScoped() -{ -} +KeyValueTreeTransformRulesScoped::~KeyValueTreeTransformRulesScoped() {} -IKeyValueTreeTransformRules *KeyValueTreeTransformRulesScoped::rules() +IKeyValueTreeTransformRules* KeyValueTreeTransformRulesScoped::rules() { return impl_.get(); } @@ -117,82 +111,75 @@ IKeyValueTreeTransformRules *KeyValueTreeTransformRulesScoped::rules() * IKeyValueTreeBackMapping */ -IKeyValueTreeBackMapping::~IKeyValueTreeBackMapping() -{ -} +IKeyValueTreeBackMapping::~IKeyValueTreeBackMapping() {} namespace { class KeyValueTreeBackMapping : public IKeyValueTreeBackMapping { +public: + class Entry + { public: - class Entry - { - public: - Entry() = default; - explicit Entry(const KeyValueTreePath &path) : sourcePath_(path) {} + Entry() = default; + explicit Entry(const KeyValueTreePath& path) : sourcePath_(path) {} - Entry *getOrCreateChildEntry(const std::string &key) - { - auto iter = childEntries_.find(key); - if (iter == childEntries_.end()) - { - iter = childEntries_.insert(std::make_pair(key, Entry())).first; - } - return &iter->second; - } - void setMapping(const KeyValueTreePath &path, - const KeyValueTreeValue &value) + Entry* getOrCreateChildEntry(const std::string& key) + { + auto iter = childEntries_.find(key); + if (iter == childEntries_.end()) + { + iter = childEntries_.insert(std::make_pair(key, Entry())).first; + } + return &iter->second; + } + void setMapping(const KeyValueTreePath& path, const KeyValueTreeValue& value) + { + GMX_RELEASE_ASSERT(sourcePath_.empty(), "Multiple entries map to same path"); + if (value.isObject()) + { + const KeyValueTreeObject& object = value.asObject(); + for (const auto& prop : object.properties()) { - GMX_RELEASE_ASSERT(sourcePath_.empty(), - "Multiple entries map to same path"); - if (value.isObject()) - { - const KeyValueTreeObject &object = value.asObject(); - for (const auto &prop : object.properties()) - { - GMX_RELEASE_ASSERT(!prop.value().isObject(), - "Nested objects not implemented"); - childEntries_[prop.key()] = Entry(path); - } - } - else - { - sourcePath_ = path; - } + GMX_RELEASE_ASSERT(!prop.value().isObject(), "Nested objects not implemented"); + childEntries_[prop.key()] = Entry(path); } + } + else + { + sourcePath_ = path; + } + } - KeyValueTreePath sourcePath_; - std::map childEntries_; - }; + KeyValueTreePath sourcePath_; + std::map childEntries_; + }; - KeyValueTreePath - originalPath(const KeyValueTreePath &path) const override + KeyValueTreePath originalPath(const KeyValueTreePath& path) const override + { + const Entry* entry = &rootEntry_; + for (const auto& element : path.elements()) { - const Entry *entry = &rootEntry_; - for (const auto &element : path.elements()) + auto iter = entry->childEntries_.find(element); + if (iter == entry->childEntries_.end()) { - auto iter = entry->childEntries_.find(element); - if (iter == entry->childEntries_.end()) - { - break; - } - entry = &iter->second; + break; } - GMX_RELEASE_ASSERT(entry->childEntries_.empty() - && !entry->sourcePath_.empty(), - "Requested path not uniquely mapped"); - return entry->sourcePath_; + entry = &iter->second; } + GMX_RELEASE_ASSERT(entry->childEntries_.empty() && !entry->sourcePath_.empty(), + "Requested path not uniquely mapped"); + return entry->sourcePath_; + } - Entry *rootEntry() { return &rootEntry_; } + Entry* rootEntry() { return &rootEntry_; } - private: - Entry rootEntry_; +private: + Entry rootEntry_; }; -} // namespace +} // namespace namespace internal { @@ -203,140 +190,131 @@ namespace internal class KeyValueTreeTransformerImpl { +public: + class Rule + { public: - class Rule - { - public: - typedef std::function - TransformFunction; - typedef std::map ChildRuleMap; - - explicit Rule(StringCompareType keyMatchType) - : expectedType_(typeid(void)), childRules_(keyMatchType) - { - } + typedef std::function TransformFunction; + typedef std::map ChildRuleMap; - const Rule *findMatchingChildRule(const std::string &key) const - { - auto iter = childRules_.find(key); - if (iter == childRules_.end()) - { - return nullptr; - } - return &iter->second; - } - Rule *getOrCreateChildRule(const std::string &key) - { - auto iter = childRules_.find(key); - if (iter == childRules_.end()) - { - return createChildRule(key, StringCompareType::Exact); - } - return &iter->second; - } - Rule *createChildRule(const std::string &key, - StringCompareType keyMatchType) - { - auto result = childRules_.insert(std::make_pair(key, Rule(keyMatchType))); - GMX_RELEASE_ASSERT(result.second, - "Cannot specify key match type after child rules"); - return &result.first->second; - } - - void collectMappedPaths(const KeyValueTreePath &prefix, - std::vector *result) const - { - for (const auto &value : childRules_) - { - KeyValueTreePath path = prefix; - path.append(value.first); - const Rule &rule = value.second; - if (rule.transform_) - { - result->push_back(path); - } - else - { - rule.collectMappedPaths(path, result); - } - } - } - - KeyValueTreePath targetPath_; - std::string targetKey_; - std::type_index expectedType_; - TransformFunction transform_; - ChildRuleMap childRules_; - }; + explicit Rule(StringCompareType keyMatchType) : + expectedType_(typeid(void)), + childRules_(keyMatchType) + { + } - class Transformer + const Rule* findMatchingChildRule(const std::string& key) const { - public: - explicit Transformer(IKeyValueTreeErrorHandler *errorHandler) - : errorHandler_(errorHandler), - backMapping_(new KeyValueTreeBackMapping) - { - if (errorHandler_ == nullptr) - { - errorHandler_ = defaultKeyValueTreeErrorHandler(); - } - } + auto iter = childRules_.find(key); + if (iter == childRules_.end()) + { + return nullptr; + } + return &iter->second; + } + Rule* getOrCreateChildRule(const std::string& key) + { + auto iter = childRules_.find(key); + if (iter == childRules_.end()) + { + return createChildRule(key, StringCompareType::Exact); + } + return &iter->second; + } + Rule* createChildRule(const std::string& key, StringCompareType keyMatchType) + { + auto result = childRules_.insert(std::make_pair(key, Rule(keyMatchType))); + GMX_RELEASE_ASSERT(result.second, "Cannot specify key match type after child rules"); + return &result.first->second; + } - void transform(const Rule *rootRule, const KeyValueTreeObject &tree) + void collectMappedPaths(const KeyValueTreePath& prefix, std::vector* result) const + { + for (const auto& value : childRules_) + { + KeyValueTreePath path = prefix; + path.append(value.first); + const Rule& rule = value.second; + if (rule.transform_) { - if (rootRule != nullptr) - { - doChildTransforms(rootRule, tree); - } + result->push_back(path); } - - KeyValueTreeTransformResult result() + else { - return KeyValueTreeTransformResult(builder_.build(), - std::move(backMapping_)); + rule.collectMappedPaths(path, result); } + } + } - private: - void doTransform(const Rule *rule, const KeyValueTreeValue &value); - void doChildTransforms(const Rule *rule, const KeyValueTreeObject &object); - void applyTransformedValue(const Rule *rule, KeyValueTreeValue &&value); - - IKeyValueTreeErrorHandler *errorHandler_; - KeyValueTreeBuilder builder_; - std::unique_ptr backMapping_; - KeyValueTreePath context_; - }; + KeyValueTreePath targetPath_; + std::string targetKey_; + std::type_index expectedType_; + TransformFunction transform_; + ChildRuleMap childRules_; + }; - KeyValueTreeTransformerImpl() - : rootScope_(this, KeyValueTreePath()) + class Transformer + { + public: + explicit Transformer(IKeyValueTreeErrorHandler* errorHandler) : + errorHandler_(errorHandler), + backMapping_(new KeyValueTreeBackMapping) { + if (errorHandler_ == nullptr) + { + errorHandler_ = defaultKeyValueTreeErrorHandler(); + } } - Rule *getOrCreateRootRule() + void transform(const Rule* rootRule, const KeyValueTreeObject& tree) { - if (rootRule_ == nullptr) + if (rootRule != nullptr) { - createRootRule(StringCompareType::Exact); + doChildTransforms(rootRule, tree); } - return rootRule_.get(); } - void createRootRule(StringCompareType keyMatchType) + + KeyValueTreeTransformResult result() + { + return KeyValueTreeTransformResult(builder_.build(), std::move(backMapping_)); + } + + private: + void doTransform(const Rule* rule, const KeyValueTreeValue& value); + void doChildTransforms(const Rule* rule, const KeyValueTreeObject& object); + void applyTransformedValue(const Rule* rule, KeyValueTreeValue&& value); + + IKeyValueTreeErrorHandler* errorHandler_; + KeyValueTreeBuilder builder_; + std::unique_ptr backMapping_; + KeyValueTreePath context_; + }; + + KeyValueTreeTransformerImpl() : rootScope_(this, KeyValueTreePath()) {} + + Rule* getOrCreateRootRule() + { + if (rootRule_ == nullptr) { - GMX_RELEASE_ASSERT(rootRule_ == nullptr, - "Cannot specify key match type after child rules"); - rootRule_ = std::make_unique(keyMatchType); + createRootRule(StringCompareType::Exact); } + return rootRule_.get(); + } + void createRootRule(StringCompareType keyMatchType) + { + GMX_RELEASE_ASSERT(rootRule_ == nullptr, "Cannot specify key match type after child rules"); + rootRule_ = std::make_unique(keyMatchType); + } - std::unique_ptr rootRule_; - KeyValueTreeTransformRulesScoped rootScope_; + std::unique_ptr rootRule_; + KeyValueTreeTransformRulesScoped rootScope_; }; /******************************************************************** * KeyValueTreeTransformerImpl::Transformer */ -void KeyValueTreeTransformerImpl::Transformer::doTransform( - const Rule *rule, const KeyValueTreeValue &value) +void KeyValueTreeTransformerImpl::Transformer::doTransform(const Rule* rule, const KeyValueTreeValue& value) { if (rule->transform_ != nullptr) { @@ -350,7 +328,7 @@ void KeyValueTreeTransformerImpl::Transformer::doTransform( } rule->transform_(&valueBuilder, value); } - catch (UserInputError &ex) + catch (UserInputError& ex) { if (!errorHandler_->onError(&ex, context_)) { @@ -367,12 +345,12 @@ void KeyValueTreeTransformerImpl::Transformer::doTransform( } } -void KeyValueTreeTransformerImpl::Transformer::doChildTransforms( - const Rule *rule, const KeyValueTreeObject &object) +void KeyValueTreeTransformerImpl::Transformer::doChildTransforms(const Rule* rule, + const KeyValueTreeObject& object) { - for (const auto &prop : object.properties()) + for (const auto& prop : object.properties()) { - const Rule *childRule = rule->findMatchingChildRule(prop.key()); + const Rule* childRule = rule->findMatchingChildRule(prop.key()); if (childRule != nullptr) { context_.append(prop.key()); @@ -382,12 +360,12 @@ void KeyValueTreeTransformerImpl::Transformer::doChildTransforms( } } -void KeyValueTreeTransformerImpl::Transformer::applyTransformedValue( - const Rule *rule, KeyValueTreeValue &&value) +void KeyValueTreeTransformerImpl::Transformer::applyTransformedValue(const Rule* rule, + KeyValueTreeValue&& value) { KeyValueTreeObjectBuilder objBuilder = builder_.rootObject(); - KeyValueTreeBackMapping::Entry *mapEntry = backMapping_->rootEntry(); - for (const std::string &key : rule->targetPath_.elements()) + KeyValueTreeBackMapping::Entry* mapEntry = backMapping_->rootEntry(); + for (const std::string& key : rule->targetPath_.elements()) { if (objBuilder.keyExists(key)) { @@ -420,22 +398,20 @@ void KeyValueTreeTransformerImpl::Transformer::applyTransformedValue( } } -} // namespace internal +} // namespace internal /******************************************************************** * KeyValueTreeTransformer */ -KeyValueTreeTransformer::KeyValueTreeTransformer() - : impl_(new internal::KeyValueTreeTransformerImpl) +KeyValueTreeTransformer::KeyValueTreeTransformer() : + impl_(new internal::KeyValueTreeTransformerImpl) { } -KeyValueTreeTransformer::~KeyValueTreeTransformer() -{ -} +KeyValueTreeTransformer::~KeyValueTreeTransformer() {} -IKeyValueTreeTransformRules *KeyValueTreeTransformer::rules() +IKeyValueTreeTransformRules* KeyValueTreeTransformer::rules() { return impl_->rootScope_.rules(); } @@ -450,9 +426,8 @@ std::vector KeyValueTreeTransformer::mappedPaths() const return result; } -KeyValueTreeTransformResult -KeyValueTreeTransformer::transform(const KeyValueTreeObject &tree, - IKeyValueTreeErrorHandler *errorHandler) const +KeyValueTreeTransformResult KeyValueTreeTransformer::transform(const KeyValueTreeObject& tree, + IKeyValueTreeErrorHandler* errorHandler) const { internal::KeyValueTreeTransformerImpl::Transformer transformer(errorHandler); transformer.transform(impl_->rootRule_.get(), tree); @@ -465,73 +440,75 @@ KeyValueTreeTransformer::transform(const KeyValueTreeObject &tree, class KeyValueTreeTransformRuleBuilder::Data { - public: - typedef internal::KeyValueTreeTransformerImpl::Rule Rule; +public: + typedef internal::KeyValueTreeTransformerImpl::Rule Rule; + + explicit Data(const KeyValueTreePath& prefix) : + prefixPath_(prefix), + expectedType_(typeid(void)), + keyMatchType_(StringCompareType::Exact), + keyMatchRule_(false) + { + } - explicit Data(const KeyValueTreePath &prefix) - : prefixPath_(prefix), expectedType_(typeid(void)), - keyMatchType_(StringCompareType::Exact), keyMatchRule_(false) + void createRule(internal::KeyValueTreeTransformerImpl* impl) + { + if (keyMatchRule_) { + createRuleWithKeyMatchType(impl); + return; } - - void createRule(internal::KeyValueTreeTransformerImpl *impl) + GMX_RELEASE_ASSERT(transform_ != nullptr, "Transform has not been specified"); + Rule* rule = impl->getOrCreateRootRule(); + for (const std::string& key : fromPath_.elements()) { - if (keyMatchRule_) - { - createRuleWithKeyMatchType(impl); - return; - } - GMX_RELEASE_ASSERT(transform_ != nullptr, - "Transform has not been specified"); - Rule *rule = impl->getOrCreateRootRule(); - for (const std::string &key : fromPath_.elements()) - { - GMX_RELEASE_ASSERT(rule->targetKey_.empty(), - "Cannot specify multiple rules from a single path"); - rule = rule->getOrCreateChildRule(key); - } GMX_RELEASE_ASSERT(rule->targetKey_.empty(), "Cannot specify multiple rules from a single path"); - rule->targetKey_ = toPath_.pop_last(); - rule->targetPath_ = std::move(toPath_); - rule->expectedType_ = expectedType_; - rule->transform_ = transform_; + rule = rule->getOrCreateChildRule(key); } + GMX_RELEASE_ASSERT(rule->targetKey_.empty(), + "Cannot specify multiple rules from a single path"); + rule->targetKey_ = toPath_.pop_last(); + rule->targetPath_ = std::move(toPath_); + rule->expectedType_ = expectedType_; + rule->transform_ = transform_; + } - void createRuleWithKeyMatchType(internal::KeyValueTreeTransformerImpl *impl) + void createRuleWithKeyMatchType(internal::KeyValueTreeTransformerImpl* impl) + { + if (fromPath_.empty()) { - if (fromPath_.empty()) - { - impl->createRootRule(keyMatchType_); - } - else + impl->createRootRule(keyMatchType_); + } + else + { + std::string lastKey = fromPath_.pop_last(); + Rule* rule = impl->getOrCreateRootRule(); + for (const std::string& key : fromPath_.elements()) { - std::string lastKey = fromPath_.pop_last(); - Rule *rule = impl->getOrCreateRootRule(); - for (const std::string &key : fromPath_.elements()) - { - rule = rule->getOrCreateChildRule(key); - } - rule->createChildRule(lastKey, keyMatchType_); + rule = rule->getOrCreateChildRule(key); } + rule->createChildRule(lastKey, keyMatchType_); } + } - const KeyValueTreePath prefixPath_; - KeyValueTreePath fromPath_; - KeyValueTreePath toPath_; - std::type_index expectedType_; - Rule::TransformFunction transform_; - StringCompareType keyMatchType_; - bool keyMatchRule_; + const KeyValueTreePath prefixPath_; + KeyValueTreePath fromPath_; + KeyValueTreePath toPath_; + std::type_index expectedType_; + Rule::TransformFunction transform_; + StringCompareType keyMatchType_; + bool keyMatchRule_; }; /******************************************************************** * KeyValueTreeTransformRuleBuilder */ -KeyValueTreeTransformRuleBuilder::KeyValueTreeTransformRuleBuilder( - internal::KeyValueTreeTransformerImpl *impl, const KeyValueTreePath &prefix) - : impl_(impl), data_(new Data(prefix)) +KeyValueTreeTransformRuleBuilder::KeyValueTreeTransformRuleBuilder(internal::KeyValueTreeTransformerImpl* impl, + const KeyValueTreePath& prefix) : + impl_(impl), + data_(new Data(prefix)) { } @@ -548,17 +525,17 @@ KeyValueTreeTransformRuleBuilder::~KeyValueTreeTransformRuleBuilder() // NOLINT( } } -void KeyValueTreeTransformRuleBuilder::setFromPath(const KeyValueTreePath &path) +void KeyValueTreeTransformRuleBuilder::setFromPath(const KeyValueTreePath& path) { data_->fromPath_ = path; } -void KeyValueTreeTransformRuleBuilder::setExpectedType(const std::type_index &type) +void KeyValueTreeTransformRuleBuilder::setExpectedType(const std::type_index& type) { data_->expectedType_ = type; } -void KeyValueTreeTransformRuleBuilder::setToPath(const KeyValueTreePath &path) +void KeyValueTreeTransformRuleBuilder::setToPath(const KeyValueTreePath& path) { data_->toPath_ = data_->prefixPath_ + path; } @@ -569,25 +546,20 @@ void KeyValueTreeTransformRuleBuilder::setKeyMatchType(StringCompareType keyMatc data_->keyMatchRule_ = true; } -void KeyValueTreeTransformRuleBuilder::addTransformToAny( - const std::function &transform) +void KeyValueTreeTransformRuleBuilder::addTransformToAny(const std::function& transform) { - data_->transform_ = - [transform] (KeyValueTreeValueBuilder *builder, const KeyValueTreeValue &value) - { - builder->setAnyValue(transform(value.asAny())); - }; + data_->transform_ = [transform](KeyValueTreeValueBuilder* builder, const KeyValueTreeValue& value) { + builder->setAnyValue(transform(value.asAny())); + }; } void KeyValueTreeTransformRuleBuilder::addTransformToObject( - const std::function &transform) + const std::function& transform) { - data_->transform_ = - [transform] (KeyValueTreeValueBuilder *builder, const KeyValueTreeValue &value) - { - KeyValueTreeObjectBuilder obj = builder->createObject(); - transform(&obj, value.asAny()); - }; + data_->transform_ = [transform](KeyValueTreeValueBuilder* builder, const KeyValueTreeValue& value) { + KeyValueTreeObjectBuilder obj = builder->createObject(); + transform(&obj, value.asAny()); + }; } } // namespace gmx diff --git a/src/gromacs/utility/keyvaluetreetransform.h b/src/gromacs/utility/keyvaluetreetransform.h index 6343121e9a..9c2a2f5acd 100644 --- a/src/gromacs/utility/keyvaluetreetransform.h +++ b/src/gromacs/utility/keyvaluetreetransform.h @@ -90,28 +90,27 @@ class KeyValueTreeTransformerImpl; */ class IKeyValueTreeTransformRules { - public: - /*! \brief - * Creates a new rule. - * - * Properties of the new rule must be specified using the returned - * builder. - */ - virtual KeyValueTreeTransformRuleBuilder addRule() = 0; - /*! \brief - * Creates a scoped set of rules, where all rules use a target sub-tree. - * - * \param[in] scope Prefix defining the scope in the target tree - * - * Any rules added to the returned scope will have `scope` prefixed to - * their target paths, i.e., it is not possible to produce elements - * outside the specified subtree. - */ - virtual KeyValueTreeTransformRulesScoped - scopedTransform(const KeyValueTreePath &scope) = 0; - - protected: - virtual ~IKeyValueTreeTransformRules(); +public: + /*! \brief + * Creates a new rule. + * + * Properties of the new rule must be specified using the returned + * builder. + */ + virtual KeyValueTreeTransformRuleBuilder addRule() = 0; + /*! \brief + * Creates a scoped set of rules, where all rules use a target sub-tree. + * + * \param[in] scope Prefix defining the scope in the target tree + * + * Any rules added to the returned scope will have `scope` prefixed to + * their target paths, i.e., it is not possible to produce elements + * outside the specified subtree. + */ + virtual KeyValueTreeTransformRulesScoped scopedTransform(const KeyValueTreePath& scope) = 0; + +protected: + virtual ~IKeyValueTreeTransformRules(); }; /*! \libinternal \brief @@ -122,24 +121,23 @@ class IKeyValueTreeTransformRules */ class KeyValueTreeTransformRulesScoped { - public: - //! Internal constructor for creating the scope. - KeyValueTreeTransformRulesScoped( - internal::KeyValueTreeTransformerImpl *impl, - const KeyValueTreePath &prefix); - //! Supports returning the object from IKeyValueTreeTransformRules::scopedTransform(). - KeyValueTreeTransformRulesScoped(KeyValueTreeTransformRulesScoped &&other) noexcept; - //! Supports returning the object from IKeyValueTreeTransformRules::scopedTransform(). - KeyValueTreeTransformRulesScoped &operator=(KeyValueTreeTransformRulesScoped &&other) noexcept; - ~KeyValueTreeTransformRulesScoped(); - - //! Returns the interface for adding rules to this scope. - IKeyValueTreeTransformRules *rules(); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + //! Internal constructor for creating the scope. + KeyValueTreeTransformRulesScoped(internal::KeyValueTreeTransformerImpl* impl, + const KeyValueTreePath& prefix); + //! Supports returning the object from IKeyValueTreeTransformRules::scopedTransform(). + KeyValueTreeTransformRulesScoped(KeyValueTreeTransformRulesScoped&& other) noexcept; + //! Supports returning the object from IKeyValueTreeTransformRules::scopedTransform(). + KeyValueTreeTransformRulesScoped& operator=(KeyValueTreeTransformRulesScoped&& other) noexcept; + ~KeyValueTreeTransformRulesScoped(); + + //! Returns the interface for adding rules to this scope. + IKeyValueTreeTransformRules* rules(); + +private: + class Impl; + + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -162,245 +160,227 @@ class KeyValueTreeTransformRulesScoped */ class KeyValueTreeTransformRuleBuilder { +public: + /*! \internal \brief + * Base class used for implementing parameter provider objects. + */ + class Base + { + protected: + //! Creates a parameter provider object within given builder. + explicit Base(KeyValueTreeTransformRuleBuilder* builder) : builder_(builder) {} + + //! The parent builder. + KeyValueTreeTransformRuleBuilder* builder_; + }; + + /*! \libinternal \brief + * Properties that can be specified after from().to(). + * + * \tparam FromType Type specified for from() to map from. + * \tparam ToType Type specified for to() to map to. + */ + template + class ToValue : public Base + { public: - /*! \internal \brief - * Base class used for implementing parameter provider objects. - */ - class Base - { - protected: - //! Creates a parameter provider object within given builder. - explicit Base(KeyValueTreeTransformRuleBuilder *builder) - : builder_(builder) - { - } - - //! The parent builder. - KeyValueTreeTransformRuleBuilder *builder_; - }; - - /*! \libinternal \brief - * Properties that can be specified after from().to(). - * - * \tparam FromType Type specified for from() to map from. - * \tparam ToType Type specified for to() to map to. - */ - template - class ToValue : public Base - { - public: - //! Creates a parameter provider object within given builder. - explicit ToValue(KeyValueTreeTransformRuleBuilder *builder) - : Base(builder) - { - } - - /*! \brief - * Specifies the transformation function to convert the value - * from FromType to ToType. - */ - void transformWith(std::function transform) - { - builder_->addTransformToAny( - [transform] (const Any &value) - { - return Any::create(transform(value.cast())); - }); - } - }; - - /*! \libinternal \brief - * Properties that can be specified after from().toObject(). - * - * \tparam FromType Type specified for from() to map from. + //! Creates a parameter provider object within given builder. + explicit ToValue(KeyValueTreeTransformRuleBuilder* builder) : Base(builder) {} + + /*! \brief + * Specifies the transformation function to convert the value + * from FromType to ToType. */ - template - class ToObject : public Base + void transformWith(std::function transform) { - public: - //! Creates a parameter provider object within given builder. - explicit ToObject(KeyValueTreeTransformRuleBuilder *builder) - : Base(builder) - { - } - - /*! \brief - * Specifies the transformation function to build the output - * object. - * - * The transform should build the output object with the - * provided builder. - */ - void transformWith(std::function transform) - { - builder_->addTransformToObject( - [transform] (KeyValueTreeObjectBuilder *builder, const Any &value) - { - transform(builder, value.cast()); - }); - } - }; - - /*! \libinternal \brief - * Properties that can be specified after from(). + builder_->addTransformToAny([transform](const Any& value) { + return Any::create(transform(value.cast())); + }); + } + }; + + /*! \libinternal \brief + * Properties that can be specified after from().toObject(). + * + * \tparam FromType Type specified for from() to map from. + */ + template + class ToObject : public Base + { + public: + //! Creates a parameter provider object within given builder. + explicit ToObject(KeyValueTreeTransformRuleBuilder* builder) : Base(builder) {} + + /*! \brief + * Specifies the transformation function to build the output + * object. * - * \tparam FromType Type specified for from() to map from. + * The transform should build the output object with the + * provided builder. */ - template - class AfterFrom : public Base + void transformWith(std::function transform) { - public: - //! Creates a parameter provider object within given builder. - explicit AfterFrom(KeyValueTreeTransformRuleBuilder *builder) - : Base(builder) - { - } - - /*! \brief - * Specifies a rule that maps to a value at given path. - * - * \tparam ToType Type to map to. - * \param[in] path Path to map to. - * - * It is an error if multiple rules map to the same path, or to - * a parent path of the target of an existing rule. - * Note that it is possible to have a to() rule map to a child - * of a toObject() rule, provided that the path is not created - * by the object rule. - */ - template - ToValue to(const KeyValueTreePath &path) - { - builder_->setToPath(path); - return ToValue(builder_); - } - - /*! \brief - * Specifies a rule that maps to an object (collection of named - * values) at given path. - * - * \param[in] path Path to map to. - * - * It is an error if multiple rules map to the same path, or to - * a parent path of the target of an existing rule. - * However, it is allowed to have two toObject() rules map to - * the same path, provided that the properties they produce are - * distinct. - */ - ToObject toObject(const KeyValueTreePath &path) - { - builder_->setToPath(path); - return ToObject(builder_); - } - }; - - //! Internal constructor for creating a builder. - KeyValueTreeTransformRuleBuilder(internal::KeyValueTreeTransformerImpl *impl, - const KeyValueTreePath &prefix); - //! Supports returning the builder from IKeyValueTreeTransformRules::addRule(). - KeyValueTreeTransformRuleBuilder(KeyValueTreeTransformRuleBuilder &&) = default; - //! Supports returning the builder from IKeyValueTreeTransformRules::addRule(). - KeyValueTreeTransformRuleBuilder &operator=(KeyValueTreeTransformRuleBuilder &&) = default; - ~KeyValueTreeTransformRuleBuilder(); // NOLINT(bugprone-exception-escape) + builder_->addTransformToObject([transform](KeyValueTreeObjectBuilder* builder, const Any& value) { + transform(builder, value.cast()); + }); + } + }; + + /*! \libinternal \brief + * Properties that can be specified after from(). + * + * \tparam FromType Type specified for from() to map from. + */ + template + class AfterFrom : public Base + { + public: + //! Creates a parameter provider object within given builder. + explicit AfterFrom(KeyValueTreeTransformRuleBuilder* builder) : Base(builder) {} /*! \brief - * Specifies a rule that maps a value at given path. - * - * \tparam FromType Type of value expected at `path`. - * \param[in] path Path to map in this rule. + * Specifies a rule that maps to a value at given path. * - * If the input tree has `path`, but it is not of type `FromType`, - * the transform will produce an error. + * \tparam ToType Type to map to. + * \param[in] path Path to map to. * - * It is an error to use the same path in two from() rules. Similarly, - * it is an error to use a child path of a path used in a different - * from() rule. + * It is an error if multiple rules map to the same path, or to + * a parent path of the target of an existing rule. + * Note that it is possible to have a to() rule map to a child + * of a toObject() rule, provided that the path is not created + * by the object rule. */ - template - AfterFrom from(const KeyValueTreePath &path) + template + ToValue to(const KeyValueTreePath& path) { - setFromPath(path); - setExpectedType(typeid(FromType)); - return AfterFrom(this); + builder_->setToPath(path); + return ToValue(builder_); } + /*! \brief - * Specifies how strings are matched when matching rules against a path. + * Specifies a rule that maps to an object (collection of named + * values) at given path. * - * For properties of the object at `path`, `keyMatchType` is used for - * string comparison. + * \param[in] path Path to map to. * - * This rule must be specified first for a path, before any other - * from() rule specifies the path or a subpath. - * The rule only applies to immediate properties at the given path, not - * recursively. - * It is an error to specify the match type multiple times for a path. + * It is an error if multiple rules map to the same path, or to + * a parent path of the target of an existing rule. + * However, it is allowed to have two toObject() rules map to + * the same path, provided that the properties they produce are + * distinct. */ - void keyMatchType(const KeyValueTreePath &path, StringCompareType keyMatchType) + ToObject toObject(const KeyValueTreePath& path) { - setFromPath(path); - setKeyMatchType(keyMatchType); + builder_->setToPath(path); + return ToObject(builder_); } - - private: - void setFromPath(const KeyValueTreePath &path); - void setExpectedType(const std::type_index &type); - void setToPath(const KeyValueTreePath &path); - void setKeyMatchType(StringCompareType keyMatchType); - void addTransformToAny(const std::function &transform); - void addTransformToObject(const std::function &transform); - - class Data; - - internal::KeyValueTreeTransformerImpl *impl_; - std::unique_ptr data_; + }; + + //! Internal constructor for creating a builder. + KeyValueTreeTransformRuleBuilder(internal::KeyValueTreeTransformerImpl* impl, + const KeyValueTreePath& prefix); + //! Supports returning the builder from IKeyValueTreeTransformRules::addRule(). + KeyValueTreeTransformRuleBuilder(KeyValueTreeTransformRuleBuilder&&) = default; + //! Supports returning the builder from IKeyValueTreeTransformRules::addRule(). + KeyValueTreeTransformRuleBuilder& operator=(KeyValueTreeTransformRuleBuilder&&) = default; + ~KeyValueTreeTransformRuleBuilder(); // NOLINT(bugprone-exception-escape) + + /*! \brief + * Specifies a rule that maps a value at given path. + * + * \tparam FromType Type of value expected at `path`. + * \param[in] path Path to map in this rule. + * + * If the input tree has `path`, but it is not of type `FromType`, + * the transform will produce an error. + * + * It is an error to use the same path in two from() rules. Similarly, + * it is an error to use a child path of a path used in a different + * from() rule. + */ + template + AfterFrom from(const KeyValueTreePath& path) + { + setFromPath(path); + setExpectedType(typeid(FromType)); + return AfterFrom(this); + } + /*! \brief + * Specifies how strings are matched when matching rules against a path. + * + * For properties of the object at `path`, `keyMatchType` is used for + * string comparison. + * + * This rule must be specified first for a path, before any other + * from() rule specifies the path or a subpath. + * The rule only applies to immediate properties at the given path, not + * recursively. + * It is an error to specify the match type multiple times for a path. + */ + void keyMatchType(const KeyValueTreePath& path, StringCompareType keyMatchType) + { + setFromPath(path); + setKeyMatchType(keyMatchType); + } + +private: + void setFromPath(const KeyValueTreePath& path); + void setExpectedType(const std::type_index& type); + void setToPath(const KeyValueTreePath& path); + void setKeyMatchType(StringCompareType keyMatchType); + void addTransformToAny(const std::function& transform); + void addTransformToObject(const std::function& transform); + + class Data; + + internal::KeyValueTreeTransformerImpl* impl_; + std::unique_ptr data_; }; class KeyValueTreeTransformer { - public: - KeyValueTreeTransformer(); - ~KeyValueTreeTransformer(); +public: + KeyValueTreeTransformer(); + ~KeyValueTreeTransformer(); - IKeyValueTreeTransformRules *rules(); + IKeyValueTreeTransformRules* rules(); - std::vector mappedPaths() const; + std::vector mappedPaths() const; - KeyValueTreeTransformResult - transform(const KeyValueTreeObject &tree, - IKeyValueTreeErrorHandler *errorHandler) const; + KeyValueTreeTransformResult transform(const KeyValueTreeObject& tree, + IKeyValueTreeErrorHandler* errorHandler) const; - private: - PrivateImplPointer impl_; +private: + PrivateImplPointer impl_; }; class IKeyValueTreeBackMapping { - public: - virtual ~IKeyValueTreeBackMapping(); +public: + virtual ~IKeyValueTreeBackMapping(); - virtual KeyValueTreePath - originalPath(const KeyValueTreePath &path) const = 0; + virtual KeyValueTreePath originalPath(const KeyValueTreePath& path) const = 0; }; class KeyValueTreeTransformResult { - public: - KeyValueTreeObject object() { return std::move(object_); } - const IKeyValueTreeBackMapping &backMapping() const { return *mapping_; } +public: + KeyValueTreeObject object() { return std::move(object_); } + const IKeyValueTreeBackMapping& backMapping() const { return *mapping_; } - private: - typedef std::unique_ptr MappingPointer; +private: + typedef std::unique_ptr MappingPointer; - KeyValueTreeTransformResult(KeyValueTreeObject &&object, - MappingPointer &&mapping) - : object_(std::move(object)), mapping_(std::move(mapping)) - { - } + KeyValueTreeTransformResult(KeyValueTreeObject&& object, MappingPointer&& mapping) : + object_(std::move(object)), + mapping_(std::move(mapping)) + { + } - KeyValueTreeObject object_; - MappingPointer mapping_; + KeyValueTreeObject object_; + MappingPointer mapping_; - friend class internal::KeyValueTreeTransformerImpl; + friend class internal::KeyValueTreeTransformerImpl; }; } // namespace gmx diff --git a/src/gromacs/utility/logger.cpp b/src/gromacs/utility/logger.cpp index 856ff58341..14d73b13e6 100644 --- a/src/gromacs/utility/logger.cpp +++ b/src/gromacs/utility/logger.cpp @@ -47,20 +47,17 @@ namespace { //! Helper method for reading logging targets from an array. -ILogTarget *getTarget(ILogTarget *targets[MDLogger::LogLevelCount], - MDLogger::LogLevel level) +ILogTarget* getTarget(ILogTarget* targets[MDLogger::LogLevelCount], MDLogger::LogLevel level) { return targets[static_cast(level)]; } -} // namespace +} // namespace -ILogTarget::~ILogTarget() -{ -} +ILogTarget::~ILogTarget() {} -LogEntryWriter &LogEntryWriter::appendTextFormatted(gmx_fmtstr const char *fmt, ...) +LogEntryWriter& LogEntryWriter::appendTextFormatted(gmx_fmtstr const char* fmt, ...) { va_list ap; @@ -70,17 +67,21 @@ LogEntryWriter &LogEntryWriter::appendTextFormatted(gmx_fmtstr const char *fmt, return *this; } -MDLogger::MDLogger() - : warning(nullptr), error(nullptr), debug(nullptr), verboseDebug(nullptr), info(nullptr) +MDLogger::MDLogger() : + warning(nullptr), + error(nullptr), + debug(nullptr), + verboseDebug(nullptr), + info(nullptr) { } -MDLogger::MDLogger(ILogTarget *targets[LogLevelCount]) - : warning(getTarget(targets, LogLevel::Warning)), - error(getTarget(targets, LogLevel::Error)), - debug(getTarget(targets, LogLevel::Debug)), - verboseDebug(getTarget(targets, LogLevel::VerboseDebug)), - info(getTarget(targets, LogLevel::Info)) +MDLogger::MDLogger(ILogTarget* targets[LogLevelCount]) : + warning(getTarget(targets, LogLevel::Warning)), + error(getTarget(targets, LogLevel::Error)), + debug(getTarget(targets, LogLevel::Debug)), + verboseDebug(getTarget(targets, LogLevel::VerboseDebug)), + info(getTarget(targets, LogLevel::Info)) { } diff --git a/src/gromacs/utility/logger.h b/src/gromacs/utility/logger.h index f1801b4df0..4c9f773848 100644 --- a/src/gromacs/utility/logger.h +++ b/src/gromacs/utility/logger.h @@ -66,11 +66,11 @@ struct LogEntry */ class ILogTarget { - public: - virtual ~ILogTarget(); +public: + virtual ~ILogTarget(); - //! Writes a log entry to this target. - virtual void writeEntry(const LogEntry &entry) = 0; + //! Writes a log entry to this target. + virtual void writeEntry(const LogEntry& entry) = 0; }; /*! \libinternal \brief @@ -80,32 +80,32 @@ class ILogTarget */ class LogEntryWriter { - public: - //! Appends given text as a line in the log entry. - LogEntryWriter &appendText(const char *text) - { - entry_.text.append(text); - return *this; - } - //! Appends given text as a line in the log entry. - LogEntryWriter &appendText(const std::string &text) - { - entry_.text.append(text); - return *this; - } - //! Appends given text as a line in the log entry, with printf-style formatting. - LogEntryWriter &appendTextFormatted(gmx_fmtstr const char *fmt, ...) gmx_format(printf, 2, 3); - //! Writes the log entry with empty lines before and after. - LogEntryWriter &asParagraph() - { - entry_.asParagraph = true; - return *this; - } - - private: - LogEntry entry_; - - friend class LogWriteHelper; +public: + //! Appends given text as a line in the log entry. + LogEntryWriter& appendText(const char* text) + { + entry_.text.append(text); + return *this; + } + //! Appends given text as a line in the log entry. + LogEntryWriter& appendText(const std::string& text) + { + entry_.text.append(text); + return *this; + } + //! Appends given text as a line in the log entry, with printf-style formatting. + LogEntryWriter& appendTextFormatted(gmx_fmtstr const char* fmt, ...) gmx_format(printf, 2, 3); + //! Writes the log entry with empty lines before and after. + LogEntryWriter& asParagraph() + { + entry_.asParagraph = true; + return *this; + } + +private: + LogEntry entry_; + + friend class LogWriteHelper; }; /*! \internal \brief @@ -115,35 +115,35 @@ class LogEntryWriter */ class LogWriteHelper { - public: - //! Initializes a helper for writing to the given target. - explicit LogWriteHelper(ILogTarget *target) : target_(target) {} - - // Should be explicit, once that works in CUDA. - /*! \brief - * Returns whether anything needs to be written. - * - * Note that the return value is unintuitively `false` when the target - * is active, to allow implementing ::GMX_LOG like it is now. - */ - operator bool() const { return target_ == nullptr; } - - /*! \brief - * Writes the entry from the given writer to the log target. - * - * This is implemented as an assignment operator to get proper - * precedence for operations for the ::GMX_LOG macro; this is a common - * technique for implementing macros that allow streming information to - * them (see, e.g., Google Test). - */ - LogWriteHelper &operator=(const LogEntryWriter &entryWriter) - { - target_->writeEntry(entryWriter.entry_); - return *this; - } - - private: - ILogTarget *target_; +public: + //! Initializes a helper for writing to the given target. + explicit LogWriteHelper(ILogTarget* target) : target_(target) {} + + // Should be explicit, once that works in CUDA. + /*! \brief + * Returns whether anything needs to be written. + * + * Note that the return value is unintuitively `false` when the target + * is active, to allow implementing ::GMX_LOG like it is now. + */ + operator bool() const { return target_ == nullptr; } + + /*! \brief + * Writes the entry from the given writer to the log target. + * + * This is implemented as an assignment operator to get proper + * precedence for operations for the ::GMX_LOG macro; this is a common + * technique for implementing macros that allow streming information to + * them (see, e.g., Google Test). + */ + LogWriteHelper& operator=(const LogEntryWriter& entryWriter) + { + target_->writeEntry(entryWriter.entry_); + return *this; + } + +private: + ILogTarget* target_; }; /*! \libinternal \brief @@ -156,19 +156,19 @@ class LogWriteHelper */ class LogLevelHelper { - public: - //! Initializes a helper for writing to the given target. - explicit LogLevelHelper(ILogTarget *target) : target_(target) {} +public: + //! Initializes a helper for writing to the given target. + explicit LogLevelHelper(ILogTarget* target) : target_(target) {} - // Both of the below should be explicit, once that works in CUDA. - //! Returns whether the output for this log level goes anywhere. - operator bool() const { return target_ != nullptr; } + // Both of the below should be explicit, once that works in CUDA. + //! Returns whether the output for this log level goes anywhere. + operator bool() const { return target_ != nullptr; } - //! Creates a helper for ::GMX_LOG. - operator LogWriteHelper() const { return LogWriteHelper(target_); } + //! Creates a helper for ::GMX_LOG. + operator LogWriteHelper() const { return LogWriteHelper(target_); } - private: - ILogTarget *target_; +private: + ILogTarget* target_; }; /*! \libinternal \brief @@ -187,34 +187,34 @@ class LogLevelHelper */ class MDLogger { - public: - //! Supported logging levels. - enum class LogLevel - { - Error, - Warning, - Info, - Debug, - VerboseDebug, - Count - }; - //! Number of logging levels. - static const int LogLevelCount = static_cast(LogLevel::Count); - - MDLogger(); - //! Creates a logger with the given targets. - explicit MDLogger(ILogTarget *targets[LogLevelCount]); - - //! For writing at LogLevel::Warning level. - LogLevelHelper warning; - //! For writing at LogLevel::Error level. - LogLevelHelper error; - //! For writing at LogLevel::Debug level. - LogLevelHelper debug; - //! For writing at LogLevel::VerboseDebug level. - LogLevelHelper verboseDebug; - //! For writing at LogLevel::Info level. - LogLevelHelper info; +public: + //! Supported logging levels. + enum class LogLevel + { + Error, + Warning, + Info, + Debug, + VerboseDebug, + Count + }; + //! Number of logging levels. + static const int LogLevelCount = static_cast(LogLevel::Count); + + MDLogger(); + //! Creates a logger with the given targets. + explicit MDLogger(ILogTarget* targets[LogLevelCount]); + + //! For writing at LogLevel::Warning level. + LogLevelHelper warning; + //! For writing at LogLevel::Error level. + LogLevelHelper error; + //! For writing at LogLevel::Debug level. + LogLevelHelper debug; + //! For writing at LogLevel::VerboseDebug level. + LogLevelHelper verboseDebug; + //! For writing at LogLevel::Info level. + LogLevelHelper info; }; /*! \brief @@ -234,8 +234,9 @@ class MDLogger * * \ingroup module_utility */ -#define GMX_LOG(logger) \ - if (::gmx::LogWriteHelper helper = ::gmx::LogWriteHelper(logger)) { } else \ +#define GMX_LOG(logger) \ + if (::gmx::LogWriteHelper helper = ::gmx::LogWriteHelper(logger)) {} \ + else \ helper = ::gmx::LogEntryWriter() } // namespace gmx diff --git a/src/gromacs/utility/loggerbuilder.cpp b/src/gromacs/utility/loggerbuilder.cpp index 5d286a6d95..91e366f2f0 100644 --- a/src/gromacs/utility/loggerbuilder.cpp +++ b/src/gromacs/utility/loggerbuilder.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -49,37 +49,34 @@ namespace gmx class LogTargetCollection : public ILogTarget { - public: - void addTarget(ILogTarget *target) - { - targets_.push_back(target); - } +public: + void addTarget(ILogTarget* target) { targets_.push_back(target); } - void writeEntry(const LogEntry &entry) override + void writeEntry(const LogEntry& entry) override + { + for (ILogTarget* target : targets_) { - for (ILogTarget *target : targets_) - { - target->writeEntry(entry); - } + target->writeEntry(entry); } + } - private: - std::vector targets_; +private: + std::vector targets_; }; class LogTargetFormatter : public ILogTarget { - public: - explicit LogTargetFormatter(TextOutputStream *stream) : writer_(stream) {} +public: + explicit LogTargetFormatter(TextOutputStream* stream) : writer_(stream) {} - void writeEntry(const LogEntry &entry) override; + void writeEntry(const LogEntry& entry) override; - private: - TextWriter writer_; +private: + TextWriter writer_; }; -void LogTargetFormatter::writeEntry(const LogEntry &entry) +void LogTargetFormatter::writeEntry(const LogEntry& entry) { if (entry.asParagraph) { @@ -98,41 +95,38 @@ void LogTargetFormatter::writeEntry(const LogEntry &entry) class LoggerOwner::Impl { - public: - explicit Impl(ILogTarget *loggerTargets[MDLogger::LogLevelCount]) - : logger_(loggerTargets) - { - } +public: + explicit Impl(ILogTarget* loggerTargets[MDLogger::LogLevelCount]) : logger_(loggerTargets) {} - MDLogger logger_; - std::vector > streams_; - std::vector > targets_; + MDLogger logger_; + std::vector> streams_; + std::vector> targets_; }; /******************************************************************** * LoggerOwner */ -LoggerOwner::LoggerOwner(std::unique_ptr impl) - : impl_(impl.release()), logger_(&impl_->logger_) +LoggerOwner::LoggerOwner(std::unique_ptr impl) : + impl_(impl.release()), + logger_(&impl_->logger_) { } -LoggerOwner::LoggerOwner(LoggerOwner &&other) noexcept - : impl_(std::move(other.impl_)), logger_(&impl_->logger_) +LoggerOwner::LoggerOwner(LoggerOwner&& other) noexcept : + impl_(std::move(other.impl_)), + logger_(&impl_->logger_) { } -LoggerOwner &LoggerOwner::operator=(LoggerOwner &&other) noexcept +LoggerOwner& LoggerOwner::operator=(LoggerOwner&& other) noexcept { impl_ = std::move(other.impl_); logger_ = &impl_->logger_; return *this; } -LoggerOwner::~LoggerOwner() -{ -} +LoggerOwner::~LoggerOwner() {} /******************************************************************** * LoggerBuilder::Impl @@ -140,36 +134,31 @@ LoggerOwner::~LoggerOwner() class LoggerBuilder::Impl { - public: - std::vector > streams_; - std::vector > targets_; - std::vector loggerTargets_[MDLogger::LogLevelCount]; +public: + std::vector> streams_; + std::vector> targets_; + std::vector loggerTargets_[MDLogger::LogLevelCount]; }; /******************************************************************** * LoggerBuilder */ -LoggerBuilder::LoggerBuilder() - : impl_(new Impl) -{ -} +LoggerBuilder::LoggerBuilder() : impl_(new Impl) {} -LoggerBuilder::~LoggerBuilder() -{ -} +LoggerBuilder::~LoggerBuilder() {} -void LoggerBuilder::addTargetStream(MDLogger::LogLevel level, TextOutputStream *stream) +void LoggerBuilder::addTargetStream(MDLogger::LogLevel level, TextOutputStream* stream) { impl_->targets_.push_back(std::unique_ptr(new LogTargetFormatter(stream))); - ILogTarget *target = impl_->targets_.back().get(); + ILogTarget* target = impl_->targets_.back().get(); for (int i = 0; i <= static_cast(level); ++i) { impl_->loggerTargets_[i].push_back(target); } } -void LoggerBuilder::addTargetFile(MDLogger::LogLevel level, FILE *fp) +void LoggerBuilder::addTargetFile(MDLogger::LogLevel level, FILE* fp) { std::unique_ptr stream(new TextOutputFile(fp)); addTargetStream(level, stream.get()); @@ -178,11 +167,11 @@ void LoggerBuilder::addTargetFile(MDLogger::LogLevel level, FILE *fp) LoggerOwner LoggerBuilder::build() { - ILogTarget *loggerTargets[MDLogger::LogLevelCount]; + ILogTarget* loggerTargets[MDLogger::LogLevelCount]; for (int i = 0; i < MDLogger::LogLevelCount; ++i) { - auto &levelTargets = impl_->loggerTargets_[i]; - loggerTargets[i] = nullptr; + auto& levelTargets = impl_->loggerTargets_[i]; + loggerTargets[i] = nullptr; if (!levelTargets.empty()) { if (levelTargets.size() == 1) @@ -192,7 +181,7 @@ LoggerOwner LoggerBuilder::build() else { std::unique_ptr collection(new LogTargetCollection); - for (auto &target : levelTargets) + for (auto& target : levelTargets) { collection->addTarget(target); } diff --git a/src/gromacs/utility/loggerbuilder.h b/src/gromacs/utility/loggerbuilder.h index ce3b77b900..1cc1e8a7ad 100644 --- a/src/gromacs/utility/loggerbuilder.h +++ b/src/gromacs/utility/loggerbuilder.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,39 +71,39 @@ class LoggerOwner; */ class LoggerBuilder { - public: - LoggerBuilder(); - ~LoggerBuilder(); - - /*! \brief - * Adds a stream to which log output is written. - * - * All output at level \p level or above it is written to \p stream. - * The caller is responsible of closing and freeing \p stream once the - * logger is discarded. - */ - void addTargetStream(MDLogger::LogLevel level, TextOutputStream *stream); - /*! \brief - * Adds a file to which log output is written. - * - * All output at level \p level or above it is written to \p fp. - * The caller is responsible of closing \p fp once the logger is - * discarded. - */ - void addTargetFile(MDLogger::LogLevel level, FILE *fp); - - /*! \brief - * Builds the logger with the targets set for this builder. - * - * After this function has been called, the builder can (and should) be - * discarded. - */ - LoggerOwner build(); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + LoggerBuilder(); + ~LoggerBuilder(); + + /*! \brief + * Adds a stream to which log output is written. + * + * All output at level \p level or above it is written to \p stream. + * The caller is responsible of closing and freeing \p stream once the + * logger is discarded. + */ + void addTargetStream(MDLogger::LogLevel level, TextOutputStream* stream); + /*! \brief + * Adds a file to which log output is written. + * + * All output at level \p level or above it is written to \p fp. + * The caller is responsible of closing \p fp once the logger is + * discarded. + */ + void addTargetFile(MDLogger::LogLevel level, FILE* fp); + + /*! \brief + * Builds the logger with the targets set for this builder. + * + * After this function has been called, the builder can (and should) be + * discarded. + */ + LoggerOwner build(); + +private: + class Impl; + + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -122,26 +122,26 @@ class LoggerBuilder */ class LoggerOwner { - public: - //! Move-constructs the owner. - LoggerOwner(LoggerOwner &&other) noexcept; - ~LoggerOwner(); +public: + //! Move-constructs the owner. + LoggerOwner(LoggerOwner&& other) noexcept; + ~LoggerOwner(); - //! Move-assings the owner. - LoggerOwner &operator=(LoggerOwner &&other) noexcept; + //! Move-assings the owner. + LoggerOwner& operator=(LoggerOwner&& other) noexcept; - //! Returns the logger for writing the logs. - const MDLogger &logger() const { return *logger_; } + //! Returns the logger for writing the logs. + const MDLogger& logger() const { return *logger_; } - private: - class Impl; +private: + class Impl; - LoggerOwner(std::unique_ptr impl); + LoggerOwner(std::unique_ptr impl); - PrivateImplPointer impl_; - const MDLogger *logger_; + PrivateImplPointer impl_; + const MDLogger* logger_; - friend class LoggerBuilder; + friend class LoggerBuilder; }; } // namespace gmx diff --git a/src/gromacs/utility/mdmodulenotification.h b/src/gromacs/utility/mdmodulenotification.h index 0d8ecb3953..c56160420d 100644 --- a/src/gromacs/utility/mdmodulenotification.h +++ b/src/gromacs/utility/mdmodulenotification.h @@ -98,40 +98,40 @@ namespace gmx * \note All added subscribers are required to out-live the MdModuleNotification * */ -template +template class MdModuleNotification : public MdModuleNotificationBase { - public: - //! Make base class notification trigger available to this class - using MdModuleNotificationBase::notify; - //! Make base class subscription available to this class - using MdModuleNotificationBase::subscribe; +public: + //! Make base class notification trigger available to this class + using MdModuleNotificationBase::notify; + //! Make base class subscription available to this class + using MdModuleNotificationBase::subscribe; - /*! \brief Trigger the subscribed notifications. - * \param[in] callParameter of the function to be called back - */ - void notify(CallParameter callParameter) const + /*! \brief Trigger the subscribed notifications. + * \param[in] callParameter of the function to be called back + */ + void notify(CallParameter callParameter) const + { + for (auto& callBack : callBackFunctions_) { - for (auto &callBack : callBackFunctions_) - { - callBack(callParameter); - } + callBack(callParameter); } + } - /*! \brief - * Add callback function to be called when notification is triggered. - * - * Notifications are distinguished by their call signature. - * - * \param[in] callBackFunction to be called from this class - */ - void subscribe(std::function callBackFunction) - { - callBackFunctions_.emplace_back(callBackFunction); - } + /*! \brief + * Add callback function to be called when notification is triggered. + * + * Notifications are distinguished by their call signature. + * + * \param[in] callBackFunction to be called from this class + */ + void subscribe(std::function callBackFunction) + { + callBackFunctions_.emplace_back(callBackFunction); + } - private: - std::vector < std::function < void(CallParameter)>> callBackFunctions_; +private: + std::vector> callBackFunctions_; }; /*! \internal @@ -144,11 +144,12 @@ class MdModuleNotification : public MdModuleNotificationBase * * \tparam CallParameter all the event types to be registered */ -template struct registerMdModuleNotification; +template +struct registerMdModuleNotification; /*! \internal \brief Template specialization to end parameter unpacking recursion. */ -template <> +template<> struct registerMdModuleNotification<> { /*! \internal @@ -159,11 +160,11 @@ struct registerMdModuleNotification<> */ class NoCallParameter { - public: - //! Do nothing but provide MdModuleNotification::notify to derived class - void notify() {} - //! Do nothing but provide MdModuleNotification::subscribe to derived class - void subscribe() {} + public: + //! Do nothing but provide MdModuleNotification::notify to derived class + void notify() {} + //! Do nothing but provide MdModuleNotification::subscribe to derived class + void subscribe() {} }; /*! \brief Defines a type if no notifications are managed. * @@ -183,7 +184,7 @@ struct registerMdModuleNotification<> * \tparam CurrentCallParameter front of the template parameter pack * \tparam CallParameter rest of the event types */ -template +template struct registerMdModuleNotification { // private: @@ -222,30 +223,27 @@ struct MdModulesEnergyOutputToDensityFittingRequestChecker */ class EnergyCalculationFrequencyErrors { - public: - //! Construct by setting the energy calculation frequency - EnergyCalculationFrequencyErrors(int64_t energyCalculationIntervalInSteps) : - energyCalculationIntervalInSteps_(energyCalculationIntervalInSteps){} - //! Return the number of steps of an energy calculation interval - std::int64_t energyCalculationIntervalInSteps() const - { - return energyCalculationIntervalInSteps_; - } - //! Collect error messages - void addError(const std::string &errorMessage) - { - errorMessages_.push_back(errorMessage); - } - //! Return error messages - const std::vector &errorMessages() const - { - return errorMessages_; - } - private: - //! The frequency of energy calculations - const std::int64_t energyCalculationIntervalInSteps_; - //! The error messages - std::vector errorMessages_; +public: + //! Construct by setting the energy calculation frequency + EnergyCalculationFrequencyErrors(int64_t energyCalculationIntervalInSteps) : + energyCalculationIntervalInSteps_(energyCalculationIntervalInSteps) + { + } + //! Return the number of steps of an energy calculation interval + std::int64_t energyCalculationIntervalInSteps() const + { + return energyCalculationIntervalInSteps_; + } + //! Collect error messages + void addError(const std::string& errorMessage) { errorMessages_.push_back(errorMessage); } + //! Return error messages + const std::vector& errorMessages() const { return errorMessages_; } + +private: + //! The frequency of energy calculations + const std::int64_t energyCalculationIntervalInSteps_; + //! The error messages + std::vector errorMessages_; }; struct SimulationTimeStep @@ -256,20 +254,19 @@ struct SimulationTimeStep struct MdModulesNotifier { -//! Register callback function types for MdModule - registerMdModuleNotification< - const t_commrec &, - EnergyCalculationFrequencyErrors *, - IndexGroupsAndNames, - KeyValueTreeObjectBuilder, - const KeyValueTreeObject &, - LocalAtomSetManager *, - MdModulesEnergyOutputToDensityFittingRequestChecker *, - MdModulesCheckpointReadingDataOnMaster, - MdModulesCheckpointReadingBroadcast, - MdModulesWriteCheckpointData, - PeriodicBoundaryConditionType, - const SimulationTimeStep &>::type notifier_; + //! Register callback function types for MdModule + registerMdModuleNotification::type notifier_; }; } // namespace gmx diff --git a/src/gromacs/utility/messagestringcollector.cpp b/src/gromacs/utility/messagestringcollector.cpp index 97d2853ec4..306838627d 100644 --- a/src/gromacs/utility/messagestringcollector.cpp +++ b/src/gromacs/utility/messagestringcollector.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2014,2016, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2014,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,36 +52,30 @@ namespace gmx class MessageStringCollector::Impl { - public: - Impl() : prevContext_(0) {} +public: + Impl() : prevContext_(0) {} - std::vector contexts_; - std::string text_; - size_t prevContext_; + std::vector contexts_; + std::string text_; + size_t prevContext_; }; -MessageStringCollector::MessageStringCollector() - : impl_(new Impl) -{ -} +MessageStringCollector::MessageStringCollector() : impl_(new Impl) {} -MessageStringCollector::~MessageStringCollector() -{ -} +MessageStringCollector::~MessageStringCollector() {} -void MessageStringCollector::startContext(const char *name) +void MessageStringCollector::startContext(const char* name) { impl_->contexts_.emplace_back(name); } -void MessageStringCollector::append(const std::string &message) +void MessageStringCollector::append(const std::string& message) { int indent = static_cast(impl_->prevContext_ * 2); if (!impl_->contexts_.empty()) { std::vector::const_iterator ci; - for (ci = impl_->contexts_.begin() + impl_->prevContext_; - ci != impl_->contexts_.end(); ++ci) + for (ci = impl_->contexts_.begin() + impl_->prevContext_; ci != impl_->contexts_.end(); ++ci) { impl_->text_.append(indent, ' '); impl_->text_.append(*ci); @@ -109,8 +103,7 @@ void MessageStringCollector::append(const std::string &message) void MessageStringCollector::finishContext() { - GMX_RELEASE_ASSERT(!impl_->contexts_.empty(), - "finishContext() called without context"); + GMX_RELEASE_ASSERT(!impl_->contexts_.empty(), "finishContext() called without context"); impl_->contexts_.pop_back(); if (impl_->prevContext_ > impl_->contexts_.size()) { diff --git a/src/gromacs/utility/messagestringcollector.h b/src/gromacs/utility/messagestringcollector.h index c0131f52e4..ee56774f86 100644 --- a/src/gromacs/utility/messagestringcollector.h +++ b/src/gromacs/utility/messagestringcollector.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,63 +61,61 @@ namespace gmx */ class MessageStringCollector { - public: - MessageStringCollector(); - ~MessageStringCollector(); +public: + MessageStringCollector(); + ~MessageStringCollector(); - /*! \brief - * Starts a context for messages. - * - * \param[in] name Short description of the context. - * - * \see finishContext() - * \see MessageStringContext - */ - void startContext(const char *name); - /*! \brief - * Convenience wrapper for startContext(const char *). - */ - void startContext(const std::string &name) - { startContext(name.c_str()); } - /*! \brief - * Adds a new message. - */ - void append(const char *message) - { append(std::string(message)); } - /*! \brief - * Adds a new message. - */ - void append(const std::string &message); - /*! \brief - * Ends a context started with startContext(). - * - * \see MessageStringContext - */ - void finishContext(); - /*! \brief - * Clears all collected messages. - */ - void clear(); + /*! \brief + * Starts a context for messages. + * + * \param[in] name Short description of the context. + * + * \see finishContext() + * \see MessageStringContext + */ + void startContext(const char* name); + /*! \brief + * Convenience wrapper for startContext(const char *). + */ + void startContext(const std::string& name) { startContext(name.c_str()); } + /*! \brief + * Adds a new message. + */ + void append(const char* message) { append(std::string(message)); } + /*! \brief + * Adds a new message. + */ + void append(const std::string& message); + /*! \brief + * Ends a context started with startContext(). + * + * \see MessageStringContext + */ + void finishContext(); + /*! \brief + * Clears all collected messages. + */ + void clear(); - /*! \brief - * Returns true if any messages have been added. - * - * \returns true if append() has been called at least once. - * - * The return value is identical to `toString().empty()`. - * Calls to startContext() or finishContext() only do not cause this - * function to return true. - */ - bool isEmpty() const; - /*! \brief - * Returns all collected messages as one string. - */ - std::string toString() const; + /*! \brief + * Returns true if any messages have been added. + * + * \returns true if append() has been called at least once. + * + * The return value is identical to `toString().empty()`. + * Calls to startContext() or finishContext() only do not cause this + * function to return true. + */ + bool isEmpty() const; + /*! \brief + * Returns all collected messages as one string. + */ + std::string toString() const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -147,37 +145,33 @@ class MessageStringCollector */ class MessageStringContext { - public: - /*! \brief - * Adds a context for the given object. - */ - MessageStringContext(MessageStringCollector *collector, const char *name) - : collector_(*collector) - { - collector_.startContext(name); - } - /*! \brief - * Adds a context for the given object. - */ - MessageStringContext(MessageStringCollector *collector, - const std::string &name) - : collector_(*collector) - { - collector_.startContext(name); - } - /*! \brief - * Calls MessageStringCollector::finishContext() on the wrapped object. - */ - ~MessageStringContext() - { - collector_.finishContext(); - } +public: + /*! \brief + * Adds a context for the given object. + */ + MessageStringContext(MessageStringCollector* collector, const char* name) : + collector_(*collector) + { + collector_.startContext(name); + } + /*! \brief + * Adds a context for the given object. + */ + MessageStringContext(MessageStringCollector* collector, const std::string& name) : + collector_(*collector) + { + collector_.startContext(name); + } + /*! \brief + * Calls MessageStringCollector::finishContext() on the wrapped object. + */ + ~MessageStringContext() { collector_.finishContext(); } - private: - //! The wrapped object. - MessageStringCollector &collector_; +private: + //! The wrapped object. + MessageStringCollector& collector_; - GMX_DISALLOW_COPY_AND_ASSIGN(MessageStringContext); + GMX_DISALLOW_COPY_AND_ASSIGN(MessageStringContext); }; } // namespace gmx diff --git a/src/gromacs/utility/mpiinplacebuffers.cpp b/src/gromacs/utility/mpiinplacebuffers.cpp index 33e775e2fd..a35c4181fd 100644 --- a/src/gromacs/utility/mpiinplacebuffers.cpp +++ b/src/gromacs/utility/mpiinplacebuffers.cpp @@ -45,7 +45,7 @@ #include "gromacs/utility/smalloc.h" -void done_mpi_in_place_buf(mpi_in_place_buf_t *buf) +void done_mpi_in_place_buf(mpi_in_place_buf_t* buf) { if (nullptr != buf) { diff --git a/src/gromacs/utility/mpiinplacebuffers.h b/src/gromacs/utility/mpiinplacebuffers.h index 64fac5a50a..dfbac0de09 100644 --- a/src/gromacs/utility/mpiinplacebuffers.h +++ b/src/gromacs/utility/mpiinplacebuffers.h @@ -52,20 +52,20 @@ struct mpi_in_place_buf_t { /* these buffers are used as destination buffers if MPI_IN_PLACE isn't supported.*/ - int *ibuf; /* for ints */ - int ibuf_alloc; + int* ibuf; /* for ints */ + int ibuf_alloc; - int64_t *libuf; - int libuf_alloc; + int64_t* libuf; + int libuf_alloc; - float *fbuf; /* for floats */ - int fbuf_alloc; + float* fbuf; /* for floats */ + int fbuf_alloc; - double *dbuf; /* for doubles */ - int dbuf_alloc; + double* dbuf; /* for doubles */ + int dbuf_alloc; }; //! Cleans up the buffers -void done_mpi_in_place_buf(mpi_in_place_buf_t *buf); +void done_mpi_in_place_buf(mpi_in_place_buf_t* buf); #endif diff --git a/src/gromacs/utility/niceheader.cpp b/src/gromacs/utility/niceheader.cpp index d45c010e52..333b9f5c02 100644 --- a/src/gromacs/utility/niceheader.cpp +++ b/src/gromacs/utility/niceheader.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,17 +50,17 @@ namespace gmx { -void niceHeader(TextWriter *writer, const char *fn, char commentChar) +void niceHeader(TextWriter* writer, const char* fn, char commentChar) { - int uid; - char userbuf[256]; - char hostbuf[256]; + int uid; + char userbuf[256]; + char hostbuf[256]; /* Write a nice header for an output file */ writer->writeLine(formatString("%c", commentChar)); writer->writeLine(formatString("%c\tFile '%s' was generated", commentChar, fn ? fn : "unknown")); - uid = gmx_getuid(); + uid = gmx_getuid(); gmx_getusername(userbuf, 256); gmx_gethostname(hostbuf, 256); @@ -70,4 +70,4 @@ void niceHeader(TextWriter *writer, const char *fn, char commentChar) writer->writeLine(formatString("%c", commentChar)); } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/utility/niceheader.h b/src/gromacs/utility/niceheader.h index e93e0de928..b133ecd967 100644 --- a/src/gromacs/utility/niceheader.h +++ b/src/gromacs/utility/niceheader.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,8 +55,8 @@ class TextWriter; * \param[in] fn Name of the file being written; if nullptr, described as "unknown". * \param[in] commentChar Character to use as the starting delimiter for comments. * \throws std::bad_alloc if out of memory. */ -void niceHeader(TextWriter *writer, const char *fn, char commentChar); +void niceHeader(TextWriter* writer, const char* fn, char commentChar); -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/utility/nodelete.h b/src/gromacs/utility/nodelete.h index dca5db5cf3..170b29716e 100644 --- a/src/gromacs/utility/nodelete.h +++ b/src/gromacs/utility/nodelete.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,11 +59,11 @@ namespace gmx * \inlibraryapi * \ingroup module_utility */ -template +template struct no_delete { //! Deleter that does nothing. - void operator()(T * /*unused*/) {} + void operator()(T* /*unused*/) {} }; } // namespace gmx diff --git a/src/gromacs/utility/path.cpp b/src/gromacs/utility/path.cpp index 37670e824c..7214749dee 100644 --- a/src/gromacs/utility/path.cpp +++ b/src/gromacs/utility/path.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,12 +60,12 @@ #include #if GMX_NATIVE_WINDOWS -#include -#include +# include +# include #else -#ifdef HAVE_UNISTD_H -#include -#endif +# ifdef HAVE_UNISTD_H +# include +# endif #endif #include "gromacs/utility/dir_separator.h" @@ -107,7 +108,7 @@ namespace gmx * Path */ -bool Path::containsDirectory(const std::string &path) +bool Path::containsDirectory(const std::string& path) { return path.find_first_of(cDirSeparators) != std::string::npos; } @@ -116,7 +117,7 @@ bool Path::containsDirectory(const std::string &path) * with "\" or "X:\" on windows. If not, the program name * is relative to the current directory. */ -bool Path::isAbsolute(const char *path) +bool Path::isAbsolute(const char* path) { #if GMX_NATIVE_WINDOWS return path[0] != '\0' && path[1] == ':' && isDirSeparator(path[2]); @@ -125,7 +126,7 @@ bool Path::isAbsolute(const char *path) #endif } -bool Path::isAbsolute(const std::string &path) +bool Path::isAbsolute(const std::string& path) { return isAbsolute(path.c_str()); } @@ -136,8 +137,7 @@ namespace struct handle_wrapper { HANDLE handle; - handle_wrapper(HANDLE h) - : handle(h){} + handle_wrapper(HANDLE h) : handle(h) {} ~handle_wrapper() { if (handle != INVALID_HANDLE_VALUE) @@ -146,12 +146,12 @@ struct handle_wrapper } } }; -} +} // namespace #endif -bool Path::isEquivalent(const std::string &path1, const std::string &path2) +bool Path::isEquivalent(const std::string& path1, const std::string& path2) { - //based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL + // based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL #if GMX_NATIVE_WINDOWS // Note well: Physical location on external media is part of the // equivalence criteria. If there are no open handles, physical location @@ -161,33 +161,17 @@ bool Path::isEquivalent(const std::string &path1, const std::string &path2) // p2 is done first, so any error reported is for p1 // FixME: #1635 - handle_wrapper h2( - CreateFile( - path2.c_str(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - handle_wrapper h1( - CreateFile( - path1.c_str(), - 0, - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - 0)); - - if (h1.handle == INVALID_HANDLE_VALUE - || h2.handle == INVALID_HANDLE_VALUE) + handle_wrapper h2(CreateFile(path2.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + + handle_wrapper h1(CreateFile(path1.c_str(), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + + if (h1.handle == INVALID_HANDLE_VALUE || h2.handle == INVALID_HANDLE_VALUE) { // if one is invalid and the other isn't, then they aren't equivalent, // but if both are invalid then it is an error - if (h1.handle == INVALID_HANDLE_VALUE - && h2.handle == INVALID_HANDLE_VALUE) + if (h1.handle == INVALID_HANDLE_VALUE && h2.handle == INVALID_HANDLE_VALUE) { GMX_THROW(FileIOError("Path::isEquivalent called with two invalid files")); } @@ -212,16 +196,11 @@ bool Path::isEquivalent(const std::string &path1, const std::string &path2) // In theory, volume serial numbers are sufficient to distinguish between // devices, but in practice VSN's are sometimes duplicated, so last write // time and file size are also checked. - return - info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber - && info1.nFileIndexHigh == info2.nFileIndexHigh - && info1.nFileIndexLow == info2.nFileIndexLow - && info1.nFileSizeHigh == info2.nFileSizeHigh - && info1.nFileSizeLow == info2.nFileSizeLow - && info1.ftLastWriteTime.dwLowDateTime - == info2.ftLastWriteTime.dwLowDateTime - && info1.ftLastWriteTime.dwHighDateTime - == info2.ftLastWriteTime.dwHighDateTime; + return info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber + && info1.nFileIndexHigh == info2.nFileIndexHigh && info1.nFileIndexLow == info2.nFileIndexLow + && info1.nFileSizeHigh == info2.nFileSizeHigh && info1.nFileSizeLow == info2.nFileSizeLow + && info1.ftLastWriteTime.dwLowDateTime == info2.ftLastWriteTime.dwLowDateTime + && info1.ftLastWriteTime.dwHighDateTime == info2.ftLastWriteTime.dwHighDateTime; #else struct stat s1, s2; int e2 = stat(path2.c_str(), &s2); @@ -233,15 +212,15 @@ bool Path::isEquivalent(const std::string &path1, const std::string &path2) // but if both are invalid then it is an error. if (e1 != 0 && e2 != 0) { - GMX_THROW_WITH_ERRNO( - FileIOError("Path::isEquivalent called with two invalid files"), - "stat", errno); + GMX_THROW_WITH_ERRNO(FileIOError("Path::isEquivalent called with two invalid files"), + "stat", errno); } return false; } // both stats now known to be valid - return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino + return s1.st_dev == s2.st_dev + && s1.st_ino == s2.st_ino // According to the POSIX stat specs, "The st_ino and st_dev fields // taken together uniquely identify the file within the system." // Just to be sure, size and mod time are also checked. @@ -249,17 +228,14 @@ bool Path::isEquivalent(const std::string &path1, const std::string &path2) #endif } -std::string Path::join(const std::string &path1, - const std::string &path2) +std::string Path::join(const std::string& path1, const std::string& path2) { // TODO: Remove extra separators if they are present in the input paths. return path1 + cDirSeparator + path2; } -std::string Path::join(const std::string &path1, - const std::string &path2, - const std::string &path3) +std::string Path::join(const std::string& path1, const std::string& path2, const std::string& path3) { // TODO: Remove extra separators if they are present in the input paths. return path1 + cDirSeparator + path2 + cDirSeparator + path3; @@ -274,7 +250,7 @@ namespace * * \returns A view of the parent-path components, or empty if no * directory separator exists. */ -compat::string_view getParentPathView(const std::string &input) +compat::string_view getParentPathView(const std::string& input) { auto inputView = compat::to_string_view(input); size_t pos = inputView.find_last_of(cDirSeparators); @@ -296,7 +272,7 @@ compat::string_view getFilenameView(const compat::string_view input) { return input; } - return input.substr(pos+1); + return input.substr(pos + 1); } /*! \brief Returns a view of the stem of the filename in \c input. @@ -305,7 +281,7 @@ compat::string_view getFilenameView(const compat::string_view input) * filename component, ie. omitting any leading directories. * * \returns The view of the filename stem, or empty if none exists. */ -compat::string_view getStemView(const std::string &input) +compat::string_view getStemView(const std::string& input) { auto filenameView = getFilenameView(input); size_t extensionSeparatorPosition = filenameView.find_last_of('.'); @@ -331,19 +307,19 @@ compat::string_view getExtensionView(const compat::string_view input) return filenameView.substr(extensionSeparatorPosition); } -} // namespace +} // namespace -std::string Path::getParentPath(const std::string &input) +std::string Path::getParentPath(const std::string& input) { return compat::to_string(getParentPathView(input)); } -std::string Path::getFilename(const std::string &input) +std::string Path::getFilename(const std::string& input) { return to_string(getFilenameView(input)); } -bool Path::hasExtension(const std::string &input) +bool Path::hasExtension(const std::string& input) { // This could be implemented with getStemView, but that search is // less efficient than just finding the first of possibly multiple @@ -351,36 +327,33 @@ bool Path::hasExtension(const std::string &input) return getFilenameView(input).find('.') != std::string::npos; } -bool Path::extensionMatches(const compat::string_view input, - const compat::string_view extension) +bool Path::extensionMatches(const compat::string_view input, const compat::string_view extension) { auto extensionWithSeparator = getExtensionView(input); - return (!extensionWithSeparator.empty() && - extensionWithSeparator.substr(1) == extension); + return (!extensionWithSeparator.empty() && extensionWithSeparator.substr(1) == extension); } -std::string Path::stripExtension(const std::string &input) +std::string Path::stripExtension(const std::string& input) { - auto pathView = getParentPathView(input); + auto pathView = getParentPathView(input); // Make sure the returned string will have room for the directory // separator between the parent path and the stem, but only where // it is needed. size_t pathLength = pathView.empty() ? 0 : pathView.length() + 1; auto stemView = getStemView(input); - return std::string(std::begin(input), - std::begin(input) + pathLength + stemView.length()); + return std::string(std::begin(input), std::begin(input) + pathLength + stemView.length()); } -std::string Path::concatenateBeforeExtension(const std::string &input, const std::string &stringToAdd) +std::string Path::concatenateBeforeExtension(const std::string& input, const std::string& stringToAdd) { std::string output = stripExtension(input); output += stringToAdd; - auto extensionView = getExtensionView(input); + auto extensionView = getExtensionView(input); output.append(std::begin(extensionView), std::end(extensionView)); return output; } -std::string Path::normalize(const std::string &path) +std::string Path::normalize(const std::string& path) { std::string result(path); #if DIR_SEPARATOR != '/' @@ -389,14 +362,14 @@ std::string Path::normalize(const std::string &path) return result; } -const char *Path::stripSourcePrefix(const char *path) +const char* Path::stripSourcePrefix(const char* path) { - const char *fallback = path; - const char *sep = path + std::strlen(path); + const char* fallback = path; + const char* sep = path + std::strlen(path); bool gromacsSubdirFound = false; while (sep > path) { - const char *prevSep = sep - 1; + const char* prevSep = sep - 1; while (prevSep >= path && !isDirSeparator(*prevSep)) { --prevSep; @@ -425,12 +398,12 @@ const char *Path::stripSourcePrefix(const char *path) return fallback; } -bool Path::exists(const char *path) +bool Path::exists(const char* path) { return gmx_fexist(path); } -bool Path::exists(const std::string &path) +bool Path::exists(const std::string& path) { return exists(path.c_str()); } @@ -443,8 +416,7 @@ std::string Path::getWorkingDirectory() return cwd; } -void Path::splitPathEnvironment(const std::string &pathEnv, - std::vector *result) +void Path::splitPathEnvironment(const std::string& pathEnv, std::vector* result) { size_t prevPos = 0; size_t separator; @@ -453,8 +425,7 @@ void Path::splitPathEnvironment(const std::string &pathEnv, separator = pathEnv.find(cPathSeparator, prevPos); result->push_back(pathEnv.substr(prevPos, separator - prevPos)); prevPos = separator + 1; - } - while (separator != std::string::npos); + } while (separator != std::string::npos); } std::vector Path::getExecutablePaths() @@ -464,7 +435,7 @@ std::vector Path::getExecutablePaths() // Add the local dir since it is not in the path on Windows. result.push_back(""); #endif - const char *path = std::getenv("PATH"); + const char* path = std::getenv("PATH"); if (path != nullptr) { splitPathEnvironment(path, &result); @@ -472,16 +443,16 @@ std::vector Path::getExecutablePaths() return result; } -std::string Path::resolveSymlinks(const std::string &path) +std::string Path::resolveSymlinks(const std::string& path) { /* Does not fully resolve the path like realpath/boost::canonical would. * It doesn't resolve path elements (including "." or ".."), but only * resolves the entire path (it does that recursively). */ std::string result(path); #if !GMX_NATIVE_WINDOWS - char buf[GMX_PATH_MAX]; - int length; - while ((length = readlink(result.c_str(), buf, sizeof(buf)-1)) > 0) + char buf[GMX_PATH_MAX]; + int length; + while ((length = readlink(result.c_str(), buf, sizeof(buf) - 1)) > 0) { buf[length] = '\0'; if (isAbsolute(buf)) @@ -501,43 +472,38 @@ std::string Path::resolveSymlinks(const std::string &path) * File */ -void File::returnFalseOnError(const NotFoundInfo & /*info*/) -{ -} +void File::returnFalseOnError(const NotFoundInfo& /*info*/) {} -void File::throwOnError(const NotFoundInfo &info) +void File::throwOnError(const NotFoundInfo& info) { if (info.wasError) { - const std::string message - = formatString("Failed to access file '%s'.\n%s", - info.filename, info.message); + const std::string message = + formatString("Failed to access file '%s'.\n%s", info.filename, info.message); GMX_THROW_WITH_ERRNO(FileIOError(message), info.call, info.err); } } -void File::throwOnNotFound(const NotFoundInfo &info) +void File::throwOnNotFound(const NotFoundInfo& info) { throwOnError(info); - const std::string message - = formatString("File '%s' does not exist or is not accessible.\n%s", - info.filename, info.message); + const std::string message = formatString("File '%s' does not exist or is not accessible.\n%s", + info.filename, info.message); GMX_THROW_WITH_ERRNO(InvalidInputError(message), info.call, info.err); } // static -bool File::exists(const char *filename, NotFoundHandler onNotFound) +bool File::exists(const char* filename, NotFoundHandler onNotFound) { if (filename == nullptr) { return false; } - FILE *test = std::fopen(filename, "r"); + FILE* test = std::fopen(filename, "r"); if (test == nullptr) { const bool wasError = (errno != ENOENT && errno != ENOTDIR); - NotFoundInfo info(filename, "The file could not be opened.", - "fopen", wasError, errno); + NotFoundInfo info(filename, "The file could not be opened.", "fopen", wasError, errno); onNotFound(info); return false; } @@ -551,15 +517,13 @@ bool File::exists(const char *filename, NotFoundHandler onNotFound) int status = stat(filename, &st_buf); if (status != 0) { - NotFoundInfo info(filename, "File information could not be read.", - "stat", true, errno); + NotFoundInfo info(filename, "File information could not be read.", "stat", true, errno); onNotFound(info); return false; } if (!S_ISREG(st_buf.st_mode)) { - NotFoundInfo info(filename, "The file is not a regular file.", - nullptr, true, 0); + NotFoundInfo info(filename, "The file is not a regular file.", nullptr, true, 0); onNotFound(info); return false; } @@ -569,7 +533,7 @@ bool File::exists(const char *filename, NotFoundHandler onNotFound) } // static -bool File::exists(const std::string &filename, NotFoundHandler onNotFound) +bool File::exists(const std::string& filename, NotFoundHandler onNotFound) { return exists(filename.c_str(), onNotFound); } @@ -578,7 +542,7 @@ bool File::exists(const std::string &filename, NotFoundHandler onNotFound) * Directory */ -int Directory::create(const char *path) +int Directory::create(const char* path) { if (Directory::exists(path)) { @@ -597,13 +561,13 @@ int Directory::create(const char *path) } -int Directory::create(const std::string &path) +int Directory::create(const std::string& path) { return create(path.c_str()); } -bool Directory::exists(const char *path) +bool Directory::exists(const char* path) { struct stat info; if (stat(path, &info) != 0) @@ -622,7 +586,7 @@ bool Directory::exists(const char *path) } -bool Directory::exists(const std::string &path) +bool Directory::exists(const std::string& path) { return exists(path.c_str()); } diff --git a/src/gromacs/utility/path.h b/src/gromacs/utility/path.h index 99422bd453..f203e96b7b 100644 --- a/src/gromacs/utility/path.h +++ b/src/gromacs/utility/path.h @@ -54,119 +54,113 @@ namespace gmx class Path { - public: - static bool containsDirectory(const std::string &path); - static bool isAbsolute(const char *path); - static bool isAbsolute(const std::string &path); - static bool isEquivalent(const std::string &path1, - const std::string &path2); - - static std::string join(const std::string &path1, - const std::string &path2); - static std::string join(const std::string &path1, - const std::string &path2, - const std::string &path3); - //! Return a path using directory separators that suit the execution OS. - static std::string normalize(const std::string &path); - /*! \brief Returns a copy of the parent path (ie. directory - * components) of \c input ie. up to but excluding the last - * directory separator (if one exists). - * - * \returns A copy of the parent path-components, or empty if - * no directory separator exists. */ - static std::string getParentPath(const std::string &input); - /*! \brief Returns a copy of the filename in \c input - * ie. after the last directory separator (if one exists). */ - static std::string getFilename(const std::string &input); - //! Returns whether an extension is present in \c input. - static bool hasExtension(const std::string &input); - /*! \brief Returns whether the extension present in \c input - * matches \c extension (which does not include the separator - * character). */ - static bool extensionMatches(compat::string_view input, - compat::string_view extension); - /*! \brief Returns a copy of the input without any trailing - * extension found in the filename component. */ - static std::string stripExtension(const std::string &input); - /*! \brief Concatenate \c stringToAdd to a copy of \c input, - * before any file extension (if one exists), and return the - * result. */ - static std::string concatenateBeforeExtension(const std::string &input, - const std::string &stringToAdd); - - static const char *stripSourcePrefix(const char *path); - - static bool exists(const char *path); - static bool exists(const std::string &path); - static std::string getWorkingDirectory(); - - static void splitPathEnvironment(const std::string &pathEnv, - std::vector *result); - static std::vector getExecutablePaths(); - - static std::string resolveSymlinks(const std::string &path); - - private: - // Disallow instantiation. - Path(); +public: + static bool containsDirectory(const std::string& path); + static bool isAbsolute(const char* path); + static bool isAbsolute(const std::string& path); + static bool isEquivalent(const std::string& path1, const std::string& path2); + + static std::string join(const std::string& path1, const std::string& path2); + static std::string join(const std::string& path1, const std::string& path2, const std::string& path3); + //! Return a path using directory separators that suit the execution OS. + static std::string normalize(const std::string& path); + /*! \brief Returns a copy of the parent path (ie. directory + * components) of \c input ie. up to but excluding the last + * directory separator (if one exists). + * + * \returns A copy of the parent path-components, or empty if + * no directory separator exists. */ + static std::string getParentPath(const std::string& input); + /*! \brief Returns a copy of the filename in \c input + * ie. after the last directory separator (if one exists). */ + static std::string getFilename(const std::string& input); + //! Returns whether an extension is present in \c input. + static bool hasExtension(const std::string& input); + /*! \brief Returns whether the extension present in \c input + * matches \c extension (which does not include the separator + * character). */ + static bool extensionMatches(compat::string_view input, compat::string_view extension); + /*! \brief Returns a copy of the input without any trailing + * extension found in the filename component. */ + static std::string stripExtension(const std::string& input); + /*! \brief Concatenate \c stringToAdd to a copy of \c input, + * before any file extension (if one exists), and return the + * result. */ + static std::string concatenateBeforeExtension(const std::string& input, const std::string& stringToAdd); + + static const char* stripSourcePrefix(const char* path); + + static bool exists(const char* path); + static bool exists(const std::string& path); + static std::string getWorkingDirectory(); + + static void splitPathEnvironment(const std::string& pathEnv, std::vector* result); + static std::vector getExecutablePaths(); + + static std::string resolveSymlinks(const std::string& path); + +private: + // Disallow instantiation. + Path(); }; class File { - public: - struct NotFoundInfo +public: + struct NotFoundInfo + { + NotFoundInfo(const char* filename, const char* message, const char* call, bool wasError, int err) : + filename(filename), + message(message), + call(call), + wasError(wasError), + err(err) { - NotFoundInfo(const char *filename, const char *message, - const char *call, bool wasError, int err) - : filename(filename), message(message), call(call), - wasError(wasError), err(err) - { - } - - const char *filename; - const char *message; - const char *call; - bool wasError; - int err; - }; - - static void returnFalseOnError(const NotFoundInfo &info); - static void throwOnError(const NotFoundInfo &info); - [[ noreturn ]] static void throwOnNotFound(const NotFoundInfo &info); - - typedef void (*NotFoundHandler)(const NotFoundInfo &info); - - /*! \brief - * Checks whether a file exists and is a regular file. - * - * \param[in] filename Path to the file to check. - * \param[in] onNotFound Function to call when the file does not - * exists or there is an error accessing it. - * \returns `true` if \p filename exists and is accessible. - * - * Does not throw, unless onNotFound throws. - */ - static bool exists(const char *filename, NotFoundHandler onNotFound); - //! \copydoc exists(const char *, NotFoundHandler) - static bool exists(const std::string &filename, - NotFoundHandler onNotFound); - - private: - // Disallow instantiation. - File(); + } + + const char* filename; + const char* message; + const char* call; + bool wasError; + int err; + }; + + static void returnFalseOnError(const NotFoundInfo& info); + static void throwOnError(const NotFoundInfo& info); + [[noreturn]] static void throwOnNotFound(const NotFoundInfo& info); + + typedef void (*NotFoundHandler)(const NotFoundInfo& info); + + /*! \brief + * Checks whether a file exists and is a regular file. + * + * \param[in] filename Path to the file to check. + * \param[in] onNotFound Function to call when the file does not + * exists or there is an error accessing it. + * \returns `true` if \p filename exists and is accessible. + * + * Does not throw, unless onNotFound throws. + */ + static bool exists(const char* filename, NotFoundHandler onNotFound); + //! \copydoc exists(const char *, NotFoundHandler) + static bool exists(const std::string& filename, NotFoundHandler onNotFound); + +private: + // Disallow instantiation. + File(); }; class Directory { - public: - static int create(const char *path); - static int create(const std::string &path); - static bool exists(const char *path); - static bool exists(const std::string &path); - - private: - // Disallow instantiation. - Directory(); +public: + static int create(const char* path); + static int create(const std::string& path); + static bool exists(const char* path); + static bool exists(const std::string& path); + +private: + // Disallow instantiation. + Directory(); }; } // namespace gmx diff --git a/src/gromacs/utility/physicalnodecommunicator.cpp b/src/gromacs/utility/physicalnodecommunicator.cpp index 703f5d5643..827a9bf301 100644 --- a/src/gromacs/utility/physicalnodecommunicator.cpp +++ b/src/gromacs/utility/physicalnodecommunicator.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,8 +50,7 @@ namespace gmx { -void -MPI_Comm_free_wrapper(MPI_Comm *comm) +void MPI_Comm_free_wrapper(MPI_Comm* comm) { #if GMX_MPI // With thread-MPI *comm is shared between ranks which causes issues with @@ -124,4 +123,4 @@ void PhysicalNodeCommunicator::barrier() const #endif } -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/utility/physicalnodecommunicator.h b/src/gromacs/utility/physicalnodecommunicator.h index a85d987750..7d57eefe39 100644 --- a/src/gromacs/utility/physicalnodecommunicator.h +++ b/src/gromacs/utility/physicalnodecommunicator.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,8 +52,7 @@ namespace gmx * * This is needed to discard the return value so it can be used as a * deleter by a smart pointer. */ -void -MPI_Comm_free_wrapper(MPI_Comm *comm); +void MPI_Comm_free_wrapper(MPI_Comm* comm); //! Make a smart pointer for MPI communicators. using MPI_Comm_ptr = gmx::unique_cptr; @@ -66,24 +65,24 @@ using MPI_Comm_ptr = gmx::unique_cptr; * suited for general-purpose communication. */ class PhysicalNodeCommunicator { - public: - /*! \brief Constructor. - * - * Communicates within \c world to make intra-communicator \c - * comm_ between all ranks that share \c physicalNodeId. */ - PhysicalNodeCommunicator(MPI_Comm world, int physicalNodeId); - //! Communicator for all ranks on this physical node - MPI_Comm comm_; - //! Number of ranks on this physical node, corresponds to MPI_Comm_size of comm. - int size_; - //! Rank ID within this physical node, corresponds to MPI_Comm_rank of comm. - int rank_; - //! RAII handler for cleaning up \c comm_ only when appropriate. - MPI_Comm_ptr commGuard_; - //! Creates a barrier for all ranks on this physical node. - void barrier() const; +public: + /*! \brief Constructor. + * + * Communicates within \c world to make intra-communicator \c + * comm_ between all ranks that share \c physicalNodeId. */ + PhysicalNodeCommunicator(MPI_Comm world, int physicalNodeId); + //! Communicator for all ranks on this physical node + MPI_Comm comm_; + //! Number of ranks on this physical node, corresponds to MPI_Comm_size of comm. + int size_; + //! Rank ID within this physical node, corresponds to MPI_Comm_rank of comm. + int rank_; + //! RAII handler for cleaning up \c comm_ only when appropriate. + MPI_Comm_ptr commGuard_; + //! Creates a barrier for all ranks on this physical node. + void barrier() const; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/utility/pleasecite.cpp b/src/gromacs/utility/pleasecite.cpp index 23b96e7e73..4c0b71b390 100644 --- a/src/gromacs/utility/pleasecite.cpp +++ b/src/gromacs/utility/pleasecite.cpp @@ -46,349 +46,258 @@ #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" -typedef struct { - const char *key; - const char *author; - const char *title; - const char *journal; +typedef struct +{ + const char* key; + const char* author; + const char* title; + const char* journal; int volume, year; - const char *pages; + const char* pages; } t_citerec; -void please_cite(FILE *fp, const char *key) +void please_cite(FILE* fp, const char* key) { static const t_citerec citedb[] = { - { "Allen1987a", - "M. P. Allen and D. J. Tildesley", - "Computer simulation of liquids", - "Oxford Science Publications", - 1, 1987, "1" }, - { "Berendsen95a", - "H. J. C. Berendsen, D. van der Spoel and R. van Drunen", + { "Allen1987a", "M. P. Allen and D. J. Tildesley", "Computer simulation of liquids", + "Oxford Science Publications", 1, 1987, "1" }, + { "Berendsen95a", "H. J. C. Berendsen, D. van der Spoel and R. van Drunen", "GROMACS: A message-passing parallel molecular dynamics implementation", - "Comp. Phys. Comm.", - 91, 1995, "43-56" }, - { "Berendsen84a", - "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak", - "Molecular dynamics with coupling to an external bath", - "J. Chem. Phys.", - 81, 1984, "3684-3690" }, - { "Ryckaert77a", - "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen", - "Numerical Integration of the Cartesian Equations of Motion of a System with Constraints; Molecular Dynamics of n-Alkanes", - "J. Comp. Phys.", - 23, 1977, "327-341" }, - { "Miyamoto92a", - "S. Miyamoto and P. A. Kollman", + "Comp. Phys. Comm.", 91, 1995, "43-56" }, + { "Berendsen84a", "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak", + "Molecular dynamics with coupling to an external bath", "J. Chem. Phys.", 81, 1984, + "3684-3690" }, + { "Ryckaert77a", "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen", + "Numerical Integration of the Cartesian Equations of Motion of a System with " + "Constraints; Molecular Dynamics of n-Alkanes", + "J. Comp. Phys.", 23, 1977, "327-341" }, + { "Miyamoto92a", "S. Miyamoto and P. A. Kollman", "SETTLE: An Analytical Version of the SHAKE and RATTLE Algorithms for Rigid Water Models", - "J. Comp. Chem.", - 13, 1992, "952-962" }, - { "Cromer1968a", - "D. T. Cromer & J. B. Mann", + "J. Comp. Chem.", 13, 1992, "952-962" }, + { "Cromer1968a", "D. T. Cromer & J. B. Mann", "X-ray scattering factors computed from numerical Hartree-Fock wave functions", - "Acta Cryst. A", - 24, 1968, "321" }, - { "Barth95a", - "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel", - "Algorithms for Constrained Molecular Dynamics", - "J. Comp. Chem.", - 16, 1995, "1192-1209" }, + "Acta Cryst. A", 24, 1968, "321" }, + { "Barth95a", "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel", + "Algorithms for Constrained Molecular Dynamics", "J. Comp. Chem.", 16, 1995, "1192-1209" }, { "Essmann95a", "U. Essmann, L. Perera, M. L. Berkowitz, T. Darden, H. Lee and L. G. Pedersen ", - "A smooth particle mesh Ewald method", - "J. Chem. Phys.", - 103, 1995, "8577-8592" }, - { "Torda89a", - "A. E. Torda and R. M. Scheek and W. F. van Gunsteren", + "A smooth particle mesh Ewald method", "J. Chem. Phys.", 103, 1995, "8577-8592" }, + { "Torda89a", "A. E. Torda and R. M. Scheek and W. F. van Gunsteren", "Time-dependent distance restraints in molecular dynamics simulations", - "Chem. Phys. Lett.", - 157, 1989, "289-294" }, - { "Tironi95a", - "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren", - "Generalized reaction field method for molecular dynamics simulations", - "J. Chem. Phys", + "Chem. Phys. Lett.", 157, 1989, "289-294" }, + { "Tironi95a", "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren", + "Generalized reaction field method for molecular dynamics simulations", "J. Chem. Phys", 102, 1995, "5451-5459" }, - { "Hess97a", - "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije", - "LINCS: A Linear Constraint Solver for molecular simulations", - "J. Comp. Chem.", - 18, 1997, "1463-1472" }, - { "Hess2008a", - "B. Hess", + { "Hess97a", "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije", + "LINCS: A Linear Constraint Solver for molecular simulations", "J. Comp. Chem.", 18, 1997, + "1463-1472" }, + { "Hess2008a", "B. Hess", "P-LINCS: A Parallel Linear Constraint Solver for molecular simulation", - "J. Chem. Theory Comput.", - 4, 2008, "116-122" }, - { "Hess2008b", - "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl", - "GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular simulation", - "J. Chem. Theory Comput.", - 4, 2008, "435-447" }, - { "Hub2010", - "J. S. Hub, B. L. de Groot and D. van der Spoel", - "g_wham - A free weighted histogram analysis implementation including robust error and autocorrelation estimates", - "J. Chem. Theory Comput.", - 6, 2010, "3713-3720"}, - { "In-Chul99a", - "Y. In-Chul and M. L. Berkowitz", - "Ewald summation for systems with slab geometry", - "J. Chem. Phys.", - 111, 1999, "3155-3162" }, + "J. Chem. Theory Comput.", 4, 2008, "116-122" }, + { "Hess2008b", "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl", + "GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular " + "simulation", + "J. Chem. Theory Comput.", 4, 2008, "435-447" }, + { "Hub2010", "J. S. Hub, B. L. de Groot and D. van der Spoel", + "g_wham - A free weighted histogram analysis implementation including robust error and " + "autocorrelation estimates", + "J. Chem. Theory Comput.", 6, 2010, "3713-3720" }, + { "In-Chul99a", "Y. In-Chul and M. L. Berkowitz", + "Ewald summation for systems with slab geometry", "J. Chem. Phys.", 111, 1999, + "3155-3162" }, { "DeGroot97a", - "B. L. de Groot and D. M. F. van Aalten and R. M. Scheek and A. Amadei and G. Vriend and H. J. C. Berendsen", - "Prediction of Protein Conformational Freedom From Distance Constrains", - "Proteins", - 29, 1997, "240-251" }, - { "Spoel98a", - "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen", - "A systematic study of water models for molecular simulation. Derivation of models optimized for use with a reaction-field.", - "J. Chem. Phys.", - 108, 1998, "10220-10230" }, - { "Wishart98a", - "D. S. Wishart and A. M. Nip", - "Protein Chemical Shift Analysis: A Practical Guide", - "Biochem. Cell Biol.", - 76, 1998, "153-163" }, - { "Maiorov95", - "V. N. Maiorov and G. M. Crippen", + "B. L. de Groot and D. M. F. van Aalten and R. M. Scheek and A. Amadei and G. Vriend and " + "H. J. C. Berendsen", + "Prediction of Protein Conformational Freedom From Distance Constrains", "Proteins", 29, + 1997, "240-251" }, + { "Spoel98a", "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen", + "A systematic study of water models for molecular simulation. Derivation of models " + "optimized for use with a reaction-field.", + "J. Chem. Phys.", 108, 1998, "10220-10230" }, + { "Wishart98a", "D. S. Wishart and A. M. Nip", + "Protein Chemical Shift Analysis: A Practical Guide", "Biochem. Cell Biol.", 76, 1998, + "153-163" }, + { "Maiorov95", "V. N. Maiorov and G. M. Crippen", "Size-Independent Comparison of Protein Three-Dimensional Structures", - "PROTEINS: Struct. Funct. Gen.", - 22, 1995, "273-283" }, - { "Feenstra99", - "K. A. Feenstra and B. Hess and H. J. C. Berendsen", - "Improving Efficiency of Large Time-scale Molecular Dynamics Simulations of Hydrogen-rich Systems", - "J. Comput. Chem.", - 20, 1999, "786-798" }, + "PROTEINS: Struct. Funct. Gen.", 22, 1995, "273-283" }, + { "Feenstra99", "K. A. Feenstra and B. Hess and H. J. C. Berendsen", + "Improving Efficiency of Large Time-scale Molecular Dynamics Simulations of " + "Hydrogen-rich Systems", + "J. Comput. Chem.", 20, 1999, "786-798" }, { "Lourenco2013a", - "Tuanan C. Lourenco and Mariny F. C. Coelho and Teodorico C. Ramalho and David van der Spoel and Luciano T. Costa", - "Insights on the Solubility of CO2 in 1-Ethyl-3-methylimidazolium Bis(trifluoromethylsulfonyl)imide from the Microscopic Point of View", - "Environ. Sci. Technol.", - 47, 2013, "7421-7429" }, - { "Timneanu2004a", - "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel", - "Auger Electron Cascades in Water and Ice", - "Chem. Phys.", - 299, 2004, "277-283" }, - { "Pascal2011a", - "T. A. Pascal and S. T. Lin and W. A. Goddard III", - "Thermodynamics of liquids: standard molar entropies and heat capacities of common solvents from 2PT molecular dynamics", - "Phys. Chem. Chem. Phys.", - 13, 2011, "169-181" }, - { "Caleman2008a", - "C. Caleman and D. van der Spoel", + "Tuanan C. Lourenco and Mariny F. C. Coelho and Teodorico C. Ramalho and David van der " + "Spoel and Luciano T. Costa", + "Insights on the Solubility of CO2 in 1-Ethyl-3-methylimidazolium " + "Bis(trifluoromethylsulfonyl)imide from the Microscopic Point of View", + "Environ. Sci. Technol.", 47, 2013, "7421-7429" }, + { "Timneanu2004a", "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel", + "Auger Electron Cascades in Water and Ice", "Chem. Phys.", 299, 2004, "277-283" }, + { "Pascal2011a", "T. A. Pascal and S. T. Lin and W. A. Goddard III", + "Thermodynamics of liquids: standard molar entropies and heat capacities of common " + "solvents from 2PT molecular dynamics", + "Phys. Chem. Chem. Phys.", 13, 2011, "169-181" }, + { "Caleman2008a", "C. Caleman and D. van der Spoel", "Picosecond Melting of Ice by an Infrared Laser Pulse: A Simulation Study", - "Angew. Chem. Int. Ed", - 47, 2008, "1417-1420" }, + "Angew. Chem. Int. Ed", 47, 2008, "1417-1420" }, { "Caleman2011b", - "C. Caleman and P. J. van Maaren and M. Hong and J. S. Hub and L. T. da Costa and D. van der Spoel", - "Force Field Benchmark of Organic Liquids: Density, Enthalpy of Vaporization, Heat Capacities, Surface Tension, Isothermal Compressibility, Volumetric Expansion Coefficient, and Dielectric Constant", - "J. Chem. Theo. Comp.", - 8, 2012, "61" }, - { "Lindahl2001a", - "E. Lindahl and B. Hess and D. van der Spoel", - "GROMACS 3.0: A package for molecular simulation and trajectory analysis", - "J. Mol. Mod.", + "C. Caleman and P. J. van Maaren and M. Hong and J. S. Hub and L. T. da Costa and D. van " + "der Spoel", + "Force Field Benchmark of Organic Liquids: Density, Enthalpy of Vaporization, Heat " + "Capacities, Surface Tension, Isothermal Compressibility, Volumetric Expansion " + "Coefficient, and Dielectric Constant", + "J. Chem. Theo. Comp.", 8, 2012, "61" }, + { "Lindahl2001a", "E. Lindahl and B. Hess and D. van der Spoel", + "GROMACS 3.0: A package for molecular simulation and trajectory analysis", "J. Mol. Mod.", 7, 2001, "306-317" }, - { "Wang2001a", - "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman", - "Solvation model based on weighted solvent accessible surface area", - "J. Phys. Chem. B", + { "Wang2001a", "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman", + "Solvation model based on weighted solvent accessible surface area", "J. Phys. Chem. B", 105, 2001, "5055-5067" }, - { "Eisenberg86a", - "D. Eisenberg and A. D. McLachlan", - "Solvation energy in protein folding and binding", - "Nature", - 319, 1986, "199-203" }, - { "Bondi1964a", - "A. Bondi", - "van der Waals Volumes and Radii", - "J. Phys. Chem.", - 68, 1964, "441-451" }, + { "Eisenberg86a", "D. Eisenberg and A. D. McLachlan", + "Solvation energy in protein folding and binding", "Nature", 319, 1986, "199-203" }, + { "Bondi1964a", "A. Bondi", "van der Waals Volumes and Radii", "J. Phys. Chem.", 68, 1964, + "441-451" }, { "Eisenhaber95", - "Frank Eisenhaber and Philip Lijnzaad and Patrick Argos and Chris Sander and Michael Scharf", - "The Double Cube Lattice Method: Efficient Approaches to Numerical Integration of Surface Area and Volume and to Dot Surface Contouring of Molecular Assemblies", - "J. Comp. Chem.", - 16, 1995, "273-284" }, - { "Hess2002", - "B. Hess, H. Saint-Martin and H.J.C. Berendsen", - "Flexible constraints: an adiabatic treatment of quantum degrees of freedom, with application to the flexible and polarizable MCDHO model for water", - "J. Chem. Phys.", - 116, 2002, "9602-9610" }, - { "Hess2003", - "B. Hess and R.M. Scheek", - "Orientation restraints in molecular dynamics simulations using time and ensemble averaging", - "J. Magn. Res.", - 164, 2003, "19-27" }, - { "Rappe1991a", - "A. K. Rappe and W. A. Goddard III", - "Charge Equillibration for Molecular Dynamics Simulations", - "J. Phys. Chem.", - 95, 1991, "3358-3363" }, - { "Mu2005a", - "Y. Mu, P. H. Nguyen and G. Stock", - "Energy landscape of a small peptide revelaed by dihedral angle principal component analysis", - "Prot. Struct. Funct. Bioinf.", - 58, 2005, "45-52" }, - { "Okabe2001a", - "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami", + "Frank Eisenhaber and Philip Lijnzaad and Patrick Argos and Chris Sander and Michael " + "Scharf", + "The Double Cube Lattice Method: Efficient Approaches to Numerical Integration of " + "Surface Area and Volume and to Dot Surface Contouring of Molecular Assemblies", + "J. Comp. Chem.", 16, 1995, "273-284" }, + { "Hess2002", "B. Hess, H. Saint-Martin and H.J.C. Berendsen", + "Flexible constraints: an adiabatic treatment of quantum degrees of freedom, with " + "application to the flexible and polarizable MCDHO model for water", + "J. Chem. Phys.", 116, 2002, "9602-9610" }, + { "Hess2003", "B. Hess and R.M. Scheek", + "Orientation restraints in molecular dynamics simulations using time and ensemble " + "averaging", + "J. Magn. Res.", 164, 2003, "19-27" }, + { "Rappe1991a", "A. K. Rappe and W. A. Goddard III", + "Charge Equillibration for Molecular Dynamics Simulations", "J. Phys. Chem.", 95, 1991, + "3358-3363" }, + { "Mu2005a", "Y. Mu, P. H. Nguyen and G. Stock", + "Energy landscape of a small peptide revelaed by dihedral angle principal component " + "analysis", + "Prot. Struct. Funct. Bioinf.", 58, 2005, "45-52" }, + { "Okabe2001a", "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami", "Replica-exchange {M}onte {C}arlo method for the isobaric-isothermal ensemble", - "Chem. Phys. Lett.", - 335, 2001, "435-439" }, - { "Hukushima96a", - "K. Hukushima and K. Nemoto", + "Chem. Phys. Lett.", 335, 2001, "435-439" }, + { "Hukushima96a", "K. Hukushima and K. Nemoto", "Exchange Monte Carlo Method and Application to Spin Glass Simulations", - "J. Phys. Soc. Jpn.", - 65, 1996, "1604-1608" }, - { "Tropp80a", - "J. Tropp", - "Dipolar Relaxation and Nuclear Overhauser effects in nonrigid molecules: The effect of fluctuating internuclear distances", - "J. Chem. Phys.", - 72, 1980, "6035-6043" }, + "J. Phys. Soc. Jpn.", 65, 1996, "1604-1608" }, + { "Tropp80a", "J. Tropp", + "Dipolar Relaxation and Nuclear Overhauser effects in nonrigid molecules: The effect of " + "fluctuating internuclear distances", + "J. Chem. Phys.", 72, 1980, "6035-6043" }, { "Bultinck2002a", - "P. Bultinck and W. Langenaeker and P. Lahorte and F. De Proft and P. Geerlings and M. Waroquier and J. P. Tollenaere", - "The electronegativity equalization method I: Parametrization and validation for atomic charge calculations", - "J. Phys. Chem. A", - 106, 2002, "7887-7894" }, - { "Yang2006b", - "Q. Y. Yang and K. A. Sharp", - "Atomic charge parameters for the finite difference Poisson-Boltzmann method using electronegativity neutralization", - "J. Chem. Theory Comput.", - 2, 2006, "1152-1167" }, + "P. Bultinck and W. Langenaeker and P. Lahorte and F. De Proft and P. Geerlings and M. " + "Waroquier and J. P. Tollenaere", + "The electronegativity equalization method I: Parametrization and validation for atomic " + "charge calculations", + "J. Phys. Chem. A", 106, 2002, "7887-7894" }, + { "Yang2006b", "Q. Y. Yang and K. A. Sharp", + "Atomic charge parameters for the finite difference Poisson-Boltzmann method using " + "electronegativity neutralization", + "J. Chem. Theory Comput.", 2, 2006, "1152-1167" }, { "Spoel2005a", "D. van der Spoel, E. Lindahl, B. Hess, G. Groenhof, A. E. Mark and H. J. C. Berendsen", - "GROMACS: Fast, Flexible and Free", - "J. Comp. Chem.", - 26, 2005, "1701-1719" }, - { "Spoel2006b", - "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu", + "GROMACS: Fast, Flexible and Free", "J. Comp. Chem.", 26, 2005, "1701-1719" }, + { "Spoel2006b", "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu", "Thermodynamics of hydrogen bonding in hydrophilic and hydrophobic media", - "J. Phys. Chem. B", - 110, 2006, "4393-4398" }, - { "Spoel2006d", - "D. van der Spoel and M. M. Seibert", + "J. Phys. Chem. B", 110, 2006, "4393-4398" }, + { "Spoel2006d", "D. van der Spoel and M. M. Seibert", "Protein folding kinetics and thermodynamics from atomistic simulations", - "Phys. Rev. Letters", - 96, 2006, "238102" }, - { "Palmer94a", - "B. J. Palmer", - "Transverse-current autocorrelation-function calculations of the shear viscosity for molecular liquids", - "Phys. Rev. E", - 49, 1994, "359-366" }, - { "Bussi2007a", - "G. Bussi, D. Donadio and M. Parrinello", - "Canonical sampling through velocity rescaling", - "J. Chem. Phys.", - 126, 2007, "014101" }, - { "Hub2006", - "J. S. Hub and B. L. de Groot", - "Does CO2 permeate through Aquaporin-1?", - "Biophys. J.", - 91, 2006, "842-848" }, - { "Hub2008", - "J. S. Hub and B. L. de Groot", - "Mechanism of selectivity in aquaporins and aquaglyceroporins", - "PNAS", - 105, 2008, "1198-1203" }, + "Phys. Rev. Letters", 96, 2006, "238102" }, + { "Palmer94a", "B. J. Palmer", + "Transverse-current autocorrelation-function calculations of the shear viscosity for " + "molecular liquids", + "Phys. Rev. E", 49, 1994, "359-366" }, + { "Bussi2007a", "G. Bussi, D. Donadio and M. Parrinello", + "Canonical sampling through velocity rescaling", "J. Chem. Phys.", 126, 2007, "014101" }, + { "Hub2006", "J. S. Hub and B. L. de Groot", "Does CO2 permeate through Aquaporin-1?", + "Biophys. J.", 91, 2006, "842-848" }, + { "Hub2008", "J. S. Hub and B. L. de Groot", + "Mechanism of selectivity in aquaporins and aquaglyceroporins", "PNAS", 105, 2008, + "1198-1203" }, { "Friedrich2009", - "M. S. Friedrichs, P. Eastman, V. Vaidyanathan, M. Houston, S. LeGrand, A. L. Beberg, D. L. Ensign, C. M. Bruns, and V. S. Pande", + "M. S. Friedrichs, P. Eastman, V. Vaidyanathan, M. Houston, S. LeGrand, A. L. Beberg, D. " + "L. Ensign, C. M. Bruns, and V. S. Pande", "Accelerating Molecular Dynamic Simulation on Graphics Processing Units", - "J. Comp. Chem.", - 30, 2009, "864-872" }, - { "Engin2010", - "O. Engin, A. Villa, M. Sayar and B. Hess", + "J. Comp. Chem.", 30, 2009, "864-872" }, + { "Engin2010", "O. Engin, A. Villa, M. Sayar and B. Hess", "Driving Forces for Adsorption of Amphiphilic Peptides to Air-Water Interface", - "J. Phys. Chem. B", - 114, 2010, "11093" }, - { "Wang2010", - "H. Wang, F. Dommert, C.Holm", - "Optimizing working parameters of the smooth particle mesh Ewald algorithm in terms of accuracy and efficiency", - "J. Chem. Phys. B", - 133, 2010, "034117" }, - { "Sugita1999a", - "Y. Sugita, Y. Okamoto", - "Replica-exchange molecular dynamics method for protein folding", - "Chem. Phys. Lett.", + "J. Phys. Chem. B", 114, 2010, "11093" }, + { "Wang2010", "H. Wang, F. Dommert, C.Holm", + "Optimizing working parameters of the smooth particle mesh Ewald algorithm in terms of " + "accuracy and efficiency", + "J. Chem. Phys. B", 133, 2010, "034117" }, + { "Sugita1999a", "Y. Sugita, Y. Okamoto", + "Replica-exchange molecular dynamics method for protein folding", "Chem. Phys. Lett.", 314, 1999, "141-151" }, - { "Kutzner2011", - "C. Kutzner and J. Czub and H. Grubmuller", - "Keep it Flexible: Driving Macromolecular Rotary Motions in Atomistic Simulations with GROMACS", - "J. Chem. Theory Comput.", - 7, 2011, "1381-1393" }, + { "Kutzner2011", "C. Kutzner and J. Czub and H. Grubmuller", + "Keep it Flexible: Driving Macromolecular Rotary Motions in Atomistic Simulations with " + "GROMACS", + "J. Chem. Theory Comput.", 7, 2011, "1381-1393" }, { "Hoefling2011", "M. Hoefling, N. Lima, D. Haenni, C.A.M. Seidel, B. Schuler, H. Grubmuller", - "Structural Heterogeneity and Quantitative FRET Efficiency Distributions of Polyprolines through a Hybrid Atomistic Simulation and Monte Carlo Approach", - "PLoS ONE", - 6, 2011, "e19791" }, - { "Hockney1988", - "R. W. Hockney and J. W. Eastwood", - "Computer simulation using particles", - "IOP, Bristol", - 1, 1988, "1" }, - { "Ballenegger2012", - "V. Ballenegger, J.J. Cerda, and C. Holm", + "Structural Heterogeneity and Quantitative FRET Efficiency Distributions of Polyprolines " + "through a Hybrid Atomistic Simulation and Monte Carlo Approach", + "PLoS ONE", 6, 2011, "e19791" }, + { "Hockney1988", "R. W. Hockney and J. W. Eastwood", "Computer simulation using particles", + "IOP, Bristol", 1, 1988, "1" }, + { "Ballenegger2012", "V. Ballenegger, J.J. Cerda, and C. Holm", "How to Convert SPME to P3M: Influence Functions and Error Estimates", - "J. Chem. Theory Comput.", - 8, 2012, "936-947" }, + "J. Chem. Theory Comput.", 8, 2012, "936-947" }, { "Garmay2012", "Garmay Yu, Shvetsov A, Karelov D, Lebedev D, Radulescu A, Petukhov M, Isaev-Ivanov V", - "Correlated motion of protein subdomains and large-scale conformational flexibility of RecA protein filament", - "Journal of Physics: Conference Series", - 340, 2012, "012094" }, - { "Kutzner2011b", - "C. Kutzner, H. Grubmuller, B. L. de Groot, and U. Zachariae", - "Computational Electrophysiology: The Molecular Dynamics of Ion Channel Permeation and Selectivity in Atomistic Detail", - "Biophys. J.", - 101, 2011, "809-817"}, + "Correlated motion of protein subdomains and large-scale conformational flexibility of " + "RecA protein filament", + "Journal of Physics: Conference Series", 340, 2012, "012094" }, + { "Kutzner2011b", "C. Kutzner, H. Grubmuller, B. L. de Groot, and U. Zachariae", + "Computational Electrophysiology: The Molecular Dynamics of Ion Channel Permeation and " + "Selectivity in Atomistic Detail", + "Biophys. J.", 101, 2011, "809-817" }, { "Lundborg2014", "M. Lundborg, R. Apostolov, D. Spangberg, A. Gardenas, D. van der Spoel and E. Lindahl", - "An efficient and extensible format, library, and API for binary trajectory data from molecular simulations", - "J. Comput. Chem.", - 35, 2014, "260-269"}, + "An efficient and extensible format, library, and API for binary trajectory data from " + "molecular simulations", + "J. Comput. Chem.", 35, 2014, "260-269" }, { "Goga2012", "N. Goga and A. J. Rzepiela and A. H. de Vries and S. J. Marrink and H. J. C. Berendsen", - "Efficient Algorithms for Langevin and DPD Dynamics", - "J. Chem. Theory Comput.", - 8, 2012, "3637--3649"}, + "Efficient Algorithms for Langevin and DPD Dynamics", "J. Chem. Theory Comput.", 8, 2012, + "3637--3649" }, { "Pronk2013", - "S. Pronk, S. Páll, R. Schulz, P. Larsson, P. Bjelkmar, R. Apostolov, M. R. Shirts, J. C. Smith, P. M. Kasson, D. van der Spoel, B. Hess, and E. Lindahl", - "GROMACS 4.5: a high-throughput and highly parallel open source molecular simulation toolkit", - "Bioinformatics", - 29, 2013, "845-54"}, - { "Pall2015", - "S. Páll, M. J. Abraham, C. Kutzner, B. Hess, E. Lindahl", + "S. Pronk, S. Páll, R. Schulz, P. Larsson, P. Bjelkmar, R. Apostolov, M. R. Shirts, J. " + "C. Smith, P. M. Kasson, D. van der Spoel, B. Hess, and E. Lindahl", + "GROMACS 4.5: a high-throughput and highly parallel open source molecular simulation " + "toolkit", + "Bioinformatics", 29, 2013, "845-54" }, + { "Pall2015", "S. Páll, M. J. Abraham, C. Kutzner, B. Hess, E. Lindahl", "Tackling Exascale Software Challenges in Molecular Dynamics Simulations with GROMACS", - "In S. Markidis & E. Laure (Eds.), Solving Software Challenges for Exascale", - 8759, 2015, "3-27" }, + "In S. Markidis & E. Laure (Eds.), Solving Software Challenges for Exascale", 8759, 2015, + "3-27" }, { "Abraham2015", "M. J. Abraham, T. Murtola, R. Schulz, S. Páll, J. C. Smith, B. Hess, E. Lindahl", - "GROMACS: High performance molecular simulations through multi-level parallelism from laptops to supercomputers", - "SoftwareX", - 1, 2015, "19-25" }, - { "Ballenegger2009", - "V. Ballenegger, A. Arnold, J. J. Cerdà", - "Simulations of non-neutral slab systems with long-range electrostatic interactions in two-dimensional periodic boundary conditions", - "J. Chem. Phys", - 131, 2009, "094107" }, - { "Hub2014a", - "J. S. Hub, B. L. de Groot, H. Grubmueller, G. Groenhof", + "GROMACS: High performance molecular simulations through multi-level parallelism from " + "laptops to supercomputers", + "SoftwareX", 1, 2015, "19-25" }, + { "Ballenegger2009", "V. Ballenegger, A. Arnold, J. J. Cerdà", + "Simulations of non-neutral slab systems with long-range electrostatic interactions in " + "two-dimensional periodic boundary conditions", + "J. Chem. Phys", 131, 2009, "094107" }, + { "Hub2014a", "J. S. Hub, B. L. de Groot, H. Grubmueller, G. Groenhof", "Quantifying Artifacts in Ewald Simulations of Inhomogeneous Systems with a Net Charge", - "J. Chem. Theory Comput.", - 10, 2014, "381-393" }, - { "Spoel2018a", - "D. van der Spoel, M. M. Ghahremanpour, J. Lemkul", + "J. Chem. Theory Comput.", 10, 2014, "381-393" }, + { "Spoel2018a", "D. van der Spoel, M. M. Ghahremanpour, J. Lemkul", "Small Molecule Thermochemistry: A Tool For Empirical Force Field Development", - "J. Phys. Chem. A", - 122, 2018, "8982-8988" }, - { "Lindahl2014", - "V. Lindahl, J. Lidmar, B. Hess", + "J. Phys. Chem. A", 122, 2018, "8982-8988" }, + { "Lindahl2014", "V. Lindahl, J. Lidmar, B. Hess", "Accelerated weight histogram method for exploring free energy landscapes", - "J. Chem. Phys.", - 141, 2014, "044110" }, + "J. Chem. Phys.", 141, 2014, "044110" }, }; #define NSTR static_cast(asize(citedb)) int index; - char *author; - char *title; + char* author; + char* title; #define LINE_WIDTH 79 if (fp == nullptr) @@ -396,10 +305,7 @@ void please_cite(FILE *fp, const char *key) return; } - for (index = 0; index < NSTR && (strcmp(citedb[index].key, key) != 0); index++) - { - ; - } + for (index = 0; index < NSTR && (strcmp(citedb[index].key, key) != 0); index++) {} fprintf(fp, "\n++++ PLEASE READ AND CITE THE FOLLOWING REFERENCE ++++\n"); if (index < NSTR) @@ -407,10 +313,8 @@ void please_cite(FILE *fp, const char *key) /* Insert newlines */ author = wrap_lines(citedb[index].author, LINE_WIDTH, 0, FALSE); title = wrap_lines(citedb[index].title, LINE_WIDTH, 0, FALSE); - fprintf(fp, "%s\n%s\n%s %d (%d) pp. %s\n", - author, title, citedb[index].journal, - citedb[index].volume, citedb[index].year, - citedb[index].pages); + fprintf(fp, "%s\n%s\n%s %d (%d) pp. %s\n", author, title, citedb[index].journal, + citedb[index].volume, citedb[index].year, citedb[index].pages); sfree(author); sfree(title); } @@ -426,8 +330,7 @@ namespace { //! Write a message to \c fp to request citation also of the source-code DOI. -void -writeSourceDoi(FILE *fp) +void writeSourceDoi(FILE* fp) { /* Check if we are in release mode or not. * TODO The check should properly target something else than @@ -455,7 +358,7 @@ writeSourceDoi(FILE *fp) } // namespace -void pleaseCiteGromacs(FILE *fplog) +void pleaseCiteGromacs(FILE* fplog) { if (fplog == nullptr) { diff --git a/src/gromacs/utility/pleasecite.h b/src/gromacs/utility/pleasecite.h index 20de82a252..02e6f5866a 100644 --- a/src/gromacs/utility/pleasecite.h +++ b/src/gromacs/utility/pleasecite.h @@ -48,11 +48,9 @@ #include //! Print a message asking to cite something -void -please_cite(FILE *fp, const char *key); +void please_cite(FILE* fp, const char* key); //! Write to \c fplog to request citation of GROMACS papers and source DOI. -void -pleaseCiteGromacs(FILE *fplog); +void pleaseCiteGromacs(FILE* fplog); #endif diff --git a/src/gromacs/utility/programcontext.cpp b/src/gromacs/utility/programcontext.cpp index 0cae677d3d..c0f7800f8b 100644 --- a/src/gromacs/utility/programcontext.cpp +++ b/src/gromacs/utility/programcontext.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -64,29 +64,29 @@ namespace */ class DefaultProgramContext : public IProgramContext { - public: - DefaultProgramContext() {} +public: + DefaultProgramContext() {} - const char *programName() const override { return "GROMACS"; } - const char *displayName() const override { return "GROMACS"; } - const char *fullBinaryPath() const override { return ""; } - InstallationPrefixInfo installationPrefix() const override - { - return InstallationPrefixInfo("", false); - } - const char *commandLine() const override { return ""; } + const char* programName() const override { return "GROMACS"; } + const char* displayName() const override { return "GROMACS"; } + const char* fullBinaryPath() const override { return ""; } + InstallationPrefixInfo installationPrefix() const override + { + return InstallationPrefixInfo("", false); + } + const char* commandLine() const override { return ""; } }; //! Global program info; stores the object set with setProgramContext(). -const IProgramContext *g_programContext; +const IProgramContext* g_programContext; //! Default program context if nothing is set. -const DefaultProgramContext g_defaultContext; +const DefaultProgramContext g_defaultContext; //! \} -} // namespace +} // namespace -const IProgramContext &getProgramContext() +const IProgramContext& getProgramContext() { if (g_programContext != nullptr) { @@ -95,7 +95,7 @@ const IProgramContext &getProgramContext() return g_defaultContext; } -void setProgramContext(const IProgramContext *programContext) +void setProgramContext(const IProgramContext* programContext) { g_programContext = programContext; } diff --git a/src/gromacs/utility/programcontext.h b/src/gromacs/utility/programcontext.h index 9ac1729936..d681c95c38 100644 --- a/src/gromacs/utility/programcontext.h +++ b/src/gromacs/utility/programcontext.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,10 +58,7 @@ namespace gmx struct InstallationPrefixInfo { //! Initializes the structure with given values. - InstallationPrefixInfo(const char *path, bool bSource) - : path(path), bSourceLayout(bSource) - { - } + InstallationPrefixInfo(const char* path, bool bSource) : path(path), bSourceLayout(bSource) {} /*! \brief * Path to the installation prefix of the current \Gromacs instance. @@ -70,7 +67,7 @@ struct InstallationPrefixInfo * install tree and \Gromacs functions that access such files may fail. * This can also contain a path to the source tree (see \a bSourceLayout). */ - const char *const path; + const char* const path; /*! \brief * Whether \a path points to a source tree -like layout. * @@ -80,7 +77,7 @@ struct InstallationPrefixInfo * should be searched using the layout of the source tree instead of the * installation. */ - const bool bSourceLayout; + const bool bSourceLayout; }; @@ -111,60 +108,60 @@ struct InstallationPrefixInfo */ class IProgramContext { - public: - /*! \brief - * Returns the name of the binary as it was invoked without any path. - * - * This is typically `argv[0]` with any leading directory stripped. - * Currently, this should be a valid file name. - */ - virtual const char *programName() const = 0; - /*! \brief - * Returns a display name for the program. - * - * For simple programs, this can equal programName(). For the \Gromacs - * `gmx` wrapper binary, this includes the name of the module (e.g., - * `gmx angle`). This is used only for informational purposes, and - * there are no constraints on contents, except that it should not be - * `NULL`. - */ - virtual const char *displayName() const = 0; - /*! \brief - * Returns the full path of the running binary. - * - * This is mainly used for informational purposes. There are no - * constraints on contents, except that it should not be `NULL`. - * Currently, this is also used for sanity checks in checkpointing. - * - * The implementation can provide an empty string if the path to the - * binary is not available. In such a case, the information is not - * shown. - */ - virtual const char *fullBinaryPath() const = 0; - /*! \brief - * Returns the installation prefix for \Gromacs. - * - * This path is used to locate the data files that are in `share/top/` - * in the source directory. - * The implementation can provide an empty string if the path is not - * available; in such a case, functions that require data files may - * fail. - * - * The returned structure also contains a flag to indicate whether the - * prefix actually points to the source tree. This is used for tests - * and to support running binaries directly from the build tree. - */ - virtual InstallationPrefixInfo installationPrefix() const = 0; - /*! \brief - * Returns the full command line used to invoke the binary. - * - * The implementation can provide an empty string if no command line is - * available. - */ - virtual const char *commandLine() const = 0; +public: + /*! \brief + * Returns the name of the binary as it was invoked without any path. + * + * This is typically `argv[0]` with any leading directory stripped. + * Currently, this should be a valid file name. + */ + virtual const char* programName() const = 0; + /*! \brief + * Returns a display name for the program. + * + * For simple programs, this can equal programName(). For the \Gromacs + * `gmx` wrapper binary, this includes the name of the module (e.g., + * `gmx angle`). This is used only for informational purposes, and + * there are no constraints on contents, except that it should not be + * `NULL`. + */ + virtual const char* displayName() const = 0; + /*! \brief + * Returns the full path of the running binary. + * + * This is mainly used for informational purposes. There are no + * constraints on contents, except that it should not be `NULL`. + * Currently, this is also used for sanity checks in checkpointing. + * + * The implementation can provide an empty string if the path to the + * binary is not available. In such a case, the information is not + * shown. + */ + virtual const char* fullBinaryPath() const = 0; + /*! \brief + * Returns the installation prefix for \Gromacs. + * + * This path is used to locate the data files that are in `share/top/` + * in the source directory. + * The implementation can provide an empty string if the path is not + * available; in such a case, functions that require data files may + * fail. + * + * The returned structure also contains a flag to indicate whether the + * prefix actually points to the source tree. This is used for tests + * and to support running binaries directly from the build tree. + */ + virtual InstallationPrefixInfo installationPrefix() const = 0; + /*! \brief + * Returns the full command line used to invoke the binary. + * + * The implementation can provide an empty string if no command line is + * available. + */ + virtual const char* commandLine() const = 0; - protected: - virtual ~IProgramContext() {} +protected: + virtual ~IProgramContext() {} }; /*! \brief @@ -187,7 +184,7 @@ class IProgramContext * * \see IProgramContext */ -const IProgramContext &getProgramContext(); +const IProgramContext& getProgramContext(); /*! \brief * Sets the global IProgramContext instance. * @@ -211,7 +208,7 @@ const IProgramContext &getProgramContext(); * * \see IProgramContext */ -void setProgramContext(const IProgramContext *context); +void setProgramContext(const IProgramContext* context); //! \} diff --git a/src/gromacs/utility/range.h b/src/gromacs/utility/range.h index 3dd8123488..56f92045b9 100644 --- a/src/gromacs/utility/range.h +++ b/src/gromacs/utility/range.h @@ -58,77 +58,74 @@ namespace gmx * * This will print: 2 3 4 */ -template +template class Range { static_assert(std::is_integral::value, "Range can only be used with integral types"); // Note: This class has as invariant: begin_ <= end_ - public: - //! An iterator that loops over a range of integers - struct iterator +public: + //! An iterator that loops over a range of integers + struct iterator + { + //! Constructor + iterator(T value) : value_(value) {} + //! Value + operator T() const { return value_; } + //! Reference + operator T&() { return value_; } + //! Pointer + int operator*() const { return value_; } + //! Inequality comparison + bool operator!=(const iterator other) { return value_ != other.value_; } + //! Increment operator + iterator& operator++() { - //! Constructor - iterator(T value) : value_(value) {} - //! Value - operator T () const { return value_; } - //! Reference - operator T &() { return value_; } - //! Pointer - int operator* () const { return value_; } - //! Inequality comparison - bool operator!= (const iterator other) { return value_ != other.value_; } - //! Increment operator - iterator &operator++() { ++value_; return *this; } - //! Increment operator - iterator operator++(T gmx_unused dummy) { iterator tmp(*this); ++value_; return tmp; } - //! The actual value - T value_; - }; - - //! Constructor, has to be called with \p begin <= \p end (is checked) - Range(const T begin, - const T end) : - begin_(begin), - end_(end) + ++value_; + return *this; + } + //! Increment operator + iterator operator++(T gmx_unused dummy) { - GMX_RELEASE_ASSERT(begin_ <= end_, "A range should have begin<=end"); + iterator tmp(*this); + ++value_; + return tmp; } + //! The actual value + T value_; + }; - //! Default constructor, produces an empty range - Range() = default; + //! Constructor, has to be called with \p begin <= \p end (is checked) + Range(const T begin, const T end) : begin_(begin), end_(end) + { + GMX_RELEASE_ASSERT(begin_ <= end_, "A range should have begin<=end"); + } - //! Begin iterator/value - iterator begin() const { return begin_; } - //! End iterator/value - iterator end() const { return end_; } + //! Default constructor, produces an empty range + Range() = default; - //! Returns the length of the range - T size() const - { - return end_ - begin_; - } + //! Begin iterator/value + iterator begin() const { return begin_; } + //! End iterator/value + iterator end() const { return end_; } - //! Returns whether the range is empty - bool empty() const - { - return size() == 0; - } + //! Returns the length of the range + T size() const { return end_ - begin_; } - //! Returns whether \p value is in range - bool isInRange(const T value) const - { - return (begin_ <= value && value < end_); - } + //! Returns whether the range is empty + bool empty() const { return size() == 0; } + + //! Returns whether \p value is in range + bool isInRange(const T value) const { return (begin_ <= value && value < end_); } - private: - //! The start of the range - T begin_ = 0; - //! The end of the range - T end_ = 0; +private: + //! The start of the range + T begin_ = 0; + //! The end of the range + T end_ = 0; }; -} // namespace gmx +} // namespace gmx #endif diff --git a/src/gromacs/utility/real.h b/src/gromacs/utility/real.h index e5e0fa6efd..13676a6a04 100644 --- a/src/gromacs/utility/real.h +++ b/src/gromacs/utility/real.h @@ -45,22 +45,22 @@ #define GMX_UTILITY_REAL_H /*! \brief Double precision accuracy */ -#define GMX_DOUBLE_EPS 2.2204460492503131e-16 +#define GMX_DOUBLE_EPS 2.2204460492503131e-16 /*! \brief Maximum double precision value - reduced 1 unit in last digit for MSVC */ -#define GMX_DOUBLE_MAX 1.7976931348623157e+308 +#define GMX_DOUBLE_MAX 1.7976931348623157e+308 /*! \brief Minimum double precision value */ -#define GMX_DOUBLE_MIN 2.2250738585072014e-308 +#define GMX_DOUBLE_MIN 2.2250738585072014e-308 /*! \brief Single precision accuracy */ -#define GMX_FLOAT_EPS 1.19209290e-07F +#define GMX_FLOAT_EPS 1.19209290e-07F /*! \brief Maximum single precision value - reduced 1 unit in last digit for MSVC */ -#define GMX_FLOAT_MAX 3.40282346E+38F +#define GMX_FLOAT_MAX 3.40282346E+38F /*! \brief Minimum single precision value */ -#define GMX_FLOAT_MIN 1.175494351E-38F +#define GMX_FLOAT_MIN 1.175494351E-38F #ifdef __PGI /* The portland group x86 C/C++ compilers do not treat negative zero initializers @@ -71,14 +71,28 @@ * be different for byte and word order), so check that it works for your platform * and add a separate section if necessary before adding to the ifdef above. */ -# define GMX_DOUBLE_NEGZERO ({ const union { int di[2]; double d; } _gmx_dzero = {0, -2147483648}; _gmx_dzero.d; }) -# define GMX_FLOAT_NEGZERO ({ const union { int fi; float f; } _gmx_fzero = {-2147483648}; _gmx_fzero.f; }) +# define GMX_DOUBLE_NEGZERO \ + ({ \ + const union { \ + int di[2]; \ + double d; \ + } _gmx_dzero = { 0, -2147483648 }; \ + _gmx_dzero.d; \ + }) +# define GMX_FLOAT_NEGZERO \ + ({ \ + const union { \ + int fi; \ + float f; \ + } _gmx_fzero = { -2147483648 }; \ + _gmx_fzero.f; \ + }) #else /*! \brief Negative zero in double */ -# define GMX_DOUBLE_NEGZERO (-0.0) +# define GMX_DOUBLE_NEGZERO (-0.0) /*! \brief Negative zero in float */ -# define GMX_FLOAT_NEGZERO (-0.0F) +# define GMX_FLOAT_NEGZERO (-0.0F) #endif /*! \typedef real @@ -115,38 +129,38 @@ * \brief The maximum supported number of `real` elements in a SIMD register. */ -#define GMX_FLOAT_MAX_SIMD_WIDTH 16 -#define GMX_DOUBLE_MAX_SIMD_WIDTH 8 +#define GMX_FLOAT_MAX_SIMD_WIDTH 16 +#define GMX_DOUBLE_MAX_SIMD_WIDTH 8 #if GMX_DOUBLE -#ifndef HAVE_REAL -typedef double real; -#define HAVE_REAL -#endif +# ifndef HAVE_REAL +typedef double real; +# define HAVE_REAL +# endif -#define GMX_MPI_REAL MPI_DOUBLE -#define GMX_REAL_EPS GMX_DOUBLE_EPS -#define GMX_REAL_MIN GMX_DOUBLE_MIN -#define GMX_REAL_MAX GMX_DOUBLE_MAX -#define GMX_REAL_NEGZERO GMX_DOUBLE_NEGZERO -#define gmx_real_fullprecision_pfmt "%21.14e" -#define GMX_REAL_MAX_SIMD_WIDTH GMX_DOUBLE_MAX_SIMD_WIDTH +# define GMX_MPI_REAL MPI_DOUBLE +# define GMX_REAL_EPS GMX_DOUBLE_EPS +# define GMX_REAL_MIN GMX_DOUBLE_MIN +# define GMX_REAL_MAX GMX_DOUBLE_MAX +# define GMX_REAL_NEGZERO GMX_DOUBLE_NEGZERO +# define gmx_real_fullprecision_pfmt "%21.14e" +# define GMX_REAL_MAX_SIMD_WIDTH GMX_DOUBLE_MAX_SIMD_WIDTH #else /* GMX_DOUBLE */ -#ifndef HAVE_REAL -typedef float real; -#define HAVE_REAL -#endif +# ifndef HAVE_REAL +typedef float real; +# define HAVE_REAL +# endif -#define GMX_MPI_REAL MPI_FLOAT -#define GMX_REAL_EPS GMX_FLOAT_EPS -#define GMX_REAL_MIN GMX_FLOAT_MIN -#define GMX_REAL_MAX GMX_FLOAT_MAX -#define GMX_REAL_NEGZERO GMX_FLOAT_NEGZERO -#define gmx_real_fullprecision_pfmt "%14.7e" -#define GMX_REAL_MAX_SIMD_WIDTH GMX_FLOAT_MAX_SIMD_WIDTH +# define GMX_MPI_REAL MPI_FLOAT +# define GMX_REAL_EPS GMX_FLOAT_EPS +# define GMX_REAL_MIN GMX_FLOAT_MIN +# define GMX_REAL_MAX GMX_FLOAT_MAX +# define GMX_REAL_NEGZERO GMX_FLOAT_NEGZERO +# define gmx_real_fullprecision_pfmt "%14.7e" +# define GMX_REAL_MAX_SIMD_WIDTH GMX_FLOAT_MAX_SIMD_WIDTH #endif /* GMX_DOUBLE */ @@ -155,12 +169,15 @@ typedef float real; * Examples: 2._real, 2.5_real, .5_real. The number is always of type real. * * It is best to use a real constant whenever it is used only with operands which are real. - * If a constant is double than the compiler is forced to do operations directly involving the constant - * in double even if all variables are real. A constant shouldn't be real when used with double operands, - * because then the constant is less accurate with GMX_DOUBLE=no. + * If a constant is double than the compiler is forced to do operations directly involving the + * constant in double even if all variables are real. A constant shouldn't be real when used with + * double operands, because then the constant is less accurate with GMX_DOUBLE=no. * * See https://en.cppreference.com/w/cpp/language/user_literal for details on this lanuage feature. */ -constexpr real operator"" _real(long double x) { return real(x); } +constexpr real operator"" _real(long double x) +{ + return real(x); +} #endif diff --git a/src/gromacs/utility/smalloc.cpp b/src/gromacs/utility/smalloc.cpp index bf5015c006..b6dd271c33 100644 --- a/src/gromacs/utility/smalloc.cpp +++ b/src/gromacs/utility/smalloc.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,7 @@ #include #ifdef WITH_DMALLOC -#include +# include #endif #include @@ -56,16 +56,16 @@ #include "gromacs/utility/dir_separator.h" #include "gromacs/utility/fatalerror.h" #ifdef PRINT_ALLOC_KB -#include "gromacs/utility/basenetwork.h" -#include "gromacs/utility/gmxmpi.h" +# include "gromacs/utility/basenetwork.h" +# include "gromacs/utility/gmxmpi.h" #endif static gmx_bool g_bOverAllocDD = FALSE; static tMPI_Thread_mutex_t g_over_alloc_mutex = TMPI_THREAD_MUTEX_INITIALIZER; -void *save_malloc(const char *name, const char *file, int line, size_t size) +void* save_malloc(const char* name, const char* file, int line, size_t size) { - void *p; + void* p; p = nullptr; if (size == 0) @@ -77,19 +77,19 @@ void *save_malloc(const char *name, const char *file, int line, size_t size) if ((p = malloc(size)) == nullptr) { gmx_fatal(errno, __FILE__, __LINE__, - "Not enough memory. Failed to malloc %" PRId64 " bytes for %s\n" + "Not enough memory. Failed to malloc %" PRId64 + " bytes for %s\n" "(called from file %s, line %d)", static_cast(size), name, file, line); } - (void) memset(p, 0, size); + (void)memset(p, 0, size); } return p; } -void *save_calloc(const char *name, const char *file, int line, - size_t nelem, size_t elsize) +void* save_calloc(const char* name, const char* file, int line, size_t nelem, size_t elsize) { - void *p; + void* p; p = nullptr; if ((nelem == 0) || (elsize == 0)) @@ -99,32 +99,29 @@ void *save_calloc(const char *name, const char *file, int line, else { #ifdef PRINT_ALLOC_KB - if (nelem*elsize >= PRINT_ALLOC_KB*1024) + if (nelem * elsize >= PRINT_ALLOC_KB * 1024) { int rank = gmx_node_rank(); printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n", - nelem*elsize/1048576.0, name, file, line, rank); + nelem * elsize / 1048576.0, name, file, line, rank); } #endif #if GMX_BROKEN_CALLOC /* emulate calloc(3) with malloc/memset on machines with a broken calloc, e.g. in -lgmalloc on cray xt3. */ - if ((p = malloc((size_t)nelem*(size_t)elsize)) == NULL) + if ((p = malloc((size_t)nelem * (size_t)elsize)) == NULL) { gmx_fatal(errno, __FILE__, __LINE__, - "Not enough memory. Failed to calloc %" PRId64 - " elements of size %" PRId64 + "Not enough memory. Failed to calloc %" PRId64 " elements of size %" PRId64 " for %s\n(called from file %s, line %d)", - (int64_t)nelem, (int64_t)elsize, - name, file, line); + (int64_t)nelem, (int64_t)elsize, name, file, line); } - memset(p, 0, (size_t) (nelem * elsize)); + memset(p, 0, (size_t)(nelem * elsize)); #else if ((p = calloc(nelem, elsize)) == nullptr) { gmx_fatal(errno, __FILE__, __LINE__, - "Not enough memory. Failed to calloc %" PRId64 - " elements of size %" PRId64 + "Not enough memory. Failed to calloc %" PRId64 " elements of size %" PRId64 " for %s\n(called from file %s, line %d)", static_cast(nelem), static_cast(elsize), name, file, line); } @@ -133,11 +130,10 @@ void *save_calloc(const char *name, const char *file, int line, return p; } -void *save_realloc(const char *name, const char *file, int line, void *ptr, - size_t nelem, size_t elsize) +void* save_realloc(const char* name, const char* file, int line, void* ptr, size_t nelem, size_t elsize) { - void *p; - size_t size = nelem*elsize; + void* p; + size_t size = nelem * elsize; p = nullptr; if (size == 0) @@ -147,11 +143,11 @@ void *save_realloc(const char *name, const char *file, int line, void *ptr, else { #ifdef PRINT_ALLOC_KB - if (size >= PRINT_ALLOC_KB*1024) + if (size >= PRINT_ALLOC_KB * 1024) { int rank = gmx_node_rank(); printf("Reallocating %.1f MB for %s (called from file %s, line %d on %d)\n", - size/1048576.0, name, file, line, rank); + size / 1048576.0, name, file, line, rank); } #endif if (ptr == nullptr) @@ -173,7 +169,7 @@ void *save_realloc(const char *name, const char *file, int line, void *ptr, return p; } -void save_free(const char gmx_unused *name, const char gmx_unused *file, int gmx_unused line, void *ptr) +void save_free(const char gmx_unused* name, const char gmx_unused* file, int gmx_unused line, void* ptr) { if (ptr != nullptr) { @@ -186,22 +182,25 @@ void save_free(const char gmx_unused *name, const char gmx_unused *file, int gmx * on systems that lack posix_memalign() and memalign() when * freeing memory that needed to be adjusted to achieve * the necessary alignment. */ -void *save_malloc_aligned(const char *name, const char *file, int line, - size_t nelem, size_t elsize, size_t alignment) +void* save_malloc_aligned(const char* name, const char* file, int line, size_t nelem, size_t elsize, size_t alignment) { - void * p; + void* p; if (alignment == 0) { gmx_fatal(errno, __FILE__, __LINE__, - "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, line %d)", file, line); + "Cannot allocate aligned memory with alignment of zero!\n(called from file %s, " + "line %d)", + file, line); } size_t alignmentSize = gmx::AlignedAllocationPolicy::alignment(); if (alignment > alignmentSize) { gmx_fatal(errno, __FILE__, __LINE__, - "Cannot allocate aligned memory with alignment > %zu bytes\n(called from file %s, line %d)", alignmentSize, file, line); + "Cannot allocate aligned memory with alignment > %zu bytes\n(called from file " + "%s, line %d)", + alignmentSize, file, line); } @@ -212,29 +211,30 @@ void *save_malloc_aligned(const char *name, const char *file, int line, else { #ifdef PRINT_ALLOC_KB - if (nelem*elsize >= PRINT_ALLOC_KB*1024) + if (nelem * elsize >= PRINT_ALLOC_KB * 1024) { int rank = gmx_node_rank(); printf("Allocating %.1f MB for %s (called from file %s, line %d on %d)\n", - nelem*elsize/1048576.0, name, file, line, rank); + nelem * elsize / 1048576.0, name, file, line, rank); } #endif - p = gmx::AlignedAllocationPolicy::malloc(nelem*elsize); + p = gmx::AlignedAllocationPolicy::malloc(nelem * elsize); if (p == nullptr) { gmx_fatal(errno, __FILE__, __LINE__, - "Not enough memory. Failed to allocate %zu aligned elements of size %zu for %s\n(called from file %s, line %d)", nelem, elsize, name, file, line); + "Not enough memory. Failed to allocate %zu aligned elements of size %zu for " + "%s\n(called from file %s, line %d)", + nelem, elsize, name, file, line); } } return p; } -void *save_calloc_aligned(const char *name, const char *file, int line, - size_t nelem, size_t elsize, size_t alignment) +void* save_calloc_aligned(const char* name, const char* file, int line, size_t nelem, size_t elsize, size_t alignment) { - void *aligned = save_malloc_aligned(name, file, line, nelem, elsize, alignment); + void* aligned = save_malloc_aligned(name, file, line, nelem, elsize, alignment); if (aligned != nullptr) { memset(aligned, 0, static_cast(nelem * elsize)); @@ -243,7 +243,7 @@ void *save_calloc_aligned(const char *name, const char *file, int line, } /* This routine can NOT be called with any pointer */ -void save_free_aligned(const char gmx_unused *name, const char gmx_unused *file, int gmx_unused line, void *ptr) +void save_free_aligned(const char gmx_unused* name, const char gmx_unused* file, int gmx_unused line, void* ptr) { gmx::AlignedAllocationPolicy::free(ptr); } @@ -261,7 +261,7 @@ int over_alloc_dd(int n) { if (g_bOverAllocDD) { - return static_cast(OVER_ALLOC_FAC*n + 100); + return static_cast(OVER_ALLOC_FAC * n + 100); } else { diff --git a/src/gromacs/utility/smalloc.h b/src/gromacs/utility/smalloc.h index ad6a3c5c2c..adb5c9a0ba 100644 --- a/src/gromacs/utility/smalloc.h +++ b/src/gromacs/utility/smalloc.h @@ -78,7 +78,7 @@ * * This should generally be called through smalloc(), not directly. */ -void *save_malloc(const char *name, const char *file, int line, size_t size); +void* save_malloc(const char* name, const char* file, int line, size_t size); /*! \brief * \Gromacs wrapper for calloc(). * @@ -91,8 +91,7 @@ void *save_malloc(const char *name, const char *file, int line, size_t size); * * This should generally be called through snew(), not directly. */ -void *save_calloc(const char *name, const char *file, int line, - size_t nelem, size_t elsize); +void* save_calloc(const char* name, const char* file, int line, size_t nelem, size_t elsize); /*! \brief * \Gromacs wrapper for realloc(). * @@ -110,8 +109,7 @@ void *save_calloc(const char *name, const char *file, int line, * * Note that the allocated memory is not initialized to zero. */ -void *save_realloc(const char *name, const char *file, int line, - void *ptr, size_t nelem, size_t elsize); +void* save_realloc(const char* name, const char* file, int line, void* ptr, size_t nelem, size_t elsize); /*! \brief * \Gromacs wrapper for free(). * @@ -124,7 +122,7 @@ void *save_realloc(const char *name, const char *file, int line, * This should generally be called through sfree(), not directly. * This never fails. */ -void save_free(const char *name, const char *file, int line, void *ptr); +void save_free(const char* name, const char* file, int line, void* ptr); /*! \brief * \Gromacs wrapper for allocating aligned memory. @@ -142,8 +140,7 @@ void save_free(const char *name, const char *file, int line, void *ptr); * * The returned pointer should only be freed with a call to save_free_aligned(). */ -void *save_malloc_aligned(const char *name, const char *file, int line, - size_t nelem, size_t elsize, size_t alignment); +void* save_malloc_aligned(const char* name, const char* file, int line, size_t nelem, size_t elsize, size_t alignment); /*! \brief * \Gromacs wrapper for allocating zero-initialized aligned memory. * @@ -160,8 +157,7 @@ void *save_malloc_aligned(const char *name, const char *file, int line, * * The returned pointer should only be freed with a call to save_free_aligned(). */ -void *save_calloc_aligned(const char *name, const char *file, int line, - size_t nelem, size_t elsize, size_t alignment); +void* save_calloc_aligned(const char* name, const char* file, int line, size_t nelem, size_t elsize, size_t alignment); /*! \brief * \Gromacs wrapper for freeing aligned memory. * @@ -176,7 +172,7 @@ void *save_calloc_aligned(const char *name, const char *file, int line, * This should generally be called through sfree_aligned(), not directly. * This never fails. */ -void save_free_aligned(const char *name, const char *file, int line, void *ptr); +void save_free_aligned(const char* name, const char* file, int line, void* ptr); #include @@ -203,48 +199,44 @@ void save_free_aligned(const char *name, const char *file, int line, void *ptr); */ /*! \{ */ /** C++ helper for snew(). */ -template static inline -void gmx_snew_impl(const char *name, const char *file, int line, - T * &ptr, size_t nelem) +template +static inline void gmx_snew_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem) { static_assert(std::is_pod::value, "snew() called on C++ type"); ptr = static_cast(save_calloc(name, file, line, nelem, sizeof(T))); } /** C++ helper for srenew(). */ -template static inline -void gmx_srenew_impl(const char *name, const char *file, int line, - T * &ptr, size_t nelem) +template +static inline void gmx_srenew_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem) { static_assert(std::is_pod::value, "srenew() called on C++ type"); ptr = static_cast(save_realloc(name, file, line, ptr, nelem, sizeof(T))); } /** C++ helper for smalloc(). */ -template static inline -void gmx_smalloc_impl(const char *name, const char *file, int line, - T * &ptr, size_t size) +template +static inline void gmx_smalloc_impl(const char* name, const char* file, int line, T*& ptr, size_t size) { static_assert(std::is_pod::value, "smalloc() called on C++ type"); ptr = static_cast(save_malloc(name, file, line, size)); } /** C++ helper for snew_aligned(). */ -template static inline -void gmx_snew_aligned_impl(const char *name, const char *file, int line, - T * &ptr, size_t nelem, size_t alignment) +template +static inline void +gmx_snew_aligned_impl(const char* name, const char* file, int line, T*& ptr, size_t nelem, size_t alignment) { static_assert(std::is_pod::value, "snew_aligned() called on C++ type"); ptr = static_cast(save_calloc_aligned(name, file, line, nelem, sizeof(T), alignment)); } /** C++ helper for sfree(). */ -template static inline -void gmx_sfree_impl(const char *name, const char *file, int line, T *ptr) +template +static inline void gmx_sfree_impl(const char* name, const char* file, int line, T* ptr) { - static_assert(std::is_pod::value || std::is_void::value, - "sfree() called on C++ type"); + static_assert(std::is_pod::value || std::is_void::value, "sfree() called on C++ type"); save_free(name, file, line, ptr); } /** C++ helper for sfree_aligned(). */ -template static inline -void gmx_sfree_aligned_impl(const char *name, const char *file, int line, T *ptr) +template +static inline void gmx_sfree_aligned_impl(const char* name, const char* file, int line, T* ptr) { static_assert(std::is_pod::value || std::is_void::value, "sfree_aligned() called on C++ type"); @@ -327,18 +319,13 @@ void gmx_sfree_aligned_impl(const char *name, const char *file, int line, T *ptr */ /* C++ implementation */ -#define snew(ptr, nelem) \ - gmx_snew_impl(#ptr, __FILE__, __LINE__, (ptr), (nelem)) -#define srenew(ptr, nelem) \ - gmx_srenew_impl(#ptr, __FILE__, __LINE__, (ptr), (nelem)) -#define smalloc(ptr, size) \ - gmx_smalloc_impl(#ptr, __FILE__, __LINE__, (ptr), (size)) +#define snew(ptr, nelem) gmx_snew_impl(#ptr, __FILE__, __LINE__, (ptr), (nelem)) +#define srenew(ptr, nelem) gmx_srenew_impl(#ptr, __FILE__, __LINE__, (ptr), (nelem)) +#define smalloc(ptr, size) gmx_smalloc_impl(#ptr, __FILE__, __LINE__, (ptr), (size)) #define snew_aligned(ptr, nelem, alignment) \ gmx_snew_aligned_impl(#ptr, __FILE__, __LINE__, (ptr), (nelem), alignment) -#define sfree(ptr) \ - gmx_sfree_impl(#ptr, __FILE__, __LINE__, (ptr)) -#define sfree_aligned(ptr) \ - gmx_sfree_aligned_impl(#ptr, __FILE__, __LINE__, (ptr)) +#define sfree(ptr) gmx_sfree_impl(#ptr, __FILE__, __LINE__, (ptr)) +#define sfree_aligned(ptr) gmx_sfree_aligned_impl(#ptr, __FILE__, __LINE__, (ptr)) /*! \brief * Over allocation factor for memory allocations. @@ -375,10 +362,16 @@ int over_alloc_dd(int n); /** Over allocation for small data types: int, real etc. */ template -constexpr T over_alloc_small(T n) { return OVER_ALLOC_FAC*n + 8000; } +constexpr T over_alloc_small(T n) +{ + return OVER_ALLOC_FAC * n + 8000; +} /** Over allocation for large data types: complex structs */ template -constexpr T over_alloc_large(T n) { return OVER_ALLOC_FAC*n + 1000; } +constexpr T over_alloc_large(T n) +{ + return OVER_ALLOC_FAC * n + 1000; +} #endif diff --git a/src/gromacs/utility/snprintf.h b/src/gromacs/utility/snprintf.h index c9c5acd14e..cff46c1c06 100644 --- a/src/gromacs/utility/snprintf.h +++ b/src/gromacs/utility/snprintf.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2012,2013,2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,7 @@ #include #if GMX_NATIVE_WINDOWS -#define snprintf _snprintf +# define snprintf _snprintf #endif #endif diff --git a/src/gromacs/utility/strconvert.cpp b/src/gromacs/utility/strconvert.cpp index c59dd01100..44ee5e9f15 100644 --- a/src/gromacs/utility/strconvert.cpp +++ b/src/gromacs/utility/strconvert.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,30 +57,28 @@ namespace gmx //! \cond libapi -bool boolFromString(const char *value) +bool boolFromString(const char* value) { - if (gmx_strcasecmp(value, "1") == 0 - || gmx_strcasecmp(value, "yes") == 0 + if (gmx_strcasecmp(value, "1") == 0 || gmx_strcasecmp(value, "yes") == 0 || gmx_strcasecmp(value, "true") == 0) { return true; } - if (gmx_strcasecmp(value, "0") == 0 - || gmx_strcasecmp(value, "no") == 0 + if (gmx_strcasecmp(value, "0") == 0 || gmx_strcasecmp(value, "no") == 0 || gmx_strcasecmp(value, "false") == 0) { return false; } - GMX_THROW(InvalidInputError("Invalid value: '" + std::string(value) + "'; supported values are: 1, 0, yes, no, true, false")); + GMX_THROW(InvalidInputError("Invalid value: '" + std::string(value) + + "'; supported values are: 1, 0, yes, no, true, false")); } -int intFromString(const char *str) +int intFromString(const char* str) { errno = 0; - char *endptr; - const long int value = std::strtol(str, &endptr, 10); - if (errno == ERANGE - || value < std::numeric_limits::min() + char* endptr; + const long int value = std::strtol(str, &endptr, 10); + if (errno == ERANGE || value < std::numeric_limits::min() || value > std::numeric_limits::max()) { GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) @@ -88,17 +86,16 @@ int intFromString(const char *str) } if (str[0] == '\0' || *endptr != '\0') { - GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) - + "'; expected an integer")); + GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) + "'; expected an integer")); } return value; } -int64_t int64FromString(const char *str) +int64_t int64FromString(const char* str) { errno = 0; - char *endptr; - const int64_t value = str_to_int64_t(str, &endptr); + char* endptr; + const int64_t value = str_to_int64_t(str, &endptr); if (errno == ERANGE) { GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) @@ -106,37 +103,34 @@ int64_t int64FromString(const char *str) } if (str[0] == '\0' || *endptr != '\0') { - GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) - + "'; expected an integer")); + GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) + "'; expected an integer")); } return value; } -float floatFromString(const char *str) +float floatFromString(const char* str) { errno = 0; - char *endptr; - const double value = std::strtod(str, &endptr); - if (errno == ERANGE - || value < -std::numeric_limits::max() - || value > std::numeric_limits::max()) + char* endptr; + const double value = std::strtod(str, &endptr); + if (errno == ERANGE || value < -std::numeric_limits::max() + || value > std::numeric_limits::max()) { GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) + "'; it causes an overflow/underflow")); } if (str[0] == '\0' || *endptr != '\0') { - GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) - + "'; expected a number")); + GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) + "'; expected a number")); } return value; } -double doubleFromString(const char *str) +double doubleFromString(const char* str) { errno = 0; - char *endptr; - const double value = std::strtod(str, &endptr); + char* endptr; + const double value = std::strtod(str, &endptr); if (errno == ERANGE) { GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) @@ -144,8 +138,7 @@ double doubleFromString(const char *str) } if (str[0] == '\0' || *endptr != '\0') { - GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) - + "'; expected a number")); + GMX_THROW(InvalidInputError("Invalid value: '" + std::string(str) + "'; expected a number")); } return value; } diff --git a/src/gromacs/utility/strconvert.h b/src/gromacs/utility/strconvert.h index 875830eb79..f9eaa30acc 100644 --- a/src/gromacs/utility/strconvert.h +++ b/src/gromacs/utility/strconvert.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ namespace gmx * * \throws InvalidInputError if `str` is not recognized as a boolean value. */ -bool boolFromString(const char *str); +bool boolFromString(const char* str); /*! \brief * Parses an integer from a string. * @@ -69,7 +69,7 @@ bool boolFromString(const char *str); * * Also checks for overflow. */ -int intFromString(const char *str); +int intFromString(const char* str); /*! \brief * Parses a 64-bit integer from a string. * @@ -77,7 +77,7 @@ int intFromString(const char *str); * * Also checks for overflow. */ -int64_t int64FromString(const char *str); +int64_t int64FromString(const char* str); /*! \brief * Parses a float value from a string. * @@ -85,7 +85,7 @@ int64_t int64FromString(const char *str); * * Also checks for overflow. */ -float floatFromString(const char *str); +float floatFromString(const char* str); /*! \brief * Parses a double value from a string. * @@ -93,7 +93,7 @@ float floatFromString(const char *str); * * Also checks for overflow. */ -double doubleFromString(const char *str); +double doubleFromString(const char* str); /*! \brief * Parses a value from a string to a given type. @@ -104,9 +104,11 @@ double doubleFromString(const char *str); * The main use for this function is to write `fromString(value)`, * but it can also be used for other types for consistency. */ -template static inline T fromString(const char *str); +template +static inline T fromString(const char* str); //! \copydoc fromString(const char *) -template static inline T fromString(const std::string &str) +template +static inline T fromString(const std::string& str) { return fromString(str.c_str()); } @@ -115,33 +117,49 @@ template static inline T fromString(const std::string &str) * Provided for situations where overload resolution cannot easily resolve the * desired std::string parameter. */ -template static inline T fromStdString(const std::string &str) +template +static inline T fromStdString(const std::string& str) { return fromString(str.c_str()); } //! Implementation for boolean values. -template <> inline -bool fromString(const char *str) { return boolFromString(str); } +template<> +inline bool fromString(const char* str) +{ + return boolFromString(str); +} //! Implementation for integer values. -template <> inline -int fromString(const char *str) { return intFromString(str); } +template<> +inline int fromString(const char* str) +{ + return intFromString(str); +} //! Implementation for 64-bit integer values. -template <> inline -int64_t fromString(const char *str) { return int64FromString(str); } +template<> +inline int64_t fromString(const char* str) +{ + return int64FromString(str); +} //! Implementation for float values. -template <> inline -float fromString(const char *str) { return floatFromString(str); } +template<> +inline float fromString(const char* str) +{ + return floatFromString(str); +} //! Implementation for double values. -template <> inline -double fromString(const char *str) { return doubleFromString(str); } +template<> +inline double fromString(const char* str) +{ + return doubleFromString(str); +} /*! \brief * Converts a boolean to a "true"/"false" string. * * Does not throw. */ -static inline const char *boolToString(bool value) +static inline const char* boolToString(bool value) { return value ? "true" : "false"; } @@ -171,12 +189,30 @@ static inline std::string doubleToString(double t) * \throws std::bad_alloc if out of memory. * \{ */ -static inline std::string toString(bool t) { return boolToString(t); } -static inline std::string toString(int t) { return intToString(t); } -static inline std::string toString(int64_t t) { return int64ToString(t); } -static inline std::string toString(float t) { return doubleToString(t); } -static inline std::string toString(double t) { return doubleToString(t); } -static inline std::string toString(std::string t) { return t; } +static inline std::string toString(bool t) +{ + return boolToString(t); +} +static inline std::string toString(int t) +{ + return intToString(t); +} +static inline std::string toString(int64_t t) +{ + return int64ToString(t); +} +static inline std::string toString(float t) +{ + return doubleToString(t); +} +static inline std::string toString(double t) +{ + return doubleToString(t); +} +static inline std::string toString(std::string t) +{ + return t; +} //! \} //! \} diff --git a/src/gromacs/utility/strdb.cpp b/src/gromacs/utility/strdb.cpp index f46b7b30d4..ab8e315a98 100644 --- a/src/gromacs/utility/strdb.cpp +++ b/src/gromacs/utility/strdb.cpp @@ -47,16 +47,16 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -gmx_bool get_a_line(FILE *fp, char line[], int n) +gmx_bool get_a_line(FILE* fp, char line[], int n) { - char *line0; - char *dum; + char* line0; + char* dum; - snew(line0, n+1); + snew(line0, n + 1); do { - if (!fgets(line0, n+1, fp)) + if (!fgets(line0, n + 1, fp)) { sfree(line0); return FALSE; @@ -68,13 +68,13 @@ gmx_bool get_a_line(FILE *fp, char line[], int n) } else if (static_cast(std::strlen(line0)) == n) { - fprintf(stderr, "Warning: line length exceeds buffer length (%d), data might be corrupted\n", n); - line0[n-1] = '\0'; + fprintf(stderr, + "Warning: line length exceeds buffer length (%d), data might be corrupted\n", n); + line0[n - 1] = '\0'; } else { - fprintf(stderr, "Warning: file does not end with a newline, last line:\n%s\n", - line0); + fprintf(stderr, "Warning: file does not end with a newline, last line:\n%s\n", line0); } dum = std::strchr(line0, ';'); if (dum) @@ -84,14 +84,13 @@ gmx_bool get_a_line(FILE *fp, char line[], int n) std::strncpy(line, line0, n); dum = line0; ltrim(dum); - } - while (dum[0] == '\0'); + } while (dum[0] == '\0'); sfree(line0); return TRUE; } -gmx_bool get_header(char line[], char *header) +gmx_bool get_header(char line[], char* header) { std::string temp = line; auto index = temp.find('['); @@ -110,7 +109,7 @@ gmx_bool get_header(char line[], char *header) return sscanf(temp.c_str(), "%s%*s", header) == 1; } -int search_str(int nstr, char **str, char *key) +int search_str(int nstr, char** str, char* key) { int i; @@ -126,15 +125,15 @@ int search_str(int nstr, char **str, char *key) return -1; } -static int fget_lines(FILE *in, const char *db, char ***strings) +static int fget_lines(FILE* in, const char* db, char*** strings) { - char **ptr; + char** ptr; char buf[STRLEN]; int i, nstr; - char *pret; + char* pret; pret = fgets(buf, STRLEN, in); - if (pret == nullptr || sscanf(buf, "%d", &nstr) != 1) + if (pret == nullptr || sscanf(buf, "%d", &nstr) != 1) { gmx_warning("File is empty"); gmx_ffclose(in); @@ -159,7 +158,7 @@ static int fget_lines(FILE *in, const char *db, char ***strings) return nstr; } -int get_lines(const char *db, char ***strings) +int get_lines(const char* db, char*** strings) { gmx::FilePtr in = gmx::openLibraryFile(db); return fget_lines(in.get(), db, strings); diff --git a/src/gromacs/utility/strdb.h b/src/gromacs/utility/strdb.h index c824466b0f..13165f4dfd 100644 --- a/src/gromacs/utility/strdb.h +++ b/src/gromacs/utility/strdb.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,7 +54,7 @@ * Comment ';...' and leading spaces are removed, empty lines are skipped. * Return FALSE when eof. */ -gmx_bool get_a_line(FILE *fp, char line[], int n); +gmx_bool get_a_line(FILE* fp, char line[], int n); /*! \brief * Read a header between '[' and ']' from line to header. @@ -69,13 +69,13 @@ gmx_bool get_header(char line[], char header[]); * First line in the file needs to specify the number of strings following. * Returns the number of strings. */ -int get_lines(const char *db, char ***strings); +int get_lines(const char* db, char*** strings); /*! \brief * Searches an array of strings for key, return the index if found. * * Returns -1 if not found. */ -int search_str(int nstr, char **str, char *key); +int search_str(int nstr, char** str, char* key); #endif diff --git a/src/gromacs/utility/stringcompare.h b/src/gromacs/utility/stringcompare.h index 211a4b67ab..9aad20897d 100644 --- a/src/gromacs/utility/stringcompare.h +++ b/src/gromacs/utility/stringcompare.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -76,33 +76,31 @@ enum class StringCompareType */ class StringCompare { - public: - /*! \brief - * Creates a comparer with the given type - * - * This is not explicit, which allows passing \ref StringCompareType - * directly to, e.g., `std::map` constructors. - */ - StringCompare(StringCompareType type = StringCompareType::Exact) - : type_(type) {} +public: + /*! \brief + * Creates a comparer with the given type + * + * This is not explicit, which allows passing \ref StringCompareType + * directly to, e.g., `std::map` constructors. + */ + StringCompare(StringCompareType type = StringCompareType::Exact) : type_(type) {} - //! The comparison operation. - bool operator()(const std::string &a, const std::string &b) const + //! The comparison operation. + bool operator()(const std::string& a, const std::string& b) const + { + switch (type_) { - switch (type_) - { - case StringCompareType::Exact: - return a < b; - case StringCompareType::CaseInsensitive: - return gmx_strcasecmp(a.c_str(), b.c_str()) < 0; - case StringCompareType::CaseAndDashInsensitive: - return gmx_strcasecmp_min(a.c_str(), b.c_str()) < 0; - } - return a < b; + case StringCompareType::Exact: return a < b; + case StringCompareType::CaseInsensitive: + return gmx_strcasecmp(a.c_str(), b.c_str()) < 0; + case StringCompareType::CaseAndDashInsensitive: + return gmx_strcasecmp_min(a.c_str(), b.c_str()) < 0; } + return a < b; + } - private: - StringCompareType type_; +private: + StringCompareType type_; }; } // namespace gmx diff --git a/src/gromacs/utility/stringstream.cpp b/src/gromacs/utility/stringstream.cpp index 51518b4166..1219ea3470 100644 --- a/src/gromacs/utility/stringstream.cpp +++ b/src/gromacs/utility/stringstream.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,33 +51,30 @@ namespace gmx { -void StringOutputStream::write(const char *str) +void StringOutputStream::write(const char* str) { str_.append(str); } -void StringOutputStream::close() -{ -} +void StringOutputStream::close() {} -StringInputStream::StringInputStream(const std::string &input) - : input_(input), pos_(0) -{ -} +StringInputStream::StringInputStream(const std::string& input) : input_(input), pos_(0) {} -StringInputStream::StringInputStream(const std::vector &input) - : input_(joinStrings(input.begin(), input.end(), "\n")), pos_(0) +StringInputStream::StringInputStream(const std::vector& input) : + input_(joinStrings(input.begin(), input.end(), "\n")), + pos_(0) { input_.append("\n"); } -StringInputStream::StringInputStream(ArrayRef const &input) - : input_(joinStrings(input.begin(), input.end(), "\n")), pos_(0) +StringInputStream::StringInputStream(ArrayRef const& input) : + input_(joinStrings(input.begin(), input.end(), "\n")), + pos_(0) { input_.append("\n"); } -bool StringInputStream::readLine(std::string *line) +bool StringInputStream::readLine(std::string* line) { if (pos_ == input_.size()) { @@ -96,7 +93,7 @@ bool StringInputStream::readLine(std::string *line) // To include the newline as well! newpos += 1; } - line->assign(input_.substr(pos_, newpos-pos_)); + line->assign(input_.substr(pos_, newpos - pos_)); pos_ = newpos; return true; } diff --git a/src/gromacs/utility/stringstream.h b/src/gromacs/utility/stringstream.h index e507886854..9912b92bd8 100644 --- a/src/gromacs/utility/stringstream.h +++ b/src/gromacs/utility/stringstream.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,19 +63,20 @@ namespace gmx */ class StringOutputStream : public TextOutputStream { - public: - //! Returns the text written to the stream so far. - const std::string &toString() const { return str_; } +public: + //! Returns the text written to the stream so far. + const std::string& toString() const { return str_; } - // From TextOutputStream - void write(const char *text) override; - void close() override; + // From TextOutputStream + void write(const char* text) override; + void close() override; - private: - std::string str_; +private: + std::string str_; }; -template class ArrayRef; +template +class ArrayRef; /*! \libinternal \brief * Helper class to convert static string data to a stream. @@ -84,38 +85,39 @@ template class ArrayRef; */ class StringInputStream : public TextInputStream { - public: - /*! \brief - * Constructor that stores input lines in a string. - * - * The string is internally but no processing is done. - * - * \param[in] input String to be served by the stream. - */ - explicit StringInputStream(const std::string &input); - /*! \brief - * Constructor that stores input lines in a string. - * - * The vector of strings is stored as a string separated by newline. - * - * \param[in] input String to be served by the stream. - */ - explicit StringInputStream(const std::vector &input); - /*! \brief - * Constructor that stores input lines in a string. - * - * The array of char * is stored as a string separated by newline. - * - * \param[in] input Array of char * to be served by the stream. - */ - explicit StringInputStream(ArrayRef const &input); +public: + /*! \brief + * Constructor that stores input lines in a string. + * + * The string is internally but no processing is done. + * + * \param[in] input String to be served by the stream. + */ + explicit StringInputStream(const std::string& input); + /*! \brief + * Constructor that stores input lines in a string. + * + * The vector of strings is stored as a string separated by newline. + * + * \param[in] input String to be served by the stream. + */ + explicit StringInputStream(const std::vector& input); + /*! \brief + * Constructor that stores input lines in a string. + * + * The array of char * is stored as a string separated by newline. + * + * \param[in] input Array of char * to be served by the stream. + */ + explicit StringInputStream(ArrayRef const& input); - // From TextInputStream - bool readLine(std::string *line) override; - void close() override {} - private: - std::string input_; - size_t pos_; + // From TextInputStream + bool readLine(std::string* line) override; + void close() override {} + +private: + std::string input_; + size_t pos_; }; } // namespace gmx diff --git a/src/gromacs/utility/stringutil.cpp b/src/gromacs/utility/stringutil.cpp index 7d959da59a..a487ae0b69 100644 --- a/src/gromacs/utility/stringutil.cpp +++ b/src/gromacs/utility/stringutil.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,8 +60,7 @@ namespace gmx { -std::size_t -countWords(const char *s) +std::size_t countWords(const char* s) { std::size_t nWords = 0; // Use length variable to avoid N^2 complexity when executing strlen(s) every iteration @@ -86,14 +86,13 @@ countWords(const char *s) } -std::size_t -countWords(const std::string &str) +std::size_t countWords(const std::string& str) { // Under out beautiful C++ interface hides an ugly c-string implementation :-) return countWords(str.c_str()); } -bool endsWith(const char *str, const char *suffix) +bool endsWith(const char* str, const char* suffix) { if (isNullOrEmpty(suffix)) { @@ -101,11 +100,10 @@ bool endsWith(const char *str, const char *suffix) } const size_t strLength = std::strlen(str); const size_t suffixLength = std::strlen(suffix); - return (strLength >= suffixLength - && std::strcmp(&str[strLength - suffixLength], suffix) == 0); + return (strLength >= suffixLength && std::strcmp(&str[strLength - suffixLength], suffix) == 0); } -std::string stripSuffixIfPresent(const std::string &str, const char *suffix) +std::string stripSuffixIfPresent(const std::string& str, const char* suffix) { if (suffix != nullptr) { @@ -118,7 +116,7 @@ std::string stripSuffixIfPresent(const std::string &str, const char *suffix) return str; } -std::string stripString(const std::string &str) +std::string stripString(const std::string& str) { std::string::const_iterator start = str.begin(); std::string::const_iterator end = str.end(); @@ -133,22 +131,22 @@ std::string stripString(const std::string &str) return std::string(start, end); } -std::string formatString(gmx_fmtstr const char *fmt, ...) +std::string formatString(gmx_fmtstr const char* fmt, ...) { - va_list ap; + va_list ap; va_start(ap, fmt); std::string result = formatStringV(fmt, ap); va_end(ap); return result; } -std::string formatStringV(const char *fmt, va_list ap) +std::string formatStringV(const char* fmt, va_list ap) { va_list ap_copy; char staticBuf[1024]; int length = 1024; std::vector dynamicBuf; - char *buf = staticBuf; + char* buf = staticBuf; // TODO: There may be a better way of doing this on Windows, Microsoft // provides their own way of doing things... @@ -175,7 +173,7 @@ std::string formatStringV(const char *fmt, va_list ap) } } -std::vector splitString(const std::string &str) +std::vector splitString(const std::string& str) { std::vector result; std::string::const_iterator currPos = str.begin(); @@ -199,7 +197,7 @@ std::vector splitString(const std::string &str) return result; } -std::vector splitDelimitedString(const std::string &str, char delim) +std::vector splitDelimitedString(const std::string& str, char delim) { std::vector result; size_t currPos = 0; @@ -212,13 +210,12 @@ std::vector splitDelimitedString(const std::string &str, char delim nextDelim = str.find(delim, currPos); result.push_back(str.substr(currPos, nextDelim - currPos)); currPos = nextDelim < len ? nextDelim + 1 : len; - } - while (currPos < len || nextDelim < len); + } while (currPos < len || nextDelim < len); } return result; } -std::vector splitAndTrimDelimitedString(const std::string &str, char delim) +std::vector splitAndTrimDelimitedString(const std::string& str, char delim) { std::vector result; @@ -254,12 +251,9 @@ bool isWordChar(char c) * * \ingroup module_utility */ -std::string -replaceInternal(const std::string &input, const char *from, const char *to, - bool bWholeWords) +std::string replaceInternal(const std::string& input, const char* from, const char* to, bool bWholeWords) { - GMX_RELEASE_ASSERT(from != nullptr && to != nullptr, - "Replacement strings must not be NULL"); + GMX_RELEASE_ASSERT(from != nullptr && to != nullptr, "Replacement strings must not be NULL"); size_t matchLength = std::strlen(from); std::string result; size_t inputPos = 0; @@ -269,13 +263,12 @@ replaceInternal(const std::string &input, const char *from, const char *to, size_t matchEnd = matchPos + matchLength; if (bWholeWords) { - if (!((matchPos == 0 || !isWordChar(input[matchPos-1])) + if (!((matchPos == 0 || !isWordChar(input[matchPos - 1])) && (matchEnd == input.length() || !isWordChar(input[matchEnd])))) { matchPos = input.find(from, matchPos + 1); continue; } - } result.append(input, inputPos, matchPos - inputPos); result.append(to); @@ -286,45 +279,37 @@ replaceInternal(const std::string &input, const char *from, const char *to, return result; } -} // namespace +} // namespace -std::string -replaceAll(const std::string &input, const char *from, const char *to) +std::string replaceAll(const std::string& input, const char* from, const char* to) { return replaceInternal(input, from, to, false); } -std::string -replaceAll(const std::string &input, const std::string &from, - const std::string &to) +std::string replaceAll(const std::string& input, const std::string& from, const std::string& to) { return replaceInternal(input, from.c_str(), to.c_str(), false); } -std::string -replaceAllWords(const std::string &input, const char *from, const char *to) +std::string replaceAllWords(const std::string& input, const char* from, const char* to) { return replaceInternal(input, from, to, true); } -std::string -replaceAllWords(const std::string &input, const std::string &from, - const std::string &to) +std::string replaceAllWords(const std::string& input, const std::string& from, const std::string& to) { return replaceInternal(input, from.c_str(), to.c_str(), true); } -bool equalCaseInsensitive(const std::string &source, const std::string &target) +bool equalCaseInsensitive(const std::string& source, const std::string& target) { - return source.length() == target.length() && - std::equal(source.begin(), source.end(), target.begin(), - [](const char &s, const char &t) - { return std::tolower(s) == std::tolower(t); }); + return source.length() == target.length() + && std::equal(source.begin(), source.end(), target.begin(), [](const char& s, const char& t) { + return std::tolower(s) == std::tolower(t); + }); } -bool equalCaseInsensitive(const std::string &source, - const std::string &target, - size_t maxLengthOfComparison) +bool equalCaseInsensitive(const std::string& source, const std::string& target, size_t maxLengthOfComparison) { std::string::const_iterator comparisonEnd; if (source.length() < maxLengthOfComparison) @@ -344,17 +329,19 @@ bool equalCaseInsensitive(const std::string &source, comparisonEnd = source.begin() + maxLengthOfComparison; } return std::equal(source.begin(), comparisonEnd, target.begin(), - [](const char &s, const char &t) - { return std::tolower(s) == std::tolower(t); }); + [](const char& s, const char& t) { return std::tolower(s) == std::tolower(t); }); } /******************************************************************** * TextLineWrapperSettings */ -TextLineWrapperSettings::TextLineWrapperSettings() - : maxLength_(0), indent_(0), firstLineIndent_(-1), - bKeepFinalSpaces_(false), continuationChar_('\0') +TextLineWrapperSettings::TextLineWrapperSettings() : + maxLength_(0), + indent_(0), + firstLineIndent_(-1), + bKeepFinalSpaces_(false), + continuationChar_('\0') { } @@ -365,12 +352,10 @@ TextLineWrapperSettings::TextLineWrapperSettings() bool TextLineWrapper::isTrivial() const { - return settings_.lineLength() == 0 && settings_.indent() == 0 - && settings_.firstLineIndent_ <= 0; + return settings_.lineLength() == 0 && settings_.indent() == 0 && settings_.firstLineIndent_ <= 0; } -size_t -TextLineWrapper::findNextLine(const char *input, size_t lineStart) const +size_t TextLineWrapper::findNextLine(const char* input, size_t lineStart) const { size_t inputLength = std::strlen(input); bool bFirstLine = (lineStart == 0 || input[lineStart - 1] == '\n'); @@ -385,37 +370,31 @@ TextLineWrapper::findNextLine(const char *input, size_t lineStart) const } int indent = (bFirstLine ? settings_.firstLineIndent() : settings_.indent()); - size_t lastAllowedBreakPoint - = (settings_.lineLength() > 0 - ? std::min(lineStart + settings_.lineLength() - indent, inputLength) - : inputLength); + size_t lastAllowedBreakPoint = + (settings_.lineLength() > 0 ? std::min(lineStart + settings_.lineLength() - indent, inputLength) + : inputLength); // Ignore trailing whitespace. lastAllowedBreakPoint += std::strspn(input + lastAllowedBreakPoint, " "); size_t lineEnd = lineStart; do { - const char *nextBreakPtr = std::strpbrk(input + lineEnd, " \n"); - size_t nextBreak - = (nextBreakPtr != nullptr ? nextBreakPtr - input : inputLength); + const char* nextBreakPtr = std::strpbrk(input + lineEnd, " \n"); + size_t nextBreak = (nextBreakPtr != nullptr ? nextBreakPtr - input : inputLength); if (nextBreak > lastAllowedBreakPoint && lineEnd > lineStart) { break; } lineEnd = nextBreak + 1; - } - while (lineEnd < lastAllowedBreakPoint && input[lineEnd - 1] != '\n'); + } while (lineEnd < lastAllowedBreakPoint && input[lineEnd - 1] != '\n'); return (lineEnd < inputLength ? lineEnd : inputLength); } -size_t -TextLineWrapper::findNextLine(const std::string &input, size_t lineStart) const +size_t TextLineWrapper::findNextLine(const std::string& input, size_t lineStart) const { return findNextLine(input.c_str(), lineStart); } -std::string -TextLineWrapper::formatLine(const std::string &input, - size_t lineStart, size_t lineEnd) const +std::string TextLineWrapper::formatLine(const std::string& input, size_t lineStart, size_t lineEnd) const { size_t inputLength = input.length(); bool bFirstLine = (lineStart == 0 || input[lineStart - 1] == '\n'); @@ -461,8 +440,7 @@ TextLineWrapper::formatLine(const std::string &input, return result; } -std::string -TextLineWrapper::wrapToString(const std::string &input) const +std::string TextLineWrapper::wrapToString(const std::string& input) const { std::string result; size_t lineStart = 0; @@ -471,8 +449,7 @@ TextLineWrapper::wrapToString(const std::string &input) const { size_t nextLineStart = findNextLine(input, lineStart); result.append(formatLine(input, lineStart, nextLineStart)); - if (nextLineStart < length - || (nextLineStart == length && input[length - 1] == '\n')) + if (nextLineStart < length || (nextLineStart == length && input[length - 1] == '\n')) { result.append("\n"); } @@ -481,8 +458,7 @@ TextLineWrapper::wrapToString(const std::string &input) const return result; } -std::vector -TextLineWrapper::wrapToVector(const std::string &input) const +std::vector TextLineWrapper::wrapToVector(const std::string& input) const { std::vector result; size_t lineStart = 0; diff --git a/src/gromacs/utility/stringutil.h b/src/gromacs/utility/stringutil.h index 4a5f4f4749..5bc06b842b 100644 --- a/src/gromacs/utility/stringutil.h +++ b/src/gromacs/utility/stringutil.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +61,7 @@ namespace gmx * * Does not throw. */ -static inline bool isNullOrEmpty(const char *str) +static inline bool isNullOrEmpty(const char* str) { return str == nullptr || str[0] == '\0'; } @@ -75,12 +76,12 @@ static inline bool isNullOrEmpty(const char *str) * Returns true if \p prefix is empty. * Does not throw. */ -static inline bool startsWith(const std::string &str, const std::string &prefix) +static inline bool startsWith(const std::string& str, const std::string& prefix) { return str.compare(0, prefix.length(), prefix) == 0; } //! \copydoc startsWith(const std::string &, const std::string &) -static inline bool startsWith(const char *str, const char *prefix) +static inline bool startsWith(const char* str, const char* prefix) { return std::strncmp(str, prefix, std::strlen(prefix)) == 0; } @@ -95,9 +96,9 @@ static inline bool startsWith(const char *str, const char *prefix) * Returns true if \p suffix is NULL or empty. * Does not throw. */ -bool endsWith(const char *str, const char *suffix); +bool endsWith(const char* str, const char* suffix); //! \copydoc endsWith(const char *, const char *) -static inline bool endsWith(const std::string &str, const char *suffix) +static inline bool endsWith(const std::string& str, const char* suffix) { return endsWith(str.c_str(), suffix); } @@ -111,12 +112,12 @@ static inline bool endsWith(const std::string &str, const char *suffix) * * Does not throw. */ -static inline bool contains(const std::string &str, const char *substr) +static inline bool contains(const std::string& str, const char* substr) { return str.find(substr) != std::string::npos; } //! \copydoc contains(const std::string &str, const char *substr) -static inline bool contains(const std::string &str, const std::string &substr) +static inline bool contains(const std::string& str, const std::string& substr) { return str.find(substr) != std::string::npos; } @@ -130,8 +131,7 @@ static inline bool contains(const std::string &str, const std::string &substr) * \note This routine is mainly meant to support legacy code in GROMACS. For * new source you should try hard to use C++ string objects instead. */ -std::size_t -countWords(const char *s); +std::size_t countWords(const char* s); /*!\brief Returns the number of space-separated words in a string object * @@ -139,11 +139,10 @@ countWords(const char *s); * * \returns number of words in string. */ -std::size_t -countWords(const std::string &str); +std::size_t countWords(const std::string& str); //! \copydoc endsWith(const std::string &str, const char *suffix) -static inline bool endsWith(const std::string &str, const std::string &suffix) +static inline bool endsWith(const std::string& str, const std::string& suffix) { return endsWith(str, suffix.c_str()); } @@ -159,7 +158,7 @@ static inline bool endsWith(const std::string &str, const std::string &suffix) * * Returns \p str if \p suffix is NULL or empty. */ -std::string stripSuffixIfPresent(const std::string &str, const char *suffix); +std::string stripSuffixIfPresent(const std::string& str, const char* suffix); /*! \brief * Removes leading and trailing whitespace from a string. * @@ -167,10 +166,10 @@ std::string stripSuffixIfPresent(const std::string &str, const char *suffix); * \returns \p str with leading and trailing whitespaces removed. * \throws std::bad_alloc if out of memory. */ -std::string stripString(const std::string &str); +std::string stripString(const std::string& str); #ifdef __GNUC__ -#define gmx_format(archetype, string_index, first_to_check) \ - __attribute__ ((format (archetype, string_index, first_to_check))) +# define gmx_format(archetype, string_index, first_to_check) \ + __attribute__((format(archetype, string_index, first_to_check))) #else /*! \brief GCC like function format attribute * @@ -181,17 +180,17 @@ std::string stripString(const std::string &str); * definitions (GCC limitation). For member functions the implicit `this` * pointer is included in the argument count. */ -#define gmx_format(archetype, string_index, first_to_check) +# define gmx_format(archetype, string_index, first_to_check) #endif #ifdef _MSC_VER -#define gmx_fmtstr _In_ _Printf_format_string_ +# define gmx_fmtstr _In_ _Printf_format_string_ #else /*! \brief MSVC like function format attribute * * Does type checking for printf like format strings in MSVC style. * Attribute has to be placed before format string. */ -#define gmx_fmtstr +# define gmx_fmtstr #endif /*! \brief * Formats a string (snprintf() wrapper). @@ -202,7 +201,7 @@ std::string stripString(const std::string &str); * instead of requiring a preallocated buffer. Arbitrary length output is * supported. */ -std::string formatString(gmx_fmtstr const char *fmt, ...) gmx_format(printf, 1, 2); +std::string formatString(gmx_fmtstr const char* fmt, ...) gmx_format(printf, 1, 2); /*! \brief * Formats a string (vsnprintf() wrapper). @@ -213,33 +212,31 @@ std::string formatString(gmx_fmtstr const char *fmt, ...) gmx_format(printf, 1, * instead of requiring a preallocated buffer. Arbitrary length output is * supported. */ -std::string formatStringV(const char *fmt, va_list ap); +std::string formatStringV(const char* fmt, va_list ap); /*! \brief Function object that wraps a call to formatString() that * expects a single conversion argument, for use with algorithms. */ class StringFormatter { - public: - /*! \brief Constructor - * - * \param[in] format The printf-style format string that will - * be applied to convert values of type T to - * string. Exactly one argument to the conversion - * specification(s) in `format` is supported. */ - explicit StringFormatter(const char *format) : format_(format) - { - } - - //! Implements the formatting functionality - template - std::string operator()(const T &value) const - { - return formatString(format_, value); - } - - private: - //! Format string to use - const char *format_; +public: + /*! \brief Constructor + * + * \param[in] format The printf-style format string that will + * be applied to convert values of type T to + * string. Exactly one argument to the conversion + * specification(s) in `format` is supported. */ + explicit StringFormatter(const char* format) : format_(format) {} + + //! Implements the formatting functionality + template + std::string operator()(const T& value) const + { + return formatString(format_, value); + } + +private: + //! Format string to use + const char* format_; }; /*! \brief Function object to implement the same interface as @@ -247,12 +244,9 @@ class StringFormatter * further. */ class IdentityFormatter { - public: - //! Implements the formatting non-functionality - std::string operator()(const std::string &value) const - { - return value; - } +public: + //! Implements the formatting non-functionality + std::string operator()(const std::string& value) const { return value; } }; /*! \brief Formats all the range as strings, and then joins them with @@ -267,11 +261,11 @@ class IdentityFormatter * as strings and concatenated with `separator` between each pair. * \throws std::bad_alloc if out of memory. */ -template -std::string formatAndJoin(InputIterator begin, InputIterator end, const char *separator, const FormatterType &formatter) +template +std::string formatAndJoin(InputIterator begin, InputIterator end, const char* separator, const FormatterType& formatter) { std::string result; - const char *currentSeparator = ""; + const char* currentSeparator = ""; for (InputIterator i = begin; i != end; ++i) { result.append(currentSeparator); @@ -292,8 +286,8 @@ std::string formatAndJoin(InputIterator begin, InputIterator end, const char *se * concatenated with `separator` between each pair. * \throws std::bad_alloc if out of memory. */ -template -std::string formatAndJoin(const ContainerType &container, const char *separator, const FormatterType &formatter) +template +std::string formatAndJoin(const ContainerType& container, const char* separator, const FormatterType& formatter) { return formatAndJoin(container.begin(), container.end(), separator, formatter); } @@ -308,9 +302,8 @@ std::string formatAndJoin(const ContainerType &container, const char *separator, * between each pair. * \throws std::bad_alloc if out of memory. */ -template -std::string joinStrings(InputIterator begin, InputIterator end, - const char *separator) +template +std::string joinStrings(InputIterator begin, InputIterator end, const char* separator) { return formatAndJoin(begin, end, separator, IdentityFormatter()); } @@ -324,8 +317,8 @@ std::string joinStrings(InputIterator begin, InputIterator end, * between each pair. * \throws std::bad_alloc if out of memory. */ -template -std::string joinStrings(const ContainerType &container, const char *separator) +template +std::string joinStrings(const ContainerType& container, const char* separator) { return joinStrings(container.begin(), container.end(), separator); } @@ -340,8 +333,8 @@ std::string joinStrings(const ContainerType &container, const char *separator) * between each pair. * \throws std::bad_alloc if out of memory. */ -template -std::string joinStrings(const char *const (&array)[count], const char *separator) +template +std::string joinStrings(const char* const (&array)[count], const char* separator) { return joinStrings(array, array + count, separator); } @@ -357,7 +350,7 @@ std::string joinStrings(const char *const (&array)[count], const char *separator * whitespace is ignored, and consecutive whitespaces are treated as a single * separator. */ -std::vector splitString(const std::string &str); +std::vector splitString(const std::string& str); /*! \brief * Splits a string to tokens separated by a given delimiter. * @@ -370,7 +363,7 @@ std::vector splitString(const std::string &str); * will leading or trailing delimiters. * Empty input will return an empty vector. */ -std::vector splitDelimitedString(const std::string &str, char delim); +std::vector splitDelimitedString(const std::string& str, char delim); /*! \brief * Splits \c str to tokens separated by delimiter \c delim. Removes * leading and trailing whitespace from those strings with std::isspace. @@ -386,7 +379,7 @@ std::vector splitDelimitedString(const std::string &str, char delim * Input with only whitespace will return a vector of size 1, * that contains an empty token. */ -std::vector splitAndTrimDelimitedString(const std::string &str, char delim); +std::vector splitAndTrimDelimitedString(const std::string& str, char delim); /*! \brief * Replace all occurrences of a string with another string. @@ -405,11 +398,9 @@ std::vector splitAndTrimDelimitedString(const std::string &str, cha * * \see replaceAllWords() */ -std::string replaceAll(const std::string &input, - const char *from, const char *to); +std::string replaceAll(const std::string& input, const char* from, const char* to); //! \copydoc replaceAll(const std::string &, const char *, const char *) -std::string replaceAll(const std::string &input, - const std::string &from, const std::string &to); +std::string replaceAll(const std::string& input, const std::string& from, const std::string& to); /*! \brief * Replace whole words with others. * @@ -424,11 +415,9 @@ std::string replaceAll(const std::string &input, * * \see replaceAll() */ -std::string replaceAllWords(const std::string &input, - const char *from, const char *to); +std::string replaceAllWords(const std::string& input, const char* from, const char* to); //! \copydoc replaceAllWords(const std::string &, const char *, const char *) -std::string replaceAllWords(const std::string &input, - const std::string &from, const std::string &to); +std::string replaceAllWords(const std::string& input, const std::string& from, const std::string& to); /*! \brief Return whether two strings are equal, ignoring case. * @@ -440,8 +429,7 @@ std::string replaceAllWords(const std::string &input, * \param[in] target String to be matched to \p source. * \returns True if the strings match. */ -bool equalCaseInsensitive(const std::string &source, - const std::string &target); +bool equalCaseInsensitive(const std::string& source, const std::string& target); /*! \brief * Checks if at most \p maxLengthOfComparison characters of two strings match case insensitive. @@ -460,9 +448,7 @@ bool equalCaseInsensitive(const std::string &source, * \param[in] maxLengthOfComparison The maximum string length to compare. * \returns True if the strings match. */ -bool equalCaseInsensitive(const std::string &source, - const std::string &target, - size_t maxLengthOfComparison); +bool equalCaseInsensitive(const std::string& source, const std::string& target, size_t maxLengthOfComparison); class TextLineWrapper; @@ -477,110 +463,104 @@ class TextLineWrapper; */ class TextLineWrapperSettings { - public: - /*! \brief - * Initializes default wrapper settings. - * - * Default settings are: - * - No maximum line width (only explicit line breaks). - * - No indentation. - * - No continuation characters. - * - Do not keep final spaces in input strings. - */ - TextLineWrapperSettings(); - - /*! \brief - * Sets the maximum length for output lines. - * - * \param[in] length Maximum length for the lines after wrapping. - * - * If this method is not called, or is called with zero \p length, the - * wrapper has no maximum length (only wraps at explicit line breaks). - */ - void setLineLength(int length) { maxLength_ = length; } - /*! \brief - * Sets the indentation for output lines. - * - * \param[in] indent Number of spaces to add for indentation. - * - * If this method is not called, the wrapper does not add indentation. - */ - void setIndent(int indent) { indent_ = indent; } - /*! \brief - * Sets the indentation for first output line after a line break. - * - * \param[in] indent Number of spaces to add for indentation. - * - * If this method is not called, or called with \p indent equal to -1, - * the value set with setIndent() is used. - */ - void setFirstLineIndent(int indent) { firstLineIndent_ = indent; } - /*! \brief - * Sets whether final spaces in input should be kept. - * - * \param[in] bKeep Whether to keep spaces at the end of the input. - * - * This means that wrapping a string that ends in spaces also keeps - * those spaces in the output. This allows using the wrapper for - * partial lines where the initial part of the line may end in a space. - * By default, all trailing whitespace is removed. Note that this - * option does not affect spaces before an explicit newline: those are - * always removed. - */ - void setKeepFinalSpaces(bool bKeep) { bKeepFinalSpaces_ = bKeep; } - /*! \brief - * Sets a continuation marker for wrapped lines. - * - * \param[in] continuationChar Character to use to mark continuation - * lines. - * - * If set to non-zero character code, this character is added at the - * end of each line where a line break is added by TextLineWrapper - * (but not after lines produced by explicit line breaks). - * The default (\c '\0') is to not add continuation markers. - * - * Note that currently, the continuation char may cause the output line - * length to exceed the value set with setLineLength() by at most two - * characters. - */ - void setContinuationChar(char continuationChar) - { - continuationChar_ = continuationChar; - } - - //! Returns the maximum length set with setLineLength(). - int lineLength() const { return maxLength_; } - //! Returns the indentation set with setIndent(). - int indent() const { return indent_; } - /*! \brief - * Returns the indentation set with setFirstLineIndent(). - * - * If setFirstLineIndent() has not been called or has been called with - * -1, indent() is returned. - */ - int firstLineIndent() const - { - return (firstLineIndent_ >= 0 ? firstLineIndent_ : indent_); - } - - private: - //! Maximum length of output lines, or <= 0 if no limit. - int maxLength_; - //! Number of spaces to indent each output line with. - int indent_; - /*! \brief - * Number of spaces to indent the first line after a newline. - * - * If -1, \a indent_ is used. - */ - int firstLineIndent_; - //! Whether to keep spaces at end of input. - bool bKeepFinalSpaces_; - //! If not \c '\0', mark each wrapping point with this character. - char continuationChar_; - - //! Needed to access the members. - friend class TextLineWrapper; +public: + /*! \brief + * Initializes default wrapper settings. + * + * Default settings are: + * - No maximum line width (only explicit line breaks). + * - No indentation. + * - No continuation characters. + * - Do not keep final spaces in input strings. + */ + TextLineWrapperSettings(); + + /*! \brief + * Sets the maximum length for output lines. + * + * \param[in] length Maximum length for the lines after wrapping. + * + * If this method is not called, or is called with zero \p length, the + * wrapper has no maximum length (only wraps at explicit line breaks). + */ + void setLineLength(int length) { maxLength_ = length; } + /*! \brief + * Sets the indentation for output lines. + * + * \param[in] indent Number of spaces to add for indentation. + * + * If this method is not called, the wrapper does not add indentation. + */ + void setIndent(int indent) { indent_ = indent; } + /*! \brief + * Sets the indentation for first output line after a line break. + * + * \param[in] indent Number of spaces to add for indentation. + * + * If this method is not called, or called with \p indent equal to -1, + * the value set with setIndent() is used. + */ + void setFirstLineIndent(int indent) { firstLineIndent_ = indent; } + /*! \brief + * Sets whether final spaces in input should be kept. + * + * \param[in] bKeep Whether to keep spaces at the end of the input. + * + * This means that wrapping a string that ends in spaces also keeps + * those spaces in the output. This allows using the wrapper for + * partial lines where the initial part of the line may end in a space. + * By default, all trailing whitespace is removed. Note that this + * option does not affect spaces before an explicit newline: those are + * always removed. + */ + void setKeepFinalSpaces(bool bKeep) { bKeepFinalSpaces_ = bKeep; } + /*! \brief + * Sets a continuation marker for wrapped lines. + * + * \param[in] continuationChar Character to use to mark continuation + * lines. + * + * If set to non-zero character code, this character is added at the + * end of each line where a line break is added by TextLineWrapper + * (but not after lines produced by explicit line breaks). + * The default (\c '\0') is to not add continuation markers. + * + * Note that currently, the continuation char may cause the output line + * length to exceed the value set with setLineLength() by at most two + * characters. + */ + void setContinuationChar(char continuationChar) { continuationChar_ = continuationChar; } + + //! Returns the maximum length set with setLineLength(). + int lineLength() const { return maxLength_; } + //! Returns the indentation set with setIndent(). + int indent() const { return indent_; } + /*! \brief + * Returns the indentation set with setFirstLineIndent(). + * + * If setFirstLineIndent() has not been called or has been called with + * -1, indent() is returned. + */ + int firstLineIndent() const { return (firstLineIndent_ >= 0 ? firstLineIndent_ : indent_); } + +private: + //! Maximum length of output lines, or <= 0 if no limit. + int maxLength_; + //! Number of spaces to indent each output line with. + int indent_; + /*! \brief + * Number of spaces to indent the first line after a newline. + * + * If -1, \a indent_ is used. + */ + int firstLineIndent_; + //! Whether to keep spaces at end of input. + bool bKeepFinalSpaces_; + //! If not \c '\0', mark each wrapping point with this character. + char continuationChar_; + + //! Needed to access the members. + friend class TextLineWrapper; }; /*! \brief @@ -619,131 +599,125 @@ class TextLineWrapperSettings */ class TextLineWrapper { - public: - /*! \brief - * Constructs a new line wrapper with default settings. - * - * Does not throw. - */ - TextLineWrapper() - { - } - /*! \brief - * Constructs a new line wrapper with given settings. - * - * \param[in] settings Wrapping settings. - * - * Does not throw. - */ - explicit TextLineWrapper(const TextLineWrapperSettings &settings) - : settings_(settings) - { - } - - /*! \brief - * Provides access to settings of this wrapper. - * - * \returns The settings object for this wrapper. - * - * The returned object can be used to modify settings for the wrapper. - * All subsequent calls to wrapToString() and wrapToVector() use the - * modified settings. - * - * Does not throw. - */ - TextLineWrapperSettings &settings() { return settings_; } - - //! Returns true if the wrapper would not modify the input string. - bool isTrivial() const; - - /*! \brief - * Finds the next line to be wrapped. - * - * \param[in] input String to wrap. - * \param[in] lineStart Index of first character of the line to find. - * \returns Index of first character of the next line. - * - * If this is the last line, returns the length of \p input. - * In determining the length of the returned line, this function - * considers the maximum line length, leaving space for indentation, - * and also whitespace stripping behavior. - * Thus, the line returned may be longer than the maximum line length - * if it has leading and/or trailing space. - * When wrapping a line on a space (not on an explicit line break), - * the returned index is always on a non-whitespace character after the - * space. - * - * To iterate over lines in a string, use the following code: - * \code - gmx::TextLineWrapper wrapper; - // - size_t lineStart = 0; - size_t length = input.length(); - while (lineStart < length) - { - size_t nextLineStart = wrapper.findNextLine(input, lineStart); - std::string line = wrapper.formatLine(input, lineStart, nextLineStart)); - // - lineStart = nextLineStart; - } - return result; - \endcode - * - * Does not throw. - */ - size_t findNextLine(const char *input, size_t lineStart) const; - //! \copydoc findNextLine(const char *, size_t)const - size_t findNextLine(const std::string &input, size_t lineStart) const; - /*! \brief - * Formats a single line for output according to wrapping settings. - * - * \param[in] input Input string. - * \param[in] lineStart Index of first character of the line to format. - * \param[in] lineEnd Index of first character of the next line. - * \returns The line with leading and/or trailing whitespace removed - * and indentation applied. - * \throws std::bad_alloc if out of memory. - * - * Intended to be used on the lines found by findNextLine(). - * When used with the lines returned from findNextLine(), the returned - * line conforms to the wrapper settings. - * Trailing whitespace is always stripped (including any newlines, - * i.e., the return value does not contain a newline). - */ - std::string formatLine(const std::string &input, - size_t lineStart, size_t lineEnd) const; - - /*! \brief - * Formats a string, producing a single string with all the lines. - * - * \param[in] input String to wrap. - * \returns \p input with added newlines such that maximum line - * length is not exceeded. - * \throws std::bad_alloc if out of memory. - * - * Newlines in the input are preserved, including terminal newlines. - * Note that if the input does not contain a terminal newline, the - * output does not either. - */ - std::string wrapToString(const std::string &input) const; - /*! \brief - * Formats a string, producing a vector with all the lines. - * - * \param[in] input String to wrap. - * \returns \p input split into lines such that maximum line length - * is not exceeded. - * \throws std::bad_alloc if out of memory. - * - * The strings in the returned vector do not contain newlines at the - * end. - * Note that a single terminal newline does not affect the output: - * "line\\n" and "line" both produce the same output (but "line\\n\\n" - * produces two lines, the second of which is empty). - */ - std::vector wrapToVector(const std::string &input) const; - - private: - TextLineWrapperSettings settings_; +public: + /*! \brief + * Constructs a new line wrapper with default settings. + * + * Does not throw. + */ + TextLineWrapper() {} + /*! \brief + * Constructs a new line wrapper with given settings. + * + * \param[in] settings Wrapping settings. + * + * Does not throw. + */ + explicit TextLineWrapper(const TextLineWrapperSettings& settings) : settings_(settings) {} + + /*! \brief + * Provides access to settings of this wrapper. + * + * \returns The settings object for this wrapper. + * + * The returned object can be used to modify settings for the wrapper. + * All subsequent calls to wrapToString() and wrapToVector() use the + * modified settings. + * + * Does not throw. + */ + TextLineWrapperSettings& settings() { return settings_; } + + //! Returns true if the wrapper would not modify the input string. + bool isTrivial() const; + + /*! \brief + * Finds the next line to be wrapped. + * + * \param[in] input String to wrap. + * \param[in] lineStart Index of first character of the line to find. + * \returns Index of first character of the next line. + * + * If this is the last line, returns the length of \p input. + * In determining the length of the returned line, this function + * considers the maximum line length, leaving space for indentation, + * and also whitespace stripping behavior. + * Thus, the line returned may be longer than the maximum line length + * if it has leading and/or trailing space. + * When wrapping a line on a space (not on an explicit line break), + * the returned index is always on a non-whitespace character after the + * space. + * + * To iterate over lines in a string, use the following code: + * \code + gmx::TextLineWrapper wrapper; + // + size_t lineStart = 0; + size_t length = input.length(); + while (lineStart < length) + { + size_t nextLineStart = wrapper.findNextLine(input, lineStart); + std::string line = wrapper.formatLine(input, lineStart, nextLineStart)); + // + lineStart = nextLineStart; + } + return result; + \endcode + * + * Does not throw. + */ + size_t findNextLine(const char* input, size_t lineStart) const; + //! \copydoc findNextLine(const char *, size_t)const + size_t findNextLine(const std::string& input, size_t lineStart) const; + /*! \brief + * Formats a single line for output according to wrapping settings. + * + * \param[in] input Input string. + * \param[in] lineStart Index of first character of the line to format. + * \param[in] lineEnd Index of first character of the next line. + * \returns The line with leading and/or trailing whitespace removed + * and indentation applied. + * \throws std::bad_alloc if out of memory. + * + * Intended to be used on the lines found by findNextLine(). + * When used with the lines returned from findNextLine(), the returned + * line conforms to the wrapper settings. + * Trailing whitespace is always stripped (including any newlines, + * i.e., the return value does not contain a newline). + */ + std::string formatLine(const std::string& input, size_t lineStart, size_t lineEnd) const; + + /*! \brief + * Formats a string, producing a single string with all the lines. + * + * \param[in] input String to wrap. + * \returns \p input with added newlines such that maximum line + * length is not exceeded. + * \throws std::bad_alloc if out of memory. + * + * Newlines in the input are preserved, including terminal newlines. + * Note that if the input does not contain a terminal newline, the + * output does not either. + */ + std::string wrapToString(const std::string& input) const; + /*! \brief + * Formats a string, producing a vector with all the lines. + * + * \param[in] input String to wrap. + * \returns \p input split into lines such that maximum line length + * is not exceeded. + * \throws std::bad_alloc if out of memory. + * + * The strings in the returned vector do not contain newlines at the + * end. + * Note that a single terminal newline does not affect the output: + * "line\\n" and "line" both produce the same output (but "line\\n\\n" + * produces two lines, the second of which is empty). + */ + std::vector wrapToVector(const std::string& input) const; + +private: + TextLineWrapperSettings settings_; }; //! \} diff --git a/src/gromacs/utility/sysinfo.cpp b/src/gromacs/utility/sysinfo.cpp index f7c0fae210..fefb8758bc 100644 --- a/src/gromacs/utility/sysinfo.cpp +++ b/src/gromacs/utility/sysinfo.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,17 +52,17 @@ #include #ifdef HAVE_SYS_TIME_H -#include +# include #endif #if GMX_NATIVE_WINDOWS -#include -#include +# include +# include #endif #if HAVE_PWD_H -#include +# include #endif #ifdef HAVE_UNISTD_H -#include +# include #endif #include "gromacs/utility/basedefinitions.h" @@ -74,19 +74,19 @@ namespace const char c_unknown[] = "unknown"; } // namespace -int gmx_gethostname(char *buf, size_t len) +int gmx_gethostname(char* buf, size_t len) { GMX_RELEASE_ASSERT(len >= 8, "Input buffer is too short"); #if GMX_NATIVE_WINDOWS - DWORD dlen = len; + DWORD dlen = len; if (GetComputerName(buf, &dlen)) { return 0; } #elif defined(HAVE_UNISTD_H) && !defined(__native_client__) - if (gethostname(buf, len-1) == 0) + if (gethostname(buf, len - 1) == 0) { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; return 0; } #endif @@ -112,21 +112,21 @@ int gmx_getuid() #endif } -int gmx_getusername(char *buf, size_t len) +int gmx_getusername(char* buf, size_t len) { GMX_RELEASE_ASSERT(len >= 8, "Input buffer is too short"); // TODO: nice_header() used getpwuid() instead; consider using getpwuid_r() // here. If not, get rid of HAVE_PWD_H completely. #if GMX_NATIVE_WINDOWS - DWORD dlen = len; + DWORD dlen = len; if (GetUserName(buf, &dlen)) { return 0; } -#elif defined(HAVE_UNISTD_H) && !__has_feature(memory_sanitizer) //MSAN Issue 83 +#elif defined(HAVE_UNISTD_H) && !__has_feature(memory_sanitizer) // MSAN Issue 83 if (!getlogin_r(buf, len)) { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; return 0; } #endif @@ -134,15 +134,14 @@ int gmx_getusername(char *buf, size_t len) return -1; } -std::string -gmx_ctime_r(const time_t *clock) +std::string gmx_ctime_r(const time_t* clock) { #ifdef _MSC_VER std::array buf; ctime_s(buf.data(), buf.size(), clock); return std::string(buf.begin(), buf.end()); #elif GMX_NATIVE_WINDOWS - char *tmpbuf = ctime(clock); + char* tmpbuf = ctime(clock); return tmpbuf; #elif (defined(__sun)) /*Solaris*/ diff --git a/src/gromacs/utility/sysinfo.h b/src/gromacs/utility/sysinfo.h index fc32046f36..c4d0b94ca9 100644 --- a/src/gromacs/utility/sysinfo.h +++ b/src/gromacs/utility/sysinfo.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,7 +66,7 @@ * * Does not throw. */ -int gmx_gethostname(char *buf, size_t len); +int gmx_gethostname(char* buf, size_t len); /*! \brief * Returns the process ID of the current process. @@ -89,15 +89,14 @@ int gmx_getuid(); * * Does not throw. */ -int gmx_getusername(char *buf, size_t len); +int gmx_getusername(char* buf, size_t len); /*! \brief * Portable version of ctime_r. * * \throws std::bad_alloc when out of memory. */ -std::string -gmx_ctime_r(const time_t *clock); +std::string gmx_ctime_r(const time_t* clock); /*! \brief * Gets the current time as a string. * diff --git a/src/gromacs/utility/tests/alignedallocator.cpp b/src/gromacs/utility/tests/alignedallocator.cpp index 7e21cc933a..7947d2fddc 100644 --- a/src/gromacs/utility/tests/alignedallocator.cpp +++ b/src/gromacs/utility/tests/alignedallocator.cpp @@ -50,6 +50,7 @@ #include "gromacs/math/vectypes.h" +#ifndef DOXYGEN namespace gmx { namespace test @@ -61,13 +62,14 @@ using AllocatorTypesToTest = ::testing::Types, AlignedAllocator, PageAlignedAllocator, AlignedAllocator, - PageAlignedAllocator - >; + PageAlignedAllocator>; TYPED_TEST_CASE(AllocatorTest, AllocatorTypesToTest); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx + +#endif // Includes tests common to all allocation policies. #include "gromacs/utility/tests/alignedallocator_impl.h" @@ -80,16 +82,15 @@ namespace test TYPED_TEST(AllocatorTest, StatelessAllocatorUsesNoMemory) { using value_type = typename TypeParam::value_type; - EXPECT_EQ(sizeof(std::vector), - sizeof(std::vector)); + EXPECT_EQ(sizeof(std::vector), sizeof(std::vector)); } TEST(AllocatorUntypedTest, Comparison) { - //Should always be true for the same policy, indpendent of value_type + // Should always be true for the same policy, indpendent of value_type EXPECT_EQ(AlignedAllocator{}, AlignedAllocator{}); EXPECT_EQ(PageAlignedAllocator{}, PageAlignedAllocator{}); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/utility/tests/alignedallocator_impl.h b/src/gromacs/utility/tests/alignedallocator_impl.h index 8d240fec74..abf6bdb34e 100644 --- a/src/gromacs/utility/tests/alignedallocator_impl.h +++ b/src/gromacs/utility/tests/alignedallocator_impl.h @@ -63,19 +63,16 @@ namespace test /*! \libinternal * \brief Templated test fixture. */ -template +template class AllocatorTest : public ::testing::Test { - public: - /*! \brief Return a bitmask for testing the alignment. - * - * e.g. for 128-byte alignment the mask is 128-1 - all of - * these bits should be zero in pointers that have the - * intended alignment. */ - std::size_t mask(const T &allocator) - { - return allocator.alignment() - 1; - } +public: + /*! \brief Return a bitmask for testing the alignment. + * + * e.g. for 128-byte alignment the mask is 128-1 - all of + * these bits should be zero in pointers that have the + * intended alignment. */ + std::size_t mask(const T& allocator) { return allocator.alignment() - 1; } }; // NB need to use this->mask() because of GoogleTest quirks @@ -127,13 +124,13 @@ TYPED_TEST(AllocatorTest, Move) //NOLINT(misc-definitions-in-headers) { using value_type = typename TypeParam::value_type; std::vector v1(1); - value_type* data = v1.data(); + value_type* data = v1.data(); EXPECT_NE(data, nullptr); std::vector v2(std::move(v1)); EXPECT_EQ(data, v2.data()); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/gromacs/utility/tests/arrayref.cpp b/src/gromacs/utility/tests/arrayref.cpp index 6cdb84b058..8c9e2759ec 100644 --- a/src/gromacs/utility/tests/arrayref.cpp +++ b/src/gromacs/utility/tests/arrayref.cpp @@ -74,28 +74,27 @@ TEST(EmptyConstArrayRefTest, IsEmpty) #ifdef GTEST_HAS_TYPED_TEST //! Define the types that end up being available as TypeParam in the test cases for both kinds of ArrayRef -typedef ::testing::Types< - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef, - ArrayRef - > ArrayRefTypes; +typedef ::testing::Types, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef, + ArrayRef> + ArrayRefTypes; constexpr index aSize = 3; @@ -103,35 +102,34 @@ constexpr index aSize = 3; * * The main objective is to verify that all the different kinds of * construction lead to the expected result. */ -template +template class ArrayRefTest : public ::testing::Test { - public: - typedef TypeParam ArrayRefType; - typedef typename ArrayRefType::value_type ValueType; - typedef std::remove_const_t NonConstValueType; - - /*! \brief Run the same tests all the time - * - * Note that test cases must call this->runTests(), because - * that's how the derived-class templates that implement - * type-parameterized tests actually work. */ - void runTests(ValueType *aData, - ArrayRefType &arrayRef) +public: + typedef TypeParam ArrayRefType; + typedef typename ArrayRefType::value_type ValueType; + typedef std::remove_const_t NonConstValueType; + + /*! \brief Run the same tests all the time + * + * Note that test cases must call this->runTests(), because + * that's how the derived-class templates that implement + * type-parameterized tests actually work. */ + void runTests(ValueType* aData, ArrayRefType& arrayRef) + { + ASSERT_EQ(aSize, arrayRef.size()); + ASSERT_FALSE(arrayRef.empty()); + EXPECT_EQ(aData, arrayRef.data()); + EXPECT_EQ(a[0], arrayRef.front()); + EXPECT_EQ(a[aSize - 1], arrayRef.back()); + for (index i = 0; i != aSize; ++i) { - ASSERT_EQ(aSize, arrayRef.size()); - ASSERT_FALSE(arrayRef.empty()); - EXPECT_EQ(aData, arrayRef.data()); - EXPECT_EQ(a[0], arrayRef.front()); - EXPECT_EQ(a[aSize-1], arrayRef.back()); - for (index i = 0; i != aSize; ++i) - { - EXPECT_EQ(a[i], arrayRef[i]); - } + EXPECT_EQ(a[i], arrayRef[i]); } + } - ValueType a[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; - NonConstValueType ma[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; + ValueType a[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; + NonConstValueType ma[aSize] = { ValueType(1.2), ValueType(2.4), ValueType(3.1) }; }; TYPED_TEST_CASE(ArrayRefTest, ArrayRefTypes); @@ -178,9 +176,9 @@ using makeConstIf_t = std::conditional_t; TYPED_TEST(ArrayRefTest, ConstructFromVectorWorks) { - makeConstIf_t::value, - std::vector > v(this->a, this->a + aSize); - typename TestFixture::ArrayRefType arrayRef(v); + makeConstIf_t::value, std::vector> v( + this->a, this->a + aSize); + typename TestFixture::ArrayRefType arrayRef(v); this->runTests(v.data(), arrayRef); } @@ -192,12 +190,12 @@ TYPED_TEST(ArrayRefTest, ConstructFromNonConstVectorWorks) } //! Helper struct for the case actually used in mdrun signalling -template +template struct Helper { - public: - T a[3]; - int size; +public: + T a[3]; + int size; }; /*! \brief Test of the case actually used in mdrun signalling @@ -221,21 +219,20 @@ TYPED_TEST(ArrayRefTest, ConstructFromStructFieldWithTemplateConstructorWorks) this->runTests(h.a, arrayRef); } -#else // GTEST_HAS_TYPED_TEST +#else // GTEST_HAS_TYPED_TEST /* A dummy test that at least signals that something is missing if one runs the * unit test executable itself. */ TEST(DISABLED_ArrayRefTest, GenericTests) { - ADD_FAILURE() - << "Tests for generic ArrayRef functionality require support for " - << "Google Test typed tests, which was not available when the tests " - << "were compiled."; + ADD_FAILURE() << "Tests for generic ArrayRef functionality require support for " + << "Google Test typed tests, which was not available when the tests " + << "were compiled."; } #endif // GTEST_HAS_TYPED_TEST -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/utility/tests/bitmask.h b/src/gromacs/utility/tests/bitmask.h index 8a0267f4cf..2cba18b9c9 100644 --- a/src/gromacs/utility/tests/bitmask.h +++ b/src/gromacs/utility/tests/bitmask.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,7 +46,7 @@ #include "gromacs/utility/bitmask.h" //! Implemenation of BITMASK_CLASSNAME -#define BITMASK_CLASSNAME_(S) BitmaskTest ## S +#define BITMASK_CLASSNAME_(S) BitmaskTest##S //! Returns name of Bitmask test fixture class #define BITMASK_CLASSNAME(S) BITMASK_CLASSNAME_(S) //! Implementation of BITMASK_TEST_P @@ -111,7 +111,7 @@ BITMASK_TEST_P(Union) //NOLINT(misc-definitions-in-headers) { gmx_bitmask_t m1, m2; int i = GetParam(); - int j = (i + BITMASK_SIZE/2)%BITMASK_SIZE; + int j = (i + BITMASK_SIZE / 2) % BITMASK_SIZE; bitmask_init_bit(&m1, i); bitmask_init_bit(&m2, j); bitmask_union(&m1, m2); @@ -135,6 +135,6 @@ BITMASK_TEST_P(ToHex) //NOLINT(misc-definitions-in-headers) { gmx_bitmask_t m; bitmask_clear(&m); - bitmask_set_bit(&m, BITMASK_SIZE-1); - EXPECT_EQ(to_hex_string(m), "8" + std::string(BITMASK_SIZE/4-1, '0')); + bitmask_set_bit(&m, BITMASK_SIZE - 1); + EXPECT_EQ(to_hex_string(m), "8" + std::string(BITMASK_SIZE / 4 - 1, '0')); } diff --git a/src/gromacs/utility/tests/defaultinitializationallocator.cpp b/src/gromacs/utility/tests/defaultinitializationallocator.cpp index 1b517f1d83..41b9801c6a 100644 --- a/src/gromacs/utility/tests/defaultinitializationallocator.cpp +++ b/src/gromacs/utility/tests/defaultinitializationallocator.cpp @@ -57,7 +57,7 @@ namespace TEST(DefaultInitializationAllocator, PerformsValueInitialization) { - std::vector < int, DefaultInitializationAllocator < int>> v; + std::vector> v; v.resize(1, 2); EXPECT_EQ(v[0], 2); @@ -65,15 +65,14 @@ TEST(DefaultInitializationAllocator, PerformsValueInitialization) TEST(DefaultInitializationAllocator, PerformsNoInitialization) { - std::vector < int, DefaultInitializationAllocator < int>> v { - 1, 2, 3 - }; + std::vector> v{ 1, 2, 3 }; - const int *oldData = v.data(); + const int* oldData = v.data(); v.resize(0); v.resize(3); GMX_RELEASE_ASSERT(v.data() == oldData, - "According to the C++ standard std::vector will not reallocate when the capacity is sufficient"); + "According to the C++ standard std::vector will not reallocate when the " + "capacity is sufficient"); // The allocation is the same, so the default initialization should // not have changed the contents EXPECT_EQ(v[0], 1); diff --git a/src/gromacs/utility/tests/enumerationhelpers.cpp b/src/gromacs/utility/tests/enumerationhelpers.cpp index d4dbb51dad..b5f84a86bf 100644 --- a/src/gromacs/utility/tests/enumerationhelpers.cpp +++ b/src/gromacs/utility/tests/enumerationhelpers.cpp @@ -56,7 +56,9 @@ namespace //! Type to use in testing enum class Foo { - Bar, Baz, Fooz, + Bar, + Baz, + Fooz, Count }; @@ -89,9 +91,7 @@ TEST(EnumerationHelpersTest, EnumerationWrapperWorks) TEST(EnumerationHelpersTest, EnumerationArrayWorks) { using FooArray = EnumerationArray; - const FooArray fooStrings { { - "Bar", "Baz", "Fooz" - } }; + const FooArray fooStrings{ { "Bar", "Baz", "Fooz" } }; // Keys give you the constants associated with each array index. int i = 0; @@ -109,7 +109,7 @@ TEST(EnumerationHelpersTest, EnumerationArrayWorks) // Using iterators and operator[] gives the array values. i = 0; - for (const auto &s : fooStrings) + for (const auto& s : fooStrings) { EXPECT_EQ(s, fooStrings[i++]); } diff --git a/src/gromacs/utility/tests/fixedcapacityvector.cpp b/src/gromacs/utility/tests/fixedcapacityvector.cpp index 96b2321fde..fb78ecb132 100644 --- a/src/gromacs/utility/tests/fixedcapacityvector.cpp +++ b/src/gromacs/utility/tests/fixedcapacityvector.cpp @@ -102,7 +102,7 @@ TEST(FixedCapacityVectorTest, EmplaceBackWorks) { FixedCapacityVector, 2> v; - const auto &elem = v.emplace_back(5); + const auto& elem = v.emplace_back(5); EXPECT_EQ(1U, v.size()); EXPECT_EQ(5U, elem.size()); } @@ -121,7 +121,7 @@ TEST(FixedCapacityVectorTest, IteratorWorks) { FixedCapacityVector v; - std::vector ref = { 7, 4, 5 }; + std::vector ref = { 7, 4, 5 }; for (auto elem : ref) { @@ -144,7 +144,7 @@ TEST(FixedCapacityVectorTest, ReverseIteratorWorks) { FixedCapacityVector v; - std::vector ref = { 7, 4, 5 }; + std::vector ref = { 7, 4, 5 }; for (auto elem : ref) { @@ -171,6 +171,6 @@ TEST(FixedCapacityVectorTest, ZeroCapacityWorks) EXPECT_TRUE(v.empty()); } -} // namespace +} // namespace -} // namespace gmx +} // namespace gmx diff --git a/src/gromacs/utility/tests/keyvaluetreeserializer.cpp b/src/gromacs/utility/tests/keyvaluetreeserializer.cpp index 815e87e463..c273d1c9b5 100644 --- a/src/gromacs/utility/tests/keyvaluetreeserializer.cpp +++ b/src/gromacs/utility/tests/keyvaluetreeserializer.cpp @@ -55,103 +55,62 @@ void raiseAssert() class RefDataSerializer : public gmx::ISerializer { - public: - RefDataSerializer(gmx::test::TestReferenceChecker *parentChecker, - const char *id) - : checker_(parentChecker->checkCompound("SerializedData", id)) - { - } - - bool reading() const override { return false; } - - void doBool(bool *value) override - { - checker_.checkBoolean(*value, nullptr); - } - void doUChar(unsigned char *value) override - { - checker_.checkUChar(*value, nullptr); - } - void doChar(char * /* value */) override - { - raiseAssert(); - } - void doUShort(unsigned short * /* value */) override - { - raiseAssert(); - } - void doInt(int *value) override - { - checker_.checkInteger(*value, nullptr); - } - void doInt32(int32_t *value) override - { - checker_.checkInt32(*value, nullptr); - } - void doInt64(int64_t *value) override - { - checker_.checkInt64(*value, nullptr); - } - void doFloat(float *value) override - { - checker_.checkFloat(*value, nullptr); - } - void doDouble(double *value) override - { - checker_.checkDouble(*value, nullptr); - } - void doString(std::string *value) override - { - checker_.checkString(*value, nullptr); - } - void doReal(real * /* value */ ) override - { - raiseAssert(); - } - void doIvec(ivec * /* value */) override - { - raiseAssert(); - } - void doRvec(rvec * /* value */) override - { - raiseAssert(); - } - - private: - gmx::test::TestReferenceChecker checker_; +public: + RefDataSerializer(gmx::test::TestReferenceChecker* parentChecker, const char* id) : + checker_(parentChecker->checkCompound("SerializedData", id)) + { + } + + bool reading() const override { return false; } + + void doBool(bool* value) override { checker_.checkBoolean(*value, nullptr); } + void doUChar(unsigned char* value) override { checker_.checkUChar(*value, nullptr); } + void doChar(char* /* value */) override { raiseAssert(); } + void doUShort(unsigned short* /* value */) override { raiseAssert(); } + void doInt(int* value) override { checker_.checkInteger(*value, nullptr); } + void doInt32(int32_t* value) override { checker_.checkInt32(*value, nullptr); } + void doInt64(int64_t* value) override { checker_.checkInt64(*value, nullptr); } + void doFloat(float* value) override { checker_.checkFloat(*value, nullptr); } + void doDouble(double* value) override { checker_.checkDouble(*value, nullptr); } + void doString(std::string* value) override { checker_.checkString(*value, nullptr); } + void doReal(real* /* value */) override { raiseAssert(); } + void doIvec(ivec* /* value */) override { raiseAssert(); } + void doRvec(rvec* /* value */) override { raiseAssert(); } + +private: + gmx::test::TestReferenceChecker checker_; }; class KeyValueTreeSerializerTest : public ::testing::Test { - public: - void runTest() - { - gmx::KeyValueTreeObject input(builder_.build()); - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - checker.checkKeyValueTreeObject(input, "Input"); - { - RefDataSerializer serializer(&checker, "Stream"); - gmx::serializeKeyValueTree(input, &serializer); - } - std::vector buffer = serializeTree(input); - { - gmx::InMemoryDeserializer deserializer(buffer, false); - gmx::KeyValueTreeObject output - = gmx::deserializeKeyValueTree(&deserializer); - checker.checkKeyValueTreeObject(output, "Input"); - } - } - - gmx::KeyValueTreeBuilder builder_; - - private: - std::vector serializeTree(const gmx::KeyValueTreeObject &tree) - { - gmx::InMemorySerializer serializer; - gmx::serializeKeyValueTree(tree, &serializer); - return serializer.finishAndGetBuffer(); - } +public: + void runTest() + { + gmx::KeyValueTreeObject input(builder_.build()); + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + checker.checkKeyValueTreeObject(input, "Input"); + { + RefDataSerializer serializer(&checker, "Stream"); + gmx::serializeKeyValueTree(input, &serializer); + } + std::vector buffer = serializeTree(input); + { + gmx::InMemoryDeserializer deserializer(buffer, false); + gmx::KeyValueTreeObject output = gmx::deserializeKeyValueTree(&deserializer); + checker.checkKeyValueTreeObject(output, "Input"); + } + } + + gmx::KeyValueTreeBuilder builder_; + +private: + std::vector serializeTree(const gmx::KeyValueTreeObject& tree) + { + gmx::InMemorySerializer serializer; + gmx::serializeKeyValueTree(tree, &serializer); + return serializer.finishAndGetBuffer(); + } }; TEST_F(KeyValueTreeSerializerTest, EmptyTree) diff --git a/src/gromacs/utility/tests/keyvaluetreetransform.cpp b/src/gromacs/utility/tests/keyvaluetreetransform.cpp index c512cf6382..1d119bae61 100644 --- a/src/gromacs/utility/tests/keyvaluetreetransform.cpp +++ b/src/gromacs/utility/tests/keyvaluetreetransform.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -56,105 +56,102 @@ namespace class TreeValueTransformTest : public ::testing::Test { - public: - void testTransform(const gmx::KeyValueTreeObject &input, - const gmx::KeyValueTreeTransformer &transform) +public: + void testTransform(const gmx::KeyValueTreeObject& input, const gmx::KeyValueTreeTransformer& transform) + { + gmx::KeyValueTreeTransformResult result = transform.transform(input, nullptr); + gmx::KeyValueTreeObject object = result.object(); + + gmx::test::TestReferenceData data; + gmx::test::TestReferenceChecker checker(data.rootChecker()); + checker.checkKeyValueTreeObject(input, "Input"); + auto mappedPaths = transform.mappedPaths(); + checker.checkSequence(mappedPaths.begin(), mappedPaths.end(), "MappedPaths", + &TreeValueTransformTest::checkMappedPath); + checker.checkKeyValueTreeObject(object, "Tree"); + checkBackMapping(&checker, object, result.backMapping()); + } + +private: + static void checkMappedPath(gmx::test::TestReferenceChecker* checker, const gmx::KeyValueTreePath& path) + { + checker->checkString(path.toString(), nullptr); + } + void checkBackMapping(gmx::test::TestReferenceChecker* checker, + const gmx::KeyValueTreeObject& object, + const gmx::IKeyValueTreeBackMapping& mapping) + { + auto compound(checker->checkCompound("BackMapping", "Mapping")); + checkBackMappingImpl(&compound, object, mapping, gmx::KeyValueTreePath()); + } + + void checkBackMappingImpl(gmx::test::TestReferenceChecker* checker, + const gmx::KeyValueTreeObject& object, + const gmx::IKeyValueTreeBackMapping& mapping, + const gmx::KeyValueTreePath& prefix) + { + for (const auto& prop : object.properties()) { - gmx::KeyValueTreeTransformResult result = transform.transform(input, nullptr); - gmx::KeyValueTreeObject object = result.object(); - - gmx::test::TestReferenceData data; - gmx::test::TestReferenceChecker checker(data.rootChecker()); - checker.checkKeyValueTreeObject(input, "Input"); - auto mappedPaths = transform.mappedPaths(); - checker.checkSequence(mappedPaths.begin(), mappedPaths.end(), "MappedPaths", - &TreeValueTransformTest::checkMappedPath); - checker.checkKeyValueTreeObject(object, "Tree"); - checkBackMapping(&checker, object, result.backMapping()); - } - - private: - static void checkMappedPath(gmx::test::TestReferenceChecker *checker, - const gmx::KeyValueTreePath &path) - { - checker->checkString(path.toString(), nullptr); - } - void checkBackMapping(gmx::test::TestReferenceChecker *checker, - const gmx::KeyValueTreeObject &object, - const gmx::IKeyValueTreeBackMapping &mapping) - { - auto compound(checker->checkCompound("BackMapping", "Mapping")); - checkBackMappingImpl(&compound, object, mapping, gmx::KeyValueTreePath()); - } - - void checkBackMappingImpl(gmx::test::TestReferenceChecker *checker, - const gmx::KeyValueTreeObject &object, - const gmx::IKeyValueTreeBackMapping &mapping, - const gmx::KeyValueTreePath &prefix) - { - for (const auto &prop : object.properties()) + gmx::KeyValueTreePath path = prefix; + path.append(prop.key()); + if (prop.value().isObject()) + { + checkBackMappingImpl(checker, prop.value().asObject(), mapping, path); + } + else { - gmx::KeyValueTreePath path = prefix; - path.append(prop.key()); - if (prop.value().isObject()) - { - checkBackMappingImpl(checker, prop.value().asObject(), mapping, path); - } - else - { - gmx::KeyValueTreePath orgPath = mapping.originalPath(path); - checker->checkString(orgPath.toString(), path.toString().c_str()); - } + gmx::KeyValueTreePath orgPath = mapping.originalPath(path); + checker->checkString(orgPath.toString(), path.toString().c_str()); } } + } }; TEST_F(TreeValueTransformTest, SimpleTransforms) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "1"); builder.rootObject().addValue("b", "2"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .from("/a").to("/i").transformWith(&gmx::fromStdString); - transform.rules()->addRule() - .from("/b").to("/j").transformWith(&gmx::fromStdString); + transform.rules()->addRule().from("/a").to("/i").transformWith( + &gmx::fromStdString); + transform.rules()->addRule().from("/b").to("/j").transformWith( + &gmx::fromStdString); testTransform(input, transform); } TEST_F(TreeValueTransformTest, SimpleTransformsCaseAndDashInsensitive) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a-x", "1"); builder.rootObject().addValue("by", "2"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive); - transform.rules()->addRule() - .from("/Ax").to("/i").transformWith(&gmx::fromStdString); - transform.rules()->addRule() - .from("/B-Y").to("/j").transformWith(&gmx::fromStdString); + transform.rules()->addRule().keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive); + transform.rules()->addRule().from("/Ax").to("/i").transformWith( + &gmx::fromStdString); + transform.rules()->addRule().from("/B-Y").to("/j").transformWith( + &gmx::fromStdString); testTransform(input, transform); } TEST_F(TreeValueTransformTest, SimpleTransformsToObject) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "1"); builder.rootObject().addValue("b", "2"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .from("/a").to("/foo/i").transformWith(&gmx::fromStdString); - transform.rules()->addRule() - .from("/b").to("/foo/j").transformWith(&gmx::fromStdString); + transform.rules()->addRule().from("/a").to("/foo/i").transformWith( + &gmx::fromStdString); + transform.rules()->addRule().from("/b").to("/foo/j").transformWith( + &gmx::fromStdString); testTransform(input, transform); } @@ -162,15 +159,13 @@ TEST_F(TreeValueTransformTest, SimpleTransformsToObject) TEST_F(TreeValueTransformTest, ObjectFromString) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "1 2"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .from("/a").toObject("/foo").transformWith( - [] (gmx::KeyValueTreeObjectBuilder *builder, const std::string &value) - { + transform.rules()->addRule().from("/a").toObject("/foo").transformWith( + [](gmx::KeyValueTreeObjectBuilder* builder, const std::string& value) { std::vector values = gmx::splitString(value); builder->addValue("a", gmx::fromString(values[0])); builder->addValue("b", gmx::fromString(values[1])); @@ -181,18 +176,16 @@ TEST_F(TreeValueTransformTest, ObjectFromString) TEST_F(TreeValueTransformTest, ObjectFromMultipleStrings) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "1"); builder.rootObject().addValue("b", "2 3"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .from("/a").to("/foo/a").transformWith(&gmx::fromStdString); - transform.rules()->addRule() - .from("/b").toObject("/foo").transformWith( - [] (gmx::KeyValueTreeObjectBuilder *builder, const std::string &value) - { + transform.rules()->addRule().from("/a").to("/foo/a").transformWith( + &gmx::fromStdString); + transform.rules()->addRule().from("/b").toObject("/foo").transformWith( + [](gmx::KeyValueTreeObjectBuilder* builder, const std::string& value) { std::vector values = gmx::splitString(value); builder->addValue("b", gmx::fromString(values[0])); builder->addValue("c", gmx::fromString(values[1])); @@ -203,17 +196,15 @@ TEST_F(TreeValueTransformTest, ObjectFromMultipleStrings) TEST_F(TreeValueTransformTest, ScopedTransformRules) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "1"); builder.rootObject().addValue("b", "2"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; auto scope = transform.rules()->scopedTransform("/foo"); - scope.rules()->addRule() - .from("/a").to("/i").transformWith(&gmx::fromStdString); - scope.rules()->addRule() - .from("/b").to("/j").transformWith(&gmx::fromStdString); + scope.rules()->addRule().from("/a").to("/i").transformWith(&gmx::fromStdString); + scope.rules()->addRule().from("/b").to("/j").transformWith(&gmx::fromStdString); testTransform(input, transform); } @@ -224,13 +215,13 @@ TEST_F(TreeValueTransformTest, ScopedTransformRules) TEST(TreeValueTransformErrorTest, ConversionError) { - gmx::KeyValueTreeBuilder builder; + gmx::KeyValueTreeBuilder builder; builder.rootObject().addValue("a", "foo"); - gmx::KeyValueTreeObject input = builder.build(); + gmx::KeyValueTreeObject input = builder.build(); gmx::KeyValueTreeTransformer transform; - transform.rules()->addRule() - .from("/a").to("/i").transformWith(&gmx::fromStdString); + transform.rules()->addRule().from("/a").to("/i").transformWith( + &gmx::fromStdString); EXPECT_THROW_GMX(transform.transform(input, nullptr), gmx::InvalidInputError); } diff --git a/src/gromacs/utility/tests/logger.cpp b/src/gromacs/utility/tests/logger.cpp index df1b5173d1..c105eea265 100644 --- a/src/gromacs/utility/tests/logger.cpp +++ b/src/gromacs/utility/tests/logger.cpp @@ -65,8 +65,8 @@ TEST_F(LoggerTest, LogsToStream) gmx::StringOutputStream stream; gmx::LoggerBuilder builder; builder.addTargetStream(gmx::MDLogger::LogLevel::VerboseDebug, &stream); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); @@ -80,12 +80,12 @@ TEST_F(LoggerTest, LogsToFile) { gmx::test::TestFileManager files; std::string filename(files.getTemporaryFilePath("log.txt")); - FILE *fp = fopen(filename.c_str(), "w"); + FILE* fp = fopen(filename.c_str(), "w"); { - gmx::LoggerBuilder builder; + gmx::LoggerBuilder builder; builder.addTargetFile(gmx::MDLogger::LogLevel::VerboseDebug, fp); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); @@ -102,8 +102,8 @@ TEST_F(LoggerTest, LevelFilteringWorks) gmx::StringOutputStream stream; gmx::LoggerBuilder builder; builder.addTargetStream(gmx::MDLogger::LogLevel::Warning, &stream); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); @@ -126,8 +126,8 @@ TEST_F(LoggerTest, LogsToMultipleStreams) builder.addTargetStream(gmx::MDLogger::LogLevel::Error, &stream3); builder.addTargetStream(gmx::MDLogger::LogLevel::Debug, &stream4); builder.addTargetStream(gmx::MDLogger::LogLevel::VerboseDebug, &stream5); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); @@ -150,20 +150,20 @@ TEST_F(LoggerTest, LogsToMultipleFiles) std::string filename3(files.getTemporaryFilePath("error.txt")); std::string filename4(files.getTemporaryFilePath("debug.txt")); std::string filename5(files.getTemporaryFilePath("verboseDebug.txt")); - FILE *fp1 = fopen(filename1.c_str(), "w"); - FILE *fp2 = fopen(filename2.c_str(), "w"); - FILE *fp3 = fopen(filename3.c_str(), "w"); - FILE *fp4 = fopen(filename4.c_str(), "w"); - FILE *fp5 = fopen(filename5.c_str(), "w"); + FILE* fp1 = fopen(filename1.c_str(), "w"); + FILE* fp2 = fopen(filename2.c_str(), "w"); + FILE* fp3 = fopen(filename3.c_str(), "w"); + FILE* fp4 = fopen(filename4.c_str(), "w"); + FILE* fp5 = fopen(filename5.c_str(), "w"); { - gmx::LoggerBuilder builder; + gmx::LoggerBuilder builder; builder.addTargetFile(gmx::MDLogger::LogLevel::Info, fp1); builder.addTargetFile(gmx::MDLogger::LogLevel::Warning, fp2); builder.addTargetFile(gmx::MDLogger::LogLevel::Error, fp3); builder.addTargetFile(gmx::MDLogger::LogLevel::Debug, fp4); builder.addTargetFile(gmx::MDLogger::LogLevel::VerboseDebug, fp5); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); @@ -188,13 +188,13 @@ TEST_F(LoggerTest, LogsToStreamAndFile) gmx::test::TestFileManager files; gmx::StringOutputStream stream; std::string filename(files.getTemporaryFilePath("verboseDebug.txt")); - FILE *fp = fopen(filename.c_str(), "w"); + FILE* fp = fopen(filename.c_str(), "w"); { - gmx::LoggerBuilder builder; + gmx::LoggerBuilder builder; builder.addTargetFile(gmx::MDLogger::LogLevel::VerboseDebug, fp); builder.addTargetStream(gmx::MDLogger::LogLevel::VerboseDebug, &stream); - gmx::LoggerOwner owner = builder.build(); - const gmx::MDLogger &logger = owner.logger(); + gmx::LoggerOwner owner = builder.build(); + const gmx::MDLogger& logger = owner.logger(); GMX_LOG(logger.info).appendText("line"); GMX_LOG(logger.warning).appendText("par").asParagraph(); GMX_LOG(logger.info).appendText("line2"); diff --git a/src/gromacs/utility/tests/mutex.cpp b/src/gromacs/utility/tests/mutex.cpp index 720a30b89c..8b1725c5c7 100644 --- a/src/gromacs/utility/tests/mutex.cpp +++ b/src/gromacs/utility/tests/mutex.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -94,7 +94,7 @@ TEST(MutexBasicTest, CanBeUsedInLockGuard) } //! A shared value for a mutex to protect -int g_sharedValue; +int g_sharedValue; //! A mutex to protect a shared value Mutex g_sharedValueMutex; @@ -138,21 +138,18 @@ int updateSharedValueWithTryLock() * implementation underlying it. */ class DifferentTasksTest : public ::testing::TestWithParam { - public: - DifferentTasksTest() - { - g_sharedValue = 0; - } - //! Check the results - void checkResults() - { - int result = 0; - EXPECT_NO_THROW(result = futureResult_.get()) << "Future should not contain an exception"; - EXPECT_EQ(1, result) << "Task should have run"; - EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated"; - } - //! Contains the result the task returns. - std::future futureResult_; +public: + DifferentTasksTest() { g_sharedValue = 0; } + //! Check the results + void checkResults() + { + int result = 0; + EXPECT_NO_THROW(result = futureResult_.get()) << "Future should not contain an exception"; + EXPECT_EQ(1, result) << "Task should have run"; + EXPECT_EQ(1, g_sharedValue) << "Shared value should be updated"; + } + //! Contains the result the task returns. + std::future futureResult_; }; TEST_P(DifferentTasksTest, StdAsyncWorksWithDefaultPolicy) @@ -172,12 +169,17 @@ TEST_P(DifferentTasksTest, StdAsyncWorksWithAsyncLaunchPolicy) TEST_P(DifferentTasksTest, StdAsyncWorksWithDeferredLaunchPolicy) { auto task = GetParam(); - EXPECT_NO_THROW(futureResult_ = std::async(std::launch::deferred, task)) << "Async should succeed"; + EXPECT_NO_THROW(futureResult_ = std::async(std::launch::deferred, task)) + << "Async should succeed"; checkResults(); } // Test that the different launch policies work with the different tasks -INSTANTIATE_TEST_CASE_P(WithAndWithoutMutex, DifferentTasksTest, ::testing::Values(updateSharedValue, updateSharedValueWithLock, updateSharedValueWithTryLock)); +INSTANTIATE_TEST_CASE_P(WithAndWithoutMutex, + DifferentTasksTest, + ::testing::Values(updateSharedValue, + updateSharedValueWithLock, + updateSharedValueWithTryLock)); TEST(MutexTaskTest, MutualExclusionWorksWithLock) { @@ -216,7 +218,7 @@ TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnOtherThread) TEST(MutexTaskTest, MutualExclusionWorksWithTryLockOnSameThread) { - g_sharedValue = 0; + g_sharedValue = 0; int finalSharedValue = GMX_NATIVE_WINDOWS ? 1 : 0; { // Hold the mutex and launch a try_lock attempt on this diff --git a/src/gromacs/utility/tests/path.cpp b/src/gromacs/utility/tests/path.cpp index 2fa5a800af..89d43b0ed4 100644 --- a/src/gromacs/utility/tests/path.cpp +++ b/src/gromacs/utility/tests/path.cpp @@ -63,34 +63,23 @@ TEST(PathTest, StripSourcePrefixWorks) EXPECT_STREQ("foo.cpp", Path::stripSourcePrefix("foo.cpp")); EXPECT_STREQ("foo.cpp", Path::stripSourcePrefix("some/dir/foo.cpp")); EXPECT_STREQ("foo.cpp", Path::stripSourcePrefix("src/some/dir/foo.cpp")); - EXPECT_STREQ("foo.cpp", - Path::stripSourcePrefix("srcx/gromacs/foo.cpp")); - EXPECT_STREQ("src/gromacs/foo.cpp", - Path::stripSourcePrefix("src/gromacs/foo.cpp")); - EXPECT_STREQ("src/gromacs/foo.cpp", - Path::stripSourcePrefix("some/dir/src/gromacs/foo.cpp")); + EXPECT_STREQ("foo.cpp", Path::stripSourcePrefix("srcx/gromacs/foo.cpp")); + EXPECT_STREQ("src/gromacs/foo.cpp", Path::stripSourcePrefix("src/gromacs/foo.cpp")); + EXPECT_STREQ("src/gromacs/foo.cpp", Path::stripSourcePrefix("some/dir/src/gromacs/foo.cpp")); // TODO: For in-source builds, this might not work. - EXPECT_EQ(Path::normalize("src/gromacs/utility/tests/path.cpp"), - Path::stripSourcePrefix(__FILE__)) - << "stripSourcePrefix() does not work with compiler-produced file names. " - << "This only affects source paths reported in fatal error messages."; + EXPECT_EQ(Path::normalize("src/gromacs/utility/tests/path.cpp"), Path::stripSourcePrefix(__FILE__)) + << "stripSourcePrefix() does not work with compiler-produced file names. " + << "This only affects source paths reported in fatal error messages."; } TEST(PathTest, SearchOperationsWork) { gmx::test::TestReferenceData data; gmx::test::TestReferenceChecker rootChecker(data.rootChecker()); - for (const std::string &input : { "", - "md.log", - "md", - "/tmp/absolute.txt", - "simpledir/traj.tng", - "simpledir/traj", - "windowsdir\\traj.tng", - "complex.dir/traj.tng", - "complex.dir/traj", - "nested/dir/conf.pdb", - "/tmp/absolutedir/conf.pdb"}) + for (const std::string& input : + { "", "md.log", "md", "/tmp/absolute.txt", "simpledir/traj.tng", "simpledir/traj", + "windowsdir\\traj.tng", "complex.dir/traj.tng", "complex.dir/traj", + "nested/dir/conf.pdb", "/tmp/absolutedir/conf.pdb" }) { SCOPED_TRACE(std::string("for input '") + input + "'"); auto checker = rootChecker.checkCompound("PathToTest", input); diff --git a/src/gromacs/utility/tests/stringutil.cpp b/src/gromacs/utility/tests/stringutil.cpp index 943ab88e23..65fbe51311 100644 --- a/src/gromacs/utility/tests/stringutil.cpp +++ b/src/gromacs/utility/tests/stringutil.cpp @@ -122,7 +122,7 @@ TEST(StringUtilityTest, SplitString) using ::testing::ElementsAre; using ::testing::IsEmpty; using ::testing::Matcher; - Matcher > matcher = ElementsAre("foo", "bar"); + Matcher> matcher = ElementsAre("foo", "bar"); EXPECT_THAT(gmx::splitString("foo bar"), matcher); EXPECT_THAT(gmx::splitString(" foo bar"), matcher); EXPECT_THAT(gmx::splitString("foo bar "), matcher); @@ -159,7 +159,8 @@ TEST(StringUtilityTest, SplitAndTrimDelimitedString) EXPECT_THAT(splitAndTrimDelimitedString("foo ; bar ", ';'), ElementsAre("foo", "bar")); EXPECT_THAT(splitAndTrimDelimitedString(" ; foo ; bar ", ';'), ElementsAre("", "foo", "bar")); EXPECT_THAT(splitAndTrimDelimitedString(" foo ; bar ; ", ';'), ElementsAre("foo", "bar", "")); - EXPECT_THAT(splitAndTrimDelimitedString(" ; foo\n ; bar ; ", ';'), ElementsAre("", "foo", "bar", "")); + EXPECT_THAT(splitAndTrimDelimitedString(" ; foo\n ; bar ; ", ';'), + ElementsAre("", "foo", "bar", "")); EXPECT_THAT(splitAndTrimDelimitedString(" foo ; ; \tbar", ';'), ElementsAre("foo", "", "bar")); } @@ -180,10 +181,7 @@ TEST(StringUtilityTest, CanCompareCaseInsensitive) * \param[in] length Max comparison length to use. * \param[in] expectedResult If we expect the result be a match between the strings or not. */ -void checkEqualCaseInsensitive(const std::string &foo, - const std::string &bar, - int length, - bool expectedResult) +void checkEqualCaseInsensitive(const std::string& foo, const std::string& bar, int length, bool expectedResult) { EXPECT_EQ(equalCaseInsensitive(foo, bar, length), expectedResult); EXPECT_EQ(equalCaseInsensitive(bar, foo, length), expectedResult); @@ -230,8 +228,8 @@ TEST(FormatStringTest, HandlesLongStrings) TEST(StringFormatterTest, HandlesBasicFormatting) { int value = 103; - EXPECT_EQ("103", gmx::StringFormatter("%d") (value)); - EXPECT_EQ("null", gmx::StringFormatter("null") (value)); + EXPECT_EQ("103", gmx::StringFormatter("%d")(value)); + EXPECT_EQ("null", gmx::StringFormatter("null")(value)); } /******************************************************************** @@ -240,14 +238,14 @@ TEST(StringFormatterTest, HandlesBasicFormatting) TEST(formatAndJoinTest, Works) { - const char * const words[] = { "The", "quick", "brown", "fox" }; + const char* const words[] = { "The", "quick", "brown", "fox" }; EXPECT_EQ("The .quick .brown .fox ", - gmx::formatAndJoin(gmx::ArrayRef(words), ".", + gmx::formatAndJoin(gmx::ArrayRef(words), ".", gmx::StringFormatter("%-10s"))); const int values[] = { 0, 1, 4 }; - EXPECT_EQ("0,1,4", gmx::formatAndJoin(gmx::ArrayRef(values), ",", - gmx::StringFormatter("%d"))); + EXPECT_EQ("0,1,4", + gmx::formatAndJoin(gmx::ArrayRef(values), ",", gmx::StringFormatter("%d"))); } /******************************************************************** @@ -256,9 +254,10 @@ TEST(formatAndJoinTest, Works) TEST(JoinStringsTest, Works) { - const char * const words[] = { "The", "quick", "brown", "fox" }; - gmx::ArrayRef refToWords(words); - EXPECT_EQ("The; quick; brown; fox", gmx::joinStrings(refToWords.begin(), refToWords.end(), "; ")); + const char* const words[] = { "The", "quick", "brown", "fox" }; + gmx::ArrayRef refToWords(words); + EXPECT_EQ("The; quick; brown; fox", + gmx::joinStrings(refToWords.begin(), refToWords.end(), "; ")); EXPECT_EQ("The-quick-brown-fox", gmx::joinStrings(refToWords, "-")); EXPECT_EQ("The-quick-brown-fox", gmx::joinStrings(words, "-")); } @@ -291,24 +290,20 @@ TEST(ReplaceAllTest, HandlesMatchesAtEnds) TEST(ReplaceAllTest, HandlesMultipleMatches) { const std::string text("Text aaa with multiple aaa matches"); - EXPECT_EQ("Text bbbb with multiple bbbb matches", - gmx::replaceAll(text, "aaa", "bbbb")); - EXPECT_EQ("Text bbbb with multiple bbbb matches", - gmx::replaceAllWords(text, "aaa", "bbbb")); + EXPECT_EQ("Text bbbb with multiple bbbb matches", gmx::replaceAll(text, "aaa", "bbbb")); + EXPECT_EQ("Text bbbb with multiple bbbb matches", gmx::replaceAllWords(text, "aaa", "bbbb")); } TEST(ReplaceAllTest, HandlesWordBoundaries) { const std::string text("Text aaax with one word aaa match"); - EXPECT_EQ("Text aaax with one word bbbb match", - gmx::replaceAllWords(text, "aaa", "bbbb")); + EXPECT_EQ("Text aaax with one word bbbb match", gmx::replaceAllWords(text, "aaa", "bbbb")); } TEST(ReplaceAllTest, HandlesPossibleRecursiveMatches) { const std::string text("Text with recursive aaabbbbbb matches"); - EXPECT_EQ("Text with recursive aaaaaabbb matches", - gmx::replaceAll(text, "aaabbb", "aaaaaa")); + EXPECT_EQ("Text with recursive aaaaaabbb matches", gmx::replaceAll(text, "aaabbb", "aaaaaa")); } /******************************************************************** @@ -322,8 +317,8 @@ const char g_wrapText2[] = "A quick brown fox jumps\nover the lazy dog"; //! Test string for wrapping with embedded line breaks and an empty line. const char g_wrapText3[] = "A quick brown fox jumps\n\nover the lazy dog"; //! Test string for wrapping with a long word. -const char g_wrapTextLongWord[] - = "A quick brown fox jumps awordthatoverflowsaline over the lazy dog"; +const char g_wrapTextLongWord[] = + "A quick brown fox jumps awordthatoverflowsaline over the lazy dog"; //! Test string for wrapping with extra whitespace. const char g_wrapTextWhitespace[] = " A quick brown fox jumps \n over the lazy dog"; @@ -467,12 +462,10 @@ TEST_F(TextLineWrapperTest, WrapsCorrectlyWithExtraWhitespace) gmx::TextLineWrapper wrapper; wrapper.settings().setLineLength(14); - checkText(wrapper.wrapToString(g_wrapTextWhitespace), - "WrappedAt14"); + checkText(wrapper.wrapToString(g_wrapTextWhitespace), "WrappedAt14"); wrapper.settings().setKeepFinalSpaces(true); - checkText(wrapper.wrapToString(g_wrapTextWhitespace), - "WrappedAt14WithTrailingWhitespace"); + checkText(wrapper.wrapToString(g_wrapTextWhitespace), "WrappedAt14WithTrailingWhitespace"); } } // namespace diff --git a/src/gromacs/utility/tests/textreader.cpp b/src/gromacs/utility/tests/textreader.cpp index 5f24ff6633..ecef72bbcb 100644 --- a/src/gromacs/utility/tests/textreader.cpp +++ b/src/gromacs/utility/tests/textreader.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,17 +67,17 @@ namespace //! Convenience name. using Container = std::vector; //! Convenience type for callbacks. -using TestCallbackFunc = void(*)(TextReader &); +using TestCallbackFunc = void (*)(TextReader&); //! Helper struct. struct TextReaderTestParams { //! Input data. - const Container input; + const Container input; //! Callback to configure the reader with the behaviour being tested. TestCallbackFunc callback; //! Output to expect from the configured reader acting on the \c input. - const Container expectedOutput; + const Container expectedOutput; }; //! Test fixture. @@ -87,7 +87,7 @@ class TextReaderTest : public ::testing::TestWithParam TEST_P(TextReaderTest, UsingDifferentConfigurations) { - const auto ¶ms = GetParam(); + const auto& params = GetParam(); // Prepare the reader with the input lines. StringInputStream stream(params.input); @@ -106,8 +106,7 @@ TEST_P(TextReaderTest, UsingDifferentConfigurations) } //! Test input data. Some configurations will remove comments delimited by '#'. -const Container g_inputs = -{ +const Container g_inputs = { "", " \t ", "expected text", @@ -131,8 +130,7 @@ const Container g_inputs = * container with "\n", so the inputs are always changed before being * read. The name of this variable reflects that TextReader does not * change them during reading. */ -const Container g_unchangedOutputs = -{ +const Container g_unchangedOutputs = { "\n", " \t \n", "expected text\n", @@ -148,132 +146,113 @@ const Container g_unchangedOutputs = "\t #\n", " # not expected \n", }; -INSTANTIATE_TEST_CASE_P(ParsesLinesDifferently, TextReaderTest, - ::testing::Values(TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - GMX_UNUSED_VALUE(r); - }, - g_unchangedOutputs - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimLeadingWhiteSpace(true); - }, - { "", - "", - "expected text\n", - "expected text \n", - "expected text \t\n", - "expected text\n", - "expected text \t\n", - "expected text#\n", - "expected text\t #\n", - "expected text# \n", - "expected text # not expected \n", - "#\n", - "#\n", - "# not expected \n", } - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimTrailingWhiteSpace(true); - }, - { "", - "", - "expected text", - " expected text", - "expected text", - " \t expected text", - " \t expected text", - "expected text#", - "expected text\t #", - "expected text#", - "expected text # not expected", - "#", - "\t #", - " # not expected", } - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimTrailingWhiteSpace(true); - r.setTrimLeadingWhiteSpace(true); - }, - { "", - "", - "expected text", - "expected text", - "expected text", - "expected text", - "expected text", - "expected text#", - "expected text\t #", - "expected text#", - "expected text # not expected", - "#", - "#", - "# not expected", } - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimTrailingComment(true, '#'); - }, - { "\n", - " \t \n", - "expected text\n", - " expected text \n", - "expected text \t\n", - " \t expected text\n", - " \t expected text \t\n", - "expected text", - "expected text\t ", - "expected text", - "expected text ", - "", - "\t ", - " ", } - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimTrailingComment(true, '#'); - r.setTrimTrailingComment(false, 0); - }, - g_unchangedOutputs - }, - TextReaderTestParams { - g_inputs, - [](TextReader &r) - { - r.setTrimTrailingComment(true, '#'); - r.setTrimTrailingWhiteSpace(true); - }, - { "", - "", - "expected text", - " expected text", - "expected text", - " \t expected text", - " \t expected text", - "expected text", - "expected text", - "expected text", - "expected text", - "", - "", - "", } - } - )); +INSTANTIATE_TEST_CASE_P( + ParsesLinesDifferently, + TextReaderTest, + ::testing::Values( + TextReaderTestParams{ g_inputs, [](TextReader& r) { GMX_UNUSED_VALUE(r); }, g_unchangedOutputs }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { r.setTrimLeadingWhiteSpace(true); }, + { + "", + "", + "expected text\n", + "expected text \n", + "expected text \t\n", + "expected text\n", + "expected text \t\n", + "expected text#\n", + "expected text\t #\n", + "expected text# \n", + "expected text # not expected \n", + "#\n", + "#\n", + "# not expected \n", + } }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { r.setTrimTrailingWhiteSpace(true); }, + { + "", + "", + "expected text", + " expected text", + "expected text", + " \t expected text", + " \t expected text", + "expected text#", + "expected text\t #", + "expected text#", + "expected text # not expected", + "#", + "\t #", + " # not expected", + } }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { + r.setTrimTrailingWhiteSpace(true); + r.setTrimLeadingWhiteSpace(true); + }, + { + "", + "", + "expected text", + "expected text", + "expected text", + "expected text", + "expected text", + "expected text#", + "expected text\t #", + "expected text#", + "expected text # not expected", + "#", + "#", + "# not expected", + } }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { r.setTrimTrailingComment(true, '#'); }, + { + "\n", + " \t \n", + "expected text\n", + " expected text \n", + "expected text \t\n", + " \t expected text\n", + " \t expected text \t\n", + "expected text", + "expected text\t ", + "expected text", + "expected text ", + "", + "\t ", + " ", + } }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { + r.setTrimTrailingComment(true, '#'); + r.setTrimTrailingComment(false, 0); + }, + g_unchangedOutputs }, + TextReaderTestParams{ g_inputs, + [](TextReader& r) { + r.setTrimTrailingComment(true, '#'); + r.setTrimTrailingWhiteSpace(true); + }, + { + "", + "", + "expected text", + " expected text", + "expected text", + " \t expected text", + " \t expected text", + "expected text", + "expected text", + "expected text", + "expected text", + "", + "", + "", + } })); } // namespace } // namespace test diff --git a/src/gromacs/utility/tests/textwriter.cpp b/src/gromacs/utility/tests/textwriter.cpp index db870a2684..973401e550 100644 --- a/src/gromacs/utility/tests/textwriter.cpp +++ b/src/gromacs/utility/tests/textwriter.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,18 +57,13 @@ namespace class TextWriterTest : public gmx::test::StringTestBase { - public: - TextWriterTest() : writer_(&stream_) - { - } - - void checkOutput() - { - checkText(stream_.toString(), "Output"); - } - - gmx::StringOutputStream stream_; - gmx::TextWriter writer_; +public: + TextWriterTest() : writer_(&stream_) {} + + void checkOutput() { checkText(stream_.toString(), "Output"); } + + gmx::StringOutputStream stream_; + gmx::TextWriter writer_; }; TEST_F(TextWriterTest, WritesLines) diff --git a/src/gromacs/utility/tests/typetraits.cpp b/src/gromacs/utility/tests/typetraits.cpp index 31e6cfcbef..a99e61ddec 100644 --- a/src/gromacs/utility/tests/typetraits.cpp +++ b/src/gromacs/utility/tests/typetraits.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,9 +45,9 @@ namespace test TEST(TypeTraitsTest, IsIntegralConstant) { EXPECT_FALSE(isIntegralConstant::value); - EXPECT_TRUE((isIntegralConstant >::value)); + EXPECT_TRUE((isIntegralConstant>::value)); EXPECT_FALSE((isIntegralConstant, long>::value)); EXPECT_TRUE((isIntegralConstant, long>::value)); } -} -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/gromacs/utility/textreader.cpp b/src/gromacs/utility/textreader.cpp index f0a14e82f5..ece89d3395 100644 --- a/src/gromacs/utility/textreader.cpp +++ b/src/gromacs/utility/textreader.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,7 +51,7 @@ namespace gmx { // static -std::string TextReader::readFileToString(const char *filename) +std::string TextReader::readFileToString(const char* filename) { TextReader reader(filename); std::string result(reader.readAll()); @@ -60,7 +60,7 @@ std::string TextReader::readFileToString(const char *filename) } // static -std::string TextReader::readFileToString(const std::string &filename) +std::string TextReader::readFileToString(const std::string& filename) { return readFileToString(filename.c_str()); } @@ -68,55 +68,53 @@ std::string TextReader::readFileToString(const std::string &filename) //! Implementation class class TextReader::Impl { - public: - //! Constructor. - explicit Impl(const TextInputStreamPointer &stream) - : stream_(stream), trimLeadingWhiteSpace_(false), trimTrailingWhiteSpace_(false), - trimTrailingComment_(false), commentChar_(0) - { - } +public: + //! Constructor. + explicit Impl(const TextInputStreamPointer& stream) : + stream_(stream), + trimLeadingWhiteSpace_(false), + trimTrailingWhiteSpace_(false), + trimTrailingComment_(false), + commentChar_(0) + { + } - //! Stream used by this reader. - TextInputStreamPointer stream_; - //! Whether leading whitespace should be removed. - bool trimLeadingWhiteSpace_; - //! Whether trailing whitespace should be removed. - bool trimTrailingWhiteSpace_; - //! Whether a trailing comment should be removed. - bool trimTrailingComment_; - /*! \brief Character that denotes the start of a comment on a line. - * - * Zero until TextReader::setTrimTrailingComment is called to - * activate such trimming with a given character. */ - char commentChar_; + //! Stream used by this reader. + TextInputStreamPointer stream_; + //! Whether leading whitespace should be removed. + bool trimLeadingWhiteSpace_; + //! Whether trailing whitespace should be removed. + bool trimTrailingWhiteSpace_; + //! Whether a trailing comment should be removed. + bool trimTrailingComment_; + /*! \brief Character that denotes the start of a comment on a line. + * + * Zero until TextReader::setTrimTrailingComment is called to + * activate such trimming with a given character. */ + char commentChar_; }; -TextReader::TextReader(const std::string &filename) - : impl_(new Impl(TextInputStreamPointer(new TextInputFile(filename)))) +TextReader::TextReader(const std::string& filename) : + impl_(new Impl(TextInputStreamPointer(new TextInputFile(filename)))) { } -TextReader::TextReader(TextInputStream *stream) - : impl_(new Impl(TextInputStreamPointer(stream, no_delete()))) +TextReader::TextReader(TextInputStream* stream) : + impl_(new Impl(TextInputStreamPointer(stream, no_delete()))) { } -TextReader::TextReader(const TextInputStreamPointer &stream) - : impl_(new Impl(stream)) -{ -} +TextReader::TextReader(const TextInputStreamPointer& stream) : impl_(new Impl(stream)) {} -TextReader::~TextReader() -{ -} +TextReader::~TextReader() {} -bool TextReader::readLine(std::string *linePtr) +bool TextReader::readLine(std::string* linePtr) { if (!impl_->stream_->readLine(linePtr)) { return false; } - auto &line = *linePtr; + auto& line = *linePtr; const char whiteSpaceChars[] = " \t\r\n"; if (impl_->trimLeadingWhiteSpace_) { diff --git a/src/gromacs/utility/textreader.h b/src/gromacs/utility/textreader.h index df713459de..55020da404 100644 --- a/src/gromacs/utility/textreader.h +++ b/src/gromacs/utility/textreader.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,121 +66,121 @@ namespace gmx */ class TextReader { - public: - /*! \brief - * Reads contents of a file to a std::string. - * - * \param[in] filename Name of the file to read. - * \returns The contents of \p filename. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - */ - static std::string readFileToString(const char *filename); - //! \copydoc readFileToString(const char *) - static std::string readFileToString(const std::string &filename); +public: + /*! \brief + * Reads contents of a file to a std::string. + * + * \param[in] filename Name of the file to read. + * \returns The contents of \p filename. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + */ + static std::string readFileToString(const char* filename); + //! \copydoc readFileToString(const char *) + static std::string readFileToString(const std::string& filename); - /*! \brief - * Creates a reader that reads from specified file. - * - * \param[in] filename Path to the file to open. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * This constructor is provided for convenience for reading directly - * from a file, without the need to construct multiple objects. - */ - explicit TextReader(const std::string &filename); - /*! \brief - * Creates a reader that reads from specified stream. - * - * \param[in] stream Stream to read from. - * \throws std::bad_alloc if out of memory. - * - * The caller is responsible of the lifetime of the stream (should - * remain in existence as long as the reader exists). - * - * This constructor is provided for convenience for cases where the - * stream is not allocated with `new` and/or not managed by a - * std::shared_ptr (e.g., if the stream is an object on the stack). - */ - explicit TextReader(TextInputStream *stream); - /*! \brief - * Creates a reader that reads from specified stream. - * - * \param[in] stream Stream to read from. - * \throws std::bad_alloc if out of memory. - * - * The reader keeps a reference to the stream, so the caller can pass - * in a temporary if necessary. - */ - explicit TextReader(const TextInputStreamPointer &stream); - ~TextReader(); + /*! \brief + * Creates a reader that reads from specified file. + * + * \param[in] filename Path to the file to open. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * This constructor is provided for convenience for reading directly + * from a file, without the need to construct multiple objects. + */ + explicit TextReader(const std::string& filename); + /*! \brief + * Creates a reader that reads from specified stream. + * + * \param[in] stream Stream to read from. + * \throws std::bad_alloc if out of memory. + * + * The caller is responsible of the lifetime of the stream (should + * remain in existence as long as the reader exists). + * + * This constructor is provided for convenience for cases where the + * stream is not allocated with `new` and/or not managed by a + * std::shared_ptr (e.g., if the stream is an object on the stack). + */ + explicit TextReader(TextInputStream* stream); + /*! \brief + * Creates a reader that reads from specified stream. + * + * \param[in] stream Stream to read from. + * \throws std::bad_alloc if out of memory. + * + * The reader keeps a reference to the stream, so the caller can pass + * in a temporary if necessary. + */ + explicit TextReader(const TextInputStreamPointer& stream); + ~TextReader(); - /*! \brief - * Reads a single line (including newline) from the stream. - * - * \param[out] line String to receive the line. - * \returns `false` if nothing was read because the file ended. - * - * On error or when false is returned, \p line will be empty. - * Newlines will be returned as part of \p line if it was present in - * the stream. - * To loop over all lines in the stream, use: - * \code - std::string line; - while (reader.readLine(&line)) - { - // ... - } - \endcode - * - * Behaviours such as trimming whitespace or comments can be - * configured by calling other methods before this one. - */ - bool readLine(std::string *line); - /*! \brief Sets whether the reader should trim leading whitespace - * from a line before returning it. - * - * \param[in] doTrimming Whether trimming should be active. - */ - void setTrimLeadingWhiteSpace(bool doTrimming); - /*! \brief Sets whether the reader should trim trailing whitespace - * from a line before returning it. - * - * Note that comment trimming will precede whitespace trimming - * when both are active. - * - * \param[in] doTrimming Whether trimming should be active. - */ - void setTrimTrailingWhiteSpace(bool doTrimming); - /*! \brief Sets whether the reader should trim at trailing - * comment from a line before returning it. - * - * Note that comment trimming will precede whitespace trimming - * when both are active. - * - * \param[in] commentChar The character that begins a comment. - * - * \param[in] doTrimming Whether trimming should be active. - */ - void setTrimTrailingComment(bool doTrimming, char commentChar); - /*! \brief - * Reads all remaining lines from the stream as a single string. - * - * \returns Full contents of the stream (from the current point to - * the end). - */ - std::string readAll(); + /*! \brief + * Reads a single line (including newline) from the stream. + * + * \param[out] line String to receive the line. + * \returns `false` if nothing was read because the file ended. + * + * On error or when false is returned, \p line will be empty. + * Newlines will be returned as part of \p line if it was present in + * the stream. + * To loop over all lines in the stream, use: + * \code + std::string line; + while (reader.readLine(&line)) + { + // ... + } + \endcode + * + * Behaviours such as trimming whitespace or comments can be + * configured by calling other methods before this one. + */ + bool readLine(std::string* line); + /*! \brief Sets whether the reader should trim leading whitespace + * from a line before returning it. + * + * \param[in] doTrimming Whether trimming should be active. + */ + void setTrimLeadingWhiteSpace(bool doTrimming); + /*! \brief Sets whether the reader should trim trailing whitespace + * from a line before returning it. + * + * Note that comment trimming will precede whitespace trimming + * when both are active. + * + * \param[in] doTrimming Whether trimming should be active. + */ + void setTrimTrailingWhiteSpace(bool doTrimming); + /*! \brief Sets whether the reader should trim at trailing + * comment from a line before returning it. + * + * Note that comment trimming will precede whitespace trimming + * when both are active. + * + * \param[in] commentChar The character that begins a comment. + * + * \param[in] doTrimming Whether trimming should be active. + */ + void setTrimTrailingComment(bool doTrimming, char commentChar); + /*! \brief + * Reads all remaining lines from the stream as a single string. + * + * \returns Full contents of the stream (from the current point to + * the end). + */ + std::string readAll(); - /*! \brief - * Closes the underlying stream. - */ - void close(); + /*! \brief + * Closes the underlying stream. + */ + void close(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/textstream.h b/src/gromacs/utility/textstream.h index a6e522bd8c..7c8421130b 100644 --- a/src/gromacs/utility/textstream.h +++ b/src/gromacs/utility/textstream.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,27 +67,27 @@ namespace gmx */ class TextInputStream { - public: - virtual ~TextInputStream() {} +public: + virtual ~TextInputStream() {} - /*! \brief - * Reads a line (with newline included) from the stream. - * - * \param[out] line String to receive the line. - * \returns `false` if nothing was read because the stream ended. - * - * On error or when `false` is returned, \p line will be empty. - */ - virtual bool readLine(std::string *line) = 0; - /*! \brief - * Closes the stream. - * - * It is not allowed to read from a stream after it has been closed. - * See TextOutputStream::close() for rationale for a close() method - * separate from the destructor. For input, failures during close - * should be rare, but it is clearer to keep the interface symmetric. - */ - virtual void close() = 0; + /*! \brief + * Reads a line (with newline included) from the stream. + * + * \param[out] line String to receive the line. + * \returns `false` if nothing was read because the stream ended. + * + * On error or when `false` is returned, \p line will be empty. + */ + virtual bool readLine(std::string* line) = 0; + /*! \brief + * Closes the stream. + * + * It is not allowed to read from a stream after it has been closed. + * See TextOutputStream::close() for rationale for a close() method + * separate from the destructor. For input, failures during close + * should be rare, but it is clearer to keep the interface symmetric. + */ + virtual void close() = 0; }; /*! \libinternal \brief @@ -117,25 +117,25 @@ class TextInputStream */ class TextOutputStream { - public: - virtual ~TextOutputStream() {} +public: + virtual ~TextOutputStream() {} - /*! \brief - * Writes a given string to the stream. - */ - virtual void write(const char *text) = 0; - /*! \brief - * Closes the stream. - * - * It is not allowed to write to a stream after it has been closed. - * A method separate from the destructor is provided such that errors - * that occur while closing the stream (e.g., when closing the file) - * can be handled using exceptions. - * The destructor is not allowed to throw, so code that wants to - * observe such errors needs to call close() after it has finished - * writing to the stream. - */ - virtual void close() = 0; + /*! \brief + * Writes a given string to the stream. + */ + virtual void write(const char* text) = 0; + /*! \brief + * Closes the stream. + * + * It is not allowed to write to a stream after it has been closed. + * A method separate from the destructor is provided such that errors + * that occur while closing the stream (e.g., when closing the file) + * can be handled using exceptions. + * The destructor is not allowed to throw, so code that wants to + * observe such errors needs to call close() after it has finished + * writing to the stream. + */ + virtual void close() = 0; }; //! Shorthand for a smart pointer to a TextInputStream. diff --git a/src/gromacs/utility/textwriter.cpp b/src/gromacs/utility/textwriter.cpp index 14b11ddcd4..3f99ed5f9d 100644 --- a/src/gromacs/utility/textwriter.cpp +++ b/src/gromacs/utility/textwriter.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,112 +55,104 @@ namespace gmx class TextWriter::Impl { - public: - explicit Impl(const TextOutputStreamPointer &stream) - : stream_(stream), newLineCount_(2), currentLineLength_(0), - pendingNewLine_(false) +public: + explicit Impl(const TextOutputStreamPointer& stream) : + stream_(stream), + newLineCount_(2), + currentLineLength_(0), + pendingNewLine_(false) + { + wrapper_.settings().setKeepFinalSpaces(true); + } + + void writeRawString(const char* str) + { + if (pendingNewLine_ && str[0] != '\n') { - wrapper_.settings().setKeepFinalSpaces(true); + stream_->write("\n"); } - - void writeRawString(const char *str) + pendingNewLine_ = false; + const char* lastNewLine = std::strrchr(str, '\n'); + if (lastNewLine == nullptr) { - if (pendingNewLine_ && str[0] != '\n') - { - stream_->write("\n"); - } - pendingNewLine_ = false; - const char *lastNewLine = std::strrchr(str, '\n'); - if (lastNewLine == nullptr) - { - newLineCount_ = 0; - currentLineLength_ += std::strlen(str); - } - else if (lastNewLine[1] != '\0') - { - newLineCount_ = 0; - currentLineLength_ += std::strlen(lastNewLine+1); - } - else - { - currentLineLength_ = 0; - int newLineCount = 0; - while (lastNewLine >= str && *lastNewLine == '\n') - { - ++newLineCount; - --lastNewLine; - } - if (lastNewLine >= str) - { - newLineCount_ = 0; - } - newLineCount_ += newLineCount; - } - stream_->write(str); + newLineCount_ = 0; + currentLineLength_ += std::strlen(str); } - void writeRawString(const std::string &str) + else if (lastNewLine[1] != '\0') { - writeRawString(str.c_str()); + newLineCount_ = 0; + currentLineLength_ += std::strlen(lastNewLine + 1); } - - void writeWrappedString(const std::string &str) + else { - if (newLineCount_ > 0) + currentLineLength_ = 0; + int newLineCount = 0; + while (lastNewLine >= str && *lastNewLine == '\n') { - writeRawString(wrapper_.wrapToString(str)); + ++newLineCount; + --lastNewLine; } - else + if (lastNewLine >= str) { - writeRawString(str); + newLineCount_ = 0; } + newLineCount_ += newLineCount; } + stream_->write(str); + } + void writeRawString(const std::string& str) { writeRawString(str.c_str()); } - TextOutputStreamPointer stream_; - TextLineWrapper wrapper_; - int newLineCount_; - int currentLineLength_; - bool pendingNewLine_; + void writeWrappedString(const std::string& str) + { + if (newLineCount_ > 0) + { + writeRawString(wrapper_.wrapToString(str)); + } + else + { + writeRawString(str); + } + } + + TextOutputStreamPointer stream_; + TextLineWrapper wrapper_; + int newLineCount_; + int currentLineLength_; + bool pendingNewLine_; }; // static -void TextWriter::writeFileFromString(const std::string &filename, - const std::string &text) +void TextWriter::writeFileFromString(const std::string& filename, const std::string& text) { TextWriter file(filename); file.writeString(text); file.close(); } -TextWriter::TextWriter(const std::string &filename) - : impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(filename)))) +TextWriter::TextWriter(const std::string& filename) : + impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(filename)))) { } -TextWriter::TextWriter(FILE *fp) - : impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(fp)))) +TextWriter::TextWriter(FILE* fp) : impl_(new Impl(TextOutputStreamPointer(new TextOutputFile(fp)))) { } -TextWriter::TextWriter(TextOutputStream *stream) - : impl_(new Impl(TextOutputStreamPointer(stream, no_delete()))) +TextWriter::TextWriter(TextOutputStream* stream) : + impl_(new Impl(TextOutputStreamPointer(stream, no_delete()))) { } -TextWriter::TextWriter(const TextOutputStreamPointer &stream) - : impl_(new Impl(stream)) -{ -} +TextWriter::TextWriter(const TextOutputStreamPointer& stream) : impl_(new Impl(stream)) {} -TextWriter::~TextWriter() -{ -} +TextWriter::~TextWriter() {} -TextLineWrapperSettings &TextWriter::wrapperSettings() +TextLineWrapperSettings& TextWriter::wrapperSettings() { return impl_->wrapper_.settings(); } -void TextWriter::writeString(const char *str) +void TextWriter::writeString(const char* str) { if (impl_->wrapper_.isTrivial()) { @@ -172,12 +164,12 @@ void TextWriter::writeString(const char *str) } } -void TextWriter::writeString(const std::string &str) +void TextWriter::writeString(const std::string& str) { impl_->writeWrappedString(str); } -void TextWriter::writeStringFormatted(const char *fmt, ...) +void TextWriter::writeStringFormatted(const char* fmt, ...) { va_list ap; @@ -186,19 +178,19 @@ void TextWriter::writeStringFormatted(const char *fmt, ...) va_end(ap); } -void TextWriter::writeLine(const char *line) +void TextWriter::writeLine(const char* line) { writeString(line); ensureLineBreak(); } -void TextWriter::writeLine(const std::string &line) +void TextWriter::writeLine(const std::string& line) { writeString(line); ensureLineBreak(); } -void TextWriter::writeLineFormatted(const char *fmt, ...) +void TextWriter::writeLineFormatted(const char* fmt, ...) { va_list ap; diff --git a/src/gromacs/utility/textwriter.h b/src/gromacs/utility/textwriter.h index f80bc2cfd6..89b7eccf1c 100644 --- a/src/gromacs/utility/textwriter.h +++ b/src/gromacs/utility/textwriter.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,135 +69,134 @@ class TextLineWrapperSettings; */ class TextWriter { - public: - /*! \brief - * Convenience method for writing a file from a string in a single call. - * - * \param[in] filename Name of the file to read. - * \param[in] text String to write to \p filename. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * If \p filename exists, it is overwritten. - */ - static void writeFileFromString(const std::string &filename, - const std::string &text); +public: + /*! \brief + * Convenience method for writing a file from a string in a single call. + * + * \param[in] filename Name of the file to read. + * \param[in] text String to write to \p filename. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * If \p filename exists, it is overwritten. + */ + static void writeFileFromString(const std::string& filename, const std::string& text); - /*! \brief - * Creates a writer that writes to specified file. - * - * \param[in] filename Path to the file to open. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * This constructor is provided for convenience for writing directly to - * a file, without the need to construct multiple objects. - */ - explicit TextWriter(const std::string &filename); - /*! \brief - * Creates a writer that writes to specified file. - * - * \param[in] fp File handle to write to. - * \throws std::bad_alloc if out of memory. - * \throws FileIOError on any I/O error. - * - * This constructor is provided for interoperability with C-like code - * for writing directly to an already opened file, without the need to - * construct multiple objects. - * - * The caller is responsible of closing \p fp; it is not allowed to - * call close() on the writer. - */ - explicit TextWriter(FILE *fp); - /*! \brief - * Creates a writer that writes to specified stream. - * - * \param[in] stream Stream to write to. - * \throws std::bad_alloc if out of memory. - * - * The caller is responsible of the lifetime of the stream (should - * remain in existence as long as the writer exists). - * - * This constructor is provided for convenience for cases where the - * stream is not allocated with `new` and/or not managed by a - * std::shared_ptr (e.g., if the stream is an object on the stack). - */ - explicit TextWriter(TextOutputStream *stream); - /*! \brief - * Creates a writer that writes to specified stream. - * - * \param[in] stream Stream to write to. - * \throws std::bad_alloc if out of memory. - * - * The writer keeps a reference to the stream, so the caller can pass - * in a temporary if necessary. - */ - explicit TextWriter(const TextOutputStreamPointer &stream); - ~TextWriter(); + /*! \brief + * Creates a writer that writes to specified file. + * + * \param[in] filename Path to the file to open. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * This constructor is provided for convenience for writing directly to + * a file, without the need to construct multiple objects. + */ + explicit TextWriter(const std::string& filename); + /*! \brief + * Creates a writer that writes to specified file. + * + * \param[in] fp File handle to write to. + * \throws std::bad_alloc if out of memory. + * \throws FileIOError on any I/O error. + * + * This constructor is provided for interoperability with C-like code + * for writing directly to an already opened file, without the need to + * construct multiple objects. + * + * The caller is responsible of closing \p fp; it is not allowed to + * call close() on the writer. + */ + explicit TextWriter(FILE* fp); + /*! \brief + * Creates a writer that writes to specified stream. + * + * \param[in] stream Stream to write to. + * \throws std::bad_alloc if out of memory. + * + * The caller is responsible of the lifetime of the stream (should + * remain in existence as long as the writer exists). + * + * This constructor is provided for convenience for cases where the + * stream is not allocated with `new` and/or not managed by a + * std::shared_ptr (e.g., if the stream is an object on the stack). + */ + explicit TextWriter(TextOutputStream* stream); + /*! \brief + * Creates a writer that writes to specified stream. + * + * \param[in] stream Stream to write to. + * \throws std::bad_alloc if out of memory. + * + * The writer keeps a reference to the stream, so the caller can pass + * in a temporary if necessary. + */ + explicit TextWriter(const TextOutputStreamPointer& stream); + ~TextWriter(); - /*! \brief - * Allows adjusting wrapping settings for the writer. - * - * \todo - * Wrapping is not currently implemented for code that writes partial - * lines with writeString(). - */ - TextLineWrapperSettings &wrapperSettings(); + /*! \brief + * Allows adjusting wrapping settings for the writer. + * + * \todo + * Wrapping is not currently implemented for code that writes partial + * lines with writeString(). + */ + TextLineWrapperSettings& wrapperSettings(); - /*! \brief - * Writes a string to the stream. - * - * \param[in] str String to write. - */ - void writeString(const char *str); - //! \copydoc writeString(const char *) - void writeString(const std::string &str); - //! Writes a string to the stream, with printf-style formatting. - void writeStringFormatted(const char *fmt, ...); - /*! \brief - * Writes a line to the stream. - * - * \param[in] line Line to write. - * - * If \p line does not end in a newline, one newline is appended. - * Otherwise, works as writeString(). - */ - void writeLine(const char *line); - //! \copydoc writeLine(const char *) - void writeLine(const std::string &line); - //! Writes a line to the stream, with printf-style formatting. - void writeLineFormatted(const char *fmt, ...); - //! Writes a newline to the stream. - void writeLine(); + /*! \brief + * Writes a string to the stream. + * + * \param[in] str String to write. + */ + void writeString(const char* str); + //! \copydoc writeString(const char *) + void writeString(const std::string& str); + //! Writes a string to the stream, with printf-style formatting. + void writeStringFormatted(const char* fmt, ...); + /*! \brief + * Writes a line to the stream. + * + * \param[in] line Line to write. + * + * If \p line does not end in a newline, one newline is appended. + * Otherwise, works as writeString(). + */ + void writeLine(const char* line); + //! \copydoc writeLine(const char *) + void writeLine(const std::string& line); + //! Writes a line to the stream, with printf-style formatting. + void writeLineFormatted(const char* fmt, ...); + //! Writes a newline to the stream. + void writeLine(); - /*! \brief - * Writes a newline if previous output did not end in one. - * - * If nothing has been written using the writer, this method does - * nothing. - */ - void ensureLineBreak(); - /*! \brief - * Ensures that the next string written starts after an empty line. - * - * Always terminates the current line (as with ensureLineBreak()), but - * the empty line is only written out when the next line is written, - * so that trailing newlines after final output can be avoided. - * - * If nothing has been written using the writer, this method does - * nothing. - */ - void ensureEmptyLine(); + /*! \brief + * Writes a newline if previous output did not end in one. + * + * If nothing has been written using the writer, this method does + * nothing. + */ + void ensureLineBreak(); + /*! \brief + * Ensures that the next string written starts after an empty line. + * + * Always terminates the current line (as with ensureLineBreak()), but + * the empty line is only written out when the next line is written, + * so that trailing newlines after final output can be avoided. + * + * If nothing has been written using the writer, this method does + * nothing. + */ + void ensureEmptyLine(); - /*! \brief - * Closes the underlying stream. - */ - void close(); + /*! \brief + * Closes the underlying stream. + */ + void close(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace gmx diff --git a/src/gromacs/utility/txtdump.cpp b/src/gromacs/utility/txtdump.cpp index ef1989752b..52fc2718e2 100644 --- a/src/gromacs/utility/txtdump.cpp +++ b/src/gromacs/utility/txtdump.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -45,7 +45,7 @@ #include "gromacs/utility/cstringutil.h" -int pr_indent(FILE *fp, int n) +int pr_indent(FILE* fp, int n) { int i; @@ -56,7 +56,7 @@ int pr_indent(FILE *fp, int n) return n; } -bool available(FILE *fp, const void *p, int indent, const char *title) +bool available(FILE* fp, const void* p, int indent, const char* title) { if (!p) { @@ -69,28 +69,28 @@ bool available(FILE *fp, const void *p, int indent, const char *title) return (p != nullptr); } -int pr_title(FILE *fp, int indent, const char *title) +int pr_title(FILE* fp, int indent, const char* title) { pr_indent(fp, indent); fprintf(fp, "%s:\n", title); - return (indent+INDENT); + return (indent + INDENT); } -int pr_title_n(FILE *fp, int indent, const char *title, int n) +int pr_title_n(FILE* fp, int indent, const char* title, int n) { pr_indent(fp, indent); fprintf(fp, "%s (%d):\n", title, n); - return (indent+INDENT); + return (indent + INDENT); } -int pr_title_nxn(FILE *fp, int indent, const char *title, int n1, int n2) +int pr_title_nxn(FILE* fp, int indent, const char* title, int n1, int n2) { pr_indent(fp, indent); fprintf(fp, "%s (%dx%d):\n", title, n1, n2); - return (indent+INDENT); + return (indent + INDENT); } -void pr_reals(FILE *fp, int indent, const char *title, const real *vec, int n) +void pr_reals(FILE* fp, int indent, const char* title, const real* vec, int n) { int i; @@ -106,7 +106,7 @@ void pr_reals(FILE *fp, int indent, const char *title, const real *vec, int n) } } -void pr_doubles(FILE *fp, int indent, const char *title, const double *vec, int n) +void pr_doubles(FILE* fp, int indent, const char* title, const double* vec, int n) { int i; @@ -122,12 +122,12 @@ void pr_doubles(FILE *fp, int indent, const char *title, const double *vec, int } } -void pr_reals_of_dim(FILE *fp, int indent, const char *title, const real *vec, int n, int dim) +void pr_reals_of_dim(FILE* fp, int indent, const char* title, const real* vec, int n, int dim) { int i, j; - const char *fshort = "%12.5e"; - const char *flong = "%15.8e"; - const char *format; + const char* fshort = "%12.5e"; + const char* flong = "%15.8e"; + const char* format; if (getenv("GMX_PRINT_LONGFORMAT") != nullptr) { @@ -151,20 +151,20 @@ void pr_reals_of_dim(FILE *fp, int indent, const char *title, const real *vec, i { fprintf(fp, ", "); } - fprintf(fp, format, vec[i * dim + j]); + fprintf(fp, format, vec[i * dim + j]); } fprintf(fp, "}\n"); } } } -void pr_int(FILE *fp, int indent, const char *title, int i) +void pr_int(FILE* fp, int indent, const char* title, int i) { pr_indent(fp, indent); fprintf(fp, "%-30s = %d\n", title, i); } -void pr_int64(FILE *fp, int indent, const char *title, int64_t i) +void pr_int64(FILE* fp, int indent, const char* title, int64_t i) { char buf[STEPSTRSIZE]; @@ -172,25 +172,25 @@ void pr_int64(FILE *fp, int indent, const char *title, int64_t i) fprintf(fp, "%-30s = %s\n", title, gmx_step_str(i, buf)); } -void pr_real(FILE *fp, int indent, const char *title, real r) +void pr_real(FILE* fp, int indent, const char* title, real r) { pr_indent(fp, indent); fprintf(fp, "%-30s = %g\n", title, r); } -void pr_double(FILE *fp, int indent, const char *title, double d) +void pr_double(FILE* fp, int indent, const char* title, double d) { pr_indent(fp, indent); fprintf(fp, "%-30s = %g\n", title, d); } -void pr_str(FILE *fp, int indent, const char *title, const char *s) +void pr_str(FILE* fp, int indent, const char* title, const char* s) { pr_indent(fp, indent); fprintf(fp, "%-30s = %s\n", title, s); } -void pr_strings(FILE *fp, int indent, const char *title, char ***nm, int n, gmx_bool bShowNumbers) +void pr_strings(FILE* fp, int indent, const char* title, char*** nm, int n, gmx_bool bShowNumbers) { int i; @@ -200,8 +200,7 @@ void pr_strings(FILE *fp, int indent, const char *title, char ***nm, int n, gmx_ for (i = 0; i < n; i++) { pr_indent(fp, indent); - fprintf(fp, "%s[%d]={name=\"%s\"}\n", - title, bShowNumbers ? i : -1, *(nm[i])); + fprintf(fp, "%s[%d]={name=\"%s\"}\n", title, bShowNumbers ? i : -1, *(nm[i])); } } } diff --git a/src/gromacs/utility/txtdump.h b/src/gromacs/utility/txtdump.h index f9975aa6c3..7a0afbacbb 100644 --- a/src/gromacs/utility/txtdump.h +++ b/src/gromacs/utility/txtdump.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,41 +50,41 @@ #include "gromacs/utility/real.h" //! Line width for text dump output. -#define LINE_WIDTH 80 +#define LINE_WIDTH 80 //! Right margin for text dump output. -#define RMARGIN 10 +#define RMARGIN 10 //! Actual line length for text dump output. -#define USE_WIDTH ((LINE_WIDTH)-(RMARGIN)) +#define USE_WIDTH ((LINE_WIDTH) - (RMARGIN)) //! Default indentation for text dump output. -#define INDENT 3 +#define INDENT 3 //! Prints an initial indentation for a line. -int pr_indent(FILE *fp, int n); +int pr_indent(FILE* fp, int n); //! Returns whether \p is available (not null), and prints a note if it is not. -bool available(FILE *fp, const void *p, int indent, const char *title); +bool available(FILE* fp, const void* p, int indent, const char* title); //! Prints a title for a dumped section. -int pr_title(FILE *fp, int indent, const char *title); +int pr_title(FILE* fp, int indent, const char* title); //! Prints a title for a dumped section with a number suffixed. -int pr_title_n(FILE *fp, int indent, const char *title, int n); +int pr_title_n(FILE* fp, int indent, const char* title, int n); //! Prints a title for a dumped section with two numbers suffixed (in NxM format). -int pr_title_nxn(FILE *fp, int indent, const char *title, int n1, int n2); +int pr_title_nxn(FILE* fp, int indent, const char* title, int n1, int n2); //! Prints an array of reals. -void pr_reals(FILE *fp, int indent, const char *title, const real vec[], int n); +void pr_reals(FILE* fp, int indent, const char* title, const real vec[], int n); //! Prints an array of doubles. -void pr_doubles(FILE *fp, int indent, const char *title, const double *vec, int n); +void pr_doubles(FILE* fp, int indent, const char* title, const double* vec, int n); //! Prints an array of reals as a matrix with inner dimension dim. -void pr_reals_of_dim(FILE *fp, int indent, const char *title, const real *vec, int n, int dim); +void pr_reals_of_dim(FILE* fp, int indent, const char* title, const real* vec, int n, int dim); //! Prints an integer value. -void pr_int(FILE *fp, int indent, const char *title, int i); +void pr_int(FILE* fp, int indent, const char* title, int i); //! Prints a int64_t value. -void pr_int64(FILE *fp, int indent, const char *title, int64_t i); +void pr_int64(FILE* fp, int indent, const char* title, int64_t i); //! Prints a floating-point value. -void pr_real(FILE *fp, int indent, const char *title, real r); +void pr_real(FILE* fp, int indent, const char* title, real r); //! Prints a double-precision floating-point value. -void pr_double(FILE *fp, int indent, const char *title, double d); +void pr_double(FILE* fp, int indent, const char* title, double d); //! Prints a string value. -void pr_str(FILE *fp, int indent, const char *title, const char *s); +void pr_str(FILE* fp, int indent, const char* title, const char* s); //! Prints strings as a section; intended to be used for an array of names. -void pr_strings(FILE *fp, int indent, const char *title, char ***nm, int n, gmx_bool bShowNumbers); +void pr_strings(FILE* fp, int indent, const char* title, char*** nm, int n, gmx_bool bShowNumbers); #endif diff --git a/src/gromacs/utility/typetraits.h b/src/gromacs/utility/typetraits.h index 2ba69ba45b..90c820002e 100644 --- a/src/gromacs/utility/typetraits.h +++ b/src/gromacs/utility/typetraits.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017, by the GROMACS development team, led by + * Copyright (c) 2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -58,13 +58,19 @@ namespace gmx * \tparam Int optional integral type */ template -struct isIntegralConstant : public std::false_type {}; +struct isIntegralConstant : public std::false_type +{ +}; template -struct isIntegralConstant, void> : public std::true_type {}; +struct isIntegralConstant, void> : public std::true_type +{ +}; template -struct isIntegralConstant, Int> : public std::true_type {}; +struct isIntegralConstant, Int> : public std::true_type +{ +}; } // namespace gmx diff --git a/src/gromacs/utility/unique_cptr.h b/src/gromacs/utility/unique_cptr.h index 6903bb29b3..1949ceea69 100644 --- a/src/gromacs/utility/unique_cptr.h +++ b/src/gromacs/utility/unique_cptr.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,29 +55,30 @@ namespace gmx /*! \brief Wrapper of standard library free(), to be used as * unique_cptr deleter for memory allocated by malloc, e.g. by an * external library such as TNG. */ -template -inline void free_wrapper(T *p) +template +inline void free_wrapper(T* p) { free(p); } //! sfree wrapper to be used as unique_cptr deleter -template -inline void sfree_wrapper(T *p) +template +inline void sfree_wrapper(T* p) { sfree(p); } //! \internal \brief wrap function into functor to be used as deleter -template -struct functor_wrapper { +template +struct functor_wrapper +{ //! call wrapped function void operator()(T* t) { D(t); } }; //! unique_ptr which takes function pointer (has to return void) as template argument -template -using unique_cptr = std::unique_ptr >; +template +using unique_cptr = std::unique_ptr>; //! Simple guard which calls sfree. See unique_cptr for details. typedef unique_cptr sfree_guard; @@ -85,8 +86,11 @@ typedef unique_cptr sfree_guard; //! Create unique_ptr with any deleter function or lambda template -std::unique_ptr create_unique_with_deleter(T *t, D d) { return std::unique_ptr(t, d); } +std::unique_ptr create_unique_with_deleter(T* t, D d) +{ + return std::unique_ptr(t, d); +} -} // namespace gmx +} // namespace gmx #endif diff --git a/src/programs/gmx.cpp b/src/programs/gmx.cpp index 94a668eadb..d46ffa034d 100644 --- a/src/programs/gmx.cpp +++ b/src/programs/gmx.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2011,2012,2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,10 +47,9 @@ #include "legacymodules.h" -int -main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - gmx::CommandLineProgramContext &context = gmx::initForCommandLine(&argc, &argv); + gmx::CommandLineProgramContext& context = gmx::initForCommandLine(&argc, &argv); try { gmx::CommandLineModuleManager manager("gmx", &context); @@ -61,7 +60,7 @@ main(int argc, char *argv[]) gmx::finalizeForCommandLine(); return rc; } - catch (const std::exception &ex) + catch (const std::exception& ex) { gmx::printFatalErrorMessage(stderr, ex); return gmx::processExceptionAtExitForCommandLine(ex); diff --git a/src/programs/legacymodules.cpp b/src/programs/legacymodules.cpp index f8184fa254..e86c5e0534 100644 --- a/src/programs/legacymodules.cpp +++ b/src/programs/legacymodules.cpp @@ -83,50 +83,41 @@ namespace */ class ObsoleteToolModule : public gmx::ICommandLineModule { - public: - //! Creates an obsolete tool module for a tool with the given name. - explicit ObsoleteToolModule(const char *name) - : name_(name) - { - } +public: + //! Creates an obsolete tool module for a tool with the given name. + explicit ObsoleteToolModule(const char* name) : name_(name) {} - const char *name() const override - { - return name_; - } - const char *shortDescription() const override - { - return nullptr; - } + const char* name() const override { return name_; } + const char* shortDescription() const override { return nullptr; } - void init(gmx::CommandLineModuleSettings * /*settings*/) override - { - } - int run(int /*argc*/, char * /*argv*/[]) override - { - printMessage(); - return 0; - } - void writeHelp(const gmx::CommandLineHelpContext & /*context*/) const override - { - printMessage(); - } + void init(gmx::CommandLineModuleSettings* /*settings*/) override {} + int run(int /*argc*/, char* /*argv*/[]) override + { + printMessage(); + return 0; + } + void writeHelp(const gmx::CommandLineHelpContext& /*context*/) const override + { + printMessage(); + } - private: - void printMessage() const - { - std::fprintf(stderr, - "This tool is no longer present in GROMACS. Please see\n" - " http://jenkins.gromacs.org/job/Documentation_Nightly_master/javadoc/user-guide/cmdline.html#command-changes\n" - "for ideas how to perform the same tasks with the " - "new tools.\n"); - } +private: + void printMessage() const + { + std::fprintf(stderr, + "This tool is no longer present in GROMACS. Please see\n" + " " + "http://jenkins.gromacs.org/job/Documentation_Nightly_master/javadoc/" + "user-guide/cmdline.html#command-changes\n" + "for ideas how to perform the same tasks with the " + "new tools.\n"); + } - const char *name_; + const char* name_; }; //! Initializer for a module that defaults to nice level zero. -void initSettingsNoNice(gmx::CommandLineModuleSettings *settings) +void initSettingsNoNice(gmx::CommandLineModuleSettings* settings) { settings->setDefaultNiceLevel(0); } @@ -139,9 +130,10 @@ void initSettingsNoNice(gmx::CommandLineModuleSettings *settings) * \param[in] name Name for the new module. * \param[in] shortDescription One-line description for the new module. */ -void registerModule(gmx::CommandLineModuleManager *manager, - gmx::CommandLineModuleManager::CMainFunction mainFunction, - const char *name, const char *shortDescription) +void registerModule(gmx::CommandLineModuleManager* manager, + gmx::CommandLineModuleManager::CMainFunction mainFunction, + const char* name, + const char* shortDescription) { manager->addModuleCMain(name, shortDescription, mainFunction); } @@ -155,12 +147,12 @@ void registerModule(gmx::CommandLineModuleManager *manager, * \param[in] name Name for the new module. * \param[in] shortDescription One-line description for the new module. */ -void registerModuleNoNice(gmx::CommandLineModuleManager *manager, - gmx::CommandLineModuleManager::CMainFunction mainFunction, - const char *name, const char *shortDescription) +void registerModuleNoNice(gmx::CommandLineModuleManager* manager, + gmx::CommandLineModuleManager::CMainFunction mainFunction, + const char* name, + const char* shortDescription) { - manager->addModuleCMainWithSettings(name, shortDescription, mainFunction, - &initSettingsNoNice); + manager->addModuleCMainWithSettings(name, shortDescription, mainFunction, &initSettingsNoNice); } /*! \brief @@ -169,8 +161,7 @@ void registerModuleNoNice(gmx::CommandLineModuleManager *manager, * \param[in] manager Module manager to which to register the module. * \param[in] name Name for the obsolete tool. */ -void registerObsoleteTool(gmx::CommandLineModuleManager *manager, - const char *name) +void registerObsoleteTool(gmx::CommandLineModuleManager* manager, const char* name) { gmx::CommandLineModulePointer module(new ObsoleteToolModule(name)); manager->addModule(std::move(module)); @@ -178,54 +169,42 @@ void registerObsoleteTool(gmx::CommandLineModuleManager *manager, } // namespace -void registerLegacyModules(gmx::CommandLineModuleManager *manager) +void registerLegacyModules(gmx::CommandLineModuleManager* manager) { - registerModule(manager, &gmx_check, "check", - "Check and compare files"); + registerModule(manager, &gmx_check, "check", "Check and compare files"); gmx::ICommandLineOptionsModule::registerModuleFactory( - manager, gmx::DumpInfo::name, - gmx::DumpInfo::shortDescription, - &gmx::DumpInfo::create); - registerModule(manager, &gmx_grompp, "grompp", - "Make a run input file"); - registerModule(manager, &gmx_convert_tpr, "convert-tpr", - "Make a modifed run-input file"); + manager, gmx::DumpInfo::name, gmx::DumpInfo::shortDescription, &gmx::DumpInfo::create); + registerModule(manager, &gmx_grompp, "grompp", "Make a run input file"); + registerModule(manager, &gmx_convert_tpr, "convert-tpr", "Make a modifed run-input file"); registerObsoleteTool(manager, "tpbconv"); - registerModule(manager, &gmx_x2top, "x2top", - "Generate a primitive topology from coordinates"); + registerModule(manager, &gmx_x2top, "x2top", "Generate a primitive topology from coordinates"); - registerModuleNoNice(manager, &gmx::gmx_mdrun, "mdrun", - "Perform a simulation, do a normal mode analysis or an energy minimization"); + registerModuleNoNice( + manager, &gmx::gmx_mdrun, "mdrun", + "Perform a simulation, do a normal mode analysis or an energy minimization"); gmx::ICommandLineOptionsModule::registerModuleFactory( manager, gmx::NonbondedBenchmarkInfo::name, - gmx::NonbondedBenchmarkInfo::shortDescription, - &gmx::NonbondedBenchmarkInfo::create); + gmx::NonbondedBenchmarkInfo::shortDescription, &gmx::NonbondedBenchmarkInfo::create); - gmx::ICommandLineOptionsModule::registerModuleFactory( - manager, gmx::InsertMoleculesInfo::name(), - gmx::InsertMoleculesInfo::shortDescription(), - &gmx::InsertMoleculesInfo::create); + gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::InsertMoleculesInfo::name(), + gmx::InsertMoleculesInfo::shortDescription(), + &gmx::InsertMoleculesInfo::create); - gmx::ICommandLineOptionsModule::registerModuleFactory( - manager, gmx::ReportMethodsInfo::name, - gmx::ReportMethodsInfo::shortDescription, - &gmx::ReportMethodsInfo::create); + gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::ReportMethodsInfo::name, + gmx::ReportMethodsInfo::shortDescription, + &gmx::ReportMethodsInfo::create); - gmx::ICommandLineOptionsModule::registerModuleFactory( - manager, gmx::pdb2gmxInfo::name, - gmx::pdb2gmxInfo::shortDescription, - &gmx::pdb2gmxInfo::create); + gmx::ICommandLineOptionsModule::registerModuleFactory(manager, gmx::pdb2gmxInfo::name, + gmx::pdb2gmxInfo::shortDescription, + &gmx::pdb2gmxInfo::create); // Modules from gmx_ana.h. registerModule(manager, &gmx_do_dssp, "do_dssp", "Assign secondary structure and calculate solvent accessible surface area"); - registerModule(manager, &gmx_editconf, "editconf", - "Convert and manipulates structure files"); - registerModule(manager, &gmx_eneconv, "eneconv", - "Convert energy files"); - registerModule(manager, &gmx_solvate, "solvate", - "Solvate a system"); + registerModule(manager, &gmx_editconf, "editconf", "Convert and manipulates structure files"); + registerModule(manager, &gmx_eneconv, "eneconv", "Convert energy files"); + registerModule(manager, &gmx_solvate, "solvate", "Solvate a system"); registerObsoleteTool(manager, "genbox"); registerModule(manager, &gmx_genconf, "genconf", "Multiply a conformation in 'random' orientations"); @@ -235,23 +214,17 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) "Generate position restraints or distance restraints for index groups"); registerModule(manager, &gmx_make_edi, "make_edi", "Generate input files for essential dynamics sampling"); - registerModule(manager, &gmx_make_ndx, "make_ndx", - "Make index files"); - registerModule(manager, &gmx_mk_angndx, "mk_angndx", - "Generate index files for 'gmx angle'"); - registerModule(manager, &gmx_trjcat, "trjcat", - "Concatenate trajectory files"); - registerModule(manager, &gmx_trjconv, "trjconv", - "Convert and manipulates trajectory files"); + registerModule(manager, &gmx_make_ndx, "make_ndx", "Make index files"); + registerModule(manager, &gmx_mk_angndx, "mk_angndx", "Generate index files for 'gmx angle'"); + registerModule(manager, &gmx_trjcat, "trjcat", "Concatenate trajectory files"); + registerModule(manager, &gmx_trjconv, "trjconv", "Convert and manipulates trajectory files"); registerModule(manager, &gmx_trjorder, "trjorder", "Order molecules according to their distance to a group"); registerModule(manager, &gmx_xpm2ps, "xpm2ps", "Convert XPM (XPixelMap) matrices to postscript or XPM"); - registerModule(manager, &gmx_anaeig, "anaeig", - "Analyze eigenvectors/normal modes"); - registerModule(manager, &gmx_analyze, "analyze", - "Analyze data sets"); + registerModule(manager, &gmx_anaeig, "anaeig", "Analyze eigenvectors/normal modes"); + registerModule(manager, &gmx_analyze, "analyze", "Analyze data sets"); registerModule(manager, &gmx_g_angle, "angle", "Calculate distributions and correlations for angles and dihedrals"); registerModule(manager, &gmx_awh, "awh", @@ -263,64 +236,46 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) registerObsoleteTool(manager, "sas"); registerObsoleteTool(manager, "sgangle"); - registerModule(manager, &gmx_bundle, "bundle", - "Analyze bundles of axes, e.g., helices"); + registerModule(manager, &gmx_bundle, "bundle", "Analyze bundles of axes, e.g., helices"); registerModule(manager, &gmx_chi, "chi", "Calculate everything you want to know about chi and other dihedrals"); - registerModule(manager, &gmx_cluster, "cluster", - "Cluster structures"); + registerModule(manager, &gmx_cluster, "cluster", "Cluster structures"); registerModule(manager, &gmx_clustsize, "clustsize", "Calculate size distributions of atomic clusters"); - registerModule(manager, &gmx_confrms, "confrms", - "Fit two structures and calculates the RMSD"); - registerModule(manager, &gmx_covar, "covar", - "Calculate and diagonalize the covariance matrix"); + registerModule(manager, &gmx_confrms, "confrms", "Fit two structures and calculates the RMSD"); + registerModule(manager, &gmx_covar, "covar", "Calculate and diagonalize the covariance matrix"); registerModule(manager, &gmx_current, "current", "Calculate dielectric constants and current autocorrelation function"); - registerModule(manager, &gmx_density, "density", - "Calculate the density of the system"); + registerModule(manager, &gmx_density, "density", "Calculate the density of the system"); registerModule(manager, &gmx_densmap, "densmap", "Calculate 2D planar or axial-radial density maps"); - registerModule(manager, &gmx_densorder, "densorder", - "Calculate surface fluctuations"); + registerModule(manager, &gmx_densorder, "densorder", "Calculate surface fluctuations"); registerModule(manager, &gmx_dielectric, "dielectric", "Calculate frequency dependent dielectric constants"); - registerModule(manager, &gmx_dipoles, "dipoles", - "Compute the total dipole plus fluctuations"); - registerModule(manager, &gmx_disre, "disre", - "Analyze distance restraints"); + registerModule(manager, &gmx_dipoles, "dipoles", "Compute the total dipole plus fluctuations"); + registerModule(manager, &gmx_disre, "disre", "Analyze distance restraints"); registerModule(manager, &gmx_dos, "dos", "Analyze density of states and properties based on that"); - registerModule(manager, &gmx_dyecoupl, "dyecoupl", - "Extract dye dynamics from trajectories"); - registerModule(manager, &gmx_enemat, "enemat", - "Extract an energy matrix from an energy file"); + registerModule(manager, &gmx_dyecoupl, "dyecoupl", "Extract dye dynamics from trajectories"); + registerModule(manager, &gmx_enemat, "enemat", "Extract an energy matrix from an energy file"); registerModule(manager, &gmx_energy, "energy", "Writes energies to xvg files and display averages"); registerModule(manager, &gmx_filter, "filter", "Frequency filter trajectories, useful for making smooth movies"); - registerModule(manager, &gmx_gyrate, "gyrate", - "Calculate the radius of gyration"); - registerModule(manager, &gmx_h2order, "h2order", - "Compute the orientation of water molecules"); - registerModule(manager, &gmx_hbond, "hbond", - "Compute and analyze hydrogen bonds"); - registerModule(manager, &gmx_helix, "helix", - "Calculate basic properties of alpha helices"); + registerModule(manager, &gmx_gyrate, "gyrate", "Calculate the radius of gyration"); + registerModule(manager, &gmx_h2order, "h2order", "Compute the orientation of water molecules"); + registerModule(manager, &gmx_hbond, "hbond", "Compute and analyze hydrogen bonds"); + registerModule(manager, &gmx_helix, "helix", "Calculate basic properties of alpha helices"); registerModule(manager, &gmx_helixorient, "helixorient", "Calculate local pitch/bending/rotation/orientation inside helices"); registerModule(manager, &gmx_hydorder, "hydorder", "Compute tetrahedrality parameters around a given atom"); - registerModule(manager, &gmx_lie, "lie", - "Estimate free energy from linear combinations"); - registerModule(manager, &gmx_mdmat, "mdmat", - "Calculate residue contact maps"); + registerModule(manager, &gmx_lie, "lie", "Estimate free energy from linear combinations"); + registerModule(manager, &gmx_mdmat, "mdmat", "Calculate residue contact maps"); registerModule(manager, &gmx_mindist, "mindist", "Calculate the minimum distance between two groups"); - registerModule(manager, &gmx_msd, "msd", - "Calculates mean square displacements"); - registerModule(manager, &gmx_nmeig, "nmeig", - "Diagonalize the Hessian for normal mode analysis"); + registerModule(manager, &gmx_msd, "msd", "Calculates mean square displacements"); + registerModule(manager, &gmx_nmeig, "nmeig", "Diagonalize the Hessian for normal mode analysis"); registerModule(manager, &gmx_nmens, "nmens", "Generate an ensemble of structures from the normal modes"); registerModule(manager, &gmx_nmr, "nmr", @@ -331,60 +286,48 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) "Compute the order parameter per atom for carbon tails"); registerModule(manager, &gmx_pme_error, "pme_error", "Estimate the error of using PME with a given input file"); - registerModule(manager, &gmx_polystat, "polystat", - "Calculate static properties of polymers"); + registerModule(manager, &gmx_polystat, "polystat", "Calculate static properties of polymers"); registerModule(manager, &gmx_potential, "potential", "Calculate the electrostatic potential across the box"); registerModule(manager, &gmx_principal, "principal", "Calculate principal axes of inertia for a group of atoms"); - registerModule(manager, &gmx_rama, "rama", - "Compute Ramachandran plots"); + registerModule(manager, &gmx_rama, "rama", "Compute Ramachandran plots"); registerModule(manager, &gmx_rms, "rms", "Calculate RMSDs with a reference structure and RMSD matrices"); registerModule(manager, &gmx_rmsdist, "rmsdist", "Calculate atom pair distances averaged with power -2, -3 or -6"); - registerModule(manager, &gmx_rmsf, "rmsf", - "Calculate atomic fluctuations"); + registerModule(manager, &gmx_rmsf, "rmsf", "Calculate atomic fluctuations"); registerModule(manager, &gmx_rotacf, "rotacf", "Calculate the rotational correlation function for molecules"); registerModule(manager, &gmx_rotmat, "rotmat", "Plot the rotation matrix for fitting to a reference structure"); - registerModule(manager, &gmx_saltbr, "saltbr", - "Compute salt bridges"); - registerModule(manager, &gmx_sans, "sans", - "Compute small angle neutron scattering spectra"); - registerModule(manager, &gmx_saxs, "saxs", - "Compute small angle X-ray scattering spectra"); + registerModule(manager, &gmx_saltbr, "saltbr", "Compute salt bridges"); + registerModule(manager, &gmx_sans, "sans", "Compute small angle neutron scattering spectra"); + registerModule(manager, &gmx_saxs, "saxs", "Compute small angle X-ray scattering spectra"); registerModule(manager, &gmx_sham, "sham", "Compute free energies or other histograms from histograms"); registerModule(manager, &gmx_sigeps, "sigeps", "Convert c6/12 or c6/cn combinations to and from sigma/epsilon"); - registerModule(manager, &gmx_sorient, "sorient", - "Analyze solvent orientation around solutes"); - registerModule(manager, &gmx_spatial, "spatial", - "Calculate the spatial distribution function"); + registerModule(manager, &gmx_sorient, "sorient", "Analyze solvent orientation around solutes"); + registerModule(manager, &gmx_spatial, "spatial", "Calculate the spatial distribution function"); registerModule(manager, &gmx_spol, "spol", "Analyze solvent dipole orientation and polarization around solutes"); - registerModule(manager, &gmx_tcaf, "tcaf", - "Calculate viscosities of liquids"); + registerModule(manager, &gmx_tcaf, "tcaf", "Calculate viscosities of liquids"); registerModule(manager, &gmx_traj, "traj", "Plot x, v, f, box, temperature and rotational energy from trajectories"); registerModule(manager, &gmx_tune_pme, "tune_pme", "Time mdrun as a function of PME ranks to optimize settings"); registerModule(manager, &gmx_vanhove, "vanhove", "Compute Van Hove displacement and correlation functions"); - registerModule(manager, &gmx_velacc, "velacc", - "Calculate velocity autocorrelation functions"); + registerModule(manager, &gmx_velacc, "velacc", "Calculate velocity autocorrelation functions"); registerModule(manager, &gmx_wham, "wham", "Perform weighted histogram analysis after umbrella sampling"); - registerModule(manager, &gmx_wheel, "wheel", - "Plot helical wheels"); - registerModuleNoNice(manager, &gmx_view, "view", - "View a trajectory on an X-Windows terminal"); + registerModule(manager, &gmx_wheel, "wheel", "Plot helical wheels"); + registerModuleNoNice(manager, &gmx_view, "view", "View a trajectory on an X-Windows terminal"); { gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Generating topologies and coordinates"); + manager->addModuleGroup("Generating topologies and coordinates"); group.addModuleWithDescription("editconf", "Edit the box and write subgroups"); group.addModule("x2top"); group.addModule("solvate"); @@ -395,28 +338,25 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("pdb2gmx"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Running a simulation"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Running a simulation"); group.addModule("grompp"); group.addModule("mdrun"); group.addModule("convert-tpr"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Viewing trajectories"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Viewing trajectories"); group.addModule("nmtraj"); group.addModule("view"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Processing energies"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Processing energies"); group.addModule("enemat"); group.addModule("energy"); - group.addModuleWithDescription("mdrun", "(Re)calculate energies for trajectory frames with -rerun"); + group.addModuleWithDescription("mdrun", + "(Re)calculate energies for trajectory frames with -rerun"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Converting files"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Converting files"); group.addModule("editconf"); group.addModule("eneconv"); group.addModule("sigeps"); @@ -425,8 +365,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("xpm2ps"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Tools"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Tools"); group.addModule("analyze"); group.addModule("awh"); group.addModule("filter"); @@ -446,8 +385,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("report-methods"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Distances between structures"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Distances between structures"); group.addModule("cluster"); group.addModule("confrms"); group.addModule("rms"); @@ -455,7 +393,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) } { gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Distances in structures over time"); + manager->addModuleGroup("Distances in structures over time"); group.addModule("mindist"); group.addModule("mdmat"); group.addModule("polystat"); @@ -463,7 +401,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) } { gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Mass distribution properties over time"); + manager->addModuleGroup("Mass distribution properties over time"); group.addModule("gyrate"); group.addModule("msd"); group.addModule("polystat"); @@ -477,13 +415,12 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) } { gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Analyzing bonded interactions"); + manager->addModuleGroup("Analyzing bonded interactions"); group.addModule("angle"); group.addModule("mk_angndx"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Structural properties"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Structural properties"); group.addModule("bundle"); group.addModule("clustsize"); group.addModule("disre"); @@ -496,8 +433,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("spol"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Kinetic properties"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Kinetic properties"); group.addModule("bar"); group.addModule("current"); group.addModule("dos"); @@ -509,8 +445,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("velacc"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Electrostatic properties"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Electrostatic properties"); group.addModule("current"); group.addModule("dielectric"); group.addModule("dipoles"); @@ -519,8 +454,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("genion"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Protein-specific analysis"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Protein-specific analysis"); group.addModule("do_dssp"); group.addModule("chi"); group.addModule("helix"); @@ -529,8 +463,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("wheel"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Interfaces"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Interfaces"); group.addModule("bundle"); group.addModule("density"); group.addModule("densmap"); @@ -541,20 +474,19 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager) group.addModule("potential"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Covariance analysis"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Covariance analysis"); group.addModuleWithDescription("anaeig", "Analyze the eigenvectors"); group.addModule("covar"); group.addModule("make_edi"); } { - gmx::CommandLineModuleGroup group = - manager->addModuleGroup("Normal modes"); + gmx::CommandLineModuleGroup group = manager->addModuleGroup("Normal modes"); group.addModuleWithDescription("anaeig", "Analyze the normal modes"); group.addModule("nmeig"); group.addModule("nmtraj"); group.addModule("nmens"); group.addModule("grompp"); - group.addModuleWithDescription("mdrun", "Find a potential energy minimum and calculate the Hessian"); + group.addModuleWithDescription("mdrun", + "Find a potential energy minimum and calculate the Hessian"); } } diff --git a/src/programs/legacymodules.h b/src/programs/legacymodules.h index 378f9bfedf..878f2af8b1 100644 --- a/src/programs/legacymodules.h +++ b/src/programs/legacymodules.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2014, by the GROMACS development team, led by + * Copyright (c) 2012,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,6 +54,6 @@ class CommandLineModuleManager; * Registers all modules corresponding to pre-5.0 binaries such that * they can be run through \p manager. */ -void registerLegacyModules(gmx::CommandLineModuleManager *manager); +void registerLegacyModules(gmx::CommandLineModuleManager* manager); #endif diff --git a/src/programs/mdrun/mdrun.cpp b/src/programs/mdrun/mdrun.cpp index 9d62cd6371..5a4a46d7f4 100644 --- a/src/programs/mdrun/mdrun.cpp +++ b/src/programs/mdrun/mdrun.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,11 +74,11 @@ namespace gmx { //! Implements C-style main function for mdrun -int gmx_mdrun(int argc, char *argv[]) +int gmx_mdrun(int argc, char* argv[]) { - auto mdModules = std::make_unique(); + auto mdModules = std::make_unique(); - std::vectordesc = { + std::vector desc = { "[THISMODULE] is the main computational chemistry engine", "within GROMACS. Obviously, it performs Molecular Dynamics simulations,", "but it can also perform Stochastic Dynamics, Energy Minimization,", @@ -205,7 +205,7 @@ int gmx_mdrun(int argc, char *argv[]) "pulling is used." }; - LegacyMdrunOptions options; + LegacyMdrunOptions options; if (options.updateFromCommandLine(argc, argv, desc) == 0) { @@ -213,7 +213,7 @@ int gmx_mdrun(int argc, char *argv[]) } ArrayRef multiSimDirectoryNames = - opt2fnsIfOptionSet("-multidir", ssize(options.filenames), options.filenames.data()); + opt2fnsIfOptionSet("-multidir", ssize(options.filenames), options.filenames.data()); // Set up the communicator, where possible (see docs for // SimulationContext). @@ -225,16 +225,12 @@ int gmx_mdrun(int argc, char *argv[]) // wrapper binary. SimulationContext simulationContext(communicator, multiSimDirectoryNames); - StartingBehavior startingBehavior = StartingBehavior::NewSimulation; - LogFilePtr logFileGuard = nullptr; - gmx_multisim_t *ms = simulationContext.multiSimulation_.get(); - std::tie(startingBehavior, - logFileGuard) = handleRestart(findIsSimulationMasterRank(ms, communicator), - communicator, - ms, - options.mdrunOptions.appendingBehavior, - ssize(options.filenames), - options.filenames.data()); + StartingBehavior startingBehavior = StartingBehavior::NewSimulation; + LogFilePtr logFileGuard = nullptr; + gmx_multisim_t* ms = simulationContext.multiSimulation_.get(); + std::tie(startingBehavior, logFileGuard) = handleRestart( + findIsSimulationMasterRank(ms, communicator), communicator, ms, + options.mdrunOptions.appendingBehavior, ssize(options.filenames), options.filenames.data()); /* The named components for the builder exposed here are descriptive of the * state of mdrun at implementation and are not intended to be prescriptive @@ -274,4 +270,4 @@ int gmx_mdrun(int argc, char *argv[]) return runner.mdrunner(); } -} +} // namespace gmx diff --git a/src/programs/mdrun/mdrun_main.h b/src/programs/mdrun/mdrun_main.h index 38f899b66f..8a6e7ecae9 100644 --- a/src/programs/mdrun/mdrun_main.h +++ b/src/programs/mdrun/mdrun_main.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -38,7 +38,7 @@ namespace gmx { -int gmx_mdrun(int argc, char *argv[]); +int gmx_mdrun(int argc, char* argv[]); } // namespace gmx diff --git a/src/programs/mdrun/nonbonded_bench.cpp b/src/programs/mdrun/nonbonded_bench.cpp index 1adf0bd7be..3f4308cfe0 100644 --- a/src/programs/mdrun/nonbonded_bench.cpp +++ b/src/programs/mdrun/nonbonded_bench.cpp @@ -64,27 +64,23 @@ namespace class NonbondedBenchmark : public ICommandLineOptionsModule { - public: - NonbondedBenchmark() - {} - - // From ICommandLineOptionsModule - void init(CommandLineModuleSettings * /*settings*/) override - { - } - void initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) override; - void optionsFinished() override; - int run() override; - private: - int sizeFactor_ = 1; - Nbnxm::KernelBenchOptions benchmarkOptions_; +public: + NonbondedBenchmark() {} + + // From ICommandLineOptionsModule + void init(CommandLineModuleSettings* /*settings*/) override {} + void initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) override; + void optionsFinished() override; + int run() override; + +private: + int sizeFactor_ = 1; + Nbnxm::KernelBenchOptions benchmarkOptions_; }; -void NonbondedBenchmark::initOptions(IOptionsContainer *options, - ICommandLineOptionsModuleSettings *settings) +void NonbondedBenchmark::initOptions(IOptionsContainer* options, ICommandLineOptionsModuleSettings* settings) { - std::vector desc = { + std::vector desc = { "[THISMODULE] runs benchmarks for one or more so-called Nbnxm", "non-bonded pair kernels. The non-bonded pair kernels are", "the most compute intensive part of MD simulations", @@ -161,67 +157,58 @@ void NonbondedBenchmark::initOptions(IOptionsContainer *options, settings->setHelpText(desc); - const char *const cNbnxmSimdStrings[] = { - "auto", "no", "4xm", "2xmm" - }; - const char *const cCombRuleStrings[] = { - "geometric", "lb", "none" - }; - const char *const cCoulombTypeStrings[] = { - "ewald", "reaction-field" - }; + const char* const cNbnxmSimdStrings[] = { "auto", "no", "4xm", "2xmm" }; + const char* const cCombRuleStrings[] = { "geometric", "lb", "none" }; + const char* const cCoulombTypeStrings[] = { "ewald", "reaction-field" }; - options->addOption(IntegerOption("size") - .store(&sizeFactor_) - .description("The system size is 3000 atoms times this value")); - options->addOption(IntegerOption("nt") - .store(&benchmarkOptions_.numThreads) - .description("The number of OpenMP threads to use")); + options->addOption( + IntegerOption("size").store(&sizeFactor_).description("The system size is 3000 atoms times this value")); + options->addOption( + IntegerOption("nt").store(&benchmarkOptions_.numThreads).description("The number of OpenMP threads to use")); options->addOption(EnumOption("simd") - .store(&benchmarkOptions_.nbnxmSimd) - .enumValue(cNbnxmSimdStrings) - .description("SIMD type, auto runs all supported SIMD setups or no SIMD when SIMD is not supported")); + .store(&benchmarkOptions_.nbnxmSimd) + .enumValue(cNbnxmSimdStrings) + .description("SIMD type, auto runs all supported SIMD setups or no " + "SIMD when SIMD is not supported")); options->addOption(EnumOption("coulomb") - .store(&benchmarkOptions_.coulombType) - .enumValue(cCoulombTypeStrings) - .description("The functional form for the Coulomb interactions")); - options->addOption(BooleanOption("table") - .store(&benchmarkOptions_.useTabulatedEwaldCorr) - .description("Use lookup table for Ewald correction instead of analytical")); + .store(&benchmarkOptions_.coulombType) + .enumValue(cCoulombTypeStrings) + .description("The functional form for the Coulomb interactions")); + options->addOption( + BooleanOption("table") + .store(&benchmarkOptions_.useTabulatedEwaldCorr) + .description("Use lookup table for Ewald correction instead of analytical")); options->addOption(EnumOption("combrule") - .store(&benchmarkOptions_.ljCombinationRule) - .enumValue(cCombRuleStrings) - .description("The LJ combination rule")); + .store(&benchmarkOptions_.ljCombinationRule) + .enumValue(cCombRuleStrings) + .description("The LJ combination rule")); options->addOption(BooleanOption("halflj") - .store(&benchmarkOptions_.useHalfLJOptimization) - .description("Use optimization for LJ on half of the atoms")); + .store(&benchmarkOptions_.useHalfLJOptimization) + .description("Use optimization for LJ on half of the atoms")); options->addOption(BooleanOption("energy") - .store(&benchmarkOptions_.computeVirialAndEnergy) - .description("Compute energies in addition to forces")); - options->addOption(BooleanOption("all") - .store(&benchmarkOptions_.doAll) - .description("Run all 12 combinations of options for coulomb, halflj, combrule")); + .store(&benchmarkOptions_.computeVirialAndEnergy) + .description("Compute energies in addition to forces")); + options->addOption( + BooleanOption("all").store(&benchmarkOptions_.doAll).description("Run all 12 combinations of options for coulomb, halflj, combrule")); options->addOption(RealOption("cutoff") - .store(&benchmarkOptions_.pairlistCutoff) - .description("Pair-list and interaction cut-off distance")); + .store(&benchmarkOptions_.pairlistCutoff) + .description("Pair-list and interaction cut-off distance")); options->addOption(IntegerOption("iter") - .store(&benchmarkOptions_.numIterations) - .description("The number of iterations for each kernel")); + .store(&benchmarkOptions_.numIterations) + .description("The number of iterations for each kernel")); options->addOption(IntegerOption("warmup") - .store(&benchmarkOptions_.numWarmupIterations) - .description("The number of iterations for initial warmup")); + .store(&benchmarkOptions_.numWarmupIterations) + .description("The number of iterations for initial warmup")); options->addOption(BooleanOption("cycles") - .store(&benchmarkOptions_.cyclesPerPair) - .description("Report cycles/pair instead of pairs/cycle")); - + .store(&benchmarkOptions_.cyclesPerPair) + .description("Report cycles/pair instead of pairs/cycle")); } void NonbondedBenchmark::optionsFinished() { // We compute the Ewald coefficient here to avoid a dependency of the Nbnxm on the Ewald module - const real ewald_rtol = 1e-5; - benchmarkOptions_.ewaldcoeff_q = calc_ewaldcoeff_q(benchmarkOptions_.pairlistCutoff, - ewald_rtol); + const real ewald_rtol = 1e-5; + benchmarkOptions_.ewaldcoeff_q = calc_ewaldcoeff_q(benchmarkOptions_.pairlistCutoff, ewald_rtol); } int NonbondedBenchmark::run() @@ -231,15 +218,15 @@ int NonbondedBenchmark::run() return 0; } -} // namespace +} // namespace -const char NonbondedBenchmarkInfo::name[] = "nonbonded-benchmark"; +const char NonbondedBenchmarkInfo::name[] = "nonbonded-benchmark"; const char NonbondedBenchmarkInfo::shortDescription[] = - "Benchmarking tool for the non-bonded pair kernels."; + "Benchmarking tool for the non-bonded pair kernels."; ICommandLineOptionsModulePointer NonbondedBenchmarkInfo::create() { return ICommandLineOptionsModulePointer(std::make_unique()); } -} //i namespace gmx +} // namespace gmx diff --git a/src/programs/mdrun/nonbonded_bench.h b/src/programs/mdrun/nonbonded_bench.h index 5b42b81191..7257d62d74 100644 --- a/src/programs/mdrun/nonbonded_bench.h +++ b/src/programs/mdrun/nonbonded_bench.h @@ -50,13 +50,13 @@ namespace gmx //! Declares gmx nonbonded-bench. class NonbondedBenchmarkInfo { - public: - //! Name of the module. - static const char name[]; - //! Short module description. - static const char shortDescription[]; - //! Build the actual gmx module to use. - static ICommandLineOptionsModulePointer create(); +public: + //! Name of the module. + static const char name[]; + //! Short module description. + static const char shortDescription[]; + //! Build the actual gmx module to use. + static ICommandLineOptionsModulePointer create(); }; } // namespace gmx diff --git a/src/programs/mdrun/tests/compressed_x_output.cpp b/src/programs/mdrun/tests/compressed_x_output.cpp index 8512d162b5..8d56daf797 100644 --- a/src/programs/mdrun/tests/compressed_x_output.cpp +++ b/src/programs/mdrun/tests/compressed_x_output.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,8 +57,9 @@ namespace { //! Test fixture for mdrun -x -class MdrunCompressedXOutputTest : public gmx::test::MdrunTestFixture, - public testing::WithParamInterface +class MdrunCompressedXOutputTest : + public gmx::test::MdrunTestFixture, + public testing::WithParamInterface { }; @@ -88,21 +89,20 @@ TEST_P(MdrunCompressedXOutput, ExitsNormally) ASSERT_EQ(0, gmx_check(checkCaller.argc(), checkCaller.argv())); } -INSTANTIATE_TEST_CASE_P(WithDifferentOutputGroupSettings, MdrunCompressedXOutput, - ::testing::Values - ( // Test writing the whole system via - // the default behaviour - "", - - // Test writing the whole system - // explicitly - "compressed-x-grps = System\n", - - // Test writing only part of the system. - // It would be nice to check that this test - // writes 3 atoms and the others write 6, but - // that's not yet easy. - "compressed-x-grps = SecondWaterMolecule\n" - )); +INSTANTIATE_TEST_CASE_P(WithDifferentOutputGroupSettings, + MdrunCompressedXOutput, + ::testing::Values( // Test writing the whole system via + // the default behaviour + "", + + // Test writing the whole system + // explicitly + "compressed-x-grps = System\n", + + // Test writing only part of the system. + // It would be nice to check that this test + // writes 3 atoms and the others write 6, but + // that's not yet easy. + "compressed-x-grps = SecondWaterMolecule\n")); } // namespace diff --git a/src/programs/mdrun/tests/densityfittingmodule.cpp b/src/programs/mdrun/tests/densityfittingmodule.cpp index adf4e4d241..fa098d82c9 100644 --- a/src/programs/mdrun/tests/densityfittingmodule.cpp +++ b/src/programs/mdrun/tests/densityfittingmodule.cpp @@ -71,65 +71,64 @@ namespace test */ class DensityFittingTest : public MdrunTestFixture { - public: - DensityFittingTest() - { - runner_.useTopGroAndNdxFromDatabase("argon12"); - runner_.edrFileName_ = fileManager_.getTemporaryFilePath(".edr"); - }; - - //! Check the output of mdrun - void checkMdrun(real energyTermMagnitude) - { - const FloatingPointTolerance energyTermTolerance = +public: + DensityFittingTest() + { + runner_.useTopGroAndNdxFromDatabase("argon12"); + runner_.edrFileName_ = fileManager_.getTemporaryFilePath(".edr"); + }; + + //! Check the output of mdrun + void checkMdrun(real energyTermMagnitude) + { + const FloatingPointTolerance energyTermTolerance = relativeToleranceAsFloatingPoint(energyTermMagnitude, 1e-4); - EnergyTermsToCompare energyTermsToCompare { - { { interaction_function[F_DENSITYFITTING].longname, energyTermTolerance }, - { interaction_function[F_EPOT].longname, energyTermTolerance } } - }; - - TestReferenceData refData; - auto checker = refData.rootChecker(); - checkEnergiesAgainstReferenceData(runner_.edrFileName_, energyTermsToCompare, &checker); - } - - //! Mdp values for steepest-decent energy minimization with default density fitting parameters. - const std::string mdpEminDensfitYesUnsetValues = formatString( - "integrator = steep\n" - "nsteps = 2\n" - "cutoff-scheme = verlet\n" - "density-guided-simulation-active = yes\n" - "density-guided-simulation-group = FirstThreeOfTwelve\n" - "density-guided-simulation-reference-density-filename = %s\n", - TestFileManager::getInputFilePath("ellipsoid-density.mrc").c_str() ); - - //! Mdp values for md integrator with default density fitting parameters. - const std::string mdpMdDensfitYesUnsetValues = formatString( - "integrator = md\n" - "nsteps = 2\n" - "cutoff-scheme = verlet\n" - "density-guided-simulation-active = yes\n" - "density-guided-simulation-group = FirstThreeOfTwelve\n" - "density-guided-simulation-reference-density-filename = %s\n", - TestFileManager::getInputFilePath("ellipsoid-density.mrc").c_str() ); - - //! Mdp values for steepest-decent energy minimization with density fitting values set to non-defaults. - const std::string mdpDensiftAllDefaultsChanged_ = formatString( - "density-guided-simulation-similarity-measure = relative-entropy\n" - "density-guided-simulation-atom-spreading-weight = mass\n" - "density-guided-simulation-force-constant = -1\n" - "density-guided-simulation-gaussian-transform-spreading-width = 0.8\n" - "density-guided-simulation-gaussian-transform-spreading-range-in-multiples-of-width = 6\n" - "density-guided-simulation-normalize-densities = false\n" - ); - //! Set mdp values so that energy calculation interval and density guided simulation interval mismatch. - const std::string mdpEnergyAndDensityfittingIntervalMismatch_ = formatString( - "nstcalcenergy = 7\n" - "density-guided-simulation-nst = 3\n" - ); - //! The command line to call mdrun - CommandLine commandLineForMdrun_; + EnergyTermsToCompare energyTermsToCompare{ + { { interaction_function[F_DENSITYFITTING].longname, energyTermTolerance }, + { interaction_function[F_EPOT].longname, energyTermTolerance } } + }; + + TestReferenceData refData; + auto checker = refData.rootChecker(); + checkEnergiesAgainstReferenceData(runner_.edrFileName_, energyTermsToCompare, &checker); + } + + //! Mdp values for steepest-decent energy minimization with default density fitting parameters. + const std::string mdpEminDensfitYesUnsetValues = formatString( + "integrator = steep\n" + "nsteps = 2\n" + "cutoff-scheme = verlet\n" + "density-guided-simulation-active = yes\n" + "density-guided-simulation-group = FirstThreeOfTwelve\n" + "density-guided-simulation-reference-density-filename = %s\n", + TestFileManager::getInputFilePath("ellipsoid-density.mrc").c_str()); + + //! Mdp values for md integrator with default density fitting parameters. + const std::string mdpMdDensfitYesUnsetValues = formatString( + "integrator = md\n" + "nsteps = 2\n" + "cutoff-scheme = verlet\n" + "density-guided-simulation-active = yes\n" + "density-guided-simulation-group = FirstThreeOfTwelve\n" + "density-guided-simulation-reference-density-filename = %s\n", + TestFileManager::getInputFilePath("ellipsoid-density.mrc").c_str()); + + //! Mdp values for steepest-decent energy minimization with density fitting values set to non-defaults. + const std::string mdpDensiftAllDefaultsChanged_ = formatString( + "density-guided-simulation-similarity-measure = relative-entropy\n" + "density-guided-simulation-atom-spreading-weight = mass\n" + "density-guided-simulation-force-constant = -1\n" + "density-guided-simulation-gaussian-transform-spreading-width = 0.8\n" + "density-guided-simulation-gaussian-transform-spreading-range-in-multiples-of-width = " + "6\n" + "density-guided-simulation-normalize-densities = false\n"); + //! Set mdp values so that energy calculation interval and density guided simulation interval mismatch. + const std::string mdpEnergyAndDensityfittingIntervalMismatch_ = formatString( + "nstcalcenergy = 7\n" + "density-guided-simulation-nst = 3\n"); + //! The command line to call mdrun + CommandLine commandLineForMdrun_; }; /* Fit a subset of three of twelve argon atoms into a reference density @@ -168,7 +167,8 @@ TEST_F(DensityFittingTest, GromppErrorWhenEnergyEvaluationFrequencyMismatch) { runner_.useStringAsMdpFile(mdpMdDensfitYesUnsetValues + mdpEnergyAndDensityfittingIntervalMismatch_); - EXPECT_DEATH_IF_SUPPORTED(runner_.callGrompp(), ".*is not a multiple of density-guided-simulation-nst.*"); + EXPECT_DEATH_IF_SUPPORTED(runner_.callGrompp(), + ".*is not a multiple of density-guided-simulation-nst.*"); } } // namespace test diff --git a/src/programs/mdrun/tests/energycomparison.cpp b/src/programs/mdrun/tests/energycomparison.cpp index 2eb0dbc3e7..fbdd46faf7 100644 --- a/src/programs/mdrun/tests/energycomparison.cpp +++ b/src/programs/mdrun/tests/energycomparison.cpp @@ -64,28 +64,18 @@ namespace gmx namespace test { -const EnergyTermsToCompare EnergyComparison::s_defaultEnergyTermsToCompare = -{ - { - interaction_function[F_EPOT].longname, - relativeToleranceAsUlp(10.0, 50) - }, - { - interaction_function[F_EKIN].longname, - relativeToleranceAsUlp(10.0, 50) - }, +const EnergyTermsToCompare EnergyComparison::s_defaultEnergyTermsToCompare = { + { interaction_function[F_EPOT].longname, relativeToleranceAsUlp(10.0, 50) }, + { interaction_function[F_EKIN].longname, relativeToleranceAsUlp(10.0, 50) }, // The pressure is very strongly affected by summation errors, // so we need a large tolerance. // The value of 15000 is calibrated for running a small water box for 16 steps. // For a single frame for a water box a value of 150 could work. - { - interaction_function[F_PRES].longname, - relativeToleranceAsUlp(10.0, 15000) - }, + { interaction_function[F_PRES].longname, relativeToleranceAsUlp(10.0, 15000) }, }; -EnergyComparison::EnergyComparison(const EnergyTermsToCompare &energyTermsToCompare) - : energyTermsToCompare_(energyTermsToCompare) +EnergyComparison::EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare) : + energyTermsToCompare_(energyTermsToCompare) { } @@ -93,27 +83,28 @@ std::vector EnergyComparison::getEnergyNames() const { std::vector keys; keys.reserve(energyTermsToCompare_.size()); - for (const auto &it : energyTermsToCompare_) + for (const auto& it : energyTermsToCompare_) { keys.push_back(it.first); } return keys; } -void EnergyComparison::operator()(const EnergyFrame &reference, - const EnergyFrame &test) const +void EnergyComparison::operator()(const EnergyFrame& reference, const EnergyFrame& test) const { - SCOPED_TRACE("Comparing energy reference frame " + reference.frameName() + " and test frame " + test.frameName()); + SCOPED_TRACE("Comparing energy reference frame " + reference.frameName() + " and test frame " + + test.frameName()); for (auto referenceIt = reference.begin(); referenceIt != reference.end(); ++referenceIt) { - auto &energyName = referenceIt->first; - SCOPED_TRACE("Comparing " + energyName + " between frames"); - auto testIt = test.find(energyName); + auto& energyName = referenceIt->first; + SCOPED_TRACE("Comparing " + energyName + " between frames"); + auto testIt = test.find(energyName); if (testIt != test.end()) { - auto &energyValueInReference = referenceIt->second; - auto &energyValueInTest = testIt->second; - EXPECT_REAL_EQ_TOL(energyValueInReference, energyValueInTest, energyTermsToCompare_.at(energyName)); + auto& energyValueInReference = referenceIt->second; + auto& energyValueInTest = testIt->second; + EXPECT_REAL_EQ_TOL(energyValueInReference, energyValueInTest, + energyTermsToCompare_.at(energyName)); } else { @@ -122,25 +113,23 @@ void EnergyComparison::operator()(const EnergyFrame &reference, } } -void -checkEnergiesAgainstReferenceData(const std::string &energyFilename, - const EnergyTermsToCompare &energyTermsToCompare, - TestReferenceChecker *checker) +void checkEnergiesAgainstReferenceData(const std::string& energyFilename, + const EnergyTermsToCompare& energyTermsToCompare, + TestReferenceChecker* checker) { const bool thisRankChecks = (gmx_node_rank() == 0); if (thisRankChecks) { EnergyComparison energyComparison(energyTermsToCompare); - auto energyReader = openEnergyFileToReadTerms(energyFilename, - energyComparison.getEnergyNames()); + auto energyReader = openEnergyFileToReadTerms(energyFilename, energyComparison.getEnergyNames()); std::unordered_map checkers; - for (const auto &energyTermToCompare : energyTermsToCompare) + for (const auto& energyTermToCompare : energyTermsToCompare) { - const auto &energyName = energyTermToCompare.first; - checkers[energyName] = checker->checkCompound("Energy", energyName.c_str()); - const auto &energyTolerance = energyTermToCompare.second; + const auto& energyName = energyTermToCompare.first; + checkers[energyName] = checker->checkCompound("Energy", energyName.c_str()); + const auto& energyTolerance = energyTermToCompare.second; checkers[energyName].setDefaultTolerance(energyTolerance); } @@ -152,15 +141,15 @@ checkEnergiesAgainstReferenceData(const std::string &energyFilename, int frameNumber = 0; while (energyReader->readNextFrame()) { - const EnergyFrame &frame = energyReader->frame(); + const EnergyFrame& frame = energyReader->frame(); const std::string frameName = frame.frameName() + " in frame " + toString(frameNumber); - for (const auto &energyTermToCompare : energyTermsToCompare) + for (const auto& energyTermToCompare : energyTermsToCompare) { - const std::string &energyName = energyTermToCompare.first; + const std::string& energyName = energyTermToCompare.first; const real energyValue = frame.at(energyName); - SCOPED_TRACE("Comparing " + energyName + " in " + frameName); + SCOPED_TRACE("Comparing " + energyName + " in " + frameName); checkers[energyName].checkReal(energyValue, frameName.c_str()); } ++frameNumber; @@ -172,5 +161,5 @@ checkEnergiesAgainstReferenceData(const std::string &energyFilename, } } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/energycomparison.h b/src/programs/mdrun/tests/energycomparison.h index c0de99746d..980f522371 100644 --- a/src/programs/mdrun/tests/energycomparison.h +++ b/src/programs/mdrun/tests/energycomparison.h @@ -65,32 +65,32 @@ using EnergyTermsToCompare = std::unordered_map getEnergyNames() const; - /*! \brief Compare \c reference with \c test within \c - * energyTermsToCompare_ - * - * Ignore any key found in either \c reference or \c test that is not - * found in the other. For all keys found in both frames, compare the - * values with EXPECT_REAL_EQ_TOL and the given tolerance for that - * key. */ - void operator()(const EnergyFrame &reference, const EnergyFrame &test) const; +public: + //! Defaults for energy comparisons + static const EnergyTermsToCompare s_defaultEnergyTermsToCompare; + //! Constructor + EnergyComparison(const EnergyTermsToCompare& energyTermsToCompare); + /*! \brief Return the names of energies that will be compared + * + * This function can be used to provide an input for + * openEnergyFileToReadTerms(). + * + * \todo This returns a copy of the keys, which is convenient, but + * inefficient. Alternatively, this could return a view of the keys + * from a range rather than a container, but there's no implementation + * of that in C++11 at the moment. */ + std::vector getEnergyNames() const; + /*! \brief Compare \c reference with \c test within \c + * energyTermsToCompare_ + * + * Ignore any key found in either \c reference or \c test that is not + * found in the other. For all keys found in both frames, compare the + * values with EXPECT_REAL_EQ_TOL and the given tolerance for that + * key. */ + void operator()(const EnergyFrame& reference, const EnergyFrame& test) const; - //! Energy terms to match with given tolerances. - EnergyTermsToCompare energyTermsToCompare_; + //! Energy terms to match with given tolerances. + EnergyTermsToCompare energyTermsToCompare_; }; /*! \brief Check a subset of the energies found in an energy file @@ -106,12 +106,11 @@ class EnergyComparison * \todo This is quite similar to the functionality used in PmeTest, * and we should consider reducing the duplication. */ -void -checkEnergiesAgainstReferenceData(const std::string &energyFilename, - const EnergyTermsToCompare &energyTermsToCompare, - TestReferenceChecker *checker); +void checkEnergiesAgainstReferenceData(const std::string& energyFilename, + const EnergyTermsToCompare& energyTermsToCompare, + TestReferenceChecker* checker); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun/tests/energyreader.cpp b/src/programs/mdrun/tests/energyreader.cpp index 7b084b02ca..858051ffa5 100644 --- a/src/programs/mdrun/tests/energyreader.cpp +++ b/src/programs/mdrun/tests/energyreader.cpp @@ -62,9 +62,8 @@ namespace gmx namespace test { -EnergyFrameReaderPtr -openEnergyFileToReadTerms(const std::string &filename, - const std::vector &namesOfRequiredEnergyTerms) +EnergyFrameReaderPtr openEnergyFileToReadTerms(const std::string& filename, + const std::vector& namesOfRequiredEnergyTerms) { ener_file_ptr energyFile(open_enx(filename.c_str(), "r")); @@ -85,16 +84,14 @@ openEnergyFileToReadTerms(const std::string &filename, std::map indicesOfEnergyTerms; { int numEnergyTerms; - gmx_enxnm_t *energyNames = nullptr; + gmx_enxnm_t* energyNames = nullptr; do_enxnms(energyFile.get(), &numEnergyTerms, &energyNames); for (int i = 0; i != numEnergyTerms; ++i) { - const char *name = energyNames[i].name; + const char* name = energyNames[i].name; auto requiredEnergy = std::find_if(std::begin(namesOfRequiredEnergyTerms), - std::end(namesOfRequiredEnergyTerms), - [name](const std::string &n){ - return name == n; - }); + std::end(namesOfRequiredEnergyTerms), + [name](const std::string& n) { return name == n; }); if (requiredEnergy != namesOfRequiredEnergyTerms.end()) { indicesOfEnergyTerms[name] = i; @@ -107,8 +104,9 @@ openEnergyFileToReadTerms(const std::string &filename, // Throw if we failed to find the terms we need if (indicesOfEnergyTerms.size() != namesOfRequiredEnergyTerms.size()) { - std::string requiredEnergiesNotFound = "Did not find the following required energies in mdrun output:\n"; - for (auto &name : namesOfRequiredEnergyTerms) + std::string requiredEnergiesNotFound = + "Did not find the following required energies in mdrun output:\n"; + for (auto& name : namesOfRequiredEnergyTerms) { auto possibleIndex = indicesOfEnergyTerms.find(name); if (possibleIndex == indicesOfEnergyTerms.end()) @@ -119,14 +117,14 @@ openEnergyFileToReadTerms(const std::string &filename, GMX_THROW(APIError(requiredEnergiesNotFound)); } - return EnergyFrameReaderPtr(std::make_unique(indicesOfEnergyTerms, - energyFile.release())); + return EnergyFrameReaderPtr( + std::make_unique(indicesOfEnergyTerms, energyFile.release())); } //! Helper function to obtain resources -static t_enxframe *make_enxframe() +static t_enxframe* make_enxframe() { - t_enxframe *frame; + t_enxframe* frame; snew(frame, 1); init_enxframe(frame); @@ -135,7 +133,7 @@ static t_enxframe *make_enxframe() } //! Helper function to clean up resources -void done_enxframe(t_enxframe *fr) +void done_enxframe(t_enxframe* fr) { // Free the contents, then the pointer itself free_enxframe(fr); @@ -144,28 +142,31 @@ void done_enxframe(t_enxframe *fr) // === EnergyFrameReader === -EnergyFrameReader::EnergyFrameReader(const std::map &indicesOfEnergyTerms, - ener_file *energyFile) - : indicesOfEnergyTerms_(indicesOfEnergyTerms), - energyFileGuard_(energyFile), - enxframeGuard_(make_enxframe()), - haveProbedForNextFrame_(false), - nextFrameExists_(false) +EnergyFrameReader::EnergyFrameReader(const std::map& indicesOfEnergyTerms, + ener_file* energyFile) : + indicesOfEnergyTerms_(indicesOfEnergyTerms), + energyFileGuard_(energyFile), + enxframeGuard_(make_enxframe()), + haveProbedForNextFrame_(false), + nextFrameExists_(false) { } -bool -EnergyFrameReader::readNextFrame() +bool EnergyFrameReader::readNextFrame() { if (haveProbedForNextFrame_) { if (nextFrameExists_) { - GMX_THROW(APIError("This frame has already been probed for, it should be used before probing again.")); + GMX_THROW( + APIError("This frame has already been probed for, it should be used before " + "probing again.")); } else { - GMX_THROW(APIError("This frame has already been probed for, it doesn't exist, so there should not be subsequent attempts to probe for it.")); + GMX_THROW( + APIError("This frame has already been probed for, it doesn't exist, so there " + "should not be subsequent attempts to probe for it.")); } } haveProbedForNextFrame_ = true; @@ -173,8 +174,7 @@ EnergyFrameReader::readNextFrame() return nextFrameExists_ = do_enx(energyFileGuard_.get(), enxframeGuard_.get()); } -EnergyFrame -EnergyFrameReader::frame() +EnergyFrame EnergyFrameReader::frame() { if (!haveProbedForNextFrame_) { @@ -182,7 +182,9 @@ EnergyFrameReader::frame() } if (!nextFrameExists_) { - GMX_THROW(APIError("There is no next frame, so there should have been no attempt to use the data, e.g. by reacting to a call to readNextFrame().")); + GMX_THROW( + APIError("There is no next frame, so there should have been no attempt to use the " + "data, e.g. by reacting to a call to readNextFrame().")); } // Prepare for reading future frames @@ -193,5 +195,5 @@ EnergyFrameReader::frame() return EnergyFrame(*enxframeGuard_.get(), indicesOfEnergyTerms_); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/energyreader.h b/src/programs/mdrun/tests/energyreader.h index 7af3bc20e0..fa8daa9e6f 100644 --- a/src/programs/mdrun/tests/energyreader.h +++ b/src/programs/mdrun/tests/energyreader.h @@ -87,13 +87,13 @@ typedef std::unique_ptr EnergyFrameReaderPtr; * * This function is intended to have the main responsibility for * making EnergyFrameReader objects. */ -EnergyFrameReaderPtr openEnergyFileToReadTerms(const std::string &filename, - const std::vector &requiredEnergyTermNames); +EnergyFrameReaderPtr openEnergyFileToReadTerms(const std::string& filename, + const std::vector& requiredEnergyTermNames); //! Convenience smart pointer typedef typedef unique_cptr ener_file_ptr; //! Helper function to free resources (NB free_enxframe only frees the contents, not the pointer itself) -void done_enxframe(t_enxframe *fr); +void done_enxframe(t_enxframe* fr); //! Convenience smart pointer typedef typedef unique_cptr enxframe_ptr; @@ -102,55 +102,55 @@ typedef unique_cptr enxframe_ptr; * term values read from successive frames of an .edr file. */ class EnergyFrameReader { - public: - /*! \brief Attempt to read the next frame from the energy file. - * - * \return Whether a frame was available to read. - * - * If true is returned, then frame() should be called - * to get access to the data. If false is returned, then no - * further data exists and no further call to - * readNextFrame() or frame() should occur. - * - * \throws APIError if an earlier probe has not been properly handled - * (by calling frame(), or stopping trying to read - * from the file). */ - bool readNextFrame(); - /*! \brief Make an EnergyFrame from the contents of the next frame in the energy file. - * - * If the next frame has not been probed for, then probe for - * it. If no next frame exists, then throw APIError, because - * user code should have called readNextFrame() itself if this - * is possible. (This permits user code to avoid making calls - * to readNextFrame() in a case where it already knows that - * the frame exists.) - * - * \throws APIError if no next frame exists. - * \throws std::bad_alloc when out of memory. */ - EnergyFrame frame(); - /*! \brief Constructor - * - * \param[in] indicesOfEnergyTerms Looks up energy terms by name to get the index into a t_enxframe structure read by the legacy API. - * \param[in] energyFile Open energy file object to manage, and from which to read frames */ - explicit EnergyFrameReader(const std::map &indicesOfEnergyTerms, - ener_file *energyFile); - private: - //! Convert energy term name to its index within a t_enxframe from this file. - std::map indicesOfEnergyTerms_; - //! Owning handle of an open energy file ready to read frames. - const ener_file_ptr energyFileGuard_; - //! Owning handle of contents of .edr file frame after reading. - const enxframe_ptr enxframeGuard_; - //! Whether the API has been used properly (ie. probe before reading). - bool haveProbedForNextFrame_; - //! Whether there has been a probe that found a next frame. - bool nextFrameExists_; - - // Multiple owners of these resources isn't very sensible, so prevent it - GMX_DISALLOW_COPY_AND_ASSIGN(EnergyFrameReader); +public: + /*! \brief Attempt to read the next frame from the energy file. + * + * \return Whether a frame was available to read. + * + * If true is returned, then frame() should be called + * to get access to the data. If false is returned, then no + * further data exists and no further call to + * readNextFrame() or frame() should occur. + * + * \throws APIError if an earlier probe has not been properly handled + * (by calling frame(), or stopping trying to read + * from the file). */ + bool readNextFrame(); + /*! \brief Make an EnergyFrame from the contents of the next frame in the energy file. + * + * If the next frame has not been probed for, then probe for + * it. If no next frame exists, then throw APIError, because + * user code should have called readNextFrame() itself if this + * is possible. (This permits user code to avoid making calls + * to readNextFrame() in a case where it already knows that + * the frame exists.) + * + * \throws APIError if no next frame exists. + * \throws std::bad_alloc when out of memory. */ + EnergyFrame frame(); + /*! \brief Constructor + * + * \param[in] indicesOfEnergyTerms Looks up energy terms by name to get the index into a t_enxframe structure read by the legacy API. + * \param[in] energyFile Open energy file object to manage, and from which to read frames */ + explicit EnergyFrameReader(const std::map& indicesOfEnergyTerms, ener_file* energyFile); + +private: + //! Convert energy term name to its index within a t_enxframe from this file. + std::map indicesOfEnergyTerms_; + //! Owning handle of an open energy file ready to read frames. + const ener_file_ptr energyFileGuard_; + //! Owning handle of contents of .edr file frame after reading. + const enxframe_ptr enxframeGuard_; + //! Whether the API has been used properly (ie. probe before reading). + bool haveProbedForNextFrame_; + //! Whether there has been a probe that found a next frame. + bool nextFrameExists_; + + // Multiple owners of these resources isn't very sensible, so prevent it + GMX_DISALLOW_COPY_AND_ASSIGN(EnergyFrameReader); }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun/tests/exactcontinuation.cpp b/src/programs/mdrun/tests/exactcontinuation.cpp index 1a68fb5309..148e5f72ef 100644 --- a/src/programs/mdrun/tests/exactcontinuation.cpp +++ b/src/programs/mdrun/tests/exactcontinuation.cpp @@ -87,139 +87,142 @@ namespace * * \tparam FrameReader Has readNextFrame() and frame() methods * useful for returning successive Frame objects */ -template +template class ContinuationFramePairManager { - public: - //! Convenience typedef - typedef std::unique_ptr FrameReaderPtr; - //! Constructor - ContinuationFramePairManager(FrameReaderPtr full, - FrameReaderPtr firstPart, - FrameReaderPtr secondPart) : - full_(std::move(full)), - firstPart_(std::move(firstPart)), - secondPart_(std::move(secondPart)), - isFirstPart_(true) - {} - /*! \brief Probe for a pair of valid frames, and return true if both are found. - * - * Gives a test failure if exactly one frame is found, because - * it is an error for either run to have missing or extra - * frames. Note that the frame where the two-part run ends - * and begins is duplicated between the two output files by - * mdrun, and the test accommodates this. - * - * \todo This would be straightforward if velocity Verlet - * behaved like other integrators. */ - bool shouldContinueComparing() +public: + //! Convenience typedef + typedef std::unique_ptr FrameReaderPtr; + //! Constructor + ContinuationFramePairManager(FrameReaderPtr full, FrameReaderPtr firstPart, FrameReaderPtr secondPart) : + full_(std::move(full)), + firstPart_(std::move(firstPart)), + secondPart_(std::move(secondPart)), + isFirstPart_(true) + { + } + /*! \brief Probe for a pair of valid frames, and return true if both are found. + * + * Gives a test failure if exactly one frame is found, because + * it is an error for either run to have missing or extra + * frames. Note that the frame where the two-part run ends + * and begins is duplicated between the two output files by + * mdrun, and the test accommodates this. + * + * \todo This would be straightforward if velocity Verlet + * behaved like other integrators. */ + bool shouldContinueComparing() + { + if (full_->readNextFrame()) { - if (full_->readNextFrame()) + if (isFirstPart_) { - if (isFirstPart_) + if (firstPart_->readNextFrame()) { - if (firstPart_->readNextFrame()) - { - // Two valid next frames exist, so we should continue comparing. - return true; - } - else + // Two valid next frames exist, so we should continue comparing. + return true; + } + else + { + // First part ran out of frames, move on to the second part + isFirstPart_ = false; + if (secondPart_->readNextFrame()) { - // First part ran out of frames, move on to the second part - isFirstPart_ = false; + // Skip a second-part frame so the one we will + // read can compare with the next full-run + // frames. + secondPart_->frame(); if (secondPart_->readNextFrame()) { - // Skip a second-part frame so the one we will - // read can compare with the next full-run - // frames. - secondPart_->frame(); - if (secondPart_->readNextFrame()) - { - // Two valid next frames exist, so we should continue comparing. - return true; - } - else - { - ADD_FAILURE() << "Second-part energy file had no (new) frames"; - } + // Two valid next frames exist, so we should continue comparing. + return true; } else { - ADD_FAILURE() << "Second-part energy file had no frames"; + ADD_FAILURE() << "Second-part energy file had no (new) frames"; } } - } - else - { - if (secondPart_->readNextFrame()) - { - // Two valid next frames exist, so we should continue comparing. - return true; - } else { - ADD_FAILURE() << "Full run energy file had at least one more frame than two-part run energy file"; + ADD_FAILURE() << "Second-part energy file had no frames"; } } } else { - if (isFirstPart_) + if (secondPart_->readNextFrame()) { - ADD_FAILURE() << "Full-run energy file ran out of frames before the first part of the two-part run completed"; + // Two valid next frames exist, so we should continue comparing. + return true; } else { - if (secondPart_->readNextFrame()) - { - ADD_FAILURE() << "Two-part run energy file had at least one more frame than full-run energy file"; - } - else - { - // Both files ran out of frames at the same time, which is the expected behaviour. - } + ADD_FAILURE() << "Full run energy file had at least one more frame than " + "two-part run energy file"; } } - // At least one file is out of frames, so should not continue comparing. - return false; } - /*! \brief Compare all possible pairs of frames using \c compareTwoFrames. - * - * \tparam Frame The type of frame used in the comparison (returned - * by FrameReader and used by compareTwoFrames). */ - template - void compareAllFramePairs(std::function compareTwoFrames) + else { - while (shouldContinueComparing()) + if (isFirstPart_) { - EnergyFrame firstFrame = full_->frame(); - EnergyFrame secondFrame = isFirstPart_ ? firstPart_->frame() : secondPart_->frame(); - SCOPED_TRACE("Comparing frames from two runs '" + firstFrame.frameName() + "' and '" + secondFrame.frameName() + "'"); - compareTwoFrames(firstFrame, secondFrame); + ADD_FAILURE() << "Full-run energy file ran out of frames before the first part of " + "the two-part run completed"; + } + else + { + if (secondPart_->readNextFrame()) + { + ADD_FAILURE() << "Two-part run energy file had at least one more frame than " + "full-run energy file"; + } + else + { + // Both files ran out of frames at the same time, which is the expected behaviour. + } } - } + // At least one file is out of frames, so should not continue comparing. + return false; + } + /*! \brief Compare all possible pairs of frames using \c compareTwoFrames. + * + * \tparam Frame The type of frame used in the comparison (returned + * by FrameReader and used by compareTwoFrames). */ + template + void compareAllFramePairs(std::function compareTwoFrames) + { + while (shouldContinueComparing()) + { + EnergyFrame firstFrame = full_->frame(); + EnergyFrame secondFrame = isFirstPart_ ? firstPart_->frame() : secondPart_->frame(); + SCOPED_TRACE("Comparing frames from two runs '" + firstFrame.frameName() + "' and '" + + secondFrame.frameName() + "'"); + compareTwoFrames(firstFrame, secondFrame); + } + } - private: - EnergyFrameReaderPtr full_; - EnergyFrameReaderPtr firstPart_; - EnergyFrameReaderPtr secondPart_; - bool isFirstPart_; +private: + EnergyFrameReaderPtr full_; + EnergyFrameReaderPtr firstPart_; + EnergyFrameReaderPtr secondPart_; + bool isFirstPart_; }; /*! \brief Run grompp for a normal mdrun, the same mdrun stopping part * way, doing a continuation, and compare the results. */ -void runTest(TestFileManager *fileManager, - SimulationRunner *runner, - const std::string &simulationName, +void runTest(TestFileManager* fileManager, + SimulationRunner* runner, + const std::string& simulationName, int maxWarningsTolerated, - const MdpFieldValues &mdpFieldValues, - const EnergyTermsToCompare &energyTermsToCompare) + const MdpFieldValues& mdpFieldValues, + const EnergyTermsToCompare& energyTermsToCompare) { int numRanksAvailable = getNumberOfTestMpiRanks(); if (!isNumberOfPpRanksSupported(simulationName, numRanksAvailable)) { - fprintf(stdout, "Test system '%s' cannot run with %d ranks.\n" + fprintf(stdout, + "Test system '%s' cannot run with %d ranks.\n" "The supported numbers are: %s\n", simulationName.c_str(), numRanksAvailable, reportNumbersOfPpRanksSupported(simulationName).c_str()); @@ -227,12 +230,12 @@ void runTest(TestFileManager *fileManager, } // prepare some names for files to use with the two mdrun calls - std::string fullRunTprFileName = fileManager->getTemporaryFilePath("full.tpr"); - std::string firstPartRunTprFileName = fileManager->getTemporaryFilePath("firstpart.tpr"); - std::string fullRunEdrFileName = fileManager->getTemporaryFilePath("full.edr"); - std::string firstPartRunEdrFileName = fileManager->getTemporaryFilePath("firstpart.edr"); - std::string firstPartRunCheckpointFileName = fileManager->getTemporaryFilePath("firstpart.cpt"); - std::string secondPartRunEdrFileName = fileManager->getTemporaryFilePath("secondpart"); + std::string fullRunTprFileName = fileManager->getTemporaryFilePath("full.tpr"); + std::string firstPartRunTprFileName = fileManager->getTemporaryFilePath("firstpart.tpr"); + std::string fullRunEdrFileName = fileManager->getTemporaryFilePath("full.edr"); + std::string firstPartRunEdrFileName = fileManager->getTemporaryFilePath("firstpart.edr"); + std::string firstPartRunCheckpointFileName = fileManager->getTemporaryFilePath("firstpart.cpt"); + std::string secondPartRunEdrFileName = fileManager->getTemporaryFilePath("secondpart"); // prepare the full run .tpr file, which will be used for the full // run, and for the second part of the two-part run. @@ -256,7 +259,7 @@ void runTest(TestFileManager *fileManager, caller.append("grompp"); caller.addOption("-maxwarn", maxWarningsTolerated); runner->useTopGroAndNdxFromDatabase(simulationName); - auto firstPartMdpFieldValues = mdpFieldValues; + auto firstPartMdpFieldValues = mdpFieldValues; firstPartMdpFieldValues["nsteps"] = "8"; runner->useStringAsMdpFile(prepareMdpFileContents(firstPartMdpFieldValues)); runner->tprFileName_ = firstPartRunTprFileName; @@ -307,10 +310,10 @@ void runTest(TestFileManager *fileManager, // TODO Here is an unnecessary copy of keys (ie. the energy term // names), for convenience. In the future, use a range. auto namesOfEnergiesToMatch = energyComparison.getEnergyNames(); - ContinuationFramePairManager - energyManager(openEnergyFileToReadTerms(fullRunEdrFileName, namesOfEnergiesToMatch), - openEnergyFileToReadTerms(firstPartRunEdrFileName, namesOfEnergiesToMatch), - openEnergyFileToReadTerms(secondPartRunEdrFileName, namesOfEnergiesToMatch)); + ContinuationFramePairManager energyManager( + openEnergyFileToReadTerms(fullRunEdrFileName, namesOfEnergiesToMatch), + openEnergyFileToReadTerms(firstPartRunEdrFileName, namesOfEnergiesToMatch), + openEnergyFileToReadTerms(secondPartRunEdrFileName, namesOfEnergiesToMatch)); // Compare the energy frames. energyManager.compareAllFramePairs(energyComparison); } @@ -326,13 +329,13 @@ void runTest(TestFileManager *fileManager, * without it? * * \todo Add FEP case. */ -class MdrunNoAppendContinuationIsExact : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string, std::string, std::string >> +class MdrunNoAppendContinuationIsExact : + public MdrunTestFixture, + public ::testing::WithParamInterface> { - public: - //! Constructor - MdrunNoAppendContinuationIsExact() {} +public: + //! Constructor + MdrunNoAppendContinuationIsExact() {} }; /* Listing all of these is tedious, but there's no other way to get a @@ -351,14 +354,13 @@ TEST_P(MdrunNoAppendContinuationIsExact, WithinTolerances) auto integrator = std::get<1>(params); auto temperatureCoupling = std::get<2>(params); auto pressureCoupling = std::get<3>(params); - SCOPED_TRACE(formatString("Comparing normal and two-part run of simulation '%s' " - "with integrator '%s'", - simulationName.c_str(), integrator.c_str())); - - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - temperatureCoupling.c_str(), - pressureCoupling.c_str()); + SCOPED_TRACE( + formatString("Comparing normal and two-part run of simulation '%s' " + "with integrator '%s'", + simulationName.c_str(), integrator.c_str())); + + auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), + temperatureCoupling.c_str(), pressureCoupling.c_str()); // The exact lambda state choice is unimportant, so long as there // is one when using an FEP input. mdpFieldValues["other"] += formatString("\ninit-lambda-state = %d", 3); @@ -370,18 +372,12 @@ TEST_P(MdrunNoAppendContinuationIsExact, WithinTolerances) // with forces on CPUs, but there is no real risk of a bug with // those propagators that would only be caught with a tighter // tolerance in this particular test. - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, - relativeToleranceAsPrecisionDependentUlp(10.0, 32, 64) - }, - }}; + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 32, 64) }, + } }; int numWarningsToTolerate = 1; - runTest(&fileManager_, &runner_, - simulationName, - numWarningsToTolerate, mdpFieldValues, + runTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues, energyTermsToCompare); } @@ -390,53 +386,64 @@ TEST_P(MdrunNoAppendContinuationIsExact, WithinTolerances) // tests can run in such configurations. #if GMX_GPU != GMX_GPU_OPENCL -INSTANTIATE_TEST_CASE_P(NormalIntegrators, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12", "spc2", "alanine_vsite_vacuo"), - ::testing::Values("md", "md-vv", "bd", "sd"), - ::testing::Values("no"), - ::testing::Values("no"))); - -INSTANTIATE_TEST_CASE_P(NormalIntegratorsWithFEP, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("nonanol_vacuo"), - ::testing::Values("md", "md-vv", "bd", "sd"), - ::testing::Values("no"), - ::testing::Values("no"))); - -INSTANTIATE_TEST_CASE_P(NormalNVT, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md", "md-vv"), - ::testing::Values("berendsen", "v-rescale", "nose-hoover"), - ::testing::Values("no"))); - -INSTANTIATE_TEST_CASE_P(LeapfrogNPH, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md"), - ::testing::Values("no"), - ::testing::Values("berendsen", "parrinello-rahman"))); - -INSTANTIATE_TEST_CASE_P(LeapfrogNPT, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md"), - ::testing::Values("berendsen", "v-rescale", "nose-hoover"), - ::testing::Values("berendsen", "parrinello-rahman"))); - -INSTANTIATE_TEST_CASE_P(VelocityVerletNPH, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md-vv"), - ::testing::Values("no"), - ::testing::Values("berendsen"))); - -INSTANTIATE_TEST_CASE_P(VelocityVerletNPT, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md-vv"), - ::testing::Values("v-rescale"), - ::testing::Values("berendsen"))); - -INSTANTIATE_TEST_CASE_P(MTTK, MdrunNoAppendContinuationIsExact, - ::testing::Combine(::testing::Values("argon12"), - ::testing::Values("md-vv"), - ::testing::Values("nose-hoover"), - ::testing::Values("mttk"))); +INSTANTIATE_TEST_CASE_P( + NormalIntegrators, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12", "spc2", "alanine_vsite_vacuo"), + ::testing::Values("md", "md-vv", "bd", "sd"), + ::testing::Values("no"), + ::testing::Values("no"))); + +INSTANTIATE_TEST_CASE_P(NormalIntegratorsWithFEP, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("nonanol_vacuo"), + ::testing::Values("md", "md-vv", "bd", "sd"), + ::testing::Values("no"), + ::testing::Values("no"))); + +INSTANTIATE_TEST_CASE_P( + NormalNVT, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md", "md-vv"), + ::testing::Values("berendsen", "v-rescale", "nose-hoover"), + ::testing::Values("no"))); + +INSTANTIATE_TEST_CASE_P(LeapfrogNPH, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md"), + ::testing::Values("no"), + ::testing::Values("berendsen", "parrinello-rahman"))); + +INSTANTIATE_TEST_CASE_P( + LeapfrogNPT, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md"), + ::testing::Values("berendsen", "v-rescale", "nose-hoover"), + ::testing::Values("berendsen", "parrinello-rahman"))); + +INSTANTIATE_TEST_CASE_P(VelocityVerletNPH, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md-vv"), + ::testing::Values("no"), + ::testing::Values("berendsen"))); + +INSTANTIATE_TEST_CASE_P(VelocityVerletNPT, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md-vv"), + ::testing::Values("v-rescale"), + ::testing::Values("berendsen"))); + +INSTANTIATE_TEST_CASE_P(MTTK, + MdrunNoAppendContinuationIsExact, + ::testing::Combine(::testing::Values("argon12"), + ::testing::Values("md-vv"), + ::testing::Values("nose-hoover"), + ::testing::Values("mttk"))); #endif diff --git a/src/programs/mdrun/tests/grompp.cpp b/src/programs/mdrun/tests/grompp.cpp index ae14fa5326..ab3003fbde 100644 --- a/src/programs/mdrun/tests/grompp.cpp +++ b/src/programs/mdrun/tests/grompp.cpp @@ -54,16 +54,15 @@ namespace { //! Test fixture for grompp -class GromppTest : - public gmx::test::MdrunTestFixture +class GromppTest : public gmx::test::MdrunTestFixture { - public: - //! Execute the trajectory writing test - void runTest() - { - runner_.useTopGroAndNdxFromDatabase("spc-and-methanol"); - EXPECT_EQ(0, runner_.callGrompp()); - } +public: + //! Execute the trajectory writing test + void runTest() + { + runner_.useTopGroAndNdxFromDatabase("spc-and-methanol"); + EXPECT_EQ(0, runner_.callGrompp()); + } }; /* This test ensures that an empty .mdp file (ie. all default values) works. */ @@ -76,24 +75,24 @@ TEST_F(GromppTest, EmptyMdpFileWorks) /* Test for making sure grompp can handle simulated annealing data */ TEST_F(GromppTest, SimulatedAnnealingWorks) { - runner_.useStringAsMdpFile("annealing = periodic\n" - "annealing-npoints = 4\n" - "annealing-time = 0 2 4 6\n" - "annealing-temp = 298 320 320 298\n" - ); + runner_.useStringAsMdpFile( + "annealing = periodic\n" + "annealing-npoints = 4\n" + "annealing-time = 0 2 4 6\n" + "annealing-temp = 298 320 320 298\n"); runTest(); } TEST_F(GromppTest, SimulatedAnnealingWorksWithMultipleGroups) { - runner_.useStringAsMdpFile("tc-grps = Methanol SOL\n" - "tau-t = 0.1 0.1\n" - "ref_t = 298 298\n" - "annealing = single periodic\n" - "annealing-npoints = 3 4\n" - "annealing-time = 0 3 6 0 2 4 6\n" - "annealing-temp = 298 280 270 298 320 320 298\n" - ); + runner_.useStringAsMdpFile( + "tc-grps = Methanol SOL\n" + "tau-t = 0.1 0.1\n" + "ref_t = 298 298\n" + "annealing = single periodic\n" + "annealing-npoints = 3 4\n" + "annealing-time = 0 3 6 0 2 4 6\n" + "annealing-temp = 298 280 270 298 320 320 298\n"); runTest(); } diff --git a/src/programs/mdrun/tests/helpwriting.cpp b/src/programs/mdrun/tests/helpwriting.cpp index a8ee35becf..8f408c1ccf 100644 --- a/src/programs/mdrun/tests/helpwriting.cpp +++ b/src/programs/mdrun/tests/helpwriting.cpp @@ -66,11 +66,8 @@ TEST(MdrunTest, WritesHelp) // like mdrun call parse_common_args, which recognizes the // existence of a global help context. That context triggers the // writing of help and a fast exit of the tool. - HelpLinks *links = nullptr; - CommandLineHelpContext context(&writer, - eHelpOutputFormat_Console, - links, - "dummy"); + HelpLinks* links = nullptr; + CommandLineHelpContext context(&writer, eHelpOutputFormat_Console, links, "dummy"); GlobalCommandLineHelpContext global(context); // Call mdrun to get the help printed to the stream @@ -85,6 +82,6 @@ TEST(MdrunTest, WritesHelp) checker.checkString(outputStream.toString(), "Help string"); }; -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/initialconstraints.cpp b/src/programs/mdrun/tests/initialconstraints.cpp index ab9f27f76d..d4ae76ae5b 100644 --- a/src/programs/mdrun/tests/initialconstraints.cpp +++ b/src/programs/mdrun/tests/initialconstraints.cpp @@ -63,11 +63,12 @@ namespace { //! This type holds input integrators. Now it's holding names, but ei* enum values from md_enums.h could be used instead. -using EnergyIntegratorType = const char *; +using EnergyIntegratorType = const char*; //! Test fixture parametrized on integrators -class InitialConstraintsTest : public gmx::test::MdrunTestFixture, - public ::testing::WithParamInterface +class InitialConstraintsTest : + public gmx::test::MdrunTestFixture, + public ::testing::WithParamInterface { }; @@ -78,19 +79,20 @@ TEST_P(InitialConstraintsTest, Works) auto integrator = GetParam(); const std::string integratorName(integrator); SCOPED_TRACE("Integrating with " + integratorName); - const std::string theMdpFile = formatString("nstcalcenergy = 1\n" - "nstenergy = 1\n" - "comm-mode = linear\n" - "continuation = no\n" - "constraints = h-bonds\n" - "lincs_iter = 2\n" - "verlet-buffer-tolerance = 1e-4\n" - "nsttcouple = 1\n" // for md-vv-avek - "nstpcouple = 1\n" // for md-vv-avek - "integrator = %s\n" - "nsteps = %d\n" - "dt = %f\n", - integratorName.c_str(), nsteps, timestep); + const std::string theMdpFile = formatString( + "nstcalcenergy = 1\n" + "nstenergy = 1\n" + "comm-mode = linear\n" + "continuation = no\n" + "constraints = h-bonds\n" + "lincs_iter = 2\n" + "verlet-buffer-tolerance = 1e-4\n" + "nsttcouple = 1\n" // for md-vv-avek + "nstpcouple = 1\n" // for md-vv-avek + "integrator = %s\n" + "nsteps = %d\n" + "dt = %f\n", + integratorName.c_str(), nsteps, timestep); runner_.useStringAsMdpFile(theMdpFile); @@ -101,14 +103,15 @@ TEST_P(InitialConstraintsTest, Works) runner_.edrFileName_ = fileManager_.getTemporaryFilePath(inputFile + ".edr"); ASSERT_EQ(0, runner_.callMdrun()); - auto energyReader = openEnergyFileToReadTerms(runner_.edrFileName_, {"Total Energy", "Kinetic En."}); - real totalEnergy = 0.0, prevTotalEnergy = 0.0; - auto tolerance = ulpTolerance(0); // The real value is set below from starting kinetic energy + auto energyReader = + openEnergyFileToReadTerms(runner_.edrFileName_, { "Total Energy", "Kinetic En." }); + real totalEnergy = 0.0, prevTotalEnergy = 0.0; + auto tolerance = ulpTolerance(0); // The real value is set below from starting kinetic energy for (int i = 0; i <= nsteps; i++) { EnergyFrame frame = energyReader->frame(); - prevTotalEnergy = totalEnergy; - totalEnergy = frame.at("Total Energy"); + prevTotalEnergy = totalEnergy; + totalEnergy = frame.at("Total Energy"); if (i == 0) { // We set the tolerance for total energy based on magnitude of kinetic energy. @@ -124,10 +127,10 @@ TEST_P(InitialConstraintsTest, Works) } //! Integrators with energy conservation to test -const EnergyIntegratorType c_integratorsToTest [] = {"md", "md-vv", "md-vv-avek"}; +const EnergyIntegratorType c_integratorsToTest[] = { "md", "md-vv", "md-vv-avek" }; INSTANTIATE_TEST_CASE_P(Checking, InitialConstraintsTest, ::testing::ValuesIn(c_integratorsToTest)); -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/interactiveMD.cpp b/src/programs/mdrun/tests/interactiveMD.cpp index 72456015c9..e2e94fafae 100644 --- a/src/programs/mdrun/tests/interactiveMD.cpp +++ b/src/programs/mdrun/tests/interactiveMD.cpp @@ -51,22 +51,17 @@ namespace gmx namespace test { -class ImdTestFixture : public MdrunTestFixture, - public ::testing::WithParamInterface +class ImdTestFixture : public MdrunTestFixture, public ::testing::WithParamInterface { - protected: - ImdTestFixture(); - ~ImdTestFixture() override; +protected: + ImdTestFixture(); + ~ImdTestFixture() override; }; -ImdTestFixture::ImdTestFixture() -{ -} +ImdTestFixture::ImdTestFixture() {} -ImdTestFixture::~ImdTestFixture() -{ -} +ImdTestFixture::~ImdTestFixture() {} //! Test fixture for mdrun with IMD settings @@ -104,7 +99,7 @@ TEST_P(ImdTest, ImdCanRun) ::gmx::test::CommandLine imdCaller; imdCaller.addOption("-imdport", 0); // automatically assign a free port imdCaller.append("-imdpull"); - imdCaller.append("-noimdwait"); // cannot use -imdwait: then mdrun would not return control ... + imdCaller.append("-noimdwait"); // cannot use -imdwait: then mdrun would not return control ... imdCaller.append("-noimdterm"); // Do an mdrun with IMD enabled @@ -113,8 +108,7 @@ TEST_P(ImdTest, ImdCanRun) // Check a dynamical integrator and an energy minimizer. No need to // cover the whole space. -INSTANTIATE_TEST_CASE_P(WithIntegrator, ImdTest, - ::testing::Values("md", "steep")); +INSTANTIATE_TEST_CASE_P(WithIntegrator, ImdTest, ::testing::Values("md", "steep")); } // namespace test } // namespace gmx diff --git a/src/programs/mdrun/tests/mdmodulenotification.cpp b/src/programs/mdrun/tests/mdmodulenotification.cpp index 325a8e76a5..a2a32ecc83 100644 --- a/src/programs/mdrun/tests/mdmodulenotification.cpp +++ b/src/programs/mdrun/tests/mdmodulenotification.cpp @@ -51,80 +51,72 @@ namespace gmx namespace { -struct EventA{}; -struct EventB{}; +struct EventA +{ +}; +struct EventB +{ +}; class EventACallee final { - public: - void callback(EventA /*a*/) - { - notifiedEventA_ = true; - }; +public: + void callback(EventA /*a*/) { notifiedEventA_ = true; }; - bool notifiedEventA() { return notifiedEventA_; } + bool notifiedEventA() { return notifiedEventA_; } - private: - bool notifiedEventA_ = false; +private: + bool notifiedEventA_ = false; }; class EventBCallee final { - public: - void callback(EventB * /* bPointer */) - { - notifiedEventB_ = true; - }; +public: + void callback(EventB* /* bPointer */) { notifiedEventB_ = true; }; - bool notifiedEventB() { return notifiedEventB_; } + bool notifiedEventB() { return notifiedEventB_; } - private: - bool notifiedEventB_ = false; +private: + bool notifiedEventB_ = false; }; class EventAandBCallee final { - public: - void notify(EventB * /* bPointer */) - { - notifiedEventB_ = true; - }; - - void callback(EventA /* a */) - { - notifiedEventA_ = true; - }; - - bool notifiedEventB() { return notifiedEventB_; } - bool notifiedEventA() { return notifiedEventA_; } - - private: - bool notifiedEventB_ = false; - bool notifiedEventA_ = false; +public: + void notify(EventB* /* bPointer */) { notifiedEventB_ = true; }; + + void callback(EventA /* a */) { notifiedEventA_ = true; }; + + bool notifiedEventB() { return notifiedEventB_; } + bool notifiedEventA() { return notifiedEventA_; } + +private: + bool notifiedEventB_ = false; + bool notifiedEventA_ = false; }; TEST(MDModuleNotificationTest, addConsumer) { registerMdModuleNotification::type notifications; - EventACallee eventACallee; + EventACallee eventACallee; EXPECT_FALSE(eventACallee.notifiedEventA()); notifications.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); - notifications.notify(EventA {}); + notifications.notify(EventA{}); EXPECT_TRUE(eventACallee.notifiedEventA()); } TEST(MDModuleNotificationTest, addConsumerWithPointerParameter) { - registerMdModuleNotification::type notifications; - EventBCallee eventBCallee; + registerMdModuleNotification::type notifications; + EventBCallee eventBCallee; EXPECT_FALSE(eventBCallee.notifiedEventB()); - notifications.subscribe([&eventBCallee](EventB * eventB) { eventBCallee.callback(eventB); }); - EventB * eventBPointer = nullptr; + notifications.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); + EventB* eventBPointer = nullptr; notifications.notify(eventBPointer); EXPECT_TRUE(eventBCallee.notifiedEventB()); @@ -132,23 +124,23 @@ TEST(MDModuleNotificationTest, addConsumerWithPointerParameter) TEST(MDModuleNotificationTest, addTwoDifferentConsumers) { - registerMdModuleNotification::type notifications; - EventBCallee eventBCallee; - EventACallee eventACallee; + registerMdModuleNotification::type notifications; + EventBCallee eventBCallee; + EventACallee eventACallee; EXPECT_FALSE(eventACallee.notifiedEventA()); EXPECT_FALSE(eventBCallee.notifiedEventB()); - notifications.subscribe([&eventBCallee](EventB *eventB) { eventBCallee.callback(eventB); }); + notifications.subscribe([&eventBCallee](EventB* eventB) { eventBCallee.callback(eventB); }); notifications.subscribe([&eventACallee](EventA eventA) { eventACallee.callback(eventA); }); - EventB * eventBPointer = nullptr; + EventB* eventBPointer = nullptr; notifications.notify(eventBPointer); EXPECT_FALSE(eventACallee.notifiedEventA()); EXPECT_TRUE(eventBCallee.notifiedEventB()); - notifications.notify(EventA {}); + notifications.notify(EventA{}); EXPECT_TRUE(eventACallee.notifiedEventA()); EXPECT_TRUE(eventBCallee.notifiedEventB()); @@ -156,25 +148,25 @@ TEST(MDModuleNotificationTest, addTwoDifferentConsumers) TEST(MDModuleNotificationTest, consumerOfTwoResources) { - registerMdModuleNotification::type notifications; + registerMdModuleNotification::type notifications; - EventAandBCallee callee; + EventAandBCallee callee; EXPECT_FALSE(callee.notifiedEventB()); EXPECT_FALSE(callee.notifiedEventA()); // requires a template parameter here, because call is ambiguous otherwise notifications.subscribe([&callee](EventA msg) { callee.callback(msg); }); - notifications.subscribe([&callee](EventB *msg) { callee.notify(msg); }); + notifications.subscribe([&callee](EventB* msg) { callee.notify(msg); }); - EventB * eventBp = nullptr; + EventB* eventBp = nullptr; notifications.notify(eventBp); EXPECT_FALSE(callee.notifiedEventA()); EXPECT_TRUE(callee.notifiedEventB()); - notifications.notify(EventA {}); + notifications.notify(EventA{}); EXPECT_TRUE(callee.notifiedEventA()); EXPECT_TRUE(callee.notifiedEventB()); diff --git a/src/programs/mdrun/tests/mdruncomparison.h b/src/programs/mdrun/tests/mdruncomparison.h index 323822454a..58809a1f54 100644 --- a/src/programs/mdrun/tests/mdruncomparison.h +++ b/src/programs/mdrun/tests/mdruncomparison.h @@ -61,72 +61,75 @@ namespace test * * \tparam FrameReader Has readNextFrame() and frame() methods * useful for returning successive Frame objects */ -template +template class FramePairManager { - public: - //! Convenience typedef - typedef std::unique_ptr FrameReaderPtr; - //! Constructor - FramePairManager(FrameReaderPtr first, - FrameReaderPtr second) : - first_(std::move(first)), - second_(std::move(second)) - {} - private: - /*! \brief Probe for a pair of valid frames, and return true if both are found. - * - * Give a test failure if exactly one frame is found, because - * that file is longer than the other one, and this is not - * expected behaviour. */ - bool shouldContinueComparing() +public: + //! Convenience typedef + typedef std::unique_ptr FrameReaderPtr; + //! Constructor + FramePairManager(FrameReaderPtr first, FrameReaderPtr second) : + first_(std::move(first)), + second_(std::move(second)) + { + } + +private: + /*! \brief Probe for a pair of valid frames, and return true if both are found. + * + * Give a test failure if exactly one frame is found, because + * that file is longer than the other one, and this is not + * expected behaviour. */ + bool shouldContinueComparing() + { + if (first_->readNextFrame()) { - if (first_->readNextFrame()) + if (second_->readNextFrame()) { - if (second_->readNextFrame()) - { - // Two valid next frames exist, so we should continue comparing. - return true; - } - else - { - ADD_FAILURE() << "first file had at least one more frame than second file"; - } + // Two valid next frames exist, so we should continue comparing. + return true; } else { - if (second_->readNextFrame()) - { - ADD_FAILURE() << "second file had at least one more frame than first file"; - } - else - { - // Both files ran out of frames at the same time, which is the expected behaviour. - } + ADD_FAILURE() << "first file had at least one more frame than second file"; } - // At least one file is out of frames, so should not continue comparing. - return false; } - public: - /*! \brief Compare all possible pairs of frames using \c compareTwoFrames. - * - * \tparam Frame The type of frame used in the comparison (returned - * by FrameReader and used by compareTwoFrames). */ - template - void compareAllFramePairs(std::function compareTwoFrames) + else { - while (shouldContinueComparing()) + if (second_->readNextFrame()) + { + ADD_FAILURE() << "second file had at least one more frame than first file"; + } + else { - Frame firstFrame = first_->frame(); - Frame secondFrame = second_->frame(); - SCOPED_TRACE("Comparing frames from two runs '" + firstFrame.frameName() + "' and '" + secondFrame.frameName() + "'"); - compareTwoFrames(firstFrame, secondFrame); + // Both files ran out of frames at the same time, which is the expected behaviour. } + } + // At least one file is out of frames, so should not continue comparing. + return false; + } +public: + /*! \brief Compare all possible pairs of frames using \c compareTwoFrames. + * + * \tparam Frame The type of frame used in the comparison (returned + * by FrameReader and used by compareTwoFrames). */ + template + void compareAllFramePairs(std::function compareTwoFrames) + { + while (shouldContinueComparing()) + { + Frame firstFrame = first_->frame(); + Frame secondFrame = second_->frame(); + SCOPED_TRACE("Comparing frames from two runs '" + firstFrame.frameName() + "' and '" + + secondFrame.frameName() + "'"); + compareTwoFrames(firstFrame, secondFrame); } - private: - FrameReaderPtr first_; - FrameReaderPtr second_; + } + +private: + FrameReaderPtr first_; + FrameReaderPtr second_; }; } // namespace test diff --git a/src/programs/mdrun/tests/mimic.cpp b/src/programs/mdrun/tests/mimic.cpp index f87695e8fd..244a98a25f 100644 --- a/src/programs/mdrun/tests/mimic.cpp +++ b/src/programs/mdrun/tests/mimic.cpp @@ -65,41 +65,37 @@ namespace test //! Test fixture for bonded interactions class MimicTest : public gmx::test::MdrunTestFixture { - public: - //! Execute the trajectory writing test - void setupGrompp(const char *index_file, const char *top_file, const char *gro_file) - { - runner_.topFileName_ = TestFileManager::getInputFilePath(top_file); - runner_.groFileName_ = TestFileManager::getInputFilePath(gro_file); - runner_.ndxFileName_ = TestFileManager::getInputFilePath(index_file); - runner_.useStringAsMdpFile("integrator = mimic\n" - "QMMM-grps = QMatoms"); - } - //! Prepare an mdrun caller - CommandLine setupRerun() - { - CommandLine rerunCaller; - rerunCaller.append("mdrun"); - rerunCaller.addOption("-rerun", runner_.groFileName_); - runner_.edrFileName_ = fileManager_.getTemporaryFilePath(".edr"); - return rerunCaller; - } - //! Check the output of mdrun - void checkRerun() - { - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, relativeToleranceAsFloatingPoint(-20.1, 1e-4) - }, - }}; - - TestReferenceData refData; - auto checker = refData.rootChecker(); - checkEnergiesAgainstReferenceData(runner_.edrFileName_, - energyTermsToCompare, - &checker); - } +public: + //! Execute the trajectory writing test + void setupGrompp(const char* index_file, const char* top_file, const char* gro_file) + { + runner_.topFileName_ = TestFileManager::getInputFilePath(top_file); + runner_.groFileName_ = TestFileManager::getInputFilePath(gro_file); + runner_.ndxFileName_ = TestFileManager::getInputFilePath(index_file); + runner_.useStringAsMdpFile( + "integrator = mimic\n" + "QMMM-grps = QMatoms"); + } + //! Prepare an mdrun caller + CommandLine setupRerun() + { + CommandLine rerunCaller; + rerunCaller.append("mdrun"); + rerunCaller.addOption("-rerun", runner_.groFileName_); + runner_.edrFileName_ = fileManager_.getTemporaryFilePath(".edr"); + return rerunCaller; + } + //! Check the output of mdrun + void checkRerun() + { + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, relativeToleranceAsFloatingPoint(-20.1, 1e-4) }, + } }; + + TestReferenceData refData; + auto checker = refData.rootChecker(); + checkEnergiesAgainstReferenceData(runner_.edrFileName_, energyTermsToCompare, &checker); + } }; // This test checks if the energies produced with one quantum molecule are reasonable diff --git a/src/programs/mdrun/tests/minimize.cpp b/src/programs/mdrun/tests/minimize.cpp index 9d40358c2a..1a0077c960 100644 --- a/src/programs/mdrun/tests/minimize.cpp +++ b/src/programs/mdrun/tests/minimize.cpp @@ -80,36 +80,20 @@ namespace * a reproducible final energy. * * The choices for tolerance are arbitrary but sufficient. */ -class EnergyMinimizationTest : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string>> +class EnergyMinimizationTest : + public MdrunTestFixture, + public ::testing::WithParamInterface> { }; /*! \brief Database of empirical tolerances for EM integrators on the various systems. */ -std::unordered_map potentialEnergyToleranceForSystem_g = -{{ - { - "argon12", - relativeToleranceAsPrecisionDependentUlp(-1, 10, 200) - }, - { - "tip3p5", - relativeToleranceAsPrecisionDependentUlp(-50, 200, 3800) - }, - { - "glycine_vacuo", - relativeToleranceAsPrecisionDependentUlp(1000, 100, 100) - }, - { - "alanine_vsite_vacuo", - relativeToleranceAsPrecisionDependentUlp(-160, 150, 400) - }, - { - "glycine_no_constraints_vacuo", - relativeToleranceAsPrecisionDependentUlp(2000, 100, 100) - } - }}; +std::unordered_map potentialEnergyToleranceForSystem_g = { + { { "argon12", relativeToleranceAsPrecisionDependentUlp(-1, 10, 200) }, + { "tip3p5", relativeToleranceAsPrecisionDependentUlp(-50, 200, 3800) }, + { "glycine_vacuo", relativeToleranceAsPrecisionDependentUlp(1000, 100, 100) }, + { "alanine_vsite_vacuo", relativeToleranceAsPrecisionDependentUlp(-160, 150, 400) }, + { "glycine_no_constraints_vacuo", relativeToleranceAsPrecisionDependentUlp(2000, 100, 100) } } +}; TEST_P(EnergyMinimizationTest, WithinTolerances) { @@ -123,16 +107,16 @@ TEST_P(EnergyMinimizationTest, WithinTolerances) int numRanksAvailable = getNumberOfTestMpiRanks(); if (!isNumberOfPpRanksSupported(simulationName, numRanksAvailable)) { - fprintf(stdout, "Test system '%s' cannot run with %d ranks.\n" + fprintf(stdout, + "Test system '%s' cannot run with %d ranks.\n" "The supported numbers are: %s\n", simulationName.c_str(), numRanksAvailable, reportNumbersOfPpRanksSupported(simulationName).c_str()); return; } - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - minimizer.c_str(), - "no", "no"); + auto mdpFieldValues = + prepareMdpFieldValues(simulationName.c_str(), minimizer.c_str(), "no", "no"); mdpFieldValues["nsteps"] = "4"; int maxWarningsTolerated = (minimizer == "l-bfgs") ? 1 : 0; @@ -157,7 +141,7 @@ TEST_P(EnergyMinimizationTest, WithinTolerances) { // Ideally we would use this death test, but it is not // stable enough in Jenkins, so we just skip it. - //EXPECT_DEATH_IF_SUPPORTED(runner_.callMdrun(mdrunCaller), + // EXPECT_DEATH_IF_SUPPORTED(runner_.callMdrun(mdrunCaller), // "L-BFGS minimization only supports a single rank"); return; } @@ -167,28 +151,25 @@ TEST_P(EnergyMinimizationTest, WithinTolerances) } } - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, potentialEnergyToleranceForSystem_g.at(simulationName) - }, - }}; + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, potentialEnergyToleranceForSystem_g.at(simulationName) }, + } }; TestReferenceData refData; auto checker = refData.rootChecker() - .checkCompound("Simulation", simulationName) - .checkCompound("Minimizer", minimizer); - checkEnergiesAgainstReferenceData(runner_.edrFileName_, - energyTermsToCompare, - &checker); + .checkCompound("Simulation", simulationName) + .checkCompound("Minimizer", minimizer); + checkEnergiesAgainstReferenceData(runner_.edrFileName_, energyTermsToCompare, &checker); } //! Containers of systems and integrators to test. //! \{ -std::vector unconstrainedSystemsToTest_g = { "argon12", "glycine_no_constraints_vacuo" }; +std::vector unconstrainedSystemsToTest_g = { "argon12", + "glycine_no_constraints_vacuo" }; std::vector minimizersToTest_g = { "steep", "cg", "l-bfgs" }; -std::vector constrainedSystemsToTest_g = { "tip3p5", "glycine_vacuo", "alanine_vsite_vacuo" }; +std::vector constrainedSystemsToTest_g = { "tip3p5", "glycine_vacuo", + "alanine_vsite_vacuo" }; std::vector minimizersToTestWithConstraints_g = { "steep", "cg" }; //! \} @@ -197,12 +178,14 @@ std::vector minimizersToTestWithConstraints_g = { "steep", "cg" }; // OpenCL builds. However, once that compilation is cached for the // lifetime of the whole test binary process, these tests should run in // such configurations. -INSTANTIATE_TEST_CASE_P(MinimizersWorkWithConstraints, EnergyMinimizationTest, - ::testing::Combine(::testing::ValuesIn(constrainedSystemsToTest_g), - ::testing::ValuesIn(minimizersToTestWithConstraints_g))); -INSTANTIATE_TEST_CASE_P(MinimizersWork, EnergyMinimizationTest, - ::testing::Combine(::testing::ValuesIn(unconstrainedSystemsToTest_g), - ::testing::ValuesIn(minimizersToTest_g))); +INSTANTIATE_TEST_CASE_P(MinimizersWorkWithConstraints, + EnergyMinimizationTest, + ::testing::Combine(::testing::ValuesIn(constrainedSystemsToTest_g), + ::testing::ValuesIn(minimizersToTestWithConstraints_g))); +INSTANTIATE_TEST_CASE_P(MinimizersWork, + EnergyMinimizationTest, + ::testing::Combine(::testing::ValuesIn(unconstrainedSystemsToTest_g), + ::testing::ValuesIn(minimizersToTest_g))); } // namespace } // namespace test diff --git a/src/programs/mdrun/tests/moduletest.cpp b/src/programs/mdrun/tests/moduletest.cpp index c4a59ca751..4447ae8f07 100644 --- a/src/programs/mdrun/tests/moduletest.cpp +++ b/src/programs/mdrun/tests/moduletest.cpp @@ -85,15 +85,15 @@ GMX_TEST_OPTIONS(MdrunTestOptions, options) { GMX_UNUSED_VALUE(options); #if GMX_OPENMP - options->addOption(IntegerOption("ntomp").store(&g_numOpenMPThreads) - .description("Number of OpenMP threads for child mdrun calls")); + options->addOption( + IntegerOption("ntomp").store(&g_numOpenMPThreads).description("Number of OpenMP threads for child mdrun calls")); #endif } //! \endcond -} // namespace +} // namespace -SimulationRunner::SimulationRunner(TestFileManager *fileManager) : +SimulationRunner::SimulationRunner(TestFileManager* fileManager) : fullPrecisionTrajectoryFileName_(fileManager->getTemporaryFilePath(".trr")), mdpOutputFileName_(fileManager->getTemporaryFilePath("output.mdp")), tprFileName_(fileManager->getTemporaryFilePath(".tpr")), @@ -116,54 +116,46 @@ SimulationRunner::SimulationRunner(TestFileManager *fileManager) : // TODO There is possible outstanding unexplained behaviour of mdp // input parsing e.g. Redmine 2074, so this particular set of mdp // contents is also tested with GetIrTest in gmxpreprocess-test. -void -SimulationRunner::useEmptyMdpFile() +void SimulationRunner::useEmptyMdpFile() { useStringAsMdpFile(""); } -void -SimulationRunner::useStringAsMdpFile(const char *mdpString) +void SimulationRunner::useStringAsMdpFile(const char* mdpString) { useStringAsMdpFile(std::string(mdpString)); } -void -SimulationRunner::useStringAsMdpFile(const std::string &mdpString) +void SimulationRunner::useStringAsMdpFile(const std::string& mdpString) { mdpInputContents_ = mdpString; } -void -SimulationRunner::useStringAsNdxFile(const char *ndxString) +void SimulationRunner::useStringAsNdxFile(const char* ndxString) { gmx::TextWriter::writeFileFromString(ndxFileName_, ndxString); } -void -SimulationRunner::useTopG96AndNdxFromDatabase(const std::string &name) +void SimulationRunner::useTopG96AndNdxFromDatabase(const std::string& name) { topFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".top"); groFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".g96"); ndxFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".ndx"); } -void -SimulationRunner::useTopGroAndNdxFromDatabase(const std::string &name) +void SimulationRunner::useTopGroAndNdxFromDatabase(const std::string& name) { topFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".top"); groFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".gro"); ndxFileName_ = gmx::test::TestFileManager::getInputFilePath(name + ".ndx"); } -void -SimulationRunner::useGroFromDatabase(const char *name) +void SimulationRunner::useGroFromDatabase(const char* name) { groFileName_ = gmx::test::TestFileManager::getInputFilePath((std::string(name) + ".gro").c_str()); } -int -SimulationRunner::callGromppOnThisRank(const CommandLine &callerRef) +int SimulationRunner::callGromppOnThisRank(const CommandLine& callerRef) { const std::string mdpInputFileName(fileManager_.getTemporaryFilePath("input.mdp")); gmx::TextWriter::writeFileFromString(mdpInputFileName, mdpInputContents_); @@ -186,14 +178,12 @@ SimulationRunner::callGromppOnThisRank(const CommandLine &callerRef) return gmx_grompp(caller.argc(), caller.argv()); } -int -SimulationRunner::callGromppOnThisRank() +int SimulationRunner::callGromppOnThisRank() { return callGromppOnThisRank(CommandLine()); } -int -SimulationRunner::callGrompp(const CommandLine &callerRef) +int SimulationRunner::callGrompp(const CommandLine& callerRef) { int returnValue = 0; #if GMX_LIB_MPI @@ -214,14 +204,12 @@ SimulationRunner::callGrompp(const CommandLine &callerRef) return returnValue; } -int -SimulationRunner::callGrompp() +int SimulationRunner::callGrompp() { return callGrompp(CommandLine()); } -int -SimulationRunner::changeTprNsteps(int nsteps) +int SimulationRunner::changeTprNsteps(int nsteps) { CommandLine caller; caller.append("convert-tpr"); @@ -234,8 +222,7 @@ SimulationRunner::changeTprNsteps(int nsteps) return gmx_convert_tpr(caller.argc(), caller.argv()); } -int -SimulationRunner::callNmeig() +int SimulationRunner::callNmeig() { /* Conforming to style guide by not passing a non-const reference to this function. Passing a non-const reference might make it @@ -256,8 +243,7 @@ SimulationRunner::callNmeig() return gmx_nmeig(caller.argc(), caller.argv()); } -int -SimulationRunner::callMdrun(const CommandLine &callerRef) +int SimulationRunner::callMdrun(const CommandLine& callerRef) { /* Conforming to style guide by not passing a non-const reference to this function. Passing a non-const reference might make it @@ -293,8 +279,7 @@ SimulationRunner::callMdrun(const CommandLine &callerRef) return gmx_mdrun(caller.argc(), caller.argv()); } -int -SimulationRunner::callMdrun() +int SimulationRunner::callMdrun() { return callMdrun(CommandLine()); } @@ -308,15 +293,11 @@ MdrunTestFixtureBase::MdrunTestFixtureBase() #endif } -MdrunTestFixtureBase::~MdrunTestFixtureBase() -{ -} +MdrunTestFixtureBase::~MdrunTestFixtureBase() {} // ==== -MdrunTestFixture::MdrunTestFixture() : runner_(&fileManager_) -{ -} +MdrunTestFixture::MdrunTestFixture() : runner_(&fileManager_) {} MdrunTestFixture::~MdrunTestFixture() { diff --git a/src/programs/mdrun/tests/moduletest.h b/src/programs/mdrun/tests/moduletest.h index 70fb20e20e..3790cd220d 100644 --- a/src/programs/mdrun/tests/moduletest.h +++ b/src/programs/mdrun/tests/moduletest.h @@ -86,75 +86,75 @@ namespace test */ class SimulationRunner { - public: - //! Initializes a runner with given manager for temporary files. - explicit SimulationRunner(TestFileManager *fileManager); +public: + //! Initializes a runner with given manager for temporary files. + explicit SimulationRunner(TestFileManager* fileManager); - //! Use an empty .mdp file as input to grompp - void useEmptyMdpFile(); - //! Use a given string as input to grompp - void useStringAsMdpFile(const char *mdpString); - //! Use a given string as input to grompp - void useStringAsMdpFile(const std::string &mdpString); - //! Use a string as -n input to grompp - void useStringAsNdxFile(const char *ndxString); - //! Use a standard .top and .g96 file as input to grompp - void useTopG96AndNdxFromDatabase(const std::string &name); - //! Use a standard .top and .gro file as input to grompp - void useTopGroAndNdxFromDatabase(const std::string &name); - //! Use a standard .gro file as input to grompp - void useGroFromDatabase(const char *name); - //! Calls grompp (on rank 0, with a customized command line) to prepare for the mdrun test - int callGrompp(const CommandLine &callerRef); - //! Convenience wrapper for a default call to \c callGrompp - int callGrompp(); - //! Calls grompp (on this rank, with a customized command line) to prepare for the mdrun test - int callGromppOnThisRank(const CommandLine &callerRef); - //! Convenience wrapper for a default call to \c callGromppOnThisRank - int callGromppOnThisRank(); - //! Calls nmeig for testing - int callNmeig(); - //! Calls mdrun for testing with a customized command line - int callMdrun(const CommandLine &callerRef); - /*! \brief Convenience wrapper for calling mdrun for testing - * with default command line */ - int callMdrun(); - //! Calls convert-tpr on this rank to set a new number of steps in the tpr. - int changeTprNsteps(int nsteps); + //! Use an empty .mdp file as input to grompp + void useEmptyMdpFile(); + //! Use a given string as input to grompp + void useStringAsMdpFile(const char* mdpString); + //! Use a given string as input to grompp + void useStringAsMdpFile(const std::string& mdpString); + //! Use a string as -n input to grompp + void useStringAsNdxFile(const char* ndxString); + //! Use a standard .top and .g96 file as input to grompp + void useTopG96AndNdxFromDatabase(const std::string& name); + //! Use a standard .top and .gro file as input to grompp + void useTopGroAndNdxFromDatabase(const std::string& name); + //! Use a standard .gro file as input to grompp + void useGroFromDatabase(const char* name); + //! Calls grompp (on rank 0, with a customized command line) to prepare for the mdrun test + int callGrompp(const CommandLine& callerRef); + //! Convenience wrapper for a default call to \c callGrompp + int callGrompp(); + //! Calls grompp (on this rank, with a customized command line) to prepare for the mdrun test + int callGromppOnThisRank(const CommandLine& callerRef); + //! Convenience wrapper for a default call to \c callGromppOnThisRank + int callGromppOnThisRank(); + //! Calls nmeig for testing + int callNmeig(); + //! Calls mdrun for testing with a customized command line + int callMdrun(const CommandLine& callerRef); + /*! \brief Convenience wrapper for calling mdrun for testing + * with default command line */ + int callMdrun(); + //! Calls convert-tpr on this rank to set a new number of steps in the tpr. + int changeTprNsteps(int nsteps); - //@{ - /*! \name Names for frequently used grompp and mdrun output files - * - * These strings can be set to point to files present in the - * source tree, or to temporary files created for the test - * fixture. In the latter case, - * IntegrationTestFixture::fileManager_ should be used to fill - * these strings with paths to files, so that they are created - * in a temporary directory and (by default behaviour of - * TestFileManager) deleted when the test is complete. - */ - std::string topFileName_; - std::string groFileName_; - std::string fullPrecisionTrajectoryFileName_; - std::string reducedPrecisionTrajectoryFileName_; - std::string groOutputFileName_; - std::string ndxFileName_; - std::string mdpOutputFileName_; - std::string tprFileName_; - std::string logFileName_; - std::string edrFileName_; - std::string mtxFileName_; - std::string cptFileName_; - std::string swapFileName_; - int nsteps_; - //@} - //! What will be written into a temporary mdp file before the grompp call - std::string mdpInputContents_; + //@{ + /*! \name Names for frequently used grompp and mdrun output files + * + * These strings can be set to point to files present in the + * source tree, or to temporary files created for the test + * fixture. In the latter case, + * IntegrationTestFixture::fileManager_ should be used to fill + * these strings with paths to files, so that they are created + * in a temporary directory and (by default behaviour of + * TestFileManager) deleted when the test is complete. + */ + std::string topFileName_; + std::string groFileName_; + std::string fullPrecisionTrajectoryFileName_; + std::string reducedPrecisionTrajectoryFileName_; + std::string groOutputFileName_; + std::string ndxFileName_; + std::string mdpOutputFileName_; + std::string tprFileName_; + std::string logFileName_; + std::string edrFileName_; + std::string mtxFileName_; + std::string cptFileName_; + std::string swapFileName_; + int nsteps_; + //@} + //! What will be written into a temporary mdp file before the grompp call + std::string mdpInputContents_; - private: - TestFileManager &fileManager_; +private: + TestFileManager& fileManager_; - GMX_DISALLOW_COPY_AND_ASSIGN(SimulationRunner); + GMX_DISALLOW_COPY_AND_ASSIGN(SimulationRunner); }; /*! \internal @@ -183,9 +183,9 @@ class SimulationRunner */ class MdrunTestFixtureBase : public ::testing::Test { - public: - MdrunTestFixtureBase(); - ~MdrunTestFixtureBase() override; +public: + MdrunTestFixtureBase(); + ~MdrunTestFixtureBase() override; }; /*! \internal @@ -198,22 +198,23 @@ class MdrunTestFixtureBase : public ::testing::Test */ class MdrunTestFixture : public ::testing::Test { - public: - MdrunTestFixture(); - ~MdrunTestFixture() override; +public: + MdrunTestFixture(); + ~MdrunTestFixture() override; - //! Manages temporary files during the test. - TestFileManager fileManager_; - //! Helper object to manage the preparation for and call of mdrun - SimulationRunner runner_; + //! Manages temporary files during the test. + TestFileManager fileManager_; + //! Helper object to manage the preparation for and call of mdrun + SimulationRunner runner_; }; /*! \internal * \brief * Parameterized test fixture for mdrun integration tests */ -class ParameterizedMdrunTestFixture : public gmx::test::MdrunTestFixture, - public ::testing::WithParamInterface +class ParameterizedMdrunTestFixture : + public gmx::test::MdrunTestFixture, + public ::testing::WithParamInterface { }; diff --git a/src/programs/mdrun/tests/multisim.cpp b/src/programs/mdrun/tests/multisim.cpp index 315e9b97d2..2d6912517c 100644 --- a/src/programs/mdrun/tests/multisim.cpp +++ b/src/programs/mdrun/tests/multisim.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -85,9 +85,9 @@ TEST_P(MultiSimTest, ExitsNormallyWithDifferentNumbersOfStepsPerSimulation) SimulationRunner runner(&fileManager_); runner.useTopGroAndNdxFromDatabase("spc2"); - const char *pcoupl = GetParam(); + const char* pcoupl = GetParam(); // Do some different small numbers of steps in each simulation - int numSteps = rank_ % 4; + int numSteps = rank_ % 4; organizeMdpFile(&runner, pcoupl, numSteps); /* Call grompp on every rank - the standard callGrompp() only runs grompp on rank 0. */ @@ -99,12 +99,10 @@ TEST_P(MultiSimTest, ExitsNormallyWithDifferentNumbersOfStepsPerSimulation) /* Note, not all preprocessor implementations nest macro expansions the same way / at all, if we would try to duplicate less code. */ #if GMX_LIB_MPI -INSTANTIATE_TEST_CASE_P(InNvt, MultiSimTest, - ::testing::Values("pcoupl = no")); +INSTANTIATE_TEST_CASE_P(InNvt, MultiSimTest, ::testing::Values("pcoupl = no")); #else // Test needs real MPI to run -INSTANTIATE_TEST_CASE_P(DISABLED_InNvt, MultiSimTest, - ::testing::Values("pcoupl = no")); +INSTANTIATE_TEST_CASE_P(DISABLED_InNvt, MultiSimTest, ::testing::Values("pcoupl = no")); #endif //! Convenience typedef @@ -115,5 +113,5 @@ TEST_F(MultiSimTerminationTest, WritesCheckpointAfterMaxhTerminationAndThenResta runMaxhTest(); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/multisimtest.cpp b/src/programs/mdrun/tests/multisimtest.cpp index 1ffedbddc1..d836c8f5b0 100644 --- a/src/programs/mdrun/tests/multisimtest.cpp +++ b/src/programs/mdrun/tests/multisimtest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,19 +66,21 @@ namespace gmx namespace test { -MultiSimTest::MultiSimTest() : size_(gmx_node_num()), - rank_(gmx_node_rank()), - mdrunCaller_(new CommandLine) +MultiSimTest::MultiSimTest() : + size_(gmx_node_num()), + rank_(gmx_node_rank()), + mdrunCaller_(new CommandLine) { - const char *directoryNameFormat = "sim_%d"; + const char* directoryNameFormat = "sim_%d"; // Modify the file manager to have a temporary directory unique to // each simulation. No need to have a mutex on this, nobody else // can access the fileManager_ yet because we only just // constructed it. std::string originalTempDirectory = fileManager_.getOutputTempDirectory(); - std::string newTempDirectory = Path::join(originalTempDirectory, formatString(directoryNameFormat, rank_)); + std::string newTempDirectory = + Path::join(originalTempDirectory, formatString(directoryNameFormat, rank_)); Directory::create(newTempDirectory); fileManager_.setOutputTempDirectory(newTempDirectory); @@ -90,39 +92,34 @@ MultiSimTest::MultiSimTest() : size_(gmx_node_num()), } } -void MultiSimTest::organizeMdpFile(SimulationRunner *runner, - const char *controlVariable, - int numSteps) +void MultiSimTest::organizeMdpFile(SimulationRunner* runner, const char* controlVariable, int numSteps) { const real baseTemperature = 298; const real basePressure = 1; - std::string mdpFileContents = - formatString("nsteps = %d\n" - "nstlog = 1\n" - "nstcalcenergy = 1\n" - "tcoupl = v-rescale\n" - "tc-grps = System\n" - "tau-t = 1\n" - "ref-t = %f\n" - // pressure coupling (if active) - "tau-p = 1\n" - "ref-p = %f\n" - "compressibility = 4.5e-5\n" - // velocity generation - "gen-vel = yes\n" - "gen-temp = %f\n" - // control variable specification - "%s\n", - numSteps, - baseTemperature + 0.0001*rank_, - basePressure * std::pow(1.01, rank_), - /* Set things up so that the initial KE decreases with - increasing replica number, so that the (identical) - starting PE decreases on the first step more for the - replicas with higher number, which will tend to force - replica exchange to occur. */ - std::max(baseTemperature - 10 * rank_, real(0)), - controlVariable); + std::string mdpFileContents = formatString( + "nsteps = %d\n" + "nstlog = 1\n" + "nstcalcenergy = 1\n" + "tcoupl = v-rescale\n" + "tc-grps = System\n" + "tau-t = 1\n" + "ref-t = %f\n" + // pressure coupling (if active) + "tau-p = 1\n" + "ref-p = %f\n" + "compressibility = 4.5e-5\n" + // velocity generation + "gen-vel = yes\n" + "gen-temp = %f\n" + // control variable specification + "%s\n", + numSteps, baseTemperature + 0.0001 * rank_, basePressure * std::pow(1.01, rank_), + /* Set things up so that the initial KE decreases with + increasing replica number, so that the (identical) + starting PE decreases on the first step more for the + replicas with higher number, which will tend to force + replica exchange to occur. */ + std::max(baseTemperature - 10 * rank_, real(0)), controlVariable); runner->useStringAsMdpFile(mdpFileContents); } @@ -137,7 +134,7 @@ void MultiSimTest::runExitsNormallyTest() SimulationRunner runner(&fileManager_); runner.useTopGroAndNdxFromDatabase("spc2"); - const char *pcoupl = GetParam(); + const char* pcoupl = GetParam(); organizeMdpFile(&runner, pcoupl); /* Call grompp on every rank - the standard callGrompp() only runs grompp on rank 0. */ @@ -159,7 +156,7 @@ void MultiSimTest::runMaxhTest() TerminationHelper helper(&fileManager_, mdrunCaller_.get(), &runner); // Make sure -maxh has a chance to propagate - int numSteps = 100; + int numSteps = 100; organizeMdpFile(&runner, "pcoupl = no", numSteps); /* Call grompp on every rank - the standard callGrompp() only runs grompp on rank 0. */ @@ -169,5 +166,5 @@ void MultiSimTest::runMaxhTest() helper.runSecondMdrun(); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/multisimtest.h b/src/programs/mdrun/tests/multisimtest.h index 7eadeda2a0..11419d86ac 100644 --- a/src/programs/mdrun/tests/multisimtest.h +++ b/src/programs/mdrun/tests/multisimtest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,45 +68,42 @@ typedef std::unique_ptr CommandLinePointer; * * \ingroup module_mdrun_integration_tests */ -class MultiSimTest : public ::testing::Test, - public ::testing::WithParamInterface +class MultiSimTest : public ::testing::Test, public ::testing::WithParamInterface { - public: - MultiSimTest(); +public: + MultiSimTest(); - /*! \brief Organize the .mdp file for this rank - * - * For testing multi-simulation, this .mdp file is more - * complicated than it needs to be, but it does little harm, - * and doing it this way allows this function to be re-used - * for testing replica-exchange. - * - * \param runner The simulation runner that uses the - * mdp file that is organized. - * \param controlVariable Allows parameterization to work with - * T, P or (later) lambda as the control variable, by passing a - * string with "mdp-param = value" such that different paths - * in init_replica_exchange() are followed. - * \param numSteps Number of MD steps to perform. - */ - void organizeMdpFile(SimulationRunner *runner, - const char *controlVariable, - int numSteps = 2); - //! Test that a basic simulation works - void runExitsNormallyTest(); - //! Test that mdrun -maxh and restart works - void runMaxhTest(); - //! Number of MPI ranks - int size_; - //! MPI rank of this process - int rank_; - //! Object for building the mdrun command line - CommandLinePointer mdrunCaller_; - //! Manages temporary files during the test. - TestFileManager fileManager_; + /*! \brief Organize the .mdp file for this rank + * + * For testing multi-simulation, this .mdp file is more + * complicated than it needs to be, but it does little harm, + * and doing it this way allows this function to be re-used + * for testing replica-exchange. + * + * \param runner The simulation runner that uses the + * mdp file that is organized. + * \param controlVariable Allows parameterization to work with + * T, P or (later) lambda as the control variable, by passing a + * string with "mdp-param = value" such that different paths + * in init_replica_exchange() are followed. + * \param numSteps Number of MD steps to perform. + */ + void organizeMdpFile(SimulationRunner* runner, const char* controlVariable, int numSteps = 2); + //! Test that a basic simulation works + void runExitsNormallyTest(); + //! Test that mdrun -maxh and restart works + void runMaxhTest(); + //! Number of MPI ranks + int size_; + //! MPI rank of this process + int rank_; + //! Object for building the mdrun command line + CommandLinePointer mdrunCaller_; + //! Manages temporary files during the test. + TestFileManager fileManager_; }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun/tests/nonbonded_bench.cpp b/src/programs/mdrun/tests/nonbonded_bench.cpp index 300322f449..ea92e2c80b 100644 --- a/src/programs/mdrun/tests/nonbonded_bench.cpp +++ b/src/programs/mdrun/tests/nonbonded_bench.cpp @@ -60,15 +60,13 @@ namespace TEST(NonbondedBenchTest, BasicEndToEndTest) { - const char *const command[] = { - "nonbonded-benchmark" - }; + const char* const command[] = { "nonbonded-benchmark" }; CommandLine cmdline(command); cmdline.addOption("-iter", 1); EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory( - &gmx::NonbondedBenchmarkInfo::create, &cmdline)); + &gmx::NonbondedBenchmarkInfo::create, &cmdline)); } -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/normalmodes.cpp b/src/programs/mdrun/tests/normalmodes.cpp index aa88ad867d..b24d758839 100644 --- a/src/programs/mdrun/tests/normalmodes.cpp +++ b/src/programs/mdrun/tests/normalmodes.cpp @@ -85,9 +85,9 @@ using MdpField = MdpFieldValues::value_type; * a reproducible eigenvalues following diagonalization. * * The choices for tolerance are arbitrary but sufficient. */ -class NormalModesTest : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string>> +class NormalModesTest : + public MdrunTestFixture, + public ::testing::WithParamInterface> { }; @@ -96,22 +96,21 @@ TEST_P(NormalModesTest, WithinTolerances) auto params = GetParam(); auto simulationName = std::get<0>(params); auto integrator = std::get<1>(params); - SCOPED_TRACE(formatString("Comparing normal modes for '%s'", - simulationName.c_str())); + SCOPED_TRACE(formatString("Comparing normal modes for '%s'", simulationName.c_str())); // TODO At some point we should also test PME-only ranks. int numRanksAvailable = getNumberOfTestMpiRanks(); if (!isNumberOfPpRanksSupported(simulationName, numRanksAvailable)) { - fprintf(stdout, "Test system '%s' cannot run with %d ranks.\n" + fprintf(stdout, + "Test system '%s' cannot run with %d ranks.\n" "The supported numbers are: %s\n", simulationName.c_str(), numRanksAvailable, reportNumbersOfPpRanksSupported(simulationName).c_str()); return; } - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - "no", "no"); + auto mdpFieldValues = + prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no"); mdpFieldValues["nsteps"] = "1"; mdpFieldValues["rcoulomb"] = "5.6"; mdpFieldValues["rlist"] = "5.6"; @@ -136,10 +135,10 @@ TEST_P(NormalModesTest, WithinTolerances) { ASSERT_EQ(0, runner_.callNmeig()); TestReferenceData refData; - auto checker = refData.rootChecker() - .checkCompound("System", simulationName) - .checkCompound("Integrator", integrator); - auto settings = XvgMatchSettings(); + auto checker = refData.rootChecker() + .checkCompound("System", simulationName) + .checkCompound("Integrator", integrator); + auto settings = XvgMatchSettings(); settings.tolerance = relativeToleranceAsFloatingPoint(1.0, 1e-05); TextInputFile input("eigenval.xvg"); checkXvgFile(&input, &checker, settings); @@ -148,7 +147,8 @@ TEST_P(NormalModesTest, WithinTolerances) //! Containers of systems and integrators to test. //! \{ -std::vector systemsToTest_g = { "scaled-water", "villin", "spc-dimer", "one-tip5p", "sw-dimer" }; +std::vector systemsToTest_g = { "scaled-water", "villin", "spc-dimer", "one-tip5p", + "sw-dimer" }; std::vector integratorsToTest_g = { "nm" }; //! \} @@ -159,9 +159,10 @@ std::vector integratorsToTest_g = { "nm" }; // lifetime of the whole test binary process, these tests should run in // such configurations. #if GMX_DOUBLE -INSTANTIATE_TEST_CASE_P(NormalModesWorks, NormalModesTest, - ::testing::Combine(::testing::ValuesIn(systemsToTest_g), - ::testing::ValuesIn(integratorsToTest_g))); +INSTANTIATE_TEST_CASE_P(NormalModesWorks, + NormalModesTest, + ::testing::Combine(::testing::ValuesIn(systemsToTest_g), + ::testing::ValuesIn(integratorsToTest_g))); #endif } // namespace } // namespace test diff --git a/src/programs/mdrun/tests/periodicactions.cpp b/src/programs/mdrun/tests/periodicactions.cpp index 041326359b..cd5180bd5c 100644 --- a/src/programs/mdrun/tests/periodicactions.cpp +++ b/src/programs/mdrun/tests/periodicactions.cpp @@ -95,37 +95,31 @@ using OutputParameterGeneratorFunction = std::vector ( */ class PeriodicActionsTest : public MdrunTestFixture, - public ::testing::WithParamInterface < std::tuple < PropagationParameters, - OutputParameterGeneratorFunction>> + public ::testing::WithParamInterface> { - public: - //PeriodicActionsTest(); - //! Run mdrun with given output parameters - void doMdrun(const PeriodicOutputParameters &output); - //! Generate reference data from mdrun writing everything every step. - void prepareReferenceData(); - //! Names for the output files from the reference mdrun call - ReferenceFileNames referenceFileNames_ = { - fileManager_.getTemporaryFilePath("reference.edr") - }; - //! Functor for energy comparison - EnergyComparison energyComparison_ { EnergyComparison::s_defaultEnergyTermsToCompare }; - //! Names of energies compared by energyComparison_ - std::vector namesOfEnergiesToMatch_ = energyComparison_.getEnergyNames(); +public: + // PeriodicActionsTest(); + //! Run mdrun with given output parameters + void doMdrun(const PeriodicOutputParameters& output); + //! Generate reference data from mdrun writing everything every step. + void prepareReferenceData(); + //! Names for the output files from the reference mdrun call + ReferenceFileNames referenceFileNames_ = { fileManager_.getTemporaryFilePath("reference.edr") }; + //! Functor for energy comparison + EnergyComparison energyComparison_{ EnergyComparison::s_defaultEnergyTermsToCompare }; + //! Names of energies compared by energyComparison_ + std::vector namesOfEnergiesToMatch_ = energyComparison_.getEnergyNames(); }; -void PeriodicActionsTest::doMdrun(const PeriodicOutputParameters &output) +void PeriodicActionsTest::doMdrun(const PeriodicOutputParameters& output) { - auto propagation = std::get<0>(GetParam()); - SCOPED_TRACE(formatString("Doing %s simulation with %s integrator, %s tcoupling and %s pcoupling\n", - propagation["simulationName"].c_str(), - propagation["integrator"].c_str(), - propagation["tcoupl"].c_str(), - propagation["pcoupl"].c_str())); - auto mdpFieldValues = prepareMdpFieldValues(propagation["simulationName"], - propagation["integrator"], - propagation["tcoupl"], - propagation["pcoupl"]); + auto propagation = std::get<0>(GetParam()); + SCOPED_TRACE( + formatString("Doing %s simulation with %s integrator, %s tcoupling and %s pcoupling\n", + propagation["simulationName"].c_str(), propagation["integrator"].c_str(), + propagation["tcoupl"].c_str(), propagation["pcoupl"].c_str())); + auto mdpFieldValues = prepareMdpFieldValues(propagation["simulationName"], propagation["integrator"], + propagation["tcoupl"], propagation["pcoupl"]); mdpFieldValues.insert(propagation.begin(), propagation.end()); mdpFieldValues.insert(output.begin(), output.end()); @@ -155,10 +149,12 @@ void PeriodicActionsTest::prepareReferenceData() std::swap(runner_.edrFileName_, referenceFileNames_.edrFileName_); // Run the reference simulation with everything output every step - PeriodicOutputParameters outputEveryStep = { { "nstenergy", "1" }, - { "nstlog", "1" }, - { "nstdhdl", "1" }, - { "description", "output everything every step"}, }; + PeriodicOutputParameters outputEveryStep = { + { "nstenergy", "1" }, + { "nstlog", "1" }, + { "nstdhdl", "1" }, + { "description", "output everything every step" }, + }; doMdrun(outputEveryStep); // Restore the standard filenames we'll use for the runs whose behavior we are testing. @@ -170,10 +166,8 @@ void PeriodicActionsTest::prepareReferenceData() * * \returns True when a successful comparison was made */ -template -bool compareFrames(Reader referenceFrameReader, - Reader testFrameReader, - const Comparator &comparator) +template +bool compareFrames(Reader referenceFrameReader, Reader testFrameReader, const Comparator& comparator) { if (!testFrameReader->readNextFrame()) { @@ -183,7 +177,7 @@ bool compareFrames(Reader referenceFrameReader, auto testFrame = testFrameReader->frame(); std::string frameName = testFrame.frameName(); SCOPED_TRACE("Found frame from test file named " + frameName); - bool foundMatch = false; + bool foundMatch = false; while (!foundMatch) { if (referenceFrameReader->readNextFrame()) @@ -210,13 +204,12 @@ TEST_P(PeriodicActionsTest, PeriodicActionsAgreeWithReference) { auto propagation = std::get<0>(GetParam()); SCOPED_TRACE(formatString("Comparing two simulations of '%s' with integrator '%s'", - propagation["simulationName"].c_str(), - propagation["integrator"].c_str())); + propagation["simulationName"].c_str(), propagation["integrator"].c_str())); prepareReferenceData(); auto outputParametersGenerator = std::get<1>(GetParam()); - for (const PeriodicOutputParameters &output : outputParametersGenerator()) + for (const PeriodicOutputParameters& output : outputParametersGenerator()) { SCOPED_TRACE("Comparing to observe " + output.at("description")); @@ -224,19 +217,22 @@ TEST_P(PeriodicActionsTest, PeriodicActionsAgreeWithReference) doMdrun(output); // Prepare readers for the reference and test output files - auto referenceEnergyFrameReader = openEnergyFileToReadTerms(referenceFileNames_.edrFileName_, namesOfEnergiesToMatch_); - auto testEnergyFrameReader = openEnergyFileToReadTerms(runner_.edrFileName_, namesOfEnergiesToMatch_); + auto referenceEnergyFrameReader = + openEnergyFileToReadTerms(referenceFileNames_.edrFileName_, namesOfEnergiesToMatch_); + auto testEnergyFrameReader = + openEnergyFileToReadTerms(runner_.edrFileName_, namesOfEnergiesToMatch_); - const bool shouldCompareEnergies = fromString(output.at("nstenergy")) > 0; - bool shouldContinueComparing = shouldCompareEnergies; + const bool shouldCompareEnergies = fromString(output.at("nstenergy")) > 0; + bool shouldContinueComparing = shouldCompareEnergies; while (shouldContinueComparing) { if (shouldCompareEnergies) { - SCOPED_TRACE("Comparing energy frames from reference '" + referenceFileNames_.edrFileName_ + - "' and test '" + runner_.edrFileName_ + "'"); - shouldContinueComparing = shouldContinueComparing && - compareFrames(referenceEnergyFrameReader.get(), testEnergyFrameReader.get(), energyComparison_); + SCOPED_TRACE("Comparing energy frames from reference '" + referenceFileNames_.edrFileName_ + + "' and test '" + runner_.edrFileName_ + "'"); + shouldContinueComparing = shouldContinueComparing + && compareFrames(referenceEnergyFrameReader.get(), + testEnergyFrameReader.get(), energyComparison_); } } } @@ -244,15 +240,11 @@ TEST_P(PeriodicActionsTest, PeriodicActionsAgreeWithReference) /*! \brief Some common choices of periodic output mdp parameters to * simplify defining values for the combinations under test */ -PeriodicOutputParameters g_basicPeriodicOutputParameters = -{ { "nstenergy", "0" }, - { "nstlog", "0" }, - { "nstxout", "0" }, - { "nstvout", "0" }, - { "nstfout", "0" }, - { "nstxout-compressed", "0" }, - { "nstdhdl", "0" }, - { "description", "unknown" } }; +PeriodicOutputParameters g_basicPeriodicOutputParameters = { + { "nstenergy", "0" }, { "nstlog", "0" }, { "nstxout", "0" }, + { "nstvout", "0" }, { "nstfout", "0" }, { "nstxout-compressed", "0" }, + { "nstdhdl", "0" }, { "description", "unknown" } +}; /*! \brief Return vector of mdp parameter sets to test * @@ -294,33 +286,15 @@ std::vector outputParameters() std::vector simplePropagationParameters() { return { - { { - "simulationName", "argon12" - }, - { - "integrator", "md" - }, - { - "comm-mode", "linear" - }, - { - "nstcomm", "1" - }, - { - "tcoupl", "no" - }, - { - "nsttcouple", "0" - }, - { - "pcoupl", "no" - }, - { - "nstpcouple", "0" - }, - { - "maxGromppWarningsTolerated", "0" - } }, + { { "simulationName", "argon12" }, + { "integrator", "md" }, + { "comm-mode", "linear" }, + { "nstcomm", "1" }, + { "tcoupl", "no" }, + { "nsttcouple", "0" }, + { "pcoupl", "no" }, + { "nstpcouple", "0" }, + { "maxGromppWarningsTolerated", "0" } }, }; } @@ -340,18 +314,18 @@ std::vector propagationParametersWithCoupling() std::string nstcomm = "5"; std::vector parameterSets; - for (std::string simulationName : {"argon12"}) + for (std::string simulationName : { "argon12" }) { - for (std::string integrator : {"md", "sd", "md-vv"}) + for (std::string integrator : { "md", "sd", "md-vv" }) { - for (std::string tcoupl : {"no", "v-rescale", "Nose-Hoover"}) + for (std::string tcoupl : { "no", "v-rescale", "Nose-Hoover" }) { // SD doesn't support temperature-coupling algorithms, if (integrator == "sd" && tcoupl != "no") { continue; } - for (std::string pcoupl : {"no", "Berendsen", "Parrinello-Rahman"}) + for (std::string pcoupl : { "no", "Berendsen", "Parrinello-Rahman" }) { // VV supports few algorithm combinations if (integrator == "md-vv") @@ -361,8 +335,8 @@ std::vector propagationParametersWithCoupling() { pcoupl = "MTTK"; } - if ((tcoupl == "Nose-Hoover" && pcoupl == "Berendsen") || - (tcoupl != "Nose-Hoover" && pcoupl == "MTTK")) + if ((tcoupl == "Nose-Hoover" && pcoupl == "Berendsen") + || (tcoupl != "Nose-Hoover" && pcoupl == "MTTK")) { continue; } @@ -378,16 +352,16 @@ std::vector propagationParametersWithCoupling() { ++maxGromppWarningsTolerated; } - parameterSets.emplace_back - (PropagationParameters {{"simulationName", simulationName}, - {"integrator", integrator}, - {"comm-mode", comm_mode}, - {"nstcomm", nstcomm}, - {"tcoupl", tcoupl}, - {"nsttcouple", nsttcouple}, - {"pcoupl", pcoupl}, - {"nstpcouple", nstpcouple}, - {"maxGromppWarningsTolerated", toString(maxGromppWarningsTolerated)}}); + parameterSets.emplace_back(PropagationParameters{ + { "simulationName", simulationName }, + { "integrator", integrator }, + { "comm-mode", comm_mode }, + { "nstcomm", nstcomm }, + { "tcoupl", tcoupl }, + { "nsttcouple", nsttcouple }, + { "pcoupl", pcoupl }, + { "nstpcouple", nstpcouple }, + { "maxGromppWarningsTolerated", toString(maxGromppWarningsTolerated) } }); } } } @@ -407,18 +381,18 @@ std::vector propagationParametersWithConstraints() std::string nstcomm = "5"; std::vector parameterSets; - for (std::string simulationName : {"tip3p5"}) + for (std::string simulationName : { "tip3p5" }) { - for (std::string integrator : {"md", "sd", "md-vv"}) + for (std::string integrator : { "md", "sd", "md-vv" }) { - for (std::string tcoupl : {"no", "v-rescale" }) + for (std::string tcoupl : { "no", "v-rescale" }) { // SD doesn't support temperature-coupling algorithms, if (integrator == "sd" && tcoupl != "no") { continue; } - for (std::string pcoupl : {"no", "Parrinello-Rahman"}) + for (std::string pcoupl : { "no", "Parrinello-Rahman" }) { // VV supports few algorithm combinations if (integrator == "md-vv") @@ -428,8 +402,8 @@ std::vector propagationParametersWithConstraints() { pcoupl = "MTTK"; } - if ((tcoupl == "Nose-Hoover" && pcoupl == "Berendsen") || - (tcoupl != "Nose-Hoover" && pcoupl == "MTTK")) + if ((tcoupl == "Nose-Hoover" && pcoupl == "Berendsen") + || (tcoupl != "Nose-Hoover" && pcoupl == "MTTK")) { continue; } @@ -441,16 +415,16 @@ std::vector propagationParametersWithConstraints() } int maxGromppWarningsTolerated = 0; - parameterSets.emplace_back - (PropagationParameters {{"simulationName", simulationName}, - {"integrator", integrator}, - {"comm-mode", comm_mode}, - {"nstcomm", nstcomm}, - {"tcoupl", tcoupl}, - {"nsttcouple", nsttcouple}, - {"pcoupl", pcoupl}, - {"nstpcouple", nstpcouple}, - {"maxGromppWarningsTolerated", toString(maxGromppWarningsTolerated)}}); + parameterSets.emplace_back(PropagationParameters{ + { "simulationName", simulationName }, + { "integrator", integrator }, + { "comm-mode", comm_mode }, + { "nstcomm", nstcomm }, + { "tcoupl", tcoupl }, + { "nsttcouple", nsttcouple }, + { "pcoupl", pcoupl }, + { "nstpcouple", nstpcouple }, + { "maxGromppWarningsTolerated", toString(maxGromppWarningsTolerated) } }); } } } @@ -466,25 +440,25 @@ using ::testing::ValuesIn; // out. Once that compilation is cached for the whole process, these // tests can run in such configurations. #if GMX_GPU != GMX_GPU_OPENCL -INSTANTIATE_TEST_CASE_P(BasicPropagators, PeriodicActionsTest, - Combine(ValuesIn(simplePropagationParameters()), - Values(outputParameters))); -INSTANTIATE_TEST_CASE_P(PropagatorsWithCoupling, PeriodicActionsTest, - Combine(ValuesIn(propagationParametersWithCoupling()), - Values(outputParameters))); -INSTANTIATE_TEST_CASE_P(PropagatorsWithConstraints, PeriodicActionsTest, - Combine(ValuesIn(propagationParametersWithConstraints()), - Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(BasicPropagators, + PeriodicActionsTest, + Combine(ValuesIn(simplePropagationParameters()), Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(PropagatorsWithCoupling, + PeriodicActionsTest, + Combine(ValuesIn(propagationParametersWithCoupling()), Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(PropagatorsWithConstraints, + PeriodicActionsTest, + Combine(ValuesIn(propagationParametersWithConstraints()), Values(outputParameters))); #else -INSTANTIATE_TEST_CASE_P(DISABLED_BasicPropagators, PeriodicActionsTest, - Combine(ValuesIn(simplePropagationParameters()), - Values(outputParameters))); -INSTANTIATE_TEST_CASE_P(DISABLED_PropagatorsWithCoupling, PeriodicActionsTest, - Combine(ValuesIn(propagationParametersWithCoupling()), - Values(outputParameters))); -INSTANTIATE_TEST_CASE_P(DISABLED_PropagatorsWithConstraints, PeriodicActionsTest, - Combine(ValuesIn(propagationParametersWithConstraints()), - Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(DISABLED_BasicPropagators, + PeriodicActionsTest, + Combine(ValuesIn(simplePropagationParameters()), Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(DISABLED_PropagatorsWithCoupling, + PeriodicActionsTest, + Combine(ValuesIn(propagationParametersWithCoupling()), Values(outputParameters))); +INSTANTIATE_TEST_CASE_P(DISABLED_PropagatorsWithConstraints, + PeriodicActionsTest, + Combine(ValuesIn(propagationParametersWithConstraints()), Values(outputParameters))); #endif } // namespace diff --git a/src/programs/mdrun/tests/pmetest.cpp b/src/programs/mdrun/tests/pmetest.cpp index 7d2c89f206..285adf87e7 100644 --- a/src/programs/mdrun/tests/pmetest.cpp +++ b/src/programs/mdrun/tests/pmetest.cpp @@ -83,15 +83,15 @@ namespace * \todo Consider also using GpuTest class. */ class PmeTest : public MdrunTestFixture { - public: - //! Before any test is run, work out whether any compatible GPUs exist. - static void SetUpTestCase(); - //! Store whether any compatible GPUs exist. - static bool s_hasCompatibleGpus; - //! Convenience typedef - using RunModesList = std::map < std::string, std::vector < const char *>>; - //! Runs the test with the given inputs - void runTest(const RunModesList &runModes); +public: + //! Before any test is run, work out whether any compatible GPUs exist. + static void SetUpTestCase(); + //! Store whether any compatible GPUs exist. + static bool s_hasCompatibleGpus; + //! Convenience typedef + using RunModesList = std::map>; + //! Runs the test with the given inputs + void runTest(const RunModesList& runModes); }; bool PmeTest::s_hasCompatibleGpus = false; @@ -101,7 +101,7 @@ void PmeTest::SetUpTestCase() s_hasCompatibleGpus = canComputeOnGpu(); } -void PmeTest::runTest(const RunModesList &runModes) +void PmeTest::runTest(const RunModesList& runModes) { const std::string inputFile = "spc-and-methanol"; runner_.useTopGroAndNdxFromDatabase(inputFile); @@ -121,11 +121,10 @@ void PmeTest::runTest(const RunModesList &runModes) EXPECT_NONFATAL_FAILURE(rootChecker.checkUnusedEntries(), ""); // skip checks on other ranks } - auto hardwareInfo_ = gmx_detect_hardware(MDLogger {}, - PhysicalNodeCommunicator(MPI_COMM_WORLD, - gmx_physicalnode_id_hash())); + auto hardwareInfo_ = gmx_detect_hardware( + MDLogger{}, PhysicalNodeCommunicator(MPI_COMM_WORLD, gmx_physicalnode_id_hash())); - for (const auto &mode : runModes) + for (const auto& mode : runModes) { auto modeTargetsGpus = (mode.first.find("Gpu") != std::string::npos); if (modeTargetsGpus && !s_hasCompatibleGpus) @@ -136,9 +135,8 @@ void PmeTest::runTest(const RunModesList &runModes) continue; } auto modeTargetsPmeOnGpus = (mode.first.find("PmeOnGpu") != std::string::npos); - if (modeTargetsPmeOnGpus && - !(pme_gpu_supports_build(nullptr) && - pme_gpu_supports_hardware(*hardwareInfo_, nullptr))) + if (modeTargetsPmeOnGpus + && !(pme_gpu_supports_build(nullptr) && pme_gpu_supports_hardware(*hardwareInfo_, nullptr))) { // This run mode will cause a fatal error from mdrun when // it finds an unsuitable device, which is not something @@ -146,11 +144,12 @@ void PmeTest::runTest(const RunModesList &runModes) continue; } - runner_.edrFileName_ = fileManager_.getTemporaryFilePath(inputFile + "_" + mode.first + ".edr"); + runner_.edrFileName_ = + fileManager_.getTemporaryFilePath(inputFile + "_" + mode.first + ".edr"); CommandLine commandLine(mode.second); - const bool usePmeTuning = (mode.first.find("Tune") != std::string::npos); + const bool usePmeTuning = (mode.first.find("Tune") != std::string::npos); if (usePmeTuning) { commandLine.append("-tunepme"); @@ -169,13 +168,14 @@ void PmeTest::runTest(const RunModesList &runModes) if (thisRankChecks) { - auto energyReader = openEnergyFileToReadTerms(runner_.edrFileName_, {"Coul. recip.", "Total Energy", "Kinetic En."}); + auto energyReader = openEnergyFileToReadTerms( + runner_.edrFileName_, { "Coul. recip.", "Total Energy", "Kinetic En." }); auto conservedChecker = rootChecker.checkCompound("Energy", "Conserved"); auto reciprocalChecker = rootChecker.checkCompound("Energy", "Reciprocal"); bool firstIteration = true; while (energyReader->readNextFrame()) { - const EnergyFrame &frame = energyReader->frame(); + const EnergyFrame& frame = energyReader->frame(); const std::string stepName = frame.frameName(); const real conservedEnergy = frame.at("Total Energy"); const real reciprocalEnergy = frame.at("Coul. recip."); @@ -183,8 +183,10 @@ void PmeTest::runTest(const RunModesList &runModes) { // use first step values as references for tolerance const real startingKineticEnergy = frame.at("Kinetic En."); - const auto conservedTolerance = relativeToleranceAsFloatingPoint(startingKineticEnergy, 2e-5); - const auto reciprocalTolerance = relativeToleranceAsFloatingPoint(reciprocalEnergy, 3e-5); + const auto conservedTolerance = + relativeToleranceAsFloatingPoint(startingKineticEnergy, 2e-5); + const auto reciprocalTolerance = + relativeToleranceAsFloatingPoint(reciprocalEnergy, 3e-5); reciprocalChecker.setDefaultTolerance(reciprocalTolerance); conservedChecker.setDefaultTolerance(conservedTolerance); firstIteration = false; @@ -202,27 +204,27 @@ void PmeTest::runTest(const RunModesList &runModes) TEST_F(PmeTest, ReproducesEnergies) { const int nsteps = 20; - const std::string theMdpFile = formatString("coulombtype = PME\n" - "nstcalcenergy = 1\n" - "nstenergy = 1\n" - "pme-order = 4\n" - "nsteps = %d\n", - nsteps - ); + const std::string theMdpFile = formatString( + "coulombtype = PME\n" + "nstcalcenergy = 1\n" + "nstenergy = 1\n" + "pme-order = 4\n" + "nsteps = %d\n", + nsteps); runner_.useStringAsMdpFile(theMdpFile); - //TODO test all proper/improper combinations in more thorough way? + // TODO test all proper/improper combinations in more thorough way? RunModesList runModes; - runModes["PmeOnCpu"] = {"-pme", "cpu"}; - runModes["PmeAuto"] = {"-pme", "auto"}; - runModes["PmeOnGpuFftOnCpu"] = {"-pme", "gpu", "-pmefft", "cpu"}; - runModes["PmeOnGpuFftOnGpu"] = {"-pme", "gpu", "-pmefft", "gpu"}; - runModes["PmeOnGpuFftAuto"] = {"-pme", "gpu", "-pmefft", "auto"}; + runModes["PmeOnCpu"] = { "-pme", "cpu" }; + runModes["PmeAuto"] = { "-pme", "auto" }; + runModes["PmeOnGpuFftOnCpu"] = { "-pme", "gpu", "-pmefft", "cpu" }; + runModes["PmeOnGpuFftOnGpu"] = { "-pme", "gpu", "-pmefft", "gpu" }; + runModes["PmeOnGpuFftAuto"] = { "-pme", "gpu", "-pmefft", "auto" }; // same manual modes but marked for PME tuning - runModes["PmeOnCpuTune"] = {"-pme", "cpu"}; - runModes["PmeOnGpuFftOnCpuTune"] = {"-pme", "gpu", "-pmefft", "cpu"}; - runModes["PmeOnGpuFftOnGpuTune"] = {"-pme", "gpu", "-pmefft", "gpu"}; + runModes["PmeOnCpuTune"] = { "-pme", "cpu" }; + runModes["PmeOnGpuFftOnCpuTune"] = { "-pme", "gpu", "-pmefft", "cpu" }; + runModes["PmeOnGpuFftOnGpuTune"] = { "-pme", "gpu", "-pmefft", "gpu" }; runTest(runModes); } @@ -230,21 +232,21 @@ TEST_F(PmeTest, ReproducesEnergies) TEST_F(PmeTest, ScalesTheBox) { const int nsteps = 0; - const std::string theMdpFile = formatString("coulombtype = PME\n" - "nstcalcenergy = 1\n" - "nstenergy = 1\n" - "pme-order = 4\n" - "pbc = xyz\n" - "nsteps = %d\n", - nsteps - ); + const std::string theMdpFile = formatString( + "coulombtype = PME\n" + "nstcalcenergy = 1\n" + "nstenergy = 1\n" + "pme-order = 4\n" + "pbc = xyz\n" + "nsteps = %d\n", + nsteps); runner_.useStringAsMdpFile(theMdpFile); RunModesList runModes; - runModes["PmeOnCpu"] = {"-pme", "cpu"}; - runModes["PmeOnGpuFftOnCpu"] = {"-pme", "gpu", "-pmefft", "cpu"}; - runModes["PmeOnGpuFftOnGpu"] = {"-pme", "gpu", "-pmefft", "gpu"}; + runModes["PmeOnCpu"] = { "-pme", "cpu" }; + runModes["PmeOnGpuFftOnCpu"] = { "-pme", "gpu", "-pmefft", "cpu" }; + runModes["PmeOnGpuFftOnGpu"] = { "-pme", "gpu", "-pmefft", "gpu" }; runTest(runModes); } @@ -252,30 +254,30 @@ TEST_F(PmeTest, ScalesTheBox) TEST_F(PmeTest, ScalesTheBoxWithWalls) { const int nsteps = 0; - const std::string theMdpFile = formatString("coulombtype = PME\n" - "nstcalcenergy = 1\n" - "nstenergy = 1\n" - "pme-order = 4\n" - "pbc = xy\n" - "nwall = 2\n" - "ewald-geometry = 3dc\n" - "wall_atomtype = CMet H\n" - "wall_density = 9 9.0\n" - "wall-ewald-zfac = 5\n" - "nsteps = %d\n", - nsteps - ); + const std::string theMdpFile = formatString( + "coulombtype = PME\n" + "nstcalcenergy = 1\n" + "nstenergy = 1\n" + "pme-order = 4\n" + "pbc = xy\n" + "nwall = 2\n" + "ewald-geometry = 3dc\n" + "wall_atomtype = CMet H\n" + "wall_density = 9 9.0\n" + "wall-ewald-zfac = 5\n" + "nsteps = %d\n", + nsteps); runner_.useStringAsMdpFile(theMdpFile); RunModesList runModes; - runModes["PmeOnCpu"] = {"-pme", "cpu"}; - runModes["PmeOnGpuFftOnCpu"] = {"-pme", "gpu", "-pmefft", "cpu"}; - runModes["PmeOnGpuFftOnGpu"] = {"-pme", "gpu", "-pmefft", "gpu"}; + runModes["PmeOnCpu"] = { "-pme", "cpu" }; + runModes["PmeOnGpuFftOnCpu"] = { "-pme", "gpu", "-pmefft", "cpu" }; + runModes["PmeOnGpuFftOnGpu"] = { "-pme", "gpu", "-pmefft", "gpu" }; runTest(runModes); } -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/replicaexchange.cpp b/src/programs/mdrun/tests/replicaexchange.cpp index 14a72b00e4..fd134f1742 100644 --- a/src/programs/mdrun/tests/replicaexchange.cpp +++ b/src/programs/mdrun/tests/replicaexchange.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -70,11 +70,13 @@ TEST_P(ReplicaExchangeEnsembleTest, ExitsNormally) /* Note, not all preprocessor implementations nest macro expansions the same way / at all, if we would try to duplicate less code. */ #if GMX_LIB_MPI -INSTANTIATE_TEST_CASE_P(WithDifferentControlVariables, ReplicaExchangeEnsembleTest, - ::testing::Values("pcoupl = no", "pcoupl = Berendsen")); +INSTANTIATE_TEST_CASE_P(WithDifferentControlVariables, + ReplicaExchangeEnsembleTest, + ::testing::Values("pcoupl = no", "pcoupl = Berendsen")); #else -INSTANTIATE_TEST_CASE_P(DISABLED_WithDifferentControlVariables, ReplicaExchangeEnsembleTest, - ::testing::Values("pcoupl = no", "pcoupl = Berendsen")); +INSTANTIATE_TEST_CASE_P(DISABLED_WithDifferentControlVariables, + ReplicaExchangeEnsembleTest, + ::testing::Values("pcoupl = no", "pcoupl = Berendsen")); #endif //! Convenience typedef @@ -86,5 +88,5 @@ TEST_F(ReplicaExchangeTerminationTest, WritesCheckpointAfterMaxhTerminationAndTh runMaxhTest(); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/rerun.cpp b/src/programs/mdrun/tests/rerun.cpp index 3b46c92ccd..87d8719c45 100644 --- a/src/programs/mdrun/tests/rerun.cpp +++ b/src/programs/mdrun/tests/rerun.cpp @@ -84,20 +84,21 @@ namespace * quantities from a normal run, because the accumulation order * differs. (Nor does it reproduce pair-search frames exactly, * either). */ -class MdrunRerunTest : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string>> +class MdrunRerunTest : + public MdrunTestFixture, + public ::testing::WithParamInterface> { - public: - //! Trajectory components to compare - static const TrajectoryFrameMatchSettings trajectoryMatchSettings; +public: + //! Trajectory components to compare + static const TrajectoryFrameMatchSettings trajectoryMatchSettings; }; // Compare box, positions and forces, but not velocities // (velocities are ignored in reruns) -const TrajectoryFrameMatchSettings MdrunRerunTest::trajectoryMatchSettings = -{ - true, true, true, +const TrajectoryFrameMatchSettings MdrunRerunTest::trajectoryMatchSettings = { + true, + true, + true, ComparisonConditions::MustCompare, ComparisonConditions::NoComparison, ComparisonConditions::MustCompare @@ -108,32 +109,28 @@ TEST_P(MdrunRerunTest, WithinTolerances) auto params = GetParam(); auto simulationName = std::get<0>(params); auto integrator = std::get<1>(params); - SCOPED_TRACE(formatString("Comparing normal and rerun of simulation '%s' " - "with integrator '%s'", - simulationName.c_str(), integrator.c_str())); + SCOPED_TRACE( + formatString("Comparing normal and rerun of simulation '%s' " + "with integrator '%s'", + simulationName.c_str(), integrator.c_str())); - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - "no", "no"); + auto mdpFieldValues = + prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no"); // bd is much less reproducible in a rerun than the other integrators const int toleranceScaleFactor = (integrator == "bd") ? 2 : 1; - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, - relativeToleranceAsPrecisionDependentUlp(10.0, 24 * toleranceScaleFactor, 40 * toleranceScaleFactor) - }, - }}; + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, + relativeToleranceAsPrecisionDependentUlp(10.0, 24 * toleranceScaleFactor, + 40 * toleranceScaleFactor) }, + } }; // Specify how trajectory frame matching must work - TrajectoryComparison trajectoryComparison { - trajectoryMatchSettings, TrajectoryComparison::s_defaultTrajectoryTolerances - }; + TrajectoryComparison trajectoryComparison{ trajectoryMatchSettings, + TrajectoryComparison::s_defaultTrajectoryTolerances }; int numWarningsToTolerate = 0; - executeRerunTest(&fileManager_, &runner_, - simulationName, numWarningsToTolerate, mdpFieldValues, + executeRerunTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues, energyTermsToCompare, trajectoryComparison); } @@ -141,18 +138,22 @@ TEST_P(MdrunRerunTest, WithinTolerances) // out. Once that compilation is cached for the whole process, these // tests can run in such configurations. #if GMX_GPU != GMX_GPU_OPENCL -INSTANTIATE_TEST_CASE_P(NormalMdrunIsReproduced, MdrunRerunTest, - ::testing::Combine(::testing::Values("argon12", "tip3p5", "alanine_vsite_vacuo"), - ::testing::Values("md", "md-vv", "bd", "sd"))); +INSTANTIATE_TEST_CASE_P( + NormalMdrunIsReproduced, + MdrunRerunTest, + ::testing::Combine(::testing::Values("argon12", "tip3p5", "alanine_vsite_vacuo"), + ::testing::Values("md", "md-vv", "bd", "sd"))); #else -INSTANTIATE_TEST_CASE_P(DISABLED_NormalMdrunIsReproduced, MdrunRerunTest, - ::testing::Combine(::testing::Values("argon12", "tip3p5", "alanine_vsite_vacuo"), - ::testing::Values("md", "md-vv", "bd", "sd"))); +INSTANTIATE_TEST_CASE_P( + DISABLED_NormalMdrunIsReproduced, + MdrunRerunTest, + ::testing::Combine(::testing::Values("argon12", "tip3p5", "alanine_vsite_vacuo"), + ::testing::Values("md", "md-vv", "bd", "sd"))); #endif -class MdrunRerunFreeEnergyTest : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string, int>> +class MdrunRerunFreeEnergyTest : + public MdrunTestFixture, + public ::testing::WithParamInterface> { }; @@ -162,44 +163,33 @@ TEST_P(MdrunRerunFreeEnergyTest, WithinTolerances) auto simulationName = std::get<0>(params); auto integrator = std::get<1>(params); auto initLambdaState = std::get<2>(params); - SCOPED_TRACE(formatString("Comparing normal and rerun of simulation '%s' " - "with integrator '%s' for initial lambda state %d", - simulationName.c_str(), integrator.c_str(), initLambdaState)); + SCOPED_TRACE( + formatString("Comparing normal and rerun of simulation '%s' " + "with integrator '%s' for initial lambda state %d", + simulationName.c_str(), integrator.c_str(), initLambdaState)); - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - "no", "no"); + auto mdpFieldValues = + prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no"); mdpFieldValues["other"] += formatString("\ninit-lambda-state = %d", initLambdaState); - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 24, 32) - }, - { - interaction_function[F_DVDL_COUL].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) - }, - { - interaction_function[F_DVDL_VDW].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) - }, - { - interaction_function[F_DVDL_BONDED].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) - }, - { - interaction_function[F_DVDL_RESTRAINT].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) - } - }}; + EnergyTermsToCompare energyTermsToCompare{ + { { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 24, 32) }, + { interaction_function[F_DVDL_COUL].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) }, + { interaction_function[F_DVDL_VDW].longname, relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) }, + { interaction_function[F_DVDL_BONDED].longname, + relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) }, + { interaction_function[F_DVDL_RESTRAINT].longname, + relativeToleranceAsPrecisionDependentUlp(1.0, 8, 8) } } + }; // Specify how trajectory frame matching must work - TrajectoryComparison trajectoryComparison { - MdrunRerunTest::trajectoryMatchSettings, TrajectoryComparison::s_defaultTrajectoryTolerances - }; + TrajectoryComparison trajectoryComparison{ MdrunRerunTest::trajectoryMatchSettings, + TrajectoryComparison::s_defaultTrajectoryTolerances }; // The md integrator triggers a warning for nearly decoupled // states, which we need to suppress. TODO sometimes? int numWarningsToTolerate = (integrator == "md") ? 1 : 0; - executeRerunTest(&fileManager_, &runner_, - simulationName, numWarningsToTolerate, mdpFieldValues, + executeRerunTest(&fileManager_, &runner_, simulationName, numWarningsToTolerate, mdpFieldValues, energyTermsToCompare, trajectoryComparison); } @@ -207,15 +197,17 @@ TEST_P(MdrunRerunFreeEnergyTest, WithinTolerances) // out. Once that compilation is cached for the whole process, these // tests can run in such configurations. #if GMX_GPU != GMX_GPU_OPENCL -INSTANTIATE_TEST_CASE_P(MdrunIsReproduced, MdrunRerunFreeEnergyTest, - ::testing::Combine(::testing::Values("nonanol_vacuo"), - ::testing::Values("md", "md-vv", "sd"), - ::testing::Range(0, 11))); +INSTANTIATE_TEST_CASE_P(MdrunIsReproduced, + MdrunRerunFreeEnergyTest, + ::testing::Combine(::testing::Values("nonanol_vacuo"), + ::testing::Values("md", "md-vv", "sd"), + ::testing::Range(0, 11))); #else -INSTANTIATE_TEST_CASE_P(DISABLED_MdrunIsReproduced, MdrunRerunFreeEnergyTest, - ::testing::Combine(::testing::Values("nonanol_vacuo"), - ::testing::Values("md", "md-vv", "sd"), - ::testing::Range(0, 11))); +INSTANTIATE_TEST_CASE_P(DISABLED_MdrunIsReproduced, + MdrunRerunFreeEnergyTest, + ::testing::Combine(::testing::Values("nonanol_vacuo"), + ::testing::Values("md", "md-vv", "sd"), + ::testing::Range(0, 11))); #endif } // namespace diff --git a/src/programs/mdrun/tests/simple_mdrun.cpp b/src/programs/mdrun/tests/simple_mdrun.cpp index d45b50db85..3eb08d53ba 100644 --- a/src/programs/mdrun/tests/simple_mdrun.cpp +++ b/src/programs/mdrun/tests/simple_mdrun.cpp @@ -78,23 +78,15 @@ namespace { /*! \brief Database of enerngy tolerances for MD integrator on the various systems. */ -std::unordered_map energyToleranceForSystem_g = -{{ - { - "angles1", - relativeToleranceAsFloatingPoint(1, 1e-4) - } - }}; +std::unordered_map energyToleranceForSystem_g = { + { { "angles1", relativeToleranceAsFloatingPoint(1, 1e-4) } } +}; /*! \brief Database of pressure tolerances for MD integrator on the various systems. */ -std::unordered_map pressureToleranceForSystem_g = -{{ - { - "angles1", - relativeToleranceAsFloatingPoint(1, 1e-4) - } - }}; +std::unordered_map pressureToleranceForSystem_g = { + { { "angles1", relativeToleranceAsFloatingPoint(1, 1e-4) } } +}; //! Helper type using MdpField = MdpFieldValues::value_type; @@ -105,9 +97,9 @@ using MdpField = MdpFieldValues::value_type; * reproducible energies. * * The choices for tolerance are arbitrary but sufficient. */ -class SimpleMdrunTest : public MdrunTestFixture, - public ::testing::WithParamInterface < - std::tuple < std::string, std::string>> +class SimpleMdrunTest : + public MdrunTestFixture, + public ::testing::WithParamInterface> { }; @@ -116,22 +108,21 @@ TEST_P(SimpleMdrunTest, WithinTolerances) auto params = GetParam(); auto simulationName = std::get<0>(params); auto integrator = std::get<1>(params); - SCOPED_TRACE(formatString("Comparing simple mdrun for '%s'", - simulationName.c_str())); + SCOPED_TRACE(formatString("Comparing simple mdrun for '%s'", simulationName.c_str())); // TODO At some point we should also test PME-only ranks. int numRanksAvailable = getNumberOfTestMpiRanks(); if (!isNumberOfPpRanksSupported(simulationName, numRanksAvailable)) { - fprintf(stdout, "Test system '%s' cannot run with %d ranks.\n" + fprintf(stdout, + "Test system '%s' cannot run with %d ranks.\n" "The supported numbers are: %s\n", simulationName.c_str(), numRanksAvailable, reportNumbersOfPpRanksSupported(simulationName).c_str()); return; } - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - "no", "no"); + auto mdpFieldValues = + prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), "no", "no"); mdpFieldValues["nsteps"] = "50"; mdpFieldValues["nstfout"] = "4"; mdpFieldValues["constraints"] = "none"; @@ -148,27 +139,18 @@ TEST_P(SimpleMdrunTest, WithinTolerances) } // Do mdrun { - CommandLine mdrunCaller; + CommandLine mdrunCaller; ASSERT_EQ(0, runner_.callMdrun(mdrunCaller)); - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, energyToleranceForSystem_g.at(simulationName) - }, - { - interaction_function[F_EKIN].longname, energyToleranceForSystem_g.at(simulationName) - }, - { - interaction_function[F_PRES].longname, pressureToleranceForSystem_g.at(simulationName) - }, - }}; - TestReferenceData refData; - auto checker = refData.rootChecker() - .checkCompound("Simulation", simulationName) - .checkCompound("Mdrun", integrator); - checkEnergiesAgainstReferenceData(runner_.edrFileName_, - energyTermsToCompare, - &checker); + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, energyToleranceForSystem_g.at(simulationName) }, + { interaction_function[F_EKIN].longname, energyToleranceForSystem_g.at(simulationName) }, + { interaction_function[F_PRES].longname, pressureToleranceForSystem_g.at(simulationName) }, + } }; + TestReferenceData refData; + auto checker = refData.rootChecker() + .checkCompound("Simulation", simulationName) + .checkCompound("Mdrun", integrator); + checkEnergiesAgainstReferenceData(runner_.edrFileName_, energyTermsToCompare, &checker); // Now check the forces TrajectoryFrameReader reader(runner_.fullPrecisionTrajectoryFileName_); checker.setDefaultTolerance(relativeToleranceAsFloatingPoint(1, 1e-4)); @@ -177,15 +159,14 @@ TEST_P(SimpleMdrunTest, WithinTolerances) auto frame = reader.frame(); auto force = frame.f(); int atom = 0; - for (auto &f : force) + for (auto& f : force) { std::string forceName = frame.frameName() + " F[" + toString(atom) + "]"; checker.checkVector(f, forceName.c_str()); atom++; } - } - while (reader.readNextFrame()); + } while (reader.readNextFrame()); } } @@ -201,7 +182,9 @@ std::vector md_g = { "md", "md-vv" }; // lifetime of the whole test binary process, these tests should run in // such configurations. #if GMX_DOUBLE -INSTANTIATE_TEST_CASE_P(Angles1, SimpleMdrunTest, ::testing::Combine(::testing::ValuesIn(systemsToTest_g), ::testing::ValuesIn(md_g))); +INSTANTIATE_TEST_CASE_P(Angles1, + SimpleMdrunTest, + ::testing::Combine(::testing::ValuesIn(systemsToTest_g), ::testing::ValuesIn(md_g))); #endif } // namespace } // namespace test diff --git a/src/programs/mdrun/tests/simulator.cpp b/src/programs/mdrun/tests/simulator.cpp index cb59293650..f49d0bb55d 100644 --- a/src/programs/mdrun/tests/simulator.cpp +++ b/src/programs/mdrun/tests/simulator.cpp @@ -68,12 +68,11 @@ namespace * are correct, and that different code paths expected to yield identical results * are equivalent. */ -using SimulatorComparisonTestParams = std::tuple< - std::tuple < std::string, std::string, std::string, std::string>, - std::string>; +using SimulatorComparisonTestParams = + std::tuple, std::string>; class SimulatorComparisonTest : public MdrunTestFixture, - public ::testing::WithParamInterface < SimulatorComparisonTestParams > + public ::testing::WithParamInterface { }; @@ -94,60 +93,42 @@ TEST_P(SimulatorComparisonTest, WithinTolerances) return; } - SCOPED_TRACE(formatString("Comparing two simulations of '%s' " - "with integrator '%s' and '%s' temperature coupling, " - "switching environment variable '%s'", - simulationName.c_str(), integrator.c_str(), - tcoupling.c_str(), envVariable.c_str())); - - auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), - integrator.c_str(), - tcoupling.c_str(), - pcoupling.c_str()); - - EnergyTermsToCompare energyTermsToCompare - {{ - { - interaction_function[F_EPOT].longname, - relativeToleranceAsPrecisionDependentUlp(10.0, 100, 40) - }, - { - interaction_function[F_EKIN].longname, - relativeToleranceAsPrecisionDependentUlp(60.0, 100, 40) - }, - { - interaction_function[F_PRES].longname, - relativeToleranceAsPrecisionDependentFloatingPoint(10.0, 0.01, 0.001) - }, - }}; + SCOPED_TRACE(formatString( + "Comparing two simulations of '%s' " + "with integrator '%s' and '%s' temperature coupling, " + "switching environment variable '%s'", + simulationName.c_str(), integrator.c_str(), tcoupling.c_str(), envVariable.c_str())); + + auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(), integrator.c_str(), + tcoupling.c_str(), pcoupling.c_str()); + + EnergyTermsToCompare energyTermsToCompare{ { + { interaction_function[F_EPOT].longname, relativeToleranceAsPrecisionDependentUlp(10.0, 100, 40) }, + { interaction_function[F_EKIN].longname, relativeToleranceAsPrecisionDependentUlp(60.0, 100, 40) }, + { interaction_function[F_PRES].longname, + relativeToleranceAsPrecisionDependentFloatingPoint(10.0, 0.01, 0.001) }, + } }; if (simulationName == "argon12") { // Without constraints, we can be more strict - energyTermsToCompare = - {{ - { - interaction_function[F_EPOT].longname, - relativeToleranceAsPrecisionDependentUlp(10.0, 24, 40) - }, - { - interaction_function[F_EKIN].longname, - relativeToleranceAsPrecisionDependentUlp(10.0, 24, 40) - }, - { - interaction_function[F_PRES].longname, - relativeToleranceAsPrecisionDependentFloatingPoint(10.0, 0.001, 0.0001) - }, - }}; + energyTermsToCompare = { { + { interaction_function[F_EPOT].longname, + relativeToleranceAsPrecisionDependentUlp(10.0, 24, 40) }, + { interaction_function[F_EKIN].longname, + relativeToleranceAsPrecisionDependentUlp(10.0, 24, 40) }, + { interaction_function[F_PRES].longname, + relativeToleranceAsPrecisionDependentFloatingPoint(10.0, 0.001, 0.0001) }, + } }; } // Specify how trajectory frame matching must work. - TrajectoryFrameMatchSettings trajectoryMatchSettings { - true, true, true, - ComparisonConditions::MustCompare, - ComparisonConditions::MustCompare, - ComparisonConditions::MustCompare - }; + TrajectoryFrameMatchSettings trajectoryMatchSettings{ true, + true, + true, + ComparisonConditions::MustCompare, + ComparisonConditions::MustCompare, + ComparisonConditions::MustCompare }; TrajectoryTolerances trajectoryTolerances = TrajectoryComparison::s_defaultTrajectoryTolerances; if (simulationName != "argon12") { @@ -156,18 +137,12 @@ TEST_P(SimulatorComparisonTest, WithinTolerances) // Build the functor that will compare reference and test // trajectory frames in the chosen way. - TrajectoryComparison trajectoryComparison { - trajectoryMatchSettings, trajectoryTolerances - }; + TrajectoryComparison trajectoryComparison{ trajectoryMatchSettings, trajectoryTolerances }; int numWarningsToTolerate = 0; - executeSimulatorComparisonTest( - envVariable, - &fileManager_, &runner_, - simulationName, numWarningsToTolerate, - mdpFieldValues, - energyTermsToCompare, - trajectoryComparison); + executeSimulatorComparisonTest(envVariable, &fileManager_, &runner_, simulationName, + numWarningsToTolerate, mdpFieldValues, energyTermsToCompare, + trajectoryComparison); } // TODO: The time for OpenCL kernel compilation means these tests time @@ -176,35 +151,37 @@ TEST_P(SimulatorComparisonTest, WithinTolerances) // These tests are very sensitive, so we only run them in double precision. // As we change call ordering, they might actually become too strict to be useful. #if GMX_GPU != GMX_GPU_OPENCL && GMX_DOUBLE -INSTANTIATE_TEST_CASE_P(SimulatorsAreEquivalentDefaultModular, SimulatorComparisonTest, - ::testing::Combine( - ::testing::Combine(::testing::Values("argon12", "tip3p5"), - ::testing::Values("md-vv"), - ::testing::Values("no", "v-rescale"), - ::testing::Values("no")), - ::testing::Values("GMX_DISABLE_MODULAR_SIMULATOR"))); -INSTANTIATE_TEST_CASE_P(SimulatorsAreEquivalentDefaultLegacy, SimulatorComparisonTest, - ::testing::Combine( - ::testing::Combine(::testing::Values("argon12", "tip3p5"), - ::testing::Values("md"), - ::testing::Values("no", "v-rescale"), - ::testing::Values("no", "Parrinello-Rahman")), - ::testing::Values("GMX_USE_MODULAR_SIMULATOR"))); +INSTANTIATE_TEST_CASE_P(SimulatorsAreEquivalentDefaultModular, + SimulatorComparisonTest, + ::testing::Combine(::testing::Combine(::testing::Values("argon12", "tip3p5"), + ::testing::Values("md-vv"), + ::testing::Values("no", "v-rescale"), + ::testing::Values("no")), + ::testing::Values("GMX_DISABLE_MODULAR_SIMULATOR"))); +INSTANTIATE_TEST_CASE_P( + SimulatorsAreEquivalentDefaultLegacy, + SimulatorComparisonTest, + ::testing::Combine(::testing::Combine(::testing::Values("argon12", "tip3p5"), + ::testing::Values("md"), + ::testing::Values("no", "v-rescale"), + ::testing::Values("no", "Parrinello-Rahman")), + ::testing::Values("GMX_USE_MODULAR_SIMULATOR"))); #else -INSTANTIATE_TEST_CASE_P(DISABLED_SimulatorsAreEquivalentDefaultModular, SimulatorComparisonTest, - ::testing::Combine( - ::testing::Combine(::testing::Values("argon12", "tip3p5"), - ::testing::Values("md-vv"), - ::testing::Values("no", "v-rescale"), - ::testing::Values("no")), - ::testing::Values("GMX_DISABLE_MODULAR_SIMULATOR"))); -INSTANTIATE_TEST_CASE_P(DISABLED_SimulatorsAreEquivalentDefaultLegacy, SimulatorComparisonTest, - ::testing::Combine( - ::testing::Combine(::testing::Values("argon12", "tip3p5"), - ::testing::Values("md"), - ::testing::Values("no", "v-rescale"), - ::testing::Values("no", "Parrinello-Rahman")), - ::testing::Values("GMX_USE_MODULAR_SIMULATOR"))); +INSTANTIATE_TEST_CASE_P(DISABLED_SimulatorsAreEquivalentDefaultModular, + SimulatorComparisonTest, + ::testing::Combine(::testing::Combine(::testing::Values("argon12", "tip3p5"), + ::testing::Values("md-vv"), + ::testing::Values("no", "v-rescale"), + ::testing::Values("no")), + ::testing::Values("GMX_DISABLE_MODULAR_SIMULATOR"))); +INSTANTIATE_TEST_CASE_P( + DISABLED_SimulatorsAreEquivalentDefaultLegacy, + SimulatorComparisonTest, + ::testing::Combine(::testing::Combine(::testing::Values("argon12", "tip3p5"), + ::testing::Values("md"), + ::testing::Values("no", "v-rescale"), + ::testing::Values("no", "Parrinello-Rahman")), + ::testing::Values("GMX_USE_MODULAR_SIMULATOR"))); #endif } // namespace diff --git a/src/programs/mdrun/tests/simulatorcomparison.cpp b/src/programs/mdrun/tests/simulatorcomparison.cpp index 20c17df342..816ce6fb6b 100644 --- a/src/programs/mdrun/tests/simulatorcomparison.cpp +++ b/src/programs/mdrun/tests/simulatorcomparison.cpp @@ -63,22 +63,22 @@ namespace { //! Run grompp and mdrun for both sets of mdp field values -template -void executeSimulatorComparisonTestImpl( - TestFileManager *fileManager, - SimulationRunner *runner, - const std::string &simulationName, - int maxWarningsTolerated, - const MdpFieldValues &mdpFieldValues, - const EnergyTermsToCompare &energyTermsToCompare, - const TrajectoryComparison &trajectoryComparison, - const std::string &environmentVariable) +template +void executeSimulatorComparisonTestImpl(TestFileManager* fileManager, + SimulationRunner* runner, + const std::string& simulationName, + int maxWarningsTolerated, + const MdpFieldValues& mdpFieldValues, + const EnergyTermsToCompare& energyTermsToCompare, + const TrajectoryComparison& trajectoryComparison, + const std::string& environmentVariable) { // TODO At some point we should also test PME-only ranks. int numRanksAvailable = getNumberOfTestMpiRanks(); if (!isNumberOfPpRanksSupported(simulationName, numRanksAvailable)) { - fprintf(stdout, "Test system '%s' cannot run with %d ranks.\n" + fprintf(stdout, + "Test system '%s' cannot run with %d ranks.\n" "The supported numbers are: %s\n", simulationName.c_str(), numRanksAvailable, reportNumbersOfPpRanksSupported(simulationName).c_str()); @@ -104,7 +104,7 @@ void executeSimulatorComparisonTestImpl( EXPECT_EQ(0, runner->callGrompp(caller)); } - char *environmentVariableBackup = nullptr; + char* environmentVariableBackup = nullptr; if (doEnvironmentVariable) { // save state of environment variable @@ -167,38 +167,33 @@ void executeSimulatorComparisonTestImpl( // // TODO Here is an unnecessary copy of keys (ie. the energy term // names), for convenience. In the future, use a range. - auto namesOfEnergiesToMatch = energyComparison.getEnergyNames(); - FramePairManager - energyManager( + auto namesOfEnergiesToMatch = energyComparison.getEnergyNames(); + FramePairManager energyManager( openEnergyFileToReadTerms(simulator1EdrFileName, namesOfEnergiesToMatch), openEnergyFileToReadTerms(simulator2EdrFileName, namesOfEnergiesToMatch)); // Compare the energy frames. energyManager.compareAllFramePairs(energyComparison); // Build the manager that will present matching pairs of frames to compare - FramePairManager - trajectoryManager(std::make_unique(simulator1TrajectoryFileName), - std::make_unique(simulator2TrajectoryFileName)); + FramePairManager trajectoryManager( + std::make_unique(simulator1TrajectoryFileName), + std::make_unique(simulator2TrajectoryFileName)); // Compare the trajectory frames. trajectoryManager.compareAllFramePairs(trajectoryComparison); } -} // namespace +} // namespace -template -void executeSimulatorComparisonTest( - const std::string &environmentVariable, - Args && ... args) +template +void executeSimulatorComparisonTest(const std::string& environmentVariable, Args&&... args) { - executeSimulatorComparisonTestImpl( - std::forward(args) ..., environmentVariable); + executeSimulatorComparisonTestImpl(std::forward(args)..., environmentVariable); } -template -void executeRerunTest(Args && ... args) +template +void executeRerunTest(Args&&... args) { - executeSimulatorComparisonTestImpl( - std::forward(args) ..., ""); + executeSimulatorComparisonTestImpl(std::forward(args)..., ""); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/simulatorcomparison.h b/src/programs/mdrun/tests/simulatorcomparison.h index 2ac0811398..b0e7843d96 100644 --- a/src/programs/mdrun/tests/simulatorcomparison.h +++ b/src/programs/mdrun/tests/simulatorcomparison.h @@ -58,10 +58,8 @@ namespace test * Run grompp, and repeat mdrun with and without the environment variable set. * Compare energies (via EnergyComparator) and trajectories. */ -template -void executeSimulatorComparisonTest( - const std::string &environmentVariable, - Args && ... args); +template +void executeSimulatorComparisonTest(const std::string& environmentVariable, Args&&... args); /*! * \brief Run and compare a simulator run to its rerun @@ -69,11 +67,11 @@ void executeSimulatorComparisonTest( * Run grompp, run mdrun and rerun the resulting trajectory. * Compare energies (via EnergyComparator) and trajectories. */ -template -void executeRerunTest(Args && ... args); +template +void executeRerunTest(Args&&... args); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx // Including this here avoid having to put everything in the header file, // or to explicitly declare the templates (which would render the parameter diff --git a/src/programs/mdrun/tests/swapcoords.cpp b/src/programs/mdrun/tests/swapcoords.cpp index 40390a0a04..4be89e7fda 100644 --- a/src/programs/mdrun/tests/swapcoords.cpp +++ b/src/programs/mdrun/tests/swapcoords.cpp @@ -51,20 +51,15 @@ namespace test class SwapTestFixture : public MdrunTestFixture { - protected: - SwapTestFixture(); - ~SwapTestFixture() override; +protected: + SwapTestFixture(); + ~SwapTestFixture() override; }; -SwapTestFixture::SwapTestFixture() -{ -} - -SwapTestFixture::~SwapTestFixture() -{ -} +SwapTestFixture::SwapTestFixture() {} +SwapTestFixture::~SwapTestFixture() {} //! Test fixture for mdrun with "Computational Electrophysiology" settings, @@ -134,7 +129,6 @@ TEST_F(CompelTest, SwapCanRun) } - /*! \todo Add other tests for the compel module, e.g. * * - a test that checks that actually ion/water swaps have been done, by diff --git a/src/programs/mdrun/tests/tabulated_bonded_interactions.cpp b/src/programs/mdrun/tests/tabulated_bonded_interactions.cpp index d57ee7b017..7eda22e90e 100644 --- a/src/programs/mdrun/tests/tabulated_bonded_interactions.cpp +++ b/src/programs/mdrun/tests/tabulated_bonded_interactions.cpp @@ -57,7 +57,8 @@ namespace test { //! Format string for building a configurable .top file -static const char *g_butaneTopFileFormatString = "\ +static const char* g_butaneTopFileFormatString = + "\ [ defaults ]\n\ ; nbfunc comb-rule gen-pairs fudgeLJ fudgeQQ\n\ 1 1 no 1.0 1.0\n\ @@ -92,36 +93,38 @@ Butane 1\n\ //! Test fixture for bonded interactions class BondedInteractionsTest : public gmx::test::MdrunTestFixture { - public: - //! Execute the trajectory writing test - void setupGrompp(const char *interaction) - { - runner_.topFileName_ = fileManager_.getTemporaryFilePath("butane1.top"); - TextWriter::writeFileFromString(runner_.topFileName_, formatString(g_butaneTopFileFormatString, interaction)); - runner_.groFileName_ = gmx::test::TestFileManager::getInputFilePath("butane1.gro"); - runner_.ndxFileName_ = gmx::test::TestFileManager::getInputFilePath("butane1.ndx"); - runner_.useEmptyMdpFile(); - } - //! Prepare an mdrun caller - CommandLine setupMdrun() - { - CommandLine rerunCaller; - rerunCaller.append("mdrun"); - rerunCaller.addOption("-rerun", runner_.groFileName_); - return rerunCaller; - } - //! Check the output of mdrun - void checkMdrun() - { - // TODO verifying some energies and forces would be good, - // once other code in gerrit is reviewed - } +public: + //! Execute the trajectory writing test + void setupGrompp(const char* interaction) + { + runner_.topFileName_ = fileManager_.getTemporaryFilePath("butane1.top"); + TextWriter::writeFileFromString(runner_.topFileName_, + formatString(g_butaneTopFileFormatString, interaction)); + runner_.groFileName_ = gmx::test::TestFileManager::getInputFilePath("butane1.gro"); + runner_.ndxFileName_ = gmx::test::TestFileManager::getInputFilePath("butane1.ndx"); + runner_.useEmptyMdpFile(); + } + //! Prepare an mdrun caller + CommandLine setupMdrun() + { + CommandLine rerunCaller; + rerunCaller.append("mdrun"); + rerunCaller.addOption("-rerun", runner_.groFileName_); + return rerunCaller; + } + //! Check the output of mdrun + void checkMdrun() + { + // TODO verifying some energies and forces would be good, + // once other code in gerrit is reviewed + } }; // This test ensures that a normal non-tabulated bond interaction works TEST_F(BondedInteractionsTest, NormalBondWorks) { - setupGrompp("[ bonds ]\n\ + setupGrompp( + "[ bonds ]\n\ ; ai aj funct c0 c1\n\ 1 2 1 1.530000e-01 3.347000e+05"); EXPECT_EQ(0, runner_.callGrompp()); @@ -134,7 +137,8 @@ TEST_F(BondedInteractionsTest, NormalBondWorks) // This test ensures that a normal abulated bond interaction works TEST_F(BondedInteractionsTest, TabulatedBondWorks) { - setupGrompp("[ bonds ]\n\ + setupGrompp( + "[ bonds ]\n\ ; ai aj funct n k\n\ 1 2 8 0 1000"); EXPECT_EQ(0, runner_.callGrompp()); @@ -149,7 +153,8 @@ TEST_F(BondedInteractionsTest, TabulatedBondWorks) // This test ensures that a normal non-tabulated angle interaction works TEST_F(BondedInteractionsTest, NormalAngleWorks) { - setupGrompp("[ angles ]\n\ + setupGrompp( + "[ angles ]\n\ ; ai aj ak funct c0 c1\n\ 1 2 3 1 1.110000e+02 4.602000e+02"); EXPECT_EQ(0, runner_.callGrompp()); @@ -162,7 +167,8 @@ TEST_F(BondedInteractionsTest, NormalAngleWorks) // This test ensures that a tabulated angle interaction works TEST_F(BondedInteractionsTest, TabulatedAngleWorks) { - setupGrompp("[ angles ]\n\ + setupGrompp( + "[ angles ]\n\ ; ai aj ak funct n k\n\ 1 2 3 8 0 1000"); EXPECT_EQ(0, runner_.callGrompp()); @@ -177,7 +183,8 @@ TEST_F(BondedInteractionsTest, TabulatedAngleWorks) // This test ensures that a normal non-tabulated dihedral interaction works TEST_F(BondedInteractionsTest, NormalDihedralWorks) { - setupGrompp("[ dihedrals ]\n \ + setupGrompp( + "[ dihedrals ]\n \ ; ai aj ak al funct c0 c1 c2 c3 c4 c5\n\ 1 2 3 4 3 9.2789 12.156 -13.12 -3.0597 26.24 -31.495"); EXPECT_EQ(0, runner_.callGrompp()); @@ -190,7 +197,8 @@ TEST_F(BondedInteractionsTest, NormalDihedralWorks) // This test ensures that a tabulated dihedral interaction works TEST_F(BondedInteractionsTest, TabulatedDihedralWorks) { - setupGrompp("[ dihedrals ]\n\ + setupGrompp( + "[ dihedrals ]\n\ ; ai aj ak al funct n k\n\ 1 2 3 4 8 0 1000"); EXPECT_EQ(0, runner_.callGrompp()); @@ -202,6 +210,6 @@ TEST_F(BondedInteractionsTest, TabulatedDihedralWorks) checkMdrun(); } -} // namespace test +} // namespace test -} // namespace gmx +} // namespace gmx diff --git a/src/programs/mdrun/tests/termination.cpp b/src/programs/mdrun/tests/termination.cpp index 7455b51489..beb6d33bd8 100644 --- a/src/programs/mdrun/tests/termination.cpp +++ b/src/programs/mdrun/tests/termination.cpp @@ -66,16 +66,16 @@ namespace test { //! Build a simple .mdp file -static void organizeMdpFile(SimulationRunner *runner, - int nsteps = 2) +static void organizeMdpFile(SimulationRunner* runner, int nsteps = 2) { // Make sure -maxh has a chance to propagate - runner->useStringAsMdpFile(formatString("nsteps = %d\n" - "tcoupl = v-rescale\n" - "tc-grps = System\n" - "tau-t = 1\n" - "ref-t = 298\n", - nsteps)); + runner->useStringAsMdpFile( + formatString("nsteps = %d\n" + "tcoupl = v-rescale\n" + "tc-grps = System\n" + "tau-t = 1\n" + "ref-t = 298\n", + nsteps)); } //! Convenience typedef @@ -95,8 +95,8 @@ TEST_F(MdrunTerminationTest, CheckpointRestartAppendsByDefault) firstPart.append("mdrun"); firstPart.addOption("-cpo", runner_.cptFileName_); ASSERT_EQ(0, runner_.callMdrun(firstPart)); - ASSERT_TRUE(File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found and should be"; + ASSERT_TRUE(File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found and should be"; } SCOPED_TRACE("Running the second simulation part with default appending behavior"); { @@ -108,7 +108,10 @@ TEST_F(MdrunTerminationTest, CheckpointRestartAppendsByDefault) ASSERT_EQ(0, runner_.callMdrun(secondPart)); auto logFileContents = TextReader::readFileToString(runner_.logFileName_); - EXPECT_NE(std::string::npos, logFileContents.find("Restarting from checkpoint, appending to previous log file")) << "appending was not detected"; + EXPECT_NE( + std::string::npos, + logFileContents.find("Restarting from checkpoint, appending to previous log file")) + << "appending was not detected"; } } @@ -133,8 +136,8 @@ TEST_F(MdrunTerminationTest, WritesCheckpointAfterMaxhTerminationAndThenRestarts firstPart.addOption("-maxh", 1e-7); firstPart.addOption("-nstlist", 1); ASSERT_EQ(0, runner_.callMdrun(firstPart)); - EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found"; + EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found"; } SCOPED_TRACE("Running the second simulation part"); @@ -147,7 +150,8 @@ TEST_F(MdrunTerminationTest, WritesCheckpointAfterMaxhTerminationAndThenRestarts ASSERT_EQ(0, runner_.callMdrun(secondPart)); auto logFileContents = TextReader::readFileToString(runner_.logFileName_); - EXPECT_NE(std::string::npos, logFileContents.find("Writing checkpoint, step 102")) << "completion of restarted simulation was not detected"; + EXPECT_NE(std::string::npos, logFileContents.find("Writing checkpoint, step 102")) + << "completion of restarted simulation was not detected"; } } @@ -165,8 +169,8 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWithNoAppendWorksAndCannotLaterApp firstPart.append("mdrun"); firstPart.addOption("-cpo", runner_.cptFileName_); ASSERT_EQ(0, runner_.callMdrun(firstPart)); - EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found"; + EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found"; } SCOPED_TRACE("Running the second simulation part with -noappend"); @@ -181,11 +185,11 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWithNoAppendWorksAndCannotLaterApp ASSERT_EQ(0, runner_.callMdrun(secondPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0002.log"); - ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0002.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; } SCOPED_TRACE("Running the third simulation part with -append, which will fail"); @@ -211,11 +215,11 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWithNoAppendWorksAndCannotLaterApp ASSERT_EQ(0, runner_.callMdrun(thirdPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0003.log"); - EXPECT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + EXPECT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0003.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; } SCOPED_TRACE("Running the fourth simulation part with default appending"); runner_.changeTprNsteps(8); @@ -231,11 +235,11 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWithNoAppendWorksAndCannotLaterApp ASSERT_EQ(0, runner_.callMdrun(fourthPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0004.log"); - ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0004.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; } SCOPED_TRACE("Running the fifth simulation part with no extra steps"); { @@ -250,11 +254,11 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWithNoAppendWorksAndCannotLaterApp ASSERT_EQ(0, runner_.callMdrun(fifthPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0005.log"); - ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0005.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; } } @@ -272,8 +276,8 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWorksEvenWithMissingCheckpointFile firstPart.append("mdrun"); firstPart.addOption("-cpo", runner_.cptFileName_); ASSERT_EQ(0, runner_.callMdrun(firstPart)); - EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found"; + EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found"; } SCOPED_TRACE("Running the second simulation part after deleting the checkpoint file"); @@ -293,7 +297,10 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWorksEvenWithMissingCheckpointFile ASSERT_EQ(0, runner_.callMdrun(secondPart)); auto logFileContents = TextReader::readFileToString(runner_.logFileName_); - EXPECT_EQ(std::string::npos, logFileContents.find("Restarting from checkpoint, appending to previous log file")) << "appending was not detected"; + EXPECT_EQ( + std::string::npos, + logFileContents.find("Restarting from checkpoint, appending to previous log file")) + << "appending was not detected"; } } @@ -311,11 +318,12 @@ TEST_F(MdrunTerminationTest, CheckpointRestartWorksEvenWithAppendAndMissingCheck firstPart.append("mdrun"); firstPart.addOption("-cpo", runner_.cptFileName_); ASSERT_EQ(0, runner_.callMdrun(firstPart)); - EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found"; + EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found"; } - SCOPED_TRACE("Running the second simulation part with -append after deleting the checkpoint file"); + SCOPED_TRACE( + "Running the second simulation part with -append after deleting the checkpoint file"); { runner_.changeTprNsteps(4); @@ -349,13 +357,13 @@ TEST_F(MdrunTerminationTest, RunWithNoAppendCreatesPartFiles) firstPart.append("-noappend"); ASSERT_EQ(0, runner_.callMdrun(firstPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0001.log"); - ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0001.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; - EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) << - runner_.cptFileName_ << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; + EXPECT_EQ(true, File::exists(runner_.cptFileName_, File::returnFalseOnError)) + << runner_.cptFileName_ << " was not found"; } SCOPED_TRACE("Running the second simulation part with -noappend"); @@ -370,13 +378,13 @@ TEST_F(MdrunTerminationTest, RunWithNoAppendCreatesPartFiles) ASSERT_EQ(0, runner_.callMdrun(secondPart)); auto expectedLogFileName = fileManager_.getTemporaryFilePath(".part0002.log"); - ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) << - expectedLogFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedLogFileName, File::returnFalseOnError)) + << expectedLogFileName << " was not found"; auto expectedEdrFileName = fileManager_.getTemporaryFilePath(".part0002.edr"); - ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) << - expectedEdrFileName << " was not found"; + ASSERT_EQ(true, File::exists(expectedEdrFileName, File::returnFalseOnError)) + << expectedEdrFileName << " was not found"; } } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/terminationhelper.cpp b/src/programs/mdrun/tests/terminationhelper.cpp index 8f2dbc4257..06afc5b658 100644 --- a/src/programs/mdrun/tests/terminationhelper.cpp +++ b/src/programs/mdrun/tests/terminationhelper.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,16 +55,17 @@ namespace gmx namespace test { -TerminationHelper::TerminationHelper(TestFileManager *fileManager, - CommandLine *mdrunCaller, - SimulationRunner *runner) - : mdrunCaller_(mdrunCaller), runner_(runner) +TerminationHelper::TerminationHelper(TestFileManager* fileManager, + CommandLine* mdrunCaller, + SimulationRunner* runner) : + mdrunCaller_(mdrunCaller), + runner_(runner) { runner_->cptFileName_ = fileManager->getTemporaryFilePath(".cpt"); runner_->useTopGroAndNdxFromDatabase("spc2"); } -void TerminationHelper::runFirstMdrun(const std::string &expectedCptFileName) +void TerminationHelper::runFirstMdrun(const std::string& expectedCptFileName) { CommandLine firstPart(*mdrunCaller_); // Stop after 0.036 ms, which should be short enough that @@ -73,7 +74,8 @@ void TerminationHelper::runFirstMdrun(const std::string &expectedCptFileName) firstPart.addOption("-nstlist", 1); firstPart.addOption("-cpo", runner_->cptFileName_); ASSERT_EQ(0, runner_->callMdrun(firstPart)); - EXPECT_EQ(true, File::exists(expectedCptFileName, File::returnFalseOnError)) << expectedCptFileName << " was not found"; + EXPECT_EQ(true, File::exists(expectedCptFileName, File::returnFalseOnError)) + << expectedCptFileName << " was not found"; } void TerminationHelper::runSecondMdrun() @@ -93,5 +95,5 @@ void TerminationHelper::runSecondMdrunWithNoAppend() ASSERT_EQ(0, runner_->callMdrun(secondPart)); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/terminationhelper.h b/src/programs/mdrun/tests/terminationhelper.h index 5acde75894..74fa419991 100644 --- a/src/programs/mdrun/tests/terminationhelper.h +++ b/src/programs/mdrun/tests/terminationhelper.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,29 +71,28 @@ namespace test */ class TerminationHelper { - public: - //! Constructor - TerminationHelper(TestFileManager *fileManager, - CommandLine *mdrunCaller, - SimulationRunner *runner); - /*! \brief Do a short simulation, likely terminated by -maxh - * - * \param[in] expectedCptFileName The name of the checkpoint - * file that mdrun will write (which has to be customizable, - * if we are testing a multi-simulation). */ - void runFirstMdrun(const std::string &expectedCptFileName); - //! Check that the restart works, but don't do any more MD steps. - void runSecondMdrun(); - //! Check that the restart works without appending, but don't do any more MD steps. - void runSecondMdrunWithNoAppend(); - protected: - //! Object to help call mdrun - CommandLine *mdrunCaller_; - //! Object to coordinate running a simulation - SimulationRunner *runner_; +public: + //! Constructor + TerminationHelper(TestFileManager* fileManager, CommandLine* mdrunCaller, SimulationRunner* runner); + /*! \brief Do a short simulation, likely terminated by -maxh + * + * \param[in] expectedCptFileName The name of the checkpoint + * file that mdrun will write (which has to be customizable, + * if we are testing a multi-simulation). */ + void runFirstMdrun(const std::string& expectedCptFileName); + //! Check that the restart works, but don't do any more MD steps. + void runSecondMdrun(); + //! Check that the restart works without appending, but don't do any more MD steps. + void runSecondMdrunWithNoAppend(); + +protected: + //! Object to help call mdrun + CommandLine* mdrunCaller_; + //! Object to coordinate running a simulation + SimulationRunner* runner_; }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun/tests/tpitest.cpp b/src/programs/mdrun/tests/tpitest.cpp index b080e4fbff..242e476b79 100644 --- a/src/programs/mdrun/tests/tpitest.cpp +++ b/src/programs/mdrun/tests/tpitest.cpp @@ -61,12 +61,11 @@ namespace /*! \brief A basic TPI runner. * The only input parameter used currently: input system random seed (ld-seed). */ -class TpiTest : public MdrunTestFixture, - public ::testing::WithParamInterface +class TpiTest : public MdrunTestFixture, public ::testing::WithParamInterface { - public: - //! Runs the test with the given inputs - void runTest(); +public: + //! Runs the test with the given inputs + void runTest(); }; void TpiTest::runTest() @@ -81,23 +80,23 @@ void TpiTest::runTest() commandLine.append(rerunFileName); ASSERT_EQ(0, runner_.callMdrun(commandLine)); - const std::string logFileContexts = TextReader::readFileToString(runner_.logFileName_); - const std::string tpiOutputs = logFileContexts.substr(logFileContexts.find("Started Test Particle Insertion")); + const std::string logFileContexts = TextReader::readFileToString(runner_.logFileName_); + const std::string tpiOutputs = + logFileContexts.substr(logFileContexts.find("Started Test Particle Insertion")); TestReferenceData refData; TestReferenceChecker checker(refData.rootChecker()); // Output values, their output patterns and relative tolerances (empirical) - const std::map > valuesToCheck = { - {"V", {" =", 1e-10}}, - {"mu", {" =", 1e-3}} + const std::map> valuesToCheck = { + { "V", { " =", 1e-10 } }, { "mu", { " =", 1e-3 } } }; - for (const auto &valueDesc : valuesToCheck) + for (const auto& valueDesc : valuesToCheck) { - const auto &name = valueDesc.first; - const auto &pattern = valueDesc.second.first; - const auto &relativeTolerance = valueDesc.second.second; + const auto& name = valueDesc.first; + const auto& pattern = valueDesc.second.first; + const auto& relativeTolerance = valueDesc.second.second; auto startIndex = tpiOutputs.find(pattern); ASSERT_NE(startIndex, std::string::npos); startIndex += pattern.size(); @@ -109,7 +108,7 @@ void TpiTest::runTest() TEST_P(TpiTest, ReproducesOutput) { - const int randomSeed = GetParam(); + const int randomSeed = GetParam(); const int nsteps = 200; const std::string mdpFileContents = formatString(R"( @@ -134,7 +133,8 @@ TEST_P(TpiTest, ReproducesOutput) tau_t = 0.5 ref_t = 298 nsteps = %d - )", randomSeed, nsteps); + )", + randomSeed, nsteps); runner_.useStringAsMdpFile(mdpFileContents); runTest(); @@ -142,6 +142,6 @@ TEST_P(TpiTest, ReproducesOutput) INSTANTIATE_TEST_CASE_P(Simple, TpiTest, ::testing::Values(1993, 2994)); -} // namespace -} // namespace test -} // namespace gmx +} // namespace +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/trajectory_writing.cpp b/src/programs/mdrun/tests/trajectory_writing.cpp index 9ca0526a6e..b3f9a7712d 100644 --- a/src/programs/mdrun/tests/trajectory_writing.cpp +++ b/src/programs/mdrun/tests/trajectory_writing.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,29 +60,31 @@ namespace //! Test fixture for mdrun trajectory writing class TrajectoryWritingTest : public gmx::test::MdrunTestFixture, - public ::testing::WithParamInterface + public ::testing::WithParamInterface { - public: - //! The file name of the MDP file - std::string theMdpFile; - - //! Execute the trajectory writing test - void runTest() - { - runner_.useStringAsMdpFile(theMdpFile); - runner_.useTopGroAndNdxFromDatabase("spc-and-methanol"); - EXPECT_EQ(0, runner_.callGrompp()); - - runner_.fullPrecisionTrajectoryFileName_ = fileManager_.getTemporaryFilePath("spc-and-methanol.tng"); - runner_.reducedPrecisionTrajectoryFileName_ = fileManager_.getTemporaryFilePath("spc-and-methanol-reduced.tng"); - ASSERT_EQ(0, runner_.callMdrun()); - // TODO When there is a way to sense something like the - // output of gmx check, compare the result with that from - // writing .trr and .xtc and assert the behaviour is - // correct. Note that TNG will always write the box, even - // when constant - this will be a source of - // trajectory-file differences. - } +public: + //! The file name of the MDP file + std::string theMdpFile; + + //! Execute the trajectory writing test + void runTest() + { + runner_.useStringAsMdpFile(theMdpFile); + runner_.useTopGroAndNdxFromDatabase("spc-and-methanol"); + EXPECT_EQ(0, runner_.callGrompp()); + + runner_.fullPrecisionTrajectoryFileName_ = + fileManager_.getTemporaryFilePath("spc-and-methanol.tng"); + runner_.reducedPrecisionTrajectoryFileName_ = + fileManager_.getTemporaryFilePath("spc-and-methanol-reduced.tng"); + ASSERT_EQ(0, runner_.callMdrun()); + // TODO When there is a way to sense something like the + // output of gmx check, compare the result with that from + // writing .trr and .xtc and assert the behaviour is + // correct. Note that TNG will always write the box, even + // when constant - this will be a source of + // trajectory-file differences. + } }; //! Helper typedef for naming test cases like sentences @@ -92,18 +94,19 @@ typedef TrajectoryWritingTest Trajectories; frequencies */ TEST_P(Trajectories, ThatDifferInNstxout) { - theMdpFile = gmx::formatString("integrator = md\n" - "nsteps = 6\n" - "nstxout = %s\n" - "nstvout = 2\n" - "nstfout = 4\n" - "nstxout-compressed = 5\n" - "tcoupl = v-rescale\n" - "tc-grps = System\n" - "tau-t = 1\n" - "ref-t = 298\n" - "compressed-x-grps = Sol\n", - GetParam()); + theMdpFile = gmx::formatString( + "integrator = md\n" + "nsteps = 6\n" + "nstxout = %s\n" + "nstvout = 2\n" + "nstfout = 4\n" + "nstxout-compressed = 5\n" + "tcoupl = v-rescale\n" + "tc-grps = System\n" + "tau-t = 1\n" + "ref-t = 298\n" + "compressed-x-grps = Sol\n", + GetParam()); runTest(); } @@ -113,31 +116,30 @@ typedef TrajectoryWritingTest NptTrajectories; /* This test ensures mdrun can write trajectories in TNG format from NPT ensembles. */ TEST_P(NptTrajectories, WithDifferentPcoupl) { - theMdpFile = gmx::formatString("integrator = md\n" - "nsteps = 2\n" - "nstxout = 2\n" - "nstvout = 1\n" - "pcoupl = %s\n" - "tau-p = 1\n" - "ref-p = 1\n" - "compressibility = 4.5e-5\n" - "tcoupl = v-rescale\n" - "tc-grps = System\n" - "tau-t = 1\n" - "ref-t = 298\n", - GetParam()); + theMdpFile = gmx::formatString( + "integrator = md\n" + "nsteps = 2\n" + "nstxout = 2\n" + "nstvout = 1\n" + "pcoupl = %s\n" + "tau-p = 1\n" + "ref-p = 1\n" + "compressibility = 4.5e-5\n" + "tcoupl = v-rescale\n" + "tc-grps = System\n" + "tau-t = 1\n" + "ref-t = 298\n", + GetParam()); runTest(); } // TODO Consider spamming more of the parameter space when we don't // have to write .mdp and .tpr files to do it. -INSTANTIATE_TEST_CASE_P(MdrunCanWrite, - Trajectories, - ::testing::Values("1", "2", "3")); +INSTANTIATE_TEST_CASE_P(MdrunCanWrite, Trajectories, ::testing::Values("1", "2", "3")); INSTANTIATE_TEST_CASE_P(MdrunCanWrite, NptTrajectories, - ::testing::Values("no", "Berendsen", "Parrinello-Rahman")); + ::testing::Values("no", "Berendsen", "Parrinello-Rahman")); #endif diff --git a/src/programs/mdrun/tests/trajectorycomparison.cpp b/src/programs/mdrun/tests/trajectorycomparison.cpp index 028b80146a..e70fd92ec0 100644 --- a/src/programs/mdrun/tests/trajectorycomparison.cpp +++ b/src/programs/mdrun/tests/trajectorycomparison.cpp @@ -64,9 +64,9 @@ using ::testing::Pointwise; * * \todo This could be streamlined when we have a proper 3D matrix * class and view. */ -static void compareBox(const TrajectoryFrame &reference, - const TrajectoryFrame &test, - const TrajectoryFrameMatchSettings &matchSettings, +static void compareBox(const TrajectoryFrame& reference, + const TrajectoryFrame& test, + const TrajectoryFrameMatchSettings& matchSettings, const FloatingPointTolerance tolerance) { if (!matchSettings.mustCompareBox) @@ -77,13 +77,13 @@ static void compareBox(const TrajectoryFrame &reference, if (!reference.hasBox()) { ADD_FAILURE() << "Comparing the box was required, " - "but the reference frame did not have one"; + "but the reference frame did not have one"; canCompareBox = false; } if (!test.hasBox()) { ADD_FAILURE() << "Comparing the box was required, " - "but the test frame did not have one"; + "but the test frame did not have one"; canCompareBox = false; } if (!canCompareBox) @@ -104,8 +104,7 @@ static void compareBox(const TrajectoryFrame &reference, /*! \brief Help put all atom coordinates in \c frame into its box. * * This can perhaps go away when frame->x is a container. */ -static std::vector -putAtomsInBox(const TrajectoryFrame &frame) +static std::vector putAtomsInBox(const TrajectoryFrame& frame) { std::vector x(frame.x().begin(), frame.x().end()); matrix box; @@ -141,10 +140,9 @@ static bool shouldDoComparison(const ComparisonConditions comparisonConditions, bool doComparison = true; if (testIsEmpty) { - if (comparisonConditions == ComparisonConditions::MustCompare || - comparisonConditions == ComparisonConditions::CompareIfBothFound || - (!referenceIsEmpty && - comparisonConditions == ComparisonConditions::CompareIfReferenceFound)) + if (comparisonConditions == ComparisonConditions::MustCompare + || comparisonConditions == ComparisonConditions::CompareIfBothFound + || (!referenceIsEmpty && comparisonConditions == ComparisonConditions::CompareIfReferenceFound)) { ADD_FAILURE() << "Test frame lacked quantity for required comparison"; } @@ -152,10 +150,9 @@ static bool shouldDoComparison(const ComparisonConditions comparisonConditions, } if (referenceIsEmpty) { - if (comparisonConditions == ComparisonConditions::MustCompare || - comparisonConditions == ComparisonConditions::CompareIfBothFound || - (!testIsEmpty && - comparisonConditions == ComparisonConditions::CompareIfTestFound)) + if (comparisonConditions == ComparisonConditions::MustCompare + || comparisonConditions == ComparisonConditions::CompareIfBothFound + || (!testIsEmpty && comparisonConditions == ComparisonConditions::CompareIfTestFound)) { ADD_FAILURE() << "Reference frame lacked quantity for required comparison"; } @@ -166,15 +163,13 @@ static bool shouldDoComparison(const ComparisonConditions comparisonConditions, /*! \brief Compares the position coordinates from \c reference and \c test * according to the \c matchSettings and \c tolerance. */ -static void compareCoordinates(const TrajectoryFrame &reference, - const TrajectoryFrame &test, - const TrajectoryFrameMatchSettings &matchSettings, +static void compareCoordinates(const TrajectoryFrame& reference, + const TrajectoryFrame& test, + const TrajectoryFrameMatchSettings& matchSettings, const FloatingPointTolerance tolerance) { SCOPED_TRACE("Comparing coordinates"); - if (!shouldDoComparison(matchSettings.coordinatesComparison, - reference.x().empty(), - test.x().empty())) + if (!shouldDoComparison(matchSettings.coordinatesComparison, reference.x().empty(), test.x().empty())) { return; } @@ -183,13 +178,13 @@ static void compareCoordinates(const TrajectoryFrame &reference, if (!reference.hasBox()) { ADD_FAILURE() << "Comparing positions required PBC handling, " - "but the reference frame did not have a box"; + "but the reference frame did not have a box"; canHandlePbc = false; } if (!test.hasBox()) { ADD_FAILURE() << "Comparing positions required PBC handling, " - "but the test frame did not have a box"; + "but the test frame did not have a box"; canHandlePbc = false; } @@ -211,15 +206,13 @@ static void compareCoordinates(const TrajectoryFrame &reference, /*! \brief Compares the velocities from \c reference and \c test * according to the \c matchSettings and \c tolerance. */ -static void compareVelocities(const TrajectoryFrame &reference, - const TrajectoryFrame &test, - const TrajectoryFrameMatchSettings &matchSettings, +static void compareVelocities(const TrajectoryFrame& reference, + const TrajectoryFrame& test, + const TrajectoryFrameMatchSettings& matchSettings, const FloatingPointTolerance tolerance) { SCOPED_TRACE("Comparing velocities"); - if (!shouldDoComparison(matchSettings.velocitiesComparison, - reference.v().empty(), - test.v().empty())) + if (!shouldDoComparison(matchSettings.velocitiesComparison, reference.v().empty(), test.v().empty())) { return; } @@ -228,15 +221,13 @@ static void compareVelocities(const TrajectoryFrame &reference, /*! \brief Compares the forces from \c reference and \c test * according to the \c matchSettings and \c tolerance. */ -static void compareForces(const TrajectoryFrame &reference, - const TrajectoryFrame &test, - const TrajectoryFrameMatchSettings &matchSettings, +static void compareForces(const TrajectoryFrame& reference, + const TrajectoryFrame& test, + const TrajectoryFrameMatchSettings& matchSettings, const FloatingPointTolerance tolerance) { SCOPED_TRACE("Comparing forces"); - if (!shouldDoComparison(matchSettings.forcesComparison, - reference.f().empty(), - test.f().empty())) + if (!shouldDoComparison(matchSettings.forcesComparison, reference.f().empty(), test.f().empty())) { return; } @@ -244,25 +235,25 @@ static void compareForces(const TrajectoryFrame &reference, } -const TrajectoryTolerances TrajectoryComparison::s_defaultTrajectoryTolerances { - defaultRealTolerance(), // box - relativeToleranceAsFloatingPoint(1.0, 1.0e-3), // positions - defaultRealTolerance(), // velocities - relativeToleranceAsFloatingPoint(100.0, GMX_DOUBLE ? 1.0e-7 : 5.0e-5) // forces +const TrajectoryTolerances TrajectoryComparison::s_defaultTrajectoryTolerances{ + defaultRealTolerance(), // box + relativeToleranceAsFloatingPoint(1.0, 1.0e-3), // positions + defaultRealTolerance(), // velocities + relativeToleranceAsFloatingPoint(100.0, GMX_DOUBLE ? 1.0e-7 : 5.0e-5) // forces }; -TrajectoryComparison::TrajectoryComparison(const TrajectoryFrameMatchSettings &matchSettings, - const TrajectoryTolerances &tolerances) - : matchSettings_(matchSettings), - tolerances_(tolerances) +TrajectoryComparison::TrajectoryComparison(const TrajectoryFrameMatchSettings& matchSettings, + const TrajectoryTolerances& tolerances) : + matchSettings_(matchSettings), + tolerances_(tolerances) { } -void TrajectoryComparison::operator()(const TrajectoryFrame &reference, - const TrajectoryFrame &test) const +void TrajectoryComparison::operator()(const TrajectoryFrame& reference, const TrajectoryFrame& test) const { - SCOPED_TRACE("Comparing trajectory reference frame " + reference.frameName() + " and test frame " + test.frameName()); + SCOPED_TRACE("Comparing trajectory reference frame " + reference.frameName() + + " and test frame " + test.frameName()); EXPECT_EQ(reference.step(), test.step()); EXPECT_EQ(reference.time(), test.time()); compareBox(reference, test, matchSettings_, tolerances_.box); @@ -271,5 +262,5 @@ void TrajectoryComparison::operator()(const TrajectoryFrame &reference, compareForces(reference, test, matchSettings_, tolerances_.forces); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/trajectorycomparison.h b/src/programs/mdrun/tests/trajectorycomparison.h index fd446d10a3..444336efe0 100644 --- a/src/programs/mdrun/tests/trajectorycomparison.h +++ b/src/programs/mdrun/tests/trajectorycomparison.h @@ -86,11 +86,11 @@ enum class ComparisonConditions : int struct TrajectoryFrameMatchSettings { //! Whether boxes must be compared. - bool mustCompareBox = false; + bool mustCompareBox = false; //! Whether PBC will be handled if it can be handled. - bool handlePbcIfPossible = true; + bool handlePbcIfPossible = true; //! Whether PBC handling must occur for a valid comparison. - bool requirePbcHandling = false; + bool requirePbcHandling = false; //! Whether position coordinates must be compared. ComparisonConditions coordinatesComparison = ComparisonConditions::CompareIfBothFound; //! Whether velocities must be compared. @@ -115,22 +115,22 @@ struct TrajectoryFrameMatchSettings * failures will be given. */ class TrajectoryComparison { - public: - //! Defaults for trajectory comparisons - static const TrajectoryTolerances s_defaultTrajectoryTolerances; - //! Constructor - TrajectoryComparison(const TrajectoryFrameMatchSettings &matchSettings, - const TrajectoryTolerances &tolerances); - /*! \brief Compare reference with test given the \c - * matchSettings_ within \c tolerances_ */ - void operator()(const TrajectoryFrame &reference, const TrajectoryFrame &test) const; - //! Specifies expected behavior in comparisons - TrajectoryFrameMatchSettings matchSettings_; - //! Trajectory fields to match with given tolerances. - TrajectoryTolerances tolerances_; +public: + //! Defaults for trajectory comparisons + static const TrajectoryTolerances s_defaultTrajectoryTolerances; + //! Constructor + TrajectoryComparison(const TrajectoryFrameMatchSettings& matchSettings, + const TrajectoryTolerances& tolerances); + /*! \brief Compare reference with test given the \c + * matchSettings_ within \c tolerances_ */ + void operator()(const TrajectoryFrame& reference, const TrajectoryFrame& test) const; + //! Specifies expected behavior in comparisons + TrajectoryFrameMatchSettings matchSettings_; + //! Trajectory fields to match with given tolerances. + TrajectoryTolerances tolerances_; }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun/tests/trajectoryreader.cpp b/src/programs/mdrun/tests/trajectoryreader.cpp index cf282fdf40..ff08891e90 100644 --- a/src/programs/mdrun/tests/trajectoryreader.cpp +++ b/src/programs/mdrun/tests/trajectoryreader.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,9 +61,9 @@ namespace test { //! Helper function to obtain resources -static t_trxframe *make_trxframe() +static t_trxframe* make_trxframe() { - t_trxframe *frame; + t_trxframe* frame; snew(frame, 1); clear_trxframe(frame, true); @@ -72,7 +72,7 @@ static t_trxframe *make_trxframe() } //! Helper function to clean up resources -void done_trxframe(t_trxframe *fr) +void done_trxframe(t_trxframe* fr) { // Free the contents, then the pointer itself sfree(fr->x); @@ -82,44 +82,44 @@ void done_trxframe(t_trxframe *fr) sfree(fr); } -TrajectoryFrameReader::TrajectoryFrameReader(const std::string &filename) - : filename_(filename), - trajectoryFileGuard_(nullptr), - trxframeGuard_(make_trxframe()), - haveReadFirstFrame_(false), - haveProbedForNextFrame_(false), - nextFrameExists_(false) +TrajectoryFrameReader::TrajectoryFrameReader(const std::string& filename) : + filename_(filename), + trajectoryFileGuard_(nullptr), + trxframeGuard_(make_trxframe()), + haveReadFirstFrame_(false), + haveProbedForNextFrame_(false), + nextFrameExists_(false) { - gmx_output_env_t *oenv; + gmx_output_env_t* oenv; output_env_init_default(&oenv); oenvGuard_.reset(oenv); } -bool -TrajectoryFrameReader::readNextFrame() +bool TrajectoryFrameReader::readNextFrame() { if (haveProbedForNextFrame_) { if (nextFrameExists_) { - GMX_THROW(APIError("This frame has already been probed for, it should be used before probing again.")); + GMX_THROW( + APIError("This frame has already been probed for, it should be used before " + "probing again.")); } else { - GMX_THROW(APIError("This frame has already been probed for, it doesn't exist, so there should not be subsequent attempts to probe for it.")); + GMX_THROW( + APIError("This frame has already been probed for, it doesn't exist, so there " + "should not be subsequent attempts to probe for it.")); } } haveProbedForNextFrame_ = true; // If there's a next frame, read it into trxframe_, and report the result. if (!haveReadFirstFrame_) { - t_trxstatus *trajectoryFile; + t_trxstatus* trajectoryFile; int flags = TRX_READ_X | TRX_READ_V | TRX_READ_F; - nextFrameExists_ = read_first_frame(oenvGuard_.get(), - &trajectoryFile, - filename_.c_str(), - trxframeGuard_.get(), - flags); + nextFrameExists_ = read_first_frame(oenvGuard_.get(), &trajectoryFile, filename_.c_str(), + trxframeGuard_.get(), flags); if (!trajectoryFile) { GMX_THROW(FileIOError("Could not open trajectory file " + filename_ + " for reading")); @@ -129,15 +129,13 @@ TrajectoryFrameReader::readNextFrame() } else { - nextFrameExists_ = read_next_frame(oenvGuard_.get(), - trajectoryFileGuard_.get(), - trxframeGuard_.get()); + nextFrameExists_ = + read_next_frame(oenvGuard_.get(), trajectoryFileGuard_.get(), trxframeGuard_.get()); } return nextFrameExists_; } -TrajectoryFrame -TrajectoryFrameReader::frame() +TrajectoryFrame TrajectoryFrameReader::frame() { if (!haveProbedForNextFrame_) { @@ -145,7 +143,9 @@ TrajectoryFrameReader::frame() } if (!nextFrameExists_) { - GMX_THROW(APIError("There is no next frame, so there should have been no attempt to get it. Perhaps the return value of readNextFrame() was misused.")); + GMX_THROW( + APIError("There is no next frame, so there should have been no attempt to get it. " + "Perhaps the return value of readNextFrame() was misused.")); } // Prepare for reading future frames @@ -156,5 +156,5 @@ TrajectoryFrameReader::frame() return TrajectoryFrame(*trxframeGuard_.get()); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/programs/mdrun/tests/trajectoryreader.h b/src/programs/mdrun/tests/trajectoryreader.h index aed0eec18c..7d8ccd2a2a 100644 --- a/src/programs/mdrun/tests/trajectoryreader.h +++ b/src/programs/mdrun/tests/trajectoryreader.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,7 +69,7 @@ typedef unique_cptr oenv_ptr; //! Convenience smart pointer typedef typedef unique_cptr trxstatus_file_ptr; //! Helper function to free all resources -void done_trxframe(t_trxframe *fr); +void done_trxframe(t_trxframe* fr); //! Convenience smart pointer typedef typedef unique_cptr trxframe_ptr; @@ -78,61 +78,62 @@ typedef unique_cptr trxframe_ptr; * successive frames of an trajectory file. */ class TrajectoryFrameReader { - public: - /*! \brief Attempt to read the next frame from the trajectory file. - * - * \return Whether a frame was available to read. - * - * This call wraps the read_first_frame()/read_next_frame() - * API, which does the file opening as a side effect of - * reading the first frame. - * - * If true is returned, then TrajectoryFrame frame() should be called - * to get access to the data. If false is returned, then no - * further data exists and no further call to - * readNextFrameStub or TrajectoryFrame frame() should occur. - * - * \throws FileIOError upon reading the first frame, if the trajectory file cannot be opened - * \throws APIError if an earlier probe has not been properly handled - * (by calling frame(), or stopping trying to read - * from the file). */ - bool readNextFrame(); - /*! \brief Return the next frame from the trajectory file. - * - * If the next frame has not been probed for, then probe for - * it. If no next frame exists, then throw APIError, because - * user code should have called readNextFrameStub itself if this - * is possible. (This permits user code to avoid making calls - * to readNextFrameStub in a case where it already knows that - * the frame exists.) - * - * \throws APIError if no next frame exists, or if it lacks either time or step number. */ - TrajectoryFrame frame(); - /*! \brief Constructor - * - * \param[in] filename Name of trajectory file to open and read. */ - explicit TrajectoryFrameReader(const std::string &filename); - private: - //! Name of trajectory file to open and read - std::string filename_; - //! Owning handle of output environment object - oenv_ptr oenvGuard_; - //! Owning handle of an open trajectory file ready to read frames. - trxstatus_file_ptr trajectoryFileGuard_; - //! Owning handle of contents of trajectory file frame after reading. - const trxframe_ptr trxframeGuard_; - //! Whether the first frame has been read - bool haveReadFirstFrame_; - //! Whether the API has been used properly (ie. probe before reading). - bool haveProbedForNextFrame_; - //! Whether there has been a probe that found a next frame. - bool nextFrameExists_; +public: + /*! \brief Attempt to read the next frame from the trajectory file. + * + * \return Whether a frame was available to read. + * + * This call wraps the read_first_frame()/read_next_frame() + * API, which does the file opening as a side effect of + * reading the first frame. + * + * If true is returned, then TrajectoryFrame frame() should be called + * to get access to the data. If false is returned, then no + * further data exists and no further call to + * readNextFrameStub or TrajectoryFrame frame() should occur. + * + * \throws FileIOError upon reading the first frame, if the trajectory file cannot be opened + * \throws APIError if an earlier probe has not been properly handled + * (by calling frame(), or stopping trying to read + * from the file). */ + bool readNextFrame(); + /*! \brief Return the next frame from the trajectory file. + * + * If the next frame has not been probed for, then probe for + * it. If no next frame exists, then throw APIError, because + * user code should have called readNextFrameStub itself if this + * is possible. (This permits user code to avoid making calls + * to readNextFrameStub in a case where it already knows that + * the frame exists.) + * + * \throws APIError if no next frame exists, or if it lacks either time or step number. */ + TrajectoryFrame frame(); + /*! \brief Constructor + * + * \param[in] filename Name of trajectory file to open and read. */ + explicit TrajectoryFrameReader(const std::string& filename); - // Multiple owners of these resources isn't very sensible, so prevent it - GMX_DISALLOW_COPY_AND_ASSIGN(TrajectoryFrameReader); +private: + //! Name of trajectory file to open and read + std::string filename_; + //! Owning handle of output environment object + oenv_ptr oenvGuard_; + //! Owning handle of an open trajectory file ready to read frames. + trxstatus_file_ptr trajectoryFileGuard_; + //! Owning handle of contents of trajectory file frame after reading. + const trxframe_ptr trxframeGuard_; + //! Whether the first frame has been read + bool haveReadFirstFrame_; + //! Whether the API has been used properly (ie. probe before reading). + bool haveProbedForNextFrame_; + //! Whether there has been a probe that found a next frame. + bool nextFrameExists_; + + // Multiple owners of these resources isn't very sensible, so prevent it + GMX_DISALLOW_COPY_AND_ASSIGN(TrajectoryFrameReader); }; -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/programs/mdrun_main.cpp b/src/programs/mdrun_main.cpp index 660e16c898..1e77a6a4da 100644 --- a/src/programs/mdrun_main.cpp +++ b/src/programs/mdrun_main.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2016,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,15 +43,15 @@ namespace { //! Initializer for a module that defaults to nice level zero. -void initSettingsNoNice(gmx::CommandLineModuleSettings *settings) +void initSettingsNoNice(gmx::CommandLineModuleSettings* settings) { settings->setDefaultNiceLevel(0); } -} +} // namespace -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - return gmx::CommandLineModuleManager::runAsMainCMainWithSettings( - argc, argv, &gmx::gmx_mdrun, &initSettingsNoNice); + return gmx::CommandLineModuleManager::runAsMainCMainWithSettings(argc, argv, &gmx::gmx_mdrun, + &initSettingsNoNice); } diff --git a/src/programs/view/3dview.cpp b/src/programs/view/3dview.cpp index af36b05cad..dd3e3556e3 100644 --- a/src/programs/view/3dview.cpp +++ b/src/programs/view/3dview.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -50,13 +50,13 @@ #include "gromacs/utility/fatalerror.h" #include "gromacs/utility/smalloc.h" -static void set_scale(t_3dview *view, real sx, real sy) +static void set_scale(t_3dview* view, real sx, real sy) { view->sc_x = sx; view->sc_y = sy; } -static void calculate_view(t_3dview *view) +static void calculate_view(t_3dview* view) { #define SMALL 1e-6 mat4 To, Te, T1, T2, T3, T4, T5, N1, D1, D2, D3, D4, D5; @@ -66,8 +66,8 @@ static void calculate_view(t_3dview *view) dx = view->eye[XX]; dy = view->eye[YY]; dz = view->eye[ZZ]; - l = std::sqrt(dx*dx+dy*dy+dz*dz); - r = std::sqrt(dx*dx+dy*dy); + l = std::sqrt(dx * dx + dy * dy + dz * dz); + r = std::sqrt(dx * dx + dy * dy); #ifdef DEBUG gmx_vec4_print(debug, "eye", view->eye); std::printf("del: %10.5f%10.5f%10.5f l: %10.5f, r: %10.5f\n", dx, dy, dz, l, r); @@ -85,11 +85,11 @@ static void calculate_view(t_3dview *view) gmx_mat4_init_unity(T3); if (r > 0) { - T3[XX][XX] = -dy/r, T3[XX][ZZ] = dx/r, T3[ZZ][XX] = -dx/r, T3[ZZ][ZZ] = -dy/r; + T3[XX][XX] = -dy / r, T3[XX][ZZ] = dx / r, T3[ZZ][XX] = -dx / r, T3[ZZ][ZZ] = -dy / r; } gmx_mat4_init_unity(T4); - T4[YY][YY] = r/l, T4[YY][ZZ] = dz/l, T4[ZZ][YY] = -dz/l, T4[ZZ][ZZ] = r/l; + T4[YY][YY] = r / l, T4[YY][ZZ] = dz / l, T4[ZZ][YY] = -dz / l, T4[ZZ][ZZ] = r / l; gmx_mat4_init_unity(T5); T5[ZZ][ZZ] = -1; @@ -118,7 +118,7 @@ static void calculate_view(t_3dview *view) #endif } -gmx_bool zoom_3d(t_3dview *view, real fac) +gmx_bool zoom_3d(t_3dview* view, real fac) { real dr; real bm, dr1, dr2; @@ -127,14 +127,14 @@ gmx_bool zoom_3d(t_3dview *view, real fac) dr2 = 0; for (i = 0; (i < DIM); i++) { - dr = view->eye[i]; - dr2 += dr*dr; + dr = view->eye[i]; + dr2 += dr * dr; } dr1 = std::sqrt(dr2); if (fac < 1) { bm = std::max(norm(view->box[XX]), std::max(norm(view->box[YY]), norm(view->box[ZZ]))); - if (dr1*fac < 1.1*bm) /* Don't come to close */ + if (dr1 * fac < 1.1 * bm) /* Don't come to close */ { return FALSE; } @@ -149,14 +149,14 @@ gmx_bool zoom_3d(t_3dview *view, real fac) } /* Initiates the state of 3d rotation matrices in the structure */ -static void init_rotate_3d(t_3dview *view) +static void init_rotate_3d(t_3dview* view) { - real rot = DEG2RAD*15; + real rot = DEG2RAD * 15; int i; for (i = 0; (i < DIM); i++) { - gmx_mat4_init_rotation(i, rot, view->RotP[i]); + gmx_mat4_init_rotation(i, rot, view->RotP[i]); gmx_mat4_init_rotation(i, -rot, view->RotM[i]); #ifdef DEBUG gmx_mat4_print(debug, "RotP", view->RotP[i]); @@ -166,7 +166,7 @@ static void init_rotate_3d(t_3dview *view) } -void rotate_3d(t_3dview *view, int axis, gmx_bool bPositive) +void rotate_3d(t_3dview* view, int axis, gmx_bool bPositive) { mat4 m4; @@ -182,23 +182,23 @@ void rotate_3d(t_3dview *view, int axis, gmx_bool bPositive) calculate_view(view); } -void translate_view(t_3dview *view, int axis, gmx_bool bPositive) +void translate_view(t_3dview* view, int axis, gmx_bool bPositive) { #ifdef DEBUG std::printf("Translate called\n"); #endif if (bPositive) { - view->origin[axis] += view->box[axis][axis]/8; + view->origin[axis] += view->box[axis][axis] / 8; } else { - view->origin[axis] -= view->box[axis][axis]/8; + view->origin[axis] -= view->box[axis][axis] / 8; } calculate_view(view); } -void reset_view(t_3dview *view) +void reset_view(t_3dview* view) { #ifdef DEBUG std::printf("Reset view called\n"); @@ -206,7 +206,7 @@ void reset_view(t_3dview *view) set_scale(view, 4.0, 4.0); clear_rvec(view->eye); calc_box_center(view->ecenter, view->box, view->origin); - view->eye[ZZ] = 3.0*std::max(view->box[XX][XX], view->box[YY][YY]); + view->eye[ZZ] = 3.0 * std::max(view->box[XX][XX], view->box[YY][YY]); zoom_3d(view, 1.0); view->eye[WW] = view->origin[WW] = 0.0; @@ -217,9 +217,9 @@ void reset_view(t_3dview *view) init_rotate_3d(view); } -t_3dview *init_view(matrix box) +t_3dview* init_view(matrix box) { - t_3dview *view; + t_3dview* view; snew(view, 1); copy_mat(box, view->box); diff --git a/src/programs/view/3dview.h b/src/programs/view/3dview.h index 774d447cd4..51896d2d3f 100644 --- a/src/programs/view/3dview.h +++ b/src/programs/view/3dview.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2010,2014, by the GROMACS development team, led by + * Copyright (c) 2010,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,9 +42,10 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" -typedef int iv2[2]; +typedef int iv2[2]; -typedef struct { +typedef struct +{ matrix box; int ecenter; /* enum for centering, see pbc.h */ vec4 eye, origin; /* The eye and origin position */ @@ -55,7 +56,7 @@ typedef struct { mat4 RotM[DIM]; } t_3dview; -t_3dview *init_view(matrix box); +t_3dview* init_view(matrix box); /* Generate the view matrix from the eye pos and the origin, * applying also the scaling for the aspect ration. * There is no accompanying done_view routine: the struct can simply @@ -68,18 +69,18 @@ t_3dview *init_view(matrix box); * reset the view */ -gmx_bool zoom_3d(t_3dview *view, real fac); +gmx_bool zoom_3d(t_3dview* view, real fac); /* Zoom in or out with factor fac, returns TRUE when zoom successful, * FALSE otherwise. */ -void rotate_3d(t_3dview *view, int axis, gmx_bool bPositive); +void rotate_3d(t_3dview* view, int axis, gmx_bool bPositive); /* Rotate the eye around the center of the box, around axis */ -void translate_view(t_3dview *view, int axis, gmx_bool bPositive); +void translate_view(t_3dview* view, int axis, gmx_bool bPositive); /* Translate the origin at which one is looking */ -void reset_view(t_3dview *view); +void reset_view(t_3dview* view); /* Reset the viewing to the initial view */ #endif diff --git a/src/programs/view/Xstuff.h b/src/programs/view/Xstuff.h index cbf3ebcb5c..796fc89ede 100644 --- a/src/programs/view/Xstuff.h +++ b/src/programs/view/Xstuff.h @@ -43,7 +43,7 @@ * need them in the inner loops. */ #ifdef __VEC__ -#undef pixel +# undef pixel #endif #include @@ -58,118 +58,133 @@ typedef unsigned char bmchar; typedef char bmchar; #endif /* _acc */ -#define XTextHeight(font) ((font)->max_bounds.ascent+(font)->max_bounds.descent) +#define XTextHeight(font) ((font)->max_bounds.ascent + (font)->max_bounds.descent) #define XDrawCircle(disp, win, gc, x, y, rad) \ - XDrawArc(disp, win, gc, (x)-(rad), (y)-(rad), 2*(rad), 2*(rad), 0, 64*360) + XDrawArc(disp, win, gc, (x) - (rad), (y) - (rad), 2 * (rad), 2 * (rad), 0, 64 * 360) #define XFillCircle(disp, win, gc, x, y, rad) \ - XFillArc(disp, win, gc, (x)-(rad), (y)-(rad), 2*(rad), 2*(rad), 0, 64*360) + XFillArc(disp, win, gc, (x) - (rad), (y) - (rad), 2 * (rad), 2 * (rad), 0, 64 * 360) #ifdef NEED_XSTUFF -extern void XSelectInput(Display *display, Window w, long event_mask); -extern void XChangeWindowAttributes(Display *display, Window w, - unsigned long valuemask, - XSetWindowAttributes *attributes); -extern void XSetWindowBackgroundPixmap(Display *disp, Drawable d, Pixmap pm); -extern Status XMatchVisualInfo(Display *display, int screen, int depth, - int class, XVisualInfo *vinfo_return); -extern Status XParseColor(Display *display, Colormap colormap, char *spec, - XColor *exact_def_return); -extern Status XAllocColor(Display *display, Colormap colormap, - XColor *screen_in_out); -extern Status XAllocNamedColor(Display *disp, Colormap cmap, char *colorname, - XColor *colorcell_def, XColor *rgb_db_def); -extern Status XQueryColor(Display *disp, Colormap cmap, - XColor *colorcell_def); -extern void XDrawArc(Display *display, Drawable d, GC gc, int x, int y, - unsigned int width, unsigned int height, int angle1, - int angle2); -extern void XFillArc(Display *display, Drawable d, GC gc, int x, int y, - unsigned int width, unsigned int height, int angle1, - int angle2); -extern void XDrawLine(Display *display, Drawable d, GC gc, int x1, int y1, - int x2, int y2); -extern void XDrawLines(Display *display, Drawable d, GC gc, XPoint *points, - int npoints, int mode); +extern void XSelectInput(Display* display, Window w, long event_mask); +extern void XChangeWindowAttributes(Display* display, + Window w, + unsigned long valuemask, + XSetWindowAttributes* attributes); +extern void XSetWindowBackgroundPixmap(Display* disp, Drawable d, Pixmap pm); +extern Status XMatchVisualInfo(Display* display, int screen, int depth, int class, XVisualInfo* vinfo_return); +extern Status XParseColor(Display* display, Colormap colormap, char* spec, XColor* exact_def_return); +extern Status XAllocColor(Display* display, Colormap colormap, XColor* screen_in_out); +extern Status XAllocNamedColor(Display* disp, Colormap cmap, char* colorname, XColor* colorcell_def, XColor* rgb_db_def); +extern Status XQueryColor(Display* disp, Colormap cmap, XColor* colorcell_def); +extern void XDrawArc(Display* display, + Drawable d, + GC gc, + int x, + int y, + unsigned int width, + unsigned int height, + int angle1, + int angle2); +extern void XFillArc(Display* display, + Drawable d, + GC gc, + int x, + int y, + unsigned int width, + unsigned int height, + int angle1, + int angle2); +extern void XDrawLine(Display* display, Drawable d, GC gc, int x1, int y1, int x2, int y2); +extern void XDrawLines(Display* display, Drawable d, GC gc, XPoint* points, int npoints, int mode); -extern void XMapWindow(Display *display, Window w); -extern void XMapSubwindows(Display *display, Window w); -extern void XUnmapSubwindows(Display *display, Window w); -extern void XUnmapWindow(Display *display, Window w); +extern void XMapWindow(Display* display, Window w); +extern void XMapSubwindows(Display* display, Window w); +extern void XUnmapSubwindows(Display* display, Window w); +extern void XUnmapWindow(Display* display, Window w); -extern void XNextEvent(Display *display, XEvent *report); -extern Bool XCheckTypedEvent(Display *display, int event_type, - XEvent *event_return); -extern void XSetForeground(Display *display, GC gc, - unsigned long foreground); -extern void XClearWindow(Display *disp, Window w); -extern void XClearArea(Display *display, Window w, int x, int y, - unsigned int width, unsigned int height, - Bool exposures); -extern void XDrawRectangle(Display *display, Drawable d, GC gc, - int x, int y, int width, int height); -extern void XDrawRectangles(Display *display, Drawable d, GC gc, - XRectangle rectangles[], int nrectangles); -extern void XDrawString(Display *display, Drawable d, GC gc, int x, int y, - char *string, int length); -extern void XDrawLine(Display *display, Drawable d, GC gc, - int x1, int y1, int x2, int y2); -extern void XSetStandardProperties(Display *display, Window w, - char *window_name, char *icon_name, - Pixmap icon_pixmap, char **argv, int argc, - XSizeHints *hints); -extern int XLookupString(XKeyEvent *event_struct, char *buffer_return, - int bytes_buffer, KeySym *keysym_return, - XComposeStatus *status_in_out); -extern void XSetGraphicsExposures(Display *display, GC gc, - Bool graphics_exposures); -extern void XMapRaised(Display *display, Window w); -extern void XSync(Display *display, Bool discard); -extern void XFlush(Display *display); -extern void XSetStandardProperties(Display *display, Window w, - char *window_name, char *icon_name, - Pixmap icon_pixmap, char **argv, int argc, - XSizeHints *hints); -extern Status XSendEvent(Display *display, Window w, Bool propagate, - long event_mask, XEvent *event_send); -extern void XFreeGC(Display *display, GC gc); -extern void XCloseDisplay(Display *display); +extern void XNextEvent(Display* display, XEvent* report); +extern Bool XCheckTypedEvent(Display* display, int event_type, XEvent* event_return); +extern void XSetForeground(Display* display, GC gc, unsigned long foreground); +extern void XClearWindow(Display* disp, Window w); +extern void XClearArea(Display* display, Window w, int x, int y, unsigned int width, unsigned int height, Bool exposures); +extern void XDrawRectangle(Display* display, Drawable d, GC gc, int x, int y, int width, int height); +extern void XDrawRectangles(Display* display, Drawable d, GC gc, XRectangle rectangles[], int nrectangles); +extern void XDrawString(Display* display, Drawable d, GC gc, int x, int y, char* string, int length); +extern void XDrawLine(Display* display, Drawable d, GC gc, int x1, int y1, int x2, int y2); +extern void XSetStandardProperties(Display* display, + Window w, + char* window_name, + char* icon_name, + Pixmap icon_pixmap, + char** argv, + int argc, + XSizeHints* hints); +extern int XLookupString(XKeyEvent* event_struct, + char* buffer_return, + int bytes_buffer, + KeySym* keysym_return, + XComposeStatus* status_in_out); +extern void XSetGraphicsExposures(Display* display, GC gc, Bool graphics_exposures); +extern void XMapRaised(Display* display, Window w); +extern void XSync(Display* display, Bool discard); +extern void XFlush(Display* display); +extern void XSetStandardProperties(Display* display, + Window w, + char* window_name, + char* icon_name, + Pixmap icon_pixmap, + char** argv, + int argc, + XSizeHints* hints); +extern Status XSendEvent(Display* display, Window w, Bool propagate, long event_mask, XEvent* event_send); +extern void XFreeGC(Display* display, GC gc); +extern void XCloseDisplay(Display* display); -extern void XNextEvent(Display *display, XEvent *report); -extern Bool XCheckTypedEvent(Display *display, int event_type, - XEvent *event_return); -extern void XSetForeground(Display *display, GC gc, - unsigned long foreground); -extern Bool XCheckMaskEvent(Display *display, long event_mask, - XEvent *event_return); +extern void XNextEvent(Display* display, XEvent* report); +extern Bool XCheckTypedEvent(Display* display, int event_type, XEvent* event_return); +extern void XSetForeground(Display* display, GC gc, unsigned long foreground); +extern Bool XCheckMaskEvent(Display* display, long event_mask, XEvent* event_return); -extern int XResizeWindow(Display *display, Window w, - unsigned int width, unsigned int height); -extern int XMoveWindow(Display *display, Window w, - unsigned int x, unsigned int y); -extern void XFreePixmap(Display *display, Pixmap pixmap); -extern void XCopyGC(Display *display, GC src, long valuemask, - GC dest); -extern int XTextWidth(XFontStruct *font_struct, char *string, int count); -extern void XSetDashes(Display *display, GC gc, int dash_offset, - unsigned char dash_list[], int n); -extern void XBell(Display *disp, int volume); -extern void XDrawRectangle(Display *disp, Drawable d, GC gc, - int x, int y, int w, int h); -extern void XFillRectangle(Display *disp, Drawable d, GC gc, - int x, int y, int w, int h); +extern int XResizeWindow(Display* display, Window w, unsigned int width, unsigned int height); +extern int XMoveWindow(Display* display, Window w, unsigned int x, unsigned int y); +extern void XFreePixmap(Display* display, Pixmap pixmap); +extern void XCopyGC(Display* display, GC src, long valuemask, GC dest); +extern int XTextWidth(XFontStruct* font_struct, char* string, int count); +extern void XSetDashes(Display* display, GC gc, int dash_offset, unsigned char dash_list[], int n); +extern void XBell(Display* disp, int volume); +extern void XDrawRectangle(Display* disp, Drawable d, GC gc, int x, int y, int w, int h); +extern void XFillRectangle(Display* disp, Drawable d, GC gc, int x, int y, int w, int h); -extern void XDestroySubwindows(Display *disp, Window Win); -extern void XDestroyWindow(Display *disp, Window Win); -extern void XQueryPointer(Display *disp, Window Win, Window *root, - Window *child, int *root_x, int *root_y, - int *win_x, int *win_y, unsigned int *keybut); -extern void XWarpPointer(Display *disp, Window src, Window dest, - int src_x, int src_y, unsigned int src_w, unsigned int src_h, - int dest_x, int dest_y); -extern void XGetGeometry(Display *disp, Window w, Window *root, - int *x, int *y, unsigned int *width, unsigned int *height, - unsigned int *border_width, unsigned int *depth); +extern void XDestroySubwindows(Display* disp, Window Win); +extern void XDestroyWindow(Display* disp, Window Win); +extern void XQueryPointer(Display* disp, + Window Win, + Window* root, + Window* child, + int* root_x, + int* root_y, + int* win_x, + int* win_y, + unsigned int* keybut); +extern void XWarpPointer(Display* disp, + Window src, + Window dest, + int src_x, + int src_y, + unsigned int src_w, + unsigned int src_h, + int dest_x, + int dest_y); +extern void XGetGeometry(Display* disp, + Window w, + Window* root, + int* x, + int* y, + unsigned int* width, + unsigned int* height, + unsigned int* border_width, + unsigned int* depth); #endif /* NEED_XSTUFF */ #endif /* _Xstuff_h */ diff --git a/src/programs/view/buttons.cpp b/src/programs/view/buttons.cpp index 72f2ec13ca..ea66889c2b 100644 --- a/src/programs/view/buttons.cpp +++ b/src/programs/view/buttons.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,18 +53,18 @@ #include "x11.h" #include "xutil.h" -static void move_bbox(t_x11 *x11, t_butbox *bbox) +static void move_bbox(t_x11* x11, t_butbox* bbox) { int x0, y0; int i, bw; real idb, bh, one = 1.0; - t_windata *wd; + t_windata* wd; - bw = std::max(1, bbox->wd.width-2*(AIR+BORDER)); + bw = std::max(1, bbox->wd.width - 2 * (AIR + BORDER)); idb = bbox->nbut; - bh = (bbox->wd.height-AIR*(bbox->nbut+1)); + bh = (bbox->wd.height - AIR * (bbox->nbut + 1)); bh /= idb; - bh = std::max(bh, one); + bh = std::max(bh, one); x0 = AIR; y0 = AIR; @@ -76,17 +76,17 @@ static void move_bbox(t_x11 *x11, t_butbox *bbox) wd->color = WHITE; XMoveWindow(x11->disp, wd->self, x0, y0); XResizeWindow(x11->disp, wd->self, wd->width, wd->height); - y0 += AIR+bh; + y0 += AIR + bh; } } -static bool BBCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool BBCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_butbox *bbox; + t_butbox* bbox; if (event->type == ConfigureNotify) { - bbox = (t_butbox *)data; + bbox = (t_butbox*)data; bbox->wd.width = event->xconfigure.width; bbox->wd.height = event->xconfigure.height; move_bbox(x11, bbox); @@ -94,46 +94,44 @@ static bool BBCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) return false; } -static bool VBCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool VBCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_butbox *vbox; - int y0; + t_butbox* vbox; + int y0; if (event->type == Expose) { - vbox = (t_butbox *)data; - y0 = XTextHeight(x11->font)+2*AIR+1; + vbox = (t_butbox*)data; + y0 = XTextHeight(x11->font) + 2 * AIR + 1; XSetForeground(x11->disp, x11->gc, WHITE); - XClearArea(x11->disp, vbox->wd.self, 1, 1, vbox->wd.width-2, y0-1, False); - TextInRect(x11, vbox->wd.self, vbox->wd.text, - 1, 1, vbox->wd.width-2, y0-1, eXLeft, eYCenter); + XClearArea(x11->disp, vbox->wd.self, 1, 1, vbox->wd.width - 2, y0 - 1, False); + TextInRect(x11, vbox->wd.self, vbox->wd.text, 1, 1, vbox->wd.width - 2, y0 - 1, eXLeft, eYCenter); XDrawLine(x11->disp, vbox->wd.self, x11->gc, 0, y0, vbox->wd.width, y0); XSetForeground(x11->disp, x11->gc, x11->fg); } return false; } -void set_vbtime(t_x11 *x11, t_butbox *vbox, char *text) +void set_vbtime(t_x11* x11, t_butbox* vbox, char* text) { sfree(vbox->wd.text); vbox->wd.text = gmx_strdup(text); ExposeWin(x11->disp, vbox->wd.self); } -static bool ButtonCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool ButtonCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { XEvent letter; - t_mwbut *but; - t_windata *wd; + t_mwbut* but; + t_windata* wd; - but = (t_mwbut *)data; + but = (t_mwbut*)data; wd = &(but->wd); switch (event->type) { case Expose: XSetForeground(x11->disp, x11->gc, WHITE); - XDrawRoundRect(x11->disp, wd->self, x11->gc, - 0, 0, wd->width-1, wd->height-1); + XDrawRoundRect(x11->disp, wd->self, x11->gc, 0, 0, wd->width - 1, wd->height - 1); TextInWin(x11, wd, wd->text, eXCenter, eYCenter); XSetForeground(x11->disp, x11->gc, x11->fg); break; @@ -141,15 +139,13 @@ static bool ButtonCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) case EnterNotify: /* LightBorder(x11->disp,wd->self,WHITE);*/ XSetForeground(x11->disp, x11->gc, WHITE); - XDrawRoundRect(x11->disp, wd->self, x11->gc, - 1, 1, wd->width-3, wd->height-3); + XDrawRoundRect(x11->disp, wd->self, x11->gc, 1, 1, wd->width - 3, wd->height - 3); XSetForeground(x11->disp, x11->gc, x11->fg); break; case LeaveNotify: /* LightBorder(x11->disp,wd->self,BLUE);*/ XSetForeground(x11->disp, x11->gc, BLUE); - XDrawRoundRect(x11->disp, wd->self, x11->gc, - 1, 1, wd->width-3, wd->height-3); + XDrawRoundRect(x11->disp, wd->self, x11->gc, 1, 1, wd->width - 3, wd->height - 3); XSetForeground(x11->disp, x11->gc, x11->fg); break; @@ -164,30 +160,28 @@ static bool ButtonCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) letter.xclient.data.l[1] = (long)event->xbutton.button; XSendEvent(x11->disp, wd->Parent, True, 0, &letter); break; - default: - break; + default: break; } return false; } -t_butbox *init_vbox(t_x11 *x11, Window Parent, Window SendTo, unsigned long fg, unsigned long bg) +t_butbox* init_vbox(t_x11* x11, Window Parent, Window SendTo, unsigned long fg, unsigned long bg) { - Pixmap pm; - unsigned char *data; - t_butbox *vb; - int i, ID, x, y0; + Pixmap pm; + unsigned char* data; + t_butbox* vb; + int i, ID, x, y0; snew(vb, 1); - vb->nbut = IDNR-IDBUTNR-1; + vb->nbut = IDNR - IDBUTNR - 1; snew(vb->b, vb->nbut); /* VBox holder */ - y0 = XTextHeight(x11->font)+2*AIR+2; - InitWin(&vb->wd, 0, 0, vb->nbut*(play_width+AIR)+AIR, - y0+play_height+2*AIR, 1, "VCR - Control"); - vb->wd.self = XCreateSimpleWindow(x11->disp, Parent, - vb->wd.x, vb->wd.y, vb->wd.width, vb->wd.height, - vb->wd.bwidth, fg, bg); + y0 = XTextHeight(x11->font) + 2 * AIR + 2; + InitWin(&vb->wd, 0, 0, vb->nbut * (play_width + AIR) + AIR, y0 + play_height + 2 * AIR, 1, + "VCR - Control"); + vb->wd.self = XCreateSimpleWindow(x11->disp, Parent, vb->wd.x, vb->wd.y, vb->wd.width, + vb->wd.height, vb->wd.bwidth, fg, bg); x11->RegisterCallback(x11, vb->wd.self, Parent, VBCallBack, vb); x11->SetInputMask(x11, vb->wd.self, ExposureMask); @@ -195,82 +189,64 @@ t_butbox *init_vbox(t_x11 *x11, Window Parent, Window SendTo, unsigned long fg, (void)CWBackPixmap; for (i = 0; (i < vb->nbut); i++) { - ID = IDBUTNR+i+1; + ID = IDBUTNR + i + 1; switch (ID) { - case IDREWIND: - data = &(rewind_bits[0]); - break; - case IDSTEP: - data = play_bits; - break; - case IDFF: - data = ff_bits; - break; - case IDSTOP_ANI: - data = stop_ani_bits; - break; - default: - fprintf(stderr, "Invalid bitmap in init_vbox %d\n", ID); - std::exit(1); + case IDREWIND: data = &(rewind_bits[0]); break; + case IDSTEP: data = play_bits; break; + case IDFF: data = ff_bits; break; + case IDSTOP_ANI: data = stop_ani_bits; break; + default: fprintf(stderr, "Invalid bitmap in init_vbox %d\n", ID); std::exit(1); } /* Rely on the fact that all bitmaps are equal size */ - pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, - (char *)data, play_width, play_height, + pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char*)data, play_width, play_height, BLACK, LIGHTGREY, x11->depth); vb->b[i].ID = ID; vb->b[i].wd.Parent = SendTo; - vb->b[i].wd.self = - XCreateSimpleWindow(x11->disp, vb->wd.self, - x, y0+AIR, play_width, play_height, 0, WHITE, BLACK); + vb->b[i].wd.self = XCreateSimpleWindow(x11->disp, vb->wd.self, x, y0 + AIR, play_width, + play_height, 0, WHITE, BLACK); XSetWindowBackgroundPixmap(x11->disp, vb->b[i].wd.self, pm); - x11->RegisterCallback(x11, vb->b[i].wd.self, vb->wd.self, - ButtonCallBack, &(vb->b[i])); - x11->SetInputMask(x11, vb->b[i].wd.self, - ButtonPressMask | StructureNotifyMask); - x += play_width+AIR; + x11->RegisterCallback(x11, vb->b[i].wd.self, vb->wd.self, ButtonCallBack, &(vb->b[i])); + x11->SetInputMask(x11, vb->b[i].wd.self, ButtonPressMask | StructureNotifyMask); + x += play_width + AIR; } return vb; } -void show_but(t_x11 *x11, t_butbox *bbox) +void show_but(t_x11* x11, t_butbox* bbox) { XMapWindow(x11->disp, bbox->wd.self); XMapSubwindows(x11->disp, bbox->wd.self); } -void hide_but(t_x11 *x11, t_butbox *bbox) +void hide_but(t_x11* x11, t_butbox* bbox) { XUnmapWindow(x11->disp, bbox->wd.self); XUnmapSubwindows(x11->disp, bbox->wd.self); } -t_butbox *init_bbox(t_x11 *x11, Window Parent, Window SendTo, - int width, unsigned long fg, unsigned long bg) +t_butbox* init_bbox(t_x11* x11, Window Parent, Window SendTo, int width, unsigned long fg, unsigned long bg) { - t_butbox *bbox; - static const char *lbut[IDBUTNR] = { - "< X-Rotate >", "< Y-Rotate >", "< Z-Rotate >", - "< X-Move >", "< Y-Move >", "< Z-Move >", "< Scale >", + t_butbox* bbox; + static const char* lbut[IDBUTNR] = { + "< X-Rotate >", "< Y-Rotate >", "< Z-Rotate >", "< X-Move >", + "< Y-Move >", "< Z-Move >", "< Scale >", }; - int i, y0, h0; - t_mwbut *but; - Window DrawOn; + int i, y0, h0; + t_mwbut* but; + Window DrawOn; snew(bbox, 1); bbox->nbut = IDBUTNR; snew(bbox->b, bbox->nbut); - y0 = XTextHeight(x11->font)+2*(AIR+BORDER); - - InitWin(&(bbox->wd), 0, 0, /*width,(y0+AIR)*IDBUTNR+AIR+2*BORDER,*/ 1, 1, - 1, "Button Box"); - width -= 2*AIR+2*BORDER; - bbox->wd.self = XCreateSimpleWindow(x11->disp, Parent, - bbox->wd.x, bbox->wd.y, bbox->wd.width, - bbox->wd.height, bbox->wd.bwidth, - fg, bg); + y0 = XTextHeight(x11->font) + 2 * (AIR + BORDER); + + InitWin(&(bbox->wd), 0, 0, /*width,(y0+AIR)*IDBUTNR+AIR+2*BORDER,*/ 1, 1, 1, "Button Box"); + width -= 2 * AIR + 2 * BORDER; + bbox->wd.self = XCreateSimpleWindow(x11->disp, Parent, bbox->wd.x, bbox->wd.y, bbox->wd.width, + bbox->wd.height, bbox->wd.bwidth, fg, bg); x11->RegisterCallback(x11, bbox->wd.self, Parent, BBCallBack, bbox); x11->SetInputMask(x11, bbox->wd.self, StructureNotifyMask); @@ -280,21 +256,18 @@ t_butbox *init_bbox(t_x11 *x11, Window Parent, Window SendTo, { but = &(bbox->b[i]); InitWin(&but->wd, AIR, h0, width, y0, 1, lbut[i]); - h0 += y0+AIR; + h0 += y0 + AIR; but->wd.Parent = SendTo; but->ID = i; - but->wd.self = XCreateSimpleWindow(x11->disp, DrawOn, - but->wd.x, but->wd.y, - but->wd.width, but->wd.height, - but->wd.bwidth, bg, bg); + but->wd.self = XCreateSimpleWindow(x11->disp, DrawOn, but->wd.x, but->wd.y, but->wd.width, + but->wd.height, but->wd.bwidth, bg, bg); x11->RegisterCallback(x11, but->wd.self, DrawOn, ButtonCallBack, but); - x11->SetInputMask(x11, but->wd.self, ExposureMask | ButtonPressMask | - EnterLeave); + x11->SetInputMask(x11, but->wd.self, ExposureMask | ButtonPressMask | EnterLeave); } return bbox; } -void done_bbox(t_x11 *x11, t_butbox *bbox) +void done_bbox(t_x11* x11, t_butbox* bbox) { int i; diff --git a/src/programs/view/buttons.h b/src/programs/view/buttons.h index 7368f86f53..f70dc1968c 100644 --- a/src/programs/view/buttons.h +++ b/src/programs/view/buttons.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,40 +40,53 @@ #include "xutil.h" -enum { - IDROTX, IDROTY, IDROTZ, IDTRANSX, IDTRANSY, IDTRANSZ, IDZOOM, IDBUTNR, - IDREWIND, IDSTEP, IDFF, IDSTOP_ANI, IDNR, - IDDRAWMOL, IDLABEL +enum +{ + IDROTX, + IDROTY, + IDROTZ, + IDTRANSX, + IDTRANSY, + IDTRANSZ, + IDZOOM, + IDBUTNR, + IDREWIND, + IDSTEP, + IDFF, + IDSTOP_ANI, + IDNR, + IDDRAWMOL, + IDLABEL }; -#define AIR 3 /* extra space between child windows */ -#define BORDER 1 +#define AIR 3 /* extra space between child windows */ +#define BORDER 1 #define EnterLeave (EnterWindowMask | LeaveWindowMask) -typedef struct { +typedef struct +{ t_windata wd; int ID; } t_mwbut; -typedef struct { - t_windata wd; - int nbut; - t_mwbut *b; +typedef struct +{ + t_windata wd; + int nbut; + t_mwbut* b; } t_butbox; -extern t_butbox *init_vbox(t_x11 *x11, Window Parent, Window SendTo, - unsigned long fg, unsigned long bg); +extern t_butbox* init_vbox(t_x11* x11, Window Parent, Window SendTo, unsigned long fg, unsigned long bg); -extern void set_vbtime(t_x11 *x11, t_butbox *vbox, char *text); +extern void set_vbtime(t_x11* x11, t_butbox* vbox, char* text); -extern t_butbox *init_bbox(t_x11 *x11, Window Parent, Window SendTo, - int width, unsigned long fg, unsigned long bg); +extern t_butbox* init_bbox(t_x11* x11, Window Parent, Window SendTo, int width, unsigned long fg, unsigned long bg); -extern void show_but(t_x11 *x11, t_butbox *bbox); +extern void show_but(t_x11* x11, t_butbox* bbox); -extern void hide_but(t_x11 *x11, t_butbox *bbox); +extern void hide_but(t_x11* x11, t_butbox* bbox); -extern void done_bbox(t_x11 *x11, t_butbox *bbox); +extern void done_bbox(t_x11* x11, t_butbox* bbox); #endif diff --git a/src/programs/view/dialogs.cpp b/src/programs/view/dialogs.cpp index 1d3c4b5065..3d7ea27ccf 100644 --- a/src/programs/view/dialogs.cpp +++ b/src/programs/view/dialogs.cpp @@ -45,7 +45,7 @@ #include #ifdef HAVE_UNISTD_H -#include // for fork() +# include // for fork() #endif #include "gromacs/mdtypes/md_enums.h" @@ -64,7 +64,7 @@ #define MBFLAGS /* MB_APPLMODAL | */ MB_DONTSHOW -void write_gmx(t_x11 *x11, t_gmx *gmx, int mess) +void write_gmx(t_x11* x11, t_gmx* gmx, int mess) { XEvent letter; @@ -78,9 +78,9 @@ void write_gmx(t_x11 *x11, t_gmx *gmx, int mess) XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter); } -static void shell_comm(const char *title, const char *script, int nsleep) +static void shell_comm(const char* title, const char* script, int nsleep) { - FILE *tfil; + FILE* tfil; char command[STRLEN]; char tmp[32]; @@ -106,7 +106,7 @@ static void shell_comm(const char *title, const char *script, int nsleep) #endif } -void show_mb(t_gmx *gmx, int mb) +void show_mb(t_gmx* gmx, int mb) { if (mb >= 0 && mb < emNR) { @@ -115,7 +115,7 @@ void show_mb(t_gmx *gmx, int mb) } } -static void hide_mb(t_gmx *gmx) +static void hide_mb(t_gmx* gmx) { if (gmx->which_mb >= 0 && gmx->which_mb < emNR) { @@ -124,38 +124,32 @@ static void hide_mb(t_gmx *gmx) } } -static void MBCallback(t_x11 * /*x11*/, int dlg_mess, int /*item_id*/, - char * /*set*/, void *data) +static void MBCallback(t_x11* /*x11*/, int dlg_mess, int /*item_id*/, char* /*set*/, void* data) { - t_gmx *gmx; + t_gmx* gmx; - gmx = static_cast(data); + gmx = static_cast(data); if (dlg_mess == DLG_EXIT) { hide_mb(gmx); } } -static t_dlg *about_mb(t_x11 *x11, t_gmx *gmx) +static t_dlg* about_mb(t_x11* x11, t_gmx* gmx) { - const char *lines[] = { - " G R O M A C S", - " Machine for Simulating Chemistry", - " Copyright (c) 1992-2013", - " Berk Hess, David van der Spoel, Erik Lindahl", - " and many collaborators!" - }; - - return MessageBox(x11, gmx->wd->self, gmx->wd->text, - asize(lines), lines, MB_OK | MB_ICONGMX | MBFLAGS, - MBCallback, gmx); + const char* lines[] = { " G R O M A C S", " Machine for Simulating Chemistry", + " Copyright (c) 1992-2013", + " Berk Hess, David van der Spoel, Erik Lindahl", + " and many collaborators!" }; + + return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, + MB_OK | MB_ICONGMX | MBFLAGS, MBCallback, gmx); } -static void QuitCB(t_x11 *x11, int dlg_mess, int /*item_id*/, - char *set, void *data) +static void QuitCB(t_x11* x11, int dlg_mess, int /*item_id*/, char* set, void* data) { - t_gmx *gmx; - gmx = static_cast(data); + t_gmx* gmx; + gmx = static_cast(data); hide_mb(gmx); if (dlg_mess == DLG_EXIT) @@ -167,69 +161,55 @@ static void QuitCB(t_x11 *x11, int dlg_mess, int /*item_id*/, } } -static t_dlg *quit_mb(t_x11 *x11, t_gmx *gmx) +static t_dlg* quit_mb(t_x11* x11, t_gmx* gmx) { - const char *lines[] = { - " Do you really want to Quit ?" - }; - - return MessageBox(x11, gmx->wd->self, gmx->wd->text, - asize(lines), lines, - MB_YESNO | MB_ICONSTOP | MBFLAGS, - QuitCB, gmx); + const char* lines[] = { " Do you really want to Quit ?" }; + + return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, + MB_YESNO | MB_ICONSTOP | MBFLAGS, QuitCB, gmx); } -static t_dlg *help_mb(t_x11 *x11, t_gmx *gmx) +static t_dlg* help_mb(t_x11* x11, t_gmx* gmx) { - const char *lines[] = { - " Help will soon be added" - }; - - return MessageBox(x11, gmx->wd->self, gmx->wd->text, - asize(lines), lines, - MB_OK | MB_ICONINFORMATION | MBFLAGS, - MBCallback, gmx); + const char* lines[] = { " Help will soon be added" }; + + return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, + MB_OK | MB_ICONINFORMATION | MBFLAGS, MBCallback, gmx); } -static t_dlg *ni_mb(t_x11 *x11, t_gmx *gmx) +static t_dlg* ni_mb(t_x11* x11, t_gmx* gmx) { - const char *lines[] = { - " This feature has not been", - " implemented yet." - }; - - return MessageBox(x11, gmx->wd->self, gmx->wd->text, - asize(lines), lines, - MB_OK | MB_ICONEXCLAMATION | MBFLAGS, - MBCallback, gmx); + const char* lines[] = { " This feature has not been", " implemented yet." }; + + return MessageBox(x11, gmx->wd->self, gmx->wd->text, asize(lines), lines, + MB_OK | MB_ICONEXCLAMATION | MBFLAGS, MBCallback, gmx); } -enum { - eExE, eExGrom, eExPdb, eExConf, eExNR +enum +{ + eExE, + eExGrom, + eExPdb, + eExConf, + eExNR }; -static void ExportCB(t_x11 *x11, int dlg_mess, int item_id, - char *set, void *data) +static void ExportCB(t_x11* x11, int dlg_mess, int item_id, char* set, void* data) { - bool bOk; - t_gmx *gmx; - t_dlg *dlg; + bool bOk; + t_gmx* gmx; + t_dlg* dlg; - gmx = static_cast(data); + gmx = static_cast(data); dlg = gmx->dlgs[edExport]; switch (dlg_mess) { case DLG_SET: switch (item_id) { - case eExGrom: - gmx->ExpMode = eExpGromos; - break; - case eExPdb: - gmx->ExpMode = eExpPDB; - break; - default: - break; + case eExGrom: gmx->ExpMode = eExpGromos; break; + case eExPdb: gmx->ExpMode = eExpPDB; break; + default: break; } #ifdef DEBUG std::fprintf(stderr, "exportcb: item_id=%d\n", item_id); @@ -249,25 +229,37 @@ static void ExportCB(t_x11 *x11, int dlg_mess, int item_id, } } -enum { - eg0, egTOPOL, egCONFIN, egPARAM, eg1, eg1PROC, eg32PROC +enum +{ + eg0, + egTOPOL, + egCONFIN, + egPARAM, + eg1, + eg1PROC, + eg32PROC }; -enum bond_set { - ebShowH = 11, ebDPlus, ebRMPBC, ebCue, ebSkip, ebWait +enum bond_set +{ + ebShowH = 11, + ebDPlus, + ebRMPBC, + ebCue, + ebSkip, + ebWait }; -static void BondsCB(t_x11 *x11, int dlg_mess, int item_id, - char *set, void *data) +static void BondsCB(t_x11* x11, int dlg_mess, int item_id, char* set, void* data) { static int ebond = -1; static int ebox = -1; bool bOk, bBond = false; int nskip, nwait; - t_gmx *gmx; - char *endptr; + t_gmx* gmx; + char* endptr; - gmx = static_cast(data); + gmx = static_cast(data); if (ebond == -1) { ebond = gmx->man->molw->bond_type; @@ -278,12 +270,12 @@ static void BondsCB(t_x11 *x11, int dlg_mess, int item_id, case DLG_SET: if (item_id <= eBNR) { - ebond = item_id-1; + ebond = item_id - 1; bBond = false; } - else if (item_id <= eBNR+esbNR+1) + else if (item_id <= eBNR + esbNR + 1) { - ebox = item_id-eBNR-2; + ebox = item_id - eBNR - 2; bBond = true; } else @@ -293,24 +285,16 @@ static void BondsCB(t_x11 *x11, int dlg_mess, int item_id, switch (item_id) { - case ebShowH: - toggle_hydrogen(x11, gmx->man->molw); - break; - case ebDPlus: - DO_NOT(gmx->man->bPlus); + case ebShowH: toggle_hydrogen(x11, gmx->man->molw); break; + case ebDPlus: DO_NOT(gmx->man->bPlus); #ifdef DEBUG - std::fprintf(stderr, "gmx->man->bPlus=%s\n", - gmx->man->bPlus ? "true" : "false"); + std::fprintf(stderr, "gmx->man->bPlus=%s\n", gmx->man->bPlus ? "true" : "false"); #endif break; - case ebRMPBC: - toggle_pbc(gmx->man); - break; - case ebCue: - DO_NOT(gmx->man->bSort); + case ebRMPBC: toggle_pbc(gmx->man); break; + case ebCue: DO_NOT(gmx->man->bSort); #ifdef DEBUG - std::fprintf(stderr, "gmx->man->bSort=%s\n", - gmx->man->bSort ? "true" : "false"); + std::fprintf(stderr, "gmx->man->bSort=%s\n", gmx->man->bSort ? "true" : "false"); #endif break; case ebSkip: @@ -355,42 +339,24 @@ static void BondsCB(t_x11 *x11, int dlg_mess, int item_id, { switch (ebond) { - case eBThin: - write_gmx(x11, gmx, IDTHIN); - break; - case eBFat: - write_gmx(x11, gmx, IDFAT); - break; - case eBVeryFat: - write_gmx(x11, gmx, IDVERYFAT); - break; - case eBSpheres: - write_gmx(x11, gmx, IDBALLS); - break; + case eBThin: write_gmx(x11, gmx, IDTHIN); break; + case eBFat: write_gmx(x11, gmx, IDFAT); break; + case eBVeryFat: write_gmx(x11, gmx, IDVERYFAT); break; + case eBSpheres: write_gmx(x11, gmx, IDBALLS); break; default: - gmx_fatal(FARGS, "Invalid bond type %d at %s, %d", - ebond, __FILE__, __LINE__); + gmx_fatal(FARGS, "Invalid bond type %d at %s, %d", ebond, __FILE__, __LINE__); } } else { switch (ebox) { - case esbNone: - write_gmx(x11, gmx, IDNOBOX); - break; - case esbRect: - write_gmx(x11, gmx, IDRECTBOX); - break; - case esbTri: - write_gmx(x11, gmx, IDTRIBOX); - break; - case esbTrunc: - write_gmx(x11, gmx, IDTOBOX); - break; + case esbNone: write_gmx(x11, gmx, IDNOBOX); break; + case esbRect: write_gmx(x11, gmx, IDRECTBOX); break; + case esbTri: write_gmx(x11, gmx, IDTRIBOX); break; + case esbTrunc: write_gmx(x11, gmx, IDTOBOX); break; default: - gmx_fatal(FARGS, "Invalid box type %d at %s, %d", - ebox, __FILE__, __LINE__); + gmx_fatal(FARGS, "Invalid box type %d at %s, %d", ebox, __FILE__, __LINE__); } } } @@ -398,31 +364,35 @@ static void BondsCB(t_x11 *x11, int dlg_mess, int item_id, } } -enum { - esFUNCT = 1, esBSHOW, esINFIL, esINDEXFIL, esLSQ, esSHOW, esPLOTFIL +enum +{ + esFUNCT = 1, + esBSHOW, + esINFIL, + esINDEXFIL, + esLSQ, + esSHOW, + esPLOTFIL }; -typedef t_dlg *t_mmb (t_x11 *x11, t_gmx *gmx); +typedef t_dlg* t_mmb(t_x11* x11, t_gmx* gmx); -typedef struct { - const char *dlgfile; - DlgCallback *cb; +typedef struct +{ + const char* dlgfile; + DlgCallback* cb; } t_dlginit; -void init_dlgs(t_x11 *x11, t_gmx *gmx) +void init_dlgs(t_x11* x11, t_gmx* gmx) { - static t_dlginit di[] = { - { "export.dlg", ExportCB }, - { "bonds.dlg", BondsCB } - }; - static t_mmb *mi[emNR] = { quit_mb, help_mb, about_mb, ni_mb }; + static t_dlginit di[] = { { "export.dlg", ExportCB }, { "bonds.dlg", BondsCB } }; + static t_mmb* mi[emNR] = { quit_mb, help_mb, about_mb, ni_mb }; snew(gmx->dlgs, edNR); for (int i = 0; (i < asize(di)); i++) { - gmx->dlgs[i] = ReadDlg(x11, gmx->wd->self, di[i].dlgfile, - di[i].dlgfile, - 0, 0, true, false, di[i].cb, gmx); + gmx->dlgs[i] = ReadDlg(x11, gmx->wd->self, di[i].dlgfile, di[i].dlgfile, 0, 0, true, false, + di[i].cb, gmx); } gmx->dlgs[edFilter] = select_filter(x11, gmx); @@ -435,7 +405,7 @@ void init_dlgs(t_x11 *x11, t_gmx *gmx) gmx->which_mb = -1; } -void done_dlgs(t_gmx *gmx) +void done_dlgs(t_gmx* gmx) { int i; @@ -449,7 +419,7 @@ void done_dlgs(t_gmx *gmx) } } -void edit_file(const char *fn) +void edit_file(const char* fn) { if (fork() == 0) { diff --git a/src/programs/view/dialogs.h b/src/programs/view/dialogs.h index 3e69058142..ecad148d30 100644 --- a/src/programs/view/dialogs.h +++ b/src/programs/view/dialogs.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,73 +43,125 @@ #include "pulldown.h" #include "xdlg.h" -typedef struct { - bool bMapped; - t_dlg *dlg; +typedef struct +{ + bool bMapped; + t_dlg* dlg; } t_dialogs; -enum eDialogs { - edExport, edBonds, edFilter, edNR +enum eDialogs +{ + edExport, + edBonds, + edFilter, + edNR }; -enum eMBoxes { - emQuit, emHelp, emAbout, emNotImplemented, emNR +enum eMBoxes +{ + emQuit, + emHelp, + emAbout, + emNotImplemented, + emNR }; -enum eExport { - eExpGromos, eExpPDB, eExpNR +enum eExport +{ + eExpGromos, + eExpPDB, + eExpNR }; -typedef struct { - char confout[256]; /* Export file */ - int ExpMode; /* Export mode */ - t_dlg **dlgs; /* Temporary storage for dlgs */ - int which_mb; /* Which mb is visible */ - t_dlg **mboxes; /* id for message boxes */ - t_filter *filter; /* Filter for visibility etc. */ - t_windata *wd; /* The main window */ - t_pulldown *pd; /* The pull-down menu */ - t_manager *man; /* The manager */ - /*t_statrec *sr;*/ /* The statistics dlg */ - t_logo *logo; /* The gromacs logo */ +typedef struct +{ + char confout[256]; /* Export file */ + int ExpMode; /* Export mode */ + t_dlg** dlgs; /* Temporary storage for dlgs */ + int which_mb; /* Which mb is visible */ + t_dlg** mboxes; /* id for message boxes */ + t_filter* filter; /* Filter for visibility etc. */ + t_windata* wd; /* The main window */ + t_pulldown* pd; /* The pull-down menu */ + t_manager* man; /* The manager */ + /*t_statrec *sr;*/ /* The statistics dlg */ + t_logo* logo; /* The gromacs logo */ } t_gmx; -enum { - IDNEW, IDOPEN, IDOPENED, IDCLOSE, IDIMPORT, IDEXPORT, IDDOEXPORT, IDQUIT, IDTERM, - IDEDITTOP, IDEDITCOORDS, IDEDITPARAMS, - IDGROMPP, IDRUNMD, IDDOGROMPP, IDGSTAT, IDDOGSTAT, IDDORUNMD, - IDFILTER, IDDOFILTER, - IDANIMATE, IDSHOWBOX, IDRMPBC, IDHYDROGEN, IDLABELSOFF, IDRESETVIEW, IDPHOTO, - IDDUMPWIN, IDDODUMP, - IDBONDOPTS, IDTHIN, IDFAT, IDVERYFAT, IDBALLS, - IDNOBOX, IDRECTBOX, IDTRIBOX, IDTOBOX, - IDBOND, IDANGLE, IDDIH, IDRMS, IDRDF, IDENERGIES, IDCORR, - IDHELP, IDABOUT, +enum +{ + IDNEW, + IDOPEN, + IDOPENED, + IDCLOSE, + IDIMPORT, + IDEXPORT, + IDDOEXPORT, + IDQUIT, + IDTERM, + IDEDITTOP, + IDEDITCOORDS, + IDEDITPARAMS, + IDGROMPP, + IDRUNMD, + IDDOGROMPP, + IDGSTAT, + IDDOGSTAT, + IDDORUNMD, + IDFILTER, + IDDOFILTER, + IDANIMATE, + IDSHOWBOX, + IDRMPBC, + IDHYDROGEN, + IDLABELSOFF, + IDRESETVIEW, + IDPHOTO, + IDDUMPWIN, + IDDODUMP, + IDBONDOPTS, + IDTHIN, + IDFAT, + IDVERYFAT, + IDBALLS, + IDNOBOX, + IDRECTBOX, + IDTRIBOX, + IDTOBOX, + IDBOND, + IDANGLE, + IDDIH, + IDRMS, + IDRDF, + IDENERGIES, + IDCORR, + IDHELP, + IDABOUT, /* Last line specifies how many IDs there are */ IDMENUNR }; -extern void run_grompp(t_gmx *gmx); +extern void run_grompp(t_gmx* gmx); -extern void run_mdrun(t_gmx *gmx); +extern void run_mdrun(t_gmx* gmx); -extern void write_gmx(t_x11 *x11, t_gmx *gmx, int mess); +extern void write_gmx(t_x11* x11, t_gmx* gmx, int mess); /*extern void run_sr(t_statrec *sr); extern t_statrec *init_sr();*/ -extern void init_dlgs(t_x11 *x11, t_gmx *gmx); +extern void init_dlgs(t_x11* x11, t_gmx* gmx); -extern void show_mb(t_gmx *gmx, int mb); +extern void show_mb(t_gmx* gmx, int mb); -extern void done_dlgs(t_gmx *gmx); +extern void done_dlgs(t_gmx* gmx); -extern void edit_file(const char *fn); +extern void edit_file(const char* fn); -extern t_filter *init_filter(t_atoms *atoms, const char *fn, int natom_trx); +extern t_filter* init_filter(t_atoms* atoms, const char* fn, int natom_trx); -extern t_dlg *select_filter(t_x11 *x11, t_gmx *gmx); +extern t_dlg* select_filter(t_x11* x11, t_gmx* gmx); #endif diff --git a/src/programs/view/fgrid.cpp b/src/programs/view/fgrid.cpp index 995dfc6f8e..85506ef39f 100644 --- a/src/programs/view/fgrid.cpp +++ b/src/programs/view/fgrid.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,50 +47,25 @@ #include "gromacs/utility/futil.h" #include "gromacs/utility/smalloc.h" -static const char *type[] = { - "button", "radiobuttons", "groupbox", "checkbox", - "pixmap", "statictext", "edittext", "defbutton" -}; +static const char* type[] = { "button", "radiobuttons", "groupbox", "checkbox", + "pixmap", "statictext", "edittext", "defbutton" }; -static void ReadDlgError(const char *infile, eDLGERR err, const char *s, - const char *file, int line) +static void ReadDlgError(const char* infile, eDLGERR err, const char* s, const char* file, int line) { std::fprintf(stderr, "Error: "); switch (err) { - case eNOVALS: - std::fprintf(stderr, "Not enough values for %s", s); - break; - case eGRIDEXP: - std::fprintf(stderr, "'grid' expected instead of %s", s); - break; - case eACCOEXP: - std::fprintf(stderr, "'{' expected instead of %s", s); - break; - case eACCCEXP: - std::fprintf(stderr, "'}' expected instead of %s", s); - break; - case eGRPEXP: - std::fprintf(stderr, "'group' expected instead of %s", s); - break; - case eITEMEXP: - std::fprintf(stderr, "item expected instead of %s", s); - break; - case eSAMEPOINT: - std::fprintf(stderr, "grid point for %s already in use", s); - break; - case eTOOWIDE: - std::fprintf(stderr, "grid too wide for %s", s); - break; - case eTOOHIGH: - std::fprintf(stderr, "grid too high for %s", s); - break; - case eQUOTE: - std::fprintf(stderr, "quote expected instead of %s", s); - break; - default: - std::fprintf(stderr, "????"); - break; + case eNOVALS: std::fprintf(stderr, "Not enough values for %s", s); break; + case eGRIDEXP: std::fprintf(stderr, "'grid' expected instead of %s", s); break; + case eACCOEXP: std::fprintf(stderr, "'{' expected instead of %s", s); break; + case eACCCEXP: std::fprintf(stderr, "'}' expected instead of %s", s); break; + case eGRPEXP: std::fprintf(stderr, "'group' expected instead of %s", s); break; + case eITEMEXP: std::fprintf(stderr, "item expected instead of %s", s); break; + case eSAMEPOINT: std::fprintf(stderr, "grid point for %s already in use", s); break; + case eTOOWIDE: std::fprintf(stderr, "grid too wide for %s", s); break; + case eTOOHIGH: std::fprintf(stderr, "grid too high for %s", s); break; + case eQUOTE: std::fprintf(stderr, "quote expected instead of %s", s); break; + default: std::fprintf(stderr, "????"); break; } std::fprintf(stderr, " in file %s\n", infile); std::fprintf(stderr, "source file: %s, line: %d\n", file, line); @@ -99,7 +74,7 @@ static void ReadDlgError(const char *infile, eDLGERR err, const char *s, #define ReadDlgErr(in, er, es) ReadDlgError(in, er, es, __FILE__, __LINE__) -static void ReadAccOpen(const char *infile, FILE *in) +static void ReadAccOpen(const char* infile, FILE* in) { char buf[STRLEN]; int result; @@ -111,7 +86,7 @@ static void ReadAccOpen(const char *infile, FILE *in) } } -static void ReadAccClose(const char *infile, FILE *in) +static void ReadAccClose(const char* infile, FILE* in) { char buf[STRLEN]; int result; @@ -123,7 +98,7 @@ static void ReadAccClose(const char *infile, FILE *in) } } -void ReadQuoteString(const char *infile, FILE *in, char *buf) +void ReadQuoteString(const char* infile, FILE* in, char* buf) { char c[2]; int i = 0; @@ -145,7 +120,7 @@ void ReadQuoteString(const char *infile, FILE *in, char *buf) buf[i] = '\0'; } -static void ReadQuoteStringOrAccClose(FILE *in, char *buf) +static void ReadQuoteStringOrAccClose(FILE* in, char* buf) { char c; int i = 0; @@ -160,8 +135,7 @@ static void ReadQuoteStringOrAccClose(FILE *in, char *buf) buf[1] = '\0'; return; } - } - while (c != '"'); + } while (c != '"'); /* Read until second quote */ while ((c = std::fgetc(in)) != '"') @@ -171,14 +145,14 @@ static void ReadQuoteStringOrAccClose(FILE *in, char *buf) buf[i] = '\0'; } -static bool bNotAccClose(const char *buf) +static bool bNotAccClose(const char* buf) { return (std::strcmp(buf, "}") != 0); } -static t_fitem *NewFItem(void) +static t_fitem* NewFItem(void) { - t_fitem *fitem; + t_fitem* fitem; snew(fitem, 1); fitem->nname = 0; @@ -191,24 +165,24 @@ static t_fitem *NewFItem(void) return fitem; } -static t_fsimple *NewFSimple(void) +static t_fsimple* NewFSimple(void) { - t_fsimple *fsimple; + t_fsimple* fsimple; snew(fsimple, 1); return fsimple; } -static void AddFItemName(t_fitem *fitem, char *name) +static void AddFItemName(t_fitem* fitem, char* name) { srenew(fitem->name, ++fitem->nname); - fitem->name[fitem->nname-1] = gmx_strdup(name); + fitem->name[fitem->nname - 1] = gmx_strdup(name); } -static t_fgroup *NewFGroup(void) +static t_fgroup* NewFGroup(void) { - t_fgroup *fgroup; + t_fgroup* fgroup; snew(fgroup, 1); fgroup->name = nullptr; @@ -218,29 +192,29 @@ static t_fgroup *NewFGroup(void) return fgroup; } -static void AddFGroupFItem(t_fgroup *fgroup, t_fitem *fitem) +static void AddFGroupFItem(t_fgroup* fgroup, t_fitem* fitem) { srenew(fgroup->fitem, ++fgroup->nfitem); - fgroup->fitem[fgroup->nfitem-1] = fitem; + fgroup->fitem[fgroup->nfitem - 1] = fitem; } -static t_fgroup *AddFGridFGroup(t_fgrid *fgrid) +static t_fgroup* AddFGridFGroup(t_fgrid* fgrid) { srenew(fgrid->fgroup, ++fgrid->nfgroup); - fgrid->fgroup[fgrid->nfgroup-1] = NewFGroup(); - return fgrid->fgroup[fgrid->nfgroup-1]; + fgrid->fgroup[fgrid->nfgroup - 1] = NewFGroup(); + return fgrid->fgroup[fgrid->nfgroup - 1]; } -static t_fsimple *AddFGridFSimple(t_fgrid *fgrid) +static t_fsimple* AddFGridFSimple(t_fgrid* fgrid) { srenew(fgrid->fsimple, ++fgrid->nfsimple); - fgrid->fsimple[fgrid->nfsimple-1] = NewFSimple(); - return fgrid->fsimple[fgrid->nfsimple-1]; + fgrid->fsimple[fgrid->nfsimple - 1] = NewFSimple(); + return fgrid->fsimple[fgrid->nfsimple - 1]; } -static t_fgrid *NewFGrid(void) +static t_fgrid* NewFGrid(void) { - t_fgrid *fgrid; + t_fgrid* fgrid; snew(fgrid, 1); fgrid->w = 0; @@ -253,7 +227,7 @@ static t_fgrid *NewFGrid(void) return fgrid; } -static void DoneFItem(t_fitem *fitem) +static void DoneFItem(t_fitem* fitem) { int i; @@ -268,7 +242,7 @@ static void DoneFItem(t_fitem *fitem) sfree(fitem->help); } -static void DoneFGroup(t_fgroup *fgroup) +static void DoneFGroup(t_fgroup* fgroup) { int i; @@ -280,13 +254,13 @@ static void DoneFGroup(t_fgroup *fgroup) sfree(fgroup->fitem); } -static void DoneFSimple(t_fsimple *fsimple) +static void DoneFSimple(t_fsimple* fsimple) { DoneFItem(fsimple->fitem); sfree(fsimple->fitem); } -void DoneFGrid(t_fgrid *fgrid) +void DoneFGrid(t_fgrid* fgrid) { int i; @@ -302,15 +276,15 @@ void DoneFGrid(t_fgrid *fgrid) sfree(fgrid->fsimple); } -static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf) +static t_fitem* ScanFItem(const char* infile, FILE* in, char* buf) { char set[STRLEN], get[STRLEN], help[STRLEN], def[STRLEN]; int edlg; - t_fitem *fitem; + t_fitem* fitem; fitem = NewFItem(); - for (edlg = 0; (edlg < edlgNR+1); edlg++) + for (edlg = 0; (edlg < edlgNR + 1); edlg++) { if (std::strcmp(buf, type[edlg]) == 0) { @@ -323,7 +297,7 @@ static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf) edlg = edlgBN; fitem->bDef = true; } - if (edlg == edlgNR+1) + if (edlg == edlgNR + 1) { ReadDlgErr(infile, eITEMEXP, buf); } @@ -348,11 +322,8 @@ static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf) } break; case edlgPM: - case edlgGB: - ReadDlgErr(infile, eITEMEXP, type[edlg]); - break; - default: - break; + case edlgGB: ReadDlgErr(infile, eITEMEXP, type[edlg]); break; + default: break; } ReadQuoteString(infile, in, set); ReadQuoteString(infile, in, get); @@ -366,19 +337,19 @@ static t_fitem *ScanFItem(const char *infile, FILE *in, char *buf) return fitem; } -t_fgrid *FGridFromFile(const char *infile) +t_fgrid* FGridFromFile(const char* infile) { - char buf[STRLEN]; - int result; + char buf[STRLEN]; + int result; - t_fgrid *fgrid; - t_fgroup *fgroup; - t_fsimple *fsimple; - int gridx, gridy; + t_fgrid* fgrid; + t_fgroup* fgroup; + t_fsimple* fsimple; + int gridx, gridy; gmx::FilePtr inGuard = gmx::openLibraryFile(infile); - FILE *in = inGuard.get(); - result = std::fscanf(in, "%6s", buf); + FILE* in = inGuard.get(); + result = std::fscanf(in, "%6s", buf); if ((1 != result) || std::strcmp(buf, "grid") != 0) { ReadDlgErr(infile, eGRIDEXP, buf); @@ -403,11 +374,11 @@ t_fgrid *FGridFromFile(const char *infile) { ReadDlgErr(infile, eNOVALS, "group x,y,w,h"); } - if (fgroup->x+fgroup->w > gridx) + if (fgroup->x + fgroup->w > gridx) { ReadDlgErr(infile, eTOOWIDE, buf); } - if (fgroup->y+fgroup->h > gridy) + if (fgroup->y + fgroup->h > gridy) { ReadDlgErr(infile, eTOOHIGH, buf); } @@ -426,11 +397,11 @@ t_fgrid *FGridFromFile(const char *infile) { ReadDlgErr(infile, eNOVALS, "simple x,y,w,h"); } - if (fsimple->x+fsimple->w > gridx) + if (fsimple->x + fsimple->w > gridx) { ReadDlgErr(infile, eTOOWIDE, "simple"); } - if (fsimple->y+fsimple->h > gridy) + if (fsimple->y + fsimple->h > gridy) { ReadDlgErr(infile, eTOOHIGH, "simple"); } @@ -458,12 +429,12 @@ t_fgrid *FGridFromFile(const char *infile) return fgrid; } -static void DumpFItem(t_fitem *fitem) +static void DumpFItem(t_fitem* fitem) { int i; - std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {", - type[fitem->edlg], fitem->set, fitem->get, fitem->def, fitem->help); + std::printf(" type: %s, set: '%s', get: '%s', def: '%s', help: '%s'\n {", type[fitem->edlg], + fitem->set, fitem->get, fitem->def, fitem->help); for (i = 0; (i < fitem->nname); i++) { std::printf(" '%s'", fitem->name[i]); @@ -471,13 +442,13 @@ static void DumpFItem(t_fitem *fitem) std::printf(" }\n"); } -static void DumpFSimple(t_fsimple *fsimple) +static void DumpFSimple(t_fsimple* fsimple) { std::printf("Simple %dx%d at %d,%d\n", fsimple->w, fsimple->h, fsimple->x, fsimple->y); DumpFItem(fsimple->fitem); } -static void DumpFGroup(t_fgroup *fgroup) +static void DumpFGroup(t_fgroup* fgroup) { int i; @@ -488,7 +459,7 @@ static void DumpFGroup(t_fgroup *fgroup) } } -void DumpFGrid(t_fgrid *fgrid) +void DumpFGrid(t_fgrid* fgrid) { int i; diff --git a/src/programs/view/fgrid.h b/src/programs/view/fgrid.h index 5f619c235a..1cae55298f 100644 --- a/src/programs/view/fgrid.h +++ b/src/programs/view/fgrid.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,47 +42,60 @@ #include "xdlgitem.h" -typedef struct { +typedef struct +{ edlgitem edlg; bool bDef; int nname; - char **name; - char *set, *get, *def, *help; + char** name; + char * set, *get, *def, *help; } t_fitem; -typedef struct { - char *name; +typedef struct +{ + char* name; int x, y, w, h; int nfitem; - t_fitem **fitem; + t_fitem** fitem; } t_fgroup; -typedef struct { +typedef struct +{ int x, y, w, h; - t_fitem *fitem; + t_fitem* fitem; } t_fsimple; -typedef struct { +typedef struct +{ int w, h; int nfgroup; - t_fgroup **fgroup; + t_fgroup** fgroup; int nfsimple; - t_fsimple **fsimple; + t_fsimple** fsimple; } t_fgrid; -typedef enum { - eGRIDEXP, eACCOEXP, eACCCEXP, eGRPEXP, eITEMEXP, eSAMEPOINT, - eTOOWIDE, eTOOHIGH, eQUOTE, eNOVALS +typedef enum +{ + eGRIDEXP, + eACCOEXP, + eACCCEXP, + eGRPEXP, + eITEMEXP, + eSAMEPOINT, + eTOOWIDE, + eTOOHIGH, + eQUOTE, + eNOVALS } eDLGERR; -void ReadDlgErr(const char *infile, eDLGERR err, const char *s); +void ReadDlgErr(const char* infile, eDLGERR err, const char* s); -t_fgrid *FGridFromFile(const char *infile); +t_fgrid* FGridFromFile(const char* infile); -void DoneFGrid(t_fgrid *fgrid); +void DoneFGrid(t_fgrid* fgrid); -void DumpFGrid(t_fgrid *fgrid); +void DumpFGrid(t_fgrid* fgrid); -void ReadQuoteString(const char *infile, FILE *in, char *buf); +void ReadQuoteString(const char* infile, FILE* in, char* buf); -#endif /* _fgrid_h */ +#endif /* _fgrid_h */ diff --git a/src/programs/view/filter.cpp b/src/programs/view/filter.cpp index 3bcfd9bcd0..3064c79de7 100644 --- a/src/programs/view/filter.cpp +++ b/src/programs/view/filter.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,9 +51,9 @@ #include "dialogs.h" #include "xdlghi.h" -t_filter *init_filter(t_atoms *atoms, const char *fn, int natom_trx) +t_filter* init_filter(t_atoms* atoms, const char* fn, int natom_trx) { - t_filter *f; + t_filter* f; int g, i; snew(f, 1); @@ -70,7 +70,7 @@ t_filter *init_filter(t_atoms *atoms, const char *fn, int natom_trx) snew(f->bDisable, f->grps->nr); for (g = 0; g < f->grps->nr; g++) { - for (i = f->grps->index[g]; i < f->grps->index[g+1] && !f->bDisable[g]; i++) + for (i = f->grps->index[g]; i < f->grps->index[g + 1] && !f->bDisable[g]; i++) { f->bDisable[g] = (f->grps->a[i] >= natom_trx); } @@ -81,15 +81,14 @@ t_filter *init_filter(t_atoms *atoms, const char *fn, int natom_trx) return f; } -static void FilterCB(t_x11 *x11, int dlg_mess, int /*item_id*/, - char *set, void *data) +static void FilterCB(t_x11* x11, int dlg_mess, int /*item_id*/, char* set, void* data) { int nset; - t_filter *f; - t_gmx *gmx; - t_dlg *dlg; + t_filter* f; + t_gmx* gmx; + t_dlg* dlg; - gmx = (t_gmx *)data; + gmx = (t_gmx*)data; dlg = gmx->dlgs[edFilter]; f = gmx->filter; @@ -114,13 +113,13 @@ static void FilterCB(t_x11 *x11, int dlg_mess, int /*item_id*/, } } -t_dlg *select_filter(t_x11 *x11, t_gmx *gmx) +t_dlg* select_filter(t_x11* x11, t_gmx* gmx) { - static const char *title = "Group"; - static const char *dummy = "\"FALSE\""; - static const char *ok = "\"Ok\""; - FILE *tmp; - t_dlg *dlg; + static const char* title = "Group"; + static const char* dummy = "\"FALSE\""; + static const char* ok = "\"Ok\""; + FILE* tmp; + t_dlg* dlg; char tmpfile[STRLEN]; int i, j, k, len, tlen, ht, ncol, nrow, x0; @@ -131,37 +130,37 @@ t_dlg *select_filter(t_x11 *x11, t_gmx *gmx) } len += 2; - ncol = 1+(gmx->filter->grps->nr / 15); - nrow = gmx->filter->grps->nr/ncol; - if (nrow*ncol < gmx->filter->grps->nr) + ncol = 1 + (gmx->filter->grps->nr / 15); + nrow = gmx->filter->grps->nr / ncol; + if (nrow * ncol < gmx->filter->grps->nr) { nrow++; } if (ncol > 1) { - ht = 1+(nrow+1)*2+3; + ht = 1 + (nrow + 1) * 2 + 3; } else { - ht = 1+(gmx->filter->grps->nr+1)*2+3; + ht = 1 + (gmx->filter->grps->nr + 1) * 2 + 3; } std::strcpy(tmpfile, "filterXXXXXX"); tmp = gmx_fopen_temporary(tmpfile); #ifdef DEBUG std::fprintf(stderr, "file: %s\n", tmpfile); #endif - tlen = 1+ncol*(1+len); + tlen = 1 + ncol * (1 + len); std::fprintf(tmp, "grid %d %d {\n\n", tlen, ht); - for (k = j = 0, x0 = 1; (j < ncol); j++, x0 += len+1) + for (k = j = 0, x0 = 1; (j < ncol); j++, x0 += len + 1) { - std::fprintf(tmp, "group \"%s-%d\" %d 1 %d %d {\n", title, j+1, x0, len, ht-5); + std::fprintf(tmp, "group \"%s-%d\" %d 1 %d %d {\n", title, j + 1, x0, len, ht - 5); for (i = 0; (i < nrow) && (k < gmx->filter->grps->nr); i++, k++) { if (!gmx->filter->bDisable[k]) { - std::fprintf(tmp, "checkbox \"%s\" \"%d\" %s %s %s\n", - gmx->filter->grpnames[k], k, dummy, dummy, dummy); + std::fprintf(tmp, "checkbox \"%s\" \"%d\" %s %s %s\n", gmx->filter->grpnames[k], k, + dummy, dummy, dummy); } else { @@ -171,13 +170,12 @@ t_dlg *select_filter(t_x11 *x11, t_gmx *gmx) } std::fprintf(tmp, "}\n\n"); } - std::fprintf(tmp, "simple 1 %d %d 2 {\n", ht-3, tlen-2); + std::fprintf(tmp, "simple 1 %d %d 2 {\n", ht - 3, tlen - 2); std::fprintf(tmp, "defbutton %s %s %s %s %s\n", ok, ok, dummy, dummy, dummy); std::fprintf(tmp, "}\n\n}\n"); gmx_ffclose(tmp); - dlg = ReadDlg(x11, gmx->wd->self, title, tmpfile, - 0, 0, true, false, FilterCB, gmx); + dlg = ReadDlg(x11, gmx->wd->self, title, tmpfile, 0, 0, true, false, FilterCB, gmx); std::remove(tmpfile); diff --git a/src/programs/view/logo.cpp b/src/programs/view/logo.cpp index c385d1ec09..e8fb69d6f6 100644 --- a/src/programs/view/logo.cpp +++ b/src/programs/view/logo.cpp @@ -49,29 +49,31 @@ #include "Xstuff.h" #include "xutil.h" -typedef struct { +typedef struct +{ int x, y, rad; - unsigned long *col; + unsigned long* col; } t_circle; -typedef struct { - const char *text; +typedef struct +{ + const char* text; int y, h; - XFontStruct *fnt; + XFontStruct* fnt; } t_mess; -void show_logo(t_x11 *x11, t_logo *logo) +void show_logo(t_x11* x11, t_logo* logo) { XMapWindow(x11->disp, logo->wd.self); XMapSubwindows(x11->disp, logo->wd.self); } -void hide_logo(t_x11 *x11, t_logo *logo) +void hide_logo(t_x11* x11, t_logo* logo) { XUnmapWindow(x11->disp, logo->wd.self); } -static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool LogoCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { /* Assume window is 100x110 */ static bool bFirst = true; @@ -81,48 +83,36 @@ static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) #define HSIZE 7 #define YOFFS 30 static t_circle c[] = { - { 10, YOFFS+12, CSIZE, &LIGHTGREEN }, - { 20, YOFFS+22, CSIZE, &LIGHTGREEN }, - { 20, YOFFS+34, OSIZE, &LIGHTRED }, - { 30, YOFFS+12, NSIZE, &LIGHTCYAN }, - { 30, YOFFS+ 2, HSIZE, &WHITE }, - { 40, YOFFS+22, CSIZE, &LIGHTGREEN }, - { 40, YOFFS+34, CSIZE, &LIGHTGREEN }, - { 50, YOFFS+12, CSIZE, &LIGHTGREEN }, - { 50, YOFFS, OSIZE, &LIGHTRED }, - { 60, YOFFS+22, NSIZE, &LIGHTCYAN }, - { 60, YOFFS+32, HSIZE, &WHITE }, - { 70, YOFFS+12, CSIZE, &LIGHTGREEN }, - { 80, YOFFS+22, CSIZE, &LIGHTGREEN }, - { 80, YOFFS+34, OSIZE, &LIGHTRED }, - { 90, YOFFS+12, NSIZE, &LIGHTCYAN }, - { 90, YOFFS+ 2, HSIZE, &WHITE }, - {100, YOFFS+22, CSIZE, &LIGHTGREEN } - }; - static int lines[] = { - 0, 1, 1, 2, 1, 3, 3, 4, 3, 5, 5, 6, 5, 7, 7, 8, 7, 9, - 9, 10, 9, 11, 11, 12, 12, 13, 12, 14, 14, 15, 14, 16 + { 10, YOFFS + 12, CSIZE, &LIGHTGREEN }, { 20, YOFFS + 22, CSIZE, &LIGHTGREEN }, + { 20, YOFFS + 34, OSIZE, &LIGHTRED }, { 30, YOFFS + 12, NSIZE, &LIGHTCYAN }, + { 30, YOFFS + 2, HSIZE, &WHITE }, { 40, YOFFS + 22, CSIZE, &LIGHTGREEN }, + { 40, YOFFS + 34, CSIZE, &LIGHTGREEN }, { 50, YOFFS + 12, CSIZE, &LIGHTGREEN }, + { 50, YOFFS, OSIZE, &LIGHTRED }, { 60, YOFFS + 22, NSIZE, &LIGHTCYAN }, + { 60, YOFFS + 32, HSIZE, &WHITE }, { 70, YOFFS + 12, CSIZE, &LIGHTGREEN }, + { 80, YOFFS + 22, CSIZE, &LIGHTGREEN }, { 80, YOFFS + 34, OSIZE, &LIGHTRED }, + { 90, YOFFS + 12, NSIZE, &LIGHTCYAN }, { 90, YOFFS + 2, HSIZE, &WHITE }, + { 100, YOFFS + 22, CSIZE, &LIGHTGREEN } }; + static int lines[] = { 0, 1, 1, 2, 1, 3, 3, 4, 3, 5, 5, 6, 5, 7, 7, 8, + 7, 9, 9, 10, 9, 11, 11, 12, 12, 13, 12, 14, 14, 15, 14, 16 }; #define COFFS 70 - static t_mess Mess[] = { - { "GROMACS", 0, 20, nullptr }, - { nullptr, 16, 9, nullptr }, - { "Copyright (c) 1991-2013", COFFS+ 2, 9, nullptr }, - { "D.v.d.Spoel, E.Lindahl, B.Hess", COFFS+11, 9, nullptr }, - { "& Groningen University ", COFFS+20, 9, nullptr }, - { "click to dismiss", COFFS+31, 8, nullptr } - }; + static t_mess Mess[] = { { "GROMACS", 0, 20, nullptr }, + { nullptr, 16, 9, nullptr }, + { "Copyright (c) 1991-2013", COFFS + 2, 9, nullptr }, + { "D.v.d.Spoel, E.Lindahl, B.Hess", COFFS + 11, 9, nullptr }, + { "& Groningen University ", COFFS + 20, 9, nullptr }, + { "click to dismiss", COFFS + 31, 8, nullptr } }; #define NMESS asize(Mess) - int i; - t_logo *logo; - t_windata *wd; + int i; + t_logo* logo; + t_windata* wd; - logo = (t_logo *)data; + logo = (t_logo*)data; wd = &(logo->wd); if (bFirst) { - const real wfac = wd->width/110.0; - const real hfac = wd->height/110.0; + const real wfac = wd->width / 110.0; + const real hfac = wd->height / 110.0; for (i = 0; (i < asize(c)); i++) { c[i].x *= wfac; @@ -131,10 +121,9 @@ static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) Mess[1].text = gmx_version(); for (i = 0; (i < NMESS); i++) { - Mess[i].y *= hfac; - Mess[i].h *= hfac; - Mess[i].fnt = (i == 0) ? logo->bigfont : (i == NMESS-1) ? x11->font : - logo->smallfont; + Mess[i].y *= hfac; + Mess[i].h *= hfac; + Mess[i].fnt = (i == 0) ? logo->bigfont : (i == NMESS - 1) ? x11->font : logo->smallfont; } bFirst = false; } @@ -145,8 +134,8 @@ static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) XSetLineAttributes(x11->disp, x11->gc, 3, LineSolid, CapNotLast, JoinRound); for (i = 0; (i < asize(lines)); i += 2) { - XDrawLine(x11->disp, wd->self, x11->gc, - c[lines[i]].x, c[lines[i]].y, c[lines[i+1]].x, c[lines[i+1]].y); + XDrawLine(x11->disp, wd->self, x11->gc, c[lines[i]].x, c[lines[i]].y, + c[lines[i + 1]].x, c[lines[i + 1]].y); } XSetLineAttributes(x11->disp, x11->gc, 1, LineSolid, CapNotLast, JoinRound); for (i = 0; (i < asize(c)); i++) @@ -155,12 +144,11 @@ static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) XFillCircle(x11->disp, wd->self, x11->gc, c[i].x, c[i].y, c[i].rad); } XSetForeground(x11->disp, x11->gc, BLACK); - XDrawRectangle(x11->disp, wd->self, x11->gc, 2, 2, wd->width-5, wd->height-5); + XDrawRectangle(x11->disp, wd->self, x11->gc, 2, 2, wd->width - 5, wd->height - 5); for (i = 0; (i < NMESS); i++) { - SpecialTextInRect(x11, Mess[i].fnt, wd->self, Mess[i].text, - 0, Mess[i].y, wd->width, Mess[i].h, - eXCenter, eYCenter); + SpecialTextInRect(x11, Mess[i].fnt, wd->self, Mess[i].text, 0, Mess[i].y, wd->width, + Mess[i].h, eXCenter, eYCenter); } XSetForeground(x11->disp, x11->gc, x11->fg); break; @@ -168,34 +156,27 @@ static bool LogoCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) hide_logo(x11, logo); return logo->bQuitOnClick; break; - default: - break; + default: break; } return false; } -t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick) +t_logo* init_logo(t_x11* x11, Window parent, bool bQuitOnClick) { - static const char *bfname[] = { - "-b&h-lucida-bold-i-normal-sans-34-240-100-100-p-215-iso8859-1", - "-b&h-lucida-bold-i-normal-sans-26-190-100-100-p-166-iso8859-1", - "lucidasans-bolditalic-24", - "lucidasans-italic-24", - "10x20", - "fixed" - }; + static const char* bfname[] = { "-b&h-lucida-bold-i-normal-sans-34-240-100-100-p-215-iso8859-1", + "-b&h-lucida-bold-i-normal-sans-26-190-100-100-p-166-iso8859-1", + "lucidasans-bolditalic-24", + "lucidasans-italic-24", + "10x20", + "fixed" }; #define NBF asize(bfname) - static const char *sfname[] = { - "lucidasans-bold-18", - "10x20", - "fixed" - }; + static const char* sfname[] = { "lucidasans-bold-18", "10x20", "fixed" }; #define NSF asize(sfname) - int i; - unsigned long bg; - char *newcol; - t_logo *logo; + int i; + unsigned long bg; + char* newcol; + t_logo* logo; snew(logo, 1); logo->bQuitOnClick = bQuitOnClick; @@ -205,10 +186,8 @@ t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick) { GetNamedColor(x11, newcol, &bg); } - logo->wd.self = XCreateSimpleWindow(x11->disp, parent, - logo->wd.x, logo->wd.y, - logo->wd.width, logo->wd.height, - logo->wd.bwidth, WHITE, bg); + logo->wd.self = XCreateSimpleWindow(x11->disp, parent, logo->wd.x, logo->wd.y, logo->wd.width, + logo->wd.height, logo->wd.bwidth, WHITE, bg); for (i = 0, logo->bigfont = nullptr; (i < NBF); i++) { if ((logo->bigfont = XLoadQueryFont(x11->disp, bfname[i])) != nullptr) @@ -218,7 +197,7 @@ t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick) } if (i == NBF) { - std::perror(bfname[i-1]); + std::perror(bfname[i - 1]); std::exit(1); } #ifdef DEBUG @@ -233,7 +212,7 @@ t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick) } if (i == NSF) { - std::perror(sfname[i-1]); + std::perror(sfname[i - 1]); std::exit(1); } #ifdef DEBUG @@ -245,7 +224,7 @@ t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick) return logo; } -void done_logo(t_x11 *x11, t_logo *logo) +void done_logo(t_x11* x11, t_logo* logo) { x11->UnRegisterCallback(x11, logo->wd.self); } diff --git a/src/programs/view/logo.h b/src/programs/view/logo.h index 92e3915267..9437636fbd 100644 --- a/src/programs/view/logo.h +++ b/src/programs/view/logo.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,19 +41,20 @@ #include "x11.h" #include "xutil.h" -typedef struct { - XFontStruct *bigfont; - XFontStruct *smallfont; +typedef struct +{ + XFontStruct* bigfont; + XFontStruct* smallfont; t_windata wd; bool bQuitOnClick; } t_logo; -extern void show_logo(t_x11 *x11, t_logo *logo); +extern void show_logo(t_x11* x11, t_logo* logo); -extern void hide_logo(t_x11 *x11, t_logo *logo); +extern void hide_logo(t_x11* x11, t_logo* logo); -extern t_logo *init_logo(t_x11 *x11, Window parent, bool bQuitOnClick); +extern t_logo* init_logo(t_x11* x11, Window parent, bool bQuitOnClick); -extern void done_logo(t_x11 *x11, t_logo *logo); +extern void done_logo(t_x11* x11, t_logo* logo); -#endif /* _logo_h */ +#endif /* _logo_h */ diff --git a/src/programs/view/manager.cpp b/src/programs/view/manager.cpp index 1b970684e9..6d77a4ea27 100644 --- a/src/programs/view/manager.cpp +++ b/src/programs/view/manager.cpp @@ -48,7 +48,7 @@ #include #ifdef HAVE_UNISTD_H -#include // for usleep() +# include // for usleep() #endif #include "gromacs/fileio/tpxio.h" @@ -68,30 +68,29 @@ #include "3dview.h" #include "nmol.h" -static void add_object(t_manager *man, eObject eO, int ai, int aj) +static void add_object(t_manager* man, eObject eO, int ai, int aj) { srenew(man->obj, ++man->nobj); - man->obj[man->nobj-1].eO = eO; - man->obj[man->nobj-1].eV = eVNormal; - man->obj[man->nobj-1].color = WHITE; - man->obj[man->nobj-1].ai = ai; - man->obj[man->nobj-1].aj = aj; - man->obj[man->nobj-1].z = 0.0; + man->obj[man->nobj - 1].eO = eO; + man->obj[man->nobj - 1].eV = eVNormal; + man->obj[man->nobj - 1].color = WHITE; + man->obj[man->nobj - 1].ai = ai; + man->obj[man->nobj - 1].aj = aj; + man->obj[man->nobj - 1].z = 0.0; } -static void add_bonds(t_manager *man, const t_functype func[], - t_ilist *b, bool bB[]) +static void add_bonds(t_manager* man, const t_functype func[], t_ilist* b, bool bB[]) { - bool *bH = man->bHydro; - t_iatom *ia; - t_iatom type, ai, aj, ak; - int i, delta, ftype; + bool* bH = man->bHydro; + t_iatom* ia; + t_iatom type, ai, aj, ak; + int i, delta, ftype; #ifdef DEBUG std::fprintf(stderr, "Going to make bonds from an ilist with %d entries\n", b->nr); #endif ia = b->iatoms; - for (i = 0; (i < b->nr); ) + for (i = 0; (i < b->nr);) { type = ia[0]; ai = ia[1]; @@ -125,12 +124,12 @@ static void add_bonds(t_manager *man, const t_functype func[], #ifdef DEBUG std::fprintf(stderr, "Type: %5d, delta: %5d\n", type, delta); #endif - ia += delta+1; - i += delta+1; + ia += delta + 1; + i += delta + 1; } } -static void add_bpl(t_manager *man, t_idef *idef, bool bB[]) +static void add_bpl(t_manager* man, t_idef* idef, bool bB[]) { int ftype; @@ -143,15 +142,15 @@ static void add_bpl(t_manager *man, t_idef *idef, bool bB[]) } } -static int which_atom(t_manager *man, int x, int y) +static int which_atom(t_manager* man, int x, int y) { #define DELTA 5 int i; - iv2 *ix = man->ix; + iv2* ix = man->ix; for (i = 0; (i < man->natom); i++) { - if ((std::abs(ix[i][XX]-x) < DELTA) && (std::abs(ix[i][YY]-y) < DELTA)) + if ((std::abs(ix[i][XX] - x) < DELTA) && (std::abs(ix[i][YY] - y) < DELTA)) { if (man->bVis[i]) { @@ -162,10 +161,10 @@ static int which_atom(t_manager *man, int x, int y) return -1; } -static void do_label(t_x11 *x11, t_manager *man, int x, int y, bool bSet) +static void do_label(t_x11* x11, t_manager* man, int x, int y, bool bSet) { - int ai; - unsigned long col; + int ai; + unsigned long col; if ((ai = which_atom(man, x, y)) != -1) { @@ -186,30 +185,29 @@ static void do_label(t_x11 *x11, t_manager *man, int x, int y, bool bSet) return; } XSetForeground(x11->disp, x11->gc, col); - XDrawString(x11->disp, man->molw->wd.self, x11->gc, x+2, y-2, man->szLab[ai], + XDrawString(x11->disp, man->molw->wd.self, x11->gc, x + 2, y - 2, man->szLab[ai], std::strlen(man->szLab[ai])); XSetForeground(x11->disp, x11->gc, x11->fg); } } -static void show_label(t_x11 *x11, t_manager *man, int x, int y) +static void show_label(t_x11* x11, t_manager* man, int x, int y) { do_label(x11, man, x, y, true); } -static void hide_label(t_x11 *x11, t_manager *man, int x, int y) +static void hide_label(t_x11* x11, t_manager* man, int x, int y) { do_label(x11, man, x, y, false); } -void set_file(t_x11 *x11, t_manager *man, const char *trajectory, - const char *status) +void set_file(t_x11* x11, t_manager* man, const char* trajectory, const char* status) { - t_atoms *at; - bool *bB; - int i; + t_atoms* at; + bool* bB; + int i; - TpxFileHeader sh = readTpxHeader(status, true); + TpxFileHeader sh = readTpxHeader(status, true); snew(man->ix, sh.natoms); snew(man->zz, sh.natoms); snew(man->col, sh.natoms); @@ -230,25 +228,25 @@ void set_file(t_x11 *x11, t_manager *man, const char *trajectory, read_tpx_top(status, nullptr, man->box, &man->natom, nullptr, nullptr, &man->top); man->gpbc = gmx_rmpbc_init(&man->top.idef, -1, man->natom); - man->natom = - read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x), - man->box); + man->natom = read_first_x(man->oenv, &man->status, trajectory, &(man->time), &(man->x), man->box); man->trajfile = gmx_strdup(trajectory); if (man->natom > man->top.atoms.nr) { - gmx_fatal(FARGS, "Topology %s (%d atoms) and trajectory %s (%d atoms) " - "do not match", status, man->top.atoms.nr, - trajectory, man->natom); + gmx_fatal(FARGS, + "Topology %s (%d atoms) and trajectory %s (%d atoms) " + "do not match", + status, man->top.atoms.nr, trajectory, man->natom); } - man->title.text = gmx_strdup(gmx::formatString("%s: %s", *man->top.name, gmx::getCoolQuote().c_str()).c_str()); - man->view = init_view(man->box); - at = &(man->top.atoms); + man->title.text = + gmx_strdup(gmx::formatString("%s: %s", *man->top.name, gmx::getCoolQuote().c_str()).c_str()); + man->view = init_view(man->box); + at = &(man->top.atoms); AtomProperties aps; for (i = 0; (i < man->natom); i++) { - char *aname = *(at->atomname[i]); - t_resinfo *ri = &at->resinfo[at->atom[i].resind]; + char* aname = *(at->atomname[i]); + t_resinfo* ri = &at->resinfo[at->atom[i].resind]; man->col[i] = Type2Color(aname); snew(man->szLab[i], 20); @@ -283,7 +281,7 @@ void set_file(t_x11 *x11, t_manager *man, const char *trajectory, ExposeWin(x11->disp, man->molw->wd.self); } -void step_message(t_x11 *x11, t_manager *man) +void step_message(t_x11* x11, t_manager* man) { XEvent letter; @@ -297,7 +295,7 @@ void step_message(t_x11 *x11, t_manager *man) XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter); } -static void reset_mols(t_block *mols, matrix box, rvec x[]) +static void reset_mols(t_block* mols, matrix box, rvec x[]) { int i, m0, m1, j, m; rvec xcm, icm; @@ -306,7 +304,7 @@ static void reset_mols(t_block *mols, matrix box, rvec x[]) for (i = 0; (i < mols->nr); i++) { m0 = mols->index[i]; - m1 = mols->index[i+1]; + m1 = mols->index[i + 1]; clear_rvec(xcm); clear_rvec(icm); @@ -317,7 +315,7 @@ static void reset_mols(t_block *mols, matrix box, rvec x[]) } for (m = 0; (m < DIM); m++) { - xcm[m] /= (m1-m0); + xcm[m] /= (m1 - m0); } for (m = 0; (m < DIM); m++) { @@ -344,10 +342,10 @@ static void reset_mols(t_block *mols, matrix box, rvec x[]) } } -static bool step_man(t_manager *man, int *nat) +static bool step_man(t_manager* man, int* nat) { - static int ncount = 0; - bool bEof; + static int ncount = 0; + bool bEof; if (!man->natom) { @@ -358,20 +356,18 @@ static bool step_man(t_manager *man, int *nat) *nat = man->natom; if (ncount == man->nSkip) { - auto atomsArrayRef = gmx::arrayRefFromArray(reinterpret_cast(man->x), man->natom); + auto atomsArrayRef = gmx::arrayRefFromArray(reinterpret_cast(man->x), man->natom); switch (man->molw->boxtype) { case esbTri: put_atoms_in_triclinic_unitcell(ecenterDEF, man->box, atomsArrayRef); break; case esbTrunc: - put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box, - atomsArrayRef); + put_atoms_in_compact_unitcell(man->molw->ePBC, ecenterDEF, man->box, atomsArrayRef); break; case esbRect: case esbNone: - default: - break; + default: break; } if (man->bPbc) { @@ -392,7 +388,7 @@ static bool step_man(t_manager *man, int *nat) return bEof; } -static void HandleClient(t_x11 *x11, t_manager *man, const long data[]) +static void HandleClient(t_x11* x11, t_manager* man, const long data[]) { int ID, button, x, y; bool bPos; @@ -408,7 +404,7 @@ static void HandleClient(t_x11 *x11, t_manager *man, const long data[]) case IDROTX: case IDROTY: case IDROTZ: - rotate_3d(man->view, ID-IDROTX, bPos); + rotate_3d(man->view, ID - IDROTX, bPos); draw_mol(x11, man); break; case IDZOOM: @@ -431,22 +427,21 @@ static void HandleClient(t_x11 *x11, t_manager *man, const long data[]) case IDTRANSX: case IDTRANSY: case IDTRANSZ: - translate_view(man->view, ID-IDTRANSX, bPos); + translate_view(man->view, ID - IDTRANSX, bPos); draw_mol(x11, man); break; case IDREWIND: if (man->status) { rewind_trj(man->status); - read_next_x(man->oenv, man->status, &(man->time), man->x, - man->box); + read_next_x(man->oenv, man->status, &(man->time), man->x, man->box); man->bEof = false; draw_mol(x11, man); } break; case IDSTEP: { - int nat; + int nat; nat = 0; if (!step_man(man, &nat)) @@ -459,34 +454,23 @@ static void HandleClient(t_x11 *x11, t_manager *man, const long data[]) if (nat > 0) { draw_mol(x11, man); - usleep(man->nWait*1000); + usleep(man->nWait * 1000); } } break; } - case IDFF: - man->bStop = false; - break; - case IDSTOP_ANI: - man->bStop = true; - break; - case IDDRAWMOL: - draw_mol(x11, man); - break; + case IDFF: man->bStop = false; break; + case IDSTOP_ANI: man->bStop = true; break; + case IDDRAWMOL: draw_mol(x11, man); break; case IDLABEL: switch (button) { case Button1: - case Button2: - show_label(x11, man, x, y); - break; - case Button3: - hide_label(x11, man, x, y); - break; + case Button2: show_label(x11, man, x, y); break; + case Button3: hide_label(x11, man, x, y); break; } break; - default: - break; + default: break; } if (man->bAnimate && !man->bEof && !man->bStop) { @@ -494,11 +478,11 @@ static void HandleClient(t_x11 *x11, t_manager *man, const long data[]) } } -static bool TitleCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool TitleCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_windata *wd; + t_windata* wd; - wd = static_cast(data); + wd = static_cast(data); switch (event->type) { case Expose: @@ -506,8 +490,7 @@ static bool TitleCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) { XSetForeground(x11->disp, x11->gc, WHITE); TextInWin(x11, wd, wd->text, eXCenter, eYCenter); - XDrawLine(x11->disp, wd->self, x11->gc, 0, wd->height, - wd->width, wd->height); + XDrawLine(x11->disp, wd->self, x11->gc, 0, wd->height, wd->width, wd->height); } break; case ConfigureNotify: @@ -518,12 +501,12 @@ static bool TitleCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) return false; } -static bool ManCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool ManCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_manager *man; + t_manager* man; int width, height; - man = static_cast(data); + man = static_cast(data); switch (event->type) { case ConfigureNotify: @@ -534,16 +517,13 @@ static bool ManCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) move_man(x11, man, width, height); } break; - case ClientMessage: - HandleClient(x11, man, event->xclient.data.l); - break; - default: - break; + case ClientMessage: HandleClient(x11, man, event->xclient.data.l); break; + default: break; } return false; } -void no_labels(t_x11 *x11, t_manager *man) +void no_labels(t_x11* x11, t_manager* man) { int i; @@ -554,7 +534,7 @@ void no_labels(t_x11 *x11, t_manager *man) draw_mol(x11, man); } -void move_man(t_x11 *x11, t_manager *man, int width, int height) +void move_man(t_x11* x11, t_manager* man, int width, int height) { int x0, y0, mw, mh, hb; int th; @@ -566,21 +546,21 @@ void move_man(t_x11 *x11, t_manager *man, int width, int height) man->wd.height = height; /* Move all subwindows, resize only Mol window */ - x0 = width-EWIDTH-AIR-4*BORDER; /* Starting of ewin etc. */ + x0 = width - EWIDTH - AIR - 4 * BORDER; /* Starting of ewin etc. */ y0 = AIR; /* Mol Window */ - mw = x0-2*AIR-4*BORDER; - mh = height-y0-AIR-2*BORDER; + mw = x0 - 2 * AIR - 4 * BORDER; + mh = height - y0 - AIR - 2 * BORDER; XMoveResizeWindow(x11->disp, man->molw->wd.self, AIR, y0, mw, mh); /* Title Window */ th = XTextHeight(x11->font); - XMoveResizeWindow(x11->disp, man->title.self, 0, 0, mw, th+AIR); + XMoveResizeWindow(x11->disp, man->title.self, 0, 0, mw, th + AIR); /* Legend Window */ XMoveResizeWindow(x11->disp, man->legw->wd.self, x0, y0, EWIDTH, LEGHEIGHT); - y0 += LEGHEIGHT+AIR+2*BORDER; + y0 += LEGHEIGHT + AIR + 2 * BORDER; if (y0 > height) { @@ -588,16 +568,16 @@ void move_man(t_x11 *x11, t_manager *man, int width, int height) } /* Button Box */ - hb = height-y0-AIR-2*BORDER; + hb = height - y0 - AIR - 2 * BORDER; XMoveResizeWindow(x11->disp, man->bbox->wd.self, x0, y0, EWIDTH, hb); /* Video Box */ - x0 = (mw-man->vbox->wd.width)/2; - y0 = (mh-2-AIR-man->vbox->wd.height); + x0 = (mw - man->vbox->wd.width) / 2; + y0 = (mh - 2 - AIR - man->vbox->wd.height); XMoveWindow(x11->disp, man->vbox->wd.self, x0, y0); } -void map_man(t_x11 *x11, t_manager *man) +void map_man(t_x11* x11, t_manager* man) { XMapWindow(x11->disp, man->wd.self); map_mw(x11, man->molw); @@ -606,7 +586,7 @@ void map_man(t_x11 *x11, t_manager *man) show_but(x11, man->bbox); } -bool toggle_animate (t_x11 *x11, t_manager *man) +bool toggle_animate(t_x11* x11, t_manager* man) { if (man->status) { @@ -625,7 +605,7 @@ bool toggle_animate (t_x11 *x11, t_manager *man) return man->bAnimate; } -bool toggle_pbc (t_manager *man) +bool toggle_pbc(t_manager* man) { man->bPbc = !man->bPbc; @@ -633,13 +613,19 @@ bool toggle_pbc (t_manager *man) } -t_manager *init_man(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg, - int ePBC, matrix box, - gmx_output_env_t *oenv) +t_manager* init_man(t_x11* x11, + Window Parent, + int x, + int y, + int width, + int height, + unsigned long fg, + unsigned long bg, + int ePBC, + matrix box, + gmx_output_env_t* oenv) { - t_manager *man; + t_manager* man; snew(man, 1); man->status = nullptr; @@ -647,12 +633,10 @@ t_manager *init_man(t_x11 *x11, Window Parent, man->bSort = true; man->oenv = oenv; InitWin(&(man->wd), x, y, width, height, 0, "Manager"); - man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y, - man->wd.width, man->wd.height, - man->wd.bwidth, fg, bg); + man->wd.self = XCreateSimpleWindow(x11->disp, Parent, man->wd.x, man->wd.y, man->wd.width, + man->wd.height, man->wd.bwidth, fg, bg); x11->RegisterCallback(x11, man->wd.self, Parent, ManCallBack, man); - x11->SetInputMask(x11, man->wd.self, StructureNotifyMask | - ExposureMask | ButtonPressMask); + x11->SetInputMask(x11, man->wd.self, StructureNotifyMask | ExposureMask | ButtonPressMask); /* The order of creating windows is important for the stacking order */ /* Mol Window */ @@ -660,12 +644,10 @@ t_manager *init_man(t_x11 *x11, Window Parent, /* Title Window */ InitWin(&(man->title), 0, 0, 1, 1, 0, nullptr); - man->title.self = XCreateSimpleWindow(x11->disp, man->molw->wd.self, - man->title.x, man->title.y, - man->title.width, man->title.height, - man->title.bwidth, WHITE, BLUE); - x11->RegisterCallback(x11, man->title.self, man->molw->wd.self, - TitleCallBack, &(man->title)); + man->title.self = + XCreateSimpleWindow(x11->disp, man->molw->wd.self, man->title.x, man->title.y, + man->title.width, man->title.height, man->title.bwidth, WHITE, BLUE); + x11->RegisterCallback(x11, man->title.self, man->molw->wd.self, TitleCallBack, &(man->title)); x11->SetInputMask(x11, man->title.self, ExposureMask | StructureNotifyMask); /* Button box */ @@ -680,7 +662,7 @@ t_manager *init_man(t_x11 *x11, Window Parent, return man; } -void done_man(t_x11 *x11, t_manager *man) +void done_man(t_x11* x11, t_manager* man) { done_bbox(x11, man->vbox); done_bbox(x11, man->bbox); @@ -697,10 +679,10 @@ void done_man(t_x11 *x11, t_manager *man) sfree(man); } -void do_filter(t_x11 *x11, t_manager *man, t_filter *filter) +void do_filter(t_x11* x11, t_manager* man, t_filter* filter) { - int i; - int j; + int i; + int j; for (i = 0; (i < man->natom); i++) { @@ -710,7 +692,7 @@ void do_filter(t_x11 *x11, t_manager *man, t_filter *filter) { if (filter->bShow[i]) { - for (j = filter->grps->index[i]; (j < filter->grps->index[i+1]); j++) + for (j = filter->grps->index[i]; (j < filter->grps->index[i + 1]); j++) { man->bVis[filter->grps->a[j]] = true; } diff --git a/src/programs/view/manager.h b/src/programs/view/manager.h index ed30a55a8b..d0461104d0 100644 --- a/src/programs/view/manager.h +++ b/src/programs/view/manager.h @@ -54,49 +54,70 @@ struct gmx_output_env_t; /* Some window sizes */ -#define EWIDTH 200 -#define EHEIGHT 0 -#define LDHEIGHT 0 -#define LEGHEIGHT 60 - -enum eObject { - eOSingle, eOBond, eOHBond, eONR +#define EWIDTH 200 +#define EHEIGHT 0 +#define LDHEIGHT 0 +#define LEGHEIGHT 60 + +enum eObject +{ + eOSingle, + eOBond, + eOHBond, + eONR }; -enum eVisible { - eVNormal, eVSpecial, eVHidden, evNR +enum eVisible +{ + eVNormal, + eVSpecial, + eVHidden, + evNR }; -enum eBwidth { - eBThin, eBFat, eBVeryFat, eBSpheres, eBNR +enum eBwidth +{ + eBThin, + eBFat, + eBVeryFat, + eBSpheres, + eBNR }; -enum esBox { - esbNone, esbRect, esbTri, esbTrunc, esbNR +enum esBox +{ + esbNone, + esbRect, + esbTri, + esbTrunc, + esbNR }; -typedef struct { - t_windata wd; /* Mol window structure */ - bool bShowHydrogen; /* Show Hydrogens? */ - int bond_type; /* Show one of the above bondtypes */ - int ePBC; /* PBC type */ - int boxtype; /* Rectangular, Tric, TruncOct (display)*/ - int realbox; /* Property of the real box */ +typedef struct +{ + t_windata wd; /* Mol window structure */ + bool bShowHydrogen; /* Show Hydrogens? */ + int bond_type; /* Show one of the above bondtypes */ + int ePBC; /* PBC type */ + int boxtype; /* Rectangular, Tric, TruncOct (display)*/ + int realbox; /* Property of the real box */ } t_molwin; -typedef struct { - eObject eO; /* The type of object */ - eVisible eV; /* Visibility status of the object */ - unsigned long color; /* The color (only when eV==evSpecial) */ - int ai, aj; /* The int for i (and j if bond) */ - real z; /* The Z-coordinate for depht cueing */ +typedef struct +{ + eObject eO; /* The type of object */ + eVisible eV; /* Visibility status of the object */ + unsigned long color; /* The color (only when eV==evSpecial) */ + int ai, aj; /* The int for i (and j if bond) */ + real z; /* The Z-coordinate for depht cueing */ } t_object; -typedef struct { - t_blocka *grps; /* Blocks with atom numbers */ - char **grpnames; /* The names of the groups */ - bool *bDisable; /* Group indexes out of natoms in TRX */ - bool *bShow; /* Show a group ? */ +typedef struct +{ + t_blocka* grps; /* Blocks with atom numbers */ + char** grpnames; /* The names of the groups */ + bool* bDisable; /* Group indexes out of natoms in TRX */ + bool* bShow; /* Show a group ? */ } t_filter; /* @@ -107,79 +128,85 @@ typedef struct { * be updated. * */ -typedef struct { - t_trxstatus *status; - const char *trajfile; - int natom; /* The number of atoms */ - t_topology top; /* topology */ - rvec box_size; - real time; /* The actual time */ - rvec *x; /* The coordinates */ - iv2 *ix; /* The coordinates after projection */ - real *zz; /* Z-coords */ - matrix box; /* The box */ - int nobj; /* The number of objects */ - t_object *obj; /* The objects on screen */ - bool *bHydro; /* true for hydrogen atoms */ - bool *bLabel; /* Show a label on atom i? */ - char **szLab; /* Array of pointers to labels */ - unsigned long *col; /* The colour of the atoms */ - int *size; /* The size of the atoms */ - real *vdw; /* The VDWaals radius of the atoms */ - bool *bVis; /* visibility of atoms */ - bool bPbc; /* Remove Periodic boundary */ - bool bAnimate; /* Animation going on? */ - bool bEof; /* End of file reached? */ - bool bStop; /* Stopped by user? */ - bool bSort; /* Sort the coordinates */ - bool bPlus; /* Draw plus for single atom */ - int nSkip; /* Skip n steps after each frame */ - int nWait; /* Wait n ms after each frame */ - gmx_rmpbc_t gpbc; /* For removing peridiocity */ - - t_windata wd; /* The manager subwindow */ - t_windata title; /* Title window */ - t_3dview *view; /* The 3d struct */ - t_molwin *molw; /* The molecule window */ - t_butbox *vbox; /* The video box */ - t_butbox *bbox; /* The button box */ - t_legendwin *legw; /* The legend window */ - - gmx_output_env_t *oenv; /* output env data */ +typedef struct +{ + t_trxstatus* status; + const char* trajfile; + int natom; /* The number of atoms */ + t_topology top; /* topology */ + rvec box_size; + real time; /* The actual time */ + rvec* x; /* The coordinates */ + iv2* ix; /* The coordinates after projection */ + real* zz; /* Z-coords */ + matrix box; /* The box */ + int nobj; /* The number of objects */ + t_object* obj; /* The objects on screen */ + bool* bHydro; /* true for hydrogen atoms */ + bool* bLabel; /* Show a label on atom i? */ + char** szLab; /* Array of pointers to labels */ + unsigned long* col; /* The colour of the atoms */ + int* size; /* The size of the atoms */ + real* vdw; /* The VDWaals radius of the atoms */ + bool* bVis; /* visibility of atoms */ + bool bPbc; /* Remove Periodic boundary */ + bool bAnimate; /* Animation going on? */ + bool bEof; /* End of file reached? */ + bool bStop; /* Stopped by user? */ + bool bSort; /* Sort the coordinates */ + bool bPlus; /* Draw plus for single atom */ + int nSkip; /* Skip n steps after each frame */ + int nWait; /* Wait n ms after each frame */ + gmx_rmpbc_t gpbc; /* For removing peridiocity */ + + t_windata wd; /* The manager subwindow */ + t_windata title; /* Title window */ + t_3dview* view; /* The 3d struct */ + t_molwin* molw; /* The molecule window */ + t_butbox* vbox; /* The video box */ + t_butbox* bbox; /* The button box */ + t_legendwin* legw; /* The legend window */ + + gmx_output_env_t* oenv; /* output env data */ } t_manager; -extern t_manager *init_man(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg, - int ePBC, matrix box, gmx_output_env_t *oenv); +extern t_manager* init_man(t_x11* x11, + Window Parent, + int x, + int y, + int width, + int height, + unsigned long fg, + unsigned long bg, + int ePBC, + matrix box, + gmx_output_env_t* oenv); /* Initiate the display manager */ -extern void move_man(t_x11 *x11, t_manager *man, int width, int height); +extern void move_man(t_x11* x11, t_manager* man, int width, int height); /* Set the right size for this window */ -extern void step_message(t_x11 *x11, t_manager *man); +extern void step_message(t_x11* x11, t_manager* man); /* Send a message to the manager */ -extern void set_file(t_x11 *x11, t_manager *man, const char *trajectory, - const char *status); +extern void set_file(t_x11* x11, t_manager* man, const char* trajectory, const char* status); /* Read a new trajectory and topology */ -extern void map_man(t_x11 *x11, t_manager *man); - +extern void map_man(t_x11* x11, t_manager* man); -extern bool toggle_animate (t_x11 *x11, t_manager *man); +extern bool toggle_animate(t_x11* x11, t_manager* man); -extern bool toggle_pbc (t_manager *man); +extern bool toggle_pbc(t_manager* man); -extern void no_labels(t_x11 *x11, t_manager *man); +extern void no_labels(t_x11* x11, t_manager* man); /* Turn off all labels */ -extern void done_man(t_x11 *x11, t_manager *man); +extern void done_man(t_x11* x11, t_manager* man); /* Clean up man struct */ -extern void draw_mol(t_x11 *x11, t_manager *man); +extern void draw_mol(t_x11* x11, t_manager* man); -extern void do_filter(t_x11 *x11, t_manager *man, t_filter *filter); +extern void do_filter(t_x11* x11, t_manager* man, t_filter* filter); #endif diff --git a/src/programs/view/molps.cpp b/src/programs/view/molps.cpp index 67860f68b0..3f2dcf5158 100644 --- a/src/programs/view/molps.cpp +++ b/src/programs/view/molps.cpp @@ -52,15 +52,15 @@ #define MSIZE 4 -static void ps_draw_atom(t_psdata *ps, int ai, iv2 vec2[], char **atomnm[]) +static void ps_draw_atom(t_psdata* ps, int ai, iv2 vec2[], char** atomnm[]) { int xi, yi; xi = vec2[ai][XX]; yi = vec2[ai][YY]; ps_rgb(ps, Type2RGB(*atomnm[ai])); - ps_line(ps, xi-MSIZE, yi, xi+MSIZE+1, yi); - ps_line(ps, xi, yi-MSIZE, xi, yi+MSIZE+1); + ps_line(ps, xi - MSIZE, yi, xi + MSIZE + 1, yi); + ps_line(ps, xi, yi - MSIZE, xi, yi + MSIZE + 1); } /* Global variables */ @@ -72,8 +72,8 @@ static void init_pbc(matrix box) for (i = 0; (i < DIM); i++) { - gl_fbox[i] = box[i][i]; - gl_hbox[i] = gl_fbox[i]*0.5; + gl_fbox[i] = box[i][i]; + gl_hbox[i] = gl_fbox[i] * 0.5; gl_mhbox[i] = -gl_hbox[i]; } } @@ -85,7 +85,7 @@ static bool local_pbc_dx(rvec x1, rvec x2) for (i = 0; (i < DIM); i++) { - dx = x1[i]-x2[i]; + dx = x1[i] - x2[i]; if (dx > gl_hbox[i]) { return false; @@ -98,13 +98,11 @@ static bool local_pbc_dx(rvec x1, rvec x2) return true; } -static void ps_draw_bond(t_psdata *ps, - int ai, int aj, iv2 vec2[], - rvec x[], char **atomnm[]) +static void ps_draw_bond(t_psdata* ps, int ai, int aj, iv2 vec2[], rvec x[], char** atomnm[]) { - char *ic, *jc; - int xi, yi, xj, yj; - int xm, ym; + char *ic, *jc; + int xi, yi, xj, yj; + int xm, ym; if (local_pbc_dx(x[ai], x[aj])) { @@ -117,8 +115,8 @@ static void ps_draw_bond(t_psdata *ps, if (ic != jc) { - xm = (xi+xj) >> 1; - ym = (yi+yj) >> 1; + xm = (xi + xj) >> 1; + ym = (yi + yj) >> 1; ps_rgb(ps, Type2RGB(ic)); ps_line(ps, xi, yi, xm, ym); @@ -133,31 +131,25 @@ static void ps_draw_bond(t_psdata *ps, } } -static void ps_draw_objects(t_psdata *ps, int nobj, t_object objs[], iv2 vec2[], - rvec x[], char **atomnm[], bool bShowHydro) +static void ps_draw_objects(t_psdata* ps, int nobj, t_object objs[], iv2 vec2[], rvec x[], char** atomnm[], bool bShowHydro) { - int i; - t_object *obj; + int i; + t_object* obj; for (i = 0; (i < nobj); i++) { obj = &(objs[i]); switch (obj->eO) { - case eOSingle: - ps_draw_atom(ps, obj->ai, vec2, atomnm); - break; - case eOBond: - ps_draw_bond(ps, obj->ai, obj->aj, vec2, x, atomnm); - break; + case eOSingle: ps_draw_atom(ps, obj->ai, vec2, atomnm); break; + case eOBond: ps_draw_bond(ps, obj->ai, obj->aj, vec2, x, atomnm); break; case eOHBond: if (bShowHydro) { ps_draw_bond(ps, obj->ai, obj->aj, vec2, x, atomnm); } break; - default: - break; + default: break; } } } @@ -166,23 +158,17 @@ static void v4_to_iv2(vec4 x4, iv2 v2, int x0, int y0, real sx, real sy) { real inv_z; - inv_z = 1.0/x4[ZZ]; - v2[XX] = x0+sx*x4[XX]*inv_z; - v2[YY] = y0-sy*x4[YY]*inv_z; + inv_z = 1.0 / x4[ZZ]; + v2[XX] = x0 + sx * x4[XX] * inv_z; + v2[YY] = y0 - sy * x4[YY] * inv_z; } -static void draw_box(t_psdata *ps, t_3dview *view, matrix box, - int x0, int y0, real sx, real sy) +static void draw_box(t_psdata* ps, t_3dview* view, matrix box, int x0, int y0, real sx, real sy) { - int ivec[8][4] = { - { 0, 0, 0, 1 }, { 1, 0, 0, 1 }, { 1, 1, 0, 1 }, { 0, 1, 0, 1 }, - { 0, 0, 1, 1 }, { 1, 0, 1, 1 }, { 1, 1, 1, 1 }, { 0, 1, 1, 1 } - }; - int bonds[12][2] = { - { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, - { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, - { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } - }; + int ivec[8][4] = { { 0, 0, 0, 1 }, { 1, 0, 0, 1 }, { 1, 1, 0, 1 }, { 0, 1, 0, 1 }, + { 0, 0, 1, 1 }, { 1, 0, 1, 1 }, { 1, 1, 1, 1 }, { 0, 1, 1, 1 } }; + int bonds[12][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, + { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }; int i, j; rvec corner[8]; vec4 x4; @@ -192,7 +178,7 @@ static void draw_box(t_psdata *ps, t_3dview *view, matrix box, { for (j = 0; (j < DIM); j++) { - corner[i][j] = ivec[i][j]*box[j][j]; + corner[i][j] = ivec[i][j] * box[j][j]; } gmx_mat4_transform_point(view->proj, corner[i], x4); v4_to_iv2(x4, vec2[i], x0, y0, sx, sy); @@ -200,21 +186,20 @@ static void draw_box(t_psdata *ps, t_3dview *view, matrix box, ps_color(ps, 0, 0, 0.5); for (i = 0; (i < 12); i++) { - ps_line(ps, - vec2[bonds[i][0]][XX], vec2[bonds[i][0]][YY], - vec2[bonds[i][1]][XX], vec2[bonds[i][1]][YY]); + ps_line(ps, vec2[bonds[i][0]][XX], vec2[bonds[i][0]][YY], vec2[bonds[i][1]][XX], + vec2[bonds[i][1]][YY]); } } -void ps_draw_mol(t_psdata *ps, t_manager *man) +void ps_draw_mol(t_psdata* ps, t_manager* man) { - t_windata *win; - t_3dview *view; - t_molwin *mw; - int i, x0, y0, nvis; - iv2 *vec2; - real sx, sy; - vec4 x4; + t_windata* win; + t_3dview* view; + t_molwin* mw; + int i, x0, y0, nvis; + iv2* vec2; + real sx, sy; + vec4 x4; if (!man->status) { @@ -227,10 +212,10 @@ void ps_draw_mol(t_psdata *ps, t_manager *man) win = &(mw->wd); vec2 = man->ix; - x0 = win->width/2; - y0 = win->height/2; - sx = win->width/2*view->sc_x; - sy = win->height/2*view->sc_y; + x0 = win->width / 2; + y0 = win->height / 2; + sx = win->width / 2 * view->sc_x; + sy = win->height / 2 * view->sc_y; init_pbc(man->box); @@ -245,7 +230,7 @@ void ps_draw_mol(t_psdata *ps, t_manager *man) } set_sizes(man); - z_fill (man, man->zz); + z_fill(man, man->zz); /* Start drawing XClearWindow(x11->disp,win->self); */ @@ -263,9 +248,7 @@ void ps_draw_mol(t_psdata *ps, t_manager *man) } /* Draw the objects */ - ps_draw_objects(ps, - nvis, man->obj, man->ix, man->x, man->top.atoms.atomname, - mw->bShowHydrogen); + ps_draw_objects(ps, nvis, man->obj, man->ix, man->x, man->top.atoms.atomname, mw->bShowHydrogen); /* Draw the labels */ ps_color(ps, 0, 0, 0); @@ -273,7 +256,7 @@ void ps_draw_mol(t_psdata *ps, t_manager *man) { if (man->bLabel[i] && man->bVis[i]) { - ps_text(ps, vec2[i][XX]+2, vec2[i][YY]-2, man->szLab[i]); + ps_text(ps, vec2[i][XX] + 2, vec2[i][YY] - 2, man->szLab[i]); } } } diff --git a/src/programs/view/molps.h b/src/programs/view/molps.h index 8b3135055f..b8346ae015 100644 --- a/src/programs/view/molps.h +++ b/src/programs/view/molps.h @@ -42,7 +42,7 @@ struct t_psdata; -extern void ps_draw_mol(t_psdata *ps, t_manager *man); +extern void ps_draw_mol(t_psdata* ps, t_manager* man); /* Draw molecules to a postscript file */ -#endif /* _molps_h */ +#endif /* _molps_h */ diff --git a/src/programs/view/nleg.cpp b/src/programs/view/nleg.cpp index 1cf4de0d1e..ec70ac1ed3 100644 --- a/src/programs/view/nleg.cpp +++ b/src/programs/view/nleg.cpp @@ -48,27 +48,23 @@ #include "buttons.h" -typedef struct { - const char *tp; - unsigned long *col; +typedef struct +{ + const char* tp; + unsigned long* col; t_rgb rgb; } t_atomcolor; static t_atomcolor ac[] = { - { "O", &LIGHTRED, { 1, 0, 0 } }, - { "N", &LIGHTCYAN, { 0, 0, 1 } }, - { "NA", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, - { "S", &YELLOW, { 1, 1, 0 } }, - { "C", &LIGHTGREEN, { 0, 1, 0 } }, - { "CL", &VIOLET, { 1, 0, 1 } }, - { "F", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, - { "Z", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, - { "P", &LIGHTBLUE, { 0.4, 0.4, 1.0 } }, - { "H", &WHITE, { 0.8, 0.8, 0.8 } } + { "O", &LIGHTRED, { 1, 0, 0 } }, { "N", &LIGHTCYAN, { 0, 0, 1 } }, + { "NA", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, { "S", &YELLOW, { 1, 1, 0 } }, + { "C", &LIGHTGREEN, { 0, 1, 0 } }, { "CL", &VIOLET, { 1, 0, 1 } }, + { "F", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, { "Z", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, + { "P", &LIGHTBLUE, { 0.4, 0.4, 1.0 } }, { "H", &WHITE, { 0.8, 0.8, 0.8 } } }; #define NAC asize(ac) -static int search_ac(const char *type) +static int search_ac(const char* type) { unsigned int nb, mij, best, besti; @@ -96,7 +92,7 @@ static int search_ac(const char *type) return besti; } -unsigned long Type2Color(const char *type) +unsigned long Type2Color(const char* type) { int i; @@ -105,7 +101,7 @@ unsigned long Type2Color(const char *type) return *(ac[i].col); } -t_rgb *Type2RGB(const char *type) +t_rgb* Type2RGB(const char* type) { int i; @@ -114,58 +110,52 @@ t_rgb *Type2RGB(const char *type) return &(ac[i].rgb); } -static void DrawLegend(t_x11 *x11, t_windata *Win) +static void DrawLegend(t_x11* x11, t_windata* Win) { #define NLAB 6 #define COLS 3 - static const char *lab[NLAB] = { "C", "O", "H", "S", "N", "P" }; + static const char* lab[NLAB] = { "C", "O", "H", "S", "N", "P" }; int i, i0, dh, dw, w, y, x1, x0; unsigned long cind; real h_2; XClearWindow(x11->disp, Win->self); w = Win->width; - h_2 = Win->height/(2.0*NLAB/COLS); - dh = h_2-2; + h_2 = Win->height / (2.0 * NLAB / COLS); + dh = h_2 - 2; dw = dh; for (i = 0; (i < NLAB); i++) { - i0 = i % (NLAB/COLS); - x0 = (i / (NLAB/COLS))*(Win->width/COLS)+AIR; - x1 = x0+2*dw+AIR; + i0 = i % (NLAB / COLS); + x0 = (i / (NLAB / COLS)) * (Win->width / COLS) + AIR; + x1 = x0 + 2 * dw + AIR; cind = Type2Color(lab[i]); XSetForeground(x11->disp, x11->gc, cind); - y = ((2*i0+1)*h_2); - XFillRectangle (x11->disp, Win->self, x11->gc, x0, y-dh, 2*dw, 2*dh); + y = ((2 * i0 + 1) * h_2); + XFillRectangle(x11->disp, Win->self, x11->gc, x0, y - dh, 2 * dw, 2 * dh); XSetForeground(x11->disp, x11->gc, WHITE); - TextInRect(x11, Win->self, lab[i], x1, y-dh, w-x1, 2*dh, - eXLeft, eYCenter); + TextInRect(x11, Win->self, lab[i], x1, y - dh, w - x1, 2 * dh, eXLeft, eYCenter); } XSetForeground(x11->disp, x11->gc, x11->fg); } -static bool LegWCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool LegWCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_legendwin *lw; + t_legendwin* lw; - lw = (t_legendwin *)data; + lw = (t_legendwin*)data; switch (event->type) { - case Expose: - DrawLegend(x11, &lw->wd); - break; - default: - break; + case Expose: DrawLegend(x11, &lw->wd); break; + default: break; } return false; } -t_legendwin *init_legw(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg) +t_legendwin* init_legw(t_x11* x11, Window Parent, int x, int y, int width, int height, unsigned long fg, unsigned long bg) { - t_legendwin *lw; + t_legendwin* lw; snew(lw, 1); InitWin(&lw->wd, x, y, width, height, 1, "Legend Window"); @@ -176,13 +166,13 @@ t_legendwin *init_legw(t_x11 *x11, Window Parent, return lw; } -void map_legw(t_x11 *x11, t_legendwin *lw) +void map_legw(t_x11* x11, t_legendwin* lw) { XMapWindow(x11->disp, lw->wd.self); } -void done_legw(t_x11 *x11, t_legendwin *lw) +void done_legw(t_x11* x11, t_legendwin* lw) { x11->UnRegisterCallback(x11, lw->wd.self); sfree(lw); diff --git a/src/programs/view/nleg.h b/src/programs/view/nleg.h index c95d6bb7f7..fc28a6b9c4 100644 --- a/src/programs/view/nleg.h +++ b/src/programs/view/nleg.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,22 +43,22 @@ struct t_rgb; -typedef struct { +typedef struct +{ t_windata wd; } t_legendwin; -extern unsigned long Type2Color(const char *type); +extern unsigned long Type2Color(const char* type); /* Return the color for a given atomtype */ -extern t_rgb *Type2RGB(const char *type); +extern t_rgb* Type2RGB(const char* type); /* Return the color for a given atomtype */ -extern t_legendwin *init_legw(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg); +extern t_legendwin* +init_legw(t_x11* x11, Window Parent, int x, int y, int width, int height, unsigned long fg, unsigned long bg); -extern void map_legw(t_x11 *x11, t_legendwin *lw); +extern void map_legw(t_x11* x11, t_legendwin* lw); -extern void done_legw(t_x11 *x11, t_legendwin *lw); +extern void done_legw(t_x11* x11, t_legendwin* lw); -#endif /* _nleg_h */ +#endif /* _nleg_h */ diff --git a/src/programs/view/nmol.cpp b/src/programs/view/nmol.cpp index c1123cf54c..21f502e29c 100644 --- a/src/programs/view/nmol.cpp +++ b/src/programs/view/nmol.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,13 +55,13 @@ #define MSIZE 4 -static bool MWCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool MWCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_molwin *mw; + t_molwin* mw; Window To; XEvent letter; - mw = static_cast(data); + mw = static_cast(data); To = mw->wd.Parent; letter.type = ClientMessage; letter.xclient.display = x11->disp; @@ -92,13 +92,12 @@ static bool MWCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) mw->wd.width = event->xconfigure.width; mw->wd.height = event->xconfigure.height; break; - default: - break; + default: break; } return false; } -static void set_def (t_molwin *mw, int ePBC, matrix box) +static void set_def(t_molwin* mw, int ePBC, matrix box) { mw->bShowHydrogen = true; mw->bond_type = eBFat; @@ -107,12 +106,18 @@ static void set_def (t_molwin *mw, int ePBC, matrix box) mw->realbox = TRICLINIC(box) ? esbTri : esbRect; } -t_molwin *init_mw(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg, - int ePBC, matrix box) +t_molwin* init_mw(t_x11* x11, + Window Parent, + int x, + int y, + int width, + int height, + unsigned long fg, + unsigned long bg, + int ePBC, + matrix box) { - t_molwin *mw; + t_molwin* mw; snew(mw, 1); set_def(mw, ePBC, box); @@ -122,18 +127,16 @@ t_molwin *init_mw(t_x11 *x11, Window Parent, mw->wd.Parent = Parent; mw->wd.self = XCreateSimpleWindow(x11->disp, Parent, x, y, width, height, 1, fg, bg); x11->RegisterCallback(x11, mw->wd.self, Parent, MWCallBack, mw); - x11->SetInputMask(x11, mw->wd.self, - ExposureMask | StructureNotifyMask | - ButtonPressMask); + x11->SetInputMask(x11, mw->wd.self, ExposureMask | StructureNotifyMask | ButtonPressMask); return mw; } -void map_mw(t_x11 *x11, t_molwin *mw) +void map_mw(t_x11* x11, t_molwin* mw) { XMapWindow(x11->disp, mw->wd.self); } -bool toggle_hydrogen(t_x11 *x11, t_molwin *mw) +bool toggle_hydrogen(t_x11* x11, t_molwin* mw) { mw->bShowHydrogen = !mw->bShowHydrogen; ExposeWin(x11->disp, mw->wd.self); @@ -141,7 +144,7 @@ bool toggle_hydrogen(t_x11 *x11, t_molwin *mw) return mw->bShowHydrogen; } -void set_bond_type(t_x11 *x11, t_molwin *mw, int bt) +void set_bond_type(t_x11* x11, t_molwin* mw, int bt) { if (bt != mw->bond_type) { @@ -150,7 +153,7 @@ void set_bond_type(t_x11 *x11, t_molwin *mw, int bt) } } -void set_box_type (t_x11 *x11, t_molwin *mw, int bt) +void set_box_type(t_x11* x11, t_molwin* mw, int bt) { #ifdef DEBUG std::fprintf(stderr, "mw->boxtype = %d, bt = %d\n", mw->boxtype, bt); @@ -169,15 +172,14 @@ void set_box_type (t_x11 *x11, t_molwin *mw, int bt) } } -void done_mw(t_x11 *x11, t_molwin *mw) +void done_mw(t_x11* x11, t_molwin* mw) { x11->UnRegisterCallback(x11, mw->wd.self); sfree(mw); } -static void draw_atom(Display *disp, Window w, GC gc, - int ai, iv2 vec2[], unsigned long col[], int size[], - bool bBall, bool bPlus) +static void +draw_atom(Display* disp, Window w, GC gc, int ai, iv2 vec2[], unsigned long col[], int size[], bool bBall, bool bPlus) { int xi, yi; @@ -186,7 +188,7 @@ static void draw_atom(Display *disp, Window w, GC gc, XSetForeground(disp, gc, col[ai]); if (bBall) { - XFillCircle(disp, w, gc, xi, yi, size[ai]-1); + XFillCircle(disp, w, gc, xi, yi, size[ai] - 1); XSetForeground(disp, gc, BLACK); XDrawCircle(disp, w, gc, xi, yi, size[ai]); /* XSetForeground(disp,gc,WHITE); @@ -194,14 +196,13 @@ static void draw_atom(Display *disp, Window w, GC gc, } else if (bPlus) { - XDrawLine(disp, w, gc, xi-MSIZE, yi, xi+MSIZE+1, yi); - XDrawLine(disp, w, gc, xi, yi-MSIZE, xi, yi+MSIZE+1); + XDrawLine(disp, w, gc, xi - MSIZE, yi, xi + MSIZE + 1, yi); + XDrawLine(disp, w, gc, xi, yi - MSIZE, xi, yi + MSIZE + 1); } else { - XDrawLine(disp, w, gc, xi-1, yi, xi+1, yi); + XDrawLine(disp, w, gc, xi - 1, yi, xi + 1, yi); } - } /* Global variables */ @@ -213,8 +214,8 @@ static void my_init_pbc(matrix box) for (i = 0; (i < DIM); i++) { - gl_fbox[i] = box[i][i]; - gl_hbox[i] = gl_fbox[i]*0.5; + gl_fbox[i] = box[i][i]; + gl_hbox[i] = gl_fbox[i] * 0.5; gl_mhbox[i] = -gl_hbox[i]; } } @@ -226,7 +227,7 @@ static bool local_pbc_dx(rvec x1, rvec x2) for (i = 0; (i < DIM); i++) { - dx = x1[i]-x2[i]; + dx = x1[i] - x2[i]; if (dx > gl_hbox[i]) { return false; @@ -239,13 +240,12 @@ static bool local_pbc_dx(rvec x1, rvec x2) return true; } -static void draw_bond(Display *disp, Window w, GC gc, - int ai, int aj, iv2 vec2[], - rvec x[], unsigned long col[], int size[], bool bBalls) +static void +draw_bond(Display* disp, Window w, GC gc, int ai, int aj, iv2 vec2[], rvec x[], unsigned long col[], int size[], bool bBalls) { - unsigned long ic, jc; - int xi, yi, xj, yj; - int xm, ym; + unsigned long ic, jc; + int xi, yi, xj, yj; + int xm, ym; if (bBalls) { @@ -265,8 +265,8 @@ static void draw_bond(Display *disp, Window w, GC gc, if (ic != jc) { - xm = (xi+xj) >> 1; - ym = (yi+yj) >> 1; + xm = (xi + xj) >> 1; + ym = (yi + yj) >> 1; XSetForeground(disp, gc, ic); XDrawLine(disp, w, gc, xi, yi, xm, ym); @@ -282,15 +282,15 @@ static void draw_bond(Display *disp, Window w, GC gc, } } -int compare_obj(const void *a, const void *b) +int compare_obj(const void* a, const void* b) { const t_object *oa, *ob; real z; - oa = static_cast(a); - ob = static_cast(b); + oa = static_cast(a); + ob = static_cast(b); - z = oa->z-ob->z; + z = oa->z - ob->z; if (z < 0) { @@ -306,42 +306,37 @@ int compare_obj(const void *a, const void *b) } } -void z_fill(t_manager *man, real *zz) +void z_fill(t_manager* man, real* zz) { - t_object *obj; + t_object* obj; int i; for (i = 0, obj = man->obj; (i < man->nobj); i++, obj++) { switch (obj->eO) { - case eOSingle: - obj->z = zz[obj->ai]; - break; + case eOSingle: obj->z = zz[obj->ai]; break; case eOBond: - case eOHBond: - obj->z = (zz[obj->ai] + zz[obj->aj]) * 0.5; - break; - default: - break; + case eOHBond: obj->z = (zz[obj->ai] + zz[obj->aj]) * 0.5; break; + default: break; } } } -int filter_vis(t_manager *man) +int filter_vis(t_manager* man) { - int i, nobj, nvis, nhide; - int ai; - bool bAdd, *bVis; - t_object *obj; - t_object *newobj; + int i, nobj, nvis, nhide; + int ai; + bool bAdd, *bVis; + t_object* obj; + t_object* newobj; nobj = man->nobj; snew(newobj, nobj); obj = man->obj; bVis = man->bVis; nvis = 0; - nhide = nobj-1; + nhide = nobj - 1; for (i = 0; (i < nobj); i++, obj++) { ai = obj->ai; @@ -368,43 +363,41 @@ int filter_vis(t_manager *man) return nvis; } -static void draw_objects(Display *disp, Window w, GC gc, int nobj, - t_object objs[], iv2 vec2[], rvec x[], - unsigned long col[], int size[], bool bShowHydro, int bond_type, - bool bPlus) +static void draw_objects(Display* disp, + Window w, + GC gc, + int nobj, + t_object objs[], + iv2 vec2[], + rvec x[], + unsigned long col[], + int size[], + bool bShowHydro, + int bond_type, + bool bPlus) { - bool bBalls; - int i; - t_object *obj; + bool bBalls; + int i; + t_object* obj; bBalls = false; switch (bond_type) { - case eBThin: - XSetLineAttributes(disp, gc, 1, LineSolid, CapNotLast, JoinRound); - break; - case eBFat: - XSetLineAttributes(disp, gc, 3, LineSolid, CapNotLast, JoinRound); - break; - case eBVeryFat: - XSetLineAttributes(disp, gc, 5, LineSolid, CapNotLast, JoinRound); - break; + case eBThin: XSetLineAttributes(disp, gc, 1, LineSolid, CapNotLast, JoinRound); break; + case eBFat: XSetLineAttributes(disp, gc, 3, LineSolid, CapNotLast, JoinRound); break; + case eBVeryFat: XSetLineAttributes(disp, gc, 5, LineSolid, CapNotLast, JoinRound); break; case eBSpheres: bBalls = true; bPlus = false; break; - default: - gmx_fatal(FARGS, "Invalid bond_type selected: %d\n", bond_type); - break; + default: gmx_fatal(FARGS, "Invalid bond_type selected: %d\n", bond_type); break; } for (i = 0; (i < nobj); i++) { obj = &(objs[i]); switch (obj->eO) { - case eOSingle: - draw_atom(disp, w, gc, obj->ai, vec2, col, size, bBalls, bPlus); - break; + case eOSingle: draw_atom(disp, w, gc, obj->ai, vec2, col, size, bBalls, bPlus); break; case eOBond: draw_bond(disp, w, gc, obj->ai, obj->aj, vec2, x, col, size, bBalls); break; @@ -414,8 +407,7 @@ static void draw_objects(Display *disp, Window w, GC gc, int nobj, draw_bond(disp, w, gc, obj->ai, obj->aj, vec2, x, col, size, bBalls); } break; - default: - break; + default: break; } } XSetLineAttributes(disp, gc, 1, LineSolid, CapNotLast, JoinRound); @@ -425,24 +417,18 @@ static void v4_to_iv2(vec4 x4, iv2 v2, int x0, int y0, real sx, real sy) { real inv_z; - inv_z = 1.0/x4[ZZ]; - v2[XX] = x0+sx*x4[XX]*inv_z; - v2[YY] = y0-sy*x4[YY]*inv_z; + inv_z = 1.0 / x4[ZZ]; + v2[XX] = x0 + sx * x4[XX] * inv_z; + v2[YY] = y0 - sy * x4[YY] * inv_z; } -static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, - int x0, int y0, real sx, real sy, int boxtype) +static void draw_box(t_x11* x11, Window w, t_3dview* view, matrix box, int x0, int y0, real sx, real sy, int boxtype) { - rvec rect_tri[8] = { - { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, - { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } - }; - int tr_bonds[12][2] = { - { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, - { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 4 }, - { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } - }; - static int *edge = nullptr; + rvec rect_tri[8] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, + { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } }; + int tr_bonds[12][2] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, + { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } }; + static int* edge = nullptr; int i, j, k, i0, i1; rvec corner[NCUCEDGE], box_center; vec4 x4; @@ -465,10 +451,9 @@ static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, XSetForeground(x11->disp, x11->gc, YELLOW); for (i = 0; i < NCUCEDGE; i++) { - i0 = edge[2*i]; - i1 = edge[2*i+1]; - XDrawLine(x11->disp, w, x11->gc, - vec2[i0][XX], vec2[i0][YY], vec2[i1][XX], vec2[i1][YY]); + i0 = edge[2 * i]; + i1 = edge[2 * i + 1]; + XDrawLine(x11->disp, w, x11->gc, vec2[i0][XX], vec2[i0][YY], vec2[i1][XX], vec2[i1][YY]); } } else @@ -477,7 +462,7 @@ static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, { for (j = 0; (j < DIM); j++) { - box_center[j] -= 0.5*box[j][j]; + box_center[j] -= 0.5 * box[j][j]; } } else @@ -486,7 +471,7 @@ static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, { for (j = 0; (j < DIM); j++) { - box_center[j] -= 0.5*box[i][j]; + box_center[j] -= 0.5 * box[i][j]; } } } @@ -499,12 +484,12 @@ static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, { for (k = 0; (k < DIM); k++) { - corner[i][k] += rect_tri[i][j]*box[j][k]; + corner[i][k] += rect_tri[i][j] * box[j][k]; } } else { - corner[i][j] = rect_tri[i][j]*box[j][j]; + corner[i][j] = rect_tri[i][j] * box[j][j]; } } rvec_inc(corner[i], box_center); @@ -521,32 +506,31 @@ static void draw_box(t_x11 *x11, Window w, t_3dview *view, matrix box, { i0 = tr_bonds[i][0]; i1 = tr_bonds[i][1]; - XDrawLine(x11->disp, w, x11->gc, - vec2[i0][XX], vec2[i0][YY], vec2[i1][XX], vec2[i1][YY]); + XDrawLine(x11->disp, w, x11->gc, vec2[i0][XX], vec2[i0][YY], vec2[i1][XX], vec2[i1][YY]); } } } -void set_sizes(t_manager *man) +void set_sizes(t_manager* man) { for (int i = 0; i < man->natom; i++) { if (man->bVis[i]) { - man->size[i] = 180*man->vdw[i]; + man->size[i] = 180 * man->vdw[i]; } } } -void draw_mol(t_x11 *x11, t_manager *man) +void draw_mol(t_x11* x11, t_manager* man) { static char tstr[2][20]; static int ntime = 0; - t_windata *win; - t_3dview *view; - t_molwin *mw; + t_windata* win; + t_3dview* view; + t_molwin* mw; int i, x0, y0, nvis; - iv2 *vec2; + iv2* vec2; real sx, sy; vec4 x4; @@ -561,10 +545,10 @@ void draw_mol(t_x11 *x11, t_manager *man) win = &(mw->wd); vec2 = man->ix; - x0 = win->width/2; - y0 = win->height/2; - sx = win->width/2*view->sc_x; - sy = win->height/2*view->sc_y; + x0 = win->width / 2; + y0 = win->height / 2; + sx = win->width / 2 * view->sc_x; + sy = win->height / 2 * view->sc_y; my_init_pbc(man->box); @@ -579,17 +563,17 @@ void draw_mol(t_x11 *x11, t_manager *man) } set_sizes(man); - z_fill (man, man->zz); + z_fill(man, man->zz); /* Start drawing */ XClearWindow(x11->disp, win->self); /* Draw Time */ std::sprintf(tstr[ntime], "Time: %.3f ps", man->time); - if (std::strcmp(tstr[ntime], tstr[1-ntime]) != 0) + if (std::strcmp(tstr[ntime], tstr[1 - ntime]) != 0) { set_vbtime(x11, man->vbox, tstr[ntime]); - ntime = 1-ntime; + ntime = 1 - ntime; } if (mw->boxtype != esbNone) @@ -605,9 +589,8 @@ void draw_mol(t_x11 *x11, t_manager *man) } /* Draw the objects */ - draw_objects(x11->disp, win->self, x11->gc, - nvis, man->obj, man->ix, man->x, man->col, man->size, - mw->bShowHydrogen, mw->bond_type, man->bPlus); + draw_objects(x11->disp, win->self, x11->gc, nvis, man->obj, man->ix, man->x, man->col, + man->size, mw->bShowHydrogen, mw->bond_type, man->bPlus); /* Draw the labels */ XSetForeground(x11->disp, x11->gc, WHITE); @@ -615,7 +598,7 @@ void draw_mol(t_x11 *x11, t_manager *man) { if (man->bLabel[i] && man->bVis[i]) { - XDrawString(x11->disp, win->self, x11->gc, vec2[i][XX]+2, vec2[i][YY]-2, + XDrawString(x11->disp, win->self, x11->gc, vec2[i][XX] + 2, vec2[i][YY] - 2, man->szLab[i], std::strlen(man->szLab[i])); } } diff --git a/src/programs/view/nmol.h b/src/programs/view/nmol.h index 65cfed3002..ab92eda497 100644 --- a/src/programs/view/nmol.h +++ b/src/programs/view/nmol.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,31 +42,37 @@ #include "x11.h" #include "xutil.h" -extern t_molwin *init_mw(t_x11 *x11, Window Parent, - int x, int y, int width, int height, - unsigned long fg, unsigned long bg, - int ePBC, matrix box); +extern t_molwin* init_mw(t_x11* x11, + Window Parent, + int x, + int y, + int width, + int height, + unsigned long fg, + unsigned long bg, + int ePBC, + matrix box); /* Create the molecule window using the x,y etc. */ -extern void map_mw(t_x11 *x11, t_molwin *mw); +extern void map_mw(t_x11* x11, t_molwin* mw); -extern void z_fill(t_manager *man, real *zz); -extern int compare_obj(const void *a, const void *b); -extern int filter_vis(t_manager *man); -extern void set_sizes(t_manager *man); +extern void z_fill(t_manager* man, real* zz); +extern int compare_obj(const void* a, const void* b); +extern int filter_vis(t_manager* man); +extern void set_sizes(t_manager* man); -extern bool toggle_hydrogen(t_x11 *x11, t_molwin *mw); +extern bool toggle_hydrogen(t_x11* x11, t_molwin* mw); /* Toggle the state of the hydrogen drawing, * return the current state */ -extern void set_bond_type(t_x11 *x11, t_molwin *mw, int bt); +extern void set_bond_type(t_x11* x11, t_molwin* mw, int bt); /* Set the state of the atoms drawing. */ -extern void set_box_type (t_x11 *x11, t_molwin *mw, int bt); +extern void set_box_type(t_x11* x11, t_molwin* mw, int bt); /* Set the type of box or none (bt = 0) */ -extern void done_mw(t_x11 *x11, t_molwin *mw); +extern void done_mw(t_x11* x11, t_molwin* mw); -#endif /* _nmol_h */ +#endif /* _nmol_h */ diff --git a/src/programs/view/popup.cpp b/src/programs/view/popup.cpp index 94fae9e020..63d2d465ff 100644 --- a/src/programs/view/popup.cpp +++ b/src/programs/view/popup.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,36 +48,31 @@ #include "x11.h" #include "xutil.h" -static bool ChildCallBack(t_x11 *x11, XEvent *event, Window w, void *data) +static bool ChildCallBack(t_x11* x11, XEvent* event, Window w, void* data) { - t_child *child; - t_mentry *m; - t_windata *wd; + t_child* child; + t_mentry* m; + t_windata* wd; XEvent letter; - child = (t_child *)data; + child = (t_child*)data; m = child->m; wd = &(child->wd); switch (event->type) { case Expose: XSetForeground(x11->disp, x11->gc, x11->fg); - TextInRect(x11, w, m->str, 16, 0, wd->width-16-2, wd->height-2, - eXLeft, eYCenter); + TextInRect(x11, w, m->str, 16, 0, wd->width - 16 - 2, wd->height - 2, eXLeft, eYCenter); if (m->bChecked) { int y = x11->font->ascent; - XDrawLine(x11->disp, w, x11->gc, 2, (y*2)/3, 6, y); - XDrawLine(x11->disp, w, x11->gc, 3, (y*2)/3, 7, y); + XDrawLine(x11->disp, w, x11->gc, 2, (y * 2) / 3, 6, y); + XDrawLine(x11->disp, w, x11->gc, 3, (y * 2) / 3, 7, y); XDrawLine(x11->disp, w, x11->gc, 7, y, 12, 2); } break; - case EnterNotify: - LightBorder(x11->disp, w, x11->fg); - break; - case LeaveNotify: - LightBorder(x11->disp, w, x11->bg); - break; + case EnterNotify: LightBorder(x11->disp, w, x11->fg); break; + case LeaveNotify: LightBorder(x11->disp, w, x11->bg); break; case ButtonRelease: letter.type = ClientMessage; letter.xclient.display = x11->disp; @@ -87,51 +82,45 @@ static bool ChildCallBack(t_x11 *x11, XEvent *event, Window w, void *data) letter.xclient.data.l[0] = m->nreturn; XSendEvent(x11->disp, letter.xclient.window, True, 0, &letter); break; - default: - break; + default: break; } return false; } -static bool MenuCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool MenuCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_menu *m; + t_menu* m; - m = (t_menu *)data; + m = (t_menu*)data; switch (event->type) { case Expose: /* Nothing to be done */ if (m->bGrabbed) { - m->bGrabbed = - GrabOK(stderr, XGrabPointer(x11->disp, m->wd.self, True, - ButtonReleaseMask, GrabModeAsync, - GrabModeAsync, m->wd.self, None, CurrentTime)); + m->bGrabbed = GrabOK(stderr, XGrabPointer(x11->disp, m->wd.self, True, ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, m->wd.self, + None, CurrentTime)); } break; - case ButtonRelease: - hide_menu(x11, m); - break; + case ButtonRelease: hide_menu(x11, m); break; case ClientMessage: event->xclient.window = m->Parent; XSendEvent(x11->disp, m->Parent, True, 0, event); break; - default: - break; + default: break; } return false; } -t_menu *init_menu(t_x11 *x11, Window Parent, unsigned long fg, unsigned long bg, - int nent, t_mentry ent[], int ncol) +t_menu* init_menu(t_x11* x11, Window Parent, unsigned long fg, unsigned long bg, int nent, t_mentry ent[], int ncol) { int i, mlen, mht, area, ht; int j, k, l; int frows, fcol; - t_menu *m; - t_child *kid; - t_windata *w; + t_menu* m; + t_child* kid; + t_windata* w; snew(m, 1); m->nitem = nent; @@ -146,41 +135,38 @@ t_menu *init_menu(t_x11 *x11, Window Parent, unsigned long fg, unsigned long bg, mht = XTextHeight(x11->font); /* Now we have the biggest single box, add a border of 2 pixels */ mlen += 20; /* We need extra space at the left for checkmarks */ - mht += 4; + mht += 4; /* Calculate the area of the menu */ - area = mlen*mht; + area = mlen * mht; ht = std::sqrt(area); /* No the number of rows per column, only beyond 8 rows */ if (ncol == 0) { if (nent > 8) { - frows = (1+ht/mht); + frows = (1 + ht / mht); } else { frows = nent; } - fcol = nent/frows; + fcol = nent / frows; } else { fcol = ncol; - frows = nent/ncol; + frows = nent / ncol; if (nent % ncol) { frows++; } } - InitWin(&(m->wd), 10, 10, fcol*mlen, frows*mht, 1, "Menu"); + InitWin(&(m->wd), 10, 10, fcol * mlen, frows * mht, 1, "Menu"); snew(m->item, nent); - m->wd.self = XCreateSimpleWindow(x11->disp, Parent, - m->wd.x, m->wd.y, - m->wd.width, m->wd.height, + m->wd.self = XCreateSimpleWindow(x11->disp, Parent, m->wd.x, m->wd.y, m->wd.width, m->wd.height, m->wd.bwidth, fg, bg); x11->RegisterCallback(x11, m->wd.self, Parent, MenuCallBack, m); - x11->SetInputMask(x11, m->wd.self, ExposureMask | - OwnerGrabButtonMask | ButtonReleaseMask); + x11->SetInputMask(x11, m->wd.self, ExposureMask | OwnerGrabButtonMask | ButtonReleaseMask); for (j = l = 0; (j < fcol); j++) { @@ -190,23 +176,20 @@ t_menu *init_menu(t_x11 *x11, Window Parent, unsigned long fg, unsigned long bg, kid->m = &(ent[l]); kid->Parent = Parent; w = &(kid->wd); - InitWin(w, j*mlen, k*mht, mlen-2, mht-2, 1, nullptr); - w->self = XCreateSimpleWindow(x11->disp, m->wd.self, - w->x, w->y, w->width, w->height, + InitWin(w, j * mlen, k * mht, mlen - 2, mht - 2, 1, nullptr); + w->self = XCreateSimpleWindow(x11->disp, m->wd.self, w->x, w->y, w->width, w->height, w->bwidth, bg, bg); - x11->RegisterCallback(x11, w->self, m->wd.self, - ChildCallBack, kid); + x11->RegisterCallback(x11, w->self, m->wd.self, ChildCallBack, kid); x11->SetInputMask(x11, w->self, - ButtonPressMask | ButtonReleaseMask | - OwnerGrabButtonMask | ExposureMask | - EnterWindowMask | LeaveWindowMask); + ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask + | ExposureMask | EnterWindowMask | LeaveWindowMask); } } return m; } -void show_menu(t_x11 *x11, t_menu *m, int x, int y, bool bGrab) +void show_menu(t_x11* x11, t_menu* m, int x, int y, bool bGrab) { XMoveWindow(x11->disp, m->wd.self, x, y); m->bGrabbed = bGrab; @@ -214,7 +197,7 @@ void show_menu(t_x11 *x11, t_menu *m, int x, int y, bool bGrab) XMapSubwindows(x11->disp, m->wd.self); } -void hide_menu(t_x11 *x11, t_menu *m) +void hide_menu(t_x11* x11, t_menu* m) { if (m->bGrabbed) { @@ -223,7 +206,7 @@ void hide_menu(t_x11 *x11, t_menu *m) XUnmapWindow(x11->disp, m->wd.self); } -void check_menu_item(t_menu *m, int nreturn, bool bStatus) +void check_menu_item(t_menu* m, int nreturn, bool bStatus) { int i; @@ -236,7 +219,7 @@ void check_menu_item(t_menu *m, int nreturn, bool bStatus) } } -void done_menu(t_x11 *x11, t_menu *m) +void done_menu(t_x11* x11, t_menu* m) { int i; @@ -249,12 +232,12 @@ void done_menu(t_x11 *x11, t_menu *m) sfree(m); } -int menu_width(t_menu *m) +int menu_width(t_menu* m) { return m->wd.width; } -int menu_height(t_menu *m) +int menu_height(t_menu* m) { return m->wd.height; } diff --git a/src/programs/view/popup.h b/src/programs/view/popup.h index fac384316e..924e364b77 100644 --- a/src/programs/view/popup.h +++ b/src/programs/view/popup.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -41,29 +41,32 @@ #include "x11.h" #include "xutil.h" -typedef struct { +typedef struct +{ Window send_to; /* Window to send messages to */ int nreturn; /* Value returned when entry is selected */ bool bChecked; /* Indicate whether menu item is check-marked */ - const char *str; /* Text for menu entry */ + const char* str; /* Text for menu entry */ } t_mentry; -typedef struct { - t_windata wd; /* The window struct */ - t_mentry *m; /* The menu entry */ - Window Parent; /* Parent window id */ +typedef struct +{ + t_windata wd; /* The window struct */ + t_mentry* m; /* The menu entry */ + Window Parent; /* Parent window id */ } t_child; -typedef struct { - t_windata wd; /* The window struct */ - Window Parent; /* The parent of the menu */ - int nitem; /* The number of menu items */ - t_child *item; /* Array of child windows */ - bool bGrabbed; /* Did this menu grab the pointer? */ +typedef struct +{ + t_windata wd; /* The window struct */ + Window Parent; /* The parent of the menu */ + int nitem; /* The number of menu items */ + t_child* item; /* Array of child windows */ + bool bGrabbed; /* Did this menu grab the pointer? */ } t_menu; -extern t_menu *init_menu(t_x11 *x11, Window Parent, unsigned long fg, unsigned long bg, - int nent, t_mentry ent[], int ncol); +extern t_menu* +init_menu(t_x11* x11, Window Parent, unsigned long fg, unsigned long bg, int nent, t_mentry ent[], int ncol); /* This routine will create a popup menu. It will create a * a base window, and child windows for all the items. * If ncol != 0 then ncol columns of items will be created; @@ -78,7 +81,7 @@ extern t_menu *init_menu(t_x11 *x11, Window Parent, unsigned long fg, unsigned l * has to be shown, call show_menu. */ -extern void show_menu(t_x11 *x11, t_menu *m, int x, int y, bool bGrab); +extern void show_menu(t_x11* x11, t_menu* m, int x, int y, bool bGrab); /* Show the menu in m at (x,y) * This will popup the menu, and when a button is released in the * menu send a ClientMessage to the Parent window of the menu @@ -86,22 +89,22 @@ extern void show_menu(t_x11 *x11, t_menu *m, int x, int y, bool bGrab); * bGrab specifies whether or not to grab the pointer. */ -extern void hide_menu(t_x11 *x11, t_menu *m); +extern void hide_menu(t_x11* x11, t_menu* m); /* Unmaps the window for m, hides the window */ -extern void check_menu_item(t_menu *m, int nreturn, bool bStatus); +extern void check_menu_item(t_menu* m, int nreturn, bool bStatus); /* Set the bChecked field in the menu item with return code * nreturn to bStatus. This function must always be called when * the bChecked flag has to changed. */ -extern void done_menu(t_x11 *x11, t_menu *m); +extern void done_menu(t_x11* x11, t_menu* m); /* This routine destroys the menu m, and unregisters it with x11 */ -extern int menu_width(t_menu *m); +extern int menu_width(t_menu* m); /* Return the width of the window */ -extern int menu_height(t_menu *m); +extern int menu_height(t_menu* m); /* Return the height of the window */ -#endif /* _popup_h */ +#endif /* _popup_h */ diff --git a/src/programs/view/pulldown.cpp b/src/programs/view/pulldown.cpp index 57a62e8868..6c4bbb703c 100644 --- a/src/programs/view/pulldown.cpp +++ b/src/programs/view/pulldown.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -48,18 +48,18 @@ #include "popup.h" #include "x11.h" -static bool PDCallBack(t_x11 *x11, XEvent *event, Window w, void *data) +static bool PDCallBack(t_x11* x11, XEvent* event, Window w, void* data) { - t_pulldown *pd; + t_pulldown* pd; int i, x, x1, y, nsel; - pd = (t_pulldown *)data; + pd = (t_pulldown*)data; y = pd->wd.height; switch (event->type) { case Expose: XSetForeground(x11->disp, x11->gc, x11->fg); - XDrawLine(x11->disp, w, x11->gc, 0, y-1, pd->wd.width, y-1); + XDrawLine(x11->disp, w, x11->gc, 0, y - 1, pd->wd.width, y - 1); for (i = 0; (i < pd->nmenu); i++) { XDrawString(x11->disp, pd->wd.self, x11->gc, pd->xpos[i], x11->font->ascent, @@ -70,29 +70,32 @@ static bool PDCallBack(t_x11 *x11, XEvent *event, Window w, void *data) if (pd->nsel == -1) { x = event->xbutton.x; - for (nsel = 0; (pd->xpos[nsel+1] < x) && (nsel < pd->nmenu-1); nsel++) + for (nsel = 0; (pd->xpos[nsel + 1] < x) && (nsel < pd->nmenu - 1); nsel++) { ; } pd->nsel = nsel; - x1 = std::max(0, std::min(pd_width(pd)-menu_width(pd->m[nsel]), pd->xpos[nsel])); - show_menu(x11, pd->m[nsel], x1, y+1, false); + x1 = std::max(0, std::min(pd_width(pd) - menu_width(pd->m[nsel]), pd->xpos[nsel])); + show_menu(x11, pd->m[nsel], x1, y + 1, false); } break; - case ButtonRelease: - hide_pd(x11, pd); - break; - default: - break; + case ButtonRelease: hide_pd(x11, pd); break; + default: break; } return false; } -t_pulldown *init_pd(t_x11 *x11, Window Parent, int width, - unsigned long fg, unsigned long bg, - int nmenu, int *nsub, t_mentry *ent[], const char **title) +t_pulldown* init_pd(t_x11* x11, + Window Parent, + int width, + unsigned long fg, + unsigned long bg, + int nmenu, + int* nsub, + t_mentry* ent[], + const char** title) { - t_pulldown *pd; + t_pulldown* pd; int i; snew(pd, 1); @@ -100,26 +103,24 @@ t_pulldown *init_pd(t_x11 *x11, Window Parent, int width, pd->nmenu = nmenu; pd->nsel = -1; snew(pd->m, nmenu); - snew(pd->xpos, nmenu+1); + snew(pd->xpos, nmenu + 1); pd->xpos[0] = 5; for (i = 1; (i <= nmenu); i++) { - pd->xpos[i] = 20+pd->xpos[i-1]+ - XTextWidth(x11->font, title[i-1], std::strlen(title[i-1])); + pd->xpos[i] = + 20 + pd->xpos[i - 1] + XTextWidth(x11->font, title[i - 1], std::strlen(title[i - 1])); } if (pd->xpos[nmenu] > width) { std::printf("Menu too wide\n"); } - InitWin(&(pd->wd), 0, 0, width, XTextHeight(x11->font)+2, 0, "PullDown"); - pd->wd.self = XCreateSimpleWindow(x11->disp, Parent, - pd->wd.x, pd->wd.y, - pd->wd.width, pd->wd.height, - pd->wd.bwidth, fg, bg); + InitWin(&(pd->wd), 0, 0, width, XTextHeight(x11->font) + 2, 0, "PullDown"); + pd->wd.self = XCreateSimpleWindow(x11->disp, Parent, pd->wd.x, pd->wd.y, pd->wd.width, + pd->wd.height, pd->wd.bwidth, fg, bg); x11->RegisterCallback(x11, pd->wd.self, Parent, PDCallBack, pd); - x11->SetInputMask(x11, pd->wd.self, ExposureMask | ButtonPressMask | - OwnerGrabButtonMask | ButtonReleaseMask); + x11->SetInputMask(x11, pd->wd.self, + ExposureMask | ButtonPressMask | OwnerGrabButtonMask | ButtonReleaseMask); XMapWindow(x11->disp, pd->wd.self); for (i = 0; (i < nmenu); i++) @@ -130,7 +131,7 @@ t_pulldown *init_pd(t_x11 *x11, Window Parent, int width, return pd; } -void hide_pd(t_x11 *x11, t_pulldown *pd) +void hide_pd(t_x11* x11, t_pulldown* pd) { if (pd->nsel != -1) { @@ -139,7 +140,7 @@ void hide_pd(t_x11 *x11, t_pulldown *pd) pd->nsel = -1; } -void check_pd_item(t_pulldown *pd, int nreturn, bool bStatus) +void check_pd_item(t_pulldown* pd, int nreturn, bool bStatus) { int i; @@ -149,7 +150,7 @@ void check_pd_item(t_pulldown *pd, int nreturn, bool bStatus) } } -void done_pd(t_x11 *x11, t_pulldown *pd) +void done_pd(t_x11* x11, t_pulldown* pd) { int i; @@ -162,7 +163,7 @@ void done_pd(t_x11 *x11, t_pulldown *pd) sfree(pd->xpos); } -int pd_width(t_pulldown *pd) +int pd_width(t_pulldown* pd) { int i, w; @@ -175,7 +176,7 @@ int pd_width(t_pulldown *pd) return w; } -int pd_height(t_pulldown *pd) +int pd_height(t_pulldown* pd) { int i, h; diff --git a/src/programs/view/pulldown.h b/src/programs/view/pulldown.h index 71777971b4..1d87cd4a17 100644 --- a/src/programs/view/pulldown.h +++ b/src/programs/view/pulldown.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,19 +40,25 @@ #include "popup.h" -typedef struct { +typedef struct +{ t_windata wd; int nmenu; int nsel; - int *xpos; - t_menu **m; - const char **title; + int* xpos; + t_menu** m; + const char** title; } t_pulldown; -extern t_pulldown *init_pd(t_x11 *x11, Window Parent, int width, - unsigned long fg, unsigned long bg, - int nmenu, int *nsub, t_mentry *ent[], - const char **title); +extern t_pulldown* init_pd(t_x11* x11, + Window Parent, + int width, + unsigned long fg, + unsigned long bg, + int nmenu, + int* nsub, + t_mentry* ent[], + const char** title); /* nmenu is the number of submenus, title are the titles of * the submenus, nsub are the numbers of entries in each submenu * ent are the entries in the pulldown menu, analogous to these in the @@ -68,22 +74,22 @@ extern t_pulldown *init_pd(t_x11 *x11, Window Parent, int width, * specifying the selected item in xclient.data.l[0]. */ -extern void hide_pd(t_x11 *x11, t_pulldown *pd); +extern void hide_pd(t_x11* x11, t_pulldown* pd); /* Hides any menu that is still on the screen when it shouldn't */ -extern void check_pd_item(t_pulldown *pd, int nreturn, bool bStatus); +extern void check_pd_item(t_pulldown* pd, int nreturn, bool bStatus); /* Set the bChecked field in the pd item with return code * nreturn to bStatus. This function must always be called when * the bChecked flag has to changed. */ -extern void done_pd(t_x11 *x11, t_pulldown *pd); +extern void done_pd(t_x11* x11, t_pulldown* pd); /* This routine destroys the menu pd, and unregisters it with x11 */ -extern int pd_width(t_pulldown *pd); +extern int pd_width(t_pulldown* pd); /* Return the width of the window */ -extern int pd_height(t_pulldown *pd); +extern int pd_height(t_pulldown* pd); /* Return the height of the window */ -#endif /* _pulldown_h */ +#endif /* _pulldown_h */ diff --git a/src/programs/view/view.cpp b/src/programs/view/view.cpp index c41e8ff80e..f3c5b5ce84 100644 --- a/src/programs/view/view.cpp +++ b/src/programs/view/view.cpp @@ -56,16 +56,16 @@ #if GMX_X11 -#include "gromacs/fileio/writeps.h" +# include "gromacs/fileio/writeps.h" -#include "Xstuff.h" -#include "dialogs.h" -#include "gromacs.bm" -#include "molps.h" -#include "nmol.h" -#include "xutil.h" +# include "Xstuff.h" +# include "dialogs.h" +# include "gromacs.bm" +# include "molps.h" +# include "nmol.h" +# include "xutil.h" -static void dump_it(t_manager *man) +static void dump_it(t_manager* man) { t_psdata ps; @@ -74,7 +74,7 @@ static void dump_it(t_manager *man) ps_close(&ps); } -static void done_gmx(t_x11 *x11, t_gmx *gmx) +static void done_gmx(t_x11* x11, t_gmx* gmx) { done_logo(x11, gmx->logo); done_pd(x11, gmx->pd); @@ -83,13 +83,12 @@ static void done_gmx(t_x11 *x11, t_gmx *gmx) x11->UnRegisterCallback(x11, gmx->wd->self); } -static void move_gmx(t_x11 *x11, t_gmx *gmx, int width, int height, - bool bSizePD) +static void move_gmx(t_x11* x11, t_gmx* gmx, int width, int height, bool bSizePD) { int y0, wl, hl; -#ifdef DEBUG +# ifdef DEBUG std::fprintf(stderr, "Move gmx %dx%d\n", width, height); -#endif +# endif y0 = XTextHeight(x11->font); /* Resize PD-Menu */ if (bSizePD) @@ -97,26 +96,24 @@ static void move_gmx(t_x11 *x11, t_gmx *gmx, int width, int height, XResizeWindow(x11->disp, gmx->pd->wd.self, width, y0); } - XMoveWindow(x11->disp, gmx->man->wd.self, 0, y0+1); - XResizeWindow(x11->disp, gmx->man->wd.self, width, height-y0-1); + XMoveWindow(x11->disp, gmx->man->wd.self, 0, y0 + 1); + XResizeWindow(x11->disp, gmx->man->wd.self, width, height - y0 - 1); wl = gmx->logo->wd.width; hl = gmx->logo->wd.height; - XMoveWindow(x11->disp, gmx->logo->wd.self, (width-wl)/2, (height-y0-hl)/2); + XMoveWindow(x11->disp, gmx->logo->wd.self, (width - wl) / 2, (height - y0 - hl) / 2); } -static bool HandleClient(t_x11 *x11, int ID, t_gmx *gmx) +static bool HandleClient(t_x11* x11, int ID, t_gmx* gmx) { - t_pulldown *pd; + t_pulldown* pd; pd = gmx->pd; switch (ID) { /* File Menu */ - case IDDUMPWIN: - write_gmx(x11, gmx, IDDODUMP); - break; + case IDDUMPWIN: write_gmx(x11, gmx, IDDODUMP); break; case IDDODUMP: if (gmx->man->bAnimate) { @@ -130,31 +127,18 @@ static bool HandleClient(t_x11 *x11, int ID, t_gmx *gmx) break; case IDCLOSE: case IDIMPORT: - case IDEXPORT: - ShowDlg(gmx->dlgs[edExport]); - break; + case IDEXPORT: ShowDlg(gmx->dlgs[edExport]); break; case IDDOEXPORT: - write_sto_conf(gmx->confout, *gmx->man->top.name, - &(gmx->man->top.atoms), - gmx->man->x, nullptr, gmx->man->molw->ePBC, gmx->man->box); - break; - case IDQUIT: - show_mb(gmx, emQuit); + write_sto_conf(gmx->confout, *gmx->man->top.name, &(gmx->man->top.atoms), gmx->man->x, + nullptr, gmx->man->molw->ePBC, gmx->man->box); break; - case IDTERM: - done_gmx(x11, gmx); - return true; + case IDQUIT: show_mb(gmx, emQuit); break; + case IDTERM: done_gmx(x11, gmx); return true; /* Edit Menu */ - case IDEDITTOP: - edit_file("topol.gmx"); - break; - case IDEDITCOORDS: - edit_file("confin.gmx"); - break; - case IDEDITPARAMS: - edit_file("mdparin.gmx"); - break; + case IDEDITTOP: edit_file("topol.gmx"); break; + case IDEDITCOORDS: edit_file("confin.gmx"); break; + case IDEDITPARAMS: edit_file("mdparin.gmx"); break; /* Display Menu */ case IDFILTER: @@ -163,49 +147,23 @@ static bool HandleClient(t_x11 *x11, int ID, t_gmx *gmx) ShowDlg(gmx->dlgs[edFilter]); } break; - case IDDOFILTER: - do_filter(x11, gmx->man, gmx->filter); - break; - case IDANIMATE: - check_pd_item(pd, IDANIMATE, toggle_animate(x11, gmx->man)); - break; - case IDLABELSOFF: - no_labels(x11, gmx->man); - break; + case IDDOFILTER: do_filter(x11, gmx->man, gmx->filter); break; + case IDANIMATE: check_pd_item(pd, IDANIMATE, toggle_animate(x11, gmx->man)); break; + case IDLABELSOFF: no_labels(x11, gmx->man); break; case IDRESETVIEW: reset_view(gmx->man->view); ExposeWin(x11->disp, gmx->man->molw->wd.self); break; - case IDPHOTO: - show_mb(gmx, emNotImplemented); - break; - case IDBONDOPTS: - ShowDlg(gmx->dlgs[edBonds]); - break; - case IDTHIN: - set_bond_type(x11, gmx->man->molw, eBThin); - break; - case IDFAT: - set_bond_type(x11, gmx->man->molw, eBFat); - break; - case IDVERYFAT: - set_bond_type(x11, gmx->man->molw, eBVeryFat); - break; - case IDBALLS: - set_bond_type(x11, gmx->man->molw, eBSpheres); - break; - case IDNOBOX: - set_box_type(x11, gmx->man->molw, esbNone); - break; - case IDRECTBOX: - set_box_type(x11, gmx->man->molw, esbRect); - break; - case IDTRIBOX: - set_box_type(x11, gmx->man->molw, esbTri); - break; - case IDTOBOX: - set_box_type(x11, gmx->man->molw, esbTrunc); - break; + case IDPHOTO: show_mb(gmx, emNotImplemented); break; + case IDBONDOPTS: ShowDlg(gmx->dlgs[edBonds]); break; + case IDTHIN: set_bond_type(x11, gmx->man->molw, eBThin); break; + case IDFAT: set_bond_type(x11, gmx->man->molw, eBFat); break; + case IDVERYFAT: set_bond_type(x11, gmx->man->molw, eBVeryFat); break; + case IDBALLS: set_bond_type(x11, gmx->man->molw, eBSpheres); break; + case IDNOBOX: set_box_type(x11, gmx->man->molw, esbNone); break; + case IDRECTBOX: set_box_type(x11, gmx->man->molw, esbRect); break; + case IDTRIBOX: set_box_type(x11, gmx->man->molw, esbTri); break; + case IDTOBOX: set_box_type(x11, gmx->man->molw, esbTrunc); break; /* Analysis Menu */ case IDBOND: @@ -214,37 +172,28 @@ static bool HandleClient(t_x11 *x11, int ID, t_gmx *gmx) case IDRMS: case IDRDF: case IDENERGIES: - case IDCORR: - show_mb(gmx, emNotImplemented); - break; + case IDCORR: show_mb(gmx, emNotImplemented); break; /* Help Menu */ - case IDHELP: - show_mb(gmx, emHelp); - break; - case IDABOUT: - show_logo(x11, gmx->logo); - break; + case IDHELP: show_mb(gmx, emHelp); break; + case IDABOUT: show_logo(x11, gmx->logo); break; - default: - break; + default: break; } return false; } -static bool MainCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) +static bool MainCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data) { - t_gmx *gmx; - int nsel, width, height; - bool result; + t_gmx* gmx; + int nsel, width, height; + bool result; result = false; - gmx = (t_gmx *)data; + gmx = (t_gmx*)data; switch (event->type) { - case ButtonRelease: - hide_pd(x11, gmx->pd); - break; + case ButtonRelease: hide_pd(x11, gmx->pd); break; case ConfigureNotify: width = event->xconfigure.width; height = event->xconfigure.height; @@ -258,90 +207,71 @@ static bool MainCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data) nsel = event->xclient.data.l[0]; result = HandleClient(x11, nsel, gmx); break; - default: - break; + default: break; } return result; } -static t_mentry FileMenu[] = { - { 0, IDEXPORT, false, "Export..." }, - { 0, IDDUMPWIN, false, "Print" }, - { 0, IDQUIT, false, "Quit" } -}; +static t_mentry FileMenu[] = { { 0, IDEXPORT, false, "Export..." }, + { 0, IDDUMPWIN, false, "Print" }, + { 0, IDQUIT, false, "Quit" } }; -static t_mentry DispMenu[] = { - { 0, IDFILTER, false, "Filter..." }, - { 0, IDANIMATE, false, "Animate" }, - { 0, IDLABELSOFF, false, "Labels Off"}, - { 0, IDRESETVIEW, false, "Reset View"}, - { 0, IDBONDOPTS, false, "Options..."} -}; +static t_mentry DispMenu[] = { { 0, IDFILTER, false, "Filter..." }, + { 0, IDANIMATE, false, "Animate" }, + { 0, IDLABELSOFF, false, "Labels Off" }, + { 0, IDRESETVIEW, false, "Reset View" }, + { 0, IDBONDOPTS, false, "Options..." } }; -static t_mentry HelpMenu[] = { - { 0, IDHELP, false, "Help" }, - { 0, IDABOUT, false, "About GROMACS..." } -}; +static t_mentry HelpMenu[] = { { 0, IDHELP, false, "Help" }, + { 0, IDABOUT, false, "About GROMACS..." } }; -static t_mentry *gmx_pd[] = { FileMenu, DispMenu, HelpMenu }; +static t_mentry* gmx_pd[] = { FileMenu, DispMenu, HelpMenu }; -#define MSIZE asize(gmx_pd) +# define MSIZE asize(gmx_pd) -static int gmx_pd_size[MSIZE] = { - asize(FileMenu), asize(DispMenu), asize(HelpMenu) -}; +static int gmx_pd_size[MSIZE] = { asize(FileMenu), asize(DispMenu), asize(HelpMenu) }; -static const char *MenuTitle[MSIZE] = { - "File", "Display", "Help" -}; +static const char* MenuTitle[MSIZE] = { "File", "Display", "Help" }; -static void init_gmx(t_x11 *x11, char *program, int nfile, t_filenm fnm[], - gmx_output_env_t *oenv) +static void init_gmx(t_x11* x11, char* program, int nfile, t_filenm fnm[], gmx_output_env_t* oenv) { - Pixmap pm; - t_gmx *gmx; - XSizeHints hints; - int w0, h0; - int natom, natom_trx; - t_topology top; - int ePBC; - matrix box; - t_trxframe fr; - t_trxstatus *status; + Pixmap pm; + t_gmx* gmx; + XSizeHints hints; + int w0, h0; + int natom, natom_trx; + t_topology top; + int ePBC; + matrix box; + t_trxframe fr; + t_trxstatus* status; snew(gmx, 1); snew(gmx->wd, 1); - ePBC = read_tpx_top(ftp2fn(efTPR, nfile, fnm), - nullptr, box, &natom, nullptr, nullptr, &top); + ePBC = read_tpx_top(ftp2fn(efTPR, nfile, fnm), nullptr, box, &natom, nullptr, nullptr, &top); read_first_frame(oenv, &status, ftp2fn(efTRX, nfile, fnm), &fr, TRX_DONT_SKIP); close_trx(status); natom_trx = fr.natoms; /* Creates a simple window */ - w0 = DisplayWidth(x11->disp, x11->screen)-132; - h0 = DisplayHeight(x11->disp, x11->screen)-140; + w0 = DisplayWidth(x11->disp, x11->screen) - 132; + h0 = DisplayHeight(x11->disp, x11->screen) - 140; InitWin(gmx->wd, 0, 0, w0, h0, 3, gmx::bromacs().c_str()); - gmx->wd->self = XCreateSimpleWindow(x11->disp, x11->root, - gmx->wd->x, gmx->wd->y, - gmx->wd->width, gmx->wd->height, - gmx->wd->bwidth, WHITE, BLACK); - pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, - (char *)gromacs_bits, gromacs_width, - gromacs_height, - WHITE, BLACK, 1); + gmx->wd->self = XCreateSimpleWindow(x11->disp, x11->root, gmx->wd->x, gmx->wd->y, gmx->wd->width, + gmx->wd->height, gmx->wd->bwidth, WHITE, BLACK); + pm = XCreatePixmapFromBitmapData(x11->disp, x11->root, (char*)gromacs_bits, gromacs_width, + gromacs_height, WHITE, BLACK, 1); hints.flags = PMinSize; - hints.min_width = 2*EWIDTH+40; - hints.min_height = EHEIGHT+LDHEIGHT+LEGHEIGHT+40; - XSetStandardProperties(x11->disp, gmx->wd->self, gmx->wd->text, program, - pm, nullptr, 0, &hints); + hints.min_width = 2 * EWIDTH + 40; + hints.min_height = EHEIGHT + LDHEIGHT + LEGHEIGHT + 40; + XSetStandardProperties(x11->disp, gmx->wd->self, gmx->wd->text, program, pm, nullptr, 0, &hints); x11->RegisterCallback(x11, gmx->wd->self, x11->root, MainCallBack, gmx); x11->SetInputMask(x11, gmx->wd->self, - ButtonPressMask | ButtonReleaseMask | - OwnerGrabButtonMask | ExposureMask | - StructureNotifyMask); + ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | ExposureMask + | StructureNotifyMask); /* The order of creating windows is important here! */ /* Manager */ @@ -355,14 +285,12 @@ static void init_gmx(t_x11 *x11, char *program, int nfile, t_filenm fnm[], map_man(x11, gmx->man); /* Pull Down menu */ - gmx->pd = init_pd(x11, gmx->wd->self, gmx->wd->width, - x11->fg, x11->bg, - MSIZE, gmx_pd_size, gmx_pd, MenuTitle); + gmx->pd = init_pd(x11, gmx->wd->self, gmx->wd->width, x11->fg, x11->bg, MSIZE, gmx_pd_size, + gmx_pd, MenuTitle); /* Dialogs & Filters */ - gmx->filter = init_filter(&(top.atoms), ftp2fn_null(efNDX, nfile, fnm), - natom_trx); + gmx->filter = init_filter(&(top.atoms), ftp2fn_null(efNDX, nfile, fnm), natom_trx); init_dlgs(x11, gmx); @@ -373,9 +301,9 @@ static void init_gmx(t_x11 *x11, char *program, int nfile, t_filenm fnm[], } #endif -int gmx_view(int argc, char *argv[]) +int gmx_view(int argc, char* argv[]) { - const char *desc[] = { + const char* desc[] = { "[THISMODULE] is the GROMACS trajectory viewer. This program reads a", "trajectory file, a run input file and an index file and plots a", "3D structure of your molecule on your standard X Window", @@ -391,30 +319,27 @@ int gmx_view(int argc, char *argv[]) "Some of the more common X command line options can be used: ", "[TT]-bg[tt], [TT]-fg[tt] change colors, [TT]-font fontname[tt] changes the font." }; - const char *bugs[] = { - "Balls option does not work", - "Some times dumps core without a good reason" - }; + const char* bugs[] = { "Balls option does not work", + "Some times dumps core without a good reason" }; - gmx_output_env_t *oenv; - t_filenm fnm[] = { - { efTRX, "-f", nullptr, ffREAD }, - { efTPR, nullptr, nullptr, ffREAD }, - { efNDX, nullptr, nullptr, ffOPTRD } - }; + gmx_output_env_t* oenv; + t_filenm fnm[] = { { efTRX, "-f", nullptr, ffREAD }, + { efTPR, nullptr, nullptr, ffREAD }, + { efNDX, nullptr, nullptr, ffOPTRD } }; #define NFILE asize(fnm) - if (parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, - 0, nullptr, asize(desc), desc, asize(bugs), bugs, &oenv)) + if (parse_common_args(&argc, argv, PCA_CAN_TIME, NFILE, fnm, 0, nullptr, asize(desc), desc, + asize(bugs), bugs, &oenv)) { #if !GMX_X11 std::fprintf(stderr, "Compiled without X-Windows - can not run viewer.\n"); #else - t_x11 *x11; + t_x11* x11; if ((x11 = GetX11(&argc, argv)) == nullptr) { - std::fprintf(stderr, "Can't connect to X Server.\n" + std::fprintf(stderr, + "Can't connect to X Server.\n" "Check your DISPLAY environment variable\n"); } else diff --git a/src/programs/view/view.h b/src/programs/view/view.h index b41877044d..a1463944aa 100644 --- a/src/programs/view/view.h +++ b/src/programs/view/view.h @@ -2,7 +2,7 @@ * This file is part of the GROMACS molecular simulation package. * * Copyright (c) 2013, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -35,10 +35,9 @@ */ #ifndef _view_h -#define _view_h +# define _view_h -int -gmx_view(int argc, char *argv[]); +int gmx_view(int argc, char* argv[]); #endif /* _view_h */ diff --git a/src/programs/view/x11.cpp b/src/programs/view/x11.cpp index fcfc76d275..b429024522 100644 --- a/src/programs/view/x11.cpp +++ b/src/programs/view/x11.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -53,9 +53,9 @@ unsigned long BLACK, BLUE, GREEN, CYAN, RED, BROWN, GREY, DARKGREY; /* These colours will be mapped to white on a monochrome screen */ unsigned long LIGHTBLUE, LIGHTGREEN, LIGHTGREY, LIGHTCYAN, LIGHTRED, VIOLET, YELLOW, WHITE; -static XFontStruct *XLQF(FILE gmx_unused *err, Display *disp, const char *name) +static XFontStruct* XLQF(FILE gmx_unused* err, Display* disp, const char* name) { - XFontStruct *font = XLoadQueryFont(disp, name); + XFontStruct* font = XLoadQueryFont(disp, name); #ifdef DEBUG if (font != NULL) { @@ -65,18 +65,15 @@ static XFontStruct *XLQF(FILE gmx_unused *err, Display *disp, const char *name) return font; } -static XFontStruct *GetFont(FILE *err, Display *disp, char *name) +static XFontStruct* GetFont(FILE* err, Display* disp, char* name) { - static const char *fontnames[] = { - "sansb12", "8x13bold", "8x13", - "9x15", "6x13", "fixed" - }; -#define MAXNAMES (sizeof(fontnames)/sizeof(fontnames[0])) - unsigned int i; - XFontStruct *font; - int count; - char **fontlist; - bool bFont = false; + static const char* fontnames[] = { "sansb12", "8x13bold", "8x13", "9x15", "6x13", "fixed" }; +#define MAXNAMES (sizeof(fontnames) / sizeof(fontnames[0])) + unsigned int i; + XFontStruct* font; + int count; + char** fontlist; + bool bFont = false; if (name) { @@ -102,22 +99,22 @@ static XFontStruct *GetFont(FILE *err, Display *disp, char *name) } if (!bFont) { - fprintf (err, "Cannot load any suitable font\n"); + fprintf(err, "Cannot load any suitable font\n"); } return font; } -static GC GetGC(Display *disp, XFontStruct *font) +static GC GetGC(Display* disp, XFontStruct* font) { - XGCValues values; + XGCValues values; values.font = font->fid; values.foreground = WhitePixel(disp, DefaultScreen(disp)); - return XCreateGC(disp, DefaultRootWindow(disp), GCForeground|GCFont, &values); + return XCreateGC(disp, DefaultRootWindow(disp), GCForeground | GCFont, &values); } -void GetNamedColor(t_x11 *x11, const char *name, unsigned long *col) +void GetNamedColor(t_x11* x11, const char* name, unsigned long* col) { /* If name is found than col set to that colour else col is unchanged */ XColor exact, clr; @@ -132,9 +129,9 @@ void GetNamedColor(t_x11 *x11, const char *name, unsigned long *col) } } -static t_wlist *GetWList(t_x11 *x11, Window w) +static t_wlist* GetWList(t_x11* x11, Window w) { - t_wlist *curs; + t_wlist* curs; curs = x11->wlist; while (curs && (curs->w != w)) @@ -145,14 +142,14 @@ static t_wlist *GetWList(t_x11 *x11, Window w) return curs; } -static void MainLoop(t_x11 *x11) +static void MainLoop(t_x11* x11) { - bool bReturn; - XEvent event; - t_wlist *curs; - Window w; + bool bReturn; + XEvent event; + t_wlist* curs; + Window w; - for (bReturn = false; (!bReturn); ) + for (bReturn = false; (!bReturn);) { if (x11->wlist) { @@ -179,8 +176,7 @@ static void MainLoop(t_x11 *x11) if (XCheckTypedWindowEvent(x11->disp,w,ConfigureNotify,&config)) curs=NULL; */ break; - default: - break; + default: break; } if (curs) { @@ -191,8 +187,7 @@ static void MainLoop(t_x11 *x11) } } -static void RegisterCallback(t_x11 *x11, Window w, Window Parent, - CallBack cb, void *data) +static void RegisterCallback(t_x11* x11, Window w, Window Parent, CallBack cb, void* data) { t_wlist *curs, *item; @@ -219,9 +214,9 @@ static void RegisterCallback(t_x11 *x11, Window w, Window Parent, } } -static void UnRegisterCallback(t_x11 *x11, Window w) +static void UnRegisterCallback(t_x11* x11, Window w) { - t_wlist *curs; + t_wlist* curs; curs = x11->wlist; if (curs) @@ -239,7 +234,7 @@ static void UnRegisterCallback(t_x11 *x11, Window w) } if (curs->next) { - t_wlist *tmp = curs->next; + t_wlist* tmp = curs->next; curs->next = curs->next->next; sfree(tmp); @@ -248,9 +243,9 @@ static void UnRegisterCallback(t_x11 *x11, Window w) } } -static void SetInputMask(t_x11 *x11, Window w, unsigned long mask) +static void SetInputMask(t_x11* x11, Window w, unsigned long mask) { - t_wlist *curs; + t_wlist* curs; curs = GetWList(x11, w); if (curs) @@ -264,9 +259,9 @@ static void SetInputMask(t_x11 *x11, Window w, unsigned long mask) } } -static unsigned long GetInputMask(t_x11 *x11, Window w) +static unsigned long GetInputMask(t_x11* x11, Window w) { - t_wlist *curs; + t_wlist* curs; curs = GetWList(x11, w); if (curs) @@ -279,9 +274,9 @@ static unsigned long GetInputMask(t_x11 *x11, Window w) } } -static void CleanUp(t_x11 *x11) +static void CleanUp(t_x11* x11) { - t_wlist *curs; + t_wlist* curs; curs = x11->wlist; while (curs) @@ -294,32 +289,27 @@ static void CleanUp(t_x11 *x11) XCloseDisplay(x11->disp); } -static void Flush(t_x11 *x11) +static void Flush(t_x11* x11) { std::fflush(x11->console); } -t_x11 *GetX11(int *argc, char *argv[]) +t_x11* GetX11(int* argc, char* argv[]) { - static const char *v_name[] = { - "DirectColor", "TrueColor", "PseudoColor", - "StaticColor", "GrayScale", "StaticGray" - }; - static int v_class[] = { - DirectColor, TrueColor, PseudoColor, - StaticColor, GrayScale, StaticGray - }; -#define NCLASS (sizeof(v_class)/sizeof(v_class[0])) - - XVisualInfo v_info; - t_x11 *x11; - int ARGC; - char **ARGV; - char *display; - char *fontname; - char *title, *FG = nullptr, *BG = nullptr; - bool bVerbose = false; - int i; + static const char* v_name[] = { "DirectColor", "TrueColor", "PseudoColor", + "StaticColor", "GrayScale", "StaticGray" }; + static int v_class[] = { DirectColor, TrueColor, PseudoColor, StaticColor, GrayScale, StaticGray }; +#define NCLASS (sizeof(v_class) / sizeof(v_class[0])) + + XVisualInfo v_info; + t_x11* x11; + int ARGC; + char** ARGV; + char* display; + char* fontname; + char * title, *FG = nullptr, *BG = nullptr; + bool bVerbose = false; + int i; title = gmx_strdup(argv[0]); @@ -335,37 +325,25 @@ t_x11 *GetX11(int *argc, char *argv[]) { if (strlen(argv[i]) > 1) { - if ((*argc) > i+1) + if ((*argc) > i + 1) { switch (argv[i][1]) { - case 'b': - BG = argv[++i]; - break; - case 'd': - display = argv[++i]; - break; + case 'b': BG = argv[++i]; break; + case 'd': display = argv[++i]; break; case 'f': switch (argv[i][2]) { - case 'o': - fontname = argv[++i]; - break; - case 'g': - FG = argv[++i]; - break; + case 'o': fontname = argv[++i]; break; + case 'g': FG = argv[++i]; break; } break; case 't': sfree(title); title = gmx_strdup(argv[++i]); break; - case 'v': - bVerbose = true; - break; - default: - ARGV[ARGC++] = argv[i]; - break; + case 'v': bVerbose = true; break; + default: ARGV[ARGC++] = argv[i]; break; } } } @@ -388,8 +366,7 @@ t_x11 *GetX11(int *argc, char *argv[]) { x11->console = stderr; } - else - if ((x11->console = std::fopen("/dev/null", "w")) == nullptr) + else if ((x11->console = std::fopen("/dev/null", "w")) == nullptr) { x11->console = stderr; } @@ -419,20 +396,18 @@ t_x11 *GetX11(int *argc, char *argv[]) /* These colours will be mapped to black on a monochrome screen */ x11->fg = BLACK = BLUE = GREEN = CYAN = RED = BROWN = GREY = DARKGREY = - BlackPixel(x11->disp, x11->screen); + BlackPixel(x11->disp, x11->screen); /* These colours will be mapped to white on a monochrome screen */ - x11->bg = - LIGHTBLUE = LIGHTGREY = LIGHTGREEN = LIGHTCYAN = LIGHTRED = VIOLET = YELLOW = WHITE = - WhitePixel(x11->disp, x11->screen); + x11->bg = LIGHTBLUE = LIGHTGREY = LIGHTGREEN = LIGHTCYAN = LIGHTRED = VIOLET = YELLOW = WHITE = + WhitePixel(x11->disp, x11->screen); if (x11->depth > 1) { /* Not B & W, Look what kind of screen we've got... */ for (i = 0; (i < (int)NCLASS); i++) { - if (!XMatchVisualInfo(x11->disp, x11->screen, x11->depth, - v_class[i], &v_info)) + if (!XMatchVisualInfo(x11->disp, x11->screen, x11->depth, v_class[i], &v_info)) { break; } diff --git a/src/programs/view/x11.h b/src/programs/view/x11.h index f755018d7f..ef567b57ca 100644 --- a/src/programs/view/x11.h +++ b/src/programs/view/x11.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,47 +46,47 @@ extern unsigned long BLACK, BLUE, GREEN, CYAN, RED, BROWN, GREY, DARKGREY; /* These colours will be mapped to white on a monochrome screen */ -extern unsigned long LIGHTBLUE, LIGHTGREY, LIGHTGREEN, LIGHTCYAN, - LIGHTRED, VIOLET, YELLOW, WHITE; +extern unsigned long LIGHTBLUE, LIGHTGREY, LIGHTGREEN, LIGHTCYAN, LIGHTRED, VIOLET, YELLOW, WHITE; -#define CBARGS (struct t_x11 *x11, XEvent *event, Window w, void *data) +#define CBARGS (struct t_x11 * x11, XEvent * event, Window w, void* data) /* Callback function. Return false to continue, true to exit */ -typedef struct t_x11 { - Display *disp; - XFontStruct *font; - GC gc; - Window root; - char *dispname; - FILE *console; - int screen, depth; - Colormap cmap; - unsigned long fg, bg; - char *title; - struct t_wlist *wlist; - void (*GetNamedColor)(struct t_x11 *x11, const char *name, unsigned long *col); - void (*MainLoop)(struct t_x11 *x11); - void (*RegisterCallback)(struct t_x11 *x11, Window w, Window Parent, - bool cb CBARGS, void *data); - void (*UnRegisterCallback)(struct t_x11 *x11, Window w); - void (*SetInputMask)(struct t_x11 *x11, Window w, unsigned long mask); - unsigned long (*GetInputMask)(struct t_x11 *x11, Window w); - void (*CleanUp)(struct t_x11 *x11); - void (*Flush)(struct t_x11 *x11); +typedef struct t_x11 +{ + Display* disp; + XFontStruct* font; + GC gc; + Window root; + char* dispname; + FILE* console; + int screen, depth; + Colormap cmap; + unsigned long fg, bg; + char* title; + struct t_wlist* wlist; + void (*GetNamedColor)(struct t_x11* x11, const char* name, unsigned long* col); + void (*MainLoop)(struct t_x11* x11); + void (*RegisterCallback)(struct t_x11* x11, Window w, Window Parent, bool cb CBARGS, void* data); + void (*UnRegisterCallback)(struct t_x11* x11, Window w); + void (*SetInputMask)(struct t_x11* x11, Window w, unsigned long mask); + unsigned long (*GetInputMask)(struct t_x11* x11, Window w); + void (*CleanUp)(struct t_x11* x11); + void (*Flush)(struct t_x11* x11); } t_x11; typedef bool CallBack CBARGS; -typedef struct t_wlist { - Window w; /* The window itself */ - Window Parent; /* It's parent window */ - CallBack *cb; /* Call back function */ - unsigned long mask; /* Input mask */ - void *data; /* User data struct */ - struct t_wlist *next; +typedef struct t_wlist +{ + Window w; /* The window itself */ + Window Parent; /* It's parent window */ + CallBack* cb; /* Call back function */ + unsigned long mask; /* Input mask */ + void* data; /* User data struct */ + struct t_wlist* next; } t_wlist; -t_x11 *GetX11(int *argc, char *argv[]); +t_x11* GetX11(int* argc, char* argv[]); /* x11 is a struct / function-set that manages a number of windows. * more or (presumably) less like Xt does, but since x11 uses only * Xlib calls, it is *PORTABLE* software. @@ -129,6 +129,6 @@ t_x11 *GetX11(int *argc, char *argv[]); * memory allocated by x11 before. */ -extern void GetNamedColor(t_x11 *x11, const char *name, unsigned long *col); +extern void GetNamedColor(t_x11* x11, const char* name, unsigned long* col); -#endif /* _x11_h */ +#endif /* _x11_h */ diff --git a/src/programs/view/xdlg.cpp b/src/programs/view/xdlg.cpp index 027b116f4c..b403a9e71b 100644 --- a/src/programs/view/xdlg.cpp +++ b/src/programs/view/xdlg.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -54,7 +54,7 @@ * Helpful routines * ****************************/ -t_dlgitem *FindItem(t_dlg *dlg, t_id id) +t_dlgitem* FindItem(t_dlg* dlg, t_id id) { int i; @@ -68,7 +68,7 @@ t_dlgitem *FindItem(t_dlg *dlg, t_id id) return nullptr; } -t_dlgitem *FindWin(t_dlg *dlg, Window win) +t_dlgitem* FindWin(t_dlg* dlg, Window win) { int i; @@ -87,9 +87,9 @@ t_dlgitem *FindWin(t_dlg *dlg, Window win) * Routines to manipulate items on a dialog box * ****************************/ -bool QueryDlgItemSize(t_dlg *dlg, t_id id, int *w, int *h) +bool QueryDlgItemSize(t_dlg* dlg, t_id id, int* w, int* h) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -100,9 +100,9 @@ bool QueryDlgItemSize(t_dlg *dlg, t_id id, int *w, int *h) return false; } -bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0) +bool QueryDlgItemPos(t_dlg* dlg, t_id id, int* x0, int* y0) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -113,9 +113,9 @@ bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0) return false; } -int QueryDlgItemX(t_dlg *dlg, t_id id) +int QueryDlgItemX(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -124,9 +124,9 @@ int QueryDlgItemX(t_dlg *dlg, t_id id) return 0; } -int QueryDlgItemY(t_dlg *dlg, t_id id) +int QueryDlgItemY(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -135,9 +135,9 @@ int QueryDlgItemY(t_dlg *dlg, t_id id) return 0; } -int QueryDlgItemW(t_dlg *dlg, t_id id) +int QueryDlgItemW(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -146,9 +146,9 @@ int QueryDlgItemW(t_dlg *dlg, t_id id) return 0; } -int QueryDlgItemH(t_dlg *dlg, t_id id) +int QueryDlgItemH(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -157,11 +157,11 @@ int QueryDlgItemH(t_dlg *dlg, t_id id) return 0; } -bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h) +bool SetDlgItemSize(t_dlg* dlg, t_id id, int w, int h) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; #ifdef DEBUG - int old_w, old_h; + int old_w, old_h; #endif if ((dlgitem = FindItem(dlg, id)) != nullptr) @@ -179,15 +179,13 @@ bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h) dlgitem->win.height = h; } #ifdef DEBUG - std::fprintf(dlg->x11->console, - "Size window from: %dx%d to %dx%d\n", old_w, old_h, + std::fprintf(dlg->x11->console, "Size window from: %dx%d to %dx%d\n", old_w, old_h, dlgitem->win.width, dlgitem->win.height); dlg->x11->Flush(dlg->x11); #endif if (dlgitem->win.self) { - XResizeWindow(dlg->x11->disp, dlgitem->win.self, dlgitem->win.width, - dlgitem->win.height); + XResizeWindow(dlg->x11->disp, dlgitem->win.self, dlgitem->win.width, dlgitem->win.height); } if ((w) && (dlgitem->type == edlgGB)) { @@ -196,10 +194,10 @@ bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h) t_id id = dlgitem->ID; for (i = 0; (i < dlg->nitem); i++) { - t_dlgitem *child = dlg->dlgitem[i]; + t_dlgitem* child = dlg->dlgitem[i]; if ((child->GroupID == gid) && (child->ID != id)) { - SetDlgItemSize(dlg, child->ID, w-4*OFFS_X, 0); + SetDlgItemSize(dlg, child->ID, w - 4 * OFFS_X, 0); } } } @@ -208,9 +206,9 @@ bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h) return false; } -bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0) +bool SetDlgItemPos(t_dlg* dlg, t_id id, int x0, int y0) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; int old_x, old_y; if ((dlgitem = FindItem(dlg, id)) != nullptr) @@ -220,8 +218,7 @@ bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0) dlgitem->win.x = x0; dlgitem->win.y = y0; #ifdef DEBUG - std::fprintf(dlg->x11->console, - "Move window from: %d,%d to %d,%d\n", old_x, old_y, x0, y0); + std::fprintf(dlg->x11->console, "Move window from: %d,%d to %d,%d\n", old_x, old_y, x0, y0); dlg->x11->Flush(dlg->x11); #endif if (dlgitem->win.self) @@ -233,14 +230,14 @@ bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0) int i, x, y; t_id gid = dlgitem->GroupID; t_id id = dlgitem->ID; - x = dlgitem->win.x+2*OFFS_X-old_x; - y = dlgitem->win.y+2*OFFS_Y-old_y; + x = dlgitem->win.x + 2 * OFFS_X - old_x; + y = dlgitem->win.y + 2 * OFFS_Y - old_y; for (i = 0; (i < dlg->nitem); i++) { - t_dlgitem *child = dlg->dlgitem[i]; + t_dlgitem* child = dlg->dlgitem[i]; if ((child->GroupID == gid) && (child->ID != id)) { - SetDlgItemPos(dlg, child->ID, child->win.x+x, child->win.y+y); + SetDlgItemPos(dlg, child->ID, child->win.x + x, child->win.y + y); } } } @@ -255,9 +252,9 @@ bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0) * after dlg is exec'ed * ****************************/ -bool IsCBChecked(t_dlg *dlg, t_id id) +bool IsCBChecked(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -270,15 +267,14 @@ bool IsCBChecked(t_dlg *dlg, t_id id) return false; } -t_id RBSelected(t_dlg *dlg, int gid) +t_id RBSelected(t_dlg* dlg, int gid) { int i; for (i = 0; (i < dlg->nitem); i++) { - if ((dlg->dlgitem[i]->type == edlgRB) && - (dlg->dlgitem[i]->u.radiobutton.bSelect) && - (dlg->dlgitem[i]->GroupID == gid)) + if ((dlg->dlgitem[i]->type == edlgRB) && (dlg->dlgitem[i]->u.radiobutton.bSelect) + && (dlg->dlgitem[i]->GroupID == gid)) { return dlg->dlgitem[i]->ID; } @@ -287,9 +283,9 @@ t_id RBSelected(t_dlg *dlg, int gid) return -1; } -int EditTextLen(t_dlg *dlg, t_id id) +int EditTextLen(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -302,9 +298,9 @@ int EditTextLen(t_dlg *dlg, t_id id) return 0; } -char *EditText(t_dlg *dlg, t_id id) +char* EditText(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindItem(dlg, id)) != nullptr) { @@ -324,10 +320,10 @@ char *EditText(t_dlg *dlg, t_id id) * return value is the ID of the button * ****************************/ -void ShowDlg(t_dlg *dlg) +void ShowDlg(t_dlg* dlg) { int i; - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; XMapWindow(dlg->x11->disp, dlg->win.self); XMapSubwindows(dlg->x11->disp, dlg->win.self); @@ -339,11 +335,9 @@ void ShowDlg(t_dlg *dlg) for (i = 0; (i < dlg->nitem); i++) { dlgitem = dlg->dlgitem[i]; - if ((dlgitem->type == edlgBN) && - (dlgitem->u.button.bDefault)) + if ((dlgitem->type == edlgBN) && (dlgitem->u.button.bDefault)) { - PushMouse(dlg->x11->disp, dlgitem->win.self, - dlgitem->win.width/2, dlgitem->win.height/2); + PushMouse(dlg->x11->disp, dlgitem->win.self, dlgitem->win.width / 2, dlgitem->win.height / 2); dlg->bPop = true; break; } @@ -351,7 +345,7 @@ void ShowDlg(t_dlg *dlg) dlg->bGrab = false; } -void HideDlg(t_dlg *dlg) +void HideDlg(t_dlg* dlg) { if (dlg->bPop) { @@ -362,33 +356,27 @@ void HideDlg(t_dlg *dlg) XUnmapWindow(dlg->x11->disp, dlg->win.self); } -void NoHelp(t_dlg *dlg) +void NoHelp(t_dlg* dlg) { - const char *lines[2] = { - "Error", - "No help for this item" - }; - MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines, - MB_OK | MB_ICONSTOP | MB_APPLMODAL, nullptr, nullptr); + const char* lines[2] = { "Error", "No help for this item" }; + MessageBox(dlg->x11, dlg->wDad, "No Help", 2, lines, MB_OK | MB_ICONSTOP | MB_APPLMODAL, + nullptr, nullptr); } -void HelpDlg(t_dlg *dlg) +void HelpDlg(t_dlg* dlg) { - const char *lines[] = { - "Place the cursor over one of the items", - "and press the F1 key to get more help.", - "First press the OK button." - }; - MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox", - 3, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr); + const char* lines[] = { "Place the cursor over one of the items", + "and press the F1 key to get more help.", "First press the OK button." }; + MessageBox(dlg->x11, dlg->win.self, "Help Dialogbox", 3, lines, + MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr); } -void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem) +void HelpNow(t_dlg* dlg, t_dlgitem* dlgitem) { - char buf[80]; - bool bCont = true; - int i, nlines = 0; - char **lines = nullptr; + char buf[80]; + bool bCont = true; + int i, nlines = 0; + char** lines = nullptr; if (!dlgitem->help) { @@ -424,13 +412,11 @@ void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem) if (bCont) { srenew(lines, ++nlines); - lines[nlines-1] = gmx_strdup(buf); + lines[nlines - 1] = gmx_strdup(buf); } } - } - while (bCont); - MessageBox(dlg->x11, dlg->wDad, "Help", - nlines, lines, + } while (bCont); + MessageBox(dlg->x11, dlg->wDad, "Help", nlines, lines, MB_OK | MB_ICONINFORMATION | MB_APPLMODAL, nullptr, nullptr); for (i = 0; (i < nlines); i++) { @@ -439,19 +425,18 @@ void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem) sfree(lines); } -static void EnterDlg(t_dlg *dlg) +static void EnterDlg(t_dlg* dlg) { if (dlg->flags & DLG_APPLMODAL) { dlg->bGrab = GrabOK(dlg->x11->console, - XGrabPointer(dlg->x11->disp, dlg->win.self, - True, 0, GrabModeAsync, GrabModeAsync, - dlg->win.self, None, CurrentTime)); + XGrabPointer(dlg->x11->disp, dlg->win.self, True, 0, GrabModeAsync, + GrabModeAsync, dlg->win.self, None, CurrentTime)); } dlg->x11->Flush(dlg->x11); } -static void ExitDlg(t_dlg *dlg) +static void ExitDlg(t_dlg* dlg) { if (dlg->bGrab) { @@ -465,18 +450,17 @@ static void ExitDlg(t_dlg *dlg) } } -static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) +static bool DlgCB(t_x11* x11, XEvent* event, Window w, void* data) { - t_dlg *dlg = (t_dlg *)data; + t_dlg* dlg = (t_dlg*)data; int i, nWndProc; - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; if ((dlgitem = FindWin(dlg, w)) != nullptr) { nWndProc = (dlgitem->WndProc)(x11, dlgitem, event); #ifdef DEBUG - std::fprintf(x11->console, - "window: %s, nWndProc: %d\n", dlgitem->win.text, nWndProc); + std::fprintf(x11->console, "window: %s, nWndProc: %d\n", dlgitem->win.text, nWndProc); x11->Flush(x11); #endif switch (nWndProc) @@ -497,12 +481,10 @@ static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) { for (i = 0; (i < dlg->nitem); i++) { - if ((dlg->dlgitem[i]->type == edlgBN) && - (dlg->dlgitem[i]->u.button.bDefault)) + if ((dlg->dlgitem[i]->type == edlgBN) && (dlg->dlgitem[i]->u.button.bDefault)) { PushMouse(x11->disp, dlg->dlgitem[i]->win.self, - dlg->dlgitem[i]->win.width/2, - dlg->dlgitem[i]->win.height/2); + dlg->dlgitem[i]->win.width / 2, dlg->dlgitem[i]->win.height / 2); break; } } @@ -527,7 +509,7 @@ static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) #endif if (tid != -1) { - t_dlgitem *dit = FindItem(dlg, tid); + t_dlgitem* dit = FindItem(dlg, tid); dit->u.radiobutton.bSelect = false; ExposeWin(x11->disp, dit->win.self); } @@ -557,22 +539,16 @@ static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) dlg->cb(x11, DLG_SET, dlgitem->ID, dlgitem->u.edittext.buf, dlg->data); } break; - case HELPPRESSED: - HelpNow(dlg, dlgitem); - break; - case ITEMOK: - break; - default: - gmx_fatal(FARGS, "Invalid return code (%d) from wndproc\n", nWndProc); + case HELPPRESSED: HelpNow(dlg, dlgitem); break; + case ITEMOK: break; + default: gmx_fatal(FARGS, "Invalid return code (%d) from wndproc\n", nWndProc); } } else if (w == dlg->win.self) { switch (event->type) { - case Expose: - EnterDlg(dlg); - break; + case Expose: EnterDlg(dlg); break; case ButtonPress: case KeyPress: if (HelpPressed(event)) @@ -584,8 +560,7 @@ static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) XBell(x11->disp, 50); } break; - default: - break; + default: break; } } return false; @@ -598,7 +573,7 @@ static bool DlgCB(t_x11 *x11, XEvent *event, Window w, void *data) * the item itself may not be freed until the dlg is done with * ****************************/ -static void DoCreateDlg(t_dlg *dlg) +static void DoCreateDlg(t_dlg* dlg) { XSizeHints hints; XSetWindowAttributes attr; @@ -609,18 +584,12 @@ static void DoCreateDlg(t_dlg *dlg) attr.override_redirect = False; attr.save_under = True; attr.cursor = XCreateFontCursor(dlg->x11->disp, XC_hand2); - Val = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | - CWCursor; - dlg->win.self = XCreateWindow(dlg->x11->disp, dlg->wDad, - dlg->win.x, dlg->win.y, - dlg->win.width, dlg->win.height, - dlg->win.bwidth, CopyFromParent, - InputOutput, CopyFromParent, - Val, &attr); - dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad, - DlgCB, dlg); - dlg->x11->SetInputMask(dlg->x11, dlg->win.self, - ExposureMask | ButtonPressMask | KeyPressMask); + Val = CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWSaveUnder | CWCursor; + dlg->win.self = XCreateWindow(dlg->x11->disp, dlg->wDad, dlg->win.x, dlg->win.y, dlg->win.width, + dlg->win.height, dlg->win.bwidth, CopyFromParent, InputOutput, + CopyFromParent, Val, &attr); + dlg->x11->RegisterCallback(dlg->x11, dlg->win.self, dlg->wDad, DlgCB, dlg); + dlg->x11->SetInputMask(dlg->x11, dlg->win.self, ExposureMask | ButtonPressMask | KeyPressMask); if (!CheckWindow(dlg->win.self)) { @@ -629,11 +598,10 @@ static void DoCreateDlg(t_dlg *dlg) hints.x = dlg->win.x; hints.y = dlg->win.y; hints.flags = PPosition; - XSetStandardProperties(dlg->x11->disp, dlg->win.self, dlg->title, - dlg->title, None, nullptr, 0, &hints); + XSetStandardProperties(dlg->x11->disp, dlg->win.self, dlg->title, dlg->title, None, nullptr, 0, &hints); } -void AddDlgItem(t_dlg *dlg, t_dlgitem *item) +void AddDlgItem(t_dlg* dlg, t_dlgitem* item) { #define EnterLeaveMask (EnterWindowMask | LeaveWindowMask) #define UserMask (ButtonPressMask | KeyPressMask) @@ -651,19 +619,17 @@ void AddDlgItem(t_dlg *dlg, t_dlgitem *item) { DoCreateDlg(dlg); } - srenew(dlg->dlgitem, dlg->nitem+1); + srenew(dlg->dlgitem, dlg->nitem + 1); if (!item) { gmx_fatal(FARGS, "dlgitem not allocated"); } - item->win.self = - XCreateSimpleWindow(dlg->x11->disp, dlg->win.self, item->win.x, item->win.y, - item->win.width, item->win.height, - item->win.bwidth, dlg->x11->fg, dlg->x11->bg); + item->win.self = XCreateSimpleWindow(dlg->x11->disp, dlg->win.self, item->win.x, item->win.y, + item->win.width, item->win.height, item->win.bwidth, + dlg->x11->fg, dlg->x11->bg); CheckWindow(item->win.self); - dlg->x11->RegisterCallback(dlg->x11, item->win.self, dlg->win.self, - DlgCB, dlg); + dlg->x11->RegisterCallback(dlg->x11, item->win.self, dlg->win.self, DlgCB, dlg); dlg->x11->SetInputMask(dlg->x11, item->win.self, InputMask[item->type]); switch (item->type) @@ -671,32 +637,30 @@ void AddDlgItem(t_dlg *dlg, t_dlgitem *item) case edlgPM: XSetWindowBackgroundPixmap(dlg->x11->disp, item->win.self, item->u.pixmap.pm); break; - default: - break; + default: break; } dlg->dlgitem[dlg->nitem] = item; dlg->nitem++; } -void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[]) +void AddDlgItems(t_dlg* dlg, int nitem, t_dlgitem* item[]) { int i; for (i = 0; (i < nitem); i++) { #ifdef DEBUG - std::fprintf(dlg->x11->console, - "Adding item: %d from group %d\n", item[i]->ID, item[i]->GroupID); + std::fprintf(dlg->x11->console, "Adding item: %d from group %d\n", item[i]->ID, item[i]->GroupID); dlg->x11->Flush(dlg->x11); #endif AddDlgItem(dlg, item[i]); } } -void FreeDlgItem(t_dlg *dlg, t_id id) +void FreeDlgItem(t_dlg* dlg, t_id id) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; int i; if ((dlgitem = FindItem(dlg, id)) != nullptr) @@ -710,16 +674,10 @@ void FreeDlgItem(t_dlg *dlg, t_id id) switch (dlgitem->type) { case edlgBN: - case edlgRB: - break; - case edlgGB: - sfree(dlgitem->u.groupbox.item); - break; - case edlgCB: - break; - case edlgPM: - XFreePixmap(dlg->x11->disp, dlgitem->u.pixmap.pm); - break; + case edlgRB: break; + case edlgGB: sfree(dlgitem->u.groupbox.item); break; + case edlgCB: break; + case edlgPM: XFreePixmap(dlg->x11->disp, dlgitem->u.pixmap.pm); break; case edlgST: for (i = 0; (i < dlgitem->u.statictext.nlines); i++) { @@ -727,16 +685,13 @@ void FreeDlgItem(t_dlg *dlg, t_id id) } sfree(dlgitem->u.statictext.lines); break; - case edlgET: - sfree(dlgitem->u.edittext.buf); - break; - default: - break; + case edlgET: sfree(dlgitem->u.edittext.buf); break; + default: break; } } } -void FreeDlg(t_dlg *dlg) +void FreeDlg(t_dlg* dlg) { int i; @@ -766,12 +721,10 @@ void FreeDlg(t_dlg *dlg) * Routine to create the DLG structure, returns NULL on failure * ****************************/ -t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title, - int x0, int y0, int w, int h, int bw, - DlgCallback *cb, void *data) +t_dlg* CreateDlg(t_x11* x11, Window Parent, const char* title, int x0, int y0, int w, int h, int bw, DlgCallback* cb, void* data) { - t_dlg *dlg; - int x = 0, y = 0; + t_dlg* dlg; + int x = 0, y = 0; snew(dlg, 1); dlg->x11 = x11; @@ -801,14 +754,12 @@ t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title, } else { - Window root; - unsigned int dum; + Window root; + unsigned int dum; - XGetGeometry(x11->disp, Parent, &root, &x, &y, - &(dlg->xmax), &(dlg->ymax), &dum, &dum); + XGetGeometry(x11->disp, Parent, &root, &x, &y, &(dlg->xmax), &(dlg->ymax), &dum, &dum); #ifdef DEBUG - std::fprintf(x11->console, - "Daddy is %d x %d at %d, %d\n", dlg->xmax, dlg->ymax, x, y); + std::fprintf(x11->console, "Daddy is %d x %d at %d, %d\n", dlg->xmax, dlg->ymax, x, y); dlg->x11->Flush(dlg->x11); #endif } @@ -833,14 +784,14 @@ t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title, return dlg; } -void SetDlgSize(t_dlg *dlg, int w, int h, bool bAutoPosition) +void SetDlgSize(t_dlg* dlg, int w, int h, bool bAutoPosition) { if (bAutoPosition) { int x, y; - x = (dlg->xmax-w)/2; - y = (dlg->ymax-h)/2; + x = (dlg->xmax - w) / 2; + y = (dlg->ymax - h) / 2; dlg->win.x = x; dlg->win.y = y; } @@ -848,8 +799,8 @@ void SetDlgSize(t_dlg *dlg, int w, int h, bool bAutoPosition) dlg->win.height = h; #ifdef DEBUG - std::fprintf(dlg->x11->console, "SetDlgSize: Dialog is %dx%d, at %d,%d\n", - dlg->win.width, dlg->win.height, dlg->win.x, dlg->win.y); + std::fprintf(dlg->x11->console, "SetDlgSize: Dialog is %dx%d, at %d,%d\n", dlg->win.width, + dlg->win.height, dlg->win.x, dlg->win.y); dlg->x11->Flush(dlg->x11); #endif if (dlg->win.self) diff --git a/src/programs/view/xdlg.h b/src/programs/view/xdlg.h index 7700ec47ff..477abc4ae7 100644 --- a/src/programs/view/xdlg.h +++ b/src/programs/view/xdlg.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013, by the GROMACS development team, led by + * Copyright (c) 2013,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -40,39 +40,41 @@ #include "xdlgitem.h" -#define DLG_SHOW (1<<0) -#define DLG_HIDE (1<<1) -#define DLG_SHOWANDHIDE (DLG_SHOW | DLG_HIDE) -#define DLG_SYSTEMMODAL (1<<2) -#define DLG_APPLMODAL (1<<3) -#define DLG_HIDEONBUTTON (1<<4) -#define DLG_FREEONBUTTON (1<<5) - -enum { - DLG_SET, DLG_EXIT +#define DLG_SHOW (1 << 0) +#define DLG_HIDE (1 << 1) +#define DLG_SHOWANDHIDE (DLG_SHOW | DLG_HIDE) +#define DLG_SYSTEMMODAL (1 << 2) +#define DLG_APPLMODAL (1 << 3) +#define DLG_HIDEONBUTTON (1 << 4) +#define DLG_FREEONBUTTON (1 << 5) + +enum +{ + DLG_SET, + DLG_EXIT }; -typedef void DlgCallback (t_x11 *x11, int dlg_mess, int item_id, - char *set, void *data); +typedef void DlgCallback(t_x11* x11, int dlg_mess, int item_id, char* set, void* data); /* User function that can be called by the dialog box. All setting of * check-boxes and radio-buttons etc., is done by the dialog manager, * the user can let himself be informed about mouse activity also. */ -typedef struct { - t_x11 *x11; /* All about X */ - t_windata win; /* The position and size of the window */ - char *title; /* Window name */ - Window wDad; /* The parent window */ - unsigned int xmax, ymax; /* Dimensions of parent window */ - unsigned long flags; /* Flags for display */ - unsigned long fg, bg; /* The colours */ - bool bPop; /* Should we pop the mouse back */ - bool bGrab; /* Have we grabbed the mouse ? */ - int nitem; /* The number of items */ - t_dlgitem **dlgitem; /* The array of item pointers */ - DlgCallback *cb; /* User call back function */ - void *data; /* User data */ +typedef struct +{ + t_x11* x11; /* All about X */ + t_windata win; /* The position and size of the window */ + char* title; /* Window name */ + Window wDad; /* The parent window */ + unsigned int xmax, ymax; /* Dimensions of parent window */ + unsigned long flags; /* Flags for display */ + unsigned long fg, bg; /* The colours */ + bool bPop; /* Should we pop the mouse back */ + bool bGrab; /* Have we grabbed the mouse ? */ + int nitem; /* The number of items */ + t_dlgitem** dlgitem; /* The array of item pointers */ + DlgCallback* cb; /* User call back function */ + void* data; /* User data */ } t_dlg; /***************************** @@ -81,9 +83,7 @@ typedef struct { * cb and data may be NULL. * ****************************/ -t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title, - int x0, int y0, int w, int h, int bw, - DlgCallback *cb, void *data); +t_dlg* CreateDlg(t_x11* x11, Window Parent, const char* title, int x0, int y0, int w, int h, int bw, DlgCallback* cb, void* data); /***************************** * @@ -92,9 +92,9 @@ t_dlg *CreateDlg(t_x11 *x11, Window Parent, const char *title, * the item itself may not be freed until the dlg is done with * ****************************/ -void AddDlgItem(t_dlg *dlg, t_dlgitem *item); +void AddDlgItem(t_dlg* dlg, t_dlgitem* item); -void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[]); +void AddDlgItems(t_dlg* dlg, int nitem, t_dlgitem* item[]); /***************************** * @@ -103,23 +103,23 @@ void AddDlgItems(t_dlg *dlg, int nitem, t_dlgitem *item[]); * false will mean most of the time, that item id was not found * ****************************/ -bool QueryDlgItemSize(t_dlg *dlg, t_id id, int *w, int *h); +bool QueryDlgItemSize(t_dlg* dlg, t_id id, int* w, int* h); -bool QueryDlgItemPos(t_dlg *dlg, t_id id, int *x0, int *y0); +bool QueryDlgItemPos(t_dlg* dlg, t_id id, int* x0, int* y0); -int QueryDlgItemX(t_dlg *dlg, t_id id); +int QueryDlgItemX(t_dlg* dlg, t_id id); -int QueryDlgItemY(t_dlg *dlg, t_id id); +int QueryDlgItemY(t_dlg* dlg, t_id id); -int QueryDlgItemW(t_dlg *dlg, t_id id); +int QueryDlgItemW(t_dlg* dlg, t_id id); -int QueryDlgItemH(t_dlg *dlg, t_id id); +int QueryDlgItemH(t_dlg* dlg, t_id id); -bool SetDlgItemSize(t_dlg *dlg, t_id id, int w, int h); +bool SetDlgItemSize(t_dlg* dlg, t_id id, int w, int h); -bool SetDlgItemPos(t_dlg *dlg, t_id id, int x0, int y0); +bool SetDlgItemPos(t_dlg* dlg, t_id id, int x0, int y0); -void SetDlgSize(t_dlg *dlg, int w, int h, bool bAutoPosition); +void SetDlgSize(t_dlg* dlg, int w, int h, bool bAutoPosition); /***************************** * @@ -127,28 +127,28 @@ void SetDlgSize(t_dlg *dlg, int w, int h, bool bAutoPosition); * after dlg is exec'ed * ****************************/ -bool IsCBChecked(t_dlg *dlg, t_id id); +bool IsCBChecked(t_dlg* dlg, t_id id); -t_id RBSelected(t_dlg *dlg, int gid); +t_id RBSelected(t_dlg* dlg, int gid); -int EditTextLen(t_dlg *dlg, t_id id); +int EditTextLen(t_dlg* dlg, t_id id); -char *EditText(t_dlg *dlg, t_id id); +char* EditText(t_dlg* dlg, t_id id); /***************************** * * Routines to do internal things * ****************************/ -t_dlgitem *FindWin(t_dlg *dlg, Window win); +t_dlgitem* FindWin(t_dlg* dlg, Window win); -t_dlgitem *FindItem(t_dlg *dlg, t_id id); +t_dlgitem* FindItem(t_dlg* dlg, t_id id); -void HelpDlg(t_dlg *dlg); +void HelpDlg(t_dlg* dlg); -void HelpNow(t_dlg *dlg, t_dlgitem *dlgitem); +void HelpNow(t_dlg* dlg, t_dlgitem* dlgitem); -void NoHelp(t_dlg *dlg); +void NoHelp(t_dlg* dlg); /***************************** * @@ -157,12 +157,12 @@ void NoHelp(t_dlg *dlg); * return value is the ID of the button * ****************************/ -void ShowDlg(t_dlg *dlg); +void ShowDlg(t_dlg* dlg); -void HideDlg(t_dlg *dlg); +void HideDlg(t_dlg* dlg); -void FreeDlgItem(t_dlg *dlg, t_id id); +void FreeDlgItem(t_dlg* dlg, t_id id); -void FreeDlg(t_dlg *dlg); +void FreeDlg(t_dlg* dlg); -#endif /* _xdlg_h */ +#endif /* _xdlg_h */ diff --git a/src/programs/view/xdlghi.cpp b/src/programs/view/xdlghi.cpp index 3cae52d971..a57a6c1e81 100644 --- a/src/programs/view/xdlghi.cpp +++ b/src/programs/view/xdlghi.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -51,10 +51,15 @@ #include "fgrid.h" #include "xutil.h" -t_dlgitem **CreateRadioButtonGroup(t_x11 *x11, char *szTitle, - t_id GroupID, int nrb, t_id rb[], - int nSelect, - char *szRB[], int x0, int y0) +t_dlgitem** CreateRadioButtonGroup(t_x11* x11, + char* szTitle, + t_id GroupID, + int nrb, + t_id rb[], + int nSelect, + char* szRB[], + int x0, + int y0) /* This routine creates a radio button group at the * specified position. The return values is a pointer to an * array of dlgitems, the array has length (nrb+1) with the +1 @@ -62,60 +67,57 @@ t_dlgitem **CreateRadioButtonGroup(t_x11 *x11, char *szTitle, * nSelect is the ordinal of the selected button. */ { - t_dlgitem **dlgitem; + t_dlgitem** dlgitem; int x, y, w; int i; - snew(dlgitem, nrb+1); + snew(dlgitem, nrb + 1); dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nrb, rb, x0, y0, 0, 0, 0); - x = x0+2*OFFS_X; - y = dlgitem[0]->win.y+dlgitem[0]->win.height; + x = x0 + 2 * OFFS_X; + y = dlgitem[0]->win.y + dlgitem[0]->win.height; w = 0; for (i = 0; (i < nrb); i++) { - dlgitem[i+1] = CreateRadioButton(x11, szRB[i], (i == nSelect), - rb[i], GroupID, x, y, 0, 0, 0); - y += dlgitem[i+1]->win.height+OFFS_Y; - w = std::max(w, dlgitem[i+1]->win.width); + dlgitem[i + 1] = CreateRadioButton(x11, szRB[i], (i == nSelect), rb[i], GroupID, x, y, 0, 0, 0); + y += dlgitem[i + 1]->win.height + OFFS_Y; + w = std::max(w, dlgitem[i + 1]->win.width); } for (i = 0; (i < nrb); i++) { - dlgitem[i+1]->win.width = w; + dlgitem[i + 1]->win.width = w; } - dlgitem[0]->win.width = w+4*OFFS_X; - dlgitem[0]->win.height = y-y0; + dlgitem[0]->win.width = w + 4 * OFFS_X; + dlgitem[0]->win.height = y - y0; return dlgitem; } -t_dlgitem **CreateDlgitemGroup(t_x11 *x11, const char *szTitle, - t_id GroupID, int x0, int y0, - int nitem, ...) +t_dlgitem** CreateDlgitemGroup(t_x11* x11, const char* szTitle, t_id GroupID, int x0, int y0, int nitem, ...) /* This routine creates a dlgitem group at the * specified position. The return values is a pointer to an * array of dlgitems, the array has length (nitem+1) with the +1 * because of the groupbox. */ { - va_list ap; - - t_dlgitem **dlgitem; - t_id *ids; - edlgitem edlg; - char *name; - bool bBool; - Pixmap pm; - int nlines, buflen; - char *buf, **lines; - int x, y, w, i; + va_list ap; + + t_dlgitem** dlgitem; + t_id* ids; + edlgitem edlg; + char* name; + bool bBool; + Pixmap pm; + int nlines, buflen; + char * buf, **lines; + int x, y, w, i; va_start(ap, nitem); - snew(dlgitem, nitem+1); + snew(dlgitem, nitem + 1); snew(ids, nitem); - x = x0+2*OFFS_X; + x = x0 + 2 * OFFS_X; dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nitem, ids, x0, y0, 0, 0, 0); - y = dlgitem[0]->win.y+dlgitem[0]->win.height; + y = dlgitem[0]->win.y + dlgitem[0]->win.height; w = 0; for (i = 0; (i < nitem); i++) { @@ -124,43 +126,40 @@ t_dlgitem **CreateDlgitemGroup(t_x11 *x11, const char *szTitle, switch (edlg) { case edlgBN: - name = va_arg(ap, char *); - bBool = va_arg(ap, int); - dlgitem[i+1] = CreateButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); + name = va_arg(ap, char*); + bBool = va_arg(ap, int); + dlgitem[i + 1] = CreateButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgRB: - name = va_arg(ap, char *); - bBool = va_arg(ap, int); - dlgitem[i+1] = CreateRadioButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); + name = va_arg(ap, char*); + bBool = va_arg(ap, int); + dlgitem[i + 1] = CreateRadioButton(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgCB: - name = va_arg(ap, char *); - bBool = va_arg(ap, int); - dlgitem[i+1] = CreateCheckBox(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); + name = va_arg(ap, char*); + bBool = va_arg(ap, int); + dlgitem[i + 1] = CreateCheckBox(x11, name, bBool, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgPM: - pm = va_arg(ap, Pixmap); - dlgitem[i+1] = CreatePixmap(pm, ids[i], GroupID, x, y, 0, 0, 0); + pm = va_arg(ap, Pixmap); + dlgitem[i + 1] = CreatePixmap(pm, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgST: - nlines = va_arg(ap, int); - lines = va_arg(ap, char **); - dlgitem[i+1] = CreateStaticText(x11, nlines, lines, ids[i], GroupID, - x, y, 0, 0, 0); + nlines = va_arg(ap, int); + lines = va_arg(ap, char**); + dlgitem[i + 1] = CreateStaticText(x11, nlines, lines, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgET: - name = va_arg(ap, char *); - buflen = va_arg(ap, int); - buf = va_arg(ap, char *); - dlgitem[i+1] = CreateEditText(x11, name, buflen, buf, ids[i], - GroupID, x, y, 0, 0, 0); + name = va_arg(ap, char*); + buflen = va_arg(ap, int); + buf = va_arg(ap, char*); + dlgitem[i + 1] = CreateEditText(x11, name, buflen, buf, ids[i], GroupID, x, y, 0, 0, 0); break; case edlgGB: - default: - gmx_fatal(FARGS, "Invalid dlgitem type: %d\n", edlg); + default: gmx_fatal(FARGS, "Invalid dlgitem type: %d\n", edlg); } - y += dlgitem[i+1]->win.height+OFFS_Y; - w = std::max(w, dlgitem[i+1]->win.width); + y += dlgitem[i + 1]->win.height + OFFS_Y; + w = std::max(w, dlgitem[i + 1]->win.width); } va_end(ap); sfree(dlgitem[0]->u.groupbox.item); @@ -168,17 +167,16 @@ t_dlgitem **CreateDlgitemGroup(t_x11 *x11, const char *szTitle, dlgitem[0] = CreateGroupBox(x11, szTitle, GroupID, nitem, ids, x0, y0, 0, 0, 0); for (i = 0; (i < nitem); i++) { - dlgitem[i+1]->win.width = w; + dlgitem[i + 1]->win.width = w; } - dlgitem[0]->win.width = w+4*OFFS_X; - dlgitem[0]->win.height = y-y0; + dlgitem[0]->win.width = w + 4 * OFFS_X; + dlgitem[0]->win.height = y - y0; return dlgitem; } -static void AddDlgItemGroups(t_dlg *dlg, int gridx, int gridy, - t_dlgitemlist **grid, bool bAutoPosition) +static void AddDlgItemGroups(t_dlg* dlg, int gridx, int gridy, t_dlgitemlist** grid, bool bAutoPosition) { - t_dlgitemlist *item; + t_dlgitemlist* item; int x1, y1, w1, h1; int x, y, dw, dh; float w, h; @@ -203,14 +201,14 @@ static void AddDlgItemGroups(t_dlg *dlg, int gridx, int gridy, AddDlgItems(dlg, item->nitem, item->list); dw = item->w; dh = item->h; - w = std::max(w, ((float) QueryDlgItemW(dlg, item->list[0]->ID))/dw); - h = std::max(h, ((float) QueryDlgItemH(dlg, item->list[0]->ID))/dh); + w = std::max(w, ((float)QueryDlgItemW(dlg, item->list[0]->ID)) / dw); + h = std::max(h, ((float)QueryDlgItemH(dlg, item->list[0]->ID)) / dh); } } } } - w1 = gridx*w; - h1 = gridy*h; + w1 = gridx * w; + h1 = gridy * h; SetDlgSize(dlg, w1, h1, bAutoPosition); #ifdef DEBUG std::printf("Dimensions of grid cell: %8.3f x %8.3f\n", w, h); @@ -224,10 +222,10 @@ static void AddDlgItemGroups(t_dlg *dlg, int gridx, int gridy, item = &(grid[x][y]); if (item->nitem) { - x1 = x*w; - y1 = y*h; - w1 = item->w*w; - h1 = item->h*h; + x1 = x * w; + y1 = y * h; + w1 = item->w * w; + h1 = item->h * h; #ifdef DEBUG std::printf("New size: %d x %d at %d, %d\n", w1, h1, x1, y1); #endif @@ -238,10 +236,10 @@ static void AddDlgItemGroups(t_dlg *dlg, int gridx, int gridy, } } -static t_dlgitemlist **NewDlgitemList(int w, int h) +static t_dlgitemlist** NewDlgitemList(int w, int h) { int i, j; - t_dlgitemlist **grid; + t_dlgitemlist** grid; snew(grid, w); for (i = 0; (i < w); i++) @@ -256,15 +254,14 @@ static t_dlgitemlist **NewDlgitemList(int w, int h) return grid; } -static void AddListItem(t_dlgitemlist *list, t_dlgitem *item) +static void AddListItem(t_dlgitemlist* list, t_dlgitem* item) { srenew(list->list, ++list->nitem); - list->list[list->nitem-1] = item; + list->list[list->nitem - 1] = item; } -static void AddListFItem(t_x11 *x11, t_dlgitemlist *list, - t_fitem *fitem, t_id GroupID, t_id *ID, - int x, int *y, int *w, bool bUseMon) +static void +AddListFItem(t_x11* x11, t_dlgitemlist* list, t_fitem* fitem, t_id GroupID, t_id* ID, int x, int* y, int* w, bool bUseMon) { int i, iSel, slen; char buf[STRLEN]; @@ -272,9 +269,8 @@ static void AddListFItem(t_x11 *x11, t_dlgitemlist *list, switch (fitem->edlg) { case edlgBN: - AddListItem - (list, CreateButton(x11, fitem->name[0], fitem->bDef, (*ID)++, GroupID, - x, (*y), 0, 0, 0)); + AddListItem(list, CreateButton(x11, fitem->name[0], fitem->bDef, (*ID)++, GroupID, x, + (*y), 0, 0, 0)); break; case edlgRB: std::strcpy(buf, fitem->def); @@ -293,13 +289,11 @@ static void AddListFItem(t_x11 *x11, t_dlgitemlist *list, for (i = 0; (i < fitem->nname); i++) { - AddListItem(list, - CreateRadioButton(x11, fitem->name[i], (iSel == i), - (*ID)++, GroupID, x, (*y), 0, 0, 0)); - (*y) += list->list[list->nitem-1]->win.height+OFFS_Y; - (*w) = std::max((*w), list->list[list->nitem-1]->win.width); - SetDlgitemOpts(list->list[list->nitem-1], bUseMon, - fitem->set, fitem->get, fitem->help); + AddListItem(list, CreateRadioButton(x11, fitem->name[i], (iSel == i), (*ID)++, + GroupID, x, (*y), 0, 0, 0)); + (*y) += list->list[list->nitem - 1]->win.height + OFFS_Y; + (*w) = std::max((*w), list->list[list->nitem - 1]->win.width); + SetDlgitemOpts(list->list[list->nitem - 1], bUseMon, fitem->set, fitem->get, fitem->help); } break; case edlgCB: @@ -307,76 +301,68 @@ static void AddListFItem(t_x11 *x11, t_dlgitemlist *list, bool bCheck; bCheck = gmx_strcasecmp(fitem->def, "TRUE") == 0; - AddListItem(list, CreateCheckBox(x11, fitem->name[0], bCheck, - (*ID)++, GroupID, x, (*y), 0, 0, 0)); + AddListItem(list, CreateCheckBox(x11, fitem->name[0], bCheck, (*ID)++, GroupID, x, (*y), + 0, 0, 0)); break; } case edlgST: - AddListItem(list, - CreateStaticText(x11, fitem->nname, - fitem->name, (*ID)++, - GroupID, x, (*y), 0, 0, 0)); + AddListItem(list, CreateStaticText(x11, fitem->nname, fitem->name, (*ID)++, GroupID, x, + (*y), 0, 0, 0)); break; case edlgET: - slen = std::strlen(fitem->name[0])+strlen(fitem->def); - AddListItem(list, CreateEditText(x11, fitem->name[0], slen, fitem->def, - (*ID)++, GroupID, x, (*y), 0, 0, 0)); + slen = std::strlen(fitem->name[0]) + strlen(fitem->def); + AddListItem(list, CreateEditText(x11, fitem->name[0], slen, fitem->def, (*ID)++, + GroupID, x, (*y), 0, 0, 0)); break; case edlgPM: case edlgGB: - default: - gmx_fatal(FARGS, "Invalid list->list type: %d\n", fitem->edlg); + default: gmx_fatal(FARGS, "Invalid list->list type: %d\n", fitem->edlg); } - SetDlgitemOpts(list->list[list->nitem-1], bUseMon, - fitem->set, fitem->get, fitem->help); + SetDlgitemOpts(list->list[list->nitem - 1], bUseMon, fitem->set, fitem->get, fitem->help); if (fitem->edlg != edlgRB) { - (*y) += list->list[list->nitem-1]->win.height+OFFS_Y; - (*w) = std::max((*w), list->list[list->nitem-1]->win.width); + (*y) += list->list[list->nitem - 1]->win.height + OFFS_Y; + (*w) = std::max((*w), list->list[list->nitem - 1]->win.width); } } -static void AddListFGroup(t_x11 *x11, t_dlgitemlist **grid, - t_fgroup *fgroup, t_id *ID, bool bUseMon) +static void AddListFGroup(t_x11* x11, t_dlgitemlist** grid, t_fgroup* fgroup, t_id* ID, bool bUseMon) { int i; t_id GroupID, *ids; - t_dlgitemlist *item; + t_dlgitemlist* item; int x, y, w; GroupID = (*ID)++; item = &(grid[fgroup->x][fgroup->y]); - AddListItem(item, CreateGroupBox(x11, fgroup->name, GroupID, - 0, nullptr, 0, 0, 0, 0, 0)); - x = 2*OFFS_X; - y = item->list[0]->win.y+item->list[0]->win.height; + AddListItem(item, CreateGroupBox(x11, fgroup->name, GroupID, 0, nullptr, 0, 0, 0, 0, 0)); + x = 2 * OFFS_X; + y = item->list[0]->win.y + item->list[0]->win.height; w = 0; for (i = 0; (i < fgroup->nfitem); i++) { AddListFItem(x11, item, fgroup->fitem[i], GroupID, ID, x, &y, &w, bUseMon); } - w = std::max(w, item->list[0]->win.width+4*OFFS_X); + w = std::max(w, item->list[0]->win.width + 4 * OFFS_X); sfree(item->list[0]->u.groupbox.item); sfree(item->list[0]->win.text); snew(ids, item->nitem); - for (i = 0; (i < item->nitem-1); i++) + for (i = 0; (i < item->nitem - 1); i++) { - ids[i] = GroupID+i+1; + ids[i] = GroupID + i + 1; } - item->list[0] = - CreateGroupBox(x11, fgroup->name, GroupID, item->nitem-1, ids, - 2*OFFS_X, 2*OFFS_Y, w+2*OFFS_X, y, 0); + item->list[0] = CreateGroupBox(x11, fgroup->name, GroupID, item->nitem - 1, ids, 2 * OFFS_X, + 2 * OFFS_Y, w + 2 * OFFS_X, y, 0); sfree(ids); item->w = fgroup->w; item->h = fgroup->h; } -static void AddListFSimple(t_x11 *x11, t_dlgitemlist **grid, - t_fsimple *fsimple, t_id *ID, bool bUseMon) +static void AddListFSimple(t_x11* x11, t_dlgitemlist** grid, t_fsimple* fsimple, t_id* ID, bool bUseMon) { - t_dlgitemlist *item; + t_dlgitemlist* item; int x, y, w; item = &(grid[fsimple->x][fsimple->y]); @@ -388,14 +374,20 @@ static void AddListFSimple(t_x11 *x11, t_dlgitemlist **grid, item->h = fsimple->h; } -t_dlg *ReadDlg(t_x11 *x11, Window Parent, const char *title, - const char *infile, - int x0, int y0, bool bAutoPosition, bool bUseMon, - DlgCallback *cb, void *data) +t_dlg* ReadDlg(t_x11* x11, + Window Parent, + const char* title, + const char* infile, + int x0, + int y0, + bool bAutoPosition, + bool bUseMon, + DlgCallback* cb, + void* data) { - t_fgrid *fgrid; - t_dlgitemlist **grid; - t_dlg *dlg; + t_fgrid* fgrid; + t_dlgitemlist** grid; + t_dlg* dlg; int i; t_id ID; diff --git a/src/programs/view/xdlghi.h b/src/programs/view/xdlghi.h index d97764842a..5d0c24fdc0 100644 --- a/src/programs/view/xdlghi.h +++ b/src/programs/view/xdlghi.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -44,16 +44,22 @@ #include "x11.h" #include "xdlg.h" -typedef struct { +typedef struct +{ int nitem; int w, h; - t_dlgitem **list; + t_dlgitem** list; } t_dlgitemlist; -extern t_dlgitem **CreateRadioButtonGroup(t_x11 *x11, char *szTitle, - t_id GroupID, int nrb, t_id rb[], - int nSelect, - char *szRB[], int x0, int y0); +extern t_dlgitem** CreateRadioButtonGroup(t_x11* x11, + char* szTitle, + t_id GroupID, + int nrb, + t_id rb[], + int nSelect, + char* szRB[], + int x0, + int y0); /* This routine creates a radio button group at the * specified position. The return values is a pointer to an * array of dlgitems, the array has length (nrb+1) with the +1 @@ -61,19 +67,24 @@ extern t_dlgitem **CreateRadioButtonGroup(t_x11 *x11, char *szTitle, * nSelect is the ordinal of the selected button. */ -extern t_dlgitem **CreateDlgitemGroup(t_x11 *x11, const char *szTitle, - t_id GroupID, int x0, int y0, - int nitem, ...); +extern t_dlgitem** +CreateDlgitemGroup(t_x11* x11, const char* szTitle, t_id GroupID, int x0, int y0, int nitem, ...); /* This routine creates a dlgitem group at the * specified position. The return values is a pointer to an * array of dlgitems, the array has length (nitem+1) with the +1 * because of the groupbox. */ -extern t_dlg *ReadDlg(t_x11 *x11, Window Parent, const char *title, - const char *infile, - int x0, int y0, bool bAutoPosition, bool bUseMon, - DlgCallback *cb, void *data); +extern t_dlg* ReadDlg(t_x11* x11, + Window Parent, + const char* title, + const char* infile, + int x0, + int y0, + bool bAutoPosition, + bool bUseMon, + DlgCallback* cb, + void* data); /* Read a dialog box from a template file */ -#endif /* _xdlghi_h */ +#endif /* _xdlghi_h */ diff --git a/src/programs/view/xdlgitem.cpp b/src/programs/view/xdlgitem.cpp index cf75e603cd..3bd79a29c8 100644 --- a/src/programs/view/xdlgitem.cpp +++ b/src/programs/view/xdlgitem.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,9 +52,9 @@ #define BUFSIZE 16 -static t_dlgitem *newitem(void) +static t_dlgitem* newitem(void) { - t_dlgitem *item; + t_dlgitem* item; snew(item, 1); @@ -66,38 +66,38 @@ static t_dlgitem *newitem(void) * Window Procedures and helpful functions * ****************************/ -static void ShowCaret(t_x11 *x11, t_dlgitem *dlgitem) +static void ShowCaret(t_x11* x11, t_dlgitem* dlgitem) { - t_edittext *et; + t_edittext* et; if (dlgitem->type == edlgET) { int x, y1, y2; et = &(dlgitem->u.edittext); - x = XTextWidth(x11->font, dlgitem->win.text, std::strlen(dlgitem->win.text))+XCARET+ - XTextWidth(x11->font, (char*) &(et->buf[et->strbegin]), et->pos); - y1 = (dlgitem->win.height-XTextHeight(x11->font))/2; - y2 = (dlgitem->win.height-y1); + x = XTextWidth(x11->font, dlgitem->win.text, std::strlen(dlgitem->win.text)) + XCARET + + XTextWidth(x11->font, (char*)&(et->buf[et->strbegin]), et->pos); + y1 = (dlgitem->win.height - XTextHeight(x11->font)) / 2; + y2 = (dlgitem->win.height - y1); y1--, y2++; - XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y1, x+XCARET, y1); + XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x - XCARET, y1, x + XCARET, y1); XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x, y1, x, y2); - XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y2, x+XCARET, y2); + XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x - XCARET, y2, x + XCARET, y2); } } -static void HideCaret(t_x11 *x11, t_dlgitem *dlgitem) +static void HideCaret(t_x11* x11, t_dlgitem* dlgitem) { XSetForeground(x11->disp, x11->gc, x11->bg); ShowCaret(x11, dlgitem); XSetForeground(x11->disp, x11->gc, x11->fg); } -static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int DefWndProc(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { XComposeStatus status; KeySym keysym; - char c[BUFSIZE+1]; + char c[BUFSIZE + 1]; #ifdef DEBUG std::printf("DefWndProc\n"); @@ -130,15 +130,14 @@ static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) HideCaret(x11, dlgitem); /* LightBorder(x11->disp,dlgitem->win.self,x11->bg); */ break; - default: - XBell(x11->disp, 50); + default: XBell(x11->disp, 50); } return ITEMOK; } -static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcBN(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_windata *win; + t_windata* win; int x, w, th; if (dlgitem->type != edlgBN) @@ -147,34 +146,30 @@ static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) } win = &(dlgitem->win); w = XTextWidth(x11->font, win->text, std::strlen(win->text)); - x = (win->width-w)/2; - th = XTextHeight(x11->font)+OFFS_Y; + x = (win->width - w) / 2; + th = XTextHeight(x11->font) + OFFS_Y; switch (event->type) { case Expose: RectWin(x11->disp, x11->gc, win, x11->fg); TextInRect(x11, win->self, win->text, 0, 0, win->width, th, eXCenter, eYCenter); break; - case ButtonPress: - return BNPRESSED; - case EnterNotify: - XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th); - break; + case ButtonPress: return BNPRESSED; + case EnterNotify: XDrawLine(x11->disp, win->self, x11->gc, x - 1, th, x + w, th); break; case LeaveNotify: XSetForeground(x11->disp, x11->gc, x11->bg); - XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th); + XDrawLine(x11->disp, win->self, x11->gc, x - 1, th, x + w, th); XSetForeground(x11->disp, x11->gc, x11->fg); break; - default: - return DefWndProc(x11, dlgitem, event); + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } -static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcRB(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_radiobutton *rb; - t_windata *win; + t_radiobutton* rb; + t_windata* win; int x, y, rad; if (dlgitem->type != edlgRB) @@ -184,22 +179,21 @@ static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) rb = &(dlgitem->u.radiobutton); win = &(dlgitem->win); - rad = win->height/3; + rad = win->height / 3; x = rad; - y = win->height/2; + y = win->height / 2; switch (event->type) { case Expose: - XClearArea(x11->disp, win->self, x-rad, y-rad, x+rad, y+rad, False); + XClearArea(x11->disp, win->self, x - rad, y - rad, x + rad, y + rad, False); if (rb->bSelect) { /* Filled */ XFillCircle(x11->disp, win->self, x11->gc, x, y, rad); } XDrawCircle(x11->disp, win->self, x11->gc, x, y, rad); - x += rad+OFFS_X; - TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height, - eXLeft, eYCenter); + x += rad + OFFS_X; + TextInRect(x11, win->self, win->text, x, 0, win->width - x, win->height, eXLeft, eYCenter); break; case ButtonPress: if (!rb->bSelect) @@ -209,17 +203,15 @@ static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) XBell(x11->disp, 50); break; case EnterNotify: - case LeaveNotify: - break; - default: - return DefWndProc(x11, dlgitem, event); + case LeaveNotify: break; + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } -static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcGB(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_windata *win; + t_windata* win; int x, y; if (dlgitem->type != edlgGB) @@ -234,24 +226,22 @@ static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) { case Expose: XSetForeground(x11->disp, x11->gc, x11->fg); - XDrawRoundRect(x11->disp, win->self, x11->gc, 0, y/2, - win->width-1, win->height-y/2-1); - XClearArea(x11->disp, win->self, OFFS_X, 0, x+OFFS_X, y, False); - TextInRect(x11, win->self, win->text, 2*OFFS_X, 0, x, y, eXCenter, eYCenter); + XDrawRoundRect(x11->disp, win->self, x11->gc, 0, y / 2, win->width - 1, + win->height - y / 2 - 1); + XClearArea(x11->disp, win->self, OFFS_X, 0, x + OFFS_X, y, False); + TextInRect(x11, win->self, win->text, 2 * OFFS_X, 0, x, y, eXCenter, eYCenter); break; case EnterNotify: - case LeaveNotify: - break; - default: - return DefWndProc(x11, dlgitem, event); + case LeaveNotify: break; + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } -static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcCB(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_checkbox *cb; - t_windata *win; + t_checkbox* cb; + t_windata* win; int x, y, w, h; if (dlgitem->type != edlgCB) @@ -262,9 +252,9 @@ static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) win = &(dlgitem->win); x = 0; - y = win->height/7; - w = 5*y; - h = 5*y; + y = win->height / 7; + w = 5 * y; + h = 5 * y; switch (event->type) { case Expose: @@ -273,29 +263,24 @@ static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) XDrawRectangle(x11->disp, win->self, x11->gc, x, y, w, h); if (cb->bChecked) { - XDrawLine(x11->disp, win->self, x11->gc, x, y, x+w, y+h); - XDrawLine(x11->disp, win->self, x11->gc, x+w, y, x, y+h); + XDrawLine(x11->disp, win->self, x11->gc, x, y, x + w, y + h); + XDrawLine(x11->disp, win->self, x11->gc, x + w, y, x, y + h); } - x = w+OFFS_X; - TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height, - eXLeft, eYCenter); + x = w + OFFS_X; + TextInRect(x11, win->self, win->text, x, 0, win->width - x, win->height, eXLeft, eYCenter); break; - case ButtonPress: - cb->bChecked = !cb->bChecked; - return CBPRESSED; + case ButtonPress: cb->bChecked = !cb->bChecked; return CBPRESSED; case EnterNotify: - case LeaveNotify: - break; - default: - return DefWndProc(x11, dlgitem, event); + case LeaveNotify: break; + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } -static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcST(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_statictext *st; - t_windata *win; + t_statictext* st; + t_windata* win; int i, dy; if (dlgitem->type != edlgST) @@ -308,20 +293,19 @@ static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) switch (event->type) { case Expose: - dy = XTextHeight(x11->font)+OFFS_Y; + dy = XTextHeight(x11->font) + OFFS_Y; for (i = 0; (i < st->nlines); i++) { - TextInRect(x11, win->self, st->lines[i], - 0, OFFS_Y+i*dy, win->width, dy, eXLeft, eYCenter); + TextInRect(x11, win->self, st->lines[i], 0, OFFS_Y + i * dy, win->width, dy, eXLeft, + eYCenter); } break; - default: - return DefWndProc(x11, dlgitem, event); + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } -static bool insert(char *s, char c, int *pos) +static bool insert(char* s, char c, int* pos) { int i, sl; @@ -329,9 +313,9 @@ static bool insert(char *s, char c, int *pos) { sl = std::strlen(s); /* +1 for zero termination */ - for (i = sl+1; (i > *pos); i--) + for (i = sl + 1; (i > *pos); i--) { - s[i+1] = s[i]; + s[i + 1] = s[i]; } s[*pos] = c; (*pos)++; @@ -340,24 +324,24 @@ static bool insert(char *s, char c, int *pos) return false; } -static bool my_backspace(char *s, int *pos) +static bool my_backspace(char* s, int* pos) { int i, sl; sl = std::strlen(s); if ((sl > 0) && ((*pos) > 0)) { - for (i = *pos-1; (i < sl); i++) + for (i = *pos - 1; (i < sl); i++) { - s[i] = s[i+1]; + s[i] = s[i + 1]; } - (*pos) = std::max(0, (*pos)-1); + (*pos) = std::max(0, (*pos) - 1); return true; } return false; } -static bool my_delete(char *s, int *pos) +static bool my_delete(char* s, int* pos) { int i, sl; @@ -366,22 +350,22 @@ static bool my_delete(char *s, int *pos) { for (i = *pos; (i < sl); i++) { - s[i] = s[i+1]; + s[i] = s[i + 1]; } return true; } return false; } -static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) +static int WndProcET(t_x11* x11, t_dlgitem* dlgitem, XEvent* event) { - t_edittext *et; - t_windata *win; - KeySym keysym; - char c[BUFSIZE+1], *bp; - char scrbuf[STRLEN]; - int i; - int xp, xtitle, ewidth; + t_edittext* et; + t_windata* win; + KeySym keysym; + char c[BUFSIZE + 1], *bp; + char scrbuf[STRLEN]; + int i; + int xp, xtitle, ewidth; if (dlgitem->type != edlgET) { @@ -393,7 +377,7 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) /* Copy string part that is visible into screen buffer */ for (i = 0; (i < et->buflen); i++) { - scrbuf[i] = et->buf[i+et->strbegin]; + scrbuf[i] = et->buf[i + et->strbegin]; } scrbuf[i] = '\0'; @@ -402,12 +386,10 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) case Expose: XSetForeground(x11->disp, x11->gc, x11->fg); xtitle = XTextWidth(x11->font, win->text, std::strlen(win->text)); - ewidth = win->width-xtitle; - TextInRect(x11, win->self, win->text, - 0, 0, xtitle-1, win->height, eXLeft, eYCenter); - XClearArea(x11->disp, win->self, xtitle, 0, ewidth+XCARET, win->height, False); - TextInRect(x11, win->self, scrbuf, - xtitle+XCARET, 0, ewidth, win->height, eXLeft, eYCenter); + ewidth = win->width - xtitle; + TextInRect(x11, win->self, win->text, 0, 0, xtitle - 1, win->height, eXLeft, eYCenter); + XClearArea(x11->disp, win->self, xtitle, 0, ewidth + XCARET, win->height, False); + TextInRect(x11, win->self, scrbuf, xtitle + XCARET, 0, ewidth, win->height, eXLeft, eYCenter); #ifdef DEBUG std::printf("Expose\n"); #endif @@ -420,8 +402,7 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) /* Calculate new position for caret */ et->pos = std::strlen(et->buf); bp = gmx_strdup(et->buf); - xp = event->xbutton.x-XTextWidth(x11->font, win->text, std::strlen(win->text))- - XCARET; + xp = event->xbutton.x - XTextWidth(x11->font, win->text, std::strlen(win->text)) - XCARET; while ((et->pos > 0) && (XTextWidth(x11->font, bp, std::strlen(bp)) > xp)) { et->pos--; @@ -465,8 +446,7 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) } break; case XK_KP_Enter: - case XK_Return: - return ENTERPRESSED; + case XK_Return: return ENTERPRESSED; case XK_Home: et->pos = 0; et->strbegin = 0; @@ -480,23 +460,22 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) else { et->pos = et->buflen; - et->strbegin = std::strlen(et->buf)-et->buflen; + et->strbegin = std::strlen(et->buf) - et->buflen; } et->bChanged = true; return ETCHANGED; case XK_Left: - et->pos = std::max(0, et->pos-1); + et->pos = std::max(0, et->pos - 1); et->strbegin = std::min(et->strbegin, et->pos); et->bChanged = true; return ETCHANGED; case XK_Right: - if ((et->pos < et->buflen) && - (et->strbegin+et->buflen > (int)strlen(et->buf))) + if ((et->pos < et->buflen) && (et->strbegin + et->buflen > (int)strlen(et->buf))) { et->pos++; } - else if ((et->buflen < (int)strlen(et->buf)) && - (et->strbegin < (int)strlen(et->buf)-et->buflen)) + else if ((et->buflen < (int)strlen(et->buf)) + && (et->strbegin < (int)strlen(et->buf) - et->buflen)) { et->strbegin++; } @@ -527,8 +506,7 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) et->bChanged = false; } break; - default: - return DefWndProc(x11, dlgitem, event); + default: return DefWndProc(x11, dlgitem, event); } return ITEMOK; } @@ -547,25 +525,24 @@ static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event) * on the dlg box, and if wished resize them. * ****************************/ -t_dlgitem *CreateButton(t_x11 *x11, - const char *szLab, bool bDef, t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw) +t_dlgitem* +CreateButton(t_x11* x11, const char* szLab, bool bDef, t_id id, t_id groupid, int x0, int y0, int w, int h, int bw) { - t_dlgitem *dlgitem; - char *lab; + t_dlgitem* dlgitem; + char* lab; dlgitem = newitem(); if (h == 0) { - h = XTextHeight(x11->font)+2*OFFS_Y; + h = XTextHeight(x11->font) + 2 * OFFS_Y; } if (w == 0) { - w = XTextWidth(x11->font, szLab, std::strlen(szLab))+2*OFFS_X; + w = XTextWidth(x11->font, szLab, std::strlen(szLab)) + 2 * OFFS_X; } if (bDef) { - snew(lab, std::strlen(szLab)+7); /* 6 for >> << and 1 for \0 */ + snew(lab, std::strlen(szLab) + 7); /* 6 for >> << and 1 for \0 */ std::sprintf(lab, ">> %s <<", szLab); } else @@ -583,21 +560,19 @@ t_dlgitem *CreateButton(t_x11 *x11, return dlgitem; } -t_dlgitem *CreateRadioButton(t_x11 *x11, - const char *szLab, bool bSet, t_id id, - t_id groupid, - int x0, int y0, int w, int h, int bw) +t_dlgitem* +CreateRadioButton(t_x11* x11, const char* szLab, bool bSet, t_id id, t_id groupid, int x0, int y0, int w, int h, int bw) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; dlgitem = newitem(); if (h == 0) { - h = XTextHeight(x11->font)+OFFS_Y; + h = XTextHeight(x11->font) + OFFS_Y; } if (w == 0) { - w = XTextWidth(x11->font, szLab, std::strlen(szLab))+OFFS_X+h; + w = XTextWidth(x11->font, szLab, std::strlen(szLab)) + OFFS_X + h; } InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab); dlgitem->ID = id; @@ -609,21 +584,19 @@ t_dlgitem *CreateRadioButton(t_x11 *x11, return dlgitem; } -t_dlgitem *CreateGroupBox(t_x11 *x11, - const char *szLab, t_id id, - int nitems, t_id items[], - int x0, int y0, int w, int h, int bw) +t_dlgitem* +CreateGroupBox(t_x11* x11, const char* szLab, t_id id, int nitems, t_id items[], int x0, int y0, int w, int h, int bw) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; dlgitem = newitem(); if (h == 0) { - h = XTextHeight(x11->font)+OFFS_Y; + h = XTextHeight(x11->font) + OFFS_Y; } if (w == 0) { - w = XTextWidth(x11->font, szLab, std::strlen(szLab))+2*OFFS_X; + w = XTextWidth(x11->font, szLab, std::strlen(szLab)) + 2 * OFFS_X; } InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab); dlgitem->GroupID = id; @@ -631,28 +604,33 @@ t_dlgitem *CreateGroupBox(t_x11 *x11, dlgitem->type = edlgGB; dlgitem->u.groupbox.nitems = nitems; snew(dlgitem->u.groupbox.item, nitems); - std::memcpy((char *)dlgitem->u.groupbox.item, (char *)items, - nitems*sizeof(items[0])); + std::memcpy((char*)dlgitem->u.groupbox.item, (char*)items, nitems * sizeof(items[0])); dlgitem->WndProc = WndProcGB; return dlgitem; } -t_dlgitem *CreateCheckBox(t_x11 *x11, - const char *szLab, bool bCheckedInitial, t_id id, - t_id groupid, - int x0, int y0, int w, int h, int bw) +t_dlgitem* CreateCheckBox(t_x11* x11, + const char* szLab, + bool bCheckedInitial, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; dlgitem = newitem(); if (h == 0) { - h = XTextHeight(x11->font)+OFFS_Y; + h = XTextHeight(x11->font) + OFFS_Y; } if (w == 0) { - w = XTextWidth(x11->font, szLab, std::strlen(szLab))+OFFS_X+h; + w = XTextWidth(x11->font, szLab, std::strlen(szLab)) + OFFS_X + h; } InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab); dlgitem->ID = id; @@ -664,10 +642,9 @@ t_dlgitem *CreateCheckBox(t_x11 *x11, return dlgitem; } -t_dlgitem *CreatePixmap(Pixmap pm, t_id id, - t_id /*groupid*/, int x0, int y0, int w, int h, int bw) +t_dlgitem* CreatePixmap(Pixmap pm, t_id id, t_id /*groupid*/, int x0, int y0, int w, int h, int bw) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; dlgitem = newitem(); InitWin(&(dlgitem->win), x0, y0, w, h, bw, nullptr); @@ -679,18 +656,24 @@ t_dlgitem *CreatePixmap(Pixmap pm, t_id id, return dlgitem; } -t_dlgitem *CreateStaticText(t_x11 *x11, - int nlines, const char * const *lines, t_id id, - t_id groupid, - int x0, int y0, int w, int h, int bw) +t_dlgitem* CreateStaticText(t_x11* x11, + int nlines, + const char* const* lines, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw) { - t_dlgitem *dlgitem; + t_dlgitem* dlgitem; int i; dlgitem = newitem(); if (h == 0) { - h = (XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y; + h = (XTextHeight(x11->font) + OFFS_Y) * nlines + OFFS_Y; } if (w == 0) { @@ -698,7 +681,7 @@ t_dlgitem *CreateStaticText(t_x11 *x11, { w = std::max(w, XTextWidth(x11->font, lines[i], std::strlen(lines[i]))); } - w += 2*OFFS_X; + w += 2 * OFFS_X; } InitWin(&(dlgitem->win), x0, y0, w, h, bw, nullptr); dlgitem->ID = id; @@ -715,28 +698,34 @@ t_dlgitem *CreateStaticText(t_x11 *x11, return dlgitem; } -t_dlgitem *CreateEditText(t_x11 *x11, - const char *title, - int screenbuf, char *buf, t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw) +t_dlgitem* CreateEditText(t_x11* x11, + const char* title, + int screenbuf, + char* buf, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw) { - t_dlgitem *dlgitem; - t_edittext *et; + t_dlgitem* dlgitem; + t_edittext* et; dlgitem = newitem(); if (h == 0) { - h = XTextHeight(x11->font)+OFFS_Y; + h = XTextHeight(x11->font) + OFFS_Y; } if (w == 0) { - char *test; + char* test; snew(test, screenbuf); std::memset(test, 'w', screenbuf); - w = XTextWidth(x11->font, test, screenbuf)+ - XTextWidth(x11->font, title, std::strlen(title))+ - 2*XCARET+2*OFFS_X; + w = XTextWidth(x11->font, test, screenbuf) + + XTextWidth(x11->font, title, std::strlen(title)) + 2 * XCARET + 2 * OFFS_X; sfree(test); } InitWin(&(dlgitem->win), x0, y0, w, h, bw, title); @@ -756,8 +745,7 @@ t_dlgitem *CreateEditText(t_x11 *x11, #define SC(src) (strlen(src) ? gmx_strdup(src) : NULL) -void SetDlgitemOpts(t_dlgitem *dlgitem, bool bUseMon, - char *set, char *get, char *help) +void SetDlgitemOpts(t_dlgitem* dlgitem, bool bUseMon, char* set, char* get, char* help) { dlgitem->bUseMon = bUseMon; dlgitem->set = SC(set); diff --git a/src/programs/view/xdlgitem.h b/src/programs/view/xdlgitem.h index 8bf04120d0..a4e0fff0f2 100644 --- a/src/programs/view/xdlgitem.h +++ b/src/programs/view/xdlgitem.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -42,60 +42,83 @@ #include "x11.h" #include "xutil.h" -typedef enum { - edlgBN, edlgRB, edlgGB, edlgCB, edlgPM, edlgST, edlgET, edlgNR +typedef enum +{ + edlgBN, + edlgRB, + edlgGB, + edlgCB, + edlgPM, + edlgST, + edlgET, + edlgNR } edlgitem; -#define XCARET 2 - -enum { - ITEMOK, RBPRESSED, BNPRESSED, CBPRESSED, ETCHANGED, HELPPRESSED, ENTERPRESSED +#define XCARET 2 + +enum +{ + ITEMOK, + RBPRESSED, + BNPRESSED, + CBPRESSED, + ETCHANGED, + HELPPRESSED, + ENTERPRESSED }; typedef int t_id; -typedef struct { - bool bDefault; /* This is the default button */ +typedef struct +{ + bool bDefault; /* This is the default button */ } t_button; -typedef struct { - bool bSelect; /* Is this rb selected ? */ +typedef struct +{ + bool bSelect; /* Is this rb selected ? */ } t_radiobutton; -typedef struct { - bool bChecked; /* Is this cb checked ? */ +typedef struct +{ + bool bChecked; /* Is this cb checked ? */ } t_checkbox; -typedef struct { - Pixmap pm; /* The pixmap bits */ +typedef struct +{ + Pixmap pm; /* The pixmap bits */ } t_pixmap; -typedef struct { +typedef struct +{ int nlines; - char **lines; + char** lines; } t_statictext; -typedef struct { - int buflen, strbegin; /* Length of the screen buf and begin of string */ - int pos; /* Current length of the string and pos of caret */ +typedef struct +{ + int buflen, strbegin; /* Length of the screen buf and begin of string */ + int pos; /* Current length of the string and pos of caret */ /* Pos is relative to strbegin, and is the pos */ /* in the window. */ - bool bChanged; - char *buf; + bool bChanged; + char* buf; } t_edittext; -typedef struct { +typedef struct +{ int nitems; - t_id *item; + t_id* item; } t_groupbox; -typedef struct t_dlgitem { - t_windata win; - t_id ID, GroupID; - bool bUseMon; - char *set, *get, *help; - edlgitem type; - int (*WndProc)(t_x11 *x11, struct t_dlgitem *dlgitem, XEvent *event); +typedef struct t_dlgitem +{ + t_windata win; + t_id ID, GroupID; + bool bUseMon; + char * set, *get, *help; + edlgitem type; + int (*WndProc)(t_x11* x11, struct t_dlgitem* dlgitem, XEvent* event); union { t_button button; t_radiobutton radiobutton; @@ -121,37 +144,51 @@ typedef struct t_dlgitem { * on the dlg box, and if wished resize them. * ****************************/ -extern t_dlgitem *CreateButton(t_x11 *x11, const char *szLab, bool bDef, - t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreateRadioButton(t_x11 *x11, - const char *szLab, bool bSet, t_id id, - t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreateGroupBox(t_x11 *x11, const char *szLab, t_id id, - int nitems, t_id items[], - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreateCheckBox(t_x11 *x11, const char *szLab, - bool bCheckedInitial, - t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreatePixmap(Pixmap pm, t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreateStaticText(t_x11 *x11, - int nlines, const char * const *lines, - t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern t_dlgitem *CreateEditText(t_x11 *x11, const char *title, - int screenbuf, char *buf, t_id id, t_id groupid, - int x0, int y0, int w, int h, int bw); - -extern void SetDlgitemOpts(t_dlgitem *dlgitem, bool bUseMon, - char *set, char *get, char *help); - -#endif /* _xdlgitem_h */ +extern t_dlgitem* +CreateButton(t_x11* x11, const char* szLab, bool bDef, t_id id, t_id groupid, int x0, int y0, int w, int h, int bw); + +extern t_dlgitem* +CreateRadioButton(t_x11* x11, const char* szLab, bool bSet, t_id id, t_id groupid, int x0, int y0, int w, int h, int bw); + +extern t_dlgitem* +CreateGroupBox(t_x11* x11, const char* szLab, t_id id, int nitems, t_id items[], int x0, int y0, int w, int h, int bw); + +extern t_dlgitem* CreateCheckBox(t_x11* x11, + const char* szLab, + bool bCheckedInitial, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw); + +extern t_dlgitem* CreatePixmap(Pixmap pm, t_id id, t_id groupid, int x0, int y0, int w, int h, int bw); + +extern t_dlgitem* CreateStaticText(t_x11* x11, + int nlines, + const char* const* lines, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw); + +extern t_dlgitem* CreateEditText(t_x11* x11, + const char* title, + int screenbuf, + char* buf, + t_id id, + t_id groupid, + int x0, + int y0, + int w, + int h, + int bw); + +extern void SetDlgitemOpts(t_dlgitem* dlgitem, bool bUseMon, char* set, char* get, char* help); + +#endif /* _xdlgitem_h */ diff --git a/src/programs/view/xmb.cpp b/src/programs/view/xmb.cpp index 155d1a3d14..1d564cf9b7 100644 --- a/src/programs/view/xmb.cpp +++ b/src/programs/view/xmb.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -52,39 +52,43 @@ #include "xdlg.h" #include "xutil.h" -#define ID_BOX -3 -#define ID_ICON -2 -#define ID_TEXT -1 +#define ID_BOX -3 +#define ID_ICON -2 +#define ID_TEXT -1 -static bmchar *icon_bits = nullptr; -static int icon_width = 0; -static int icon_height = 0; -static unsigned long icon_fg = 0; -static unsigned long icon_bg = 0; +static bmchar* icon_bits = nullptr; +static int icon_width = 0; +static int icon_height = 0; +static unsigned long icon_fg = 0; +static unsigned long icon_bg = 0; -static void SetIcon(unsigned char *bits, int w, int h, unsigned long fg, unsigned long bg) +static void SetIcon(unsigned char* bits, int w, int h, unsigned long fg, unsigned long bg) { - icon_bits = (bmchar *)bits; + icon_bits = (bmchar*)bits; icon_width = w; icon_height = h; icon_fg = fg; icon_bg = bg; } -t_dlg *MessageBox(t_x11 *x11, Window Parent, const char *title, - int nlines, const char * const * lines, unsigned long Flags, - DlgCallback *cb, void *data) +t_dlg* MessageBox(t_x11* x11, + Window Parent, + const char* title, + int nlines, + const char* const* lines, + unsigned long Flags, + DlgCallback* cb, + void* data) { - t_dlg *dlg; - int width, nicon; - int x, y, x0; - unsigned long nFlag; - unsigned long bg; + t_dlg* dlg; + int width, nicon; + int x, y, x0; + unsigned long nFlag; + unsigned long bg; /* Check flags for inconsistencies */ - if (((Flags & MB_OK) && (Flags & MB_YES)) || - ((Flags & MB_NO) && (Flags & MB_CANCEL)) || - (!(Flags & MB_OK) && !(Flags & MB_YES))) + if (((Flags & MB_OK) && (Flags & MB_YES)) || ((Flags & MB_NO) && (Flags & MB_CANCEL)) + || (!(Flags & MB_OK) && !(Flags & MB_YES))) { std::fprintf(stderr, "Invalid button selection in MessageBox\n"); std::exit(1); @@ -133,62 +137,58 @@ t_dlg *MessageBox(t_x11 *x11, Window Parent, const char *title, } dlg = CreateDlg(x11, Parent, title, 0, 0, 0, 0, 3, cb, data); - x = 2*OFFS_X; + x = 2 * OFFS_X; if (nicon > 0) { - AddDlgItem(dlg, CreatePixmap - (XCreatePixmapFromBitmapData - (x11->disp, dlg->win.self, icon_bits, icon_width, icon_height, - icon_fg, icon_bg, x11->depth), - ID_ICON, ID_BOX, 2*OFFS_X, 2*OFFS_Y, icon_width, icon_height, 0)); - x += QueryDlgItemW(dlg, ID_ICON)+2*OFFS_X; + AddDlgItem(dlg, + CreatePixmap(XCreatePixmapFromBitmapData(x11->disp, dlg->win.self, icon_bits, icon_width, + icon_height, icon_fg, icon_bg, x11->depth), + ID_ICON, ID_BOX, 2 * OFFS_X, 2 * OFFS_Y, icon_width, icon_height, 0)); + x += QueryDlgItemW(dlg, ID_ICON) + 2 * OFFS_X; } - AddDlgItem(dlg, CreateStaticText(x11, nlines, lines, ID_TEXT, ID_BOX, - x, 2*OFFS_Y, 0, 0, 0)); + AddDlgItem(dlg, CreateStaticText(x11, nlines, lines, ID_TEXT, ID_BOX, x, 2 * OFFS_Y, 0, 0, 0)); - y = QueryDlgItemY(dlg, ID_TEXT)+QueryDlgItemH(dlg, ID_TEXT); + y = QueryDlgItemY(dlg, ID_TEXT) + QueryDlgItemH(dlg, ID_TEXT); if (nicon > 0) { int yi; - yi = QueryDlgItemY(dlg, ID_ICON)+QueryDlgItemH(dlg, ID_ICON); + yi = QueryDlgItemY(dlg, ID_ICON) + QueryDlgItemH(dlg, ID_ICON); if (yi > y) { - SetDlgItemPos(dlg, ID_TEXT, x, 2*OFFS_Y+(yi-y)/2); + SetDlgItemPos(dlg, ID_TEXT, x, 2 * OFFS_Y + (yi - y) / 2); } else { - SetDlgItemPos(dlg, ID_ICON, 2*OFFS_X, 2*OFFS_Y+(y-yi)/2); + SetDlgItemPos(dlg, ID_ICON, 2 * OFFS_X, 2 * OFFS_Y + (y - yi) / 2); } if (yi > y) { y = yi; } } - x += QueryDlgItemW(dlg, ID_TEXT)+2*OFFS_X; - y += 2*OFFS_Y; - width = (x-8*OFFS_X)/2; + x += QueryDlgItemW(dlg, ID_TEXT) + 2 * OFFS_X; + y += 2 * OFFS_Y; + width = (x - 8 * OFFS_X) / 2; - if (((Flags & MB_OKCANCEL) == MB_OKCANCEL) || - ((Flags & MB_YESNO) == MB_YESNO)) + if (((Flags & MB_OKCANCEL) == MB_OKCANCEL) || ((Flags & MB_YESNO) == MB_YESNO)) { - x0 = 2*OFFS_X; + x0 = 2 * OFFS_X; } else { - x0 = (x-width)/2; + x0 = (x - width) / 2; } -#define CB(name, butx, id) AddDlgItem(dlg, CreateButton(x11, name, \ - true, id, ID_BOX, \ - butx, y, width, 0, 0)) +#define CB(name, butx, id) \ + AddDlgItem(dlg, CreateButton(x11, name, true, id, ID_BOX, butx, y, width, 0, 0)) if (Flags & MB_OK) { CB("OK", x0, MB_OK); } if (Flags & MB_CANCEL) { - CB("Cancel", x/2+2*OFFS_X, MB_CANCEL); + CB("Cancel", x / 2 + 2 * OFFS_X, MB_CANCEL); } if (Flags & MB_YES) { @@ -196,11 +196,10 @@ t_dlg *MessageBox(t_x11 *x11, Window Parent, const char *title, } if (Flags & MB_NO) { - CB("No", x/2+2*OFFS_X, MB_NO); + CB("No", x / 2 + 2 * OFFS_X, MB_NO); } - SetDlgSize(dlg, x, y+2*OFFS_Y+ - QueryDlgItemH(dlg, (Flags & MB_OK) ? MB_OK : MB_YES), true); + SetDlgSize(dlg, x, y + 2 * OFFS_Y + QueryDlgItemH(dlg, (Flags & MB_OK) ? MB_OK : MB_YES), true); if (Flags & MB_SYSTEMMODAL) { diff --git a/src/programs/view/xmb.h b/src/programs/view/xmb.h index ccb5fa28df..0401818f67 100644 --- a/src/programs/view/xmb.h +++ b/src/programs/view/xmb.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -43,22 +43,27 @@ #include "xdlg.h" #include "xmb.h" -#define MB_OK 1 -#define MB_CANCEL (1<<1) -#define MB_OKCANCEL (MB_OK | MB_CANCEL) -#define MB_YES (1<<2) -#define MB_NO (1<<3) -#define MB_YESNO (MB_YES | MB_NO) -#define MB_ICONSTOP (1<<16) -#define MB_ICONINFORMATION (1<<17) -#define MB_ICONEXCLAMATION (1<<18) -#define MB_ICONGMX (1<<19) -#define MB_SYSTEMMODAL (1<<20) -#define MB_APPLMODAL (1<<21) -#define MB_DONTSHOW (1<<22) +#define MB_OK 1 +#define MB_CANCEL (1 << 1) +#define MB_OKCANCEL (MB_OK | MB_CANCEL) +#define MB_YES (1 << 2) +#define MB_NO (1 << 3) +#define MB_YESNO (MB_YES | MB_NO) +#define MB_ICONSTOP (1 << 16) +#define MB_ICONINFORMATION (1 << 17) +#define MB_ICONEXCLAMATION (1 << 18) +#define MB_ICONGMX (1 << 19) +#define MB_SYSTEMMODAL (1 << 20) +#define MB_APPLMODAL (1 << 21) +#define MB_DONTSHOW (1 << 22) -t_dlg *MessageBox(t_x11 *x11, Window Parent, const char *title, - int nlines, const char * const *lines, unsigned long Flags, - DlgCallback *cb, void *data); +t_dlg* MessageBox(t_x11* x11, + Window Parent, + const char* title, + int nlines, + const char* const* lines, + unsigned long Flags, + DlgCallback* cb, + void* data); -#endif /* _xmb_h */ +#endif /* _xmb_h */ diff --git a/src/programs/view/xutil.cpp b/src/programs/view/xutil.cpp index 2c53b3e785..17d2081c04 100644 --- a/src/programs/view/xutil.cpp +++ b/src/programs/view/xutil.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2013, The GROMACS development team. - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -46,23 +46,19 @@ #include "Xstuff.h" -int CheckWin(Window win, const char *file, int line) +int CheckWin(Window win, const char* file, int line) { - typedef struct { + typedef struct + { Window n; - const char *s; + const char* s; } t_winerr; - t_winerr winerr[] = { - { BadAlloc, "Bad Alloc" }, - { BadColor, "Bad Color" }, - { BadCursor, "Bad Cursor"}, - { BadMatch, "Bad Match" }, - { BadPixmap, "Bad Pixmap"}, - { BadValue, "Bad Value" }, - { BadWindow, "Bad Window"} - }; -#define NERR (sizeof(winerr)/sizeof(winerr[0])) - unsigned int i; + t_winerr winerr[] = { { BadAlloc, "Bad Alloc" }, { BadColor, "Bad Color" }, + { BadCursor, "Bad Cursor" }, { BadMatch, "Bad Match" }, + { BadPixmap, "Bad Pixmap" }, { BadValue, "Bad Value" }, + { BadWindow, "Bad Window" } }; +#define NERR (sizeof(winerr) / sizeof(winerr[0])) + unsigned int i; for (i = 0; (i < NERR); i++) { @@ -81,7 +77,7 @@ int CheckWin(Window win, const char *file, int line) return 0; } -void LightBorder(Display *disp, Window win, unsigned long color) +void LightBorder(Display* disp, Window win, unsigned long color) { XSetWindowAttributes attributes; @@ -89,12 +85,19 @@ void LightBorder(Display *disp, Window win, unsigned long color) XChangeWindowAttributes(disp, win, CWBorderPixel, &attributes); } -void SpecialTextInRect(t_x11 *x11, XFontStruct *font, Drawable win, - const char *s, int x, int y, int width, int height, - eXPos eX, eYPos eY) +void SpecialTextInRect(t_x11* x11, + XFontStruct* font, + Drawable win, + const char* s, + int x, + int y, + int width, + int height, + eXPos eX, + eYPos eY) { int fw, fh, x0, y0; - XFontStruct *f; + XFontStruct* f; if (font) { @@ -110,29 +113,17 @@ void SpecialTextInRect(t_x11 *x11, XFontStruct *font, Drawable win, fh = XTextHeight(f); switch (eX) { - case eXLeft: - x0 = x; - break; - case eXRight: - x0 = x+width-fw; - break; + case eXLeft: x0 = x; break; + case eXRight: x0 = x + width - fw; break; case eXCenter: - default: - x0 = x+(width-fw)/2; - break; + default: x0 = x + (width - fw) / 2; break; } switch (eY) { - case eYTop: - y0 = y+f->ascent; - break; - case eYBottom: - y0 = y+height-f->descent; - break; + case eYTop: y0 = y + f->ascent; break; + case eYBottom: y0 = y + height - f->descent; break; case eYCenter: - default: - y0 = y+(height-fh)/2+f->ascent; - break; + default: y0 = y + (height - fh) / 2 + f->ascent; break; } XDrawString(x11->disp, win, x11->gc, x0, y0, s, std::strlen(s)); if (font) @@ -141,20 +132,17 @@ void SpecialTextInRect(t_x11 *x11, XFontStruct *font, Drawable win, } } -void TextInRect(t_x11 *x11, Drawable win, - const char *s, int x, int y, int width, int height, - eXPos eX, eYPos eY) +void TextInRect(t_x11* x11, Drawable win, const char* s, int x, int y, int width, int height, eXPos eX, eYPos eY) { SpecialTextInRect(x11, nullptr, win, s, x, y, width, height, eX, eY); } -void TextInWin(t_x11 *x11, t_windata *win, - const char *s, eXPos eX, eYPos eY) +void TextInWin(t_x11* x11, t_windata* win, const char* s, eXPos eX, eYPos eY) { TextInRect(x11, win->self, s, 0, 0, win->width, win->height, eX, eY); } -void InitWin(t_windata *win, int x0, int y0, int w, int h, int bw, const char *text) +void InitWin(t_windata* win, int x0, int y0, int w, int h, int bw, const char* text) { win->self = 0; win->color = 0; @@ -178,7 +166,7 @@ void InitWin(t_windata *win, int x0, int y0, int w, int h, int bw, const char *t #endif } -void FreeWin(Display *disp, t_windata *win) +void FreeWin(Display* disp, t_windata* win) { if (win->text) { @@ -190,7 +178,7 @@ void FreeWin(Display *disp, t_windata *win) } } -void ExposeWin(Display *disp, Window win) +void ExposeWin(Display* disp, Window win) { XEvent event; @@ -205,11 +193,12 @@ void ExposeWin(Display *disp, Window win) XSendEvent(disp, win, False, ExposureMask, &event); } -void XDrawRoundRect(Display *disp, Window win, GC gc, - int x, int y, int w, int h) +void XDrawRoundRect(Display* disp, Window win, GC gc, int x, int y, int w, int h) { -#define RAD (OFFS_X/2) -#define SetPoint(pn, x0, y0) pn.x = x0; pn.y = y0 +#define RAD (OFFS_X / 2) +#define SetPoint(pn, x0, y0) \ + pn.x = x0; \ + pn.y = y0 if ((w < 10) || (h < 10)) { @@ -219,55 +208,54 @@ void XDrawRoundRect(Display *disp, Window win, GC gc, { XPoint p[9]; - SetPoint(p[0], x+RAD, y); - SetPoint(p[1], w-2*RAD, 0); + SetPoint(p[0], x + RAD, y); + SetPoint(p[1], w - 2 * RAD, 0); SetPoint(p[2], RAD, RAD); - SetPoint(p[3], 0, h-2*RAD); + SetPoint(p[3], 0, h - 2 * RAD); SetPoint(p[4], -RAD, RAD); - SetPoint(p[5], 2*RAD-w, 0); + SetPoint(p[5], 2 * RAD - w, 0); SetPoint(p[6], -RAD, -RAD); - SetPoint(p[7], 0, 2*RAD-h); + SetPoint(p[7], 0, 2 * RAD - h); SetPoint(p[8], RAD, -RAD); XDrawLines(disp, win, gc, p, 9, CoordModePrevious); } } -void RoundRectWin(Display *disp, GC gc, t_windata *win, - int offsx, int offsy, unsigned long color) +void RoundRectWin(Display* disp, GC gc, t_windata* win, int offsx, int offsy, unsigned long color) { XSetLineAttributes(disp, gc, 1, LineOnOffDash, CapButt, JoinRound); XSetForeground(disp, gc, color); - XDrawRoundRect(disp, win->self, gc, offsx, offsy, - win->width-2*offsx-1, win->height-2*offsy-1); + XDrawRoundRect(disp, win->self, gc, offsx, offsy, win->width - 2 * offsx - 1, + win->height - 2 * offsy - 1); XSetLineAttributes(disp, gc, 1, LineSolid, CapButt, JoinRound); } -void RectWin(Display *disp, GC gc, t_windata *win, unsigned long color) +void RectWin(Display* disp, GC gc, t_windata* win, unsigned long color) { int bw = 1; /*2*w.bwidth;*/ XSetForeground(disp, gc, color); - XDrawRoundRect(disp, win->self, gc, 0, 0, win->width-bw, win->height-bw); + XDrawRoundRect(disp, win->self, gc, 0, 0, win->width - bw, win->height - bw); } -typedef struct t_mpos { +typedef struct t_mpos +{ int x, y; - struct t_mpos *prev; + struct t_mpos* prev; } t_mpos; -static t_mpos *mpos = nullptr; +static t_mpos* mpos = nullptr; -void PushMouse(Display *disp, Window dest, int x, int y) +void PushMouse(Display* disp, Window dest, int x, int y) { - Window root, child; - int root_x, root_y; - int win_x, win_y; - unsigned int keybut; - t_mpos *newpos; + Window root, child; + int root_x, root_y; + int win_x, win_y; + unsigned int keybut; + t_mpos* newpos; snew(newpos, 1); - XQueryPointer(disp, DefaultRootWindow(disp), &root, &child, &root_x, &root_y, - &win_x, &win_y, &keybut); + XQueryPointer(disp, DefaultRootWindow(disp), &root, &child, &root_x, &root_y, &win_x, &win_y, &keybut); newpos->x = root_x; newpos->y = root_y; newpos->prev = mpos; @@ -278,9 +266,9 @@ void PushMouse(Display *disp, Window dest, int x, int y) #endif } -void PopMouse(Display *disp) +void PopMouse(Display* disp) { - t_mpos *old; + t_mpos* old; old = mpos; if (!old) @@ -296,10 +284,10 @@ void PopMouse(Display *disp) sfree(old); } -bool HelpPressed(XEvent *event) +bool HelpPressed(XEvent* event) { #define BUFSIZE 24 - char buf[BUFSIZE+1]; + char buf[BUFSIZE + 1]; XComposeStatus compose; KeySym keysym; @@ -308,22 +296,16 @@ bool HelpPressed(XEvent *event) return (keysym == XK_F1); } -bool GrabOK(FILE *out, int err) +bool GrabOK(FILE* out, int err) { switch (err) { - case GrabSuccess: - return true; - case GrabNotViewable: - std::fprintf(out, "GrabNotViewable\n"); break; - case AlreadyGrabbed: - std::fprintf(out, "AlreadyGrabbed\n"); break; - case GrabFrozen: - std::fprintf(out, "GrabFrozen\n"); break; - case GrabInvalidTime: - std::fprintf(out, "GrabInvalidTime\n"); break; - default: - break; + case GrabSuccess: return true; + case GrabNotViewable: std::fprintf(out, "GrabNotViewable\n"); break; + case AlreadyGrabbed: std::fprintf(out, "AlreadyGrabbed\n"); break; + case GrabFrozen: std::fprintf(out, "GrabFrozen\n"); break; + case GrabInvalidTime: std::fprintf(out, "GrabInvalidTime\n"); break; + default: break; } return false; } diff --git a/src/programs/view/xutil.h b/src/programs/view/xutil.h index 38510d820e..8094ff55a3 100644 --- a/src/programs/view/xutil.h +++ b/src/programs/view/xutil.h @@ -3,7 +3,7 @@ * * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. - * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,57 +47,62 @@ #include "Xstuff.h" #include "x11.h" -#define OFFS_X 4 -#define OFFS_Y 4 - -typedef struct { - Window self, Parent; - unsigned long color; - char *text; - bool bFocus; - int x, y, width, height, bwidth; - Cursor cursor; +#define OFFS_X 4 +#define OFFS_Y 4 + +typedef struct +{ + Window self, Parent; + unsigned long color; + char* text; + bool bFocus; + int x, y, width, height, bwidth; + Cursor cursor; } t_windata; -extern int CheckWin(Window win, const char *file, int line); +extern int CheckWin(Window win, const char* file, int line); #define CheckWindow(win) CheckWin(win, __FILE__, __LINE__) -extern void LightBorder(Display *disp, Window win, unsigned long color); +extern void LightBorder(Display* disp, Window win, unsigned long color); -extern void SpecialTextInRect(t_x11 *x11, XFontStruct *font, Drawable win, - const char *s, int x, int y, int width, int height, - eXPos eX, eYPos eY); +extern void SpecialTextInRect(t_x11* x11, + XFontStruct* font, + Drawable win, + const char* s, + int x, + int y, + int width, + int height, + eXPos eX, + eYPos eY); -extern void TextInRect(t_x11 *x11, Drawable win, - const char *s, int x, int y, int width, int height, - eXPos eX, eYPos eY); +extern void +TextInRect(t_x11* x11, Drawable win, const char* s, int x, int y, int width, int height, eXPos eX, eYPos eY); -extern void TextInWin(t_x11 *x11, t_windata *win, const char *s, eXPos eX, eYPos eY); +extern void TextInWin(t_x11* x11, t_windata* win, const char* s, eXPos eX, eYPos eY); -extern void InitWin(t_windata *win, int x0, int y0, int w, int h, int bw, const char *text); +extern void InitWin(t_windata* win, int x0, int y0, int w, int h, int bw, const char* text); -extern void FreeWin(Display *disp, t_windata *win); +extern void FreeWin(Display* disp, t_windata* win); -extern void ExposeWin(Display *disp, Window win); +extern void ExposeWin(Display* disp, Window win); -extern void RectWin(Display *disp, GC gc, t_windata *win, unsigned long color); +extern void RectWin(Display* disp, GC gc, t_windata* win, unsigned long color); -extern void XDrawRoundRect(Display *disp, Window win, GC gc, - int x, int y, int w, int h); +extern void XDrawRoundRect(Display* disp, Window win, GC gc, int x, int y, int w, int h); -extern void RoundRectWin(Display *disp, GC gc, t_windata *win, - int offsx, int offsy, unsigned long color); +extern void RoundRectWin(Display* disp, GC gc, t_windata* win, int offsx, int offsy, unsigned long color); -extern void PushMouse(Display *disp, Window dest, int x, int y); +extern void PushMouse(Display* disp, Window dest, int x, int y); -extern void PopMouse(Display *disp); +extern void PopMouse(Display* disp); -extern bool HelpPressed(XEvent *event); +extern bool HelpPressed(XEvent* event); -extern bool GrabOK(FILE *out, int err); +extern bool GrabOK(FILE* out, int err); /* Return true if grab succeeded, prints a message to out * and returns false otherwise. */ -#endif /* _xutil_h */ +#endif /* _xutil_h */ diff --git a/src/testutils/cmdlinetest.cpp b/src/testutils/cmdlinetest.cpp index 1db63fc708..32051396b4 100644 --- a/src/testutils/cmdlinetest.cpp +++ b/src/testutils/cmdlinetest.cpp @@ -78,24 +78,24 @@ namespace test class CommandLine::Impl { - public: - Impl(const ArrayRef &cmdline); - Impl(const ArrayRef &cmdline); - ~Impl(); - - std::vector args_; - std::vector argv_; - int argc_; +public: + Impl(const ArrayRef& cmdline); + Impl(const ArrayRef& cmdline); + ~Impl(); + + std::vector args_; + std::vector argv_; + int argc_; }; -CommandLine::Impl::Impl(const ArrayRef &cmdline) +CommandLine::Impl::Impl(const ArrayRef& cmdline) { args_.reserve(cmdline.size()); argv_.reserve(cmdline.size() + 1); argc_ = ssize(cmdline); - for (const auto &arg : cmdline) + for (const auto& arg : cmdline) { - char *argCopy = strdup(arg); + char* argCopy = strdup(arg); if (argCopy == nullptr) { throw std::bad_alloc(); @@ -110,20 +110,23 @@ namespace { //! Helper function so we can delegate from the std::string constructor to the const char * one. -std::vector convertFromStringArrayRef(const ArrayRef &cmdline) +std::vector convertFromStringArrayRef(const ArrayRef& cmdline) { std::vector v(cmdline.size()); - std::transform(cmdline.begin(), cmdline.end(), v.begin(), [](const std::string &s){return s.c_str(); }); + std::transform(cmdline.begin(), cmdline.end(), v.begin(), + [](const std::string& s) { return s.c_str(); }); return v; } -} // namespace +} // namespace // This makes a new temporary vector of views of the const char * in // the view passed in. Those are then deep copied in the constructor // delegated to. -CommandLine::Impl::Impl(const ArrayRef &cmdline) - : Impl(convertFromStringArrayRef(cmdline)) {} +CommandLine::Impl::Impl(const ArrayRef& cmdline) : + Impl(convertFromStringArrayRef(cmdline)) +{ +} CommandLine::Impl::~Impl() { @@ -137,43 +140,32 @@ CommandLine::Impl::~Impl() * CommandLine */ -CommandLine::CommandLine() - : impl_(new Impl(ArrayRef{})) -{ -} +CommandLine::CommandLine() : impl_(new Impl(ArrayRef{})) {} -CommandLine::CommandLine(const ArrayRef &cmdline) - : impl_(new Impl(cmdline)) -{ -} +CommandLine::CommandLine(const ArrayRef& cmdline) : impl_(new Impl(cmdline)) {} -CommandLine::CommandLine(const ArrayRef &cmdline) - : impl_(new Impl(cmdline)) -{ -} +CommandLine::CommandLine(const ArrayRef& cmdline) : impl_(new Impl(cmdline)) {} -CommandLine::CommandLine(const CommandLine &other) - : impl_(new Impl(arrayRefFromArray(other.argv(), other.argc()))) +CommandLine::CommandLine(const CommandLine& other) : + impl_(new Impl(arrayRefFromArray(other.argv(), other.argc()))) { } -CommandLine::~CommandLine() -{ -} +CommandLine::~CommandLine() {} -void CommandLine::initFromArray(const ArrayRef &cmdline) +void CommandLine::initFromArray(const ArrayRef& cmdline) { impl_.reset(new Impl(cmdline)); } -void CommandLine::append(const char *arg) +void CommandLine::append(const char* arg) { GMX_RELEASE_ASSERT(impl_->argc_ == ssize(impl_->args_), "Command-line has been modified externally"); size_t newSize = impl_->args_.size() + 1; impl_->args_.reserve(newSize); impl_->argv_.reserve(newSize + 1); - char *newArg = strdup(arg); + char* newArg = strdup(arg); if (newArg == nullptr) { throw std::bad_alloc(); @@ -185,35 +177,35 @@ void CommandLine::append(const char *arg) impl_->argc_ = static_cast(newSize); } -void CommandLine::addOption(const char *name) +void CommandLine::addOption(const char* name) { append(name); } -void CommandLine::addOption(const char *name, const char *value) +void CommandLine::addOption(const char* name, const char* value) { append(name); append(value); } -void CommandLine::addOption(const char *name, const std::string &value) +void CommandLine::addOption(const char* name, const std::string& value) { addOption(name, value.c_str()); } -void CommandLine::addOption(const char *name, int value) +void CommandLine::addOption(const char* name, int value) { append(name); append(gmx::toString(value)); } -void CommandLine::addOption(const char *name, double value) +void CommandLine::addOption(const char* name, double value) { append(name); append(gmx::toString(value)); } -void CommandLine::merge(const CommandLine &args) +void CommandLine::merge(const CommandLine& args) { if (args.argc() > 0) { @@ -226,11 +218,11 @@ void CommandLine::merge(const CommandLine &args) } } -int &CommandLine::argc() +int& CommandLine::argc() { return impl_->argc_; } -char **CommandLine::argv() +char** CommandLine::argv() { return &impl_->argv_[0]; } @@ -238,11 +230,11 @@ int CommandLine::argc() const { return impl_->argc_; } -const char *const *CommandLine::argv() const +const char* const* CommandLine::argv() const { return &impl_->argv_[0]; } -const char *CommandLine::arg(int i) const +const char* CommandLine::arg(int i) const { return impl_->argv_[i]; } @@ -252,7 +244,7 @@ std::string CommandLine::toString() const return CommandLineProgramContext(argc(), argv()).commandLine(); } -bool CommandLine::contains(const char *name) const +bool CommandLine::contains(const char* name) const { for (int i = 0; i < impl_->argc_; ++i) { @@ -270,29 +262,27 @@ bool CommandLine::contains(const char *name) const class CommandLineTestHelper::Impl { - public: - struct OutputFileInfo +public: + struct OutputFileInfo + { + OutputFileInfo(const char* option, const std::string& path, FileMatcherPointer matcher) : + option(option), + path(path), + matcher(move(matcher)) { - OutputFileInfo(const char *option, const std::string &path, - FileMatcherPointer matcher) - : option(option), path(path), matcher(move(matcher)) - { - } + } - std::string option; - std::string path; - FileMatcherPointer matcher; - }; + std::string option; + std::string path; + FileMatcherPointer matcher; + }; - typedef std::vector OutputFileList; + typedef std::vector OutputFileList; - explicit Impl(TestFileManager *fileManager) - : fileManager_(*fileManager) - { - } + explicit Impl(TestFileManager* fileManager) : fileManager_(*fileManager) {} - TestFileManager &fileManager_; - OutputFileList outputFiles_; + TestFileManager& fileManager_; + OutputFileList outputFiles_; }; /******************************************************************** @@ -300,8 +290,7 @@ class CommandLineTestHelper::Impl */ // static -int CommandLineTestHelper::runModuleDirect( - ICommandLineModule *module, CommandLine *commandLine) +int CommandLineTestHelper::runModuleDirect(ICommandLineModule* module, CommandLine* commandLine) { CommandLineModuleSettings settings; module->init(&settings); @@ -309,8 +298,8 @@ int CommandLineTestHelper::runModuleDirect( } // static -int CommandLineTestHelper::runModuleDirect( - std::unique_ptr module, CommandLine *commandLine) +int CommandLineTestHelper::runModuleDirect(std::unique_ptr module, + CommandLine* commandLine) { // The name and description are not used in the tests, so they can be NULL. const std::unique_ptr wrapperModule( @@ -320,41 +309,41 @@ int CommandLineTestHelper::runModuleDirect( // static int CommandLineTestHelper::runModuleFactory( - const std::function()> &factory, - CommandLine *commandLine) + const std::function()>& factory, + CommandLine* commandLine) { return runModuleDirect(factory(), commandLine); } -CommandLineTestHelper::CommandLineTestHelper(TestFileManager *fileManager) - : impl_(new Impl(fileManager)) +CommandLineTestHelper::CommandLineTestHelper(TestFileManager* fileManager) : + impl_(new Impl(fileManager)) { } -CommandLineTestHelper::~CommandLineTestHelper() -{ -} +CommandLineTestHelper::~CommandLineTestHelper() {} -void CommandLineTestHelper::setInputFileContents( - CommandLine *args, const char *option, const char *extension, - const std::string &contents) +void CommandLineTestHelper::setInputFileContents(CommandLine* args, + const char* option, + const char* extension, + const std::string& contents) { GMX_ASSERT(extension[0] != '.', "Extension should not contain a dot"); - std::string fullFilename = impl_->fileManager_.getTemporaryFilePath( - formatString("%d.%s", args->argc(), extension)); + std::string fullFilename = + impl_->fileManager_.getTemporaryFilePath(formatString("%d.%s", args->argc(), extension)); TextWriter::writeFileFromString(fullFilename, contents); args->addOption(option, fullFilename); } -void CommandLineTestHelper::setInputFileContents( - CommandLine *args, const char *option, const char *extension, - const ArrayRef &contents) +void CommandLineTestHelper::setInputFileContents(CommandLine* args, + const char* option, + const char* extension, + const ArrayRef& contents) { GMX_ASSERT(extension[0] != '.', "Extension should not contain a dot"); - std::string fullFilename = impl_->fileManager_.getTemporaryFilePath( - formatString("%d.%s", args->argc(), extension)); - TextWriter file(fullFilename); - ArrayRef::const_iterator i; + std::string fullFilename = + impl_->fileManager_.getTemporaryFilePath(formatString("%d.%s", args->argc(), extension)); + TextWriter file(fullFilename); + ArrayRef::const_iterator i; for (i = contents.begin(); i != contents.end(); ++i) { file.writeLine(*i); @@ -363,16 +352,18 @@ void CommandLineTestHelper::setInputFileContents( args->addOption(option, fullFilename); } -void CommandLineTestHelper::setOutputFile( - CommandLine *args, const char *option, const char *filename, - const ITextBlockMatcherSettings &matcher) +void CommandLineTestHelper::setOutputFile(CommandLine* args, + const char* option, + const char* filename, + const ITextBlockMatcherSettings& matcher) { setOutputFile(args, option, filename, TextFileMatch(matcher)); } -void CommandLineTestHelper::setOutputFile( - CommandLine *args, const char *option, const char *filename, - const IFileMatcherSettings &matcher) +void CommandLineTestHelper::setOutputFile(CommandLine* args, + const char* option, + const char* filename, + const IFileMatcherSettings& matcher) { std::string suffix(filename); if (startsWith(filename, ".")) @@ -388,12 +379,10 @@ void CommandLineTestHelper::checkOutputFiles(TestReferenceChecker checker) const { if (!impl_->outputFiles_.empty()) { - TestReferenceChecker outputChecker( - checker.checkCompound("OutputFiles", "Files")); - for (const auto &outfile : impl_->outputFiles_) + TestReferenceChecker outputChecker(checker.checkCompound("OutputFiles", "Files")); + for (const auto& outfile : impl_->outputFiles_) { - TestReferenceChecker fileChecker( - outputChecker.checkCompound("File", outfile.option.c_str())); + TestReferenceChecker fileChecker(outputChecker.checkCompound("File", outfile.option.c_str())); outfile.matcher->checkFile(outfile.path, &fileChecker); } } @@ -405,51 +394,39 @@ void CommandLineTestHelper::checkOutputFiles(TestReferenceChecker checker) const class CommandLineTestBase::Impl { - public: - Impl() : helper_(&tempFiles_) - { - cmdline_.append("module"); - } +public: + Impl() : helper_(&tempFiles_) { cmdline_.append("module"); } - TestReferenceData data_; - TestFileManager tempFiles_; - CommandLineTestHelper helper_; - CommandLine cmdline_; + TestReferenceData data_; + TestFileManager tempFiles_; + CommandLineTestHelper helper_; + CommandLine cmdline_; }; /******************************************************************** * CommandLineTestBase */ -CommandLineTestBase::CommandLineTestBase() - : impl_(new Impl) -{ -} +CommandLineTestBase::CommandLineTestBase() : impl_(new Impl) {} -CommandLineTestBase::~CommandLineTestBase() -{ -} +CommandLineTestBase::~CommandLineTestBase() {} -void CommandLineTestBase::setInputFile( - const char *option, const char *filename) +void CommandLineTestBase::setInputFile(const char* option, const char* filename) { impl_->cmdline_.addOption(option, TestFileManager::getInputFilePath(filename)); } -void CommandLineTestBase::setInputFile( - const char *option, const std::string &filename) +void CommandLineTestBase::setInputFile(const char* option, const std::string& filename) { setInputFile(option, filename.c_str()); } -void CommandLineTestBase::setModifiableInputFile( - const char *option, const std::string &filename) +void CommandLineTestBase::setModifiableInputFile(const char* option, const std::string& filename) { setModifiableInputFile(option, filename.c_str()); } -void CommandLineTestBase::setModifiableInputFile( - const char *option, const char *filename) +void CommandLineTestBase::setModifiableInputFile(const char* option, const char* filename) { std::string originalFileName = gmx::test::TestFileManager::getInputFilePath(filename); std::string modifiableFileName = fileManager().getTemporaryFilePath(filename); @@ -457,38 +434,37 @@ void CommandLineTestBase::setModifiableInputFile( impl_->cmdline_.addOption(option, modifiableFileName); } -void CommandLineTestBase::setInputFileContents( - const char *option, const char *extension, const std::string &contents) +void CommandLineTestBase::setInputFileContents(const char* option, + const char* extension, + const std::string& contents) { - impl_->helper_.setInputFileContents(&impl_->cmdline_, option, extension, - contents); + impl_->helper_.setInputFileContents(&impl_->cmdline_, option, extension, contents); } -void CommandLineTestBase::setInputFileContents( - const char *option, const char *extension, - const ArrayRef &contents) +void CommandLineTestBase::setInputFileContents(const char* option, + const char* extension, + const ArrayRef& contents) { - impl_->helper_.setInputFileContents(&impl_->cmdline_, option, extension, - contents); + impl_->helper_.setInputFileContents(&impl_->cmdline_, option, extension, contents); } -void CommandLineTestBase::setOutputFile( - const char *option, const char *filename, - const ITextBlockMatcherSettings &matcher) +void CommandLineTestBase::setOutputFile(const char* option, + const char* filename, + const ITextBlockMatcherSettings& matcher) { impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename, matcher); } -void CommandLineTestBase::setOutputFile( - const char *option, const char *filename, - const IFileMatcherSettings &matcher) +void CommandLineTestBase::setOutputFile(const char* option, + const char* filename, + const IFileMatcherSettings& matcher) { impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename, matcher); } -void CommandLineTestBase::setInputAndOutputFile( - const char *option, const char *filename, - const ITextBlockMatcherSettings &matcher) +void CommandLineTestBase::setInputAndOutputFile(const char* option, + const char* filename, + const ITextBlockMatcherSettings& matcher) { std::string originalFileName = gmx::test::TestFileManager::getInputFilePath(filename); std::string modifiableFileName = fileManager().getTemporaryFilePath(filename); @@ -496,9 +472,9 @@ void CommandLineTestBase::setInputAndOutputFile( impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename, matcher); } -void CommandLineTestBase::setInputAndOutputFile( - const char *option, const char *filename, - const IFileMatcherSettings &matcher) +void CommandLineTestBase::setInputAndOutputFile(const char* option, + const char* filename, + const IFileMatcherSettings& matcher) { std::string originalFileName = gmx::test::TestFileManager::getInputFilePath(filename); std::string modifiableFileName = fileManager().getTemporaryFilePath(filename); @@ -506,12 +482,12 @@ void CommandLineTestBase::setInputAndOutputFile( impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename, matcher); } -CommandLine &CommandLineTestBase::commandLine() +CommandLine& CommandLineTestBase::commandLine() { return impl_->cmdline_; } -TestFileManager &CommandLineTestBase::fileManager() +TestFileManager& CommandLineTestBase::fileManager() { return impl_->tempFiles_; } @@ -521,19 +497,19 @@ TestReferenceChecker CommandLineTestBase::rootChecker() return impl_->data_.rootChecker(); } -void CommandLineTestBase::setDefaultTolerance(const FloatingPointTolerance &tolerance) +void CommandLineTestBase::setDefaultTolerance(const FloatingPointTolerance& tolerance) { impl_->data_.rootChecker().setDefaultTolerance(tolerance); } -void CommandLineTestBase::testWriteHelp(ICommandLineModule *module) +void CommandLineTestBase::testWriteHelp(ICommandLineModule* module) { StringOutputStream stream; TextWriter writer(&stream); CommandLineHelpContext context(&writer, eHelpOutputFormat_Console, nullptr, "test"); context.setModuleDisplayName(formatString("%s %s", "test", module->name())); module->writeHelp(context); - TestReferenceChecker checker(rootChecker()); + TestReferenceChecker checker(rootChecker()); checker.checkTextBlock(stream.toString(), "HelpOutput"); } diff --git a/src/testutils/cmdlinetest.h b/src/testutils/cmdlinetest.h index 4febb0d70e..1c2aa2c867 100644 --- a/src/testutils/cmdlinetest.h +++ b/src/testutils/cmdlinetest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -98,102 +98,102 @@ class TestReferenceChecker; */ class CommandLine { - public: - //! Initializes an empty command-line object. - CommandLine(); - /*! \brief - * Initializes a command-line object from an array. - * - * \param[in] cmdline Array of command-line arguments. - * - * \p cmdline should include the binary name as the first element if - * that is desired in the output. - * - * This constructor is not explicit to make it possible to create a - * CommandLine object directly from a C array. - */ - CommandLine(const ArrayRef &cmdline); - //! \copydoc CommandLine(const ArrayRef &) - CommandLine(const ArrayRef &cmdline); - //! Creates a deep copy of a command-line object. - CommandLine(const CommandLine &other); - ~CommandLine(); +public: + //! Initializes an empty command-line object. + CommandLine(); + /*! \brief + * Initializes a command-line object from an array. + * + * \param[in] cmdline Array of command-line arguments. + * + * \p cmdline should include the binary name as the first element if + * that is desired in the output. + * + * This constructor is not explicit to make it possible to create a + * CommandLine object directly from a C array. + */ + CommandLine(const ArrayRef& cmdline); + //! \copydoc CommandLine(const ArrayRef &) + CommandLine(const ArrayRef& cmdline); + //! Creates a deep copy of a command-line object. + CommandLine(const CommandLine& other); + ~CommandLine(); - /*! \brief - * Initializes a command-line object in-place from an array. - * - * \param[in] cmdline Array of command-line arguments. - * - * \p cmdline should include the binary name as the first element if - * that is desired in the output. - * - * This function does the same as the constructor that takes a - * ArrayRef. Any earlier contents of the object are discarded. - * - * Strong exception safety. - */ - void initFromArray(const ArrayRef &cmdline); + /*! \brief + * Initializes a command-line object in-place from an array. + * + * \param[in] cmdline Array of command-line arguments. + * + * \p cmdline should include the binary name as the first element if + * that is desired in the output. + * + * This function does the same as the constructor that takes a + * ArrayRef. Any earlier contents of the object are discarded. + * + * Strong exception safety. + */ + void initFromArray(const ArrayRef& cmdline); - /*! \brief - * Appends an argument to the command line. - * - * \param[in] arg Argument to append. - * - * Strong exception safety. - */ - void append(const char *arg); - //! Convenience overload taking a std::string. - void append(const std::string &arg) { append(arg.c_str()); } - /*! \brief - * Adds an option to the command line, typically a boolean. - * - * \param[in] name Name of the option to append, which - * should start with "-". - */ - void addOption(const char *name); - /*! \brief - * Adds an option-value pair to the command line. - * - * \param[in] name Name of the option to append, which - * should start with "-". - * \param[in] value Value of the argument to append. - */ - void addOption(const char *name, const char *value); - //! Convenience overload taking a std::string. - void addOption(const char *name, const std::string &value); - //! Overload taking an int. - void addOption(const char *name, int value); - //! Overload taking a double. - void addOption(const char *name, double value); - /*! \brief - * Appends all arguments from \p args to the command line. - * - * If the first argument of \p args does not start with a `-`, it is - * skipped, assuming it is a gmx module name and thus useless. - */ - void merge(const CommandLine &args); + /*! \brief + * Appends an argument to the command line. + * + * \param[in] arg Argument to append. + * + * Strong exception safety. + */ + void append(const char* arg); + //! Convenience overload taking a std::string. + void append(const std::string& arg) { append(arg.c_str()); } + /*! \brief + * Adds an option to the command line, typically a boolean. + * + * \param[in] name Name of the option to append, which + * should start with "-". + */ + void addOption(const char* name); + /*! \brief + * Adds an option-value pair to the command line. + * + * \param[in] name Name of the option to append, which + * should start with "-". + * \param[in] value Value of the argument to append. + */ + void addOption(const char* name, const char* value); + //! Convenience overload taking a std::string. + void addOption(const char* name, const std::string& value); + //! Overload taking an int. + void addOption(const char* name, int value); + //! Overload taking a double. + void addOption(const char* name, double value); + /*! \brief + * Appends all arguments from \p args to the command line. + * + * If the first argument of \p args does not start with a `-`, it is + * skipped, assuming it is a gmx module name and thus useless. + */ + void merge(const CommandLine& args); - //! Returns argc for passing into C-style command-line handling. - int &argc(); - //! Returns argv for passing into C-style command-line handling. - char **argv(); - //! Returns argc for passing into C-style command-line handling. - int argc() const; - //! Returns argv for passing into C-style command-line handling. - const char *const *argv() const; - //! Returns a single argument. - const char *arg(int i) const; + //! Returns argc for passing into C-style command-line handling. + int& argc(); + //! Returns argv for passing into C-style command-line handling. + char** argv(); + //! Returns argc for passing into C-style command-line handling. + int argc() const; + //! Returns argv for passing into C-style command-line handling. + const char* const* argv() const; + //! Returns a single argument. + const char* arg(int i) const; - //! Returns the command line formatted as a single string. - std::string toString() const; + //! Returns the command line formatted as a single string. + std::string toString() const; - //! Whether the command line contains the given option. - bool contains(const char *name) const; + //! Whether the command line contains the given option. + bool contains(const char* name) const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -220,140 +220,140 @@ class CommandLine */ class CommandLineTestHelper { - public: - /*! \brief - * Runs a command-line program that implements ICommandLineModule. - * - * \param[in,out] module Module to run. - * The function does not take ownership. - * \param[in,out] commandLine Command line parameters to pass. - * This is only modified if \p module modifies it. - * \returns The return value of the module. - * \throws unspecified Any exception thrown by the module. - */ - static int - runModuleDirect(ICommandLineModule *module, CommandLine *commandLine); - /*! \brief - * Runs a command-line program that implements - * ICommandLineOptionsModule. - * - * \param[in,out] module Module to run. - * \param[in,out] commandLine Command line parameters to pass. - * This is only modified if \p module modifies it. - * \returns The return value of the module. - * \throws unspecified Any exception thrown by the module. - */ - static int - runModuleDirect(std::unique_ptr module, - CommandLine *commandLine); - /*! \brief - * Runs a command-line program that implements - * ICommandLineOptionsModule. - * - * \param[in] factory Factory method for the module to run. - * \param[in,out] commandLine Command line parameters to pass. - * This is only modified if the module modifies it. - * \returns The return value of the module. - * \throws unspecified Any exception thrown by the factory or the - * module. - */ - static int - runModuleFactory(const std::function()> &factory, - CommandLine *commandLine); +public: + /*! \brief + * Runs a command-line program that implements ICommandLineModule. + * + * \param[in,out] module Module to run. + * The function does not take ownership. + * \param[in,out] commandLine Command line parameters to pass. + * This is only modified if \p module modifies it. + * \returns The return value of the module. + * \throws unspecified Any exception thrown by the module. + */ + static int runModuleDirect(ICommandLineModule* module, CommandLine* commandLine); + /*! \brief + * Runs a command-line program that implements + * ICommandLineOptionsModule. + * + * \param[in,out] module Module to run. + * \param[in,out] commandLine Command line parameters to pass. + * This is only modified if \p module modifies it. + * \returns The return value of the module. + * \throws unspecified Any exception thrown by the module. + */ + static int runModuleDirect(std::unique_ptr module, CommandLine* commandLine); + /*! \brief + * Runs a command-line program that implements + * ICommandLineOptionsModule. + * + * \param[in] factory Factory method for the module to run. + * \param[in,out] commandLine Command line parameters to pass. + * This is only modified if the module modifies it. + * \returns The return value of the module. + * \throws unspecified Any exception thrown by the factory or the + * module. + */ + static int runModuleFactory(const std::function()>& factory, + CommandLine* commandLine); - /*! \brief - * Initializes an instance. - * - * \param fileManager File manager to use for generating temporary - * file names and to track temporary files. - */ - explicit CommandLineTestHelper(TestFileManager *fileManager); - ~CommandLineTestHelper(); + /*! \brief + * Initializes an instance. + * + * \param fileManager File manager to use for generating temporary + * file names and to track temporary files. + */ + explicit CommandLineTestHelper(TestFileManager* fileManager); + ~CommandLineTestHelper(); - /*! \brief - * Generates and sets an input file. - * - * \param[in,out] args CommandLine to which to add the option. - * \param[in] option Option to set. - * \param[in] extension Extension for the file to create. - * \param[in] contents Text to write to the input file. - * - * Creates a temporary file with contents from \p contents, and adds - * \p option to \p args with a value that points to the generated file. - */ - void setInputFileContents(CommandLine *args, const char *option, - const char *extension, - const std::string &contents); - /*! \brief - * Generates and sets an input file. - * - * \param[in,out] args CommandLine to which to add the option. - * \param[in] option Option to set. - * \param[in] extension Extension for the file to create. - * \param[in] contents Text to write to the input file. - * - * Creates a temporary file with contents from \p contents (each array - * entry on its own line), and adds \p option to \p args with a value - * that points to the generated file. - */ - void setInputFileContents(CommandLine *args, const char *option, - const char *extension, - const ArrayRef &contents); - /*! \brief - * Sets an output file parameter and adds it to the set of tested files. - * - * \param[in,out] args CommandLine to which to add the option. - * \param[in] option Option to set. - * \param[in] filename Name of the output file. - * \param[in] matcher Specifies how the contents of the file are - * tested. - * - * This method does the following: - * - Adds \p option to \p args to point a temporary file name - * constructed from \p filename. - * - Makes checkOutputFiles() to check the contents of the file - * against reference data, using \p matcher. - * - Marks the temporary file for removal at test teardown. - * - * \p filename is given to TestTemporaryFileManager to make a unique - * filename for the temporary file. - * If \p filename starts with a dot, a unique number is prefixed (such - * that it is possible to create multiple files with the same extension - * by just specifying the extension for every call of setOutputFile()). - * - * If the output file is needed to trigger some computation, or is - * unconditionally produced by the code under test, but the contents - * are not interesting for the test, use NoContentsMatch as the matcher. - * Note that the existence of the output file is still verified. - */ - void setOutputFile(CommandLine *args, const char *option, - const char *filename, - const ITextBlockMatcherSettings &matcher); - //! \copydoc setOutputFile(CommandLine *, const char *, const char *, const ITextBlockMatcherSettings &) - void setOutputFile(CommandLine *args, const char *option, - const char *filename, - const IFileMatcherSettings &matcher); + /*! \brief + * Generates and sets an input file. + * + * \param[in,out] args CommandLine to which to add the option. + * \param[in] option Option to set. + * \param[in] extension Extension for the file to create. + * \param[in] contents Text to write to the input file. + * + * Creates a temporary file with contents from \p contents, and adds + * \p option to \p args with a value that points to the generated file. + */ + void setInputFileContents(CommandLine* args, + const char* option, + const char* extension, + const std::string& contents); + /*! \brief + * Generates and sets an input file. + * + * \param[in,out] args CommandLine to which to add the option. + * \param[in] option Option to set. + * \param[in] extension Extension for the file to create. + * \param[in] contents Text to write to the input file. + * + * Creates a temporary file with contents from \p contents (each array + * entry on its own line), and adds \p option to \p args with a value + * that points to the generated file. + */ + void setInputFileContents(CommandLine* args, + const char* option, + const char* extension, + const ArrayRef& contents); + /*! \brief + * Sets an output file parameter and adds it to the set of tested files. + * + * \param[in,out] args CommandLine to which to add the option. + * \param[in] option Option to set. + * \param[in] filename Name of the output file. + * \param[in] matcher Specifies how the contents of the file are + * tested. + * + * This method does the following: + * - Adds \p option to \p args to point a temporary file name + * constructed from \p filename. + * - Makes checkOutputFiles() to check the contents of the file + * against reference data, using \p matcher. + * - Marks the temporary file for removal at test teardown. + * + * \p filename is given to TestTemporaryFileManager to make a unique + * filename for the temporary file. + * If \p filename starts with a dot, a unique number is prefixed (such + * that it is possible to create multiple files with the same extension + * by just specifying the extension for every call of setOutputFile()). + * + * If the output file is needed to trigger some computation, or is + * unconditionally produced by the code under test, but the contents + * are not interesting for the test, use NoContentsMatch as the matcher. + * Note that the existence of the output file is still verified. + */ + void setOutputFile(CommandLine* args, + const char* option, + const char* filename, + const ITextBlockMatcherSettings& matcher); + //! \copydoc setOutputFile(CommandLine *, const char *, const char *, const ITextBlockMatcherSettings &) + void setOutputFile(CommandLine* args, + const char* option, + const char* filename, + const IFileMatcherSettings& matcher); - /*! \brief - * Checks output files added with setOutputFile() against reference - * data. - * - * \param checker Reference data root location where the reference - * data is stored. - * - * The file contents are tested verbatim, using direct string - * comparison. The text can be found verbatim in the reference data - * XML files for manual inspection. - * - * Generates non-fatal test failures if some output file contents do - * not match the reference data. - */ - void checkOutputFiles(TestReferenceChecker checker) const; + /*! \brief + * Checks output files added with setOutputFile() against reference + * data. + * + * \param checker Reference data root location where the reference + * data is stored. + * + * The file contents are tested verbatim, using direct string + * comparison. The text can be found verbatim in the reference data + * XML files for manual inspection. + * + * Generates non-fatal test failures if some output file contents do + * not match the reference data. + */ + void checkOutputFiles(TestReferenceChecker checker) const; - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; /*! \libinternal \brief @@ -374,125 +374,121 @@ class CommandLineTestHelper */ class CommandLineTestBase : public ::testing::Test { - public: - CommandLineTestBase(); - ~CommandLineTestBase() override; +public: + CommandLineTestBase(); + ~CommandLineTestBase() override; - /*! \brief - * Sets an input file. - * - * \param[in] option Option to set. - * \param[in] filename Name of the input file. - * - * \see TestFileManager::getInputFilePath() - */ - void setInputFile(const char *option, const char *filename); - //! \copydoc setInputFile(const char *, const char *); - void setInputFile(const char *option, const std::string &filename); - /*! \brief - * Sets an input file that may be modified. The file is copied to a - * temporary file, which is used as the test input - * - * \param[in] option Option to set. - * \param[in] filename Name of the input file. - * - */ - void setModifiableInputFile(const char *option, const char *filename); - //! \copydoc setModifiableInputFile(const char *, const char *); - void setModifiableInputFile(const char *option, const std::string &filename); - /*! \brief - * Generates and sets an input file. - * - * \see CommandLineTestHelper::setInputFileContents() - */ - void setInputFileContents(const char *option, - const char *extension, - const std::string &contents); - /*! \brief - * Generates and sets an input file. - * - * \see CommandLineTestHelper::setInputFileContents() - */ - void setInputFileContents(const char *option, - const char *extension, - const ArrayRef &contents); - /*! \brief - * Sets an output file parameter and adds it to the set of tested files. - * - * \see CommandLineTestHelper::setOutputFile() - */ - void setOutputFile(const char *option, const char *filename, - const ITextBlockMatcherSettings &matcher); - /*! \brief - * Sets an output file parameter and adds it to the set of tested files. - * - * \see CommandLineTestHelper::setOutputFile() - */ - void setOutputFile(const char *option, const char *filename, - const IFileMatcherSettings &matcher); - /*! \brief - * Sets a file parameter that is used for input and modified as output. The input file - * is copied to a temporary file that is used as input and can be modified. - */ - void setInputAndOutputFile(const char *option, const char *filename, - const ITextBlockMatcherSettings &matcher); - //! \copydoc setInputAndOutputFile(const char *, const char *, const ITextBlockMatcherSettings&); - void setInputAndOutputFile(const char *option, const char *filename, - const IFileMatcherSettings &matcher); + /*! \brief + * Sets an input file. + * + * \param[in] option Option to set. + * \param[in] filename Name of the input file. + * + * \see TestFileManager::getInputFilePath() + */ + void setInputFile(const char* option, const char* filename); + //! \copydoc setInputFile(const char *, const char *); + void setInputFile(const char* option, const std::string& filename); + /*! \brief + * Sets an input file that may be modified. The file is copied to a + * temporary file, which is used as the test input + * + * \param[in] option Option to set. + * \param[in] filename Name of the input file. + * + */ + void setModifiableInputFile(const char* option, const char* filename); + //! \copydoc setModifiableInputFile(const char *, const char *); + void setModifiableInputFile(const char* option, const std::string& filename); + /*! \brief + * Generates and sets an input file. + * + * \see CommandLineTestHelper::setInputFileContents() + */ + void setInputFileContents(const char* option, const char* extension, const std::string& contents); + /*! \brief + * Generates and sets an input file. + * + * \see CommandLineTestHelper::setInputFileContents() + */ + void setInputFileContents(const char* option, + const char* extension, + const ArrayRef& contents); + /*! \brief + * Sets an output file parameter and adds it to the set of tested files. + * + * \see CommandLineTestHelper::setOutputFile() + */ + void setOutputFile(const char* option, const char* filename, const ITextBlockMatcherSettings& matcher); + /*! \brief + * Sets an output file parameter and adds it to the set of tested files. + * + * \see CommandLineTestHelper::setOutputFile() + */ + void setOutputFile(const char* option, const char* filename, const IFileMatcherSettings& matcher); + /*! \brief + * Sets a file parameter that is used for input and modified as output. The input file + * is copied to a temporary file that is used as input and can be modified. + */ + void setInputAndOutputFile(const char* option, + const char* filename, + const ITextBlockMatcherSettings& matcher); + //! \copydoc setInputAndOutputFile(const char *, const char *, const ITextBlockMatcherSettings&); + void setInputAndOutputFile(const char* option, const char* filename, const IFileMatcherSettings& matcher); - /*! \brief - * Returns the internal CommandLine object used to construct the - * command line for the test. - * - * Derived test fixtures can use this to add additional options, and - * to access the final command line to do the actual call that is being - * tested. - * - * Does not throw. - */ - CommandLine &commandLine(); - /*! \brief - * Returns the internal TestFileManager object used to manage the - * files. - * - * Derived test fixtures can use this to manage files in cases the - * canned methods are not sufficient. - * - * Does not throw. - */ - TestFileManager &fileManager(); - /*! \brief - * Returns the root reference data checker. - * - * Derived test fixtures can use this to check other things than output - * file contents. - */ - TestReferenceChecker rootChecker(); - /*! \brief - * Sets the tolerance for floating-point comparisons. - * - * All following floating-point comparisons using the checker will use - * the new tolerance. - * - * Does not throw. - */ - void setDefaultTolerance(const FloatingPointTolerance &tolerance); - /*! \brief - * Checks the output of writeHelp() against reference data. - */ - void testWriteHelp(ICommandLineModule *module); - /*! \brief - * Checks output files added with setOutputFile() against reference - * data. - * - * \see CommandLineTestHelper::checkOutputFiles() - */ - void checkOutputFiles(); + /*! \brief + * Returns the internal CommandLine object used to construct the + * command line for the test. + * + * Derived test fixtures can use this to add additional options, and + * to access the final command line to do the actual call that is being + * tested. + * + * Does not throw. + */ + CommandLine& commandLine(); + /*! \brief + * Returns the internal TestFileManager object used to manage the + * files. + * + * Derived test fixtures can use this to manage files in cases the + * canned methods are not sufficient. + * + * Does not throw. + */ + TestFileManager& fileManager(); + /*! \brief + * Returns the root reference data checker. + * + * Derived test fixtures can use this to check other things than output + * file contents. + */ + TestReferenceChecker rootChecker(); + /*! \brief + * Sets the tolerance for floating-point comparisons. + * + * All following floating-point comparisons using the checker will use + * the new tolerance. + * + * Does not throw. + */ + void setDefaultTolerance(const FloatingPointTolerance& tolerance); + /*! \brief + * Checks the output of writeHelp() against reference data. + */ + void testWriteHelp(ICommandLineModule* module); + /*! \brief + * Checks output files added with setOutputFile() against reference + * data. + * + * \see CommandLineTestHelper::checkOutputFiles() + */ + void checkOutputFiles(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/testutils/conftest.cpp b/src/testutils/conftest.cpp index dccc71fbf1..e7be0564a9 100644 --- a/src/testutils/conftest.cpp +++ b/src/testutils/conftest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -65,30 +65,26 @@ namespace class ConfMatcher : public ITextBlockMatcher { - public: - explicit ConfMatcher(const ConfMatchSettings &settings) : settings_(settings) - { - } +public: + explicit ConfMatcher(const ConfMatchSettings& settings) : settings_(settings) {} - void checkStream(TextInputStream *stream, - TestReferenceChecker *checker) override - { - checkConfFile(stream, checker, settings_); - } - private: - ConfMatchSettings settings_; + void checkStream(TextInputStream* stream, TestReferenceChecker* checker) override + { + checkConfFile(stream, checker, settings_); + } + +private: + ConfMatchSettings settings_; }; -} // namespace +} // namespace -void checkConfFile(TextInputStream *input, - TestReferenceChecker *checker, - const ConfMatchSettings & /*unused*/) +void checkConfFile(TextInputStream* input, TestReferenceChecker* checker, const ConfMatchSettings& /*unused*/) { TestReferenceChecker groChecker(checker->checkCompound("GroFile", "Header")); // Just check the first two lines of the output file - std::string line; + std::string line; EXPECT_TRUE(input->readLine(&line)); line = stripSuffixIfPresent(line, "\n"); groChecker.checkString(line, "Title"); diff --git a/src/testutils/conftest.h b/src/testutils/conftest.h index 5c388aba42..c8c7c14dc3 100644 --- a/src/testutils/conftest.h +++ b/src/testutils/conftest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,11 +60,9 @@ class TestReferenceChecker; struct ConfMatchSettings { - ConfMatchSettings() : tolerance(defaultRealTolerance()) - { - } + ConfMatchSettings() : tolerance(defaultRealTolerance()) {} - FloatingPointTolerance tolerance; + FloatingPointTolerance tolerance; }; /*! \brief @@ -79,9 +77,7 @@ struct ConfMatchSettings * * \see ConfMatch */ -void checkConfFile(TextInputStream *input, - TestReferenceChecker *checker, - const ConfMatchSettings &settings); +void checkConfFile(TextInputStream* input, TestReferenceChecker* checker, const ConfMatchSettings& settings); /*! \libinternal \brief * Match the contents as an gro file. @@ -93,18 +89,18 @@ void checkConfFile(TextInputStream *input, */ class ConfMatch : public ITextBlockMatcherSettings { - public: - //! Sets the tolerance for matching floating point values. - ConfMatch &tolerance(const FloatingPointTolerance &tolerance) - { - settings_.tolerance = tolerance; - return *this; - } +public: + //! Sets the tolerance for matching floating point values. + ConfMatch& tolerance(const FloatingPointTolerance& tolerance) + { + settings_.tolerance = tolerance; + return *this; + } - TextBlockMatcherPointer createMatcher() const override; + TextBlockMatcherPointer createMatcher() const override; - private: - ConfMatchSettings settings_; +private: + ConfMatchSettings settings_; }; } // namespace test diff --git a/src/testutils/filematchers.cpp b/src/testutils/filematchers.cpp index 27c011a6c1..d836f4e6fc 100644 --- a/src/testutils/filematchers.cpp +++ b/src/testutils/filematchers.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,33 +57,25 @@ namespace class TextFileMatcher : public IFileMatcher { - public: - explicit TextFileMatcher(TextBlockMatcherPointer matcher) - : matcher_(std::move(matcher)) - { - } +public: + explicit TextFileMatcher(TextBlockMatcherPointer matcher) : matcher_(std::move(matcher)) {} - void checkFile(const std::string &path, - TestReferenceChecker *checker) override - { - TextInputFile stream(path); - matcher_->checkStream(&stream, checker); - stream.close(); - } + void checkFile(const std::string& path, TestReferenceChecker* checker) override + { + TextInputFile stream(path); + matcher_->checkStream(&stream, checker); + stream.close(); + } - private: - TextBlockMatcherPointer matcher_; +private: + TextBlockMatcherPointer matcher_; }; -} // namespace +} // namespace -IFileMatcher::~IFileMatcher() -{ -} +IFileMatcher::~IFileMatcher() {} -IFileMatcherSettings::~IFileMatcherSettings() -{ -} +IFileMatcherSettings::~IFileMatcherSettings() {} FileMatcherPointer TextFileMatch::createFileMatcher() const { diff --git a/src/testutils/filematchers.h b/src/testutils/filematchers.h index cc628ed487..84201794a5 100644 --- a/src/testutils/filematchers.h +++ b/src/testutils/filematchers.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2017,2018, by the GROMACS development team, led by + * Copyright (c) 2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,22 +74,21 @@ class TestReferenceChecker; */ class IFileMatcher { - public: - virtual ~IFileMatcher(); +public: + virtual ~IFileMatcher(); - /*! \brief - * Matches contents of a file. - * - * \param path Path to the file to match. - * \param checker Checker to use for matching. - * - * The method can change the state of the provided checker (e.g., by - * changing the default tolerance). - * The caller is responsible of providing a checker where such state - * changes do not matter. - */ - virtual void checkFile(const std::string &path, - TestReferenceChecker *checker) = 0; + /*! \brief + * Matches contents of a file. + * + * \param path Path to the file to match. + * \param checker Checker to use for matching. + * + * The method can change the state of the provided checker (e.g., by + * changing the default tolerance). + * The caller is responsible of providing a checker where such state + * changes do not matter. + */ + virtual void checkFile(const std::string& path, TestReferenceChecker* checker) = 0; }; //! Smart pointer for managing a IFileMatcher. @@ -109,12 +108,12 @@ typedef std::unique_ptr FileMatcherPointer; */ class IFileMatcherSettings { - public: - //! Factory method that constructs the matcher after parameters are set. - virtual FileMatcherPointer createFileMatcher() const = 0; +public: + //! Factory method that constructs the matcher after parameters are set. + virtual FileMatcherPointer createFileMatcher() const = 0; - protected: - virtual ~IFileMatcherSettings(); +protected: + virtual ~IFileMatcherSettings(); }; /*! \libinternal \brief @@ -125,17 +124,17 @@ class IFileMatcherSettings */ class TextFileMatch : public IFileMatcherSettings { - public: - //! Creates a matcher to match contents with given text matcher. - explicit TextFileMatch(const ITextBlockMatcherSettings &streamSettings) - : streamSettings_(streamSettings) - { - } +public: + //! Creates a matcher to match contents with given text matcher. + explicit TextFileMatch(const ITextBlockMatcherSettings& streamSettings) : + streamSettings_(streamSettings) + { + } - FileMatcherPointer createFileMatcher() const override; + FileMatcherPointer createFileMatcher() const override; - private: - const ITextBlockMatcherSettings &streamSettings_; +private: + const ITextBlockMatcherSettings& streamSettings_; }; /*! \libinternal \brief @@ -146,8 +145,8 @@ class TextFileMatch : public IFileMatcherSettings */ class NoContentsMatch : public IFileMatcherSettings { - public: - FileMatcherPointer createFileMatcher() const override; +public: + FileMatcherPointer createFileMatcher() const override; }; } // namespace test diff --git a/src/testutils/interactivetest.cpp b/src/testutils/interactivetest.cpp index 5874e9dc91..897a01660e 100644 --- a/src/testutils/interactivetest.cpp +++ b/src/testutils/interactivetest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -68,107 +68,104 @@ namespace test class MockTextInputStream : public TextInputStream { - public: - MOCK_METHOD1(readLine, bool(std::string *)); - MOCK_METHOD0(close, void()); +public: + MOCK_METHOD1(readLine, bool(std::string*)); + MOCK_METHOD0(close, void()); }; class MockTextOutputStream : public TextOutputStream { - public: - MOCK_METHOD1(write, void(const char *)); - MOCK_METHOD0(close, void()); +public: + MOCK_METHOD1(write, void(const char*)); + MOCK_METHOD0(close, void()); }; class InteractiveTestHelper::Impl { - public: - explicit Impl(TestReferenceChecker checker) - : checker_(std::move(checker)), bLastNewline_(true), - currentLine_(0), bHasOutput_(false) +public: + explicit Impl(TestReferenceChecker checker) : + checker_(std::move(checker)), + bLastNewline_(true), + currentLine_(0), + bHasOutput_(false) + { + using ::testing::_; + using ::testing::Invoke; + EXPECT_CALL(inputStream_, readLine(_)).WillRepeatedly(Invoke(this, &Impl::readInputLine)); + EXPECT_CALL(inputStream_, close()).Times(0); + EXPECT_CALL(outputStream_, write(_)).WillRepeatedly(Invoke(this, &Impl::addOutput)); + EXPECT_CALL(outputStream_, close()).Times(0); + } + + bool readInputLine(std::string* line) + { + checkOutput(); + line->clear(); + const bool bPresent = (currentLine_ < index(inputLines_.size())); + if (bPresent) { - using ::testing::_; - using ::testing::Invoke; - EXPECT_CALL(inputStream_, readLine(_)) - .WillRepeatedly(Invoke(this, &Impl::readInputLine)); - EXPECT_CALL(inputStream_, close()).Times(0); - EXPECT_CALL(outputStream_, write(_)) - .WillRepeatedly(Invoke(this, &Impl::addOutput)); - EXPECT_CALL(outputStream_, close()).Times(0); - } - - bool readInputLine(std::string *line) - { - checkOutput(); - line->clear(); - const bool bPresent = (currentLine_ < index(inputLines_.size())); - if (bPresent) + line->assign(inputLines_[currentLine_]); + if (bLastNewline_ || currentLine_ + 1 < index(inputLines_.size())) { - line->assign(inputLines_[currentLine_]); - if (bLastNewline_ || currentLine_ + 1 < index(inputLines_.size())) - { - line->append("\n"); - } + line->append("\n"); } - ++currentLine_; - const std::string id = formatString("Input%d", static_cast(currentLine_)); - StringTestBase::checkText(&checker_, *line, id.c_str()); - return bPresent; } - void addOutput(const char *str) + ++currentLine_; + const std::string id = formatString("Input%d", static_cast(currentLine_)); + StringTestBase::checkText(&checker_, *line, id.c_str()); + return bPresent; + } + void addOutput(const char* str) + { + bHasOutput_ = true; + currentOutput_.append(str); + } + + void checkOutput() + { + if (bHasOutput_) { - bHasOutput_ = true; - currentOutput_.append(str); + const std::string id = formatString("Output%d", static_cast(currentLine_)); + StringTestBase::checkText(&checker_, currentOutput_, id.c_str()); + bHasOutput_ = false; } - - void checkOutput() - { - if (bHasOutput_) - { - const std::string id = formatString("Output%d", static_cast(currentLine_)); - StringTestBase::checkText(&checker_, currentOutput_, id.c_str()); - bHasOutput_ = false; - } - currentOutput_.clear(); - } - - TestReferenceChecker checker_; - ArrayRef inputLines_; - bool bLastNewline_; - index currentLine_; - bool bHasOutput_; - std::string currentOutput_; - MockTextInputStream inputStream_; - MockTextOutputStream outputStream_; + currentOutput_.clear(); + } + + TestReferenceChecker checker_; + ArrayRef inputLines_; + bool bLastNewline_; + index currentLine_; + bool bHasOutput_; + std::string currentOutput_; + MockTextInputStream inputStream_; + MockTextOutputStream outputStream_; }; -InteractiveTestHelper::InteractiveTestHelper(TestReferenceChecker checker) - : impl_(new Impl(checker.checkCompound("InteractiveSession", "Interactive"))) +InteractiveTestHelper::InteractiveTestHelper(TestReferenceChecker checker) : + impl_(new Impl(checker.checkCompound("InteractiveSession", "Interactive"))) { } -InteractiveTestHelper::~InteractiveTestHelper() -{ -} +InteractiveTestHelper::~InteractiveTestHelper() {} void InteractiveTestHelper::setLastNewline(bool bInclude) { impl_->bLastNewline_ = bInclude; } -void InteractiveTestHelper::setInputLines( - const ArrayRef &inputLines) +void InteractiveTestHelper::setInputLines(const ArrayRef& inputLines) { impl_->inputLines_ = inputLines; impl_->currentLine_ = 0; } -TextInputStream &InteractiveTestHelper::inputStream() +TextInputStream& InteractiveTestHelper::inputStream() { return impl_->inputStream_; } -TextOutputStream &InteractiveTestHelper::outputStream() +TextOutputStream& InteractiveTestHelper::outputStream() { return impl_->outputStream_; } diff --git a/src/testutils/interactivetest.h b/src/testutils/interactivetest.h index 11d96862cd..6e0e279deb 100644 --- a/src/testutils/interactivetest.h +++ b/src/testutils/interactivetest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,51 +74,51 @@ class TestReferenceChecker; */ class InteractiveTestHelper { - public: - /*! \brief - * Initializes the helper. - * - * \param[in] checker Parent reference checker to use. - * - * The helper creates a compound item under \p checker for the - * interactive session it tests. - */ - explicit InteractiveTestHelper(gmx::test::TestReferenceChecker checker); - ~InteractiveTestHelper(); +public: + /*! \brief + * Initializes the helper. + * + * \param[in] checker Parent reference checker to use. + * + * The helper creates a compound item under \p checker for the + * interactive session it tests. + */ + explicit InteractiveTestHelper(gmx::test::TestReferenceChecker checker); + ~InteractiveTestHelper(); - //! Sets whether the last input line contains a newline (by default, it does). - void setLastNewline(bool bInclude); - /*! \brief - * Sets the input lines for the interactive session. - * - * Calls to TextInputStream::readLine() will return strings from this - * array in sequence. - * Newlines are added at the end automatically (except for the last - * line if `setLastNewLine(false)` has been called). - * If there are more `readLine()` calls than there are input lines, - * the remaining calls return end-of-input. - */ - void setInputLines(const ArrayRef &inputLines); + //! Sets whether the last input line contains a newline (by default, it does). + void setLastNewline(bool bInclude); + /*! \brief + * Sets the input lines for the interactive session. + * + * Calls to TextInputStream::readLine() will return strings from this + * array in sequence. + * Newlines are added at the end automatically (except for the last + * line if `setLastNewLine(false)` has been called). + * If there are more `readLine()` calls than there are input lines, + * the remaining calls return end-of-input. + */ + void setInputLines(const ArrayRef& inputLines); - //! Returns the input stream for the session. - TextInputStream &inputStream(); - //! Returns the output stream for the session. - TextOutputStream &outputStream(); + //! Returns the input stream for the session. + TextInputStream& inputStream(); + //! Returns the output stream for the session. + TextOutputStream& outputStream(); - /*! \brief - * Finalizes the checking for the session. - * - * This must be called after all input and output from a session has - * occurred, as the helper will not otherwise know when output after - * the last input has finished. This method also checks that the - * required number of input lines were read in the session. - */ - void checkSession(); + /*! \brief + * Finalizes the checking for the session. + * + * This must be called after all input and output from a session has + * occurred, as the helper will not otherwise know when output after + * the last input has finished. This method also checks that the + * required number of input lines were read in the session. + */ + void checkSession(); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace test } // namespace gmx diff --git a/src/testutils/loggertest.cpp b/src/testutils/loggertest.cpp index 7d3076e7bd..c090c3b2f7 100644 --- a/src/testutils/loggertest.cpp +++ b/src/testutils/loggertest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -59,10 +59,10 @@ namespace { class MockLogTarget : public ILogTarget { - public: - MOCK_METHOD1(writeEntry, void(const LogEntry &)); +public: + MOCK_METHOD1(writeEntry, void(const LogEntry&)); }; -} // namespace +} // namespace /******************************************************************** * LoggerTestHelper::Impl @@ -70,47 +70,41 @@ class MockLogTarget : public ILogTarget class LoggerTestHelper::Impl { - public: - Impl() - { - // TODO: Add support for -stdout for echoing the log to stdout. - logger_.warning = LogLevelHelper(&getTarget(MDLogger::LogLevel::Warning)); - logger_.info = LogLevelHelper(&getTarget(MDLogger::LogLevel::Info)); - } - - NiceMock &getTarget(MDLogger::LogLevel level) - { - return targets_[static_cast(level)]; - } - - NiceMock targets_[MDLogger::LogLevelCount]; - MDLogger logger_; +public: + Impl() + { + // TODO: Add support for -stdout for echoing the log to stdout. + logger_.warning = LogLevelHelper(&getTarget(MDLogger::LogLevel::Warning)); + logger_.info = LogLevelHelper(&getTarget(MDLogger::LogLevel::Info)); + } + + NiceMock& getTarget(MDLogger::LogLevel level) + { + return targets_[static_cast(level)]; + } + + NiceMock targets_[MDLogger::LogLevelCount]; + MDLogger logger_; }; /******************************************************************** * LoggerTestHelper */ -LoggerTestHelper::LoggerTestHelper() - : impl_(new Impl) -{ -} +LoggerTestHelper::LoggerTestHelper() : impl_(new Impl) {} -LoggerTestHelper::~LoggerTestHelper() -{ -} +LoggerTestHelper::~LoggerTestHelper() {} -const MDLogger &LoggerTestHelper::logger() +const MDLogger& LoggerTestHelper::logger() { return impl_->logger_; } -void LoggerTestHelper::expectEntryMatchingRegex(gmx::MDLogger::LogLevel level, - const char *re) +void LoggerTestHelper::expectEntryMatchingRegex(gmx::MDLogger::LogLevel level, const char* re) { using ::testing::ContainsRegex; using ::testing::Field; - auto &target = impl_->getTarget(level); + auto& target = impl_->getTarget(level); EXPECT_CALL(target, writeEntry(Field(&LogEntry::text, ContainsRegex(re)))); } diff --git a/src/testutils/loggertest.h b/src/testutils/loggertest.h index 1fc4fbfa0f..5fe63949ce 100644 --- a/src/testutils/loggertest.h +++ b/src/testutils/loggertest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2017, by the GROMACS development team, led by + * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,30 +60,29 @@ namespace test */ class LoggerTestHelper { - public: - LoggerTestHelper(); - ~LoggerTestHelper(); +public: + LoggerTestHelper(); + ~LoggerTestHelper(); - //! Returns the logger to pass to code under test. - const MDLogger &logger(); + //! Returns the logger to pass to code under test. + const MDLogger& logger(); - /*! \brief - * Expects a log entry at a given level matching a given regex. - * - * Currently, the order of the entries is not checked, and if this - * method is called once for a log level, then it needs to be called - * for all entries produced by the test. - * - * If not called for a log level, all entries for that level are - * accepted. - */ - void expectEntryMatchingRegex(gmx::MDLogger::LogLevel level, - const char *re); + /*! \brief + * Expects a log entry at a given level matching a given regex. + * + * Currently, the order of the entries is not checked, and if this + * method is called once for a log level, then it needs to be called + * for all entries produced by the test. + * + * If not called for a log level, all entries for that level are + * accepted. + */ + void expectEntryMatchingRegex(gmx::MDLogger::LogLevel level, const char* re); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/testutils/mpi_printer.cpp b/src/testutils/mpi_printer.cpp index a193d12763..15778e154f 100644 --- a/src/testutils/mpi_printer.cpp +++ b/src/testutils/mpi_printer.cpp @@ -42,65 +42,71 @@ #if GMX_LIB_MPI -#include -#include -#include - -#include - -#include "gromacs/utility/classhelpers.h" -#include "gromacs/utility/gmxassert.h" - -#define FORWARD_TO_DEFAULT_PRINTER1(MethodName, Param1Type) \ - virtual void MethodName(const Param1Type ¶m1) { \ - if (rank_ == 0) { \ - defaultPrinter_->MethodName(param1); \ - } \ - } -#define FORWARD_TO_DEFAULT_PRINTER2(MethodName, Param1Type, Param2Type) \ - virtual void MethodName(const Param1Type ¶m1, Param2Type param2) { \ - if (rank_ == 0) { \ - defaultPrinter_->MethodName(param1, param2); \ - } \ - } +# include +# include +# include + +# include + +# include "gromacs/utility/classhelpers.h" +# include "gromacs/utility/gmxassert.h" + +# define FORWARD_TO_DEFAULT_PRINTER1(MethodName, Param1Type) \ + virtual void MethodName(const Param1Type& param1) \ + { \ + if (rank_ == 0) \ + { \ + defaultPrinter_->MethodName(param1); \ + } \ + } +# define FORWARD_TO_DEFAULT_PRINTER2(MethodName, Param1Type, Param2Type) \ + virtual void MethodName(const Param1Type& param1, Param2Type param2) \ + { \ + if (rank_ == 0) \ + { \ + defaultPrinter_->MethodName(param1, param2); \ + } \ + } namespace { class MPIEventForward : public ::testing::TestEventListener { - public: - MPIEventForward(TestEventListener* defaultPrinter, int rank, int size) - : defaultPrinter_(defaultPrinter), rank_(rank), size_(size) - { - } +public: + MPIEventForward(TestEventListener* defaultPrinter, int rank, int size) : + defaultPrinter_(defaultPrinter), + rank_(rank), + size_(size) + { + } - FORWARD_TO_DEFAULT_PRINTER1(OnTestProgramStart, ::testing::UnitTest); - FORWARD_TO_DEFAULT_PRINTER2(OnTestIterationStart, ::testing::UnitTest, int); - FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsSetUpStart, ::testing::UnitTest); - FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsSetUpEnd, ::testing::UnitTest); - FORWARD_TO_DEFAULT_PRINTER1(OnTestCaseStart, ::testing::TestCase); - FORWARD_TO_DEFAULT_PRINTER1(OnTestStart, ::testing::TestInfo); - virtual void OnTestPartResult(const ::testing::TestPartResult & /*result*/) - { - // Do nothing; all printing is done in OnTestEnd(). - } - virtual void OnTestEnd(const ::testing::TestInfo &test_info); - FORWARD_TO_DEFAULT_PRINTER1(OnTestCaseEnd, ::testing::TestCase); - FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsTearDownStart, ::testing::UnitTest); - FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsTearDownEnd, ::testing::UnitTest); - FORWARD_TO_DEFAULT_PRINTER2(OnTestIterationEnd, ::testing::UnitTest, int); - FORWARD_TO_DEFAULT_PRINTER1(OnTestProgramEnd, ::testing::UnitTest); - - private: - const std::unique_ptr defaultPrinter_; - int rank_; - int size_; - - GMX_DISALLOW_COPY_AND_ASSIGN(MPIEventForward); + FORWARD_TO_DEFAULT_PRINTER1(OnTestProgramStart, ::testing::UnitTest); + FORWARD_TO_DEFAULT_PRINTER2(OnTestIterationStart, ::testing::UnitTest, int); + FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsSetUpStart, ::testing::UnitTest); + FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsSetUpEnd, ::testing::UnitTest); + FORWARD_TO_DEFAULT_PRINTER1(OnTestCaseStart, ::testing::TestCase); + FORWARD_TO_DEFAULT_PRINTER1(OnTestStart, ::testing::TestInfo); + virtual void OnTestPartResult(const ::testing::TestPartResult& /*result*/) + { + // Do nothing; all printing is done in OnTestEnd(). + } + virtual void OnTestEnd(const ::testing::TestInfo& test_info); + FORWARD_TO_DEFAULT_PRINTER1(OnTestCaseEnd, ::testing::TestCase); + FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsTearDownStart, ::testing::UnitTest); + FORWARD_TO_DEFAULT_PRINTER1(OnEnvironmentsTearDownEnd, ::testing::UnitTest); + FORWARD_TO_DEFAULT_PRINTER2(OnTestIterationEnd, ::testing::UnitTest, int); + FORWARD_TO_DEFAULT_PRINTER1(OnTestProgramEnd, ::testing::UnitTest); + +private: + const std::unique_ptr defaultPrinter_; + int rank_; + int size_; + + GMX_DISALLOW_COPY_AND_ASSIGN(MPIEventForward); }; -void MPIEventForward::OnTestEnd(const ::testing::TestInfo &test_info) +void MPIEventForward::OnTestEnd(const ::testing::TestInfo& test_info) { // Serialize printing test results to stdout in rank order by // passing a flag in order from ranks 0 .. (n-1). Rank 0 does not @@ -112,8 +118,8 @@ void MPIEventForward::OnTestEnd(const ::testing::TestInfo &test_info) } // Now this rank can print - int localPassed = true; - const ::testing::TestResult *result = test_info.result(); + int localPassed = true; + const ::testing::TestResult* result = test_info.result(); if (result->Failed()) { // TODO: This sometimes races with the defaultPrinter_, but @@ -167,12 +173,11 @@ void MPIEventForward::OnTestEnd(const ::testing::TestInfo &test_info) // This marks the current test failed, and modifies test_info // behind the scenes, so the default printer sees the test as // failed even if localPassed is true. - ADD_FAILURE() << - "See AllFailingRanks for the rank IDs that failed. Only if " - "rank 0 was among those that failed, will there be some " - "accompanying information about the failure, and it will " - "pertain only to that rank. Run this test manually to get " - "more information."; + ADD_FAILURE() << "See AllFailingRanks for the rank IDs that failed. Only if " + "rank 0 was among those that failed, will there be some " + "accompanying information about the failure, and it will " + "pertain only to that rank. Run this test manually to get " + "more information."; } } } @@ -193,17 +198,16 @@ void gmx::test::initMPIOutput() return; } MPI_Comm_rank(MPI_COMM_WORLD, &rank); - ::testing::UnitTest &unit_test = *::testing::UnitTest::GetInstance(); - ::testing::TestEventListeners &listeners = unit_test.listeners(); - ::testing::TestEventListener *defprinter = - listeners.Release(listeners.default_result_printer()); + ::testing::UnitTest& unit_test = *::testing::UnitTest::GetInstance(); + ::testing::TestEventListeners& listeners = unit_test.listeners(); + ::testing::TestEventListener* defprinter = listeners.Release(listeners.default_result_printer()); listeners.Append(new MPIEventForward(defprinter, rank, size)); if (0 != rank) { /* Permit only rank 0 to write to the single GTest XML file, by removing the generator on the other ranks. This suppresses races when writing that file. */ - ::testing::TestEventListener *oldlistener = listeners.Release(listeners.default_xml_generator()); + ::testing::TestEventListener* oldlistener = listeners.Release(listeners.default_xml_generator()); delete oldlistener; } #endif diff --git a/src/testutils/mpitest.cpp b/src/testutils/mpitest.cpp index 198b55c115..63b04b9ce6 100644 --- a/src/testutils/mpitest.cpp +++ b/src/testutils/mpitest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016,2018, by the GROMACS development team, led by + * Copyright (c) 2016,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -71,15 +71,15 @@ int g_numThreads = 1; //! \cond GMX_TEST_OPTIONS(ThreadMpiTestOptions, options) { - options->addOption(IntegerOption("ntmpi").store(&g_numThreads) - .description("Number of thread-MPI threads/ranks for the test")); + options->addOption( + IntegerOption("ntmpi").store(&g_numThreads).description("Number of thread-MPI threads/ranks for the test")); } //! \endcond //! Thread entry function for other thread-MPI threads. -void threadStartFunc(const void *data) +void threadStartFunc(const void* data) { - const std::function &testBody = *reinterpret_cast *>(data); + const std::function& testBody = *reinterpret_cast*>(data); try { testBody(); @@ -88,24 +88,23 @@ void threadStartFunc(const void *data) } //! Helper function for starting thread-MPI threads for a test. -bool startThreads(std::function *testBody) +bool startThreads(std::function* testBody) { - int ret = tMPI_Init_fn(TRUE, g_numThreads, TMPI_AFFINITY_NONE, - threadStartFunc, testBody); + int ret = tMPI_Init_fn(TRUE, g_numThreads, TMPI_AFFINITY_NONE, threadStartFunc, testBody); return ret == TMPI_SUCCESS; } class InTestGuard { - public: - explicit InTestGuard(bool *inTest) : inTest_(inTest) { *inTest = true; } - ~InTestGuard() { *inTest_ = false; } +public: + explicit InTestGuard(bool* inTest) : inTest_(inTest) { *inTest = true; } + ~InTestGuard() { *inTest_ = false; } - private: - bool *inTest_; +private: + bool* inTest_; }; -} // namespace +} // namespace //! \cond internal bool threadMpiTestRunner(std::function testBody) @@ -116,11 +115,10 @@ bool threadMpiTestRunner(std::function testBody) { return true; } -#if GMX_THREAD_MPI && !defined(GTEST_IS_THREADSAFE) - ADD_FAILURE() - << "Google Test is not thread safe on this platform. " - << "Cannot run multi-rank tests with thread-MPI."; -#else +# if GMX_THREAD_MPI && !defined(GTEST_IS_THREADSAFE) + ADD_FAILURE() << "Google Test is not thread safe on this platform. " + << "Cannot run multi-rank tests with thread-MPI."; +# else InTestGuard guard(&inTest); if (!startThreads(&testBody)) { @@ -132,7 +130,7 @@ bool threadMpiTestRunner(std::function testBody) } GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR; tMPI_Finalize(); -#endif +# endif return false; } //! \endcond diff --git a/src/testutils/mpitest.h b/src/testutils/mpitest.h index d4eababfca..dbb640a933 100644 --- a/src/testutils/mpitest.h +++ b/src/testutils/mpitest.h @@ -111,18 +111,19 @@ bool threadMpiTestRunner(std::function testBody); * \ingroup module_testutils */ #if GMX_THREAD_MPI -#define GMX_MPI_TEST(expectedRankCount) \ - do { \ - ASSERT_EQ(expectedRankCount, ::gmx::test::getNumberOfTestMpiRanks()); \ - using MyTestClass = std::remove_reference_t; \ - if (!::gmx::test::threadMpiTestRunner(std::bind(&MyTestClass::TestBody, this))) \ - { \ - return; \ - } \ - } while (0) +# define GMX_MPI_TEST(expectedRankCount) \ + do \ + { \ + ASSERT_EQ(expectedRankCount, ::gmx::test::getNumberOfTestMpiRanks()); \ + using MyTestClass = std::remove_reference_t; \ + if (!::gmx::test::threadMpiTestRunner(std::bind(&MyTestClass::TestBody, this))) \ + { \ + return; \ + } \ + } while (0) #else -#define GMX_MPI_TEST(expectedRankCount) \ - ASSERT_EQ(expectedRankCount, ::gmx::test::getNumberOfTestMpiRanks()) +# define GMX_MPI_TEST(expectedRankCount) \ + ASSERT_EQ(expectedRankCount, ::gmx::test::getNumberOfTestMpiRanks()) #endif } // namespace test diff --git a/src/testutils/refdata.cpp b/src/testutils/refdata.cpp index 0482fdf45e..3b65ed95aa 100644 --- a/src/testutils/refdata.cpp +++ b/src/testutils/refdata.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -88,50 +89,50 @@ namespace internal */ class TestReferenceDataImpl { - public: - //! Initializes a checker in the given mode. - TestReferenceDataImpl(ReferenceDataMode mode, bool bSelfTestMode); - - //! Performs final reference data processing when test ends. - void onTestEnd(bool testPassed); - - //! Full path of the reference data file. - std::string fullFilename_; - /*! \brief - * Root entry for comparing the reference data. - * - * Null after construction iff in compare mode and reference data was - * not loaded successfully. - * In all write modes, copies are present for nodes added to - * \a outputRootEntry_, and ReferenceDataEntry::correspondingOutputEntry() - * points to the copy in the output tree. - */ - ReferenceDataEntry::EntryPointer compareRootEntry_; - /*! \brief - * Root entry for writing new reference data. - * - * Null if only comparing against existing data. Otherwise, starts - * always as empty. - * When creating new reference data, this is maintained as a copy of - * \a compareRootEntry_. - * When updating existing data, entries are added either by copying - * from \a compareRootEntry_ (if they exist and comparison passes), or - * by creating new ones. - */ - ReferenceDataEntry::EntryPointer outputRootEntry_; - /*! \brief - * Whether updating existing reference data. - */ - bool updateMismatchingEntries_; - //! `true` if self-testing (enables extra failure messages). - bool bSelfTestMode_; - /*! \brief - * Whether any reference checkers have been created for this data. - */ - bool bInUse_; +public: + //! Initializes a checker in the given mode. + TestReferenceDataImpl(ReferenceDataMode mode, bool bSelfTestMode); + + //! Performs final reference data processing when test ends. + void onTestEnd(bool testPassed); + + //! Full path of the reference data file. + std::string fullFilename_; + /*! \brief + * Root entry for comparing the reference data. + * + * Null after construction iff in compare mode and reference data was + * not loaded successfully. + * In all write modes, copies are present for nodes added to + * \a outputRootEntry_, and ReferenceDataEntry::correspondingOutputEntry() + * points to the copy in the output tree. + */ + ReferenceDataEntry::EntryPointer compareRootEntry_; + /*! \brief + * Root entry for writing new reference data. + * + * Null if only comparing against existing data. Otherwise, starts + * always as empty. + * When creating new reference data, this is maintained as a copy of + * \a compareRootEntry_. + * When updating existing data, entries are added either by copying + * from \a compareRootEntry_ (if they exist and comparison passes), or + * by creating new ones. + */ + ReferenceDataEntry::EntryPointer outputRootEntry_; + /*! \brief + * Whether updating existing reference data. + */ + bool updateMismatchingEntries_; + //! `true` if self-testing (enables extra failure messages). + bool bSelfTestMode_; + /*! \brief + * Whether any reference checkers have been created for this data. + */ + bool bInUse_; }; -} // namespace internal +} // namespace internal /******************************************************************** * Internal helpers @@ -141,8 +142,7 @@ namespace { //! Convenience typedef for a smart pointer to TestReferenceDataImpl. -typedef std::shared_ptr - TestReferenceDataImplPointer; +typedef std::shared_ptr TestReferenceDataImplPointer; /*! \brief * Global reference data instance. @@ -154,7 +154,7 @@ typedef std::shared_ptr */ TestReferenceDataImplPointer g_referenceData; //! Global reference data mode set with setReferenceDataMode(). -ReferenceDataMode g_referenceDataMode = erefdataCompare; +ReferenceDataMode g_referenceDataMode = erefdataCompare; //! Returns the global reference data mode. ReferenceDataMode getReferenceDataMode() @@ -165,8 +165,7 @@ ReferenceDataMode getReferenceDataMode() //! Returns a reference to the global reference data object. TestReferenceDataImplPointer initReferenceDataInstance() { - GMX_RELEASE_ASSERT(!g_referenceData, - "Test cannot create multiple TestReferenceData instances"); + GMX_RELEASE_ASSERT(!g_referenceData, "Test cannot create multiple TestReferenceData instances"); g_referenceData.reset(new internal::TestReferenceDataImpl(getReferenceDataMode(), false)); return g_referenceData; } @@ -187,40 +186,39 @@ TestReferenceDataImplPointer initReferenceDataInstanceForSelfTest(ReferenceDataM class ReferenceDataTestEventListener : public ::testing::EmptyTestEventListener { - public: - void OnTestEnd(const ::testing::TestInfo &test_info) override +public: + void OnTestEnd(const ::testing::TestInfo& test_info) override + { + if (g_referenceData) { - if (g_referenceData) - { - GMX_RELEASE_ASSERT(g_referenceData.unique(), - "Test leaked TestRefeferenceData objects"); - g_referenceData->onTestEnd(test_info.result()->Passed()); - g_referenceData.reset(); - } + GMX_RELEASE_ASSERT(g_referenceData.unique(), "Test leaked TestRefeferenceData objects"); + g_referenceData->onTestEnd(test_info.result()->Passed()); + g_referenceData.reset(); } + } - void OnTestProgramEnd(const ::testing::UnitTest & /*unused*/) override - { - // Could be used e.g. to free internal buffers allocated by an XML parsing library - } + void OnTestProgramEnd(const ::testing::UnitTest& /*unused*/) override + { + // Could be used e.g. to free internal buffers allocated by an XML parsing library + } }; //! Formats a path to a reference data entry with a non-null id. -std::string formatEntryPath(const std::string &prefix, const std::string &id) +std::string formatEntryPath(const std::string& prefix, const std::string& id) { return prefix + "/" + id; } //! Formats a path to a reference data entry with a null id. -std::string formatSequenceEntryPath(const std::string &prefix, int seqIndex) +std::string formatSequenceEntryPath(const std::string& prefix, int seqIndex) { - return formatString("%s/[%d]", prefix.c_str(), seqIndex+1); + return formatString("%s/[%d]", prefix.c_str(), seqIndex + 1); } //! Finds all entries that have not been checked under a given root. -void gatherUnusedEntries(const ReferenceDataEntry &root, - const std::string &rootPath, - std::vector *unusedPaths) +void gatherUnusedEntries(const ReferenceDataEntry& root, + const std::string& rootPath, + std::vector* unusedPaths) { if (!root.hasBeenChecked()) { @@ -228,7 +226,7 @@ void gatherUnusedEntries(const ReferenceDataEntry &root, return; } int seqIndex = 0; - for (const auto &child : root.children()) + for (const auto& child : root.children()) { std::string path; if (child->id().empty()) @@ -245,7 +243,7 @@ void gatherUnusedEntries(const ReferenceDataEntry &root, } //! Produces a GTest assertion of any entries under given root have not been checked. -void checkUnusedEntries(const ReferenceDataEntry &root, const std::string &rootPath) +void checkUnusedEntries(const ReferenceDataEntry& root, const std::string& rootPath) { std::vector unusedPaths; gatherUnusedEntries(root, rootPath, &unusedPaths); @@ -266,19 +264,17 @@ void checkUnusedEntries(const ReferenceDataEntry &root, const std::string &rootP } } -} // namespace +} // namespace -void initReferenceData(IOptionsContainer *options) +void initReferenceData(IOptionsContainer* options) { // Needs to correspond to the enum order in refdata.h. - const char *const refDataEnum[] = - { "check", "create", "update-changed", "update-all" }; - options->addOption( - EnumOption("ref-data") - .enumValue(refDataEnum).store(&g_referenceDataMode) - .description("Operation mode for tests that use reference data")); - ::testing::UnitTest::GetInstance()->listeners().Append( - new ReferenceDataTestEventListener); + const char* const refDataEnum[] = { "check", "create", "update-changed", "update-all" }; + options->addOption(EnumOption("ref-data") + .enumValue(refDataEnum) + .store(&g_referenceDataMode) + .description("Operation mode for tests that use reference data")); + ::testing::UnitTest::GetInstance()->listeners().Append(new ReferenceDataTestEventListener); } /******************************************************************** @@ -288,16 +284,15 @@ void initReferenceData(IOptionsContainer *options) namespace internal { -TestReferenceDataImpl::TestReferenceDataImpl( - ReferenceDataMode mode, bool bSelfTestMode) - : updateMismatchingEntries_(false), bSelfTestMode_(bSelfTestMode), bInUse_(false) +TestReferenceDataImpl::TestReferenceDataImpl(ReferenceDataMode mode, bool bSelfTestMode) : + updateMismatchingEntries_(false), + bSelfTestMode_(bSelfTestMode), + bInUse_(false) { - const std::string dirname = - bSelfTestMode - ? TestFileManager::getGlobalOutputTempDirectory() - : TestFileManager::getInputDataDirectory(); + const std::string dirname = bSelfTestMode ? TestFileManager::getGlobalOutputTempDirectory() + : TestFileManager::getInputDataDirectory(); const std::string filename = TestFileManager::getTestSpecificFileName(".xml"); - fullFilename_ = Path::join(dirname, "refdata", filename); + fullFilename_ = Path::join(dirname, "refdata", filename); switch (mode) { @@ -365,7 +360,7 @@ void TestReferenceDataImpl::onTestEnd(bool testPassed) } } -} // namespace internal +} // namespace internal /******************************************************************** @@ -379,233 +374,241 @@ void TestReferenceDataImpl::onTestEnd(bool testPassed) */ class TestReferenceChecker::Impl { - public: - //! String constant for naming XML elements for boolean values. - static const char * const cBooleanNodeName; - //! String constant for naming XML elements for string values. - static const char * const cStringNodeName; - //! String constant for naming XML elements for unsigned char values. - static const char * const cUCharNodeName; - //! String constant for naming XML elements for integer values. - static const char * const cIntegerNodeName; - //! String constant for naming XML elements for int32 values. - static const char * const cInt32NodeName; - //! String constant for naming XML elements for unsigned int32 values. - static const char * const cUInt32NodeName; - //! String constant for naming XML elements for int32 values. - static const char * const cInt64NodeName; - //! String constant for naming XML elements for unsigned int64 values. - static const char * const cUInt64NodeName; - //! String constant for naming XML elements for floating-point values. - static const char * const cRealNodeName; - //! String constant for naming XML attribute for value identifiers. - static const char * const cIdAttrName; - //! String constant for naming compounds for vectors. - static const char * const cVectorType; - //! String constant for naming compounds for key-value tree objects. - static const char * const cObjectType; - //! String constant for naming compounds for sequences. - static const char * const cSequenceType; - //! String constant for value identifier for sequence length. - static const char * const cSequenceLengthName; - - //! Creates a checker that does nothing. - explicit Impl(bool initialized); - //! Creates a checker with a given root entry. - Impl(const std::string &path, ReferenceDataEntry *compareRootEntry, - ReferenceDataEntry *outputRootEntry, bool updateMismatchingEntries, - bool bSelfTestMode, const FloatingPointTolerance &defaultTolerance); - - //! Returns the path of this checker with \p id appended. - std::string appendPath(const char *id) const; - - //! Creates an entry with given parameters and fills it with \p checker. - ReferenceDataEntry::EntryPointer - createEntry(const char *type, const char *id, - const IReferenceDataEntryChecker &checker) const - { - ReferenceDataEntry::EntryPointer entry(new ReferenceDataEntry(type, id)); - checker.fillEntry(entry.get()); - return entry; - } - //! Checks an entry for correct type and using \p checker. - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId, - const char *type, const IReferenceDataEntryChecker &checker) const - { - if (entry.type() != type) - { - return ::testing::AssertionFailure() - << "Mismatching reference data item type" << std::endl - << " In item: " << fullId << std::endl - << " Actual: " << type << std::endl - << "Reference: " << entry.type(); - } - return checker.checkEntry(entry, fullId); - } - //! Finds an entry by id and updates the last found entry pointer. - ReferenceDataEntry *findEntry(const char *id); - /*! \brief - * Finds/creates a reference data entry to match against. - * - * \param[in] type Type of entry to create. - * \param[in] id Unique identifier of the entry (can be NULL, in - * which case the next entry without an id is matched). - * \param[out] checker Checker to use for filling out created entries. - * \returns Matching entry, or NULL if no matching entry found - * (NULL is never returned in write mode; new entries are created - * instead). - */ - ReferenceDataEntry * - findOrCreateEntry(const char *type, const char *id, - const IReferenceDataEntryChecker &checker); - /*! \brief - * Helper method for checking a reference data value. - * - * \param[in] name Type of entry to find. - * \param[in] id Unique identifier of the entry (can be NULL, in - * which case the next entry without an id is matched). - * \param[in] checker Checker that provides logic specific to the - * type of the entry. - * \returns Whether the reference data matched, including details - * of the mismatch if the comparison failed. - * \throws TestException if there is a problem parsing the - * reference data. - * - * Performs common tasks in checking a reference value, such as - * finding or creating the correct entry. - * Caller needs to provide a checker object that provides the string - * value for a newly created entry and performs the actual comparison - * against a found entry. - */ - ::testing::AssertionResult - processItem(const char *name, const char *id, - const IReferenceDataEntryChecker &checker); - /*! \brief - * Whether the checker is initialized. - */ - bool initialized() const { return initialized_; } - /*! \brief - * Whether the checker should ignore all validation calls. - * - * This is used to ignore any calls within compounds for which - * reference data could not be found, such that only one error is - * issued for the missing compound, instead of every individual value. - */ - bool shouldIgnore() const +public: + //! String constant for naming XML elements for boolean values. + static const char* const cBooleanNodeName; + //! String constant for naming XML elements for string values. + static const char* const cStringNodeName; + //! String constant for naming XML elements for unsigned char values. + static const char* const cUCharNodeName; + //! String constant for naming XML elements for integer values. + static const char* const cIntegerNodeName; + //! String constant for naming XML elements for int32 values. + static const char* const cInt32NodeName; + //! String constant for naming XML elements for unsigned int32 values. + static const char* const cUInt32NodeName; + //! String constant for naming XML elements for int32 values. + static const char* const cInt64NodeName; + //! String constant for naming XML elements for unsigned int64 values. + static const char* const cUInt64NodeName; + //! String constant for naming XML elements for floating-point values. + static const char* const cRealNodeName; + //! String constant for naming XML attribute for value identifiers. + static const char* const cIdAttrName; + //! String constant for naming compounds for vectors. + static const char* const cVectorType; + //! String constant for naming compounds for key-value tree objects. + static const char* const cObjectType; + //! String constant for naming compounds for sequences. + static const char* const cSequenceType; + //! String constant for value identifier for sequence length. + static const char* const cSequenceLengthName; + + //! Creates a checker that does nothing. + explicit Impl(bool initialized); + //! Creates a checker with a given root entry. + Impl(const std::string& path, + ReferenceDataEntry* compareRootEntry, + ReferenceDataEntry* outputRootEntry, + bool updateMismatchingEntries, + bool bSelfTestMode, + const FloatingPointTolerance& defaultTolerance); + + //! Returns the path of this checker with \p id appended. + std::string appendPath(const char* id) const; + + //! Creates an entry with given parameters and fills it with \p checker. + ReferenceDataEntry::EntryPointer createEntry(const char* type, + const char* id, + const IReferenceDataEntryChecker& checker) const + { + ReferenceDataEntry::EntryPointer entry(new ReferenceDataEntry(type, id)); + checker.fillEntry(entry.get()); + return entry; + } + //! Checks an entry for correct type and using \p checker. + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, + const std::string& fullId, + const char* type, + const IReferenceDataEntryChecker& checker) const + { + if (entry.type() != type) { - GMX_RELEASE_ASSERT(initialized(), - "Accessing uninitialized reference data checker."); - return compareRootEntry_ == nullptr; + return ::testing::AssertionFailure() << "Mismatching reference data item type" << std::endl + << " In item: " << fullId << std::endl + << " Actual: " << type << std::endl + << "Reference: " << entry.type(); } + return checker.checkEntry(entry, fullId); + } + //! Finds an entry by id and updates the last found entry pointer. + ReferenceDataEntry* findEntry(const char* id); + /*! \brief + * Finds/creates a reference data entry to match against. + * + * \param[in] type Type of entry to create. + * \param[in] id Unique identifier of the entry (can be NULL, in + * which case the next entry without an id is matched). + * \param[out] checker Checker to use for filling out created entries. + * \returns Matching entry, or NULL if no matching entry found + * (NULL is never returned in write mode; new entries are created + * instead). + */ + ReferenceDataEntry* findOrCreateEntry(const char* type, + const char* id, + const IReferenceDataEntryChecker& checker); + /*! \brief + * Helper method for checking a reference data value. + * + * \param[in] name Type of entry to find. + * \param[in] id Unique identifier of the entry (can be NULL, in + * which case the next entry without an id is matched). + * \param[in] checker Checker that provides logic specific to the + * type of the entry. + * \returns Whether the reference data matched, including details + * of the mismatch if the comparison failed. + * \throws TestException if there is a problem parsing the + * reference data. + * + * Performs common tasks in checking a reference value, such as + * finding or creating the correct entry. + * Caller needs to provide a checker object that provides the string + * value for a newly created entry and performs the actual comparison + * against a found entry. + */ + ::testing::AssertionResult processItem(const char* name, + const char* id, + const IReferenceDataEntryChecker& checker); + /*! \brief + * Whether the checker is initialized. + */ + bool initialized() const { return initialized_; } + /*! \brief + * Whether the checker should ignore all validation calls. + * + * This is used to ignore any calls within compounds for which + * reference data could not be found, such that only one error is + * issued for the missing compound, instead of every individual value. + */ + bool shouldIgnore() const + { + GMX_RELEASE_ASSERT(initialized(), "Accessing uninitialized reference data checker."); + return compareRootEntry_ == nullptr; + } - //! Whether initialized with other means than the default constructor. - bool initialized_; - //! Default floating-point comparison tolerance. - FloatingPointTolerance defaultTolerance_; - /*! \brief - * Human-readable path to the root node of this checker. - * - * For the root checker, this will be "/", and for each compound, the - * id of the compound is added. Used for reporting comparison - * mismatches. - */ - std::string path_; - /*! \brief - * Current entry under which reference data is searched for comparison. - * - * Points to either the TestReferenceDataImpl::compareRootEntry_, or to - * a compound entry in the tree rooted at that entry. - * - * Can be NULL, in which case this checker does nothing (doesn't even - * report errors, see shouldIgnore()). - */ - ReferenceDataEntry *compareRootEntry_; - /*! \brief - * Current entry under which entries for writing are created. - * - * Points to either the TestReferenceDataImpl::outputRootEntry_, or to - * a compound entry in the tree rooted at that entry. NULL if only - * comparing, or if shouldIgnore() returns `false`. - */ - ReferenceDataEntry *outputRootEntry_; - /*! \brief - * Iterator to a child of \a compareRootEntry_ that was last found. - * - * If `compareRootEntry_->isValidChild()` returns false, no entry has - * been found yet. - * After every check, is updated to point to the entry that was used - * for the check. - * Subsequent checks start the search for the matching node on this - * node. - */ - ReferenceDataEntry::ChildIterator lastFoundEntry_; - /*! \brief - * Whether the reference data is being written (true) or compared - * (false). - */ - bool updateMismatchingEntries_; - //! `true` if self-testing (enables extra failure messages). - bool bSelfTestMode_; - /*! \brief - * Current number of unnamed elements in a sequence. - * - * It is the index of the current unnamed element. - */ - int seqIndex_; + //! Whether initialized with other means than the default constructor. + bool initialized_; + //! Default floating-point comparison tolerance. + FloatingPointTolerance defaultTolerance_; + /*! \brief + * Human-readable path to the root node of this checker. + * + * For the root checker, this will be "/", and for each compound, the + * id of the compound is added. Used for reporting comparison + * mismatches. + */ + std::string path_; + /*! \brief + * Current entry under which reference data is searched for comparison. + * + * Points to either the TestReferenceDataImpl::compareRootEntry_, or to + * a compound entry in the tree rooted at that entry. + * + * Can be NULL, in which case this checker does nothing (doesn't even + * report errors, see shouldIgnore()). + */ + ReferenceDataEntry* compareRootEntry_; + /*! \brief + * Current entry under which entries for writing are created. + * + * Points to either the TestReferenceDataImpl::outputRootEntry_, or to + * a compound entry in the tree rooted at that entry. NULL if only + * comparing, or if shouldIgnore() returns `false`. + */ + ReferenceDataEntry* outputRootEntry_; + /*! \brief + * Iterator to a child of \a compareRootEntry_ that was last found. + * + * If `compareRootEntry_->isValidChild()` returns false, no entry has + * been found yet. + * After every check, is updated to point to the entry that was used + * for the check. + * Subsequent checks start the search for the matching node on this + * node. + */ + ReferenceDataEntry::ChildIterator lastFoundEntry_; + /*! \brief + * Whether the reference data is being written (true) or compared + * (false). + */ + bool updateMismatchingEntries_; + //! `true` if self-testing (enables extra failure messages). + bool bSelfTestMode_; + /*! \brief + * Current number of unnamed elements in a sequence. + * + * It is the index of the current unnamed element. + */ + int seqIndex_; }; -const char *const TestReferenceChecker::Impl::cBooleanNodeName = "Bool"; -const char *const TestReferenceChecker::Impl::cStringNodeName = "String"; -const char *const TestReferenceChecker::Impl::cUCharNodeName = "UChar"; -const char *const TestReferenceChecker::Impl::cIntegerNodeName = "Int"; -const char *const TestReferenceChecker::Impl::cInt32NodeName = "Int32"; -const char *const TestReferenceChecker::Impl::cUInt32NodeName = "UInt32"; -const char *const TestReferenceChecker::Impl::cInt64NodeName = "Int64"; -const char *const TestReferenceChecker::Impl::cUInt64NodeName = "UInt64"; -const char *const TestReferenceChecker::Impl::cRealNodeName = "Real"; -const char *const TestReferenceChecker::Impl::cIdAttrName = "Name"; -const char *const TestReferenceChecker::Impl::cVectorType = "Vector"; -const char *const TestReferenceChecker::Impl::cObjectType = "Object"; -const char *const TestReferenceChecker::Impl::cSequenceType = "Sequence"; -const char *const TestReferenceChecker::Impl::cSequenceLengthName = "Length"; - - -TestReferenceChecker::Impl::Impl(bool initialized) - : initialized_(initialized), defaultTolerance_(defaultRealTolerance()), - compareRootEntry_(nullptr), outputRootEntry_(nullptr), - updateMismatchingEntries_(false), bSelfTestMode_(false), seqIndex_(-1) +const char* const TestReferenceChecker::Impl::cBooleanNodeName = "Bool"; +const char* const TestReferenceChecker::Impl::cStringNodeName = "String"; +const char* const TestReferenceChecker::Impl::cUCharNodeName = "UChar"; +const char* const TestReferenceChecker::Impl::cIntegerNodeName = "Int"; +const char* const TestReferenceChecker::Impl::cInt32NodeName = "Int32"; +const char* const TestReferenceChecker::Impl::cUInt32NodeName = "UInt32"; +const char* const TestReferenceChecker::Impl::cInt64NodeName = "Int64"; +const char* const TestReferenceChecker::Impl::cUInt64NodeName = "UInt64"; +const char* const TestReferenceChecker::Impl::cRealNodeName = "Real"; +const char* const TestReferenceChecker::Impl::cIdAttrName = "Name"; +const char* const TestReferenceChecker::Impl::cVectorType = "Vector"; +const char* const TestReferenceChecker::Impl::cObjectType = "Object"; +const char* const TestReferenceChecker::Impl::cSequenceType = "Sequence"; +const char* const TestReferenceChecker::Impl::cSequenceLengthName = "Length"; + + +TestReferenceChecker::Impl::Impl(bool initialized) : + initialized_(initialized), + defaultTolerance_(defaultRealTolerance()), + compareRootEntry_(nullptr), + outputRootEntry_(nullptr), + updateMismatchingEntries_(false), + bSelfTestMode_(false), + seqIndex_(-1) { } -TestReferenceChecker::Impl::Impl(const std::string &path, - ReferenceDataEntry *compareRootEntry, - ReferenceDataEntry *outputRootEntry, - bool updateMismatchingEntries, bool bSelfTestMode, - const FloatingPointTolerance &defaultTolerance) - : initialized_(true), defaultTolerance_(defaultTolerance), path_(path), - compareRootEntry_(compareRootEntry), outputRootEntry_(outputRootEntry), - lastFoundEntry_(compareRootEntry->children().end()), - updateMismatchingEntries_(updateMismatchingEntries), - bSelfTestMode_(bSelfTestMode), seqIndex_(-1) +TestReferenceChecker::Impl::Impl(const std::string& path, + ReferenceDataEntry* compareRootEntry, + ReferenceDataEntry* outputRootEntry, + bool updateMismatchingEntries, + bool bSelfTestMode, + const FloatingPointTolerance& defaultTolerance) : + initialized_(true), + defaultTolerance_(defaultTolerance), + path_(path), + compareRootEntry_(compareRootEntry), + outputRootEntry_(outputRootEntry), + lastFoundEntry_(compareRootEntry->children().end()), + updateMismatchingEntries_(updateMismatchingEntries), + bSelfTestMode_(bSelfTestMode), + seqIndex_(-1) { } -std::string -TestReferenceChecker::Impl::appendPath(const char *id) const +std::string TestReferenceChecker::Impl::appendPath(const char* id) const { - return id != nullptr - ? formatEntryPath(path_, id) - : formatSequenceEntryPath(path_, seqIndex_); + return id != nullptr ? formatEntryPath(path_, id) : formatSequenceEntryPath(path_, seqIndex_); } -ReferenceDataEntry *TestReferenceChecker::Impl::findEntry(const char *id) +ReferenceDataEntry* TestReferenceChecker::Impl::findEntry(const char* id) { ReferenceDataEntry::ChildIterator entry = compareRootEntry_->findChild(id, lastFoundEntry_); - seqIndex_ = (id == nullptr) ? seqIndex_+1 : -1; + seqIndex_ = (id == nullptr) ? seqIndex_ + 1 : -1; if (compareRootEntry_->isValidChild(entry)) { lastFoundEntry_ = entry; @@ -614,12 +617,11 @@ ReferenceDataEntry *TestReferenceChecker::Impl::findEntry(const char *id) return nullptr; } -ReferenceDataEntry * -TestReferenceChecker::Impl::findOrCreateEntry( - const char *type, const char *id, - const IReferenceDataEntryChecker &checker) +ReferenceDataEntry* TestReferenceChecker::Impl::findOrCreateEntry(const char* type, + const char* id, + const IReferenceDataEntryChecker& checker) { - ReferenceDataEntry *entry = findEntry(id); + ReferenceDataEntry* entry = findEntry(id); if (entry == nullptr && outputRootEntry_ != nullptr) { lastFoundEntry_ = compareRootEntry_->addChild(createEntry(type, id, checker)); @@ -628,20 +630,19 @@ TestReferenceChecker::Impl::findOrCreateEntry( return entry; } -::testing::AssertionResult -TestReferenceChecker::Impl::processItem(const char *type, const char *id, - const IReferenceDataEntryChecker &checker) +::testing::AssertionResult TestReferenceChecker::Impl::processItem(const char* type, + const char* id, + const IReferenceDataEntryChecker& checker) { if (shouldIgnore()) { return ::testing::AssertionSuccess(); } std::string fullId = appendPath(id); - ReferenceDataEntry *entry = findOrCreateEntry(type, id, checker); + ReferenceDataEntry* entry = findOrCreateEntry(type, id, checker); if (entry == nullptr) { - return ::testing::AssertionFailure() - << "Reference data item " << fullId << " not found"; + return ::testing::AssertionFailure() << "Reference data item " << fullId << " not found"; } entry->setChecked(); ::testing::AssertionResult result(checkEntry(*entry, fullId, type, checker)); @@ -664,8 +665,8 @@ TestReferenceChecker::Impl::processItem(const char *type, const char *id, ReferenceDataEntry expected(type, id); checker.fillEntry(&expected); result << std::endl - << "String value: '" << expected.value() << "'" << std::endl - << " Ref. string: '" << entry->value() << "'"; + << "String value: '" << expected.value() << "'" << std::endl + << " Ref. string: '" << entry->value() << "'"; } return result; } @@ -675,29 +676,23 @@ TestReferenceChecker::Impl::processItem(const char *type, const char *id, * TestReferenceData */ -TestReferenceData::TestReferenceData() - : impl_(initReferenceDataInstance()) -{ -} +TestReferenceData::TestReferenceData() : impl_(initReferenceDataInstance()) {} -TestReferenceData::TestReferenceData(ReferenceDataMode mode) - : impl_(initReferenceDataInstanceForSelfTest(mode)) +TestReferenceData::TestReferenceData(ReferenceDataMode mode) : + impl_(initReferenceDataInstanceForSelfTest(mode)) { } -TestReferenceData::~TestReferenceData() -{ -} +TestReferenceData::~TestReferenceData() {} TestReferenceChecker TestReferenceData::rootChecker() { if (!impl_->bInUse_ && !impl_->compareRootEntry_) { - ADD_FAILURE() << "Reference data file not found: " - << impl_->fullFilename_; + ADD_FAILURE() << "Reference data file not found: " << impl_->fullFilename_; } impl_->bInUse_ = true; if (!impl_->compareRootEntry_) @@ -705,11 +700,9 @@ TestReferenceChecker TestReferenceData::rootChecker() return TestReferenceChecker(new TestReferenceChecker::Impl(true)); } impl_->compareRootEntry_->setChecked(); - return TestReferenceChecker( - new TestReferenceChecker::Impl("", impl_->compareRootEntry_.get(), - impl_->outputRootEntry_.get(), - impl_->updateMismatchingEntries_, impl_->bSelfTestMode_, - defaultRealTolerance())); + return TestReferenceChecker(new TestReferenceChecker::Impl( + "", impl_->compareRootEntry_.get(), impl_->outputRootEntry_.get(), + impl_->updateMismatchingEntries_, impl_->bSelfTestMode_, defaultRealTolerance())); } @@ -717,36 +710,27 @@ TestReferenceChecker TestReferenceData::rootChecker() * TestReferenceChecker */ -TestReferenceChecker::TestReferenceChecker() - : impl_(new Impl(false)) -{ -} +TestReferenceChecker::TestReferenceChecker() : impl_(new Impl(false)) {} -TestReferenceChecker::TestReferenceChecker(Impl *impl) - : impl_(impl) -{ -} +TestReferenceChecker::TestReferenceChecker(Impl* impl) : impl_(impl) {} -TestReferenceChecker::TestReferenceChecker(const TestReferenceChecker &other) - : impl_(new Impl(*other.impl_)) +TestReferenceChecker::TestReferenceChecker(const TestReferenceChecker& other) : + impl_(new Impl(*other.impl_)) { } -TestReferenceChecker::TestReferenceChecker(TestReferenceChecker &&other) noexcept - : impl_(std::move(other.impl_)) +TestReferenceChecker::TestReferenceChecker(TestReferenceChecker&& other) noexcept : + impl_(std::move(other.impl_)) { } -TestReferenceChecker & -TestReferenceChecker::operator=(TestReferenceChecker &&other) noexcept +TestReferenceChecker& TestReferenceChecker::operator=(TestReferenceChecker&& other) noexcept { impl_ = std::move(other.impl_); return *this; } -TestReferenceChecker::~TestReferenceChecker() -{ -} +TestReferenceChecker::~TestReferenceChecker() {} bool TestReferenceChecker::isValid() const { @@ -754,8 +738,7 @@ bool TestReferenceChecker::isValid() const } -void TestReferenceChecker::setDefaultTolerance( - const FloatingPointTolerance &tolerance) +void TestReferenceChecker::setDefaultTolerance(const FloatingPointTolerance& tolerance) { impl_->defaultTolerance_ = tolerance; } @@ -772,22 +755,20 @@ void TestReferenceChecker::checkUnusedEntries() } -bool TestReferenceChecker::checkPresent(bool bPresent, const char *id) +bool TestReferenceChecker::checkPresent(bool bPresent, const char* id) { if (impl_->shouldIgnore() || impl_->outputRootEntry_ != nullptr) { return bPresent; } - ReferenceDataEntry::ChildIterator entry - = impl_->compareRootEntry_->findChild(id, impl_->lastFoundEntry_); - const bool bFound - = impl_->compareRootEntry_->isValidChild(entry); + ReferenceDataEntry::ChildIterator entry = + impl_->compareRootEntry_->findChild(id, impl_->lastFoundEntry_); + const bool bFound = impl_->compareRootEntry_->isValidChild(entry); if (bFound != bPresent) { - ADD_FAILURE() << "Mismatch while checking reference data item '" - << impl_->appendPath(id) << "'\n" - << "Expected: " << (bPresent ? "it is present.\n" : "it is absent.\n") - << " Actual: " << (bFound ? "it is present." : "it is absent."); + ADD_FAILURE() << "Mismatch while checking reference data item '" << impl_->appendPath(id) << "'\n" + << "Expected: " << (bPresent ? "it is present.\n" : "it is absent.\n") + << " Actual: " << (bFound ? "it is present." : "it is absent."); } if (bFound && bPresent) { @@ -798,7 +779,7 @@ bool TestReferenceChecker::checkPresent(bool bPresent, const char *id) } -TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const char *id) +TestReferenceChecker TestReferenceChecker::checkCompound(const char* type, const char* id) { if (impl_->shouldIgnore()) { @@ -806,7 +787,7 @@ TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const } std::string fullId = impl_->appendPath(id); NullChecker checker; - ReferenceDataEntry *entry = impl_->findOrCreateEntry(type, id, checker); + ReferenceDataEntry* entry = impl_->findOrCreateEntry(type, id, checker); if (entry == nullptr) { ADD_FAILURE() << "Reference data item " << fullId << " not found"; @@ -830,13 +811,12 @@ TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const { impl_->outputRootEntry_->addChild(entry->cloneToOutputEntry()); } - return TestReferenceChecker( - new Impl(fullId, entry, entry->correspondingOutputEntry(), - impl_->updateMismatchingEntries_, impl_->bSelfTestMode_, - impl_->defaultTolerance_)); + return TestReferenceChecker(new Impl(fullId, entry, entry->correspondingOutputEntry(), + impl_->updateMismatchingEntries_, impl_->bSelfTestMode_, + impl_->defaultTolerance_)); } -TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const std::string &id) +TestReferenceChecker TestReferenceChecker::checkCompound(const char* type, const std::string& id) { return checkCompound(type, id.c_str()); } @@ -851,123 +831,119 @@ TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const * \todo Eliminate this limitation of TinyXML2. See * e.g. https://github.com/leethomason/tinyxml2/issues/432 */ -static void -throwIfNonEmptyAndOnlyWhitespace(const std::string &s, const char *id) +static void throwIfNonEmptyAndOnlyWhitespace(const std::string& s, const char* id) { - if (!s.empty() && std::all_of(s.cbegin(), s.cend(), [](const char &c){ return std::isspace(c); })) + if (!s.empty() && std::all_of(s.cbegin(), s.cend(), [](const char& c) { return std::isspace(c); })) { std::string message("String '" + s + "' with "); message += (id != nullptr) ? "null " : ""; message += "ID "; message += (id != nullptr) ? "" : id; - message += " cannot be handled. We must refuse to write a refdata String" - "field for a non-empty string that contains only whitespace, " - "because it will not be read correctly by TinyXML2."; + message += + " cannot be handled. We must refuse to write a refdata String" + "field for a non-empty string that contains only whitespace, " + "because it will not be read correctly by TinyXML2."; GMX_THROW(TestException(message)); } } -void TestReferenceChecker::checkBoolean(bool value, const char *id) +void TestReferenceChecker::checkBoolean(bool value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cBooleanNodeName, id, ExactStringChecker(value ? "true" : "false"))); } -void TestReferenceChecker::checkString(const char *value, const char *id) +void TestReferenceChecker::checkString(const char* value, const char* id) { throwIfNonEmptyAndOnlyWhitespace(value, id); - EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, - ExactStringChecker(value))); + EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, ExactStringChecker(value))); } -void TestReferenceChecker::checkString(const std::string &value, const char *id) +void TestReferenceChecker::checkString(const std::string& value, const char* id) { throwIfNonEmptyAndOnlyWhitespace(value, id); - EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, - ExactStringChecker(value))); + EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, ExactStringChecker(value))); } -void TestReferenceChecker::checkTextBlock(const std::string &value, - const char *id) +void TestReferenceChecker::checkTextBlock(const std::string& value, const char* id) { - EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, - ExactStringBlockChecker(value))); + EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, ExactStringBlockChecker(value))); } -void TestReferenceChecker::checkUChar(unsigned char value, const char *id) +void TestReferenceChecker::checkUChar(unsigned char value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cUCharNodeName, id, ExactStringChecker(formatString("%d", value)))); } -void TestReferenceChecker::checkInteger(int value, const char *id) +void TestReferenceChecker::checkInteger(int value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cIntegerNodeName, id, ExactStringChecker(formatString("%d", value)))); } -void TestReferenceChecker::checkInt32(int32_t value, const char *id) +void TestReferenceChecker::checkInt32(int32_t value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cInt32NodeName, id, ExactStringChecker(formatString("%" PRId32, value)))); } -void TestReferenceChecker::checkUInt32(uint32_t value, const char *id) +void TestReferenceChecker::checkUInt32(uint32_t value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cUInt32NodeName, id, ExactStringChecker(formatString("%" PRIu32, value)))); } -void TestReferenceChecker::checkInt64(int64_t value, const char *id) +void TestReferenceChecker::checkInt64(int64_t value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cInt64NodeName, id, ExactStringChecker(formatString("%" PRId64, value)))); } -void TestReferenceChecker::checkUInt64(uint64_t value, const char *id) +void TestReferenceChecker::checkUInt64(uint64_t value, const char* id) { EXPECT_PLAIN(impl_->processItem(Impl::cUInt64NodeName, id, ExactStringChecker(formatString("%" PRIu64, value)))); } -void TestReferenceChecker::checkDouble(double value, const char *id) +void TestReferenceChecker::checkDouble(double value, const char* id) { FloatingPointChecker checker(value, impl_->defaultTolerance_); EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, checker)); } -void TestReferenceChecker::checkFloat(float value, const char *id) +void TestReferenceChecker::checkFloat(float value, const char* id) { FloatingPointChecker checker(value, impl_->defaultTolerance_); EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, checker)); } -void TestReferenceChecker::checkReal(float value, const char *id) +void TestReferenceChecker::checkReal(float value, const char* id) { checkFloat(value, id); } -void TestReferenceChecker::checkReal(double value, const char *id) +void TestReferenceChecker::checkReal(double value, const char* id) { checkDouble(value, id); } -void TestReferenceChecker::checkRealFromString(const std::string &value, const char *id) +void TestReferenceChecker::checkRealFromString(const std::string& value, const char* id) { FloatingPointFromStringChecker checker(value, impl_->defaultTolerance_); EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, checker)); } -void TestReferenceChecker::checkVector(const int value[3], const char *id) +void TestReferenceChecker::checkVector(const int value[3], const char* id) { TestReferenceChecker compound(checkCompound(Impl::cVectorType, id)); compound.checkInteger(value[0], "X"); @@ -976,7 +952,7 @@ void TestReferenceChecker::checkVector(const int value[3], const char *id) } -void TestReferenceChecker::checkVector(const float value[3], const char *id) +void TestReferenceChecker::checkVector(const float value[3], const char* id) { TestReferenceChecker compound(checkCompound(Impl::cVectorType, id)); compound.checkReal(value[0], "X"); @@ -985,7 +961,7 @@ void TestReferenceChecker::checkVector(const float value[3], const char *id) } -void TestReferenceChecker::checkVector(const double value[3], const char *id) +void TestReferenceChecker::checkVector(const double value[3], const char* id) { TestReferenceChecker compound(checkCompound(Impl::cVectorType, id)); compound.checkReal(value[0], "X"); @@ -994,7 +970,7 @@ void TestReferenceChecker::checkVector(const double value[3], const char *id) } -void TestReferenceChecker::checkAny(const Any &any, const char *id) +void TestReferenceChecker::checkAny(const Any& any, const char* id) { if (any.isType()) { @@ -1039,10 +1015,10 @@ void TestReferenceChecker::checkAny(const Any &any, const char *id) } -void TestReferenceChecker::checkKeyValueTreeObject(const KeyValueTreeObject &tree, const char *id) +void TestReferenceChecker::checkKeyValueTreeObject(const KeyValueTreeObject& tree, const char* id) { TestReferenceChecker compound(checkCompound(Impl::cObjectType, id)); - for (const auto &prop : tree.properties()) + for (const auto& prop : tree.properties()) { compound.checkKeyValueTreeValue(prop.value(), prop.key().c_str()); } @@ -1050,7 +1026,7 @@ void TestReferenceChecker::checkKeyValueTreeObject(const KeyValueTreeObject &tre } -void TestReferenceChecker::checkKeyValueTreeValue(const KeyValueTreeValue &value, const char *id) +void TestReferenceChecker::checkKeyValueTreeValue(const KeyValueTreeValue& value, const char* id) { if (value.isObject()) { @@ -1058,7 +1034,7 @@ void TestReferenceChecker::checkKeyValueTreeValue(const KeyValueTreeValue &value } else if (value.isArray()) { - const auto &values = value.asArray().values(); + const auto& values = value.asArray().values(); checkSequence(values.begin(), values.end(), id); } else @@ -1068,8 +1044,7 @@ void TestReferenceChecker::checkKeyValueTreeValue(const KeyValueTreeValue &value } -TestReferenceChecker -TestReferenceChecker::checkSequenceCompound(const char *id, size_t length) +TestReferenceChecker TestReferenceChecker::checkSequenceCompound(const char* id, size_t length) { TestReferenceChecker compound(checkCompound(Impl::cSequenceType, id)); compound.checkInteger(static_cast(length), Impl::cSequenceLengthName); @@ -1077,93 +1052,86 @@ TestReferenceChecker::checkSequenceCompound(const char *id, size_t length) } -unsigned char TestReferenceChecker::readUChar(const char *id) +unsigned char TestReferenceChecker::readUChar(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } int value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cUCharNodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cUCharNodeName, id, ValueExtractor(&value))); return value; } -int TestReferenceChecker::readInteger(const char *id) +int TestReferenceChecker::readInteger(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } int value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cIntegerNodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cIntegerNodeName, id, ValueExtractor(&value))); return value; } -int32_t TestReferenceChecker::readInt32(const char *id) +int32_t TestReferenceChecker::readInt32(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } int32_t value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cInt32NodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cInt32NodeName, id, ValueExtractor(&value))); return value; } -int64_t TestReferenceChecker::readInt64(const char *id) +int64_t TestReferenceChecker::readInt64(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } int64_t value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cInt64NodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cInt64NodeName, id, ValueExtractor(&value))); return value; } -float TestReferenceChecker::readFloat(const char *id) +float TestReferenceChecker::readFloat(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } float value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, ValueExtractor(&value))); return value; } -double TestReferenceChecker::readDouble(const char *id) +double TestReferenceChecker::readDouble(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } double value = 0; - EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cRealNodeName, id, ValueExtractor(&value))); return value; } -std::string TestReferenceChecker::readString(const char *id) +std::string TestReferenceChecker::readString(const char* id) { if (impl_->shouldIgnore()) { GMX_THROW(TestException("Trying to read from non-existent reference data value")); } std::string value; - EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, - ValueExtractor(&value))); + EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id, ValueExtractor(&value))); return value; } diff --git a/src/testutils/refdata.h b/src/testutils/refdata.h index efd63e1881..a33069170b 100644 --- a/src/testutils/refdata.h +++ b/src/testutils/refdata.h @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by + * Copyright (c) 2011-2018, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -116,7 +117,7 @@ enum ReferenceDataMode * * \ingroup module_testutils */ -void initReferenceData(IOptionsContainer *options); +void initReferenceData(IOptionsContainer* options); class TestReferenceChecker; @@ -177,41 +178,41 @@ class TestReferenceDataImpl; */ class TestReferenceData { - public: - /*! \brief - * Initializes the reference data in the global mode. - */ - TestReferenceData(); - /*! \brief - * Initializes the reference data in a specific mode. - * - * This function is only useful for self-testing the reference data - * framework. As such, it also puts the framework in a state where it - * logs additional internal information for failures to help diagnosing - * problems in the framework, and stores the reference data in a - * temporary directory instead of the source tree. - * The default constructor should be used in tests utilizing this class. - */ - explicit TestReferenceData(ReferenceDataMode mode); - /*! \brief - * Frees reference data structures. - * - * The reference data is written out if necessary automatically when - * the test finishes. - */ - ~TestReferenceData(); - - /*! \brief - * Returns a root-level checker object for comparisons. - * - * Each call returns an independent instance. - */ - TestReferenceChecker rootChecker(); - - private: - std::shared_ptr impl_; - - GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData); +public: + /*! \brief + * Initializes the reference data in the global mode. + */ + TestReferenceData(); + /*! \brief + * Initializes the reference data in a specific mode. + * + * This function is only useful for self-testing the reference data + * framework. As such, it also puts the framework in a state where it + * logs additional internal information for failures to help diagnosing + * problems in the framework, and stores the reference data in a + * temporary directory instead of the source tree. + * The default constructor should be used in tests utilizing this class. + */ + explicit TestReferenceData(ReferenceDataMode mode); + /*! \brief + * Frees reference data structures. + * + * The reference data is written out if necessary automatically when + * the test finishes. + */ + ~TestReferenceData(); + + /*! \brief + * Returns a root-level checker object for comparisons. + * + * Each call returns an independent instance. + */ + TestReferenceChecker rootChecker(); + +private: + std::shared_ptr impl_; + + GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData); }; /*! \libinternal \brief @@ -237,373 +238,337 @@ class TestReferenceData */ class TestReferenceChecker { - public: - /*! \brief - * Creates a checker that cannot be used for checking. - * - * Attempting to call the check methods generates an assert. - * It is possible to check whether the checker is initialized by - * calling isValid(). - * This constructor exists to allow declaring checker variables that - * will receive their value later without resorting to dynamic - * allocation. - */ - TestReferenceChecker(); - //! Creates a deep copy of the other checker. - explicit TestReferenceChecker(const TestReferenceChecker &other); - //! Moves the checker. - TestReferenceChecker(TestReferenceChecker &&other) noexcept; - ~TestReferenceChecker(); - - //! Prevents implicit copying during assignment. - TestReferenceChecker &operator=(const TestReferenceChecker &) = delete; - //! Assigns a test reference checker. - TestReferenceChecker &operator=(TestReferenceChecker &&other) noexcept; - - //! Returns whether the checker is initialized. - bool isValid() const; - //! Allows testing whether the checker is initialized directly with if. - explicit operator bool() const { return isValid(); } - - /*! \brief - * Sets the tolerance for floating-point comparisons. - * - * All following floating-point comparisons using this checker will use - * the new tolerance. Child checkers created with checkCompound() - * will inherit the tolerance from their parent checker at the time - * checkCompound() is called. - * - * Does not throw. - */ - void setDefaultTolerance(const FloatingPointTolerance &tolerance); - - /*! \brief - * Checks that all reference values have been compared against. - * - * All values under the compound represented by this checker are - * checked, and a non-fatal Google Test assertion is produced if some - * values have not been used. - * - * If not called explicitly, the same check will be done for all - * reference data values when the test ends. - * - * This method also marks the values used, so that subsequent checks - * (including the check at the end of the test) will not produce - * another assertion about the same values. - */ - void checkUnusedEntries(); - - /*! \brief - * Checks whether a data item is present. - * - * \param[in] bPresent Whether to check for presence or absence. - * \param[in] id Unique identifier of the item to check. - * \returns true if bPresent was true and the data item was found. - * - * If \p bPresent is true, checks that a data item with \p id is - * present, otherwise checks that the data item is absent. - * If the check fails, a non-fatal Google Test assertion is generated. - * - * If reference data is being written, the check always succeeds and the - * return value is \p bPresent. - * - * The main use of this method is to assign meaning for missing - * reference data. Example use: - * \code - if (checker.checkPresent(bHaveVelocities, "Velocities")) - { - // - } - * \endcode - */ - bool checkPresent(bool bPresent, const char *id); - - /*! \brief - * Initializes comparison of a group of related data items. - * - * \param[in] type Informational type for the compound. - * \param[in] id Unique identifier for the compound among its - * siblings. - * \returns Checker to use for comparison within the compound. - * - * All checks performed with the returned checker only - * need to have unique ids within the compound, not globally. - * - * Compound structures can be nested. - */ - TestReferenceChecker checkCompound(const char *type, const char *id); - //! \copydoc checkCompound(const char *, const char *) - TestReferenceChecker checkCompound(const char *type, const std::string &id); - - //! Check a single boolean value. - void checkBoolean(bool value, const char *id); - //! Check a single string value. - void checkString(const char *value, const char *id); - //! Check a single string value. - void checkString(const std::string &value, const char *id); - /*! \brief - * Check a multi-line string value. - * - * This method works as checkString(), but should be used for long - * strings that may contain, e.g., newlines. Typically used to check - * formatted output, and attempts to make the output XML such that it - * is easier to edit by hand to set the desired output formatting. - */ - void checkTextBlock(const std::string &value, const char *id); - //! Check a single unsigned char value. - void checkUChar(unsigned char value, const char *id); - //! Check a single integer value. - void checkInteger(int value, const char *id); - //! Check a single int32 value. - void checkInt32(int32_t value, const char *id); - //! Check a single uint32 value. - void checkUInt32(uint32_t value, const char *id); - //! Check a single int64 value. - void checkInt64(int64_t value, const char *id); - //! Check a single uint64 value. - void checkUInt64(uint64_t value, const char *id); - //! Check a single single-precision floating point value. - void checkFloat(float value, const char *id); - //! Check a single double-precision floating point value. - void checkDouble(double value, const char *id); - //! Check a single floating point value. - void checkReal(float value, const char *id); - //! Check a single floating point value. - void checkReal(double value, const char *id); - //! Check a vector of three integer values. - void checkVector(const int value[3], const char *id); - //! Check a vector of three single-precision floating point values. - void checkVector(const float value[3], const char *id); - //! Check a vector of three double-precision floating point values. - void checkVector(const double value[3], const char *id); - //! Check a single floating-point value from a string. - void checkRealFromString(const std::string &value, const char *id); - //! Checks a any value that contains a supported simple type. - void checkAny(const Any &value, const char *id); - //! Checks a key-value tree rooted at a object. - void checkKeyValueTreeObject(const KeyValueTreeObject &tree, const char *id); - //! Checks a generic key-value tree value. - void checkKeyValueTreeValue(const KeyValueTreeValue &value, const char *id); - - /*! \name Methods to read values from reference data - * - * These methods assume that a value with the given `id` has already - * been created in the test with `check*()` methods, and that it has - * the correct type. - * - * Currently, these methods do not work correctly if the reference data - * file does not exist, so a test using them may fail with exceptions - * before the reference data has been generated. - * \{ - */ - //! Reads an unsigned char value. - unsigned char readUChar(const char *id); - //! Reads an integer value. - int readInteger(const char *id); - //! Reads a 32-bit integer value. - int32_t readInt32(const char *id); - //! Reads a 64-bit integer value. - int64_t readInt64(const char *id); - //! Reads a float value. - float readFloat(const char *id); - //! Reads a double value. - double readDouble(const char *id); - //! Reads a string value. - std::string readString(const char *id); - //! \} - - /*! \name Overloaded versions of simple checker methods - * - * These methods provide overloads under a single name for all the - * methods checkBoolean(), checkString(), checkReal() and checkVector(). - * They are provided mainly to allow template implementations (such as - * checkSequence()). Typically callers should use the individually - * named versions for greater clarity. - * \{ - */ - //! Check a single boolean value. - void checkValue(bool value, const char *id) - { - checkBoolean(value, id); - } - //! Check a single string value. - void checkValue(const char *value, const char *id) - { - checkString(value, id); - } - //! Check a single string value. - void checkValue(const std::string &value, const char *id) - { - checkString(value, id); - } - //! Check a single signed integer value - void checkValue(int value, const char *id) - { - checkInteger(value, id); - } - //! Check a single signed integer value of width 64 bits. - void checkValue(int64_t value, const char *id) - { - checkInt64(value, id); - } - //! Check a single unsigned integer value of width 64 bits. - void checkValue(uint64_t value, const char *id) - { - checkUInt64(value, id); - } - //! Check a single single-precision floating point value. - void checkValue(float value, const char *id) - { - checkFloat(value, id); - } - //! Check a single double-precision floating point value. - void checkValue(double value, const char *id) - { - checkDouble(value, id); - } - //! Check a vector of three integer values. - void checkValue(const int value[3], const char *id) - { - checkVector(value, id); - } - //! Check a vector of three single-precision floating point values. - void checkValue(const float value[3], const char *id) - { - checkVector(value, id); - } - //! Check a vector of three double-precision floating point values. - void checkValue(const double value[3], const char *id) - { - checkVector(value, id); - } - //! Check a generic key-value tree value. - void checkValue(const KeyValueTreeValue &value, const char *id) - { - checkKeyValueTreeValue(value, id); - } - /*!\}*/ - - /*! \brief - * Generic method to check a sequence of simple values. - * - * \tparam Iterator Input iterator that allows multiple (two) passes. - * Value type must be one of those accepted by checkValue(), or - * implicitly convertible to one. - * \param[in] begin Iterator to the start of the range to check. - * \param[in] end Iterator to the end of the range to check. - * \param[in] id Unique identifier for the sequence among its - * siblings. - */ - template - void checkSequence(Iterator begin, Iterator end, const char *id) - { - typename std::iterator_traits::difference_type length - = std::distance(begin, end); - TestReferenceChecker compound(checkSequenceCompound(id, length)); - for (Iterator i = begin; i != end; ++i) - { - compound.checkValue(*i, nullptr); - } - } - /*! \brief - * Generic method to check a sequence of custom values. - * - * \tparam Iterator Input iterator that allows multiple (two) passes. - * \tparam ItemChecker Functor to check an individual value. Signature - * void(TestReferenceChecker *, const T &), where T is the value - * type of \p Iterator. - * \param[in] begin Iterator to the start of the range to check. - * \param[in] end Iterator to the end of the range to check. - * \param[in] id Unique identifier for the sequence among its - * siblings. - * \param[in] checkItem Functor to check an individual item. - * - * This method creates a compound checker \c compound within which all - * values of the sequence are checked. Calls \c checkItem(&compound, *i) - * with that compound for each iterator \c i in the range [begin, end). - * \p checkItem should use the various check methods in the passed - * checker to check each value. - * - * This method can be used to check a sequence made of compound types. - * Typically \p checkItem will create a compound within the passed - * checker to check different aspects of the value that was passed - * to it. Either NULL or a unique identifier string must be used for - * the id value of that compound. */ - template - void checkSequence(Iterator begin, Iterator end, const char *id, - ItemChecker checkItem) +public: + /*! \brief + * Creates a checker that cannot be used for checking. + * + * Attempting to call the check methods generates an assert. + * It is possible to check whether the checker is initialized by + * calling isValid(). + * This constructor exists to allow declaring checker variables that + * will receive their value later without resorting to dynamic + * allocation. + */ + TestReferenceChecker(); + //! Creates a deep copy of the other checker. + explicit TestReferenceChecker(const TestReferenceChecker& other); + //! Moves the checker. + TestReferenceChecker(TestReferenceChecker&& other) noexcept; + ~TestReferenceChecker(); + + //! Prevents implicit copying during assignment. + TestReferenceChecker& operator=(const TestReferenceChecker&) = delete; + //! Assigns a test reference checker. + TestReferenceChecker& operator=(TestReferenceChecker&& other) noexcept; + + //! Returns whether the checker is initialized. + bool isValid() const; + //! Allows testing whether the checker is initialized directly with if. + explicit operator bool() const { return isValid(); } + + /*! \brief + * Sets the tolerance for floating-point comparisons. + * + * All following floating-point comparisons using this checker will use + * the new tolerance. Child checkers created with checkCompound() + * will inherit the tolerance from their parent checker at the time + * checkCompound() is called. + * + * Does not throw. + */ + void setDefaultTolerance(const FloatingPointTolerance& tolerance); + + /*! \brief + * Checks that all reference values have been compared against. + * + * All values under the compound represented by this checker are + * checked, and a non-fatal Google Test assertion is produced if some + * values have not been used. + * + * If not called explicitly, the same check will be done for all + * reference data values when the test ends. + * + * This method also marks the values used, so that subsequent checks + * (including the check at the end of the test) will not produce + * another assertion about the same values. + */ + void checkUnusedEntries(); + + /*! \brief + * Checks whether a data item is present. + * + * \param[in] bPresent Whether to check for presence or absence. + * \param[in] id Unique identifier of the item to check. + * \returns true if bPresent was true and the data item was found. + * + * If \p bPresent is true, checks that a data item with \p id is + * present, otherwise checks that the data item is absent. + * If the check fails, a non-fatal Google Test assertion is generated. + * + * If reference data is being written, the check always succeeds and the + * return value is \p bPresent. + * + * The main use of this method is to assign meaning for missing + * reference data. Example use: + * \code + if (checker.checkPresent(bHaveVelocities, "Velocities")) + { + // + } + * \endcode + */ + bool checkPresent(bool bPresent, const char* id); + + /*! \brief + * Initializes comparison of a group of related data items. + * + * \param[in] type Informational type for the compound. + * \param[in] id Unique identifier for the compound among its + * siblings. + * \returns Checker to use for comparison within the compound. + * + * All checks performed with the returned checker only + * need to have unique ids within the compound, not globally. + * + * Compound structures can be nested. + */ + TestReferenceChecker checkCompound(const char* type, const char* id); + //! \copydoc checkCompound(const char *, const char *) + TestReferenceChecker checkCompound(const char* type, const std::string& id); + + //! Check a single boolean value. + void checkBoolean(bool value, const char* id); + //! Check a single string value. + void checkString(const char* value, const char* id); + //! Check a single string value. + void checkString(const std::string& value, const char* id); + /*! \brief + * Check a multi-line string value. + * + * This method works as checkString(), but should be used for long + * strings that may contain, e.g., newlines. Typically used to check + * formatted output, and attempts to make the output XML such that it + * is easier to edit by hand to set the desired output formatting. + */ + void checkTextBlock(const std::string& value, const char* id); + //! Check a single unsigned char value. + void checkUChar(unsigned char value, const char* id); + //! Check a single integer value. + void checkInteger(int value, const char* id); + //! Check a single int32 value. + void checkInt32(int32_t value, const char* id); + //! Check a single uint32 value. + void checkUInt32(uint32_t value, const char* id); + //! Check a single int64 value. + void checkInt64(int64_t value, const char* id); + //! Check a single uint64 value. + void checkUInt64(uint64_t value, const char* id); + //! Check a single single-precision floating point value. + void checkFloat(float value, const char* id); + //! Check a single double-precision floating point value. + void checkDouble(double value, const char* id); + //! Check a single floating point value. + void checkReal(float value, const char* id); + //! Check a single floating point value. + void checkReal(double value, const char* id); + //! Check a vector of three integer values. + void checkVector(const int value[3], const char* id); + //! Check a vector of three single-precision floating point values. + void checkVector(const float value[3], const char* id); + //! Check a vector of three double-precision floating point values. + void checkVector(const double value[3], const char* id); + //! Check a single floating-point value from a string. + void checkRealFromString(const std::string& value, const char* id); + //! Checks a any value that contains a supported simple type. + void checkAny(const Any& value, const char* id); + //! Checks a key-value tree rooted at a object. + void checkKeyValueTreeObject(const KeyValueTreeObject& tree, const char* id); + //! Checks a generic key-value tree value. + void checkKeyValueTreeValue(const KeyValueTreeValue& value, const char* id); + + /*! \name Methods to read values from reference data + * + * These methods assume that a value with the given `id` has already + * been created in the test with `check*()` methods, and that it has + * the correct type. + * + * Currently, these methods do not work correctly if the reference data + * file does not exist, so a test using them may fail with exceptions + * before the reference data has been generated. + * \{ + */ + //! Reads an unsigned char value. + unsigned char readUChar(const char* id); + //! Reads an integer value. + int readInteger(const char* id); + //! Reads a 32-bit integer value. + int32_t readInt32(const char* id); + //! Reads a 64-bit integer value. + int64_t readInt64(const char* id); + //! Reads a float value. + float readFloat(const char* id); + //! Reads a double value. + double readDouble(const char* id); + //! Reads a string value. + std::string readString(const char* id); + //! \} + + /*! \name Overloaded versions of simple checker methods + * + * These methods provide overloads under a single name for all the + * methods checkBoolean(), checkString(), checkReal() and checkVector(). + * They are provided mainly to allow template implementations (such as + * checkSequence()). Typically callers should use the individually + * named versions for greater clarity. + * \{ + */ + //! Check a single boolean value. + void checkValue(bool value, const char* id) { checkBoolean(value, id); } + //! Check a single string value. + void checkValue(const char* value, const char* id) { checkString(value, id); } + //! Check a single string value. + void checkValue(const std::string& value, const char* id) { checkString(value, id); } + //! Check a single signed integer value + void checkValue(int value, const char* id) { checkInteger(value, id); } + //! Check a single signed integer value of width 64 bits. + void checkValue(int64_t value, const char* id) { checkInt64(value, id); } + //! Check a single unsigned integer value of width 64 bits. + void checkValue(uint64_t value, const char* id) { checkUInt64(value, id); } + //! Check a single single-precision floating point value. + void checkValue(float value, const char* id) { checkFloat(value, id); } + //! Check a single double-precision floating point value. + void checkValue(double value, const char* id) { checkDouble(value, id); } + //! Check a vector of three integer values. + void checkValue(const int value[3], const char* id) { checkVector(value, id); } + //! Check a vector of three single-precision floating point values. + void checkValue(const float value[3], const char* id) { checkVector(value, id); } + //! Check a vector of three double-precision floating point values. + void checkValue(const double value[3], const char* id) { checkVector(value, id); } + //! Check a generic key-value tree value. + void checkValue(const KeyValueTreeValue& value, const char* id) + { + checkKeyValueTreeValue(value, id); + } + /*!\}*/ + + /*! \brief + * Generic method to check a sequence of simple values. + * + * \tparam Iterator Input iterator that allows multiple (two) passes. + * Value type must be one of those accepted by checkValue(), or + * implicitly convertible to one. + * \param[in] begin Iterator to the start of the range to check. + * \param[in] end Iterator to the end of the range to check. + * \param[in] id Unique identifier for the sequence among its + * siblings. + */ + template + void checkSequence(Iterator begin, Iterator end, const char* id) + { + typename std::iterator_traits::difference_type length = std::distance(begin, end); + TestReferenceChecker compound(checkSequenceCompound(id, length)); + for (Iterator i = begin; i != end; ++i) { - typename std::iterator_traits::difference_type length - = std::distance(begin, end); - TestReferenceChecker compound(checkSequenceCompound(id, length)); - for (Iterator i = begin; i != end; ++i) - { - checkItem(&compound, *i); - } + compound.checkValue(*i, nullptr); } - /*! \brief - * Check an array of values. - * - * \tparam T Type of values to check. Should be one of those accepted - * by checkValue(), or implicitly convertible to one. - * - * \param[in] length Number of values to check. - * \param[in] values Pointer to the first value to check. - * \param[in] id Unique identifier for the sequence among its - * siblings. - * - * This is a convenience method that delegates all work to - * checkSequence(). - */ - template - void checkSequenceArray(size_t length, const T *values, const char *id) + } + /*! \brief + * Generic method to check a sequence of custom values. + * + * \tparam Iterator Input iterator that allows multiple (two) passes. + * \tparam ItemChecker Functor to check an individual value. Signature + * void(TestReferenceChecker *, const T &), where T is the value + * type of \p Iterator. + * \param[in] begin Iterator to the start of the range to check. + * \param[in] end Iterator to the end of the range to check. + * \param[in] id Unique identifier for the sequence among its + * siblings. + * \param[in] checkItem Functor to check an individual item. + * + * This method creates a compound checker \c compound within which all + * values of the sequence are checked. Calls \c checkItem(&compound, *i) + * with that compound for each iterator \c i in the range [begin, end). + * \p checkItem should use the various check methods in the passed + * checker to check each value. + * + * This method can be used to check a sequence made of compound types. + * Typically \p checkItem will create a compound within the passed + * checker to check different aspects of the value that was passed + * to it. Either NULL or a unique identifier string must be used for + * the id value of that compound. */ + template + void checkSequence(Iterator begin, Iterator end, const char* id, ItemChecker checkItem) + { + typename std::iterator_traits::difference_type length = std::distance(begin, end); + TestReferenceChecker compound(checkSequenceCompound(id, length)); + for (Iterator i = begin; i != end; ++i) { - checkSequence(values, values + length, id); + checkItem(&compound, *i); } - /*! \brief - * Convenience method for checking that a sequence is empty. - * - * \param[in] id Unique identifier for the sequence among its - * siblings. - * - * This method provides a convenient solution for a case where there is - * implicitly a sequence to be checked, but there is no pointer - * available to the values since the sequence is empty. - * Since this method does not require the type of the values, it can be - * used in such cases easily. - */ - void checkEmptySequence(const char *id); - /*! \brief - * Initializes a compound for a sequence of items. - * - * \param[in] id Unique identifier for the sequence among its - * siblings. - * \param[in] length Number of items that will be in the sequence. - * \returns Checker to use for comparison within the sequence. - * - * This method can be used to check custom sequences where - * checkSequence() is not appropriate. - */ - TestReferenceChecker checkSequenceCompound(const char *id, size_t length); - - private: - class Impl; - - /*! \brief - * Constructs a checker with a specific internal state. - * - * Is private to only allow users of this class to create instances - * using TestReferenceData::rootChecker() or checkCompound() - * (or by copying). - */ - explicit TestReferenceChecker(Impl *impl); - - PrivateImplPointer impl_; - - /*! \brief - * Needed to expose the constructor only to TestReferenceData. - */ - friend class TestReferenceData; + } + /*! \brief + * Check an array of values. + * + * \tparam T Type of values to check. Should be one of those accepted + * by checkValue(), or implicitly convertible to one. + * + * \param[in] length Number of values to check. + * \param[in] values Pointer to the first value to check. + * \param[in] id Unique identifier for the sequence among its + * siblings. + * + * This is a convenience method that delegates all work to + * checkSequence(). + */ + template + void checkSequenceArray(size_t length, const T* values, const char* id) + { + checkSequence(values, values + length, id); + } + /*! \brief + * Convenience method for checking that a sequence is empty. + * + * \param[in] id Unique identifier for the sequence among its + * siblings. + * + * This method provides a convenient solution for a case where there is + * implicitly a sequence to be checked, but there is no pointer + * available to the values since the sequence is empty. + * Since this method does not require the type of the values, it can be + * used in such cases easily. + */ + void checkEmptySequence(const char* id); + /*! \brief + * Initializes a compound for a sequence of items. + * + * \param[in] id Unique identifier for the sequence among its + * siblings. + * \param[in] length Number of items that will be in the sequence. + * \returns Checker to use for comparison within the sequence. + * + * This method can be used to check custom sequences where + * checkSequence() is not appropriate. + */ + TestReferenceChecker checkSequenceCompound(const char* id, size_t length); + +private: + class Impl; + + /*! \brief + * Constructs a checker with a specific internal state. + * + * Is private to only allow users of this class to create instances + * using TestReferenceData::rootChecker() or checkCompound() + * (or by copying). + */ + explicit TestReferenceChecker(Impl* impl); + + PrivateImplPointer impl_; + + /*! \brief + * Needed to expose the constructor only to TestReferenceData. + */ + friend class TestReferenceData; }; } // namespace test diff --git a/src/testutils/refdata_checkers.h b/src/testutils/refdata_checkers.h index 0d3fda7aab..f8c69f791a 100644 --- a/src/testutils/refdata_checkers.h +++ b/src/testutils/refdata_checkers.h @@ -66,202 +66,174 @@ namespace test class IReferenceDataEntryChecker { - public: - virtual void fillEntry(ReferenceDataEntry *entry) const = 0; - virtual ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId) const = 0; +public: + virtual void fillEntry(ReferenceDataEntry* entry) const = 0; + virtual ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, + const std::string& fullId) const = 0; - protected: - virtual ~IReferenceDataEntryChecker() {} +protected: + virtual ~IReferenceDataEntryChecker() {} }; class NullChecker : public IReferenceDataEntryChecker { - public: - void fillEntry(ReferenceDataEntry * /*entry*/) const override {} - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry & /*entry*/, const std::string & /*fullId*/) const override - { - return ::testing::AssertionSuccess(); - } +public: + void fillEntry(ReferenceDataEntry* /*entry*/) const override {} + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& /*entry*/, + const std::string& /*fullId*/) const override + { + return ::testing::AssertionSuccess(); + } }; class ExactStringChecker : public IReferenceDataEntryChecker { - public: - explicit ExactStringChecker(const std::string &value) - : value_(value) - { - } +public: + explicit ExactStringChecker(const std::string& value) : value_(value) {} - void fillEntry(ReferenceDataEntry *entry) const override - { - entry->setValue(value_); - } - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId) const override + void fillEntry(ReferenceDataEntry* entry) const override { entry->setValue(value_); } + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, const std::string& fullId) const override + { + if (entry.value() == value_) { - if (entry.value() == value_) - { - return ::testing::AssertionSuccess(); - } - return ::testing::AssertionFailure() - << " In item: " << fullId << std::endl - << " Actual: '" << value_ << "'" << std::endl - << "Reference: '" << entry.value() << "'"; + return ::testing::AssertionSuccess(); } + return ::testing::AssertionFailure() << " In item: " << fullId << std::endl + << " Actual: '" << value_ << "'" << std::endl + << "Reference: '" << entry.value() << "'"; + } - private: - std::string value_; +private: + std::string value_; }; class ExactStringBlockChecker : public IReferenceDataEntryChecker { - public: - explicit ExactStringBlockChecker(const std::string &value) - : value_(value) - { - } +public: + explicit ExactStringBlockChecker(const std::string& value) : value_(value) {} - void fillEntry(ReferenceDataEntry *entry) const override - { - entry->setTextBlockValue(value_); - } - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId) const override + void fillEntry(ReferenceDataEntry* entry) const override { entry->setTextBlockValue(value_); } + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, const std::string& fullId) const override + { + if (entry.value() == value_) { - if (entry.value() == value_) - { - return ::testing::AssertionSuccess(); - } - return ::testing::AssertionFailure() - << " In item: " << fullId << std::endl - << " Actual: '" << value_ << "'" << std::endl - << "Reference: '" << entry.value() << "'"; + return ::testing::AssertionSuccess(); } + return ::testing::AssertionFailure() << " In item: " << fullId << std::endl + << " Actual: '" << value_ << "'" << std::endl + << "Reference: '" << entry.value() << "'"; + } - private: - std::string value_; +private: + std::string value_; }; //! Helper function to parse a floating-point reference data value. -static inline double convertDoubleReferenceValue(const std::string &value) +static inline double convertDoubleReferenceValue(const std::string& value) { try { return fromString(value); } - catch (const InvalidInputError &ex) + catch (const InvalidInputError& ex) { GMX_THROW_WRAPPER_TESTEXCEPTION(ex); } } -template +template class FloatingPointChecker : public IReferenceDataEntryChecker { - public: - FloatingPointChecker(FloatType value, const FloatingPointTolerance &tolerance) - : value_(value), tolerance_(tolerance) - { - } +public: + FloatingPointChecker(FloatType value, const FloatingPointTolerance& tolerance) : + value_(value), + tolerance_(tolerance) + { + } - void fillEntry(ReferenceDataEntry *entry) const override - { - const int prec = std::numeric_limits::digits10 + 2; - entry->setValue(formatString("%.*g", prec, value_)); - } - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId) const override + void fillEntry(ReferenceDataEntry* entry) const override + { + const int prec = std::numeric_limits::digits10 + 2; + entry->setValue(formatString("%.*g", prec, value_)); + } + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, const std::string& fullId) const override + { + FloatType refValue = static_cast(convertDoubleReferenceValue(entry.value())); + FloatingPointDifference diff(refValue, value_); + if (tolerance_.isWithin(diff)) { - FloatType refValue = static_cast(convertDoubleReferenceValue(entry.value())); - FloatingPointDifference diff(refValue, value_); - if (tolerance_.isWithin(diff)) - { - return ::testing::AssertionSuccess(); - } - return ::testing::AssertionFailure() - << " In item: " << fullId << std::endl - << " Actual: " << value_ << std::endl - << " Reference: " << refValue << std::endl - << "Difference: " << diff.toString() << std::endl - << " Tolerance: " << tolerance_.toString(diff); + return ::testing::AssertionSuccess(); } + return ::testing::AssertionFailure() << " In item: " << fullId << std::endl + << " Actual: " << value_ << std::endl + << " Reference: " << refValue << std::endl + << "Difference: " << diff.toString() << std::endl + << " Tolerance: " << tolerance_.toString(diff); + } - private: - FloatType value_; - FloatingPointTolerance tolerance_; +private: + FloatType value_; + FloatingPointTolerance tolerance_; }; -template +template class FloatingPointFromStringChecker : public IReferenceDataEntryChecker { - public: - FloatingPointFromStringChecker( - const std::string &value, const FloatingPointTolerance &tolerance) - : value_(value), tolerance_(tolerance) - { - } +public: + FloatingPointFromStringChecker(const std::string& value, const FloatingPointTolerance& tolerance) : + value_(value), + tolerance_(tolerance) + { + } - void fillEntry(ReferenceDataEntry *entry) const override - { - entry->setValue(value_); - } - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string &fullId) const override + void fillEntry(ReferenceDataEntry* entry) const override { entry->setValue(value_); } + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, const std::string& fullId) const override + { + FloatType value = fromString(value_); + FloatType refValue = static_cast(convertDoubleReferenceValue(entry.value())); + FloatingPointDifference diff(refValue, value); + if (tolerance_.isWithin(diff)) { - FloatType value = fromString(value_); - FloatType refValue = static_cast(convertDoubleReferenceValue(entry.value())); - FloatingPointDifference diff(refValue, value); - if (tolerance_.isWithin(diff)) - { - return ::testing::AssertionSuccess(); - } - return ::testing::AssertionFailure() - << " In item: " << fullId << std::endl - << " Actual: " << value << std::endl - << " Reference: " << entry.value() << std::endl - << "Difference: " << diff.toString() << std::endl - << " Tolerance: " << tolerance_.toString(diff); + return ::testing::AssertionSuccess(); } + return ::testing::AssertionFailure() << " In item: " << fullId << std::endl + << " Actual: " << value << std::endl + << " Reference: " << entry.value() << std::endl + << "Difference: " << diff.toString() << std::endl + << " Tolerance: " << tolerance_.toString(diff); + } - private: - std::string value_; - FloatingPointTolerance tolerance_; +private: + std::string value_; + FloatingPointTolerance tolerance_; }; -template +template class ValueExtractor : public IReferenceDataEntryChecker { - public: - explicit ValueExtractor(ValueType *value) - : value_(value) - { - } +public: + explicit ValueExtractor(ValueType* value) : value_(value) {} - void fillEntry(ReferenceDataEntry * /*entry*/) const override - { - GMX_THROW(TestException("Extracting value from non-existent reference data entry")); - } - ::testing::AssertionResult - checkEntry(const ReferenceDataEntry &entry, const std::string & /*fullId*/) const override - { - extractValue(entry.value()); - return ::testing::AssertionSuccess(); - } + void fillEntry(ReferenceDataEntry* /*entry*/) const override + { + GMX_THROW(TestException("Extracting value from non-existent reference data entry")); + } + ::testing::AssertionResult checkEntry(const ReferenceDataEntry& entry, + const std::string& /*fullId*/) const override + { + extractValue(entry.value()); + return ::testing::AssertionSuccess(); + } - void extractValue(const std::string &value) const - { - *value_ = fromString(value); - } + void extractValue(const std::string& value) const { *value_ = fromString(value); } - private: - ValueType *value_; +private: + ValueType* value_; }; -template <> inline void -ValueExtractor::extractValue(const std::string &value) const +template<> +inline void ValueExtractor::extractValue(const std::string& value) const { *value_ = value; } diff --git a/src/testutils/refdata_impl.h b/src/testutils/refdata_impl.h index 93f0798bc4..891a6b590f 100644 --- a/src/testutils/refdata_impl.h +++ b/src/testutils/refdata_impl.h @@ -55,144 +55,134 @@ namespace test class ReferenceDataEntry { - public: - typedef std::unique_ptr EntryPointer; - typedef std::list ChildList; - typedef ChildList::const_iterator ChildIterator; - - static EntryPointer createRoot() - { - return std::make_unique("", ""); - } - - ReferenceDataEntry(const char *type, const char *id) - : type_(type), id_(id != nullptr ? id : ""), isTextBlock_(false), - hasBeenChecked_(false), correspondingOutputEntry_(nullptr) +public: + typedef std::unique_ptr EntryPointer; + typedef std::list ChildList; + typedef ChildList::const_iterator ChildIterator; + + static EntryPointer createRoot() { return std::make_unique("", ""); } + + ReferenceDataEntry(const char* type, const char* id) : + type_(type), + id_(id != nullptr ? id : ""), + isTextBlock_(false), + hasBeenChecked_(false), + correspondingOutputEntry_(nullptr) + { + } + + const std::string& type() const { return type_; } + const std::string& id() const { return id_; } + bool isCompound() const { return !children_.empty(); } + bool isTextBlock() const { return isTextBlock_; } + const std::string& value() const { return value_; } + const ChildList& children() const { return children_; } + ReferenceDataEntry* correspondingOutputEntry() const { return correspondingOutputEntry_; } + + bool idMatches(const char* id) const + { + return (id == nullptr && id_.empty()) || (id != nullptr && id_ == id); + } + + ChildIterator findChild(const char* id, const ChildIterator& prev) const + { + if (children_.empty()) { + return children_.end(); } - - const std::string &type() const { return type_; } - const std::string &id() const { return id_; } - bool isCompound() const { return !children_.empty(); } - bool isTextBlock() const { return isTextBlock_; } - const std::string &value() const { return value_; } - const ChildList &children() const { return children_; } - ReferenceDataEntry *correspondingOutputEntry() const - { - return correspondingOutputEntry_; - } - - bool idMatches(const char *id) const + ChildIterator child = prev; + bool wrappingSearch = true; + if (child != children_.end()) { - return (id == nullptr && id_.empty()) || (id != nullptr && id_ == id); - } - - ChildIterator findChild(const char *id, const ChildIterator &prev) const - { - if (children_.empty()) - { - return children_.end(); - } - ChildIterator child = prev; - bool wrappingSearch = true; - if (child != children_.end()) - { - if (id == nullptr && (*child)->id().empty()) - { - wrappingSearch = false; - ++child; - if (child == children_.end()) - { - return children_.end(); - } - } - } - else + if (id == nullptr && (*child)->id().empty()) { - child = children_.begin(); wrappingSearch = false; - } - do - { - if ((*child)->idMatches(id)) - { - return child; - } ++child; - if (wrappingSearch && child == children_.end()) + if (child == children_.end()) { - child = children_.begin(); + return children_.end(); } } - while (child != children_.end() && child != prev); - return children_.end(); } - bool isValidChild(const ChildIterator &prev) const + else { - return prev != children_.end(); + child = children_.begin(); + wrappingSearch = false; } - - bool hasBeenChecked() const { return hasBeenChecked_; } - void setChecked() { hasBeenChecked_ = true; } - - void setCheckedIncludingChildren() + do { - setChecked(); - for (const auto &child : children_) + if ((*child)->idMatches(id)) { - child->setCheckedIncludingChildren(); + return child; } - } - - EntryPointer cloneToOutputEntry() - { - EntryPointer entry(new ReferenceDataEntry(type_.c_str(), id_.c_str())); - setCorrespondingOutputEntry(entry.get()); - entry->setValue(value()); - entry->isTextBlock_ = isTextBlock_; - return entry; - } - - void setValue(const std::string &value) - { - GMX_RELEASE_ASSERT(!isCompound(), - "Cannot have a value for a compound entry"); - value_ = value; - } - void setTextBlockValue(const std::string &value) - { - GMX_RELEASE_ASSERT(!isCompound(), - "Cannot have a value for a compound entry"); - value_ = value; - isTextBlock_ = true; - } - void makeCompound(const char *type) - { - type_.assign(type); - value_.clear(); - isTextBlock_ = false; - } - void setCorrespondingOutputEntry(ReferenceDataEntry *entry) - { - GMX_RELEASE_ASSERT(correspondingOutputEntry_ == nullptr, - "Output entry already exists"); - correspondingOutputEntry_ = entry; - } - ChildIterator addChild(EntryPointer child) + ++child; + if (wrappingSearch && child == children_.end()) + { + child = children_.begin(); + } + } while (child != children_.end() && child != prev); + return children_.end(); + } + bool isValidChild(const ChildIterator& prev) const { return prev != children_.end(); } + + bool hasBeenChecked() const { return hasBeenChecked_; } + void setChecked() { hasBeenChecked_ = true; } + + void setCheckedIncludingChildren() + { + setChecked(); + for (const auto& child : children_) { - GMX_RELEASE_ASSERT(isCompound() || value_.empty(), - "Cannot make an entry with a value to a compound"); - return children_.insert(children_.end(), move(child)); + child->setCheckedIncludingChildren(); } - - private: - std::string type_; - std::string id_; - std::string value_; - bool isTextBlock_; - ChildList children_; - bool hasBeenChecked_; - ReferenceDataEntry *correspondingOutputEntry_; + } + + EntryPointer cloneToOutputEntry() + { + EntryPointer entry(new ReferenceDataEntry(type_.c_str(), id_.c_str())); + setCorrespondingOutputEntry(entry.get()); + entry->setValue(value()); + entry->isTextBlock_ = isTextBlock_; + return entry; + } + + void setValue(const std::string& value) + { + GMX_RELEASE_ASSERT(!isCompound(), "Cannot have a value for a compound entry"); + value_ = value; + } + void setTextBlockValue(const std::string& value) + { + GMX_RELEASE_ASSERT(!isCompound(), "Cannot have a value for a compound entry"); + value_ = value; + isTextBlock_ = true; + } + void makeCompound(const char* type) + { + type_.assign(type); + value_.clear(); + isTextBlock_ = false; + } + void setCorrespondingOutputEntry(ReferenceDataEntry* entry) + { + GMX_RELEASE_ASSERT(correspondingOutputEntry_ == nullptr, "Output entry already exists"); + correspondingOutputEntry_ = entry; + } + ChildIterator addChild(EntryPointer child) + { + GMX_RELEASE_ASSERT(isCompound() || value_.empty(), + "Cannot make an entry with a value to a compound"); + return children_.insert(children_.end(), move(child)); + } + +private: + std::string type_; + std::string id_; + std::string value_; + bool isTextBlock_; + ChildList children_; + bool hasBeenChecked_; + ReferenceDataEntry* correspondingOutputEntry_; }; } // namespace test diff --git a/src/testutils/refdata_xml.cpp b/src/testutils/refdata_xml.cpp index 50e2e6f4e8..4d2a71775d 100644 --- a/src/testutils/refdata_xml.cpp +++ b/src/testutils/refdata_xml.cpp @@ -60,15 +60,16 @@ namespace { //! XML version declaration used when writing the reference data. -const char *const c_VersionDeclarationString = "xml version=\"1.0\""; +const char* const c_VersionDeclarationString = "xml version=\"1.0\""; //! XML stylesheet declaration used for writing the reference data. -const char *const c_StyleSheetDeclarationString = "xml-stylesheet type=\"text/xsl\" href=\"referencedata.xsl\""; +const char* const c_StyleSheetDeclarationString = + "xml-stylesheet type=\"text/xsl\" href=\"referencedata.xsl\""; //! Name of the root element in reference data XML files. -const char *const c_RootNodeName = "ReferenceData"; +const char* const c_RootNodeName = "ReferenceData"; //! Name of the XML attribute used to store identifying strings for reference data elements. -const char *const c_IdAttrName = "Name"; +const char* const c_IdAttrName = "Name"; -} // namespace +} // namespace /******************************************************************** * XML reading @@ -78,25 +79,23 @@ namespace { //! Convenience typedef -typedef tinyxml2::XMLDocument *XMLDocumentPtr; +typedef tinyxml2::XMLDocument* XMLDocumentPtr; //! Convenience typedef -typedef tinyxml2::XMLNode *XMLNodePtr; +typedef tinyxml2::XMLNode* XMLNodePtr; //! Convenience typedef -typedef tinyxml2::XMLElement *XMLElementPtr; +typedef tinyxml2::XMLElement* XMLElementPtr; //! Convenience typedef -typedef tinyxml2::XMLText *XMLTextPtr; +typedef tinyxml2::XMLText* XMLTextPtr; //! \name Helper functions for XML reading //! \{ -void readEntry(XMLNodePtr node, ReferenceDataEntry *entry); +void readEntry(XMLNodePtr node, ReferenceDataEntry* entry); XMLNodePtr getCDataChildNode(XMLNodePtr node) { XMLNodePtr cdata = node->FirstChild(); - while (cdata != nullptr && - cdata->ToText() != nullptr && - !cdata->ToText()->CData()) + while (cdata != nullptr && cdata->ToText() != nullptr && !cdata->ToText()->CData()) { cdata = cdata->NextSibling(); } @@ -129,7 +128,7 @@ std::string getValueFromLeafElement(XMLNodePtr node) { std::string value; - XMLNodePtr childNode = getNextTextChildNode(node->FirstChild()); + XMLNodePtr childNode = getNextTextChildNode(node->FirstChild()); while (childNode != nullptr) { value += std::string(childNode->Value()); @@ -155,13 +154,13 @@ std::string getValueFromLeafElement(XMLNodePtr node) //! Make a new entry from \c element. ReferenceDataEntry::EntryPointer createEntry(XMLElementPtr element) { - const char *id = element->Attribute(c_IdAttrName); + const char* id = element->Attribute(c_IdAttrName); ReferenceDataEntry::EntryPointer entry(new ReferenceDataEntry(element->Value(), id)); return entry; } //! Read the child entries of \c parentElement and transfer the contents to \c entry -void readChildEntries(XMLNodePtr parentElement, ReferenceDataEntry *entry) +void readChildEntries(XMLNodePtr parentElement, ReferenceDataEntry* entry) { XMLElementPtr childElement = parentElement->FirstChildElement(); while (childElement != nullptr) @@ -180,7 +179,7 @@ bool isCompoundElement(XMLNodePtr node) } //! Read \c element and transfer the contents to \c entry -void readEntry(XMLNodePtr element, ReferenceDataEntry *entry) +void readEntry(XMLNodePtr element, ReferenceDataEntry* entry) { if (isCompoundElement(element)) { @@ -198,18 +197,17 @@ void readEntry(XMLNodePtr element, ReferenceDataEntry *entry) //! \} -} // namespace +} // namespace //! \cond internal -ReferenceDataEntry::EntryPointer -readReferenceDataFile(const std::string &path) +ReferenceDataEntry::EntryPointer readReferenceDataFile(const std::string& path) { tinyxml2::XMLDocument document; document.LoadFile(path.c_str()); if (document.Error()) { - const char *errorStr1 = document.GetErrorStr1(); - const char *errorStr2 = document.GetErrorStr2(); + const char* errorStr1 = document.GetErrorStr1(); + const char* errorStr2 = document.GetErrorStr2(); std::string errorString("Error was "); if (errorStr1) { @@ -223,7 +221,8 @@ readReferenceDataFile(const std::string &path) { errorString += "not specified."; } - GMX_THROW(TestException("Reference data not parsed successfully: " + path + "\n." + errorString + "\n")); + GMX_THROW(TestException("Reference data not parsed successfully: " + path + "\n." + + errorString + "\n")); } XMLElementPtr rootNode = document.RootElement(); if (rootNode == nullptr) @@ -251,10 +250,9 @@ namespace //! \name Helper functions for XML writing //! \{ -void createElementAndContents(XMLElementPtr parentElement, - const ReferenceDataEntry &entry); +void createElementAndContents(XMLElementPtr parentElement, const ReferenceDataEntry& entry); -void setIdAttribute(XMLElementPtr element, const std::string &id) +void setIdAttribute(XMLElementPtr element, const std::string& id) { if (!id.empty()) { @@ -262,7 +260,7 @@ void setIdAttribute(XMLElementPtr element, const std::string &id) } } -XMLElementPtr createElement(XMLElementPtr parentElement, const ReferenceDataEntry &entry) +XMLElementPtr createElement(XMLElementPtr parentElement, const ReferenceDataEntry& entry) { XMLElementPtr element = parentElement->GetDocument()->NewElement(entry.type().c_str()); parentElement->InsertEndChild(element); @@ -270,9 +268,9 @@ XMLElementPtr createElement(XMLElementPtr parentElement, const ReferenceDataEntr return element; } -void createChildElements(XMLElementPtr parentElement, const ReferenceDataEntry &entry) +void createChildElements(XMLElementPtr parentElement, const ReferenceDataEntry& entry) { - const ReferenceDataEntry::ChildList &children(entry.children()); + const ReferenceDataEntry::ChildList& children(entry.children()); ReferenceDataEntry::ChildIterator child; for (child = children.begin(); child != children.end(); ++child) { @@ -291,7 +289,7 @@ void createChildElements(XMLElementPtr parentElement, const ReferenceDataEntry & * This is an edge case that is unimportant for GROMACS refdata, but * it is preferable to know that the infrastructure won't break. */ -std::vector breakUpAnyCdataEndTags(const std::string &input) +std::vector breakUpAnyCdataEndTags(const std::string& input) { std::vector strings; std::size_t startPos = 0; @@ -307,13 +305,12 @@ std::vector breakUpAnyCdataEndTags(const std::string &input) } strings.push_back(input.substr(startPos, endPos)); startPos = endPos; - } - while (endPos != std::string::npos); + } while (endPos != std::string::npos); return strings; } -void createElementContents(XMLElementPtr element, const ReferenceDataEntry &entry) +void createElementContents(XMLElementPtr element, const ReferenceDataEntry& entry) { // TODO: Figure out if \r and \r\n can be handled without them // changing to \n in the roundtrip. @@ -328,7 +325,7 @@ void createElementContents(XMLElementPtr element, const ReferenceDataEntry &entr // of the starting CDATA tag). const std::string adjustedValue = "\n" + entry.value(); std::vector cdataStrings = breakUpAnyCdataEndTags(adjustedValue); - for (auto const &s : cdataStrings) + for (auto const& s : cdataStrings) { XMLTextPtr textNode = element->GetDocument()->NewText(s.c_str()); textNode->SetCData(true); @@ -342,7 +339,7 @@ void createElementContents(XMLElementPtr element, const ReferenceDataEntry &entr } } -void createElementAndContents(XMLElementPtr parentElement, const ReferenceDataEntry &entry) +void createElementAndContents(XMLElementPtr parentElement, const ReferenceDataEntry& entry) { XMLElementPtr element = createElement(parentElement, entry); createElementContents(element, entry); @@ -357,16 +354,15 @@ XMLElementPtr createRootElement(XMLDocumentPtr document) //! \} -} // namespace +} // namespace //! \cond internal -void writeReferenceDataFile(const std::string &path, - const ReferenceDataEntry &rootEntry) +void writeReferenceDataFile(const std::string& path, const ReferenceDataEntry& rootEntry) { // TODO: Error checking - tinyxml2::XMLDocument document; + tinyxml2::XMLDocument document; - tinyxml2::XMLDeclaration *declaration = document.NewDeclaration(c_VersionDeclarationString); + tinyxml2::XMLDeclaration* declaration = document.NewDeclaration(c_VersionDeclarationString); document.InsertEndChild(declaration); declaration = document.NewDeclaration(c_StyleSheetDeclarationString); diff --git a/src/testutils/refdata_xml.h b/src/testutils/refdata_xml.h index fd56e34652..d2a9707ccf 100644 --- a/src/testutils/refdata_xml.h +++ b/src/testutils/refdata_xml.h @@ -64,8 +64,7 @@ class ReferenceDataEntry; * * \ingroup module_testutils */ -ReferenceDataEntry::EntryPointer -readReferenceDataFile(const std::string &path); +ReferenceDataEntry::EntryPointer readReferenceDataFile(const std::string& path); /*! \internal * \brief * Saves reference data to an XML file. @@ -76,8 +75,7 @@ readReferenceDataFile(const std::string &path); * * \ingroup module_testutils */ -void writeReferenceDataFile(const std::string &path, - const ReferenceDataEntry &root); +void writeReferenceDataFile(const std::string& path, const ReferenceDataEntry& root); //! \endcond } // namespace test diff --git a/src/testutils/setenv.h b/src/testutils/setenv.h index 8418f02c5d..588d93f921 100644 --- a/src/testutils/setenv.h +++ b/src/testutils/setenv.h @@ -47,16 +47,16 @@ #include #ifndef GMX_TESTUTILS_SETENV_H -#define GMX_TESTUTILS_SETENV_H +# define GMX_TESTUTILS_SETENV_H namespace gmx { namespace test { //! Workaround to make setenv work on Windows -inline int gmxSetenv(const char * name, const char * value, int overwrite) +inline int gmxSetenv(const char* name, const char* value, int overwrite) { -#if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS if (!overwrite) { size_t size = 0; @@ -67,21 +67,21 @@ inline int gmxSetenv(const char * name, const char * value, int overwrite) } } return _putenv_s(name, value); -#else +# else return setenv(name, value, overwrite); -#endif +# endif } //! Workaround to make unsetenv work on Windows -inline int gmxUnsetenv(const char * name) +inline int gmxUnsetenv(const char* name) { -#if GMX_NATIVE_WINDOWS +# if GMX_NATIVE_WINDOWS return _putenv_s(name, ""); -#else +# else return unsetenv(name); -#endif +# endif } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif // GMX_TESTUTILS_SETENV_H diff --git a/src/testutils/simulationdatabase.cpp b/src/testutils/simulationdatabase.cpp index 7215252694..d628e2b7ab 100644 --- a/src/testutils/simulationdatabase.cpp +++ b/src/testutils/simulationdatabase.cpp @@ -69,183 +69,69 @@ struct DatabaseEntry using MdpFileValues = std::map; //! Database of .mdp strings that supports prepareDefaultMdpValues() -const MdpFileValues mdpFileValueDatabase_g -{ +const MdpFileValues mdpFileValueDatabase_g{ // Simple system with 12 argon atoms, fairly widely separated - { - "argon12", { { { - "ref-t", "80" - }, - { - "compressibility", "5e-10" - }, - { - "tau-p", "1000" - } }, - { - 1, 2, 3, 4 - } } - }, + { "argon12", + { { { "ref-t", "80" }, { "compressibility", "5e-10" }, { "tau-p", "1000" } }, { 1, 2, 3, 4 } } }, // Simple system with 5 water molecules, fairly widely separated - { - "tip3p5", { { { - "compressibility", "5e-10" - }, - { - "tau-p", "1000" - } }, - { - 1, 2, 3, 4, 5, 6, 8, 9 - } } - }, + { "tip3p5", { { { "compressibility", "5e-10" }, { "tau-p", "1000" } }, { 1, 2, 3, 4, 5, 6, 8, 9 } } }, // Simple system with 5832 argon atoms, suitable for normal pressure coupling - { - "argon5832", { { { - "ref-t", "80" - } }, - { - // TODO This test case is not currently used, so we - // have not tested which rank counts work. - 1, 2, 3, 4, 5, 6, 7, 8, 9 - } } - }, + { "argon5832", + { { { "ref-t", "80" } }, + { // TODO This test case is not currently used, so we + // have not tested which rank counts work. + 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, // Simple system with 2 nearby water molecules - { - "spc2", { { }, - { - // TODO This test case is not currently used, so we - // have not tested which rank counts work. - 1, 2, 3, 4, 5, 6, 7, 8, 9 - } } - }, + { "spc2", + { {}, + { // TODO This test case is not currently used, so we + // have not tested which rank counts work. + 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, // Simple system with 216 water molecules, condensed phase - { - "spc216", { { }, - { - // TODO This test case is not currently used, so we - // have not tested which rank counts work. - 1, 2, 3, 4, 5, 6, 7, 8, 9 // TODO tpi test - } } - }, + { "spc216", + { {}, + { + // TODO This test case is not currently used, so we + // have not tested which rank counts work. + 1, 2, 3, 4, 5, 6, 7, 8, 9 // TODO tpi test + } } }, // Capped alanine peptide in vacuo with virtual sites - { - "alanine_vsite_vacuo", { { { - "constraints", "all-bonds" - }, - { - "compressibility", "5e-10" - }, - { - "tau-p", "1000" - } }, - { - 1, 2, 3, 4, 6, 9 - } } - }, + { "alanine_vsite_vacuo", + { { { "constraints", "all-bonds" }, { "compressibility", "5e-10" }, { "tau-p", "1000" } }, + { 1, 2, 3, 4, 6, 9 } } }, // Capped alanine peptide in aqueous condensed phase, with virtual sites - { - "alanine_vsite_solvated", { { { - "constraints", "all-bonds" - }, - { - "compressibility", "5e-10" - }, - { - "tau-p", "1000" - } }, - { - // TODO This test case is not currently used, so we - // have not tested which rank counts work. - 1, 2, 3, 4, 5, 6, 7, 8, 9 - } } - }, + { "alanine_vsite_solvated", + { { { "constraints", "all-bonds" }, { "compressibility", "5e-10" }, { "tau-p", "1000" } }, + { // TODO This test case is not currently used, so we + // have not tested which rank counts work. + 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, // Zwitterionic glycine in vacuo - { - "glycine_vacuo", { { { - "constraints", "h-bonds" - } }, - { - 1, 2, 3, 4, 5, 6, 7, 8, 9 - } } - }, + { "glycine_vacuo", { { { "constraints", "h-bonds" } }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, // Zwitterionic glycine in vacuo, without constraints - { - "glycine_no_constraints_vacuo", { { { - "constraints", "none" - } }, - { - 1, 2, 3, 4, 5, 6, 7, 8, 9 - } } - }, + { "glycine_no_constraints_vacuo", { { { "constraints", "none" } }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, // Simple mdrun tests of energy - { - "angles1", { { }, - { - 1, 2 - } } - }, + { "angles1", { {}, { 1, 2 } } }, // Scaled water for NMA - { - "scaled-water", { { }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "scaled-water", { {}, { 1, 2, 3, 4, 5, 6 } } }, // Villin for NMA - { - "villin", { { }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "villin", { {}, { 1, 2, 3, 4, 5, 6 } } }, // SPC-Dimer for NMA - { - "spc-dimer", { { }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "spc-dimer", { {}, { 1, 2, 3, 4, 5, 6 } } }, // SW-Dimer for NMA - { - "sw-dimer", { { { - "nstcalcenergy", "1" - } }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "sw-dimer", { { { "nstcalcenergy", "1" } }, { 1, 2, 3, 4, 5, 6 } } }, // TIP5P for NMA - { - "one-tip5p", { { }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "one-tip5p", { {}, { 1, 2, 3, 4, 5, 6 } } }, // ICE-Binding protein for NMA - { - "ice-binding", { { }, - { - 1, 2, 3, 4, 5, 6 - } } - }, + { "ice-binding", { {}, { 1, 2, 3, 4, 5, 6 } } }, // Nonanol molecule in vacuo, topology suitable for testing FEP // on KE, angles, dihedral restraints, coulomb and vdw - { - "nonanol_vacuo", { { { - "nsteps", "16" - }, - { - "compressibility", "5e-10" - }, - { - "tau-p", "1000" - }, - { - "constraints", "h-bonds" - }, - { - "other", - R"(free-energy = yes + { "nonanol_vacuo", + { { { "nsteps", "16" }, + { "compressibility", "5e-10" }, + { "tau-p", "1000" }, + { "constraints", "h-bonds" }, + { "other", + R"(free-energy = yes sc-alpha = 0.5 sc-r-power = 6 mass-lambdas = 0.0 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 @@ -256,12 +142,8 @@ const MdpFileValues mdpFileValueDatabase_g ;couple-moltype = nonanol ;couple-lambda0 = none ;couple-lambda1 = vdw-q - ;couple-intramol = yes)" - } }, - { - 1, 2, 3, 4, 5, 6, 8, 9 - } } - } + ;couple-intramol = yes)" } }, + { 1, 2, 3, 4, 5, 6, 8, 9 } } } }; /*! \brief Prepare default .mdp values @@ -276,7 +158,7 @@ const MdpFileValues mdpFileValueDatabase_g * * \throws std::bad_alloc if out of memory * std::out_of_range if \c simulationName is not in the database */ -MdpFieldValues prepareDefaultMdpFieldValues(const std::string &simulationName) +MdpFieldValues prepareDefaultMdpFieldValues(const std::string& simulationName) { using MdpField = MdpFieldValues::value_type; @@ -304,30 +186,26 @@ MdpFieldValues prepareDefaultMdpFieldValues(const std::string &simulationName) return mdpFieldValues; } -} // namespace +} // namespace -bool -isNumberOfPpRanksSupported(const std::string &simulationName, - int possibleNumberOfPpRanks) +bool isNumberOfPpRanksSupported(const std::string& simulationName, int possibleNumberOfPpRanks) { - const auto &possibleNumbers = mdpFileValueDatabase_g.at(simulationName).validPpRankCounts; - return (std::find(std::begin(possibleNumbers), std::end(possibleNumbers), - possibleNumberOfPpRanks) != std::end(possibleNumbers)); + const auto& possibleNumbers = mdpFileValueDatabase_g.at(simulationName).validPpRankCounts; + return (std::find(std::begin(possibleNumbers), std::end(possibleNumbers), possibleNumberOfPpRanks) + != std::end(possibleNumbers)); } -std::string -reportNumbersOfPpRanksSupported(const std::string &simulationName) +std::string reportNumbersOfPpRanksSupported(const std::string& simulationName) { - const auto &possibleNumbers = mdpFileValueDatabase_g.at(simulationName).validPpRankCounts; - return formatAndJoin(std::begin(possibleNumbers), std::end(possibleNumbers), - ",", StringFormatter("%d")); + const auto& possibleNumbers = mdpFileValueDatabase_g.at(simulationName).validPpRankCounts; + return formatAndJoin(std::begin(possibleNumbers), std::end(possibleNumbers), ",", + StringFormatter("%d")); } -MdpFieldValues -prepareMdpFieldValues(const std::string &simulationName, - const std::string &integrator, - const std::string &tcoupl, - const std::string &pcoupl) +MdpFieldValues prepareMdpFieldValues(const std::string& simulationName, + const std::string& integrator, + const std::string& tcoupl, + const std::string& pcoupl) { using MdpField = MdpFieldValues::value_type; @@ -338,16 +216,14 @@ prepareMdpFieldValues(const std::string &simulationName, return mdpFieldValues; } -MdpFieldValues -prepareMdpFieldValues(const char *simulationName, - const char *integrator, - const char *tcoupl, - const char *pcoupl) +MdpFieldValues prepareMdpFieldValues(const char* simulationName, + const char* integrator, + const char* tcoupl, + const char* pcoupl) { return prepareMdpFieldValues(std::string(simulationName), integrator, tcoupl, pcoupl); } -std::string -prepareMdpFileContents(const MdpFieldValues &mdpFieldValues) +std::string prepareMdpFileContents(const MdpFieldValues& mdpFieldValues) { /* Set up an .mdp file that permits a highly reproducible * simulation. The format string needs to be configured with @@ -368,7 +244,8 @@ prepareMdpFileContents(const MdpFieldValues &mdpFieldValues) * energies were not computed with those from rerun on the same * coordinates. */ - return formatString(R"(rcoulomb = %s + return formatString( + R"(rcoulomb = %s rvdw = %s rlist = -1 bd-fric = 1000 @@ -402,28 +279,17 @@ prepareMdpFileContents(const MdpFieldValues &mdpFieldValues) comm-mode = %s nstcomm = %s %s)", - mdpFieldValues.at("rcoulomb").c_str(), - mdpFieldValues.at("rvdw").c_str(), - mdpFieldValues.at("nsteps").c_str(), - mdpFieldValues.at("nstenergy").c_str(), - mdpFieldValues.at("nstxout").c_str(), - mdpFieldValues.at("nstvout").c_str(), - mdpFieldValues.at("nstfout").c_str(), - mdpFieldValues.at("nstxout-compressed").c_str(), - mdpFieldValues.at("nstdhdl").c_str(), - mdpFieldValues.at("integrator").c_str(), - mdpFieldValues.at("tcoupl").c_str(), - mdpFieldValues.at("nsttcouple").c_str(), - mdpFieldValues.at("ref-t").c_str(), - mdpFieldValues.at("pcoupl").c_str(), - mdpFieldValues.at("nstpcouple").c_str(), - mdpFieldValues.at("tau-p").c_str(), - mdpFieldValues.at("compressibility").c_str(), - mdpFieldValues.at("constraints").c_str(), - mdpFieldValues.at("nstcalcenergy").c_str(), - mdpFieldValues.at("comm-mode").c_str(), - mdpFieldValues.at("nstcomm").c_str(), - mdpFieldValues.at("other").c_str()); + mdpFieldValues.at("rcoulomb").c_str(), mdpFieldValues.at("rvdw").c_str(), + mdpFieldValues.at("nsteps").c_str(), mdpFieldValues.at("nstenergy").c_str(), + mdpFieldValues.at("nstxout").c_str(), mdpFieldValues.at("nstvout").c_str(), + mdpFieldValues.at("nstfout").c_str(), mdpFieldValues.at("nstxout-compressed").c_str(), + mdpFieldValues.at("nstdhdl").c_str(), mdpFieldValues.at("integrator").c_str(), + mdpFieldValues.at("tcoupl").c_str(), mdpFieldValues.at("nsttcouple").c_str(), + mdpFieldValues.at("ref-t").c_str(), mdpFieldValues.at("pcoupl").c_str(), + mdpFieldValues.at("nstpcouple").c_str(), mdpFieldValues.at("tau-p").c_str(), + mdpFieldValues.at("compressibility").c_str(), mdpFieldValues.at("constraints").c_str(), + mdpFieldValues.at("nstcalcenergy").c_str(), mdpFieldValues.at("comm-mode").c_str(), + mdpFieldValues.at("nstcomm").c_str(), mdpFieldValues.at("other").c_str()); } } // namespace test diff --git a/src/testutils/simulationdatabase.h b/src/testutils/simulationdatabase.h index 31b18d3fc1..11b1e428d9 100644 --- a/src/testutils/simulationdatabase.h +++ b/src/testutils/simulationdatabase.h @@ -57,14 +57,11 @@ namespace test * * This method lets test runners understand when end-to-end tests * should be expected to work. */ -bool -isNumberOfPpRanksSupported(const std::string &simulationName, - int possibleNumberOfPpRanks); +bool isNumberOfPpRanksSupported(const std::string& simulationName, int possibleNumberOfPpRanks); /*! \brief Return a string describing the numbers of ranks supported * for the simulation \c simulationName in the database. */ -std::string -reportNumbersOfPpRanksSupported(const std::string &simulationName); +std::string reportNumbersOfPpRanksSupported(const std::string& simulationName); //! Helper typedef using MdpFieldValues = std::map; @@ -103,24 +100,21 @@ using MdpFieldValues = std::map; * * \throws std::bad_alloc if out of memory * std::out_of_range if \c simulationName is not in the database */ -MdpFieldValues -prepareMdpFieldValues(const std::string &simulationName, - const std::string &integrator, - const std::string &tcoupl, - const std::string &pcoupl); +MdpFieldValues prepareMdpFieldValues(const std::string& simulationName, + const std::string& integrator, + const std::string& tcoupl, + const std::string& pcoupl); //! \copydoc prepareMdpFieldValues() -MdpFieldValues -prepareMdpFieldValues(const char *simulationName, - const char *integrator, - const char *tcoupl, - const char *pcoupl); +MdpFieldValues prepareMdpFieldValues(const char* simulationName, + const char* integrator, + const char* tcoupl, + const char* pcoupl); /*! \brief Make a string containing an .mdp file from the \c mdpFieldValues. * * \throws std::bad_alloc if out of memory */ -std::string -prepareMdpFileContents(const MdpFieldValues &mdpFieldValues); +std::string prepareMdpFileContents(const MdpFieldValues& mdpFieldValues); } // namespace test } // namespace gmx diff --git a/src/testutils/stdiohelper.cpp b/src/testutils/stdiohelper.cpp index 60b95cf6eb..4afb9ba460 100644 --- a/src/testutils/stdiohelper.cpp +++ b/src/testutils/stdiohelper.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2015,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,16 +60,13 @@ namespace test * StdioTestHelper */ -void -StdioTestHelper::redirectStringToStdin(const char *theString) +void StdioTestHelper::redirectStringToStdin(const char* theString) { const std::string fakeStdin = fileManager_.getTemporaryFilePath(".stdin"); gmx::TextWriter::writeFileFromString(fakeStdin, theString); if (nullptr == std::freopen(fakeStdin.c_str(), "r", stdin)) { - GMX_THROW_WITH_ERRNO(FileIOError("Failed to redirect a string to stdin"), - "freopen", - errno); + GMX_THROW_WITH_ERRNO(FileIOError("Failed to redirect a string to stdin"), "freopen", errno); } } diff --git a/src/testutils/stdiohelper.h b/src/testutils/stdiohelper.h index c111476ce4..6cb8b68947 100644 --- a/src/testutils/stdiohelper.h +++ b/src/testutils/stdiohelper.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2013,2014,2017, by the GROMACS development team, led by + * Copyright (c) 2013,2014,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,25 +62,22 @@ class TestFileManager; */ class StdioTestHelper { - public: - //! Creates a helper using the given file manager. - explicit StdioTestHelper(TestFileManager *fileManager) - : fileManager_(*fileManager) - { - } +public: + //! Creates a helper using the given file manager. + explicit StdioTestHelper(TestFileManager* fileManager) : fileManager_(*fileManager) {} - /*! \brief Accepts a string as input, writes it to a temporary - * file and then reopens stdin to read the contents of that - * string. - * - * \throws FileIOError when the freopen() fails - */ - void redirectStringToStdin(const char *theString); + /*! \brief Accepts a string as input, writes it to a temporary + * file and then reopens stdin to read the contents of that + * string. + * + * \throws FileIOError when the freopen() fails + */ + void redirectStringToStdin(const char* theString); - private: - TestFileManager &fileManager_; +private: + TestFileManager& fileManager_; - GMX_DISALLOW_COPY_AND_ASSIGN(StdioTestHelper); + GMX_DISALLOW_COPY_AND_ASSIGN(StdioTestHelper); }; } // namespace test diff --git a/src/testutils/stringtest.cpp b/src/testutils/stringtest.cpp index c08f8cf55e..452c300435 100644 --- a/src/testutils/stringtest.cpp +++ b/src/testutils/stringtest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,7 +61,7 @@ namespace { //! Stores the -stdout flag value to print out values instead of checking them. bool g_bWriteToStdOut = false; -} +} // namespace // TODO: Only add this option to those test binaries that actually need it // (depending on the linker, it may or may not appear right now), @@ -70,9 +70,7 @@ bool g_bWriteToStdOut = false; GMX_TEST_OPTIONS(StringTestOptions, options) { options->addOption( - BooleanOption("stdout") - .store(&g_bWriteToStdOut) - .description("Print the test string to stdout instead of checking against reference data")); + BooleanOption("stdout").store(&g_bWriteToStdOut).description("Print the test string to stdout instead of checking against reference data")); } //! \endcond @@ -82,9 +80,9 @@ GMX_TEST_OPTIONS(StringTestOptions, options) class StringTestBase::Impl { - public: - TestReferenceData data_; - TestReferenceChecker checker_; +public: + TestReferenceData data_; + TestReferenceChecker checker_; }; /******************************************************************** @@ -92,8 +90,7 @@ class StringTestBase::Impl */ // static -void StringTestBase::checkText(TestReferenceChecker *checker, - const std::string &text, const char *id) +void StringTestBase::checkText(TestReferenceChecker* checker, const std::string& text, const char* id) { if (g_bWriteToStdOut) { @@ -106,17 +103,11 @@ void StringTestBase::checkText(TestReferenceChecker *checker, } } -StringTestBase::StringTestBase() - : impl_(new Impl) -{ -} +StringTestBase::StringTestBase() : impl_(new Impl) {} -StringTestBase::~StringTestBase() -{ -} +StringTestBase::~StringTestBase() {} -TestReferenceChecker & -StringTestBase::checker() +TestReferenceChecker& StringTestBase::checker() { if (!impl_->checker_) { @@ -125,22 +116,18 @@ StringTestBase::checker() return impl_->checker_; } -void -StringTestBase::checkText(const std::string &text, const char *id) +void StringTestBase::checkText(const std::string& text, const char* id) { checkText(&checker(), text, id); } -void -StringTestBase::checkFileContents(const std::string &filename, const char *id) +void StringTestBase::checkFileContents(const std::string& filename, const char* id) { const std::string text = TextReader::readFileToString(filename); checkText(text, id); } -void -StringTestBase::testFilesEqual(const std::string &refFilename, - const std::string &testFilename) +void StringTestBase::testFilesEqual(const std::string& refFilename, const std::string& testFilename) { const std::string expectedContents = TextReader::readFileToString(refFilename); const std::string contents = TextReader::readFileToString(testFilename); diff --git a/src/testutils/stringtest.h b/src/testutils/stringtest.h index 5685335cb3..dd766d12c5 100644 --- a/src/testutils/stringtest.h +++ b/src/testutils/stringtest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -74,59 +74,57 @@ class TestReferenceChecker; */ class StringTestBase : public ::testing::Test { - public: - /*! \brief - * Checks a block of text. - * - * This static method is provided for code that does not derive from - * StringTestBase to use the same functionality, e.g., implementing the - * `-stdout` option. - */ - static void checkText(TestReferenceChecker *checker, - const std::string &text, const char *id); +public: + /*! \brief + * Checks a block of text. + * + * This static method is provided for code that does not derive from + * StringTestBase to use the same functionality, e.g., implementing the + * `-stdout` option. + */ + static void checkText(TestReferenceChecker* checker, const std::string& text, const char* id); - StringTestBase(); - ~StringTestBase() override; + StringTestBase(); + ~StringTestBase() override; - /*! \brief - * Returns the root checker for this test's reference data. - * - * Can be used to perform custom checks against reference data (e.g., - * if the test needs to check some other values than plain strings. - */ - TestReferenceChecker &checker(); + /*! \brief + * Returns the root checker for this test's reference data. + * + * Can be used to perform custom checks against reference data (e.g., + * if the test needs to check some other values than plain strings. + */ + TestReferenceChecker& checker(); - /*! \brief - * Checks a string. - * - * \param[in] text String to check. - * \param[in] id Unique (within a single test) id for the string. - */ - void checkText(const std::string &text, const char *id); - /*! \brief - * Checks contents of a file as a single string. - * - * \param[in] filename Name of the file to check. - * \param[in] id Unique (within a single test) id for the string. - * - * Provided for convenience. Reads the contents of \p filename into a - * single string and calls checkText(). - */ - void checkFileContents(const std::string &filename, const char *id); + /*! \brief + * Checks a string. + * + * \param[in] text String to check. + * \param[in] id Unique (within a single test) id for the string. + */ + void checkText(const std::string& text, const char* id); + /*! \brief + * Checks contents of a file as a single string. + * + * \param[in] filename Name of the file to check. + * \param[in] id Unique (within a single test) id for the string. + * + * Provided for convenience. Reads the contents of \p filename into a + * single string and calls checkText(). + */ + void checkFileContents(const std::string& filename, const char* id); - /*! \brief - * Tests that contents of two files are equal. - * - * \param[in] refFilename File with the expected contents. - * \param[in] testFilename File with the contents to be tested. - */ - void testFilesEqual(const std::string &refFilename, - const std::string &testFilename); + /*! \brief + * Tests that contents of two files are equal. + * + * \param[in] refFilename File with the expected contents. + * \param[in] testFilename File with the contents to be tested. + */ + void testFilesEqual(const std::string& refFilename, const std::string& testFilename); - private: - class Impl; +private: + class Impl; - PrivateImplPointer impl_; + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/testutils/testasserts.cpp b/src/testutils/testasserts.cpp index afd2b4c622..acf173cd95 100644 --- a/src/testutils/testasserts.cpp +++ b/src/testutils/testasserts.cpp @@ -74,18 +74,18 @@ bool g_showExpectedExceptions = false; GMX_TEST_OPTIONS(ExceptionOptions, options) { options->addOption(BooleanOption("show-error-messages") - .store(&g_showExpectedExceptions) - .description("Show error messages from expected " - "exceptions")); + .store(&g_showExpectedExceptions) + .description("Show error messages from expected " + "exceptions")); } //! \endcond -} // namespace +} // namespace namespace internal { //! \cond internal -void processExpectedException(const std::exception &ex) +void processExpectedException(const std::exception& ex) { if (g_showExpectedExceptions) { @@ -95,7 +95,7 @@ void processExpectedException(const std::exception &ex) } //! \endcond -} // namespace internal +} // namespace internal namespace { @@ -122,9 +122,8 @@ using ::testing::internal::FloatingPoint; * zero, and the order of the integer values matches the order of the * floating-point values. */ -template -typename FloatingPoint::Bits -floatingPointToBiasedInteger(const FloatingPoint &value) +template +typename FloatingPoint::Bits floatingPointToBiasedInteger(const FloatingPoint& value) { if (value.sign_bit()) { @@ -140,23 +139,19 @@ floatingPointToBiasedInteger(const FloatingPoint &value) * Computes the magnitude of the difference in ULPs between two numbers, * treating also values of different sign. */ -template -uint64_t calculateUlpDifference(const FloatingPoint &value1, - const FloatingPoint &value2) +template +uint64_t calculateUlpDifference(const FloatingPoint& value1, const FloatingPoint& value2) { - typename FloatingPoint::Bits biased1 - = floatingPointToBiasedInteger(value1); - typename FloatingPoint::Bits biased2 - = floatingPointToBiasedInteger(value2); + typename FloatingPoint::Bits biased1 = floatingPointToBiasedInteger(value1); + typename FloatingPoint::Bits biased2 = floatingPointToBiasedInteger(value2); return biased1 > biased2 ? biased1 - biased2 : biased2 - biased1; } /*! \brief * Helper to implement the constructors for FloatingPointDifference. */ -template -void initDifference(FloatType raw1, FloatType raw2, double *absoluteDifference, - uint64_t *ulpDifference, bool *bSignDifference) +template +void initDifference(FloatType raw1, FloatType raw2, double* absoluteDifference, uint64_t* ulpDifference, bool* bSignDifference) { FloatingPoint value1(raw1); FloatingPoint value2(raw2); @@ -176,7 +171,7 @@ void initDifference(FloatType raw1, FloatType raw2, double *absoluteDifference, /*! \brief * Converts a relative tolerance into an ULP difference. */ -template +template uint64_t relativeToleranceToUlp(FloatType tolerance) { FloatingPoint m(1.0); @@ -187,25 +182,23 @@ uint64_t relativeToleranceToUlp(FloatType tolerance) //! \} //! \} -} // namespace +} // namespace /******************************************************************** * FloatingPointDifference */ -FloatingPointDifference::FloatingPointDifference(float ref, float value) - : termMagnitude_(std::abs(ref)) +FloatingPointDifference::FloatingPointDifference(float ref, float value) : + termMagnitude_(std::abs(ref)) { - initDifference(ref, value, - &absoluteDifference_, &ulpDifference_, &bSignDifference_); + initDifference(ref, value, &absoluteDifference_, &ulpDifference_, &bSignDifference_); bDouble_ = false; } -FloatingPointDifference::FloatingPointDifference(double ref, double value) - : termMagnitude_(std::abs(ref)) +FloatingPointDifference::FloatingPointDifference(double ref, double value) : + termMagnitude_(std::abs(ref)) { - initDifference(ref, value, - &absoluteDifference_, &ulpDifference_, &bSignDifference_); + initDifference(ref, value, &absoluteDifference_, &ulpDifference_, &bSignDifference_); bDouble_ = true; } @@ -221,7 +214,7 @@ std::string FloatingPointDifference::toString() const if (termMagnitude_ > 0) { // If the reference value is finite we calculate the proper quotient - relDiffStr = formatString("%.3g", std::abs(absoluteDifference_/termMagnitude_)); + relDiffStr = formatString("%.3g", std::abs(absoluteDifference_ / termMagnitude_)); } else if (absoluteDifference_ == 0.0) { @@ -235,10 +228,8 @@ std::string FloatingPointDifference::toString() const relDiffStr = formatString("Inf"); } - return formatString("%g (%" PRIu64 " %s-prec. ULPs, rel. %s)%s", - absoluteDifference_, ulpDifference_, - isDouble() ? "double" : "single", - relDiffStr.c_str(), + return formatString("%g (%" PRIu64 " %s-prec. ULPs, rel. %s)%s", absoluteDifference_, + ulpDifference_, isDouble() ? "double" : "single", relDiffStr.c_str(), bSignDifference_ ? ", signs differ" : ""); } @@ -246,8 +237,7 @@ std::string FloatingPointDifference::toString() const * FloatingPointTolerance */ -bool FloatingPointTolerance::isWithin( - const FloatingPointDifference &difference) const +bool FloatingPointTolerance::isWithin(const FloatingPointDifference& difference) const { if (difference.isNaN()) { @@ -259,8 +249,8 @@ bool FloatingPointTolerance::isWithin( return false; } - const double absoluteTolerance - = difference.isDouble() ? doubleAbsoluteTolerance_ : singleAbsoluteTolerance_; + const double absoluteTolerance = + difference.isDouble() ? doubleAbsoluteTolerance_ : singleAbsoluteTolerance_; if (difference.asAbsolute() < absoluteTolerance) { return true; @@ -269,28 +259,26 @@ bool FloatingPointTolerance::isWithin( // By using smaller-than-or-equal below, we allow the test to pass if // the numbers are identical, even if the term magnitude is 0, which seems // a reasonable thing to do... - const double relativeTolerance - = difference.isDouble() ? doubleRelativeTolerance_ : singleRelativeTolerance_; + const double relativeTolerance = + difference.isDouble() ? doubleRelativeTolerance_ : singleRelativeTolerance_; if (difference.asAbsolute() <= relativeTolerance * difference.termMagnitude()) { return true; } - const uint64_t ulpTolerance - = difference.isDouble() ? doubleUlpTolerance_ : singleUlpTolerance_; + const uint64_t ulpTolerance = difference.isDouble() ? doubleUlpTolerance_ : singleUlpTolerance_; return ulpTolerance < UINT64_MAX && difference.asUlps() <= ulpTolerance; } -std::string FloatingPointTolerance::toString(const FloatingPointDifference &difference) const +std::string FloatingPointTolerance::toString(const FloatingPointDifference& difference) const { - std::string result; - const double absoluteTolerance - = difference.isDouble() ? doubleAbsoluteTolerance_ : singleAbsoluteTolerance_; - const double relativeTolerance - = difference.isDouble() ? doubleRelativeTolerance_ : singleRelativeTolerance_; - const uint64_t ulpTolerance - = difference.isDouble() ? doubleUlpTolerance_ : singleUlpTolerance_; + std::string result; + const double absoluteTolerance = + difference.isDouble() ? doubleAbsoluteTolerance_ : singleAbsoluteTolerance_; + const double relativeTolerance = + difference.isDouble() ? doubleRelativeTolerance_ : singleRelativeTolerance_; + const uint64_t ulpTolerance = difference.isDouble() ? doubleUlpTolerance_ : singleUlpTolerance_; if (absoluteTolerance > 0.0) { @@ -325,25 +313,19 @@ std::string FloatingPointTolerance::toString(const FloatingPointDifference &diff // Doxygen does not recognize this as the same function as in the header... //! \cond -FloatingPointTolerance -relativeToleranceAsFloatingPoint(double magnitude, double tolerance) +FloatingPointTolerance relativeToleranceAsFloatingPoint(double magnitude, double tolerance) { - return relativeToleranceAsPrecisionDependentFloatingPoint( - magnitude, float(tolerance), tolerance); + return relativeToleranceAsPrecisionDependentFloatingPoint(magnitude, float(tolerance), tolerance); } -FloatingPointTolerance -relativeToleranceAsPrecisionDependentFloatingPoint(double magnitude, - float singleTolerance, - double doubleTolerance) +FloatingPointTolerance relativeToleranceAsPrecisionDependentFloatingPoint(double magnitude, + float singleTolerance, + double doubleTolerance) { const float absoluteSingleTolerance = std::abs(float(magnitude)) * singleTolerance; const double absoluteDoubleTolerance = std::abs(magnitude) * doubleTolerance; return { - absoluteSingleTolerance, absoluteDoubleTolerance, - singleTolerance, doubleTolerance, - UINT64_MAX, UINT64_MAX, - false + absoluteSingleTolerance, absoluteDoubleTolerance, singleTolerance, doubleTolerance, UINT64_MAX, UINT64_MAX, false }; } //! \endcond diff --git a/src/testutils/testasserts.h b/src/testutils/testasserts.h index fa0f41f877..1a243802cd 100644 --- a/src/testutils/testasserts.h +++ b/src/testutils/testasserts.h @@ -77,9 +77,9 @@ namespace internal * * \param[in] ex Exception that was thrown. */ -void processExpectedException(const std::exception &ex); +void processExpectedException(const std::exception& ex); //! \endcond -} // namespace internal +} // namespace internal //! \libinternal \addtogroup module_testutils //! \{ @@ -105,36 +105,43 @@ void processExpectedException(const std::exception &ex); * The implementation is copied and adjusted from * include/gtest/internal/gtest-internal.h in Google Test 1.6.0. */ -#define GMX_TEST_THROW_(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) { \ - bool gmx_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (expected_exception const &ex) { \ - gmx_caught_expected = true; \ - ::gmx::test::internal::processExpectedException(ex); \ - } \ - catch (std::exception const &ex) { \ - gmx_ar << "Expected: " #statement " throws an exception of type " \ - << #expected_exception ".\n Actual: it throws a different type.\n" \ - << "Exception details:\n" << ::gmx::formatExceptionMessageToString(ex); \ - goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ - } \ - catch (...) { \ - gmx_ar << "Expected: " #statement " throws an exception of type " \ - << #expected_exception ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ - } \ - if (!gmx_caught_expected) { \ - gmx_ar << "Expected: " #statement " throws an exception of type " \ - << #expected_exception ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__) : \ - fail(gmx_ar.message()) +#define GMX_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) \ + { \ + bool gmx_caught_expected = false; \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const& ex) \ + { \ + gmx_caught_expected = true; \ + ::gmx::test::internal::processExpectedException(ex); \ + } \ + catch (std::exception const& ex) \ + { \ + gmx_ar << "Expected: " #statement " throws an exception of type " \ + << #expected_exception ".\n Actual: it throws a different type.\n" \ + << "Exception details:\n" \ + << ::gmx::formatExceptionMessageToString(ex); \ + goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ + } \ + catch (...) \ + { \ + gmx_ar << "Expected: " #statement " throws an exception of type " \ + << #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ + } \ + if (!gmx_caught_expected) \ + { \ + gmx_ar << "Expected: " #statement " throws an exception of type " \ + << #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__) : fail(gmx_ar.message()) /*! \brief * Internal implementation macro for exception assertations. @@ -145,26 +152,31 @@ void processExpectedException(const std::exception &ex); * The implementation is copied and adjusted from * include/gtest/internal/gtest-internal.h in Google Test 1.6.0. */ -#define GMX_TEST_NO_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) { \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (std::exception const &ex) { \ +#define GMX_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) \ + { \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (std::exception const& ex) \ + { \ gmx_ar << "Expected: " #statement " doesn't throw an exception.\n" \ - << " Actual: it throws.\n" \ - << "Exception details:\n" << ::gmx::formatExceptionMessageToString(ex); \ - goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \ - } \ - catch (...) { \ + << " Actual: it throws.\n" \ + << "Exception details:\n" \ + << ::gmx::formatExceptionMessageToString(ex); \ + goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \ + } \ + catch (...) \ + { \ gmx_ar << "Expected: " #statement " doesn't throw an exception.\n" \ - << " Actual: it throws."; \ - goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__) : \ - fail(gmx_ar.message()) + << " Actual: it throws."; \ + goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__) : fail(gmx_ar.message()) //! \endcond /*! \brief @@ -179,8 +191,7 @@ void processExpectedException(const std::exception &ex); * * \hideinitializer */ -#define EXPECT_NO_THROW_GMX(statement) \ - GMX_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW_GMX(statement) GMX_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) /*! \brief * Asserts that a statement throws a given exception. * @@ -193,8 +204,7 @@ void processExpectedException(const std::exception &ex); * * \hideinitializer */ -#define ASSERT_NO_THROW_GMX(statement) \ - GMX_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW_GMX(statement) GMX_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) //! \} @@ -208,79 +218,77 @@ void processExpectedException(const std::exception &ex); */ class FloatingPointDifference { - public: - - /*! \brief Initializes a single-precision difference. - * - * \param ref First term in difference - * \param value Second term in difference - * - * For absolute and ULP differences the two parameters are equivalent, - * since the difference is symmetric. For relative differences - * the first term is interpreted as the reference value, from which - * we extract the magnitude to compare with. - */ - FloatingPointDifference(float ref, float value); - - /*! \brief Initializes a double-precision difference. - * - * \param ref First term in difference - * \param value Second term in difference - * - * For absolute and ULP differences the two parameters are equivalent, - * since the difference is symmetric. For relative differences - * the first term is interpreted as the reference value, from which - * we extract the magnitude to compare with. - */ - FloatingPointDifference(double ref, double value); - - /*! \brief - * Whether one or both of the compared values were NaN. - * - * If this returns `true`, other accessors return meaningless values. - */ - bool isNaN() const; - //! Returns the difference as an absolute number (always non-negative). - double asAbsolute() const { return absoluteDifference_; } - /*! \brief - * Returns the difference as ULPs (always non-negative). - * - * The ULPs are calculated for the type that corresponds to the - * constructor used to initialize the difference. - * The ULP difference between 0.0 and -0.0 is zero. - */ - uint64_t asUlps() const { return ulpDifference_; } - /*! \brief - * Whether the compared values were of different sign. - * - * 0.0 and -0.0 are treated as positive and negative, respectively. - */ - bool signsDiffer() const { return bSignDifference_; } - /*! \brief - * Whether the difference is between single- or double-precision - * numbers. - */ - bool isDouble() const { return bDouble_; } - //! Formats the difference as a string for assertion failure messages. - std::string toString() const; - - //! Returns the magnitude of the original second term of the difference. - double termMagnitude() const { return termMagnitude_; } - - private: - - //! Save the magnitude of the reference value for relative (i.e., not ULP) tolerance - double termMagnitude_; - //! Stores the absolute difference, or NaN if one or both values were NaN. - double absoluteDifference_; - uint64_t ulpDifference_; - bool bSignDifference_; - /*! \brief - * Whether the difference was computed for single or double precision. - * - * This sets the units for `ulpDifference_`. - */ - bool bDouble_; +public: + /*! \brief Initializes a single-precision difference. + * + * \param ref First term in difference + * \param value Second term in difference + * + * For absolute and ULP differences the two parameters are equivalent, + * since the difference is symmetric. For relative differences + * the first term is interpreted as the reference value, from which + * we extract the magnitude to compare with. + */ + FloatingPointDifference(float ref, float value); + + /*! \brief Initializes a double-precision difference. + * + * \param ref First term in difference + * \param value Second term in difference + * + * For absolute and ULP differences the two parameters are equivalent, + * since the difference is symmetric. For relative differences + * the first term is interpreted as the reference value, from which + * we extract the magnitude to compare with. + */ + FloatingPointDifference(double ref, double value); + + /*! \brief + * Whether one or both of the compared values were NaN. + * + * If this returns `true`, other accessors return meaningless values. + */ + bool isNaN() const; + //! Returns the difference as an absolute number (always non-negative). + double asAbsolute() const { return absoluteDifference_; } + /*! \brief + * Returns the difference as ULPs (always non-negative). + * + * The ULPs are calculated for the type that corresponds to the + * constructor used to initialize the difference. + * The ULP difference between 0.0 and -0.0 is zero. + */ + uint64_t asUlps() const { return ulpDifference_; } + /*! \brief + * Whether the compared values were of different sign. + * + * 0.0 and -0.0 are treated as positive and negative, respectively. + */ + bool signsDiffer() const { return bSignDifference_; } + /*! \brief + * Whether the difference is between single- or double-precision + * numbers. + */ + bool isDouble() const { return bDouble_; } + //! Formats the difference as a string for assertion failure messages. + std::string toString() const; + + //! Returns the magnitude of the original second term of the difference. + double termMagnitude() const { return termMagnitude_; } + +private: + //! Save the magnitude of the reference value for relative (i.e., not ULP) tolerance + double termMagnitude_; + //! Stores the absolute difference, or NaN if one or both values were NaN. + double absoluteDifference_; + uint64_t ulpDifference_; + bool bSignDifference_; + /*! \brief + * Whether the difference was computed for single or double precision. + * + * This sets the units for `ulpDifference_`. + */ + bool bDouble_; }; /*! \libinternal \brief @@ -333,60 +341,60 @@ class FloatingPointDifference */ class FloatingPointTolerance { - public: - /*! \brief - * Creates a tolerance with the specified values. - * - * \param[in] singleAbsoluteTolerance - * Allowed absolute difference in a single-precision number. - * \param[in] doubleAbsoluteTolerance - * Allowed absolute difference in a double-precision number. - * \param[in] singleRelativeTolerance - * Allowed relative difference in a single-precision number. - * \param[in] doubleRelativeTolerance - * Allowed relative difference in a double-precision number. - * \param[in] singleUlpTolerance - * Allowed ULP difference in a single-precision number. - * \param[in] doubleUlpTolerance - * Allowed ULP difference in a double-precision number. - * \param[in] bSignMustMatch - * Whether sign mismatch fails the comparison. - */ - FloatingPointTolerance(float singleAbsoluteTolerance, - double doubleAbsoluteTolerance, - float singleRelativeTolerance, - double doubleRelativeTolerance, - uint64_t singleUlpTolerance, - uint64_t doubleUlpTolerance, - bool bSignMustMatch) - : singleAbsoluteTolerance_(singleAbsoluteTolerance), - doubleAbsoluteTolerance_(doubleAbsoluteTolerance), - singleRelativeTolerance_(singleRelativeTolerance), - doubleRelativeTolerance_(doubleRelativeTolerance), - singleUlpTolerance_(singleUlpTolerance), - doubleUlpTolerance_(doubleUlpTolerance), - bSignMustMatch_(bSignMustMatch) - { - } - - /*! \brief - * Checks whether a difference is within the specified tolerance. - * - * NaNs are always treated outside the tolerance. - */ - bool isWithin(const FloatingPointDifference &difference) const; - - //! Formats the tolerance as a string for assertion failure messages. - std::string toString(const FloatingPointDifference &difference) const; - - private: - float singleAbsoluteTolerance_; - double doubleAbsoluteTolerance_; - float singleRelativeTolerance_; - double doubleRelativeTolerance_; - uint64_t singleUlpTolerance_; - uint64_t doubleUlpTolerance_; - bool bSignMustMatch_; +public: + /*! \brief + * Creates a tolerance with the specified values. + * + * \param[in] singleAbsoluteTolerance + * Allowed absolute difference in a single-precision number. + * \param[in] doubleAbsoluteTolerance + * Allowed absolute difference in a double-precision number. + * \param[in] singleRelativeTolerance + * Allowed relative difference in a single-precision number. + * \param[in] doubleRelativeTolerance + * Allowed relative difference in a double-precision number. + * \param[in] singleUlpTolerance + * Allowed ULP difference in a single-precision number. + * \param[in] doubleUlpTolerance + * Allowed ULP difference in a double-precision number. + * \param[in] bSignMustMatch + * Whether sign mismatch fails the comparison. + */ + FloatingPointTolerance(float singleAbsoluteTolerance, + double doubleAbsoluteTolerance, + float singleRelativeTolerance, + double doubleRelativeTolerance, + uint64_t singleUlpTolerance, + uint64_t doubleUlpTolerance, + bool bSignMustMatch) : + singleAbsoluteTolerance_(singleAbsoluteTolerance), + doubleAbsoluteTolerance_(doubleAbsoluteTolerance), + singleRelativeTolerance_(singleRelativeTolerance), + doubleRelativeTolerance_(doubleRelativeTolerance), + singleUlpTolerance_(singleUlpTolerance), + doubleUlpTolerance_(doubleUlpTolerance), + bSignMustMatch_(bSignMustMatch) + { + } + + /*! \brief + * Checks whether a difference is within the specified tolerance. + * + * NaNs are always treated outside the tolerance. + */ + bool isWithin(const FloatingPointDifference& difference) const; + + //! Formats the tolerance as a string for assertion failure messages. + std::string toString(const FloatingPointDifference& difference) const; + +private: + float singleAbsoluteTolerance_; + double doubleAbsoluteTolerance_; + float singleRelativeTolerance_; + double doubleRelativeTolerance_; + uint64_t singleUlpTolerance_; + uint64_t doubleUlpTolerance_; + bool bSignMustMatch_; }; /*! \brief @@ -397,8 +405,7 @@ class FloatingPointTolerance * * \related FloatingPointTolerance */ -static inline FloatingPointTolerance -ulpTolerance(uint64_t ulpDiff) +static inline FloatingPointTolerance ulpTolerance(uint64_t ulpDiff) { return FloatingPointTolerance(0.0, 0.0, 0.0, 0.0, ulpDiff, ulpDiff, false); } @@ -420,8 +427,7 @@ ulpTolerance(uint64_t ulpDiff) * * \related FloatingPointTolerance */ -FloatingPointTolerance - relativeToleranceAsFloatingPoint(double magnitude, double tolerance); +FloatingPointTolerance relativeToleranceAsFloatingPoint(double magnitude, double tolerance); /*! \brief * Creates a tolerance that allows a precision-dependent difference in two @@ -444,10 +450,9 @@ FloatingPointTolerance * * \related FloatingPointTolerance */ -FloatingPointTolerance - relativeToleranceAsPrecisionDependentFloatingPoint(double magnitude, - float singleTolerance, - double doubleTolerance); +FloatingPointTolerance relativeToleranceAsPrecisionDependentFloatingPoint(double magnitude, + float singleTolerance, + double doubleTolerance); /*! \brief * Creates a tolerance that allows a precision-dependent relative difference in @@ -467,14 +472,12 @@ FloatingPointTolerance * * \related FloatingPointTolerance */ -static inline FloatingPointTolerance -relativeToleranceAsPrecisionDependentUlp(double magnitude, - uint64_t singleUlpDiff, - uint64_t doubleUlpDiff) +static inline FloatingPointTolerance relativeToleranceAsPrecisionDependentUlp(double magnitude, + uint64_t singleUlpDiff, + uint64_t doubleUlpDiff) { - return FloatingPointTolerance(float(magnitude)*singleUlpDiff*GMX_FLOAT_EPS, - magnitude*doubleUlpDiff*GMX_DOUBLE_EPS, - 0.0, 0.0, + return FloatingPointTolerance(float(magnitude) * singleUlpDiff * GMX_FLOAT_EPS, + magnitude * doubleUlpDiff * GMX_DOUBLE_EPS, 0.0, 0.0, singleUlpDiff, doubleUlpDiff, false); } @@ -483,11 +486,9 @@ relativeToleranceAsPrecisionDependentUlp(double magnitude, * * \related FloatingPointTolerance */ -static inline FloatingPointTolerance -absoluteTolerance(double tolerance) +static inline FloatingPointTolerance absoluteTolerance(double tolerance) { - return FloatingPointTolerance(float(tolerance), tolerance, 0.0, 0.0, - UINT64_MAX, UINT64_MAX, false); + return FloatingPointTolerance(float(tolerance), tolerance, 0.0, 0.0, UINT64_MAX, UINT64_MAX, false); } /*! \brief @@ -506,8 +507,7 @@ absoluteTolerance(double tolerance) * * \related FloatingPointTolerance */ -static inline FloatingPointTolerance -relativeToleranceAsUlp(double magnitude, uint64_t ulpDiff) +static inline FloatingPointTolerance relativeToleranceAsUlp(double magnitude, uint64_t ulpDiff) { return relativeToleranceAsPrecisionDependentUlp(magnitude, ulpDiff, ulpDiff); } @@ -516,7 +516,7 @@ namespace detail { //! Default tolerance in ULPs for two floating-point values to compare equal. constexpr uint64_t g_defaultUlpTolerance = 4; -} +} // namespace detail /*! \brief * Returns the default tolerance for comparing `real` numbers. @@ -540,9 +540,9 @@ static inline FloatingPointTolerance defaultRealTolerance() */ static inline FloatingPointTolerance defaultFloatTolerance() { - return relativeToleranceAsPrecisionDependentUlp - (1.0, detail::g_defaultUlpTolerance, - static_cast(detail::g_defaultUlpTolerance * (GMX_FLOAT_EPS / GMX_DOUBLE_EPS))); + return relativeToleranceAsPrecisionDependentUlp( + 1.0, detail::g_defaultUlpTolerance, + static_cast(detail::g_defaultUlpTolerance * (GMX_FLOAT_EPS / GMX_DOUBLE_EPS))); } /*! \name Assertions for floating-point comparison @@ -561,24 +561,25 @@ static inline FloatingPointTolerance defaultFloatTolerance() /*! \internal \brief * Assertion predicate formatter for comparing two floating-point values. */ -template -static inline ::testing::AssertionResult assertEqualWithinTolerance( - const char *expr1, const char *expr2, const char * /*exprTolerance*/, - FloatType value1, FloatType value2, - const FloatingPointTolerance &tolerance) +template +static inline ::testing::AssertionResult assertEqualWithinTolerance(const char* expr1, + const char* expr2, + const char* /*exprTolerance*/, + FloatType value1, + FloatType value2, + const FloatingPointTolerance& tolerance) { FloatingPointDifference diff(value1, value2); if (tolerance.isWithin(diff)) { return ::testing::AssertionSuccess(); } - return ::testing::AssertionFailure() - << " Value of: " << expr2 << std::endl - << " Actual: " << value2 << std::endl - << " Expected: " << expr1 << std::endl - << " Which is: " << value1 << std::endl - << "Difference: " << diff.toString() << std::endl - << " Tolerance: " << tolerance.toString(diff); + return ::testing::AssertionFailure() << " Value of: " << expr2 << std::endl + << " Actual: " << value2 << std::endl + << " Expected: " << expr1 << std::endl + << " Which is: " << value1 << std::endl + << "Difference: " << diff.toString() << std::endl + << " Tolerance: " << tolerance.toString(diff); } //! \endcond @@ -588,16 +589,14 @@ static inline ::testing::AssertionResult assertEqualWithinTolerance( * \hideinitializer */ #define EXPECT_FLOAT_EQ_TOL(value1, value2, tolerance) \ - EXPECT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, \ - value1, value2, tolerance) + EXPECT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, value1, value2, tolerance) /*! \brief * Asserts that two double-precision values are within the given tolerance. * * \hideinitializer */ #define EXPECT_DOUBLE_EQ_TOL(value1, value2, tolerance) \ - EXPECT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, \ - value1, value2, tolerance) + EXPECT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, value1, value2, tolerance) /*! \def EXPECT_REAL_EQ_TOL * \brief * Asserts that two `real` values are within the given tolerance. @@ -610,16 +609,14 @@ static inline ::testing::AssertionResult assertEqualWithinTolerance( * \hideinitializer */ #define ASSERT_FLOAT_EQ_TOL(value1, value2, tolerance) \ - ASSERT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, \ - value1, value2, tolerance) + ASSERT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, value1, value2, tolerance) /*! \brief * Asserts that two double-precision values are within the given tolerance. * * \hideinitializer */ #define ASSERT_DOUBLE_EQ_TOL(value1, value2, tolerance) \ - ASSERT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, \ - value1, value2, tolerance) + ASSERT_PRED_FORMAT3(::gmx::test::assertEqualWithinTolerance, value1, value2, tolerance) /*! \def ASSERT_REAL_EQ_TOL * \brief * Asserts that two `real` values are within the given tolerance. @@ -628,29 +625,31 @@ static inline ::testing::AssertionResult assertEqualWithinTolerance( */ #if GMX_DOUBLE -#define EXPECT_REAL_EQ_TOL(value1, value2, tolerance) \ - EXPECT_DOUBLE_EQ_TOL(value1, value2, tolerance) -#define ASSERT_REAL_EQ_TOL(value1, value2, tolerance) \ - ASSERT_DOUBLE_EQ_TOL(value1, value2, tolerance) +# define EXPECT_REAL_EQ_TOL(value1, value2, tolerance) \ + EXPECT_DOUBLE_EQ_TOL(value1, value2, tolerance) +# define ASSERT_REAL_EQ_TOL(value1, value2, tolerance) \ + ASSERT_DOUBLE_EQ_TOL(value1, value2, tolerance) #else -#define EXPECT_REAL_EQ_TOL(value1, value2, tolerance) \ - EXPECT_FLOAT_EQ_TOL(value1, value2, tolerance) -#define ASSERT_REAL_EQ_TOL(value1, value2, tolerance) \ - ASSERT_FLOAT_EQ_TOL(value1, value2, tolerance) +# define EXPECT_REAL_EQ_TOL(value1, value2, tolerance) \ + EXPECT_FLOAT_EQ_TOL(value1, value2, tolerance) +# define ASSERT_REAL_EQ_TOL(value1, value2, tolerance) \ + ASSERT_FLOAT_EQ_TOL(value1, value2, tolerance) #endif //! EXPECT_REAL_EQ_TOL with default tolerance -#define EXPECT_REAL_EQ(value1, value2) EXPECT_REAL_EQ_TOL(value1, value2, ::gmx::test::defaultRealTolerance()) +#define EXPECT_REAL_EQ(value1, value2) \ + EXPECT_REAL_EQ_TOL(value1, value2, ::gmx::test::defaultRealTolerance()) //! ASSERT_REAL_EQ_TOL with default tolerance -#define ASSERT_REAL_EQ(value1, value2) ASSERT_REAL_EQ_TOL(value1, value2, ::gmx::test::defaultRealTolerance()) +#define ASSERT_REAL_EQ(value1, value2) \ + ASSERT_REAL_EQ_TOL(value1, value2, ::gmx::test::defaultRealTolerance()) //! \} //! \cond internal /*! \internal \brief * Helper method for `(EXPECT|ASSERT)_PLAIN`. */ -static inline ::testing::AssertionResult -plainAssertHelper(const char * /*expr*/, const ::testing::AssertionResult &expr) +static inline ::testing::AssertionResult plainAssertHelper(const char* /*expr*/, + const ::testing::AssertionResult& expr) { return expr; } diff --git a/src/testutils/testexceptions.h b/src/testutils/testexceptions.h index fdd595cc3d..edbdd6b6fa 100644 --- a/src/testutils/testexceptions.h +++ b/src/testutils/testexceptions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2011,2012,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2011,2012,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,25 +62,23 @@ namespace test */ class TestException : public GromacsException { - public: - /*! \brief - * Creates a test exception object with the provided detailed reason. - * - * \param[in] reason Detailed reason for the exception. - */ - explicit TestException(const std::string &reason) - : GromacsException(reason) {} - /*! \brief - * Creates a test exception based on another GromacsException object. - * - * \param[in] base Exception to wrap. - * - * \see GMX_THROW_WRAPPER_TESTEXCEPTION - */ - explicit TestException(const GromacsException &base) - : GromacsException(base) {} +public: + /*! \brief + * Creates a test exception object with the provided detailed reason. + * + * \param[in] reason Detailed reason for the exception. + */ + explicit TestException(const std::string& reason) : GromacsException(reason) {} + /*! \brief + * Creates a test exception based on another GromacsException object. + * + * \param[in] base Exception to wrap. + * + * \see GMX_THROW_WRAPPER_TESTEXCEPTION + */ + explicit TestException(const GromacsException& base) : GromacsException(base) {} - int errorCode() const override { return -1; } + int errorCode() const override { return -1; } }; /*! \brief @@ -109,8 +107,7 @@ class TestException : public GromacsException } * \endcode */ -#define GMX_THROW_WRAPPER_TESTEXCEPTION(e) \ - throw ::gmx::test::TestException(e) +#define GMX_THROW_WRAPPER_TESTEXCEPTION(e) throw ::gmx::test::TestException(e) } // namespace test } // namespace gmx diff --git a/src/testutils/testfilemanager.cpp b/src/testutils/testfilemanager.cpp index 522312b1cd..b59434dd6d 100644 --- a/src/testutils/testfilemanager.cpp +++ b/src/testutils/testfilemanager.cpp @@ -74,49 +74,48 @@ namespace test */ class TestFileManager::Impl { - public: - //! Global test input data path set with setDataInputDirectory(). - static std::string s_inputDirectory; - - //! Global path to simulation input database set with setTestSimulationDataBaseDirectory(). - static std::string s_simulationDatabaseDirectory; - - //! Global temporary output directory for tests, set with setGlobalOutputTempDirectory(). - static const char *s_globalOutputTempDirectory; - - //! Container type for names of temporary files. - typedef std::set FileNameList; - - /*! \brief Constructor - * - * \param path Value for the outputTempDirectory, typically - * set by default from s_globalOutputTempDirectory */ - explicit Impl(const char *path) - : outputTempDirectory_(path) - { - GMX_RELEASE_ASSERT(Directory::exists(outputTempDirectory_), - "Directory for tests' temporary files does not exist"); - } - - /*! \brief - * Try to remove all temporary files. - * - * Does not throw; errors (e.g., missing files) are silently ignored. - */ - void removeFiles(); - - //! List of unique paths returned by getTemporaryFilePath(). - FileNameList files_; - - /*! \brief Temporary output directory local to the current - * test, set by a test with setOutputTempDirectory() if the - * global default is inappropriate. */ - std::string outputTempDirectory_; +public: + //! Global test input data path set with setDataInputDirectory(). + static std::string s_inputDirectory; + + //! Global path to simulation input database set with setTestSimulationDataBaseDirectory(). + static std::string s_simulationDatabaseDirectory; + + //! Global temporary output directory for tests, set with setGlobalOutputTempDirectory(). + static const char* s_globalOutputTempDirectory; + + //! Container type for names of temporary files. + typedef std::set FileNameList; + + /*! \brief Constructor + * + * \param path Value for the outputTempDirectory, typically + * set by default from s_globalOutputTempDirectory */ + explicit Impl(const char* path) : outputTempDirectory_(path) + { + GMX_RELEASE_ASSERT(Directory::exists(outputTempDirectory_), + "Directory for tests' temporary files does not exist"); + } + + /*! \brief + * Try to remove all temporary files. + * + * Does not throw; errors (e.g., missing files) are silently ignored. + */ + void removeFiles(); + + //! List of unique paths returned by getTemporaryFilePath(). + FileNameList files_; + + /*! \brief Temporary output directory local to the current + * test, set by a test with setOutputTempDirectory() if the + * global default is inappropriate. */ + std::string outputTempDirectory_; }; std::string TestFileManager::Impl::s_inputDirectory; std::string TestFileManager::Impl::s_simulationDatabaseDirectory; -const char *TestFileManager::Impl::s_globalOutputTempDirectory = nullptr; +const char* TestFileManager::Impl::s_globalOutputTempDirectory = nullptr; /** Controls whether TestFileManager should delete temporary files after the test finishes. */ static bool g_bDeleteFilesAfterTest = true; @@ -124,9 +123,11 @@ static bool g_bDeleteFilesAfterTest = true; //! \cond GMX_TEST_OPTIONS(TestFileManagerOptions, options) { - options->addOption(BooleanOption("delete-temporary-files") - .store(&g_bDeleteFilesAfterTest) - .description("At the end of each test case, delete temporary and output files")); + options->addOption( + BooleanOption("delete-temporary-files") + .store(&g_bDeleteFilesAfterTest) + .description( + "At the end of each test case, delete temporary and output files")); } //! \endcond @@ -144,10 +145,7 @@ void TestFileManager::Impl::removeFiles() * TestFileManager */ -TestFileManager::TestFileManager() - : impl_(new Impl(Impl::s_globalOutputTempDirectory)) -{ -} +TestFileManager::TestFileManager() : impl_(new Impl(Impl::s_globalOutputTempDirectory)) {} TestFileManager::~TestFileManager() { @@ -157,45 +155,42 @@ TestFileManager::~TestFileManager() } } -std::string TestFileManager::getTemporaryFilePath(const char *suffix) +std::string TestFileManager::getTemporaryFilePath(const char* suffix) { /* Configure a temporary directory from CMake, so that temporary * output from a test goes to a location relevant to that * test. Currently, files whose names are returned by this method * get cleaned up (by default) at the end of all tests. */ - std::string filename = - Path::join(getOutputTempDirectory(), - getTestSpecificFileName(suffix)); + std::string filename = Path::join(getOutputTempDirectory(), getTestSpecificFileName(suffix)); impl_->files_.insert(filename); return filename; } -std::string TestFileManager::getTemporaryFilePath(const std::string &suffix) +std::string TestFileManager::getTemporaryFilePath(const std::string& suffix) { return getTemporaryFilePath(suffix.c_str()); } std::string TestFileManager::getTestSpecificFileNameRoot() { - const ::testing::TestInfo *test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); + const ::testing::TestInfo* test_info = ::testing::UnitTest::GetInstance()->current_test_info(); std::string filenameRoot; if (test_info) { - filenameRoot = std::string(test_info->test_case_name()) - + "_" + test_info->name(); + filenameRoot = std::string(test_info->test_case_name()) + "_" + test_info->name(); } else { - const ::testing::TestCase *test_case_info = ::testing::UnitTest::GetInstance()->current_test_case(); + const ::testing::TestCase* test_case_info = + ::testing::UnitTest::GetInstance()->current_test_case(); filenameRoot = std::string(test_case_info->name()); } std::replace(filenameRoot.begin(), filenameRoot.end(), '/', '_'); return filenameRoot; } -std::string TestFileManager::getTestSpecificFileName(const char *suffix) +std::string TestFileManager::getTestSpecificFileName(const char* suffix) { std::string filename = getTestSpecificFileNameRoot(); if (suffix[0] != '.') @@ -206,7 +201,7 @@ std::string TestFileManager::getTestSpecificFileName(const char *suffix) return filename; } -std::string TestFileManager::getInputFilePath(const char *filename) +std::string TestFileManager::getInputFilePath(const char* filename) { // Check if file is present in local directory. if (File::exists(Path::join(getInputDataDirectory(), filename), File::returnFalseOnError)) @@ -225,53 +220,53 @@ std::string TestFileManager::getInputFilePath(const char *filename) } } -std::string TestFileManager::getInputFilePath(const std::string &filename) +std::string TestFileManager::getInputFilePath(const std::string& filename) { return getInputFilePath(filename.c_str()); } -const char *TestFileManager::getInputDataDirectory() +const char* TestFileManager::getInputDataDirectory() { GMX_RELEASE_ASSERT(!Impl::s_inputDirectory.empty(), "Path for test input files is not set"); return Impl::s_inputDirectory.c_str(); } -const char *TestFileManager::getGlobalOutputTempDirectory() +const char* TestFileManager::getGlobalOutputTempDirectory() { - GMX_RELEASE_ASSERT(Impl::s_globalOutputTempDirectory != nullptr, "Global path for temporary output files from tests is not set"); + GMX_RELEASE_ASSERT(Impl::s_globalOutputTempDirectory != nullptr, + "Global path for temporary output files from tests is not set"); return Impl::s_globalOutputTempDirectory; } -const char *TestFileManager::getOutputTempDirectory() const +const char* TestFileManager::getOutputTempDirectory() const { return impl_->outputTempDirectory_.c_str(); } -const char *TestFileManager::getTestSimulationDatabaseDirectory() +const char* TestFileManager::getTestSimulationDatabaseDirectory() { - GMX_RELEASE_ASSERT(!Impl::s_simulationDatabaseDirectory.empty(), "Path for simulation input database directory is not set"); + GMX_RELEASE_ASSERT(!Impl::s_simulationDatabaseDirectory.empty(), + "Path for simulation input database directory is not set"); return Impl::s_simulationDatabaseDirectory.c_str(); } -void TestFileManager::setInputDataDirectory(const std::string &path) +void TestFileManager::setInputDataDirectory(const std::string& path) { // There is no need to protect this by a mutex, as this is called in early // initialization of the tests. - GMX_RELEASE_ASSERT(Directory::exists(path), - "Test data directory does not exist"); + GMX_RELEASE_ASSERT(Directory::exists(path), "Test data directory does not exist"); Impl::s_inputDirectory = path; } -void TestFileManager::setTestSimulationDatabaseDirectory(const std::string &path) +void TestFileManager::setTestSimulationDatabaseDirectory(const std::string& path) { // There is no need to protect this by a mutex, as this is called in early // initialization of the tests. - GMX_RELEASE_ASSERT(Directory::exists(path), - "Simulation database directory does not exist"); + GMX_RELEASE_ASSERT(Directory::exists(path), "Simulation database directory does not exist"); Impl::s_simulationDatabaseDirectory = path; } -void TestFileManager::setGlobalOutputTempDirectory(const char *path) +void TestFileManager::setGlobalOutputTempDirectory(const char* path) { // There is no need to protect this by a mutex, as this is called in early // initialization of the tests. @@ -280,7 +275,7 @@ void TestFileManager::setGlobalOutputTempDirectory(const char *path) Impl::s_globalOutputTempDirectory = path; } -void TestFileManager::setOutputTempDirectory(const std::string &path) +void TestFileManager::setOutputTempDirectory(const std::string& path) { // There could be a need to protect this with a mutex, since it is // intended to be used in test fixtures, not just during setup. diff --git a/src/testutils/testfilemanager.h b/src/testutils/testfilemanager.h index 07e8cea987..d415c28e5d 100644 --- a/src/testutils/testfilemanager.h +++ b/src/testutils/testfilemanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -87,154 +87,154 @@ namespace test */ class TestFileManager { - public: - /*! \brief Constructor */ - TestFileManager(); - /*! \brief Frees internal storage and deletes any accessed - * file paths - * - * Any errors (e.g., missing files) encountered while deleting the - * files are ignored. - */ - ~TestFileManager(); - - /*! \brief - * Creates a name for a temporary file within a single unit test. - * - * \param[in] suffix Suffix to add to the file name (should contain an - * extension if one is desired). - * \returns Temporary file name that includes the test name and - * \p suffix. - * - * This method should only be called from within a Google Test test. - * Two calls with the same \p suffix return the same string within the - * same test. - */ - std::string getTemporaryFilePath(const char *suffix); - //! \copydoc TestFileManager::getTemporaryFilePath(const char *) - std::string getTemporaryFilePath(const std::string &suffix); - - /*! \brief Returns the path to the output temporary directory - * for tests which use this TestFileManager object. - * - * \returns Path to output temporary directory - */ - const char *getOutputTempDirectory() const; - - /*! \brief Sets the output temporary directory for tests which - * use this TestFileManager object. - * - * \param[in] path Path at which test should write temporary files - * - * \p path must name an existing directory. An internal copy - * of path is made. The caller is responsible for holding a - * valid mutex on the object before calling this member - * function. - */ - void setOutputTempDirectory(const std::string &path); - - // static functions follow - - /*! \brief - * Creates a file name root for use within a single unit test. - * - * This method should only be called from within a Google Test - * test. Uses the Google Test test fixture and test case name - * to construct a string that is unique over all - * tests. Intended to produce distinct names for files that - * may be stored in the same directory for multiple tests. - */ - static std::string getTestSpecificFileNameRoot(); - - /*! \brief - * Creates a file name for use within a single unit test. - * - * \param[in] suffix Suffix to add to the file name (should contain an - * extension if one is desired). - * \returns File name that includes the test name and - * \p suffix. - * - * This method should only be called from within a Google Test test. - * Two calls with the same \p suffix return the same string within the - * same test. - * Intended to produce distinct names for files that may be stored in - * the same directory for multiple tests. - */ - static std::string getTestSpecificFileName(const char *suffix); - - /*! \brief - * Returns the path to a test input file. - * - * \param[in] filename Relative path/filename to a test input file. - * \returns Path to \p filename under the test input data directory. - */ - static std::string getInputFilePath(const char *filename); - //! \copydoc TestFileManager::getInputFilePath(const char *) - static std::string getInputFilePath(const std::string &filename); - - /*! \brief - * Returns the path to the simulation input database directory. - * - * \returns Path to simulation input database directory. - */ - static const char *getTestSimulationDatabaseDirectory(); - - /*! \brief - * Returns the path to the test input directory. - * - * \returns Path to input data directory for the test executable. - */ - static const char *getInputDataDirectory(); - - /*! \brief - * Sets the test input directory. - * - * \param[in] path Path from which test input data is looked up from. - * - * \p path must name an existing directory. - * - * This function is automatically called by unittest_main.cpp through - * initTestUtils(). - */ - static void setInputDataDirectory(const std::string &path); - - /*! \brief - * Sets the input directory for simulation input files. - * - * \param[in] path Path to look up the directory for simulation input files. - * - * \p path must name an exisitng directory. - * - * This function is automatically called by unittest_main.cpp through - * initTestUtils(). - */ - static void setTestSimulationDatabaseDirectory(const std::string &path); - - /*! \brief Returns the path to the global test output - * temporary directory for future TestFileManager objects. - * - * \returns Path to default output temporary directory for the test executable. - */ - static const char *getGlobalOutputTempDirectory(); - - /*! \brief Sets the default global test output temporary - * directory for future TestFileManager objects. - * - * \param[in] path Path at which tests should write temporary files - * - * \p path must name an existing directory. - * - * This function is automatically called by unittest_main.cpp - * through initTestUtils(). Test fixtures should call - * setOutputTempDirectory(), rather than change the global - * state. - */ - static void setGlobalOutputTempDirectory(const char *path); - - private: - class Impl; - - PrivateImplPointer impl_; +public: + /*! \brief Constructor */ + TestFileManager(); + /*! \brief Frees internal storage and deletes any accessed + * file paths + * + * Any errors (e.g., missing files) encountered while deleting the + * files are ignored. + */ + ~TestFileManager(); + + /*! \brief + * Creates a name for a temporary file within a single unit test. + * + * \param[in] suffix Suffix to add to the file name (should contain an + * extension if one is desired). + * \returns Temporary file name that includes the test name and + * \p suffix. + * + * This method should only be called from within a Google Test test. + * Two calls with the same \p suffix return the same string within the + * same test. + */ + std::string getTemporaryFilePath(const char* suffix); + //! \copydoc TestFileManager::getTemporaryFilePath(const char *) + std::string getTemporaryFilePath(const std::string& suffix); + + /*! \brief Returns the path to the output temporary directory + * for tests which use this TestFileManager object. + * + * \returns Path to output temporary directory + */ + const char* getOutputTempDirectory() const; + + /*! \brief Sets the output temporary directory for tests which + * use this TestFileManager object. + * + * \param[in] path Path at which test should write temporary files + * + * \p path must name an existing directory. An internal copy + * of path is made. The caller is responsible for holding a + * valid mutex on the object before calling this member + * function. + */ + void setOutputTempDirectory(const std::string& path); + + // static functions follow + + /*! \brief + * Creates a file name root for use within a single unit test. + * + * This method should only be called from within a Google Test + * test. Uses the Google Test test fixture and test case name + * to construct a string that is unique over all + * tests. Intended to produce distinct names for files that + * may be stored in the same directory for multiple tests. + */ + static std::string getTestSpecificFileNameRoot(); + + /*! \brief + * Creates a file name for use within a single unit test. + * + * \param[in] suffix Suffix to add to the file name (should contain an + * extension if one is desired). + * \returns File name that includes the test name and + * \p suffix. + * + * This method should only be called from within a Google Test test. + * Two calls with the same \p suffix return the same string within the + * same test. + * Intended to produce distinct names for files that may be stored in + * the same directory for multiple tests. + */ + static std::string getTestSpecificFileName(const char* suffix); + + /*! \brief + * Returns the path to a test input file. + * + * \param[in] filename Relative path/filename to a test input file. + * \returns Path to \p filename under the test input data directory. + */ + static std::string getInputFilePath(const char* filename); + //! \copydoc TestFileManager::getInputFilePath(const char *) + static std::string getInputFilePath(const std::string& filename); + + /*! \brief + * Returns the path to the simulation input database directory. + * + * \returns Path to simulation input database directory. + */ + static const char* getTestSimulationDatabaseDirectory(); + + /*! \brief + * Returns the path to the test input directory. + * + * \returns Path to input data directory for the test executable. + */ + static const char* getInputDataDirectory(); + + /*! \brief + * Sets the test input directory. + * + * \param[in] path Path from which test input data is looked up from. + * + * \p path must name an existing directory. + * + * This function is automatically called by unittest_main.cpp through + * initTestUtils(). + */ + static void setInputDataDirectory(const std::string& path); + + /*! \brief + * Sets the input directory for simulation input files. + * + * \param[in] path Path to look up the directory for simulation input files. + * + * \p path must name an exisitng directory. + * + * This function is automatically called by unittest_main.cpp through + * initTestUtils(). + */ + static void setTestSimulationDatabaseDirectory(const std::string& path); + + /*! \brief Returns the path to the global test output + * temporary directory for future TestFileManager objects. + * + * \returns Path to default output temporary directory for the test executable. + */ + static const char* getGlobalOutputTempDirectory(); + + /*! \brief Sets the default global test output temporary + * directory for future TestFileManager objects. + * + * \param[in] path Path at which tests should write temporary files + * + * \p path must name an existing directory. + * + * This function is automatically called by unittest_main.cpp + * through initTestUtils(). Test fixtures should call + * setOutputTempDirectory(), rather than change the global + * state. + */ + static void setGlobalOutputTempDirectory(const char* path); + +private: + class Impl; + + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/testutils/testfileredirector.cpp b/src/testutils/testfileredirector.cpp index 993b4070e7..da0e74ae21 100644 --- a/src/testutils/testfileredirector.cpp +++ b/src/testutils/testfileredirector.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,21 +62,16 @@ namespace test * TestFileInputRedirector */ -TestFileInputRedirector::TestFileInputRedirector() -{ -} +TestFileInputRedirector::TestFileInputRedirector() {} -TestFileInputRedirector::~TestFileInputRedirector() -{ -} +TestFileInputRedirector::~TestFileInputRedirector() {} -void TestFileInputRedirector::addExistingFile(const char *filename) +void TestFileInputRedirector::addExistingFile(const char* filename) { existingFiles_.insert(filename); } -bool TestFileInputRedirector::fileExists(const char *filename, - File::NotFoundHandler onNotFound) const +bool TestFileInputRedirector::fileExists(const char* filename, File::NotFoundHandler onNotFound) const { if (existingFiles_.count(filename) == 0) { @@ -93,28 +88,23 @@ bool TestFileInputRedirector::fileExists(const char *filename, class TestFileOutputRedirector::Impl { - public: - typedef std::shared_ptr StringStreamPointer; - typedef std::pair FileListEntry; +public: + typedef std::shared_ptr StringStreamPointer; + typedef std::pair FileListEntry; - StringStreamPointer stdoutStream_; - std::vector fileList_; + StringStreamPointer stdoutStream_; + std::vector fileList_; }; /******************************************************************** * TestFileOutputRedirector */ -TestFileOutputRedirector::TestFileOutputRedirector() - : impl_(new Impl) -{ -} +TestFileOutputRedirector::TestFileOutputRedirector() : impl_(new Impl) {} -TestFileOutputRedirector::~TestFileOutputRedirector() -{ -} +TestFileOutputRedirector::~TestFileOutputRedirector() {} -TextOutputStream &TestFileOutputRedirector::standardOutput() +TextOutputStream& TestFileOutputRedirector::standardOutput() { if (!impl_->stdoutStream_) { @@ -124,15 +114,14 @@ TextOutputStream &TestFileOutputRedirector::standardOutput() return *impl_->stdoutStream_; } -TextOutputStreamPointer -TestFileOutputRedirector::openTextOutputFile(const char *filename) +TextOutputStreamPointer TestFileOutputRedirector::openTextOutputFile(const char* filename) { Impl::StringStreamPointer stream(new StringOutputStream); impl_->fileList_.emplace_back(filename, stream); return stream; } -void TestFileOutputRedirector::checkRedirectedFiles(TestReferenceChecker *checker) +void TestFileOutputRedirector::checkRedirectedFiles(TestReferenceChecker* checker) { std::vector::const_iterator i; for (i = impl_->fileList_.begin(); i != impl_->fileList_.end(); ++i) diff --git a/src/testutils/testfileredirector.h b/src/testutils/testfileredirector.h index e68717db7a..5e34af133b 100644 --- a/src/testutils/testfileredirector.h +++ b/src/testutils/testfileredirector.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,27 +67,26 @@ class TestReferenceChecker; */ class TestFileInputRedirector : public IFileInputRedirector { - public: - TestFileInputRedirector(); - ~TestFileInputRedirector() override; - - /*! \brief - * Marks the provided path as an existing file. - * - * \throws std::bad_alloc if out of memory. - * - * Further checks for existence of the given path will return `true`. - */ - void addExistingFile(const char *filename); - - // From IFileInputRedirector - bool fileExists(const char *filename, - File::NotFoundHandler onNotFound) const override; - - private: - std::set existingFiles_; - - GMX_DISALLOW_COPY_AND_ASSIGN(TestFileInputRedirector); +public: + TestFileInputRedirector(); + ~TestFileInputRedirector() override; + + /*! \brief + * Marks the provided path as an existing file. + * + * \throws std::bad_alloc if out of memory. + * + * Further checks for existence of the given path will return `true`. + */ + void addExistingFile(const char* filename); + + // From IFileInputRedirector + bool fileExists(const char* filename, File::NotFoundHandler onNotFound) const override; + +private: + std::set existingFiles_; + + GMX_DISALLOW_COPY_AND_ASSIGN(TestFileInputRedirector); }; /*! \libinternal \brief @@ -100,28 +99,28 @@ class TestFileInputRedirector : public IFileInputRedirector */ class TestFileOutputRedirector : public IFileOutputRedirector { - public: - TestFileOutputRedirector(); - ~TestFileOutputRedirector() override; - - /*! \brief - * Checks contents of all redirected files (including stdout). - * - * This method should not be called if the redirector will still be - * used for further output in the test. Behavior is not designed for - * checking in the middle of the test, although that could potentially - * be changed if necessary. - */ - void checkRedirectedFiles(TestReferenceChecker *checker); - - // From IFileOutputRedirector - TextOutputStream &standardOutput() override; - TextOutputStreamPointer openTextOutputFile(const char *filename) override; - - private: - class Impl; - - PrivateImplPointer impl_; +public: + TestFileOutputRedirector(); + ~TestFileOutputRedirector() override; + + /*! \brief + * Checks contents of all redirected files (including stdout). + * + * This method should not be called if the redirector will still be + * used for further output in the test. Behavior is not designed for + * checking in the middle of the test, although that could potentially + * be changed if necessary. + */ + void checkRedirectedFiles(TestReferenceChecker* checker); + + // From IFileOutputRedirector + TextOutputStream& standardOutput() override; + TextOutputStreamPointer openTextOutputFile(const char* filename) override; + +private: + class Impl; + + PrivateImplPointer impl_; }; } // namespace test diff --git a/src/testutils/testinit.cpp b/src/testutils/testinit.cpp index 5acb455869..63b37f9118 100644 --- a/src/testutils/testinit.cpp +++ b/src/testutils/testinit.cpp @@ -92,55 +92,41 @@ namespace */ class TestProgramContext : public IProgramContext { - public: - /*! \brief - * Initializes a test program context. - * - * \param[in] context Current \Gromacs program context. - */ - explicit TestProgramContext(const IProgramContext &context) - : context_(context), dataPath_(CMAKE_SOURCE_DIR) - { - } +public: + /*! \brief + * Initializes a test program context. + * + * \param[in] context Current \Gromacs program context. + */ + explicit TestProgramContext(const IProgramContext& context) : + context_(context), + dataPath_(CMAKE_SOURCE_DIR) + { + } - /*! \brief - * Sets the source directory root from which to look for data files. - */ - void overrideSourceRoot(const std::string &sourceRoot) - { - dataPath_ = sourceRoot; - } + /*! \brief + * Sets the source directory root from which to look for data files. + */ + void overrideSourceRoot(const std::string& sourceRoot) { dataPath_ = sourceRoot; } - const char *programName() const override - { - return context_.programName(); - } - const char *displayName() const override - { - return context_.displayName(); - } - const char *fullBinaryPath() const override - { - return context_.fullBinaryPath(); - } - InstallationPrefixInfo installationPrefix() const override - { - return InstallationPrefixInfo(dataPath_.c_str(), true); - } - const char *commandLine() const override - { - return context_.commandLine(); - } + const char* programName() const override { return context_.programName(); } + const char* displayName() const override { return context_.displayName(); } + const char* fullBinaryPath() const override { return context_.fullBinaryPath(); } + InstallationPrefixInfo installationPrefix() const override + { + return InstallationPrefixInfo(dataPath_.c_str(), true); + } + const char* commandLine() const override { return context_.commandLine(); } - private: - const IProgramContext &context_; - std::string dataPath_; +private: + const IProgramContext& context_; + std::string dataPath_; }; //! Prints the command-line options for the unit test binary. -void printHelp(const Options &options) +void printHelp(const Options& options) { - const std::string &program = getProgramContext().displayName(); + const std::string& program = getProgramContext().displayName(); std::fprintf(stderr, "\nYou can use the following GROMACS-specific command-line flags\n" "to control the behavior of the tests:\n\n"); @@ -154,18 +140,22 @@ void printHelp(const Options &options) // Never releases ownership. std::unique_ptr g_testContext; -} // namespace +} // namespace //! \cond internal -void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, - bool usesHardwareDetection, int *argc, char ***argv) +void initTestUtils(const char* dataPath, + const char* tempPath, + bool usesMpi, + bool usesHardwareDetection, + int* argc, + char*** argv) { -#if !defined NDEBUG && \ - !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \ - && defined __OPTIMIZE__) +#if !defined NDEBUG \ + && !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \ + && defined __OPTIMIZE__) gmx_feenableexcept(); #endif - const CommandLineProgramContext &context = initForCommandLine(argc, argv); + const CommandLineProgramContext& context = initForCommandLine(argc, argv); try { if (!usesMpi && gmx_node_num() > 1) @@ -175,7 +165,8 @@ void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, // continue with the master rank here. if (gmx_node_rank() == 0) { - fprintf(stderr, "NOTE: You are running %s on %d MPI ranks, " + fprintf(stderr, + "NOTE: You are running %s on %d MPI ranks, " "but it is does not contain MPI-enabled tests. " "The test will now exit.\n", context.programName(), gmx_node_num()); @@ -195,15 +186,13 @@ void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, ::testing::InitGoogleMock(argc, *argv); if (dataPath != nullptr) { - TestFileManager::setInputDataDirectory( - Path::join(CMAKE_SOURCE_DIR, dataPath)); + TestFileManager::setInputDataDirectory(Path::join(CMAKE_SOURCE_DIR, dataPath)); } if (tempPath != nullptr) { TestFileManager::setGlobalOutputTempDirectory(tempPath); } - TestFileManager::setTestSimulationDatabaseDirectory( - GMX_TESTSIMULATIONDATABASE_DIR); + TestFileManager::setTestSimulationDatabaseDirectory(GMX_TESTSIMULATIONDATABASE_DIR); bool bHelp = false; std::string sourceRoot; @@ -211,13 +200,13 @@ void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, // TODO: A single option that accepts multiple names would be nicer. // Also, we recognize -help, but GTest doesn't, which leads to a bit // unintuitive behavior. - options.addOption(BooleanOption("h").store(&bHelp) - .description("Print GROMACS-specific unit test options")); + options.addOption(BooleanOption("h").store(&bHelp).description( + "Print GROMACS-specific unit test options")); options.addOption(BooleanOption("help").store(&bHelp).hidden()); options.addOption(BooleanOption("?").store(&bHelp).hidden()); // TODO: Make this into a FileNameOption (or a DirectoryNameOption). - options.addOption(StringOption("src-root").store(&sourceRoot) - .description("Override source tree location (for data files)")); + options.addOption( + StringOption("src-root").store(&sourceRoot).description("Override source tree location (for data files)")); // The potential MPI test event listener must be initialized first, // because it should appear in the start of the event listener list, // before other event listeners that may generate test failures @@ -235,7 +224,7 @@ void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, CommandLineParser(&options).parse(argc, *argv); options.finish(); } - catch (const UserInputError &) + catch (const UserInputError&) { printHelp(options); throw; @@ -247,11 +236,10 @@ void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, if (!sourceRoot.empty()) { g_testContext->overrideSourceRoot(sourceRoot); - TestFileManager::setInputDataDirectory( - Path::join(sourceRoot, dataPath)); + TestFileManager::setInputDataDirectory(Path::join(sourceRoot, dataPath)); } } - catch (const std::exception &ex) + catch (const std::exception& ex) { printFatalErrorMessage(stderr, ex); int retcode = processExceptionAtExitForCommandLine(ex); diff --git a/src/testutils/testinit.h b/src/testutils/testinit.h index 8cbe43c542..3b5227bf0a 100644 --- a/src/testutils/testinit.h +++ b/src/testutils/testinit.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,8 +67,12 @@ namespace test * * \ingroup module_testutils */ -void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi, - bool usesHardwareDetection, int *argc, char ***argv); +void initTestUtils(const char* dataPath, + const char* tempPath, + bool usesMpi, + bool usesHardwareDetection, + int* argc, + char*** argv); /*! \internal * \brief diff --git a/src/testutils/testmatchers.cpp b/src/testutils/testmatchers.cpp index 04e4116311..6d980826b0 100644 --- a/src/testutils/testmatchers.cpp +++ b/src/testutils/testmatchers.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -62,60 +62,52 @@ namespace test * The implementation is templated so that we can support all of real, * float and double in the same build without duplication. */ -template -class FloatTypeMatcher : public testing::MatcherInterface < std::tuple < FloatType, FloatType>> +template +class FloatTypeMatcher : public testing::MatcherInterface> { - public: - //! Constructor - FloatTypeMatcher(const FloatingPointTolerance &tolerance) - : tolerance_(tolerance) {} - //! Compare the two elements of \c arg, return whether they are equal, and comment on \c listener when they are not. - bool MatchAndExplain(std::tuple arg, - testing::MatchResultListener* listener) const override +public: + //! Constructor + FloatTypeMatcher(const FloatingPointTolerance& tolerance) : tolerance_(tolerance) {} + //! Compare the two elements of \c arg, return whether they are equal, and comment on \c listener when they are not. + bool MatchAndExplain(std::tuple arg, testing::MatchResultListener* listener) const override + { + const FloatType& value1 = std::get<0>(arg); + const FloatType& value2 = std::get<1>(arg); + FloatingPointDifference diff(value1, value2); + if (tolerance_.isWithin(diff)) { - const FloatType &value1 = std::get<0>(arg); - const FloatType &value2 = std::get<1>(arg); - FloatingPointDifference diff(value1, value2); - if (tolerance_.isWithin(diff)) - { - return true; - } - *listener->stream() - << " Actual value: " << value2 << std::endl - << "Expected value: " << value1 << std::endl - << " Difference: " << diff.toString() << std::endl - << " Tolerance: " << tolerance_.toString(diff); - return false; + return true; } - //! Describe to a human what matching means. - void DescribeTo(::std::ostream* os) const override - { - *os << "matches within tolerance"; - } - //! Describe to a human what failing to match means. - void DescribeNegationTo(::std::ostream* os) const override - { - *os << "does not match within tolerance"; - } - private: - //! Tolerance used in matching - FloatingPointTolerance tolerance_; + *listener->stream() << " Actual value: " << value2 << std::endl + << "Expected value: " << value1 << std::endl + << " Difference: " << diff.toString() << std::endl + << " Tolerance: " << tolerance_.toString(diff); + return false; + } + //! Describe to a human what matching means. + void DescribeTo(::std::ostream* os) const override { *os << "matches within tolerance"; } + //! Describe to a human what failing to match means. + void DescribeNegationTo(::std::ostream* os) const override + { + *os << "does not match within tolerance"; + } + +private: + //! Tolerance used in matching + FloatingPointTolerance tolerance_; }; -testing::Matcher < std::tuple < float, float>> -FloatEq(const FloatingPointTolerance &tolerance) +testing::Matcher> FloatEq(const FloatingPointTolerance& tolerance) { return testing::MakeMatcher(new FloatTypeMatcher(tolerance)); } -testing::Matcher < std::tuple < double, double>> -DoubleEq(const FloatingPointTolerance &tolerance) +testing::Matcher> DoubleEq(const FloatingPointTolerance& tolerance) { return testing::MakeMatcher(new FloatTypeMatcher(tolerance)); } -testing::Matcher < std::tuple < real, real>> -RealEq(const FloatingPointTolerance &tolerance) +testing::Matcher> RealEq(const FloatingPointTolerance& tolerance) { return testing::MakeMatcher(new FloatTypeMatcher(tolerance)); } @@ -124,53 +116,52 @@ RealEq(const FloatingPointTolerance &tolerance) * * See RvecEq(). */ -template +template class RVecMatcher : - public testing::MatcherInterface < std::tuple < BasicVector, BasicVector>> + public testing::MatcherInterface, BasicVector>> { - public: - //! Convenience type - using VectorType = BasicVector; - //! Constructor - RVecMatcher(const FloatingPointTolerance &tolerance) - : tolerance_(tolerance) {} - //! Compare the two elements of \c arg, return whether they are equal, and comment on \c listener when they are not. - bool MatchAndExplain(std::tuple arg, - testing::MatchResultListener* listener) const override +public: + //! Convenience type + using VectorType = BasicVector; + //! Constructor + RVecMatcher(const FloatingPointTolerance& tolerance) : tolerance_(tolerance) {} + //! Compare the two elements of \c arg, return whether they are equal, and comment on \c listener when they are not. + bool MatchAndExplain(std::tuple arg, + testing::MatchResultListener* listener) const override + { + const VectorType& lhs = std::get<0>(arg); + const VectorType& rhs = std::get<1>(arg); + FloatTypeMatcher floatTypeMatcher(tolerance_); + bool matches = true; + for (int d = 0; d < DIM; ++d) { - const VectorType &lhs = std::get<0>(arg); - const VectorType &rhs = std::get<1>(arg); - FloatTypeMatcher floatTypeMatcher(tolerance_); - bool matches = true; - for (int d = 0; d < DIM; ++d) - { - auto floatTuple = std::make_tuple(lhs[d], rhs[d]); - matches = matches && floatTypeMatcher.MatchAndExplain(floatTuple, listener); - } - return matches; + auto floatTuple = std::make_tuple(lhs[d], rhs[d]); + matches = matches && floatTypeMatcher.MatchAndExplain(floatTuple, listener); } - //! Describe to a human what matching means. - void DescribeTo(::std::ostream* os) const override - { - *os << "matches all elements within tolerance"; - } - //! Describe to a human what failing to match means. - void DescribeNegationTo(::std::ostream* os) const override - { - *os << "does not match all elements within tolerance"; - } - private: - //! Tolerance used in matching - FloatingPointTolerance tolerance_; + return matches; + } + //! Describe to a human what matching means. + void DescribeTo(::std::ostream* os) const override + { + *os << "matches all elements within tolerance"; + } + //! Describe to a human what failing to match means. + void DescribeNegationTo(::std::ostream* os) const override + { + *os << "does not match all elements within tolerance"; + } + +private: + //! Tolerance used in matching + FloatingPointTolerance tolerance_; }; // Currently there's no need for explicit float or double flavours of // RVec comparison, but those would be simple to add later. -testing::Matcher < std::tuple < RVec, RVec>> -RVecEq(const FloatingPointTolerance &tolerance) +testing::Matcher> RVecEq(const FloatingPointTolerance& tolerance) { return testing::MakeMatcher(new RVecMatcher(tolerance)); } -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx diff --git a/src/testutils/testmatchers.h b/src/testutils/testmatchers.h index 0394d2b914..255d9e5cb0 100644 --- a/src/testutils/testmatchers.h +++ b/src/testutils/testmatchers.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2018, by the GROMACS development team, led by + * Copyright (c) 2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -69,8 +69,7 @@ namespace test * * EXPECT_THAT(testFloats, Pointwise(FloatEq(tolerance), referenceFloats)); */ -testing::Matcher < std::tuple < float, float>> -FloatEq(const FloatingPointTolerance &tolerance); +testing::Matcher> FloatEq(const FloatingPointTolerance& tolerance); /*! \brief Make matcher for doubles for use with GoogleMock that compare * equal when \c tolerance is satisifed. @@ -79,8 +78,7 @@ FloatEq(const FloatingPointTolerance &tolerance); * * EXPECT_THAT(testDoubles, Pointwise(DoubleEq(tolerance), referenceDoubles)); */ -testing::Matcher < std::tuple < double, double>> -DoubleEq(const FloatingPointTolerance &tolerance); +testing::Matcher> DoubleEq(const FloatingPointTolerance& tolerance); /*! \brief Make matcher for reals for use with GoogleMock that compare * equal when \c tolerance is satisifed. @@ -89,8 +87,7 @@ DoubleEq(const FloatingPointTolerance &tolerance); * * EXPECT_THAT(testReals, Pointwise(RealEq(tolerance), referenceReals)); */ -testing::Matcher < std::tuple < real, real>> -RealEq(const FloatingPointTolerance &tolerance); +testing::Matcher> RealEq(const FloatingPointTolerance& tolerance); /*! \brief Make matcher for RVecs for use with GoogleMock that compare * equal when \c tolerance is satisifed. @@ -99,10 +96,9 @@ RealEq(const FloatingPointTolerance &tolerance); * * EXPECT_THAT(testRVecs, Pointwise(RVecEq(tolerance), referenceRVecs)); */ -testing::Matcher < std::tuple < RVec, RVec>> -RVecEq(const FloatingPointTolerance &tolerance); +testing::Matcher> RVecEq(const FloatingPointTolerance& tolerance); -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/testutils/testoptions.cpp b/src/testutils/testoptions.cpp index 5f63a6d970..02749d8259 100644 --- a/src/testutils/testoptions.cpp +++ b/src/testutils/testoptions.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -63,55 +63,55 @@ namespace */ class TestOptionsRegistry { - public: - //! Returns the singleton instance of this class. - static TestOptionsRegistry &getInstance() - { - static TestOptionsRegistry singleton; - return singleton; - } +public: + //! Returns the singleton instance of this class. + static TestOptionsRegistry& getInstance() + { + static TestOptionsRegistry singleton; + return singleton; + } - //! Adds a provider into the registry. - void add(const char * /*name*/, TestOptionsProvider *provider) - { - lock_guard lock(listMutex_); - providerList_.push_back(provider); - } + //! Adds a provider into the registry. + void add(const char* /*name*/, TestOptionsProvider* provider) + { + lock_guard lock(listMutex_); + providerList_.push_back(provider); + } - //! Initializes the options from all the provides. - void initOptions(IOptionsContainer *options); + //! Initializes the options from all the provides. + void initOptions(IOptionsContainer* options); - private: - TestOptionsRegistry() {} +private: + TestOptionsRegistry() {} - typedef std::list ProviderList; + typedef std::list ProviderList; - Mutex listMutex_; - ProviderList providerList_; + Mutex listMutex_; + ProviderList providerList_; - GMX_DISALLOW_COPY_AND_ASSIGN(TestOptionsRegistry); + GMX_DISALLOW_COPY_AND_ASSIGN(TestOptionsRegistry); }; -void TestOptionsRegistry::initOptions(IOptionsContainer *options) +void TestOptionsRegistry::initOptions(IOptionsContainer* options) { // TODO: Have some deterministic order for the options; now it depends on // the order in which the global initializers are run. - lock_guard lock(listMutex_); - ProviderList::const_iterator i; + lock_guard lock(listMutex_); + ProviderList::const_iterator i; for (i = providerList_.begin(); i != providerList_.end(); ++i) { (*i)->initOptions(options); } } -} // namespace +} // namespace -void registerTestOptions(const char *name, TestOptionsProvider *provider) +void registerTestOptions(const char* name, TestOptionsProvider* provider) { TestOptionsRegistry::getInstance().add(name, provider); } -void initTestOptions(IOptionsContainer *options) +void initTestOptions(IOptionsContainer* options) { TestOptionsRegistry::getInstance().initOptions(options); } diff --git a/src/testutils/testoptions.h b/src/testutils/testoptions.h index 2a65e415ff..ab2d4f914a 100644 --- a/src/testutils/testoptions.h +++ b/src/testutils/testoptions.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -66,16 +66,16 @@ namespace test */ class TestOptionsProvider { - public: - /*! \brief - * Initializes the options from this provider. - * - * \param options The options need to be added here. - */ - virtual void initOptions(IOptionsContainer *options) = 0; +public: + /*! \brief + * Initializes the options from this provider. + * + * \param options The options need to be added here. + */ + virtual void initOptions(IOptionsContainer* options) = 0; - protected: - virtual ~TestOptionsProvider() {} +protected: + virtual ~TestOptionsProvider() {} }; /*! \libinternal \brief @@ -96,7 +96,7 @@ class TestOptionsProvider * * \ingroup module_testutils */ -void registerTestOptions(const char *name, TestOptionsProvider *provider); +void registerTestOptions(const char* name, TestOptionsProvider* provider); /*! \libinternal \brief * Initializes the options from all registered test providers. * @@ -106,7 +106,7 @@ void registerTestOptions(const char *name, TestOptionsProvider *provider); * * \ingroup module_testutils */ -void initTestOptions(IOptionsContainer *options); +void initTestOptions(IOptionsContainer* options); // Uncrustify screws up the indentation for the example otherwise. /* *INDENT-OFF* */ @@ -162,22 +162,19 @@ void initTestOptions(IOptionsContainer *options); * \hideinitializer */ /* *INDENT-ON* */ -#define GMX_TEST_OPTIONS(name, options) \ +#define GMX_TEST_OPTIONS(name, options) \ class name : public ::gmx::test::TestOptionsProvider /*NOLINT(misc-macro-parentheses,bugprone-macro-parentheses)*/ \ - { \ - public: \ - name() \ - { \ - ::gmx::test::registerTestOptions(#name, this); \ - } \ - virtual void initOptions(::gmx::IOptionsContainer *(options)); \ - }; \ - \ - static name s_ ## name ## Instance; \ - \ - void name::initOptions(::gmx::IOptionsContainer *options) //NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) + { \ + public: \ + name() { ::gmx::test::registerTestOptions(#name, this); } \ + virtual void initOptions(::gmx::IOptionsContainer*(options)); \ + }; \ + \ + static name s_##name##Instance; \ + \ + void name::initOptions(::gmx::IOptionsContainer* options) //NOLINT(misc-macro-parentheses,bugprone-macro-parentheses) -} // namespace test -} // namespace gmx +} // namespace test +} // namespace gmx #endif diff --git a/src/testutils/tests/interactivetest.cpp b/src/testutils/tests/interactivetest.cpp index eb1ac9914f..21744bf4bd 100644 --- a/src/testutils/tests/interactivetest.cpp +++ b/src/testutils/tests/interactivetest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -57,84 +57,77 @@ namespace class InteractiveSession { - public: - explicit InteractiveSession(gmx::test::ReferenceDataMode mode) - : data_(mode), helper_(data_.rootChecker()), nextInputLine_(0) - { - } +public: + explicit InteractiveSession(gmx::test::ReferenceDataMode mode) : + data_(mode), + helper_(data_.rootChecker()), + nextInputLine_(0) + { + } - void addOutput(const char *output) - { - events_.emplace_back(WriteOutput, output); - } - void addInputLine(const char *inputLine) - { - inputLines_.push_back(inputLine); - } - void addReadInput() - { - events_.emplace_back(ReadInput, ""); - } - void addInput(const char *inputLine) - { - addInputLine(inputLine); - addReadInput(); - } - void addInputNoNewline(const char *inputLine) - { - addInputLine(inputLine); - helper_.setLastNewline(false); - events_.emplace_back(ReadInputNoNewline, ""); - } + void addOutput(const char* output) { events_.emplace_back(WriteOutput, output); } + void addInputLine(const char* inputLine) { inputLines_.push_back(inputLine); } + void addReadInput() { events_.emplace_back(ReadInput, ""); } + void addInput(const char* inputLine) + { + addInputLine(inputLine); + addReadInput(); + } + void addInputNoNewline(const char* inputLine) + { + addInputLine(inputLine); + helper_.setLastNewline(false); + events_.emplace_back(ReadInputNoNewline, ""); + } - void run() + void run() + { + gmx::TextInputStream& input = helper_.inputStream(); + gmx::TextOutputStream& output = helper_.outputStream(); + helper_.setInputLines(inputLines_); + std::vector::const_iterator event; + for (event = events_.begin(); event != events_.end(); ++event) { - gmx::TextInputStream &input = helper_.inputStream(); - gmx::TextOutputStream &output = helper_.outputStream(); - helper_.setInputLines(inputLines_); - std::vector::const_iterator event; - for (event = events_.begin(); event != events_.end(); ++event) + if (event->first == WriteOutput) { - if (event->first == WriteOutput) - { - output.write(event->second); - } - else + output.write(event->second); + } + else + { + std::string expectedLine; + const bool bInputRemaining = (nextInputLine_ < inputLines_.size()); + if (bInputRemaining) { - std::string expectedLine; - const bool bInputRemaining = (nextInputLine_ < inputLines_.size()); - if (bInputRemaining) + expectedLine = inputLines_[nextInputLine_]; + if (event->first != ReadInputNoNewline) { - expectedLine = inputLines_[nextInputLine_]; - if (event->first != ReadInputNoNewline) - { - expectedLine.append("\n"); - } + expectedLine.append("\n"); } - ++nextInputLine_; - std::string line; - EXPECT_EQ(bInputRemaining, input.readLine(&line)); - EXPECT_EQ(expectedLine, line); } + ++nextInputLine_; + std::string line; + EXPECT_EQ(bInputRemaining, input.readLine(&line)); + EXPECT_EQ(expectedLine, line); } - helper_.checkSession(); } + helper_.checkSession(); + } - private: - enum EventType - { - ReadInput, - ReadInputNoNewline, - WriteOutput - }; - // The latter is the output string. - typedef std::pair Event; +private: + enum EventType + { + ReadInput, + ReadInputNoNewline, + WriteOutput + }; + // The latter is the output string. + typedef std::pair Event; - gmx::test::TestReferenceData data_; - gmx::test::InteractiveTestHelper helper_; - std::vector inputLines_; - size_t nextInputLine_; - std::vector events_; + gmx::test::TestReferenceData data_; + gmx::test::InteractiveTestHelper helper_; + std::vector inputLines_; + size_t nextInputLine_; + std::vector events_; }; TEST(InteractiveTestHelperTest, ChecksSimpleSession) diff --git a/src/testutils/tests/mpitest.cpp b/src/testutils/tests/mpitest.cpp index b810a2597f..d41ee8d928 100644 --- a/src/testutils/tests/mpitest.cpp +++ b/src/testutils/tests/mpitest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -55,11 +55,10 @@ namespace class MpiSelfTest : public ::testing::Test { - public: - MpiSelfTest() : reached {0, 0} - {} +public: + MpiSelfTest() : reached{ 0, 0 } {} - int reached[2]; + int reached[2]; }; TEST_F(MpiSelfTest, Runs) diff --git a/src/testutils/tests/refdata_tests.cpp b/src/testutils/tests/refdata_tests.cpp index 689005ffd2..04a9848c7b 100644 --- a/src/testutils/tests/refdata_tests.cpp +++ b/src/testutils/tests/refdata_tests.cpp @@ -59,8 +59,8 @@ namespace { -using gmx::test::TestReferenceData; using gmx::test::TestReferenceChecker; +using gmx::test::TestReferenceData; TEST(ReferenceDataTest, HandlesSimpleData) { @@ -69,10 +69,10 @@ TEST(ReferenceDataTest, HandlesSimpleData) TestReferenceChecker checker(data.rootChecker()); checker.checkBoolean(true, "bool"); checker.checkInteger(1, "int"); - checker.checkInt32(1ULL<<12, "int32"); - checker.checkUInt32(1ULL<<12, "uint32"); - checker.checkInt64(1ULL<<42, "int64"); - checker.checkUInt64(1ULL<<42, "uint64"); + checker.checkInt32(1ULL << 12, "int32"); + checker.checkUInt32(1ULL << 12, "uint32"); + checker.checkInt64(1ULL << 42, "int64"); + checker.checkUInt64(1ULL << 42, "uint64"); checker.checkDouble(0.5, "real"); checker.checkString("Test", "string"); } @@ -81,10 +81,10 @@ TEST(ReferenceDataTest, HandlesSimpleData) TestReferenceChecker checker(data.rootChecker()); checker.checkBoolean(true, "bool"); checker.checkInteger(1, "int"); - checker.checkInt32(1ULL<<12, "int32"); - checker.checkUInt32(1ULL<<12, "uint32"); - checker.checkInt64(1ULL<<42, "int64"); - checker.checkUInt64(1ULL<<42, "uint64"); + checker.checkInt32(1ULL << 12, "int32"); + checker.checkUInt32(1ULL << 12, "uint32"); + checker.checkInt64(1ULL << 42, "int64"); + checker.checkUInt64(1ULL << 42, "uint64"); checker.checkDouble(0.5, "real"); checker.checkString("Test", "string"); } @@ -92,8 +92,8 @@ TEST(ReferenceDataTest, HandlesSimpleData) TEST(ReferenceDataTest, HandlesFloatingPointData) { - const float floatValue = 4.0F/3.0F; - const double doubleValue = 4.0/3.0; + const float floatValue = 4.0F / 3.0F; + const double doubleValue = 4.0 / 3.0; { TestReferenceData data(gmx::test::erefdataUpdateAll); @@ -125,7 +125,7 @@ TEST(ReferenceDataTest, HandlesPresenceChecks) TestReferenceData data(gmx::test::erefdataCompare); TestReferenceChecker checker(data.rootChecker()); // Assigned to avoid warnings about potentially uninitialized value. - bool bRet = true; + bool bRet = true; EXPECT_TRUE(checker.checkPresent(true, "present")); checker.checkInteger(1, "present"); EXPECT_NONFATAL_FAILURE(bRet = checker.checkPresent(false, "present"), ""); @@ -197,14 +197,14 @@ TEST(ReferenceDataTest, HandlesSequenceData) //! Helper typedef typedef double dvec[3]; //! Helper function for HandlesSequenceOfCustomData -void checkCustomVector(TestReferenceChecker *checker, const dvec &value) +void checkCustomVector(TestReferenceChecker* checker, const dvec& value) { checker->checkVector(value, nullptr); } TEST(ReferenceDataTest, HandlesSequenceOfCustomData) { - const dvec seq[] = { {-3, 4, 5}, {-2.3, 5, 0} }; + const dvec seq[] = { { -3, 4, 5 }, { -2.3, 5, 0 } }; { TestReferenceData data(gmx::test::erefdataUpdateAll); @@ -380,7 +380,7 @@ gmx::KeyValueTreeObject buildKeyValueTree(bool full) { obj.addValue("s", "x"); } - auto arr = root.addUniformArray("a"); + auto arr = root.addUniformArray("a"); arr.addValue(2); arr.addValue(3); root.addValue("s", "y"); @@ -414,7 +414,8 @@ TEST(ReferenceDataTest, HandlesKeyValueTreeExtraKey) { TestReferenceData data(gmx::test::erefdataCompare); TestReferenceChecker checker(data.rootChecker()); - EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(true), "tree"), ""); + EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(true), "tree"), + ""); } } @@ -429,7 +430,8 @@ TEST(ReferenceDataTest, HandlesKeyValueTreeMissingKey) { TestReferenceData data(gmx::test::erefdataCompare); TestReferenceChecker checker(data.rootChecker()); - EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(false), "tree"), ""); + EXPECT_NONFATAL_FAILURE(checker.checkKeyValueTreeObject(buildKeyValueTree(false), "tree"), + ""); } } @@ -480,14 +482,16 @@ TEST(ReferenceDataTest, HandlesMissingReferenceDataFile) { const int seq[5] = { -1, 3, 5, 2, 4 }; - EXPECT_NONFATAL_FAILURE({ - TestReferenceData data(gmx::test::erefdataCompare); - TestReferenceChecker checker(data.rootChecker()); - checker.checkInteger(1, "int"); - checker.checkDouble(0.5, "real"); - checker.checkString("Test", "string"); - checker.checkSequenceArray(5, seq, "seq"); - }, ""); + EXPECT_NONFATAL_FAILURE( + { + TestReferenceData data(gmx::test::erefdataCompare); + TestReferenceChecker checker(data.rootChecker()); + checker.checkInteger(1, "int"); + checker.checkDouble(0.5, "real"); + checker.checkString("Test", "string"); + checker.checkSequenceArray(5, seq, "seq"); + }, + ""); } @@ -512,11 +516,12 @@ TEST(ReferenceDataTest, HandlesSpecialCharactersInStrings) TEST(ReferenceDataTest, HandlesStringsWithTextAndWhitespace) { - const char *strings[] = { " test", "test ", " test ", "the test", "\ntest", "\n\ntest", "test\n", "test\n\n" }; + const char* strings[] = { " test", "test ", " test ", "the test", + "\ntest", "\n\ntest", "test\n", "test\n\n" }; { TestReferenceData data(gmx::test::erefdataUpdateAll); TestReferenceChecker checker(data.rootChecker()); - for (const auto &s : strings) + for (const auto& s : strings) { checker.checkString(s, nullptr); checker.checkTextBlock(s, nullptr); @@ -525,7 +530,7 @@ TEST(ReferenceDataTest, HandlesStringsWithTextAndWhitespace) { TestReferenceData data(gmx::test::erefdataCompare); TestReferenceChecker checker(data.rootChecker()); - for (const auto &s : strings) + for (const auto& s : strings) { checker.checkString(s, nullptr); checker.checkTextBlock(s, nullptr); diff --git a/src/testutils/tests/testasserts_tests.cpp b/src/testutils/tests/testasserts_tests.cpp index cb781cc469..83b7d07851 100644 --- a/src/testutils/tests/testasserts_tests.cpp +++ b/src/testutils/tests/testasserts_tests.cpp @@ -57,11 +57,10 @@ using ::testing::internal::FloatingPoint; * * \ingroup module_testutils */ -template +template FloatType addUlps(FloatType value, int ulps) { - return FloatingPoint::ReinterpretBits( - FloatingPoint(value).bits() + ulps); + return FloatingPoint::ReinterpretBits(FloatingPoint(value).bits() + ulps); } using ::gmx::test::FloatingPointDifference; @@ -72,7 +71,7 @@ TEST(FloatingPointDifferenceTest, HandlesEqualValues) EXPECT_TRUE(diff.isDouble()); EXPECT_FALSE(diff.isNaN()); EXPECT_EQ(0.0, diff.asAbsolute()); - EXPECT_EQ(0U, diff.asUlps()); + EXPECT_EQ(0U, diff.asUlps()); EXPECT_FALSE(diff.signsDiffer()); } @@ -83,7 +82,7 @@ TEST(FloatingPointDifferenceTest, HandlesFloatValues) EXPECT_FALSE(diff.isDouble()); EXPECT_FALSE(diff.isNaN()); EXPECT_EQ(0.0, diff.asAbsolute()); - EXPECT_EQ(0U, diff.asUlps()); + EXPECT_EQ(0U, diff.asUlps()); EXPECT_FALSE(diff.signsDiffer()); } @@ -92,7 +91,7 @@ TEST(FloatingPointDifferenceTest, HandlesZerosOfDifferentSign) FloatingPointDifference diff(0.0, GMX_DOUBLE_NEGZERO); EXPECT_FALSE(diff.isNaN()); EXPECT_EQ(0.0, diff.asAbsolute()); - EXPECT_EQ(0U, diff.asUlps()); + EXPECT_EQ(0U, diff.asUlps()); EXPECT_TRUE(diff.signsDiffer()); } @@ -135,7 +134,7 @@ TEST(FloatingPointDifferenceTest, HandlesUlpDifferences) TEST(FloatingPointDifferenceTest, HandlesUlpDifferenceAcrossZero) { const double first = addUlps(GMX_DOUBLE_NEGZERO, 2); - const double second = addUlps( 0.0, 2); + const double second = addUlps(0.0, 2); FloatingPointDifference diff(first, second); EXPECT_FALSE(diff.isNaN()); EXPECT_DOUBLE_EQ(second - first, diff.asAbsolute()); @@ -162,8 +161,8 @@ TEST(FloatingPointToleranceTest, UlpTolerance) EXPECT_TRUE(ulpTolerance(2).isWithin(fulp2)); FloatingPointDifference dequal(1.0, 1.0); - FloatingPointDifference dulp2(1.0, addUlps(1.0, 2)); - FloatingPointDifference dulp2f(1.0, static_cast(addUlps(1.0F, 2))); + FloatingPointDifference dulp2(1.0, addUlps(1.0, 2)); + FloatingPointDifference dulp2f(1.0, static_cast(addUlps(1.0F, 2))); EXPECT_TRUE(ulpTolerance(0).isWithin(dequal)); EXPECT_TRUE(ulpTolerance(2).isWithin(dulp2)); EXPECT_FALSE(ulpTolerance(2).isWithin(dulp2f)); @@ -221,7 +220,7 @@ TEST(FloatingPointToleranceTest, RelativeToleranceAsUlp) FloatingPointDifference dequal(1.0, 1.0); FloatingPointDifference dulp4(1.0, addUlps(1.0, 4)); - FloatingPointDifference dulp4f(1.0, static_cast(addUlps(1.0F, 4))); + FloatingPointDifference dulp4f(1.0, static_cast(addUlps(1.0F, 4))); FloatingPointDifference dsmall(0.1, addUlps(1.0, 2) - 0.9); FloatingPointDifference dsmall2(0.1, addUlps(1.0, 6) - 0.9); EXPECT_TRUE(relativeToleranceAsUlp(1.0, 2).isWithin(dequal)); diff --git a/src/testutils/tests/xvgtest_tests.cpp b/src/testutils/tests/xvgtest_tests.cpp index 37a336b89b..f8381a8ca6 100644 --- a/src/testutils/tests/xvgtest_tests.cpp +++ b/src/testutils/tests/xvgtest_tests.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,14 +61,9 @@ using gmx::test::checkXvgFile; using gmx::test::XvgMatchSettings; //! Input testing data - an inline xvg file. -const char * const input[] = { - "0 2905.86 -410.199", - "0.2 6656.67 -430.437", - "0.4 5262.44 -409.399", - "0.6 5994.69 -405.763", - "0.8 5941.37 -408.337", - "1 5869.87 -411.124" -}; +const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437", + "0.4 5262.44 -409.399", "0.6 5994.69 -405.763", + "0.8 5941.37 -408.337", "1 5869.87 -411.124" }; TEST(XvgTests, CreateFile) { @@ -77,7 +72,7 @@ TEST(XvgTests, CreateFile) gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll); gmx::test::TestReferenceChecker checker(data.rootChecker()); // Convert char array to a stream and add it to the checker - gmx::StringInputStream sis(input); + gmx::StringInputStream sis(input); checkXvgFile(&sis, &checker, XvgMatchSettings()); } { @@ -85,7 +80,7 @@ TEST(XvgTests, CreateFile) gmx::test::TestReferenceData data(gmx::test::erefdataCompare); gmx::test::TestReferenceChecker checker(data.rootChecker()); // Convert char array to a stream and add it to the checker - gmx::StringInputStream sis(input); + gmx::StringInputStream sis(input); checkXvgFile(&sis, &checker, XvgMatchSettings()); } } @@ -97,20 +92,18 @@ TEST(XvgTests, CheckMissing) gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll); gmx::test::TestReferenceChecker checker(data.rootChecker()); // Convert char array to a stream and add it to the checker - gmx::StringInputStream sis(input); + gmx::StringInputStream sis(input); checkXvgFile(&sis, &checker, XvgMatchSettings()); } { - const char * const input[] = { - "0 2905.86 -410.199", - "0.2 6656.67 -430.437", - "0.4 5262.44 -409.399" - }; + const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437", + "0.4 5262.44 -409.399" }; // Now check with missing data gmx::test::TestReferenceData data(gmx::test::erefdataCompare); gmx::test::TestReferenceChecker checker(data.rootChecker()); gmx::StringInputStream sis(input); - EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "not used in test"); + EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), + "not used in test"); } } @@ -121,19 +114,14 @@ TEST(XvgTests, CheckExtra) gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll); gmx::test::TestReferenceChecker checker(data.rootChecker()); // Convert char array to a stream and add it to the checker - gmx::StringInputStream sis(input); + gmx::StringInputStream sis(input); checkXvgFile(&sis, &checker, XvgMatchSettings()); } { - const char * const input[] = { - "0 2905.86 -410.199", - "0.2 6656.67 -430.437", - "0.4 5262.44 -409.399", - "0.6 5994.69 -405.763", - "0.8 5941.37 -408.337", - "1 5869.87 -411.124", - "1.2 5889.87 -413.124" - }; + const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437", + "0.4 5262.44 -409.399", "0.6 5994.69 -405.763", + "0.8 5941.37 -408.337", "1 5869.87 -411.124", + "1.2 5889.87 -413.124" }; // Now check with missing data gmx::test::TestReferenceData data(gmx::test::erefdataCompare); gmx::test::TestReferenceChecker checker(data.rootChecker()); @@ -149,18 +137,13 @@ TEST(XvgTests, ReadIncorrect) gmx::test::TestReferenceData data(gmx::test::erefdataUpdateAll); gmx::test::TestReferenceChecker checker(data.rootChecker()); // Convert char array to a stream and add it to the checker - gmx::StringInputStream sis(input); + gmx::StringInputStream sis(input); checkXvgFile(&sis, &checker, XvgMatchSettings()); } { - const char * const input[] = { - "0 2905.86 -410.199", - "0.2 6656.67 -430.437", - "0.4 5262.44 -409.399", - "0.6 5994.69 -405.763", - "0.8 5941.37 -408.337", - "1 5869.87 -421.124" - }; + const char* const input[] = { "0 2905.86 -410.199", "0.2 6656.67 -430.437", + "0.4 5262.44 -409.399", "0.6 5994.69 -405.763", + "0.8 5941.37 -408.337", "1 5869.87 -421.124" }; // Now check with incorrect data gmx::test::TestReferenceData data(gmx::test::erefdataCompare); gmx::test::TestReferenceChecker checker(data.rootChecker()); diff --git a/src/testutils/textblockmatchers.cpp b/src/testutils/textblockmatchers.cpp index 159b75c93b..7dd2f7ca6c 100644 --- a/src/testutils/textblockmatchers.cpp +++ b/src/testutils/textblockmatchers.cpp @@ -62,80 +62,71 @@ namespace class ExactTextMatcher : public ITextBlockMatcher { - public: - void checkStream(TextInputStream *stream, - TestReferenceChecker *checker) override - { - TextReader reader(stream); - checker->checkTextBlock(reader.readAll(), "Contents"); - } +public: + void checkStream(TextInputStream* stream, TestReferenceChecker* checker) override + { + TextReader reader(stream); + checker->checkTextBlock(reader.readAll(), "Contents"); + } }; class NoTextMatcher : public ITextBlockMatcher { - public: - void checkStream(TextInputStream * /*stream*/, - TestReferenceChecker * /*checker*/) override - { - } +public: + void checkStream(TextInputStream* /*stream*/, TestReferenceChecker* /*checker*/) override {} }; class FilteringExactTextMatcher : public ITextBlockMatcher { - public: - FilteringExactTextMatcher(const std::vector &linesToSkip) +public: + FilteringExactTextMatcher(const std::vector& linesToSkip) + { + // Prepare the regular expressions to filter out of the stream. + for (const auto& lineToSkip : linesToSkip) { - // Prepare the regular expressions to filter out of the stream. - for (const auto &lineToSkip : linesToSkip) - { - regexesToSkip_.emplace_back(lineToSkip, std::regex::nosubs | std::regex::extended); - } + regexesToSkip_.emplace_back(lineToSkip, std::regex::nosubs | std::regex::extended); } + } - void checkStream(TextInputStream *stream, - TestReferenceChecker *checker) override + void checkStream(TextInputStream* stream, TestReferenceChecker* checker) override + { + StringOutputStream filteredStream; { - StringOutputStream filteredStream; - { - TextReader reader(stream); - TextWriter writer(&filteredStream); + TextReader reader(stream); + TextWriter writer(&filteredStream); - // Filter the stream - std::string line; - while (reader.readLine(&line)) + // Filter the stream + std::string line; + while (reader.readLine(&line)) + { + bool shouldSkip = false; + for (const auto& regexToSkip : regexesToSkip_) { - bool shouldSkip = false; - for (const auto ®exToSkip : regexesToSkip_) + if (std::regex_match(line.c_str(), regexToSkip)) { - if (std::regex_match(line.c_str(), regexToSkip)) - { - shouldSkip = true; - break; - } - } - if (!shouldSkip) - { - writer.writeLine(line); + shouldSkip = true; + break; } } + if (!shouldSkip) + { + writer.writeLine(line); + } } - StringInputStream filteredStreamToCheck(filteredStream.toString()); - TextReader reader(&filteredStreamToCheck); - checker->checkTextBlock(reader.readAll(), "Contents"); } + StringInputStream filteredStreamToCheck(filteredStream.toString()); + TextReader reader(&filteredStreamToCheck); + checker->checkTextBlock(reader.readAll(), "Contents"); + } - std::vector regexesToSkip_; + std::vector regexesToSkip_; }; -} // namespace +} // namespace -ITextBlockMatcher::~ITextBlockMatcher() -{ -} +ITextBlockMatcher::~ITextBlockMatcher() {} -ITextBlockMatcherSettings::~ITextBlockMatcherSettings() -{ -} +ITextBlockMatcherSettings::~ITextBlockMatcherSettings() {} TextBlockMatcherPointer ExactTextMatch::createMatcher() const { @@ -147,11 +138,12 @@ TextBlockMatcherPointer NoTextMatch::createMatcher() const return TextBlockMatcherPointer(std::make_unique()); } -FilteringExactTextMatch::FilteringExactTextMatch(std::vector linesToSkip) - : linesToSkip_(std::move(linesToSkip)) -{} +FilteringExactTextMatch::FilteringExactTextMatch(std::vector linesToSkip) : + linesToSkip_(std::move(linesToSkip)) +{ +} -void FilteringExactTextMatch::addRegexToSkip(const std::string &lineToSkip) +void FilteringExactTextMatch::addRegexToSkip(const std::string& lineToSkip) { linesToSkip_.push_back(lineToSkip); } diff --git a/src/testutils/textblockmatchers.h b/src/testutils/textblockmatchers.h index f2f7292338..6eb6be88e9 100644 --- a/src/testutils/textblockmatchers.h +++ b/src/testutils/textblockmatchers.h @@ -77,22 +77,21 @@ class TestReferenceChecker; */ class ITextBlockMatcher { - public: - virtual ~ITextBlockMatcher(); - - /*! \brief - * Matches contents of a stream against reference data. - * - * \param stream Stream to match. - * \param checker Checker to use for matching. - * - * The method can change the state of the provided checker (e.g., by - * changing the default tolerance). - * The caller is responsible of providing a checker where such state - * changes do not matter. - */ - virtual void checkStream(TextInputStream *stream, - TestReferenceChecker *checker) = 0; +public: + virtual ~ITextBlockMatcher(); + + /*! \brief + * Matches contents of a stream against reference data. + * + * \param stream Stream to match. + * \param checker Checker to use for matching. + * + * The method can change the state of the provided checker (e.g., by + * changing the default tolerance). + * The caller is responsible of providing a checker where such state + * changes do not matter. + */ + virtual void checkStream(TextInputStream* stream, TestReferenceChecker* checker) = 0; }; //! Smart pointer for managing a ITextBlockMatcher. @@ -112,12 +111,12 @@ typedef std::unique_ptr TextBlockMatcherPointer; */ class ITextBlockMatcherSettings { - public: - //! Factory method that constructs the matcher after parameters are set. - virtual TextBlockMatcherPointer createMatcher() const = 0; +public: + //! Factory method that constructs the matcher after parameters are set. + virtual TextBlockMatcherPointer createMatcher() const = 0; - protected: - virtual ~ITextBlockMatcherSettings(); +protected: + virtual ~ITextBlockMatcherSettings(); }; /*! \libinternal \brief @@ -128,8 +127,8 @@ class ITextBlockMatcherSettings */ class ExactTextMatch : public ITextBlockMatcherSettings { - public: - TextBlockMatcherPointer createMatcher() const override; +public: + TextBlockMatcherPointer createMatcher() const override; }; /*! \libinternal \brief @@ -140,8 +139,8 @@ class ExactTextMatch : public ITextBlockMatcherSettings */ class NoTextMatch : public ITextBlockMatcherSettings { - public: - TextBlockMatcherPointer createMatcher() const override; +public: + TextBlockMatcherPointer createMatcher() const override; }; /*! \libinternal \brief @@ -158,17 +157,17 @@ class NoTextMatch : public ITextBlockMatcherSettings */ class FilteringExactTextMatch : public ITextBlockMatcherSettings { - public: - //! Constructor - explicit FilteringExactTextMatch(std::vector linesToSkip); - //! Factory method. - TextBlockMatcherPointer createMatcher() const override; - //! Add a regular expression for which a matching line should be skipped. - void addRegexToSkip(const std::string &lineToSkip); - private: - //! The regular expressions for lines that should be skipped. - std::vector linesToSkip_; - +public: + //! Constructor + explicit FilteringExactTextMatch(std::vector linesToSkip); + //! Factory method. + TextBlockMatcherPointer createMatcher() const override; + //! Add a regular expression for which a matching line should be skipped. + void addRegexToSkip(const std::string& lineToSkip); + +private: + //! The regular expressions for lines that should be skipped. + std::vector linesToSkip_; }; } // namespace test diff --git a/src/testutils/tprfilegenerator.cpp b/src/testutils/tprfilegenerator.cpp index ac214d0efd..872703eef1 100644 --- a/src/testutils/tprfilegenerator.cpp +++ b/src/testutils/tprfilegenerator.cpp @@ -54,7 +54,7 @@ namespace gmx namespace test { -TprAndFileManager::TprAndFileManager(const std::string &name) +TprAndFileManager::TprAndFileManager(const std::string& name) { const std::string mdpInputFileName = fileManager_.getTemporaryFilePath(name + ".mdp"); gmx::TextWriter::writeFileFromString(mdpInputFileName, ""); diff --git a/src/testutils/tprfilegenerator.h b/src/testutils/tprfilegenerator.h index 3b176fd275..2073eccfd6 100644 --- a/src/testutils/tprfilegenerator.h +++ b/src/testutils/tprfilegenerator.h @@ -59,20 +59,21 @@ class TestFileManager; */ class TprAndFileManager { - public: - /*! \brief - * Generates the file when needed. - * - * \param[in] name The basename of the input files and the generated TPR. - */ - TprAndFileManager(const std::string &name); - //! Access to the string. - const std::string &tprName() const { return tprFileName_; } - private: - //! Tpr file name. - std::string tprFileName_; - //! Filemanager, needed to clean up the file later. - TestFileManager fileManager_; +public: + /*! \brief + * Generates the file when needed. + * + * \param[in] name The basename of the input files and the generated TPR. + */ + TprAndFileManager(const std::string& name); + //! Access to the string. + const std::string& tprName() const { return tprFileName_; } + +private: + //! Tpr file name. + std::string tprFileName_; + //! Filemanager, needed to clean up the file later. + TestFileManager fileManager_; }; } // namespace test diff --git a/src/testutils/unittest_main.cpp b/src/testutils/unittest_main.cpp index 706ba13e58..1faf7979dd 100644 --- a/src/testutils/unittest_main.cpp +++ b/src/testutils/unittest_main.cpp @@ -1,7 +1,8 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by + * Copyright (c) 2010-2017, The GROMACS development team. + * Copyright (c) 2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -47,41 +48,40 @@ #ifndef TEST_DATA_PATH //! Path to test input data directory (needs to be set by the build system). -#define TEST_DATA_PATH 0 +# define TEST_DATA_PATH 0 #endif #ifndef TEST_TEMP_PATH //! Path to test output temporary directory (needs to be set by the build system). -#define TEST_TEMP_PATH 0 +# define TEST_TEMP_PATH 0 #endif #ifndef TEST_USES_MPI //! Whether the test expects/supports running with multiple MPI ranks. -#define TEST_USES_MPI false +# define TEST_USES_MPI false #endif #ifndef TEST_USES_HARDWARE_DETECTION //! Whether the test expects/supports running with knowledge of the hardware. -#define TEST_USES_HARDWARE_DETECTION false +# define TEST_USES_HARDWARE_DETECTION false namespace gmx { namespace test { //! Implement a stub definition for tests that don't ask for a real one. -void callAddGlobalTestEnvironment() {}; -} -} +void callAddGlobalTestEnvironment(){}; +} // namespace test +} // namespace gmx #endif /*! \brief * Initializes unit testing for \ref module_testutils. */ -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { // Calls ::testing::InitGoogleMock() - ::gmx::test::initTestUtils(TEST_DATA_PATH, TEST_TEMP_PATH, - TEST_USES_MPI, TEST_USES_HARDWARE_DETECTION, - &argc, &argv); + ::gmx::test::initTestUtils(TEST_DATA_PATH, TEST_TEMP_PATH, TEST_USES_MPI, + TEST_USES_HARDWARE_DETECTION, &argc, &argv); int errcode = RUN_ALL_TESTS(); ::gmx::test::finalizeTestUtils(); return errcode; diff --git a/src/testutils/xvgtest.cpp b/src/testutils/xvgtest.cpp index 66249a3fc0..eb73e8fb27 100644 --- a/src/testutils/xvgtest.cpp +++ b/src/testutils/xvgtest.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,43 +67,34 @@ namespace class XvgMatcher : public ITextBlockMatcher { - public: - explicit XvgMatcher(const XvgMatchSettings &settings) - : settings_(settings) - { - } +public: + explicit XvgMatcher(const XvgMatchSettings& settings) : settings_(settings) {} - void checkStream(TextInputStream *stream, - TestReferenceChecker *checker) override - { - checkXvgFile(stream, checker, settings_); - } + void checkStream(TextInputStream* stream, TestReferenceChecker* checker) override + { + checkXvgFile(stream, checker, settings_); + } - private: - XvgMatchSettings settings_; +private: + XvgMatchSettings settings_; }; //! Helper function to identify which @ lines in xvg files should be tested. -bool isRelevantXvgCommand(const std::string &line) +bool isRelevantXvgCommand(const std::string& line) { - return contains(line, " title ") - || contains(line, " subtitle ") - || contains(line, " label ") - || contains(line, "@TYPE ") - || contains(line, " legend \""); + return contains(line, " title ") || contains(line, " subtitle ") || contains(line, " label ") + || contains(line, "@TYPE ") || contains(line, " legend \""); } //! Helper function to check a single xvg value in a sequence. -void checkXvgDataPoint(TestReferenceChecker *checker, const std::string &value) +void checkXvgDataPoint(TestReferenceChecker* checker, const std::string& value) { checker->checkRealFromString(value, nullptr); } -} // namespace +} // namespace -void checkXvgFile(TextInputStream *input, - TestReferenceChecker *checker, - const XvgMatchSettings &settings) +void checkXvgFile(TextInputStream* input, TestReferenceChecker* checker, const XvgMatchSettings& settings) { TestReferenceChecker legendChecker(checker->checkCompound("XvgLegend", "Legend")); TestReferenceChecker dataChecker(checker->checkCompound("XvgData", "Data")); @@ -136,8 +127,7 @@ void checkXvgFile(TextInputStream *input, } const std::vector columns = splitString(line); const std::string id = formatString("Row%d", dataRowCount); - dataChecker.checkSequence(columns.begin(), columns.end(), id.c_str(), - &checkXvgDataPoint); + dataChecker.checkSequence(columns.begin(), columns.end(), id.c_str(), &checkXvgDataPoint); ++dataRowCount; } dataChecker.checkUnusedEntries(); diff --git a/src/testutils/xvgtest.h b/src/testutils/xvgtest.h index e92c8d99d5..1812cc328d 100644 --- a/src/testutils/xvgtest.h +++ b/src/testutils/xvgtest.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015,2018, by the GROMACS development team, led by + * Copyright (c) 2015,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -61,12 +61,10 @@ class TestReferenceChecker; struct XvgMatchSettings { - XvgMatchSettings() : tolerance(defaultRealTolerance()), testData(true) - { - } + XvgMatchSettings() : tolerance(defaultRealTolerance()), testData(true) {} - FloatingPointTolerance tolerance; - bool testData; + FloatingPointTolerance tolerance; + bool testData; }; /*! \brief @@ -84,9 +82,7 @@ struct XvgMatchSettings * * \see XvgMatch */ -void checkXvgFile(TextInputStream *input, - TestReferenceChecker *checker, - const XvgMatchSettings &settings); +void checkXvgFile(TextInputStream* input, TestReferenceChecker* checker, const XvgMatchSettings& settings); /*! \libinternal \brief * Match the contents as an xvg file. @@ -98,29 +94,29 @@ void checkXvgFile(TextInputStream *input, */ class XvgMatch : public ITextBlockMatcherSettings { - public: - //! Sets the tolerance for matching data point values. - XvgMatch &tolerance(const FloatingPointTolerance &tolerance) - { - settings_.tolerance = tolerance; - return *this; - } - /*! \brief - * Sets whether the actual data is checked. - * - * If set to `false`, only the legends are checked. Use this if the - * data is already tested using different means. - */ - XvgMatch &testData(bool test) - { - settings_.testData = test; - return *this; - } +public: + //! Sets the tolerance for matching data point values. + XvgMatch& tolerance(const FloatingPointTolerance& tolerance) + { + settings_.tolerance = tolerance; + return *this; + } + /*! \brief + * Sets whether the actual data is checked. + * + * If set to `false`, only the legends are checked. Use this if the + * data is already tested using different means. + */ + XvgMatch& testData(bool test) + { + settings_.testData = test; + return *this; + } - TextBlockMatcherPointer createMatcher() const override; + TextBlockMatcherPointer createMatcher() const override; - private: - XvgMatchSettings settings_; +private: + XvgMatchSettings settings_; }; } // namespace test -- 2.22.0